[
  {
    "path": ".deepsource.toml",
    "content": "version = 1\n\n[[analyzers]]\nname = \"go\"\nenabled = true\n\n  [analyzers.meta]\n  import_paths = [\"github.com/docker-slim/docker-slim\"]\n"
  },
  {
    "path": ".dockerignore",
    "content": "**\n!dist_linux/**\n!dist_linux_arm64/**\n!build/package/docker/.ds.container.d3e2c84f976743bdb92a7044ef12e381\n**/.DS_Store\n**/*.command\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]\npatreon: dockerslim\nopen_collective: docker-slim\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: docker-slim\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "Expected Behavior\n=================\n\n\n\n---\nActual Behavior\n=================\n\n\n\n---\nSteps to Reproduce the Problem\n===============================\n<!---\nOpen an issue and provide enough cotext information to \nrepro the condition. Don't worry if it's not possible to \nreproduce (reliably). Submit an issue anyways including \nthe information you do have. The version information \nshould be provided in all bug reports.\n--> \n\n  1.\n  1.\n  1.\n\n---\nSpecifications\n=================\n  - Version:\n  - Platform:\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "[Fixes-###](https://github.com/docker-slim/docker-slim/issues/###)\n==================================================================\n\nWhat\n===============\n\n\nWhy\n===============\n\n\nHow Tested\n===============\n\n\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "---\nversion: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n  - package-ecosystem: \"gitsubmodule\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\"\n"
  },
  {
    "path": ".github/workflows/acceptance-testing-bats.yml",
    "content": "name: Acceptance testing (using bats tests)\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n    types: [opened, synchronize, closed]\njobs:\n  test:\n    strategy:\n      matrix:\n        go: ['1.21']\n    runs-on: 'ubuntu-latest'\n    steps:\n      - uses: actions/checkout@v6.0.2\n        with:\n          fetch-depth: 0\n          submodules: recursive\n\n      - uses: actions/setup-go@v6.3.0\n        with:\n          go-version: ${{ matrix.go }}\n\n      - name: Build Slim (quick dev)\n        run: make build_dev\n\n      - name: Run the bats test suite\n        run: ./test/bats/bin/bats test/debug.bats\n"
  },
  {
    "path": ".github/workflows/acceptance-testing-e2e.yml",
    "content": "name: Acceptance testing (using e2e framework and examples)\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n    types: [opened, synchronize, closed]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check out slimtoolkit/slim repo\n        uses: actions/checkout@v6.0.2\n\n      - name: Set up Go development environment\n        uses: actions/setup-go@v6.3.0\n        with:\n          go-version: '1.21.4'\n\n      - name: Build Slim (multi-arch)\n        run: make build\n\n      - name: Upload Slim app binaries (Linux, amd64)\n        uses: actions/upload-artifact@v7.0.0\n        with:\n          name: dist_linux\n          path: dist_linux\n          retention-days: 1\n\n      - name: Upload Slim app binaries (Linux, arm64)\n        uses: actions/upload-artifact@v7.0.0\n        with:\n          name: dist_linux_arm64\n          path: dist_linux_arm64\n          retention-days: 1\n\n      - name: Upload Slim app binaries (Linux, arm)\n        uses: actions/upload-artifact@v7.0.0\n        with:\n          name: dist_linux_arm\n          path: dist_linux_arm\n          retention-days: 1\n\n      - name: Upload Slim app binaries (macOS, amd64)\n        uses: actions/upload-artifact@v7.0.0\n        with:\n          name: dist_mac\n          path: dist_mac\n          retention-days: 1\n\n  # Run sensor tests using the e2e testing framework.\n  test-sensor-e2e:\n    needs: build\n    strategy:\n      matrix:\n        os:\n          # macos runners don't support docker yet\n          - ubuntu-latest\n        include:\n          - os: ubuntu-latest\n            bin_artifacts: dist_linux\n    runs-on: ${{ matrix.os }}\n    steps:\n      - name: Check out slimtoolkit/slim repo\n        uses: actions/checkout@v6.0.2\n\n      - name: Set up Go development environment\n        uses: actions/setup-go@v6.3.0\n        with:\n          go-version: '1.21.4'\n\n      - name: Download Slim app binaries\n        uses: actions/download-artifact@v8.0.0\n        with:\n          name: ${{ matrix.bin_artifacts }}\n          path: bin\n\n      - name: Fix Slim app binaries permissions\n        run: chmod a+x bin/*\n\n      - name: Add Slim bin folder to $PATH\n        run: echo \"${GITHUB_WORKSPACE}/bin\" >> $GITHUB_PATH\n\n      - name: Run sensor e2e tests\n        timeout-minutes: 60\n        run: make test-e2e-sensor\n\n  # Run full-cycle tests (ab)using the slimtoolkit/examples repository.\n  test-full-e2e:\n    needs: build\n    strategy:\n      matrix:\n        os:\n          # macos runners don't support docker yet\n          - ubuntu-latest\n        suite:\n          - compose\n          - distroless\n          - dotnet\n          - elixir\n          - golang\n          - haskell\n          - http-probe\n          - image-edit\n          - java\n          - node\n          - php\n          - python\n          - ruby\n          - rust\n        include:\n          - os: ubuntu-latest\n            bin_artifacts: dist_linux\n    runs-on: ${{ matrix.os }}\n    steps:\n      - name: Check out slimtoolkit/slim repo\n        uses: actions/checkout@v6.0.2\n\n      - name: Check out slimtoolkit/examples repo\n        uses: actions/checkout@v6.0.2\n        with:\n          repository: slimtoolkit/examples\n          path: e2e\n\n      - name: Download Slim app binaries\n        uses: actions/download-artifact@v8.0.0\n        with:\n          name: ${{ matrix.bin_artifacts }}\n          path: bin\n\n      - name: Fix Slim app binaries permissions\n        run: chmod a+x bin/*\n\n      - name: Add Slim app bin folder to $PATH\n        run: echo \"${GITHUB_WORKSPACE}/bin\" >> $GITHUB_PATH\n\n      - name: Run all e2e tests from slimtoolkit/examples\n        timeout-minutes: 60\n        run: |\n          export DSLIM_LOG_LEVEL=debug\n          export DSLIM_SHOW_CLOGS=1\n          export DSLIM_EXAMPLES_DIR=e2e\n          make test-e2e-${{ matrix.suite }}\n"
  },
  {
    "path": ".github/workflows/codesee-arch-diagram.yml",
    "content": "name: CodeSee\n\npermissions: read-all\non:\n  push:\n    branches:\n      - master\n  pull_request_target:\n    types: [opened, synchronize, reopened]\njobs:\n  codesee:\n    runs-on: ubuntu-latest\n    continue-on-error: true\n    name: Analyze the repo with CodeSee\n    steps:\n      - uses: Codesee-io/codesee-action@v2\n        with:\n          codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/unit-testing.yml",
    "content": "name: Unit testing\non:\n  push:\n    branches:\n      - master\n  pull_request:\n    branches:\n      - master\n    types: [opened, synchronize, closed]\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Check out slimtoolkit/slim repo\n        uses: actions/checkout@v6.0.2\n\n      - name: Set up Go development environment\n        uses: actions/setup-go@v6.3.0\n        with:\n          go-version: '1.21.4'\n\n      - name: Run tests\n        run: make test\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n/docker-slim\n/slim\n/docker-slim-sensor\n/slim-sensor\n/dist_linux*/\n/dist_mac/\n/dist_mac_m1/\n/bin/\n/_gopath/\nslim.report.json\ndist_linux*.tar.gz\ndist_mac.zip\ndist_mac_m1.zip\n.idea\n*.swp\n*.swo\nslim.report.json\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"test/bats\"]\n\tpath = test/bats\n\turl = https://github.com/bats-core/bats-core.git\n[submodule \"test/test_helper/bats-support\"]\n\tpath = test/test_helper/bats-support\n\turl = https://github.com/bats-core/bats-support.git\n[submodule \"test/test_helper/bats-assert\"]\n\tpath = test/test_helper/bats-assert\n\turl = https://github.com/bats-core/bats-assert.git\n"
  },
  {
    "path": ".gitpod.yml",
    "content": "# List the start up tasks. You can start them in parallel in multiple terminals.\n# https://www.gitpod.io/docs/config-start-tasks/\ntasks:\n  - init: >\n      make tools build\n    command: make inspect\n\n# Enable prebuilds of your project to enable faster workspace start times.\n# https://www.gitpod.io/docs/prebuilds/#configure-the-github-app\ngithub:\n  prebuilds:\n    master: true\n    branches: true\n    pullRequests: true\n    pullRequestsFromForks: true\n    addCheck: true"
  },
  {
    "path": ".markdownlint.json",
    "content": "{\n  \"MD024\": false,\n  \"MD013\": false\n}\n"
  },
  {
    "path": ".vscode/launch.json",
    "content": "{\n    // Use IntelliSense to learn about possible attributes.\n    // Hover to view descriptions of existing attributes.\n    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n    \"version\": \"0.2.0\",\n    \"configurations\": [\n        {\n            \"name\": \"Launch Package\",\n            \"type\": \"go\",\n            \"request\": \"launch\",\n            \"mode\": \"auto\",\n            \"program\": \"${fileDirname}\",\n            \"args\": [\"registry\", \n            \"image-index-create\", \n            \"--image-index-name\", \n            \"dslim/slim-multi-test:latest\",\n            \"--image-name\", \"dslim/slim-arm:latest\",\n            \"--image-name\", \"dslim/slim:latest\" ]\n        }\n    ]\n}"
  },
  {
    "path": "ADOPTERS.md",
    "content": "# Adopters\n\nTBD\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Releases\n\n## 1.40.11 (2/2/2024)\n\n### New Features\n\n- New `build` command flags (`--include-dir-bins` and `--include-ssh-client`).\n- Simple `images` command to list container images.\n\n### Improvements\n\n- OCI image format support in `xray`.\n- Improved `xray` command reports to include object type information.\n\n### Bug Fixes\n\n- Fixes and dependency updates to support the new Docker Engine version (25.x).\n\n\n## 1.40.10 (1/17/2024)\n\n### Bug Fixes\n\n- Sensor artifact (post-)processing bug fix for additional PT generated artifacts.\n\n\n## 1.40.9 (1/15/2024)\n\n### Improvements\n\n- Added command parameter information to process events in `mondel`.\n- Enhanced `mondel` event capture to prevent event data loss on sensor shutdown.\n\n\n## 1.40.8 (1/7/2024)\n\n### New Features\n\n- New `vulnerability` command and the `epss` subcommand to lookup EPSS scores for vulnerabilities.\n- Simple `registry server` command to have a local OCI registry (thank you Sarvesh Raj, @sarveshraj, for your contribution!).\n- Simple `registry push` command to push local images to a registry.\n- Simple `images` command to list container images.\n- RPM packaging for the apps (thank you Rohan Jamadagni, @Rohansjamadagni, for your contribution!)\n\n### Improvements\n\n- Enhanced `registry pull` command to pull images from authenticated registries.\n- `quiet` mode improvements (WIP) to hide the standard execution context output when it's enabled.\n- `quiet` mode for the `images` command.\n- Interactive prompt updates to include the `images`, `registry` and `vulnerability` commands and a couple of global flags.\n- Monitor Data Event Log (mondel) enhancement to improve the write path.\n\n\n## 1.40.7 (12/9/2023)\n\n### New Features\n\n- Simple `registry image-index-create` command to create multi-architecture images.\n- Simple `images` command to list container images.\n\n### Improvements\n\n- Improved ptmon syscall handling.\n- Enhanced `mondel` events with timestamps and sequence numbers.\n- Extra docker socket validation checks.\n- Version info on exit/failure.\n- Temp container cleanup improvements.\n- ARM image build scripts for the containerized distribution.\n\n### Bug Fixes\n\n- Websocket http probe bug fix.\n- Various ptmod bug fixes.\n\n\n## 1.40.5/1.40.6 (11/2/2023)\n\n### New Features\n\n- Sensor `control` commands to control sensor execution when running in the standalone mode (first command: `stop-target-app`).\n- `xray` - detect system identities (users, groups) and their properties (`--detect-identities` flag, enabled by default).\n- `build` - Keep the OS/libc zoneinfo data (`--include-zoneinfo` flag, disabled by default).\n- `build`/`profile` - Mon(itor) Data Event Log (aka `mondel`) - optional data event log for sensor monitors to log/stream monitor events (`--enable-mondel` main app flag, `--mondel`/`-n` sensor flag(s)).\n\n### Improvements\n\n- `target-app-running` sensor lifecycle hook.\n- `build`/`profile`: `--env-file` to load env vars from a file.\n- `build`/`profile`: basic input validation to ignore malformed env var data for the `--env` flag.\n- `build`: Using internal output image builder by default (`--image-build-engine` flag)\n- Renamed the reverse engineered Dockerfile from `Dockerfile.fat` \nto `Dockerfile.reversed`\n\n### Bug Fixes\n\n- Various bug fixes\n\n\n## 1.40.4 (8/25/2023)\n\n### Improvements\n\n- Auto-complete in the interactive `prompt` mode for the target, namespace, pod and session flags\n- Interactive `debug` command terminal that runs as if you are connected directly to the target image you are debugging (enabled by default)\n- Basic sessions for `debug` command\n- Ability to show logs for the existing `debug` command sessions\n- More `debug` command flags (see README)\n- README docs updates for the `debug` command\n\n### Bug Fixes\n\n- Many `debug` command bug fixes\n\n## 1.40.3 (7/13/2023)\n\n### New Features\n\n- Kubernetes runtime support for the `debug` command\n- `appbom` command in the main app and `--appbom` flag in the sensor\n- `merge` command to merge two container images (optimized to merge two minified images).\n\n### Improvements\n\n- More `debug` command flags\n- README docs for the `debug` command\n- Ability to detect the Docker Desktop unix socket\n- Code and logging cleanup\n\n### Bug Fixes\n\n- Sensor volume fix for sensor symlinks (to address the Homebrew installed problems with sensor)\n- Various dependency updates to get security fixes\n\n## 1.40.2 (5/12/2023)\n\n### Improvements\n\n- New experimental `build` command flag to prevent the vulnerability scanners from discovering the metadata they need to identify the vulnerabilities (`--obfuscate-metadata`) inspired by the [`Malicious Compliance`](https://kccnceu2023.sched.com/event/1Hybu/malicious-compliance-reflections-on-trusting-container-scanners-ian-coldwater-independent-duffie-cooley-isovalent-brad-geesaman-ghost-security-rory-mccune-datadog) KubeCon EU 2023 talk\n\n### Bug Fixes\n\n- HEALTHCHECK instruction decoding enhancements to handle the data generated by buildah\n- fsutil format string bug fix\n\n## 1.40.1 (4/5/2023)\n\n### Improvements\n\n- New include flags for the `build` command (`--include-workdir`)\n- Debug/trace logging improvements\n\n### Bug Fixes\n\n- todo: add info\n\n## 1.40.0 (1/15/2023)\n\n### New Features\n\n- Base image metadata for xray\n- Basic support for multiple image build engines (`--image-build-engine`, `--image-build-arch` parameters)\n\n### Improvements\n\n- dockerfile reverse engineering updates\n- buildkit dockerfile instruction support\n- name change\n\n### Bug Fixes\n\n- todo: add info\n\n## 1.39.1 (11/12/2022)\n\n## 1.39.0 (10/24/2022)\n\n## 1.38.0 (8/27/2022)\n\n### New Features\n\n- Experimental 'debug' command\n- JSON console output format\n\n### Improvements\n\n- refactored http-probe-exec and http-probe-exec-file to be host-exec and host-exec-file (breaking change)\n\n### Bug Fixes\n\n- todo: add info\n\n## 1.37.6 (4/22/2022)\n\n### Improvements\n\n- Source image label in minified images\n- Full image path enhancements for container entry info\n\n### Bug Fixes\n\n- Traced application signal handling bugfix\n- Healthcheck instruction parsing bugfix\n\n## 1.37.5 (3/20/2022)\n\n### New Features\n\n- Experimental Node.js package include flag\n- Experimental Next.js(React.js) app include flags\n- Experimental Nuxt.js(Vue.js) app include flags\n- Ability to disable the ptrace data source\n\n## 1.37.4 (2/27/2022)\n\n### New Features\n\n- Container probe feature to use one of the compose services to test/probe the target container (`--container-probe-compose-svc` flag and `container.probe` continue-after mode)\n- Ability to override the container image name and/or tag when targetting a compose service (`--target-compose-svc-image` flag)\n- Ability to wait before executing the HTTP probes (`--http-probe-start-wait` flag)\n- Ability to wait before starting each compose service (`--compose-svc-start-wait` flag)\n- Basic FastCGI protocol support in HTTP probes (docs TBD)\n- New `registry` command and a basic `pull` subcommand\n- `--include-new` build flag to keep new files created by target during dynamic analysis\n- Supprot for stored global param in `slim.config.json`\n\n\n### Improvements\n\n- Improved containerized CI/CD environments support (`sensor-ipc-mode` and `sensor-ipc-endpoint` flags for `build` and `profile`)\n- Docker host detection improvements\n- Target container IP detection improvements\n- Not minifying onbuild base images by default\n- Not minifying already minified images\n- Cleanup container resources on exit\n- `include-cert-all` build flag enabled by default\n- Propagate logging flags to sensor\n- Not using default http probe if custom probes are already defined\n- Many compose related enhancements (volume lookup enhancements, compose image detection and error handling, etc)\n- Various monitoring engine enhancements\n- Migrate from urfave/cli/v1 to urfave/cli/v2\n- Dockerfile reverse engineering enhancements (HEALTHCHECK instruction support, improved RUN instruction reversing when ARGs are also used)\n\n## 1.37.3 (12/10/2021)\n\n### New Features\n\n- Install command / docker cli plugin install option (preview version)\n\n### Improvements\n\n- Container and compose link handling enhancements\n- Volume mounting enhancements\n- Static analysis improvements\n- Symlink handling improvements for builds\n- Collecting file check filesystem activity\n- Entrypoint/cmd override handling improvements\n\n### Bug Fixes\n\n- Volume mounting bug fixes for compose\n\n## 1.37.1/1.37.2 (11/7/2021)\n\n### New Features\n\n- Ability to pull images from private registries (`--registry-account`, `--registry-secret`, `--docker-config-path` flags)\n\n### Improvements\n\n- Additional flags for compose (`dep-include-target-compose-svc-deps`, `compose-env-nohost`, `compose-env-file`, `compose-workdir`, `compose-project-name`)\n- Variable substitution support in compose\n- Detect duplicates by default in xray\n- Resource cleanup when the build command exits\n- `delete-generated-fat-image` flag to cleanup the non-optimized images when `docker-slim` builds images from source/Dockerfile\n- Improved `maintainer` info collection for xray\n\n### Bug Fixes\n\n- Volume mounting bug fixes for compose\n\n## 1.37.0 (9/23/2021)\n\n### New Features\n\n- Experimental docker-compose support for the build command\n- Include cert flags to make it easier to keep certificate data in the optimized images\n\n### Improvements\n\n- Install script\n\n## 1.36.4\n\n## 1.36.3 (8/30/2021)\n\n## 1.36.2 (8/5/2021)\n\n## 1.36.1 (6/20/2021)\n\n### Improvements\n\n- `--cro-host-config-file`, `--cro-sysctl` and `--cro-shm-size` flags.\n- M1 builds.\n\n### Bug Fixes\n\n- xray and sensor volume detection bug fixes.\n\n### Improvements\n\n- Ability to detect additional shells.\n- Saving command report to /tmp directory if it's not possible to save it in the current working directory.\n- Printing tag information for build command.\n\n### Bug Fixes\n\n- Default `continue-after` value handling fix (remove `probe` mode if http probing is disabled).\n- Sensor not exiting when it's trying to copy a directory it already copied.\n\n## 1.36.0 (6/12/2021)\n\n### New Features\n\n- Ability to find duplicate files for xray (`--detect-duplicates`, `--show-duplicates`).\n- Ability to find all utf8 encoded files for xray using the `--detect-utf8` flag  (optionally dumping them to console, directory or tar file).\n- Ability to find the files with special permissions (`--show-special-perms`).\n- Ability to find all installed shells for xray.\n- Container entry information for xray with file detection.\n- Inherited image instructions (aka ONBUILD instructions) for xray.\n- More image level stats for xray.\n\n### Improvements\n\n- Multiple tags for the build command.\n- `--http-probe-off` flag for the build command to provide a shortcut to disable HTTP probing.\n- Flexible target image handling to use non-default tags if the `latest` tag doesn't exist and no explicit tag is provided.\n\n## 1.35.2 (5/2/2021)\n\n### New Features\n\n- `change-match-layers-only` xray flag to print only the layers that contain the matches.\n\n### Improvements\n\n- xray enhancement: printing to console by default for pattern or data matches.\n\n### Bug Fixes\n\n- Various xray command bug fixes.\n\n## 1.35.1 (4/27/2021)\n\n### Improvements\n\n- Ability to combine `probe` and `exec` `continue-after` modes\n\n### Bug Fixes\n\n- Various xray command bug fixes\n\n## 1.35.0 (4/14/2021)\n\n### New Features\n\n- Console color output (on by default; disable with `no-color`)\n- Loading http probe request data from separate files\n- Ability to execute external probe commands (`--http-probe-exec` and `--http-probe-exec-file` flags)\n- Ability to preserve original files in the target container discarding its test runtime data (`--preserve-path` and `--preserve-path-file`)\n- Ability to pull container images if they don't exist locally yet (`--pull` and `--show-plogs`)\n- File hashing for xray (`--hash-data`)\n- Additional flags to control the xray command executions (`--top-changes-max`, `--reuse-saved-image`)\n- Ability to match by file path, file data and file hash for xray (`--change-path value`, `--change-data value`, `--change-data-hash value`)\n\n### Improvements\n\n- Lots of additional container build flags (`--tag-fat`, `--cbo-add-host`, `--cbo-build-arg`, `--cbo-label`, `--cbo-target`, `--cbo-network`, `--cbo-cache-from`).\n- Additional container runtime flags (`--cro-runtime`)\n- `sigint` should kill the running container (#186)\n\n### Bug Fixes\n\n- Various xray image layer inspection bug fixes\n\n## 1.34.0 (1/29/2021)\n\n### New Features\n\n- New `xray` flags to control what layer change data to include in the generated reports (`layer-changes-max`, `all-changes-max`, `add-changes-max`, `modify-changes-max`, `delete-changes-max`)\n\n### Improvements\n\n- `host` network flag handling enhancements.\n- Returning non-zero exit codes on failures\n- Additional image checks to catch missing ENTRYPOINT/CMD instructions\n\n### Bug Fixes\n\n- Fixed container image listing bug that broke the `--target` value suggestions in the interactive prompt mode.\n\n## 1.33.0 (12/12/2020)\n\n### New Features\n\n- Ability to interact with the temporary containers using the `--exec` and `--exec-file` flags\n\n### Improvements\n\n- `npm` support enhancements (makes it possible to use `npm start` in Dockerfiles, which isn't recommended though)\n\n### Bug Fixes\n\n- Various bug fixes.\n\n## 1.32.0 (8/23/2020)\n\n### New Features\n\n- Mapping container ports to specific host ports analyzing image at runtime (`--publish-port` and `--publish-exposed-ports` flags)\n\n### Improvements\n\n- `seccomp` security profile generation capability updates\n- User namespace handling improvements (thanks to `@solarnz`)\n\n## 1.31.0 (8/13/2020)\n\n### New Features\n\n- Experimental HTTP probe command generation based on the API descriptions from the Swagger and OpenAPI specs (`--http-probe-apispec` and `--http-probe-apispec-file` flags)\n- Image metadata editing capabilities to add, remove and update the LABEL, VOLUME, EXPOSE, ENV and WORKDIR instructions (`--new-workdir`, `--new-expose`, `--new-label`, `--new-volume`, `--remove-volume`, `--remove-env`, `--remove-label`, `--remove-expose` and `--image-overrides` combined with `--expose`, `--workdir`, `--env`, `--volume`, `--label`, `--env`)\n\n### Improvements\n\n- Layer change details available in the `xray` command reports when the `--changes` flag is set.\n- System and engine information in the command reports to improve debugging\n- Ability to enable crawling for the HTTP probes specified using the `--http-probe-cmd` flag\n- Improved HTTP probe crawler documentation\n\n## 1.30.0 (7/27/2020)\n\n### New Features\n\n- `lint` command (initial Dockerfile linting capabilities with a basic set of checks)\n- HTTP probe crawler (automatically probes additional endpoints referenced in the processed targets; see the `--http-probe-crawl` and related flags)\n\n### Improvements\n\n- ARM64 support (need more people to test!)\n- `--http-probe-exit-on-failure` flag to exit execution when all HTTP probe calls fail\n- `--include-bin-file` and `--include-exe-file` flags to make it easier to specify multiple binaries and executables loading them from files\n- `xray` command report enhancements\n\n## 1.29.0 (3/18/2020)\n\n### New Features\n\n- Interactive CLI prompt\n\n### Improvements\n\n- `xray` command output improvements\n- Additional image data saved with the `xray` command reports (`--add-image-manifest` and `--add-image-config` flags)\n\n## 1.28.1 (3/9/2020)\n\n### Improvements\n\n- New `xray` parameters to control how much to show when it's printing the layer details (`--changes value` and `--layer value`)\n- Image history enhancements and more data saved in the xray command reports\n\n## 1.28.0 (3/6/2020)\n\n### New Features\n\n- `xray` command enhancements to show the detailed container image information including its layers and their files and directories (initial version).\n\n### Improvements\n\n- The `--exclude-pattern` `build` parameter to filter/exclude the artifacts in the optimized container.\n\n## 1.27.0 (2/28/2020)\n\n### New Features\n\n- Option to set permissions, user and group information for the artifacts included with the `--include-*` parameters.\n- Option to overwrite the permissions and ownership info in the optimized image using the new `--path-perms` and `path-perms-file` parameters.\n\n### Improvements\n\n- Option to run the containerized application using user and group information from the USER instruction.\n- Filter leftover PID files.\n- UX enhancements for the containers created using Dockerfiles.\n- Additional debugging information.\n\n### Bug Fixes\n\n- Support for special install directories on Linux (to prevent failures when `docker-slim` is trying to save its state).\n\n## 1.26.1 (11/28/2019)\n\n### Improvements\n\n- Saving command execution report, by default (`slim.report.json`).\n- CLI output UX enhancements.\n- Docker connect info checks.\n\n### Bug Fixes\n\n- Version check fixes when running in containers.\n\n## 1.26 (11/16/2019)\n\n### New Features\n\n- Run `docker-slim` in containers.\n- New distribution option ([`dslim/docker-slim`](https://hub.docker.com/r/dslim/docker-slim) image available in Docker Hub).\n- Archive `docker-slim` state into a separate Docker volume.\n\n### Improvements\n\n- Default to continuing `docker-slim` execution after the http probing step is done when http probing is enabled.\n- Improved IPC.\n- Improved seccomp and metadata artifact copy option.\n- Improved execution report.\n\n## 1.25.3 (8/4/2019)\n\n### New Features\n\n- Build minified images from `source` using the new `--from-dockerfile` build flag (see `README.md` for details).\n\n### Improvements\n\n- Custom HTTP POST probes support request bodies\n\n## 1.25.2 (7/21/2019)\n\n### New Features\n\n- Enhanced build command reports with additional container image metadata (using the global `--report` flag)\n- Ability to update the minified image Dockerfile instructions (using the --new-cmd, --new-entrypoint, --new-expose, --new-workdir, --new-env and --image-overrides flags)\n- Dockerfile volume support\n\n### Improvements\n\n- HTTP probes by default (you will have to disable HTTP probes if you don't need them)\n- Various UX enhancements to provide better CLI feedback and to avoid generating minified images that might not work\n\n### Bug Fixes\n\n- TTY bug fix caused by an external dependency (used to track update download progress)\n\n## 1.25.0 (4/23/2019)\n\n### New Features\n\n- Experimental ARM32 support\n- Easy way to keep a shell in your image (just pass `--include-shell` to the `build` command)\n- Easy way to include additional executables (`--include-exe` flag) and binary objects (`--include-bin` flag), which will also include their binary dependencies, so you don't have to explicitly include them all yourself\n- `update` command - now you can update `docker-slim` from `docker-slim`!\n- Current version checks to know if the installed release is out of date\n\n### Improvements\n\n- Improvements to handle complex `--entrypoint` and `--cmd` parameters\n\n## Previous Releases\n\n- Better Mac OS X support - when you install `docker-slim` to /usr/local/bin or other special/non-shared directories docker-slim will detect it and use the /temp directory to save its artifacts and to mount its sensor\n- HTTP Probing enhancements and new flags to control the probing process\n- Better Nginx support\n- Support for non-default users\n- Improved symlink handling\n- Better failure monitoring and reporting\n- The `--include-path-file` option to make it easier to load extra files you want to keep in your image\n- CentOS support\n- Enhancements for ruby applications with extensions\n- Save the docker-slim command results in a JSON file using the `--report` flag\n- Better support for applications with dynamic libraries (e.g., python compiled with `--enable-shared`)\n- Additional network related Docker parameters\n- Extended version information\n- Alpine image support\n- Ability to override ENV variables analyzing target image\n- Docker 1.12 support\n- User selected location to store DockerSlim state (global `--state-path` parameter).\n- Auto-generated seccomp profiles for Docker 1.10.\n- Python 3 support\n- Docker connect options\n- HTTP probe commands\n- Include extra directories and files in minified images\n"
  },
  {
    "path": "COMMUNITY_ACTIVITY_LOG.md",
    "content": "# Community Activity Log\n\n## Meetings/Events\n\nTBD\n\n## Engaging with CNCF TAGs\n\nTBD\n\n## Collaborating/Integrating with Other Projects (CNCF or Not)\n\nTBD\n\n## Conferences\n\nTBD\n\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to SlimToolkit\n\nIf you want to contribute submit a GitHub pull request or open an issue. Thank you!\n\n## TL;DR\n\nAny contribution is better than no contribution :-) Submit a [pull request](https://help.github.com/articles/using-pull-requests) or open an issue even if you are not sure or if you feel the contribution is not significant enough. If you want to accelerate the process you can follow the guidelines below.\n\nThere's a number of already open issues with the `good first issue` tag. Start there if you are new to the project. Explore the issues with the `help wanted` tag too. Help with any open issue is highly appreciated, of course.\n\nYou can also take a look at the [`ROADMAP`](ROADMAP.md) to get ideas for your contribution. Also take a look at the [`WISHLIST`](WISHLIST.md) doc, which includes even more potential improvements (that are not a part of the roadmap yet, but they are still valuable).\n\n## Code\n\nTo learn more about the code take a look at the `SlimToolkit Code` videos on ['YouTube'](https://www.youtube.com/channel/UCy7RHjJlaBhpCCbChrd8POA?sub_confirmation=1)\n\n## Guidelines\n\n### Reporting Issues\n\nOpen an issue and provide enough cotext information to repro the condition. Don't worry if it's not possible to reproduce (reliably). Submit an issue anyways including the information you do have. The version information should be provided in all bug reports.\n\n### Environment Setup\n\nSee the `BUILD PROCESS` section in the `README.md` file.\n\n### Enhancements\n\nTake a look at the open issues or feel free to create a new issue if what you'd like to do doesn't have an issue already. This includes documentation enhancements and design proposals too. When you submit your [pull request](https://help.github.com/articles/using-pull-requests) make sure to reference the issue.\n\n### Coding Standards\n\nThe coding standards are based on the [Golang community standards](https://github.com/golang/go/wiki/CodeReviewComments). Make sure to leverage the `scripts/src.fmt.sh` and `scripts/src.inspect.sh` helper scripts or their equivalent.\n\n### Dependencies\n\nTBD - information about adding dependencies\n\n### Testing\n\nYes :-)\n\n### Documentation\n\nYes :-)\n\n### Pull Requests\n\nStandard guidelines for [pull requests](https://help.github.com/articles/using-pull-requests)\n\n### Sign Your Code\n\nPlease certify your [Developer Certificate of Origin (DCO)](https://developercertificate.org/), by signing off your commit with `git commit -s` (use your real name).\n"
  },
  {
    "path": "GOVERNANCE.md",
    "content": "# Governance\n\nTBD\n"
  },
  {
    "path": "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 2015-2022 SlimToolkit.\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": "MAINTAINERS.md",
    "content": "# Maintainers\n\n- [Kyle Quest](https://github.com/kcq) (@kcq)\n- [Ivan Velichko](https://github.com/iximiuz) (@iximiuz)\n"
  },
  {
    "path": "Makefile",
    "content": "default: build_in_docker ## build docker-slim in docker by default\n\nbuild_in_docker:   ## build docker-slim in docker\n\trm -rfv bin\n\t'$(CURDIR)/scripts/docker-builder.run.sh'\n\nbuild_m1_in_docker:\n\trm -rfv bin\n\t'$(CURDIR)/scripts/docker-builder-m1.run.sh'\n\nbuild:  ## build docker-slim\n\t'$(CURDIR)/scripts/src.build.sh'\n\nbuild_m1:  ## build docker-slim\n\t'$(CURDIR)/scripts/src.build.m1.sh'\n\nbuild_dev:  ## build docker-slim for development (quickly), in bin/\n\t'$(CURDIR)/scripts/src.build.quick.sh'\n\nfmt:  ## format all golang files\n\t'$(CURDIR)/scripts/src.fmt.sh'\n\nhelp: ## prints out the menu of command options\n\t@awk -F ':.*?## ' '/^[a-zA-Z0-9_-]+:.*?## / {printf \"\\033[36m%-20s\\033[0m %s\\n\", $$1, $$2}' $(MAKEFILE_LIST)\n\ninspect: ## report suspicious constructs and linting errors\n\t'$(CURDIR)/scripts/src.inspect.sh'\n\ntools: ## install necessary tools\n\t'$(CURDIR)/scripts/tools.get.sh'\n\n## run unit tests\ntest: export GO_TEST_FLAGS ?=\ntest:\n\t'$(CURDIR)/scripts/src.test.sh'\n\nclean: ## clean up\n\t'$(CURDIR)/scripts/src.cleanup.sh'\n\ninclude $(CURDIR)/test/e2e-tests.mk\n\n.PHONY: default help build_in_docker build_m1_in_docker build build_m1 build_dev fmt inspect tools test clean\n"
  },
  {
    "path": "README.md",
    "content": "![SK](assets/images/dslim/logo.png)\n\n[![Gitter chat](https://img.shields.io/badge/chat-on%20gitter-brightgreen.svg?style=for-the-badge)](https://gitter.im/docker-slim/community)\n[![Discord chat](https://img.shields.io/static/v1.svg?label=chat&message=on%20discord&color=7389D8&style=for-the-badge)](https://discord.gg/9tDyxYS)\n[![Follow](https://img.shields.io/badge/follow-on%20twitter-%231DA1F2.svg?style=for-the-badge&logoColor=white)](https://twitter.com/DockerSlim)\n[![Youtube](https://img.shields.io/badge/-YouTube-red?style=for-the-badge&logo=youtube&logoColor=white)](https://www.youtube.com/channel/UCy7RHjJlaBhpCCbChrd8POA?sub_confirmation=1)\n\n[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-908a85?logo=gitpod&style=for-the-badge)](https://gitpod.io/#https://github.com/slimtoolkit/slim)\n\n[![Install SlimToolkit](https://img.shields.io/badge/install-slim-blue?style=for-the-badge)](https://github.com/slimtoolkit/slim#installation)\n[![Get Examples](https://img.shields.io/badge/slim-app%20examples-green?style=for-the-badge)](https://github.com/slimtoolkit/examples)\n\n[![Try Slim.AI SaaS](https://img.shields.io/badge/try-Slim.AI%20SaaS-red?style=for-the-badge)](https://portal.slim.dev/login?invitecode=invite.1s85zlfnYX0p5TT1XKja49pAHbL)\n\n\n\n# Optimize Your Experience with Containers. Make Your Containers Better, Smaller, More Secure and Do Less to Get There (free and open source!)\n\nNote that **DockerSlim** is now just **Slim** (**SlimToolkit** is the full name, so it's easier to find it online) to show its growing support for additional container tools and runtimes in the cloud native ecosystem.\n\n**Slim** is now a CNCF Sandbox project. It was created by [Kyle](https://github.com/kcq) [Quest](https://twitter.com/kcqon) and it's been improved by many [contributors](https://github.com/slimtoolkit/slim/graphs/contributors). The project is supported by Root.io (formerly known as Slim.AI).\n \nHere's how Slim and Root work together: Slim helps you build optimized containers, while Root.io automatically fixes vulnerabilities without disrupting your workflows. Use Slim's open source toolkit to optimize containers, then keep them secure with Root's automated vulnerability remediation – from optimization to continuous security in one seamless journey. Learn more at www.root.io.\n\n## Overview\n\nSlimToolkit allows developers to inspect, optimize and debug their containers using its `xray`, `lint`, `build`, `debug`, `run`, `images`, `merge`, `registry`, `vulnerability` (and other) commands. It simplifies and improves your developer experience building, customizing and using containers. It makes your containers better, smaller and more secure while providing advanced visibility and improved usability working with the original and minified containers.\n\nDon't change anything in your container image and minify it by up to 30x making it secure too! Optimizing images isn't the only thing it can do though. It can also help you understand and author better container images.\n\nKeep doing what you are doing. No need to change anything. Use the base image you want. Use the package manager you want. Don't worry about hand optimizing your Dockerfile. You shouldn't have to throw away your tools and your workflow to have small container images.\n\nDon't worry about manually creating Seccomp and AppArmor security profiles. You shouldn't have to become an expert in Linux syscalls, Seccomp and AppArmor to have secure containers. Even if you do know enough about it wasting time reverse engineering your application behavior can be time-consuming.\n\nSlimToolkit will optimize and secure your containers by understanding your application and what it needs using various analysis techniques. It will throw away what you don't need, reducing the attack surface of your container. What if you need some of those extra things to debug your container? You can use dedicated debugging side-car containers for that (more details below).\n\nSlimToolkit has been used with Node.js, Python, Ruby, Java, Go, Rust, Elixir and PHP (some app types) running on Ubuntu, Debian, CentOS, Alpine and even Distroless.\n\nNote that some application stacks do require advanced container probing to make sure that all dynamically loaded components are detected. See the `--http-probe*` flags for more details to know how you can define custom probe commands. In some cases you might also need to use the `--include-path` flag to make sure everything your application needs is included (e.g., `ubuntu.com` python SPA app container image [example](https://github.com/slimtoolkit/examples/tree/master/3rdparty/ubuntu-com) where the client side template files are explicitly included).\n\nIt's also a good idea to use your app/environment tests when you run the Slim app. See the `--continue-after` flag for more details about integrating your tests with the temporary container Slim creates when it's doing its dynamic analysis. Running tests in the target container is also an option, but it does require you to specify a custom ENTRYPOINT/CMD with a custom wrapper to start your app and to execute your tests.\n\n![Slim How](assets/images/docs/SlimHow.jpeg)\n\nInteractive CLI prompt screencast:\n\n[![asciicast](assets/images/dslim/DockerSlimIntPromptDemo.gif)](https://asciinema.org/a/311513)\n\nWatch this screencast to see how an application image is minified by more than 30x.\n\n[![asciicast](https://asciinema.org/a/rHqW8cbr3vXe0WxorHsD36n7V.png)](https://asciinema.org/a/rHqW8cbr3vXe0WxorHsD36n7V)\n\nWhen you run the `build` or `profile` commands in Slim it gives you an opportunity to interact with the temporary container it creates. By default, it will pause and wait for your input before it continues its execution. You can change this behavior using the `--continue-after` flag.\n\nIf your application exposes any web interfaces (e.g., when you have a web server or an HTTP API), you'll see the port numbers on the host machine you will need to use to interact with your application (look for the `port.list` and `target.port.info` messages on the screen). For example, in the screencast above you'll see that the internal application port 8000 is mapped to port 32911 on your host.\n\nNote that Slim will interact with your application for you when HTTP probing is enabled (enabled by default; see the `--http-probe*` flag docs for more details). Some web applications built with scripting languages like Python or Ruby require service interactions to load everything in the application. Enable HTTP probing unless it gets in your way.\n\nYou can also interact with the temporary container via a shell script or snippet using `--exec-file` or `--exec`. For example, you can create a container which is only capable of using curl.\n\n```bash\n>> docker pull archlinux:latest\n...\n\n>> slim build --target archlinux:latest --tag archlinux:curl --http-probe=false --exec \"curl checkip.amazonaws.com\"\n...\n\n>> docker run archlinux:curl curl checkip.amazonaws.com\n...\n\n>> docker images\narchlinux                 curl                ...        ...         17.4MB\narchlinux                 latest              ...        ...         467MB\n...\n```\n\n## Community\n\nFeel free to join any of these channels or just open a new [`Github issue`](https://github.com/slimtoolkit/slim/issues) if you want to chat or if you need help.\n\n* [`CNCF Slack channel`](https://cloud-native.slack.com/archives/C059QP1RH1S)\n* [`Discord server`](https://discord.gg/9tDyxYS)\n* [`Discussions`](https://github.com/slimtoolkit/slim/discussions)\n* [`Twitter`](https://twitter.com/SlimToolkit)\n\n## SlimToolkit on the Internet\n\n##### Books:\n* [`Everyone's Docker/Kubernetes`](https://www.amazon.co.jp/dp/429710461X) (Japanese)\n* [`Docker in Practice (2nd edition)`](https://www.amazon.com/Docker-Practice-Ian-Miell/dp/1617294802)\n* [`Docker/Kubernetes Security Practice Guide`](https://www.amazon.co.jp/dp/4839970505) (Japanese)\n\n\n## Minification Examples\n\nYou can find the examples in a separate repository: [https://github.com/slimtoolkit/examples](https://github.com/slimtoolkit/examples)\n\nNode.js application images:\n\n- from ubuntu:14.04 - 432MB => 14MB (minified by **30.85X**)\n- from debian:jessie - 406MB => 25.1MB (minified by **16.21X**)\n- from node:alpine - 66.7MB => 34.7MB (minified by **1.92X**)\n- from node:distroless - 72.7MB => 39.7MB (minified by **1.83X**)\n\nPython application images:\n\n- from ubuntu:14.04 - 438MB => 16.8MB (minified by **25.99X**)\n- from python:2.7-alpine - 84.3MB => 23.1MB (minified by **3.65X**)\n- from python:2.7.15 - 916MB => 27.5MB (minified by **33.29X**)\n- from centos:7 - 647MB => 23MB (minified by **28.57X**)\n- from centos/python-27-centos7 - 700MB => 24MB (minified by **29.01X**)\n- from python2.7:distroless - 60.7MB => 18.3MB (minified by **3.32X**)\n\nRuby application images:\n\n- from ubuntu:14.04 - 433MB => 13.8MB (minified by **31.31X**)\n- from ruby:2.2-alpine - 319MB => 27MB (minified by **11.88X**)\n- from ruby:2.5.3 - 978MB => 30MB (minified by **32.74X**)\n\nGo application images:\n\n- from golang:latest - 700MB => 1.56MB (minified by **448.76X**)\n- from ubuntu:14.04 - 531MB => 1.87MB (minified by **284.10X**)\n- from golang:alpine - 258MB => 1.56MB (minified by **165.61X**)\n- from centos:7 - 615MB => 1.87MB (minified by **329.14X**)\n\nRust application images:\n\n- from rust:1.31 - 2GB => 14MB (minified by **147.16X**)\n\nJava application images:\n\n- from ubuntu:14.04 - 743.6 MB => 100.3 MB\n\nPHP application images:\n\n- from php:7.0-cli - 368MB => 26.6MB (minified by **13.85X**)\n\nHaskell application images:\n\n- (Scotty service) from haskell:8 - 2.09GB => 16.6MB (minified by **125.32X**)\n- (Scotty service) from haskell:7 - 1.5GB => 21MB (minified by 71X)\n\nElixir application images:\n\n- (Phoenix service) from elixir:1.6 - 1.1 GB => 37 MB (minified by **29.25X**)\n\n---\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n- [RECENT UPDATES](#recent-updates)\n- [INSTALLATION](#installation)\n- [BASIC USAGE INFO](#basic-usage-info)\n- [COMMANDS](#commands)\n- [USAGE DETAILS](#usage-details)\n  - [`LINT` COMMAND OPTIONS](#lint-command-options)\n  - [`XRAY` COMMAND OPTIONS](#xray-command-options)\n  - [`BUILD` COMMAND OPTIONS](#build-command-options)\n  - [`DEBUG` COMMAND OPTIONS](#debug-command-options)\n  - [`RUN` COMMAND OPTIONS](#run-command-options)\n  - [`REGISTRY` COMMAND OPTIONS](#registry-command-options)\n  - [`VULNERABILITY` COMMAND OPTIONS](#vulnerability-command-options)\n- [RUNNING CONTAINERIZED](#running-containerized)\n- [DOCKER CONNECT OPTIONS](#docker-connect-options)\n- [HTTP PROBE COMMANDS](#http-probe-commands)\n- [DEBUGGING MINIFIED CONTAINERS](#debugging-minified-containers)\n- [MINIFYING COMMAND LINE TOOLS](#minifying-command-line-tools)\n- [QUICK SECCOMP EXAMPLE](#quick-seccomp-example)\n- [USING AUTO-GENERATED SECCOMP PROFILES](#using-auto-generated-seccomp-profiles)\n- [ORIGINAL DEMO VIDEO](#original-demo-video)\n- [DEMO STEPS](#demo-steps)\n- [FAQ](#faq)\n  - [Is it safe for production use?](#is-it-safe-for-production-use)\n  - [How can I contribute if I don't know Go?](#how-can-i-contribute-if-i-dont-know-go)\n  - [What's the best application for Slim?](#whats-the-best-application-for-slim)\n  - [Can I use Slim with dockerized command line tools?](#can-i-use-slim-with-dockerized-command-line-tools)\n  - [What if my Docker images uses the USER command?](#what-if-my-docker-images-uses-the-user-command)\n  - [Nginx fails in my minified image](#nginx-fails-in-my-minified-image)\n  - [Slim fails with a 'no permission to read from' error](#slim-fails-with-a-no-permission-to-read-from-error)\n- [BUILD PROCESS](#build-process)\n  - [Build Steps](#build-steps)\n- [CONTRIBUTING](#contributing)\n- [DESIGN](#design)\n  - [CORE CONCEPTS](#core-concepts)\n  - [DYNAMIC ANALYSIS OPTIONS](#dynamic-analysis-options)\n  - [SECURITY](#security)\n  - [CHALLENGES](#challenges)\n- [ORIGINS](#origins)\n- [MINIFIED IMAGES ON DOCKER HUB](#minified-images-on-docker-hub)\n- [LICENSE](#license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n## RECENT UPDATES\n\nLatest version: `1.40.11` (`2/2/2024`)\n\nThe 1.40.11 version adds support for the latest Docker Engine version, improves `xray` reports and adds new `build` command flags (`--include-dir-bins` and `--include-ssh-client`).\n\nFor more info about the latest release see the [`CHANGELOG`](CHANGELOG.md).\n\n\n## INSTALLATION\n\nIf you already have Slim installed use the `update` command to get the latest version:\n\n```\nslim update\n```\n\n### Downloads\n\n1. Download the zip package for your platform.\n\n   - [Latest Mac binaries](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac.zip) (`curl -L -o ds.zip https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac.zip`)\n\n   - [Latest Mac M1 binaries](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac_m1.zip) (`curl -L -o ds.zip https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac_m1.zip)`)\n\n   - [Latest Linux binaries](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux.tar.gz) (`curl -L -o ds.tar.gz https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux.tar.gz`)\n\n   - [Latest Linux ARM binaries](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm.tar.gz) (`curl -L -o ds.tar.gz https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm.tar.gz`)\n\n   - [Latest Linux ARM64 binaries](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm64.tar.gz) (`curl -L -o ds.tar.gz https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm64.tar.gz`)\n\n2. Unzip the package and optionally move it to your bin directory.\n\nLinux (for non-intel replace `dist_linux` with the platform-specific extracted path):\n```\ntar -xvf ds.tar.gz\nmv  dist_linux/slim /usr/local/bin/\nmv  dist_linux/slim-sensor /usr/local/bin/\n```\nMac:\n```\nunzip ds.zip\nmv  dist_mac/slim /usr/local/bin/\nmv  dist_mac/slim-sensor /usr/local/bin/\n```\n\n3. Add the location where you unzipped the package to your PATH environment variable (optional).\n\nIf the directory where you extracted the binaries is not in your PATH then you'll need to run your Slim app binary from that directory.\n\n#### Scripted Install\n\nYou can also use this script to install the current release of Slim on Linux (x86 and ARM) and macOS (x86 and Apple Silicon)\n\n```bash\ncurl -sL https://raw.githubusercontent.com/slimtoolkit/slim/master/scripts/install-slim.sh | sudo -E bash -\n```\n\n### Homebrew\n\n```\nbrew install docker-slim\n```\n\nThe Homebrew installer: https://formulae.brew.sh/formula/docker-slim\n\n### Docker\n\n```\ndocker pull dslim/slim\n```\n\nSee the [RUNNING CONTAINERIZED](#running-containerized) section for more usage info.\n\n### SaaS\n\nPowered by Slim. It will help you understand and troubleshoot your application containers and a lot more. If you use the `xray` command you'll want to try the SaaS. Understanding image changes is easy with its container diff capabilities. Connect your own registry and you can do the same with your own containers. Try it [here](https://portal.slim.dev/login?invitecode=invite.1s85zlfnYX0p5TT1XKja49pAHbL) without installing anything locally.\n\n\n## BASIC USAGE INFO\n\n`slim [global flags] [xray|build|profile|run|debug|lint|merge|images|registry|vulnerability|update|version|appbom|help] [command-specific flags] <IMAGE_ID_OR_NAME>`\n\nIf you don't specify any command `slim` will start in the interactive prompt mode.\n\n### COMMANDS\n\n- `xray` - Performs static analysis for the target container image (including 'reverse engineering' the Dockerfile for the image). Use this command if you want to know what's inside of your container image and what makes it fat.\n- `lint` - Analyzes container instructions in Dockerfiles (Docker image support is WIP)\n- `build` - Analyzes, profiles and optimizes your container image generating the supported security profiles. This is the most popular command.\n- `debug` - Debug the running target container. This command is useful for troubleshooting running containers created from minimal/minified or regular container images.\n- `registry` - Execute registry operations (`pull`, `push`, `copy`, `server`).\n- `profile` - Performs basic container image analysis and dynamic container analysis, but it doesn't generate an optimized image.\n- `run` - Runs one or more containers (for now runs a single container similar to `docker run`)\n- `merge` - Merge two container images (optimized to merge minified images).\n- `images` - Get information about container images (example: `slim --quiet images`).\n- `vulnerability` - Execute vulnerability related tools and operations (`epss`).\n- `version` - Shows the version information.\n- `appbom` - Shows the application BOM (app composition/dependencies).\n- `update` - Updates Slim to the latest version.\n- `help` - Show the available commands and global flags\n\nExample: `slim build my/sample-app`\n\nSee the `USAGE DETAILS` section for more details. Run `slim help` to get a high level overview of the available commands. Run `slim COMMAND_NAME` without any parameters and you'll get more information about that command (e.g., `slim build`).\n\nIf you run `slim` without any parameters you'll get an interactive prompt that will provide suggestions about the available commands and flags. `Tabs` are used to show the available options, to autocomplete the parameters and to navigate the option menu (which you can also do with Up and Down arrows). `Spaces` are used to move to the next parameter and `Enter` is used to run the command. For more info about the interactive prompt see [`go-prompt`](https://github.com/c-bata/go-prompt).\n\n## USAGE DETAILS\n\n`slim [global options] command [command options] <target image ID or name>`\n\nCommands:\n\n- `xray` - Show what's in the container image and reverse engineer its Dockerfile\n- `lint` - Lint the target Dockerfile (or image, in the future)\n- `build` - Analyze the target container image along with its application and build an optimized image from it\n- `debug` - Debug the running target container. This command is useful for troubleshooting running containers created from minimal/minified or regular container images.\n- `registry` - Execute registry operations (`pull`, `push`, `copy`, `server`).\n- `profile` - Collect fat image information and generate a fat container report\n- `merge` - Merge two container images (optimized to merge minified images)\n- `images` - Get information about container images.\n- `vulnerability` - Execute vulnerability related tools and operations (`epss`).\n- `appbom` - Shows the application BOM (app composition/dependencies)\n- `version` - Show app and docker version information\n- `update` - Update the app\n- `help` - Show help info\n\nGlobal options:\n\n- `--report` - command report location (target location where to save the executed command results; `slim.report.json` by default; set it to `off` to disable)\n- `--check-version` - check if the current version is outdated\n- `--version` - print the version\n- `--debug` - enable debug logs\n- `--verbose` - enable info logs\n- `--log-level` - set the logging level ('debug', 'info', 'warn' (default), 'error', 'fatal', 'panic')\n- `--log-format` - set the format used by logs ('text' (default), or 'json')\n- `--crt-api-version` - Container runtime API version\n- `--quiet` - less verbose CLI execution mode\n- `--output-format` - set the output format to use ('text' (default), or 'json')\n- `--log` - log file to store logs\n- `--host` - Docker host address or socket (prefix with `tcp://` or `unix://`)\n- `--tls` - use TLS connecting to Docker\n- `--tls-verify` - do TLS verification\n- `--tls-cert-path` - path to TLS cert files\n- `--state-path value` - Slim state base path (must set it if the Slim binaries are not in a writable directory!)\n- `--archive-state` - Archives Slim state to the selected Docker volume (default volume - `slim-state`). By default, enabled when Slim is running in a container (disabled otherwise). Set it to `off` to disable explicitly.\n- `--in-container` - Set it to true to explicitly indicate that Slim is running in a container (if it's not set Slim will try to analyze the environment where it's running to determine if it's containerized)\n\nTo disable the version checks set the global `--check-version` flag to `false` (e.g., `--check-version=false`) or you can use the `DSLIM_CHECK_VERSION` environment variable.\n\n### `LINT` COMMAND OPTIONS\n\n- `--target` - target Dockerfile path (or Docker image, in the future; if you don't use this flag you must specify the target as the argument to the command)\n- `--target-type` - explicitly specify the command target type (values: dockerfile, image)\n- `--skip-build-context` - don't try to analyze build context\n- `--build-context-dir` - explicitly specify the build context directory\n- `--skip-dockerignore` - don't try to analyze .dockerignore\n- `--include-check-label` - include checks with the selected label key:value\n- `--exclude-check-label` - exclude checks with the selected label key:value\n- `--include-check-id` - check ID to include\n- `--include-check-id-file` - file with check IDs to include\n- `--exclude-check-id` - check ID to exclude\n- `--exclude-check-id-file` - file with check IDs to exclude\n- `--show-nohits` - show checks with no matches\n- `--show-snippet` - show check match snippet (default value: true)\n- `--list-checks` - list available checks (don't need to specify the target flag if you just want to list the available checks)\n\n### `XRAY` COMMAND OPTIONS\n\n- `--target` - Target container image (name or ID)\n- `--pull` - Try pulling target if it's not available locally (default: false).\n- `--docker-config-path` - Set the docker config path used to fetch registry credentials (used with the `--pull` flag).\n- `--registry-account` - Account to be used when pulling images from private registries (used with the `--pull` flag).\n- `--registry-secret` - Account secret to be used when pulling images from private registries (used with the `--pull` and `--registry-account` flags).\n- `--show-plogs` - Show image pull logs (default: false).\n- `--changes value` - Show layer change details for the selected change type (values: none, all, delete, modify, add).\n- `--changes-output value` - Where to show the changes (values: all, report, console).\n- `--layer value` - Show details for the selected layer (using layer index or ID)\n- `--add-image-manifest` - Add raw image manifest to the command execution report file\n- `--add-image-config` - Add raw image config object to the command execution report file\n- `--layer-changes-max` - Maximum number of changes to show for each layer\n- `--all-changes-max` - Maximum number of changes to show for all layers\n- `--add-changes-max` - Maximum number of `add` changes to show for all layers\n- `--modify-changes-max` - Maximum number of `modify` changes to show for all layers\n- `--delete-changes-max` - Maximum number of `delete` changes to show for all layers\n- `--change-path value` - Include changes for the files that match the path pattern (Glob/Match in Go and **). Value formats: `<path pattern>` | `dump:<output type>:<path pattern>` | `::<path pattern>` where `output type` is `console` or a directory name. If `value` starts with `dump:` the match will be 'dumped' to the selected `output type`. [can use this flag multiple times]\n- `--change-data value` - Include changes for the files that match the data pattern (regex). Value formats: `<data regex>` | `dump:<output type>:<path pattern>:<data regex>` | `::<path pattern>:<data regex>` | `:::<data regex>` where `output type` is `console` or a directory name. If `value` starts with `dump:` the match will be 'dumped' to the selected `output type`. [can use this flag multiple times]\n- `--change-data-hash value` - Include changes for the files that match the provided data hashes (sha1). Value formats: `<sha1 hash>` | `dump:<output type>:<sha1 hash>` | `::<sha1 hash>` where `output type` is `console` or a directory name. If `value` starts with `dump:` the match will be 'dumped' to the selected `output type`. [can use this flag multiple times]\n- `--reuse-saved-image` - Reuse saved container image (default: true).\n- `--top-changes-max` - Maximum number of top changes to track (default: 20).\n- `--hash-data` - Generate file data hashes (default: false).\n- `--detect-duplicates` - Detect duplicate files based on their hashes (default: true).\n- `--show-duplicates` - Show all discovered duplicate file paths (default: false).\n- `--show-special-perms` - Show files with special permissions (setuid,setgid,sticky) (default: true)\n- `--detect-utf8` - Detect utf8 files and optionally extract the discovered utf8 file content (possible values: \"true\" or \"dump\" or \"dump:output_target.tgz\" or \"dump:output_target.tgz::max_size_bytes\" or \"dump:output_target.tgz:::max_size_bytes\").\n- `--detect-all-certs` - Detect all certificate files\n- `--detect-all-cert-pks` - Detect all certificate private key files\n- `--detect-identities` - Detect system identities (users, groups) and their properties (default: true)\n- `--change-match-layers-only` - Show only layers with change matches (default: false).\n- `--export-all-data-artifacts` - TAR archive file path to export all text data artifacts (if value is set to `.` then the archive file path defaults to `./data-artifacts.tar`)\n- `--remove-file-artifacts` - Remove file artifacts when command is done (note: you'll loose the reverse engineered Dockerfile)\n\nChange Types:\n\n- `none` - Don't show any file system change details in image layers (the top changes from the corresponding layer are still shown)\n- `all` - Show all file system change details in image layers\n- `delete` - Show only `delete` file system change details in image layers\n- `modify` - Show only `modify` file system change details in image layers\n- `add` - Show only 'add' file system change details in image layers\n\nIn the interactive CLI prompt mode you must specify the target image using the `--target` flag while in the traditional CLI mode you can use the `--target` flag or you can specify the target image as the last value in the command.\n\n### `BUILD` COMMAND OPTIONS\n\n- `--target` - Target container image (name or ID). It's an alternative way to provide the target information. The standard way to provide the target information is by putting as the last value in the `build` command CLI call.\n- `--pull` - Try pulling target if it's not available locally (default: false).\n- `--docker-config-path` - Set the docker config path used to fetch registry credentials (used with the `--pull` flag).\n- `--registry-account` - Account to be used when pulling images from private registries (used with the `--pull` flag).\n- `--registry-secret` - Account secret to be used when pulling images from private registries (used with the `--pull` and `--registry-account` flags).\n- `--show-plogs` - Show image pull logs (default: false).\n\n- `--compose-file` - Load container info from selected compose file\n- `--target-compose-svc` - Target service from compose file\n- `--target-compose-svc-image` - Override the container image name and/or tag when targeting a compose service using the target-compose-svc parameter (format: tag_name or image_name:tag_name)\n- `--target-compose-svc-no-ports` - Do not publish ports for target service from compose file\n- `--dep-exclude-compose-svc-all` - Do not start any compose services as target dependencies\n- `--dep-include-compose-svc` - Include specific compose service as a target dependency (only selected services will be started)\n- `--dep-exclude-compose-svc` - Exclude specific service from the compose services that will be started as target dependencies\n- `--dep-include-compose-svc-deps` - Include all dependencies for the selected compose service (excluding the service itself) as target dependencies\n- `--dep-include-target-compose-svc-deps` - Include all dependencies for the target compose service (excluding the service itself) as target dependencies. This is a shortcut flag to avoid repeating the service name (it's a pretty long flag name though :-))\n- `--compose-svc-start-wait` - Number of seconds to wait before starting each compose service\n- `--compose-net` - Attach target to the selected compose network(s) otherwise all networks will be attached\n- `--compose-env-nohost` - Don't include the env vars from the host to compose\n- `--compose-env-file` - Load compose env vars from file (host env vars override the values loaded from this file)\n- `--compose-workdir` - Set custom work directory for compose\n- `--compose-project-name` - Use custom project name for compose\n- `--container-probe-compose-svc` - Container test/probe service from compose file\n- `--prestart-compose-svc` - placeholder for now\n- `--poststart-compose-svc` - placeholder for now\n- `--http-probe` - Enables/disables HTTP probing (ENABLED by default; you have to disable the probe if you don't need it by setting the flag to `false`: `--http-probe=false`)\n- `--http-probe-off` - Alternative way to disable HTTP probing\n- `--http-probe-cmd` - Additional HTTP probe command [can use this flag multiple times]\n- `--http-probe-cmd-file` - File with user defined HTTP probe commands\n- `--http-probe-start-wait` - Number of seconds to wait before starting HTTP probing\n- `--http-probe-retry-count` - Number of retries for each HTTP probe (default value: 5)\n- `--http-probe-retry-wait` - Number of seconds to wait before retrying HTTP probe (doubles when target is not ready; default value: 8)\n- `--http-probe-ports` - Explicit list of ports to probe (in the order you want them to be probed; excluded ports are not probed!)\n- `--http-probe-full` - Do full HTTP probe for all selected ports (if false, finish after first successful scan; default value: false)\n- `--http-probe-exit-on-failure` - Exit when all HTTP probe commands fail (default value: true)\n- `--http-probe-crawl` - Enable crawling for the default HTTP probe command (default value: true)\n- `--http-crawl-max-depth` - Max depth to use for the HTTP probe crawler (default value: 3)\n- `--http-crawl-max-page-count` - Max number of pages to visit for the HTTP probe crawler (default value: 1000)\n- `--http-crawl-concurrency` - Number of concurrent workers when crawling an HTTP target (default value: 10)\n- `--http-max-concurrent-crawlers` - Number of concurrent crawlers in the HTTP probe (default value: 1)\n- `--http-probe-apispec` - Run HTTP probes for API spec where the value represents the target path where the spec is available (supports Swagger 2.x and OpenAPI 3.x) [can use this flag multiple times]\n- `--http-probe-apispec-file` - Run HTTP probes for API spec from file (supports Swagger 2.x and OpenAPI 3.x) [can use this flag multiple times]\n- `--http-probe-exec` - App to execute when running HTTP probes. [can use this flag multiple times]\n- `--http-probe-exec-file` - Apps to execute when running HTTP probes loaded from file.\n- `--publish-port` - Map container port to host port analyzing image at runtime to make it easier to integrate external tests (format => port | hostPort:containerPort | hostIP:hostPort:containerPort | hostIP::containerPort )[can use this flag multiple times]\n- `--publish-exposed-ports` - Map all exposed ports to the same host ports analyzing image at runtime (default value: false)\n- `--show-clogs` - Show container logs (from the container used to perform dynamic inspection)\n- `--show-blogs` - Show build logs (when the minified container is built)\n- `--copy-meta-artifacts` - Copy meta artifacts to the provided location\n- `--remove-file-artifacts` - Remove file artifacts when command is done (note: you'll loose autogenerated Seccomp and Apparmor profiles unless you copy them with the `copy-meta-artifacts` flag or if you archive the state)\n- `--tag` - Use a custom tag for the generated image (instead of the default value: `<original_image_name>.slim`) [can use this flag multiple times if you need to create additional tags for the optimized image]\n- `--entrypoint` - Override ENTRYPOINT analyzing image at runtime\n- `--cmd` - Override CMD analyzing image at runtime\n- `--mount` - Mount volume analyzing image (the mount parameter format is identical to the `-v` mount command in Docker) [can use this flag multiple times]\n- `--include-path` - Include directory (and what's in it) or file from image [can use this flag multiple times] (optionally overwriting the artifact's permissions, user and group information; full format: `targetPath:octalPermFlags#uid#gid`, minimal format: `targetPath` ; see the non-default USER FAQ section for more details)\n- `--include-path-file` - Load directory or file includes from a file (optionally overwriting the artifact's permissions, user and group information; full format: `targetPath:octalPermFlags#uid#gid`, minimal format: `targetPath` ; see the non-default USER FAQ section for more details)\n- `--include-paths-creport-file` - Keep files from the referenced creport\n- `--include-bin value` - Include binary from image (executable or shared object using its absolute path)\n- `--include-bin-file` - Load shared binary file includes from a file (similar to `--include-path-file`)\n- `--include-dir-bins value` - Include binaries in the target directory and include their dependencies, which could be in other locations (executables or shared objects using its absolute path)\n- `--include-exe value` - Include executable from image (by executable name)\n- `--include-exe-file` - Load executable file includes from a file (similar to `--include-path-file`)\n- `--include-shell` - Include basic shell functionality (default value: false)\n- `--include-workdir` - Keep files in working directory (default value: false)\n- `--include-cert-all` - Keep all discovered cert files (default: true)\n- `--include-cert-bundles-only` - Keep only cert bundles\n- `--include-cert-dirs` - Keep known cert directories and all files in them\n- `--include-cert-pk-all` - Keep all discovered cert private keys\n- `--include-cert-pk-dirs` - Keep known cert private key directories and all files in them\n- `--include-new` - Keep new files created by target during dynamic analysis (default value: true)\n- `--include-oslibs-net` - Keep the common networking OS libraries (default value: true)\n- `--include-ssh-client` - Keep the common SSH client components and configs\n- `--include-zoneinfo` - Keep the OS/libc zoneinfo data (default value: false)\n- `--include-app-nuxt-dir` - Keep the root Nuxt.js app directory (default value: false)\n- `--include-app-nuxt-build-dir` - Keep the build Nuxt.js app directory (default value: false)\n- `--include-app-nuxt-dist-dir` - Keep the dist Nuxt.js app directory (default value: false)\n- `--include-app-nuxt-static-dir` - Keep the static asset directory for Nuxt.js apps (default value: false)\n- `--include-app-nuxt-nodemodules-dir` - Keep the node modules directory for Nuxt.js apps (default value: false)\n- `--include-app-next-dir` - Keep the root Next.js app directory (default value: false)\n- `--include-app-next-build-dir` - Keep the build directory for Next.js app (default value: false)\n- `--include-app-next-dist-dir` - Keep the static SPA directory for Next.js apps (default value: false)\n- `--include-app-next-static-dir` - Keep the static public asset directory for Next.js apps (default value: false)\n- `--include-app-next-nodemodules-dir` - Keep the node modules directory for Next.js apps (default value: false)\n- `--include-node-package` - Keep node.js package by name [can use this flag multiple times]\n- `--preserve-path` - Keep path from original image in its initial state (changes to the selected container image files when it runs will be discarded). [can use this flag multiple times]\n- `--preserve-path-file` - File with paths to keep from original image in their original state (changes to the selected container image files when it runs will be discarded).\n- `--path-perms` - Set path permissions/user/group in optimized image (format: `target:octalPermFlags#uid#gid` ; see the non-default USER FAQ section for more details)\n- `--path-perms-file` - File with path permissions to set (format: `target:octalPermFlags#uid#gid` ; see the non-default USER FAQ section for more details)\n- `--exclude-pattern` - Exclude path pattern ([Glob/Match in Go](https://golang.org/pkg/path/filepath/#Match) and `**`) from image (useful when `--include-path` keeps a directory and you need to exclude / filter out some of the files in that directory)\n- `--exclude-varlock-files` - Exclude the files in the var and run lock directory (default value: true)\n- `--exclude-mounts` - Exclude mounted volumes from image (default value: true)\n- `--label` - Override or add LABEL analyzing image at runtime [can use this flag multiple times]\n- `--volume` - Add VOLUME analyzing image at runtime [can use this flag multiple times]\n- `--env` - Add ENV analyzing target image at runtime [can use this flag multiple times]\n- `--env-file` - Load multiple environment variables from a file when analyzing target image at runtime.\n- `--workdir` - Override WORKDIR analyzing image at runtime\n- `--network` - Override default container network settings analyzing image at runtime\n- `--expose` - Use additional EXPOSE instructions analyzing image at runtime [can use this flag multiple times]\n- `--link` - Add link to another container analyzing image at runtime [can use this flag multiple times]\n- `--hostname` - Override default container hostname analyzing image at runtime\n- `--etc-hosts-map` - Add a host to IP mapping to /etc/hosts analyzing image at runtime [can use this flag multiple times]\n- `--container-dns` - Add a dns server analyzing image at runtime [can use this flag multiple times]\n- `--container-dns-search` - Add a dns search domain for unqualified hostnames analyzing image at runtime [can use this flag multiple times]\n- `--image-overrides` - Save runtime overrides in generated image (values is `all` or a comma delimited list of override types: `entrypoint`, `cmd`, `workdir`, `env`, `expose`, `volume`, `label`). Use this flag if you need to set a runtime value and you want to persist it in the optimized image. If you only want to add, edit or delete an image value in the optimized image use one of the `--new-*` or `--remove-*` flags (define below).\n- `--continue-after` - Select continue mode: `enter` | `signal` | `probe` | `exec` | `timeout-number-in-seconds` | `container.probe` (default value if http probes are disabled: `enter`). You can also select `probe` and `exec` together: `'probe&exec'` (make sure to use quotes around the two modes or the `&` will break the shell command).\n- `--dockerfile` - The source Dockerfile name to build the fat image before it's optimized.\n- `--tag-fat` - Custom tag for the fat image built from Dockerfile.\n- `--cbo-add-host` - Add an extra host-to-IP mapping in /etc/hosts to use when building an image (Container Build Option).\n- `--cbo-build-arg` - Add a build-time variable (Container Build Option).\n- `--cbo-label` - Add a label when building from Dockerfiles (Container Build Option).\n- `--cbo-target` - Target stage to build for multi-stage Dockerfiles (Container Build Option).\n- `--cbo-network` - Networking mode to use for the RUN instructions at build-time (Container Build Option).\n- `--cbo-cache-from` - Add an image to the build cache (Container Build Option).\n- `--cro-runtime` - Runtime to use with the created containers (Container Runtime Option).\n- `--cro-host-config-file` - File to load the Docker host configuration data (JSON format) to use when running the container. See the [HostConfig](https://pkg.go.dev/github.com/fsouza/go-dockerclient#HostConfig) struct definition from the `go-dockerclient` package for configuration details. Note that Slim will automatically add `SYS_ADMIN` to the list of capabilities and run the container in privileged mode, which are required to generate the seccomp profiles. The host config parameters specified using their standalone build or profile command flags overwrite the values in the host config file (volume binds are merged).\n- `--cro-sysctl` - Set namespaced kernel parameters in the created container (Container Runtime Option).\n- `--cro-shm-size` - Shared memory size for /dev/shm in the created container (Container Runtime Option).\n- `--use-local-mounts` - Mount local paths for target container artifact input and output (off, by default)\n- `--use-sensor-volume` - Sensor volume name to use (set it to your Docker volume name if you manage your own Slim sensor volume).\n- `--keep-tmp-artifacts` - Keep temporary artifacts when command is done (off, by default).\n- `--keep-perms` - Keep artifact permissions as-is (default: true)\n- `--run-target-as-user` - Run target app (in the temporary container) as USER from Dockerfile (true, by default)\n- `--new-entrypoint` - New ENTRYPOINT instruction for the optimized image\n- `--new-cmd` - New CMD instruction for the optimized image\n- `--new-expose` - New EXPOSE instructions for the optimized image\n- `--new-workdir` - New WORKDIR instruction for the optimized image\n- `--new-env` - New ENV instructions for the optimized image\n- `--new-label` - New LABEL instructions for the optimized image\n- `--new-volume` - New VOLUME instructions for the optimized image\n- `--remove-volume` - Remove VOLUME instructions for the optimized image\n- `--remove-env` - Remove ENV instructions for the optimized image\n- `--remove-label` - Remove LABEL instructions for the optimized image\n- `--remove-expose` - Remove EXPOSE instructions for the optimized image\n- `--exec` - A shell script snippet to run via Docker exec\n- `--exec-file` - A shell script file to run via Docker exec\n- `--sensor-ipc-mode` - Select sensor IPC mode: proxy | direct (useful for containerized CI/CD environments)\n- `--sensor-ipc-endpoint` - Override sensor IPC endpoint\n- `--rta-onbuild-base-image` - Enable runtime analysis for onbuild base images (default: false)\n- `--rta-source-ptrace` - Enable PTRACE runtime analysis source (default: true)\n- `--image-build-engine` - Select image build engine: `internal` | `docker` | `none` (`internal` - build the output image without using Docker [default behavior], `docker` - build the output image with Docker, `none` - don't build the output image, allows you to do your own build with the tools you want to use, which you'll be able to do by pointing to the artifact directory where the `files.tar` and `Dockerfile` artifacts are located for the output image)\n- `--image-build-arch` - Select output image build architecture (use the standard container image names for the architectures without the OS part)\n- `--obfuscate-metadata` - Obfuscate the standard system and application metadata to make it more challenging to identify the image components (experimental flag, first version of obfuscation; inspired by the [`Malicious Compliance`](https://kccnceu2023.sched.com/event/1Hybu/malicious-compliance-reflections-on-trusting-container-scanners-ian-coldwater-independent-duffie-cooley-isovalent-brad-geesaman-ghost-security-rory-mccune-datadog) KubeCon EU 2023 talk)\n- `--enable-mondel` - Enable monitor data event log for sensor monitors to log/stream the events captured by those monitors (default: false)\n\nIn the interactive CLI prompt mode you must specify the target image using the `--target` flag while in the traditional CLI mode you can use the `--target` flag or you can specify the target image as the last value in the command.\n\nThe `--include-path` option is useful if you want to customize your minified image adding extra files and directories. The `--include-path-file` option allows you to load multiple includes from a newline delimited file. Use this option if you have a lot of includes. The includes from `--include-path` and `--include-path-file` are combined together. You can also use the `--exclude-pattern` flag to control what shouldn't be included.\n\nThe `--continue-after` option is useful if you need to script the Slim app. If you pick the `probe` option then Slim will continue executing the build command after the HTTP probe is done executing. If you pick the `exec` options then Slim will continue executing the build command after the container exec shell commands (specified using the `--exec-file` or `--exec` flags) are done executing. If you pick the `timeout` option Slim will allow the target container to run for 60 seconds before it will attempt to collect the artifacts. You can specify a custom timeout value by passing a number of seconds you need instead of the `timeout` string. If you pick the `signal` option you'll need to send a `USR1` signal to the Slim app process. The `signal` option is useful when you want to run your own tests against the temporary container Slim creates. Your test automation / CI/CD pipeline will be able to notify the Slim app that it's done running its test by sending the `USR1` to it.\n\nYou can also combine multiple `continue-after` modes. For now only combining `probe` and `exec` is supported (using either `probe&exec` or `exec&probe` as the `--continue-after` flag value). Other combinations may work too. Combining `probe` and `signal` is not supported.\n\nThe `--include-shell` option provides a simple way to keep a basic shell in the minified container. Not all shell commands are included. To get additional shell commands or other command line utilities use the `--include-exe` and/or `--include-bin` options. Note that the extra apps and binaries might missed some of the non-binary dependencies (which don't get picked up during static analysis). For those additional dependencies use the `--include-path` and `--include-path-file` options.\n\nThe `--dockerfile` option makes it possible to build a new minified image directly from source Dockerfile. Pass the Dockerfile name as the value for this flag and pass the build context directory or URL instead of the docker image name as the last parameter for the `build` command: `slim build --dockerfile Dockerfile --tag my/custom_minified_image_name .` If you want to see the console output from the build stages (when the fat and slim images are built) add the `--show-blogs` build flag. Note that the build console output is not interactive and it's printed only after the corresponding build step is done. The fat image created during the build process has the `.fat` suffix in its name. If you specify a custom image tag (with the `--tag` flag) the `.fat` suffix is added to the name part of the tag. If you don't provide a custom tag the generated fat image name will have the following format: `slim-tmp-fat-image.<pid_of_slim>.<current_timestamp>`. The minified image name will have the `.slim` suffix added to that auto-generated container image name (`slim-tmp-fat-image.<pid_of_slim>.<current_timestamp>.slim`). Take a look at this [python examples](https://github.com/slimtoolkit/examples/tree/master/python_ubuntu_18_py27_from_dockerfile) to see how it's using the `--dockerfile` flag.\n\nThe `--use-local-mounts` option is used to choose how the Slim sensor is added to the target container and how the sensor artifacts are delivered back to the master. If you enable this option you'll get the original Slim app behavior where it uses local file system volume mounts to add the sensor executable and to extract the artifacts from the target container. This option doesn't always work as expected in the dockerized environment where Slim itself is running in a Docker container. When this option is disabled (default behavior) then a separate Docker volume is used to mount the sensor and the sensor artifacts are explicitly copied from the target container.\n\n### `DEBUG` COMMAND OPTIONS\n\n- `--runtime` - Runtime environment type (values: `docker`, `k8s`; defaults to `docker`)\n- `--debug-image` - Debug image to use for the debug side-car container (default value for this flag is `busybox`).\n- `--list-debug-images` - List possible debug images to use for the debug side-car container (for the `--debug-image` flag). This list is a ready to use set of debug images. You can use other images too.\n- `--target` - Target container name or ID (this can also be provided as the last param in the command line invocation of the `debug` command). Note that the target container must be running. You can use the `docker run` command to start the target container (or the kubernetes equivalent).\n- `--namespace` - Namespace to target [k8s runtime] (defaults to `default`)\n- `--pod` - Pod to target [k8s runtime]\n- `--cmd` - (Optional) custom CMD to use for the debug side-car container (alternatively pass custom CMD params after '--').\n- `--entrypoint` - (Optional) custom ENTRYPOINT to use for the debug side-car container.\n- `--terminal` - Attach interactive terminal to the debug container (default: true). When the interactive terminal is not enabled the debug container output will be printed out to the screen when the `debug` command exits.\n- `--kubeconfig` - Kubeconfig file location [k8s runtime]\n- `--workdir` - Custom WORKDIR to use for the debug side-car container.\n- `--env` - Environment variable to add to the debug side-car container.\n- `--run-as-target-shell` - Attach interactive terminal to the debug container and run shell as if it's running in the target container environment.\n- `--list-sessions` - List all debug sessions for the selected target (pod and optionally selected container for k8s or container for other runtimes).\n- `--show-session-logs` - Show logs for the selected debug session (using namespace, pod, target container or debug session container name for k8s or debug session container name for other runtimes).\n- `--session` - Debug session container name (used for debug sessoin actions).\n- `--connect-session` - Connect to existing debug session.\n- `--list-namespaces` - List names for available namespaces (use this flag by itself) [k8s runtime].\n- `--list-pods` - List names for running pods in the selected namespace (use this flag by itself) [k8s runtime].\n- `--list-debuggable-containers` - List container names for active containers that can be debugged (use this flag by itself).\n- `--list-debug-images` - List possible debug images to use for the debug side-car container (use this flag by itself).\n- `--help` show help (default: false)\n\nSee the \"Debugging Using the `debug` Command\" section for more information about this command.\n\n### `RUN` COMMAND OPTIONS\n\nRun one or more containers\n\nUSAGE: `slim [GLOBAL FLAGS] run [FLAGS] [IMAGE]`\n\nFlags:\n\n- `--target` - Target container image to run. Same as specifying the target container image as the last value for the command. Used mostly for the interactive prompt mode where you need to select flag names.\n- `--pull` - Pull the target image before trying to run it.\n- `--docker-config-path` - Docker config path (used to fetch registry credentials).\n- `--registry-account` - Target registry account used when pulling images from private registries.\n- `--registry-secret` - Target registry secret used when pulling images from private registries.\n- `--show-plogs` - Show image pull logs.\n- `--entrypoint` - Override ENTRYPOINT running the target image.\n- `--cmd` - Override CMD running the target image.\n- `--live-logs` - Show live logs for the container (can't use with --terminal).\n- `--terminal` - Attach interactive terminal to the container.\n- `--publish` - Map container port to host port (format => port | hostPort:containerPort | hostIP:hostPort:containerPort | hostIP::containerPort ).\n- `--rm` - Remove the container when it exits.\n- `--detach` - Start the container and do not wait for it to exit.\n\n### `MERGE` COMMAND OPTIONS\n\nMerge two container images. Optimized to merge minified images.\n\nFlags:\n\n- `--image` - Image to merge. Flag instance position determines the merge order. The command supports two instances of this flag.\n\n- `--use-last-image-metadata` - Use only the last image metadata for the merged image.\n\n- `--tag` - Custom tags for the output image (multiple instances).\n\n\n### `REGISTRY` COMMAND OPTIONS\n\nFor the operations that require authentication you can reuse the registry credentials from Docker (do `docker login` first and then use the `--use-docker-credentials` flag with the `registry` command) or you can specify the auth info using the `--account` and `--secret` flags).\n\nCurrent sub-commands: `pull`, `push`, `image-index-create`, `server`.\n\nThere's also a placeholder for `copy`, but it doesn't do anything yet. Great opportunity to contribute ;-)\n\nShared Command Level Flags:\n\n- `--use-docker-credentials` - Use the registry credentials from the default Docker config file.\n- `--account` - Registry credentials account.\n- `--secret` - Registry credentials secret.\n\n#### `PULL` SUBCOMMAND OPTIONS\n\nUSAGE: `slim [GLOBAL FLAGS] registry [SHARED FLAGS] pull [FLAGS] [IMAGE]`\n\nFlags:\n\n- `--target value` - Target container image (name or ID) [$DSLIM_TARGET]\n- `--save-to-docker`- Save pulled image to docker (default: true) [$DSLIM_REG_PULL_SAVE_TO_DOCKER]\n\n#### `PUSH` SUBCOMMAND OPTIONS\n\nUSAGE: `slim [GLOBAL FLAGS] registry [SHARED FLAGS] push [FLAGS] [IMAGE]`\n\nFlags:\n\n- `--docker` -- Push local docker image.\n- `--tar` -- Push image from a local tar file.\n- `--as` -- Tag the selected image with the specified name before pushing.\n\nNote that `slim registry push LOCAL_DOCKER_IMAGE_NAME` is a shortcut for `slim registry push --docker LOCAL_DOCKER_IMAGE_NAME`.\n\nNormally you have to explicitly tag the target image to have a name that's appropriate for the destination registry. The `--as` flag is a convenient way to tag the image while you are pushing it. Here's an example pushing a local Docker `nginx` image to a local registry: `slim registry push --docker nginx --as localhost:5000/nginx`\n\nYou can create a local registry using the `server` subcommand. See the `server` sub-command section below for more details.\n\n#### `COPY` SUBCOMMAND OPTIONS\n\nUSAGE: `slim registry copy [SRC_IMAGE] [DST_IMAGE]`\n\nNOTE: Just a placeholder for now (TBD)\n\n#### `IMAGE-INDEX-CREATE` SUBCOMMAND OPTIONS\n\nUSAGE: `slim registry image-index-create --image-index-name [MULTI-ARCH_IMAGE_TAG] --image-name [IMAGE_ONE] --image-name [IMAGE_TWO]`\n\nFlags: \n\n- `--image-index-name` - Image index name to use.\n- `--image-name` - Target image name to include in image index.\n- `--as-manifest-list` - Create image index with the manifest list media type instead of the default OCI image index type.\n- `--dump-raw-manifest` - Dump raw manifest for the created image index.\n- `--insecure-refs` - Allow the referenced images from insecure registry connections.\n\n#### `SERVER` SUBCOMMAND OPTIONS\n\nStarts a server which implements the [OCI API spec](https://github.com/opencontainers/distribution-spec/blob/v1.0.1/spec.md) on port 5000 by default.\n\nUSAGE: `slim [GLOBAL FLAGS] registry server [FLAGS]`\n\nFlags:\n\n- `--address` - Registry server address to listen on (default: `0.0.0.0`)\n- `--port` - Registry server port (default: 5000)\n- `--https` - Use HTTPS.\n- `--cert-path` - Cert path for use with HTTPS (for use when not using autocert).\n- `--key-path` - Key path for use with HTTPS (for use when not using autocert).\n- `--domain` - Domain to use for registry server (to get certs). Only works if the registry is internet accessible (see `autocert` Go docs for more details).\n- `--referrers-api` - Enables the [referrers API endpoint](https://github.com/opencontainers/distribution-spec/blob/v1.1.0-rc3/spec.md#enabling-the-referrers-api) (OCI 1.1+). Enabled by default (set to `false` to disable).\n\n### `VULNERABILITY` COMMAND OPTIONS\n\nUSAGE: `slim [GLOBAL FLAGS] vulnerability [SHARED FLAGS] [SUBCOMMAND] [FLAGS]`\n\nCurrent sub-commands: \n\n* `epss` - Gets EPPS information for the target vulnerabilities or based on the selected vulnerability filters.\n\nShared Command Level Flags:\n\n- `--cve` - Target vulnerability CVE ID (can specify multiple times to target multiple vulnerabilities).\n\n#### `EPSS` SUBCOMMAND OPTIONS\n\nUSAGE: `slim [GLOBAL FLAGS] vulnerability [SHARED FLAGS] epss [FLAGS]`\n\nFlags:\n\n- `--op` - EPSS operation (`lookup` | `list`).\n- `--date` - Date for the EPSS information (YYYY-MM-DD format). Works with the `lookup` and `list` operations.\n- `--with-history` - Return EPSS results with historical data. Works with the `lookup` and `list` operations.\n- `--limit` - Limit the number of returned records.\n- `offset` - Offset where to start returning records.\n- `filter-cve-id-pattern` - 'CVE ID pattern' ESPP list operation filter.\n- `filter-days-since-added` - 'days since added' ESPP list operation filter.\n- `filter-score-gt` - 'score is greater than' ESPP list operation filter.\n- `filter-score-lt` - 'score is less than' ESPP list operation filter.\n- `filter-percentile-gt` - 'percentile is greater than' ESPP list operation filter.\n- `filter-percentile-lt` - 'percentile is less than' ESPP list operation filter.\n- `filter-order-records` - 'order returned records' ESPP list operation filter ('score-desc' | 'score-asc' | 'percentile-desc' | 'percentile-asc').\n\nExamples:\n\n* `slim --quiet vulnerability --cve CVE-2021-21315 epss`\n* `slim --output-format=json vulnerability --cve CVE-2021-21315 epss`\n* `slim --quiet --output-format=json vulnerability --cve CVE-2021-21315 --cve CVE-2023-49070 epss`\n* `slim --quiet vulnerability --cve CVE-2021-21315 epss --with-history --date 2022-12-13`\n* `slim --quiet vulnerability epss --op list --date 2024-01-05`\n* `slim --quiet vulnerability epss --op list --filter-cve-id-pattern 2023 --filter-score-gt 0.92 --limit 2 --offset 3`\n\n\n## RUNNING CONTAINERIZED\n\nThe current version of Slim is able to run in containers. It will try to detect if it's running in a containerized environment, but you can also tell Slim explicitly using the `--in-container` global flag.\n\nYou can run Slim in your container directly or you can use the Slim container image in your containerized environment. If you are using the Slim container image make sure you run it configured with the Docker IPC information, so it can communicate with the Docker daemon. The most common way to do it is by mounting the Docker unix socket to the Slim app container. Some containerized environments (like Gitlab and their `dind` service) might not expose the Docker unix socket to you, so you'll need to make sure the environment variables used to communicate with Docker (e.g., `DOCKER_HOST`) are passed to the Slim app container. Note that if those environment variables reference any kind of local host names those names need to be replaced or you need to tell the Slim app about them using the `--etc-hosts-map` flag. If those environment variables reference local files those local files (e.g., files for TLS cert validation) will need to be copied to a temporary container, so that temporary container can be used as a data container to make those files accessible by the Slim app container.\n\nWhen Slim app runs in a container it will attempt to save its execution state in a separate Docker volume. If the volume doesn't exist it will try to create it (`slim-state`, by default). You can pick a different state volume or disable this behavior completely by using the global `--archive-state` flag. If you do want to persist the Slim app execution state (which includes the `seccomp` and `AppArmor` profiles) without using the state archiving feature you can mount your own volume that maps to the `/bin/.slim-state` directory in the Slim app container.\n\nBy default, the Slim app will try to create a Docker volume for its sensor unless one already exists. If this behavior is not supported by your containerized environment you can create a volume separately and pass its name to the Slim app using the `--use-sensor-volume` flag.\n\nHere's a basic example of how to use the containerized version of the Slim app:\n`docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock dslim/slim build your-docker-image-name`\n\nHere's a GitLab example for their `dind` `.gitlab-ci.yml` config file:\n`docker run -e DOCKER_HOST=tcp://$(grep docker /etc/hosts | cut -f1):2375 dslim/slim build your-docker-image-name`\n\nHere's a CircleCI example for their `remote docker` `.circleci/config.yml` config file (used after the `setup_remote_docker` step):\n\n```bash\ndocker create -v /dcert_path --name dcert alpine:latest /bin/true\ndocker cp $DOCKER_CERT_PATH/. dcert:/dcert_path\ndocker run --volumes-from dcert -e DOCKER_HOST=$DOCKER_HOST -e DOCKER_TLS_VERIFY=$DOCKER_TLS_VERIFY -e DOCKER_CERT_PATH=/dcert_path dslim/slim build your-docker-image-name\n```\n\nDifferent CI/CD services have different containerized environment designs that impose various restrictions that may impact the ability of the main app to communicate with the sensor app embedded in the temporary container Slim creates. Try adjusting the values for the `--sensor-ipc-mode` and `--sensor-ipc-endpoint` flags. This [`Google Cloud Build`](https://medium.com/google-cloud/integrating-dockerslim-container-minify-step-on-cloud-build-64da29fd58d1) blog post by Márton Kodok is a good reference for both of those flags. \n\n### Using `*-file` Flags\n- There are several flags that accept file paths (`--include-path-file`, `--compose-file`, `--http-probe-cmd-file`, etc). You need volume mount the location of the referenced paths or the file paths themselves when you use the containerized version of Slim because the Slim app container won't have accept to the referenced files otherwise.\n\n## CI/CD INTEGRATIONS\n\n### Integrating Slim in Jenkins\n#### Prerequisites:\n- Spin up a virtual machine(e.g.EC2 Instance, Azure VM, GCE) which has an Ubuntu OS via your desired cloud platform(AWS, Azure, GCP), SSH into the machine, update the machine packages and install docker. An example of this step is highlighted below given you are running an AWS EC2 Instance.\n```\nsudo apt update -y\n```\n```\nsudo apt install docker -y\n```\n```\nsudo systemctl start docker\n```\n```\nsudo usermod -aG docker ec2-user\n```\n- Install Jenkins on the virtual machine using docker as stipulated by the [Jenkins Documentation](https://github.com/jenkinsci/docker/blob/master/README.md), this step pulls [Jenkins Image from DockerHub](https://hub.docker.com/r/jenkins/jenkins), runs Jenkins as a container via port 8080 and creates an explicit docker volume on the host machine to retain Jenkins data. Given you are running an AWS EC2 Instance, create a TCP rule with port 8080 in the Instance security group rules which allows only your Internet Protocol(IP) address to access the Jenkins server. \n```\ndocker run -p 8080:8080 -p 50000:50000 -d -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts\n```\n- Given Jenkins is now running as a containerized environment in the virtual machine, you need to make docker available in the Jenkins container, you can do this by bind mounting the virtual machine docker unix socket onto the jenkins container, note that to carry out this step you need to stop the running jenkins container, you can find the jenkins container ID by using the docker ps command, the commands to execute are highlighted below. This step is essential as it makes docker available in the Jenkins container, and with docker you can pull Slim Image which is to be used in further steps.\n```\ndocker ps \n```\n```\ndocker stop [jenkins_container_id]\n```\n```\ndocker run -p 8080:8080 -p 50000:50000 -d \\  \n-v jenkins_home:/var/jenkins_home \\ \n-v /var/run/docker.sock:/var/run/docker.sock \\ \n-v $(which docker):/usr/bin/docker jenkins/jenkins:lts\n```\n- Enable Docker permissions in the new jenkins container, such that Jenkins can perform docker commands and pull the [Slim Official Image](https://hub.docker.com/r/dslim/docker-slim) in the container. To do this, you need to get into the Jenkins container as a root user, you can find the jenkins container ID by using the docker ps command, the commands to execute are highlighted below:\n```\ndocker exec -u 0 -it [jenkins_container_id] bash\n```\n```\nchmod 666 /var/run/docker.sock \n```\n```\ndocker pull dslim/slim\n```\n#### Jenkinsfile Slim Stage\nGiven you have completed the prerequisite steps above, you can build a docker image and minify the image size using Slim via the snippet stage below which should be highlighted in your Jenkinsfile stages.\n```\nstage(\"Build and Slim Docker Image\") {\n  steps {\n      script {\n          echo \"building and slimming docker image...\"\n          sh 'docker build -t IMAGE_NAME:$BUILD_NUMBER .'\n          sh 'docker run --rm -v /var/run/docker.sock:/var/run/docker.sock dslim/slim \\\n              build --target IMAGE_NAME:$BUILD_NUMBER --tag IMAGE_NAME:slim-$BUILD_NUMBER \\\n              exit'\n      }\n  }\n}\n```\n- The snippet stage above allows for customization, you should replace the image name--IMAGE_NAME with your desired image name, the environment variable tag--$BUILD_NUMBER represents a unique incremental number allocated by Jenkins each time your jenkins pipeline runs. \n- The docker build command builds a Docker Image of your application from a Dockerfile.\n- The docker run command runs Slim in a non-interactive mode via the docker unix socket, minifies the built(target) image--IMAGE_NAME:$BUILD_NUMBER, and adjusting it to a new slimmed image with the image/tag--IMAGE_NAME:slim-$BUILD_NUMBER.\n- You should put the Slim stage before a docker tag/push stage and after a build/test artifact in your Jenkinsfile, an example pipeline is highlighted below for a sample nodejs application; The first stage test and builds an artifact of the application; The second stage builds a docker image and a slimmed version of the docker image; The third stage tags the slimmed docker image with a DockerHub account remote repository and pushes the image to the remote repository.\n```\npipeline {\n    agent any\n    stages {\n        stage(\"building nodejs app\") {\n            steps{\n                script {\n                    echo \"building nodejs app...\"\n                    sh 'npm run test'\n                    sh 'npm pack'\n                }\n            }\n        }\n        stage(\"Build and Slim Docker Image\") {\n            steps {\n                script {\n                    echo \"building and slimming docker image...\"\n                    sh 'docker build -t node_alpine:$BUILD_NUMBER .'\n                    sh 'docker run --rm -v /var/run/docker.sock:/var/run/docker.sock dslim/slim \\\n                        build --target node_alpine:$BUILD_NUMBER --tag node_alpine:slim-$BUILD_NUMBER \\\n                        exit'\n                }\n            }\n        }\n        stage(\"Push Slim Image to Regristy\") {\n            steps {\n                script {\n                    echo 'pushing image to docker regristry...'\n                    withCredentials([usernamePassword(credentialsId: 'docker-hub-credentials', passwordVariable: 'PASS', usernameVariable: 'USER')]) {\n                        sh 'docker tag node_alpine:slim-$BUILD_NUMBER $USER/node_alpine:slim-$BUILD_NUMBER'\n                        sh 'echo $PASS | docker login -u $USER --password-stdin'\n                        sh 'docker push $USER/node_alpine:slim-$BUILD_NUMBER'\n                    }\n                }\n            }\n        }\n    }\n}   \n```\n\n### Integrating Slimtoolkit in Github Actions\n#### Github Action\nIntegrating SlimToolkit in Github Actions in your CI/CD workflow involves using the [Docker-Slim Github Action](https://github.com/marketplace/actions/docker-slim-github-action), this Action(snippet below) minifies a target docker image--IMAGE_NAME:latest in your workflow, making it smaller and adjusting the new slimmed image as IMAGE_NAME:slim.  \n```\n# Slim it!\n- uses: kitabisa/docker-slim-action@v1\n  env:\n    DSLIM_HTTP_PROBE: false\n  with:\n    target: IMAGE_NAME:latest\n    tag: \"slim\"\n```\n#### Github Actions Slim Workflow\nYou can integrate the Docker-Slim Github Action in your workflow by inserting the Action after a [Docker Build/Push Github Action](https://github.com/docker/build-push-action), before [Docker Login Github Action](https://github.com/docker/login-action) and docker tag/push commands, a customized example workflow is highlighted below. Note that the environment variable tag--{{github.run_number}} in the workflow represents a unique incremental number allocated by Github Actions each time your workflow runs.\n```\n# Build the Docker image first\n- uses: docker/build-push-action@v4\n  with:\n    push: false\n    tags: IMAGE_NAME:{{github.run_number}} \n\n# Slim the Image\n- uses: kitabisa/docker-slim-action@v1\n  env:\n    DSLIM_HTTP_PROBE: false\n  with:\n    target: IMAGE_NAME:{{github.run_number}}\n    tag: \"slim-{{github.run_number}}\"\n\n# Docker Hub Login\n  uses: docker/login-action@v2\n  with:\n    username: ${{ secrets.DOCKERHUB_USERNAME }}\n    password: ${{ secrets.DOCKERHUB_TOKEN }}\n\n# Push to the registry\n- run: | \n   docker tag IMAGE_NAME:slim-{{github.run_number}} ${{ secrets.DOCKERHUB_USERNAME }}/IMAGE_NAME:slim-{{github.run_number}}\n   docker push ${{ secrets.DOCKERHUB_USERNAME }}/IMAGE_NAME:slim-{{github.run_number}}\n```\nThe workflow above indicates four steps:\n- A [Docker Build/Push Github Action](https://github.com/docker/build-push-action) for building a docker image with the image name/tag--IMAGE_NAME:{{github.run_number}}, you should give replace IMAGE_NAME with your desired image name. Note that this Action must have a false option to push the built image--given that you need the image slimmed/minified before pushing it to a container registry. \n- A Docker-Slim Github Action which minifies the target image--IMAGE_NAME:{{github.run_number}}, this Action has the \"slim-{{github.run_number}}\" tag and adds this tag to the slimmed/minified docker image such that the image name/tag becomes IMAGE_NAME:slim-{{github.run_number}}.\n- A Docker Login Github Action which logs into your DockerHub container regristry account, you should store your DockerHub username and personal access token as secrets in the github repository meant for the workflow. Suppose your container registry is not DockerHub, you can check the [Docker Login Github Action documentation](https://github.com/docker/login-action) for the use case of logging into your desired container registry. \n- A docker tag command for naming/tagging the slimmed image with your DockerHub account remote repository name which could be the same name(IMAGE_NAME) as the slimmed image; A docker push command to push the slimmed image to your Dockerhub account remote repository.\n\n\n## DOCKER CONNECT OPTIONS\n\nIf you don't specify any Docker connect options the Slim app expects to find the Docker Unix socket (`/var/run/docker.sock`) or the following environment variables: `DOCKER_HOST`, `DOCKER_TLS_VERIFY` (optional), `DOCKER_CERT_PATH` (required if `DOCKER_TLS_VERIFY` is set to `\"1\"`). Note that the `DOCKER_HOST` environment variable can be used to point to a Unix socket address (in case the default Unix socket isn't there). This is useful when you use Docker Desktop and you haven't configured Docker Desktop to create the default Unix socket.\n\nIf the Docker environment variables are configured to use TLS and to verify the Docker cert (default behavior), but you want to disable the TLS verification you can override the TLS verification behavior by setting the `--tls-verify` to false:\n\n`slim --tls-verify=false build my/sample-node-app-multi`\n\nYou can override all Docker connection options using these flags: `--host`, `--tls`, `--tls-verify`, `--tls-cert-path`. These flags correspond to the standard Docker options (and the environment variables). Note that you can also use the `--host` flag (similar to `DOCKER_HOST`) to point to a Unix socket (e.g., `--host=unix:///var/run/docker.sock`).\n\nIf you want to use TLS with verification:\n\n`slim --host=tcp://192.168.99.100:2376 --tls-cert-path=/Users/youruser/.docker/machine/machines/default --tls=true --tls-verify=true build my/sample-node-app-multi`\n\nIf you want to use TLS without verification:\n\n`slim --host=tcp://192.168.99.100:2376 --tls-cert-path=/Users/youruser/.docker/machine/machines/default --tls=true --tls-verify=false build my/sample-node-app-multi`\n\nIf the Docker environment variables are not set and if you don't specify any Docker connect options Slim will try to use the default unix socket.\n\n### DOCKER DESKTOP\n\nYou may not have the default Unix socket (`/var/run/docker.sock`) configured if you use Docker Desktop. By default, Docker Desktop uses `~/.docker/run/docker.sock` as the Unix socket.\n\nYou can either use `--host` or `DOCKER_HOST` to point to the Docker Desktop's Unix socket or you can configure Docker Desktop to create the default/traditional Unix socket (creating the `/var/run/docker.sock` symlink manually is an option too).\n\nTo configure Docker Desktop to create the default Unix socket open its UI and go to `Settings -> Advanced` where you need to check the `Enable default Docker socket (Requires password)` option.\n\n### COLIMA\n\nSimilar to with Docker Desktop, but the socked will need to be configured to use `unix://${HOME}/.colima/<PROFILE>/docker.sock`.\n\n## HTTP PROBE COMMANDS\n\nIf the HTTP probe is enabled (note: it is enabled by default) it will default to running `GET /` with HTTP and then HTTPS on every exposed port. You can add additional commands using the `--http-probe-cmd` and `--http-probe-cmd-file` options.\n\nIf you want to disable HTTP probing set the `--http-probe` flag to false (e.g., `--http-probe=false`). You can also use the `--http-probe-off` flag to do the same (simply use the flag without any parameters).\n\nThe `--http-probe-cmd` option is good when you want to specify a small number of simple commands where you select some or all of these HTTP command options: crawling (defaults to false), protocol, method (defaults to GET), resource (path and query string).\n\nIf you only want to use custom HTTP probe command and you don't want the default `GET /` command added to the command list you explicitly provided you'll need to set `--http-probe` to false when you specify your custom HTTP probe command. Note that this inconsistency will be addressed in the future releases to make it less confusing.\n\nPossible field combinations:\n* `/path` - runs `GET /path`\n* `crawl:/path` - runs `GET /path` and then crawls the pages referenced by the target page\n* `post:/path` - runs `POST /path`\n* `crawl:get:/path` - runs `GET /path` and then crawls the pages referenced by the target page\n* `https:get:/path` runs `GET /path` only on https\n* `crawl:http:get:/path` - runs `GET /path` and then crawls the pages referenced by the target page\n\nHere are a couple of examples:\n\nAdds two extra probe commands: `GET /api/info` and `POST /submit` (tries http first, then tries https):\n`slim build --show-clogs --http-probe-cmd /api/info --http-probe-cmd POST:/submit my/sample-node-app-multi`\n\nAdds one extra probe command: `POST /submit` (using only http):\n`slim build --show-clogs --http-probe-cmd http:POST:/submit my/sample-node-app-multi`\n\nThe `--http-probe-cmd-file` option is good when you have a lot of commands and/or you want to select additional HTTP command options.\n\nAvailable HTTP command options:\n* `method` - HTTP method to use\n* `resource` - target resource URL\n* `port` - port number\n* `protocol` - `http`, `https`, `http2`, `http2c` (cleartext version of http2), `ws`, `wss` (secure websocket)\n* `headers` - array of strings with column delimited key/value pairs (e.g., \"Content-Type: application/json\")\n* `body` - request body as a string\n* `body_file` - request body loaded from the provided file\n* `username` - username to use for basic auth\n* `password` - password to use for basic auth\n* `crawl` - boolean to indicate if you want to crawl the target (to visit all referenced resources)\n\nHere's a probe command file example:\n\n`slim build --show-clogs --http-probe-cmd-file probeCmds.json my/sample-node-app-multi`\n\nCommands in `probeCmds.json`:\n\n```\n{\n  \"commands\":\n  [\n   {\n     \"resource\": \"/api/info\"\n   },\n   {\n     \"method\": \"POST\",\n     \"resource\": \"/submit\"\n   },\n   {\n     \"procotol\": \"http\",\n     \"resource\": \"/api/call?arg=one\"\n   },\n   {\n     \"protocol\": \"http\",\n     \"method\": \"POST\",\n     \"resource\": \"/submit2\",\n     \"body\": \"key=value\"\n   },\n   {\n     \"protocol\": \"http\",\n     \"method\": \"POST\",\n     \"resource\": \"/submit3\",\n     \"body_file\": \"mydata.json\",\n     \"headers\": [\"Content-Type: application/json\"]\n   }\n  ]\n}\n```\n\nThe HTTP probe command file path can be a relative path (relative to the current working directory) or it can be an absolute path.\n\nFor each HTTP probe call Slim will print the call status. Example: `info=http.probe.call status=200 method=GET target=http://127.0.0.1:32899/ attempt=1 error=none`.\n\nYou can execute your own external HTTP requests using the `target.port.list` field in the container info message Slim prints when it starts its test container: `slim[build]: info=container name=<your_container_name> id=<your_container_id> target.port.list=[<comma_separated_list_of_port_numbers_to_use>] target.port.info=[<comma_separated_list_of_port_mapping_records>]`. Example: `slim[build]: info=container name=slimk_42861_20190203084955 id=aa44c43bcf4dd0dae78e2a8b3ac011e7beb6f098a65b09c8bce4a91dc2ff8427 target.port.list=[32899] target.port.info=[9000/tcp => 0.0.0.0:32899]`. With this information you can run `curl` or other HTTP request generating tools: `curl http://localhost:32899`.\n\nThe current version also includes an experimental `crawling` capability. To enable it for the default HTTP probe use the `--http-probe-crawl` flag. You can also enable it for the HTTP probe commands in your command file using the `crawl` boolean field.\n\nWhen `crawling` is enabled the HTTP probe will act like a web crawler following the links it finds in the target endpoint.\n\nProbing based on the Swagger/OpenAPI spec is another experimental capability. This feature introduces two new flags:\n* `http-probe-apispec` - value: `<path_to_fetch_spec>:<api_endpoint_prefix>`\n* `http-probe-apispec-file` - value: `<local_file_path_to_spec>`\n\nYou can use the `--http-probe-exec` and `--http-probe-exec-file` options to run the user provided commands when the http probes are executed. This example shows how you can run `curl` against the temporary container created by Slim when the http probes are executed.\n\n`slim build --http-probe-exec 'curl http://localhost:YOUR_CONTAINER_PORT_NUM/some/path' --publish-port YOUR_CONTAINER_PORT_NUM your-container-image-name`\n\n\n## DEBUGGING MINIFIED CONTAINERS\n\n### Debugging Using the `debug` Command\n\nThe current version of the `debug` command is pretty basic and it lacks a number of useful capabilities. It will help you debug containers running in Docker or Kubernetes (use the `--runtime` flag and set it to `k8s` if you need to debug a container in Kubernetes). \n\nBy default the `debug` command will provide you with an interactive terminal when it attaches the debugger side-car image to the debugged target container. Future versions will allow you to have different interaction modes with the target.\n\n#### The Debug Images\n\nYou can use any container image as a debug image, but there's a list of pre-selected debug images you can choose.\n\nYou can list all pre-selected debug images with the `--list-debug-images` and if you are using the interactive prompt mode there'll be an auto-complete dropdown menu for the `--debug-image` flag.\n\nHere's the current list of debug images:\n\n* `cgr.dev/chainguard/slim-toolkit-debug:latest` - a general purpose SlimToolkit debug image created by Chainguard\n* `cgr.dev/chainguard/wolfi-base:latest` - a basic lightweight Wolfi image\n* `busybox:latest` - a lightweight image with common unix utilities\n* `nicolaka/netshoot` - a network trouble-shooting swiss-army container\n* `lightruncom/koolkits:node` - a debug image for Node.js applications\n* `lightruncom/koolkits:python` - a debug image for Python applications\n* `lightruncom/koolkits:golang` - a debug image for Go applications\n* `lightruncom/koolkits:jvm` - a debug image for Java applications\n* `digitalocean/doks-debug:latest` - a kubernetes troubleshooting debug image\n* `public.ecr.aws/zinclabs/debug-ubuntu-base:latest` - an image with common debugging utilities \n\n#### Steps to Debug Your Container (Kubernetes Runtime)\n\n1. Make sure the target environment you want to debug is up (the example k8s manifest creates a pod with the minimal nginx image from Chainguard and it has no shell):\n```bash\n\n>> kubectl apply -f examples/k8s_nginx_cgr/manifest.yaml\n\n```\n2. Run the debug command:\n\n```bash\n\n>> slim debug --runtime=k8s --pod=example-pod example-container\n\n```\nor\n```bash\n\n>> slim debug --runtime=k8s --pod=example-pod --target=example-container\n\n```\n\nNow you should have an interactive shell into the debug container started by `slim` and you can type your regular shell commands.\n\nBy default the `debug` command will connect the interactive terminal to the debugged container and it will run a shell as if it's running in the target container environment, so you will see the file system of the target container as if you are directly connected (you won't have to go through the `proc` file system). You can change this behavior by using the `--run-as-target-shell` (which is true by default). For example, this call will connect you to the debug container in a more traditional way: `slim debug --runtime=k8s --run-as-target-shell=false example-container`\n\nAlso note that if you use the interactive `prompt` mode (when you run `slim` with no command line parameters) you will get auto-complete behavior for a number of flags: `--target`, `--namespace`, `--pod`, `--session`.\n\nEach time you try to debug an image `slim` will have a session that represents it. You'll be able to reconnect to the existing active debug sessions and you'll be able to get logs from all available sessions.\n\n#### Steps to Debug Your Container (Docker Runtime) \n\n1. Start the target container you want to debug:\n```bash\n\n>> docker run -it --rm -p 80:80 --name mycontainer nginx\n\n```\n2. Run the debug command:\n\n```bash\n\n>> slim debug mycontainer\n\n```\nor\n```bash\n\n>> slim debug --target=mycontainer\n\n```\n\nNow you should have an interactive shell into the debug container started by `slim` and you can type your regular shell commands.\n\nBy default the `debug` command will connect the interactive terminal to the debugged container and it will run a shell as if it's running in the target container environment, so you will see the file system of the target container as if you are directly connected (you won't have to go through the `proc` file system). You can change this behavior by using the `--run-as-target-shell` (which is true by default). For example, this call will connect you to the debug container in a more traditional way: `slim debug --run-as-target-shell=false mycontainer`\n\nAlso note that if you use the interactive `prompt` mode (when you run `slim` with no command line parameters) you will get auto-complete behavior for a number of flags: `--target`, `--session`.\n\nEach time you try to debug an image `slim` will have a session that represents it. You'll be able to reconnect to the existing active debug sessions and you'll be able to get logs from all available sessions.\n\n### Debugging the \"Hard Way\" (Docker Runtime)\n\nYou can create dedicated debugging side-car container images loaded with the tools you need for debugging target containers. This allows you to keep your production container images small. The debugging side-car containers attach to the running target containers.\n\nAssuming you have a running container named `node_app_alpine` you can attach your debugging side-car with a command like this: `docker run --rm -it --pid=container:node_app_alpine --net=container:node_app_alpine --cap-add sys_admin alpine sh`. In this example, the debugging side-car is a regular alpine image. This is exactly what happens with the `node_alpine` app sample (located in the `node_alpine` directory of the `examples` repo) and the `run_debug_sidecar.command` helper script.\n\nIf you run the `ps` command in the side-car you'll see the application from the target container:\n\n```\n# ps\nPID   USER     TIME   COMMAND\n    1 root       0:00 node /opt/my/service/server.js\n   13 root       0:00 sh\n   38 root       0:00 ps\n```\n\nYou can access the target container file system through `/proc/<TARGET_PID>/root`:\n\n```\n# ls -lh /proc/1/root/opt/my/service\ntotal 8\ndrwxr-xr-x    3 root     root        4.0K Sep  2 15:51 node_modules\n-rwxr-xr-x    1 root     root         415 Sep  8 00:52 server.js\n```\n\nSome of the useful debugging commands include `cat /proc/<TARGET_PID>/cmdline`, `ls -l /proc/<TARGET_PID>/cwd`, `cat /proc/1/environ`, `cat /proc/<TARGET_PID>/limits`, `cat /proc/<TARGET_PID>/status` and `ls -l /proc/<TARGET_PID>/fd`.\n\n\n## MINIFYING COMMAND LINE TOOLS\n\nUnless the default CMD instruction in your Dockerfile is sufficient you'll have to specify command line parameters when you execute the `build` command in Slim. This can be done with the `--cmd` option.\n\nOther useful command line parameters:\n\n- `--show-clogs` - use it if you want to see the output of your container.\n- `--mount` - use it to mount a volume when Slim inspects your image.\n- `--entrypoint` - use it if you want to override the ENTRYPOINT instruction when Slim inspects your image.\n\nNote that the `--entrypoint` and `--cmd` options don't override the `ENTRYPOINT` and `CMD` instructions in the final minified image.\n\nHere's a sample `build` command:\n\n`slim build --show-clogs=true --cmd docker-compose.yml --mount $(pwd)/data/:/data/ dslim/container-transform`\n\nIt's used to minify the `container-transform` tool. You can get the minified image from [`Docker Hub`](https://hub.docker.com/r/dslim/container-transform.slim/).\n\n## QUICK SECCOMP EXAMPLE\n\nIf you want to auto-generate a Seccomp profile AND minify your image use the `build` command. If you only want to auto-generate a Seccomp profile (along with other interesting image metadata) use the `profile` command.\n\nStep one: run Slim\n\n`slim build your-name/your-app`\n\nStep two: use the generated Seccomp profile\n\n`docker run --security-opt seccomp:<slim directory>/.images/<YOUR_APP_IMAGE_ID>/artifacts/your-name-your-app-seccomp.json <your other run params> your-name/your-app`\n\nFeel free to copy the generated profile :-)\n\nYou can use the generated Seccomp profile with your original image or with the minified image.\n\n## USING AUTO-GENERATED SECCOMP PROFILES\n\nYou can use the generated profile with your original image or with the minified image Slim created:\n\n`docker run -it --rm --security-opt seccomp:path_to/my-sample-node-app-seccomp.json -p 8000:8000 my/sample-node-app.slim`\n\n## ORIGINAL DEMO VIDEO\n\n[![DockerSlim demo](http://img.youtube.com/vi/uKdHnfEbc-E/0.jpg)](https://www.youtube.com/watch?v=uKdHnfEbc-E)\n\n[Demo video on YouTube](https://youtu.be/uKdHnfEbc-E)\n\n## DEMO STEPS\n\nThe demo runs on Mac OS X, but you can build a linux version. Note that these steps are different from the steps in the demo video.\n\n1. Get the Slim app binaries:\n\n* [Mac](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac.zip),\n* [Mac M1](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_mac_m1.zip), \n* [Linux](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux.tar.gz), \n* [Linux ARM](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm.tar.gz),\n* [Linux ARM64](https://github.com/slimtoolkit/slim/releases/download/1.40.11/dist_linux_arm64.tar.gz) \n\nUnzip them and optionally add their directory to your `PATH` environment variable if you want to use the app from other locations.\n\nThe extracted directory contains two binaries (and now it also contains a symlink for the old name):\n\n- `slim` <- the main Slim application binary\n- `slim-sensor` <- the sensor application used to collect information from running containers\n- `docker-slim` <- the symlink to `slim`, the new main app binary (useful if you are still using the old name in your scripts)\n\n2. Clone the `examples` repo to use the sample apps (note: the examples have been moved to a separate repo). You can skip this step if you have your own app.\n\n`git clone https://github.com/slimtoolkit/examples.git`\n\n3. Create a Docker image for the sample node.js app in `examples/node_ubuntu`. You can skip this step if you have your own app.\n\n`cd examples/node_ubuntu`\n\n`docker build -t my/sample-node-app .`\n\n4. Run the Slim app:\n\n`./slim build my/sample-node-app` <- run it from the location where you extracted the Slim app binaries (or update your `PATH` env var to include the directory where the Slim app binaries are located)\n\nSlim creates a special container based on the target image you provided. It also creates a resource directory where it stores the information it discovers about your image: `<slim directory>/.images/<TARGET_IMAGE_ID>`.\n\nBy default, the Slim app will run its http probe against the temporary container. If you are minifying a command line tool that doesn't expose any web service interface you'll need to explicitly disable http probing (by setting `--http-probe=false`).\n\n5. Use curl (or other tools) to call the sample app (optional)\n\n`curl http://<YOUR_DOCKER_HOST_IP>:<PORT>`\n\nThis is an optional step to make sure the target app container is doing something. Depending on the application it's an optional step. For some applications it's required if it loads new application resources dynamically based on the requests it's processing (e.g., Ruby or Python).\n\nYou'll see the mapped ports printed to the console when the Slim app starts the target container. You can also get the port number either from the `docker ps` or `docker port <CONTAINER_ID>` commands. The current version of DockerSlim doesn't allow you to map exposed network ports (it works like `docker run … -P`).\n\n6. Press <enter> and wait until the Slim app says it's done\n\nBy default or when http probing is enabled explicitly the Slim app will continue its execution once the http probe is done running. If you explicitly picked a different `continue-after` option follow the expected steps. For example, for the `enter` `continue-after` option you must press the `enter` button on your keyboard.\n\nIf http probing is enabled (when `http-probe` is set) and if `continue-after` is set to `enter` and you press the `enter` key before the built-in HTTP probe is done the probe might produce an EOF error because the Slim app will shut down the target container before all probe commands are done executing. It's ok to ignore it unless you really need the probe to finish.\n\n7. Once Slim is done check that the new minified image is there\n\n`docker images`\n\nYou should see `my/sample-node-app.slim` in the list of images. Right now all generated images have `.slim` at the end of its name.\n\n8. Use the minified image\n\n`docker run -it --rm --name=\"slim_node_app\" -p 8000:8000 my/sample-node-app.slim`\n\n## FAQ\n\n### Is it safe for production use?\n\nYes! Either way, you should test your Docker images.\n\n### How can I contribute if I don't know Go?\n\nYou don't need to read the language spec and lots of books :-) Go through the [Tour of Go](https://tour.golang.org/welcome/1) and optionally read [50 Shades of Go](https://golang50shades.com/) and you'll be ready to contribute!\n\n### What's the best application for Slim?\n\nSlimRToolkit will work for any containerized application; however, Slim automates app interactions for applications with an HTTP API. You can use Slim even if your app doesn't have an HTTP API. You'll need to interact with your application manually to make sure Slim can observe your application behavior.\n\n### Can I use Slim with dockerized command line tools?\n\nYes. The `--cmd`, `--entrypoint`, and `--mount` options will help you minify your image. The `container-transform` tool is a good example.\n\nNotes:\n\nYou can explore the artifacts Slim generates when it's creating a slim image. You'll find those in `<slim directory>/.images/<TARGET_IMAGE_ID>/artifacts`. One of the artifacts is a \"reverse engineered\" Dockerfile for the original image. It'll be called `Dockerfile.reversed`.\n\nIf you don't want to create a minified image and only want to \"reverse engineer\" the Dockerfile you can use the `info` command.\n\n### What if my Docker images uses the USER command?\n\nThe current version of Slim does include support for non-default users (take a look at the non-default user examples (including the ElasticSearch example located in the `3rdparty` directory) in the [`examples`](https://github.com/slimtoolkit/examples) repo. Please open tickets if something doesn't work for you.\n\nEverything should work as-is, but for the special cases where the current behavior don't work as expected you can adjust what Slim does using various `build` command parameters: `--run-target-as-user`, `--keep-perms`, `--path-perms`, `--path-perms-file` (along with the `--include-*` parameters).\n\nThe `--run-target-as-user` parameter is enabled by default and it controls if the application in the temporary container is started using the identity from the USER instruction in the container's Dockerfile.\n\nThe `--keep-perms` parameter is also enabled by default. It tells Slim to retain the permissions and the ownership information for the files and directories copied to the optimized container image.\n\nThe `--path-perms` and `--path-perms-file` parameters are similar to the `--include-path` and `--include-path-file` parameters. They are used to overwrite the permission and the user/group information for the target files and directories. Note that the target files/directories are expected to be in the optimized container image. If you don't know if the target files/directories will be in the optimized container you'll need to use one of the `--include-*` parameters (e.g., `--include-path-file`) to explicitly require those artifacts to be included. You can specify the permissions and the ownership information in the `--include-*` parameters too (so you don't need to have the `--path-*` parameters just to set the permissions).\n\nThe `--path-*` and `--include-*` params use the same format to communicate the permission/owernship info: `TARGET_PATH_OR_NAME:PERMS_IN_OCTAL_FORMAT#USER_ID#GROUP_ID`.\n\nYou don't have to specify the user and group IDs if you don't want to change them.\n\nHere's an example using these parameters to minify the standard `nginx` image adding extra artifacts and changing their permissions: `slim build --include-path='/opt:770#104#107' --include-path='/bin/uname:710' --path-perms='/tmp:700' nginx`.\n\nThis is what you'll see in the optimized container image:\n\n```\ndrwx------  0 0      0           0 Feb 28 22:15 tmp/\n-rwx--x---  0 0      0       31240 Mar 14  2015 bin/uname\ndrwxrwx---  0 104    107         0 Feb 28 22:13 opt/\n```\n\nThe `uname` binary isn't used by nginx, so the `--include-path` parameter is used to keep it in the optimized image changing its permissions to `710`.\n\nThe `/tmp` directory will be included in the optimized image on its own, so the `--path-perms` parameter is used to change its permissions to `700`.\n\nWhen you set permissions/user/group on a directory the settings are only applied to that directory and not to the artifacts inside. The future versions will allow you to apply the same settings to everything inside the target directory too.\n\nAlso note that for now you have to use numeric user and group IDs. The future versions will allow you to use user and group names too.\n\n### Nginx fails in my minified image\n\nIf you see `nginx: [emerg] mkdir() \"/var/lib/nginx/body\" failed` it means your nginx setup uses a non-standard temporary directory. Nginx will fail if the base directory for its temporary folders doesn't exist (they won't create the missing intermediate directories). Normally it's `/var/lib/nginx`, but if you have a custom config that points to something else you'll need to add an `--include-path` flag as an extra flag when you run the Slim app.\n\n### Slim fails with a 'no permission to read from' error\n\nThis problem shouldn't happen anymore because the exported artifacts are saved in a tar file and the master app doesn't need to access the files directly anymore.\n\nIf you run older versions of Slim you can get around this problem by running Slim from a root shell. That way it will have access to all exported files.\n\nSlim copies the relevant image artifacts trying to preserve their permissions. If the permissions are too restrictive the master app might not have sufficient privilege to access these files when it's building the new minified image.\n\n## BUILD PROCESS\n\n#### Build Options\n\nPick one of the build options that works best for you.\n\n##### Containerized\n\nRun `make build_in_docker` on linux or `make build_m1_in_docker` on Macs (or `./scripts/docker-builder.run.sh` or click on `./scripts/mac/docker-builder.run.command` on Macs) from the project directory (builds Slim in a Docker container; great if you don't want to install Go on your local machine and if you already have Docker).\n\n##### Native\n\nRun `make build` on linux or `make build_m1` on Macs (or `./scripts/src.build.sh` or click on `./scripts/mac/src.build.command` on Macs) to build Slim natively (requires Go installed locally).\n\nNote:\n\nTry using the latest version of Go building the Slim app. The current version of Go used to build the Slim app is 1.21.\n\n##### Gitpod\n\nIf you have a web browser, you can get a fully pre-configured development environment in one click:\n\n[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/slimtoolkit/slim)\n\n\n##### Additional Tools\n\n- `license-bill-of-materials` - Optional tool to track dependencies and their licenses.\n- `golint` - Optional tool for code analysis. See `https://github.com/golang/lint` for more details.\n\nYou can install these tools using the `tools.get.sh` shell script in the `scripts` directory.\n\nNotes:\n\n- Make sure you have `golint` if you intend to run the `src.inspect.sh` or `mac.src.inspect.command` scripts.\n\n## CONTRIBUTING\n\nIf the project sounds interesting or if you found a bug see [`CONTRIBUTING.md`](CONTRIBUTING.md) and submit a PR or open an issue! Non-code contributions including docs are highly appreciated! Open an issue even if you have a question or something is not clear.\n\n### CORE CONCEPTS\n\n1. Inspect container metadata (static analysis)\n2. Inspect container data (static analysis)\n3. Inspect running application (dynamic analysis)\n4. Build an application artifact graph\n5. Use the collected application data to build small images\n6. Use the collected application data to auto-generate various security framework configurations.\n\n### DYNAMIC ANALYSIS OPTIONS\n\n1. Instrument the container image (and replace the entrypoint/cmd) to collect application activity data\n2. Use kernel-level tools that provide visibility into running containers (without instrumenting the containers)\n3. Disable relevant namespaces in the target container to gain container visibility (can be done with runC)\n\n### SECURITY\n\nThe goal is to auto-generate Seccomp, AppArmor, (and potentially SELinux) profiles based on the collected information.\n\n- AppArmor profiles\n- Seccomp profiles\n\n### CHALLENGES\n\nSome of the advanced analysis options require a number of Linux kernel features that are not always included. The kernel you get with Docker Machine / Boot2docker is a great example of that.\n\n## ORIGINS\n\nDockerSlim was a `Docker Global Hack Day` \\#`dockerhackday` project. It barely worked at the time, but it did get a win in Seattle and it took the second place in the `Plumbing` category overall :-)\n\n![DHD3](assets/images/dhd/docker_global_hackday3_red.png)\n\nSince then it's been improved and it works pretty well for its core use cases. It can be better though. That's why the project needs your help! You don't need to know much about the container internals, container runtimes and you don't need to know anything about Go. You can contribute in many different ways. For example, use Slim on your images and open Github issues documenting your experience even if it worked just fine :-)\n\n## LICENSE\n\nApache License v2, see [LICENSE](https://github.com/slimtoolkit/slim/blob/master/LICENSE) for details.\n\n## CODE OF CONDUCT\n\nThe project follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).\n\n---\n\n**We are a [Cloud Native Computing Foundation](https://cncf.io/) sandbox project.**\n\n<img src=\"assets/images/cncf/cncf.svg\" width=300 />\n\n---\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/slimtoolkit/slim)](https://goreportcard.com/report/github.com/slimtoolkit/slim)\n\n"
  },
  {
    "path": "ROADMAP.md",
    "content": "# High Level Project Roadmap\n\nThis is a high level roadmap that identies the current areas of focus. Note that it's not a detailed list of every possible enhancement.\n\n* Community\n  * Collaborate with other CNCF projects to achieve mutually benefitial outcomes\n  * Talks, outreach, community training\n  * Engage with the community to increase project contributions\n\n* Documentation\n  * Improve system design documentations to make it easier for new contributors to contribute to the project\n  * User docs (v1)\n\n* Non-docker runtime support\n  * Direct ContainerD support\n  * Finch integration\n  * Podman support\n  * Kubernetes support vNext\n\n* Container debugging\n  * Ephemeral container based debugging for Kubernetes\n\n* Build/Optimize engine\n  * Error and logging enhancements to improve debuggability\n  * Improved build flag documentation with examples\n  * Improved CI/build tool integration documentation (including Github Actions)\n\n* Integrations\n  * Consign integrations for `xray` (reporting) and `build` (signing)\n\n* Plugins\n  * Plugin subsystem design\n  * Sample plugins\n  * Container image build plugin for BuildKit\n\n* System sensor\n  * System sensor subsystem design\n  * External sensor integrations for Tetragon, Falco and Tracee as plugins\n\n* Installers for all major platforms/package managers and publishing the packages to the official package manager distribution repos\n  * Homebrew (official tap), Mac Ports\n  * Apt\n  * Yum/Dnf/Rpm\n  * Apk\n  * Aur\n  * Nix\n\n* Example\n  * More build/optimize/minify examples\n  * Documenting examples including the configs used to produce the minified images\n\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# All Things Security\n\n## Reporting Security Issues\n\nTo report a security issue in the project itself, please use the GitHub Security Advisory [\"Report a Vulnerability\"](https://github.com/slimtoolkit/slim/security/advisories/new) tab.\n\nThe project members will send a response indicating the next steps in handling your report. After the initial reply to your report, the project members will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.\n\nTo report a known security issue in one of the project dependencies, please open a regular project issue and/or submit a PR with the updated version of the impacted dependency.\n\n\n\n\n"
  },
  {
    "path": "WISHLIST.md",
    "content": "# Enhancements Wishlist\n\nIf you want to help feel free to submit a PR! You can also open an issue to track the work and to have a place to talk about it.\n\n## AppArmor profile improvements\n\n## Better support for command line applications (e.g., ability to specify multiple executions)\n\n## Discover HTTP endpoints to make the HTTP probe more intelligent.\n\n## Scripting language dependency discovery in the \"scanner\" app.\n\n## Explore additional dependency discovery methods.\n\n## \"Live\" image create mode - to create new images from containers where users install their applications interactively.\n\n## Classic container image optimizations (aka ability to disable minification based on dynamic/static analysis)\n\n- Docker image flattening\n- OS specific cleanup commands (optional)\n\n## Native Windows Support\n\nOriginal issue:\n\n- <https://github.com/docker-slim/docker-slim/issues/57>\n\n## Provide an Audit Log for the Removed Files\n\nOriginal issue:\n\n- <https://github.com/docker-slim/docker-slim/issues/67>\n\n## Dockerizing Local Applications (Linux Only)\n\nDockerizing local applications and creating minified images for them.\n\n## Minifying Local Applications and Saving to Directory (Linux Only)\n\nOriginal issue:\n\n- <https://github.com/docker-slim/docker-slim/issues/60>\n\n## Podman Support\n\nOriginal issues:\n\n- <https://github.com/docker-slim/docker-slim/issues/91>\n- <https://github.com/docker-slim/docker-slim/issues/99>\n\n## Windows Container Support\n\nOriginal issues:\n\n- <https://github.com/docker-slim/docker-slim/issues/77>\n"
  },
  {
    "path": "assets/images/docs/SlimHow.excalidraw",
    "content": "{\n  \"type\": \"excalidraw\",\n  \"version\": 2,\n  \"source\": \"https://excalidraw.com\",\n  \"elements\": [\n    {\n      \"type\": \"rectangle\",\n      \"version\": 315,\n      \"versionNonce\": 1437085463,\n      \"isDeleted\": false,\n      \"id\": \"z5FJM2AF322l6jPcAbRUT\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 60,\n      \"angle\": 0,\n      \"x\": 433.236328125,\n      \"y\": 462.1044921875,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#ced4da\",\n      \"width\": 119.07421875,\n      \"height\": 60.2578125,\n      \"seed\": 2130074937,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"id\": \"t5q3DU5ObK_JRfQ6w1xnQ\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"V5vFMqArwYWyLiCq52rz3\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277748492,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 231,\n      \"versionNonce\": 1785310969,\n      \"isDeleted\": false,\n      \"id\": \"CPRJJsoQCL9gIWgMlqRSW\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 70,\n      \"angle\": 0,\n      \"x\": 610.5283203125,\n      \"y\": 575.9296875,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"#ced4da\",\n      \"width\": 257,\n      \"height\": 85,\n      \"seed\": 1618919993,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 1\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"t5q3DU5ObK_JRfQ6w1xnQ\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"RVgkHQgXZXIxCj76R427q\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"BfrdlP1Cm8qndUsOb9Uyr\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"sM8K4HhcbMtur8rrMNU7R\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"uFyv2pSPIcyBia8PNAfgX\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277590802,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 448,\n      \"versionNonce\": 1587188953,\n      \"isDeleted\": false,\n      \"id\": \"FYTFj4-mnR4zFfjpeWS5f\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 40,\n      \"angle\": 0,\n      \"x\": 121.69189453125,\n      \"y\": 821.80224609375,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"#15aabf\",\n      \"width\": 267.2802734375,\n      \"height\": 105.56640624999999,\n      \"seed\": 521273,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 1\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"uFyv2pSPIcyBia8PNAfgX\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"_rYpNumYsf_s6iMScQHjX\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"sM8K4HhcbMtur8rrMNU7R\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277053785,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 136,\n      \"versionNonce\": 1620316665,\n      \"isDeleted\": false,\n      \"id\": \"QOHGSkDnHQWYI-H2QmJiR\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 70,\n      \"angle\": 0,\n      \"x\": 614.451171875,\n      \"y\": 399.01953125,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#15aabf\",\n      \"width\": 252.7470703125,\n      \"height\": 84.02734375,\n      \"seed\": 1780101943,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"id\": \"RVgkHQgXZXIxCj76R427q\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277165337,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 171,\n      \"versionNonce\": 1703457160,\n      \"isDeleted\": false,\n      \"id\": \"DG1lDpjssUskLgYXdBntC\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 640.5009765625,\n      \"y\": 425.1005859375,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 205,\n      \"height\": 30,\n      \"seed\": 491250873,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1673285239485,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 24.855468749999993,\n      \"fontFamily\": 3,\n      \"text\": \"original image\",\n      \"baseline\": 24,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"original image\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 1333,\n      \"versionNonce\": 1149242248,\n      \"isDeleted\": false,\n      \"id\": \"dM4b1D2w11licRcaXwKCI\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 406.2029128389365,\n      \"y\": 241.02862936877142,\n      \"strokeColor\": \"#364fc7\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 806,\n      \"height\": 106,\n      \"seed\": 1982017081,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1673285172173,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 46.19083069132936,\n      \"fontFamily\": 2,\n      \"text\": \"How Slim makes images smaller, faster\\n...and more secure\",\n      \"baseline\": 96,\n      \"textAlign\": \"right\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"How Slim makes images smaller, faster\\n...and more secure\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 301,\n      \"versionNonce\": 2047994489,\n      \"isDeleted\": false,\n      \"id\": \"PqX1zxQsw9VE86_SzdHQt\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 20,\n      \"angle\": 0,\n      \"x\": 611.859375,\n      \"y\": 752.9091796875,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#ced4da\",\n      \"width\": 253.396484375,\n      \"height\": 117.71484374999994,\n      \"seed\": 293155001,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1652277601970,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 396,\n      \"versionNonce\": 401807193,\n      \"isDeleted\": false,\n      \"id\": \"crQQzA8TS6rb5RWykT26t\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 70,\n      \"angle\": 0,\n      \"x\": 610.505859375,\n      \"y\": 962.2109375,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#15aabf\",\n      \"width\": 254,\n      \"height\": 48,\n      \"seed\": 1079428281,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"id\": \"wz_CJ_GfqheVtN5tUFmax\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"_rYpNumYsf_s6iMScQHjX\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277239768,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 736,\n      \"versionNonce\": 1589654117,\n      \"isDeleted\": false,\n      \"id\": \"GbjLgg--QdFAwXGlfgW_T\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 85.2552083333334,\n      \"y\": 333.7072405133929,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 568,\n      \"height\": 34,\n      \"seed\": 538091993,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1673284487993,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 28.461916095800987,\n      \"fontFamily\": 3,\n      \"text\": \"$ slim build --target nginx:latest\",\n      \"baseline\": 28,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"$ slim build --target nginx:latest\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 855,\n      \"versionNonce\": 2079903609,\n      \"isDeleted\": false,\n      \"id\": \"vBMcaaFI9kuqkow1X67Yi\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 80,\n      \"angle\": 0,\n      \"x\": 611.2001953125,\n      \"y\": 1020.8388671875,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#fab005\",\n      \"width\": 251,\n      \"height\": 41,\n      \"seed\": 787876665,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [\n        {\n          \"id\": \"QeTboF3pareoNleVc6BRi\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277256179,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 2170,\n      \"versionNonce\": 896420249,\n      \"isDeleted\": false,\n      \"id\": \"sM8K4HhcbMtur8rrMNU7R\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"dashed\",\n      \"roughness\": 1,\n      \"opacity\": 50,\n      \"angle\": 0,\n      \"x\": 385.2291230938969,\n      \"y\": 602.1984828376064,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 221.72107221860313,\n      \"height\": 19.770614981174276,\n      \"seed\": 1331821687,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277951776,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"zasfCRJFIwlKmgpkmVLKv\",\n        \"focus\": -0.4186831681048361,\n        \"gap\": 14.42712114077176\n      },\n      \"endBinding\": {\n        \"elementId\": \"CPRJJsoQCL9gIWgMlqRSW\",\n        \"focus\": -0.283861701539277,\n        \"gap\": 3.578125\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": null,\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          221.72107221860313,\n          19.770614981174276\n        ]\n      ]\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 714,\n      \"versionNonce\": 391364375,\n      \"isDeleted\": false,\n      \"id\": \"t5q3DU5ObK_JRfQ6w1xnQ\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"dashed\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 547.7092635363069,\n      \"y\": 526.7060994337498,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 61.5425314704446,\n      \"height\": 49.59285764199774,\n      \"seed\": 515474615,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277889185,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"z5FJM2AF322l6jPcAbRUT\",\n        \"focus\": -0.12542319940551994,\n        \"gap\": 4.343794746249841\n      },\n      \"endBinding\": {\n        \"elementId\": \"CPRJJsoQCL9gIWgMlqRSW\",\n        \"focus\": -0.4275761472351255,\n        \"gap\": 1.2765253057484642\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          61.5425314704446,\n          49.59285764199774\n        ]\n      ]\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 463,\n      \"versionNonce\": 1622338649,\n      \"isDeleted\": false,\n      \"id\": \"bqnQdIHAkULBIug1XcmPG\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 441.8232421875,\n      \"y\": 420.7783203125,\n      \"strokeColor\": \"#d9480f\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 110,\n      \"height\": 30,\n      \"seed\": 1243474103,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"V5vFMqArwYWyLiCq52rz3\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652278037947,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 23.804687500000046,\n      \"fontFamily\": 1,\n      \"text\": \"...injected\",\n      \"baseline\": 21,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"...injected\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 462,\n      \"versionNonce\": 443190231,\n      \"isDeleted\": false,\n      \"id\": \"RVgkHQgXZXIxCj76R427q\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 743.4718635056754,\n      \"y\": 488.46550802076536,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 0,\n      \"height\": 80.0842839888669,\n      \"seed\": 280942169,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652278050690,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"QOHGSkDnHQWYI-H2QmJiR\",\n        \"focus\": -0.020947079395637863,\n        \"gap\": 5.4186330207653555\n      },\n      \"endBinding\": {\n        \"elementId\": \"CPRJJsoQCL9gIWgMlqRSW\",\n        \"focus\": 0.03458010267062569,\n        \"gap\": 7.379895490367744\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          0,\n          80.0842839888669\n        ]\n      ]\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 2012,\n      \"versionNonce\": 81754937,\n      \"isDeleted\": false,\n      \"id\": \"uFyv2pSPIcyBia8PNAfgX\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"dashed\",\n      \"roughness\": 1,\n      \"opacity\": 50,\n      \"angle\": 0,\n      \"x\": 391.6142700172496,\n      \"y\": 724.4170629482254,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 218.19024224766747,\n      \"height\": 73.20081820558028,\n      \"seed\": 1434877081,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652278291361,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"i_JDhedICwAdWdxkiudrF\",\n        \"focus\": 0.34566114961327016,\n        \"gap\": 5.454602048499623\n      },\n      \"endBinding\": {\n        \"elementId\": \"CPRJJsoQCL9gIWgMlqRSW\",\n        \"focus\": 0.12342916764409954,\n        \"gap\": 1\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": null,\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          218.19024224766747,\n          -73.20081820558028\n        ]\n      ]\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 208,\n      \"versionNonce\": 113407577,\n      \"isDeleted\": false,\n      \"id\": \"JzjVz4GXgYEQjEGYJmImJ\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 622.744140625,\n      \"y\": 762.8055462861181,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 203,\n      \"height\": 98,\n      \"seed\": 853002329,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"BfrdlP1Cm8qndUsOb9Uyr\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"wz_CJ_GfqheVtN5tUFmax\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277508373,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 20.395532349246235,\n      \"fontFamily\": 3,\n      \"text\": \"   Usage report\\n- files accessed\\n- syscalls issued\\n- certs detected\",\n      \"baseline\": 93,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"   Usage report\\n- files accessed\\n- syscalls issued\\n- certs detected\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 1201,\n      \"versionNonce\": 246888101,\n      \"isDeleted\": false,\n      \"id\": \"WrWXFw3ZUzBc8EWTQaN9a\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 139.72831864567638,\n      \"y\": 833.4317599335407,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 231,\n      \"height\": 86,\n      \"seed\": 622664953,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"_rYpNumYsf_s6iMScQHjX\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673284433631,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 22.383996272638267,\n      \"fontFamily\": 1,\n      \"text\": \"...contains only files\\nthat have been used\\nor allow-listed!\",\n      \"baseline\": 77,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"...contains only files\\nthat have been used\\nor allow-listed!\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 289,\n      \"versionNonce\": 101505911,\n      \"isDeleted\": false,\n      \"id\": \"_oadoJngWdG6I-ukx4lVQ\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1012.060546875,\n      \"y\": 423.767578125,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 96,\n      \"height\": 46,\n      \"seed\": 401330327,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277522957,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 36.01924189814814,\n      \"fontFamily\": 1,\n      \"text\": \"Input\",\n      \"baseline\": 32,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Input\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 533,\n      \"versionNonce\": 1599961145,\n      \"isDeleted\": false,\n      \"id\": \"SrROoMHa6yZE1bPrQlyug\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1007.0869140625,\n      \"y\": 993.3746925636574,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 127,\n      \"height\": 46,\n      \"seed\": 561191607,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277086720,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 36.01924189814814,\n      \"fontFamily\": 1,\n      \"text\": \"Output\",\n      \"baseline\": 32,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Output\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 419,\n      \"versionNonce\": 110228951,\n      \"isDeleted\": false,\n      \"id\": \"1Wyoi3jBu6hHSKrc54wuX\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1001.08984375,\n      \"y\": 786.3388671875,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 168,\n      \"height\": 46,\n      \"seed\": 940889113,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277089165,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 36.01924189814814,\n      \"fontFamily\": 1,\n      \"text\": \"Artifacts\",\n      \"baseline\": 32,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Artifacts\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 437,\n      \"versionNonce\": 692570841,\n      \"isDeleted\": false,\n      \"id\": \"R9CCEm5odcJmVEN_Hv3WD\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 1007.5380859375,\n      \"y\": 595.416015625,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 172,\n      \"height\": 46,\n      \"seed\": 886007447,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277848435,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 36.01924189814814,\n      \"fontFamily\": 1,\n      \"text\": \"Monitoring\",\n      \"baseline\": 32,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Monitoring\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 407,\n      \"versionNonce\": 217048889,\n      \"isDeleted\": false,\n      \"id\": \"BfrdlP1Cm8qndUsOb9Uyr\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 744.9128571963805,\n      \"y\": 669.0392584528588,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 0.8645066131217618,\n      \"height\": 79.2116003332593,\n      \"seed\": 492680345,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652278054270,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"CPRJJsoQCL9gIWgMlqRSW\",\n        \"focus\": -0.049912317353729085,\n        \"gap\": 8.109570952858803\n      },\n      \"endBinding\": {\n        \"elementId\": \"JzjVz4GXgYEQjEGYJmImJ\",\n        \"focus\": 0.18729477388763419,\n        \"gap\": 14.5546875\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          -0.8645066131217618,\n          79.2116003332593\n        ]\n      ]\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 343,\n      \"versionNonce\": 512939959,\n      \"isDeleted\": false,\n      \"id\": \"wz_CJ_GfqheVtN5tUFmax\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 744.6362904671561,\n      \"y\": 876.8055462861182,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 0.22841240668788032,\n      \"height\": 77.80103853531045,\n      \"seed\": 428109753,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277881130,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"JzjVz4GXgYEQjEGYJmImJ\",\n        \"focus\": -0.19872764374547802,\n        \"gap\": 16\n      },\n      \"endBinding\": {\n        \"elementId\": \"crQQzA8TS6rb5RWykT26t\",\n        \"focus\": 0.058641711083579316,\n        \"gap\": 7.604352678571331\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": \"arrow\",\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          0.22841240668788032,\n          77.80103853531045\n        ]\n      ]\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 486,\n      \"versionNonce\": 1852162952,\n      \"isDeleted\": false,\n      \"id\": \"V00LcEEQ_gK9fHP0y5o1T\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 818.8847656249998,\n      \"y\": 514.744140625,\n      \"strokeColor\": \"#d9480f\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 192,\n      \"height\": 31,\n      \"seed\": 309311449,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1673285330321,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 24.60546875000003,\n      \"fontFamily\": 1,\n      \"text\": \"Start container\",\n      \"baseline\": 22,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Start container\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 431,\n      \"versionNonce\": 342087928,\n      \"isDeleted\": false,\n      \"id\": \"3l0CLOhz3zEXXW6HtE8ZQ\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 811.546875,\n      \"y\": 694.6171875,\n      \"strokeColor\": \"#d9480f\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 229,\n      \"height\": 32,\n      \"seed\": 945625687,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1673285206328,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 25.542968750000032,\n      \"fontFamily\": 1,\n      \"text\": \"Collect intelligence\",\n      \"baseline\": 23,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Collect intelligence\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 885,\n      \"versionNonce\": 311163640,\n      \"isDeleted\": false,\n      \"id\": \"v3pcwqTE_okdLy0SnTK-u\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 811.8203125,\n      \"y\": 887.5185856894842,\n      \"strokeColor\": \"#d9480f\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 310,\n      \"height\": 60,\n      \"seed\": 376023255,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1673285210447,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 23.871651785714267,\n      \"fontFamily\": 1,\n      \"text\": \"Build slim image &\\nGenerate security profiles\",\n      \"baseline\": 51,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Build slim image &\\nGenerate security profiles\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 1708,\n      \"versionNonce\": 1315138071,\n      \"isDeleted\": false,\n      \"id\": \"_rYpNumYsf_s6iMScQHjX\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"dashed\",\n      \"roughness\": 1,\n      \"opacity\": 50,\n      \"angle\": 0,\n      \"x\": 389.8753776410778,\n      \"y\": 910.4155513824027,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 216.6888320638979,\n      \"height\": 57.55225935236285,\n      \"seed\": 388971671,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277933826,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"WrWXFw3ZUzBc8EWTQaN9a\",\n        \"focus\": -0.01603557213069114,\n        \"gap\": 19.6931103884736\n      },\n      \"endBinding\": {\n        \"elementId\": \"crQQzA8TS6rb5RWykT26t\",\n        \"focus\": -0.2864109335297447,\n        \"gap\": 3.941649670024276\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": null,\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          216.6888320638979,\n          57.55225935236285\n        ]\n      ]\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 853,\n      \"versionNonce\": 769412325,\n      \"isDeleted\": false,\n      \"id\": \"rILfc2fIcaTQXZMawymNt\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 85.2490234375,\n      \"y\": 260.3280741373698,\n      \"strokeColor\": \"#d9480f\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 122,\n      \"height\": 60,\n      \"seed\": 2106685079,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1673284473184,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 23.489067485367045,\n      \"fontFamily\": 1,\n      \"text\": \"Turn-key\\nexperience!\",\n      \"baseline\": 51,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Turn-key\\nexperience!\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 502,\n      \"versionNonce\": 1521493625,\n      \"isDeleted\": false,\n      \"id\": \"gfNwGmVCEp-4jZWpPJdmi\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 40,\n      \"angle\": 0,\n      \"x\": 120.34521484375,\n      \"y\": 958.528076171875,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"#15aabf\",\n      \"width\": 267.2802734375,\n      \"height\": 88.59375,\n      \"seed\": 598563481,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 1\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"uFyv2pSPIcyBia8PNAfgX\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"_rYpNumYsf_s6iMScQHjX\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"QeTboF3pareoNleVc6BRi\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277075868,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 1317,\n      \"versionNonce\": 1429967205,\n      \"isDeleted\": false,\n      \"id\": \"BIbK5nClxTKKeZyQVy-th\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 138.04616477272685,\n      \"y\": 973.9619140625,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 236,\n      \"height\": 56,\n      \"seed\": 2000031479,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"QeTboF3pareoNleVc6BRi\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673284433633,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 22.237859080018172,\n      \"fontFamily\": 1,\n      \"text\": \"...can be used for\\nfuture container runs\",\n      \"baseline\": 48,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"...can be used for\\nfuture container runs\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 1798,\n      \"versionNonce\": 690402521,\n      \"isDeleted\": false,\n      \"id\": \"QeTboF3pareoNleVc6BRi\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"dashed\",\n      \"roughness\": 1,\n      \"opacity\": 50,\n      \"angle\": 0,\n      \"x\": 389.64943041233084,\n      \"y\": 1012.8135126541206,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 218.37225484115527,\n      \"height\": 32.670948771896064,\n      \"seed\": 1016723929,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652278282558,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"BIbK5nClxTKKeZyQVy-th\",\n        \"focus\": -0.19757405030399774,\n        \"gap\": 15.562516349830872\n      },\n      \"endBinding\": {\n        \"elementId\": \"dTwf5rZDEkp-V27Ai9lU3\",\n        \"focus\": -0.7613862562065846,\n        \"gap\": 14.963666309013888\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": null,\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          218.37225484115527,\n          32.670948771896064\n        ]\n      ]\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 456,\n      \"versionNonce\": 1790881081,\n      \"isDeleted\": false,\n      \"id\": \"KhmJMkd5HKY0qq1lceBTL\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 40,\n      \"angle\": 0,\n      \"x\": 118.63525390625,\n      \"y\": 559.05322265625,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"#15aabf\",\n      \"width\": 267.2802734375,\n      \"height\": 99.20410156250006,\n      \"seed\": 1801822617,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 1\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"sM8K4HhcbMtur8rrMNU7R\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"uFyv2pSPIcyBia8PNAfgX\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277942774,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 782,\n      \"versionNonce\": 97896633,\n      \"isDeleted\": false,\n      \"id\": \"zasfCRJFIwlKmgpkmVLKv\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 129.8020019531251,\n      \"y\": 571.1163736979165,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 241,\n      \"height\": 81,\n      \"seed\": 544317559,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"sM8K4HhcbMtur8rrMNU7R\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277951775,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 21.447541316350293,\n      \"fontFamily\": 1,\n      \"text\": \"Probe running container\\n- Send HTTP requests\\n- Exec commands\",\n      \"baseline\": 73,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Probe running container\\n- Send HTTP requests\\n- Exec commands\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 566,\n      \"versionNonce\": 1169826359,\n      \"isDeleted\": false,\n      \"id\": \"i_JDhedICwAdWdxkiudrF\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 40,\n      \"angle\": 0,\n      \"x\": 118.87939453125,\n      \"y\": 689.099609375,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"#15aabf\",\n      \"width\": 267.2802734375,\n      \"height\": 98.8134765625,\n      \"seed\": 655355703,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 1\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"uFyv2pSPIcyBia8PNAfgX\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277965303,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 900,\n      \"versionNonce\": 1527538539,\n      \"isDeleted\": false,\n      \"id\": \"6-9VXYHfqETW1jPuxlEkR\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 136.07952277861432,\n      \"y\": 697.47119140625,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 223,\n      \"height\": 84,\n      \"seed\": 93520825,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1673284433634,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 22.15852204288347,\n      \"fontFamily\": 1,\n      \"text\": \"Apply heuristics\\n- find SSL certs\\n- detect shells, etc.\",\n      \"baseline\": 76,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"Apply heuristics\\n- find SSL certs\\n- detect shells, etc.\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 252,\n      \"versionNonce\": 2057015800,\n      \"isDeleted\": false,\n      \"id\": \"pEd0fds1ka7qENQ9DIWVu\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 661.8134765625,\n      \"y\": 971.4794921875,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 147,\n      \"height\": 30,\n      \"seed\": 1189050327,\n      \"groupIds\": [],\n      \"roundness\": null,\n      \"boundElements\": [],\n      \"updated\": 1673285246587,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 24.855468749999993,\n      \"fontFamily\": 3,\n      \"text\": \"slim image\",\n      \"baseline\": 24,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"slim image\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 87,\n      \"versionNonce\": 1961761989,\n      \"isDeleted\": false,\n      \"id\": \"dTwf5rZDEkp-V27Ai9lU3\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"dashed\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 623.0654296875005,\n      \"y\": 1028.97265625,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#fab005\",\n      \"width\": 229,\n      \"height\": 26,\n      \"seed\": 1400126743,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"QeTboF3pareoNleVc6BRi\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673284433634,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 21.611328125000043,\n      \"fontFamily\": 3,\n      \"text\": \"AppArmor & seccomp\",\n      \"baseline\": 21,\n      \"textAlign\": \"right\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"AppArmor & seccomp\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 217,\n      \"versionNonce\": 1876461561,\n      \"isDeleted\": false,\n      \"id\": \"oRPMpJJXx9jtmBzX17fXM\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 679.515625,\n      \"y\": 589.7587890625,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#ced4da\",\n      \"width\": 124,\n      \"height\": 56,\n      \"seed\": 321048313,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277479950,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 23.352864583333275,\n      \"fontFamily\": 3,\n      \"text\": \"tmp\\ncontainer\",\n      \"baseline\": 51,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"tmp\\ncontainer\"\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 288,\n      \"versionNonce\": 543842327,\n      \"isDeleted\": false,\n      \"id\": \"cgn0SQz_n5ih5Kfi34k8T\",\n      \"fillStyle\": \"solid\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 450.4482421875,\n      \"y\": 476.158203125,\n      \"strokeColor\": \"#000000\",\n      \"backgroundColor\": \"#ced4da\",\n      \"width\": 83,\n      \"height\": 28,\n      \"seed\": 1989060951,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277570463,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 23.352864583333275,\n      \"fontFamily\": 3,\n      \"text\": \"sensor\",\n      \"baseline\": 23,\n      \"textAlign\": \"center\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"sensor\"\n    },\n    {\n      \"type\": \"rectangle\",\n      \"version\": 553,\n      \"versionNonce\": 449118233,\n      \"isDeleted\": false,\n      \"id\": \"FBg8KHuxXgjqikZHW44mF\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 1,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 40,\n      \"angle\": 0,\n      \"x\": 117.75146484375,\n      \"y\": 428.31591796875,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"#15aabf\",\n      \"width\": 267.2802734375,\n      \"height\": 96.1962890625,\n      \"seed\": 825056697,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 1\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"sM8K4HhcbMtur8rrMNU7R\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"uFyv2pSPIcyBia8PNAfgX\",\n          \"type\": \"arrow\"\n        },\n        {\n          \"id\": \"V5vFMqArwYWyLiCq52rz3\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1652277753742,\n      \"link\": null,\n      \"locked\": false\n    },\n    {\n      \"type\": \"text\",\n      \"version\": 973,\n      \"versionNonce\": 774028811,\n      \"isDeleted\": false,\n      \"id\": \"8hru3Ov7Y2SQk8-ogQPD1\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"solid\",\n      \"roughness\": 1,\n      \"opacity\": 100,\n      \"angle\": 0,\n      \"x\": 147.1025390624999,\n      \"y\": 436.326171875,\n      \"strokeColor\": \"#343a40\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 198,\n      \"height\": 83,\n      \"seed\": 2001103255,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [\n        {\n          \"id\": \"sM8K4HhcbMtur8rrMNU7R\",\n          \"type\": \"arrow\"\n        }\n      ],\n      \"updated\": 1673284433634,\n      \"link\": null,\n      \"locked\": false,\n      \"fontSize\": 21.80801497565377,\n      \"fontFamily\": 1,\n      \"text\": \"...supports multiple\\nmonitors: ptrace,\\nfanotify, etc.\",\n      \"baseline\": 75,\n      \"textAlign\": \"left\",\n      \"verticalAlign\": \"top\",\n      \"containerId\": null,\n      \"originalText\": \"...supports multiple\\nmonitors: ptrace,\\nfanotify, etc.\"\n    },\n    {\n      \"type\": \"arrow\",\n      \"version\": 2334,\n      \"versionNonce\": 398947705,\n      \"isDeleted\": false,\n      \"id\": \"V5vFMqArwYWyLiCq52rz3\",\n      \"fillStyle\": \"hachure\",\n      \"strokeWidth\": 2,\n      \"strokeStyle\": \"dashed\",\n      \"roughness\": 1,\n      \"opacity\": 50,\n      \"angle\": 0,\n      \"x\": 387.0132970958768,\n      \"y\": 483.00853630125755,\n      \"strokeColor\": \"#495057\",\n      \"backgroundColor\": \"transparent\",\n      \"width\": 40.42427847351763,\n      \"height\": 5.393809927460552,\n      \"seed\": 14150681,\n      \"groupIds\": [],\n      \"roundness\": {\n        \"type\": 2\n      },\n      \"boundElements\": [],\n      \"updated\": 1652277766342,\n      \"link\": null,\n      \"locked\": false,\n      \"startBinding\": {\n        \"elementId\": \"FBg8KHuxXgjqikZHW44mF\",\n        \"focus\": -0.1744512163789095,\n        \"gap\": 1.9815588146267942\n      },\n      \"endBinding\": {\n        \"elementId\": \"z5FJM2AF322l6jPcAbRUT\",\n        \"focus\": -0.12835124589854846,\n        \"gap\": 5.798752555605574\n      },\n      \"lastCommittedPoint\": null,\n      \"startArrowhead\": null,\n      \"endArrowhead\": null,\n      \"points\": [\n        [\n          0,\n          0\n        ],\n        [\n          40.42427847351763,\n          5.393809927460552\n        ]\n      ]\n    }\n  ],\n  \"appState\": {\n    \"gridSize\": null,\n    \"viewBackgroundColor\": \"#ffffff\"\n  },\n  \"files\": {}\n}"
  },
  {
    "path": "build/package/docker/.dockerignore",
    "content": "**\n!dist_linux/**\n!build/package/docker/.ds.container.d3e2c84f976743bdb92a7044ef12e381\n**/.DS_Store\n**/*.command\n"
  },
  {
    "path": "build/package/docker/.ds.container.d3e2c84f976743bdb92a7044ef12e381",
    "content": ""
  },
  {
    "path": "build/package/docker/Dockerfile",
    "content": "FROM alpine:latest as ca-certs\nLABEL build-role=ca-certs\nRUN apk update && apk upgrade && apk add --no-cache ca-certificates && update-ca-certificates 2>/dev/null || true\n\nFROM scratch\nLABEL app=slim\nCOPY --from=ca-certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt\nCOPY dist_linux /bin\nCOPY build/package/docker/.ds.container.d3e2c84f976743bdb92a7044ef12e381 /.ds.container.d3e2c84f976743bdb92a7044ef12e381\nVOLUME /bin/.slim-state\nENTRYPOINT [\"/bin/slim\"]\n\n\n"
  },
  {
    "path": "build/package/docker/Dockerfile.arm",
    "content": "FROM alpine:latest as ca-certs\nLABEL build-role=ca-certs\nRUN apk update && apk upgrade && apk add --no-cache ca-certificates && update-ca-certificates 2>/dev/null || true\n\nFROM scratch\nLABEL app=slim\nCOPY --from=ca-certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt\nCOPY dist_linux_arm64 /bin\nCOPY build/package/docker/.ds.container.d3e2c84f976743bdb92a7044ef12e381 /.ds.container.d3e2c84f976743bdb92a7044ef12e381\nVOLUME /bin/.slim-state\nENTRYPOINT [\"/bin/slim\"]\n\n\n"
  },
  {
    "path": "build/package/docker/build.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\ndocker build --squash --rm -t slim -f Dockerfile ../../..\ndocker image prune --filter label=build-role=ca-certs -f\ndocker image prune --filter label=app=slim -f"
  },
  {
    "path": "build/package/docker/build_arm.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\ndocker build --platform linux/arm64 -t slim-arm -f Dockerfile.arm ../../..\ndocker image prune --filter label=build-role=ca-certs -f\ndocker image prune --filter label=app=slim -f"
  },
  {
    "path": "build/package/docker/dockerhub_publish.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/../../..\" && pwd )\"\n\nTAG=\"current\"\npushd $BDIR\nif hash git 2>/dev/null && [ -e $BDIR/.git ]; then\n  TAG=\"$(git describe --tags)\"\nfi\npopd\n\ndocker tag slim dslim/slim:$TAG\ndocker tag slim dslim/slim\ndocker push dslim/slim:$TAG\ndocker push dslim/slim\n"
  },
  {
    "path": "build/package/docker/dockerhub_publish_arm.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/../../..\" && pwd )\"\n\nTAG=\"current\"\npushd $BDIR\nif hash git 2>/dev/null && [ -e $BDIR/.git ]; then\n  TAG=\"$(git describe --tags)\"\nfi\npopd\n\ndocker tag slim-arm dslim/slim-arm:$TAG\ndocker tag slim-arm dslim/slim-arm\ndocker push dslim/slim-arm:$TAG\ndocker push dslim/slim-arm\n"
  },
  {
    "path": "build/package/docker/mac/build.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./build.sh\n\n\n\n"
  },
  {
    "path": "build/package/docker/mac/build_arm.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./build_arm.sh\n\n\n\n"
  },
  {
    "path": "build/package/docker/mac/dockerhub_login.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here\n\ndocker login --username dslim\n\n"
  },
  {
    "path": "build/package/docker/mac/dockerhub_publish.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./dockerhub_publish.sh\n\n\n\n"
  },
  {
    "path": "build/package/docker/mac/dockerhub_publish_arm.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./dockerhub_publish_arm.sh\n\n\n\n"
  },
  {
    "path": "build/package/rpm/slim.spec",
    "content": "%global go_version 1.18.2\n\nName: slim\nVersion: 1.40.6\nRelease: 1%{?dist}\nSummary: Slim Toolkit helps you make your containers better, smaller, and secure\nLicense: Apache-2.0\nBuildRequires: golang >= %{go_version}\nURL: https://github.com/slimtoolkit/slim\nSource0: https://github.com/slimtoolkit/slim/archive/refs/tags/%{version}.tar.gz\n\n%define debug_package %{nil}\n\n%prep\n%autosetup\n\n%description\nSlim Toolkit helps you make your containers better, smaller, and secure\n\n%ifarch x86_64\n%define goarch amd64\n%endif\n\n%ifarch aarch64\n%define goarch arm64\n%endif\n\n%ifarch arm\n%define goarch arm\n%endif\n\n%global slim_version %(git describe --tags --always)\n%global slim_revision %(git rev-parse HEAD)\n%global slim_buildtime %(date '+%Y-%m-%d_%I:%M:%''S')\n%global slim_ldflags -s -w -X github.com/docker-slim/docker-slim/pkg/version.appVersionTag=%{slim_version} -X github.com/docker-slim/docker-slim/pkg/version.appVersionRev=%{slim_revision} -X github.com/docker-slim/docker-slim/pkg/version.appVersionTime=%{slim_buildtime}\n\n%build\nexport CGO_ENABLED=0\ngo generate github.com/docker-slim/docker-slim/pkg/appbom\nmkdir dist_linux\nGOOS=linux GOARCH=%{goarch} go build  -mod=vendor -trimpath -ldflags=\"%{slim_ldflags}\" -a -tags 'netgo osusergo' -o \"dist_linux/\" ./cmd/slim/...\nGOOS=linux GOARCH=%{goarch} go build -mod=vendor -trimpath -ldflags=\"%{slim_ldflags}\" -a -tags 'netgo osusergo' -o \"dist_linux/\" ./cmd/slim-sensor/...\n\n%install\ninstall -d -m 755 %{buildroot}%{_bindir}\ninstall -d -m 755 %{buildroot}%{_bindir}\ninstall -d -m 755 %{buildroot}/usr/share/doc/slim/\ninstall -d -m 755 %{buildroot}/usr/share/licenses/slim/\ninstall -m 755 dist_linux/%{name} %{buildroot}%{_bindir}\ninstall -m 755 dist_linux/%{name}-sensor %{buildroot}%{_bindir}\ninstall -m 644 README.md %{buildroot}/usr/share/doc/slim/README.md\ninstall -m 644 LICENSE %{buildroot}/usr/share/licenses/slim/LICENSE\n\n%post\n%{__ln_s} -f %{_bindir}/%{name} %{_bindir}/docker-slim\nchmod a+x %{_bindir}/%{name}\nchmod a+x %{_bindir}/%{name}-sensor\n\n%files \n%{_bindir}/%{name}\n%{_bindir}/%{name}-sensor\n%doc /usr/share/doc/slim/README.md\n%license /usr/share/licenses/slim/LICENSE\n"
  },
  {
    "path": "cmd/slim/main.go",
    "content": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master\"\n)\n\nfunc main() {\n\tif len(os.Args) > 1 && os.Args[1] == \"slim\" {\n\t\t//hack to handle plugin invocations\n\t\tos.Args = append([]string{os.Args[0]}, os.Args[2:]...)\n\t}\n\n\tapp.Run()\n}\n"
  },
  {
    "path": "cmd/slim-sensor/main.go",
    "content": "package main\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor\"\n)\n\nfunc main() {\n\tsensor.Run()\n}\n"
  },
  {
    "path": "examples/README.md",
    "content": "# Examples\n\nThe containerized application examples have been moved to a separate repo: https://github.com/slimtoolkit/examples\n\nThe examples cover many different base images and programming languages (and language frameworks). Pick one that looks close enough to your app and use it as a starting point if you want to minify your application container image.\n\n"
  },
  {
    "path": "examples/k8s_nginx_cgr/manifest.yaml",
    "content": "apiVersion: v1\nkind: Pod\nmetadata:\n  name: example-pod\n  labels:\n    name: nginx\nspec:\n  containers:\n  - name: example-container\n    image: cgr.dev/chainguard/nginx:latest\n    ports:\n    - containerPort: 8080\n      hostPort: 8080\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/slimtoolkit/slim\n\ngo 1.24.0\n\nrequire (\n\tgithub.com/armon/go-radix v1.0.0\n\tgithub.com/bmatcuk/doublestar v1.3.4\n\tgithub.com/bmatcuk/doublestar/v3 v3.0.0\n\tgithub.com/c-bata/go-prompt v0.2.3\n\tgithub.com/c4milo/unpackit v0.0.0-20170704181138-4ed373e9ef1c\n\tgithub.com/cespare/xxhash/v2 v2.2.0\n\tgithub.com/compose-spec/compose-go v0.0.0-20210916141509-a7e1bc322970\n\tgithub.com/docker/docker v25.0.6+incompatible\n\tgithub.com/docker/go-connections v0.4.0\n\tgithub.com/dustin/go-humanize v1.0.0\n\tgithub.com/fatih/color v1.13.0\n\tgithub.com/fsouza/go-dockerclient v1.10.0\n\tgithub.com/getkin/kin-openapi v0.131.0\n\tgithub.com/ghodss/yaml v1.0.0\n\tgithub.com/gocolly/colly/v2 v2.1.0\n\tgithub.com/google/go-containerregistry v0.19.0\n\tgithub.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510\n\tgithub.com/gorilla/websocket v1.4.2\n\tgithub.com/jedib0t/go-pretty/v6 v6.4.9\n\tgithub.com/moby/term v0.5.0\n\tgithub.com/opencontainers/image-spec v1.1.0-rc5\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/segmentio/ksuid v1.0.4\n\tgithub.com/sirupsen/logrus v1.9.3\n\tgithub.com/slimtoolkit/go-update v0.0.0-20231119011834-99945ebd76f7\n\tgithub.com/slimtoolkit/uiprogress v0.0.0-20231119012247-4a052fb12f37\n\tgithub.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635\n\tgithub.com/urfave/cli/v2 v2.27.1\n\tgolang.org/x/crypto v0.45.0\n\tgolang.org/x/net v0.47.0\n\tgolang.org/x/sys v0.38.0\n\tk8s.io/api v0.27.3\n\tk8s.io/apimachinery v0.27.3\n\tk8s.io/cli-runtime v0.27.3\n\tk8s.io/client-go v0.27.3\n)\n\nrequire (\n\tgithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect\n\tgithub.com/Microsoft/go-winio v0.6.1 // indirect\n\tgithub.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 // indirect\n\tgithub.com/containerd/log v0.1.0 // indirect\n\tgithub.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect\n\tgithub.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect\n\tgithub.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e // indirect\n\tgithub.com/distribution/reference v0.6.0 // indirect\n\tgithub.com/docker/cli v24.0.0+incompatible // indirect\n\tgithub.com/docker/distribution v2.8.2+incompatible // indirect\n\tgithub.com/docker/docker-credential-helpers v0.7.0 // indirect\n\tgithub.com/docker/go-units v0.5.0 // indirect\n\tgithub.com/emicklei/go-restful/v3 v3.10.1 // indirect\n\tgithub.com/evanphx/json-patch v4.12.0+incompatible // indirect\n\tgithub.com/felixge/httpsnoop v1.0.3 // indirect\n\tgithub.com/go-errors/errors v1.4.2 // indirect\n\tgithub.com/go-logr/logr v1.2.4 // indirect\n\tgithub.com/go-logr/stdr v1.2.2 // indirect\n\tgithub.com/go-openapi/jsonpointer v0.21.0 // indirect\n\tgithub.com/go-openapi/jsonreference v0.20.1 // indirect\n\tgithub.com/go-openapi/swag v0.23.0 // indirect\n\tgithub.com/gobwas/glob v0.2.3 // indirect\n\tgithub.com/gogo/protobuf v1.3.2 // indirect\n\tgithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect\n\tgithub.com/golang/protobuf v1.5.3 // indirect\n\tgithub.com/google/btree v1.0.1 // indirect\n\tgithub.com/google/gnostic v0.5.7-v3refs // indirect\n\tgithub.com/google/go-cmp v0.6.0 // indirect\n\tgithub.com/google/gofuzz v1.2.0 // indirect\n\tgithub.com/gosuri/uilive v0.0.4 // indirect\n\tgithub.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect\n\tgithub.com/hooklift/assert v0.1.0 // indirect\n\tgithub.com/imdario/mergo v0.3.13 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/josharian/intern v1.0.0 // indirect\n\tgithub.com/kennygrant/sanitize v1.2.4 // indirect\n\tgithub.com/klauspost/compress v1.17.3 // indirect\n\tgithub.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect\n\tgithub.com/mailru/easyjson v0.7.7 // indirect\n\tgithub.com/mattn/go-isatty v0.0.14 // indirect\n\tgithub.com/mattn/go-shellwords v1.0.12 // indirect\n\tgithub.com/mitchellh/go-homedir v1.1.0 // indirect\n\tgithub.com/moby/spdystream v0.2.0 // indirect\n\tgithub.com/moby/sys/user v0.2.0 // indirect\n\tgithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect\n\tgithub.com/modern-go/reflect2 v1.0.2 // indirect\n\tgithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect\n\tgithub.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect\n\tgithub.com/morikuni/aec v1.0.0 // indirect\n\tgithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect\n\tgithub.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect\n\tgithub.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect\n\tgithub.com/opencontainers/go-digest v1.0.0 // indirect\n\tgithub.com/perimeterx/marshmallow v1.1.5 // indirect\n\tgithub.com/peterbourgon/diskv v2.0.1+incompatible // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/rivo/uniseg v0.2.0 // indirect\n\tgithub.com/russross/blackfriday/v2 v2.1.0 // indirect\n\tgithub.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect\n\tgithub.com/slimtoolkit/uilive v0.0.2 // indirect\n\tgithub.com/spf13/cobra v1.7.0 // indirect\n\tgithub.com/spf13/pflag v1.0.5 // indirect\n\tgithub.com/temoto/robotstxt v1.1.2 // indirect\n\tgithub.com/ulyssessouza/godotenv v1.3.1-0.20210806120901-e417b721114e // indirect\n\tgithub.com/vbatts/tar-split v0.11.3 // indirect\n\tgithub.com/xlab/treeprint v1.1.0 // indirect\n\tgithub.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect\n\tgo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect\n\tgo.opentelemetry.io/otel v1.19.0 // indirect\n\tgo.opentelemetry.io/otel/metric v1.19.0 // indirect\n\tgo.opentelemetry.io/otel/trace v1.19.0 // indirect\n\tgo.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect\n\tgolang.org/x/mod v0.29.0 // indirect\n\tgolang.org/x/oauth2 v0.10.0 // indirect\n\tgolang.org/x/sync v0.18.0 // indirect\n\tgolang.org/x/term v0.37.0 // indirect\n\tgolang.org/x/text v0.31.0 // indirect\n\tgolang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect\n\tgolang.org/x/tools v0.38.0 // indirect\n\tgoogle.golang.org/appengine v1.6.7 // indirect\n\tgoogle.golang.org/protobuf v1.33.0 // indirect\n\tgopkg.in/inf.v0 v0.9.1 // indirect\n\tgopkg.in/yaml.v2 v2.4.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n\tsigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect\n\tsigs.k8s.io/kustomize/api v0.13.2 // indirect\n\tsigs.k8s.io/kustomize/kyaml v0.14.1 // indirect\n\tsigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect\n\tsigs.k8s.io/yaml v1.3.0 // indirect\n)\n\nrequire (\n\tgithub.com/PuerkitoBio/goquery v1.8.1 // indirect\n\tgithub.com/andybalholm/cascadia v1.3.2 // indirect\n\tgithub.com/antchfx/htmlquery v1.3.0 // indirect\n\tgithub.com/antchfx/xmlquery v1.3.17 // indirect\n\tgithub.com/antchfx/xpath v1.2.4 // indirect\n\tgithub.com/containerd/containerd v1.7.11 // indirect\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/dsnet/compress v0.0.1 // indirect\n\tgithub.com/google/uuid v1.3.0\n\tgithub.com/json-iterator/go v1.1.12 // indirect\n\tgithub.com/klauspost/pgzip v1.2.4 // indirect\n\tgithub.com/mattn/go-colorable v0.1.12 // indirect\n\tgithub.com/mattn/go-runewidth v0.0.13 // indirect\n\tgithub.com/mattn/go-tty v0.0.3 // indirect\n\tgithub.com/mitchellh/mapstructure v1.4.3 // indirect\n\tgithub.com/moby/patternmatcher v0.6.0 // indirect\n\tgithub.com/moby/sys/sequential v0.5.0 // indirect\n\tgithub.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 // indirect\n\tgithub.com/stretchr/testify v1.9.0\n\tgithub.com/ulikunitz/xz v0.5.7 // indirect\n\tk8s.io/klog/v2 v2.90.1 // indirect\n\tk8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect\n\tk8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect\n)\n\nreplace github.com/compose-spec/compose-go => ./pkg/third_party/compose-go\n"
  },
  {
    "path": "go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=\ngithub.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=\ngithub.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=\ngithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=\ngithub.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=\ngithub.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=\ngithub.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=\ngithub.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=\ngithub.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=\ngithub.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=\ngithub.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=\ngithub.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM=\ngithub.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=\ngithub.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=\ngithub.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY=\ngithub.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=\ngithub.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=\ngithub.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=\ngithub.com/antchfx/htmlquery v1.2.3/go.mod h1:B0ABL+F5irhhMWg54ymEZinzMSi0Kt3I2if0BLYa3V0=\ngithub.com/antchfx/htmlquery v1.3.0 h1:5I5yNFOVI+egyia5F2s/5Do2nFWxJz41Tr3DyfKD25E=\ngithub.com/antchfx/htmlquery v1.3.0/go.mod h1:zKPDVTMhfOmcwxheXUsx4rKJy8KEY/PU6eXr/2SebQ8=\ngithub.com/antchfx/xmlquery v1.2.4/go.mod h1:KQQuESaxSlqugE2ZBcM/qn+ebIpt+d+4Xx7YcSGAIrM=\ngithub.com/antchfx/xmlquery v1.3.17 h1:d0qWjPp/D+vtRw7ivCwT5ApH/3CkQU8JOeo3245PpTk=\ngithub.com/antchfx/xmlquery v1.3.17/go.mod h1:Afkq4JIeXut75taLSuI31ISJ/zeq+3jG7TunF7noreA=\ngithub.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=\ngithub.com/antchfx/xpath v1.1.8/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=\ngithub.com/antchfx/xpath v1.2.3/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=\ngithub.com/antchfx/xpath v1.2.4 h1:dW1HB/JxKvGtJ9WyVGJ0sIoEcqftV3SqIstujI+B9XY=\ngithub.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=\ngithub.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=\ngithub.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=\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/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=\ngithub.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=\ngithub.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=\ngithub.com/bmatcuk/doublestar/v3 v3.0.0 h1:TQtVPlDnAYwcrVNB2JiGuMc++H5qzWZd9PhkNo5WyHI=\ngithub.com/bmatcuk/doublestar/v3 v3.0.0/go.mod h1:6PcTVMw80pCY1RVuoqu3V++99uQB3vsSYKPTd8AWA0k=\ngithub.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=\ngithub.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8 h1:GKTyiRCL6zVf5wWaqKnf+7Qs6GbEPfd4iMOitWzXJx8=\ngithub.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8/go.mod h1:spo1JLcs67NmW1aVLEgtA8Yy1elc+X8y5SRW1sFW4Og=\ngithub.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=\ngithub.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=\ngithub.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=\ngithub.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=\ngithub.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s=\ngithub.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=\ngithub.com/c4milo/unpackit v0.0.0-20170704181138-4ed373e9ef1c h1:aprLqMn7gSPT+vdDSl+/E6NLEuArwD/J7IWd8bJt5lQ=\ngithub.com/c4milo/unpackit v0.0.0-20170704181138-4ed373e9ef1c/go.mod h1:Ie6SubJv/NTO9Q0UBH0QCl3Ve50lu9hjbi5YJUw03TE=\ngithub.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=\ngithub.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=\ngithub.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw=\ngithub.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE=\ngithub.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=\ngithub.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=\ngithub.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=\ngithub.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=\ngithub.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=\ngithub.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=\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/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=\ngithub.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e h1:n81KvOMrLZa+VWHwST7dun9f0G98X3zREHS1ztYzZKU=\ngithub.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mod h1:xpWTC2KnJMiDLkoawhsPQcXjvwATEBcbq0xevG2YR9M=\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/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=\ngithub.com/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM=\ngithub.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=\ngithub.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=\ngithub.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=\ngithub.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg=\ngithub.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=\ngithub.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=\ngithub.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=\ngithub.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=\ngithub.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=\ngithub.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=\ngithub.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=\ngithub.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\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/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=\ngithub.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=\ngithub.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=\ngithub.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=\ngithub.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=\ngithub.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=\ngithub.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=\ngithub.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=\ngithub.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=\ngithub.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=\ngithub.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=\ngithub.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=\ngithub.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=\ngithub.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/fsouza/go-dockerclient v1.10.0 h1:ppSBsbR60I1DFbV4Ag7LlHlHakHFRNLk9XakATW1yVQ=\ngithub.com/fsouza/go-dockerclient v1.10.0/go.mod h1:+iNzAW78AzClIBTZ6WFjkaMvOgz68GyCJ236b1opLTs=\ngithub.com/getkin/kin-openapi v0.131.0 h1:NO2UeHnFKRYhZ8wg6Nyh5Cq7dHk4suQQr72a4pMrDxE=\ngithub.com/getkin/kin-openapi v0.131.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58=\ngithub.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=\ngithub.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=\ngithub.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=\ngithub.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\ngithub.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=\ngithub.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=\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-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=\ngithub.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=\ngithub.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=\ngithub.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=\ngithub.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=\ngithub.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=\ngithub.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=\ngithub.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=\ngithub.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=\ngithub.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=\ngithub.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=\ngithub.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=\ngithub.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=\ngithub.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=\ngithub.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=\ngithub.com/gocolly/colly/v2 v2.1.0 h1:k0DuZkDoCsx51bKpRJNEmcxcp+W5N8ziuwGaSDuFoGs=\ngithub.com/gocolly/colly/v2 v2.1.0/go.mod h1:I2MuhsLjQ+Ex+IzK3afNS8/1qP3AedHOusRPcRdC5o0=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=\ngithub.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=\ngithub.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=\ngithub.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=\ngithub.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=\ngithub.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=\ngithub.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=\ngithub.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\ngithub.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-containerregistry v0.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic=\ngithub.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=\ngithub.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=\ngithub.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=\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.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=\ngithub.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=\ngithub.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=\ngithub.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=\ngithub.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=\ngithub.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=\ngithub.com/gosuri/uilive v0.0.4 h1:hUEBpQDj8D8jXgtCdBu7sWsy5sbW/5GhuO8KBwJ2jyY=\ngithub.com/gosuri/uilive v0.0.4/go.mod h1:V/epo5LjjlDE5RJUcqx8dbw+zc93y5Ya3yg8tfZ74VI=\ngithub.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=\ngithub.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=\ngithub.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=\ngithub.com/hooklift/assert v0.1.0 h1:UZzFxx5dSb9aBtvMHTtnPuvFnBvcEhHTPb9+0+jpEjs=\ngithub.com/hooklift/assert v0.1.0/go.mod h1:pfexfvIHnKCdjh6CkkIZv5ic6dQ6aU2jhKghBlXuwwY=\ngithub.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=\ngithub.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=\ngithub.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/jawher/mow.cli v1.1.0/go.mod h1:aNaQlc7ozF3vw6IJ2dHjp2ZFiA4ozMIYY6PyuRJwlUg=\ngithub.com/jedib0t/go-pretty/v6 v6.4.9 h1:vZ6bjGg2eBSrJn365qlxGcaWu09Id+LHtrfDWlB2Usc=\ngithub.com/jedib0t/go-pretty/v6 v6.4.9/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs=\ngithub.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=\ngithub.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=\ngithub.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/kennygrant/sanitize v1.2.4 h1:gN25/otpP5vAsO2djbMhF/LQX6R7+O1TB4yv8NzpJ3o=\ngithub.com/kennygrant/sanitize v1.2.4/go.mod h1:LGsjYYtgxbetdg5owWB2mpgUL6e2nfw2eObZ0u0qvak=\ngithub.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=\ngithub.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA=\ngithub.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=\ngithub.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=\ngithub.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=\ngithub.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\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/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=\ngithub.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=\ngithub.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=\ngithub.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=\ngithub.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=\ngithub.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=\ngithub.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=\ngithub.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=\ngithub.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=\ngithub.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=\ngithub.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=\ngithub.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=\ngithub.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=\ngithub.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=\ngithub.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=\ngithub.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=\ngithub.com/mattn/go-runewidth v0.0.13/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/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI=\ngithub.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=\ngithub.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=\ngithub.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=\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/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=\ngithub.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=\ngithub.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=\ngithub.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=\ngithub.com/moby/sys/user v0.2.0 h1:OnpapJsRp25vkhw8TFG6OLJODNh/3rEwRWtJ3kakwRM=\ngithub.com/moby/sys/user v0.2.0/go.mod h1:RYstrcWOJpVh+6qzUqp2bU3eaRpdiQeKGlKitaH0PM8=\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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=\ngithub.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=\ngithub.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=\ngithub.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=\ngithub.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=\ngithub.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=\ngithub.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=\ngithub.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=\ngithub.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw=\ngithub.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c=\ngithub.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=\ngithub.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=\ngithub.com/onsi/ginkgo/v2 v2.9.1/go.mod h1:FEcmzVcCHl+4o9bQZVab+4dC9+j+91t2FHSzmGAPfuo=\ngithub.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=\ngithub.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=\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.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=\ngithub.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=\ngithub.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=\ngithub.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s=\ngithub.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw=\ngithub.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=\ngithub.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=\ngithub.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 h1:pd4YKIqCB0U7O2I4gWHgEUA2mCEOENmco0l/bM957bU=\ngithub.com/pkg/term v0.0.0-20200520122047-c3ffed290a03/go.mod h1:Z9+Ul5bCbBKnbCvdOWbLqTHhJiYV414CURZJba6L8qA=\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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=\ngithub.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=\ngithub.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=\ngithub.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=\ngithub.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=\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/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=\ngithub.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=\ngithub.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=\ngithub.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=\ngithub.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=\ngithub.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=\ngithub.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=\ngithub.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=\ngithub.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=\ngithub.com/slimtoolkit/go-update v0.0.0-20231119011834-99945ebd76f7 h1:uM8XWZNInZ8e7o9p9YrQLwoazAiBNhHzElPuUVMSYaQ=\ngithub.com/slimtoolkit/go-update v0.0.0-20231119011834-99945ebd76f7/go.mod h1:3uSkRs/BunnCLdBx0k3cyWDPAnYNFnDaioawCN3g9NA=\ngithub.com/slimtoolkit/uilive v0.0.2 h1:JZiBu3VMea13z6PLuuOfH/At32HUnfCqDjSWD0pfJHA=\ngithub.com/slimtoolkit/uilive v0.0.2/go.mod h1:r9dTgnFgOfeEYT+gQwP8rLGQXBZbT/K7IgjWckJiaxc=\ngithub.com/slimtoolkit/uiprogress v0.0.0-20231119012247-4a052fb12f37 h1:ai8Sj4lIpZURxtXhMYQiRaOxTR1+VvPAXDGpz2aJfXE=\ngithub.com/slimtoolkit/uiprogress v0.0.0-20231119012247-4a052fb12f37/go.mod h1:8mt8XhLNN4ZywNc2bYadbIApGVkDhgkhCdMnZYgTYJU=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=\ngithub.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=\ngithub.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=\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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\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.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\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.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=\ngithub.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=\ngithub.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=\ngithub.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=\ngithub.com/temoto/robotstxt v1.1.2 h1:W2pOjSJ6SWvldyEuiFXNxz3xZ8aiWX5LbfDiOFd7Fxg=\ngithub.com/temoto/robotstxt v1.1.2/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=\ngithub.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=\ngithub.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=\ngithub.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=\ngithub.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=\ngithub.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=\ngithub.com/ulyssessouza/godotenv v1.3.1-0.20210806120901-e417b721114e h1:byEYm3QADv5mDUesYKstWwRodf2RoxxC/YuGOxtdqJw=\ngithub.com/ulyssessouza/godotenv v1.3.1-0.20210806120901-e417b721114e/go.mod h1:9JN/BuU6Agy5aHyEoA5EIPkBsYbk0+2R42zJgYi/SlI=\ngithub.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=\ngithub.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho=\ngithub.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=\ngithub.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=\ngithub.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=\ngithub.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=\ngithub.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=\ngithub.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=\ngithub.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=\ngithub.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=\ngithub.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngithub.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=\ngithub.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=\ngithub.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q=\ngo.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=\ngo.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=\ngo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=\ngo.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=\ngo.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=\ngo.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=\ngo.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=\ngo.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=\ngo.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=\ngo.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=\ngo.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=\ngo.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=\ngo.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=\ngolang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=\ngolang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=\ngolang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=\ngolang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=\ngolang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=\ngolang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=\ngolang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/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.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=\ngolang.org/x/sys v0.38.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.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=\ngolang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=\ngolang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\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.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=\ngolang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=\ngolang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=\ngolang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=\ngolang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw=\ngoogle.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=\ngoogle.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=\ngoogle.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=\ngoogle.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=\ngoogle.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/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/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=\ngopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\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.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.0/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.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=\ngotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nk8s.io/api v0.27.3 h1:yR6oQXXnUEBWEWcvPWS0jQL575KoAboQPfJAuKNrw5Y=\nk8s.io/api v0.27.3/go.mod h1:C4BNvZnQOF7JA/0Xed2S+aUyJSfTGkGFxLXz9MnpIpg=\nk8s.io/apimachinery v0.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM=\nk8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=\nk8s.io/cli-runtime v0.27.3 h1:h592I+2eJfXj/4jVYM+tu9Rv8FEc/dyCoD80UJlMW2Y=\nk8s.io/cli-runtime v0.27.3/go.mod h1:LzXud3vFFuDFXn2LIrWnscPgUiEj7gQQcYZE2UPn9Kw=\nk8s.io/client-go v0.27.3 h1:7dnEGHZEJld3lYwxvLl7WoehK6lAq7GvgjxpA3nv1E8=\nk8s.io/client-go v0.27.3/go.mod h1:2MBEKuTo6V1lbKy3z1euEGnhPfGZLKTS9tiJ2xodM48=\nk8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=\nk8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=\nk8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=\nk8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=\nk8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk=\nk8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=\nsigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=\nsigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=\nsigs.k8s.io/kustomize/api v0.13.2 h1:kejWfLeJhUsTGioDoFNJET5LQe/ajzXhJGYoU+pJsiA=\nsigs.k8s.io/kustomize/api v0.13.2/go.mod h1:DUp325VVMFVcQSq+ZxyDisA8wtldwHxLZbr1g94UHsw=\nsigs.k8s.io/kustomize/kyaml v0.14.1 h1:c8iibius7l24G2wVAGZn/Va2wNys03GXLjYVIcFVxKA=\nsigs.k8s.io/kustomize/kyaml v0.14.1/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4=\nsigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=\nsigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=\nsigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=\nsigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=\n"
  },
  {
    "path": "pkg/acounter/acounter.go",
    "content": "package acounter\n\nimport (\n\t\"sync/atomic\"\n)\n\ntype Type struct {\n\tval uint64\n}\n\nfunc (self *Type) Value() uint64 {\n\treturn atomic.LoadUint64(&self.val)\n}\n\nfunc (self *Type) Inc() uint64 {\n\treturn self.Add(1)\n}\n\nfunc (self *Type) Add(val uint64) uint64 {\n\treturn atomic.AddUint64(&self.val, val)\n}\n"
  },
  {
    "path": "pkg/aflag/aflag.go",
    "content": "package aflag\n\nimport (\n\t\"sync/atomic\"\n)\n\nconst (\n\tNone uint32 = iota\n\tOff\n\tOn\n)\n\ntype Type struct {\n\tval uint32\n}\n\nfunc (self *Type) Value() uint32 {\n\treturn atomic.LoadUint32(&self.val)\n}\n\nfunc (self *Type) On() {\n\tself.Set(On)\n}\n\nfunc (self *Type) Off() {\n\tself.Set(Off)\n}\n\nfunc (self *Type) Set(val uint32) {\n\tatomic.StoreUint32(&self.val, val)\n}\n\nfunc (self *Type) IsOn() bool {\n\treturn self.Is(On)\n}\n\nfunc (self *Type) IsOff() bool {\n\treturn self.Is(Off)\n}\n\nfunc (self *Type) IsNone() bool {\n\treturn self.Is(None)\n}\n\nfunc (self *Type) Is(val uint32) bool {\n\treturn atomic.LoadUint32(&self.val) == val\n}\n\nfunc (self *Type) Has(val uint32) bool {\n\treturn (atomic.LoadUint32(&self.val) & val) == val\n}\n"
  },
  {
    "path": "pkg/app/constants.go",
    "content": "package app\n\nconst (\n\tDefaultArtifactsDirPath = \"/opt/_slim/artifacts\"\n\tArtifactFilesDirName    = \"files\"\n)\n"
  },
  {
    "path": "pkg/app/execontext.go",
    "content": "package app\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"strings\"\n\n\t\"github.com/fatih/color\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst (\n\tofJSON = \"json\"\n\tofText = \"text\"\n)\n\ntype ExecutionContext struct {\n\tOut             *Output\n\tcleanupHandlers []func()\n}\n\nfunc (ref *ExecutionContext) Exit(exitCode int) {\n\tref.doCleanup()\n\tref.exit(exitCode)\n}\n\nfunc (ref *ExecutionContext) AddCleanupHandler(handler func()) {\n\tif handler != nil {\n\t\tref.cleanupHandlers = append(ref.cleanupHandlers, handler)\n\t}\n}\n\nfunc (ref *ExecutionContext) doCleanup() {\n\tif len(ref.cleanupHandlers) == 0 {\n\t\treturn\n\t}\n\n\t//call cleanup handlers in reverse order\n\tfor i := len(ref.cleanupHandlers) - 1; i >= 0; i-- {\n\t\tcleanup := ref.cleanupHandlers[i]\n\t\tif cleanup != nil {\n\t\t\tcleanup()\n\t\t}\n\t}\n}\n\nfunc (ref *ExecutionContext) FailOn(err error) {\n\tif err != nil {\n\t\tref.doCleanup()\n\n\t\t//not using FailOn from errutil to control the flow/output better\n\t\tstackData := debug.Stack()\n\t\tlog.WithError(err).WithFields(log.Fields{\n\t\t\t\"stack\": string(stackData),\n\t\t}).Error(\"terminating\")\n\n\t\tif ref.Out != nil {\n\t\t\tref.Out.Info(\"fail.on\", OutVars{\"version\": v.Current()})\n\t\t}\n\n\t\tref.exit(-1)\n\t}\n}\n\nfunc (ref *ExecutionContext) Fail(reason string) {\n\tref.doCleanup()\n\n\t//not using FailOn from errutil to control the flow/output better\n\tstackData := debug.Stack()\n\tlog.WithFields(log.Fields{\n\t\t\"stack\":  string(stackData),\n\t\t\"reason\": reason,\n\t}).Error(\"terminating\")\n\n\tif ref.Out != nil {\n\t\tref.Out.Info(\"fail.on\", OutVars{\"version\": v.Current()})\n\t}\n\n\tShowCommunityInfo(ref.Out.OutputFormat)\n\tref.exit(-1)\n}\n\nfunc (ref *ExecutionContext) exit(exitCode int) {\n\tif ref.Out != nil {\n\t\tref.Out.Info(\"exit\", OutVars{\n\t\t\t\"code\":     exitCode,\n\t\t\t\"version\":  v.Current(),\n\t\t\t\"location\": fsutil.ExeDir()})\n\t}\n\n\tShowCommunityInfo(ref.Out.OutputFormat)\n\tos.Exit(exitCode)\n}\n\nfunc NewExecutionContext(\n\tcmdName string,\n\tquiet bool,\n\toutputFormat string) *ExecutionContext {\n\tref := &ExecutionContext{\n\t\tOut: NewOutput(cmdName, quiet, outputFormat),\n\t}\n\n\treturn ref\n}\n\ntype Output struct {\n\tCmdName      string\n\tQuiet        bool\n\tOutputFormat string\n}\n\nfunc NewOutput(cmdName string, quiet bool, outputFormat string) *Output {\n\tref := &Output{\n\t\tCmdName:      cmdName,\n\t\tQuiet:        quiet,\n\t\tOutputFormat: outputFormat,\n\t}\n\n\treturn ref\n}\n\nfunc NoColor() {\n\tcolor.NoColor = true\n}\n\ntype OutVars map[string]interface{}\n\nfunc (ref *Output) LogDump(logType string, data string, params ...OutVars) {\n\tif ref.Quiet {\n\t\treturn\n\t}\n\n\tvar info string\n\tmsg := map[string]string{}\n\tvar jsonData []byte\n\n\tmsg[\"cmd\"] = ref.CmdName\n\tmsg[\"log\"] = logType\n\tmsg[\"data\"] = data\n\n\tif len(params) > 0 {\n\t\tkvSet := params[0]\n\t\tif len(kvSet) > 0 {\n\t\t\tvar builder strings.Builder\n\t\t\tfor k, v := range kvSet {\n\t\t\t\tmsg[k] = fmt.Sprintf(\"%v\", v)\n\t\t\t\tbuilder.WriteString(kcolor(k))\n\t\t\t\tbuilder.WriteString(\"=\")\n\t\t\t\tbuilder.WriteString(fmt.Sprintf(\"'%s'\", vcolor(\"%v\", v)))\n\t\t\t\tbuilder.WriteString(\" \")\n\t\t\t}\n\n\t\t\tinfo = builder.String()\n\t\t}\n\t}\n\tswitch ref.OutputFormat {\n\tcase ofJSON:\n\t\tjsonData, _ = json.Marshal(msg)\n\t\tfmt.Println(string(jsonData))\n\tcase ofText:\n\t\tfmt.Printf(\"cmd=%s log='%s' event=LOG.START %s ====================\\n\", ref.CmdName, logType, info)\n\t\tfmt.Println(data)\n\t\tfmt.Printf(\"cmd=%s log='%s' event=LOG.END %s ====================\\n\", ref.CmdName, logType, info)\n\tdefault:\n\t\tlog.Fatalf(\"Unknown console output flag: %s\\n. It should be either 'text' or 'json\", ref.OutputFormat)\n\t}\n\n}\n\nfunc (ref *Output) Prompt(data string) {\n\tif ref.Quiet {\n\t\treturn\n\t}\n\n\tswitch ref.OutputFormat {\n\tcase ofJSON:\n\t\t//marshal data to json\n\t\tvar jsonData []byte\n\t\tif len(data) > 0 {\n\t\t\tmsg := map[string]string{\n\t\t\t\t\"cmd\":    ref.CmdName,\n\t\t\t\t\"prompt\": data,\n\t\t\t}\n\t\t\tjsonData, _ = json.Marshal(msg)\n\t\t\tfmt.Println(string(jsonData))\n\t\t}\n\tcase ofText:\n\t\tcolor.Set(color.FgHiRed)\n\t\tdefer color.Unset()\n\n\t\tfmt.Printf(\"cmd=%s prompt='%s'\\n\", ref.CmdName, data)\n\tdefault:\n\t\tlog.Fatalf(\"Unknown console output flag: %s\\n. It should be either 'text' or 'json\", ref.OutputFormat)\n\t}\n\n}\n\nfunc (ref *Output) Error(errType string, data string) {\n\tif ref.Quiet {\n\t\treturn\n\t}\n\n\tswitch ref.OutputFormat {\n\tcase ofJSON:\n\t\t//marshal data to json\n\t\tvar jsonData []byte\n\t\tif len(data) > 0 {\n\t\t\tmsg := map[string]string{\n\t\t\t\t\"cmd\":     ref.CmdName,\n\t\t\t\t\"error\":   errType,\n\t\t\t\t\"message\": data,\n\t\t\t}\n\t\t\tjsonData, _ = json.Marshal(msg)\n\t\t\tfmt.Println(string(jsonData))\n\t\t}\n\tcase ofText:\n\t\tcolor.Set(color.FgHiRed)\n\t\tdefer color.Unset()\n\n\t\tfmt.Printf(\"cmd=%s error=%s message='%s'\\n\", ref.CmdName, errType, data)\n\tdefault:\n\t\tlog.Fatalf(\"Unknown console output flag: %s\\n. It should be either 'text' or 'json\", ref.OutputFormat)\n\t}\n\n}\n\nfunc (ref *Output) Message(data string) {\n\tif ref.Quiet {\n\t\treturn\n\t}\n\n\tswitch ref.OutputFormat {\n\tcase ofJSON:\n\t\t//marshal data to json\n\t\tvar jsonData []byte\n\t\tif len(data) > 0 {\n\t\t\tmsg := map[string]string{\n\t\t\t\t\"cmd\":     ref.CmdName,\n\t\t\t\t\"message\": data,\n\t\t\t}\n\t\t\tjsonData, _ = json.Marshal(msg)\n\t\t\tfmt.Println(string(jsonData))\n\t\t}\n\tcase ofText:\n\t\tcolor.Set(color.FgHiMagenta)\n\t\tdefer color.Unset()\n\n\t\tfmt.Printf(\"cmd=%s message='%s'\\n\", ref.CmdName, data)\n\tdefault:\n\t\tlog.Fatalf(\"Unknown console output flag: %s\\n. It should be either 'text' or 'json\", ref.OutputFormat)\n\t}\n\n}\n\nfunc (ref *Output) State(state string, params ...OutVars) {\n\tif ref.Quiet {\n\t\treturn\n\t}\n\n\tvar exitInfo string\n\tvar info string\n\tvar sep string\n\tmsg := map[string]string{}\n\tvar jsonData []byte\n\tmsg[\"cmd\"] = ref.CmdName\n\tmsg[\"state\"] = state\n\n\tif len(params) > 0 {\n\t\tvar minCount int\n\t\tkvSet := params[0]\n\t\tif exitCode, ok := kvSet[\"exit.code\"]; ok {\n\t\t\tminCount = 1\n\t\t\texitInfo = fmt.Sprintf(\" code=%d\", exitCode)\n\t\t}\n\n\t\tif len(kvSet) > minCount {\n\t\t\tvar builder strings.Builder\n\t\t\tsep = \" \"\n\n\t\t\tfor k, v := range kvSet {\n\t\t\t\tif k == \"exit.code\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tmsg[\"exit.info\"] = exitInfo\n\t\t\t\tmsg[k] = fmt.Sprintf(\"%v\", v)\n\t\t\t\tbuilder.WriteString(k)\n\t\t\t\tbuilder.WriteString(\"=\")\n\t\t\t\tval := fmt.Sprintf(\"%v\", v)\n\t\t\t\tif strings.Contains(val, \" \") && !strings.HasPrefix(val, `\"`) {\n\t\t\t\t\tval = fmt.Sprintf(\"\\\"%s\\\"\", val)\n\t\t\t\t}\n\n\t\t\t\tbuilder.WriteString(val)\n\t\t\t\tbuilder.WriteString(\" \")\n\t\t\t}\n\n\t\t\tinfo = builder.String()\n\t\t}\n\t}\n\n\tswitch ref.OutputFormat {\n\tcase ofJSON:\n\t\tjsonData, _ = json.Marshal(msg)\n\t\tfmt.Println(string(jsonData))\n\tcase ofText:\n\t\tif state == \"exited\" || strings.Contains(state, \"error\") {\n\t\t\tcolor.Set(color.FgHiRed, color.Bold)\n\t\t} else {\n\t\t\tcolor.Set(color.FgCyan, color.Bold)\n\t\t}\n\t\tdefer color.Unset()\n\n\t\tfmt.Printf(\"cmd=%s state=%s%s%s%s\\n\", ref.CmdName, state, exitInfo, sep, info)\n\n\tdefault:\n\t\tlog.Fatalf(\"Unknown console output flag: %s\\n. It should be either 'text' or 'json\", ref.OutputFormat)\n\t}\n}\n\nvar (\n\titcolor = color.New(color.FgMagenta, color.Bold).SprintFunc()\n\tkcolor  = color.New(color.FgHiGreen, color.Bold).SprintFunc()\n\tvcolor  = color.New(color.FgHiBlue).SprintfFunc()\n)\n\nfunc (ref *Output) Info(infoType string, params ...OutVars) {\n\tif ref.Quiet {\n\t\treturn\n\t}\n\n\tvar data string\n\tvar sep string\n\tmsg := map[string]string{}\n\tvar jsonData []byte\n\tmsg[\"cmd\"] = ref.CmdName\n\tmsg[\"info\"] = infoType\n\n\tif len(params) > 0 {\n\t\tkvSet := params[0]\n\t\tif len(kvSet) > 0 {\n\t\t\tvar builder strings.Builder\n\t\t\tsep = \" \"\n\n\t\t\tfor k, v := range kvSet {\n\t\t\t\tmsg[k] = fmt.Sprintf(\"%v\", v)\n\t\t\t\tbuilder.WriteString(kcolor(k))\n\t\t\t\tbuilder.WriteString(\"=\")\n\t\t\t\tbuilder.WriteString(fmt.Sprintf(\"'%s'\", vcolor(\"%v\", v)))\n\t\t\t\tbuilder.WriteString(\" \")\n\t\t\t}\n\n\t\t\tdata = builder.String()\n\t\t}\n\t}\n\n\tswitch ref.OutputFormat {\n\tcase ofJSON:\n\t\tjsonData, _ = json.Marshal(msg)\n\t\tfmt.Println(string(jsonData))\n\tcase ofText:\n\t\tfmt.Printf(\"cmd=%s info=%s%s%s\\n\", ref.CmdName, itcolor(infoType), sep, data)\n\n\tdefault:\n\t\tlog.Fatalf(\"Unknown console output flag: %s\\n. It should be either 'text' or 'json\", ref.OutputFormat)\n\t}\n\n}\n\nfunc ShowCommunityInfo(outputFormat string) {\n\tlines := []struct {\n\t\tApp     string `json:\"app\"`\n\t\tMessage string `json:\"message\"`\n\t\tInfo    string `json:\"info\"`\n\t}{\n\t\t{\n\t\t\tApp:     consts.AppName,\n\t\t\tMessage: \"GitHub Discussions\",\n\t\t\tInfo:    consts.CommunityDiscussions,\n\t\t},\n\t\t{\n\t\t\tApp:     consts.AppName,\n\t\t\tMessage: \"Join the CNCF Slack channel to ask questions or to share your feedback\",\n\t\t\tInfo:    consts.CommunityCNCFSlack,\n\t\t},\n\t\t{\n\t\t\tApp:     consts.AppName,\n\t\t\tMessage: \"Join the Discord server to ask questions or to share your feedback\",\n\t\t\tInfo:    consts.CommunityDiscord,\n\t\t},\n\t\t{\n\t\t\tApp:     consts.AppName,\n\t\t\tMessage: \"Join the Gitter channel to ask questions or to share your feedback\",\n\t\t\tInfo:    consts.CommunityGitter,\n\t\t},\n\t}\n\n\tswitch outputFormat {\n\tcase ofJSON:\n\t\tfor _, v := range lines {\n\t\t\tjsonData, _ := json.Marshal(v)\n\t\t\tfmt.Println(string(jsonData))\n\t\t}\n\tdefault:\n\t\tcolor.Set(color.FgHiMagenta)\n\t\tdefer color.Unset()\n\n\t\tfor _, v := range lines {\n\t\t\tfmt.Printf(\"app='%s' message='%s' info='%s'\\n\", v.App, v.Message, v.Info)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/app.go",
    "content": "package app\n\nimport (\n\t\"os\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/signals\"\n)\n\n// Run starts the master app\nfunc Run() {\n\tsignals.InitHandlers()\n\tcli := newCLI()\n\tif err := cli.Run(os.Args); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/builder/image_builder.go",
    "content": "package builder\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n//todo: move/refactor this to be a \"pkg/imagebuilder\" engine\n\nvar (\n\tErrInvalidContextDir = errors.New(\"invalid context directory\")\n)\n\n// BasicImageBuilder creates regular container images\ntype BasicImageBuilder struct {\n\tShowBuildLogs bool\n\tBuildOptions  docker.BuildImageOptions\n\tAPIClient     *docker.Client\n\tBuildLog      bytes.Buffer\n}\n\n// ImageBuilder creates new optimized container images\ntype ImageBuilder struct {\n\tBasicImageBuilder\n\tRepoName       string\n\tAdditionalTags []string\n\tID             string\n\tEntrypoint     []string\n\tCmd            []string\n\tWorkingDir     string\n\tEnv            []string\n\tLabels         map[string]string\n\tExposedPorts   map[docker.Port]struct{}\n\tVolumes        map[string]struct{}\n\tOnBuild        []string\n\tUser           string\n\tHasData        bool\n\tTarData        bool\n}\n\nconst (\n\tdsCmdPortInfo = \"65501/tcp\"\n\tdsEvtPortInfo = \"65502/tcp\"\n)\n\n// NewBasicImageBuilder creates a new BasicImageBuilder instances\nfunc NewBasicImageBuilder(client *docker.Client,\n\t//imageRepoNameTag string,\n\t//dockerfileName string,\n\tcbOpts *config.ContainerBuildOptions,\n\tbuildContext string,\n\tshowBuildLogs bool) (*BasicImageBuilder, error) {\n\tvar buildArgs []docker.BuildArg\n\tfor _, ba := range cbOpts.BuildArgs {\n\t\tbuildArgs = append(buildArgs, docker.BuildArg{Name: ba.Name, Value: ba.Value})\n\t}\n\n\tlabels := map[string]string{}\n\t//cleanup non-standard labels from buildpacks\n\tfor k, v := range cbOpts.Labels {\n\t\tlineLen := len(k) + len(v) + 7\n\t\tif lineLen > 65535 {\n\t\t\t//TODO: improve JSON data splitting\n\t\t\tvalueLen := len(v)\n\t\t\tparts := valueLen / 50000\n\t\t\tparts++\n\t\t\toffset := 0\n\t\t\tfor i := 0; i < parts && offset < valueLen; i++ {\n\t\t\t\tchunkSize := 50000\n\t\t\t\tif (offset + chunkSize) > valueLen {\n\t\t\t\t\tchunkSize = valueLen - offset\n\t\t\t\t}\n\t\t\t\tvalue := v[offset:(offset + chunkSize)]\n\t\t\t\toffset += chunkSize\n\t\t\t\tkey := fmt.Sprintf(\"%s.%d\", k, i)\n\t\t\t\tlabels[key] = value\n\t\t\t}\n\t\t} else {\n\t\t\tlabels[k] = v\n\t\t}\n\t}\n\n\tbuilder := BasicImageBuilder{\n\t\tShowBuildLogs: showBuildLogs,\n\t\tBuildOptions: docker.BuildImageOptions{\n\t\t\tName:           cbOpts.Tag,\n\t\t\tDockerfile:     cbOpts.Dockerfile,\n\t\t\tTarget:         cbOpts.Target,\n\t\t\tNetworkMode:    cbOpts.NetworkMode,\n\t\t\tExtraHosts:     cbOpts.ExtraHosts,\n\t\t\tCacheFrom:      cbOpts.CacheFrom,\n\t\t\tLabels:         labels,\n\t\t\tBuildArgs:      buildArgs,\n\t\t\tRmTmpContainer: true,\n\t\t},\n\t\tAPIClient: client,\n\t}\n\n\tif strings.HasPrefix(buildContext, \"http://\") || strings.HasPrefix(buildContext, \"https://\") {\n\t\tbuilder.BuildOptions.Remote = buildContext\n\t} else {\n\t\tif exists := fsutil.DirExists(buildContext); exists {\n\t\t\tbuilder.BuildOptions.ContextDir = buildContext\n\t\t\tfullDockerfileName := filepath.Join(buildContext, cbOpts.Dockerfile)\n\t\t\tif !fsutil.Exists(fullDockerfileName) || !fsutil.IsRegularFile(fullDockerfileName) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid dockerfile reference - %s\", fullDockerfileName)\n\t\t\t}\n\t\t} else {\n\t\t\treturn nil, ErrInvalidContextDir\n\t\t}\n\t}\n\n\tbuilder.BuildOptions.OutputStream = &builder.BuildLog\n\treturn &builder, nil\n}\n\n// Build creates a new container image\nfunc (b *BasicImageBuilder) Build() error {\n\treturn b.APIClient.BuildImage(b.BuildOptions)\n}\n\n// Remove deletes the configured container image\nfunc (b *BasicImageBuilder) Remove() error {\n\treturn nil\n}\n\n// NewImageBuilder creates a new ImageBuilder instances\nfunc NewImageBuilder(\n\tclient *docker.Client,\n\timageRepoNameTag string,\n\tadditionalTags []string,\n\timageInfo *docker.Image,\n\tartifactLocation string,\n\tshowBuildLogs bool,\n\toverrideSelectors map[string]bool,\n\toverrides *config.ContainerOverrides,\n\tinstructions *config.ImageNewInstructions,\n\tsourceImage string) (*ImageBuilder, error) {\n\n\tlabels := map[string]string{}\n\tif imageInfo.Config.Labels != nil {\n\t\t//cleanup non-standard labels from buildpacks\n\t\tfor k, v := range imageInfo.Config.Labels {\n\t\t\tlineLen := len(k) + len(v) + 7\n\t\t\tif lineLen > 65535 {\n\t\t\t\t//TODO: improve JSON data splitting\n\t\t\t\tvalueLen := len(v)\n\t\t\t\tparts := valueLen / 50000\n\t\t\t\tparts++\n\t\t\t\toffset := 0\n\t\t\t\tfor i := 0; i < parts && offset < valueLen; i++ {\n\t\t\t\t\tchunkSize := 50000\n\t\t\t\t\tif (offset + chunkSize) > valueLen {\n\t\t\t\t\t\tchunkSize = valueLen - offset\n\t\t\t\t\t}\n\t\t\t\t\tvalue := v[offset:(offset + chunkSize)]\n\t\t\t\t\toffset += chunkSize\n\t\t\t\t\tkey := fmt.Sprintf(\"%s.%d\", k, i)\n\t\t\t\t\tlabels[key] = value\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlabels[k] = v\n\t\t\t}\n\t\t}\n\t}\n\n\tvar platform string\n\tif imageInfo != nil && imageInfo.OS != \"\" && imageInfo.Architecture != \"\" {\n\t\tplatform = fmt.Sprintf(\"%s/%s\", imageInfo.OS, imageInfo.Architecture)\n\t}\n\t// omitempty will remove platform if empty on marshalled request to engine\n\n\tbuilder := &ImageBuilder{\n\t\tBasicImageBuilder: BasicImageBuilder{\n\t\t\tShowBuildLogs: showBuildLogs,\n\t\t\tAPIClient:     client,\n\t\t\t// extract platform - from image inspector\n\t\t\tBuildOptions: docker.BuildImageOptions{\n\t\t\t\tName:           imageRepoNameTag,\n\t\t\t\tRmTmpContainer: true,\n\t\t\t\tContextDir:     artifactLocation,\n\t\t\t\tDockerfile:     \"Dockerfile\",\n\t\t\t\tPlatform:       platform,\n\t\t\t\t//SuppressOutput: true,\n\t\t\t},\n\t\t},\n\t\tRepoName:       imageRepoNameTag,\n\t\tAdditionalTags: additionalTags,\n\t\tID:             imageInfo.ID,\n\t\tEntrypoint:     imageInfo.Config.Entrypoint,\n\t\tCmd:            imageInfo.Config.Cmd,\n\t\tWorkingDir:     imageInfo.Config.WorkingDir,\n\t\tEnv:            imageInfo.Config.Env,\n\t\tLabels:         labels,\n\t\tExposedPorts:   imageInfo.Config.ExposedPorts,\n\t\tVolumes:        imageInfo.Config.Volumes,\n\t\tOnBuild:        imageInfo.Config.OnBuild,\n\t\tUser:           imageInfo.Config.User,\n\t}\n\n\tif builder.ExposedPorts == nil {\n\t\tbuilder.ExposedPorts = map[docker.Port]struct{}{}\n\t}\n\n\tif builder.Volumes == nil {\n\t\tbuilder.Volumes = map[string]struct{}{}\n\t}\n\n\tif builder.Labels == nil {\n\t\tbuilder.Labels = map[string]string{}\n\t}\n\n\tif overrides != nil && len(overrideSelectors) > 0 {\n\t\tlog.Debugf(\"NewImageBuilder: Using container runtime overrides => %+v\", overrideSelectors)\n\t\tfor k := range overrideSelectors {\n\t\t\tswitch k {\n\t\t\tcase \"entrypoint\":\n\t\t\t\tif len(overrides.Entrypoint) > 0 {\n\t\t\t\t\tbuilder.Entrypoint = overrides.Entrypoint\n\t\t\t\t}\n\t\t\tcase \"cmd\":\n\t\t\t\tif len(overrides.Cmd) > 0 {\n\t\t\t\t\tbuilder.Cmd = overrides.Cmd\n\t\t\t\t}\n\t\t\tcase \"workdir\":\n\t\t\t\tif overrides.Workdir != \"\" {\n\t\t\t\t\tbuilder.WorkingDir = overrides.Workdir\n\t\t\t\t}\n\t\t\tcase \"env\":\n\t\t\t\tif len(overrides.Env) > 0 {\n\t\t\t\t\tbuilder.Env = append(builder.Env, overrides.Env...)\n\t\t\t\t}\n\t\t\tcase \"label\":\n\t\t\t\tfor k, v := range overrides.Labels {\n\t\t\t\t\tbuilder.Labels[k] = v\n\t\t\t\t}\n\t\t\tcase \"volume\":\n\t\t\t\tfor k, v := range overrides.Volumes {\n\t\t\t\t\tbuilder.Volumes[k] = v\n\t\t\t\t}\n\t\t\tcase \"expose\":\n\t\t\t\tdsCmdPort := docker.Port(dsCmdPortInfo)\n\t\t\t\tdsEvtPort := docker.Port(dsEvtPortInfo)\n\n\t\t\t\tfor k, v := range overrides.ExposedPorts {\n\t\t\t\t\tif k == dsCmdPort || k == dsEvtPort {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tbuilder.ExposedPorts[k] = v\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t//instructions have higher value precedence over the runtime overrides\n\tif instructions != nil {\n\t\tlog.Debugf(\"NewImageBuilder: Using new image instructions => %+v\", instructions)\n\n\t\tif instructions.Workdir != \"\" {\n\t\t\tbuilder.WorkingDir = instructions.Workdir\n\t\t}\n\n\t\tif len(instructions.Env) > 0 {\n\t\t\tbuilder.Env = append(builder.Env, instructions.Env...)\n\t\t}\n\n\t\tfor k, v := range instructions.ExposedPorts {\n\t\t\tbuilder.ExposedPorts[k] = v\n\t\t}\n\n\t\tfor k, v := range instructions.Volumes {\n\t\t\tbuilder.Volumes[k] = v\n\t\t}\n\n\t\tfor k, v := range instructions.Labels {\n\t\t\tbuilder.Labels[k] = v\n\t\t}\n\n\t\tif len(instructions.Entrypoint) > 0 {\n\t\t\tbuilder.Entrypoint = instructions.Entrypoint\n\t\t}\n\n\t\tif len(instructions.Cmd) > 0 {\n\t\t\tbuilder.Cmd = instructions.Cmd\n\t\t}\n\n\t\tif len(builder.ExposedPorts) > 0 &&\n\t\t\tlen(instructions.RemoveExposedPorts) > 0 {\n\t\t\tfor k := range instructions.RemoveExposedPorts {\n\t\t\t\tif _, ok := builder.ExposedPorts[k]; ok {\n\t\t\t\t\tdelete(builder.ExposedPorts, k)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(builder.Volumes) > 0 &&\n\t\t\tlen(instructions.RemoveVolumes) > 0 {\n\t\t\tfor k := range instructions.RemoveVolumes {\n\t\t\t\tif _, ok := builder.Volumes[k]; ok {\n\t\t\t\t\tdelete(builder.Volumes, k)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(builder.Labels) > 0 &&\n\t\t\tlen(instructions.RemoveLabels) > 0 {\n\t\t\tfor k := range instructions.RemoveLabels {\n\t\t\t\tif _, ok := builder.Labels[k]; ok {\n\t\t\t\t\tdelete(builder.Labels, k)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(instructions.RemoveEnvs) > 0 &&\n\t\t\tlen(builder.Env) > 0 {\n\t\t\tvar newEnv []string\n\t\t\tfor _, envPair := range builder.Env {\n\t\t\t\tenvParts := strings.SplitN(envPair, \"=\", 2)\n\t\t\t\tif len(envParts) > 0 && envParts[0] != \"\" {\n\t\t\t\t\tif _, ok := instructions.RemoveEnvs[envParts[0]]; !ok {\n\t\t\t\t\t\tnewEnv = append(newEnv, envPair)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tbuilder.Env = newEnv\n\t\t}\n\t}\n\n\tif sourceImage != \"\" {\n\t\tbuilder.Labels[consts.DSLabelSourceImage] = sourceImage\n\t}\n\n\tif imageInfo != nil && imageInfo.ID != \"\" {\n\t\tbuilder.Labels[consts.DSLabelSourceImageID] = imageInfo.ID\n\t}\n\n\tbuilder.BuildOptions.OutputStream = &builder.BuildLog\n\n\tdataTar := filepath.Join(artifactLocation, \"files.tar\")\n\tbuilder.TarData = fsutil.IsRegularFile(dataTar)\n\tif builder.TarData {\n\t\tbuilder.HasData = true\n\t} else {\n\t\tdataDir := filepath.Join(artifactLocation, \"files\")\n\t\tbuilder.HasData = fsutil.IsDir(dataDir)\n\t}\n\n\treturn builder, nil\n}\n\n// Build creates a new container image\nfunc (b *ImageBuilder) Build() error {\n\tif err := b.GenerateDockerfile(); err != nil {\n\t\treturn err\n\t}\n\n\terr := b.APIClient.BuildImage(b.BuildOptions)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, fullTag := range b.AdditionalTags {\n\t\tfullTag := strings.TrimSpace(fullTag)\n\t\tif len(fullTag) == 0 {\n\t\t\tlog.Debug(\"ImageBuilder.Build: Skipping empty tag\")\n\t\t\tcontinue\n\t\t}\n\n\t\tvar options docker.TagImageOptions\n\t\tparts := strings.Split(fullTag, \":\")\n\t\tif len(parts) > 2 {\n\t\t\tlog.Debugf(\"ImageBuilder.Build: Skipping malformed tag - '%s'\", fullTag)\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(parts) == 2 {\n\t\t\toptions.Repo = parts[0]\n\t\t\toptions.Tag = parts[1]\n\t\t} else {\n\t\t\toptions.Repo = parts[0]\n\t\t}\n\n\t\ttargetImage := b.BuildOptions.Name\n\t\tif err := b.APIClient.TagImage(targetImage, options); err != nil {\n\t\t\t//not failing on tagging errors\n\t\t\tlog.Debugf(\"ImageBuilder.Build: Error tagging image '%s' with tag - '%s' (error - %v)\", targetImage, fullTag, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// GenerateDockerfile creates a Dockerfile file\nfunc (b *ImageBuilder) GenerateDockerfile() error {\n\treturn dockerfile.GenerateFromInfo(b.BuildOptions.ContextDir,\n\t\tb.Volumes,\n\t\tb.WorkingDir,\n\t\tb.Env,\n\t\tb.Labels,\n\t\tb.User,\n\t\tb.ExposedPorts,\n\t\tb.Entrypoint,\n\t\tb.Cmd,\n\t\tb.HasData,\n\t\tb.TarData)\n}\n"
  },
  {
    "path": "pkg/app/master/cli.go",
    "content": "package app\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/appbom\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/build\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/command/containerize\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/command/convert\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/debug\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/dockerclipm\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/command/edit\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/help\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/images\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/install\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/lint\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/merge\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/probe\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/profile\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/registry\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/run\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/command/server\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/update\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/version\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/vulnerability\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/xray\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// Main/driver app CLI constants\nconst (\n\tAppName  = \"slim\"\n\tAppUsage = \"inspect, optimize and debug your containers!\"\n)\n\nfunc registerCommands() {\n\t//registering commands explicitly instead of relying on init()\n\t//also get to control the order of the commands in the interactive prompt\n\n\tdebug.RegisterCommand()\n\tbuild.RegisterCommand()\n\txray.RegisterCommand()\n\tlint.RegisterCommand()\n\tmerge.RegisterCommand()\n\timages.RegisterCommand()\n\tregistry.RegisterCommand()\n\tvulnerability.RegisterCommand()\n\tprofile.RegisterCommand()\n\tversion.RegisterCommand()\n\tappbom.RegisterCommand()\n\thelp.RegisterCommand()\n\tupdate.RegisterCommand()\n\tinstall.RegisterCommand()\n\t//edit.RegisterCommand() - not doing anything yet\n\tprobe.RegisterCommand()\n\t//convert.RegisterCommand() - not doing anything yet\n\trun.RegisterCommand()\n\t//server.RegisterCommand() - not doing anything yet\n\t//containerize.RegisterCommand() - not doing anything yet\n\tdockerclipm.RegisterCommand()\n}\n\nfunc newCLI() *cli.App {\n\tregisterCommands()\n\n\tdoShowCommunityInfo := true\n\tcliApp := cli.NewApp()\n\tcliApp.Version = v.Current()\n\tcliApp.Name = AppName\n\tcliApp.Usage = AppUsage\n\tcliApp.CommandNotFound = func(ctx *cli.Context, command string) {\n\t\tfmt.Printf(\"unknown command - %v \\n\\n\", command)\n\t\tcli.ShowAppHelp(ctx)\n\t}\n\n\tcliApp.Flags = command.GlobalFlags()\n\n\tcliApp.Before = func(ctx *cli.Context) error {\n\t\tgparams := command.GlobalFlagValues(ctx)\n\n\t\tappParams, err := config.NewAppOptionsFromFile(fsutil.ResolveImageStateBasePath(gparams.StatePath))\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"config.NewAppOptionsFromFile error - %v\", err)\n\t\t\treturn err\n\t\t}\n\n\t\tgparams = command.UpdateGlobalFlagValues(appParams, gparams)\n\n\t\tctx.Context = command.CLIContextSave(ctx.Context, command.GlobalParams, gparams)\n\t\tctx.Context = command.CLIContextSave(ctx.Context, command.AppParams, appParams)\n\n\t\tif gparams.NoColor {\n\t\t\tapp.NoColor()\n\t\t}\n\n\t\tif gparams.Debug {\n\t\t\tlog.SetLevel(log.DebugLevel)\n\t\t} else {\n\t\t\tif gparams.Verbose {\n\t\t\t\tlog.SetLevel(log.InfoLevel)\n\t\t\t} else {\n\t\t\t\tlogLevel := log.WarnLevel\n\t\t\t\tswitch gparams.LogLevel {\n\t\t\t\tcase \"trace\":\n\t\t\t\t\tlogLevel = log.TraceLevel\n\t\t\t\tcase \"debug\":\n\t\t\t\t\tlogLevel = log.DebugLevel\n\t\t\t\tcase \"info\":\n\t\t\t\t\tlogLevel = log.InfoLevel\n\t\t\t\tcase \"warn\":\n\t\t\t\t\tlogLevel = log.WarnLevel\n\t\t\t\tcase \"error\":\n\t\t\t\t\tlogLevel = log.ErrorLevel\n\t\t\t\tcase \"fatal\":\n\t\t\t\t\tlogLevel = log.FatalLevel\n\t\t\t\tcase \"panic\":\n\t\t\t\t\tlogLevel = log.PanicLevel\n\t\t\t\tdefault:\n\t\t\t\t\tlog.Fatalf(\"unknown log-level %q\", gparams.LogLevel)\n\t\t\t\t}\n\n\t\t\t\tlog.SetLevel(logLevel)\n\t\t\t}\n\t\t}\n\n\t\tif gparams.Log != \"\" {\n\t\t\tf, err := os.Create(gparams.Log)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tlog.SetOutput(f)\n\t\t}\n\n\t\tswitch gparams.LogFormat {\n\t\tcase \"text\":\n\t\t\tlog.SetFormatter(&log.TextFormatter{DisableColors: true})\n\t\tcase \"json\":\n\t\t\tlog.SetFormatter(new(log.JSONFormatter))\n\t\tdefault:\n\t\t\tlog.Fatalf(\"unknown log-format %q\", gparams.LogFormat)\n\t\t}\n\n\t\tlog.Debugf(\"sysinfo => %#v\", system.GetSystemInfo())\n\n\t\t//NOTE: not displaying the community info here to reduce noise\n\t\t//tmp hack\n\t\t//if !strings.Contains(strings.Join(os.Args, \" \"), \" docker-cli-plugin-metadata\") {\n\t\t//   app.ShowCommunityInfo(gparams.OutputFormat)\n\t\t//}\n\t\treturn nil\n\t}\n\n\tcliApp.After = func(ctx *cli.Context) error {\n\t\t//todo: get already fetched gcvalues from ctx.Context\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\n\t\tif gcvalues.QuietCLIMode {\n\t\t\treturn nil\n\t\t}\n\n\t\t//tmp hack\n\t\tif !strings.Contains(strings.Join(os.Args, \" \"), \" docker-cli-plugin-metadata\") {\n\t\t\tif doShowCommunityInfo {\n\t\t\t\tapp.ShowCommunityInfo(ctx.String(command.FlagOutputFormat))\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tcliApp.Action = func(ctx *cli.Context) error {\n\t\t//todo: get already fetched gcvalues from ctx.Context\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\n\t\t//disable community info in interactive mode (too noisy)\n\t\tdoShowCommunityInfo = false\n\t\tia := command.NewInteractiveApp(cliApp, gcvalues)\n\t\tia.Run()\n\t\treturn nil\n\t}\n\n\tcliApp.Commands = command.GetCommands()\n\treturn cliApp\n}\n"
  },
  {
    "path": "pkg/app/master/command/appbom/cli.go",
    "content": "package appbom\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\n\t\"github.com/urfave/cli/v2\"\n)\n\nconst (\n\tName  = \"appbom\"\n\tUsage = \"Show application BOM\"\n\tAlias = \"a\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/appbom/handler.go",
    "content": "package appbom\n\nimport (\n\t//log \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/appbom\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'server' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams) {\n\t//logger := log.WithFields(log.Fields{\"app\": appName, \"command\": Name})\n\n\tinfo := appbom.Get()\n\tif info == nil {\n\t\txc.Out.Error(\"appbom.info\", \"missing\")\n\t\txc.Exit(0)\n\t}\n\n\tif info.BuilderHash != \"\" {\n\t\txc.Out.Info(\"appbom\", ovars{\"builder_hash\": info.BuilderHash})\n\t}\n\n\txc.Out.Info(\"appbom\", ovars{\"runtime\": info.Runtime})\n\txc.Out.Info(\"appbom.entrypoint\",\n\t\tovars{\n\t\t\t\"path\":    info.Entrypoint.Path,\n\t\t\t\"version\": info.Entrypoint.Version,\n\t\t})\n\n\tif info.SourceControl != nil {\n\t\txc.Out.Info(\"appbom.source_control\",\n\t\t\tovars{\n\t\t\t\t\"type\":              info.SourceControl.Type,\n\t\t\t\t\"revision\":          info.SourceControl.Revision,\n\t\t\t\t\"revision_time\":     info.SourceControl.RevisionTime,\n\t\t\t\t\"has_local_changes\": info.SourceControl.HasLocalChanges,\n\t\t\t})\n\t}\n\n\toutputParam := func(param *appbom.ParamInfo, header string) {\n\t\tif param != nil {\n\t\t\txc.Out.Info(header,\n\t\t\t\tovars{\n\t\t\t\t\t\"name\":  param.Name,\n\t\t\t\t\t\"type\":  param.Type,\n\t\t\t\t\t\"value\": param.Value,\n\t\t\t\t})\n\t\t}\n\t}\n\n\toutputParam(info.BuildParams.Os, \"appbom.build_params.os\")\n\toutputParam(info.BuildParams.Arch, \"appbom.build_params.arch\")\n\toutputParam(info.BuildParams.ArchFeature, \"appbom.build_params.arch_feature\")\n\toutputParam(info.BuildParams.BuildMode, \"appbom.build_params.build_mode\")\n\toutputParam(info.BuildParams.Compiler, \"appbom.build_params.compiler\")\n\toutputParam(info.BuildParams.CgoEnabled, \"appbom.build_params.cgo_enabled\")\n\toutputParam(info.BuildParams.CgoCFlags, \"appbom.build_params.cgo_cflags\")\n\toutputParam(info.BuildParams.CgoCppFlags, \"appbom.build_params.cgo_cppflags\")\n\toutputParam(info.BuildParams.CgoCxxFlags, \"appbom.build_params.cgo_cxxflags\")\n\toutputParam(info.BuildParams.CgoLdFlags, \"appbom.build_params.cgo_ldflags\")\n\n\tif len(info.OtherParams) > 0 {\n\t\tfor k, v := range info.OtherParams {\n\t\t\txc.Out.Info(\"appbom.other_params\", ovars{\"key\": k, \"value\": v})\n\t\t}\n\t}\n\n\tif len(info.Includes) > 0 {\n\t\tfor _, v := range info.Includes {\n\t\t\tvals := ovars{\n\t\t\t\t\"name\":    v.Name,\n\t\t\t\t\"version\": v.Version,\n\t\t\t\t\"path\":    v.Path,\n\t\t\t\t\"hash\":    v.Hash,\n\t\t\t}\n\t\t\tif v.ReplacedBy != \"\" {\n\t\t\t\tvals[\"replaced_by\"] = v.ReplacedBy\n\t\t\t}\n\n\t\t\txc.Out.Info(\"appbom.includes\", vals)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/appbom/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/appbom\"\n)\n\nfunc init() {\n\tappbom.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/appbom/prompt.go",
    "content": "package appbom\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/appbom/register.go",
    "content": "package appbom\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/cli.go",
    "content": "package build\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/artifact\"\n)\n\nconst (\n\tName  = \"build\"\n\tUsage = \"Analyzes, profiles and optimizes your container image auto-generating Seccomp and AppArmor security profiles\"\n\tAlias = \"b\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: append([]cli.Flag{\n\t\tcommand.Cflag(command.FlagCommandParamsFile),\n\t\tcommand.Cflag(command.FlagTarget),\n\t\tcommand.Cflag(command.FlagPull),\n\t\tcommand.Cflag(command.FlagDockerConfigPath),\n\t\tcommand.Cflag(command.FlagRegistryAccount),\n\t\tcommand.Cflag(command.FlagRegistrySecret),\n\t\tcommand.Cflag(command.FlagShowPullLogs),\n\n\t\tcommand.Cflag(command.FlagComposeFile),\n\t\tcommand.Cflag(command.FlagTargetComposeSvc),\n\t\tcommand.Cflag(command.FlagTargetComposeSvcImage),\n\t\tcommand.Cflag(command.FlagComposeSvcStartWait),\n\t\tcommand.Cflag(command.FlagComposeSvcNoPorts),\n\t\tcommand.Cflag(command.FlagDepExcludeComposeSvcAll),\n\t\tcommand.Cflag(command.FlagDepIncludeComposeSvc),\n\t\tcommand.Cflag(command.FlagDepExcludeComposeSvc),\n\t\tcommand.Cflag(command.FlagDepIncludeComposeSvcDeps),\n\t\tcommand.Cflag(command.FlagDepIncludeTargetComposeSvcDeps),\n\t\tcommand.Cflag(command.FlagComposeNet),\n\t\tcommand.Cflag(command.FlagComposeEnvNoHost),\n\t\tcommand.Cflag(command.FlagComposeEnvFile),\n\t\tcommand.Cflag(command.FlagComposeProjectName),\n\t\tcommand.Cflag(command.FlagComposeWorkdir),\n\t\tcommand.Cflag(command.FlagContainerProbeComposeSvc),\n\t\tcommand.Cflag(command.FlagHostExec),\n\t\tcommand.Cflag(command.FlagHostExecFile),\n\n\t\tcommand.Cflag(command.FlagTargetKubeWorkload),\n\t\tcommand.Cflag(command.FlagTargetKubeWorkloadNamespace),\n\t\tcommand.Cflag(command.FlagTargetKubeWorkloadContainer),\n\t\tcommand.Cflag(command.FlagTargetKubeWorkloadImage),\n\t\tcommand.Cflag(command.FlagKubeManifestFile),\n\t\tcommand.Cflag(command.FlagKubeKubeconfigFile),\n\n\t\tcommand.Cflag(command.FlagPublishPort),\n\t\tcommand.Cflag(command.FlagPublishExposedPorts),\n\t\tcommand.Cflag(command.FlagRunTargetAsUser),\n\t\tcommand.Cflag(command.FlagShowContainerLogs),\n\t\tcommand.Cflag(command.FlagEnableMondelLogs),\n\t\tcflag(FlagShowBuildLogs),\n\t\tcommand.Cflag(command.FlagCopyMetaArtifacts),\n\t\tcommand.Cflag(command.FlagRemoveFileArtifacts),\n\t\tcommand.Cflag(command.FlagExec),\n\t\tcommand.Cflag(command.FlagExecFile),\n\t\t//\n\t\tcflag(FlagTag),\n\t\tcflag(FlagImageOverrides),\n\t\t//Container Run Options\n\t\tcommand.Cflag(command.FlagCRORuntime),\n\t\tcommand.Cflag(command.FlagCROHostConfigFile),\n\t\tcommand.Cflag(command.FlagCROSysctl),\n\t\tcommand.Cflag(command.FlagCROShmSize),\n\t\tcommand.Cflag(command.FlagUser),\n\t\tcommand.Cflag(command.FlagEntrypoint),\n\t\tcommand.Cflag(command.FlagCmd),\n\t\tcommand.Cflag(command.FlagWorkdir),\n\t\tcommand.Cflag(command.FlagEnv),\n\t\tcommand.Cflag(command.FlagEnvFile),\n\t\tcommand.Cflag(command.FlagLabel),\n\t\tcommand.Cflag(command.FlagVolume),\n\t\tcommand.Cflag(command.FlagLink),\n\t\tcommand.Cflag(command.FlagEtcHostsMap),\n\t\tcommand.Cflag(command.FlagContainerDNS),\n\t\tcommand.Cflag(command.FlagContainerDNSSearch),\n\t\tcommand.Cflag(command.FlagNetwork),\n\t\tcommand.Cflag(command.FlagHostname),\n\t\tcommand.Cflag(command.FlagExpose),\n\t\tcommand.Cflag(command.FlagMount),\n\t\t//Container Build Options\n\t\tcflag(FlagImageBuildEngine),\n\t\tcflag(FlagImageBuildArch),\n\t\tcflag(FlagBuildFromDockerfile),\n\t\tcflag(FlagDockerfileContext),\n\t\tcflag(FlagTagFat),\n\t\tcflag(FlagCBOAddHost),\n\t\tcflag(FlagCBOBuildArg),\n\t\tcflag(FlagCBOCacheFrom),\n\t\tcflag(FlagCBOLabel),\n\t\tcflag(FlagCBOTarget),\n\t\tcflag(FlagCBONetwork),\n\t\tcflag(FlagDeleteFatImage),\n\t\t//New/Optimized Build Options\n\t\tcflag(FlagNewEntrypoint),\n\t\tcflag(FlagNewCmd),\n\t\tcflag(FlagNewExpose),\n\t\tcflag(FlagNewWorkdir),\n\t\tcflag(FlagNewEnv),\n\t\tcflag(FlagNewVolume),\n\t\tcflag(FlagNewLabel),\n\t\tcflag(FlagRemoveExpose),\n\t\tcflag(FlagRemoveEnv),\n\t\tcflag(FlagRemoveLabel),\n\t\tcflag(FlagRemoveVolume),\n\t\tcflag(FlagPreservePath),\n\t\tcflag(FlagPreservePathFile),\n\t\tcflag(FlagIncludePath),\n\t\tcflag(FlagIncludePathFile),\n\t\tcflag(FlagIncludeDirBins),\n\t\tcflag(FlagIncludeBin),\n\t\tcflag(FlagIncludeBinFile),\n\t\tcflag(FlagIncludeExeFile),\n\t\tcflag(FlagIncludeExe),\n\t\tcflag(FlagIncludeShell),\n\t\tcflag(FlagIncludeWorkdir),\n\t\tcflag(FlagIncludeAppImageAll),\n\t\tcflag(FlagAppImageStartInstGroup),\n\t\tcflag(FlagAppImageStartInst),\n\t\tcflag(FlagAppImageDockerfile),\n\t\tcflag(FlagIncludePathsCreportFile),\n\t\tcflag(FlagIncludeOSLibsNet),\n\t\tcflag(FlagIncludeSSHClient),\n\t\tcflag(FlagIncludeZoneInfo),\n\t\tcflag(FlagIncludeCertAll),\n\t\tcflag(FlagIncludeCertBundles),\n\t\tcflag(FlagIncludeCertDirs),\n\t\tcflag(FlagIncludeCertPKAll),\n\t\tcflag(FlagIncludeCertPKDirs),\n\t\tcflag(FlagIncludeNew),\n\t\tcflag(FlagKeepTmpArtifacts),\n\t\tcflag(FlagIncludeAppNuxtDir),\n\t\tcflag(FlagIncludeAppNuxtBuildDir),\n\t\tcflag(FlagIncludeAppNuxtDistDir),\n\t\tcflag(FlagIncludeAppNuxtStaticDir),\n\t\tcflag(FlagIncludeAppNuxtNodeModulesDir),\n\t\tcflag(FlagIncludeAppNextDir),\n\t\tcflag(FlagIncludeAppNextBuildDir),\n\t\tcflag(FlagIncludeAppNextDistDir),\n\t\tcflag(FlagIncludeAppNextStaticDir),\n\t\tcflag(FlagIncludeAppNextNodeModulesDir),\n\t\tcflag(FlagIncludeNodePackage),\n\t\tcflag(FlagKeepPerms),\n\t\tcflag(FlagPathPerms),\n\t\tcflag(FlagPathPermsFile),\n\t\t//\"EXCLUDE\" FLAGS - START\n\t\tcflag(FlagExcludePattern),\n\t\tcflag(FlagExcludeVarLockFiles),\n\t\tcflag(FlagExcludeMounts),\n\t\t//\"EXCLUDE\" FLAGS - END\n\t\tcflag(FlagObfuscateMetadata),\n\t\tcommand.Cflag(command.FlagContinueAfter),\n\t\tcommand.Cflag(command.FlagUseLocalMounts),\n\t\tcommand.Cflag(command.FlagUseSensorVolume),\n\t\tcommand.Cflag(command.FlagRTAOnbuildBaseImage),\n\t\tcommand.Cflag(command.FlagRTASourcePT),\n\t\t//Sensor flags:\n\t\tcommand.Cflag(command.FlagSensorIPCEndpoint),\n\t\tcommand.Cflag(command.FlagSensorIPCMode),\n\t}, command.HTTPProbeFlags()...),\n\tAction: func(ctx *cli.Context) error {\n\t\tgparams, ok := command.CLIContextGet(ctx.Context, command.GlobalParams).(*command.GenericParams)\n\t\tif !ok || gparams == nil {\n\t\t\treturn command.ErrNoGlobalParams\n\t\t}\n\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgparams.QuietCLIMode,\n\t\t\tgparams.OutputFormat)\n\n\t\t//NOTE: this is a placeholder to load all command params from a file\n\t\t_ = ctx.String(command.FlagCommandParamsFile)\n\n\t\tcbOpts, err := GetContainerBuildOptions(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.container.build.options\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdeleteFatImage := ctx.Bool(command.FlagDeleteFatImage)\n\t\tif cbOpts.Dockerfile == \"\" {\n\t\t\tdeleteFatImage = false\n\t\t}\n\n\t\tcomposeFiles := ctx.StringSlice(command.FlagComposeFile)\n\n\t\t//todo: load/parse compose file and then use it to validate the related compose params\n\t\ttargetComposeSvc := ctx.String(command.FlagTargetComposeSvc)\n\t\ttargetComposeSvcImage := ctx.String(command.FlagTargetComposeSvcImage)\n\t\tcomposeSvcNoPorts := ctx.Bool(command.FlagComposeSvcNoPorts)\n\t\tdepExcludeComposeSvcAll := ctx.Bool(command.FlagDepExcludeComposeSvcAll)\n\t\tdepIncludeComposeSvcDeps := ctx.String(command.FlagDepIncludeComposeSvcDeps)\n\t\tdepIncludeTargetComposeSvcDeps := ctx.Bool(command.FlagDepIncludeTargetComposeSvcDeps)\n\t\tdepIncludeComposeSvcs := ctx.StringSlice(command.FlagDepIncludeComposeSvc)\n\t\tdepExcludeComposeSvcs := ctx.StringSlice(command.FlagDepExcludeComposeSvc)\n\t\tcomposeNets := ctx.StringSlice(command.FlagComposeNet)\n\n\t\tcomposeSvcStartWait := ctx.Int(command.FlagComposeSvcStartWait)\n\n\t\tcomposeEnvNoHost := ctx.Bool(command.FlagComposeEnvNoHost)\n\t\tcomposeEnvVars, err := command.ParseLinesWithCommentsFile(ctx.String(command.FlagComposeEnvFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.compose.env.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tcomposeProjectName := ctx.String(command.FlagComposeProjectName)\n\t\tcomposeWorkdir := ctx.String(command.FlagComposeWorkdir)\n\t\tcontainerProbeComposeSvc := ctx.String(command.FlagContainerProbeComposeSvc)\n\n\t\tkubeOpts, err := GetKubernetesOptions(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.kubernetes.options\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tvar targetRef string\n\n\t\tif kubeOpts.HasTargetSet() {\n\t\t\ttargetRef = kubeOpts.Target.Workload\n\t\t} else if len(composeFiles) > 0 && targetComposeSvc != \"\" {\n\t\t\ttargetRef = targetComposeSvc\n\t\t} else if cbOpts.Dockerfile == \"\" {\n\t\t\ttargetRef = ctx.String(command.FlagTarget)\n\n\t\t\tif targetRef == \"\" {\n\t\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\t\txc.Out.Error(\"param.target\", \"missing image ID/name\")\n\t\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\t\treturn nil\n\t\t\t\t} else {\n\t\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\ttargetRef = cbOpts.DockerfileContext\n\t\t\tif targetRef == \"\" {\n\t\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\t\txc.Out.Error(\"param.target\", \"missing Dockerfile build context directory\")\n\t\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\t\treturn nil\n\t\t\t\t} else {\n\t\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif targetRef == \"\" {\n\t\t\txc.Out.Error(\"param.target\", \"missing target - make sure to set one of the target params\")\n\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\treturn nil\n\t\t}\n\n\t\tappOpts, ok := command.CLIContextGet(ctx.Context, command.AppParams).(*config.AppOptions)\n\t\tif !kubeOpts.HasTargetSet() && (!ok || appOpts == nil) {\n\t\t\tlog.Debug(\"param.error.app.options - no app params\")\n\t\t}\n\n\t\tcrOpts, err := command.GetContainerRunOptions(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.container.run.options\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdoPull := ctx.Bool(command.FlagPull)\n\t\tdockerConfigPath := ctx.String(command.FlagDockerConfigPath)\n\t\tregistryAccount := ctx.String(command.FlagRegistryAccount)\n\t\tregistrySecret := ctx.String(command.FlagRegistrySecret)\n\t\tdoShowPullLogs := ctx.Bool(command.FlagShowPullLogs)\n\n\t\tdoRmFileArtifacts := ctx.Bool(command.FlagRemoveFileArtifacts)\n\t\tdoCopyMetaArtifacts := ctx.String(command.FlagCopyMetaArtifacts)\n\n\t\tportBindings, err := command.ParsePortBindings(ctx.StringSlice(command.FlagPublishPort))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.publish.port\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdoPublishExposedPorts := ctx.Bool(command.FlagPublishExposedPorts)\n\n\t\thttpProbeOpts := command.GetHTTPProbeOptions(xc, ctx, false)\n\n\t\tcontinueAfter, err := command.GetContinueAfter(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.continue.after\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tif continueAfter.Mode == config.CAMProbe && !httpProbeOpts.Do {\n\t\t\tcontinueAfter.Mode = \"\"\n\t\t\txc.Out.Info(\"exec\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"changing continue-after from probe to nothing because http-probe is disabled\",\n\t\t\t\t})\n\t\t}\n\n\t\texecCmd := ctx.String(command.FlagExec)\n\t\texecFile := ctx.String(command.FlagExecFile)\n\t\tif strings.Contains(continueAfter.Mode, config.CAMExec) &&\n\t\t\tlen(execCmd) == 0 &&\n\t\t\tlen(execFile) == 0 {\n\t\t\tcontinueAfter.Mode = config.CAMEnter\n\t\t\txc.Out.Info(\"exec\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"changing continue-after from exec to enter because there are no exec flags\",\n\t\t\t\t})\n\t\t}\n\n\t\tif len(execCmd) != 0 && len(execFile) != 0 {\n\t\t\txc.Out.Error(\"param.error.exec\", \"fatal: cannot use both --exec and --exec-file\")\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\t\tvar execFileCmd []byte\n\t\tif len(execFile) > 0 {\n\t\t\texecFileCmd, err = os.ReadFile(execFile)\n\t\t\txc.FailOn(err)\n\n\t\t\tif !strings.Contains(continueAfter.Mode, config.CAMExec) {\n\t\t\t\tif continueAfter.Mode == \"\" {\n\t\t\t\t\tcontinueAfter.Mode = config.CAMExec\n\t\t\t\t} else {\n\t\t\t\t\tcontinueAfter.Mode = fmt.Sprintf(\"%s&%s\", continueAfter.Mode, config.CAMExec)\n\t\t\t\t}\n\n\t\t\t\txc.Out.Info(\"exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": fmt.Sprintf(\"updating continue-after mode to %s\", continueAfter.Mode),\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t} else if len(execCmd) > 0 {\n\t\t\tif !strings.Contains(continueAfter.Mode, config.CAMExec) {\n\t\t\t\tif continueAfter.Mode == \"\" {\n\t\t\t\t\tcontinueAfter.Mode = config.CAMExec\n\t\t\t\t} else {\n\t\t\t\t\tcontinueAfter.Mode = fmt.Sprintf(\"%s&%s\", continueAfter.Mode, config.CAMExec)\n\t\t\t\t}\n\n\t\t\t\txc.Out.Info(\"exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": fmt.Sprintf(\"updating continue-after mode to %s\", continueAfter.Mode),\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif containerProbeComposeSvc != \"\" {\n\t\t\tif !strings.Contains(continueAfter.Mode, config.CAMContainerProbe) {\n\t\t\t\tif continueAfter.Mode == \"\" {\n\t\t\t\t\tcontinueAfter.Mode = config.CAMContainerProbe\n\t\t\t\t} else {\n\t\t\t\t\tcontinueAfter.Mode = fmt.Sprintf(\"%s&%s\", continueAfter.Mode, config.CAMContainerProbe)\n\t\t\t\t}\n\n\t\t\t\txc.Out.Info(\"continue.after\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": fmt.Sprintf(\"updating mode to %s\", continueAfter.Mode),\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif continueAfter.Mode == \"\" {\n\t\t\tcontinueAfter.Mode = config.CAMEnter\n\t\t\txc.Out.Info(\"exec\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"changing continue-after to enter\",\n\t\t\t\t})\n\t\t}\n\n\t\thostExecProbes := ctx.StringSlice(command.FlagHostExec)\n\t\tmoreHostExecProbes, err := command.ParseHTTPProbeExecFile(ctx.String(command.FlagHostExecFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.host.exec.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tif len(moreHostExecProbes) > 0 {\n\t\t\thostExecProbes = append(hostExecProbes, moreHostExecProbes...)\n\t\t}\n\n\t\tif strings.Contains(continueAfter.Mode, config.CAMHostExec) &&\n\t\t\tlen(hostExecProbes) == 0 {\n\t\t\tif continueAfter.Mode == config.CAMHostExec {\n\t\t\t\tcontinueAfter.Mode = config.CAMEnter\n\t\t\t\txc.Out.Info(\"host-exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": \"changing continue-after from host-exec to enter because there are no host-exec commands\",\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tcontinueAfter.Mode = command.RemoveContinueAfterMode(continueAfter.Mode, config.CAMHostExec)\n\t\t\t\txc.Out.Info(\"host-exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": \"removing host-exec continue-after mode because there are no host-exec commands\",\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif len(hostExecProbes) > 0 {\n\t\t\tif !strings.Contains(continueAfter.Mode, config.CAMHostExec) {\n\t\t\t\tif continueAfter.Mode == \"\" {\n\t\t\t\t\tcontinueAfter.Mode = config.CAMHostExec\n\t\t\t\t} else {\n\t\t\t\t\tcontinueAfter.Mode = fmt.Sprintf(\"%s&%s\", continueAfter.Mode, config.CAMHostExec)\n\t\t\t\t}\n\n\t\t\t\txc.Out.Info(\"exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": fmt.Sprintf(\"updating continue-after mode to %s\", continueAfter.Mode),\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tdoKeepPerms := ctx.Bool(FlagKeepPerms)\n\n\t\tdoRunTargetAsUser := ctx.Bool(command.FlagRunTargetAsUser)\n\n\t\tdoShowContainerLogs := ctx.Bool(command.FlagShowContainerLogs)\n\t\tdoEnableMondel := ctx.Bool(command.FlagEnableMondelLogs)\n\t\tdoShowBuildLogs := ctx.Bool(FlagShowBuildLogs)\n\t\toutputTags := ctx.StringSlice(FlagTag)\n\n\t\tdoImageOverrides := ctx.String(FlagImageOverrides)\n\t\toverrides, err := command.GetContainerOverrides(xc, ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.image.overrides\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tinstructions, err := GetImageInstructions(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.image.instructions\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tvolumeMounts, err := command.ParseVolumeMounts(ctx.StringSlice(command.FlagMount))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.mount\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\texcludePatterns := command.ParsePaths(ctx.StringSlice(FlagExcludePattern))\n\n\t\tpreservePaths := command.ParsePaths(ctx.StringSlice(FlagPreservePath))\n\t\tmorePreservePaths, err := command.ParsePathsFile(ctx.String(FlagPreservePathFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.preserve.path.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t} else {\n\t\t\tfor k, v := range morePreservePaths {\n\t\t\t\tpreservePaths[k] = v\n\t\t\t}\n\t\t}\n\n\t\tif len(preservePaths) > 0 {\n\t\t\tfor filtered := range artifact.FilteredPaths {\n\t\t\t\tif _, found := preservePaths[filtered]; found {\n\t\t\t\t\tdelete(preservePaths, filtered)\n\t\t\t\t\txc.Out.Info(\"params\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"preserve.path\": filtered,\n\t\t\t\t\t\t\t\"message\":       \"ignoring\",\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar toDelete []string\n\t\t\tfor ip := range preservePaths {\n\t\t\t\tif artifact.IsFilteredPath(ip) {\n\t\t\t\t\ttoDelete = append(toDelete, ip)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor _, dp := range toDelete {\n\t\t\t\tdelete(preservePaths, dp)\n\t\t\t\txc.Out.Info(\"params\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"preserve.path\": dp,\n\t\t\t\t\t\t\"message\":       \"ignoring\",\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tincludePaths := command.ParsePaths(ctx.StringSlice(FlagIncludePath))\n\t\tmoreIncludePaths, err := command.ParsePathsFile(ctx.String(FlagIncludePathFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.include.path.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t} else {\n\t\t\tfor k, v := range moreIncludePaths {\n\t\t\t\tincludePaths[k] = v\n\t\t\t}\n\t\t}\n\n\t\tif len(includePaths) > 0 {\n\t\t\tfor filtered := range artifact.FilteredPaths {\n\t\t\t\tif _, found := includePaths[filtered]; found {\n\t\t\t\t\tdelete(includePaths, filtered)\n\t\t\t\t\txc.Out.Info(\"params\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"include.path\": filtered,\n\t\t\t\t\t\t\t\"message\":      \"ignoring\",\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar toDelete []string\n\t\t\tfor ip := range includePaths {\n\t\t\t\tif artifact.IsFilteredPath(ip) {\n\t\t\t\t\ttoDelete = append(toDelete, ip)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor _, dp := range toDelete {\n\t\t\t\tdelete(includePaths, dp)\n\t\t\t\txc.Out.Info(\"params\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"include.path\": dp,\n\t\t\t\t\t\t\"message\":      \"ignoring\",\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tcreportIncludePaths, err := command.ParsePathsCreportFile(ctx.String(FlagIncludePathsCreportFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.include.paths.creport.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t} else {\n\t\t\tfor k, v := range creportIncludePaths {\n\t\t\t\tincludePaths[k] = v\n\t\t\t}\n\t\t}\n\n\t\tpathPerms := command.ParsePaths(ctx.StringSlice(FlagPathPerms))\n\t\tmorePathPerms, err := command.ParsePathsFile(ctx.String(FlagPathPermsFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.path.perms.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t} else {\n\t\t\tfor k, v := range morePathPerms {\n\t\t\t\tpathPerms[k] = v\n\t\t\t}\n\t\t}\n\n\t\tincludeBins := command.ParsePaths(ctx.StringSlice(FlagIncludeBin))\n\t\tmoreIncludeBins, err := command.ParsePathsFile(ctx.String(FlagIncludeBinFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.include.bin.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t} else {\n\t\t\tfor k, v := range moreIncludeBins {\n\t\t\t\tincludeBins[k] = v\n\t\t\t}\n\t\t}\n\n\t\tif len(includeBins) > 0 {\n\t\t\t//shouldn't happen, but filtering either way\n\t\t\tfor filtered := range artifact.FilteredPaths {\n\t\t\t\tif _, found := includeBins[filtered]; found {\n\t\t\t\t\tdelete(includeBins, filtered)\n\t\t\t\t\txc.Out.Info(\"params\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"include.bin\": filtered,\n\t\t\t\t\t\t\t\"message\":     \"ignoring\",\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar toDelete []string\n\t\t\tfor ip := range includeBins {\n\t\t\t\tif artifact.IsFilteredPath(ip) {\n\t\t\t\t\ttoDelete = append(toDelete, ip)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor _, dp := range toDelete {\n\t\t\t\tdelete(includeBins, dp)\n\t\t\t\txc.Out.Info(\"params\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"include.bin\": dp,\n\t\t\t\t\t\t\"message\":     \"ignoring\",\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t//note: if path perms, ID change are provided they are applied to all matching binaries\n\t\tincludeDirBinsList := command.ParsePaths(ctx.StringSlice(FlagIncludeDirBins))\n\n\t\tincludeExes := command.ParsePaths(ctx.StringSlice(FlagIncludeExe))\n\t\tmoreIncludeExes, err := command.ParsePathsFile(ctx.String(FlagIncludeExeFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.include.exe.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t} else {\n\t\t\tfor k, v := range moreIncludeExes {\n\t\t\t\tincludeExes[k] = v\n\t\t\t}\n\t\t}\n\n\t\tdoIncludeShell := ctx.Bool(FlagIncludeShell)\n\n\t\tdoIncludeWorkdir := ctx.Bool(FlagIncludeWorkdir)\n\t\tincludeLastImageLayers := uint(0)\n\t\tdoIncludeAppImageAll := ctx.Bool(FlagIncludeAppImageAll)\n\t\tappImageStartInstGroup := ctx.Int(FlagAppImageStartInstGroup)\n\t\tappImageStartInst := ctx.String(FlagAppImageStartInst)\n\n\t\tappImageDockerfilePath := ctx.String(FlagAppImageDockerfile)\n\t\tappImageDockerfileInsts, err := command.ParseLinesWithCommentsFile(appImageDockerfilePath)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.app.image.dockerfile\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdoIncludeSSHClient := ctx.Bool(FlagIncludeSSHClient)\n\t\tdoIncludeOSLibsNet := ctx.Bool(FlagIncludeOSLibsNet)\n\n\t\tdoIncludeZoneInfo := ctx.Bool(FlagIncludeZoneInfo)\n\n\t\tdoIncludeCertAll := ctx.Bool(FlagIncludeCertAll)\n\t\tdoIncludeCertBundles := ctx.Bool(FlagIncludeCertBundles)\n\t\tdoIncludeCertDirs := ctx.Bool(FlagIncludeCertDirs)\n\t\tdoIncludeCertPKAll := ctx.Bool(FlagIncludeCertPKAll)\n\t\tdoIncludeCertPKDirs := ctx.Bool(FlagIncludeCertPKDirs)\n\n\t\tdoIncludeNew := ctx.Bool(FlagIncludeNew)\n\n\t\tdoUseLocalMounts := ctx.Bool(command.FlagUseLocalMounts)\n\t\tdoUseSensorVolume := ctx.String(command.FlagUseSensorVolume)\n\n\t\tdoKeepTmpArtifacts := ctx.Bool(FlagKeepTmpArtifacts)\n\n\t\tdoExcludeVarLockFiles := ctx.Bool(FlagExcludeVarLockFiles)\n\t\tdoExcludeMounts := ctx.Bool(FlagExcludeMounts)\n\t\tif doExcludeMounts {\n\t\t\tfor mpath := range volumeMounts {\n\t\t\t\texcludePatterns[mpath] = nil\n\t\t\t\tmpattern := fmt.Sprintf(\"%s/**\", mpath)\n\t\t\t\texcludePatterns[mpattern] = nil\n\t\t\t}\n\t\t}\n\n\t\tcommandReport := ctx.String(command.FlagCommandReport)\n\t\tif commandReport == \"off\" {\n\t\t\tcommandReport = \"\"\n\t\t}\n\n\t\trtaOnbuildBaseImage := ctx.Bool(command.FlagRTAOnbuildBaseImage)\n\t\trtaSourcePT := ctx.Bool(command.FlagRTASourcePT)\n\n\t\tdoObfuscateMetadata := ctx.Bool(FlagObfuscateMetadata)\n\n\t\timageBuildEngine, err := getImageBuildEngine(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.image-build-engine\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\timageBuildArch, err := getImageBuildArch(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.image-build-arch\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgparams,\n\t\t\ttargetRef,\n\t\t\tdoPull,\n\t\t\tdockerConfigPath,\n\t\t\tregistryAccount,\n\t\t\tregistrySecret,\n\t\t\tdoShowPullLogs,\n\t\t\tcomposeFiles,\n\t\t\ttargetComposeSvc,\n\t\t\ttargetComposeSvcImage,\n\t\t\tcomposeSvcStartWait,\n\t\t\tcomposeSvcNoPorts,\n\t\t\tdepExcludeComposeSvcAll,\n\t\t\tdepIncludeComposeSvcDeps,\n\t\t\tdepIncludeTargetComposeSvcDeps,\n\t\t\tdepIncludeComposeSvcs,\n\t\t\tdepExcludeComposeSvcs,\n\t\t\tcomposeNets,\n\t\t\tcomposeEnvVars,\n\t\t\tcomposeEnvNoHost,\n\t\t\tcomposeWorkdir,\n\t\t\tcomposeProjectName,\n\t\t\tcontainerProbeComposeSvc,\n\t\t\tcbOpts,\n\t\t\tcrOpts,\n\t\t\toutputTags,\n\t\t\thttpProbeOpts,\n\t\t\tportBindings,\n\t\t\tdoPublishExposedPorts,\n\t\t\thostExecProbes,\n\t\t\tdoRmFileArtifacts,\n\t\t\tdoCopyMetaArtifacts,\n\t\t\tdoRunTargetAsUser,\n\t\t\tdoShowContainerLogs,\n\t\t\tdoEnableMondel,\n\t\t\tdoShowBuildLogs,\n\t\t\tcommand.ParseImageOverrides(doImageOverrides),\n\t\t\toverrides,\n\t\t\tinstructions,\n\t\t\tctx.StringSlice(command.FlagLink),\n\t\t\tctx.StringSlice(command.FlagEtcHostsMap),\n\t\t\tctx.StringSlice(command.FlagContainerDNS),\n\t\t\tctx.StringSlice(command.FlagContainerDNSSearch),\n\t\t\tvolumeMounts,\n\t\t\tdoKeepPerms,\n\t\t\tpathPerms,\n\t\t\texcludePatterns,\n\t\t\tdoExcludeVarLockFiles,\n\t\t\tpreservePaths,\n\t\t\tincludePaths,\n\t\t\tincludeBins,\n\t\t\tincludeDirBinsList,\n\t\t\tincludeExes,\n\t\t\tdoIncludeShell,\n\t\t\tdoIncludeWorkdir,\n\t\t\tincludeLastImageLayers,\n\t\t\tdoIncludeAppImageAll,\n\t\t\tappImageStartInstGroup,\n\t\t\tappImageStartInst,\n\t\t\tappImageDockerfileInsts,\n\t\t\tdoIncludeSSHClient,\n\t\t\tdoIncludeOSLibsNet,\n\t\t\tdoIncludeZoneInfo,\n\t\t\tdoIncludeCertAll,\n\t\t\tdoIncludeCertBundles,\n\t\t\tdoIncludeCertDirs,\n\t\t\tdoIncludeCertPKAll,\n\t\t\tdoIncludeCertPKDirs,\n\t\t\tdoIncludeNew,\n\t\t\tdoUseLocalMounts,\n\t\t\tdoUseSensorVolume,\n\t\t\tdoKeepTmpArtifacts,\n\t\t\tcontinueAfter,\n\t\t\texecCmd,\n\t\t\tstring(execFileCmd),\n\t\t\tdeleteFatImage,\n\t\t\trtaOnbuildBaseImage,\n\t\t\trtaSourcePT,\n\t\t\tdoObfuscateMetadata,\n\t\t\tctx.String(command.FlagSensorIPCEndpoint),\n\t\t\tctx.String(command.FlagSensorIPCMode),\n\t\t\tkubeOpts,\n\t\t\tGetAppNodejsInspectOptions(ctx),\n\t\t\timageBuildEngine,\n\t\t\timageBuildArch)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/flags.go",
    "content": "package build\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Build command flag names\nconst (\n\tFlagImageBuildEngine = \"image-build-engine\"\n\tFlagImageBuildArch   = \"image-build-arch\"\n\n\tFlagDeleteFatImage = \"delete-generated-fat-image\"\n\n\tFlagShowBuildLogs = \"show-blogs\"\n\n\tFlagPathPerms        = \"path-perms\"\n\tFlagPathPermsFile    = \"path-perms-file\"\n\tFlagPreservePath     = \"preserve-path\"\n\tFlagPreservePathFile = \"preserve-path-file\"\n\tFlagIncludePath      = \"include-path\"\n\tFlagIncludePathFile  = \"include-path-file\"\n\tFlagIncludeBin       = \"include-bin\"\n\tFlagIncludeBinFile   = \"include-bin-file\"\n\tFlagIncludeExe       = \"include-exe\"\n\tFlagIncludeExeFile   = \"include-exe-file\"\n\tFlagIncludeShell     = \"include-shell\"\n\n\tFlagIncludeDirBins      = \"include-dir-bins\"\n\tFlagIncludeDirBinsUsage = \"Keep binaries in the target directory (executables or shared objects) and their dependencies, which could be in other locations\"\n\n\tFlagIncludeWorkdir      = \"include-workdir\"\n\tFlagIncludeWorkdirUsage = \"Keep files in working directory\"\n\n\t//TBD\n\tFlagWorkdirExclude      = \"workdir-exclude\"\n\tFlagWorkdirExcludeUsage = \"Exclude filter for artifacts when working directory is included\"\n\n\tFlagIncludeAppImageAddCopyAll = \"include-app-image-addcopy-all\" //TBD\n\tFlagIncludeAppImageRun        = \"include-app-image-run\"         //TBD\n\n\tFlagIncludeAppImageAll      = \"include-app-image-all\"\n\tFlagIncludeAppImageAllUsage = \"Keep everything in the app part of the container image\"\n\n\tFlagAppImageStartInst      = \"app-image-start-instruction\"\n\tFlagAppImageStartInstUsage = \"Instruction (prefix) that indicates where the app starts in the container image\"\n\n\tFlagAppImageStartLayerCount = \"app-image-start-layer-count\" //TBD\n\n\tFlagAppImageStartInstGroup      = \"app-image-start-instruction-group\"\n\tFlagAppImageStartInstGroupUsage = \"Instruction group (reverse) index that indicates where the app starts in the container image\"\n\n\tFlagAppImageStartDetect = \"app-image-start-detect\" //TBD\n\n\tFlagAppImageDockerfile      = \"app-image-dockerfile\" //TODO: make it work with FlagBuildFromDockerfile too\n\tFlagAppImageDockerfileUsage = \"Path to app image Dockerfile (used to determine where the application part of the image starts)\"\n\n\tFlagIncludePathsCreportFile      = \"include-paths-creport-file\"\n\tFlagIncludePathsCreportFileUsage = \"Keep files from the referenced creport\"\n\n\tFlagIncludeOSLibsNet      = \"include-oslibs-net\"\n\tFlagIncludeOSLibsNetUsage = \"Keep the common networking OS libraries\"\n\n\tFlagIncludeSSHClient           = \"include-ssh-client\"\n\tFlagIncludeSSHClientUsage      = \"Keep the common SSH client components and configs\"\n\tFlagIncludeSSHClientAll        = \"include-ssh-client-all\"\n\tFlagIncludeSSHClientAllUsage   = \"Keep all SSH client components and configs\"\n\tFlagIncludeSSHClientBasic      = \"include-ssh-client-basic\"\n\tFlagIncludeSSHClientBasicUsage = \"Keep the basic SSH client components and configs\"\n\n\tFlagIncludeZoneInfo = \"include-zoneinfo\"\n\n\tFlagIncludeCertAll     = \"include-cert-all\"\n\tFlagIncludeCertBundles = \"include-cert-bundles-only\"\n\tFlagIncludeCertDirs    = \"include-cert-dirs\"\n\tFlagIncludeCertPKAll   = \"include-cert-pk-all\"\n\tFlagIncludeCertPKDirs  = \"include-cert-pk-dirs\"\n\n\tFlagIncludeNew = \"include-new\"\n\n\t//FlagIncludeLicenses  = \"include-licenses\"\n\n\tFlagKeepTmpArtifacts = \"keep-tmp-artifacts\"\n\n\tFlagIncludeAppNuxtDir            = \"include-app-nuxt-dir\"\n\tFlagIncludeAppNuxtBuildDir       = \"include-app-nuxt-build-dir\"\n\tFlagIncludeAppNuxtDistDir        = \"include-app-nuxt-dist-dir\"\n\tFlagIncludeAppNuxtStaticDir      = \"include-app-nuxt-static-dir\"\n\tFlagIncludeAppNuxtNodeModulesDir = \"include-app-nuxt-nodemodules-dir\"\n\n\tFlagIncludeAppNextDir            = \"include-app-next-dir\"\n\tFlagIncludeAppNextBuildDir       = \"include-app-next-build-dir\"\n\tFlagIncludeAppNextDistDir        = \"include-app-next-dist-dir\"\n\tFlagIncludeAppNextStaticDir      = \"include-app-next-static-dir\"\n\tFlagIncludeAppNextNodeModulesDir = \"include-app-next-nodemodules-dir\"\n\n\tFlagIncludeNodePackage = \"include-node-package\"\n\n\tFlagKeepPerms = \"keep-perms\"\n\n\t//\"EXCLUDE\" FLAGS:\n\n\tFlagExcludePattern      = \"exclude-pattern\"\n\tFlagExcludePatternUsage = \"Exclude path pattern (Glob/Match in Go and **) from image\"\n\n\tFlagExcludeVarLockFiles      = \"exclude-varlock-files\"\n\tFlagExcludeVarLockFilesUsage = \"Exclude the files in the var and run lock directory\"\n\t//NOTES:\n\t// also \"exclude-varlock-new-files\" <- related to \"include-new\"\n\n\tFlagExcludeMounts      = \"exclude-mounts\"\n\tFlagExcludeMountsUsage = \"Exclude mounted volumes from image\"\n\n\t//Flags to edit (modify, add and remove) image metadata\n\n\tFlagNewEntrypoint = \"new-entrypoint\"\n\tFlagNewCmd        = \"new-cmd\"\n\tFlagNewLabel      = \"new-label\"\n\tFlagNewVolume     = \"new-volume\"\n\tFlagNewExpose     = \"new-expose\"\n\tFlagNewWorkdir    = \"new-workdir\"\n\tFlagNewEnv        = \"new-env\"\n\tFlagRemoveVolume  = \"remove-volume\"\n\tFlagRemoveExpose  = \"remove-expose\"\n\tFlagRemoveEnv     = \"remove-env\"\n\tFlagRemoveLabel   = \"remove-label\"\n\n\tFlagTag = \"tag\"\n\n\tFlagImageOverrides = \"image-overrides\"\n\n\t//Flags to build fat images from Dockerfile\n\tFlagTagFat              = \"tag-fat\"\n\tFlagBuildFromDockerfile = \"dockerfile\"\n\tFlagDockerfileContext   = \"dockerfile-context\"\n\tFlagCBOAddHost          = \"cbo-add-host\"\n\tFlagCBOBuildArg         = \"cbo-build-arg\"\n\tFlagCBOLabel            = \"cbo-label\"\n\tFlagCBOTarget           = \"cbo-target\"\n\tFlagCBONetwork          = \"cbo-network\"\n\tFlagCBOCacheFrom        = \"cbo-cache-from\"\n\n\t//Experimenal flags\n\tFlagObfuscateMetadata = \"obfuscate-metadata\"\n)\n\n// Build command flag usage info\nconst (\n\tFlagImageBuildEngineUsage = \"Select image build engine: internal | docker | none\"\n\tFlagImageBuildArchUsage   = \"Select output image build architecture\"\n\n\tFlagDeleteFatImageUsage = \"Delete generated fat image requires --dockerfile flag\"\n\n\tFlagShowBuildLogsUsage = \"Show image build logs\"\n\n\tFlagPathPermsUsage        = \"Set path permissions in optimized image\"\n\tFlagPathPermsFileUsage    = \"File with path permissions to set\"\n\tFlagPreservePathUsage     = \"Keep path from orignal image in its initial state (changes to the selected container image files when it runs will be discarded)\"\n\tFlagPreservePathFileUsage = \"File with paths to keep from original image in their original state (changes to the selected container image files when it runs will be discarded)\"\n\tFlagIncludePathUsage      = \"Keep path from original image\"\n\tFlagIncludePathFileUsage  = \"File with paths to keep from original image\"\n\tFlagIncludeBinUsage       = \"Keep binary from original image (executable or shared object using its absolute path)\"\n\tFlagIncludeExeUsage       = \"Keep executable from original image (by executable name)\"\n\tFlagIncludeShellUsage     = \"Keep basic shell functionality\"\n\n\tFlagIncludeZoneInfoUsage = \"Keep the OS/libc zoneinfo data\"\n\n\tFlagIncludeCertAllUsage     = \"Keep all discovered cert files\"\n\tFlagIncludeCertBundlesUsage = \"Keep only cert bundles\"\n\tFlagIncludeCertDirsUsage    = \"Keep known cert directories and all files in them\"\n\tFlagIncludeCertPKAllUsage   = \"Keep all discovered cert private keys\"\n\tFlagIncludeCertPKDirsUsage  = \"Keep known cert private key directories and all files in them\"\n\n\tFlagIncludeNewUsage = \"Keep new files created by target during dynamic analysis\"\n\n\tFlagKeepTmpArtifactsUsage = \"Keep temporary artifacts when command is done\"\n\n\tFlagIncludeAppNuxtDirUsage            = \"Keep the root Nuxt.js app directory\"\n\tFlagIncludeAppNuxtBuildDirUsage       = \"Keep the build Nuxt.js app directory\"\n\tFlagIncludeAppNuxtDistDirUsage        = \"Keep the dist Nuxt.js app directory\"\n\tFlagIncludeAppNuxtStaticDirUsage      = \"Keep the static asset directory for Nuxt.js apps\"\n\tFlagIncludeAppNuxtNodeModulesDirUsage = \"Keep the node modules directory for Nuxt.js apps\"\n\n\tFlagIncludeAppNextDirUsage            = \"Keep the root Next.js app directory\"\n\tFlagIncludeAppNextBuildDirUsage       = \"Keep the build directory for Next.js app\"\n\tFlagIncludeAppNextDistDirUsage        = \"Keep the static SPA directory for Next.js apps\"\n\tFlagIncludeAppNextStaticDirUsage      = \"Keep the static public asset directory for Next.js apps\"\n\tFlagIncludeAppNextNodeModulesDirUsage = \"Keep the node modules directory for Next.js apps\"\n\n\tFlagIncludeNodePackageUsage = \"Keep node.js package by name\"\n\n\tFlagKeepPermsUsage = \"Keep artifact permissions as-is\"\n\n\tFlagNewEntrypointUsage = \"New ENTRYPOINT instruction for the optimized image\"\n\tFlagNewCmdUsage        = \"New CMD instruction for the optimized image\"\n\tFlagNewVolumeUsage     = \"New VOLUME instructions for the optimized image\"\n\tFlagNewLabelUsage      = \"New LABEL instructions for the optimized image\"\n\tFlagNewExposeUsage     = \"New EXPOSE instructions for the optimized image\"\n\tFlagNewWorkdirUsage    = \"New WORKDIR instruction for the optimized image\"\n\tFlagNewEnvUsage        = \"New ENV instructions for the optimized image\"\n\tFlagRemoveExposeUsage  = \"Remove EXPOSE instructions for the optimized image\"\n\tFlagRemoveEnvUsage     = \"Remove ENV instructions for the optimized image\"\n\tFlagRemoveLabelUsage   = \"Remove LABEL instructions for the optimized image\"\n\tFlagRemoveVolumeUsage  = \"Remove VOLUME instructions for the optimized image\"\n\n\tFlagTagUsage = \"Custom tags for the generated image\"\n\n\tFlagImageOverridesUsage = \"Save runtime overrides in generated image (values is 'all' or a comma delimited list of override types: 'entrypoint', 'cmd', 'workdir', 'env', 'expose', 'volume', 'label')\"\n\n\tFlagIncludeBinFileUsage = \"File with shared binary file names to include from image\"\n\tFlagIncludeExeFileUsage = \"File with executable file names to include from image\"\n\n\tFlagTagFatUsage              = \"Custom tag for the fat image built from Dockerfile\"\n\tFlagBuildFromDockerfileUsage = \"The source Dockerfile name to build the fat image before it's optimized\"\n\tFlagDockerfileContextUsage   = \"The build context directory when building source Dockerfile\"\n\tFlagCBOAddHostUsage          = \"Add an extra host-to-IP mapping in /etc/hosts to use when building an image\"\n\tFlagCBOBuildArgUsage         = \"Add a build-time variable\"\n\tFlagCBOLabelUsage            = \"Add a label when building from Dockerfiles\"\n\tFlagCBOTargetUsage           = \"Target stage to build for multi-stage Dockerfiles\"\n\tFlagCBONetworkUsage          = \"Networking mode to use for the RUN instructions at build-time\"\n\tFlagCBOCacheFromUsage        = \"Add an image to the build cache\"\n\n\tFlagObfuscateMetadataUsage = \"Obfuscate the standard system and application metadata to make it more challenging to identify the image components\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagShowBuildLogs: &cli.BoolFlag{\n\t\tName:    FlagShowBuildLogs,\n\t\tUsage:   FlagShowBuildLogsUsage,\n\t\tEnvVars: []string{\"DSLIM_SHOW_BLOGS\"},\n\t},\n\tFlagPathPerms: &cli.StringSliceFlag{\n\t\tName:    FlagPathPerms,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagPathPermsUsage,\n\t\tEnvVars: []string{\"DSLIM_PATH_PERMS\"},\n\t},\n\tFlagPathPermsFile: &cli.StringFlag{\n\t\tName:    FlagPathPermsFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagPathPermsFileUsage,\n\t\tEnvVars: []string{\"DSLIM_PATH_PERMS_FILE\"},\n\t},\n\tFlagPreservePath: &cli.StringSliceFlag{\n\t\tName:    FlagPreservePath,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagPreservePathUsage,\n\t\tEnvVars: []string{\"DSLIM_PRESERVE_PATH\"},\n\t},\n\tFlagPreservePathFile: &cli.StringFlag{\n\t\tName:    FlagPreservePathFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagPreservePathFileUsage,\n\t\tEnvVars: []string{\"DSLIM_PRESERVE_PATH_FILE\"},\n\t},\n\tFlagIncludePath: &cli.StringSliceFlag{\n\t\tName:    FlagIncludePath,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagIncludePathUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_PATH\"},\n\t},\n\tFlagIncludePathFile: &cli.StringFlag{\n\t\tName:    FlagIncludePathFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagIncludePathFileUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_PATH_FILE\"},\n\t},\n\tFlagIncludeBin: &cli.StringSliceFlag{\n\t\tName:    FlagIncludeBin,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagIncludeBinUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_BIN\"},\n\t},\n\tFlagIncludeDirBins: &cli.StringSliceFlag{\n\t\tName:    FlagIncludeDirBins,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagIncludeDirBinsUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_DIR_BINS\"},\n\t},\n\tFlagIncludeExe: &cli.StringSliceFlag{\n\t\tName:    FlagIncludeExe,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagIncludeExeUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_EXE\"},\n\t},\n\tFlagIncludeShell: &cli.BoolFlag{\n\t\tName:    FlagIncludeShell,\n\t\tUsage:   FlagIncludeShellUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_SHELL\"},\n\t},\n\t////\n\tFlagIncludeWorkdir: &cli.BoolFlag{\n\t\tName:    FlagIncludeWorkdir,\n\t\tUsage:   FlagIncludeWorkdirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_WORKDIR\"},\n\t},\n\tFlagIncludeAppImageAll: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppImageAll,\n\t\tUsage:   FlagIncludeAppImageAllUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_IMAGE_ALL\"},\n\t},\n\tFlagAppImageStartInstGroup: &cli.IntFlag{\n\t\tName:    FlagAppImageStartInstGroup,\n\t\tValue:   -1,\n\t\tUsage:   FlagAppImageStartInstGroupUsage,\n\t\tEnvVars: []string{\"DSLIM_APP_IMAGE_START_INST_GROUP\"},\n\t},\n\tFlagAppImageStartInst: &cli.StringFlag{\n\t\tName:    FlagAppImageStartInst,\n\t\tUsage:   FlagAppImageStartInstUsage,\n\t\tEnvVars: []string{\"DSLIM_APP_IMAGE_START_INST\"},\n\t},\n\tFlagAppImageDockerfile: &cli.StringFlag{\n\t\tName:    FlagAppImageDockerfile,\n\t\tUsage:   FlagAppImageDockerfileUsage,\n\t\tEnvVars: []string{\"DSLIM_APP_IMAGE_DOCKERFILE\"},\n\t},\n\t////\n\tFlagIncludePathsCreportFile: &cli.StringFlag{\n\t\tName:    FlagIncludePathsCreportFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagIncludePathsCreportFileUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_PATHS_CREPORT_FILE\"},\n\t},\n\t////\n\tFlagIncludeOSLibsNet: &cli.BoolFlag{\n\t\tName:    FlagIncludeOSLibsNet,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagIncludeOSLibsNetUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_OSLIBS_NET\"},\n\t},\n\t////\n\tFlagIncludeSSHClient: &cli.BoolFlag{\n\t\tName:    FlagIncludeSSHClient,\n\t\tValue:   false, //disabled by default (for now)\n\t\tUsage:   FlagIncludeSSHClientUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_SSH_CLIENT\"},\n\t},\n\t////\n\tFlagIncludeZoneInfo: &cli.BoolFlag{\n\t\tName:    FlagIncludeZoneInfo,\n\t\tValue:   false,\n\t\tUsage:   FlagIncludeZoneInfoUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_ZONEINFO\"},\n\t},\n\t////\n\tFlagIncludeCertAll: &cli.BoolFlag{\n\t\tName:    FlagIncludeCertAll,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagIncludeCertAllUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_CERT_ALL\"},\n\t},\n\tFlagIncludeCertBundles: &cli.BoolFlag{\n\t\tName:    FlagIncludeCertBundles,\n\t\tUsage:   FlagIncludeCertBundlesUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_CERT_BUNDLES\"},\n\t},\n\tFlagIncludeCertDirs: &cli.BoolFlag{\n\t\tName:    FlagIncludeCertDirs,\n\t\tUsage:   FlagIncludeCertDirsUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_CERT_DIRS\"},\n\t},\n\tFlagIncludeCertPKAll: &cli.BoolFlag{\n\t\tName:    FlagIncludeCertPKAll,\n\t\tUsage:   FlagIncludeCertPKAllUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_CERT_PK_ALL\"},\n\t},\n\tFlagIncludeCertPKDirs: &cli.BoolFlag{\n\t\tName:    FlagIncludeCertPKDirs,\n\t\tUsage:   FlagIncludeCertPKDirsUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_CERT_PK_DIRS\"},\n\t},\n\tFlagIncludeNew: &cli.BoolFlag{\n\t\tName:    FlagIncludeNew,\n\t\tValue:   true, //enabled by default for now to keep the original behavior until minification works the same\n\t\tUsage:   FlagIncludeNewUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_NEW\"},\n\t},\n\t////\n\tFlagKeepTmpArtifacts: &cli.BoolFlag{\n\t\tName:    FlagKeepTmpArtifacts,\n\t\tUsage:   FlagKeepTmpArtifactsUsage,\n\t\tEnvVars: []string{\"DSLIM_KEEP_TMP_ARTIFACTS\"},\n\t},\n\tFlagIncludeAppNuxtDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNuxtDir,\n\t\tUsage:   FlagIncludeAppNuxtDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NUXT_DIR\"},\n\t},\n\tFlagIncludeAppNuxtBuildDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNuxtBuildDir,\n\t\tUsage:   FlagIncludeAppNuxtBuildDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NUXT_BUILD_DIR\"},\n\t},\n\tFlagIncludeAppNuxtDistDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNuxtDistDir,\n\t\tUsage:   FlagIncludeAppNuxtDistDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NUXT_DIST_DIR\"},\n\t},\n\tFlagIncludeAppNuxtStaticDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNuxtStaticDir,\n\t\tUsage:   FlagIncludeAppNuxtStaticDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NUXT_STATIC_DIR\"},\n\t},\n\tFlagIncludeAppNuxtNodeModulesDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNuxtNodeModulesDir,\n\t\tUsage:   FlagIncludeAppNuxtNodeModulesDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NUXT_NM_DIR\"},\n\t},\n\tFlagIncludeAppNextDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNextDir,\n\t\tUsage:   FlagIncludeAppNextDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NEXT_DIR\"},\n\t},\n\tFlagIncludeAppNextBuildDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNextBuildDir,\n\t\tUsage:   FlagIncludeAppNextBuildDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NEXT_BUILD_DIR\"},\n\t},\n\tFlagIncludeAppNextDistDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNextDistDir,\n\t\tUsage:   FlagIncludeAppNextDistDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NEXT_DIST_DIR\"},\n\t},\n\tFlagIncludeAppNextStaticDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNextStaticDir,\n\t\tUsage:   FlagIncludeAppNextStaticDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NEXT_STATIC_DIR\"},\n\t},\n\tFlagIncludeAppNextNodeModulesDir: &cli.BoolFlag{\n\t\tName:    FlagIncludeAppNextNodeModulesDir,\n\t\tUsage:   FlagIncludeAppNextNodeModulesDirUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_APP_NEXT_NM_DIR\"},\n\t},\n\tFlagIncludeNodePackage: &cli.StringSliceFlag{\n\t\tName:    FlagIncludeNodePackage,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagIncludeNodePackageUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_NODE_PKG\"},\n\t},\n\tFlagKeepPerms: &cli.BoolFlag{\n\t\tName:    FlagKeepPerms,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagKeepPermsUsage,\n\t\tEnvVars: []string{\"DSLIM_KEEP_PERMS\"},\n\t},\n\t//\"EXCLUDE\" FLAGS - START\n\tFlagExcludePattern: &cli.StringSliceFlag{\n\t\tName:    FlagExcludePattern,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagExcludePatternUsage,\n\t\tEnvVars: []string{\"DSLIM_EXCLUDE_PATTERN\"},\n\t},\n\tFlagExcludeVarLockFiles: &cli.BoolFlag{\n\t\tName:    FlagExcludeVarLockFiles, //true by default\n\t\tValue:   true,\n\t\tUsage:   FlagExcludeVarLockFilesUsage,\n\t\tEnvVars: []string{\"DSLIM_EXCLUDE_VARLOCK\"},\n\t},\n\tFlagExcludeMounts: &cli.BoolFlag{\n\t\tName:    FlagExcludeMounts, //true by default\n\t\tValue:   true,\n\t\tUsage:   FlagExcludeMountsUsage,\n\t\tEnvVars: []string{\"DSLIM_EXCLUDE_MOUNTS\"},\n\t},\n\t//\"EXCLUDE\" FLAGS - END\n\tFlagNewEntrypoint: &cli.StringFlag{\n\t\tName:    FlagNewEntrypoint,\n\t\tValue:   \"\",\n\t\tUsage:   FlagNewEntrypointUsage,\n\t\tEnvVars: []string{\"DSLIM_NEW_ENTRYPOINT\"},\n\t},\n\tFlagNewCmd: &cli.StringFlag{\n\t\tName:    FlagNewCmd,\n\t\tValue:   \"\",\n\t\tUsage:   FlagNewCmdUsage,\n\t\tEnvVars: []string{\"DSLIM_NEW_CMD\"},\n\t},\n\tFlagNewExpose: &cli.StringSliceFlag{\n\t\tName:    FlagNewExpose,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagNewExposeUsage,\n\t\tEnvVars: []string{\"DSLIM_NEW_EXPOSE\"},\n\t},\n\tFlagNewWorkdir: &cli.StringFlag{\n\t\tName:    FlagNewWorkdir,\n\t\tValue:   \"\",\n\t\tUsage:   FlagNewWorkdirUsage,\n\t\tEnvVars: []string{\"DSLIM_NEW_WORKDIR\"},\n\t},\n\tFlagNewEnv: &cli.StringSliceFlag{\n\t\tName:    FlagNewEnv,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagNewEnvUsage,\n\t\tEnvVars: []string{\"DSLIM_NEW_ENV\"},\n\t},\n\tFlagNewVolume: &cli.StringSliceFlag{\n\t\tName:    FlagNewVolume,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagNewVolumeUsage,\n\t\tEnvVars: []string{\"DSLIM_NEW_VOLUME\"},\n\t},\n\tFlagNewLabel: &cli.StringSliceFlag{\n\t\tName:    FlagNewLabel,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagNewLabelUsage,\n\t\tEnvVars: []string{\"DSLIM_NEW_LABEL\"},\n\t},\n\tFlagTag: &cli.StringSliceFlag{\n\t\tName:    FlagTag,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagTagUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_TAG\"},\n\t},\n\tFlagImageOverrides: &cli.StringFlag{\n\t\tName:    FlagImageOverrides,\n\t\tValue:   \"\",\n\t\tUsage:   FlagImageOverridesUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_OVERRIDES\"},\n\t},\n\t//Container Build Options\n\tFlagBuildFromDockerfile: &cli.StringFlag{\n\t\tName:    FlagBuildFromDockerfile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagBuildFromDockerfileUsage,\n\t\tEnvVars: []string{\"DSLIM_BUILD_DOCKERFILE\"},\n\t},\n\tFlagDockerfileContext: &cli.StringFlag{\n\t\tName:    FlagDockerfileContext,\n\t\tValue:   \"\",\n\t\tUsage:   FlagDockerfileContextUsage,\n\t\tEnvVars: []string{\"DSLIM_BUILD_DOCKERFILE_CTX\"},\n\t},\n\tFlagTagFat: &cli.StringFlag{\n\t\tName:    FlagTagFat,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTagFatUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_TAG_FAT\"},\n\t},\n\tFlagCBOAddHost: &cli.StringSliceFlag{\n\t\tName:    FlagCBOAddHost,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagCBOAddHostUsage,\n\t\tEnvVars: []string{\"DSLIM_CBO_ADD_HOST\"},\n\t},\n\tFlagCBOBuildArg: &cli.StringSliceFlag{\n\t\tName:    FlagCBOBuildArg,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagCBOBuildArgUsage,\n\t\tEnvVars: []string{\"DSLIM_CBO_BUILD_ARG\"},\n\t},\n\tFlagCBOCacheFrom: &cli.StringSliceFlag{\n\t\tName:    FlagCBOCacheFrom,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagCBOCacheFromUsage,\n\t\tEnvVars: []string{\"DSLIM_CBO_CACHE_FROM\"},\n\t},\n\tFlagCBOLabel: &cli.StringSliceFlag{\n\t\tName:    FlagCBOLabel,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagCBOLabelUsage,\n\t\tEnvVars: []string{\"DSLIM_CBO_LABEL\"},\n\t},\n\tFlagCBOTarget: &cli.StringFlag{\n\t\tName:    FlagCBOTarget,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCBOTargetUsage,\n\t\tEnvVars: []string{\"DSLIM_CBO_TARGET\"},\n\t},\n\tFlagCBONetwork: &cli.StringFlag{\n\t\tName:    FlagCBONetwork,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCBONetworkUsage,\n\t\tEnvVars: []string{\"DSLIM_CBO_NETWORK\"},\n\t},\n\tFlagImageBuildEngine: &cli.StringFlag{\n\t\tName:    FlagImageBuildEngine,\n\t\tValue:   IBEInternal,\n\t\tUsage:   FlagImageBuildEngineUsage,\n\t\tEnvVars: []string{\"DSLIM_IMAGE_BUILD_ENG\"},\n\t},\n\tFlagImageBuildArch: &cli.StringFlag{\n\t\tName:    FlagImageBuildArch,\n\t\tUsage:   FlagImageBuildArchUsage,\n\t\tEnvVars: []string{\"DSLIM_IMAGE_BUILD_ARCH\"},\n\t},\n\tFlagDeleteFatImage: &cli.BoolFlag{\n\t\tName:    FlagDeleteFatImage,\n\t\tUsage:   FlagDeleteFatImageUsage,\n\t\tEnvVars: []string{\"DSLIM_DELETE_FAT\"},\n\t},\n\tFlagRemoveExpose: &cli.StringSliceFlag{\n\t\tName:    FlagRemoveExpose,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagRemoveExposeUsage,\n\t\tEnvVars: []string{\"DSLIM_RM_EXPOSE\"},\n\t},\n\tFlagRemoveEnv: &cli.StringSliceFlag{\n\t\tName:    FlagRemoveEnv,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagRemoveEnvUsage,\n\t\tEnvVars: []string{\"DSLIM_RM_ENV\"},\n\t},\n\tFlagRemoveLabel: &cli.StringSliceFlag{\n\t\tName:    FlagRemoveLabel,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagRemoveLabelUsage,\n\t\tEnvVars: []string{\"DSLIM_RM_LABEL\"},\n\t},\n\tFlagRemoveVolume: &cli.StringSliceFlag{\n\t\tName:    FlagRemoveVolume,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagRemoveVolumeUsage,\n\t\tEnvVars: []string{\"DSLIM_RM_VOLUME\"},\n\t},\n\tFlagIncludeBinFile: &cli.StringFlag{\n\t\tName:    FlagIncludeBinFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagIncludeBinFileUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_BIN_FILE\"},\n\t},\n\tFlagIncludeExeFile: &cli.StringFlag{\n\t\tName:    FlagIncludeExeFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagIncludeExeFileUsage,\n\t\tEnvVars: []string{\"DSLIM_INCLUDE_EXE_FILE\"},\n\t},\n\t////\n\tFlagObfuscateMetadata: &cli.BoolFlag{\n\t\tName:    FlagObfuscateMetadata,\n\t\tUsage:   FlagObfuscateMetadataUsage,\n\t\tEnvVars: []string{\"DSLIM_OBFUSCATE_METADATA\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n\nfunc GetContainerBuildOptions(ctx *cli.Context) (*config.ContainerBuildOptions, error) {\n\tcbo := &config.ContainerBuildOptions{\n\t\tLabels: map[string]string{},\n\t}\n\n\tcbo.Dockerfile = ctx.String(FlagBuildFromDockerfile)\n\tcbo.DockerfileContext = ctx.String(FlagDockerfileContext)\n\tcbo.Tag = ctx.String(FlagTagFat)\n\tcbo.Target = ctx.String(FlagCBOTarget)\n\tcbo.NetworkMode = ctx.String(FlagCBONetwork)\n\tcbo.CacheFrom = ctx.StringSlice(FlagCBOCacheFrom)\n\n\thosts := ctx.StringSlice(FlagCBOAddHost)\n\t//TODO: figure out how to encode multiple host entries to a string (docs are not helpful)\n\tcbo.ExtraHosts = strings.Join(hosts, \",\")\n\n\trawBuildArgs := ctx.StringSlice(FlagCBOBuildArg)\n\tfor _, rba := range rawBuildArgs {\n\t\t//need to handle:\n\t\t//NAME=VALUE\n\t\t//\"NAME\"=\"VALUE\"\n\t\t//NAME <- value is copied from the env var with the same name\n\t\tparts := strings.SplitN(rba, \"=\", 2)\n\t\tswitch len(parts) {\n\t\tcase 2:\n\t\t\tif strings.HasPrefix(parts[0], \"\\\"\") {\n\t\t\t\tparts[0] = strings.Trim(parts[0], \"\\\"\")\n\t\t\t\tparts[1] = strings.Trim(parts[1], \"\\\"\")\n\t\t\t} else {\n\t\t\t\tparts[0] = strings.Trim(parts[0], \"'\")\n\t\t\t\tparts[1] = strings.Trim(parts[1], \"'\")\n\t\t\t}\n\t\t\tba := config.CBOBuildArg{\n\t\t\t\tName:  parts[0],\n\t\t\t\tValue: parts[1],\n\t\t\t}\n\n\t\t\tcbo.BuildArgs = append(cbo.BuildArgs, ba)\n\t\tcase 1:\n\t\t\tif envVal := os.Getenv(parts[0]); envVal != \"\" {\n\t\t\t\tba := config.CBOBuildArg{\n\t\t\t\t\tName:  parts[0],\n\t\t\t\t\tValue: envVal,\n\t\t\t\t}\n\n\t\t\t\tcbo.BuildArgs = append(cbo.BuildArgs, ba)\n\t\t\t}\n\t\tdefault:\n\t\t\tfmt.Printf(\"GetContainerBuildOptions(): unexpected build arg format - '%v'\\n\", rba)\n\t\t}\n\t}\n\n\trawLabels := ctx.StringSlice(FlagCBOLabel)\n\tfor _, rlabel := range rawLabels {\n\t\tparts := strings.SplitN(rlabel, \"=\", 2)\n\t\tswitch len(parts) {\n\t\tcase 2:\n\t\t\tif strings.HasPrefix(parts[0], \"\\\"\") {\n\t\t\t\tparts[0] = strings.Trim(parts[0], \"\\\"\")\n\t\t\t\tparts[1] = strings.Trim(parts[1], \"\\\"\")\n\t\t\t} else {\n\t\t\t\tparts[0] = strings.Trim(parts[0], \"'\")\n\t\t\t\tparts[1] = strings.Trim(parts[1], \"'\")\n\t\t\t}\n\n\t\t\tcbo.Labels[parts[0]] = parts[1]\n\t\tcase 1:\n\t\t\tif envVal := os.Getenv(parts[0]); envVal != \"\" {\n\t\t\t\tcbo.Labels[parts[0]] = envVal\n\t\t\t}\n\t\tdefault:\n\t\t\tfmt.Printf(\"GetContainerBuildOptions(): unexpected label format - '%v'\\n\", rlabel)\n\t\t}\n\t}\n\n\treturn cbo, nil\n}\n\n//TODO: move/share when the 'edit' command needs these flags too\n\nfunc GetImageInstructions(ctx *cli.Context) (*config.ImageNewInstructions, error) {\n\tentrypoint := ctx.String(FlagNewEntrypoint)\n\tcmd := ctx.String(FlagNewCmd)\n\texpose := ctx.StringSlice(FlagNewExpose)\n\tremoveExpose := ctx.StringSlice(FlagRemoveExpose)\n\n\tinstructions := &config.ImageNewInstructions{\n\t\tWorkdir: ctx.String(FlagNewWorkdir),\n\t\tEnv:     ctx.StringSlice(FlagNewEnv),\n\t}\n\n\tvolumes, err := command.ParseTokenSet(ctx.StringSlice(FlagNewVolume))\n\tif err != nil {\n\t\tfmt.Printf(\"getImageInstructions(): invalid new volume options %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tinstructions.Volumes = volumes\n\n\tlabels, err := command.ParseTokenMap(ctx.StringSlice(FlagNewLabel))\n\tif err != nil {\n\t\tfmt.Printf(\"getImageInstructions(): invalid new label options %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tinstructions.Labels = labels\n\n\tremoveLabels, err := command.ParseTokenSet(ctx.StringSlice(FlagRemoveLabel))\n\tif err != nil {\n\t\tfmt.Printf(\"getImageInstructions(): invalid remove label options %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tinstructions.RemoveLabels = removeLabels\n\n\tremoveEnvs, err := command.ParseTokenSet(ctx.StringSlice(FlagRemoveEnv))\n\tif err != nil {\n\t\tfmt.Printf(\"getImageInstructions(): invalid remove env options %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tinstructions.RemoveEnvs = removeEnvs\n\n\tremoveVolumes, err := command.ParseTokenSet(ctx.StringSlice(FlagRemoveVolume))\n\tif err != nil {\n\t\tfmt.Printf(\"getImageInstructions(): invalid remove volume options %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tinstructions.RemoveVolumes = removeVolumes\n\n\t//TODO(future): also load instructions from a file\n\n\tif len(expose) > 0 {\n\t\tinstructions.ExposedPorts, err = command.ParseDockerExposeOpt(expose)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"getImageInstructions(): invalid expose options => %v\", err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif len(removeExpose) > 0 {\n\t\tinstructions.RemoveExposedPorts, err = command.ParseDockerExposeOpt(removeExpose)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"getImageInstructions(): invalid remove-expose options => %v\", err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tinstructions.Entrypoint, err = command.ParseExec(entrypoint)\n\tif err != nil {\n\t\tlog.Errorf(\"getImageInstructions(): invalid entrypoint option => %v\", err)\n\t\treturn nil, err\n\t}\n\n\t//one space is a hacky way to indicate that you want to remove this instruction from the image\n\tinstructions.ClearEntrypoint = command.IsOneSpace(entrypoint)\n\n\tinstructions.Cmd, err = command.ParseExec(cmd)\n\tif err != nil {\n\t\tlog.Errorf(\"getImageInstructions(): invalid cmd option => %v\", err)\n\t\treturn nil, err\n\t}\n\n\t//same hack to indicate you want to remove this instruction\n\tinstructions.ClearCmd = command.IsOneSpace(cmd)\n\n\treturn instructions, nil\n}\n\nfunc GetAppNodejsInspectOptions(ctx *cli.Context) config.AppNodejsInspectOptions {\n\treturn config.AppNodejsInspectOptions{\n\t\tIncludePackages: ctx.StringSlice(FlagIncludeNodePackage),\n\t\tNextOpts:        getAppNextInspectOptions(ctx),\n\t\tNuxtOpts:        getAppNuxtInspectOptions(ctx),\n\t}\n}\n\nfunc getAppNextInspectOptions(ctx *cli.Context) config.NodejsWebFrameworkInspectOptions {\n\treturn config.NodejsWebFrameworkInspectOptions{\n\t\tIncludeAppDir:         ctx.Bool(FlagIncludeAppNextDir),\n\t\tIncludeBuildDir:       ctx.Bool(FlagIncludeAppNextBuildDir),\n\t\tIncludeDistDir:        ctx.Bool(FlagIncludeAppNextDistDir),\n\t\tIncludeStaticDir:      ctx.Bool(FlagIncludeAppNextStaticDir),\n\t\tIncludeNodeModulesDir: ctx.Bool(FlagIncludeAppNextNodeModulesDir),\n\t}\n}\n\nfunc getAppNuxtInspectOptions(ctx *cli.Context) config.NodejsWebFrameworkInspectOptions {\n\treturn config.NodejsWebFrameworkInspectOptions{\n\t\tIncludeAppDir:         ctx.Bool(FlagIncludeAppNuxtDir),\n\t\tIncludeBuildDir:       ctx.Bool(FlagIncludeAppNuxtBuildDir),\n\t\tIncludeDistDir:        ctx.Bool(FlagIncludeAppNuxtDistDir),\n\t\tIncludeStaticDir:      ctx.Bool(FlagIncludeAppNuxtStaticDir),\n\t\tIncludeNodeModulesDir: ctx.Bool(FlagIncludeAppNuxtNodeModulesDir),\n\t}\n}\n\nfunc GetKubernetesOptions(ctx *cli.Context) (config.KubernetesOptions, error) {\n\tcfg := config.KubernetesOptions{\n\t\tTarget: config.KubernetesTarget{\n\t\t\tWorkload:  ctx.String(command.FlagTargetKubeWorkload),\n\t\t\tNamespace: ctx.String(command.FlagTargetKubeWorkloadNamespace),\n\t\t\tContainer: ctx.String(command.FlagTargetKubeWorkloadContainer),\n\t\t},\n\t\tTargetOverride: config.KubernetesTargetOverride{\n\t\t\tImage: ctx.String(command.FlagTargetKubeWorkloadImage),\n\t\t},\n\t\tManifests:  ctx.StringSlice(command.FlagKubeManifestFile),\n\t\tKubeconfig: ctx.String(command.FlagKubeKubeconfigFile),\n\t}\n\n\tif len(cfg.Target.Namespace)+len(cfg.Target.Container)+len(cfg.TargetOverride.Image)+len(cfg.Manifests) > 0 && cfg.Target.Workload == \"\" {\n\t\treturn cfg, errors.New(\"--target-kube-workload flag must be provided\")\n\t}\n\n\treturn cfg, nil\n}\n\nconst (\n\tIBENone     = \"none\"\n\tIBEInternal = \"internal\"\n\tIBEDocker   = \"docker\"\n\tIBEBuildKit = \"buildkit\"\n)\n\nfunc getImageBuildEngine(ctx *cli.Context) (string, error) {\n\tvalue := ctx.String(FlagImageBuildEngine)\n\tswitch value {\n\tcase IBENone, IBEInternal, IBEDocker, IBEBuildKit:\n\t\treturn value, nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"bad value\")\n\t}\n}\n\nconst (\n\tArchEmpty = \"\"\n\tArchAmd64 = \"amd64\"\n\tArchArm64 = \"arm64\"\n)\n\nfunc getImageBuildArch(ctx *cli.Context) (string, error) {\n\tvalue := ctx.String(FlagImageBuildArch)\n\tswitch value {\n\tcase ArchEmpty, ArchAmd64, ArchArm64:\n\t\treturn value, nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"bad value\")\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/handler.go",
    "content": "package build\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/compose\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/container\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/kubernetes\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/probe/http\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerimage\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/printbuffer\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\t\"github.com/dustin/go-humanize\"\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst appName = command.AppName\nconst composeProjectNamePat = \"dsbuild_%v_%v\"\n\n// Build command exit codes\nconst (\n\tecbOther = iota + 1\n\tecbBadCustomImageTag\n\tecbImageBuildError\n\tecbImageAlreadyOptimized\n\tecbOnbuildBaseImage\n\tecbNoEntrypoint\n\tecbBadTargetComposeSvc\n\tecbComposeSvcNoImage\n\tecbComposeSvcUnknownImage\n\tecbKubernetesNoWorkload\n\tecbKubernetesNoWorkloadContainer\n\tecbNotImplementedYet\n)\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'build' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\ttargetRef string,\n\tdoPull bool,\n\tdockerConfigPath string,\n\tregistryAccount string,\n\tregistrySecret string,\n\tdoShowPullLogs bool,\n\n\tcomposeFiles []string,\n\ttargetComposeSvc string,\n\ttargetComposeSvcImage string,\n\tcomposeSvcStartWait int,\n\tcomposeSvcNoPorts bool,\n\tdepExcludeComposeSvcAll bool,\n\tdepIncludeComposeSvcDeps string,\n\tdepIncludeTargetComposeSvcDeps bool,\n\tdepIncludeComposeSvcs []string,\n\tdepExcludeComposeSvcs []string,\n\tcomposeNets []string,\n\tcomposeEnvVars []string,\n\tcomposeEnvNoHost bool,\n\tcomposeWorkdir string,\n\tcomposeProjectName string,\n\tcontainerProbeComposeSvc string,\n\n\tcbOpts *config.ContainerBuildOptions,\n\tcrOpts *config.ContainerRunOptions,\n\toutputTags []string,\n\n\thttpProbeOpts config.HTTPProbeOptions,\n\n\tportBindings map[dockerapi.Port][]dockerapi.PortBinding,\n\tdoPublishExposedPorts bool,\n\thostExecProbes []string,\n\tdoRmFileArtifacts bool,\n\tcopyMetaArtifactsLocation string,\n\tdoRunTargetAsUser bool,\n\tdoShowContainerLogs bool,\n\tdoEnableMondel bool,\n\tdoShowBuildLogs bool,\n\timageOverrideSelectors map[string]bool,\n\toverrides *config.ContainerOverrides,\n\tinstructions *config.ImageNewInstructions,\n\tlinks []string,\n\tetcHostsMaps []string,\n\tdnsServers []string,\n\tdnsSearchDomains []string,\n\texplicitVolumeMounts map[string]config.VolumeMount,\n\tdoKeepPerms bool,\n\tpathPerms map[string]*fsutil.AccessInfo,\n\n\texcludePatterns map[string]*fsutil.AccessInfo,\n\tdoExcludeVarLockFiles bool,\n\tpreservePaths map[string]*fsutil.AccessInfo,\n\tincludePaths map[string]*fsutil.AccessInfo,\n\tincludeBins map[string]*fsutil.AccessInfo,\n\tincludeDirBinsList map[string]*fsutil.AccessInfo,\n\tincludeExes map[string]*fsutil.AccessInfo,\n\tdoIncludeShell bool,\n\tdoIncludeWorkdir bool,\n\tincludeLastImageLayers uint,\n\tdoIncludeAppImageAll bool,\n\tappImageStartInstGroup int,\n\tappImageStartInst string,\n\tappImageDockerfileInsts []string,\n\tdoIncludeSSHClient bool,\n\tdoIncludeOSLibsNet bool,\n\tdoIncludeZoneInfo bool,\n\tdoIncludeCertAll bool,\n\tdoIncludeCertBundles bool,\n\tdoIncludeCertDirs bool,\n\tdoIncludeCertPKAll bool,\n\tdoIncludeCertPKDirs bool,\n\tdoIncludeNew bool,\n\tdoUseLocalMounts bool,\n\tdoUseSensorVolume string,\n\tdoKeepTmpArtifacts bool,\n\tcontinueAfter *config.ContinueAfter,\n\texecCmd string,\n\texecFileCmd string,\n\tdoDeleteFatImage bool,\n\trtaOnbuildBaseImage bool,\n\trtaSourcePT bool,\n\tdoObfuscateMetadata bool,\n\tsensorIPCEndpoint string,\n\tsensorIPCMode string,\n\tkubeOpts config.KubernetesOptions,\n\tappNodejsInspectOpts config.AppNodejsInspectOptions,\n\timageBuildEngine string,\n\timageBuildArch string,\n) {\n\tprintState := true\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": Name})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewBuildCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\tcmdReport.TargetReference = targetRef\n\n\tcmdReportOnExit := func() {\n\t\tcmdReport.State = cmd.StateError\n\t\tif cmdReport.Save() {\n\t\t\txc.Out.Info(\"report\",\n\t\t\t\tovars{\n\t\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t\t})\n\t\t}\n\t}\n\n\txc.AddCleanupHandler(cmdReportOnExit)\n\n\tvar customImageTag string\n\tvar additionalTags []string\n\n\tif len(outputTags) > 0 {\n\t\tcustomImageTag = outputTags[0]\n\n\t\tif len(outputTags) > 1 {\n\t\t\tadditionalTags = outputTags[1:]\n\t\t}\n\t}\n\n\tlogger.Debugf(\"customImageTag='%s', additionalTags=%#v\", customImageTag, additionalTags)\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim container\"\n\t\t}\n\n\t\txc.Out.Error(\"docker.connect.error\", exitMsg)\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\n\t\tcmdReport.Error = \"docker.connect.error\"\n\t\txc.Exit(exitCode)\n\t}\n\txc.FailOn(err)\n\n\txc.Out.State(\"started\")\n\n\tif kubeOpts.HasTargetSet() {\n\t\txc.Out.Info(\"params\",\n\t\t\tovars{\n\t\t\t\t\"target.type\":        \"kubernetes.workload\",\n\t\t\t\t\"target\":             kubeOpts.Target.Workload,\n\t\t\t\t\"target.namespace\":   kubeOpts.Target.Namespace,\n\t\t\t\t\"target.container\":   kubeOpts.Target.Container,\n\t\t\t\t\"target.image\":       kubeOpts.TargetOverride.Image,\n\t\t\t\t\"continue.mode\":      continueAfter.Mode,\n\t\t\t\t\"image-build-engine\": imageBuildEngine,\n\t\t\t})\n\n\t\tkubeClient, err := kubernetes.NewClient(kubeOpts)\n\t\txc.FailOn(err)\n\n\t\tvar manifests *kubernetes.Manifests\n\t\tif len(kubeOpts.Manifests) > 0 {\n\t\t\tmanifests, err = kubernetes.ManifestsFromFiles(\n\t\t\t\tkubeOpts,\n\t\t\t\tkubeClient,\n\t\t\t\tkubernetes.NewResourceBuilderFunc(kubeOpts))\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\th := newKubeHandler(\n\t\t\txc,\n\t\t\tcontext.TODO(),\n\t\t\tcmdReport,\n\t\t\tlogger,\n\t\t\tclient,\n\t\t\tkubeClient,\n\t\t\tkubernetes.NewKubectl(kubeOpts),\n\t\t\tkubernetes.NewWorkloadFinder(manifests, kubernetes.NewResourceBuilderFunc(kubeOpts)))\n\t\th.Handle(\n\t\t\tkubeOpts.Target,\n\t\t\tkubeOpts.TargetOverride,\n\t\t\tmanifests,\n\t\t\tkubeHandleOptions{\n\t\t\t\tDoPull:                    doPull,\n\t\t\t\tDoShowPullLogs:            doShowPullLogs,\n\t\t\t\tDoShowBuildLogs:           doShowBuildLogs,\n\t\t\t\tDoShowContainerLogs:       doShowContainerLogs,\n\t\t\t\tDoEnableMondel:            doEnableMondel,\n\t\t\t\tDoDeleteFatImage:          doDeleteFatImage,\n\t\t\t\tDoRmFileArtifacts:         doRmFileArtifacts,\n\t\t\t\tCBOpts:                    cbOpts,\n\t\t\t\tRtaOnbuildBaseImage:       rtaOnbuildBaseImage,\n\t\t\t\tRtaSourcePT:               rtaSourcePT,\n\t\t\t\tDockerConfigPath:          dockerConfigPath,\n\t\t\t\tRegistryAccount:           registryAccount,\n\t\t\t\tRegistrySecret:            registrySecret,\n\t\t\t\tKeepPerms:                 doKeepPerms,\n\t\t\t\tPathPerms:                 pathPerms,\n\t\t\t\tArchiveState:              gparams.ArchiveState,\n\t\t\t\tStatePath:                 gparams.StatePath,\n\t\t\t\tCopyMetaArtifactsLocation: copyMetaArtifactsLocation,\n\t\t\t\tDebug:                     gparams.Debug,\n\t\t\t\tLogLevel:                  gparams.LogLevel,\n\t\t\t\tLogFormat:                 gparams.LogFormat,\n\t\t\t\tSensorIPCEndpoint:         sensorIPCEndpoint,\n\t\t\t\tCustomImageTag:            customImageTag,\n\t\t\t\tAdditionalTags:            additionalTags,\n\t\t\t\thttpProbeOpts:             httpProbeOpts,\n\t\t\t\tcontinueAfter:             continueAfter,\n\t\t\t\texecCmd:                   execCmd,\n\t\t\t\timageBuildEngine:          imageBuildEngine,\n\t\t\t\timageBuildArch:            imageBuildArch,\n\t\t\t})\n\n\t\tvinfo := <-viChan\n\t\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\t\treturn\n\t}\n\n\tif len(composeFiles) > 0 && targetComposeSvc != \"\" {\n\t\txc.Out.Info(\"params\",\n\t\t\tovars{\n\t\t\t\t\"target.type\":        \"compose.service\",\n\t\t\t\t\"target\":             targetRef,\n\t\t\t\t\"continue.mode\":      continueAfter.Mode,\n\t\t\t\t\"rt.as.user\":         doRunTargetAsUser,\n\t\t\t\t\"keep.perms\":         doKeepPerms,\n\t\t\t\t\"tags\":               strings.Join(outputTags, \",\"),\n\t\t\t\t\"image-build-engine\": imageBuildEngine,\n\t\t\t})\n\t} else if cbOpts.Dockerfile != \"\" {\n\t\txc.Out.Info(\"params\",\n\t\t\tovars{\n\t\t\t\t\"target.type\":        \"dockerfile\",\n\t\t\t\t\"context\":            targetRef,\n\t\t\t\t\"file\":               cbOpts.Dockerfile,\n\t\t\t\t\"continue.mode\":      continueAfter.Mode,\n\t\t\t\t\"rt.as.user\":         doRunTargetAsUser,\n\t\t\t\t\"keep.perms\":         doKeepPerms,\n\t\t\t\t\"image-build-engine\": imageBuildEngine,\n\t\t\t})\n\t} else {\n\t\txc.Out.Info(\"params\",\n\t\t\tovars{\n\t\t\t\t\"target.type\":        \"image\",\n\t\t\t\t\"target.image\":       targetRef,\n\t\t\t\t\"continue.mode\":      continueAfter.Mode,\n\t\t\t\t\"rt.as.user\":         doRunTargetAsUser,\n\t\t\t\t\"keep.perms\":         doKeepPerms,\n\t\t\t\t\"tags\":               strings.Join(outputTags, \",\"),\n\t\t\t\t\"image-build-engine\": imageBuildEngine,\n\t\t\t})\n\t}\n\n\tif cbOpts.Dockerfile != \"\" {\n\t\ttargetRef = buildFatImage(xc, targetRef, customImageTag, cbOpts, doShowBuildLogs, client, cmdReport)\n\t}\n\n\tvar serviceAliases []string\n\tvar depServicesExe *compose.Execution\n\tvar baseVolumesFrom []string\n\tvar baseMounts []dockerapi.HostMount\n\tif len(composeFiles) > 0 {\n\t\tif targetComposeSvc != \"\" && depIncludeComposeSvcDeps != targetComposeSvc {\n\t\t\tvar found bool\n\t\t\tfor _, svcName := range depExcludeComposeSvcs {\n\t\t\t\tif svcName == targetComposeSvc {\n\t\t\t\t\tfound = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !found {\n\t\t\t\t//exclude the target service if the target service is not excluded already\n\t\t\t\tdepExcludeComposeSvcs = append(depExcludeComposeSvcs, targetComposeSvc)\n\t\t\t}\n\t\t}\n\n\t\tif depIncludeTargetComposeSvcDeps {\n\t\t\tdepIncludeComposeSvcDeps = targetComposeSvc\n\t\t}\n\n\t\tselectors := compose.NewServiceSelectors(\n\t\t\tdepIncludeComposeSvcDeps,\n\t\t\tdepIncludeComposeSvcs,\n\t\t\tdepExcludeComposeSvcs)\n\n\t\t//todo: move compose flags to options\n\t\toptions := &compose.ExecutionOptions{\n\t\t\tSvcStartWait: composeSvcStartWait,\n\t\t}\n\n\t\tlogger.Debugf(\"compose: file(s)='%s' selectors='%+v'\\n\",\n\t\t\tstrings.Join(composeFiles, \",\"), selectors)\n\n\t\tif composeProjectName == \"\" {\n\t\t\tcomposeProjectName = fmt.Sprintf(composeProjectNamePat, os.Getpid(), time.Now().UTC().Format(\"20060102150405\"))\n\t\t}\n\n\t\texe, err := compose.NewExecution(xc,\n\t\t\tlogger,\n\t\t\tclient,\n\t\t\tcomposeFiles,\n\t\t\tselectors,\n\t\t\tcomposeProjectName,\n\t\t\tcomposeWorkdir,\n\t\t\tcomposeEnvVars,\n\t\t\tcomposeEnvNoHost,\n\t\t\tcontainerProbeComposeSvc,\n\t\t\tfalse, //buildImages\n\t\t\tdoPull,\n\t\t\tnil,  //pullExcludes (todo: add a flag)\n\t\t\ttrue, //ownAllResources\n\t\t\toptions,\n\t\t\tnil, //eventCh\n\t\t\tprintState)\n\n\t\txc.FailOn(err)\n\n\t\tif !depExcludeComposeSvcAll && !exe.SelectedHaveImages() {\n\t\t\txc.Out.Info(\"compose.file.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\": \"service.no.image\",\n\t\t\t\t\t\"files\":  strings.Join(composeFiles, \",\"),\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTBuild | ecbComposeSvcNoImage\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t\t})\n\n\t\t\txc.Exit(exitCode)\n\t\t}\n\n\t\tif targetComposeSvc != \"\" {\n\t\t\ttargetSvcInfo := exe.Service(targetComposeSvc)\n\t\t\tif targetSvcInfo == nil {\n\t\t\t\txc.Out.Info(\"target.compose.svc.error\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"status\": \"unknown.compose.service\",\n\t\t\t\t\t\t\"target\": targetComposeSvc,\n\t\t\t\t\t\t\"files\":  strings.Join(composeFiles, \",\"),\n\t\t\t\t\t})\n\n\t\t\t\texitCode := command.ECTBuild | ecbBadTargetComposeSvc\n\t\t\t\txc.Out.State(\"exited\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t\t\t})\n\n\t\t\t\txc.Exit(exitCode)\n\t\t\t}\n\n\t\t\tserviceAliases = append(serviceAliases, targetSvcInfo.Config.Name)\n\n\t\t\ttargetRef = targetSvcInfo.Config.Image\n\t\t\tif targetComposeSvcImage != \"\" {\n\t\t\t\ttargetRef = command.UpdateImageRef(logger, targetRef, targetComposeSvcImage)\n\t\t\t\t//shouldn't need to\n\t\t\t\ttargetSvcInfo.Config.Image = targetRef\n\t\t\t\tlogger.Debugf(\"using target service override '%s' -> '%s' \", targetComposeSvcImage, targetRef)\n\t\t\t}\n\n\t\t\tif len(targetSvcInfo.Config.Entrypoint) > 0 {\n\t\t\t\tlogger.Debug(\"using targetSvcInfo.Config.Entrypoint\")\n\t\t\t\toverrides.Entrypoint = targetSvcInfo.Config.Entrypoint\n\t\t\t}\n\n\t\t\tif len(targetSvcInfo.Config.Command) > 0 {\n\t\t\t\tlogger.Debug(\"using targetSvcInfo.Config.Command\")\n\t\t\t\toverrides.Cmd = targetSvcInfo.Config.Command\n\t\t\t}\n\n\t\t\tif overrides.Workdir == \"\" {\n\t\t\t\toverrides.Workdir = targetSvcInfo.Config.WorkingDir\n\t\t\t}\n\n\t\t\tif overrides.Hostname == \"\" {\n\t\t\t\toverrides.Hostname = targetSvcInfo.Config.Hostname\n\t\t\t}\n\n\t\t\tlabelMap := map[string]string{}\n\t\t\tfor k, v := range targetSvcInfo.Config.Labels {\n\t\t\t\tlabelMap[k] = v\n\t\t\t}\n\n\t\t\tfor k, v := range overrides.Labels {\n\t\t\t\tlabelMap[k] = v\n\t\t\t}\n\n\t\t\toverrides.Labels = labelMap\n\n\t\t\tif overrides.User != \"\" {\n\t\t\t\toverrides.User = targetSvcInfo.Config.User\n\t\t\t}\n\n\t\t\t//todo: add command flags for these fields too\n\t\t\t//targetSvcInfo.Config.DomainName\n\n\t\t\t//env vars\n\t\t\t//the env vars from compose are already \"resolved\" and must be \"k=v\"\n\t\t\tsvcEnvVars := compose.EnvVarsFromService(\n\t\t\t\ttargetSvcInfo.Config.Environment,\n\t\t\t\ttargetSvcInfo.Config.EnvFile)\n\n\t\t\temap := map[string]string{}\n\t\t\t//start with compose env vars\n\t\t\tfor _, env := range svcEnvVars {\n\t\t\t\tenvComponents := strings.SplitN(env, \"=\", 2)\n\t\t\t\tif len(envComponents) == 2 {\n\t\t\t\t\temap[envComponents[0]] = envComponents[1]\n\t\t\t\t} else {\n\t\t\t\t\tlogger.Debugf(\"svcEnvVars - unexpected env var: '%s'\", env)\n\t\t\t\t}\n\t\t\t}\n\t\t\t//then use env vars from overrides\n\t\t\tfor _, env := range overrides.Env {\n\t\t\t\tenvComponents := strings.SplitN(env, \"=\", 2)\n\t\t\t\tif len(envComponents) == 2 {\n\t\t\t\t\temap[envComponents[0]] = envComponents[1]\n\t\t\t\t} else {\n\t\t\t\t\tlogger.Debugf(\"overrides.Env - unexpected env var: '%s'\", env)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// combine into overrides\n\t\t\tvar combineEnv []string\n\t\t\tfor key, val := range emap {\n\t\t\t\tvariable := fmt.Sprintf(\"%s=%s\", key, val)\n\t\t\t\tcombineEnv = append(combineEnv, variable)\n\t\t\t}\n\t\t\toverrides.Env = combineEnv\n\n\t\t\tlogger.Debugf(\"compose: Environment_Variables='%v'\\n\", overrides.Env)\n\n\t\t\t//expose ports\n\t\t\tsvcExposedPorts := compose.ExposedPorts(targetSvcInfo.Config.Expose, targetSvcInfo.Config.Ports)\n\t\t\tif len(svcExposedPorts) > 0 && overrides.ExposedPorts == nil {\n\t\t\t\toverrides.ExposedPorts = map[dockerapi.Port]struct{}{}\n\t\t\t}\n\n\t\t\tfor k, v := range svcExposedPorts {\n\t\t\t\toverrides.ExposedPorts[k] = v\n\t\t\t}\n\n\t\t\t//publish ports\n\t\t\tif !composeSvcNoPorts {\n\t\t\t\tlogger.Debug(\"using targetSvcInfo.Config.Ports\")\n\t\t\t\tfor _, p := range targetSvcInfo.Config.Ports {\n\t\t\t\t\tportKey := fmt.Sprintf(\"%v/%v\", p.Target, p.Protocol)\n\t\t\t\t\tpbSet, found := portBindings[dockerapi.Port(portKey)]\n\t\t\t\t\tif found {\n\t\t\t\t\t\tfound := false\n\t\t\t\t\t\thostPort := fmt.Sprintf(\"%v\", p.Published)\n\t\t\t\t\t\tfor _, pinfo := range pbSet {\n\t\t\t\t\t\t\tif pinfo.HostIP == p.HostIP && pinfo.HostPort == hostPort {\n\t\t\t\t\t\t\t\tfound = true\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\tpbSet = append(pbSet, dockerapi.PortBinding{\n\t\t\t\t\t\t\t\tHostIP:   p.HostIP,\n\t\t\t\t\t\t\t\tHostPort: hostPort,\n\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tportBindings[dockerapi.Port(portKey)] = pbSet\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tportBindings[dockerapi.Port(portKey)] = []dockerapi.PortBinding{{\n\t\t\t\t\t\t\tHostIP:   p.HostIP,\n\t\t\t\t\t\t\tHostPort: fmt.Sprintf(\"%v\", p.Published),\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\t//make sure not to shadow baseMounts\n\t\t\tbaseMounts, err = compose.MountsFromVolumeConfigs(\n\t\t\t\texe.BaseComposeDir,\n\t\t\t\ttargetSvcInfo.Config.Volumes,\n\t\t\t\ttargetSvcInfo.Config.Tmpfs,\n\t\t\t\texe.ActiveVolumes)\n\t\t\txc.FailOn(err)\n\n\t\t\tlogger.Debugf(\"compose targetSvcInfo - baseMounts(%d)\", len(baseMounts))\n\n\t\t\tbaseVolumesFrom = compose.VolumesFrom(exe.AllServiceNames,\n\t\t\t\ttargetSvcInfo.Config.VolumesFrom)\n\n\t\t\tlogger.Debugf(\"compose targetSvcInfo - baseVolumesFrom(%d)\", len(baseVolumesFrom))\n\t\t}\n\n\t\tif !depExcludeComposeSvcAll {\n\t\t\tdepServicesExe = exe\n\t\t}\n\t}\n\n\tlogger.Infof(\"image=%v http-probe=%v remove-file-artifacts=%v image-overrides=%+v entrypoint=%+v (%v) cmd=%+v (%v) workdir='%v' env=%+v expose=%+v\",\n\t\ttargetRef, httpProbeOpts.Do, doRmFileArtifacts,\n\t\timageOverrideSelectors,\n\t\toverrides.Entrypoint, overrides.ClearEntrypoint, overrides.Cmd, overrides.ClearCmd,\n\t\toverrides.Workdir, overrides.Env, overrides.ExposedPorts)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, Name, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tif overrides.Network == \"host\" && runtime.GOOS == \"darwin\" {\n\t\txc.Out.Info(\"param.error\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"unsupported.network.mac\",\n\t\t\t\t\"value\":  overrides.Network,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCBadNetworkName\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\n\t\txc.Exit(exitCode)\n\t}\n\n\tif !command.ConfirmNetwork(logger, client, overrides.Network) {\n\t\txc.Out.Info(\"param.error\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"unknown.network\",\n\t\t\t\t\"value\":  overrides.Network,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCBadNetworkName\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\n\t\txc.Exit(exitCode)\n\t}\n\n\timageInspector, localVolumePath, statePath, stateKey := inspectFatImage(\n\t\txc,\n\t\ttargetRef,\n\t\tdoPull,\n\t\tdoShowPullLogs,\n\t\trtaOnbuildBaseImage,\n\t\tdockerConfigPath,\n\t\tregistryAccount,\n\t\tregistrySecret,\n\t\tgparams.StatePath,\n\t\tclient,\n\t\tlogger,\n\t\tcmdReport)\n\n\tloadExtraIncludePaths := func() {\n\t\tif (includeLastImageLayers > 0) ||\n\t\t\t(appImageStartInstGroup > -1) ||\n\t\t\t(appImageStartInst != \"\") ||\n\t\t\t(len(appImageDockerfileInsts) > 0) {\n\t\t\tlogger.Debugf(\"loadExtraIncludePaths: includeLastImageLayers=%v appImageStartInstGroup=%v appImageStartInst='%v' len.appImageDockerfileInsts=%v\",\n\t\t\t\tincludeLastImageLayers, appImageStartInstGroup, appImageStartInst, len(appImageDockerfileInsts))\n\n\t\t\tincludeLayerPaths := map[string]*fsutil.AccessInfo{}\n\t\t\timageID := dockerutil.CleanImageID(imageInspector.ImageInfo.ID)\n\t\t\tiaName := fmt.Sprintf(\"%s.tar\", imageID)\n\t\t\tiaPath := filepath.Join(localVolumePath, \"image\", iaName)\n\t\t\tiaPathReady := fmt.Sprintf(\"%s.ready\", iaPath)\n\n\t\t\tvar doSave bool\n\t\t\tif fsutil.IsRegularFile(iaPath) {\n\t\t\t\t//if !doReuseSavedImage {\n\t\t\t\t//\tdoSave = true\n\t\t\t\t//}\n\n\t\t\t\tif !fsutil.Exists(iaPathReady) {\n\t\t\t\t\tdoSave = true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdoSave = true\n\t\t\t}\n\n\t\t\tif doSave {\n\t\t\t\tif fsutil.Exists(iaPathReady) {\n\t\t\t\t\tfsutil.Remove(iaPathReady)\n\t\t\t\t}\n\n\t\t\t\txc.Out.Info(\"image.data.inspection.save.image.start\")\n\t\t\t\terr = dockerutil.SaveImage(client, imageID, iaPath, false, false)\n\t\t\t\terrutil.FailOn(err)\n\n\t\t\t\terr = fsutil.Touch(iaPathReady)\n\t\t\t\terrutil.WarnOn(err)\n\n\t\t\t\txc.Out.Info(\"image.data.inspection.save.image.end\")\n\t\t\t} else {\n\t\t\t\tlogger.Debugf(\"exported image already exists - %s\", iaPath)\n\t\t\t}\n\n\t\t\txc.Out.Info(\"image.data.inspection.list.files.start\")\n\t\t\timgFiles, err := dockerimage.NewPackageFiles(iaPath)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Errorf(\"loadExtraIncludePaths: dockerimage.NewPackageFiles(%v) error - %v\", iaPath, err)\n\t\t\t} else {\n\t\t\t\tlayerCount := imgFiles.LayerCount()\n\n\t\t\t\tif (layerCount > 0) &&\n\t\t\t\t\t((appImageStartInstGroup > -1) || (appImageStartInst != \"\") || (len(appImageDockerfileInsts) > 0)) &&\n\t\t\t\t\tdoIncludeAppImageAll {\n\t\t\t\t\t//TODO: refactor the condition logic\n\t\t\t\t\t//appImageStartInstGroup - reverse index\n\t\t\t\t\thistory, err := imgFiles.ListImageHistory()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlogger.Errorf(\"loadExtraIncludePaths: imgFiles.ListImageHistory() - error - %v\", err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tlayers, err := imgFiles.ListLayerMetadata()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlogger.Errorf(\"loadExtraIncludePaths: imgFiles.ListLayerMetadata() - error - %v\", err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tif len(imageInspector.DockerfileInfo.AllInstructions) != len(history) {\n\t\t\t\t\t\tlogger.Errorf(\"loadExtraIncludePaths: instruction count (%d) != history count (%d)\",\n\t\t\t\t\t\t\tlen(imageInspector.DockerfileInfo.AllInstructions), len(history))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\n\t\t\t\t\tappImageStartInstIndex := -1\n\t\t\t\t\tappImageStartLayerIndex := -1\n\t\t\t\t\t//var appImageStartLayerInfo *dockerimage.LayerMetadata\n\n\t\t\t\t\t//calculate the start instruction index by iterating over df instruction list\n\t\t\t\t\tvar instCount int\n\t\t\t\t\tif len(appImageDockerfileInsts) > 0 {\n\t\t\t\t\t\t//use the instructions from the last 'stage' (first 'FROM' in reverse)\n\t\t\t\t\t\tfor i := len(appImageDockerfileInsts) - 1; i > -1; i-- {\n\t\t\t\t\t\t\tif strings.HasPrefix(appImageDockerfileInsts[i], \"FROM \") {\n\t\t\t\t\t\t\t\tlogger.Tracef(\"loadExtraIncludePaths: app image dockerfile (reverse) instruction count - [%v] %v\", i, instCount)\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif strings.HasPrefix(appImageDockerfileInsts[i], \"ARG \") {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tinstCount++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif instCount > 0 {\n\t\t\t\t\t\t//NOTE: prefer reverse instruction count from the app image Dockerfile\n\t\t\t\t\t\tfor current, idx := 0, len(imageInspector.DockerfileInfo.AllInstructions)-1; idx > -1; idx-- {\n\t\t\t\t\t\t\tcurrent++\n\t\t\t\t\t\t\tif current == instCount {\n\t\t\t\t\t\t\t\tappImageStartInstIndex = idx\n\t\t\t\t\t\t\t\tlogger.Tracef(\"loadExtraIncludePaths: app image start instruction from app dockerfile - [%v][%v] %#v\",\n\t\t\t\t\t\t\t\t\tinstCount, idx, imageInspector.DockerfileInfo.AllInstructions[idx])\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor idx, instInfo := range imageInspector.DockerfileInfo.AllInstructions {\n\t\t\t\t\t\t\tif appImageStartInst != \"\" {\n\t\t\t\t\t\t\t\t//NOTE: prefer to use the start instruction prefix if it's provided\n\t\t\t\t\t\t\t\tif strings.HasPrefix(instInfo.CommandAll, appImageStartInst) {\n\t\t\t\t\t\t\t\t\t//use the fist match\n\t\t\t\t\t\t\t\t\tappImageStartInstIndex = idx\n\t\t\t\t\t\t\t\t\tlogger.Tracef(\"loadExtraIncludePaths: app image start instruction match - [%v] %#v\", idx, instInfo)\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif instInfo.InstSetTimeReverseIndex == appImageStartInstGroup {\n\t\t\t\t\t\t\t\t\tappImageStartInstIndex = idx\n\t\t\t\t\t\t\t\t\tlogger.Tracef(\"loadExtraIncludePaths: app image start instruction group match - [%v] => [%v] %#v\", appImageStartInstGroup, idx, instInfo)\n\t\t\t\t\t\t\t\t\tbreak\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\n\t\t\t\t\tif appImageStartInstIndex > -1 {\n\t\t\t\t\t\trawLayerCount := 0\n\t\t\t\t\t\tfor hidx, record := range history {\n\t\t\t\t\t\t\tif hidx == appImageStartInstIndex {\n\t\t\t\t\t\t\t\t//start layer index is the layer that follows\n\t\t\t\t\t\t\t\t//the last layer we've seen already\n\t\t\t\t\t\t\t\tappImageStartLayerIndex = rawLayerCount\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif !record.EmptyLayer {\n\t\t\t\t\t\t\t\trawLayerCount++\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif rawLayerCount >= layerCount {\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif appImageStartLayerIndex > -1 {\n\t\t\t\t\t\t\tstartLayerInfo := layers[appImageStartLayerIndex]\n\t\t\t\t\t\t\tlogger.Tracef(\"loadExtraIncludePaths: app image start layer - %#v\", startLayerInfo)\n\n\t\t\t\t\t\t\tif doIncludeAppImageAll {\n\t\t\t\t\t\t\t\tselectors := []dockerimage.FileSelector{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tType:        dockerimage.FSTIndexRange,\n\t\t\t\t\t\t\t\t\t\tIndexKey:    appImageStartLayerIndex,\n\t\t\t\t\t\t\t\t\t\tIndexEndKey: layerCount - 1,\n\t\t\t\t\t\t\t\t\t\tNoDirs:      true,\n\t\t\t\t\t\t\t\t\t\tDeleted:     false,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif layerFiles, err := imgFiles.ListLayerFiles(selectors); err != nil {\n\t\t\t\t\t\t\t\t\tlogger.Errorf(\"loadExtraIncludePaths: imgFiles.ListLayerFiles() error - %v\", err)\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tfor _, lf := range layerFiles {\n\t\t\t\t\t\t\t\t\t\tlogger.Tracef(\"loadExtraIncludePaths: [ALS] layerFiles=%v/%v/%v fileCount=%v\",\n\t\t\t\t\t\t\t\t\t\t\tlf.Layer.Index,\n\t\t\t\t\t\t\t\t\t\t\tlf.Layer.Digest,\n\t\t\t\t\t\t\t\t\t\t\tlf.Layer.DiffID,\n\t\t\t\t\t\t\t\t\t\t\tlen(lf.Files))\n\t\t\t\t\t\t\t\t\t\tfor _, fileInfo := range lf.Files {\n\t\t\t\t\t\t\t\t\t\t\tlogger.Tracef(\"loadExtraIncludePaths: [ALS] layerFiles.File=%v\", fileInfo.Name)\n\t\t\t\t\t\t\t\t\t\t\tincludeLayerPaths[fileInfo.Name] = nil\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlogger.Debugf(\"loadExtraIncludePaths: doIncludeAppImageAll=false\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlogger.Debug(\"loadExtraIncludePaths: no layer instructions found\")\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger.Debug(\"loadExtraIncludePaths: no appImageStartInstIndex\")\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif includeLastImageLayers > 0 {\n\t\t\t\t\tif includeLastImageLayers > uint(layerCount) {\n\t\t\t\t\t\tlogger.Debugf(\"includeLastImageLayers(%v) > layerCount(%v)\", includeLastImageLayers, layerCount)\n\t\t\t\t\t\tincludeLastImageLayers = uint(layerCount)\n\t\t\t\t\t}\n\n\t\t\t\t\tselectors := []dockerimage.FileSelector{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tType:              dockerimage.FSTIndexRange,\n\t\t\t\t\t\t\tIndexKey:          0,\n\t\t\t\t\t\t\tIndexEndKey:       int(includeLastImageLayers) - 1,\n\t\t\t\t\t\t\tReverseIndexRange: true,\n\t\t\t\t\t\t\tNoDirs:            true,\n\t\t\t\t\t\t\tDeleted:           false,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\n\t\t\t\t\tif layerFiles, err := imgFiles.ListLayerFiles(selectors); err != nil {\n\t\t\t\t\t\tlogger.Errorf(\"imgFiles.ListLayerFiles() error - %v\", err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor _, lf := range layerFiles {\n\t\t\t\t\t\t\tlogger.Tracef(\"layerFiles=%v/%v/%v fileCount=%v\",\n\t\t\t\t\t\t\t\tlf.Layer.Index,\n\t\t\t\t\t\t\t\tlf.Layer.Digest,\n\t\t\t\t\t\t\t\tlf.Layer.DiffID,\n\t\t\t\t\t\t\t\tlen(lf.Files))\n\t\t\t\t\t\t\tfor _, fileInfo := range lf.Files {\n\t\t\t\t\t\t\t\tlogger.Tracef(\"layerFiles.File=%v\", fileInfo.Name)\n\t\t\t\t\t\t\t\tincludeLayerPaths[fileInfo.Name] = nil\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\n\t\t\t}\n\t\t\txc.Out.Info(\"image.data.inspection.list.files.end\")\n\n\t\t\tfor k := range includeLayerPaths {\n\t\t\t\tincludePaths[k] = nil\n\t\t\t}\n\t\t}\n\t}\n\n\tloadExtraIncludePaths()\n\n\t//refresh the target refs\n\ttargetRef = imageInspector.ImageRef\n\n\t//validate links (check if target container exists, ignore&log if not)\n\tsvcLinkMap := map[string]struct{}{}\n\tfor _, linkInfo := range links {\n\t\tsvcLinkMap[linkInfo] = struct{}{}\n\t}\n\n\tselectedNetNames := map[string]compose.NetNameInfo{}\n\tif depServicesExe != nil {\n\t\txc.Out.State(\"container.dependencies.init.start\")\n\t\terr = depServicesExe.Prepare()\n\t\tif err != nil {\n\t\t\tvar svcErr *compose.ServiceError\n\t\t\tif errors.As(err, &svcErr) {\n\t\t\t\txc.Out.Info(\"compose.file.error\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"status\":       \"deps.unknown.image\",\n\t\t\t\t\t\t\"files\":        strings.Join(composeFiles, \",\"),\n\t\t\t\t\t\t\"service\":      svcErr.Service,\n\t\t\t\t\t\t\"pull.enabled\": doPull,\n\t\t\t\t\t\t\"message\":      \"Unknown dependency image (make sure to pull or build the images for your dependencies in compose)\",\n\t\t\t\t\t})\n\n\t\t\t\texitCode := command.ECTBuild | ecbComposeSvcUnknownImage\n\t\t\t\txc.Out.State(\"exited\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t\t\t})\n\n\t\t\t\txc.Exit(exitCode)\n\t\t\t}\n\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\terr = depServicesExe.Start()\n\t\tif err != nil {\n\t\t\tdepServicesExe.Stop()\n\t\t\tdepServicesExe.Cleanup()\n\t\t}\n\t\txc.FailOn(err)\n\n\t\texeCleanup := func() {\n\t\t\tif depServicesExe != nil {\n\t\t\t\txc.Out.State(\"container.dependencies.shutdown.start\")\n\t\t\t\terr = depServicesExe.Stop()\n\t\t\t\terrutil.WarnOn(err)\n\t\t\t\terr = depServicesExe.Cleanup()\n\t\t\t\terrutil.WarnOn(err)\n\t\t\t\txc.Out.State(\"container.dependencies.shutdown.done\")\n\t\t\t}\n\t\t}\n\n\t\txc.AddCleanupHandler(exeCleanup)\n\n\t\t//todo:\n\t\t//need a better way to make sure the dependencies are ready\n\t\t//monitor docker events\n\t\t//use basic application level checks (probing)\n\t\ttime.Sleep(3 * time.Second)\n\t\txc.Out.State(\"container.dependencies.init.done\")\n\n\t\t//might need more info (including alias info) when targeting compose services\n\t\tallNetNames := depServicesExe.ActiveNetworkNames()\n\n\t\tif targetComposeSvc != \"\" {\n\t\t\t//if we are targeting a compose service, and we\n\t\t\t//have explicitly selected compose networks (composeNets)\n\t\t\t//we use the selected subset of the configured networks for the target service\n\t\t\tcomposeNetsSet := map[string]struct{}{}\n\t\t\tfor _, key := range composeNets {\n\t\t\t\tcomposeNetsSet[key] = struct{}{}\n\t\t\t}\n\n\t\t\tsvcNets := depServicesExe.ActiveServiceNetworks(targetComposeSvc)\n\t\t\tfor key, netNameInfo := range svcNets {\n\t\t\t\tif len(composeNets) > 0 {\n\t\t\t\t\tif _, found := composeNetsSet[key]; !found {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tselectedNetNames[key] = netNameInfo\n\t\t\t}\n\t\t} else {\n\t\t\t//we are not targeting a compose service,\n\t\t\t//but we do want to connect to the networks in compose\n\t\t\tif len(composeNets) > 0 {\n\t\t\t\tfor _, key := range composeNets {\n\t\t\t\t\tif net, found := allNetNames[key]; found {\n\t\t\t\t\t\tselectedNetNames[key] = compose.NetNameInfo{\n\t\t\t\t\t\t\tFullName: net,\n\t\t\t\t\t\t\t//Aliases: serviceAliases, - we merge serviceAliases later\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//select/use all networks if specific networks are not selected\n\t\t\t\tfor key, fullName := range allNetNames {\n\t\t\t\t\tselectedNetNames[key] = compose.NetNameInfo{\n\t\t\t\t\t\tFullName: fullName,\n\t\t\t\t\t\t//Aliases: serviceAliases, - we merge serviceAliases later\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tlinks = []string{} //reset&reuse\n\tif targetComposeSvc != \"\" && depServicesExe != nil {\n\t\ttargetSvcInfo := depServicesExe.Service(targetComposeSvc)\n\t\t//convert service links to container links (after deps are started)\n\t\ttargetSvcLinkMap := map[string]struct{}{}\n\t\tfor _, linkInfo := range targetSvcInfo.Config.Links {\n\t\t\tvar linkTarget string\n\t\t\tvar linkName string\n\t\t\tparts := strings.Split(linkInfo, \":\")\n\t\t\tswitch len(parts) {\n\t\t\tcase 1:\n\t\t\t\tlinkTarget = parts[0]\n\t\t\t\tlinkName = parts[0]\n\t\t\tcase 2:\n\t\t\t\tlinkTarget = parts[0]\n\t\t\t\tlinkName = parts[1]\n\t\t\tdefault:\n\t\t\t\tlogger.Debugf(\"targetSvcInfo.Config.Links: malformed link - %s\", linkInfo)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlinkSvcInfo := depServicesExe.Service(linkTarget)\n\t\t\tif linkSvcInfo == nil {\n\t\t\t\tlogger.Debugf(\"targetSvcInfo.Config.Links: unknown service in link - %s\", linkInfo)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlogger.Debugf(\"targetSvcInfo.Config.Links: linkInfo=%s linkSvcInfo=%#v\", linkInfo, linkSvcInfo)\n\t\t\tif linkSvcInfo.ContainerName == \"\" {\n\t\t\t\tlogger.Debugf(\"targetSvcInfo.Config.Links: no container name - linkInfo=%s\", linkInfo)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tclink := fmt.Sprintf(\"%s:%s\", linkSvcInfo.ContainerName, linkSvcInfo.ContainerName)\n\t\t\ttargetSvcLinkMap[clink] = struct{}{}\n\t\t\tclink = fmt.Sprintf(\"%s:%s\", linkSvcInfo.ContainerName, linkName)\n\t\t\ttargetSvcLinkMap[clink] = struct{}{}\n\t\t}\n\n\t\tfor k := range targetSvcLinkMap {\n\t\t\tlinks = append(links, k)\n\t\t}\n\t}\n\n\tfor k := range svcLinkMap {\n\t\tlinks = append(links, k)\n\t}\n\n\tselectedNetworks := map[string]container.NetNameInfo{}\n\tfor key, info := range selectedNetNames {\n\t\taset := map[string]struct{}{}\n\t\tfor _, a := range info.Aliases {\n\t\t\taset[a] = struct{}{}\n\t\t}\n\n\t\t//merge serviceAliases with the main set of aliases\n\t\tfor _, a := range serviceAliases {\n\t\t\taset[a] = struct{}{}\n\t\t}\n\t\tvar alist []string\n\t\tfor a := range aset {\n\t\t\talist = append(alist, a)\n\t\t}\n\n\t\tselectedNetworks[key] = container.NetNameInfo{\n\t\t\tName:     key,\n\t\t\tFullName: info.FullName,\n\t\t\tAliases:  alist,\n\t\t}\n\t}\n\n\txc.Out.State(\"container.inspection.start\")\n\n\thasClassicLinks := true\n\tif targetComposeSvc != \"\" ||\n\t\tlen(composeNets) > 0 ||\n\t\toverrides.Network != \"\" {\n\t\thasClassicLinks = false\n\t}\n\n\tcontainerInspector, err := container.NewInspector(\n\t\txc,\n\t\tcrOpts,\n\t\tlogger,\n\t\tclient,\n\t\tstatePath,\n\t\timageInspector,\n\t\tlocalVolumePath,\n\t\tdoUseLocalMounts,\n\t\tdoUseSensorVolume,\n\t\tdoKeepTmpArtifacts,\n\t\toverrides,\n\t\texplicitVolumeMounts,\n\t\tbaseMounts,\n\t\tbaseVolumesFrom,\n\t\tportBindings,\n\t\tdoPublishExposedPorts,\n\t\thasClassicLinks,\n\t\tlinks,\n\t\tetcHostsMaps,\n\t\tdnsServers,\n\t\tdnsSearchDomains,\n\t\tdoShowContainerLogs,\n\t\tdoEnableMondel,\n\t\tdoRunTargetAsUser,\n\t\tdoKeepPerms,\n\t\tpathPerms,\n\t\texcludePatterns,\n\t\tdoExcludeVarLockFiles,\n\t\tpreservePaths,\n\t\tincludePaths,\n\t\tincludeBins,\n\t\tincludeDirBinsList,\n\t\tincludeExes,\n\t\tdoIncludeShell,\n\t\tdoIncludeWorkdir,\n\t\tdoIncludeCertAll,\n\t\tdoIncludeCertBundles,\n\t\tdoIncludeCertDirs,\n\t\tdoIncludeCertPKAll,\n\t\tdoIncludeCertPKDirs,\n\t\tdoIncludeNew,\n\t\tdoIncludeSSHClient,\n\t\tdoIncludeOSLibsNet,\n\t\tdoIncludeZoneInfo,\n\t\tselectedNetworks,\n\t\tgparams.Debug,\n\t\tgparams.LogLevel,\n\t\tgparams.LogFormat,\n\t\tgparams.InContainer,\n\t\trtaSourcePT,\n\t\tdoObfuscateMetadata,\n\t\tsensorIPCEndpoint,\n\t\tsensorIPCMode,\n\t\tprintState,\n\t\tappNodejsInspectOpts)\n\txc.FailOn(err)\n\n\tif len(containerInspector.FatContainerCmd) == 0 {\n\t\txc.Out.Info(\"target.image.error\",\n\t\t\tovars{\n\t\t\t\t\"status\":  \"no.entrypoint.cmd\",\n\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\"message\": \"no ENTRYPOINT/CMD\",\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbNoEntrypoint\n\t\txc.Out.State(\"exited\", ovars{\"exit.code\": exitCode})\n\n\t\tcmdReport.Error = \"no.entrypoint.cmd\"\n\t\txc.Exit(exitCode)\n\t}\n\n\tlogger.Info(\"starting instrumented 'fat' container...\")\n\terr = containerInspector.RunContainer()\n\tif err != nil {\n\t\tcontainerInspector.ShowContainerLogs()\n\t\tcontainerInspector.ShutdownContainer(true)\n\t\txc.FailOn(err)\n\t}\n\n\tcontainerName := containerInspector.ContainerName\n\tcontainerID := containerInspector.ContainerID\n\tinspectorCleanup := func() {\n\t\txc.Out.Info(\"container.inspector.cleanup\",\n\t\t\tovars{\n\t\t\t\t\"name\": containerName,\n\t\t\t\t\"id\":   containerID,\n\t\t\t})\n\n\t\tif containerInspector != nil {\n\t\t\txc.Out.State(\"container.target.shutdown.start\")\n\t\t\tcontainerInspector.FinishMonitoring()\n\t\t\t_ = containerInspector.ShutdownContainer(false)\n\t\t\txc.Out.State(\"container.target.shutdown.done\")\n\t\t}\n\t}\n\n\txc.AddCleanupHandler(inspectorCleanup)\n\n\txc.Out.Info(\"container\",\n\t\tovars{\n\t\t\t\"name\":             containerInspector.ContainerName,\n\t\t\t\"id\":               containerInspector.ContainerID,\n\t\t\t\"target.port.list\": containerInspector.ContainerPortList,\n\t\t\t\"target.port.info\": containerInspector.ContainerPortsInfo,\n\t\t\t\"message\":          \"YOU CAN USE THESE PORTS TO INTERACT WITH THE CONTAINER\",\n\t\t})\n\n\tlogger.Info(\"watching container monitor...\")\n\n\tmonitorContainer(\n\t\txc,\n\t\ttargetRef,\n\t\tcontinueAfter,\n\t\texecCmd,\n\t\texecFileCmd,\n\t\thttpProbeOpts,\n\t\thostExecProbes,\n\t\tdepServicesExe,\n\t\tcontainerProbeComposeSvc,\n\t\tcontainerInspector,\n\t\tclient,\n\t\tcmdReport,\n\t\tprintState)\n\n\txc.Out.State(\"container.inspection.finishing\")\n\n\tcontainerInspector.FinishMonitoring()\n\n\tlogger.Info(\"shutting down 'fat' container...\")\n\terr = containerInspector.ShutdownContainer(false)\n\terrutil.WarnOn(err)\n\n\tif depServicesExe != nil {\n\t\txc.Out.State(\"container.dependencies.shutdown.start\")\n\t\terr = depServicesExe.Stop()\n\t\terrutil.WarnOn(err)\n\t\terr = depServicesExe.Cleanup()\n\t\terrutil.WarnOn(err)\n\t\txc.Out.State(\"container.dependencies.shutdown.done\")\n\t}\n\n\txc.Out.State(\"container.inspection.artifact.processing\")\n\n\tif !containerInspector.HasCollectedData() {\n\t\timageInspector.ShowFatImageDockerInstructions()\n\t\txc.Out.Info(\"results\",\n\t\t\tovars{\n\t\t\t\t\"status\":   \"no data collected (no minified image generated)\",\n\t\t\t\t\"version\":  v.Current(),\n\t\t\t\t\"location\": fsutil.ExeDir(),\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbImageBuildError\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t})\n\n\t\tcmdReport.Error = \"no.data.collected\"\n\t\txc.Exit(exitCode)\n\t}\n\n\tlogger.Info(\"processing instrumented 'fat' container info...\")\n\terr = containerInspector.ProcessCollectedData()\n\txc.FailOn(err)\n\n\txc.Out.State(\"container.inspection.done\")\n\n\tminifiedImageName := buildOutputImage(\n\t\txc,\n\t\tcustomImageTag,\n\t\tadditionalTags,\n\t\tcbOpts,\n\t\toverrides,\n\t\timageOverrideSelectors,\n\t\tinstructions,\n\t\tdoDeleteFatImage,\n\t\tdoShowBuildLogs,\n\t\timageInspector,\n\t\tclient,\n\t\tlogger,\n\t\tcmdReport,\n\t\timageBuildEngine,\n\t\timageBuildArch)\n\n\tfinishCommand(\n\t\txc,\n\t\tminifiedImageName,\n\t\tcopyMetaArtifactsLocation,\n\t\tdoRmFileArtifacts,\n\t\tgparams.ArchiveState,\n\t\tstateKey,\n\t\timageInspector,\n\t\tclient,\n\t\tlogger,\n\t\tcmdReport,\n\t\timageBuildEngine)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n}\n\nfunc monitorContainer(\n\txc *app.ExecutionContext,\n\ttargetRef string,\n\tcontinueAfter *config.ContinueAfter,\n\texecCmd string,\n\texecFileCmd string,\n\thttpProbeOpts config.HTTPProbeOptions,\n\thostExecProbes []string,\n\tdepServicesExe *compose.Execution,\n\tcontainerProbeComposeSvc string,\n\tcontainerInspector *container.Inspector,\n\tclient *dockerapi.Client,\n\tcmdReport *report.BuildCommand,\n\tprintState bool,\n) {\n\tif hasContinueAfterMode(continueAfter.Mode, config.CAMProbe) {\n\t\thttpProbeOpts.Do = true\n\t}\n\n\tvar probe *http.CustomProbe\n\tif httpProbeOpts.Do {\n\t\tvar err error\n\t\tprobe, err = http.NewContainerProbe(xc, containerInspector, httpProbeOpts, printState)\n\t\txc.FailOn(err)\n\n\t\tif len(probe.Ports()) == 0 {\n\t\t\txc.Out.State(\"http.probe.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"error\":   \"NO EXPOSED PORTS\",\n\t\t\t\t\t\"message\": \"expose your service port with --expose or disable HTTP probing with --http-probe=false if your containerized application doesnt expose any network services\",\n\t\t\t\t})\n\n\t\t\t//note: should be handled by inspectorCleanup\n\t\t\t//logger.Info(\"shutting down 'fat' container...\")\n\t\t\t//containerInspector.FinishMonitoring()\n\t\t\t//_ = containerInspector.ShutdownContainer(false)\n\n\t\t\texitCode := command.ECTBuild | ecbImageBuildError\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t})\n\n\t\t\tcmdReport.Error = \"no.exposed.ports\"\n\t\t\txc.Exit(exitCode)\n\t\t}\n\n\t\tprobe.Start()\n\t\tcontinueAfter.ContinueChan = probe.DoneChan()\n\t}\n\n\tcontinueAfterMsg := \"provide the expected input to allow the container inspector to continue its execution\"\n\tif continueAfter.Mode == config.CAMTimeout {\n\t\tcontinueAfterMsg = \"no input required, execution will resume after the timeout\"\n\t}\n\n\tif hasContinueAfterMode(continueAfter.Mode, config.CAMProbe) {\n\t\tcontinueAfterMsg = \"no input required, execution will resume when HTTP probing is completed\"\n\t}\n\n\txc.Out.Info(\"continue.after\",\n\t\tovars{\n\t\t\t\"mode\":    continueAfter.Mode,\n\t\t\t\"message\": continueAfterMsg,\n\t\t})\n\n\texecFail := false\n\n\tmodes := command.GetContinueAfterModeNames(continueAfter.Mode)\n\tfor _, mode := range modes {\n\t\t//should work for the most parts except\n\t\t//when probe and signal are combined\n\t\t//because both need channels (TODO: fix)\n\t\tswitch mode {\n\t\tcase config.CAMContainerProbe:\n\t\t\tidsToLog := map[string]string{}\n\t\t\tidsToLog[targetRef] = containerInspector.ContainerID\n\t\t\tfor name, svc := range depServicesExe.RunningServices {\n\t\t\t\tidsToLog[name] = svc.ID\n\t\t\t}\n\t\t\t//TODO:\n\t\t\t//need a flag to control logs for dep services\n\t\t\t//also good to leverage the logging capabilities in compose (TBD)\n\t\t\tfor name, id := range idsToLog {\n\t\t\t\tname := name\n\t\t\t\tid := id\n\t\t\t\tgo func() {\n\t\t\t\t\terr := client.Logs(dockerapi.LogsOptions{\n\t\t\t\t\t\tContainer:    id,\n\t\t\t\t\t\tOutputStream: NewLogWriter(name + \"-stdout\"),\n\t\t\t\t\t\tErrorStream:  NewLogWriter(name + \"-stderr\"),\n\t\t\t\t\t\tFollow:       true,\n\t\t\t\t\t\tStdout:       true,\n\t\t\t\t\t\tStderr:       true,\n\t\t\t\t\t})\n\t\t\t\t\txc.FailOn(err)\n\t\t\t\t}()\n\t\t\t}\n\n\t\t\tsvc, ok := depServicesExe.RunningServices[containerProbeComposeSvc]\n\t\t\tif !ok {\n\t\t\t\txc.Out.State(\"error\", ovars{\"message\": \"container-prove-compose-svc not found in running services\"})\n\t\t\t\txc.Exit(1)\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tc, err := client.InspectContainerWithOptions(dockerapi.InspectContainerOptions{\n\t\t\t\t\tID: svc.ID,\n\t\t\t\t})\n\t\t\t\txc.FailOn(err)\n\t\t\t\tif c.State.Running {\n\t\t\t\t\txc.Out.Info(\"wait for container.probe to finish\")\n\t\t\t\t} else {\n\t\t\t\t\tif c.State.ExitCode != 0 {\n\t\t\t\t\t\txc.Out.State(\"exited\", ovars{\"container.probe exit.code\": c.State.ExitCode})\n\t\t\t\t\t\txc.Exit(1)\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttime.Sleep(1 * time.Second)\n\t\t\t}\n\n\t\tcase config.CAMEnter:\n\t\t\txc.Out.Prompt(\"USER INPUT REQUIRED, PRESS <ENTER> WHEN YOU ARE DONE USING THE CONTAINER\")\n\t\t\tcreader := bufio.NewReader(os.Stdin)\n\t\t\t_, _, _ = creader.ReadLine()\n\n\t\tcase config.CAMExec:\n\t\t\tvar input *bytes.Buffer\n\t\t\tvar cmd []string\n\t\t\tif len(execFileCmd) != 0 {\n\t\t\t\tinput = bytes.NewBufferString(execFileCmd)\n\t\t\t\tcmd = []string{\"sh\", \"-s\"}\n\t\t\t\tfor _, line := range strings.Split(string(execFileCmd), \"\\n\") {\n\t\t\t\t\txc.Out.Info(\"continue.after\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"mode\":  config.CAMExec,\n\t\t\t\t\t\t\t\"shell\": line,\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tinput = bytes.NewBufferString(\"\")\n\t\t\t\tcmd = []string{\"sh\", \"-c\", execCmd}\n\t\t\t\txc.Out.Info(\"continue.after\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"mode\":  config.CAMExec,\n\t\t\t\t\t\t\"shell\": execCmd,\n\t\t\t\t\t})\n\t\t\t}\n\t\t\texec, err := containerInspector.APIClient.CreateExec(dockerapi.CreateExecOptions{\n\t\t\t\tContainer:    containerInspector.ContainerID,\n\t\t\t\tCmd:          cmd,\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\txc.FailOn(err)\n\n\t\t\tbuffer := &printbuffer.PrintBuffer{Prefix: fmt.Sprintf(\"%s[%s][exec]: output:\", appName, Name)}\n\t\t\txc.FailOn(containerInspector.APIClient.StartExec(exec.ID, dockerapi.StartExecOptions{\n\t\t\t\tInputStream:  input,\n\t\t\t\tOutputStream: buffer,\n\t\t\t\tErrorStream:  buffer,\n\t\t\t}))\n\n\t\t\tinspect, err := containerInspector.APIClient.InspectExec(exec.ID)\n\t\t\txc.FailOn(err)\n\t\t\terrutil.FailWhen(inspect.Running, \"still running\")\n\t\t\tif inspect.ExitCode != 0 {\n\t\t\t\texecFail = true\n\t\t\t}\n\n\t\t\txc.Out.Info(\"continue.after\",\n\t\t\t\tovars{\n\t\t\t\t\t\"mode\":     config.CAMExec,\n\t\t\t\t\t\"exitcode\": inspect.ExitCode,\n\t\t\t\t})\n\n\t\tcase config.CAMSignal:\n\t\t\txc.Out.Prompt(\"send SIGUSR1 when you are done using the container\")\n\t\t\t<-continueAfter.ContinueChan\n\t\t\txc.Out.Info(\"event\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"got SIGUSR1\",\n\t\t\t\t})\n\n\t\tcase config.CAMTimeout:\n\t\t\txc.Out.Prompt(fmt.Sprintf(\"waiting for the target container (%v seconds)\", int(continueAfter.Timeout)))\n\t\t\t<-time.After(time.Second * continueAfter.Timeout)\n\t\t\txc.Out.Info(\"event\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"done waiting for the target container\",\n\t\t\t\t})\n\n\t\tcase config.CAMProbe:\n\t\t\txc.Out.Prompt(\"waiting for the HTTP probe to finish\")\n\t\t\t<-continueAfter.ContinueChan\n\t\t\txc.Out.Info(\"event\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"HTTP probe is done\",\n\t\t\t\t})\n\n\t\t\tif probe != nil && probe.CallCount > 0 && probe.OkCount == 0 && httpProbeOpts.ExitOnFailure {\n\t\t\t\txc.Out.Error(\"probe.error\", \"no.successful.calls\")\n\n\t\t\t\tcontainerInspector.ShowContainerLogs()\n\t\t\t\txc.Out.State(\"exited\", ovars{\"exit.code\": -1})\n\t\t\t\txc.Exit(-1)\n\t\t\t}\n\t\tcase config.CAMHostExec:\n\t\t\tcommand.RunHostExecProbes(printState, xc, hostExecProbes)\n\t\tcase config.CAMAppExit:\n\t\t\txc.Out.Prompt(\"waiting for the target app to exit\")\n\t\t\t//TBD\n\t\tdefault:\n\t\t\terrutil.Fail(\"unknown continue-after mode\")\n\t\t}\n\t}\n\n\tif execFail {\n\t\txc.Out.Info(\"continue.after\",\n\t\t\tovars{\n\t\t\t\t\"mode\":    config.CAMExec,\n\t\t\t\t\"message\": \"fatal: exec cmd failure\",\n\t\t\t})\n\n\t\texitCode := 1\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t})\n\n\t\tcmdReport.Error = \"exec.cmd.failure\"\n\t\txc.Exit(exitCode)\n\t}\n}\n\nfunc finishCommand(\n\txc *app.ExecutionContext,\n\tminifiedImageName string,\n\tcopyMetaArtifactsLocation string,\n\tdoRmFileArtifacts bool,\n\tarchiveState string,\n\tstateKey string,\n\timageInspector *image.Inspector,\n\tclient *dockerapi.Client,\n\tlogger *log.Entry,\n\tcmdReport *report.BuildCommand,\n\timageBuildEngine string,\n) {\n\tnewImageInspector, err := image.NewInspector(client, minifiedImageName)\n\txc.FailOn(err)\n\n\tnoImage, err := imageInspector.NoImage()\n\terrutil.FailOn(err)\n\tif noImage {\n\t\txc.Out.Info(\"results\",\n\t\t\tovars{\n\t\t\t\t\"message\": \"minified image not found\",\n\t\t\t\t\"image\":   minifiedImageName,\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbImageBuildError\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t})\n\n\t\tcmdReport.Error = \"minified.image.not.found\"\n\t\txc.Exit(exitCode)\n\t}\n\n\terr = newImageInspector.Inspect()\n\terrutil.WarnOn(err)\n\n\tif err == nil {\n\t\tcmdReport.MinifiedBy = float64(imageInspector.ImageInfo.VirtualSize) / float64(newImageInspector.ImageInfo.VirtualSize)\n\t\timgIdentity := dockerutil.ImageToIdentity(imageInspector.ImageInfo)\n\t\tcmdReport.SourceImage = report.ImageMetadata{\n\t\t\tIdentity: report.ImageIdentity{\n\t\t\t\tID:          imgIdentity.ID,\n\t\t\t\tTags:        imgIdentity.ShortTags,\n\t\t\t\tNames:       imgIdentity.RepoTags,\n\t\t\t\tDigests:     imgIdentity.ShortDigests,\n\t\t\t\tFullDigests: imgIdentity.RepoDigests,\n\t\t\t},\n\t\t\tSize:          imageInspector.ImageInfo.VirtualSize,\n\t\t\tSizeHuman:     humanize.Bytes(uint64(imageInspector.ImageInfo.VirtualSize)),\n\t\t\tCreateTime:    imageInspector.ImageInfo.Created.UTC().Format(time.RFC3339),\n\t\t\tAuthor:        imageInspector.ImageInfo.Author,\n\t\t\tDockerVersion: imageInspector.ImageInfo.DockerVersion,\n\t\t\tArchitecture:  imageInspector.ImageInfo.Architecture,\n\t\t\tUser:          imageInspector.ImageInfo.Config.User,\n\t\t\tOS:            imageInspector.ImageInfo.OS,\n\t\t}\n\n\t\tif cmdReport.MinifiedImageID != newImageInspector.ImageInfo.ID {\n\t\t\tlogger.Errorf(\"finishCommand: output image ID mismatch '%s' != '%s'\",\n\t\t\t\tcmdReport.MinifiedImageID, newImageInspector.ImageInfo.ID)\n\t\t}\n\n\t\tfor k := range imageInspector.ImageInfo.Config.ExposedPorts {\n\t\t\tcmdReport.SourceImage.ExposedPorts = append(cmdReport.SourceImage.ExposedPorts, string(k))\n\t\t}\n\n\t\tfor k := range imageInspector.ImageInfo.Config.Volumes {\n\t\t\tcmdReport.SourceImage.Volumes = append(cmdReport.SourceImage.Volumes, k)\n\t\t}\n\n\t\tcmdReport.SourceImage.Labels = imageInspector.ImageInfo.Config.Labels\n\t\tcmdReport.SourceImage.EnvVars = imageInspector.ImageInfo.Config.Env\n\n\t\tcmdReport.MinifiedImageSize = newImageInspector.ImageInfo.VirtualSize\n\t\tcmdReport.MinifiedImageSizeHuman = humanize.Bytes(uint64(newImageInspector.ImageInfo.VirtualSize))\n\n\t\txc.Out.Info(\"results\",\n\t\t\tovars{\n\t\t\t\t\"status\":         \"MINIFIED\",\n\t\t\t\t\"by\":             fmt.Sprintf(\"%.2fX\", cmdReport.MinifiedBy),\n\t\t\t\t\"size.original\":  cmdReport.SourceImage.SizeHuman,\n\t\t\t\t\"size.optimized\": cmdReport.MinifiedImageSizeHuman,\n\t\t\t})\n\t} else {\n\t\tcmdReport.State = cmd.StateError\n\t\tcmdReport.Error = err.Error()\n\t}\n\n\tcmdReport.ArtifactLocation = imageInspector.ArtifactLocation\n\tcmdReport.ContainerReportName = report.DefaultContainerReportFileName\n\tcmdReport.SeccompProfileName = imageInspector.SeccompProfileName\n\tcmdReport.AppArmorProfileName = imageInspector.AppArmorProfileName\n\n\t//todo:\n\t//need to enhance the 'docker' image builder to provide\n\t//the output image metadata (until then we have this quick 'fix')\n\tif cmdReport.MinifiedImageID == \"\" {\n\t\tcmdReport.MinifiedImageID = newImageInspector.ImageInfo.ID\n\t\t//also need the digest...\n\t}\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"image-build-engine\": imageBuildEngine,\n\t\t\t\"image.name\":         cmdReport.MinifiedImage,\n\t\t\t\"image.size\":         cmdReport.MinifiedImageSizeHuman,\n\t\t\t\"image.id\":           cmdReport.MinifiedImageID,\n\t\t\t\"image.digest\":       cmdReport.MinifiedImageDigest,\n\t\t\t\"has.data\":           cmdReport.MinifiedImageHasData,\n\t\t})\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.location\": cmdReport.ArtifactLocation,\n\t\t})\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.report\": cmdReport.ContainerReportName,\n\t\t})\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.dockerfile.reversed\": consts.ReversedDockerfile,\n\t\t})\n\n\tif imageBuildEngine == IBEDocker ||\n\t\timageBuildEngine == IBEBuildKit {\n\t\t//no minified Dockerfile when using IBEInternal (or IBENone)\n\t\txc.Out.Info(\"results\",\n\t\t\tovars{\n\t\t\t\t\"artifacts.dockerfile.minified\": \"Dockerfile\",\n\t\t\t})\n\t}\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.seccomp\": cmdReport.SeccompProfileName,\n\t\t})\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.apparmor\": cmdReport.AppArmorProfileName,\n\t\t})\n\n\tif cmdReport.ArtifactLocation != \"\" {\n\t\tcreportPath := filepath.Join(cmdReport.ArtifactLocation, cmdReport.ContainerReportName)\n\t\tif creportData, err := os.ReadFile(creportPath); err == nil {\n\t\t\tvar creport report.ContainerReport\n\t\t\tif err := json.Unmarshal(creportData, &creport); err == nil {\n\t\t\t\tcmdReport.System = report.SystemMetadata{\n\t\t\t\t\tType:    creport.System.Type,\n\t\t\t\t\tRelease: creport.System.Release,\n\t\t\t\t\tDistro:  creport.System.Distro,\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlogger.Infof(\"could not read container report - json parsing error - %v\", err)\n\t\t\t}\n\t\t} else {\n\t\t\tlogger.Infof(\"could not read container report - %v\", err)\n\t\t}\n\t}\n\n\t/////////////////////////////\n\tif copyMetaArtifactsLocation != \"\" {\n\t\ttoCopy := []string{\n\t\t\treport.DefaultContainerReportFileName,\n\t\t\timageInspector.SeccompProfileName,\n\t\t\timageInspector.AppArmorProfileName,\n\t\t}\n\t\tif !command.CopyMetaArtifacts(logger,\n\t\t\ttoCopy,\n\t\t\timageInspector.ArtifactLocation, copyMetaArtifactsLocation) {\n\t\t\txc.Out.Info(\"artifacts\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"could not copy meta artifacts\",\n\t\t\t\t})\n\t\t}\n\t}\n\n\tif err := command.DoArchiveState(logger, client, imageInspector.ArtifactLocation, archiveState, stateKey); err != nil {\n\t\txc.Out.Info(\"state\",\n\t\t\tovars{\n\t\t\t\t\"message\": \"could not archive state\",\n\t\t\t})\n\n\t\tlogger.Errorf(\"error archiving state - %v\", err)\n\t}\n\n\tif doRmFileArtifacts {\n\t\tlogger.Info(\"removing temporary artifacts...\")\n\t\terr = fsutil.Remove(imageInspector.ArtifactLocation)\n\t\terrutil.WarnOn(err)\n\t}\n\n\txc.Out.State(\"done\")\n\n\txc.Out.Info(\"commands\",\n\t\tovars{\n\t\t\t\"message\": \"use the xray command to learn more about the optimize image\",\n\t\t})\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\nfunc hasContinueAfterMode(modeSet, mode string) bool {\n\tfor _, current := range strings.Split(modeSet, \"&\") {\n\t\tif current == mode {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc NewLogWriter(name string) *chanWriter {\n\tr, w := io.Pipe()\n\tcw := &chanWriter{\n\t\tName: name,\n\t\tr:    r,\n\t\tw:    w,\n\t}\n\tgo func() {\n\t\ts := bufio.NewScanner(cw.r)\n\t\tfor s.Scan() {\n\t\t\tfmt.Println(name + \": \" + string(s.Bytes()))\n\t\t}\n\t}()\n\treturn cw\n}\n\ntype chanWriter struct {\n\tName string\n\tChan chan string\n\tw    *io.PipeWriter\n\tr    *io.PipeReader\n}\n\nfunc (w *chanWriter) Write(p []byte) (n int, err error) {\n\treturn w.w.Write(p)\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/image.go",
    "content": "package build\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dustin/go-humanize\"\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/builder\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n\t\"github.com/slimtoolkit/slim/pkg/imagebuilder\"\n\t\"github.com/slimtoolkit/slim/pkg/imagebuilder/internalbuilder\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nfunc inspectFatImage(\n\txc *app.ExecutionContext,\n\ttargetRef string,\n\tdoPull bool,\n\tdoShowPullLogs bool,\n\trtaOnbuildBaseImage bool,\n\tdockerConfigPath string,\n\tregistryAccount string,\n\tregistrySecret string,\n\tparamsStatePath string,\n\tclient *dockerapi.Client,\n\tlogger *log.Entry,\n\tcmdReport *report.BuildCommand,\n) (*image.Inspector, string, string, string) {\n\timageInspector, err := image.NewInspector(client, targetRef)\n\txc.FailOn(err)\n\n\tnoImage, err := imageInspector.NoImage()\n\terrutil.FailOn(err)\n\tif noImage {\n\t\tif doPull {\n\t\t\txc.Out.Info(\"target.image\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"image.not.found\",\n\t\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\t\"message\": \"trying to pull target image\",\n\t\t\t\t})\n\n\t\t\terr := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret)\n\t\t\txc.FailOn(err)\n\t\t} else {\n\t\t\txc.Out.Info(\"target.image.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"image.not.found\",\n\t\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\t\"message\": \"make sure the target image already exists locally (use --pull flag to auto-download it from registry)\",\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTCommon | command.ECCImageNotFound\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t})\n\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t}\n\n\tlogger.Tracef(\"targetRef=%s ii.ImageRef=%s\", targetRef, imageInspector.ImageRef)\n\tcmdReport.TargetReference = imageInspector.ImageRef\n\n\txc.Out.State(\"image.inspection.start\")\n\n\tlogger.Info(\"inspecting 'fat' image metadata...\")\n\terr = imageInspector.Inspect()\n\txc.FailOn(err)\n\n\tlocalVolumePath, artifactLocation, statePath, stateKey := fsutil.PrepareImageStateDirs(paramsStatePath, imageInspector.ImageInfo.ID)\n\timageInspector.ArtifactLocation = artifactLocation\n\tlogger.Debugf(\"localVolumePath=%v, artifactLocation=%v, statePath=%v, stateKey=%v\", localVolumePath, artifactLocation, statePath, stateKey)\n\n\txc.Out.Info(\"image\",\n\t\tovars{\n\t\t\t\"id\":         imageInspector.ImageInfo.ID,\n\t\t\t\"size.bytes\": imageInspector.ImageInfo.VirtualSize,\n\t\t\t\"size.human\": humanize.Bytes(uint64(imageInspector.ImageInfo.VirtualSize)),\n\t\t})\n\n\tif imageInspector.ImageInfo.Config != nil &&\n\t\tlen(imageInspector.ImageInfo.Config.Labels) > 0 {\n\t\tfor labelName := range imageInspector.ImageInfo.Config.Labels {\n\t\t\tif labelName == consts.DSLabelVersion {\n\t\t\t\txc.Out.Info(\"target.image.error\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"status\":  \"image.already.optimized\",\n\t\t\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\t\t\"message\": \"the target image is already optimized\",\n\t\t\t\t\t})\n\n\t\t\t\texitCode := command.ECTBuild | ecbImageAlreadyOptimized\n\t\t\t\txc.Out.State(\"exited\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t})\n\n\t\t\t\tcmdReport.Error = \"image.already.optimized\"\n\t\t\t\txc.Exit(exitCode)\n\t\t\t}\n\t\t}\n\t}\n\n\tlogger.Info(\"processing 'fat' image info...\")\n\terr = imageInspector.ProcessCollectedData()\n\txc.FailOn(err)\n\n\tif imageInspector.DockerfileInfo != nil {\n\t\tif imageInspector.DockerfileInfo.ExeUser != \"\" {\n\t\t\txc.Out.Info(\"image.users\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exe\": imageInspector.DockerfileInfo.ExeUser,\n\t\t\t\t\t\"all\": strings.Join(imageInspector.DockerfileInfo.AllUsers, \",\"),\n\t\t\t\t})\n\t\t}\n\n\t\tif len(imageInspector.DockerfileInfo.ImageStack) > 0 {\n\t\t\tcmdReport.ImageStack = imageInspector.DockerfileInfo.ImageStack\n\n\t\t\tfor idx, layerInfo := range imageInspector.DockerfileInfo.ImageStack {\n\t\t\t\txc.Out.Info(\"image.stack\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"index\": idx,\n\t\t\t\t\t\t\"name\":  layerInfo.FullName,\n\t\t\t\t\t\t\"id\":    layerInfo.ID,\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif len(imageInspector.DockerfileInfo.ExposedPorts) > 0 {\n\t\t\txc.Out.Info(\"image.exposed_ports\",\n\t\t\t\tovars{\n\t\t\t\t\t\"list\": strings.Join(imageInspector.DockerfileInfo.ExposedPorts, \",\"),\n\t\t\t\t})\n\t\t}\n\n\t\tif !rtaOnbuildBaseImage && imageInspector.DockerfileInfo.HasOnbuild {\n\t\t\txc.Out.Info(\"target.image.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"onbuild.base.image\",\n\t\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\t\"message\": \"Runtime analysis for onbuild base images is not supported\",\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTBuild | ecbOnbuildBaseImage\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t})\n\n\t\t\tcmdReport.Error = \"onbuild.base.image\"\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t}\n\n\txc.Out.State(\"image.inspection.done\")\n\treturn imageInspector, localVolumePath, statePath, stateKey\n}\n\nfunc buildFatImage(\n\txc *app.ExecutionContext,\n\ttargetRef string,\n\tcustomImageTag string,\n\tcbOpts *config.ContainerBuildOptions,\n\tdoShowBuildLogs bool,\n\tclient *dockerapi.Client,\n\tcmdReport *report.BuildCommand,\n) (fatImageRepoNameTag string) {\n\txc.Out.State(\"building\",\n\t\tovars{\n\t\t\t\"message\": \"building basic image\",\n\t\t})\n\n\t//create a fat image name:\n\t//* use the explicit fat image tag if provided\n\t//* or create one based on the user provided (slim image) custom tag if it's available\n\t//* otherwise auto-generate a name\n\tif cbOpts.Tag != \"\" {\n\t\tfatImageRepoNameTag = cbOpts.Tag\n\t} else if customImageTag != \"\" {\n\t\tcitParts := strings.Split(customImageTag, \":\")\n\t\tswitch len(citParts) {\n\t\tcase 1:\n\t\t\tfatImageRepoNameTag = fmt.Sprintf(\"%s.fat\", customImageTag)\n\t\tcase 2:\n\t\t\tfatImageRepoNameTag = fmt.Sprintf(\"%s.fat:%s\", citParts[0], citParts[1])\n\t\tdefault:\n\t\t\txc.Out.Info(\"param.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\": \"malformed.custom.image.tag\",\n\t\t\t\t\t\"value\":  customImageTag,\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTBuild | ecbBadCustomImageTag\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t\t})\n\n\t\t\tcmdReport.Error = \"malformed.custom.image.tag\"\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t} else {\n\t\tfatImageRepoNameTag = fmt.Sprintf(\"slim-tmp-fat-image.%v.%v\",\n\t\t\tos.Getpid(), time.Now().UTC().Format(\"20060102150405\"))\n\t}\n\n\tcbOpts.Tag = fatImageRepoNameTag\n\n\txc.Out.Info(\"basic.image.info\",\n\t\tovars{\n\t\t\t\"tag\":        cbOpts.Tag,\n\t\t\t\"dockerfile\": cbOpts.Dockerfile,\n\t\t\t\"context\":    targetRef,\n\t\t})\n\n\tfatBuilder, err := builder.NewBasicImageBuilder(\n\t\tclient,\n\t\tcbOpts,\n\t\ttargetRef,\n\t\tdoShowBuildLogs)\n\txc.FailOn(err)\n\n\terr = fatBuilder.Build()\n\n\tif doShowBuildLogs || err != nil {\n\t\txc.Out.LogDump(\"regular.image.build\", fatBuilder.BuildLog.String(),\n\t\t\tovars{\n\t\t\t\t\"tag\": cbOpts.Tag,\n\t\t\t})\n\t}\n\n\tif err != nil {\n\t\txc.Out.Info(\"build.error\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"standard.image.build.error\",\n\t\t\t\t\"value\":  err,\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbImageBuildError\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\n\t\txc.Exit(exitCode)\n\t}\n\n\txc.Out.State(\"basic.image.build.completed\")\n\n\treturn fatImageRepoNameTag\n}\n\nfunc buildOutputImage(\n\txc *app.ExecutionContext,\n\tcustomImageTag string,\n\tadditionalTags []string,\n\tcbOpts *config.ContainerBuildOptions,\n\toverrides *config.ContainerOverrides,\n\timageOverrideSelectors map[string]bool,\n\tinstructions *config.ImageNewInstructions,\n\tdoDeleteFatImage bool,\n\tdoShowBuildLogs bool,\n\timageInspector *image.Inspector,\n\tclient *dockerapi.Client,\n\tlogger *log.Entry,\n\tcmdReport *report.BuildCommand,\n\timageBuildEngine string,\n\timageBuildArch string,\n) string {\n\tonError := func(e error) {\n\t\txc.Out.Info(\"build.error\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"optimized.image.build.error\",\n\t\t\t\t\"error\":  e,\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbImageBuildError\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\n\t\tcmdReport.Error = \"optimized.image.build.error\"\n\t\txc.Exit(exitCode)\n\t}\n\n\tif customImageTag == \"\" {\n\t\tcustomImageTag = imageInspector.SlimImageRepo\n\t}\n\n\tcmdReport.ImageBuildEngine = imageBuildEngine\n\n\tlogger.Debugf(\"image build engine - %v\", imageBuildEngine)\n\txc.Out.State(\"building\",\n\t\tovars{\n\t\t\t\"message\": \"building optimized image\",\n\t\t\t\"engine\":  imageBuildEngine,\n\t\t})\n\n\tvar outputImageName string\n\tvar hasData bool\n\tvar imageCreated bool\n\tswitch imageBuildEngine {\n\tcase IBENone:\n\tcase IBEInternal:\n\t\tengine, err := internalbuilder.New(doShowBuildLogs,\n\t\t\ttrue, //pushToDaemon - TODO: have a param to control this &\n\t\t\t//output image tar (if not 'saving' to daemon)\n\t\t\tfalse)\n\t\txc.FailOn(err)\n\n\t\topts := imagebuilder.SimpleBuildOptions{\n\t\t\tImageConfig: imagebuilder.ImageConfig{\n\t\t\t\tArchitecture: imageBuildArch,\n\t\t\t\tConfig: imagebuilder.RunConfig{\n\t\t\t\t\tExposedPorts: map[string]struct{}{},\n\t\t\t\t\tVolumes:      map[string]struct{}{},\n\t\t\t\t\tLabels:       map[string]string{},\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tif customImageTag != \"\" {\n\t\t\t//must be first\n\t\t\topts.Tags = append(opts.Tags, customImageTag)\n\t\t}\n\n\t\tif len(additionalTags) > 0 {\n\t\t\topts.Tags = append(opts.Tags, additionalTags...)\n\t\t}\n\n\t\tUpdateBuildOptionsWithSrcImageInfo(&opts, imageInspector.ImageInfo)\n\t\tUpdateBuildOptionsWithOverrides(&opts, imageOverrideSelectors, overrides)\n\n\t\tif imageInspector.ImageRef != \"\" {\n\t\t\topts.ImageConfig.Config.Labels[consts.DSLabelSourceImage] = imageInspector.ImageRef\n\t\t}\n\n\t\tvar sourceImageID string\n\t\tif imageInspector.ImageInfo != nil &&\n\t\t\timageInspector.ImageInfo.ID != \"\" {\n\t\t\tsourceImageID = imageInspector.ImageInfo.ID\n\t\t}\n\n\t\tif sourceImageID == \"\" &&\n\t\t\timageInspector.ImageRecordInfo.ID != \"\" {\n\t\t\tsourceImageID = imageInspector.ImageRecordInfo.ID\n\t\t}\n\n\t\tif sourceImageID != \"\" {\n\t\t\topts.ImageConfig.Config.Labels[consts.DSLabelSourceImageID] = sourceImageID\n\t\t}\n\n\t\topts.ImageConfig.Config.Labels[consts.DSLabelVersion] = v.Current()\n\n\t\t//(new) instructions have higher value precedence over the runtime overrides\n\t\tUpdateBuildOptionsWithNewInstructions(&opts, instructions)\n\n\t\tdataTar := filepath.Join(imageInspector.ArtifactLocation, \"files.tar\")\n\t\tif fsutil.Exists(dataTar) &&\n\t\t\tfsutil.IsRegularFile(dataTar) &&\n\t\t\tfsutil.IsTarFile(dataTar) {\n\t\t\tlayerInfo := imagebuilder.LayerDataInfo{\n\t\t\t\tType:   imagebuilder.TarSource,\n\t\t\t\tSource: dataTar,\n\t\t\t\tParams: &imagebuilder.DataParams{\n\t\t\t\t\tTargetPath: \"/\",\n\t\t\t\t},\n\t\t\t}\n\n\t\t\topts.Layers = append(opts.Layers, layerInfo)\n\t\t\thasData = true\n\t\t} else {\n\t\t\tdataDir := filepath.Join(imageInspector.ArtifactLocation, \"files\")\n\t\t\tif fsutil.Exists(dataTar) && fsutil.IsDir(dataDir) {\n\t\t\t\tlayerInfo := imagebuilder.LayerDataInfo{\n\t\t\t\t\tType:   imagebuilder.DirSource,\n\t\t\t\t\tSource: dataDir,\n\t\t\t\t\tParams: &imagebuilder.DataParams{\n\t\t\t\t\t\tTargetPath: \"/\",\n\t\t\t\t\t},\n\t\t\t\t}\n\n\t\t\t\topts.Layers = append(opts.Layers, layerInfo)\n\t\t\t\thasData = true\n\t\t\t} else {\n\t\t\t\tlogger.Info(\"WARNING - no data artifacts\")\n\t\t\t}\n\t\t}\n\n\t\timageResult, err := engine.Build(opts)\n\t\tif err != nil {\n\t\t\tonError(err)\n\t\t}\n\n\t\toutputImageName = imageResult.Name // customImageTag // engine.RepoName\n\t\tcmdReport.MinifiedImageID = imageResult.ID\n\t\tcmdReport.MinifiedImageDigest = imageResult.Digest\n\t\timageCreated = true\n\tcase IBEBuildKit:\n\tcase IBEDocker:\n\t\tengine, err := builder.NewImageBuilder(\n\t\t\tclient,\n\t\t\tcustomImageTag,\n\t\t\tadditionalTags,\n\t\t\timageInspector.ImageInfo,\n\t\t\timageInspector.ArtifactLocation,\n\t\t\tdoShowBuildLogs,\n\t\t\timageOverrideSelectors,\n\t\t\toverrides,\n\t\t\tinstructions,\n\t\t\timageInspector.ImageRef)\n\t\txc.FailOn(err)\n\n\t\tif !engine.HasData {\n\t\t\tlogger.Info(\"WARNING - no data artifacts\")\n\t\t}\n\n\t\terr = engine.Build()\n\t\tif doShowBuildLogs || err != nil {\n\t\t\txc.Out.LogDump(\"optimized.image.build\", engine.BuildLog.String(),\n\t\t\t\tovars{\n\t\t\t\t\t\"tag\": customImageTag,\n\t\t\t\t})\n\t\t}\n\n\t\tif err != nil {\n\t\t\tonError(err)\n\t\t}\n\n\t\tif cbOpts.Dockerfile != \"\" {\n\t\t\tif doDeleteFatImage {\n\t\t\t\txc.Out.Info(\"Dockerfile\", ovars{\n\t\t\t\t\t\"image.name\":        cbOpts.Tag,\n\t\t\t\t\t\"image.fat.deleted\": \"true\",\n\t\t\t\t})\n\t\t\t\tvar err = client.RemoveImage(cbOpts.Tag)\n\t\t\t\terrutil.WarnOn(err)\n\t\t\t} else {\n\t\t\t\txc.Out.Info(\"Dockerfile\", ovars{\n\t\t\t\t\t\"image.name\":        cbOpts.Tag,\n\t\t\t\t\t\"image.fat.deleted\": \"false\",\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\toutputImageName = engine.RepoName\n\t\thasData = engine.HasData\n\t\timageCreated = true\n\tdefault:\n\t\tlogger.Errorf(\"bad image build engine - %v\", imageBuildEngine)\n\t\tonError(fmt.Errorf(\"bad image build engine - %v\", imageBuildEngine))\n\t}\n\n\tcmdReport.State = cmd.StateCompleted\n\tcmdReport.ImageCreated = imageCreated\n\tcmdReport.MinifiedImage = outputImageName\n\tcmdReport.MinifiedImageHasData = hasData\n\n\txc.Out.State(\"completed\")\n\n\treturn outputImageName\n}\n\n// NOTE: lots of C&P from image_builder (TODO: refactor)\nconst (\n\tdsCmdPortInfo = \"65501/tcp\"\n\tdsEvtPortInfo = \"65502/tcp\"\n)\n\nfunc UpdateBuildOptionsWithNewInstructions(\n\toptions *imagebuilder.SimpleBuildOptions,\n\tinstructions *config.ImageNewInstructions) {\n\tif instructions != nil {\n\t\tlog.Debugf(\"NewImageBuilder: Using new image instructions => %+v\", instructions)\n\n\t\tif instructions.Workdir != \"\" {\n\t\t\toptions.ImageConfig.Config.WorkingDir = instructions.Workdir\n\t\t}\n\n\t\tif len(instructions.Env) > 0 {\n\t\t\toptions.ImageConfig.Config.Env = append(options.ImageConfig.Config.Env, instructions.Env...)\n\t\t}\n\n\t\tfor k, v := range instructions.ExposedPorts {\n\t\t\toptions.ImageConfig.Config.ExposedPorts[string(k)] = v\n\t\t}\n\n\t\tfor k, v := range instructions.Volumes {\n\t\t\toptions.ImageConfig.Config.Volumes[k] = v\n\t\t}\n\n\t\tfor k, v := range instructions.Labels {\n\t\t\toptions.ImageConfig.Config.Labels[k] = v\n\t\t}\n\n\t\tif len(instructions.Entrypoint) > 0 {\n\t\t\toptions.ImageConfig.Config.Entrypoint = instructions.Entrypoint\n\t\t}\n\n\t\tif len(instructions.Cmd) > 0 {\n\t\t\toptions.ImageConfig.Config.Cmd = instructions.Cmd\n\t\t}\n\n\t\tif len(options.ImageConfig.Config.ExposedPorts) > 0 &&\n\t\t\tlen(instructions.RemoveExposedPorts) > 0 {\n\t\t\tfor k := range instructions.RemoveExposedPorts {\n\t\t\t\tif _, ok := options.ImageConfig.Config.ExposedPorts[string(k)]; ok {\n\t\t\t\t\tdelete(options.ImageConfig.Config.ExposedPorts, string(k))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(options.ImageConfig.Config.Volumes) > 0 &&\n\t\t\tlen(instructions.RemoveVolumes) > 0 {\n\t\t\tfor k := range instructions.RemoveVolumes {\n\t\t\t\tif _, ok := options.ImageConfig.Config.Volumes[k]; ok {\n\t\t\t\t\tdelete(options.ImageConfig.Config.Volumes, k)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(options.ImageConfig.Config.Labels) > 0 &&\n\t\t\tlen(instructions.RemoveLabels) > 0 {\n\t\t\tfor k := range instructions.RemoveLabels {\n\t\t\t\tif _, ok := options.ImageConfig.Config.Labels[k]; ok {\n\t\t\t\t\tdelete(options.ImageConfig.Config.Labels, k)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(instructions.RemoveEnvs) > 0 &&\n\t\t\tlen(options.ImageConfig.Config.Env) > 0 {\n\t\t\tvar newEnv []string\n\t\t\tfor _, envPair := range options.ImageConfig.Config.Env {\n\t\t\t\tenvParts := strings.SplitN(envPair, \"=\", 2)\n\t\t\t\tif len(envParts) > 0 && envParts[0] != \"\" {\n\t\t\t\t\tif _, ok := instructions.RemoveEnvs[envParts[0]]; !ok {\n\t\t\t\t\t\tnewEnv = append(newEnv, envPair)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\toptions.ImageConfig.Config.Env = newEnv\n\t\t}\n\t}\n}\n\nfunc UpdateBuildOptionsWithOverrides(\n\toptions *imagebuilder.SimpleBuildOptions,\n\toverrideSelectors map[string]bool,\n\toverrides *config.ContainerOverrides) {\n\tif overrides != nil && len(overrideSelectors) > 0 {\n\t\tlog.Debugf(\"UpdateBuildOptionsWithOverrides: Using container runtime overrides => %+v\", overrideSelectors)\n\t\tfor k := range overrideSelectors {\n\t\t\tswitch k {\n\t\t\tcase \"entrypoint\":\n\t\t\t\tif len(overrides.Entrypoint) > 0 {\n\t\t\t\t\toptions.ImageConfig.Config.Entrypoint = overrides.Entrypoint\n\t\t\t\t}\n\t\t\tcase \"cmd\":\n\t\t\t\tif len(overrides.Cmd) > 0 {\n\t\t\t\t\toptions.ImageConfig.Config.Cmd = overrides.Cmd\n\t\t\t\t}\n\t\t\tcase \"workdir\":\n\t\t\t\tif overrides.Workdir != \"\" {\n\t\t\t\t\toptions.ImageConfig.Config.WorkingDir = overrides.Workdir\n\t\t\t\t}\n\t\t\tcase \"env\":\n\t\t\t\tif len(overrides.Env) > 0 {\n\t\t\t\t\toptions.ImageConfig.Config.Env = append(options.ImageConfig.Config.Env, overrides.Env...)\n\t\t\t\t}\n\t\t\tcase \"label\":\n\t\t\t\tfor k, v := range overrides.Labels {\n\t\t\t\t\toptions.ImageConfig.Config.Labels[k] = v\n\t\t\t\t}\n\t\t\tcase \"volume\":\n\t\t\t\tfor k, v := range overrides.Volumes {\n\t\t\t\t\toptions.ImageConfig.Config.Volumes[k] = v\n\t\t\t\t}\n\t\t\tcase \"expose\":\n\t\t\t\tdsCmdPort := dockerapi.Port(dsCmdPortInfo)\n\t\t\t\tdsEvtPort := dockerapi.Port(dsEvtPortInfo)\n\n\t\t\t\tfor k, v := range overrides.ExposedPorts {\n\t\t\t\t\tif k == dsCmdPort || k == dsEvtPort {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\toptions.ImageConfig.Config.ExposedPorts[string(k)] = v\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc UpdateBuildOptionsWithSrcImageInfo(\n\toptions *imagebuilder.SimpleBuildOptions,\n\timageInfo *dockerapi.Image) {\n\tlabels := SourceToOutputImageLabels(imageInfo.Config.Labels)\n\tfor k, v := range labels {\n\t\toptions.ImageConfig.Config.Labels[k] = v\n\t}\n\n\t//note: not passing imageInfo.OS explicitly\n\t//because it gets \"hardcoded\" to \"linux\" internally\n\t//(other OS types are not supported)\n\tif options.ImageConfig.Architecture == \"\" {\n\t\toptions.ImageConfig.Architecture = imageInfo.Architecture\n\t}\n\n\toptions.ImageConfig.Config.User = imageInfo.Config.User\n\toptions.ImageConfig.Config.Entrypoint = imageInfo.Config.Entrypoint\n\toptions.ImageConfig.Config.Cmd = imageInfo.Config.Cmd\n\toptions.ImageConfig.Config.WorkingDir = imageInfo.Config.WorkingDir\n\toptions.ImageConfig.Config.Env = imageInfo.Config.Env\n\toptions.ImageConfig.Config.Volumes = imageInfo.Config.Volumes\n\toptions.ImageConfig.Config.OnBuild = imageInfo.Config.OnBuild\n\toptions.ImageConfig.Config.StopSignal = imageInfo.Config.StopSignal\n\n\tfor k, v := range imageInfo.Config.ExposedPorts {\n\t\toptions.ImageConfig.Config.ExposedPorts[string(k)] = v\n\t}\n\n\tif options.ImageConfig.Config.ExposedPorts == nil {\n\t\toptions.ImageConfig.Config.ExposedPorts = map[string]struct{}{}\n\t}\n\n\tif options.ImageConfig.Config.Volumes == nil {\n\t\toptions.ImageConfig.Config.Volumes = map[string]struct{}{}\n\t}\n\n\tif options.ImageConfig.Config.Labels == nil {\n\t\toptions.ImageConfig.Config.Labels = map[string]string{}\n\t}\n}\n\nfunc SourceToOutputImageLabels(srcLabels map[string]string) map[string]string {\n\tlabels := map[string]string{}\n\tif srcLabels != nil {\n\t\t//cleanup non-standard labels from buildpacks\n\t\tfor k, v := range srcLabels {\n\t\t\tlineLen := len(k) + len(v) + 7\n\t\t\tif lineLen > 65535 {\n\t\t\t\t//TODO: improve JSON data splitting\n\t\t\t\tvalueLen := len(v)\n\t\t\t\tparts := valueLen / 50000\n\t\t\t\tparts++\n\t\t\t\toffset := 0\n\t\t\t\tfor i := 0; i < parts && offset < valueLen; i++ {\n\t\t\t\t\tchunkSize := 50000\n\t\t\t\t\tif (offset + chunkSize) > valueLen {\n\t\t\t\t\t\tchunkSize = valueLen - offset\n\t\t\t\t\t}\n\t\t\t\t\tvalue := v[offset:(offset + chunkSize)]\n\t\t\t\t\toffset += chunkSize\n\t\t\t\t\tkey := fmt.Sprintf(\"%s.%d\", k, i)\n\t\t\t\t\tlabels[key] = value\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlabels[k] = v\n\t\t\t}\n\t\t}\n\t}\n\n\treturn labels\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/build\"\n)\n\nfunc init() {\n\tbuild.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/kubernetes.go",
    "content": "package build\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/pod\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/kubernetes\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/probe/http\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"k8s.io/cli-runtime/pkg/resource\"\n)\n\ntype kubeHandler struct {\n\t*app.ExecutionContext\n\tctx    context.Context\n\treport *report.BuildCommand\n\tlogger *log.Entry\n\n\tdockerClient *dockerapi.Client\n\tkubeClient   *kubernetes.Client\n\tkubectl      kubernetes.Kubectl\n\n\tfinder *kubernetes.WorkloadFinder\n}\n\nfunc newKubeHandler(\n\txc *app.ExecutionContext,\n\tctx context.Context,\n\tcmdReport *report.BuildCommand,\n\tlogger *log.Entry,\n\tdockerClient *dockerapi.Client,\n\tkubeClient *kubernetes.Client,\n\tkubectl kubernetes.Kubectl,\n\tfinder *kubernetes.WorkloadFinder,\n) *kubeHandler {\n\treturn &kubeHandler{\n\t\tctx:              ctx,\n\t\tExecutionContext: xc,\n\t\treport:           cmdReport,\n\t\tlogger:           logger,\n\n\t\tdockerClient: dockerClient,\n\t\tkubeClient:   kubeClient,\n\t\tkubectl:      kubectl,\n\n\t\tfinder: finder,\n\t}\n}\n\ntype kubeHandleOptions struct {\n\tDoPull                    bool\n\tDoShowPullLogs            bool\n\tDoShowBuildLogs           bool\n\tDoShowContainerLogs       bool\n\tDoEnableMondel            bool\n\tDoDeleteFatImage          bool\n\tDoRmFileArtifacts         bool\n\tRtaOnbuildBaseImage       bool\n\tRtaSourcePT               bool\n\tDockerConfigPath          string\n\tRegistryAccount           string\n\tRegistrySecret            string\n\tKeepPerms                 bool\n\tPathPerms                 map[string]*fsutil.AccessInfo\n\tArchiveState              string\n\tStatePath                 string\n\tCopyMetaArtifactsLocation string\n\tDebug                     bool\n\tLogLevel                  string\n\tLogFormat                 string\n\tSensorIPCEndpoint         string\n\tCBOpts                    *config.ContainerBuildOptions\n\n\tCustomImageTag string\n\tAdditionalTags []string\n\n\tPortBindings          map[dockerapi.Port][]dockerapi.PortBinding\n\tDoPublishExposedPorts bool\n\n\thttpProbeOpts    config.HTTPProbeOptions\n\tcontinueAfter    *config.ContinueAfter\n\texecCmd          string\n\timageBuildEngine string\n\timageBuildArch   string\n}\n\nfunc (h *kubeHandler) Handle(\n\ttarget config.KubernetesTarget,\n\ttargetOverride config.KubernetesTargetOverride,\n\tmanifests *kubernetes.Manifests,\n\topts kubeHandleOptions,\n) {\n\t// 1. Pre-process the workload\n\t//    - find the running workload in the cluster\n\t//    - ...or in the supplied manifest\n\tworkload := h.findWorkloadOrFail(target)\n\n\tif manifests != nil {\n\t\th.applyManifestsOrFail(manifests, workload)\n\t}\n\n\t// 2. Inspect the workload's original image.\n\tif targetOverride.Image != \"\" {\n\t\tworkload.TargetContainer().Image = command.UpdateImageRef(\n\t\t\th.logger,\n\t\t\tworkload.TargetContainer().Image,\n\t\t\ttargetOverride.Image)\n\t}\n\n\timageInspector, _, statePath, stateKey := inspectFatImage(\n\t\th.ExecutionContext,\n\t\tworkload.TargetContainer().Image,\n\t\topts.DoPull,\n\t\topts.DoShowPullLogs,\n\t\topts.RtaOnbuildBaseImage,\n\t\topts.DockerConfigPath,\n\t\topts.RegistryAccount,\n\t\topts.RegistrySecret,\n\t\topts.StatePath,\n\t\th.dockerClient,\n\t\th.logger,\n\t\th.report)\n\tworkload.TargetContainer().Image = imageInspector.ImageRef\n\n\t// 3. Patch and run the workload\n\t//    - patch: add the init container, the volume, replace the entrypoint\n\t//    - copy sensor to the volume via the init container\n\t//    - terminate (successfully) the init container\n\t//    - send StartCommand to the sensor\n\tpodInspector, err := pod.NewInspector(\n\t\th.ctx,\n\t\th.ExecutionContext,\n\t\th.logger,\n\t\tworkload,\n\t\th.kubectl,\n\t\th.kubeClient,\n\t\timageInspector,\n\t\topts.KeepPerms,\n\t\topts.PathPerms,\n\t\topts.Debug,\n\t\topts.LogLevel,\n\t\topts.LogFormat,\n\t\topts.RtaSourcePT,\n\t\tstatePath,\n\t\tnil,\n\t\topts.SensorIPCEndpoint,\n\t\topts.PortBindings,\n\t\topts.DoPublishExposedPorts,\n\t)\n\th.FailOn(err)\n\n\th.AddCleanupHandler(func() {\n\t\tpodInspector.FinishMonitoring()\n\t\tpodInspector.ShutdownPod(manifests == nil)\n\t})\n\n\th.logger.Info(\"starting instrumented 'fat' workload...\")\n\terr = podInspector.RunPod()\n\tif err != nil && opts.DoShowContainerLogs {\n\t\tpodInspector.ShowPodLogs()\n\t}\n\th.FailOn(err)\n\n\th.Out.Info(\"pod\",\n\t\tovars{\n\t\t\t\"name\":             podInspector.PodName(),\n\t\t\t\"target.port.list\": podInspector.PodPortList(),\n\t\t\t\"target.port.info\": podInspector.PodPortsInfo(),\n\t\t\t\"message\":          \"YOU CAN USE THESE PORTS TO INTERACT WITH THE POD\",\n\t\t})\n\n\t// 4. Monitor the workload.\n\th.logger.Info(\"watching pod monitor...\")\n\th.monitorPod(opts, podInspector)\n\n\t// 5. Copy the artifact from the workload.\n\th.Out.State(\"pod.inspection.finishing\")\n\n\tpodInspector.FinishMonitoring()\n\n\t// 6. Shut down the workload.\n\th.logger.Info(\"shutting down 'fat' pod...\")\n\tpodInspector.ShutdownPod(manifests == nil)\n\n\tif manifests != nil {\n\t\terrutil.WarnOn(manifests.Delete(h.ctx))\n\t}\n\n\t// 7. Build the slim image & create AppArmor and seccomp profiles\n\th.processCollectedDataOrFail(podInspector, imageInspector)\n\n\tminifiedImageName := buildOutputImage(\n\t\th.ExecutionContext,\n\t\topts.CustomImageTag,\n\t\topts.AdditionalTags,\n\t\topts.CBOpts,\n\t\tnil, // TODO: overrrides\n\t\tnil, // TODO: imageOverrideSelectors,\n\t\tnil, // TODO: instructions,\n\t\topts.DoDeleteFatImage,\n\t\topts.DoShowBuildLogs,\n\t\timageInspector,\n\t\th.dockerClient,\n\t\th.logger,\n\t\th.report,\n\t\topts.imageBuildEngine,\n\t\topts.imageBuildArch)\n\n\tfinishCommand(\n\t\th.ExecutionContext,\n\t\tminifiedImageName,\n\t\topts.CopyMetaArtifactsLocation,\n\t\topts.DoRmFileArtifacts,\n\t\topts.ArchiveState,\n\t\tstateKey,\n\t\timageInspector,\n\t\th.dockerClient,\n\t\th.logger,\n\t\th.report,\n\t\topts.imageBuildEngine)\n}\n\nfunc (h *kubeHandler) findWorkloadOrFail(target config.KubernetesTarget) *kubernetes.Workload {\n\tworkload, err := h.finder.Find(target)\n\th.FailOn(err)\n\n\tif workload == nil {\n\t\th.Out.Info(\"kubernetes.workload.error\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"workload.not.found\",\n\t\t\t\t\"target\": target.Workload,\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbKubernetesNoWorkload\n\t\th.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\n\t\th.Exit(exitCode)\n\t}\n\n\tif workload.TargetContainer() == nil {\n\t\th.Out.Info(\"kubernetes.workload.error\",\n\t\t\tovars{\n\t\t\t\t\"status\":           \"container.not.found\",\n\t\t\t\t\"target.container\": target.Container,\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbKubernetesNoWorkloadContainer\n\t\th.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\n\t\th.Exit(exitCode)\n\t}\n\n\th.Out.Info(\"kubernetes.workload\",\n\t\tovars{\n\t\t\t\"namespace\": workload.Namespace(),\n\t\t\t\"name\":      workload.Name(),\n\t\t\t\"template\":  asJSON(workload.Template()),\n\t\t\t\"target\":    asJSON(workload.TargetContainer()),\n\t\t})\n\n\treturn workload\n}\n\nfunc (h *kubeHandler) applyManifestsOrFail(\n\tmanifests *kubernetes.Manifests,\n\tworkload *kubernetes.Workload,\n) {\n\th.AddCleanupHandler(func() {\n\t\terrutil.WarnOn(manifests.Delete(h.ctx))\n\t})\n\n\t// PodInspector will be applying the workload manifest separately.\n\terr := manifests.Apply(h.ctx, func(info *resource.Info) bool {\n\t\treturn workload.Info().Mapping.GroupVersionKind.GroupKind() != info.Mapping.GroupVersionKind.GroupKind() ||\n\t\t\tworkload.Name() != info.Name || workload.Namespace() != info.Namespace\n\t})\n\th.FailOn(err)\n}\n\nfunc (h *kubeHandler) monitorPod(\n\topts kubeHandleOptions,\n\tpodInspector *pod.Inspector,\n) {\n\tvar probe *http.CustomProbe\n\tif opts.httpProbeOpts.Do {\n\t\tvar err error\n\t\tprobe, err = http.NewPodProbe(h.ExecutionContext, podInspector, opts.httpProbeOpts, true)\n\t\th.FailOn(err)\n\n\t\tif len(probe.Ports()) == 0 {\n\t\t\th.Out.State(\"http.probe.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"error\":   \"NO EXPOSED PORTS\",\n\t\t\t\t\t\"message\": \"make sure target container spec has `ports` field filled or disable HTTP probing with --http-probe=false if your Kubernetes workload doesn't expose any network services\",\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTBuild | ecbImageBuildError\n\t\t\th.Out.State(\"exited\", ovars{\"exit.code\": exitCode})\n\n\t\t\th.report.Error = \"no.exposed.ports\"\n\t\t\th.Exit(exitCode)\n\t\t}\n\n\t\tprobe.Start()\n\t\topts.continueAfter.ContinueChan = probe.DoneChan()\n\t}\n\n\tcontinueAfterMsg := \"provide the expected input to allow the container inspector to continue its execution\"\n\tif opts.continueAfter.Mode == config.CAMTimeout {\n\t\tcontinueAfterMsg = \"no input required, execution will resume after the timeout\"\n\t}\n\n\tif hasContinueAfterMode(opts.continueAfter.Mode, config.CAMProbe) {\n\t\tcontinueAfterMsg = \"no input required, execution will resume when HTTP probing is completed\"\n\t}\n\n\th.Out.Info(\"continue.after\",\n\t\tovars{\n\t\t\t\"mode\":    opts.continueAfter.Mode,\n\t\t\t\"message\": continueAfterMsg,\n\t\t})\n\n\tmodes := strings.Split(opts.continueAfter.Mode, \"&\")\n\tfor _, mode := range modes {\n\t\tswitch mode {\n\t\tcase config.CAMEnter:\n\t\t\th.Out.Prompt(\"USER INPUT REQUIRED, PRESS <ENTER> WHEN YOU ARE DONE USING THE KUBERNETES WORKLOAD\")\n\t\t\tcreader := bufio.NewReader(os.Stdin)\n\t\t\t_, _, _ = creader.ReadLine()\n\n\t\tcase config.CAMExec:\n\t\t\t// Use execCmd\n\t\t\th.Out.Info(\"continue.after\", ovars{\"mode\": config.CAMExec, \"shell\": opts.execCmd})\n\n\t\t\tout, err := podInspector.Exec(\"sh\", \"-c\", opts.execCmd)\n\t\t\terrutil.WarnOn(err)\n\n\t\t\th.Out.Info(\"continue.after\", ovars{\"mode\": config.CAMExec, \"output\": string(out)})\n\n\t\tcase config.CAMSignal:\n\t\t\th.Out.Prompt(\"send SIGUSR1 when you are done using the container\")\n\t\t\t<-opts.continueAfter.ContinueChan\n\t\t\th.Out.Info(\"event\", ovars{\"message\": \"got SIGUSR1\"})\n\n\t\tcase config.CAMTimeout:\n\t\t\th.Out.Prompt(fmt.Sprintf(\"waiting for the target container (%v seconds)\", int(opts.continueAfter.Timeout)))\n\t\t\t<-time.After(time.Second * opts.continueAfter.Timeout)\n\t\t\th.Out.Info(\"event\", ovars{\"message\": \"done waiting for the target container\"})\n\n\t\tcase config.CAMProbe:\n\t\t\th.Out.Prompt(\"waiting for the HTTP probe to finish\")\n\t\t\t<-opts.continueAfter.ContinueChan\n\t\t\th.Out.Info(\"event\", ovars{\"message\": \"HTTP probe is done\"})\n\n\t\t\tif probe.CallCount > 0 && probe.OkCount == 0 && opts.httpProbeOpts.ExitOnFailure {\n\t\t\t\th.Out.Error(\"probe.error\", \"no.successful.calls\")\n\n\t\t\t\tpodInspector.ShowPodLogs()\n\t\t\t\th.Out.State(\"exited\", ovars{\"exit.code\": -1})\n\t\t\t\th.Exit(-1)\n\t\t\t}\n\n\t\tdefault:\n\t\t\terrutil.Fail(\"unknown continue-after mode\")\n\t\t}\n\t}\n}\n\nfunc (h *kubeHandler) processCollectedDataOrFail(podInspector *pod.Inspector, imageInspector *image.Inspector) {\n\tif !podInspector.HasCollectedData() {\n\t\timageInspector.ShowFatImageDockerInstructions()\n\t\th.Out.Info(\"results\",\n\t\t\tovars{\n\t\t\t\t\"status\":   \"no data collected (no minified image generated)\",\n\t\t\t\t\"version\":  v.Current(),\n\t\t\t\t\"location\": fsutil.ExeDir(),\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecbImageBuildError\n\t\th.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t})\n\n\t\th.report.Error = \"no.data.collected\"\n\t\th.Exit(exitCode)\n\t}\n\n\th.logger.Info(\"processing instrumented 'fat' container info...\")\n\th.FailOn(podInspector.ProcessCollectedData())\n}\n\nfunc asJSON(val interface{}) string {\n\tbytes, err := json.Marshal(val)\n\tif err != nil {\n\t\tpanic(\"json.Marshal failed: \" + err.Error())\n\t}\n\treturn string(bytes)\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/prompt.go",
    "content": "package build\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(command.FlagCommandParamsFile), Description: command.FlagCommandParamsFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagTarget), Description: command.FlagTargetUsage},\n\t\t{Text: command.FullFlagName(command.FlagComposeFile), Description: command.FlagComposeFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagTargetComposeSvc), Description: command.FlagTargetComposeSvcUsage},\n\t\t{Text: command.FullFlagName(command.FlagTargetComposeSvcImage), Description: command.FlagTargetComposeSvcImageUsage},\n\t\t{Text: command.FullFlagName(command.FlagComposeSvcStartWait), Description: command.FlagComposeSvcStartWaitUsage},\n\t\t{Text: command.FullFlagName(command.FlagDepIncludeComposeSvc), Description: command.FlagDepIncludeComposeSvcUsage},\n\t\t{Text: command.FullFlagName(command.FlagDepExcludeComposeSvc), Description: command.FlagDepExcludeComposeSvcUsage},\n\t\t{Text: command.FullFlagName(command.FlagDepIncludeComposeSvcDeps), Description: command.FlagDepIncludeComposeSvcDepsUsage},\n\t\t{Text: command.FullFlagName(command.FlagComposeNet), Description: command.FlagComposeNetUsage},\n\t\t{Text: command.FullFlagName(command.FlagDepIncludeTargetComposeSvcDeps), Description: command.FlagDepIncludeTargetComposeSvcDepsUsage},\n\t\t{Text: command.FullFlagName(command.FlagComposeEnvNoHost), Description: command.FlagComposeEnvNoHostUsage},\n\t\t{Text: command.FullFlagName(command.FlagComposeEnvFile), Description: command.FlagComposeEnvFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagComposeProjectName), Description: command.FlagComposeProjectNameUsage},\n\t\t{Text: command.FullFlagName(command.FlagComposeWorkdir), Description: command.FlagComposeWorkdirUsage},\n\t\t{Text: command.FullFlagName(command.FlagContainerProbeComposeSvc), Description: command.FlagContainerProbeComposeSvcUsage},\n\t\t{Text: command.FullFlagName(command.FlagTargetKubeWorkload), Description: command.FlagTargetKubeWorkloadUsage},\n\t\t{Text: command.FullFlagName(command.FlagTargetKubeWorkloadNamespace), Description: command.FlagTargetKubeWorkloadNamespaceUsage},\n\t\t{Text: command.FullFlagName(command.FlagTargetKubeWorkloadContainer), Description: command.FlagTargetKubeWorkloadContainerUsage},\n\t\t{Text: command.FullFlagName(command.FlagTargetKubeWorkloadImage), Description: command.FlagTargetKubeWorkloadImageUsage},\n\t\t{Text: command.FullFlagName(command.FlagKubeManifestFile), Description: command.FlagKubeManifestFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagKubeKubeconfigFile), Description: command.FlagKubeKubeconfigFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagPull), Description: command.FlagPullUsage},\n\t\t{Text: command.FullFlagName(command.FlagShowPullLogs), Description: command.FlagShowPullLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagRegistryAccount), Description: command.FlagRegistryAccountUsage},\n\t\t{Text: command.FullFlagName(command.FlagRegistrySecret), Description: command.FlagRegistrySecretUsage},\n\t\t{Text: command.FullFlagName(command.FlagDockerConfigPath), Description: command.FlagDockerConfigPathUsage},\n\t\t{Text: command.FullFlagName(FlagShowBuildLogs), Description: FlagShowBuildLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagShowContainerLogs), Description: command.FlagShowContainerLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagEnableMondelLogs), Description: command.FlagEnableMondelLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagCRORuntime), Description: command.FlagCRORuntimeUsage},\n\t\t{Text: command.FullFlagName(command.FlagCROHostConfigFile), Description: command.FlagCROHostConfigFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagCROSysctl), Description: command.FlagCROSysctlUsage},\n\t\t{Text: command.FullFlagName(command.FlagCROShmSize), Description: command.FlagCROShmSizeUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeOff), Description: command.FlagHTTPProbeOffUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbe), Description: command.FlagHTTPProbeUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCmd), Description: command.FlagHTTPProbeCmdUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCmdFile), Description: command.FlagHTTPProbeCmdFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeStartWait), Description: command.FlagHTTPProbeStartWaitUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeRetryCount), Description: command.FlagHTTPProbeRetryCountUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeRetryWait), Description: command.FlagHTTPProbeRetryWaitUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbePorts), Description: command.FlagHTTPProbePortsUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeFull), Description: command.FlagHTTPProbeFullUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeExitOnFailure), Description: command.FlagHTTPProbeExitOnFailureUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCrawl), Description: command.FlagHTTPProbeCrawlUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlMaxDepth), Description: command.FlagHTTPCrawlMaxDepthUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlMaxPageCount), Description: command.FlagHTTPCrawlMaxPageCountUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlConcurrency), Description: command.FlagHTTPCrawlConcurrencyUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPMaxConcurrentCrawlers), Description: command.FlagHTTPMaxConcurrentCrawlersUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeAPISpec), Description: command.FlagHTTPProbeAPISpecUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeAPISpecFile), Description: command.FlagHTTPProbeAPISpecFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagPublishPort), Description: command.FlagPublishPortUsage},\n\t\t{Text: command.FullFlagName(command.FlagPublishExposedPorts), Description: command.FlagPublishExposedPortsUsage},\n\t\t{Text: command.FullFlagName(command.FlagHostExec), Description: command.FlagHostExecUsage},\n\t\t{Text: command.FullFlagName(command.FlagHostExecFile), Description: command.FlagHostExecFileUsage},\n\t\t{Text: command.FullFlagName(FlagKeepPerms), Description: FlagKeepPermsUsage},\n\t\t{Text: command.FullFlagName(command.FlagRunTargetAsUser), Description: command.FlagRunTargetAsUserUsage},\n\t\t{Text: command.FullFlagName(command.FlagCopyMetaArtifacts), Description: command.FlagCopyMetaArtifactsUsage},\n\t\t{Text: command.FullFlagName(command.FlagRemoveFileArtifacts), Description: command.FlagRemoveFileArtifactsUsage},\n\t\t{Text: command.FullFlagName(FlagTag), Description: FlagTagUsage},\n\t\t{Text: command.FullFlagName(FlagImageOverrides), Description: FlagImageOverridesUsage},\n\t\t{Text: command.FullFlagName(command.FlagUser), Description: command.FlagUserUsage},\n\t\t{Text: command.FullFlagName(command.FlagEntrypoint), Description: command.FlagEntrypointUsage},\n\t\t{Text: command.FullFlagName(command.FlagCmd), Description: command.FlagCmdUsage},\n\t\t{Text: command.FullFlagName(command.FlagWorkdir), Description: command.FlagWorkdirUsage},\n\t\t{Text: command.FullFlagName(command.FlagEnv), Description: command.FlagEnvUsage},\n\t\t{Text: command.FullFlagName(command.FlagEnvFile), Description: command.FlagEnvFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagLabel), Description: command.FlagLabelUsage},\n\t\t{Text: command.FullFlagName(command.FlagVolume), Description: command.FlagVolumeUsage},\n\t\t{Text: command.FullFlagName(command.FlagLink), Description: command.FlagLinkUsage},\n\t\t{Text: command.FullFlagName(command.FlagEtcHostsMap), Description: command.FlagEtcHostsMapUsage},\n\t\t{Text: command.FullFlagName(command.FlagContainerDNS), Description: command.FlagContainerDNSUsage},\n\t\t{Text: command.FullFlagName(command.FlagContainerDNSSearch), Description: command.FlagContainerDNSSearchUsage},\n\t\t{Text: command.FullFlagName(command.FlagNetwork), Description: command.FlagNetworkUsage},\n\t\t{Text: command.FullFlagName(command.FlagHostname), Description: command.FlagHostnameUsage},\n\t\t{Text: command.FullFlagName(command.FlagExpose), Description: command.FlagExposeUsage},\n\t\t{Text: command.FullFlagName(FlagNewEntrypoint), Description: FlagNewEntrypointUsage},\n\t\t{Text: command.FullFlagName(FlagNewCmd), Description: FlagNewCmdUsage},\n\t\t{Text: command.FullFlagName(FlagNewExpose), Description: FlagNewExposeUsage},\n\t\t{Text: command.FullFlagName(FlagNewWorkdir), Description: FlagNewWorkdirUsage},\n\t\t{Text: command.FullFlagName(FlagNewEnv), Description: FlagNewEnvUsage},\n\t\t{Text: command.FullFlagName(FlagNewVolume), Description: FlagNewVolumeUsage},\n\t\t{Text: command.FullFlagName(FlagNewLabel), Description: FlagNewLabelUsage},\n\t\t{Text: command.FullFlagName(FlagRemoveExpose), Description: FlagRemoveExposeUsage},\n\t\t{Text: command.FullFlagName(FlagRemoveEnv), Description: FlagRemoveEnvUsage},\n\t\t{Text: command.FullFlagName(FlagRemoveLabel), Description: FlagRemoveLabelUsage},\n\t\t{Text: command.FullFlagName(FlagRemoveVolume), Description: FlagRemoveVolumeUsage},\n\t\t{Text: command.FullFlagName(FlagExcludeMounts), Description: FlagExcludeMountsUsage},\n\t\t{Text: command.FullFlagName(FlagExcludeVarLockFiles), Description: FlagExcludeVarLockFilesUsage},\n\t\t{Text: command.FullFlagName(FlagExcludePattern), Description: FlagExcludePatternUsage},\n\t\t{Text: command.FullFlagName(FlagPathPerms), Description: FlagPathPermsUsage},\n\t\t{Text: command.FullFlagName(FlagPathPermsFile), Description: FlagPathPermsFileUsage},\n\t\t{Text: command.FullFlagName(FlagPreservePath), Description: FlagPreservePathUsage},\n\t\t{Text: command.FullFlagName(FlagPreservePathFile), Description: FlagPreservePathFileUsage},\n\t\t{Text: command.FullFlagName(FlagIncludePath), Description: FlagIncludePathUsage},\n\t\t{Text: command.FullFlagName(FlagIncludePathFile), Description: FlagIncludePathFileUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeBin), Description: FlagIncludeBinUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeBinFile), Description: FlagIncludeBinFileUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeExe), Description: FlagIncludeExeUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeExeFile), Description: FlagIncludeExeFileUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeShell), Description: FlagIncludeShellUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeWorkdir), Description: FlagIncludeWorkdirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppImageAll), Description: FlagIncludeAppImageAllUsage},\n\t\t{Text: command.FullFlagName(FlagAppImageStartInstGroup), Description: FlagAppImageStartInstGroupUsage},\n\t\t{Text: command.FullFlagName(FlagAppImageStartInst), Description: FlagAppImageStartInstUsage},\n\t\t{Text: command.FullFlagName(FlagAppImageDockerfile), Description: FlagAppImageDockerfileUsage},\n\t\t{Text: command.FullFlagName(FlagIncludePathsCreportFile), Description: FlagIncludePathsCreportFileUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeSSHClient), Description: FlagIncludeSSHClientUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeOSLibsNet), Description: FlagIncludeOSLibsNetUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCertAll), Description: FlagIncludeCertAllUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCertBundles), Description: FlagIncludeCertBundlesUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCertDirs), Description: FlagIncludeCertDirsUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCertPKAll), Description: FlagIncludeCertPKAllUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCertPKDirs), Description: FlagIncludeCertPKDirsUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeNew), Description: FlagIncludeNewUsage},\n\t\t{Text: command.FullFlagName(command.FlagMount), Description: command.FlagMountUsage},\n\t\t{Text: command.FullFlagName(command.FlagContinueAfter), Description: command.FlagContinueAfterUsage},\n\t\t{Text: command.FullFlagName(command.FlagUseLocalMounts), Description: command.FlagUseLocalMountsUsage},\n\t\t{Text: command.FullFlagName(command.FlagUseSensorVolume), Description: command.FlagUseSensorVolumeUsage},\n\t\t{Text: command.FullFlagName(FlagKeepTmpArtifacts), Description: FlagKeepTmpArtifactsUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNuxtDir), Description: FlagIncludeAppNuxtDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNuxtBuildDir), Description: FlagIncludeAppNuxtBuildDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNuxtDistDir), Description: FlagIncludeAppNuxtDistDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNuxtStaticDir), Description: FlagIncludeAppNuxtStaticDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNuxtNodeModulesDir), Description: FlagIncludeAppNuxtNodeModulesDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNextDir), Description: FlagIncludeAppNextDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNextBuildDir), Description: FlagIncludeAppNextBuildDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNextDistDir), Description: FlagIncludeAppNextDistDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNextStaticDir), Description: FlagIncludeAppNextStaticDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeAppNextNodeModulesDir), Description: FlagIncludeAppNextNodeModulesDirUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeNodePackage), Description: FlagIncludeNodePackageUsage},\n\t\t{Text: command.FullFlagName(FlagBuildFromDockerfile), Description: FlagBuildFromDockerfileUsage},\n\t\t{Text: command.FullFlagName(FlagDockerfileContext), Description: FlagDockerfileContextUsage},\n\t\t{Text: command.FullFlagName(FlagTagFat), Description: FlagTagFatUsage},\n\t\t{Text: command.FullFlagName(FlagCBOAddHost), Description: FlagCBOAddHostUsage},\n\t\t{Text: command.FullFlagName(FlagCBOBuildArg), Description: FlagCBOBuildArgUsage},\n\t\t{Text: command.FullFlagName(FlagCBOLabel), Description: FlagCBOLabelUsage},\n\t\t{Text: command.FullFlagName(FlagCBOTarget), Description: FlagCBOTargetUsage},\n\t\t{Text: command.FullFlagName(FlagCBONetwork), Description: FlagCBONetworkUsage},\n\t\t{Text: command.FullFlagName(FlagCBOCacheFrom), Description: FlagCBOCacheFromUsage},\n\t\t{Text: command.FullFlagName(command.FlagDeleteFatImage), Description: command.FlagDeleteFatImageUsage},\n\t\t{Text: command.FullFlagName(command.FlagRTAOnbuildBaseImage), Description: command.FlagRTAOnbuildBaseImageUsage},\n\t\t{Text: command.FullFlagName(command.FlagRTASourcePT), Description: command.FlagRTASourcePTUsage},\n\t\t{Text: command.FullFlagName(command.FlagSensorIPCMode), Description: command.FlagSensorIPCModeUsage},\n\t\t{Text: command.FullFlagName(command.FlagSensorIPCEndpoint), Description: command.FlagSensorIPCEndpointUsage},\n\t\t{Text: command.FullFlagName(FlagImageBuildEngine), Description: FlagImageBuildEngineUsage},\n\t\t{Text: command.FullFlagName(FlagImageBuildArch), Description: FlagImageBuildArchUsage},\n\t\t{Text: command.FullFlagName(FlagObfuscateMetadata), Description: FlagObfuscateMetadataUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(command.FlagCommandParamsFile): command.CompleteFile,\n\t\t//NOTE: with FlagPull target complete needs to check remote registries too\n\t\tcommand.FullFlagName(command.FlagPull):                           command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagShowPullLogs):                   command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagDockerConfigPath):               command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagTarget):                         command.CompleteImage,\n\t\tcommand.FullFlagName(command.FlagComposeFile):                    command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagDepIncludeTargetComposeSvcDeps): command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagComposeEnvNoHost):               command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagComposeEnvFile):                 command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagComposeWorkdir):                 command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagKubeManifestFile):               command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagKubeKubeconfigFile):             command.CompleteFile,\n\t\tcommand.FullFlagName(FlagShowBuildLogs):                          command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagShowContainerLogs):              command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagEnableMondelLogs):               command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagPublishExposedPorts):            command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeOff):                   command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbe):                      command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeCmdFile):               command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeFull):                  command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeExitOnFailure):         command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeCrawl):                 command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeAPISpecFile):           command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagHostExecFile):                   command.CompleteFile,\n\t\tcommand.FullFlagName(FlagKeepPerms):                              command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagRunTargetAsUser):                command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagRemoveFileArtifacts):            command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagNetwork):                        command.CompleteNetwork,\n\t\tcommand.FullFlagName(FlagExcludeVarLockFiles):                    command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagExcludeMounts):                          command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagPathPermsFile):                          command.CompleteFile,\n\t\tcommand.FullFlagName(FlagPreservePathFile):                       command.CompleteFile,\n\t\tcommand.FullFlagName(FlagIncludePathFile):                        command.CompleteFile,\n\t\tcommand.FullFlagName(FlagIncludeBinFile):                         command.CompleteFile,\n\t\tcommand.FullFlagName(FlagIncludeExeFile):                         command.CompleteFile,\n\t\tcommand.FullFlagName(FlagIncludePathsCreportFile):                command.CompleteFile,\n\t\tcommand.FullFlagName(FlagIncludeShell):                           command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeWorkdir):                         command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppImageAll):                     command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeSSHClient):                       command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeOSLibsNet):                       command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeCertAll):                         command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeCertBundles):                     command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeCertDirs):                        command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeCertPKAll):                       command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeCertPKDirs):                      command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeNew):                             command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagContinueAfter):                  command.CompleteContinueAfter,\n\t\t//command.FullFlagName(command.FlagConsoleFormat):                  command.CompleteConsoleOutput,\n\t\tcommand.FullFlagName(command.FlagUseLocalMounts):       command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagUseSensorVolume):      command.CompleteVolume,\n\t\tcommand.FullFlagName(FlagKeepTmpArtifacts):             command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNuxtDir):            command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNuxtBuildDir):       command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNuxtDistDir):        command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNuxtStaticDir):      command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNuxtNodeModulesDir): command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNextDir):            command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNextBuildDir):       command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNextDistDir):        command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNextStaticDir):      command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeAppNextNodeModulesDir): command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagCROHostConfigFile):    command.CompleteFile,\n\t\tcommand.FullFlagName(FlagDockerfileContext):            command.CompleteFile,\n\t\tcommand.FullFlagName(FlagDeleteFatImage):               command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagRTAOnbuildBaseImage):  command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagRTASourcePT):          command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagSensorIPCMode):        command.CompleteIPCMode,\n\t\tcommand.FullFlagName(FlagImageBuildEngine):             CompleteImageBuildEngine,\n\t\tcommand.FullFlagName(FlagImageBuildArch):               CompleteImageBuildArch,\n\t\tcommand.FullFlagName(FlagAppImageDockerfile):           command.CompleteFile,\n\t\tcommand.FullFlagName(FlagObfuscateMetadata):            command.CompleteBool,\n\t},\n}\n\nvar imageBuildEngineValues = []prompt.Suggest{\n\t{Text: IBENone, Description: \"no image build engine (output image is not built)\"},\n\t{Text: IBEInternal, Description: \"internal image build engine\"},\n\t{Text: IBEDocker, Description: \"standard Docker image build engine\"},\n\t{Text: IBEBuildKit, Description: \"BuildKit image build engine\"},\n}\n\nfunc CompleteImageBuildEngine(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(imageBuildEngineValues, token, true)\n}\n\nvar imageBuildArchValues = []prompt.Suggest{\n\t{Text: ArchAmd64, Description: \"amd64 architecture\"},\n\t{Text: ArchArm64, Description: \"arm64 architecture\"},\n}\n\nfunc CompleteImageBuildArch(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(imageBuildArchValues, token, true)\n}\n"
  },
  {
    "path": "pkg/app/master/command/build/register.go",
    "content": "package build\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/cliflags.go",
    "content": "package command\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n\t\"k8s.io/client-go/tools/clientcmd\"\n)\n\n/////////////////////////////////////////////////////////\n//Flags\n/////////////////////////////////////////////////////////\n\n// Global flag names\nconst (\n\tFlagCommandReport = \"report\"\n\tFlagCheckVersion  = \"check-version\"\n\tFlagDebug         = \"debug\"\n\tFlagVerbose       = \"verbose\"\n\tFlagQuietCLIMode  = \"quiet\"\n\tFlagLogLevel      = \"log-level\"\n\tFlagLog           = \"log\"\n\tFlagLogFormat     = \"log-format\"\n\tFlagAPIVersion    = \"crt-api-version\"\n\tFlagUseTLS        = \"tls\"\n\tFlagVerifyTLS     = \"tls-verify\"\n\tFlagTLSCertPath   = \"tls-cert-path\"\n\tFlagHost          = \"host\"\n\tFlagStatePath     = \"state-path\"\n\tFlagInContainer   = \"in-container\"\n\tFlagArchiveState  = \"archive-state\"\n\tFlagNoColor       = \"no-color\"\n\tFlagOutputFormat  = \"output-format\"\n)\n\nconst (\n\tOutputFormatJSON = \"json\"\n\tOutputFormatText = \"text\"\n)\n\n// Global flag usage info\nconst (\n\tFlagCommandReportUsage = \"command report location (enabled by default; set it to \\\"off\\\" to disable it)\"\n\tFlagCheckVersionUsage  = \"check if the current version is outdated\"\n\tFlagDebugUsage         = \"enable debug logs\"\n\tFlagVerboseUsage       = \"enable info logs\"\n\tFlagQuietCLIModeUsage  = \"Quiet CLI execution mode\"\n\tFlagLogLevelUsage      = \"set the logging level ('trace', 'debug', 'info', 'warn' (default), 'error', 'fatal', 'panic')\"\n\tFlagLogUsage           = \"log file to store logs\"\n\tFlagLogFormatUsage     = \"set the format used by logs ('text' (default), or 'json')\"\n\tFlagOutputFormatUsage  = \"set the output format to use ('text' (default), or 'json')\"\n\tFlagUseTLSUsage        = \"use TLS\"\n\tFlagVerifyTLSUsage     = \"verify TLS\"\n\tFlagTLSCertPathUsage   = \"path to TLS cert files\"\n\tFlagAPIVersionUsage    = \"Container runtime API version\"\n\tFlagHostUsage          = \"Docker host address or socket (prefix with 'tcp://' or 'unix://')\"\n\tFlagStatePathUsage     = \"app state base path\"\n\tFlagInContainerUsage   = \"app is running in a container\"\n\tFlagArchiveStateUsage  = \"archive app state to the selected Docker volume (default volume - slim-state). By default, enabled when app is running in a container (disabled otherwise). Set it to \\\"off\\\" to disable explicitly.\"\n\tFlagNoColorUsage       = \"disable color output\"\n)\n\n// Shared command flag names\nconst (\n\tFlagCommandParamsFile = \"command-params-file\"\n\tFlagTarget            = \"target\"\n\tFlagPull              = \"pull\"\n\tFlagDockerConfigPath  = \"docker-config-path\"\n\tFlagRegistryAccount   = \"registry-account\"\n\tFlagRegistrySecret    = \"registry-secret\"\n\tFlagShowPullLogs      = \"show-plogs\"\n\n\t//Compose-related flags\n\tFlagComposeFile                    = \"compose-file\"\n\tFlagTargetComposeSvc               = \"target-compose-svc\"\n\tFlagTargetComposeSvcImage          = \"target-compose-svc-image\"\n\tFlagComposeSvcStartWait            = \"compose-svc-start-wait\"\n\tFlagComposeSvcNoPorts              = \"target-compose-svc-no-ports\"\n\tFlagDepExcludeComposeSvcAll        = \"dep-exclude-compose-svc-all\"\n\tFlagDepIncludeComposeSvc           = \"dep-include-compose-svc\"\n\tFlagDepExcludeComposeSvc           = \"dep-exclude-compose-svc\"\n\tFlagDepIncludeComposeSvcDeps       = \"dep-include-compose-svc-deps\"\n\tFlagDepIncludeTargetComposeSvcDeps = \"dep-include-target-compose-svc-deps\"\n\tFlagComposeNet                     = \"compose-net\"\n\tFlagComposeEnvNoHost               = \"compose-env-nohost\"\n\tFlagComposeEnvFile                 = \"compose-env-file\"\n\tFlagComposeWorkdir                 = \"compose-workdir\"\n\tFlagComposeProjectName             = \"compose-project-name\"\n\tFlagPrestartComposeSvc             = \"prestart-compose-svc\"\n\tFlagPoststartComposeSvc            = \"poststart-compose-svc\"\n\tFlagPrestartComposeWaitExit        = \"prestart-compose-wait-exit\"\n\tFlagContainerProbeComposeSvc       = \"container-probe-compose-svc\"\n\n\t//Kubernetes-related flags\n\tFlagTargetKubeWorkload          = \"target-kube-workload\" // <kind>/<name> e.g: deployment/foo, job/bar\n\tFlagTargetKubeWorkloadNamespace = \"target-kube-workload-namespace\"\n\tFlagTargetKubeWorkloadContainer = \"target-kube-workload-container\"\n\tFlagTargetKubeWorkloadImage     = \"target-kube-workload-image\"\n\tFlagKubeManifestFile            = \"kube-manifest-file\"\n\tFlagKubeKubeconfigFile          = \"kube-kubeconfig-file\"\n\t// TODO: FlagKubeContext        = \"kube-context\"\n\t//       FlagKubeCluster        =\" kube-cluster\"\n\t//       etc.\n\t// Naming convention: keep the well known kubectl flag names as-is and prefix them with `--kube-`\n\n\tFlagRemoveFileArtifacts = \"remove-file-artifacts\"\n\tFlagCopyMetaArtifacts   = \"copy-meta-artifacts\"\n\n\tFlagHTTPProbe                 = \"http-probe\"\n\tFlagHTTPProbeOff              = \"http-probe-off\" //alternative way to disable http probing\n\tFlagHTTPProbeCmd              = \"http-probe-cmd\"\n\tFlagHTTPProbeCmdFile          = \"http-probe-cmd-file\"\n\tFlagHTTPProbeStartWait        = \"http-probe-start-wait\"\n\tFlagHTTPProbeRetryCount       = \"http-probe-retry-count\"\n\tFlagHTTPProbeRetryWait        = \"http-probe-retry-wait\"\n\tFlagHTTPProbePorts            = \"http-probe-ports\"\n\tFlagHTTPProbeFull             = \"http-probe-full\"\n\tFlagHTTPProbeExitOnFailure    = \"http-probe-exit-on-failure\"\n\tFlagHTTPProbeCrawl            = \"http-probe-crawl\"\n\tFlagHTTPCrawlMaxDepth         = \"http-crawl-max-depth\"\n\tFlagHTTPCrawlMaxPageCount     = \"http-crawl-max-page-count\"\n\tFlagHTTPCrawlConcurrency      = \"http-crawl-concurrency\"\n\tFlagHTTPMaxConcurrentCrawlers = \"http-max-concurrent-crawlers\"\n\tFlagHTTPProbeAPISpec          = \"http-probe-apispec\"\n\tFlagHTTPProbeAPISpecFile      = \"http-probe-apispec-file\"\n\tFlagHTTPProbeProxyEndpoint    = \"http-probe-proxy-endpoint\"\n\tFlagHTTPProbeProxyPort        = \"http-probe-proxy-port\"\n\n\tFlagHostExec     = \"host-exec\"\n\tFlagHostExecFile = \"host-exec-file\"\n\n\tFlagPublishPort         = \"publish-port\"\n\tFlagPublishExposedPorts = \"publish-exposed-ports\"\n\n\tFlagRunTargetAsUser   = \"run-target-as-user\"\n\tFlagShowContainerLogs = \"show-clogs\"\n\tFlagEnableMondelLogs  = \"enable-mondel\" //Mon(itor) Data Event Log\n\n\tFlagUseLocalMounts  = \"use-local-mounts\"\n\tFlagUseSensorVolume = \"use-sensor-volume\"\n\tFlagContinueAfter   = \"continue-after\"\n\n\t//RunTime Analysis Options\n\tFlagRTAOnbuildBaseImage = \"rta-onbuild-base-image\"\n\tFlagRTASourcePT         = \"rta-source-ptrace\"\n\n\t//Sensor IPC Options (for build and profile commands)\n\tFlagSensorIPCEndpoint = \"sensor-ipc-endpoint\"\n\tFlagSensorIPCMode     = \"sensor-ipc-mode\"\n\n\tFlagExec     = \"exec\"\n\tFlagExecFile = \"exec-file\"\n\n\t//Container Run Options (for build, profile and run commands)\n\tFlagCRORuntime        = \"cro-runtime\"\n\tFlagCROHostConfigFile = \"cro-host-config-file\"\n\tFlagCROSysctl         = \"cro-sysctl\"\n\tFlagCROShmSize        = \"cro-shm-size\"\n\n\t//Original Container Runtime Options (without cro- prefix)\n\tFlagUser               = \"user\"\n\tFlagEntrypoint         = \"entrypoint\"\n\tFlagCmd                = \"cmd\"\n\tFlagWorkdir            = \"workdir\"\n\tFlagEnv                = \"env\"\n\tFlagEnvFile            = \"env-file\"\n\tFlagLabel              = \"label\"\n\tFlagVolume             = \"volume\"\n\tFlagExpose             = \"expose\"\n\tFlagLink               = \"link\"\n\tFlagNetwork            = \"network\"\n\tFlagHostname           = \"hostname\"\n\tFlagEtcHostsMap        = \"etc-hosts-map\"\n\tFlagContainerDNS       = \"container-dns\"\n\tFlagContainerDNSSearch = \"container-dns-search\"\n\tFlagMount              = \"mount\"\n\tFlagDeleteFatImage     = \"delete-generated-fat-image\"\n)\n\n// Shared command flag usage info\nconst (\n\tFlagCommandParamsFileUsage = \"JSON file with all command parameters\"\n\tFlagTargetUsage            = \"Target container image (name or ID)\"\n\tFlagPullUsage              = \"Try pulling target if it's not available locally\"\n\tFlagDockerConfigPathUsage  = \"Docker config path (used to fetch registry credentials)\"\n\tFlagRegistryAccountUsage   = \"Target registry account used when pulling images from private registries\"\n\tFlagRegistrySecretUsage    = \"Target registry secret used when pulling images from private registries\"\n\tFlagShowPullLogsUsage      = \"Show image pull logs\"\n\n\t//Compose-related flags\n\tFlagComposeFileUsage                    = \"Load container info from selected compose file(s)\"\n\tFlagTargetComposeSvcUsage               = \"Target service from compose file\"\n\tFlagTargetComposeSvcImageUsage          = \"Override the container image name and/or tag when targeting a compose service using the target-compose-svc parameter (format: tag_name or image_name:tag_name)\"\n\tFlagComposeSvcStartWaitUsage            = \"Number of seconds to wait before starting each compose service\"\n\tFlagComposeSvcNoPortsUsage              = \"Do not publish ports for target service from compose file\"\n\tFlagDepExcludeComposeSvcAllUsage        = \"Do not start any compose services as target dependencies\"\n\tFlagDepIncludeComposeSvcUsage           = \"Include specific compose service as a target dependency (only selected services will be started)\"\n\tFlagDepExcludeComposeSvcUsage           = \"Exclude specific service from the compose services that will be started as target dependencies\"\n\tFlagDepIncludeComposeSvcDepsUsage       = \"Include all dependencies for the selected compose service (excluding the service itself) as target dependencies\"\n\tFlagDepIncludeTargetComposeSvcDepsUsage = \"Include all dependencies for the target compose service (excluding the service itself) as target dependencies\"\n\tFlagComposeNetUsage                     = \"Attach target to the selected compose network(s) otherwise all networks will be attached\"\n\tFlagComposeEnvNoHostUsage               = \"Don't include the env vars from the host to compose\"\n\tFlagComposeEnvFileUsage                 = \"Load compose env vars from file (host env vars override the values loaded from this file)\"\n\tFlagComposeWorkdirUsage                 = \"Set custom work directory for compose\"\n\tFlagContainerProbeComposeSvcUsage       = \"Container test/probe service from compose file\"\n\tFlagComposeProjectNameUsage             = \"Use custom project name for compose\"\n\tFlagPrestartComposeSvcUsage             = \"Run selected compose service(s) before any other compose services or target container\"\n\tFlagPoststartComposeSvcUsage            = \"Run selected compose service(s) after the target container is running (need a new continue after mode too)\"\n\tFlagPrestartComposeWaitExitUsage        = \"Wait for selected prestart compose services to exit before starting other compose services or target container\"\n\n\t//Kubernetes-related flags\n\tFlagTargetKubeWorkloadUsage          = \"[Experimental] Target Kubernetes workload from the manifests (if --kube-manifest-file is provided) or in the default kubeconfig cluster (format: <resource>/<name>, e.g., deployments/foobar)\"\n\tFlagTargetKubeWorkloadNamespaceUsage = \"[Experimental] Target Kubernetes workload namespace (if not set, the value from the manifest is used if provided, otherwise - \\\"default\\\")\"\n\tFlagTargetKubeWorkloadContainerUsage = \"[Experimental] Target container in the Kubernetes workload's pod template spec\"\n\tFlagTargetKubeWorkloadImageUsage     = \"[Experimental] Override the container image name and/or tag when targeting a Kubernetes workload (format: tag_name or image_name:tag_name)\"\n\tFlagKubeManifestFileUsage            = \"[Experimental] Kubernetes manifest(s) to apply before run\"\n\tFlagKubeKubeconfigFileUsage          = \"[Experimental] Path to the kubeconfig file\"\n\n\tFlagRemoveFileArtifactsUsage = \"remove file artifacts when command is done\"\n\tFlagCopyMetaArtifactsUsage   = \"copy metadata artifacts to the selected location when command is done\"\n\n\tFlagHTTPProbeUsage                 = \"Enable or disable HTTP probing\"\n\tFlagHTTPProbeOffUsage              = \"Alternative way to disable HTTP probing\"\n\tFlagHTTPProbeCmdUsage              = \"User defined HTTP probe(s) as [[[[\\\"crawl\\\":]PROTO:]METHOD:]PATH]\"\n\tFlagHTTPProbeCmdFileUsage          = \"File with user defined HTTP probes\"\n\tFlagHTTPProbeStartWaitUsage        = \"Number of seconds to wait before starting HTTP probing\"\n\tFlagHTTPProbeRetryCountUsage       = \"Number of retries for each HTTP probe\"\n\tFlagHTTPProbeRetryWaitUsage        = \"Number of seconds to wait before retrying HTTP probe (doubles when target is not ready)\"\n\tFlagHTTPProbePortsUsage            = \"Explicit list of ports to probe (in the order you want them to be probed)\"\n\tFlagHTTPProbeFullUsage             = \"Do full HTTP probe for all selected ports (if false, finish after first successful scan)\"\n\tFlagHTTPProbeExitOnFailureUsage    = \"Exit when all HTTP probe commands fail\"\n\tFlagHTTPProbeCrawlUsage            = \"Enable crawling for the default HTTP probe command\"\n\tFlagHTTPCrawlMaxDepthUsage         = \"Max depth to use for the HTTP probe crawler\"\n\tFlagHTTPCrawlMaxPageCountUsage     = \"Max number of pages to visit for the HTTP probe crawler\"\n\tFlagHTTPCrawlConcurrencyUsage      = \"Number of concurrent workers when crawling an HTTP target\"\n\tFlagHTTPMaxConcurrentCrawlersUsage = \"Number of concurrent crawlers in the HTTP probe\"\n\tFlagHTTPProbeAPISpecUsage          = \"Run HTTP probes for API spec\"\n\tFlagHTTPProbeAPISpecFileUsage      = \"Run HTTP probes for API spec from file\"\n\tFlagHTTPProbeProxyEndpointUsage    = \"Endpoint to proxy HTTP probes\"\n\tFlagHTTPProbeProxyPortUsage        = \"Port to proxy HTTP probes (used with HTTP probe proxy endpoint)\"\n\n\tFlagHostExecUsage     = \"Host commands to execute (aka host commands probes)\"\n\tFlagHostExecFileUsage = \"Host commands to execute loaded from file (aka host commands probes)\"\n\n\tFlagPublishPortUsage         = \"Map container port to host port (format => port | hostPort:containerPort | hostIP:hostPort:containerPort | hostIP::containerPort )\"\n\tFlagPublishExposedPortsUsage = \"Map all exposed ports to the same host ports\"\n\n\tFlagRunTargetAsUserUsage   = \"Run target app as USER\"\n\tFlagShowContainerLogsUsage = \"Show container logs\"\n\tFlagEnableMondelLogsUsage  = \"Enable data event log for sensor monitors\"\n\n\tFlagUseLocalMountsUsage  = \"Mount local paths for target container artifact input and output\"\n\tFlagUseSensorVolumeUsage = \"Sensor volume name to use\"\n\tFlagContinueAfterUsage   = \"Select continue mode: enter | signal | probe | timeout-number-in-seconds | container.probe\"\n\n\tFlagRTAOnbuildBaseImageUsage = \"Enable runtime analysis for onbuild base images\"\n\tFlagRTASourcePTUsage         = \"Enable PTRACE runtime analysis source\"\n\n\tFlagSensorIPCEndpointUsage = \"Override sensor IPC endpoint\"\n\tFlagSensorIPCModeUsage     = \"Select sensor IPC mode: proxy | direct\"\n\n\tFlagExecUsage     = \"A shell script snippet to run via Docker exec\"\n\tFlagExecFileUsage = \"A shell script file to run via Docker exec\"\n\n\t//Container Run Options (for build, profile and run commands)\n\tFlagCRORuntimeUsage        = \"Runtime to use with the created containers\"\n\tFlagCROHostConfigFileUsage = \"Base Docker host configuration file (JSON format) to use when running the container\"\n\tFlagCROSysctlUsage         = \"Set namespaced kernel parameters in the created container\"\n\tFlagCROShmSizeUsage        = \"Shared memory size for /dev/shm in the created container\"\n\n\tFlagUserUsage               = \"Override USER analyzing image at runtime\"\n\tFlagEntrypointUsage         = \"Override ENTRYPOINT analyzing image at runtime. To persist ENTRYPOINT changes in the output image, pass the --image-overrides=entrypoint or --image-overrides=all flag as well.\"\n\tFlagCmdUsage                = \"Override CMD analyzing image at runtime. To persist CMD changes in the output image, pass the --image-overrides=cmd or --image-overrides=all flag as well.\"\n\tFlagWorkdirUsage            = \"Override WORKDIR analyzing image at runtime. To persist WORKDIR changes in the output image, pass the --image-overrides=workdir or --image-overrides=all flag as well.\"\n\tFlagEnvUsage                = \"Override or add ENV only during runtime. To persist ENV additions or changes in the output image, pass the --image-overrides=env or --image-overrides=all flag as well.\"\n\tFlagEnvFileUsage            = \"File to override or add ENV only during runtime. To persist ENV additions or changes in the output image, pass the --image-overrides=env or --image-overrides=all flag as well.\"\n\tFlagLabelUsage              = \"Override or add LABEL analyzing image at runtime. To persist LABEL additions or changes in the output image, pass the --image-overrides=label or --image-overrides=all flag as well.\"\n\tFlagVolumeUsage             = \"Add VOLUME analyzing image at runtime. To persist VOLUME additions in the output image, pass the --image-overrides=volume or --image-overrides=all flag as well.\"\n\tFlagExposeUsage             = \"Use additional EXPOSE instructions analyzing image at runtime. To persist EXPOSE additions in the output image, pass the --image-overrides=expose or --image-overrides=all flag as well.\"\n\tFlagLinkUsage               = \"Add link to another container analyzing image at runtime\"\n\tFlagNetworkUsage            = \"Override default container network settings analyzing image at runtime\"\n\tFlagHostnameUsage           = \"Override default container hostname analyzing image at runtime\"\n\tFlagEtcHostsMapUsage        = \"Add a host to IP mapping to /etc/hosts analyzing image at runtime\"\n\tFlagContainerDNSUsage       = \"Add a dns server analyzing image at runtime\"\n\tFlagContainerDNSSearchUsage = \"Add a dns search domain for unqualified hostnames analyzing image at runtime\"\n\tFlagMountUsage              = \"Mount volume analyzing image\"\n\tFlagDeleteFatImageUsage     = \"Delete generated fat image requires --dockerfile flag\"\n)\n\n///////////////////////////////////\n\nfunc GlobalFlags() []cli.Flag {\n\treturn []cli.Flag{\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagCommandReport,\n\t\t\tValue: \"slim.report.json\",\n\t\t\tUsage: \"command report location (enabled by default; set it to \\\"off\\\" to disable it)\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    FlagCheckVersion,\n\t\t\tValue:   true,\n\t\t\tUsage:   \"check if the current version is outdated\",\n\t\t\tEnvVars: []string{\"DSLIM_CHECK_VERSION\"},\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    FlagDebug,\n\t\t\tUsage:   FlagDebugUsage,\n\t\t\tEnvVars: []string{\"DSLIM_DEBUG\"},\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    FlagVerbose,\n\t\t\tUsage:   \"enable info logs\",\n\t\t\tEnvVars: []string{\"DSLIM_VERBOSE\"},\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    FlagQuietCLIMode,\n\t\t\tUsage:   FlagQuietCLIModeUsage,\n\t\t\tEnvVars: []string{\"DSLIM_QUIET\"},\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:    FlagLogLevel,\n\t\t\tValue:   \"warn\",\n\t\t\tUsage:   \"set the logging level ('debug', 'info', 'warn' (default), 'error', 'fatal', 'panic')\",\n\t\t\tEnvVars: []string{\"DSLIM_LOG_LEVEL\"},\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagLog,\n\t\t\tUsage: \"log file to store logs\",\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagLogFormat,\n\t\t\tValue: \"text\",\n\t\t\tUsage: \"set the format used by logs ('text' (default), or 'json')\",\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagOutputFormat,\n\t\t\tValue: \"text\",\n\t\t\tUsage: FlagOutputFormatUsage,\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:  FlagUseTLS,\n\t\t\tValue: true,\n\t\t\tUsage: \"use TLS\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:  FlagVerifyTLS,\n\t\t\tValue: true,\n\t\t\tUsage: \"verify TLS\",\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagTLSCertPath,\n\t\t\tValue: \"\",\n\t\t\tUsage: FlagTLSCertPathUsage,\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:    FlagAPIVersion,\n\t\t\tValue:   \"1.25\", // We need at least 1.25 for to support builds from Dockerfile.\n\t\t\tUsage:   FlagAPIVersionUsage,\n\t\t\tEnvVars: []string{\"DSLIM_CRT_API_VER\"},\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagHost,\n\t\t\tValue: \"\",\n\t\t\tUsage: \"Docker host address\",\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagStatePath,\n\t\t\tValue: \"\",\n\t\t\tUsage: \"app state base path\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:  FlagInContainer,\n\t\t\tUsage: \"app is running in a container\",\n\t\t},\n\t\t&cli.StringFlag{\n\t\t\tName:  FlagArchiveState,\n\t\t\tValue: \"\",\n\t\t\tUsage: \"archive app state to the selected Docker volume (default volume - slim-state). By default, enabled when app is running in a container (disabled otherwise). Set it to \\\"off\\\" to disable explicitly.\",\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:  FlagNoColor,\n\t\t\tUsage: FlagNoColorUsage,\n\t\t},\n\t}\n}\n\nvar CommonFlags = map[string]cli.Flag{\n\tFlagCommandParamsFile: &cli.StringFlag{\n\t\tName:    FlagCommandParamsFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCommandParamsFileUsage,\n\t\tEnvVars: []string{\"DSLIM_COMMAND_PARAMS_FILE\"},\n\t},\n\tFlagTarget: &cli.StringFlag{\n\t\tName:    FlagTarget,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET\"},\n\t},\n\tFlagPull: &cli.BoolFlag{\n\t\tName:    FlagPull,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagPullUsage,\n\t\tEnvVars: []string{\"DSLIM_PULL\"},\n\t},\n\tFlagDockerConfigPath: &cli.StringFlag{\n\t\tName:    FlagDockerConfigPath,\n\t\tUsage:   FlagDockerConfigPathUsage,\n\t\tEnvVars: []string{\"DSLIM_DOCKER_CONFIG_PATH\"},\n\t},\n\tFlagRegistryAccount: &cli.StringFlag{\n\t\tName:    FlagRegistryAccount,\n\t\tUsage:   FlagRegistryAccountUsage,\n\t\tEnvVars: []string{\"DSLIM_REGISTRY_ACCOUNT\"},\n\t},\n\tFlagRegistrySecret: &cli.StringFlag{\n\t\tName:    FlagRegistrySecret,\n\t\tUsage:   FlagRegistrySecretUsage,\n\t\tEnvVars: []string{\"DSLIM_REGISTRY_SECRET\"},\n\t},\n\tFlagShowPullLogs: &cli.BoolFlag{\n\t\tName:    FlagShowPullLogs,\n\t\tUsage:   FlagShowPullLogsUsage,\n\t\tEnvVars: []string{\"DSLIM_PLOG\"},\n\t},\n\t//\n\tFlagComposeFile: &cli.StringSliceFlag{\n\t\tName:    FlagComposeFile,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagComposeFileUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_FILE\"},\n\t},\n\tFlagTargetComposeSvc: &cli.StringFlag{\n\t\tName:    FlagTargetComposeSvc,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetComposeSvcUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_COMPOSE_SVC\"},\n\t},\n\tFlagTargetComposeSvcImage: &cli.StringFlag{\n\t\tName:    FlagTargetComposeSvcImage,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetComposeSvcImageUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_COMPOSE_SVC_IMAGE\"},\n\t},\n\tFlagComposeSvcStartWait: &cli.IntFlag{\n\t\tName:    FlagComposeSvcStartWait,\n\t\tValue:   0,\n\t\tUsage:   FlagComposeSvcStartWaitUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_SVC_START_WAIT\"},\n\t},\n\tFlagComposeSvcNoPorts: &cli.BoolFlag{\n\t\tName:    FlagComposeSvcNoPorts,\n\t\tUsage:   FlagComposeSvcNoPortsUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_SVC_NO_PORTS\"},\n\t},\n\tFlagDepExcludeComposeSvcAll: &cli.BoolFlag{\n\t\tName:    FlagDepExcludeComposeSvcAll,\n\t\tUsage:   FlagDepExcludeComposeSvcAllUsage,\n\t\tEnvVars: []string{\"DSLIM_DEP_INCLUDE_COMPOSE_SVC_ALL\"},\n\t},\n\tFlagDepIncludeComposeSvcDeps: &cli.StringFlag{\n\t\tName:    FlagDepIncludeComposeSvcDeps,\n\t\tValue:   \"\",\n\t\tUsage:   FlagDepIncludeComposeSvcDepsUsage,\n\t\tEnvVars: []string{\"DSLIM_DEP_INCLUDE_COMPOSE_SVC_DEPS\"},\n\t},\n\tFlagDepIncludeComposeSvc: &cli.StringSliceFlag{\n\t\tName:    FlagDepIncludeComposeSvc,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagDepIncludeComposeSvcUsage,\n\t\tEnvVars: []string{\"DSLIM_DEP_INCLUDE_COMPOSE_SVC\"},\n\t},\n\tFlagDepExcludeComposeSvc: &cli.StringSliceFlag{\n\t\tName:    FlagDepExcludeComposeSvc,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagDepExcludeComposeSvcUsage,\n\t\tEnvVars: []string{\"DSLIM_DEP_EXCLUDE_COMPOSE_SVC\"},\n\t},\n\tFlagComposeNet: &cli.StringSliceFlag{\n\t\tName:    FlagComposeNet,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagComposeNetUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_NET\"},\n\t},\n\tFlagDepIncludeTargetComposeSvcDeps: &cli.BoolFlag{\n\t\tName:    FlagDepIncludeTargetComposeSvcDeps,\n\t\tUsage:   FlagDepIncludeTargetComposeSvcDepsUsage,\n\t\tEnvVars: []string{\"DSLIM_DEP_INCLUDE_TARGET_COMPOSE_SVC_DEPS\"},\n\t},\n\tFlagComposeEnvNoHost: &cli.BoolFlag{\n\t\tName:    FlagComposeEnvNoHost,\n\t\tUsage:   FlagComposeEnvNoHostUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_ENV_NOHOST\"},\n\t},\n\tFlagComposeEnvFile: &cli.StringFlag{\n\t\tName:    FlagComposeEnvFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagComposeEnvFileUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_ENV_FILE\"},\n\t},\n\tFlagComposeProjectName: &cli.StringFlag{\n\t\tName:    FlagComposeProjectName,\n\t\tValue:   \"\",\n\t\tUsage:   FlagComposeProjectNameUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_PROJECT_NAME\"},\n\t},\n\tFlagComposeWorkdir: &cli.StringFlag{\n\t\tName:    FlagComposeWorkdir,\n\t\tValue:   \"\",\n\t\tUsage:   FlagComposeWorkdirUsage,\n\t\tEnvVars: []string{\"DSLIM_COMPOSE_WORKDIR\"},\n\t},\n\tFlagContainerProbeComposeSvc: &cli.StringFlag{\n\t\tName:    FlagContainerProbeComposeSvc,\n\t\tValue:   \"\",\n\t\tUsage:   FlagContainerProbeComposeSvcUsage,\n\t\tEnvVars: []string{\"DSLIM_CONTAINER_PROBE_COMPOSE_SVC\"},\n\t},\n\tFlagPrestartComposeSvc: &cli.StringSliceFlag{\n\t\tName:    FlagPrestartComposeSvc,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagPrestartComposeSvcUsage,\n\t\tEnvVars: []string{\"DSLIM_PRESTART_COMPOSE_SVC\"},\n\t},\n\tFlagPrestartComposeWaitExit: &cli.BoolFlag{\n\t\tName:    FlagPrestartComposeWaitExit,\n\t\tUsage:   FlagPrestartComposeWaitExitUsage,\n\t\tEnvVars: []string{\"DSLIM_PRESTART_COMPOSE_WAIT\"},\n\t},\n\tFlagPoststartComposeSvc: &cli.StringSliceFlag{\n\t\tName:    FlagPoststartComposeSvc,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagPoststartComposeSvcUsage,\n\t\tEnvVars: []string{\"DSLIM_POSTSTART_COMPOSE_SVC\"},\n\t},\n\t//\n\tFlagTargetKubeWorkload: &cli.StringFlag{\n\t\tName:    FlagTargetKubeWorkload,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetKubeWorkloadUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_KUBE_WORKLOAD\"},\n\t},\n\tFlagTargetKubeWorkloadNamespace: &cli.StringFlag{\n\t\tName:    FlagTargetKubeWorkloadNamespace,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetKubeWorkloadNamespaceUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_KUBE_WORKLOAD_NAMESPACE\"},\n\t},\n\tFlagTargetKubeWorkloadContainer: &cli.StringFlag{\n\t\tName:    FlagTargetKubeWorkloadContainer,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetKubeWorkloadContainerUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_KUBE_WORKLOAD_CONTAINER\"},\n\t},\n\tFlagTargetKubeWorkloadImage: &cli.StringFlag{\n\t\tName:    FlagTargetKubeWorkloadImage,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetKubeWorkloadImageUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_KUBE_WORKLOAD_IMAGE\"},\n\t},\n\tFlagKubeManifestFile: &cli.StringSliceFlag{\n\t\tName:    FlagKubeManifestFile,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagKubeManifestFileUsage,\n\t\tEnvVars: []string{\"DSLIM_KUBE_MANIFEST_FILE\"},\n\t},\n\tFlagKubeKubeconfigFile: &cli.StringFlag{\n\t\tName:  FlagKubeKubeconfigFile,\n\t\tValue: clientcmd.RecommendedHomeFile,\n\t\tUsage: FlagKubeKubeconfigFileUsage,\n\t\tEnvVars: []string{\n\t\t\t\"DSLIM_KUBE_KUBECONFIG_FILE\",\n\t\t\t\"KUBECONFIG\", // subject to an industry-wide convention\n\t\t},\n\t},\n\t//\n\tFlagRemoveFileArtifacts: &cli.BoolFlag{\n\t\tName:    FlagRemoveFileArtifacts,\n\t\tUsage:   FlagRemoveFileArtifactsUsage,\n\t\tEnvVars: []string{\"DSLIM_RM_FILE_ARTIFACTS\"},\n\t},\n\tFlagCopyMetaArtifacts: &cli.StringFlag{\n\t\tName:    FlagCopyMetaArtifacts,\n\t\tUsage:   FlagCopyMetaArtifactsUsage,\n\t\tEnvVars: []string{\"DSLIM_CP_META_ARTIFACTS\"},\n\t},\n\t//\n\tFlagHTTPProbe: &cli.BoolFlag{ //true by default\n\t\tName:    FlagHTTPProbe,\n\t\tValue:   true,\n\t\tUsage:   FlagHTTPProbeUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE\"},\n\t},\n\tFlagHTTPProbeOff: &cli.BoolFlag{\n\t\tName:    FlagHTTPProbeOff,\n\t\tUsage:   FlagHTTPProbeOffUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_OFF\"},\n\t},\n\tFlagHTTPProbeCmd: &cli.StringSliceFlag{\n\t\tName:    FlagHTTPProbeCmd,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagHTTPProbeCmdUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_CMD\"},\n\t},\n\tFlagHTTPProbeCmdFile: &cli.StringFlag{\n\t\tName:    FlagHTTPProbeCmdFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagHTTPProbeCmdFileUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_CMD_FILE\"},\n\t},\n\tFlagHTTPProbeAPISpec: &cli.StringSliceFlag{\n\t\tName:    FlagHTTPProbeAPISpec,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagHTTPProbeAPISpecUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_API_SPEC\"},\n\t},\n\tFlagHTTPProbeAPISpecFile: &cli.StringSliceFlag{\n\t\tName:    FlagHTTPProbeAPISpecFile,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagHTTPProbeAPISpecFileUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_API_SPEC_FILE\"},\n\t},\n\tFlagHTTPProbeStartWait: &cli.IntFlag{\n\t\tName:    FlagHTTPProbeStartWait,\n\t\tValue:   0,\n\t\tUsage:   FlagHTTPProbeStartWaitUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_START_WAIT\"},\n\t},\n\tFlagHTTPProbeRetryCount: &cli.IntFlag{\n\t\tName:    FlagHTTPProbeRetryCount,\n\t\tValue:   5,\n\t\tUsage:   FlagHTTPProbeRetryCountUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_RETRY_COUNT\"},\n\t},\n\tFlagHTTPProbeRetryWait: &cli.IntFlag{\n\t\tName:    FlagHTTPProbeRetryWait,\n\t\tValue:   8,\n\t\tUsage:   FlagHTTPProbeRetryWaitUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_RETRY_WAIT\"},\n\t},\n\tFlagHTTPProbePorts: &cli.StringFlag{\n\t\tName:    FlagHTTPProbePorts,\n\t\tValue:   \"\",\n\t\tUsage:   FlagHTTPProbePortsUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_PORTS\"},\n\t},\n\tFlagHTTPProbeFull: &cli.BoolFlag{\n\t\tName:    FlagHTTPProbeFull,\n\t\tUsage:   FlagHTTPProbeFullUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_FULL\"},\n\t},\n\tFlagHTTPProbeExitOnFailure: &cli.BoolFlag{ //true by default now\n\t\tName:    FlagHTTPProbeExitOnFailure,\n\t\tValue:   true,\n\t\tUsage:   FlagHTTPProbeExitOnFailureUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_EXIT_ON_FAILURE\"},\n\t},\n\tFlagHTTPProbeCrawl: &cli.BoolFlag{\n\t\tName:    FlagHTTPProbeCrawl,\n\t\tValue:   true,\n\t\tUsage:   FlagHTTPProbeCrawl,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_CRAWL\"},\n\t},\n\tFlagHTTPCrawlMaxDepth: &cli.IntFlag{\n\t\tName:    FlagHTTPCrawlMaxDepth,\n\t\tValue:   3,\n\t\tUsage:   FlagHTTPCrawlMaxDepthUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_CRAWL_MAX_DEPTH\"},\n\t},\n\tFlagHTTPCrawlMaxPageCount: &cli.IntFlag{\n\t\tName:    FlagHTTPCrawlMaxPageCount,\n\t\tValue:   1000,\n\t\tUsage:   FlagHTTPCrawlMaxPageCountUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_CRAWL_MAX_PAGE_COUNT\"},\n\t},\n\tFlagHTTPCrawlConcurrency: &cli.IntFlag{\n\t\tName:    FlagHTTPCrawlConcurrency,\n\t\tValue:   10,\n\t\tUsage:   FlagHTTPCrawlConcurrencyUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_CRAWL_CONCURRENCY\"},\n\t},\n\tFlagHTTPMaxConcurrentCrawlers: &cli.IntFlag{\n\t\tName:    FlagHTTPMaxConcurrentCrawlers,\n\t\tValue:   1,\n\t\tUsage:   FlagHTTPMaxConcurrentCrawlersUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_MAX_CONCURRENT_CRAWLERS\"},\n\t},\n\tFlagHTTPProbeProxyEndpoint: &cli.StringFlag{\n\t\tName:    FlagHTTPProbeProxyEndpoint,\n\t\tValue:   \"\",\n\t\tUsage:   FlagHTTPProbeProxyEndpointUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_PROXY_ENDPOINT\"},\n\t},\n\tFlagHTTPProbeProxyPort: &cli.IntFlag{\n\t\tName:    FlagHTTPProbeProxyPort,\n\t\tValue:   0,\n\t\tUsage:   FlagHTTPProbeProxyPortUsage,\n\t\tEnvVars: []string{\"DSLIM_HTTP_PROBE_PROXY_PORT\"},\n\t},\n\tFlagHostExec: &cli.StringSliceFlag{\n\t\tName:    FlagHostExec,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagHostExecUsage,\n\t\tEnvVars: []string{\"DSLIM_HOST_EXEC\"},\n\t},\n\tFlagHostExecFile: &cli.StringFlag{\n\t\tName:    FlagHostExecFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagHostExecFileUsage,\n\t\tEnvVars: []string{\"DSLIM_HOST_EXEC_FILE\"},\n\t},\n\tFlagPublishPort: &cli.StringSliceFlag{\n\t\tName:    FlagPublishPort,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagPublishPortUsage,\n\t\tEnvVars: []string{\"DSLIM_PUBLISH_PORT\"},\n\t},\n\tFlagPublishExposedPorts: &cli.BoolFlag{\n\t\tName:    FlagPublishExposedPorts,\n\t\tUsage:   FlagPublishExposedPortsUsage,\n\t\tEnvVars: []string{\"DSLIM_PUBLISH_EXPOSED\"},\n\t},\n\tFlagRunTargetAsUser: &cli.BoolFlag{\n\t\tName:    FlagRunTargetAsUser,\n\t\tValue:   true,\n\t\tUsage:   FlagRunTargetAsUserUsage,\n\t\tEnvVars: []string{\"DSLIM_RUN_TAS_USER\"},\n\t},\n\tFlagShowContainerLogs: &cli.BoolFlag{\n\t\tName:    FlagShowContainerLogs,\n\t\tUsage:   FlagShowContainerLogsUsage,\n\t\tEnvVars: []string{\"DSLIM_SHOW_CLOGS\"},\n\t},\n\tFlagEnableMondelLogs: &cli.BoolFlag{\n\t\tName:    FlagEnableMondelLogs,\n\t\tUsage:   FlagEnableMondelLogsUsage,\n\t\tEnvVars: []string{\"DSLIM_ENABLE_MONDEL\"},\n\t},\n\tFlagSensorIPCMode: &cli.StringFlag{\n\t\tName:    FlagSensorIPCMode,\n\t\tValue:   \"\",\n\t\tUsage:   FlagSensorIPCModeUsage,\n\t\tEnvVars: []string{\"DSLIM_SENSOR_IPC_MODE\"},\n\t},\n\tFlagSensorIPCEndpoint: &cli.StringFlag{\n\t\tName:    FlagSensorIPCEndpoint,\n\t\tValue:   \"\",\n\t\tUsage:   FlagSensorIPCEndpointUsage,\n\t\tEnvVars: []string{\"DSLIM_SENSOR_IPC_ENDPOINT\"},\n\t},\n\tFlagExec: &cli.StringFlag{\n\t\tName:    FlagExec,\n\t\tValue:   \"\",\n\t\tUsage:   FlagExecUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_EXE\"},\n\t},\n\tFlagExecFile: &cli.StringFlag{\n\t\tName:    FlagExecFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagExecFileUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_EXE_FILE\"},\n\t},\n\tFlagUseLocalMounts: &cli.BoolFlag{\n\t\tName:    FlagUseLocalMounts,\n\t\tUsage:   FlagUseLocalMountsUsage,\n\t\tEnvVars: []string{\"DSLIM_USE_LOCAL_MOUNTS\"},\n\t},\n\tFlagUseSensorVolume: &cli.StringFlag{\n\t\tName:    FlagUseSensorVolume,\n\t\tValue:   \"\",\n\t\tUsage:   FlagUseSensorVolumeUsage,\n\t\tEnvVars: []string{\"DSLIM_USE_SENSOR_VOLUME\"},\n\t},\n\tFlagContinueAfter: &cli.StringFlag{\n\t\tName:    FlagContinueAfter,\n\t\tValue:   \"probe\",\n\t\tUsage:   FlagContinueAfterUsage,\n\t\tEnvVars: []string{\"DSLIM_CONTINUE_AFTER\"},\n\t},\n\t//Container Run Options\n\tFlagCRORuntime: &cli.StringFlag{\n\t\tName:    FlagCRORuntime,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCRORuntimeUsage,\n\t\tEnvVars: []string{\"DSLIM_CRO_RUNTIME\"},\n\t},\n\tFlagCROHostConfigFile: &cli.StringFlag{\n\t\tName:    FlagCROHostConfigFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCROHostConfigFileUsage,\n\t\tEnvVars: []string{\"DSLIM_CRO_HOST_CONFIG_FILE\"},\n\t},\n\tFlagCROSysctl: &cli.StringSliceFlag{\n\t\tName:    FlagCROSysctl,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagCROSysctlUsage,\n\t\tEnvVars: []string{\"DSLIM_CRO_SYSCTL\"},\n\t},\n\tFlagCROShmSize: &cli.Int64Flag{\n\t\tName:    FlagCROShmSize,\n\t\tValue:   -1,\n\t\tUsage:   FlagCROShmSizeUsage,\n\t\tEnvVars: []string{\"DSLIM_CRO_SHM_SIZE\"},\n\t},\n\tFlagUser: &cli.StringFlag{\n\t\tName:    FlagUser,\n\t\tValue:   \"\",\n\t\tUsage:   FlagUserUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_USER\"},\n\t},\n\tFlagEntrypoint: &cli.StringFlag{\n\t\tName:    FlagEntrypoint,\n\t\tValue:   \"\",\n\t\tUsage:   FlagEntrypointUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_ENTRYPOINT\"},\n\t},\n\tFlagCmd: &cli.StringFlag{\n\t\tName:    FlagCmd,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCmdUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_CMD\"},\n\t},\n\tFlagWorkdir: &cli.StringFlag{\n\t\tName:    FlagWorkdir,\n\t\tValue:   \"\",\n\t\tUsage:   FlagWorkdirUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_WORKDIR\"},\n\t},\n\tFlagEnv: &cli.StringSliceFlag{\n\t\tName:    FlagEnv,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagEnvUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_ENV\"},\n\t},\n\tFlagEnvFile: &cli.StringFlag{\n\t\tName:    FlagEnvFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagEnvFileUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_ENV_FILE\"},\n\t},\n\tFlagLabel: &cli.StringSliceFlag{\n\t\tName:    FlagLabel,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagLabelUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_LABEL\"},\n\t},\n\tFlagVolume: &cli.StringSliceFlag{\n\t\tName:    FlagVolume,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagVolumeUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_VOLUME\"},\n\t},\n\tFlagLink: &cli.StringSliceFlag{\n\t\tName:    FlagLink,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagLinkUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_LINK\"},\n\t},\n\tFlagEtcHostsMap: &cli.StringSliceFlag{\n\t\tName:    FlagEtcHostsMap,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagEtcHostsMapUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_ETC_HOSTS_MAP\"},\n\t},\n\tFlagContainerDNS: &cli.StringSliceFlag{\n\t\tName:    FlagContainerDNS,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagContainerDNSUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_DNS\"},\n\t},\n\tFlagContainerDNSSearch: &cli.StringSliceFlag{\n\t\tName:    FlagContainerDNSSearch,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagContainerDNSSearchUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_DNS_SEARCH\"},\n\t},\n\tFlagHostname: &cli.StringFlag{\n\t\tName:    FlagHostname,\n\t\tValue:   \"\",\n\t\tUsage:   FlagHostnameUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_HOSTNAME\"},\n\t},\n\tFlagNetwork: &cli.StringFlag{\n\t\tName:    FlagNetwork,\n\t\tValue:   \"\",\n\t\tUsage:   FlagNetworkUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_NET\"},\n\t},\n\tFlagExpose: &cli.StringSliceFlag{\n\t\tName:    FlagExpose,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagExposeUsage,\n\t\tEnvVars: []string{\"DSLIM_RC_EXPOSE\"},\n\t},\n\tFlagMount: &cli.StringSliceFlag{\n\t\tName:    FlagMount,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagMountUsage,\n\t\tEnvVars: []string{\"DSLIM_MOUNT\"},\n\t},\n\tFlagDeleteFatImage: &cli.BoolFlag{\n\t\tName:    FlagDeleteFatImage,\n\t\tUsage:   FlagDeleteFatImageUsage,\n\t\tEnvVars: []string{\"DSLIM_DELETE_FAT\"},\n\t},\n\tFlagRTAOnbuildBaseImage: &cli.BoolFlag{ //should be disabled by default\n\t\tName:    FlagRTAOnbuildBaseImage,\n\t\tUsage:   FlagRTAOnbuildBaseImageUsage,\n\t\tEnvVars: []string{\"DSLIM_RTA_ONBUILD_BI\"},\n\t},\n\tFlagRTASourcePT: &cli.BoolFlag{\n\t\tName:    FlagRTASourcePT,\n\t\tValue:   true, //all sources are enabled by default\n\t\tUsage:   FlagRTASourcePTUsage,\n\t\tEnvVars: []string{\"DSLIM_RTA_SRC_PT\"},\n\t},\n}\n\n//var CommonFlags\n\nfunc Cflag(name string) cli.Flag {\n\tcf, ok := CommonFlags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"commands.Cflag: unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n\nfunc HTTPProbeFlags() []cli.Flag {\n\treturn append([]cli.Flag{\n\t\tCflag(FlagHTTPProbeOff),\n\t\tCflag(FlagHTTPProbe),\n\t\tCflag(FlagHTTPProbeExitOnFailure),\n\t}, HTTPProbeFlagsBasic()...)\n}\n\nfunc HTTPProbeFlagsBasic() []cli.Flag {\n\treturn []cli.Flag{\n\t\tCflag(FlagHTTPProbeCmd),\n\t\tCflag(FlagHTTPProbeCmdFile),\n\t\tCflag(FlagHTTPProbeStartWait),\n\t\tCflag(FlagHTTPProbeRetryCount),\n\t\tCflag(FlagHTTPProbeRetryWait),\n\t\tCflag(FlagHTTPProbePorts),\n\t\tCflag(FlagHTTPProbeFull),\n\t\tCflag(FlagHTTPProbeCrawl),\n\t\tCflag(FlagHTTPCrawlMaxDepth),\n\t\tCflag(FlagHTTPCrawlMaxPageCount),\n\t\tCflag(FlagHTTPCrawlConcurrency),\n\t\tCflag(FlagHTTPMaxConcurrentCrawlers),\n\t\tCflag(FlagHTTPProbeAPISpec),\n\t\tCflag(FlagHTTPProbeAPISpecFile),\n\t}\n}\n\n///////////////////////////////////\n\n// Update command flag names\nconst (\n\tFlagShowProgress = \"show-progress\"\n)\n\n// Update command flag usage info\nconst (\n\tFlagShowProgressUsage = \"show progress when the release package is downloaded\"\n)\n"
  },
  {
    "path": "pkg/app/master/command/clifvgetter.go",
    "content": "package command\n\n//Flag value getters\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/signals\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n)\n\nfunc GetContainerRunOptions(ctx *cli.Context) (*config.ContainerRunOptions, error) {\n\tconst op = \"commands.GetContainerRunOptions\"\n\tvar cro config.ContainerRunOptions\n\tcro.Runtime = ctx.String(FlagCRORuntime)\n\tsysctlList := ctx.StringSlice(FlagCROSysctl)\n\tif len(sysctlList) > 0 {\n\t\tparams, err := ParseTokenMap(sysctlList)\n\t\tif err != nil {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":    op,\n\t\t\t\t\"error\": err,\n\t\t\t}).Error(\"invalid sysctl options\")\n\t\t\treturn nil, err\n\t\t}\n\n\t\tcro.SysctlParams = params\n\t}\n\thostConfigFileName := ctx.String(FlagCROHostConfigFile)\n\tif len(hostConfigFileName) > 0 {\n\t\thostConfigBytes, err := os.ReadFile(hostConfigFileName)\n\t\tif err != nil {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":        op,\n\t\t\t\t\"file.name\": hostConfigFileName,\n\t\t\t\t\"error\":     err,\n\t\t\t}).Error(\"could not read host config file\")\n\t\t\treturn nil, err\n\t\t}\n\t\tjson.Unmarshal(hostConfigBytes, &cro.HostConfig)\n\t}\n\n\tcro.ShmSize = ctx.Int64(FlagCROShmSize)\n\treturn &cro, nil\n}\n\nfunc GetHTTPProbeOptions(xc *app.ExecutionContext, ctx *cli.Context, doProbe bool) config.HTTPProbeOptions {\n\topts := config.HTTPProbeOptions{\n\t\tFull: ctx.Bool(FlagHTTPProbeFull),\n\n\t\tStartWait:  ctx.Int(FlagHTTPProbeStartWait),\n\t\tRetryCount: ctx.Int(FlagHTTPProbeRetryCount),\n\t\tRetryWait:  ctx.Int(FlagHTTPProbeRetryWait),\n\n\t\tCrawlMaxDepth:       ctx.Int(FlagHTTPCrawlMaxDepth),\n\t\tCrawlMaxPageCount:   ctx.Int(FlagHTTPCrawlMaxPageCount),\n\t\tCrawlConcurrency:    ctx.Int(FlagHTTPCrawlConcurrency),\n\t\tCrawlConcurrencyMax: ctx.Int(FlagHTTPMaxConcurrentCrawlers),\n\t}\n\n\tif doProbe {\n\t\topts.Do = true\n\t} else {\n\t\topts.Do = ctx.Bool(FlagHTTPProbe) && !ctx.Bool(FlagHTTPProbeOff)\n\t\topts.ExitOnFailure = ctx.Bool(FlagHTTPProbeExitOnFailure)\n\t}\n\n\tcmds, err := GetHTTPProbes(ctx)\n\tif err != nil {\n\t\txc.Out.Error(\"param.http.probe\", err.Error())\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": -1,\n\t\t\t})\n\t\txc.Exit(-1)\n\t}\n\topts.Cmds = cmds\n\n\tif opts.Do && len(opts.Cmds) == 0 {\n\t\t//add default probe cmd if the \"http-probe\" flag is set\n\t\t//but only if there are no custom http probe commands\n\t\txc.Out.Info(\"param.http.probe\",\n\t\t\tovars{\n\t\t\t\t\"message\": \"using default probe\",\n\t\t\t})\n\n\t\topts.Cmds = append(opts.Cmds, GetDefaultHTTPProbe())\n\n\t\tif ctx.Bool(FlagHTTPProbeCrawl) {\n\t\t\topts.Cmds[0].Crawl = true\n\t\t}\n\t}\n\n\tif len(opts.Cmds) > 0 {\n\t\topts.Do = true\n\t}\n\n\tports, err := ParseHTTPProbesPorts(ctx.String(FlagHTTPProbePorts))\n\tif err != nil {\n\t\txc.Out.Error(\"param.http.probe.ports\", err.Error())\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": -1,\n\t\t\t})\n\t\txc.Exit(-1)\n\t}\n\topts.Ports = ports\n\n\topts.APISpecs = ctx.StringSlice(FlagHTTPProbeAPISpec)\n\tapiSpecFiles, fileErrors := ValidateFiles(ctx.StringSlice(FlagHTTPProbeAPISpecFile))\n\tif len(fileErrors) > 0 {\n\t\tfor k, v := range fileErrors {\n\t\t\terr = v\n\t\t\txc.Out.Info(\"error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"file\":  k,\n\t\t\t\t\t\"error\": err,\n\t\t\t\t})\n\n\t\t\txc.Out.Error(\"param.error.http.api.spec.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\t}\n\topts.APISpecFiles = apiSpecFiles\n\n\tif len(opts.APISpecs)+len(opts.APISpecFiles) > 0 {\n\t\topts.Do = true\n\t}\n\n\treturn opts\n}\n\nfunc GetDefaultHTTPProbe() config.HTTPProbeCmd {\n\treturn config.HTTPProbeCmd{\n\t\tProtocol: \"http\",\n\t\tMethod:   \"GET\",\n\t\tResource: \"/\",\n\t}\n}\n\nfunc GetHTTPProbes(ctx *cli.Context) ([]config.HTTPProbeCmd, error) {\n\thttpProbeCmds, err := ParseHTTPProbes(ctx.StringSlice(FlagHTTPProbeCmd))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmoreHTTPProbeCmds, err := ParseHTTPProbesFile(ctx.String(FlagHTTPProbeCmdFile))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif moreHTTPProbeCmds != nil {\n\t\thttpProbeCmds = append(httpProbeCmds, moreHTTPProbeCmds...)\n\t}\n\n\treturn httpProbeCmds, nil\n}\n\nfunc GetContinueAfter(ctx *cli.Context) (*config.ContinueAfter, error) {\n\tinfo := &config.ContinueAfter{\n\t\tMode: config.CAMEnter,\n\t}\n\n\tdoContinueAfter := ctx.String(FlagContinueAfter)\n\tswitch doContinueAfter {\n\tcase config.CAMEnter:\n\t\tinfo.Mode = config.CAMEnter\n\tcase config.CAMSignal:\n\t\tinfo.Mode = config.CAMSignal\n\t\tinfo.ContinueChan = signals.AppContinueChan\n\tcase config.CAMProbe:\n\t\tinfo.Mode = config.CAMProbe\n\tcase config.CAMExec:\n\t\tinfo.Mode = config.CAMExec\n\tcase config.CAMContainerProbe:\n\t\tinfo.Mode = config.CAMContainerProbe\n\tcase config.CAMHostExec:\n\t\tinfo.Mode = config.CAMHostExec\n\tcase config.CAMAppExit:\n\t\tinfo.Mode = config.CAMAppExit\n\tcase config.CAMTimeout:\n\t\tinfo.Mode = config.CAMTimeout\n\t\tinfo.Timeout = 60\n\tdefault:\n\t\tmodes := strings.Split(doContinueAfter, \"&\")\n\t\tif len(modes) > 1 {\n\t\t\t//not supporting combining signal or custom timeout modes with other modes\n\t\t\tinfo.Mode = doContinueAfter\n\t\t} else {\n\t\t\tif waitTime, err := strconv.Atoi(doContinueAfter); err == nil && waitTime > 0 {\n\t\t\t\tinfo.Mode = config.CAMTimeout\n\t\t\t\tinfo.Timeout = time.Duration(waitTime)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn info, nil\n}\n\nfunc RemoveContinueAfterMode(continueAfter, mode string) string {\n\tif continueAfter == mode {\n\t\treturn \"\"\n\t}\n\n\tvar result []string\n\tmodes := strings.Split(continueAfter, \"&\")\n\tfor _, current := range modes {\n\t\tif current != mode {\n\t\t\tresult = append(result, mode)\n\t\t}\n\t}\n\n\treturn strings.Join(modes, \"&\")\n}\n\nfunc GetContinueAfterModeNames(continueAfter string) []string {\n\treturn strings.Split(continueAfter, \"&\")\n}\n\nfunc GetContainerOverrides(xc *app.ExecutionContext, ctx *cli.Context) (*config.ContainerOverrides, error) {\n\tconst op = \"commands.GetContainerOverrides\"\n\n\tdoUseEntrypoint := ctx.String(FlagEntrypoint)\n\tdoUseCmd := ctx.String(FlagCmd)\n\texposePortList := ctx.StringSlice(FlagExpose)\n\n\tvolumesList := ctx.StringSlice(FlagVolume)\n\tlabelsList := ctx.StringSlice(FlagLabel)\n\tenvList, envErr := ParseEnvFile(ctx.String(FlagEnvFile))\n\tif envErr != nil {\n\t\treturn nil, envErr\n\t}\n\tenvList = validateAndCleanEnvVariables(xc, envList, \"param.env-file.value\")\n\tenv := validateAndCleanEnvVariables(xc, ctx.StringSlice(FlagEnv), \"param.env\")\n\tenvList = append(envList, env...)\n\toverrides := &config.ContainerOverrides{\n\t\tUser:     ctx.String(FlagUser),\n\t\tWorkdir:  ctx.String(FlagWorkdir),\n\t\tEnv:      envList,\n\t\tNetwork:  ctx.String(FlagNetwork),\n\t\tHostname: ctx.String(FlagHostname),\n\t}\n\n\tvar err error\n\tif len(exposePortList) > 0 {\n\t\toverrides.ExposedPorts, err = ParseDockerExposeOpt(exposePortList)\n\t\tif err != nil {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":    op,\n\t\t\t\t\"error\": err,\n\t\t\t}).Error(\"invalid expose options\")\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif len(volumesList) > 0 {\n\t\tvolumes, err := ParseTokenSet(volumesList)\n\t\tif err != nil {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":    op,\n\t\t\t\t\"error\": err,\n\t\t\t}).Error(\"invalid volume options\")\n\t\t\treturn nil, err\n\t\t}\n\n\t\toverrides.Volumes = volumes\n\t}\n\n\tif len(labelsList) > 0 {\n\t\tlabels, err := ParseTokenMap(labelsList)\n\t\tif err != nil {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":    op,\n\t\t\t\t\"error\": err,\n\t\t\t}).Error(\"invalid label options\")\n\t\t\treturn nil, err\n\t\t}\n\n\t\toverrides.Labels = labels\n\t}\n\n\toverrides.Entrypoint, err = ParseExec(doUseEntrypoint)\n\tif err != nil {\n\t\tlog.WithFields(log.Fields{\n\t\t\t\"op\":    op,\n\t\t\t\"error\": err,\n\t\t}).Error(\"invalid entrypoint option\")\n\t\treturn nil, err\n\t}\n\n\t//TODO: use a '--no-entrypoint' flag instead of this one space hack\n\toverrides.ClearEntrypoint = IsOneSpace(doUseEntrypoint)\n\n\toverrides.Cmd, err = ParseExec(doUseCmd)\n\tif err != nil {\n\t\tlog.WithFields(log.Fields{\n\t\t\t\"op\":    op,\n\t\t\t\"error\": err,\n\t\t}).Error(\"invalid cmd option\")\n\t\treturn nil, err\n\t}\n\n\toverrides.ClearCmd = IsOneSpace(doUseCmd)\n\n\treturn overrides, nil\n}\n\nfunc UpdateGlobalFlagValues(appOpts *config.AppOptions, values *GenericParams) *GenericParams {\n\tif appOpts == nil || appOpts.Global == nil || values == nil {\n\t\treturn values\n\t}\n\n\tif appOpts.Global.NoColor != nil {\n\t\tvalues.NoColor = *appOpts.Global.NoColor\n\t}\n\n\tif appOpts.Global.Debug != nil {\n\t\tvalues.Debug = *appOpts.Global.Debug\n\t}\n\n\tif appOpts.Global.Verbose != nil {\n\t\tvalues.Verbose = *appOpts.Global.Verbose\n\t}\n\n\tif appOpts.Global.Quiet != nil {\n\t\tvalues.QuietCLIMode = *appOpts.Global.Quiet\n\t}\n\n\tif appOpts.Global.OutputFormat != nil {\n\t\tvalues.OutputFormat = *appOpts.Global.OutputFormat\n\t}\n\n\tif appOpts.Global.LogLevel != nil {\n\t\tvalues.LogLevel = *appOpts.Global.LogLevel\n\t}\n\n\tif appOpts.Global.LogFormat != nil {\n\t\tvalues.LogFormat = *appOpts.Global.LogFormat\n\t}\n\n\tif appOpts.Global.Log != nil {\n\t\tvalues.Log = *appOpts.Global.Log\n\t}\n\n\tif appOpts.Global.UseTLS != nil {\n\t\tvalues.ClientConfig.UseTLS = *appOpts.Global.UseTLS\n\t}\n\n\tif appOpts.Global.VerifyTLS != nil {\n\t\tvalues.ClientConfig.VerifyTLS = *appOpts.Global.VerifyTLS\n\t}\n\n\tif appOpts.Global.TLSCertPath != nil {\n\t\tvalues.ClientConfig.TLSCertPath = *appOpts.Global.TLSCertPath\n\t}\n\n\tif appOpts.Global.Host != nil {\n\t\tvalues.ClientConfig.Host = *appOpts.Global.Host\n\t}\n\n\tif appOpts.Global.APIVersion != nil {\n\t\tvalues.ClientConfig.APIVersion = *appOpts.Global.APIVersion\n\t}\n\n\treturn values\n}\n\nfunc GlobalFlagValues(ctx *cli.Context) *GenericParams {\n\tvalues := GenericParams{\n\t\tCheckVersion:   ctx.Bool(FlagCheckVersion),\n\t\tDebug:          ctx.Bool(FlagDebug),\n\t\tVerbose:        ctx.Bool(FlagVerbose),\n\t\tQuietCLIMode:   ctx.Bool(FlagQuietCLIMode),\n\t\tLogLevel:       ctx.String(FlagLogLevel),\n\t\tLogFormat:      ctx.String(FlagLogFormat),\n\t\tOutputFormat:   ctx.String(FlagOutputFormat),\n\t\tLog:            ctx.String(FlagLog),\n\t\tStatePath:      ctx.String(FlagStatePath),\n\t\tReportLocation: ctx.String(FlagCommandReport),\n\t}\n\n\tif values.ReportLocation == \"off\" {\n\t\tvalues.ReportLocation = \"\"\n\t}\n\n\tvalues.InContainer, values.IsDSImage = IsInContainer(ctx.Bool(FlagInContainer))\n\tvalues.ArchiveState = ArchiveState(ctx.String(FlagArchiveState), values.InContainer)\n\n\tvalues.ClientConfig = GetDockerClientConfig(ctx)\n\n\treturn &values\n}\n\nfunc GetDockerClientConfig(ctx *cli.Context) *config.DockerClient {\n\tconfig := &config.DockerClient{\n\t\tAPIVersion:  ctx.String(FlagAPIVersion),\n\t\tUseTLS:      ctx.Bool(FlagUseTLS),\n\t\tVerifyTLS:   ctx.Bool(FlagVerifyTLS),\n\t\tTLSCertPath: ctx.String(FlagTLSCertPath),\n\t\tHost:        ctx.String(FlagHost),\n\t\tEnv:         map[string]string{},\n\t}\n\n\tgetEnv := func(name string) {\n\t\tif value, exists := os.LookupEnv(name); exists {\n\t\t\tconfig.Env[name] = value\n\t\t}\n\t}\n\n\tfor _, ev := range dockerclient.EnvVarNames {\n\t\tgetEnv(ev)\n\t}\n\n\treturn config\n}\n\nfunc validateAndCleanEnvVariables(xc *app.ExecutionContext, envList []string, errType string) []string {\n\tvar envStaging []string\n\n\tif len(envList) == 0 {\n\t\treturn envStaging\n\t}\n\n\tfor i, kv := range envList {\n\t\tkv = strings.TrimSpace(kv)\n\n\t\tif len(kv) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif !strings.ContainsAny(kv, \"=\") {\n\t\t\txc.Out.Error(errType, fmt.Sprintf(\"skipping malformed env var - (index=%d data='%s')\", i, kv))\n\t\t\tcontinue\n\t\t}\n\n\t\tenvKeyValue := strings.SplitN(kv, \"=\", 2)\n\t\tif len(envKeyValue) != 2 {\n\t\t\txc.Out.Error(errType, fmt.Sprintf(\"skipping malformed env var - (index=%d data='%s')\", i, kv))\n\t\t\tcontinue\n\t\t}\n\n\t\tkeyIsEmpty := len(strings.TrimSpace(envKeyValue[0])) == 0\n\t\t//no need to trim value (it may have spaces intentionally)\n\t\tvalIsEmpty := len(envKeyValue[1]) == 0\n\n\t\tif !keyIsEmpty && !valIsEmpty {\n\t\t\tenvStaging = append(envStaging, kv)\n\t\t} else {\n\t\t\txc.Out.Error(errType, fmt.Sprintf(\"skipping malformed env var - (index=%d data='%s')\", i, kv))\n\t\t}\n\t}\n\n\treturn envStaging\n}\n"
  },
  {
    "path": "pkg/app/master/command/clifvparser.go",
    "content": "package command\n\n//Flag value parsers\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/docker/go-connections/nat\"\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\t\"github.com/google/shlex\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/sysenv\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nconst (\n\tDefaultStateArchiveVolumeName = \"slim-state\"\n)\n\nfunc IsInContainer(flag bool) (bool, bool) {\n\tif flag {\n\t\treturn true, sysenv.HasDSImageFlag()\n\t}\n\n\treturn sysenv.InDSContainer()\n}\n\nfunc ArchiveState(flag string, inContainer bool) string {\n\tswitch flag {\n\tcase \"\":\n\t\tswitch inContainer {\n\t\tcase true:\n\t\t\treturn DefaultStateArchiveVolumeName\n\t\tdefault:\n\t\t\treturn \"\"\n\t\t}\n\tcase \"off\":\n\t\treturn \"\"\n\tdefault:\n\t\treturn flag //should validate if it can be a Docker volume name\n\t}\n}\n\n// based on expose opt parsing in Docker\nfunc ParseDockerExposeOpt(values []string) (map[docker.Port]struct{}, error) {\n\texposedPorts := map[docker.Port]struct{}{}\n\n\tfor _, raw := range values {\n\t\tif strings.Contains(raw, \":\") {\n\t\t\treturn nil, fmt.Errorf(\"invalid EXPOSE format: %s\", raw)\n\t\t}\n\n\t\tproto, ports := nat.SplitProtoPort(raw)\n\t\tstartPort, endPort, err := nat.ParsePortRange(ports)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid port range in EXPOSE: %s / error: %s\", raw, err)\n\t\t}\n\n\t\tfor i := startPort; i <= endPort; i++ {\n\t\t\tportInfo, 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\n\t\t\texposedPorts[docker.Port(portInfo)] = struct{}{}\n\t\t}\n\t}\n\treturn exposedPorts, nil\n}\n\nfunc ParsePortBindings(values []string) (map[docker.Port][]docker.PortBinding, error) {\n\tportBindings := map[docker.Port][]docker.PortBinding{}\n\n\tfor _, raw := range values {\n\t\tvar (\n\t\t\thostIP   = \"\"\n\t\t\thostPort = \"\"\n\t\t\tportKey  = \"\"\n\t\t)\n\n\t\tparts := strings.Split(raw, \":\")\n\t\t//format:\n\t\t// port\n\t\t// hostPort:containerPort\n\t\t// hostIP:hostPort:containerPort\n\t\t// hostIP::containerPort\n\t\tswitch len(parts) {\n\t\tcase 1:\n\t\t\tportKey = fmt.Sprintf(\"%s/tcp\", parts[0])\n\t\t\thostPort = parts[0]\n\t\tcase 2:\n\t\t\thostPort = parts[0]\n\t\t\tif strings.Contains(parts[1], \"/\") {\n\t\t\t\tportKey = parts[1]\n\t\t\t} else {\n\t\t\t\tportKey = fmt.Sprintf(\"%s/tcp\", parts[1])\n\t\t\t}\n\t\tcase 3:\n\t\t\thostIP = parts[0]\n\t\t\tif len(parts[1]) > 0 {\n\t\t\t\thostPort = parts[1]\n\t\t\t} else {\n\t\t\t\thostPort = parts[2]\n\t\t\t}\n\n\t\t\tif strings.Contains(parts[2], \"/\") {\n\t\t\t\tportKey = parts[2]\n\t\t\t} else {\n\t\t\t\tportKey = fmt.Sprintf(\"%s/tcp\", parts[2])\n\t\t\t}\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"invalid publish-port: %s\", raw)\n\t\t}\n\n\t\tportBindings[docker.Port(portKey)] = []docker.PortBinding{{\n\t\t\tHostIP:   hostIP,\n\t\t\tHostPort: hostPort,\n\t\t}}\n\t}\n\n\treturn portBindings, nil\n}\n\nfunc IsOneSpace(value string) bool {\n\tif len(value) > 0 && utf8.RuneCountInString(value) == 1 {\n\t\tr, _ := utf8.DecodeRuneInString(value)\n\t\tif r != utf8.RuneError && unicode.IsSpace(r) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nvar AllImageOverrides = map[string]bool{\n\t\"entrypoint\": true,\n\t\"cmd\":        true,\n\t\"workdir\":    true,\n\t\"env\":        true,\n\t\"expose\":     true,\n\t\"volume\":     true,\n\t\"label\":      true,\n}\n\nfunc ParseImageOverrides(value string) map[string]bool {\n\tswitch value {\n\tcase \"\":\n\t\treturn map[string]bool{}\n\tcase \"all\":\n\t\treturn AllImageOverrides\n\tdefault:\n\t\tparts := strings.Split(value, \",\")\n\t\toverrides := map[string]bool{}\n\t\tfor _, part := range parts {\n\t\t\tpart = strings.ToLower(part)\n\t\t\tif _, ok := AllImageOverrides[part]; ok {\n\t\t\t\toverrides[part] = true\n\t\t\t}\n\t\t}\n\t\treturn overrides\n\t}\n}\n\nfunc ParseExec(value string) ([]string, error) {\n\tif value == \"\" {\n\t\treturn []string{}, nil\n\t}\n\n\tif value[0] != '[' {\n\t\treturn shlex.Split(value)\n\t}\n\n\tvar parts []string\n\tif err := json.Unmarshal([]byte(value), &parts); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn parts, nil\n}\n\nfunc ParseTokenSet(values []string) (map[string]struct{}, error) {\n\ttokens := map[string]struct{}{}\n\tfor _, token := range values {\n\t\ttoken = strings.TrimSpace(token)\n\t\tif token == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\ttokens[token] = struct{}{}\n\t}\n\n\treturn tokens, nil\n}\n\nfunc ParseTokenMap(values []string) (map[string]string, error) {\n\ttokens := map[string]string{}\n\tfor _, token := range values {\n\t\ttoken = strings.TrimSpace(token)\n\t\tif token == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tparts := strings.SplitN(token, \"=\", 2)\n\t\tif len(parts) != 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\ttokens[parts[0]] = parts[1]\n\t}\n\n\treturn tokens, nil\n}\n\nfunc ParseCheckTags(values []string) (map[string]string, error) {\n\ttags := map[string]string{}\n\tfor _, raw := range values {\n\t\traw = strings.TrimSpace(raw)\n\t\tif raw == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif !strings.Contains(raw, \":\") {\n\t\t\treturn nil, fmt.Errorf(\"invalid check tag format: %s\", raw)\n\t\t}\n\n\t\tparts := strings.Split(raw, \":\")\n\t\tif len(parts) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"invalid check tag format: %s\", raw)\n\t\t}\n\n\t\ttags[parts[0]] = parts[1]\n\t}\n\n\treturn tags, nil\n}\n\nfunc ParseTokenSetFile(filePath string) (map[string]struct{}, error) {\n\ttokens := map[string]struct{}{}\n\n\tif filePath == \"\" {\n\t\treturn tokens, nil\n\t}\n\n\tfullPath, err := filepath.Abs(filePath)\n\tif err != nil {\n\t\treturn tokens, err\n\t}\n\n\t_, err = os.Stat(fullPath)\n\tif err != nil {\n\t\treturn tokens, err\n\t}\n\n\tfileData, err := os.ReadFile(fullPath) //[]byte\n\tif err != nil {\n\t\treturn tokens, err\n\t}\n\n\tif len(fileData) == 0 {\n\t\treturn tokens, nil\n\t}\n\n\tlines := strings.Split(string(fileData), \"\\n\")\n\n\tfor _, token := range lines {\n\t\ttoken = strings.TrimSpace(token)\n\t\tif len(token) != 0 {\n\t\t\ttokens[token] = struct{}{}\n\t\t}\n\t}\n\n\treturn tokens, nil\n}\n\nfunc ParseVolumeMounts(values []string) (map[string]config.VolumeMount, error) {\n\tvolumeMounts := map[string]config.VolumeMount{}\n\n\tfor _, raw := range values {\n\t\tif !strings.Contains(raw, \":\") {\n\t\t\treturn nil, fmt.Errorf(\"invalid volume mount format: %s\", raw)\n\t\t}\n\n\t\tparts := strings.Split(raw, \":\")\n\t\tif (len(parts) > 3) ||\n\t\t\t(len(parts[0]) < 1) ||\n\t\t\t(len(parts[1]) < 1) ||\n\t\t\t((len(parts) == 3) && (len(parts[2]) < 1)) {\n\t\t\treturn nil, fmt.Errorf(\"invalid volume mount format: %s\", raw)\n\t\t}\n\n\t\tmount := config.VolumeMount{\n\t\t\tSource:      parts[0],\n\t\t\tDestination: parts[1],\n\t\t\tOptions:     \"rw\",\n\t\t}\n\n\t\tif len(parts) == 3 {\n\t\t\tmount.Options = parts[2]\n\t\t}\n\n\t\t//NOTE: also need to support volume bindings\n\t\t//with the same source, but different destinations\n\t\tvolumeMounts[mount.Source] = mount\n\t}\n\treturn volumeMounts, nil\n}\n\nfunc ParseVolumeMountsAsList(values []string) ([]config.VolumeMount, error) {\n\tvolumeMounts := map[string]config.VolumeMount{}\n\n\tfor _, raw := range values {\n\t\tif !strings.Contains(raw, \":\") {\n\t\t\treturn nil, fmt.Errorf(\"invalid volume mount format: %s\", raw)\n\t\t}\n\n\t\tparts := strings.Split(raw, \":\")\n\t\tif (len(parts) > 3) ||\n\t\t\t(len(parts[0]) < 1) ||\n\t\t\t(len(parts[1]) < 1) ||\n\t\t\t((len(parts) == 3) && (len(parts[2]) < 1)) {\n\t\t\treturn nil, fmt.Errorf(\"invalid volume mount format: %s\", raw)\n\t\t}\n\n\t\tmount := config.VolumeMount{\n\t\t\tSource:      parts[0],\n\t\t\tDestination: parts[1],\n\t\t\tOptions:     \"rw\",\n\t\t}\n\n\t\tif len(parts) == 3 {\n\t\t\tmount.Options = parts[2]\n\t\t}\n\n\t\tkey := fmt.Sprintf(\"%s:%s\", mount.Source, mount.Destination)\n\t\tvolumeMounts[key] = mount\n\t}\n\n\tvar volumeList []config.VolumeMount\n\tfor _, m := range volumeMounts {\n\t\tvolumeList = append(volumeList, m)\n\t}\n\n\treturn volumeList, nil\n}\n\nfunc ParsePathPerms(raw string) (string, *fsutil.AccessInfo, error) {\n\taccess := fsutil.NewAccessInfo()\n\t//note: will work for ASCII (todo: make it work for unicode)\n\t//\n\t//DATA FORMAT:\n\t//\n\t//    filePath\n\t//    filePath:octalFilemodeFlags#uid\n\t//    filePath:octalFilemodeFlags#uid#gid\n\t//\n\t//Filemode bits: perms and extra bits (sticky, setuid, setgid)\n\n\tsepIdx := strings.LastIndex(raw, \":\")\n\tif sepIdx == -1 || sepIdx == (len(raw)-1) {\n\t\treturn raw, nil, nil\n\t}\n\n\tpathStr := raw[0:sepIdx]\n\tmetaStr := raw[sepIdx+1:]\n\n\tmetaParts := strings.Split(metaStr, \"#\")\n\n\tvar permBitsStr string\n\tvar extraBitsStr string\n\n\tfileModeStr := metaParts[0]\n\tif len(fileModeStr) > 3 {\n\t\taccess.PermsOnly = false\n\t\tif len(fileModeStr) > 4 {\n\t\t\tfileModeStr = fileModeStr[len(fileModeStr)-4:]\n\t\t}\n\t\textraBitsStr = fileModeStr[0:1]\n\t\tpermBitsStr = fileModeStr[1:]\n\t} else {\n\t\taccess.PermsOnly = true\n\t\tpermBitsStr = fileModeStr\n\t}\n\n\tpermsNum, err := strconv.ParseUint(permBitsStr, 8, 32)\n\tif err != nil {\n\t\treturn \"\", nil, err\n\t}\n\n\taccess.Flags = os.FileMode(permsNum)\n\n\tif len(extraBitsStr) > 0 {\n\t\textraBits, err := strconv.ParseUint(extraBitsStr, 8, 32)\n\t\tif err != nil {\n\t\t\treturn \"\", nil, err\n\t\t}\n\n\t\taccess.Flags |= fsutil.FileModeExtraBitsUnix2Go(uint32(extraBits))\n\t}\n\n\tif len(metaParts) > 1 {\n\t\tuidNum, err := strconv.ParseInt(metaParts[1], 10, 32)\n\t\tif err == nil && uidNum > -1 {\n\t\t\taccess.UID = int(uidNum)\n\t\t}\n\t}\n\n\tif len(metaParts) > 2 {\n\t\tgidNum, err := strconv.ParseInt(metaParts[2], 10, 32)\n\t\tif err == nil && gidNum > -1 {\n\t\t\taccess.GID = int(gidNum)\n\t\t}\n\t}\n\n\treturn pathStr, access, nil\n}\n\nfunc ParsePaths(values []string) map[string]*fsutil.AccessInfo {\n\tconst op = \"commands.ParsePaths\"\n\tpaths := map[string]*fsutil.AccessInfo{}\n\n\tfor _, raw := range values {\n\t\tpathStr, access, err := ParsePathPerms(raw)\n\t\tif err != nil {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":    op,\n\t\t\t\t\"line\":  raw,\n\t\t\t\t\"error\": err,\n\t\t\t}).Debug(\"skipping.line\")\n\t\t\tcontinue\n\t\t}\n\n\t\tpaths[pathStr] = access\n\t}\n\n\treturn paths\n}\n\nfunc ValidateFiles(names []string) ([]string, map[string]error) {\n\tfound := []string{}\n\terrors := map[string]error{}\n\n\tfor _, name := range names {\n\t\tif name == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tfullPath, err := filepath.Abs(name)\n\t\tif err != nil {\n\t\t\terrors[name] = err\n\t\t\tcontinue\n\t\t}\n\n\t\t_, err = os.Stat(fullPath)\n\t\tif err != nil {\n\t\t\terrors[name] = err\n\t\t\tcontinue\n\t\t}\n\n\t\tfound = append(found, name)\n\t}\n\n\treturn found, errors\n}\n\nfunc ParsePathsFile(filePath string) (map[string]*fsutil.AccessInfo, error) {\n\tconst op = \"commands.ParsePathsFile\"\n\tpaths := map[string]*fsutil.AccessInfo{}\n\n\tif filePath == \"\" {\n\t\treturn paths, nil\n\t}\n\n\tfullPath, err := filepath.Abs(filePath)\n\tif err != nil {\n\t\treturn paths, err\n\t}\n\n\t_, err = os.Stat(fullPath)\n\tif err != nil {\n\t\treturn paths, err\n\t}\n\n\tfileData, err := os.ReadFile(fullPath) //[]byte\n\tif err != nil {\n\t\treturn paths, err\n\t}\n\n\tif len(fileData) == 0 {\n\t\treturn paths, nil\n\t}\n\n\tlines := strings.Split(string(fileData), \"\\n\")\n\tlog.WithFields(log.Fields{\n\t\t\"op\":          op,\n\t\t\"file.path\":   filePath,\n\t\t\"full.path\":   fullPath,\n\t\t\"lines.count\": len(lines),\n\t}).Trace(\"data\")\n\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\t\tif len(line) != 0 {\n\t\t\tpathStr, access, err := ParsePathPerms(line)\n\t\t\tif err != nil {\n\t\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\t\"op\":        op,\n\t\t\t\t\t\"file.path\": filePath,\n\t\t\t\t\t\"full.path\": fullPath,\n\t\t\t\t\t\"line\":      line,\n\t\t\t\t\t\"error\":     err,\n\t\t\t\t}).Debug(\"skipping.line\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tpaths[pathStr] = access\n\t\t}\n\t}\n\n\treturn paths, nil\n}\n\n// ///\nfunc ParsePathsCreportFile(filePath string) (map[string]*fsutil.AccessInfo, error) {\n\tconst op = \"commands.ParsePathsCreportFile\"\n\tpaths := map[string]*fsutil.AccessInfo{}\n\n\tif filePath == \"\" {\n\t\treturn paths, nil\n\t}\n\n\tfullPath, err := filepath.Abs(filePath)\n\tif err != nil {\n\t\treturn paths, err\n\t}\n\n\t_, err = os.Stat(fullPath)\n\tif err != nil {\n\t\treturn paths, err\n\t}\n\n\tfileData, err := os.ReadFile(fullPath) //[]byte\n\tif err != nil {\n\t\treturn paths, err\n\t}\n\n\tif len(fileData) == 0 {\n\t\treturn paths, nil\n\t}\n\n\tvar creport report.ContainerReport\n\tif err = json.NewDecoder(bytes.NewReader(fileData)).Decode(&creport); err != nil {\n\t\treturn paths, err\n\t}\n\n\tfor _, finfo := range creport.Image.Files {\n\t\tif finfo == nil || finfo.FilePath == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tpaths[finfo.FilePath] = nil\n\t}\n\n\treturn paths, nil\n}\n\n/////\n\nfunc ParseHTTPProbes(values []string) ([]config.HTTPProbeCmd, error) {\n\tprobes := []config.HTTPProbeCmd{}\n\n\tfor _, raw := range values {\n\t\tvar crawl bool\n\t\tparts := strings.Split(raw, \":\")\n\t\tif parts[0] == \"crawl\" {\n\t\t\tcrawl = true\n\t\t\tparts = parts[1:]\n\t\t}\n\n\t\tproto := \"http\"\n\t\tmethod := \"GET\"\n\t\tresource := \"/\"\n\n\t\t//sepCount := strings.Count(raw, \":\")\n\t\tswitch len(parts) {\n\t\tcase 0:\n\t\tcase 1:\n\t\t\tif parts[0] == \"\" || !isResource(parts[0]) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command resource: %+v\", raw)\n\t\t\t}\n\n\t\t\tresource = parts[0]\n\t\tcase 2:\n\t\t\tif parts[0] != \"\" && !isMethod(parts[0]) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command method: %+v\", raw)\n\t\t\t}\n\n\t\t\tmethod = strings.ToUpper(parts[0])\n\n\t\t\tif parts[1] == \"\" || !isResource(parts[1]) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command resource: %+v\", raw)\n\t\t\t}\n\n\t\t\tresource = parts[1]\n\t\tcase 3:\n\t\t\tif parts[0] != \"\" && !config.IsProto(parts[0]) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command protocol: %+v\", raw)\n\t\t\t}\n\n\t\t\tproto = strings.ToLower(parts[0])\n\n\t\t\tif parts[1] != \"\" && !isMethod(parts[1]) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command method: %+v\", raw)\n\t\t\t}\n\n\t\t\tmethod = strings.ToUpper(parts[1])\n\n\t\t\tif parts[2] == \"\" || !isResource(parts[2]) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command resource: %+v\", raw)\n\t\t\t}\n\n\t\t\tresource = parts[2]\n\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command: %s\", raw)\n\t\t}\n\n\t\tcmd := config.HTTPProbeCmd{\n\t\t\tProtocol: proto,\n\t\t\tMethod:   method,\n\t\t\tResource: resource,\n\t\t\tCrawl:    crawl,\n\t\t}\n\t\tprobes = append(probes, cmd)\n\t}\n\n\treturn probes, nil\n}\n\nfunc ParseHTTPProbesFile(filePath string) ([]config.HTTPProbeCmd, error) {\n\tprobes := []config.HTTPProbeCmd{}\n\n\tif filePath != \"\" {\n\t\tfullPath, err := filepath.Abs(filePath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t_, err = os.Stat(fullPath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tconfigFile, err := os.Open(fullPath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer configFile.Close()\n\n\t\tvar configs config.HTTPProbeCmds\n\t\tif err = json.NewDecoder(configFile).Decode(&configs); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tfor _, cmd := range configs.Commands {\n\t\t\tif cmd.Protocol != \"\" && !config.IsProto(cmd.Protocol) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command protocol: %+v\", cmd)\n\t\t\t}\n\n\t\t\tif cmd.Method != \"\" && !isMethod(cmd.Method) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command method: %+v\", cmd)\n\t\t\t}\n\n\t\t\tif cmd.Method == \"\" {\n\t\t\t\tcmd.Method = \"GET\"\n\t\t\t}\n\n\t\t\tcmd.Method = strings.ToUpper(cmd.Method)\n\n\t\t\tif cmd.Resource == \"\" || !isResource(cmd.Resource) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command resource: %+v\", cmd)\n\t\t\t}\n\n\t\t\tif cmd.Port != 0 && !isPortNum(cmd.Port) {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid HTTP probe command port: %v\", cmd)\n\t\t\t}\n\n\t\t\tif cmd.BodyFile != \"\" {\n\t\t\t\tbfFullPath, err := filepath.Abs(cmd.BodyFile)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t\t_, err = os.Stat(bfFullPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t\tcmd.BodyFile = bfFullPath\n\n\t\t\t\t//the body data file should be ok to load\n\t\t\t\t//will load the data at runtime\n\t\t\t}\n\n\t\t\tprobes = append(probes, cmd)\n\t\t}\n\t}\n\n\treturn probes, nil\n}\n\nfunc isMethod(value string) bool {\n\tswitch strings.ToUpper(value) {\n\tcase \"HEAD\", \"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc isResource(value string) bool {\n\tif value != \"\" && value[0] == '/' {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc isPortNum(value int) bool {\n\tif 1 <= value && value <= 65535 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc ParseHTTPProbesPorts(portList string) ([]uint16, error) {\n\tvar ports []uint16\n\n\tif portList == \"\" {\n\t\treturn ports, nil\n\t}\n\n\tparts := strings.Split(portList, \",\")\n\tfor _, part := range parts {\n\t\tport, err := strconv.ParseUint(part, 10, 16)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tports = append(ports, uint16(port))\n\t}\n\n\treturn ports, nil\n}\n\nfunc ParseHTTPProbeExecFile(filePath string) ([]string, error) {\n\tvar appCalls []string\n\n\tif filePath == \"\" {\n\t\treturn appCalls, nil\n\t}\n\n\tfullPath, err := filepath.Abs(filePath)\n\tif err != nil {\n\t\treturn appCalls, err\n\t}\n\n\t_, err = os.Stat(fullPath)\n\tif err != nil {\n\t\treturn appCalls, err\n\t}\n\n\tfileData, err := os.ReadFile(fullPath)\n\tif err != nil {\n\t\treturn appCalls, err\n\t}\n\n\tif len(fileData) == 0 {\n\t\treturn appCalls, nil\n\t}\n\n\tlines := strings.Split(string(fileData), \"\\n\")\n\n\tfor _, appCall := range lines {\n\t\tappCall = strings.TrimSpace(appCall)\n\t\tif len(appCall) != 0 {\n\t\t\tappCalls = append(appCalls, appCall)\n\t\t}\n\t}\n\n\treturn appCalls, nil\n}\n\nfunc ParseLinesWithCommentsFile(filePath string) ([]string, error) {\n\tvar output []string\n\n\tif filePath == \"\" {\n\t\treturn output, nil\n\t}\n\n\tfullPath, err := filepath.Abs(filePath)\n\tif err != nil {\n\t\treturn output, err\n\t}\n\n\t_, err = os.Stat(fullPath)\n\tif err != nil {\n\t\treturn output, err\n\t}\n\n\tfileData, err := os.ReadFile(fullPath)\n\tif err != nil {\n\t\treturn output, err\n\t}\n\n\tif len(fileData) == 0 {\n\t\treturn output, nil\n\t}\n\n\tlines := strings.Split(string(fileData), \"\\n\")\n\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\t\tif len(line) != 0 && !strings.HasPrefix(line, \"#\") {\n\t\t\toutput = append(output, line)\n\t\t}\n\t}\n\n\treturn output, nil\n}\n\nfunc IsTrueStr(value string) bool {\n\tif strings.ToLower(value) == \"true\" {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc ParseEnvFile(filePath string) ([]string, error) {\n\tvar output []string\n\n\tif filePath == \"\" {\n\t\treturn output, nil\n\t}\n\n\tfullPath, err := filepath.Abs(filePath)\n\tif err != nil {\n\t\treturn output, err\n\t}\n\t_, err = os.Stat(fullPath)\n\tif err != nil {\n\t\treturn output, err\n\t}\n\n\tfileData, err := os.ReadFile(fullPath)\n\tif err != nil {\n\t\treturn output, err\n\t}\n\n\tif len(fileData) == 0 {\n\t\treturn output, nil\n\t}\n\n\tlines := strings.Split(string(fileData), \"\\n\")\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\t\tif len(line) > 0 {\n\t\t\t//env var format validation is done separately\n\t\t\toutput = append(output, line)\n\t\t}\n\t}\n\treturn output, nil\n}\n"
  },
  {
    "path": "pkg/app/master/command/cliprompt.go",
    "content": "package command\n\n//CLI prompts\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/c-bata/go-prompt\"\n\t\"github.com/c-bata/go-prompt/completer\"\n\t\"github.com/dustin/go-humanize\"\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\t\"github.com/google/shlex\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t\"github.com/slimtoolkit/slim/pkg/version\"\n)\n\ntype InteractiveApp struct {\n\tappPrompt   *prompt.Prompt\n\tfpCompleter completer.FilePathCompleter\n\tapp         *cli.App\n\tdclient     *dockerapi.Client\n}\n\nfunc NewInteractiveApp(app *cli.App, gparams *GenericParams) *InteractiveApp {\n\tia := InteractiveApp{\n\t\tapp: app,\n\t\tfpCompleter: completer.FilePathCompleter{\n\t\t\tIgnoreCase: true,\n\t\t},\n\t}\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\t\tfmt.Printf(\"slim: info=docker.connect.error message='%s'\\n\", exitMsg)\n\t\tfmt.Printf(\"slim: state=exited version=%s location='%s'\\n\", version.Current(), fsutil.ExeDir())\n\t\tos.Exit(-777)\n\t}\n\terrutil.FailOn(err)\n\n\tia.dclient = client\n\n\tia.appPrompt = prompt.New(\n\t\tia.execute,\n\t\tia.complete,\n\t\tprompt.OptionTitle(fmt.Sprintf(\"%s: interactive prompt\", AppName)),\n\t\tprompt.OptionPrefix(\">>> \"),\n\t\tprompt.OptionInputTextColor(prompt.Red),\n\t\tprompt.OptionCompletionWordSeparator(completer.FilePathCompletionSeparator),\n\t)\n\n\treturn &ia\n}\n\nfunc (ia *InteractiveApp) execute(command string) {\n\tcommand = strings.TrimSpace(command)\n\tparts, err := shlex.Split(command)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tif len(parts) == 0 {\n\t\treturn\n\t}\n\n\tif parts[0] == \"exit\" {\n\t\tapp.ShowCommunityInfo(OutputFormatText)\n\t\tos.Exit(0)\n\t}\n\n\tpartsCount := len(parts)\n\tfor i := 0; i < partsCount; i++ {\n\t\tif parts[i] == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(parts[i], \"--\") &&\n\t\t\t(i+1) < partsCount &&\n\t\t\t(parts[i+1] == \"true\" || parts[i+1] == \"false\") {\n\t\t\tparts[i] = fmt.Sprintf(\"%s=%s\", parts[i], parts[i+1])\n\t\t\tparts[i+1] = \"\"\n\t\t}\n\t}\n\n\targs := []string{AppName}\n\tfor _, val := range parts {\n\t\tif val == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\targs = append(args, val)\n\t}\n\n\tif err := ia.app.Run(args); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n\nfunc (ia *InteractiveApp) complete(params prompt.Document) []prompt.Suggest {\n\tallParamsLine := params.TextBeforeCursor()\n\n\tallParamsLine = strings.TrimSpace(allParamsLine)\n\tif allParamsLine == \"\" {\n\t\treturn append(CommandSuggestions, GlobalFlagSuggestions...)\n\t}\n\n\tcommandState := newCurrentCommandState()\n\tcommandState.Dclient = ia.dclient\n\n\tcurrentToken := params.GetWordBeforeCursor()\n\tcommandState.CurrentToken = currentToken\n\n\tallTokens := strings.Split(allParamsLine, \" \")\n\tcommandState.AllTokensList = allTokens\n\n\tvar prevToken string\n\tprevTokenIdx := -1\n\ttokenCount := len(allTokens)\n\n\tif tokenCount > 0 {\n\t\tif currentToken == \"\" {\n\t\t\t//currentToken 'points' past allTokens[last]\n\t\t\tprevTokenIdx = tokenCount - 1\n\t\t\tprevToken = allTokens[prevTokenIdx]\n\t\t} else {\n\t\t\t//currentToken 'points' to allTokens[last]\n\t\t\tif tokenCount >= 2 {\n\t\t\t\tprevTokenIdx = tokenCount - 2\n\t\t\t\tprevToken = allTokens[prevTokenIdx]\n\t\t\t}\n\t\t}\n\t}\n\n\tcommandState.PrevToken = prevToken\n\tcommandState.PrevTokenIdx = prevTokenIdx\n\tcommandState.State = InputStateCommand\n\n\tif prevToken == \"\" {\n\t\tsaveCurrentCommandState(commandState)\n\n\t\tsuggestions := append(CommandSuggestions, GlobalFlagSuggestions...)\n\t\treturn prompt.FilterHasPrefix(suggestions, currentToken, true)\n\t}\n\n\tcommandTokenIdx := -1\n\tlastValueIdx := -1\n\tvar lastFlagName string\n\n\tfor i := 0; i <= prevTokenIdx; i++ {\n\t\tif strings.HasPrefix(allTokens[i], \"--\") {\n\t\t\tlastFlagName = allTokens[i]\n\t\t\tlastValueIdx = -1\n\t\t} else {\n\t\t\tif lastFlagName == \"\" {\n\t\t\t\t//non-flag name token\n\t\t\t\t//command token if the previous token was not a flag name\n\t\t\t\tcommandTokenIdx = i\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif lastFlagName == \"\" {\n\t\t\t\tlastValueIdx = i\n\t\t\t} else {\n\t\t\t\tlastFlagName = \"\"\n\t\t\t}\n\t\t}\n\t}\n\n\tif commandTokenIdx == -1 && lastValueIdx > -1 {\n\t\tcommandTokenIdx = lastValueIdx\n\t}\n\n\tif commandTokenIdx == -1 {\n\t\tsaveCurrentCommandState(commandState)\n\n\t\tif strings.HasPrefix(prevToken, \"--\") {\n\t\t\tif completeValue, ok := GlobalFlagValueSuggestions[prevToken]; ok && completeValue != nil {\n\t\t\t\treturn completeValue(ia, currentToken, params)\n\t\t\t}\n\t\t} else {\n\t\t\tsuggestions := append(CommandSuggestions, GlobalFlagSuggestions...)\n\t\t\treturn prompt.FilterHasPrefix(suggestions, currentToken, true)\n\t\t}\n\n\t\treturn []prompt.Suggest{}\n\t}\n\n\tcommandToken := allTokens[commandTokenIdx]\n\n\tcommandState.CommandTokenIdx = commandTokenIdx\n\tcommandState.Command = commandToken\n\n\tif strings.HasPrefix(commandState.CurrentToken, \"--\") {\n\t\tcommandState.State = InputStateCommandFlag\n\t} else {\n\t\tcommandState.State = InputStateCommandFlagValue\n\t}\n\n\tlastFlagName = \"\"\n\tfor i := 0; i < commandTokenIdx; i++ {\n\t\tif strings.HasPrefix(allTokens[i], \"--\") {\n\t\t\tlastFlagName = allTokens[i]\n\t\t} else {\n\t\t\tif lastFlagName != \"\" {\n\t\t\t\tcommandState.GlobalFlags[lastFlagName] = allTokens[i]\n\t\t\t\tlastFlagName = \"\"\n\t\t\t}\n\t\t}\n\t}\n\n\tif commandTokenIdx == (tokenCount - 1) {\n\t\tsaveCurrentCommandState(commandState)\n\t\tif currentToken != \"\" {\n\t\t\t//currentToken still points to the command token\n\t\t\treturn prompt.FilterHasPrefix(CommandSuggestions, currentToken, true)\n\t\t} else {\n\t\t\t//need to return the command flag suggestions\n\t\t\tif cmdFlagSuggestions, ok := CommandFlagSuggestions[commandToken]; ok && cmdFlagSuggestions != nil {\n\t\t\t\treturn prompt.FilterHasPrefix(cmdFlagSuggestions.Names, currentToken, true)\n\t\t\t} else {\n\t\t\t\treturn []prompt.Suggest{}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlastFlagName = \"\"\n\t\tfor i := commandTokenIdx + 1; i < tokenCount; i++ {\n\t\t\tif strings.HasPrefix(allTokens[i], \"--\") {\n\t\t\t\tlastFlagName = allTokens[i]\n\t\t\t} else {\n\t\t\t\tif lastFlagName != \"\" {\n\t\t\t\t\tvalList := commandState.CommandFlags[lastFlagName]\n\t\t\t\t\tvalList = append(valList, allTokens[i])\n\t\t\t\t\tcommandState.CommandFlags[lastFlagName] = valList\n\t\t\t\t\tlastFlagName = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tsaveCurrentCommandState(commandState)\n\t}\n\n\tcmdFlagSuggestions, ok := CommandFlagSuggestions[commandToken]\n\tif !ok {\n\t\treturn []prompt.Suggest{}\n\t}\n\n\tif strings.HasPrefix(prevToken, \"--\") {\n\t\tif completeValue, ok := cmdFlagSuggestions.Values[prevToken]; ok && completeValue != nil {\n\t\t\treturn completeValue(ia, currentToken, params)\n\t\t}\n\t} else {\n\t\treturn prompt.FilterHasPrefix(cmdFlagSuggestions.Names, currentToken, true)\n\t}\n\n\treturn []prompt.Suggest{}\n}\n\nfunc (ia *InteractiveApp) Run() {\n\tia.appPrompt.Run()\n}\n\n/////////////////////////////////////////////\n\ntype CompleteValue func(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest\n\ntype FlagSuggestions struct {\n\tNames  []prompt.Suggest\n\tValues map[string]CompleteValue\n}\n\nvar CommandFlagSuggestions = map[string]*FlagSuggestions{}\n\nvar CommandSuggestions = []prompt.Suggest{\n\t{Text: \"exit\", Description: \"Exit app\"},\n}\n\nconst (\n\tInputStateEmpty            = \"empty\"\n\tInputStateGlobalFlag       = \"global.flag\"\n\tInputStateGlobalFlagValue  = \"global.flag.value\"\n\tInputStateCommand          = \"command\"\n\tInputStateCommandFlag      = \"command.flag\"\n\tInputStateCommandFlagValue = \"command.flag.value\"\n)\n\ntype CurrentCommandState struct {\n\tDclient *dockerapi.Client\n\tState   string\n\n\tAllTokensList   []string\n\tCurrentToken    string\n\tPrevToken       string\n\tPrevTokenIdx    int\n\tCommandTokenIdx int\n\n\tGlobalFlags  map[string]string\n\tCommand      string\n\tCommandFlags map[string][]string\n}\n\nfunc newCurrentCommandState() *CurrentCommandState {\n\treturn &CurrentCommandState{\n\t\tState:           InputStateEmpty,\n\t\tPrevTokenIdx:    -1,\n\t\tCommandTokenIdx: -1,\n\t\tGlobalFlags:     map[string]string{},\n\t\tCommandFlags:    map[string][]string{},\n\t}\n}\n\nfunc (ref *CurrentCommandState) GetCFValue(name string) string {\n\treturn ref.GetCFValueWithDefault(name, \"\")\n}\n\nfunc (ref *CurrentCommandState) GetCFValueWithDefault(name string, dvalue string) string {\n\tfullFlag := FullFlagName(name)\n\tvals, found := ref.CommandFlags[fullFlag]\n\tif found && len(vals) > 0 && vals[0] != \"\" {\n\t\treturn vals[0]\n\t}\n\n\treturn dvalue\n}\n\nfunc saveCurrentCommandState(value *CurrentCommandState) {\n\t//fmt.Printf(\"\\nsaveCurrentCommandState: %#v\\n\\n\",value)\n\tgCurrentCommandState = value\n}\n\nvar gCurrentCommandState *CurrentCommandState\n\nfunc GetCurrentCommandState() *CurrentCommandState {\n\treturn gCurrentCommandState\n}\n\n/////////////////////////////////////////////\n\n//NOTE: command packages will add their prompt command suggestion in their init()\n\nvar GlobalFlagSuggestions = []prompt.Suggest{\n\t{Text: FullFlagName(FlagStatePath), Description: FlagStatePathUsage},\n\t{Text: FullFlagName(FlagCommandReport), Description: FlagCommandReportUsage},\n\t{Text: FullFlagName(FlagDebug), Description: FlagDebugUsage},\n\t{Text: FullFlagName(FlagVerbose), Description: FlagVerboseUsage},\n\t{Text: FullFlagName(FlagLogLevel), Description: FlagLogLevelUsage},\n\t{Text: FullFlagName(FlagLog), Description: FlagLogUsage},\n\t{Text: FullFlagName(FlagLogFormat), Description: FlagLogFormatUsage},\n\t{Text: FullFlagName(FlagQuietCLIMode), Description: FlagQuietCLIModeUsage},\n\t{Text: FullFlagName(FlagOutputFormat), Description: FlagOutputFormatUsage},\n\t{Text: FullFlagName(FlagUseTLS), Description: FlagUseTLSUsage},\n\t{Text: FullFlagName(FlagVerifyTLS), Description: FlagVerifyTLSUsage},\n\t{Text: FullFlagName(FlagTLSCertPath), Description: FlagTLSCertPathUsage},\n\t{Text: FullFlagName(FlagHost), Description: FlagHostUsage},\n\t{Text: FullFlagName(FlagArchiveState), Description: FlagArchiveStateUsage},\n\t{Text: FullFlagName(FlagInContainer), Description: FlagInContainerUsage},\n\t{Text: FullFlagName(FlagCheckVersion), Description: FlagCheckVersionUsage},\n\t{Text: FullFlagName(FlagNoColor), Description: FlagNoColorUsage},\n}\n\nvar GlobalFlagValueSuggestions = map[string]CompleteValue{\n\tFullFlagName(FlagQuietCLIMode): CompleteBool,\n\tFullFlagName(FlagOutputFormat): CompleteOutputFormat,\n\tFullFlagName(FlagDebug):        CompleteBool,\n\tFullFlagName(FlagVerbose):      CompleteBool,\n\tFullFlagName(FlagNoColor):      CompleteBool,\n\tFullFlagName(FlagCheckVersion): CompleteTBool,\n}\n\nfunc FullFlagName(name string) string {\n\treturn fmt.Sprintf(\"--%s\", name)\n}\n\nvar boolValues = []prompt.Suggest{\n\t{Text: \"false\", Description: \"default\"},\n\t{Text: \"true\"},\n}\n\nvar tboolValues = []prompt.Suggest{\n\t{Text: \"true\", Description: \"default\"},\n\t{Text: \"false\"},\n}\n\nvar continueAfterValues = []prompt.Suggest{\n\t{Text: config.CAMAppExit, Description: \"Continue after the target app exits\"},\n\t{Text: config.CAMHostExec, Description: \"Continue after host command execution is finished running\"},\n\t{Text: config.CAMExec, Description: \"Continue after container command execution is finished running\"},\n\t{Text: config.CAMProbe, Description: \"Continue after the HTTP probe is finished running\"},\n\t{Text: config.CAMEnter, Description: \"Use the <enter> key to indicate you that you are done using the container\"},\n\t{Text: config.CAMSignal, Description: \"Use SIGUSR1 to signal that you are done using the container\"},\n\t{Text: config.CAMTimeout, Description: \"Continue after the default timeout (60 seconds)\"},\n\t{Text: config.CAMContainerProbe, Description: \"Continue after the probed container exits\"},\n\t{Text: \"<seconds>\", Description: \"Enter the number of seconds to wait instead of <seconds>\"},\n}\n\nvar consoleOutputValues = []prompt.Suggest{\n\t{Text: OutputFormatText, Description: \"Default, output in text format (as a table in quiet CLI mode)\"},\n\t{Text: OutputFormatJSON, Description: \"JSON output format\"},\n}\n\nvar ipcModeValues = []prompt.Suggest{\n\t{Text: \"proxy\", Description: \"Proxy sensor ipc mode\"},\n\t{Text: \"direct\", Description: \"Direct sensor ipc mode\"},\n}\n\nfunc CompleteProgress(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tswitch runtime.GOOS {\n\tcase \"darwin\":\n\t\treturn CompleteTBool(ia, token, params)\n\tdefault:\n\t\treturn CompleteBool(ia, token, params)\n\t}\n}\n\nfunc CompleteBool(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(boolValues, token, true)\n}\n\nfunc CompleteTBool(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(tboolValues, token, true)\n}\n\nfunc CompleteContinueAfter(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(continueAfterValues, token, true)\n}\n\nfunc CompleteOutputFormat(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(consoleOutputValues, token, true)\n}\n\nfunc CompleteIPCMode(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(ipcModeValues, token, true)\n}\n\nfunc CompleteImage(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\timages, err := dockerutil.ListImages(ia.dclient, \"\")\n\tif err != nil {\n\t\tlog.Errorf(\"CompleteImage(%q): error - %v\", token, err)\n\t\treturn []prompt.Suggest{}\n\t}\n\n\tvar values []prompt.Suggest\n\tfor name, info := range images {\n\t\tdescription := fmt.Sprintf(\"size=%v created=%v id=%v\",\n\t\t\thumanize.Bytes(uint64(info.Size)),\n\t\t\ttime.Unix(info.Created, 0).Format(time.RFC3339),\n\t\t\tinfo.ID)\n\n\t\tentry := prompt.Suggest{\n\t\t\tText:        name,\n\t\t\tDescription: description,\n\t\t}\n\n\t\tvalues = append(values, entry)\n\t}\n\n\treturn prompt.FilterContains(values, token, true)\n}\n\nfunc CompleteVolume(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tnames, err := dockerutil.ListVolumes(ia.dclient, token)\n\tif err != nil {\n\t\tlog.Errorf(\"completeVolume(%q): error - %v\", token, err)\n\t\treturn []prompt.Suggest{}\n\t}\n\n\tvar values []prompt.Suggest\n\tfor _, name := range names {\n\t\tentry := prompt.Suggest{\n\t\t\tText: name,\n\t\t}\n\n\t\tvalues = append(values, entry)\n\t}\n\n\treturn prompt.FilterContains(values, token, true)\n}\n\nfunc CompleteNetwork(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tnames, err := dockerutil.ListNetworks(ia.dclient, token)\n\tif err != nil {\n\t\tlog.Errorf(\"completeNetwork(%q): error - %v\", token, err)\n\t\treturn []prompt.Suggest{}\n\t}\n\n\tvar values []prompt.Suggest\n\tfor _, name := range names {\n\t\tentry := prompt.Suggest{\n\t\t\tText: name,\n\t\t}\n\n\t\tvalues = append(values, entry)\n\t}\n\n\treturn prompt.FilterContains(values, token, true)\n}\n\nfunc CompleteFile(ia *InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn ia.fpCompleter.Complete(params)\n}\n"
  },
  {
    "path": "pkg/app/master/command/common.go",
    "content": "package command\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/c-bata/go-prompt\"\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\t\"github.com/google/shlex\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nconst (\n\tImagesStateRootPath = \"images\"\n)\n\nvar (\n\tErrNoGlobalParams = errors.New(\"No global params\")\n)\n\ntype ovars = app.OutVars\n\n/////////////////////////////////////////////////////////\n\ntype CLIContextKey int\n\nconst (\n\tGlobalParams CLIContextKey = 1\n\tAppParams    CLIContextKey = 2\n)\n\nfunc CLIContextSave(ctx context.Context, key CLIContextKey, data interface{}) context.Context {\n\treturn context.WithValue(ctx, key, data)\n}\n\nfunc CLIContextGet(ctx context.Context, key CLIContextKey) interface{} {\n\tif ctx == nil {\n\t\treturn nil\n\t}\n\n\treturn ctx.Value(key)\n}\n\n/////////////////////////////////////////////////////////\n\ntype GenericParams struct {\n\tNoColor        bool\n\tCheckVersion   bool\n\tDebug          bool\n\tVerbose        bool\n\tQuietCLIMode   bool\n\tLogLevel       string\n\tLogFormat      string\n\tOutputFormat   string\n\tLog            string\n\tStatePath      string\n\tReportLocation string\n\tInContainer    bool\n\tIsDSImage      bool\n\tArchiveState   string\n\tClientConfig   *config.DockerClient\n}\n\n// TODO: spread these code types across all command definition, so it's not all defined here\n// Exit Code Types\nconst (\n\tECTCommon  = 0x01000000\n\tECTBuild   = 0x02000000\n\tectProfile = 0x03000000\n\tectInfo    = 0x04000000\n\tectUpdate  = 0x05000000\n\tectVersion = 0x06000000\n\tECTXray    = 0x07000000\n\tECTRun     = 0x08000000\n\tECTMerge   = 0x09000000\n)\n\n// Build command exit codes\nconst (\n\tECCOther = iota + 1\n\tECCImageNotFound\n\tECCNoDockerConnectInfo\n\tECCBadNetworkName\n)\n\nconst (\n\tAppName = \"slim\"\n\tappName = \"slim\"\n)\n\n//Common command handler code\n\nfunc DoArchiveState(logger *log.Entry, client *docker.Client, localStatePath, volumeName, stateKey string) error {\n\tif volumeName == \"\" {\n\t\treturn nil\n\t}\n\n\terr := dockerutil.HasVolume(client, volumeName)\n\tswitch {\n\tcase err == nil:\n\t\tlogger.Debugf(\"archiveState: already have volume = %v\", volumeName)\n\tcase err == dockerutil.ErrNotFound:\n\t\tlogger.Debugf(\"archiveState: no volume yet = %v\", volumeName)\n\t\tif dockerutil.HasEmptyImage(client) == dockerutil.ErrNotFound {\n\t\t\terr := dockerutil.BuildEmptyImage(client)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Debugf(\"archiveState: dockerutil.BuildEmptyImage() - error = %v\", err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\terr = dockerutil.CreateVolumeWithData(client, \"\", volumeName, nil)\n\t\tif err != nil {\n\t\t\tlogger.Debugf(\"archiveState: dockerutil.CreateVolumeWithData() - error = %v\", err)\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\tlogger.Debugf(\"archiveState: dockerutil.HasVolume() - error = %v\", err)\n\t\treturn err\n\t}\n\n\treturn dockerutil.CopyToVolume(client, volumeName, localStatePath, ImagesStateRootPath, stateKey)\n}\n\nfunc CopyMetaArtifacts(logger *log.Entry, names []string, artifactLocation, targetLocation string) bool {\n\tif targetLocation != \"\" {\n\t\tif !fsutil.Exists(artifactLocation) {\n\t\t\tlogger.Debugf(\"copyMetaArtifacts() - bad artifact location (%v)\\n\", artifactLocation)\n\t\t\treturn false\n\t\t}\n\n\t\tif len(names) == 0 {\n\t\t\tlogger.Debug(\"copyMetaArtifacts() - no artifact names\")\n\t\t\treturn false\n\t\t}\n\n\t\tfor _, name := range names {\n\t\t\tsrcPath := filepath.Join(artifactLocation, name)\n\t\t\tif fsutil.Exists(srcPath) && fsutil.IsRegularFile(srcPath) {\n\t\t\t\tdstPath := filepath.Join(targetLocation, name)\n\t\t\t\terr := fsutil.CopyRegularFile(false, srcPath, dstPath, true)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Debugf(\"copyMetaArtifacts() - error saving file: %v\\n\", err)\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\tlogger.Debug(\"copyMetaArtifacts() - no target location\")\n\treturn false\n}\n\nfunc ConfirmNetwork(logger *log.Entry, client *docker.Client, network string) bool {\n\tif network == \"\" {\n\t\treturn true\n\t}\n\n\tif networks, err := client.ListNetworks(); err == nil {\n\t\tfor _, n := range networks {\n\t\t\tif n.Name == network {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlogger.Debugf(\"confirmNetwork() - error getting networks = %v\", err)\n\t}\n\n\treturn false\n}\n\n// /\nfunc UpdateImageRef(logger *log.Entry, ref, override string) string {\n\tlogger.Debugf(\"UpdateImageRef() - ref='%s' override='%s'\", ref, override)\n\tif override == \"\" {\n\t\treturn ref\n\t}\n\n\trefParts := strings.SplitN(ref, \":\", 2)\n\trefImage := refParts[0]\n\trefTag := \"\"\n\tif len(refParts) > 1 {\n\t\trefTag = refParts[1]\n\t}\n\n\toverrideParts := strings.SplitN(override, \":\", 2)\n\tswitch len(overrideParts) {\n\tcase 2:\n\t\trefImage = overrideParts[0]\n\t\trefTag = overrideParts[1]\n\tcase 1:\n\t\trefTag = overrideParts[0]\n\t}\n\n\tif refTag == \"\" {\n\t\t//shouldn't happen\n\t\trefTag = \"latest\"\n\t}\n\n\treturn fmt.Sprintf(\"%s:%s\", refImage, refTag)\n}\n\nfunc RunHostExecProbes(printState bool, xc *app.ExecutionContext, hostExecProbes []string) {\n\tif len(hostExecProbes) > 0 {\n\t\tvar callCount uint\n\t\tvar okCount uint\n\t\tvar errCount uint\n\n\t\tif printState {\n\t\t\txc.Out.Info(\"host.exec.probes\",\n\t\t\t\tovars{\n\t\t\t\t\t\"count\": len(hostExecProbes),\n\t\t\t\t})\n\t\t}\n\n\t\tfor idx, appCall := range hostExecProbes {\n\t\t\tif printState {\n\t\t\t\txc.Out.Info(\"host.exec.probes\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"idx\": idx,\n\t\t\t\t\t\t\"app\": appCall,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\txc.Out.Info(\"host.exec.probe.output.start\")\n\t\t\t//TODO LATER:\n\t\t\t//add more parameters and outputs for more advanced execution control capabilities\n\t\t\terr := exeAppCall(appCall)\n\t\t\txc.Out.Info(\"host.exec.probe.output.end\")\n\n\t\t\tcallCount++\n\t\t\tstatusCode := \"error\"\n\t\t\tcallErrorStr := \"none\"\n\t\t\tif err == nil {\n\t\t\t\tokCount++\n\t\t\t\tstatusCode = \"ok\"\n\t\t\t} else {\n\t\t\t\terrCount++\n\t\t\t\tcallErrorStr = err.Error()\n\t\t\t}\n\n\t\t\tif printState {\n\t\t\t\txc.Out.Info(\"host.exec.probes\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"idx\":    idx,\n\t\t\t\t\t\t\"app\":    appCall,\n\t\t\t\t\t\t\"status\": statusCode,\n\t\t\t\t\t\t\"error\":  callErrorStr,\n\t\t\t\t\t\t\"time\":   time.Now().UTC().Format(time.RFC3339),\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc exeAppCall(appCall string) error {\n\tctx, cancel := context.WithTimeout(context.Background(), 200*time.Second)\n\tdefer cancel()\n\n\tappCall = strings.TrimSpace(appCall)\n\targs, err := shlex.Split(appCall)\n\tif err != nil {\n\t\tlog.Errorf(\"exeAppCall(%s): call parse error: %v\", appCall, err)\n\t\treturn err\n\t}\n\n\tif len(args) == 0 {\n\t\treturn fmt.Errorf(\"empty appCall\")\n\t}\n\n\tcmd := exec.CommandContext(ctx, args[0], args[1:]...)\n\t//cmd.Dir = \".\"\n\tcmd.Stdin = os.Stdin\n\n\t//var outBuf, errBuf bytes.Buffer\n\t//cmd.Stdout = io.MultiWriter(os.Stdout, &outBuf)\n\t//cmd.Stderr = io.MultiWriter(os.Stderr, &errBuf)\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\n\tif err := cmd.Start(); err != nil {\n\t\tlog.Errorf(\"exeAppCall(%s): command start error: %v\", appCall, err)\n\t\treturn err\n\t}\n\n\terr = cmd.Wait()\n\tfmt.Printf(\"\\n\")\n\tif err != nil {\n\t\tlog.Fatalf(\"exeAppCall(%s): command exited with error: %v\", appCall, err)\n\t\treturn err\n\t}\n\n\t//TODO: process outBuf and errBuf here\n\treturn nil\n}\n\n///////////////////////////////////////\n\n// var CLI []*cli.Command\nvar cliCommands []*cli.Command\n\nfunc AddCLICommand(\n\tname string,\n\tcmd *cli.Command,\n\tcmdSuggestion prompt.Suggest,\n\tflagSuggestions *FlagSuggestions) {\n\tcliCommands = append(cliCommands, cmd)\n\tif flagSuggestions != nil {\n\t\tCommandFlagSuggestions[name] = flagSuggestions\n\t}\n\n\tif cmdSuggestion.Text != \"\" {\n\t\tCommandSuggestions = append(CommandSuggestions, cmdSuggestion)\n\t}\n}\n\nfunc GetCommands() []*cli.Command {\n\treturn cliCommands\n}\n"
  },
  {
    "path": "pkg/app/master/command/containerize/cli.go",
    "content": "package containerize\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"containerize\"\n\tUsage = \"Containerize the target app\"\n\tAlias = \"c\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\ttargetRef := ctx.String(command.FlagTarget)\n\t\tif targetRef == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\txc.Out.Error(\"param.target\", \"missing target\")\n\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t}\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues,\n\t\t\ttargetRef)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/containerize/handler.go",
    "content": "package containerize\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'containerize' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\ttargetRef string) {\n\tconst cmdName = Name\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": cmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewContainerizeCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(\"started\")\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"target\": targetRef,\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\txc.Out.State(\"completed\")\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(\"done\")\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/containerize/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/containerize\"\n)\n\nfunc init() {\n\tcontainerize.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/containerize/prompt.go",
    "content": "package containerize\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/containerize/register.go",
    "content": "package containerize\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/convert/cli.go",
    "content": "package convert\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"convert\"\n\tUsage = \"Convert container image\"\n\tAlias = \"k\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\ttargetRef := ctx.String(command.FlagTarget)\n\t\tif targetRef == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\txc.Out.Error(\"param.target\", \"missing target\")\n\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t}\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues,\n\t\t\ttargetRef)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/convert/handler.go",
    "content": "package convert\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'convert' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\ttargetRef string) {\n\tconst cmdName = Name\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": cmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewConvertCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(\"started\")\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"target\": targetRef,\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\txc.Out.State(\"completed\")\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(\"done\")\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/convert/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/convert\"\n)\n\nfunc init() {\n\tconvert.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/convert/prompt.go",
    "content": "package convert\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/convert/register.go",
    "content": "package convert\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/cli.go",
    "content": "package debug\n\nimport (\n\t\"strings\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\n//Debug container\n\nconst (\n\tName  = \"debug\"\n\tUsage = \"Debug the target container from a debug (side-car) container\"\n\tAlias = \"dbg\"\n)\n\nconst (\n\tDockerRuntime     = \"docker\"\n\tKubernetesRuntime = \"k8s\"\n\tKubeconfigDefault = \"${HOME}/.kube/config\"\n\tNamespaceDefault  = \"default\"\n)\n\ntype NVPair struct {\n\tName  string\n\tValue string\n}\n\ntype CommandParams struct {\n\t/// the runtime environment type\n\tRuntime string\n\t/// the running container which we want to attach to\n\tTargetRef string\n\t/// the target namespace (k8s runtime)\n\tTargetNamespace string\n\t/// the target pod (k8s runtime)\n\tTargetPod string\n\t/// the name/id of the container image used for debugging\n\tDebugContainerImage string\n\t/// ENTRYPOINT used launching the debugging container\n\tEntrypoint []string\n\t/// CMD used launching the debugging container\n\tCmd []string\n\t/// WORKDIR used launching the debugging container\n\tWorkdir string\n\t/// Environment variables used launching the debugging container\n\tEnvVars []NVPair\n\t/// launch the debug container with an interactive terminal attached (like '--it' in docker)\n\tDoTerminal bool\n\t/// make it look like shell is running in the target container\n\tDoRunAsTargetShell bool\n\t/// Kubeconfig file path (k8s runtime)\n\tKubeconfig string\n\t/// Debug session container name\n\tSession string\n\t/// Simple (non-debug) action - list namespaces\n\tActionListNamespaces bool\n\t/// Simple (non-debug) action - list pods\n\tActionListPods bool\n\t/// Simple (non-debug) action - list debuggable container\n\tActionListDebuggableContainers bool\n\t/// Simple (non-debug) action - list debug sessions\n\tActionListSessions bool\n\t/// Simple (non-debug) action - show debug sessions logs\n\tActionShowSessionLogs bool\n\t/// Simple (non-debug) action - connect to an existing debug session\n\tActionConnectSession bool\n}\n\nfunc ParseNameValueList(list []string) []NVPair {\n\tvar pairs []NVPair\n\tfor _, val := range list {\n\t\tval = strings.TrimSpace(val)\n\t\tif val == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tparts := strings.SplitN(val, \"=\", 2)\n\t\tif len(parts) != 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\tnv := NVPair{Name: parts[0], Value: parts[1]}\n\t\tpairs = append(pairs, nv)\n\t}\n\n\treturn pairs\n}\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tcflag(FlagRuntime),\n\t\tcflag(FlagTarget),\n\t\tcflag(FlagNamespace),\n\t\tcflag(FlagPod),\n\t\tcflag(FlagDebugImage),\n\t\tcflag(FlagEntrypoint),\n\t\tcflag(FlagCmd),\n\t\tcflag(FlagWorkdir),\n\t\tcflag(FlagEnv),\n\t\tcflag(FlagTerminal),\n\t\tcflag(FlagRunAsTargetShell),\n\t\tcflag(FlagListSessions),\n\t\tcflag(FlagShowSessionLogs),\n\t\tcflag(FlagConnectSession),\n\t\tcflag(FlagSession),\n\t\tcflag(FlagListNamespaces),\n\t\tcflag(FlagListPods),\n\t\tcflag(FlagListDebuggableContainers),\n\t\tcflag(FlagListDebugImage),\n\t\tcflag(FlagKubeconfig),\n\t},\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\tif ctx.Bool(FlagListDebugImage) {\n\t\t\txc.Out.State(\"action.list_debug_images\")\n\t\t\tfor k, v := range debugImages {\n\t\t\t\txc.Out.Info(\"debug.image\", ovars{\"name\": k, \"description\": v})\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}\n\n\t\tcommandParams := &CommandParams{\n\t\t\tRuntime:                        ctx.String(FlagRuntime),\n\t\t\tTargetRef:                      ctx.String(FlagTarget),\n\t\t\tTargetNamespace:                ctx.String(FlagNamespace),\n\t\t\tTargetPod:                      ctx.String(FlagPod),\n\t\t\tDebugContainerImage:            ctx.String(FlagDebugImage),\n\t\t\tDoTerminal:                     ctx.Bool(FlagTerminal),\n\t\t\tDoRunAsTargetShell:             ctx.Bool(FlagRunAsTargetShell),\n\t\t\tKubeconfig:                     ctx.String(FlagKubeconfig),\n\t\t\tWorkdir:                        ctx.String(FlagWorkdir),\n\t\t\tEnvVars:                        ParseNameValueList(ctx.StringSlice(FlagEnv)),\n\t\t\tSession:                        ctx.String(FlagSession),\n\t\t\tActionListNamespaces:           ctx.Bool(FlagListNamespaces),\n\t\t\tActionListPods:                 ctx.Bool(FlagListPods),\n\t\t\tActionListDebuggableContainers: ctx.Bool(FlagListDebuggableContainers),\n\t\t\tActionListSessions:             ctx.Bool(FlagListSessions),\n\t\t\tActionShowSessionLogs:          ctx.Bool(FlagShowSessionLogs),\n\t\t\tActionConnectSession:           ctx.Bool(FlagConnectSession),\n\t\t}\n\n\t\tif commandParams.Runtime != KubernetesRuntime &&\n\t\t\t(commandParams.ActionListNamespaces ||\n\t\t\t\tcommandParams.ActionListPods) {\n\t\t\tvar actionName string\n\t\t\tif commandParams.ActionListNamespaces {\n\t\t\t\tactionName = FlagListNamespaces\n\t\t\t}\n\n\t\t\tif commandParams.ActionListPods {\n\t\t\t\tactionName = FlagListPods\n\t\t\t}\n\n\t\t\txc.Out.Error(\"param\", \"unsupported runtime flag\")\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"runtime.provided\": commandParams.Runtime,\n\t\t\t\t\t\"runtime.required\": KubernetesRuntime,\n\t\t\t\t\t\"action\":           actionName,\n\t\t\t\t\t\"exit.code\":        -1,\n\t\t\t\t})\n\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tvar err error\n\t\tif rawEntrypoint := ctx.String(FlagEntrypoint); rawEntrypoint != \"\" {\n\t\t\tcommandParams.Entrypoint, err = command.ParseExec(rawEntrypoint)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif rawCmd := ctx.String(FlagCmd); rawCmd != \"\" {\n\t\t\tcommandParams.Cmd, err = command.ParseExec(rawCmd)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\t//explicitly setting the entrypoint and/or cmd clears\n\t\t//implies a custom debug session where the 'RATS' setting should be ignored\n\t\tif len(commandParams.Entrypoint) > 0 || len(commandParams.Cmd) > 0 {\n\t\t\tcommandParams.DoRunAsTargetShell = false\n\t\t}\n\n\t\tif commandParams.DoRunAsTargetShell {\n\t\t\tcommandParams.DoTerminal = true\n\t\t}\n\n\t\tif !commandParams.ActionListNamespaces &&\n\t\t\t!commandParams.ActionListPods &&\n\t\t\t!commandParams.ActionListDebuggableContainers &&\n\t\t\t!commandParams.ActionListSessions &&\n\t\t\t!commandParams.ActionShowSessionLogs &&\n\t\t\t!commandParams.ActionConnectSession &&\n\t\t\tcommandParams.TargetRef == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\tif commandParams.Runtime != KubernetesRuntime {\n\t\t\t\t\txc.Out.Error(\"param.target\", \"missing target\")\n\t\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\t//NOTE:\n\t\t\t\t//It's ok to not specify the target container for k8s\n\t\t\t\t//We'll pick the default or first container in the target pod\n\t\t\t} else {\n\t\t\t\tcommandParams.TargetRef = ctx.Args().First()\n\t\t\t\tif ctx.Args().Len() > 1 && ctx.Args().Slice()[1] == \"--\" {\n\t\t\t\t\t//NOTE:\n\t\t\t\t\t//Keep the original 'no terminal' behavior\n\t\t\t\t\t//use this shortcut mode as a way to quickly\n\t\t\t\t\t//run one off commands in the debugged container\n\t\t\t\t\t//When there's 'no terminal' we show\n\t\t\t\t\t//the debugger container log at the end.\n\t\t\t\t\t//TODO: revisit the behavior later...\n\t\t\t\t\tcmdSlice := ctx.Args().Slice()[2:]\n\t\t\t\t\tvar cmdClean []string\n\t\t\t\t\tfor _, v := range cmdSlice {\n\t\t\t\t\t\tv = strings.TrimSpace(v)\n\t\t\t\t\t\tif v != \"\" {\n\t\t\t\t\t\t\tcmdClean = append(cmdClean, v)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif len(cmdClean) > 0 {\n\t\t\t\t\t\tcommandParams.Cmd = cmdClean\n\t\t\t\t\t\tcommandParams.DoTerminal = false\n\t\t\t\t\t\tcommandParams.DoRunAsTargetShell = false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif commandParams.DebugContainerImage == \"\" {\n\t\t\tcommandParams.DebugContainerImage = BusyboxImage\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues,\n\t\t\tcommandParams)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/debug_images.go",
    "content": "package debug\n\nimport (\n// \"strings\"\n)\n\nconst (\n\tCgrSlimToolkitDebugImage = \"cgr.dev/chainguard/slim-toolkit-debug:latest\"\n\tWolfiBaseImage           = \"cgr.dev/chainguard/wolfi-base:latest\"\n\tBusyboxImage             = \"busybox:latest\"\n\tNicolakaNetshootImage    = \"nicolaka/netshoot\"\n\tKoolkitsNodeImage        = \"lightruncom/koolkits:node\"\n\tKoolkitsPythonImage      = \"lightruncom/koolkits:python\"\n\tKoolkitsGolangImage      = \"lightruncom/koolkits:golang\"\n\tKoolkitsJVMImage         = \"lightruncom/koolkits:jvm\"\n\tDigitaloceanDoksImage    = \"digitalocean/doks-debug:latest\"\n\tZinclabsUbuntuImage      = \"public.ecr.aws/zinclabs/debug-ubuntu-base:latest\"\n\tInfuserImage             = \"ghcr.io/teaxyz/infuser:latest\"\n)\n\nvar debugImages = map[string]string{\n\tCgrSlimToolkitDebugImage: \"Chainguard SlimToolkit debug image - https://edu.chainguard.dev/chainguard/chainguard-images/reference/slim-toolkit-debug\",\n\tWolfiBaseImage:           \"A lightweight Wolfi base image - https://github.com/chainguard-images/images/tree/main/images/wolfi-base\",\n\tBusyboxImage:             \"A lightweight image with common unix utilities - https://busybox.net/about.html\",\n\tNicolakaNetshootImage:    \"Network trouble-shooting swiss-army container - https://github.com/nicolaka/netshoot\",\n\tKoolkitsNodeImage:        \"Node.js KoolKit - https://github.com/lightrun-platform/koolkits/tree/main/nodejs\",\n\tKoolkitsPythonImage:      \"Python KoolKit - https://github.com/lightrun-platform/koolkits/tree/main/python\",\n\tKoolkitsGolangImage:      \"Go KoolKit - https://github.com/lightrun-platform/koolkits/tree/main/golang\",\n\tKoolkitsJVMImage:         \"JVM KoolKit - https://github.com/lightrun-platform/koolkits/blob/main/jvm/README.md\",\n\tDigitaloceanDoksImage:    \"Kubernetes manifests for investigation and troubleshooting - https://github.com/digitalocean/doks-debug\",\n\tZinclabsUbuntuImage:      \"Common utilities for debugging your cluster - https://github.com/openobserve/debug-container\",\n\tInfuserImage:             \"Tea package manager image - https://github.com/teaxyz/infuser\",\n}\n\nfunc ShellCommandPrefix(imageName string) []string {\n\tshellName := defaultShellName\n\t//TODO:\n\t//Need to have a reliable solution to deal with\n\t//the dynamic library dependencies for bash\n\t//before we default to it in interactive debug shells\n\t//Need to work out the compat issues linking the shared\n\t//object dir(s) from the debugging container\n\t//if strings.Contains(imageName, \"lightruncom/koolkits\") ||\n\t//   strings.Contains(imageName, \"ubuntu\") ||\n\t//   strings.Contains(imageName, \"debian\") {\n\t//   \tshellName = bashShellName\n\t//   \t//debian/ubuntu-based images link 'sh' to 'dash', which doesn't support 'set -o pipefail'\n\t//}\n\n\treturn []string{shellName, \"-c\"}\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/flags.go",
    "content": "package debug\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Debug command flag names and usage descriptions\nconst (\n\tFlagRuntime      = \"runtime\"\n\tFlagRuntimeUsage = \"Runtime environment type\"\n\n\tFlagTarget      = \"target\"\n\tFlagTargetUsage = \"Target container (name or ID)\"\n\n\tFlagNamespace      = \"namespace\"\n\tFlagNamespaceUsage = \"Namespace to target (k8s runtime)\"\n\n\tFlagPod      = \"pod\"\n\tFlagPodUsage = \"Pod to target (k8s runtime)\"\n\n\tFlagDebugImage      = \"debug-image\"\n\tFlagDebugImageUsage = \"Debug image to use for the debug side-car container\"\n\n\tFlagEntrypoint      = \"entrypoint\"\n\tFlagEntrypointUsage = \"Custom ENTRYPOINT to use for the debug side-car container.\"\n\n\tFlagCmd      = \"cmd\"\n\tFlagCmdUsage = \"Custom CMD to use for the debug side-car container (alternatively pass custom CMD params after '--').\"\n\n\tFlagWorkdir      = \"workdir\"\n\tFlagWorkdirUsage = \"Custom WORKDIR to use for the debug side-car container.\"\n\n\t//value expected to be \"name=value\"\n\tFlagEnv      = \"env\"\n\tFlagEnvUsage = \"Environment variable to add to the debug side-car container.\"\n\n\t//TBD\n\tFlagMount      = \"mount\"\n\tFlagMountUsage = \"Volume mount to create in the debug side-car container.\"\n\n\t//TBD\n\tFlagLoadAllTargetEnvVars      = \"load-all-target-env-vars\"\n\tFlagLoadAllTargetEnvVarsUsage = \"Load all (known) environment variables from the target container\"\n\n\tFlagTerminal      = \"terminal\"\n\tFlagTerminalUsage = \"Attach interactive terminal to the debug container\"\n\n\tFlagRunAsTargetShell      = \"run-as-target-shell\"\n\tFlagRunAsTargetShellUsage = \"Attach interactive terminal to the debug container and run shell as if it's running in the target container environment.\"\n\n\tFlagListSessions      = \"list-sessions\"\n\tFlagListSessionsUsage = \"List all debug sessions for the selected target (pod and optionally selected container for k8s or container for other runtimes).\"\n\n\tFlagShowSessionLogs      = \"show-session-logs\"\n\tFlagShowSessionLogsUsage = \"Show logs for the selected debug session (using namespace, pod, target container or debug session container name for k8s or debug session container name for other runtimes).\"\n\n\tFlagSession      = \"session\"\n\tFlagSessionUsage = \"Debug session container name (used for debug sessoin actions).\"\n\n\tFlagConnectSession      = \"connect-session\"\n\tFlagConnectSessionUsage = \"Connect to existing debug session.\"\n\n\t//TBD\n\tFlagConnectLastSession      = \"connect-last-session\"\n\tFlagConnectLastSessionUsage = \"Connect to last debug session\"\n\n\tFlagListNamespaces      = \"list-namespaces\"\n\tFlagListNamespacesUsage = \"List names for available namespaces (use this flag by itself).\"\n\n\tFlagListPods      = \"list-pods\"\n\tFlagListPodsUsage = \"List names for running pods in the selected namespace (use this flag by itself).\"\n\n\tFlagListDebuggableContainers      = \"list-debuggable-containers\"\n\tFlagListDebuggableContainersUsage = \"List container names for active containers that can be debugged (use this flag by itself).\"\n\n\tFlagListDebugImage      = \"list-debug-images\"\n\tFlagListDebugImageUsage = \"List possible debug images to use for the debug side-car container (use this flag by itself).\"\n\n\tFlagKubeconfig      = \"kubeconfig\"\n\tFlagKubeconfigUsage = \"Kubeconfig file location (k8s runtime)\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagRuntime: &cli.StringFlag{\n\t\tName:    FlagRuntime,\n\t\tValue:   DockerRuntime,\n\t\tUsage:   FlagRuntimeUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_RT\"},\n\t},\n\tFlagTarget: &cli.StringFlag{\n\t\tName:    FlagTarget,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_TARGET\"},\n\t},\n\tFlagNamespace: &cli.StringFlag{\n\t\tName:    FlagNamespace,\n\t\tValue:   NamespaceDefault,\n\t\tUsage:   FlagNamespaceUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_TARGET_NS\"},\n\t},\n\tFlagPod: &cli.StringFlag{\n\t\tName:    FlagPod,\n\t\tValue:   \"\",\n\t\tUsage:   FlagPodUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_TARGET_POD\"},\n\t},\n\tFlagDebugImage: &cli.StringFlag{\n\t\tName:    FlagDebugImage,\n\t\tValue:   BusyboxImage,\n\t\tUsage:   FlagDebugImageUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_IMAGE\"},\n\t},\n\tFlagEntrypoint: &cli.StringFlag{\n\t\tName:    FlagEntrypoint,\n\t\tValue:   \"\",\n\t\tUsage:   FlagEntrypointUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_ENTRYPOINT\"},\n\t},\n\tFlagCmd: &cli.StringFlag{\n\t\tName:    FlagCmd,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCmdUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_CMD\"},\n\t},\n\tFlagWorkdir: &cli.StringFlag{\n\t\tName:    FlagWorkdir,\n\t\tValue:   \"\",\n\t\tUsage:   FlagWorkdirUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_WDIR\"},\n\t},\n\tFlagEnv: &cli.StringSliceFlag{\n\t\tName:    FlagEnv,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagEnvUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_ENV\"},\n\t},\n\tFlagTerminal: &cli.BoolFlag{\n\t\tName:    FlagTerminal,\n\t\tValue:   true, //attach interactive terminal by default\n\t\tUsage:   FlagTerminalUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_TERMINAL\"},\n\t},\n\tFlagRunAsTargetShell: &cli.BoolFlag{\n\t\tName:    FlagRunAsTargetShell,\n\t\tValue:   true, //do it by default (FlagTerminal will be ignored, assumed to be true)\n\t\tUsage:   FlagRunAsTargetShellUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_RATS\"},\n\t},\n\tFlagListSessions: &cli.BoolFlag{\n\t\tName:    FlagListSessions,\n\t\tValue:   false,\n\t\tUsage:   FlagListSessionsUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_LIST_SESSIONS\"},\n\t},\n\tFlagShowSessionLogs: &cli.BoolFlag{\n\t\tName:    FlagShowSessionLogs,\n\t\tValue:   false,\n\t\tUsage:   FlagShowSessionLogsUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_SHOW_SESSION_LOGS\"},\n\t},\n\tFlagConnectSession: &cli.BoolFlag{\n\t\tName:    FlagConnectSession,\n\t\tValue:   false,\n\t\tUsage:   FlagConnectSessionUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_CONNECT_SESSION\"},\n\t},\n\tFlagSession: &cli.StringFlag{\n\t\tName:    FlagSession,\n\t\tValue:   \"\",\n\t\tUsage:   FlagSessionUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_SESSION\"},\n\t},\n\tFlagListNamespaces: &cli.BoolFlag{\n\t\tName:    FlagListNamespaces,\n\t\tValue:   false,\n\t\tUsage:   FlagListNamespacesUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_LIST_NAMESPACES\"},\n\t},\n\tFlagListPods: &cli.BoolFlag{\n\t\tName:    FlagListPods,\n\t\tValue:   false,\n\t\tUsage:   FlagListPodsUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_LIST_PODS\"},\n\t},\n\tFlagListDebuggableContainers: &cli.BoolFlag{\n\t\tName:    FlagListDebuggableContainers,\n\t\tValue:   false,\n\t\tUsage:   FlagListDebuggableContainersUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_LIST_CONTAINERS\"},\n\t},\n\tFlagListDebugImage: &cli.BoolFlag{\n\t\tName:    FlagListDebugImage,\n\t\tValue:   false,\n\t\tUsage:   FlagListDebugImageUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_LIST_IMAGES\"},\n\t},\n\tFlagKubeconfig: &cli.StringFlag{\n\t\tName:    FlagKubeconfig,\n\t\tValue:   KubeconfigDefault,\n\t\tUsage:   FlagKubeconfigUsage,\n\t\tEnvVars: []string{\"DSLIM_DBG_KUBECONFIG\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/handle_docker_runtime.go",
    "content": "package debug\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/container\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n)\n\n// HandleDockerRuntime implements support for the docker runtime\nfunc HandleDockerRuntime(\n\tlogger *log.Entry,\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcommandParams *CommandParams,\n\tclient *dockerapi.Client,\n\tsid string,\n\tdebugContainerName string) {\n\n\tif commandParams.ActionListDebuggableContainers {\n\t\txc.Out.State(\"action.list_debuggable_containers\")\n\n\t\tresult, err := listDockerDebuggableContainers(client)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listDockerDebuggableContainers\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\txc.Out.Info(\"debuggable.containers\", ovars{\"count\": len(result)})\n\t\tfor cname, iname := range result {\n\t\t\txc.Out.Info(\"debuggable.container\", ovars{\"name\": cname, \"image\": iname})\n\t\t}\n\n\t\treturn\n\t}\n\n\t//todo: need to check that if targetRef is not empty it is valid\n\n\tif commandParams.ActionListSessions {\n\t\txc.Out.State(\"action.list_sessions\", ovars{\"target\": commandParams.TargetRef})\n\n\t\t//later will track/show additional debug session info\n\t\tresult, err := listDockerDebugContainers(client, commandParams.TargetRef, false)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listDockerDebugContainers\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\tvar waitingCount int\n\t\tvar runningCount int\n\t\tvar terminatedCount int\n\t\tfor _, info := range result {\n\t\t\tswitch info.State {\n\t\t\tcase CSWaiting:\n\t\t\t\twaitingCount++\n\t\t\tcase CSRunning:\n\t\t\t\trunningCount++\n\t\t\tcase CSTerminated:\n\t\t\t\tterminatedCount++\n\t\t\t}\n\t\t}\n\n\t\txc.Out.Info(\"debug.session.count\",\n\t\t\tovars{\n\t\t\t\t\"total\":      len(result),\n\t\t\t\t\"running\":    runningCount,\n\t\t\t\t\"waiting\":    waitingCount,\n\t\t\t\t\"terminated\": terminatedCount,\n\t\t\t})\n\n\t\tfor name, info := range result {\n\t\t\toutParams := ovars{\n\t\t\t\t\"target\":     info.TargetContainerName,\n\t\t\t\t\"name\":       name,\n\t\t\t\t\"image\":      info.SpecImage,\n\t\t\t\t\"state\":      info.State,\n\t\t\t\t\"start.time\": info.StartTime,\n\t\t\t}\n\n\t\t\t/*\n\t\t\t\tif info.State == CSTerminated {\n\t\t\t\t\toutParams[\"exit.code\"] = info.ExitCode\n\t\t\t\t\toutParams[\"finish.time\"] = info.FinishTime\n\t\t\t\t\tif info.ExitReason != \"\" {\n\t\t\t\t\t\toutParams[\"exit.reason\"] = info.ExitReason\n\t\t\t\t\t}\n\t\t\t\t\tif info.ExitMessage != \"\" {\n\t\t\t\t\t\toutParams[\"exit.message\"] = info.ExitMessage\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t*/\n\n\t\t\txc.Out.Info(\"debug.session\", outParams)\n\t\t}\n\n\t\treturn\n\t}\n\n\tif commandParams.ActionShowSessionLogs {\n\t\txc.Out.State(\"action.show_session_logs\",\n\t\t\tovars{\n\t\t\t\t\"target\":  commandParams.TargetRef,\n\t\t\t\t\"session\": commandParams.Session})\n\n\t\tresult, err := listDockerDebugContainers(client, commandParams.TargetRef, false)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listDockerDebugContainers\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\tif len(result) < 1 {\n\t\t\txc.Out.Info(\"no.debug.session\")\n\t\t\treturn\n\t\t}\n\n\t\t//todo: need to pick the last session if commandParams.Session is empty\n\t\tvar containerID string\n\t\tfor _, info := range result {\n\t\t\tif commandParams.Session == \"\" {\n\t\t\t\tcommandParams.Session = info.Name\n\t\t\t}\n\n\t\t\tif commandParams.Session == info.Name {\n\t\t\t\tcontainerID = info.ContainerID\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\txc.Out.Info(\"container.logs.target\", ovars{\n\t\t\t\"container.name\": commandParams.Session,\n\t\t\t\"container.id\":   containerID})\n\n\t\tif err := dumpDockerContainerLogs(logger, xc, client, containerID); err != nil {\n\t\t\tlogger.WithError(err).Error(\"dumpDockerContainerLogs\")\n\t\t}\n\n\t\treturn\n\t}\n\n\tif commandParams.ActionConnectSession {\n\t\txc.Out.State(\"action.connect_session\",\n\t\t\tovars{\n\t\t\t\t\"target\":  commandParams.TargetRef,\n\t\t\t\t\"session\": commandParams.Session})\n\n\t\tresult, err := listDockerDebugContainers(client, commandParams.TargetRef, true)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listDockerDebugContainers\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\tif len(result) < 1 {\n\t\t\txc.Out.Info(\"no.debug.session\")\n\t\t\treturn\n\t\t}\n\n\t\t//todo: need to pick the last session if commandParams.Session is empty\n\t\tvar containerID string\n\t\tfor _, info := range result {\n\t\t\tif commandParams.Session == \"\" {\n\t\t\t\tcommandParams.Session = info.Name\n\t\t\t}\n\n\t\t\tif commandParams.Session == info.Name {\n\t\t\t\tcontainerID = info.ContainerID\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\t//todo: need to validate that the session container exists and it's running\n\n\t\tr, w := io.Pipe()\n\t\tgo io.Copy(w, os.Stdin)\n\n\t\toptions := dockerapi.AttachToContainerOptions{\n\t\t\tContainer:    containerID,\n\t\t\tInputStream:  r,\n\t\t\tOutputStream: os.Stdout,\n\t\t\tErrorStream:  os.Stderr,\n\t\t\tStdin:        true,\n\t\t\tStdout:       true,\n\t\t\tStderr:       true,\n\t\t\tStream:       true,\n\t\t\tRawTerminal:  true,\n\t\t\tLogs:         true,\n\t\t}\n\n\t\terr = client.AttachToContainer(options)\n\t\txc.FailOn(err)\n\t\treturn\n\t}\n\n\timageInspector, err := image.NewInspector(client, commandParams.DebugContainerImage)\n\terrutil.FailOn(err)\n\tnoImage, err := imageInspector.NoImage()\n\terrutil.FailOn(err)\n\tif noImage {\n\t\terr := imageInspector.Pull(true, \"\", \"\", \"\")\n\t\txc.FailOn(err)\n\t}\n\n\ttargetContainerInfo, err := client.InspectContainer(commandParams.TargetRef)\n\tif err != nil {\n\t\txc.Out.Error(\"target.container.inspect\", err.Error())\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": -1,\n\t\t\t})\n\t\txc.Exit(-1)\n\t}\n\n\tif commandParams.DoRunAsTargetShell {\n\t\tlogger.Trace(\"doRunAsTargetShell\")\n\t\tcommandParams.Entrypoint = ShellCommandPrefix(commandParams.DebugContainerImage)\n\t\tshellConfig := configShell(sid, false)\n\t\tif CgrSlimToolkitDebugImage == commandParams.DebugContainerImage {\n\t\t\tshellConfig = configShellAlt(sid, false)\n\t\t}\n\n\t\tcommandParams.Cmd = []string{shellConfig}\n\t} else {\n\t\tif len(commandParams.Cmd) == 0 &&\n\t\t\tCgrSlimToolkitDebugImage == commandParams.DebugContainerImage {\n\t\t\tcommandParams.Cmd = []string{bashShellName}\n\t\t}\n\t}\n\n\toptions := container.ExecutionOptions{\n\t\tContainerName: debugContainerName,\n\t\tEntrypoint:    commandParams.Entrypoint,\n\t\tCmd:           commandParams.Cmd,\n\t\tTerminal:      commandParams.DoTerminal,\n\t}\n\n\texe, err := container.NewExecution(\n\t\txc,\n\t\tlogger,\n\t\tclient,\n\t\tcommandParams.DebugContainerImage,\n\t\t&options,\n\t\tnil,\n\t\ttrue,\n\t\ttrue)\n\n\t// attach network, IPC & PIDs, essentially this is run --network container:golang_service --pid container:golang_service --ipc container:golang_service\n\tmode := fmt.Sprintf(\"container:%s\", commandParams.TargetRef)\n\n\tif targetContainerInfo.HostConfig.IpcMode == \"shareable\" {\n\t\texe.IpcMode = mode\n\t}\n\n\texe.NetworkMode = mode\n\texe.PidMode = mode\n\n\txc.FailOn(err)\n\n\terr = exe.Start()\n\txc.FailOn(err)\n\n\t_, err = exe.Wait()\n\txc.FailOn(err)\n\n\tdefer func() {\n\t\terr = exe.Cleanup()\n\t\terrutil.WarnOn(err)\n\t}()\n\n\tif !commandParams.DoTerminal {\n\t\texe.ShowContainerLogs()\n\t}\n}\n\nfunc listDockerDebuggableContainers(client *dockerapi.Client) (map[string]string, error) {\n\tconst op = \"debug.listDockerDebuggableContainers\"\n\n\tcontainers, err := dockerutil.ListContainers(client, \"\", false)\n\tif err != nil {\n\t\tlog.WithFields(log.Fields{\n\t\t\t\"op\":               op,\n\t\t\t\"containers.count\": len(containers),\n\t\t}).Error(\"dockerutil.ListContainers\")\n\t\treturn nil, err\n\t}\n\n\tactiveContainers := map[string]string{}\n\tfor name, info := range containers {\n\t\tif info.State != dockerutil.CSRunning {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":        \"listDockerDebuggableContainers\",\n\t\t\t\t\"container\": name,\n\t\t\t\t\"state\":     info.State,\n\t\t\t}).Trace(\"ignoring.nonrunning.container\")\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasPrefix(name, containerNamePrefix) {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":        \"listDockerDebuggableContainers\",\n\t\t\t\t\"container\": name,\n\t\t\t}).Trace(\"ignoring.debug.container\")\n\t\t\tcontinue\n\t\t}\n\n\t\tactiveContainers[name] = info.Image\n\t}\n\n\treturn activeContainers, nil\n}\n\nfunc listDebuggableDockerContainersWithConfig(client *dockerapi.Client) (map[string]string, error) {\n\t//todo: pass the docker client config params instead of the existing client\n\treturn listDockerDebuggableContainers(client)\n}\n\nfunc listDockerDebugContainers(\n\tclient *dockerapi.Client,\n\ttargetContainer string,\n\tonlyActive bool) (map[string]*DebugContainerInfo, error) {\n\tcontainers, err := dockerutil.ListContainers(client, \"\", true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresult := map[string]*DebugContainerInfo{}\n\tfor name, container := range containers {\n\t\tif !strings.HasPrefix(name, containerNamePrefix) {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":        \"listDockerDebugContainers\",\n\t\t\t\t\"container\": name,\n\t\t\t}).Trace(\"ignoring.nondebug.container\")\n\t\t\tcontinue\n\t\t}\n\n\t\t//todo: filter by targetContainer (when info.TargetContainerName is populated)\n\n\t\tt := time.Unix(container.Created, 0) //UnixMilli, UnixMicro\n\t\tinfo := &DebugContainerInfo{\n\t\t\t//TargetContainerName: info.TargetContainerName,\n\t\t\tName:        container.Name,\n\t\t\tSpecImage:   container.Image,\n\t\t\tContainerID: container.ID,\n\t\t\t//Command:             info.Command,\n\t\t\t//Args:                info.Args,\n\t\t\t//WorkingDir:          info.WorkingDir,\n\t\t\t//TTY:                 info.TTY,\n\t\t\tStartTime: fmt.Sprintf(\"%v\", t),\n\t\t}\n\n\t\tswitch container.State {\n\t\tcase dockerutil.CSCreated, dockerutil.CSRestarting, dockerutil.CSPaused:\n\t\t\tinfo.State = CSWaiting\n\t\tcase dockerutil.CSRunning:\n\t\t\tinfo.State = CSRunning\n\t\tcase dockerutil.CSRemoving, dockerutil.CSExited, dockerutil.CSDead:\n\t\t\tinfo.State = CSTerminated\n\t\t}\n\n\t\tif onlyActive {\n\t\t\tif info.State == CSRunning {\n\t\t\t\tresult[info.Name] = info\n\t\t\t}\n\t\t} else {\n\t\t\tresult[info.Name] = info\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc listDockerDebugContainersWithConfig(\n\tclient *dockerapi.Client,\n\ttargetContainer string,\n\tonlyActive bool) (map[string]*DebugContainerInfo, error) {\n\t//todo: pass the docker client config params instead of the existing client\n\treturn listDockerDebugContainers(client, targetContainer, onlyActive)\n}\n\nfunc dumpDockerContainerLogs(\n\tlogger *log.Entry,\n\txc *app.ExecutionContext,\n\tclient *dockerapi.Client,\n\tcontainerID string) error {\n\tlogger.Tracef(\"dumpDockerContainerLogs(%s)\", containerID)\n\n\toutData, errData, err := dockerutil.GetContainerLogs(client, containerID, true)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"error reading container logs\")\n\t\treturn err\n\t}\n\n\txc.Out.Info(\"container.logs.start\")\n\txc.Out.LogDump(\"debug.container.logs.stdout\", string(outData))\n\txc.Out.LogDump(\"debug.container.logs.stderr\", string(errData))\n\txc.Out.Info(\"container.logs.end\")\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/handle_kubernetes_runtime.go",
    "content": "package debug\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n\t\"k8s.io/client-go/kubernetes\"\n\t\"k8s.io/client-go/kubernetes/scheme\"\n\trestclient \"k8s.io/client-go/rest\"\n\t\"k8s.io/client-go/tools/clientcmd\"\n\t\"k8s.io/client-go/tools/remotecommand\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\n// HandleKubernetesRuntime implements support for the k8s runtime\nfunc HandleKubernetesRuntime(\n\tlogger *log.Entry,\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcommandParams *CommandParams,\n\tsid string,\n\tdebugContainerName string) {\n\tlogger = logger.WithFields(\n\t\tlog.Fields{\n\t\t\t\"op\": \"debug.HandleKubernetesRuntime\",\n\t\t})\n\n\tcpJson, _ := json.Marshal(commandParams)\n\tlogger.WithField(\"cparams\", string(cpJson)).Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tctx := context.Background()\n\n\tapi, restConfig, err := apiClientFromConfig(commandParams.Kubeconfig)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"apiClientFromConfig\")\n\t\txc.FailOn(err)\n\t}\n\n\tif commandParams.ActionListNamespaces {\n\t\txc.Out.State(\"action.list_namespaces\")\n\t\tnames, err := listNamespaces(ctx, api)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listNamespaces\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\tfor _, name := range names {\n\t\t\txc.Out.Info(\"namespace\", ovars{\"name\": name})\n\t\t}\n\n\t\treturn\n\t}\n\n\tnsName, err := ensureNamespace(ctx, api, commandParams.TargetNamespace)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"ensureNamespace\")\n\t\txc.FailOn(err)\n\t}\n\n\tif commandParams.ActionListPods {\n\t\txc.Out.State(\"action.list_pods\", ovars{\"namespace\": nsName})\n\t\tnames, err := listActivePods(ctx, api, nsName)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listActivePods\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\tfor _, name := range names {\n\t\t\txc.Out.Info(\"pod\", ovars{\"name\": name})\n\t\t}\n\n\t\treturn\n\t}\n\n\tpod, podName, err := ensurePod(ctx, api, nsName, commandParams.TargetPod)\n\tif apierrors.IsNotFound(err) {\n\t\tlogger.WithError(err).\n\t\t\tWithFields(log.Fields{\n\t\t\t\t\"ns\":  nsName,\n\t\t\t\t\"pod\": podName,\n\t\t\t}).Error(\"ensurePod - not found\")\n\t\txc.FailOn(err)\n\t} else if statusError, isStatus := err.(*apierrors.StatusError); isStatus {\n\t\tlogger.WithError(err).\n\t\t\tWithFields(log.Fields{\n\t\t\t\t\"ns\":     nsName,\n\t\t\t\t\"pod\":    podName,\n\t\t\t\t\"status\": statusError.ErrStatus.Message,\n\t\t\t}).Error(\"ensurePod - status error\")\n\t\txc.FailOn(err)\n\t} else if err != nil {\n\t\tlogger.WithError(err).\n\t\t\tWithFields(log.Fields{\n\t\t\t\t\"ns\":     nsName,\n\t\t\t\t\"pod\":    podName,\n\t\t\t\t\"status\": statusError.ErrStatus.Message,\n\t\t\t}).Error(\"ensurePod - other error\")\n\t\txc.FailOn(err)\n\t}\n\n\tlogger.WithField(\"phase\", pod.Status.Phase).Debug(\"target pod status\")\n\n\tif pod.Status.Phase != corev1.PodRunning {\n\t\tlogger.Error(\"target pod is not running\")\n\t\txc.FailOn(fmt.Errorf(\"target pod is not running\"))\n\t}\n\n\tlogger.WithFields(\n\t\tlog.Fields{\n\t\t\t\"ns\":       nsName,\n\t\t\t\"pod\":      podName,\n\t\t\t\"ec.count\": len(pod.Spec.EphemeralContainers),\n\t\t}).Debug(\"target pod info\")\n\n\tif commandParams.ActionListDebuggableContainers {\n\t\txc.Out.State(\"action.list_debuggable_containers\",\n\t\t\tovars{\"namespace\": nsName, \"pod\": podName})\n\t\tresult, err := listK8sDebuggableContainers(ctx, api, nsName, podName)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listK8sDebuggableContainers\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\tfor cname, iname := range result {\n\t\t\txc.Out.Info(\"debuggable.container\", ovars{\"name\": cname, \"image\": iname})\n\t\t}\n\n\t\treturn\n\t}\n\n\t//todo: need to check that if targetRef is not empty it is valid\n\n\tif commandParams.ActionListSessions {\n\t\t//list sessions before we pick a target container,\n\t\t//so we can list all debug session for the selected pod\n\t\txc.Out.State(\"action.list_sessions\",\n\t\t\tovars{\n\t\t\t\t\"namespace\": nsName,\n\t\t\t\t\"pod\":       podName,\n\t\t\t\t\"target\":    commandParams.TargetRef})\n\n\t\t//later will track/show additional debug session info\n\t\tresult, err := listK8sDebugContainers(ctx, api, nsName, podName, commandParams.TargetRef, false)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"listK8sDebugContainers\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\tvar waitingCount int\n\t\tvar runningCount int\n\t\tvar terminatedCount int\n\t\tfor _, info := range result {\n\t\t\tswitch info.State {\n\t\t\tcase CSWaiting:\n\t\t\t\twaitingCount++\n\t\t\tcase CSRunning:\n\t\t\t\trunningCount++\n\t\t\tcase CSTerminated:\n\t\t\t\tterminatedCount++\n\t\t\t}\n\t\t}\n\n\t\txc.Out.Info(\"debug.session.count\",\n\t\t\tovars{\n\t\t\t\t\"total\":      len(result),\n\t\t\t\t\"running\":    runningCount,\n\t\t\t\t\"waiting\":    waitingCount,\n\t\t\t\t\"terminated\": terminatedCount,\n\t\t\t})\n\n\t\tfor name, info := range result {\n\t\t\toutParams := ovars{\n\t\t\t\t\"target\":     info.TargetContainerName,\n\t\t\t\t\"name\":       name,\n\t\t\t\t\"image\":      info.SpecImage,\n\t\t\t\t\"state\":      info.State,\n\t\t\t\t\"start.time\": info.StartTime,\n\t\t\t}\n\n\t\t\tif info.State == CSTerminated {\n\t\t\t\toutParams[\"exit.code\"] = info.ExitCode\n\t\t\t\toutParams[\"finish.time\"] = info.FinishTime\n\t\t\t\tif info.ExitReason != \"\" {\n\t\t\t\t\toutParams[\"exit.reason\"] = info.ExitReason\n\t\t\t\t}\n\t\t\t\tif info.ExitMessage != \"\" {\n\t\t\t\t\toutParams[\"exit.message\"] = info.ExitMessage\n\t\t\t\t}\n\t\t\t}\n\n\t\t\txc.Out.Info(\"debug.session\", outParams)\n\t\t}\n\n\t\treturn\n\t}\n\n\tif commandParams.TargetRef == \"\" {\n\t\tlogger.Debug(\"no explicit target container... pick one\")\n\t\t//TODO: improve this logic (to also check for the default container)\n\t\tif len(pod.Spec.Containers) > 0 {\n\t\t\tcommandParams.TargetRef = pod.Spec.Containers[0].Name\n\t\t} else {\n\t\t\txc.FailOn(fmt.Errorf(\"no containers\"))\n\t\t}\n\t}\n\n\tif commandParams.ActionShowSessionLogs {\n\t\t//list sessions before we pick a target container,\n\t\t//so we can list all debug session for the selected pod\n\t\txc.Out.State(\"action.show_session_logs\",\n\t\t\tovars{\n\t\t\t\t\"namespace\": nsName,\n\t\t\t\t\"pod\":       podName,\n\t\t\t\t\"target\":    commandParams.TargetRef,\n\t\t\t\t\"session\":   commandParams.Session})\n\n\t\tif commandParams.Session == \"\" {\n\t\t\tresult, err := listK8sDebugContainers(ctx, api, nsName, podName, commandParams.TargetRef, false)\n\t\t\tif err != nil {\n\t\t\t\tlogger.WithError(err).Error(\"listK8sDebugContainers\")\n\t\t\t\txc.FailOn(err)\n\t\t\t}\n\n\t\t\tif len(result) < 1 {\n\t\t\t\txc.Out.Info(\"no.debug.session\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t//todo: need to pick the last session\n\t\t\tfor _, info := range result {\n\t\t\t\tcommandParams.Session = info.Name\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif err := dumpK8sContainerLogs(logger, xc, ctx, api, nsName, podName, commandParams.Session); err != nil {\n\t\t\tlogger.WithError(err).Error(\"dumpK8sContainerLogs\")\n\t\t}\n\n\t\treturn\n\t}\n\n\tif commandParams.ActionConnectSession {\n\t\txc.Out.State(\"action.connect_session\",\n\t\t\tovars{\n\t\t\t\t\"namespace\": nsName,\n\t\t\t\t\"pod\":       podName,\n\t\t\t\t\"target\":    commandParams.TargetRef,\n\t\t\t\t\"session\":   commandParams.Session})\n\n\t\tif commandParams.Session == \"\" {\n\t\t\tresult, err := listK8sDebugContainers(ctx, api, nsName, podName, commandParams.TargetRef, true)\n\t\t\tif err != nil {\n\t\t\t\tlogger.WithError(err).Error(\"listK8sDebugContainers\")\n\t\t\t\txc.FailOn(err)\n\t\t\t}\n\n\t\t\tif len(result) < 1 {\n\t\t\t\txc.Out.Info(\"no.debug.session\")\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t//todo: need to pick the last session\n\t\t\tfor _, info := range result {\n\t\t\t\tcommandParams.Session = info.Name\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t//todo: need to validate that the debug session container exists and it's running\n\n\t\t//note: tty should be controlled by the 'terminal' flag\n\t\t//and connecting would not be interactive if it's not true\n\t\tdoTTY := true\n\n\t\treq := api.CoreV1().RESTClient().Post().\n\t\t\tResource(\"pods\").\n\t\t\tName(podName).\n\t\t\tNamespace(nsName).\n\t\t\tSubResource(\"attach\").\n\t\t\tVersionedParams(&corev1.PodAttachOptions{\n\t\t\t\tContainer: commandParams.Session,\n\t\t\t\tStdin:     true,\n\t\t\t\tStdout:    true,\n\t\t\t\tStderr:    true,\n\t\t\t\tTTY:       doTTY,\n\t\t\t}, scheme.ParameterCodec)\n\n\t\tlogger.Tracef(\"(connect to session) pod attach request URL: %s\", req.URL())\n\n\t\tattach, err := remotecommand.NewSPDYExecutor(restConfig, http.MethodPost, req.URL())\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"remotecommand.NewSPDYExecutor\")\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\txc.Out.Info(\"terminal.start\",\n\t\t\tovars{\n\t\t\t\t\"mode\": \"connecting to existing debug session\",\n\t\t\t\t\"note\": \"press enter if you dont see any output\",\n\t\t\t})\n\n\t\tlogger.Trace(\"starting stream...\")\n\t\t//TODO:\n\t\t//use commandParams.DoTerminal to conditionally enable the interactive terminal\n\t\t//if false configure stream to do a one off command execution\n\t\t//and dump the container logs\n\t\t//similar to how it's done with the docker runtime\n\n\t\tfmt.Printf(\"\\n\")\n\t\t//note: blocks until done streaming or failure...\n\t\terr = attach.StreamWithContext(\n\t\t\tctx,\n\t\t\tremotecommand.StreamOptions{\n\t\t\t\tStdin:  os.Stdin,\n\t\t\t\tStdout: os.Stdout,\n\t\t\t\tStderr: os.Stderr,\n\t\t\t\tTty:    doTTY,\n\t\t\t})\n\n\t\tif err != nil {\n\t\t\tif apierrors.IsNotFound(err) {\n\t\t\t\tlogger.WithError(err).\n\t\t\t\t\tError(\"attach.StreamWithContext - not found\")\n\t\t\t} else if statusError, isStatus := err.(*apierrors.StatusError); isStatus {\n\t\t\t\tlogger.WithError(err).\n\t\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\t\"status\": statusError.ErrStatus.Message,\n\t\t\t\t\t}).Error(\"attach.StreamWithContext - status error\")\n\t\t\t} else {\n\t\t\t\tlogger.WithError(err).\n\t\t\t\t\tError(\"attach.StreamWithContext - other error\")\n\t\t\t}\n\n\t\t\txc.FailOn(err)\n\t\t}\n\n\t\treturn\n\t}\n\n\tlogger.WithField(\"target\", commandParams.TargetRef).Debug(\"locating container\")\n\n\ttargetContainerIndex := -1\n\ttargetContainerIsRunning := false\n\tvar targetContainer *corev1.Container\n\tfor i, c := range pod.Spec.Containers {\n\t\tif c.Name == commandParams.TargetRef {\n\t\t\ttargetContainerIndex = i\n\t\t\ttargetContainer = &c\n\n\t\t\tlogger.WithFields(\n\t\t\t\tlog.Fields{\n\t\t\t\t\t\"index\":  targetContainerIndex,\n\t\t\t\t\t\"ns\":     nsName,\n\t\t\t\t\t\"pod\":    podName,\n\t\t\t\t\t\"target\": commandParams.TargetRef,\n\t\t\t\t}).Trace(\"found container\")\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif targetContainer != nil {\n\t\t//doTTY = targetContainer.TTY\n\t\tlogger.WithField(\"data\", fmt.Sprintf(\"%#v\", targetContainer)).Trace(\"target container info\")\n\t}\n\n\tcontainerFound := false\n\tfor _, containerStatus := range pod.Status.ContainerStatuses {\n\t\tif containerStatus.Name == commandParams.TargetRef {\n\t\t\tcontainerFound = true\n\t\t\tif containerStatus.State.Running != nil {\n\t\t\t\ttargetContainerIsRunning = true\n\t\t\t\tlogger.Trace(\"target container is running\")\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !containerFound {\n\t\tlogger.Errorf(\"Container %s not found in pod %s\", commandParams.TargetRef, podName)\n\t\txc.FailOn(fmt.Errorf(\"target container not found\"))\n\t}\n\n\tif !targetContainerIsRunning {\n\t\txc.Out.Info(\"wait.for.target.container\",\n\t\t\tovars{\n\t\t\t\t\"name\":      commandParams.TargetRef,\n\t\t\t\t\"pod\":       podName,\n\t\t\t\t\"namespace\": nsName,\n\t\t\t})\n\n\t\terr = waitForContainer(logger, xc, ctx, api, nsName, podName, commandParams.TargetRef, ctStandard)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"waitForContainer\")\n\t\t\txc.FailOn(err)\n\t\t}\n\t}\n\n\t//'tty' config needs to be the same when creating & attaching\n\tdoTTY := true\n\tisEcPrivileged := true\n\n\tif commandParams.DoRunAsTargetShell {\n\t\tlogger.Trace(\"doRunAsTargetShell\")\n\t\tcommandParams.Entrypoint = ShellCommandPrefix(commandParams.DebugContainerImage)\n\t\tshellConfig := configShell(sid, true)\n\t\tif CgrSlimToolkitDebugImage == commandParams.DebugContainerImage {\n\t\t\tshellConfig = configShellAlt(sid, true)\n\t\t}\n\n\t\tcommandParams.Cmd = []string{shellConfig}\n\t} else {\n\t\tif len(commandParams.Cmd) == 0 &&\n\t\t\tCgrSlimToolkitDebugImage == commandParams.DebugContainerImage {\n\t\t\tcommandParams.Cmd = []string{bashShellName}\n\t\t}\n\t}\n\n\tlogger.WithFields(\n\t\tlog.Fields{\n\t\t\t\"work.dir\": commandParams.Workdir,\n\t\t\t\"params\":   fmt.Sprintf(\"%#v\", commandParams),\n\t\t}).Trace(\"newEphemeralContainerInfo\")\n\n\t//TODO: pass commandParams.DoTerminal\n\tecInfo := newEphemeralContainerInfo(\n\t\tcommandParams.TargetRef,\n\t\tdebugContainerName,\n\t\tcommandParams.DebugContainerImage,\n\t\tcommandParams.Entrypoint,\n\t\tcommandParams.Cmd,\n\t\tcommandParams.Workdir,\n\t\tcommandParams.EnvVars,\n\t\tisEcPrivileged,\n\t\tdoTTY)\n\n\tpod.Spec.EphemeralContainers = append(pod.Spec.EphemeralContainers, ecInfo)\n\n\t_, err = api.CoreV1().\n\t\tPods(pod.Namespace).\n\t\tUpdateEphemeralContainers(ctx, pod.Name, pod, metav1.UpdateOptions{})\n\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"error adding the ephemeral container to target pod\")\n\t\txc.FailOn(err)\n\t}\n\n\tupdatedPod, err := api.CoreV1().\n\t\tPods(pod.Namespace).\n\t\tGet(ctx, pod.Name, metav1.GetOptions{})\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"error getting the ephemeral container from target pod\")\n\t\txc.FailOn(err)\n\t}\n\n\tlogger.WithFields(\n\t\tlog.Fields{\n\t\t\t\"ns\":     nsName,\n\t\t\t\"pod\":    podName,\n\t\t\t\"target\": commandParams.TargetRef,\n\t\t\t\"image\":  commandParams.DebugContainerImage,\n\t\t}).Debug(\"attached ephemeral container\")\n\n\tec := ephemeralContainerFromPod(updatedPod, commandParams.TargetRef, debugContainerName)\n\tif ec == nil {\n\t\tlogger.Errorf(\"ephemeral container not found in pod\")\n\t\txc.FailOn(fmt.Errorf(\"ephemeral container not found\"))\n\t}\n\n\tecData, _ := json.Marshal(ec)\n\tlogger.WithField(\"data\", string(ecData)).Trace(\"ephemeral container\")\n\n\tvar ecContainerIsRunning bool\n\tfor _, ecStatus := range updatedPod.Status.EphemeralContainerStatuses {\n\t\tif ecStatus.Name == debugContainerName {\n\t\t\tif ecStatus.State.Running != nil {\n\t\t\t\tecContainerIsRunning = true\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif !ecContainerIsRunning {\n\t\txc.Out.Info(\"wait.for.debug.container\",\n\t\t\tovars{\n\t\t\t\t\"name\":      debugContainerName,\n\t\t\t\t\"pod\":       podName,\n\t\t\t\t\"namespace\": nsName,\n\t\t\t})\n\n\t\terr = waitForContainer(logger, xc, ctx, api, nsName, podName, debugContainerName, ctEphemeral)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"waitForContainer\")\n\n\t\t\tif err == ErrContainerTerminated {\n\t\t\t\txc.Out.Error(\"debug.container.error\", \"terminated\")\n\n\t\t\t\tif err := dumpK8sContainerLogs(logger, xc, ctx, api, nsName, podName, debugContainerName); err != nil {\n\t\t\t\t\tlogger.WithError(err).Error(\"dumpK8sContainerLogs\")\n\t\t\t\t}\n\n\t\t\t\txc.Out.State(\"debug.container.error\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t\t})\n\t\t\t\txc.Exit(-1)\n\t\t\t} else {\n\t\t\t\txc.FailOn(err)\n\t\t\t}\n\t\t}\n\t}\n\n\txc.Out.State(\"debug.container.running\")\n\n\treq := api.CoreV1().RESTClient().Post().\n\t\tResource(\"pods\").\n\t\tName(podName).\n\t\tNamespace(nsName).\n\t\tSubResource(\"attach\").\n\t\tVersionedParams(&corev1.PodAttachOptions{\n\t\t\tContainer: debugContainerName,\n\t\t\tStdin:     true,\n\t\t\tStdout:    true,\n\t\t\tStderr:    true,\n\t\t\tTTY:       doTTY,\n\t\t}, scheme.ParameterCodec)\n\n\tlogger.Tracef(\"pod attach request URL: %s\", req.URL())\n\n\tattach, err := remotecommand.NewSPDYExecutor(restConfig, http.MethodPost, req.URL())\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"remotecommand.NewSPDYExecutor\")\n\t\txc.FailOn(err)\n\t}\n\n\txc.Out.Info(\"terminal.start\",\n\t\tovars{\n\t\t\t\"note\": \"press enter if you dont see any output\",\n\t\t})\n\n\tlogger.Trace(\"starting stream...\")\n\t//TODO:\n\t//use commandParams.DoTerminal to conditionally enable the interactive terminal\n\t//if false configure stream to do a one off command execution\n\t//and dump the container logs\n\t//similar to how it's done with the docker runtime\n\n\tfmt.Printf(\"\\n\")\n\t//note: blocks until done streaming or failure...\n\terr = attach.StreamWithContext(\n\t\tctx,\n\t\tremotecommand.StreamOptions{\n\t\t\tStdin:  os.Stdin,\n\t\t\tStdout: os.Stdout,\n\t\t\tStderr: os.Stderr,\n\t\t\tTty:    doTTY,\n\t\t})\n\n\tif err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlogger.WithError(err).\n\t\t\t\tError(\"attach.StreamWithContext - not found\")\n\t\t} else if statusError, isStatus := err.(*apierrors.StatusError); isStatus {\n\t\t\tlogger.WithError(err).\n\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\"status\": statusError.ErrStatus.Message,\n\t\t\t\t}).Error(\"attach.StreamWithContext - status error\")\n\t\t} else {\n\t\t\tlogger.WithError(err).\n\t\t\t\tError(\"attach.StreamWithContext - other error\")\n\t\t}\n\n\t\txc.FailOn(err)\n\t}\n}\n\nfunc listNamespaces(ctx context.Context, api *kubernetes.Clientset) ([]string, error) {\n\tnamespaces, err := api.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(namespaces.Items) == 0 {\n\t\treturn []string{}, nil\n\t}\n\n\tvar names []string\n\tfor _, nsInfo := range namespaces.Items {\n\t\tnames = append(names, nsInfo.Name)\n\t}\n\n\treturn names, nil\n}\n\nfunc listNamespacesWithConfig(kubeconfig string) ([]string, error) {\n\tctx := context.Background()\n\n\tapi, _, err := apiClientFromConfig(kubeconfig)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"apiClientFromConfig\")\n\t\treturn nil, err\n\t}\n\n\tnames, err := listNamespaces(ctx, api)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"listNamespaces\")\n\t\treturn nil, err\n\t}\n\n\treturn names, nil\n}\n\nfunc ensureNamespace(ctx context.Context, api *kubernetes.Clientset, name string) (string, error) {\n\tif name == \"\" {\n\t\tnamespaces, err := api.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tif len(namespaces.Items) == 0 {\n\t\t\treturn \"\", fmt.Errorf(\"no namespaces\")\n\t\t}\n\n\t\treturn namespaces.Items[0].Name, nil\n\t}\n\n\t_, err := api.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{})\n\tif err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.Debugf(\"ensureNamespace: %s namespace is not found\", name)\n\t\t}\n\n\t\treturn \"\", err\n\t}\n\n\treturn name, nil\n}\n\nfunc listActivePods(ctx context.Context, api *kubernetes.Clientset, nsName string) ([]string, error) {\n\tpods, err := api.CoreV1().Pods(nsName).List(ctx, metav1.ListOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(pods.Items) == 0 {\n\t\treturn []string{}, nil\n\t}\n\n\tvar names []string\n\tfor _, podInfo := range pods.Items {\n\t\tswitch podInfo.Status.Phase {\n\t\tcase corev1.PodRunning, corev1.PodPending:\n\t\t\tnames = append(names, podInfo.Name)\n\t\t}\n\t}\n\n\treturn names, nil\n}\n\nfunc listActivePodsWithConfig(kubeconfig string, nsName string) ([]string, error) {\n\tctx := context.Background()\n\n\tapi, _, err := apiClientFromConfig(kubeconfig)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"apiClientFromConfig\")\n\t\treturn nil, err\n\t}\n\n\tnames, err := listActivePods(ctx, api, nsName)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"listActivePods\")\n\t\treturn nil, err\n\t}\n\n\treturn names, nil\n}\n\nfunc listAllActiveContainers(\n\tctx context.Context,\n\tapi *kubernetes.Clientset,\n\tnsName string,\n\tpodName string) ([]string, error) {\n\n\tpod, err := api.CoreV1().Pods(nsName).Get(ctx, podName, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif pod.Status.Phase != corev1.PodRunning {\n\t\treturn nil, ErrPodNotRunning\n\t}\n\n\tvar names []string\n\tcnl := getActiveContainerNames(pod.Status.ContainerStatuses)\n\tnames = append(names, cnl...)\n\ticnl := getActiveContainerNames(pod.Status.InitContainerStatuses)\n\tnames = append(names, icnl...)\n\tecnl := getActiveContainerNames(pod.Status.EphemeralContainerStatuses)\n\tnames = append(names, ecnl...)\n\n\treturn names, nil\n}\n\nfunc listK8sDebuggableContainers(\n\tctx context.Context,\n\tapi *kubernetes.Clientset,\n\tnsName string,\n\tpodName string) (map[string]string, error) {\n\n\tpod, err := api.CoreV1().Pods(nsName).Get(ctx, podName, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif pod.Status.Phase != corev1.PodRunning {\n\t\treturn nil, ErrPodNotRunning\n\t}\n\n\tactiveNames := getActiveContainerNames(pod.Status.ContainerStatuses)\n\tactiveContainers := map[string]string{}\n\tfor _, name := range activeNames {\n\t\tactiveContainers[name] = \"\"\n\t}\n\n\tfor _, c := range pod.Spec.Containers {\n\t\t_, found := activeContainers[c.Name]\n\t\tif found {\n\t\t\tactiveContainers[c.Name] = c.Image\n\t\t}\n\t}\n\n\treturn activeContainers, nil\n}\n\nfunc listDebuggableK8sContainersWithConfig(\n\tkubeconfig string,\n\tnsName string,\n\tpodName string) (map[string]string, error) {\n\tctx := context.Background()\n\n\tapi, _, err := apiClientFromConfig(kubeconfig)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"apiClientFromConfig\")\n\t\treturn nil, err\n\t}\n\n\t_, podName, err = ensurePod(ctx, api, nsName, podName)\n\tif err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.WithError(err).\n\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\"ns\":  nsName,\n\t\t\t\t\t\"pod\": podName,\n\t\t\t\t}).Error(\"ensurePod - not found\")\n\t\t} else if statusError, isStatus := err.(*apierrors.StatusError); isStatus {\n\t\t\tlog.WithError(err).\n\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\"ns\":     nsName,\n\t\t\t\t\t\"pod\":    podName,\n\t\t\t\t\t\"status\": statusError.ErrStatus.Message,\n\t\t\t\t}).Error(\"ensurePod - status error\")\n\t\t} else if err != nil {\n\t\t\tlog.WithError(err).\n\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\"ns\":  nsName,\n\t\t\t\t\t\"pod\": podName,\n\t\t\t\t}).Error(\"ensurePod - other error\")\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tresult, err := listK8sDebuggableContainers(ctx, api, nsName, podName)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"listK8sDebuggableContainers\")\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\nfunc listK8sDebugContainers(\n\tctx context.Context,\n\tapi *kubernetes.Clientset,\n\tnsName string,\n\tpodName string,\n\ttargetContainer string,\n\tonlyActive bool) (map[string]*DebugContainerInfo, error) {\n\n\tpod, err := api.CoreV1().Pods(nsName).Get(ctx, podName, metav1.GetOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif pod.Status.Phase != corev1.PodRunning {\n\t\treturn nil, ErrPodNotRunning\n\t}\n\n\tall := map[string]*DebugContainerInfo{}\n\tfor _, ec := range pod.Spec.EphemeralContainers {\n\t\tif !strings.HasPrefix(ec.Name, containerNamePrefix) {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":        \"listK8sDebugContainers\",\n\t\t\t\t\"ns\":        nsName,\n\t\t\t\t\"pod\":       podName,\n\t\t\t\t\"container\": ec.Name,\n\t\t\t}).Trace(\"ignoring.other.ec\")\n\t\t\tcontinue\n\t\t}\n\n\t\tif targetContainer != \"\" && ec.TargetContainerName != targetContainer {\n\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\"op\":              \"listK8sDebugContainers\",\n\t\t\t\t\"ns\":              nsName,\n\t\t\t\t\"pod\":             podName,\n\t\t\t\t\"container\":       ec.Name,\n\t\t\t\t\"target.selected\": targetContainer,\n\t\t\t\t\"target\":          ec.TargetContainerName,\n\t\t\t}).Trace(\"ignoring.ec\")\n\t\t\tcontinue\n\t\t}\n\n\t\tinfo := &DebugContainerInfo{\n\t\t\tTargetContainerName: ec.TargetContainerName,\n\t\t\tName:                ec.Name,\n\t\t\tSpecImage:           ec.Image,\n\t\t\tCommand:             ec.Command,\n\t\t\tArgs:                ec.Args,\n\t\t\tWorkingDir:          ec.WorkingDir,\n\t\t\tTTY:                 ec.TTY,\n\t\t}\n\n\t\tall[info.Name] = info\n\t}\n\n\tresult := map[string]*DebugContainerInfo{}\n\tfor _, status := range pod.Status.EphemeralContainerStatuses {\n\t\tinfo, found := all[status.Name]\n\t\tif !found {\n\t\t\tcontinue\n\t\t}\n\n\t\tinfo.ContainerID = status.ContainerID\n\t\tinfo.RunningImage = status.Image\n\t\tinfo.RunningImageID = status.ImageID\n\n\t\tif status.State.Waiting != nil {\n\t\t\tinfo.State = CSWaiting\n\t\t\tinfo.WaitReason = status.State.Waiting.Reason\n\t\t\tinfo.WaitMessage = status.State.Waiting.Message\n\t\t}\n\n\t\tif status.State.Running != nil {\n\t\t\tinfo.State = CSRunning\n\t\t\tinfo.StartTime = fmt.Sprintf(\"%v\", status.State.Running.StartedAt)\n\t\t}\n\n\t\tif status.State.Terminated != nil {\n\t\t\tinfo.State = CSTerminated\n\t\t\tinfo.ExitCode = status.State.Terminated.ExitCode\n\t\t\tinfo.ExitReason = status.State.Terminated.Reason\n\t\t\tinfo.ExitMessage = status.State.Terminated.Message\n\t\t\tinfo.StartTime = fmt.Sprintf(\"%v\", status.State.Terminated.StartedAt)\n\t\t\tinfo.FinishTime = fmt.Sprintf(\"%v\", status.State.Terminated.FinishedAt)\n\t\t}\n\n\t\tif onlyActive {\n\t\t\tif info.State == CSRunning {\n\t\t\t\tresult[info.Name] = info\n\t\t\t}\n\t\t} else {\n\t\t\tresult[info.Name] = info\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc listK8sDebugContainersWithConfig(\n\tkubeconfig string,\n\tnsName string,\n\tpodName string,\n\ttargetContainer string,\n\tonlyActive bool) (map[string]*DebugContainerInfo, error) {\n\tctx := context.Background()\n\n\tapi, _, err := apiClientFromConfig(kubeconfig)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"apiClientFromConfig\")\n\t\treturn nil, err\n\t}\n\n\t_, podName, err = ensurePod(ctx, api, nsName, podName)\n\tif err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\tlog.WithError(err).\n\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\"ns\":  nsName,\n\t\t\t\t\t\"pod\": podName,\n\t\t\t\t}).Error(\"ensurePod - not found\")\n\t\t} else if statusError, isStatus := err.(*apierrors.StatusError); isStatus {\n\t\t\tlog.WithError(err).\n\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\"ns\":     nsName,\n\t\t\t\t\t\"pod\":    podName,\n\t\t\t\t\t\"status\": statusError.ErrStatus.Message,\n\t\t\t\t}).Error(\"ensurePod - status error\")\n\t\t} else if err != nil {\n\t\t\tlog.WithError(err).\n\t\t\t\tWithFields(log.Fields{\n\t\t\t\t\t\"ns\":     nsName,\n\t\t\t\t\t\"pod\":    podName,\n\t\t\t\t\t\"status\": statusError.ErrStatus.Message,\n\t\t\t\t}).Error(\"ensurePod - other error\")\n\t\t}\n\t\treturn nil, err\n\t}\n\n\tresult, err := listK8sDebugContainers(ctx, api, nsName, podName, targetContainer, onlyActive)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"listK8sDebugContainers\")\n\t\treturn nil, err\n\t}\n\n\treturn result, nil\n}\n\nfunc getActiveContainerNames(input []corev1.ContainerStatus) []string {\n\tvar list []string\n\tfor _, status := range input {\n\t\tif status.State.Running != nil || status.State.Waiting != nil {\n\t\t\tlist = append(list, status.Name)\n\t\t}\n\t}\n\n\treturn list\n}\n\nfunc ensurePod(ctx context.Context, api *kubernetes.Clientset, nsName string, podName string) (*corev1.Pod, string, error) {\n\tif podName == \"\" {\n\t\tpods, err := api.CoreV1().Pods(nsName).List(ctx, metav1.ListOptions{})\n\t\tif err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\n\t\tif len(pods.Items) == 0 {\n\t\t\treturn nil, \"\", fmt.Errorf(\"no pods\")\n\t\t}\n\n\t\tpodName = pods.Items[0].Name\n\t}\n\n\tvar outputPod *corev1.Pod\n\tisPodRunning := func() (bool, error) {\n\t\tpod, err := api.CoreV1().Pods(nsName).Get(ctx, podName, metav1.GetOptions{})\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tswitch pod.Status.Phase {\n\t\tcase corev1.PodRunning:\n\t\t\toutputPod = pod\n\t\t\treturn true, nil\n\t\tcase corev1.PodFailed, corev1.PodSucceeded:\n\t\t\treturn false, fmt.Errorf(\"pod is done\")\n\t\t}\n\t\treturn false, nil\n\t}\n\n\terr := wait.PollImmediate(2*time.Second, 2*time.Minute, isPodRunning)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\n\treturn outputPod, podName, nil\n}\n\nconst (\n\tctInit      = \"init\"\n\tctStandard  = \"standard\"\n\tctEphemeral = \"ephemeral\"\n)\n\nvar (\n\tErrPodTerminated       = errors.New(\"Pod terminated\")\n\tErrPodNotRunning       = errors.New(\"Pod not running\")\n\tErrContainerTerminated = errors.New(\"Container terminated\")\n)\n\nfunc waitForContainer(\n\tlogger *log.Entry,\n\txc *app.ExecutionContext,\n\tctx context.Context,\n\tapi *kubernetes.Clientset,\n\tnsName string,\n\tpodName string,\n\tcontainerName string,\n\tcontainerType string) error {\n\tlogger.Tracef(\"waitForContainer(%s,%s,%s,%s)\", nsName, podName, containerName, containerType)\n\n\tisContainerRunning := func() (bool, error) {\n\t\tpod, err := api.CoreV1().Pods(nsName).Get(ctx, podName, metav1.GetOptions{})\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tswitch pod.Status.Phase {\n\t\tcase corev1.PodRunning:\n\t\t\tvar statuses []corev1.ContainerStatus\n\t\t\tswitch containerType {\n\t\t\tcase ctInit:\n\t\t\t\tstatuses = pod.Status.InitContainerStatuses\n\t\t\tcase ctStandard:\n\t\t\t\tstatuses = pod.Status.ContainerStatuses\n\t\t\tcase ctEphemeral:\n\t\t\t\tstatuses = pod.Status.EphemeralContainerStatuses\n\t\t\tdefault:\n\t\t\t\treturn false, fmt.Errorf(\"unknown container type\")\n\t\t\t}\n\n\t\t\tlogger.Tracef(\"waitForContainer: statuses (%d)\", len(statuses))\n\t\t\tfor _, status := range statuses {\n\t\t\t\tif status.Name == containerName {\n\t\t\t\t\tif status.State.Running != nil {\n\t\t\t\t\t\tlogger.Tracef(\"waitForContainer: RUNNING - %s/%s/%s[%s]\", nsName, podName, containerName, containerType)\n\n\t\t\t\t\t\tif xc != nil {\n\t\t\t\t\t\t\txc.Out.Info(\"wait.for.container.done\",\n\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\"state\":      \"RUNNING\",\n\t\t\t\t\t\t\t\t\t\"name\":       containerName,\n\t\t\t\t\t\t\t\t\t\"pod\":        podName,\n\t\t\t\t\t\t\t\t\t\"namespace\":  nsName,\n\t\t\t\t\t\t\t\t\t\"type\":       containerType,\n\t\t\t\t\t\t\t\t\t\"start_time\": fmt.Sprintf(\"%v\", status.State.Running.StartedAt),\n\t\t\t\t\t\t\t\t\t\"id\":         status.ContainerID,\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true, nil\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlogger.Trace(\"waitForContainer: target is not running yet...\")\n\n\t\t\t\t\t\tif xc != nil {\n\t\t\t\t\t\t\tparamVars := ovars{\n\t\t\t\t\t\t\t\t\"name\":      containerName,\n\t\t\t\t\t\t\t\t\"pod\":       podName,\n\t\t\t\t\t\t\t\t\"namespace\": nsName,\n\t\t\t\t\t\t\t\t\"type\":      containerType,\n\t\t\t\t\t\t\t\t\"id\":        status.ContainerID,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif status.Started != nil && *status.Started {\n\t\t\t\t\t\t\t\tparamVars[\"is_started\"] = true\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif status.State.Waiting != nil {\n\t\t\t\t\t\t\t\tparamVars[\"state\"] = \"WAITING\"\n\n\t\t\t\t\t\t\t\tif status.State.Waiting.Reason != \"\" {\n\t\t\t\t\t\t\t\t\tparamVars[\"reason\"] = status.State.Waiting.Reason\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif status.State.Waiting.Message != \"\" {\n\t\t\t\t\t\t\t\t\tparamVars[\"message\"] = status.State.Waiting.Message\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif status.State.Terminated != nil {\n\t\t\t\t\t\t\t\tparamVars[\"state\"] = \"TERMINATED\"\n\t\t\t\t\t\t\t\tparamVars[\"exit_code\"] = status.State.Terminated.ExitCode\n\n\t\t\t\t\t\t\t\tif status.State.Terminated.Reason != \"\" {\n\t\t\t\t\t\t\t\t\tparamVars[\"reason\"] = status.State.Terminated.Reason\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif status.State.Terminated.Message != \"\" {\n\t\t\t\t\t\t\t\t\tparamVars[\"message\"] = status.State.Terminated.Message\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\txc.Out.Info(\"wait.for.container\", paramVars)\n\n\t\t\t\t\t\t\tif status.State.Terminated != nil {\n\t\t\t\t\t\t\t\treturn false, ErrContainerTerminated\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\n\t\t\t//don't fail right away, let it time out...\n\t\t\treturn false, nil\n\t\tcase corev1.PodFailed, corev1.PodSucceeded:\n\t\t\treturn false, ErrPodTerminated\n\t\t}\n\n\t\treturn false, nil\n\t}\n\n\treturn wait.PollImmediate(2*time.Second, 4*time.Minute, isContainerRunning)\n}\n\nfunc dumpK8sContainerLogs(\n\tlogger *log.Entry,\n\txc *app.ExecutionContext,\n\tctx context.Context,\n\tapi *kubernetes.Clientset,\n\tnsName string,\n\tpodName string,\n\tcontainerName string) error {\n\tlogger.Tracef(\"dumpK8sContainerLogs(%s,%s,%s)\", nsName, podName, containerName)\n\n\toptions := &corev1.PodLogOptions{\n\t\tContainer: containerName,\n\t}\n\n\treq := api.CoreV1().\n\t\tPods(nsName).\n\t\tGetLogs(podName, options)\n\n\tcontainerLogs, err := req.Stream(ctx)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"error streaming container logs\")\n\t\treturn err\n\t}\n\tdefer containerLogs.Close()\n\n\t/*\n\t\tvar outData bytes.Buffer\n\t\t_, err = io.Copy(&outData, containerLogs)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"error copying container logs\")\n\t\t\treturn err\n\t\t}\n\n\t\tfmt.Printf(\"%s\\n\", outData.String())\n\t\t//_, _ = outData.WriteTo(os.Stdout)\n\t*/\n\n\toutData, err := ioutil.ReadAll(containerLogs)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"error reading container logs\")\n\t\treturn err\n\t}\n\n\txc.Out.Info(\"container.logs.start\")\n\txc.Out.LogDump(\"debug.container.logs\", string(outData))\n\txc.Out.Info(\"container.logs.end\")\n\treturn nil\n}\n\nfunc ephemeralContainerFromPod(\n\tpod *corev1.Pod,\n\ttarget string,\n\tname string) *corev1.EphemeralContainer {\n\tfor _, ec := range pod.Spec.EphemeralContainers {\n\t\tif ec.TargetContainerName == target &&\n\t\t\tec.Name == name {\n\t\t\treturn &ec\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc newEphemeralContainerInfo(\n\ttarget string, // target container in the pod\n\tname string, // name to use for the ephemeral container (must be unique)\n\timage string, // image to use for the ephemeral container\n\tcommand []string, // custom ENTRYPOINT to use for the ephemeral container (yes, it's not CMD :-))\n\targs []string, // custom CMD to use\n\tworkingDir string,\n\tenvVars []NVPair,\n\tisPrivileged bool, // true if it should be a privileged container\n\tdoTTY bool,\n) corev1.EphemeralContainer {\n\tisTrue := true\n\tout := corev1.EphemeralContainer{\n\t\tTargetContainerName: target,\n\t\tEphemeralContainerCommon: corev1.EphemeralContainerCommon{\n\t\t\tTTY:        doTTY,\n\t\t\tStdin:      true,\n\t\t\tName:       name,\n\t\t\tImage:      image,\n\t\t\tCommand:    command,\n\t\t\tArgs:       args,\n\t\t\tWorkingDir: workingDir,\n\t\t\t//TODO: add support for more params:\n\t\t\t//EnvFrom\n\t\t\t//VolumeMounts\n\t\t\t//maybe:\n\t\t\t//ImagePullPolicy\n\t\t},\n\t}\n\n\tif len(envVars) > 0 {\n\t\tfor _, val := range envVars {\n\t\t\tif val.Name == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tnv := corev1.EnvVar{Name: val.Name, Value: val.Value}\n\t\t\tout.Env = append(out.Env, nv)\n\t\t}\n\t}\n\n\tif isPrivileged {\n\t\tout.EphemeralContainerCommon.SecurityContext = &corev1.SecurityContext{\n\t\t\tPrivileged: &isTrue,\n\t\t}\n\t}\n\n\treturn out\n}\n\nfunc apiClientFromConfig(kubeconfig string) (*kubernetes.Clientset, *restclient.Config, error) {\n\tkubeconfig = os.ExpandEnv(kubeconfig)\n\n\tconfig, err := clientcmd.BuildConfigFromFlags(\"\", kubeconfig)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tclientset, err := kubernetes.NewForConfig(config)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn clientset, config, nil\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/handler.go",
    "content": "package debug\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/container\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t//\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'debug' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcommandParams *CommandParams) {\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": Name})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewDebugCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(\"started\")\n\tparamVars := ovars{\n\t\t\"runtime\":     commandParams.Runtime,\n\t\t\"target\":      commandParams.TargetRef,\n\t\t\"debug-image\": commandParams.DebugContainerImage,\n\t\t\"entrypoint\":  commandParams.Entrypoint,\n\t\t\"cmd\":         commandParams.Cmd,\n\t\t\"terminal\":    commandParams.DoTerminal,\n\t}\n\n\tif commandParams.Runtime == KubernetesRuntime {\n\t\tparamVars[\"namespace\"] = commandParams.TargetNamespace\n\t\tparamVars[\"pod\"] = commandParams.TargetPod\n\t}\n\n\txc.Out.Info(\"params\", paramVars)\n\n\tsid := generateSessionID()\n\tdebugContainerName := generateContainerName(sid)\n\tlogger = logger.WithFields(\n\t\tlog.Fields{\n\t\t\t\"sid\":                  sid,\n\t\t\t\"debug.container.name\": debugContainerName,\n\t\t})\n\n\tswitch commandParams.Runtime {\n\tcase DockerRuntime:\n\t\tclient, err := dockerclient.New(gparams.ClientConfig)\n\t\tif err == dockerclient.ErrNoDockerInfo {\n\t\t\texitMsg := \"missing Docker connection info\"\n\t\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t\t}\n\n\t\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": exitMsg,\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t\t})\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t\txc.FailOn(err)\n\n\t\tif gparams.Debug {\n\t\t\tversion.Print(xc, Name, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t\t}\n\n\t\tHandleDockerRuntime(logger, xc, gparams, commandParams, client, sid, debugContainerName)\n\tcase KubernetesRuntime:\n\t\tif gparams.Debug {\n\t\t\tversion.Print(xc, Name, logger, nil, false, gparams.InContainer, gparams.IsDSImage)\n\t\t}\n\n\t\tHandleKubernetesRuntime(logger, xc, gparams, commandParams, sid, debugContainerName)\n\tdefault:\n\t\txc.Out.Error(\"runtime\", \"unsupported runtime\")\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": -1,\n\t\t\t})\n\t\txc.Exit(-1)\n\t}\n\n\txc.Out.State(\"completed\")\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(\"done\")\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/debug\"\n)\n\nfunc init() {\n\tdebug.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/prompt.go",
    "content": "package debug\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(FlagRuntime), Description: FlagRuntimeUsage},\n\t\t{Text: command.FullFlagName(FlagTarget), Description: FlagTargetUsage},\n\t\t{Text: command.FullFlagName(FlagNamespace), Description: FlagNamespaceUsage},\n\t\t{Text: command.FullFlagName(FlagPod), Description: FlagPodUsage},\n\t\t{Text: command.FullFlagName(FlagDebugImage), Description: FlagDebugImageUsage},\n\t\t{Text: command.FullFlagName(FlagEntrypoint), Description: FlagEntrypointUsage},\n\t\t{Text: command.FullFlagName(FlagCmd), Description: FlagCmdUsage},\n\t\t{Text: command.FullFlagName(FlagWorkdir), Description: FlagWorkdirUsage},\n\t\t{Text: command.FullFlagName(FlagEnv), Description: FlagEnvUsage},\n\t\t{Text: command.FullFlagName(FlagTerminal), Description: FlagTerminalUsage},\n\t\t{Text: command.FullFlagName(FlagRunAsTargetShell), Description: FlagRunAsTargetShellUsage},\n\t\t{Text: command.FullFlagName(FlagListSessions), Description: FlagListSessionsUsage},\n\t\t{Text: command.FullFlagName(FlagShowSessionLogs), Description: FlagShowSessionLogsUsage},\n\t\t{Text: command.FullFlagName(FlagConnectSession), Description: FlagConnectSessionUsage},\n\t\t{Text: command.FullFlagName(FlagSession), Description: FlagSessionUsage},\n\t\t{Text: command.FullFlagName(FlagListNamespaces), Description: FlagListNamespacesUsage},\n\t\t{Text: command.FullFlagName(FlagListPods), Description: FlagListPodsUsage},\n\t\t{Text: command.FullFlagName(FlagListDebuggableContainers), Description: FlagListDebuggableContainersUsage},\n\t\t{Text: command.FullFlagName(FlagListDebugImage), Description: FlagListDebugImageUsage},\n\t\t{Text: command.FullFlagName(FlagKubeconfig), Description: FlagKubeconfigUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(FlagRuntime):                  completeRuntime,\n\t\tcommand.FullFlagName(FlagTarget):                   completeTarget,\n\t\tcommand.FullFlagName(FlagDebugImage):               completeDebugImage,\n\t\tcommand.FullFlagName(FlagTerminal):                 command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagRunAsTargetShell):         command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagListSessions):             command.CompleteBool,\n\t\tcommand.FullFlagName(FlagShowSessionLogs):          command.CompleteBool,\n\t\tcommand.FullFlagName(FlagConnectSession):           command.CompleteBool,\n\t\tcommand.FullFlagName(FlagSession):                  completeSession,\n\t\tcommand.FullFlagName(FlagListNamespaces):           command.CompleteBool,\n\t\tcommand.FullFlagName(FlagListPods):                 command.CompleteBool,\n\t\tcommand.FullFlagName(FlagListDebuggableContainers): command.CompleteBool,\n\t\tcommand.FullFlagName(FlagListDebugImage):           command.CompleteBool,\n\t\tcommand.FullFlagName(FlagNamespace):                completeNamespace,\n\t\tcommand.FullFlagName(FlagPod):                      completePod,\n\t},\n}\n\nfunc getDebugImageValues() []prompt.Suggest {\n\tvar values []prompt.Suggest\n\tfor k, v := range debugImages {\n\t\tvalue := prompt.Suggest{Text: k, Description: v}\n\t\tvalues = append(values, value)\n\t}\n\n\treturn values\n}\n\nfunc completeDebugImage(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(getDebugImageValues(), token, true)\n}\n\nvar runtimeValues = []prompt.Suggest{\n\t{Text: DockerRuntime, Description: \"Docker runtime - debug a container running in Docker\"},\n\t{Text: KubernetesRuntime, Description: \"Kubernetes runtime - debug a container running in Kubernetes\"},\n}\n\nfunc completeRuntime(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(runtimeValues, token, true)\n}\n\nfunc completeNamespace(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tvar values []prompt.Suggest\n\tccs := command.GetCurrentCommandState()\n\tif ccs != nil && ccs.Command == Name {\n\t\truntimeFlag := command.FullFlagName(FlagRuntime)\n\t\tif rtFlagVals, found := ccs.CommandFlags[runtimeFlag]; found {\n\t\t\tif len(rtFlagVals) > 0 && rtFlagVals[0] == KubernetesRuntime {\n\t\t\t\tkubeconfig := KubeconfigDefault\n\t\t\t\tkubeconfigFlag := command.FullFlagName(FlagKubeconfig)\n\t\t\t\tkcFlagVals, found := ccs.CommandFlags[kubeconfigFlag]\n\t\t\t\tif found && len(kcFlagVals) > 0 {\n\t\t\t\t\tkubeconfig = kcFlagVals[0]\n\t\t\t\t}\n\n\t\t\t\tnames, _ := listNamespacesWithConfig(kubeconfig)\n\t\t\t\tfor _, name := range names {\n\t\t\t\t\tvalue := prompt.Suggest{Text: name}\n\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn prompt.FilterHasPrefix(values, token, true)\n}\n\nfunc completePod(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tvar values []prompt.Suggest\n\tccs := command.GetCurrentCommandState()\n\tif ccs != nil && ccs.Command == Name {\n\t\truntimeFlag := command.FullFlagName(FlagRuntime)\n\t\tif rtFlagVals, found := ccs.CommandFlags[runtimeFlag]; found {\n\t\t\tif len(rtFlagVals) > 0 && rtFlagVals[0] == KubernetesRuntime {\n\t\t\t\tkubeconfig := KubeconfigDefault\n\t\t\t\tkubeconfigFlag := command.FullFlagName(FlagKubeconfig)\n\t\t\t\tkcFlagVals, found := ccs.CommandFlags[kubeconfigFlag]\n\t\t\t\tif found && len(kcFlagVals) > 0 {\n\t\t\t\t\tkubeconfig = kcFlagVals[0]\n\t\t\t\t}\n\n\t\t\t\tnamespace := NamespaceDefault\n\t\t\t\tnamespaceFlag := command.FullFlagName(FlagNamespace)\n\t\t\t\tnsFlagVals, found := ccs.CommandFlags[namespaceFlag]\n\t\t\t\tif found && len(nsFlagVals) > 0 {\n\t\t\t\t\tnamespace = nsFlagVals[0]\n\t\t\t\t}\n\n\t\t\t\tnames, _ := listActivePodsWithConfig(kubeconfig, namespace)\n\t\t\t\tfor _, name := range names {\n\t\t\t\t\tvalue := prompt.Suggest{Text: name}\n\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn prompt.FilterHasPrefix(values, token, true)\n}\n\nfunc completeTarget(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tvar values []prompt.Suggest\n\tccs := command.GetCurrentCommandState()\n\tif ccs != nil && ccs.Command == Name {\n\t\truntimeFlag := command.FullFlagName(FlagRuntime)\n\t\trtFlagVals, found := ccs.CommandFlags[runtimeFlag]\n\t\tif found && len(rtFlagVals) > 0 && rtFlagVals[0] == KubernetesRuntime {\n\t\t\tkubeconfig := KubeconfigDefault\n\t\t\tkubeconfigFlag := command.FullFlagName(FlagKubeconfig)\n\t\t\tkcFlagVals, found := ccs.CommandFlags[kubeconfigFlag]\n\t\t\tif found && len(kcFlagVals) > 0 {\n\t\t\t\tkubeconfig = kcFlagVals[0]\n\t\t\t}\n\n\t\t\tnamespace := NamespaceDefault\n\t\t\tnamespaceFlag := command.FullFlagName(FlagNamespace)\n\t\t\tnsFlagVals, found := ccs.CommandFlags[namespaceFlag]\n\t\t\tif found && len(nsFlagVals) > 0 {\n\t\t\t\tnamespace = nsFlagVals[0]\n\t\t\t}\n\n\t\t\tvar pod string\n\t\t\tpodFlag := command.FullFlagName(FlagPod)\n\t\t\tpodFlagVals, found := ccs.CommandFlags[podFlag]\n\t\t\tif found && len(podFlagVals) > 0 {\n\t\t\t\tpod = podFlagVals[0]\n\t\t\t}\n\n\t\t\tresult, err := listDebuggableK8sContainersWithConfig(kubeconfig, namespace, pod)\n\t\t\tif err == nil {\n\t\t\t\tfor cname, iname := range result {\n\t\t\t\t\tvalue := prompt.Suggest{\n\t\t\t\t\t\tText:        cname,\n\t\t\t\t\t\tDescription: fmt.Sprintf(\"image: %s\", iname),\n\t\t\t\t\t}\n\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//either no explicit 'runtime' param or other/docker runtime\n\t\t\t//todo: need a way to access/pass the docker client struct (or just pass the connect params)\n\t\t\tresult, err := listDebuggableDockerContainersWithConfig(ccs.Dclient)\n\t\t\tif err == nil {\n\t\t\t\tfor cname, iname := range result {\n\t\t\t\t\tvalue := prompt.Suggest{\n\t\t\t\t\t\tText:        cname,\n\t\t\t\t\t\tDescription: fmt.Sprintf(\"image: %s\", iname),\n\t\t\t\t\t}\n\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn prompt.FilterHasPrefix(values, token, true)\n}\n\nfunc completeSession(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tvar values []prompt.Suggest\n\tccs := command.GetCurrentCommandState()\n\tif ccs != nil && ccs.Command == Name {\n\t\tcsessValStr := ccs.GetCFValue(FlagConnectSession)\n\n\t\truntimeFlag := command.FullFlagName(FlagRuntime)\n\t\trtFlagVals, found := ccs.CommandFlags[runtimeFlag]\n\t\tif found && len(rtFlagVals) > 0 && rtFlagVals[0] == KubernetesRuntime {\n\t\t\tkubeconfig := KubeconfigDefault\n\t\t\tkubeconfigFlag := command.FullFlagName(FlagKubeconfig)\n\t\t\tkcFlagVals, found := ccs.CommandFlags[kubeconfigFlag]\n\t\t\tif found && len(kcFlagVals) > 0 {\n\t\t\t\tkubeconfig = kcFlagVals[0]\n\t\t\t}\n\n\t\t\tnamespace := ccs.GetCFValueWithDefault(FlagNamespace, NamespaceDefault)\n\n\t\t\tvar pod string\n\t\t\tpodFlag := command.FullFlagName(FlagPod)\n\t\t\tpodFlagVals, found := ccs.CommandFlags[podFlag]\n\t\t\tif found && len(podFlagVals) > 0 {\n\t\t\t\tpod = podFlagVals[0]\n\t\t\t}\n\n\t\t\ttarget := ccs.GetCFValue(FlagTarget)\n\n\t\t\tresult, err := listK8sDebugContainersWithConfig(\n\t\t\t\tkubeconfig,\n\t\t\t\tnamespace,\n\t\t\t\tpod,\n\t\t\t\ttarget,\n\t\t\t\tcommand.IsTrueStr(csessValStr))\n\n\t\t\tif err == nil {\n\t\t\t\tfor _, info := range result {\n\t\t\t\t\tdesc := fmt.Sprintf(\"state: %s / start_time: %s / target: %s / image: %s\",\n\t\t\t\t\t\tinfo.State,\n\t\t\t\t\t\tinfo.StartTime,\n\t\t\t\t\t\tinfo.TargetContainerName,\n\t\t\t\t\t\tinfo.SpecImage)\n\t\t\t\t\tvalue := prompt.Suggest{\n\t\t\t\t\t\tText:        info.Name,\n\t\t\t\t\t\tDescription: desc,\n\t\t\t\t\t}\n\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t//either no explicit 'runtime' param or other/docker runtime\n\t\t\t//todo: need a way to access/pass the docker client struct (or just pass the connect params)\n\t\t\tvar target string\n\t\t\ttargetFlag := command.FullFlagName(FlagTarget)\n\t\t\ttargetFlagVals, found := ccs.CommandFlags[targetFlag]\n\t\t\tif found && len(targetFlagVals) > 0 {\n\t\t\t\ttarget = targetFlagVals[0]\n\t\t\t}\n\n\t\t\tresult, err := listDockerDebugContainersWithConfig(ccs.Dclient,\n\t\t\t\ttarget,\n\t\t\t\tcommand.IsTrueStr(csessValStr))\n\t\t\tif err == nil {\n\t\t\t\tfor _, info := range result {\n\t\t\t\t\tdesc := fmt.Sprintf(\"state: %s / start_time: %s / target: %s / image: %s\",\n\t\t\t\t\t\tinfo.State,\n\t\t\t\t\t\tinfo.StartTime,\n\t\t\t\t\t\tinfo.TargetContainerName,\n\t\t\t\t\t\tinfo.SpecImage)\n\t\t\t\t\tvalue := prompt.Suggest{\n\t\t\t\t\t\tText:        info.Name,\n\t\t\t\t\t\tDescription: desc,\n\t\t\t\t\t}\n\t\t\t\t\tvalues = append(values, value)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn prompt.FilterHasPrefix(values, token, true)\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/register.go",
    "content": "package debug\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/session.go",
    "content": "package debug\n\nimport (\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/segmentio/ksuid\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst (\n\tcontainerNamePrefix = \"mint-debugger-\"\n\tcontainerNamePat    = \"mint-debugger-%v\"\n)\n\nconst (\n\tCSWaiting    = \"WAITING\"\n\tCSRunning    = \"RUNNING\"\n\tCSTerminated = \"TERMINATED\"\n)\n\ntype DebugContainerInfo struct {\n\tTargetContainerName string\n\tName                string\n\tSpecImage           string\n\tCommand             []string\n\tArgs                []string\n\tWorkingDir          string\n\tTTY                 bool\n\tContainerID         string\n\tRunningImage        string\n\tRunningImageID      string\n\tStartTime           string\n\tFinishTime          string\n\tState               string\n\tExitCode            int32\n\tExitReason          string\n\tExitMessage         string\n\tWaitReason          string\n\tWaitMessage         string\n}\n\nfunc generateSessionID() string {\n\tid, err := ksuid.NewRandom()\n\tif err != nil {\n\t\tlog.WithField(\"op\", \"debug.generateSessionID\").WithError(err).Error(\"ksuid.NewRandom\")\n\t\treturn fmt.Sprintf(\"%v%v\", time.Now().UTC().UnixNano(), os.Getpid())\n\t}\n\n\treturn hex.EncodeToString(id.Bytes())\n}\n\nfunc generateContainerName(sid string) string {\n\tif sid == \"\" {\n\t\tsid = generateSessionID()\n\t}\n\n\treturn fmt.Sprintf(containerNamePat, sid)\n}\n"
  },
  {
    "path": "pkg/app/master/command/debug/shell.go",
    "content": "package debug\n\nimport (\n\t\"strings\"\n\t//log \"github.com/sirupsen/logrus\"\n)\n\nconst (\n\tsidKey   = \"_SESSION_ID_\"\n\tshellKey = \"_SHELL_NAME_\"\n)\n\nconst (\n\tdefaultShellName = \"sh\"\n\tbashShellName    = \"bash\"\n)\n\n// NOTES: Mitigating variable expansion done by kubernetes & shell/heredoc\nvar shellConfig = `\nset -eu\n\ncat << 'EOF' > /.mint_debugger_shell_config.sh\n#!/bin/sh\n\nif [ -d \"/proc/$$$/root/usr/local/sbin/\" ]; then\nln -s /proc/$$$/root/usr/local/sbin/ /proc/1/root/.mint_debugger_ulsbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_ulsbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/usr/local/bin/\" ]; then\nln -s /proc/$$$/root/usr/local/bin/ /proc/1/root/.mint_debugger_ulbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_ulbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/usr/sbin/\" ]; then\nln -s /proc/$$$/root/usr/sbin/ /proc/1/root/.mint_debugger_usbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_usbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/usr/bin/\" ]; then\nln -s /proc/$$$/root/usr/bin/ /proc/1/root/.mint_debugger_ubin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_ubin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/sbin/\" ]; then\nln -s /proc/$$$/root/sbin/ /proc/1/root/.mint_debugger_sbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_sbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/bin/\" ]; then\nln -s /proc/$$$/root/bin/ /proc/1/root/.mint_debugger_bin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_bin__SESSION_ID_\nfi\n\nchroot /proc/1/root sh\nEOF\n\nsh /.mint_debugger_shell_config.sh\n`\n\n//exec sh...\n\nfunc configShell(sessionID string, isK8s bool) string {\n\tresult := strings.ReplaceAll(shellConfig, sidKey, sessionID)\n\tif isK8s {\n\t\treturn result\n\t}\n\n\treturn strings.ReplaceAll(result, \"/$$$/\", \"/$$/\")\n}\n\nvar shellConfigAlt = `\nset -eu\n\ncat << 'EOF' > /.mint_debugger_shell_config.sh\n#!/bin/sh\n\nif [ -d \"/proc/$$$/root/usr/local/sbin/\" ]; then\nln -s /proc/$$$/root/usr/local/sbin/ /proc/1/root/.mint_debugger_ulsbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_ulsbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/usr/local/bin/\" ]; then\nln -s /proc/$$$/root/usr/local/bin/ /proc/1/root/.mint_debugger_ulbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_ulbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/usr/sbin/\" ]; then\nln -s /proc/$$$/root/usr/sbin/ /proc/1/root/.mint_debugger_usbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_usbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/usr/bin/\" ]; then\nln -s /proc/$$$/root/usr/bin/ /proc/1/root/.mint_debugger_ubin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_ubin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/sbin/\" ]; then\nln -s /proc/$$$/root/sbin/ /proc/1/root/.mint_debugger_sbin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_sbin__SESSION_ID_\nfi\n\nif [ -d \"/proc/$$$/root/bin/\" ]; then\nln -s /proc/$$$/root/bin/ /proc/1/root/.mint_debugger_bin__SESSION_ID_\n\nexport PATH=$PATH:/.mint_debugger_bin__SESSION_ID_\nfi\n\nif [ -f \"/proc/$$$/root/bin/busybox\" ] && [ ! -f \"/proc/1/root/bin/busybox\" ]; then\nln -s /proc/$$$/root/bin/busybox /proc/1/root/bin/busybox\nfi\n\nln -s /proc/$$$/root/lib/ /proc/1/root/.mint_debugger_lib__SESSION_ID_\nln -s /proc/$$$/root/usr/lib/ /proc/1/root/.mint_debugger_ulib__SESSION_ID_\n\nln -s /proc/$$$/root/usr/lib/libncursesw.so.6 /proc/1/root/usr/lib/libncursesw.so.6\nln -s /proc/$$$/root/usr/lib/libncursesw.so.6.4 /proc/1/root/usr/lib/libncursesw.so.6.4\n\n#if [ -n \"$LD_LIBRARY_PATH\" ]; then\n#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/.mint_debugger_ulib__SESSION_ID_\n#  export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/.mint_debugger_lib__SESSION_ID_:/.mint_debugger_ulib__SESSION_ID_\n#else\n#export LD_LIBRARY_PATH=/.mint_debugger_ulib__SESSION_ID_\n#  export LD_LIBRARY_PATH=/.mint_debugger_lib__SESSION_ID_:/.mint_debugger_ulib__SESSION_ID_\n#fi\n\nchroot /proc/1/root bash\nEOF\n\nsh /.mint_debugger_shell_config.sh\n`\n\nfunc configShellAlt(sessionID string, isK8s bool) string {\n\tresult := strings.ReplaceAll(shellConfigAlt, sidKey, sessionID)\n\tif isK8s {\n\t\treturn result\n\t}\n\n\treturn strings.ReplaceAll(result, \"/$$$/\", \"/$$/\")\n}\n"
  },
  {
    "path": "pkg/app/master/command/dockerclipm/cli.go",
    "content": "package dockerclipm\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst (\n\tName  = \"docker-cli-plugin-metadata\"\n\tUsage = \"Plugin metadata for the docker cli\"\n)\n\ntype pluginMetadata struct {\n\tSchemaVersion    string\n\tVendor           string\n\tVersion          string\n\tShortDescription string\n\tURL              string\n}\n\nvar CLI = &cli.Command{\n\tCategory: \"internal.metadata\",\n\tName:     Name,\n\tUsage:    Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tmetadata := pluginMetadata{\n\t\t\tSchemaVersion:    \"0.1.0\",\n\t\t\tVendor:           \"SlimToolkit\",\n\t\t\tVersion:          version.Current(),\n\t\t\tShortDescription: \"SlimToolkit commands (build=minify, xray=static analyze, profile=dynamic analyze, lint=validate, more)\",\n\t\t\tURL:              \"https://dockersl.im\",\n\t\t}\n\n\t\tencoder := json.NewEncoder(os.Stdout)\n\t\tencoder.SetIndent(\"\", \"    \")\n\t\tencoder.Encode(metadata)\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/dockerclipm/register.go",
    "content": "package dockerclipm\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tprompt.Suggest{},\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/edit/cli.go",
    "content": "package edit\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"edit\"\n\tUsage = \"Edit container image\"\n\tAlias = \"e\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\ttargetRef := ctx.String(command.FlagTarget)\n\t\tif targetRef == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\txc.Out.Error(\"param.target\", \"missing target image ID/name\")\n\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t}\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues,\n\t\t\ttargetRef)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/edit/handler.go",
    "content": "package edit\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'edit' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\ttargetRef string) {\n\tconst cmdName = Name\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": cmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewEditCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(\"started\")\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"target\": targetRef,\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\txc.Out.State(\"completed\")\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(\"done\")\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/edit/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/edit\"\n)\n\nfunc init() {\n\tedit.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/edit/prompt.go",
    "content": "package edit\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/edit/register.go",
    "content": "package edit\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/help/cli.go",
    "content": "package help\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n)\n\nconst (\n\tName  = \"help\"\n\tUsage = \"Show help info\"\n\tAlias = \"h\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tcli.ShowAppHelp(ctx)\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/help/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/help\"\n)\n\nfunc init() {\n\thelp.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/help/prompt.go",
    "content": "package help\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/help/register.go",
    "content": "package help\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/images/cli.go",
    "content": "package images\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n)\n\nconst (\n\tName  = string(cmd.Images)\n\tUsage = \"Get information about container images\"\n\tAlias = \"i\"\n)\n\n//todo soon: add a lot of useful filtering flags\n// (to show new images from last hour, to show images in use, by size, with details, etc)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/images/handler.go",
    "content": "package images\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/dustin/go-humanize\"\n\t\"github.com/jedib0t/go-pretty/v6/table\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/jsonutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'images' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams) {\n\tconst cmdName = Name\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": cmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewImagesCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(\"started\")\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t//\"target\": targetRef, - todo: add command params here when added\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\txc.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\timages, err := dockerutil.ListImages(client, \"\")\n\txc.FailOn(err)\n\n\tif xc.Out.Quiet {\n\t\tif xc.Out.OutputFormat == command.OutputFormatJSON {\n\t\t\tfmt.Printf(\"%s\\n\", jsonutil.ToPretty(images))\n\t\t\treturn\n\t\t}\n\n\t\tprintImagesTable(images)\n\t\treturn\n\t} else {\n\t\tfor name, info := range images {\n\t\t\tfields := ovars{\n\t\t\t\t\"name\":    name,\n\t\t\t\t\"id\":      info.ID,\n\t\t\t\t\"size\":    humanize.Bytes(uint64(info.Size)),\n\t\t\t\t\"created\": time.Unix(info.Created, 0).Format(time.RFC3339),\n\t\t\t}\n\n\t\t\txc.Out.Info(\"image\", fields)\n\t\t}\n\t}\n\n\txc.Out.State(\"completed\")\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(\"done\")\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\nfunc printImagesTable(images map[string]dockerutil.BasicImageProps) {\n\ttw := table.NewWriter()\n\ttw.AppendHeader(table.Row{\"Name\", \"ID\", \"Size\", \"Created\"})\n\n\tfor name, info := range images {\n\t\ttw.AppendRow(table.Row{\n\t\t\tname,\n\t\t\tinfo.ID,\n\t\t\thumanize.Bytes(uint64(info.Size)),\n\t\t\ttime.Unix(info.Created, 0).Format(time.RFC3339),\n\t\t})\n\t}\n\n\ttw.SetStyle(table.StyleLight)\n\ttw.Style().Options.DrawBorder = false\n\tfmt.Printf(\"%s\\n\", tw.Render())\n}\n"
  },
  {
    "path": "pkg/app/master/command/images/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/images\"\n)\n\nfunc init() {\n\timages.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/images/prompt.go",
    "content": "package images\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/images/register.go",
    "content": "package images\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/install/cli.go",
    "content": "package install\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\n\t\"github.com/urfave/cli/v2\"\n)\n\nconst (\n\tName  = \"install\"\n\tUsage = \"Installs slim\"\n\tAlias = \"in\"\n)\n\nconst (\n\tFlagBinDir      = \"bin-dir\"\n\tFlagBinDirUsage = \"Install binaries to the standard user app bin directory (/usr/local/bin)\"\n\n\tFlagDockerCLIPlugin      = \"docker-cli-plugin\"\n\tFlagDockerCLIPluginUsage = \"Install as Docker CLI plugin\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\t&cli.BoolFlag{\n\t\t\tName:    FlagBinDir,\n\t\t\tUsage:   FlagBinDirUsage,\n\t\t\tEnvVars: []string{\"DSLIM_INSTALL_BIN_DIR\"},\n\t\t},\n\t\t&cli.BoolFlag{\n\t\t\tName:    FlagDockerCLIPlugin,\n\t\t\tUsage:   FlagDockerCLIPluginUsage,\n\t\t\tEnvVars: []string{\"DSLIM_INSTALL_DOCKER_CLI_PLUGIN\"},\n\t\t},\n\t},\n\tAction: func(ctx *cli.Context) error {\n\t\tdoDebug := ctx.Bool(command.FlagDebug)\n\t\tstatePath := ctx.String(command.FlagStatePath)\n\t\tinContainer, isDSImage := command.IsInContainer(ctx.Bool(command.FlagInContainer))\n\t\tarchiveState := command.ArchiveState(ctx.String(command.FlagArchiveState), inContainer)\n\n\t\tbinDir := ctx.Bool(FlagBinDir)\n\t\tdockerCLIPlugin := ctx.Bool(FlagDockerCLIPlugin)\n\n\t\tOnCommand(doDebug, statePath, archiveState, inContainer, isDSImage, binDir, dockerCLIPlugin)\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/install/handler.go",
    "content": "package install\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/slimtoolkit/go-update\"\n\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tvinfo \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst (\n\tdockerCLIPluginDirSuffx = \"/.docker/cli-plugins\"\n\tmasterAppName           = \"slim\"\n\tsensorAppName           = \"slim-sensor\"\n\tbinDirName              = \"/usr/local/bin\"\n)\n\n// OnCommand implements the 'install' command\nfunc OnCommand(\n\tdoDebug bool,\n\tstatePath string,\n\tarchiveState string,\n\tinContainer bool,\n\tisDSImage bool,\n\tbinDir bool,\n\tdockerCLIPlugin bool) {\n\tlogger := log.WithFields(log.Fields{\"app\": \"slim\", \"cmd\": \"install\"})\n\n\tappPath, err := os.Executable()\n\terrutil.FailOn(err)\n\tappDirPath := filepath.Dir(appPath)\n\n\tif binDir {\n\t\terr := installToBinDir(logger, statePath, inContainer, isDSImage, appDirPath)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"slim[install]: info=status message='error installing to bin dir'\\n\")\n\t\t\tfmt.Printf(\"slim[install]: state=exited version=%s\\n\", vinfo.Current())\n\t\t\treturn\n\t\t}\n\n\t\tfmt.Printf(\"slim[install]: state=bin.dir.installed\\n\")\n\n\t\t//use the path from the bin dir, so installing docker CLI plugin symlinks to the right binaries\n\t\tappDirPath = binDirName\n\t}\n\n\tif dockerCLIPlugin {\n\t\t//create a symlink\n\t\terr := installDockerCLIPlugin(logger, statePath, inContainer, isDSImage, appDirPath)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"slim[install]: info=status message='error installing as Docker CLI plugin'\\n\")\n\t\t\tfmt.Printf(\"slim[install]: state=exited version=%s\\n\", vinfo.Current())\n\t\t\treturn\n\t\t}\n\n\t\tfmt.Printf(\"slim[install]: state=docker.cli.plugin.installed\\n\")\n\t}\n}\n\nfunc installToBinDir(logger *log.Entry, statePath string, inContainer, isDSImage bool, appDirPath string) error {\n\tif err := installRelease(logger, appDirPath, statePath, binDirName); err != nil {\n\t\tlogger.Debugf(\"installToBinDir error: %v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc symlinkBinaries(logger *log.Entry, appRootPath, symlinkRootPath string) error {\n\tsymlinkMasterAppPath := filepath.Join(symlinkRootPath, masterAppName)\n\tsymlinkSensorAppPath := filepath.Join(symlinkRootPath, sensorAppName)\n\ttargetSensorAppPath := filepath.Join(appRootPath, sensorAppName)\n\ttargetMasterAppPath := filepath.Join(appRootPath, masterAppName)\n\n\t//todo:\n\t//should not symlink the sensor because Docker CLI will treat it as an invalid plugin\n\t//need to improve sensor bin discovery from master app symlink\n\terr := os.Symlink(targetSensorAppPath, symlinkSensorAppPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = os.Symlink(targetMasterAppPath, symlinkMasterAppPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc installDockerCLIPlugin(logger *log.Entry, statePath string, inContainer, isDSImage bool, appDirPath string) error {\n\thd, _ := os.UserHomeDir()\n\tdockerCLIPluginDir := filepath.Join(hd, dockerCLIPluginDirSuffx)\n\n\tif !fsutil.Exists(dockerCLIPluginDir) {\n\t\tvar dirMode os.FileMode = 0755\n\t\terr := os.MkdirAll(dockerCLIPluginDir, dirMode)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := symlinkBinaries(logger, appDirPath, dockerCLIPluginDir); err != nil {\n\t\tlogger.Debugf(\"installDockerCLIPlugin error: %v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc installRelease(logger *log.Entry, appRootPath, statePath, targetRootPath string) error {\n\ttargetMasterAppPath := filepath.Join(targetRootPath, masterAppName)\n\ttargetSensorAppPath := filepath.Join(targetRootPath, sensorAppName)\n\tsrcSensorAppPath := filepath.Join(appRootPath, sensorAppName)\n\tsrcMasterAppPath := filepath.Join(appRootPath, masterAppName)\n\n\terr := updateFile(logger, srcSensorAppPath, targetSensorAppPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t//will copy the sensor to the state dir if DS is installed in a bad non-shared location on Macs\n\tfsutil.PreparePostUpdateStateDir(statePath)\n\n\terr = updateFile(logger, srcMasterAppPath, targetMasterAppPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// copied from updater\nfunc updateFile(logger *log.Entry, sourcePath, targetPath string) error {\n\tfile, err := os.Open(sourcePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\toptions := update.Options{}\n\tif targetPath != \"\" {\n\t\toptions.TargetPath = targetPath\n\t}\n\n\terr = update.Apply(file, options)\n\tif err != nil {\n\t\tif rerr := update.RollbackError(err); rerr != nil {\n\t\t\tlogger.Debugf(\"install.updateFile(%s,%s): Failed to rollback from bad update: %v\",\n\t\t\t\tsourcePath, targetPath, rerr)\n\t\t}\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "pkg/app/master/command/install/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/install\"\n)\n\nfunc init() {\n\tinstall.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/install/prompt.go",
    "content": "package install\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(FlagDockerCLIPlugin), Description: FlagDockerCLIPluginUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(FlagDockerCLIPlugin): command.CompleteBool,\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/install/register.go",
    "content": "package install\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/lint/cli.go",
    "content": "package lint\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"lint\"\n\tUsage = \"Analyzes container instructions in Dockerfiles\"\n\tAlias = \"l\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tcflag(command.FlagTarget),\n\t\tcflag(FlagTargetType),\n\t\tcflag(FlagSkipBuildContext),\n\t\tcflag(FlagBuildContextDir),\n\t\tcflag(FlagSkipDockerignore),\n\t\tcflag(FlagIncludeCheckLabel),\n\t\tcflag(FlagExcludeCheckLabel),\n\t\tcflag(FlagIncludeCheckID),\n\t\tcflag(FlagIncludeCheckIDFile),\n\t\tcflag(FlagExcludeCheckID),\n\t\tcflag(FlagExcludeCheckIDFile),\n\t\tcflag(FlagShowNoHits),\n\t\tcflag(FlagShowSnippet),\n\t\tcflag(FlagListChecks),\n\t},\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\tdoListChecks := ctx.Bool(FlagListChecks)\n\n\t\ttargetRef := ctx.String(command.FlagTarget)\n\t\tif !doListChecks {\n\t\t\tif targetRef == \"\" {\n\t\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\t\txc.Out.Error(\"param.target\", \"missing target Dockerfile\")\n\t\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\t\treturn nil\n\t\t\t\t} else {\n\t\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttargetType := ctx.String(FlagTargetType)\n\t\tdoSkipBuildContext := ctx.Bool(FlagSkipBuildContext)\n\t\tbuildContextDir := ctx.String(FlagBuildContextDir)\n\t\tdoSkipDockerignore := ctx.Bool(FlagSkipDockerignore)\n\n\t\tincludeCheckLabels, err := command.ParseCheckTags(ctx.StringSlice(FlagIncludeCheckLabel))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.invalid.include.check.labels\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\texcludeCheckLabels, err := command.ParseCheckTags(ctx.StringSlice(FlagExcludeCheckLabel))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.invalid.exclude.check.labels\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tincludeCheckIDs, err := command.ParseTokenSet(ctx.StringSlice(FlagIncludeCheckID))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.invalid.include.check.ids\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tincludeCheckIDFile := ctx.String(FlagIncludeCheckIDFile)\n\t\tmoreIncludeCheckIDs, err := command.ParseTokenSetFile(includeCheckIDFile)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.invalid.include.check.ids.from.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tfor k, v := range moreIncludeCheckIDs {\n\t\t\tincludeCheckIDs[k] = v\n\t\t}\n\n\t\texcludeCheckIDs, err := command.ParseTokenSet(ctx.StringSlice(FlagExcludeCheckID))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.invalid.exclude.check.ids\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\texcludeCheckIDFile := ctx.String(FlagExcludeCheckIDFile)\n\t\tmoreExcludeCheckIDs, err := command.ParseTokenSetFile(excludeCheckIDFile)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.invalid.exclude.check.ids.from.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tfor k, v := range moreExcludeCheckIDs {\n\t\t\texcludeCheckIDs[k] = v\n\t\t}\n\n\t\tdoShowNoHits := ctx.Bool(FlagShowNoHits)\n\t\tdoShowSnippet := ctx.Bool(FlagShowSnippet)\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues,\n\t\t\ttargetRef,\n\t\t\ttargetType,\n\t\t\tdoSkipBuildContext,\n\t\t\tbuildContextDir,\n\t\t\tdoSkipDockerignore,\n\t\t\tincludeCheckLabels,\n\t\t\texcludeCheckLabels,\n\t\t\tincludeCheckIDs,\n\t\t\texcludeCheckIDs,\n\t\t\tdoShowNoHits,\n\t\t\tdoShowSnippet,\n\t\t\tdoListChecks)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/lint/flags.go",
    "content": "package lint\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\n// Lint command flag names\nconst (\n\tFlagTargetType         = \"target-type\"\n\tFlagSkipBuildContext   = \"skip-build-context\"\n\tFlagBuildContextDir    = \"build-context-dir\"\n\tFlagSkipDockerignore   = \"skip-dockerignore\"\n\tFlagIncludeCheckLabel  = \"include-check-label\"\n\tFlagExcludeCheckLabel  = \"exclude-check-label\"\n\tFlagIncludeCheckID     = \"include-check-id\"\n\tFlagIncludeCheckIDFile = \"include-check-id-file\"\n\tFlagExcludeCheckID     = \"exclude-check-id\"\n\tFlagExcludeCheckIDFile = \"exclude-check-id-file\"\n\tFlagShowNoHits         = \"show-nohits\"\n\tFlagShowSnippet        = \"show-snippet\"\n\tFlagListChecks         = \"list-checks\"\n)\n\n// Lint command flag usage info\nconst (\n\tFlagLintTargetUsage         = \"Target Dockerfile path (or container image)\"\n\tFlagTargetTypeUsage         = \"Explicitly specify the command target type (values: dockerfile, image)\"\n\tFlagSkipBuildContextUsage   = \"Don't try to analyze build context\"\n\tFlagBuildContextDirUsage    = \"Explicitly specify the build context directory\"\n\tFlagSkipDockerignoreUsage   = \"Don't try to analyze .dockerignore\"\n\tFlagIncludeCheckLabelUsage  = \"Include checks with the selected label key:value\"\n\tFlagExcludeCheckLabelUsage  = \"Exclude checks with the selected label key:value\"\n\tFlagIncludeCheckIDUsage     = \"Check ID to include\"\n\tFlagIncludeCheckIDFileUsage = \"File with check IDs to include\"\n\tFlagExcludeCheckIDUsage     = \"Check ID to exclude\"\n\tFlagExcludeCheckIDFileUsage = \"File with check IDs to exclude\"\n\tFlagShowNoHitsUsage         = \"Show checks with no matches\"\n\tFlagShowSnippetUsage        = \"Show check match snippet\"\n\tFlagListChecksUsage         = \"List available checks\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tcommand.FlagTarget: &cli.StringFlag{\n\t\tName:    command.FlagTarget,\n\t\tValue:   \"\",\n\t\tUsage:   FlagLintTargetUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET\"},\n\t},\n\tFlagTargetType: &cli.StringFlag{\n\t\tName:    FlagTargetType,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetTypeUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_TARGET_TYPE\"},\n\t},\n\tFlagSkipBuildContext: &cli.BoolFlag{\n\t\tName:    FlagSkipBuildContext,\n\t\tUsage:   FlagSkipBuildContextUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_SKIP_BC\"},\n\t},\n\tFlagBuildContextDir: &cli.StringFlag{\n\t\tName:    FlagBuildContextDir,\n\t\tValue:   \"\",\n\t\tUsage:   FlagBuildContextDirUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_BC_DIR\"},\n\t},\n\tFlagSkipDockerignore: &cli.BoolFlag{\n\t\tName:    FlagSkipDockerignore,\n\t\tUsage:   FlagSkipDockerignoreUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_SKIP_DI\"},\n\t},\n\tFlagIncludeCheckLabel: &cli.StringSliceFlag{\n\t\tName:    FlagIncludeCheckLabel,\n\t\tValue:   cli.NewStringSlice(\"\"),\n\t\tUsage:   FlagIncludeCheckLabelUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_INCLUDE_LABEL\"},\n\t},\n\tFlagExcludeCheckLabel: &cli.StringSliceFlag{\n\t\tName:    FlagExcludeCheckLabel,\n\t\tValue:   cli.NewStringSlice(\"\"),\n\t\tUsage:   FlagExcludeCheckLabelUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_EXCLUDE_LABEL\"},\n\t},\n\tFlagIncludeCheckID: &cli.StringSliceFlag{\n\t\tName:    FlagIncludeCheckID,\n\t\tValue:   cli.NewStringSlice(\"\"),\n\t\tUsage:   FlagIncludeCheckIDUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_INCLUDE_CID\"},\n\t},\n\tFlagIncludeCheckIDFile: &cli.StringFlag{\n\t\tName:    FlagIncludeCheckIDFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagIncludeCheckIDFileUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_INCLUDE_CID_FILE\"},\n\t},\n\tFlagExcludeCheckID: &cli.StringSliceFlag{\n\t\tName:    FlagExcludeCheckID,\n\t\tValue:   cli.NewStringSlice(\"\"),\n\t\tUsage:   FlagExcludeCheckIDUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_EXCLUDE_CID\"},\n\t},\n\tFlagExcludeCheckIDFile: &cli.StringFlag{\n\t\tName:    FlagExcludeCheckIDFile,\n\t\tValue:   \"\",\n\t\tUsage:   FlagExcludeCheckIDFileUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_EXCLUDE_CID_FILE\"},\n\t},\n\tFlagShowNoHits: &cli.BoolFlag{\n\t\tName:    FlagShowNoHits,\n\t\tUsage:   FlagShowNoHitsUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_SHOW_NOHITS\"},\n\t},\n\tFlagShowSnippet: &cli.BoolFlag{\n\t\tName:    FlagShowSnippet,\n\t\tValue:   true,\n\t\tUsage:   FlagShowSnippetUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_SHOW_SNIPPET\"},\n\t},\n\tFlagListChecks: &cli.BoolFlag{\n\t\tName:    FlagListChecks,\n\t\tUsage:   FlagListChecksUsage,\n\t\tEnvVars: []string{\"DSLIM_LINT_LIST_CHECKS\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/lint/handler.go",
    "content": "package lint\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/linter\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/linter/check\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'lint' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\ttargetRef string,\n\ttargetType string,\n\tdoSkipBuildContext bool,\n\tbuildContextDir string,\n\tdoSkipDockerignore bool,\n\tincludeCheckLabels map[string]string,\n\texcludeCheckLabels map[string]string,\n\tincludeCheckIDs map[string]struct{},\n\texcludeCheckIDs map[string]struct{},\n\tdoShowNoHits bool,\n\tdoShowSnippet bool,\n\tdoListChecks bool) {\n\tconst cmdName = Name\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": cmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewLintCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(\"started\")\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"target\":      targetRef,\n\t\t\t\"list.checks\": doListChecks,\n\t\t})\n\n\t/*\n\t\tdo it only when targeting images\n\t\tclient, err := dockerclient.New(gparams.ClientConfig)\n\t\tif err == dockerclient.ErrNoDockerInfo {\n\t\t\texitMsg := \"missing Docker connection info\"\n\t\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the 'slim' container\"\n\t\t\t}\n\t\t\tfmt.Printf(\"cmd=%s info=docker.connect.error message='%s'\\n\", cmdName, exitMsg)\n\t\t\tfmt.Printf(\"cmd=%s state=exited version=%s location='%s'\\n\", cmdName, v.Current(), fsutil.ExeDir())\n\t\t\tos.Exit(ectCommon | ecNoDockerConnectInfo)\n\t\t}\n\t\terrutil.FailOn(err)\n\t*/\n\tvar client *dockerapi.Client\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tif doListChecks {\n\t\tchecks := linter.ListChecks()\n\t\tprintLintChecks(xc, checks, appName, cmdName)\n\t} else {\n\t\tcmdReport.TargetType = linter.DockerfileTargetType\n\t\tcmdReport.TargetReference = targetRef\n\n\t\toptions := linter.Options{\n\t\t\tDockerfilePath:   targetRef,\n\t\t\tSkipBuildContext: doSkipBuildContext,\n\t\t\tBuildContextDir:  buildContextDir,\n\t\t\tSkipDockerignore: doSkipDockerignore,\n\t\t\tSelector: linter.CheckSelector{\n\t\t\t\tIncludeCheckLabels: includeCheckLabels,\n\t\t\t\tIncludeCheckIDs:    includeCheckIDs,\n\t\t\t\tExcludeCheckLabels: excludeCheckLabels,\n\t\t\t\tExcludeCheckIDs:    excludeCheckIDs,\n\t\t\t},\n\t\t}\n\n\t\tlintResults, err := linter.Execute(options)\n\t\terrutil.FailOn(err)\n\n\t\tcmdReport.BuildContextDir = lintResults.BuildContextDir\n\t\tcmdReport.Hits = lintResults.Hits\n\t\tcmdReport.Errors = lintResults.Errors\n\n\t\tprintLintResults(xc, lintResults, appName, cmdName, cmdReport, doShowNoHits, doShowSnippet)\n\t}\n\n\txc.Out.State(\"completed\")\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(\"done\")\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\nfunc printLintChecks(\n\txc *app.ExecutionContext,\n\tchecks []*check.Info,\n\tappName string,\n\tcmdName cmd.Type) {\n\txc.Out.Info(\"lint.checks\",\n\t\tovars{\n\t\t\t\"count\": len(checks),\n\t\t})\n\n\tfor _, info := range checks {\n\t\txc.Out.Info(\"lint.check.info\",\n\t\t\tovars{\n\t\t\t\t\"id\":          info.ID,\n\t\t\t\t\"name\":        info.Name,\n\t\t\t\t\"labels\":      kvMapString(info.Labels),\n\t\t\t\t\"description\": info.Description,\n\t\t\t\t\"url\":         info.DetailsURL,\n\t\t\t})\n\t}\n}\n\nfunc kvMapString(m map[string]string) string {\n\tvar pairs []string\n\tfor k, v := range m {\n\t\tpairs = append(pairs, fmt.Sprintf(\"%s=%s\", k, v))\n\t}\n\n\treturn strings.Join(pairs, \",\")\n}\n\nfunc printLintResults(\n\txc *app.ExecutionContext,\n\tlintResults *linter.Report,\n\tappName string,\n\tcmdName cmd.Type,\n\tcmdReport *report.LintCommand,\n\tdoShowNoHits bool,\n\tdoShowSnippet bool) {\n\tcmdReport.HitsCount = len(lintResults.Hits)\n\tcmdReport.NoHitsCount = len(lintResults.NoHits)\n\tcmdReport.ErrorsCount = len(lintResults.Errors)\n\n\txc.Out.Info(\"lint.results\",\n\t\tovars{\n\t\t\t\"hits\":   cmdReport.HitsCount,\n\t\t\t\"nohits\": cmdReport.NoHitsCount,\n\t\t\t\"errors\": cmdReport.ErrorsCount,\n\t\t})\n\n\tif cmdReport.HitsCount > 0 {\n\t\txc.Out.Info(\"lint.check.hits\",\n\t\t\tovars{\n\t\t\t\t\"count\": cmdReport.HitsCount,\n\t\t\t})\n\n\t\tfor id, result := range lintResults.Hits {\n\t\t\txc.Out.Info(\"lint.check.hit\",\n\t\t\t\tovars{\n\t\t\t\t\t\"id\":      id,\n\t\t\t\t\t\"name\":    result.Source.Name,\n\t\t\t\t\t\"level\":   result.Source.Labels[check.LabelLevel],\n\t\t\t\t\t\"message\": result.Message,\n\t\t\t\t})\n\n\t\t\tif len(result.Matches) > 0 {\n\t\t\t\txc.Out.Info(\"lint.check.hit.matches\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"count\": len(result.Matches),\n\t\t\t\t\t})\n\n\t\t\t\tfor _, m := range result.Matches {\n\t\t\t\t\t//var instructionInfo string\n\t\t\t\t\t//the match message has the instruction info already\n\t\t\t\t\t//if m.Instruction != nil {\n\t\t\t\t\t//\tinstructionInfo = fmt.Sprintf(\" instruction(start=%d end=%d name=%s gindex=%d sindex=%d)\",\n\t\t\t\t\t//\t\tm.Instruction.StartLine,\n\t\t\t\t\t//\t\tm.Instruction.EndLine,\n\t\t\t\t\t//\t\tm.Instruction.Name,\n\t\t\t\t\t//\t\tm.Instruction.GlobalIndex,\n\t\t\t\t\t//\t\tm.Instruction.StageIndex)\n\t\t\t\t\t//}\n\n\t\t\t\t\tminfo := ovars{}\n\t\t\t\t\tif m.Stage != nil {\n\t\t\t\t\t\tminfo[\"stage\"] = fmt.Sprintf(\"%d:%s\", m.Stage.Index, m.Stage.Name)\n\t\t\t\t\t}\n\n\t\t\t\t\tminfo[\"message\"] = m.Message\n\t\t\t\t\txc.Out.Info(\"lint.check.hit.match\", minfo)\n\n\t\t\t\t\tif m.Instruction != nil &&\n\t\t\t\t\t\tlen(m.Instruction.RawLines) > 0 &&\n\t\t\t\t\t\tdoShowSnippet {\n\t\t\t\t\t\tfor idx, data := range m.Instruction.RawLines {\n\t\t\t\t\t\t\txc.Out.Info(\"lint.check.hit.match.snippet\",\n\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\"line\": idx + m.Instruction.StartLine,\n\t\t\t\t\t\t\t\t\t\"data\": data,\n\t\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}\n\t}\n\n\tif doShowNoHits && cmdReport.NoHitsCount > 0 {\n\t\txc.Out.Info(\"lint.check.nohits\",\n\t\t\tovars{\n\t\t\t\t\"count\": cmdReport.NoHitsCount,\n\t\t\t})\n\n\t\tfor id, result := range lintResults.NoHits {\n\t\t\txc.Out.Info(\"lint.check.nohit\",\n\t\t\t\tovars{\n\t\t\t\t\t\"id\":   id,\n\t\t\t\t\t\"name\": result.Source.Name,\n\t\t\t\t})\n\t\t}\n\t}\n\n\tif cmdReport.ErrorsCount > 0 {\n\t\txc.Out.Info(\"lint.check.errors\",\n\t\t\tovars{\n\t\t\t\t\"count\": cmdReport.ErrorsCount,\n\t\t\t})\n\n\t\tfor id, err := range lintResults.Errors {\n\t\t\txc.Out.Info(\"lint.check.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"id\":      id,\n\t\t\t\t\t\"message\": err,\n\t\t\t\t})\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/lint/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/lint\"\n)\n\nfunc init() {\n\tlint.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/lint/prompt.go",
    "content": "package lint\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/linter/check\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(command.FlagTarget), Description: FlagLintTargetUsage},\n\t\t{Text: command.FullFlagName(FlagTargetType), Description: FlagTargetTypeUsage},\n\t\t{Text: command.FullFlagName(FlagSkipBuildContext), Description: FlagSkipBuildContextUsage},\n\t\t{Text: command.FullFlagName(FlagBuildContextDir), Description: FlagBuildContextDirUsage},\n\t\t{Text: command.FullFlagName(FlagSkipDockerignore), Description: FlagSkipDockerignoreUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCheckLabel), Description: FlagIncludeCheckLabelUsage},\n\t\t{Text: command.FullFlagName(FlagExcludeCheckLabel), Description: FlagExcludeCheckLabelUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCheckID), Description: FlagIncludeCheckIDUsage},\n\t\t{Text: command.FullFlagName(FlagIncludeCheckIDFile), Description: FlagIncludeCheckIDFileUsage},\n\t\t{Text: command.FullFlagName(FlagExcludeCheckID), Description: FlagExcludeCheckIDUsage},\n\t\t{Text: command.FullFlagName(FlagExcludeCheckIDFile), Description: FlagExcludeCheckIDFileUsage},\n\t\t{Text: command.FullFlagName(FlagShowNoHits), Description: FlagShowNoHitsUsage},\n\t\t{Text: command.FullFlagName(FlagShowSnippet), Description: FlagShowSnippetUsage},\n\t\t{Text: command.FullFlagName(FlagListChecks), Description: FlagListChecksUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(command.FlagTarget):     completeLintTarget,\n\t\tcommand.FullFlagName(FlagTargetType):         completeLintTargetType,\n\t\tcommand.FullFlagName(FlagSkipBuildContext):   command.CompleteBool,\n\t\tcommand.FullFlagName(FlagBuildContextDir):    command.CompleteFile,\n\t\tcommand.FullFlagName(FlagSkipDockerignore):   command.CompleteBool,\n\t\tcommand.FullFlagName(FlagIncludeCheckID):     completeLintCheckID,\n\t\tcommand.FullFlagName(FlagIncludeCheckIDFile): command.CompleteFile,\n\t\tcommand.FullFlagName(FlagExcludeCheckID):     completeLintCheckID,\n\t\tcommand.FullFlagName(FlagExcludeCheckIDFile): command.CompleteFile,\n\t\tcommand.FullFlagName(FlagShowNoHits):         command.CompleteBool,\n\t\tcommand.FullFlagName(FlagShowSnippet):        command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagListChecks):         command.CompleteBool,\n\t},\n}\n\nfunc completeLintTarget(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\t//for now only support selecting Dockerfiles\n\t//later add an ability to choose (files or images)\n\t//based on the target-type parameter\n\treturn command.CompleteFile(ia, token, params)\n}\n\nvar lintTargetTypeValues = []prompt.Suggest{\n\t{Text: \"dockerfile\", Description: \"Dockerfile target type\"},\n\t{Text: \"image\", Description: \"Docker image target type\"},\n}\n\nfunc completeLintTargetType(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(lintTargetTypeValues, token, true)\n}\n\nfunc completeLintCheckID(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\tvar values []prompt.Suggest\n\tfor _, check := range check.AllChecks {\n\t\tinfo := check.Get()\n\t\tentry := prompt.Suggest{\n\t\t\tText:        info.ID,\n\t\t\tDescription: info.Name,\n\t\t}\n\n\t\tvalues = append(values, entry)\n\t}\n\n\treturn prompt.FilterContains(values, token, true)\n}\n"
  },
  {
    "path": "pkg/app/master/command/lint/register.go",
    "content": "package lint\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/merge/cli.go",
    "content": "package merge\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"merge\"\n\tUsage = \"Merge two container images (optimized to merge minified images)\"\n\tAlias = \"m\"\n)\n\n//FUTURE/TODO: extend it to be a generic merge function not limited to minified images\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tcflag(FlagImage),\n\t\tcflag(FlagUseLastImageMetadata),\n\t\tcflag(FlagTag),\n\t},\n\tAction: func(ctx *cli.Context) error {\n\t\tgfvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgfvalues.QuietCLIMode,\n\t\t\tgfvalues.OutputFormat)\n\n\t\tif ctx.Args().Len() < 1 {\n\t\t\txc.Out.Error(\"param.target\", \"missing target image ID/name\")\n\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\treturn nil\n\t\t}\n\n\t\tcfvalues, err := CommandFlagValues(xc, ctx)\n\t\tif err != nil {\n\t\t\t//CommandFlagValues() outputs the error messages already\n\t\t\treturn nil\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgfvalues,\n\t\t\tcfvalues)\n\n\t\treturn nil\n\t},\n}\n\ntype CommandParams struct {\n\tFirstImage           string   `json:\"first_image\"`\n\tLastImage            string   `json:\"last_image\"`\n\tUseLastImageMetadata bool     `json:\"use_last_image_metadata\"`\n\tOutputTags           []string `json:\"output_tags\"`\n}\n\nfunc CommandFlagValues(xc *app.ExecutionContext, ctx *cli.Context) (*CommandParams, error) {\n\tvalues := &CommandParams{\n\t\tUseLastImageMetadata: ctx.Bool(FlagUseLastImageMetadata),\n\t\tOutputTags:           ctx.StringSlice(FlagTag),\n\t}\n\n\timages := ctx.StringSlice(FlagImage)\n\tif len(images) > 0 {\n\t\tif len(images) < 2 {\n\t\t\txc.Out.Error(\"param.image\", \"must have two image references\")\n\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\treturn nil, fmt.Errorf(\"must have two image references\")\n\t\t}\n\n\t\tvalues.FirstImage = images[0]\n\t\tvalues.LastImage = images[1]\n\t}\n\n\tif ctx.Args().Len() > 0 {\n\t\tif ctx.Args().Len() < 2 {\n\t\t\txc.Out.Error(\"param.image\", \"must have two image references\")\n\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\treturn nil, fmt.Errorf(\"must have two image references\")\n\t\t}\n\n\t\tvalues.FirstImage = ctx.Args().Get(0)\n\t\tvalues.LastImage = ctx.Args().Get(1)\n\t}\n\n\tif values.FirstImage == \"\" || values.LastImage == \"\" {\n\t\txc.Out.Error(\"param.image\", \"not enough image references\")\n\t\tcli.ShowCommandHelp(ctx, Name)\n\t\treturn nil, fmt.Errorf(\"not enough image references\")\n\t}\n\n\treturn values, nil\n}\n"
  },
  {
    "path": "pkg/app/master/command/merge/flags.go",
    "content": "package merge\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Merge command flag names\nconst (\n\tFlagImage                = \"image\"\n\tFlagUseLastImageMetadata = \"use-last-image-metadata\"\n\tFlagTag                  = \"tag\"\n)\n\n// Merge command flag usage info\nconst (\n\tFlagImageUsage                = \"Image to merge (flag instance position determines the merge order)\"\n\tFlagUseLastImageMetadataUsage = \"Use only the last image metadata for the merged image\"\n\tFlagTagUsage                  = \"Custom tags for the output image\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagImage: &cli.StringSliceFlag{\n\t\tName:    FlagImage,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagImageUsage,\n\t\tEnvVars: []string{\"DSLIM_MERGE_IMAGE\"},\n\t},\n\tFlagUseLastImageMetadata: &cli.BoolFlag{\n\t\tName:    FlagUseLastImageMetadata,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagUseLastImageMetadataUsage,\n\t\tEnvVars: []string{\"DSLIM_MERGE_USE_LAST_IMAGE_META\"},\n\t},\n\tFlagTag: &cli.StringSliceFlag{\n\t\tName:    FlagTag,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagTagUsage,\n\t\tEnvVars: []string{\"DSLIM_TARGET_TAG\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/merge/handler.go",
    "content": "package merge\n\nimport (\n\t\"archive/tar\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/cespare/xxhash/v2\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/imagebuilder\"\n\t\"github.com/slimtoolkit/slim/pkg/imagebuilder/internalbuilder\"\n\t\"github.com/slimtoolkit/slim/pkg/imagereader\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'merge' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *CommandParams) {\n\tconst cmdName = Name\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": cmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewMergeCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\tcmdReport.FirstImage = cparams.FirstImage\n\tcmdReport.LastImage = cparams.LastImage\n\tcmdReport.UseLastImageMetadata = cparams.UseLastImageMetadata\n\n\txc.Out.State(\"started\")\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"image.first\":             cparams.FirstImage,\n\t\t\t\"image.last\":              cparams.LastImage,\n\t\t\t\"use.last.image.metadata\": cparams.UseLastImageMetadata,\n\t\t\t\"output.tags\":             cparams.OutputTags,\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\txc.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\t//////////////////////////////////////////////////\n\tensureImage := func(name string, imageRef string, cr *report.MergeCommand) string {\n\t\timageInspector, err := image.NewInspector(client, imageRef)\n\t\txc.FailOn(err)\n\n\t\tnoImage, err := imageInspector.NoImage()\n\t\terrutil.FailOn(err)\n\t\tif noImage {\n\t\t\txc.Out.Error(fmt.Sprintf(\"%s.image.not.found\", name), \"make sure the target image already exists locally\")\n\n\t\t\tcmdReport.State = cmd.StateError\n\t\t\texitCode := command.ECTCommon | command.ECCImageNotFound\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t})\n\t\t\txc.Exit(exitCode)\n\t\t}\n\n\t\treturn imageInspector.ImageRef\n\t}\n\n\t//and refresh the image refs\n\tcparams.FirstImage = ensureImage(\"first\", cmdReport.FirstImage, cmdReport)\n\tcmdReport.FirstImage = cparams.FirstImage\n\n\t//and refresh the image refs\n\tcparams.LastImage = ensureImage(\"last\", cmdReport.LastImage, cmdReport)\n\tcmdReport.LastImage = cparams.LastImage\n\n\toutputTags := cparams.OutputTags\n\tif len(outputTags) == 0 {\n\t\tvar outputName string\n\t\tif strings.Contains(cparams.LastImage, \":\") {\n\t\t\tparts := strings.SplitN(cparams.LastImage, \":\", 2)\n\t\t\toutputName = fmt.Sprintf(\"%s.merged:%s\", parts[0], parts[1])\n\t\t} else {\n\t\t\toutputName = fmt.Sprintf(\"%s.merged\", cparams.LastImage)\n\t\t}\n\t\toutputTags = append(outputTags, outputName)\n\t}\n\n\tfiReader, err := imagereader.New(cparams.FirstImage)\n\txc.FailOn(err)\n\tliReader, err := imagereader.New(cparams.LastImage)\n\txc.FailOn(err)\n\n\txc.Out.State(\"image.metadata.merge.start\")\n\tfiImageConfig, err := fiReader.ImageConfig()\n\txc.FailOn(err)\n\tliImageConfig, err := liReader.ImageConfig()\n\txc.FailOn(err)\n\n\tvar outImageConfig *imagebuilder.ImageConfig\n\tif cparams.UseLastImageMetadata {\n\t\toutImageConfig = liImageConfig\n\t} else {\n\t\timageConfig := *liImageConfig\n\n\t\t//merge environment variables (todo: do a better job merging envs, need to parse k/v)\n\t\tenvMap := map[string]struct{}{}\n\t\tfor _, v := range fiImageConfig.Config.Env {\n\t\t\tenvMap[v] = struct{}{}\n\t\t}\n\t\tfor _, v := range liImageConfig.Config.Env {\n\t\t\tenvMap[v] = struct{}{}\n\t\t}\n\n\t\timageConfig.Config.Env = []string{}\n\t\tfor k := range envMap {\n\t\t\timageConfig.Config.Env = append(imageConfig.Config.Env, k)\n\t\t}\n\n\t\t//merge labels\n\t\tlabelMap := map[string]string{}\n\t\tfor k, v := range fiImageConfig.Config.Labels {\n\t\t\tlabelMap[k] = v\n\t\t}\n\t\tfor k, v := range liImageConfig.Config.Labels {\n\t\t\tlabelMap[k] = v\n\t\t}\n\n\t\timageConfig.Config.Labels = labelMap\n\n\t\t//merge exposed ports\n\t\tportMap := map[string]struct{}{}\n\t\tfor k := range fiImageConfig.Config.ExposedPorts {\n\t\t\tportMap[k] = struct{}{}\n\t\t}\n\t\tfor k := range liImageConfig.Config.ExposedPorts {\n\t\t\tportMap[k] = struct{}{}\n\t\t}\n\n\t\timageConfig.Config.ExposedPorts = portMap\n\n\t\t//merge volumes\n\t\tvolumeMap := map[string]struct{}{}\n\t\tfor k := range fiImageConfig.Config.Volumes {\n\t\t\tvolumeMap[k] = struct{}{}\n\t\t}\n\t\tfor k := range liImageConfig.Config.Volumes {\n\t\t\tvolumeMap[k] = struct{}{}\n\t\t}\n\n\t\timageConfig.Config.Volumes = volumeMap\n\n\t\t//Merging OnBuild requires the instruction order to be preserved\n\t\t//Auto-merging OnBuild instructions is not always ideal because\n\t\t//of the potential side effects if the merged images are not very compatible.\n\t\t//Merging minified images of the same source image should have no side effects\n\t\t//because the OnBuild instructions will be identical.\n\t\tsameLists := func(first, second []string) bool {\n\t\t\tif len(first) != len(second) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tfor idx := range first {\n\t\t\t\tif first[idx] != second[idx] {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn true\n\t\t}\n\n\t\tif !sameLists(fiImageConfig.Config.OnBuild, liImageConfig.Config.OnBuild) {\n\t\t\tvar onBuild []string\n\t\t\tonBuild = append(onBuild, fiImageConfig.Config.OnBuild...)\n\t\t\tonBuild = append(onBuild, liImageConfig.Config.OnBuild...)\n\t\t\timageConfig.Config.OnBuild = onBuild\n\t\t}\n\n\t\toutImageConfig = &imageConfig\n\t}\n\n\txc.Out.State(\"image.metadata.merge.done\")\n\txc.Out.State(\"image.data.merge.start\")\n\n\tfiDataTarName, err := fiReader.ExportFilesystem()\n\txc.FailOn(err)\n\n\tliDataTarName, err := liReader.ExportFilesystem()\n\txc.FailOn(err)\n\n\tf1, err := os.Open(fiDataTarName)\n\txc.FailOn(err)\n\tdefer f1.Close()\n\n\tindex, err := tarMapFromFile(f1)\n\txc.FailOn(err)\n\n\tf2, err := os.Open(liDataTarName)\n\txc.FailOn(err)\n\tdefer f2.Close()\n\n\tindex2, err := tarMapFromFile(f2)\n\txc.FailOn(err)\n\n\tlogger.Debug(\"updating tar map with first tar data...\")\n\tfor p, info := range index2 {\n\t\tother, found := index[p]\n\t\tif !found {\n\t\t\tindex[p] = info\n\t\t\tcontinue\n\t\t}\n\n\t\tif info.Header.Typeflag == other.Header.Typeflag &&\n\t\t\tinfo.Header.Size == other.Header.Size &&\n\t\t\tinfo.Hash == other.Hash {\n\t\t\t//can/should also check info.Header.Mode and info.Header.ModTime\n\t\t\t//if info.Header.ModTime.After(other.Header.ModTime) {\n\t\t\t//\tinfo.Replaced = append(other.Replaced, other)\n\t\t\t//\tindex[p] = info\n\t\t\t//\tcontinue\n\t\t\t//}\n\n\t\t\tother.Dups++\n\t\t\tcontinue\n\t\t}\n\n\t\tinfo.Replaced = append(other.Replaced, other)\n\t\tindex[p] = info\n\t}\n\n\toutTarFileName, err := tarFromMap(logger, \"\", index)\n\n\tif !fsutil.Exists(outTarFileName) ||\n\t\t!fsutil.IsRegularFile(outTarFileName) ||\n\t\t!fsutil.IsTarFile(outTarFileName) {\n\t\txc.FailOn(fmt.Errorf(\"bad output tar - %s\", outTarFileName))\n\t}\n\n\txc.Out.State(\"image.data.merge.done\")\n\txc.Out.State(\"output.image.generate.start\")\n\n\tibo, err := imagebuilder.SimpleBuildOptionsFromImageConfig(outImageConfig)\n\txc.FailOn(err)\n\n\tibo.Tags = outputTags\n\n\tlayerInfo := imagebuilder.LayerDataInfo{\n\t\tType:   imagebuilder.TarSource,\n\t\tSource: outTarFileName,\n\t\tParams: &imagebuilder.DataParams{\n\t\t\tTargetPath: \"/\",\n\t\t},\n\t}\n\n\tibo.Layers = append(ibo.Layers, layerInfo)\n\n\tengine, err := internalbuilder.New(\n\t\tfalse, //show build logs doShowBuildLogs,\n\t\ttrue,  //push to daemon - TODO: have a param to control this later\n\t\t//output image tar (if not 'saving' to daemon)\n\t\tfalse)\n\txc.FailOn(err)\n\n\timageResult, err := engine.Build(*ibo)\n\txc.FailOn(err)\n\n\txc.Out.Info(\"results.output\",\n\t\tovars{\n\t\t\t\"image.name\":   imageResult.Name,\n\t\t\t\"image.id\":     imageResult.ID,\n\t\t\t\"image.digest\": imageResult.Digest,\n\t\t})\n\n\tensureImage(\"output\", outputTags[0], cmdReport)\n\txc.Out.State(\"output.image.generate.done\")\n\t//////////////////////////////////////////////////\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\ntype tfInfo struct {\n\tFileIndex  uint32\n\tHeader     *tar.Header\n\tHash       uint64\n\tFile       *os.File\n\tDataOffset int64\n\tDups       uint32 //to count duplicates (can have extra field to track tar file metadata later)\n\tReplaced   []*tfInfo\n}\n\nfunc tarMapFromFile(f *os.File) (map[string]*tfInfo, error) {\n\ttr := tar.NewReader(f)\n\ttarMap := map[string]*tfInfo{}\n\n\tvar fileIndex uint32\n\tfor {\n\t\tth, err := tr.Next()\n\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tfmt.Println(err)\n\t\t\treturn tarMap, err\n\t\t}\n\n\t\tif th == nil {\n\t\t\tfmt.Println(\"skipping empty tar header...\")\n\t\t\tcontinue\n\t\t}\n\n\t\toffset, err := f.Seek(0, os.SEEK_CUR)\n\t\tif err != nil {\n\t\t\tfmt.Println(err)\n\t\t\treturn tarMap, err\n\t\t}\n\n\t\tsr := io.NewSectionReader(f, offset, th.Size)\n\n\t\thash := xxhash.New()\n\t\t//if _, err := io.Copy(hash, tr); err != nil {\n\t\tif _, err := io.Copy(hash, sr); err != nil {\n\t\t\t//_, err = io.CopyN(hash, sr, th.Size)\n\t\t\tlog.Fatalf(\"Failed to compute hash: %v\", err)\n\t\t}\n\t\thashValue := hash.Sum64()\n\n\t\t//NOTE:\n\t\t//Not exposing the archived file data right now\n\t\t//because it'll require to read/load the data into memory\n\t\t//and for big images it'll be a lot of data.\n\t\t//For now just re-read the data when needed.\n\n\t\ttarMap[th.Name] = &tfInfo{\n\t\t\tFileIndex:  fileIndex,\n\t\t\tHeader:     th,\n\t\t\tHash:       hashValue,\n\t\t\tFile:       f,      //tar file ref (not the file inside tar)\n\t\t\tDataOffset: offset, //offset in tar file\n\t\t}\n\n\t\tfileIndex++\n\t}\n\n\treturn tarMap, nil\n}\n\nfunc tarFromMap(logger *log.Entry, outputPath string, tarMap map[string]*tfInfo) (string, error) {\n\tvar out *os.File\n\n\tif outputPath == \"\" {\n\t\ttarFile, err := os.CreateTemp(\"\", \"image-output-*.tar\")\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tout = tarFile\n\t} else {\n\t\ttarFile, err := os.Create(outputPath)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tout = tarFile\n\t}\n\n\tdefer out.Close()\n\n\t// Create a new tar archive\n\ttw := tar.NewWriter(out)\n\tdefer tw.Close()\n\n\t// Iterate over the input files\n\tfor filePath, info := range tarMap {\n\t\tlogger.Tracef(\"%s -> %+v\\n\", filePath, info)\n\n\t\tif err := tw.WriteHeader(info.Header); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tif info.Header.Size == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif info.DataOffset < 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tsr := io.NewSectionReader(info.File, info.DataOffset, info.Header.Size)\n\t\tif _, err := io.Copy(tw, sr); err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\n\treturn out.Name(), nil\n}\n"
  },
  {
    "path": "pkg/app/master/command/merge/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/merge\"\n)\n\nfunc init() {\n\tmerge.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/merge/prompt.go",
    "content": "package merge\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(FlagImage), Description: FlagImageUsage},\n\t\t{Text: command.FullFlagName(FlagUseLastImageMetadata), Description: FlagUseLastImageMetadataUsage},\n\t\t{Text: command.FullFlagName(FlagTag), Description: FlagTagUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(FlagUseLastImageMetadata): command.CompleteBool,\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/merge/register.go",
    "content": "package merge\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/probe/cli.go",
    "content": "package probe\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\n\t\"github.com/urfave/cli/v2\"\n)\n\n//Standalone probing\n\nconst (\n\tName  = \"probe\"\n\tUsage = \"Probe target endpoint\"\n\tAlias = \"prb\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: append([]cli.Flag{\n\t\tcflag(FlagTarget),\n\t\tcflag(FlagPort),\n\t}, command.HTTPProbeFlagsBasic()...),\n\tAction: func(ctx *cli.Context) error {\n\t\tgparams, ok := command.CLIContextGet(ctx.Context, command.GlobalParams).(*command.GenericParams)\n\t\tif !ok || gparams == nil {\n\t\t\treturn command.ErrNoGlobalParams\n\t\t}\n\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgparams.QuietCLIMode,\n\t\t\tgparams.OutputFormat)\n\n\t\ttargetEndpoint := ctx.String(FlagTarget)\n\t\tif targetEndpoint == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\txc.Out.Error(\"param.target\", \"missing target\")\n\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\ttargetEndpoint = ctx.Args().First()\n\t\t\t}\n\t\t}\n\n\t\thttpProbeOpts := command.GetHTTPProbeOptions(xc, ctx, true)\n\t\ttargetPorts := ctx.UintSlice(FlagPort)\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgparams,\n\t\t\ttargetEndpoint,\n\t\t\ttargetPorts,\n\t\t\thttpProbeOpts)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/probe/flags.go",
    "content": "package probe\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Probe command flag names and usage descriptions\nconst (\n\tFlagTarget      = \"target\"\n\tFlagTargetUsage = \"Target endpoint to probe\"\n\n\t//for now just TCP ports (so no FlagProto for now)\n\tFlagPort      = \"port\"\n\tFlagPortUsage = \"Endpoint port to probe\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagTarget: &cli.StringFlag{\n\t\tName:    FlagTarget,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTargetUsage,\n\t\tEnvVars: []string{\"DSLIM_PRB_TARGET\"},\n\t},\n\tFlagPort: &cli.UintSliceFlag{\n\t\tName:    FlagPort,\n\t\tValue:   cli.NewUintSlice(),\n\t\tUsage:   FlagPortUsage,\n\t\tEnvVars: []string{\"DSLIM_PRB_PORT\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/probe/handler.go",
    "content": "package probe\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/probe/http\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'probe' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\ttargetEndpoint string,\n\ttargetPorts []uint,\n\thttpProbeOpts config.HTTPProbeOptions) {\n\tprintState := true\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": Name})\n\tcmdName := fmt.Sprintf(\"cmd=%s\", Name)\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewProbeCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(cmd.StateStarted)\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"target\": targetEndpoint,\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := -222\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tprobe, err := http.NewEndpointProbe(xc, targetEndpoint, targetPorts, httpProbeOpts, printState)\n\txc.FailOn(err)\n\n\tprobe.Start()\n\n\txc.Out.Prompt(\"waiting for the HTTP probe to finish\")\n\t<-probe.DoneChan()\n\txc.Out.Info(\"event\",\n\t\tovars{\n\t\t\t\"message\": \"HTTP probe is done\",\n\t\t})\n\n\tif probe != nil && probe.CallCount > 0 && probe.OkCount == 0 {\n\t\txc.Out.Error(\"probe.error\", \"no.successful.calls\")\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/probe/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/probe\"\n)\n\nfunc init() {\n\tprobe.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/probe/prompt.go",
    "content": "package probe\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(FlagTarget), Description: FlagTargetUsage},\n\t\t{Text: command.FullFlagName(FlagPort), Description: FlagPortUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCmd), Description: command.FlagHTTPProbeCmdUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCmdFile), Description: command.FlagHTTPProbeCmdFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeStartWait), Description: command.FlagHTTPProbeStartWaitUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeRetryCount), Description: command.FlagHTTPProbeRetryCountUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeRetryWait), Description: command.FlagHTTPProbeRetryWaitUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbePorts), Description: command.FlagHTTPProbePortsUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeFull), Description: command.FlagHTTPProbeFullUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeExitOnFailure), Description: command.FlagHTTPProbeExitOnFailureUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCrawl), Description: command.FlagHTTPProbeCrawlUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlMaxDepth), Description: command.FlagHTTPCrawlMaxDepthUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlMaxPageCount), Description: command.FlagHTTPCrawlMaxPageCountUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlConcurrency), Description: command.FlagHTTPCrawlConcurrencyUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPMaxConcurrentCrawlers), Description: command.FlagHTTPMaxConcurrentCrawlersUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeAPISpec), Description: command.FlagHTTPProbeAPISpecUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeAPISpecFile), Description: command.FlagHTTPProbeAPISpecFileUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(command.FlagHTTPProbeCmdFile):     command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeFull):        command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeCrawl):       command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeAPISpecFile): command.CompleteFile,\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/probe/register.go",
    "content": "package probe\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/profile/cli.go",
    "content": "package profile\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\nconst (\n\tName  = \"profile\"\n\tUsage = \"Collects fat image information and generates a fat container report\"\n\tAlias = \"p\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: append([]cli.Flag{\n\t\tcommand.Cflag(command.FlagTarget),\n\t\tcommand.Cflag(command.FlagPull),\n\t\tcommand.Cflag(command.FlagDockerConfigPath),\n\t\tcommand.Cflag(command.FlagRegistryAccount),\n\t\tcommand.Cflag(command.FlagRegistrySecret),\n\t\tcommand.Cflag(command.FlagShowPullLogs),\n\t\t//Compose support\n\t\tcommand.Cflag(command.FlagComposeFile),                    //not used yet\n\t\tcommand.Cflag(command.FlagTargetComposeSvc),               //not used yet\n\t\tcommand.Cflag(command.FlagComposeSvcStartWait),            //not used yet\n\t\tcommand.Cflag(command.FlagTargetComposeSvcImage),          //not used yet\n\t\tcommand.Cflag(command.FlagComposeSvcNoPorts),              //not used yet\n\t\tcommand.Cflag(command.FlagDepExcludeComposeSvcAll),        //not used yet\n\t\tcommand.Cflag(command.FlagDepIncludeComposeSvc),           //not used yet\n\t\tcommand.Cflag(command.FlagDepExcludeComposeSvc),           //not used yet\n\t\tcommand.Cflag(command.FlagDepIncludeComposeSvcDeps),       //not used yet\n\t\tcommand.Cflag(command.FlagDepIncludeTargetComposeSvcDeps), //not used yet\n\t\tcommand.Cflag(command.FlagComposeNet),                     //not used yet\n\t\tcommand.Cflag(command.FlagComposeEnvNoHost),               //not used yet\n\t\tcommand.Cflag(command.FlagComposeEnvFile),                 //not used yet\n\t\tcommand.Cflag(command.FlagComposeProjectName),             //not used yet\n\t\tcommand.Cflag(command.FlagComposeWorkdir),                 //not used yet\n\t\tcommand.Cflag(command.FlagPublishPort),\n\t\tcommand.Cflag(command.FlagPublishExposedPorts),\n\t\tcommand.Cflag(command.FlagHostExec),\n\t\tcommand.Cflag(command.FlagHostExecFile),\n\t\t//command.Cflag(command.FlagKeepPerms),\n\t\tcommand.Cflag(command.FlagRunTargetAsUser),\n\t\tcommand.Cflag(command.FlagShowContainerLogs),\n\t\tcommand.Cflag(command.FlagEnableMondelLogs),\n\t\tcommand.Cflag(command.FlagCopyMetaArtifacts),\n\t\tcommand.Cflag(command.FlagRemoveFileArtifacts),\n\t\tcommand.Cflag(command.FlagExec),\n\t\tcommand.Cflag(command.FlagExecFile),\n\t\t//Container Run Options\n\t\tcommand.Cflag(command.FlagCRORuntime),\n\t\tcommand.Cflag(command.FlagCROHostConfigFile),\n\t\tcommand.Cflag(command.FlagCROSysctl),\n\t\tcommand.Cflag(command.FlagCROShmSize),\n\t\tcommand.Cflag(command.FlagUser),\n\t\tcommand.Cflag(command.FlagEntrypoint),\n\t\tcommand.Cflag(command.FlagCmd),\n\t\tcommand.Cflag(command.FlagWorkdir),\n\t\tcommand.Cflag(command.FlagEnv),\n\t\tcommand.Cflag(command.FlagEnvFile),\n\t\tcommand.Cflag(command.FlagLabel),\n\t\tcommand.Cflag(command.FlagVolume),\n\t\tcommand.Cflag(command.FlagLink),\n\t\tcommand.Cflag(command.FlagEtcHostsMap),\n\t\tcommand.Cflag(command.FlagContainerDNS),\n\t\tcommand.Cflag(command.FlagContainerDNSSearch),\n\t\tcommand.Cflag(command.FlagNetwork),\n\t\tcommand.Cflag(command.FlagHostname),\n\t\tcommand.Cflag(command.FlagExpose),\n\t\t//command.Cflag(command.FlagExcludeMounts),\n\t\t//command.Cflag(command.FlagExcludePattern), //should remove too (no need)\n\t\tcommand.Cflag(command.FlagMount),\n\t\tcommand.Cflag(command.FlagContinueAfter),\n\t\tcommand.Cflag(command.FlagUseLocalMounts),\n\t\tcommand.Cflag(command.FlagUseSensorVolume),\n\t\t//Sensor flags:\n\t\tcommand.Cflag(command.FlagSensorIPCEndpoint),\n\t\tcommand.Cflag(command.FlagSensorIPCMode),\n\t}, command.HTTPProbeFlags()...),\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\ttargetRef := ctx.String(command.FlagTarget)\n\t\tif targetRef == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\txc.Out.Error(\"param.target\", \"missing target image ID/name\")\n\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t}\n\t\t}\n\n\t\tcrOpts, err := command.GetContainerRunOptions(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.container.run.options\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdoPull := ctx.Bool(command.FlagPull)\n\t\tdockerConfigPath := ctx.String(command.FlagDockerConfigPath)\n\t\tregistryAccount := ctx.String(command.FlagRegistryAccount)\n\t\tregistrySecret := ctx.String(command.FlagRegistrySecret)\n\t\tdoShowPullLogs := ctx.Bool(command.FlagShowPullLogs)\n\n\t\tdoRmFileArtifacts := ctx.Bool(command.FlagRemoveFileArtifacts)\n\t\tdoCopyMetaArtifacts := ctx.String(command.FlagCopyMetaArtifacts)\n\n\t\tportBindings, err := command.ParsePortBindings(ctx.StringSlice(command.FlagPublishPort))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.publish.port\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdoPublishExposedPorts := ctx.Bool(command.FlagPublishExposedPorts)\n\n\t\thttpProbeOpts := command.GetHTTPProbeOptions(xc, ctx, false)\n\n\t\tcontinueAfter, err := command.GetContinueAfter(ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.continue.after\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tif !httpProbeOpts.Do && continueAfter.Mode == \"probe\" {\n\t\t\tcontinueAfter.Mode = \"enter\"\n\t\t\txc.Out.Info(\"enter\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"changing continue-after from probe to enter because http-probe is disabled\",\n\t\t\t\t})\n\t\t}\n\n\t\thostExecProbes := ctx.StringSlice(command.FlagHostExec)\n\t\tmoreHostExecProbes, err := command.ParseHTTPProbeExecFile(ctx.String(command.FlagHostExecFile))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.host.exec.file\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tif len(moreHostExecProbes) > 0 {\n\t\t\thostExecProbes = append(hostExecProbes, moreHostExecProbes...)\n\t\t}\n\n\t\tif strings.Contains(continueAfter.Mode, config.CAMHostExec) &&\n\t\t\tlen(hostExecProbes) == 0 {\n\t\t\tif continueAfter.Mode == config.CAMHostExec {\n\t\t\t\tcontinueAfter.Mode = config.CAMEnter\n\t\t\t\txc.Out.Info(\"host-exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": \"changing continue-after from host-exec to enter because there are no host-exec commands\",\n\t\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tcontinueAfter.Mode = command.RemoveContinueAfterMode(continueAfter.Mode, config.CAMHostExec)\n\t\t\t\txc.Out.Info(\"host-exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": \"removing host-exec continue-after mode because there are no host-exec commands\",\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif len(hostExecProbes) > 0 {\n\t\t\tif !strings.Contains(continueAfter.Mode, config.CAMHostExec) {\n\t\t\t\tif continueAfter.Mode == \"\" {\n\t\t\t\t\tcontinueAfter.Mode = config.CAMHostExec\n\t\t\t\t} else {\n\t\t\t\t\tcontinueAfter.Mode = fmt.Sprintf(\"%s&%s\", continueAfter.Mode, config.CAMHostExec)\n\t\t\t\t}\n\n\t\t\t\txc.Out.Info(\"exec\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\": fmt.Sprintf(\"updating continue-after mode to %s\", continueAfter.Mode),\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\t//doKeepPerms := ctx.Bool(command.FlagKeepPerms)\n\n\t\tdoRunTargetAsUser := ctx.Bool(command.FlagRunTargetAsUser)\n\n\t\tdoShowContainerLogs := ctx.Bool(command.FlagShowContainerLogs)\n\t\tdoEnableMondel := ctx.Bool(command.FlagEnableMondelLogs)\n\n\t\toverrides, err := command.GetContainerOverrides(xc, ctx)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.container.overrides\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tvolumeMounts, err := command.ParseVolumeMounts(ctx.StringSlice(command.FlagMount))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.mount\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\t//excludePatterns := command.ParsePaths(ctx.StringSlice(command.FlagExcludePattern))\n\n\t\t//includePaths := command.ParsePaths(ctx.StringSlice(command.FlagIncludePath))\n\t\t//moreIncludePaths, err := command.ParsePathsFile(ctx.String(command.FlagIncludePathFile))\n\t\t//if err != nil {\n\t\t//\txc.Out.Error(\"param.error.include.path.file\", err.Error())\n\t\t//\txc.Out.State(\"exited\",\n\t\t//\t\tovars{\n\t\t//\t\t\t\"exit.code\": -1,\n\t\t//\t\t})\n\t\t//\txc.Exit(-1)\n\t\t//} else {\n\t\t//\tfor k, v := range moreIncludePaths {\n\t\t//\t\tincludePaths[k] = v\n\t\t//\t}\n\t\t//}\n\n\t\t//pathPerms := command.ParsePaths(ctx.StringSlice(command.FlagPathPerms))\n\t\t//morePathPerms, err := command.ParsePathsFile(ctx.String(command.FlagPathPermsFile))\n\t\t//if err != nil {\n\t\t//\txc.Out.Error(\"param.error.path.perms.file\", err.Error())\n\t\t//\txc.Out.State(\"exited\",\n\t\t//\t\tovars{\n\t\t//\t\t\t\"exit.code\": -1,\n\t\t//\t\t})\n\t\t//\txc.Exit(-1)\n\t\t//} else {\n\t\t//\tfor k, v := range morePathPerms {\n\t\t//\t\tpathPerms[k] = v\n\t\t//\t}\n\t\t//}\n\n\t\t//includeBins := command.ParsePaths(ctx.StringSlice(command.FlagIncludeBin))\n\t\t//includeExes := command.ParsePaths(ctx.StringSlice(command.FlagIncludeExe))\n\t\t//doIncludeShell := ctx.Bool(command.FlagIncludeShell)\n\n\t\tdoUseLocalMounts := ctx.Bool(command.FlagUseLocalMounts)\n\t\tdoUseSensorVolume := ctx.String(command.FlagUseSensorVolume)\n\n\t\t//doKeepTmpArtifacts := ctx.Bool(command.FlagKeepTmpArtifacts)\n\n\t\t//doExcludeMounts := ctx.Bool(command.FlagExcludeMounts)\n\t\t//if doExcludeMounts {\n\t\t//\tfor mpath := range volumeMounts {\n\t\t//\t\texcludePatterns[mpath] = nil\n\t\t//\t\tmpattern := fmt.Sprintf(\"%s/**\", mpath)\n\t\t//\t\texcludePatterns[mpattern] = nil\n\t\t//\t}\n\t\t//}\n\n\t\tcommandReport := ctx.String(command.FlagCommandReport)\n\t\tif commandReport == \"off\" {\n\t\t\tcommandReport = \"\"\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues,\n\t\t\ttargetRef,\n\t\t\tdoPull,\n\t\t\tdockerConfigPath,\n\t\t\tregistryAccount,\n\t\t\tregistrySecret,\n\t\t\tdoShowPullLogs,\n\t\t\tcrOpts,\n\t\t\thttpProbeOpts,\n\t\t\tportBindings,\n\t\t\tdoPublishExposedPorts,\n\t\t\thostExecProbes,\n\t\t\tdoRmFileArtifacts,\n\t\t\tdoCopyMetaArtifacts,\n\t\t\tdoRunTargetAsUser,\n\t\t\tdoShowContainerLogs,\n\t\t\tdoEnableMondel,\n\t\t\toverrides,\n\t\t\tctx.StringSlice(command.FlagLink),\n\t\t\tctx.StringSlice(command.FlagEtcHostsMap),\n\t\t\tctx.StringSlice(command.FlagContainerDNS),\n\t\t\tctx.StringSlice(command.FlagContainerDNSSearch),\n\t\t\tvolumeMounts,\n\t\t\t//doKeepPerms,\n\t\t\t//pathPerms,\n\t\t\t//excludePatterns,\n\t\t\t//includePaths,\n\t\t\t//includeBins,\n\t\t\t//includeExes,\n\t\t\t//doIncludeShell,\n\t\t\tdoUseLocalMounts,\n\t\t\tdoUseSensorVolume,\n\t\t\t//doKeepTmpArtifacts,\n\t\t\tcontinueAfter,\n\t\t\tctx.String(command.FlagSensorIPCEndpoint),\n\t\t\tctx.String(command.FlagSensorIPCMode),\n\t\t\tctx.String(command.FlagLogLevel),\n\t\t\tctx.String(command.FlagLogFormat))\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/profile/handler.go",
    "content": "package profile\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"time\"\n\n\t\"github.com/dustin/go-humanize\"\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/container\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/probe/http\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\n// Profile command exit codes\nconst (\n\tecpOther = iota + 1\n\tecpNoEntrypoint\n\tecpImageNotFound\n)\n\ntype ovars = app.OutVars\n\n//note: the runtime part of the 'profile' logic is a bit behind 'build'\n//todo: refactor 'xray', 'profile' and 'build' to compose and reuse common logic\n\n// OnCommand implements the 'profile' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\ttargetRef string,\n\tdoPull bool,\n\tdockerConfigPath string,\n\tregistryAccount string,\n\tregistrySecret string,\n\tdoShowPullLogs bool,\n\tcrOpts *config.ContainerRunOptions,\n\thttpProbeOpts config.HTTPProbeOptions,\n\tportBindings map[docker.Port][]docker.PortBinding,\n\tdoPublishExposedPorts bool,\n\thostExecProbes []string,\n\tdoRmFileArtifacts bool,\n\tcopyMetaArtifactsLocation string,\n\tdoRunTargetAsUser bool,\n\tdoShowContainerLogs bool,\n\tdoEnableMondel bool,\n\toverrides *config.ContainerOverrides,\n\tlinks []string,\n\tetcHostsMaps []string,\n\tdnsServers []string,\n\tdnsSearchDomains []string,\n\texplicitVolumeMounts map[string]config.VolumeMount,\n\t//doKeepPerms bool,\n\t//pathPerms map[string]*fsutil.AccessInfo,\n\t//excludePatterns map[string]*fsutil.AccessInfo,\n\t//includePaths map[string]*fsutil.AccessInfo,\n\t//includeBins map[string]*fsutil.AccessInfo,\n\t//includeExes map[string]*fsutil.AccessInfo,\n\t//doIncludeShell bool,\n\tdoUseLocalMounts bool,\n\tdoUseSensorVolume string,\n\t//doKeepTmpArtifacts bool,\n\tcontinueAfter *config.ContinueAfter,\n\tsensorIPCEndpoint string,\n\tsensorIPCMode string,\n\tlogLevel string,\n\tlogFormat string) {\n\tprintState := true\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": Name})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewProfileCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\tcmdReport.OriginalImage = targetRef\n\n\txc.Out.State(cmd.StateStarted)\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"target\": targetRef,\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the 'slim' container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, Name, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tif overrides.Network == \"host\" && runtime.GOOS == \"darwin\" {\n\t\txc.Out.Info(\"param.error\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"unsupported.network.mac\",\n\t\t\t\t\"value\":  overrides.Network,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCBadNetworkName\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\n\tif !command.ConfirmNetwork(logger, client, overrides.Network) {\n\t\txc.Out.Info(\"param.error\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"unknown.network\",\n\t\t\t\t\"value\":  overrides.Network,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCBadNetworkName\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\n\timageInspector, err := image.NewInspector(client, targetRef)\n\terrutil.FailOn(err)\n\n\tnoImage, err := imageInspector.NoImage()\n\terrutil.FailOn(err)\n\tif noImage {\n\t\tif doPull {\n\t\t\txc.Out.Info(\"target.image\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"image.not.found\",\n\t\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\t\"message\": \"trying to pull target image\",\n\t\t\t\t})\n\n\t\t\terr := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret)\n\t\t\terrutil.FailOn(err)\n\t\t} else {\n\t\t\txc.Out.Info(\"target.image.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"image.not.found\",\n\t\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\t\"message\": \"make sure the target image already exists locally\",\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTCommon | ecpImageNotFound\n\t\t\txc.Out.State(\"exited\", ovars{\"exit.code\": exitCode})\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t}\n\n\t//refresh the target refs\n\ttargetRef = imageInspector.ImageRef\n\n\txc.Out.State(\"image.inspection.start\")\n\n\tlogger.Info(\"inspecting 'fat' image metadata...\")\n\terr = imageInspector.Inspect()\n\terrutil.FailOn(err)\n\n\tlocalVolumePath, artifactLocation, statePath, stateKey := fsutil.PrepareImageStateDirs(gparams.StatePath, imageInspector.ImageInfo.ID)\n\timageInspector.ArtifactLocation = artifactLocation\n\tlogger.Debugf(\"localVolumePath=%v, artifactLocation=%v, statePath=%v, stateKey=%v\", localVolumePath, artifactLocation, statePath, stateKey)\n\n\txc.Out.Info(\"image\",\n\t\tovars{\n\t\t\t\"id\":           imageInspector.ImageInfo.ID,\n\t\t\t\"size.bytes\":   imageInspector.ImageInfo.VirtualSize,\n\t\t\t\"size.human\":   humanize.Bytes(uint64(imageInspector.ImageInfo.VirtualSize)),\n\t\t\t\"architecture\": imageInspector.ImageInfo.Architecture,\n\t\t})\n\n\tlogger.Info(\"processing 'fat' image info...\")\n\terr = imageInspector.ProcessCollectedData()\n\terrutil.FailOn(err)\n\n\txc.Out.State(\"image.inspection.done\")\n\txc.Out.State(\"container.inspection.start\")\n\n\t//note:\n\t//not pre-processing links for 'profile' yet\n\t//need to copy the logic from 'build'\n\t//(better yet refactor to share code)\n\thasClassicLinks := true //placeholder for now\n\n\tcontainerInspector, err := container.NewInspector(\n\t\txc,\n\t\tcrOpts,\n\t\tlogger,\n\t\tclient,\n\t\tstatePath,\n\t\timageInspector,\n\t\tlocalVolumePath,\n\t\tdoUseLocalMounts,\n\t\tdoUseSensorVolume,\n\t\tfalse, //doKeepTmpArtifacts,\n\t\toverrides,\n\t\texplicitVolumeMounts,\n\t\tnil, //baseMounts,\n\t\tnil, //baseVolumesFrom,\n\t\tportBindings,\n\t\tdoPublishExposedPorts,\n\t\thasClassicLinks,\n\t\tlinks,\n\t\tetcHostsMaps,\n\t\tdnsServers,\n\t\tdnsSearchDomains,\n\t\tdoShowContainerLogs,\n\t\tdoEnableMondel,\n\t\tdoRunTargetAsUser,\n\t\tfalse, //doKeepPerms,\n\t\tnil,   //pathPerms,\n\t\tnil,   //excludePatterns,\n\t\tfalse, //doExcludeVarLockFiles\n\t\tnil,   //preservePaths,\n\t\tnil,   //includePaths,\n\t\tnil,   //includeBins,\n\t\tnil,   //includeDirBinsList,\n\t\tnil,   //includeExes,\n\t\tfalse, //doIncludeShell,\n\t\tfalse, //doIncludeWorkdir,\n\t\tfalse, //doIncludeCertAll\n\t\tfalse, //doIncludeCertBundles\n\t\tfalse, //doIncludeCertDirs\n\t\tfalse, //doIncludeCertPKAll\n\t\tfalse, //doIncludeCertPKDirs\n\t\tfalse, //doIncludeNew\n\t\tfalse, //doIncludeSSHClient\n\t\tfalse, //doIncludeOSLibsNet\n\t\tfalse, //doIncludeZoneInfo\n\t\tnil,   //selectedNetNames\n\t\tgparams.Debug,\n\t\tlogLevel,\n\t\tlogFormat,\n\t\tgparams.InContainer,\n\t\ttrue,  //rtaSourcePT\n\t\tfalse, //doObfuscateMetadata\n\t\tsensorIPCEndpoint,\n\t\tsensorIPCMode,\n\t\tprintState,\n\t\tconfig.AppNodejsInspectOptions{})\n\terrutil.FailOn(err)\n\n\tif len(containerInspector.FatContainerCmd) == 0 {\n\t\txc.Out.Info(\"target.image.error\",\n\t\t\tovars{\n\t\t\t\t\"status\":  \"no.entrypoint.cmd\",\n\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\"message\": \"no ENTRYPOINT/CMD\",\n\t\t\t})\n\n\t\texitCode := command.ECTBuild | ecpNoEntrypoint\n\t\txc.Out.State(\"exited\", ovars{\"exit.code\": exitCode})\n\t\txc.Exit(exitCode)\n\t}\n\n\tlogger.Info(\"starting instrumented 'fat' container...\")\n\terr = containerInspector.RunContainer()\n\tif err != nil {\n\t\tcontainerInspector.ShowContainerLogs()\n\t\tcontainerInspector.ShutdownContainer(true)\n\t\txc.FailOn(err)\n\t}\n\n\txc.Out.Info(\"container\",\n\t\tovars{\n\t\t\t\"name\":             containerInspector.ContainerName,\n\t\t\t\"id\":               containerInspector.ContainerID,\n\t\t\t\"target.port.list\": containerInspector.ContainerPortList,\n\t\t\t\"target.port.info\": containerInspector.ContainerPortsInfo,\n\t\t\t\"message\":          \"YOU CAN USE THESE PORTS TO INTERACT WITH THE CONTAINER\",\n\t\t})\n\n\tlogger.Info(\"watching container monitor...\")\n\n\tif config.CAMProbe == continueAfter.Mode {\n\t\thttpProbeOpts.Do = true\n\t}\n\n\tvar probe *http.CustomProbe\n\tif httpProbeOpts.Do {\n\t\tvar err error\n\t\tprobe, err = http.NewContainerProbe(xc, containerInspector, httpProbeOpts, printState)\n\t\terrutil.FailOn(err)\n\n\t\tif len(probe.Ports()) == 0 {\n\t\t\txc.Out.State(\"http.probe.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"error\":   \"NO EXPOSED PORTS\",\n\t\t\t\t\t\"message\": \"expose your service port with --expose or disable HTTP probing with --http-probe=false if your containerized application doesnt expose any network services\",\n\t\t\t\t})\n\n\t\t\tlogger.Info(\"shutting down 'fat' container...\")\n\t\t\tcontainerInspector.FinishMonitoring()\n\t\t\t_ = containerInspector.ShutdownContainer(false)\n\n\t\t\txc.Out.State(\"exited\", ovars{\"exit.code\": -1})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tprobe.Start()\n\t\tcontinueAfter.ContinueChan = probe.DoneChan()\n\t}\n\n\tcontinueAfterMsg := \"provide the expected input to allow the container inspector to continue its execution\"\n\tswitch continueAfter.Mode {\n\tcase config.CAMTimeout:\n\t\tcontinueAfterMsg = \"no input required, execution will resume after the timeout\"\n\tcase config.CAMProbe:\n\t\tcontinueAfterMsg = \"no input required, execution will resume when HTTP probing is completed\"\n\t}\n\n\txc.Out.Info(\"continue.after\",\n\t\tovars{\n\t\t\t\"mode\":    continueAfter.Mode,\n\t\t\t\"message\": continueAfterMsg,\n\t\t})\n\n\texecFail := false\n\n\tmodes := command.GetContinueAfterModeNames(continueAfter.Mode)\n\tfor _, mode := range modes {\n\t\tswitch mode {\n\t\t//case config.CAMContainerProbe:\n\t\t/*\n\t\t\tcase config.CAMExec:\n\t\t\t\tvar input *bytes.Buffer\n\t\t\t\tvar cmd []string\n\t\t\t\tif len(execFileCmd) != 0 {\n\t\t\t\t\tinput = bytes.NewBufferString(execFileCmd)\n\t\t\t\t\tcmd = []string{\"sh\", \"-s\"}\n\t\t\t\t\tfor _, line := range strings.Split(string(execFileCmd), \"\\n\") {\n\t\t\t\t\t\txc.Out.Info(\"continue.after\",\n\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\"mode\":  config.CAMExec,\n\t\t\t\t\t\t\t\t\"shell\": line,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tinput = bytes.NewBufferString(\"\")\n\t\t\t\t\tcmd = []string{\"sh\", \"-c\", execCmd}\n\t\t\t\t\txc.Out.Info(\"continue.after\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"mode\":  config.CAMExec,\n\t\t\t\t\t\t\t\"shell\": execCmd,\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\texec, err := containerInspector.APIClient.CreateExec(dockerapi.CreateExecOptions{\n\t\t\t\t\tContainer:    containerInspector.ContainerID,\n\t\t\t\t\tCmd:          cmd,\n\t\t\t\t\tAttachStdin:  true,\n\t\t\t\t\tAttachStdout: true,\n\t\t\t\t\tAttachStderr: true,\n\t\t\t\t})\n\t\t\t\txc.FailOn(err)\n\n\t\t\t\tbuffer := &printbuffer.PrintBuffer{Prefix: fmt.Sprintf(\"%s[%s][exec]: output:\", appName, Name)}\n\t\t\t\txc.FailOn(containerInspector.APIClient.StartExec(exec.ID, dockerapi.StartExecOptions{\n\t\t\t\t\tInputStream:  input,\n\t\t\t\t\tOutputStream: buffer,\n\t\t\t\t\tErrorStream:  buffer,\n\t\t\t\t}))\n\n\t\t\t\tinspect, err := containerInspector.APIClient.InspectExec(exec.ID)\n\t\t\t\txc.FailOn(err)\n\t\t\t\terrutil.FailWhen(inspect.Running, \"still running\")\n\t\t\t\tif inspect.ExitCode != 0 {\n\t\t\t\t\texecFail = true\n\t\t\t\t}\n\n\t\t\t\txc.Out.Info(\"continue.after\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"mode\":     config.CAMExec,\n\t\t\t\t\t\t\"exitcode\": inspect.ExitCode,\n\t\t\t\t\t})\n\t\t*/\n\t\tcase config.CAMEnter:\n\t\t\txc.Out.Prompt(\"USER INPUT REQUIRED, PRESS <ENTER> WHEN YOU ARE DONE USING THE CONTAINER\")\n\t\t\tcreader := bufio.NewReader(os.Stdin)\n\t\t\t_, _, _ = creader.ReadLine()\n\t\tcase config.CAMSignal:\n\t\t\txc.Out.Prompt(\"send SIGUSR1 when you are done using the container\")\n\t\t\t<-continueAfter.ContinueChan\n\t\t\txc.Out.Info(\"event\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"got SIGUSR1\",\n\t\t\t\t})\n\t\tcase config.CAMTimeout:\n\t\t\txc.Out.Prompt(fmt.Sprintf(\"waiting for the target container (%v seconds)\", int(continueAfter.Timeout)))\n\t\t\t<-time.After(time.Second * continueAfter.Timeout)\n\t\t\txc.Out.Info(\"event\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"done waiting for the target container\",\n\t\t\t\t})\n\t\tcase config.CAMProbe:\n\t\t\txc.Out.Prompt(\"waiting for the HTTP probe to finish\")\n\t\t\t<-continueAfter.ContinueChan\n\t\t\txc.Out.Info(\"event\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"HTTP probe is done\",\n\t\t\t\t})\n\n\t\t\tif probe != nil && probe.CallCount > 0 && probe.OkCount == 0 && httpProbeOpts.ExitOnFailure {\n\t\t\t\txc.Out.Error(\"probe.error\", \"no.successful.calls\")\n\n\t\t\t\tcontainerInspector.ShowContainerLogs()\n\t\t\t\txc.Out.State(\"exited\", ovars{\"exit.code\": -1})\n\t\t\t\txc.Exit(-1)\n\t\t\t}\n\t\tcase config.CAMHostExec:\n\t\t\tcommand.RunHostExecProbes(printState, xc, hostExecProbes)\n\t\tcase config.CAMAppExit:\n\t\t\txc.Out.Prompt(\"waiting for the target app to exit\")\n\t\t\t//TBD\n\t\tdefault:\n\t\t\terrutil.Fail(\"unknown continue-after mode\")\n\t\t}\n\t}\n\n\txc.Out.State(\"container.inspection.finishing\")\n\n\tcontainerInspector.FinishMonitoring()\n\n\tlogger.Info(\"shutting down 'fat' container...\")\n\terr = containerInspector.ShutdownContainer(false)\n\terrutil.WarnOn(err)\n\n\tif execFail {\n\t\txc.Out.Info(\"continue.after\",\n\t\t\tovars{\n\t\t\t\t\"mode\":    config.CAMExec,\n\t\t\t\t\"message\": \"fatal: exec cmd failure\",\n\t\t\t})\n\n\t\texitCode := 1\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t})\n\n\t\tcmdReport.Error = \"exec.cmd.failure\"\n\t\txc.Exit(exitCode)\n\t}\n\n\txc.Out.State(\"container.inspection.artifact.processing\")\n\n\tif !containerInspector.HasCollectedData() {\n\t\timageInspector.ShowFatImageDockerInstructions()\n\t\txc.Out.Info(\"results\",\n\t\t\tovars{\n\t\t\t\t\"status\":   \"no data collected (no minified image generated)\",\n\t\t\t\t\"version\":  v.Current(),\n\t\t\t\t\"location\": fsutil.ExeDir(),\n\t\t\t})\n\n\t\txc.Out.State(\"exited\", ovars{\"exit.code\": -1})\n\t\txc.Exit(-1)\n\t}\n\n\tlogger.Info(\"processing instrumented 'fat' container info...\")\n\terr = containerInspector.ProcessCollectedData()\n\terrutil.FailOn(err)\n\n\txc.Out.State(\"container.inspection.done\")\n\txc.Out.State(cmd.StateCompleted)\n\n\tcmdReport.State = cmd.StateCompleted\n\n\tcmdReport.SeccompProfileName = imageInspector.SeccompProfileName\n\tcmdReport.AppArmorProfileName = imageInspector.AppArmorProfileName\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.seccomp\": cmdReport.SeccompProfileName,\n\t\t})\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.apparmor\": cmdReport.AppArmorProfileName,\n\t\t})\n\n\tif copyMetaArtifactsLocation != \"\" {\n\t\ttoCopy := []string{\n\t\t\treport.DefaultContainerReportFileName,\n\t\t\timageInspector.SeccompProfileName,\n\t\t\timageInspector.AppArmorProfileName,\n\t\t}\n\t\tif !command.CopyMetaArtifacts(logger,\n\t\t\ttoCopy,\n\t\t\tartifactLocation, copyMetaArtifactsLocation) {\n\t\t\txc.Out.Info(\"artifacts\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"could not copy meta artifacts\",\n\t\t\t\t})\n\t\t}\n\t}\n\n\tif err := command.DoArchiveState(logger, client, artifactLocation, gparams.ArchiveState, stateKey); err != nil {\n\t\txc.Out.Info(\"state\",\n\t\t\tovars{\n\t\t\t\t\"message\": \"could not archive state\",\n\t\t\t})\n\n\t\tlogger.Errorf(\"error archiving state - %v\", err)\n\t}\n\n\tif doRmFileArtifacts {\n\t\tlogger.Info(\"removing temporary artifacts...\")\n\t\terr = fsutil.Remove(artifactLocation)\n\t\terrutil.WarnOn(err)\n\t}\n\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/profile/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/profile\"\n)\n\nfunc init() {\n\tprofile.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/profile/prompt.go",
    "content": "package profile\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(command.FlagTarget), Description: command.FlagTargetUsage},\n\t\t{Text: command.FullFlagName(command.FlagPull), Description: command.FlagPullUsage},\n\t\t{Text: command.FullFlagName(command.FlagShowPullLogs), Description: command.FlagShowPullLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagShowContainerLogs), Description: command.FlagShowContainerLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagEnableMondelLogs), Description: command.FlagEnableMondelLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagCRORuntime), Description: command.FlagCRORuntimeUsage},\n\t\t{Text: command.FullFlagName(command.FlagCROHostConfigFile), Description: command.FlagCROHostConfigFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagCROSysctl), Description: command.FlagCROSysctlUsage},\n\t\t{Text: command.FullFlagName(command.FlagCROShmSize), Description: command.FlagCROShmSizeUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeOff), Description: command.FlagHTTPProbeOffUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbe), Description: command.FlagHTTPProbeUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCmd), Description: command.FlagHTTPProbeCmdUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCmdFile), Description: command.FlagHTTPProbeCmdFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeStartWait), Description: command.FlagHTTPProbeStartWaitUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeRetryCount), Description: command.FlagHTTPProbeRetryCountUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeRetryWait), Description: command.FlagHTTPProbeRetryWaitUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbePorts), Description: command.FlagHTTPProbePortsUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeFull), Description: command.FlagHTTPProbeFullUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeExitOnFailure), Description: command.FlagHTTPProbeExitOnFailureUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeCrawl), Description: command.FlagHTTPProbeCrawlUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlMaxDepth), Description: command.FlagHTTPCrawlMaxDepthUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlMaxPageCount), Description: command.FlagHTTPCrawlMaxPageCountUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPCrawlConcurrency), Description: command.FlagHTTPCrawlConcurrencyUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPMaxConcurrentCrawlers), Description: command.FlagHTTPMaxConcurrentCrawlersUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeAPISpec), Description: command.FlagHTTPProbeAPISpecUsage},\n\t\t{Text: command.FullFlagName(command.FlagHTTPProbeAPISpecFile), Description: command.FlagHTTPProbeAPISpecFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagPublishPort), Description: command.FlagPublishPortUsage},\n\t\t{Text: command.FullFlagName(command.FlagPublishExposedPorts), Description: command.FlagPublishExposedPortsUsage},\n\t\t{Text: command.FullFlagName(command.FlagHostExec), Description: command.FlagHostExecUsage},\n\t\t{Text: command.FullFlagName(command.FlagHostExecFile), Description: command.FlagHostExecFileUsage},\n\t\t//{Text: command.FullFlagName(command.FlagKeepPerms), Description: command.FlagKeepPermsUsage},\n\t\t{Text: command.FullFlagName(command.FlagRunTargetAsUser), Description: command.FlagRunTargetAsUserUsage},\n\t\t{Text: command.FullFlagName(command.FlagCopyMetaArtifacts), Description: command.FlagCopyMetaArtifactsUsage},\n\t\t{Text: command.FullFlagName(command.FlagRemoveFileArtifacts), Description: command.FlagRemoveFileArtifactsUsage},\n\t\t{Text: command.FullFlagName(command.FlagUser), Description: command.FlagUserUsage},\n\t\t{Text: command.FullFlagName(command.FlagEntrypoint), Description: command.FlagEntrypointUsage},\n\t\t{Text: command.FullFlagName(command.FlagCmd), Description: command.FlagCmdUsage},\n\t\t{Text: command.FullFlagName(command.FlagWorkdir), Description: command.FlagWorkdirUsage},\n\t\t{Text: command.FullFlagName(command.FlagEnv), Description: command.FlagEnvUsage},\n\t\t{Text: command.FullFlagName(command.FlagEnvFile), Description: command.FlagEnvFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagLabel), Description: command.FlagLabelUsage},\n\t\t{Text: command.FullFlagName(command.FlagVolume), Description: command.FlagVolumeUsage},\n\t\t{Text: command.FullFlagName(command.FlagLink), Description: command.FlagLinkUsage},\n\t\t{Text: command.FullFlagName(command.FlagEtcHostsMap), Description: command.FlagEtcHostsMapUsage},\n\t\t{Text: command.FullFlagName(command.FlagContainerDNS), Description: command.FlagContainerDNSUsage},\n\t\t{Text: command.FullFlagName(command.FlagContainerDNSSearch), Description: command.FlagContainerDNSSearchUsage},\n\t\t{Text: command.FullFlagName(command.FlagNetwork), Description: command.FlagNetworkUsage},\n\t\t{Text: command.FullFlagName(command.FlagHostname), Description: command.FlagHostnameUsage},\n\t\t{Text: command.FullFlagName(command.FlagExpose), Description: command.FlagExposeUsage},\n\t\t//{Text: command.FullFlagName(command.FlagExcludeMounts), Description: command.FlagExcludeMountsUsage},\n\t\t//{Text: command.FullFlagName(command.FlagExcludePattern), Description: command.FlagExcludePatternUsage},\n\t\t{Text: command.FullFlagName(command.FlagMount), Description: command.FlagMountUsage},\n\t\t{Text: command.FullFlagName(command.FlagContinueAfter), Description: command.FlagContinueAfterUsage},\n\t\t{Text: command.FullFlagName(command.FlagUseLocalMounts), Description: command.FlagUseLocalMountsUsage},\n\t\t{Text: command.FullFlagName(command.FlagUseSensorVolume), Description: command.FlagUseSensorVolumeUsage},\n\t\t{Text: command.FullFlagName(command.FlagSensorIPCMode), Description: command.FlagSensorIPCModeUsage},\n\t\t{Text: command.FullFlagName(command.FlagSensorIPCEndpoint), Description: command.FlagSensorIPCEndpointUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(command.FlagPull):                   command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagShowPullLogs):           command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagTarget):                 command.CompleteImage,\n\t\tcommand.FullFlagName(command.FlagShowContainerLogs):      command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagEnableMondelLogs):       command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagPublishExposedPorts):    command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeOff):           command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbe):              command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeCmdFile):       command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeFull):          command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeExitOnFailure): command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeCrawl):         command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagHTTPProbeAPISpecFile):   command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagHostExecFile):           command.CompleteFile,\n\t\t//command.FullFlagName(command.FlagKeepPerms):              command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagRunTargetAsUser):     command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagRemoveFileArtifacts): command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagNetwork):             command.CompleteNetwork,\n\t\t//command.FullFlagName(command.FlagExcludeMounts):       command.CompleteTBool,\n\t\t//command.FullFlagName(command.FlagPathPermsFile):          command.CompleteFile,\n\t\t//command.FullFlagName(command.FlagIncludePathFile):        command.CompleteFile,\n\t\t//command.FullFlagName(command.FlagIncludeShell):           command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagContinueAfter): command.CompleteContinueAfter,\n\t\t//command.FullFlagName(command.FlagConsoleOutput):   command.CompleteConsoleOutput,\n\t\tcommand.FullFlagName(command.FlagUseLocalMounts):  command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagUseSensorVolume): command.CompleteVolume,\n\t\t//command.FullFlagName(command.FlagKeepTmpArtifacts):       command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagCROHostConfigFile): command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagSensorIPCMode):     command.CompleteIPCMode,\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/profile/register.go",
    "content": "package profile\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/auth.go",
    "content": "package registry\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\t//log \"github.com/sirupsen/logrus\"\n)\n\nfunc ConfigureAuth(cparams *CommonCommandParams, remoteOpts []remote.Option) ([]remote.Option, error) {\n\tif cparams.UseDockerCreds {\n\t\tremoteOpts = append(remoteOpts, remote.WithAuthFromKeychain(authn.DefaultKeychain))\n\t\treturn remoteOpts, nil\n\t}\n\n\tif cparams.CredsAccount != \"\" && cparams.CredsSecret != \"\" {\n\t\tremoteOpts = append(remoteOpts, remote.WithAuth(&authn.Basic{\n\t\t\tUsername: cparams.CredsAccount,\n\t\t\tPassword: cparams.CredsSecret,\n\t\t}))\n\n\t\treturn remoteOpts, nil\n\t}\n\n\t//it's authn.Anonymous by default, but good to be explicit\n\treturn append(remoteOpts, remote.WithAuth(authn.Anonymous)), nil\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/cli.go",
    "content": "package registry\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"registry\"\n\tUsage = \"Execute registry operations\"\n\tAlias = \"reg\"\n\n\tPullCmdName      = \"pull\"\n\tPullCmdNameUsage = \"Pull a container image from registry\"\n\n\tPushCmdName      = \"push\"\n\tPushCmdNameUsage = \"Push a container image to a registry\"\n\n\tCopyCmdName      = \"copy\"\n\tCopyCmdNameUsage = \"Copy a container image from one registry to another\"\n\n\tImageIndexCreateCmdName      = \"image-index-create\"\n\tImageIndexCreateCmdNameUsage = \"Create an image index (aka manifest list) with the referenced images (already in the target registry)\"\n\n\tServerCmdName      = \"server\"\n\tServerCmdNameUsage = \"Start a registry server\"\n)\n\nfunc fullCmdName(subCmdName string) string {\n\treturn fmt.Sprintf(\"%s.%s\", Name, subCmdName)\n}\n\ntype CommonCommandParams struct {\n\tUseDockerCreds bool\n\tCredsAccount   string\n\tCredsSecret    string\n}\n\nfunc CommonCommandFlagValues(ctx *cli.Context) (*CommonCommandParams, error) {\n\tvalues := &CommonCommandParams{\n\t\tUseDockerCreds: ctx.Bool(FlagUseDockerCreds),\n\t\tCredsAccount:   ctx.String(FlagCredsAccount),\n\t\t//prefer env var for secret (todo: add interactive and file read modes)\n\t\tCredsSecret: ctx.String(FlagCredsSecret),\n\t}\n\n\treturn values, nil\n}\n\ntype PullCommandParams struct {\n\t*CommonCommandParams\n\tTargetRef    string\n\tSaveToDocker bool\n}\n\nfunc PullCommandFlagValues(ctx *cli.Context) (*PullCommandParams, error) {\n\tcommon, err := CommonCommandFlagValues(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalues := &PullCommandParams{\n\t\tCommonCommandParams: common,\n\t\tTargetRef:           ctx.String(command.FlagTarget),\n\t\tSaveToDocker:        ctx.Bool(FlagSaveToDocker),\n\t}\n\n\treturn values, nil\n}\n\ntype PushCommandParams struct {\n\t*CommonCommandParams\n\tTargetRef  string\n\tTargetType string\n\tAsTag      string\n}\n\nconst (\n\tttDocker = \"tt.docker\"\n\tttTar    = \"tt.tar\"\n\tttOCI    = \"tt.oci\"\n)\n\nfunc PushCommandFlagValues(ctx *cli.Context) (*PushCommandParams, error) {\n\tcommon, err := CommonCommandFlagValues(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalues := &PushCommandParams{\n\t\tCommonCommandParams: common,\n\t\tAsTag:               ctx.String(FlagAs),\n\t}\n\n\tif val := ctx.String(FlagDocker); val != \"\" {\n\t\t//todo: validate that this local docker image exists\n\t\tvalues.TargetRef = val\n\t\tvalues.TargetType = ttDocker\n\t} else if val := ctx.String(FlagTar); val != \"\" {\n\t\t//todo: validate that this local tar file exists\n\t\tvalues.TargetRef = val\n\t\tvalues.TargetType = ttTar\n\t} else if val := ctx.String(FlagOCI); val != \"\" {\n\t\t//todo: validate that this local directory exists\n\t\tvalues.TargetRef = val\n\t\tvalues.TargetType = ttOCI\n\t}\n\n\treturn values, nil\n}\n\ntype ImageIndexCreateCommandParams struct {\n\t*CommonCommandParams\n\tImageIndexName  string\n\tImageNames      []string\n\tAsManifestList  bool\n\tInsecureRefs    bool\n\tDumpRawManifest bool\n}\n\nfunc ImageIndexCreateCommandFlagValues(ctx *cli.Context) (*ImageIndexCreateCommandParams, error) {\n\tcommon, err := CommonCommandFlagValues(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalues := &ImageIndexCreateCommandParams{\n\t\tCommonCommandParams: common,\n\t\tImageIndexName:      ctx.String(FlagImageIndexName),\n\t\tImageNames:          ctx.StringSlice(FlagImageName),\n\t\tAsManifestList:      ctx.Bool(FlagAsManifestList),\n\t\tInsecureRefs:        ctx.Bool(FlagInsecureRefs),\n\t\tDumpRawManifest:     ctx.Bool(FlagDumpRawManifest),\n\t}\n\n\treturn values, nil\n}\n\ntype ServerCommandParams struct {\n\t*CommonCommandParams\n\tDomain       string\n\tAddress      string\n\tPort         uint\n\tUseHTTPS     bool\n\tCertPath     string\n\tKeyPath      string\n\tReferrersAPI bool\n\tStorePath    string\n\tUseMemStore  bool\n}\n\nfunc ServerCommandFlagValues(ctx *cli.Context) (*ServerCommandParams, error) {\n\tcommon, err := CommonCommandFlagValues(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalues := &ServerCommandParams{\n\t\tCommonCommandParams: common,\n\t\tDomain:              ctx.String(FlagDomain),\n\t\tAddress:             ctx.String(FlagAddress),\n\t\tPort:                ctx.Uint(FlagPort),\n\t\tUseHTTPS:            ctx.Bool(FlagHTTPS),\n\t\tCertPath:            ctx.String(FlagCertPath),\n\t\tKeyPath:             ctx.String(FlagKeyPath),\n\t\tReferrersAPI:        ctx.Bool(FlagReferrersAPI),\n\t\tStorePath:           ctx.String(FlagStorePath),\n\t\tUseMemStore:         ctx.Bool(FlagMemStore),\n\t}\n\n\treturn values, nil\n}\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tcflag(FlagUseDockerCreds),\n\t\tcflag(FlagCredsAccount),\n\t\tcflag(FlagCredsSecret),\n\t},\n\tSubcommands: []*cli.Command{\n\t\t{\n\t\t\tName:  PullCmdName,\n\t\t\tUsage: PullCmdNameUsage,\n\t\t\tFlags: []cli.Flag{\n\t\t\t\tcommand.Cflag(command.FlagTarget),\n\t\t\t\tcflag(FlagSaveToDocker),\n\t\t\t},\n\t\t\tAction: func(ctx *cli.Context) error {\n\t\t\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\t\t\txc := app.NewExecutionContext(\n\t\t\t\t\tfullCmdName(PullCmdName),\n\t\t\t\t\tgcvalues.QuietCLIMode,\n\t\t\t\t\tgcvalues.OutputFormat)\n\n\t\t\t\tcparams, err := PullCommandFlagValues(ctx)\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 cparams.TargetRef == \"\" {\n\t\t\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\t\t\txc.Out.Error(\"param.target\", \"missing target\")\n\t\t\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcparams.TargetRef = ctx.Args().First()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tOnPullCommand(xc, gcvalues, cparams)\n\t\t\t\treturn nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName:  PushCmdName,\n\t\t\tUsage: PushCmdNameUsage,\n\t\t\tFlags: []cli.Flag{\n\t\t\t\tcflag(FlagAs),\n\t\t\t\tcflag(FlagDocker),\n\t\t\t\tcflag(FlagTar),\n\t\t\t\tcflag(FlagOCI),\n\t\t\t},\n\t\t\tAction: func(ctx *cli.Context) error {\n\t\t\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\t\t\txc := app.NewExecutionContext(\n\t\t\t\t\tfullCmdName(PushCmdName),\n\t\t\t\t\tgcvalues.QuietCLIMode,\n\t\t\t\t\tgcvalues.OutputFormat)\n\n\t\t\t\tcparams, err := PushCommandFlagValues(ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\txc.Out.Error(\"params\", err.Error())\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tif cparams.TargetType == \"\" {\n\t\t\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\t\t\txc.Out.Error(\"params.target\", \"missing pull target\")\n\t\t\t\t\t\treturn fmt.Errorf(\"no target selected\")\n\t\t\t\t\t}\n\n\t\t\t\t\tcparams.TargetRef = ctx.Args().First()\n\t\t\t\t\tcparams.TargetType = ttDocker\n\t\t\t\t}\n\n\t\t\t\tOnPushCommand(xc, gcvalues, cparams)\n\t\t\t\treturn nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName:  CopyCmdName,\n\t\t\tUsage: CopyCmdNameUsage,\n\t\t\tAction: func(ctx *cli.Context) error {\n\t\t\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\t\t\txc := app.NewExecutionContext(\n\t\t\t\t\tfullCmdName(CopyCmdName),\n\t\t\t\t\tgcvalues.QuietCLIMode,\n\t\t\t\t\tgcvalues.OutputFormat)\n\n\t\t\t\tOnCopyCommand(xc, gcvalues)\n\t\t\t\treturn nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName:  ImageIndexCreateCmdName,\n\t\t\tUsage: ImageIndexCreateCmdNameUsage,\n\t\t\tFlags: []cli.Flag{\n\t\t\t\tcflag(FlagImageIndexName),\n\t\t\t\tcflag(FlagImageName),\n\t\t\t\tcflag(FlagAsManifestList),\n\t\t\t\tcflag(FlagInsecureRefs),\n\t\t\t\tcflag(FlagDumpRawManifest),\n\t\t\t},\n\t\t\tAction: func(ctx *cli.Context) error {\n\t\t\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\t\t\txc := app.NewExecutionContext(\n\t\t\t\t\tfullCmdName(ImageIndexCreateCmdName),\n\t\t\t\t\tgcvalues.QuietCLIMode,\n\t\t\t\t\tgcvalues.OutputFormat)\n\n\t\t\t\tcparams, err := ImageIndexCreateCommandFlagValues(ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tOnImageIndexCreateCommand(xc, gcvalues, cparams)\n\t\t\t\treturn nil\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tName:  ServerCmdName,\n\t\t\tUsage: ServerCmdNameUsage,\n\t\t\tFlags: []cli.Flag{\n\t\t\t\tcflag(FlagDomain),\n\t\t\t\tcflag(FlagAddress),\n\t\t\t\tcflag(FlagPort),\n\t\t\t\tcflag(FlagHTTPS),\n\t\t\t\tcflag(FlagCertPath),\n\t\t\t\tcflag(FlagKeyPath),\n\t\t\t\tcflag(FlagReferrersAPI),\n\t\t\t},\n\t\t\tAction: func(ctx *cli.Context) error {\n\t\t\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\t\t\txc := app.NewExecutionContext(\n\t\t\t\t\tfullCmdName(ServerCmdName),\n\t\t\t\t\tgcvalues.QuietCLIMode,\n\t\t\t\t\tgcvalues.OutputFormat)\n\n\t\t\t\tcparams, err := ServerCommandFlagValues(ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tOnServerCommand(xc, gcvalues, cparams)\n\t\t\t\treturn nil\n\t\t\t},\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/flags.go",
    "content": "package registry\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Registry command flag names\nconst (\n\tFlagUseDockerCreds      = \"use-docker-credentials\"\n\tFlagUseDockerCredsUsage = \"Use the registry credentials from the default Docker config file\"\n\n\tFlagCredsAccount      = \"account\"\n\tFlagCredsAccountUsage = \"Registry credentials account\"\n\n\tFlagCredsSecret      = \"secret\"\n\tFlagCredsSecretUsage = \"Registry credentials secret\"\n\n\t// Pull Flags\n\n\tFlagSaveToDocker      = \"save-to-docker\"\n\tFlagSaveToDockerUsage = \"Save pulled image to docker\"\n\n\t// Push Flags\n\n\tFlagDocker      = \"docker\"\n\tFlagDockerUsage = \"Push local docker image\"\n\n\tFlagTar      = \"tar\"\n\tFlagTarUsage = \"Push image from a local tar file\"\n\n\tFlagOCI      = \"oci\"\n\tFlagOCIUsage = \"Push image from a local OCI Image Layout directory\"\n\n\tFlagAs      = \"as\"\n\tFlagAsUsage = \"Tag the selected image with the specified name before pushing\"\n\n\t// Image Index Flags\n\n\tFlagImageIndexName      = \"image-index-name\"\n\tFlagImageIndexNameUsage = \"Image index name to use\"\n\n\tFlagImageName      = \"image-name\"\n\tFlagImageNameUsage = \"Target image name to include in image index\"\n\n\tFlagAsManifestList      = \"as-manifest-list\"\n\tFlagAsManifestListUsage = \"Create image index with the manifest list media type instead of the default OCI image index type\"\n\n\tFlagInsecureRefs      = \"insecure-refs\"\n\tFlagInsecureRefsUsage = \"Allow the referenced images from insecure registry connections\"\n\n\tFlagDumpRawManifest      = \"dump-raw-manifest\"\n\tFlagDumpRawManifestUsage = \"Dump raw manifest for the created image index\"\n\n\t// Registry Server Flags\n\n\tFlagAddress      = \"address\"\n\tFlagAddressUsage = \"Registry server address\"\n\n\tFlagPort      = \"port\"\n\tFlagPortUsage = \"Registry server port\"\n\n\tFlagDomain      = \"domain\"\n\tFlagDomainUsage = \"Domain to use for registry server (to get certs)\"\n\n\tFlagHTTPS      = \"https\"\n\tFlagHTTPSUsage = \"Use HTTPS\"\n\n\tFlagCertPath      = \"cert-path\"\n\tFlagCertPathUsage = \"Cert path for use with HTTPS\"\n\n\tFlagKeyPath      = \"key-path\"\n\tFlagKeyPathUsage = \"Key path for use with HTTPS\"\n\n\tFlagReferrersAPI      = \"referrers-api\"\n\tFlagReferrersAPIUsage = \"Enables the referrers API endpoint (OCI 1.1+) for the registry server\"\n\n\tFlagStorePath      = \"store-path\"\n\tFlagStorePathUsage = \"Directory to store registry blobs\"\n\n\tFlagMemStore      = \"mem-store\"\n\tFlagMemStoreUsage = \"Use memory registry blob store\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagUseDockerCreds: &cli.BoolFlag{\n\t\tName:    FlagUseDockerCreds,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagUseDockerCredsUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_DOCKER_CREDS\"},\n\t},\n\tFlagCredsAccount: &cli.StringFlag{\n\t\tName:    FlagCredsAccount,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCredsAccountUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_ACCOUNT\"},\n\t},\n\tFlagCredsSecret: &cli.StringFlag{\n\t\tName:    FlagCredsSecret,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCredsSecretUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SECRET\"},\n\t},\n\t// Pull Flags:\n\tFlagSaveToDocker: &cli.BoolFlag{\n\t\tName:    FlagSaveToDocker,\n\t\tValue:   true, //defaults to true\n\t\tUsage:   FlagSaveToDockerUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_PULL_SAVE_TO_DOCKER\"},\n\t},\n\t// Push Flags:\n\tFlagDocker: &cli.StringFlag{\n\t\tName:    FlagDocker,\n\t\tValue:   \"\",\n\t\tUsage:   FlagDockerUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_PUSH_DOCKER\"},\n\t},\n\tFlagTar: &cli.StringFlag{\n\t\tName:    FlagTar,\n\t\tValue:   \"\",\n\t\tUsage:   FlagTarUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_PUSH_TAR\"},\n\t},\n\tFlagOCI: &cli.StringFlag{\n\t\tName:    FlagOCI,\n\t\tValue:   \"\",\n\t\tUsage:   FlagOCIUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_PUSH_OCI\"},\n\t},\n\tFlagAs: &cli.StringFlag{\n\t\tName:    FlagAs,\n\t\tValue:   \"\",\n\t\tUsage:   FlagAsUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_PUSH_AS\"},\n\t},\n\t// Image Index Flags:\n\tFlagImageIndexName: &cli.StringFlag{\n\t\tName:    FlagImageIndexName,\n\t\tValue:   \"\",\n\t\tUsage:   FlagImageIndexNameUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_IIC_INDEX_NAME\"},\n\t},\n\tFlagImageName: &cli.StringSliceFlag{\n\t\tName:    FlagImageName,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagImageNameUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_IIC_IMAGE_NAME\"},\n\t},\n\tFlagAsManifestList: &cli.BoolFlag{\n\t\tName:    FlagAsManifestList,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagAsManifestListUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_IIC_AS_MLIST\"},\n\t},\n\tFlagInsecureRefs: &cli.BoolFlag{\n\t\tName:    FlagInsecureRefs,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagInsecureRefsUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_IIC_INSECURE_REFS\"},\n\t},\n\tFlagDumpRawManifest: &cli.BoolFlag{\n\t\tName:    FlagDumpRawManifest,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagDumpRawManifestUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_IIC_DUMP_MANIFEST\"},\n\t},\n\t// Registry Server Flags:\n\tFlagReferrersAPI: &cli.BoolFlag{\n\t\tName:    FlagReferrersAPI,\n\t\tValue:   true, //defaults to true\n\t\tUsage:   FlagReferrersAPIUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_REFERRERS_API\"},\n\t},\n\tFlagDomain: &cli.StringFlag{\n\t\tName:    FlagDomain,\n\t\tValue:   \"\",\n\t\tUsage:   FlagDomainUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_DOMAIN\"},\n\t},\n\tFlagAddress: &cli.StringFlag{\n\t\tName:    FlagAddress,\n\t\tValue:   \"0.0.0.0\",\n\t\tUsage:   FlagAddressUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_ADDR\"},\n\t},\n\tFlagPort: &cli.UintFlag{\n\t\tName:    FlagPort,\n\t\tValue:   5000,\n\t\tUsage:   FlagPortUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_PORT\"},\n\t},\n\tFlagHTTPS: &cli.BoolFlag{\n\t\tName:    FlagHTTPS,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagHTTPSUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_HTTPS\"},\n\t},\n\tFlagCertPath: &cli.StringFlag{\n\t\tName:    FlagCertPath,\n\t\tValue:   \"\",\n\t\tUsage:   FlagCertPathUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_CERT\"},\n\t},\n\tFlagKeyPath: &cli.StringFlag{\n\t\tName:    FlagKeyPath,\n\t\tValue:   \"\",\n\t\tUsage:   FlagKeyPathUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_KEY\"},\n\t},\n\tFlagStorePath: &cli.StringFlag{\n\t\tName:    FlagStorePath,\n\t\tValue:   \"registry_server_data\",\n\t\tUsage:   FlagStorePathUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_STORE_PATH\"},\n\t},\n\tFlagMemStore: &cli.BoolFlag{\n\t\tName:    FlagMemStore,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagMemStoreUsage,\n\t\tEnvVars: []string{\"DSLIM_REG_SRV_MEM_STORE\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/handler_copy.go",
    "content": "package registry\n\nimport (\n\t//\"github.com/google/go-containerregistry/pkg/crane\"\n\t//\"github.com/google/go-containerregistry/pkg/name\"\n\t//gocrv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t//\"github.com/google/go-containerregistry/pkg/v1/daemon\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// OnCopyCommand implements the 'registry copy' command\nfunc OnCopyCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams) {\n\tcmdName := fullCmdName(CopyCmdName)\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": appName,\n\t\t\"cmd\": cmdName,\n\t\t\"sub\": CopyCmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewRegistryCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(cmd.StateStarted)\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the docker-slim container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/handler_image_index.go",
    "content": "package registry\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/empty\"\n\t\"github.com/google/go-containerregistry/pkg/v1/mutate\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// OnImageIndexCreateCommand implements the 'registry image-index-create' command\nfunc OnImageIndexCreateCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *ImageIndexCreateCommandParams) {\n\tcmdName := fullCmdName(CopyCmdName)\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": appName,\n\t\t\"cmd\": cmdName,\n\t\t\"sub\": ImageIndexCreateCmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewRegistryCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(cmd.StateStarted)\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the docker-slim container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\txc.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tif len(cparams.ImageNames) == 0 {\n\t\txc.FailOn(fmt.Errorf(\"no image references for image index\"))\n\t}\n\n\tif !cparams.UseDockerCreds &&\n\t\t!(cparams.CredsAccount != \"\" && cparams.CredsSecret != \"\") {\n\t\txc.FailOn(fmt.Errorf(\"missing auth params\"))\n\t}\n\n\tremoteOpts := []remote.Option{\n\t\tremote.WithContext(context.Background()),\n\t}\n\n\tremoteOpts, err = ConfigureAuth(cparams.CommonCommandParams, remoteOpts)\n\txc.FailOn(err)\n\n\tnameOpts := []name.Option{\n\t\tname.WeakValidation,\n\t}\n\n\tif cparams.InsecureRefs {\n\t\tnameOpts = append(nameOpts, name.Insecure)\n\t}\n\n\timageIndexRef, err := name.ParseReference(cparams.ImageIndexName, nameOpts...)\n\tif err != nil {\n\t\txc.FailOn(fmt.Errorf(\"malformed image index reference - %s (%v)\", cparams.ImageIndexName, err))\n\t}\n\n\tif _, err := remote.Head(imageIndexRef, remoteOpts...); err != nil {\n\t\tif _, ok := err.(*transport.Error); ok {\n\t\t\tlogger.Debug(\"no image index in registry (ok)\")\n\t\t} else {\n\t\t\tlogger.Debugf(\"error checking image index in registry - %v\", err)\n\t\t}\n\t} else {\n\t\tlogger.Debug(\"image index is already in the registry\")\n\t}\n\n\timageIndex := v1.ImageIndex(empty.Index)\n\tindexImageImgRefs := make([]mutate.IndexAddendum, 0, len(cparams.ImageNames))\n\tfor _, imageName := range cparams.ImageNames {\n\t\timgRef, err := name.ParseReference(imageName, nameOpts...)\n\t\tif err != nil {\n\t\t\txc.FailOn(fmt.Errorf(\"malformed image reference - %s (%v)\", imageName, err))\n\t\t}\n\n\t\tmeta, err := remote.Get(imgRef, remoteOpts...)\n\t\tif err != nil {\n\t\t\txc.FailOn(fmt.Errorf(\"image reference metadata get error - %s (%v)\", imageName, err))\n\t\t}\n\n\t\tif meta.MediaType.IsImage() {\n\t\t\timgMeta, err := meta.Image()\n\t\t\txc.FailOn(err)\n\n\t\t\tbasicImageInfo(xc, imgMeta)\n\n\t\t\timgConfig, err := imgMeta.ConfigFile()\n\t\t\tif err != nil {\n\t\t\t\txc.FailOn(err)\n\t\t\t}\n\t\t\timgRefMeta, err := partial.Descriptor(imgMeta)\n\t\t\tif err != nil {\n\t\t\t\txc.FailOn(err)\n\t\t\t}\n\t\t\timgRefMeta.Platform = imgConfig.Platform()\n\t\t\tindexImageImgRefs = append(indexImageImgRefs,\n\t\t\t\tmutate.IndexAddendum{\n\t\t\t\t\tAdd:        imgMeta,\n\t\t\t\t\tDescriptor: *imgRefMeta,\n\t\t\t\t})\n\t\t} else {\n\t\t\txc.FailOn(fmt.Errorf(\"unexpected target image type - %s (%v)\", imageName, meta.MediaType))\n\t\t}\n\t}\n\n\tif cparams.AsManifestList {\n\t\timageIndex = mutate.IndexMediaType(imageIndex, types.DockerManifestList)\n\t}\n\n\timageIndex = mutate.AppendManifests(imageIndex, indexImageImgRefs...)\n\n\tif err := remote.WriteIndex(imageIndexRef, imageIndex, remoteOpts...); err != nil {\n\t\tvar terr *transport.Error\n\t\tif errors.As(err, &terr) && terr.StatusCode == http.StatusUnauthorized {\n\t\t\txc.Out.Info(\"registry.auth.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"need to authenticate\",\n\t\t\t\t})\n\n\t\t\texitCode := -111\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t})\n\t\t\txc.Exit(exitCode)\n\t\t} else {\n\t\t\txc.FailOn(fmt.Errorf(\"saving image index error - %s (%v)\", cparams.ImageIndexName, err))\n\t\t}\n\t}\n\n\tindexMeta, err := remote.Index(imageIndexRef, remoteOpts...)\n\tif err != nil {\n\t\txc.FailOn(fmt.Errorf(\"index reference metadata get error - %s (%v)\", cparams.ImageIndexName, err))\n\t}\n\n\tindexMediaType, err := indexMeta.MediaType()\n\txc.FailOn(err)\n\n\tif !indexMediaType.IsIndex() {\n\t\txc.FailOn(fmt.Errorf(\"unexpected media type for index\"))\n\t}\n\n\tindexDigest, err := indexMeta.Digest()\n\txc.FailOn(err)\n\n\tindexManifest, err := indexMeta.IndexManifest()\n\txc.FailOn(err)\n\txc.Out.Info(\"index.info\",\n\t\tovars{\n\t\t\t\"reference\":                imageIndexRef,\n\t\t\t\"digest\":                   indexDigest.String(),\n\t\t\t\"manifest.schema\":          indexManifest.SchemaVersion,\n\t\t\t\"manifest.media_type\":      indexManifest.MediaType,\n\t\t\t\"manifest.image.ref.count\": len(indexManifest.Manifests),\n\t\t})\n\n\tif cparams.DumpRawManifest {\n\t\tif rm, err := indexMeta.RawManifest(); err == nil {\n\t\t\t//todo: reformat to pretty print\n\t\t\tfmt.Printf(\"\\n\\n%s\\n\\n\", string(rm))\n\t\t}\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\nfunc basicImageInfo(\n\txc *app.ExecutionContext,\n\ttargetImage v1.Image) {\n\tcn, err := targetImage.ConfigName()\n\txc.FailOn(err)\n\n\td, err := targetImage.Digest()\n\txc.FailOn(err)\n\n\tcf, err := targetImage.ConfigFile()\n\txc.FailOn(err)\n\n\tm, err := targetImage.Manifest()\n\txc.FailOn(err)\n\n\txc.Out.Info(\"image.info\",\n\t\tovars{\n\t\t\t\"id\":                         fmt.Sprintf(\"%s:%s\", cn.Algorithm, cn.Hex),\n\t\t\t\"digest\":                     fmt.Sprintf(\"%s:%s\", d.Algorithm, d.Hex),\n\t\t\t\"architecture\":               cf.Architecture,\n\t\t\t\"os\":                         cf.OS,\n\t\t\t\"manifest.schema\":            m.SchemaVersion,\n\t\t\t\"manifest.media_type\":        m.MediaType,\n\t\t\t\"manifest.config.media_type\": m.Config.MediaType,\n\t\t\t\"manifest.config.size\":       fmt.Sprintf(\"%v\", m.Config.Size),\n\t\t\t\"manifest.config.digest\":     fmt.Sprintf(\"%s:%s\", m.Config.Digest.Algorithm, m.Config.Digest.Hex),\n\t\t\t\"manifest.layers.count\":      fmt.Sprintf(\"%v\", len(m.Layers)),\n\t\t})\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/handler_pull.go",
    "content": "package registry\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/daemon\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnPullCommand implements the 'registry pull' command\nfunc OnPullCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *PullCommandParams) {\n\tcmdName := fullCmdName(PullCmdName)\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": appName,\n\t\t\"cmd\": cmdName,\n\t\t\"sub\": PullCmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewRegistryCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\tcmdReport.TargetReference = cparams.TargetRef\n\n\txc.Out.State(cmd.StateStarted)\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"cmd.params\": fmt.Sprintf(\"%+v\", cparams),\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the docker-slim container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tremoteOpts := []remote.Option{\n\t\tremote.WithContext(context.Background()),\n\t}\n\tremoteOpts, err = ConfigureAuth(cparams.CommonCommandParams, remoteOpts)\n\txc.FailOn(err)\n\n\tnameOpts := []name.Option{\n\t\tname.WeakValidation,\n\t\tname.Insecure,\n\t}\n\n\tref, err := name.ParseReference(cparams.TargetRef, nameOpts...)\n\terrutil.FailOn(err)\n\n\t//todo: pass a custom client to Pull (based on `client` above)\n\ttargetImage, err := remote.Image(ref, remoteOpts...)\n\terrutil.FailOn(err)\n\toutImageInfo(xc, targetImage)\n\n\tif cparams.SaveToDocker {\n\t\txc.Out.State(\"save.docker.start\")\n\n\t\ttag, err := name.NewTag(cparams.TargetRef)\n\t\terrutil.FailOn(err)\n\n\t\trawResponse, err := daemon.Write(tag, targetImage)\n\t\terrutil.FailOn(err)\n\t\tlogger.Tracef(\"Image save to Docker response: %v\", rawResponse)\n\n\t\txc.Out.State(\"save.docker.done\")\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\nfunc outImageInfo(\n\txc *app.ExecutionContext,\n\ttargetImage v1.Image) {\n\tcn, err := targetImage.ConfigName()\n\txc.FailOn(err)\n\n\td, err := targetImage.Digest()\n\txc.FailOn(err)\n\n\tcf, err := targetImage.ConfigFile()\n\txc.FailOn(err)\n\n\tm, err := targetImage.Manifest()\n\txc.FailOn(err)\n\n\txc.Out.Info(\"image.info\",\n\t\tovars{\n\t\t\t\"id\":                         fmt.Sprintf(\"%s:%s\", cn.Algorithm, cn.Hex),\n\t\t\t\"digest\":                     fmt.Sprintf(\"%s:%s\", d.Algorithm, d.Hex),\n\t\t\t\"architecture\":               cf.Architecture,\n\t\t\t\"os\":                         cf.OS,\n\t\t\t\"manifest.schema\":            m.SchemaVersion,\n\t\t\t\"manifest.media_type\":        m.MediaType,\n\t\t\t\"manifest.config.media_type\": m.Config.MediaType,\n\t\t\t\"manifest.config.size\":       fmt.Sprintf(\"%v\", m.Config.Size),\n\t\t\t\"manifest.config.digest\":     fmt.Sprintf(\"%s:%s\", m.Config.Digest.Algorithm, m.Config.Digest.Hex),\n\t\t\t\"manifest.layers.count\":      fmt.Sprintf(\"%v\", len(m.Layers)),\n\t\t})\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/handler_push.go",
    "content": "package registry\n\nimport (\n\t\"context\"\n\t\"os\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/daemon\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// OnPushCommand implements the 'registry push' command\nfunc OnPushCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *PushCommandParams) {\n\tcmdName := fullCmdName(PushCmdName)\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": appName,\n\t\t\"cmd\": cmdName,\n\t\t\"sub\": PushCmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewRegistryCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(cmd.StateStarted)\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the docker-slim container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\txc.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tremoteOpts := []remote.Option{\n\t\tremote.WithContext(context.Background()),\n\t}\n\tremoteOpts, err = ConfigureAuth(cparams.CommonCommandParams, remoteOpts)\n\txc.FailOn(err)\n\n\tnameOpts := []name.Option{\n\t\tname.WeakValidation,\n\t\tname.Insecure,\n\t}\n\n\t//todo: add support for other target types too\n\tif cparams.TargetType == ttDocker {\n\t\ttarPath, err := uniqueTarFilePath()\n\t\txc.FailOn(err)\n\n\t\terr = saveDockerImage(logger, cparams.TargetRef, tarPath, nameOpts)\n\t\txc.FailOn(err)\n\n\t\tremoteImageName := cparams.TargetRef\n\t\tif cparams.AsTag != \"\" {\n\t\t\tremoteImageName = cparams.AsTag\n\t\t}\n\n\t\terr = pushImageFromTar(logger, tarPath, remoteImageName, nameOpts, remoteOpts)\n\t\txc.FailOn(err)\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\nfunc uniqueTarFilePath() (string, error) {\n\tf, err := os.CreateTemp(\"\", \"saved-image-*.tar\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tdefer f.Close()\n\tdefer os.Remove(f.Name())\n\treturn f.Name(), nil\n}\n\nfunc saveDockerImage(\n\tlogger *log.Entry,\n\tlocalImageName string,\n\ttarPath string,\n\tnameOpts []name.Option) error {\n\tlogger = logger.WithField(\"op\", \"registry.saveDockerImage\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tref, err := name.ParseReference(localImageName, nameOpts...)\n\tif err != nil {\n\t\tlogger.WithError(err).Errorf(\"name.ParseReference(%s)\", localImageName)\n\t\treturn err\n\t}\n\n\timg, err := daemon.Image(ref)\n\tif err != nil {\n\t\tlogger.WithError(err).Errorf(\"daemon.Image(%s)\", localImageName)\n\t\treturn err\n\t}\n\n\tif err := tarball.WriteToFile(tarPath, ref, img); err != nil {\n\t\tlogger.WithError(err).Errorf(\"tarball.WriteToFile(%s, %s)\", tarPath, localImageName)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc pushImageFromTar(\n\tlogger *log.Entry,\n\ttarPath string,\n\tremoteImageName string,\n\tnameOpts []name.Option,\n\tremoteOpts []remote.Option) error {\n\tlogger = logger.WithField(\"op\", \"registry.saveDockerImage\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tref, err := name.ParseReference(remoteImageName, nameOpts...)\n\tif err != nil {\n\t\tlogger.WithError(err).Errorf(\"name.ParseReference(%s)\", remoteImageName)\n\t\treturn err\n\t}\n\n\timg, err := tarball.ImageFromPath(tarPath, nil)\n\tif err != nil {\n\t\tlogger.WithError(err).Errorf(\"tarball.ImageFromPath(%s)\", tarPath)\n\t\treturn err\n\t}\n\n\terr = remote.Write(ref, img, remoteOpts...)\n\tif err != nil {\n\t\tlogger.WithError(err).Errorf(\"tarball.ImageFromPath(%s, %s)\", tarPath, remoteImageName)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/handler_server.go",
    "content": "package registry\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"golang.org/x/crypto/acme/autocert\"\n\tstdlog \"log\"\n\t\"net/http\"\n\t\"time\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/google/go-containerregistry/pkg/registry\"\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t//\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t//\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t//v \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// OnServerCommand implements the 'registry server' command\nfunc OnServerCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *ServerCommandParams) {\n\tcmdName := fullCmdName(ServerCmdName)\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": appName,\n\t\t\"cmd\": cmdName,\n\t\t\"sub\": ServerCmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewRegistryCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(cmd.StateStarted)\n\n\tvar client *docker.Client\n\t/* NOTE: don't really need a docker client for the server...\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the docker-slim container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\txc.FailOn(err)\n\t*/\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\topts := []registry.Option{registry.Logger(stdlog.New(logger.Logger.Out, \"\", stdlog.LstdFlags))}\n\tif cparams.ReferrersAPI {\n\t\topts = append(opts, registry.WithReferrersSupport(true))\n\t}\n\n\t//TODO: add the custom blob handler logic\n\tif cparams.UseMemStore {\n\t\t//bh := registry.NewInMemoryBlobHandler()\n\t} else {\n\t\t//cparams.StorePath\n\t\t//bh = registry.NewDiskBlobHandler(diskp)\n\t\t//opts = append(opts, registry.WithBlobHandler(bh))\n\t}\n\n\t//TODO: wrap http server to record the calls and save them in the report\n\tgo func() {\n\t\ttime.Sleep(3 * time.Second)\n\n\t\txc.Out.State(cmd.StateCompleted)\n\t\tcmdReport.State = cmd.StateCompleted\n\t\txc.Out.State(cmd.StateDone)\n\n\t\tvinfo := <-viChan\n\t\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\t\tcmdReport.State = cmd.StateDone\n\t\tif cmdReport.Save() {\n\t\t\txc.Out.Info(\"report\",\n\t\t\t\tovars{\n\t\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t\t})\n\t\t}\n\t}()\n\n\tserver := &http.Server{\n\t\tAddr:              fmt.Sprintf(\"%s:%d\", cparams.Address, cparams.Port),\n\t\tReadTimeout:       5 * time.Second,\n\t\tReadHeaderTimeout: 4 * time.Second,\n\t\tWriteTimeout:      10 * time.Second,\n\t\tIdleTimeout:       120 * time.Second,\n\t\tHandler:           registry.New(opts...),\n\t}\n\n\tvar err error\n\tif cparams.UseHTTPS {\n\t\tserver.TLSConfig = &tls.Config{\n\t\t\tMinVersion:               tls.VersionTLS12,\n\t\t\tPreferServerCipherSuites: true,\n\t\t\tCurvePreferences: []tls.CurveID{\n\t\t\t\ttls.CurveP256,\n\t\t\t\ttls.X25519,\n\t\t\t},\n\t\t}\n\n\t\tif cparams.Domain != \"\" &&\n\t\t\tcparams.CertPath == \"\" &&\n\t\t\tcparams.KeyPath == \"\" {\n\t\t\tcertManager := autocert.Manager{\n\t\t\t\tPrompt: autocert.AcceptTOS,\n\t\t\t\t//TODO: needs to put it as a sub-dir in the state path\n\t\t\t\tCache:      autocert.DirCache(\".mint_certs\"),\n\t\t\t\tHostPolicy: autocert.HostWhitelist(cparams.Domain),\n\t\t\t}\n\n\t\t\tserver.TLSConfig.GetCertificate = certManager.GetCertificate\n\t\t}\n\n\t\terr = server.ListenAndServeTLS(cparams.CertPath, cparams.KeyPath)\n\t} else {\n\t\terr = server.ListenAndServe()\n\t}\n\n\tif errors.Is(err, http.ErrServerClosed) {\n\t\txc.Out.Message(\"Server is done...\")\n\t} else {\n\t\txc.FailOn(err)\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/registry\"\n)\n\nfunc init() {\n\tregistry.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/prompt.go",
    "content": "package registry\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(FlagUseDockerCreds), Description: FlagUseDockerCredsUsage},\n\t\t{Text: command.FullFlagName(FlagCredsAccount), Description: FlagCredsAccountUsage},\n\t\t{Text: command.FullFlagName(FlagCredsSecret), Description: FlagCredsSecretUsage},\n\t\t//including sub-commands here too\n\t\t{Text: PullCmdName, Description: PullCmdNameUsage},\n\t\t{Text: PushCmdName, Description: PushCmdNameUsage},\n\t\t{Text: ImageIndexCreateCmdName, Description: ImageIndexCreateCmdNameUsage},\n\t\t{Text: ServerCmdName, Description: ServerCmdNameUsage},\n\t},\n\tValues: map[string]command.CompleteValue{},\n}\n"
  },
  {
    "path": "pkg/app/master/command/registry/register.go",
    "content": "package registry\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/run/cli.go",
    "content": "package run\n\nimport (\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\nconst (\n\tName  = \"run\"\n\tUsage = \"Run one or more containers\"\n\tAlias = \"r\"\n)\n\ntype CommandParams struct {\n\tTargetRef        string\n\tDoPull           bool\n\tDockerConfigPath string\n\tRegistryAccount  string\n\tRegistrySecret   string\n\tDoShowPullLogs   bool\n\tEntrypoint       []string\n\tCmd              []string\n\tDoLiveLogs       bool\n\tDoTerminal       bool\n\tPublishPorts     map[dockerapi.Port][]dockerapi.PortBinding\n\tEnvVars          []string\n\tVolumes          []config.VolumeMount\n\tDoRemoveOnExit   bool\n\tDoDetach         bool\n}\n\nfunc CommandFlagValues(ctx *cli.Context) (*CommandParams, error) {\n\tvalues := &CommandParams{\n\t\tTargetRef:        ctx.String(command.FlagTarget),\n\t\tDoPull:           ctx.Bool(command.FlagPull),\n\t\tDockerConfigPath: ctx.String(command.FlagDockerConfigPath),\n\t\tRegistryAccount:  ctx.String(command.FlagRegistryAccount),\n\t\tRegistrySecret:   ctx.String(command.FlagRegistrySecret),\n\t\tDoShowPullLogs:   ctx.Bool(command.FlagShowPullLogs),\n\t\tDoLiveLogs:       ctx.Bool(FlagLiveLogs),\n\t\tDoTerminal:       ctx.Bool(FlagTerminal),\n\t\tEnvVars:          ctx.StringSlice(command.FlagEnv),\n\t\tDoRemoveOnExit:   ctx.Bool(FlagRemove),\n\t\tDoDetach:         ctx.Bool(FlagDetach),\n\t}\n\n\tvar err error\n\tif rawEntrypoint := ctx.String(command.FlagEntrypoint); rawEntrypoint != \"\" {\n\t\tvalues.Entrypoint, err = command.ParseExec(rawEntrypoint)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif rawCmd := ctx.String(command.FlagCmd); rawCmd != \"\" {\n\t\tvalues.Cmd, err = command.ParseExec(rawCmd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif rawVolumes := ctx.StringSlice(command.FlagVolume); len(rawVolumes) > 0 {\n\t\tvalues.Volumes, err = command.ParseVolumeMountsAsList(rawVolumes)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif rawPorts := ctx.StringSlice(FlagPublishPort); len(rawPorts) > 0 {\n\t\tvalues.PublishPorts, err = command.ParsePortBindings(rawPorts)\n\t}\n\n\treturn values, nil\n}\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tcommand.Cflag(command.FlagTarget),\n\t\tcommand.Cflag(command.FlagPull),\n\t\tcommand.Cflag(command.FlagDockerConfigPath),\n\t\tcommand.Cflag(command.FlagRegistryAccount),\n\t\tcommand.Cflag(command.FlagRegistrySecret),\n\t\tcommand.Cflag(command.FlagShowPullLogs),\n\t\tcommand.Cflag(command.FlagEntrypoint),\n\t\tcommand.Cflag(command.FlagCmd),\n\t\tcflag(FlagLiveLogs),\n\t\tcflag(FlagTerminal),\n\t\tcflag(FlagPublishPort),\n\t\tcommand.Cflag(command.FlagEnv),\n\t\tcommand.Cflag(command.FlagVolume),\n\t\tcflag(FlagRemove),\n\t\tcflag(FlagDetach),\n\t},\n\tAction: func(ctx *cli.Context) error {\n\t\tgparams := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgparams.QuietCLIMode,\n\t\t\tgparams.OutputFormat)\n\n\t\tcparams, err := CommandFlagValues(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif cparams.TargetRef == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\txc.Out.Error(\"param.target\", \"missing target\")\n\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\tcparams.TargetRef = ctx.Args().First()\n\t\t\t}\n\t\t}\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgparams,\n\t\t\tcparams)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/run/flags.go",
    "content": "package run\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Run command flag names\nconst (\n\tFlagLiveLogs    = \"live-logs\"\n\tFlagTerminal    = \"terminal\"\n\tFlagPublishPort = \"publish\"\n\tFlagRemove      = \"rm\"\n\tFlagDetach      = \"detach\"\n)\n\n// Run command flag usage info\nconst (\n\tFlagLiveLogsUsage    = \"Show live logs for the container (cant use with --terminal)\"\n\tFlagTerminalUsage    = \"Attach interactive terminal to the container\"\n\tFlagPublishPortUsage = \"Map container port to host port (format => port | hostPort:containerPort | hostIP:hostPort:containerPort | hostIP::containerPort )\"\n\tFlagRemoveUsage      = \"Remove the container when it exits\"\n\tFlagDetachUsage      = \"Start the container and do not wait for it to exit\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagLiveLogs: &cli.BoolFlag{\n\t\tName:    FlagLiveLogs,\n\t\tUsage:   FlagLiveLogsUsage,\n\t\tEnvVars: []string{\"DSLIM_RUN_LIVE_LOGS\"},\n\t},\n\tFlagTerminal: &cli.BoolFlag{\n\t\tName:    FlagTerminal,\n\t\tUsage:   FlagTerminalUsage,\n\t\tEnvVars: []string{\"DSLIM_RUN_TERMINAL\"},\n\t},\n\tFlagPublishPort: &cli.StringSliceFlag{\n\t\tName:    FlagPublishPort,\n\t\tValue:   &cli.StringSlice{},\n\t\tUsage:   FlagPublishPortUsage,\n\t\tEnvVars: []string{\"DSLIM_RUN_PUBLISH_PORT\"},\n\t},\n\tFlagRemove: &cli.BoolFlag{\n\t\tName:    FlagRemove,\n\t\tUsage:   FlagRemoveUsage,\n\t\tEnvVars: []string{\"DSLIM_RUN_RM\"},\n\t},\n\tFlagDetach: &cli.BoolFlag{\n\t\tName:    FlagDetach,\n\t\tUsage:   FlagDetachUsage,\n\t\tEnvVars: []string{\"DSLIM_RUN_DETACH\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/run/handler.go",
    "content": "package run\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/container\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/signals\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\n// Run command exit codes\nconst (\n\tecbOther = iota + 1\n\tecbTarget\n)\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'run' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *CommandParams) {\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": Name})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewRunCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\tcmdReport.TargetReference = cparams.TargetRef\n\n\txc.Out.State(cmd.StateStarted)\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"cmd.params\": fmt.Sprintf(\"%+v\", cparams),\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, Name, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\timageInspector, err := image.NewInspector(client, cparams.TargetRef)\n\terrutil.FailOn(err)\n\n\tnoImage, err := imageInspector.NoImage()\n\terrutil.FailOn(err)\n\tif noImage {\n\t\tif cparams.DoPull {\n\t\t\txc.Out.Info(\"target.image\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"image.not.found\",\n\t\t\t\t\t\"image\":   cparams.TargetRef,\n\t\t\t\t\t\"message\": \"trying to pull target image\",\n\t\t\t\t})\n\n\t\t\terr := imageInspector.Pull(cparams.DoShowPullLogs, cparams.DockerConfigPath, cparams.RegistryAccount, cparams.RegistrySecret)\n\t\t\terrutil.FailOn(err)\n\t\t} else {\n\t\t\txc.Out.Info(\"target.image.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"image.not.found\",\n\t\t\t\t\t\"image\":   cparams.TargetRef,\n\t\t\t\t\t\"message\": \"make sure the target image already exists locally (use --pull flag to auto-download it from registry)\",\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTRun | ecbTarget\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t})\n\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t}\n\n\t//refresh the target refs\n\tcparams.TargetRef = imageInspector.ImageRef\n\tcmdReport.TargetReference = imageInspector.ImageRef\n\n\txc.Out.State(\"container.run.start\")\n\n\toptions := &container.ExecutionOptions{\n\t\tEntrypoint:   cparams.Entrypoint,\n\t\tCmd:          cparams.Cmd,\n\t\tPublishPorts: cparams.PublishPorts,\n\t\tEnvVars:      cparams.EnvVars,\n\t\tVolumes:      cparams.Volumes,\n\t\tLiveLogs:     cparams.DoLiveLogs,\n\t\tTerminal:     cparams.DoTerminal,\n\t}\n\n\tif options.Terminal {\n\t\toptions.LiveLogs = false\n\t}\n\n\tcontainerEventCh := make(chan *container.ExecutionEvenInfo, 10)\n\texe, err := container.NewExecution(\n\t\txc,\n\t\tlogger,\n\t\tclient,\n\t\tcparams.TargetRef,\n\t\toptions,\n\t\tcontainerEventCh,\n\t\ttrue,\n\t\ttrue)\n\n\terrutil.FailOn(err)\n\n\tcontinueCh := make(chan struct{})\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase evt := <-containerEventCh:\n\t\t\t\tlogger.Tracef(\"Exection Event: name=%s\", evt.Event)\n\t\t\t\tswitch evt.Event {\n\t\t\t\tcase container.XEExitedCrash:\n\t\t\t\t\txc.Out.Info(\"target.container.event\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"event\": evt.Event,\n\t\t\t\t\t\t\t\"image\": cparams.TargetRef,\n\t\t\t\t\t\t})\n\n\t\t\t\t\texe.ShowContainerLogs()\n\t\t\t\t\tclose(continueCh)\n\t\t\t\t\treturn\n\t\t\t\tcase container.XEExited:\n\t\t\t\t\tclose(continueCh)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\tcase <-signals.AppContinueChan:\n\t\t\t\terr = exe.Stop()\n\t\t\t\tif err != nil {\n\t\t\t\t\terrutil.WarnOn(err)\n\t\t\t\t}\n\n\t\t\t\tclose(continueCh)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\terr = exe.Start()\n\terrutil.FailOn(err)\n\n\t<-continueCh\n\n\tif cparams.DoRemoveOnExit {\n\t\texe.Cleanup()\n\t}\n\n\txc.Out.State(\"container.run.done\")\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/run/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/run\"\n)\n\nfunc init() {\n\trun.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/run/prompt.go",
    "content": "package run\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/run/register.go",
    "content": "package run\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/server/cli.go",
    "content": "package server\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\n\t\"github.com/urfave/cli/v2\"\n)\n\nconst (\n\tName  = \"server\"\n\tUsage = \"Run as an HTTP server\"\n\tAlias = \"s\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/server/handler.go",
    "content": "package server\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'server' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams) {\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": Name})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewServerCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\n\txc.Out.State(cmd.StateStarted)\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, Name, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/command/server/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/server\"\n)\n\nfunc init() {\n\tserver.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/server/prompt.go",
    "content": "package server\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/server/register.go",
    "content": "package server\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/update/cli.go",
    "content": "package update\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"update\"\n\tUsage = \"Updates slim\"\n\tAlias = \"u\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tinitFlagShowProgress(),\n\t},\n\tAction: func(ctx *cli.Context) error {\n\t\tdoDebug := ctx.Bool(command.FlagDebug)\n\t\tstatePath := ctx.String(command.FlagStatePath)\n\t\tinContainer, isDSImage := command.IsInContainer(ctx.Bool(command.FlagInContainer))\n\t\tarchiveState := command.ArchiveState(ctx.String(command.FlagArchiveState), inContainer)\n\t\tdoShowProgress := ctx.Bool(command.FlagShowProgress)\n\n\t\tOnCommand(doDebug, statePath, archiveState, inContainer, isDSImage, doShowProgress)\n\t\treturn nil\n\t},\n}\n\nfunc initFlagShowProgress() cli.Flag {\n\t//enable 'show-progress' by default only on Mac OS X\n\tvar doShowProgressFlag cli.Flag\n\tswitch runtime.GOOS {\n\tcase \"darwin\":\n\t\tdoShowProgressFlag = &cli.BoolFlag{\n\t\t\tName:    command.FlagShowProgress,\n\t\t\tValue:   true,\n\t\t\tUsage:   fmt.Sprintf(\"%s (default: true)\", command.FlagShowProgressUsage),\n\t\t\tEnvVars: []string{\"DSLIM_UPDATE_SHOW_PROGRESS\"},\n\t\t}\n\tdefault:\n\t\tdoShowProgressFlag = &cli.BoolFlag{\n\t\t\tName:    command.FlagShowProgress,\n\t\t\tUsage:   fmt.Sprintf(\"%s (default: false)\", command.FlagShowProgressUsage),\n\t\t\tEnvVars: []string{\"DSLIM_UPDATE_SHOW_PROGRESS\"},\n\t\t}\n\t}\n\n\treturn doShowProgressFlag\n}\n"
  },
  {
    "path": "pkg/app/master/command/update/handler.go",
    "content": "package update\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/update\"\n)\n\n// OnCommand implements the 'update' command\nfunc OnCommand(doDebug bool, statePath, archiveState string, inContainer, isDSImage bool, doShowProgress bool) {\n\tupdate.Run(doDebug, statePath, inContainer, isDSImage, doShowProgress)\n}\n"
  },
  {
    "path": "pkg/app/master/command/update/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/update\"\n)\n\nfunc init() {\n\tupdate.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/update/prompt.go",
    "content": "package update\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(command.FlagShowProgress), Description: command.FlagShowProgressUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(command.FlagShowProgress): command.CompleteProgress,\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/update/register.go",
    "content": "package update\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/version/cli.go",
    "content": "package version\n\nimport (\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nconst (\n\tName  = \"version\"\n\tUsage = \"Shows slim and docker version information\"\n\tAlias = \"v\"\n)\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues := command.GlobalFlagValues(ctx)\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\tOnCommand(xc,\n\t\t\tgcvalues.Debug,\n\t\t\tgcvalues.InContainer,\n\t\t\tgcvalues.IsDSImage,\n\t\t\tgcvalues.ClientConfig)\n\n\t\treturn nil\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/version/handler.go",
    "content": "package version\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/commands\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\ntype ovars = app.OutVars\n\n// OnCommand implements the 'version' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tdoDebug, inContainer, isDSImage bool,\n\tclientConfig *config.DockerClient) {\n\tlogger := log.WithFields(log.Fields{\"app\": \"slim\", \"cmd\": cmd.Version})\n\n\tclient, err := dockerclient.New(clientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif inContainer && isDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the slim app container\"\n\t\t}\n\n\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": exitMsg,\n\t\t\t})\n\n\t\texitCode := -777\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tversion.Print(xc, Name, logger, client, true, inContainer, isDSImage)\n}\n"
  },
  {
    "path": "pkg/app/master/command/version/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/version\"\n)\n\nfunc init() {\n\tversion.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/version/prompt.go",
    "content": "package version\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n"
  },
  {
    "path": "pkg/app/master/command/version/register.go",
    "content": "package version\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tnil)\n}\n"
  },
  {
    "path": "pkg/app/master/command/vulnerability/cli.go",
    "content": "package vulnerability\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/vulnerability/epss\"\n)\n\nconst (\n\tName  = \"vulnerability\"\n\tUsage = \"Execute vulnerability related tools and operations\"\n\tAlias = \"vuln\"\n\n\tEpssCmdName      = \"epss\"\n\tEpssCmdNameUsage = \"Get EPPS information for the target vulnerabilities\"\n)\n\nconst (\n\tEpssOrderRecordsScoreDesc      = \"score-desc\"\n\tEpssOrderRecordsScoreAsc       = \"score-asc\"\n\tEpssOrderRecordsPercentileDesc = \"percentile-desc\"\n\tEpssOrderRecordsPercentileAsc  = \"percentile-asc\"\n)\n\nfunc IsValidOp(input string) bool {\n\tswitch input {\n\tcase EpssOpLookup, EpssOpList:\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc IsValidOrderRecordsValue(input string) bool {\n\tswitch input {\n\tcase EpssOrderRecordsScoreDesc, EpssOrderRecordsScoreAsc, EpssOrderRecordsPercentileDesc, EpssOrderRecordsPercentileAsc:\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc OrderType(input string) epss.OrderType {\n\tswitch input {\n\tcase EpssOrderRecordsScoreDesc:\n\t\treturn epss.ScoreDescOrder\n\tcase EpssOrderRecordsScoreAsc:\n\t\treturn epss.ScoreAscOrder\n\tcase EpssOrderRecordsPercentileDesc:\n\t\treturn epss.PercentileDescOrder\n\tcase EpssOrderRecordsPercentileAsc:\n\t\treturn epss.PercentileAscOrder\n\t}\n\n\treturn epss.NoOrder\n}\n\nfunc fullCmdName(subCmdName string) string {\n\treturn fmt.Sprintf(\"%s.%s\", Name, subCmdName)\n}\n\ntype CommonCommandParams struct {\n\tCVEList []string\n}\n\nfunc CommonCommandFlagValues(ctx *cli.Context) (*CommonCommandParams, error) {\n\tvalues := &CommonCommandParams{\n\t\tCVEList: ctx.StringSlice(FlagCVE),\n\t}\n\n\treturn values, nil\n}\n\ntype EpssCommandParams struct {\n\t*CommonCommandParams\n\tDate                 time.Time\n\tOp                   string\n\tWithHistory          bool\n\tLimit                uint64\n\tOffset               uint64\n\tFilterCveIDPattern   string\n\tFilterDaysSinceAdded uint\n\tFilterScoreGt        float64\n\tFilterScoreLt        float64\n\tFilterPercentileGt   float64\n\tFilterPercentileLt   float64\n\tFilterOrderRecords   epss.OrderType\n}\n\nfunc EpssCommandFlagValues(ctx *cli.Context) (*EpssCommandParams, error) {\n\tcommon, err := CommonCommandFlagValues(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvalues := &EpssCommandParams{\n\t\tCommonCommandParams:  common,\n\t\tOp:                   ctx.String(FlagOp),\n\t\tWithHistory:          ctx.Bool(FlagWithHistory),\n\t\tLimit:                ctx.Uint64(FlagLimit),\n\t\tOffset:               ctx.Uint64(FlagOffset),\n\t\tFilterCveIDPattern:   ctx.String(FlagFilterCveIDPattern),\n\t\tFilterDaysSinceAdded: ctx.Uint(FlagFilterDaysSinceAdded),\n\t\tFilterScoreGt:        ctx.Float64(FlagFilterScoreGt),\n\t\tFilterScoreLt:        ctx.Float64(FlagFilterScoreLt),\n\t\tFilterPercentileGt:   ctx.Float64(FlagFilterPercentileGt),\n\t\tFilterPercentileLt:   ctx.Float64(FlagFilterPercentileLt),\n\t}\n\n\tif !IsValidOp(values.Op) {\n\t\treturn nil, fmt.Errorf(\"invalid operation - %s\", values.Op)\n\t}\n\n\tif orderStr := ctx.String(FlagFilterOrderRecords); orderStr != \"\" {\n\t\tif !IsValidOrderRecordsValue(orderStr) {\n\t\t\treturn nil, fmt.Errorf(\"invalid order records value - %s\", orderStr)\n\t\t}\n\n\t\tvalues.FilterOrderRecords = OrderType(orderStr)\n\t}\n\n\tif dateStr := ctx.String(FlagDate); dateStr != \"\" {\n\t\tdate, err := epss.DateFromString(dateStr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvalues.Date = date\n\t}\n\n\treturn values, nil\n}\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tcflag(FlagCVE),\n\t},\n\tSubcommands: []*cli.Command{\n\t\t{\n\t\t\tName:  EpssCmdName,\n\t\t\tUsage: EpssCmdNameUsage,\n\t\t\tFlags: []cli.Flag{\n\t\t\t\tcflag(FlagDate),\n\t\t\t\tcflag(FlagOp),\n\t\t\t\tcflag(FlagWithHistory),\n\t\t\t\tcflag(FlagLimit),\n\t\t\t\tcflag(FlagOffset),\n\t\t\t\tcflag(FlagFilterCveIDPattern),\n\t\t\t\tcflag(FlagFilterDaysSinceAdded),\n\t\t\t\tcflag(FlagFilterScoreGt),\n\t\t\t\tcflag(FlagFilterScoreLt),\n\t\t\t\tcflag(FlagFilterPercentileGt),\n\t\t\t\tcflag(FlagFilterPercentileLt),\n\t\t\t\tcflag(FlagFilterOrderRecords),\n\t\t\t},\n\t\t\tAction: func(ctx *cli.Context) error {\n\t\t\t\tgcvalues, ok := command.CLIContextGet(ctx.Context, command.GlobalParams).(*command.GenericParams)\n\t\t\t\tif !ok || gcvalues == nil {\n\t\t\t\t\treturn command.ErrNoGlobalParams\n\t\t\t\t}\n\n\t\t\t\txc := app.NewExecutionContext(\n\t\t\t\t\tfullCmdName(EpssCmdName),\n\t\t\t\t\tgcvalues.QuietCLIMode,\n\t\t\t\t\tgcvalues.OutputFormat)\n\n\t\t\t\tcparams, err := EpssCommandFlagValues(ctx)\n\t\t\t\txc.FailOn(err)\n\n\t\t\t\tif len(cparams.CVEList) == 0 && cparams.Op == EpssOpLookup {\n\t\t\t\t\txc.Fail(\"EPSS lookup requires, at least, one CVE\")\n\t\t\t\t}\n\n\t\t\t\tOnEpssCommand(xc, gcvalues, cparams)\n\t\t\t\treturn nil\n\t\t\t},\n\t\t},\n\t},\n}\n"
  },
  {
    "path": "pkg/app/master/command/vulnerability/flags.go",
    "content": "package vulnerability\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Vulnerability command flags\nconst (\n\t// Shared Flags\n\tFlagCVE      = \"cve\"\n\tFlagCVEUsage = \"Target vulnerability CVE ID\"\n\n\t// EPSS Flags\n\tFlagDate      = \"date\"\n\tFlagDateUsage = \"Date for the EPSS information (YYYY-MM-DD format)\"\n\n\tFlagOp      = \"op\"\n\tFlagOpUsage = \"EPSS operation ('lookup' | 'list')\"\n\n\tFlagWithHistory      = \"with-history\"\n\tFlagWithHistoryUsage = \"Return EPSS results with historical data\"\n\n\tFlagLimit      = \"limit\"\n\tFlagLimitUsage = \"Limit the number of returned records\"\n\n\tFlagOffset      = \"offset\"\n\tFlagOffsetUsage = \"Offset where to start returning records\"\n\n\tFlagFilterCveIDPattern      = \"filter-cve-id-pattern\"\n\tFlagFilterCveIDPatternUsage = \"'CVE ID pattern' ESPP list operation filter\"\n\n\tFlagFilterDaysSinceAdded      = \"filter-days-since-added\"\n\tFlagFilterDaysSinceAddedUsage = \"'days since added' ESPP list operation filter\"\n\n\tFlagFilterScoreGt      = \"filter-score-gt\"\n\tFlagFilterScoreGtUsage = \"'score is greater than' ESPP list operation filter\"\n\n\tFlagFilterScoreLt      = \"filter-score-lt\"\n\tFlagFilterScoreLtUsage = \"'score is less than' ESPP list operation filter\"\n\n\tFlagFilterPercentileGt      = \"filter-percentile-gt\"\n\tFlagFilterPercentileGtUsage = \"'percentile is greater than' ESPP list operation filter\"\n\n\tFlagFilterPercentileLt      = \"filter-percentile-lt\"\n\tFlagFilterPercentileLtUsage = \"'percentile is less than' ESPP list operation filter\"\n\n\tFlagFilterOrderRecords      = \"filter-order-records\"\n\tFlagFilterOrderRecordsUsage = \"'order returned records' ESPP list operation filter ('score-desc' | 'score-asc' | 'percentile-desc' | 'percentile-asc')\"\n)\n\nconst (\n\tEpssOpLookup = \"lookup\"\n\tEpssOpList   = \"list\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagCVE: &cli.StringSliceFlag{\n\t\tName:    FlagCVE,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagCVEUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_CVE\"},\n\t},\n\tFlagDate: &cli.StringFlag{\n\t\tName:    FlagDate,\n\t\tValue:   \"\",\n\t\tUsage:   FlagDateUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_DATE\"},\n\t},\n\tFlagOp: &cli.StringFlag{\n\t\tName:    FlagOp,\n\t\tValue:   EpssOpLookup,\n\t\tUsage:   FlagOpUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_OP\"},\n\t},\n\tFlagWithHistory: &cli.BoolFlag{\n\t\tName:    FlagWithHistory,\n\t\tValue:   false, //defaults to false\n\t\tUsage:   FlagWithHistoryUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_HISTORY\"},\n\t},\n\tFlagLimit: &cli.Uint64Flag{\n\t\tName:    FlagLimit,\n\t\tValue:   10,\n\t\tUsage:   FlagLimitUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_LIMIT\"},\n\t},\n\tFlagOffset: &cli.Uint64Flag{\n\t\tName:    FlagOffset,\n\t\tValue:   0,\n\t\tUsage:   FlagOffsetUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_OFFSET\"},\n\t},\n\tFlagFilterCveIDPattern: &cli.StringFlag{\n\t\tName:    FlagFilterCveIDPattern,\n\t\tValue:   \"\",\n\t\tUsage:   FlagFilterCveIDPatternUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_FILTER_CVEID_PAT\"},\n\t},\n\tFlagFilterDaysSinceAdded: &cli.UintFlag{\n\t\tName:    FlagFilterDaysSinceAdded,\n\t\tValue:   0,\n\t\tUsage:   FlagFilterDaysSinceAddedUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_FILTER_DAYS_SINCE\"},\n\t},\n\tFlagFilterScoreGt: &cli.Float64Flag{\n\t\tName:    FlagFilterScoreGt,\n\t\tValue:   0,\n\t\tUsage:   FlagFilterScoreGtUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_FILTER_SCORE_GT\"},\n\t},\n\tFlagFilterScoreLt: &cli.Float64Flag{\n\t\tName:    FlagFilterScoreLt,\n\t\tValue:   0,\n\t\tUsage:   FlagFilterScoreLtUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_FILTER_SCORE_LT\"},\n\t},\n\tFlagFilterPercentileGt: &cli.Float64Flag{\n\t\tName:    FlagFilterPercentileGt,\n\t\tValue:   0,\n\t\tUsage:   FlagFilterPercentileGtUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_FILTER_PERC_GT\"},\n\t},\n\tFlagFilterPercentileLt: &cli.Float64Flag{\n\t\tName:    FlagFilterPercentileLt,\n\t\tValue:   0,\n\t\tUsage:   FlagFilterPercentileLtUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_FILTER_PERC_LT\"},\n\t},\n\tFlagFilterOrderRecords: &cli.StringFlag{\n\t\tName:    FlagFilterOrderRecords,\n\t\tValue:   \"\",\n\t\tUsage:   FlagFilterOrderRecordsUsage,\n\t\tEnvVars: []string{\"DSLIM_VULN_EPSS_FILTER_ORDER\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/vulnerability/handler_tool_epss.go",
    "content": "package vulnerability\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/jedib0t/go-pretty/v6/table\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t//\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t//\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/jsonutil\"\n\t//v \"github.com/slimtoolkit/slim/pkg/version\"\n\t\"github.com/slimtoolkit/slim/pkg/vulnerability/epss\"\n\t\"github.com/slimtoolkit/slim/pkg/vulnerability/epss/client\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// OnEpssCommand implements the 'vulnerability epss' command\nfunc OnEpssCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *EpssCommandParams) {\n\tcmdName := fullCmdName(EpssCmdName)\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": appName,\n\t\t\"cmd\": cmdName,\n\t\t\"sub\": EpssCmdName})\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewVulnerabilityCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\tcmdReport.Operation = cparams.Op\n\n\txc.Out.State(cmd.StateStarted)\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"cmd.params\": jsonutil.ToString(cparams),\n\t\t})\n\n\t/*\n\t\tclient, err := dockerclient.New(gparams.ClientConfig)\n\t\tif err == dockerclient.ErrNoDockerInfo {\n\t\t\texitMsg := \"missing Docker connection info\"\n\t\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the docker-slim container\"\n\t\t\t}\n\n\t\t\txc.Out.Info(\"docker.connect.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": exitMsg,\n\t\t\t\t})\n\n\t\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t\t})\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t\txc.FailOn(err)\n\t*/\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, nil /*client*/, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\tepssClient := client.New(client.Options{Debug: gparams.Debug})\n\tswitch cparams.Op {\n\tcase EpssOpList:\n\t\tcallOptions := client.FilteredCallOptions{\n\t\t\tCallOptions: client.CallOptions{\n\t\t\t\tDate:     cparams.Date,\n\t\t\t\tPageSize: cparams.Limit,\n\t\t\t\tOffset:   cparams.Offset,\n\t\t\t},\n\t\t\tCveIDPattern:   cparams.FilterCveIDPattern,\n\t\t\tScoreGt:        cparams.FilterScoreGt,\n\t\t\tScoreLt:        cparams.FilterScoreLt,\n\t\t\tPercentileGt:   cparams.FilterPercentileGt,\n\t\t\tPercentileLt:   cparams.FilterPercentileLt,\n\t\t\tDaysSinceAdded: cparams.FilterDaysSinceAdded,\n\t\t\tOrderRecords:   cparams.FilterOrderRecords,\n\t\t}\n\n\t\t//note: not fetching all pages/records (should have a special flag for it)\n\t\tif cparams.WithHistory {\n\t\t\tscores, _, err := epssClient.ListScoresWithHistory(\n\t\t\t\tcontext.Background(),\n\t\t\t\tcallOptions,\n\t\t\t)\n\n\t\t\txc.FailOn(err)\n\t\t\tshowScoresWithHistory(xc, scores)\n\t\t} else {\n\t\t\tscores, _, err := epssClient.ListScores(\n\t\t\t\tcontext.Background(),\n\t\t\t\tcallOptions,\n\t\t\t)\n\n\t\t\txc.FailOn(err)\n\t\t\tshowScores(xc, scores)\n\t\t}\n\tdefault:\n\t\tcallOptions := client.CallOptions{\n\t\t\tDate: cparams.Date,\n\t\t}\n\n\t\tif cparams.WithHistory {\n\t\t\tscores, _, err := epssClient.LookupScoresWithHistory(\n\t\t\t\tcontext.Background(),\n\t\t\t\tcparams.CVEList,\n\t\t\t\tcallOptions)\n\n\t\t\txc.FailOn(err)\n\t\t\tshowScoresWithHistory(xc, scores)\n\t\t} else {\n\t\t\tscores, _, err := epssClient.LookupScores(\n\t\t\t\tcontext.Background(),\n\t\t\t\tcparams.CVEList,\n\t\t\t\tcallOptions)\n\n\t\t\txc.FailOn(err)\n\t\t\tshowScores(xc, scores)\n\t\t}\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\txc.Out.State(cmd.StateDone)\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n}\n\nfunc showScores(xc *app.ExecutionContext, scores []*epss.Score) {\n\tif xc.Out.Quiet {\n\t\tif xc.Out.OutputFormat == command.OutputFormatJSON {\n\t\t\tfmt.Printf(\"%s\\n\", jsonutil.ToPretty(scores))\n\t\t\treturn\n\t\t}\n\n\t\tprintScoresTable(scores)\n\t\treturn\n\t}\n\n\txc.Out.Info(\"epss.scores.summary\", ovars{\"count\": len(scores)})\n\tfor idx, score := range scores {\n\t\tfields := baseScoreFields(score)\n\t\tfields[\"index\"] = idx\n\t\txc.Out.Info(\"epss.score\", fields)\n\t}\n}\n\nfunc printScoresTable(scores []*epss.Score) {\n\ttw := table.NewWriter()\n\ttw.AppendHeader(table.Row{\"CVE ID\", \"Value\", \"Percentile\", \"Date\"})\n\n\tfor _, score := range scores {\n\t\ttw.AppendRow(table.Row{\n\t\t\tscore.CVE,\n\t\t\tscore.EPSS,\n\t\t\tscore.Percentile,\n\t\t\tscore.Date.Format(time.DateOnly),\n\t\t})\n\t}\n\n\ttw.SetStyle(table.StyleLight)\n\ttw.Style().Options.DrawBorder = false\n\tfmt.Printf(\"%s\\n\", tw.Render())\n}\n\nfunc printScoresWithHistoryTable(scores []*epss.ScoreWithHistory) {\n\ttw := table.NewWriter()\n\ttw.AppendHeader(table.Row{\"CVE ID\", \"Value\", \"Percentile\", \"Date\", \"History\"})\n\n\tfor _, score := range scores {\n\t\thtw := table.NewWriter()\n\t\thtw.AppendHeader(table.Row{\"Value\", \"Percentile\", \"Date\"})\n\t\tfor _, data := range score.History {\n\t\t\thtw.AppendRow(table.Row{\n\t\t\t\tdata.EPSS,\n\t\t\t\tdata.Percentile,\n\t\t\t\tdata.Date.Format(time.DateOnly),\n\t\t\t})\n\t\t}\n\n\t\thtw.SetStyle(table.StyleLight)\n\t\thtw.Style().Options.DrawBorder = false\n\t\ttw.AppendRow(table.Row{\n\t\t\tscore.CVE,\n\t\t\tscore.EPSS,\n\t\t\tscore.Percentile,\n\t\t\tscore.Date.Format(time.DateOnly),\n\t\t\thtw.Render(),\n\t\t})\n\t}\n\n\ttw.SetStyle(table.StyleLight)\n\ttw.Style().Options.DrawBorder = false\n\tfmt.Printf(\"%s\\n\", tw.Render())\n}\n\nfunc showScoresWithHistory(xc *app.ExecutionContext, scores []*epss.ScoreWithHistory) {\n\tif xc.Out.Quiet {\n\t\tif xc.Out.OutputFormat == command.OutputFormatJSON {\n\t\t\tfmt.Printf(\"%s\\n\", jsonutil.ToPretty(scores))\n\t\t\treturn\n\t\t}\n\n\t\tprintScoresWithHistoryTable(scores)\n\t\treturn\n\t}\n\n\txc.Out.Info(\"epss.scores.summary\", ovars{\"count\": len(scores)})\n\tfor idx, score := range scores {\n\t\tfields := baseScoreFields(&score.Score)\n\t\tfields[\"index\"] = idx\n\t\tfor k, v := range scoreHistoryFields(score.History) {\n\t\t\tfields[k] = v\n\t\t}\n\n\t\txc.Out.Info(\"epss.score\", fields)\n\t}\n}\n\nfunc baseScoreFields(score *epss.Score) app.OutVars {\n\treturn app.OutVars{\n\t\t\"cve\":        score.CVE,\n\t\t\"value\":      score.EPSS,\n\t\t\"percentile\": score.Percentile,\n\t\t\"date\":       score.Date.Format(time.DateOnly),\n\t}\n}\n\nfunc scoreHistoryFields(scoreHistory []epss.ScoreData) app.OutVars {\n\tfields := app.OutVars{}\n\tfor idx, data := range scoreHistory {\n\t\tfields[fmt.Sprintf(\"history.%d\", idx)] =\n\t\t\tfmt.Sprintf(\"%s/%f/%f\",\n\t\t\t\tdata.Date.Format(time.DateOnly),\n\t\t\t\tdata.EPSS,\n\t\t\t\tdata.Percentile)\n\t}\n\n\treturn fields\n}\n"
  },
  {
    "path": "pkg/app/master/command/vulnerability/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/vulnerability\"\n)\n\nfunc init() {\n\tvulnerability.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/vulnerability/prompt.go",
    "content": "package vulnerability\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(FlagCVE), Description: FlagCVEUsage},\n\t\t//including sub-commands here too\n\t\t{Text: EpssCmdName, Description: EpssCmdNameUsage},\n\t},\n\tValues: map[string]command.CompleteValue{},\n}\n"
  },
  {
    "path": "pkg/app/master/command/vulnerability/register.go",
    "content": "package vulnerability\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/command/xray/cli.go",
    "content": "package xray\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/urfave/cli/v2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerimage\"\n)\n\nconst (\n\tName  = \"xray\"\n\tUsage = \"Shows what's inside of your container image and reverse engineers its Dockerfile\"\n\tAlias = \"x\"\n)\n\ntype DetectOpParam struct {\n\t/// Operation is enabled\n\tEnabled bool\n\t/// Dump/save raw data\n\tDumpRaw bool\n\t/// Dump raw data to console\n\tIsConsoleOut bool\n\t/// Dump raw data to directory (otherwise save to an archive file)\n\tIsDirOut bool\n\t/// Output path (directory or archive path)\n\tOutputPath string\n\t/// Input parameters for the operation\n\tInputParams map[string]string\n}\n\ntype CommandParams struct {\n\tDetectIdentities     *DetectOpParam `json:\"detect_identities,omitempty\"`\n\tDetectScheduledTasks *DetectOpParam `json:\"detect_scheduled_tasks,omitempty\"`\n\tDetectServices       *DetectOpParam `json:\"detect_services,omitempty\"`\n\tDetectSystemHooks    *DetectOpParam `json:\"detect_system_hooks,omitempty\"`\n\n\t//todo: migrate simple bool param to DetectOpParam\n\tDetectAllCertFiles   bool `json:\"detect_all_cert_files,omitempty\"`\n\tDetectAllCertPKFiles bool `json:\"detect_all_cert_pks,omitempty\"`\n}\n\nvar CLI = &cli.Command{\n\tName:    Name,\n\tAliases: []string{Alias},\n\tUsage:   Usage,\n\tFlags: []cli.Flag{\n\t\tcommand.Cflag(command.FlagCommandParamsFile),\n\t\tcommand.Cflag(command.FlagTarget),\n\t\tcommand.Cflag(command.FlagPull),\n\t\tcommand.Cflag(command.FlagDockerConfigPath),\n\t\tcommand.Cflag(command.FlagRegistryAccount),\n\t\tcommand.Cflag(command.FlagRegistrySecret),\n\t\tcommand.Cflag(command.FlagShowPullLogs),\n\t\tcflag(FlagChanges),\n\t\tcflag(FlagChangesOutput),\n\t\tcflag(FlagLayer),\n\t\tcflag(FlagAddImageManifest),\n\t\tcflag(FlagAddImageConfig),\n\t\tcflag(FlagLayerChangesMax),\n\t\tcflag(FlagAllChangesMax),\n\t\tcflag(FlagAddChangesMax),\n\t\tcflag(FlagModifyChangesMax),\n\t\tcflag(FlagDeleteChangesMax),\n\t\tcflag(FlagChangePath),\n\t\tcflag(FlagChangeData),\n\t\tcflag(FlagReuseSavedImage),\n\t\tcflag(FlagTopChangesMax),\n\t\tcflag(FlagChangeMatchLayersOnly),\n\t\tcflag(FlagHashData),\n\t\tcflag(FlagDetectUTF8),\n\t\tcflag(FlagDetectAllCertFiles),\n\t\tcflag(FlagDetectAllCertPKFiles),\n\t\tcflag(FlagDetectDuplicates),\n\t\tcflag(FlagShowDuplicates),\n\t\tcflag(FlagShowSpecialPerms),\n\t\tcflag(FlagChangeDataHash),\n\t\tcflag(FlagExportAllDataArtifacts),\n\t\tcflag(FlagDetectIdentities),\n\t\tcflag(FlagDetectIdentitiesParam),\n\t\tcflag(FlagDetectIdentitiesDumpRaw),\n\t\tcflag(FlagDetectScheduledTasks),\n\t\tcflag(FlagDetectScheduledTasksParam),\n\t\tcflag(FlagDetectScheduledTasksDumpRaw),\n\t\tcflag(FlagDetectServices),\n\t\tcflag(FlagDetectServicesParam),\n\t\tcflag(FlagDetectServicesDumpRaw),\n\t\tcflag(FlagDetectSystemHooks),\n\t\tcflag(FlagDetectSystemHooksParam),\n\t\tcflag(FlagDetectSystemHooksDumpRaw),\n\t\tcommand.Cflag(command.FlagRemoveFileArtifacts),\n\t},\n\tAction: func(ctx *cli.Context) error {\n\t\tgcvalues, ok := command.CLIContextGet(ctx.Context, command.GlobalParams).(*command.GenericParams)\n\t\tif !ok || gcvalues == nil {\n\t\t\treturn command.ErrNoGlobalParams\n\t\t}\n\n\t\txc := app.NewExecutionContext(\n\t\t\tName,\n\t\t\tgcvalues.QuietCLIMode,\n\t\t\tgcvalues.OutputFormat)\n\n\t\t//NOTE: this is a placeholder to load all command params from a file\n\t\t_ = ctx.String(command.FlagCommandParamsFile)\n\n\t\ttargetRef := ctx.String(command.FlagTarget)\n\t\tif targetRef == \"\" {\n\t\t\tif ctx.Args().Len() < 1 {\n\t\t\t\txc.Out.Error(\"param.target\", \"missing image ID/name\")\n\t\t\t\tcli.ShowCommandHelp(ctx, Name)\n\t\t\t\treturn nil\n\t\t\t} else {\n\t\t\t\ttargetRef = ctx.Args().First()\n\t\t\t}\n\t\t}\n\n\t\tdetectIdentities, err := getDetectOpParam(ctx,\n\t\t\tFlagDetectIdentities,\n\t\t\tFlagDetectIdentitiesParam,\n\t\t\tFlagDetectIdentitiesDumpRaw,\n\t\t\tdetectIdentitiesDumpRawDefault,\n\t\t\tdetectIdentitiesOpParamKeys)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.detect_identities\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdetectScheduledTasks, err := getDetectOpParam(ctx,\n\t\t\tFlagDetectScheduledTasks,\n\t\t\tFlagDetectScheduledTasksParam,\n\t\t\tFlagDetectScheduledTasksDumpRaw,\n\t\t\tdetectScheduledTasksDumpRawDefault,\n\t\t\tdetectScheduledTasksOpParamKeys)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.detect_scheduled_tasks\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdetectServices, err := getDetectOpParam(ctx,\n\t\t\tFlagDetectServices,\n\t\t\tFlagDetectServicesParam,\n\t\t\tFlagDetectServicesDumpRaw,\n\t\t\tdetectServicesDumpRawDefault,\n\t\t\tdetectServicesOpParamKeys)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.detect_services\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdetectSystemHooks, err := getDetectOpParam(ctx,\n\t\t\tFlagDetectSystemHooks,\n\t\t\tFlagDetectSystemHooksParam,\n\t\t\tFlagDetectSystemHooksDumpRaw,\n\t\t\tdetectSystemHooksDumpRawDefault,\n\t\t\tdetectSystemHooksOpParamKeys)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.detect_system_hooks\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\t//todo:\n\t\t//1. migrate all param fields to CommandParams\n\t\t//2. load command params from file if command.FlagCommandParamsFile is provided\n\t\tcparams := &CommandParams{\n\t\t\tDetectAllCertFiles:   ctx.Bool(FlagDetectAllCertFiles),\n\t\t\tDetectAllCertPKFiles: ctx.Bool(FlagDetectAllCertPKFiles),\n\t\t\tDetectIdentities:     detectIdentities,\n\t\t\tDetectScheduledTasks: detectScheduledTasks,\n\t\t\tDetectServices:       detectServices,\n\t\t\tDetectSystemHooks:    detectSystemHooks,\n\t\t}\n\n\t\txdArtifactsPath := ctx.String(FlagExportAllDataArtifacts)\n\n\t\tdoPull := ctx.Bool(command.FlagPull)\n\t\tdockerConfigPath := ctx.String(command.FlagDockerConfigPath)\n\t\tregistryAccount := ctx.String(command.FlagRegistryAccount)\n\t\tregistrySecret := ctx.String(command.FlagRegistrySecret)\n\t\tdoShowPullLogs := ctx.Bool(command.FlagShowPullLogs)\n\n\t\tchanges, err := parseChangeTypes(ctx.StringSlice(FlagChanges))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.change.types\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tif xdArtifactsPath != \"\" {\n\t\t\t//need 'changes all' when exporting all data artifacts\n\t\t\tchanges[\"delete\"] = struct{}{}\n\t\t\tchanges[\"modify\"] = struct{}{}\n\t\t\tchanges[\"add\"] = struct{}{}\n\t\t}\n\n\t\trawChangesOutputs := ctx.StringSlice(FlagChangesOutput)\n\t\tif xdArtifactsPath != \"\" && len(rawChangesOutputs) == 0 {\n\t\t\trawChangesOutputs = append(rawChangesOutputs, \"report\")\n\t\t}\n\n\t\tchangesOutputs, err := parseChangeOutputTypes(rawChangesOutputs)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.change.output\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tif xdArtifactsPath != \"\" {\n\t\t\tchangesOutputs[\"report\"] = struct{}{}\n\t\t}\n\n\t\tlayers, err := command.ParseTokenSet(ctx.StringSlice(FlagLayer))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.layer\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tlayerChangesMax := ctx.Int(FlagLayerChangesMax)\n\t\tallChangesMax := ctx.Int(FlagAllChangesMax)\n\t\taddChangesMax := ctx.Int(FlagAddChangesMax)\n\t\tmodifyChangesMax := ctx.Int(FlagModifyChangesMax)\n\t\tdeleteChangesMax := ctx.Int(FlagDeleteChangesMax)\n\t\ttopChangesMax := ctx.Int(FlagTopChangesMax)\n\n\t\tchangePathMatchers, err := parseChangePathMatchers(ctx.StringSlice(FlagChangePath))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.change.path\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tchangeDataMatchers, err := parseChangeDataMatchers(ctx.StringSlice(FlagChangeData))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.change.data\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdoAddImageManifest := ctx.Bool(FlagAddImageManifest)\n\t\tif xdArtifactsPath != \"\" {\n\t\t\tdoAddImageManifest = true\n\t\t}\n\n\t\tdoAddImageConfig := ctx.Bool(FlagAddImageConfig)\n\t\tif xdArtifactsPath != \"\" {\n\t\t\tdoAddImageConfig = true\n\t\t}\n\n\t\tdoRmFileArtifacts := ctx.Bool(command.FlagRemoveFileArtifacts)\n\t\tdoReuseSavedImage := ctx.Bool(FlagReuseSavedImage)\n\n\t\tdoHashData := ctx.Bool(FlagHashData)\n\t\tif xdArtifactsPath != \"\" {\n\t\t\tdoHashData = true\n\t\t}\n\n\t\tdoDetectDuplicates := ctx.Bool(FlagDetectDuplicates)\n\t\tif doDetectDuplicates {\n\t\t\tdoHashData = true\n\t\t}\n\n\t\trawDetectUTF8 := ctx.String(FlagDetectUTF8)\n\t\tif xdArtifactsPath != \"\" && rawDetectUTF8 == \"\" {\n\t\t\trawDetectUTF8 = \"dump:utf8.tgz::10000000\"\n\t\t}\n\n\t\tutf8Detector, err := parseDetectUTF8(rawDetectUTF8)\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.detect.utf8\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tif utf8Detector != nil && !doHashData {\n\t\t\txc.Out.Error(\"param.error.detect.utf8\", \"--detect-utf8 requires option --hash-data\")\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tdoShowDuplicates := ctx.Bool(FlagShowDuplicates)\n\t\tdoShowSpecialPerms := ctx.Bool(FlagShowSpecialPerms)\n\n\t\tchangeDataHashMatchers, err := parseChangeDataHashMatchers(ctx.StringSlice(FlagChangeDataHash))\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"param.error.change.data.hash\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tchangeMatchLayersOnly := ctx.Bool(FlagChangeMatchLayersOnly)\n\n\t\tOnCommand(\n\t\t\txc,\n\t\t\tgcvalues,\n\t\t\tcparams,\n\t\t\ttargetRef,\n\t\t\tdoPull,\n\t\t\tdockerConfigPath,\n\t\t\tregistryAccount,\n\t\t\tregistrySecret,\n\t\t\tdoShowPullLogs,\n\t\t\tchanges,\n\t\t\tchangesOutputs,\n\t\t\tlayers,\n\t\t\tlayerChangesMax,\n\t\t\tallChangesMax,\n\t\t\taddChangesMax,\n\t\t\tmodifyChangesMax,\n\t\t\tdeleteChangesMax,\n\t\t\ttopChangesMax,\n\t\t\tchangePathMatchers,\n\t\t\tchangeDataMatchers,\n\t\t\tchangeDataHashMatchers,\n\t\t\tdoHashData,\n\t\t\tdoDetectDuplicates,\n\t\t\tdoShowDuplicates,\n\t\t\tdoShowSpecialPerms,\n\t\t\tchangeMatchLayersOnly,\n\t\t\tdoAddImageManifest,\n\t\t\tdoAddImageConfig,\n\t\t\tdoReuseSavedImage,\n\t\t\tdoRmFileArtifacts,\n\t\t\tutf8Detector,\n\t\t\txdArtifactsPath,\n\t\t)\n\n\t\treturn nil\n\t},\n}\n\nfunc parseChangeTypes(values []string) (map[string]struct{}, error) {\n\tchanges := map[string]struct{}{}\n\tif len(values) == 0 {\n\t\tvalues = append(values, \"all\")\n\t}\n\n\tfor _, item := range values {\n\t\tswitch item {\n\t\tcase \"none\":\n\t\t\treturn nil, nil\n\t\tcase \"all\":\n\t\t\tchanges[\"delete\"] = struct{}{}\n\t\t\tchanges[\"modify\"] = struct{}{}\n\t\t\tchanges[\"add\"] = struct{}{}\n\t\tcase \"delete\":\n\t\t\tchanges[\"delete\"] = struct{}{}\n\t\tcase \"modify\":\n\t\t\tchanges[\"modify\"] = struct{}{}\n\t\tcase \"add\":\n\t\t\tchanges[\"add\"] = struct{}{}\n\t\t}\n\t}\n\n\treturn changes, nil\n}\n\nfunc parseChangeOutputTypes(values []string) (map[string]struct{}, error) {\n\toutputs := map[string]struct{}{}\n\tif len(values) == 0 {\n\t\tvalues = append(values, \"all\")\n\t}\n\n\tfor _, item := range values {\n\t\tswitch item {\n\t\tcase \"all\":\n\t\t\toutputs[\"report\"] = struct{}{}\n\t\t\toutputs[\"console\"] = struct{}{}\n\t\tcase \"report\":\n\t\t\toutputs[\"report\"] = struct{}{}\n\t\tcase \"console\":\n\t\t\toutputs[\"console\"] = struct{}{}\n\t\t}\n\t}\n\n\treturn outputs, nil\n}\n\nfunc parseChangeDataMatchers(values []string) ([]*dockerimage.ChangeDataMatcher, error) {\n\tvar matchers []*dockerimage.ChangeDataMatcher\n\n\tfor _, raw := range values {\n\t\tvar m dockerimage.ChangeDataMatcher\n\n\t\tif strings.HasPrefix(raw, \"dump:\") {\n\t\t\tparts := strings.SplitN(raw, \":\", 4)\n\t\t\tif len(parts) != 4 {\n\t\t\t\treturn nil, fmt.Errorf(\"malformed change data matcher: %s\", raw)\n\t\t\t}\n\n\t\t\tm.Dump = true\n\n\t\t\toutTarget := strings.TrimSpace(parts[1])\n\t\t\tif len(outTarget) == 0 || outTarget == dockerimage.CDMDumpToConsole {\n\t\t\t\tm.DumpConsole = true\n\t\t\t} else {\n\t\t\t\tm.DumpDir = outTarget\n\t\t\t}\n\n\t\t\tm.PathPattern = parts[2]\n\t\t\tm.DataPattern = parts[3]\n\n\t\t\t//\"dump:output:path_ptrn:data_regex\"\n\t\t\t//\"::path_ptrn:data_regex\"\n\t\t\t//\":::data_regex\"\n\t\t\t//\"data_regex\"\n\t\t} else {\n\t\t\tif !strings.HasPrefix(raw, \":\") {\n\t\t\t\tm.DataPattern = raw\n\t\t\t} else {\n\t\t\t\tparts := strings.SplitN(raw, \":\", 4)\n\t\t\t\tif len(parts) != 4 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"malformed change data matcher: %s\", raw)\n\t\t\t\t}\n\n\t\t\t\tm.PathPattern = parts[2]\n\t\t\t\tm.DataPattern = parts[3]\n\t\t\t}\n\t\t}\n\n\t\tmatchers = append(matchers, &m)\n\t}\n\n\treturn matchers, nil\n}\n\nfunc parseChangePathMatchers(values []string) ([]*dockerimage.ChangePathMatcher, error) {\n\tvar matchers []*dockerimage.ChangePathMatcher\n\n\tfor _, raw := range values {\n\t\tvar m dockerimage.ChangePathMatcher\n\n\t\tif strings.HasPrefix(raw, \"dump:\") {\n\t\t\tparts := strings.SplitN(raw, \":\", 3)\n\t\t\tif len(parts) != 3 {\n\t\t\t\treturn nil, fmt.Errorf(\"malformed change path matcher: %s\", raw)\n\t\t\t}\n\n\t\t\tm.Dump = true\n\n\t\t\toutTarget := strings.TrimSpace(parts[1])\n\t\t\tif len(outTarget) == 0 || outTarget == dockerimage.CDMDumpToConsole {\n\t\t\t\tm.DumpConsole = true\n\t\t\t} else {\n\t\t\t\tm.DumpDir = outTarget\n\t\t\t}\n\n\t\t\tm.PathPattern = parts[2]\n\n\t\t\t//\"dump:output:path_ptrn\"\n\t\t\t//\"::path_ptrn\"\n\t\t\t//\"path_ptrn\"\n\t\t} else {\n\t\t\tif !strings.HasPrefix(raw, \":\") {\n\t\t\t\tm.PathPattern = raw\n\t\t\t} else {\n\t\t\t\tparts := strings.SplitN(raw, \":\", 3)\n\t\t\t\tif len(parts) != 3 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"malformed change path matcher: %s\", raw)\n\t\t\t\t}\n\n\t\t\t\tm.PathPattern = parts[2]\n\t\t\t}\n\t\t}\n\n\t\tmatchers = append(matchers, &m)\n\t}\n\n\treturn matchers, nil\n}\n\nfunc parseChangeDataHashMatchers(values []string) ([]*dockerimage.ChangeDataHashMatcher, error) {\n\tvar matchers []*dockerimage.ChangeDataHashMatcher\n\n\tfor _, raw := range values {\n\t\tvar m dockerimage.ChangeDataHashMatcher\n\n\t\tif strings.HasPrefix(raw, \"dump:\") {\n\t\t\tparts := strings.SplitN(raw, \":\", 3)\n\t\t\tif len(parts) != 3 {\n\t\t\t\treturn nil, fmt.Errorf(\"malformed change data hash matcher: %s\", raw)\n\t\t\t}\n\n\t\t\tm.Dump = true\n\n\t\t\toutTarget := strings.TrimSpace(parts[1])\n\t\t\tif len(outTarget) == 0 || outTarget == dockerimage.CDMDumpToConsole {\n\t\t\t\tm.DumpConsole = true\n\t\t\t} else {\n\t\t\t\tm.DumpDir = outTarget\n\t\t\t}\n\n\t\t\tm.Hash = strings.ToLower(strings.TrimSpace(parts[2]))\n\n\t\t\t//\"dump:output:hash\"\n\t\t\t//\"::hash\"\n\t\t\t//\"hash\"\n\t\t} else {\n\t\t\tif !strings.HasPrefix(raw, \":\") {\n\t\t\t\tm.Hash = strings.ToLower(strings.TrimSpace(raw))\n\t\t\t} else {\n\t\t\t\tparts := strings.SplitN(raw, \":\", 3)\n\t\t\t\tif len(parts) != 3 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"malformed change data hash matcher: %s\", raw)\n\t\t\t\t}\n\n\t\t\t\tm.Hash = strings.ToLower(strings.TrimSpace(parts[2]))\n\t\t\t}\n\t\t}\n\n\t\tmatchers = append(matchers, &m)\n\t}\n\n\treturn matchers, nil\n}\n\nfunc parseDetectUTF8(raw string) (*dockerimage.UTF8Detector, error) {\n\tif raw == \"\" {\n\t\treturn nil, nil\n\t}\n\n\tvar detector dockerimage.UTF8Detector\n\tif raw == \"dump\" {\n\t\tdetector.Dump = true\n\t\tdetector.DumpConsole = true\n\t} else if strings.HasPrefix(raw, \"dump:\") {\n\t\tparts := strings.SplitN(raw, \":\", 2)\n\t\tif len(parts) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"malformed find utf8: %s\", raw)\n\t\t}\n\n\t\tdetector.Dump = true\n\n\t\toutTarget := strings.TrimSpace(parts[1])\n\t\tif len(outTarget) == 0 || outTarget == dockerimage.CDMDumpToConsole {\n\t\t\tdetector.DumpConsole = true\n\t\t} else {\n\t\t\tif strings.Count(outTarget, \":\") == 2 {\n\t\t\t\tparts = strings.SplitN(outTarget, \":\", 3)\n\t\t\t\tif len(parts) != 3 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"malformed find utf8: %s\", raw)\n\t\t\t\t}\n\t\t\t\toutTarget = parts[0]\n\t\t\t\t_ = parts[1] // TODO implemement path pattern matcher\n\t\t\t\tmaxSizeBytes := parts[2]\n\t\t\t\tvar err error\n\t\t\t\tdetector.MaxSizeBytes, err = strconv.Atoi(maxSizeBytes)\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 if strings.Count(outTarget, \":\") == 3 {\n\t\t\t\tparts = strings.SplitN(outTarget, \":\", 4)\n\t\t\t\tif len(parts) != 4 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"malformed find utf8: %s\", raw)\n\t\t\t\t}\n\t\t\t\toutTarget = parts[0]\n\t\t\t\t_ = parts[1] // TODO implemement path pattern matcher\n\t\t\t\t_ = parts[2] // TODO implemement data regex matcher\n\t\t\t\tmaxSizeBytes := parts[3]\n\t\t\t\tvar err error\n\t\t\t\tdetector.MaxSizeBytes, err = strconv.Atoi(maxSizeBytes)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}\n\t\t\tif strings.HasSuffix(outTarget, \".tgz\") ||\n\t\t\t\tstrings.HasSuffix(outTarget, \".tar.gz\") {\n\t\t\t\tdetector.DumpArchive = outTarget\n\n\t\t\t\tdar, err := dockerimage.NewTarWriter(outTarget)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t\tdetector.Archive = dar\n\t\t\t} else {\n\t\t\t\tdetector.DumpDir = outTarget\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif raw != \"true\" {\n\t\t\treturn nil, nil\n\t\t}\n\t}\n\n\t//TODO:\n\t//get detector filters if we need to find/extract only a subset of the utf8\n\n\treturn &detector, nil\n}\n\nfunc getDetectOpParam(\n\tctx *cli.Context,\n\tenableFlag string,\n\tkvListFlag string,\n\tdumpRawFlag string,\n\tdefaultDumpRawFile string,\n\tvalidOpParamKeys map[string]struct{}) (*DetectOpParam, error) {\n\tvar param DetectOpParam\n\n\tenable := ctx.Bool(enableFlag)\n\tkvList := ctx.StringSlice(kvListFlag)\n\tdumpRaw := ctx.String(dumpRawFlag)\n\n\tif enable == false && len(kvList) == 0 && dumpRaw == \"\" {\n\t\treturn &param, nil\n\t}\n\n\tparam.Enabled = true\n\tparam.InputParams = map[string]string{}\n\tfor _, raw := range kvList {\n\t\traw = strings.TrimSpace(raw)\n\t\tparts := strings.SplitN(raw, \"=\", 2)\n\t\tif len(parts) != 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif parts[0] == \"\" || parts[1] == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif _, found := validOpParamKeys[parts[0]]; !found {\n\t\t\tcontinue\n\t\t}\n\n\t\tparam.InputParams[parts[0]] = parts[1]\n\t}\n\n\tif dumpRaw != \"\" {\n\t\tparam.DumpRaw = true\n\t\tswitch dumpRaw {\n\t\tcase \".\":\n\t\t\tparam.OutputPath = defaultDumpRawFile\n\t\t\treturn &param, nil\n\t\tcase \"console\":\n\t\t\tparam.IsConsoleOut = true\n\t\t\treturn &param, nil\n\t\tcase \"no\":\n\t\t\treturn &param, nil\n\t\t}\n\n\t\tparts := strings.SplitN(dumpRaw, \":\", 2)\n\t\tif parts[1] == \"\" {\n\t\t\tparam.IsConsoleOut = true\n\t\t\treturn &param, nil\n\t\t}\n\n\t\tswitch parts[0] {\n\t\tcase \"dir\":\n\t\t\tparam.IsDirOut = true\n\t\tdefault: //\"file\"\n\t\t\tparam.OutputPath = parts[1]\n\t\t}\n\t}\n\n\treturn &param, nil\n}\n\nconst (\n\tdetectIdentitiesDumpRawDefault     = \"./raw-identities.tar\"\n\tdetectScheduledTasksDumpRawDefault = \"./raw-scheduled-tasks.tar\"\n\tdetectServicesDumpRawDefault       = \"./raw-services.tar\"\n\tdetectSystemHooksDumpRawDefault    = \"./raw-system-hooks.tar\"\n)\n\nvar (\n\tdetectIdentitiesOpParamKeys     = map[string]struct{}{} //no keys yet\n\tdetectScheduledTasksOpParamKeys = map[string]struct{}{} //no keys yet\n\tdetectServicesOpParamKeys       = map[string]struct{}{} //no keys yet\n\tdetectSystemHooksOpParamKeys    = map[string]struct{}{} //no keys yet\n)\n"
  },
  {
    "path": "pkg/app/master/command/xray/flags.go",
    "content": "package xray\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/urfave/cli/v2\"\n)\n\n// Xray command flag names\nconst (\n\tFlagChanges                = \"changes\"\n\tFlagChangesOutput          = \"changes-output\"\n\tFlagLayer                  = \"layer\"\n\tFlagAddImageManifest       = \"add-image-manifest\"\n\tFlagAddImageConfig         = \"add-image-config\"\n\tFlagLayerChangesMax        = \"layer-changes-max\"\n\tFlagAllChangesMax          = \"all-changes-max\"\n\tFlagAddChangesMax          = \"add-changes-max\"\n\tFlagModifyChangesMax       = \"modify-changes-max\"\n\tFlagDeleteChangesMax       = \"delete-changes-max\"\n\tFlagChangePath             = \"change-path\"\n\tFlagChangeData             = \"change-data\"\n\tFlagChangeDataHash         = \"change-data-hash\"\n\tFlagReuseSavedImage        = \"reuse-saved-image\"\n\tFlagTopChangesMax          = \"top-changes-max\"\n\tFlagHashData               = \"hash-data\"\n\tFlagDetectUTF8             = \"detect-utf8\"\n\tFlagDetectDuplicates       = \"detect-duplicates\"\n\tFlagShowDuplicates         = \"show-duplicates\"\n\tFlagShowSpecialPerms       = \"show-special-perms\"\n\tFlagChangeMatchLayersOnly  = \"change-match-layers-only\"\n\tFlagExportAllDataArtifacts = \"export-all-data-artifacts\"\n\tFlagDetectAllCertFiles     = \"detect-all-certs\"\n\tFlagDetectAllCertPKFiles   = \"detect-all-cert-pks\"\n\n\tFlagDetectIdentities        = \"detect-identities\"\n\tFlagDetectIdentitiesParam   = \"detect-identities-param\"\n\tFlagDetectIdentitiesDumpRaw = \"detect-identities-dump-raw\"\n\n\tFlagDetectScheduledTasks        = \"detect-scheduled-tasks\"\n\tFlagDetectScheduledTasksParam   = \"detect-scheduled-tasks-param\"\n\tFlagDetectScheduledTasksDumpRaw = \"detect-scheduled-tasks-dump-raw\"\n\n\tFlagDetectServices        = \"detect-services\"\n\tFlagDetectServicesParam   = \"detect-services-param\"\n\tFlagDetectServicesDumpRaw = \"detect-services-dump-raw\"\n\n\tFlagDetectSystemHooks        = \"detect-system-hooks\"\n\tFlagDetectSystemHooksParam   = \"detect-system-hooks-param\"\n\tFlagDetectSystemHooksDumpRaw = \"detect-system-hooks-dump-raw\"\n)\n\n// Xray command flag usage info\nconst (\n\tFlagChangesUsage                = \"Show layer change details for the selected change type (values: none, all, delete, modify, add)\"\n\tFlagChangesOutputUsage          = \"Where to show the changes (values: all, report, console)\"\n\tFlagLayerUsage                  = \"Show details for the selected layer (using layer index or ID)\"\n\tFlagAddImageManifestUsage       = \"Add raw image manifest to the command execution report file\"\n\tFlagAddImageConfigUsage         = \"Add raw image config object to the command execution report file\"\n\tFlagLayerChangesMaxUsage        = \"Maximum number of changes to show for each layer\"\n\tFlagAllChangesMaxUsage          = \"Maximum number of changes to show for all layers\"\n\tFlagAddChangesMaxUsage          = \"Maximum number of 'add' changes to show for all layers\"\n\tFlagModifyChangesMaxUsage       = \"Maximum number of 'modify' changes to show for all layers\"\n\tFlagDeleteChangesMaxUsage       = \"Maximum number of 'delete' changes to show for all layers\"\n\tFlagChangePathUsage             = \"Include changes for the files that match the path pattern (Glob/Match in Go and **)\"\n\tFlagChangeDataUsage             = \"Include changes for the files that match the data pattern (regex)\"\n\tFlagReuseSavedImageUsage        = \"Reuse saved container image\"\n\tFlagTopChangesMaxUsage          = \"Maximum number of top changes to track\"\n\tFlagChangeDataHashUsage         = \"Include changes for the files that match the provided data hashes (sha1)\"\n\tFlagHashDataUsage               = \"Generate file data hashes\"\n\tFlagDetectUTF8Usage             = \"Detect utf8 files and optionally extract the discovered utf8 file content\"\n\tFlagDetectDuplicatesUsage       = \"Detect duplicate files based on their hashes\"\n\tFlagShowDuplicatesUsage         = \"Show discovered duplicate file paths\"\n\tFlagShowSpecialPermsUsage       = \"Show files with special permissions (setuid,setgid,sticky)\"\n\tFlagChangeMatchLayersOnlyUsage  = \"Show only layers with change matches\"\n\tFlagExportAllDataArtifactsUsage = \"TAR archive file path to export all text data artifacts (if value is set to `.` then the archive file path defaults to `./data-artifacts.tar`)\"\n\tFlagDetectAllCertFilesUsage     = \"Detect all certificate files\"\n\tFlagDetectAllCertPKFilesUsage   = \"Detect all certificate private key files\"\n\n\tFlagDetectIdentitiesUsage        = \"Detect system identities (users, groups) and their properties\"\n\tFlagDetectIdentitiesParamUsage   = \"Input parameters for system identities detection\"\n\tFlagDetectIdentitiesDumpRawUsage = \"Raw data dump options for system identities detection (values: no, console, directory or a tar archive file path where setting value to `.` defaults tar file path to `./raw-identities.tar`\"\n\n\tFlagDetectScheduledTasksUsage        = \"Detect scheduled tasks and their properties\"\n\tFlagDetectScheduledTasksParamUsage   = \"Input parameters for scheduled tasks detection\"\n\tFlagDetectScheduledTasksDumpRawUsage = \"Raw data dump options for scheduled tasks detection (values: `no`, `console`, directory or a tar archive file path where setting value to `.` defaults tar file path to `./raw-scheduled-tasks.tar`\"\n\n\tFlagDetectServicesUsage        = \"Detect services and their properties\"\n\tFlagDetectServicesParamUsage   = \"Input parameters for services detection\"\n\tFlagDetectServicesDumpRawUsage = \"Raw data dump options for services detection (values: no, console, directory or a tar archive file path where setting value to `.` defaults tar file path to `./raw-services.tar`\"\n\n\tFlagDetectSystemHooksUsage        = \"Detect system hooks and their properties\"\n\tFlagDetectSystemHooksParamUsage   = \"Input parameters for system hooks detection\"\n\tFlagDetectSystemHooksDumpRawUsage = \"Raw data dump options for system hooks detection (values: no, console, directory or a tar archive file path where setting value to `.` defaults tar file path to `./raw-system-hooks.tar`\"\n)\n\nvar Flags = map[string]cli.Flag{\n\tFlagChanges: &cli.StringSliceFlag{\n\t\tName:    FlagChanges,\n\t\tValue:   cli.NewStringSlice(\"\"),\n\t\tUsage:   FlagChangesUsage,\n\t\tEnvVars: []string{\"DSLIM_CHANGES\"},\n\t},\n\tFlagChangesOutput: &cli.StringSliceFlag{\n\t\tName:    FlagChangesOutput,\n\t\tValue:   cli.NewStringSlice(\"all\"),\n\t\tUsage:   FlagChangesOutputUsage,\n\t\tEnvVars: []string{\"DSLIM_CHANGES_OUTPUT\"},\n\t},\n\tFlagLayer: &cli.StringSliceFlag{\n\t\tName:    FlagLayer,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagLayerUsage,\n\t\tEnvVars: []string{\"DSLIM_LAYER\"},\n\t},\n\tFlagAddImageManifest: &cli.BoolFlag{\n\t\tName:    FlagAddImageManifest,\n\t\tUsage:   FlagAddImageManifestUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_IMAGE_MANIFEST\"},\n\t},\n\tFlagAddImageConfig: &cli.BoolFlag{\n\t\tName:    FlagAddImageConfig,\n\t\tUsage:   FlagAddImageConfigUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_IMAGE_CONFIG\"},\n\t},\n\tFlagLayerChangesMax: &cli.IntFlag{\n\t\tName:    FlagLayerChangesMax,\n\t\tValue:   -1,\n\t\tUsage:   FlagLayerChangesMaxUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_LAYER_CHANGES_MAX\"},\n\t},\n\tFlagAllChangesMax: &cli.IntFlag{\n\t\tName:    FlagAllChangesMax,\n\t\tValue:   -1,\n\t\tUsage:   FlagAllChangesMaxUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_ALL_CHANGES_MAX\"},\n\t},\n\tFlagAddChangesMax: &cli.IntFlag{\n\t\tName:    FlagAddChangesMax,\n\t\tValue:   -1,\n\t\tUsage:   FlagAddChangesMaxUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_ADD_CHANGES_MAX\"},\n\t},\n\tFlagModifyChangesMax: &cli.IntFlag{\n\t\tName:    FlagModifyChangesMax,\n\t\tValue:   -1,\n\t\tUsage:   FlagModifyChangesMaxUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_MODIFY_CHANGES_MAX\"},\n\t},\n\tFlagDeleteChangesMax: &cli.IntFlag{\n\t\tName:    FlagDeleteChangesMax,\n\t\tValue:   -1,\n\t\tUsage:   FlagDeleteChangesMaxUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DELETE_CHANGES_MAX\"},\n\t},\n\tFlagChangePath: &cli.StringSliceFlag{\n\t\tName:    FlagChangePath,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagChangePathUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_CHANGE_PATH\"},\n\t},\n\tFlagChangeData: &cli.StringSliceFlag{\n\t\tName:    FlagChangeData,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagChangeDataUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_CHANGE_DATA\"},\n\t},\n\tFlagReuseSavedImage: &cli.BoolFlag{\n\t\tName:    FlagReuseSavedImage,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagReuseSavedImageUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_REUSE_SAVED\"},\n\t},\n\tFlagTopChangesMax: &cli.IntFlag{\n\t\tName:    FlagTopChangesMax,\n\t\tValue:   20,\n\t\tUsage:   FlagTopChangesMaxUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_TOP_CHANGES_MAX\"},\n\t},\n\tFlagHashData: &cli.BoolFlag{\n\t\tName:    FlagHashData,\n\t\tUsage:   FlagHashDataUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_HASH_DATA\"},\n\t},\n\tFlagDetectUTF8: &cli.StringFlag{\n\t\tName:    FlagDetectUTF8,\n\t\tUsage:   FlagDetectUTF8Usage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_UTF8\"},\n\t},\n\tFlagDetectDuplicates: &cli.BoolFlag{\n\t\tName:    FlagDetectDuplicates,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagDetectDuplicatesUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_DUP\"},\n\t},\n\tFlagShowDuplicates: &cli.BoolFlag{\n\t\tName:    FlagShowDuplicates,\n\t\tUsage:   FlagShowDuplicatesUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_SHOW_DUP\"},\n\t},\n\tFlagShowSpecialPerms: &cli.BoolFlag{\n\t\tName:    FlagShowSpecialPerms,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagShowSpecialPermsUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_SHOW_SPECIAL\"},\n\t},\n\tFlagChangeDataHash: &cli.StringSliceFlag{\n\t\tName:    FlagChangeDataHash,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagChangeDataHashUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_CHANGE_DATA_HASH\"},\n\t},\n\tFlagChangeMatchLayersOnly: &cli.BoolFlag{\n\t\tName:    FlagChangeMatchLayersOnly,\n\t\tUsage:   FlagChangeMatchLayersOnlyUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_CHANGE_MATCH_LAYERS_ONLY\"},\n\t},\n\tFlagExportAllDataArtifacts: &cli.StringFlag{\n\t\tName:    FlagExportAllDataArtifacts,\n\t\tUsage:   FlagExportAllDataArtifactsUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_EXPORT_ALL_DARTIFACTS\"},\n\t},\n\tFlagDetectAllCertFiles: &cli.BoolFlag{\n\t\tName:    FlagDetectAllCertFiles,\n\t\tUsage:   FlagDetectAllCertFilesUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_ALL_CERTS\"},\n\t},\n\tFlagDetectAllCertPKFiles: &cli.BoolFlag{\n\t\tName:    FlagDetectAllCertPKFiles,\n\t\tUsage:   FlagDetectAllCertPKFilesUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_ALL_CERT_PKS\"},\n\t},\n\n\tFlagDetectIdentities: &cli.BoolFlag{\n\t\tName:    FlagDetectIdentities,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagDetectIdentitiesUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_IDENTITIES\"},\n\t},\n\tFlagDetectIdentitiesParam: &cli.StringSliceFlag{\n\t\tName:    FlagDetectIdentitiesParam,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagDetectIdentitiesParamUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_IDENTITIES_PARAM\"},\n\t},\n\tFlagDetectIdentitiesDumpRaw: &cli.StringFlag{\n\t\tName:    FlagDetectIdentitiesDumpRaw,\n\t\tUsage:   FlagDetectIdentitiesDumpRawUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_IDENTITIES_DUMP_RAW\"},\n\t},\n\n\tFlagDetectScheduledTasks: &cli.BoolFlag{\n\t\tName:    FlagDetectScheduledTasks,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagDetectScheduledTasksUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SCHEDULED_TASKS\"},\n\t},\n\tFlagDetectScheduledTasksParam: &cli.StringSliceFlag{\n\t\tName:    FlagDetectScheduledTasksParam,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagDetectScheduledTasksParamUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SCHEDULED_TASKS_PARAM\"},\n\t},\n\tFlagDetectScheduledTasksDumpRaw: &cli.StringFlag{\n\t\tName:    FlagDetectScheduledTasksDumpRaw,\n\t\tUsage:   FlagDetectScheduledTasksDumpRawUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SCHEDULED_TASKS_DUMP_RAW\"},\n\t},\n\n\tFlagDetectServices: &cli.BoolFlag{\n\t\tName:    FlagDetectServices,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagDetectServicesUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SERVICES\"},\n\t},\n\tFlagDetectServicesParam: &cli.StringSliceFlag{\n\t\tName:    FlagDetectServicesParam,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagDetectServicesParamUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SERVICES_PARAM\"},\n\t},\n\tFlagDetectServicesDumpRaw: &cli.StringFlag{\n\t\tName:    FlagDetectServicesDumpRaw,\n\t\tUsage:   FlagDetectServicesDumpRawUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SERVICES_DUMP_RAW\"},\n\t},\n\n\tFlagDetectSystemHooks: &cli.BoolFlag{\n\t\tName:    FlagDetectSystemHooks,\n\t\tValue:   true, //enabled by default\n\t\tUsage:   FlagDetectSystemHooksUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SYSTEM_HOOKS\"},\n\t},\n\tFlagDetectSystemHooksParam: &cli.StringSliceFlag{\n\t\tName:    FlagDetectSystemHooksParam,\n\t\tValue:   cli.NewStringSlice(),\n\t\tUsage:   FlagDetectSystemHooksParamUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SYSTEM_HOOKS_PARAM\"},\n\t},\n\tFlagDetectSystemHooksDumpRaw: &cli.StringFlag{\n\t\tName:    FlagDetectSystemHooksDumpRaw,\n\t\tUsage:   FlagDetectSystemHooksDumpRawUsage,\n\t\tEnvVars: []string{\"DSLIM_XRAY_DETECT_SYSTEM_HOOKS_DUMP_RAW\"},\n\t},\n}\n\nfunc cflag(name string) cli.Flag {\n\tcf, ok := Flags[name]\n\tif !ok {\n\t\tlog.Fatalf(\"unknown flag='%s'\", name)\n\t}\n\n\treturn cf\n}\n"
  },
  {
    "path": "pkg/app/master/command/xray/handler.go",
    "content": "package xray\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n\n\t//\"github.com/bmatcuk/doublestar/v3\"\n\t\"github.com/dustin/go-humanize\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\tcmd \"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/buildpackinfo\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerimage\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst appName = command.AppName\n\ntype ovars = app.OutVars\n\n// Xray command exit codes\nconst (\n\tecxOther = iota + 1\n)\n\nconst (\n\tfatDockerfileName = \"Dockerfile.fat\"\n)\n\nconst (\n\t// image.ref.name and image.version are supposed to represent\n\t// the corresponding target image identity properties\n\t// but sometimes it's base image properties\n\t// (when the builder doesn't set its own values inheriting the base image tags)\n\n\tociLabelImageName = \"org.opencontainers.image.ref.name\"\n\n\tociLabelImageVersion = \"org.opencontainers.image.version\"\n\tlsLabelImageVersion  = \"org.label-schema.version\"\n\n\t// image build source info\n\tociLabelImageSource = \"org.opencontainers.image.source\"\n\tlsLabelImageSource  = \"org.label-schema.vcs-url\"\n\n\t//SCM repo revision info (could be commit hash, tag, branch)\n\tociLabelImageRevision = \"org.opencontainers.image.revision\"\n\tlsLabelImageRevision  = \"org.label-schema.vcs-ref\"\n\n\tociLabelImageURL = \"org.opencontainers.image.url\"\n\tlsLabelImageURL  = \"org.label-schema.url\"\n\n\tociLabelImageTitle = \"org.opencontainers.image.title\"\n\tlsLabelImageTitle  = \"org.label-schema.name\"\n\n\tociLabelImageDesc = \"org.opencontainers.image.description\"\n\tlsLabelImageDesc  = \"org.label-schema.description\"\n\n\tociLabelImageDocs = \"org.opencontainers.image.documentation\"\n\tlsLabelImageDocs  = \"org.label-schema.usage\"\n\n\tociLabelImageVendor = \"org.opencontainers.image.vendor\" //high level 'author' info\n\tlsLabelImageVendor  = \"org.label-schema.vendor\"\n\n\tociLabelImageAuthors      = \"org.opencontainers.image.authors\"\n\tociLabelBaseImageDigest   = \"org.opencontainers.image.base.digest\"\n\tociLabelBaseImageName     = \"org.opencontainers.image.base.name\"\n\tazureLabelBaseImageName   = \"image.base.ref.name\"\n\tazureLabelBaseImageDigest = \"image.base.digest\"\n\n\tlsLabelDockerCmd      = \"org.label-schema.docker.cmd\"\n\tlsLabelDockerCmdDevel = \"org.label-schema.docker.cmd.devel\"\n\tlsLabelDockerCmdTest  = \"org.label-schema.docker.cmd.test\"\n\tlsLabelDockerCmdDebug = \"org.label-schema.docker.debug\"\n\tlsLabelDockerCmdHelp  = \"org.label-schema.docker.cmd.help\"\n\tlsLabelDockerParams   = \"org.label-schema.docker.params\"\n)\n\n// OCI label info:\n// https://specs.opencontainers.org/image-spec/annotations/\n\n// OnCommand implements the 'xray' command\nfunc OnCommand(\n\txc *app.ExecutionContext,\n\tgparams *command.GenericParams,\n\tcparams *CommandParams,\n\ttargetRef string,\n\tdoPull bool,\n\tdockerConfigPath string,\n\tregistryAccount string,\n\tregistrySecret string,\n\tdoShowPullLogs bool,\n\tchanges map[string]struct{},\n\tchangesOutputs map[string]struct{},\n\tlayers map[string]struct{},\n\tlayerChangesMax int,\n\tallChangesMax int,\n\taddChangesMax int,\n\tmodifyChangesMax int,\n\tdeleteChangesMax int,\n\ttopChangesMax int,\n\tchangePathMatchers []*dockerimage.ChangePathMatcher,\n\tchangeDataMatcherList []*dockerimage.ChangeDataMatcher,\n\tchangeDataHashMatcherList []*dockerimage.ChangeDataHashMatcher,\n\tdoHashData bool,\n\tdoDetectDuplicates bool,\n\tdoShowDuplicates bool,\n\tdoShowSpecialPerms bool,\n\tchangeMatchLayersOnly bool,\n\tdoAddImageManifest bool,\n\tdoAddImageConfig bool,\n\tdoReuseSavedImage bool,\n\tdoRmFileArtifacts bool,\n\tutf8Detector *dockerimage.UTF8Detector,\n\txdArtifactsPath string,\n) {\n\tconst cmdName = Name\n\tlogger := log.WithFields(log.Fields{\"app\": appName, \"cmd\": cmdName})\n\n\tchangeDataMatchers := map[string]*dockerimage.ChangeDataMatcher{}\n\tfor _, cdm := range changeDataMatcherList {\n\t\tmatcher, err := regexp.Compile(cdm.DataPattern)\n\t\terrutil.FailOn(err)\n\n\t\tcdm.Matcher = matcher\n\t\tchangeDataMatchers[cdm.DataPattern] = cdm\n\t}\n\n\tchangeDataHashMatchers := map[string]*dockerimage.ChangeDataHashMatcher{}\n\tfor _, cdhm := range changeDataHashMatcherList {\n\t\tchangeDataHashMatchers[cdhm.Hash] = cdhm\n\t}\n\n\tviChan := version.CheckAsync(gparams.CheckVersion, gparams.InContainer, gparams.IsDSImage)\n\n\tcmdReport := report.NewXrayCommand(gparams.ReportLocation, gparams.InContainer)\n\tcmdReport.State = cmd.StateStarted\n\tcmdReport.TargetReference = targetRef\n\n\txc.Out.State(cmd.StateStarted)\n\txc.Out.Info(\"params\",\n\t\tovars{\n\t\t\t\"target\":             targetRef,\n\t\t\t\"add-image-manifest\": doAddImageManifest,\n\t\t\t\"add-image-config\":   doAddImageConfig,\n\t\t\t\"rm-file-artifacts\":  doRmFileArtifacts,\n\t\t})\n\n\tclient, err := dockerclient.New(gparams.ClientConfig)\n\tif err == dockerclient.ErrNoDockerInfo {\n\t\texitMsg := \"missing Docker connection info\"\n\t\tif gparams.InContainer && gparams.IsDSImage {\n\t\t\texitMsg = \"make sure to pass the Docker connect parameters to the docker-slim container\"\n\t\t}\n\n\t\txc.Out.Error(\"docker.connect.error\", exitMsg)\n\n\t\texitCode := command.ECTCommon | command.ECCNoDockerConnectInfo\n\t\txc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\"location\":  fsutil.ExeDir(),\n\t\t\t})\n\t\txc.Exit(exitCode)\n\t}\n\terrutil.FailOn(err)\n\n\tif gparams.Debug {\n\t\tversion.Print(xc, cmdName, logger, client, false, gparams.InContainer, gparams.IsDSImage)\n\t}\n\n\timageInspector, err := image.NewInspector(client, targetRef)\n\terrutil.FailOn(err)\n\n\tnoImage, err := imageInspector.NoImage()\n\terrutil.FailOn(err)\n\tif noImage {\n\t\tif doPull {\n\t\t\txc.Out.Info(\"target.image\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":  \"not.found\",\n\t\t\t\t\t\"image\":   targetRef,\n\t\t\t\t\t\"message\": \"trying to pull target image\",\n\t\t\t\t})\n\n\t\t\terr := imageInspector.Pull(doShowPullLogs, dockerConfigPath, registryAccount, registrySecret)\n\t\t\terrutil.FailOn(err)\n\t\t} else {\n\t\t\txc.Out.Error(\"image.not.found\", \"make sure the target image already exists locally (use --pull flag to auto-download it from registry)\")\n\n\t\t\texitCode := command.ECTCommon | command.ECCImageNotFound\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": exitCode,\n\t\t\t\t})\n\t\t\txc.Exit(exitCode)\n\t\t}\n\t}\n\n\t//refresh the target refs\n\ttargetRef = imageInspector.ImageRef\n\tcmdReport.TargetReference = imageInspector.ImageRef\n\n\txc.Out.State(\"image.api.inspection.start\")\n\n\tlogger.Info(\"inspecting 'fat' image metadata...\")\n\terr = imageInspector.Inspect()\n\terrutil.FailOn(err)\n\n\tlocalVolumePath, artifactLocation, statePath, stateKey := fsutil.PrepareImageStateDirs(gparams.StatePath, imageInspector.ImageInfo.ID)\n\timageInspector.ArtifactLocation = artifactLocation\n\tlogger.Debugf(\"localVolumePath=%v, artifactLocation=%v, statePath=%v, stateKey=%v\", localVolumePath, artifactLocation, statePath, stateKey)\n\n\txc.Out.Info(\"image\",\n\t\tovars{\n\t\t\t\"id\":           imageInspector.ImageInfo.ID,\n\t\t\t\"size.bytes\":   imageInspector.ImageInfo.VirtualSize,\n\t\t\t\"size.human\":   humanize.Bytes(uint64(imageInspector.ImageInfo.VirtualSize)),\n\t\t\t\"architecture\": imageInspector.ImageInfo.Architecture,\n\t\t})\n\n\tlogger.Info(\"processing 'fat' image info...\")\n\terr = imageInspector.ProcessCollectedData()\n\terrutil.FailOn(err)\n\n\tif imageInspector.DockerfileInfo != nil {\n\t\tif imageInspector.DockerfileInfo.ExeUser != \"\" {\n\t\t\txc.Out.Info(\"image.users\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exe\": imageInspector.DockerfileInfo.ExeUser,\n\t\t\t\t\t\"all\": strings.Join(imageInspector.DockerfileInfo.AllUsers, \",\"),\n\t\t\t\t})\n\t\t}\n\n\t\tif len(imageInspector.DockerfileInfo.ImageStack) > 0 {\n\t\t\tcmdReport.ImageStack = imageInspector.DockerfileInfo.ImageStack\n\n\t\t\tfor idx, imageInfo := range imageInspector.DockerfileInfo.ImageStack {\n\t\t\t\txc.Out.Info(\"image.stack\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"index\":        idx,\n\t\t\t\t\t\t\"name\":         imageInfo.FullName,\n\t\t\t\t\t\t\"id\":           imageInfo.ID,\n\t\t\t\t\t\t\"instructions\": len(imageInfo.Instructions),\n\t\t\t\t\t\t\"message\":      \"see report file for details\",\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tif len(imageInspector.DockerfileInfo.ExposedPorts) > 0 {\n\t\t\txc.Out.Info(\"image.exposed_ports\",\n\t\t\t\tovars{\n\t\t\t\t\t\"list\": strings.Join(imageInspector.DockerfileInfo.ExposedPorts, \",\"),\n\t\t\t\t})\n\t\t}\n\t}\n\n\timgIdentity := dockerutil.ImageToIdentity(imageInspector.ImageInfo)\n\tcmdReport.SourceImage = report.ImageMetadata{\n\t\tIdentity: report.ImageIdentity{\n\t\t\tID:          imgIdentity.ID,\n\t\t\tTags:        imgIdentity.ShortTags,\n\t\t\tNames:       imgIdentity.RepoTags,\n\t\t\tDigests:     imgIdentity.ShortDigests,\n\t\t\tFullDigests: imgIdentity.RepoDigests,\n\t\t},\n\t\tSize:          imageInspector.ImageInfo.VirtualSize,\n\t\tSizeHuman:     humanize.Bytes(uint64(imageInspector.ImageInfo.VirtualSize)),\n\t\tCreateTime:    imageInspector.ImageInfo.Created.UTC().Format(time.RFC3339),\n\t\tAuthor:        imageInspector.ImageInfo.Author,\n\t\tDockerVersion: imageInspector.ImageInfo.DockerVersion,\n\t\tArchitecture:  imageInspector.ImageInfo.Architecture,\n\t\tUser:          imageInspector.ImageInfo.Config.User,\n\t\tOS:            imageInspector.ImageInfo.OS,\n\t\tWorkDir:       imageInspector.ImageInfo.Config.WorkingDir,\n\t\tContainerEntry: report.ContainerEntryInfo{\n\t\t\tEntrypoint: imageInspector.ImageInfo.Config.Entrypoint,\n\t\t\tCmd:        imageInspector.ImageInfo.Config.Cmd,\n\t\t},\n\t\tInheritedInstructions: imageInspector.ImageInfo.Config.OnBuild,\n\t}\n\n\tcmdReport.SourceImage.EnvVars = imageInspector.ImageInfo.Config.Env\n\n\tfor k := range imageInspector.ImageInfo.Config.ExposedPorts {\n\t\tcmdReport.SourceImage.ExposedPorts = append(cmdReport.SourceImage.ExposedPorts, string(k))\n\t}\n\n\tfor k := range imageInspector.ImageInfo.Config.Volumes {\n\t\tcmdReport.SourceImage.Volumes = append(cmdReport.SourceImage.Volumes, k)\n\t}\n\n\tcmdReport.SourceImage.Labels = imageInspector.ImageInfo.Config.Labels\n\n\tmaintainers := map[string]struct{}{}\n\n\tif buildpackinfo.HasBuildbackLabels(imageInspector.ImageInfo.Config.Labels) {\n\t\tfor k, v := range imageInspector.ImageInfo.Config.Labels {\n\t\t\tif k == \"io.buildpacks.stack.maintainer\" {\n\t\t\t\tbuildpackMaintainer := v + \" (buildpack)\"\n\t\t\t\tmaintainers[buildpackMaintainer] = struct{}{}\n\t\t\t}\n\t\t}\n\n\t\tbpStack := imageInspector.ImageInfo.Config.Labels[buildpackinfo.LabelKeyStackID]\n\t\tcmdReport.SourceImage.Buildpack = &report.BuildpackInfo{\n\t\t\tStack: bpStack,\n\t\t}\n\t}\n\n\tfor _, m := range imageInspector.DockerfileInfo.Maintainers {\n\t\tmaintainers[m] = struct{}{}\n\t}\n\n\tfor k, v := range cmdReport.SourceImage.Labels {\n\t\tif strings.ToLower(k) == \"maintainer\" || strings.ToLower(k) == \"author\" || strings.ToLower(k) == \"authors\" || k == ociLabelImageAuthors {\n\t\t\tmaintainers[v] = struct{}{}\n\t\t} else {\n\t\t\tswitch k {\n\t\t\tcase ociLabelBaseImageDigest, azureLabelBaseImageDigest:\n\t\t\t\tcmdReport.SourceImage.BaseImageDigest = v\n\t\t\tcase ociLabelBaseImageName, azureLabelBaseImageName:\n\t\t\t\tcmdReport.SourceImage.BaseImageName = v\n\t\t\t}\n\t\t}\n\t}\n\n\tfor m := range maintainers {\n\t\tcmdReport.SourceImage.Maintainers = append(cmdReport.SourceImage.Maintainers, m)\n\t}\n\n\tcmdReport.ArtifactLocation = imageInspector.ArtifactLocation\n\n\txc.Out.State(\"image.api.inspection.done\")\n\txc.Out.State(\"image.data.inspection.start\")\n\n\timageID := dockerutil.CleanImageID(imageInspector.ImageInfo.ID)\n\tiaName := fmt.Sprintf(\"%s.tar\", imageID)\n\tiaPath := filepath.Join(localVolumePath, \"image\", iaName)\n\tiaPathReady := fmt.Sprintf(\"%s.ready\", iaPath)\n\n\tvar doSave bool\n\tif fsutil.IsRegularFile(iaPath) {\n\t\tif !doReuseSavedImage {\n\t\t\tdoSave = true\n\t\t}\n\n\t\tif !fsutil.Exists(iaPathReady) {\n\t\t\tdoSave = true\n\t\t}\n\t} else {\n\t\tdoSave = true\n\t}\n\n\tif doSave {\n\t\tif fsutil.Exists(iaPathReady) {\n\t\t\tfsutil.Remove(iaPathReady)\n\t\t}\n\n\t\txc.Out.Info(\"image.data.inspection.save.image.start\")\n\t\terr = dockerutil.SaveImage(client, imageID, iaPath, false, false)\n\t\terrutil.FailOn(err)\n\n\t\terr = fsutil.Touch(iaPathReady)\n\t\terrutil.WarnOn(err)\n\n\t\txc.Out.Info(\"image.data.inspection.save.image.end\")\n\t} else {\n\t\tlogger.Debugf(\"exported image already exists - %s\", iaPath)\n\t}\n\n\tpp := &dockerimage.ProcessorParams{\n\t\tDetectIdentities: &dockerimage.DetectOpParam{\n\t\t\tEnabled:      cparams.DetectIdentities.Enabled,\n\t\t\tDumpRaw:      cparams.DetectIdentities.DumpRaw,\n\t\t\tIsConsoleOut: cparams.DetectIdentities.IsConsoleOut,\n\t\t\tIsDirOut:     cparams.DetectIdentities.IsDirOut,\n\t\t\tOutputPath:   cparams.DetectIdentities.OutputPath,\n\t\t\tInputParams:  cparams.DetectIdentities.InputParams,\n\t\t},\n\t\tDetectAllCertFiles:   cparams.DetectAllCertFiles,\n\t\tDetectAllCertPKFiles: cparams.DetectAllCertPKFiles,\n\t}\n\n\txc.Out.Info(\"image.data.inspection.process.image.start\")\n\timagePkg, err := dockerimage.LoadPackage(\n\t\tiaPath,\n\t\timageID,\n\t\tfalse,\n\t\ttopChangesMax,\n\t\tdoHashData,\n\t\tdoDetectDuplicates,\n\t\tchangeDataHashMatchers,\n\t\tchangePathMatchers,\n\t\tchangeDataMatchers,\n\t\tutf8Detector,\n\t\tpp)\n\n\terrutil.FailOn(err)\n\txc.Out.Info(\"image.data.inspection.process.image.end\")\n\n\tif utf8Detector != nil {\n\t\terrutil.FailOn(utf8Detector.Close())\n\t}\n\n\txc.Out.State(\"image.data.inspection.done\")\n\n\tif len(imageInspector.DockerfileInfo.AllInstructions) == len(imagePkg.Config.History) {\n\t\tfor instIdx, instInfo := range imageInspector.DockerfileInfo.AllInstructions {\n\t\t\tinstInfo.Author = imagePkg.Config.History[instIdx].Author\n\t\t\tinstInfo.EmptyLayer = imagePkg.Config.History[instIdx].EmptyLayer\n\t\t\tinstInfo.LayerID = imagePkg.Config.History[instIdx].LayerID\n\t\t\tinstInfo.LayerIndex = imagePkg.Config.History[instIdx].LayerIndex\n\t\t\tinstInfo.LayerFSDiffID = imagePkg.Config.History[instIdx].LayerFSDiffID\n\t\t}\n\t} else {\n\t\tlogger.Debugf(\"history instruction set size mismatch - %v/%v \",\n\t\t\tlen(imageInspector.DockerfileInfo.AllInstructions),\n\t\t\tlen(imagePkg.Config.History))\n\t}\n\n\tallEntryParams := append(cmdReport.SourceImage.ContainerEntry.Entrypoint,\n\t\tcmdReport.SourceImage.ContainerEntry.Cmd...)\n\tif len(allEntryParams) > 0 {\n\t\tcmdReport.SourceImage.ContainerEntry.ExePath = allEntryParams[0]\n\t\tcmdReport.SourceImage.ContainerEntry.ExeArgs = allEntryParams[1:]\n\n\t\t//fix up exe path if relative\n\t\tif !strings.HasPrefix(cmdReport.SourceImage.ContainerEntry.ExePath, \"/\") {\n\t\t\t//check relative path\n\t\t\tif strings.HasPrefix(cmdReport.SourceImage.ContainerEntry.ExePath, \"./\") ||\n\t\t\t\tstrings.HasPrefix(cmdReport.SourceImage.ContainerEntry.ExePath, \"../\") {\n\n\t\t\t\tfullExePath := filepath.Join(cmdReport.SourceImage.WorkDir, cmdReport.SourceImage.ContainerEntry.ExePath)\n\t\t\t\tobject := findChange(imagePkg, fullExePath)\n\t\t\t\tif object != nil {\n\t\t\t\t\tcmdReport.SourceImage.ContainerEntry.FullExePath =\n\t\t\t\t\t\t&report.ContainerFileInfo{\n\t\t\t\t\t\t\tName:  fullExePath,\n\t\t\t\t\t\t\tLayer: object.LayerIndex,\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//check env paths\n\t\t\t\tvar envPaths []string\n\t\t\t\tfor _, envInfo := range cmdReport.SourceImage.EnvVars {\n\t\t\t\t\tif strings.HasPrefix(envInfo, \"PATH=\") {\n\t\t\t\t\t\tenvInfo = strings.TrimPrefix(envInfo, \"PATH=\")\n\t\t\t\t\t\tenvPaths = strings.Split(envInfo, \":\")\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor _, envPath := range envPaths {\n\t\t\t\t\tfullExePath := fmt.Sprintf(\"%s/%s\", envPath, cmdReport.SourceImage.ContainerEntry.ExePath)\n\t\t\t\t\tobject := findChange(imagePkg, fullExePath)\n\t\t\t\t\tif object != nil {\n\t\t\t\t\t\tcmdReport.SourceImage.ContainerEntry.FullExePath =\n\t\t\t\t\t\t\t&report.ContainerFileInfo{\n\t\t\t\t\t\t\t\tName:  fullExePath,\n\t\t\t\t\t\t\t\tLayer: object.LayerIndex,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tobject := findChange(imagePkg, cmdReport.SourceImage.ContainerEntry.ExePath)\n\t\t\tif object != nil {\n\t\t\t\tcmdReport.SourceImage.ContainerEntry.FullExePath =\n\t\t\t\t\t&report.ContainerFileInfo{\n\t\t\t\t\t\tName:  cmdReport.SourceImage.ContainerEntry.ExePath,\n\t\t\t\t\t\tLayer: object.LayerIndex,\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//find files in exe args\n\t\tfor _, exeArg := range cmdReport.SourceImage.ContainerEntry.ExeArgs {\n\t\t\t//if starts with / assume a full path and lookup/find in the layer references\n\t\t\t//otherwise try to use workdir and lookup/find in the layer references\n\t\t\tif strings.HasPrefix(exeArg, \"-\") {\n\t\t\t\t//skip flag names (might have false positives)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar filePath string\n\t\t\tif strings.HasPrefix(exeArg, \"/\") {\n\t\t\t\tfilePath = exeArg\n\t\t\t} else {\n\t\t\t\t//not a perfect way to find potential files\n\t\t\t\t//but better than nothing\n\t\t\t\tfilePath = fmt.Sprintf(\"%s/%s\", cmdReport.SourceImage.WorkDir, exeArg)\n\t\t\t}\n\n\t\t\tobject := findChange(imagePkg, filePath)\n\t\t\tif object != nil {\n\t\t\t\tcmdReport.SourceImage.ContainerEntry.ArgFiles =\n\t\t\t\t\tappend(cmdReport.SourceImage.ContainerEntry.ArgFiles,\n\t\t\t\t\t\t&report.ContainerFileInfo{\n\t\t\t\t\t\t\tName:  filePath,\n\t\t\t\t\t\t\tLayer: object.LayerIndex,\n\t\t\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprintImagePackage(\n\t\txc,\n\t\timagePkg,\n\t\tappName,\n\t\tcmdName,\n\t\tchanges,\n\t\tchangesOutputs,\n\t\tlayers,\n\t\tlayerChangesMax,\n\t\tallChangesMax,\n\t\taddChangesMax,\n\t\tmodifyChangesMax,\n\t\tdeleteChangesMax,\n\t\tdoHashData,\n\t\tdoDetectDuplicates,\n\t\tdoShowDuplicates,\n\t\tdoShowSpecialPerms,\n\t\tchangeMatchLayersOnly,\n\t\tchangeDataHashMatchers,\n\t\tchangePathMatchers,\n\t\tchangeDataMatchers,\n\t\tcparams,\n\t\tcmdReport)\n\n\tif doAddImageManifest {\n\t\tcmdReport.RawImageManifest = imagePkg.Manifest\n\t}\n\n\tif doAddImageConfig {\n\t\tcmdReport.RawImageConfig = imagePkg.Config\n\t}\n\n\tcmdReport.ImageReport.BuildInfo = imagePkg.Config.BuildInfoDecoded\n\n\tif (cmdReport.SourceImage.BaseImageDigest == \"\" || cmdReport.SourceImage.BaseImageName == \"\") &&\n\t\tcmdReport.ImageReport.BuildInfo != nil &&\n\t\tlen(cmdReport.ImageReport.BuildInfo.Sources) > 0 {\n\t\tvar lastImageSource *dockerimage.BuildSource\n\t\tfor _, s := range cmdReport.ImageReport.BuildInfo.Sources {\n\t\t\tif s.Type == dockerimage.SourceTypeDockerImage {\n\t\t\t\tlastImageSource = s\n\t\t\t}\n\t\t}\n\n\t\tif lastImageSource != nil {\n\t\t\tif lastImageSource.Ref != \"\" && cmdReport.SourceImage.BaseImageName == \"\" {\n\t\t\t\tcmdReport.SourceImage.BaseImageName = lastImageSource.Ref\n\t\t\t}\n\n\t\t\tif lastImageSource.Pin != \"\" && cmdReport.SourceImage.BaseImageDigest == \"\" {\n\t\t\t\tcmdReport.SourceImage.BaseImageDigest = lastImageSource.Pin\n\t\t\t}\n\t\t}\n\t}\n\n\txc.Out.State(cmd.StateCompleted)\n\tcmdReport.State = cmd.StateCompleted\n\n\tif doRmFileArtifacts {\n\t\tlogger.Info(\"removing temporary artifacts...\")\n\t\terr = fsutil.Remove(iaPath)\n\t\terrutil.WarnOn(err)\n\t} else {\n\t\tcmdReport.ImageArchiveLocation = iaPath\n\t}\n\n\txc.Out.State(cmd.StateDone)\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.location\": cmdReport.ArtifactLocation,\n\t\t})\n\n\txc.Out.Info(\"results\",\n\t\tovars{\n\t\t\t\"artifacts.dockerfile.original\": \"Dockerfile.fat\",\n\t\t})\n\n\tvinfo := <-viChan\n\tversion.PrintCheckVersion(xc, \"\", vinfo)\n\n\tcmdReport.State = cmd.StateDone\n\tif cmdReport.Save() {\n\t\txc.Out.Info(\"report\",\n\t\t\tovars{\n\t\t\t\t\"file\": cmdReport.ReportLocation(),\n\t\t\t})\n\t}\n\n\tif xdArtifactsPath != \"\" {\n\t\tvar filesToExport []string\n\t\tfilesToExport = append(filesToExport, cmdReport.ReportLocation())\n\t\tfilesToExport = append(filesToExport, filepath.Join(cmdReport.ArtifactLocation, fatDockerfileName))\n\t\tif utf8Detector.DumpArchive != \"\" {\n\t\t\tfilesToExport = append(filesToExport, utf8Detector.DumpArchive)\n\t\t}\n\n\t\tif xdArtifactsPath == \".\" {\n\t\t\txdArtifactsPath = \"data-artifacts.tar\"\n\t\t}\n\n\t\tif err := fsutil.ArchiveFiles(xdArtifactsPath, filesToExport, true, \"\"); err == nil {\n\t\t\txc.Out.Info(\"exported-data-artifacts\",\n\t\t\t\tovars{\n\t\t\t\t\t\"file\": xdArtifactsPath,\n\t\t\t\t})\n\t\t} else {\n\t\t\tlogger.Errorf(\"error exporting data artifacts (%s) - %v\", xdArtifactsPath, err)\n\t\t}\n\t}\n}\n\nfunc findChange(pkg *dockerimage.Package, filepath string) *dockerimage.ObjectMetadata {\n\tfor _, layer := range pkg.Layers {\n\t\tif object, found := layer.References[filepath]; found {\n\t\t\treturn object\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc printImagePackage(\n\txc *app.ExecutionContext,\n\tpkg *dockerimage.Package,\n\tappName string,\n\tcmdName cmd.Type,\n\tchanges map[string]struct{},\n\tchangesOutputs map[string]struct{},\n\tlayers map[string]struct{},\n\tlayerChangesMax int,\n\tallChangesMax int,\n\taddChangesMax int,\n\tmodifyChangesMax int,\n\tdeleteChangesMax int,\n\tdoHashData bool,\n\tdoDetectDuplicates bool,\n\tdoShowDuplicates bool,\n\tdoShowSpecialPerms bool,\n\tchangeMatchLayersOnly bool,\n\tchangeDataHashMatchers map[string]*dockerimage.ChangeDataHashMatcher,\n\tchangePathMatchers []*dockerimage.ChangePathMatcher,\n\tchangeDataMatchers map[string]*dockerimage.ChangeDataMatcher,\n\tcparams *CommandParams,\n\tcmdReport *report.XrayCommand) {\n\tvar allChangesCount int\n\tvar addChangesCount int\n\tvar modifyChangesCount int\n\tvar deleteChangesCount int\n\n\txc.Out.Info(\"image.package.details\")\n\txc.Out.Info(\"layers.count\",\n\t\tovars{\n\t\t\t\"value\": len(pkg.Layers),\n\t\t})\n\n\t//NOTE: all this cmdReport.ImageReport logic should be moved outside of this function\n\tcmdReport.ImageReport = &dockerimage.ImageReport{\n\t\tStats: pkg.Stats,\n\t}\n\n\tif cparams.DetectIdentities.Enabled {\n\t\tcmdReport.ImageReport.Identities = pkg.ProcessIdentityData()\n\n\t\tif cmdReport.ImageReport.Identities != nil {\n\t\t\txc.Out.Info(\"image.identities.stats\",\n\t\t\t\tovars{\n\t\t\t\t\t\"user_count\":  len(cmdReport.ImageReport.Identities.Users),\n\t\t\t\t\t\"group_count\": len(cmdReport.ImageReport.Identities.Groups),\n\t\t\t\t})\n\n\t\t\tfor username, userInfo := range cmdReport.ImageReport.Identities.Users {\n\t\t\t\txc.Out.Info(\"image.identities.user\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"username\":          username,\n\t\t\t\t\t\t\"uid\":               userInfo.UID,\n\t\t\t\t\t\t\"home\":              userInfo.Home,\n\t\t\t\t\t\t\"shell\":             userInfo.Shell,\n\t\t\t\t\t\t\"no_login_shell\":    userInfo.NoLoginShell,\n\t\t\t\t\t\t\"no_password_login\": userInfo.ShadowPassword.NoPasswordLogin,\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\tfor k := range pkg.Certs.Bundles {\n\t\tcmdReport.ImageReport.Certs.Bundles =\n\t\t\tappend(cmdReport.ImageReport.Certs.Bundles, k)\n\t}\n\n\tfor k := range pkg.Certs.Files {\n\t\tcmdReport.ImageReport.Certs.Files =\n\t\t\tappend(cmdReport.ImageReport.Certs.Files, k)\n\t}\n\n\tcmdReport.ImageReport.Certs.Links = pkg.Certs.Links\n\tcmdReport.ImageReport.Certs.Hashes = pkg.Certs.Hashes\n\n\tfor k := range pkg.Certs.PrivateKeys {\n\t\tcmdReport.ImageReport.Certs.PrivateKeys =\n\t\t\tappend(cmdReport.ImageReport.Certs.PrivateKeys, k)\n\t}\n\n\tcmdReport.ImageReport.Certs.PrivateKeyLinks = pkg.Certs.PrivateKeyLinks\n\n\tfor k := range pkg.CACerts.Bundles {\n\t\tcmdReport.ImageReport.CACerts.Bundles =\n\t\t\tappend(cmdReport.ImageReport.CACerts.Bundles, k)\n\t}\n\n\tfor k := range pkg.CACerts.Files {\n\t\tcmdReport.ImageReport.CACerts.Files =\n\t\t\tappend(cmdReport.ImageReport.CACerts.Files, k)\n\t}\n\n\tcmdReport.ImageReport.CACerts.Links = pkg.CACerts.Links\n\tcmdReport.ImageReport.CACerts.Hashes = pkg.CACerts.Hashes\n\n\tfor k := range pkg.CACerts.PrivateKeys {\n\t\tcmdReport.ImageReport.CACerts.PrivateKeys =\n\t\t\tappend(cmdReport.ImageReport.CACerts.PrivateKeys, k)\n\t}\n\n\tcmdReport.ImageReport.CACerts.PrivateKeyLinks = pkg.CACerts.PrivateKeyLinks\n\n\tif doDetectDuplicates && pkg.Stats.DuplicateFileCount > 0 {\n\t\txc.Out.Info(\"image.stats.duplicates\",\n\t\t\tovars{\n\t\t\t\t\"file_count\":            pkg.Stats.DuplicateFileCount,\n\t\t\t\t\"file_total_count\":      pkg.Stats.DuplicateFileTotalCount,\n\t\t\t\t\"file_size.bytes\":       pkg.Stats.DuplicateFileSize,\n\t\t\t\t\"file_size.human\":       humanize.Bytes(pkg.Stats.DuplicateFileSize),\n\t\t\t\t\"file_total_size.bytes\": pkg.Stats.DuplicateFileTotalSize,\n\t\t\t\t\"file_total_size.human\": humanize.Bytes(pkg.Stats.DuplicateFileTotalSize),\n\t\t\t\t\"wasted.bytes\":          pkg.Stats.DuplicateFileWastedSize,\n\t\t\t\t\"wasted.human\":          humanize.Bytes(pkg.Stats.DuplicateFileWastedSize),\n\t\t\t})\n\t}\n\n\tdoShow := func(changeMatchLayersOnly bool, layer *dockerimage.Layer) bool {\n\t\tif !changeMatchLayersOnly || (changeMatchLayersOnly && layer.HasMatches()) {\n\t\t\treturn true\n\t\t}\n\n\t\treturn false\n\t}\n\n\tfor _, layer := range pkg.Layers {\n\t\tlayerInfo := ovars{\n\t\t\t\"index\": layer.Index,\n\t\t\t\"id\":    layer.ID,\n\t\t\t\"path\":  layer.Path,\n\t\t}\n\n\t\tif layer.MetadataChangesOnly {\n\t\t\tlayerInfo[\"metadata_change_only\"] = true\n\t\t}\n\n\t\tif layer.LayerDataSource != \"\" {\n\t\t\tlayerInfo[\"layer_data_source\"] = layer.LayerDataSource\n\t\t}\n\n\t\tif doShow(changeMatchLayersOnly, layer) {\n\t\t\txc.Out.Info(\"layer.start\")\n\t\t\txc.Out.Info(\"layer\", layerInfo)\n\t\t}\n\n\t\tvar layerChangesCount int\n\n\t\tif layer.Distro != nil {\n\t\t\tdistro := &report.DistroInfo{\n\t\t\t\tName:        layer.Distro.Name,\n\t\t\t\tVersion:     layer.Distro.Version,\n\t\t\t\tDisplayName: layer.Distro.DisplayName,\n\t\t\t}\n\n\t\t\txc.Out.Info(\"distro\",\n\t\t\t\tovars{\n\t\t\t\t\t\"name\":    distro.Name,\n\t\t\t\t\t\"version\": distro.Version,\n\t\t\t\t\t\"display\": distro.DisplayName,\n\t\t\t\t})\n\n\t\t\tcmdReport.SourceImage.Distro = distro\n\t\t}\n\n\t\ttopList := layer.Top.List()\n\n\t\tlayerReport := dockerimage.LayerReport{\n\t\t\tID:                  layer.ID,\n\t\t\tIndex:               layer.Index,\n\t\t\tPath:                layer.Path,\n\t\t\tLayerDataSource:     layer.LayerDataSource,\n\t\t\tMetadataChangesOnly: layer.MetadataChangesOnly,\n\t\t\tFSDiffID:            layer.FSDiffID,\n\t\t\tStats:               layer.Stats,\n\t\t}\n\n\t\tlayerReport.Changes.Deleted = uint64(len(layer.Changes.Deleted))\n\t\tlayerReport.Changes.Modified = uint64(len(layer.Changes.Modified))\n\t\tlayerReport.Changes.Added = uint64(len(layer.Changes.Added))\n\n\t\tlayerReport.Top = topList\n\n\t\tfor imgIdx, imgInfo := range cmdReport.ImageStack {\n\t\t\tfor instIdx, instInfo := range imgInfo.Instructions {\n\t\t\t\tif layerReport.ID == instInfo.LayerID {\n\t\t\t\t\tif !instInfo.EmptyLayer {\n\t\t\t\t\t\tif layerReport.ChangeInstruction != nil {\n\t\t\t\t\t\t\tlog.Debugf(\"overwriting existing layerReport.ChangeInstruction = %#v\", layerReport.ChangeInstruction)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlayerReport.ChangeInstruction = &dockerimage.InstructionSummary{\n\t\t\t\t\t\t\tIndex:      instIdx,\n\t\t\t\t\t\t\tImageIndex: imgIdx,\n\t\t\t\t\t\t\tType:       instInfo.Type,\n\t\t\t\t\t\t\tAll:        instInfo.CommandAll,\n\t\t\t\t\t\t\tSnippet:    instInfo.CommandSnippet,\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\textraInst := &dockerimage.InstructionSummary{\n\t\t\t\t\t\t\tIndex:      instIdx,\n\t\t\t\t\t\t\tImageIndex: imgIdx,\n\t\t\t\t\t\t\tType:       instInfo.Type,\n\t\t\t\t\t\t\tAll:        instInfo.CommandAll,\n\t\t\t\t\t\t\tSnippet:    instInfo.CommandSnippet,\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlayerReport.OtherInstructions = append(layerReport.OtherInstructions, extraInst)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcmdReport.ImageLayers = append(cmdReport.ImageLayers, &layerReport)\n\n\t\tif layerReport.ChangeInstruction != nil {\n\t\t\tif doShow(changeMatchLayersOnly, layer) {\n\t\t\t\txc.Out.Info(\"change.instruction\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"index\":   fmt.Sprintf(\"%d:%d\", layerReport.ChangeInstruction.ImageIndex, layerReport.ChangeInstruction.Index),\n\t\t\t\t\t\t\"type\":    layerReport.ChangeInstruction.Type,\n\t\t\t\t\t\t\"snippet\": layerReport.ChangeInstruction.Snippet,\n\t\t\t\t\t\t\"all\":     layerReport.ChangeInstruction.All,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t}\n\n\t\tif doShow(changeMatchLayersOnly, layer) {\n\t\t\tif layerReport.OtherInstructions != nil {\n\t\t\t\txc.Out.Info(\"other.instructions\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"count\": len(layerReport.OtherInstructions),\n\t\t\t\t\t})\n\n\t\t\t\tfor idx, info := range layerReport.OtherInstructions {\n\t\t\t\t\txc.Out.Info(\"other.instruction\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"pos\":     idx,\n\t\t\t\t\t\t\t\"index\":   fmt.Sprintf(\"%d:%d\", info.ImageIndex, info.Index),\n\t\t\t\t\t\t\t\"type\":    info.Type,\n\t\t\t\t\t\t\t\"snippet\": info.Snippet,\n\t\t\t\t\t\t\t\"all\":     info.All,\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif layer.Stats.AllSize != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"all_size.human\": humanize.Bytes(uint64(layer.Stats.AllSize)),\n\t\t\t\t\t\t\"all_size.bytes\": layer.Stats.AllSize,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.ObjectCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"object_count\": layer.Stats.ObjectCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.DirCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"dir_count\": layer.Stats.DirCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.FileCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"file_count\": layer.Stats.FileCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.LinkCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"link_count\": layer.Stats.LinkCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.MaxFileSize != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"max_file_size.human\": humanize.Bytes(uint64(layer.Stats.MaxFileSize)),\n\t\t\t\t\t\t\"max_file_size.bytes\": layer.Stats.MaxFileSize,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.DeletedCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"deleted_count\": layer.Stats.DeletedCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.DeletedDirCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"deleted_dir_count\": layer.Stats.DeletedDirCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.DeletedFileCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"deleted_file_count\": layer.Stats.DeletedFileCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.DeletedLinkCount != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"deleted_link_count\": layer.Stats.DeletedLinkCount,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.DeletedSize != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"deleted_size\": layer.Stats.DeletedSize,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.AddedSize != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"added_size.human\": humanize.Bytes(uint64(layer.Stats.AddedSize)),\n\t\t\t\t\t\t\"added_size.bytes\": layer.Stats.AddedSize,\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tif layer.Stats.ModifiedSize != 0 {\n\t\t\t\txc.Out.Info(\"layer.stats\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"modified_size.human\": humanize.Bytes(uint64(layer.Stats.ModifiedSize)),\n\t\t\t\t\t\t\"modified_size.bytes\": layer.Stats.ModifiedSize,\n\t\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tchangeCount := len(layer.Changes.Deleted) + len(layer.Changes.Modified) + len(layer.Changes.Added)\n\n\t\tif doShow(changeMatchLayersOnly, layer) {\n\t\t\txc.Out.Info(\"layer.change.summary\",\n\t\t\t\tovars{\n\t\t\t\t\t\"deleted\":  len(layer.Changes.Deleted),\n\t\t\t\t\t\"modified\": len(layer.Changes.Modified),\n\t\t\t\t\t\"added\":    len(layer.Changes.Added),\n\t\t\t\t\t\"all\":      changeCount,\n\t\t\t\t})\n\n\t\t\txc.Out.Info(\"layer.objects.count\",\n\t\t\t\tovars{\n\t\t\t\t\t\"value\": len(layer.Objects),\n\t\t\t\t})\n\n\t\t\tif len(topList) > 0 {\n\t\t\t\txc.Out.Info(\"layer.objects.top.start\")\n\t\t\t\tfor _, topObject := range topList {\n\t\t\t\t\tmatch := topObject.PathMatch\n\n\t\t\t\t\tif !match && len(changePathMatchers) > 0 {\n\t\t\t\t\t\tlog.Tracef(\"Change path patterns, no match. skipping 'top' change ['%s']\", topObject.Name)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif len(changeDataMatchers) > 0 {\n\t\t\t\t\t\t\tmatchedPatterns, found := layer.DataMatches[topObject.Name]\n\t\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\t\tlog.Tracef(\"Change data patterns, no match. skipping 'top' change ['%s']\", topObject.Name)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlog.Tracef(\"'%s' ('top' change) matched data patterns - %d\", topObject.Name, len(matchedPatterns))\n\t\t\t\t\t\t\tfor _, cdm := range matchedPatterns {\n\t\t\t\t\t\t\t\tlog.Tracef(\"matched => PP='%s' DP='%s'\", cdm.PathPattern, cdm.DataPattern)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif len(changeDataHashMatchers) > 0 {\n\t\t\t\t\t\t\t\tmatched, found := layer.DataHashMatches[topObject.Name]\n\t\t\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\t\t\tlog.Trace(\"Change data hash patterns, no match. skipping 'top' change...\")\n\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tlog.Tracef(\"'%s' ('top' change) matched data hash pattern - %s\", topObject.Name, matched.Hash)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tprintObject(xc, topObject)\n\t\t\t\t}\n\t\t\t\txc.Out.Info(\"layer.objects.top.end\")\n\t\t\t}\n\t\t}\n\n\t\tshowLayer := true\n\t\tif len(layers) > 0 {\n\t\t\tshowLayer = false\n\t\t\t_, hasID := layers[layer.ID]\n\t\t\tlayerIdx := fmt.Sprintf(\"%v\", layer.Index)\n\t\t\t_, hasIndex := layers[layerIdx]\n\t\t\tif hasID || hasIndex {\n\t\t\t\tshowLayer = true\n\t\t\t}\n\t\t}\n\n\t\tif doShow(changeMatchLayersOnly, layer) && showLayer {\n\t\t\tif _, ok := changes[\"delete\"]; ok && len(layer.Changes.Deleted) > 0 {\n\t\t\t\txc.Out.Info(\"layer.objects.deleted.start\")\n\t\t\t\tfor _, objectIdx := range layer.Changes.Deleted {\n\t\t\t\t\tallChangesCount++\n\t\t\t\t\tdeleteChangesCount++\n\t\t\t\t\tlayerChangesCount++\n\n\t\t\t\t\tobjectInfo := layer.Objects[objectIdx]\n\n\t\t\t\t\t//TODO: add a flag to select change type to apply path patterns\n\t\t\t\t\tmatch := objectInfo.PathMatch\n\n\t\t\t\t\tif !match && len(changePathMatchers) > 0 {\n\t\t\t\t\t\tlog.Tracef(\"Change path patterns, no match. skipping 'delete' change ['%s']\", objectInfo.Name)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t//NOTE: not checking change data pattern matches for deletes\n\n\t\t\t\t\tif allChangesMax > -1 && allChangesCount > allChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif deleteChangesMax > -1 && deleteChangesCount > deleteChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif layerChangesMax > -1 && layerChangesCount > layerChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := changesOutputs[\"report\"]; ok {\n\t\t\t\t\t\tlayerReport.Deleted = append(layerReport.Deleted, objectInfo)\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := changesOutputs[\"console\"]; ok {\n\t\t\t\t\t\tprintObject(xc, objectInfo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\txc.Out.Info(\"layer.objects.deleted.end\")\n\t\t\t}\n\n\t\t\tif _, ok := changes[\"modify\"]; ok && len(layer.Changes.Modified) > 0 {\n\t\t\t\txc.Out.Info(\"layer.objects.modified.start\")\n\t\t\t\tfor _, objectIdx := range layer.Changes.Modified {\n\t\t\t\t\tallChangesCount++\n\t\t\t\t\tmodifyChangesCount++\n\t\t\t\t\tlayerChangesCount++\n\n\t\t\t\t\tobjectInfo := layer.Objects[objectIdx]\n\n\t\t\t\t\t//TODO: add a flag to select change type to apply path patterns\n\t\t\t\t\tmatch := objectInfo.PathMatch\n\n\t\t\t\t\tif !match && len(changePathMatchers) > 0 {\n\t\t\t\t\t\tlog.Tracef(\"Change path patterns, no match. skipping 'modify' change ['%s']\", objectInfo.Name)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif len(changeDataMatchers) > 0 {\n\t\t\t\t\t\t\tmatchedPatterns, found := layer.DataMatches[objectInfo.Name]\n\t\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\t\tlog.Tracef(\"Change data patterns, no match. skipping change ['%s']\", objectInfo.Name)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlog.Tracef(\"'%s' ('modify' change) matched data patterns - %d\", objectInfo.Name, len(matchedPatterns))\n\t\t\t\t\t\t\tfor _, cdm := range matchedPatterns {\n\t\t\t\t\t\t\t\tlog.Tracef(\"matched => PP='%s' DP='%s'\", cdm.PathPattern, cdm.DataPattern)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif len(changeDataHashMatchers) > 0 {\n\t\t\t\t\t\t\t\tmatched, found := layer.DataHashMatches[objectInfo.Name]\n\t\t\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\t\t\tlog.Trace(\"Change data hash patterns, no match. skipping 'modify' change...\")\n\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tlog.Tracef(\"'%s' ('modify' change) matched data hash pattern - %s\", objectInfo.Name, matched.Hash)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif allChangesMax > -1 && allChangesCount > allChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif modifyChangesMax > -1 && modifyChangesCount > modifyChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif layerChangesMax > -1 && layerChangesCount > layerChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := changesOutputs[\"report\"]; ok {\n\t\t\t\t\t\tlayerReport.Modified = append(layerReport.Modified, objectInfo)\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := changesOutputs[\"console\"]; ok {\n\t\t\t\t\t\tprintObject(xc, objectInfo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\txc.Out.Info(\"layer.objects.modified.end\")\n\t\t\t}\n\n\t\t\tif _, ok := changes[\"add\"]; ok && len(layer.Changes.Added) > 0 {\n\t\t\t\txc.Out.Info(\"layer.objects.added.start\")\n\t\t\t\tfor _, objectIdx := range layer.Changes.Added {\n\t\t\t\t\tallChangesCount++\n\t\t\t\t\taddChangesCount++\n\t\t\t\t\tlayerChangesCount++\n\n\t\t\t\t\tobjectInfo := layer.Objects[objectIdx]\n\n\t\t\t\t\t//TODO: add a flag to select change type to apply path patterns\n\t\t\t\t\tmatch := objectInfo.PathMatch\n\n\t\t\t\t\tif !match && len(changePathMatchers) > 0 {\n\t\t\t\t\t\tlog.Tracef(\"Change path patterns, no match. skipping 'add' change ['%s']\", objectInfo.Name)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif len(changeDataMatchers) > 0 {\n\t\t\t\t\t\t\tmatchedPatterns, found := layer.DataMatches[objectInfo.Name]\n\t\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\t\tlog.Tracef(\"change data patterns, no match. skipping change ['%s']\", objectInfo.Name)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlog.Tracef(\"'%s' ('add' change) matched data patterns - %d\", objectInfo.Name, len(matchedPatterns))\n\t\t\t\t\t\t\tfor _, cdm := range matchedPatterns {\n\t\t\t\t\t\t\t\tlog.Tracef(\"matched => PP='%s' DP='%s'\", cdm.PathPattern, cdm.DataPattern)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif len(changeDataHashMatchers) > 0 {\n\t\t\t\t\t\t\t\tmatched, found := layer.DataHashMatches[objectInfo.Name]\n\t\t\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\t\t\tlog.Trace(\"Change data hash patterns, no match. skipping 'add' change...\")\n\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tlog.Tracef(\"'%s' ('add' change) matched data hash pattern - %s\", objectInfo.Name, matched.Hash)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif allChangesMax > -1 && allChangesCount > allChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif addChangesMax > -1 && addChangesCount > addChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif layerChangesMax > -1 && layerChangesCount > layerChangesMax {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := changesOutputs[\"report\"]; ok {\n\t\t\t\t\t\tlayerReport.Added = append(layerReport.Added, layer.Objects[objectIdx])\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := changesOutputs[\"console\"]; ok {\n\t\t\t\t\t\tprintObject(xc, layer.Objects[objectIdx])\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\txc.Out.Info(\"layer.objects.added.end\")\n\t\t\t}\n\t\t}\n\n\t\tif doShow(changeMatchLayersOnly, layer) {\n\t\t\txc.Out.Info(\"layer.end\")\n\t\t}\n\t}\n\n\tfor _, info := range pkg.OSShells {\n\t\txc.Out.Info(\"image.shells\",\n\t\t\tovars{\n\t\t\t\t\"full_name\":  info.FullName,\n\t\t\t\t\"short_name\": info.ShortName,\n\t\t\t\t\"exe_path\":   info.ExePath,\n\t\t\t\t\"link_path\":  info.LinkPath,\n\t\t\t\t\"reference\":  info.Reference,\n\t\t\t\t\"verified\":   info.Verified,\n\t\t\t})\n\n\t\tcmdReport.ImageReport.OSShells = append(cmdReport.ImageReport.OSShells, info)\n\t}\n\n\txc.Out.Info(\"image.entry\",\n\t\tovars{\n\t\t\t\"exe_path\": cmdReport.SourceImage.ContainerEntry.ExePath,\n\t\t\t\"exe_args\": strings.Join(cmdReport.SourceImage.ContainerEntry.ExeArgs, \",\"),\n\t\t})\n\n\tif cmdReport.SourceImage.ContainerEntry.FullExePath != nil {\n\t\txc.Out.Info(\"image.entry.full_exe_path\",\n\t\t\tovars{\n\t\t\t\t\"name\":  cmdReport.SourceImage.ContainerEntry.FullExePath.Name,\n\t\t\t\t\"layer\": cmdReport.SourceImage.ContainerEntry.FullExePath.Layer,\n\t\t\t})\n\t}\n\n\tif len(cmdReport.SourceImage.ContainerEntry.ArgFiles) > 0 {\n\t\tfor _, argFile := range cmdReport.SourceImage.ContainerEntry.ArgFiles {\n\t\t\txc.Out.Info(\"image.entry.arg_file\",\n\t\t\t\tovars{\n\t\t\t\t\t\"name\":  argFile.Name,\n\t\t\t\t\t\"layer\": argFile.Layer,\n\t\t\t\t})\n\t\t}\n\t}\n\n\tif doShowSpecialPerms &&\n\t\t(len(pkg.SpecialPermRefs.Setuid) > 0 ||\n\t\t\tlen(pkg.SpecialPermRefs.Setgid) > 0 ||\n\t\t\tlen(pkg.SpecialPermRefs.Sticky) > 0) {\n\t\tcmdReport.ImageReport.SpecialPerms = &dockerimage.SpecialPermsInfo{}\n\n\t\tfor name := range pkg.SpecialPermRefs.Setuid {\n\t\t\txc.Out.Info(\"image.special_perms.setuid\",\n\t\t\t\tovars{\n\t\t\t\t\t\"name\": name,\n\t\t\t\t})\n\n\t\t\tcmdReport.ImageReport.SpecialPerms.Setuid =\n\t\t\t\tappend(cmdReport.ImageReport.SpecialPerms.Setuid, name)\n\t\t}\n\n\t\tfor name := range pkg.SpecialPermRefs.Setgid {\n\t\t\txc.Out.Info(\"image.special_perms.setgid\",\n\t\t\t\tovars{\n\t\t\t\t\t\"name\": name,\n\t\t\t\t})\n\n\t\t\tcmdReport.ImageReport.SpecialPerms.Setgid =\n\t\t\t\tappend(cmdReport.ImageReport.SpecialPerms.Setgid, name)\n\t\t}\n\n\t\tfor name := range pkg.SpecialPermRefs.Sticky {\n\t\t\txc.Out.Info(\"image.special_perms.sticky\",\n\t\t\t\tovars{\n\t\t\t\t\t\"name\": name,\n\t\t\t\t})\n\n\t\t\tcmdReport.ImageReport.SpecialPerms.Sticky =\n\t\t\t\tappend(cmdReport.ImageReport.SpecialPerms.Sticky, name)\n\t\t}\n\t}\n\n\tif doDetectDuplicates && len(pkg.HashReferences) > 0 {\n\t\tcmdReport.ImageReport.Duplicates = map[string]*dockerimage.DuplicateFilesReport{}\n\n\t\t//TODO: show duplicates by duplicate total size (biggest waste first)\n\t\tfor hash, hobjects := range pkg.HashReferences {\n\t\t\tvar dfr *dockerimage.DuplicateFilesReport\n\t\t\tshowStart := true\n\t\t\tfor fpath, info := range hobjects {\n\t\t\t\tif showStart {\n\t\t\t\t\tdfr = &dockerimage.DuplicateFilesReport{\n\t\t\t\t\t\tFiles:       map[string]int{},\n\t\t\t\t\t\tFileCount:   uint64(len(hobjects)),\n\t\t\t\t\t\tFileSize:    uint64(info.Size),\n\t\t\t\t\t\tAllFileSize: uint64(info.Size * int64(len(hobjects))),\n\t\t\t\t\t}\n\n\t\t\t\t\tdfr.WastedSize = dfr.AllFileSize - dfr.FileSize\n\t\t\t\t\tcmdReport.ImageReport.Duplicates[hash] = dfr\n\n\t\t\t\t\tif doShowDuplicates {\n\t\t\t\t\t\txc.Out.Info(\"image.duplicates.set.start\",\n\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\"hash\":             hash,\n\t\t\t\t\t\t\t\t\"count\":            dfr.FileCount,\n\t\t\t\t\t\t\t\t\"size.bytes\":       dfr.FileSize,\n\t\t\t\t\t\t\t\t\"size.human\":       humanize.Bytes(uint64(dfr.FileSize)),\n\t\t\t\t\t\t\t\t\"all_size.bytes\":   dfr.AllFileSize,\n\t\t\t\t\t\t\t\t\"size_total.human\": humanize.Bytes(dfr.AllFileSize),\n\t\t\t\t\t\t\t\t\"wasted.bytes\":     dfr.WastedSize,\n\t\t\t\t\t\t\t\t\"wasted.human\":     humanize.Bytes(dfr.WastedSize),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tshowStart = false\n\t\t\t\t}\n\n\t\t\t\tdfr.Files[fpath] = info.LayerIndex\n\n\t\t\t\tif doShowDuplicates {\n\t\t\t\t\txc.Out.Info(\"image.duplicates.object\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"name\":  fpath,\n\t\t\t\t\t\t\t\"layer\": info.LayerIndex,\n\t\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif doShowDuplicates {\n\t\t\t\txc.Out.Info(\"image.duplicates.set.end\")\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc objectHistoryString(history *dockerimage.ObjectHistory) string {\n\tif history == nil {\n\t\treturn \"H=[]\"\n\t}\n\n\tvar builder strings.Builder\n\tbuilder.WriteString(\"H=[\")\n\tif history.Add != nil {\n\t\tbuilder.WriteString(fmt.Sprintf(\"A:%d\", history.Add.Layer))\n\t}\n\n\tif history.Add != nil {\n\t\tvar idxList []string\n\t\tfor _, mod := range history.Modifies {\n\t\t\tidxList = append(idxList, fmt.Sprintf(\"%d\", mod.Layer))\n\t\t}\n\n\t\tif len(idxList) > 0 {\n\t\t\tbuilder.WriteString(fmt.Sprintf(\"/M:%s\", strings.Join(idxList, \",\")))\n\t\t}\n\t}\n\n\tif history.Delete != nil {\n\t\tbuilder.WriteString(fmt.Sprintf(\"/D:%d\", history.Delete.Layer))\n\t}\n\n\tbuilder.WriteString(\"]\")\n\treturn builder.String()\n}\n\nfunc printObject(xc *app.ExecutionContext, object *dockerimage.ObjectMetadata) {\n\tvar hashInfo string\n\n\tif object.Hash != \"\" {\n\t\thashInfo = fmt.Sprintf(\" hash=%s\", object.Hash)\n\t}\n\tov := ovars{\n\t\t\"mode\":        object.Mode,\n\t\t\"size.human\":  humanize.Bytes(uint64(object.Size)),\n\t\t\"size.bytes\":  object.Size,\n\t\t\"uid\":         object.UID,\n\t\t\"gid\":         object.GID,\n\t\t\"mtime\":       object.ModTime.UTC().Format(time.RFC3339),\n\t\t\"H\":           objectHistoryString(object.History),\n\t\t\"hash\":        hashInfo,\n\t\t\"object.name\": object.Name,\n\t}\n\n\tif object.LinkTarget != \"\" {\n\t\tov[\"link.target\"] = object.LinkTarget\n\t}\n\n\txc.Out.Info(\"object\", ov)\n\n}\n"
  },
  {
    "path": "pkg/app/master/command/xray/init/init.go",
    "content": "package init\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command/xray\"\n)\n\nfunc init() {\n\txray.RegisterCommand()\n}\n"
  },
  {
    "path": "pkg/app/master/command/xray/prompt.go",
    "content": "package xray\n\nimport (\n\t\"github.com/c-bata/go-prompt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nvar CommandSuggestion = prompt.Suggest{\n\tText:        Name,\n\tDescription: Usage,\n}\n\nvar CommandFlagSuggestions = &command.FlagSuggestions{\n\tNames: []prompt.Suggest{\n\t\t{Text: command.FullFlagName(command.FlagCommandParamsFile), Description: command.FlagCommandParamsFileUsage},\n\t\t{Text: command.FullFlagName(command.FlagTarget), Description: command.FlagTargetUsage},\n\t\t{Text: command.FullFlagName(command.FlagPull), Description: command.FlagPullUsage},\n\t\t{Text: command.FullFlagName(command.FlagShowPullLogs), Description: command.FlagShowPullLogsUsage},\n\t\t{Text: command.FullFlagName(command.FlagRegistryAccount), Description: command.FlagRegistryAccountUsage},\n\t\t{Text: command.FullFlagName(command.FlagRegistrySecret), Description: command.FlagRegistrySecretUsage},\n\t\t{Text: command.FullFlagName(command.FlagDockerConfigPath), Description: command.FlagDockerConfigPathUsage},\n\t\t{Text: command.FullFlagName(FlagChanges), Description: FlagChangesUsage},\n\t\t{Text: command.FullFlagName(FlagChangesOutput), Description: FlagChangesOutputUsage},\n\t\t{Text: command.FullFlagName(FlagLayer), Description: FlagLayerUsage},\n\t\t{Text: command.FullFlagName(FlagAddImageManifest), Description: FlagAddImageManifestUsage},\n\t\t{Text: command.FullFlagName(FlagAddImageConfig), Description: FlagAddImageConfigUsage},\n\t\t{Text: command.FullFlagName(FlagLayerChangesMax), Description: FlagLayerChangesMaxUsage},\n\t\t{Text: command.FullFlagName(FlagAllChangesMax), Description: FlagAllChangesMaxUsage},\n\t\t{Text: command.FullFlagName(FlagAddChangesMax), Description: FlagAddChangesMaxUsage},\n\t\t{Text: command.FullFlagName(FlagModifyChangesMax), Description: FlagModifyChangesMaxUsage},\n\t\t{Text: command.FullFlagName(FlagDeleteChangesMax), Description: FlagDeleteChangesMaxUsage},\n\t\t{Text: command.FullFlagName(FlagChangePath), Description: FlagChangePathUsage},\n\t\t{Text: command.FullFlagName(FlagChangeData), Description: FlagChangeDataUsage},\n\t\t{Text: command.FullFlagName(FlagReuseSavedImage), Description: FlagReuseSavedImageUsage},\n\t\t{Text: command.FullFlagName(FlagHashData), Description: FlagHashDataUsage},\n\t\t{Text: command.FullFlagName(FlagDetectUTF8), Description: FlagDetectUTF8Usage},\n\t\t{Text: command.FullFlagName(FlagDetectDuplicates), Description: FlagDetectDuplicatesUsage},\n\t\t{Text: command.FullFlagName(FlagShowDuplicates), Description: FlagShowDuplicatesUsage},\n\t\t{Text: command.FullFlagName(FlagShowSpecialPerms), Description: FlagShowSpecialPermsUsage},\n\t\t{Text: command.FullFlagName(FlagChangeDataHash), Description: FlagChangeDataHashUsage},\n\t\t{Text: command.FullFlagName(FlagTopChangesMax), Description: FlagTopChangesMaxUsage},\n\t\t{Text: command.FullFlagName(FlagDetectAllCertFiles), Description: FlagDetectAllCertFilesUsage},\n\t\t{Text: command.FullFlagName(FlagDetectAllCertPKFiles), Description: FlagDetectAllCertPKFilesUsage},\n\t\t{Text: command.FullFlagName(FlagDetectIdentities), Description: FlagDetectIdentitiesUsage},\n\t\t{Text: command.FullFlagName(FlagDetectIdentitiesParam), Description: FlagDetectIdentitiesParamUsage},\n\t\t{Text: command.FullFlagName(FlagDetectIdentitiesDumpRaw), Description: FlagDetectIdentitiesDumpRawUsage},\n\t\t{Text: command.FullFlagName(FlagExportAllDataArtifacts), Description: FlagExportAllDataArtifactsUsage},\n\t\t{Text: command.FullFlagName(command.FlagRemoveFileArtifacts), Description: command.FlagRemoveFileArtifactsUsage},\n\t},\n\tValues: map[string]command.CompleteValue{\n\t\tcommand.FullFlagName(command.FlagCommandParamsFile):   command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagPull):                command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagShowPullLogs):        command.CompleteBool,\n\t\tcommand.FullFlagName(command.FlagDockerConfigPath):    command.CompleteFile,\n\t\tcommand.FullFlagName(command.FlagTarget):              command.CompleteImage,\n\t\tcommand.FullFlagName(FlagChanges):                     completeLayerChanges,\n\t\tcommand.FullFlagName(FlagChangesOutput):               completeOutputs,\n\t\tcommand.FullFlagName(FlagAddImageManifest):            command.CompleteBool,\n\t\tcommand.FullFlagName(FlagAddImageConfig):              command.CompleteBool,\n\t\tcommand.FullFlagName(FlagHashData):                    command.CompleteBool,\n\t\tcommand.FullFlagName(FlagDetectDuplicates):            command.CompleteBool,\n\t\tcommand.FullFlagName(FlagShowDuplicates):              command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagShowSpecialPerms):            command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagReuseSavedImage):             command.CompleteTBool,\n\t\tcommand.FullFlagName(FlagDetectAllCertFiles):          command.CompleteBool,\n\t\tcommand.FullFlagName(FlagDetectAllCertPKFiles):        command.CompleteBool,\n\t\tcommand.FullFlagName(FlagDetectIdentities):            command.CompleteTBool,\n\t\tcommand.FullFlagName(command.FlagRemoveFileArtifacts): command.CompleteBool,\n\t},\n}\n\nvar layerChangeValues = []prompt.Suggest{\n\t{Text: \"none\", Description: \"Don't show any file system change details in image layers\"},\n\t{Text: \"all\", Description: \"Show all file system change details in image layers\"},\n\t{Text: \"delete\", Description: \"Show only 'delete' file system change details in image layers\"},\n\t{Text: \"modify\", Description: \"Show only 'modify' file system change details in image layers\"},\n\t{Text: \"add\", Description: \"Show only 'add' file system change details in image layers\"},\n}\n\nfunc completeLayerChanges(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(layerChangeValues, token, true)\n}\n\nvar outputsValues = []prompt.Suggest{\n\t{Text: \"all\", Description: \"Show changes in all outputs\"},\n\t{Text: \"report\", Description: \"Show changes in command report\"},\n\t{Text: \"console\", Description: \"Show changes in console\"},\n}\n\nfunc completeOutputs(ia *command.InteractiveApp, token string, params prompt.Document) []prompt.Suggest {\n\treturn prompt.FilterHasPrefix(outputsValues, token, true)\n}\n"
  },
  {
    "path": "pkg/app/master/command/xray/register.go",
    "content": "package xray\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/app/master/command\"\n)\n\nfunc RegisterCommand() {\n\tcommand.AddCLICommand(\n\t\tName,\n\t\tCLI,\n\t\tCommandSuggestion,\n\t\tCommandFlagSuggestions)\n}\n"
  },
  {
    "path": "pkg/app/master/compose/execution.go",
    "content": "package compose\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\n\t\"github.com/compose-spec/compose-go/loader\"\n\t\"github.com/compose-spec/compose-go/types\"\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar ErrNoServiceImage = errors.New(\"no service image\")\n\ntype ServiceError struct {\n\tService string\n\tOp      string\n\tInfo    string\n}\n\nfunc (e *ServiceError) Error() string {\n\treturn fmt.Sprintf(\"compose.ServiceError: service=%s op=%s info='%s'\",\n\t\te.Service, e.Op, e.Info)\n}\n\ntype ovars = app.OutVars\n\ntype ExecutionState string\n\nconst (\n\tXSNone        ExecutionState = \"xs.none\"\n\tXSCreated                    = \"xs.created\"\n\tXSStarted                    = \"xs.started\"\n\tXSStopping                   = \"xs.stopping\"\n\tXSStopped                    = \"xs.stopped\"\n\tXSRemoved                    = \"xs.removed\"\n\tXSExited                     = \"xs.exited\"\n\tXSExitedCrash                = \"xs.exited.crash\"\n\tXSError                      = \"xs.error\"\n)\n\ntype ExecutionEvent string\n\nconst (\n\tXECreated     ExecutionEvent = \"xe.container.created\"\n\tXEStarted                    = \"xe.container.started\"\n\tXEStopping                   = \"xe.container.stopping\"\n\tXEStopped                    = \"xe.container.stopped\"\n\tXERemoved                    = \"xe.container.removed\"\n\tXEExited                     = \"xe.container.exited\"\n\tXEExitedCrash                = \"xe.container.exited.crash\"\n\tXEAPIError                   = \"xe.api.error\"\n\tXEInterrupt                  = \"xe.interrupt\"\n)\n\ntype ExecutionEventInfo struct {\n\tEvent ExecutionEvent\n\tData  map[string]string\n}\n\nconst (\n\tComposeVerUnknown = 0\n\tComposeVerOne     = 1\n\tComposeVerTwo     = 2\n\tComposeVerThree   = 3\n)\n\nconst (\n\tComposeVerOneStr   = \"1\"\n\tComposeVerTwoStr   = \"2\"\n\tComposeVerThreeStr = \"3\"\n)\n\ntype ExecutionOptions struct {\n\tSvcStartWait int\n}\n\ntype Execution struct {\n\t*ConfigInfo\n\tState             ExecutionState\n\tSelectors         *ServiceSelectors\n\tBuildImages       bool\n\tPullImages        bool\n\tOwnAllResources   bool\n\tAllServiceNames   map[string]struct{}\n\tAllServices       map[string]*ServiceInfo\n\tAllNetworks       map[string]*NetworkInfo\n\tPendingServices   map[string]struct{}\n\tRunningServices   map[string]*RunningService\n\tActiveVolumes     map[string]*ActiveVolume\n\tActiveNetworks    map[string]*ActiveNetwork\n\tStopTimeout       uint\n\tContainerProbeSvc string\n\n\toptions    *ExecutionOptions\n\teventCh    chan *ExecutionEventInfo\n\tprintState bool\n\txc         *app.ExecutionContext\n\tlogger     *log.Entry\n\tapiClient  *dockerapi.Client\n}\n\ntype ConfigInfo struct {\n\tBaseComposeDir string\n\tVersion        uint\n\tFullVersion    string\n\tProject        *types.Project\n\tRaw            map[string]interface{}\n\tRawList        []map[string]interface{}\n}\n\ntype ServiceSelectors struct {\n\tIncludes       map[string]struct{}\n\tExcludes       map[string]struct{}\n\tServiceAllDeps string\n}\n\nfunc NewServiceSelectors(serviceAllDeps string,\n\tincludes []string,\n\texcludes []string) *ServiceSelectors {\n\tselectors := &ServiceSelectors{\n\t\tIncludes:       map[string]struct{}{},\n\t\tExcludes:       map[string]struct{}{},\n\t\tServiceAllDeps: serviceAllDeps,\n\t}\n\n\tfor _, val := range includes {\n\t\tselectors.Includes[val] = struct{}{}\n\t}\n\n\tfor _, val := range excludes {\n\t\tselectors.Excludes[val] = struct{}{}\n\t}\n\n\treturn selectors\n}\n\ntype ServiceInfo struct {\n\tSelected        bool\n\tShortName       string\n\tName            string\n\tContainerName   string\n\tAllDependencies []string\n\tConfig          types.ServiceConfig\n}\n\ntype NetworkInfo struct {\n\tName   string\n\tConfig types.NetworkConfig\n}\n\ntype RunningService struct {\n\tName          string\n\tID            string\n\tContainerName string\n}\n\ntype ActiveVolume struct {\n\tShortName string\n\tFullName  string\n\tID        string\n}\n\ntype ActiveNetwork struct {\n\tName    string //full network name\n\tID      string\n\tCreated bool\n}\n\nconst defaultStopTimeout = 7 //7 seconds\n\nfunc NewConfigInfo(\n\tcomposeFiles []string,\n\tprojectName string,\n\tworkingDir string,\n\tenvVars []string,\n\tenvironmentNoHost bool,\n) (*ConfigInfo, error) {\n\t//not supporting compose profiles for now\n\tcv := &ConfigInfo{}\n\n\tvar pcConfigFiles []types.ConfigFile\n\tfor idx, composeFile := range composeFiles {\n\t\tfullComposeFilePath, err := filepath.Abs(composeFile)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tif idx == 0 {\n\t\t\tbaseComposeDir := filepath.Dir(fullComposeFilePath)\n\t\t\tif projectName == \"\" {\n\t\t\t\t//default project name to the dir name for compose file\n\t\t\t\tprojectName = filepath.Base(baseComposeDir)\n\t\t\t}\n\n\t\t\tif workingDir == \"\" {\n\t\t\t\t//all paths in the compose files are relative\n\t\t\t\t//to the base path of the first compose file\n\t\t\t\t//unless there's an explicitly provided working directory\n\t\t\t\tworkingDir = baseComposeDir\n\t\t\t}\n\n\t\t\tcv.BaseComposeDir = workingDir\n\t\t}\n\n\t\tb, err := os.ReadFile(fullComposeFilePath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\trawConfig, err := loader.ParseYAML(b)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif idx == 0 {\n\t\t\tcv.Raw = rawConfig\n\t\t}\n\n\t\tcv.RawList = append(cv.RawList, rawConfig)\n\n\t\tcf := types.ConfigFile{\n\t\t\tFilename: composeFile,\n\t\t\tContent:  b, //pass raw bytes, so loader parses and interpolates\n\t\t}\n\n\t\tpcConfigFiles = append(pcConfigFiles, cf)\n\t}\n\n\tprojectConfig := types.ConfigDetails{\n\t\tWorkingDir:  workingDir,\n\t\tConfigFiles: pcConfigFiles,\n\t}\n\n\tif len(envVars) > 0 {\n\t\tprojectConfig.Environment = map[string]string{}\n\t\tfor _, evar := range envVars {\n\t\t\tparts := strings.SplitN(evar, \"=\", 2)\n\t\t\tif len(parts) == 2 {\n\t\t\t\tprojectConfig.Environment[parts[0]] = parts[1]\n\t\t\t}\n\t\t}\n\t}\n\n\tif !environmentNoHost {\n\t\tif projectConfig.Environment == nil {\n\t\t\tprojectConfig.Environment = map[string]string{}\n\t\t}\n\n\t\t//host env vars override explicit vars\n\t\tfor _, evar := range os.Environ() {\n\t\t\tparts := strings.SplitN(evar, \"=\", 2)\n\t\t\tif len(parts) == 2 {\n\t\t\t\tprojectConfig.Environment[parts[0]] = parts[1]\n\t\t\t}\n\t\t}\n\t}\n\n\tproject, err := loader.Load(projectConfig, withProjectName(projectName))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif project == nil {\n\t\treturn nil, fmt.Errorf(\"no project info\")\n\t}\n\n\tcv.Project = project\n\n\treturn cv, nil\n}\n\nfunc NewExecution(\n\txc *app.ExecutionContext,\n\tlogger *log.Entry,\n\tapiClient *dockerapi.Client,\n\tcomposeFiles []string,\n\tselectors *ServiceSelectors,\n\tprojectName string,\n\tworkingDir string,\n\tenvVars []string,\n\tenvironmentNoHost bool,\n\tcontainerProbeComposeSvc string,\n\tbuildImages bool,\n\tpullImages bool,\n\tpullExcludes []string,\n\townAllResources bool,\n\toptions *ExecutionOptions,\n\teventCh chan *ExecutionEventInfo,\n\tprintState bool) (*Execution, error) {\n\tif logger != nil {\n\t\tlogger = logger.WithFields(log.Fields{\"com\": \"compose.execution\"})\n\t}\n\n\tconfigInfo, err := NewConfigInfo(composeFiles,\n\t\tprojectName,\n\t\tworkingDir,\n\t\tenvVars,\n\t\tenvironmentNoHost)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t//todo: explicitly check for invalid/unknown service dependencies\n\t//todo: have an option to ignore/cleanup invalid/unknown service dependencies\n\n\t//not supporting compose profiles for now\n\texe := &Execution{\n\t\tConfigInfo:        configInfo,\n\t\tState:             XSNone,\n\t\tSelectors:         selectors,\n\t\tOwnAllResources:   ownAllResources,\n\t\tBuildImages:       buildImages,\n\t\tPullImages:        pullImages,\n\t\tAllServiceNames:   map[string]struct{}{},\n\t\tAllServices:       map[string]*ServiceInfo{},\n\t\tAllNetworks:       map[string]*NetworkInfo{},\n\t\tPendingServices:   map[string]struct{}{},\n\t\tRunningServices:   map[string]*RunningService{},\n\t\tActiveVolumes:     map[string]*ActiveVolume{},\n\t\tActiveNetworks:    map[string]*ActiveNetwork{},\n\t\tContainerProbeSvc: containerProbeComposeSvc,\n\t\tStopTimeout:       defaultStopTimeout,\n\t\tapiClient:         apiClient,\n\t\toptions:           options,\n\t\teventCh:           eventCh,\n\t\tprintState:        printState,\n\t\txc:                xc,\n\t\tlogger:            logger,\n\t}\n\n\texe.initVersion()\n\n\terr = exe.initServices()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\texe.initNetworks()\n\n\treturn exe, nil\n}\n\ntype LoaderOptionsFn func(opts *loader.Options)\n\nfunc withProjectName(name string) LoaderOptionsFn {\n\treturn func(opts *loader.Options) {\n\t\topts.Name = name\n\t}\n}\n\nfunc withResolvePaths(resolve bool) LoaderOptionsFn {\n\treturn func(opts *loader.Options) {\n\t\topts.ResolvePaths = resolve\n\t}\n}\n\nfunc withInterpolation(interpolation bool) LoaderOptionsFn {\n\treturn func(opts *loader.Options) {\n\t\topts.SkipInterpolation = !interpolation\n\t}\n}\n\n//loader.WithDiscardEnvFiles\n//loader.WithSkipValidation\n\nfunc (ref *Execution) ProjectName() string {\n\treturn ref.Project.Name\n}\n\nfunc (ref *Execution) ProjectWorkingDir() string {\n\treturn ref.Project.WorkingDir\n}\n\nfunc (ref *Execution) Service(name string) *ServiceInfo {\n\treturn ref.AllServices[name]\n}\n\nfunc (ref *Execution) SelectedHaveImages() bool {\n\tfor _, svc := range ref.AllServices {\n\t\tif svc.Selected && svc.Config.Image == \"\" {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype NetNameInfo struct {\n\tFullName string\n\tAliases  []string\n}\n\nfunc (ref *Execution) ActiveServiceNetworks(svcName string) map[string]NetNameInfo {\n\tnetworks := map[string]NetNameInfo{}\n\n\tif svc, found := ref.AllServices[svcName]; found {\n\t\tfor netKey, netConfig := range svc.Config.Networks {\n\t\t\tif netInfo, found := ref.AllNetworks[netKey]; found && netInfo != nil {\n\t\t\t\tinfo := NetNameInfo{\n\t\t\t\t\tFullName: netInfo.Name,\n\t\t\t\t}\n\n\t\t\t\tif netConfig != nil {\n\t\t\t\t\tinfo.Aliases = netConfig.Aliases\n\t\t\t\t}\n\n\t\t\t\tnetworks[netKey] = info\n\t\t\t}\n\t\t}\n\t}\n\n\treturn networks\n}\n\nfunc (ref *Execution) ActiveNetworkNames() map[string]string {\n\tnetworks := map[string]string{}\n\n\tfor netKey, netInfo := range ref.AllNetworks {\n\t\tif netInfo != nil {\n\t\t\tnetworks[netKey] = netInfo.Name\n\t\t}\n\t}\n\n\treturn networks\n}\n\nfunc (ref *Execution) initServices() error {\n\tfor _, service := range ref.Project.Services {\n\t\tname := service.Name\n\t\tinfo := &ServiceInfo{\n\t\t\tShortName: name,\n\t\t\tName:      fullServiceName(ref.Project.Name, name),\n\t\t\tConfig:    service,\n\t\t}\n\n\t\tif err := ref.Project.WithServices([]string{name},\n\t\t\tfunc(svc types.ServiceConfig) error {\n\t\t\t\tif svc.Name != name {\n\t\t\t\t\tinfo.AllDependencies = append(info.AllDependencies, svc.Name)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif ref.Selectors != nil {\n\t\t\tif ref.Selectors.ServiceAllDeps != \"\" {\n\t\t\t\tif ref.Selectors.ServiceAllDeps == name {\n\t\t\t\t\tinfo.Selected = false\n\t\t\t\t\tif len(info.AllDependencies) > 0 {\n\t\t\t\t\t\tref.Selectors.Includes = map[string]struct{}{}\n\t\t\t\t\t\tfor _, sname := range info.AllDependencies {\n\t\t\t\t\t\t\tref.Selectors.Includes[sname] = struct{}{}\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} else {\n\t\t\tinfo.Selected = true\n\t\t}\n\n\t\tref.AllServices[name] = info\n\t\tref.AllServiceNames[name] = struct{}{}\n\t}\n\n\tif ref.Selectors != nil {\n\t\tfor name := range ref.AllServices {\n\t\t\tif len(ref.Selectors.Includes) > 0 {\n\t\t\t\tif _, found := ref.Selectors.Includes[name]; found {\n\t\t\t\t\tref.AllServices[name].Selected = true\n\t\t\t\t}\n\t\t\t} else if len(ref.Selectors.Excludes) > 0 {\n\t\t\t\tif _, found := ref.Selectors.Excludes[name]; !found {\n\t\t\t\t\tref.AllServices[name].Selected = true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tref.AllServices[name].Selected = true\n\t\t\t}\n\t\t}\n\t}\n\n\tif ref.ContainerProbeSvc != \"\" {\n\t\tref.AllServices[ref.ContainerProbeSvc].Selected = true\n\t\tref.Selectors.Includes[ref.ContainerProbeSvc] = struct{}{}\n\t}\n\n\tref.logger.Debug(\"Execution.initServices: checking ref.AllServices[x].Selected\")\n\tfor shortName, svc := range ref.AllServices {\n\t\tref.logger.Debugf(\"sname=%s/%s name=%s SELECTED?=%v\\n\",\n\t\t\tshortName,\n\t\t\tsvc.ShortName,\n\t\t\tsvc.Name,\n\t\t\tsvc.Selected)\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) initNetworks() {\n\tfor key, network := range ref.Project.Networks {\n\t\tref.AllNetworks[key] = &NetworkInfo{\n\t\t\tName:   fullNetworkName(ref.Project.Name, key, network.Name),\n\t\t\tConfig: network,\n\t\t}\n\t}\n\n\tif _, ok := ref.AllNetworks[defaultNetName]; !ok {\n\t\tref.AllNetworks[defaultNetName] = &NetworkInfo{\n\t\t\tName:   fullNetworkName(ref.Project.Name, defaultNetName, defaultNetName),\n\t\t\tConfig: types.NetworkConfig{},\n\t\t}\n\t}\n}\n\nfunc (ref *Execution) initVersion() {\n\tref.Version = ComposeVerUnknown\n\tfullVersion, ok := ref.Raw[\"version\"].(string)\n\tif !ok {\n\t\treturn\n\t}\n\n\tref.FullVersion = fullVersion\n\tif ref.FullVersion != \"\" {\n\t\tswitch ref.FullVersion[0:1] {\n\t\tcase ComposeVerOneStr:\n\t\t\tref.Version = ComposeVerOne\n\t\tcase ComposeVerTwoStr:\n\t\t\tref.Version = ComposeVerTwo\n\t\tcase ComposeVerThreeStr:\n\t\t\tref.Version = ComposeVerThree\n\t\t}\n\t}\n}\n\nfunc fullServiceName(project, service string) string {\n\t//todo: lower case\n\treturn fmt.Sprintf(\"%s_%s\", project, service)\n}\n\nfunc fullNetworkName(project, networkKey, networkName string) string {\n\t//todo: lower case\n\tfullName := fmt.Sprintf(\"%s_%s\", project, networkKey)\n\tif networkName != \"\" && networkName != defaultNetName {\n\t\tfullName = networkName\n\t}\n\treturn fullName\n}\n\nfunc (ref *Execution) Prepare() error {\n\tref.logger.Debug(\"Execution.Prepare\")\n\n\tif err := ref.PrepareServices(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := ref.CreateNetworks(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := ref.CreateVolumes(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) PrepareServices() error {\n\terrCh := make(chan error, len(ref.AllServices))\n\tvar wg sync.WaitGroup\n\tctx, cancel := context.WithCancel(context.Background())\n\tfor name := range ref.AllServices {\n\t\twg.Add(1)\n\t\tgo func(svcName string) {\n\t\t\tdefer wg.Done()\n\t\t\tref.logger.Debugf(\"Execution.Prepare: service=%s\", svcName)\n\t\t\tif err := ref.PrepareService(ctx, svcName); err != nil {\n\t\t\t\tref.logger.Debugf(\"Execution.Prepare: PrepareService(%s) error - %v\", svcName, err)\n\t\t\t\t//errCh <- fmt.Errorf(\"error preparing service - %s (%s)\", svcName, err.Error())\n\t\t\t\terrCh <- &ServiceError{Service: svcName, Op: \"Execution.PrepareService\", Info: err.Error()}\n\t\t\t\tref.logger.Debugf(\"Execution.Prepare: PrepareService(%s) - CANCEL ALL PREPARE SVC\", svcName)\n\t\t\t\tcancel()\n\t\t\t}\n\t\t}(name)\n\t}\n\n\twg.Wait()\n\tselect {\n\tcase err := <-errCh:\n\t\treturn err\n\tdefault:\n\t\treturn nil\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) PrepareService(ctx context.Context, name string) error {\n\tref.logger.Debugf(\"Execution.PrepareService(%s)\", name)\n\tserviceInfo, ok := ref.AllServices[name]\n\tif !ok {\n\t\treturn fmt.Errorf(\"unknown service - %s\", name)\n\t}\n\n\tservice := serviceInfo.Config\n\tref.logger.Debugf(\"Execution.PrepareService(%s): image=%s\", name, service.Image)\n\n\tif service.Image == \"\" {\n\t\timageName := fmt.Sprintf(\"%s_%s\", ref.Project.Name, name)\n\t\tif ref.BuildImages && service.Build != nil {\n\t\t\tif err := buildImage(ctx, ref.apiClient, ref.BaseComposeDir, imageName, service.Build); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cant build service image - %s\", name)\n\t\t}\n\t} else {\n\t\tfound, err := HasImage(ref.apiClient, service.Image)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif found {\n\t\t\treturn nil\n\t\t}\n\n\t\t//building image as if service.PullPolicy == types.PullPolicyBuild\n\t\t//todo: have an explicit flag for this behavior\n\t\tif ref.BuildImages && service.Build != nil {\n\t\t\tif err := buildImage(ctx, ref.apiClient, ref.BaseComposeDir, service.Image, service.Build); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif ref.PullImages {\n\t\t\t//building image as if\n\t\t\t//service.PullPolicy == types.PullPolicyIfNotPresent || types.PullPolicyMissing\n\t\t\tif err := pullImage(ctx, ref.apiClient, service.Image); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t//note: might need a better image check (already in DS?)\n\t\t\tfound, err := HasImage(ref.apiClient, service.Image)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif !found {\n\t\t\t\tref.logger.Debugf(\"Execution.PrepareService(%s): image=%s - no image and image pull did not pull image\", name, service.Image)\n\t\t\t\treturn ErrNoServiceImage\n\t\t\t}\n\t\t} else {\n\t\t\tref.logger.Debugf(\"Execution.PrepareService(%s): image=%s - no image and image pull is not enabled\", name, service.Image)\n\t\t\treturn ErrNoServiceImage\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) DiscoverResources() error {\n\tref.logger.Debug(\"Execution.DiscoverResources\")\n\t//discover existing containers, volumes, networks for project\n\treturn nil\n}\n\nfunc (ref *Execution) Start() error {\n\tref.logger.Debug(\"Execution.Start\")\n\tif err := ref.StartServices(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) StartServices() error {\n\tref.logger.Debug(\"Execution.StartServices\")\n\n\tif err := ref.Project.WithServices(nil,\n\t\tfunc(service types.ServiceConfig) error {\n\t\t\tref.logger.Debugf(\"Execution.StartServices: service.Name='%s'\", service.Name)\n\t\t\tfullSvcInfo, found := ref.AllServices[service.Name]\n\t\t\tif !found {\n\t\t\t\treturn fmt.Errorf(\"unknown service - %s\", service.Name)\n\t\t\t}\n\n\t\t\tref.logger.Debugf(\"Execution.StartServices: starting service=%s (image=%s)\", service.Name, fullSvcInfo.Config.Image)\n\n\t\t\tif ref.options.SvcStartWait > 0 {\n\t\t\t\tref.logger.Debugf(\"Execution.StartServices: waiting %v seconds before starting service=%s (image=%s)\", ref.options.SvcStartWait, service.Name, fullSvcInfo.Config.Image)\n\t\t\t\ttime.Sleep(time.Duration(ref.options.SvcStartWait) * time.Second)\n\t\t\t}\n\n\t\t\terr := ref.StartService(service.Name)\n\t\t\tif err != nil {\n\t\t\t\tref.logger.Debugf(\"Execution.StartServices: ref.StartService() error = %v\", err)\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}); err != nil {\n\t\tref.logger.Debugf(\"Execution.StartServices: ref.Project.WithServices error = %v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) StartService(name string) error {\n\tref.logger.Debugf(\"Execution.StartService(%s)\", name)\n\n\t_, running := ref.RunningServices[name]\n\tif running {\n\t\tref.logger.Debugf(\"Execution.StartService(%s) - already running\", name)\n\t\treturn nil\n\t}\n\n\t_, pending := ref.PendingServices[name]\n\tif pending {\n\t\tref.logger.Debugf(\"Execution.StartService(%s) - already starting\", name)\n\t\treturn nil\n\t}\n\n\tserviceInfo, found := ref.AllServices[name]\n\tif !found {\n\t\treturn fmt.Errorf(\"unknown service - %s\", name)\n\t}\n\n\tif !serviceInfo.Selected {\n\t\tref.logger.Debugf(\"Execution.StartService(%s) - NOT SELECTED\", name)\n\t\treturn nil\n\t} else {\n\t\tref.logger.Debugf(\"Execution.StartService(%s) - selected\", name)\n\t}\n\n\tservice := serviceInfo.Config\n\tref.PendingServices[name] = struct{}{}\n\n\t//note:\n\t//don't really need this because StartService()\n\t//is called in reverse dependency order\n\tdependencies := service.GetDependencies()\n\tfor _, dep := range dependencies {\n\t\tref.logger.Debugf(\"Execution.StartService(%s): start dependency=%s\", name, dep)\n\t\terr := ref.StartService(dep)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tdelete(ref.PendingServices, name)\n\t//todo: need to refactor to use container.Execution\n\tid, err := startContainer(\n\t\tref.apiClient,\n\t\tref.Project.Name,\n\t\t//serviceInfo.Name, //full service name\n\t\tref.AllServiceNames,\n\t\tref.BaseComposeDir,\n\t\tref.ActiveVolumes,\n\t\tref.ActiveNetworks,\n\t\tserviceInfo)\n\t//service)\n\tif err != nil {\n\t\tref.logger.Debugf(\"Execution.StartService(%s): startContainer() error - %v\", name, err)\n\t\treturn err\n\t}\n\n\t//if fullName != serviceInfo.Name {\n\t//\treturn fmt.Errorf(\"mismatching service name: %s/%s\", fullName, serviceInfo.Name)\n\t//}\n\n\trsvc := &RunningService{\n\t\tName:          serviceInfo.Name,\n\t\tID:            id,\n\t\tContainerName: serviceInfo.ContainerName,\n\t}\n\n\tref.RunningServices[name] = rsvc\n\tref.logger.Debugf(\"Execution.StartService(%s): runningService=%#v\", name, rsvc)\n\n\treturn nil\n}\n\nfunc (ref *Execution) StopServices() error {\n\tref.logger.Debug(\"Execution.StopServices\")\n\n\tfor key := range ref.RunningServices {\n\t\terr := ref.StopService(key)\n\t\tif err != nil && key != ref.ContainerProbeSvc {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (ref *Execution) CleanupServices() error {\n\tref.logger.Debug(\"Execution.CleanupServices\")\n\n\tfor key := range ref.RunningServices {\n\t\terr := ref.CleanupService(key)\n\t\tif err != nil && key != ref.ContainerProbeSvc {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (ref *Execution) StopService(key string) error {\n\tref.logger.Debugf(\"Execution.StopService(%s)\\n\", key)\n\tservice, running := ref.RunningServices[key]\n\tif !running {\n\t\tref.logger.Debugf(\"Execution.StopService(%s) - no running service\", key)\n\t\tif serviceInfo, found := ref.AllServices[key]; found && serviceInfo != nil {\n\t\t\tif !serviceInfo.Selected {\n\t\t\t\tref.logger.Debugf(\"Execution.StopService(%s) - service not selected\", key)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tref.logger.Debugf(\"Execution.StopService(%s): service=%+v\", key, service)\n\n\ttimeout := uint(defaultStopTimeout)\n\tif err := ref.apiClient.StopContainer(service.ID, timeout); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) CleanupService(key string) error {\n\tref.logger.Debugf(\"Execution.CleanupService(%s)\", key)\n\tservice, running := ref.RunningServices[key]\n\tif !running {\n\t\tref.logger.Debugf(\"Execution.CleanupService(%s) - no running service\", key)\n\t\tif serviceInfo, found := ref.AllServices[key]; found && serviceInfo != nil {\n\t\t\tif !serviceInfo.Selected {\n\t\t\t\tref.logger.Debugf(\"Execution.CleanupService(%s) - service not selected\", key)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tref.logger.Debugf(\"Execution.CleanupService(%s): service=%+v\", key, service)\n\n\toptions := dockerapi.RemoveContainerOptions{\n\t\tID:    service.ID,\n\t\tForce: true,\n\t}\n\n\tif err := ref.apiClient.RemoveContainer(options); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nconst (\n\trtLabelAppVersion = \"tmp.version\"\n\trtLabelApp        = \"ds.runtime.container.type\"\n\trtLabelProject    = \"ds.engine.compose.project\"\n\trtLabelService    = \"ds.engine.compose.service\"\n\trtLabelVolumeName = \"ds.engine.compose.volume.name\"\n\trtLabelVolumeKey  = \"ds.engine.compose.volume.key\"\n\trtLabelNetwork    = \"ds.engine.compose.network\"\n)\n\nfunc ExposedPorts(expose types.StringOrNumberList, ports []types.ServicePortConfig) map[dockerapi.Port]struct{} {\n\texposed := map[dockerapi.Port]struct{}{}\n\tfor _, key := range expose {\n\t\texposed[dockerapi.Port(key)] = struct{}{}\n\t}\n\n\tfor _, portInfo := range ports {\n\t\tkey := fmt.Sprintf(\"%d/%s\", portInfo.Target, portInfo.Protocol)\n\t\texposed[dockerapi.Port(key)] = struct{}{}\n\t}\n\n\treturn exposed\n}\n\nfunc MountsFromVolumeConfigs(\n\tbaseComposeDir string,\n\tconfigs []types.ServiceVolumeConfig,\n\ttmpfsConfigs []string,\n\tactiveVolumes map[string]*ActiveVolume) ([]dockerapi.HostMount, error) {\n\tmounts := []dockerapi.HostMount{}\n\tfor _, c := range configs {\n\t\tlog.Debugf(\"compose.MountsFromVolumeConfigs(): volumeConfig=%#v\", c)\n\n\t\tmount := dockerapi.HostMount{\n\t\t\tType:     c.Type,\n\t\t\tTarget:   c.Target,\n\t\t\tReadOnly: c.ReadOnly,\n\t\t}\n\n\t\tif c.Source == \"\" {\n\t\t\tmount.Type = types.VolumeTypeVolume\n\t\t} else {\n\t\t\tsource := c.Source\n\t\t\t_, found := activeVolumes[source]\n\t\t\tif !found {\n\t\t\t\tif !filepath.IsAbs(source) {\n\t\t\t\t\tif strings.HasPrefix(source, \"~/\") {\n\t\t\t\t\t\thd, _ := os.UserHomeDir()\n\t\t\t\t\t\tsource = filepath.Join(hd, source[2:])\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsource = filepath.Join(baseComposeDir, source)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlog.Debugf(\"compose.MountsFromVolumeConfigs(): no active volume (orig.source='%s' source='%s' activeVolumes=%#v)\",\n\t\t\t\t\tc.Source, source, activeVolumes)\n\n\t\t\t\tmount.Type = types.VolumeTypeBind\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"compose.MountsFromVolumeConfigs(): activeVolume='%s'\", source)\n\t\t\t\tmount.Type = types.VolumeTypeVolume\n\t\t\t}\n\n\t\t\tmount.Source = source\n\t\t}\n\n\t\tif c.Bind != nil {\n\t\t\tmount.BindOptions = &dockerapi.BindOptions{\n\t\t\t\tPropagation: c.Bind.Propagation,\n\t\t\t}\n\t\t}\n\n\t\tif c.Volume != nil {\n\t\t\tmount.VolumeOptions = &dockerapi.VolumeOptions{\n\t\t\t\tNoCopy: c.Volume.NoCopy,\n\t\t\t}\n\t\t}\n\n\t\tif c.Tmpfs != nil {\n\t\t\tmount.TempfsOptions = &dockerapi.TempfsOptions{\n\t\t\t\tSizeBytes: c.Tmpfs.Size,\n\t\t\t}\n\t\t}\n\n\t\tmounts = append(mounts, mount)\n\t}\n\n\tfor _, tc := range tmpfsConfigs {\n\t\tmount := dockerapi.HostMount{\n\t\t\tType:   types.VolumeTypeTmpfs,\n\t\t\tTarget: tc,\n\t\t}\n\n\t\tmounts = append(mounts, mount)\n\t}\n\n\treturn mounts, nil\n}\n\nfunc EnvVarsFromService(varMap types.MappingWithEquals, varFiles types.StringList) []string {\n\tvar result []string\n\tfor k, v := range varMap {\n\t\trecord := k\n\t\tif v != nil {\n\t\t\trecord = fmt.Sprintf(\"%s=%s\", record, *v)\n\t\t}\n\n\t\tresult = append(result, record)\n\t}\n\n\tfor _, file := range varFiles {\n\t\tdata, err := os.ReadFile(file)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"compose.EnvVarsFromService: error reading '%s' - %v\", file, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tlines := strings.Split(string(data), \"\\n\")\n\t\tfor _, line := range lines {\n\t\t\tline = strings.TrimSpace(line)\n\t\t\tif len(line) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(line, \"#\") {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tresult = append(result, line)\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunc HasImage(dclient *dockerapi.Client, imageRef string) (bool, error) {\n\tif imageRef == \"\" || imageRef == \".\" || imageRef == \"..\" {\n\t\treturn false, fmt.Errorf(\"bad image reference\")\n\t}\n\n\tinfo, err := dockerutil.HasImage(dclient, imageRef)\n\tif err != nil {\n\t\tif err == dockerapi.ErrNoSuchImage ||\n\t\t\terr == dockerutil.ErrNotFound {\n\t\t\treturn false, nil\n\t\t}\n\n\t\treturn false, err\n\t}\n\n\tlog.Debugf(\"compose.HasImage(%s): image identity - %#v\", imageRef, info)\n\n\tvar repo string\n\tvar tag string\n\tif strings.Contains(imageRef, \"@\") {\n\t\tparts := strings.SplitN(imageRef, \"@\", 2)\n\t\trepo = parts[0]\n\t\ttag = parts[1]\n\t} else {\n\t\tif strings.Contains(imageRef, \":\") {\n\t\t\tparts := strings.SplitN(imageRef, \":\", 2)\n\t\t\trepo = parts[0]\n\t\t\ttag = parts[1]\n\t\t} else {\n\t\t\trepo = imageRef\n\t\t\ttag = \"latest\"\n\t\t}\n\t}\n\n\tfor _, t := range info.ShortTags {\n\t\tif t == tag {\n\t\t\tlog.Debugf(\"compose.HasImage(%s): FOUND IT - %s (%s)\", imageRef, t, repo)\n\t\t\treturn true, nil\n\t\t}\n\t}\n\n\tlog.Debugf(\"compose.HasImage(%s): NOT FOUND IT\", imageRef)\n\treturn false, nil\n}\n\ntype ImageIdentity struct {\n\tID           string\n\tShortTags    []string\n\tRepoTags     []string\n\tShortDigests []string\n\tRepoDigests  []string\n}\n\nfunc ImageToIdentity(info *dockerapi.Image) *ImageIdentity {\n\tresult := &ImageIdentity{\n\t\tID:          info.ID,\n\t\tRepoTags:    info.RepoTags,\n\t\tRepoDigests: info.RepoDigests,\n\t}\n\n\tfor _, tag := range result.RepoTags {\n\t\tparts := strings.Split(tag, \":\")\n\t\tif len(parts) == 2 {\n\t\t\tresult.ShortTags = append(result.ShortTags, parts[1])\n\t\t}\n\t}\n\n\tfor _, digest := range result.RepoDigests {\n\t\tparts := strings.Split(digest, \"@\")\n\t\tif len(parts) == 2 {\n\t\t\tresult.ShortDigests = append(result.ShortDigests, parts[1])\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunc pullImage(ctx context.Context, apiClient *dockerapi.Client, imageRef string) error {\n\tlog.Debugf(\"pullImage(%s)\", imageRef)\n\n\tvar repo string\n\tvar tag string\n\n\tif strings.Contains(imageRef, \"@\") {\n\t\tparts := strings.SplitN(imageRef, \"@\", 2)\n\t\trepo = parts[0]\n\t\ttag = parts[1]\n\t} else {\n\t\tif strings.Contains(imageRef, \":\") {\n\t\t\tparts := strings.SplitN(imageRef, \":\", 2)\n\t\t\trepo = parts[0]\n\t\t\ttag = parts[1]\n\t\t} else {\n\t\t\trepo = imageRef\n\t\t\ttag = \"latest\"\n\t\t}\n\t}\n\n\tvar output bytes.Buffer\n\toptions := dockerapi.PullImageOptions{\n\t\t//Registry:\n\t\tRepository:    repo,\n\t\tTag:           tag,\n\t\tOutputStream:  &output,\n\t\tRawJSONStream: true,\n\t\tContext:       ctx,\n\t}\n\t/*\n\t\t{\"status\":\"\",\"progressDetail\":{\"current\":NUM,\"total\":NUM},progress:\"\",\"id\":\"\"}\n\t*/\n\n\t//TODO: add support for auth\n\tauth := dockerapi.AuthConfiguration{}\n\n\tlog.Debugf(\"pullImage(%s) repo=%s tag=%s\", imageRef, repo, tag)\n\tif err := apiClient.PullImage(options, auth); err != nil {\n\t\tlog.Debugf(\"pullImage: dockerapi.PullImage() error = %v\", err)\n\t\treturn err\n\t}\n\n\tfmt.Println(\"pull output:\")\n\tfmt.Println(output.String())\n\tfmt.Println(\"pull output [DONE]\")\n\n\treturn nil\n}\n\n// TODO: move builder into pkg\nfunc buildImage(ctx context.Context, apiClient *dockerapi.Client, basePath, imageName string, config *types.BuildConfig) error {\n\tlog.Debugf(\"buildImage(%s,%s)\", basePath, imageName)\n\n\tvar output bytes.Buffer\n\tbuildOptions := dockerapi.BuildImageOptions{\n\t\tContext:             ctx,\n\t\tName:                imageName,\n\t\tDockerfile:          config.Dockerfile,\n\t\tOutputStream:        &output,\n\t\tRmTmpContainer:      true,\n\t\tForceRmTmpContainer: true,\n\t\tTarget:              config.Target,\n\t\tRawJSONStream:       true,\n\t}\n\t/*\n\t   {\"stream\":\"\"}\n\t*/\n\n\t//buildOptions.NetworkMode = config.Network\n\n\tfor key, val := range config.Args {\n\t\tif val == nil {\n\t\t\targ := dockerapi.BuildArg{\n\t\t\t\tName: key,\n\t\t\t}\n\n\t\t\tbuildOptions.BuildArgs = append(buildOptions.BuildArgs, arg)\n\t\t\tcontinue\n\t\t}\n\n\t\targ := dockerapi.BuildArg{\n\t\t\tName:  key,\n\t\t\tValue: *val,\n\t\t}\n\t\tbuildOptions.BuildArgs = append(buildOptions.BuildArgs, arg)\n\t}\n\n\tfor key, val := range config.Labels {\n\t\tbuildOptions.Labels[key] = val\n\t}\n\n\tfor _, val := range config.CacheFrom {\n\t\tbuildOptions.CacheFrom = append(buildOptions.CacheFrom, val)\n\t}\n\n\t//TODO: investigate []string to string\n\tif len(config.ExtraHosts) > 0 {\n\t\tbuildOptions.ExtraHosts = config.ExtraHosts[0]\n\t}\n\n\tif strings.HasPrefix(config.Context, \"http://\") || strings.HasPrefix(config.Context, \"https://\") {\n\t\tbuildOptions.Remote = config.Context\n\t} else {\n\t\tcontextDir := config.Context\n\t\tif !strings.HasPrefix(contextDir, \"/\") {\n\t\t\tcontextDir = filepath.Join(basePath, contextDir)\n\t\t}\n\n\t\tif info, err := os.Stat(contextDir); err == nil && info.IsDir() {\n\t\t\tbuildOptions.ContextDir = contextDir\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"invalid context directory - %s\", contextDir)\n\t\t}\n\t}\n\n\tif err := apiClient.BuildImage(buildOptions); err != nil {\n\t\tlog.Debugf(\"buildImage: dockerapi.BuildImage() error = %v\", err)\n\t\treturn err\n\t}\n\n\tfmt.Println(\"build output:\")\n\tfmt.Println(output.String())\n\tfmt.Println(\"build output [DONE]\")\n\n\treturn nil\n}\n\nfunc durationToSeconds(d *types.Duration) int {\n\tif d == nil {\n\t\treturn 0\n\t}\n\n\treturn int(time.Duration(*d).Seconds())\n}\n\nfunc VolumesFrom(serviceNames map[string]struct{},\n\tvolumesFrom []string) []string {\n\tvar vfList []string\n\tfor _, vf := range volumesFrom {\n\t\t//service_name\n\t\t//service_name:ro\n\t\t//container:container_name\n\t\t//container:container_name:rw\n\t\tif strings.HasPrefix(vf, \"container:\") {\n\t\t\tvfList = append(vfList, vf[len(\"container:\"):])\n\t\t}\n\n\t\tif len(serviceNames) > 0 {\n\t\t\tif strings.Contains(vf, \":\") {\n\t\t\t\tparts := strings.Split(vf, \":\")\n\t\t\t\tvf = parts[0]\n\t\t\t}\n\n\t\t\t//todo: check that we get the right names here\n\t\t\tif _, found := serviceNames[vf]; found {\n\t\t\t\tvfList = append(vfList, vf)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn vfList\n}\n\nfunc startContainer(\n\tapiClient *dockerapi.Client,\n\tprojectName string,\n\t//fullServiceName string,\n\tserviceNames map[string]struct{},\n\tbaseComposeDir string,\n\tactiveVolumes map[string]*ActiveVolume,\n\tactiveNetworks map[string]*ActiveNetwork,\n\t//service types.ServiceConfig\n\tserviceInfo *ServiceInfo) (string, error) {\n\tservice := serviceInfo.Config //todo - cleanup\n\tlog.Debugf(\"startContainer(%s/%s/%s)\", serviceInfo.Name, service.Name, service.ContainerName)\n\tlog.Debugf(\"service.Image=%s\", service.Image)\n\tlog.Debugf(\"service.Entrypoint=%s\", service.Entrypoint)\n\tlog.Debugf(\"service.Command=%s\", service.Command)\n\tlog.Debugf(\"service.Ports=%#v\", service.Ports)\n\tlog.Debugf(\"service.Environment=%#v\", service.Environment)\n\n\tlabels := map[string]string{}\n\tfor name, val := range service.Labels {\n\t\tlabels[name] = val\n\t}\n\n\tgetServiceImage := func() string {\n\t\treturn service.Image\n\t\t/*\n\t\t\ttodo: test first with building images\n\t\t\tif service.Image != \"\" {\n\t\t\t\treturn service.Image\n\t\t\t}\n\n\t\t\treturn projectName + \"_\" + service.Name\n\t\t*/\n\t}\n\n\tlabels[rtLabelApp] = rtLabelAppVersion\n\tlabels[rtLabelProject] = projectName\n\tlabels[rtLabelService] = service.Name\n\n\tvar netModeKey string\n\tnetMode := service.NetworkMode\n\tif netMode == \"\" {\n\t\tlog.Debugf(\"startContainer(): activeNetworks[%d]=%+v\",\n\t\t\tlen(activeNetworks), activeNetworks)\n\n\t\tif len(activeNetworks) > 0 {\n\t\t\tserviceNetworks := service.Networks\n\t\t\tlog.Debugf(\"startContainer(): configured service network count - %d\", len(serviceNetworks))\n\t\t\tif len(serviceNetworks) == 0 {\n\t\t\t\tlog.Debug(\"startContainer(): adding default service network config\")\n\t\t\t\tdefaultNet := fmt.Sprintf(\"%s_default\", projectName)\n\t\t\t\tserviceNetworks = map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\tdefaultNet: nil,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor name := range serviceNetworks {\n\t\t\t\tlog.Debugf(\"startContainer(): service network config - %s\", name)\n\t\t\t\tif _, ok := activeNetworks[name]; ok {\n\t\t\t\t\tnetMode = activeNetworks[name].Name\n\t\t\t\t\tnetModeKey = name\n\t\t\t\t\tlog.Debugf(\"startContainer(): found active network config - %s (netMode=%s)\", name, netMode)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif netMode == \"\" {\n\t\t\tnetMode = \"none\"\n\t\t\tlog.Debug(\"startContainer(): default netMode to none\")\n\t\t}\n\t}\n\n\tif (netMode == \"none\" || netMode == \"host\") && len(service.Networks) > 0 {\n\t\tlog.Debugf(\"startContainer(%s): incompatible network_mode and networks config\", service.Name)\n\t\treturn \"\", fmt.Errorf(\"startContainer(%s): incompatible network_mode and networks config\", service.Name)\n\t}\n\n\tnetAliases := []string{\n\t\tservice.Name,\n\t}\n\n\tif len(service.Networks) != 0 {\n\t\tnetConfig, ok := service.Networks[netModeKey]\n\t\tif ok && netConfig != nil {\n\t\t\tnetAliases = append(netAliases, netConfig.Aliases...)\n\t\t}\n\t}\n\n\tendpointsConfig := map[string]*dockerapi.EndpointConfig{\n\t\tnetMode: {\n\t\t\tAliases: netAliases,\n\t\t},\n\t}\n\n\tlog.Debugf(\"startContainer(%s): endpointsConfig=%+v\", service.Name, endpointsConfig)\n\n\tmounts, err := MountsFromVolumeConfigs(baseComposeDir, service.Volumes, service.Tmpfs, activeVolumes)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t//need to make it work with all container name checks\n\tserviceInfo.ContainerName = serviceInfo.Name\n\tif service.ContainerName != \"\" {\n\t\tserviceInfo.ContainerName = service.ContainerName\n\t}\n\n\tenvVars := EnvVarsFromService(service.Environment, service.EnvFile)\n\tcontainerOptions := dockerapi.CreateContainerOptions{\n\t\tName: serviceInfo.ContainerName,\n\t\tConfig: &dockerapi.Config{\n\t\t\tImage:        getServiceImage(),\n\t\t\tEntrypoint:   []string(service.Entrypoint),\n\t\t\tCmd:          []string(service.Command),\n\t\t\tWorkingDir:   service.WorkingDir,\n\t\t\tEnv:          envVars,\n\t\t\tHostname:     service.Hostname,\n\t\t\tDomainname:   service.DomainName,\n\t\t\tDNS:          []string(service.DNS),\n\t\t\tUser:         service.User,\n\t\t\tExposedPorts: ExposedPorts(service.Expose, service.Ports),\n\t\t\tLabels:       labels,\n\t\t\t//Volumes:    - covered by \"volume\" HostConfig.Mounts,\n\t\t\tStopSignal:  service.StopSignal,\n\t\t\tStopTimeout: durationToSeconds(service.StopGracePeriod),\n\t\t\t//Healthcheck *HealthConfig -> service.HealthCheck *HealthCheckConfig - todo\n\t\t\tSecurityOpts: service.SecurityOpt,\n\t\t\t//AttachStdout: true, //todo: revisit\n\t\t\t//AttachStderr: true, //todo: revisit\n\t\t\tAttachStdin:     false,             //for termnal\n\t\t\tTty:             service.Tty,       //for termnal\n\t\t\tOpenStdin:       service.StdinOpen, //for termnal\n\t\t\tStdinOnce:       false,\n\t\t\tNetworkDisabled: netMode == \"none\", //service.NetworkMode == \"disabled\"\n\t\t\tMacAddress:      service.MacAddress,\n\t\t},\n\t\tHostConfig: &dockerapi.HostConfig{\n\t\t\tMounts:         mounts,\n\t\t\tVolumesFrom:    VolumesFrom(serviceNames, service.VolumesFrom),\n\t\t\tVolumeDriver:   service.VolumeDriver,\n\t\t\tReadonlyRootfs: service.ReadOnly,\n\t\t\t//Binds: - covered by \"bind\" HostConfig.Mounts\n\t\t\tCapAdd:       []string(service.CapAdd),\n\t\t\tCapDrop:      []string(service.CapDrop),\n\t\t\tPortBindings: portBindingsFromServicePortConfigs(service.Ports), //map[Port][]PortBinding  -> Ports []ServicePortConfig\n\t\t\t//Links:        service.Links, - not the same links\n\t\t\tDNS:         service.DNS,\n\t\t\tDNSOptions:  service.DNSOpts,\n\t\t\tDNSSearch:   service.DNSSearch,\n\t\t\tExtraHosts:  service.ExtraHosts,\n\t\t\tUsernsMode:  service.UserNSMode,\n\t\t\tNetworkMode: netMode,\n\t\t\tIpcMode:     service.Ipc,\n\t\t\tIsolation:   service.Isolation,\n\t\t\tPidMode:     service.Pid,\n\t\t\t//RestartPolicy: dockerapi.RestartPolicy{Name: service.Restart},//RestartPolicy - todo: handle it the right way\n\t\t\t//Devices: ,//[]Device <- service.Devices\n\t\t\t//LogConfig: ,//LogConfig <- service.Logging\n\t\t\tSecurityOpt:  service.SecurityOpt,\n\t\t\tPrivileged:   service.Privileged,\n\t\t\tCgroupParent: service.CgroupParent,\n\t\t\t//Memory: ,//int64 <- service.MemLimit\n\t\t\t//MemoryReservation: ,//int64\n\t\t\t//KernelMemory: ,//int64\n\t\t\t//MemorySwap: ,//int64\n\t\t\tCPUShares: service.CPUShares,\n\t\t\tCPUSet:    service.CPUSet,\n\t\t\t//Ulimits: ,//[]ULimit <- service.Ulimits\n\t\t\tOomScoreAdj: int(service.OomScoreAdj),\n\t\t\t//MemorySwappiness: ,//*int64\n\t\t\t//OOMKillDisable: ,//*bool\n\t\t\tShmSize: int64(service.ShmSize),\n\t\t\t//Tmpfs: - covered by \"tmpfs\" HostConfig.Mounts\n\t\t\tSysctls:  service.Sysctls,\n\t\t\tCPUCount: service.CPUCount,\n\t\t\t//CPUPercent: ,///int64 <- service.CPUPercent\n\t\t\tRuntime: service.Runtime, //string\n\t\t},\n\t\tNetworkingConfig: &dockerapi.NetworkingConfig{\n\t\t\tEndpointsConfig: endpointsConfig,\n\t\t},\n\t}\n\n\tif service.Init != nil {\n\t\tcontainerOptions.HostConfig.Init = *service.Init\n\t}\n\n\tif service.PidsLimit > 0 {\n\t\tcontainerOptions.HostConfig.PidsLimit = &service.PidsLimit\n\t}\n\n\tif service.Init != nil {\n\t\tcontainerOptions.HostConfig.Init = *service.Init\n\t}\n\n\tlog.Debugf(\"startContainer(%s): creating container...\", service.Name)\n\tcontainerInfo, err := apiClient.CreateContainer(containerOptions)\n\tif err != nil {\n\t\tlog.Debugf(\"startContainer(%s): create container error - %v\", service.Name, err)\n\t\treturn \"\", err\n\t}\n\n\tlog.Debugf(\"startContainer(%s): connecting container to networks...\", service.Name)\n\tfor key, serviceNet := range service.Networks {\n\t\tlog.Debugf(\"startContainer(%s): service network key=%s info=%v\", service.Name, key, serviceNet)\n\t\tnetInfo, found := activeNetworks[key]\n\t\tif !found || netInfo == nil {\n\t\t\tlog.Debugf(\"startContainer(%s): skipping network = '%s'\", service.Name, key)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Debugf(\"startContainer(%s): found network key=%s netInfo=%#v\", service.Name, key, netInfo)\n\n\t\toptions := dockerapi.NetworkConnectionOptions{\n\t\t\tContainer: containerInfo.ID,\n\t\t\tEndpointConfig: &dockerapi.EndpointConfig{\n\t\t\t\tAliases: []string{\n\t\t\t\t\tservice.Name,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\tif serviceNet != nil && len(serviceNet.Aliases) != 0 {\n\t\t\toptions.EndpointConfig.Aliases = append(options.EndpointConfig.Aliases, serviceNet.Aliases...)\n\t\t}\n\n\t\toptions.EndpointConfig.Aliases = append(options.EndpointConfig.Aliases, containerInfo.ID[:12])\n\n\t\tif len(service.Links) > 0 {\n\t\t\tvar networkLinks []string\n\t\t\tfor _, linkInfo := range service.Links {\n\t\t\t\tvar linkTarget string\n\t\t\t\tvar linkName string\n\t\t\t\tparts := strings.Split(linkInfo, \":\")\n\t\t\t\tswitch len(parts) {\n\t\t\t\tcase 1:\n\t\t\t\t\tlinkTarget = parts[0]\n\t\t\t\t\tlinkName = parts[0]\n\t\t\t\tcase 2:\n\t\t\t\t\tlinkTarget = parts[0]\n\t\t\t\t\tlinkName = parts[1]\n\t\t\t\tdefault:\n\t\t\t\t\tlog.Debugf(\"startContainer(%s): service.Links: malformed link - %s\", service.Name, linkInfo)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tnetworkLinks = append(networkLinks, fmt.Sprintf(\"%s:%s\", linkTarget, linkName))\n\t\t\t}\n\n\t\t\toptions.EndpointConfig.Links = networkLinks\n\t\t}\n\n\t\tif err := apiClient.ConnectNetwork(netInfo.ID, options); err != nil {\n\t\t\tlog.Debugf(\"startContainer(%s): container network connect error - %v\", service.Name, err)\n\t\t\tlog.Debugf(\"startContainer(%s): netInfo.ID=%s options=%#v\", service.Name, netInfo.ID, options)\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\n\tlog.Debugf(\"startContainer(%s): starting container id='%s' cn='%s'\",\n\t\tservice.Name, containerInfo.ID, serviceInfo.ContainerName)\n\n\tif err := apiClient.StartContainer(containerInfo.ID, nil); err != nil {\n\t\tlog.Debugf(\"startContainer(%s): start container error - %v\", service.Name, err)\n\t\treturn \"\", err\n\t}\n\n\treturn containerInfo.ID, nil\n}\n\nfunc portBindingsFromServicePortConfigs(configs []types.ServicePortConfig) map[dockerapi.Port][]dockerapi.PortBinding {\n\tresult := map[dockerapi.Port][]dockerapi.PortBinding{}\n\tfor _, config := range configs {\n\t\tvar bindings []dockerapi.PortBinding\n\t\tvar binding dockerapi.PortBinding\n\n\t\tif config.Published > 0 {\n\t\t\tbinding.HostPort = fmt.Sprint(config.Published)\n\t\t}\n\n\t\tportKey := dockerapi.Port(fmt.Sprintf(\"%d/%s\", config.Target, config.Protocol))\n\t\tresult[portKey] = append(bindings, binding)\n\t}\n\n\treturn result\n}\n\nfunc createVolume(apiClient *dockerapi.Client, projectName, volKey, volFullName string, config types.VolumeConfig) (string, error) {\n\tlabels := config.Labels\n\tif labels == nil {\n\t\tlabels = map[string]string{}\n\t}\n\n\tlabels[rtLabelApp] = rtLabelAppVersion\n\tlabels[rtLabelProject] = projectName\n\tlabels[rtLabelVolumeName] = volFullName\n\tlabels[rtLabelVolumeKey] = volKey\n\n\tvolumeOptions := dockerapi.CreateVolumeOptions{\n\t\tName:       volFullName, //already includes the project prefix\n\t\tDriver:     config.Driver,\n\t\tDriverOpts: config.DriverOpts,\n\t\tLabels:     labels,\n\t}\n\n\tlog.Debugf(\"createVolume(%s, %s, %s) volumeOptions=%#v\", projectName, volKey, volFullName, volumeOptions)\n\tvolumeInfo, err := apiClient.CreateVolume(volumeOptions)\n\tif err != nil {\n\t\tlog.Debugf(\"apiClient.CreateVolume() error = %v\", err)\n\t\treturn \"\", err\n\t}\n\n\treturn volumeInfo.Name, nil\n}\n\nfunc (ref *Execution) CreateVolumes() error {\n\tprojectName := strings.Trim(ref.Project.Name, \"-_\")\n\n\tfor key, volume := range ref.Project.Volumes {\n\t\tname := fmt.Sprintf(\"%s_%s\", projectName, key)\n\t\tref.logger.Debugf(\"CreateVolumes: key=%s gen.Name=%s volume.Name=%s\", key, name, volume.Name)\n\n\t\tif volume.Name != \"\" {\n\t\t\tname = volume.Name\n\t\t}\n\n\t\tid, err := createVolume(ref.apiClient, projectName, key, name, volume)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tref.ActiveVolumes[key] = &ActiveVolume{\n\t\t\tShortName: key,\n\t\t\tFullName:  name,\n\t\t\tID:        id,\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) DeleteVolumes() error {\n\tfor key, volume := range ref.ActiveVolumes {\n\t\tref.logger.Debugf(\"DeleteVolumes: key/name=%s ID=%s\", key, volume.ID)\n\n\t\terr := deleteVolume(ref.apiClient, volume.ID)\n\t\tif err != nil && key != ref.ContainerProbeSvc {\n\t\t\treturn err\n\t\t}\n\n\t\tdelete(ref.ActiveVolumes, key)\n\t}\n\n\treturn nil\n}\n\nfunc deleteVolume(apiClient *dockerapi.Client, id string) error {\n\tremoveOptions := dockerapi.RemoveVolumeOptions{\n\t\tName:  id,\n\t\tForce: true,\n\t}\n\n\terr := apiClient.RemoveVolumeWithOptions(removeOptions)\n\tif err != nil {\n\t\tlog.Debugf(\"dclient.RemoveVolumeWithOptions() error = %v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nconst defaultNetName = \"default\"\n\nfunc (ref *Execution) CreateNetworks() error {\n\tref.logger.Debugf(\"Execution.CreateNetworks\")\n\tprojectName := strings.Trim(ref.Project.Name, \"-_\")\n\n\tfor key, networkInfo := range ref.AllNetworks {\n\t\tnetwork := networkInfo.Config\n\t\tref.logger.Debugf(\"Execution.CreateNetworks: key=%s name=%s\", key, network.Name)\n\n\t\tcreated, id, err := createNetwork(ref.apiClient, projectName, key, networkInfo.Name, network)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tref.ActiveNetworks[key] = &ActiveNetwork{\n\t\t\tName:    networkInfo.Name,\n\t\t\tID:      id,\n\t\t\tCreated: created,\n\t\t}\n\t}\n\n\t//need to create the 'default' network if it's not created yet\n\tif _, ok := ref.ActiveNetworks[defaultNetName]; !ok {\n\t\t//var defaultNetConfig types.NetworkConfig\n\n\t\tdefaultNetworkInfo := ref.AllNetworks[defaultNetName]\n\n\t\tcreated, id, err := createNetwork(ref.apiClient, projectName, defaultNetName, defaultNetworkInfo.Name, defaultNetworkInfo.Config)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tref.ActiveNetworks[defaultNetName] = &ActiveNetwork{\n\t\t\tName:    defaultNetworkInfo.Name,\n\t\t\tID:      id,\n\t\t\tCreated: created,\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc createNetwork(apiClient *dockerapi.Client, projectName, name, fullName string, config types.NetworkConfig) (bool, string, error) {\n\tlog.Debugf(\"createNetwork(%s,%s)\", projectName, name)\n\n\t//fullName := fullNetworkName(projectName, name, config.Name)\n\t//fullName := fmt.Sprintf(\"%s_%s\", projectName, name)\n\t//if config.Name != \"\" && config.Name != defaultNetName {\n\t//\tfullName = config.Name\n\t//}\n\n\tlabels := map[string]string{\n\t\trtLabelApp:     rtLabelAppVersion,\n\t\trtLabelProject: projectName,\n\t\trtLabelNetwork: name,\n\t}\n\n\tdriverOpts := map[string]interface{}{}\n\tfor k, v := range config.DriverOpts {\n\t\tdriverOpts[k] = v\n\t}\n\n\toptions := dockerapi.CreateNetworkOptions{\n\t\tName:       fullName,\n\t\tDriver:     config.Driver,\n\t\tOptions:    driverOpts,\n\t\tLabels:     labels,\n\t\tInternal:   config.Internal,\n\t\tAttachable: config.Attachable,\n\t}\n\n\tif options.Driver == \"\" {\n\t\toptions.Driver = \"bridge\"\n\t}\n\n\tmustFind := false\n\tif config.External.External {\n\t\tmustFind = true\n\t\tfullName = name\n\t\tif config.External.Name != \"\" {\n\t\t\tfullName = config.External.Name\n\t\t}\n\t}\n\n\t//not using config.Ipam for now\n\n\tfilter := dockerapi.NetworkFilterOpts{\n\t\t\"name\": map[string]bool{\n\t\t\tfullName: true,\n\t\t},\n\t}\n\n\tlog.Debugf(\"createNetwork(%s,%s): lookup '%s'\", projectName, name, fullName)\n\n\tnetworkList, err := apiClient.FilteredListNetworks(filter)\n\tif err != nil {\n\t\tlog.Debugf(\"listNetworks(%s): dockerapi.FilteredListNetworks() error = %v\", name, err)\n\t\treturn false, \"\", err\n\t}\n\n\tif len(networkList) == 0 || networkList[0].Name != fullName {\n\t\tif mustFind {\n\t\t\treturn false, \"\", fmt.Errorf(\"no external network - %s\", fullName)\n\t\t}\n\n\t\tlog.Debugf(\"createNetwork(%s,%s): create '%s'\", projectName, name, options.Name)\n\t\tnetworkInfo, err := apiClient.CreateNetwork(options)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"apiClient.CreateNetwork() error = %v\", err)\n\t\t\treturn false, \"\", err\n\t\t}\n\n\t\treturn true, networkInfo.ID, nil\n\t}\n\n\tlog.Debugf(\"createNetwork(%s,%s): found network '%s' (id=%s)\", projectName, name, fullName, networkList[0].ID)\n\treturn false, networkList[0].ID, nil\n}\n\nfunc (ref *Execution) DeleteNetworks() error {\n\tfor key, network := range ref.ActiveNetworks {\n\t\tref.logger.Debugf(\"DeleteNetworks: key=%s name=%s ID=%s\", key, network.Name, network.ID)\n\t\tif !network.Created {\n\t\t\tref.logger.Debug(\"DeleteNetworks: skipping...\")\n\t\t\tcontinue\n\t\t}\n\n\t\terr := deleteNetwork(ref.apiClient, network.ID)\n\t\tif err != nil && key != ref.ContainerProbeSvc {\n\t\t\treturn err\n\t\t}\n\n\t\tdelete(ref.ActiveNetworks, key)\n\t}\n\n\treturn nil\n}\n\nfunc deleteNetwork(apiClient *dockerapi.Client, id string) error {\n\terr := apiClient.RemoveNetwork(id)\n\tif err != nil {\n\t\tlog.Debugf(\"dclient.RemoveNetwork() error = %v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc dumpComposeJSON(data *types.Project) {\n\tif pretty, err := json.MarshalIndent(data, \"\", \"  \"); err == nil {\n\t\tfmt.Printf(\"%s\\n\", string(pretty))\n\t}\n}\n\nfunc dumpRawJSON(data map[string]interface{}) {\n\tif pretty, err := json.MarshalIndent(data, \"\", \"  \"); err == nil {\n\t\tfmt.Printf(\"%s\\n\", string(pretty))\n\t}\n}\n\nfunc dumpConfig(config *types.Config) {\n\tfmt.Printf(\"\\n\\n\")\n\tfmt.Printf(\"types.Config:\\n%#v\\n\", config)\n}\n\nfunc (ref *Execution) Stop() error {\n\tref.logger.Debugf(\"Execution.Stop\")\n\n\tif err := ref.StopServices(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (ref *Execution) Cleanup() error {\n\tref.logger.Debugf(\"Execution.Cleanup\")\n\t//todo:\n\t//pass 'force'/'all' param to clean the spec resources\n\t//not created by this instance (except external resources)\n\n\tif err := ref.CleanupServices(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := ref.DeleteVolumes(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := ref.DeleteNetworks(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/config/config.go",
    "content": "package config\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\n// AppOptionsFilename is the default name for the app configs\nconst AppOptionsFilename = \"slim.config.json\"\n\n// AppOptions provides a set of global application parameters and command-specific defaults\n// AppOptions values override the default flag values if they are set\n// AppOptions is loaded from the \"slim.config.json\" file stored in the state path directory\ntype AppOptions struct {\n\tGlobal *GlobalAppOptions `json:\"global,omitempty\"`\n}\n\n// GlobalAppOptions provides a set of global application parameters\ntype GlobalAppOptions struct {\n\tNoColor      *bool   `json:\"no_color,omitempty\"`\n\tDebug        *bool   `json:\"debug,omitempty\"`\n\tVerbose      *bool   `json:\"verbose,omitempty\"`\n\tQuiet        *bool   `json:\"quiet,omitempty\"`\n\tOutputFormat *string `json:\"output_format,omitempty\"`\n\tLogLevel     *string `json:\"log_level,omitempty\"`\n\tLog          *string `json:\"log,omitempty\"`\n\tLogFormat    *string `json:\"log_format,omitempty\"`\n\tUseTLS       *bool   `json:\"tls,omitempty\"`\n\tVerifyTLS    *bool   `json:\"tls_verify,omitempty\"`\n\tTLSCertPath  *string `json:\"tls_cert_path,omitempty\"`\n\tAPIVersion   *string `json:\"api_version,omitempty\"`\n\tHost         *string `json:\"host,omitempty\"`\n\tArchiveState *string `json:\"archive_state,omitempty\"`\n}\n\nfunc NewAppOptionsFromFile(dir string) (*AppOptions, error) {\n\tfilePath := filepath.Join(dir, AppOptionsFilename)\n\tvar result AppOptions\n\terr := fsutil.LoadStructFromFile(filePath, &result)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, nil\n\t\t}\n\n\t\tif err == fsutil.ErrNoFileData {\n\t\t\treturn nil, nil\n\t\t}\n\n\t\treturn nil, err\n\t}\n\n\treturn &result, nil\n}\n\n// TODO: robustly parse `--network`/Network at the CLI level to avoid ambiguity.\n// https://github.com/docker/cli/blob/cf8c4bab6477ef62122bda875f80d8472005010d/opts/network.go#L35\n\n// ContainerOverrides provides a set of container field overrides\n// It can also be used to update the image instructions when\n// the \"image-overrides\" flag is provided\ntype ContainerOverrides struct {\n\tUser            string\n\tEntrypoint      []string\n\tClearEntrypoint bool\n\tCmd             []string\n\tClearCmd        bool\n\tWorkdir         string\n\tEnv             []string\n\tHostname        string\n\tNetwork         string\n\tExposedPorts    map[docker.Port]struct{}\n\tVolumes         map[string]struct{}\n\tLabels          map[string]string\n}\n\n// ImageNewInstructions provides a set new image instructions\ntype ImageNewInstructions struct {\n\tEntrypoint         []string\n\tClearEntrypoint    bool\n\tCmd                []string\n\tClearCmd           bool\n\tWorkdir            string\n\tEnv                []string\n\tVolumes            map[string]struct{}\n\tExposedPorts       map[docker.Port]struct{}\n\tLabels             map[string]string\n\tRemoveEnvs         map[string]struct{}\n\tRemoveVolumes      map[string]struct{}\n\tRemoveExposedPorts map[docker.Port]struct{}\n\tRemoveLabels       map[string]struct{}\n}\n\n// ContainerBuildOptions provides the options to use when\n// building container images from Dockerfiles\ntype ContainerBuildOptions struct {\n\tDockerfile        string\n\tDockerfileContext string\n\tTag               string\n\tExtraHosts        string\n\tBuildArgs         []CBOBuildArg\n\tLabels            map[string]string\n\tCacheFrom         []string\n\tTarget            string\n\tNetworkMode       string\n}\n\ntype CBOBuildArg struct {\n\tName  string\n\tValue string\n}\n\n// ContainerRunOptions provides the options to use running a container\ntype ContainerRunOptions struct {\n\tHostConfig *docker.HostConfig\n\t//Explicit overrides for the base and host config fields\n\t//Host config field override are applied\n\t//on top of the fields in the HostConfig struct if it's provided (volume mounts are merged though)\n\tRuntime      string\n\tSysctlParams map[string]string\n\tShmSize      int64\n}\n\n// VolumeMount provides the volume mount configuration information\ntype VolumeMount struct {\n\tSource      string\n\tDestination string\n\tOptions     string\n}\n\nconst (\n\tProtoHTTP   = \"http\"\n\tProtoHTTPS  = \"https\"\n\tProtoHTTP2  = \"http2\"\n\tProtoHTTP2C = \"http2c\"\n\tProtoWS     = \"ws\"\n\tProtoWSS    = \"wss\"\n)\n\nfunc IsProto(value string) bool {\n\tswitch strings.ToLower(value) {\n\tcase ProtoHTTP,\n\t\tProtoHTTPS,\n\t\tProtoHTTP2,\n\t\tProtoHTTP2C,\n\t\tProtoWS,\n\t\tProtoWSS:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// HTTPProbeCmd provides the HTTP probe parameters\ntype HTTPProbeCmd struct {\n\tMethod   string   `json:\"method\"`\n\tResource string   `json:\"resource\"`\n\tPort     int      `json:\"port\"`\n\tProtocol string   `json:\"protocol\"`\n\tHeaders  []string `json:\"headers\"`\n\tBody     string   `json:\"body\"`\n\tBodyFile string   `json:\"body_file\"`\n\tUsername string   `json:\"username\"`\n\tPassword string   `json:\"password\"`\n\tCrawl    bool     `json:\"crawl\"`\n\n\tFastCGI *FastCGIProbeWrapperConfig `json:\"fastcgi,omitempty\"`\n}\n\n// FastCGI permits fine-grained configuration of the fastcgi RoundTripper.\ntype FastCGIProbeWrapperConfig struct {\n\t// Root is the fastcgi root directory.\n\t// Defaults to the root directory of the container.\n\tRoot string `json:\"root,omitempty\"`\n\n\t// The path in the URL will be split into two, with the first piece ending\n\t// with the value of SplitPath. The first piece will be assumed as the\n\t// actual resource (CGI script) name, and the second piece will be set to\n\t// PATH_INFO for the CGI script to use.\n\tSplitPath []string `json:\"split_path,omitempty\"`\n\n\t// Extra environment variables.\n\tEnvVars map[string]string `json:\"env,omitempty\"`\n\n\t// The duration used to set a deadline when connecting to an upstream.\n\tDialTimeout time.Duration `json:\"dial_timeout,omitempty\"`\n\n\t// The duration used to set a deadline when reading from the FastCGI server.\n\tReadTimeout time.Duration `json:\"read_timeout,omitempty\"`\n\n\t// The duration used to set a deadline when sending to the FastCGI server.\n\tWriteTimeout time.Duration `json:\"write_timeout,omitempty\"`\n}\n\n// HTTPProbeCmds is a list of HTTPProbeCmd instances\ntype HTTPProbeCmds struct {\n\tCommands []HTTPProbeCmd `json:\"commands\"`\n}\n\n// DockerClient provides Docker client parameters\ntype DockerClient struct {\n\tUseTLS      bool\n\tVerifyTLS   bool\n\tTLSCertPath string\n\tHost        string\n\tAPIVersion  string\n\tEnv         map[string]string\n}\n\nconst (\n\tCAMContainerProbe = \"container-probe\"\n\tCAMProbe          = \"probe\"\n\tCAMEnter          = \"enter\"\n\tCAMTimeout        = \"timeout\"\n\tCAMSignal         = \"signal\"\n\tCAMExec           = \"exec\"\n\tCAMHostExec       = \"host-exec\"\n\tCAMAppExit        = \"app-exit\"\n)\n\n// ContinueAfter provides the command execution mode parameters\ntype ContinueAfter struct {\n\tMode         string\n\tTimeout      time.Duration\n\tContinueChan <-chan struct{}\n}\n\ntype HTTPProbeOptions struct {\n\tDo            bool\n\tFull          bool\n\tExitOnFailure bool\n\n\tCmds  []HTTPProbeCmd\n\tPorts []uint16\n\n\tStartWait  int\n\tRetryCount int\n\tRetryWait  int\n\n\tCrawlMaxDepth       int\n\tCrawlMaxPageCount   int\n\tCrawlConcurrency    int\n\tCrawlConcurrencyMax int\n\n\tAPISpecs     []string\n\tAPISpecFiles []string\n\n\tProxyEndpoint string\n\tProxyPort     int\n}\n\ntype AppNodejsInspectOptions struct {\n\tIncludePackages []string\n\tNextOpts        NodejsWebFrameworkInspectOptions\n\tNuxtOpts        NodejsWebFrameworkInspectOptions\n}\n\ntype NodejsWebFrameworkInspectOptions struct {\n\tIncludeAppDir         bool\n\tIncludeBuildDir       bool\n\tIncludeDistDir        bool\n\tIncludeStaticDir      bool\n\tIncludeNodeModulesDir bool\n}\n\ntype KubernetesOptions struct {\n\tTarget         KubernetesTarget\n\tTargetOverride KubernetesTargetOverride\n\n\tManifests  []string\n\tKubeconfig string\n}\n\ntype KubernetesTarget struct {\n\tWorkload  string\n\tNamespace string\n\tContainer string\n}\n\nfunc (t *KubernetesTarget) WorkloadName() (string, error) {\n\tparts := strings.Split(t.Workload, \"/\")\n\tif len(parts) != 2 || len(parts[1]) == 0 {\n\t\treturn \"\", errors.New(\"malformed Kubernetes workload name\")\n\t}\n\n\treturn parts[1], nil\n}\n\ntype KubernetesTargetOverride struct {\n\tImage string\n}\n\nfunc (ko KubernetesOptions) HasTargetSet() bool {\n\treturn ko.Target.Workload != \"\"\n}\n"
  },
  {
    "path": "pkg/app/master/container/execution.go",
    "content": "package container\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\t\"github.com/moby/term\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\n//Custom I/O for terminal later\n\nconst (\n\tContainerNamePat = \"ds.run_%v_%v\"\n)\n\ntype ovars = app.OutVars\n\ntype ExecutionState string\n\nconst (\n\tXSNone        ExecutionState = \"xs.none\"\n\tXSCreated                    = \"xs.created\"\n\tXSStarted                    = \"xs.started\"\n\tXSStopping                   = \"xs.stopping\"\n\tXSStopped                    = \"xs.stopped\"\n\tXSRemoved                    = \"xs.removed\"\n\tXSExited                     = \"xs.exited\"\n\tXSExitedCrash                = \"xs.exited.crash\"\n\tXSError                      = \"xs.error\"\n)\n\ntype ExecutionEvent string\n\nconst (\n\tXECreated     ExecutionEvent = \"xe.container.created\"\n\tXEStarted                    = \"xe.container.started\"\n\tXEStopping                   = \"xe.container.stopping\"\n\tXEStopped                    = \"xe.container.stopped\"\n\tXERemoved                    = \"xe.container.removed\"\n\tXEExited                     = \"xe.container.exited\"\n\tXEExitedCrash                = \"xe.container.exited.crash\"\n\tXEAPIError                   = \"xe.api.error\"\n\tXEInterrupt                  = \"xe.interrupt\"\n)\n\ntype ExecutionEvenInfo struct {\n\tEvent ExecutionEvent\n\tData  map[string]string\n}\n\ntype VolumeInfo struct {\n\tSource      string\n\tDestination string\n\tOptions     string\n}\n\ntype ExecutionOptions struct {\n\tContainerName string\n\tEntrypoint    []string\n\tCmd           []string\n\tPublishPorts  map[dockerapi.Port][]dockerapi.PortBinding\n\tEnvVars       []string\n\tVolumes       []config.VolumeMount\n\tLiveLogs      bool\n\tTerminal      bool\n\tIO            ExecutionIO\n}\n\ntype ExecutionIO struct {\n\tInput  io.Reader\n\tOutput io.Writer\n\tError  io.Writer\n}\n\ntype Execution struct {\n\tContainerInfo *dockerapi.Container\n\tContainerName string\n\tContainerID   string\n\tState         ExecutionState\n\tCrashed       bool\n\tStopTimeout   uint\n\n\t/// the following fields are forwarded to dockerapi.HostConfig and take\n\t/// the same parameters as docker's `--pid`, `--network` and `--ipc` CLI\n\t/// flags\n\tPidMode     string\n\tNetworkMode string\n\tIpcMode     string\n\n\timageRef          string\n\tAPIClient         *dockerapi.Client\n\toptions           *ExecutionOptions\n\tcleanupOnSysExit  bool\n\teventCh           chan *ExecutionEvenInfo\n\tprintState        bool\n\tdockerEventCh     chan *dockerapi.APIEvents\n\tdockerEventStopCh chan struct{}\n\txc                *app.ExecutionContext\n\tlogger            *log.Entry\n\tterminalExitChan  chan error\n\ttermFd            uintptr\n\tisInterrupted     bool\n}\n\nconst defaultStopTimeout = 7 //7 seconds\n\nfunc NewExecution(\n\txc *app.ExecutionContext,\n\tlogger *log.Entry,\n\tclient *dockerapi.Client,\n\timageRef string,\n\toptions *ExecutionOptions,\n\teventCh chan *ExecutionEvenInfo,\n\tcleanupOnSysExit bool,\n\tprintState bool) (*Execution, error) {\n\tif logger != nil {\n\t\tlogger = logger.WithFields(log.Fields{\"com\": \"container.execution\"})\n\t}\n\n\texe := &Execution{\n\t\tState:             XSNone,\n\t\tStopTimeout:       defaultStopTimeout,\n\t\timageRef:          imageRef,\n\t\tAPIClient:         client,\n\t\toptions:           options,\n\t\teventCh:           eventCh,\n\t\tcleanupOnSysExit:  cleanupOnSysExit,\n\t\tprintState:        printState,\n\t\txc:                xc,\n\t\tlogger:            logger,\n\t\tdockerEventCh:     make(chan *dockerapi.APIEvents),\n\t\tdockerEventStopCh: make(chan struct{}),\n\t}\n\n\t//allow liveLogs only if terminal is not enabled\n\tif exe.options != nil && exe.options.Terminal {\n\t\texe.options.LiveLogs = false\n\t}\n\n\treturn exe, nil\n}\n\n// Start starts a new container execution\nfunc (ref *Execution) Start() error {\n\tif ref.options.ContainerName != \"\" {\n\t\t//we have an explicitly provided container name to use\n\t\t//ideally we first validate that this name can be used...\n\t\tref.ContainerName = ref.options.ContainerName\n\t} else {\n\t\tref.ContainerName = fmt.Sprintf(ContainerNamePat, os.Getpid(), time.Now().UTC().Format(\"20060102150405\"))\n\t}\n\n\thostConfig := &dockerapi.HostConfig{\n\t\tNetworkMode: ref.NetworkMode,\n\t\tPidMode:     ref.PidMode,\n\t\tIpcMode:     ref.IpcMode,\n\t}\n\n\tcontainerOptions := dockerapi.CreateContainerOptions{\n\t\tName: ref.ContainerName,\n\t\tConfig: &dockerapi.Config{\n\t\t\tImage: ref.imageRef,\n\t\t},\n\t\tHostConfig: hostConfig,\n\t}\n\n\tif ref.options != nil {\n\t\tif len(ref.options.Entrypoint) > 0 {\n\t\t\tcontainerOptions.Config.Entrypoint = ref.options.Entrypoint\n\t\t}\n\n\t\tif len(ref.options.Cmd) > 0 {\n\t\t\tcontainerOptions.Config.Cmd = ref.options.Cmd\n\t\t}\n\n\t\tif len(ref.options.EnvVars) > 0 {\n\t\t\tcontainerOptions.Config.Env = ref.options.EnvVars\n\t\t}\n\n\t\tif len(ref.options.Volumes) > 0 {\n\t\t\tmounts := []dockerapi.HostMount{}\n\t\t\tfor _, vol := range ref.options.Volumes {\n\t\t\t\tmount := dockerapi.HostMount{\n\t\t\t\t\tTarget: vol.Destination,\n\t\t\t\t}\n\n\t\t\t\tif vol.Source == \"\" {\n\t\t\t\t\tmount.Type = \"volume\"\n\t\t\t\t} else {\n\t\t\t\t\tif strings.HasPrefix(vol.Source, \"/\") {\n\t\t\t\t\t\tmount.Source = vol.Source\n\t\t\t\t\t\tmount.Type = \"bind\"\n\t\t\t\t\t} else if strings.HasPrefix(vol.Source, \"~/\") {\n\t\t\t\t\t\thd, _ := os.UserHomeDir()\n\t\t\t\t\t\tmount.Source = filepath.Join(hd, vol.Source[2:])\n\t\t\t\t\t\tmount.Type = \"bind\"\n\t\t\t\t\t} else if strings.HasPrefix(vol.Source, \"./\") ||\n\t\t\t\t\t\tstrings.HasPrefix(vol.Source, \"../\") ||\n\t\t\t\t\t\t(vol.Source == \"..\") ||\n\t\t\t\t\t\t(vol.Source == \".\") {\n\t\t\t\t\t\tmount.Source, _ = filepath.Abs(vol.Source)\n\t\t\t\t\t\tmount.Type = \"bind\"\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//todo: list volumes and check vol.Source instead of defaulting to named volume\n\t\t\t\t\t\tmount.Source = vol.Source\n\t\t\t\t\t\tmount.Type = \"volume\"\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif vol.Options == \"ro\" {\n\t\t\t\t\tmount.ReadOnly = true\n\t\t\t\t}\n\n\t\t\t\tmounts = append(mounts, mount)\n\t\t\t}\n\t\t\tcontainerOptions.HostConfig.Mounts = mounts\n\t\t}\n\n\t\tif len(ref.options.PublishPorts) > 0 {\n\t\t\tcontainerOptions.HostConfig.PortBindings = ref.options.PublishPorts\n\t\t}\n\t}\n\n\tif ref.options != nil && ref.options.Terminal {\n\t\tfmt.Println(\"adding more container params for Terminal\")\n\t\tcontainerOptions.Config.OpenStdin = true\n\t\t//containerOptions.Config.StdinOnce = true\n\t\tcontainerOptions.Config.AttachStdin = true\n\t\tcontainerOptions.Config.Tty = true\n\t}\n\n\tcontainerInfo, err := ref.APIClient.CreateContainer(containerOptions)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tref.State = XSCreated\n\n\tif ref.ContainerName != containerInfo.Name {\n\t\tif ref.logger != nil {\n\t\t\tref.logger.Debugf(\"RunContainer: Container name mismatch expected=%v got=%v\",\n\t\t\t\tref.ContainerName, ref.ContainerName)\n\t\t}\n\t}\n\n\tref.ContainerID = containerInfo.ID\n\n\tif ref.printState && ref.xc != nil {\n\t\tref.xc.Out.Info(\"container\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"created\",\n\t\t\t\t\"name\":   ref.ContainerName,\n\t\t\t\t\"id\":     ref.ContainerID,\n\t\t\t})\n\n\t\tif ref.logger != nil {\n\t\t\tref.logger.Tracef(\"container created: name=%s id=%s\",\n\t\t\t\tref.ContainerName, ref.ContainerID)\n\t\t}\n\t}\n\n\tif ref.eventCh != nil {\n\t\tref.eventCh <- &ExecutionEvenInfo{\n\t\t\tEvent: XECreated,\n\t\t}\n\t}\n\n\tgo ref.monitorContainerExitSync()\n\n\tif ref.cleanupOnSysExit {\n\t\tgo ref.monitorSysExitSync()\n\t}\n\n\tif ref.options != nil {\n\t\tif ref.options.Terminal {\n\t\t\tvar oldState *term.State\n\t\t\tvar isTerminal bool\n\t\t\tref.termFd, isTerminal = term.GetFdInfo(os.Stdout)\n\t\t\tif !isTerminal {\n\t\t\t\treturn errors.New(\"not a terminal\")\n\t\t\t}\n\n\t\t\toldState, err = term.SetRawTerminal(ref.termFd)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tdefer term.RestoreTerminal(ref.termFd, oldState)\n\n\t\t\tref.terminalExitChan = make(chan error)\n\n\t\t\tgo ref.startTerminal()\n\t\t} else if ref.options.LiveLogs {\n\t\t\tgo ref.startLiveLogs()\n\t\t}\n\t}\n\n\tif err := ref.APIClient.StartContainer(ref.ContainerID, nil); err != nil {\n\t\tref.State = \"error\"\n\t\treturn err\n\t}\n\n\tref.State = XSStarted\n\n\tif ref.ContainerInfo, err = ref.APIClient.InspectContainer(ref.ContainerID); err != nil {\n\t\tref.State = XSError\n\t\tif ref.eventCh != nil {\n\t\t\tref.eventCh <- &ExecutionEvenInfo{\n\t\t\t\tEvent: XEAPIError,\n\t\t\t\tData: map[string]string{\n\t\t\t\t\t\"error\": err.Error(),\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\treturn err\n\t}\n\n\tif ref.printState && ref.xc != nil {\n\t\tref.xc.Out.Info(\"container\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"started\",\n\t\t\t\t\"name\":   containerInfo.Name,\n\t\t\t\t\"id\":     ref.ContainerID,\n\t\t\t})\n\n\t\tif ref.logger != nil {\n\t\t\tref.logger.Tracef(\"container started = name=%s id=%s\\n\",\n\t\t\t\tref.ContainerName, ref.ContainerID)\n\t\t}\n\t}\n\n\tif ref.eventCh != nil {\n\t\tref.eventCh <- &ExecutionEvenInfo{\n\t\t\tEvent: XEStarted,\n\t\t}\n\t}\n\n\tif ref.options != nil && ref.options.Terminal {\n\t\tgo ref.monitorTerminalSizeSync()\n\n\t\tif ref.terminalExitChan != nil {\n\t\t\tattachErr := <-ref.terminalExitChan\n\t\t\treturn attachErr\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Stop stops the container execution\nfunc (ref *Execution) Stop() error {\n\tref.State = XSStopping\n\tif ref.eventCh != nil {\n\t\tref.eventCh <- &ExecutionEvenInfo{\n\t\t\tEvent: XEStopping,\n\t\t}\n\t}\n\n\terr := ref.APIClient.StopContainer(ref.ContainerID, ref.StopTimeout)\n\n\tif err != nil {\n\t\tif _, ok := err.(*dockerapi.ContainerNotRunning); ok {\n\t\t\tif ref.logger != nil {\n\t\t\t\tref.logger.Info(\"can't stop the 'slim' container (container is not running)...\")\n\t\t\t}\n\t\t} else {\n\t\t\tif ref.logger != nil {\n\t\t\t\tref.logger.Infof(\"Execution.Stop: apiClient.StopContainer error - %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tref.State = XSStopped\n\tif ref.eventCh != nil {\n\t\tref.eventCh <- &ExecutionEvenInfo{\n\t\t\tEvent: XEStopped,\n\t\t}\n\t}\n\n\treturn err\n}\n\n// Cleanup removes stopped container for the execution\nfunc (ref *Execution) Cleanup() error {\n\tremoveOption := dockerapi.RemoveContainerOptions{\n\t\tID:            ref.ContainerID,\n\t\tRemoveVolumes: true,\n\t\tForce:         true,\n\t}\n\n\terr := ref.APIClient.RemoveContainer(removeOption)\n\tif err != nil {\n\t\tif ref.logger != nil {\n\t\t\tref.logger.Info(\"error removing container =>\", err)\n\t\t}\n\t}\n\n\tref.State = XSRemoved\n\tif ref.eventCh != nil {\n\t\tref.eventCh <- &ExecutionEvenInfo{\n\t\t\tEvent: XERemoved,\n\t\t}\n\t}\n\n\treturn err\n}\n\n// Wait waits the container execution\nfunc (ref *Execution) Wait() (int, error) {\n\t//TODO: use WaitContainerWithContext\n\treturn ref.APIClient.WaitContainer(ref.ContainerID)\n}\n\nfunc (ref *Execution) monitorContainerExitSync() {\n\tref.APIClient.AddEventListener(ref.dockerEventCh)\n\n\tfor {\n\t\tselect {\n\t\tcase devent := <-ref.dockerEventCh:\n\t\t\tif devent == nil || devent.ID == \"\" || devent.Status == \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif devent.ID == ref.ContainerID {\n\t\t\t\tif devent.Status == \"die\" {\n\t\t\t\t\tref.State = XSExited\n\n\t\t\t\t\texitEvent := &ExecutionEvenInfo{\n\t\t\t\t\t\tEvent: XEExited,\n\t\t\t\t\t}\n\n\t\t\t\t\tnonZeroExitCode := false\n\t\t\t\t\texitCodeStr, ok := devent.Actor.Attributes[\"exitCode\"]\n\t\t\t\t\tif ok && exitCodeStr != \"\" && exitCodeStr != \"0\" {\n\t\t\t\t\t\tnonZeroExitCode = true\n\t\t\t\t\t}\n\n\t\t\t\t\tif nonZeroExitCode {\n\t\t\t\t\t\tif ref.isInterrupted && exitCodeStr == \"137\" {\n\t\t\t\t\t\t\tif ref.logger != nil {\n\t\t\t\t\t\t\t\tref.logger.Tracef(\"container interrupted (expected) = %s\", ref.ContainerID)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tref.State = XSExitedCrash\n\t\t\t\t\t\t\tref.Crashed = true\n\t\t\t\t\t\t\tif ref.printState && ref.xc != nil {\n\t\t\t\t\t\t\t\tref.xc.Out.Info(\"container\",\n\t\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\t\"status\":    \"crashed\",\n\t\t\t\t\t\t\t\t\t\t\"id\":        ref.ContainerID,\n\t\t\t\t\t\t\t\t\t\t\"exit.code\": exitCodeStr,\n\t\t\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\t\tif ref.logger != nil {\n\t\t\t\t\t\t\t\t\tref.logger.Tracef(\"container crashed = %s\", ref.ContainerID)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\texitEvent.Event = XEExitedCrash\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif exitEvent.Event == XEExited {\n\t\t\t\t\t\tif ref.printState && ref.xc != nil {\n\t\t\t\t\t\t\tref.xc.Out.Info(\"container\",\n\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\"status\":    \"exited\",\n\t\t\t\t\t\t\t\t\t\"id\":        ref.ContainerID,\n\t\t\t\t\t\t\t\t\t\"exit.code\": exitCodeStr,\n\t\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tif ref.logger != nil {\n\t\t\t\t\t\t\t\tref.logger.Tracef(\"container exited = %s\", ref.ContainerID)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ref.eventCh != nil {\n\t\t\t\t\t\tref.eventCh <- exitEvent\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase <-ref.dockerEventStopCh:\n\t\t\tif ref.logger != nil {\n\t\t\t\tref.logger.Debug(\"container.Execution.monitorContainerExitSync: Docker event monitor stopped\")\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (ref *Execution) monitorSysExitSync() {\n\tsignals := make(chan os.Signal, 1)\n\tsignal.Notify(signals, syscall.SIGINT)\n\n\t<-signals\n\tref.isInterrupted = true\n\t//_ = ref.APIClient.KillContainer(dockerapi.KillContainerOptions{ID: ref.ContainerID})\n\t//if ref.logger != nil {\n\t//\tref.logger.Debugf(\"Execution.monitorSysExitSync: received SIGINT, killing container %s\", ref.ContainerID)\n\t//}\n\n\tif ref.eventCh != nil {\n\t\tref.eventCh <- &ExecutionEvenInfo{\n\t\t\tEvent: XEInterrupt,\n\t\t}\n\t}\n\n\terr := ref.Stop()\n\tif err != nil {\n\t\tif ref.logger != nil {\n\t\t\tref.logger.Debugf(\"ref.Stop error: id=%s err=%v\", ref.ContainerID, err)\n\t\t}\n\t}\n}\n\nfunc (ref *Execution) startTerminal() {\n\tr, w := io.Pipe()\n\tgo io.Copy(w, os.Stdin)\n\toptions := dockerapi.AttachToContainerOptions{\n\t\tContainer:    ref.ContainerID,\n\t\tInputStream:  r,\n\t\tOutputStream: os.Stdout,\n\t\tErrorStream:  os.Stderr,\n\t\tStdin:        true,\n\t\tStdout:       true,\n\t\tStderr:       true,\n\t\tStream:       true,\n\t\tRawTerminal:  true,\n\t\tLogs:         true,\n\t}\n\n\terr := ref.APIClient.AttachToContainer(options)\n\tref.terminalExitChan <- err\n}\n\nfunc (ref *Execution) startLiveLogs() {\n\toptions := dockerapi.AttachToContainerOptions{\n\t\tContainer:    ref.ContainerID,\n\t\tOutputStream: os.Stdout,\n\t\tErrorStream:  os.Stderr,\n\t\tStdin:        false,\n\t\tStdout:       true,\n\t\tStderr:       true,\n\t\tLogs:         true,\n\t\tStream:       true,\n\t\tRawTerminal:  true,\n\t}\n\n\tif ref.options != nil {\n\t\tif ref.options.IO.Output != nil {\n\t\t\toptions.OutputStream = ref.options.IO.Output\n\t\t}\n\n\t\tif ref.options.IO.Error != nil {\n\t\t\toptions.ErrorStream = ref.options.IO.Error\n\t\t}\n\t}\n\n\terr := ref.APIClient.AttachToContainer(options)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\nfunc (ref *Execution) ShowContainerLogs() {\n\tvar outData bytes.Buffer\n\toutw := bufio.NewWriter(&outData)\n\tvar errData bytes.Buffer\n\terrw := bufio.NewWriter(&errData)\n\n\tif ref.logger != nil {\n\t\tref.logger.Debug(\"getting container logs => \", ref.ContainerID)\n\t}\n\n\tlogsOptions := dockerapi.LogsOptions{\n\t\tContainer:    ref.ContainerID,\n\t\tOutputStream: outw,\n\t\tErrorStream:  errw,\n\t\tStdout:       true,\n\t\tStderr:       true,\n\t}\n\n\terr := ref.APIClient.Logs(logsOptions)\n\tif err != nil {\n\t\tif ref.logger != nil {\n\t\t\tref.logger.Infof(\"error getting container logs => %v - %v\", ref.ContainerID, err)\n\t\t}\n\t} else {\n\t\toutw.Flush()\n\t\terrw.Flush()\n\t\tfmt.Printf(\"[%s] CONTAINER STDOUT:\\n\", ref.ContainerID)\n\t\toutData.WriteTo(os.Stdout)\n\t\tfmt.Printf(\"[%s] CONTAINER STDERR:\\n\", ref.ContainerID)\n\t\terrData.WriteTo(os.Stdout)\n\t\tfmt.Printf(\"[%s] END OF CONTAINER LOGS =============\\n\", ref.ContainerID)\n\t}\n}\n\nfunc (ref *Execution) monitorTerminalSizeSync() {\n\tref.updateTerminalSize()\n\n\twinchCh := make(chan os.Signal, 1)\n\tsignal.Notify(winchCh, syscall.SIGWINCH)\n\tdefer signal.Stop(winchCh)\n\n\tfor range winchCh {\n\t\tref.updateTerminalSize()\n\t}\n}\n\nfunc (ref *Execution) updateTerminalSize() error {\n\theight, width := terminalSize(ref.termFd)\n\tif height == 0 && width == 0 {\n\t\treturn nil\n\t}\n\treturn ref.APIClient.ResizeContainerTTY(ref.ContainerID, height, width)\n}\n\nfunc terminalSize(fd uintptr) (int, int) {\n\tws, err := term.GetWinsize(fd)\n\tif err != nil {\n\t\tif ws == nil {\n\t\t\treturn 0, 0\n\t\t}\n\t}\n\n\treturn int(ws.Height), int(ws.Width)\n}\n"
  },
  {
    "path": "pkg/app/master/docker/dockerhost/host.go",
    "content": "package dockerhost\n\nimport (\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst (\n\tlocalHostIP = \"127.0.0.1\"\n)\n\n// GetIP returns the Docker host IP address\nfunc GetIP(apiClient *dockerapi.Client) string {\n\tdockerHost := os.Getenv(\"DOCKER_HOST\")\n\tif dockerHost == \"\" {\n\t\tif apiClient != nil {\n\t\t\tnetInfo, err := apiClient.NetworkInfo(\"bridge\")\n\t\t\tif err != nil {\n\t\t\t\tlog.WithFields(log.Fields{\n\t\t\t\t\t\"op\":    \"dockerhost.GetIP\",\n\t\t\t\t\t\"error\": err,\n\t\t\t\t}).Debug(\"apiClient.NetworkInfo\")\n\t\t\t} else {\n\t\t\t\tif netInfo != nil && netInfo.Name == \"bridge\" {\n\t\t\t\t\tif len(netInfo.IPAM.Config) > 0 {\n\t\t\t\t\t\treturn netInfo.IPAM.Config[0].Gateway\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn localHostIP\n\t}\n\n\tu, err := url.Parse(dockerHost)\n\tif err != nil {\n\t\treturn localHostIP\n\t}\n\n\tswitch u.Scheme {\n\tcase \"unix\":\n\t\treturn localHostIP\n\tdefault:\n\t\thost, _, err := net.SplitHostPort(u.Host)\n\t\tif err != nil {\n\t\t\treturn localHostIP\n\t\t}\n\n\t\treturn host\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/inspectors/container/container_inspector.go",
    "content": "package container\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/aflag\"\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/docker/dockerhost\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/ipc\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/sensor\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/security/apparmor\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/security/seccomp\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/channel\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/jsonutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\tcontainertypes \"github.com/docker/docker/api/types/container\"\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// Container inspector constants\nconst (\n\tSensorIPCModeDirect = \"direct\"\n\tSensorIPCModeProxy  = \"proxy\"\n\tSensorBinPath       = \"/opt/_slim/bin/slim-sensor\"\n\tContainerNamePat    = \"slimk_%v_%v\"\n\tArtifactsDir        = \"artifacts\"\n\tReportArtifactTar   = \"creport.tar\"\n\tfileArtifactsTar    = \"files.tar\"\n\tFileArtifactsOutTar = \"files_out.tar\"\n\t// FileArtifactsArchiveTar = \"files_archive.tar\"\n\tSensorMountPat       = \"%s:/opt/_slim/bin/slim-sensor:ro\"\n\tVolumeSensorMountPat = \"%s:/opt/_slim/bin:ro\"\n\tLabelName            = \"_slim\"\n\tMondelArtifactTar    = \"mondel.tar\"\n)\n\ntype ovars = app.OutVars\n\nvar (\n\tcmdPortStrDefault  = fmt.Sprintf(\"%d\", channel.CmdPort)\n\tcmdPortSpecDefault = dockerapi.Port(fmt.Sprintf(\"%d/tcp\", channel.CmdPort))\n\tevtPortStrDefault  = fmt.Sprintf(\"%d\", channel.EvtPort)\n\tevtPortSpecDefault = dockerapi.Port(fmt.Sprintf(\"%d/tcp\", channel.EvtPort))\n)\n\nvar ErrStartMonitorTimeout = errors.New(\"start monitor timeout\")\n\nconst (\n\tsensorVolumeBaseName = \"slim-sensor\"\n)\n\ntype NetNameInfo struct {\n\tName     string\n\tFullName string\n\tAliases  []string\n}\n\n// TODO(estroz): move all fields configured only after RunContainer is called\n// to a InspectorRunResponse struct returned by RunContainer.\n\n// Inspector is a container execution inspector\ntype Inspector struct {\n\tContainerInfo         *dockerapi.Container\n\tContainerPortsInfo    string\n\tContainerPortList     string\n\tAvailablePorts        map[dockerapi.Port]dockerapi.PortBinding // Ports found to be available for probing.\n\tContainerID           string\n\tContainerName         string\n\tFatContainerCmd       []string\n\tLocalVolumePath       string\n\tDoUseLocalMounts      bool\n\tSensorVolumeName      string\n\tDoKeepTmpArtifacts    bool\n\tStatePath             string\n\tCmdPort               dockerapi.Port\n\tEvtPort               dockerapi.Port\n\tDockerHostIP          string\n\tImageInspector        *image.Inspector\n\tAPIClient             *dockerapi.Client\n\tOverrides             *config.ContainerOverrides\n\tExplicitVolumeMounts  map[string]config.VolumeMount\n\tBaseMounts            []dockerapi.HostMount\n\tBaseVolumesFrom       []string\n\tDoPublishExposedPorts bool\n\tHasClassicLinks       bool\n\tLinks                 []string\n\tEtcHostsMaps          []string\n\tDNSServers            []string\n\tDNSSearchDomains      []string\n\tDoShowContainerLogs   bool\n\tDoEnableMondel        bool\n\tRunTargetAsUser       bool\n\tKeepPerms             bool\n\tPathPerms             map[string]*fsutil.AccessInfo\n\tExcludePatterns       map[string]*fsutil.AccessInfo\n\tDoExcludeVarLockFiles bool\n\tPreservePaths         map[string]*fsutil.AccessInfo\n\tIncludePaths          map[string]*fsutil.AccessInfo\n\tIncludeBins           map[string]*fsutil.AccessInfo\n\tIncludeDirBinsList    map[string]*fsutil.AccessInfo\n\tIncludeExes           map[string]*fsutil.AccessInfo\n\tDoIncludeShell        bool\n\tDoIncludeWorkdir      bool\n\tDoIncludeCertAll      bool\n\tDoIncludeCertBundles  bool\n\tDoIncludeCertDirs     bool\n\tDoIncludeCertPKAll    bool\n\tDoIncludeCertPKDirs   bool\n\tDoIncludeNew          bool\n\tDoIncludeSSHClient    bool\n\tDoIncludeOSLibsNet    bool\n\tDoIncludeZoneInfo     bool\n\tSelectedNetworks      map[string]NetNameInfo\n\tDoDebug               bool\n\tLogLevel              string\n\tLogFormat             string\n\tPrintState            bool\n\tInContainer           bool\n\tRTASourcePT           bool\n\tDoObfuscateMetadata   bool\n\tSensorIPCEndpoint     string\n\tSensorIPCMode         string\n\tTargetHost            string\n\tdockerEventCh         chan *dockerapi.APIEvents\n\tdockerEventStopCh     chan struct{}\n\tisDone                aflag.Type\n\tipcClient             *ipc.Client\n\tlogger                *log.Entry\n\txc                    *app.ExecutionContext\n\tcrOpts                *config.ContainerRunOptions\n\tportBindings          map[dockerapi.Port][]dockerapi.PortBinding\n\tappNodejsInspectOpts  config.AppNodejsInspectOptions\n}\n\nfunc pathMapKeys(m map[string]*fsutil.AccessInfo) []string {\n\tif len(m) == 0 {\n\t\treturn nil\n\t}\n\n\tkeys := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\n\treturn keys\n}\n\n// NewInspector creates a new container execution inspector\nfunc NewInspector(\n\txc *app.ExecutionContext,\n\tcrOpts *config.ContainerRunOptions,\n\tlogger *log.Entry,\n\tclient *dockerapi.Client,\n\tstatePath string,\n\timageInspector *image.Inspector,\n\tlocalVolumePath string,\n\tdoUseLocalMounts bool,\n\tsensorVolumeName string,\n\tdoKeepTmpArtifacts bool,\n\toverrides *config.ContainerOverrides,\n\texplicitVolumeMounts map[string]config.VolumeMount,\n\tbaseMounts []dockerapi.HostMount,\n\tbaseVolumesFrom []string,\n\tportBindings map[dockerapi.Port][]dockerapi.PortBinding,\n\tdoPublishExposedPorts bool,\n\thasClassicLinks bool,\n\tlinks []string,\n\tetcHostsMaps []string,\n\tdnsServers []string,\n\tdnsSearchDomains []string,\n\tshowContainerLogs bool,\n\tdoEnableMondel bool,\n\trunTargetAsUser bool,\n\tkeepPerms bool,\n\tpathPerms map[string]*fsutil.AccessInfo,\n\texcludePatterns map[string]*fsutil.AccessInfo,\n\tdoExcludeVarLockFiles bool,\n\tpreservePaths map[string]*fsutil.AccessInfo,\n\tincludePaths map[string]*fsutil.AccessInfo,\n\tincludeBins map[string]*fsutil.AccessInfo,\n\tincludeDirBinsList map[string]*fsutil.AccessInfo,\n\tincludeExes map[string]*fsutil.AccessInfo,\n\tdoIncludeShell bool,\n\tdoIncludeWorkdir bool,\n\tdoIncludeCertAll bool,\n\tdoIncludeCertBundles bool,\n\tdoIncludeCertDirs bool,\n\tdoIncludeCertPKAll bool,\n\tdoIncludeCertPKDirs bool,\n\tdoIncludeNew bool,\n\tdoIncludeSSHClient bool,\n\tdoIncludeOSLibsNet bool,\n\tdoIncludeZoneInfo bool,\n\tselectedNetworks map[string]NetNameInfo,\n\t//serviceAliases []string,\n\tdoDebug bool,\n\tlogLevel string,\n\tlogFormat string,\n\tinContainer bool,\n\trtaSourcePT bool,\n\tdoObfuscateMetadata bool,\n\tsensorIPCEndpoint string,\n\tsensorIPCMode string,\n\tprintState bool,\n\tappNodejsInspectOpts config.AppNodejsInspectOptions) (*Inspector, error) {\n\n\tlogger = logger.WithFields(log.Fields{\"component\": \"container.inspector\"})\n\tinspector := &Inspector{\n\t\tlogger:                logger,\n\t\tStatePath:             statePath,\n\t\tLocalVolumePath:       localVolumePath,\n\t\tDoUseLocalMounts:      doUseLocalMounts,\n\t\tSensorVolumeName:      sensorVolumeName,\n\t\tDoKeepTmpArtifacts:    doKeepTmpArtifacts,\n\t\tCmdPort:               cmdPortSpecDefault,\n\t\tEvtPort:               evtPortSpecDefault,\n\t\tImageInspector:        imageInspector,\n\t\tAPIClient:             client,\n\t\tOverrides:             overrides,\n\t\tExplicitVolumeMounts:  explicitVolumeMounts,\n\t\tBaseMounts:            baseMounts,\n\t\tBaseVolumesFrom:       baseVolumesFrom,\n\t\tDoPublishExposedPorts: doPublishExposedPorts,\n\t\tHasClassicLinks:       hasClassicLinks,\n\t\tLinks:                 links,\n\t\tEtcHostsMaps:          etcHostsMaps,\n\t\tDNSServers:            dnsServers,\n\t\tDNSSearchDomains:      dnsSearchDomains,\n\t\tDoShowContainerLogs:   showContainerLogs,\n\t\tDoEnableMondel:        doEnableMondel,\n\t\tRunTargetAsUser:       runTargetAsUser,\n\t\tKeepPerms:             keepPerms,\n\t\tPathPerms:             pathPerms,\n\t\tExcludePatterns:       excludePatterns,\n\t\tDoExcludeVarLockFiles: doExcludeVarLockFiles,\n\t\tPreservePaths:         preservePaths,\n\t\tIncludePaths:          includePaths,\n\t\tIncludeBins:           includeBins,\n\t\tIncludeDirBinsList:    includeDirBinsList,\n\t\tIncludeExes:           includeExes,\n\t\tDoIncludeShell:        doIncludeShell,\n\t\tDoIncludeWorkdir:      doIncludeWorkdir,\n\t\tDoIncludeCertAll:      doIncludeCertAll,\n\t\tDoIncludeCertBundles:  doIncludeCertBundles,\n\t\tDoIncludeCertDirs:     doIncludeCertDirs,\n\t\tDoIncludeCertPKAll:    doIncludeCertPKAll,\n\t\tDoIncludeCertPKDirs:   doIncludeCertPKDirs,\n\t\tDoIncludeNew:          doIncludeNew,\n\t\tDoIncludeSSHClient:    doIncludeSSHClient,\n\t\tDoIncludeOSLibsNet:    doIncludeOSLibsNet,\n\t\tDoIncludeZoneInfo:     doIncludeZoneInfo,\n\t\tSelectedNetworks:      selectedNetworks,\n\t\tDoDebug:               doDebug,\n\t\tLogLevel:              logLevel,\n\t\tLogFormat:             logFormat,\n\t\tPrintState:            printState,\n\t\tInContainer:           inContainer,\n\t\tRTASourcePT:           rtaSourcePT,\n\t\tDoObfuscateMetadata:   doObfuscateMetadata,\n\t\tSensorIPCEndpoint:     sensorIPCEndpoint,\n\t\tSensorIPCMode:         sensorIPCMode,\n\t\txc:                    xc,\n\t\tcrOpts:                crOpts,\n\t\tportBindings:          portBindings,\n\t\tappNodejsInspectOpts:  appNodejsInspectOpts,\n\t}\n\n\tif overrides == nil {\n\t\tinspector.FatContainerCmd = BuildStartupCommand(\n\t\t\timageInspector.ImageInfo.Config.Entrypoint,\n\t\t\timageInspector.ImageInfo.Config.Cmd,\n\t\t\timageInspector.ImageInfo.Config.Shell,\n\t\t\tfalse, nil, false, nil,\n\t\t)\n\t} else {\n\t\tinspector.FatContainerCmd = BuildStartupCommand(\n\t\t\timageInspector.ImageInfo.Config.Entrypoint,\n\t\t\timageInspector.ImageInfo.Config.Cmd,\n\t\t\timageInspector.ImageInfo.Config.Shell,\n\t\t\toverrides.ClearEntrypoint,\n\t\t\toverrides.Entrypoint,\n\t\t\toverrides.ClearCmd,\n\t\t\toverrides.Cmd,\n\t\t)\n\t}\n\n\tlogger.Debugf(\"FatContainerCmd - %+v\", inspector.FatContainerCmd)\n\n\tinspector.dockerEventCh = make(chan *dockerapi.APIEvents)\n\tinspector.dockerEventStopCh = make(chan struct{})\n\n\treturn inspector, nil\n}\n\n// RunContainer starts the container inspector instance execution\nfunc (i *Inspector) RunContainer() error {\n\tlogger := i.logger.WithField(\"op\", \"container.Inspector.RunContainer\")\n\n\tartifactsPath := filepath.Join(i.LocalVolumePath, ArtifactsDir)\n\tsensorPath := sensor.EnsureLocalBinary(i.xc, i.logger, i.StatePath, i.PrintState)\n\n\tallMountsMap := map[string]dockerapi.HostMount{}\n\n\t//start with the base mounts (usually come from compose)\n\tif len(i.BaseMounts) > 0 {\n\t\tfor _, m := range i.BaseMounts {\n\t\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", m.Type, m.Source, m.Target)\n\t\t\tallMountsMap[mkey] = m\n\t\t}\n\t}\n\n\t//var volumeBinds []string\n\t//then add binds and mounts from the host config param\n\tif i.crOpts != nil && i.crOpts.HostConfig != nil {\n\t\t//volumeBinds = i.crOpts.HostConfig.Binds\n\t\tfor _, vb := range i.crOpts.HostConfig.Binds {\n\t\t\tparts := strings.Split(vb, \":\")\n\t\t\tif len(parts) < 2 {\n\t\t\t\tlogger.Errorf(\"invalid bind format in crOpts.HostConfig.Binds => %s\", vb)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvm := dockerapi.HostMount{\n\t\t\t\tType:   \"bind\",\n\t\t\t\tSource: parts[0],\n\t\t\t\tTarget: parts[1],\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(vm.Source, \"~/\") {\n\t\t\t\thd, _ := os.UserHomeDir()\n\t\t\t\tvm.Source = filepath.Join(hd, vm.Source[2:])\n\t\t\t} else if strings.HasPrefix(vm.Source, \"./\") ||\n\t\t\t\tstrings.HasPrefix(vm.Source, \"../\") ||\n\t\t\t\t(vm.Source == \"..\") ||\n\t\t\t\t(vm.Source == \".\") {\n\t\t\t\tvm.Source, _ = filepath.Abs(vm.Source)\n\t\t\t}\n\n\t\t\tif len(parts) == 3 && parts[2] == \"ro\" {\n\t\t\t\tvm.ReadOnly = true\n\t\t\t}\n\n\t\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\t\tallMountsMap[mkey] = vm\n\t\t}\n\n\t\tfor _, vm := range i.crOpts.HostConfig.Mounts {\n\t\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\t\tallMountsMap[mkey] = vm\n\t\t}\n\t}\n\n\t//configVolumes := i.Overrides.Volumes\n\t//if configVolumes == nil {\n\t//\tconfigVolumes = map[string]struct{}{}\n\t//}\n\n\t//then add volumes from overrides\n\tif i.Overrides != nil && len(i.Overrides.Volumes) > 0 {\n\t\tfor vol := range i.Overrides.Volumes {\n\t\t\tvm := dockerapi.HostMount{\n\t\t\t\tType:   \"volume\",\n\t\t\t\tTarget: vol,\n\t\t\t}\n\n\t\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\t\tallMountsMap[mkey] = vm\n\t\t}\n\t}\n\n\t//now handle the explicit volume mounts\n\tfor _, vol := range i.ExplicitVolumeMounts {\n\t\t//mountInfo := fmt.Sprintf(\"%s:%s:%s\", volumeMount.Source, volumeMount.Destination, volumeMount.Options)\n\t\t//volumeBinds = append(volumeBinds, mountInfo)\n\n\t\tvm := dockerapi.HostMount{\n\t\t\tTarget: vol.Destination,\n\t\t}\n\n\t\tif strings.HasPrefix(vol.Source, \"/\") {\n\t\t\tvm.Source = vol.Source\n\t\t\tvm.Type = \"bind\"\n\t\t} else if strings.HasPrefix(vol.Source, \"~/\") {\n\t\t\thd, _ := os.UserHomeDir()\n\t\t\tvm.Source = filepath.Join(hd, vol.Source[2:])\n\t\t\tvm.Type = \"bind\"\n\t\t} else if strings.HasPrefix(vol.Source, \"./\") ||\n\t\t\tstrings.HasPrefix(vol.Source, \"../\") ||\n\t\t\t(vol.Source == \"..\") ||\n\t\t\t(vol.Source == \".\") {\n\t\t\tvm.Source, _ = filepath.Abs(vol.Source)\n\t\t\tvm.Type = \"bind\"\n\t\t} else {\n\t\t\t//todo: list volumes and check vol.Source instead of defaulting to named volume\n\t\t\tvm.Source = vol.Source\n\t\t\tvm.Type = \"volume\"\n\t\t}\n\n\t\tif vol.Options == \"ro\" {\n\t\t\tvm.ReadOnly = true\n\t\t}\n\n\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\tallMountsMap[mkey] = vm\n\t}\n\n\tvar err error\n\tvar volumeName string\n\tif !i.DoUseLocalMounts {\n\t\tvolumeName, err = ensureSensorVolume(i.logger, i.APIClient, sensorPath, i.SensorVolumeName)\n\t\terrutil.FailOn(err)\n\t}\n\n\t//var artifactsMountInfo string\n\tif i.DoUseLocalMounts {\n\t\t//\"%s:/opt/_slim/artifacts\"\n\t\t//artifactsMountInfo = fmt.Sprintf(ArtifactsMountPat, artifactsPath)\n\t\t//volumeBinds = append(volumeBinds, artifactsMountInfo)\n\t\tvm := dockerapi.HostMount{\n\t\t\tType:   \"bind\",\n\t\t\tSource: artifactsPath,\n\t\t\tTarget: app.DefaultArtifactsDirPath,\n\t\t}\n\n\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\tallMountsMap[mkey] = vm\n\t} else {\n\t\t//artifactsMountInfo = app.DefaultArtifactsDirPath\n\t\t//configVolumes[artifactsMountInfo] = struct{}{}\n\t\tvm := dockerapi.HostMount{\n\t\t\tType:   \"volume\",\n\t\t\tTarget: app.DefaultArtifactsDirPath,\n\t\t}\n\n\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\tallMountsMap[mkey] = vm\n\t}\n\n\t//var sensorMountInfo string\n\tif i.DoUseLocalMounts {\n\t\t//sensorMountInfo = fmt.Sprintf(SensorMountPat, sensorPath)\n\t\tvm := dockerapi.HostMount{\n\t\t\tType:     \"bind\",\n\t\t\tSource:   sensorPath,\n\t\t\tTarget:   SensorBinPath,\n\t\t\tReadOnly: true,\n\t\t}\n\n\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\tallMountsMap[mkey] = vm\n\t} else {\n\t\t//sensorMountInfo = fmt.Sprintf(VolumeSensorMountPat, volumeName)\n\t\tvm := dockerapi.HostMount{\n\t\t\tType:     \"volume\",\n\t\t\tSource:   volumeName,\n\t\t\tTarget:   \"/opt/_slim/bin\",\n\t\t\tReadOnly: true,\n\t\t}\n\n\t\tmkey := fmt.Sprintf(\"%s:%s:%s\", vm.Type, vm.Source, vm.Target)\n\t\tallMountsMap[mkey] = vm\n\t}\n\n\t//volumeBinds = append(volumeBinds, sensorMountInfo)\n\n\tvar containerCmd []string\n\tif i.DoDebug {\n\t\tcontainerCmd = append(containerCmd, \"-d\")\n\t}\n\n\tif i.LogLevel != \"\" {\n\t\tcontainerCmd = append(containerCmd, \"-log-level\", i.LogLevel)\n\t}\n\n\tif i.LogFormat != \"\" {\n\t\tcontainerCmd = append(containerCmd, \"-log-format\", i.LogFormat)\n\t}\n\n\tif i.DoEnableMondel {\n\t\tcontainerCmd = append(containerCmd, \"-n\")\n\t}\n\n\ti.ContainerName = fmt.Sprintf(ContainerNamePat, os.Getpid(), time.Now().UTC().Format(\"20060102150405\"))\n\n\tlabels := i.Overrides.Labels\n\tif labels == nil {\n\t\tlabels = map[string]string{}\n\t}\n\n\tlabels[\"runtime.container.type\"] = LabelName\n\n\tvar hostConfig *dockerapi.HostConfig\n\tif i.crOpts != nil && i.crOpts.HostConfig != nil {\n\t\thostConfig = i.crOpts.HostConfig\n\t}\n\n\tif hostConfig == nil {\n\t\thostConfig = &dockerapi.HostConfig{}\n\t}\n\n\t//hostConfig.Binds = volumeBinds\n\tvar mountsList []dockerapi.HostMount\n\tfor _, m := range allMountsMap {\n\t\tmountsList = append(mountsList, m)\n\t}\n\thostConfig.Mounts = mountsList\n\n\thostConfig.Privileged = true\n\thostConfig.UsernsMode = \"host\"\n\n\thasSysAdminCap := false\n\tfor _, c := range hostConfig.CapAdd {\n\t\tif c == \"SYS_ADMIN\" {\n\t\t\thasSysAdminCap = true\n\t\t}\n\t}\n\n\tif !hasSysAdminCap {\n\t\thostConfig.CapAdd = append(hostConfig.CapAdd, \"SYS_ADMIN\")\n\t}\n\n\tcontainerOptions := dockerapi.CreateContainerOptions{\n\t\tName: i.ContainerName,\n\t\tConfig: &dockerapi.Config{\n\t\t\tImage:      i.ImageInspector.ImageRef,\n\t\t\tEntrypoint: []string{SensorBinPath},\n\t\t\tCmd:        containerCmd,\n\t\t\tEnv:        i.Overrides.Env,\n\t\t\tLabels:     labels,\n\t\t\tHostname:   i.Overrides.Hostname,\n\t\t\tWorkingDir: i.Overrides.Workdir,\n\t\t},\n\t\tHostConfig:       hostConfig,\n\t\tNetworkingConfig: &dockerapi.NetworkingConfig{},\n\t}\n\n\tif i.crOpts != nil {\n\t\tif i.crOpts.Runtime != \"\" {\n\t\t\tcontainerOptions.HostConfig.Runtime = i.crOpts.Runtime\n\t\t\tlogger.Debugf(\"using custom runtime => %s\", containerOptions.HostConfig.Runtime)\n\t\t}\n\n\t\tif len(i.crOpts.SysctlParams) > 0 {\n\t\t\tcontainerOptions.HostConfig.Sysctls = i.crOpts.SysctlParams\n\t\t\tlogger.Debugf(\"using sysctl params => %#v\", containerOptions.HostConfig.Sysctls)\n\t\t}\n\n\t\tif i.crOpts.ShmSize > -1 {\n\t\t\tcontainerOptions.HostConfig.ShmSize = i.crOpts.ShmSize\n\t\t\tlogger.Debugf(\"using shm-size params => %#v\", containerOptions.HostConfig.ShmSize)\n\t\t}\n\t}\n\n\t//if len(configVolumes) > 0 {\n\t//\tcontainerOptions.Config.Volumes = configVolumes\n\t//}\n\n\trunAsUser := i.ImageInspector.ImageInfo.Config.User\n\tif i.Overrides.User != \"\" {\n\t\trunAsUser = i.Overrides.User\n\t}\n\n\tcontainerOptions.Config.User = \"0:0\"\n\n\tif runAsUser != \"\" && strings.ToLower(runAsUser) != \"root\" {\n\t\t//containerOptions.Config.Tty = true\n\t\t//containerOptions.Config.OpenStdin = true\n\t\t//NOTE:\n\t\t//when enabling TTY need to add extra params getting logs\n\t\t//or the client.Logs() call will fail with an\n\t\t//\"Unrecognized input header\" error\n\t}\n\n\thostProbePorts := i.setPorts(&containerOptions)\n\tcommsExposedPorts := containerOptions.Config.ExposedPorts\n\n\tif i.Overrides.Network != \"\" {\n\t\t// Non-user defined networks are *probably* a mode, ex. \"host\".\n\t\tif !containertypes.NetworkMode(i.Overrides.Network).IsUserDefined() {\n\t\t\tcontainerOptions.HostConfig.NetworkMode = i.Overrides.Network\n\t\t\tlogger.Debugf(\"HostConfig.NetworkMode => %v\", i.Overrides.Network)\n\t\t}\n\n\t\tif containerOptions.NetworkingConfig.EndpointsConfig == nil {\n\t\t\tcontainerOptions.NetworkingConfig.EndpointsConfig = map[string]*dockerapi.EndpointConfig{}\n\t\t}\n\t\tcontainerOptions.NetworkingConfig.EndpointsConfig[i.Overrides.Network] = &dockerapi.EndpointConfig{}\n\t\tlogger.Debugf(\"NetworkingConfig.EndpointsConfig => %v\", i.Overrides.Network)\n\t}\n\n\t// adding this separately for better visibility...\n\tif i.HasClassicLinks && len(i.Links) > 0 {\n\t\tcontainerOptions.HostConfig.Links = i.Links\n\t\tlogger.Debugf(\"HostConfig.Links => %v\", i.Links)\n\t}\n\n\tif len(i.EtcHostsMaps) > 0 {\n\t\tcontainerOptions.HostConfig.ExtraHosts = i.EtcHostsMaps\n\t\tlogger.Debugf(\"HostConfig.ExtraHosts => %v\", i.EtcHostsMaps)\n\t}\n\n\tif len(i.DNSServers) > 0 {\n\t\tcontainerOptions.HostConfig.DNS = i.DNSServers //for newer versions of Docker\n\t\tcontainerOptions.Config.DNS = i.DNSServers     //for older versions of Docker\n\t\tlogger.Debugf(\"HostConfig.DNS/Config.DNS => %v\", i.DNSServers)\n\t}\n\n\tif len(i.DNSSearchDomains) > 0 {\n\t\tcontainerOptions.HostConfig.DNSSearch = i.DNSSearchDomains\n\t\tlogger.Debugf(\"HostConfig.DNSSearch => %v\", i.DNSSearchDomains)\n\t}\n\n\tcontainerInfo, err := i.APIClient.CreateContainer(containerOptions)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// note: now need to cleanup the created container if there's an error\n\n\tif i.ContainerName != containerInfo.Name {\n\t\tlogger.Debugf(\"Container name mismatch expected=%v got=%v\", i.ContainerName, containerInfo.Name)\n\t}\n\n\ti.ContainerID = containerInfo.ID\n\tif i.PrintState {\n\t\ti.xc.Out.Info(\"container\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"created\",\n\t\t\t\t\"name\":   containerInfo.Name,\n\t\t\t\t\"id\":     i.ContainerID,\n\t\t\t})\n\t}\n\n\tif len(i.SelectedNetworks) > 0 {\n\t\tvar networkLinks []string\n\t\tif !i.HasClassicLinks && len(i.Links) > 0 {\n\t\t\tnetworkLinks = i.Links\n\t\t}\n\n\t\tlogger.Debugf(\"SelectedNetworks => %#v\", i.SelectedNetworks)\n\t\tfor key, netNameInfo := range i.SelectedNetworks {\n\t\t\terr = attachContainerToNetwork(i.logger, i.APIClient, i.ContainerID, netNameInfo, networkLinks)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Debugf(\"AttachContainerToNetwork(%s,%+v) key=%s error => %#v\", i.ContainerID, netNameInfo, key, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := i.APIClient.AddEventListener(i.dockerEventCh); err != nil {\n\t\tlogger.Debugf(\"i.APIClient.AddEventListener error => %v\", err)\n\t\treturn err\n\t}\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase devent := <-i.dockerEventCh:\n\t\t\t\tif devent == nil || devent.ID == \"\" || devent.Status == \"\" {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif devent.ID == i.ContainerID {\n\t\t\t\t\tif devent.Status == \"die\" {\n\t\t\t\t\t\tnonZeroExitCode := false\n\t\t\t\t\t\texitCodeStr, ok := devent.Actor.Attributes[\"exitCode\"]\n\t\t\t\t\t\tif ok && exitCodeStr != \"\" && exitCodeStr != \"0\" {\n\t\t\t\t\t\t\tnonZeroExitCode = true\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif nonZeroExitCode {\n\t\t\t\t\t\t\tif i.PrintState {\n\t\t\t\t\t\t\t\ti.xc.Out.Info(\"container\",\n\t\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\t\"status\":    \"crashed\",\n\t\t\t\t\t\t\t\t\t\t\"id\":        i.ContainerID,\n\t\t\t\t\t\t\t\t\t\t\"exit.code\": exitCodeStr,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ti.ShowContainerLogs()\n\n\t\t\t\t\t\t\tif i.PrintState {\n\t\t\t\t\t\t\t\ti.xc.Out.State(\"exited\",\n\t\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\t\"exit.code\":       -999,\n\t\t\t\t\t\t\t\t\t\t\"version\":         v.Current(),\n\t\t\t\t\t\t\t\t\t\t\"location.exe\":    fsutil.ExeDir(),\n\t\t\t\t\t\t\t\t\t\t\"location.sensor\": sensorPath,\n\t\t\t\t\t\t\t\t\t\t\"sensor.filemode\": fsutil.FileMode(sensorPath),\n\t\t\t\t\t\t\t\t\t\t\"sensor.volume\":   volumeName,\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ti.xc.Exit(-999)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase <-i.dockerEventStopCh:\n\t\t\t\tlogger.Debug(\"Docker event monitor stopped\")\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\tsignals := make(chan os.Signal, 1)\n\tsignal.Notify(signals, syscall.SIGINT)\n\tgo func() {\n\t\tselect {\n\t\tcase <-signals:\n\t\t\t_ = i.APIClient.KillContainer(dockerapi.KillContainerOptions{ID: i.ContainerID})\n\t\t\tlogger.Fatalf(\"[SIGMON] received SIGINT, killing container %s\", i.ContainerID)\n\t\tcase <-i.dockerEventStopCh:\n\t\t\tlogger.Debug(\"[SIGMON] Docker event monitor stopped\")\n\t\t\t//not killing target because we are going through a graceful shutdown\n\t\t\t//where we sent the StopMonitor and ShutdownSensor ipc commands\n\t\t}\n\t}()\n\n\tif err := i.APIClient.StartContainer(i.ContainerID, nil); err != nil {\n\t\treturn err\n\t}\n\n\tinspectContainerOpts := dockerapi.InspectContainerOptions{ID: i.ContainerID, Size: true}\n\tif i.ContainerInfo, err = i.APIClient.InspectContainerWithOptions(inspectContainerOpts); err != nil {\n\t\treturn err\n\t}\n\n\tif i.ContainerInfo.NetworkSettings == nil {\n\t\treturn fmt.Errorf(\"slim: error => no network info\")\n\t}\n\n\tif hCfg := i.ContainerInfo.HostConfig; hCfg != nil && !i.isHostNetworked() {\n\t\tlogger.Debugf(\"container HostConfig.NetworkMode => %s len(ports)=%d\",\n\t\t\thCfg.NetworkMode, len(i.ContainerInfo.NetworkSettings.Ports))\n\n\t\tif len(i.ContainerInfo.NetworkSettings.Ports) < len(commsExposedPorts) {\n\t\t\treturn fmt.Errorf(\"slim: error => missing comms ports\")\n\t\t}\n\t}\n\n\tlogger.Debugf(\"container NetworkSettings.Ports => %#v\", i.ContainerInfo.NetworkSettings.Ports)\n\n\ti.setAvailablePorts(hostProbePorts)\n\n\tif i.PrintState {\n\t\ti.xc.Out.Info(\"container\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"running\",\n\t\t\t\t\"name\":   containerInfo.Name,\n\t\t\t\t\"id\":     i.ContainerID,\n\t\t\t})\n\t}\n\n\tif err = i.initContainerChannels(); err != nil {\n\t\treturn err\n\t}\n\n\tcmd := &command.StartMonitor{\n\t\tRTASourcePT: i.RTASourcePT,\n\t\tAppName:     i.FatContainerCmd[0],\n\t}\n\n\tif len(i.FatContainerCmd) > 1 {\n\t\tcmd.AppArgs = i.FatContainerCmd[1:]\n\t}\n\n\tif len(i.ExcludePatterns) > 0 {\n\t\tcmd.Excludes = pathMapKeys(i.ExcludePatterns)\n\t}\n\n\tcmd.ExcludeVarLockFiles = i.DoExcludeVarLockFiles\n\n\tif len(i.PreservePaths) > 0 {\n\t\tcmd.Preserves = i.PreservePaths\n\t}\n\n\tif len(i.IncludePaths) > 0 {\n\t\tcmd.Includes = i.IncludePaths\n\t}\n\n\tcmd.KeepPerms = i.KeepPerms\n\n\tif len(i.PathPerms) > 0 {\n\t\tcmd.Perms = i.PathPerms\n\t}\n\n\tif len(i.IncludeBins) > 0 {\n\t\tcmd.IncludeBins = pathMapKeys(i.IncludeBins)\n\t}\n\n\tif len(i.IncludeDirBinsList) > 0 {\n\t\tcmd.IncludeDirBinsList = i.IncludeDirBinsList\n\t}\n\n\tif len(i.IncludeExes) > 0 {\n\t\tcmd.IncludeExes = pathMapKeys(i.IncludeExes)\n\t}\n\n\tcmd.IncludeShell = i.DoIncludeShell\n\n\tif i.DoIncludeWorkdir {\n\t\tcmd.IncludeWorkdir = i.ImageInspector.ImageInfo.Config.WorkingDir\n\t}\n\n\tcmd.IncludeCertAll = i.DoIncludeCertAll\n\tcmd.IncludeCertBundles = i.DoIncludeCertBundles\n\tcmd.IncludeCertDirs = i.DoIncludeCertDirs\n\tcmd.IncludeCertPKAll = i.DoIncludeCertPKAll\n\tcmd.IncludeCertPKDirs = i.DoIncludeCertPKDirs\n\tcmd.IncludeNew = i.DoIncludeNew\n\tcmd.IncludeSSHClient = i.DoIncludeSSHClient\n\tcmd.IncludeOSLibsNet = i.DoIncludeOSLibsNet\n\tcmd.IncludeZoneInfo = i.DoIncludeZoneInfo\n\n\tif runAsUser != \"\" {\n\t\tcmd.AppUser = runAsUser\n\n\t\tif strings.ToLower(runAsUser) != \"root\" {\n\t\t\tcmd.RunTargetAsUser = i.RunTargetAsUser\n\t\t}\n\t}\n\n\tcmd.IncludeAppNextDir = i.appNodejsInspectOpts.NextOpts.IncludeAppDir\n\tcmd.IncludeAppNextBuildDir = i.appNodejsInspectOpts.NextOpts.IncludeBuildDir\n\tcmd.IncludeAppNextDistDir = i.appNodejsInspectOpts.NextOpts.IncludeDistDir\n\tcmd.IncludeAppNextStaticDir = i.appNodejsInspectOpts.NextOpts.IncludeStaticDir\n\tcmd.IncludeAppNextNodeModulesDir = i.appNodejsInspectOpts.NextOpts.IncludeNodeModulesDir\n\n\tcmd.IncludeAppNuxtDir = i.appNodejsInspectOpts.NuxtOpts.IncludeAppDir\n\tcmd.IncludeAppNuxtBuildDir = i.appNodejsInspectOpts.NuxtOpts.IncludeBuildDir\n\tcmd.IncludeAppNuxtDistDir = i.appNodejsInspectOpts.NuxtOpts.IncludeDistDir\n\tcmd.IncludeAppNuxtStaticDir = i.appNodejsInspectOpts.NuxtOpts.IncludeStaticDir\n\tcmd.IncludeAppNuxtNodeModulesDir = i.appNodejsInspectOpts.NuxtOpts.IncludeNodeModulesDir\n\n\tcmd.IncludeNodePackages = i.appNodejsInspectOpts.IncludePackages\n\n\tcmd.ObfuscateMetadata = i.DoObfuscateMetadata\n\n\t_, err = i.ipcClient.SendCommand(cmd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif i.PrintState {\n\t\ti.xc.Out.Info(\"cmd.startmonitor\",\n\t\t\tovars{\n\t\t\t\t\"status\": \"sent\",\n\t\t\t})\n\t}\n\n\t// We really need this code block to produce conclusive\n\t// outcomes. Hence, many retries to prevent (most of) the\n\t// premature terminations of the master process with the\n\t// sensor process (in a container) remaining (semi-)started.\n\tfor idx := 0; idx < 16; idx++ {\n\t\tevt, err := i.ipcClient.GetEvent()\n\t\tif err != nil {\n\t\t\tif os.IsTimeout(err) || err == channel.ErrWaitTimeout {\n\t\t\t\tif i.PrintState {\n\t\t\t\t\ti.xc.Out.Info(\"event.startmonitor.done\",\n\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\"status\": \"receive.timeout\",\n\t\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tlogger.Debug(\"timeout waiting for the slim container to start...\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\treturn err\n\t\t}\n\n\t\tif evt == nil || evt.Name == \"\" {\n\t\t\tlogger.Warn(\"empty event waiting for the slim container to start (trying again)...\")\n\t\t\tcontinue\n\t\t}\n\n\t\tif evt.Name == event.StartMonitorDone {\n\t\t\tif i.PrintState {\n\t\t\t\ti.xc.Out.Info(\"event.startmonitor.done\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"status\": \"received\",\n\t\t\t\t\t})\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif evt.Name == event.Error {\n\t\t\tif i.PrintState {\n\t\t\t\ti.xc.Out.Info(\"event.error\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"status\": \"received\",\n\t\t\t\t\t\t\"data\":   evt.Data,\n\t\t\t\t\t})\n\n\t\t\t\ti.xc.Out.State(\"exited\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"exit.code\": -124,\n\t\t\t\t\t\t\"component\": \"container.inspector\",\n\t\t\t\t\t\t\"version\":   v.Current(),\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\t//not returning an error, exiting, need to clean up the container\n\t\t\ti.ShutdownContainer(true)\n\t\t\ti.xc.Exit(-124)\n\t\t}\n\n\t\tif evt.Name != event.StartMonitorDone {\n\t\t\tif i.PrintState {\n\t\t\t\ti.xc.Out.Info(\"event.startmonitor.done\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"status\": \"received.unexpected\",\n\t\t\t\t\t\t\"data\":   jsonutil.ToString(evt),\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn event.ErrUnexpectedEvent\n\t\t}\n\t}\n\n\treturn ErrStartMonitorTimeout\n}\n\n// isHostNetworked returns true if either the created container's network mode is \"host\"\n// or if the Inspector is configured with a network \"host\".\nfunc (i *Inspector) isHostNetworked() bool {\n\tif i.ContainerInfo != nil {\n\t\treturn containertypes.NetworkMode(i.ContainerInfo.HostConfig.NetworkMode).IsHost()\n\t}\n\treturn containertypes.NetworkMode(i.Overrides.Network).IsHost()\n}\n\nconst localHostIP = \"127.0.0.1\"\n\n// setPorts sets all port fields in CreateContainerOptions from user input and defaults.\n// Exposed tcp ports are returned as hostProbePorts for containers configured with host networks,\n// as those ports are exposed directly by the contained application on the loopback interface,\n// and will not be surfaced in network settings.\nfunc (i *Inspector) setPorts(ctrOpts *dockerapi.CreateContainerOptions) (hostProbePorts map[dockerapi.Port][]dockerapi.PortBinding) {\n\t// This is the minimal set of ports to either expose or directly use.\n\tcommsExposedPorts := map[dockerapi.Port]struct{}{\n\t\ti.CmdPort: {},\n\t\ti.EvtPort: {},\n\t}\n\n\t//add comms ports to the exposed ports in the container\n\tif len(i.Overrides.ExposedPorts) > 0 {\n\t\tctrOpts.Config.ExposedPorts = i.Overrides.ExposedPorts\n\t\tfor k, v := range commsExposedPorts {\n\t\t\tif _, ok := ctrOpts.Config.ExposedPorts[k]; ok {\n\t\t\t\ti.logger.Errorf(\"RunContainer: comms port conflict => %v\", k)\n\t\t\t}\n\n\t\t\tctrOpts.Config.ExposedPorts[k] = v\n\t\t}\n\t\ti.logger.Debugf(\"RunContainer: Config.ExposedPorts => %#v\", ctrOpts.Config.ExposedPorts)\n\t} else {\n\t\tctrOpts.Config.ExposedPorts = commsExposedPorts\n\t\ti.logger.Debugf(\"RunContainer: default exposed ports => %#v\", ctrOpts.Config.ExposedPorts)\n\t}\n\n\tif len(i.portBindings) > 0 {\n\t\t//need to add the IPC ports too\n\t\tcmdPort := dockerapi.Port(i.CmdPort)\n\t\tevtPort := dockerapi.Port(i.EvtPort)\n\t\tif pbInfo, ok := i.portBindings[cmdPort]; ok {\n\t\t\ti.exitIPCPortConflict(pbInfo, \"cmd\", -126)\n\t\t}\n\t\tif pbInfo, ok := i.portBindings[evtPort]; ok {\n\t\t\ti.exitIPCPortConflict(pbInfo, \"evt\", -127)\n\t\t}\n\n\t\ti.portBindings[cmdPort] = []dockerapi.PortBinding{{HostPort: cmdPortStrDefault}}\n\t\ti.portBindings[evtPort] = []dockerapi.PortBinding{{HostPort: evtPortStrDefault}}\n\n\t\tctrOpts.HostConfig.PortBindings = i.portBindings\n\t} else if i.DoPublishExposedPorts {\n\t\tportBindings := map[dockerapi.Port][]dockerapi.PortBinding{}\n\n\t\tif i.ImageInspector.ImageInfo.Config != nil {\n\t\t\tfor p := range i.ImageInspector.ImageInfo.Config.ExposedPorts {\n\t\t\t\tportBindings[p] = []dockerapi.PortBinding{{\n\t\t\t\t\tHostPort: p.Port(),\n\t\t\t\t}}\n\t\t\t}\n\t\t}\n\n\t\tfor p := range ctrOpts.Config.ExposedPorts {\n\t\t\tportBindings[p] = []dockerapi.PortBinding{{\n\t\t\t\tHostPort: p.Port(),\n\t\t\t}}\n\t\t}\n\n\t\tctrOpts.HostConfig.PortBindings = portBindings\n\t\ti.logger.Debugf(\"RunContainer: publishExposedPorts/portBindings => %+v\", portBindings)\n\t} else {\n\t\tctrOpts.HostConfig.PublishAllPorts = true\n\t\ti.logger.Debugf(\"RunContainer: HostConfig.PublishAllPorts => %v\", ctrOpts.HostConfig.PublishAllPorts)\n\t}\n\n\tif i.isHostNetworked() {\n\t\tportMap := map[dockerapi.Port][]dockerapi.PortBinding{}\n\t\tif ctrOpts.HostConfig.PublishAllPorts {\n\t\t\tfor p := range ctrOpts.Config.ExposedPorts {\n\t\t\t\tportMap[p] = []dockerapi.PortBinding{{HostPort: p.Port()}}\n\t\t\t}\n\t\t} else {\n\t\t\tportMap = ctrOpts.HostConfig.PortBindings\n\t\t}\n\n\t\thostProbePorts = map[dockerapi.Port][]dockerapi.PortBinding{}\n\t\tfor p, pbindings := range portMap {\n\t\t\tif p == i.CmdPort || p == i.EvtPort || p.Proto() != \"tcp\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif len(pbindings) == 0 {\n\t\t\t\tpbindings = []dockerapi.PortBinding{{HostPort: p.Port()}}\n\t\t\t}\n\t\t\t// Ensure all bindings at least have the loopback IP since this interface is\n\t\t\t// where host TCP ports are exposed by default.\n\t\t\tfor i, pbinding := range pbindings {\n\t\t\t\tif pbinding.HostIP == \"\" {\n\t\t\t\t\tpbindings[i].HostIP = localHostIP\n\t\t\t\t}\n\t\t\t}\n\t\t\thostProbePorts[p] = pbindings\n\t\t}\n\t\ti.logger.Debugf(\"RunContainer: host network loopback ports => %v\", hostProbePorts)\n\t}\n\n\treturn hostProbePorts\n}\n\nfunc (i *Inspector) setAvailablePorts(hostProbePorts map[dockerapi.Port][]dockerapi.PortBinding) {\n\ti.AvailablePorts = map[dockerapi.Port]dockerapi.PortBinding{}\n\taddPorts := func(keys, list []string, pk dockerapi.Port, pbinding []dockerapi.PortBinding) ([]string, []string) {\n\t\tif len(pbinding) > 0 {\n\t\t\tkeys = append(keys, fmt.Sprintf(\"%v => %v:%v\", pk, pbinding[0].HostIP, pbinding[0].HostPort))\n\t\t\tlist = append(list, string(pbinding[0].HostPort))\n\t\t} else {\n\t\t\tkeys = append(keys, string(pk))\n\t\t}\n\t\treturn keys, list\n\t}\n\n\t// These may be empty if host networking is used.\n\tvar portKeys, portList []string\n\tfor pk, pbinding := range i.ContainerInfo.NetworkSettings.Ports {\n\t\tif pk == i.CmdPort || pk == i.EvtPort {\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(pbinding) == 0 {\n\t\t\ti.logger.Debugf(\"setAvailablePorts: skipping empty port bindings => pk=%v\", pk)\n\t\t\tcontinue\n\t\t}\n\n\t\ti.AvailablePorts[pk] = pbinding[0]\n\n\t\tportKeys, portList = addPorts(portKeys, portList, pk, pbinding)\n\t}\n\n\tif i.isHostNetworked() {\n\t\tfor pk, pbinding := range hostProbePorts {\n\t\t\tif pk == i.CmdPort || pk == i.EvtPort {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// The above loop handled this key/binding.\n\t\t\tif b, added := i.AvailablePorts[pk]; added && b == (dockerapi.PortBinding{}) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\ti.AvailablePorts[pk] = pbinding[0]\n\n\t\t\tportKeys, portList = addPorts(portKeys, portList, pk, pbinding)\n\t\t}\n\t}\n\n\ti.ContainerPortList = strings.Join(portList, \",\")\n\ti.ContainerPortsInfo = strings.Join(portKeys, \",\")\n\tif i.isHostNetworked() {\n\t\tconst hostMsg = \"(ports on host loopback)\"\n\t\tif i.ContainerPortList != \"\" {\n\t\t\ti.ContainerPortList = fmt.Sprintf(\"%s %s\", i.ContainerPortList, hostMsg)\n\t\t}\n\t\tif i.ContainerPortsInfo != \"\" {\n\t\t\ti.ContainerPortsInfo = fmt.Sprintf(\"%s %s\", i.ContainerPortsInfo, hostMsg)\n\t\t}\n\t}\n}\n\nfunc (i *Inspector) exitIPCPortConflict(port []dockerapi.PortBinding, typ string, code int) {\n\ti.logger.Errorf(\"RunContainer: port bindings comms port conflict (%s) = %#v\", typ, port)\n\tif i.PrintState {\n\t\ti.xc.Out.Info(\"sensor.error\",\n\t\t\tovars{\n\t\t\t\t\"message\": \"port binding ipc port conflict\",\n\t\t\t\t\"type\":    typ,\n\t\t\t})\n\n\t\ti.xc.Out.State(\"exited\",\n\t\t\tovars{\n\t\t\t\t\"exit.code\": code,\n\t\t\t\t\"component\": \"container.inspector\",\n\t\t\t\t\"version\":   v.Current(),\n\t\t\t})\n\t}\n\n\ti.xc.Exit(code)\n}\n\nfunc (i *Inspector) ShowContainerLogs() {\n\tvar outData bytes.Buffer\n\toutw := bufio.NewWriter(&outData)\n\tvar errData bytes.Buffer\n\terrw := bufio.NewWriter(&errData)\n\n\ti.logger.Debug(\"getting container logs => \", i.ContainerID)\n\tlogsOptions := dockerapi.LogsOptions{\n\t\tContainer:    i.ContainerID,\n\t\tOutputStream: outw,\n\t\tErrorStream:  errw,\n\t\tStdout:       true,\n\t\tStderr:       true,\n\t}\n\n\terr := i.APIClient.Logs(logsOptions)\n\tif err != nil {\n\t\ti.logger.Infof(\"error getting container logs => %v - %v\", i.ContainerID, err)\n\t} else {\n\t\toutw.Flush()\n\t\terrw.Flush()\n\t\tfmt.Println(\"slim: container stdout:\")\n\t\t_, _ = outData.WriteTo(os.Stdout)\n\t\tfmt.Println(\"slim: container stderr:\")\n\t\t_, _ = errData.WriteTo(os.Stdout)\n\t\tfmt.Println(\"slim: end of container logs =============\")\n\t}\n}\n\n// ShutdownContainer terminates the container inspector instance execution\nfunc (i *Inspector) ShutdownContainer(terminateOnly bool) error {\n\tif i.ContainerID == \"\" {\n\t\t//no container to shutdown...\n\t\treturn nil\n\t}\n\n\tif i.isDone.IsOn() {\n\t\treturn nil\n\t}\n\n\tlogger := i.logger.WithField(\"op\", \"container.Inspector.ShutdownContainer\")\n\ti.isDone.On()\n\n\tdefer func() {\n\t\ti.shutdownContainerChannels()\n\n\t\tif i.DoShowContainerLogs {\n\t\t\ti.ShowContainerLogs()\n\t\t}\n\n\t\terr := i.APIClient.StopContainer(i.ContainerID, 9)\n\n\t\tif _, ok := err.(*dockerapi.ContainerNotRunning); ok {\n\t\t\tlogger.Info(\"can't stop the slim container (container is not running)...\")\n\t\t} else {\n\t\t\terrutil.WarnOn(err)\n\t\t}\n\n\t\tremoveOption := dockerapi.RemoveContainerOptions{\n\t\t\tID:            i.ContainerID,\n\t\t\tRemoveVolumes: true,\n\t\t\tForce:         true,\n\t\t}\n\n\t\tif err := i.APIClient.RemoveContainer(removeOption); err != nil {\n\t\t\tlogger.Infof(\"error removing container ('%v')... terminating container\", err)\n\t\t\t_ = i.APIClient.KillContainer(dockerapi.KillContainerOptions{ID: i.ContainerID})\n\t\t}\n\t}()\n\n\tif !terminateOnly {\n\t\tif !i.DoUseLocalMounts {\n\t\t\tdeleteOrig := true\n\t\t\tif i.DoKeepTmpArtifacts {\n\t\t\t\tdeleteOrig = false\n\t\t\t}\n\n\t\t\t//copy the container report\n\t\t\treportLocalPath := filepath.Join(i.LocalVolumePath, ArtifactsDir, ReportArtifactTar)\n\t\t\treportRemotePath := filepath.Join(app.DefaultArtifactsDirPath, report.DefaultContainerReportFileName)\n\t\t\terr := dockerutil.CopyFromContainer(i.APIClient, i.ContainerID, reportRemotePath, reportLocalPath, true, deleteOrig)\n\t\t\tif err != nil {\n\t\t\t\tlogger.WithError(err).WithField(\"container\", i.ContainerID).Error(\"dockerutil.CopyFromContainer\")\n\t\t\t\t//can't call errutil.FailOn() because we won't cleanup the target container\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif i.DoEnableMondel {\n\t\t\t\t//copy the monitor data event log (if available)\n\t\t\t\tmondelLocalPath := filepath.Join(i.LocalVolumePath, ArtifactsDir, MondelArtifactTar)\n\t\t\t\tmondelRemotePath := filepath.Join(app.DefaultArtifactsDirPath, report.DefaultMonDelFileName)\n\t\t\t\terr = dockerutil.CopyFromContainer(i.APIClient, i.ContainerID, mondelRemotePath, mondelLocalPath, true, deleteOrig)\n\t\t\t\tif err != nil {\n\t\t\t\t\t//not a failure because the log might not be there (just log it)\n\t\t\t\t\tlogger.WithFields(log.Fields{\n\t\t\t\t\t\t\"artifact.type\": \"mondel\",\n\t\t\t\t\t\t\"local.path\":    mondelLocalPath,\n\t\t\t\t\t\t\"remote.path\":   mondelRemotePath,\n\t\t\t\t\t\t\"err\":           err,\n\t\t\t\t\t}).Debug(\"dockerutil.CopyFromContainer\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/*\n\t\t\t\t//ALTERNATIVE WAY TO XFER THE FILE ARTIFACTS\n\t\t\t\tfilesOutLocalPath := filepath.Join(i.LocalVolumePath, ArtifactsDir, FileArtifactsArchiveTar)\n\t\t\t\tfilesTarRemotePath := filepath.Join(app.DefaultArtifactsDirPath, fileArtifactsTar)\n\t\t\t\terr = dockerutil.CopyFromContainer(i.APIClient,\n\t\t\t\t\ti.ContainerID,\n\t\t\t\t\tfilesTarRemotePath,\n\t\t\t\t\tfilesOutLocalPath,\n\t\t\t\t\ttrue,\n\t\t\t\t\tfalse) //make it 'true' once tested/debugged\n\t\t\t\tif err != nil {\n\t\t\t\t\terrutil.FailOn(err)\n\t\t\t\t}\n\t\t\t*/\n\n\t\t\tfilesOutLocalPath := filepath.Join(i.LocalVolumePath, ArtifactsDir, FileArtifactsOutTar)\n\t\t\tfilesRemotePath := filepath.Join(app.DefaultArtifactsDirPath, app.ArtifactFilesDirName)\n\t\t\terr = dockerutil.CopyFromContainer(i.APIClient, i.ContainerID, filesRemotePath, filesOutLocalPath, false, false)\n\t\t\tif err != nil {\n\t\t\t\tlogger.WithError(err).WithField(\"container\", i.ContainerID).Error(\"dockerutil.CopyFromContainer\")\n\t\t\t\t//can't call errutil.FailOn() because we won't cleanup the target container\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t//NOTE: possible enhancement (if the original filemode bits still get lost)\n\t\t\t//(alternative to archiving files in the container to preserve filemodes)\n\t\t\t//Rewrite the filemode bits using the data from creport.json,\n\t\t\t//but creport.json also needs to be enhanced to use\n\t\t\t//octal filemodes for the file records\n\t\t\terr = dockerutil.PrepareContainerDataArchive(filesOutLocalPath, fileArtifactsTar, app.ArtifactFilesDirName+\"/\", deleteOrig)\n\t\t\tif err != nil {\n\t\t\t\tlogger.WithError(err).WithField(\"container\", i.ContainerID).Error(\"dockerutil.PrepareContainerDataArchive\")\n\t\t\t\t//can't call errutil.FailOn() because we won't cleanup the target container\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// FinishMonitoring ends the target container monitoring activities\nfunc (i *Inspector) FinishMonitoring() {\n\tif i.dockerEventStopCh == nil {\n\t\tif i.PrintState {\n\t\t\ti.xc.Out.Info(\"container.inspector\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"already finished monitoring\",\n\t\t\t\t})\n\t\t}\n\n\t\treturn\n\t}\n\n\tclose(i.dockerEventStopCh)\n\ti.dockerEventStopCh = nil\n\n\tcmdResponse, err := i.ipcClient.SendCommand(&command.StopMonitor{})\n\terrutil.WarnOn(err)\n\t//_ = cmdResponse\n\ti.logger.Debugf(\"'stop' monitor response => '%v'\", cmdResponse)\n\n\ti.logger.Info(\"waiting for the container to finish its work...\")\n\n\tevt, err := i.ipcClient.GetEvent()\n\ti.logger.Debugf(\"sensor event => '%v'\", evt)\n\n\terrutil.WarnOn(err)\n\t_ = evt\n\ti.logger.Debugf(\"sensor event => '%v'\", evt)\n\n\tcmdResponse, err = i.ipcClient.SendCommand(&command.ShutdownSensor{})\n\tif err != nil {\n\t\ti.logger.Debugf(\"error sending 'shutdown' => '%v'\", err)\n\t}\n\ti.logger.Debugf(\"'shutdown' sensor response => '%v'\", cmdResponse)\n}\n\nfunc (i *Inspector) initContainerChannels() error {\n\tconst op = \"container.Inspector.initContainerChannels\"\n\n\tvar cn string\n\tif i.Overrides != nil {\n\t\tcn = i.Overrides.Network\n\t}\n\n\t// Top level IP info will not be populated when not using \"bridge\",\n\t// which is only set for backwards compatibility.\n\t//\n\t// https://github.com/moby/moby/issues/21658#issuecomment-203527083\n\tipAddr := i.ContainerInfo.NetworkSettings.IPAddress\n\tif cn != \"\" {\n\t\tnetwork, found := i.ContainerInfo.NetworkSettings.Networks[cn]\n\t\terrutil.FailWhen(!found, fmt.Sprintf(\"slim: error => expected NetworkSettings.Networks to contain %s: %v\",\n\t\t\tcn, i.ContainerInfo.NetworkSettings.Networks))\n\n\t\tipAddr = network.IPAddress\n\t}\n\t// If running in host mode, no IP may be set but the contained application\n\t// is listening on the exposed ports on localhost.\n\tif ipAddr == \"\" && i.isHostNetworked() {\n\t\tipAddr = localHostIP\n\t}\n\n\tif i.PrintState {\n\t\ti.xc.Out.Info(\"container\",\n\t\t\tovars{\n\t\t\t\t\"message\": \"obtained IP address\",\n\t\t\t\t\"ip\":      ipAddr,\n\t\t\t})\n\t}\n\n\tvar ipcMode string\n\tswitch i.SensorIPCMode {\n\tcase SensorIPCModeDirect, SensorIPCModeProxy:\n\t\tipcMode = i.SensorIPCMode\n\tdefault:\n\t\tif i.InContainer || i.isHostNetworked() {\n\t\t\tipcMode = SensorIPCModeDirect\n\t\t} else {\n\t\t\tipcMode = SensorIPCModeProxy\n\t\t}\n\t}\n\n\tvar cmdPort, evtPort string\n\tswitch ipcMode {\n\tcase SensorIPCModeDirect:\n\t\ti.TargetHost = ipAddr\n\t\tcmdPort = i.CmdPort.Port()\n\t\tevtPort = i.EvtPort.Port()\n\tcase SensorIPCModeProxy:\n\t\ti.DockerHostIP = dockerhost.GetIP(i.APIClient)\n\t\ti.TargetHost = i.DockerHostIP\n\t\tcmdPortBindings := i.ContainerInfo.NetworkSettings.Ports[i.CmdPort]\n\t\tevtPortBindings := i.ContainerInfo.NetworkSettings.Ports[i.EvtPort]\n\t\tcmdPort = cmdPortBindings[0].HostPort\n\t\tevtPort = evtPortBindings[0].HostPort\n\t}\n\ti.SensorIPCMode = ipcMode\n\n\tif i.SensorIPCEndpoint != \"\" {\n\t\ti.TargetHost = i.SensorIPCEndpoint\n\t}\n\n\ti.logger.WithFields(log.Fields{\n\t\t\"op\":                op,\n\t\t\"in.container\":      i.InContainer,\n\t\t\"container.network\": cn,\n\t\t\"ipc.mode\":          ipcMode,\n\t\t\"target\":            i.TargetHost,\n\t\t\"port.cmd\":          cmdPort,\n\t\t\"port.evt\":          evtPort,\n\t}).Debugf(\"target.container.ipc.connect\")\n\n\tipcClient, err := ipc.NewClient(i.TargetHost, cmdPort, evtPort, sensor.DefaultConnectWait)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ti.ipcClient = ipcClient\n\treturn nil\n}\n\nfunc (i *Inspector) shutdownContainerChannels() {\n\tconst op = \"container.Inspector.shutdownContainerChannels\"\n\tif i.ipcClient != nil {\n\t\tif err := i.ipcClient.Stop(); err != nil {\n\t\t\ti.logger.WithFields(log.Fields{\n\t\t\t\t\"op\":    op,\n\t\t\t\t\"error\": err,\n\t\t\t}).Debug(\"shutting down channels\")\n\t\t}\n\t\ti.ipcClient = nil\n\t}\n}\n\n// HasCollectedData returns true if any data was produced monitoring the target container\nfunc (i *Inspector) HasCollectedData() bool {\n\treturn fsutil.Exists(filepath.Join(i.ImageInspector.ArtifactLocation, report.DefaultContainerReportFileName))\n}\n\n// ProcessCollectedData performs post-processing on the collected container data\nfunc (i *Inspector) ProcessCollectedData() error {\n\ti.logger.Info(\"generating AppArmor profile...\")\n\terr := apparmor.GenProfile(i.ImageInspector.ArtifactLocation, i.ImageInspector.AppArmorProfileName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn seccomp.GenProfile(i.ImageInspector.ArtifactLocation, i.ImageInspector.SeccompProfileName)\n}\n\n/////////////////////////////////////////////////////////////////////////////////\n\nfunc sensorVolumeName() string {\n\treturn fmt.Sprintf(\"%s.%s\", sensorVolumeBaseName, v.Tag())\n}\n\nfunc ensureSensorVolume(logger *log.Entry, client *dockerapi.Client, localSensorPath, volumeName string) (string, error) {\n\tif volumeName == \"\" {\n\t\tvolumeName = sensorVolumeName()\n\t}\n\n\terr := dockerutil.HasVolume(client, volumeName)\n\tswitch {\n\tcase err == nil:\n\t\tlogger.Debugf(\"ensureSensorVolume: already have volume = %v\", volumeName)\n\t\t//TODO: need to check if the volume has the sensor (otherwise delete and recreate)\n\tcase err == dockerutil.ErrNotFound:\n\t\tlogger.Debugf(\"ensureSensorVolume: no volume yet = %v\", volumeName)\n\t\tif dockerutil.HasEmptyImage(client) == dockerutil.ErrNotFound {\n\t\t\terr := dockerutil.BuildEmptyImage(client)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Debugf(\"ensureSensorVolume: dockerutil.BuildEmptyImage() - error = %v\", err)\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t}\n\n\t\terr = dockerutil.CreateVolumeWithData(client, localSensorPath, volumeName, nil)\n\t\tif err != nil {\n\t\t\tlogger.Debugf(\"ensureSensorVolume: dockerutil.CreateVolumeWithData() - error = %v\", err)\n\t\t\treturn \"\", err\n\t\t}\n\tdefault:\n\t\tlogger.Debugf(\"ensureSensorVolume: dockerutil.HasVolume() - error = %v\", err)\n\t\treturn \"\", err\n\t}\n\n\treturn volumeName, nil\n}\n\nfunc attachContainerToNetwork(\n\tlogger *log.Entry,\n\tapiClient *dockerapi.Client,\n\tcontainerID string,\n\tnetNameInfo NetNameInfo,\n\tnetworkLinks []string) error {\n\t//network names seem to work ok (no need to use need network IDs)\n\toptions := dockerapi.NetworkConnectionOptions{\n\t\tContainer: containerID,\n\t\tEndpointConfig: &dockerapi.EndpointConfig{\n\t\t\tAliases: netNameInfo.Aliases,\n\t\t},\n\t}\n\n\tif len(networkLinks) > 0 {\n\t\toptions.EndpointConfig.Links = networkLinks\n\t}\n\n\tif err := apiClient.ConnectNetwork(netNameInfo.FullName, options); err != nil {\n\t\tlogger.Debugf(\"attachContainerToNetwork(%s,%s,%s): container network connect error - %v\",\n\t\t\tcontainerID, netNameInfo.FullName, networkLinks, err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/inspectors/container/container_startup.go",
    "content": "package container\n\nimport (\n\t\"strings\"\n)\n\nvar defaultShellFormPrefix = []string{\"/bin/sh\", \"-c\"}\n\nfunc hasPrefixSlice(input []string, prefix []string) bool {\n\tif len(prefix) > len(input) {\n\t\treturn false\n\t}\n\n\tfor idx, val := range prefix {\n\t\tif input[idx] != val {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc BuildStartupCommand(\n\tentrypoint []string,\n\tcmd []string,\n\tshell []string,\n\tclearEntrypoint bool,\n\tnewEntrypoint []string,\n\tclearCmd bool,\n\tnewCmd []string) []string {\n\tvar output []string\n\n\tif len(shell) == 0 {\n\t\tshell = defaultShellFormPrefix\n\t}\n\n\t// Dockerfile CMD and runtime cmd params\n\t// are ignored when entrypoint is in shell form\n\tentryIsShellForm := hasPrefixSlice(entrypoint, shell)\n\n\t//note: need to refactor this messy algorithm (keeping it as-is for now)...\n\tif !clearEntrypoint && !clearCmd && len(newEntrypoint) == 0 && len(newCmd) == 0 {\n\t\t//if entrypoint is in shell format then ignore cmd\n\t\toutput = append(output, entrypoint...)\n\t\tif !entryIsShellForm {\n\t\t\toutput = append(output, cmd...)\n\t\t}\n\t} else {\n\t\tif len(newEntrypoint) > 0 || clearEntrypoint {\n\t\t\toutput = append(output, newEntrypoint...)\n\n\t\t\tif len(newCmd) > 0 {\n\t\t\t\toutput = append(output, newCmd...)\n\t\t\t}\n\t\t\t//note: not using CMD from image if there's an override for ENTRYPOINT\n\t\t} else {\n\t\t\toutput = append(output, entrypoint...)\n\n\t\t\tif len(newCmd) > 0 || clearCmd {\n\t\t\t\toutput = append(output, newCmd...)\n\t\t\t} else {\n\t\t\t\tif !entryIsShellForm {\n\t\t\t\t\toutput = append(output, cmd...)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\temptyIdx := -1\n\tfor idx, val := range output {\n\t\tval = strings.TrimSpace(val)\n\t\tif val != \"\" {\n\t\t\tbreak\n\t\t}\n\n\t\temptyIdx = idx\n\t}\n\n\tif emptyIdx > -1 {\n\t\toutput = output[emptyIdx+1:]\n\t}\n\n\treturn output\n}\n"
  },
  {
    "path": "pkg/app/master/inspectors/image/extract_registry_test.go",
    "content": "package image\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n)\n\nfunc TestRegistryExtraction(t *testing.T) {\n\ttt := []struct {\n\t\tin       string\n\t\texpected string\n\t}{\n\t\t{in: \"https://gcr.io/nginx/nginx:3.9.11\", expected: \"https://gcr.io\"},\n\t\t{in: \"https://www.gcr.io/nginx/nginx:3.9.11\", expected: \"https://www.gcr.io\"},\n\t\t{in: \"eu.gcr.io/nginx/nginx:3.9.11\", expected: \"eu.gcr.io\"},\n\t\t{in: \"https://mcr.com/puppet/nginx:1.1.11\", expected: \"https://mcr.com\"},\n\t\t{in: \"http://192.168.10.11/nginx/nginx:3.9.11\", expected: \"http://192.168.10.11\"},\n\t\t{in: \"http://192.158.1.10:2678/nginx/nginx:3.9.11\", expected: \"http://192.158.1.10:2678\"},\n\t\t{in: \"https://192.158.1.10:2678/nginx/nginx:3.9.11\", expected: \"https://192.158.1.10:2678\"},\n\t\t{in: \"https://2001:0db8:85a3:0000:0000:8a2e:0370:7334/nginx/nginx:3.9.11\", expected: \"https://2001:0db8:85a3:0000:0000:8a2e:0370:7334\"},\n\t\t{in: \"https://2001:0db8:85a3:0000:0000:8a2e:0370:7334/nginx/nginx:3.9.11\", expected: \"https://2001:0db8:85a3:0000:0000:8a2e:0370:7334\"},\n\t\t{in: \"http://[2001:db8:1f70::999:de8:7648:6e8]:1000/nginx/rad:76.9\", expected: \"http://[2001:db8:1f70::999:de8:7648:6e8]:1000\"},\n\t\t{in: \"http://127.0.0.1/ops/scrap:latest\", expected: \"http://127.0.0.1\"},\n\t\t{in: \"127.0.0.1:4000/ops/scrap:latest\", expected: \"127.0.0.1:4000\"},\n\t\t{in: \"https://127.0.0.1:4000/ops/scrap:latest\", expected: \"https://127.0.0.1:4000\"},\n\t\t{in: \"http://localhost/ops/scrap:latest\", expected: \"http://localhost\"},\n\t\t{in: \"slim/docker-slim:latest\", expected: \"https://index.docker.io\"},\n\t\t//{in: \"local-registry/ops/scrap:latest\", expected: \"local-registry\"},\n\t\t//{in: \"local-registry:9000/ops/scrap:latest\", expected: \"local-registry:9000\"},\n\t}\n\n\tfor _, test := range tt {\n\t\tregistry := extractRegistry(test.in)\n\t\tif !equal(registry, test.expected) {\n\t\t\tt.Errorf(\"got %s expected %s\", registry, test.expected)\n\t\t}\n\t}\n}\n\nfunc equal(res, expected interface{}) bool {\n\treturn reflect.DeepEqual(res, expected)\n}\n"
  },
  {
    "path": "pkg/app/master/inspectors/image/image_inspector.go",
    "content": "package image\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile/reverse\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n)\n\nconst (\n\tslimImageRepo          = \"slim\"\n\tappArmorProfileName    = \"apparmor-profile\"\n\tseccompProfileName     = \"seccomp-profile\"\n\tappArmorProfileNamePat = \"%s-apparmor-profile\"\n\tseccompProfileNamePat  = \"%s-seccomp.json\"\n\thttps                  = \"https://\"\n\thttp                   = \"http://\"\n)\n\n// Inspector is a container image inspector\ntype Inspector struct {\n\tImageRef            string\n\tArtifactLocation    string\n\tSlimImageRepo       string\n\tAppArmorProfileName string\n\tSeccompProfileName  string\n\tImageInfo           *docker.Image\n\tImageRecordInfo     docker.APIImages\n\tAPIClient           *docker.Client\n\t//fatImageDockerInstructions []string\n\tDockerfileInfo *reverse.Dockerfile\n}\n\n// NewInspector creates a new container image inspector\nfunc NewInspector(client *docker.Client, imageRef string /*, artifactLocation string*/) (*Inspector, error) {\n\tinspector := &Inspector{\n\t\tImageRef:            imageRef,\n\t\tSlimImageRepo:       slimImageRepo,\n\t\tAppArmorProfileName: appArmorProfileName,\n\t\tSeccompProfileName:  seccompProfileName,\n\t\t//ArtifactLocation:    artifactLocation,\n\t\tAPIClient: client,\n\t}\n\n\treturn inspector, nil\n}\n\n// NoImage returns true if the target image doesn't exist\nfunc (i *Inspector) NoImage() (bool, error) {\n\t//first, do a simple exact match lookup\n\tii, err := dockerutil.HasImage(i.APIClient, i.ImageRef)\n\tif err == nil {\n\t\tlog.Tracef(\"image.inspector.NoImage: ImageRef=%v ImageIdentity=%#v\", i.ImageRef, ii)\n\t\treturn false, nil\n\t}\n\n\tif err != dockerutil.ErrNotFound {\n\t\tlog.Errorf(\"image.inspector.NoImage: err=%v\", err)\n\t\treturn true, err\n\t}\n\n\t//second, try to find something close enough\n\t//handle the case where there's no tag in the target image reference\n\t//and there are no default 'latest' tag\n\t//this will return/save the first available tag\n\tif err == dockerutil.ErrNotFound &&\n\t\t!strings.Contains(i.ImageRef, \":\") {\n\t\t//check if there are any tags for the target image\n\t\tmatches, err := dockerutil.ListImages(i.APIClient, i.ImageRef)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"image.inspector.NoImage: err=%v\", err)\n\t\t\treturn true, err\n\t\t}\n\n\t\tfor ref, props := range matches {\n\t\t\tlog.Debugf(\"image.inspector.NoImage: match.ref=%s match.props=%#v\", ref, props)\n\t\t\ti.ImageRef = ref\n\t\t\treturn false, nil\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\n// Pull tries to download the target image\nfunc (i *Inspector) Pull(showPullLog bool, dockerConfigPath, registryAccount, registrySecret string) error {\n\tvar pullLog bytes.Buffer\n\tvar repo string\n\tvar tag string\n\tif strings.Contains(i.ImageRef, \":\") {\n\t\tparts := strings.SplitN(i.ImageRef, \":\", 2)\n\t\trepo = parts[0]\n\t\ttag = parts[1]\n\t} else {\n\t\trepo = i.ImageRef\n\t\ttag = \"latest\"\n\t}\n\n\tinput := docker.PullImageOptions{\n\t\tRepository: repo,\n\t\tTag:        tag,\n\t}\n\n\tif showPullLog {\n\t\tinput.OutputStream = &pullLog\n\t}\n\n\tvar err error\n\tvar authConfig *docker.AuthConfiguration\n\tregistry := extractRegistry(repo)\n\tauthConfig, err = getRegistryCredential(registryAccount, registrySecret, dockerConfigPath, registry)\n\tif err != nil {\n\t\tlog.Warnf(\"image.inspector.Pull: failed to get registry credential for registry=%s with err=%v\", registry, err)\n\t\t//warn, attempt pull anyway, needs to work for public registries\n\t}\n\n\tif authConfig == nil {\n\t\tauthConfig = &docker.AuthConfiguration{}\n\t}\n\n\terr = i.APIClient.PullImage(input, *authConfig)\n\tif err != nil {\n\t\tlog.Debugf(\"image.inspector.Pull: client.PullImage err=%v\", err)\n\t\treturn err\n\t}\n\n\tif showPullLog {\n\t\tfmt.Printf(\"pull logs ====================\\n\")\n\t\tfmt.Println(pullLog.String())\n\t\tfmt.Printf(\"end of pull logs =============\\n\")\n\t}\n\n\treturn nil\n}\n\nfunc getRegistryCredential(registryAccount, registrySecret, dockerConfigPath, registry string) (cred *docker.AuthConfiguration, err error) {\n\tif registryAccount != \"\" && registrySecret != \"\" {\n\t\tcred = &docker.AuthConfiguration{\n\t\t\tUsername: registryAccount,\n\t\t\tPassword: registrySecret,\n\t\t}\n\t\treturn\n\t}\n\n\tmissingAuthConfigErr := fmt.Errorf(\"could not find an auth config for registry - %s\", registry)\n\tif dockerConfigPath != \"\" {\n\t\tdAuthConfigs, err := docker.NewAuthConfigurationsFromFile(dockerConfigPath)\n\t\tif err != nil {\n\t\t\tlog.Warnf(\n\t\t\t\t\"image.inspector.Pull: getDockerCredential - failed to acquire local docker config path=%s err=%s\",\n\t\t\t\tdockerConfigPath,\n\t\t\t\terr.Error(),\n\t\t\t)\n\t\t\treturn nil, err\n\t\t}\n\t\tr, found := dAuthConfigs.Configs[registry]\n\t\tif !found {\n\t\t\treturn nil, missingAuthConfigErr\n\t\t}\n\t\tcred = &r\n\t\treturn cred, nil\n\t}\n\n\tcred, err = docker.NewAuthConfigurationsFromCredsHelpers(registry)\n\tif err != nil {\n\t\tlog.Warnf(\n\t\t\t\"image.inspector.Pull: failed to acquire local docker credential helpers for %s err=%s\",\n\t\t\tregistry,\n\t\t\terr.Error(),\n\t\t)\n\t\treturn nil, err\n\t}\n\n\t// could not find a credentials' helper, check auth configs\n\tif cred == nil {\n\t\tdConfigs, err := docker.NewAuthConfigurationsFromDockerCfg()\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"image.inspector.Pull: getDockerCredential err extracting docker auth configs - %s\", err.Error())\n\t\t\treturn nil, err\n\t\t}\n\t\tr, found := dConfigs.Configs[registry]\n\t\tif !found {\n\t\t\treturn nil, missingAuthConfigErr\n\t\t}\n\t\tcred = &r\n\t}\n\n\tlog.Debugf(\"loaded registry auth config %+v\", cred)\n\treturn cred, nil\n}\n\nfunc extractRegistry(repo string) string {\n\tvar scheme string\n\tif strings.Contains(repo, https) {\n\t\tscheme = https\n\t\trepo = strings.TrimPrefix(repo, https)\n\t}\n\tif strings.Contains(repo, http) {\n\t\tscheme = http\n\t\trepo = strings.TrimPrefix(repo, http)\n\t}\n\tregistry := strings.Split(repo, \"/\")[0]\n\n\tdomain := `((?:[a-z\\d](?:[a-z\\d-]{0,63}[a-z\\d])?|\\*)\\.)+[a-z\\d][a-z\\d-]{0,63}[a-z\\d]`\n\tipv6 := `^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$`\n\tipv4 := `^(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.|$)){4})`\n\tipv4Port := `([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})\\:?([0-9]{1,5})?`\n\tipv6Port := `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`\n\n\tif registry == \"localhost\" || strings.Contains(registry, \"localhost:\") {\n\t\treturn scheme + registry\n\t}\n\n\tvalidDomain := regexp.MustCompile(domain)\n\tvalidIpv4 := regexp.MustCompile(ipv4)\n\tvalidIpv6 := regexp.MustCompile(ipv6)\n\tvalidIpv4WithPort := regexp.MustCompile(ipv4Port)\n\tvalidIpv6WithPort := regexp.MustCompile(ipv6Port)\n\n\tif validIpv6WithPort.MatchString(registry) {\n\t\treturn scheme + registry\n\t}\n\tif validIpv4WithPort.MatchString(registry) {\n\t\treturn scheme + registry\n\t}\n\tif validIpv6.MatchString(registry) {\n\t\treturn scheme + registry\n\t}\n\tif validIpv4.MatchString(registry) {\n\t\treturn scheme + registry\n\t}\n\n\tif !validDomain.MatchString(registry) {\n\t\treturn https + \"index.docker.io\"\n\t}\n\treturn scheme + registry\n}\n\n// Inspect starts the target image inspection\nfunc (i *Inspector) Inspect() error {\n\tvar err error\n\ti.ImageInfo, err = i.APIClient.InspectImage(i.ImageRef)\n\tif err != nil {\n\t\tif err == docker.ErrNoSuchImage {\n\t\t\tlog.Info(\"could not find target image\")\n\t\t}\n\t\treturn err\n\t}\n\n\tlog.Tracef(\"image.Inspector.Inspect: ImageInfo=%#v\", i.ImageInfo)\n\n\timageList, err := i.APIClient.ListImages(docker.ListImagesOptions{All: true})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlog.Tracef(\"image.Inspector.Inspect: imageList.size=%v\", len(imageList))\n\tfor _, r := range imageList {\n\t\tlog.Tracef(\"image.Inspector.Inspect: target=%v record=%#v\", i.ImageInfo.ID, r)\n\t\tif r.ID == i.ImageInfo.ID {\n\t\t\ti.ImageRecordInfo = r\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif i.ImageRecordInfo.ID == \"\" {\n\t\tlog.Info(\"could not find target image in the image list\")\n\t\treturn docker.ErrNoSuchImage\n\t}\n\n\treturn nil\n}\n\nfunc (i *Inspector) processImageName() {\n\tif len(i.ImageRecordInfo.RepoTags) > 0 {\n\t\t//try to find the repo/tag that matches the image ref (if it's not an image ID)\n\t\t//then pick the first available repo/tag if we can't\n\t\timageName := i.ImageRecordInfo.RepoTags[0]\n\t\tfor _, current := range i.ImageRecordInfo.RepoTags {\n\t\t\tif strings.HasPrefix(current, i.ImageRef) {\n\t\t\t\timageName = current\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif rtInfo := strings.Split(imageName, \":\"); len(rtInfo) > 1 {\n\t\t\tif rtInfo[0] == \"<none>\" {\n\t\t\t\trtInfo[0] = strings.TrimLeft(i.ImageRecordInfo.ID, \"sha256:\")[0:8]\n\t\t\t}\n\t\t\ti.SlimImageRepo = fmt.Sprintf(\"%s.slim\", rtInfo[0])\n\t\t\tif nameParts := strings.Split(rtInfo[0], \"/\"); len(nameParts) > 1 {\n\t\t\t\ti.AppArmorProfileName = strings.Join(nameParts, \"-\")\n\t\t\t\ti.SeccompProfileName = strings.Join(nameParts, \"-\")\n\t\t\t} else {\n\t\t\t\ti.AppArmorProfileName = rtInfo[0]\n\t\t\t\ti.SeccompProfileName = rtInfo[0]\n\t\t\t}\n\t\t\ti.AppArmorProfileName = fmt.Sprintf(appArmorProfileNamePat, i.AppArmorProfileName)\n\t\t\ti.SeccompProfileName = fmt.Sprintf(seccompProfileNamePat, i.SeccompProfileName)\n\t\t}\n\t}\n}\n\n// ProcessCollectedData performs post-processing on the collected image data\nfunc (i *Inspector) ProcessCollectedData() error {\n\ti.processImageName()\n\n\tvar err error\n\ti.DockerfileInfo, err = reverse.DockerfileFromHistory(i.APIClient, i.ImageRef)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfatImageDockerfileLocation := filepath.Join(i.ArtifactLocation, consts.ReversedDockerfile)\n\terr = reverse.SaveDockerfileData(fatImageDockerfileLocation, i.DockerfileInfo.Lines)\n\terrutil.FailOn(err)\n\t//save the reversed Dockerfile with the old name too (tmp compat)\n\tfatImageDockerfileLocationOld := filepath.Join(i.ArtifactLocation, consts.ReversedDockerfileOldName)\n\terr = reverse.SaveDockerfileData(fatImageDockerfileLocationOld, i.DockerfileInfo.Lines)\n\terrutil.WarnOn(err)\n\n\treturn nil\n}\n\n// ShowFatImageDockerInstructions prints the original target image Dockerfile instructions\nfunc (i *Inspector) ShowFatImageDockerInstructions() {\n\tif i.DockerfileInfo != nil && i.DockerfileInfo.Lines != nil {\n\t\tfmt.Println(\"slim: Fat image - Dockerfile instructures: start ====\")\n\t\tfmt.Println(strings.Join(i.DockerfileInfo.Lines, \"\\n\"))\n\t\tfmt.Println(\"slim: Fat image - Dockerfile instructures: end ======\")\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/inspectors/ipc/ipc.go",
    "content": "package ipc\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/ipc/channel\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n)\n\nconst (\n\tconnectTimeout = 15\n\treadTimeout    = 30\n\twriteTimeout   = 30\n)\n\ntype Client struct {\n\tconnectWait int\n\ttarget      string\n\tcmdPort     string\n\tevtPort     string\n\tevtChannel  *channel.EventClient\n\tcmdChannel  *channel.CommandClient\n}\n\nfunc NewClient(target, cmdChannelPort, evtChannelPort string, connectWait int) (*Client, error) {\n\tlog.Debugf(\"ipc.NewClient(%s,%s,%s)\", target, cmdChannelPort, evtChannelPort)\n\tclient := Client{\n\t\ttarget:      target,\n\t\tcmdPort:     cmdChannelPort,\n\t\tevtPort:     evtChannelPort,\n\t\tconnectWait: connectWait,\n\t}\n\n\tif client.cmdPort == \"\" {\n\t\tclient.cmdPort = fmt.Sprintf(\"%d\", channel.CmdPort)\n\t}\n\n\tif client.evtPort == \"\" {\n\t\tclient.evtPort = fmt.Sprintf(\"%d\", channel.EvtPort)\n\t}\n\n\tif err := client.initChannels(); err != nil {\n\t\tlog.Errorf(\"ipc.NewClient init error = %v\", err)\n\t\treturn nil, err\n\t}\n\n\treturn &client, nil\n}\n\nfunc (c *Client) initChannels() error {\n\tcmdChannelAddr := fmt.Sprintf(\"%s:%s\", c.target, c.cmdPort)\n\tcmdChannel, err := channel.NewCommandClient(cmdChannelAddr, c.connectWait, connectTimeout, readTimeout, writeTimeout)\n\tif os.IsTimeout(err) {\n\t\tlog.Debug(\"ipc.initChannels(): connect timeout...\")\n\t\treturn err\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\tc.cmdChannel = cmdChannel\n\n\tevtChannelAddr := fmt.Sprintf(\"%s:%s\", c.target, c.evtPort)\n\tevtChannel, err := channel.NewEventClient(evtChannelAddr, c.connectWait, connectTimeout, -1)\n\tif os.IsTimeout(err) {\n\t\tlog.Debug(\"ipc.initChannels(): connect timeout...\")\n\t\treturn err\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\tc.evtChannel = evtChannel\n\n\treturn nil\n}\n\nfunc (c *Client) shutdownChannels() error {\n\tif c.cmdChannel != nil {\n\t\tc.cmdChannel.Close()\n\t\tc.cmdChannel = nil\n\t}\n\n\tif c.evtChannel != nil {\n\t\tc.evtChannel.Close()\n\t\tc.evtChannel = nil\n\t}\n\n\treturn nil\n}\n\nfunc (c *Client) Stop() error {\n\treturn c.shutdownChannels()\n}\n\nfunc (c *Client) SendCommand(cmd command.Message) (*command.Response, error) {\n\treqData, err := command.Encode(cmd)\n\tif err != nil {\n\t\tlog.Error(\"ipc.Client.SendCommand(): malformed cmd - \", err)\n\t\treturn nil, err\n\t}\n\n\tlog.Debugf(\"ipc.Client.SendCommand() cmd channel call data='%s'\\n\", string(reqData))\n\trespData, err := c.cmdChannel.Call(reqData, 3)\n\tif err != nil {\n\t\tlog.Errorf(\"ipc.Client.SendCommand() cmd channel call error=%v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tlog.Debugf(\"ipc.Client.SendCommand() cmd channel call response='%s'\\n\", string(respData))\n\tif len(respData) == 0 {\n\t\tlog.Info(\"ipc.Client.SendCommand() no cmd channel call response (closed connection)\")\n\t\treturn nil, nil\n\t}\n\n\tvar resp command.Response\n\terr = json.Unmarshal(respData, &resp)\n\tif err != nil {\n\t\tlog.Error(\"ipc.Client.SendCommand(): malformed cmd response - \", err)\n\t\treturn nil, err\n\t}\n\n\treturn &resp, nil\n}\n\nfunc (c *Client) GetEvent() (*event.Message, error) {\n\traw, id, err := c.evtChannel.Next(3)\n\tif err != nil {\n\t\tlog.Errorf(\"ipc.Client.GetEvent(): event channel error = %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\tlog.Debugf(\"ipc.Client.GetEvent(): channel.Recv() - done [tid=%s evt=%v]\\n\", id, string(raw))\n\tif len(raw) == 0 {\n\t\tlog.Info(\"ipc.Client.GetEvent() no event channel data (closed connection)\")\n\t\treturn nil, nil\n\t}\n\n\tvar evt event.Message\n\tif err := json.Unmarshal(raw, &evt); err != nil {\n\t\tlog.Errorf(\"ipc.Client.GetEvent(): malformed event = %v\\n\", err)\n\t\treturn nil, err\n\t}\n\n\treturn &evt, nil\n}\n"
  },
  {
    "path": "pkg/app/master/inspectors/pod/pod_inspector.go",
    "content": "package pod\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/image\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/ipc\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/sensor\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/kubernetes\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/security/apparmor\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/security/seccomp\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/channel\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/util/wait\"\n)\n\ntype ovars = app.OutVars\n\n// TODO: unify with similar constants in container_inspector.go\nconst (\n\tsensorVolumeName      = \"slim-sensor\"\n\tsensorVolumeMountPath = \"/opt/_slim/bin\"\n\tsensorBinFileAbs      = sensorVolumeMountPath + \"/\" + sensor.LocalBinFile\n\tsensorLoaderContainer = \"slim-sensor-loader\"\n\n\tartifactsVolumeName = \"slim-artifacts\"\n\n\ttargetPodLabelName = \"dockersl.im/target-pod\"\n\ttargetPodLabelPat  = \"slimk_%v_%v\"\n)\n\ntype portInfo struct {\n\t// Ports found to be available for probing.\n\tavailablePorts map[dockerapi.Port]dockerapi.PortBinding\n\tpodPortsInfo   []string\n\tpodPortList    []string\n\n\t// Needed only to populate the struct during the RunPod() call.\n\tmux sync.Mutex\n}\n\ntype Inspector struct {\n\tctx         context.Context\n\tctxCancelFn context.CancelFunc\n\n\txc         *app.ExecutionContext\n\tlogger     *log.Entry\n\tkubectl    kubernetes.Kubectl\n\tkubeClient *kubernetes.Client\n\n\tworkload       *kubernetes.Workload\n\timageInspector *image.Inspector\n\n\tfatContainerCmd []string\n\tkeepPerms       bool\n\tpathPerms       map[string]*fsutil.AccessInfo\n\t// ExcludePatterns       map[string]*fsutil.AccessInfo\n\t// PreservePaths         map[string]*fsutil.AccessInfo\n\t// IncludePaths          map[string]*fsutil.AccessInfo\n\t// IncludeBins           map[string]*fsutil.AccessInfo\n\t// IncludeExes           map[string]*fsutil.AccessInfo\n\t// DoIncludeShell        bool\n\t// DoIncludeCertAll      bool\n\t// DoIncludeCertBundles  bool\n\t// DoIncludeCertDirs     bool\n\t// DoIncludeCertPKAll    bool\n\t// DoIncludeCertPKDirs   bool\n\t// DoIncludeNew          bool\n\tdoDebug           bool\n\tlogLevel          string\n\tlogFormat         string\n\trtaSourcePT       bool\n\tsensorIPCEndpoint string\n\tstatePath         string\n\n\tportBindings          map[dockerapi.Port][]dockerapi.PortBinding\n\tdoPublishExposedPorts bool\n\tportInfo              portInfo\n\n\tpod             *corev1.Pod\n\tsensorIPCClient *ipc.Client\n}\n\nfunc NewInspector(\n\tctx context.Context,\n\txc *app.ExecutionContext,\n\tlogger *log.Entry,\n\tworkload *kubernetes.Workload,\n\tkubectl kubernetes.Kubectl,\n\tkubeClient *kubernetes.Client,\n\timageInspector *image.Inspector,\n\tkeepPerms bool,\n\tpathPerms map[string]*fsutil.AccessInfo,\n\t// TODO: pass these params\n\t// ExcludePatterns       map[string]*fsutil.AccessInfo\n\t// PreservePaths         map[string]*fsutil.AccessInfo\n\t// IncludePaths          map[string]*fsutil.AccessInfo\n\t// IncludeBins           map[string]*fsutil.AccessInfo\n\t// IncludeExes           map[string]*fsutil.AccessInfo\n\t// DoIncludeShell        bool\n\t// DoIncludeCertAll      bool\n\t// DoIncludeCertBundles  bool\n\t// DoIncludeCertDirs     bool\n\t// DoIncludeCertPKAll    bool\n\t// DoIncludeCertPKDirs   bool\n\t// DoIncludeNew          bool\n\tdoDebug bool,\n\tlogLevel string,\n\tlogFormat string,\n\trtaSourcePT bool,\n\tstatePath string,\n\tcontOverrides *config.ContainerOverrides,\n\tsensorIPCEndpoint string,\n\tportBindings map[dockerapi.Port][]dockerapi.PortBinding,\n\tdoPublishExposedPorts bool,\n) (*Inspector, error) {\n\tctx, cancelFn := context.WithCancel(ctx)\n\treturn &Inspector{\n\t\tctx:                   ctx,\n\t\tctxCancelFn:           cancelFn,\n\t\txc:                    xc,\n\t\tlogger:                logger,\n\t\tworkload:              workload,\n\t\tkubectl:               kubectl,\n\t\tkubeClient:            kubeClient,\n\t\timageInspector:        imageInspector,\n\t\tfatContainerCmd:       fatContainerCmd(workload, imageInspector, contOverrides),\n\t\tkeepPerms:             keepPerms,\n\t\tpathPerms:             pathPerms,\n\t\tdoDebug:               doDebug,\n\t\tlogLevel:              logLevel,\n\t\tlogFormat:             logFormat,\n\t\trtaSourcePT:           rtaSourcePT,\n\t\tstatePath:             statePath,\n\t\tsensorIPCEndpoint:     sensorIPCEndpoint,\n\t\tportBindings:          portBindings,\n\t\tdoPublishExposedPorts: doPublishExposedPorts,\n\t\tportInfo: portInfo{\n\t\t\tavailablePorts: map[dockerapi.Port]dockerapi.PortBinding{},\n\t\t},\n\t}, nil\n}\n\nfunc (i *Inspector) TargetHost() string {\n\t// Since at the moment we rely only on `kubectl port-forward`\n\treturn \"127.0.0.1\"\n}\n\nfunc (i *Inspector) RunPod() error {\n\tif err := i.prepareWorkload(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := i.applyWorkload(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := waitForContainer(i.ctx, i.kubeClient, i.pod.Namespace, i.pod.Name, sensorLoaderContainer, true); err != nil {\n\t\treturn err\n\t}\n\n\tlocalSensorPath := sensor.EnsureLocalBinary(i.xc, i.logger, i.statePath, true)\n\ti.logger.Debugf(\"RunPod: detected sensor at %q\", localSensorPath)\n\n\tif err := i.injectSensor(localSensorPath); err != nil {\n\t\treturn err\n\t}\n\n\tif err := waitForContainer(i.ctx, i.kubeClient, i.pod.Namespace, i.pod.Name, i.workload.TargetContainer().Name, false); err != nil {\n\t\treturn err\n\t}\n\n\tif err := i.sensorConnect(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := i.sensorCommandStart(); err != nil {\n\t\treturn err\n\t}\n\n\treturn i.publishPorts()\n}\n\nfunc (i *Inspector) PodName() string {\n\treturn i.pod.Namespace + \"/\" + i.pod.Name\n}\n\nfunc (i *Inspector) PodPortsInfo() string {\n\treturn strings.Join(i.portInfo.podPortsInfo, \",\")\n}\n\nfunc (i *Inspector) PodPortList() string {\n\treturn strings.Join(i.portInfo.podPortList, \",\")\n}\n\nfunc (i *Inspector) AvailablePorts() map[dockerapi.Port]dockerapi.PortBinding {\n\treturn i.portInfo.availablePorts\n}\n\nfunc (i *Inspector) FinishMonitoring() {\n\tif i.sensorIPCClient == nil {\n\t\treturn\n\t}\n\n\terrutil.WarnOn(i.sensorCommandStop())\n\n\tout, err := i.kubectl.CpFrom(\n\t\ti.ctx,\n\t\ti.pod.Namespace,\n\t\ti.pod.Name,\n\t\ti.workload.TargetContainer().Name,\n\t\tfilepath.Join(app.DefaultArtifactsDirPath, report.DefaultContainerReportFileName),\n\t\tfilepath.Join(i.imageInspector.ArtifactLocation, report.DefaultContainerReportFileName),\n\t)\n\tif err != nil {\n\t\terrutil.WarnOn(err)\n\t\ti.logger.Debugf(\"RunPod: kubectl cp pod:artifacts:creport -> localArtifactLocation failed with %q: %s\", err, string(out))\n\t}\n\n\tout, err = i.kubectl.CpFrom(\n\t\ti.ctx,\n\t\ti.pod.Namespace,\n\t\ti.pod.Name,\n\t\ti.workload.TargetContainer().Name,\n\t\tfilepath.Join(app.DefaultArtifactsDirPath, app.ArtifactFilesDirName),\n\t\tfilepath.Join(i.imageInspector.ArtifactLocation, app.ArtifactFilesDirName+\"/\"),\n\t)\n\tif err != nil {\n\t\terrutil.WarnOn(err)\n\t\ti.logger.Debugf(\"RunPod: kubectl cp pod:artifacts:files -> localArtifactLocation failed with %q: %s\", err, string(out))\n\t}\n}\n\nfunc (i *Inspector) ShowPodLogs() {\n\t// TODO: Implement me!\n\tfmt.Println(\"slim: pod stdout:\")\n\tfmt.Println(\"slim: pod stderr:\")\n\tfmt.Println(\"slim: end of pod logs =============\")\n}\n\nfunc (i *Inspector) ShutdownPod(resetChanges bool) {\n\tif i.sensorIPCClient == nil {\n\t\treturn\n\t}\n\n\tresp, err := i.sensorIPCClient.SendCommand(&command.ShutdownSensor{})\n\tif err != nil {\n\t\ti.logger.Debugf(\"error sending 'shutdown' => '%v'\", err)\n\t}\n\ti.logger.Debugf(\"'shutdown' sensor response => '%v'\", resp)\n\n\tif resetChanges {\n\t\ti.workload.ResetChanges()\n\t\tif err := i.kubeClient.CreateOrUpdate(i.ctx, i.workload.Info()); err != nil {\n\t\t\ti.logger.Debugf(\"error resetting workload changes => '%v'\", err)\n\t\t}\n\t} else if i.workload.SetReplicasIfApplicable(0) {\n\t\tif err := i.kubeClient.CreateOrUpdate(i.ctx, i.workload.Info()); err != nil {\n\t\t\ti.logger.Debugf(\"error scaling down the workload => '%v'\", err)\n\t\t}\n\t}\n\n\ti.sensorDisconnect()\n\ti.ctxCancelFn()\n}\n\nfunc (i *Inspector) HasCollectedData() bool {\n\treturn fsutil.Exists(filepath.Join(i.imageInspector.ArtifactLocation, report.DefaultContainerReportFileName))\n}\n\nfunc (i *Inspector) ProcessCollectedData() error {\n\ti.logger.Info(\"generating AppArmor profile...\")\n\terr := apparmor.GenProfile(i.imageInspector.ArtifactLocation, i.imageInspector.AppArmorProfileName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn seccomp.GenProfile(i.imageInspector.ArtifactLocation, i.imageInspector.SeccompProfileName)\n}\n\nfunc (i *Inspector) Exec(cmd string, args ...string) ([]byte, error) {\n\treturn i.kubectl.Exec(\n\t\ti.ctx,\n\t\ti.pod.Namespace,\n\t\ti.pod.Name,\n\t\ti.workload.TargetContainer().Name,\n\t\tcmd,\n\t\targs...,\n\t)\n}\n\nfunc (i *Inspector) prepareWorkload() error {\n\ti.workload.Template().Labels[targetPodLabelName] = fmt.Sprintf(\n\t\ttargetPodLabelPat, os.Getpid(), time.Now().UTC().Format(\"20060102150405\"))\n\n\ti.workload.AddEmptyDirVolume(sensorVolumeName)\n\n\ti.workload.AddEmptyDirVolume(artifactsVolumeName)\n\n\ti.workload.AddInitContainer(corev1.Container{\n\t\tName:  sensorLoaderContainer,\n\t\tImage: \"alpine\",\n\t\tCommand: []string{\n\t\t\t\"sh\",\n\t\t\t\"-c\",\n\t\t\tfmt.Sprintf(\n\t\t\t\t`until [ -f %s ]; do echo \"Waiting for sensor to appear...\"; sleep 1; done; echo \"Sensor found! Exiting...\"`,\n\t\t\t\tsensorBinFileAbs,\n\t\t\t),\n\t\t},\n\t\tVolumeMounts: []corev1.VolumeMount{\n\t\t\t{Name: sensorVolumeName, MountPath: sensorVolumeMountPath},\n\t\t},\n\t})\n\n\ti.workload.SetReplicasIfApplicable(1)\n\n\ttargetCont := i.workload.TargetContainer()\n\ttargetCont.VolumeMounts = append(\n\t\ttargetCont.VolumeMounts,\n\t\tcorev1.VolumeMount{\n\t\t\tName:      sensorVolumeName,\n\t\t\tMountPath: sensorVolumeMountPath,\n\t\t},\n\t\tcorev1.VolumeMount{\n\t\t\tName:      artifactsVolumeName,\n\t\t\tMountPath: app.DefaultArtifactsDirPath,\n\t\t},\n\t)\n\n\ttargetCont.Command = []string{sensorBinFileAbs}\n\n\tif targetCont.SecurityContext == nil {\n\t\ttargetCont.SecurityContext = &corev1.SecurityContext{}\n\t}\n\n\ttargetCont.SecurityContext.Privileged = boolPtr(true)\n\n\t// TODO: check if it's already there\n\tif targetCont.SecurityContext.Capabilities == nil {\n\t\ttargetCont.SecurityContext.Capabilities = &corev1.Capabilities{}\n\t}\n\ttargetCont.SecurityContext.Capabilities.Add = append(\n\t\ttargetCont.SecurityContext.Capabilities.Add,\n\t\t\"SYS_ADMIN\",\n\t)\n\n\treturn nil\n}\n\nfunc (i *Inspector) applyWorkload() error {\n\tif err := i.kubeClient.CreateOrUpdate(i.ctx, i.workload.Info()); err != nil {\n\t\treturn err\n\t}\n\ti.logger.Debugf(\"RunPod: workload (re)applied. Waiting for pod to start up...\")\n\n\tpod, err := findPod(i.ctx, i.kubeClient, i.workload.Namespace(), i.workload.Template().Labels[targetPodLabelName])\n\tif err != nil {\n\t\treturn err\n\t}\n\ti.logger.Debugf(\"RunPod: found workload pod '%s/%s'. Waiting for sensor-loader container to start up...\", pod.Namespace, pod.Name)\n\n\ti.xc.Out.Info(\"pod\",\n\t\tovars{\n\t\t\t\"status\":    \"created\",\n\t\t\t\"namespace\": pod.Namespace,\n\t\t\t\"name\":      pod.Name,\n\t\t})\n\n\ti.pod = &pod\n\treturn nil\n}\n\nfunc (i *Inspector) publishPorts() error {\n\ttoPublish := map[dockerapi.Port][]dockerapi.PortBinding{}\n\n\tif len(i.portBindings) > 0 {\n\t\tfor contPort, hostPorts := range i.portBindings {\n\t\t\tif contPort.Port() == toStringPort(channel.CmdPort) {\n\t\t\t\ti.exitIPCPortConflict(hostPorts, \"cmd\", -126)\n\t\t\t}\n\t\t\tif contPort.Port() == toStringPort(channel.EvtPort) {\n\t\t\t\ti.exitIPCPortConflict(hostPorts, \"evt\", -127)\n\t\t\t}\n\t\t\ttoPublish[contPort] = hostPorts\n\t\t}\n\t} else {\n\t\tfor _, portInfo := range i.workload.TargetContainer().Ports {\n\t\t\tif portInfo.Protocol != \"\" && portInfo.Protocol != corev1.ProtocolTCP {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tport := toDockerPort(portInfo.ContainerPort)\n\t\t\ttoPublish[port] = []dockerapi.PortBinding{}\n\t\t\tif i.doPublishExposedPorts {\n\t\t\t\ttoPublish[port] = append(toPublish[port], dockerapi.PortBinding{\n\t\t\t\t\tHostPort: string(port), // same port number\n\t\t\t\t\tHostIP:   i.TargetHost(),\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\tvar wg sync.WaitGroup\n\tfor cp, hps := range toPublish {\n\t\twg.Add(1)\n\n\t\tgo func(contPort dockerapi.Port, hostPorts []dockerapi.PortBinding) {\n\t\t\thostIP := \"127.0.0.1\"\n\t\t\thostPort := \"\"\n\t\t\tif len(hostPorts) > 0 {\n\t\t\t\thostIP = hostPorts[0].HostIP\n\t\t\t\thostPort = hostPorts[0].HostPort\n\t\t\t}\n\n\t\t\tcmd, hostPort, err := i.kubectl.PortForward(\n\t\t\t\ti.ctx,\n\t\t\t\ti.pod.Namespace,\n\t\t\t\ti.pod.Name,\n\t\t\t\thostIP,\n\t\t\t\thostPort,\n\t\t\t\tcontPort.Port(),\n\t\t\t)\n\t\t\tif err == nil {\n\t\t\t\ti.portInfo.mux.Lock()\n\n\t\t\t\ti.portInfo.availablePorts[contPort] = dockerapi.PortBinding{HostIP: i.TargetHost(), HostPort: hostPort}\n\t\t\t\ti.portInfo.podPortsInfo = append(\n\t\t\t\t\ti.portInfo.podPortsInfo,\n\t\t\t\t\tfmt.Sprintf(\"%v => %v:%v\", contPort, hostIP, hostPort),\n\t\t\t\t)\n\t\t\t\ti.portInfo.podPortList = append(i.portInfo.podPortList, hostPort)\n\n\t\t\t\ti.portInfo.mux.Unlock()\n\t\t\t}\n\n\t\t\twg.Done()\n\n\t\t\tif err == nil {\n\t\t\t\terr = cmd.Wait()\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\ti.logger.Warnf(\"RunPod: kubectl port-forward container port failed. err=%q\", err)\n\t\t\t}\n\t\t}(cp, hps)\n\t}\n\n\twg.Wait()\n\treturn nil\n}\n\nfunc (i *Inspector) exitIPCPortConflict(port []dockerapi.PortBinding, typ string, code int) {\n\ti.logger.Errorf(\"RunPod: port bindings comms port conflict (%s) = %#v\", typ, port)\n\n\ti.xc.Out.Info(\"sensor.error\",\n\t\tovars{\n\t\t\t\"message\": \"port binding ipc port conflict\",\n\t\t\t\"type\":    typ,\n\t\t})\n\n\ti.xc.Out.State(\"exited\",\n\t\tovars{\n\t\t\t\"exit.code\": code,\n\t\t\t\"component\": \"pod.inspector\",\n\t\t\t\"version\":   v.Current(),\n\t\t})\n\n\ti.xc.Exit(code)\n}\n\nfunc (i *Inspector) injectSensor(localSensorPath string) error {\n\t// Trying to inject the sensor binary atomically using a \"cp then mv\" trick.\n\n\ti.logger.Debugf(\"RunPod: sending sensor to pod\")\n\tout, err := i.kubectl.CpTo(\n\t\ti.ctx,\n\t\ti.pod.Namespace,\n\t\ti.pod.Name,\n\t\tsensorLoaderContainer,\n\t\tlocalSensorPath,\n\t\tsensorBinFileAbs+\".uploading\")\n\tif err != nil {\n\t\ti.logger.Debugf(\"RunPod: kubectl cp sensor.uploading -> pod failed with %q: %s\", err, string(out))\n\t\treturn err\n\t}\n\n\tout, err = i.kubectl.Exec(\n\t\ti.ctx,\n\t\ti.pod.Namespace,\n\t\ti.pod.Name,\n\t\tsensorLoaderContainer,\n\t\t\"mv\", sensorBinFileAbs+\".uploading\", sensorBinFileAbs)\n\tif err != nil {\n\t\ti.logger.Debugf(\"RunPod: kubectl exec sensor.uploading -> sensor failed with %q: %s\", err, string(out))\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (i *Inspector) sensorConnect() error {\n\tsensorListenIP := \"127.0.0.1\"\n\tfor _, p := range []int32{channel.CmdPort, channel.EvtPort} {\n\t\tgo func(port int32) {\n\t\t\tcmd, _, err := i.kubectl.PortForward(\n\t\t\t\ti.ctx,\n\t\t\t\ti.pod.Namespace,\n\t\t\t\ti.pod.Name,\n\t\t\t\tsensorListenIP,\n\t\t\t\ttoStringPort(port),\n\t\t\t\ttoStringPort(port),\n\t\t\t)\n\t\t\tif err == nil {\n\t\t\t\terr = cmd.Wait()\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\t// TODO: Make it fatal!\n\t\t\t\ti.logger.Debugf(\"RunPod: kubectl port-forward sensor port %d failed. err=%q\", port, err)\n\t\t\t}\n\t\t}(p)\n\t}\n\n\tipcClient, err := ipc.NewClient(\n\t\tsensorListenIP,\n\t\tstrconv.Itoa(channel.CmdPort),\n\t\tstrconv.Itoa(channel.EvtPort),\n\t\tsensor.DefaultConnectWait)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ti.sensorIPCClient = ipcClient\n\treturn nil\n}\n\nfunc (i *Inspector) sensorCommandStart() error {\n\tcmd := &command.StartMonitor{\n\t\tRTASourcePT: i.rtaSourcePT,\n\t\tAppName:     i.fatContainerCmd[0],\n\t\tKeepPerms:   i.keepPerms,\n\t}\n\tif len(i.fatContainerCmd) > 1 {\n\t\tcmd.AppArgs = i.fatContainerCmd[1:]\n\t}\n\n\t// if len(i.ExcludePatterns) > 0 {\n\t// \tcmd.Excludes = pathMapKeys(i.ExcludePatterns)\n\t// }\n\n\t// if len(i.PreservePaths) > 0 {\n\t// \tcmd.Preserves = i.PreservePaths\n\t// }\n\n\t// if len(i.IncludePaths) > 0 {\n\t// \tcmd.Includes = i.IncludePaths\n\t// }\n\n\tif len(i.pathPerms) > 0 {\n\t\tcmd.Perms = i.pathPerms\n\t}\n\n\t// if len(i.IncludeBins) > 0 {\n\t// \tcmd.IncludeBins = pathMapKeys(i.IncludeBins)\n\t// }\n\n\t// if len(i.IncludeExes) > 0 {\n\t// \tcmd.IncludeExes = pathMapKeys(i.IncludeExes)\n\t// }\n\n\t// cmd.IncludeShell = i.DoIncludeShell\n\t// cmd.IncludeCertAll = i.DoIncludeCertAll\n\t// cmd.IncludeCertBundles = i.DoIncludeCertBundles\n\t// cmd.IncludeCertDirs = i.DoIncludeCertDirs\n\t// cmd.IncludeCertPKAll = i.DoIncludeCertPKAll\n\t// cmd.IncludeCertPKDirs = i.DoIncludeCertPKDirs\n\t// cmd.IncludeNew = i.DoIncludeNew\n\n\t// if runAsUser != \"\" {\n\t// \tcmd.AppUser = runAsUser\n\n\t// \tif strings.ToLower(runAsUser) != \"root\" {\n\t// \t\tcmd.RunTargetAsUser = i.RunTargetAsUser\n\t// \t}\n\t// }\n\n\t// cmd.IncludeAppNextDir = i.appNodejsInspectOpts.NextOpts.IncludeAppDir\n\t// cmd.IncludeAppNextBuildDir = i.appNodejsInspectOpts.NextOpts.IncludeBuildDir\n\t// cmd.IncludeAppNextDistDir = i.appNodejsInspectOpts.NextOpts.IncludeDistDir\n\t// cmd.IncludeAppNextStaticDir = i.appNodejsInspectOpts.NextOpts.IncludeStaticDir\n\t// cmd.IncludeAppNextNodeModulesDir = i.appNodejsInspectOpts.NextOpts.IncludeNodeModulesDir\n\n\t// cmd.IncludeAppNuxtDir = i.appNodejsInspectOpts.NuxtOpts.IncludeAppDir\n\t// cmd.IncludeAppNuxtBuildDir = i.appNodejsInspectOpts.NuxtOpts.IncludeBuildDir\n\t// cmd.IncludeAppNuxtDistDir = i.appNodejsInspectOpts.NuxtOpts.IncludeDistDir\n\t// cmd.IncludeAppNuxtStaticDir = i.appNodejsInspectOpts.NuxtOpts.IncludeStaticDir\n\t// cmd.IncludeAppNuxtNodeModulesDir = i.appNodejsInspectOpts.NuxtOpts.IncludeNodeModulesDir\n\n\t// cmd.IncludeNodePackages = i.appNodejsInspectOpts.IncludePackages\n\n\tif _, err := i.sensorIPCClient.SendCommand(cmd); err != nil {\n\t\treturn err\n\t}\n\n\ti.xc.Out.Info(\"cmd.startmonitor\", ovars{\"status\": \"sent\"})\n\n\tfor idx := 0; idx < 3; idx++ {\n\t\tevt, err := i.sensorIPCClient.GetEvent()\n\t\tif err != nil {\n\t\t\tif os.IsTimeout(err) || err == channel.ErrWaitTimeout {\n\t\t\t\ti.xc.Out.Info(\"event.startmonitor.done\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"status\": \"receive.timeout\",\n\t\t\t\t\t})\n\n\t\t\t\ti.logger.Debug(\"timeout waiting for the slim container to start...\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\treturn err\n\t\t}\n\n\t\tif evt == nil || evt.Name == \"\" {\n\t\t\ti.logger.Debug(\"empty event waiting for the slim container to start (trying again)...\")\n\t\t\tcontinue\n\t\t}\n\n\t\tif evt.Name == event.StartMonitorDone {\n\t\t\ti.xc.Out.Info(\"event.startmonitor.done\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\": \"received\",\n\t\t\t\t})\n\t\t\treturn nil\n\t\t}\n\n\t\tif evt.Name == event.Error {\n\t\t\treturn fmt.Errorf(\"start monitor error: %v\", evt.Data)\n\t\t}\n\n\t\tif evt.Name != event.StartMonitorDone {\n\t\t\ti.xc.Out.Info(\"event.startmonitor.done\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\": \"received.unexpected\",\n\t\t\t\t\t\"data\":   fmt.Sprintf(\"%+v\", evt),\n\t\t\t\t})\n\n\t\t\t//TODO: dump temp container logs\n\t\t\treturn event.ErrUnexpectedEvent\n\t\t}\n\t}\n\n\treturn errors.New(\"start monitor timeout\")\n}\n\nfunc (i *Inspector) sensorCommandStop() error {\n\tresp, err := i.sensorIPCClient.SendCommand(&command.StopMonitor{})\n\tif err != nil {\n\t\treturn err\n\t}\n\ti.logger.Debugf(\"'stop' monitor response => '%v'\", resp)\n\n\ti.logger.Info(\"waiting for the pod to finish its work...\")\n\n\tevt, err := i.sensorIPCClient.GetEvent()\n\tif err != nil {\n\t\treturn err\n\t}\n\ti.logger.Debugf(\"sensor event => '%v'\", evt)\n\treturn nil\n}\n\nfunc (i *Inspector) sensorDisconnect() {\n\tconst op = \"container.Inspector.shutdownContainerChannels\"\n\tif i.sensorIPCClient != nil {\n\t\tif err := i.sensorIPCClient.Stop(); err != nil {\n\t\t\ti.logger.WithFields(log.Fields{\n\t\t\t\t\"op\":    op,\n\t\t\t\t\"error\": err,\n\t\t\t}).Debug(\"shutting down channels\")\n\t\t}\n\t\ti.sensorIPCClient = nil\n\t}\n}\n\nfunc findPod(\n\tctx context.Context,\n\tclient *kubernetes.Client,\n\tnamespace string,\n\ttargetPodLabelValue string,\n) (corev1.Pod, error) {\n\tvar pod corev1.Pod\n\terr := wait.PollImmediateWithContext(ctx, 1*time.Second, 5*time.Minute, func(ctx context.Context) (bool, error) {\n\t\tpods, err := client.\n\t\t\tStatic().\n\t\t\tCoreV1().\n\t\t\tPods(namespace).\n\t\t\tList(context.TODO(), metav1.ListOptions{\n\t\t\t\tLabelSelector: targetPodLabelName + \"=\" + targetPodLabelValue,\n\t\t\t})\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tif len(pods.Items) == 0 {\n\t\t\treturn false, nil // Keep waiting\n\t\t}\n\t\tif len(pods.Items) == 1 {\n\t\t\tpod = pods.Items[0]\n\t\t\treturn true, nil // Done\n\t\t}\n\n\t\treturn false, errors.New(\"unexpected - more than one target pod found\")\n\t})\n\n\treturn pod, err\n}\n\nfunc waitForContainer(\n\tctx context.Context,\n\tclient *kubernetes.Client,\n\tnamespace string,\n\tpodName string,\n\tcontName string,\n\tisInit bool,\n) error {\n\treturn wait.PollImmediateWithContext(ctx, 1*time.Second, 5*time.Minute, func(ctx context.Context) (bool, error) {\n\t\tpod, err := client.Static().CoreV1().Pods(namespace).Get(ctx, podName, metav1.GetOptions{})\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tstatuses := pod.Status.ContainerStatuses\n\t\tif isInit {\n\t\t\tstatuses = pod.Status.InitContainerStatuses\n\t\t}\n\t\tfor _, contStatus := range statuses {\n\t\t\tif contStatus.Name == contName && contStatus.State.Running != nil {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\n\t\treturn false, nil\n\t})\n}\n\nfunc fatContainerCmd(\n\tworkload *kubernetes.Workload,\n\timageInspector *image.Inspector,\n\toverrides *config.ContainerOverrides,\n) []string {\n\tentrypoint := workload.TargetContainer().Command\n\tif len(entrypoint) == 0 {\n\t\tentrypoint = imageInspector.ImageInfo.Config.Entrypoint\n\t}\n\tcmd := workload.TargetContainer().Args\n\tif len(cmd) == 0 {\n\t\tcmd = imageInspector.ImageInfo.Config.Cmd\n\t}\n\n\tfullCmd := append(entrypoint, cmd...)\n\tif overrides != nil {\n\t\tif len(overrides.Entrypoint) > 0 || overrides.ClearEntrypoint {\n\t\t\tfullCmd = overrides.Entrypoint\n\t\t\tif len(overrides.Cmd) > 0 || overrides.ClearCmd {\n\t\t\t\tfullCmd = append(fullCmd, overrides.Cmd...)\n\t\t\t}\n\t\t\t//note: not using Args from PodTemplateSpec if there's an override for ENTRYPOINT\n\t\t} else {\n\t\t\tfullCmd = entrypoint\n\t\t\tif len(overrides.Cmd) > 0 || overrides.ClearCmd {\n\t\t\t\tfullCmd = append(fullCmd, overrides.Cmd...)\n\t\t\t} else {\n\t\t\t\tfullCmd = append(fullCmd, cmd...)\n\t\t\t}\n\t\t}\n\t}\n\treturn fullCmd\n}\n\nfunc boolPtr(v bool) *bool {\n\treturn &v\n}\n\nfunc toDockerPort(p int32) dockerapi.Port {\n\treturn dockerapi.Port(fmt.Sprintf(\"%d/tcp\", p))\n}\n\nfunc toStringPort(p int32) string {\n\treturn fmt.Sprintf(\"%d\", p)\n}\n"
  },
  {
    "path": "pkg/app/master/inspectors/sensor/sensor.go",
    "content": "package sensor\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype ovars = app.OutVars\n\nconst (\n\tLocalBinFile       = \"slim-sensor\"\n\tDefaultConnectWait = 60\n)\n\nfunc EnsureLocalBinary(xc *app.ExecutionContext, logger *log.Entry, statePath string, printState bool) string {\n\tsensorPath := filepath.Join(fsutil.ExeDir(), LocalBinFile)\n\n\tif runtime.GOOS == \"darwin\" {\n\t\tstateSensorPath := filepath.Join(statePath, LocalBinFile)\n\t\tif fsutil.Exists(stateSensorPath) {\n\t\t\tsensorPath = stateSensorPath\n\t\t}\n\t}\n\n\tif !fsutil.Exists(sensorPath) {\n\t\tif printState {\n\t\t\txc.Out.Info(\"sensor.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\":  \"sensor binary not found\",\n\t\t\t\t\t\"location\": sensorPath,\n\t\t\t\t})\n\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\":    -999,\n\t\t\t\t\t\"component\":    \"container.inspector\",\n\t\t\t\t\t\"version\":      v.Current(),\n\t\t\t\t\t\"location.exe\": fsutil.ExeDir(),\n\t\t\t\t})\n\t\t}\n\n\t\txc.Exit(-999)\n\t}\n\n\tif finfo, err := os.Lstat(sensorPath); err == nil {\n\t\tlogger.Debugf(\"sensor.EnsureLocalBinary: sensor (%s) perms => %#o\", sensorPath, finfo.Mode().Perm())\n\t\tif finfo.Mode().Perm()&fsutil.FilePermUserExe == 0 {\n\t\t\tif printState {\n\t\t\t\txc.Out.Info(\"sensor.perms\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"message\":  \"sensor missing execute permission\",\n\t\t\t\t\t\t\"location\": sensorPath,\n\t\t\t\t\t\t\"mode\":     finfo.Mode().String(),\n\t\t\t\t\t\t\"perm\":     finfo.Mode().Perm().String(),\n\t\t\t\t\t})\n\t\t\t}\n\n\t\t\tlogger.Debugf(\"sensor.EnsureLocalBinary: sensor (%s) missing execute permission\", sensorPath)\n\t\t\tupdatedMode := finfo.Mode() | fsutil.FilePermUserExe | fsutil.FilePermGroupExe | fsutil.FilePermOtherExe\n\t\t\tif err = os.Chmod(sensorPath, updatedMode); err != nil {\n\t\t\t\tlogger.Errorf(\"sensor.EnsureLocalBinary: error updating sensor (%s) perms (%#o -> %#o) => %v\",\n\t\t\t\t\tsensorPath, finfo.Mode().Perm(), updatedMode.Perm(), err)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tlogger.Errorf(\"sensor.EnsureLocalBinary: error getting sensor (%s) info => %#v\", sensorPath, err)\n\t}\n\n\treturn sensorPath\n}\n"
  },
  {
    "path": "pkg/app/master/kubernetes/client.go",
    "content": "package kubernetes\n\nimport (\n\t\"context\"\n\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\tmetav1 \"k8s.io/apimachinery/pkg/apis/meta/v1\"\n\t\"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/cli-runtime/pkg/genericclioptions\"\n\t\"k8s.io/cli-runtime/pkg/resource\"\n\t\"k8s.io/client-go/dynamic\"\n\t\"k8s.io/client-go/kubernetes\"\n\t\"k8s.io/client-go/tools/clientcmd\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\ntype Client struct {\n\tdynamic dynamic.Interface\n\tstatic  kubernetes.Interface\n}\n\nfunc NewClient(kubeOpts config.KubernetesOptions) (*Client, error) {\n\tconfig, err := clientcmd.BuildConfigFromFlags(\"\", kubeOpts.Kubeconfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient := Client{}\n\n\tclient.dynamic, err = dynamic.NewForConfig(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient.static, err = kubernetes.NewForConfig(config)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &client, nil\n}\n\nfunc (c *Client) Dynamic() dynamic.Interface {\n\treturn c.dynamic\n}\n\nfunc (c *Client) Static() kubernetes.Interface {\n\treturn c.static\n}\n\nfunc (c *Client) CreateOrUpdate(ctx context.Context, info *resource.Info) (err error) {\n\tdto := unstructured.Unstructured{}\n\tdto.Object, err = runtime.DefaultUnstructuredConverter.ToUnstructured(info.Object)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// Disable the version check since we don't expect concurrent changes.\n\tdto.SetResourceVersion(\"\")\n\n\tvar obj *unstructured.Unstructured\n\tobj, err = c.dynamic.\n\t\tResource(info.Mapping.Resource).\n\t\tNamespace(info.Namespace).\n\t\tCreate(ctx, &dto, metav1.CreateOptions{})\n\tif apierrors.IsAlreadyExists(err) {\n\t\tobj, err = c.dynamic.\n\t\t\tResource(info.Mapping.Resource).\n\t\t\tNamespace(info.Namespace).\n\t\t\tUpdate(ctx, &dto, metav1.UpdateOptions{})\n\t}\n\n\tif err != nil {\n\t\treturn\n\t}\n\n\terr = runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, info.Object)\n\tif err == nil {\n\t\tinfo.ResourceVersion = obj.GetResourceVersion()\n\t}\n\n\treturn\n}\n\nfunc (c *Client) Delete(ctx context.Context, info *resource.Info) error {\n\treturn c.dynamic.\n\t\tResource(info.Mapping.Resource).\n\t\tNamespace(info.Namespace).\n\t\tDelete(\n\t\t\tctx,\n\t\t\tinfo.Name,\n\t\t\tmetav1.DeleteOptions{})\n}\n\n// ResourceBuilderFunc is a helper function to avoid\n// passing KuberneteOptions through unrelated code.\ntype ResourceBuilderFunc func() *resource.Builder\n\nfunc NewResourceBuilder(kubeOpts config.KubernetesOptions) *resource.Builder {\n\tconfigFlags := genericclioptions.NewConfigFlags(true)\n\tconfigFlags.KubeConfig = &kubeOpts.Kubeconfig\n\treturn resource.NewBuilder(configFlags)\n}\n\nfunc NewResourceBuilderFunc(kubeOpts config.KubernetesOptions) ResourceBuilderFunc {\n\treturn func() *resource.Builder {\n\t\treturn NewResourceBuilder(kubeOpts)\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/kubernetes/kubectl.go",
    "content": "package kubernetes\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\ntype Kubectl interface {\n\tCpFrom(ctx context.Context, namespace, pod, container, srcPath, dstPath string) ([]byte, error)\n\tCpTo(ctx context.Context, namespace, pod, container, srcPath, dstPath string) ([]byte, error)\n\tExec(ctx context.Context, namespace, pod, container, cmd string, args ...string) ([]byte, error)\n\tPortForward(ctx context.Context, namespace, pod, address, hostPort, podPort string) (*exec.Cmd, string, error)\n}\n\ntype kubectl struct {\n\tkubeconfig string\n}\n\nvar _ Kubectl = &kubectl{}\n\nfunc NewKubectl(opts config.KubernetesOptions) Kubectl {\n\treturn &kubectl{\n\t\tkubeconfig: opts.Kubeconfig,\n\t}\n}\n\nfunc (k *kubectl) CpFrom(\n\tctx context.Context,\n\tnamespace string,\n\tpod string,\n\tcontainer string,\n\tsrcPath string,\n\tdstPath string,\n) ([]byte, error) {\n\tcmd1 := []string{\n\t\t\"kubectl\",\n\t\t\"exec\", pod,\n\t\t\"--kubeconfig\", k.kubeconfig,\n\t\t\"--namespace\", namespace,\n\t\t\"--container\", container,\n\t\t\"--\", \"tar\", \"cf\", \"-\", \"-C\", filepath.Dir(srcPath), filepath.Base(srcPath),\n\t}\n\n\tcmd2 := []string{\"tar\", \"xf\", \"-\", \"-C\", filepath.Dir(dstPath), filepath.Base(dstPath)}\n\n\tcmd := exec.CommandContext(\n\t\tctx,\n\t\t\"bash\", \"-c\", strings.Join(cmd1, \" \")+\"|\"+strings.Join(cmd2, \" \"),\n\t)\n\treturn cmd.CombinedOutput()\n\n\t// r, w, err := os.Pipe()\n\t// if err != nil {\n\t// \treturn nil, err\n\t// }\n\n\t// c1.Stdout = w\n\t// c2.Stdin = io.TeeReader(r, os.Stdout)\n\n\t// var out bytes.Buffer\n\t// c2.Stdout = &out\n\t// c2.Stderr = &out\n\n\t// if err := c1.Start(); err != nil {\n\t// \treturn nil, err\n\t// }\n\n\t// if err := c2.Start(); err != nil {\n\t// \treturn nil, err\n\t// }\n\n\t// if err := c1.Wait(); err != nil {\n\t// \treturn nil, err\n\t// }\n\n\t// if err := w.Close(); err != nil {\n\t// \treturn nil, err\n\t// }\n\n\t// if err := c2.Wait(); err != nil {\n\t// \treturn nil, err\n\t// }\n\n\t// return out.Bytes(), nil\n}\n\nfunc (k *kubectl) CpTo(\n\tctx context.Context,\n\tnamespace string,\n\tpod string,\n\tcontainer string,\n\tsrcPath string,\n\tdstPath string,\n) ([]byte, error) {\n\treturn exec.CommandContext(\n\t\tctx,\n\t\t\"kubectl\",\n\t\t\"cp\", srcPath, pod+\":\"+dstPath,\n\t\t\"--kubeconfig\", k.kubeconfig,\n\t\t\"--namespace\", namespace,\n\t\t\"--container\", container,\n\t).CombinedOutput()\n}\n\nfunc (k *kubectl) Exec(\n\tctx context.Context,\n\tnamespace string,\n\tpod string,\n\tcontainer string,\n\tcmd string,\n\targs ...string,\n) ([]byte, error) {\n\targs = append([]string{\n\t\t\"kubectl\",\n\t\t\"exec\", pod,\n\t\t\"--kubeconfig\", k.kubeconfig,\n\t\t\"--namespace\", namespace,\n\t\t\"--container\", container,\n\t\t\"--\", cmd,\n\t}, args...)\n\treturn exec.Command(args[0], args[1:]...).CombinedOutput()\n}\n\nfunc (k *kubectl) PortForward(\n\tctx context.Context,\n\tnamespace string,\n\tpod string,\n\taddress string,\n\thostPort string,\n\tpodPort string,\n) (*exec.Cmd, string, error) {\n\tif podPort == \"\" {\n\t\treturn nil, \"\", errors.New(\"podPort cannot be empty\")\n\t}\n\n\tmapping := \":\" + podPort\n\tif hostPort != \"\" {\n\t\tmapping = hostPort + mapping\n\t}\n\n\tcmd := exec.CommandContext(\n\t\tctx,\n\t\t\"kubectl\",\n\t\t\"--kubeconfig\", k.kubeconfig,\n\t\t\"--namespace\", namespace,\n\t\t\"--address\", address,\n\t\t\"port-forward\", \"pod/\"+pod, mapping,\n\t)\n\n\tout, err := cmd.StdoutPipe()\n\tif err != nil {\n\t\treturn cmd, \"\", err\n\t}\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn cmd, \"\", err\n\t}\n\n\tvar actualHostPort int\n\tpattern := fmt.Sprintf(\"Forwarding from %s:%s -> %s\", address, \"%d\", podPort)\n\tscanner := bufio.NewScanner(out)\n\tfor scanner.Scan() {\n\t\tn, err := fmt.Sscanf(scanner.Text(), pattern, &actualHostPort)\n\t\tif err == nil && n == 1 {\n\t\t\treturn cmd, fmt.Sprintf(\"%d\", actualHostPort), nil\n\t\t}\n\t}\n\n\treturn cmd, \"\", errors.New(\"cannot detect host port\")\n}\n"
  },
  {
    "path": "pkg/app/master/kubernetes/manifests.go",
    "content": "package kubernetes\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\tapierrors \"k8s.io/apimachinery/pkg/api/errors\"\n\t\"k8s.io/cli-runtime/pkg/resource\"\n\t\"k8s.io/client-go/kubernetes/scheme\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\n// TODO: Start supporting CRDs - currently the hardcoded client-go scheme usage\n//       will likely make the manifests containing CRDs fail.\n\ntype Manifests struct {\n\tinfos []*resource.Info\n\n\tclient            *Client\n\tresourceBuilderFn ResourceBuilderFunc\n}\n\nfunc ManifestsFromFiles(\n\topts config.KubernetesOptions,\n\tclient *Client,\n\tresourceBuilderFn ResourceBuilderFunc,\n) (*Manifests, error) {\n\tnamespace := opts.Target.Namespace\n\tif namespace == \"\" {\n\t\tnamespace = namespaceDefault\n\t}\n\n\tinfos, err := resourceBuilderFn().\n\t\tWithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).\n\t\tNamespaceParam(namespace).\n\t\tDefaultNamespace().\n\t\tFilenameParam(\n\t\t\tfalse,\n\t\t\t&resource.FilenameOptions{\n\t\t\t\tFilenames: opts.Manifests,\n\t\t\t\tRecursive: true,\n\t\t\t}).\n\t\tDo().\n\t\tInfos()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &Manifests{\n\t\tinfos:             infos,\n\t\tclient:            client,\n\t\tresourceBuilderFn: resourceBuilderFn,\n\t}, nil\n}\n\nfunc (ms *Manifests) Find(target config.KubernetesTarget) (*resource.Info, error) {\n\tmapping, err := ms.resourceBuilderFn().\n\t\tLocal().\n\t\tWithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).\n\t\tNamespaceParam(\"not-really-used\").\n\t\tResourceTypeOrNameArgs(true, target.Workload).\n\t\tSingleResourceType().\n\t\tDo().\n\t\tResourceMapping()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tname, err := target.WorkloadName()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmatches := []*resource.Info{}\n\tfor _, info := range ms.infos {\n\t\tif info.Mapping.GroupVersionKind.GroupKind() != mapping.GroupVersionKind.GroupKind() {\n\t\t\tcontinue\n\t\t}\n\t\tif info.Name != name {\n\t\t\tcontinue\n\t\t}\n\t\tif target.Namespace != \"\" && target.Namespace != info.Namespace {\n\t\t\tcontinue\n\t\t}\n\n\t\tmatches = append(matches, info)\n\t}\n\n\tif len(matches) == 0 {\n\t\treturn nil, nil\n\t}\n\tif len(matches) > 1 {\n\t\treturn nil, fmt.Errorf(\"found more than 1 workload '%s/%s' match in the supplied manifests\", target.Namespace, name)\n\t}\n\n\treturn matches[0], nil\n}\n\nfunc (ms *Manifests) Apply(ctx context.Context, predicate func(info *resource.Info) bool) error {\n\tfor _, info := range ms.infos {\n\t\tif !predicate(info) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := ms.client.CreateOrUpdate(ctx, info); err != nil {\n\t\t\t// TODO: consider partial applying\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (ms *Manifests) Delete(ctx context.Context) error {\n\tfor _, info := range ms.infos {\n\t\tif err := ms.client.Delete(ctx, info); err != nil && !apierrors.IsNotFound(err) {\n\t\t\t// TODO: consider partial deletion\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/kubernetes/workload.go",
    "content": "package kubernetes\n\nimport (\n\t\"errors\"\n\n\tappsv1 \"k8s.io/api/apps/v1\"\n\tbatchv1 \"k8s.io/api/batch/v1\"\n\tcorev1 \"k8s.io/api/core/v1\"\n\t\"k8s.io/apimachinery/pkg/runtime\"\n\t\"k8s.io/cli-runtime/pkg/resource\"\n\t\"k8s.io/client-go/kubernetes/scheme\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\nconst (\n\tnamespaceDefault           = \"default\"\n\tannotationDefaultContainer = \"kubectl.kubernetes.io/default-container\"\n)\n\ntype Workload struct {\n\tinfo                *resource.Info\n\torig                runtime.Object\n\ttargetContainerName string\n}\n\nfunc newWorkload(info *resource.Info, targetContainerName string) *Workload {\n\treturn &Workload{\n\t\tinfo:                info,\n\t\torig:                info.Object.DeepCopyObject(),\n\t\ttargetContainerName: targetContainerName,\n\t}\n}\n\nfunc (w *Workload) Namespace() string {\n\treturn w.info.Namespace\n}\n\nfunc (w *Workload) Name() string {\n\treturn w.info.Name\n}\n\nfunc (w *Workload) Info() *resource.Info {\n\treturn w.info\n}\n\nfunc (w *Workload) Template() *corev1.PodTemplateSpec {\n\tswitch obj := w.info.Object.(type) {\n\tcase *appsv1.DaemonSet:\n\t\treturn &obj.Spec.Template\n\tcase *appsv1.Deployment:\n\t\treturn &obj.Spec.Template\n\tcase *appsv1.ReplicaSet:\n\t\treturn &obj.Spec.Template\n\tcase *appsv1.StatefulSet:\n\t\treturn &obj.Spec.Template\n\tcase *batchv1.Job:\n\t\treturn &obj.Spec.Template\n\tcase *batchv1.CronJob:\n\t\treturn &obj.Spec.JobTemplate.Spec.Template\n\tdefault:\n\t\t// Shouldn't really happen...\n\t\treturn nil\n\t}\n}\n\nfunc (w *Workload) Container(name string) *corev1.Container {\n\tfor _, c := range w.Template().Spec.Containers {\n\t\tif c.Name == name {\n\t\t\treturn &c\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (w *Workload) DefaultContainer() *corev1.Container {\n\tas := w.Template().Annotations\n\tif as != nil && as[annotationDefaultContainer] != \"\" {\n\t\treturn w.Container(as[annotationDefaultContainer])\n\t}\n\n\tif len(w.Template().Spec.Containers) == 1 {\n\t\treturn &w.Template().Spec.Containers[0]\n\t}\n\n\t// No default\n\treturn nil\n}\n\nfunc (w *Workload) TargetContainer() *corev1.Container {\n\tif w.targetContainerName == \"\" {\n\t\treturn w.DefaultContainer()\n\t}\n\treturn w.Container(w.targetContainerName)\n}\n\nfunc (w *Workload) AddEmptyDirVolume(name string) {\n\tw.Template().Spec.Volumes = append(w.Template().Spec.Volumes,\n\t\tcorev1.Volume{\n\t\t\tName: name,\n\t\t\tVolumeSource: corev1.VolumeSource{\n\t\t\t\tEmptyDir: &corev1.EmptyDirVolumeSource{},\n\t\t\t},\n\t\t})\n}\n\nfunc (w *Workload) AddInitContainer(cont corev1.Container) {\n\tw.Template().Spec.InitContainers = append(w.Template().Spec.InitContainers, cont)\n}\n\nfunc (w *Workload) SetReplicasIfApplicable(n int32) bool {\n\tswitch obj := w.info.Object.(type) {\n\tcase *appsv1.Deployment:\n\t\tobj.Spec.Replicas = &n\n\tcase *appsv1.ReplicaSet:\n\t\tobj.Spec.Replicas = &n\n\tcase *appsv1.StatefulSet:\n\t\tobj.Spec.Replicas = &n\n\tdefault:\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (w *Workload) ResetChanges() {\n\tw.info.Object = w.orig.DeepCopyObject()\n\tw.info.ResourceVersion = \"\"\n}\n\n// WorkloadFinder searches for the workload object in:\n//   - supplied manifest files (if any)\n//   - default cluster\ntype WorkloadFinder struct {\n\tmanifests         *Manifests\n\tresourceBuilderFn ResourceBuilderFunc\n}\n\nfunc NewWorkloadFinder(manifests *Manifests, resourceBuilderFn ResourceBuilderFunc) *WorkloadFinder {\n\treturn &WorkloadFinder{\n\t\tmanifests:         manifests,\n\t\tresourceBuilderFn: resourceBuilderFn,\n\t}\n}\n\nfunc (f *WorkloadFinder) Find(target config.KubernetesTarget) (*Workload, error) {\n\tinfo, err := func() (*resource.Info, error) {\n\t\tif f.manifests != nil {\n\t\t\treturn f.manifests.Find(target)\n\t\t}\n\t\treturn f.findInCluster(target)\n\t}()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif info == nil {\n\t\treturn nil, nil\n\t}\n\n\treturn newWorkload(info, target.Container), nil\n}\n\nfunc (f *WorkloadFinder) findInCluster(target config.KubernetesTarget) (*resource.Info, error) {\n\tnamespace := target.Namespace\n\tif namespace == \"\" {\n\t\tnamespace = namespaceDefault\n\t}\n\n\tinfos, err := f.resourceBuilderFn().\n\t\tWithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).\n\t\tNamespaceParam(namespace).\n\t\tSingleResourceType().\n\t\tResourceTypeOrNameArgs(true, target.Workload).\n\t\tDo().\n\t\tInfos()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(infos) == 0 {\n\t\treturn nil, errors.New(\"couldn't find workload in cluster\")\n\t}\n\tif len(infos) > 1 {\n\t\treturn nil, errors.New(\"couldn't unambiguously identify workload in cluster\")\n\t}\n\n\treturn infos[0], nil\n}\n"
  },
  {
    "path": "pkg/app/master/probe/http/crawler.go",
    "content": "package http\n\nimport (\n\t\"net/http\"\n\t\"net/http/cookiejar\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/gocolly/colly/v2\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n)\n\nconst (\n\tdefaultCrawlMaxDepth         = 3\n\tdefaultCrawlMaxPageCount     = 1000\n\tdefaultCrawlConcurrency      = 10\n\tdefaultMaxConcurrentCrawlers = 1\n)\n\nfunc (p *CustomProbe) crawl(proto, domain, addr string) {\n\n\tvar httpClient *http.Client\n\tif strings.HasPrefix(proto, config.ProtoHTTP2) {\n\t\tvar err error\n\t\tif httpClient, err = getHTTPClient(proto); err != nil {\n\t\t\tp.xc.Out.Error(\"HTTP probe - construct client error - %v\", err.Error())\n\t\t\treturn\n\t\t}\n\n\t\thttpClient.Timeout = 10 * time.Second //matches the timeout used by Colly\n\t\tjar, _ := cookiejar.New(nil)\n\t\thttpClient.Jar = jar\n\t}\n\n\tif p.opts.CrawlConcurrencyMax > 0 &&\n\t\tp.concurrentCrawlers != nil {\n\t\tp.concurrentCrawlers <- struct{}{}\n\t}\n\n\tp.workers.Add(1)\n\tgo func() {\n\t\tdefer func() {\n\t\t\tif p.opts.CrawlConcurrencyMax > 0 &&\n\t\t\t\tp.concurrentCrawlers != nil {\n\t\t\t\t<-p.concurrentCrawlers\n\t\t\t}\n\n\t\t\tp.workers.Done()\n\t\t}()\n\n\t\tvar pageCount int\n\n\t\tc := colly.NewCollector()\n\t\tc.UserAgent = \"ds.crawler\"\n\t\tc.IgnoreRobotsTxt = true\n\t\tc.Async = true\n\t\tc.AllowedDomains = []string{domain}\n\t\tc.AllowURLRevisit = false\n\t\tif httpClient != nil {\n\t\t\tc.SetClient(httpClient)\n\t\t}\n\n\t\tif p.opts.CrawlMaxDepth > 0 {\n\t\t\tc.MaxDepth = p.opts.CrawlMaxDepth\n\t\t}\n\n\t\tif p.opts.CrawlConcurrency > 0 {\n\t\t\tc.Limit(&colly.LimitRule{\n\t\t\t\tDomainGlob:  \"*\",\n\t\t\t\tParallelism: p.opts.CrawlConcurrency,\n\t\t\t})\n\t\t}\n\n\t\tc.OnHTML(\"a[href]\", func(e *colly.HTMLElement) {\n\t\t\tif p.opts.CrawlMaxPageCount > 0 &&\n\t\t\t\tpageCount > p.opts.CrawlMaxPageCount {\n\t\t\t\tlog.Debugf(\"http.CustomProbe.crawl.OnHTML(a[href]) - reached max page count, ignoring link (%v)\", p.opts.CrawlMaxPageCount)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\te.Request.Visit(e.Attr(\"href\"))\n\t\t})\n\n\t\tc.OnHTML(\"link[href]\", func(e *colly.HTMLElement) {\n\t\t\tif p.opts.CrawlMaxPageCount > 0 &&\n\t\t\t\tpageCount > p.opts.CrawlMaxPageCount {\n\t\t\t\tlog.Debugf(\"http.CustomProbe.crawl.OnHTML(link[href]) - reached max page count, ignoring link (%v)\", p.opts.CrawlMaxPageCount)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tswitch e.Attr(\"rel\") {\n\t\t\tcase \"dns-prefetch\", \"preconnect\", \"alternate\":\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\te.Request.Visit(e.Attr(\"href\"))\n\t\t})\n\n\t\tc.OnHTML(\"script[src], source[src], img[src]\", func(e *colly.HTMLElement) {\n\t\t\tif p.opts.CrawlMaxPageCount > 0 &&\n\t\t\t\tpageCount > p.opts.CrawlMaxPageCount {\n\t\t\t\tlog.Debugf(\"http.CustomProbe.crawl.OnHTML(script/source/img) - reached max page count, ignoring link (%v)\", p.opts.CrawlMaxPageCount)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\te.Request.Visit(e.Attr(\"src\"))\n\t\t})\n\n\t\tc.OnHTML(\"source[srcset]\", func(e *colly.HTMLElement) {\n\t\t\tif p.opts.CrawlMaxPageCount > 0 &&\n\t\t\t\tpageCount > p.opts.CrawlMaxPageCount {\n\t\t\t\tlog.Debugf(\"http.CustomProbe.crawl.OnHTML(source[srcset]) - reached max page count, ignoring link (%v)\", p.opts.CrawlMaxPageCount)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\te.Request.Visit(e.Attr(\"srcset\"))\n\t\t})\n\n\t\tc.OnHTML(\"[data-src]\", func(e *colly.HTMLElement) {\n\t\t\tif p.opts.CrawlMaxPageCount > 0 &&\n\t\t\t\tpageCount > p.opts.CrawlMaxPageCount {\n\t\t\t\tlog.Debugf(\"http.CustomProbe.crawl.OnHTML([data-src]) - reached max page count, ignoring link (%v)\", p.opts.CrawlMaxPageCount)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\te.Request.Visit(e.Attr(\"data-src\"))\n\t\t})\n\n\t\tc.OnRequest(func(r *colly.Request) {\n\t\t\tp.xc.Out.Info(\"http.probe.crawler\",\n\t\t\t\tovars{\n\t\t\t\t\t\"page\": pageCount,\n\t\t\t\t\t\"url\":  r.URL,\n\t\t\t\t})\n\n\t\t\tif p.opts.CrawlMaxPageCount > 0 &&\n\t\t\t\tpageCount > p.opts.CrawlMaxPageCount {\n\t\t\t\tp.xc.Out.Info(\"http.probe.crawler.stop\",\n\t\t\t\t\tovars{\n\t\t\t\t\t\t\"reason\": \"reached max visits\",\n\t\t\t\t\t})\n\n\t\t\t\tlog.Debugf(\"http.CustomProbe.crawl.OnRequest - reached max page count (%v)\", p.opts.CrawlMaxPageCount)\n\t\t\t\tr.Abort()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tpageCount++\n\t\t})\n\n\t\tc.OnError(func(_ *colly.Response, err error) {\n\t\t\tlog.Tracef(\"http.CustomProbe.crawl - error=%v\", err)\n\t\t})\n\n\t\tc.Visit(addr)\n\t\tc.Wait()\n\t\tp.xc.Out.Info(\"probe.crawler.done\",\n\t\t\tovars{\n\t\t\t\t\"addr\": addr,\n\t\t\t})\n\t}()\n}\n"
  },
  {
    "path": "pkg/app/master/probe/http/custom_probe.go",
    "content": "package http\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/container\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/pod\"\n)\n\nconst (\n\tprobeRetryCount = 5\n\n\tdefaultHTTPPortStr    = \"80\"\n\tdefaultHTTPSPortStr   = \"443\"\n\tdefaultFastCGIPortStr = \"9000\"\n)\n\ntype ovars = app.OutVars\n\n// CustomProbe is a custom HTTP probe\ntype CustomProbe struct {\n\txc *app.ExecutionContext\n\n\topts config.HTTPProbeOptions\n\n\tports      []string\n\ttargetHost string\n\n\tAPISpecProbes []apiSpecInfo\n\n\tprintState bool\n\n\tCallCount uint64\n\tErrCount  uint64\n\tOkCount   uint64\n\n\tdoneChan           chan struct{}\n\tworkers            sync.WaitGroup\n\tconcurrentCrawlers chan struct{}\n}\n\n// NewEndpointProbe creates a new custom HTTP probe for an endpoint\nfunc NewEndpointProbe(\n\txc *app.ExecutionContext,\n\ttargetEndpoint string,\n\tports []uint,\n\topts config.HTTPProbeOptions,\n\tprintState bool,\n) (*CustomProbe, error) {\n\tprobe := newCustomProbe(xc, targetEndpoint, opts, printState)\n\tif len(ports) == 0 {\n\t\tports = []uint{80}\n\t}\n\n\tfor _, pnum := range ports {\n\t\tprobe.ports = append(probe.ports, fmt.Sprintf(\"%d\", pnum))\n\t}\n\n\tif len(probe.opts.APISpecFiles) > 0 {\n\t\tprobe.loadAPISpecFiles()\n\t}\n\n\treturn probe, nil\n}\n\n// NewContainerProbe creates a new custom HTTP probe\nfunc NewContainerProbe(\n\txc *app.ExecutionContext,\n\tinspector *container.Inspector,\n\topts config.HTTPProbeOptions,\n\tprintState bool,\n) (*CustomProbe, error) {\n\tprobe := newCustomProbe(xc, inspector.TargetHost, opts, printState)\n\n\tavailableHostPorts := map[string]string{}\n\tfor nsPortKey, nsPortData := range inspector.AvailablePorts {\n\t\tlog.Debugf(\"HTTP probe - target's network port key='%s' data='%#v'\", nsPortKey, nsPortData)\n\n\t\tif nsPortKey.Proto() != \"tcp\" {\n\t\t\tlog.Debugf(\"HTTP probe - skipping non-tcp port => %v\", nsPortKey)\n\t\t\tcontinue\n\t\t}\n\n\t\tif nsPortData.HostPort == \"\" {\n\t\t\tlog.Debugf(\"HTTP probe - skipping network setting without port data => %v\", nsPortKey)\n\t\t\tcontinue\n\t\t}\n\n\t\tavailableHostPorts[nsPortData.HostPort] = nsPortKey.Port()\n\t}\n\n\tlog.Debugf(\"HTTP probe - available host ports => %+v\", availableHostPorts)\n\n\tif len(probe.opts.Ports) > 0 {\n\t\tfor _, pnum := range probe.opts.Ports {\n\t\t\tpspec := dockerapi.Port(fmt.Sprintf(\"%v/tcp\", pnum))\n\t\t\tif _, ok := inspector.AvailablePorts[pspec]; ok {\n\t\t\t\tif inspector.SensorIPCMode == container.SensorIPCModeDirect {\n\t\t\t\t\tprobe.ports = append(probe.ports, fmt.Sprintf(\"%d\", pnum))\n\t\t\t\t} else {\n\t\t\t\t\tprobe.ports = append(probe.ports, inspector.AvailablePorts[pspec].HostPort)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"HTTP probe - ignoring port => %v\", pspec)\n\t\t\t}\n\t\t}\n\t\tlog.Debugf(\"HTTP probe - filtered ports => %+v\", probe.ports)\n\t} else {\n\t\t//order the port list based on the order of the 'EXPOSE' instructions\n\t\tif len(inspector.ImageInspector.DockerfileInfo.ExposedPorts) > 0 {\n\t\t\tfor epi := len(inspector.ImageInspector.DockerfileInfo.ExposedPorts) - 1; epi >= 0; epi-- {\n\t\t\t\tportInfo := inspector.ImageInspector.DockerfileInfo.ExposedPorts[epi]\n\t\t\t\tif !strings.Contains(portInfo, \"/\") {\n\t\t\t\t\tportInfo = fmt.Sprintf(\"%v/tcp\", portInfo)\n\t\t\t\t}\n\n\t\t\t\tpspec := dockerapi.Port(portInfo)\n\n\t\t\t\tif _, ok := inspector.AvailablePorts[pspec]; ok {\n\t\t\t\t\thostPort := inspector.AvailablePorts[pspec].HostPort\n\t\t\t\t\tif inspector.SensorIPCMode == container.SensorIPCModeDirect {\n\t\t\t\t\t\tif containerPort := availableHostPorts[hostPort]; containerPort != \"\" {\n\t\t\t\t\t\t\tprobe.ports = append(probe.ports, containerPort)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - could not find container port from host port => %v\", hostPort)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tprobe.ports = append(probe.ports, hostPort)\n\t\t\t\t\t}\n\n\t\t\t\t\tif _, ok := availableHostPorts[hostPort]; ok {\n\t\t\t\t\t\tlog.Debugf(\"HTTP probe - delete exposed port from the available host ports => %v (%v)\", hostPort, portInfo)\n\t\t\t\t\t\tdelete(availableHostPorts, hostPort)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"HTTP probe - Unknown exposed port - %v\", portInfo)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor hostPort, containerPort := range availableHostPorts {\n\t\t\tif inspector.SensorIPCMode == container.SensorIPCModeDirect {\n\t\t\t\tprobe.ports = append(probe.ports, containerPort)\n\t\t\t} else {\n\t\t\t\tprobe.ports = append(probe.ports, hostPort)\n\t\t\t}\n\t\t}\n\n\t\tlog.Debugf(\"HTTP probe - probe.Ports => %+v\", probe.ports)\n\t}\n\n\tif len(probe.opts.APISpecFiles) > 0 {\n\t\tprobe.loadAPISpecFiles()\n\t}\n\n\treturn probe, nil\n}\n\nfunc NewPodProbe(\n\txc *app.ExecutionContext,\n\tinspector *pod.Inspector,\n\topts config.HTTPProbeOptions,\n\tprintState bool,\n) (*CustomProbe, error) {\n\tprobe := newCustomProbe(xc, inspector.TargetHost(), opts, printState)\n\n\tavailableHostPorts := map[string]string{}\n\tfor nsPortKey, nsPortData := range inspector.AvailablePorts() {\n\t\tlog.Debugf(\"HTTP probe - target's network port key='%s' data='%#v'\", nsPortKey, nsPortData)\n\t\tavailableHostPorts[nsPortData.HostPort] = nsPortKey.Port()\n\t}\n\n\tlog.Debugf(\"HTTP probe - available host ports => %+v\", availableHostPorts)\n\n\tif len(probe.opts.Ports) > 0 {\n\t\tfor _, pnum := range probe.opts.Ports {\n\t\t\tpspec := dockerapi.Port(fmt.Sprintf(\"%v/tcp\", pnum))\n\t\t\tif port, ok := inspector.AvailablePorts()[pspec]; ok {\n\t\t\t\tprobe.ports = append(probe.ports, port.HostPort)\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"HTTP probe - ignoring port => %v\", pspec)\n\t\t\t}\n\t\t}\n\n\t\tlog.Debugf(\"HTTP probe - filtered ports => %+v\", probe.ports)\n\t} else {\n\t\tfor hostPort := range availableHostPorts {\n\t\t\tprobe.ports = append(probe.ports, hostPort)\n\t\t}\n\n\t\tlog.Debugf(\"HTTP probe - probe.Ports => %+v\", probe.ports)\n\t}\n\n\tif len(probe.opts.APISpecFiles) > 0 {\n\t\tprobe.loadAPISpecFiles()\n\t}\n\n\treturn probe, nil\n}\n\nfunc newCustomProbe(\n\txc *app.ExecutionContext,\n\ttargetHost string,\n\topts config.HTTPProbeOptions,\n\tprintState bool,\n) *CustomProbe {\n\t//note: the default probe should already be there if the user asked for it\n\n\t//-1 means disabled\n\tif opts.CrawlMaxDepth == 0 {\n\t\topts.CrawlMaxDepth = defaultCrawlMaxDepth\n\t}\n\n\t//-1 means disabled\n\tif opts.CrawlMaxPageCount == 0 {\n\t\topts.CrawlMaxPageCount = defaultCrawlMaxPageCount\n\t}\n\n\t//-1 means disabled\n\tif opts.CrawlConcurrency == 0 {\n\t\topts.CrawlConcurrency = defaultCrawlConcurrency\n\t}\n\n\t//-1 means disabled\n\tif opts.CrawlConcurrencyMax == 0 {\n\t\topts.CrawlConcurrencyMax = defaultMaxConcurrentCrawlers\n\t}\n\n\tprobe := &CustomProbe{\n\t\txc:         xc,\n\t\topts:       opts,\n\t\tprintState: printState,\n\t\ttargetHost: targetHost,\n\t\tdoneChan:   make(chan struct{}),\n\t}\n\n\tif opts.CrawlConcurrencyMax > 0 {\n\t\tprobe.concurrentCrawlers = make(chan struct{}, opts.CrawlConcurrencyMax)\n\t}\n\n\treturn probe\n}\n\nfunc (p *CustomProbe) Ports() []string {\n\treturn p.ports\n}\n\n// Start starts the HTTP probe instance execution\nfunc (p *CustomProbe) Start() {\n\tif p.printState {\n\t\tp.xc.Out.State(\"http.probe.starting\",\n\t\t\tovars{\n\t\t\t\t\"message\": \"WAIT FOR HTTP PROBE TO FINISH\",\n\t\t\t})\n\t}\n\n\tgo func() {\n\t\t//TODO: need to do a better job figuring out if the target app is ready to accept connections\n\t\ttime.Sleep(9 * time.Second) //base start wait time\n\t\tif p.opts.StartWait > 0 {\n\t\t\tif p.printState {\n\t\t\t\tp.xc.Out.State(\"http.probe.start.wait\", ovars{\"time\": p.opts.StartWait})\n\t\t\t}\n\n\t\t\t//additional wait time\n\t\t\ttime.Sleep(time.Duration(p.opts.StartWait) * time.Second)\n\n\t\t\tif p.printState {\n\t\t\t\tp.xc.Out.State(\"http.probe.start.wait.done\")\n\t\t\t}\n\t\t}\n\n\t\tif p.printState {\n\t\t\tp.xc.Out.State(\"http.probe.running\")\n\t\t}\n\n\t\tlog.Info(\"HTTP probe started...\")\n\n\t\tfindIdx := func(ports []string, target string) int {\n\t\t\tfor idx, val := range ports {\n\t\t\t\tif val == target {\n\t\t\t\t\treturn idx\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1\n\t\t}\n\n\t\thttpIdx := findIdx(p.ports, defaultHTTPPortStr)\n\t\thttpsIdx := findIdx(p.ports, defaultHTTPSPortStr)\n\t\tif httpIdx != -1 && httpsIdx != -1 && httpsIdx < httpIdx {\n\t\t\t//want to probe http first\n\t\t\tlog.Debugf(\"http.probe - swapping http and https ports (http=%v <-> https=%v)\",\n\t\t\t\thttpIdx, httpsIdx)\n\n\t\t\tp.ports[httpIdx], p.ports[httpsIdx] = p.ports[httpsIdx], p.ports[httpIdx]\n\t\t}\n\n\t\tif p.printState {\n\t\t\tp.xc.Out.Info(\"http.probe.ports\",\n\t\t\t\tovars{\n\t\t\t\t\t\"count\":   len(p.ports),\n\t\t\t\t\t\"targets\": strings.Join(p.ports, \",\"),\n\t\t\t\t})\n\n\t\t\tvar cmdListPreview []string\n\t\t\tvar cmdListTail string\n\t\t\tfor idx, c := range p.opts.Cmds {\n\t\t\t\tcmdListPreview = append(cmdListPreview, fmt.Sprintf(\"%s %s\", c.Method, c.Resource))\n\t\t\t\tif idx == 2 {\n\t\t\t\t\tcmdListTail = \",...\"\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcmdInfo := fmt.Sprintf(\"%s%s\", strings.Join(cmdListPreview, \",\"), cmdListTail)\n\t\t\tp.xc.Out.Info(\"http.probe.commands\",\n\t\t\t\tovars{\n\t\t\t\t\t\"count\":    len(p.opts.Cmds),\n\t\t\t\t\t\"commands\": cmdInfo,\n\t\t\t\t})\n\t\t}\n\n\t\tfor _, port := range p.ports {\n\t\t\t//If it's ok stop after the first successful probe pass\n\t\t\tif p.OkCount > 0 && !p.opts.Full {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tfor _, cmd := range p.opts.Cmds {\n\t\t\t\tvar reqBody io.Reader\n\t\t\t\tvar rbSeeker io.Seeker\n\n\t\t\t\tif cmd.BodyFile != \"\" {\n\t\t\t\t\t_, err := os.Stat(cmd.BodyFile)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Errorf(\"http.probe - cmd.BodyFile (%s) check error: %v\", cmd.BodyFile, err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbodyFile, err := os.Open(cmd.BodyFile)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tlog.Errorf(\"http.probe - cmd.BodyFile (%s) read error: %v\", cmd.BodyFile, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treqBody = bodyFile\n\t\t\t\t\t\t\trbSeeker = bodyFile\n\t\t\t\t\t\t\t//the file will be closed only when the function exits\n\t\t\t\t\t\t\tdefer bodyFile.Close()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstrBody := strings.NewReader(cmd.Body)\n\t\t\t\t\treqBody = strBody\n\t\t\t\t\trbSeeker = strBody\n\t\t\t\t}\n\n\t\t\t\t// TODO: need a smarter and more dynamic way to determine the actual protocol type\n\n\t\t\t\t// Set up FastCGI defaults if the default CGI port is used without a FastCGI config.\n\t\t\t\tif port == defaultFastCGIPortStr && cmd.FastCGI == nil {\n\t\t\t\t\tlog.Debugf(\"HTTP probe - FastCGI default port (%s) used, setting up HTTP probe FastCGI wrapper defaults\", port)\n\n\t\t\t\t\t// Typicall the entrypoint into a PHP app.\n\t\t\t\t\tif cmd.Resource == \"/\" {\n\t\t\t\t\t\tcmd.Resource = \"/index.php\"\n\t\t\t\t\t}\n\n\t\t\t\t\t// SplitPath is typically on the first .php path element.\n\t\t\t\t\tvar splitPath []string\n\t\t\t\t\tif phpIdx := strings.Index(cmd.Resource, \".php\"); phpIdx != -1 {\n\t\t\t\t\t\tsplitPath = []string{cmd.Resource[:phpIdx+4]}\n\t\t\t\t\t}\n\n\t\t\t\t\tcmd.FastCGI = &config.FastCGIProbeWrapperConfig{\n\t\t\t\t\t\t// /var/www is a typical root for PHP indices.\n\t\t\t\t\t\tRoot:      \"/var/www\",\n\t\t\t\t\t\tSplitPath: splitPath,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar protocols []string\n\t\t\t\tif cmd.Protocol == \"\" {\n\t\t\t\t\tswitch port {\n\t\t\t\t\tcase defaultHTTPPortStr:\n\t\t\t\t\t\tprotocols = []string{config.ProtoHTTP}\n\t\t\t\t\tcase defaultHTTPSPortStr:\n\t\t\t\t\t\tprotocols = []string{config.ProtoHTTPS}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tprotocols = []string{config.ProtoHTTP, config.ProtoHTTPS}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tprotocols = []string{cmd.Protocol}\n\t\t\t\t}\n\n\t\t\t\tfor _, proto := range protocols {\n\t\t\t\t\tmaxRetryCount := probeRetryCount\n\t\t\t\t\tif p.opts.RetryCount > 0 {\n\t\t\t\t\t\tmaxRetryCount = p.opts.RetryCount\n\t\t\t\t\t}\n\n\t\t\t\t\tnotReadyErrorWait := time.Duration(16)\n\t\t\t\t\twebErrorWait := time.Duration(8)\n\t\t\t\t\totherErrorWait := time.Duration(4)\n\t\t\t\t\tif p.opts.RetryWait > 0 {\n\t\t\t\t\t\twebErrorWait = time.Duration(p.opts.RetryWait)\n\t\t\t\t\t\tnotReadyErrorWait = time.Duration(p.opts.RetryWait * 2)\n\t\t\t\t\t\totherErrorWait = time.Duration(p.opts.RetryWait / 2)\n\t\t\t\t\t}\n\n\t\t\t\t\tif IsValidWSProto(proto) {\n\t\t\t\t\t\twc, err := NewWebsocketClient(proto, p.targetHost, port)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - new websocket error - %v\", err)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twc.ReadCh = make(chan WebsocketMessage, 10)\n\t\t\t\t\t\tfor i := 0; i < maxRetryCount; i++ {\n\t\t\t\t\t\t\terr = wc.Connect()\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - ws target not ready yet (retry again later) [err=%v]...\", err)\n\t\t\t\t\t\t\t\ttime.Sleep(notReadyErrorWait * time.Second)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\twc.CheckConnection()\n\t\t\t\t\t\t\t//TODO: prep data to write from the HTTPProbeCmd fields\n\t\t\t\t\t\t\terr = wc.WriteString(\"ws.data\")\n\t\t\t\t\t\t\tp.CallCount++\n\n\t\t\t\t\t\t\tif p.printState {\n\t\t\t\t\t\t\t\tstatusCode := \"error\"\n\t\t\t\t\t\t\t\tcallErrorStr := \"none\"\n\t\t\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\t\t\tstatusCode = \"ok\"\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcallErrorStr = err.Error()\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tp.xc.Out.Info(\"http.probe.call.ws\",\n\t\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\t\"status\":    statusCode,\n\t\t\t\t\t\t\t\t\t\t\"stats.rc\":  wc.ReadCount,\n\t\t\t\t\t\t\t\t\t\t\"stats.pic\": wc.PingCount,\n\t\t\t\t\t\t\t\t\t\t\"stats.poc\": wc.PongCount,\n\t\t\t\t\t\t\t\t\t\t\"target\":    wc.Addr,\n\t\t\t\t\t\t\t\t\t\t\"attempt\":   i + 1,\n\t\t\t\t\t\t\t\t\t\t\"error\":     callErrorStr,\n\t\t\t\t\t\t\t\t\t\t\"time\":      time.Now().UTC().Format(time.RFC3339),\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tp.ErrCount++\n\t\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - websocket write error - %v\", err)\n\t\t\t\t\t\t\t\ttime.Sleep(notReadyErrorWait * time.Second)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tp.OkCount++\n\n\t\t\t\t\t\t\t\t//try to read something from the socket\n\t\t\t\t\t\t\t\tselect {\n\t\t\t\t\t\t\t\tcase wsMsg := <-wc.ReadCh:\n\t\t\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - websocket read - [type=%v data=%s]\", wsMsg.Type, string(wsMsg.Data))\n\t\t\t\t\t\t\t\tcase <-time.After(time.Second * 5):\n\t\t\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - websocket read time out\")\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\twc.Disconnect()\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tvar client *http.Client\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase cmd.FastCGI != nil:\n\t\t\t\t\t\tlog.Debug(\"HTTP probe - FastCGI embedded proxy configured\")\n\t\t\t\t\t\tclient = getFastCGIClient(cmd.FastCGI)\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tvar err error\n\t\t\t\t\t\tif client, err = getHTTPClient(proto); err != nil {\n\t\t\t\t\t\t\tp.xc.Out.Error(\"HTTP probe - construct client error - %v\", err.Error())\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tbaseAddr := getHTTPAddr(proto, p.targetHost, port)\n\t\t\t\t\t// TODO: cmd.Resource may need to be a part of cmd.FastCGI instead.\n\t\t\t\t\taddr := fmt.Sprintf(\"%s%s\", baseAddr, cmd.Resource)\n\n\t\t\t\t\treq, err := newHTTPRequestFromCmd(cmd, addr, reqBody)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tp.xc.Out.Error(\"HTTP probe - construct request error - %v\", err.Error())\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tfor i := 0; i < maxRetryCount; i++ {\n\t\t\t\t\t\tres, err := client.Do(req.Clone(context.Background()))\n\t\t\t\t\t\tp.CallCount++\n\t\t\t\t\t\trbSeeker.Seek(0, 0)\n\n\t\t\t\t\t\tif res != nil {\n\t\t\t\t\t\t\tif res.Body != nil {\n\t\t\t\t\t\t\t\tio.Copy(io.Discard, res.Body)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tres.Body.Close()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstatusCode := \"error\"\n\t\t\t\t\t\tcallErrorStr := \"none\"\n\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\tstatusCode = fmt.Sprintf(\"%v\", res.StatusCode)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcallErrorStr = err.Error()\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif p.printState {\n\t\t\t\t\t\t\tp.xc.Out.Info(\"http.probe.call\",\n\t\t\t\t\t\t\t\tovars{\n\t\t\t\t\t\t\t\t\t\"status\":  statusCode,\n\t\t\t\t\t\t\t\t\t\"method\":  cmd.Method,\n\t\t\t\t\t\t\t\t\t\"target\":  addr,\n\t\t\t\t\t\t\t\t\t\"attempt\": i + 1,\n\t\t\t\t\t\t\t\t\t\"error\":   callErrorStr,\n\t\t\t\t\t\t\t\t\t\"time\":    time.Now().UTC().Format(time.RFC3339),\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\tp.OkCount++\n\n\t\t\t\t\t\t\tif p.OkCount == 1 {\n\t\t\t\t\t\t\t\tif len(p.opts.APISpecs) != 0 && len(p.opts.APISpecFiles) != 0 && cmd.FastCGI != nil {\n\t\t\t\t\t\t\t\t\tp.xc.Out.Info(\"HTTP probe - API spec probing not implemented for fastcgi\")\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tp.probeAPISpecs(proto, p.targetHost, port)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif cmd.Crawl {\n\t\t\t\t\t\t\t\tif cmd.FastCGI != nil {\n\t\t\t\t\t\t\t\t\tp.xc.Out.Info(\"HTTP probe - crawling not implemented for fastcgi\")\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tp.crawl(proto, p.targetHost, addr)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tp.ErrCount++\n\n\t\t\t\t\t\t\turlErr := &url.Error{}\n\t\t\t\t\t\t\tif errors.As(err, &urlErr) {\n\t\t\t\t\t\t\t\tif errors.Is(urlErr.Err, io.EOF) {\n\t\t\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - target not ready yet (retry again later)...\")\n\t\t\t\t\t\t\t\t\ttime.Sleep(notReadyErrorWait * time.Second)\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - web error... retry again later...\")\n\t\t\t\t\t\t\t\t\ttime.Sleep(webErrorWait * time.Second)\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlog.Debugf(\"HTTP probe - other error... retry again later...\")\n\t\t\t\t\t\t\t\ttime.Sleep(otherErrorWait * time.Second)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlog.Info(\"HTTP probe done.\")\n\n\t\tif p.printState {\n\t\t\tp.xc.Out.Info(\"http.probe.summary\",\n\t\t\t\tovars{\n\t\t\t\t\t\"total\":      p.CallCount,\n\t\t\t\t\t\"failures\":   p.ErrCount,\n\t\t\t\t\t\"successful\": p.OkCount,\n\t\t\t\t})\n\n\t\t\toutVars := ovars{}\n\t\t\t//warning := \"\"\n\t\t\tswitch {\n\t\t\tcase p.CallCount == 0:\n\t\t\t\toutVars[\"warning\"] = \"no.calls\"\n\t\t\t\t//warning = \"warning=no.calls\"\n\t\t\tcase p.OkCount == 0:\n\t\t\t\t//warning = \"warning=no.successful.calls\"\n\t\t\t\toutVars[\"warning\"] = \"no.successful.calls\"\n\t\t\t}\n\n\t\t\tp.xc.Out.State(\"http.probe.done\", outVars)\n\t\t}\n\n\t\tp.workers.Wait()\n\t\tclose(p.doneChan)\n\t}()\n}\n\nfunc (p *CustomProbe) probeAPISpecs(proto, targetHost, port string) {\n\t//fetch the API spec when we know the target is reachable\n\tp.loadAPISpecs(proto, targetHost, port)\n\n\t//ideally api spec probes should work without http probe commands\n\t//for now trigger the api spec probes after the first successful http probe command\n\t//and once the api specs are loaded\n\tfor _, specInfo := range p.APISpecProbes {\n\t\tvar apiPrefix string\n\t\tif specInfo.prefixOverride != \"\" {\n\t\t\tapiPrefix = specInfo.prefixOverride\n\t\t} else {\n\t\t\tvar err error\n\t\t\tapiPrefix, err = apiSpecPrefix(specInfo.spec)\n\t\t\tif err != nil {\n\t\t\t\tp.xc.Out.Error(\"http.probe.api-spec.error.prefix\", err.Error())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tp.probeAPISpecEndpoints(proto, targetHost, port, apiPrefix, specInfo.spec)\n\t}\n}\n\n// DoneChan returns the 'done' channel for the HTTP probe instance\nfunc (p *CustomProbe) DoneChan() <-chan struct{} {\n\treturn p.doneChan\n}\n\nfunc newHTTPRequestFromCmd(cmd config.HTTPProbeCmd, addr string, reqBody io.Reader) (*http.Request, error) {\n\treq, err := http.NewRequestWithContext(context.Background(), cmd.Method, addr, reqBody)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, hline := range cmd.Headers {\n\t\thparts := strings.SplitN(hline, \":\", 2)\n\t\tif len(hparts) != 2 {\n\t\t\tlog.Debugf(\"ignoring malformed header (%v)\", hline)\n\t\t\tcontinue\n\t\t}\n\n\t\thname := strings.TrimSpace(hparts[0])\n\t\thvalue := strings.TrimSpace(hparts[1])\n\t\treq.Header.Add(hname, hvalue)\n\t}\n\n\tif (cmd.Username != \"\") || (cmd.Password != \"\") {\n\t\treq.SetBasicAuth(cmd.Username, cmd.Password)\n\t}\n\n\treturn req, nil\n}\n"
  },
  {
    "path": "pkg/app/master/probe/http/httpclient.go",
    "content": "package http\n\nimport (\n\t\"crypto/tls\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"golang.org/x/net/http2\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/probe/http/internal\"\n)\n\nfunc getHTTP1Client() *http.Client {\n\tclient := &http.Client{\n\t\tTimeout: time.Second * 30,\n\t\tTransport: &http.Transport{\n\t\t\tMaxIdleConns:    10,\n\t\t\tIdleConnTimeout: 30 * time.Second,\n\t\t\tTLSClientConfig: &tls.Config{\n\t\t\t\tInsecureSkipVerify: true,\n\t\t\t},\n\t\t},\n\t}\n\n\treturn client\n}\n\nfunc getHTTP2Client(h2c bool) *http.Client {\n\ttransport := &http2.Transport{\n\t\tTLSClientConfig: &tls.Config{\n\t\t\tInsecureSkipVerify: true,\n\t\t},\n\t}\n\n\tclient := &http.Client{\n\t\tTimeout:   time.Second * 30,\n\t\tTransport: transport,\n\t}\n\n\tif h2c {\n\t\ttransport.AllowHTTP = true\n\t\ttransport.DialTLS = func(network, addr string, cfg *tls.Config) (net.Conn, error) {\n\t\t\treturn net.Dial(network, addr)\n\t\t}\n\t}\n\n\treturn client\n}\n\nfunc getHTTPClient(proto string) (*http.Client, error) {\n\tswitch proto {\n\tcase config.ProtoHTTP2:\n\t\treturn getHTTP2Client(false), nil\n\tcase config.ProtoHTTP2C:\n\t\treturn getHTTP2Client(true), nil\n\tdefault:\n\t\treturn getHTTP1Client(), nil\n\t}\n\n\treturn nil, fmt.Errorf(\"unsupported HTTP-family protocol %s\", proto)\n}\n\nfunc getHTTPAddr(proto, targetHost, port string) string {\n\tscheme := getHTTPScheme(proto)\n\treturn fmt.Sprintf(\"%s://%s:%s\", scheme, targetHost, port)\n}\n\nfunc getHTTPScheme(proto string) string {\n\tvar scheme string\n\tswitch proto {\n\tcase config.ProtoHTTP:\n\t\tscheme = proto\n\tcase config.ProtoHTTPS:\n\t\tscheme = proto\n\tcase config.ProtoHTTP2:\n\t\tscheme = config.ProtoHTTPS\n\tcase config.ProtoHTTP2C:\n\t\tscheme = config.ProtoHTTP\n\t}\n\n\treturn scheme\n}\n\nfunc getFastCGIClient(cfg *config.FastCGIProbeWrapperConfig) *http.Client {\n\n\tgenericTimeout := time.Second * 30\n\tvar dialTimeout, readTimeout, writeTimeout time.Duration\n\tif dialTimeout = cfg.DialTimeout; dialTimeout == 0 {\n\t\tdialTimeout = genericTimeout\n\t}\n\tif readTimeout = cfg.ReadTimeout; readTimeout == 0 {\n\t\treadTimeout = genericTimeout\n\t}\n\tif writeTimeout = cfg.WriteTimeout; writeTimeout == 0 {\n\t\twriteTimeout = genericTimeout\n\t}\n\n\treturn &http.Client{\n\t\tTimeout: genericTimeout,\n\t\tTransport: &internal.FastCGITransport{\n\t\t\tRoot:         cfg.Root,\n\t\t\tSplitPath:    cfg.SplitPath,\n\t\t\tEnvVars:      cfg.EnvVars,\n\t\t\tDialTimeout:  dialTimeout,\n\t\t\tReadTimeout:  readTimeout,\n\t\t\tWriteTimeout: writeTimeout,\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/probe/http/internal/client.go",
    "content": "// This file is a modified version of\n// https://github.com/caddyserver/caddy/blob/44e5e9e/modules/caddyhttp/reverseproxy/fastcgi/client.go\n// Modifications made permit targeting containerized PHP scripts\n// and decouple Caddy dependencies.\n\n// Copyright 2015 Matthew Holt and The Caddy Authors\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//     http://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\n// Forked Jan. 2015 from http://bitbucket.org/PinIdea/fcgi_client\n// (which is forked from https://code.google.com/p/go-fastcgi-client/).\n// This fork contains several fixes and improvements by Matt Holt and\n// other contributors to the Caddy project.\n\n// Copyright 2012 Junqing Tan <ivan@mysqlab.net> and The Go Authors\n// Use of this source code is governed by a BSD-style\n// Part of source code is from Go fcgi package\n\npackage internal\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n\t\"mime/multipart\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/textproto\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// FCGIListenSockFileno describes listen socket file number.\nconst FCGIListenSockFileno uint8 = 0\n\n// FCGIHeaderLen describes header length.\nconst FCGIHeaderLen uint8 = 8\n\n// Version1 describes the version.\nconst Version1 uint8 = 1\n\n// FCGINullRequestID describes the null request ID.\nconst FCGINullRequestID uint8 = 0\n\n// FCGIKeepConn describes keep connection mode.\nconst FCGIKeepConn uint8 = 1\n\nconst (\n\t// BeginRequest is the begin request flag.\n\tBeginRequest uint8 = iota + 1\n\t// AbortRequest is the abort request flag.\n\tAbortRequest\n\t// EndRequest is the end request flag.\n\tEndRequest\n\t// Params is the parameters flag.\n\tParams\n\t// Stdin is the standard input flag.\n\tStdin\n\t// Stdout is the standard output flag.\n\tStdout\n\t// Stderr is the standard error flag.\n\tStderr\n\t// Data is the data flag.\n\tData\n\t// GetValues is the get values flag.\n\tGetValues\n\t// GetValuesResult is the get values result flag.\n\tGetValuesResult\n\t// UnknownType is the unknown type flag.\n\tUnknownType\n\t// MaxType is the maximum type flag.\n\tMaxType = UnknownType\n)\n\nconst (\n\t// Responder is the responder flag.\n\tResponder uint8 = iota + 1\n\t// Authorizer is the authorizer flag.\n\tAuthorizer\n\t// Filter is the filter flag.\n\tFilter\n)\n\nconst (\n\t// RequestComplete is the completed request flag.\n\tRequestComplete uint8 = iota\n\t// CantMultiplexConns is the multiplexed connections flag.\n\tCantMultiplexConns\n\t// Overloaded is the overloaded flag.\n\tOverloaded\n\t// UnknownRole is the unknown role flag.\n\tUnknownRole\n)\n\nconst (\n\t// MaxConns is the maximum connections flag.\n\tMaxConns string = \"MAX_CONNS\"\n\t// MaxRequests is the maximum requests flag.\n\tMaxRequests string = \"MAX_REQS\"\n\t// MultiplexConns is the multiplex connections flag.\n\tMultiplexConns string = \"MPXS_CONNS\"\n)\n\nconst (\n\tmaxWrite = 65500 // 65530 may work, but for compatibility\n\tmaxPad   = 255\n)\n\ntype header struct {\n\tVersion       uint8\n\tType          uint8\n\tID            uint16\n\tContentLength uint16\n\tPaddingLength uint8\n\tReserved      uint8\n}\n\n// for padding so we don't have to allocate all the time\n// not synchronized because we don't care what the contents are\nvar pad [maxPad]byte\n\nfunc (h *header) init(recType uint8, reqID uint16, contentLength int) {\n\th.Version = 1\n\th.Type = recType\n\th.ID = reqID\n\th.ContentLength = uint16(contentLength)\n\th.PaddingLength = uint8(-contentLength & 7)\n}\n\ntype record struct {\n\th    header\n\trbuf []byte\n}\n\nfunc (rec *record) read(r io.Reader) (buf []byte, err error) {\n\tif err = binary.Read(r, binary.BigEndian, &rec.h); err != nil {\n\t\treturn\n\t}\n\tif rec.h.Version != 1 {\n\t\terr = errors.New(\"fcgi: invalid header version\")\n\t\treturn\n\t}\n\tif rec.h.Type == EndRequest {\n\t\terr = io.EOF\n\t\treturn\n\t}\n\tn := int(rec.h.ContentLength) + int(rec.h.PaddingLength)\n\tif len(rec.rbuf) < n {\n\t\trec.rbuf = make([]byte, n)\n\t}\n\tif _, err = io.ReadFull(r, rec.rbuf[:n]); err != nil {\n\t\treturn\n\t}\n\tbuf = rec.rbuf[:int(rec.h.ContentLength)]\n\n\treturn\n}\n\n// FCGIClient implements a FastCGI client, which is a standard for\n// interfacing external applications with Web servers.\ntype FCGIClient struct {\n\tmutex     sync.Mutex\n\trwc       io.ReadWriteCloser\n\th         header\n\tbuf       bytes.Buffer\n\tstderr    bytes.Buffer\n\tkeepAlive bool\n\treqID     uint16\n}\n\n// DialWithDialerContext connects to the fcgi responder at the specified network address, using custom net.Dialer\n// and a context.\n// See func net.Dial for a description of the network and address parameters.\nfunc DialWithDialerContext(ctx context.Context, network, address string, dialer net.Dialer) (fcgi *FCGIClient, err error) {\n\tvar conn net.Conn\n\tconn, err = dialer.DialContext(ctx, network, address)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tfcgi = &FCGIClient{\n\t\trwc:       conn,\n\t\tkeepAlive: false,\n\t\treqID:     1,\n\t}\n\n\treturn\n}\n\n// Close closes fcgi connection\nfunc (c *FCGIClient) Close() {\n\tc.rwc.Close()\n}\n\nfunc (c *FCGIClient) writeRecord(recType uint8, content []byte) (err error) {\n\tc.mutex.Lock()\n\tdefer c.mutex.Unlock()\n\tc.buf.Reset()\n\tc.h.init(recType, c.reqID, len(content))\n\tif err := binary.Write(&c.buf, binary.BigEndian, c.h); err != nil {\n\t\treturn err\n\t}\n\tif _, err := c.buf.Write(content); err != nil {\n\t\treturn err\n\t}\n\tif _, err := c.buf.Write(pad[:c.h.PaddingLength]); err != nil {\n\t\treturn err\n\t}\n\t_, err = c.rwc.Write(c.buf.Bytes())\n\treturn err\n}\n\nfunc (c *FCGIClient) writeBeginRequest(role uint16, flags uint8) error {\n\tb := [8]byte{byte(role >> 8), byte(role), flags}\n\treturn c.writeRecord(BeginRequest, b[:])\n}\n\nfunc (c *FCGIClient) writePairs(recType uint8, pairs map[string]string) error {\n\tw := newWriter(c, recType)\n\tb := make([]byte, 8)\n\tnn := 0\n\tfor k, v := range pairs {\n\t\tm := 8 + len(k) + len(v)\n\t\tif m > maxWrite {\n\t\t\t// param data size exceed 65535 bytes\"\n\t\t\tvl := maxWrite - 8 - len(k)\n\t\t\tv = v[:vl]\n\t\t}\n\t\tn := encodeSize(b, uint32(len(k)))\n\t\tn += encodeSize(b[n:], uint32(len(v)))\n\t\tm = n + len(k) + len(v)\n\t\tif (nn + m) > maxWrite {\n\t\t\tw.Flush()\n\t\t\tnn = 0\n\t\t}\n\t\tnn += m\n\t\tif _, err := w.Write(b[:n]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := w.WriteString(k); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := w.WriteString(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tw.Close()\n\treturn nil\n}\n\nfunc encodeSize(b []byte, size uint32) int {\n\tif size > 127 {\n\t\tsize |= 1 << 31\n\t\tbinary.BigEndian.PutUint32(b, size)\n\t\treturn 4\n\t}\n\tb[0] = byte(size)\n\treturn 1\n}\n\n// bufWriter encapsulates bufio.Writer but also closes the underlying stream when\n// Closed.\ntype bufWriter struct {\n\tcloser io.Closer\n\t*bufio.Writer\n}\n\nfunc (w *bufWriter) Close() error {\n\tif err := w.Writer.Flush(); err != nil {\n\t\tw.closer.Close()\n\t\treturn err\n\t}\n\treturn w.closer.Close()\n}\n\nfunc newWriter(c *FCGIClient, recType uint8) *bufWriter {\n\ts := &streamWriter{c: c, recType: recType}\n\tw := bufio.NewWriterSize(s, maxWrite)\n\treturn &bufWriter{s, w}\n}\n\n// streamWriter abstracts out the separation of a stream into discrete records.\n// It only writes maxWrite bytes at a time.\ntype streamWriter struct {\n\tc       *FCGIClient\n\trecType uint8\n}\n\nfunc (w *streamWriter) Write(p []byte) (int, error) {\n\tnn := 0\n\tfor len(p) > 0 {\n\t\tn := len(p)\n\t\tif n > maxWrite {\n\t\t\tn = maxWrite\n\t\t}\n\t\tif err := w.c.writeRecord(w.recType, p[:n]); err != nil {\n\t\t\treturn nn, err\n\t\t}\n\t\tnn += n\n\t\tp = p[n:]\n\t}\n\treturn nn, nil\n}\n\nfunc (w *streamWriter) Close() error {\n\t// send empty record to close the stream\n\treturn w.c.writeRecord(w.recType, nil)\n}\n\ntype streamReader struct {\n\tc   *FCGIClient\n\tbuf []byte\n}\n\nfunc (w *streamReader) Read(p []byte) (n int, err error) {\n\n\tif len(p) > 0 {\n\t\tif len(w.buf) == 0 {\n\n\t\t\t// filter outputs for error log\n\t\t\tfor {\n\t\t\t\trec := &record{}\n\t\t\t\tvar buf []byte\n\t\t\t\tbuf, err = rec.read(w.c.rwc)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// standard error output\n\t\t\t\tif rec.h.Type == Stderr {\n\t\t\t\t\tw.c.stderr.Write(buf)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tw.buf = buf\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tn = len(p)\n\t\tif n > len(w.buf) {\n\t\t\tn = len(w.buf)\n\t\t}\n\t\tcopy(p, w.buf[:n])\n\t\tw.buf = w.buf[n:]\n\t}\n\n\treturn\n}\n\n// Do made the request and returns a io.Reader that translates the data read\n// from fcgi responder out of fcgi packet before returning it.\nfunc (c *FCGIClient) Do(p map[string]string, req io.Reader) (r io.Reader, err error) {\n\terr = c.writeBeginRequest(uint16(Responder), 0)\n\tif err != nil {\n\t\treturn\n\t}\n\n\terr = c.writePairs(Params, p)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tbody := newWriter(c, Stdin)\n\tif req != nil {\n\t\t_, _ = io.Copy(body, req)\n\t}\n\tbody.Close()\n\n\tr = &streamReader{c: c}\n\treturn\n}\n\n// clientCloser is a io.ReadCloser. It wraps a io.Reader with a Closer\n// that closes FCGIClient connection.\ntype clientCloser struct {\n\t*FCGIClient\n\tio.Reader\n}\n\nfunc (f clientCloser) Close() error { return f.rwc.Close() }\n\n// Request returns a HTTP Response with Header and Body\n// from fcgi responder\nfunc (c *FCGIClient) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) {\n\tr, err := c.Do(p, req)\n\tif err != nil {\n\t\treturn\n\t}\n\n\trb := bufio.NewReader(r)\n\ttp := textproto.NewReader(rb)\n\tresp = new(http.Response)\n\n\t// Parse the response headers.\n\tmimeHeader, err := tp.ReadMIMEHeader()\n\tif err != nil && err != io.EOF {\n\t\treturn\n\t}\n\tresp.Header = http.Header(mimeHeader)\n\n\tif resp.Header.Get(\"Status\") != \"\" {\n\t\tstatusParts := strings.SplitN(resp.Header.Get(\"Status\"), \" \", 2)\n\t\tresp.StatusCode, err = strconv.Atoi(statusParts[0])\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif len(statusParts) > 1 {\n\t\t\tresp.Status = statusParts[1]\n\t\t}\n\n\t} else {\n\t\tresp.StatusCode = http.StatusOK\n\t}\n\n\t// TODO: fixTransferEncoding ?\n\tresp.TransferEncoding = resp.Header[\"Transfer-Encoding\"]\n\tresp.ContentLength, _ = strconv.ParseInt(resp.Header.Get(\"Content-Length\"), 10, 64)\n\n\tif chunked(resp.TransferEncoding) {\n\t\tresp.Body = clientCloser{c, httputil.NewChunkedReader(rb)}\n\t} else {\n\t\tresp.Body = clientCloser{c, io.NopCloser(rb)}\n\t}\n\treturn\n}\n\n// Get issues a GET request to the fcgi responder.\nfunc (c *FCGIClient) Get(p map[string]string, body io.Reader, l int64) (resp *http.Response, err error) {\n\n\tp[\"REQUEST_METHOD\"] = \"GET\"\n\tp[\"CONTENT_LENGTH\"] = strconv.FormatInt(l, 10)\n\n\treturn c.Request(p, body)\n}\n\n// Head issues a HEAD request to the fcgi responder.\nfunc (c *FCGIClient) Head(p map[string]string) (resp *http.Response, err error) {\n\n\tp[\"REQUEST_METHOD\"] = \"HEAD\"\n\tp[\"CONTENT_LENGTH\"] = \"0\"\n\n\treturn c.Request(p, nil)\n}\n\n// Options issues an OPTIONS request to the fcgi responder.\nfunc (c *FCGIClient) Options(p map[string]string) (resp *http.Response, err error) {\n\n\tp[\"REQUEST_METHOD\"] = \"OPTIONS\"\n\tp[\"CONTENT_LENGTH\"] = \"0\"\n\n\treturn c.Request(p, nil)\n}\n\n// Post issues a POST request to the fcgi responder. with request body\n// in the format that bodyType specified\nfunc (c *FCGIClient) Post(p map[string]string, method string, bodyType string, body io.Reader, l int64) (resp *http.Response, err error) {\n\tif p == nil {\n\t\tp = map[string]string{}\n\t}\n\n\tp[\"REQUEST_METHOD\"] = strings.ToUpper(method)\n\n\tif len(p[\"REQUEST_METHOD\"]) == 0 || p[\"REQUEST_METHOD\"] == \"GET\" {\n\t\tp[\"REQUEST_METHOD\"] = \"POST\"\n\t}\n\n\tp[\"CONTENT_LENGTH\"] = strconv.FormatInt(l, 10)\n\tif len(bodyType) > 0 {\n\t\tp[\"CONTENT_TYPE\"] = bodyType\n\t} else {\n\t\tp[\"CONTENT_TYPE\"] = \"application/x-www-form-urlencoded\"\n\t}\n\n\treturn c.Request(p, body)\n}\n\n// PostForm issues a POST to the fcgi responder, with form\n// as a string key to a list values (url.Values)\nfunc (c *FCGIClient) PostForm(p map[string]string, data url.Values) (resp *http.Response, err error) {\n\tbody := bytes.NewReader([]byte(data.Encode()))\n\treturn c.Post(p, \"POST\", \"application/x-www-form-urlencoded\", body, int64(body.Len()))\n}\n\n// PostFile issues a POST to the fcgi responder in multipart(RFC 2046) standard,\n// with form as a string key to a list values (url.Values),\n// and/or with file as a string key to a list file path.\nfunc (c *FCGIClient) PostFile(p map[string]string, data url.Values, file map[string]string) (resp *http.Response, err error) {\n\tbuf := &bytes.Buffer{}\n\twriter := multipart.NewWriter(buf)\n\tbodyType := writer.FormDataContentType()\n\n\tfor key, val := range data {\n\t\tfor _, v0 := range val {\n\t\t\terr = writer.WriteField(key, v0)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tfor key, val := range file {\n\t\tfd, e := os.Open(val)\n\t\tif e != nil {\n\t\t\treturn nil, e\n\t\t}\n\t\tdefer fd.Close()\n\n\t\tpart, e := writer.CreateFormFile(key, filepath.Base(val))\n\t\tif e != nil {\n\t\t\treturn nil, e\n\t\t}\n\t\t_, err = io.Copy(part, fd)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\terr = writer.Close()\n\tif err != nil {\n\t\treturn\n\t}\n\n\treturn c.Post(p, \"POST\", bodyType, buf, int64(buf.Len()))\n}\n\n// SetReadTimeout sets the read timeout for future calls that read from the\n// fcgi responder. A zero value for t means no timeout will be set.\nfunc (c *FCGIClient) SetReadTimeout(t time.Duration) error {\n\tif conn, ok := c.rwc.(net.Conn); ok && t != 0 {\n\t\treturn conn.SetReadDeadline(time.Now().Add(t))\n\t}\n\treturn nil\n}\n\n// SetWriteTimeout sets the write timeout for future calls that send data to\n// the fcgi responder. A zero value for t means no timeout will be set.\nfunc (c *FCGIClient) SetWriteTimeout(t time.Duration) error {\n\tif conn, ok := c.rwc.(net.Conn); ok && t != 0 {\n\t\treturn conn.SetWriteDeadline(time.Now().Add(t))\n\t}\n\treturn nil\n}\n\n// Checks whether chunked is part of the encodings stack\nfunc chunked(te []string) bool { return len(te) > 0 && te[0] == \"chunked\" }\n"
  },
  {
    "path": "pkg/app/master/probe/http/internal/fastcgi.go",
    "content": "// This file is a modified version of\n// https://github.com/caddyserver/caddy/blob/44e5e9e/modules/caddyhttp/reverseproxy/fastcgi/fastcgi.go\n// Modifications made permit targeting containerized PHP scripts\n// and decouple Caddy dependencies.\n\n// Copyright 2015 Matthew Holt and The Caddy Authors\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//     http://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\npackage internal\n\nimport (\n\t\"crypto/tls\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"path\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar _ http.RoundTripper = &FastCGITransport{}\n\n// FastCGITransport facilitates FastCGI communication.\ntype FastCGITransport struct {\n\t// Root is the fastcgi root directory.\n\t// Defaults to the root directory of the container.\n\tRoot string\n\n\t// The path in the URL will be split into two, with the first piece ending\n\t// with the value of SplitPath. The first piece will be assumed as the\n\t// actual resource (CGI script) name, and the second piece will be set to\n\t// PATH_INFO for the CGI script to use.\n\tSplitPath []string\n\n\t// Extra environment variables.\n\tEnvVars map[string]string\n\n\t// The duration used to set a deadline when connecting to an upstream.\n\tDialTimeout time.Duration\n\n\t// The duration used to set a deadline when reading from the FastCGI server.\n\tReadTimeout time.Duration\n\n\t// The duration used to set a deadline when sending to the FastCGI server.\n\tWriteTimeout time.Duration\n}\n\n// init sets up t.\nfunc (t *FastCGITransport) init() {\n\tif t.Root == \"\" {\n\t\tt.Root = \"/\"\n\t}\n}\n\n// RoundTrip implements http.RoundTripper.\nfunc (t FastCGITransport) RoundTrip(r *http.Request) (*http.Response, error) {\n\tt.init()\n\n\tenv, err := t.buildEnv(r)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"building environment: %v\", err)\n\t}\n\n\tnetwork, address := \"tcp\", r.URL.Host\n\n\tif log.IsLevelEnabled(log.DebugLevel) {\n\t\tenvJSON, _ := json.Marshal(env)\n\t\tlog.Debugf(\"HTTP probe - FastCGI env - %s\", string(envJSON))\n\t}\n\n\tctx := r.Context()\n\tdialer := net.Dialer{Timeout: t.DialTimeout}\n\tfcgiBackend, err := DialWithDialerContext(ctx, network, address, dialer)\n\tif err != nil {\n\t\t// TODO: wrap in a special error type if the dial failed, so retries can happen if enabled\n\t\treturn nil, fmt.Errorf(\"dialing backend: %v\", err)\n\t}\n\t// fcgiBackend gets closed when response body is closed (see clientCloser)\n\n\t// read/write timeouts\n\tif err := fcgiBackend.SetReadTimeout(t.ReadTimeout); err != nil {\n\t\treturn nil, fmt.Errorf(\"setting read timeout: %v\", err)\n\t}\n\tif err := fcgiBackend.SetWriteTimeout(t.WriteTimeout); err != nil {\n\t\treturn nil, fmt.Errorf(\"setting write timeout: %v\", err)\n\t}\n\n\tcontentLength := r.ContentLength\n\tif contentLength == 0 {\n\t\tcontentLength, _ = strconv.ParseInt(r.Header.Get(\"Content-Length\"), 10, 64)\n\t}\n\n\tvar resp *http.Response\n\tswitch r.Method {\n\tcase http.MethodHead:\n\t\tresp, err = fcgiBackend.Head(env)\n\tcase http.MethodGet:\n\t\tresp, err = fcgiBackend.Get(env, r.Body, contentLength)\n\tcase http.MethodOptions:\n\t\tresp, err = fcgiBackend.Options(env)\n\tdefault:\n\t\tresp, err = fcgiBackend.Post(env, r.Method, r.Header.Get(\"Content-Type\"), r.Body, contentLength)\n\t}\n\n\treturn resp, err\n}\n\n// buildEnv returns a set of CGI environment variables for the request.\nfunc (t FastCGITransport) buildEnv(r *http.Request) (map[string]string, error) {\n\n\t// Separate remote IP and port; more lenient than net.SplitHostPort\n\tvar ip, port string\n\tif idx := strings.LastIndex(r.RemoteAddr, \":\"); idx > -1 {\n\t\tip = r.RemoteAddr[:idx]\n\t\tport = r.RemoteAddr[idx+1:]\n\t} else {\n\t\tip = r.RemoteAddr\n\t}\n\n\t// Remove [] from IPv6 addresses\n\tip = strings.Replace(ip, \"[\", \"\", 1)\n\tip = strings.Replace(ip, \"]\", \"\", 1)\n\n\t// make sure file root is absolute\n\tif !path.IsAbs(t.Root) {\n\t\treturn nil, fmt.Errorf(\"root %q is not absolute\", t.Root)\n\t}\n\troot := t.Root\n\n\tfpath := r.URL.Path\n\tscriptName := fpath\n\n\tdocURI := fpath\n\t// split \"actual path\" from \"path info\" if configured\n\tvar pathInfo string\n\tif splitPos := t.splitPos(fpath); splitPos > -1 {\n\t\tdocURI = fpath[:splitPos]\n\t\tpathInfo = fpath[splitPos:]\n\n\t\t// Strip PATH_INFO from SCRIPT_NAME\n\t\tscriptName = strings.TrimSuffix(scriptName, pathInfo)\n\t}\n\n\t// SCRIPT_FILENAME is the absolute path of SCRIPT_NAME\n\tscriptFilename := path.Join(root, scriptName)\n\n\t// Ensure the SCRIPT_NAME has a leading slash for compliance with RFC3875\n\t// Info: https://tools.ietf.org/html/rfc3875#section-4.1.13\n\tif scriptName != \"\" && !path.IsAbs(scriptName) {\n\t\tscriptName = \"/\" + scriptName\n\t}\n\n\trequestScheme := \"http\"\n\tif r.TLS != nil {\n\t\trequestScheme = \"https\"\n\t}\n\n\treqHost, reqPort, err := net.SplitHostPort(r.Host)\n\tif err != nil {\n\t\t// whatever, just assume there was no port\n\t\treqHost = r.Host\n\t}\n\n\tauthUser, _, _ := r.BasicAuth()\n\n\t// Some variables are unused but cleared explicitly to prevent\n\t// the parent environment from interfering.\n\tenv := map[string]string{\n\t\t// Variables defined in CGI 1.1 spec\n\t\t\"AUTH_TYPE\":         \"\", // Not used\n\t\t\"CONTENT_LENGTH\":    r.Header.Get(\"Content-Length\"),\n\t\t\"CONTENT_TYPE\":      r.Header.Get(\"Content-Type\"),\n\t\t\"GATEWAY_INTERFACE\": \"CGI/1.1\",\n\t\t\"PATH_INFO\":         pathInfo,\n\t\t\"QUERY_STRING\":      r.URL.RawQuery,\n\t\t\"REMOTE_ADDR\":       ip,\n\t\t\"REMOTE_HOST\":       ip, // For speed, remote host lookups disabled\n\t\t\"REMOTE_PORT\":       port,\n\t\t\"REMOTE_IDENT\":      \"\", // Not used\n\t\t\"REMOTE_USER\":       authUser,\n\t\t\"REQUEST_METHOD\":    r.Method,\n\t\t\"REQUEST_SCHEME\":    requestScheme,\n\t\t\"SERVER_NAME\":       reqHost,\n\t\t\"SERVER_PROTOCOL\":   r.Proto,\n\t\t\"SERVER_SOFTWARE\":   \"slimtoolkit/v0.0.0\",\n\n\t\t// Other variables\n\t\t\"DOCUMENT_ROOT\": root,\n\t\t\"DOCUMENT_URI\":  docURI,\n\t\t\"HTTP_HOST\":     r.Host, // added here, since not always part of headers\n\t\t// \"REQUEST_URI\":     \"\",\n\t\t\"SCRIPT_FILENAME\": scriptFilename,\n\t\t\"SCRIPT_NAME\":     scriptName,\n\t}\n\n\t// compliance with the CGI specification requires that\n\t// PATH_TRANSLATED should only exist if PATH_INFO is defined.\n\t// Info: https://www.ietf.org/rfc/rfc3875 Page 14\n\tif pathInfo != \"\" {\n\t\tenv[\"PATH_TRANSLATED\"] = path.Join(root, pathInfo)\n\t}\n\n\t// compliance with the CGI specification requires that\n\t// SERVER_PORT should only exist if it's a valid numeric value.\n\t// Info: https://www.ietf.org/rfc/rfc3875 Page 18\n\tif reqPort != \"\" {\n\t\tenv[\"SERVER_PORT\"] = reqPort\n\t}\n\n\t// Some web apps rely on knowing HTTPS or not\n\tif r.TLS != nil {\n\t\tenv[\"HTTPS\"] = \"on\"\n\t\t// and pass the protocol details in a manner compatible with apache's mod_ssl\n\t\t// (which is why these have a SSL_ prefix and not TLS_).\n\t\tv, ok := tlsProtocolStrings[r.TLS.Version]\n\t\tif ok {\n\t\t\tenv[\"SSL_PROTOCOL\"] = v\n\t\t}\n\t\t// and pass the cipher suite in a manner compatible with apache's mod_ssl\n\t\tfor _, cs := range tls.CipherSuites() {\n\t\t\tif cs.ID == r.TLS.CipherSuite {\n\t\t\t\tenv[\"SSL_CIPHER\"] = cs.Name\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add env variables from config (with support for placeholders in values)\n\tfor key, value := range t.EnvVars {\n\t\tenv[key] = value\n\t}\n\n\t// Add all HTTP headers to env variables\n\tfor field, val := range r.Header {\n\t\theader := strings.ToUpper(field)\n\t\theader = headerNameReplacer.Replace(header)\n\t\tenv[\"HTTP_\"+header] = strings.Join(val, \", \")\n\t}\n\n\treturn env, nil\n}\n\n// splitPos returns the index where path should\n// be split based on t.SplitPath.\nfunc (t FastCGITransport) splitPos(path string) int {\n\tif len(t.SplitPath) == 0 {\n\t\treturn 0\n\t}\n\n\tlowerPath := strings.ToLower(path)\n\tfor _, split := range t.SplitPath {\n\t\tif idx := strings.Index(lowerPath, strings.ToLower(split)); idx > -1 {\n\t\t\treturn idx + len(split)\n\t\t}\n\t}\n\treturn -1\n}\n\n// Map of supported protocols to Apache ssl_mod format\n// Note that these are slightly different from SupportedProtocols in caddytls/config.go\nvar tlsProtocolStrings = map[uint16]string{\n\ttls.VersionTLS10: \"TLSv1\",\n\ttls.VersionTLS11: \"TLSv1.1\",\n\ttls.VersionTLS12: \"TLSv1.2\",\n\ttls.VersionTLS13: \"TLSv1.3\",\n}\n\nvar headerNameReplacer = strings.NewReplacer(\" \", \"_\", \"-\", \"_\")\n"
  },
  {
    "path": "pkg/app/master/probe/http/swagger.go",
    "content": "package http\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/getkin/kin-openapi/openapi2\"\n\t\"github.com/getkin/kin-openapi/openapi2conv\"\n\t\"github.com/getkin/kin-openapi/openapi3\"\n\t\"github.com/ghodss/yaml\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype apiSpecInfo struct {\n\tspec           *openapi3.T\n\tprefixOverride string\n}\n\nfunc (p *CustomProbe) loadAPISpecFiles() {\n\tfor _, info := range p.opts.APISpecFiles {\n\t\tfileName := info\n\t\tprefixOverride := \"\"\n\t\tif strings.Contains(info, \":\") {\n\t\t\tparts := strings.SplitN(info, \":\", 2)\n\t\t\tfileName = parts[0]\n\t\t\tprefixOverride = parts[1]\n\t\t}\n\n\t\tspec, err := loadAPISpecFromFile(fileName)\n\t\tif err != nil {\n\t\t\tp.xc.Out.Info(\"http.probe.apispec.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"error loading api spec file\",\n\t\t\t\t\t\"error\":   err,\n\t\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tif spec == nil {\n\t\t\tp.xc.Out.Info(\"http.probe.apispec\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"unsupported spec type\",\n\t\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tinfo := apiSpecInfo{\n\t\t\tspec:           spec,\n\t\t\tprefixOverride: prefixOverride,\n\t\t}\n\n\t\tp.APISpecProbes = append(p.APISpecProbes, info)\n\t}\n}\n\nfunc parseAPISpec(rdata []byte) (*openapi3.T, error) {\n\tif isOpenAPI(rdata) {\n\t\tlog.Debug(\"http.CustomProbe.parseAPISpec - is openapi\")\n\t\tloader := openapi3.NewLoader()\n\t\tloader.IsExternalRefsAllowed = true\n\t\tspec, err := loader.LoadFromData(rdata)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"http.CustomProbe.parseAPISpec.LoadFromData - error=%v\", err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn spec, nil\n\t}\n\n\tif isSwagger(rdata) {\n\t\tlog.Debug(\"http.CustomProbe.parseAPISpec - is swagger\")\n\t\tspec2 := &openapi2.T{}\n\t\tif err := yaml.Unmarshal(rdata, spec2); err != nil {\n\t\t\tlog.Debugf(\"http.CustomProbe.parseAPISpec.yaml.Unmarshal - error=%v\", err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\tspec, err := openapi2conv.ToV3(spec2)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"http.CustomProbe.parseAPISpec.ToV3 - error=%v\", err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn spec, nil\n\t}\n\n\tlog.Debugf(\"http.CustomProbe.parseAPISpec - unsupported api spec type (%d): %s\", len(rdata), string(rdata))\n\treturn nil, nil\n}\n\nfunc loadAPISpecFromEndpoint(client *http.Client, endpoint string) (*openapi3.T, error) {\n\tlog.Debugf(\"http.CustomProbe.loadAPISpecFromEndpoint(%s)\", endpoint)\n\treq, err := http.NewRequest(\"GET\", endpoint, nil)\n\tif err != nil {\n\t\tlog.Debugf(\"http.CustomProbe.loadAPISpecFromEndpoint.http.NewRequest - error=%v\", err)\n\t\treturn nil, err\n\t}\n\n\tres, err := client.Do(req)\n\tif err != nil {\n\t\tlog.Debugf(\"http.CustomProbe.loadAPISpecFromEndpoint.httpClient.Do - error=%v\", err)\n\t\treturn nil, err\n\t}\n\n\tif res != nil && res.Body != nil {\n\t\tdefer res.Body.Close()\n\t}\n\n\tif res.Body != nil {\n\t\trdata, err := io.ReadAll(res.Body)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"http.CustomProbe.loadAPISpecFromEndpoint.response.read - error=%v\", err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn parseAPISpec(rdata)\n\t}\n\n\tlog.Debug(\"http.CustomProbe.loadAPISpecFromEndpoint.response - no body\")\n\treturn nil, nil\n}\n\nfunc loadAPISpecFromFile(name string) (*openapi3.T, error) {\n\trdata, err := os.ReadFile(name)\n\tif err != nil {\n\t\tlog.Debugf(\"http.CustomProbe.loadAPISpecFromFile.ReadFile - error=%v\", err)\n\t\treturn nil, err\n\t}\n\n\treturn parseAPISpec(rdata)\n}\n\nfunc isSwagger(data []byte) bool {\n\tif (bytes.Contains(data, []byte(`\"swagger\":`)) ||\n\t\tbytes.Contains(data, []byte(`swagger:`))) &&\n\t\tbytes.Contains(data, []byte(`paths`)) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc isOpenAPI(data []byte) bool {\n\tif (bytes.Contains(data, []byte(`\"openapi\":`)) ||\n\t\tbytes.Contains(data, []byte(`openapi:`))) &&\n\t\tbytes.Contains(data, []byte(`paths`)) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc apiSpecPrefix(spec *openapi3.T) (string, error) {\n\t//for now get the api prefix from the first server struc\n\t//later, support multiple prefixes if there's more than one server struct\n\tvar prefix string\n\tfor _, sinfo := range spec.Servers {\n\t\txurl := sinfo.URL\n\t\tif strings.Contains(xurl, \"{\") {\n\t\t\tfor k, vinfo := range sinfo.Variables {\n\t\t\t\tvarStr := fmt.Sprintf(\"{%s}\", k)\n\t\t\t\tif strings.Contains(xurl, varStr) {\n\t\t\t\t\tvalStr := \"var\"\n\t\t\t\t\tif vinfo.Default != \"\" {\n\t\t\t\t\t\tvalStr = fmt.Sprintf(\"%v\", vinfo.Default)\n\t\t\t\t\t} else if len(vinfo.Enum) > 0 {\n\t\t\t\t\t\tvalStr = fmt.Sprintf(\"%v\", vinfo.Enum[0])\n\t\t\t\t\t}\n\n\t\t\t\t\txurl = strings.ReplaceAll(xurl, varStr, valStr)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif strings.Contains(xurl, \"{\") {\n\t\t\txurl = strings.ReplaceAll(xurl, \"{\", \"\")\n\n\t\t\tif strings.Contains(xurl, \"}\") {\n\t\t\t\txurl = strings.ReplaceAll(xurl, \"}\", \"\")\n\t\t\t}\n\t\t}\n\n\t\tparsed, err := url.Parse(xurl)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tif parsed.Path != \"\" && parsed.Path != \"/\" {\n\t\t\tprefix = parsed.Path\n\t\t}\n\t}\n\n\treturn prefix, nil\n}\n\nfunc (p *CustomProbe) loadAPISpecs(proto, targetHost, port string) {\n\n\tbaseAddr := getHTTPAddr(proto, targetHost, port)\n\tclient, err := getHTTPClient(proto)\n\tif err != nil {\n\t\tp.xc.Out.Error(\"HTTP probe - construct client error - %v\", err.Error())\n\t\treturn\n\t}\n\n\t//TODO:\n\t//Need to support user provided target port for the spec,\n\t//but these need to be mapped to the actual port at runtime\n\t//Need to support user provided target proto for the spec\n\tfor _, info := range p.opts.APISpecs {\n\t\tspecPath := info\n\t\tprefixOverride := \"\"\n\t\tif strings.Contains(info, \":\") {\n\t\t\tparts := strings.SplitN(info, \":\", 2)\n\t\t\tspecPath = parts[0]\n\t\t\tprefixOverride = parts[1]\n\t\t}\n\n\t\taddr := fmt.Sprintf(\"%s%s\", baseAddr, specPath)\n\t\tspec, err := loadAPISpecFromEndpoint(client, addr)\n\t\tif err != nil {\n\t\t\tp.xc.Out.Info(\"http.probe.apispec.error\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"error loading api spec from endpoint\",\n\t\t\t\t\t\"error\":   err,\n\t\t\t\t})\n\n\t\t\tcontinue\n\t\t}\n\n\t\tif spec == nil {\n\t\t\tp.xc.Out.Info(\"http.probe.apispec\",\n\t\t\t\tovars{\n\t\t\t\t\t\"message\": \"unsupported spec type\",\n\t\t\t\t})\n\n\t\t\tcontinue\n\t\t}\n\n\t\tinfo := apiSpecInfo{\n\t\t\tspec:           spec,\n\t\t\tprefixOverride: prefixOverride,\n\t\t}\n\n\t\tp.APISpecProbes = append(p.APISpecProbes, info)\n\t}\n}\n\nfunc pathOps(pinfo *openapi3.PathItem) map[string]*openapi3.Operation {\n\tops := map[string]*openapi3.Operation{}\n\taddPathOp(&ops, pinfo.Connect, \"connect\")\n\taddPathOp(&ops, pinfo.Delete, \"delete\")\n\taddPathOp(&ops, pinfo.Get, \"get\")\n\taddPathOp(&ops, pinfo.Head, \"head\")\n\taddPathOp(&ops, pinfo.Options, \"options\")\n\taddPathOp(&ops, pinfo.Patch, \"patch\")\n\taddPathOp(&ops, pinfo.Post, \"post\")\n\taddPathOp(&ops, pinfo.Put, \"put\")\n\taddPathOp(&ops, pinfo.Trace, \"trace\")\n\treturn ops\n}\n\nfunc addPathOp(m *map[string]*openapi3.Operation, op *openapi3.Operation, name string) {\n\tif op != nil {\n\t\t(*m)[name] = op\n\t}\n}\n\nfunc (p *CustomProbe) probeAPISpecEndpoints(proto, targetHost, port, prefix string, spec *openapi3.T) {\n\taddr := getHTTPAddr(proto, targetHost, port)\n\n\tif p.printState {\n\t\tp.xc.Out.State(\"http.probe.api-spec.probe.endpoint.starting\",\n\t\t\tovars{\n\t\t\t\t\"addr\":      addr,\n\t\t\t\t\"prefix\":    prefix,\n\t\t\t\t\"endpoints\": len(spec.Paths),\n\t\t\t})\n\t}\n\n\thttpClient, err := getHTTPClient(proto)\n\tif err != nil {\n\t\tp.xc.Out.Error(\"HTTP probe - construct client error - %v\", err.Error())\n\t\treturn\n\t}\n\n\tfor apiPath, pathInfo := range spec.Paths {\n\t\t//very primitive way to set the path params (will break for numeric values)\n\t\tif strings.Contains(apiPath, \"{\") {\n\t\t\tapiPath = strings.ReplaceAll(apiPath, \"{\", \"\")\n\n\t\t\tif strings.Contains(apiPath, \"}\") {\n\t\t\t\tapiPath = strings.ReplaceAll(apiPath, \"}\", \"\")\n\t\t\t}\n\t\t}\n\n\t\tendpoint := fmt.Sprintf(\"%s%s%s\", addr, prefix, apiPath)\n\t\tops := pathOps(pathInfo)\n\t\tfor apiMethod := range ops {\n\t\t\t//make a call (no params for now)\n\t\t\tp.apiSpecEndpointCall(httpClient, endpoint, apiMethod)\n\t\t}\n\t}\n}\n\nfunc (p *CustomProbe) apiSpecEndpointCall(client *http.Client, endpoint, method string) {\n\tmaxRetryCount := probeRetryCount\n\tif p.opts.RetryCount > 0 {\n\t\tmaxRetryCount = p.opts.RetryCount\n\t}\n\n\tnotReadyErrorWait := time.Duration(16)\n\twebErrorWait := time.Duration(8)\n\totherErrorWait := time.Duration(4)\n\tif p.opts.RetryWait > 0 {\n\t\twebErrorWait = time.Duration(p.opts.RetryWait)\n\t\tnotReadyErrorWait = time.Duration(p.opts.RetryWait * 2)\n\t\totherErrorWait = time.Duration(p.opts.RetryWait / 2)\n\t}\n\n\tmethod = strings.ToUpper(method)\n\tfor i := 0; i < maxRetryCount; i++ {\n\t\treq, err := http.NewRequest(method, endpoint, nil)\n\t\tif err != nil {\n\t\t\tp.xc.Out.Error(\"HTTP probe - construct request error - %v\", err.Error())\n\t\t\t// Break since the same args are passed to NewRequest() on each loop.\n\t\t\tbreak\n\t\t}\n\t\t//no body, no request headers and no credentials for now\n\t\tres, err := client.Do(req)\n\t\tp.CallCount++\n\n\t\tif res != nil {\n\t\t\tif res.Body != nil {\n\t\t\t\tio.Copy(io.Discard, res.Body)\n\t\t\t}\n\n\t\t\tdefer res.Body.Close()\n\t\t}\n\n\t\tstatusCode := \"error\"\n\t\tcallErrorStr := \"none\"\n\t\tif err == nil {\n\t\t\tstatusCode = fmt.Sprintf(\"%v\", res.StatusCode)\n\t\t} else {\n\t\t\tcallErrorStr = err.Error()\n\t\t}\n\n\t\tif p.printState {\n\t\t\tp.xc.Out.Info(\"http.probe.api-spec.probe.endpoint.call\",\n\t\t\t\tovars{\n\t\t\t\t\t\"status\":   statusCode,\n\t\t\t\t\t\"method\":   method,\n\t\t\t\t\t\"endpoint\": endpoint,\n\t\t\t\t\t\"attempt\":  i + 1,\n\t\t\t\t\t\"error\":    callErrorStr,\n\t\t\t\t\t\"time\":     time.Now().UTC().Format(time.RFC3339),\n\t\t\t\t})\n\t\t}\n\n\t\tif err == nil {\n\t\t\tp.OkCount++\n\t\t\tbreak\n\t\t} else {\n\t\t\tp.ErrCount++\n\n\t\t\tif urlErr, ok := err.(*url.Error); ok {\n\t\t\t\tif urlErr.Err == io.EOF {\n\t\t\t\t\tlog.Debugf(\"HTTP probe - target not ready yet (retry again later)...\")\n\t\t\t\t\ttime.Sleep(notReadyErrorWait * time.Second)\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"HTTP probe - web error... retry again later...\")\n\t\t\t\t\ttime.Sleep(webErrorWait * time.Second)\n\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"HTTP probe - other error... retry again later...\")\n\t\t\t\ttime.Sleep(otherErrorWait * time.Second)\n\t\t\t}\n\t\t}\n\n\t}\n}\n"
  },
  {
    "path": "pkg/app/master/probe/http/wsclient.go",
    "content": "package http\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/gorilla/websocket\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/acounter\"\n)\n\nconst (\n\tProtoWS  = \"ws\"\n\tProtoWSS = \"wss\"\n)\n\ntype WebsocketClient struct {\n\tOnRead    func(mtype int, mdata []byte)\n\tReadCh    chan WebsocketMessage\n\tConn      *websocket.Conn\n\tReadCount acounter.Type\n\tPongCount acounter.Type\n\tPingCount acounter.Type\n\tAddr      string\n\tpongCh    chan string\n\tdoneCh    chan struct{}\n}\n\ntype WebsocketMessage struct {\n\tType int\n\tData []byte\n}\n\nfunc NewWebsocketClient(proto, host, port string) (*WebsocketClient, error) {\n\tif proto == \"\" {\n\t\tproto = ProtoWS\n\t}\n\n\tif !IsValidWSProto(proto) {\n\t\treturn nil, fmt.Errorf(\"invalid ws proto - %s\", proto)\n\t}\n\n\twsclient := &WebsocketClient{\n\t\tAddr:   fmt.Sprintf(\"%s://%s:%s\", proto, host, port),\n\t\tdoneCh: make(chan struct{}),\n\t\tpongCh: make(chan string, 10),\n\t}\n\n\treturn wsclient, nil\n}\n\nfunc IsValidWSProto(proto string) bool {\n\tswitch proto {\n\tcase ProtoWS, ProtoWSS:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (wc *WebsocketClient) Connect() error {\n\tconn, _, err := websocket.DefaultDialer.Dial(wc.Addr, nil)\n\tif err != nil {\n\t\tlog.Debugf(\"WebsocketClient.Connect: ws.Dial error=%v\", err)\n\t\treturn err\n\t}\n\n\tpongHandler := func(data string) error {\n\t\twc.PongCount.Inc()\n\t\tlog.Debugf(\"WebsocketClient: Pong Handler - data='%s'\", data)\n\t\twc.pongCh <- data\n\t\treturn nil\n\t}\n\tconn.SetPongHandler(pongHandler)\n\n\tdefaultPingHandler := conn.PingHandler()\n\tpingHandler := func(data string) error {\n\t\twc.PingCount.Inc()\n\t\tlog.Debugf(\"WebsocketClient: Ping Handler - data='%s'\", data)\n\t\treturn defaultPingHandler(data)\n\t}\n\tconn.SetPingHandler(pingHandler)\n\n\tgo func() {\n\t\tfor {\n\t\t\tlog.Debug(\"WebsocketClient: reader - waiting for errors...\")\n\t\t\tselect {\n\t\t\tcase <-wc.doneCh:\n\t\t\t\tlog.Debug(\"WebsocketClient: reader - error collector - done...\")\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tmtype, message, err := conn.ReadMessage()\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"WebsocketClient: reader - read error=%v\", err)\n\t\t\t\t\t//read err: websocket: close 1000 (normal)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tlog.Debugf(\"WebsocketClient: reader - read={type=%s(%d) len=%d data='%s'}\\n\", wsMessageType(mtype), mtype, len(message), message)\n\t\t\t\twc.ReadCount.Inc()\n\t\t\t\tif wc.OnRead != nil {\n\t\t\t\t\twc.OnRead(mtype, message)\n\t\t\t\t}\n\n\t\t\t\tif wc.ReadCh != nil {\n\t\t\t\t\tselect {\n\t\t\t\t\tcase wc.ReadCh <- WebsocketMessage{Type: mtype, Data: message}:\n\t\t\t\t\t\tlog.Debug(\"WebsocketClient: reader - posted message to wc.ReadCh\")\n\t\t\t\t\tcase <-time.After(time.Second * 5):\n\t\t\t\t\t\tlog.Debug(\"WebsocketClient: reader - timed out posting message to wc.ReadCh\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\twc.Conn = conn\n\treturn nil\n}\n\nfunc wsMessageType(val int) string {\n\tswitch val {\n\tcase websocket.TextMessage:\n\t\treturn \"text\"\n\tcase websocket.BinaryMessage:\n\t\treturn \"binary\"\n\tcase websocket.CloseMessage:\n\t\treturn \"close\"\n\tcase websocket.PingMessage:\n\t\treturn \"ping\"\n\tcase websocket.PongMessage:\n\t\treturn \"pong\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"unknown(%d)\", val)\n\t}\n}\n\nfunc (wc *WebsocketClient) CheckConnection() error {\n\tlog.Debugf(\"WebsocketClient.CheckConnection: conn.WriteControl(websocket.PingMessage)\")\n\n\terr := wc.Conn.WriteControl(websocket.PingMessage, []byte(\"wc.ping\"), time.Now().Add(3*time.Second))\n\tif err != nil {\n\t\tlog.Debugf(\"WebsocketClient.CheckConnection: conn.WriteControl(websocket.PingMessage) error=%v\", err)\n\t\treturn err\n\t}\n\n\tselect {\n\tcase pongData := <-wc.pongCh:\n\t\tlog.Debugf(\"WebsocketClient.CheckConnection: pong data = %v\", pongData)\n\tcase <-time.After(time.Second * 5):\n\t\tlog.Debug(\"WebsocketClient.CheckConnection: pong data timeout\")\n\t}\n\n\treturn nil\n}\n\nfunc (wc *WebsocketClient) WriteString(data string) error {\n\terr := wc.Conn.WriteMessage(websocket.TextMessage, []byte(data))\n\tif err != nil {\n\t\tlog.Debugf(\"WebsocketClient.WriteString: conn.WriteMessage(websocket.TextMessage) error=%v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (wc *WebsocketClient) WriteBinary(data []byte) error {\n\terr := wc.Conn.WriteMessage(websocket.BinaryMessage, data)\n\tif err != nil {\n\t\tlog.Debugf(\"WebsocketClient.WriteString: conn.WriteMessage(websocket.BinaryMessage) error=%v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (wc *WebsocketClient) Disconnect() error {\n\tif wc.Conn != nil {\n\t\tclose(wc.doneCh)\n\t\twc.doneCh = nil\n\n\t\terr := wc.Conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, \"\"))\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"WebsocketClient.Disconnect: conn.WriteMessage(websocket.CloseMessage) error=%v\", err)\n\t\t\treturn err\n\t\t}\n\n\t\t//TODO: should wait for the 'websocket: close 1000 (normal)' read error\n\t\ttime.Sleep(2 * time.Second)\n\n\t\twc.Conn.Close()\n\t\twc.Conn = nil\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/security/apparmor/apparmor.go",
    "content": "package apparmor\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"text/template\"\n\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n)\n\nconst appArmorTemplate = `\nprofile {{.ProfileName}} flags=(attach_disconnected,mediate_deleted) {\n\n  network,\n\n{{range $value := .ExeFileRules}}  {{$value.FilePath}} {{$value.PermSet}},\n{{end}}\n{{range $value := .WriteFileRules}}  {{$value.FilePath}} {{$value.PermSet}},\n{{end}}\n{{range $value := .ReadFileRules}}  {{$value.FilePath}} {{$value.PermSet}},\n{{end}}\n}\n`\n\ntype appArmorFileRule struct {\n\tFilePath string\n\tPermSet  string\n}\n\ntype appArmorProfileData struct {\n\tProfileName    string\n\tExeFileRules   []appArmorFileRule\n\tWriteFileRules []appArmorFileRule\n\tReadFileRules  []appArmorFileRule\n}\n\n//TODO:\n//need to safe more metadata about the artifacts in the monitor data\n//1. exe bit\n//2. w/r operation info (so we can add useful write rules)\n\n// GenProfile creates an AppArmor profile\nfunc GenProfile(artifactLocation string, profileName string) error {\n\tcontainerReportFilePath := filepath.Join(artifactLocation, report.DefaultContainerReportFileName)\n\n\tif _, err := os.Stat(containerReportFilePath); err != nil {\n\t\treturn err\n\t}\n\treportFile, err := os.Open(containerReportFilePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer reportFile.Close()\n\n\tvar creport report.ContainerReport\n\tif err = json.NewDecoder(reportFile).Decode(&creport); err != nil {\n\t\treturn err\n\t}\n\n\tprofilePath := filepath.Join(artifactLocation, profileName)\n\n\tprofileFile, err := os.OpenFile(profilePath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|os.O_APPEND, 0644)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer profileFile.Close()\n\n\tprofileData := appArmorProfileData{ProfileName: profileName}\n\n\tfor _, aprops := range creport.Image.Files {\n\t\tif aprops == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif aprops.Flags == nil {\n\t\t\t//default to \"R\" (todo: double check flag creation...)\n\t\t\tprofileData.ReadFileRules = append(profileData.ReadFileRules,\n\t\t\t\tappArmorFileRule{\n\t\t\t\t\tFilePath: aprops.FilePath,\n\t\t\t\t\tPermSet:  \"r\",\n\t\t\t\t})\n\t\t} else {\n\t\t\tswitch {\n\t\t\tcase aprops.Flags[\"X\"]:\n\t\t\t\tprofileData.ExeFileRules = append(profileData.ExeFileRules,\n\t\t\t\t\tappArmorFileRule{\n\t\t\t\t\t\tFilePath: aprops.FilePath,\n\t\t\t\t\t\tPermSet:  report.PermSetFromFlags(aprops.Flags),\n\t\t\t\t\t})\n\t\t\tcase aprops.Flags[\"W\"]:\n\t\t\t\tprofileData.WriteFileRules = append(profileData.WriteFileRules,\n\t\t\t\t\tappArmorFileRule{\n\t\t\t\t\t\tFilePath: aprops.FilePath,\n\t\t\t\t\t\tPermSet:  report.PermSetFromFlags(aprops.Flags),\n\t\t\t\t\t})\n\t\t\tcase aprops.Flags[\"R\"]:\n\t\t\t\tprofileData.ReadFileRules = append(profileData.ReadFileRules,\n\t\t\t\t\tappArmorFileRule{\n\t\t\t\t\t\tFilePath: aprops.FilePath,\n\t\t\t\t\t\tPermSet:  report.PermSetFromFlags(aprops.Flags),\n\t\t\t\t\t})\n\t\t\tdefault:\n\t\t\t\t//logrus.Printf(\"slim: genAppArmorProfile - other artifact => %v\\n\", aprops)\n\t\t\t\t//note: most are Symlinks\n\t\t\t}\n\t\t}\n\t}\n\n\tt, err := template.New(\"profile\").Parse(appArmorTemplate)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := t.Execute(profileFile, profileData); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/security/seccomp/seccomp.go",
    "content": "package seccomp\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n\t\"github.com/slimtoolkit/slim/pkg/third_party/opencontainers/specs\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar archMap = map[system.ArchName]specs.Arch{\n\tsystem.ArchName386:   specs.ArchX86,\n\tsystem.ArchNameAmd64: specs.ArchX86_64,\n\tsystem.ArchNameArm32: specs.ArchARM,\n\tsystem.ArchNameArm64: specs.ArchAARCH64,\n}\n\nfunc archNameToSeccompArch(name string) specs.Arch {\n\tif arch, ok := archMap[system.ArchName(name)]; ok {\n\t\treturn arch\n\t}\n\treturn \"unknown\"\n}\n\nvar extraCalls = []string{\n\t\"openat\",\n\t\"getdents64\",\n\t\"capget\",\n\t\"capset\",\n\t\"chdir\",\n\t\"setuid\",\n\t\"setgroups\",\n\t\"setgid\",\n\t\"prctl\",\n\t\"fchown\",\n\t\"getppid\",\n\t\"getpid\",\n\t\"getuid\",\n\t\"getgid\",\n\t\"epoll_pwait\",\n\t\"newfstatat\",\n\t\"exit\",\n\t\"stat\",\n\t\"lstat\",\n\t\"write\",\n\t\"futex\",\n\t\"execve\", //always detected, but it's still one of the syscalls Docker itself needs\n\t\"rt_sigreturn\",\n\t\"rt_sigsuspend\",\n\t\"exit_group\",\n\t\"kill\", //extra calls\n\t\"sendmsg\",\n\t\"wait4\",\n\t\"setitimer\",\n\t\"unlink\",\n\t\"dup3\",   //needed for some tty detection/setup logic (doesn't always get picked up)\n\t\"getcwd\", //safe to add\n}\n\n// GenProfile creates a SecComp profile\nfunc GenProfile(artifactLocation string, profileName string) error {\n\tcontainerReportFilePath := filepath.Join(artifactLocation, report.DefaultContainerReportFileName)\n\n\tif _, err := os.Stat(containerReportFilePath); err != nil {\n\t\treturn err\n\t}\n\treportFile, err := os.Open(containerReportFilePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer reportFile.Close()\n\n\tvar creport report.ContainerReport\n\tif err = json.NewDecoder(reportFile).Decode(&creport); err != nil {\n\t\treturn err\n\t}\n\n\tif !creport.Monitors.Pt.Enabled {\n\t\tlog.Debug(\"seccomp.GenProfile: not generating seccomp profile (PT mon disabled, no syscall info)\")\n\t\treturn nil\n\t}\n\n\tprofilePath := filepath.Join(artifactLocation, profileName)\n\tlog.Debug(\"seccomp.GenProfile: saving seccomp profile to \", profilePath)\n\n\tprofile := &specs.Seccomp{\n\t\tDefaultAction: specs.ActErrno,\n\t\tArchitectures: []specs.Arch{\n\t\t\tarchNameToSeccompArch(creport.Monitors.Pt.ArchName),\n\t\t},\n\t}\n\n\tnameResolver := system.CallNameResolver(system.ArchName(creport.Monitors.Pt.ArchName))\n\tif nameResolver != nil {\n\t\tfor _, xcall := range extraCalls {\n\t\t\tif cnum, ok := nameResolver(xcall); ok {\n\t\t\t\tcnKey := fmt.Sprintf(\"%d\", cnum)\n\t\t\t\tif _, ok := creport.Monitors.Pt.SyscallStats[cnKey]; !ok {\n\t\t\t\t\tcreport.Monitors.Pt.SyscallStats[cnKey] = report.SyscallStatInfo{Name: xcall}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tscSpec := specs.Syscall{\n\t\tAction: specs.ActAllow,\n\t}\n\n\tfor _, scInfo := range creport.Monitors.Pt.SyscallStats {\n\t\tscSpec.Names = append(scSpec.Names, scInfo.Name)\n\t}\n\n\tprofile.Syscalls = append(profile.Syscalls, &scSpec)\n\n\tprofileData, err := json.MarshalIndent(profile, \"\", \"  \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = os.WriteFile(profilePath, profileData, 0644)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/master/signals/signals.go",
    "content": "package signals\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar AppContinueChan = make(chan struct{})\nvar appDoneChan = make(chan struct{})\n\nvar signals = []os.Signal{\n\tsyscall.SIGUSR1,\n}\n\nfunc InitHandlers() {\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, signals...)\n\tlog.Debugf(\"slim: listening for signals - %+v\", signals)\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-appDoneChan:\n\t\t\t\treturn\n\t\t\tcase sig := <-sigChan:\n\t\t\t\tswitch sig {\n\t\t\t\tcase syscall.SIGUSR1:\n\t\t\t\t\tlog.Debug(\"slim: continue signal\")\n\t\t\t\t\tAppContinueChan <- struct{}{}\n\t\t\t\tdefault:\n\t\t\t\t\tlog.Debugf(\"slim: other signal (%v)...\", sig)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n}\n"
  },
  {
    "path": "pkg/app/master/update/update.go",
    "content": "package update\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"time\"\n\n\tvchecker \"github.com/slimtoolkit/slim/pkg/app/master/version\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tvinfo \"github.com/slimtoolkit/slim/pkg/version\"\n\n\t\"github.com/c4milo/unpackit\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/slimtoolkit/go-update\"\n\t\"github.com/slimtoolkit/uiprogress\"\n)\n\nconst (\n\thdrUserAgent     = \"User-Agent\"\n\thdrContentLength = \"Content-Length\"\n\tdownloadEndpoint = \"https://downloads.dockerslim.com/releases\"\n\tmasterAppName    = \"slim\"\n\tsensorAppName    = \"slim-sensor\"\n\tdistDirName      = \"dist\"\n\tartifactsPerms   = 0740\n)\n\nvar (\n\terrUnexpectedHTTPStatus = errors.New(\"unexpected HTTP status code\")\n)\n\n// Run checks the current version and updates it if it doesn't match the latest available version\nfunc Run(doDebug bool, statePath string, inContainer, isDSImage, doShowProgress bool) {\n\tlogger := log.WithFields(log.Fields{\"app\": \"slim\", \"command\": \"update\"})\n\n\tappPath, err := os.Executable()\n\terrutil.FailOn(err)\n\tappDirPath := filepath.Dir(appPath)\n\n\tvstatus := vchecker.Check(inContainer, isDSImage)\n\tlogger.Debugf(\"Version Status => %+v\", vstatus)\n\n\tif vstatus == nil || vstatus.Status != \"success\" {\n\t\tfmt.Printf(\"slim[update]: info=status message='version check was not successful'\\n\")\n\t\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n\t\treturn\n\t}\n\n\tif !vstatus.Outdated {\n\t\tfmt.Printf(\"slim[update]: info=status message='already using the current version'\\n\")\n\t\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n\t\treturn\n\t}\n\n\tfmt.Printf(\"slim[update]: info=version local=%s current=%s\\n\", vinfo.Tag(), vstatus.Current)\n\n\tblobNameBase, blobNameExt := getReleaseBlobInfo()\n\terrutil.FailWhen(blobNameBase == \"\", \"could not discover platform-specific release package name\")\n\n\treleaseDirPath, statePath := fsutil.PrepareReleaseStateDirs(statePath, vstatus.Current)\n\terrutil.FailOn(err)\n\n\tblobName := fmt.Sprintf(\"%s.%s\", blobNameBase, blobNameExt)\n\tblobPath := filepath.Join(releaseDirPath, blobName)\n\tlogger.Debugf(\"release package blob: %v\", blobPath)\n\n\tif fsutil.Exists(blobPath) {\n\t\t//feature: not removing/replacing the existing release package blob if it's already there\n\t\tfmt.Printf(\"slim[update]: info=status message='release package already downloaded'\\n\")\n\t\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n\t\treturn\n\t}\n\n\tfmt.Println(\"slim[update]: state=update.download.started\")\n\n\treleaseDownloadPath := fmt.Sprintf(\"%s/%s/%s\", downloadEndpoint, vstatus.Current, blobName)\n\tlogger.Debugf(\"release download path: %v\", releaseDownloadPath)\n\n\tif !isGoodDownloadSource(logger, releaseDownloadPath) {\n\t\tfmt.Printf(\"slim[update]: info=status message='release package download location is not accessible'\\n\")\n\t\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n\t\treturn\n\t}\n\n\tvar brConstructor BlobReaderConstructor = newPassThroughReader\n\tif doShowProgress {\n\t\tlogger.Debug(\"show download progress\")\n\t\tbrConstructor = newProgressReader\n\t}\n\n\terr = downloadRelease(logger, blobPath, releaseDownloadPath, brConstructor)\n\tif err != nil {\n\t\tlogger.Debugf(\"error downloading release: %v\", err)\n\t\tfmt.Printf(\"slim[update]: info=status message='error downloading release package'\\n\")\n\t\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n\t\treturn\n\t}\n\n\tfmt.Println(\"slim[update]: state=update.download.completed\")\n\n\tif err := unpackRelease(logger, blobPath, releaseDirPath, blobNameBase); err != nil {\n\t\tlogger.Debugf(\"error unpacking release package: %v\", err)\n\t\tfmt.Printf(\"slim[update]: info=status message='error unpacking release package'\\n\")\n\t\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n\t\treturn\n\t}\n\n\tfmt.Println(\"slim[update]: state=update.unpacked\")\n\n\tif err := installRelease(logger, appDirPath, statePath, releaseDirPath); err != nil {\n\t\tlogger.Debugf(\"error installing release: %v\", err)\n\t\tfmt.Printf(\"slim[update]: info=status message='error installing release'\\n\")\n\t\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n\t\treturn\n\t}\n\n\tfmt.Println(\"slim[update]: state=update.installed\")\n\tfmt.Printf(\"slim[update]: state=exited version=%s\\n\", vinfo.Current())\n}\n\nfunc getReleaseBlobInfo() (base string, ext string) {\n\tswitch runtime.GOOS {\n\tcase \"darwin\":\n\t\treturn \"dist_mac\", \"zip\"\n\tcase \"linux\":\n\t\tswitch runtime.GOARCH {\n\t\tcase \"amd64\":\n\t\t\treturn \"dist_linux\", \"tar.gz\"\n\t\tcase \"arm\":\n\t\t\treturn \"dist_linux_arm\", \"tar.gz\"\n\t\tcase \"arm64\":\n\t\t\treturn \"dist_linux_arm64\", \"tar.gz\"\n\t\tdefault:\n\t\t\treturn \"\", \"\"\n\t\t}\n\tdefault:\n\t\treturn \"\", \"\"\n\t}\n}\n\nfunc downloadRelease(logger *log.Entry, localBlobPath, downloadSource string, c BlobReaderConstructor) error {\n\td, err := os.Create(localBlobPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tclient := http.Client{\n\t\tTimeout: 13 * time.Second,\n\t}\n\n\treq, err := http.NewRequest(\"GET\", downloadSource, nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(hdrUserAgent, fmt.Sprintf(\"DockerSlimApp/%s\", vinfo.Current()))\n\n\tqs := url.Values{}\n\tqs.Add(\"cv\", vinfo.Tag())\n\treq.URL.RawQuery = qs.Encode()\n\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\tif resp != nil && resp.Body != nil {\n\t\t\tio.Copy(io.Discard, resp.Body)\n\t\t\tresp.Body.Close()\n\t\t}\n\n\t\td.Close()\n\t\tos.Remove(localBlobPath)\n\t\treturn err\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tlogger.Debugf(\"downloadRelease: unexpected status code - %v\", resp.StatusCode)\n\t\tio.Copy(io.Discard, resp.Body)\n\t\tresp.Body.Close()\n\t\td.Close()\n\t\tos.Remove(localBlobPath)\n\t\treturn errUnexpectedHTTPStatus\n\t}\n\n\tif resp.ContentLength == -1 {\n\t\tlogger.Debug(\"downloadRelease: content length is unknown\")\n\t}\n\tblobSize := int(resp.ContentLength)\n\tblobReader := c(blobSize, resp.Body)\n\n\tcopied, err := io.Copy(d, blobReader)\n\tif err != nil {\n\t\tblobReader.Close()\n\t\td.Close()\n\t\tos.Remove(localBlobPath)\n\t\treturn err\n\t}\n\n\tlogger.Debugf(\"downloadRelease: data size = %v (content length = %v)\", copied, blobSize)\n\n\tif err := blobReader.Close(); err != nil {\n\t\tlogger.Debugf(\"downloadRelease: error closing downloaded reader - %v\", err)\n\t}\n\n\td.Chmod(artifactsPerms)\n\n\tif err := d.Close(); err != nil {\n\t\tlogger.Debugf(\"downloadRelease: error closing downloaded release package - %v\", err)\n\t}\n\n\treturn nil\n}\n\nfunc isGoodDownloadSource(logger *log.Entry, location string) bool {\n\tclient := http.Client{\n\t\tTimeout: 13 * time.Second,\n\t\tCheckRedirect: func(req *http.Request, via []*http.Request) error {\n\t\t\treturn http.ErrUseLastResponse\n\t\t},\n\t}\n\n\treq, err := http.NewRequest(\"HEAD\", location, nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treq.Header.Set(hdrUserAgent, fmt.Sprintf(\"DockerSlimApp/%s\", vinfo.Current()))\n\n\tresp, err := client.Do(req)\n\tif resp != nil && resp.Body != nil {\n\t\tdefer func() {\n\t\t\tio.Copy(io.Discard, resp.Body)\n\t\t\tresp.Body.Close()\n\t\t}()\n\t}\n\n\tif err != nil {\n\t\tlogger.Debugf(\"isGoodDownloadSource: error - %v\", err)\n\t\treturn false\n\t}\n\n\tif resp.StatusCode >= 200 && resp.StatusCode < 400 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc unpackRelease(logger *log.Entry, blobPath, releaseRootPath, blobNameBase string) error {\n\tunpackedBlobDir := filepath.Join(releaseRootPath, blobNameBase)\n\tcommonBlobDir := filepath.Join(releaseRootPath, distDirName)\n\n\tif fsutil.DirExists(unpackedBlobDir) {\n\t\t//feature: not removing the unpacked directory if it's already there (todo: revisit the feature later)\n\t\tlogger.Debug(\"unpackRelease: error - unpacked package blob dir already exists\")\n\t\treturn nil\n\t}\n\n\t//todo: should check if it exists before we download the release package...\n\tif fsutil.DirExists(commonBlobDir) {\n\t\t//feature: not removing the unpacked dist directory if it's already there (todo: revisit the feature later)\n\t\tlogger.Debug(\"unpackRelease: error - release package dir already exists\")\n\t\treturn nil\n\t}\n\n\tfile, err := os.Open(blobPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer file.Close()\n\n\tdestPath, err := unpackit.Unpack(file, releaseRootPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlogger.Debugf(\"unpackRelease: unpacked package directory - %v\", destPath)\n\n\tif err := os.Remove(blobPath); err != nil {\n\t\tlogger.Debugf(\"unpackRelease: could not remove the release package blob - %v\", err)\n\t}\n\n\tif err := os.Rename(unpackedBlobDir, commonBlobDir); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc installRelease(logger *log.Entry, appRootPath, statePath, releaseRootPath string) error {\n\tnewMasterAppPath := filepath.Join(releaseRootPath, distDirName, masterAppName)\n\tnewSensorAppPath := filepath.Join(releaseRootPath, distDirName, sensorAppName)\n\tsensorAppPath := filepath.Join(appRootPath, sensorAppName)\n\n\terr := updateFile(logger, newSensorAppPath, sensorAppPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t//will copy the sensor to the state dir if DS is installed in a bad non-shared location on Macs\n\tfsutil.PreparePostUpdateStateDir(statePath)\n\n\terr = updateFile(logger, newMasterAppPath, \"\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc updateFile(logger *log.Entry, sourcePath, targetPath string) error {\n\tfile, err := os.Open(sourcePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\toptions := update.Options{}\n\tif targetPath != \"\" {\n\t\toptions.TargetPath = targetPath\n\t}\n\n\terr = update.Apply(file, options)\n\tif err != nil {\n\t\tif rerr := update.RollbackError(err); rerr != nil {\n\t\t\tlogger.Debugf(\"updateFile(%s,%s): Failed to rollback from bad update: %v\",\n\t\t\t\tsourcePath, targetPath, rerr)\n\t\t}\n\t}\n\treturn err\n}\n\ntype BlobReaderConstructor func(size int, rc io.ReadCloser) io.ReadCloser\n\nfunc newPassThroughReader(size int, rc io.ReadCloser) io.ReadCloser {\n\treturn rc\n}\n\nfunc newProgressReader(size int, rc io.ReadCloser) io.ReadCloser {\n\tpr := progressReader{\n\t\trc:       rc,\n\t\tsize:     size,\n\t\tprogress: uiprogress.New(),\n\t}\n\n\tif pr.progress != nil {\n\t\tpr.progress.SetRefreshInterval(time.Millisecond * 100)\n\t\tpr.progress.Start()\n\n\t\tpr.bar = pr.progress.AddBar(pr.size).AppendCompleted().PrependElapsed()\n\t\tpr.bar.Width = 50\n\t}\n\n\treturn &pr\n}\n\ntype progressReader struct {\n\trc       io.ReadCloser\n\tsize     int\n\tcurrent  int\n\tprogress *uiprogress.Progress\n\tbar      *uiprogress.Bar\n}\n\nfunc (pr *progressReader) Read(b []byte) (int, error) {\n\tcount, err := pr.rc.Read(b)\n\tif err == nil {\n\t\tpr.current += count\n\t\tif pr.bar != nil {\n\t\t\tpr.bar.Set(pr.current)\n\t\t}\n\t}\n\n\treturn count, err\n}\n\nfunc (pr *progressReader) Close() error {\n\tif pr.progress != nil {\n\t\tpr.progress.Stop()\n\t}\n\tio.Copy(io.Discard, pr.rc)\n\treturn pr.rc.Close()\n}\n"
  },
  {
    "path": "pkg/app/master/version/version.go",
    "content": "package version\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t//\"github.com/slimtoolkit/slim/pkg/app/master/commands\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst (\n\tversionCheckEndpoint = \"https://versions.api.dockerslim.com/check\"\n\tjsonContentType      = \"application/json\"\n\tversionAuthKey       = \"1JZg1RXvS6mZ0ANgf7p9PoYWQ9q.1JZg3zytWMmBVH50c0RvtBvVpq8\"\n)\n\ntype ovars = app.OutVars\ntype CheckVersionRequest struct {\n\tAppVersion string `json:\"app_version\"`\n}\n\ntype CheckVersionInfo struct {\n\tStatus   string `json:\"status\"`\n\tOutdated bool   `json:\"outdated,omitempty\"`\n\tCurrent  string `json:\"current,omitempty\"`\n}\n\n// PrintCheckVersion shows if the current version is outdated\nfunc PrintCheckVersion(\n\txc *app.ExecutionContext,\n\tprintPrefix string,\n\tinfo *CheckVersionInfo) {\n\tif info != nil && info.Status == \"success\" && info.Outdated {\n\t\tmsg := \"Your version of SlimToolkit is out of date! Use `slim update` to get the latest version.\"\n\t\tif xc == nil {\n\t\t\tfmt.Printf(\"%s info=version status=OUTDATED local=%s current=%s\\n\", printPrefix, v.Tag(), info.Current)\n\t\t\tfmt.Printf(\"%s info=message message='%s'\\n\", printPrefix, msg)\n\t\t} else {\n\t\t\txc.Out.Info(\"version\",\n\t\t\t\tapp.OutVars{\n\t\t\t\t\t\"status\":  \"OUTDATED\",\n\t\t\t\t\t\"local\":   v.Tag(),\n\t\t\t\t\t\"current\": info.Current,\n\t\t\t\t})\n\t\t\txc.Out.Message(msg)\n\t\t}\n\t}\n}\n\n// GetCheckVersionVerdict returns the version status of the locally installed package\nfunc GetCheckVersionVerdict(info *CheckVersionInfo) string {\n\tif info != nil && info.Status == \"success\" {\n\t\tif info.Outdated {\n\t\t\treturn fmt.Sprintf(\"your installed version is OUTDATED (local=%s current=%s)\", v.Tag(), info.Current)\n\t\t} else {\n\t\t\treturn \"you have the latest version\"\n\t\t}\n\t}\n\n\treturn \"version status information is not available\"\n}\n\n// Print shows the master app version information\nfunc Print(xc *app.ExecutionContext, cmdNameParam string, logger *log.Entry, client *docker.Client, checkVersion, inContainer, isDSImage bool) {\n\n\tovApp := ovars{\n\t\t\"cmd\":       cmdNameParam,\n\t\t\"version\":   v.Current(),\n\t\t\"container\": inContainer,\n\t\t\"dsimage\":   isDSImage,\n\t\t\"location\":  fsutil.ExeDir(),\n\t}\n\n\tif checkVersion {\n\t\tvinfo := Check(inContainer, isDSImage)\n\t\tcurrent := \"unknown\"\n\t\tif vinfo != nil && vinfo.Status == \"success\" {\n\t\t\tif vinfo.Outdated {\n\t\t\t\tovApp[\"status\"] = \"OUTDATED\"\n\t\t\t}\n\t\t\tcurrent = vinfo.Current\n\t\t}\n\n\t\tovApp[\"current\"] = current\n\t\tovApp[\"verdict\"] = GetCheckVersionVerdict(vinfo)\n\t}\n\txc.Out.Info(\"app\", ovApp)\n\n\thostInfo := system.GetSystemInfo()\n\tovHost := ovars{\n\t\t\"cmd\":     cmdNameParam,\n\t\t\"osname\":  hostInfo.Distro.DisplayName,\n\t\t\"osbuild\": hostInfo.OsBuild,\n\t\t\"version\": hostInfo.Version,\n\t\t\"release\": hostInfo.Release,\n\t\t\"sysname\": hostInfo.Sysname,\n\t}\n\txc.Out.Info(\"host\", ovHost)\n\n\tif client != nil {\n\t\tinfo, err := client.Info()\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"error getting docker info\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\n\t\tovDocker := ovars{\n\t\t\t\"cmd\":              cmdNameParam,\n\t\t\t\"name\":             info.Name,\n\t\t\t\"kernel.version\":   info.KernelVersion,\n\t\t\t\"operating.system\": info.OperatingSystem,\n\t\t\t\"ostype\":           info.OSType,\n\t\t\t\"server.version\":   info.ServerVersion,\n\t\t\t\"architecture\":     info.Architecture,\n\t\t}\n\t\txc.Out.Info(\"docker\", ovDocker)\n\n\t\tver, err := client.Version()\n\t\tif err != nil {\n\t\t\txc.Out.Error(\"error getting docker client version\", err.Error())\n\t\t\txc.Out.State(\"exited\",\n\t\t\t\tovars{\n\t\t\t\t\t\"exit.code\": -1,\n\t\t\t\t})\n\t\t\txc.Exit(-1)\n\t\t}\n\t\tovDockerClient := ovars{\n\t\t\t\"cmd\":             cmdNameParam,\n\t\t\t\"api.version\":     ver.Get(\"ApiVersion\"),\n\t\t\t\"min.api.version\": ver.Get(\"MinAPIVersion\"),\n\t\t\t\"build.time\":      ver.Get(\"BuildTime\"),\n\t\t\t\"git.commit\":      ver.Get(\"GitCommit\"),\n\t\t}\n\t\txc.Out.Info(\"dclient\", ovDockerClient)\n\t} else {\n\t\txc.Out.Info(\"no.docker.client\", ovars{})\n\t}\n\n}\n\n// Check checks the app version\nfunc Check(inContainer, isDSImage bool) *CheckVersionInfo {\n\tlogger := log.WithFields(log.Fields{\"app\": \"slim\"})\n\n\tclient := http.Client{\n\t\tTimeout: 13 * time.Second,\n\t}\n\n\tdata := CheckVersionRequest{\n\t\tAppVersion: v.Current(),\n\t}\n\n\tvar b bytes.Buffer\n\tencoder := json.NewEncoder(&b)\n\tencoder.SetEscapeHTML(false)\n\tif err := encoder.Encode(&data); err != nil {\n\t\tlogger.Debugf(\"Check - error encoding data => %v\", err)\n\t\treturn nil\n\t}\n\n\treq, err := http.NewRequest(\"POST\", versionCheckEndpoint, &b)\n\tif err != nil {\n\t\tlogger.Debugf(\"Check - error creating version check request => %v\", err)\n\t\treturn nil\n\t}\n\thinfo := system.GetSystemInfo()\n\treq.Header.Set(\"User-Agent\", fmt.Sprintf(\"DockerSlimApp/%v/%v/%v/%v\",\n\t\tv.Current(), inContainer, isDSImage, hinfo.Distro.DisplayName))\n\treq.Header.Set(\"Content-Type\", jsonContentType)\n\treq.Header.Set(\"Authorization\", fmt.Sprintf(\"Bearer %s\", versionAuthKey))\n\n\tresp, err := client.Do(req)\n\tif resp != nil && resp.Body != nil {\n\t\tdefer func() {\n\t\t\tio.Copy(io.Discard, resp.Body)\n\t\t\tresp.Body.Close()\n\t\t}()\n\t}\n\n\tif err != nil {\n\t\tlogger.Debugf(\"Check - error checking version => %v\", err)\n\t\treturn nil\n\t}\n\n\tlogger.Debug(\"version.Check: http status = \", resp.Status)\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil\n\t}\n\n\tvar checkInfo CheckVersionInfo\n\tif err := json.NewDecoder(resp.Body).Decode(&checkInfo); err != nil {\n\t\tlogger.Debugf(\"Check - error decoding response => %v\", err)\n\t\treturn nil\n\t}\n\n\treturn &checkInfo\n}\n\n// CheckAsync checks the app version without blocking\nfunc CheckAsync(doCheckVersion, inContainer, isDSImage bool) <-chan *CheckVersionInfo {\n\tresultCh := make(chan *CheckVersionInfo, 1)\n\n\tif doCheckVersion {\n\t\tgo func() {\n\t\t\tresultCh <- Check(inContainer, isDSImage)\n\t\t}()\n\t} else {\n\t\tclose(resultCh)\n\t}\n\n\treturn resultCh\n}\n\n// CheckAndPrintAsync check the app version and prints the results\nfunc CheckAndPrintAsync(printPrefix string, inContainer, isDSImage bool) {\n\tgo func() {\n\t\tPrintCheckVersion(nil, printPrefix, Check(inContainer, isDSImage))\n\t}()\n}\n"
  },
  {
    "path": "pkg/app/sensor/app.go",
    "content": "//go:build linux\n// +build linux\n\npackage sensor\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/artifact\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/controlled\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/execution\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/standalone\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/standalone/control\"\n\t\"github.com/slimtoolkit/slim/pkg/appbom\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/sysenv\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/version\"\n)\n\nconst (\n\t// Execution modes\n\tsensorModeControlled = \"controlled\"\n\tsensorModeStandalone = \"standalone\"\n\n\t// Flags\n\n\tgetAppBomFlagUsage   = \"get sensor application BOM\"\n\tgetAppBomFlagDefault = false\n\n\tenableDebugFlagUsage   = \"enable debug logging\"\n\tenableDebugFlagDefault = false\n\n\tlogLevelFlagUsage   = \"set the logging level ('debug', 'info', 'warn', 'error', 'fatal', 'panic')\"\n\tlogLevelFlagDefault = \"info\"\n\n\tlogFormatFlagUsage   = \"set the logging format ('text', or 'json')\"\n\tlogFormatFlagDefault = \"text\"\n\n\tlogFileFlagUsage   = \"enable logging redirection to a file (allowing to keep sensor's output separate from the target app's output)\"\n\tlogFileFlagDefault = \"\"\n\n\tsensorModeFlagUsage   = \"set the sensor execution mode ('controlled' when sensor expect the driver 'slim' app to manipulate its lifecycle; or 'standalone' when sensor depends on nothing but the target app\"\n\tsensorModeFlagDefault = sensorModeControlled\n\n\tcommandsFileFlagUsage   = \"provide a JSONL-encoded file with one ore more sensor commands (standalone mode only)\"\n\tcommandsFileFlagDefault = \"/opt/_slim/commands.json\"\n\n\tlifecycleHookCommandFlagUsage   = \"set path to an executable that'll be invoked at various sensor lifecycle events (post-start, pre-shutdown, etc)\"\n\tlifecycleHookCommandFlagDefault = \"\"\n\n\t// Should stopSignal and stopGracePeriod become StartMonitor\n\t// command's fields instead? Hypothetically, in a multi-command\n\t// monitoring run, these two params may have different values.\n\tstopSignalFlagUsage   = \"set the signal to stop the target app (and, eventually, the sensor)\"\n\tstopSignalFlagDefault = \"TERM\"\n\n\tstopGracePeriodFlagUsage   = \"set the time to wait for the graceful termination of the target app (before sensor SIGKILL's it)\"\n\tstopGracePeriodFlagDefault = 5 * time.Second\n\n\tartifactsDirFlagUsage   = \"output director for all sensor artifacts\"\n\tartifactsDirFlagDefault = app.DefaultArtifactsDirPath\n\n\tenableMondelFlagUsage   = \"enable monitor data event logging\"\n\tenableMondelFlagDefault = false\n)\n\nvar (\n\tgetAppBom            *bool          = flag.Bool(\"appbom\", getAppBomFlagDefault, getAppBomFlagUsage)\n\tenableDebug          *bool          = flag.Bool(\"debug\", enableDebugFlagDefault, enableDebugFlagUsage)\n\tlogLevel             *string        = flag.String(\"log-level\", logLevelFlagDefault, logLevelFlagUsage)\n\tlogFormat            *string        = flag.String(\"log-format\", logFormatFlagDefault, logFormatFlagUsage)\n\tlogFile              *string        = flag.String(\"log-file\", logFileFlagDefault, logFileFlagUsage)\n\tsensorMode           *string        = flag.String(\"mode\", sensorModeFlagDefault, sensorModeFlagUsage)\n\tcommandsFile         *string        = flag.String(\"command-file\", commandsFileFlagDefault, commandsFileFlagUsage)\n\tartifactsDir         *string        = flag.String(\"artifacts-dir\", artifactsDirFlagDefault, artifactsDirFlagUsage)\n\tlifecycleHookCommand *string        = flag.String(\"lifecycle-hook\", lifecycleHookCommandFlagDefault, lifecycleHookCommandFlagUsage)\n\tstopSignal           *string        = flag.String(\"stop-signal\", stopSignalFlagDefault, stopSignalFlagUsage)\n\tstopGracePeriod      *time.Duration = flag.Duration(\"stop-grace-period\", stopGracePeriodFlagDefault, stopGracePeriodFlagUsage)\n\tenableMondel         *bool          = flag.Bool(\"mondel\", enableMondelFlagDefault, enableMondelFlagUsage)\n\n\terrUnknownMode = errors.New(\"unknown sensor mode\")\n)\n\nfunc eventsFilePath() string {\n\treturn filepath.Join(*artifactsDir, \"events.json\")\n}\n\nfunc init() {\n\tflag.BoolVar(getAppBom, \"b\", getAppBomFlagDefault, getAppBomFlagUsage)\n\tflag.BoolVar(enableDebug, \"d\", enableDebugFlagDefault, enableDebugFlagUsage)\n\tflag.StringVar(logLevel, \"l\", logLevelFlagDefault, logLevelFlagUsage)\n\tflag.StringVar(logFormat, \"f\", logFormatFlagDefault, logFormatFlagUsage)\n\tflag.StringVar(logFile, \"o\", logFileFlagDefault, logFileFlagUsage)\n\tflag.StringVar(sensorMode, \"m\", sensorModeFlagDefault, sensorModeFlagUsage)\n\tflag.StringVar(commandsFile, \"c\", commandsFileFlagDefault, commandsFileFlagUsage)\n\tflag.StringVar(artifactsDir, \"e\", artifactsDirFlagDefault, artifactsDirFlagUsage)\n\tflag.StringVar(lifecycleHookCommand, \"a\", lifecycleHookCommandFlagDefault, lifecycleHookCommandFlagUsage)\n\tflag.StringVar(stopSignal, \"s\", stopSignalFlagDefault, stopSignalFlagUsage)\n\tflag.DurationVar(stopGracePeriod, \"w\", stopGracePeriodFlagDefault, stopGracePeriodFlagUsage)\n\tflag.BoolVar(enableMondel, \"n\", enableMondelFlagDefault, enableMondelFlagUsage)\n}\n\n// Run starts the sensor app\nfunc Run() {\n\tflag.Parse()\n\n\tif *getAppBom {\n\t\tdumpAppBom()\n\t\treturn\n\t}\n\n\terrutil.FailOn(configureLogger(*enableDebug, *logLevel, *logFormat, *logFile))\n\tctx := context.Background()\n\tif len(os.Args) > 1 && os.Args[1] == \"control\" {\n\t\tif err := runControlCommand(ctx); err != nil {\n\t\t\tfmt.Fprintln(os.Stderr, \"Control command failed: \"+err.Error())\n\t\t\tos.Exit(1)\n\t\t}\n\t\treturn\n\t}\n\n\tactiveCaps, maxCaps, err := sysenv.Capabilities(0)\n\terrutil.WarnOn(err)\n\n\tsr := &report.SensorReport{\n\t\tVersion: version.Current(),\n\t\tArgs:    os.Args,\n\t}\n\n\tlog.Infof(\"sensor: ver=%v\", sr.Version)\n\tlog.Debugf(\"sensor: args => %#v\", sr.Args)\n\n\tlog.Tracef(\"sensor: uid=%v euid=%v\", os.Getuid(), os.Geteuid())\n\tlog.Tracef(\"sensor: privileged => %v\", sysenv.IsPrivileged())\n\tlog.Tracef(\"sensor: active capabilities => %#v\", activeCaps)\n\tlog.Tracef(\"sensor: max capabilities => %#v\", maxCaps)\n\tlog.Tracef(\"sensor: sysinfo => %#v\", system.GetSystemInfo())\n\tlog.Tracef(\"sensor: kernel flags => %#v\", system.DefaultKernelFeatures.Raw)\n\n\tvar artifactsExtra []string\n\tif len(*commandsFile) > 0 {\n\t\tartifactsExtra = append(artifactsExtra, *commandsFile)\n\t}\n\tif len(*logFile) > 0 {\n\t\tartifactsExtra = append(artifactsExtra, *logFile)\n\t}\n\tartifactor := artifact.NewProcessor(sr, *artifactsDir, artifactsExtra)\n\n\texe, err := newExecution(\n\t\tctx,\n\t\t*sensorMode,\n\t\t*commandsFile,\n\t\teventsFilePath(),\n\t\t*lifecycleHookCommand,\n\t)\n\tif err != nil {\n\t\terrutil.WarnOn(artifactor.Archive())\n\t\terrutil.FailOn(err) // calls os.Exit(1)\n\t}\n\n\tmondelFile := filepath.Join(*artifactsDir, report.DefaultMonDelFileName)\n\tdel := mondel.NewPublisher(ctx, *enableMondel, mondelFile)\n\n\tsen, err := newSensor(ctx, exe, *sensorMode, artifactor, del, *artifactsDir)\n\tif err != nil {\n\t\texe.Close()\n\t\terrutil.WarnOn(artifactor.Archive())\n\t\terrutil.FailOn(err) // calls os.Exit(1)\n\t}\n\n\tif err := sen.Run(); err != nil {\n\t\tlog.WithError(err).Error(\"sensor: run finished with error\")\n\t\tif errors.Is(err, monitor.ErrInsufficientPermissions) {\n\t\t\tlog.Info(\"sensor: Instrumented containers require root and ALL capabilities enabled. Example: `docker run --user root --cap-add ALL app:v1-instrumented`\")\n\t\t}\n\t} else {\n\t\tlog.Info(\"sensor: run finished succesfully\")\n\t}\n\n\texe.Close()\n\n\tlog.Info(\"sensor: exiting...\")\n}\n\nfunc newExecution(\n\tctx context.Context,\n\tmode string,\n\tcommandsFile string,\n\teventsFile string,\n\tlifecycleHookCommand string,\n) (execution.Interface, error) {\n\tswitch mode {\n\tcase sensorModeControlled:\n\t\treturn execution.NewControlled(ctx, lifecycleHookCommand)\n\tcase sensorModeStandalone:\n\t\treturn execution.NewStandalone(\n\t\t\tctx,\n\t\t\tcommandsFile,\n\t\t\teventsFile,\n\t\t\tlifecycleHookCommand,\n\t\t)\n\t}\n\n\treturn nil, errUnknownMode\n}\n\ntype sensor interface {\n\tRun() error\n}\n\nfunc newSensor(\n\tctx context.Context,\n\texe execution.Interface,\n\tmode string,\n\tartifactor artifact.Processor,\n\tdel mondel.Publisher,\n\tartifactsDir string,\n) (sensor, error) {\n\tworkDir, err := os.Getwd()\n\terrutil.WarnOn(err)\n\tlog.Debugf(\"sensor: cwd => %s\", workDir)\n\n\tmountPoint := \"/\"\n\tlog.Debugf(\"sensor: mount point => %s\", mountPoint)\n\n\tswitch mode {\n\tcase sensorModeControlled:\n\t\tctx, cancel := context.WithCancel(ctx)\n\n\t\t// To preserve the backward compatibility, don't forward\n\t\t// signals to the target app in the default (controlled) mode.\n\t\tstartSystemSignalsMonitor(func() {\n\t\t\tcancel()\n\t\t\ttime.Sleep(2 * time.Second)\n\t\t})\n\n\t\treturn controlled.NewSensor(\n\t\t\tctx,\n\t\t\texe,\n\t\t\tmonitor.NewCompositeMonitor,\n\t\t\tdel,\n\t\t\tartifactor,\n\t\t\tworkDir,\n\t\t\tmountPoint,\n\t\t), nil\n\tcase sensorModeStandalone:\n\t\treturn standalone.NewSensor(\n\t\t\tctx,\n\t\t\texe,\n\t\t\tmonitor.NewCompositeMonitor,\n\t\t\tdel,\n\t\t\tartifactor,\n\t\t\tworkDir,\n\t\t\tmountPoint,\n\t\t\tsignalFromString(*stopSignal),\n\t\t\t*stopGracePeriod,\n\t\t), nil\n\t}\n\n\texe.PubEvent(event.StartMonitorFailed,\n\t\t&event.StartMonitorFailedData{\n\t\t\tComponent: event.ComSensorConstructor,\n\t\t\tState:     event.StateSensorTypeCreating,\n\t\t\tContext: map[string]string{\n\t\t\t\tevent.CtxSensorType: mode,\n\t\t\t},\n\t\t\tErrors: []string{errUnknownMode.Error()},\n\t\t})\n\treturn nil, errUnknownMode\n}\n\nfunc dumpAppBom() {\n\tinfo := appbom.Get()\n\tif info == nil {\n\t\treturn\n\t}\n\n\tvar out bytes.Buffer\n\tencoder := json.NewEncoder(&out)\n\tencoder.SetEscapeHTML(false)\n\tencoder.SetIndent(\" \", \" \")\n\t_ = encoder.Encode(info)\n\tfmt.Printf(\"%s\\n\", out.String())\n}\n\n// sensor control <stop-target-app|wait-for-event|change-log-level|...>\nfunc runControlCommand(ctx context.Context) error {\n\tif len(os.Args) < 3 {\n\t\treturn errors.New(\"missing command\")\n\t}\n\n\tcmd := control.Command(os.Args[2])\n\n\tswitch cmd {\n\tcase control.StopTargetAppCommand:\n\t\tif err := control.ExecuteStopTargetAppCommand(ctx, *commandsFile); err != nil {\n\t\t\treturn fmt.Errorf(\"error stopping target app: %w\", err)\n\t\t}\n\n\tcase control.WaitForEventCommand:\n\t\tif len(os.Args) < 4 {\n\t\t\treturn errors.New(\"missing event name\")\n\t\t}\n\t\tif err := control.ExecuteWaitEvenCommand(ctx, eventsFilePath(), event.Type(os.Args[3])); err != nil {\n\t\t\treturn fmt.Errorf(\"error waiting for sensor event: %w\", err)\n\t\t}\n\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown command: %s\", cmd)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/app_test.go",
    "content": "//go:build e2e\n// +build e2e\n\npackage sensor_test\n\nimport (\n\t\"context\"\n\t\"strings\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/uuid\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/standalone/control\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\ttestsensor \"github.com/slimtoolkit/slim/pkg/test/e2e/sensor\"\n\ttestutil \"github.com/slimtoolkit/slim/pkg/test/util\"\n)\n\nconst (\n\timageSimpleService = \"docker.io/library/nginx:1.21\"\n\timageSimpleCLI     = \"docker.io/library/alpine:3.16.2\"\n)\n\nvar (\n\tsensorFullLifecycleSequence = []string{\n\t\t\"sensor: ver=\",\n\t\t\"sensor: creating monitors...\",\n\t\t\"sensor: starting monitors...\",\n\t\t\"sensor: run finished succesfully\",\n\t}\n\n\tsensorLifecycleHookSequence = []string{\n\t\t\"sensor-post-start\",\n\t\t\"monitor-pre-start\",\n\t\t\"monitor-post-shutdown\",\n\t\t\"sensor-pre-shutdown\",\n\t}\n)\n\nfunc init() {\n\tlog.SetLevel(log.DebugLevel)\n}\n\nfunc TestSimpleSensorRun_Controlled_CLI(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleCLI)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartControlledOrFail(t, ctx)\n\n\tsensor.SendStartCommandOrFail(t, ctx,\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithSaneDefaults(),\n\t\t\ttestsensor.WithAppNameArgs(\"cat\", \"/etc/alpine-release\"),\n\t\t),\n\t)\n\tsensor.ExpectEvent(t, event.StartMonitorDone)\n\n\ttime.Sleep(1 * time.Second)\n\n\tsensor.SendStopCommandOrFail(t, ctx)\n\tsensor.ExpectEvent(t, event.StopMonitorDone)\n\n\tsensor.ShutdownOrFail(t, ctx)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"3.16.2\")\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertReportIncludesFiles(t, \"/bin/cat\", \"/bin/busybox\", \"/etc/alpine-release\")\n\tsensor.AssertReportNotIncludesFiles(t, \"/bin/echo2\", \"/etc/resolve.conf\")\n}\n\nfunc TestSimpleSensorRun_Controlled_Service(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleService)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartControlledOrFail(t, ctx)\n\n\tsensor.SendStartCommandOrFail(t, ctx)\n\tsensor.ExpectEvent(t, event.StartMonitorDone)\n\n\ttime.Sleep(5 * time.Second)\n\n\tsensor.SendStopCommandOrFail(t, ctx)\n\tsensor.ExpectEvent(t, event.StopMonitorDone)\n\n\tsensor.ShutdownOrFail(t, ctx)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx,\n\t\t\"nginx/1.21\",\n\t\t\"start worker processes\",\n\t)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertReportIncludesFiles(t,\n\t\t\"/bin/sh\",\n\t\t\"/etc/nginx/nginx.conf\",\n\t\t\"/etc/nginx/conf.d/default.conf\",\n\t\t\"/var/cache/nginx\",\n\t\t\"/var/run\",\n\t\t// Here is an interesting one - in the controlled (default) mode, sensor doesn't\n\t\t// await the target process termination. Hence, no cleanup on the nginx side\n\t\t// happens, and the pid file remains in the report.\n\t\t\"/run/nginx.pid\",\n\t)\n\tsensor.AssertReportNotIncludesFiles(t,\n\t\t\"/bin/bash\",\n\t\t\"/bin/cat\",\n\t\t\"/etc/apt/sources.list\",\n\t)\n}\n\nfunc TestSimpleSensorRun_Standalone_CLI(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleCLI)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, []string{\"cat\", \"/etc/alpine-release\"})\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"3.16.2\")\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertReportIncludesFiles(t, \"/bin/cat\", \"/bin/busybox\", \"/etc/alpine-release\")\n\tsensor.AssertReportNotIncludesFiles(t, \"/bin/echo2\", \"/etc/resolve.conf\")\n\n\tsensor.AssertSensorEventsFileContains(t, ctx,\n\t\tevent.StartMonitorDone,\n\t\tevent.StopMonitorDone,\n\t\tevent.ShutdownSensorDone,\n\t)\n}\n\nfunc TestSimpleSensorRun_Standalone_Service(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleService)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, nil)\n\tgo testutil.Delayed(ctx, 5*time.Second, func() {\n\t\tsensor.SignalOrFail(t, ctx, syscall.SIGTERM)\n\t})\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx,\n\t\t\"nginx/1.21\",\n\t\t\"start worker processes\",\n\t\t\"(SIGTERM) received from 1, exiting\",\n\t)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertReportIncludesFiles(t,\n\t\t\"/bin/sh\",\n\t\t\"/etc/nginx/nginx.conf\",\n\t\t\"/etc/nginx/conf.d/default.conf\",\n\t\t\"/var/cache/nginx\",\n\t\t\"/var/run\",\n\t)\n\tsensor.AssertReportNotIncludesFiles(t,\n\t\t\"/bin/bash\",\n\t\t\"/bin/cat\",\n\t\t\"/etc/apt/sources.list\",\n\t\t// Here is an interesting one - in the standalone mode sensor\n\t\t// tries gracefully terminate the target process by forwarding\n\t\t// it the StopSignal from it receives from the runtime. Nginx\n\t\t// exits and cleans up its pid file.\n\t\t\"/run/nginx.pid\",\n\t)\n}\n\nfunc TestSensorLogsGoToFile(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleCLI,\n\t\ttestsensor.WithSensorLogsToFile(),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, []string{\"echo\", \"123456879\"})\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertTargetAppLogsEqualTo(t, ctx, \"123456879\")\n\n\t// When WithSensorLogsToFile() is used, sensor's logs become part of artifacts.\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n}\n\nfunc TestAppStdoutToFile(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleCLI,\n\t\ttestsensor.WithSensorLogsToFile(),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(\n\t\tt, ctx,\n\t\t[]string{\"sh\", \"-c\", \"echo 123456789; echo 987654321 >&2\"},\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithSaneDefaults(),\n\t\t\ttestsensor.WithAppStdoutToFile(),\n\t\t),\n\t)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"123456789\")\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"987654321\")\n\tsensor.AssertTargetAppStdoutFileEqualsTo(t, ctx, \"123456789\")\n}\n\nfunc TestAppStderrToFile(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleCLI,\n\t\ttestsensor.WithSensorLogsToFile(),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(\n\t\tt, ctx,\n\t\t[]string{\"sh\", \"-c\", \"echo 123456789; echo 987654321 >&2\"},\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithSaneDefaults(),\n\t\t\ttestsensor.WithAppStderrToFile(),\n\t\t),\n\t)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"123456789\")\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"987654321\")\n\tsensor.AssertTargetAppStderrFileEqualsTo(t, ctx, \"987654321\")\n}\n\nfunc TestAccessedButThenDeletedFilesShouldBeReported(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tt.Skip(\"Fix for the sensor's logic is required!\")\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleCLI)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, []string{\n\t\t\"sh\", \"-c\", \"cat /etc/alpine-release; rm /etc/alpine-release\",\n\t})\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"3.16.2\")\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertReportIncludesFiles(t, \"/etc/alpine-release\")\n}\n\nfunc TestPreservedPathsWorkWithFilesDeletedDuringProbing(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tt.Skip(\"Fix for the sensor's logic is required!\")\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleCLI)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx,\n\t\t[]string{\"sh\", \"-c\", \"cat /etc/alpine-release; rm /etc/alpine-release\"},\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithPreserves(\"/etc/alpine-release\"),\n\t\t),\n\t)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"3.16.2\")\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertReportIncludesFiles(t, \"/etc/alpine-release\")\n}\n\nfunc newTestRun(t *testing.T) string {\n\trunID := t.Name() + \"-\" + strings.SplitN(uuid.New().String(), \"-\", 2)[0]\n\tlog.Debugf(\"New test run %s\", runID)\n\treturn runID\n}\n\nfunc TestLifecycleHook_Controlled_CLI(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt,\n\t\tctx,\n\t\tt.TempDir(),\n\t\trunID,\n\t\timageSimpleCLI,\n\t\ttestsensor.WithSensorLifecycleHook(\"echo\"),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartControlledOrFail(t, ctx)\n\n\tsensor.SendStartCommandOrFail(t, ctx,\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithSaneDefaults(),\n\t\t\ttestsensor.WithAppNameArgs(\"cat\", \"/etc/alpine-release\"),\n\t\t),\n\t)\n\n\ttime.Sleep(1 * time.Second)\n\n\tsensor.SendStopCommandOrFail(t, ctx)\n\n\tsensor.ShutdownOrFail(t, ctx)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"3.16.2\")\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertSensorLogsContain(t, ctx, sensorLifecycleHookSequence...)\n}\n\nfunc TestLifecycleHook_Standalone_CLI(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt,\n\t\tctx,\n\t\tt.TempDir(),\n\t\trunID,\n\t\timageSimpleCLI,\n\t\ttestsensor.WithSensorLifecycleHook(\"echo\"),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, []string{\"cat\", \"/etc/alpine-release\"})\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"3.16.2\")\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertSensorLogsContain(t, ctx, sensorLifecycleHookSequence...)\n}\n\nfunc TestRunTargetAsUser(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleCLI)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(\n\t\tt, ctx, []string{\"whoami\"},\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithAppUser(\"daemon\"),\n\t\t),\n\t)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx, \"daemon\")\n}\n\nfunc TestTargetAppEnvVars(t *testing.T) {\n\tcases := []struct {\n\t\timage string\n\t\tuser  string\n\t\thome  string\n\t}{\n\t\t// nixery.dev/shell lacks the /etc/passwd file: all UIDs should end up with HOME=/\n\t\t{image: \"nixery.dev/shell\", user: \"0\", home: \"/\"},\n\t\t{image: \"nixery.dev/shell\", user: \"65534\", home: \"/\"},\n\n\t\t// Alpine\n\t\t{image: imageSimpleCLI, home: \"/root\"},\n\t\t{image: imageSimpleCLI, user: \"root\", home: \"/root\"},\n\t\t{image: imageSimpleCLI, user: \"0\", home: \"/root\"},\n\t\t{image: imageSimpleCLI, user: \"nobody\", home: \"/\"},\n\t\t{image: imageSimpleCLI, user: \"65534\", home: \"/\"}, // nobody's UID\n\t\t{image: imageSimpleCLI, user: \"bin\", home: \"/bin\"},\n\t\t{image: imageSimpleCLI, user: \"1\", home: \"/bin\"}, // bin's UID\n\t\t{image: imageSimpleCLI, user: \"daemon\", home: \"/sbin\"},\n\t\t{image: imageSimpleCLI, user: \"2\", home: \"/sbin\"}, // daemon's UID\n\t\t{image: imageSimpleCLI, user: \"nosuchuser\", home: \"/\"},\n\t\t{image: imageSimpleCLI, user: \"14567\", home: \"/\"}, // hopefully, no such UID\n\n\t\t// Nginx\n\t\t{image: imageSimpleService, user: \"nginx\", home: \"/nonexistent\"},\n\t\t{image: imageSimpleService, user: \"101\", home: \"/nonexistent\"}, // nginx's UID\n\t\t{image: imageSimpleService, user: \"nobody\", home: \"/\"},\n\t\t{image: imageSimpleService, user: \"65534\", home: \"/\"}, // nobody's UID\n\t\t{image: imageSimpleService, user: \"daemon\", home: \"/usr/sbin\"},\n\t\t{image: imageSimpleService, user: \"1\", home: \"/usr/sbin\"}, // daemon's UID\n\t\t{image: imageSimpleService, user: \"nosuchuser\", home: \"/\"},\n\t\t{image: imageSimpleService, user: \"14567\", home: \"/\"}, // hopefully, no such UID\n\t}\n\n\tfor _, tcase := range cases {\n\t\tfunc() {\n\t\t\trunID := newTestRun(t)\n\t\t\tctx := context.Background()\n\n\t\t\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, tcase.image)\n\t\t\tdefer sensor.Cleanup(t, ctx)\n\n\t\t\tvar startOpts []testsensor.StartMonitorOpt\n\t\t\tif len(tcase.user) > 0 {\n\t\t\t\tstartOpts = append(startOpts, testsensor.WithAppUser(tcase.user))\n\t\t\t}\n\t\t\tsensor.StartStandaloneOrFail(\n\t\t\t\tt, ctx, []string{\"env\"},\n\t\t\t\ttestsensor.NewMonitorStartCommand(startOpts...),\n\t\t\t)\n\t\t\tsensor.WaitOrFail(t, ctx)\n\n\t\t\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\t\t\tsensor.AssertTargetAppLogsContain(t, ctx, \"HOME=\"+tcase.home)\n\t\t}()\n\t}\n}\n\nfunc TestArchiveArtifacts_HappyPath(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleCLI,\n\t\ttestsensor.WithSensorLogsToFile(),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(\n\t\tt, ctx,\n\t\t[]string{\"cat\", \"/etc/alpine-release\"},\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithSaneDefaults(),\n\t\t\ttestsensor.WithAppStdoutToFile(),\n\t\t\ttestsensor.WithAppStderrToFile(),\n\t\t),\n\t)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\n\tsensor.AssertArtifactsArchiveContains(t, ctx,\n\t\treport.DefaultContainerReportFileName,\n\t\ttestsensor.EventsFileName,\n\t\ttestsensor.CommandsFileName,\n\t\ttestsensor.SensorLogFileName,\n\t\ttestsensor.AppStdoutFileName,\n\t\ttestsensor.AppStderrFileName,\n\t)\n}\n\nfunc TestArchiveArtifacts_CustomLocation(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleCLI,\n\t\ttestsensor.WithSensorLogsToFile(),\n\t\ttestsensor.WithSensorArtifactsDir(\"/opt/not-dockerslim-at-all/files\"),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(\n\t\tt, ctx,\n\t\t[]string{\"cat\", \"/etc/alpine-release\"},\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithSaneDefaults(),\n\t\t\ttestsensor.WithAppStdoutToFile(),\n\t\t\ttestsensor.WithAppStderrToFile(),\n\t\t),\n\t)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\n\tsensor.AssertArtifactsArchiveContains(t, ctx,\n\t\treport.DefaultContainerReportFileName,\n\t\ttestsensor.EventsFileName,\n\t\ttestsensor.CommandsFileName,\n\t\ttestsensor.SensorLogFileName,\n\t\ttestsensor.AppStdoutFileName,\n\t\ttestsensor.AppStderrFileName,\n\t)\n}\n\nfunc TestArchiveArtifacts_SensorFailure_NoCaps(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleCLI,\n\t\ttestsensor.WithSensorLogsToFile(),\n\t\ttestsensor.WithSensorCapabilities(), // Cancels out the default --cap-add=ALL.\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(\n\t\tt, ctx,\n\t\t[]string{\"cat\", \"/etc/alpine-release\"},\n\t\ttestsensor.NewMonitorStartCommand(\n\t\t\ttestsensor.WithSaneDefaults(),\n\t\t\ttestsensor.WithAppStdoutToFile(),\n\t\t\ttestsensor.WithAppStderrToFile(),\n\t\t\ttestsensor.WithAppStderrToFile(),\n\t\t),\n\t)\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, []string{\n\t\t\"sensor: creating monitors...\",\n\t\t\"sensor: starting monitors...\",\n\t\t\"sensor: composite monitor - FAN failed to start running\", // <-- failure!\n\t\t\"sensor: run finished with error\",\n\t}...)\n\n\tsensor.AssertArtifactsArchiveContains(t, ctx,\n\t\ttestsensor.EventsFileName,\n\t\ttestsensor.CommandsFileName,\n\t\ttestsensor.SensorLogFileName,\n\t)\n}\n\nfunc TestArchiveArtifacts_SensorFailure_NoRoot(t *testing.T) {\n\t// It's a fairly common failure scenario.\n\tt.Skip(\"Implement me!\")\n}\n\nfunc TestStopSignal_ForceKill(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\twrongStopSignal := syscall.SIGUSR1 // This signal isn't going to make Nginx exit.\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleService,\n\t\ttestsensor.WithStopSignal(wrongStopSignal), // Emulate misconfiguration.\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, nil)\n\tgo testutil.Delayed(ctx, 5*time.Second, func() {\n\t\t// However, the sensor will terminate the target app\n\t\t// anyway, when the grace period after receiving the\n\t\t// stop signal is over.\n\t\tsensor.SignalOrFail(t, ctx, wrongStopSignal)\n\t})\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\tsensor.AssertTargetAppLogsContain(t, ctx,\n\t\t\"nginx/1.21\",\n\t\t\"start worker processes\",\n\t\t\"sensor: stop signal was sent to target app - starting grace period\",\n\t\t\"sensor: grace timeout expired - SIGKILL goes to target app\",\n\t)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\tsensor.AssertReportIncludesFiles(t,\n\t\t\"/etc/nginx/nginx.conf\",\n\t\t\"/etc/nginx/conf.d/default.conf\",\n\t\t\"/var/cache/nginx\",\n\t\t\"/var/run\",\n\t\t// Because the target app was terminated by SIGKILL,\n\t\t// the pid file is not cleaned up.\n\t\t\"/run/nginx.pid\",\n\t)\n\tsensor.AssertReportNotIncludesFiles(t,\n\t\t\"/bin/bash\",\n\t\t\"/bin/cat\",\n\t\t\"/etc/apt/sources.list\",\n\t)\n}\n\nfunc TestControlCommands_StopTargetApp(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(t, ctx, t.TempDir(), runID, imageSimpleService)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, nil)\n\n\tgo testutil.Delayed(ctx, 5*time.Second, func() {\n\t\tsensor.ExecuteControlCommandOrFail(t, ctx, control.StopTargetAppCommand)\n\t\tsensor.WaitForEventOrFail(t, ctx, event.StopMonitorDone)\n\t\tsensor.WaitForEventOrFail(t, ctx, event.ShutdownSensorDone)\n\n\t\t// In the real world, there might be some (long) time between\n\t\t// the stop command and the target app signalling - maybe\n\t\t// we need to simulate that here?\n\t\tsensor.SignalOrFail(t, ctx, syscall.SIGQUIT)\n\t})\n\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n}\n\nfunc TestEnableMondel(t *testing.T) {\n\trunID := newTestRun(t)\n\tctx := context.Background()\n\n\tsensor := testsensor.NewSensorOrFail(\n\t\tt, ctx, t.TempDir(), runID, imageSimpleService,\n\t\ttestsensor.WithEnableMondel(),\n\t)\n\tdefer sensor.Cleanup(t, ctx)\n\n\tsensor.StartStandaloneOrFail(t, ctx, nil)\n\tgo testutil.Delayed(ctx, 5*time.Second, func() {\n\t\tsensor.SignalOrFail(t, ctx, syscall.SIGTERM)\n\t})\n\tsensor.WaitOrFail(t, ctx)\n\n\tsensor.AssertSensorLogsContain(t, ctx, sensorFullLifecycleSequence...)\n\n\tsensor.DownloadArtifactsOrFail(t, ctx)\n\n\tsensor.AssertMondelIncludesFiles(t,\n\t\t\"/etc/nginx/nginx.conf\",\n\t\t\"/etc/nginx/conf.d/default.conf\",\n\n\t\t// TODO: investigate why these files are not included in the mondel (but are in the creport).\n\t\t// \"/bin/sh\",\n\t\t// \"/var/cache/nginx\",\n\t\t// \"/var/run\",\n\t)\n\tsensor.AssertMondelNotIncludesFiles(t,\n\t\t\"/bin/bash\",\n\t\t\"/bin/cat\",\n\t\t\"/etc/apt/sources.list\",\n\n\t\t// TODO: investigate why this file is included in the mondel (but not in the creport).\n\t\t// \"/run/nginx.pid\",\n\t)\n\n\t// Uncomment when the mondel and creport file sets are synced.\n\t// sensor.AssertReportAndMondelFileListsMatch(t)\n}\n"
  },
  {
    "path": "pkg/app/sensor/artifact/artifact.go",
    "content": "//go:build linux\n// +build linux\n\npackage artifact\n\nimport (\n\t\"bytes\"\n\t\"crypto/sha1\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/armon/go-radix\"\n\t\"github.com/bmatcuk/doublestar/v3\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/detector/binfile\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/inspector/sodeps\"\n\t\"github.com/slimtoolkit/slim/pkg/artifact\"\n\t\"github.com/slimtoolkit/slim/pkg/certdiscover\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/sysidentity\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nconst (\n\tpidFileSuffix    = \".pid\"\n\tvarRunDir        = \"/var/run/\"\n\tfileTypeCmdName  = \"file\"\n\tfilesArchiveName = \"files.tar\"\n\trunArchiveName   = \"run.tar\"\n\tpreservedDirName = \"preserved\"\n)\n\n//TODO: extract these app, framework and language specific login into separate packages\n\n// Nginx related consts\nconst (\n\tngxBinName    = \"/nginx\"\n\tngxSubDir     = \"/nginx/\"\n\tngxCommonTemp = \"/var/lib/nginx\"\n\tngxLogTemp    = \"/var/log/nginx\"\n\tngxCacheTemp  = \"/var/cache/nginx\"\n)\n\n// Ruby related consts\nconst (\n\trbBinName           = \"/ruby\"\n\trbIrbBinName        = \"/irb\"\n\trbGemBinName        = \"/gem\"\n\trbBundleBinName     = \"/bundle\"\n\trbRbenvBinName      = \"/rbenv\"\n\trbSrcFileExt        = \".rb\"\n\trbGemSpecExt        = \".gemspec\"\n\trbGemsSubDir        = \"/gems/\"\n\trbGemfile           = \"Gemfile\"\n\trbGemfileLockFile   = \"Gemfile.lock\"\n\trbDefaultSpecSubDir = \"/specifications/default/\"\n\trbSpecSubDir        = \"/specifications/\"\n\trgExtSibDir         = \"extensions\"\n\trbGemBuildFlag      = \"gem.build_complete\"\n)\n\n// Python related consts\nconst (\n\tpyBinName            = \"/python\"\n\tpy2BinName           = \"/python2\"\n\tpy3BinName           = \"/python3\"\n\tpyPipBinName         = \"/pip\"\n\tpyPip2BinName        = \"/pip2\"\n\tpyPip3BinName        = \"/pip3\"\n\tpyPoetryBinName      = \"/poetry\"\n\tpyCondaBinName       = \"/conda\"\n\tpyPipEnvBinName      = \"/pipenv\"\n\tpyEasyInstallBinName = \"/easy_install\"\n\tpyPipxBinName        = \"/pipx\"\n\tpyVirtEnvBinName     = \"/virtualenv\"\n\tpySrcFileExt         = \".py\"\n\tpycExt               = \".pyc\"\n\tpyoExt               = \".pyo\"\n\tpycacheDir           = \"/__pycache__/\"\n\tpycache              = \"__pycache__\"\n\tpyReqsFile           = \"requirements.txt\"\n\tpyPoetryProjectFile  = \"pyproject.toml\"\n\tpyPipEnvProjectFile  = \"Pipfile\"\n\tpyPipEnvLockFile     = \"Pipfile.lock\"\n\tpyDistPkgDir         = \"/dist-packages/\"\n\tpySitePkgDir         = \"/site-packages/\"\n)\n\n// Node.js related consts\nconst (\n\tnodeBinName           = \"/node\"\n\tnodeNpmBinName        = \"/npm\"\n\tnodeYarnBinName       = \"/yarn\"\n\tnodePnpmBinName       = \"/pnpm\"\n\tnodeRushBinName       = \"/rush\"\n\tnodeLernaBinName      = \"/lerna\"\n\tnodeSrcFileExt        = \".js\"\n\tnodePackageFile       = \"package.json\"\n\tnodePackageLockFile   = \"package-lock.json\"\n\tnodeNpmShrinkwrapFile = \"npm-shrinkwrap.json\"\n\tnodeYarnLockFile      = \"yarn.lock\"\n\tnodePackageDirPath    = \"/node_modules/\"\n\tnodePackageDirName    = \"node_modules\"\n\tnodeNPMNodeGypPackage = \"/npm/node_modules/node-gyp/package.json\"\n\tnodeNPMNodeGypFile    = \"bin/node-gyp.js\"\n)\n\n// nuxt.js related consts\nconst (\n\tnuxtConfigFile      = \"nuxt.config.js\"\n\tnuxtBuildDirKey     = \"buildDir\"\n\tnuxtSrcDirKey       = \"srcDir\" //defaults to rootDir\n\tnuxtDistDirKey      = \"dir\"    //in 'generate'\n\tnuxtDefaultDistDir  = \"dist\"\n\tnuxtDefaultBuildDir = \".nuxt\"\n\tnuxtStaticDir       = \"static\"\n)\n\n// next.js related consts\nconst (\n\tnextConfigFile                = \"next.config.js\"\n\tnextConfigFileAlt             = \"next.config.mjs\"\n\tnextDefaultBuildDir           = \".next\"\n\tnextDefaultBuildStandaloneDir = \".next/standalone\"\n\tnextDefaultBuildStaticDir     = \".next/static\"\n\tnextStaticDir                 = \"public\"\n\tnextDefaultStaticSpaDir       = \"out\"\n\tnextDefaultStaticSpaDirPath   = \"/out/_next/\"\n)\n\ntype NodePackageConfigSimple struct {\n\tName         string            `json:\"name\"`\n\tVersion      string            `json:\"version\"`\n\tDependencies map[string]string `json:\"dependencies\"`\n}\n\ntype appStackInfo struct {\n\tlanguage    string //will be reusing language consts from certdiscover (todo: replace it later)\n\tcodeFiles   uint\n\tpackageDirs map[string]struct{}\n}\n\n// later: each language pack will register its metadata files\nvar appMetadataFiles = map[string]struct{}{\n\t//python:\n\tpyReqsFile:          {},\n\tpyPoetryProjectFile: {},\n\tpyPipEnvProjectFile: {},\n\tpyPipEnvLockFile:    {},\n\t//ruby:\n\trbGemfile:         {},\n\trbGemfileLockFile: {},\n\t//node:\n\tnodePackageFile:       {},\n\tnodePackageLockFile:   {},\n\tnodeNpmShrinkwrapFile: {},\n\tnodeYarnLockFile:      {},\n\tnuxtConfigFile:        {},\n\tnextConfigFile:        {},\n\tnextConfigFileAlt:     {},\n}\n\nfunc isAppMetadataFile(filePath string) bool {\n\ttarget := filepath.Base(filePath)\n\n\tfor name := range appMetadataFiles {\n\t\tif target == name {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nvar binDataReplace = []fsutil.ReplaceInfo{\n\t{\n\t\tPathSuffix: \"/node\",\n\t\tMatch:      \"node.js/v\",\n\t\tReplace:    \"done,xu/v\",\n\t},\n}\n\nvar appMetadataFileUpdate = map[string]fsutil.DataUpdaterFn{\n\tnodePackageFile: nodePackageJSONVerUpdater,\n}\n\nfunc appMetadataFileUpdater(filePath string) error {\n\ttarget := filepath.Base(filePath)\n\n\tupdater, found := appMetadataFileUpdate[target]\n\tif !found {\n\t\tlog.Tracef(\"appMetadataFileUpdater - no updater\")\n\t\treturn nil\n\t}\n\n\treturn fsutil.UpdateFileData(filePath, updater, true)\n}\n\nfunc nodePackageJSONVerUpdater(target string, data []byte) ([]byte, error) {\n\tvar info map[string]interface{}\n\n\terr := json.Unmarshal(data, &info)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tversion, ok := info[\"version\"].(string)\n\tif !ok {\n\t\tlog.Tracef(\"nodePackageJSONVerUpdater - no version field, return as-is\")\n\t\treturn data, nil\n\t}\n\n\tversion = fmt.Sprintf(\"1%s\", version)\n\tlog.Tracef(\"nodePackageJSONVerUpdater(%s) - version='%v'->'%v')\\n\", target, info[\"version\"], version)\n\tinfo[\"version\"] = version\n\n\tvar b bytes.Buffer\n\tenc := json.NewEncoder(&b)\n\tenc.SetEscapeHTML(false)\n\tenc.SetIndent(\"  \", \"  \")\n\terr = enc.Encode(info)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error encoding updated package data\")\n\t}\n\n\treturn b.Bytes(), nil\n}\n\nvar fileTypeCmd string\n\nfunc init() {\n\tfindFileTypeCmd()\n}\n\nfunc findFileTypeCmd() {\n\tfileTypeCmd, err := exec.LookPath(fileTypeCmdName)\n\tif err != nil {\n\t\tlog.Debugf(\"findFileTypeCmd - cmd not found: %v\", err)\n\t\treturn\n\t}\n\n\tlog.Debugf(\"findFileTypeCmd - cmd found: %v\", fileTypeCmd)\n}\n\n// Needed mostly to be able to mock it in the sensor tests.\ntype Processor interface {\n\t// Current location of the artifacts folder.\n\tArtifactsDir() string\n\n\t// Enumerate all files under a given root (used later on to tell the files\n\t// that were created during probing and the existed files appart).\n\tGetCurrentPaths(root string, excludes []string) (map[string]struct{}, error)\n\n\t// Create the artifacts folder, preserve some files, etc.\n\tPrepareEnv(cmd *command.StartMonitor) error\n\n\t// Dump the creport and the files to the artifacts folder.\n\tProcess(\n\t\tcmd *command.StartMonitor,\n\t\tmountPoint string,\n\t\tpeReport *report.PeMonitorReport,\n\t\tfanReport *report.FanMonitorReport,\n\t\tptReport *report.PtMonitorReport,\n\t) error\n\n\t// Archives commands.json, creport.json, events.json, sensor.log, etc\n\t// to a tar ball.\n\tArchive() error\n}\n\ntype processor struct {\n\tseReport         *report.SensorReport\n\tartifactsDirName string\n\t// Extra files to put into the artifacts archive before exiting.\n\tartifactsExtra []string\n\torigPathMap    map[string]struct{}\n}\n\nfunc NewProcessor(seReport *report.SensorReport, artifactsDirName string, artifactsExtra []string) Processor {\n\treturn &processor{\n\t\tseReport:         seReport,\n\t\tartifactsDirName: artifactsDirName,\n\t\tartifactsExtra:   artifactsExtra,\n\t}\n}\n\nfunc (a *processor) ArtifactsDir() string {\n\treturn a.artifactsDirName\n}\n\nfunc (a *processor) GetCurrentPaths(root string, excludes []string) (map[string]struct{}, error) {\n\tlogger := log.WithField(\"op\", \"processor.GetCurrentPaths\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tpathMap := map[string]struct{}{}\n\terr := filepath.Walk(root,\n\t\tfunc(pth string, info os.FileInfo, err error) error {\n\t\t\tif strings.HasPrefix(pth, \"/proc/\") {\n\t\t\t\tlogger.Debugf(\"skipping /proc file system objects... - '%s'\", pth)\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(pth, \"/sys/\") {\n\t\t\t\tlogger.Debugf(\"skipping /sys file system objects... - '%s'\", pth)\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(pth, \"/dev/\") {\n\t\t\t\tlogger.Debugf(\"skipping /dev file system objects... - '%s'\", pth)\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\t// Optimization: Exclude folders early on to prevent slow enumerat\n\t\t\t//               Can help with mounting big folders from the host.\n\t\t\t// TODO: Combine this logic with the similar logic in findSymlinks().\n\t\t\tfor _, xpattern := range excludes {\n\t\t\t\tif match, _ := doublestar.Match(xpattern, pth); match {\n\t\t\t\t\tif info.Mode().IsDir() {\n\t\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\tlogger.Debugf(\"skipping %s with error: %v\", pth, err)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif !(info.Mode().IsRegular() || (info.Mode()&os.ModeSymlink) != 0) {\n\t\t\t\t//need symlinks too\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tpth, err = filepath.Abs(pth)\n\t\t\tif err != nil {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(pth, \"/proc/\") ||\n\t\t\t\tstrings.HasPrefix(pth, \"/sys/\") ||\n\t\t\t\tstrings.HasPrefix(pth, \"/dev/\") {\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tpathMap[pth] = struct{}{}\n\t\t\treturn nil\n\t\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ta.origPathMap = pathMap\n\treturn pathMap, nil\n}\n\nfunc (a *processor) PrepareEnv(cmd *command.StartMonitor) error {\n\tlogger := log.WithField(\"op\", \"processor.PrepareEnv\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tdstRootPath := filepath.Join(a.artifactsDirName, app.ArtifactFilesDirName)\n\tlogger.Debugf(\"prep file artifacts root dir - '%s'\", dstRootPath)\n\tif err := os.MkdirAll(dstRootPath, 0777); err != nil {\n\t\treturn err\n\t}\n\n\tif cmd != nil && len(cmd.Preserves) > 0 {\n\t\tlogger.Debugf(\"preserving paths - %d\", len(cmd.Preserves))\n\n\t\tpreservedDirPath := filepath.Join(a.artifactsDirName, preservedDirName)\n\t\tlogger.Debugf(\"prep preserved artifacts root dir - '%s'\", preservedDirPath)\n\t\tif err := os.MkdirAll(preservedDirPath, 0777); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tpreservePaths := preparePaths(getKeys(cmd.Preserves))\n\t\tlogger.Debugf(\"preservePaths(%v): %+v\", len(preservePaths), preservePaths)\n\n\t\tnewPerms := getRecordsWithPerms(cmd.Preserves)\n\t\tlogger.Debugf(\"newPerms(%v): %+v\", len(newPerms), newPerms)\n\n\t\tfor inPath, isDir := range preservePaths {\n\t\t\tif artifact.IsFilteredPath(inPath) {\n\t\t\t\tlogger.Debugf(\"skipping filtered path [isDir=%v] %s\", isDir, inPath)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tdstPath := fmt.Sprintf(\"%s%s\", preservedDirPath, inPath)\n\t\t\tlogger.Debugf(\"[isDir=%v] %s\", isDir, dstPath)\n\n\t\t\tif isDir {\n\t\t\t\terr, errs := fsutil.CopyDir(cmd.KeepPerms, inPath, dstPath, true, true, nil, nil, nil)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Debugf(\"fsutil.CopyDir(%v,%v) error: %v\", inPath, dstPath, err)\n\t\t\t\t}\n\n\t\t\t\tif len(errs) > 0 {\n\t\t\t\t\tlogger.Debugf(\"fsutil.CopyDir(%v,%v) copy errors: %+v\", inPath, dstPath, errs)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err := fsutil.CopyFile(cmd.KeepPerms, inPath, dstPath, true); err != nil {\n\t\t\t\t\tlogger.Debugf(\"fsutil.CopyFile(%v,%v) error: %v\", inPath, dstPath, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor inPath, perms := range newPerms {\n\t\t\tdstPath := fmt.Sprintf(\"%s%s\", preservedDirPath, inPath)\n\t\t\tif fsutil.Exists(dstPath) {\n\t\t\t\tif err := fsutil.SetAccess(dstPath, perms); err != nil {\n\t\t\t\t\tlogger.Debugf(\"fsutil.SetAccess(%v,%v) error: %v\", dstPath, perms, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (a *processor) Process(\n\tcmd *command.StartMonitor,\n\tmountPoint string,\n\tpeReport *report.PeMonitorReport,\n\tfanReport *report.FanMonitorReport,\n\tptReport *report.PtMonitorReport,\n) error {\n\t//TODO: when peReport is available filter file events from fanReport\n\tlogger := log.WithField(\"op\", \"processor.Process\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tlogger.Debug(\"processing data...\")\n\n\tfileCount := 0\n\tfileList := make([]string, 0, fileCount)\n\tfor _, processFileMap := range fanReport.ProcessFiles {\n\t\tfileCount += len(processFileMap)\n\t\tfor fpath := range processFileMap {\n\t\t\tfileList = append(fileList, fpath)\n\t\t}\n\t}\n\n\tlogger.Debugf(\"len(fanReport.ProcessFiles)=%v / fileCount=%v\", len(fanReport.ProcessFiles), fileCount)\n\tallFilesMap := findSymlinks(fileList, mountPoint, cmd.Excludes)\n\treturn saveResults(a.origPathMap, a.artifactsDirName, cmd, allFilesMap, fanReport, ptReport, peReport, a.seReport)\n}\n\nfunc (a *processor) Archive() error {\n\ttoArchive := map[string]struct{}{}\n\tfor _, f := range a.artifactsExtra {\n\t\tif fsutil.Exists(f) {\n\t\t\ttoArchive[f] = struct{}{}\n\t\t}\n\t}\n\n\tartifacts, err := os.ReadDir(a.artifactsDirName)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// We archive everything in the /opt/_slim/artifacts folder\n\t// except (potentially large data) `files` and `files.tar` entries.\n\t// and the monitor data event log\n\t// (which is used for local debugging or it should be streamed out of band)\n\t// In particular, this may include:\n\t//   - creport.json\n\t//   - events.json\n\t//   - app_stdout.log\n\t//   - app_stderr.log\n\tfor _, f := range artifacts {\n\t\tif f.Name() != app.ArtifactFilesDirName &&\n\t\t\tf.Name() != filesArchiveName &&\n\t\t\tf.Name() != report.DefaultMonDelFileName {\n\t\t\ttoArchive[filepath.Join(a.artifactsDirName, f.Name())] = struct{}{}\n\t\t}\n\t}\n\n\tvar toArchiveList []string\n\tfor name := range toArchive {\n\t\ttoArchiveList = append(toArchiveList, name)\n\t}\n\treturn fsutil.ArchiveFiles(\n\t\tfilepath.Join(a.artifactsDirName, runArchiveName), toArchiveList, false, \"\")\n}\n\nfunc saveResults(\n\torigPathMap map[string]struct{},\n\tartifactsDirName string,\n\tcmd *command.StartMonitor,\n\tfileNames map[string]*report.ArtifactProps,\n\tfanMonReport *report.FanMonitorReport,\n\tptMonReport *report.PtMonitorReport,\n\tpeReport *report.PeMonitorReport,\n\tseReport *report.SensorReport,\n) error {\n\tlog.Debugf(\"saveResults(%v,...)\", len(fileNames))\n\n\tartifactStore := newStore(origPathMap,\n\t\tartifactsDirName,\n\t\tfileNames,\n\t\tfanMonReport,\n\t\tptMonReport,\n\t\tpeReport,\n\t\tseReport,\n\t\tcmd)\n\n\tartifactStore.prepareArtifacts()\n\tartifactStore.saveArtifacts()\n\tartifactStore.enumerateArtifacts()\n\t//artifactStore.archiveArtifacts() //alternative way to xfer artifacts\n\treturn artifactStore.saveReport()\n}\n\n// NOTE:\n// the 'store' is supposed to only store/save/copy the artifacts we identified,\n// but overtime a lot of artifact processing and post-processing logic\n// ended up there too (which belongs in the artifact 'processor').\n// TODO: refactor 'processor' and 'store' to have the right logic in the right places\ntype store struct {\n\torigPathMap   map[string]struct{}\n\tstoreLocation string\n\tfanMonReport  *report.FanMonitorReport\n\tptMonReport   *report.PtMonitorReport\n\tpeMonReport   *report.PeMonitorReport\n\tseReport      *report.SensorReport\n\trawNames      map[string]*report.ArtifactProps\n\tnameList      []string\n\tresolve       map[string]struct{}\n\tlinkMap       map[string]*report.ArtifactProps\n\tfileMap       map[string]*report.ArtifactProps\n\tsaFileMap     map[string]*report.ArtifactProps\n\tcmd           *command.StartMonitor\n\tappStacks     map[string]*appStackInfo\n}\n\nfunc newStore(\n\torigPathMap map[string]struct{},\n\tstoreLocation string,\n\trawNames map[string]*report.ArtifactProps,\n\tfanMonReport *report.FanMonitorReport,\n\tptMonReport *report.PtMonitorReport,\n\tpeMonReport *report.PeMonitorReport,\n\tseReport *report.SensorReport,\n\tcmd *command.StartMonitor) *store {\n\tstore := &store{\n\t\torigPathMap:   origPathMap,\n\t\tstoreLocation: storeLocation,\n\t\tfanMonReport:  fanMonReport,\n\t\tptMonReport:   ptMonReport,\n\t\tpeMonReport:   peMonReport,\n\t\tseReport:      seReport,\n\t\trawNames:      rawNames,\n\t\tnameList:      make([]string, 0, len(rawNames)),\n\t\tresolve:       map[string]struct{}{},\n\t\tlinkMap:       map[string]*report.ArtifactProps{},\n\t\tfileMap:       map[string]*report.ArtifactProps{},\n\t\tsaFileMap:     map[string]*report.ArtifactProps{},\n\t\tcmd:           cmd,\n\t\tappStacks:     map[string]*appStackInfo{},\n\t}\n\n\treturn store\n}\n\nfunc (p *store) getArtifactFlags(artifactFileName string) map[string]bool {\n\tflags := map[string]bool{}\n\tfor _, processFileMap := range p.fanMonReport.ProcessFiles {\n\t\tif finfo, ok := processFileMap[artifactFileName]; ok {\n\t\t\tif finfo.ReadCount > 0 {\n\t\t\t\tflags[\"R\"] = true\n\t\t\t}\n\n\t\t\tif finfo.WriteCount > 0 {\n\t\t\t\tflags[\"W\"] = true\n\t\t\t}\n\n\t\t\tif finfo.ExeCount > 0 {\n\t\t\t\tflags[\"X\"] = true\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(flags) < 1 {\n\t\treturn nil\n\t}\n\n\treturn flags\n}\n\nfunc (p *store) prepareArtifact(artifactFileName string) {\n\tsrcLinkFileInfo, err := os.Lstat(artifactFileName)\n\tif err != nil {\n\t\tlog.Debugf(\"prepareArtifact - artifact don't exist: %v (%v)\", artifactFileName, os.IsNotExist(err))\n\t\treturn\n\t}\n\n\tp.nameList = append(p.nameList, artifactFileName)\n\n\tprops := &report.ArtifactProps{\n\t\tFilePath: artifactFileName,\n\t\tMode:     srcLinkFileInfo.Mode(),\n\t\tModeText: srcLinkFileInfo.Mode().String(),\n\t\tFileSize: srcLinkFileInfo.Size(),\n\t}\n\n\tprops.Flags = p.getArtifactFlags(artifactFileName)\n\n\tlog.Tracef(\"prepareArtifact - file mode:%v\", srcLinkFileInfo.Mode())\n\tswitch {\n\tcase srcLinkFileInfo.Mode().IsRegular():\n\t\tprops.FileType = report.FileArtifactType\n\t\tprops.Sha1Hash, _ = getFileHash(artifactFileName)\n\n\t\tif fileTypeCmd != \"\" {\n\t\t\tprops.DataType, _ = getDataType(artifactFileName)\n\t\t}\n\n\t\tp.fileMap[artifactFileName] = props\n\t\tp.rawNames[artifactFileName] = props\n\tcase (srcLinkFileInfo.Mode() & os.ModeSymlink) != 0:\n\t\tlinkRef, err := os.Readlink(artifactFileName)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"prepareArtifact - error getting reference for symlink (%v) -> %v\", err, artifactFileName)\n\t\t\treturn\n\t\t}\n\n\t\tprops.FileType = report.SymlinkArtifactType\n\t\tprops.LinkRef = linkRef\n\t\t//props.LinkRefAbs, err := filepath.Abs(linkRef)\n\t\t//if err != nil {\n\t\t//\tlog.Warnf(\"prepareArtifact - error getting absolute path for symlink reference (%v) -> %v => %v\",\n\t\t//\t\terr, artifactFileName, linkRef)\n\t\t//}\n\n\t\t//build absolute and evaluated symlink target paths\n\t\tvar absLinkRef string\n\t\tif !filepath.IsAbs(linkRef) {\n\t\t\tlinkDir := filepath.Dir(artifactFileName)\n\t\t\tfullLinkRef := filepath.Join(linkDir, linkRef)\n\t\t\tabsLinkRef, err = filepath.Abs(fullLinkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"prepareArtifact - error getting absolute path for symlink ref (%v) -> %v => %v\", err, artifactFileName, fullLinkRef)\n\t\t\t}\n\t\t} else {\n\t\t\tabsLinkRef, err = filepath.Abs(linkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"prepareArtifact - error getting absolute path for symlink ref 2 (%v) -> %v => %v\", err, artifactFileName, linkRef)\n\t\t\t}\n\t\t}\n\n\t\tif absLinkRef != \"\" {\n\t\t\tevalLinkRef, err := filepath.EvalSymlinks(absLinkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"prepareArtifact - error evaluating symlink (%v) -> %v => %v\", err, artifactFileName, absLinkRef)\n\t\t\t} else {\n\t\t\t\tif evalLinkRef != absLinkRef {\n\t\t\t\t\tif _, ok := p.rawNames[evalLinkRef]; !ok {\n\t\t\t\t\t\tp.resolve[evalLinkRef] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif _, ok := p.rawNames[absLinkRef]; !ok {\n\t\t\t\tp.resolve[absLinkRef] = struct{}{}\n\t\t\t}\n\t\t}\n\n\t\tp.linkMap[artifactFileName] = props\n\t\tp.rawNames[artifactFileName] = props\n\n\tcase srcLinkFileInfo.Mode().IsDir():\n\t\tlog.Debugf(\"prepareArtifact - is a directory (shouldn't see it) - %v\", artifactFileName)\n\t\tprops.FileType = report.DirArtifactType\n\t\tp.rawNames[artifactFileName] = props\n\tdefault:\n\t\tlog.Debugf(\"prepareArtifact - other type (shouldn't see it) - %v\", artifactFileName)\n\t\tp.rawNames[artifactFileName] = props\n\t}\n}\n\nfunc (p *store) prepareArtifacts() {\n\tlog.Debugf(\"p.prepareArtifacts() p.rawNames=%v\", len(p.rawNames))\n\n\tfor artifactFileName := range p.rawNames {\n\t\tlog.Debugf(\"prepareArtifacts - artifact => %v\", artifactFileName)\n\t\tp.prepareArtifact(artifactFileName)\n\t}\n\n\tif p.ptMonReport.Enabled {\n\t\tlog.Debug(\"prepareArtifacts - ptMonReport.Enabled\")\n\t\tfor artifactFileName, fsaInfo := range p.ptMonReport.FSActivity {\n\t\t\tartifactInfo, found := p.rawNames[artifactFileName]\n\t\t\tif found && artifactInfo != nil {\n\t\t\t\tartifactInfo.FSActivity = fsaInfo\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"prepareArtifacts [%v] - fsa artifact => %v\", found, artifactFileName)\n\t\t\t\tif found && artifactInfo == nil {\n\t\t\t\t\tlog.Debugf(\"prepareArtifacts - fsa artifact (found, but no info) => %v\", artifactFileName)\n\t\t\t\t}\n\t\t\t\tp.prepareArtifact(artifactFileName)\n\t\t\t\tartifactInfo, found := p.rawNames[artifactFileName]\n\t\t\t\tif found && artifactInfo != nil {\n\t\t\t\t\tartifactInfo.FSActivity = fsaInfo\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"[warn] prepareArtifacts - fsa artifact - missing in rawNames => %v\", artifactFileName)\n\t\t\t\t}\n\n\t\t\t\t//TMP:\n\t\t\t\t//fsa might include directories, which we'll need to copy (dir only)\n\t\t\t\t//but p.prepareArtifact() doesn't do anything with dirs for now\n\t\t\t}\n\t\t}\n\t}\n\n\tfor artifactFileName := range p.fileMap {\n\t\t//TODO: conditionally detect binary files and their deps\n\t\tif binProps, _ := binfile.Detected(artifactFileName); binProps == nil || !binProps.IsBin {\n\t\t\tcontinue\n\t\t}\n\n\t\tbinArtifacts, err := sodeps.AllDependencies(artifactFileName)\n\t\tif err != nil {\n\t\t\tif err == sodeps.ErrDepResolverNotFound {\n\t\t\t\tlog.Debug(\"prepareArtifacts.binArtifacts[bsa] - no static bin dep resolver\")\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"prepareArtifacts.binArtifacts[bsa] - %v - error getting bin artifacts => %v\\n\", artifactFileName, err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tfor idx, bpath := range binArtifacts {\n\t\t\tif artifactFileName == bpath {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t_, found := p.rawNames[bpath]\n\t\t\tif found {\n\t\t\t\tlog.Debugf(\"prepareArtifacts.binArtifacts[bsa] - known file path (%s)\", bpath)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tbpathFileInfo, err := os.Lstat(bpath)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"prepareArtifacts.binArtifacts[bsa] - artifact doesn't exist: %v (%v)\", bpath, os.IsNotExist(err))\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tbprops := &report.ArtifactProps{\n\t\t\t\tFilePath: bpath,\n\t\t\t\tMode:     bpathFileInfo.Mode(),\n\t\t\t\tModeText: bpathFileInfo.Mode().String(),\n\t\t\t\tFileSize: bpathFileInfo.Size(),\n\t\t\t}\n\n\t\t\tbprops.Flags = p.getArtifactFlags(bpath)\n\n\t\t\tfsType := report.UnknownArtifactTypeName\n\t\t\tswitch {\n\t\t\tcase bpathFileInfo.Mode().IsRegular():\n\t\t\t\tfsType = report.FileArtifactTypeName\n\t\t\t\tp.rawNames[bpath] = bprops\n\t\t\t\t//use a separate file map, so we can save them last\n\t\t\t\t//in case we are dealing with intermediate symlinks\n\t\t\t\t//and to better track what bin deps are not covered by dynamic analysis\n\t\t\t\tp.saFileMap[bpath] = bprops\n\t\t\tcase (bpathFileInfo.Mode() & os.ModeSymlink) != 0:\n\t\t\t\tfsType = report.SymlinkArtifactTypeName\n\t\t\t\tp.linkMap[bpath] = bprops\n\t\t\t\tp.rawNames[bpath] = bprops\n\t\t\tdefault:\n\t\t\t\tfsType = report.UnexpectedArtifactTypeName\n\t\t\t\tlog.Debugf(\"prepareArtifacts.binArtifacts[bsa] - unexpected ft - %s\", bpath)\n\t\t\t}\n\n\t\t\tlog.Debugf(\"prepareArtifacts.binArtifacts[bsa] - bin artifact (%s) fsType=%s [%d]bdep=%s\", artifactFileName, fsType, idx, bpath)\n\t\t}\n\t}\n\n\tp.resolveLinks()\n}\n\nfunc (p *store) resolveLinks() {\n\t//note:\n\t//the links should be resolved in findSymlinks, but\n\t//the current design needs to be improved to catch all symlinks\n\t//this is a backup to catch the root level symlinks\n\tfiles, err := os.ReadDir(\"/\")\n\tif err != nil {\n\t\tlog.Debug(\"resolveLinks - os.ReadDir error: \", err)\n\t\treturn\n\t}\n\n\tfor _, file := range files {\n\t\tfpath := fmt.Sprintf(\"/%s\", file.Name())\n\t\tlog.Debugf(\"resolveLinks.files - fpath='%s'\", fpath)\n\n\t\tif fpath == \"/proc\" ||\n\t\t\tfpath == \"/sys\" ||\n\t\t\tfpath == \"/dev\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tfileInfo, err := os.Lstat(fpath)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"resolveLinks.files - os.Lstat(%s) error: %v\", fpath, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tif fileInfo.Mode()&os.ModeSymlink == 0 {\n\t\t\tlog.Debug(\"resolveLinks.files - skipping non-symlink\")\n\t\t\tcontinue\n\t\t}\n\n\t\tlinkRef, err := os.Readlink(fpath)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"resolveLinks.files - os.Readlink(%s) error: %v\", fpath, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tvar absLinkRef string\n\t\tif !filepath.IsAbs(linkRef) {\n\t\t\tlinkDir := filepath.Dir(fpath)\n\t\t\tlog.Debugf(\"resolveLinks.files - relative linkRef %v -> %v +/+ %v\", fpath, linkDir, linkRef)\n\t\t\tfullLinkRef := filepath.Join(linkDir, linkRef)\n\t\t\tvar err error\n\t\t\tabsLinkRef, err = filepath.Abs(fullLinkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"resolveLinks.files - error getting absolute path for symlink ref (1) (%v) -> %v => %v\", err, fpath, fullLinkRef)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t} else {\n\t\t\tvar err error\n\t\t\tabsLinkRef, err = filepath.Abs(linkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"resolveLinks.files - error getting absolute path for symlink ref (2) (%v) -> %v => %v\", err, fpath, linkRef)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t//todo: skip \"/proc/...\" references\n\t\tevalLinkRef, err := filepath.EvalSymlinks(absLinkRef)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"resolveLinks.files - error evaluating symlink (%v) -> %v => %v\", err, fpath, absLinkRef)\n\t\t}\n\n\t\t//detecting intermediate dir symlinks\n\t\tsymlinkPrefix := fmt.Sprintf(\"%s/\", fpath)\n\t\tabsPrefix := fmt.Sprintf(\"%s/\", absLinkRef)\n\t\tevalPrefix := fmt.Sprintf(\"%s/\", evalLinkRef)\n\t\tfor rawName := range p.rawNames {\n\t\t\tif strings.HasPrefix(rawName, symlinkPrefix) {\n\t\t\t\tif _, found := p.rawNames[fpath]; found {\n\t\t\t\t\tlog.Debugf(\"resolveLinks.files - rawNames - known symlink: name=%s target=%s\", fpath, symlinkPrefix)\n\t\t\t\t} else {\n\t\t\t\t\tp.rawNames[fpath] = nil\n\t\t\t\t\tlog.Debugf(\"resolveLinks.files - added path symlink to p.rawNames (0) -> %v\", fpath)\n\t\t\t\t\tp.prepareArtifact(fpath)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(rawName, absPrefix) {\n\t\t\t\tif _, found := p.rawNames[fpath]; found {\n\t\t\t\t\tlog.Debugf(\"resolveLinks.files - rawNames - known symlink: name=%s target=%s\", fpath, absPrefix)\n\t\t\t\t} else {\n\t\t\t\t\tp.rawNames[fpath] = nil\n\t\t\t\t\tlog.Debugf(\"resolveLinks.files - added path symlink to p.rawNames (1) -> %v\", fpath)\n\t\t\t\t\tp.prepareArtifact(fpath)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif evalLinkRef != \"\" &&\n\t\t\t\tabsPrefix != evalPrefix &&\n\t\t\t\tstrings.HasPrefix(rawName, evalPrefix) {\n\t\t\t\tif _, found := p.rawNames[fpath]; found {\n\t\t\t\t\tlog.Debugf(\"resolveLinks.files - rawNames - known symlink: name=%s target=%s\", fpath, evalPrefix)\n\t\t\t\t} else {\n\t\t\t\t\tp.rawNames[fpath] = nil\n\t\t\t\t\tlog.Debugf(\"resolveLinks.files - added path symlink to p.rawNames (2) -> %v\", fpath)\n\t\t\t\t\tp.prepareArtifact(fpath)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t//note: resolve these extra symlinks after the root level symlinks\n\tfor name := range p.resolve {\n\t\tlog.Debug(\"resolveLinks - resolving: \", name)\n\t\tp.prepareArtifact(name)\n\t}\n}\n\nfunc preparePaths(pathList []string) map[string]bool {\n\tif len(pathList) < 1 {\n\t\treturn nil\n\t}\n\n\tpaths := map[string]bool{}\n\tfor _, pathValue := range pathList {\n\t\tpathInfo, err := os.Stat(pathValue)\n\t\tif err != nil {\n\t\t\tlog.WithError(err).Debug(\"preparePaths(): skipping path = \", pathValue)\n\t\t\tcontinue\n\t\t}\n\n\t\tif pathInfo.IsDir() {\n\t\t\tpaths[pathValue] = true\n\t\t} else {\n\t\t\tpaths[pathValue] = false\n\t\t}\n\t}\n\n\treturn paths\n}\n\nfunc getKeys(m map[string]*fsutil.AccessInfo) []string {\n\tif len(m) == 0 {\n\t\treturn nil\n\t}\n\n\tkeys := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, k)\n\t}\n\n\treturn keys\n}\n\nfunc getRecordsWithPerms(m map[string]*fsutil.AccessInfo) map[string]*fsutil.AccessInfo {\n\tperms := map[string]*fsutil.AccessInfo{}\n\tfor k, v := range m {\n\t\tif v != nil {\n\t\t\tperms[k] = v\n\t\t}\n\t}\n\n\treturn perms\n}\n\n// copied from dockerimage.go\nfunc linkTargetToFullPath(fullPath, target string) string {\n\tif filepath.IsAbs(target) {\n\t\treturn target\n\t}\n\n\tif target == \".\" {\n\t\treturn \"\"\n\t}\n\n\td := filepath.Dir(fullPath)\n\n\treturn filepath.Clean(filepath.Join(d, target))\n}\n\nfunc (p *store) saveWorkdir(excludePatterns []string) {\n\tif p.cmd.IncludeWorkdir == \"\" {\n\t\treturn\n\t}\n\n\tif artifact.IsFilteredPath(p.cmd.IncludeWorkdir) {\n\t\tlog.Debug(\"sensor.store.saveWorkdir(): skipping filtered workdir\")\n\t\treturn\n\t}\n\n\tif !fsutil.DirExists(p.cmd.IncludeWorkdir) {\n\t\tlog.Debugf(\"sensor.store.saveWorkdir: workdir does not exist %s\", p.cmd.IncludeWorkdir)\n\t\treturn\n\t}\n\n\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, p.cmd.IncludeWorkdir)\n\tif fsutil.Exists(dstPath) {\n\t\tlog.Debug(\"sensor.store.saveWorkdir: workdir dst path already exists\")\n\t\t//it's possible that some of the files in the work dir are already copied\n\t\t//the copy logic will improve when we copy the files separately\n\t\t//for now just copy the whole workdir\n\t}\n\n\tlog.Debugf(\"sensor.store.saveWorkdir: workdir=%s\", p.cmd.IncludeWorkdir)\n\n\terr, errs := fsutil.CopyDir(p.cmd.KeepPerms, p.cmd.IncludeWorkdir, dstPath, true, true, excludePatterns, nil, nil)\n\tif err != nil {\n\t\tlog.Debugf(\"sensor.store.saveWorkdir: CopyDir(%v,%v) error: %v\", p.cmd.IncludeWorkdir, dstPath, err)\n\t}\n\n\tif len(errs) > 0 {\n\t\tlog.Debugf(\"sensor.store.saveWorkdir: CopyDir(%v,%v) copy errors: %+v\", p.cmd.IncludeWorkdir, dstPath, errs)\n\t}\n\n\t//todo:\n\t//copy files separately and\n\t//apply 'workdir-exclude' patterns in addition to the global excludes (excludePatterns)\n\t//resolve symlinks\n}\n\n/////////////////////////////////////////////////////////\n\nconst (\n\tziDirOne    = \"/usr/lib/zoneinfo\"\n\tziDirTwo    = \"/usr/share/zoneinfo\"\n\tziDirThree  = \"/usr/share/zoneinfo-icu\"\n\tziEnv       = \"TZDIR\" //TODO: lookup zoneinfo data path from TZDIR\n\tziTimezone  = \"/etc/timezone\"\n\tziLocaltime = \"/etc/localtime\"\n)\n\nvar ziDirs = []string{\n\tziDirOne,\n\tziDirTwo,\n\tziDirThree,\n}\n\nvar ziFiles = []string{\n\tziTimezone,\n\tziLocaltime,\n}\n\nfunc (p *store) saveZoneInfo() {\n\tif !p.cmd.IncludeZoneInfo {\n\t\treturn\n\t}\n\n\tlog.Trace(\"sensor.store.saveZoneInfo\")\n\tfor _, fp := range ziFiles {\n\t\tif !fsutil.Exists(fp) {\n\t\t\tlog.Debugf(\"sensor.store.saveZoneInfo: no target file '%s' (skipping...)\", fp)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Tracef(\"sensor.store.saveZoneInfo: copy %s\", fp)\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, fp)\n\t\tif fsutil.Exists(dstPath) {\n\t\t\tlog.Debugf(\"sensor.store.saveZoneInfo: already copied target file '%s' (skipping...)\", dstPath)\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, fp, dstPath, true); err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveZoneInfo: fsutil.CopyFile(%v,%v) error - %v\", fp, dstPath, err)\n\t\t}\n\t}\n\n\tfor _, dp := range ziDirs {\n\t\tif !fsutil.DirExists(dp) {\n\t\t\tlog.Debugf(\"sensor.store.saveZoneInfo: no target directory '%s' (skipping...)\", dp)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Tracef(\"sensor.store.saveZoneInfo: copy dir %s\", dp)\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, dp)\n\n\t\terr, errs := fsutil.CopyDir(p.cmd.KeepPerms, dp, dstPath, true, true, nil, nil, nil)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveZoneInfo: fsutil.CopyDir(%s,%s) error: %v\", dp, dstPath, err)\n\t\t}\n\n\t\tif len(errs) > 0 {\n\t\t\tlog.Debugf(\"sensor.store.saveZoneInfo: fsutil.CopyDir(%v,%v) copy errors: %+v\", dp, dstPath, errs)\n\t\t}\n\t}\n}\n\n/////////////////////////////////////////////////////////\n\nconst (\n\tsshUserSSHDir    = \".ssh\"\n\tsshUserSSHDirPat = \"/.ssh/\"\n\tsshEtc           = \"/etc/ssh\"\n\tsshLibOpenSSH    = \"/usr/lib/openssh\"\n\tsshDefaultExeDir = \"/usr/bin\"\n\n\tsshExeName        = \"ssh\"\n\tsshAddExeName     = \"ssh-add\"\n\tsshAgentExeName   = \"ssh-agent\"\n\tsshKeygenExeName  = \"ssh-keygen\"\n\tsshKeyscanExeName = \"ssh-keyscan\"\n\tsshArgv0ExeName   = \"ssh-argv0\"\n\tsshCopyIDExeName  = \"ssh-copy-id\"\n)\n\nvar sshConfigDirs = []string{\n\tsshEtc,\n}\n\nvar sshBinDirs = []string{\n\tsshLibOpenSSH,\n}\n\nvar sshExeNames = []string{\n\tsshExeName,\n\tsshAddExeName,\n\tsshAgentExeName,\n\tsshKeygenExeName,\n\tsshKeyscanExeName,\n\tsshArgv0ExeName,\n\tsshCopyIDExeName,\n}\n\nfunc homeDirs() []string {\n\tdirMap := map[string]struct{}{}\n\tvar done bool\n\tif fsutil.Exists(sysidentity.PasswdFilePath) {\n\t\tinfo, err := sysidentity.ReadPasswdFile(sysidentity.PasswdFilePath)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.homeDirs: error processing passwd: %v\", err)\n\t\t} else {\n\t\t\tfor _, pr := range info.Records {\n\t\t\t\tif pr.NoLoginShell || pr.Home == \"\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tdirMap[pr.Home] = struct{}{}\n\t\t\t}\n\n\t\t\tdone = true\n\t\t}\n\t}\n\n\tif !done {\n\t\t// hacky way to get the home directories for users...\n\t\trootDir := \"/root\"\n\t\tif !fsutil.DirExists(rootDir) {\n\t\t\tdirMap[rootDir] = struct{}{}\n\t\t}\n\n\t\thomeBaseDir := \"/home\"\n\t\thdFiles, err := os.ReadDir(homeBaseDir)\n\t\tif err == nil {\n\t\t\tfor _, file := range hdFiles {\n\t\t\t\tfullPath := filepath.Join(homeBaseDir, file.Name())\n\t\t\t\tif fsutil.IsDir(fullPath) {\n\t\t\t\t\tdirMap[fullPath] = struct{}{}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debugf(\"sensor.store.homeDirs: error enumerating %s: %v\", homeBaseDir, err)\n\t\t}\n\t}\n\n\tvar dirList []string\n\tfor dp := range dirMap {\n\t\tdirList = append(dirList, dp)\n\t}\n\n\treturn dirList\n}\n\nfunc (ref *store) saveSSHClient() {\n\tif !ref.cmd.IncludeSSHClient {\n\t\treturn\n\t}\n\n\tlog.Trace(\"sensor.store.saveSSHClient\")\n\tconfigDirs := append([]string{}, sshConfigDirs...)\n\n\t// copy user config dirs\n\tfor _, dir := range homeDirs() {\n\t\tdp := filepath.Join(dir, sshUserSSHDir)\n\t\tif !fsutil.DirExists(dp) {\n\t\t\tcontinue\n\t\t}\n\n\t\tconfigDirs = append(configDirs, dp)\n\t}\n\n\t// copy config dirs\n\tfor _, dp := range configDirs {\n\t\tif !fsutil.DirExists(dp) {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: no target directory '%s' (skipping...)\", dp)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Tracef(\"sensor.store.saveSSHClient: copy dir %s\", dp)\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", ref.storeLocation, dp)\n\n\t\terr, errs := fsutil.CopyDir(ref.cmd.KeepPerms, dp, dstPath, true, true, nil, nil, nil)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: fsutil.CopyDir(%s,%s) error: %v\", dp, dstPath, err)\n\t\t}\n\n\t\tif len(errs) > 0 {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: fsutil.CopyDir(%v,%v) copy errors: %+v\", dp, dstPath, errs)\n\t\t}\n\t}\n\n\t// locate/resolve exes to full bin paths\n\tallDepsMap := map[string]struct{}{}\n\tfor _, name := range sshExeNames {\n\t\texePath, err := exec.LookPath(name)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient - checking '%s' exe (not found: %s)\", name, err)\n\t\t\texePath = filepath.Join(sshDefaultExeDir, name)\n\t\t}\n\n\t\tif !fsutil.Exists(exePath) {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient - exe bin file not found - '%s' (skipping)\", exePath)\n\t\t\tcontinue\n\t\t}\n\n\t\tartifacts, err := sodeps.AllDependencies(exePath)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient - %s - error getting bin artifacts => %v\", exePath, err)\n\t\t\t// still add the bin path itself even if we had problems locating its deps\n\t\t\tallDepsMap[exePath] = struct{}{}\n\t\t\tcontinue\n\t\t}\n\n\t\t// artifacts includes exePath\n\t\tfor _, an := range artifacts {\n\t\t\tallDepsMap[an] = struct{}{}\n\t\t}\n\t}\n\n\t// copy bin dirs and identify bin deps\n\tfor _, dp := range sshBinDirs {\n\t\tif !fsutil.DirExists(dp) {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: no target directory '%s' (skipping...)\", dp)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Tracef(\"sensor.store.saveSSHClient: copy dir %s\", dp)\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", ref.storeLocation, dp)\n\n\t\terr, errs := fsutil.CopyDir(ref.cmd.KeepPerms, dp, dstPath, true, true, nil, nil, nil)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: fsutil.CopyDir(%s,%s) error: %v\", dp, dstPath, err)\n\t\t}\n\n\t\tif len(errs) > 0 {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: fsutil.CopyDir(%v,%v) copy errors: %+v\", dp, dstPath, errs)\n\t\t}\n\n\t\tdirFiles := map[string]struct{}{}\n\t\terr = filepath.Walk(dp,\n\t\t\tfunc(p string, info os.FileInfo, err error) error {\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: [bin dir path - %s] skipping %s with error: %v\", dp, p, err)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tp, err = filepath.Abs(p)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tdirFiles[p] = struct{}{}\n\t\t\t\treturn nil\n\t\t\t})\n\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: error enumerating %s: %v\", dp, err)\n\t\t}\n\n\t\tfor fp := range dirFiles {\n\t\t\tif !fsutil.Exists(fp) {\n\t\t\t\tlog.Debugf(\"sensor.store.saveSSHClient - bin dir (%s) file not found - '%s' (skipping)\", dp, fp)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif binProps, _ := binfile.Detected(fp); binProps != nil && binProps.IsBin {\n\t\t\t\tbinArtifacts, err := sodeps.AllDependencies(fp)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// still add the bin path itself even if we had problems locating its deps\n\t\t\t\t\tallDepsMap[fp] = struct{}{}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfor _, bpath := range binArtifacts {\n\t\t\t\t\tbfpaths, err := resloveLink(bpath)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: error resolving link - %s (%v)\", bpath, err)\n\t\t\t\t\t\t// still add the path...\n\t\t\t\t\t\tallDepsMap[bpath] = struct{}{}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tfor _, bfp := range bfpaths {\n\t\t\t\t\t\tif bfp == \"\" {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif !fsutil.Exists(bfp) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tallDepsMap[bfp] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tallDepsMap[fp] = struct{}{}\n\t\t\t}\n\t\t}\n\t}\n\n\t// copy bin files and their deps\n\tlog.Tracef(\"sensor.store.saveSSHClient: - paths.len(%d) = %+v\", len(allDepsMap), allDepsMap)\n\tfor fp := range allDepsMap {\n\t\tif !fsutil.Exists(fp) {\n\t\t\tcontinue\n\t\t}\n\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", ref.storeLocation, fp)\n\t\tif fsutil.Exists(dstPath) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := fsutil.CopyFile(ref.cmd.KeepPerms, fp, dstPath, true); err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveSSHClient: fsutil.CopyFile(%v,%v) error - %v\", fp, dstPath, err)\n\t\t}\n\t}\n}\n\nconst (\n\tosLibDir          = \"/lib/\"\n\tosUsrLibDir       = \"/usr/lib/\"\n\tosUsrLib64Dir     = \"/usr/lib64/\"\n\tosLibNssDns       = \"/libnss_dns\"\n\tosLibNssResolv    = \"/libresolv\"\n\tosLibNssFiles     = \"/libnss_files\"\n\tosLibSO           = \".so\"\n\tosLibResolveConf  = \"/etc/resolv.conf\"\n\tosLibNsswitchConf = \"/etc/nsswitch.conf\"\n\tosLibHostConf     = \"/etc/host.conf\"\n)\n\nvar osLibsNetFiles = []string{\n\tosLibResolveConf,\n\tosLibNsswitchConf,\n\tosLibHostConf,\n}\n\nfunc (p *store) saveOSLibsNetwork() {\n\tif !p.cmd.IncludeOSLibsNet {\n\t\treturn\n\t}\n\n\tlog.Trace(\"sensor.store.saveOSLibsNetwork\")\n\tfor _, fp := range osLibsNetFiles {\n\t\tif !fsutil.Exists(fp) {\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Debugf(\"sensor.store.saveOSLibsNetwork: copy %s\", fp)\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, fp)\n\t\tif fsutil.Exists(dstPath) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, fp, dstPath, true); err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveOSLibsNetwork: fsutil.CopyFile(%v,%v) error - %v\", fp, dstPath, err)\n\t\t}\n\t}\n\n\tif len(p.origPathMap) == 0 {\n\t\tlog.Debug(\"sensor.store.saveOSLibsNetwork: no origPathMap\")\n\t\treturn\n\t}\n\n\tpathMap := map[string]struct{}{}\n\tfor fileName := range p.origPathMap {\n\t\tif (strings.Contains(fileName, osLibNssDns) ||\n\t\t\tstrings.Contains(fileName, osLibNssResolv) ||\n\t\t\tstrings.Contains(fileName, osLibNssFiles)) &&\n\t\t\t(strings.Contains(fileName, osLibDir) ||\n\t\t\t\tstrings.Contains(fileName, osUsrLibDir) ||\n\t\t\t\tstrings.Contains(fileName, osUsrLib64Dir)) &&\n\t\t\tstrings.Contains(fileName, osLibSO) {\n\t\t\tlog.Debugf(\"sensor.store.saveOSLibsNetwork: match - %s\", fileName)\n\t\t\tpathMap[fileName] = struct{}{}\n\t\t}\n\t}\n\n\tallPathMap := map[string]struct{}{}\n\tfor fpath := range pathMap {\n\t\tif !fsutil.Exists(fpath) {\n\t\t\tcontinue\n\t\t}\n\n\t\tfpaths, err := resloveLink(fpath)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveOSLibsNetwork: error resolving link - %s\", fpath)\n\t\t\tcontinue\n\t\t}\n\n\t\tfpaths = append(fpaths, fpath)\n\t\tfor _, fp := range fpaths {\n\t\t\tif fp == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !fsutil.Exists(fp) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tallPathMap[fp] = struct{}{}\n\t\t\tif binProps, _ := binfile.Detected(fp); binProps != nil && binProps.IsBin {\n\t\t\t\tbinArtifacts, err := sodeps.AllDependencies(fp)\n\t\t\t\tif err != nil {\n\t\t\t\t\tif err == sodeps.ErrDepResolverNotFound {\n\t\t\t\t\t\tlog.Debug(\"sensor.store.saveOSLibsNetwork[bsa] - no static bin dep resolver\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveOSLibsNetwork[bsa] - %v - error getting bin artifacts => %v\\n\", fp, err)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfor _, bpath := range binArtifacts {\n\t\t\t\t\tbfpaths, err := resloveLink(bpath)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveOSLibsNetwork: error resolving link - %s\", bpath)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tfor _, bfp := range bfpaths {\n\t\t\t\t\t\tif bfp == \"\" {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif !fsutil.Exists(bfp) {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tallPathMap[bfp] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tlog.Debugf(\"sensor.store.saveOSLibsNetwork: - allPathMap(%v) = %+v\", len(allPathMap), allPathMap)\n\tfor fp := range allPathMap {\n\t\tif !fsutil.Exists(fp) {\n\t\t\tcontinue\n\t\t}\n\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, fp)\n\t\tif fsutil.Exists(dstPath) {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, fp, dstPath, true); err != nil {\n\t\t\tlog.Debugf(\"sensor.store.saveOSLibsNetwork: fsutil.CopyFile(%v,%v) error - %v\", fp, dstPath, err)\n\t\t}\n\t}\n}\n\nfunc resloveLink(fpath string) ([]string, error) {\n\tfinfo, err := os.Lstat(fpath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif finfo.Mode()&os.ModeSymlink == 0 {\n\t\treturn nil, nil\n\t}\n\n\tlinkRef, err := os.Readlink(fpath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar out []string\n\tvar target string\n\tif filepath.IsAbs(linkRef) {\n\t\ttarget = linkRef\n\t} else {\n\t\tlinkDir := filepath.Dir(fpath)\n\t\tfullLinkRef := filepath.Clean(filepath.Join(linkDir, linkRef))\n\t\tif fullLinkRef != \".\" {\n\t\t\ttarget = fullLinkRef\n\t\t}\n\t}\n\n\tif target != \"\" {\n\t\tout = append(out, target)\n\t\tif evalLinkRef, err := filepath.EvalSymlinks(target); err == nil {\n\t\t\tif evalLinkRef != target {\n\t\t\t\tout = append(out, evalLinkRef)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn out, nil\n}\n\nfunc (p *store) saveCertsData() {\n\tcopyCertFiles := func(list []string) {\n\t\tlog.Debugf(\"sensor.store.saveCertsData.copyCertFiles(list=%+v)\", list)\n\t\tfor _, fname := range list {\n\t\t\tif fsutil.Exists(fname) {\n\t\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, fname)\n\t\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, fname, dstPath, true); err != nil {\n\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyCertFiles: fsutil.CopyFile(%v,%v) error - %v\", fname, dstPath, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcopyDirs := func(list []string, copyLinkTargets bool) {\n\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs(list=%+v,copyLinkTargets=%v)\", list, copyLinkTargets)\n\t\tfor _, fname := range list {\n\t\t\tif fsutil.Exists(fname) {\n\t\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, fname)\n\n\t\t\t\tif fsutil.IsDir(fname) {\n\t\t\t\t\terr, errs := fsutil.CopyDir(p.cmd.KeepPerms, fname, dstPath, true, true, nil, nil, nil)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs: fsutil.CopyDir(%v,%v) error: %v\", fname, dstPath, err)\n\t\t\t\t\t} else if copyLinkTargets {\n\t\t\t\t\t\tfoList, err := os.ReadDir(fname)\n\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs(): dir=%v fcount=%v\", fname, len(foList))\n\t\t\t\t\t\t\tfor _, fo := range foList {\n\t\t\t\t\t\t\t\tfullPath := filepath.Join(fname, fo.Name())\n\t\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs(): dir=%v fullPath=%v\", fname, fullPath)\n\t\t\t\t\t\t\t\tif fsutil.IsSymlink(fullPath) {\n\t\t\t\t\t\t\t\t\tlinkRef, err := os.Readlink(fullPath)\n\t\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs: os.Readlink(%v) error - %v\", fullPath, err)\n\t\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs(): dir=%v fullPath=%v linkRef=%v\",\n\t\t\t\t\t\t\t\t\t\tfname, fullPath, linkRef)\n\t\t\t\t\t\t\t\t\tif strings.Contains(linkRef, \"/\") {\n\t\t\t\t\t\t\t\t\t\ttargetFilePath := linkTargetToFullPath(fullPath, linkRef)\n\t\t\t\t\t\t\t\t\t\tif targetFilePath != \"\" && fsutil.Exists(targetFilePath) {\n\t\t\t\t\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs(): dir=%v fullPath=%v linkRef=%v targetFilePath=%v\",\n\t\t\t\t\t\t\t\t\t\t\t\tfname, fullPath, linkRef, targetFilePath)\n\t\t\t\t\t\t\t\t\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, targetFilePath)\n\t\t\t\t\t\t\t\t\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, targetFilePath, dstPath, true); err != nil {\n\t\t\t\t\t\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs: fsutil.CopyFile(%v,%v) error - %v\", targetFilePath, dstPath, err)\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs: targetFilePath does not exist - %v\", targetFilePath)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs: os.ReadDir(%v) error - %v\", fname, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif len(errs) > 0 {\n\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs: fsutil.CopyDir(%v,%v) copy errors: %+v\", fname, dstPath, errs)\n\t\t\t\t\t}\n\t\t\t\t} else if fsutil.IsSymlink(fname) {\n\t\t\t\t\tif err := fsutil.CopySymlinkFile(p.cmd.KeepPerms, fname, dstPath, true); err != nil {\n\t\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyDirs: fsutil.CopySymlinkFile(%v,%v) error - %v\", fname, dstPath, err)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"store.saveCertsData.copyDir: unexpected obect type - %s\", fname)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tcopyAppCertFiles := func(suffix string, dirs []string, subdirPrefix string) {\n\t\t//NOTE: dirs end with \"/\" (need to revisit the formatting to make it consistent)\n\t\tlog.Debugf(\"sensor.store.saveCertsData.copyAppCertFiles(suffix=%v,dirs=%+v,subdirPrefix=%v)\",\n\t\t\tsuffix, dirs, subdirPrefix)\n\t\tfor _, dirName := range dirs {\n\t\t\tif subdirPrefix != \"\" {\n\t\t\t\tfoList, err := os.ReadDir(dirName)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyAppCertFiles: os.ReadDir(%v) error - %v\", dirName, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfor _, fo := range foList {\n\t\t\t\t\tif strings.HasPrefix(fo.Name(), subdirPrefix) {\n\t\t\t\t\t\tdirName = fmt.Sprintf(\"%s%s/\", dirName, fo.Name())\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsrcFilePath := fmt.Sprintf(\"%s%s\", dirName, suffix)\n\t\t\tif fsutil.Exists(srcFilePath) {\n\t\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, srcFilePath)\n\t\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, srcFilePath, dstPath, true); err != nil {\n\t\t\t\t\tlog.Debugf(\"sensor.store.saveCertsData.copyAppCertFiles: fsutil.CopyFile(%v,%v) error - %v\", srcFilePath, dstPath, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsetToList := func(in map[string]struct{}) []string {\n\t\tvar out []string\n\t\tfor k := range in {\n\t\t\tout = append(out, k)\n\t\t}\n\n\t\treturn out\n\t}\n\n\tif p.cmd.IncludeCertAll {\n\t\tcopyCertFiles(certdiscover.CertFileList())\n\t\tcopyCertFiles(certdiscover.CACertFileList())\n\t\t//TODO:\n\t\t//need to 'walk' these directories detecting cert files\n\t\t//and only copying those files instead of copying all files\n\t\tcopyDirs(certdiscover.CertDirList(), true)\n\t\tcopyDirs(certdiscover.CACertDirList(), true)\n\t\t//shouldn't copy the extra dirs explicitly here\n\t\t//the actual cert files should be copied through links above\n\t\tcopyDirs(certdiscover.CertExtraDirList(), false)\n\n\t\tfor _, appStack := range p.appStacks {\n\t\t\tswitch appStack.language {\n\t\t\tcase certdiscover.LanguagePython:\n\t\t\t\tcopyAppCertFiles(certdiscover.AppCertPathSuffixPython, setToList(appStack.packageDirs), \"\")\n\t\t\tcase certdiscover.LanguageNode:\n\t\t\t\tcopyAppCertFiles(certdiscover.AppCertPathSuffixNode, setToList(appStack.packageDirs), \"\")\n\t\t\tcase certdiscover.LanguageRuby:\n\t\t\t\t//ruby needs the versioned package name too <prefix>certifi-zzzzz/<suffix>\n\t\t\t\tcopyAppCertFiles(certdiscover.AppCertPathSuffixRuby,\n\t\t\t\t\tsetToList(appStack.packageDirs),\n\t\t\t\t\tcertdiscover.AppCertPackageName)\n\t\t\t\t//case certdiscover.LanguageJava:\n\t\t\t}\n\t\t}\n\t}\n\n\tif !p.cmd.IncludeCertAll && p.cmd.IncludeCertBundles {\n\t\tcopyCertFiles(certdiscover.CertFileList())\n\t\tcopyCertFiles(certdiscover.CACertFileList())\n\n\t\tfor _, appStack := range p.appStacks {\n\t\t\tswitch appStack.language {\n\t\t\tcase certdiscover.LanguagePython:\n\t\t\t\tcopyAppCertFiles(certdiscover.AppCertPathSuffixPython, setToList(appStack.packageDirs), \"\")\n\t\t\tcase certdiscover.LanguageNode:\n\t\t\t\tcopyAppCertFiles(certdiscover.AppCertPathSuffixNode, setToList(appStack.packageDirs), \"\")\n\t\t\tcase certdiscover.LanguageRuby:\n\t\t\t\t//ruby needs the versioned package name too <prefix>certifi-zzzzz/<suffix>\n\t\t\t\tcopyAppCertFiles(certdiscover.AppCertPathSuffixRuby,\n\t\t\t\t\tsetToList(appStack.packageDirs),\n\t\t\t\t\tcertdiscover.AppCertPackageName)\n\t\t\t\t//case certdiscover.LanguageJava:\n\t\t\t}\n\t\t}\n\t}\n\n\tif !p.cmd.IncludeCertAll && p.cmd.IncludeCertDirs {\n\t\tcopyDirs(certdiscover.CertDirList(), true)\n\t\tcopyDirs(certdiscover.CACertDirList(), true)\n\t\tcopyDirs(certdiscover.CertExtraDirList(), false)\n\t}\n\n\tif p.cmd.IncludeCertPKAll {\n\t\tcopyCertFiles(certdiscover.CACertPKFileList())\n\t\t//TODO:\n\t\t//need to 'walk' these directories detecting cert PK files\n\t\t//and only copying those files instead of copying all files\n\t\tcopyDirs(certdiscover.CertPKDirList(), true)\n\t\tcopyDirs(certdiscover.CACertPKDirList(), true)\n\t}\n\n\tif !p.cmd.IncludeCertPKAll && p.cmd.IncludeCertPKDirs {\n\t\tcopyDirs(certdiscover.CertPKDirList(), true)\n\t\tcopyDirs(certdiscover.CACertPKDirList(), true)\n\t}\n}\n\nfunc (p *store) saveArtifacts() {\n\tvar includePaths map[string]bool\n\tvar includeDirBinsList map[string]bool\n\tvar newPerms map[string]*fsutil.AccessInfo\n\n\tsyscall.Umask(0)\n\n\texcludePatterns := p.cmd.Excludes\n\texcludePatterns = append(excludePatterns, \"/opt/_slim\")\n\texcludePatterns = append(excludePatterns, \"/opt/_slim/**\")\n\tif p.cmd.ExcludeVarLockFiles {\n\t\texcludePatterns = append(excludePatterns, \"/var/lock/**\")\n\t\texcludePatterns = append(excludePatterns, \"/run/lock/**\")\n\t}\n\n\tlog.Debugf(\"saveArtifacts - excludePatterns(%v): %+v\", len(excludePatterns), excludePatterns)\n\n\tincludePaths = preparePaths(getKeys(p.cmd.Includes))\n\tlog.Debugf(\"saveArtifacts - includePaths(%v): %+v\", len(includePaths), includePaths)\n\n\tif includePaths == nil {\n\t\tincludePaths = map[string]bool{}\n\t}\n\n\tincludeDirBinsList = preparePaths(getKeys(p.cmd.IncludeDirBinsList))\n\tlog.Debugf(\"saveArtifacts - includeDirBinsList(%d): %+v\", len(includeDirBinsList), includeDirBinsList)\n\tif includeDirBinsList == nil {\n\t\tincludeDirBinsList = map[string]bool{}\n\t}\n\n\tnewPerms = getRecordsWithPerms(p.cmd.Includes)\n\tlog.Debugf(\"saveArtifacts - newPerms(%v): %+v\", len(newPerms), newPerms)\n\n\tfor pk, pv := range p.cmd.Perms {\n\t\tnewPerms[pk] = pv\n\t}\n\tlog.Debugf(\"saveArtifacts - merged newPerms(%v): %+v\", len(newPerms), newPerms)\n\n\t//moved to prepareEnv\n\t//dstRootPath := filepath.Join(p.storeLocation, app.ArtifactFilesDirName)\n\t//log.Debugf(\"saveArtifacts - prep file artifacts root dir - '%s'\", dstRootPath)\n\t//err := os.MkdirAll(dstRootPath, 0777)\n\t//errutil.FailOn(err)\n\n\textraDirs := map[string]struct{}{}\n\tsymlinkFailed := map[string]*report.ArtifactProps{}\n\n\tlog.Debugf(\"saveArtifacts - copy links (%v)\", len(p.linkMap))\n\t//copyLinks:\n\t//NOTE: MUST copy the links FIRST, so the dir symlinks get created before their files are copied\n\tsymlinkMap := radix.New()\n\tfor linkName, linkProps := range p.linkMap {\n\t\tsymlinkMap.Insert(linkName, linkProps)\n\t}\n\n\tsymlinkWalk := func(linkName string, val interface{}) bool {\n\t\tlinkProps, ok := val.(*report.ArtifactProps)\n\t\tif !ok {\n\t\t\tlog.Debugf(\"saveArtifacts.symlinkWalk: could not convert data - %s\\n\", linkName)\n\t\t\treturn false\n\t\t}\n\n\t\tfor _, xpattern := range excludePatterns {\n\t\t\tfound, err := doublestar.Match(xpattern, linkName)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts.symlinkWalk - copy links - [%v] excludePatterns Match error - %v\\n\", linkName, err)\n\t\t\t\t//should only happen when the pattern is malformed\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tlog.Debugf(\"saveArtifacts.symlinkWalk - copy links - [%v] - excluding (%s) \", linkName, xpattern)\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t//TODO: review\n\t\tlinkPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, linkName)\n\t\tlinkDir := fsutil.FileDir(linkPath)\n\t\t//NOTE:\n\t\t//The symlink target dir might not exist, which means\n\t\t//the dir create calls that start with the current symlink prefix will fail.\n\t\t//We'll save the failed links to try again\n\t\t//later when the symlink target is already created.\n\t\t//Another option is to create the symlink targets,\n\t\t//but it might be tricky if the target is a symlink (potentially to another symlink, etc)\n\n\t\t//log.Debugf(\"saveArtifacts.symlinkWalk - saving symlink - create subdir: linkName=%s linkDir=%s linkPath=%s\", linkName, linkDir, linkPath)\n\t\terr := os.MkdirAll(linkDir, 0777)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"saveArtifacts.symlinkWalk - dir error (linkName=%s linkDir=%s linkPath=%s) => error=%v\", linkName, linkDir, linkPath, err)\n\t\t\t//save it and try again later\n\t\t\tsymlinkFailed[linkName] = linkProps\n\t\t\treturn false\n\t\t}\n\n\t\tif linkProps != nil &&\n\t\t\tlinkProps.FSActivity != nil &&\n\t\t\tlinkProps.FSActivity.OpsCheckFile > 0 {\n\t\t\tlog.Debug(\"saveArtifacts.symlinkWalk - saving 'checked' symlink => \", linkName)\n\t\t}\n\n\t\t//log.Debugf(\"saveArtifacts.symlinkWalk - saving symlink: name=%s target=%s\", linkName, linkProps.LinkRef)\n\t\terr = os.Symlink(linkProps.LinkRef, linkPath)\n\t\tif err != nil {\n\t\t\tif os.IsExist(err) {\n\t\t\t\tlog.Debug(\"saveArtifacts.symlinkWalk - symlink already exists\")\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"saveArtifacts.symlinkWalk - symlink create error: %v\", err)\n\t\t\t}\n\t\t}\n\n\t\treturn false\n\t}\n\n\tsymlinkMap.Walk(symlinkWalk)\n\n\tfor linkName, linkProps := range symlinkFailed {\n\t\tlinkPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, linkName)\n\t\tlinkDir := fsutil.FileDir(linkPath)\n\n\t\t//log.Debugf(\"saveArtifacts.symlinkFailed - saving symlink - create subdir: linkName=%s linkDir=%s linkPath=%s\", linkName, linkDir, linkPath)\n\t\terr := os.MkdirAll(linkDir, 0777)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"saveArtifacts.symlinkFailed - dir error (linkName=%s linkDir=%s linkPath=%s) => error=%v\", linkName, linkDir, linkPath, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tif linkProps != nil &&\n\t\t\tlinkProps.FSActivity != nil &&\n\t\t\tlinkProps.FSActivity.OpsCheckFile > 0 {\n\t\t\tlog.Debug(\"saveArtifacts.symlinkFailed - saving 'checked' symlink => \", linkName)\n\t\t}\n\n\t\t//log.Debugf(\"saveArtifacts.symlinkFailed - saving symlink: name=%s target=%s\", linkName, linkProps.LinkRef)\n\n\t\terr = os.Symlink(linkProps.LinkRef, linkPath)\n\t\tif err != nil {\n\t\t\tif os.IsExist(err) {\n\t\t\t\tlog.Debug(\"saveArtifacts.symlinkFailed - symlink already exists\")\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"saveArtifacts.symlinkFailed - symlink create error ==> %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\t//NOTE: need to copy the files after the links are copied\n\tlog.Debugf(\"saveArtifacts - copy files (%v) and copy additional files checked at runtime...\", len(p.fileMap))\n\tngxEnsured := false\n\ncopyFiles:\n\tfor srcFileName, artifactInfo := range p.fileMap {\n\t\t//need to make sure we don't filter out something we need\n\t\tif artifact.IsFilteredPath(srcFileName) {\n\t\t\tlog.Debugf(\"saveArtifacts - skipping filtered copy file - %s\", srcFileName)\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, xpattern := range excludePatterns {\n\t\t\tfound, err := doublestar.Match(xpattern, srcFileName)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - copy files - [%v] excludePatterns Match error - %v\\n\", srcFileName, err)\n\t\t\t\t//should only happen when the pattern is malformed\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tlog.Debugf(\"saveArtifacts - copy files - [%v] - excluding (%s) \", srcFileName, xpattern)\n\t\t\t\tcontinue copyFiles\n\t\t\t}\n\t\t}\n\n\t\t//filter out pid files (todo: have a flag to enable/disable these capabilities)\n\t\tif isKnownPidFilePath(srcFileName) {\n\t\t\tlog.Debugf(\"saveArtifacts - copy files - skipping known pid file (%v)\", srcFileName)\n\t\t\textraDirs[fsutil.FileDir(srcFileName)] = struct{}{}\n\t\t\tcontinue\n\t\t}\n\n\t\tif hasPidFileSuffix(srcFileName) {\n\t\t\tlog.Debugf(\"saveArtifacts - copy files - skipping a pid file (%v)\", srcFileName)\n\t\t\textraDirs[fsutil.FileDir(srcFileName)] = struct{}{}\n\t\t\tcontinue\n\t\t}\n\n\t\tfilePath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, srcFileName)\n\t\tlog.Debug(\"saveArtifacts - saving file data => \", filePath)\n\n\t\tif artifactInfo != nil &&\n\t\t\tartifactInfo.FSActivity != nil &&\n\t\t\tartifactInfo.FSActivity.OpsCheckFile > 0 {\n\t\t\tlog.Debugf(\"saveArtifacts - saving 'checked' file => %v\", srcFileName)\n\t\t\t//NOTE: later have an option to save 'checked' only files without data\n\t\t}\n\n\t\tif p.cmd.ObfuscateMetadata {\n\t\t\tif isAppMetadataFile(srcFileName) {\n\t\t\t\tlog.Tracef(\"saveArtifacts - isAppMetadataFile - src(%s)->dst(%s)\", srcFileName, filePath)\n\t\t\t\terr := fsutil.CopyAndObfuscateFile(p.cmd.KeepPerms, srcFileName, filePath, true)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts [%s,%s] - error saving file => %v\", srcFileName, filePath, err)\n\t\t\t\t}\n\n\t\t\t\tif err := appMetadataFileUpdater(filePath); err != nil {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts [%s,%s] - appMetadataFileUpdater => not updated / err = %v\", srcFileName, filePath, err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr := fsutil.CopyRegularFile(p.cmd.KeepPerms, srcFileName, filePath, true)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts [%s,%s] - error saving file => %v\", srcFileName, filePath, err)\n\t\t\t\t} else {\n\t\t\t\t\t//NOTE: this covers the main file set (doesn't cover the extra includes)\n\t\t\t\t\tbinProps, err := binfile.Detected(filePath)\n\t\t\t\t\tif err == nil && binProps != nil && binProps.IsBin && binProps.IsExe {\n\t\t\t\t\t\tif err := fsutil.AppendToFile(filePath, []byte(\"KCQ\"), true); err != nil {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts [%s,%s] - fsutil.AppendToFile error => %v\", srcFileName, filePath, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts - binfile.Detected[IsExe]/fsutil.AppendToFile - %s\", filePath)\n\n\t\t\t\t\t\t\terr := fsutil.ReplaceFileData(filePath, binDataReplace, true)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts [%s,%s] - fsutil.ReplaceFileData error => %v\", srcFileName, filePath, err)\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} else {\n\t\t\terr := fsutil.CopyRegularFile(p.cmd.KeepPerms, srcFileName, filePath, true)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - error saving file => %v\", err)\n\t\t\t}\n\t\t}\n\n\t\t///////////////////\n\t\tfileName := srcFileName\n\t\tp.detectAppStack(fileName)\n\n\t\tif p.cmd.IncludeAppNuxtDir ||\n\t\t\tp.cmd.IncludeAppNuxtBuildDir ||\n\t\t\tp.cmd.IncludeAppNuxtDistDir ||\n\t\t\tp.cmd.IncludeAppNuxtStaticDir ||\n\t\t\tp.cmd.IncludeAppNuxtNodeModulesDir {\n\t\t\tif isNuxtConfigFile(fileName) {\n\t\t\t\tnuxtConfig, err := getNuxtConfig(fileName)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts: failed to get nuxt config: %v\", err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif nuxtConfig == nil {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts: nuxt config not found: %v\", fileName)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t//note:\n\t\t\t\t//Nuxt config file is usually in the app directory, but not always\n\t\t\t\t//cust app path is defined with the \"srcDir\" field in the Nuxt config file\n\t\t\t\tnuxtAppDir := filepath.Dir(fileName)\n\t\t\t\tnuxtAppDirPrefix := fmt.Sprintf(\"%s/\", nuxtAppDir)\n\t\t\t\tif p.cmd.IncludeAppNuxtDir {\n\t\t\t\t\tincludePaths[nuxtAppDir] = true\n\t\t\t\t\tlog.Tracef(\"saveArtifacts[nuxt] - including app dir - %s\", nuxtAppDir)\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNuxtStaticDir {\n\t\t\t\t\tsrcPath := filepath.Join(nuxtAppDir, nuxtStaticDir)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNuxtDir && strings.HasPrefix(srcPath, nuxtAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - static dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[nuxt] - including static dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - static dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNuxtBuildDir && nuxtConfig.Build != \"\" {\n\t\t\t\t\tbasePath := nuxtAppDir\n\t\t\t\t\tif strings.HasPrefix(nuxtConfig.Build, \"/\") {\n\t\t\t\t\t\tbasePath = \"\"\n\t\t\t\t\t}\n\n\t\t\t\t\tsrcPath := filepath.Join(basePath, nuxtConfig.Build)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNuxtDir && strings.HasPrefix(srcPath, nuxtAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - build dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[nuxt] - including build dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - build dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNuxtDistDir && nuxtConfig.Dist != \"\" {\n\t\t\t\t\tbasePath := nuxtAppDir\n\t\t\t\t\tif strings.HasPrefix(nuxtConfig.Dist, \"/\") {\n\t\t\t\t\t\tbasePath = \"\"\n\t\t\t\t\t}\n\n\t\t\t\t\tsrcPath := filepath.Join(basePath, nuxtConfig.Dist)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNuxtDir && strings.HasPrefix(srcPath, nuxtAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - dist dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[nuxt] - including dist dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - dist dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNuxtNodeModulesDir {\n\t\t\t\t\tsrcPath := filepath.Join(nuxtAppDir, nodePackageDirName)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNuxtDir && strings.HasPrefix(srcPath, nuxtAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - node_modules dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[nuxt] - including node_modules dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[nuxt] - node_modules dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif p.cmd.IncludeAppNextDir ||\n\t\t\tp.cmd.IncludeAppNextBuildDir ||\n\t\t\tp.cmd.IncludeAppNextDistDir ||\n\t\t\tp.cmd.IncludeAppNextStaticDir ||\n\t\t\tp.cmd.IncludeAppNextNodeModulesDir {\n\t\t\tif isNextConfigFile(fileName) {\n\t\t\t\tnextAppDir := filepath.Dir(fileName)\n\t\t\t\tnextAppDirPrefix := fmt.Sprintf(\"%s/\", nextAppDir)\n\t\t\t\tif p.cmd.IncludeAppNextDir {\n\t\t\t\t\tincludePaths[nextAppDir] = true\n\t\t\t\t\tlog.Tracef(\"saveArtifacts[next] - including app dir - %s\", nextAppDir)\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNextStaticDir {\n\t\t\t\t\tsrcPath := filepath.Join(nextAppDir, nextStaticDir)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNextDir && strings.HasPrefix(srcPath, nextAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - static public dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[next] - including static public dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - static public dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNextBuildDir {\n\t\t\t\t\tsrcPath := filepath.Join(nextAppDir, nextDefaultBuildDir)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNextDir && strings.HasPrefix(srcPath, nextAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - build dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[next] - including build dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - build dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNextDistDir {\n\t\t\t\t\tsrcPath := filepath.Join(nextAppDir, nextDefaultStaticSpaDir)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNextDir && strings.HasPrefix(srcPath, nextAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - dist dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[next] - including dist dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - dist dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif p.cmd.IncludeAppNextNodeModulesDir {\n\t\t\t\t\tsrcPath := filepath.Join(nextAppDir, nodePackageDirName)\n\t\t\t\t\tif fsutil.DirExists(srcPath) {\n\t\t\t\t\t\tif p.cmd.IncludeAppNextDir && strings.HasPrefix(srcPath, nextAppDirPrefix) {\n\t\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - node_modules dir is already included (%s)\", srcPath)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tincludePaths[srcPath] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[next] - including node_modules dir - %s\", srcPath)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts[next] - node_modules dir does not exists (%s)\", srcPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif isRbGemSpecFile(fileName) {\n\t\t\tlog.Debug(\"saveArtifacts - processing ruby gem spec ==>\", fileName)\n\t\t\terr := rbEnsureGemFiles(fileName, p.storeLocation, \"/files\")\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - error ensuring ruby gem files => %v\", err)\n\t\t\t}\n\t\t} else if isNodePackageFile(fileName) {\n\t\t\tlog.Debug(\"saveArtifacts - processing node package file ==>\", fileName)\n\t\t\terr := nodeEnsurePackageFiles(p.cmd.KeepPerms, fileName, p.storeLocation, \"/files\")\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - error ensuring node package files => %v\", err)\n\t\t\t}\n\n\t\t\tif len(p.cmd.IncludeNodePackages) > 0 {\n\t\t\t\tnodePackageInfo, err := getNodePackageFileData(fileName)\n\t\t\t\tif err == nil && nodePackageInfo != nil {\n\t\t\t\t\tfor _, pkgName := range p.cmd.IncludeNodePackages {\n\t\t\t\t\t\t//note: use a better match lookup and include package version match later (\":\" as separator)\n\t\t\t\t\t\tif pkgName != \"\" && pkgName == nodePackageInfo.Name {\n\t\t\t\t\t\t\tnodeAppDir := filepath.Dir(fileName)\n\t\t\t\t\t\t\tincludePaths[nodeAppDir] = true\n\t\t\t\t\t\t\tlog.Tracef(\"saveArtifacts[node] - including app(%s) dir - %s\", nodePackageInfo.Name, nodeAppDir)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts - error getting node package config file => %v\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else if isNgxArtifact(fileName) && !ngxEnsured {\n\t\t\tlog.Debug(\"saveArtifacts - ensuring ngx artifacts....\")\n\t\t\tngxEnsure(p.storeLocation)\n\t\t\tngxEnsured = true\n\t\t} else {\n\t\t\terr := fixPy3CacheFile(fileName, filePath)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - error fixing py3 cache file => %v\", err)\n\t\t\t}\n\t\t}\n\t\t///////////////////\n\t}\n\n\tlog.Debugf(\"saveArtifacts[bsa] - copy files (%v)\", len(p.saFileMap))\ncopyBsaFiles:\n\tfor srcFileName := range p.saFileMap {\n\t\tfor _, xpattern := range excludePatterns {\n\t\t\tfound, err := doublestar.Match(xpattern, srcFileName)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts[bsa] - copy files - [%v] excludePatterns Match error - %v\\n\", srcFileName, err)\n\t\t\t\t//should only happen when the pattern is malformed\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tlog.Debugf(\"saveArtifacts[bsa] - copy files - [%v] - excluding (%s) \", srcFileName, xpattern)\n\t\t\t\tcontinue copyBsaFiles\n\t\t\t}\n\t\t}\n\n\t\tdstFilePath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, srcFileName)\n\t\tlog.Debug(\"saveArtifacts[bsa] - saving file data => \", dstFilePath)\n\t\tif fsutil.Exists(dstFilePath) {\n\t\t\t//we might already have the target file\n\t\t\t//when we have intermediate symlinks in the path\n\t\t\tlog.Debugf(\"saveArtifacts[bsa] - target file already exists (%s)\", dstFilePath)\n\t\t} else {\n\t\t\tif p.cmd.ObfuscateMetadata && isAppMetadataFile(srcFileName) {\n\t\t\t\terr := fsutil.CopyAndObfuscateFile(p.cmd.KeepPerms, srcFileName, dstFilePath, true)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts[bsa] - error saving file => %v\", err)\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts[bsa] - saved file (%s)\", dstFilePath)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr := fsutil.CopyRegularFile(p.cmd.KeepPerms, srcFileName, dstFilePath, true)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts[bsa] - error saving file => %v\", err)\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts[bsa] - saved file (%s)\", dstFilePath)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t//was conditional: if p.cmd.AppUser != \"\"\n\t//NOTE:\n\t//we may need the user info even if the caller didn't explicitly indicated it\n\t//makes this conditional again when/if we can fully analyze the target app(s)\n\t//to understand if it really needs the user info from the system\n\tcopyBasicUserInfo := func() {\n\t\t//always copy the '/etc/passwd' file when we have a user\n\t\t//later: do it only when AppUser is a name (not UID)\n\t\tdstPasswdFilePath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, sysidentity.PasswdFilePath)\n\t\tif _, err := os.Stat(sysidentity.PasswdFilePath); err == nil {\n\t\t\t//if err := cpFile(passwdFilePath, passwdFileTargetPath); err != nil {\n\t\t\tif err := fsutil.CopyRegularFile(p.cmd.KeepPerms, sysidentity.PasswdFilePath, dstPasswdFilePath, true); err != nil {\n\t\t\t\tlog.Debugf(\"sensor: monitor - error copying user info file => %v\", err)\n\t\t\t}\n\t\t} else {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tlog.Debug(\"sensor: monitor - no user info file\")\n\t\t\t} else {\n\t\t\t\tlog.Debug(\"sensor: monitor - could not save user info file =>\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tcopyBasicUserInfo()\n\ncopyIncludes:\n\tfor inPath, isDir := range includePaths {\n\t\tif artifact.IsFilteredPath(inPath) {\n\t\t\tlog.Debugf(\"saveArtifacts - skipping filtered include path [isDir=%v] %s\", isDir, inPath)\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, xpattern := range excludePatterns {\n\t\t\tfound, err := doublestar.Match(xpattern, inPath)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - copy includes - [%v] excludePatterns Match error - %v\\n\", inPath, err)\n\t\t\t\t//should only happen when the pattern is malformed\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tlog.Debugf(\"saveArtifacts - copy includes - [%v] - excluding (%s) \", inPath, xpattern)\n\t\t\t\tcontinue copyIncludes\n\t\t\t}\n\t\t}\n\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, inPath)\n\t\tif isDir {\n\t\t\terr, errs := fsutil.CopyDir(p.cmd.KeepPerms, inPath, dstPath, true, true, excludePatterns, nil, nil)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"CopyDir(%v,%v) error: %v\", inPath, dstPath, err)\n\t\t\t}\n\n\t\t\tif len(errs) > 0 {\n\t\t\t\tlog.Debugf(\"CopyDir(%v,%v) copy errors: %+v\", inPath, dstPath, errs)\n\t\t\t}\n\t\t} else {\n\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, inPath, dstPath, true); err != nil {\n\t\t\t\tlog.Debugf(\"CopyFile(%v,%v) error: %v\", inPath, dstPath, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, exePath := range p.cmd.IncludeExes {\n\t\texeArtifacts, err := sodeps.AllExeDependencies(exePath, true)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"saveArtifacts - %v - error getting exe artifacts => %v\", exePath, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Debugf(\"saveArtifacts - include exe [%s]: artifacts (%d):\\n%v\\n\",\n\t\t\texePath, len(exeArtifacts), strings.Join(exeArtifacts, \"\\n\"))\n\n\t\tfor _, apath := range exeArtifacts {\n\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, apath)\n\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, apath, dstPath, true); err != nil {\n\t\t\t\tlog.Debugf(\"CopyFile(%v,%v) error: %v\", apath, dstPath, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tbinPathMap := map[string]struct{}{}\n\tfor _, binPath := range p.cmd.IncludeBins {\n\t\tbinPathMap[binPath] = struct{}{}\n\t}\n\naddExtraBinIncludes:\n\tfor inPath, isDir := range includeDirBinsList {\n\t\tif !isDir {\n\t\t\tlog.Debugf(\"saveArtifacts - skipping non-directory in includeDirBinsList - %s\", inPath)\n\t\t\tcontinue\n\t\t}\n\n\t\tif artifact.IsFilteredPath(inPath) {\n\t\t\tlog.Debugf(\"saveArtifacts - skipping filtered path in includeDirBinsList - %s\", inPath)\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, xpattern := range excludePatterns {\n\t\t\tfound, err := doublestar.Match(xpattern, inPath)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - includeDirBinsList - [%s] excludePatterns Match error - %v\\n\", inPath, err)\n\t\t\t\t//should only happen when the pattern is malformed\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tlog.Debugf(\"saveArtifacts - includeDirBinsList - [%s] - excluding (%s) \", inPath, xpattern)\n\t\t\t\tcontinue addExtraBinIncludes\n\t\t\t}\n\t\t}\n\n\t\terr := filepath.Walk(inPath,\n\t\t\tfunc(pth string, info os.FileInfo, err error) error {\n\t\t\t\tif strings.HasPrefix(pth, \"/proc/\") {\n\t\t\t\t\tlog.Debugf(\"skipping /proc file system objects... - '%s'\", pth)\n\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t}\n\n\t\t\t\tif strings.HasPrefix(pth, \"/sys/\") {\n\t\t\t\t\tlog.Debugf(\"skipping /sys file system objects... - '%s'\", pth)\n\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t}\n\n\t\t\t\tif strings.HasPrefix(pth, \"/dev/\") {\n\t\t\t\t\tlog.Debugf(\"skipping /dev file system objects... - '%s'\", pth)\n\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t}\n\n\t\t\t\t// Optimization: Exclude folders early on to prevent slow enumerat\n\t\t\t\t//               Can help with mounting big folders from the host.\n\t\t\t\t// TODO: Combine this logic with the similar logic in findSymlinks().\n\t\t\t\tfor _, xpattern := range excludePatterns {\n\t\t\t\t\tif match, _ := doublestar.Match(xpattern, pth); match {\n\t\t\t\t\t\tif info.Mode().IsDir() {\n\t\t\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"skipping %s with error: %v\", pth, err)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tif !info.Mode().IsRegular() {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tpth, err = filepath.Abs(pth)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tif strings.HasPrefix(pth, \"/proc/\") ||\n\t\t\t\t\tstrings.HasPrefix(pth, \"/sys/\") ||\n\t\t\t\t\tstrings.HasPrefix(pth, \"/dev/\") {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\tif binProps, _ := binfile.Detected(pth); binProps != nil && binProps.IsBin {\n\t\t\t\t\tbinPathMap[pth] = struct{}{}\n\t\t\t\t}\n\n\t\t\t\treturn nil\n\t\t\t})\n\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"saveArtifacts - error enumerating includeDirBinsList dir (%s) - %v\", inPath, err)\n\t\t}\n\t}\n\ncopyBinIncludes:\n\tfor binPath := range binPathMap {\n\t\tif artifact.IsFilteredPath(binPath) {\n\t\t\tlog.Debugf(\"saveArtifacts - skipping filtered include bin - %s\", binPath)\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, xpattern := range excludePatterns {\n\t\t\tfound, err := doublestar.Match(xpattern, binPath)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - copy bin includes - [%v] excludePatterns Match error - %v\\n\", binPath, err)\n\t\t\t\t//should only happen when the pattern is malformed\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tlog.Debugf(\"saveArtifacts - copy bin includes - [%v] - excluding (%s) \", binPath, xpattern)\n\t\t\t\tcontinue copyBinIncludes\n\t\t\t}\n\t\t}\n\n\t\tbinArtifacts, err := sodeps.AllDependencies(binPath)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"saveArtifacts - %v - error getting bin artifacts => %v\", binPath, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tlog.Debugf(\"saveArtifacts - include bin [%s]: artifacts (%d):\\n%v\",\n\t\t\tbinPath, len(binArtifacts), strings.Join(binArtifacts, \"\\n\"))\n\n\t\tfor _, bpath := range binArtifacts {\n\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, bpath)\n\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, bpath, dstPath, true); err != nil {\n\t\t\t\tlog.Debugf(\"CopyFile(%v,%v) error: %v\", bpath, dstPath, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif p.cmd.IncludeShell {\n\t\tshellArtifacts, err := shellDependencies()\n\t\tif err == nil {\n\t\t\tlog.Debugf(\"saveArtifacts - include shell: artifacts (%d):\\n%v\\n\",\n\t\t\t\tlen(shellArtifacts), strings.Join(shellArtifacts, \"\\n\"))\n\n\t\t\tfor _, spath := range shellArtifacts {\n\t\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, spath)\n\t\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, spath, dstPath, true); err != nil {\n\t\t\t\t\tlog.Debugf(\"CopyFile(%v,%v) error: %v\", spath, dstPath, err)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debugf(\"saveArtifacts - error getting shell artifacts => %v\", err)\n\t\t}\n\n\t}\n\n\tp.saveWorkdir(excludePatterns)\n\n\tp.saveSSHClient()\n\tp.saveOSLibsNetwork()\n\tp.saveCertsData()\n\tp.saveZoneInfo()\n\n\tif fsutil.DirExists(\"/tmp\") {\n\t\ttdTargetPath := fmt.Sprintf(\"%s/files/tmp\", p.storeLocation)\n\t\tif !fsutil.DirExists(tdTargetPath) {\n\t\t\tif err := os.MkdirAll(tdTargetPath, os.ModeSticky|os.ModeDir|0777); err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - error creating tmp directory => %v\", err)\n\t\t\t}\n\t\t} else {\n\t\t\tif err := os.Chmod(tdTargetPath, os.ModeSticky|os.ModeDir|0777); err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - error setting tmp directory permission ==> %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif fsutil.DirExists(\"/run\") {\n\t\ttdTargetPath := fmt.Sprintf(\"%s/files/run\", p.storeLocation)\n\t\tif !fsutil.DirExists(tdTargetPath) {\n\t\t\t//should use perms from source\n\t\t\tif err := os.MkdirAll(tdTargetPath, 0755); err != nil {\n\t\t\t\tlog.Debugf(\"saveArtifacts - error creating run directory => %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tfor extraDir := range extraDirs {\n\t\ttdTargetPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, extraDir)\n\t\tif fsutil.DirExists(extraDir) && !fsutil.DirExists(tdTargetPath) {\n\t\t\tif err := fsutil.CopyDirOnly(p.cmd.KeepPerms, extraDir, tdTargetPath); err != nil {\n\t\t\t\tlog.Debugf(\"CopyDirOnly(%v,%v) error: %v\", extraDir, tdTargetPath, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tfor inPath, perms := range newPerms {\n\t\tdstPath := fmt.Sprintf(\"%s/files%s\", p.storeLocation, inPath)\n\t\tif fsutil.Exists(dstPath) {\n\t\t\tif err := fsutil.SetAccess(dstPath, perms); err != nil {\n\t\t\t\tlog.Debugf(\"SetPerms(%v,%v) error: %v\", dstPath, perms, err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(p.cmd.Preserves) > 0 {\n\t\tlog.Debugf(\"saveArtifacts: restoring preserved paths - %d\", len(p.cmd.Preserves))\n\n\t\tpreservedDirPath := filepath.Join(p.storeLocation, preservedDirName)\n\t\tif fsutil.Exists(preservedDirPath) {\n\t\t\tfilesDirPath := filepath.Join(p.storeLocation, app.ArtifactFilesDirName)\n\t\t\tpreservePaths := preparePaths(getKeys(p.cmd.Preserves))\n\t\t\tfor inPath, isDir := range preservePaths {\n\t\t\t\tif artifact.IsFilteredPath(inPath) {\n\t\t\t\t\tlog.Debugf(\"saveArtifacts: skipping filtered preserved path [isDir=%v] %s\", isDir, inPath)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tsrcPath := fmt.Sprintf(\"%s%s\", preservedDirPath, inPath)\n\t\t\t\tdstPath := fmt.Sprintf(\"%s%s\", filesDirPath, inPath)\n\n\t\t\t\tif isDir {\n\t\t\t\t\terr, errs := fsutil.CopyDir(p.cmd.KeepPerms, srcPath, dstPath, true, true, nil, nil, nil)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts.CopyDir(%v,%v) error: %v\", srcPath, dstPath, err)\n\t\t\t\t\t}\n\n\t\t\t\t\tif len(errs) > 0 {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts.CopyDir(%v,%v) copy errors: %+v\", srcPath, dstPath, errs)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif err := fsutil.CopyFile(p.cmd.KeepPerms, srcPath, dstPath, true); err != nil {\n\t\t\t\t\t\tlog.Debugf(\"saveArtifacts.CopyFile(%v,%v) error: %v\", srcPath, dstPath, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debug(\"saveArtifacts(): preserved root path doesnt exist\")\n\t\t}\n\t}\n}\n\nfunc (p *store) detectAppStack(fileName string) {\n\tisPython := detectPythonCodeFile(fileName)\n\tif isPython {\n\t\tappStack, ok := p.appStacks[certdiscover.LanguagePython]\n\t\tif !ok {\n\t\t\tappStack = &appStackInfo{\n\t\t\t\tlanguage:    certdiscover.LanguagePython,\n\t\t\t\tpackageDirs: map[string]struct{}{},\n\t\t\t}\n\n\t\t\tp.appStacks[certdiscover.LanguagePython] = appStack\n\t\t}\n\n\t\tappStack.codeFiles++\n\t}\n\n\tpyPkgDir := detectPythonPkgDir(fileName)\n\tif pyPkgDir != \"\" {\n\t\tappStack, ok := p.appStacks[certdiscover.LanguagePython]\n\t\tif !ok {\n\t\t\tappStack = &appStackInfo{\n\t\t\t\tlanguage:    certdiscover.LanguagePython,\n\t\t\t\tpackageDirs: map[string]struct{}{},\n\t\t\t}\n\n\t\t\tp.appStacks[certdiscover.LanguagePython] = appStack\n\t\t}\n\n\t\tappStack.packageDirs[pyPkgDir] = struct{}{}\n\t}\n\n\tif isPython || pyPkgDir != \"\" {\n\t\treturn\n\t}\n\n\tisRuby := detectRubyCodeFile(fileName)\n\tif isRuby {\n\t\tappStack, ok := p.appStacks[certdiscover.LanguageRuby]\n\t\tif !ok {\n\t\t\tappStack = &appStackInfo{\n\t\t\t\tlanguage:    certdiscover.LanguageRuby,\n\t\t\t\tpackageDirs: map[string]struct{}{},\n\t\t\t}\n\n\t\t\tp.appStacks[certdiscover.LanguageRuby] = appStack\n\t\t}\n\n\t\tappStack.codeFiles++\n\t}\n\n\trbPkgDir := detectRubyPkgDir(fileName)\n\tif rbPkgDir != \"\" {\n\t\tappStack, ok := p.appStacks[certdiscover.LanguageRuby]\n\t\tif !ok {\n\t\t\tappStack = &appStackInfo{\n\t\t\t\tlanguage:    certdiscover.LanguageRuby,\n\t\t\t\tpackageDirs: map[string]struct{}{},\n\t\t\t}\n\n\t\t\tp.appStacks[certdiscover.LanguageRuby] = appStack\n\t\t}\n\n\t\tappStack.packageDirs[rbPkgDir] = struct{}{}\n\t}\n\n\tif isRuby || rbPkgDir != \"\" {\n\t\treturn\n\t}\n\n\tisNode := detectNodeCodeFile(fileName)\n\tif isNode {\n\t\tappStack, ok := p.appStacks[certdiscover.LanguageNode]\n\t\tif !ok {\n\t\t\tappStack = &appStackInfo{\n\t\t\t\tlanguage:    certdiscover.LanguageNode,\n\t\t\t\tpackageDirs: map[string]struct{}{},\n\t\t\t}\n\n\t\t\tp.appStacks[certdiscover.LanguageNode] = appStack\n\t\t}\n\n\t\tappStack.codeFiles++\n\t}\n\n\tnodePkgDir := detectNodePkgDir(fileName)\n\tif nodePkgDir != \"\" {\n\t\tappStack, ok := p.appStacks[certdiscover.LanguageNode]\n\t\tif !ok {\n\t\t\tappStack = &appStackInfo{\n\t\t\t\tlanguage:    certdiscover.LanguageNode,\n\t\t\t\tpackageDirs: map[string]struct{}{},\n\t\t\t}\n\n\t\t\tp.appStacks[certdiscover.LanguageNode] = appStack\n\t\t}\n\n\t\tappStack.packageDirs[nodePkgDir] = struct{}{}\n\t}\n}\n\nfunc isFileExt(filePath, match string) bool {\n\tfileExt := filepath.Ext(filePath)\n\treturn fileExt == match\n}\n\nfunc getPathElementPrefix(filePath, match string) string {\n\tif !strings.Contains(filePath, match) {\n\t\treturn \"\"\n\t}\n\n\tparts := strings.Split(filePath, match)\n\tif len(parts) > 0 {\n\t\treturn parts[0]\n\t}\n\n\treturn \"\"\n}\n\nfunc getPathElementPrefixLast(filePath, match string) string {\n\tif !strings.Contains(filePath, match) {\n\t\treturn \"\"\n\t}\n\n\tif idx := strings.LastIndex(filePath, match); idx != -1 {\n\t\treturn filePath[0:idx]\n\t}\n\n\treturn \"\"\n}\n\nfunc detectPythonCodeFile(fileName string) bool {\n\treturn isFileExt(fileName, pySrcFileExt)\n}\n\nfunc detectPythonPkgDir(fileName string) string {\n\tdpPrefix := getPathElementPrefix(fileName, pyDistPkgDir)\n\tif dpPrefix != \"\" {\n\t\treturn fmt.Sprintf(\"%s%s\", dpPrefix, pyDistPkgDir)\n\t}\n\n\tspPrefix := getPathElementPrefix(fileName, pySitePkgDir)\n\tif spPrefix != \"\" {\n\t\treturn fmt.Sprintf(\"%s%s\", spPrefix, pySitePkgDir)\n\t}\n\n\treturn \"\"\n}\n\nfunc detectRubyCodeFile(fileName string) bool {\n\treturn isFileExt(fileName, rbSrcFileExt)\n}\n\nfunc detectRubyPkgDir(fileName string) string {\n\tprefix := getPathElementPrefixLast(fileName, rbGemsSubDir)\n\tif prefix != \"\" {\n\t\treturn fmt.Sprintf(\"%s%s\", prefix, rbGemsSubDir)\n\t}\n\n\treturn \"\"\n}\n\nfunc detectNodeCodeFile(fileName string) bool {\n\treturn isFileExt(fileName, nodeSrcFileExt)\n}\n\nfunc detectNodePkgDir(fileName string) string {\n\tprefix := getPathElementPrefix(fileName, nodePackageDirPath)\n\tif prefix != \"\" {\n\t\treturn fmt.Sprintf(\"%s%s\", prefix, nodePackageDirPath)\n\t}\n\n\treturn \"\"\n}\n\nfunc (p *store) archiveArtifacts() error {\n\tlogger := log.WithField(\"op\", \"store.archiveArtifacts\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tsrc := filepath.Join(p.storeLocation, app.ArtifactFilesDirName)\n\tdst := filepath.Join(p.storeLocation, filesArchiveName)\n\tlogger.Debugf(\"src='%s' dst='%s'\", src, dst)\n\n\ttrimPrefix := fmt.Sprintf(\"%s/\", src)\n\treturn fsutil.ArchiveDir(dst, src, trimPrefix, \"\")\n}\n\n// Go over all saved artifacts and update the name list to make\n// sure all the files & folders are reflected in the final report.\n// Hopefully, just a temporary workaround until a proper refactoring.\nfunc (p *store) enumerateArtifacts() {\n\tlogger := log.WithField(\"op\", \"store.enumerateArtifacts\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tknownFiles := list2map(p.nameList)\n\tartifactFilesDir := filepath.Join(p.storeLocation, app.ArtifactFilesDirName)\n\n\tvar curpath string\n\tdirqueue := []string{artifactFilesDir}\n\tfor len(dirqueue) > 0 {\n\t\tcurpath, dirqueue = dirqueue[0], dirqueue[1:]\n\n\t\tentries, err := os.ReadDir(curpath)\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Debugf(\"os.ReadDir(%s)\", curpath)\n\t\t\t// Keep processing though since it might have been a partial result.\n\t\t}\n\n\t\t// Leaf element - empty dir.\n\t\tif len(entries) == 0 {\n\t\t\t// Trim /opt/_slim/artifacts/files prefix from the dirpath.\n\t\t\tcurpath = strings.TrimPrefix(curpath, artifactFilesDir)\n\n\t\t\tif knownFiles[curpath] {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif props, err := artifactProps(curpath); err == nil {\n\t\t\t\tp.nameList = append(p.nameList, curpath)\n\t\t\t\tp.rawNames[curpath] = props\n\t\t\t\tknownFiles[curpath] = true\n\t\t\t} else {\n\t\t\t\tlogger.WithError(err).\n\t\t\t\t\tWithField(\"path\", curpath).\n\t\t\t\t\tDebugf(\"artifactProps(%s): failed computing dir artifact props\", curpath)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tfor _, child := range entries {\n\t\t\tchildpath := filepath.Join(curpath, child.Name())\n\t\t\tif child.IsDir() {\n\t\t\t\tdirqueue = append(dirqueue, childpath)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Trim /opt/_slim/artifacts/files prefix from the filepath.\n\t\t\tchildpath = strings.TrimPrefix(childpath, artifactFilesDir)\n\n\t\t\t// Leaf element - regular file or symlink.\n\t\t\tif knownFiles[childpath] {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif props, err := artifactProps(childpath); err == nil {\n\t\t\t\tp.nameList = append(p.nameList, childpath)\n\t\t\t\tp.rawNames[childpath] = props\n\t\t\t\tknownFiles[childpath] = true\n\t\t\t} else {\n\t\t\t\tlogger.WithError(err).\n\t\t\t\t\tWithField(\"path\", childpath).\n\t\t\t\t\tDebugf(\"artifactProps(%s): failed computing artifact props\", childpath)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (p *store) saveReport() error {\n\tlogger := log.WithField(\"op\", \"store.saveReport\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tcreport := report.ContainerReport{\n\t\tSensor: p.seReport,\n\t\tMonitors: report.MonitorReports{\n\t\t\tPt:  p.ptMonReport,\n\t\t\tFan: p.fanMonReport,\n\t\t},\n\t}\n\n\tif p.cmd != nil {\n\t\tcreport.StartCommand = &report.StartCommandReport{\n\t\t\tAppName:       p.cmd.AppName,\n\t\t\tAppArgs:       p.cmd.AppArgs,\n\t\t\tAppUser:       p.cmd.AppUser,\n\t\t\tAppEntrypoint: p.cmd.AppEntrypoint,\n\t\t\tAppCmd:        p.cmd.AppCmd,\n\t\t}\n\t}\n\n\tsinfo := system.GetSystemInfo()\n\tcreport.System = report.SystemReport{\n\t\tType:    sinfo.Sysname,\n\t\tRelease: sinfo.Release,\n\t\tDistro: report.DistroInfo{\n\t\t\tName:        sinfo.Distro.Name,\n\t\t\tVersion:     sinfo.Distro.Version,\n\t\t\tDisplayName: sinfo.Distro.DisplayName,\n\t\t},\n\t}\n\n\tsort.Strings(p.nameList)\n\tfor _, fname := range p.nameList {\n\t\trawNameRecord, found := p.rawNames[fname]\n\t\tif found {\n\t\t\tcreport.Image.Files = append(creport.Image.Files, rawNameRecord)\n\t\t} else {\n\t\t\tlogger.Debugf(\"nameList file name (%s) not found in rawNames map\", fname)\n\t\t}\n\t}\n\n\t_, err := os.Stat(p.storeLocation)\n\tif os.IsNotExist(err) {\n\t\tos.MkdirAll(p.storeLocation, 0777)\n\t\tif _, err := os.Stat(p.storeLocation); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treportFilePath := filepath.Join(p.storeLocation, report.DefaultContainerReportFileName)\n\tlogger.Debugf(\"saving report to '%s'\", reportFilePath)\n\n\tvar reportData bytes.Buffer\n\tencoder := json.NewEncoder(&reportData)\n\tencoder.SetEscapeHTML(false)\n\tencoder.SetIndent(\"\", \"  \")\n\tif err := encoder.Encode(creport); err != nil {\n\t\treturn err\n\t}\n\n\treturn os.WriteFile(reportFilePath, reportData.Bytes(), 0644)\n}\n\nfunc getFileHash(artifactFileName string) (string, error) {\n\tfileData, err := os.ReadFile(artifactFileName)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\thash := sha1.Sum(fileData)\n\treturn hex.EncodeToString(hash[:]), nil\n}\n\nfunc getDataType(artifactFileName string) (string, error) {\n\t//TODO: use libmagic (pure impl)\n\tvar cerr bytes.Buffer\n\tvar cout bytes.Buffer\n\n\tcmd := exec.Command(fileTypeCmd, artifactFileName)\n\tcmd.Stderr = &cerr\n\tcmd.Stdout = &cout\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif err := cmd.Wait(); err != nil {\n\t\terr = fmt.Errorf(\"getDataType - error getting data type: %s / stderr: %s\", err, cerr.String())\n\t\treturn \"\", err\n\t}\n\n\tif typeInfo := strings.Split(strings.TrimSpace(cout.String()), \":\"); len(typeInfo) > 1 {\n\t\treturn strings.TrimSpace(typeInfo[1]), nil\n\t}\n\n\treturn \"unknown\", nil\n}\n\n/*\n\n\nfunc cpFile(src, dst string) error {\n\ts, err := os.Open(src)\n\tif err != nil {\n\t\tlog.Warnln(\"sensor: monitor - cp - error opening source file =>\", src)\n\t\treturn err\n\t}\n\tdefer s.Close()\n\n\tdstDir := fsutil.FileDir(dst)\n\terr = os.MkdirAll(dstDir, 0777)\n\tif err != nil {\n\t\tlog.Warnln(\"sensor: monitor - dir error =>\", err)\n\t}\n\n\td, err := os.Create(dst)\n\tif err != nil {\n\t\tlog.Warnln(\"sensor: monitor - cp - error opening dst file =>\", dst)\n\t\treturn err\n\t}\n\n\t//todo: copy owner info...\n\n\tsrcFileInfo, err := s.Stat()\n\tif err == nil {\n\t\tif err := d.Chmod(srcFileInfo.Mode()); err != nil {\n\t\t\tlog.Warnln(\"sensor: cpFile - unable to set mode =>\", dst)\n\t\t}\n\t}\n\n\tif _, err := io.Copy(d, s); err != nil {\n\t\td.Close()\n\t\treturn err\n\t}\n\n\tif err := d.Close(); err != nil {\n\t\treturn err\n\t}\n\n\tsysStat, ok := srcFileInfo.Sys().(*syscall.Stat_t)\n\tif !ok {\n\t\tlog.Warnln(\"sensor: cpFile - unable to get Stat_t =>\", src)\n\t\treturn nil\n\t}\n\n\t//note: cpFile() is only for regular files\n\tif srcFileInfo.Mode()&os.ModeSymlink != 0 {\n\t\tlog.Warnln(\"sensor: cpFile - source is a symlink =>\", src)\n\t\treturn nil\n\t}\n\n\t//note: need to do the same for symlinks too\n\tif err := fsutil.UpdateFileTimes(dst, sysStat.Atim, sysStat.Mtim); err != nil {\n\t\tlog.Warnln(\"sensor: cpFile - UpdateFileTimes error =>\", dst)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n*/\n\nfunc py3FileNameFromCache(p string) string {\n\text := path.Ext(p)\n\n\tif !(((ext == pycExt) || (ext == pyoExt)) && strings.Contains(p, pycacheDir)) {\n\t\treturn \"\"\n\t}\n\n\tpathParts := strings.Split(p, \"/\")\n\n\tif !((len(pathParts) > 1) && (pycache == pathParts[len(pathParts)-2])) {\n\t\treturn \"\"\n\t}\n\n\tpycFileName := path.Base(p)\n\n\tnameParts := strings.Split(pycFileName, \".\")\n\tif !(len(nameParts) > 2) {\n\t\treturn \"\"\n\t}\n\n\tvar pyFileName string\n\tif len(nameParts) == 3 {\n\t\tpyFileName = fmt.Sprintf(\"%v.py\", nameParts[0])\n\t} else {\n\t\tpyFileName = fmt.Sprintf(\"%v.py\", strings.Join(nameParts[0:len(nameParts)-2], \".\"))\n\t}\n\n\treturn path.Join(path.Dir(path.Dir(p)), pyFileName)\n}\n\nfunc fixPy3CacheFile(src, dst string) error {\n\tdstPyFilePath := py3FileNameFromCache(dst)\n\tif dstPyFilePath == \"\" {\n\t\treturn nil\n\t}\n\n\tsrcPyFilePath := py3FileNameFromCache(src)\n\tif srcPyFilePath == \"\" {\n\t\treturn nil\n\t}\n\n\tif _, err := os.Stat(dstPyFilePath); err != nil && os.IsNotExist(err) {\n\t\t//if err := cpFile(srcPyFilePath, dstPyFilePath); err != nil {\n\t\tif err := fsutil.CopyRegularFile(true, srcPyFilePath, dstPyFilePath, true); err != nil {\n\t\t\tlog.Debugf(\"sensor: monitor - fixPy3CacheFile - error copying file => %v\", dstPyFilePath)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc rbEnsureGemFiles(src, storeLocation, prefix string) error {\n\tif strings.Contains(src, rbDefaultSpecSubDir) {\n\t\treturn nil\n\t}\n\n\tdir, file := path.Split(src)\n\tbase := strings.TrimSuffix(dir, rbSpecSubDir)\n\tgemName := strings.TrimSuffix(file, rbGemSpecExt)\n\n\textBasePath := filepath.Join(base, rgExtSibDir)\n\tfoList, err := os.ReadDir(extBasePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, fo := range foList {\n\t\tif fo.IsDir() {\n\t\t\tplatform := fo.Name()\n\n\t\t\textPlatformPath := filepath.Join(extBasePath, platform)\n\t\t\tfoVerList, err := os.ReadDir(extPlatformPath)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tfor _, foVer := range foVerList {\n\t\t\t\tif foVer.IsDir() {\n\t\t\t\t\trversion := foVer.Name()\n\n\t\t\t\t\textBuildFlagFilePath := filepath.Join(base, rgExtSibDir, platform, rversion, gemName, rbGemBuildFlag)\n\n\t\t\t\t\tif _, err := os.Stat(extBuildFlagFilePath); err != nil && os.IsNotExist(err) {\n\t\t\t\t\t\tlog.Debug(\"sensor: monitor - rbEnsureGemFiles - no native extensions for gem =>\", gemName)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\textBuildFlagFilePathDst := fmt.Sprintf(\"%s%s%s\", storeLocation, prefix, extBuildFlagFilePath)\n\n\t\t\t\t\tif _, err := os.Stat(extBuildFlagFilePathDst); err != nil && os.IsNotExist(err) {\n\t\t\t\t\t\t//if err := cpFile(extBuildFlagFilePath, extBuildFlagFilePathDst); err != nil {\n\t\t\t\t\t\tif err := fsutil.CopyRegularFile(true, extBuildFlagFilePath, extBuildFlagFilePathDst, true); err != nil {\n\t\t\t\t\t\t\tlog.Debugf(\"sensor: monitor - rbEnsureGemFiles - error copying file => %v\", extBuildFlagFilePathDst)\n\t\t\t\t\t\t\treturn err\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\treturn nil\n}\n\ntype nuxtDirs struct {\n\tBuild string\n\tDist  string\n}\n\nfunc getNuxtConfig(path string) (*nuxtDirs, error) {\n\tif _, err := os.Stat(path); err != nil && os.IsNotExist(err) {\n\t\tlog.Debugf(\"sensor: monitor - getNuxtConfig - err stat => %s - %s\", path, err.Error())\n\t\treturn nil, fmt.Errorf(\"sensor: artifact - getNuxtConfig - error getting file => %s\", path)\n\t}\n\n\tdat, err := os.ReadFile(path)\n\tif err != nil {\n\t\tlog.Debugf(\"sensor: monitor - getNuxtConfig - err reading file => %s - %s\", path, err.Error())\n\t\treturn nil, fmt.Errorf(\"sensor: artifact - getNuxtConfig - error reading file => %s\", path)\n\t}\n\n\tlog.Tracef(\"sensor: monitor - getNuxtConfig(%s) - %s\", path, string(dat))\n\n\tnuxt := nuxtDirs{\n\t\tBuild: nuxtDefaultBuildDir,\n\t\tDist:  fmt.Sprintf(\"%s/%s\", nuxtDefaultBuildDir, nuxtDefaultDistDir),\n\t}\n\n\t/*\n\t\ttodo: need more test apps to verify this part of the code\n\t\tvm := otto.New()\n\t\tvm.Run(dat)\n\n\t\tif value, err := vm.Get(nuxtBuildDirKey); err == nil {\n\t\t\tif v, err := value.ToString(); err == nil {\n\t\t\t\tnuxt.Build = v\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"saveArtifacts - using build default => %s\", err.Error())\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debug(\"saveArtifacts - error reading nuxt.config.js file => \", err.Error())\n\t\t\treturn nil, fmt.Errorf(\"sensor: artifact - getNuxtConfig - error getting buildDir => %s\", path)\n\t\t}\n\n\t\tif value, err := vm.Get(nuxtDistDirKey); err == nil {\n\t\t\tif v, err := value.ToString(); err == nil {\n\t\t\t\tnuxt.Dist = fmt.Sprintf(\"%s/%s\", nuxt.Build, v)\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"saveArtifacts - using dist default => %s\", err.Error())\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debug(\"saveArtifacts - reading nuxt.config.js file => \", err.Error())\n\t\t\treturn nil, fmt.Errorf(\"sensor: artifact - getNuxtConfig - error getting distDir => %s\", path)\n\t\t}\n\t*/\n\n\treturn &nuxt, nil\n}\n\nfunc isNuxtConfigFile(filePath string) bool {\n\tfileName := filepath.Base(filePath)\n\tif fileName == nuxtConfigFile {\n\t\treturn true\n\t}\n\n\t//TODO: read the file and verify that it's a real nuxt config file\n\treturn false\n}\n\n/////\n\nfunc isNextConfigFile(filePath string) bool {\n\tfileName := filepath.Base(filePath)\n\tif fileName == nextConfigFile || fileName == nextConfigFileAlt {\n\t\treturn true\n\t}\n\n\t//TODO: read the file and verify that it's a real next config file\n\treturn false\n}\n\n/////\n\nfunc isRbGemSpecFile(filePath string) bool {\n\text := path.Ext(filePath)\n\n\tif ext == rbGemSpecExt && strings.Contains(filePath, rbSpecSubDir) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc isNodePackageFile(filePath string) bool {\n\tfileName := filepath.Base(filePath)\n\n\tif fileName == nodePackageFile {\n\t\treturn true\n\t}\n\n\t//TODO: read the file and verify that it's a real package file\n\treturn false\n}\n\nfunc getNodePackageFileData(filePath string) (*NodePackageConfigSimple, error) {\n\tfileName := filepath.Base(filePath)\n\tif fileName != nodePackageFile {\n\t\treturn nil, nil\n\t}\n\n\tvar result NodePackageConfigSimple\n\terr := fsutil.LoadStructFromFile(filePath, &result)\n\tif err != nil {\n\t\tlog.Debugf(\"sensor: getNodePackageFileData(%s) - error loading data => %v\", filePath, err)\n\t\treturn nil, err\n\t}\n\n\treturn &result, nil\n}\n\nfunc nodeEnsurePackageFiles(keepPerms bool, src, storeLocation, prefix string) error {\n\tif strings.HasSuffix(src, nodeNPMNodeGypPackage) {\n\t\t//for now only ensure that we have node-gyp for npm\n\t\t//npm requires it to be there even though it won't use it\n\t\t//'check if exists' condition (not picked up by the FAN monitor, but picked up by the PT monitor)\n\t\tnodeGypFilePath := path.Join(filepath.Dir(src), nodeNPMNodeGypFile)\n\t\tif _, err := os.Stat(nodeGypFilePath); err == nil {\n\t\t\tnodeGypFilePathDst := fmt.Sprintf(\"%s%s%s\", storeLocation, prefix, nodeGypFilePath)\n\t\t\tif err := fsutil.CopyRegularFile(keepPerms, nodeGypFilePath, nodeGypFilePathDst, true); err != nil {\n\t\t\t\tlog.Debugf(\"sensor: nodeEnsurePackageFiles - error copying %s => %v\", nodeGypFilePath, err)\n\t\t\t}\n\t\t}\n\t}\n\n\t//NOTE: can also read the dependencies and confirm/ensure that we copied everything we need\n\treturn nil\n}\n\nvar pidFilePathSuffixes = []string{\n\t\"/var/run/nginx.pid\",\n\t\"/run/nginx.pid\",\n\t\"/tmp/nginx.pid\",\n\t\"/tmp/pids/server.pid\",\n}\n\nfunc isKnownPidFilePath(filePath string) bool {\n\tfor _, suffix := range pidFilePathSuffixes {\n\t\tif strings.HasSuffix(filePath, suffix) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc hasPidFileSuffix(filePath string) bool {\n\tif strings.HasSuffix(filePath, pidFileSuffix) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc isNgxArtifact(filePath string) bool {\n\tif strings.Contains(filePath, ngxSubDir) || strings.HasSuffix(filePath, ngxBinName) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc ngxEnsure(prefix string) {\n\t//ensure common temp paths (note: full implementation needs mkdir syscall info)\n\tif info, err := os.Stat(ngxCommonTemp); err == nil {\n\t\tif info.IsDir() {\n\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", prefix, ngxCommonTemp)\n\t\t\tif !fsutil.DirExists(dstPath) {\n\t\t\t\terr := os.MkdirAll(dstPath, 0777)\n\t\t\t\t//err, errs := fsutil.CopyDir(true, ngxCommonTemp, dstPath, true, true, nil, nil, nil)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"ngxEnsure - MkdirAll(%v) error: %v\", dstPath, err)\n\t\t\t\t}\n\t\t\t\t//if len(errs) > 0 {\n\t\t\t\t//\tlog.Warnf(\"ngxEnsure - CopyDir copy error: %+v\", errs)\n\t\t\t\t//}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debugf(\"ngxEnsure - %v should be a directory\", ngxCommonTemp)\n\t\t}\n\t} else {\n\t\tif !os.IsNotExist(err) {\n\t\t\tlog.Debugf(\"ngxEnsure - error checking %v => %v\", ngxCommonTemp, err)\n\t\t}\n\t}\n\n\tif info, err := os.Stat(ngxLogTemp); err == nil {\n\t\tif info.IsDir() {\n\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", prefix, ngxLogTemp)\n\t\t\tif !fsutil.DirExists(dstPath) {\n\t\t\t\terr := os.MkdirAll(dstPath, 0777)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"ngxEnsure -  MkdirAll(%v) error: %v\", dstPath, err)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debugf(\"ngxEnsure - %v should be a directory\", ngxLogTemp)\n\t\t}\n\t} else {\n\t\tif !os.IsNotExist(err) {\n\t\t\tlog.Debugf(\"ngxEnsure - error checking %v => %v\", ngxLogTemp, err)\n\t\t}\n\t}\n\n\tif info, err := os.Stat(ngxCacheTemp); err == nil {\n\t\tif info.IsDir() {\n\t\t\tdstPath := fmt.Sprintf(\"%s/files%s\", prefix, ngxCacheTemp)\n\t\t\tif !fsutil.DirExists(dstPath) {\n\t\t\t\terr := os.MkdirAll(dstPath, 0777)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"ngxEnsure -  MkdirAll(%v) error: %v\", dstPath, err)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Debugf(\"ngxEnsure - %v should be a directory\", ngxCacheTemp)\n\t\t}\n\t} else {\n\t\tif !os.IsNotExist(err) {\n\t\t\tlog.Debugf(\"ngxEnsure - error checking %v => %v\", ngxCacheTemp, err)\n\t\t}\n\t}\n}\n\nfunc shellDependencies() ([]string, error) {\n\tvar allDeps []string\n\tfor _, name := range artifact.ShellNames {\n\t\tshellPath, err := exec.LookPath(name)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"shellDependencies - checking '%s' shell (not found: %s)\", name, err)\n\t\t\tcontinue\n\t\t}\n\n\t\texeArtifacts, err := sodeps.AllExeDependencies(shellPath, true)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"shellDependencies - %v - error getting shell artifacts => %v\", shellPath, err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\tallDeps = append(allDeps, exeArtifacts...)\n\t\tbreak\n\t}\n\n\tif len(allDeps) == 0 {\n\t\tlog.Debug(\"shellDependencies - no shell found\")\n\t\treturn nil, nil\n\t}\n\n\tfor _, name := range artifact.ShellCommands {\n\t\tcmdPath, err := exec.LookPath(name)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"shellDependencies - checking '%s' cmd (not found: %s)\", name, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tcmdArtifacts, err := sodeps.AllExeDependencies(cmdPath, true)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"shellDependencies - %v - error getting cmd artifacts => %v\", cmdPath, err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\tallDeps = append(allDeps, cmdArtifacts...)\n\t}\n\n\treturn allDeps, nil\n}\n\n// TODO: Merge it with prepareArtifact().\nfunc artifactProps(filename string) (*report.ArtifactProps, error) {\n\tfileInfo, err := os.Lstat(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfileType := report.UnknownArtifactType\n\tswitch true {\n\tcase fileInfo.Mode().IsRegular():\n\t\tfileType = report.FileArtifactType\n\tcase (fileInfo.Mode() & os.ModeSymlink) != 0:\n\t\tfileType = report.SymlinkArtifactType\n\tcase fileInfo.IsDir():\n\t\tfileType = report.DirArtifactType\n\t}\n\n\treturn &report.ArtifactProps{\n\t\tFileType: fileType,\n\t\tFilePath: filename,\n\t\tMode:     fileInfo.Mode(),\n\t\tModeText: fileInfo.Mode().String(),\n\t\tFileSize: fileInfo.Size(),\n\t}, nil\n}\n\nfunc list2map(l []string) map[string]bool {\n\tm := map[string]bool{}\n\tfor _, v := range l {\n\t\tm[v] = true\n\t}\n\treturn m\n}\n\nfunc findSymlinks(files []string, mountPoint string, excludes []string) map[string]*report.ArtifactProps {\n\tlog.Debugf(\"findSymlinks(%v,%v)\", len(files), mountPoint)\n\n\tresult := map[string]*report.ArtifactProps{}\n\tsymlinks := map[string]string{}\n\n\tcheckPathSymlinks := func(symlinkFileName string) {\n\t\tif _, ok := result[symlinkFileName]; ok {\n\t\t\tlog.Tracef(\"findSymlinks.checkPathSymlinks - symlink already in files -> %v\", symlinkFileName)\n\t\t\treturn\n\t\t}\n\n\t\tlinkRef, err := os.Readlink(symlinkFileName)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"findSymlinks.checkPathSymlinks - error getting reference for symlink (%v) -> %v\", err, symlinkFileName)\n\t\t\treturn\n\t\t}\n\n\t\tvar absLinkRef string\n\t\tif !filepath.IsAbs(linkRef) {\n\t\t\tlinkDir := filepath.Dir(symlinkFileName)\n\t\t\tlog.Tracef(\"findSymlinks.checkPathSymlinks - relative linkRef %v -> %v +/+ %v\", symlinkFileName, linkDir, linkRef)\n\t\t\tfullLinkRef := filepath.Join(linkDir, linkRef)\n\t\t\tvar err error\n\t\t\tabsLinkRef, err = filepath.Abs(fullLinkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"findSymlinks.checkPathSymlinks - error getting absolute path for symlink ref (1) (%v) -> %v => %v\", err, symlinkFileName, fullLinkRef)\n\t\t\t\treturn\n\t\t\t}\n\t\t} else {\n\t\t\tvar err error\n\t\t\tabsLinkRef, err = filepath.Abs(linkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"findSymlinks.checkPathSymlinks - error getting absolute path for symlink ref (2) (%v) -> %v => %v\", err, symlinkFileName, linkRef)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t//todo: skip \"/proc/...\" references\n\t\tevalLinkRef, err := filepath.EvalSymlinks(absLinkRef)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"findSymlinks.checkPathSymlinks - error evaluating symlink (%v) -> %v => %v\", err, symlinkFileName, absLinkRef)\n\t\t}\n\n\t\t//detecting intermediate dir symlinks\n\t\tsymlinkPrefix := fmt.Sprintf(\"%s/\", symlinkFileName)\n\t\tabsPrefix := fmt.Sprintf(\"%s/\", absLinkRef)\n\t\tevalPrefix := fmt.Sprintf(\"%s/\", evalLinkRef)\n\n\t\t//TODO:\n\t\t//have an option not to resolve intermediate dir symlinks\n\t\t//it'll result in file duplication, but the symlinks\n\t\t//resolution logic will be less complicated and faster\n\t\tfor _, fname := range files {\n\t\t\tadded := false\n\t\t\tif strings.HasPrefix(fname, symlinkPrefix) {\n\t\t\t\tresult[symlinkFileName] = nil\n\t\t\t\tlog.Tracef(\"findSymlinks.checkPathSymlinks - added path symlink to files (0) -> %v\", symlinkFileName)\n\t\t\t\tadded = true\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(fname, absPrefix) {\n\t\t\t\tresult[symlinkFileName] = nil\n\t\t\t\tlog.Tracef(\"findSymlinks.checkPathSymlinks - added path symlink to files (1) -> %v\", symlinkFileName)\n\t\t\t\tadded = true\n\t\t\t}\n\n\t\t\tif evalLinkRef != \"\" &&\n\t\t\t\tabsPrefix != evalPrefix &&\n\t\t\t\tstrings.HasPrefix(fname, evalPrefix) {\n\t\t\t\tresult[symlinkFileName] = nil\n\t\t\t\tlog.Tracef(\"findSymlinks.checkPathSymlinks - added path symlink to files (2) -> %v\", symlinkFileName)\n\t\t\t\tadded = true\n\t\t\t}\n\n\t\t\tif added {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tsymlinks[symlinkFileName] = linkRef\n\t}\n\n\tinodes, devices := filesToInodesNative(files)\n\tlog.Debugf(\"findSymlinks - len(inodes)=%v len(devices)=%v\", len(inodes), len(devices))\n\n\tinodeToFiles := map[uint64][]string{}\n\n\t//native filepath.Walk is a bit slow (compared to the \"find\" command)\n\t//but it's fast enough for now\n\tfilepath.Walk(mountPoint,\n\t\tfunc(fullName string, fileInfo os.FileInfo, err error) error {\n\t\t\tif strings.HasPrefix(fullName, \"/proc/\") {\n\t\t\t\tlog.Debugf(\"findSymlinks: skipping /proc file system objects...\")\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(fullName, \"/sys/\") {\n\t\t\t\tlog.Debugf(\"findSymlinks: skipping /sys file system objects...\")\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(fullName, \"/dev/\") {\n\t\t\t\tlog.Debugf(\"findSymlinks: skipping /dev file system objects...\")\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\t// Optimization: Avoid walking excluded folders. Supposed to help with\n\t\t\t//               mounting big folders from the host (they should be explicitly\n\t\t\t//               excluded).\n\t\t\t// TODO: Combine this logic with the similar logic in GetCurrentPaths().\n\t\t\tfor _, xpattern := range excludes {\n\t\t\t\tif match, _ := doublestar.Match(xpattern, fullName); match {\n\t\t\t\t\tif fileInfo.Mode().IsDir() {\n\t\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"findSymlinks: error accessing %q: %v\\n\", fullName, err)\n\t\t\t\t//just ignore the error and keep going\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif fileInfo.Sys() == nil {\n\t\t\t\tlog.Debugf(\"findSymlinks: fileInfo.Sys() is nil (ignoring)\")\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tsysStatInfo, ok := fileInfo.Sys().(*syscall.Stat_t)\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"findSymlinks - could not convert fileInfo to Stat_t for %s\", fullName)\n\t\t\t}\n\n\t\t\tif _, ok := devices[uint64(sysStatInfo.Dev)]; !ok {\n\t\t\t\tlog.Debugf(\"findSymlinks: ignoring %v (by device id - %v)\", fullName, sysStatInfo.Dev)\n\t\t\t\t//NOTE:\n\t\t\t\t//don't return filepath.SkipDir for everything\n\t\t\t\t//because we might still need other files in the dir\n\t\t\t\t//return filepath.SkipDir\n\t\t\t\t//example: \"/etc/hostname\" Docker mounts from another device\n\t\t\t\t//NOTE:\n\t\t\t\t//can move the checks for /dev, /sys and /proc here too\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif fileInfo.Mode()&os.ModeSymlink != 0 {\n\t\t\t\tcheckPathSymlinks(fullName)\n\n\t\t\t\tif info, err := getFileSysStats(fullName); err == nil {\n\n\t\t\t\t\tif _, ok := inodes[info.Ino]; ok {\n\t\t\t\t\t\t//not using the inode for the link (using the target inode instead)\n\t\t\t\t\t\tinodeToFiles[info.Ino] = append(inodeToFiles[info.Ino], fullName)\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//log.Debugf(\"findSymlinks - don't care about this symlink (%s)\",fullName)\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tlog.Infof(\"findSymlinks - could not get target stats info for file (%v) -> %v\", err, fullName)\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\tif _, ok := inodes[sysStatInfo.Ino]; ok {\n\t\t\t\t\tinodeToFiles[sysStatInfo.Ino] = append(inodeToFiles[sysStatInfo.Ino], fullName)\n\t\t\t\t} else {\n\t\t\t\t\t//log.Debugf(\"findSymlinks - don't care about this file (%s)\",fullName)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn nil\n\t\t})\n\n\tlog.Debugf(\"findSymlinks - len(inodeToFiles)=%v\", len(inodeToFiles))\n\n\tfor inodeID := range inodes {\n\t\tv := inodeToFiles[inodeID]\n\t\tfor _, f := range v {\n\t\t\t//result[f] = inodeID\n\t\t\tresult[f] = nil\n\t\t}\n\t}\n\n\t//NOTE/TODO:\n\t//Might need multiple passes until no new symlinks are added to result\n\t//(with the current approach)\n\t//Should REDESIGN to use a reverse/target radix and a radix-based result\n\tfor symlinkFileName, linkRef := range symlinks {\n\t\tvar absLinkRef string\n\t\tif !filepath.IsAbs(linkRef) {\n\t\t\tlinkDir := filepath.Dir(symlinkFileName)\n\t\t\tlog.Debugf(\"findSymlinks.walkSymlinks - relative linkRef %v -> %v +/+ %v\", symlinkFileName, linkDir, linkRef)\n\t\t\tfullLinkRef := filepath.Join(linkDir, linkRef)\n\t\t\tvar err error\n\t\t\tabsLinkRef, err = filepath.Abs(fullLinkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"findSymlinks.walkSymlinks - error getting absolute path for symlink ref (1) (%v) -> %v => %v\", err, symlinkFileName, fullLinkRef)\n\t\t\t\tbreak\n\t\t\t}\n\t\t} else {\n\t\t\tvar err error\n\t\t\tabsLinkRef, err = filepath.Abs(linkRef)\n\t\t\tif err != nil {\n\t\t\t\tlog.Debugf(\"findSymlinks.walkSymlinks - error getting absolute path for symlink ref (2) (%v) -> %v => %v\", err, symlinkFileName, linkRef)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t//todo: skip \"/proc/...\" references\n\t\tevalLinkRef, err := filepath.EvalSymlinks(absLinkRef)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"findSymlinks.walkSymlinks - error evaluating symlink (%v) -> %v => %v\", err, symlinkFileName, absLinkRef)\n\t\t}\n\n\t\t//detecting intermediate dir symlinks\n\t\tsymlinkPrefix := fmt.Sprintf(\"%s/\", symlinkFileName)\n\t\tabsPrefix := fmt.Sprintf(\"%s/\", absLinkRef)\n\t\tevalPrefix := fmt.Sprintf(\"%s/\", evalLinkRef)\n\n\t\tfor fname := range result {\n\t\t\tadded := false\n\t\t\tif strings.HasPrefix(fname, symlinkPrefix) {\n\t\t\t\tresult[symlinkFileName] = nil\n\t\t\t\tlog.Debugf(\"findSymlinks.walkSymlinks - added path symlink to files (0) -> %v\", symlinkFileName)\n\t\t\t\tadded = true\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(fname, absPrefix) {\n\t\t\t\tresult[symlinkFileName] = nil\n\t\t\t\tlog.Debugf(\"findSymlinks.walkSymlinks - added path symlink to files (1) -> %v\", symlinkFileName)\n\t\t\t\tadded = true\n\t\t\t}\n\n\t\t\tif evalLinkRef != \"\" &&\n\t\t\t\tabsPrefix != evalPrefix &&\n\t\t\t\tstrings.HasPrefix(fname, evalPrefix) {\n\t\t\t\tresult[symlinkFileName] = nil\n\t\t\t\tlog.Debugf(\"findSymlinks.walkSymlinks - added path symlink to files (2) -> %v\", symlinkFileName)\n\t\t\t\tadded = true\n\t\t\t}\n\n\t\t\tif added {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n\nfunc filesToInodesNative(files []string) (map[uint64]struct{}, map[uint64]struct{}) {\n\tinodes := map[uint64]struct{}{}\n\tdevices := map[uint64]struct{}{}\n\n\tfor _, fullName := range files {\n\t\tinfo, err := getFileSysStats(fullName)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"filesToInodesNative - could not get inode for %s\", fullName)\n\t\t\tcontinue\n\t\t}\n\n\t\tinodes[info.Ino] = struct{}{}\n\t\tdevices[uint64(info.Dev)] = struct{}{}\n\t}\n\n\treturn inodes, devices\n}\n\nfunc getFileSysStats(fullName string) (*syscall.Stat_t, error) {\n\tstatInfo, err := os.Stat(fullName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsysStatInfo, ok := statInfo.Sys().(*syscall.Stat_t)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"failed to get system stat info for %s\", fullName)\n\t}\n\n\treturn sysStatInfo, nil\n}\n\nfunc getFileDevice(fullName string) (uint64, error) {\n\tinfo, err := getFileSysStats(fullName)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn uint64(info.Dev), nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/controlled/controlled.go",
    "content": "package controlled\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/artifact\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/execution\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n)\n\nvar ErrPrematureShutdown = errors.New(\"sensor shutdown before monitor stop\")\n\ntype Sensor struct {\n\tctx context.Context\n\texe execution.Interface\n\n\tnewMonitor monitor.NewCompositeMonitorFunc\n\tdel        mondel.Publisher\n\tartifactor artifact.Processor\n\n\tworkDir    string\n\tmountPoint string\n}\n\nfunc NewSensor(\n\tctx context.Context,\n\texe execution.Interface,\n\tnewMonitor monitor.NewCompositeMonitorFunc,\n\tdel mondel.Publisher,\n\tartifactor artifact.Processor,\n\tworkDir string,\n\tmountPoint string,\n) *Sensor {\n\treturn &Sensor{\n\t\tctx:        ctx,\n\t\texe:        exe,\n\t\tnewMonitor: newMonitor,\n\t\tdel:        del,\n\t\tartifactor: artifactor,\n\t\tworkDir:    workDir,\n\t\tmountPoint: mountPoint,\n\t}\n}\n\n// Sensor can be in two interchanging (and mutually exclusive) \"states\":\n//\n//   - (I) No monitor is running\n//     -> ShutdownSensor command arrives => clean exit\n//     -> StartMonitor command arrives   => go to state II.\n//     -> Any other command              => grumble but keep waiting\n//\n//   - (II) Monitor is running\n//     -> StopMonitor command arrives    => stop the mon, dump the report, and go to state I.\n//     -> ShutdownSensor command arrives => cancel monitoring, grumble, and exit\n//     -> Any other command              => grumble but keep waiting\nfunc (s *Sensor) Run() error {\n\ts.exe.HookSensorPostStart()\n\n\terr := s.run()\n\tif err != nil {\n\t\ts.exe.PubEvent(event.Error, err.Error())\n\t}\n\n\t// We have to dump the artifacts before invokin the pre-shutdown\n\t// hook - it may want to upload the artifacts somewhere.\n\terrutil.WarnOn(s.artifactor.Archive())\n\n\ts.exe.HookSensorPreShutdown()\n\ts.exe.PubEvent(event.ShutdownSensorDone)\n\n\treturn err\n}\n\nfunc (s *Sensor) run() error {\n\tlog.Info(\"sensor: waiting for commands...\")\n\n\tfor {\n\t\tmon, err := s.runWithoutMonitor()\n\t\tif err != nil {\n\t\t\ts.exe.HookMonitorFailed()\n\t\t\ts.exe.PubEvent(event.StartMonitorFailed,\n\t\t\t\t&event.StartMonitorFailedData{\n\t\t\t\t\tComponent: event.ComMonitorRunner, //TODO: need to get to the real component\n\t\t\t\t\tState:     s.exe.State(),\n\t\t\t\t\tErrors:    []string{err.Error()},\n\t\t\t\t})\n\n\t\t\treturn fmt.Errorf(\"run sensor without monitor failed: %w\", err)\n\t\t}\n\n\t\tif mon == nil {\n\t\t\treturn nil\n\t\t}\n\n\t\ts.exe.PubEvent(event.StartMonitorDone)\n\n\t\tif err := s.runWithMonitor(mon); err != nil {\n\t\t\treturn fmt.Errorf(\"run sensor with monitor failed: %w\", err)\n\t\t}\n\n\t\ts.exe.HookMonitorPostShutdown()\n\t\ts.exe.PubEvent(event.StopMonitorDone)\n\t}\n}\n\nfunc (s *Sensor) runWithoutMonitor() (monitor.CompositeMonitor, error) {\n\tticker := time.NewTicker(5 * time.Second)\n\tdefer ticker.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase cmd := <-s.exe.Commands():\n\t\t\tlog.Debugf(\"sensor: new command => %+v\", cmd)\n\n\t\t\tswitch typedCmd := cmd.(type) {\n\t\t\tcase *command.StartMonitor:\n\t\t\t\treturn s.startMonitor(typedCmd)\n\n\t\t\tcase *command.ShutdownSensor:\n\t\t\t\treturn nil, nil // Clean exit\n\n\t\t\tdefault:\n\t\t\t\tlog.Warn(\"sensor: ignoring unknown or unexpected command => \", cmd)\n\t\t\t} // eof: type switch\n\n\t\tcase <-ticker.C:\n\t\t\tlog.Debug(\".\")\n\t\t} // eof: select\n\t}\n}\n\nfunc (s *Sensor) startMonitor(cmd *command.StartMonitor) (monitor.CompositeMonitor, error) {\n\tif err := s.artifactor.PrepareEnv(cmd); err != nil {\n\t\tlog.WithError(err).Error(\"sensor: artifactor.PrepareEnv() failed\")\n\t\treturn nil, fmt.Errorf(\"failed to prepare artifacts env: %w\", err)\n\t}\n\n\torigPaths, err := s.artifactor.GetCurrentPaths(s.mountPoint, cmd.Excludes)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"sensor: artifactor.GetCurrentPaths() failed\")\n\t\treturn nil, fmt.Errorf(\"failed to enumerate current paths: %w\", err)\n\t}\n\n\ts.exe.HookMonitorPreStart()\n\n\tmon, err := s.newMonitor(\n\t\ts.ctx,\n\t\tcmd,\n\t\ts.workDir,\n\t\ts.del,\n\t\ts.artifactor.ArtifactsDir(),\n\t\ts.mountPoint,\n\t\torigPaths,\n\t)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"sensor: failed to create composite monitor\")\n\t\treturn nil, err\n\t}\n\n\tif err := mon.Start(); err != nil {\n\t\tlog.WithError(err).Error(\"sensor: failed to start composite monitor\")\n\t\treturn nil, err\n\t}\n\n\tlog.Info(\"sensor: monitor started...\")\n\n\treturn mon, nil\n}\n\nfunc (s *Sensor) runWithMonitor(mon monitor.CompositeMonitor) error {\n\tlog.Debug(\"sensor: monitor.worker - waiting to stop monitoring...\")\n\tlog.Debug(\"sensor: error collector - waiting for errors...\")\n\n\tticker := time.NewTicker(time.Second * 5)\n\tdefer ticker.Stop()\n\n\t// Only two ways out of this: either StopMonitor or ShutdownSensor.\n\tstopCommandReceived := false\n\nloop:\n\tfor {\n\t\tselect {\n\t\tcase <-mon.Done():\n\t\t\tbreak loop\n\n\t\tcase cmd := <-s.exe.Commands():\n\t\t\tswitch cmd.(type) {\n\t\t\tcase *command.StopMonitor:\n\t\t\t\tstopCommandReceived = true\n\t\t\t\tmon.Cancel()\n\t\t\t\tbreak loop\n\n\t\t\tcase *command.ShutdownSensor:\n\t\t\t\tmon.Cancel() // Dirty exit - abandoning the results.\n\t\t\t\treturn ErrPrematureShutdown\n\n\t\t\tdefault:\n\t\t\t\tlog.Info(\"sensor: ignoring unknown or unexpected command => \", cmd)\n\t\t\t} // eof: type switch\n\n\t\tcase err := <-mon.Errors():\n\t\t\tlog.WithError(err).Warn(\"sensor: non-critical monitor error condition\")\n\t\t\ts.exe.PubEvent(event.Error, monitor.NonCriticalError(err).Error())\n\n\t\tcase <-ticker.C:\n\t\t\ts.exe.HookTargetAppRunning()\n\t\t\tlog.Debug(\".\")\n\t\t} // eof: select\n\t}\n\n\tif !stopCommandReceived {\n\t\t// Monitor can finish before the stop command is received.\n\t\t// In such case, we have to await the explicit stop.\n\t\tif cmd, ok := (<-s.exe.Commands()).(*command.StopMonitor); !ok {\n\t\t\treturn fmt.Errorf(\"sensor received unepxected command: %#+v\", cmd)\n\t\t}\n\t}\n\n\treturn s.processMonitoringResults(mon)\n}\n\nfunc (s *Sensor) processMonitoringResults(mon monitor.CompositeMonitor) error {\n\t// A bit of code duplication to avoid starting a goroutine\n\t// for error event handling - keeping the control flow\n\t// \"single-threaded\" keeps reasoning about the logic.\n\tfor _, err := range mon.DrainErrors() {\n\t\tlog.WithError(err).Warn(\"sensor: non-critical monitor error condition (drained)\")\n\t\ts.exe.PubEvent(event.Error, monitor.NonCriticalError(err).Error())\n\t}\n\n\tlog.Info(\"sensor: composite monitor is done, checking status...\")\n\n\treport, err := mon.Status()\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"sensor: composite monitor failed\")\n\t\treturn fmt.Errorf(\"composite monitor failed: %w\", err)\n\t}\n\n\tif err := s.artifactor.Process(\n\t\tmon.StartCommand(),\n\t\ts.mountPoint,\n\t\treport.PeReport,\n\t\treport.FanReport,\n\t\treport.PtReport,\n\t); err != nil {\n\t\tlog.WithError(err).Error(\"sensor: artifact.Process() failed\")\n\t\treturn fmt.Errorf(\"saving reports failed: %w\", err)\n\t}\n\treturn nil // Clean exit\n}\n"
  },
  {
    "path": "pkg/app/sensor/controlled/controlled_test.go",
    "content": "package controlled_test\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/artifact\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/controlled\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor/fanotify\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor/ptrace\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/test/stub/sensor/execution\"\n\tstubmonitor \"github.com/slimtoolkit/slim/pkg/test/stub/sensor/monitor\"\n)\n\n// Stubs\nfunc newStubMonitorFunc(\n\tctx context.Context,\n\tfanMon fanotify.Monitor,\n\tptMon ptrace.Monitor,\n) monitor.NewCompositeMonitorFunc {\n\tif fanMon == nil {\n\t\tfanMon = stubmonitor.NewFanMonitor(ctx)\n\t}\n\tif ptMon == nil {\n\t\tptMon = stubmonitor.NewPtMonitor(ctx)\n\t}\n\n\treturn func(\n\t\tctx context.Context,\n\t\tcmd *command.StartMonitor,\n\t\tworkDir string,\n\t\tdel mondel.Publisher,\n\t\tartifactsDir string,\n\t\tmountPoint string,\n\t\torigPaths map[string]struct{},\n\t) (monitor.CompositeMonitor, error) {\n\t\treturn monitor.Compose(\n\t\t\tcmd,\n\t\t\tnil,\n\t\t\tfanMon,\n\t\t\tptMon,\n\t\t\tnil,\n\t\t\tnil,\n\t\t), nil\n\t}\n}\n\ntype artifactorStub struct{}\n\nvar _ artifact.Processor = &artifactorStub{}\n\nfunc (a *artifactorStub) ArtifactsDir() string {\n\treturn \"\"\n}\n\nfunc (a *artifactorStub) GetCurrentPaths(root string, excludes []string) (map[string]struct{}, error) {\n\treturn map[string]struct{}{}, nil\n}\n\nfunc (a *artifactorStub) PrepareEnv(cmd *command.StartMonitor) error {\n\treturn nil\n}\n\nfunc (a *artifactorStub) Archive() error {\n\treturn nil\n}\n\nfunc (a *artifactorStub) Process(\n\tcmd *command.StartMonitor,\n\tmountPoint string,\n\tpeReport *report.PeMonitorReport,\n\tfanReport *report.FanMonitorReport,\n\tptReport *report.PtMonitorReport,\n) error {\n\treturn nil\n}\n\n// Tests\nfunc TestStartStopShutdown(t *testing.T) {\n\tctx := context.Background()\n\texe := execution.NewExecution()\n\tsen := controlled.NewSensor(\n\t\tctx,\n\t\texe,\n\t\tnewStubMonitorFunc(ctx, nil, nil),\n\t\tnil, //Monitor Data Event Log\n\t\t&artifactorStub{},\n\t\t\"\", \"\",\n\t)\n\n\tgo func() {\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\texe.SendCommand(&command.StartMonitor{})\n\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\texe.SendCommand(&command.StopMonitor{})\n\n\t\ttime.Sleep(100 * time.Millisecond)\n\t\texe.SendCommand(&command.ShutdownSensor{})\n\t}()\n\n\tif err := sen.Run(); err != nil {\n\t\tt.Fatal(\"Unexpected sensor run error:\", err)\n\t}\n}\n\nfunc TestShutdownBeforeStart(t *testing.T) {\n\tctx := context.Background()\n\texe := execution.NewExecution()\n\tsen := controlled.NewSensor(\n\t\tctx,\n\t\texe,\n\t\tnewStubMonitorFunc(ctx, nil, nil),\n\t\tnil, //Monitor Data Event Log\n\t\t&artifactorStub{},\n\t\t\"\", \"\",\n\t)\n\n\tgo func() {\n\t\texe.SendCommand(&command.ShutdownSensor{})\n\t}()\n\n\tif err := sen.Run(); err != nil {\n\t\tt.Fatal(\"Unexpected sensor run error:\", err)\n\t}\n}\n\nfunc TestStartFollowedByShutdown(t *testing.T) {\n\tctx := context.Background()\n\texe := execution.NewExecution()\n\tsen := controlled.NewSensor(\n\t\tctx,\n\t\texe,\n\t\tnewStubMonitorFunc(ctx, nil, nil),\n\t\tnil, //Monitor Data Event Log\n\t\t&artifactorStub{},\n\t\t\"\", \"\",\n\t)\n\n\tgo func() {\n\t\texe.SendCommand(&command.StartMonitor{})\n\t\texe.SendCommand(&command.ShutdownSensor{})\n\t}()\n\n\tif err := sen.Run(); !errors.Is(err, controlled.ErrPrematureShutdown) {\n\t\tt.Fatal(\"Unexpected sensor run error:\", err)\n\t}\n}\n\nfunc TestStopNonStartedMonitor(t *testing.T) {\n\tctx := context.Background()\n\texe := execution.NewExecution()\n\tsen := controlled.NewSensor(\n\t\tctx,\n\t\texe,\n\t\tnewStubMonitorFunc(ctx, nil, nil),\n\t\tnil, //Monitor Data Event Log\n\t\t&artifactorStub{},\n\t\t\"\", \"\",\n\t)\n\n\tgo func() {\n\t\texe.SendCommand(&command.StopMonitor{})\n\t\texe.SendCommand(&command.ShutdownSensor{})\n\t}()\n\n\tif err := sen.Run(); err != nil {\n\t\tt.Fatal(\"Unexpected sensor run error:\", err)\n\t}\n}\n"
  },
  {
    "path": "pkg/app/sensor/detector/binfile/binfile.go",
    "content": "package binfile\n\nimport (\n\t\"debug/elf\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\ntype BinProps struct {\n\tIsBin bool\n\tIsSO  bool\n\tIsExe bool\n}\n\nfunc Detected(filePath string) (*BinProps, error) {\n\tbinFile, err := elf.Open(filePath)\n\tif err == nil {\n\t\tbinProps := &BinProps{\n\t\t\tIsBin: true,\n\t\t}\n\n\t\tswitch binFile.Type {\n\t\tcase elf.ET_EXEC:\n\t\t\tbinProps.IsExe = true\n\t\tcase elf.ET_DYN:\n\t\t\tbinProps.IsSO = true\n\t\t}\n\n\t\tbinFile.Close()\n\t\treturn binProps, nil\n\t}\n\n\tlog.Debugf(\"binfile.Detected(%v) - elf.Open error: %v\", filePath, err)\n\n\tif elfErr, ok := err.(*elf.FormatError); ok {\n\t\tif strings.Contains(elfErr.Error(), \"bad magic number\") {\n\t\t\treturn nil, nil\n\t\t}\n\n\t\tlog.Debugf(\"binfile.Detected(%v) - malformed binary file\", filePath)\n\t\treturn nil, err\n\t}\n\n\treturn nil, err\n}\n"
  },
  {
    "path": "pkg/app/sensor/detector/filetype/filetype.go",
    "content": "package filetype\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst (\n\tfileTypeCmdName = \"file\"\n)\n\nvar fileTypeCmd string\n\nfunc init() {\n\tfindFileTypeCmd()\n}\n\nfunc findFileTypeCmd() {\n\tfileTypeCmd, err := exec.LookPath(fileTypeCmdName)\n\tif err != nil {\n\t\tlog.Debugf(\"findFileTypeCmd - cmd not found: %v\", err)\n\t\treturn\n\t}\n\n\tlog.Debugf(\"findFileTypeCmd - cmd found: %v\", fileTypeCmd)\n}\n\nfunc Detect(filePath string) (string, error) {\n\t//TODO: use libmagic (pure impl)\n\tvar cerr bytes.Buffer\n\tvar cout bytes.Buffer\n\n\tif fileTypeCmd != \"\" {\n\t\treturn \"\", nil\n\t}\n\n\tcmd := exec.Command(fileTypeCmd, filePath)\n\tcmd.Stderr = &cerr\n\tcmd.Stdout = &cout\n\n\tif err := cmd.Start(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif err := cmd.Wait(); err != nil {\n\t\terr = fmt.Errorf(\"Detect - error getting data type: %s / stderr: %s\", err, cerr.String())\n\t\treturn \"\", err\n\t}\n\n\tif typeInfo := strings.Split(strings.TrimSpace(cout.String()), \":\"); len(typeInfo) > 1 {\n\t\treturn strings.TrimSpace(typeInfo[1]), nil\n\t}\n\n\treturn \"unknown\", nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/execution/controlled.go",
    "content": "package execution\n\nimport (\n\t\"context\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/ipc\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n)\n\ntype controlledExe struct {\n\thookExecutor\n\n\tipcServer *ipc.Server\n}\n\nfunc NewControlled(\n\tctx context.Context,\n\tlifecycleHookCommand string,\n) (Interface, error) {\n\tlog.Debug(\"sensor: starting IPC server...\")\n\n\tipcServer, err := ipc.NewServer(ctx.Done())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := ipcServer.Run(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &controlledExe{\n\t\thookExecutor: hookExecutor{\n\t\t\tctx: ctx,\n\t\t\tcmd: lifecycleHookCommand,\n\t\t},\n\t\tipcServer: ipcServer,\n\t}, nil\n}\n\nfunc (e *controlledExe) Close() {\n\te.ipcServer.Stop()\n}\n\nfunc (e *controlledExe) Commands() <-chan command.Message {\n\treturn e.ipcServer.CommandChan()\n}\n\nfunc (e *controlledExe) PubEvent(etype event.Type, data ...interface{}) {\n\tevt := &event.Message{Name: etype}\n\tif len(data) > 0 {\n\t\tevt.Data = data[0]\n\t}\n\n\te.ipcServer.TryPublishEvt(evt, 3)\n}\n"
  },
  {
    "path": "pkg/app/sensor/execution/hook.go",
    "content": "package execution\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/acounter\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n)\n\ntype kind string\n\nconst (\n\tsensorPostStart     kind = \"sensor-post-start\"\n\tsensorPreShutdown   kind = \"sensor-pre-shutdown\"\n\tmonitorPreStart     kind = \"monitor-pre-start\"\n\ttargetAppRunning    kind = \"target-app-running\"\n\tmonitorPostShutdown kind = \"monitor-post-shutdown\"\n\tmonitorFailed       kind = \"monitor-failed\"\n)\n\n// todo:\n// add 'kind' to the lifecycle event and\n// pass the whole event to the lifecycle hook command\ntype LifecycleEvent struct {\n\tTimestamp int64  `json:\"ts\"`\n\tSeqNumber uint64 `json:\"sn\"`\n}\n\ntype hookExecutor struct {\n\tctx       context.Context\n\tcmd       string\n\tlastHook  kind\n\tseqNumber acounter.Type\n}\n\nfunc (h *hookExecutor) State() string {\n\treturn fmt.Sprintf(\"%s/%s\", h.cmd, string(h.lastHook))\n}\n\nfunc (h *hookExecutor) HookSensorPostStart() {\n\th.doHook(sensorPostStart)\n}\n\nfunc (h *hookExecutor) HookSensorPreShutdown() {\n\th.doHook(sensorPreShutdown)\n}\n\nfunc (h *hookExecutor) HookMonitorPreStart() {\n\th.doHook(monitorPreStart)\n}\n\nfunc (h *hookExecutor) HookTargetAppRunning() {\n\th.doHook(targetAppRunning)\n}\n\nfunc (h *hookExecutor) HookMonitorPostShutdown() {\n\th.doHook(monitorPostShutdown)\n}\n\nfunc (h *hookExecutor) HookMonitorFailed() {\n\th.doHook(monitorFailed)\n}\n\nfunc (h *hookExecutor) doHook(k kind) {\n\tif len(h.cmd) == 0 {\n\t\treturn\n\t}\n\n\tevent := LifecycleEvent{\n\t\tTimestamp: time.Now().UTC().UnixNano(),\n\t\tSeqNumber: h.seqNumber.Inc(),\n\t}\n\n\th.lastHook = k\n\t//todo: pass event as a base64 encoded json string as an extra param to 'cmd'\n\tcmd := exec.CommandContext(h.ctx, h.cmd, string(k))\n\tout, err := cmd.CombinedOutput()\n\n\tlogger := log.\n\t\tWithField(\"kind\", string(k)).\n\t\tWithField(\"event\", fmt.Sprintf(\"%+v\", event)).\n\t\tWithField(\"command\", h.cmd).\n\t\tWithField(\"exit_code\", cmd.ProcessState.ExitCode()).\n\t\tWithField(\"output\", string(out))\n\n\t// Some lifecycle hooks are really fast - hence, the IsNoChildProcesses() check.\n\tif err == nil || errutil.IsNoChildProcesses(err) {\n\t\tlogger.Debugf(\"sensor: %s hook succeeded\", k)\n\t} else {\n\t\tlogger.WithError(err).Warnf(\"sensor: %s hook failed\", k)\n\t}\n}\n"
  },
  {
    "path": "pkg/app/sensor/execution/interface.go",
    "content": "package execution\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n)\n\ntype Interface interface {\n\tState() string\n\tCommands() <-chan command.Message\n\tPubEvent(etype event.Type, data ...interface{})\n\tClose()\n\n\t// Lifecycle hooks (extension points)\n\tHookSensorPostStart()\n\tHookSensorPreShutdown()\n\tHookMonitorPreStart()\n\tHookTargetAppRunning()\n\tHookMonitorPostShutdown()\n\tHookMonitorFailed()\n}\n"
  },
  {
    "path": "pkg/app/sensor/execution/standalone.go",
    "content": "package execution\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/standalone/control\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\ntype standaloneExe struct {\n\thookExecutor\n\n\tcommandCh chan command.Message\n\teventFile io.WriteCloser\n}\n\nfunc NewStandalone(\n\tctx context.Context,\n\tcommandFileName string,\n\teventFileName string,\n\tlifecycleHookCommand string,\n) (Interface, error) {\n\t// fsutil.Touch() creates (potentially missing) folder(s).\n\tif err := fsutil.Touch(eventFileName); err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"cannot create execution - touch event file %q failed: %w\",\n\t\t\teventFileName, err,\n\t\t)\n\t}\n\n\teventFile, err := os.OpenFile(eventFileName, os.O_APPEND|os.O_WRONLY|os.O_SYNC, 0644)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"cannot create execution - open event file %q failed: %w\",\n\t\t\teventFileName, err,\n\t\t)\n\t}\n\n\tcmd, err := readCommandFile(commandFileName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"cannot create execution - cannot read command file %q: %w\",\n\t\t\tcommandFileName, err,\n\t\t)\n\t}\n\n\tcommandCh := make(chan command.Message, 10)\n\tcommandCh <- &cmd\n\n\tgo control.HandleControlCommandQueue(ctx, commandFileName, commandCh)\n\n\treturn &standaloneExe{\n\t\thookExecutor: hookExecutor{\n\t\t\tctx: ctx,\n\t\t\tcmd: lifecycleHookCommand,\n\t\t},\n\t\tcommandCh: commandCh,\n\t\teventFile: eventFile,\n\t}, nil\n}\n\nfunc (e *standaloneExe) Close() {\n\te.eventFile.Close()\n\tclose(e.commandCh)\n}\n\nfunc (e *standaloneExe) Commands() <-chan command.Message {\n\treturn e.commandCh\n}\n\nfunc (e *standaloneExe) PubEvent(name event.Type, data ...interface{}) {\n\tencoder := json.NewEncoder(e.eventFile)\n\tencoder.SetEscapeHTML(false)\n\tevt := event.Message{Name: name}\n\tif len(data) > 0 {\n\t\tevt.Data = data[0]\n\t}\n\n\tif err := encoder.Encode(evt); err != nil {\n\t\tlog.WithError(err).Warn(\"sensor: failed dumping event\")\n\t}\n}\n\n// TODO: Make this function return a list of commands.\nfunc readCommandFile(filename string) (command.StartMonitor, error) {\n\tvar cmd command.StartMonitor\n\n\tdata, err := os.ReadFile(filename)\n\tif err != nil {\n\t\treturn cmd, fmt.Errorf(\"could not read command file %q: %w\", filename, err)\n\t}\n\tdata = bytes.Split(data, []byte(\"\\n\"))[0]\n\n\tif err := json.Unmarshal(data, &cmd); err != nil {\n\t\treturn cmd, fmt.Errorf(\"could not decode command %q: %w\", string(data), err)\n\t}\n\n\t// The instrumented image will always have the ENTRYPOINT overwritten\n\t// by the instrumentor to make the sensor the PID1 process in the monitored\n\t// container.\n\t// The original ENTRYPOINT & CMD will be preserved as part of the\n\t// `commands.json` file. However, it's also possible to override the\n\t// CMD at runtime by supplying extra args to the `docker run` (or alike)\n\t// command. Sensor needs to be able to detect this and replace the\n\t// baked in CMD with the new list of args. For that, the instrumented image's\n\t// ENTRYPOINT has to contain a special separator value `--` denoting the end\n\t// of the sensor's flags sequence. Example:\n\t//\n\t// ENTRYPOINT [\"/path/to/sensor\", \"-m=standalone\", \"-c=/path/to/commands.json\", \"--\" ]\n\n\t// Note on CMD & ENTRYPOINT override: Historically, sensor used\n\t// AppName + AppArgs[] to start the target process. With the addition\n\t// of the standalone mode, the need for supporting Docker's original\n\t// CMD[] + ENTRYPOINT[] approach arose. However, to keep things simple:\n\t//\n\t//  - These two \"modes\" of starting the target app will be mutually exclusive\n\t//    (from the sensor's users standpoint).\n\t//  - The CMD + ENTRYPOINT mode will be converted back to the AppName + AppArgs\n\t//    early on in the sensor's processing (to prevent cascading changes).\n\n\t// First, check if there is a run-time override of the CMD[] part\n\t// (i.e., anything after the `--` separator).\n\t// If there is some, it'll essentially \"activate\" the CMD + ENTRYPOINT mode.\n\tif args := flag.Args(); len(args) > 0 {\n\t\tcmd.AppCmd = args\n\t}\n\n\t// If it's ENTRYPOINT + CMD mode, converting back to AppName + AppArgs.\n\tif len(cmd.AppEntrypoint)+len(cmd.AppCmd) > 0 {\n\t\tif len(cmd.AppName)+len(cmd.AppArgs) > 0 {\n\t\t\treturn cmd, errors.New(\"ambiguous start command: cannot use [app_name,app_args] and [app_entrypoint,app_cmd] simultaneously\")\n\t\t}\n\n\t\tif len(cmd.AppEntrypoint) > 0 {\n\t\t\tcmd.AppName = cmd.AppEntrypoint[0]\n\t\t\tcmd.AppArgs = append(cmd.AppEntrypoint[1:], cmd.AppCmd...)\n\t\t} else {\n\t\t\tcmd.AppName = cmd.AppCmd[0]\n\t\t\tcmd.AppArgs = cmd.AppCmd[1:]\n\t\t}\n\t}\n\n\treturn cmd, nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/inspector/sodeps/sodeps.go",
    "content": "package sodeps\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/detector/binfile\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// Inspector errors\nvar (\n\tErrFilePathNotAbs      = errors.New(\"file path is not absolute\")\n\tErrFileNotBin          = errors.New(\"file is not a binary\")\n\tErrDepResolverNotFound = errors.New(\"dependency resolver not found\")\n)\n\nconst (\n\tresolverExeName = \"ldd\"\n)\n\nfunc AllExeDependencies(exeFileName string, find bool) ([]string, error) {\n\tif !strings.HasPrefix(exeFileName, \"/\") {\n\t\tif !find {\n\t\t\treturn nil, ErrFilePathNotAbs\n\t\t}\n\n\t\texePath, err := exec.LookPath(exeFileName)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\texeFileName = exePath\n\t}\n\n\treturn AllDependencies(exeFileName)\n}\n\nconst (\n\tstrExitStatus       = \"exit status 127\"\n\tstrErrorReloc       = \"Error relocating\"\n\tstrErrorSymNotFound = \"symbol not found\"\n)\n\nfunc AllDependencies(binFilePath string) ([]string, error) {\n\t//binFilePath could point to an executable or a shared object\n\tif !strings.HasPrefix(binFilePath, \"/\") {\n\t\treturn nil, ErrFilePathNotAbs\n\t}\n\n\tif _, err := os.Stat(binFilePath); err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): missing target - %v\", binFilePath, err)\n\t\t}\n\n\t\treturn nil, err\n\t}\n\n\tif binProps, _ := binfile.Detected(binFilePath); binProps == nil || !binProps.IsBin {\n\t\treturn nil, ErrFileNotBin\n\t}\n\n\tresolverExePath, err := exec.LookPath(resolverExeName)\n\tif err != nil {\n\t\tlog.Debugf(\"sodeps.AllDependencies(%v): resolver not found - %v\", binFilePath, err)\n\t\treturn nil, ErrDepResolverNotFound\n\t}\n\n\tvar cerr bytes.Buffer\n\tvar cout bytes.Buffer\n\tcmd := exec.Command(resolverExePath, binFilePath)\n\tcmd.Stderr = &cerr\n\tcmd.Stdout = &cout\n\n\tif err := cmd.Start(); err != nil {\n\t\tlog.Debugf(\"sodeps.AllDependencies(%v): exe run error - %v\", binFilePath, err)\n\t\treturn nil, err\n\t}\n\n\tdepMap := map[string]struct{}{}\n\tvar deps []string\n\tdeps = append(deps, binFilePath)\n\n\tif err := cmd.Wait(); err != nil {\n\t\tif strings.Contains(err.Error(), strExitStatus) &&\n\t\t\tstrings.Contains(cerr.String(), strErrorReloc) &&\n\t\t\tstrings.Contains(cerr.String(), strErrorSymNotFound) {\n\t\t\telines := strings.Split(cerr.String(), \"\\n\")\n\t\t\tfor _, line := range elines {\n\t\t\t\tclean := strings.TrimSpace(line)\n\t\t\t\tif len(clean) == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif !strings.Contains(clean, strErrorReloc) {\n\t\t\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): skipping '%s'\", binFilePath, line)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tparts := strings.Split(clean, \" \")\n\t\t\t\t//Error relocating __LIB_NAME__: __SYMBOL_NAME__: symbol not found\n\t\t\t\tif len(parts) == 7 {\n\t\t\t\t\tif strings.HasSuffix(parts[2], \":\") {\n\t\t\t\t\t\tdep := strings.Trim(parts[2], \":\")\n\t\t\t\t\t\tdepMap[dep] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): skipping '%s'\", binFilePath, line)\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): exe error result - %v (stderr: '%v')\", binFilePath, err, cerr.String())\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tfor dep := range depMap {\n\t\tdeps = append(deps, dep)\n\t}\n\n\tlines := strings.Split(cout.String(), \"\\n\")\n\tfor _, line := range lines {\n\t\tclean := strings.TrimSpace(line)\n\t\tif len(clean) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.Contains(clean, \"statically linked\") {\n\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): statically linked binary file\", binFilePath)\n\t\t\tcontinue\n\t\t}\n\n\t\tparts := strings.Split(clean, \" \")\n\n\t\tif len(parts) == 4 {\n\t\t\tif parts[1] != \"=>\" {\n\t\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): unexpected line format - '%v'\", binFilePath, clean)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif parts[2] == resolverExeName {\n\t\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): ignore non-lib dependency - '%v'\", binFilePath, clean)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tdeps = append(deps, parts[2])\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(parts) == 2 {\n\t\t\tif strings.HasPrefix(parts[0], \"/\") {\n\t\t\t\t//full path (dynamic linker)\n\t\t\t\tdeps = append(deps, parts[0])\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(parts[0], \"linux-vdso\") {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(parts[0], resolverExeName) {\n\t\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): ignore resolver dependency - '%v'\", binFilePath, clean)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): unexpected line - '%v'\", binFilePath, clean)\n\t\t\tcontinue\n\t\t}\n\t}\n\n\tvar allDeps []string\n\tfor depth := 0; len(deps) > 0; depth++ {\n\t\tvar fileDeps []string\n\t\tfileDeps, deps = resolveDepArtifacts(deps)\n\t\tallDeps = append(allDeps, fileDeps...)\n\n\t\tif depth > 5 {\n\t\t\tlog.Debugf(\"sodeps.AllDependencies(%v): link ref too deep - breaking\", binFilePath)\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn allDeps, nil\n}\n\nfunc resolveDepArtifacts(names []string) (files, links []string) {\n\tfor _, name := range names {\n\t\tif info, err := os.Lstat(name); err == nil {\n\t\t\tfiles = append(files, name)\n\t\t\tif info.Mode()&os.ModeSymlink != 0 {\n\t\t\t\tlinkRef, err := os.Readlink(name)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Debugf(\"sodeps.resolveDepArtifacts: %v - error reading link (%v)\\n\", name, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tvar absLinkRef string\n\t\t\t\tif !filepath.IsAbs(linkRef) {\n\t\t\t\t\tlinkDir := filepath.Dir(name)\n\t\t\t\t\tfullLinkRef := filepath.Join(linkDir, linkRef)\n\t\t\t\t\tvar err error\n\t\t\t\t\tabsLinkRef, err = filepath.Abs(fullLinkRef)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"sodeps.resolveDepArtifacts: %v - error getting absolute path for symlink ref (1) %v - (%v)\\n\", name, fullLinkRef, err)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tvar err error\n\t\t\t\t\tabsLinkRef, err = filepath.Abs(linkRef)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"sodeps.resolveDepArtifacts: %v - error getting absolute path for symlink ref (2) %v - (%v)\\n\", name, linkRef, err)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlinks = append(links, absLinkRef)\n\t\t\t}\n\t\t} else {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tlog.Debugf(\"sodeps.resolveDepArtifacts: %v - missing dep (%v)\\n\", name, err)\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"sodeps.resolveDepArtifacts: %v - error checking dep (%v)\\n\", name, err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn files, links\n}\n"
  },
  {
    "path": "pkg/app/sensor/ipc/ipc.go",
    "content": "package ipc\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/ipc/channel\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n)\n\ntype Server struct {\n\tevtChannel *channel.EventServer\n\tcmdChannel *channel.CommandServer\n\tcmdChan    chan command.Message\n\tdoneChan   <-chan struct{}\n}\n\nfunc NewServer(doneChan <-chan struct{}) (*Server, error) {\n\tserver := Server{\n\t\tdoneChan: doneChan,\n\t\tcmdChan:  make(chan command.Message, 10),\n\t}\n\n\tif err := server.initChannels(); err != nil {\n\t\tlog.Errorf(\"sensor: ipc.NewServer error = %v\", err)\n\t\treturn nil, err\n\t}\n\n\treturn &server, nil\n}\n\nfunc (s *Server) initChannels() error {\n\tevtChannelAddr := fmt.Sprintf(\"0.0.0.0:%d\", channel.EvtPort)\n\tevtChannel := channel.NewEventServer(evtChannelAddr)\n\ts.evtChannel = evtChannel\n\n\tcmdChannelAddr := fmt.Sprintf(\"0.0.0.0:%d\", channel.CmdPort)\n\tcmdChannel := channel.NewCommandServer(cmdChannelAddr, s)\n\ts.cmdChannel = cmdChannel\n\n\treturn nil\n}\n\nfunc (s *Server) shutdownChannels() error {\n\tif s.cmdChannel != nil {\n\t\ts.cmdChannel.Stop()\n\t\ts.cmdChannel = nil\n\t}\n\n\tif s.evtChannel != nil {\n\t\ts.evtChannel.Stop()\n\t\ts.evtChannel = nil\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) Stop() {\n\ts.shutdownChannels()\n}\n\nfunc (s *Server) CommandChan() <-chan command.Message {\n\treturn s.cmdChan\n}\n\nfunc (s *Server) OnRequest(data []byte) ([]byte, error) {\n\tresp := command.Response{\n\t\tStatus: command.ResponseStatusError,\n\t}\n\n\tif cmd, err := command.Decode(data); err == nil {\n\t\ts.cmdChan <- cmd\n\t\tresp.Status = command.ResponseStatusOk\n\t} else {\n\t\tlog.Errorf(\"ipc.Server.OnRequest: error decoding request = %v\", err)\n\t}\n\n\trespData, err := json.Marshal(&resp)\n\tif err != nil {\n\t\tlog.Errorf(\"ipc.Server.OnRequest: error encoding response = %v\", err)\n\t\treturn nil, err\n\t}\n\n\treturn respData, nil\n}\n\nfunc (s *Server) Run() error {\n\tlog.Debug(\"sensor: ipc.Server.Run()\")\n\terr := s.evtChannel.Start(true)\n\tif err != nil {\n\t\tlog.Errorf(\"sensor: ipc.Server.Run() - evtChannel.Start error = %v\\n\", err)\n\t\treturn err\n\t}\n\n\terr = s.cmdChannel.Start(true)\n\tif err != nil {\n\t\tlog.Errorf(\"sensor: ipc.Server.Run() - cmdChannel.Start error = %v\\n\", err)\n\t\treturn err\n\t}\n\n\ts.cmdChannel.WaitForConnection()\n\ts.evtChannel.WaitForConnection()\n\n\tgo func() {\n\t\tfor {\n\t\t\tlog.Debug(\"sensor: ipc.Server.Run - waiting for done signal...\")\n\t\t\tselect {\n\t\t\tcase <-s.doneChan:\n\t\t\t\tlog.Debug(\"sensor: ipc.Server.Run - done...\")\n\t\t\t\ts.Stop()\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc (s *Server) TryPublishEvt(evt *event.Message, retries uint) error {\n\tlog.Debugf(\"ipc.Server.TryPublishEvt(%+v)\", evt)\n\n\tif s.evtChannel == nil {\n\t\tlog.Warnf(\"ipc.Server.TryPublishEvt(): skipped - server has already been stopped\")\n\t\treturn nil\n\t}\n\n\tdata, err := json.Marshal(evt)\n\tif err != nil {\n\t\tlog.Errorf(\"app.TryPublishEvt(): failed to encode event - %v\", err)\n\t\treturn err\n\t}\n\n\treturn s.evtChannel.Publish(data, retries)\n}\n"
  },
  {
    "path": "pkg/app/sensor/logger.go",
    "content": "//go:build linux\n// +build linux\n\npackage sensor\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nfunc configureLogger(\n\tenableDebug bool,\n\tlevelName string,\n\tformat string,\n\tlogFile string,\n) error {\n\tif err := setLogLevel(enableDebug, levelName); err != nil {\n\t\treturn fmt.Errorf(\"failed to set log-level: %v\", err)\n\t}\n\n\tif err := setLogFormat(format); err != nil {\n\t\treturn fmt.Errorf(\"failed to set log format: %v\", err)\n\t}\n\n\tif len(logFile) > 0 {\n\t\t// This touch is not ideal - need to understand how to merge this logic with artifacts.PrepareEnv().\n\t\tif err := fsutil.Touch(logFile); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to set log output destination to %q, touch failed with: %v\", logFile, err)\n\t\t}\n\n\t\tf, err := os.OpenFile(logFile, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to set log output destination to %q: %w\", logFile, err)\n\t\t}\n\n\t\tlog.SetOutput(f)\n\t}\n\n\treturn nil\n}\n\nfunc setLogFormat(format string) error {\n\tswitch format {\n\tcase \"text\":\n\t\tlog.SetFormatter(&log.TextFormatter{DisableColors: true})\n\tcase \"json\":\n\t\tlog.SetFormatter(&log.JSONFormatter{})\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown log-format %q\", format)\n\t}\n\n\treturn nil\n}\n\nfunc setLogLevel(enableDebug bool, levelName string) error {\n\tif enableDebug {\n\t\tlog.SetLevel(log.DebugLevel)\n\t\treturn nil\n\t}\n\n\tvar logLevel log.Level\n\n\tswitch levelName {\n\tcase \"trace\":\n\t\tlogLevel = log.TraceLevel\n\tcase \"debug\":\n\t\tlogLevel = log.DebugLevel\n\tcase \"info\":\n\t\tlogLevel = log.InfoLevel\n\tcase \"warn\":\n\t\tlogLevel = log.WarnLevel\n\tcase \"error\":\n\t\tlogLevel = log.ErrorLevel\n\tcase \"fatal\":\n\t\tlogLevel = log.FatalLevel\n\tcase \"panic\":\n\t\tlogLevel = log.PanicLevel\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown log-level %q\", levelName)\n\t}\n\n\tlog.SetLevel(logLevel)\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/monitor/composite.go",
    "content": "package monitor\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor/fanotify\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor/ptrace\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n)\n\nconst (\n\tsignalChanBufSize = 10\n\n\terrorChanBufSize   = 100\n\terrorChanDrainTime = 200 * time.Millisecond\n\n\t// Some monitors are passive. If the driving monitor\n\t// is too fast, the passive ones may not have a chance\n\t// to track all the needed events (used to happen often\n\t// between the driving ptrace and observing fanotify mons).\n\tminPassiveMonitoring = 1 * time.Second\n)\n\nvar (\n\tErrInsufficientPermissions = errors.New(\"insufficient permissions\")\n)\n\ntype CompositeReport struct {\n\tPeReport  *report.PeMonitorReport\n\tFanReport *report.FanMonitorReport\n\tPtReport  *report.PtMonitorReport\n}\n\ntype CompositeMonitor interface {\n\t// Start() is not reentrant!\n\tStart() error\n\n\t// Just a helper getter.\n\tStartCommand() *command.StartMonitor\n\n\tSignalTargetApp(s os.Signal)\n\n\tCancel()\n\n\t// Done() is reentrant. Every invocation returns the same instance of the channel.\n\tDone() <-chan struct{}\n\n\t// Errors() method is a way to communicate non-fatal monitor's error\n\t// conditions back to the caller. The method is reentrant. Every invocation\n\t// returns the same instance of the channel. The error channel is never closed,\n\t// but ideally it should stop returning eny errors after the monitor is done\n\t// (the actual behavior might differ due to the subordinate monitors, especially\n\t// the one at pkg/monitors/ptrace).\n\tErrors() <-chan error\n\n\t// Helper method to read left-over non-critical error events after the monitor\n\t// is done.\n\tDrainErrors() []error\n\n\t// TODO: Consider adding the Files() method for the incremental\n\t//       report storing.\n\t// Files() <-chan *ArtifactProp\n\n\tStatus() (*CompositeReport, error)\n}\n\n// The sensor is designed to be capable of processing multiple\n// StartMonitor commands (sequentially?). However, monitors are\n// supposed to be one-shot entities. Every time the sensor receives\n// a new start command, it should initialize a new instance of the\n// composite monitor using fresh instances of the underlying mons.\ntype monitor struct {\n\tcmd *command.StartMonitor\n\tdel mondel.Publisher\n\n\tstartedAt time.Time\n\n\t// peMon  *pevent.Monitor\n\tfanMon fanotify.Monitor\n\tptMon  ptrace.Monitor\n\n\t// Inspired by os/exec.Cmd\n\tcloseAfterDone []io.Closer\n\n\tsignalCh chan os.Signal\n\n\tdoneCh   chan struct{}\n\tdoneOnce sync.Once\n\n\terrorCh chan error\n}\n\nvar _ CompositeMonitor = (*monitor)(nil)\n\ntype NewCompositeMonitorFunc func(\n\tctx context.Context,\n\tcmd *command.StartMonitor,\n\tworkDir string,\n\tdel mondel.Publisher,\n\tartifactsDir string,\n\tmountPoint string,\n\torigPaths map[string]struct{},\n) (CompositeMonitor, error)\n\nfunc NewCompositeMonitor(\n\tctx context.Context,\n\tcmd *command.StartMonitor,\n\tworkDir string,\n\tdel mondel.Publisher,\n\tartifactsDir string,\n\tmountPoint string,\n\torigPaths map[string]struct{},\n) (CompositeMonitor, error) {\n\tlog.Info(\"sensor: creating monitors...\")\n\n\terrorCh := make(chan error, errorChanBufSize)\n\n\tfanMon := fanotify.NewMonitor(\n\t\tctx,\n\t\tdel,\n\t\tartifactsDir,\n\t\tmountPoint,\n\t\tcmd.IncludeNew,\n\t\torigPaths,\n\t\terrorCh,\n\t)\n\n\tvar closeAfterDone []io.Closer\n\n\tappStdout := os.Stdout\n\tif cmd.AppStdoutToFile {\n\t\tsink, file, err := dupAppStdStream(artifactsDir, os.Stdout, \"stdout\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcloseAfterDone = append(closeAfterDone, sink, file)\n\t\tappStdout = sink\n\t}\n\n\tappStderr := os.Stderr\n\tif cmd.AppStderrToFile {\n\t\tsink, file, err := dupAppStdStream(artifactsDir, os.Stderr, \"stderr\")\n\t\tif err != nil {\n\t\t\tcloseAll(closeAfterDone)\n\t\t\treturn nil, err\n\t\t}\n\t\tcloseAfterDone = append(closeAfterDone, sink, file)\n\t\tappStderr = sink\n\t}\n\n\tsignalCh := make(chan os.Signal, signalChanBufSize)\n\n\tptMon := ptrace.NewMonitor(\n\t\tctx,\n\t\tdel,\n\t\tartifactsDir,\n\t\tptrace.AppRunOpt{\n\t\t\tCmd:                 cmd.AppName,\n\t\t\tArgs:                cmd.AppArgs,\n\t\t\tAppStdout:           appStdout,\n\t\t\tAppStderr:           appStderr,\n\t\t\tWorkDir:             workDir,\n\t\t\tUser:                cmd.AppUser,\n\t\t\tRunAsUser:           cmd.RunTargetAsUser,\n\t\t\tRTASourcePT:         cmd.RTASourcePT,\n\t\t\tReportOnMainPidExit: cmd.ReportOnMainPidExit,\n\t\t},\n\t\tcmd.IncludeNew,\n\t\torigPaths,\n\t\tsignalCh,\n\t\terrorCh,\n\t)\n\n\tm := Compose(cmd, del, fanMon, ptMon, signalCh, errorCh)\n\tm.closeAfterDone = closeAfterDone\n\n\treturn m, nil\n}\n\nfunc Compose(\n\tcmd *command.StartMonitor,\n\tdel mondel.Publisher,\n\tfanMon fanotify.Monitor,\n\tptMon ptrace.Monitor,\n\tsignalCh chan os.Signal,\n\terrorCh chan error,\n) *monitor {\n\treturn &monitor{\n\t\tcmd: cmd,\n\t\tdel: del,\n\t\t// TODO: peMon:  peMon,\n\t\tfanMon: fanMon,\n\t\tptMon:  ptMon,\n\n\t\tsignalCh: signalCh,\n\t\terrorCh:  errorCh,\n\t}\n}\n\n// TODO: Consider adding an option to make fanotify\n//\n//\tand pevent monitor errors non-fatal.\nfunc (m *monitor) Start() error {\n\tlog.Info(\"sensor: starting monitors...\")\n\n\t// if err := m.peMon.Start(); err != nil {\n\t// \treturn err\n\t// }\n\n\tif err := m.fanMon.Start(); err != nil {\n\t\tlog.WithError(err).Debug(\"sensor: composite monitor - FAN error\")\n\t\tlog.Error(\"sensor: composite monitor - FAN failed to start running\")\n\n\t\tif strings.Contains(err.Error(), \"operation not permitted\") {\n\t\t\treturn ErrInsufficientPermissions\n\t\t}\n\n\t\tcloseAll(m.closeAfterDone)\n\t\treturn err\n\t}\n\n\tif err := m.ptMon.Start(); err != nil {\n\t\tlog.WithError(err).Debug(\"sensor: composite monitor - PTAN error\")\n\t\tlog.Error(\"sensor: composite monitor - PTAN failed to start running\")\n\n\t\tcloseAll(m.closeAfterDone)\n\t\treturn err\n\t}\n\n\tm.startedAt = time.Now()\n\n\treturn nil\n}\n\nfunc (m *monitor) StartCommand() *command.StartMonitor {\n\treturn m.cmd\n}\n\nfunc (m *monitor) SignalTargetApp(s os.Signal) {\n\tm.signalCh <- s\n}\n\nfunc (m *monitor) Cancel() {\n\t// m.peMon.Cancel()\n\tm.fanMon.Cancel()\n\tm.ptMon.Cancel()\n}\n\nfunc (m *monitor) Done() <-chan struct{} {\n\tm.doneOnce.Do(func() {\n\t\tm.doneCh = make(chan struct{})\n\n\t\tgo func() {\n\t\t\tlog.Debug(\"sensor: composite monitor - waiting for sub-monitors...\")\n\n\t\t\t// The order matters here because the ptrace monitor is the\n\t\t\t// driving one while the others are rather passive observers.\n\t\t\t<-m.ptMon.Done()\n\t\t\tlog.Debug(\"sensor: composite monitor - ptmon is done\")\n\n\t\t\t// This code smells... If the ptrace monitor finished too quickly,\n\t\t\t// we have to give the other monitors more time to increase their\n\t\t\t// chances to track the needed events. But we only do this if the\n\t\t\t// driving monitor finished successfully.\n\t\t\telapsed := time.Since(m.startedAt)\n\t\t\tif _, err := m.ptMon.Status(); err == nil && elapsed < minPassiveMonitoring {\n\t\t\t\ttime.Sleep(minPassiveMonitoring - elapsed)\n\t\t\t}\n\n\t\t\t// m.peMon.Cancel()\n\t\t\tm.fanMon.Cancel()\n\n\t\t\t// <-m.peMon.Done()\n\t\t\t<-m.fanMon.Done()\n\t\t\tlog.Debug(\"sensor: composite monitor - fanmon is done\")\n\n\t\t\tcloseAll(m.closeAfterDone)\n\n\t\t\t//need to call del.Stop here to make sure we get all drained monitor events\n\t\t\tif m.del != nil {\n\t\t\t\tm.del.Stop()\n\t\t\t}\n\n\t\t\t// The composite is done when all its subordinates are done.\n\t\t\tclose(m.doneCh)\n\t\t}()\n\t})\n\n\treturn m.doneCh\n}\n\nfunc (m *monitor) Errors() <-chan error {\n\treturn m.errorCh\n}\n\nfunc (m *monitor) DrainErrors() (errors []error) {\n\ttimer := time.After(errorChanDrainTime)\n\n\tfor {\n\t\tselect {\n\t\tcase <-timer:\n\t\t\treturn errors\n\n\t\tcase err := <-m.errorCh:\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n}\n\nfunc (m *monitor) Status() (*CompositeReport, error) {\n\t// peReport, peErr := m.peMon.Status()\n\tfanReport, fanErr := m.fanMon.Status()\n\tptReport, ptErr := m.ptMon.Status()\n\n\tif fanErr != nil || ptErr != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"one or more monitors failed: fanotify.error=%q, ptrace.error=%q\",\n\t\t\tfanErr, ptErr,\n\t\t)\n\t}\n\n\treturn &CompositeReport{\n\t\t// PeReport: peReport,\n\t\tFanReport: fanReport,\n\t\tPtReport:  ptReport,\n\t}, nil\n}\n\nfunc NonCriticalError(err error) error {\n\treturn fmt.Errorf(\"non-critical monitor error: %w\", err)\n}\n\n// Using simple io.MultiWriter(os.Stdout, os.File) would make cmd.Wait()\n// block until either the cmd's stdout is closed or the multi-writer is closed.\n// However, both are impossible. We need the Wait() to return much earlier\n// than the process termination (see pkg/monitors/ptrace logic), and multi-writer\n// cannot be closed at all. Hence, the pipe trick.\nfunc dupAppStdStream(artifactsDir string, w io.Writer, kind string) (*os.File, *os.File, error) {\n\tfilename := filepath.Join(artifactsDir, \"app_\"+kind+\".log\")\n\n\tf, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, 0o644)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"cannot open file %q to duplicate app's %s stream: %w\", filename, kind, err)\n\t}\n\n\tpr, pw, err := os.Pipe()\n\tif err != nil {\n\t\tf.Close()\n\t\treturn nil, nil, fmt.Errorf(\"cannot create pipe for app %s stream: %w\", kind, err)\n\t}\n\n\tgo func() {\n\t\tn, err := io.Copy(io.MultiWriter(w, f), pr)\n\t\tlog.Debugf(\"dupAppStdStream: io.Copy() finished; written=%d error=%v\", n, err)\n\t}()\n\n\treturn pw, f, nil\n}\n\nfunc closeAll(cs []io.Closer) {\n\tfor _, c := range cs {\n\t\terrutil.WarnOn(c.Close())\n\t}\n}\n"
  },
  {
    "path": "pkg/app/sensor/monitor/composite_test.go",
    "content": "package monitor\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"testing\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\tstubmonitor \"github.com/slimtoolkit/slim/pkg/test/stub/sensor/monitor\"\n)\n\nfunc init() {\n\tlog.SetLevel(log.DebugLevel)\n}\n\nfunc TestCompositeMonitor_Lifecycle(t *testing.T) {\n\tmon := &monitor{\n\t\tfanMon: stubmonitor.NewFanMonitor(context.Background()),\n\t\tptMon:  stubmonitor.NewPtMonitor(context.Background()),\n\t}\n\n\tmon.Start()\n\n\tselect {\n\tcase <-mon.Done():\n\t\tt.Fatal(\"composite monitor must not be done yet\")\n\tdefault:\n\t}\n\n\tmon.Cancel()\n\n\tselect {\n\tcase <-mon.Done():\n\t\tbreak\n\tcase <-time.After(1*time.Second + minPassiveMonitoring):\n\t\tt.Fatal(\"composite monitor must be done by this time\")\n\t}\n\n\tselect {\n\tcase <-mon.Done():\n\t\tbreak\n\tdefault:\n\t\tt.Fatal(\"composite monitor Done() method must be reentrant\")\n\t}\n\n\t// TODO: Check the status (reports & final error).\n}\n\nfunc TestCompositeMonitor_DrainErrors(t *testing.T) {\n\tmon := &monitor{\n\t\terrorCh: make(chan error, errorChanBufSize),\n\t}\n\n\tgo func() {\n\t\t// Definitely within the drain window.\n\t\tmon.errorCh <- errors.New(\"err1\")\n\n\t\ttime.Sleep(errorChanDrainTime / 2)\n\n\t\t// Still within the drain window.\n\t\tmon.errorCh <- errors.New(\"err2\")\n\n\t\ttime.Sleep(errorChanDrainTime * 2)\n\n\t\t// Definitely outside of the drain window.\n\t\tmon.errorCh <- errors.New(\"err3\")\n\t}()\n\n\tdrained := mon.DrainErrors()\n\tif len(drained) != 2 {\n\t\tt.Errorf(\"Unexpected number of drained errors: %d\", len(drained))\n\t}\n\tif drained[0].Error() != \"err1\" {\n\t\tt.Errorf(\"Unexpected drained error: %q\", drained[0])\n\t}\n\tif drained[1].Error() != \"err2\" {\n\t\tt.Errorf(\"Unexpected drained error: %q\", drained[1])\n\t}\n}\n"
  },
  {
    "path": "pkg/app/sensor/monitor/fanotify/monitor.go",
    "content": "//go:build linux\n// +build linux\n\npackage fanotify\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/errors\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\tfanapi \"github.com/slimtoolkit/slim/pkg/third_party/madmo/fanotify\"\n)\n\nconst (\n\terrorBufSize   = 10\n\teventBufSize   = 1000\n\tprocFsFdInfo   = \"/proc/self/fd/%d\"\n\tprocFsFilePath = \"/proc/%v/%v\"\n)\n\n// Event is file operation event\ntype Event struct {\n\tID      uint32\n\tPid     int32\n\tFile    string\n\tIsRead  bool\n\tIsWrite bool\n}\n\ntype Monitor interface {\n\t// Starts the long running monitoring. The method itself is not\n\t// blocking and not reentrant!\n\tStart() error\n\n\t// Cancels the underlying ptrace execution context but doesn't\n\t// make the current monitor done immediately. You still need to await\n\t// the final cleanup with <-mon.Done() before accessing the status.\n\tCancel()\n\n\t// With Done clients can await for the monitoring completion.\n\t// The method is reentrant - every invocation returns the same\n\t// instance of the channel.\n\tDone() <-chan struct{}\n\n\tStatus() (*report.FanMonitorReport, error)\n}\n\ntype status struct {\n\treport *report.FanMonitorReport\n\terr    error\n}\n\ntype monitor struct {\n\tctx    context.Context\n\tcancel context.CancelFunc\n\n\tdel mondel.Publisher\n\n\tartifactsDir string\n\tmountPoint   string\n\n\t// TODO: Move the logic behind these two fields to the artifact processig stage.\n\tincludeNew bool\n\torigPaths  map[string]struct{}\n\n\tstatus  status\n\tdoneCh  chan struct{}\n\terrorCh chan<- error\n\n\tlogger *log.Entry\n}\n\nfunc NewMonitor(\n\tctx context.Context,\n\tdel mondel.Publisher,\n\tartifactsDir string,\n\tmountPoint string,\n\tincludeNew bool,\n\torigPaths map[string]struct{},\n\terrorCh chan<- error,\n) Monitor {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": \"sensor\",\n\t\t\"com\": \"fanmon\",\n\t})\n\n\tctx, cancel := context.WithCancel(ctx)\n\treturn &monitor{\n\t\tctx:    ctx,\n\t\tcancel: cancel,\n\n\t\tdel: del,\n\n\t\tartifactsDir: artifactsDir,\n\t\tmountPoint:   mountPoint,\n\t\tincludeNew:   includeNew,\n\t\torigPaths:    origPaths,\n\n\t\tdoneCh:  make(chan struct{}),\n\t\terrorCh: errorCh,\n\t\tlogger:  logger,\n\t}\n}\n\nfunc (m *monitor) Start() error {\n\tlogger := m.logger.WithField(\"op\", \"Start\")\n\tlogger.Info(\"call\")\n\tdefer logger.Info(\"exit\")\n\n\tnd, err := fanapi.Initialize(fanapi.FAN_CLASS_NOTIF, os.O_RDONLY)\n\tif err != nil {\n\t\treturn errors.SE(\"sensor.fanotify.Run/fanapi.Initialize\", \"call.error\", err)\n\t}\n\n\tif err = nd.Mark(\n\t\tfanapi.FAN_MARK_ADD|fanapi.FAN_MARK_MOUNT,\n\t\tfanapi.FAN_MODIFY|fanapi.FAN_ACCESS|fanapi.FAN_OPEN,\n\t\t-1, m.mountPoint,\n\t); err != nil {\n\t\treturn errors.SE(\"sensor.fanotify.Run/nd.Mark\", \"call.error\", err)\n\t}\n\n\t// Sync part of the start was successful.\n\t// Tracking the completetion of the monitor....\n\n\tgo func() {\n\t\tlogger := m.logger.WithField(\"op\", \"collector\")\n\t\tlogger.Info(\"call\")\n\t\tdefer logger.Info(\"exit\")\n\n\t\tvar eventID uint32\n\t\teventCh := make(chan Event, eventBufSize)\n\n\t\tgo func() {\n\t\t\tlogger := m.logger.WithField(\"op\", \"processor\")\n\t\t\tlogger.Info(\"call\")\n\n\t\t\tfanReport := &report.FanMonitorReport{\n\t\t\t\tMonitorPid:       os.Getpid(),\n\t\t\t\tMonitorParentPid: os.Getppid(),\n\t\t\t\tProcessFiles:     map[string]map[string]*report.FileInfo{},\n\t\t\t\tProcesses:        map[string]*report.ProcessInfo{},\n\t\t\t}\n\n\t\tprocess:\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase <-m.ctx.Done():\n\t\t\t\t\tlogger.Info(\"process - done\")\n\t\t\t\t\tbreak process\n\n\t\t\t\tcase e := <-eventCh:\n\t\t\t\t\tm.processEvent(e, fanReport)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.Debug(\"done, drain - starting...\")\n\n\t\tdrain:\n\t\t\tfor {\n\t\t\t\tselect {\n\t\t\t\tcase e := <-eventCh:\n\t\t\t\t\tm.processEvent(e, fanReport)\n\n\t\t\t\tdefault:\n\t\t\t\t\tlogger.Debug(\"draining - done\")\n\t\t\t\t\tbreak drain\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.Debugf(\"sending report (processed %v events)...\", fanReport.EventCount)\n\t\t\tm.status.report = fanReport\n\t\t\tclose(m.doneCh)\n\t\t\tlogger.Info(\"exit\")\n\t\t}()\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-m.ctx.Done():\n\t\t\t\tlogger.Info(\"done - returning\")\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t}\n\n\t\t\t//TODO: enhance FA Notify to return the original file handle too\n\t\t\tdata, err := nd.GetEvent()\n\t\t\tif err != nil {\n\t\t\t\tm.errorCh <- errors.SE(\"sensor.fanotify.Run/nd.GetEvent\", \"call.error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tlogger.Debugf(\"data.Mask => %x\", data.Mask)\n\n\t\t\tif (data.Mask & fanapi.FAN_Q_OVERFLOW) == fanapi.FAN_Q_OVERFLOW {\n\t\t\t\tlogger.Debug(\"overflow event\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tdoNotify := false\n\t\t\tisRead := false\n\t\t\tisWrite := false\n\n\t\t\tif (data.Mask & fanapi.FAN_OPEN) == fanapi.FAN_OPEN {\n\t\t\t\tlogger.Trace(\"FAN.E - file open\")\n\t\t\t\tdoNotify = true\n\t\t\t}\n\n\t\t\tif (data.Mask & fanapi.FAN_ACCESS) == fanapi.FAN_ACCESS {\n\t\t\t\tlogger.Trace(\"FAN.E - file read\")\n\t\t\t\tisRead = true\n\t\t\t\tdoNotify = true\n\t\t\t}\n\n\t\t\tif (data.Mask & fanapi.FAN_MODIFY) == fanapi.FAN_MODIFY {\n\t\t\t\tlogger.Trace(\"FAN.E - file write\")\n\t\t\t\tisWrite = true\n\t\t\t\tdoNotify = true\n\t\t\t}\n\n\t\t\t// Ivan: It might be a good idea to move this from collector to processor.\n\t\t\t// Probably, the fanotify events should be read as quick as just possible.\n\t\t\tpath, err := os.Readlink(fmt.Sprintf(procFsFdInfo, data.File.Fd()))\n\t\t\tif err != nil {\n\t\t\t\tm.errorCh <- errors.SE(\"sensor.fanotify.Run/os.Readlink\", \"call.error\", err)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tdata.File.Close()\n\n\t\t\tlogger.Debugf(\"file path => %v\", path)\n\t\t\tif strings.HasPrefix(path, m.artifactsDir) {\n\t\t\t\tlogger.Trace(\"skipping artifacts dir op...\")\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif doNotify {\n\t\t\t\teventID++\n\t\t\t\te := Event{ID: eventID, Pid: data.Pid, File: path, IsRead: isRead, IsWrite: isWrite}\n\n\t\t\t\tselect {\n\t\t\t\tcase eventCh <- e:\n\t\t\t\tcase <-m.ctx.Done():\n\t\t\t\t\tlogger.Info(\"stopping....\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc (m *monitor) Cancel() {\n\tm.cancel()\n}\n\nfunc (m *monitor) Done() <-chan struct{} {\n\treturn m.doneCh\n}\n\nfunc (m *monitor) Status() (*report.FanMonitorReport, error) {\n\treturn m.status.report, m.status.err\n}\n\nfunc (m *monitor) processEvent(e Event, fanReport *report.FanMonitorReport) {\n\tfanReport.EventCount++\n\tlogger := m.logger.WithField(\"op\", \"processEvent\")\n\tlogger.Debugf(\"[%v] handling event %v\", fanReport.EventCount, e)\n\n\tif m.del != nil {\n\t\tdelEvent := &report.MonitorDataEvent{\n\t\t\tSource:   report.MDESourceFan,\n\t\t\tType:     report.MDETypeArtifact,\n\t\t\tPid:      e.Pid,\n\t\t\tArtifact: e.File,\n\t\t}\n\n\t\tif e.IsRead {\n\t\t\tdelEvent.OpType = report.OpTypeRead\n\t\t}\n\t\tif e.IsWrite {\n\t\t\tdelEvent.OpType = report.OpTypeWrite\n\t\t}\n\n\t\tif err := m.del.Publish(delEvent); err != nil {\n\t\t\tlogger.Errorf(\n\t\t\t\t\"mondel publish event failed - source=%v type=%v: %v\",\n\t\t\t\tdelEvent.Source, delEvent.Type, err,\n\t\t\t)\n\t\t}\n\t}\n\n\tif _, ok := m.origPaths[e.File]; !ok && !m.includeNew {\n\t\treturn\n\t}\n\n\tvar newProcess *report.ProcessInfo\n\tif e.ID == 1 {\n\t\t//first event represents the main process\n\t\tif pinfo, err := getProcessInfo(e.Pid); (err == nil) && (pinfo != nil) {\n\t\t\tfanReport.MainProcess = pinfo\n\t\t\tfanReport.Processes[strconv.Itoa(int(e.Pid))] = pinfo\n\t\t\tnewProcess = pinfo\n\t\t}\n\t} else {\n\t\tif _, ok := fanReport.Processes[strconv.Itoa(int(e.Pid))]; !ok {\n\t\t\tif pinfo, err := getProcessInfo(e.Pid); (err == nil) && (pinfo != nil) {\n\t\t\t\t// Ivan: PIDs can be reused, so we might be overwriting pinfo here.\n\t\t\t\t// But if we consider this probability as too low to care about,\n\t\t\t\t// then we should probably start caching getProcessInfo() calls :)\n\t\t\t\tfanReport.Processes[strconv.Itoa(int(e.Pid))] = pinfo\n\t\t\t\tnewProcess = pinfo\n\t\t\t}\n\t\t}\n\t}\n\n\tif newProcess != nil && m.del != nil {\n\t\tdelEvent := &report.MonitorDataEvent{\n\t\t\tSource:    report.MDESourceFan,\n\t\t\tType:      report.MDETypeProcess,\n\t\t\tPid:       newProcess.Pid,\n\t\t\tParentPid: newProcess.ParentPid,\n\t\t\tArtifact:  newProcess.Path,\n\t\t\tCmd:       newProcess.Cmd,\n\t\t\tWorkDir:   newProcess.Cwd,\n\t\t\tRoot:      newProcess.Root,\n\t\t}\n\t\tif err := m.del.Publish(delEvent); err != nil {\n\t\t\tlogger.Errorf(\n\t\t\t\t\"mondel publish event failed - source=%v type=%v: %v\",\n\t\t\t\tdelEvent.Source, delEvent.Type, err,\n\t\t\t)\n\t\t}\n\t}\n\n\tif _, ok := fanReport.ProcessFiles[strconv.Itoa(int(e.Pid))]; !ok {\n\t\tfanReport.ProcessFiles[strconv.Itoa(int(e.Pid))] = map[string]*report.FileInfo{}\n\t}\n\n\tif existingFi, ok := fanReport.ProcessFiles[strconv.Itoa(int(e.Pid))][e.File]; !ok {\n\t\tfi := &report.FileInfo{\n\t\t\tEventCount:   1,\n\t\t\tName:         e.File,\n\t\t\tFirstEventID: e.ID,\n\t\t}\n\n\t\tif e.IsRead {\n\t\t\tfi.ReadCount = 1\n\t\t}\n\n\t\tif e.IsWrite {\n\t\t\tfi.WriteCount = 1\n\t\t}\n\n\t\tif pi, ok := fanReport.Processes[strconv.Itoa(int(e.Pid))]; ok && (e.File == pi.Path) {\n\t\t\tfi.ExeCount = 1\n\t\t}\n\n\t\tfanReport.ProcessFiles[strconv.Itoa(int(e.Pid))][e.File] = fi\n\t} else {\n\t\texistingFi.EventCount++\n\n\t\tif e.IsRead {\n\t\t\texistingFi.ReadCount++\n\t\t}\n\n\t\tif e.IsWrite {\n\t\t\texistingFi.WriteCount++\n\t\t}\n\n\t\tif pi, ok := fanReport.Processes[strconv.Itoa(int(e.Pid))]; ok && (e.File == pi.Path) {\n\t\t\texistingFi.ExeCount++\n\t\t}\n\t}\n}\n\nfunc procFilePath(pid int, key string) string {\n\treturn fmt.Sprintf(procFsFilePath, pid, key)\n}\n\nfunc getProcessInfo(pid int32) (*report.ProcessInfo, error) {\n\tinfo := &report.ProcessInfo{Pid: pid}\n\tvar err error\n\n\tinfo.Path, err = os.Readlink(procFilePath(int(pid), \"exe\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo.Cwd, err = os.Readlink(procFilePath(int(pid), \"cwd\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tinfo.Root, err = os.Readlink(procFilePath(int(pid), \"root\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\trawCmdline, err := os.ReadFile(procFilePath(int(pid), \"cmdline\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(rawCmdline) > 0 {\n\t\trawCmdline = bytes.TrimRight(rawCmdline, \"\\x00\")\n\t\t//NOTE: later/future (when we do more app analytics)\n\t\t//split rawCmdline and resolve the \"entry point\" (exe or cmd param)\n\t\tinfo.Cmd = string(bytes.Replace(rawCmdline, []byte(\"\\x00\"), []byte(\" \"), -1))\n\t}\n\n\t//note: will need to get \"environ\" at some point :)\n\t//rawEnviron, err := os.ReadFile(procFilePath(int(pid), \"environ\"))\n\t//if err != nil {\n\t//\treturn nil, err\n\t//}\n\t//if len(rawEnviron) > 0 {\n\t//\trawEnviron = bytes.TrimRight(rawEnviron,\"\\x00\")\n\t//\tinfo.Env = strings.Split(string(rawEnviron),\"\\x00\")\n\t//}\n\n\tinfo.Name = \"unknown\"\n\tinfo.ParentPid = -1\n\n\tstat, err := os.ReadFile(procFilePath(int(pid), \"stat\"))\n\tif err == nil {\n\t\tvar procPid int\n\t\tvar procName string\n\t\tvar procStatus string\n\t\tvar procPpid int\n\t\tfmt.Sscanf(string(stat), \"%d %s %s %d\", &procPid, &procName, &procStatus, &procPpid)\n\n\t\tinfo.Name = procName[1 : len(procName)-1]\n\t\tinfo.ParentPid = int32(procPpid)\n\t}\n\n\treturn info, nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/monitor/pevent/monitor.go",
    "content": "//go:build linux\n// +build linux\n\npackage pevent\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/pdiscover\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n//Process Event Monitor goal:\n//Watch the processes to separate the activity we care about from unrelated stuff running in the background.\n\n// Run starts the PEVENT monitor\nfunc Run(stopChan <-chan struct{}) <-chan *report.PeMonitorReport {\n\tlog.Info(\"pemon: starting...\")\n\n\t//\"connection refused\" with boot2docker...\n\twatcher, err := pdiscover.NewAllWatcher(pdiscover.PROC_EVENT_ALL)\n\terrutil.FailOn(err)\n\n\treportChan := make(chan *report.PeMonitorReport, 1)\n\n\tgo func() {\n\t\tpeReport := &report.PeMonitorReport{\n\t\t\tChildren: map[int][]int{},\n\t\t\tParents:  map[int]int{},\n\t\t}\n\n\tdone:\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-stopChan:\n\t\t\t\tlog.Info(\"pemon: stopping...\")\n\t\t\t\tbreak done\n\t\t\tcase ev := <-watcher.Fork:\n\t\t\t\tpeReport.Children[ev.ParentPid] = append(peReport.Children[ev.ParentPid], ev.ChildPid)\n\t\t\t\tpeReport.Parents[ev.ChildPid] = ev.ParentPid\n\t\t\tcase <-watcher.Exec:\n\t\t\tcase <-watcher.Exit:\n\t\t\tcase err := <-watcher.Error:\n\t\t\t\terrutil.FailOn(err)\n\t\t\t}\n\t\t}\n\n\t\treportChan <- peReport\n\t\twatcher.Close()\n\t}()\n\n\treturn reportChan\n}\n"
  },
  {
    "path": "pkg/app/sensor/monitor/ptrace/interface.go",
    "content": "package ptrace\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/monitor/ptrace\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n)\n\ntype AppRunOpt = ptrace.AppRunOpt\n\ntype Monitor interface {\n\t// Starts the long running monitoring. The method itself is not\n\t// blocking and not reentrant!\n\tStart() error\n\n\t// Cancels the underlying ptrace execution context but doesn't\n\t// make the current monitor done immediately. You still need to await\n\t// the final cleanup with <-mon.Done() before accessing the status.\n\tCancel()\n\n\t// With Done clients can await for the monitoring completion.\n\t// The method is reentrant - every invocation returns the same\n\t// instance of the channel.\n\tDone() <-chan struct{}\n\n\tStatus() (*report.PtMonitorReport, error)\n}\n"
  },
  {
    "path": "pkg/app/sensor/monitor/ptrace/monitor.go",
    "content": "//go:build !arm64\n// +build !arm64\n\npackage ptrace\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/errors\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/monitor/ptrace\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n)\n\ntype status struct {\n\treport *report.PtMonitorReport\n\terr    error\n}\n\ntype monitor struct {\n\tctx    context.Context\n\tcancel context.CancelFunc\n\n\tdel mondel.Publisher\n\n\tartifactsDir string\n\n\trunOpt AppRunOpt\n\n\t// TODO: Move the logic behind these two fields to the artifact processig stage.\n\tincludeNew bool\n\torigPaths  map[string]struct{}\n\n\t// To receive signals that should be delivered to the target app.\n\tsignalCh <-chan os.Signal\n\terrorCh  chan<- error\n\n\tapp *ptrace.App\n\n\tstatus status\n\tdoneCh chan struct{}\n\n\tlogger *log.Entry\n}\n\nfunc NewMonitor(\n\tctx context.Context,\n\tdel mondel.Publisher,\n\tartifactsDir string,\n\trunOpt AppRunOpt,\n\tincludeNew bool,\n\torigPaths map[string]struct{},\n\tsignalCh <-chan os.Signal,\n\terrorCh chan<- error,\n) Monitor {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"app\": \"sensor\",\n\t\t\"com\": \"ptmon\",\n\t})\n\n\tctx, cancel := context.WithCancel(ctx)\n\treturn &monitor{\n\t\tctx:    ctx,\n\t\tcancel: cancel,\n\n\t\tdel: del,\n\n\t\tartifactsDir: artifactsDir,\n\n\t\trunOpt: runOpt,\n\n\t\tincludeNew: includeNew,\n\t\torigPaths:  origPaths,\n\n\t\tsignalCh: signalCh,\n\t\terrorCh:  errorCh,\n\n\t\tdoneCh: make(chan struct{}),\n\t\tlogger: logger,\n\t}\n}\n\nfunc (m *monitor) Start() error {\n\tlogger := m.logger.WithField(\"op\", \"sensor.pt.monitor.Start\")\n\tlogger.Info(\"call\")\n\tdefer logger.Info(\"exit\")\n\n\tlogger.WithFields(log.Fields{\n\t\t\"name\": m.runOpt.Cmd,\n\t\t\"args\": m.runOpt.Args,\n\t}).Debug(\"starting target app...\")\n\n\t// Despite the name, ptrace.Run() is not blocking.\n\tapp, err := ptrace.Run(\n\t\tm.ctx,\n\t\tm.del,\n\t\tm.runOpt,\n\t\tm.includeNew,\n\t\tm.origPaths,\n\t\tm.signalCh,\n\t\tm.errorCh,\n\t)\n\tif err != nil {\n\t\treturn errors.SE(\"sensor.ptrace.Run/ptrace.Run\", \"call.error\", err)\n\t}\n\tm.app = app\n\n\tappState := <-app.StateCh\n\tlogger.\n\t\tWithField(\"state\", appState).\n\t\tDebugf(\"pta state watcher - new target app state\")\n\n\tif appState == ptrace.AppFailed {\n\t\t// Don't need to wait for the 'done' state.\n\t\tlogger.Error(\"pta state watcher - target app failed\")\n\t\treturn fmt.Errorf(\"ptmon: target app startup failed: %q\", appState)\n\t}\n\tif appState != ptrace.AppStarted {\n\t\t// Cannot really happen.\n\t\tlogger.Error(\"pta state watcher - unexpected target app state\")\n\t\treturn fmt.Errorf(\"ptmon: unexpected target app state %q\", appState)\n\t}\n\n\t// The sync part of the start was successful.\n\n\t// Tracking the completetion of the monitor.\n\tgo func() {\n\t\tlogger := m.logger.WithField(\"op\", \"sensor.pt.monitor.completetion.monitor\")\n\t\tlogger.Info(\"call\")\n\t\tdefer logger.Info(\"exit\")\n\n\t\tappState := <-app.StateCh\n\t\tif appState == ptrace.AppDone {\n\t\t\tm.status.report = <-app.ReportCh\n\t\t} else {\n\t\t\tm.status.err = fmt.Errorf(\"ptmon: target app failed with state %q\", appState)\n\t\t}\n\n\t\t// Monitor is done.\n\t\tclose(m.doneCh)\n\t}()\n\n\treturn nil\n}\n\nfunc (m *monitor) Cancel() {\n\tm.cancel()\n}\n\nfunc (m *monitor) Done() <-chan struct{} {\n\treturn m.doneCh\n}\n\nfunc (m *monitor) Status() (*report.PtMonitorReport, error) {\n\treturn m.status.report, m.status.err\n}\n"
  },
  {
    "path": "pkg/app/sensor/monitor/ptrace/monitor_arm64.go",
    "content": "//go:build arm64\n// +build arm64\n\npackage ptrace\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"os/exec\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"syscall\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/slimtoolkit/slim/pkg/errors\"\n\t\"github.com/slimtoolkit/slim/pkg/launcher\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n)\n\ntype syscallEvent struct {\n\tcallNum uint32\n\tretVal  uint64\n}\n\nconst (\n\teventBufSize = 500\n\tptOptions    = unix.PTRACE_O_TRACECLONE | unix.PTRACE_O_TRACEFORK | unix.PTRACE_O_TRACEVFORK\n)\n\n/*\n\tunix.PTRACE_O_EXITKILL|\n\tunix.PTRACE_O_TRACESECCOMP|\n\tsyscall.PTRACE_O_TRACESYSGOOD|\n\tsyscall.PTRACE_O_TRACEEXEC|\n\tsyscall.PTRACE_O_TRACECLONE|\n\tsyscall.PTRACE_O_TRACEFORK|\n\tsyscall.PTRACE_O_TRACEVFORK\n\n\tsyscall.PTRACE_O_TRACECLONE|syscall.PTRACE_O_TRACEEXIT\n*/\n\ntype status struct {\n\treport *report.PtMonitorReport\n\terr    error\n}\n\ntype monitor struct {\n\tctx    context.Context\n\tcancel context.CancelFunc\n\n\tdel mondel.Publisher\n\n\tartifactsDir string\n\n\trunOpt AppRunOpt\n\n\t// TODO: Move the logic behind these two fields to the artifact processig stage.\n\tincludeNew bool\n\torigPaths  map[string]struct{}\n\n\t// To receive signals that should be delivered to the target app.\n\tsignalCh <-chan os.Signal\n\n\tstatus status\n\tdoneCh chan struct{}\n}\n\nfunc NewMonitor(\n\tctx context.Context,\n\tdel mondel.Publisher,\n\tartifactsDir string,\n\trunOpt AppRunOpt,\n\tincludeNew bool,\n\torigPaths map[string]struct{},\n\tsignalCh <-chan os.Signal,\n\terrorCh chan<- error,\n) Monitor {\n\tctx, cancel := context.WithCancel(ctx)\n\treturn &monitor{\n\t\tctx:    ctx,\n\t\tcancel: cancel,\n\n\t\tdel: del,\n\n\t\tartifactsDir: artifactsDir,\n\n\t\trunOpt: runOpt,\n\n\t\tincludeNew: includeNew,\n\t\torigPaths:  origPaths,\n\n\t\tsignalCh: signalCh,\n\n\t\tdoneCh: make(chan struct{}),\n\t}\n}\n\nfunc (m *monitor) Start() error {\n\tlogger := log.WithField(\"op\", \"sensor.pt.monitor.Start\")\n\tlogger.Info(\"call\")\n\tdefer logger.Info(\"exit\")\n\n\tlogger.WithFields(log.Fields{\n\t\t\"name\": m.runOpt.Cmd,\n\t\t\"args\": m.runOpt.Args,\n\t}).Debug(\"starting target app...\")\n\n\tsysInfo := system.GetSystemInfo()\n\tarchName := system.MachineToArchName(sysInfo.Machine)\n\tsyscallResolver := system.CallNumberResolver(archName)\n\n\tappName := m.runOpt.Cmd\n\tappArgs := m.runOpt.Args\n\tworkDir := m.runOpt.WorkDir\n\tappUser := m.runOpt.User\n\trunTargetAsUser := m.runOpt.RunAsUser\n\trtaSourcePT := m.runOpt.RTASourcePT\n\t// TODO(ivan): Implement the runOpt.ReportOnMainPidExit handling.\n\n\t// The sync part of the start was successful.\n\n\t// Starting the async part...\n\tgo func() {\n\t\tlogger := log.WithField(\"op\", \"sensor.pt.monitor.processor\")\n\t\tlogger.Debug(\"call\")\n\t\tdefer logger.Debug(\"exit\")\n\n\t\tptReport := &report.PtMonitorReport{\n\t\t\tArchName:     string(archName),\n\t\t\tSyscallStats: map[string]report.SyscallStatInfo{},\n\t\t}\n\n\t\tsyscallStats := map[uint32]uint64{}\n\t\teventChan := make(chan syscallEvent, eventBufSize)\n\t\tcollectorDoneChan := make(chan int, 1)\n\n\t\tvar app *exec.Cmd\n\n\t\tgo func() {\n\t\t\tlogger := log.WithField(\"op\", \"sensor.pt.monitor.collector\")\n\t\t\tlogger.Debug(\"call\")\n\t\t\tdefer logger.Debug(\"exit\")\n\n\t\t\t//IMPORTANT:\n\t\t\t//Ptrace is not pretty... and it requires that you do all ptrace calls from the same thread\n\t\t\truntime.LockOSThread()\n\n\t\t\tvar err error\n\t\t\tapp, err = launcher.Start(\n\t\t\t\tappName,\n\t\t\t\tappArgs,\n\t\t\t\tworkDir,\n\t\t\t\tappUser,\n\t\t\t\trunTargetAsUser,\n\t\t\t\trtaSourcePT,\n\t\t\t\tm.runOpt.AppStdout,\n\t\t\t\tm.runOpt.AppStderr,\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\tm.status.err = errors.SE(\"sensor.ptrace.Run/launcher.Start\", \"call.error\", err)\n\t\t\t\tclose(m.doneCh)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// TODO: Apparently, rtaSourcePT is ignored by this below code.\n\t\t\t//       The x86-64 version of it has an alternative code branch\n\t\t\t//       to run the target app w/o tracing.\n\n\t\t\tcancelSignalForwarding := startSignalForwarding(m.ctx, app, m.signalCh)\n\t\t\tdefer cancelSignalForwarding()\n\n\t\t\ttargetPid := app.Process.Pid\n\n\t\t\t//pgid, err := syscall.Getpgid(targetPid)\n\t\t\t//if err != nil {\n\t\t\t//\tlog.Warnf(\"ptmon: collector - getpgid error %d: %v\", targetPid, err)\n\t\t\t//\tcollectorDoneChan <- 1\n\t\t\t//\treturn\n\t\t\t//}\n\n\t\t\tlogger.Debugf(\"target PID ==> %d\", targetPid)\n\n\t\t\tvar wstat unix.WaitStatus\n\n\t\t\t//pid, err := syscall.Wait4(-1, &wstat, syscall.WALL, nil) - WIP\n\t\t\tpid, err := unix.Wait4(targetPid, &wstat, 0, nil)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Warnf(\"unix.Wait4 - error waiting for %d: %v\", targetPid, err)\n\t\t\t\tcollectorDoneChan <- 2\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t//err = syscall.PtraceSetOptions(targetPid, ptOptions)\n\t\t\t//if err != nil {\n\t\t\t//\tlog.Warnf(\"ptmon: collector - error setting trace options %d: %v\", targetPid, err)\n\t\t\t//\tcollectorDoneChan <- 3\n\t\t\t//\treturn\n\t\t\t//}\n\n\t\t\tlogger.Debugf(\"initial process status = %v (pid=%d)\\n\", wstat, pid)\n\n\t\t\tif wstat.Exited() {\n\t\t\t\tlogger.Warn(\"app exited (unexpected)\")\n\t\t\t\tcollectorDoneChan <- 4\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif wstat.Signaled() {\n\t\t\t\tlogger.Warn(\"app signalled (unexpected)\")\n\t\t\t\tcollectorDoneChan <- 5\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tsyscallReturn := false\n\t\t\tgotCallNum := false\n\t\t\tgotRetVal := false\n\t\t\tvar callNum uint64\n\t\t\tvar retVal uint64\n\t\t\tfor wstat.Stopped() {\n\t\t\t\tvar regs unix.PtraceRegsArm64\n\n\t\t\t\tswitch syscallReturn {\n\t\t\t\tcase false:\n\t\t\t\t\tlogger.Infof(\"target pid is %d\", targetPid)\n\t\t\t\t\tif err := unix.PtraceGetRegSetArm64(targetPid, 1, &regs); err != nil {\n\t\t\t\t\t\t//if err := syscall.PtraceGetRegs(pid, &regs); err != nil {\n\t\t\t\t\t\tlogger.Fatalf(\"unix.PtraceGetRegsArm64(call): %v\", err)\n\t\t\t\t\t}\n\n\t\t\t\t\tcallNum = system.CallNumber(regs)\n\t\t\t\t\tsyscallReturn = true\n\t\t\t\t\tgotCallNum = true\n\n\t\t\t\tcase true:\n\t\t\t\t\tif err := unix.PtraceGetRegSetArm64(targetPid, 1, &regs); err != nil {\n\t\t\t\t\t\t//if err := syscall.PtraceGetRegs(pid, &regs); err != nil {\n\t\t\t\t\t\tlogger.Fatalf(\"unix.PtraceGetRegsArm64(return): %v\", err)\n\t\t\t\t\t}\n\n\t\t\t\t\tretVal = system.CallReturnValue(regs)\n\t\t\t\t\tsyscallReturn = false\n\t\t\t\t\tgotRetVal = true\n\n\t\t\t\t}\n\n\t\t\t\t//err = syscall.PtraceSyscall(pid, 0)\n\t\t\t\terr = unix.PtraceSyscall(targetPid, 0)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Warnf(\"unix.PtraceSyscall error: %v\", err)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t//pid, err = syscall.Wait4(-1, &wstat, syscall.WALL, nil)\n\t\t\t\tpid, err = unix.Wait4(targetPid, &wstat, 0, nil)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Warnf(\"unix.Wait4 - error waiting 4 %d: %v\", targetPid, err)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif gotCallNum && gotRetVal {\n\t\t\t\t\tgotCallNum = false\n\t\t\t\t\tgotRetVal = false\n\n\t\t\t\t\tselect {\n\t\t\t\t\tcase eventChan <- syscallEvent{\n\t\t\t\t\t\tcallNum: uint32(callNum),\n\t\t\t\t\t\tretVal:  retVal,\n\t\t\t\t\t}:\n\t\t\t\t\tcase <-m.ctx.Done():\n\t\t\t\t\t\tlogger.Info(\"stopping...\")\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.Infof(\"exiting... status=%v\", wstat)\n\t\t\tcollectorDoneChan <- 0\n\t\t}()\n\n\tdone:\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase rc := <-collectorDoneChan:\n\t\t\t\tlogger.Info(\"collector finished =>\", rc)\n\t\t\t\tbreak done\n\t\t\tcase <-m.ctx.Done():\n\t\t\t\tlogger.Info(\"stopping...\")\n\t\t\t\t//NOTE: need a better way to stop the target app...\n\t\t\t\tif err := app.Process.Signal(unix.SIGTERM); err != nil {\n\t\t\t\t\tlogger.Warnf(\"app.Process.Signal(unix.SIGTERM) - error stopping target app => %v\", err)\n\t\t\t\t\tif err := app.Process.Kill(); err != nil {\n\t\t\t\t\t\tlogger.Warnf(\"app.Process.Kill - error killing target app => %v\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak done\n\t\t\tcase e := <-eventChan:\n\t\t\t\tptReport.SyscallCount++\n\t\t\t\tlogger.Tracef(\"syscall ==> %d\", e.callNum)\n\n\t\t\t\tif _, ok := syscallStats[e.callNum]; ok {\n\t\t\t\t\tsyscallStats[e.callNum]++\n\t\t\t\t} else {\n\t\t\t\t\tsyscallStats[e.callNum] = 1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tlogger.Debugf(\"executed syscall count = %d\", ptReport.SyscallCount)\n\t\tlogger.Debugf(\"number of syscalls: %v\", len(syscallStats))\n\t\tfor scNum, scCount := range syscallStats {\n\t\t\tlogger.Tracef(\"%v\", syscallResolver(scNum))\n\t\t\tlogger.Tracef(\"[%v] %v = %v\", scNum, syscallResolver(scNum), scCount)\n\t\t\tptReport.SyscallStats[strconv.FormatInt(int64(scNum), 10)] = report.SyscallStatInfo{\n\t\t\t\tNumber: scNum,\n\t\t\t\tName:   syscallResolver(scNum),\n\t\t\t\tCount:  scCount,\n\t\t\t}\n\t\t}\n\n\t\tptReport.SyscallNum = uint32(len(ptReport.SyscallStats))\n\n\t\tm.status.report = ptReport\n\t\tclose(m.doneCh)\n\t}()\n\n\treturn nil\n}\n\nfunc (m *monitor) Cancel() {\n\tm.cancel()\n}\n\nfunc (m *monitor) Done() <-chan struct{} {\n\treturn m.doneCh\n}\n\nfunc (m *monitor) Status() (*report.PtMonitorReport, error) {\n\treturn m.status.report, m.status.err\n}\n\nfunc startSignalForwarding(\n\tctx context.Context,\n\tapp *exec.Cmd,\n\tsignalCh <-chan os.Signal,\n) context.CancelFunc {\n\tlog.Debug(\"ptmon: signal forwarder - starting...\")\n\n\tctx, cancel := context.WithCancel(ctx)\n\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\n\t\t\tcase s := <-signalCh:\n\t\t\t\tlog.WithField(\"signal\", s).Debug(\"ptmon: signal forwarder - received signal\")\n\n\t\t\t\tif s == syscall.SIGCHLD {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tlog.WithField(\"signal\", s).Debug(\"ptmon: signal forwarder - forwarding signal\")\n\n\t\t\t\tif err := app.Process.Signal(s); err != nil {\n\t\t\t\t\tlog.\n\t\t\t\t\t\tWithError(err).\n\t\t\t\t\t\tWithField(\"signal\", s).\n\t\t\t\t\t\tDebug(\"ptmon: signal forwarder - failed to signal target app\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn cancel\n}\n"
  },
  {
    "path": "pkg/app/sensor/signals.go",
    "content": "//go:build linux\n// +build linux\n\npackage sensor\n\nimport (\n\t\"os\"\n\t\"os/signal\"\n\t\"strings\"\n\t\"syscall\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/sys/unix\"\n)\n\nvar signals = []os.Signal{\n\tos.Interrupt,\n\tsyscall.SIGTERM,\n\tsyscall.SIGQUIT,\n\tsyscall.SIGHUP,\n\tsyscall.SIGSTOP,\n\tsyscall.SIGCONT,\n}\n\nfunc startSystemSignalsMonitor(cleanup func()) {\n\tsigChan := make(chan os.Signal, 1)\n\tsignal.Notify(sigChan, signals...)\n\tgo func() {\n\t\tsig := <-sigChan\n\t\tlog.Debugf(\"sensor: cleanup on signal (%v)...\", sig)\n\t\tcleanup()\n\t\tos.Exit(0)\n\t}()\n}\n\nfunc signalFromString(s string) syscall.Signal {\n\tif !strings.HasPrefix(s, \"SIG\") {\n\t\ts = \"SIG\" + s\n\t}\n\treturn unix.SignalNum(s)\n}\n"
  },
  {
    "path": "pkg/app/sensor/standalone/control/commands.go",
    "content": "package control\n\ntype Command string\n\nconst (\n\tStopTargetAppCommand Command = \"stop-target-app\"\n\tWaitForEventCommand  Command = \"wait-for-event\"\n)\n"
  },
  {
    "path": "pkg/app/sensor/standalone/control/queue.go",
    "content": "package control\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n)\n\nfunc HandleControlCommandQueue(ctx context.Context, commandsFile string, commandCh chan command.Message) {\n\tfifoPath := getFIFOPath(commandsFile)\n\tif !createFIFOIfNeeded(fifoPath) {\n\t\treturn\n\t}\n\tgo func() {\n\t\t<-ctx.Done()\n\t\tos.Remove(fifoPath)\n\t}()\n\n\tprocessCommandsFromFIFO(ctx, fifoPath, commandCh)\n}\n\nfunc getFIFOPath(commandsFile string) string {\n\treturn commandsFile + \".fifo\"\n}\n\nfunc createFIFOIfNeeded(fifoPath string) bool {\n\tif _, err := os.Stat(fifoPath); os.IsNotExist(err) {\n\t\tif err = syscall.Mkfifo(fifoPath, 0600); err != nil {\n\t\t\tlog.Warnf(\"sensor: control commands not activated - cannot create %s FIFO file: %s\", fifoPath, err)\n\t\t\treturn false\n\t\t}\n\t\tlog.Info(\"sensor: control commands activated\")\n\t}\n\treturn true\n}\n\nfunc processCommandsFromFIFO(ctx context.Context, fifoPath string, commandCh chan command.Message) {\n\tfor ctx.Err() == nil {\n\t\tfifo, err := os.Open(fifoPath)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"sensor: control commands - cannot open %s FIFO file: %s\", fifoPath, err)\n\t\t\ttime.Sleep(1 * time.Second)\n\t\t\tcontinue\n\t\t}\n\n\t\treadAndHandleCommands(fifo, commandCh)\n\t\tfifo.Close()\n\t}\n}\n\nfunc readAndHandleCommands(fifo *os.File, commandCh chan command.Message) {\n\treader := bufio.NewReader(fifo)\n\tfor {\n\t\tline, err := reader.ReadBytes('\\n')\n\t\tif len(line) > 0 {\n\t\t\thandleCommand(line, commandCh)\n\t\t}\n\n\t\tif err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tif err != nil {\n\t\t\tlog.Warnf(\"sensor: error reading control command: %s\", err)\n\t\t\ttime.Sleep(1 * time.Second)\n\t\t}\n\t}\n}\n\nfunc handleCommand(line []byte, commandCh chan command.Message) {\n\tmsg, err := command.Decode(line)\n\tif err == nil {\n\t\tcommandCh <- msg\n\t} else {\n\t\tlog.Warnf(\"sensor: cannot decode control command %#q: %s\", line, err)\n\t}\n}\n"
  },
  {
    "path": "pkg/app/sensor/standalone/control/stop.go",
    "content": "package control\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nfunc ExecuteStopTargetAppCommand(ctx context.Context, commandsFile string) error {\n\tmsg, err := command.Encode(&command.StopMonitor{})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot encode stop command: %w\", err)\n\t}\n\n\tif err := fsutil.AppendToFile(getFIFOPath(commandsFile), msg, false); err != nil {\n\t\treturn fmt.Errorf(\"cannot append stop command to FIFO file: %w\", err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/standalone/control/wait.go",
    "content": "package control\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n)\n\nfunc ExecuteWaitEvenCommand(\n\tctx context.Context,\n\teventsFile string,\n\tevt event.Type,\n) error {\n\tif err := waitForEvent(ctx, eventsFile, evt); err != nil {\n\t\treturn fmt.Errorf(\"waiting for %v event: %w\", evt, err)\n\t}\n\n\treturn nil\n}\n\nfunc waitForEvent(ctx context.Context, eventsFile string, target event.Type) error {\n\tfor ctx.Err() == nil {\n\t\tfound, err := findEvent(eventsFile, target)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif found {\n\t\t\treturn nil\n\t\t}\n\n\t\ttime.Sleep(1 * time.Second)\n\t}\n\n\treturn ctx.Err()\n}\n\nfunc findEvent(eventsFile string, target event.Type) (bool, error) {\n\tfile, err := os.Open(eventsFile)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tfor scanner.Scan() {\n\t\tline := scanner.Text()\n\t\t// A bit hacky - we probably need to parse the event struct properly.\n\t\tif strings.Contains(line, string(target)) {\n\t\t\treturn true, nil\n\t\t}\n\t}\n\n\tif scanner.Err() != nil {\n\t\treturn false, scanner.Err()\n\t}\n\n\treturn false, nil\n}\n"
  },
  {
    "path": "pkg/app/sensor/standalone/standalone.go",
    "content": "package standalone\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/artifact\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/execution\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n)\n\ntype Sensor struct {\n\tctx context.Context\n\texe execution.Interface\n\n\tnewMonitor monitor.NewCompositeMonitorFunc\n\tdel        mondel.Publisher\n\tartifactor artifact.Processor\n\n\tworkDir    string\n\tmountPoint string\n\n\tsignalCh chan os.Signal\n\n\tstopSignal          os.Signal\n\tstopGracePeriod     time.Duration\n\tstopCommandReceived bool\n}\n\nfunc NewSensor(\n\tctx context.Context,\n\texe execution.Interface,\n\tnewMonitor monitor.NewCompositeMonitorFunc,\n\tdel mondel.Publisher,\n\tartifactor artifact.Processor,\n\tworkDir string,\n\tmountPoint string,\n\tstopSignal os.Signal,\n\tstopGracePeriod time.Duration,\n) *Sensor {\n\treturn &Sensor{\n\t\tctx:             ctx,\n\t\texe:             exe,\n\t\tnewMonitor:      newMonitor,\n\t\tdel:             del,\n\t\tartifactor:      artifactor,\n\t\tworkDir:         workDir,\n\t\tmountPoint:      mountPoint,\n\t\tstopSignal:      stopSignal,\n\t\tstopGracePeriod: stopGracePeriod,\n\t}\n}\n\nfunc (s *Sensor) Run() error {\n\ts.exe.HookSensorPostStart()\n\n\terr := s.run()\n\tif err != nil {\n\t\ts.exe.PubEvent(event.Error, err.Error())\n\t}\n\n\t// We have to dump the artifacts before invokin the pre-shutdown\n\t// hook - it may want to upload the artifacts somewhere.\n\terrutil.WarnOn(s.artifactor.Archive())\n\n\ts.exe.HookSensorPreShutdown()\n\ts.exe.PubEvent(event.ShutdownSensorDone)\n\n\t// The target app can be done before the stop signal is received\n\t// because of two reasons:\n\t//\n\t// - App terminated on its own (e.g., a typical CLI use case)\n\t//\n\t// - The \"stop monitor\" control command was received.\n\t//\n\t// In the latter case, sensor needs to wait for the stop signal\n\t// before proceeding with the shutdown because otherwise the container\n\t// runtime may restart the container which is not desirable.\n\tif s.stopCommandReceived {\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\tcase <-s.signalCh:\n\t\t}\n\t}\n\n\treturn err\n}\n\nfunc (s *Sensor) run() error {\n\traw := <-s.exe.Commands()\n\tcmd, ok := (raw).(*command.StartMonitor)\n\tif !ok {\n\t\tlog.\n\t\t\tWithField(\"cmd\", fmt.Sprintf(\"%+v\", cmd)).\n\t\t\tError(\"sensor: unexpected start monitor command\")\n\t\ts.exe.HookMonitorFailed()\n\n\t\ts.exe.PubEvent(event.StartMonitorFailed,\n\t\t\t&event.StartMonitorFailedData{\n\t\t\t\tComponent: event.ComSensorCmdServer,\n\t\t\t\tState:     event.StateCmdStartMonCmdWaiting,\n\t\t\t\tContext: map[string]string{\n\t\t\t\t\tevent.CtxCmdType: string(raw.GetName()),\n\t\t\t\t},\n\t\t\t})\n\n\t\treturn fmt.Errorf(\"unexpected start monitor command: %+v\", cmd)\n\t}\n\n\tif err := s.artifactor.PrepareEnv(cmd); err != nil {\n\t\tlog.WithError(err).Error(\"sensor: artifactor.PrepareEnv() failed\")\n\t\ts.exe.HookMonitorFailed()\n\t\ts.exe.PubEvent(event.StartMonitorFailed,\n\t\t\t&event.StartMonitorFailedData{\n\t\t\t\tComponent: event.ComSensorCmdServer,\n\t\t\t\tState:     event.StateEnvPreparing,\n\t\t\t\tErrors:    []string{err.Error()},\n\t\t\t})\n\t\treturn fmt.Errorf(\"failed to prepare artifacts env: %w\", err)\n\t}\n\n\torigPaths, err := s.artifactor.GetCurrentPaths(s.mountPoint, cmd.Excludes)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"sensor: artifactor.GetCurrentPaths() failed\")\n\t\treturn fmt.Errorf(\"failed to enumerate current paths: %w\", err)\n\t}\n\n\ts.exe.HookMonitorPreStart()\n\n\tmon, err := s.newMonitor(\n\t\ts.ctx,\n\t\tcmd,\n\t\ts.workDir,\n\t\ts.del,\n\t\ts.artifactor.ArtifactsDir(),\n\t\ts.mountPoint,\n\t\torigPaths,\n\t)\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"sensor: failed to create composite monitor\")\n\t\ts.exe.HookMonitorFailed()\n\t\ts.exe.PubEvent(event.StartMonitorFailed,\n\t\t\t&event.StartMonitorFailedData{\n\t\t\t\tComponent: event.ComSensorCmdServer,\n\t\t\t\tState:     event.StateMonCreating,\n\t\t\t\tErrors:    []string{err.Error()},\n\t\t\t})\n\t\treturn err\n\t}\n\n\ts.signalCh = make(chan os.Signal, 1024)\n\tgo s.runSignalForwarder(mon)\n\n\tif err := mon.Start(); err != nil {\n\t\tlog.WithError(err).Error(\"sensor: failed to start composite monitor\")\n\t\ts.exe.HookMonitorFailed()\n\t\ts.exe.PubEvent(event.StartMonitorFailed,\n\t\t\t&event.StartMonitorFailedData{\n\t\t\t\tComponent: event.ComSensorCmdServer,\n\t\t\t\tState:     event.StateMonStarting,\n\t\t\t\tErrors:    []string{err.Error()},\n\t\t\t})\n\t\treturn err\n\t}\n\ts.exe.PubEvent(event.StartMonitorDone)\n\n\ts.runMonitor(mon)\n\n\treport, err := mon.Status()\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"sensor: target app failed\")\n\t\treturn err\n\t}\n\tlog.Info(\"sensor: target app is done\")\n\ts.exe.HookMonitorPostShutdown()\n\ts.exe.PubEvent(event.StopMonitorDone)\n\n\tif err := s.artifactor.Process(\n\t\tcmd,\n\t\ts.mountPoint,\n\t\treport.PeReport,\n\t\treport.FanReport,\n\t\treport.PtReport,\n\t); err != nil {\n\t\tlog.WithError(err).Error(\"sensor: artifact.Process() failed\")\n\t\treturn fmt.Errorf(\"saving reports failed: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Sensor) runMonitor(mon monitor.CompositeMonitor) {\n\tticker := time.NewTicker(time.Second * 5)\n\tdefer ticker.Stop()\n\nloop:\n\tfor {\n\t\tselect {\n\t\tcase <-mon.Done():\n\t\t\tbreak loop\n\n\t\tcase cmd := <-s.exe.Commands():\n\t\t\tlog.Infof(\"sensor: recieved control command => %s\", cmd.GetName())\n\t\t\tif cmd.GetName() == command.StopMonitorName {\n\t\t\t\ts.stopCommandReceived = true\n\t\t\t\ts.signalTargetApp(mon, s.stopSignal)\n\t\t\t} else {\n\t\t\t\tlog.Warnf(\"sensor: unsupported control command => %s\", cmd.GetName())\n\t\t\t}\n\n\t\tcase err := <-mon.Errors():\n\t\t\tlog.WithError(err).Warn(\"sensor: non-critical monitor error condition\")\n\t\t\ts.exe.PubEvent(event.Error, monitor.NonCriticalError(err).Error())\n\n\t\tcase <-ticker.C:\n\t\t\ts.exe.HookTargetAppRunning()\n\t\t\tlog.Debug(\".\")\n\t\t}\n\n\t\t// TODO: Implement me!\n\t\t// case file := <-mon.Files():\n\t\t//   Stub for the incremental artifact storing.\n\t}\n\n\t// A bit of code duplication to avoid starting a goroutine\n\t// for error event handling - keeping the control flow\n\t// \"single-threaded\" keeps reasoning about the logic.\n\tfor _, err := range mon.DrainErrors() {\n\t\tlog.WithError(err).Warn(\"sensor: non-critical monitor error condition (drained)\")\n\t\ts.exe.PubEvent(event.Error, monitor.NonCriticalError(err).Error())\n\t}\n}\n\n// TODO: Combine the signal forwarder loop with the run monitor loop\n//\n//\tto avoid competting event loops - this will simplify the code\n//\tand let us avoid subtle race conditions when the stop signal\n//\tarrives while the app is being stoped due to the stop control command.\nfunc (s *Sensor) runSignalForwarder(mon monitor.CompositeMonitor) {\n\tlog.Debug(\"sensor: starting forwarding signals to target app...\")\n\n\tsignal.Notify(s.signalCh)\n\n\tfor {\n\t\tselect {\n\t\tcase <-s.ctx.Done():\n\t\t\tlog.Debug(\"sensor: forwarding signal to target app no more - sensor is done\")\n\t\t\treturn\n\n\t\tcase sig := <-s.signalCh:\n\t\t\tif s.stopCommandReceived && sig == s.stopSignal {\n\t\t\t\tsignal.Stop(s.signalCh)\n\t\t\t\tclose(s.signalCh)\n\t\t\t}\n\n\t\t\tselect {\n\t\t\tcase <-mon.Done():\n\t\t\t\tlog.Debug(\"sensor: skipping signal forwarding - target app is done\")\n\n\t\t\tdefault:\n\t\t\t\tif sig != syscall.SIGCHLD {\n\t\t\t\t\t// Due to ptrace, SIGCHLDs flood the output.\n\t\t\t\t\t// TODO: Log SIGCHLD if ptrace-ing is off.\n\t\t\t\t\tlog.Debugf(\"sensor: forwarding signal %s to target app\", unix.SignalName(sig.(syscall.Signal)))\n\t\t\t\t}\n\t\t\t\ts.signalTargetApp(mon, sig)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) signalTargetApp(mon monitor.CompositeMonitor, sig os.Signal) {\n\tmon.SignalTargetApp(sig)\n\n\tif sig == s.stopSignal {\n\t\tlog.Debug(\"sensor: stop signal was sent to target app - starting grace period\")\n\n\t\tgo func() {\n\t\t\t// Starting the grace period.\n\t\t\ttimer := time.NewTimer(s.stopGracePeriod)\n\t\t\tdefer func() {\n\t\t\t\tif !timer.Stop() {\n\t\t\t\t\t<-timer.C\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tselect {\n\t\t\tcase <-mon.Done():\n\t\t\t\tlog.Debug(\"sensor: target app finished before grace timeout - dismantling SIGKILL\")\n\n\t\t\tcase <-timer.C:\n\t\t\t\tlog.Debug(\"sensor: grace timeout expired - SIGKILL goes to target app\")\n\t\t\t\tmon.SignalTargetApp(syscall.SIGKILL)\n\t\t\t}\n\t\t}()\n\t}\n}\n"
  },
  {
    "path": "pkg/appbom/.gitignore",
    "content": "/gobinhash\n\n"
  },
  {
    "path": "pkg/appbom/appbom.go",
    "content": "/*\nThere are two ways to provide the Go executable hash to \"appbom\":\n\n1. \"go generate\" and \"embed\"\n2. \"-ldflags\"\n\nUsing \"go generate\" to hash the Go binary:\n\ngo generate ./...\ngo generate github.com/slimtoolkit/slim/pkg/appbom\n\nWith \"go generate\" you also need to use embedding (enabled by default).\nIf you can't use \"embed\" you can disable it with the \"appbom_noembed\" tag:\n\ngo build -tags appbom_noembed\n\nIf you disable embedding then you'll need to pass the Go executable hash using \"-ldflags\":\n\nMac:\n\ngo build -ldflags \"-X github.com/slimtoolkit/slim/pkg/appbom.GoBinHash=sha256:$(shasum -a 256 $(go env GOROOT)/bin/go | head -c 64)\"\n\nLinux:\n\ngo build -ldflags \"-X github.com/slimtoolkit/slim/pkg/appbom.GoBinHash=sha256:$(sha256sum $(go env GOROOT)/bin/go | head -c 64)\"\n\nYou can use \"-ldflags\" instead of go generate/embed if that approach works better for you.\n*/\npackage appbom\n\n//go:generate go run gobinhasher.go\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"runtime/debug\"\n)\n\n// Known Settings key names\nconst (\n\tSettingBuildMode = \"-buildmode\" // the buildmode flag used\n\tSettingCompiler  = \"-compiler\"  // the compiler toolchain flag used\n\tSettingTags      = \"-tags\"\n\tSettingTrimPath  = \"-trimpath\"\n\tSettingLdFlags   = \"-ldflags\"\n\tSettingMod       = \"-mod\"\n\n\tSettingEnvVarCgoEnabled  = \"CGO_ENABLED\"  // the effective CGO_ENABLED environment variable\n\tSettingEnvVarCgoCFlags   = \"CGO_CFLAGS\"   // the effective CGO_CFLAGS environment variable\n\tSettingEnvVarCgoCppFlags = \"CGO_CPPFLAGS\" // the effective CGO_CPPFLAGS environment variable\n\tSettingEnvVarCgoCxxFlags = \"CGO_CXXFLAGS\" // the effective CGO_CXXFLAGS environment variable\n\tSettingEnvVarCgoLdFlags  = \"CGO_LDFLAGS\"  // the effective CGO_LDFLAGS environment variable\n\tSettingEnvVarGoOs        = \"GOOS\"         // the operating system target\n\tSettingEnvVarGoArch      = \"GOARCH\"       // the architecture target\n\n\t// the architecture feature level for GOARCH\n\tSettingEnvVarGoAmd64  = \"GOAMD64\"\n\tSettingEnvVarGoArm64  = \"GOARM64\"\n\tSettingEnvVarGoArm    = \"GOARM\"\n\tSettingEnvVarGo386    = \"GO386\"\n\tSettingEnvVarGoPpc64  = \"GOPPC64\"\n\tSettingEnvVarGoMips   = \"GOMIPS\"\n\tSettingEnvVarGoMips64 = \"GOMIPS64\"\n\tSettingEnvVarGoWasm   = \"GOWASM\"\n\n\tSettingVcsType     = \"vcs\"          // the version control system for the source tree where the build ran\n\tSettingVcsRevision = \"vcs.revision\" // the revision identifier for the current commit or checkout\n\tSettingVcsTime     = \"vcs.time\"     // the modification time associated with vcs.revision, in RFC3339 format\n\tSettingVcsModified = \"vcs.modified\" // true or false indicating whether the source tree had local modifications\n)\n\n//todo: expose the setting description as a 'details'/'summary' field\n\ntype MainPackageInfo struct {\n\tPath    string `json:\"path\"` //todo: add 'main'\n\tVersion string `json:\"version\"`\n}\n\ntype PackageInfo struct {\n\tName       string `json:\"name\"`\n\tVersion    string `json:\"version\"`\n\tHash       string `json:\"hash\"` // 'h1' algo is sha256: https://go.dev/ref/mod#go-sum-files\n\tPath       string `json:\"path\"`\n\tReplacedBy string `json:\"replaced_by,omitempty\"`\n}\n\ntype SourceControlInfo struct {\n\tType            string `json:\"type\"`\n\tRevision        string `json:\"revision\"`\n\tRevisionTime    string `json:\"revision_time\"`\n\tHasLocalChanges bool   `json:\"has_local_changes\"`\n}\n\ntype ParamType string\n\nconst (\n\tPTFlag   ParamType = \"flag\"\n\tPTEnvVar           = \"envvar\"\n)\n\ntype ParamName string\n\nconst (\n\tPNBuildMode   = ParamName(SettingBuildMode)\n\tPNCompiler    = ParamName(SettingCompiler)\n\tPNTags        = ParamName(SettingTags)\n\tPNTrimPath    = ParamName(SettingTrimPath)\n\tPNLdFlags     = ParamName(SettingLdFlags)\n\tPNMod         = ParamName(SettingMod)\n\tPNCgoEnabled  = ParamName(SettingEnvVarCgoEnabled)\n\tPNCgoCFlags   = ParamName(SettingEnvVarCgoCFlags)\n\tPNCgoCppFlags = ParamName(SettingEnvVarCgoCppFlags)\n\tPNCgoCxxFlags = ParamName(SettingEnvVarCgoCxxFlags)\n\tPNCgoLdFlags  = ParamName(SettingEnvVarCgoLdFlags)\n\tPNGoOs        = ParamName(SettingEnvVarGoOs)\n\tPNGoArch      = ParamName(SettingEnvVarGoArch)\n\n\tPNGoAmd64  = ParamName(SettingEnvVarGoAmd64)\n\tPNGoArm64  = ParamName(SettingEnvVarGoArm64)\n\tPNGoArm    = ParamName(SettingEnvVarGoArm)\n\tPNGo386    = ParamName(SettingEnvVarGo386)\n\tPNGoPpc64  = ParamName(SettingEnvVarGoPpc64)\n\tPNGoMips   = ParamName(SettingEnvVarGoMips)\n\tPNGoMips64 = ParamName(SettingEnvVarGoMips64)\n\tPNGoWasm   = ParamName(SettingEnvVarGoWasm)\n)\n\ntype ParamInfo struct {\n\tName        ParamName `json:\"name\"`\n\tType        ParamType `json:\"type\"`\n\tValue       string    `json:\"value\"`\n\tDescription string    `json:\"description,omitempty\"`\n}\n\ntype BuildParams struct {\n\tBuildMode   *ParamInfo `json:\"build_mode,omitempty\"`\n\tCompiler    *ParamInfo `json:\"compiler,omitempty\"`\n\tCgoEnabled  *ParamInfo `json:\"cgo_enabled,omitempty\"`\n\tCgoCFlags   *ParamInfo `json:\"cgo_cflags,omitempty\"`\n\tCgoCppFlags *ParamInfo `json:\"cgo_cppflags,omitempty\"`\n\tCgoCxxFlags *ParamInfo `json:\"cgo_cxxflags,omitempty\"`\n\tCgoLdFlags  *ParamInfo `json:\"cgo_ldflags,omitempty\"`\n\tOs          *ParamInfo `json:\"os,omitempty\"`\n\tArch        *ParamInfo `json:\"arch,omitempty\"`\n\tArchFeature *ParamInfo `json:\"arch_feature,omitempty\"`\n}\n\ntype Info struct {\n\tBuilderHash   string             `json:\"builder_hash,omitempty\"`\n\tRuntime       string             `json:\"runtime\"`\n\tEntrypoint    MainPackageInfo    `json:\"entrypoint\"`\n\tBuildParams   BuildParams        `json:\"build_params\"`\n\tOtherParams   map[string]string  `json:\"other_params,omitempty\"`\n\tSourceControl *SourceControlInfo `json:\"source_control,omitempty\"`\n\tIncludes      []*PackageInfo     `json:\"includes,omitempty\"`\n}\n\nfunc Get() *Info {\n\traw, ok := debug.ReadBuildInfo()\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tinfo := &Info{\n\t\tBuilderHash: goBinHash,\n\t\tRuntime:     raw.GoVersion,\n\t\tOtherParams: map[string]string{},\n\t}\n\n\tif raw.Path != \"\" {\n\t\tif raw.Path == \"command-line-arguments\" {\n\t\t\tinfo.Entrypoint.Path = \"unknown.prefix/main\"\n\t\t} else {\n\t\t\tinfo.Entrypoint.Path = fmt.Sprintf(\"%s/main\", raw.Path)\n\t\t}\n\t}\n\n\tif raw.Main.Path != \"\" {\n\t\tinfo.Entrypoint.Path = fmt.Sprintf(\"%s/main\", raw.Main.Path)\n\t}\n\n\tinfo.Entrypoint.Version = raw.Main.Version\n\n\tfor _, kv := range raw.Settings {\n\t\tswitch kv.Key {\n\t\tcase SettingVcsType:\n\t\t\tif info.SourceControl == nil {\n\t\t\t\tinfo.SourceControl = &SourceControlInfo{}\n\t\t\t}\n\n\t\t\tinfo.SourceControl.Type = kv.Value\n\t\tcase SettingVcsRevision:\n\t\t\tif info.SourceControl == nil {\n\t\t\t\tinfo.SourceControl = &SourceControlInfo{}\n\t\t\t}\n\n\t\t\tinfo.SourceControl.Revision = kv.Value\n\t\tcase SettingVcsTime:\n\t\t\tif info.SourceControl == nil {\n\t\t\t\tinfo.SourceControl = &SourceControlInfo{}\n\t\t\t}\n\n\t\t\tinfo.SourceControl.RevisionTime = kv.Value\n\t\tcase SettingVcsModified:\n\t\t\tif info.SourceControl == nil {\n\t\t\t\tinfo.SourceControl = &SourceControlInfo{}\n\t\t\t}\n\n\t\t\tswitch kv.Value {\n\t\t\tcase \"true\", \"TRUE\":\n\t\t\t\tinfo.SourceControl.HasLocalChanges = true\n\t\t\t}\n\n\t\tcase SettingBuildMode:\n\t\t\tinfo.BuildParams.BuildMode = &ParamInfo{\n\t\t\t\tName:  PNBuildMode,\n\t\t\t\tType:  PTFlag,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingCompiler:\n\t\t\tinfo.BuildParams.Compiler = &ParamInfo{\n\t\t\t\tName:  PNCompiler,\n\t\t\t\tType:  PTFlag,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingTags:\n\t\t\tinfo.BuildParams.Compiler = &ParamInfo{\n\t\t\t\tName:  PNTags,\n\t\t\t\tType:  PTFlag,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingTrimPath:\n\t\t\tinfo.BuildParams.Compiler = &ParamInfo{\n\t\t\t\tName:  PNTrimPath,\n\t\t\t\tType:  PTFlag,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\n\t\tcase SettingLdFlags:\n\t\t\tinfo.BuildParams.Compiler = &ParamInfo{\n\t\t\t\tName:  PNLdFlags,\n\t\t\t\tType:  PTFlag,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingMod:\n\t\t\tinfo.BuildParams.Compiler = &ParamInfo{\n\t\t\t\tName:  PNMod,\n\t\t\t\tType:  PTFlag,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarCgoEnabled:\n\t\t\tinfo.BuildParams.CgoEnabled = &ParamInfo{\n\t\t\t\tName:  PNCgoEnabled,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarCgoCFlags:\n\t\t\tinfo.BuildParams.CgoCFlags = &ParamInfo{\n\t\t\t\tName:  PNCgoCFlags,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarCgoCppFlags:\n\t\t\tinfo.BuildParams.CgoCppFlags = &ParamInfo{\n\t\t\t\tName:  PNCgoCppFlags,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarCgoCxxFlags:\n\t\t\tinfo.BuildParams.CgoCxxFlags = &ParamInfo{\n\t\t\t\tName:  PNCgoCxxFlags,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarCgoLdFlags:\n\t\t\tinfo.BuildParams.CgoLdFlags = &ParamInfo{\n\t\t\t\tName:  PNCgoLdFlags,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoOs:\n\t\t\tinfo.BuildParams.Os = &ParamInfo{\n\t\t\t\tName:  PNGoOs,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoArch:\n\t\t\tinfo.BuildParams.Arch = &ParamInfo{\n\t\t\t\tName:  PNGoArch,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\n\t\t// the architecture feature level for GOARCH\n\t\tcase SettingEnvVarGoAmd64:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGoAmd64,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoArm64:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGoArm64,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoArm:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGoArm,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGo386:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGo386,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoPpc64:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGoPpc64,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoMips:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGoMips,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoMips64:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGoMips64,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\t\tcase SettingEnvVarGoWasm:\n\t\t\tinfo.BuildParams.ArchFeature = &ParamInfo{\n\t\t\t\tName:  PNGoWasm,\n\t\t\t\tType:  PTEnvVar,\n\t\t\t\tValue: kv.Value,\n\t\t\t}\n\n\t\tdefault:\n\t\t\tinfo.OtherParams[kv.Key] = kv.Value\n\t\t}\n\t}\n\n\tincludeMap := map[string]*PackageInfo{}\n\tfor _, depData := range raw.Deps {\n\t\tif _, found := includeMap[depData.Path]; found {\n\t\t\tcontinue\n\t\t}\n\n\t\tpkg := &PackageInfo{\n\t\t\tName:    filepath.Base(depData.Path),\n\t\t\tPath:    depData.Path,\n\t\t\tVersion: depData.Version,\n\t\t\tHash:    depData.Sum,\n\t\t}\n\n\t\tincludeMap[depData.Path] = pkg\n\n\t\tfor depData.Replace != nil {\n\t\t\tpkg.ReplacedBy = depData.Replace.Path\n\n\t\t\tif _, found := includeMap[depData.Replace.Path]; found {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tpkg = &PackageInfo{\n\t\t\t\tName:    filepath.Base(depData.Replace.Path),\n\t\t\t\tPath:    depData.Replace.Path,\n\t\t\t\tVersion: depData.Replace.Version,\n\t\t\t\tHash:    depData.Replace.Sum,\n\t\t\t}\n\n\t\t\tincludeMap[depData.Replace.Path] = pkg\n\n\t\t\tdepData.Replace = depData.Replace.Replace\n\t\t}\n\t}\n\n\tfor _, pkg := range includeMap {\n\t\tinfo.Includes = append(info.Includes, pkg)\n\t}\n\n\treturn info\n}\n\n//TODO: have an option to add package metadata (from deps.dev and osv.dev)\n"
  },
  {
    "path": "pkg/appbom/gobinhash.go",
    "content": "//go:build !appbom_noembed\n// +build !appbom_noembed\n\npackage appbom\n\nimport (\n\t_ \"embed\"\n)\n\n//go:embed gobinhash\nvar goBinHash string\n"
  },
  {
    "path": "pkg/appbom/gobinhash_noembed.go",
    "content": "//go:build appbom_noembed\n// +build appbom_noembed\n\npackage appbom\n\nvar goBinHash string\n"
  },
  {
    "path": "pkg/appbom/gobinhasher.go",
    "content": "//go:build ignore\n// +build ignore\n\npackage main\n\nimport (\n\t\"crypto/sha256\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n)\n\nfunc main() {\n\tfullPath, err := getGoExeFullPath()\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t\treturn\n\t}\n\n\tfmt.Printf(\"found go binary: %s\\n\", fullPath)\n\n\thash, err := hashFile(fullPath)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t\treturn\n\t}\n\n\tdata := fmt.Sprintf(\"sha256:%s\", hash)\n\tfmt.Printf(\"saving go binary hash: %s\\n\", data)\n\terr = os.WriteFile(\"gobinhash\", []byte(data), 0644)\n\tif err != nil {\n\t\tfmt.Println(\"Error:\", err)\n\t\treturn\n\t}\n}\n\nconst (\n\tgoBinName    = \"go\"\n\tgoEnvCmd     = \"env\"\n\tgoRootEnvVar = \"GOROOT\"\n\tgoBinPathPat = \"%s/bin/%s\"\n)\n\nfunc getGoExeFullPath() (string, error) {\n\toutput, err := exec.Command(goBinName, goEnvCmd, goRootEnvVar).Output()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tgoRoot := string(output[:len(output)-1]) // removing the newline\n\tfullPath := fmt.Sprintf(goBinPathPat, goRoot, goBinName)\n\n\tif _, err := os.Stat(fullPath); err == nil {\n\t\treturn fullPath, nil\n\t}\n\n\treturn exec.LookPath(goBinName)\n}\n\nfunc hashFile(fullPath string) (string, error) {\n\tfile, err := os.Open(fullPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer file.Close()\n\n\thasher := sha256.New()\n\tif _, err := io.Copy(hasher, file); err != nil {\n\t\treturn \"\", err\n\t}\n\n\thash := hasher.Sum(nil)\n\treturn fmt.Sprintf(\"%x\", hash), nil\n}\n"
  },
  {
    "path": "pkg/artifact/artifact.go",
    "content": "package artifact\n\nimport (\n\t\"strings\"\n)\n\nvar ShellNames = []string{\n\t\"bash\",\n\t\"sh\",\n}\n\nvar ShellCommands = []string{\n\t\"ls\",\n\t\"pwd\",\n\t\"cd\",\n\t\"ps\",\n\t\"head\",\n\t\"tail\",\n\t\"cat\",\n\t\"more\",\n\t\"find\",\n\t\"grep\",\n\t\"awk\",\n\t\"env\",\n}\n\nvar FilteredPaths = map[string]struct{}{\n\t\"/\":     {},\n\t\"/proc\": {},\n\t\"/sys\":  {},\n\t\"/dev\":  {},\n}\n\nvar FileteredPathPrefixList = []string{\n\t\"/proc/\",\n\t\"/sys/\",\n\t\"/dev/\",\n}\n\nfunc IsFilteredPath(name string) bool {\n\tswitch name {\n\tcase \"/\", \"/proc\", \"/sys\", \"/dev\":\n\t\treturn true\n\t}\n\n\tfor _, prefix := range FileteredPathPrefixList {\n\t\tif strings.HasPrefix(name, prefix) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "pkg/certdiscover/certdiscover.go",
    "content": "package certdiscover\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// Cert Files (standard system cert bundles) and Java Keystore\nvar certFiles = []string{\n\t\"/etc/ssl/certs/ca-certificates.crt\",                // Debian / Ubuntu / Gentoo / etc.\n\t\"/etc/ssl/cert.pem\",                                 // Alpine / Arch / RHEL 9\n\t\"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem\", // CentOS / RHEL 7\n\t\"/etc/ssl/certs/ca-bundle.crt\",                      // RHEL / Fedora\n\t\"/etc/pki/tls/certs/ca-bundle.crt\",                  // Fedora / RHEL 6\n\t\"/etc/pki/tls/cert.pem\",                             // CentOS 7, 8 / RHEL 7, 8 / Fedora <= 33 (can be a symlnk to /etc/pki/tls/certs/ca-bundle.crt)\n\t\"/etc/ssl/ca-bundle.pem\",                            // OpenSUSE\n\t\"/etc/pki/tls/cacert.pem\",                           // OpenELEC\n\t\"/etc/ssl/certs/java/cacerts\",                       // Java Keystore Alpine / Ubuntu\n\t\"/etc/pki/java/cacerts\",                             // Java Keystore RHEL\n}\n\nvar certFilesSet map[string]struct{}\n\n// Cert Directories\nvar certDirectories = []string{\n\t\"/etc/ssl/certs\",       // Debian/Ubuntu/OpenSUSE\n\t\"/etc/pki/tls/certs\",   // Fedora/RHEL/CentOS/Amazon Linux\n\t\"/usr/lib/ssl/certs\",   // OpenSSL, usually linked to the OS-specific location (e.g., /etc/ssl/certs)\n\t\"/usr/local/ssl/certs\", // OpenSSL\n}\n\nvar certDirsSet map[string]struct{}\n\n// Cert Extra Directories (directories that container the actual standalone certs)\nvar certExtraDirectories = []string{\n\t\"/usr/share/ca-certificates\",\n\t\"/usr/local/share/ca-certificates\",\n\t\"/usr/lib/ca-certificates\",\n\t\"/usr/share/pki/trust/anchors\",\n}\n\n// Cert File Env Vars (TODO: use these)\nvar certFileEnvVars = []string{\n\t\"SSL_CERT_FILE\",\n\t\"PIP_CERT\",\n\t\"NODE_EXTRA_CA_CERTS\",\n\t\"CURL_CA_BUNDLE\",\n}\n\nvar certFileEnvVarsSet map[string]struct{}\n\n// Cert Dir Env Vars\nvar certDirEnvVars = []string{\n\t\"SSL_CERT_DIR\", // \":\" separated list of directories\n}\n\nvar certDirEnvVarsSet map[string]struct{}\n\n// Cert Private Key Directories\nvar certPKDirectories = []string{\n\t\"/etc/ssl/private\",       // Debian/Ubuntu/OpenSUSE\n\t\"/etc/pki/tls/private\",   // Fedora/RHEL/CentOS/Amazon Linux\n\t\"/usr/lib/ssl/private\",   // OpenSSL, usually linked to the OS-specific location (e.g., /etc/ssl/private)\n\t\"/usr/local/ssl/private\", // OpenSSL\n}\n\nvar certPKDirsSet map[string]struct{}\n\n// CA Cert Files (standard CA cert bundles)\nvar caCertFiles = []string{\n\t\"/etc/ssl/ca/certs/ca.crt\",\n\t\"/etc/pki/CA/certs/ca.crt\",\n\t\"/etc/ssl/ca/cacert.pem\",\n\t//\"/etc/letsencrypt/live/<domain>/fullchain.pem\" (also: cert.pem, chain.pem)\n}\n\nvar caCertFilesSet map[string]struct{}\n\n// CA Cert Directories\nvar caCertDirectories = []string{\n\t\"/etc/ssl/ca/certs\",\n\t\"/etc/pki/CA/certs\",\n\t\"/etc/letsencrypt/live\",\n}\n\nvar caCertDirsSet map[string]struct{}\n\n// CA Private Key Files\nvar caCertPKFiles = []string{\n\t\"/etc/ssl/ca/private/ca.key\",\n\t\"/etc/pki/CA/private/ca.key\",\n\t\"/etc/ssl/ca/private/cakey.pem\",\n\t//\"/etc/letsencrypt/live/<domain>/privkey.pem\"\n}\n\nvar caCertPKFilesSet map[string]struct{}\n\n// CA Private Key Directories\nvar caCertPKDirectories = []string{\n\t\"/etc/ssl/ca/private\",\n\t\"/etc/pki/CA/private\",\n\t\"/etc/letsencrypt/live\",\n}\n\nvar caCertPKDirsSet map[string]struct{}\n\nfunc CertFileList() []string {\n\treturn certFiles\n}\n\nfunc IsCertFile(name string) bool {\n\t_, found := certFilesSet[name]\n\treturn found\n}\n\nfunc IsCertDirPath(name string) bool {\n\tfor _, dir := range certDirectories {\n\t\tdir := fmt.Sprintf(\"%s/\", dir)\n\t\tif strings.HasPrefix(name, dir) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc CertDirList() []string {\n\treturn certDirectories\n}\n\nfunc IsCertDir(name string) bool {\n\t_, found := certDirsSet[name]\n\treturn found\n}\n\nfunc CertExtraDirList() []string {\n\treturn certExtraDirectories\n}\n\nfunc CertPKDirList() []string {\n\treturn certPKDirectories\n}\n\nfunc IsCertPKDir(name string) bool {\n\t_, found := certPKDirsSet[name]\n\treturn found\n}\n\nfunc IsCertPKDirPath(name string) bool {\n\tfor _, dir := range certPKDirectories {\n\t\tdir := fmt.Sprintf(\"%s/\", dir)\n\t\tif strings.HasPrefix(name, dir) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc CACertFileList() []string {\n\treturn caCertFiles\n}\n\nfunc IsCACertFile(name string) bool {\n\t_, found := caCertFilesSet[name]\n\treturn found\n}\n\nfunc CACertDirList() []string {\n\treturn caCertDirectories\n}\n\nfunc IsCACertDir(name string) bool {\n\t_, found := caCertDirsSet[name]\n\treturn found\n}\n\nfunc IsCACertDirPath(name string) bool {\n\tfor _, dir := range caCertDirectories {\n\t\tdir := fmt.Sprintf(\"%s/\", dir)\n\t\tif strings.HasPrefix(name, dir) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc CACertPKFileList() []string {\n\treturn caCertPKFiles\n}\n\nfunc IsCACertPKFile(name string) bool {\n\t_, found := caCertPKFilesSet[name]\n\treturn found\n}\n\nfunc IsCACertPKDir(name string) bool {\n\t_, found := caCertPKDirsSet[name]\n\treturn found\n}\n\nfunc IsCACertPKDirPath(name string) bool {\n\tfor _, dir := range caCertPKDirectories {\n\t\tdir := fmt.Sprintf(\"%s/\", dir)\n\t\tif strings.HasPrefix(name, dir) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc CACertPKDirList() []string {\n\treturn caCertPKDirectories\n}\n\nconst (\n\tLanguageNomatch = \"nomatch\"\n\tLanguagePython  = \"python\"\n\tLanguageNode    = \"node.js\"\n\tLanguageRuby    = \"ruby\"\n\tLanguageJava    = \"java\"\n)\n\nconst AppCertPackageName = \"certifi\"\n\nconst (\n\tAppCertPathSuffixPython = \"certifi/cacert.pem\"\n\tAppCertPathSuffixNode   = \"certifi/cacert.pem\"\n\tAppCertPathSuffixRuby   = \"lib/certifi/vendor/cacert.pem\"\n\tAppCertPathSuffixJava   = \"security/cacerts\"\n)\n\nconst (\n\tAppCertPathMatcherPython = \"-packages/certifi/cacert.pem\"\n\tAppCertPathMatcherNode   = \"/node_modules/certifi/cacert.pem\"\n\tAppCertPathMatcherRuby   = \"/lib/certifi/vendor/cacert.pem\"\n\tAppCertPathMatcherJava   = \"/jre/lib/security/cacerts\"\n)\n\n// Certifi package cert file (bundle) path matchers (+ Java Keystore)\nvar certifiCertPathMatchers = map[string]string{\n\tAppCertPathMatcherPython: LanguagePython,\n\tAppCertPathMatcherNode:   LanguageNode,\n\tAppCertPathMatcherRuby:   LanguageRuby, //also should include \"gems/\"\n\tAppCertPathMatcherJava:   LanguageJava, //Java Keystore\n}\n\nfunc IsAppCertFile(name string) bool {\n\tfor pat := range certifiCertPathMatchers {\n\t\tif strings.HasSuffix(name, pat) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc IsAppCertFileWithInfo(name string) string {\n\tfor pat, info := range certifiCertPathMatchers {\n\t\tif strings.HasSuffix(name, pat) {\n\t\t\treturn info\n\t\t}\n\t}\n\n\treturn LanguageNomatch\n}\n\nconst (\n\tbeginCert = \"-----BEGIN CERTIFICATE-----\"\n\tendCert   = \"-----END CERTIFICATE-----\"\n)\n\nfunc IsCertData(data []byte) bool {\n\tif !utf8.Valid(data) {\n\t\treturn false\n\t}\n\n\tif bytes.Contains(data, []byte(beginCert)) &&\n\t\tbytes.Contains(data, []byte(endCert)) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nconst (\n\tbeginRSAPK = \"-----BEGIN RSA PRIVATE KEY-----\"\n\tendRSAPK   = \"-----END RSA PRIVATE KEY-----\"\n\n\tbeginEncPK = \"-----BEGIN ENCRYPTED PRIVATE KEY-----\"\n\tendEncPK   = \"-----END ENCRYPTED PRIVATE KEY-----\"\n\n\tbeginPK = \"-----BEGIN PRIVATE KEY-----\"\n\tendPK   = \"-----END PRIVATE KEY-----\"\n\n\tpkPart = \" PRIVATE KEY-----\"\n)\n\nfunc IsPrivateKeyData(data []byte) bool {\n\tif !utf8.Valid(data) {\n\t\treturn false\n\t}\n\n\t//Basic PEM detection (TODO: detect other formats like DER)\n\tif bytes.Contains(data, []byte(pkPart)) {\n\t\tif (bytes.Contains(data, []byte(beginPK)) && bytes.Contains(data, []byte(endPK))) ||\n\t\t\t(bytes.Contains(data, []byte(beginRSAPK)) && bytes.Contains(data, []byte(endRSAPK))) ||\n\t\t\t(bytes.Contains(data, []byte(beginEncPK)) && bytes.Contains(data, []byte(endEncPK))) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc IsCertHashName(name string) bool {\n\tif len(name) == 10 &&\n\t\tname[8] == '.' &&\n\t\t(name[9] >= '0' && name[9] <= '9') {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc init() {\n\tcertFilesSet = initItemSet(certFiles)\n\tcertDirsSet = initItemSet(certDirectories)\n\tcertPKDirsSet = initItemSet(certPKDirectories)\n\n\tcertFileEnvVarsSet = initItemSet(certFileEnvVars)\n\tcertDirEnvVarsSet = initItemSet(certDirEnvVars)\n\n\tcaCertFilesSet = initItemSet(caCertFiles)\n\tcaCertDirsSet = initItemSet(caCertDirectories)\n\tcaCertPKFilesSet = initItemSet(caCertPKFiles)\n\tcaCertPKDirsSet = initItemSet(caCertPKDirectories)\n}\n\nfunc initItemSet(items []string) map[string]struct{} {\n\tset := map[string]struct{}{}\n\tfor _, item := range items {\n\t\tset[item] = struct{}{}\n\t}\n\n\treturn set\n}\n\n//todo: handle symlinks\n"
  },
  {
    "path": "pkg/command/command.go",
    "content": "package command\n\n// Command type constants\nconst (\n\tBuild         Type = \"build\"\n\tProfile       Type = \"profile\"\n\tXray          Type = \"xray\"\n\tLint          Type = \"lint\"\n\tImages        Type = \"images\"\n\tContainerize  Type = \"containerize\"\n\tConvert       Type = \"convert\"\n\tMerge         Type = \"merge\"\n\tEdit          Type = \"edit\"\n\tDebug         Type = \"debug\"\n\tProbe         Type = \"probe\"\n\tRun           Type = \"run\"\n\tServer        Type = \"server\"\n\tRegistry      Type = \"registry\"\n\tVulnerability Type = \"vulnerability\"\n\tVersion       Type = \"version\"\n\tUpdate        Type = \"update\"\n)\n\n// Type is the command type name\ntype Type string\n\n// Command state constants\nconst (\n\tStateUnknown   = \"unknown\"\n\tStateError     = \"error\"\n\tStateStarted   = \"started\"\n\tStateCompleted = \"completed\"\n\tStateExited    = \"exited\"\n\tStateDone      = \"done\"\n)\n\n// State is the command state type\ntype State string\n"
  },
  {
    "path": "pkg/consts/community.go",
    "content": "package consts\n\n// Community communication forums\nconst (\n\tCommunityCNCFSlack   = \"https://cloud-native.slack.com/archives/C059QP1RH1S\"\n\tCommunityGitter      = \"https://gitter.im/docker-slim/community\"\n\tCommunityDiscord     = \"https://discord.gg/9tDyxYS\"\n\tCommunityDiscussions = \"https://github.com/slimtoolkit/slim/discussions\"\n)\n"
  },
  {
    "path": "pkg/consts/external.go",
    "content": "package consts\n\n// Labels added to optimized container images\nconst (\n\tDSLabelVersion           = \"slimtoolkit.version\"\n\tDSLabelSourceImage       = \"slimtoolkit.source.image\"\n\tDSLabelSourceImageID     = \"slimtoolkit.source.image.id\"\n\tDSLabelSourceImageDigest = \"slimtoolkit.source.image.digest\"\n)\n\n// Other constants that external users/consumers will see\nconst (\n\t//reverse engineered Dockerfile for the target container image\n\tReversedDockerfile        = \"Dockerfile.reversed\"\n\tReversedDockerfileOldName = \"Dockerfile.fat\" //tmp compat\n)\n"
  },
  {
    "path": "pkg/consts/version.go",
    "content": "package consts\n\n// App version constants\nconst (\n\tAppName        = \"slim\"\n\tAppVersionName = \"Transformer\"\n)\n"
  },
  {
    "path": "pkg/docker/buildpackinfo/buildpackinfo.go",
    "content": "// Package buildpackinfo contains buildpack metadata extraction code\npackage buildpackinfo\n\nconst (\n\tLabelKeyStackID           = \"io.buildpacks.stack.id\"\n\tLabelKeyProjectMetadata   = \"io.buildpacks.project.metadata\"\n\tLabelKeyBuildMetadata     = \"io.buildpacks.build.metadata\"\n\tLabelKeyLifecycleMetadata = \"io.buildpacks.lifecycle.metadata\"\n\tLabelKeyStackMaintainer   = \"io.buildpacks.stack.maintainer\"\n)\n\nconst (\n\tStackHeroku18 = \"heroku-18\"\n\tStackGoogle   = \"google\"\n\tStackPaketo   = \"io.buildpacks.stacks.bionic\"\n)\n\nconst (\n\tVendorHeroku = \"heroku\"\n\tVendorGoogle = \"google\"\n\tVendorPaketo = \"paketo\"\n)\n\nconst Entrypoint = \"/cnb/process/web\"\n\nvar Labels = map[string]struct{}{\n\tLabelKeyStackID:           {},\n\tLabelKeyProjectMetadata:   {},\n\tLabelKeyBuildMetadata:     {},\n\tLabelKeyLifecycleMetadata: {},\n\tLabelKeyStackMaintainer:   {},\n}\n\nfunc HasBuildbackLabels(labels map[string]string) bool {\n\tfor k := range labels {\n\t\tif _, found := Labels[k]; found {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "pkg/docker/dockerclient/client.go",
    "content": "package dockerclient\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/master/config\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/jsonutil\"\n)\n\nconst (\n\tEnvDockerAPIVer      = \"DOCKER_API_VERSION\"\n\tEnvDockerHost        = \"DOCKER_HOST\"\n\tEnvDockerTLSVerify   = \"DOCKER_TLS_VERIFY\"\n\tEnvDockerCertPath    = \"DOCKER_CERT_PATH\"\n\tUnixSocketPath       = \"/var/run/docker.sock\"\n\tUnixSocketAddr       = \"unix:///var/run/docker.sock\"\n\tunixUserSocketSuffix = \".docker/run/docker.sock\"\n)\n\nvar EnvVarNames = []string{\n\tEnvDockerHost,\n\tEnvDockerTLSVerify,\n\tEnvDockerCertPath,\n\tEnvDockerAPIVer,\n}\n\nvar (\n\tErrNoDockerInfo = errors.New(\"no docker info\")\n)\n\nfunc UserDockerSocket() string {\n\thome, _ := os.UserHomeDir()\n\treturn filepath.Join(home, unixUserSocketSuffix)\n}\n\ntype SocketInfo struct {\n\tAddress       string `json:\"address\"`\n\tFilePath      string `json:\"file_path\"`\n\tFileType      string `json:\"type\"`\n\tFilePerms     string `json:\"perms\"`\n\tSymlinkTarget string `json:\"symlink_target,omitempty\"`\n\tTargetPerms   string `json:\"target_perms,omitempty\"`\n\tTargetType    string `json:\"target_type,omitempty\"`\n\tCanRead       bool   `json:\"can_read\"`\n\tCanWrite      bool   `json:\"can_write\"`\n}\n\nfunc getSocketInfo(filePath string) (*SocketInfo, error) {\n\tinfo := &SocketInfo{\n\t\tFileType: \"file\",\n\t\tFilePath: filePath,\n\t}\n\n\tfi, err := os.Lstat(info.FilePath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerclient.getSocketInfo.os.Lstat(%s): error - %v\", filePath, err)\n\t\treturn nil, err\n\t}\n\n\tif fi.Mode()&os.ModeSymlink != 0 {\n\t\tinfo.SymlinkTarget, err = os.Readlink(info.FilePath)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerclient.getSocketInfo.os.Readlink(%s): error - %v\", filePath, err)\n\t\t\treturn nil, err\n\t\t}\n\t\tinfo.FileType = \"symlink\"\n\t\tinfo.FilePerms = fmt.Sprintf(\"%#o\", fi.Mode().Perm())\n\t\tif info.SymlinkTarget != \"\" {\n\t\t\ttfi, err := os.Lstat(info.SymlinkTarget)\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"dockerclient.getSocketInfo.os.Lstat(%s): error - %v\", info.SymlinkTarget, err)\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tinfo.TargetPerms = fmt.Sprintf(\"%#o\", tfi.Mode().Perm())\n\t\t\tif tfi.Mode()&os.ModeSymlink != 0 {\n\t\t\t\tinfo.TargetType = \"symlink\"\n\t\t\t}\n\t\t}\n\t}\n\n\tinfo.CanRead, err = fsutil.HasReadAccess(info.FilePath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerclient.getSocketInfo.fsutil.HasReadAccess(%s): error - %v\", info.FilePath, err)\n\t\treturn nil, err\n\t}\n\n\tinfo.CanWrite, err = fsutil.HasWriteAccess(info.FilePath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerclient.getSocketInfo.fsutil.HasWriteAccess(%s): error - %v\", info.FilePath, err)\n\t\treturn nil, err\n\t}\n\n\treturn info, nil\n}\n\nfunc GetUnixSocketAddr() (*SocketInfo, error) {\n\t//note: may move this to dockerutil\n\tif _, err := os.Stat(UnixSocketPath); err == nil {\n\t\tsocketInfo, err := getSocketInfo(UnixSocketPath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tsocketInfo.Address = UnixSocketAddr\n\t\tlog.Debugf(\"dockerclient.GetUnixSocketAddr(): found => %s\", jsonutil.ToString(socketInfo))\n\t\treturn socketInfo, nil\n\t}\n\n\tuserDockerSocket := UserDockerSocket()\n\tif _, err := os.Stat(userDockerSocket); err == nil {\n\t\tsocketInfo, err := getSocketInfo(userDockerSocket)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tsocketInfo.Address = fmt.Sprintf(\"unix://%s\", userDockerSocket)\n\t\tlog.Debugf(\"dockerclient.GetUnixSocketAddr(): found => %s\", jsonutil.ToString(socketInfo))\n\t\treturn socketInfo, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"docker socket not found\")\n}\n\n// New creates a new Docker client instance\nfunc New(config *config.DockerClient) (*docker.Client, error) {\n\tvar client *docker.Client\n\tvar err error\n\n\tnewTLSClient := func(host string, certPath string, verify bool, apiVersion string) (*docker.Client, error) {\n\t\tvar ca []byte\n\n\t\tcert, err := os.ReadFile(filepath.Join(certPath, \"cert.pem\"))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tkey, err := os.ReadFile(filepath.Join(certPath, \"key.pem\"))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif verify {\n\t\t\tvar err error\n\t\t\tca, err = os.ReadFile(filepath.Join(certPath, \"ca.pem\"))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\treturn docker.NewVersionedTLSClientFromBytes(host, cert, key, ca, apiVersion)\n\t}\n\n\tswitch {\n\tcase config.Host != \"\" &&\n\t\tconfig.UseTLS &&\n\t\tconfig.VerifyTLS &&\n\t\tconfig.TLSCertPath != \"\":\n\t\tclient, err = newTLSClient(config.Host, config.TLSCertPath, true, config.APIVersion)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: new Docker client (TLS,verify) [1]\")\n\n\tcase config.Host != \"\" &&\n\t\tconfig.UseTLS &&\n\t\t!config.VerifyTLS &&\n\t\tconfig.TLSCertPath != \"\":\n\t\tclient, err = newTLSClient(config.Host, config.TLSCertPath, false, config.APIVersion)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: new Docker client (TLS,no verify) [2]\")\n\n\tcase config.Host != \"\" &&\n\t\t!config.UseTLS:\n\t\tclient, err = docker.NewVersionedClient(config.Host, config.APIVersion)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif config.APIVersion != \"\" {\n\t\t\tclient.SkipServerVersionCheck = true\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: new Docker client [3]\")\n\n\tcase config.Host == \"\" &&\n\t\t!config.VerifyTLS &&\n\t\tconfig.Env[EnvDockerTLSVerify] == \"1\" &&\n\t\tconfig.Env[EnvDockerCertPath] != \"\" &&\n\t\tconfig.Env[EnvDockerHost] != \"\":\n\t\tclient, err = newTLSClient(config.Env[EnvDockerHost], config.Env[EnvDockerCertPath], false, config.APIVersion)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: new Docker client (TLS,no verify) [4]\")\n\n\tcase config.Env[EnvDockerHost] != \"\":\n\t\tclient, err = docker.NewClientFromEnv()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: new Docker client (env) [5]\")\n\n\tcase config.Host == \"\" && config.Env[EnvDockerHost] == \"\":\n\t\tsocketInfo, err := GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tif socketInfo.CanRead == false || socketInfo.CanWrite == false {\n\t\t\treturn nil, fmt.Errorf(\"insufficient socket permissions (can_read=%v can_write=%v)\", socketInfo.CanRead, socketInfo.CanWrite)\n\t\t}\n\n\t\tconfig.Host = socketInfo.Address\n\t\tclient, err = docker.NewVersionedClient(config.Host, config.APIVersion)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif config.APIVersion != \"\" {\n\t\t\tclient.SkipServerVersionCheck = true\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: new Docker client (default) [6]\")\n\n\tdefault:\n\t\treturn nil, ErrNoDockerInfo\n\t}\n\n\tif config.Env[EnvDockerHost] == \"\" {\n\t\tif err := os.Setenv(EnvDockerHost, config.Host); err != nil {\n\t\t\terrutil.WarnOn(err)\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: configured DOCKER_HOST env var\")\n\t}\n\n\tif config.APIVersion != \"\" && config.Env[EnvDockerAPIVer] == \"\" {\n\t\tif err := os.Setenv(EnvDockerAPIVer, config.APIVersion); err != nil {\n\t\t\terrutil.WarnOn(err)\n\t\t}\n\n\t\tlog.Debug(\"dockerclient.New: configured DOCKER_API_VERSION env var\")\n\t}\n\n\treturn client, nil\n}\n"
  },
  {
    "path": "pkg/docker/dockerfile/ast/line_parsers.go",
    "content": "package ast\n\n// line parsers are dispatch calls that parse a single unit of text into a\n// Node object which contains the whole statement. Dockerfiles have varied\n// (but not usually unique, see ONBUILD for a unique example) parsing rules\n// per-command, and these unify the processing in a way that makes it\n// manageable.\n\n// Augmented BuildKit parser code to support linting\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\ntype NameValError struct {\n\tParseError\n}\n\nfunc nve(context, data, message string) NameValError {\n\treturn NameValError{\n\t\tParseError: pe(context, data, message),\n\t}\n}\n\ntype OldFormatNameValError struct {\n\tNameValError\n}\n\nfunc ofnve(context, message string) OldFormatNameValError {\n\treturn OldFormatNameValError{\n\t\tNameValError: nve(context, \"\", message),\n\t}\n}\n\ntype NewFormatNameValError struct {\n\tNameValError\n}\n\nfunc nfnve(context, data, message string) NewFormatNameValError {\n\treturn NewFormatNameValError{\n\t\tNameValError: nve(context, data, message),\n\t}\n}\n\nvar (\n\tErrDockerfileNotStringArray = errors.New(\"when using JSON array syntax, arrays must be comprised of strings only\")\n)\n\n// ignore the current argument. This will still leave a command parsed, but\n// will not incorporate the arguments into the ast.\nfunc parseIgnore(rest string, d *Directive) (*Node, map[string]bool, error) {\n\treturn &Node{}, nil, nil\n}\n\n// used for onbuild. Could potentially be used for anything that represents a\n// statement with sub-statements.\n//\n// ONBUILD RUN foo bar -> (onbuild (run foo bar))\nfunc parseSubCommand(rest string, d *Directive) (*Node, map[string]bool, error) {\n\tif rest == \"\" {\n\t\treturn nil, nil, nil\n\t}\n\n\tchild, err := newNodeFromLine(rest, d)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn &Node{Children: []*Node{child}}, nil, nil\n}\n\n// helper to parse words (i.e space delimited or quoted strings) in a statement.\n// The quotes are preserved as part of this function and they are stripped later\n// as part of processWords().\nfunc parseWords(rest string, d *Directive) []string {\n\tconst (\n\t\tinSpaces = iota // looking for start of a word\n\t\tinWord\n\t\tinQuote\n\t)\n\n\twords := []string{}\n\tphase := inSpaces\n\tword := \"\"\n\tquote := '\\000'\n\tblankOK := false\n\tvar ch rune\n\tvar chWidth int\n\n\tfor pos := 0; pos <= len(rest); pos += chWidth {\n\t\tif pos != len(rest) {\n\t\t\tch, chWidth = utf8.DecodeRuneInString(rest[pos:])\n\t\t}\n\n\t\tif phase == inSpaces { // Looking for start of word\n\t\t\tif pos == len(rest) { // end of input\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif unicode.IsSpace(ch) { // skip spaces\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tphase = inWord // found it, fall through\n\t\t}\n\t\tif (phase == inWord || phase == inQuote) && (pos == len(rest)) {\n\t\t\tif blankOK || len(word) > 0 {\n\t\t\t\twords = append(words, word)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif phase == inWord {\n\t\t\tif unicode.IsSpace(ch) {\n\t\t\t\tphase = inSpaces\n\t\t\t\tif blankOK || len(word) > 0 {\n\t\t\t\t\twords = append(words, word)\n\t\t\t\t}\n\t\t\t\tword = \"\"\n\t\t\t\tblankOK = false\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ch == '\\'' || ch == '\"' {\n\t\t\t\tquote = ch\n\t\t\t\tblankOK = true\n\t\t\t\tphase = inQuote\n\t\t\t}\n\t\t\tif ch == d.escapeToken {\n\t\t\t\tif pos+chWidth == len(rest) {\n\t\t\t\t\tcontinue // just skip an escape token at end of line\n\t\t\t\t}\n\t\t\t\t// If we're not quoted and we see an escape token, then always just\n\t\t\t\t// add the escape token plus the char to the word, even if the char\n\t\t\t\t// is a quote.\n\t\t\t\tword += string(ch)\n\t\t\t\tpos += chWidth\n\t\t\t\tch, chWidth = utf8.DecodeRuneInString(rest[pos:])\n\t\t\t}\n\t\t\tword += string(ch)\n\t\t\tcontinue\n\t\t}\n\t\tif phase == inQuote {\n\t\t\tif ch == quote {\n\t\t\t\tphase = inWord\n\t\t\t}\n\t\t\t// The escape token is special except for ' quotes - can't escape anything for '\n\t\t\tif ch == d.escapeToken && quote != '\\'' {\n\t\t\t\tif pos+chWidth == len(rest) {\n\t\t\t\t\tphase = inWord\n\t\t\t\t\tcontinue // just skip the escape token at end\n\t\t\t\t}\n\t\t\t\tpos += chWidth\n\t\t\t\tword += string(ch)\n\t\t\t\tch, chWidth = utf8.DecodeRuneInString(rest[pos:])\n\t\t\t}\n\t\t\tword += string(ch)\n\t\t}\n\t}\n\n\treturn words\n}\n\n// parse environment like statements. Note that this does *not* handle\n// variable interpolation, which will be handled in the evaluator.\nfunc parseNameVal(rest string, key string, d *Directive) (*Node, error) {\n\t// This is kind of tricky because we need to support the old\n\t// variant:   KEY name value\n\t// as well as the new one:    KEY name=value ...\n\t// The trigger to know which one is being used will be whether we hit\n\t// a space or = first.  space ==> old, \"=\" ==> new\n\n\twords := parseWords(rest, d)\n\tif len(words) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Old format (KEY name value)\n\tif !strings.Contains(words[0], \"=\") {\n\t\tparts := tokenWhitespace.Split(rest, 2)\n\t\tif len(parts) < 2 {\n\t\t\treturn nil, ofnve(key, fmt.Sprintf(key+\" must have two arguments\"))\n\t\t}\n\t\treturn newKeyValueNode(parts[0], parts[1]), nil\n\t}\n\n\tvar rootNode *Node\n\tvar prevNode *Node\n\tfor _, word := range words {\n\t\tif !strings.Contains(word, \"=\") {\n\t\t\treturn nil, nfnve(key, word,\n\t\t\t\tfmt.Sprintf(\"Syntax error - can't find = in %q. Must be of the form: name=value\",\n\t\t\t\t\tword))\n\t\t}\n\n\t\tparts := strings.SplitN(word, \"=\", 2)\n\t\tnode := newKeyValueNode(parts[0], parts[1])\n\t\trootNode, prevNode = appendKeyValueNode(node, rootNode, prevNode)\n\t}\n\n\treturn rootNode, nil\n}\n\nfunc newKeyValueNode(key, value string) *Node {\n\treturn &Node{\n\t\tValue: key,\n\t\tNext:  &Node{Value: value},\n\t}\n}\n\nfunc appendKeyValueNode(node, rootNode, prevNode *Node) (*Node, *Node) {\n\tif rootNode == nil {\n\t\trootNode = node\n\t}\n\tif prevNode != nil {\n\t\tprevNode.Next = node\n\t}\n\n\tprevNode = node.Next\n\treturn rootNode, prevNode\n}\n\nfunc parseEnv(rest string, d *Directive) (*Node, map[string]bool, error) {\n\tnode, err := parseNameVal(rest, instruction.Env, d)\n\treturn node, nil, err\n}\n\nfunc parseLabel(rest string, d *Directive) (*Node, map[string]bool, error) {\n\tnode, err := parseNameVal(rest, instruction.Label, d)\n\treturn node, nil, err\n}\n\n// parses a statement containing one or more keyword definition(s) and/or\n// value assignments, like `name1 name2= name3=\"\" name4=value`.\n// Note that this is a stricter format than the old format of assignment,\n// allowed by parseNameVal(), in a way that this only allows assignment of the\n// form `keyword=[<value>]` like  `name2=`, `name3=\"\"`, and `name4=value` above.\n// In addition, a keyword definition alone is of the form `keyword` like `name1`\n// above. And the assignments `name2=` and `name3=\"\"` are equivalent and\n// assign an empty value to the respective keywords.\nfunc parseNameOrNameVal(rest string, d *Directive) (*Node, map[string]bool, error) {\n\twords := parseWords(rest, d)\n\tif len(words) == 0 {\n\t\treturn nil, nil, nil\n\t}\n\n\tvar (\n\t\trootnode *Node\n\t\tprevNode *Node\n\t)\n\tfor i, word := range words {\n\t\tnode := &Node{}\n\t\tnode.Value = word\n\t\tif i == 0 {\n\t\t\trootnode = node\n\t\t} else {\n\t\t\tprevNode.Next = node\n\t\t}\n\t\tprevNode = node\n\t}\n\n\treturn rootnode, nil, nil\n}\n\n// parses a whitespace-delimited set of arguments. The result is effectively a\n// linked list of string arguments.\nfunc parseStringsWhitespaceDelimited(rest string, d *Directive) (*Node, map[string]bool, error) {\n\tif rest == \"\" {\n\t\treturn nil, nil, nil\n\t}\n\n\tnode := &Node{}\n\trootnode := node\n\tprevnode := node\n\tfor _, str := range tokenWhitespace.Split(rest, -1) { // use regexp\n\t\tprevnode = node\n\t\tnode.Value = str\n\t\tnode.Next = &Node{}\n\t\tnode = node.Next\n\t}\n\n\t// XXX to get around regexp.Split *always* providing an empty string at the\n\t// end due to how our loop is constructed, nil out the last node in the\n\t// chain.\n\tprevnode.Next = nil\n\n\treturn rootnode, nil, nil\n}\n\n// parseString just wraps the string in quotes and returns a working node.\nfunc parseString(rest string, d *Directive) (*Node, map[string]bool, error) {\n\tif rest == \"\" {\n\t\treturn nil, nil, nil\n\t}\n\tn := &Node{}\n\tn.Value = rest\n\treturn n, nil, nil\n}\n\n// parseJSON converts JSON arrays to an AST.\nfunc parseJSON(rest string, d *Directive) (*Node, map[string]bool, error) {\n\trest = strings.TrimLeftFunc(rest, unicode.IsSpace)\n\tif !strings.HasPrefix(rest, \"[\") {\n\t\treturn nil, nil, ParseError{\n\t\t\tData:    rest,\n\t\t\tMessage: fmt.Sprintf(`Error parsing \"%s\" as a JSON array`, rest),\n\t\t}\n\t}\n\n\tvar myJSON []interface{}\n\tif err := json.NewDecoder(strings.NewReader(rest)).Decode(&myJSON); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tvar top, prev *Node\n\tfor _, str := range myJSON {\n\t\ts, ok := str.(string)\n\t\tif !ok {\n\t\t\treturn nil, nil, ErrDockerfileNotStringArray\n\t\t}\n\n\t\tnode := &Node{Value: s}\n\t\tif prev == nil {\n\t\t\ttop = node\n\t\t} else {\n\t\t\tprev.Next = node\n\t\t}\n\t\tprev = node\n\t}\n\n\treturn top, map[string]bool{\"json\": true}, nil\n}\n\n// parseMaybeJSON determines if the argument appears to be a JSON array. If\n// so, passes to parseJSON; if not, quotes the result and returns a single\n// node.\nfunc parseMaybeJSON(rest string, d *Directive) (*Node, map[string]bool, error) {\n\tif rest == \"\" {\n\t\treturn nil, nil, nil\n\t}\n\n\tnode, attrs, err := parseJSON(rest, d)\n\n\tif err == nil {\n\t\treturn node, attrs, nil\n\t}\n\tif err == ErrDockerfileNotStringArray {\n\t\treturn nil, nil, err\n\t}\n\n\tnode = &Node{}\n\tnode.Value = rest\n\treturn node, nil, nil\n}\n\n// parseMaybeJSONToList determines if the argument appears to be a JSON array. If\n// so, passes to parseJSON; if not, attempts to parse it as a whitespace\n// delimited string.\nfunc parseMaybeJSONToList(rest string, d *Directive) (*Node, map[string]bool, error) {\n\tnode, attrs, err := parseJSON(rest, d)\n\n\tif err == nil {\n\t\treturn node, attrs, nil\n\t}\n\tif err == ErrDockerfileNotStringArray {\n\t\treturn nil, nil, err\n\t}\n\n\treturn parseStringsWhitespaceDelimited(rest, d)\n}\n\n// The HEALTHCHECK command is like parseMaybeJSON, but has an extra type argument.\nfunc parseHealthConfig(rest string, d *Directive) (*Node, map[string]bool, error) {\n\t// Find end of first argument\n\tvar sep int\n\tfor ; sep < len(rest); sep++ {\n\t\tif unicode.IsSpace(rune(rest[sep])) {\n\t\t\tbreak\n\t\t}\n\t}\n\tnext := sep\n\tfor ; next < len(rest); next++ {\n\t\tif !unicode.IsSpace(rune(rest[next])) {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif sep == 0 {\n\t\treturn nil, nil, nil\n\t}\n\n\ttyp := rest[:sep]\n\tcmd, attrs, err := parseMaybeJSON(rest[next:], d)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn &Node{Value: typ, Next: cmd}, attrs, err\n}\n"
  },
  {
    "path": "pkg/docker/dockerfile/ast/parser.go",
    "content": "// Package ast implements a (low level) parser and parse tree dumper for Dockerfiles.\npackage ast\n\n// Augmented BuildKit parser code to support linting\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nconst (\n\tUnknownInstMsg = \"unknown instruction\"\n)\n\nvar (\n\tErrDockerfileUnknownInst = errors.New(UnknownInstMsg)\n)\n\ntype ParseError struct {\n\tContext string\n\tData    string\n\tMessage string\n}\n\nfunc (e ParseError) Error() string {\n\treturn e.Message\n}\n\nfunc pe(context, data, message string) ParseError {\n\treturn ParseError{\n\t\tContext: context,\n\t\tData:    data,\n\t\tMessage: message,\n\t}\n}\n\n// Node is a structure used to represent a parse tree.\n//\n// In the node there are three fields, Value, Next, and Children. Value is the\n// current token's string value. Next is always the next non-child token, and\n// children contains all the children. Here's an example:\n//\n// (value next (child child-next child-next-next) next-next)\n//\n// This data structure is frankly pretty lousy for handling complex languages,\n// but lucky for us the Dockerfile isn't very complicated. This structure\n// works a little more effectively than a \"proper\" parse tree for our needs.\ntype Node struct {\n\tIsValid    bool\n\tErrors     []string\n\tValue      string // actual content\n\tArgsRaw    string\n\tNext       *Node           // the next item in the current sexp\n\tChildren   []*Node         // the children of this sexp\n\tAttributes map[string]bool // special attributes for this node\n\tOriginal   string          // original line used before parsing\n\tFlags      []string        // only top Node should have this set\n\tStartLine  int             // the line in the original dockerfile where the node begins\n\tEndLine    int             // the line in the original dockerfile where the node ends\n}\n\n// Dump dumps the AST defined by `node` as a list of sexps.\n// Returns a string suitable for printing.\nfunc (node *Node) Dump() string {\n\tstr := \"\"\n\n\tif !node.IsValid {\n\t\tstr += fmt.Sprintf(\"is_invalid errors='%+v' \", node.Errors)\n\t}\n\n\tstr += fmt.Sprintf(\"value=%q\", node.Value)\n\n\tif len(node.Flags) > 0 {\n\t\tstr += fmt.Sprintf(\" flags=%q\", node.Flags)\n\t}\n\n\tif len(node.Attributes) > 0 {\n\t\tstr += fmt.Sprintf(\" attributes=%+v\", node.Attributes)\n\t}\n\n\tif len(node.Children) > 0 {\n\t\tstr += \" children start:\\n\"\n\t\tfor _, n := range node.Children {\n\t\t\tstr += \"(\" + n.Dump() + \")\\n\"\n\t\t}\n\t\tstr += \":children done\\n\"\n\t}\n\n\tfor n := node.Next; n != nil; n = n.Next {\n\t\tif len(n.Children) > 0 {\n\t\t\tstr += \" next=\" + n.Dump()\n\t\t} else {\n\t\t\tstr += \" nextv=\" + strconv.Quote(n.Value)\n\t\t}\n\t}\n\n\treturn strings.TrimSpace(str)\n}\n\nfunc (node *Node) lines(start, end int) {\n\tnode.StartLine = start\n\tnode.EndLine = end\n}\n\n// AddChild adds a new child node, and updates line information\nfunc (node *Node) AddChild(child *Node, startLine, endLine int) {\n\tchild.lines(startLine, endLine)\n\tif node.StartLine < 0 {\n\t\tnode.StartLine = startLine\n\t}\n\tnode.EndLine = endLine\n\tnode.Children = append(node.Children, child)\n}\n\nvar (\n\tdispatch           map[string]func(string, *Directive) (*Node, map[string]bool, error)\n\ttokenWhitespace    = regexp.MustCompile(`[\\t\\v\\f\\r ]+`)\n\ttokenEscapeCommand = regexp.MustCompile(`^#[ \\t]*escape[ \\t]*=[ \\t]*(?P<escapechar>.).*$`)\n\ttokenComment       = regexp.MustCompile(`^#.*$`)\n)\n\n// DefaultEscapeToken is the default escape token\nconst DefaultEscapeToken = '\\\\'\n\n// Directive is the structure used during a build run to hold the state of\n// parsing directives.\ntype Directive struct {\n\tescapeToken           rune           // Current escape token\n\tlineContinuationRegex *regexp.Regexp // Current line continuation regex\n\tprocessingComplete    bool           // Whether we are done looking for directives\n\tescapeSeen            bool           // Whether the escape directive has been seen\n}\n\n// setEscapeToken sets the default token for escaping characters in a Dockerfile.\nfunc (d *Directive) setEscapeToken(s string) error {\n\tif s != \"`\" && s != \"\\\\\" {\n\t\treturn fmt.Errorf(\"invalid ESCAPE '%s'. Must be ` or \\\\\", s)\n\t}\n\td.escapeToken = rune(s[0])\n\td.lineContinuationRegex = regexp.MustCompile(`\\` + s + `[ \\t]*$`)\n\treturn nil\n}\n\n// possibleParserDirective looks for parser directives, eg '# escapeToken=<char>'.\n// Parser directives must precede any builder instruction or other comments,\n// and cannot be repeated.\nfunc (d *Directive) possibleParserDirective(line string) error {\n\tif d.processingComplete {\n\t\treturn nil\n\t}\n\n\ttecMatch := tokenEscapeCommand.FindStringSubmatch(strings.ToLower(line))\n\tif len(tecMatch) != 0 {\n\t\tfor i, n := range tokenEscapeCommand.SubexpNames() {\n\t\t\tif n == \"escapechar\" {\n\t\t\t\tif d.escapeSeen {\n\t\t\t\t\treturn errors.New(\"only one escape parser directive can be used\")\n\t\t\t\t}\n\t\t\t\td.escapeSeen = true\n\t\t\t\treturn d.setEscapeToken(tecMatch[i])\n\t\t\t}\n\t\t}\n\t}\n\n\td.processingComplete = true\n\treturn nil\n}\n\n// NewDefaultDirective returns a new Directive with the default escapeToken token\nfunc NewDefaultDirective() *Directive {\n\tdirective := Directive{}\n\tdirective.setEscapeToken(string(DefaultEscapeToken))\n\treturn &directive\n}\n\nfunc init() {\n\t// Dispatch Table. see line_parsers.go for the parse functions.\n\t// The command is parsed and mapped to the line parser. The line parser\n\t// receives the arguments but not the command, and returns an AST after\n\t// reformulating the arguments according to the rules in the parser\n\t// functions. Errors are propagated up by Parse() and the resulting AST can\n\t// be incorporated directly into the existing AST as a next.\n\tdispatch = map[string]func(string, *Directive) (*Node, map[string]bool, error){\n\t\tinstruction.Add:         parseMaybeJSONToList,\n\t\tinstruction.Arg:         parseNameOrNameVal,\n\t\tinstruction.Cmd:         parseMaybeJSON,\n\t\tinstruction.Copy:        parseMaybeJSONToList,\n\t\tinstruction.Entrypoint:  parseMaybeJSON,\n\t\tinstruction.Env:         parseEnv,\n\t\tinstruction.Expose:      parseStringsWhitespaceDelimited,\n\t\tinstruction.From:        parseStringsWhitespaceDelimited,\n\t\tinstruction.Healthcheck: parseHealthConfig,\n\t\tinstruction.Label:       parseLabel,\n\t\tinstruction.Maintainer:  parseString,\n\t\tinstruction.Onbuild:     parseSubCommand,\n\t\tinstruction.Run:         parseMaybeJSON,\n\t\tinstruction.Shell:       parseMaybeJSON,\n\t\tinstruction.StopSignal:  parseString,\n\t\tinstruction.User:        parseString,\n\t\tinstruction.Volume:      parseMaybeJSONToList,\n\t\tinstruction.Workdir:     parseString,\n\t}\n}\n\n// newNodeFromLine splits the line into parts, and dispatches to a function\n// based on the command and command arguments. A Node is created from the\n// result of the dispatch.\nfunc newNodeFromLine(line string, directive *Directive) (*Node, error) {\n\tcmd, flags, args, err := splitCommand(line)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfn, found := dispatch[cmd]\n\t// Ignore invalid Dockerfile instructions\n\tif !found {\n\t\tfn = parseIgnore\n\t}\n\n\tvar isValid bool\n\tvar errors []string\n\n\tnext, attrs, err := fn(args, directive)\n\tif err != nil {\n\t\terrors = append(errors, err.Error())\n\t\tnext = &Node{\n\t\t\tValue: args,\n\t\t}\n\t} else {\n\t\tif !found {\n\t\t\terrors = append(errors, UnknownInstMsg)\n\t\t\tnext.Value = args\n\t\t} else {\n\t\t\tisValid = true\n\t\t}\n\t}\n\n\treturn &Node{\n\t\tIsValid:    isValid,\n\t\tErrors:     errors,\n\t\tValue:      cmd,\n\t\tOriginal:   line,\n\t\tFlags:      flags,\n\t\tNext:       next,\n\t\tAttributes: attrs,\n\t\tArgsRaw:    args,\n\t}, nil\n}\n\n// Result is the result of parsing a Dockerfile\ntype Result struct {\n\tLines       []string\n\tAST         *Node\n\tEscapeToken rune\n\tWarnings    []string\n}\n\n// PrintWarnings to the writer\nfunc (r *Result) PrintWarnings(out io.Writer) {\n\tif len(r.Warnings) == 0 {\n\t\treturn\n\t}\n\tfmt.Fprintf(out, strings.Join(r.Warnings, \"\\n\")+\"\\n\")\n}\n\n// Parse reads lines from a Reader, parses the lines into an AST and returns\n// the AST and escape token\nfunc Parse(rwc io.Reader) (*Result, error) {\n\tvar lines []string\n\td := NewDefaultDirective()\n\tcurrentLine := 0\n\n\troot := &Node{IsValid: true, StartLine: -1}\n\tscanner := bufio.NewScanner(rwc)\n\twarnings := []string{}\n\n\tvar err error\n\tfor scanner.Scan() {\n\t\tbytesRead := scanner.Bytes()\n\t\tif currentLine == 0 {\n\t\t\t// First line, strip the byte-order-marker if present\n\t\t\tbytesRead = bytes.TrimPrefix(bytesRead, utf8bom)\n\t\t}\n\n\t\tlines = append(lines, string(bytesRead))\n\n\t\tbytesRead, err = processLine(d, bytesRead, true)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tcurrentLine++\n\n\t\tstartLine := currentLine\n\t\tline, isEndOfLine := trimContinuationCharacter(string(bytesRead), d)\n\t\tif isEndOfLine && line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar hasEmptyContinuationLine bool\n\t\tfor !isEndOfLine && scanner.Scan() {\n\t\t\tbytesRead, err := processLine(d, scanner.Bytes(), false)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tcurrentLine++\n\n\t\t\tif isComment(scanner.Bytes()) {\n\t\t\t\t// original line was a comment (processLine strips comments)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif isEmptyContinuationLine(bytesRead) {\n\t\t\t\thasEmptyContinuationLine = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcontinuationLine := string(bytesRead)\n\t\t\tcontinuationLine, isEndOfLine = trimContinuationCharacter(continuationLine, d)\n\t\t\tline += continuationLine\n\t\t}\n\n\t\tif hasEmptyContinuationLine {\n\t\t\twarnings = append(warnings, \"[WARNING]: Empty continuation line found in:\\n    \"+line)\n\t\t}\n\n\t\tchild, err := newNodeFromLine(line, d)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\troot.AddChild(child, startLine, currentLine)\n\t}\n\n\tif len(warnings) > 0 {\n\t\twarnings = append(warnings, \"[WARNING]: Empty continuation lines will become errors in a future release.\")\n\t}\n\n\tif root.StartLine < 0 {\n\t\twarnings = append(warnings, \"[WARNING]: File with no instructions.\")\n\t\t//return nil, errors.New(\"file with no instructions.\")\n\t}\n\n\treturn &Result{\n\t\tLines:       lines,\n\t\tAST:         root,\n\t\tWarnings:    warnings,\n\t\tEscapeToken: d.escapeToken,\n\t}, handleScannerError(scanner.Err())\n}\n\nfunc trimComments(src []byte) []byte {\n\treturn tokenComment.ReplaceAll(src, []byte{})\n}\n\nfunc trimWhitespace(src []byte) []byte {\n\treturn bytes.TrimLeftFunc(src, unicode.IsSpace)\n}\n\nfunc isComment(line []byte) bool {\n\treturn tokenComment.Match(trimWhitespace(line))\n}\n\nfunc isEmptyContinuationLine(line []byte) bool {\n\treturn len(trimWhitespace(line)) == 0\n}\n\nvar utf8bom = []byte{0xEF, 0xBB, 0xBF}\n\nfunc trimContinuationCharacter(line string, d *Directive) (string, bool) {\n\tif d.lineContinuationRegex.MatchString(line) {\n\t\tline = d.lineContinuationRegex.ReplaceAllString(line, \"\")\n\t\treturn line, false\n\t}\n\treturn line, true\n}\n\n// TODO: remove stripLeftWhitespace after deprecation period. It seems silly\n// to preserve whitespace on continuation lines. Why is that done?\nfunc processLine(d *Directive, token []byte, stripLeftWhitespace bool) ([]byte, error) {\n\tif stripLeftWhitespace {\n\t\ttoken = trimWhitespace(token)\n\t}\n\treturn trimComments(token), d.possibleParserDirective(string(token))\n}\n\nfunc handleScannerError(err error) error {\n\tswitch err {\n\tcase bufio.ErrTooLong:\n\t\treturn errors.Errorf(\"dockerfile line greater than max allowed size of %d\", bufio.MaxScanTokenSize-1)\n\tdefault:\n\t\treturn err\n\t}\n}\n"
  },
  {
    "path": "pkg/docker/dockerfile/ast/split_command.go",
    "content": "package ast\n\n// Augmented BuildKit parser code to support linting\n\nimport (\n\t\"strings\"\n\t\"unicode\"\n)\n\n// splitCommand takes a single line of text and parses out the cmd and args,\n// which are used for dispatching to more exact parsing functions.\nfunc splitCommand(line string) (string, []string, string, error) {\n\tvar args string\n\tvar flags []string\n\n\t// Make sure we get the same results irrespective of leading/trailing spaces\n\tcmdline := tokenWhitespace.Split(strings.TrimSpace(line), 2)\n\tcmd := strings.ToLower(cmdline[0])\n\n\tif len(cmdline) == 2 {\n\t\tvar err error\n\t\targs, flags, err = extractBuilderFlags(cmdline[1])\n\t\tif err != nil {\n\t\t\treturn \"\", nil, \"\", err\n\t\t}\n\t}\n\n\treturn cmd, flags, strings.TrimSpace(args), nil\n}\n\nfunc extractBuilderFlags(line string) (string, []string, error) {\n\t// Parses the BuilderFlags and returns the remaining part of the line\n\n\tconst (\n\t\tinSpaces = iota // looking for start of a word\n\t\tinWord\n\t\tinQuote\n\t)\n\n\twords := []string{}\n\tphase := inSpaces\n\tword := \"\"\n\tquote := '\\000'\n\tblankOK := false\n\tvar ch rune\n\n\tfor pos := 0; pos <= len(line); pos++ {\n\t\tif pos != len(line) {\n\t\t\tch = rune(line[pos])\n\t\t}\n\n\t\tif phase == inSpaces { // Looking for start of word\n\t\t\tif pos == len(line) { // end of input\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif unicode.IsSpace(ch) { // skip spaces\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Only keep going if the next word starts with --\n\t\t\tif ch != '-' || pos+1 == len(line) || rune(line[pos+1]) != '-' {\n\t\t\t\treturn line[pos:], words, nil\n\t\t\t}\n\n\t\t\tphase = inWord // found something with \"--\", fall through\n\t\t}\n\t\tif (phase == inWord || phase == inQuote) && (pos == len(line)) {\n\t\t\tif word != \"--\" && (blankOK || len(word) > 0) {\n\t\t\t\twords = append(words, word)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif phase == inWord {\n\t\t\tif unicode.IsSpace(ch) {\n\t\t\t\tphase = inSpaces\n\t\t\t\tif word == \"--\" {\n\t\t\t\t\treturn line[pos:], words, nil\n\t\t\t\t}\n\t\t\t\tif blankOK || len(word) > 0 {\n\t\t\t\t\twords = append(words, word)\n\t\t\t\t}\n\t\t\t\tword = \"\"\n\t\t\t\tblankOK = false\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ch == '\\'' || ch == '\"' {\n\t\t\t\tquote = ch\n\t\t\t\tblankOK = true\n\t\t\t\tphase = inQuote\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ch == '\\\\' {\n\t\t\t\tif pos+1 == len(line) {\n\t\t\t\t\tcontinue // just skip \\ at end\n\t\t\t\t}\n\t\t\t\tpos++\n\t\t\t\tch = rune(line[pos])\n\t\t\t}\n\t\t\tword += string(ch)\n\t\t\tcontinue\n\t\t}\n\t\tif phase == inQuote {\n\t\t\tif ch == quote {\n\t\t\t\tphase = inWord\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ch == '\\\\' {\n\t\t\t\tif pos+1 == len(line) {\n\t\t\t\t\tphase = inWord\n\t\t\t\t\tcontinue // just skip \\ at end\n\t\t\t\t}\n\t\t\t\tpos++\n\t\t\t\tch = rune(line[pos])\n\t\t\t}\n\t\t\tword += string(ch)\n\t\t}\n\t}\n\n\treturn \"\", words, nil\n}\n"
  },
  {
    "path": "pkg/docker/dockerfile/dockerfile.go",
    "content": "package dockerfile\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n\tv \"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// note: dup (todo: refactor)\nconst (\n\t//MAINTAINER:\n\tinstPrefixMaintainer = \"MAINTAINER \"\n\t//ENTRYPOINT:\n\tinstTypeEntrypoint   = \"ENTRYPOINT\"\n\tinstPrefixEntrypoint = \"ENTRYPOINT \"\n\t//CMD:\n\tinstTypeCmd   = \"CMD\"\n\tinstPrefixCmd = \"CMD \"\n\t//USER:\n\tinstTypeUser   = \"USER\"\n\tinstPrefixUser = \"USER \"\n\t//EXPOSE:\n\tinstTypeExpose   = \"EXPOSE\"\n\tinstPrefixExpose = \"EXPOSE \"\n\t//WORKDIR:\n\tinstTypeWorkdir   = \"WORKDIR\"\n\tinstPrefixWorkdir = \"WORKDIR \"\n\t//HEALTHCHECK:\n\tinstTypeHealthcheck   = \"HEALTHCHECK\"\n\tinstPrefixHealthcheck = \"HEALTHCHECK \"\n\t//ONBUILD:\n\tinstTypeOnbuild = \"ONBUILD\"\n\t//RUN:\n\tinstTypeRun   = \"RUN\"\n\tinstPrefixRun = \"RUN \"\n\t//ADD:\n\tinstTypeAdd = \"ADD\"\n\t//COPY:\n\tinstTypeCopy = \"COPY\"\n)\n\n// GenerateFromInfo builds and saves a Dockerfile file object\nfunc GenerateFromInfo(\n\tlocation string,\n\tvolumes map[string]struct{},\n\tworkingDir string,\n\tenv []string,\n\tlabels map[string]string,\n\tuser string,\n\texposedPorts map[docker.Port]struct{},\n\tentrypoint []string,\n\tcmd []string,\n\thasData bool,\n\ttarData bool) error {\n\n\tdockerfileLocation := filepath.Join(location, \"Dockerfile\")\n\n\tvar dfData bytes.Buffer\n\tdfData.WriteString(\"FROM scratch\\n\")\n\n\tdsInfoLabel := fmt.Sprintf(\"LABEL %s=\\\"%s\\\"\\n\", consts.DSLabelVersion, v.Current())\n\tdfData.WriteString(dsInfoLabel)\n\n\tif len(labels) > 0 {\n\t\tfor name, value := range labels {\n\t\t\tvar encoded bytes.Buffer\n\t\t\tencoder := json.NewEncoder(&encoded)\n\t\t\tencoder.SetEscapeHTML(false)\n\t\t\tencoder.Encode(value)\n\t\t\tlabelInfo := fmt.Sprintf(\"LABEL %s=%s\\n\", name, encoded.String())\n\t\t\tdfData.WriteString(labelInfo)\n\t\t}\n\t\tdfData.WriteByte('\\n')\n\t}\n\n\tif len(env) > 0 {\n\t\tfor _, envInfo := range env {\n\t\t\tif envParts := strings.SplitN(envInfo, \"=\", 2); len(envParts) > 1 {\n\t\t\t\tdfData.WriteString(\"ENV \")\n\t\t\t\tenvLine := fmt.Sprintf(\"%s \\\"%s\\\"\", envParts[0], envParts[1])\n\t\t\t\tdfData.WriteString(envLine)\n\t\t\t\tdfData.WriteByte('\\n')\n\t\t\t}\n\t\t}\n\t\tdfData.WriteByte('\\n')\n\t}\n\n\tif len(volumes) > 0 {\n\t\tvar volumeList []string\n\t\tfor volumeName := range volumes {\n\t\t\tvolumeList = append(volumeList, strconv.Quote(volumeName))\n\t\t}\n\n\t\tvolumeInst := fmt.Sprintf(\"VOLUME [%s]\", strings.Join(volumeList, \",\"))\n\t\tdfData.WriteString(volumeInst)\n\t\tdfData.WriteByte('\\n')\n\t}\n\n\tif hasData {\n\t\taddData := \"COPY files /\\n\"\n\t\tif tarData {\n\t\t\taddData = \"ADD files.tar /\\n\"\n\t\t}\n\n\t\tdfData.WriteString(addData)\n\t}\n\n\tif workingDir != \"\" {\n\t\tdfData.WriteString(instPrefixWorkdir)\n\t\tdfData.WriteString(workingDir)\n\t\tdfData.WriteByte('\\n')\n\t}\n\n\tif user != \"\" {\n\t\tdfData.WriteString(instPrefixUser)\n\t\tdfData.WriteString(user)\n\t\tdfData.WriteByte('\\n')\n\t}\n\n\tif len(exposedPorts) > 0 {\n\t\tfor portInfo := range exposedPorts {\n\t\t\tdfData.WriteString(instPrefixExpose)\n\t\t\tdfData.WriteString(string(portInfo))\n\t\t\tdfData.WriteByte('\\n')\n\t\t}\n\t}\n\n\tif len(entrypoint) > 0 {\n\t\t//TODO: need to make sure the generated ENTRYPOINT is compatible with the original behavior\n\t\tvar quotedEntryPoint []string\n\t\tfor idx := range entrypoint {\n\t\t\tquotedEntryPoint = append(quotedEntryPoint, strconv.Quote(entrypoint[idx]))\n\t\t}\n\n\t\tdfData.WriteString(\"ENTRYPOINT [\")\n\t\tdfData.WriteString(strings.Join(quotedEntryPoint, \",\"))\n\t\tdfData.WriteByte(']')\n\t\tdfData.WriteByte('\\n')\n\t}\n\n\tif len(cmd) > 0 {\n\t\t//TODO: need to make sure the generated CMD is compatible with the original behavior\n\t\tvar quotedCmd []string\n\t\tfor idx := range cmd {\n\t\t\tquotedCmd = append(quotedCmd, strconv.Quote(cmd[idx]))\n\t\t}\n\t\tdfData.WriteString(\"CMD [\")\n\t\tdfData.WriteString(strings.Join(quotedCmd, \",\"))\n\t\tdfData.WriteByte(']')\n\t\tdfData.WriteByte('\\n')\n\t}\n\n\treturn os.WriteFile(dockerfileLocation, dfData.Bytes(), 0644)\n}\n"
  },
  {
    "path": "pkg/docker/dockerfile/parser/parser.go",
    "content": "// Package parser implements a Dockerfile parser\npackage parser\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile/ast\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile/spec\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nvar (\n\tErrInvalidDockerfile = errors.New(\"invalid Dockerfile\")\n)\n\n//TODO:\n//* support incremental, partial and instruction level parsing\n//* support parsing from reader and from string\n\nfunc FromFile(fpath string) (*spec.Dockerfile, error) {\n\tfo, err := os.Open(fpath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer fo.Close()\n\n\tastParsed, err := ast.Parse(fo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !astParsed.AST.IsValid {\n\t\treturn nil, ErrInvalidDockerfile\n\t}\n\n\tdockerfile := spec.NewDockerfile()\n\tdockerfile.Name = filepath.Base(fpath)\n\tdockerfile.Location = filepath.Dir(fpath)\n\tdockerfile.Lines = astParsed.Lines\n\n\tif astParsed.AST.StartLine > -1 && len(astParsed.AST.Children) > 0 {\n\t\tvar currentStage *spec.BuildStage\n\t\tinstStageIndex := -1\n\t\tfor idx, node := range astParsed.AST.Children {\n\t\t\tinst := &instruction.Field{\n\t\t\t\tGlobalIndex: idx,\n\t\t\t\tStageIndex:  instStageIndex,\n\t\t\t\tIsValid:     node.IsValid,\n\t\t\t\tRawData:     node.Original,\n\t\t\t\tStartLine:   node.StartLine,\n\t\t\t\tEndLine:     node.EndLine,\n\t\t\t\tName:        node.Value,\n\t\t\t\tFlags:       node.Flags,\n\t\t\t\tArgsRaw:     node.ArgsRaw,\n\t\t\t}\n\n\t\t\tif len(dockerfile.Lines) > 0 &&\n\t\t\t\tinst.StartLine > 0 &&\n\t\t\t\tinst.StartLine <= len(dockerfile.Lines) &&\n\t\t\t\tinst.EndLine <= len(dockerfile.Lines) &&\n\t\t\t\tinst.EndLine >= inst.StartLine {\n\t\t\t\tinst.RawLines = dockerfile.Lines[inst.StartLine-1 : inst.EndLine]\n\t\t\t}\n\n\t\t\tif !inst.IsValid {\n\t\t\t\tinst.Errors = append(inst.Errors, node.Errors...)\n\t\t\t}\n\n\t\t\tif inst.Name == instruction.Onbuild &&\n\t\t\t\tnode.Next != nil &&\n\t\t\t\tlen(node.Next.Children) > 0 {\n\t\t\t\tinst.IsOnBuild = true\n\t\t\t\tnode = node.Next.Children[0]\n\t\t\t\tinst.Name = node.Value\n\t\t\t\tinst.ArgsRaw = node.ArgsRaw\n\t\t\t\tinst.Flags = node.Flags\n\t\t\t}\n\n\t\t\tfor n := node.Next; n != nil; n = n.Next {\n\t\t\t\tinst.Args = append(inst.Args, n.Value)\n\t\t\t}\n\n\t\t\tif _, ok := node.Attributes[\"json\"]; ok {\n\t\t\t\tinst.IsJSONForm = true\n\t\t\t}\n\n\t\t\tif inst.Name == instruction.From {\n\t\t\t\tcurrentStage = spec.NewBuildStage()\n\t\t\t\tcurrentStage.FromInstruction = inst\n\t\t\t\tcurrentStage.Index = len(dockerfile.Stages)\n\t\t\t\tinstStageIndex = -1\n\n\t\t\t\tcurrentStage.StartLine = inst.StartLine\n\n\t\t\t\tif len(inst.Args) == 3 && strings.ToLower(inst.Args[1]) == \"as\" {\n\t\t\t\t\tcurrentStage.Name = inst.Args[2]\n\t\t\t\t\tdockerfile.StagesByName[currentStage.Name] = currentStage\n\t\t\t\t}\n\n\t\t\t\tif len(inst.Args) > 0 {\n\t\t\t\t\tvar parts []string\n\t\t\t\t\tvar hasDigest bool\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase strings.Contains(inst.Args[0], \":\"):\n\t\t\t\t\t\tparts = strings.Split(inst.Args[0], \":\")\n\t\t\t\t\tcase strings.Contains(inst.Args[0], \"@\"):\n\t\t\t\t\t\tparts = strings.Split(inst.Args[0], \"@\")\n\t\t\t\t\t\thasDigest = true\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tparts = append(parts, inst.Args[0])\n\t\t\t\t\t}\n\n\t\t\t\t\tif len(parts) > 0 {\n\t\t\t\t\t\tif len(parts[0]) > 0 {\n\t\t\t\t\t\t\tif strings.HasPrefix(parts[0], \"$\") {\n\t\t\t\t\t\t\t\targName := GetRefName(parts[0])\n\t\t\t\t\t\t\t\targVal, ok := dockerfile.FromArgs[argName]\n\t\t\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\t\t\tcurrentStage.UnknownFromArgs[argName] = struct{}{}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentStage.FromArgs[argName] = argVal\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif len(parts) == 1 {\n\t\t\t\t\t\t\t\t\tif len(argVal) > 0 {\n\t\t\t\t\t\t\t\t\t\tswitch {\n\t\t\t\t\t\t\t\t\t\tcase strings.Contains(argVal, \":\"):\n\t\t\t\t\t\t\t\t\t\t\tparts = strings.Split(argVal, \":\")\n\t\t\t\t\t\t\t\t\t\tcase strings.Contains(argVal, \"@\"):\n\t\t\t\t\t\t\t\t\t\t\tparts = strings.Split(argVal, \"@\")\n\t\t\t\t\t\t\t\t\t\t\thasDigest = true\n\t\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\t\tparts = nil\n\t\t\t\t\t\t\t\t\t\t\tparts = append(parts, argVal)\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif len(parts) == 1 {\n\t\t\t\t\t\t\t\t\t\t\tcurrentStage.Parent.Name = parts[0]\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.BuildArgAll = argName\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.BuildArgName = argName\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.Name = argVal\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcurrentStage.Parent.Name = parts[0]\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcurrentStage.Parent.HasEmptyName = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\t\tif len(parts[1]) > 0 {\n\t\t\t\t\t\t\tif strings.HasPrefix(parts[1], \"$\") {\n\t\t\t\t\t\t\t\targName := GetRefName(parts[1])\n\t\t\t\t\t\t\t\targVal, ok := dockerfile.FromArgs[argName]\n\t\t\t\t\t\t\t\tif !ok {\n\t\t\t\t\t\t\t\t\tcurrentStage.UnknownFromArgs[argName] = struct{}{}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentStage.FromArgs[argName] = argVal\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif hasDigest {\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.BuildArgDigest = argName\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.Digest = argVal\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.BuildArgTag = argName\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.Tag = argVal\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif hasDigest {\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.Digest = parts[1]\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentStage.Parent.Tag = parts[1]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif hasDigest {\n\t\t\t\t\t\t\t\tcurrentStage.Parent.HasEmptyDigest = true\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcurrentStage.Parent.HasEmptyTag = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif currentStage.Parent.Name != \"\" {\n\t\t\t\t\t\tif parentStage, ok := dockerfile.StagesByName[currentStage.Parent.Name]; ok {\n\t\t\t\t\t\t\tparentStage.IsUsed = true\n\t\t\t\t\t\t\tcurrentStage.Parent.ParentStage = parentStage\n\t\t\t\t\t\t\tcurrentStage.StageReferences[currentStage.Parent.Name] = parentStage\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcurrentStage.Parent.HasEmptyName = true\n\t\t\t\t\tcurrentStage.Parent.HasEmptyTag = true\n\t\t\t\t\tcurrentStage.Parent.HasEmptyDigest = true\n\t\t\t\t}\n\n\t\t\t\tdockerfile.Stages = append(dockerfile.Stages, currentStage)\n\t\t\t\tdockerfile.LastStage = currentStage\n\t\t\t}\n\n\t\t\tdockerfile.AllInstructions = append(dockerfile.AllInstructions, inst)\n\t\t\tdockerfile.InstructionsByType[inst.Name] = append(\n\t\t\t\tdockerfile.InstructionsByType[inst.Name], inst)\n\n\t\t\tif currentStage != nil {\n\t\t\t\tcurrentStage.EndLine = inst.EndLine\n\n\t\t\t\tinst.StageID = currentStage.Index\n\t\t\t\tinstStageIndex++\n\t\t\t\tinst.StageIndex = instStageIndex\n\t\t\t\tcurrentStage.AllInstructions = append(currentStage.AllInstructions, inst)\n\n\t\t\t\tif inst.Name == instruction.Onbuild {\n\t\t\t\t\tcurrentStage.OnBuildInstructions = append(currentStage.OnBuildInstructions, inst)\n\t\t\t\t} else if inst.Name == instruction.Copy {\n\t\t\t\t\tfor _, flag := range inst.Flags {\n\t\t\t\t\t\tif strings.HasPrefix(flag, \"--from=\") {\n\t\t\t\t\t\t\tfparts := strings.SplitN(flag, \"=\", 2)\n\t\t\t\t\t\t\t//possible values: stage index, stage name, image name\n\t\t\t\t\t\t\tvar stageRef *spec.BuildStage\n\t\t\t\t\t\t\trefIdx, err := strconv.Atoi(fparts[1])\n\t\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\t\tif refIdx >= 0 && refIdx < len(dockerfile.Stages) {\n\t\t\t\t\t\t\t\t\tstageRef = dockerfile.Stages[refIdx]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tstageRef = dockerfile.StagesByName[fparts[1]]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif stageRef != nil {\n\t\t\t\t\t\t\t\tstageRef.IsUsed = true\n\t\t\t\t\t\t\t\tcurrentStage.StageReferences[fparts[1]] = stageRef\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcurrentStage.ExternalReferences[fparts[1]] = struct{}{}\n\t\t\t\t\t\t\t\t//todo: check if it references a local (or remote) image\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} else if instruction.IsKnown(inst.Name) {\n\t\t\t\t\tcurrentStage.CurrentInstructions = append(currentStage.CurrentInstructions, inst)\n\t\t\t\t\tcurrentStage.CurrentInstructionsByType[inst.Name] = append(\n\t\t\t\t\t\tcurrentStage.CurrentInstructionsByType[inst.Name], inst)\n\n\t\t\t\t\tif inst.IsValid {\n\t\t\t\t\t\tswitch inst.Name {\n\t\t\t\t\t\tcase instruction.Arg:\n\t\t\t\t\t\t\tfor _, iarg := range inst.Args {\n\t\t\t\t\t\t\t\tif iarg == \"\" {\n\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif strings.Contains(iarg, \"=\") {\n\t\t\t\t\t\t\t\t\tiaparts := strings.SplitN(iarg, \"=\", 2)\n\t\t\t\t\t\t\t\t\tcurrentStage.BuildArgs[iaparts[0]] = iaparts[1]\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcurrentStage.BuildArgs[iarg] = \"\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t//only one ARG is supposed to be defined, but we'll use all\n\t\t\t\t\t\t\t//the 'ARG' value count lint check will detect the extra values\n\t\t\t\t\t\t\t//the k=v ARG values are also not parsed (unlike ENV k=v values)\n\t\t\t\t\t\tcase instruction.Env:\n\t\t\t\t\t\t\tfor i := 0; i < len(inst.Args) && (i+1) < len(inst.Args); i += 2 {\n\t\t\t\t\t\t\t\tif len(inst.Args[i]) == 0 {\n\t\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tcurrentStage.EnvVars[inst.Args[i]] = inst.Args[i+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} else {\n\t\t\t\tif inst.Name == instruction.Arg {\n\t\t\t\t\tif inst.IsValid && len(inst.Args) > 0 {\n\t\t\t\t\t\tdockerfile.ArgInstructions = append(dockerfile.ArgInstructions, inst)\n\t\t\t\t\t\tparts := strings.Split(inst.Args[0], \"=\")\n\t\t\t\t\t\targVal := \"\"\n\t\t\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\t\t\targVal = parts[1]\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdockerfile.FromArgs[parts[0]] = argVal\n\t\t\t\t\t} //note: should have a lint check for ARG without 'args'\n\t\t\t\t} else {\n\t\t\t\t\tdockerfile.StagelessInstructions = append(dockerfile.StagelessInstructions, inst)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !inst.IsValid {\n\t\t\t\tif !instruction.IsKnown(inst.Name) {\n\t\t\t\t\tdockerfile.UnknownInstructions = append(dockerfile.UnknownInstructions, inst)\n\t\t\t\t\tif currentStage != nil {\n\t\t\t\t\t\tcurrentStage.UnknownInstructions = append(currentStage.UnknownInstructions, inst)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tdockerfile.InvalidInstructions = append(dockerfile.InvalidInstructions, inst)\n\t\t\t\t\tif currentStage != nil {\n\t\t\t\t\t\tcurrentStage.InvalidInstructions = append(currentStage.InvalidInstructions, inst)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif dockerfile.LastStage != nil {\n\t\t\tdockerfile.LastStage.IsUsed = true\n\t\t}\n\t}\n\n\tdockerfile.Warnings = astParsed.Warnings\n\n\treturn dockerfile, nil\n}\n\nfunc GetRefName(ref string) string {\n\tref = strings.TrimPrefix(ref, \"$\")\n\tif strings.HasPrefix(ref, \"{\") && strings.HasSuffix(ref, \"}\") {\n\t\tref = strings.TrimPrefix(ref, \"{\")\n\t\tref = strings.TrimSuffix(ref, \"}\")\n\t}\n\n\treturn ref\n}\n"
  },
  {
    "path": "pkg/docker/dockerfile/reverse/reverse.go",
    "content": "package reverse\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dustin/go-humanize\"\n\tdocker \"github.com/fsouza/go-dockerclient\"\n\t\"github.com/google/shlex\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar (\n\tErrBadInstPrefix = errors.New(\"bad instruction prefix\")\n)\n\n// Dockerfile represents the reverse engineered Dockerfile info\ntype Dockerfile struct {\n\tLines                    []string             `json:\"lines,omitempty\"`\n\tMaintainers              []string             `json:\"maintainers,omitempty\"`\n\tAllUsers                 []string             `json:\"all_users,omitempty\"`\n\tExeUser                  string               `json:\"exe_user,omitempty\"`\n\tExposedPorts             []string             `json:\"exposed_ports,omitempty\"`\n\tImageStack               []*ImageInfo         `json:\"image_stack\"`\n\tAllInstructions          []*InstructionInfo   `json:\"all_instructions\"`\n\tInstructionGroups        [][]*InstructionInfo `json:\"instruction_groups\"`\n\tInstructionGroupsReverse [][]*InstructionInfo `json:\"instruction_groups_reverse\"`\n\tHasOnbuild               bool                 `json:\"has_onbuild\"`\n}\n\ntype ImageInfo struct {\n\tIsTopImage   bool               `json:\"is_top_image\"`\n\tID           string             `json:\"id\"`\n\tFullName     string             `json:\"full_name\"`\n\tRepoName     string             `json:\"repo_name\"`\n\tVersionTag   string             `json:\"version_tag\"`\n\tRawTags      []string           `json:\"raw_tags,omitempty\"`\n\tCreateTime   string             `json:\"create_time\"`\n\tNewSize      int64              `json:\"new_size\"`\n\tNewSizeHuman string             `json:\"new_size_human\"`\n\tBaseImageID  string             `json:\"base_image_id,omitempty\"`\n\tInstructions []*InstructionInfo `json:\"instructions\"`\n}\n\ntype InstructionInfo struct {\n\tType string `json:\"type\"`\n\tTime string `json:\"time\"`\n\t//Time              time.Time `json:\"time\"`\n\tIsLastInstruction       bool     `json:\"is_last_instruction,omitempty\"`\n\tIsNop                   bool     `json:\"is_nop\"`\n\tIsExecForm              bool     `json:\"is_exec_form,omitempty\"` //is exec/json format (a valid field for RUN, ENTRYPOINT, CMD)\n\tLocalImageExists        bool     `json:\"local_image_exists\"`\n\tIntermediateImageID     string   `json:\"intermediate_image_id,omitempty\"`\n\tLayerIndex              int      `json:\"layer_index\"` //-1 for an empty layer\n\tLayerID                 string   `json:\"layer_id,omitempty\"`\n\tLayerFSDiffID           string   `json:\"layer_fsdiff_id,omitempty\"`\n\tSize                    int64    `json:\"size\"`\n\tSizeHuman               string   `json:\"size_human,omitempty\"`\n\tParams                  string   `json:\"params,omitempty\"`\n\tCommandSnippet          string   `json:\"command_snippet\"`\n\tCommandAll              string   `json:\"command_all\"`\n\tSystemCommands          []string `json:\"system_commands,omitempty\"`\n\tComment                 string   `json:\"comment,omitempty\"`\n\tAuthor                  string   `json:\"author,omitempty\"`\n\tEmptyLayer              bool     `json:\"empty_layer,omitempty\"`\n\tinstPosition            string\n\timageFullName           string\n\tRawTags                 []string  `json:\"raw_tags,omitempty\"`\n\tTarget                  string    `json:\"target,omitempty\"`      //for ADD and COPY\n\tSourceType              string    `json:\"source_type,omitempty\"` //for ADD and COPY\n\tIsBuildKitInstruction   bool      `json:\"is_buildkit_instruction,omitempty\"`\n\tBuildKitInfo            string    `json:\"buildkit_info,omitempty\"`\n\tTimeValue               time.Time `json:\"-\"`\n\tInstSetTimeBucket       time.Time `json:\"inst_set_time_bucket,omitempty\"`\n\tInstSetTimeIndex        int       `json:\"inst_set_time_index\"`\n\tInstSetTimeReverseIndex int       `json:\"inst_set_time_reverse_index\"`\n}\n\nconst (\n\tbuildkitCreatedBySuffix  = \"# buildkit\"\n\tbuildkitPrefix           = \"buildkit.\"\n\tbuildkitDockerfilePrefix = \"buildkit.dockerfile.\"\n\tbuildkitDockerfileV0     = \"buildkit.dockerfile.v0\"\n)\n\n//The 'History' API doesn't expose the 'author' in the records it returns\n//The 'author' field is useful in detecting if it's a Dockerfile instruction\n//or if it's created with something else.\n//One option is to combine the 'History' API data with the history data\n//from the image config JSON embedded in the image.\n//Another option is to rely on '#(nop)'.\n\nconst (\n\tdefaultRunInstShell = \"/bin/sh\"\n\tnotRunInstPrefix    = \"/bin/sh -c #(nop) \"\n\trunInstShellPrefix  = \"/bin/sh -c \" //without any ARG params\n\trunInstArgsPrefix   = \"|\"\n)\n\nconst (\n\t//MAINTAINER:\n\tinstTypeMaintainer   = \"MAINTAINER\"\n\tinstPrefixMaintainer = \"MAINTAINER \"\n\t//ENTRYPOINT:\n\tinstTypeEntrypoint   = \"ENTRYPOINT\"\n\tinstPrefixEntrypoint = \"ENTRYPOINT \"\n\t//CMD:\n\tinstTypeCmd   = \"CMD\"\n\tinstPrefixCmd = \"CMD \"\n\t//USER:\n\tinstTypeUser   = \"USER\"\n\tinstPrefixUser = \"USER \"\n\t//EXPOSE:\n\tinstTypeExpose   = \"EXPOSE\"\n\tinstPrefixExpose = \"EXPOSE \"\n\t//WORKDIR:\n\tinstTypeWorkdir   = \"WORKDIR\"\n\tinstPrefixWorkdir = \"WORKDIR \"\n\t//HEALTHCHECK:\n\tinstTypeHealthcheck           = \"HEALTHCHECK\"\n\tinstPrefixHealthcheck         = \"HEALTHCHECK \"\n\tinstPrefixBasicEncHealthcheck = \"HEALTHCHECK --\"\n\t//ONBUILD:\n\tinstTypeOnbuild = \"ONBUILD\"\n\t//RUN:\n\tinstTypeRun   = \"RUN\"\n\tinstPrefixRun = \"RUN \"\n\t//ADD:\n\tinstTypeAdd = \"ADD\"\n\t//COPY:\n\tinstTypeCopy = \"COPY\"\n\n\tinstTypeVolume     = \"VOLUME\"\n\tinstTypeEnv        = \"ENV\"\n\tinstTypeLabel      = \"LABEL\"\n\tinstTypeStopSignal = \"STOPSIGNAL\"\n\tinstTypeShell      = \"SHELL\"\n\tinstTypeArg        = \"ARG\" //shouldn't see it as an standalone instruction\n)\n\nvar instructionTypes = map[string]struct{}{\n\tinstTypeRun:         {},\n\tinstTypeEntrypoint:  {},\n\tinstTypeCmd:         {},\n\tinstTypeUser:        {},\n\tinstTypeExpose:      {},\n\tinstTypeWorkdir:     {},\n\tinstTypeHealthcheck: {},\n\tinstTypeOnbuild:     {},\n\tinstTypeAdd:         {},\n\tinstTypeCopy:        {},\n\tinstTypeMaintainer:  {},\n\tinstTypeVolume:      {},\n\tinstTypeEnv:         {},\n\tinstTypeLabel:       {},\n\tinstTypeStopSignal:  {},\n\tinstTypeShell:       {},\n\tinstTypeArg:         {},\n}\n\nfunc isInstructionType(input string) bool {\n\t_, found := instructionTypes[input]\n\treturn found\n}\n\nfunc hasInstructionPrefix(input string) bool {\n\tif !strings.Contains(input, \" \") {\n\t\treturn false\n\t}\n\n\tparts := strings.SplitN(input, \" \", 2)\n\treturn isInstructionType(parts[0])\n}\n\nconst (\n\tmapPrefix        = \"map[\"\n\tportMapKeySuffix = \":{}]\"\n)\n\ntype tbrecord struct {\n\tindex       int\n\tinstruction *InstructionInfo\n\ttb          time.Time\n}\n\nconst tbDuration = (15 * time.Minute)\n\n// DockerfileFromHistoryData recreates Dockerfile information from container image history\nfunc DockerfileFromHistoryData(data string) (*Dockerfile, error) {\n\tvar imageHistory []docker.ImageHistory\n\tif err := json.NewDecoder(strings.NewReader(data)).Decode(&imageHistory); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn DockerfileFromHistoryStruct(imageHistory)\n}\n\n// DockerfileFromHistory recreates Dockerfile information from container image history\nfunc DockerfileFromHistory(apiClient *docker.Client, imageID string) (*Dockerfile, error) {\n\t//TODO: make it possible to pass the history information as a param\n\t//TODO: pass the other image metadata (including OCI and buildkit base image info)\n\timageHistory, err := apiClient.ImageHistory(imageID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn DockerfileFromHistoryStruct(imageHistory)\n}\n\n// DockerfileFromHistoryStruct recreates Dockerfile information from container image history\nfunc DockerfileFromHistoryStruct(imageHistory []docker.ImageHistory) (*Dockerfile, error) {\n\tvar out Dockerfile\n\n\tlog.Tracef(\"\\n\\nreverse.DockerfileFromHistoryStruct - IMAGE HISTORY:\\n%#v\\n\\n\", imageHistory)\n\n\tvar timeBuckets = map[time.Time][]tbrecord{}\n\tvar reversedInstructions []*InstructionInfo\n\tvar currentImageInfo *ImageInfo\n\tvar prevImageID string\n\n\timageLayerCount := len(imageHistory)\n\timageLayerStart := imageLayerCount - 1\n\tstartNewImage := true\n\tif imageLayerCount > 0 {\n\t\tfor idx := imageLayerStart; idx >= 0; idx-- {\n\t\t\trawLine := imageHistory[idx].CreatedBy\n\n\t\t\tvar isNop bool\n\t\t\tvar inst string\n\n\t\t\tvar isBuildKitInstruction bool\n\t\t\tif strings.HasSuffix(rawLine, buildkitCreatedBySuffix) {\n\t\t\t\tisBuildKitInstruction = true\n\t\t\t\trawLine = strings.TrimSuffix(rawLine, buildkitCreatedBySuffix)\n\t\t\t}\n\n\t\t\tvar rawInst string\n\t\t\tisRunInst := strings.HasPrefix(rawLine, instPrefixRun)\n\t\t\tif isRunInst {\n\t\t\t\tparts := strings.SplitN(rawLine, \" \", 2)\n\t\t\t\trawInst = parts[1]\n\t\t\t} else {\n\t\t\t\trawInst = rawLine\n\t\t\t}\n\n\t\t\tif strings.Contains(rawLine, \"#(nop)\") {\n\t\t\t\tisNop = true\n\t\t\t}\n\n\t\t\tisExecForm := false\n\n\t\t\tswitch {\n\t\t\tcase len(rawInst) == 0:\n\t\t\t\tinst = \"\"\n\t\t\t\t//NOTE:\n\t\t\t\t//still keeping a placeholder for the empty instructions in history\n\t\t\t\t//because not all builders populate all history record fields (e.g., buildkits)\n\t\t\tcase strings.HasPrefix(rawInst, notRunInstPrefix):\n\t\t\t\t//Instructions that are not RUN\n\t\t\t\tinst = strings.TrimPrefix(rawInst, notRunInstPrefix)\n\t\t\tcase strings.HasPrefix(rawInst, runInstShellPrefix):\n\t\t\t\t//RUN instruction in shell form\n\t\t\t\trunData := strings.TrimPrefix(rawInst, runInstShellPrefix)\n\t\t\t\tif strings.Contains(runData, \"&&\") {\n\t\t\t\t\tparts := strings.Split(runData, \"&&\")\n\t\t\t\t\tfor i := range parts {\n\t\t\t\t\t\tpartPrefix := \"\"\n\t\t\t\t\t\tif i != 0 {\n\t\t\t\t\t\t\tpartPrefix = \"\\t\"\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparts[i] = partPrefix + strings.TrimSpace(parts[i])\n\t\t\t\t\t}\n\t\t\t\t\trunDataFormatted := strings.Join(parts, \" && \\\\\\n\")\n\t\t\t\t\tinst = instPrefixRun + runDataFormatted\n\t\t\t\t} else {\n\t\t\t\t\tinst = instPrefixRun + runData\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\t//TODO: need to refactor\n\t\t\t\tprocessed := false\n\t\t\t\t//rawInst := rawLine\n\t\t\t\tif strings.HasPrefix(rawInst, runInstArgsPrefix) {\n\t\t\t\t\tvar err error\n\t\t\t\t\tinst, processed, isExecForm, err = stripRunInstArgs(rawInst) //should not be ':='\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"stripRunInstArgs: err -> %v\\n\", err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif hasInstructionPrefix(rawInst) {\n\t\t\t\t\tinst = rawInst\n\t\t\t\t} else {\n\t\t\t\t\tif !processed {\n\t\t\t\t\t\t//default to RUN instruction in exec form\n\t\t\t\t\t\tisExecForm = true\n\t\t\t\t\t\tinst = instPrefixRun + rawInst\n\t\t\t\t\t\tif outArray, err := shlex.Split(rawInst); err == nil {\n\t\t\t\t\t\t\tvar outJson bytes.Buffer\n\t\t\t\t\t\t\tencoder := json.NewEncoder(&outJson)\n\t\t\t\t\t\t\tencoder.SetEscapeHTML(false)\n\t\t\t\t\t\t\terr := encoder.Encode(outArray)\n\t\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\t\tinst = fmt.Sprintf(\"RUN %s\", outJson.String())\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\n\t\t\t//NOTE: Dockerfile instructions can be any case, but the instructions from history are always uppercase\n\t\t\tcleanInst := strings.TrimSpace(inst)\n\n\t\t\tif strings.HasPrefix(cleanInst, instPrefixEntrypoint) {\n\t\t\t\tcleanInst = strings.Replace(cleanInst, \"&{[\", \"[\", -1)\n\t\t\t\tcleanInst = strings.Replace(cleanInst, \"]}\", \"]\", -1)\n\n\t\t\t\tentrypointShellFormPrefix := `ENTRYPOINT [\"/bin/sh\" \"-c\" \"`\n\t\t\t\tif strings.HasPrefix(cleanInst, entrypointShellFormPrefix) {\n\t\t\t\t\tinstData := strings.TrimPrefix(cleanInst, entrypointShellFormPrefix)\n\t\t\t\t\tinstData = strings.TrimSuffix(instData, `\"]`)\n\t\t\t\t\tcleanInst = instPrefixEntrypoint + instData\n\t\t\t\t} else {\n\t\t\t\t\tisExecForm = true\n\n\t\t\t\t\tinstData := strings.TrimPrefix(cleanInst, instPrefixEntrypoint)\n\t\t\t\t\tinstData = fixJSONArray(instData)\n\t\t\t\t\tcleanInst = instPrefixEntrypoint + instData\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(cleanInst, instPrefixCmd) {\n\t\t\t\tcmdShellFormPrefix := `CMD [\"/bin/sh\" \"-c\" \"`\n\t\t\t\tif strings.HasPrefix(cleanInst, cmdShellFormPrefix) {\n\t\t\t\t\tinstData := strings.TrimPrefix(cleanInst, cmdShellFormPrefix)\n\t\t\t\t\tinstData = strings.TrimSuffix(instData, `\"]`)\n\t\t\t\t\tcleanInst = instPrefixCmd + instData\n\t\t\t\t} else {\n\t\t\t\t\tisExecForm = true\n\n\t\t\t\t\tinstData := strings.TrimPrefix(cleanInst, instPrefixCmd)\n\t\t\t\t\tinstData = fixJSONArray(instData)\n\t\t\t\t\tcleanInst = instPrefixCmd + instData\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(cleanInst, instPrefixMaintainer) {\n\t\t\t\tparts := strings.SplitN(cleanInst, \" \", 2)\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\tmaintainer := strings.TrimSpace(parts[1])\n\n\t\t\t\t\tout.Maintainers = append(out.Maintainers, maintainer)\n\t\t\t\t} else {\n\t\t\t\t\tlog.Infof(\"ReverseDockerfileFromHistory - MAINTAINER - unexpected number of user parts - %v\", len(parts))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(cleanInst, instPrefixUser) {\n\t\t\t\tparts := strings.SplitN(cleanInst, \" \", 2)\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\tuserName := strings.TrimSpace(parts[1])\n\n\t\t\t\t\tout.AllUsers = append(out.AllUsers, userName)\n\t\t\t\t\tout.ExeUser = userName\n\t\t\t\t} else {\n\t\t\t\t\tlog.Infof(\"ReverseDockerfileFromHistory - unexpected number of user parts - %v\", len(parts))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(cleanInst, instPrefixExpose) {\n\t\t\t\tparts := strings.SplitN(cleanInst, \" \", 2)\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\tportInfo := strings.TrimSpace(parts[1])\n\t\t\t\t\tif strings.HasPrefix(portInfo, mapPrefix) &&\n\t\t\t\t\t\tstrings.HasSuffix(portInfo, portMapKeySuffix) {\n\t\t\t\t\t\tportInfo = strings.TrimPrefix(portInfo, mapPrefix)\n\t\t\t\t\t\tportInfo = strings.TrimSuffix(portInfo, portMapKeySuffix)\n\t\t\t\t\t\tcleanInst = fmt.Sprintf(\"EXPOSE %s\", portInfo)\n\t\t\t\t\t}\n\n\t\t\t\t\tout.ExposedPorts = append(out.ExposedPorts, portInfo)\n\t\t\t\t} else {\n\t\t\t\t\tlog.Infof(\"ReverseDockerfileFromHistory - unexpected number of expose parts - %v\", len(parts))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tinstInfo := InstructionInfo{\n\t\t\t\tIsNop:                   isNop,\n\t\t\t\tIsExecForm:              isExecForm,\n\t\t\t\tCommandAll:              cleanInst,\n\t\t\t\tTime:                    time.Unix(imageHistory[idx].Created, 0).UTC().Format(time.RFC3339),\n\t\t\t\tTimeValue:               time.Unix(imageHistory[idx].Created, 0),\n\t\t\t\tComment:                 imageHistory[idx].Comment,\n\t\t\t\tRawTags:                 imageHistory[idx].Tags,\n\t\t\t\tSize:                    imageHistory[idx].Size,\n\t\t\t\tIsBuildKitInstruction:   isBuildKitInstruction,\n\t\t\t\tInstSetTimeIndex:        -1,\n\t\t\t\tInstSetTimeReverseIndex: -1,\n\t\t\t}\n\n\t\t\tinstInfo.InstSetTimeBucket = instInfo.TimeValue.Truncate(tbDuration)\n\n\t\t\tif strings.HasPrefix(instInfo.Comment, buildkitPrefix) {\n\t\t\t\tinstInfo.IsBuildKitInstruction = true\n\t\t\t}\n\n\t\t\tinstParts := strings.SplitN(cleanInst, \" \", 2)\n\t\t\tif len(instParts) == 2 {\n\t\t\t\tinstInfo.Type = instParts[0]\n\t\t\t}\n\n\t\t\tif instInfo.Type == instTypeOnbuild {\n\t\t\t\tout.HasOnbuild = true\n\t\t\t}\n\n\t\t\tif instInfo.CommandAll == \"\" {\n\t\t\t\tinstInfo.Type = \"NONE\"\n\t\t\t\tinstInfo.CommandAll = \"# no instruction info\"\n\t\t\t}\n\n\t\t\tif instInfo.Type == instTypeRun {\n\t\t\t\tvar cmdParts []string\n\t\t\t\tcmds := strings.Replace(instParts[1], \"\\\\\", \"\", -1)\n\t\t\t\tif strings.Contains(cmds, \"&&\") {\n\t\t\t\t\tcmdParts = strings.Split(cmds, \"&&\")\n\t\t\t\t} else {\n\t\t\t\t\tcmdParts = strings.Split(cmds, \";\")\n\t\t\t\t}\n\n\t\t\t\tfor _, cmd := range cmdParts {\n\t\t\t\t\tcmd = strings.TrimSpace(cmd)\n\t\t\t\t\tcmd = strings.Replace(cmd, \"\\t\", \"\", -1)\n\t\t\t\t\tcmd = strings.Replace(cmd, \"\\n\", \"\", -1)\n\t\t\t\t\tinstInfo.SystemCommands = append(instInfo.SystemCommands, cmd)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif len(instParts) == 2 {\n\t\t\t\t\tinstInfo.Params = instParts[1]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif instInfo.Type == instTypeWorkdir {\n\t\t\t\tinstInfo.SystemCommands = append(instInfo.SystemCommands, fmt.Sprintf(\"mkdir -p %s\", instParts[1]))\n\t\t\t}\n\n\t\t\tswitch instInfo.Type {\n\t\t\tcase instTypeAdd, instTypeCopy:\n\t\t\t\tif strings.Contains(instInfo.Params, \":\") && strings.Contains(instInfo.Params, \" in \") {\n\t\t\t\t\tpparts := strings.SplitN(instInfo.Params, \":\", 2)\n\t\t\t\t\tif len(pparts) == 2 {\n\t\t\t\t\t\tinstInfo.SourceType = pparts[0]\n\t\t\t\t\t\ttparts := strings.SplitN(pparts[1], \" in \", 2)\n\t\t\t\t\t\tif len(tparts) == 2 {\n\t\t\t\t\t\t\tinstInfo.Target = tparts[1]\n\n\t\t\t\t\t\t\tinstInfo.CommandAll = fmt.Sprintf(\"%s %s:%s %s\",\n\t\t\t\t\t\t\t\tinstInfo.Type,\n\t\t\t\t\t\t\t\tinstInfo.SourceType,\n\t\t\t\t\t\t\t\ttparts[0],\n\t\t\t\t\t\t\t\tinstInfo.Target)\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\tif instInfo.Type == instTypeHealthcheck {\n\n\t\t\t\thealthInst, _, err := deserialiseHealtheckInstruction(instInfo.CommandAll)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"ReverseDockerfileFromHistory - HEALTHCHECK - deserialiseHealtheckInstruction - %v\", err)\n\t\t\t\t}\n\n\t\t\t\tinstInfo.CommandAll = healthInst\n\t\t\t}\n\n\t\t\tif len(instInfo.CommandAll) > 44 {\n\t\t\t\tinstInfo.CommandSnippet = fmt.Sprintf(\"%s...\", instInfo.CommandAll[0:44])\n\t\t\t} else {\n\t\t\t\tinstInfo.CommandSnippet = instInfo.CommandAll\n\t\t\t}\n\n\t\t\tif instInfo.Size > 0 {\n\t\t\t\tinstInfo.SizeHuman = humanize.Bytes(uint64(instInfo.Size))\n\t\t\t}\n\n\t\t\tif imageHistory[idx].ID != \"<missing>\" {\n\t\t\t\tinstInfo.LocalImageExists = true\n\t\t\t\tinstInfo.IntermediateImageID = imageHistory[idx].ID\n\t\t\t}\n\n\t\t\tif startNewImage {\n\t\t\t\tstartNewImage = false\n\t\t\t\tcurrentImageInfo = &ImageInfo{\n\t\t\t\t\tBaseImageID: prevImageID,\n\t\t\t\t\tNewSize:     0,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentImageInfo.NewSize += imageHistory[idx].Size\n\t\t\tcurrentImageInfo.Instructions = append(currentImageInfo.Instructions, &instInfo)\n\n\t\t\tout.AllInstructions = append(out.AllInstructions, &instInfo)\n\n\t\t\tinstPosition := \"intermediate\"\n\t\t\tif idx == imageLayerStart {\n\t\t\t\tinstPosition = \"first\" //first instruction in the list\n\t\t\t}\n\n\t\t\tif idx == 0 || (len(imageHistory[idx].Tags) > 0) {\n\t\t\t\tinstPosition = \"last\" //last in an image\n\n\t\t\t\tcurrentImageInfo.ID = imageHistory[idx].ID\n\t\t\t\tprevImageID = currentImageInfo.ID\n\n\t\t\t\tif instInfo.IntermediateImageID == currentImageInfo.ID {\n\t\t\t\t\tinstInfo.IntermediateImageID = \"\"\n\t\t\t\t\tinstInfo.IsLastInstruction = true\n\t\t\t\t}\n\n\t\t\t\tcurrentImageInfo.CreateTime = instInfo.Time\n\t\t\t\tcurrentImageInfo.RawTags = imageHistory[idx].Tags\n\n\t\t\t\tif len(imageHistory[idx].Tags) > 0 {\n\t\t\t\t\tinstInfo.imageFullName = imageHistory[idx].Tags[0]\n\t\t\t\t\tcurrentImageInfo.FullName = imageHistory[idx].Tags[0]\n\n\t\t\t\t\tif tagInfo := strings.Split(imageHistory[idx].Tags[0], \":\"); len(tagInfo) > 1 {\n\t\t\t\t\t\tcurrentImageInfo.RepoName = tagInfo[0]\n\t\t\t\t\t\tcurrentImageInfo.VersionTag = tagInfo[1]\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcurrentImageInfo.NewSizeHuman = humanize.Bytes(uint64(currentImageInfo.NewSize))\n\n\t\t\t\tout.ImageStack = append(out.ImageStack, currentImageInfo)\n\t\t\t\tstartNewImage = true\n\t\t\t}\n\n\t\t\tinstInfo.instPosition = instPosition\n\n\t\t\treversedInstructions = append(reversedInstructions, &instInfo)\n\n\t\t\ttbr := tbrecord{\n\t\t\t\tindex:       len(reversedInstructions) - 1,\n\t\t\t\tinstruction: &instInfo,\n\t\t\t\ttb:          instInfo.InstSetTimeBucket,\n\t\t\t}\n\t\t\ttimeBuckets[instInfo.InstSetTimeBucket] = append(timeBuckets[instInfo.InstSetTimeBucket], tbr)\n\t\t}\n\n\t\tif currentImageInfo != nil {\n\t\t\tcurrentImageInfo.IsTopImage = true\n\t\t}\n\t}\n\n\ttkeys := make([]time.Time, 0, len(timeBuckets))\n\tfor k := range timeBuckets {\n\t\ttkeys = append(tkeys, k)\n\t}\n\n\tsort.SliceStable(tkeys, func(i, j int) bool { return tkeys[i].Before(tkeys[j]) })\n\ttkListLen := len(tkeys)\n\tfor i, k := range tkeys {\n\t\ttbrList := timeBuckets[k]\n\t\tfor _, tbr := range tbrList {\n\t\t\ttbr.instruction.InstSetTimeIndex = i\n\t\t\ttbr.instruction.InstSetTimeReverseIndex = tkListLen - 1 - i\n\t\t}\n\t}\n\n\tout.InstructionGroups = make([][]*InstructionInfo, tkListLen)\n\tout.InstructionGroupsReverse = make([][]*InstructionInfo, tkListLen)\n\n\t//Always adding \"FROM scratch\" as the first line\n\t//GOAL: to have a reversed Dockerfile that can be used to build a new image\n\tout.Lines = append(out.Lines, \"FROM scratch\")\n\tprevInstSetTimeIndex := -1\n\tfor idx, instInfo := range reversedInstructions {\n\t\tif instInfo.instPosition == \"first\" {\n\t\t\tout.Lines = append(out.Lines, \"# new image\")\n\t\t}\n\n\t\tif instInfo.InstSetTimeIndex != prevInstSetTimeIndex {\n\t\t\tout.Lines = append(out.Lines, fmt.Sprintf(\"\\n# instruction set group %d\\n\", instInfo.InstSetTimeIndex+1))\n\t\t\tprevInstSetTimeIndex = instInfo.InstSetTimeIndex\n\t\t}\n\n\t\tout.InstructionGroups[instInfo.InstSetTimeIndex] = append(out.InstructionGroups[instInfo.InstSetTimeIndex], instInfo)\n\t\tout.InstructionGroupsReverse[instInfo.InstSetTimeReverseIndex] = append(out.InstructionGroupsReverse[instInfo.InstSetTimeReverseIndex], instInfo)\n\n\t\tif instInfo.Comment != \"\" {\n\t\t\toutComment := fmt.Sprintf(\"# %s\", instInfo.Comment)\n\t\t\tif instInfo.IsBuildKitInstruction {\n\t\t\t\toutComment = fmt.Sprintf(\"%s (a buildkit instruction)\", outComment)\n\t\t\t}\n\t\t\tout.Lines = append(out.Lines, outComment)\n\t\t} else if instInfo.IsBuildKitInstruction {\n\t\t\tout.Lines = append(out.Lines, \"# a buildkit instruction\")\n\t\t}\n\n\t\tout.Lines = append(out.Lines, instInfo.CommandAll)\n\t\tif instInfo.instPosition == \"last\" {\n\t\t\tcommentText := fmt.Sprintf(\"# end of image: %s (id: %s tags: %s)\",\n\t\t\t\tinstInfo.imageFullName, instInfo.IntermediateImageID, strings.Join(instInfo.RawTags, \",\"))\n\n\t\t\tout.Lines = append(out.Lines, commentText)\n\t\t\tout.Lines = append(out.Lines, \"\")\n\t\t\tif idx < (len(reversedInstructions) - 1) {\n\t\t\t\tout.Lines = append(out.Lines, \"# new image\")\n\t\t\t}\n\t\t}\n\t}\n\n\tlog.Debugf(\"IMAGE INSTRUCTIONS:\")\n\tfor _, iiLine := range out.Lines {\n\t\tlog.Debug(iiLine)\n\t}\n\n\treturn &out, nil\n\n\t//BASE LAYER IDENTIFICATION:\n\t//* tags from the instruction history\n\t//* instruction time-based clustering\n\t//* instruction patterns (e.g., base images often have their own ENTRYPOINT/CMD instructions)\n\t//* base image metadata from the image labels (e.g., \"org.opencontainers.image.base.digest\" OCI label)\n\t//* database with pre-indexed common base image digests (will require a network lookup)\n}\n\nfunc stripRunInstArgs(rawInst string) (string, bool, bool, error) {\n\tparts := strings.SplitN(rawInst, \" \", 2)\n\tif len(parts) == 2 {\n\t\twithArgs := strings.TrimSpace(parts[1])\n\t\targNumStr := parts[0][1:]\n\t\targNum, err := strconv.Atoi(argNumStr)\n\t\tif err == nil {\n\t\t\tif withArgsArray, err := shlex.Split(withArgs); err == nil {\n\t\t\t\tif len(withArgsArray) > argNum {\n\t\t\t\t\trawInstParts := withArgsArray[argNum:]\n\t\t\t\t\tisExecForm := false\n\t\t\t\t\tprocessed := true\n\t\t\t\t\tinst := \"\"\n\t\t\t\t\tif len(rawInstParts) > 2 &&\n\t\t\t\t\t\trawInstParts[0] == defaultRunInstShell &&\n\t\t\t\t\t\trawInstParts[1] == \"-c\" {\n\t\t\t\t\t\tisExecForm = false\n\t\t\t\t\t\trawInstParts = rawInstParts[2:]\n\n\t\t\t\t\t\tinst = fmt.Sprintf(\"RUN %s\", strings.Join(rawInstParts, \" \"))\n\t\t\t\t\t\tinst = strings.TrimSpace(inst)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tisExecForm = true\n\n\t\t\t\t\t\tvar outJson bytes.Buffer\n\t\t\t\t\t\tencoder := json.NewEncoder(&outJson)\n\t\t\t\t\t\tencoder.SetEscapeHTML(false)\n\t\t\t\t\t\terr = encoder.Encode(rawInstParts)\n\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\tinst = fmt.Sprintf(\"RUN %s\", outJson.String())\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn inst, processed, isExecForm, err\n\t\t\t\t} else {\n\t\t\t\t\tlog.Infof(\"reverse.stripRunInstArgs - RUN with ARGs - malformed - %v (%v)\", rawInst, err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlog.Infof(\"reverse.stripRunInstArgs - RUN with ARGs - malformed - %v (%v)\", rawInst, err)\n\t\t\t}\n\n\t\t} else {\n\t\t\tlog.Infof(\"reverse.stripRunInstArgs - RUN with ARGs - malformed number of ARGs - %v (%v)\", rawInst, err)\n\t\t}\n\t} else {\n\t\tlog.Infof(\"reverse.stripRunInstArgs - RUN with ARGs - unexpected number of parts - %v\", rawInst)\n\t}\n\n\treturn \"\", false, false, nil\n}\n\n// SaveDockerfileData saves the Dockerfile information to a file\nfunc SaveDockerfileData(fatImageDockerfileLocation string, fatImageDockerfileLines []string) error {\n\tvar data bytes.Buffer\n\tdata.WriteString(strings.Join(fatImageDockerfileLines, \"\\n\"))\n\treturn os.WriteFile(fatImageDockerfileLocation, data.Bytes(), 0644)\n}\n\nfunc fixJSONArray(in string) string {\n\tdata := in\n\tif data[0] == '[' {\n\t\tdata = data[1 : len(data)-1]\n\t}\n\toutArray, err := shlex.Split(data)\n\tif err != nil {\n\t\treturn in\n\t}\n\n\tvar out bytes.Buffer\n\tencoder := json.NewEncoder(&out)\n\tencoder.SetEscapeHTML(false)\n\terr = encoder.Encode(outArray)\n\tif err != nil {\n\t\treturn in\n\t}\n\n\treturn out.String()\n}\n\nfunc deserialiseHealtheckInstruction(data string) (string, *docker.HealthConfig, error) {\n\t//Example:\n\t// HEALTHCHECK &{[\"CMD\" \"/healthcheck\" \"8080\"] \"5s\" \"10s\" \"0s\" '\\x03'}\n\t// HEALTHCHECK --interval=5s --timeout=10s --retries=3 CMD [ \"/healthcheck\", \"8080\" ]\n\t//Note: CMD can be specified with both formats (shell and json)\n\t//Buildah example (raw/full):\n\t// /bin/sh -c #(nop) HEALTHCHECK --interval=5m --timeout=3s  CMD curl -f http://localhost/ || exit 1\n\tcleanInst := strings.TrimSpace(data)\n\tif !strings.HasPrefix(cleanInst, instPrefixHealthcheck) {\n\t\treturn \"\", nil, ErrBadInstPrefix\n\t}\n\n\tvar config docker.HealthConfig\n\tvar strTest string\n\tif strings.HasPrefix(cleanInst, instPrefixBasicEncHealthcheck) || !strings.Contains(cleanInst, \"&{[\") {\n\t\t//handling the basic Buildah encoding\n\n\t\tvar err error\n\t\tif strings.Contains(cleanInst, \"--interval=\") {\n\t\t\tvparts := strings.SplitN(cleanInst, \"--interval=\", 2)\n\t\t\tvparts = strings.SplitN(vparts[1], \" \", 2)\n\n\t\t\tconfig.Interval, err = time.ParseDuration(vparts[0])\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"[%s] config.Interval err = %v\", vparts[0], err)\n\t\t\t}\n\t\t}\n\n\t\tif strings.Contains(cleanInst, \"--timeout=\") {\n\t\t\tvparts := strings.SplitN(cleanInst, \"--timeout=\", 2)\n\t\t\tvparts = strings.SplitN(vparts[1], \" \", 2)\n\n\t\t\tconfig.Timeout, err = time.ParseDuration(vparts[0])\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"[%s] config.Timeout err = %v\", vparts[0], err)\n\t\t\t}\n\t\t}\n\n\t\tif strings.Contains(cleanInst, \"--start-period=\") {\n\t\t\tvparts := strings.SplitN(cleanInst, \"--start-period=\", 2)\n\t\t\tvparts = strings.SplitN(vparts[1], \" \", 2)\n\n\t\t\tconfig.StartPeriod, err = time.ParseDuration(vparts[0])\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"[%s] config.StartPeriod err = %v\", vparts[0], err)\n\t\t\t}\n\t\t}\n\n\t\tif strings.Contains(cleanInst, \"--retries=\") {\n\t\t\tvparts := strings.SplitN(cleanInst, \"--retries=\", 2)\n\t\t\tvparts = strings.SplitN(vparts[1], \" \", 2)\n\n\t\t\tretries, err := strconv.ParseInt(vparts[0], 16, 64)\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"[%s] config.Retries err = %v\", vparts[0], err)\n\t\t\t} else {\n\t\t\t\tconfig.Retries = int(retries)\n\t\t\t}\n\t\t}\n\n\t\tif strings.Contains(cleanInst, \" CMD \") {\n\t\t\tparts := strings.SplitN(cleanInst, \" CMD \", 2)\n\t\t\tstrTest = fmt.Sprintf(\"CMD %s\", parts[1])\n\t\t\tconfig.Test = []string{\"CMD\", parts[1]}\n\t\t}\n\t} else {\n\t\tcleanInst = strings.Replace(cleanInst, \"&{[\", \"\", -1)\n\n\t\t//Splits the string into two parts - first part pointer to array of string and rest of the string with } in end.\n\t\tinstParts := strings.SplitN(cleanInst, \"]\", 2)\n\t\t// Cleans HEALTHCHECK part and splits the first part further\n\t\tparts := strings.SplitN(instParts[0], \" \", 2)\n\t\t// joins the first part of the string\n\t\tinstPart1 := strings.Join(parts[1:], \" \")\n\t\t// removes quotes from the first part of the string\n\t\tinstPart1 = strings.ReplaceAll(instPart1, \"\\\"\", \"\")\n\n\t\t// cleans it to assign it to the pointer config.Test\n\t\tconfig.Test = strings.Split(instPart1, \" \")\n\n\t\t// removes the } from the second part of the string\n\t\tinstPart2 := strings.Replace(instParts[1], \"}\", \"\", -1)\n\t\t// removes extra spaces from string\n\t\tinstPart2 = strings.TrimSpace(instPart2)\n\n\t\tparamParts := strings.SplitN(instPart2, \" \", 4)\n\t\tfor i, param := range paramParts {\n\t\t\tparamParts[i] = strings.Trim(param, \"\\\"'\")\n\t\t}\n\n\t\tvar err error\n\t\tconfig.Interval, err = time.ParseDuration(paramParts[0])\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"[%s] config.Interval err = %v\", paramParts[0], err)\n\t\t}\n\n\t\tconfig.Timeout, err = time.ParseDuration(paramParts[1])\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"[%s] config.Timeout err = %v\", paramParts[1], err)\n\t\t}\n\n\t\tconfig.StartPeriod, err = time.ParseDuration(paramParts[2])\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"[%s] config.StartPeriod err = %v\", paramParts[2], err)\n\t\t}\n\n\t\tvar retries int64\n\t\tif strings.Index(paramParts[3], `\\x`) != -1 {\n\t\t\t// retries are hex encoded\n\t\t\tretries, err = strconv.ParseInt(strings.TrimPrefix(paramParts[3], `\\x`), 16, 64)\n\t\t} else if strings.Index(paramParts[3], `\\U`) != -1 {\n\t\t\t// retries are a unicode string\n\t\t\tretries, err = strconv.ParseInt(strings.TrimPrefix(paramParts[3], `\\U`), 16, 64)\n\t\t} else if strings.Index(paramParts[3], `\\`) == 0 {\n\t\t\t// retries is printed as a C-escape\n\t\t\tif len(paramParts[3]) != 2 {\n\t\t\t\terr = fmt.Errorf(\"expected retries (%s) to be an escape sequence\", paramParts[3])\n\t\t\t} else {\n\t\t\t\tescapeCodes := map[byte]int64{\n\t\t\t\t\tbyte('a'): 7,\n\t\t\t\t\tbyte('b'): 8,\n\t\t\t\t\tbyte('t'): 9,\n\t\t\t\t\tbyte('n'): 10,\n\t\t\t\t\tbyte('v'): 11,\n\t\t\t\t\tbyte('f'): 12,\n\t\t\t\t\tbyte('r'): 13,\n\t\t\t\t}\n\t\t\t\tvar ok bool\n\t\t\t\tif retries, ok = escapeCodes[(paramParts[3])[1]]; !ok {\n\t\t\t\t\terr = fmt.Errorf(\"got an invalid escape sequence: %s\", paramParts[3])\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tretries = int64((paramParts[3])[0])\n\t\t}\n\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"[%s] config.Retries err = %v\", paramParts[3], err)\n\t\t} else {\n\t\t\tconfig.Retries = int(retries)\n\t\t}\n\n\t\tvar testType string\n\t\tif len(config.Test) > 0 {\n\t\t\ttestType = config.Test[0]\n\t\t}\n\n\t\tswitch testType {\n\t\tcase \"NONE\":\n\t\t\tstrTest = \"NONE\"\n\t\tcase \"CMD\":\n\t\t\tif len(config.Test) == 1 {\n\t\t\t\tstrTest = \"CMD []\"\n\t\t\t} else {\n\t\t\t\tstrTest = fmt.Sprintf(`CMD [\"%s\"]`, strings.Join(config.Test[1:], `\", \"`))\n\t\t\t}\n\t\tcase \"CMD-SHELL\":\n\t\t\tcmdShell := strings.Join(config.Test[1:], \" \")\n\t\t\tstrTest = fmt.Sprintf(\"CMD %s\", cmdShell)\n\t\t\tconfig.Test = []string{config.Test[0], cmdShell}\n\t\t}\n\t}\n\n\tdefaultTimeout := false\n\tdefaultInterval := false\n\tdefaultRetries := false\n\tdefaultStartPeriod := false\n\n\tif config.Timeout == 0 {\n\t\tdefaultTimeout = true\n\t\tconfig.Timeout = 30 * time.Second\n\t}\n\tif config.Interval == 0 {\n\t\tdefaultInterval = true\n\t\tconfig.Interval = 30 * time.Second\n\t}\n\tif config.Retries == 0 {\n\t\tdefaultRetries = true\n\t\tconfig.Retries = 3\n\t}\n\tif config.StartPeriod == 0 {\n\t\tdefaultStartPeriod = true\n\t}\n\n\ttype HealthCheckFlag struct {\n\t\tflagFmtStr string\n\t\tisDefault  bool\n\t\tvalue      interface{}\n\t}\n\n\thealthInst := \"HEALTHCHECK\"\n\tfor _, flag := range []HealthCheckFlag{\n\t\t{flagFmtStr: \"--interval=%v\", isDefault: defaultInterval, value: config.Interval},\n\t\t{flagFmtStr: \"--timeout=%v\", isDefault: defaultTimeout, value: config.Timeout},\n\t\t{flagFmtStr: \"--start-period=%v\", isDefault: defaultStartPeriod, value: config.StartPeriod},\n\t\t{flagFmtStr: \"--retries=%d\", isDefault: defaultRetries, value: config.Retries},\n\t} {\n\t\tif !flag.isDefault {\n\t\t\thealthInst = healthInst + \" \" + fmt.Sprintf(flag.flagFmtStr, flag.value)\n\t\t}\n\t}\n\n\thealthInst += \" \" + strTest\n\tif strTest == \"NONE\" {\n\t\thealthInst = \"HEALTHCHECK NONE\"\n\t}\n\n\treturn healthInst, &config, nil\n}\n\n//\n// https://docs.docker.com/engine/reference/builder/\n//\n"
  },
  {
    "path": "pkg/docker/dockerfile/reverse/reverse_test.go",
    "content": "package reverse\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\tdockerclient \"github.com/fsouza/go-dockerclient\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestHealthCheck(t *testing.T) {\n\ttype TestData struct {\n\t\tinput                    string\n\t\treconstructedHealthcheck string\n\t\texpectedHealthConf       dockerclient.HealthConfig\n\t}\n\n\ttestHealthCheckData := []TestData{\n\t\t{\n\t\t\tinput:                    `HEALTHCHECK &{[\"CMD\" \"curl\" \"--fail-with-body\" \"127.0.0.1:5000\"] \"15s\" \"1s\" \"20s\" '\\x0A'}`,\n\t\t\treconstructedHealthcheck: `HEALTHCHECK --interval=15s --timeout=1s --start-period=20s --retries=10 CMD [\"curl\", \"--fail-with-body\", \"127.0.0.1:5000\"]`,\n\t\t\texpectedHealthConf: dockerclient.HealthConfig{\n\t\t\t\tInterval:    15 * time.Second,\n\t\t\t\tTimeout:     1 * time.Second,\n\t\t\t\tStartPeriod: 20 * time.Second,\n\t\t\t\tRetries:     10,\n\t\t\t\tTest:        []string{\"CMD\", \"curl\", \"--fail-with-body\", \"127.0.0.1:5000\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput:                    `HEALTHCHECK &{[\"CMD-SHELL\" \"cat /etc/resolv.conf\"] \"20s\" \"10s\" \"5s\" '\\x02'}`,\n\t\t\treconstructedHealthcheck: \"HEALTHCHECK --interval=20s --timeout=10s --start-period=5s --retries=2 CMD cat /etc/resolv.conf\",\n\t\t\texpectedHealthConf: dockerclient.HealthConfig{\n\t\t\t\tInterval:    20 * time.Second,\n\t\t\t\tTimeout:     10 * time.Second,\n\t\t\t\tStartPeriod: 5 * time.Second,\n\t\t\t\tRetries:     2,\n\t\t\t\tTest:        []string{\"CMD-SHELL\", \"cat /etc/resolv.conf\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput:                    `HEALTHCHECK &{[\"CMD-SHELL\" \"/opt/up-yet.sh\"] \"0s\" \"0s\" \"0s\" '\\x00'}`,\n\t\t\treconstructedHealthcheck: \"HEALTHCHECK CMD /opt/up-yet.sh\",\n\t\t\texpectedHealthConf: dockerclient.HealthConfig{\n\t\t\t\tTest:        []string{\"CMD-SHELL\", \"/opt/up-yet.sh\"},\n\t\t\t\tInterval:    30 * time.Second,\n\t\t\t\tTimeout:     30 * time.Second,\n\t\t\t\tStartPeriod: 0 * time.Second,\n\t\t\t\tRetries:     3,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput:                    `HEALTHCHECK &{[\"CMD\" \"cat\" \"/etc/resolv.conf\"] \"0s\" \"0s\" \"0s\" '!'}`,\n\t\t\treconstructedHealthcheck: `HEALTHCHECK --retries=33 CMD [\"cat\", \"/etc/resolv.conf\"]`,\n\t\t\texpectedHealthConf: dockerclient.HealthConfig{\n\t\t\t\tTest:        []string{\"CMD\", \"cat\", \"/etc/resolv.conf\"},\n\t\t\t\tInterval:    30 * time.Second,\n\t\t\t\tTimeout:     30 * time.Second,\n\t\t\t\tStartPeriod: 0 * time.Second,\n\t\t\t\tRetries:     33,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput:                    `HEALTHCHECK &{[\"CMD-SHELL\" \"ss -tulpn|grep 22\"] \"2s\" \"0s\" \"0s\" '\\U00051615'}`,\n\t\t\treconstructedHealthcheck: `HEALTHCHECK --interval=2s --retries=333333 CMD ss -tulpn|grep 22`,\n\t\t\texpectedHealthConf: dockerclient.HealthConfig{\n\t\t\t\tTest:        []string{\"CMD-SHELL\", \"ss -tulpn|grep 22\"},\n\t\t\t\tInterval:    2 * time.Second,\n\t\t\t\tTimeout:     30 * time.Second,\n\t\t\t\tStartPeriod: 0 * time.Second,\n\t\t\t\tRetries:     333333,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tinput:                    `HEALTHCHECK &{[\"CMD\" \"/bin/uptime\"] \"0s\" \"1h23m20s\" \"0s\" '\\n'}`,\n\t\t\treconstructedHealthcheck: `HEALTHCHECK --timeout=1h23m20s --retries=10 CMD [\"/bin/uptime\"]`,\n\t\t\texpectedHealthConf: dockerclient.HealthConfig{\n\t\t\t\tTest:        []string{\"CMD\", \"/bin/uptime\"},\n\t\t\t\tInterval:    30 * time.Second,\n\t\t\t\tTimeout:     5000 * time.Second,\n\t\t\t\tStartPeriod: 0 * time.Second,\n\t\t\t\tRetries:     10,\n\t\t\t},\n\t\t},\n\t}\n\n\tfor retries := 1; retries <= 31; retries++ {\n\t\ttestHealthCheckData = append(testHealthCheckData, TestData{\n\t\t\tinput:                    fmt.Sprintf(`HEALTHCHECK &{[\"CMD\" \"/bin/uptime\"] \"0s\" \"1h23m20s\" \"0s\" '%q'}`, retries),\n\t\t\treconstructedHealthcheck: fmt.Sprintf(`HEALTHCHECK --timeout=1h23m20s --retries=%d CMD [\"/bin/uptime\"]`, retries),\n\t\t\texpectedHealthConf: dockerclient.HealthConfig{\n\t\t\t\tTest:        []string{\"CMD\", \"/bin/uptime\"},\n\t\t\t\tInterval:    30 * time.Second,\n\t\t\t\tTimeout:     5000 * time.Second,\n\t\t\t\tStartPeriod: 0 * time.Second,\n\t\t\t\tRetries:     retries,\n\t\t\t},\n\t\t})\n\t}\n\n\tfor _, testData := range testHealthCheckData {\n\t\tres, healthConf, err := deserialiseHealtheckInstruction(testData.input)\n\t\trequire.NoError(t, err, \"No error should occur\")\n\t\tassert.Equal(t, &testData.expectedHealthConf, healthConf)\n\t\tassert.Equal(t, testData.reconstructedHealthcheck, res)\n\t}\n}\n"
  },
  {
    "path": "pkg/docker/dockerfile/spec/spec.go",
    "content": "// Package spec describes the Dockerfile data model.\npackage spec\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\ntype ParentImage struct {\n\tName           string      `json:\"name,omitempty\"`\n\tTag            string      `json:\"tag,omitempty\"`\n\tDigest         string      `json:\"digest,omitempty\"`\n\tBuildArgAll    string      `json:\"-\"`\n\tBuildArgName   string      `json:\"-\"`\n\tBuildArgTag    string      `json:\"-\"`\n\tBuildArgDigest string      `json:\"-\"`\n\tHasEmptyName   bool        `json:\"-\"`\n\tHasEmptyTag    bool        `json:\"-\"`\n\tHasEmptyDigest bool        `json:\"-\"`\n\tParentStage    *BuildStage `json:\"-\"`\n}\n\ntype BuildStage struct {\n\tIndex     int         `json:\"index\"`\n\tStartLine int         `json:\"start_line\"`\n\tEndLine   int         `json:\"end_line\"`\n\tName      string      `json:\"name,omitempty\"`\n\tParent    ParentImage `json:\"parent\"`\n\n\tAllInstructions           []*instruction.Field            `json:\"-\"`\n\tCurrentInstructions       []*instruction.Field            `json:\"-\"`\n\tOnBuildInstructions       []*instruction.Field            `json:\"-\"`\n\tUnknownInstructions       []*instruction.Field            `json:\"-\"`\n\tInvalidInstructions       []*instruction.Field            `json:\"-\"` //not including unknown instructions\n\tCurrentInstructionsByType map[string][]*instruction.Field `json:\"-\"`\n\tFromInstruction           *instruction.Field              `json:\"-\"`\n\tArgInstructions           []*instruction.Field            `json:\"-\"`\n\tEnvInstructions           []*instruction.Field            `json:\"-\"`\n\n\tEnvVars            map[string]string      `json:\"-\"`\n\tBuildArgs          map[string]string      `json:\"-\"`\n\tFromArgs           map[string]string      `json:\"-\"` //\"FROM\" ARGs used by the stage\n\tUnknownFromArgs    map[string]struct{}    `json:\"-\"`\n\tIsUsed             bool                   `json:\"-\"`\n\tStageReferences    map[string]*BuildStage `json:\"-\"`\n\tExternalReferences map[string]struct{}    `json:\"-\"`\n}\n\nfunc NewBuildStage() *BuildStage {\n\treturn &BuildStage{\n\t\tCurrentInstructionsByType: map[string][]*instruction.Field{},\n\t\tEnvVars:                   map[string]string{},\n\t\tBuildArgs:                 map[string]string{},\n\t\tFromArgs:                  map[string]string{},\n\t\tUnknownFromArgs:           map[string]struct{}{},\n\t\tStageReferences:           map[string]*BuildStage{},\n\t\tExternalReferences:        map[string]struct{}{},\n\t}\n}\n\ntype Dockerfile struct {\n\tName                  string\n\tLocation              string\n\tLines                 []string\n\tFromArgs              map[string]string //all \"FROM\" ARGs\n\tStages                []*BuildStage\n\tStagesByName          map[string]*BuildStage\n\tLastStage             *BuildStage\n\tStagelessInstructions []*instruction.Field\n\tArgInstructions       []*instruction.Field\n\tAllInstructions       []*instruction.Field\n\tInstructionsByType    map[string][]*instruction.Field\n\tUnknownInstructions   []*instruction.Field\n\tInvalidInstructions   []*instruction.Field //not including unknown instructions\n\tWarnings              []string\n}\n\nfunc NewDockerfile() *Dockerfile {\n\treturn &Dockerfile{\n\t\tFromArgs:           map[string]string{},\n\t\tStagesByName:       map[string]*BuildStage{},\n\t\tInstructionsByType: map[string][]*instruction.Field{},\n\t}\n}\n"
  },
  {
    "path": "pkg/docker/dockerignore/dockerignore.go",
    "content": "// Package dockerignore contains the code to deal with the .dockerignore files.\npackage dockerignore\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\t\"text/scanner\"\n)\n\nconst (\n\tfilename = \".dockerignore\"\n)\n\ntype Matcher struct {\n\tLocation string\n\tExists   bool\n\tPatterns []string\n}\n\nfunc (m *Matcher) Match(fpath string) (bool, error) {\n\t//Docker's dockerignore matching (including the '.' exception)\n\tpm, err := newPatternMatcher(m.Patterns)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tfpath = filepath.Clean(fpath)\n\n\tif fpath == \".\" {\n\t\treturn false, nil\n\t}\n\n\treturn pm.Matches(fpath)\n}\n\nfunc Load(location string) (*Matcher, error) {\n\tlocation = filepath.Clean(location)\n\tif _, err := os.Stat(location); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmatcher := &Matcher{\n\t\tLocation: location,\n\t}\n\n\tfpath := filepath.Join(location, filename)\n\tfo, err := os.Open(fpath)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn matcher, nil\n\t\t} else {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tdefer fo.Close()\n\n\tmatcher.Exists = true\n\tpatterns, err := readPatterns(fo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmatcher.Patterns = patterns\n\n\treturn matcher, nil\n}\n\nfunc readPatterns(reader io.Reader) ([]string, error) {\n\t// Docker's dockerignore function to read the patterns\n\tif reader == nil {\n\t\treturn nil, nil\n\t}\n\n\tscanner := bufio.NewScanner(reader)\n\tvar excludes []string\n\tcurrentLine := 0\n\n\tutf8bom := []byte{0xEF, 0xBB, 0xBF}\n\tfor scanner.Scan() {\n\t\tscannedBytes := scanner.Bytes()\n\t\t// We trim UTF8 BOM\n\t\tif currentLine == 0 {\n\t\t\tscannedBytes = bytes.TrimPrefix(scannedBytes, utf8bom)\n\t\t}\n\t\tpattern := string(scannedBytes)\n\t\tcurrentLine++\n\t\t// Lines starting with # (comments) are ignored before processing\n\t\tif strings.HasPrefix(pattern, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tpattern = strings.TrimSpace(pattern)\n\t\tif pattern == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\t// normalize absolute paths to paths relative to the context\n\t\t// (taking care of '!' prefix)\n\t\tinvert := pattern[0] == '!'\n\t\tif invert {\n\t\t\tpattern = strings.TrimSpace(pattern[1:])\n\t\t}\n\t\tif len(pattern) > 0 {\n\t\t\tpattern = filepath.Clean(pattern)\n\t\t\tpattern = filepath.ToSlash(pattern)\n\t\t\tif len(pattern) > 1 && pattern[0] == '/' {\n\t\t\t\tpattern = pattern[1:]\n\t\t\t}\n\t\t}\n\t\tif invert {\n\t\t\tpattern = \"!\" + pattern\n\t\t}\n\n\t\texcludes = append(excludes, pattern)\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, fmt.Errorf(\"Error reading .dockerignore: %v\", err)\n\t}\n\treturn excludes, nil\n}\n\n//Docker's pattern matching\n\ntype patternMatcher struct {\n\tpatterns   []*pattern\n\texclusions bool\n}\n\nfunc newPatternMatcher(patterns []string) (*patternMatcher, error) {\n\tpm := &patternMatcher{\n\t\tpatterns: make([]*pattern, 0, len(patterns)),\n\t}\n\tfor _, p := range patterns {\n\t\t// Eliminate leading and trailing whitespace.\n\t\tp = strings.TrimSpace(p)\n\t\tif p == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tp = filepath.Clean(p)\n\t\tnewp := &pattern{}\n\t\tif p[0] == '!' {\n\t\t\tif len(p) == 1 {\n\t\t\t\treturn nil, errors.New(\"illegal exclusion pattern: \\\"!\\\"\")\n\t\t\t}\n\t\t\tnewp.exclusion = true\n\t\t\tp = p[1:]\n\t\t\tpm.exclusions = true\n\t\t}\n\t\t// Do some syntax checking on the pattern.\n\t\t// filepath's Match() has some really weird rules that are inconsistent\n\t\t// so instead of trying to dup their logic, just call Match() for its\n\t\t// error state and if there is an error in the pattern return it.\n\t\t// If this becomes an issue we can remove this since its really only\n\t\t// needed in the error (syntax) case - which isn't really critical.\n\t\tif _, err := filepath.Match(p, \".\"); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnewp.cleanedPattern = p\n\t\tnewp.dirs = strings.Split(p, string(os.PathSeparator))\n\t\tpm.patterns = append(pm.patterns, newp)\n\t}\n\treturn pm, nil\n}\n\nfunc (pm *patternMatcher) Matches(file string) (bool, error) {\n\tmatched := false\n\tfile = filepath.FromSlash(file)\n\tparentPath := filepath.Dir(file)\n\tparentPathDirs := strings.Split(parentPath, string(os.PathSeparator))\n\n\tfor _, p := range pm.patterns {\n\t\tnegative := false\n\n\t\tif p.exclusion {\n\t\t\tnegative = true\n\t\t}\n\n\t\tmatch, err := p.match(file)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tif !match && parentPath != \".\" {\n\t\t\t// Check to see if the pattern matches one of our parent dirs.\n\t\t\tif len(p.dirs) <= len(parentPathDirs) {\n\t\t\t\tmatch, _ = p.match(strings.Join(parentPathDirs[:len(p.dirs)], string(os.PathSeparator)))\n\t\t\t}\n\t\t}\n\n\t\tif match {\n\t\t\tmatched = !negative\n\t\t}\n\t}\n\n\treturn matched, nil\n}\n\ntype pattern struct {\n\tcleanedPattern string\n\tdirs           []string\n\tregexp         *regexp.Regexp\n\texclusion      bool\n}\n\nfunc (p *pattern) match(path string) (bool, error) {\n\n\tif p.regexp == nil {\n\t\tif err := p.compile(); err != nil {\n\t\t\treturn false, filepath.ErrBadPattern\n\t\t}\n\t}\n\n\tb := p.regexp.MatchString(path)\n\n\treturn b, nil\n}\n\nfunc (p *pattern) compile() error {\n\tregStr := \"^\"\n\tpatternStr := p.cleanedPattern\n\t// Go through the pattern and convert it to a regexp.\n\t// We use a scanner so we can support utf-8 chars.\n\tvar scan scanner.Scanner\n\tscan.Init(strings.NewReader(patternStr))\n\n\tsl := string(os.PathSeparator)\n\tescSL := sl\n\tif sl == `\\` {\n\t\tescSL += `\\`\n\t}\n\n\tfor scan.Peek() != scanner.EOF {\n\t\tch := scan.Next()\n\n\t\tif ch == '*' {\n\t\t\tif scan.Peek() == '*' {\n\t\t\t\t// is some flavor of \"**\"\n\t\t\t\tscan.Next()\n\n\t\t\t\t// Treat **/ as ** so eat the \"/\"\n\t\t\t\tif string(scan.Peek()) == sl {\n\t\t\t\t\tscan.Next()\n\t\t\t\t}\n\n\t\t\t\tif scan.Peek() == scanner.EOF {\n\t\t\t\t\t// is \"**EOF\" - to align with .gitignore just accept all\n\t\t\t\t\tregStr += \".*\"\n\t\t\t\t} else {\n\t\t\t\t\t// is \"**\"\n\t\t\t\t\t// Note that this allows for any # of /'s (even 0) because\n\t\t\t\t\t// the .* will eat everything, even /'s\n\t\t\t\t\tregStr += \"(.*\" + escSL + \")?\"\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// is \"*\" so map it to anything but \"/\"\n\t\t\t\tregStr += \"[^\" + escSL + \"]*\"\n\t\t\t}\n\t\t} else if ch == '?' {\n\t\t\t// \"?\" is any char except \"/\"\n\t\t\tregStr += \"[^\" + escSL + \"]\"\n\t\t} else if ch == '.' || ch == '$' {\n\t\t\t// Escape some regexp special chars that have no meaning\n\t\t\t// in golang's filepath.Match\n\t\t\tregStr += `\\` + string(ch)\n\t\t} else if ch == '\\\\' {\n\t\t\t// escape next char. Note that a trailing \\ in the pattern\n\t\t\t// will be left alone (but need to escape it)\n\t\t\tif sl == `\\` {\n\t\t\t\t// On windows map \"\\\" to \"\\\\\", meaning an escaped backslash,\n\t\t\t\t// and then just continue because filepath.Match on\n\t\t\t\t// Windows doesn't allow escaping at all\n\t\t\t\tregStr += escSL\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif scan.Peek() != scanner.EOF {\n\t\t\t\tregStr += `\\` + string(scan.Next())\n\t\t\t} else {\n\t\t\t\tregStr += `\\`\n\t\t\t}\n\t\t} else {\n\t\t\tregStr += string(ch)\n\t\t}\n\t}\n\n\tregStr += \"$\"\n\n\tre, err := regexp.Compile(regStr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tp.regexp = re\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/docker/dockerimage/dockerimage.go",
    "content": "package dockerimage\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"container/heap\"\n\t\"crypto/sha1\"\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\"strings\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"github.com/bmatcuk/doublestar/v3\"\n\t\"github.com/dustin/go-humanize\"\n\toci \"github.com/opencontainers/image-spec/specs-go/v1\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/certdiscover\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerutil\"\n\t\"github.com/slimtoolkit/slim/pkg/sysidentity\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n\t\"github.com/slimtoolkit/slim/pkg/util/jsonutil\"\n)\n\nconst (\n\tdefaultTopObjectMax = 10\n)\n\ntype ImageFormatType string\n\nconst (\n\tFormatUnknown   ImageFormatType = \"unknown\"\n\tFormatDockerV1                  = \"docker.v1\"\n\tFormatDockerOCI                 = \"docker.oci\"\n\tFormatOCI                       = \"oci\"\n)\n\n// todo: rename 'Package' struct\ntype Package struct {\n\tFormat          ImageFormatType\n\tIsOCI           bool\n\tManifestOCI     *oci.Manifest\n\tManifest        *DockerManifestObject\n\tConfig          *ConfigObject\n\tLayers          []*Layer\n\tLayerIDRefs     map[string]*Layer\n\tHashReferences  map[string]map[string]*ObjectMetadata\n\tStats           PackageStats\n\tOSShells        map[string]*system.OSShell\n\tSpecialPermRefs SpecialPermsRefsInfo\n\tCerts           CertsRefInfo\n\tCACerts         CertsRefInfo\n\tIdentityData    *sysidentity.DataSet\n}\n\ntype CertsRefInfo struct {\n\tBundles         map[string]struct{} `json:\"bundles,omitempty\"`\n\tFiles           map[string]struct{} `json:\"files,omitempty\"`\n\tLinks           map[string]string   `json:\"links,omitempty\"`\n\tHashes          map[string]string   `json:\"hashes,omitempty\"`\n\tPrivateKeys     map[string]struct{} `json:\"private_keys,omitempty\"`\n\tPrivateKeyLinks map[string]string   `json:\"private_key_links,omitempty\"`\n}\n\ntype CertsInfo struct {\n\tBundles         []string          `json:\"bundles,omitempty\"`\n\tFiles           []string          `json:\"files,omitempty\"`\n\tLinks           map[string]string `json:\"links,omitempty\"`\n\tHashes          map[string]string `json:\"hashes,omitempty\"`\n\tPrivateKeys     []string          `json:\"private_keys,omitempty\"`\n\tPrivateKeyLinks map[string]string `json:\"private_key_links,omitempty\"`\n}\n\ntype SpecialPermsRefsInfo struct {\n\tSetuid map[string]*ObjectMetadata\n\tSetgid map[string]*ObjectMetadata\n\tSticky map[string]*ObjectMetadata\n}\n\ntype SpecialPermsInfo struct {\n\tSetuid []string `json:\"setuid,omitempty\"`\n\tSetgid []string `json:\"setgid,omitempty\"`\n\tSticky []string `json:\"sticky,omitempty\"`\n}\n\ntype ImageReport struct {\n\tStats        PackageStats                     `json:\"stats\"`\n\tDuplicates   map[string]*DuplicateFilesReport `json:\"duplicates,omitempty\"`\n\tSpecialPerms *SpecialPermsInfo                `json:\"special_perms,omitempty\"`\n\tOSShells     []*system.OSShell                `json:\"shells,omitempty\"`\n\tCerts        CertsInfo                        `json:\"certs\"`\n\tCACerts      CertsInfo                        `json:\"ca_certs\"`\n\tBuildInfo    *BuildKitBuildInfo               `json:\"build_info,omitempty\"`\n\tIdentities   *sysidentity.Report              `json:\"identities,omitempty\"`\n}\n\ntype DuplicateFilesReport struct {\n\tFileCount   uint64         `json:\"file_count\"`\n\tFileSize    uint64         `json:\"file_size\"`\n\tAllFileSize uint64         `json:\"all_file_size\"`\n\tWastedSize  uint64         `json:\"wasted_size\"`\n\tFiles       map[string]int `json:\"files\"`\n}\n\ntype LayerReport struct {\n\tID                  string                `json:\"id\"`\n\tIndex               int                   `json:\"index\"`\n\tPath                string                `json:\"path,omitempty\"`\n\tLayerDataSource     string                `json:\"layer_data_source,omitempty\"`\n\tMetadataChangesOnly bool                  `json:\"metadata_changes_only,omitempty\"`\n\tFSDiffID            string                `json:\"fsdiff_id,omitempty\"`\n\tStats               LayerStats            `json:\"stats\"`\n\tChanges             ChangesetSummary      `json:\"changes\"`\n\tTop                 []*ObjectMetadata     `json:\"top\"`\n\tDeleted             []*ObjectMetadata     `json:\"deleted,omitempty\"`\n\tAdded               []*ObjectMetadata     `json:\"added,omitempty\"`\n\tModified            []*ObjectMetadata     `json:\"modified,omitempty\"`\n\tChangeInstruction   *InstructionSummary   `json:\"change_instruction,omitempty\"`\n\tOtherInstructions   []*InstructionSummary `json:\"other_instructions,omitempty\"`\n}\n\ntype InstructionSummary struct {\n\tIndex      int    `json:\"index\"`\n\tImageIndex int    `json:\"image_index\"`\n\tType       string `json:\"type\"`\n\tAll        string `json:\"all\"`\n\tSnippet    string `json:\"snippet\"`\n}\n\ntype ChangesetSummary struct {\n\tDeleted  uint64 `json:\"deleted\"`\n\tAdded    uint64 `json:\"added\"`\n\tModified uint64 `json:\"modified\"`\n}\n\ntype Layer struct {\n\tID                  string\n\tIndex               int\n\tPath                string\n\tLayerDataSource     string\n\tMetadataChangesOnly bool\n\tFSDiffID            string\n\tStats               LayerStats\n\tChanges             Changeset\n\tObjects             []*ObjectMetadata\n\tReferences          map[string]*ObjectMetadata\n\tTop                 TopObjects\n\tDistro              *system.DistroInfo\n\tDataMatches         map[string][]*ChangeDataMatcher   //object.Name -> matched CDM\n\tDataHashMatches     map[string]*ChangeDataHashMatcher //object.Name -> matched CDHM\n\tpathMatches         bool\n}\n\nfunc (ref *Layer) HasMatches() bool {\n\tif len(ref.DataMatches) > 0 {\n\t\treturn true\n\t}\n\n\tif len(ref.DataHashMatches) > 0 {\n\t\treturn true\n\t}\n\n\tif ref.pathMatches {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\ntype LayerStats struct {\n\t//BlobSize         uint64 `json:\"blob_size\"`\n\tAllSize                uint64 `json:\"all_size\"`\n\tObjectCount            uint64 `json:\"object_count\"`\n\tDirCount               uint64 `json:\"dir_count\"`\n\tFileCount              uint64 `json:\"file_count\"`\n\tLinkCount              uint64 `json:\"link_count\"`\n\tMaxFileSize            uint64 `json:\"max_file_size\"`\n\tMaxDirSize             uint64 `json:\"max_dir_size\"`\n\tDeletedCount           uint64 `json:\"deleted_count\"`\n\tDeletedDirContentCount uint64 `json:\"deleted_dir_content_count\"`\n\tDeletedDirCount        uint64 `json:\"deleted_dir_count\"`\n\tDeletedFileCount       uint64 `json:\"deleted_file_count\"`\n\tDeletedLinkCount       uint64 `json:\"deleted_link_count\"`\n\tDeletedSize            uint64 `json:\"deleted_size\"`\n\tAddedSize              uint64 `json:\"added_size\"`\n\tModifiedSize           uint64 `json:\"modified_size\"`\n\tUTF8Count              uint64 `json:\"utf8_count,omitempty\"`\n\tUTF8Size               uint64 `json:\"utf8_size,omitempty\"`\n\tUTF8SizeHuman          string `json:\"utf8_size_human,omitempty\"`\n\tBinaryCount            uint64 `json:\"binary_count,omitempty\"`\n\tBinarySize             uint64 `json:\"binary_size,omitempty\"`\n\tBinarySizeHuman        string `json:\"binary_size_human,omitempty\"`\n\tSetuidCount            uint64 `json:\"setuid_count,omitempty\"`\n\tSetgidCount            uint64 `json:\"setgid_count,omitempty\"`\n\tStickyCount            uint64 `json:\"sticky_count,omitempty\"`\n}\n\ntype PackageStats struct {\n\tDuplicateFileCount      uint64 `json:\"duplicate_file_count\"`\n\tDuplicateFileTotalCount uint64 `json:\"duplicate_file_total_count\"`\n\tDuplicateFileSize       uint64 `json:\"duplicate_file_size\"`\n\tDuplicateFileTotalSize  uint64 `json:\"duplicate_file_total_size\"`\n\tDuplicateFileWastedSize uint64 `json:\"duplicate_file_wasted_size\"`\n\tDeletedCount            uint64 `json:\"deleted_count\"`\n\tDeletedDirContentCount  uint64 `json:\"deleted_dir_content_count\"`\n\tDeletedDirCount         uint64 `json:\"deleted_dir_count\"`\n\tDeletedFileCount        uint64 `json:\"deleted_file_count\"`\n\tDeletedLinkCount        uint64 `json:\"deleted_link_count\"`\n\tDeletedFileSize         uint64 `json:\"deleted_file_size\"`\n\tUTF8Count               uint64 `json:\"utf8_count,omitempty\"`\n\tUTF8Size                uint64 `json:\"utf8_size,omitempty\"`\n\tUTF8SizeHuman           string `json:\"utf8_size_human,omitempty\"`\n\tBinaryCount             uint64 `json:\"binary_count,omitempty\"`\n\tBinarySize              uint64 `json:\"binary_size,omitempty\"`\n\tBinarySizeHuman         string `json:\"binary_size_human,omitempty\"`\n\tSetuidCount             uint64 `json:\"setuid_count,omitempty\"`\n\tSetgidCount             uint64 `json:\"setgid_count,omitempty\"`\n\tStickyCount             uint64 `json:\"sticky_count,omitempty\"`\n}\n\ntype ChangeType int\n\nconst (\n\tChangeUnknown ChangeType = iota\n\tChangeDelete\n\tChangeAdd\n\tChangeModify\n)\n\nvar changeTypeToStrings = map[ChangeType]string{\n\tChangeUnknown: \"U\",\n\tChangeDelete:  \"D\",\n\tChangeAdd:     \"A\",\n\tChangeModify:  \"M\",\n}\n\nvar changeTypeFromStrings = map[string]ChangeType{\n\t\"U\": ChangeUnknown,\n\t\"D\": ChangeDelete,\n\t\"A\": ChangeAdd,\n\t\"M\": ChangeModify,\n}\n\nconst CDMDumpToConsole = \"console\"\n\ntype ChangeDataMatcher struct {\n\tDump        bool\n\tDumpConsole bool\n\tDumpDir     string\n\tPathPattern string\n\tDataPattern string\n\tMatcher     *regexp.Regexp\n}\n\ntype ChangeDataHashMatcher struct {\n\tDump        bool\n\tDumpConsole bool\n\tDumpDir     string\n\tHash        string //lowercase\n}\n\ntype ChangePathMatcher struct {\n\tDump        bool\n\tDumpConsole bool\n\tDumpDir     string\n\tPathPattern string\n}\n\ntype UTF8Detector struct {\n\tDump         bool\n\tDumpConsole  bool\n\tDumpDir      string\n\tDumpArchive  string\n\tMaxSizeBytes int\n\tArchive      *TarWriter\n\tFilters      []UTF8DetectorMatcher\n}\n\ntype UTF8DetectorMatcher struct {\n\tPathPattern string\n\tDataPattern string\n\tMatcher     *regexp.Regexp\n}\n\ntype TarWriter struct {\n\tfile       *os.File\n\tbufferGzip *gzip.Writer\n\tWriter     *tar.Writer\n}\n\nfunc NewTarWriter(name string) (*TarWriter, error) {\n\tfile, err := os.Create(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbufferGzip := gzip.NewWriter(file)\n\twriter := tar.NewWriter(bufferGzip)\n\n\ttw := &TarWriter{\n\t\tfile:       file,\n\t\tbufferGzip: bufferGzip,\n\t\tWriter:     writer,\n\t}\n\n\treturn tw, nil\n}\n\nfunc (w *TarWriter) Close() error {\n\tif err := w.Writer.Close(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := w.bufferGzip.Close(); err != nil {\n\t\treturn err\n\t}\n\n\tif err := w.file.Close(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (d *UTF8Detector) Close() error {\n\tif d.Archive != nil {\n\t\treturn d.Archive.Close()\n\t}\n\n\treturn nil\n}\n\nfunc (ct ChangeType) String() string {\n\tif v, ok := changeTypeToStrings[ct]; ok {\n\t\treturn v\n\t}\n\n\treturn \"U\"\n}\n\nfunc (ct ChangeType) MarshalJSON() ([]byte, error) {\n\tv, ok := changeTypeToStrings[ct]\n\tif !ok {\n\t\tv = \"O\"\n\t}\n\n\td := bytes.NewBufferString(`\"`)\n\td.WriteString(v)\n\td.WriteString(`\"`)\n\n\treturn d.Bytes(), nil\n}\n\nfunc (ct *ChangeType) UnmarshalJSON(b []byte) error {\n\tvar d string\n\terr := json.Unmarshal(b, &d)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif v, ok := changeTypeFromStrings[d]; ok {\n\t\t*ct = v\n\t} else {\n\t\t*ct = ChangeUnknown\n\t}\n\n\treturn nil\n}\n\nconst (\n\tContentTypeUTF8   = \"utf8\"\n\tContentTypeBinary = \"binary\"\n)\n\ntype ObjectMetadata struct {\n\tChange           ChangeType     `json:\"change\"`\n\tDirContentDelete bool           `json:\"dir_content_delete,omitempty\"`\n\tName             string         `json:\"name\"`\n\tSize             int64          `json:\"size,omitempty\"`\n\tSizeHuman        string         `json:\"size_human,omitempty\"`\n\tMode             os.FileMode    `json:\"mode,omitempty\"`\n\tModeHuman        string         `json:\"mode_human,omitempty\"`\n\tUID              int            `json:\"uid\"` //don't omit uid 0\n\tGID              int            `json:\"gid\"` //don't omit gid 0\n\tModTime          time.Time      `json:\"mod_time,omitempty\"`\n\tChangeTime       time.Time      `json:\"change_time,omitempty\"`\n\tLinkTarget       string         `json:\"link_target,omitempty\"`\n\tHistory          *ObjectHistory `json:\"history,omitempty\"`\n\tHash             string         `json:\"hash,omitempty\"`\n\tPathMatch        bool           `json:\"-\"`\n\tLayerIndex       int            `json:\"-\"`\n\tTypeFlag         byte           `json:\"-\"`\n\tType             string         `json:\"type\"`\n\tContentType      string         `json:\"content_type,omitempty\"`\n}\n\ntype ObjectHistory struct {\n\tAdd      *ChangeInfo   `json:\"A,omitempty\"`\n\tModifies []*ChangeInfo `json:\"M,omitempty\"`\n\tDelete   *ChangeInfo   `json:\"D,omitempty\"`\n}\n\ntype ChangeInfo struct {\n\tLayer  int             `json:\"layer\"`\n\tObject *ObjectMetadata `json:\"-\"`\n}\n\ntype Changeset struct {\n\tDeleted           []int\n\tDeletedDirContent []int\n\tAdded             []int\n\tModified          []int\n}\n\nfunc newPackage() *Package {\n\tpkg := Package{\n\t\tFormat:         FormatUnknown,\n\t\tLayerIDRefs:    map[string]*Layer{},\n\t\tHashReferences: map[string]map[string]*ObjectMetadata{},\n\t\tOSShells:       map[string]*system.OSShell{},\n\t\tSpecialPermRefs: SpecialPermsRefsInfo{\n\t\t\tSetuid: map[string]*ObjectMetadata{},\n\t\t\tSetgid: map[string]*ObjectMetadata{},\n\t\t\tSticky: map[string]*ObjectMetadata{},\n\t\t},\n\t\tCerts: CertsRefInfo{\n\t\t\tBundles:         map[string]struct{}{},\n\t\t\tFiles:           map[string]struct{}{},\n\t\t\tLinks:           map[string]string{},\n\t\t\tHashes:          map[string]string{},\n\t\t\tPrivateKeys:     map[string]struct{}{},\n\t\t\tPrivateKeyLinks: map[string]string{},\n\t\t},\n\t\tCACerts: CertsRefInfo{\n\t\t\tBundles:         map[string]struct{}{},\n\t\t\tFiles:           map[string]struct{}{},\n\t\t\tLinks:           map[string]string{},\n\t\t\tHashes:          map[string]string{},\n\t\t\tPrivateKeys:     map[string]struct{}{},\n\t\t\tPrivateKeyLinks: map[string]string{},\n\t\t},\n\t\tIdentityData: sysidentity.NewDataSet(),\n\t}\n\n\treturn &pkg\n}\n\nfunc newLayer(id string, topChangesMax int) *Layer {\n\ttopChangesCount := defaultTopObjectMax\n\tif topChangesMax > -1 {\n\t\ttopChangesCount = topChangesMax\n\t}\n\n\tlayer := Layer{\n\t\tID:              id,\n\t\tIndex:           -1,\n\t\tReferences:      map[string]*ObjectMetadata{},\n\t\tTop:             NewTopObjects(topChangesCount),\n\t\tDataMatches:     map[string][]*ChangeDataMatcher{},\n\t\tDataHashMatches: map[string]*ChangeDataHashMatcher{},\n\t}\n\n\theap.Init(&(layer.Top))\n\n\treturn &layer\n}\n\n//todo: refactor, so we don't have duplicated structures\n\ntype DetectOpParam struct {\n\t/// Operation is enabled\n\tEnabled bool\n\t/// Dump/save raw data\n\tDumpRaw bool\n\t/// Dump raw data to console\n\tIsConsoleOut bool\n\t/// Dump raw data to directory (otherwise save to an archive file)\n\tIsDirOut bool\n\t/// Output path (directory or archive path)\n\tOutputPath string\n\t/// Input parameters for the operation\n\tInputParams map[string]string\n}\n\n// todo: add other processor params (passed separately for now)\ntype ProcessorParams struct {\n\tDetectIdentities     *DetectOpParam\n\tDetectScheduledTasks *DetectOpParam\n\tDetectServices       *DetectOpParam\n\tDetectSystemHooks    *DetectOpParam\n\n\tDetectAllCertFiles   bool\n\tDetectAllCertPKFiles bool\n}\n\ntype LayerLocation struct {\n\tPosition int\n\tPath     string\n\tLayerID  string\n}\n\ntype LayerLocationSource string\n\nconst (\n\tDockerManifestLayersLocation = \"ll.dm.layers\"\n\tOCIImageManifestLocation     = \"ll.oci.imagemanifest\"\n)\n\nfunc LoadPackage(archivePath string,\n\timageID string,\n\tskipObjects bool,\n\ttopChangesMax int,\n\tdoHashData bool,\n\tdoDetectDuplicates bool,\n\tchangeDataHashMatchers map[string]*ChangeDataHashMatcher,\n\tchangePathMatchers []*ChangePathMatcher,\n\tchangeDataMatchers map[string]*ChangeDataMatcher,\n\tutf8Detector *UTF8Detector,\n\tprocessorParams *ProcessorParams,\n) (*Package, error) {\n\timageID = dockerutil.CleanImageID(imageID)\n\n\tcpmDumps := hasChangePathMatcherDumps(changePathMatchers)\n\tdv1ConfigObjectFileName := fmt.Sprintf(\"%s.json\", imageID)\n\tafile, err := os.Open(archivePath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerimage.LoadPackage: os.Open error - %v\", err)\n\t\treturn nil, err\n\t}\n\n\tdefer afile.Close()\n\n\tpkg := newPackage()\n\tlayers := map[string]*Layer{}\n\n\tarchiveFiles := map[string]struct{}{}\n\tvar tarFileCount uint\n\tvar foundOCILayout bool\n\tvar foundBlobsDir bool\n\tvar foundIndex bool\n\tvar foundDockerManifest bool\n\tvar foundDockerV1Config bool\n\tvar foundDockerV1Layer bool\n\tvar ociImageManifestDesc *oci.Descriptor\n\n\ttr := tar.NewReader(afile)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err != nil {\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading archive(%v) enumerating files - %v\", archivePath, err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\ttarFileCount++\n\t\tif hdr == nil || hdr.Name == \"\" {\n\t\t\tlog.Debugf(\"dockerimage.LoadPackage: ignoring bad tar header (%d)\", tarFileCount)\n\t\t\tcontinue\n\t\t}\n\n\t\thdr.Name = filepath.Clean(hdr.Name)\n\t\tarchiveFiles[hdr.Name] = struct{}{}\n\t\tif hdr.Name == ociBlobDirName ||\n\t\t\tstrings.HasPrefix(hdr.Name, ociBlobDirPrefix) {\n\t\t\tfoundBlobsDir = true\n\t\t}\n\n\t\tswitch {\n\t\tcase hdr.Name == ociLayoutFileName:\n\t\t\tvar ociLayout OCILayout\n\t\t\tif err := jsonFromStream(archivePath, hdr.Name, tr, &ociLayout); err != nil {\n\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: error reading oci-layout from archive(%v/%v) - %v\", archivePath, ociLayoutFileName, err)\n\t\t\t\t//not erroring right away (ok if we don't have a good oci layout if the Docker Manifest info is still there)\n\t\t\t} else {\n\t\t\t\tif ociLayout.Version != ociLayoutVersion {\n\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: unexpected version in oci-layout from archive(%v/%v) - %#v\", archivePath, ociLayoutFileName, ociLayout)\n\t\t\t\t}\n\n\t\t\t\tfoundOCILayout = true\n\t\t\t}\n\n\t\tcase hdr.Name == ociIndexFileName:\n\t\t\tvar ociIndex oci.Index\n\t\t\tif err := jsonFromStream(archivePath, hdr.Name, tr, &ociIndex); err != nil {\n\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: error reading oci index from archive(%v/%v) - %v\", archivePath, ociIndexFileName, err)\n\t\t\t\t//not erroring right away (ok if we don't have a good oci index if the Docker Manifest info is still there)\n\t\t\t} else {\n\t\t\t\tif ociIndex.MediaType == oci.MediaTypeImageIndex {\n\t\t\t\t\t// Docker bug (ociIndex.Manifests is null when image is saved by ID, not by name)\n\t\t\t\t\tif len(ociIndex.Manifests) != 0 {\n\t\t\t\t\t\t// picking the first usable manifest descriptor (for now)\n\t\t\t\t\t\t// make it selectable later\n\t\t\t\t\t\tfor _, md := range ociIndex.Manifests {\n\t\t\t\t\t\t\tmd := md\n\t\t\t\t\t\t\tif md.MediaType == oci.MediaTypeImageManifest &&\n\t\t\t\t\t\t\t\tmd.Platform != nil &&\n\t\t\t\t\t\t\t\tmd.Platform.OS == DefaultOS &&\n\t\t\t\t\t\t\t\tmd.Platform.Architecture == DefaultRuntimeArch() {\n\t\t\t\t\t\t\t\tociImageManifestDesc = &md\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ociImageManifestDesc == nil {\n\t\t\t\t\t\t\tfor _, md := range ociIndex.Manifests {\n\t\t\t\t\t\t\t\tmd := md\n\t\t\t\t\t\t\t\tif md.MediaType == oci.MediaTypeImageManifest &&\n\t\t\t\t\t\t\t\t\tmd.Platform != nil &&\n\t\t\t\t\t\t\t\t\tmd.Platform.OS == DefaultOS {\n\t\t\t\t\t\t\t\t\tociImageManifestDesc = &md\n\t\t\t\t\t\t\t\t\tbreak\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\n\t\t\t\t\t\tif ociImageManifestDesc == nil {\n\t\t\t\t\t\t\tfor _, md := range ociIndex.Manifests {\n\t\t\t\t\t\t\t\tmd := md\n\t\t\t\t\t\t\t\tif md.MediaType == oci.MediaTypeImageManifest {\n\t\t\t\t\t\t\t\t\tociImageManifestDesc = &md\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ociImageManifestDesc == nil {\n\t\t\t\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: oci index from archive(%s/%s) has no image manifest references - '%s'\",\n\t\t\t\t\t\t\t\t\tarchivePath, ociIndexFileName, jsonutil.ToString(ociIndex))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ociImageManifestDesc != nil {\n\t\t\t\t\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - OCI Index - found image manifest = '%#v'\",\n\t\t\t\t\t\t\t\tarchivePath,\n\t\t\t\t\t\t\t\tociImageManifestDesc)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//index file counts only if it's somewhat well structured\n\t\t\t\t\t\tfoundIndex = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: malformed index file - no image manifests\")\n\t\t\t\t\t\t//still ok if the Docker Manifest file has the data we need\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlog.Tracef(\"dockerimage.LoadPackage: oci index from archive(%v/%v) [found oci image manifest desc - '%v'] = %s\",\n\t\t\t\tarchivePath, ociIndexFileName, ociImageManifestDesc != nil, jsonutil.ToString(ociIndex))\n\n\t\tcase hdr.Name == dockerManifestFileName:\n\t\t\tvar manifests []DockerManifestObject\n\t\t\tif err := jsonFromStream(archivePath, hdr.Name, tr, &manifests); err != nil {\n\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: error reading manifest file from archive(%v/%v) - %v\",\n\t\t\t\t\tarchivePath, dockerManifestFileName, err)\n\t\t\t\t//not erroring right away (ok if we don't have a good Docker Manifest if the OCI Index and OCI Image Manifest info is still there)\n\t\t\t} else {\n\t\t\t\tif len(manifests) != 0 {\n\t\t\t\t\tpkg.Manifest = &manifests[0]\n\t\t\t\t\t/*\n\t\t\t\t\t\tTODO: REFACTOR\n\t\t\t\t\t\tuse either v1 config name\n\t\t\t\t\t\tor the config name from the OCI manifest\n\n\t\t\t\t\t\tfor _, m := range manifests {\n\t\t\t\t\t\t\tif m.Config == dv1ConfigObjectFileName {\n\t\t\t\t\t\t\t\tmanifest := m\n\t\t\t\t\t\t\t\tpkg.Manifest = &manifest\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t*/\n\n\t\t\t\t\tfoundDockerManifest = true\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: malformed manifest file - no manifests\")\n\t\t\t\t\t//still ok if we have the OCI image manifest (referenced in the OCI index)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlog.Tracef(\"dockerimage.LoadPackage: Docker manifest from archive(%v/%v) = %s\",\n\t\t\t\tarchivePath, dockerManifestFileName, jsonutil.ToString(manifests))\n\n\t\tcase hdr.Name == dv1ConfigObjectFileName:\n\t\t\tvar imageConfig ConfigObject\n\t\t\tif err := jsonFromStream(archivePath, hdr.Name, tr, &imageConfig); err != nil {\n\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading config object from archive(%v/%v) - %v\", archivePath, dv1ConfigObjectFileName, err)\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif imageConfig.BuildInfoRaw != \"\" {\n\t\t\t\timageConfig.BuildInfoDecoded, err = buildInfoDecode(imageConfig.BuildInfoRaw)\n\t\t\t}\n\n\t\t\tpkg.Config = &imageConfig\n\t\t\tfoundDockerV1Config = true\n\n\t\tcase strings.HasSuffix(hdr.Name, dockerV1LayerSuffix):\n\t\t\tfoundDockerV1Layer = true\n\t\t}\n\t}\n\n\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - tfc=%d, archiveFiles=%d [dm=%v/dv1config=%v/dv1layer=%v/ocilayout=%v/ociindex=%v/ociblobs=%v]\",\n\t\tarchivePath,\n\t\ttarFileCount,\n\t\tlen(archiveFiles),\n\t\tfoundDockerManifest,\n\t\tfoundDockerV1Config,\n\t\tfoundDockerV1Layer,\n\t\tfoundOCILayout,\n\t\tfoundIndex,\n\t\tfoundBlobsDir)\n\n\tif foundOCILayout &&\n\t\tfoundBlobsDir &&\n\t\tfoundIndex {\n\t\tif foundDockerManifest {\n\t\t\tpkg.Format = FormatDockerOCI\n\t\t\tpkg.IsOCI = true\n\t\t} else {\n\t\t\tpkg.Format = FormatOCI\n\t\t\tpkg.IsOCI = true\n\t\t}\n\t} else if foundDockerManifest &&\n\t\tfoundDockerV1Config {\n\t\tpkg.Format = FormatDockerV1\n\t}\n\n\tlog.Debugf(\"dockerimage.LoadPackage: pkg.Format=%s pkg.IsOCI=%v archive - (%s)\",\n\t\tpkg.Format, pkg.IsOCI, archivePath)\n\n\tvar configObjectFileName string\n\t//list of layer IDs based on their order in Docker Manifest or OCI Image Manifest\n\tvar layerSequence []LayerLocation\n\tvar ociLayerSequence []LayerLocation\n\tvar layerLocationSource LayerLocationSource\n\n\tlayerFileNames := map[string]struct{}{}\n\tociLayerFileNames := map[string]struct{}{}\n\tnonLayerFileNames := map[string]string{}\n\tif pkg.Manifest != nil {\n\t\tif pkg.Manifest.Config != \"\" &&\n\t\t\tpkg.Manifest.Config != dv1ConfigObjectFileName {\n\t\t\tconfigObjectFileName = pkg.Manifest.Config\n\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - DM - config object path = '%s'\", archivePath, configObjectFileName)\n\t\t}\n\n\t\tif len(pkg.Manifest.Layers) > 0 {\n\t\t\tlayerLocationSource = DockerManifestLayersLocation\n\n\t\t\tfor idx, layerPath := range pkg.Manifest.Layers {\n\t\t\t\tparts := strings.Split(layerPath, \"/\")\n\t\t\t\tvar layerID string\n\t\t\t\tif parts[0] == ociBlobDirName {\n\t\t\t\t\tlayerID = parts[2]\n\t\t\t\t} else {\n\t\t\t\t\tlayerID = parts[0]\n\t\t\t\t}\n\n\t\t\t\tlayerSequence = append(layerSequence, LayerLocation{\n\t\t\t\t\tPosition: idx,\n\t\t\t\t\tPath:     layerPath,\n\t\t\t\t\tLayerID:  layerID,\n\t\t\t\t})\n\n\t\t\t\tlayerFileNames[layerPath] = struct{}{}\n\t\t\t}\n\n\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - DM - layer paths [%d] = '%#v'\",\n\t\t\t\tarchivePath,\n\t\t\t\tlen(layerFileNames),\n\t\t\t\tlayerFileNames)\n\t\t} else {\n\t\t\t// todo: figure out the layer file names from pkg.Manifest.LayerSources\n\t\t}\n\t}\n\n\t// note: for a 'Docker OCI' image loading the OCI image manifest is not a \"must have\"\n\tvar ociImageManifestPath string\n\tif ociImageManifestDesc != nil &&\n\t\tociImageManifestDesc.Digest.String() != \"\" {\n\t\tparts := strings.Split(ociImageManifestDesc.Digest.String(), \":\")\n\t\tif len(parts) == 2 {\n\t\t\tociImageManifestPath = filepath.Join(ociBlobDirName, parts[0], parts[1])\n\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - found OCI image manifest path = '%s'\",\n\t\t\t\tarchivePath,\n\t\t\t\tociImageManifestPath)\n\n\t\t\tif _, found := archiveFiles[ociImageManifestPath]; !found {\n\t\t\t\t//show an error, but don't exit\n\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: malformed oci image manifest path from archive(%s) - %s\",\n\t\t\t\t\tarchivePath, ociImageManifestPath)\n\t\t\t\tociImageManifestPath = \"\"\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Errorf(\"dockerimage.LoadPackage: malformed oci image manifest digest from archive(%s) - %s\",\n\t\t\t\tarchivePath, ociImageManifestDesc.Digest.String())\n\t\t}\n\n\t\tafile.Seek(0, 0)\n\t\ttr = tar.NewReader(afile)\n\t\tfor {\n\t\t\thdr, err := tr.Next()\n\t\t\tif err != nil {\n\t\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading archive(%v) enumerating files - %v\", archivePath, err)\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif hdr == nil || hdr.Name == \"\" {\n\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: ignoring bad tar header (%d)\", tarFileCount)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\thdr.Name = filepath.Clean(hdr.Name)\n\n\t\t\tif configObjectFileName != \"\" &&\n\t\t\t\thdr.Name == configObjectFileName {\n\t\t\t\tvar imageConfig ConfigObject\n\t\t\t\tif err := jsonFromStream(archivePath, hdr.Name, tr, &imageConfig); err != nil {\n\t\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading config object from archive(%v/%v) - %v\", archivePath, configObjectFileName, err)\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t\tif imageConfig.BuildInfoRaw != \"\" {\n\t\t\t\t\timageConfig.BuildInfoDecoded, err = buildInfoDecode(imageConfig.BuildInfoRaw)\n\t\t\t\t}\n\n\t\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - loaded config object from path = '%s'\",\n\t\t\t\t\tarchivePath,\n\t\t\t\t\tconfigObjectFileName)\n\n\t\t\t\t//possible to have a v1 pkg.Config already\n\t\t\t\t//good to check if they are different\n\t\t\t\tpkg.Config = &imageConfig\n\t\t\t\tconfigObjectFileName = \"\"\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif pkg.ManifestOCI == nil &&\n\t\t\t\tociImageManifestPath != \"\" &&\n\t\t\t\thdr.Name == ociImageManifestPath {\n\t\t\t\tvar ociImageManifest oci.Manifest\n\t\t\t\tif err := jsonFromStream(archivePath, hdr.Name, tr, &ociImageManifest); err != nil {\n\t\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading oci image manifest from archive(%v/%v) - %v\", archivePath, ociImageManifestPath, err)\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - loaded OCI Image Manifest from path = '%s'\",\n\t\t\t\t\tarchivePath,\n\t\t\t\t\tociImageManifestPath)\n\n\t\t\t\tpkg.ManifestOCI = &ociImageManifest\n\t\t\t\tociImageManifestPath = \"\"\n\t\t\t}\n\n\t\t\tif configObjectFileName == \"\" && ociImageManifestPath == \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif pkg.ManifestOCI != nil &&\n\t\tpkg.ManifestOCI.Config.Digest.String() != \"\" {\n\t\t// when we don't have a Docker manifest\n\t\tparts := strings.Split(pkg.ManifestOCI.Config.Digest.String(), \":\")\n\t\tif len(parts) == 2 {\n\t\t\tociConfigObjectFileName := filepath.Join(ociBlobDirName, parts[0], parts[1])\n\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - config object path from OCI Image Manifest = '%s'\",\n\t\t\t\tarchivePath,\n\t\t\t\tociConfigObjectFileName)\n\n\t\t\tif _, found := archiveFiles[ociConfigObjectFileName]; !found {\n\t\t\t\t//show the error, but don't exit\n\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: malformed oci config object path from archive(%s) - %s\",\n\t\t\t\t\tarchivePath, ociConfigObjectFileName)\n\t\t\t\t//make it empty,so we don't attempt to extract the config again\n\t\t\t\tconfigObjectFileName = \"\"\n\t\t\t} else {\n\t\t\t\tif ociConfigObjectFileName != configObjectFileName {\n\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: config object path mismatch (OCI='%s' != DM='%s') from archive(%s)\",\n\t\t\t\t\t\tociConfigObjectFileName, configObjectFileName, archivePath)\n\t\t\t\t\t//make sure we fetch and save the OCI config\n\t\t\t\t\tconfigObjectFileName = ociConfigObjectFileName\n\t\t\t\t} else {\n\t\t\t\t\tconfigObjectFileName = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Errorf(\"dockerimage.LoadPackage: malformed oci config object digest from archive(%s) - %s\",\n\t\t\t\tarchivePath, pkg.ManifestOCI.Config.Digest.String())\n\t\t}\n\t}\n\n\tif pkg.ManifestOCI != nil {\n\t\t// get layers from oci image manifest\n\t\tfor idx, layerInfo := range pkg.ManifestOCI.Layers {\n\t\t\t// todo: add support for oci.MediaTypeImageLayerGzip and oci.MediaTypeImageLayerZstd\n\t\t\tif layerInfo.MediaType == oci.MediaTypeImageLayer &&\n\t\t\t\tlayerInfo.Digest.String() != \"\" {\n\t\t\t\tparts := strings.Split(layerInfo.Digest.String(), \":\")\n\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\tlayerFileName := filepath.Join(ociBlobDirName, parts[0], parts[1])\n\t\t\t\t\tif _, found := archiveFiles[layerFileName]; !found {\n\t\t\t\t\t\t//show error, but don't exit (exit if we have --strict-image-format)\n\t\t\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: malformed oci layer path from archive(%s) - %s\",\n\t\t\t\t\t\t\tarchivePath, layerFileName)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tociLayerSequence = append(ociLayerSequence, LayerLocation{\n\t\t\t\t\t\t\tPosition: idx,\n\t\t\t\t\t\t\tPath:     layerFileName,\n\t\t\t\t\t\t\tLayerID:  parts[1],\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tociLayerFileNames[layerFileName] = struct{}{}\n\n\t\t\t\t\t\t//cross reference the OCI layers with the Docker Manifest layers (if we have them)\n\n\t\t\t\t\t\tif len(layerFileNames) > 0 {\n\t\t\t\t\t\t\tif _, layerFound := layerFileNames[layerFileName]; !layerFound {\n\t\t\t\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: oci layer path (%s) should be known already - archive(%s)\",\n\t\t\t\t\t\t\t\t\tlayerFileName, archivePath)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif len(layerSequence) >= len(ociLayerSequence) {\n\t\t\t\t\t\t\tlsIdx := len(ociLayerSequence) - 1\n\t\t\t\t\t\t\tif layerSequence[lsIdx].Path != ociLayerSequence[lsIdx].Path ||\n\t\t\t\t\t\t\t\tlayerSequence[lsIdx].Position != ociLayerSequence[lsIdx].Position ||\n\t\t\t\t\t\t\t\tlayerSequence[lsIdx].LayerID != ociLayerSequence[lsIdx].LayerID {\n\t\t\t\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: layerFileName=%s / OCI layer and DM layer sequence record mismatch lsIdx=%d ('%+v' / '%+v') - archive(%s)\",\n\t\t\t\t\t\t\t\t\tlayerFileName, lsIdx, layerSequence[lsIdx], ociLayerSequence[lsIdx], archivePath)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: layerFileName=%s / OCI layer and DM layer sequence mismatch (%d / %d) - archive(%s)\",\n\t\t\t\t\t\t\t\tlayerFileName, len(layerSequence), len(ociLayerSequence), archivePath)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: malformed oci layer digest from archive(%s) - %s\",\n\t\t\t\t\t\tarchivePath, layerInfo.Digest.String())\n\t\t\t\t}\n\t\t\t} else if layerInfo.MediaType != oci.MediaTypeImageLayer {\n\t\t\t\tif layerInfo.Digest.String() != \"\" {\n\t\t\t\t\tparts := strings.Split(layerInfo.Digest.String(), \":\")\n\t\t\t\t\tif len(parts) == 2 {\n\t\t\t\t\t\tlayerFileName := filepath.Join(ociBlobDirName, parts[0], parts[1])\n\t\t\t\t\t\tnonLayerFileNames[layerFileName] = layerInfo.MediaType\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: malformed oci layer digest from archive(%s) - %s\",\n\t\t\t\t\t\t\tarchivePath, layerInfo.Digest.String())\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: non-image layer, no digest '%s' - archive(%s)\",\n\t\t\t\t\t\tjsonutil.ToString(layerInfo), archivePath)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// a 'simple' way to decide when to use the OCI layer metadata (todo: review later)\n\tif len(ociLayerFileNames) > len(layerFileNames) {\n\t\tlayerFileNames = ociLayerFileNames\n\t\tlayerSequence = ociLayerSequence\n\t\tlayerLocationSource = OCIImageManifestLocation\n\t}\n\n\t// now load the layers\n\tafile.Seek(0, 0)\n\ttr = tar.NewReader(afile)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading archive(%v) - %v\", archivePath, err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif hdr == nil || hdr.Name == \"\" {\n\t\t\tlog.Debugf(\"dockerimage.LoadPackage: ignoring bad tar header\")\n\t\t\tcontinue\n\t\t}\n\n\t\thdr.Name = filepath.Clean(hdr.Name)\n\t\tif configObjectFileName != \"\" &&\n\t\t\thdr.Name == configObjectFileName {\n\t\t\tvar imageConfig ConfigObject\n\t\t\tif err := jsonFromStream(archivePath, hdr.Name, tr, &imageConfig); err != nil {\n\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading oci config object from archive(%v/%v) - %v\", archivePath, configObjectFileName, err)\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif imageConfig.BuildInfoRaw != \"\" {\n\t\t\t\timageConfig.BuildInfoDecoded, err = buildInfoDecode(imageConfig.BuildInfoRaw)\n\t\t\t}\n\n\t\t\tlog.Tracef(\"dockerimage.LoadPackage: archive(%v) - loaded config object from path = '%s'\",\n\t\t\t\tarchivePath,\n\t\t\t\tconfigObjectFileName)\n\n\t\t\t//pkg.Config might alread point to a config (v1 or DM)\n\t\t\t//todo: check the difference\n\t\t\tpkg.Config = &imageConfig\n\t\t\tconfigObjectFileName = \"\"\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch hdr.Typeflag {\n\t\tcase tar.TypeReg, tar.TypeSymlink:\n\t\t\tswitch {\n\t\t\tcase strings.HasSuffix(hdr.Name, dockerV1LayerSuffix):\n\t\t\t\tparts := strings.Split(hdr.Name, \"/\")\n\t\t\t\tlayerID := parts[0]\n\n\t\t\t\tvar layer *Layer\n\t\t\t\tif hdr.Typeflag == tar.TypeSymlink {\n\t\t\t\t\tlayer = newLayer(layerID, topChangesMax)\n\t\t\t\t\tlayer.Path = hdr.Name\n\t\t\t\t\tlayer.MetadataChangesOnly = true\n\n\t\t\t\t\tparts := strings.Split(hdr.Linkname, \"/\")\n\t\t\t\t\tif len(parts) == 3 && parts[2] == \"layer.tar\" {\n\t\t\t\t\t\tlayer.LayerDataSource = parts[1]\n\n\t\t\t\t\t\tif srcLayer, ok := layers[layer.LayerDataSource]; ok {\n\t\t\t\t\t\t\tfor _, srcObj := range srcLayer.Objects {\n\t\t\t\t\t\t\t\tif srcObj.Change != ChangeDelete {\n\t\t\t\t\t\t\t\t\tnewObj := *srcObj\n\t\t\t\t\t\t\t\t\tnewObj.Change = ChangeUnknown\n\t\t\t\t\t\t\t\t\tlayer.Objects = append(layer.Objects, &newObj)\n\t\t\t\t\t\t\t\t\tlayer.References[srcObj.Name] = &newObj\n\t\t\t\t\t\t\t\t\tlayer.Stats.ObjectCount++\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlayer.Stats.LinkCount = srcLayer.Stats.LinkCount - srcLayer.Stats.DeletedLinkCount\n\t\t\t\t\t\t\tlayer.Stats.FileCount = srcLayer.Stats.FileCount - srcLayer.Stats.DeletedFileCount\n\t\t\t\t\t\t\tlayer.Stats.DirCount = srcLayer.Stats.DirCount - srcLayer.Stats.DeletedDirCount\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: could not find source layer - %v\", layer.LayerDataSource)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlayer, err = layerFromStream(\n\t\t\t\t\t\tpkg,\n\t\t\t\t\t\thdr.Name,\n\t\t\t\t\t\ttar.NewReader(tr),\n\t\t\t\t\t\tlayerID,\n\t\t\t\t\t\ttopChangesMax,\n\t\t\t\t\t\tdoHashData,\n\t\t\t\t\t\tdoDetectDuplicates,\n\t\t\t\t\t\tchangeDataHashMatchers,\n\t\t\t\t\t\tchangePathMatchers,\n\t\t\t\t\t\tcpmDumps,\n\t\t\t\t\t\tchangeDataMatchers,\n\t\t\t\t\t\tutf8Detector,\n\t\t\t\t\t\tprocessorParams,\n\t\t\t\t\t)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading layer from archive(%v/%v) - %v\", archivePath, hdr.Name, err)\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlayers[layerID] = layer\n\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: saved v1 layer '%s' from archive - %s\",\n\t\t\t\t\tlayerID, archivePath)\n\n\t\t\tdefault:\n\t\t\t\tif _, found := layerFileNames[hdr.Name]; found {\n\t\t\t\t\t// todo: test if we can get symlinks...\n\t\t\t\t\tparts := strings.SplitN(hdr.Name, \"/\", 3)\n\t\t\t\t\tlayerID := parts[2]\n\t\t\t\t\tlayer, err := layerFromStream(\n\t\t\t\t\t\tpkg,\n\t\t\t\t\t\thdr.Name,\n\t\t\t\t\t\ttar.NewReader(tr),\n\t\t\t\t\t\tlayerID,\n\t\t\t\t\t\ttopChangesMax,\n\t\t\t\t\t\tdoHashData,\n\t\t\t\t\t\tdoDetectDuplicates,\n\t\t\t\t\t\tchangeDataHashMatchers,\n\t\t\t\t\t\tchangePathMatchers,\n\t\t\t\t\t\tcpmDumps,\n\t\t\t\t\t\tchangeDataMatchers,\n\t\t\t\t\t\tutf8Detector,\n\t\t\t\t\t\tprocessorParams,\n\t\t\t\t\t)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error reading oci layer from archive(%s/%s) - %v\", archivePath, hdr.Name, err)\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\tlayers[layerID] = layer\n\t\t\t\t\tlog.Debugf(\"dockerimage.LoadPackage: saved layer '%s' from archive - %s\",\n\t\t\t\t\t\tlayerID, archivePath)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif pkg.Format == FormatOCI {\n\t\tif pkg.ManifestOCI == nil {\n\t\t\treturn nil, fmt.Errorf(\"dockerimage.LoadPackage: missing OCI Image Manifest object for image ID=%s / archive='%s' / files=%+v\",\n\t\t\t\timageID, archivePath, archiveFiles)\n\t\t}\n\t} else {\n\t\tif pkg.Manifest == nil {\n\t\t\treturn nil, fmt.Errorf(\"dockerimage.LoadPackage: missing manifest object for image ID=%s / archive='%s' / files=%+v\",\n\t\t\t\timageID, archivePath, archiveFiles)\n\t\t}\n\t}\n\n\tif pkg.Config == nil {\n\t\treturn nil, fmt.Errorf(\"dockerimage.LoadPackage: missing image config object for image ID=%s / archive='%s' / files=%+v\",\n\t\t\timageID, archivePath, archiveFiles)\n\t}\n\n\tif len(layers) == 0 {\n\t\t//todo: display non-image layer metadata if there are any\n\t\t//todo: save non-image layer metadata/data\n\t\tlog.Debugf(\"dockerimage.LoadPackage: no image layers in archive - %s (%+v)\",\n\t\t\tarchivePath, layerFileNames)\n\t}\n\n\tif len(nonLayerFileNames) > 0 {\n\t\tlog.Debugf(\"dockerimage.LoadPackage: non-image layers in archive - %s (%s)\",\n\t\t\tarchivePath, jsonutil.ToString(nonLayerFileNames))\n\t}\n\n\tlog.Debugf(\"dockerimage.LoadPackage: layerLocationSource=%v layerSequence='%#v' - archive='%s'\",\n\t\tlayerLocationSource, layerSequence, archivePath)\n\n\tfor idx, layerLocationInfo := range layerSequence {\n\t\tlayer, ok := layers[layerLocationInfo.LayerID]\n\t\tif !ok {\n\t\t\tlog.Errorf(\"dockerimage.LoadPackage: error missing layer (idx=%d layerPath=%s layerID=%s) archive=%s\",\n\t\t\t\tidx, layerLocationInfo.Path, layerLocationInfo.LayerID, archivePath)\n\t\t\treturn nil, fmt.Errorf(\"dockerimage.LoadPackage: missing layer (%v) for image ID - %v\", layerLocationInfo.Path, imageID)\n\t\t}\n\n\t\tlayer.Index = idx\n\t\t//adding layers based on their manifest order\n\t\tpkg.Layers = append(pkg.Layers, layer)\n\t\tif len(pkg.Layers)-1 != layer.Index {\n\t\t\treturn nil, fmt.Errorf(\"dockerimage.LoadPackage: layer index mismatch - %v / %v\", len(pkg.Layers)-1, layer.Index)\n\t\t}\n\n\t\tif layerLocationInfo.Path != layer.Path {\n\t\t\treturn nil, fmt.Errorf(\"dockerimage.LoadPackage: layer path mismatch - %v / %v\", layerLocationInfo.Path, layer.Path)\n\t\t}\n\n\t\tif idx == 0 {\n\t\t\tfor oidx, object := range layer.Objects {\n\t\t\t\tobject.LayerIndex = idx\n\n\t\t\t\tif utf8Detector != nil {\n\t\t\t\t\tswitch object.ContentType {\n\t\t\t\t\tcase ContentTypeUTF8:\n\t\t\t\t\t\tlayer.Stats.UTF8Count++\n\t\t\t\t\t\tlayer.Stats.UTF8Size += uint64(object.Size)\n\t\t\t\t\t\tpkg.Stats.UTF8Count++\n\t\t\t\t\t\tpkg.Stats.UTF8Size += uint64(object.Size)\n\t\t\t\t\tcase ContentTypeBinary:\n\t\t\t\t\t\tlayer.Stats.BinaryCount++\n\t\t\t\t\t\tlayer.Stats.BinarySize += uint64(object.Size)\n\t\t\t\t\t\tpkg.Stats.BinaryCount++\n\t\t\t\t\t\tpkg.Stats.BinarySize += uint64(object.Size)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif object.Change == ChangeUnknown {\n\t\t\t\t\tobject.Change = ChangeAdd\n\t\t\t\t\tlayer.Changes.Added = append(layer.Changes.Added, oidx)\n\t\t\t\t\tlayer.Stats.AddedSize += uint64(object.Size)\n\t\t\t\t}\n\n\t\t\t\tif object.History == nil {\n\t\t\t\t\tobject.History = &ObjectHistory{}\n\t\t\t\t}\n\n\t\t\t\tchangeInfo := ChangeInfo{\n\t\t\t\t\tLayer:  layer.Index,\n\t\t\t\t\tObject: object,\n\t\t\t\t}\n\n\t\t\t\tswitch object.Change {\n\t\t\t\tcase ChangeAdd:\n\t\t\t\t\tobject.History.Add = &changeInfo\n\t\t\t\tcase ChangeDelete:\n\t\t\t\t\tobject.History.Delete = &changeInfo\n\t\t\t\t}\n\n\t\t\t\tif object.Change == ChangeAdd ||\n\t\t\t\t\tobject.Change == ChangeModify {\n\t\t\t\t\tif shellInfo, found := pkg.OSShells[object.Name]; found {\n\t\t\t\t\t\tif exeInfo, rfound := layer.References[shellInfo.ExePath]; rfound {\n\t\t\t\t\t\t\tshellInfo.Verified = true\n\t\t\t\t\t\t\tif exeInfo.LinkTarget != \"\" {\n\t\t\t\t\t\t\t\tshellInfo.LinkPath = exeInfo.LinkTarget\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\n\t\t\tif utf8Detector != nil {\n\t\t\t\tlayer.Stats.UTF8SizeHuman = humanize.Bytes(layer.Stats.UTF8Size)\n\t\t\t\tlayer.Stats.BinarySizeHuman = humanize.Bytes(layer.Stats.BinarySize)\n\t\t\t}\n\n\t\t} else {\n\t\t\tfor oidx, object := range layer.Objects {\n\t\t\t\tobject.LayerIndex = idx\n\n\t\t\t\tif utf8Detector != nil {\n\t\t\t\t\tswitch object.ContentType {\n\t\t\t\t\tcase ContentTypeUTF8:\n\t\t\t\t\t\tlayer.Stats.UTF8Count++\n\t\t\t\t\t\tlayer.Stats.UTF8Size += uint64(object.Size)\n\t\t\t\t\t\tpkg.Stats.UTF8Count++\n\t\t\t\t\t\tpkg.Stats.UTF8Size += uint64(object.Size)\n\t\t\t\t\tcase ContentTypeBinary:\n\t\t\t\t\t\tlayer.Stats.BinaryCount++\n\t\t\t\t\t\tlayer.Stats.BinarySize += uint64(object.Size)\n\t\t\t\t\t\tpkg.Stats.BinaryCount++\n\t\t\t\t\t\tpkg.Stats.BinarySize += uint64(object.Size)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif object.Change == ChangeUnknown {\n\t\t\t\t\tfor prevIdx := 0; prevIdx < idx; prevIdx++ {\n\t\t\t\t\t\tprevLayer := pkg.Layers[prevIdx]\n\t\t\t\t\t\tif om, ok := prevLayer.References[object.Name]; ok {\n\t\t\t\t\t\t\tobject.Change = ChangeModify\n\t\t\t\t\t\t\tlayer.Changes.Modified = append(layer.Changes.Modified, oidx)\n\t\t\t\t\t\t\tlayer.Stats.ModifiedSize += uint64(object.Size)\n\n\t\t\t\t\t\t\tif om.History != nil {\n\t\t\t\t\t\t\t\tobject.History = om.History\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tobject.History = &ObjectHistory{}\n\t\t\t\t\t\t\t\tom.History = object.History\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tchangeInfo := ChangeInfo{\n\t\t\t\t\t\t\t\tLayer:  layer.Index,\n\t\t\t\t\t\t\t\tObject: object,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tobject.History.Modifies = append(object.History.Modifies, &changeInfo)\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif object.Change == ChangeUnknown {\n\t\t\t\t\t\tif object.History == nil {\n\t\t\t\t\t\t\tobject.History = &ObjectHistory{}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tobject.History.Add = &ChangeInfo{\n\t\t\t\t\t\t\tLayer:  layer.Index,\n\t\t\t\t\t\t\tObject: object,\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tobject.Change = ChangeAdd\n\t\t\t\t\t\tlayer.Changes.Added = append(layer.Changes.Added, oidx)\n\t\t\t\t\t\tlayer.Stats.AddedSize += uint64(object.Size)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif object.Change == ChangeDelete {\n\t\t\t\t\tfor prevIdx := 0; prevIdx < idx; prevIdx++ {\n\t\t\t\t\t\tprevLayer := pkg.Layers[prevIdx]\n\t\t\t\t\t\tif om, ok := prevLayer.References[object.Name]; ok {\n\n\t\t\t\t\t\t\tif om.History != nil {\n\t\t\t\t\t\t\t\tobject.History = om.History\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tobject.History = &ObjectHistory{}\n\t\t\t\t\t\t\t\tom.History = object.History\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tobject.History.Delete = &ChangeInfo{\n\t\t\t\t\t\t\t\tLayer:  layer.Index,\n\t\t\t\t\t\t\t\tObject: object,\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tswitch object.TypeFlag {\n\t\t\t\t\t\t\tcase tar.TypeReg:\n\t\t\t\t\t\t\t\t//NOTE: counting the file size of the first instance\n\t\t\t\t\t\t\t\tlayer.Stats.DeletedSize += uint64(om.Size)\n\t\t\t\t\t\t\t\tpkg.Stats.DeletedFileSize += uint64(om.Size)\n\t\t\t\t\t\t\tcase tar.TypeDir:\n\t\t\t\t\t\t\t\t//TODO: need to count all file sizes in the dir\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif object.Change == ChangeAdd ||\n\t\t\t\t\tobject.Change == ChangeModify {\n\t\t\t\t\tif shellInfo, found := pkg.OSShells[object.Name]; found {\n\t\t\t\t\t\tif exeInfo, rfound := layer.References[shellInfo.ExePath]; rfound {\n\t\t\t\t\t\t\tshellInfo.Verified = true\n\t\t\t\t\t\t\tif exeInfo.LinkTarget != \"\" {\n\t\t\t\t\t\t\t\tshellInfo.LinkPath = exeInfo.LinkTarget\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\tif utf8Detector != nil {\n\t\t\t\tlayer.Stats.UTF8SizeHuman = humanize.Bytes(layer.Stats.UTF8Size)\n\t\t\t\tlayer.Stats.BinarySizeHuman = humanize.Bytes(layer.Stats.BinarySize)\n\t\t\t}\n\t\t}\n\n\t\tpkg.LayerIDRefs[layerLocationInfo.LayerID] = layer\n\n\t\tif pkg.Config.RootFS != nil && idx < len(pkg.Config.RootFS.DiffIDs) {\n\t\t\tdiffID := pkg.Config.RootFS.DiffIDs[idx]\n\t\t\tlayer.FSDiffID = diffID\n\t\t} else {\n\t\t\tlog.Debugf(\"dockerimage.LoadPackage: no FS diff for layer index %v\", idx)\n\t\t}\n\t}\n\n\tif utf8Detector != nil {\n\t\tpkg.Stats.UTF8SizeHuman = humanize.Bytes(pkg.Stats.UTF8Size)\n\t\tpkg.Stats.BinarySizeHuman = humanize.Bytes(pkg.Stats.BinarySize)\n\t}\n\n\tif len(pkg.Layers) > 0 {\n\t\tcurrentLayerIndex := 0\n\t\tisFirstLayer := true\n\t\tfor hidx := range pkg.Config.History {\n\t\t\tif !pkg.Config.History[hidx].EmptyLayer {\n\t\t\t\tif currentLayerIndex < (len(pkg.Layers)-1) &&\n\t\t\t\t\t!isFirstLayer {\n\t\t\t\t\tcurrentLayerIndex++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcurrentLayer := pkg.Layers[currentLayerIndex]\n\n\t\t\tif currentLayer != nil {\n\t\t\t\tpkg.Config.History[hidx].LayerFSDiffID = currentLayer.FSDiffID\n\t\t\t\tpkg.Config.History[hidx].LayerID = currentLayer.ID\n\t\t\t\tpkg.Config.History[hidx].LayerIndex = currentLayer.Index\n\t\t\t}\n\n\t\t\tif !pkg.Config.History[hidx].EmptyLayer && isFirstLayer {\n\t\t\t\tisFirstLayer = false\n\t\t\t}\n\t\t}\n\t}\n\n\tif doDetectDuplicates {\n\t\tfor hash, hr := range pkg.HashReferences {\n\t\t\tdupCount := len(hr)\n\t\t\tif dupCount > 1 {\n\t\t\t\tpkg.Stats.DuplicateFileCount++\n\t\t\t\tpkg.Stats.DuplicateFileTotalCount += uint64(dupCount)\n\t\t\t\tfor _, om := range hr {\n\t\t\t\t\tpkg.Stats.DuplicateFileSize += uint64(om.Size)\n\t\t\t\t\tpkg.Stats.DuplicateFileTotalSize += uint64(om.Size * int64(dupCount))\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdelete(pkg.HashReferences, hash)\n\t\t\t}\n\t\t}\n\n\t\tif pkg.Stats.DuplicateFileCount > 0 {\n\t\t\tpkg.Stats.DuplicateFileWastedSize = uint64(pkg.Stats.DuplicateFileTotalSize - pkg.Stats.DuplicateFileSize)\n\t\t}\n\t}\n\n\treturn pkg, nil\n}\n\nfunc (ref *Package) ProcessIdentityData() *sysidentity.Report {\n\tif ref.IdentityData == nil {\n\t\treturn nil\n\t}\n\n\treport, err := sysidentity.NewReportFromData(ref.IdentityData)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerimage.Package.ProcessIdentityData: error - %v\", err)\n\t\treturn nil\n\t}\n\n\treturn report\n}\n\nfunc hasChangePathMatcherDumps(changePathMatchers []*ChangePathMatcher) bool {\n\tfor _, cpm := range changePathMatchers {\n\t\tif cpm.PathPattern != \"\" && cpm.Dump {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc linkTargetToFullPath(fullPath, target string) string {\n\tif filepath.IsAbs(target) {\n\t\treturn target\n\t}\n\n\tif target == \".\" {\n\t\treturn \"\"\n\t}\n\n\td := filepath.Dir(fullPath)\n\n\treturn filepath.Clean(filepath.Join(d, target))\n}\n\nfunc layerFromStream(\n\tpkg *Package,\n\tlayerPath string,\n\ttr *tar.Reader,\n\tlayerID string,\n\ttopChangesMax int,\n\tdoHashData bool,\n\tdoDetectDuplicates bool,\n\tchangeDataHashMatchers map[string]*ChangeDataHashMatcher,\n\tchangePathMatchers []*ChangePathMatcher,\n\tcpmDumps bool,\n\tchangeDataMatchers map[string]*ChangeDataMatcher,\n\tutf8Detector *UTF8Detector,\n\tprocessorParams *ProcessorParams,\n) (*Layer, error) {\n\n\tlayer := newLayer(layerID, topChangesMax)\n\tlayer.Path = layerPath\n\n\ttopChangesCount := defaultTopObjectMax\n\tif topChangesMax > -1 {\n\t\ttopChangesCount = topChangesMax\n\t}\n\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"layerFromStream: error reading layer(%v) - %v\", layerID, err)\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif hdr == nil || hdr.Name == \"\" {\n\t\t\tlog.Debug(\"layerFromStream: ignoring bad tar header\")\n\t\t\tcontinue\n\t\t}\n\n\t\thdr.Name = filepath.Clean(hdr.Name)\n\n\t\tobject := &ObjectMetadata{\n\t\t\tName:       hdr.Name,\n\t\t\tSize:       hdr.Size,\n\t\t\tSizeHuman:  humanize.Bytes(uint64(hdr.Size)),\n\t\t\tMode:       hdr.FileInfo().Mode(),\n\t\t\tUID:        hdr.Uid,\n\t\t\tGID:        hdr.Gid,\n\t\t\tModTime:    hdr.ModTime,\n\t\t\tChangeTime: hdr.ChangeTime,\n\t\t\tTypeFlag:   hdr.Typeflag,\n\t\t\tType:       ObjectTypeFromTarType(hdr.Typeflag),\n\t\t}\n\n\t\tnormalized, isDeleted, isDeletedDirContent, err := NormalizeFileObjectLayerPath(object.Name)\n\t\tif err == nil && len(object.Name) > 0 && object.Name[0] != '/' {\n\t\t\tobject.Name = fmt.Sprintf(\"/%s\", normalized)\n\t\t}\n\n\t\tobject.Name = strings.ReplaceAll(object.Name, \"//\", \"/\")\n\t\tobject.LinkTarget = strings.ReplaceAll(object.LinkTarget, \"//\", \"/\")\n\n\t\tif isDeletedDirContent {\n\t\t\tobject.DirContentDelete = true\n\t\t}\n\n\t\tlayer.Objects = append(layer.Objects, object)\n\t\tlayer.References[object.Name] = object\n\n\t\theap.Push(&(layer.Top), object)\n\t\tif layer.Top.Len() > topChangesCount {\n\t\t\t_ = heap.Pop(&(layer.Top))\n\t\t}\n\n\t\tlayer.Stats.AllSize += uint64(object.Size)\n\t\tlayer.Stats.ObjectCount++\n\n\t\tif isDeletedDirContent {\n\t\t\tobject.Change = ChangeDelete\n\t\t\tidx := len(layer.Objects) - 1\n\t\t\tlayer.Changes.Deleted = append(layer.Changes.Deleted, idx)\n\t\t\tlayer.Changes.DeletedDirContent = append(layer.Changes.DeletedDirContent, idx)\n\t\t\tlayer.Stats.DeletedDirContentCount++\n\t\t\tpkg.Stats.DeletedDirContentCount++\n\t\t} else {\n\t\t\tif isDeleted {\n\t\t\t\tobject.Change = ChangeDelete\n\t\t\t\tidx := len(layer.Objects) - 1\n\t\t\t\tlayer.Changes.Deleted = append(layer.Changes.Deleted, idx)\n\t\t\t\tlayer.Stats.DeletedCount++\n\t\t\t\tpkg.Stats.DeletedCount++\n\t\t\t\t//layer.Stats.DeletedSize += uint64(object.Size)\n\t\t\t\t//NOTE:\n\t\t\t\t//This is not the real deleted size.\n\t\t\t\t//Need to find the actual object in a previous layer to know the actual size.\n\t\t\t}\n\t\t}\n\n\t\tswitch hdr.Typeflag {\n\t\tcase tar.TypeSymlink, tar.TypeLink:\n\t\t\tobject.LinkTarget = hdr.Linkname\n\t\t\tlayer.Stats.LinkCount++\n\t\t\tif isDeleted {\n\t\t\t\tlayer.Stats.DeletedLinkCount++\n\t\t\t\tpkg.Stats.DeletedLinkCount++\n\t\t\t}\n\n\t\t\tnameOnly := filepath.Base(object.Name)\n\t\t\tif certdiscover.IsCertHashName(nameOnly) {\n\t\t\t\tif certdiscover.IsCertPKDirPath(object.Name) {\n\t\t\t\t\tpkg.CACerts.Hashes[object.Name] = object.LinkTarget\n\t\t\t\t} else if certdiscover.IsCertDirPath(object.Name) {\n\t\t\t\t\tpkg.Certs.Hashes[object.Name] = object.LinkTarget\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlinkFullPath := linkTargetToFullPath(object.Name, object.LinkTarget)\n\t\t\t\tif certdiscover.IsCertFile(object.Name) {\n\t\t\t\t\tpkg.Certs.Bundles[object.Name] = struct{}{}\n\t\t\t\t\tif linkFullPath != \"\" {\n\t\t\t\t\t\tpkg.Certs.Bundles[linkFullPath] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t} else if certdiscover.IsAppCertFile(object.Name) {\n\t\t\t\t\tpkg.Certs.Bundles[object.Name] = struct{}{}\n\t\t\t\t\tif linkFullPath != \"\" {\n\t\t\t\t\t\tpkg.Certs.Bundles[linkFullPath] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t} else if certdiscover.IsCACertFile(object.Name) {\n\t\t\t\t\tpkg.CACerts.Bundles[object.Name] = struct{}{}\n\t\t\t\t\tif linkFullPath != \"\" {\n\t\t\t\t\t\tpkg.CACerts.Bundles[linkFullPath] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t} else if certdiscover.IsCACertPKFile(object.Name) {\n\t\t\t\t\tpkg.CACerts.PrivateKeys[object.Name] = struct{}{}\n\t\t\t\t\tif linkFullPath != \"\" {\n\t\t\t\t\t\tpkg.CACerts.PrivateKeys[linkFullPath] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t//NOTE: Links require post-processing\n\t\t\t\t\tif certdiscover.IsCertDir(object.Name) {\n\t\t\t\t\t\tpkg.Certs.Links[object.Name] = linkFullPath\n\t\t\t\t\t} else if certdiscover.IsCertPKDir(object.Name) {\n\t\t\t\t\t\tpkg.Certs.PrivateKeyLinks[object.Name] = linkFullPath\n\t\t\t\t\t} else if certdiscover.IsCACertDir(object.Name) {\n\t\t\t\t\t\tpkg.CACerts.Links[object.Name] = linkFullPath\n\t\t\t\t\t} else if certdiscover.IsCACertPKDir(object.Name) {\n\t\t\t\t\t\tpkg.CACerts.PrivateKeyLinks[object.Name] = linkFullPath\n\t\t\t\t\t} else if certdiscover.IsCertDirPath(object.Name) {\n\t\t\t\t\t\tpkg.Certs.Links[object.Name] = linkFullPath\n\t\t\t\t\t} else if certdiscover.IsCACertDirPath(object.Name) {\n\t\t\t\t\t\tpkg.CACerts.Links[object.Name] = linkFullPath\n\t\t\t\t\t} else if certdiscover.IsCertPKDirPath(object.Name) {\n\t\t\t\t\t\tpkg.Certs.PrivateKeyLinks[object.Name] = linkFullPath\n\t\t\t\t\t} else if certdiscover.IsCACertPKDirPath(object.Name) {\n\t\t\t\t\t\tpkg.CACerts.PrivateKeyLinks[object.Name] = linkFullPath\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase tar.TypeReg:\n\t\t\tlayer.Stats.FileCount++\n\t\t\tif uint64(object.Size) > layer.Stats.MaxFileSize {\n\t\t\t\tlayer.Stats.MaxFileSize = uint64(object.Size)\n\t\t\t}\n\n\t\t\tif isDeleted {\n\t\t\t\tlayer.Stats.DeletedFileCount++\n\t\t\t\tpkg.Stats.DeletedFileCount++\n\t\t\t} else {\n\t\t\t\t//TODO:\n\t\t\t\t//do unique pkg stats counts,\n\t\t\t\t//so we don't count the same thing multiple times\n\t\t\t\t//across different layers\n\t\t\t\tif fsutil.FileModeIsSetuid(object.Mode) {\n\t\t\t\t\tlayer.Stats.SetuidCount++\n\t\t\t\t\tpkg.Stats.SetuidCount++\n\t\t\t\t\tpkg.SpecialPermRefs.Setuid[object.Name] = object\n\t\t\t\t}\n\n\t\t\t\tif fsutil.FileModeIsSetgid(object.Mode) {\n\t\t\t\t\tlayer.Stats.SetgidCount++\n\t\t\t\t\tpkg.Stats.SetgidCount++\n\t\t\t\t\tpkg.SpecialPermRefs.Setgid[object.Name] = object\n\t\t\t\t}\n\n\t\t\t\tif fsutil.FileModeIsSticky(object.Mode) {\n\t\t\t\t\tlayer.Stats.StickyCount++\n\t\t\t\t\tpkg.Stats.StickyCount++\n\t\t\t\t\tpkg.SpecialPermRefs.Sticky[object.Name] = object\n\t\t\t\t}\n\n\t\t\t\terr = inspectFile(\n\t\t\t\t\tobject,\n\t\t\t\t\ttr,\n\t\t\t\t\tpkg,\n\t\t\t\t\tlayer,\n\t\t\t\t\tdoHashData,\n\t\t\t\t\tchangeDataHashMatchers,\n\t\t\t\t\tchangePathMatchers,\n\t\t\t\t\tcpmDumps,\n\t\t\t\t\tchangeDataMatchers,\n\t\t\t\t\tutf8Detector,\n\t\t\t\t\tprocessorParams,\n\t\t\t\t)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"layerFromStream: error inspecting layer file (%s) - (%v) - %v\", object.Name, layerID, err)\n\t\t\t\t} else {\n\t\t\t\t\tif doDetectDuplicates && len(object.Hash) != 0 {\n\t\t\t\t\t\thr, found := pkg.HashReferences[object.Hash]\n\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\thr = map[string]*ObjectMetadata{}\n\t\t\t\t\t\t\tpkg.HashReferences[object.Hash] = hr\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\thr[object.Name] = object\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase tar.TypeDir:\n\t\t\tlayer.Stats.DirCount++\n\t\t\tif uint64(object.Size) > layer.Stats.MaxDirSize {\n\t\t\t\tlayer.Stats.MaxDirSize = uint64(object.Size)\n\t\t\t}\n\n\t\t\tif isDeleted {\n\t\t\t\tlayer.Stats.DeletedDirCount++\n\t\t\t\tpkg.Stats.DeletedDirCount++\n\t\t\t} else {\n\t\t\t\t//TODO:\n\t\t\t\t//do unique pkg stats counts,\n\t\t\t\t//so we don't count the same thing multiple times\n\t\t\t\t//across different layers\n\t\t\t\tif fsutil.FileModeIsSticky(object.Mode) {\n\t\t\t\t\tlayer.Stats.StickyCount++\n\t\t\t\t\tpkg.Stats.StickyCount++\n\t\t\t\t\tpkg.SpecialPermRefs.Sticky[object.Name] = object\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn layer, nil\n}\n\nfunc getStreamHash(reader io.Reader) (string, error) {\n\thasher := sha1.New()\n\n\t_, err := io.Copy(hasher, reader)\n\tif err != nil {\n\t\tlog.Errorf(\"getStreamHash: error=%v\", err)\n\t\treturn \"\", err\n\t}\n\n\thash := hasher.Sum(nil)\n\treturn hex.EncodeToString(hash[:]), nil\n}\n\nfunc getBytesHash(data []byte) string {\n\thash := sha1.Sum(data)\n\treturn hex.EncodeToString(hash[:])\n}\n\ntype utf8FileInfo struct {\n\tname    string\n\tsize    int64\n\tmodtime time.Time\n}\n\nfunc (f *utf8FileInfo) Name() string       { return f.name }\nfunc (f *utf8FileInfo) Size() int64        { return f.size }\nfunc (f *utf8FileInfo) Mode() os.FileMode  { return os.ModePerm }\nfunc (f *utf8FileInfo) ModTime() time.Time { return f.modtime }\nfunc (f *utf8FileInfo) IsDir() bool        { return false }\nfunc (f *utf8FileInfo) Sys() interface{}   { return nil }\n\nfunc inspectFile(\n\tobject *ObjectMetadata,\n\treader io.Reader,\n\tpkg *Package,\n\tlayer *Layer,\n\tdoHashData bool,\n\tchangeDataHashMatchers map[string]*ChangeDataHashMatcher,\n\tchangePathMatchers []*ChangePathMatcher,\n\tcpmDumps bool,\n\tchangeDataMatchers map[string]*ChangeDataMatcher,\n\tutf8Detector *UTF8Detector,\n\tprocessorParams *ProcessorParams,\n) error {\n\t//TODO: refactor and enhance the OS Distro detection logic\n\tfullPath := object.Name\n\n\tvar cdhmDumps bool\n\tfor _, dhm := range changeDataHashMatchers {\n\t\tif dhm.Dump {\n\t\t\tcdhmDumps = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tvar isKnownCertFile bool\n\tif certdiscover.IsCertFile(fullPath) {\n\t\tpkg.Certs.Bundles[fullPath] = struct{}{}\n\t\tisKnownCertFile = true\n\t} else if certdiscover.IsAppCertFile(fullPath) {\n\t\tpkg.Certs.Bundles[fullPath] = struct{}{}\n\t\tisKnownCertFile = true\n\t} else if certdiscover.IsCACertFile(fullPath) {\n\t\tpkg.CACerts.Bundles[fullPath] = struct{}{}\n\t\tisKnownCertFile = true\n\t} else if certdiscover.IsCACertPKFile(fullPath) {\n\t\tpkg.CACerts.PrivateKeys[fullPath] = struct{}{}\n\t\tisKnownCertFile = true\n\t}\n\n\tif (processorParams.DetectIdentities.Enabled &&\n\t\tsysidentity.IsSourceFile(fullPath)) ||\n\t\tsystem.IsOSReleaseFile(fullPath) ||\n\t\tsystem.IsOSShellsFile(fullPath) ||\n\t\tlen(changeDataMatchers) > 0 ||\n\t\tcpmDumps ||\n\t\tcdhmDumps ||\n\t\tutf8Detector != nil ||\n\t\t(!isKnownCertFile && processorParams.DetectAllCertFiles) ||\n\t\t(!isKnownCertFile && processorParams.DetectAllCertPKFiles) {\n\t\tdata, err := io.ReadAll(reader)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif processorParams.DetectIdentities.Enabled &&\n\t\t\tsysidentity.IsSourceFile(fullPath) {\n\t\t\tpkg.IdentityData.AddData(fullPath, data)\n\t\t}\n\n\t\tif !isKnownCertFile {\n\t\t\tif processorParams.DetectAllCertFiles {\n\t\t\t\t//NOTE:\n\t\t\t\t//not limiting detection to the main cert directories,\n\t\t\t\t//but checking the CA cert dir prefix to know where to put it\n\t\t\t\tif certdiscover.IsCertData(data) {\n\t\t\t\t\tif certdiscover.IsCACertDirPath(fullPath) {\n\t\t\t\t\t\tpkg.CACerts.Files[fullPath] = struct{}{}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpkg.Certs.Files[fullPath] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif processorParams.DetectAllCertPKFiles {\n\t\t\t\t//NOTE: not limiting detection to the main cert private key directories\n\t\t\t\tif certdiscover.IsPrivateKeyData(data) {\n\t\t\t\t\tif certdiscover.IsCACertPKDirPath(fullPath) {\n\t\t\t\t\t\tpkg.CACerts.PrivateKeys[fullPath] = struct{}{}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpkg.Certs.PrivateKeys[fullPath] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif system.IsOSShellsFile(fullPath) {\n\t\t\tshellsList, _ := system.NewOSShellsFromData(data)\n\t\t\tfor _, shellInfo := range shellsList {\n\t\t\t\tif shellInfo.Reference != \"\" {\n\t\t\t\t\tpkg.OSShells[shellInfo.Reference] = shellInfo\n\t\t\t\t} else {\n\t\t\t\t\tpkg.OSShells[shellInfo.ExePath] = shellInfo\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif system.IsOSReleaseFile(fullPath) {\n\t\t\tosr, err := system.NewOsRelease(data)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tdistro := &system.DistroInfo{\n\t\t\t\tName:        osr.Name,\n\t\t\t\tVersion:     osr.VersionID,\n\t\t\t\tDisplayName: osr.PrettyName,\n\t\t\t}\n\n\t\t\tif distro.Version == \"\" {\n\t\t\t\tdistro.Version = osr.Version\n\t\t\t}\n\n\t\t\tif distro.DisplayName == \"\" {\n\t\t\t\tnameMain := osr.Name\n\t\t\t\tnameVersion := osr.Version\n\t\t\t\tif nameVersion == \"\" {\n\t\t\t\t\tnameVersion = osr.VersionID\n\t\t\t\t}\n\n\t\t\t\tdistro.DisplayName = fmt.Sprintf(\"%v %v\", nameMain, nameVersion)\n\t\t\t}\n\n\t\t\tlayer.Distro = distro\n\t\t}\n\n\t\tvar hash string\n\t\tif doHashData ||\n\t\t\tlen(changeDataHashMatchers) > 0 ||\n\t\t\tutf8Detector != nil {\n\t\t\thash = getBytesHash(data)\n\t\t}\n\n\t\tif doHashData {\n\t\t\tobject.Hash = hash\n\t\t}\n\n\t\tif len(hash) > 0 && utf8Detector != nil {\n\t\t\tif utf8.Valid(data) {\n\t\t\t\tobject.ContentType = ContentTypeUTF8\n\t\t\t\tif utf8Detector.Dump {\n\t\t\t\t\tif utf8Detector.Archive != nil {\n\t\t\t\t\t\tif utf8Detector.MaxSizeBytes != 0 && object.Size > int64(utf8Detector.MaxSizeBytes) {\n\t\t\t\t\t\t\tfileInfo := &utf8FileInfo{\n\t\t\t\t\t\t\t\tname:    hash,\n\t\t\t\t\t\t\t\tsize:    int64(utf8Detector.MaxSizeBytes),\n\t\t\t\t\t\t\t\tmodtime: object.ModTime,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\theader, err := tar.FileInfoHeader(fileInfo, hash)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\theader.Name = hash\n\t\t\t\t\t\t\terr = utf8Detector.Archive.Writer.WriteHeader(header)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t_, err = utf8Detector.Archive.Writer.Write(data[:utf8Detector.MaxSizeBytes])\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfileInfo := &utf8FileInfo{\n\t\t\t\t\t\t\t\tname:    hash,\n\t\t\t\t\t\t\t\tsize:    object.Size,\n\t\t\t\t\t\t\t\tmodtime: object.ModTime,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\theader, err := tar.FileInfoHeader(fileInfo, hash)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\theader.Name = hash\n\t\t\t\t\t\t\terr = utf8Detector.Archive.Writer.WriteHeader(header)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t_, err = utf8Detector.Archive.Writer.Write(data)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif utf8Detector.DumpConsole {\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=detect.utf8.match.start\\n\")\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=detect.utf8.match file='%s')\\n\", fullPath)\n\t\t\t\t\t\tfmt.Printf(\"%s\\n\", string(data))\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=detect.utf8.match.end\\n\")\n\t\t\t\t\t}\n\n\t\t\t\t\tif utf8Detector.DumpDir != \"\" {\n\t\t\t\t\t\tdumpPath := filepath.Join(utf8Detector.DumpDir, fullPath)\n\t\t\t\t\t\tdirPath := fsutil.FileDir(dumpPath)\n\t\t\t\t\t\tif !fsutil.DirExists(dirPath) {\n\t\t\t\t\t\t\terr := os.MkdirAll(dirPath, 0755)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=detect.utf8.match.dump.error file='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\t\t\tfullPath, dumpPath, err)\n\t\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\terr := os.WriteFile(dumpPath, data, 0644)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=detect.utf8.match.dump.error file='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\t\tfullPath, dumpPath, err)\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=detect.utf8.match.dump file='%s' target='%s'):\\n\",\n\t\t\t\t\t\t\tfullPath, dumpPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tobject.ContentType = ContentTypeBinary\n\t\t\t}\n\t\t}\n\n\t\tif len(hash) > 0 && len(changeDataHashMatchers) > 0 {\n\t\t\tif dhm, found := changeDataHashMatchers[hash]; found {\n\t\t\t\t//need to save to DataHashMatches to make it work without generating/saving hashes for all objects\n\t\t\t\tlayer.DataHashMatches[fullPath] = dhm\n\n\t\t\t\tif dhm.DumpConsole {\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.hash.match.start\\n\")\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.hash.match file='%s' hash='%s')\\n\",\n\t\t\t\t\t\tfullPath, hash)\n\t\t\t\t\tfmt.Printf(\"%s\\n\", string(data))\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.hash.match.end\\n\")\n\t\t\t\t}\n\n\t\t\t\tif dhm.DumpDir != \"\" {\n\t\t\t\t\tdumpPath := filepath.Join(dhm.DumpDir, fullPath)\n\t\t\t\t\tdirPath := fsutil.FileDir(dumpPath)\n\t\t\t\t\tif !fsutil.DirExists(dirPath) {\n\t\t\t\t\t\terr := os.MkdirAll(dirPath, 0755)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.hash.match.dump.error file='%s' hash='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\t\tfullPath, hash, dumpPath, err)\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\terr := os.WriteFile(dumpPath, data, 0644)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.hash.match.dump.error file='%s' hash='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\tfullPath, hash, dumpPath, err)\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.hash.match.dump file='%s' hash='%s' target='%s'):\\n\",\n\t\t\t\t\t\tfullPath, hash, dumpPath)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor _, cpm := range changePathMatchers {\n\t\t\tif cpm.PathPattern != \"\" {\n\t\t\t\tpmatch, err := doublestar.Match(cpm.PathPattern, fullPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"doublestar.Match name='%s' error=%v\", fullPath, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif !pmatch {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tobject.PathMatch = true\n\t\t\t\tlayer.pathMatches = true\n\n\t\t\t\tif cpm.Dump && cpm.DumpConsole {\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.path.match.start\\n\")\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.path.match file='%s' ppattern='%s')\\n\",\n\t\t\t\t\t\tfullPath, cpm.PathPattern)\n\t\t\t\t\tfmt.Printf(\"%s\\n\", string(data))\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.path.match.end\\n\")\n\t\t\t\t}\n\n\t\t\t\tif cpm.Dump && cpm.DumpDir != \"\" {\n\t\t\t\t\tdumpPath := filepath.Join(cpm.DumpDir, fullPath)\n\t\t\t\t\tdirPath := fsutil.FileDir(dumpPath)\n\t\t\t\t\tif !fsutil.DirExists(dirPath) {\n\t\t\t\t\t\terr := os.MkdirAll(dirPath, 0755)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.path.match.dump.error file='%s' ppattern='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\t\tfullPath, cpm.PathPattern, dumpPath, err)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\terr := os.WriteFile(dumpPath, data, 0644)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.path.match.dump.error file='%s' ppattern='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\tfullPath, cpm.PathPattern, dumpPath, err)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.path.match.dump file='%s' ppattern='%s' target='%s'):\\n\",\n\t\t\t\t\t\tfullPath, cpm.PathPattern, dumpPath)\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tfor _, cdm := range changeDataMatchers {\n\t\t\tif cdm.PathPattern != \"\" {\n\t\t\t\tpmatch, err := doublestar.Match(cdm.PathPattern, fullPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"doublestar.Match name='%s' error=%v\", fullPath, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif !pmatch {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif cdm.Matcher.Match(data) {\n\t\t\t\tlayer.DataMatches[fullPath] = append(layer.DataMatches[fullPath], cdm)\n\n\t\t\t\tif cdm.Dump {\n\t\t\t\t\tif cdm.DumpConsole {\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.match.start\\n\")\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.match file='%s' ppattern='%s' dpattern='%s')\\n\",\n\t\t\t\t\t\t\tfullPath, cdm.PathPattern, cdm.DataPattern)\n\t\t\t\t\t\tfmt.Printf(\"%s\\n\", string(data))\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.match.end\\n\")\n\t\t\t\t\t}\n\n\t\t\t\t\tif cdm.DumpDir != \"\" {\n\t\t\t\t\t\tdumpPath := filepath.Join(cdm.DumpDir, fullPath)\n\t\t\t\t\t\tdirPath := fsutil.FileDir(dumpPath)\n\t\t\t\t\t\tif !fsutil.DirExists(dirPath) {\n\t\t\t\t\t\t\terr := os.MkdirAll(dirPath, 0755)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.match.dump.error file='%s' ppattern='%s' dpattern='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\t\t\tfullPath, cdm.PathPattern, cdm.DataPattern, dumpPath, err)\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\terr := os.WriteFile(dumpPath, data, 0644)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.match.dump.error file='%s' ppattern='%s' dpattern='%s' target='%s' error='%s'):\\n\",\n\t\t\t\t\t\t\t\tfullPath, cdm.PathPattern, cdm.DataPattern, dumpPath, err)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfmt.Printf(\"cmd=xray info=change.data.match.dump file='%s' ppattern='%s' dpattern='%s' target='%s'):\\n\",\n\t\t\t\t\t\t\tfullPath, cdm.PathPattern, cdm.DataPattern, dumpPath)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t//TODO:\n\t\t\t\t//add a flag to do first match only\n\t\t\t\t//now we'll try to match all data patterns\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor _, cpm := range changePathMatchers {\n\t\t\tif cpm.PathPattern != \"\" {\n\t\t\t\tpmatch, err := doublestar.Match(cpm.PathPattern, fullPath)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"doublestar.Match name='%s' error=%v\", fullPath, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif pmatch {\n\t\t\t\t\tobject.PathMatch = true\n\t\t\t\t\tlayer.pathMatches = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar hash string\n\t\tif doHashData || len(changeDataHashMatchers) > 0 {\n\t\t\tvar err error\n\t\t\thash, err = getStreamHash(reader)\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"inspectFile: getStreamHash error - name='%s' error=%v\", fullPath, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif doHashData {\n\t\t\tobject.Hash = hash\n\t\t}\n\n\t\tif len(hash) > 0 && len(changeDataHashMatchers) > 0 {\n\t\t\tif dhm, found := changeDataHashMatchers[hash]; found {\n\t\t\t\t//need to save to DataHashMatches to make it work without generating/saving hashes for all objects\n\t\t\t\tlayer.DataHashMatches[fullPath] = dhm\n\n\t\t\t\tif dhm.Dump {\n\t\t\t\t\tlog.Errorf(\"inspectFile: should not dump - %#v\", dhm)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc jsonFromStream(source string, name string, reader io.Reader, data interface{}) error {\n\traw, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsr := strings.NewReader(string(raw))\n\tlog.Tracef(\"dockerimage.LoadPackage.jsonFromStream: name='%s' data[%d]='%s' source='%s'\",\n\t\tname, len(raw), string(raw), source)\n\n\treturn json.NewDecoder(sr).Decode(data)\n}\n\ntype TarReadCloser struct {\n\tio.Reader\n\tio.Closer\n}\n\nfunc FileReaderFromTar(tarPath, filePath string) (io.ReadCloser, error) {\n\ttfile, err := os.Open(tarPath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerimage.FileReaderFromTar: os.Open error - %v\", err)\n\t\treturn nil, err\n\t}\n\n\tdefer tfile.Close()\n\ttr := tar.NewReader(tfile)\n\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif hdr == nil || hdr.Name == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\thdr.Name = filepath.Clean(hdr.Name)\n\t\tif hdr.Name == filePath {\n\t\t\tswitch hdr.Typeflag {\n\t\t\tcase tar.TypeReg, tar.TypeSymlink, tar.TypeLink:\n\t\t\t\treturn TarReadCloser{\n\t\t\t\t\tReader: tr,\n\t\t\t\t\tCloser: tfile,\n\t\t\t\t}, nil\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"no file - %s\", filePath)\n}\n\nfunc FileDataFromTar(tarPath, filePath string) ([]byte, error) {\n\ttfile, err := os.Open(tarPath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerimage.FileDataFromTar: os.Open error - %v\", err)\n\t\treturn nil, err\n\t}\n\n\tdefer tfile.Close()\n\ttr := tar.NewReader(tfile)\n\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif hdr == nil || hdr.Name == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\thdr.Name = filepath.Clean(hdr.Name)\n\t\tif hdr.Name == filePath {\n\t\t\tswitch hdr.Typeflag {\n\t\t\tcase tar.TypeReg, tar.TypeSymlink, tar.TypeLink:\n\t\t\t\treturn io.ReadAll(tr)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"no file - %s\", filePath)\n}\n\nfunc LoadManifestObject(archivePath, imageID string) (*DockerManifestObject, error) {\n\treturn nil, nil\n}\n\nfunc LoadConfigObject(archivePath, imageID string) (*ConfigObject, error) {\n\treturn nil, nil\n}\n\nfunc LoadLayer(archivePath, imageID, layerID string) (*Layer, error) {\n\treturn nil, nil\n}\n"
  },
  {
    "path": "pkg/docker/dockerimage/imagelayout.go",
    "content": "package dockerimage\n\nconst (\n\tdockerManifestFileName = \"manifest.json\"\n\tdockerReposFileName    = \"repositories\"\n\n\t//dockerV1 config object file name: <IMAGE_ID>.json\n\tdockerV1LayerSuffix = \"/layer.tar\"\n)\n\nconst (\n\tociLayoutFileName = \"oci-layout\"\n\tociLayoutVersion  = \"1.0.0\"\n\tociIndexFileName  = \"index.json\"\n\tociBlobDirName    = \"blobs\"\n\tociBlobDirPrefix  = \"blobs/\"\n)\n\ntype OCILayout struct {\n\tVersion string `json:\"imageLayoutVersion\"`\n}\n"
  },
  {
    "path": "pkg/docker/dockerimage/metadata.go",
    "content": "package dockerimage\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n)\n\n// pkg/system/architecture.go has architecture enums,\n// but the enums are not always identical\nconst (\n\tOSLinux   = \"linux\"\n\tDefaultOS = OSLinux\n\n\tArchARM     = \"arm\"\n\tArchARM64   = \"arm64\"\n\tArchAMD64   = \"amd64\"\n\tDefaultArch = ArchAMD64\n)\n\nfunc DefaultRuntimeArch() string {\n\treturn runtime.GOARCH\n}\n\n// focusing on the primary OS and architectures (ignoring the rest)\n\nvar ArchVarMap = map[string][]string{\n\tArchARM:   {\"\", \"v6\", \"v7\", \"v8\"},\n\tArchARM64: {\"\", \"v8\"},\n\tArchAMD64: {\"\"},\n}\n\nfunc IsValidArchitecture(arch string, variant string) bool {\n\tfor varch, vvariants := range ArchVarMap {\n\t\tif varch == arch {\n\t\t\tfor _, vvariant := range vvariants {\n\t\t\t\tif vvariant == variant {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn false\n}\n\nvar OSArchMap = map[string][]string{\n\tOSLinux: {\n\t\t\"386\",\n\t\tArchAMD64,\n\t\tArchARM,\n\t\tArchARM64,\n\t\t\"ppc64\",\n\t\t\"ppc64le\",\n\t\t\"mips64\",\n\t\t\"mips64le\",\n\t\t\"s390x\",\n\t\t\"riscv64\"},\n}\n\nfunc IsValidPlatform(os string, arch string) bool {\n\tfor vos, varchs := range OSArchMap {\n\t\tif vos == os {\n\t\t\tfor _, varch := range varchs {\n\t\t\t\tif varch == arch {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn false\n}\n\n// v1 and oci-based Manifest structure is the same* / compatible\n// but config and layer paths are different\ntype DockerManifestObject struct {\n\t// v1 format:  \"IMAGE_ID.json\" (no sha256 prefix in IMAGE_ID)\n\t// oci format: \"blobs/sha256/DIGEST_NO_PREFIX\"\n\tConfig   string\n\tRepoTags []string `json:\",omitempty\"` //[\"user/repo:tag\"]\n\t// v1 format:  \"LAYER_ID/layer.tar\" (no sha256 prefix in LAYER_ID)\n\t// oci format: \"blobs/sha256/DIGEST\" (no sha256 prefix in DIGEST)\n\tLayers []string\n\n\t// newer fields\n\n\tParent string `json:\",omitempty\"`\n\t// DiffID map (where DiffID does have the \"sha256:\" prefix)\n\tLayerSources map[string]BlobDescriptor `json:\",omitempty\"`\n}\n\n// can reuse the 'Descriptor' for 'BlobDescriptor' from github.com/opencontainers/image-spec/specs-go/v1\n\ntype BlobDescriptor struct {\n\tMediaType string `json:\"mediaType,omitempty\"`\n\tSize      int64  `json:\"size,omitempty\"`\n\tDigest    string `json:\"digest,omitempty\"`\n\n\t// extra fields\n\tAnnotations map[string]string `json:\"annotations,omitempty\"`\n\tURLs        []string          `json:\"urls,omitempty\"`\n\tPlatform    *Platform         `json:\"platform,omitempty\"`\n}\n\n// todo: can reuse 'Platform' from github.com/opencontainers/image-spec/specs-go/v1\n\ntype Platform struct {\n\tArchitecture string   `json:\"architecture\"`\n\tOS           string   `json:\"os\"`\n\tOSVersion    string   `json:\"os.version,omitempty\"`\n\tOSFeatures   []string `json:\"os.features,omitempty\"`\n\tVariant      string   `json:\"variant,omitempty\"`\n}\n\n// data structures from https://github.com/moby/moby/blob/master/image\n\ntype V1ConfigObject struct {\n\t// ID is a unique 64 character identifier of the image\n\tID string `json:\"id,omitempty\"`\n\t// Parent is the ID of the parent image\n\tParent string `json:\"parent,omitempty\"`\n\t// Comment is the commit message that was set when committing the image\n\tComment string `json:\"comment,omitempty\"`\n\t// Created is the timestamp at which the image was created\n\tCreated time.Time `json:\"created\"`\n\t// Container is the id of the container used to commit\n\tContainer string `json:\"container,omitempty\"`\n\t// ContainerConfig is the configuration of the container that is committed into the image\n\tContainerConfig ContainerConfig `json:\"container_config,omitempty\"`\n\t// DockerVersion specifies the version of Docker that was used to build the image\n\tDockerVersion string `json:\"docker_version,omitempty\"`\n\t// Author is the name of the author that was specified when committing the image\n\tAuthor string `json:\"author,omitempty\"`\n\t// Config is the configuration of the container received from the client\n\tConfig *ContainerConfig `json:\"config,omitempty\"`\n\t// Architecture is the hardware that the image is built and runs on\n\tArchitecture string `json:\"architecture,omitempty\"`\n\t// Variant is the CPU architecture variant (presently ARM-only)\n\tVariant string `json:\"variant,omitempty\"`\n\t// OS is the operating system used to build and run the image\n\tOS string `json:\"os,omitempty\"`\n\t// Size is the total size of the image including all layers it is composed of\n\tSize int64 `json:\",omitempty\"`\n}\n\ntype ConfigObject struct {\n\tV1ConfigObject\n\tParent     string     `json:\"parent,omitempty\"` //nolint:govet\n\tRootFS     *RootFS    `json:\"rootfs,omitempty\"`\n\tHistory    []XHistory `json:\"history,omitempty\"`\n\tOSVersion  string     `json:\"os.version,omitempty\"`\n\tOSFeatures []string   `json:\"os.features,omitempty\"`\n\n\t//buildkit build info\n\tBuildInfoRaw     string `json:\"moby.buildkit.buildinfo.v1,omitempty\"`\n\tBuildInfoDecoded *BuildKitBuildInfo\n}\n\n//data structures from https://github.com/moby/moby/blob/master/image/rootfs.go\n\nconst TypeLayers = \"layers\"\n\ntype RootFS struct {\n\tType    string   `json:\"type\"`\n\tDiffIDs []string `json:\"diff_ids,omitempty\"`\n}\n\n//data structures from https://github.com/moby/moby/blob/master/image/image.go\n\n// XHistory augments the standard History struct with extra layer info\ntype XHistory struct {\n\t// Created is the timestamp at which the image was created\n\tCreated time.Time `json:\"created\"`\n\t// Author is the name of the author that was specified when committing the image\n\tAuthor string `json:\"author,omitempty\"`\n\t// CreatedBy keeps the Dockerfile command used while building the image\n\tCreatedBy string `json:\"created_by,omitempty\"`\n\t// Comment is the commit message that was set when committing the image\n\tComment string `json:\"comment,omitempty\"`\n\t// EmptyLayer is set to true if this history item did not generate a\n\t// layer. Otherwise, the history item is associated with the next\n\t// layer in the RootFS section.\n\tEmptyLayer bool `json:\"empty_layer,omitempty\"`\n\n\t//extra fields\n\n\tLayerID       string `json:\"layer_id,omitempty\"`\n\tLayerIndex    int    `json:\"layer_index\"`\n\tLayerFSDiffID string `json:\"layer_fsdiff_id,omitempty\"`\n}\n\n//data structures from https://github.com/moby/moby/blob/master/api/types/container/config.go\n\ntype ContainerConfig struct {\n\tHostname        string              // Hostname\n\tDomainname      string              // Domainname\n\tUser            string              // User that will run the command(s) inside the container, also support user:group\n\tAttachStdin     bool                // Attach the standard input, makes possible user interaction\n\tAttachStdout    bool                // Attach the standard output\n\tAttachStderr    bool                // Attach the standard error\n\tExposedPorts    map[string]struct{} `json:\",omitempty\"` // List of exposed ports\n\tTty             bool                // Attach standard streams to a tty, including stdin if it is not closed.\n\tOpenStdin       bool                // Open stdin\n\tStdinOnce       bool                // If true, close stdin after the 1 attached client disconnects.\n\tEnv             []string            // List of environment variable to set in the container\n\tCmd             []string            // Command to run when starting the container\n\tHealthcheck     *HealthConfig       `json:\",omitempty\"` // Healthcheck describes how to check the container is healthy\n\tArgsEscaped     bool                `json:\",omitempty\"` // True if command is already escaped (meaning treat as a command line) (Windows specific).\n\tImage           string              // Name of the image as it was passed by the operator (e.g. could be symbolic)\n\tVolumes         map[string]struct{} // List of volumes (mounts) used for the container\n\tWorkingDir      string              // Current directory (PWD) in the command will be launched\n\tEntrypoint      []string            // Entrypoint to run when starting the container\n\tNetworkDisabled bool                `json:\",omitempty\"` // Is network disabled\n\tMacAddress      string              `json:\",omitempty\"` // Mac Address of the container\n\tOnBuild         []string            // ONBUILD metadata that were defined on the image Dockerfile\n\tLabels          map[string]string   // List of labels set to this container\n\tStopSignal      string              `json:\",omitempty\"` // Signal to stop a container\n\tStopTimeout     *int                `json:\",omitempty\"` // Timeout (in seconds) to stop a container\n\tShell           []string            `json:\",omitempty\"` // Shell for shell-form of RUN, CMD, ENTRYPOINT\n}\n\n//data structures from https://github.com/moby/moby/blob/master/api/types/container/config.go\n\ntype HealthConfig struct {\n\t// Test is the test to perform to check that the container is healthy.\n\t// An empty slice means to inherit the default.\n\t// The options are:\n\t// {} : inherit healthcheck\n\t// {\"NONE\"} : disable healthcheck\n\t// {\"CMD\", args...} : exec arguments directly\n\t// {\"CMD-SHELL\", command} : run command with system's default shell\n\tTest []string `json:\",omitempty\"`\n\n\t// Zero means to inherit. Durations are expressed as integer nanoseconds.\n\tInterval    time.Duration `json:\",omitempty\"` // Interval is the time to wait between checks.\n\tTimeout     time.Duration `json:\",omitempty\"` // Timeout is the time to wait before considering the check to have hung.\n\tStartPeriod time.Duration `json:\",omitempty\"` // The start period for the container to initialize before the retries starts to count down.\n\n\t// Retries is the number of consecutive failures needed to consider a container as unhealthy.\n\t// Zero means inherit.\n\tRetries int `json:\",omitempty\"`\n}\n\n//data structures from https://github.com/moby/buildkit/blob/master/util/buildinfo/types/types.go\n\ntype BuildKitBuildInfo struct {\n\t// Frontend defines the frontend used to build.\n\tFrontend string `json:\"frontend,omitempty\"`\n\t// Attrs defines build request attributes.\n\tAttrs map[string]*string `json:\"attrs,omitempty\"`\n\t// Sources defines build dependencies.\n\tSources []*BuildSource `json:\"sources,omitempty\"`\n\t// Deps defines context dependencies.\n\tDeps map[string]BuildKitBuildInfo `json:\"deps,omitempty\"`\n}\n\ntype BuildSource struct {\n\t// Type defines the SourceType source type (docker-image, git, http).\n\tType SourceType `json:\"type,omitempty\"`\n\t// Ref is the reference of the source.\n\tRef string `json:\"ref,omitempty\"`\n\t// Alias is a special field used to match with the actual source ref\n\t// because frontend might have already transformed a string user typed\n\t// before generating LLB.\n\tAlias string `json:\"alias,omitempty\"`\n\t// Pin is the source digest.\n\tPin string `json:\"pin,omitempty\"`\n}\n\ntype SourceType string\n\nconst (\n\tSourceTypeDockerImage SourceType = \"docker-image\"\n\tSourceTypeGit         SourceType = \"git\"\n\tSourceTypeHTTP        SourceType = \"http\"\n)\n\nfunc buildInfoDecode(encoded string) (*BuildKitBuildInfo, error) {\n\tif encoded == \"\" {\n\t\treturn nil, nil\n\t}\n\n\traw, err := base64.StdEncoding.DecodeString(encoded)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar info BuildKitBuildInfo\n\tif err = json.Unmarshal(raw, &info); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &info, nil\n}\n\n// consts from https://github.com/moby/moby/blob/master/pkg/archive/whiteouts.go\n\n// WhiteoutPrefix prefix means file is a whiteout. If this is followed by a\n// filename this means that file has been removed from the base layer.\nconst WhiteoutPrefix = \".wh.\"\n\n// WhiteoutMetaPrefix prefix means whiteout has a special meaning and is not\n// for removing an actual file. Normally these files are excluded from exported\n// archives.\nconst WhiteoutMetaPrefix = WhiteoutPrefix + WhiteoutPrefix\n\n// WhiteoutLinkDir is a directory AUFS uses for storing hardlink links to other\n// layers. Normally these should not go into exported archives and all changed\n// hardlinks should be copied to the top layer.\nconst WhiteoutLinkDir = WhiteoutMetaPrefix + \"plnk\"\n\n// WhiteoutOpaqueDir file means directory has been made opaque - meaning\n// readdir calls to this directory do not follow to lower layers.\nconst WhiteoutOpaqueDir = WhiteoutMetaPrefix + \".opq\"\n\nfunc IsDeletedFileObject(path string) bool {\n\tname := filepath.Base(path)\n\treturn strings.HasPrefix(name, WhiteoutPrefix)\n}\n\nfunc NormalizeFileObjectLayerPath(path string) (string, bool, bool, error) {\n\tisDeleted := false\n\tname := filepath.Base(path)\n\tif name == WhiteoutOpaqueDir {\n\t\t//return a fake wildcard delete path for now (to make it easy to detect)\n\t\treturn filepath.Join(filepath.Dir(path), \"*\"), true, true, nil\n\t}\n\n\tif strings.HasPrefix(name, WhiteoutPrefix) {\n\t\trestored := name[len(WhiteoutPrefix):]\n\t\tdir := filepath.Dir(path)\n\t\tisDeleted = true\n\t\tpath = filepath.Join(dir, restored)\n\t}\n\n\treturn path, isDeleted, false, nil\n}\n"
  },
  {
    "path": "pkg/docker/dockerimage/packagefiles.go",
    "content": "package dockerimage\n\nimport (\n\t\"archive/tar\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nconst (\n\tDirType        = \"dir\"\n\tFileType       = \"file\"\n\tSymlinkType    = \"symlink\"\n\tHardlinkType   = \"hardlink\"\n\tOtherType      = \"other\"\n\tUnknownType    = \"unknown\"\n\tUnexpectedType = \"unexpected\"\n)\n\nfunc ObjectTypeFromTarType(flag byte) string {\n\tswitch flag {\n\tcase tar.TypeDir:\n\t\treturn DirType\n\tcase tar.TypeReg, tar.TypeRegA:\n\t\treturn FileType\n\tcase tar.TypeSymlink:\n\t\treturn SymlinkType\n\tcase tar.TypeLink:\n\t\treturn HardlinkType\n\tdefault:\n\t\treturn fmt.Sprintf(\"other(%v)\", flag)\n\t}\n}\n\nfunc TarHeaderTypeName(flag byte) string {\n\tswitch flag {\n\tcase tar.TypeReg:\n\t\treturn \"tar.TypeReg\"\n\tcase tar.TypeRegA:\n\t\treturn \"tar.TypeRegA\"\n\tcase tar.TypeLink:\n\t\treturn \"tar.TypeLink\"\n\tcase tar.TypeSymlink:\n\t\treturn \"tar.TypeSymlink\"\n\tcase tar.TypeChar:\n\t\treturn \"tar.TypeChar\"\n\tcase tar.TypeBlock:\n\t\treturn \"tar.TypeBlock\"\n\tcase tar.TypeDir:\n\t\treturn \"tar.TypeDir\"\n\tcase tar.TypeFifo:\n\t\treturn \"tar.TypeFifo\"\n\tdefault:\n\t\treturn fmt.Sprintf(\"other(%v)\", flag)\n\t}\n}\n\ntype PackageFiles struct {\n\timg       v1.Image\n\timgDigest string\n\timgID     string\n}\n\ntype LayerMetadata struct {\n\tIndex     int    `json:\"index,omitempty\"`\n\tDigest    string `json:\"digest,omitempty\"`\n\tDiffID    string `json:\"diff_id,omitempty\"`\n\tMediaType string `json:\"media_type,omitempty\"`\n\tSize      int64  `json:\"size,omitempty\"`\n}\n\ntype FileSelectorType string\n\nconst (\n\tFSTAll        FileSelectorType = \"fst.all\"\n\tFSTDigest     FileSelectorType = \"fst.digest\"\n\tFSTDiffID     FileSelectorType = \"fst.diffid\"\n\tFSTIndex      FileSelectorType = \"fst.index\"\n\tFSTIndexRange FileSelectorType = \"fst.index.range\"\n)\n\ntype FileSelector struct {\n\tType              FileSelectorType\n\tKey               string\n\tIndexKey          int\n\tIndexEndKey       int\n\tReverseIndexRange bool\n\tRawNames          bool\n\tNoDirs            bool\n\tDeleted           bool\n}\n\ntype FileMetadata struct {\n\tType       string      `json:\"type,omitempty\"`\n\tIsDir      bool        `json:\"is_dir,omitempty\"`\n\tIsDelete   bool        `json:\"is_delete,omitempty\"`\n\tIsOpq      bool        `json:\"is_opq,omitempty\"`\n\tName       string      `json:\"name,omitempty\"`\n\tRawName    string      `json:\"raw_name,omitempty\"`\n\tSize       int64       `json:\"size,omitempty\"`\n\tMode       os.FileMode `json:\"mode,omitempty\"`\n\tUID        int         `json:\"uid\"`\n\tGID        int         `json:\"gid\"`\n\tModTime    time.Time   `json:\"mod_time,omitempty\"`\n\tChangeTime time.Time   `json:\"change_time,omitempty\"`\n}\n\ntype LayerFiles struct {\n\tLayer *LayerMetadata  `json:\"layer\"`\n\tFiles []*FileMetadata `json:\"files\"`\n}\n\nfunc NewPackageFiles(archivePath string) (*PackageFiles, error) {\n\timg, err := tarball.ImageFromPath(archivePath, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdigest, err := img.Digest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcfgName, err := img.ConfigName()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tref := &PackageFiles{\n\t\timg:       img,\n\t\timgDigest: digest.String(),\n\t\timgID:     cfgName.String(),\n\t}\n\n\treturn ref, nil\n}\n\nfunc (ref *PackageFiles) ImageDigest() string {\n\treturn ref.imgDigest\n}\n\nfunc (ref *PackageFiles) ImageID() string {\n\treturn ref.imgID\n}\n\nfunc (ref *PackageFiles) ListImageHistory() ([]XHistory, error) {\n\tconfigFile, err := ref.img.ConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar list []XHistory\n\tfor _, record := range configFile.History {\n\t\tinfo := XHistory{\n\t\t\tCreated:    record.Created.Time,\n\t\t\tCreatedBy:  record.CreatedBy,\n\t\t\tComment:    record.Comment,\n\t\t\tEmptyLayer: record.EmptyLayer,\n\t\t\tAuthor:     record.Author,\n\t\t}\n\n\t\tlist = append(list, info)\n\t}\n\n\treturn list, nil\n}\n\nfunc (ref *PackageFiles) LayerCount() int {\n\tlayers, _ := ref.img.Layers()\n\treturn len(layers)\n}\n\nfunc (ref *PackageFiles) ListLayerMetadata() ([]*LayerMetadata, error) {\n\tlayers, err := ref.img.Layers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar list []*LayerMetadata\n\tfor idx, layer := range layers {\n\t\tdigest, _ := layer.Digest()\n\t\tdiffID, _ := layer.DiffID()\n\t\tsize, _ := layer.Size()\n\t\tmediaType, _ := layer.MediaType()\n\n\t\tlayerInfo := &LayerMetadata{\n\t\t\tIndex:     idx,\n\t\t\tDigest:    digest.String(),\n\t\t\tDiffID:    diffID.String(),\n\t\t\tMediaType: string(mediaType),\n\t\t\tSize:      size,\n\t\t}\n\n\t\tlist = append(list, layerInfo)\n\t}\n\n\treturn list, nil\n}\n\nfunc (ref *PackageFiles) ListLayerFiles(selectors []FileSelector) ([]*LayerFiles, error) {\n\t//layersMetadata (by index)\n\tlayersMetadata, err := ref.ListLayerMetadata()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlayers, err := ref.img.Layers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlayersMetadataByDigest := map[string]*LayerMetadata{}\n\tlayersMetadataByDiffID := map[string]*LayerMetadata{}\n\tfor _, lmInfo := range layersMetadata {\n\t\tif lmInfo.Digest != \"\" {\n\t\t\tlayersMetadataByDigest[lmInfo.Digest] = lmInfo\n\t\t}\n\n\t\tif lmInfo.DiffID != \"\" {\n\t\t\tlayersMetadataByDiffID[lmInfo.DiffID] = lmInfo\n\t\t}\n\t}\n\n\tlayerSelectors := map[string]FileSelector{}\n\tfor _, selector := range selectors {\n\t\tswitch selector.Type {\n\t\tcase FSTAll:\n\t\t\tfor k := range layersMetadataByDiffID {\n\t\t\t\t//todo: create a deep selector copy\n\t\t\t\tlayerSelectors[k] = selector\n\t\t\t}\n\t\tcase FSTDigest:\n\t\t\tif selector.Key != \"\" {\n\t\t\t\tif info, found := layersMetadataByDigest[selector.Key]; found {\n\t\t\t\t\tlayerSelectors[info.DiffID] = selector\n\t\t\t\t}\n\t\t\t}\n\t\tcase FSTDiffID:\n\t\t\tif selector.Key != \"\" {\n\t\t\t\tif info, found := layersMetadataByDiffID[selector.Key]; found {\n\t\t\t\t\tlayerSelectors[info.DiffID] = selector\n\t\t\t\t}\n\t\t\t}\n\t\tcase FSTIndex:\n\t\t\tif (selector.IndexKey >= 0) &&\n\t\t\t\t(selector.IndexKey < len(layersMetadata)) {\n\t\t\t\tlayerSelectors[layersMetadata[selector.IndexKey].DiffID] = selector\n\t\t\t}\n\t\tcase FSTIndexRange:\n\t\t\tif selector.ReverseIndexRange {\n\t\t\t\tif (selector.IndexKey >= 0) &&\n\t\t\t\t\t(selector.IndexKey < len(layersMetadata)) &&\n\t\t\t\t\t(selector.IndexEndKey >= 0) &&\n\t\t\t\t\t(selector.IndexEndKey < len(layersMetadata)) {\n\t\t\t\t\tif selector.IndexEndKey > selector.IndexKey {\n\t\t\t\t\t\tfor i := selector.IndexKey; i <= selector.IndexEndKey; i++ {\n\t\t\t\t\t\t\trindex := len(layersMetadata) - 1 - i\n\t\t\t\t\t\t\tif rindex >= 0 {\n\t\t\t\t\t\t\t\tlayerSelectors[layersMetadata[rindex].DiffID] = selector\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} else {\n\t\t\t\tif (selector.IndexKey >= 0) &&\n\t\t\t\t\t(selector.IndexKey < len(layersMetadata)) {\n\t\t\t\t\tif selector.IndexEndKey < 0 {\n\t\t\t\t\t\t//means 'until the last index'\n\t\t\t\t\t\tselector.IndexEndKey = len(layersMetadata) - 1\n\t\t\t\t\t}\n\n\t\t\t\t\tif (selector.IndexEndKey >= 0) &&\n\t\t\t\t\t\t(selector.IndexEndKey < len(layersMetadata)) {\n\t\t\t\t\t\tif selector.IndexEndKey > selector.IndexKey {\n\t\t\t\t\t\t\tfor i := selector.IndexKey; i <= selector.IndexEndKey; i++ {\n\t\t\t\t\t\t\t\tlayerSelectors[layersMetadata[i].DiffID] = selector\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}\n\t}\n\n\tlayerFilesByDiff := map[string]*LayerFiles{}\n\tfor _, layer := range layers {\n\t\tdiffID, _ := layer.DiffID()\n\t\tdiffIDStr := diffID.String()\n\t\tlayerSelector, found := layerSelectors[diffIDStr]\n\t\tif !found {\n\t\t\tcontinue\n\t\t}\n\n\t\tlayerInfo, found := layersMetadataByDiffID[diffIDStr]\n\t\tif !found {\n\t\t\tcontinue\n\t\t}\n\n\t\tcurrentLayerFiles := &LayerFiles{\n\t\t\tLayer: layerInfo,\n\t\t}\n\n\t\tucr, err := layer.Uncompressed()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tdefer ucr.Close()\n\t\tltr := tar.NewReader(ucr)\n\n\t\tfor {\n\t\t\tlayerHeader, err := ltr.Next()\n\t\t\tif err != nil {\n\t\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tinfo := getFileMetadata(layerHeader)\n\t\t\tif info == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif layerSelector.NoDirs && info.IsDir {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !layerSelector.Deleted && (info.IsDelete || info.IsOpq) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcurrentLayerFiles.Files = append(currentLayerFiles.Files, info)\n\t\t}\n\n\t\tlayerFilesByDiff[diffIDStr] = currentLayerFiles\n\t}\n\n\tvar layerFiles []*LayerFiles\n\tfor _, v := range layerFilesByDiff {\n\t\tlayerFiles = append(layerFiles, v)\n\t}\n\n\treturn layerFiles, nil\n}\n\nfunc getFileMetadata(header *tar.Header) *FileMetadata {\n\tif header == nil || header.Name == \"\" {\n\t\treturn nil\n\t}\n\n\tvar isDir bool\n\tif header.Typeflag == tar.TypeDir {\n\t\tisDir = true\n\t}\n\n\tfileName := filepath.Clean(header.Name)\n\tif fileName != \"\" && fileName[0] != '/' {\n\t\tfileName = fmt.Sprintf(\"/%s\", fileName)\n\t}\n\n\trawFileName := fileName\n\tbname := filepath.Base(fileName)\n\tdname := filepath.Dir(fileName)\n\tisDelete := strings.HasPrefix(bname, whPrefix)\n\tvar isOpq bool\n\tif isDelete {\n\t\tif bname == whOpaqueDir {\n\t\t\tisd := header.Typeflag == tar.TypeDir\n\t\t\tlog.Debugf(\"dockerimage.getFileMetadata - special name: %s (header.Typeflag=%v/%s) / isd=%v\", bname, header.Typeflag, TarHeaderTypeName(header.Typeflag), isd)\n\t\t\tisOpq = true\n\t\t\tisDelete = false\n\t\t\tfileName = dname\n\t\t} else {\n\t\t\tbname = bname[len(whPrefix):]\n\n\t\t\tif header.Typeflag != tar.TypeDir {\n\t\t\t\tfileName = filepath.Join(dname, bname)\n\t\t\t}\n\t\t}\n\t}\n\n\tresult := &FileMetadata{\n\t\tType:       ObjectTypeFromTarType(header.Typeflag),\n\t\tIsDir:      isDir,\n\t\tIsDelete:   isDelete,\n\t\tIsOpq:      isOpq,\n\t\tName:       fileName,\n\t\tSize:       header.Size,\n\t\tMode:       header.FileInfo().Mode(),\n\t\tUID:        header.Uid,\n\t\tGID:        header.Gid,\n\t\tModTime:    header.ModTime,\n\t\tChangeTime: header.ChangeTime,\n\t}\n\n\tif isDelete || isOpq {\n\t\tresult.RawName = rawFileName\n\t}\n\n\treturn result\n}\n\n// TODO: use already defined constants\nconst (\n\twhPrefix          = \".wh.\"\n\twhOpaqueDirSuffix = \".wh..opq\"\n\twhOpaqueDir       = whPrefix + whOpaqueDirSuffix\n)\n\n//FileDataFromTar\n//FileReaderFromTar\n\nfunc IsLayerMediaType(value types.MediaType) bool {\n\tswitch value {\n\tcase types.DockerLayer,\n\t\ttypes.DockerUncompressedLayer,\n\t\ttypes.OCILayer,\n\t\ttypes.OCIUncompressedLayer,\n\t\ttypes.OCILayerZStd:\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n/*\n\nNOTE:\nTAR FILE LIST INCLUDES EXTRAS\nLIKE INTERMEDIATE DIRECTORIES,\nWHITEOUT FILES,\nDIRECTORY WHITEOUT FILES\nNEED TO CLEAN UP THOSE THINGS WHEN GENERATING THE FILE LIST\nALSO HAVE A MODE TO INCLUDE/EXCLUDE INTERMEDIATE DIRECTORIES\n\n\nINPUT: IMAGE TAR FILE PATH\nOPTIONS/FLAGS (WHAT I WANT? / CAPABILITIES:\n* List files for the last X layers (note: this is a \"range\" call) - MVP (should i retain any extra meta data for layers, etc?)\n* List files for one specific layer (how to select? options: index, digest, fsdiffid)\n* List files for a set of layers\n* List all files - MAYBE\n (return a map of layers with lists/maps of files in each???) OR\n (return a global map of files with layer as a property???) OR\n (both or configurable to have either of these three options???)\n\n*/\n"
  },
  {
    "path": "pkg/docker/dockerimage/topobjects.go",
    "content": "package dockerimage\n\nimport (\n\t\"container/heap\"\n)\n\ntype TopObjects []*ObjectMetadata\n\nfunc NewTopObjects(n int) TopObjects {\n\tif n < 1 {\n\t\tn = 1\n\t}\n\tn++\n\treturn make(TopObjects, 0, n)\n}\n\nfunc (to TopObjects) Len() int { return len(to) }\n\nfunc (to TopObjects) Less(i, j int) bool {\n\treturn to[i].Size < to[j].Size\n}\n\nfunc (to TopObjects) Swap(i, j int) {\n\tto[i], to[j] = to[j], to[i]\n}\n\nfunc (to *TopObjects) Push(x interface{}) {\n\titem := x.(*ObjectMetadata)\n\t*to = append(*to, item)\n}\n\nfunc (to *TopObjects) Pop() interface{} {\n\told := *to\n\tn := len(old)\n\titem := old[n-1]\n\told[n-1] = nil\n\t*to = old[0 : n-1]\n\treturn item\n}\n\nfunc (to TopObjects) List() []*ObjectMetadata {\n\tlist := []*ObjectMetadata{}\n\tfor len(to) > 0 {\n\t\titem := heap.Pop(&to).(*ObjectMetadata)\n\t\tlist = append([]*ObjectMetadata{item}, list...)\n\t}\n\n\treturn list\n}\n"
  },
  {
    "path": "pkg/docker/dockerutil/dockerutil.go",
    "content": "package dockerutil\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/docker/docker/pkg/archive\"\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerclient\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nvar (\n\tErrBadParam = errors.New(\"bad parameter\")\n\tErrNotFound = errors.New(\"not found\")\n)\n\nconst (\n\tvolumeMountPat       = \"%s:/data\"\n\tvolumeBasePath       = \"/data\"\n\temptyImageName       = \"docker-slim-empty-image:latest\"\n\temptyImageDockerfile = \"FROM scratch\\nCMD\\n\"\n)\n\ntype BasicImageProps struct {\n\tID      string\n\tSize    int64\n\tCreated int64\n}\n\ntype ImageIdentity struct {\n\tID           string\n\tShortTags    []string\n\tRepoTags     []string\n\tShortDigests []string\n\tRepoDigests  []string\n}\n\nfunc APIImagesToIdentity(info *dockerapi.APIImages) *ImageIdentity {\n\timageInfo := &dockerapi.Image{\n\t\tID:          info.ID,\n\t\tRepoTags:    info.RepoTags,\n\t\tRepoDigests: info.RepoDigests,\n\t}\n\n\treturn ImageToIdentity(imageInfo)\n}\n\nfunc ImageToIdentity(info *dockerapi.Image) *ImageIdentity {\n\tresult := &ImageIdentity{\n\t\tID:          info.ID,\n\t\tRepoTags:    info.RepoTags,\n\t\tRepoDigests: info.RepoDigests,\n\t}\n\n\tuniqueTags := map[string]struct{}{}\n\tfor _, tag := range result.RepoTags {\n\t\tparts := strings.Split(tag, \":\")\n\t\tif len(parts) == 2 {\n\t\t\tuniqueTags[parts[1]] = struct{}{}\n\t\t}\n\t}\n\n\tfor k := range uniqueTags {\n\t\tresult.ShortTags = append(result.ShortTags, k)\n\t}\n\n\tuniqueDigests := map[string]struct{}{}\n\tfor _, digest := range result.RepoDigests {\n\t\tparts := strings.Split(digest, \"@\")\n\t\tif len(parts) == 2 {\n\t\t\tuniqueDigests[parts[1]] = struct{}{}\n\t\t}\n\t}\n\n\tfor k := range uniqueDigests {\n\t\tresult.ShortDigests = append(result.ShortDigests, k)\n\t}\n\n\treturn result\n}\n\nfunc CleanImageID(id string) string {\n\tif strings.HasPrefix(id, \"sha256:\") {\n\t\tid = strings.TrimPrefix(id, \"sha256:\")\n\t}\n\n\treturn id\n}\n\nfunc HasEmptyImage(dclient *dockerapi.Client) error {\n\t_, err := HasImage(dclient, emptyImageName)\n\treturn err\n}\n\nfunc HasImage(dclient *dockerapi.Client, imageRef string) (*ImageIdentity, error) {\n\t//NOTES:\n\t//ListImages doesn't filter by image ID (must use ImageInspect instead)\n\t//Check images by name:tag, full or partial image ID or name@digest\n\tif imageRef == \"\" || imageRef == \".\" || imageRef == \"..\" {\n\t\treturn nil, ErrBadParam\n\t}\n\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.HasImage(%s): dockerapi.NewClient() error = %v\", imageRef, err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\timageInfo, err := dclient.InspectImage(imageRef)\n\tif err != nil {\n\t\tif err == dockerapi.ErrNoSuchImage {\n\t\t\treturn nil, ErrNotFound\n\t\t}\n\n\t\treturn nil, err\n\t}\n\n\treturn ImageToIdentity(imageInfo), nil\n}\n\nfunc ListImages(dclient *dockerapi.Client, imageNameFilter string) (map[string]BasicImageProps, error) {\n\t// python <- exact match only\n\t// py* <- all image names starting with 'py' (no/default namespace)\n\t// dslimexamples/* <- all image names in the 'dslimexamples' namespace\n\t// dslimexamples/ser* <- all image names starting with 'ser' in the 'dslimexamples' namespace\n\t// dslimexamples/*python* <- all image names with 'python' in them in the 'dslimexamples' namespace\n\t// */*python* <- all image names with 'python' in them in all namesapces (except the default namespace)\n\t// */*alpine <- all image names ending with 'alpine' in all namesapces (except the default namespace)\n\t// * <- all image names with no/default namespace. note that no images with namespaces will be returned\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.ListImages(%s): dockerapi.NewClient() error = %v\", imageNameFilter, err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tlistOptions := dockerapi.ListImagesOptions{\n\t\tAll: false,\n\t}\n\n\tif imageNameFilter != \"\" {\n\t\tlistOptions.Filters = map[string][]string{\n\t\t\t\"reference\": {imageNameFilter},\n\t\t}\n\t}\n\n\timageList, err := dclient.ListImages(listOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.ListImages(%s): dockerapi.ListImages() error = %v\", imageNameFilter, err)\n\t\treturn nil, err\n\t}\n\n\tlog.Debugf(\"dockerutil.ListImages(%s): matching images - %+v\", imageNameFilter, imageList)\n\n\timages := map[string]BasicImageProps{}\n\tfor _, imageInfo := range imageList {\n\t\tfor _, repo := range imageInfo.RepoTags {\n\t\t\tinfo := BasicImageProps{\n\t\t\t\tID:      strings.TrimPrefix(imageInfo.ID, \"sha256:\"),\n\t\t\t\tSize:    imageInfo.Size,\n\t\t\t\tCreated: imageInfo.Created,\n\t\t\t}\n\n\t\t\tif repo == \"<none>:<none>\" {\n\t\t\t\trepo = strings.TrimPrefix(imageInfo.ID, \"sha256:\")\n\t\t\t\timages[repo] = info\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\timages[repo] = info\n\t\t}\n\t}\n\n\treturn images, nil\n}\n\nfunc BuildEmptyImage(dclient *dockerapi.Client) error {\n\t//TODO: use the 'internal' build engine that doesn't need Docker\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\t//note: shouldn't use \":=\" here to avoid var shadowing\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.BuildEmptyImage: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tvar input bytes.Buffer\n\ttw := tar.NewWriter(&input)\n\theader := tar.Header{\n\t\tName: \"Dockerfile\",\n\t\tSize: int64(len(emptyImageDockerfile)),\n\t}\n\n\tif err := tw.WriteHeader(&header); err != nil {\n\t\treturn err\n\t}\n\n\tif _, err := tw.Write([]byte(emptyImageDockerfile)); err != nil {\n\t\treturn err\n\t}\n\n\tif err := tw.Close(); err != nil {\n\t\treturn err\n\t}\n\n\tvar output bytes.Buffer\n\tbuildOptions := dockerapi.BuildImageOptions{\n\t\tName:                emptyImageName,\n\t\tInputStream:         &input,\n\t\tOutputStream:        &output,\n\t\tRmTmpContainer:      true,\n\t\tForceRmTmpContainer: true,\n\t}\n\tif err := dclient.BuildImage(buildOptions); err != nil {\n\t\tlog.Errorf(\"dockerutil.BuildEmptyImage: dockerapi.BuildImage() error = %v / output: %s\", err, output.String())\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc SaveImage(dclient *dockerapi.Client, imageRef, local string, extract, removeOrig bool) error {\n\tif local == \"\" {\n\t\treturn ErrBadParam\n\t}\n\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.SaveImage: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\timageRef = CleanImageID(imageRef)\n\n\t//todo: 'pull' the image if it's not available locally yet\n\t//note: HasImage() doesn't work with image IDs\n\n\tdir := fsutil.FileDir(local)\n\tif !fsutil.DirExists(dir) {\n\t\terr := os.MkdirAll(dir, 0755)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tdfile, err := os.Create(local)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\toptions := dockerapi.ExportImageOptions{\n\t\tName:              imageRef,\n\t\tOutputStream:      dfile,\n\t\tInactivityTimeout: 20 * time.Second,\n\t}\n\n\terr = dclient.ExportImage(options)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.SaveImage: dclient.ExportImage() error = %v\", err)\n\t\tdfile.Close()\n\t\treturn err\n\t}\n\n\tdfile.Close()\n\n\tif extract {\n\t\tdstDir := filepath.Dir(local)\n\t\tarc := archive.NewDefaultArchiver()\n\n\t\tafile, err := os.Open(local)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.SaveImage: os.Open error - %v\", err)\n\t\t\treturn err\n\t\t}\n\n\t\ttarOptions := &archive.TarOptions{\n\t\t\tNoLchown: true,\n\t\t\t//UIDMaps:  arc.IDMapping.UIDs(),\n\t\t\t//GIDMaps:  arc.IDMapping.GIDs(),\n\n\t\t}\n\n\t\ttarOptions.IDMap.UIDMaps = arc.IDMapping.UIDMaps\n\t\ttarOptions.IDMap.GIDMaps = arc.IDMapping.GIDMaps\n\n\t\terr = arc.Untar(afile, dstDir, tarOptions)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.SaveImage: error unpacking tar - %v\", err)\n\t\t\tafile.Close()\n\t\t\treturn err\n\t\t}\n\n\t\tafile.Close()\n\n\t\tif removeOrig {\n\t\t\tos.Remove(local)\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype VolumeInfo struct {\n\tCreated    time.Time\n\tMountpoint string\n\tSize       uint64\n\tFileCount  uint64\n}\n\nfunc GetVolumeInfo(dclient *dockerapi.Client, name string, fileCount bool) (*VolumeInfo, error) {\n\tif name == \"\" {\n\t\treturn nil, ErrBadParam\n\t}\n\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.GetVolumeInfo: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvolume, err := dclient.InspectVolume(name)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.GetVolumeInfo: dclient.InspectVolume() error = %v\", err)\n\t\treturn nil, err\n\t}\n\n\tinfo := &VolumeInfo{\n\t\tCreated:    volume.CreatedAt,\n\t\tMountpoint: volume.Mountpoint,\n\t}\n\n\treturn info, nil\n}\n\nfunc ListVolumeFiles(dclient *dockerapi.Client, name string) ([]string, error) {\n\tif name == \"\" {\n\t\treturn nil, ErrBadParam\n\t}\n\n\treturn nil, nil\n}\n\nfunc VolumePathExists(dclient *dockerapi.Client, volume string, pth string) (bool, error) {\n\tif volume == \"\" || pth == \"\" {\n\t\treturn false, ErrBadParam\n\t}\n\n\treturn false, nil\n}\n\nfunc HasVolume(dclient *dockerapi.Client, name string) error {\n\tif name == \"\" {\n\t\treturn ErrBadParam\n\t}\n\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.HasVolume: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tlistOptions := dockerapi.ListVolumesOptions{\n\t\tFilters: map[string][]string{\"name\": {name}},\n\t}\n\n\tvolumes, err := dclient.ListVolumes(listOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.HasVolume: dclient.ListVolumes() error = %v\", err)\n\t\treturn err\n\t}\n\n\tif len(volumes) == 0 {\n\t\tlog.Debugf(\"dockerutil.HasVolume: volume not found - %v\", name)\n\t\treturn ErrNotFound\n\t}\n\n\tfor _, info := range volumes {\n\t\tif info.Name == name {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn ErrNotFound\n}\n\nfunc DeleteVolume(dclient *dockerapi.Client, name string) error {\n\tif name == \"\" {\n\t\treturn ErrBadParam\n\t}\n\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\t//note: shouldn't use \":=\" here to avoid var shadowing\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.DeleteVolume: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := HasVolume(dclient, name); err == nil {\n\t\tremoveOptions := dockerapi.RemoveVolumeOptions{\n\t\t\tName:  name,\n\t\t\tForce: true,\n\t\t}\n\n\t\t//ok to call remove even if the volume isn't there\n\t\terr = dclient.RemoveVolumeWithOptions(removeOptions)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"dockerutil.DeleteVolume: dclient.RemoveVolumeWithOptions() error = %v\\n\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc CopyToVolume(\n\tdclient *dockerapi.Client,\n\tvolumeName string,\n\tsource string,\n\tdstRootDir string,\n\tdstTargetDir string) error {\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CopyToVolume: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tvolumeBinds := []string{fmt.Sprintf(volumeMountPat, volumeName)}\n\n\tcontainerOptions := dockerapi.CreateContainerOptions{\n\t\tName: volumeName, //todo: might be good to make it unique (to support concurrent copy op)\n\t\tConfig: &dockerapi.Config{\n\t\t\tImage:  emptyImageName,\n\t\t\tLabels: map[string]string{\"owner\": \"docker-slim\"},\n\t\t},\n\t\tHostConfig: &dockerapi.HostConfig{\n\t\t\tBinds: volumeBinds,\n\t\t},\n\t}\n\n\tcontainerInfo, err := dclient.CreateContainer(containerOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.CopyToVolume: dclient.CreateContainer() error = %v\", err)\n\t\treturn err\n\t}\n\n\tcontainerID := containerInfo.ID\n\tlog.Debugf(\"dockerutil.CopyToVolume: containerID - %v\", containerID)\n\n\trmContainer := func() {\n\t\tremoveOptions := dockerapi.RemoveContainerOptions{\n\t\t\tID:    containerID,\n\t\t\tForce: true,\n\t\t}\n\n\t\terr = dclient.RemoveContainer(removeOptions)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"dockerutil.CopyToVolume: dclient.RemoveContainer() error = %v\\n\", err)\n\t\t}\n\t}\n\n\tcleanSource, err := filepath.EvalSymlinks(source)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.CopyToVolume: filepath.EvalSymlinks(%s) error = %v\", source, err)\n\t\trmContainer()\n\t\treturn err\n\t}\n\n\tif fsutil.IsSymlink(cleanSource) {\n\t\tlog.Errorf(\"dockerutil.CopyToVolume: source is a symlink = %s\", cleanSource)\n\t\trmContainer()\n\t\treturn fmt.Errorf(\"source is symlink\")\n\t}\n\n\ttarData, err := archive.Tar(cleanSource, archive.Uncompressed)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.CopyToVolume: archive.Tar() error = %v\", err)\n\t\trmContainer()\n\t\treturn err\n\t}\n\n\ttargetPath := volumeBasePath\n\tif dstRootDir != \"\" {\n\t\tdirData, err := GenStateDirsTar(dstRootDir, dstTargetDir)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CopyToVolume: GenStateDirsTar() error = %v\", err)\n\t\t\trmContainer()\n\t\t\treturn err\n\t\t}\n\n\t\tdirUploadOptions := dockerapi.UploadToContainerOptions{\n\t\t\tInputStream: dirData,\n\t\t\tPath:        targetPath,\n\t\t}\n\n\t\terr = dclient.UploadToContainer(containerID, dirUploadOptions)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CopyToVolume: copy dirs - dclient.UploadToContainer() error = %v\", err)\n\t\t\trmContainer()\n\t\t\treturn err\n\t\t}\n\n\t\ttargetPath = filepath.Join(volumeBasePath, dstRootDir, dstTargetDir)\n\t}\n\n\tuploadOptions := dockerapi.UploadToContainerOptions{\n\t\tInputStream: tarData,\n\t\tPath:        targetPath,\n\t}\n\n\terr = dclient.UploadToContainer(containerID, uploadOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.CopyToVolume: dclient.UploadToContainer() error = %v\", err)\n\t\ttarData.Close()\n\t\trmContainer()\n\t\treturn err\n\t}\n\n\ttarData.Close()\n\trmContainer()\n\n\treturn nil\n}\n\nfunc GenStateDirsTar(rootDir, stateDir string) (io.Reader, error) {\n\tif rootDir == \"\" || stateDir == \"\" {\n\t\treturn nil, ErrBadParam\n\t}\n\n\tvar b bytes.Buffer\n\ttw := tar.NewWriter(&b)\n\n\tbaseDirHdr := tar.Header{\n\t\tTypeflag: tar.TypeDir,\n\t\tName:     fmt.Sprintf(\"%s/\", rootDir),\n\t\tMode:     16877,\n\t}\n\n\tif err := tw.WriteHeader(&baseDirHdr); err != nil {\n\t\tlog.Errorf(\"dockerutil.GenStateDirsTar: error writing base dir header to archive - %v\", err)\n\t\treturn nil, err\n\t}\n\n\tstateDirHdr := tar.Header{\n\t\tTypeflag: tar.TypeDir,\n\t\tName:     fmt.Sprintf(\"%s/%s/\", rootDir, stateDir),\n\t\tMode:     16877,\n\t}\n\n\tif err := tw.WriteHeader(&stateDirHdr); err != nil {\n\t\tlog.Errorf(\"dockerutil.GenStateDirsTar: error writing state dir header to archive - %v\", err)\n\t\treturn nil, err\n\t}\n\n\tif err := tw.Close(); err != nil {\n\t\tlog.Errorf(\"dockerutil.GenStateDirsTar: error closing archive - %v\", err)\n\t\treturn nil, err\n\t}\n\n\treturn &b, nil\n}\n\nfunc CreateVolumeWithData(\n\tdclient *dockerapi.Client,\n\tsource string,\n\tname string,\n\tlabels map[string]string) error {\n\tif name == \"\" {\n\t\treturn ErrBadParam\n\t}\n\n\tif source != \"\" {\n\t\tif _, err := os.Stat(source); err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CreateVolumeWithData: bad source (%v) = %v\", source, err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CreateVolumeWithData: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tvolumeOptions := dockerapi.CreateVolumeOptions{\n\t\tName:   name,\n\t\tLabels: labels,\n\t}\n\n\tvolumeInfo, err := dclient.CreateVolume(volumeOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.CreateVolumeWithData: dclient.CreateVolume() error = %v\", err)\n\t\treturn err\n\t}\n\n\tlog.Debugf(\"dockerutil.CreateVolumeWithData: volumeInfo = %+v\", volumeInfo)\n\n\tif source != \"\" {\n\t\treturn CopyToVolume(dclient, name, source, \"\", \"\")\n\t}\n\n\treturn nil\n}\n\nfunc CopyFromContainer(dclient *dockerapi.Client, containerID, remote, local string, extract, removeOrig bool) error {\n\tif containerID == \"\" || remote == \"\" || local == \"\" {\n\t\treturn ErrBadParam\n\t}\n\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CopyFromContainer: dockerapi.NewClient() error = %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\n\tdfile, err := os.Create(local)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdownloadOptions := dockerapi.DownloadFromContainerOptions{\n\t\tPath:              remote,\n\t\tOutputStream:      dfile,\n\t\tInactivityTimeout: 20 * time.Second,\n\t}\n\n\terr = dclient.DownloadFromContainer(containerID, downloadOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.CopyFromContainer: dclient.DownloadFromContainer() error = %v\", err)\n\t\tdfile.Close()\n\t\treturn err\n\t}\n\n\tdfile.Close()\n\n\tif extract {\n\t\tdstDir := filepath.Dir(local)\n\t\tarc := archive.NewDefaultArchiver()\n\n\t\tafile, err := os.Open(local)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CopyFromContainer: os.Open error - %v\", err)\n\t\t\treturn err\n\t\t}\n\n\t\ttarOptions := &archive.TarOptions{\n\t\t\tNoLchown: true,\n\t\t\t//UIDMaps:  arc.IDMapping.UIDs(),\n\t\t\t//GIDMaps:  arc.IDMapping.GIDs(),\n\t\t}\n\n\t\ttarOptions.IDMap.UIDMaps = arc.IDMapping.UIDMaps\n\t\ttarOptions.IDMap.GIDMaps = arc.IDMapping.GIDMaps\n\n\t\terr = arc.Untar(afile, dstDir, tarOptions)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.CopyFromContainer: error unpacking tar - %v\", err)\n\t\t\tafile.Close()\n\t\t\treturn err\n\t\t}\n\n\t\tafile.Close()\n\n\t\tif removeOrig {\n\t\t\tos.Remove(local)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc PrepareContainerDataArchive(fullPath, newName, removePrefix string, removeOrig bool) error {\n\tif fullPath == \"\" || newName == \"\" || removePrefix == \"\" {\n\t\treturn ErrBadParam\n\t}\n\n\tdirName := filepath.Dir(fullPath)\n\tdstPath := filepath.Join(dirName, newName)\n\n\tinFile, err := os.Open(fullPath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.PrepareContainerDataArchive: os.Open(%s) error - %v\", fullPath, err)\n\t\treturn err\n\t}\n\n\toutFile, err := os.Create(dstPath)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.PrepareContainerDataArchive: os.Open(%s) error - %v\", dstPath, err)\n\t\tinFile.Close()\n\t\treturn err\n\t}\n\n\ttw := tar.NewWriter(outFile)\n\ttr := tar.NewReader(inFile)\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.PrepareContainerDataArchive: error reading archive(%v) - %v\", fullPath, err)\n\t\t\tinFile.Close()\n\t\t\treturn err\n\t\t}\n\n\t\tif hdr == nil || hdr.Name == \"\" {\n\t\t\tlog.Debugf(\"dockerutil.PrepareContainerDataArchive: ignoring bad tar header\")\n\t\t\tcontinue\n\t\t}\n\n\t\tif hdr.Name == removePrefix {\n\t\t\tlog.Debugf(\"dockerutil.PrepareContainerDataArchive: ignoring tar object: %v\", hdr.Name)\n\t\t\tcontinue\n\t\t}\n\n\t\tif hdr.Name != \"\" && strings.HasPrefix(hdr.Name, removePrefix) {\n\t\t\thdr.Name = strings.TrimPrefix(hdr.Name, removePrefix)\n\t\t}\n\n\t\tif err := tw.WriteHeader(hdr); err != nil {\n\t\t\tlog.Errorf(\"dockerutil.PrepareContainerDataArchive: error writing header to archive(%v) - %v\", dstPath, err)\n\t\t\tinFile.Close()\n\t\t\toutFile.Close()\n\t\t\treturn err\n\t\t}\n\n\t\tif _, err := io.Copy(tw, tr); err != nil {\n\t\t\tlog.Errorf(\"dockerutil.PrepareContainerDataArchive: error copying data to archive(%v) - %v\", dstPath, err)\n\t\t\tinFile.Close()\n\t\t\toutFile.Close()\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif err := tw.Close(); err != nil {\n\t\tlog.Errorf(\"dockerutil.PrepareContainerDataArchive: error closing archive(%v) - %v\", dstPath, err)\n\t}\n\n\toutFile.Close()\n\tinFile.Close()\n\n\tif removeOrig {\n\t\tos.Remove(fullPath)\n\t}\n\n\treturn nil\n}\n\nfunc ListNetworks(dclient *dockerapi.Client, nameFilter string) ([]string, error) {\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.ListNetworks(%s): dockerapi.NewClient() error = %v\", nameFilter, err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tfilter := dockerapi.NetworkFilterOpts{\n\t\t\"name\": map[string]bool{\n\t\t\tnameFilter: true,\n\t\t},\n\t}\n\n\tnetworkList, err := dclient.FilteredListNetworks(filter)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.ListNetworks(%s): dockerapi.FilteredListNetworks() error = %v\", nameFilter, err)\n\t\treturn nil, err\n\t}\n\n\tvar names []string\n\tfor _, networkInfo := range networkList {\n\t\tnames = append(names, networkInfo.Name)\n\t}\n\n\treturn names, nil\n}\n\nfunc ListVolumes(dclient *dockerapi.Client, nameFilter string) ([]string, error) {\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.ListVolumes(%s): dockerapi.NewClient() error = %v\", nameFilter, err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tlistOptions := dockerapi.ListVolumesOptions{\n\t\tFilters: map[string][]string{\n\t\t\t\"name\": {nameFilter},\n\t\t},\n\t}\n\n\tvolumeList, err := dclient.ListVolumes(listOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.ListVolumes(%s): dockerapi.ListVolumes() error = %v\", nameFilter, err)\n\t\treturn nil, err\n\t}\n\n\tvar names []string\n\tfor _, volumeInfo := range volumeList {\n\t\tnames = append(names, volumeInfo.Name)\n\t}\n\n\treturn names, nil\n}\n\n////////\n\nconst (\n\tCSCreated    = \"created\"\n\tCSRestarting = \"restarting\"\n\tCSRunning    = \"running\"\n\tCSRemoving   = \"removing\"\n\tCSPaused     = \"paused\"\n\tCSExited     = \"exited\"\n\tCSDead       = \"dead\"\n)\n\ntype BasicContainerProps struct {\n\tName    string\n\tNames   []string //names have \"/\" as the prefix\n\tID      string\n\tImage   string //'spec' image ref (inspect to get the exact image ID)\n\tCreated int64\n\tState   string\n\tStatus  string //e.g., \"Up X seconds\"\n\tCommand string //Entrypoint+Cmd in the shell format\n}\n\nfunc ListContainers(dclient *dockerapi.Client, nameFilter string, all bool) (map[string]BasicContainerProps, error) {\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.ListContainers(%s): dockerapi.NewClient() error = %v\", nameFilter, err)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tlistOptions := dockerapi.ListContainersOptions{\n\t\tAll: all, //if 'all' then also non-running containers are returned\n\t}\n\n\tif nameFilter != \"\" {\n\t\tlistOptions.Filters = map[string][]string{\n\t\t\t\"name\": {nameFilter},\n\t\t}\n\t}\n\n\t//note: will need to call 'inspect' to get additional container fields\n\tcontainerList, err := dclient.ListContainers(listOptions)\n\tif err != nil {\n\t\tlog.Errorf(\"dockerutil.ListContainers(%s): dockerapi.ListContainers() error = %v\", nameFilter, err)\n\t\treturn nil, err\n\t}\n\n\tcontainers := map[string]BasicContainerProps{}\n\tfor _, containerInfo := range containerList {\n\t\tvar name string\n\t\tif len(containerInfo.Names) > 0 {\n\t\t\tname = strings.TrimPrefix(containerInfo.Names[0], \"/\")\n\t\t}\n\n\t\tinfo := BasicContainerProps{\n\t\t\tName:    name,\n\t\t\tNames:   containerInfo.Names,\n\t\t\tID:      containerInfo.ID,\n\t\t\tCreated: containerInfo.Created,\n\t\t\tImage:   containerInfo.Image,\n\t\t\tState:   containerInfo.State,\n\t\t\tStatus:  containerInfo.Status,\n\t\t\tCommand: containerInfo.Command,\n\t\t}\n\n\t\tcontainers[name] = info\n\t}\n\n\treturn containers, nil\n}\n\nfunc GetContainerLogs(dclient *dockerapi.Client, containerID string, rawTerminal bool) (string, string, error) {\n\tvar err error\n\tif dclient == nil {\n\t\tsocketInfo, err := dockerclient.GetUnixSocketAddr()\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", err\n\t\t}\n\n\t\tif socketInfo == nil || socketInfo.Address == \"\" {\n\t\t\treturn \"\", \"\", fmt.Errorf(\"no unix socket found\")\n\t\t}\n\n\t\tdclient, err = dockerapi.NewClient(socketInfo.Address)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"dockerutil.GetContainerLogs(%s): dockerapi.NewClient() error = %v\", containerID, err)\n\t\t\treturn \"\", \"\", err\n\t\t}\n\t}\n\n\tvar outData bytes.Buffer\n\toutw := bufio.NewWriter(&outData)\n\tvar errData bytes.Buffer\n\terrw := bufio.NewWriter(&errData)\n\n\toptions := dockerapi.LogsOptions{\n\t\tContainer:    containerID,\n\t\tOutputStream: outw,\n\t\tErrorStream:  errw,\n\t\tStdout:       true,\n\t\tStderr:       true,\n\t\tRawTerminal:  rawTerminal,\n\t}\n\n\terr = dclient.Logs(options)\n\tif err != nil {\n\t\tlog.Errorf(\"error getting container logs => %v - %v\", containerID, err)\n\t\treturn \"\", \"\", err\n\t}\n\n\treturn outData.String(), errData.String(), nil\n}\n"
  },
  {
    "path": "pkg/docker/instruction/instruction.go",
    "content": "// Package instruction describes the Docker instruction data model.\npackage instruction\n\nimport (\n\t\"strings\"\n)\n\n// All supported instruction names\nconst (\n\tAdd         = \"add\"\n\tArg         = \"arg\"\n\tCmd         = \"cmd\"\n\tCopy        = \"copy\"\n\tEntrypoint  = \"entrypoint\"\n\tEnv         = \"env\"\n\tExpose      = \"expose\"\n\tFrom        = \"from\"\n\tHealthcheck = \"healthcheck\"\n\tLabel       = \"label\"\n\tMaintainer  = \"maintainer\"\n\tOnbuild     = \"onbuild\"\n\tRun         = \"run\"\n\tShell       = \"shell\"\n\tStopSignal  = \"stopsignal\"\n\tUser        = \"user\"\n\tVolume      = \"volume\"\n\tWorkdir     = \"workdir\"\n)\n\ntype Field struct {\n\tGlobalIndex int      `json:\"start_index\"`\n\tStageIndex  int      `json:\"stage_index\"`\n\tStageID     int      `json:\"stage_id\"`\n\tRawData     string   `json:\"-\"`\n\tRawLines    []string `json:\"raw_lines\"`\n\tStartLine   int      `json:\"start_line\"`\n\tEndLine     int      `json:\"end_line\"`\n\tName        string   `json:\"name\"`\n\tFlags       []string `json:\"flags,omitempty\"`\n\tArgs        []string `json:\"args,omitempty\"`\n\tArgsRaw     string   `json:\"args_raw,omitempty\"`\n\tIsJSONForm  bool     `json:\"is_json\"`\n\tIsOnBuild   bool     `json:\"is_onbuild,omitempty\"`\n\tIsValid     bool     `json:\"is_valid\"`\n\tErrors      []string `json:\"errors,omitempty\"`\n}\n\ntype Format struct {\n\tName               string\n\tSupportsFlags      bool //todo: add a list allowed flags\n\tSupportsJSONForm   bool\n\tSupportsNameValues bool\n\tRequiresNameValues bool\n\tSupportsSubInst    bool\n\tIsDepricated       bool\n}\n\n// Specs is a map of all available instructions and their format info (by name)\nvar Specs = map[string]Format{\n\tAdd: {\n\t\tName:             Add,\n\t\tSupportsFlags:    true,\n\t\tSupportsJSONForm: true,\n\t},\n\tArg: {\n\t\tName:               Arg,\n\t\tSupportsNameValues: true,\n\t},\n\tCmd: {\n\t\tName:             Cmd,\n\t\tSupportsJSONForm: true,\n\t},\n\tCopy: {\n\t\tName:             Copy,\n\t\tSupportsFlags:    true,\n\t\tSupportsJSONForm: true,\n\t},\n\tEntrypoint: {\n\t\tName:             Entrypoint,\n\t\tSupportsJSONForm: true,\n\t},\n\tEnv: {\n\t\tName:               Env,\n\t\tRequiresNameValues: true,\n\t},\n\tExpose: {\n\t\tName: Expose,\n\t},\n\tFrom: {\n\t\tName:          From,\n\t\tSupportsFlags: true,\n\t},\n\tHealthcheck: {\n\t\tName:             Healthcheck,\n\t\tSupportsJSONForm: true,\n\t},\n\tLabel: {\n\t\tName:               Label,\n\t\tRequiresNameValues: true,\n\t},\n\tMaintainer: {\n\t\tName:         Maintainer,\n\t\tIsDepricated: true,\n\t},\n\tOnbuild: {\n\t\tName:            Label,\n\t\tSupportsSubInst: true,\n\t},\n\tRun: {\n\t\tName:             Run,\n\t\tSupportsJSONForm: true,\n\t},\n\tShell: {\n\t\tName:             Shell,\n\t\tSupportsJSONForm: true,\n\t},\n\tStopSignal: {\n\t\tName: StopSignal,\n\t},\n\tUser: {\n\t\tName: User,\n\t},\n\tVolume: {\n\t\tName:             Volume,\n\t\tSupportsJSONForm: true,\n\t},\n\tWorkdir: {\n\t\tName: Workdir,\n\t},\n}\n\nfunc IsKnown(name string) bool {\n\tname = strings.ToLower(name)\n\t_, ok := Specs[name]\n\treturn ok\n}\n\nfunc SupportsJSONForm() []string {\n\tvar names []string\n\tfor _, spec := range Specs {\n\t\tnames = append(names, spec.Name)\n\t}\n\n\treturn names\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/check.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile/spec\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerignore\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\ntype Context struct {\n\tDockerfilePath  string\n\tDockerfile      *spec.Dockerfile\n\tBuildContextDir string\n\tDockerignore    *dockerignore.Matcher\n}\n\ntype Options struct {\n}\n\ntype Info struct {\n\tID           string            `json:\"id\"`\n\tName         string            `json:\"name\"`\n\tDescription  string            `json:\"-\"`\n\tMainMessage  string            `json:\"-\"` //can be a template with a format string\n\tMatchMessage string            `json:\"-\"` //can be a template with a format string\n\tDetailsURL   string            `json:\"-\"`\n\tLabels       map[string]string `json:\"-\"`\n}\n\nconst (\n\tLabelLevel       = \"level\"\n\tLabelScope       = \"scope\"\n\tLabelInstruction = \"instruction\"\n\tLabelApp         = \"app\"\n\tLabelShell       = \"shell\"\n)\n\nconst (\n\tLevelAny   = \"any\"\n\tLevelFatal = \"fatal\" //parse or other errors that will result in image build failures\n\tLevelError = \"error\"\n\tLevelWarn  = \"warn\"\n\tLevelInfo  = \"info\"\n\tLevelStyle = \"style\"\n)\n\nconst (\n\tScopeAll          = \"all\"\n\tScopeDockerfile   = \"dockerfile\"\n\tScopeStage        = \"stage\"\n\tScopeInstruction  = \"instruction\"\n\tScopeDockerignore = \"dockerignore\"\n\tScopeData         = \"data\"\n\tScopeApp          = \"app\"\n\tScopeShell        = \"shell\"\n)\n\n//Possible labels:\n//\"level\" -> \"info\", \"warn\", \"error\", \"style\"\n//\"scope\" -> \"app\", \"shell\", \"instruction\", \"stage\", \"dockerfile\", \"all\", \"dockerignore\", \"data\"\n//\"instruction\" -> \"list,of,instructions\" (negative with !instruction)\n//\"app\" -> \"list,of,app names\"\n//\"shell\" -> \"general or specific shell name\"\n\nfunc (i *Info) Get() *Info {\n\treturn i\n}\n\ntype Result struct {\n\tSource     *Info    `json:\"source\"`\n\tHit        bool     `json:\"-\"`\n\tMessage    string   `json:\"message,omitempty\"`\n\tMatches    []*Match `json:\"matches,omitempty\"`\n\tDetailsURL string   `json:\"-\"`\n}\n\ntype Match struct {\n\tStage       *spec.BuildStage   `json:\"stage,omitempty\"`\n\tInstruction *instruction.Field `json:\"instruction,omitempty\"`\n\tMessage     string             `json:\"message,omitempty\"`\n}\n\ntype Runner interface {\n\tGet() *Info\n\tRun(opts *Options, ctx *Context) (*Result, error)\n}\n\n//regex-based (with rules)\n//type PolicyCheck struct {\n//\tInfo\n//}\n\nvar AllChecks = []Runner{}\n"
  },
  {
    "path": "pkg/docker/linter/check/id10001.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &NoDockerignore{\n\t\tInfo: Info{\n\t\t\tID:          \"ID.10001\",\n\t\t\tName:        \"Missing .dockerignore\",\n\t\t\tDescription: \"Missing .dockerignore\",\n\t\t\tDetailsURL:  \"https://lint.dockersl.im/check/ID.10001\",\n\t\t\tMainMessage: \"No .dockerignore\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeDockerignore,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype NoDockerignore struct {\n\tInfo\n}\n\nfunc (c *NoDockerignore) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tif ctx.Dockerignore == nil {\n\t\treturn result, nil\n\t}\n\n\tif !ctx.Dockerignore.Exists {\n\t\tresult.Hit = true\n\t\tresult.Message = c.MainMessage\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id10002.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &EmptyDockerignore{\n\t\tInfo: Info{\n\t\t\tID:          \"ID.10002\",\n\t\t\tName:        \"Empty .dockerignore\",\n\t\t\tDescription: \"Empty .dockerignore\",\n\t\t\tDetailsURL:  \"https://lint.dockersl.im/check/ID.10002\",\n\t\t\tMainMessage: \"No exclude patterns in .dockerignore\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeDockerignore,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype EmptyDockerignore struct {\n\tInfo\n}\n\nfunc (c *EmptyDockerignore) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tif ctx.Dockerignore == nil {\n\t\treturn result, nil\n\t}\n\n\tif ctx.Dockerignore.Exists && len(ctx.Dockerignore.Patterns) == 0 {\n\t\tresult.Hit = true\n\t\tresult.Message = c.MainMessage\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20000.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &InvalidInstruction{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20000\",\n\t\t\tName:         \"Invalid instruction\",\n\t\t\tDescription:  \"Invalid instruction\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20000\",\n\t\t\tMainMessage:  \"Invalid instruction in Dockerfile\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelFatal,\n\t\t\t\tLabelScope: ScopeDockerfile,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype InvalidInstruction struct {\n\tInfo\n}\n\nfunc (c *InvalidInstruction) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, inst := range ctx.Dockerfile.InvalidInstructions {\n\t\tif !inst.IsValid {\n\t\t\tif !result.Hit {\n\t\t\t\tresult.Hit = true\n\t\t\t\tresult.Message = c.MainMessage\n\t\t\t}\n\n\t\t\tmatch := &Match{\n\t\t\t\tInstruction: inst,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\tinst.StartLine,\n\t\t\t\t\tinst.EndLine,\n\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\tinst.StageID,\n\t\t\t\t\tinst.StageIndex),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20001.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &EmptyDockerfile{\n\t\tInfo: Info{\n\t\t\tID:          \"ID.20001\",\n\t\t\tName:        \"Empty Dockerfile\",\n\t\t\tDescription: \"Empty Dockerfile\",\n\t\t\tDetailsURL:  \"https://lint.dockersl.im/check/ID.20001\",\n\t\t\tMainMessage: \"No instructions in Dockerfile\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeDockerfile,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype EmptyDockerfile struct {\n\tInfo\n}\n\nfunc (c *EmptyDockerfile) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tif len(ctx.Dockerfile.AllInstructions) == 0 {\n\t\tresult.Hit = true\n\t\tresult.Message = c.MainMessage\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20002.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &NoStages{\n\t\tInfo: Info{\n\t\t\tID:          \"ID.20002\",\n\t\t\tName:        \"No stages\",\n\t\t\tDescription: \"No stages\",\n\t\t\tDetailsURL:  \"https://lint.dockersl.im/check/ID.20002\",\n\t\t\tMainMessage: \"No stages in Dockerfile\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype NoStages struct {\n\tInfo\n}\n\nfunc (c *NoStages) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tif len(ctx.Dockerfile.Stages) == 0 {\n\t\tresult.Hit = true\n\t\tresult.Message = c.MainMessage\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20003.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &EmptyStage{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20003\",\n\t\t\tName:         \"Empty stage\",\n\t\t\tDescription:  \"Empty stage\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20003\",\n\t\t\tMainMessage:  \"Empty stage in Dockerfile\",\n\t\t\tMatchMessage: \"Stage: index=%d name='%s' start=%d end=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype EmptyStage struct {\n\tInfo\n}\n\nfunc (c *EmptyStage) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif len(stage.AllInstructions) == 1 {\n\t\t\tif !result.Hit {\n\t\t\t\tresult.Hit = true\n\t\t\t\tresult.Message = c.MainMessage\n\t\t\t}\n\n\t\t\tmatch := &Match{\n\t\t\t\tStage: stage,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\tstage.Index,\n\t\t\t\t\tstage.Name,\n\t\t\t\t\tstage.StartLine,\n\t\t\t\t\tstage.EndLine),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20004.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &NoStageArgs{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20004\",\n\t\t\tName:         \"No stage arguments\",\n\t\t\tDescription:  \"No stage arguments\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20004\",\n\t\t\tMainMessage:  \"Stage without arguments in Dockerfile\",\n\t\t\tMatchMessage: \"Stage: index=%d start=%d end=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelFatal,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype NoStageArgs struct {\n\tInfo\n}\n\nfunc (c *NoStageArgs) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif stage.FromInstruction == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(stage.FromInstruction.ArgsRaw) == 0 {\n\t\t\tif !result.Hit {\n\t\t\t\tresult.Hit = true\n\t\t\t\tresult.Message = c.MainMessage\n\t\t\t}\n\n\t\t\tmatch := &Match{\n\t\t\t\tStage: stage,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\tstage.Index,\n\t\t\t\t\tstage.StartLine,\n\t\t\t\t\tstage.EndLine),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20005.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &InvalidStageArgs{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20005\",\n\t\t\tName:         \"Invalid stage arguments\",\n\t\t\tDescription:  \"Invalid stage arguments\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20005\",\n\t\t\tMainMessage:  \"Stage with invalid arguments in Dockerfile\",\n\t\t\tMatchMessage: \"Stage: reason='%s' index=%d name='%s' start=%d end=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelFatal,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype InvalidStageArgs struct {\n\tInfo\n}\n\nfunc (c *InvalidStageArgs) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif stage.FromInstruction == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif !stage.FromInstruction.IsValid {\n\t\t\tif !result.Hit {\n\t\t\t\tresult.Hit = true\n\t\t\t\tresult.Message = c.MainMessage\n\t\t\t}\n\n\t\t\tmatch := &Match{\n\t\t\t\tStage: stage,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\"invalid from instruction\",\n\t\t\t\t\tstage.Index,\n\t\t\t\t\tstage.Name,\n\t\t\t\t\tstage.StartLine,\n\t\t\t\t\tstage.EndLine),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\n\t\t//FROM args are always parsed\n\t\tif len(stage.FromInstruction.Args) == 2 ||\n\t\t\tlen(stage.FromInstruction.Args) > 3 {\n\t\t\tif !result.Hit {\n\t\t\t\tresult.Hit = true\n\t\t\t\tresult.Message = c.MainMessage\n\t\t\t}\n\n\t\t\tmatch := &Match{\n\t\t\t\tStage: stage,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\"incorrect number of arguments\",\n\t\t\t\t\tstage.Index,\n\t\t\t\t\tstage.Name,\n\t\t\t\t\tstage.StartLine,\n\t\t\t\t\tstage.EndLine),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\n\t\tif len(stage.FromInstruction.Args) == 3 &&\n\t\t\tstrings.ToLower(stage.FromInstruction.Args[1]) != \"as\" {\n\t\t\tif !result.Hit {\n\t\t\t\tresult.Hit = true\n\t\t\t\tresult.Message = c.MainMessage\n\t\t\t}\n\n\t\t\tmatch := &Match{\n\t\t\t\tStage: stage,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\"malformed arguments\",\n\t\t\t\t\tstage.Index,\n\t\t\t\t\tstage.Name,\n\t\t\t\t\tstage.StartLine,\n\t\t\t\t\tstage.EndLine),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\t}\n\n\tfor name, stageByName := range ctx.Dockerfile.StagesByName {\n\t\tfor _, stageByIdx := range ctx.Dockerfile.Stages {\n\t\t\tif stageByIdx.Name != \"\" {\n\t\t\t\tif stageByIdx.Name == name && stageByIdx != stageByName {\n\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t\t}\n\n\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\tStage: stageByIdx,\n\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\t\"duplicate name\",\n\t\t\t\t\t\t\tstageByIdx.Index,\n\t\t\t\t\t\t\tstageByIdx.Name,\n\t\t\t\t\t\t\tstageByIdx.StartLine,\n\t\t\t\t\t\t\tstageByIdx.EndLine),\n\t\t\t\t\t}\n\n\t\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20006.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &StageFromLatest{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20006\",\n\t\t\tName:         \"Stage from latest tag\",\n\t\t\tDescription:  \"Stage from latest tag\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20006\",\n\t\t\tMainMessage:  \"Stage from latest tag in Dockerfile\",\n\t\t\tMatchMessage: \"Stage: index=%d name='%s' start=%d end=%d parent='%s'\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype StageFromLatest struct {\n\tInfo\n}\n\nfunc (c *StageFromLatest) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif stage.Parent.Name != \"\" {\n\t\t\tif (stage.Parent.Tag == \"\" || strings.ToLower(stage.Parent.Tag) == \"latest\") &&\n\t\t\t\tstage.Parent.Digest == \"\" {\n\t\t\t\tif !result.Hit {\n\t\t\t\t\tresult.Hit = true\n\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t}\n\n\t\t\t\tmatch := &Match{\n\t\t\t\t\tStage: stage,\n\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\tstage.Index,\n\t\t\t\t\t\tstage.Name,\n\t\t\t\t\t\tstage.StartLine,\n\t\t\t\t\t\tstage.EndLine,\n\t\t\t\t\t\tstage.Parent.Name),\n\t\t\t\t}\n\n\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20007.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &UnknownInstruction{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20007\",\n\t\t\tName:         \"Unknown instruction\",\n\t\t\tDescription:  \"Unknown instruction\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20007\",\n\t\t\tMainMessage:  \"Unknown instruction in Dockerfile\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d name='%s' global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelInfo,\n\t\t\t\tLabelScope: ScopeInstruction,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype UnknownInstruction struct {\n\tInfo\n}\n\nfunc (c *UnknownInstruction) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tif len(ctx.Dockerfile.UnknownInstructions) > 0 {\n\t\tresult.Hit = true\n\t\tresult.Message = c.MainMessage\n\n\t\tfor _, inst := range ctx.Dockerfile.UnknownInstructions {\n\t\t\tmatch := &Match{\n\t\t\t\tInstruction: inst,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\tinst.StartLine,\n\t\t\t\t\tinst.EndLine,\n\t\t\t\t\tinst.Name,\n\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\tinst.StageID,\n\t\t\t\t\tinst.StageIndex),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20008.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &DeprecatedInstruction{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20008\",\n\t\t\tName:         \"Deprecated instruction\",\n\t\t\tDescription:  \"Deprecated instruction\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20008\",\n\t\t\tMainMessage:  \"Deprecated instruction\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d name='%s' global_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelInfo,\n\t\t\t\tLabelScope: ScopeDockerfile,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype DeprecatedInstruction struct {\n\tInfo\n}\n\nfunc (c *DeprecatedInstruction) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tif instructions, ok := ctx.Dockerfile.InstructionsByType[instruction.Maintainer]; ok {\n\t\tresult.Hit = true\n\t\tresult.Message = c.MainMessage\n\n\t\tfor _, inst := range instructions {\n\t\t\tmatch := &Match{\n\t\t\t\tInstruction: inst,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\tinst.StartLine,\n\t\t\t\t\tinst.EndLine,\n\t\t\t\t\tinst.Name,\n\t\t\t\t\tinst.GlobalIndex),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20009.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &StagelessInstruction{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20009\",\n\t\t\tName:         \"Stageless instruction\",\n\t\t\tDescription:  \"Stageless instruction\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20009\",\n\t\t\tMainMessage:  \"Non-arg instruction outside of a Dockerfile stage\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d name='%s' global_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeDockerfile,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype StagelessInstruction struct {\n\tInfo\n}\n\nfunc (c *StagelessInstruction) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tif len(ctx.Dockerfile.StagelessInstructions) > 0 {\n\t\tresult.Hit = true\n\t\tresult.Message = c.MainMessage\n\n\t\tfor _, inst := range ctx.Dockerfile.StagelessInstructions {\n\t\t\tmatch := &Match{\n\t\t\t\tInstruction: inst,\n\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\tinst.StartLine,\n\t\t\t\t\tinst.EndLine,\n\t\t\t\t\tinst.Name,\n\t\t\t\t\tinst.GlobalIndex),\n\t\t\t}\n\n\t\t\tresult.Matches = append(result.Matches, match)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20010.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &MultipleEntrypointInstructions{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20010\",\n\t\t\tName:         \"Multiple ENTRYPOINT instructions\",\n\t\t\tDescription:  \"Multiple ENTRYPOINT instructions\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20010\",\n\t\t\tMainMessage:  \"Multiple ENTRYPOINT instructions in stage\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype MultipleEntrypointInstructions struct {\n\tInfo\n}\n\nfunc (c *MultipleEntrypointInstructions) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.Entrypoint]; ok {\n\t\t\tif len(instructions) > 1 {\n\t\t\t\tif !result.Hit {\n\t\t\t\t\tresult.Hit = true\n\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t}\n\n\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t}\n\n\t\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20011.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &MultipleCmdInstructions{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20011\",\n\t\t\tName:         \"Multiple CMD instructions\",\n\t\t\tDescription:  \"Multiple CMD instructions\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20011\",\n\t\t\tMainMessage:  \"Multiple CMD instructions in stage\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype MultipleCmdInstructions struct {\n\tInfo\n}\n\nfunc (c *MultipleCmdInstructions) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.Cmd]; ok {\n\t\t\tif len(instructions) > 1 {\n\t\t\t\tif !result.Hit {\n\t\t\t\t\tresult.Hit = true\n\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t}\n\n\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t}\n\n\t\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20012.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &EntrypointCmdShellForm{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20012\",\n\t\t\tName:         \"ENTRYPOINT or CMD in shell form\",\n\t\t\tDescription:  \"ENTRYPOINT or CMD should use the exec/JSON form\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20012\",\n\t\t\tMainMessage:  \"Instruction in shell form\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d name='%s' global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t\tNames: []string{\n\t\t\tinstruction.Entrypoint,\n\t\t\tinstruction.Cmd,\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype EntrypointCmdShellForm struct {\n\tInfo\n\tNames []string\n}\n\nfunc (c *EntrypointCmdShellForm) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tfor _, name := range c.Names {\n\t\t\tif instructions, ok := stage.CurrentInstructionsByType[name]; ok {\n\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\tif !inst.IsJSONForm {\n\t\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\t\t\tinst.Name,\n\t\t\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tresult.Matches = append(result.Matches, match)\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\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20013.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &MalformedInstExecForm{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20013\",\n\t\t\tName:         \"Malformed instruction in exec/JSON form\",\n\t\t\tDescription:  \"Malformed instruction in exec/JSON form\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20013\",\n\t\t\tMainMessage:  \"Malformed instruction in exec/JSON form\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d name='%s' global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype MalformedInstExecForm struct {\n\tInfo\n}\n\nfunc (c *MalformedInstExecForm) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tfor _, name := range instruction.SupportsJSONForm() {\n\t\t\tif instructions, ok := stage.CurrentInstructionsByType[name]; ok {\n\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\tif inst.IsJSONForm {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tif strings.HasPrefix(inst.ArgsRaw, \"[\") ||\n\t\t\t\t\t\tstrings.HasSuffix(inst.ArgsRaw, \"]\") {\n\t\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\t\t\tinst.Name,\n\t\t\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tresult.Matches = append(result.Matches, match)\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\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20014.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\t//related to ID.20016 (but fatal because it'll result in failed container builds)\n\tcheck := &NoWorkdirPath{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20014\",\n\t\t\tName:         \"No WORKDIR path\",\n\t\t\tDescription:  \"No WORKDIR path\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20014\",\n\t\t\tMainMessage:  \"No WORKDIR path in stage\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelFatal,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype NoWorkdirPath struct {\n\tInfo\n}\n\nfunc (c *NoWorkdirPath) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.Workdir]; ok {\n\t\t\tfor _, inst := range instructions {\n\t\t\t\tif len(inst.ArgsRaw) == 0 {\n\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t\t}\n\n\t\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20015.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &RelativeWorkdir{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20015\",\n\t\t\tName:         \"Relative WORKDIR path\",\n\t\t\tDescription:  \"Relative WORKDIR path\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20015\",\n\t\t\tMainMessage:  \"Relative WORKDIR path in stage\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype RelativeWorkdir struct {\n\tInfo\n}\n\nfunc (c *RelativeWorkdir) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.Workdir]; ok {\n\t\t\tfor _, inst := range instructions {\n\t\t\t\tif len(inst.ArgsRaw) > 0 {\n\t\t\t\t\tworkdirPath := inst.ArgsRaw\n\t\t\t\t\tif strings.Contains(workdirPath, \"$\") {\n\t\t\t\t\t\tworkdirPath = expandEnvVars(workdirPath, stage.EnvVars)\n\t\t\t\t\t}\n\n\t\t\t\t\tif strings.HasPrefix(workdirPath, \"/\") {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t\t}\n\n\t\t\t\t\tfor _, inst := range instructions {\n\t\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n\nfunc expandEnvVars(data string, vars map[string]string) string {\n\t//todo: do it the right way\n\tif strings.HasPrefix(data, \"$\") {\n\t\tname := data[1:]\n\t\tif val, ok := vars[name]; ok {\n\t\t\treturn val\n\t\t}\n\t}\n\n\treturn data\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20016.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nfunc init() {\n\tcheck := &NoEnvArgs{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20016\",\n\t\t\tName:         \"No instruction args\",\n\t\t\tDescription:  \"No instruction args\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20016\",\n\t\t\tMainMessage:  \"No instruction args in stage\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d name='%s' global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelError,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype NoEnvArgs struct {\n\tInfo\n}\n\nfunc (c *NoEnvArgs) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tfor _, inst := range stage.CurrentInstructions {\n\t\t\tif len(inst.ArgsRaw) == 0 {\n\t\t\t\tif !result.Hit {\n\t\t\t\t\tresult.Hit = true\n\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t}\n\n\t\t\t\tmatch := &Match{\n\t\t\t\t\tStage:       stage,\n\t\t\t\t\tInstruction: inst,\n\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\tinst.Name,\n\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t}\n\n\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20017.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &LastUserRoot{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20017\",\n\t\t\tName:         \"Last USER instruction with root\",\n\t\t\tDescription:  \"Last USER instruction with root\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20017\",\n\t\t\tMainMessage:  \"Last USER instruction with root\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelInfo,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype LastUserRoot struct {\n\tInfo\n}\n\nfunc (c *LastUserRoot) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tlastStageIdx := len(ctx.Dockerfile.Stages) - 1\n\tif lastStageIdx > -1 {\n\t\tstage := ctx.Dockerfile.Stages[lastStageIdx]\n\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.User]; ok {\n\t\t\tlastUserIdx := len(instructions) - 1\n\t\t\tif lastUserIdx > -1 {\n\t\t\t\tinst := instructions[lastUserIdx]\n\t\t\t\targsRaw := strings.ToLower(inst.ArgsRaw)\n\t\t\t\tif argsRaw == \"0\" ||\n\t\t\t\t\targsRaw == \"root\" ||\n\t\t\t\t\tstrings.HasPrefix(argsRaw, \"0:\") ||\n\t\t\t\t\tstrings.HasPrefix(argsRaw, \"root:\") {\n\n\t\t\t\t\tresult.Hit = true\n\t\t\t\t\tresult.Message = c.MainMessage\n\n\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t}\n\n\t\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t//if no explicit USER instruction (parent's USER is inherited)\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20018.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/google/shlex\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &PyPipInstallLatest{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20018\",\n\t\t\tName:         \"Python Pip installs latest package version\",\n\t\t\tDescription:  \"Python Pip installs latest package version\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20018\",\n\t\t\tMainMessage:  \"Python Pip installs latest package version\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d package=%s\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype PyPipInstallLatest struct {\n\tInfo\n}\n\nfunc (c *PyPipInstallLatest) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.Run]; ok {\n\t\t\tfor _, inst := range instructions {\n\t\t\t\tif len(inst.ArgsRaw) == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tvar args []string\n\t\t\t\tif inst.IsJSONForm {\n\t\t\t\t\targs = inst.Args\n\t\t\t\t} else {\n\t\t\t\t\tvar err error\n\t\t\t\t\targs, err = shlex.Split(inst.ArgsRaw)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Fatal(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif len(args) > 1 {\n\t\t\t\t\tcmdName := strings.ToLower(args[0])\n\n\t\t\t\t\tif strings.HasPrefix(cmdName, \"python\") &&\n\t\t\t\t\t\tlen(args) > 3 &&\n\t\t\t\t\t\targs[1] == \"-m\" {\n\t\t\t\t\t\tcmdName = strings.ToLower(args[2])\n\t\t\t\t\t\targs = args[2:]\n\t\t\t\t\t\t//handle 'pythonX -m pip install pkgname'\n\t\t\t\t\t}\n\n\t\t\t\t\t//pip install -x 'pkgname>=x.y.z,<a.b.c' pkgname==x.y --somefield\n\n\t\t\t\t\tif strings.HasPrefix(cmdName, \"pip\") &&\n\t\t\t\t\t\tstrings.ToLower(args[1]) == \"install\" {\n\t\t\t\t\t\tif len(args) == 4 &&\n\t\t\t\t\t\t\t(args[2] == \"-U\" || args[2] == \"--upgrade\") &&\n\t\t\t\t\t\t\targs[3] == \"pip\" {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif strings.Contains(inst.ArgsRaw, \" -r \") ||\n\t\t\t\t\t\t\tstrings.Contains(inst.ArgsRaw, \" --requirement\") ||\n\t\t\t\t\t\t\tstrings.Contains(inst.ArgsRaw, \" -c \") ||\n\t\t\t\t\t\t\tstrings.Contains(inst.ArgsRaw, \" --constraint\") {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//assumption: requirements/constraint files contain versions\n\t\t\t\t\t\t//todo:\n\t\t\t\t\t\t//should confirm the requirements/constraint files\n\t\t\t\t\t\t//and what versions they include\n\n\t\t\t\t\t\tif (strings.Contains(inst.ArgsRaw, \" git\") ||\n\t\t\t\t\t\t\tstrings.Contains(inst.ArgsRaw, \"https://\") ||\n\t\t\t\t\t\t\tstrings.Contains(inst.ArgsRaw, \"http://\")) &&\n\t\t\t\t\t\t\tstrings.Contains(inst.ArgsRaw, \"@\") {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor i := 2; i < len(args); i++ {\n\t\t\t\t\t\t\tif strings.HasPrefix(args[i], \"-\") {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t//todo: check for local packages and wheels...\n\n\t\t\t\t\t\t\tpkgInfoParts := strings.FieldsFunc(args[i],\n\t\t\t\t\t\t\t\tfunc(c rune) bool {\n\t\t\t\t\t\t\t\t\treturn c == '=' || c == '<' || c == '>' || c == '!'\n\t\t\t\t\t\t\t\t})\n\n\t\t\t\t\t\t\tpkgName := pkgInfoParts[0]\n\t\t\t\t\t\t\tif pkgName[0] == '\\'' || pkgName[0] == '\"' {\n\t\t\t\t\t\t\t\tpkgName = pkgName[1:]\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif strings.Contains(args[i], \"==\") ||\n\t\t\t\t\t\t\t\tstrings.Contains(args[i], \"<=\") ||\n\t\t\t\t\t\t\t\tstrings.Contains(args[i], \"<\") {\n\t\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\t\t\tinst.StageIndex,\n\t\t\t\t\t\t\t\t\tpkgInfoParts[0]),\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tresult.Matches = append(result.Matches, match)\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\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20019.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &UnnecessaryLayer{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20019\",\n\t\t\tName:         \"Unnecessary Layer\",\n\t\t\tDescription:  \"RUN instruction will result in unnecessary layer (combine command with previous RUN instruciton)\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20019\",\n\t\t\tMainMessage:  \"RUN instruction will result in unnecessary layer\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d prev_start=%d prev_end=%d prev_global_index=%d prev_stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype UnnecessaryLayer struct {\n\tInfo\n}\n\nfunc (c *UnnecessaryLayer) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\n\t\tvar prevInst *instruction.Field\n\t\tfor _, inst := range stage.CurrentInstructions {\n\n\t\t\tif inst.Name == instruction.Run &&\n\t\t\t\tprevInst != nil &&\n\t\t\t\tprevInst.Name == instruction.Run {\n\t\t\t\t//very primitive unnecessary layer that only checks the previous RUN instruction\n\t\t\t\t//should have a separate check with more advanced unnecessary layer detection\n\t\t\t\tif !result.Hit {\n\t\t\t\t\tresult.Hit = true\n\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t}\n\n\t\t\t\tmatch := &Match{\n\t\t\t\t\tStage:       stage,\n\t\t\t\t\tInstruction: inst,\n\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\tinst.StageIndex,\n\t\t\t\t\t\tprevInst.StartLine,\n\t\t\t\t\t\tprevInst.EndLine,\n\t\t\t\t\t\tprevInst.GlobalIndex,\n\t\t\t\t\t\tprevInst.StageIndex),\n\t\t\t\t}\n\n\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t}\n\n\t\t\tprevInst = inst\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20020.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nconst (\n\tmaxLayerCount = 100\n)\n\nfunc init() {\n\tcheck := &TooManyLayers{\n\t\tInfo: Info{\n\t\t\tID:          \"ID.20020\",\n\t\t\tName:        \"Too Many Layers\",\n\t\t\tDescription: \"Too many image layers\",\n\t\t\tDetailsURL:  \"https://lint.dockersl.im/check/ID.20020\",\n\t\t\tMainMessage: \"Too many image layers in stage: count=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype TooManyLayers struct {\n\tInfo\n}\n\nfunc (c *TooManyLayers) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\t//NOTES:\n\t//A regular Dockerfile lint check won't be very accurate because:\n\t//* the check doesn't know how many layers exist in the base image\n\t//* it doesn't know the storage driver and its exact limit\n\t//* not all RUN instructions generate new layers (e.g., \"RUN python -V\")\n\t//* not all WORKDIR instructions generate new layers (new layer only when dir doesn't exist)\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tlayerCount := 0\n\t\tfor _, inst := range stage.CurrentInstructions {\n\t\t\tswitch inst.Name {\n\t\t\tcase instruction.Run,\n\t\t\t\tinstruction.Workdir,\n\t\t\t\tinstruction.Copy,\n\t\t\t\tinstruction.Add:\n\t\t\t\tlayerCount++\n\t\t\t}\n\t\t}\n\n\t\tif layerCount > maxLayerCount {\n\t\t\tresult.Hit = true\n\t\t\tresult.Message = fmt.Sprintf(c.MainMessage, layerCount)\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20021.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/google/shlex\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &SeparateRemove{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20021\",\n\t\t\tName:         \"Separate rm Command\",\n\t\t\tDescription:  \"Separate rm command only hides data\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20021\",\n\t\t\tMainMessage:  \"Separate rm command only hides data in the image (also creates a new layer)\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelWarn,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype SeparateRemove struct {\n\tInfo\n}\n\nfunc (c *SeparateRemove) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", c.ID, c.Name)\n\tresult := &Result{\n\t\tSource: &c.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.Run]; ok {\n\t\t\tfor _, inst := range instructions {\n\t\t\t\tif len(inst.ArgsRaw) == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tvar args []string\n\t\t\t\tif inst.IsJSONForm {\n\t\t\t\t\targs = inst.Args\n\t\t\t\t} else {\n\t\t\t\t\tvar err error\n\t\t\t\t\targs, err = shlex.Split(inst.ArgsRaw)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Fatal(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif len(args) > 1 {\n\t\t\t\t\tif strings.ToLower(args[0]) == \"rm\" {\n\t\t\t\t\t\t//can also check/track if it's the only RUN instruction\n\t\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\t\tresult.Message = c.MainMessage\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\t\tMessage: fmt.Sprintf(c.MatchMessage,\n\t\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\t\tinst.StageIndex),\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresult.Matches = append(result.Matches, match)\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/check/id20022.go",
    "content": "// Package check contains the linter checks\npackage check\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/google/shlex\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\nfunc init() {\n\tcheck := &BadContainerCommands{\n\t\tInfo: Info{\n\t\t\tID:           \"ID.20022\",\n\t\t\tName:         \"Bad Container Commands\",\n\t\t\tDescription:  \"Bad container commands\",\n\t\t\tDetailsURL:   \"https://lint.dockersl.im/check/ID.20022\",\n\t\t\tMainMessage:  \"Bad container commands\",\n\t\t\tMatchMessage: \"Instruction: start=%d end=%d global_index=%d stage_id=%d stage_index=%d cmd=%s\",\n\t\t\tLabels: map[string]string{\n\t\t\t\tLabelLevel: LevelInfo,\n\t\t\t\tLabelScope: ScopeStage,\n\t\t\t},\n\t\t},\n\t\tNames: []string{\n\t\t\t\"vim\",\n\t\t\t\"shutdown\",\n\t\t\t\"mount\",\n\t\t\t\"kill\",\n\t\t\t\"top\",\n\t\t\t\"free\",\n\t\t\t\"service\",\n\t\t\t\"ssh\",\n\t\t\t\"ps\",\n\t\t},\n\t}\n\n\tAllChecks = append(AllChecks, check)\n}\n\ntype BadContainerCommands struct {\n\tInfo\n\tNames []string\n}\n\nfunc (check *BadContainerCommands) Run(opts *Options, ctx *Context) (*Result, error) {\n\tlog.Debugf(\"linter.check[%s:'%s']\", check.ID, check.Name)\n\tresult := &Result{\n\t\tSource: &check.Info,\n\t}\n\n\tfor _, stage := range ctx.Dockerfile.Stages {\n\t\tif instructions, ok := stage.CurrentInstructionsByType[instruction.Run]; ok {\n\t\t\tfor _, inst := range instructions {\n\t\t\t\tif len(inst.ArgsRaw) == 0 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tvar args []string\n\t\t\t\tif inst.IsJSONForm {\n\t\t\t\t\targs = inst.Args\n\t\t\t\t} else {\n\t\t\t\t\tvar err error\n\t\t\t\t\targs, err = shlex.Split(inst.ArgsRaw)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Fatal(err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif len(args) > 1 {\n\t\t\t\t\tfor _, cmdName := range check.Names {\n\t\t\t\t\t\t//TODO:\n\t\t\t\t\t\t//need to make it work with multiple commands in instruction\n\t\t\t\t\t\t//need better shell parsing first\n\t\t\t\t\t\tif strings.ToLower(args[0]) == cmdName {\n\t\t\t\t\t\t\tif !result.Hit {\n\t\t\t\t\t\t\t\tresult.Hit = true\n\t\t\t\t\t\t\t\tresult.Message = check.MainMessage\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tmatch := &Match{\n\t\t\t\t\t\t\t\tStage:       stage,\n\t\t\t\t\t\t\t\tInstruction: inst,\n\t\t\t\t\t\t\t\tMessage: fmt.Sprintf(check.MatchMessage,\n\t\t\t\t\t\t\t\t\tinst.StartLine,\n\t\t\t\t\t\t\t\t\tinst.EndLine,\n\t\t\t\t\t\t\t\t\tinst.GlobalIndex,\n\t\t\t\t\t\t\t\t\tinst.StageID,\n\t\t\t\t\t\t\t\t\tinst.StageIndex,\n\t\t\t\t\t\t\t\t\tcmdName),\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tresult.Matches = append(result.Matches, match)\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\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/docker/linter/linter.go",
    "content": "// Package linter implements a Dockerfile linter\npackage linter\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile/parser\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile/spec\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerignore\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/linter/check\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar (\n\tErrBadParams = errors.New(\"bad params\")\n)\n\nconst (\n\tDockerfileTargetType = \"dockerfile\"\n\tImageTargetType      = \"image\"\n)\n\n//TODO:\n//* support incremental, partial and instruction level linting\n//* support linting from string\n\ntype Options struct {\n\tDockerfilePath   string\n\tDockerfile       *spec.Dockerfile\n\tSkipBuildContext bool\n\tBuildContextDir  string\n\tSkipDockerignore bool //to disable .dockerignore parsing\n\tDockerignore     *dockerignore.Matcher\n\tSelector         CheckSelector\n\tConfig           map[string]*check.Options\n}\n\ntype CheckContext struct {\n\tDockerfilePath  string\n\tDockerfile      *spec.Dockerfile\n\tBuildContextDir string\n\tDockerignore    *dockerignore.Matcher\n}\n\ntype CheckSelector struct {\n\tIncludeCheckLabels map[string]string\n\tIncludeCheckIDs    map[string]struct{}\n\tExcludeCheckLabels map[string]string\n\tExcludeCheckIDs    map[string]struct{}\n}\n\nconst (\n\tStatusUnknown  = \"unknown\"\n\tStatusRunning  = \"running\"\n\tStatusComplete = \"complete\"\n\tStatusTimedOut = \"timeout\"\n\tStatusFailed   = \"failed\"\n)\n\n// TODO: add report name, report time, etc\ntype Report struct {\n\tStatus          string\n\tBuildContextDir string\n\tDockerfile      *spec.Dockerfile\n\tDockerignore    *dockerignore.Matcher\n\tHits            map[string]*check.Result\n\tNoHits          map[string]*check.Result\n\tErrors          map[string]error\n}\n\nfunc NewReport() *Report {\n\treturn &Report{\n\t\tStatus: StatusUnknown,\n\t\tHits:   map[string]*check.Result{},\n\t\tNoHits: map[string]*check.Result{},\n\t\tErrors: map[string]error{},\n\t}\n}\n\ntype CheckState struct {\n\tCheck   check.Runner\n\tOptions *check.Options\n\tContext *check.Context\n\tResult  *check.Result\n\tError   error\n}\n\nfunc Execute(options Options) (*Report, error) {\n\tdf := options.Dockerfile\n\tif df == nil {\n\t\tif options.DockerfilePath == \"\" {\n\t\t\treturn nil, ErrBadParams\n\t\t}\n\n\t\tvar err error\n\t\tdf, err = parser.FromFile(options.DockerfilePath)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tvar buildContextDir string\n\tif !options.SkipBuildContext {\n\t\tif df != nil {\n\t\t\tbuildContextDir = df.Location\n\t\t}\n\n\t\tif options.BuildContextDir != \"\" {\n\t\t\tbuildContextDir = options.BuildContextDir\n\t\t}\n\t}\n\n\tdi := options.Dockerignore\n\tif di == nil && !options.SkipDockerignore {\n\t\tvar err error\n\t\tdi, err = dockerignore.Load(buildContextDir)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treport := NewReport()\n\treport.BuildContextDir = options.BuildContextDir\n\treport.Dockerfile = df\n\treport.Dockerignore = di\n\n\tvar selectedChecks []check.Runner\n\tfor _, check := range check.AllChecks {\n\t\tinfo := check.Get()\n\n\t\tif len(options.Selector.IncludeCheckIDs) > 0 {\n\t\t\tif _, ok := options.Selector.IncludeCheckIDs[info.ID]; ok {\n\t\t\t\tselectedChecks = append(selectedChecks, check)\n\t\t\t\tlog.Debugf(\"linter.Execute: selected check - id=%v (IncludeCheckIDs)\", info.ID)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(options.Selector.IncludeCheckLabels) > 0 {\n\t\t\tfor k, v := range info.Labels {\n\t\t\t\tif inval := options.Selector.IncludeCheckLabels[k]; inval == v {\n\t\t\t\t\tif len(options.Selector.ExcludeCheckIDs) == 0 {\n\t\t\t\t\t\tselectedChecks = append(selectedChecks, check)\n\t\t\t\t\t\tlog.Debugf(\"linter.Execute: selected check - id=%v label=%v:%v (IncludeCheckLabels)\", info.ID, k, v)\n\t\t\t\t\t} else if _, ok := options.Selector.ExcludeCheckIDs[info.ID]; !ok {\n\t\t\t\t\t\tselectedChecks = append(selectedChecks, check)\n\t\t\t\t\t\tlog.Debugf(\"linter.Execute: selected check - id=%v label=%v:%v (IncludeCheckLabels/ExcludeCheckIDs)\", info.ID, k, v)\n\t\t\t\t\t}\n\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(options.Selector.ExcludeCheckLabels) > 0 {\n\t\t\tfor k, v := range info.Labels {\n\t\t\t\tif inval := options.Selector.ExcludeCheckLabels[k]; inval == v {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(options.Selector.ExcludeCheckIDs) > 0 {\n\t\t\tif _, ok := options.Selector.ExcludeCheckIDs[info.ID]; ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tselectedChecks = append(selectedChecks, check)\n\t\tlog.Debugf(\"linter.Execute: selected check - id=%v\", info.ID)\n\t}\n\n\tif len(selectedChecks) == 0 {\n\t\treport.Status = StatusComplete\n\t\treturn report, nil\n\t}\n\n\treport.Status = StatusRunning\n\n\tcheckContext := &check.Context{\n\t\tDockerfilePath:  options.DockerfilePath,\n\t\tDockerfile:      df,\n\t\tBuildContextDir: options.BuildContextDir,\n\t\tDockerignore:    di,\n\t}\n\n\tstateCh := make(chan *CheckState, len(selectedChecks))\n\tvar workers sync.WaitGroup\n\tworkers.Add(len(selectedChecks))\n\n\tfor _, c := range selectedChecks {\n\t\tgo func(c check.Runner) {\n\t\t\tdefer workers.Done()\n\t\t\tinfo := c.Get()\n\t\t\tvar checkOptions *check.Options\n\t\t\tif len(options.Config) > 0 {\n\t\t\t\tcheckOptions = options.Config[info.ID]\n\t\t\t}\n\n\t\t\tstate := &CheckState{\n\t\t\t\tCheck:   c,\n\t\t\t\tOptions: checkOptions,\n\t\t\t\tContext: checkContext,\n\t\t\t}\n\n\t\t\tresult, err := c.Run(checkOptions, checkContext)\n\n\t\t\tstate.Result = result\n\t\t\tstate.Error = err\n\t\t\tstateCh <- state\n\t\t}(c)\n\t}\n\n\tgo func() {\n\t\tworkers.Wait()\n\t\tclose(stateCh)\n\t}()\n\n\ttimeout := time.After(120 * time.Second)\ndone:\n\tfor {\n\t\tselect {\n\t\tcase checkState, ok := <-stateCh:\n\t\t\tif !ok {\n\t\t\t\treport.Status = StatusComplete\n\t\t\t\tbreak done\n\t\t\t}\n\t\t\tif checkState != nil {\n\t\t\t\tinfo := checkState.Check.Get()\n\t\t\t\tif checkState.Error != nil {\n\t\t\t\t\treport.Errors[info.ID] = checkState.Error\n\t\t\t\t} else {\n\t\t\t\t\tif checkState.Result.Hit {\n\t\t\t\t\t\treport.Hits[info.ID] = checkState.Result\n\t\t\t\t\t} else {\n\t\t\t\t\t\treport.NoHits[info.ID] = checkState.Result\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase <-timeout:\n\t\t\treport.Status = StatusTimedOut\n\t\t\tbreak done\n\t\t}\n\t}\n\n\treturn report, nil\n}\n\nfunc ListChecks() []*check.Info {\n\tvar list []*check.Info\n\tfor _, check := range check.AllChecks {\n\t\tinfo := check.Get()\n\t\tlist = append(list, info)\n\t}\n\n\treturn list\n}\n"
  },
  {
    "path": "pkg/errors/errors.go",
    "content": "package errors\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n)\n\ntype SensorError struct {\n\tOp      string        `json:\"op\"`\n\tKind    string        `json:\"kind\"`\n\tNext    *SensorError  `json:\"next,omitempty\"`\n\tWrapped *WrappedError `json:\"wrapped,omitempty\"`\n}\n\ntype WrappedError struct {\n\tType string `json:\"type\"`\n\tInfo string `json:\"info\"`\n\tFile string `json:\"file\"`\n\tLine int    `json:\"line\"`\n}\n\nfunc (e *SensorError) Error() string {\n\terrStr := \"\"\n\tif e.Next != nil {\n\t\terrStr = fmt.Sprintf(\",Next:%s\", e.Next.Error())\n\t}\n\tif e.Wrapped != nil {\n\t\tif errStr == \"\" {\n\t\t\terrStr = fmt.Sprintf(\",Wrapped:{Type=%s,Info=%s,Line:%d,File:%s}\", e.Wrapped.Type, e.Wrapped.Info, e.Wrapped.Line, e.Wrapped.File)\n\t\t} else {\n\t\t\terrStr = fmt.Sprintf(\"%s,Wrapped:{Type=%s,Info=%s,Line:%d,File:%s}\", errStr, e.Wrapped.Type, e.Wrapped.Info, e.Wrapped.Line, e.Wrapped.File)\n\t\t}\n\t}\n\n\treturn fmt.Sprintf(\"SensorError{Op:%s,Kind:%s%s}\", e.Op, e.Kind, errStr)\n}\n\nfunc SE(op string, kind string, err error) *SensorError {\n\te := &SensorError{\n\t\tOp:   op,\n\t\tKind: kind,\n\t}\n\n\tif next, ok := err.(*SensorError); ok {\n\t\te.Next = next\n\t} else {\n\t\te.Wrapped = &WrappedError{\n\t\t\tType: fmt.Sprintf(\"%T\", err),\n\t\t\tInfo: err.Error(),\n\t\t}\n\n\t\tif _, file, line, ok := runtime.Caller(1); ok {\n\t\t\te.Wrapped.File = file\n\t\t\te.Wrapped.Line = line\n\t\t}\n\t}\n\n\treturn e\n}\n\nfunc Drain(ch <-chan error) (arr []error) {\n\tfor {\n\t\tselect {\n\t\tcase e := <-ch:\n\t\t\tarr = append(arr, e)\n\t\tdefault:\n\t\t\treturn arr\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/imagebuilder/imagebuilder.go",
    "content": "package imagebuilder\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/slim/pkg/docker/instruction\"\n)\n\n// ImageConfig describes the container image configurations (aka ConfigFile or V1Image/Image in other libraries)\n// Fields (ordered according to spec):\n// * https://github.com/opencontainers/image-spec/blob/main/config.md#properties\n// * https://github.com/moby/moby/blob/e1c92184f08153456ecbf5e302a851afd6f28e1c/image/image.go#LL40C6-L40C13\n// Note: related to pkg/docker/dockerimage/V1ConfigObject|ConfigObject\n// TODO: refactor into one set of common structs later\ntype ImageConfig struct {\n\tCreated      time.Time `json:\"created,omitempty\"`\n\tAuthor       string    `json:\"author,omitempty\"`\n\tArchitecture string    `json:\"architecture\"`\n\tOS           string    `json:\"os\"`\n\tOSVersion    string    `json:\"os.version,omitempty\"`\n\tOSFeatures   []string  `json:\"os.features,omitempty\"`\n\tVariant      string    `json:\"variant,omitempty\"`\n\tConfig       RunConfig `json:\"config\"`\n\tRootFS       *RootFS   `json:\"rootfs\"`            //not used building images\n\tHistory      []History `json:\"history,omitempty\"` //not used building images\n\t//Extra fields\n\tContainer     string `json:\"container,omitempty\"`\n\tDockerVersion string `json:\"docker_version,omitempty\"`\n\t//More extra fields\n\tID      string `json:\"id,omitempty\"`\n\tComment string `json:\"comment,omitempty\"`\n}\n\ntype RootFS struct {\n\tType    string   `json:\"type\"`\n\tDiffIDs []string `json:\"diff_ids,omitempty\"`\n}\n\ntype History struct {\n\tCreated    string `json:\"created,omitempty\"`\n\tAuthor     string `json:\"author,omitempty\"`\n\tCreatedBy  string `json:\"created_by,omitempty\"`\n\tComment    string `json:\"comment,omitempty\"`\n\tEmptyLayer bool   `json:\"empty_layer,omitempty\"`\n}\n\n// RunConfig describes the runtime config parameters for container instances (aka Config in other libraries)\n// Fields (ordered according to spec): Memory, MemorySwap, CpuShares aren't necessary\n// * https://github.com/opencontainers/image-spec/blob/main/config.md#properties (Config field)\n// * https://github.com/moby/moby/blob/master/api/types/container/config.go#L70\n// Note: related to pkg/docker/dockerimage/ContainerConfig\n// TODO: refactor into one set of common structs later\ntype RunConfig struct {\n\tUser         string              `json:\"User,omitempty\"`\n\tExposedPorts map[string]struct{} `json:\"ExposedPorts,omitempty\"`\n\tEnv          []string            `json:\"Env,omitempty\"`\n\tEntrypoint   []string            `json:\"Entrypoint,omitempty\"`\n\tCmd          []string            `json:\"Cmd,omitempty\"`\n\tVolumes      map[string]struct{} `json:\"Volumes,omitempty\"`\n\tWorkingDir   string              `json:\"WorkingDir,omitempty\"`\n\tLabels       map[string]string   `json:\"Labels,omitempty\"`\n\tStopSignal   string              `json:\"StopSignal,omitempty\"`\n\tArgsEscaped  bool                `json:\"ArgsEscaped,omitempty\"`\n\tHealthcheck  *HealthConfig       `json:\"Healthcheck,omitempty\"`\n\t//Extra fields\n\tAttachStderr    bool     `json:\"AttachStderr,omitempty\"`\n\tAttachStdin     bool     `json:\"AttachStdin,omitempty\"`\n\tAttachStdout    bool     `json:\"AttachStdout,omitempty\"`\n\tDomainname      string   `json:\"Domainname,omitempty\"`\n\tHostname        string   `json:\"Hostname,omitempty\"`\n\tImage           string   `json:\"Image,omitempty\"`\n\tOnBuild         []string `json:\"OnBuild,omitempty\"`\n\tOpenStdin       bool     `json:\"OpenStdin,omitempty\"`\n\tStdinOnce       bool     `json:\"StdinOnce,omitempty\"`\n\tTty             bool     `json:\"Tty,omitempty\"`\n\tNetworkDisabled bool     `json:\"NetworkDisabled,omitempty\"`\n\tMacAddress      string   `json:\"MacAddress,omitempty\"`\n\tStopTimeout     *int     `json:\"StopTimeout,omitempty\"`\n\tShell           []string `json:\"Shell,omitempty\"`\n}\n\ntype HealthConfig struct {\n\tTest        []string      `json:\",omitempty\"`\n\tInterval    time.Duration `json:\",omitempty\"`\n\tTimeout     time.Duration `json:\",omitempty\"`\n\tStartPeriod time.Duration `json:\",omitempty\"`\n\tRetries     int           `json:\",omitempty\"`\n}\n\ntype SimpleBuildOptions struct {\n\tFrom        string\n\tTags        []string\n\tLayers      []LayerDataInfo\n\tImageConfig ImageConfig\n\n\t/*\n\t   //todo:  add 'Healthcheck'\n\t   Entrypoint   []string\n\t   Cmd          []string\n\t   WorkDir      string\n\t   User         string\n\t   StopSignal   string\n\t   OnBuild      []string\n\t   Volumes      map[string]struct{}\n\t   EnvVars      []string\n\t   ExposedPorts map[string]struct{}\n\t   Labels       map[string]string\n\t   Architecture string\n\t*/\n}\n\ntype LayerSourceType string\n\nconst (\n\tTarSource LayerSourceType = \"lst.tar\"\n\tDirSource LayerSourceType = \"lst.dir\"\n)\n\ntype LayerDataInfo struct {\n\tType   LayerSourceType\n\tSource string\n\tParams *DataParams\n\t//TODO: add other common layer metadata...\n}\n\ntype DataParams struct {\n\tTargetPath string\n\t//TODO: add useful fields (e.g., to filter directory files or to use specific file perms, etc)\n}\n\ntype ImageResult struct {\n\tID        string   `json:\"id,omitempty\"`\n\tDigest    string   `json:\"digest,omitempty\"`\n\tName      string   `json:\"name,omitempty\"`\n\tOtherTags []string `json:\"other_tags,omitempty\"`\n}\n\ntype SimpleBuildEngine interface {\n\tName() string\n\tBuild(options SimpleBuildOptions) (*ImageResult, error)\n}\n\nfunc SimpleBuildOptionsFromDockerfileData(data string, ignoreExeInstructions bool) (*SimpleBuildOptions, error) {\n\tvar options SimpleBuildOptions\n\tlines := strings.Split(data, \"\\n\")\n\n\tfor _, line := range lines {\n\t\tline = strings.TrimSpace(line)\n\t\tif strings.HasPrefix(line, \"#\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tparts := strings.SplitN(line, \" \", 2)\n\t\tif len(parts) != 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\tinstName := strings.ToLower(parts[0])\n\t\tswitch instName {\n\t\tcase instruction.Entrypoint:\n\t\t\t//options.Entrypoint []string\n\t\tcase instruction.Cmd:\n\t\t\t//options.Cmd []string\n\t\tcase instruction.Env:\n\t\t\t//options.EnvVars []string\n\t\tcase instruction.Expose:\n\t\t\t//options.ExposedPorts map[string]struct{}\n\t\tcase instruction.Label:\n\t\t\t//options.Labels map[string]string\n\t\tcase instruction.User:\n\t\t\t//options.User = parts[1]\n\t\t\toptions.ImageConfig.Config.User = parts[1]\n\t\tcase instruction.Volume:\n\t\t\t//options.Volumes map[string]struct{}\n\t\tcase instruction.Workdir:\n\t\t\t//options.WorkDir = parts[1]\n\t\t\toptions.ImageConfig.Config.WorkingDir = parts[1]\n\t\tcase instruction.Add:\n\t\t\t//support tar files (ignore other things, at leas, for now)\n\t\t\t//options.Layers []LayerDataInfo\n\t\tcase instruction.Copy:\n\t\t\t//options.Layers []LayerDataInfo\n\t\tcase instruction.Maintainer:\n\t\t\t//TBD\n\t\tcase instruction.Healthcheck:\n\t\t\t//TBD\n\t\tcase instruction.From:\n\t\t\t//options.From string\n\t\tcase instruction.Arg:\n\t\t\t//TODO\n\t\tcase instruction.Run:\n\t\t\tif !ignoreExeInstructions {\n\t\t\t\treturn nil, fmt.Errorf(\"RUN instructions are not supported\")\n\t\t\t}\n\t\tcase instruction.Onbuild:\n\t\t\t//IGNORE\n\t\tcase instruction.Shell:\n\t\t\t//IGNORE\n\t\tcase instruction.StopSignal:\n\t\t\t//IGNORE\n\t\t}\n\t}\n\treturn &options, nil\n}\n\nfunc SimpleBuildOptionsFromDockerfile(path string, ignoreExeInstructions bool) (*SimpleBuildOptions, error) {\n\tdata, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn SimpleBuildOptionsFromDockerfileData(string(data), ignoreExeInstructions)\n}\n\nfunc SimpleBuildOptionsFromImageConfig(data *ImageConfig) (*SimpleBuildOptions, error) {\n\treturn &SimpleBuildOptions{ImageConfig: *data}, nil\n}\n"
  },
  {
    "path": "pkg/imagebuilder/internalbuilder/engine.go",
    "content": "package internalbuilder\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/daemon\"\n\t\"github.com/google/go-containerregistry/pkg/v1/empty\"\n\t\"github.com/google/go-containerregistry/pkg/v1/mutate\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/imagebuilder\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nconst (\n\tName = \"internal.container.build.engine\"\n)\n\n// Engine is the default simple build engine\ntype Engine struct {\n\tShowBuildLogs  bool\n\tPushToDaemon   bool\n\tPushToRegistry bool\n}\n\n// New creates new Engine instances\nfunc New(\n\tshowBuildLogs bool,\n\tpushToDaemon bool,\n\tpushToRegistry bool) (*Engine, error) {\n\n\tengine := &Engine{\n\t\tShowBuildLogs:  showBuildLogs,\n\t\tPushToDaemon:   pushToDaemon,\n\t\tPushToRegistry: pushToRegistry,\n\t}\n\n\treturn engine, nil\n}\n\nfunc (ref *Engine) Build(options imagebuilder.SimpleBuildOptions) (*imagebuilder.ImageResult, error) {\n\tif len(options.ImageConfig.Config.Entrypoint) == 0 &&\n\t\tlen(options.ImageConfig.Config.Cmd) == 0 {\n\t\treturn nil, fmt.Errorf(\"missing startup info\")\n\t}\n\n\tif len(options.Layers) == 0 {\n\t\treturn nil, fmt.Errorf(\"no layers\")\n\t}\n\n\tif len(options.Layers) > 255 {\n\t\treturn nil, fmt.Errorf(\"too many layers\")\n\t}\n\n\tswitch options.ImageConfig.Architecture {\n\tcase \"\":\n\t\toptions.ImageConfig.Architecture = \"amd64\"\n\tcase \"arm64\", \"amd64\":\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"bad architecture value\")\n\t}\n\n\tvar img v1.Image\n\tif options.From == \"\" {\n\t\t//same as FROM scratch\n\t\timg = empty.Image\n\t} else {\n\t\treturn nil, fmt.Errorf(\"custom base images are not supported yet\")\n\t}\n\n\timgRunConfig := v1.Config{\n\t\tUser:            options.ImageConfig.Config.User,\n\t\tExposedPorts:    options.ImageConfig.Config.ExposedPorts,\n\t\tEnv:             options.ImageConfig.Config.Env,\n\t\tEntrypoint:      options.ImageConfig.Config.Entrypoint,\n\t\tCmd:             options.ImageConfig.Config.Cmd,\n\t\tVolumes:         options.ImageConfig.Config.Volumes,\n\t\tWorkingDir:      options.ImageConfig.Config.WorkingDir,\n\t\tLabels:          options.ImageConfig.Config.Labels,\n\t\tStopSignal:      options.ImageConfig.Config.StopSignal,\n\t\tArgsEscaped:     options.ImageConfig.Config.ArgsEscaped,\n\t\tAttachStderr:    options.ImageConfig.Config.AttachStderr,\n\t\tAttachStdin:     options.ImageConfig.Config.AttachStdin,\n\t\tAttachStdout:    options.ImageConfig.Config.AttachStdout,\n\t\tDomainname:      options.ImageConfig.Config.Domainname,\n\t\tHostname:        options.ImageConfig.Config.Hostname,\n\t\tImage:           options.ImageConfig.Config.Image,\n\t\tOnBuild:         options.ImageConfig.Config.OnBuild,\n\t\tOpenStdin:       options.ImageConfig.Config.OpenStdin,\n\t\tStdinOnce:       options.ImageConfig.Config.StdinOnce,\n\t\tTty:             options.ImageConfig.Config.Tty,\n\t\tNetworkDisabled: options.ImageConfig.Config.NetworkDisabled,\n\t\tMacAddress:      options.ImageConfig.Config.MacAddress,\n\t\tShell:           options.ImageConfig.Config.Shell,\n\t}\n\n\tif options.ImageConfig.Config.Healthcheck != nil {\n\t\timgRunConfig.Healthcheck = &v1.HealthConfig{\n\t\t\tTest:        options.ImageConfig.Config.Healthcheck.Test,\n\t\t\tInterval:    options.ImageConfig.Config.Healthcheck.Interval,\n\t\t\tTimeout:     options.ImageConfig.Config.Healthcheck.Timeout,\n\t\t\tStartPeriod: options.ImageConfig.Config.Healthcheck.StartPeriod,\n\t\t\tRetries:     options.ImageConfig.Config.Healthcheck.Retries,\n\t\t}\n\t}\n\n\timgConfig := &v1.ConfigFile{\n\t\tCreated:      v1.Time{Time: time.Now()},\n\t\tAuthor:       options.ImageConfig.Author,\n\t\tArchitecture: options.ImageConfig.Architecture,\n\t\tOS:           options.ImageConfig.OS,\n\t\tOSVersion:    options.ImageConfig.OSVersion,\n\t\tOSFeatures:   options.ImageConfig.OSFeatures,\n\t\tVariant:      options.ImageConfig.Variant,\n\t\tConfig:       imgRunConfig,\n\t\t//History - not setting for now (actual history needs to match the added layers)\n\t\tContainer:     options.ImageConfig.Container,\n\t\tDockerVersion: options.ImageConfig.DockerVersion,\n\t}\n\n\tif imgConfig.OS == \"\" {\n\t\timgConfig.OS = \"linux\"\n\t}\n\n\tif imgConfig.Author == \"\" {\n\t\timgConfig.Author = \"slimtoolkit\"\n\t}\n\n\tif !options.ImageConfig.Created.IsZero() {\n\t\timgConfig.Created = v1.Time{Time: options.ImageConfig.Created}\n\t}\n\n\tlog.Debug(\"DefaultSimpleBuilder.Build: config image\")\n\n\timg, err := mutate.ConfigFile(img, imgConfig)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar layersToAdd []v1.Layer\n\n\tfor i, layerInfo := range options.Layers {\n\t\tlog.Debugf(\"DefaultSimpleBuilder.Build: [%d] create image layer (type=%v source=%s)\",\n\t\t\ti, layerInfo.Type, layerInfo.Source)\n\n\t\tif layerInfo.Source == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"empty image layer data source\")\n\t\t}\n\n\t\tif !fsutil.Exists(layerInfo.Source) {\n\t\t\treturn nil, fmt.Errorf(\"image layer data source path doesnt exist - %s\", layerInfo.Source)\n\t\t}\n\n\t\tswitch layerInfo.Type {\n\t\tcase imagebuilder.TarSource:\n\t\t\tif !fsutil.IsRegularFile(layerInfo.Source) {\n\t\t\t\treturn nil, fmt.Errorf(\"image layer data source path is not a file - %s\", layerInfo.Source)\n\t\t\t}\n\n\t\t\tif !fsutil.IsTarFile(layerInfo.Source) {\n\t\t\t\treturn nil, fmt.Errorf(\"image layer data source path is not a tar file - %s\", layerInfo.Source)\n\t\t\t}\n\n\t\t\tlayer, err := layerFromTar(layerInfo)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tlayersToAdd = append(layersToAdd, layer)\n\t\tcase imagebuilder.DirSource:\n\t\t\tif !fsutil.IsDir(layerInfo.Source) {\n\t\t\t\treturn nil, fmt.Errorf(\"image layer data source path is not a directory - %s\", layerInfo.Source)\n\t\t\t}\n\n\t\t\tlayer, err := layerFromDir(layerInfo)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tlayersToAdd = append(layersToAdd, layer)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unknown image data source - %v\", layerInfo.Source)\n\t\t}\n\t}\n\n\tlog.Debug(\"DefaultSimpleBuilder.Build: adding layers to image\")\n\tnewImg, err := mutate.AppendLayers(img, layersToAdd...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(options.Tags) == 0 {\n\t\treturn nil, fmt.Errorf(\"missing tags\")\n\t}\n\n\ttag, err := name.NewTag(options.Tags[0])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\totherTags := options.Tags[1:]\n\n\tif ref.PushToDaemon {\n\t\tlog.Debug(\"DefaultSimpleBuilder.Build: saving image to Docker\")\n\t\timageLoadResponseStr, err := daemon.Write(tag, newImg)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tlog.Debugf(\"DefaultSimpleBuilder.Build: pushed image to daemon - %s\", imageLoadResponseStr)\n\t\tif ref.ShowBuildLogs {\n\t\t\t//TBD (need execution context to display the build logs)\n\t\t}\n\n\t\tif len(otherTags) > 0 {\n\t\t\tlog.Debug(\"DefaultSimpleBuilder.Build: adding other tags\")\n\n\t\t\tfor _, tagName := range otherTags {\n\t\t\t\tntag, err := name.NewTag(tagName)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"DefaultSimpleBuilder.Build: error creating tag: %v\", err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif err := daemon.Tag(tag, ntag); err != nil {\n\t\t\t\t\tlog.Errorf(\"DefaultSimpleBuilder.Build: error tagging: %v\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif ref.PushToRegistry {\n\t\t//TBD\n\t}\n\n\tid, _ := newImg.ConfigName()\n\tdigest, _ := newImg.Digest()\n\tresult := &imagebuilder.ImageResult{\n\t\tName:      options.Tags[0],\n\t\tOtherTags: otherTags,\n\t\tID:        fmt.Sprintf(\"%s:%s\", id.Algorithm, id.Hex),\n\t\tDigest:    fmt.Sprintf(\"%s:%s\", digest.Algorithm, digest.Hex),\n\t}\n\n\treturn result, nil\n}\n\nfunc layerFromTar(input imagebuilder.LayerDataInfo) (v1.Layer, error) {\n\tif !fsutil.Exists(input.Source) ||\n\t\t!fsutil.IsRegularFile(input.Source) {\n\t\treturn nil, fmt.Errorf(\"bad input data\")\n\t}\n\n\treturn tarball.LayerFromFile(input.Source)\n}\n\nfunc layerFromDir(input imagebuilder.LayerDataInfo) (v1.Layer, error) {\n\tif !fsutil.Exists(input.Source) ||\n\t\t!fsutil.IsDir(input.Source) {\n\t\treturn nil, fmt.Errorf(\"bad input data\")\n\t}\n\n\tvar b bytes.Buffer\n\ttw := tar.NewWriter(&b)\n\n\tlayerBasePath := \"/\"\n\tif input.Params != nil && input.Params.TargetPath != \"\" {\n\t\tlayerBasePath = input.Params.TargetPath\n\t}\n\n\terr := filepath.Walk(input.Source, func(fp string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\t\trel, err := filepath.Rel(input.Source, fp)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to calculate relative path: %w\", err)\n\t\t}\n\n\t\thdr := &tar.Header{\n\t\t\tName: path.Join(layerBasePath, filepath.ToSlash(rel)),\n\t\t\tMode: int64(info.Mode()),\n\t\t}\n\n\t\tif !info.IsDir() {\n\t\t\thdr.Size = info.Size()\n\t\t}\n\n\t\tif info.Mode().IsDir() {\n\t\t\thdr.Typeflag = tar.TypeDir\n\t\t} else if info.Mode().IsRegular() {\n\t\t\thdr.Typeflag = tar.TypeReg\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"not implemented archiving file type %s (%s)\", info.Mode(), rel)\n\t\t}\n\n\t\tif err := tw.WriteHeader(hdr); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write tar header: %w\", err)\n\t\t}\n\t\tif !info.IsDir() {\n\t\t\tf, err := os.Open(fp)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif _, err := io.Copy(tw, f); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to read file into the tar: %w\", err)\n\t\t\t}\n\t\t\tf.Close()\n\t\t}\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to scan files: %w\", err)\n\t}\n\tif err := tw.Close(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to finish tar: %w\", err)\n\t}\n\n\treturn tarball.LayerFromReader(&b)\n}\n"
  },
  {
    "path": "pkg/imagereader/imagereader.go",
    "content": "package imagereader\n\nimport (\n\t\"os\"\n\n\t\"github.com/google/go-containerregistry/pkg/crane\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/daemon\"\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/imagebuilder\"\n)\n\ntype Instance struct {\n\timageName       string\n\tnameRef         name.Reference\n\timageRef        v1.Image\n\texportedTarPath string\n\timageConfig     *imagebuilder.ImageConfig\n}\n\nfunc New(imageName string) (*Instance, error) {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"op\":         \"imagereader.New\",\n\t\t\"image.name\": imageName,\n\t})\n\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tref, err := name.ParseReference(imageName) //, name.WeakValidation)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"name.ParseReference\")\n\t\treturn nil, err\n\t}\n\n\t//TODO/FUTURE: add other image source options (not just local Docker daemon)\n\t//TODO/ASAP: need to pass the 'daemon' client otherwise it'll fail if the default client isn't enough\n\timg, err := daemon.Image(ref)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"daemon.Image\")\n\t\treturn nil, err\n\t}\n\n\tinstance := &Instance{\n\t\timageName: imageName,\n\t\tnameRef:   ref,\n\t\timageRef:  img,\n\t}\n\n\treturn instance, nil\n}\n\nfunc (ref *Instance) ImageConfig() (*imagebuilder.ImageConfig, error) {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"op\":         \"imagereader.Instance.ImageConfig\",\n\t\t\"image.name\": ref.imageName,\n\t})\n\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tif ref.imageConfig != nil {\n\t\treturn ref.imageConfig, nil\n\t}\n\n\tcf, err := ref.imageRef.ConfigFile()\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"v1.Image.ConfigFile\")\n\t\treturn nil, err\n\t}\n\n\tref.imageConfig = &imagebuilder.ImageConfig{\n\t\tCreated:      cf.Created.Time,\n\t\tAuthor:       cf.Author,\n\t\tArchitecture: cf.Architecture,\n\t\tOS:           cf.OS,\n\t\tOSVersion:    cf.OSVersion,\n\t\tOSFeatures:   cf.OSFeatures,\n\t\tVariant:      cf.Variant,\n\t\t//RootFS       *RootFS   `json:\"rootfs\"`            //not used building images\n\t\t//History      []History `json:\"history,omitempty\"` //not used building images\n\t\tContainer:     cf.Container,\n\t\tDockerVersion: cf.DockerVersion,\n\t\tConfig: imagebuilder.RunConfig{\n\t\t\tUser:            cf.Config.User,\n\t\t\tExposedPorts:    cf.Config.ExposedPorts,\n\t\t\tEnv:             cf.Config.Env,\n\t\t\tEntrypoint:      cf.Config.Entrypoint,\n\t\t\tCmd:             cf.Config.Cmd,\n\t\t\tVolumes:         cf.Config.Volumes,\n\t\t\tWorkingDir:      cf.Config.WorkingDir,\n\t\t\tLabels:          cf.Config.Labels,\n\t\t\tStopSignal:      cf.Config.StopSignal,\n\t\t\tArgsEscaped:     cf.Config.ArgsEscaped,\n\t\t\tAttachStderr:    cf.Config.AttachStderr,\n\t\t\tAttachStdin:     cf.Config.AttachStdin,\n\t\t\tAttachStdout:    cf.Config.AttachStdout,\n\t\t\tDomainname:      cf.Config.Domainname,\n\t\t\tHostname:        cf.Config.Hostname,\n\t\t\tImage:           cf.Config.Image,\n\t\t\tOnBuild:         cf.Config.OnBuild,\n\t\t\tOpenStdin:       cf.Config.OpenStdin,\n\t\t\tStdinOnce:       cf.Config.StdinOnce,\n\t\t\tTty:             cf.Config.Tty,\n\t\t\tNetworkDisabled: cf.Config.NetworkDisabled,\n\t\t\tMacAddress:      cf.Config.MacAddress,\n\t\t\tShell:           cf.Config.Shell, //??\n\t\t\t//Healthcheck  *HealthConfig       `json:\"Healthcheck,omitempty\"`\n\t\t},\n\t}\n\n\treturn ref.imageConfig, nil\n}\n\nfunc (ref *Instance) FreeExportedFilesystem() error {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"op\":         \"imagereader.Instance.FreeExportedFilesystem\",\n\t\t\"image.name\": ref.imageName,\n\t})\n\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tif ref.exportedTarPath == \"\" {\n\t\treturn nil\n\t}\n\n\terr := os.Remove(ref.exportedTarPath)\n\tref.exportedTarPath = \"\"\n\treturn err\n}\n\nfunc (ref *Instance) ExportFilesystem() (string, error) {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"op\":         \"imagereader.Instance.ExportFilesystem\",\n\t\t\"image.name\": ref.imageName,\n\t})\n\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tif ref.exportedTarPath != \"\" {\n\t\treturn ref.exportedTarPath, nil\n\t}\n\n\ttarFile, err := os.CreateTemp(\"\", \"image-exported-fs-*.tar\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tdefer tarFile.Close()\n\n\terr = crane.Export(ref.imageRef, tarFile)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif _, err := os.Stat(tarFile.Name()); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tref.exportedTarPath = tarFile.Name()\n\treturn ref.exportedTarPath, nil\n}\n\nfunc (ref *Instance) ExportedTarPath() string {\n\treturn ref.exportedTarPath\n}\n"
  },
  {
    "path": "pkg/ipc/channel/channel.go",
    "content": "package channel\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"net\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n)\n\nvar (\n\tErrNoData           = errors.New(\"no data\")\n\tErrFrameTIDMismatch = errors.New(\"frame TID mismatch\")\n\tErrFrameUnexpected  = errors.New(\"unexpected frame type\")\n\tErrRemoteError      = errors.New(\"remote error\")\n\tErrWaitTimeout      = errors.New(\"wait timeout\")\n\tErrFrameMalformed   = errors.New(\"malformed frame\")\n)\n\n// Channel ports\nconst (\n\tCmdPort = 65501\n\tEvtPort = 65502\n)\n\nconst (\n\tproto                         = \"tcp\"\n\tdefaultConnectTimeoutDuration = 11 * time.Second\n\tdefaultReadTimeoutDuration    = 11 * time.Second\n\tdefaultWriteTimeoutDuration   = 11 * time.Second\n\tmsgEndByte                    = '\\n'\n)\n\nvar (\n\tframeHeader  = []byte(\"[<|]\")\n\tframeTrailer = []byte(\"[|>]\\n\")\n)\n\n// FrameType is a Frame struct type\ntype FrameType string\n\n// Supported frame types\nconst (\n\tRequestFrameType  FrameType = \"ft.request\"\n\tResponseFrameType FrameType = \"ft.response\"\n\tEventFrameType    FrameType = \"ft.event\"\n\tErrorFrameType    FrameType = \"ft.error\"\n\tControlFrameType  FrameType = \"ft.control\"\n)\n\ntype Frame struct {\n\tTID  string          `json:\"tid\"`\n\tType FrameType       `json:\"type\"`\n\tBody json.RawMessage `json:\"body,omitempty\"`\n}\n\nfunc newFrame(ftype FrameType, data []byte, tid string) *Frame {\n\tframe := Frame{\n\t\tType: ftype,\n\t\tBody: data,\n\t}\n\n\tif tid != \"\" {\n\t\tframe.TID = tid\n\t} else {\n\t\tframe.TID = GenerateTID()\n\t}\n\n\treturn &frame\n}\n\nfunc createFrameBytes(frame *Frame) ([]byte, error) {\n\traw, err := json.Marshal(frame)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar b bytes.Buffer\n\tb.Write(frameHeader)\n\tb.Write(raw)\n\tb.Write(frameTrailer)\n\n\treturn b.Bytes(), nil\n}\n\nfunc createFrameBytesFromFields(ftype FrameType, data []byte, tid string) ([]byte, error) {\n\tframe := newFrame(ftype, data, tid)\n\treturn createFrameBytes(frame)\n}\n\nfunc GenerateTID() string {\n\tnow := time.Now().UnixNano()\n\trandom := make([]byte, 8)\n\trand.Read(random)\n\treturn fmt.Sprintf(\"%d.%s\", now, hex.EncodeToString(random))\n}\n\nfunc getFrame(raw []byte) (*Frame, error) {\n\tif len(raw) > (len(frameHeader)+len(frameTrailer)) && bytes.HasPrefix(raw, frameHeader) && bytes.HasSuffix(raw, frameTrailer) {\n\t\tdata := raw[len(frameHeader) : len(raw)-len(frameTrailer)]\n\n\t\tvar frame Frame\n\t\tif err := json.Unmarshal(data, &frame); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn &frame, nil\n\t}\n\n\treturn nil, ErrFrameMalformed\n}\n\ntype ConnectionHandler interface {\n\tOnConnection(conn net.Conn)\n}\n\ntype Server struct {\n\taddr     string\n\tlistener net.Listener\n\thandler  ConnectionHandler\n}\n\nfunc NewServer(addr string) *Server {\n\tserver := Server{\n\t\taddr: addr,\n\t}\n\n\treturn &server\n}\n\nfunc (s *Server) SetConnHandler(handler ConnectionHandler) {\n\ts.handler = handler\n}\n\nfunc (s *Server) Start(async bool) error {\n\tvar err error\n\tlog.Debugf(\"channel.Server.Start() - addr=%v [time=%v]\", s.addr, time.Now().UnixNano())\n\ts.listener, err = net.Listen(proto, s.addr)\n\tif err != nil {\n\t\tlog.Debugf(\"channel:Server.Start() - net.Listen error = %v\", err)\n\t\treturn err\n\t}\n\n\tloop := func() {\n\t\tlog.Debugf(\"channel.Server.Start.loop()... [time=%v]\", time.Now().UnixNano())\n\t\tfor {\n\t\t\tconn, err := s.listener.Accept()\n\t\t\tlog.Debugf(\"channel.Server.Start.loop.Accept - new connection... [time=%v]\", time.Now().UnixNano())\n\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"channel.Server.Start() - loop.Accept error = %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tlog.Debugf(\"channel.Server.Start.loop(): new connection = %s -> %s\", conn.RemoteAddr(), conn.LocalAddr())\n\n\t\t\tif s.handler != nil {\n\t\t\t\tlog.Debug(\"channel.Server.Start.loop(): new connection - call handler...\")\n\t\t\t\ts.handler.OnConnection(conn)\n\t\t\t}\n\t\t}\n\t}\n\n\tif async {\n\t\tgo loop()\n\t} else {\n\t\tloop()\n\t}\n\n\treturn nil\n}\n\nfunc (s *Server) Stop() {\n\tif s.listener != nil {\n\t\ts.listener.Close()\n\t}\n}\n\ntype EventServer struct {\n\t*Server\n\n\tmu    sync.Mutex\n\tlinks []net.Conn\n\n\tpending chan struct{}\n}\n\nfunc NewEventServer(addr string) *EventServer {\n\tserver := &EventServer{\n\t\tServer:  NewServer(addr),\n\t\tpending: make(chan struct{}),\n\t}\n\n\tserver.SetConnHandler(server)\n\treturn server\n}\n\nfunc (s *EventServer) OnConnection(conn net.Conn) {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\ts.links = append(s.links, conn)\n\n\tselect {\n\tcase <-s.pending: // Has already been closed\n\t\tbreak\n\tdefault:\n\t\tclose(s.pending)\n\t}\n}\n\nfunc (s *EventServer) WaitForConnection() {\n\t<-s.pending\n}\n\nfunc (s *EventServer) Publish(data []byte, retries uint) error {\n\tif len(data) == 0 {\n\t\treturn nil\n\t}\n\n\tframe, err := createFrameBytesFromFields(EventFrameType, data, \"\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor _, conn := range s.links {\n\t\ttimeouts := uint(0)\n\t\tfor {\n\t\t\tconn.SetWriteDeadline(time.Now().Add(defaultWriteTimeoutDuration))\n\t\t\tn, err := conn.Write(frame)\n\t\t\tlog.Debugf(\"channel.Broadcast.Write: %s -> %s - conn.Write wc=%v err=%v\", conn.RemoteAddr(), conn.LocalAddr(), n, err)\n\t\t\tif err == nil {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif os.IsTimeout(err) {\n\t\t\t\tlog.Debugf(\"channel.Broadcast.Write: %s -> %s - write timeout...\", conn.RemoteAddr(), conn.LocalAddr())\n\t\t\t\ttimeouts++\n\t\t\t\tif retries > 0 && timeouts > retries {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t} else if err != nil {\n\t\t\t\tlog.Errorf(\"channel.Broadcast.Write: %s -> %s - write error = %v\", conn.RemoteAddr(), conn.LocalAddr(), err)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype Client struct {\n\taddr         string\n\tconn         net.Conn\n\treader       *bufio.Reader\n\treadTimeout  time.Duration\n\twriteTimeout time.Duration\n}\n\nfunc durationValue(vparam int, vdefault time.Duration) time.Duration {\n\tval := vdefault\n\n\tswitch {\n\tcase vparam > 0:\n\t\tval = time.Duration(vparam) * time.Second\n\tcase vparam < 0:\n\t\tval = 0\n\t}\n\n\treturn val\n}\n\nfunc NewClient(addr string, connectWait, connectTimeout, readTimeout, writeTimeout int) (*Client, error) {\n\tcwd := durationValue(connectWait, 0)\n\tctd := durationValue(connectTimeout, defaultConnectTimeoutDuration) //todo: use non-timeout net.Dial or net.DialContext\n\trtd := durationValue(readTimeout, defaultReadTimeoutDuration)\n\twtd := durationValue(writeTimeout, defaultWriteTimeoutDuration)\n\n\tclient := Client{\n\t\taddr:         addr,\n\t\treadTimeout:  rtd,\n\t\twriteTimeout: wtd,\n\t}\n\n\tvar timeout <-chan time.Time\n\tif cwd > 0 {\n\t\tlog.Debugf(\"channel.NewClient: connect wait timeout - %v\", cwd)\n\t\ttimeout = time.After(cwd)\n\t}\n\n\tconnectStart := time.Now()\ndone:\n\tfor {\n\t\tselect {\n\t\tcase <-timeout:\n\t\t\tlog.Debugf(\"channel.NewClient: connect wait timeout (waited=%v)\", time.Since(connectStart))\n\t\t\treturn nil, ErrWaitTimeout\n\t\tdefault:\n\t\t\tstart := time.Now()\n\t\t\tvar err error\n\t\t\tif ctd != 0 {\n\t\t\t\tlog.Debugf(\"channel.NewClient: net.DialTimeout(%v,%v,%v) [time=%v]\", proto, addr, ctd, time.Now().UnixNano())\n\t\t\t\tclient.conn, err = net.DialTimeout(proto, addr, ctd)\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"channel.NewClient: net.Dial(%v,%v)\", proto, addr)\n\t\t\t\tclient.conn, err = net.Dial(proto, addr)\n\t\t\t}\n\n\t\t\tif err == nil {\n\t\t\t\tbreak done\n\t\t\t}\n\n\t\t\tlog.Debugf(\"channel.NewClient: (dial time = %v) - connect error = %v\", time.Since(start), err)\n\n\t\t\tif connectWait < 1 {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tlog.Debug(\"channel.NewClient: waiting before trying to connect again...\")\n\t\t\ttime.Sleep(2 * time.Second)\n\t\t}\n\t}\n\n\tclient.reader = bufio.NewReader(client.conn)\n\n\treturn &client, nil\n}\n\nfunc (c *Client) Write(frame *Frame, retries uint) (n int, err error) {\n\tframeBytes, e := createFrameBytes(frame)\n\tif err != nil {\n\t\treturn 0, e\n\t}\n\n\ttimeouts := uint(0)\n\n\tfor {\n\t\tif c.writeTimeout != 0 {\n\t\t\tc.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))\n\t\t}\n\n\t\tn, err = c.conn.Write(frameBytes)\n\t\tlog.Debugf(\"channel.Client.Write: remote=%s -> local=%s - conn.Write wc=%v err=%v [time=%v]\", c.conn.RemoteAddr(), c.conn.LocalAddr(), n, err, time.Now().UnixNano())\n\t\tif err == nil {\n\t\t\treturn n, nil\n\t\t}\n\n\t\tif os.IsTimeout(err) {\n\t\t\tlog.Debugf(\"channel.Client.Write: %s -> %s - write timeout...\", c.conn.RemoteAddr(), c.conn.LocalAddr())\n\t\t\ttimeouts++\n\t\t\tif retries > 0 && timeouts > retries {\n\t\t\t\treturn\n\t\t\t}\n\t\t} else if err != nil {\n\t\t\tlog.Errorf(\"channel.Client.Write: %s -> %s - write error = %v\", c.conn.RemoteAddr(), c.conn.LocalAddr(), err)\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (c *Client) Read(retries uint) (*Frame, error) {\n\ttimeouts := uint(0)\n\n\tvar raw string\n\tfor {\n\t\tvar err error\n\t\tif c.readTimeout != 0 {\n\t\t\tc.conn.SetReadDeadline(time.Now().Add(c.readTimeout))\n\t\t}\n\t\traw, err = c.reader.ReadString(msgEndByte)\n\t\tlog.Debugf(\"channel.Client.Read() - (%p)reader.ReadString => err=%v raw=%#v\", c.reader, err, raw)\n\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tlog.Debug(\"channel.Client.Read: connection done...\")\n\t\t\t\treturn nil, err\n\t\t\t} else if os.IsTimeout(err) {\n\t\t\t\tlog.Debug(\"channel.Client.Read: read timeout...\")\n\t\t\t\ttimeouts++\n\t\t\t\tif retries > 0 && timeouts > retries {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\tlog.Errorf(\"channel.Client.Read: read error (%v), exiting...\", err)\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\tlog.Debugf(\"channel.Client.Read: got raw frame ='%s'\", raw)\n\t\tbreak\n\t}\n\n\tframe, err := getFrame([]byte(raw))\n\tif err != nil {\n\t\tlog.Infof(\"channel.Client.Read: malformed frame (%v) ='%s'\", len(raw), raw)\n\t\treturn nil, err\n\t}\n\n\tif frame != nil {\n\t\tlog.Debugf(\"channel.Client.Read: frame data => tid=%s type=%s body='%s'\",\n\t\t\tframe.TID, frame.Type, string(frame.Body))\n\t} else {\n\t\tlog.Infof(\"channel.Client.Read: malformed frame (%v) ='%s'\", len(raw), raw)\n\t}\n\n\treturn frame, nil\n}\n\nfunc (c *Client) Close() error {\n\treturn c.conn.Close()\n}\n\ntype EventClient struct {\n\t*Client\n}\n\nfunc NewEventClient(addr string, connectWait, connectTimeout, readTimeout int) (*EventClient, error) {\n\tclient, err := NewClient(addr, connectWait, connectTimeout, readTimeout, -1)\n\tif err != nil {\n\t\tlog.Errorf(\"channel.NewSubscriber: NewClient error = %v\", err)\n\t\treturn nil, err\n\t}\n\n\teventClient := &EventClient{\n\t\tClient: client,\n\t}\n\n\treturn eventClient, nil\n}\n\nfunc (c *EventClient) Next(retries uint) ([]byte, string, error) {\n\tframe, err := c.Read(retries)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\n\tif frame == nil {\n\t\tlog.Info(\"channel.EventClient.Next: c.Read() - no data, closed connection...\")\n\t\treturn nil, \"\", nil\n\t}\n\n\treturn frame.Body, frame.TID, nil\n}\n\ntype CommandClient struct {\n\t*Client\n}\n\nfunc NewCommandClient(addr string, connectWait, connectTimeout, readTimeout, writeTimeout int) (*CommandClient, error) {\n\tcwd := durationValue(connectWait, 0)\n\tvar timeout <-chan time.Time\n\tif cwd > 0 {\n\t\ttimeout = time.After(cwd)\n\t}\n\n\tconnectStart := time.Now()\n\tfor {\n\t\tselect {\n\t\tcase <-timeout:\n\t\t\tlog.Debugf(\"channel.NewCommandClient: connect wait timeout (waited=%v)...\", time.Since(connectStart))\n\t\t\treturn nil, ErrWaitTimeout\n\t\tdefault:\n\t\t\tclient, err := NewClient(addr, connectWait, connectTimeout, readTimeout, writeTimeout)\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"channel.NewCommandClient: NewClient error = %v\", err)\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\terr = verifyCommandChannel(client, 3)\n\t\t\tif err == nil {\n\t\t\t\tcmdClient := &CommandClient{\n\t\t\t\t\tClient: client,\n\t\t\t\t}\n\n\t\t\t\treturn cmdClient, nil\n\t\t\t}\n\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\tlog.Debug(\"channel.NewCommandClient: closed connection.\")\n\t\t\t} else {\n\t\t\t\tlog.Errorf(\"channel.NewCommandClient: channel verify error = %v\", err)\n\t\t\t}\n\n\t\t\tif connectWait < 1 {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tlog.Debugf(\"channel.NewCommandClient: waiting before trying to connect again...\")\n\t\t\ttime.Sleep(5 * time.Second)\n\t\t}\n\t}\n}\n\nfunc verifyCommandChannel(client *Client, retries uint) error {\n\treqFrame := newFrame(ControlFrameType, nil, \"\")\n\n\t_, err := client.Write(reqFrame, retries)\n\tif err != nil {\n\t\tlog.Errorf(\"verifyCommandChannel: client.Write error = %v\", err)\n\t\treturn err\n\t}\n\n\treplyFrame, err := client.Read(retries)\n\tif err != nil {\n\t\tlog.Debugf(\"verifyCommandChannel: client.Read error = %v\", err)\n\t\treturn err\n\t}\n\n\tif replyFrame == nil {\n\t\tlog.Info(\"verifyCommandChannel: client.Read() - no data\")\n\t\treturn ErrFrameUnexpected\n\t}\n\n\tlog.Debugf(\"verifyCommandChannel: client.Read() (tid=%v type=%v) result.data='%s'\",\n\t\treplyFrame.TID, replyFrame.Type, string(replyFrame.Body))\n\n\tif replyFrame.Type == ErrorFrameType {\n\t\treturn ErrRemoteError\n\t}\n\n\tif replyFrame.Type != ControlFrameType {\n\t\treturn ErrFrameUnexpected\n\t}\n\n\tif reqFrame.TID != replyFrame.TID {\n\t\tlog.Errorf(\"verifyCommandChannel: frame TID mismatch  %s = %s\", reqFrame.TID, replyFrame.TID)\n\t\treturn ErrFrameTIDMismatch\n\t}\n\n\treturn nil\n}\n\nfunc (c *CommandClient) Call(data []byte, retries uint) ([]byte, error) {\n\tlog.Debug(\"channel.CommandClient.Call: calling c.Write()\")\n\tif len(data) == 0 {\n\t\treturn nil, ErrNoData\n\t}\n\n\treqFrame := newFrame(RequestFrameType, data, \"\")\n\t_, err := c.Write(reqFrame, retries)\n\tif err != nil {\n\t\tlog.Errorf(\"channel.CommandClient.Call: c.Write error = %v\", err)\n\t\treturn nil, err\n\t}\n\n\tlog.Debugf(\"channel.CommandClient.Call: calling c.Read()\")\n\treplyFrame, err := c.Read(retries)\n\tif err != nil {\n\t\tlog.Errorf(\"channel.CommandClient.Call: c.Read error = %v\", err)\n\t\treturn nil, err\n\t}\n\n\tif replyFrame == nil {\n\t\tlog.Info(\"channel.CommandClient.Call: c.Read() - no data, closed connection...\")\n\t\treturn nil, nil\n\t}\n\n\tlog.Debugf(\"channel.CommandClient.Call: c.Read() (tid=%v type=%v) result.data='%s'\",\n\t\treplyFrame.TID, replyFrame.Type, string(replyFrame.Body))\n\n\tif replyFrame.Type == ErrorFrameType {\n\t\treturn nil, ErrRemoteError\n\t}\n\n\tif replyFrame.Type != ResponseFrameType {\n\t\treturn nil, ErrFrameUnexpected\n\t}\n\n\tif reqFrame.TID != replyFrame.TID {\n\t\tlog.Errorf(\"channel.CommandClient.Call: frame TID mismatch  %s = %s\", reqFrame.TID, replyFrame.TID)\n\t\treturn nil, ErrFrameTIDMismatch\n\t}\n\n\treturn replyFrame.Body, nil\n}\n\ntype RequestHandler interface {\n\tOnRequest(data []byte) ([]byte, error)\n}\n\ntype CommandServer struct {\n\t*Server\n\thandler RequestHandler\n\n\tpending chan struct{}\n}\n\nfunc NewCommandServer(addr string, handler RequestHandler) *CommandServer {\n\tserver := &CommandServer{\n\t\tServer:  NewServer(addr),\n\t\tpending: make(chan struct{}),\n\t}\n\n\tserver.SetConnHandler(server)\n\tserver.SetReqHandler(handler)\n\treturn server\n}\n\nfunc (s *CommandServer) SetReqHandler(handler RequestHandler) {\n\ts.handler = handler\n}\n\nfunc (s *CommandServer) WaitForConnection() {\n\t<-s.pending\n}\n\nfunc (s *CommandServer) OnConnection(conn net.Conn) {\n\tlog.Debugf(\"channel.CommandServer.OnConnection: %s -> %s\", conn.RemoteAddr(), conn.LocalAddr())\n\n\tselect {\n\tcase <-s.pending: // Has already been closed\n\t\tbreak\n\tdefault:\n\t\tclose(s.pending)\n\t}\n\n\tgo func() {\n\t\tdefer func() {\n\t\t\tlog.Debug(\"channel.CommandServer.OnConnection.worker: closing connection...\")\n\t\t\tconn.Close()\n\t\t}()\n\n\t\treader := bufio.NewReader(conn)\n\t\tfor {\n\t\t\tconn.SetReadDeadline(time.Now().Add(defaultReadTimeoutDuration))\n\t\t\tinRaw, err := reader.ReadString(msgEndByte)\n\t\t\tif err == io.EOF {\n\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - connection done...\", conn.RemoteAddr(), conn.LocalAddr())\n\t\t\t\treturn\n\t\t\t} else if os.IsTimeout(err) {\n\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - read timeout...\", conn.RemoteAddr(), conn.LocalAddr())\n\t\t\t\tcontinue\n\t\t\t} else if err != nil {\n\t\t\t\tlog.Errorf(\"channel.CommandServer.OnConnection.worker: %s -> %s - read error (%v)\", conn.RemoteAddr(), conn.LocalAddr(), err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif s.handler != nil {\n\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: raw frame => '%s'\", inRaw)\n\t\t\t\tinFrame, err := getFrame([]byte(inRaw))\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Errorf(\"channel.CommandServer.OnConnection.worker: %s -> %s - error getting frame (%v) [raw(%v)='%s']\",\n\t\t\t\t\t\tconn.RemoteAddr(), conn.LocalAddr(), err, len(inRaw), inRaw)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tif inFrame == nil {\n\t\t\t\t\tlog.Errorf(\"channel.CommandServer.OnConnection.worker: %s -> %s - no frame\", conn.RemoteAddr(), conn.LocalAddr())\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: in frame => tid=%v type=%v body='%s'\",\n\t\t\t\t\tinFrame.TID, inFrame.Type, string(inFrame.Body))\n\n\t\t\t\tvar outFrame []byte\n\t\t\t\tif inFrame.Type == ControlFrameType {\n\t\t\t\t\toutFrame, err = createFrameBytesFromFields(ControlFrameType, nil, inFrame.TID)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - error creating control out frame (%v)\", conn.RemoteAddr(), conn.LocalAddr(), err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\toutData, err := s.handler.OnRequest(inFrame.Body)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Errorf(\"channel.CommandServer.OnConnection.worker: handler.OnRequest error => %v\", err)\n\t\t\t\t\t\toutFrame, err = createFrameBytesFromFields(ErrorFrameType, nil, inFrame.TID)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tlog.Errorf(\"channel.CommandServer.OnConnection.worker: %s -> %s - error creating out frame (%v)\", conn.RemoteAddr(), conn.LocalAddr(), err)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutFrame, err = createFrameBytesFromFields(ResponseFrameType, outData, inFrame.TID)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - error creating out frame (%v)\", conn.RemoteAddr(), conn.LocalAddr(), err)\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor {\n\t\t\t\t\tconn.SetWriteDeadline(time.Now().Add(defaultWriteTimeoutDuration))\n\t\t\t\t\twc, err := conn.Write(outFrame)\n\t\t\t\t\t//todo handle timeouts properly\n\t\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - conn.Write wc=%v err=%v\", conn.RemoteAddr(), conn.LocalAddr(), wc, err)\n\t\t\t\t\tif err == nil {\n\t\t\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - replied with frame='%s'\", conn.RemoteAddr(), conn.LocalAddr(), string(outFrame))\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\tif os.IsTimeout(err) {\n\t\t\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - write timeout (trying again)...\", conn.RemoteAddr(), conn.LocalAddr())\n\t\t\t\t\t} else if err == io.EOF {\n\t\t\t\t\t\tlog.Debugf(\"channel.CommandServer.OnConnection.worker: %s -> %s - connection done (worker exiting)...\", conn.RemoteAddr(), conn.LocalAddr())\n\t\t\t\t\t\treturn\n\t\t\t\t\t} else if err != nil {\n\t\t\t\t\t\tlog.Errorf(\"channel.CommandServer.OnConnection.worker: %s -> %s - write error = %v (worker exiting)\", conn.RemoteAddr(), conn.LocalAddr(), err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n}\n"
  },
  {
    "path": "pkg/ipc/command/command.go",
    "content": "package command\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\n// Message errors\nvar (\n\tErrUnknownMessage = errors.New(\"unknown command type\")\n)\n\nconst (\n\tResponseStatusOk    = \"ok\"\n\tResponseStatusError = \"error\"\n)\n\n// Response contains the command response status information\ntype Response struct {\n\tStatus string `json:\"status\"`\n}\n\n// MessageName is a message ID type\ntype MessageName string\n\n// Supported messages\nconst (\n\tStartMonitorName   MessageName = \"cmd.monitor.start\"\n\tStopMonitorName    MessageName = \"cmd.monitor.stop\"\n\tShutdownSensorName MessageName = \"cmd.sensor.shutdown\"\n)\n\n// Message represents the message interface\ntype Message interface {\n\tGetName() MessageName\n}\n\n// StartMonitor contains the start monitor command fields\ntype StartMonitor struct {\n\tObfuscateMetadata            bool                          `json:\"obfuscate_metadata\"`\n\tRTASourcePT                  bool                          `json:\"rta_source_ptrace\"`\n\tAppName                      string                        `json:\"app_name\"`\n\tAppArgs                      []string                      `json:\"app_args,omitempty\"`\n\tAppEntrypoint                []string                      `json:\"app_entrypoint,omitempty\"`\n\tAppCmd                       []string                      `json:\"app_cmd,omitempty\"`\n\tAppUser                      string                        `json:\"app_user,omitempty\"`\n\tAppStdoutToFile              bool                          `json:\"app_stdout_to_file\"`\n\tAppStderrToFile              bool                          `json:\"app_stderr_to_file\"`\n\tRunTargetAsUser              bool                          `json:\"run_tas_user,omitempty\"`\n\tReportOnMainPidExit          bool                          `json:\"report_on_main_pid_exit\"`\n\tKeepPerms                    bool                          `json:\"keep_perms,omitempty\"`\n\tPerms                        map[string]*fsutil.AccessInfo `json:\"perms,omitempty\"`\n\tExcludes                     []string                      `json:\"excludes,omitempty\"`\n\tExcludeVarLockFiles          bool                          `json:\"exclude_varlock_files,omitempty\"`\n\tPreserves                    map[string]*fsutil.AccessInfo `json:\"preserves,omitempty\"`\n\tIncludes                     map[string]*fsutil.AccessInfo `json:\"includes,omitempty\"`\n\tIncludeBins                  []string                      `json:\"include_bins,omitempty\"`\n\tIncludeDirBinsList           map[string]*fsutil.AccessInfo `json:\"include_dir_bins_list,omitempty\"`\n\tIncludeExes                  []string                      `json:\"include_exes,omitempty\"`\n\tIncludeShell                 bool                          `json:\"include_shell,omitempty\"`\n\tIncludeWorkdir               string                        `json:\"include_workdir,omitempty\"`\n\tIncludeCertAll               bool                          `json:\"include_cert_all,omitempty\"`\n\tIncludeCertBundles           bool                          `json:\"include_cert_bundles,omitempty\"`\n\tIncludeCertDirs              bool                          `json:\"include_cert_dirs,omitempty\"`\n\tIncludeCertPKAll             bool                          `json:\"include_cert_pk_all,omitempty\"`\n\tIncludeCertPKDirs            bool                          `json:\"include_cert_pk_dirs,omitempty\"`\n\tIncludeNew                   bool                          `json:\"include_new,omitempty\"`\n\tIncludeSSHClient             bool                          `json:\"include_ssh_client,omitempty\"`\n\tIncludeOSLibsNet             bool                          `json:\"include_oslibs_net,omitempty\"`\n\tIncludeZoneInfo              bool                          `json:\"include_zoneinfo,omitempty\"`\n\tIncludeAppNuxtDir            bool                          `json:\"include_app_nuxt_dir,omitempty\"`\n\tIncludeAppNuxtBuildDir       bool                          `json:\"include_app_nuxt_build,omitempty\"`\n\tIncludeAppNuxtDistDir        bool                          `json:\"include_app_nuxt_dist,omitempty\"`\n\tIncludeAppNuxtStaticDir      bool                          `json:\"include_app_nuxt_static,omitempty\"`\n\tIncludeAppNuxtNodeModulesDir bool                          `json:\"include_app_nuxt_nm,omitempty\"`\n\tIncludeAppNextDir            bool                          `json:\"include_app_next_dir,omitempty\"`\n\tIncludeAppNextBuildDir       bool                          `json:\"include_app_next_build,omitempty\"`\n\tIncludeAppNextDistDir        bool                          `json:\"include_app_next_dist,omitempty\"`\n\tIncludeAppNextStaticDir      bool                          `json:\"include_app_next_static,omitempty\"`\n\tIncludeAppNextNodeModulesDir bool                          `json:\"include_app_next_nm,omitempty\"`\n\tIncludeNodePackages          []string                      `json:\"include_node_packages,omitempty\"`\n}\n\n// GetName returns the command message ID for the start monitor command\nfunc (m *StartMonitor) GetName() MessageName {\n\treturn StartMonitorName\n}\n\n// StopMonitor contains the stop monitor command fields\ntype StopMonitor struct {\n}\n\n// GetName returns the command message ID for the stop monitor command\nfunc (m *StopMonitor) GetName() MessageName {\n\treturn StopMonitorName\n}\n\n// ShutdownSensor contains the 'shutdown sensor' command fields\ntype ShutdownSensor struct{}\n\n// GetName returns the command message ID for the 'shutdown sensor' command\nfunc (m *ShutdownSensor) GetName() MessageName {\n\treturn ShutdownSensorName\n}\n\ntype messageWrapper struct {\n\tName MessageName     `json:\"name\"`\n\tData json.RawMessage `json:\"data,omitempty\"`\n}\n\n// Encode encodes the message instance to a JSON buffer object\nfunc Encode(m Message) ([]byte, error) {\n\tobj := messageWrapper{\n\t\tName: m.GetName(),\n\t}\n\n\tswitch v := m.(type) {\n\tcase *StartMonitor:\n\t\tvar b bytes.Buffer\n\t\tencoder := json.NewEncoder(&b)\n\t\tencoder.SetEscapeHTML(false)\n\t\tif err := encoder.Encode(v); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tobj.Data = b.Bytes()\n\tcase *StopMonitor:\n\tcase *ShutdownSensor:\n\tdefault:\n\t\treturn nil, ErrUnknownMessage\n\t}\n\n\treturn json.Marshal(&obj)\n}\n\n// Decode decodes JSON data into a message instance\nfunc Decode(data []byte) (Message, error) {\n\tvar wrapper messageWrapper\n\tif err := json.Unmarshal(data, &wrapper); err != nil {\n\t\treturn nil, err\n\t}\n\n\tswitch wrapper.Name {\n\tcase StartMonitorName:\n\t\tvar cmd StartMonitor\n\t\tif err := json.Unmarshal(wrapper.Data, &cmd); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn &cmd, nil\n\tcase StopMonitorName:\n\t\treturn &StopMonitor{}, nil\n\tcase ShutdownSensorName:\n\t\treturn &ShutdownSensor{}, nil\n\tdefault:\n\t\treturn nil, ErrUnknownMessage\n\t}\n}\n"
  },
  {
    "path": "pkg/ipc/event/event.go",
    "content": "package event\n\nimport (\n\t\"encoding/json\"\n\tgoerr \"errors\"\n\n\t\"github.com/slimtoolkit/slim/pkg/errors\"\n)\n\n// Event errors\nvar (\n\tErrUnknownEvent    = goerr.New(\"unknown event type\")\n\tErrUnexpectedEvent = goerr.New(\"unexpected event type\")\n)\n\n// Type is an event ID type\ntype Type string\n\n// Supported events\nconst (\n\tStartMonitorDone   Type = \"event.monitor.start.done\"\n\tStartMonitorFailed Type = \"event.monitor.start.failed\"\n\tStopMonitorDone    Type = \"event.monitor.stop.done\"\n\tShutdownSensorDone Type = \"event.sensor.shutdown.done\"\n\tError              Type = \"event.error\"\n)\n\ntype Message struct {\n\tName Type        `json:\"name\"`\n\tData interface{} `json:\"data,omitempty\"`\n}\n\n// StartMonitorFailedData contains additional context for the failure\ntype StartMonitorFailedData struct {\n\tComponent string            `json:\"component,omitempty\"`\n\tState     string            `json:\"state,omitempty\"`\n\tContext   map[string]string `json:\"context,omitempty\"`\n\tErrors    []string          `json:\"errors,omitempty\"`\n}\n\nconst (\n\tStateSensorTypeCreating    = \"sensor.type.creating\"\n\tStateCmdStartMonCmdWaiting = \"cmd.monitor.start.waiting\"\n\tStateEnvPreparing          = \"env.preparing\"\n\tStateMonCreating           = \"monitor.creating\"\n\tStateMonStarting           = \"monitor.starting\"\n)\n\nconst (\n\tComSensorConstructor = \"sensor.constructor\"\n\tComSensorCmdServer   = \"sensor.cmd.server\"\n\tComMonitorRunner     = \"monitor.runner\"\n)\n\nconst (\n\tCtxSensorType = \"sensor.type\"\n\tCtxCmdType    = \"cmd.type\"\n)\n\nfunc (m *Message) UnmarshalJSON(data []byte) error {\n\tvar tmp struct {\n\t\tName Type            `json:\"name\"`\n\t\tData json.RawMessage `json:\"data,omitempty\"`\n\t}\n\n\tif err := json.Unmarshal(data, &tmp); err != nil {\n\t\treturn err\n\t}\n\n\tm.Name = tmp.Name\n\tswitch tmp.Name {\n\tcase Error:\n\t\tvar data errors.SensorError\n\t\tif err := json.Unmarshal(tmp.Data, &data); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tm.Data = &data\n\tcase StartMonitorFailed:\n\t\tvar data StartMonitorFailedData\n\t\tif err := json.Unmarshal(tmp.Data, &data); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tm.Data = &data\n\tdefault:\n\t\tif len(tmp.Data) > 0 {\n\t\t\treturn json.Unmarshal(tmp.Data, &m.Data)\n\t\t}\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/lambdaproxy/lambdaproxy.go",
    "content": "package lambdaproxy\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n)\n\nvar isbnRegexp = regexp.MustCompile(`[0-9]{3}\\-[0-9]{10}`)\nvar errorLogger = log.New(os.Stderr, \"ERROR \", log.Llongfile)\n\n// HTTPProbeCmd provides the HTTP probe parameters\ntype HTTPProbeCmd struct {\n\tMethod   string   `json:\"method\"`\n\tResource string   `json:\"resource\"`\n\tPort     int      `json:\"port\"`\n\tProtocol string   `json:\"protocol\"`\n\tHeaders  []string `json:\"headers\"`\n\tBody     string   `json:\"body\"`\n\tBodyFile string   `json:\"body_file\"`\n\tUsername string   `json:\"username\"`\n\tPassword string   `json:\"password\"`\n\tCrawl    bool     `json:\"crawl\"`\n}\n\ntype apiGatewayProxyRequest struct {\n\tPath                  string            `json:\"path,omitempty\"` // The url path for the caller\n\tHTTPMethod            string            `json:\"httpMethod,omitempty\"`\n\tHeaders               map[string]string `json:\"headers,omitempty\"`\n\tQueryStringParameters map[string]string `json:\"queryStringParameters,omitempty\"`\n\tBody                  string            `json:\"body,omitempty\"`\n\tIsBase64Encoded       bool              `json:\"isBase64Encoded,omitempty\"`\n\tResource              string            `json:\"resource,omitempty\"` // The resource path defined in API Gateway\n}\n\ntype apiGatewayProxyResponse struct {\n\tStatusCode      int               `json:\"statusCode\"`\n\tHeaders         map[string]string `json:\"headers\"`\n\tBody            string            `json:\"body\"`\n\tIsBase64Encoded bool              `json:\"isBase64Encoded,omitempty\"`\n}\n\ntype HTTPRequest struct {\n\tMethod   string   `json:\"method\"`\n\tResource string   `json:\"resource\"`\n\tHeaders  []string `json:\"headers\"`\n\tBody     string   `json:\"body\"`\n\tProtocol string   `json:\"protocol\"`\n\tUsername string   `json:\"username\"`\n\tPassword string   `json:\"password\"`\n}\n\ntype HTTPResponse struct {\n\tStatusCode int      `json:\"statusCode\"`\n\tHeaders    []string `json:\"headers\"`\n\tBody       string   `json:\"body\"`\n}\n\n// encode and decode options - future placeholder for v1 and v2 options of lambda results\ntype EncodeOptions struct {\n\tversion string `json:\"version\"`\n}\n\ntype DecodeOptions struct {\n\tversion string `json:\"version\"`\n}\n\n// Add a helper for handling errors. This logs any error to os.Stderr\n// and returns a 500 Internal Server Error response that the AWS API\n// Gateway understands.\nfunc serverError(err error) (apiGatewayProxyResponse, error) {\n\terrorLogger.Println(err.Error())\n\n\treturn apiGatewayProxyResponse{\n\t\tStatusCode: http.StatusInternalServerError,\n\t\tBody:       http.StatusText(http.StatusInternalServerError),\n\t}, nil\n}\n\n// Similarly add a helper for send responses relating to client errors.\nfunc clientError(status int) (apiGatewayProxyResponse, error) {\n\treturn apiGatewayProxyResponse{\n\t\tStatusCode: status,\n\t\tBody:       http.StatusText(status),\n\t}, nil\n}\n\nfunc handleRequest(ctx context.Context, request *HTTPProbeCmd) (*HTTPRequest, error) {\n\n\treturn &HTTPRequest{Method: request.Method, Resource: request.Resource, Headers: request.Headers, Body: request.Body}, nil\n}\n\nfunc EncodeRequest(input *HTTPRequest, options *EncodeOptions) ([]byte, error) {\n\n\t// encode http request to api gateway proxy request\n\t// to do matching of parsing of both structs\n\tencodeapiGatewayStruct := apiGatewayProxyRequest{\n\t\tResource: input.Resource,\n\t\tBody:     input.Body,\n\t\tHeaders:  convertSliceToMap(input.Headers),\n\t}\n\n\tvar b bytes.Buffer\n\tencoder := json.NewEncoder(&b)\n\tencoder.SetEscapeHTML(false)\n\tif err := encoder.Encode(&encodeapiGatewayStruct); err != nil {\n\t\tfmt.Errorf(\"Error encoding apiGatewayProxyRequest: %s\", err)\n\t\treturn nil, err\n\t}\n\n\treturn b.Bytes(), nil\n}\n\nfunc DecodeResponse(input []byte, options *DecodeOptions) (HTTPResponse, error) {\n\n\tvar response apiGatewayProxyResponse\n\tif err := json.NewDecoder(bytes.NewBuffer(input)).Decode(&response); err != nil {\n\t\treturn HTTPResponse{}, err\n\t}\n\t//decode the response.Body if base64 encoded\n\tif response.IsBase64Encoded {\n\t\tresponseBodyBytes, err := base64.StdEncoding.DecodeString(string(response.Body))\n\t\tif err != nil {\n\t\t\tlog.Fatalf(\"Some error occured during base64 decode. Error %s\", err.Error())\n\t\t}\n\t\tresponse.Body = string(responseBodyBytes)\n\t}\n\n\treturn HTTPResponse{StatusCode: response.StatusCode, Body: response.Body, Headers: convertMapToSlice(response.Headers)}, nil\n}\n\nfunc convertSliceToMap(pairs []string) map[string]string {\n\tm := map[string]string{}\n\tfor _, pair := range pairs {\n\t\tparts := strings.SplitN(pair, \":\", 2)\n\t\tparts[0] = strings.TrimSpace(parts[0])\n\t\tparts[1] = strings.TrimSpace(parts[1])\n\t\tif val, found := m[parts[0]]; !found {\n\t\t\tm[parts[0]] = parts[1]\n\t\t} else {\n\t\t\tm[parts[0]] = fmt.Sprintf(\"%s,%s\", val, parts[1])\n\t\t}\n\t}\n\treturn m\n}\n\nfunc convertMapToSlice(input map[string]string) []string {\n\t// Convert map to slice of keys.\n\t//since map is unordered we need to sort the keys.\n\tkeys := make([]string, 0, len(input))\n\tfor key := range input {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\n\t// Convert map to slice of values.\n\tvalues := []string{}\n\tfor _, key := range keys {\n\t\tvalues = append(values, input[key])\n\t}\n\n\t// Convert map to slice of key-value pairs.\n\tpairs := []string{}\n\tfor key, value := range input {\n\t\tsplitvalue := strings.Split(value, \",\")\n\t\tif len(splitvalue) > 1 {\n\t\t\tfor _, v := range splitvalue {\n\t\t\t\tpairs = append(pairs, fmt.Sprintf(\"%s: %s\", key, strings.TrimSpace(v)))\n\t\t\t}\n\t\t} else {\n\t\t\tpairs = append(pairs, fmt.Sprintf(\"%s: %s\", key, value))\n\t\t}\n\t}\n\n\treturn pairs\n}\n"
  },
  {
    "path": "pkg/lambdaproxy/lambdaproxy_test.go",
    "content": "package lambdaproxy\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nvar (\n\tcmd     *HTTPProbeCmd\n\trequest *HTTPRequest\n)\n\n// /WIP Test\nfunc TestHandleRequest(t *testing.T) {\n\n\t// Create a new HTTPProbeCmd\n\n\terr := json.Unmarshal([]byte(`{\n\t\t\"resource\": \"/2015-03-31/functions/function/invocations\",\n\t\t\"method\": \"POST\",\n\t\t\"body\": \"{\\\"httpMethod\\\":\\\"POST\\\", \\\"path\\\":\\\"/stuff\\\", \\\"body\\\":\\\"{\\\"key\\\":\\\"val data\\\"}\\\", \\\"headers\\\": {\\\"Content-Type\\\": \\\"application/json\\\"}}\",\n\t\t\"protocol\": \"http\"\n\t}`), &cmd)\n\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Call HandleRequest\n\trequest, err = handleRequest(context.Background(), cmd)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Check that the request is correct\n\tassert.Equal(t, request.Method, \"POST\")\n\tassert.Equal(t, request.Body, \"{\\\"httpMethod\\\":\\\"POST\\\", \\\"path\\\":\\\"/stuff\\\", \\\"body\\\":\\\"{\\\"key\\\":\\\"val data\\\"}\\\", \\\"headers\\\": {\\\"Content-Type\\\": \\\"application/json\\\"}}\")\n\tassert.Equal(t, request.Resource, \"/2015-03-31/functions/function/invocations\")\n}\n\nfunc TestEncodeRequest(t *testing.T) {\n\n\tvar testrequest *HTTPRequest\n\n\terr := json.Unmarshal([]byte(`{\n\t\t\"headers\": [\n\t\t\t\"header1: value1\",\n\t\t\t\"header2: value1,value2\"\n\t\t],\n\t\t\"body\": \"Hello from Lambda\",\n\t\t\"resource\": \"/2015-03-31/functions/function/invocations\"\n\t}`), &testrequest)\n\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Call EncodeRequest\n\tencodedRequest, err := EncodeRequest(testrequest, nil)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\t// Check that the encoded request is correct\n\t//to-fix-this-test\n\tassert.Equal(t, string(encodedRequest),\n\t\t`{\"headers\":{\"header1\":\"value1\",\"header2\":\"value1,value2\"},\"body\":\"Hello from Lambda\",\"resource\":\"/2015-03-31/functions/function/invocations\"}\n`)\n}\n\n// function to decode response from lambda proxy\nfunc TestDecodeResponse(t *testing.T) {\n\n\t// Call DecodeResponse\n\tresponse, err := DecodeResponse([]byte(`{\"statusCode\":200,\"headers\":{\"x-powered-by\":\"Express\",\"content-type\":\"application/json; charset=utf-8\",\"content-length\":\"68\",\"etag\":\"W/\\\"44-ef4gTsYXxI2SCuYqkSK9GcCRgKo\\\"\"},\"isBase64Encoded\":false,\"body\":\"{\\\"status\\\":\\\"ok\\\",\\\"call\\\":\\\"POST /stuff\\\",\\\"data\\\":\\\"{\\\\\\\"key\\\\\\\":\\\\\\\"val data\\\\\\\"}\\\"}\"}`), &DecodeOptions{})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\t// Check that the response is correct\n\tassert.Equal(t, response.StatusCode, 200)\n\tassert.Equal(t, response.Body, \"{\\\"status\\\":\\\"ok\\\",\\\"call\\\":\\\"POST /stuff\\\",\\\"data\\\":\\\"{\\\\\\\"key\\\\\\\":\\\\\\\"val data\\\\\\\"}\\\"}\")\n\tassert.ElementsMatch(t, response.Headers, []string{\"x-powered-by: Express\", \"content-type: application/json; charset=utf-8\", \"content-length: 68\", \"etag: W/\\\"44-ef4gTsYXxI2SCuYqkSK9GcCRgKo\\\"\"})\n}\n"
  },
  {
    "path": "pkg/launcher/launcher.go",
    "content": "//go:build linux\n// +build linux\n\npackage launcher\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"os/user\"\n\t\"strings\"\n\t\"syscall\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n)\n\n// copied from libcontainer\nfunc fixStdioPermissions(uid int) error {\n\tvar null unix.Stat_t\n\tif err := unix.Stat(\"/dev/null\", &null); err != nil {\n\t\treturn err\n\t}\n\tfor _, fd := range []uintptr{\n\t\tos.Stdin.Fd(),\n\t\tos.Stderr.Fd(),\n\t\tos.Stdout.Fd(),\n\t} {\n\t\tvar s unix.Stat_t\n\t\tif err := unix.Fstat(int(fd), &s); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif s.Rdev == null.Rdev {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := unix.Fchown(int(fd), uid, int(s.Gid)); err != nil {\n\t\t\tif err == unix.EINVAL || err == unix.EPERM {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc fixStdioPermissionsAlt(uid int) error {\n\tvar null unix.Stat_t\n\tif err := unix.Stat(\"/dev/null\", &null); err != nil {\n\t\treturn err\n\t}\n\tfor _, fd := range []uintptr{\n\t\tos.Stdin.Fd(),\n\t\tos.Stderr.Fd(),\n\t\tos.Stdout.Fd(),\n\t} {\n\t\tvar s unix.Stat_t\n\t\tif err := unix.Fstat(int(fd), &s); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif s.Rdev == null.Rdev {\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := unix.Fchmod(int(fd), 0777); err != nil {\n\t\t\tif err == unix.EINVAL || err == unix.EPERM {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Start starts the target application in the container\nfunc Start(\n\tappName string,\n\tappArgs []string,\n\tappDir string,\n\tappUser string,\n\trunTargetAsUser bool,\n\tdoPtrace bool,\n\tappStdout io.Writer,\n\tappStderr io.Writer,\n) (*exec.Cmd, error) {\n\tlog.Debugf(\"launcher.Start(%v,%v,%v,%v)\", appName, appArgs, appDir, appUser)\n\tif !runTargetAsUser {\n\t\tappUser = \"\"\n\t}\n\n\tapp := exec.Command(appName, appArgs...)\n\n\tif doPtrace {\n\t\tapp.SysProcAttr = &syscall.SysProcAttr{\n\t\t\tPtrace:    true,\n\t\t\tPdeathsig: syscall.SIGKILL,\n\t\t}\n\t}\n\n\tapp.Dir = appDir\n\tapp.Stdin = os.Stdin\n\tapp.Stdout = appStdout\n\tapp.Stderr = appStderr\n\n\tif appUser != \"\" {\n\t\tif app.SysProcAttr == nil {\n\t\t\tapp.SysProcAttr = &syscall.SysProcAttr{}\n\t\t}\n\n\t\tappUserParts := strings.Split(appUser, \":\")\n\t\tif len(appUserParts) > 0 {\n\t\t\tuid, gid, home, err := system.ResolveUser(appUserParts[0])\n\t\t\tif err == nil {\n\t\t\t\tif len(appUserParts) > 1 {\n\t\t\t\t\txgid, err := system.ResolveGroup(appUserParts[1])\n\t\t\t\t\tif err == nil {\n\t\t\t\t\t\tgid = xgid\n\t\t\t\t\t} else {\n\t\t\t\t\t\tlog.Errorf(\"launcher.Start: error resolving group identity (%v/%v) - %v\", appUser, appUserParts[1], err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tapp.SysProcAttr.Credential = &syscall.Credential{\n\t\t\t\t\tUid: uid,\n\t\t\t\t\tGid: gid,\n\t\t\t\t}\n\n\t\t\t\tlog.Debugf(\"launcher.Start: start target as user (%s) - (uid=%d,gid=%d)\", appUser, uid, gid)\n\n\t\t\t\tif err = fixStdioPermissions(int(uid)); err != nil {\n\t\t\t\t\tlog.Errorf(\"launcher.Start: error fixing i/o perms for user (%v/%v) - %v\", appUser, uid, err)\n\t\t\t\t}\n\n\t\t\t\tapp.Env = appEnv(home)\n\t\t\t} else {\n\t\t\t\tlog.Errorf(\"launcher.Start: error resolving user identity (%v/%v) - %v\", appUser, appUserParts[0], err)\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// This is not exactly the same as leaving app.Env unset.\n\t\t// When cmd.Env == nil, Go stdlib takes the os.Environ() list\n\t\t// **AND** adds the PWD=`cmd.Dir` unless Dir is empty. This doesn't\n\t\t// match the Docker's standard behavior - even when an image has\n\t\t// the WORKDIR set, there is no PWD env var unless it's set\n\t\t// explicitly. Thus, before this change was made to the sensor\n\t\t// logic, instrumented containers would have non-identical ENV list.\n\t\tapp.Env = os.Environ()\n\t}\n\n\terr := app.Start()\n\tif err != nil {\n\t\tlog.Errorf(\"launcher.Start: error - %v\", err)\n\t\treturn nil, err\n\t}\n\n\tlog.Debugf(\"launcher.Start: started target app --> PID=%d\", app.Process.Pid)\n\treturn app, nil\n}\n\nfunc appEnv(appUserHome string) (appEnv []string) {\n\t// Another attempt to make the sensor's presence invisible to the target app.\n\t// Instrumented containers must be started as \"root\". But it makes Docker\n\t// (and other container runtimes) setting the HOME env var accordingly\n\t// (typically, using \"/root\" if /etc/passwd record exists or defaulting to \"/\"\n\t// otherwise to stay POSIX-conformant). However, when the target app needs\n\t// to be run as `appUser` != \"root\", the HOME env var may very well be different.\n\t// So we need to restore it by reading the corresponding /etc/passwd record.\n\t//\n\t// Note that the above logic is applicable only to the HOME env var. Other\n\t// typical env vars like USER or PATH don't need to be restored. Container\n\t// runtimes typically don't touch the USER var and almost always do set\n\t// the PATH var explicitly (during image building). So we just (implicitly)\n\t// propagate these values to app.Env from os.Environ().\n\n\tsensorUser, err := user.Current()\n\tif err != nil {\n\t\tlog.WithError(err).Error(\"launcher.Start: couldn't get current user\")\n\t\treturn os.Environ()\n\t}\n\n\tfor _, e := range os.Environ() {\n\t\tif !strings.HasPrefix(e, \"HOME=\") {\n\t\t\tappEnv = append(appEnv, e) // Just copy everything... except HOME.\n\t\t\tcontinue\n\t\t}\n\n\t\tif \"HOME=\"+sensorUser.HomeDir == e {\n\t\t\t// Since current HOME var is equal to the sensor's user HomeDir,\n\t\t\t// it's highly likely it wasn't set explicitly in the `docker run`\n\t\t\t// command (or alike) and instead was \"computed\" by the runtime upon\n\t\t\t// launching the container. Since the target app user != sensor's user,\n\t\t\t// we need to \"recompute\" it.\n\t\t\tappEnv = append(appEnv, \"HOME=\"+appUserHome)\n\t\t} else {\n\t\t\tappEnv = append(appEnv, e) // Likely the HOME var was set explicitly - don't mess with it.\n\t\t}\n\t}\n\n\treturn appEnv\n}\n"
  },
  {
    "path": "pkg/mondel/mondel.go",
    "content": "package mondel\n\n//Monitor Data Event Logger\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/acounter\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nconst eventBufSize = 10000\n\nvar (\n\tErrEventDropped = errors.New(\"event dropped\")\n)\n\ntype Publisher interface {\n\tPublish(event *report.MonitorDataEvent) error\n\tStop()\n}\n\ntype publisher struct {\n\tstopped   chan struct{}\n\tctx       context.Context\n\tenable    bool\n\toutput    *os.File\n\teventCh   chan *report.MonitorDataEvent\n\tseqNumber acounter.Type\n}\n\nfunc NewPublisher(ctx context.Context, enable bool, outputFile string) *publisher {\n\tlogger := log.WithField(\"op\", \"NewPublisher\")\n\tlogger.WithFields(log.Fields{\n\t\t\"enable\":      enable,\n\t\t\"output.file\": outputFile,\n\t}).Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\n\tref := &publisher{\n\t\tstopped: make(chan struct{}),\n\t\tctx:     ctx,\n\t\tenable:  enable,\n\t}\n\n\tif !ref.enable {\n\t\treturn ref\n\t}\n\n\t// fsutil.Touch() creates potentially missing folder(s).\n\tif err := fsutil.Touch(outputFile); err != nil {\n\t\tlog.WithError(err).Errorf(\"cannot create mondel file %q - fsutil.Touch() failed\", outputFile)\n\t\tref.enable = false\n\t\treturn ref\n\t}\n\n\t// Using O_SYNC because there is another process (art_collector) that is\n\t// reading from this file. If we don't use O_SYNC, then the file may not\n\t// be flushed to disk for too long.\n\tf, err := os.OpenFile(outputFile, os.O_APPEND|os.O_WRONLY|os.O_SYNC, 0644)\n\tif err != nil {\n\t\tlog.WithError(err).Errorf(\"os.OpenFile(%v)\", outputFile)\n\t\tref.enable = false\n\t\treturn ref\n\t}\n\n\tref.output = f\n\tref.eventCh = make(chan *report.MonitorDataEvent, eventBufSize)\n\n\tgo ref.process()\n\n\treturn ref\n}\n\nfunc (ref *publisher) Stop() {\n\tclose(ref.stopped)\n}\n\nfunc (ref *publisher) Publish(event *report.MonitorDataEvent) error {\n\tif !ref.enable || event == nil {\n\t\treturn nil\n\t}\n\n\tevent.Timestamp = time.Now().UTC().UnixNano()\n\tevent.SeqNumber = ref.seqNumber.Inc()\n\n\tlogger := log.WithField(\"op\", \"mondel.publisher.Publish\")\n\tselect {\n\tcase <-ref.stopped:\n\t\tlogger.Debugf(\"publisher stopped - dropped event (%#v)\", event)\n\t\treturn ErrEventDropped\n\t\treturn nil\n\tcase <-ref.ctx.Done():\n\t\treturn ref.ctx.Err()\n\n\tcase ref.eventCh <- event:\n\t\treturn nil\n\n\tdefault:\n\t\tlogger.Debugf(\"dropped event (%#v)\", event)\n\t\treturn ErrEventDropped\n\t}\n}\n\nfunc (ref *publisher) process() {\n\tlogger := log.WithField(\"op\", \"mondel.publisher.process\")\n\tlogger.Trace(\"call\")\n\tdefer logger.Trace(\"exit\")\n\tdefer func() {\n\t\terr := ref.output.Close()\n\t\tlogger.Tracef(\"closed ref.output (e=%v)\", err)\n\t}()\n\n\tvar buf bytes.Buffer\n\tticker := time.NewTicker(1 * time.Second)\n\tdefer ticker.Stop()\n\n\tvar once sync.Once\n\tfinish := func() {\n\t\tonce.Do(func() {\n\t\t\tclose(ref.eventCh)\n\n\t\t\tlogger.Debugf(\"draining eventCh - %d\", len(ref.eventCh))\n\t\t\tfor evt := range ref.eventCh {\n\t\t\t\tencoded, err := encodeEvent(evt)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Debugf(\"could not encode - %v\", encoded)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbuf.WriteString(encoded)\n\t\t\t}\n\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tlogger.Debugf(\"saving leftover data - %d\", buf.Len())\n\t\t\t\tif _, err := ref.output.Write(buf.Bytes()); err != nil {\n\t\t\t\t\tlogger.Errorf(\"Error writing batch: %v\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlogger.Debug(\"finish(): done\")\n\t\t})\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-ref.stopped:\n\t\t\tlogger.Debug(\"done - finishing....\")\n\t\t\tfinish()\n\t\t\treturn\n\t\tcase <-ref.ctx.Done():\n\t\t\tlogger.Debug(\"done - finishing....\")\n\t\t\tfinish()\n\t\t\treturn\n\n\t\tcase evt := <-ref.eventCh:\n\t\t\tencoded, err := encodeEvent(evt)\n\t\t\tif err != nil {\n\t\t\t\tlogger.Debugf(\"could not encode - %v\", encoded)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbuf.WriteString(encoded)\n\n\t\tcase <-ticker.C:\n\t\t\t// Flush the buffer every second\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tif _, err := ref.output.Write(buf.Bytes()); err != nil {\n\t\t\t\t\tlogger.Errorf(\"Error writing batch: %v\", err)\n\t\t\t\t}\n\t\t\t\tbuf.Reset()\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc encodeEvent(event *report.MonitorDataEvent) (string, error) {\n\tvar b bytes.Buffer\n\tenc := json.NewEncoder(&b)\n\tenc.SetEscapeHTML(false)\n\tif err := enc.Encode(event); err != nil {\n\t\treturn \"\", fmt.Errorf(\"error encoding data - %v\", err)\n\t}\n\n\treturn b.String(), nil\n}\n"
  },
  {
    "path": "pkg/monitor/ptrace/ptrace.go",
    "content": "//go:build !arm64\n// +build !arm64\n\npackage ptrace\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/armon/go-radix\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/slimtoolkit/slim/pkg/errors\"\n\t\"github.com/slimtoolkit/slim/pkg/launcher\"\n\t\"github.com/slimtoolkit/slim/pkg/mondel\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n)\n\ntype AppState string\n\nconst (\n\tAppStarted AppState = \"app.started\"\n\tAppFailed  AppState = \"app.failed\"\n\tAppDone    AppState = \"app.done\"\n)\n\nconst (\n\tcwdFD = unix.AT_FDCWD // AT_FDCWD = -0x64\n)\n\nfunc Run(\n\tctx context.Context,\n\tdel mondel.Publisher,\n\trunOpt AppRunOpt,\n\t// TODO(ivan): includeNew & origPaths logic should be applied at the artifact dumping stage.\n\tincludeNew bool,\n\torigPaths map[string]struct{},\n\tsignalCh <-chan os.Signal,\n\terrorCh chan<- error,\n) (*App, error) {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"com\": \"pt\",\n\t\t\"op\":  \"Run\",\n\t})\n\n\tlogger.Debug(\"call\")\n\tdefer logger.Debug(\"exit\")\n\n\tapp, err := newApp(ctx, del, runOpt, includeNew, origPaths, signalCh, errorCh)\n\tif err != nil {\n\t\tapp.StateCh <- AppFailed\n\t\treturn nil, err\n\t}\n\n\tif runOpt.RTASourcePT {\n\t\tlogger.Debug(\"tracing target app\")\n\t\tapp.Report.Enabled = true\n\t\tgo app.process()\n\t\tgo app.trace()\n\t} else {\n\t\tlogger.Debug(\"not tracing target app...\")\n\t\tgo func() {\n\t\t\tlogger.Debug(\"not tracing target app - start app\")\n\t\t\tif err := app.start(); err != nil {\n\t\t\t\tlogger.Debugf(\"not tracing target app - start app error - %v\", err)\n\t\t\t\tapp.errorCh <- errors.SE(\"ptrace.App.trace.app.start\", \"call.error\", err)\n\t\t\t\tapp.StateCh <- AppFailed\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tcancelSignalForwarding := app.startSignalForwarding()\n\t\t\tdefer cancelSignalForwarding()\n\n\t\t\tapp.StateCh <- AppStarted\n\n\t\t\tif err := app.cmd.Wait(); err != nil {\n\t\t\t\tlogger.WithError(err).Debug(\"not tracing target app - state<-AppFailed\")\n\t\t\t\tapp.StateCh <- AppFailed\n\t\t\t} else {\n\t\t\t\tlogger.Debug(\"not tracing target app - state<-AppDone\")\n\t\t\t\tapp.StateCh <- AppDone\n\t\t\t}\n\n\t\t\tapp.ReportCh <- &app.Report\n\t\t}()\n\t}\n\n\treturn app, nil\n}\n\nconst ptOptions = syscall.PTRACE_O_TRACECLONE |\n\tsyscall.PTRACE_O_TRACEFORK |\n\tsyscall.PTRACE_O_TRACEVFORK |\n\tsyscall.PTRACE_O_TRACEEXEC |\n\tsyscall.PTRACE_O_TRACESYSGOOD |\n\tsyscall.PTRACE_O_TRACEEXIT |\n\tunix.PTRACE_O_EXITKILL\n\ntype syscallState struct {\n\tpid          int\n\tcallNum      uint64\n\tretVal       uint64\n\texpectReturn bool\n\tgotCallNum   bool\n\tgotRetVal    bool\n\tstarted      bool\n\texiting      bool\n\tpathParam    string\n\tpathParamErr error\n}\n\ntype App struct {\n\tctx       context.Context\n\tCmd       string\n\tArgs      []string\n\tWorkDir   string\n\tUser      string\n\tRunAsUser bool\n\n\tdel mondel.Publisher\n\n\tappStdout io.Writer\n\tappStderr io.Writer\n\n\tRTASourcePT         bool\n\treportOnMainPidExit bool\n\n\tincludeNew bool\n\torigPaths  map[string]struct{}\n\n\tsignalCh <-chan os.Signal\n\terrorCh  chan<- error\n\n\tStateCh  chan AppState\n\tReportCh chan *report.PtMonitorReport\n\n\tcmd    *exec.Cmd\n\tpgid   int\n\tReport report.PtMonitorReport\n\n\tfsActivity      map[string]*report.FSActivityInfo\n\tsyscallActivity map[uint32]uint64\n\t//syscallResolver system.NumberResolverFunc\n\n\teventCh         chan syscallEvent\n\tcollectorDoneCh chan int\n\n\tlogger *log.Entry\n}\n\nfunc (a *App) MainPID() int {\n\treturn a.cmd.Process.Pid\n}\n\nfunc (a *App) PGID() int {\n\treturn a.pgid\n}\n\nconst eventBufSize = 2000\n\ntype syscallEvent struct {\n\treturned  bool\n\tpid       int\n\tcallNum   uint32\n\tretVal    uint64\n\tpathParam string\n}\n\nfunc newApp(\n\tctx context.Context,\n\tdel mondel.Publisher,\n\trunOpt AppRunOpt,\n\tincludeNew bool,\n\torigPaths map[string]struct{},\n\tsignalCh <-chan os.Signal,\n\terrorCh chan<- error,\n) (*App, error) {\n\tlogger := log.WithFields(log.Fields{\n\t\t\"com\": \"pt.App\",\n\t})\n\n\tsysInfo := system.GetSystemInfo()\n\tarchName := system.MachineToArchName(sysInfo.Machine)\n\n\ta := App{\n\t\tctx:       ctx,\n\t\tdel:       del,\n\t\tCmd:       runOpt.Cmd,\n\t\tArgs:      runOpt.Args,\n\t\tWorkDir:   runOpt.WorkDir,\n\t\tUser:      runOpt.User,\n\t\tRunAsUser: runOpt.RunAsUser,\n\n\t\tappStdout: runOpt.AppStdout,\n\t\tappStderr: runOpt.AppStderr,\n\n\t\tRTASourcePT:         runOpt.RTASourcePT,\n\t\treportOnMainPidExit: runOpt.ReportOnMainPidExit,\n\n\t\tincludeNew: includeNew,\n\t\torigPaths:  origPaths,\n\n\t\tsignalCh: signalCh,\n\t\terrorCh:  errorCh,\n\n\t\tStateCh:  make(chan AppState, 5),\n\t\tReportCh: make(chan *report.PtMonitorReport),\n\n\t\tReport: report.PtMonitorReport{\n\t\t\tArchName:     string(archName),\n\t\t\tSyscallStats: map[string]report.SyscallStatInfo{},\n\t\t\tFSActivity:   map[string]*report.FSActivityInfo{},\n\t\t},\n\n\t\tfsActivity:      map[string]*report.FSActivityInfo{},\n\t\tsyscallActivity: map[uint32]uint64{},\n\n\t\teventCh:         make(chan syscallEvent, eventBufSize),\n\t\tcollectorDoneCh: make(chan int, 2),\n\n\t\tlogger: logger,\n\t}\n\n\treturn &a, nil\n}\n\nfunc (app *App) trace() {\n\tlogger := app.logger.WithField(\"op\", \"trace\")\n\tlogger.Debug(\"call\")\n\tdefer logger.Debug(\"exit\")\n\n\truntime.LockOSThread()\n\n\tif err := app.start(); err != nil {\n\t\tapp.collectorDoneCh <- 1\n\t\tapp.errorCh <- errors.SE(\"ptrace.App.trace.app.start\", \"call.error\", err)\n\t\tapp.StateCh <- AppFailed\n\t\treturn\n\t}\n\n\tcancelSignalForwarding := app.startSignalForwarding()\n\tdefer cancelSignalForwarding()\n\n\tapp.StateCh <- AppStarted\n\tapp.collect()\n}\n\nfunc (app *App) processSyscallActivity(e *syscallEvent) {\n\tapp.syscallActivity[e.callNum]++\n}\n\nfunc (app *App) processFileActivity(e *syscallEvent) {\n\tif e.pathParam != \"\" {\n\t\tlogger := app.logger.WithField(\"op\", \"processFileActivity\")\n\t\tp, found := syscallProcessors[int(e.callNum)]\n\t\tif !found {\n\t\t\tlogger.Debugf(\"no syscall processor - %#v\", e)\n\t\t\t//shouldn't happen\n\t\t\treturn\n\t\t}\n\n\t\tif (p.SyscallType() == CheckFileType ||\n\t\t\tp.SyscallType() == OpenFileType) &&\n\t\t\tp.OKReturnStatus(e.retVal) {\n\t\t\t//todo: filter \"/proc/\", \"/sys/\", \"/dev/\" externally\n\t\t\tif e.pathParam != \".\" &&\n\t\t\t\te.pathParam != \"/proc\" &&\n\t\t\t\t!strings.HasPrefix(e.pathParam, \"/proc/\") &&\n\t\t\t\t!strings.HasPrefix(e.pathParam, \"/sys/\") &&\n\t\t\t\t!strings.HasPrefix(e.pathParam, \"/dev/\") {\n\t\t\t\tif fsa, ok := app.fsActivity[e.pathParam]; ok {\n\t\t\t\t\tfsa.OpsAll++\n\t\t\t\t\tfsa.Pids[e.pid] = struct{}{}\n\t\t\t\t\tfsa.Syscalls[int(e.callNum)] = struct{}{}\n\n\t\t\t\t\tif processor, found := syscallProcessors[int(e.callNum)]; found {\n\t\t\t\t\t\tswitch processor.SyscallType() {\n\t\t\t\t\t\tcase CheckFileType:\n\t\t\t\t\t\t\tfsa.OpsCheckFile++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfsa := &report.FSActivityInfo{\n\t\t\t\t\t\tOpsAll:       1,\n\t\t\t\t\t\tOpsCheckFile: 1,\n\t\t\t\t\t\tPids:         map[int]struct{}{},\n\t\t\t\t\t\tSyscalls:     map[int]struct{}{},\n\t\t\t\t\t}\n\n\t\t\t\t\tfsa.Pids[e.pid] = struct{}{}\n\t\t\t\t\tfsa.Syscalls[int(e.callNum)] = struct{}{}\n\n\t\t\t\t\tapp.fsActivity[e.pathParam] = fsa\n\t\t\t\t}\n\n\t\t\t\tif app.del != nil {\n\t\t\t\t\t//NOTE:\n\t\t\t\t\t//not capturing the 'dirfd' syscall params necessary\n\t\t\t\t\t//to reconstruct relative paths for some syscalls (todo: improve later)\n\t\t\t\t\tdelEvent := &report.MonitorDataEvent{\n\t\t\t\t\t\tSource:   report.MDESourcePT,\n\t\t\t\t\t\tType:     report.MDETypeArtifact,\n\t\t\t\t\t\tPid:      int32(e.pid),\n\t\t\t\t\t\tArtifact: e.pathParam, //note: might not be full path\n\t\t\t\t\t\tOpNum:    e.callNum,\n\t\t\t\t\t\tOp:       p.SyscallName(),\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch p.SyscallType() {\n\t\t\t\t\tcase CheckFileType:\n\t\t\t\t\t\tdelEvent.OpType = report.OpTypeCheck\n\t\t\t\t\tcase OpenFileType:\n\t\t\t\t\t\tdelEvent.OpType = report.OpTypeRead\n\t\t\t\t\t}\n\n\t\t\t\t\tif err := app.del.Publish(delEvent); err != nil {\n\t\t\t\t\t\tlogger.Errorf(\n\t\t\t\t\t\t\t\"mondel publish event failed - source=%v type=%v: %v\",\n\t\t\t\t\t\t\tdelEvent.Source, delEvent.Type, err,\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\n\t\tif p.SyscallType() == ExecType &&\n\t\t\t(!e.returned || //need to catch exec calls that haven't completed yet\n\t\t\t\t(e.returned && p.OKReturnStatus(e.retVal))) {\n\t\t\tif fsa, ok := app.fsActivity[e.pathParam]; ok {\n\t\t\t\tfsa.OpsAll++\n\t\t\t\tfsa.Pids[e.pid] = struct{}{}\n\t\t\t\tfsa.Syscalls[int(e.callNum)] = struct{}{}\n\t\t\t} else {\n\t\t\t\tfsa := &report.FSActivityInfo{\n\t\t\t\t\tOpsAll:       1,\n\t\t\t\t\tOpsCheckFile: 0,\n\t\t\t\t\tPids:         map[int]struct{}{},\n\t\t\t\t\tSyscalls:     map[int]struct{}{},\n\t\t\t\t}\n\n\t\t\t\tfsa.Pids[e.pid] = struct{}{}\n\t\t\t\tfsa.Syscalls[int(e.callNum)] = struct{}{}\n\n\t\t\t\tapp.fsActivity[e.pathParam] = fsa\n\t\t\t}\n\n\t\t\tif app.del != nil {\n\t\t\t\t//NOTE:\n\t\t\t\t//not capturing the 'dirfd' syscall params necessary\n\t\t\t\t//to reconstruct relative paths for some syscalls (todo: improve later)\n\t\t\t\tdelEvent := &report.MonitorDataEvent{\n\t\t\t\t\tSource:   report.MDESourcePT,\n\t\t\t\t\tType:     report.MDETypeArtifact,\n\t\t\t\t\tPid:      int32(e.pid),\n\t\t\t\t\tArtifact: e.pathParam, //note: might not be full path\n\t\t\t\t\tOpNum:    e.callNum,\n\t\t\t\t\tOp:       p.SyscallName(),\n\t\t\t\t\tOpType:   report.OpTypeExec,\n\t\t\t\t}\n\n\t\t\t\tif err := app.del.Publish(delEvent); err != nil {\n\t\t\t\t\tlogger.Errorf(\n\t\t\t\t\t\t\"mondel publish event failed - source=%v type=%v op_type=%v: %v\",\n\t\t\t\t\t\tdelEvent.Source, delEvent.Type, delEvent.OpType, err,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (app *App) process() {\n\tlogger := app.logger.WithField(\"op\", \"process\")\n\tlogger.Debug(\"call\")\n\tdefer logger.Debug(\"exit\")\n\n\tstate := AppDone\n\ndone:\n\tfor {\n\t\tselect {\n\t\t// Highest priority - monitor's context has been cancelled from the outside.\n\t\tcase <-app.ctx.Done():\n\t\t\tlogger.Debug(\"done - stopping...\")\n\t\t\t//NOTE: need a better way to stop the target app...\n\t\t\t//\"os: process already finished\" error is ok\n\t\t\tif err := app.cmd.Process.Signal(syscall.SIGTERM); err != nil {\n\t\t\t\tlogger.Debug(\"error stopping target app => \", err)\n\t\t\t\tif err := app.cmd.Process.Kill(); err != nil {\n\t\t\t\t\tlogger.Debug(\"error killing target app => \", err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak done\n\n\t\tcase e := <-app.eventCh:\n\t\t\tapp.Report.SyscallCount++\n\t\t\tlogger.Tracef(\"event ==> {pid=%v cn=%d}\", e.pid, e.callNum)\n\n\t\t\tapp.processSyscallActivity(&e)\n\t\t\tapp.processFileActivity(&e)\n\n\t\tcase rc := <-app.collectorDoneCh:\n\t\t\tlogger.Debugf(\"collector finished => %v\", rc)\n\t\t\tif rc > 0 {\n\t\t\t\tstate = AppFailed\n\t\t\t}\n\t\t\tbreak done\n\t\t}\n\t}\n\n\t// Drainign the remaining events after the collection is done.\n\t// Note that it likely introduces a race when ReportOnMainPidExit is true.\n\t// Events might be generated by the child processes (indefinitely) long after\n\t// the main process' exit, and this could make the sensor hang. However, the\n\t// alternative race (when events aren't drained) is even worse - it leads to\n\t// loosing files in the report.\ndrain:\n\tfor {\n\t\tselect {\n\t\tcase e := <-app.eventCh:\n\t\t\tapp.Report.SyscallCount++\n\t\t\tlogger.Tracef(\"event (drained) ==> {pid=%v cn=%d}\", e.pid, e.callNum)\n\n\t\t\tapp.processSyscallActivity(&e)\n\t\t\tapp.processFileActivity(&e)\n\n\t\tdefault:\n\t\t\tlogger.Trace(\"event draining is finished\")\n\t\t\tbreak drain\n\t\t}\n\t}\n\n\tlogger.Tracef(\"executed syscall count = %d\", app.Report.SyscallCount)\n\tlogger.Tracef(\"number of syscalls: %v\", len(app.syscallActivity))\n\n\tfor scNum, scCount := range app.syscallActivity {\n\t\t//syscallName := app.syscallResolver(scNum)\n\t\tsyscallName := system.LookupCallName(scNum)\n\t\tlog.Debugf(\"[%v] %v = %v\", scNum, syscallName, scCount)\n\t\tscKey := strconv.FormatInt(int64(scNum), 10)\n\t\tapp.Report.SyscallStats[scKey] = report.SyscallStatInfo{\n\t\t\tNumber: scNum,\n\t\t\tName:   syscallName,\n\t\t\tCount:  scCount,\n\t\t}\n\t}\n\n\tapp.Report.SyscallNum = uint32(len(app.Report.SyscallStats))\n\tapp.Report.FSActivity = app.FileActivity()\n\n\tapp.StateCh <- state\n\tapp.ReportCh <- &app.Report\n}\n\nfunc (app *App) FileActivity() map[string]*report.FSActivityInfo {\n\tlogger := app.logger.WithField(\"op\", \"FileActivity\")\n\tlogger.Debugf(\"call - [all records - %d]\", len(app.fsActivity))\n\n\t//get the file activity info (ignore intermediate directories)\n\tt := radix.New()\n\tfor k, v := range app.fsActivity {\n\t\tt.Insert(k, v)\n\t}\n\n\twalk := func(wkey string, wv interface{}) bool {\n\t\twdata, ok := wv.(*report.FSActivityInfo)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\n\t\twalkAfter := func(akey string, av interface{}) bool {\n\t\t\t//adata, ok := av.(*report.FSActivityInfo)\n\t\t\t//if !ok {\n\t\t\t//    return false\n\t\t\t//}\n\n\t\t\tif wkey == akey {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\twdata.IsSubdir = true\n\t\t\treturn true\n\t\t}\n\n\t\tt.WalkPrefix(wkey, walkAfter)\n\t\treturn false\n\t}\n\n\tt.Walk(walk)\n\n\tresult := map[string]*report.FSActivityInfo{}\n\tfor k, v := range app.fsActivity {\n\t\tif v.IsSubdir {\n\t\t\tcontinue\n\t\t}\n\n\t\tresult[k] = v\n\t}\n\n\tlogger.Debugf(\"exit - [file records - %d]\", len(result))\n\treturn result\n}\n\nfunc (app *App) start() error {\n\tlogger := app.logger.WithField(\"op\", \"start\")\n\tlogger.Debug(\"call\")\n\tdefer logger.Debug(\"exit\")\n\n\tvar err error\n\tapp.cmd, err = launcher.Start(\n\t\tapp.Cmd,\n\t\tapp.Args,\n\t\tapp.WorkDir,\n\t\tapp.User,\n\t\tapp.RunAsUser,\n\t\tapp.RTASourcePT,\n\t\tapp.appStdout,\n\t\tapp.appStderr,\n\t)\n\tif err != nil {\n\t\tlogger.WithError(err).Errorf(\n\t\t\t\"cmd='%v' args='%+v' dir='%v'\",\n\t\t\tapp.Cmd, app.Args, app.WorkDir,\n\t\t)\n\t\treturn err\n\t}\n\n\tif !app.RTASourcePT {\n\t\tapp.pgid, err = syscall.Getpgid(app.cmd.Process.Pid)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t}\n\n\terr = app.cmd.Wait()\n\tlogger.Debugf(\"app.cmd.Wait err - %v\", err)\n\tlogger.Debugf(\"Target process state info - Exited=%v ExitCode=%v SysWaitStatus=%v\",\n\t\tapp.cmd.ProcessState.Exited(),\n\t\tapp.cmd.ProcessState.ExitCode(),\n\t\tapp.cmd.ProcessState.Sys())\n\n\twaitStatus, ok := app.cmd.ProcessState.Sys().(syscall.WaitStatus)\n\tif ok {\n\t\tlogger.Debugf(\"Target process wait status - %v (Exited=%v Signaled=%v Signal='%v' Stopped=%v StopSignal='%v' TrapCause=%v)\",\n\t\t\twaitStatus,\n\t\t\twaitStatus.Exited(),\n\t\t\twaitStatus.Signaled(),\n\t\t\twaitStatus.Signal(),\n\t\t\twaitStatus.Stopped(),\n\t\t\twaitStatus.StopSignal(),\n\t\t\twaitStatus.TrapCause())\n\n\t\tif waitStatus.Exited() {\n\t\t\tlogger.Debug(\"unexpected app exit\")\n\t\t\treturn fmt.Errorf(\"unexpected app exit\")\n\t\t}\n\n\t\tif waitStatus.Signaled() {\n\t\t\tlogger.Debug(\"unexpected app signalled\")\n\t\t\treturn fmt.Errorf(\"unexpected app signalled\")\n\t\t}\n\n\t\t//we should be in the Stopped state\n\t\tif waitStatus.Stopped() {\n\t\t\tsigEnum := SignalEnum(int(waitStatus.StopSignal()))\n\t\t\tlogger.Debugf(\"Process Stop Signal - code=%d enum=%s str=%s\",\n\t\t\t\twaitStatus.StopSignal(), sigEnum, waitStatus.StopSignal())\n\t\t} else {\n\t\t\t//TODO:\n\t\t\t//check for Exited or Signaled process state (shouldn't happen)\n\t\t\t//do it for context indicating that we are in a failed state\n\t\t}\n\t} else {\n\t\tlogger.WithError(err).Error(\"process status error\")\n\t\treturn fmt.Errorf(\"process status error\")\n\t}\n\n\tapp.pgid, err = syscall.Getpgid(app.cmd.Process.Pid)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlogger.Debugf(\"started target app --> PID=%d PGID=%d\",\n\t\tapp.cmd.Process.Pid, app.pgid)\n\n\terr = syscall.PtraceSetOptions(app.cmd.Process.Pid, ptOptions)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nconst traceSysGoodStatusBit = 0x80\n\nfunc StopSignalInfo(sig syscall.Signal) string {\n\tsigNum := int(sig)\n\tif sigNum == -1 {\n\t\treturn fmt.Sprintf(\"(code=%d)\", sigNum)\n\t}\n\n\tsigEnum := SignalEnum(sigNum)\n\tsigStr := sig.String()\n\tif sig&traceSysGoodStatusBit == traceSysGoodStatusBit {\n\t\tmsig := sig &^ traceSysGoodStatusBit\n\t\tsigEnum = fmt.Sprintf(\"%s|0x%04x\", SignalEnum(int(msig)), traceSysGoodStatusBit)\n\t\tsigStr = fmt.Sprintf(\"%s|0x%04x\", msig, traceSysGoodStatusBit)\n\t}\n\n\tinfo := fmt.Sprintf(\"(code=%d/0x%04x enum='%s' str='%s')\",\n\t\tsigNum, sigNum, sigEnum, sigStr)\n\n\treturn info\n}\n\nfunc SigTrapCauseInfo(cause int) string {\n\tif cause == -1 {\n\t\treturn fmt.Sprintf(\"(code=%d)\", cause)\n\t}\n\n\tcauseEnum := PtraceEvenEnum(cause)\n\tinfo := fmt.Sprintf(\"(code=%d enum=%s)\", cause, causeEnum)\n\n\treturn info\n}\n\nfunc PtraceEvenEnum(data int) string {\n\tif enum, ok := ptEventMap[data]; ok {\n\t\treturn enum\n\t} else {\n\t\treturn fmt.Sprintf(\"(%d)\", data)\n\t}\n}\n\nvar ptEventMap = map[int]string{\n\tsyscall.PTRACE_EVENT_CLONE:      \"PTRACE_EVENT_CLONE\",\n\tsyscall.PTRACE_EVENT_EXEC:       \"PTRACE_EVENT_EXEC\",\n\tsyscall.PTRACE_EVENT_EXIT:       \"PTRACE_EVENT_EXIT\",\n\tsyscall.PTRACE_EVENT_FORK:       \"PTRACE_EVENT_FORK\",\n\tunix.PTRACE_EVENT_SECCOMP:       \"PTRACE_EVENT_SECCOMP\",\n\tunix.PTRACE_EVENT_STOP:          \"PTRACE_EVENT_STOP\",\n\tsyscall.PTRACE_EVENT_VFORK:      \"PTRACE_EVENT_VFORK\",\n\tsyscall.PTRACE_EVENT_VFORK_DONE: \"PTRACE_EVENT_VFORK_DONE\",\n}\n\nfunc (app *App) collect() {\n\tlogger := app.logger.WithField(\"op\", \"collect\")\n\tlogger.Debug(\"call\")\n\tdefer logger.Debug(\"exit\")\n\n\tcallPid := app.MainPID()\n\tprevPid := callPid\n\n\tlogger.Debugf(\"trace syscall mainPID=%v\", callPid)\n\n\tpidSyscallState := map[int]*syscallState{}\n\tpidSyscallState[callPid] = &syscallState{pid: callPid}\n\n\tmainExiting := false\n\twaitFor := -1\n\tdoSyscall := true\n\tcallSig := 0\n\tfor {\n\t\tselect {\n\t\tcase <-app.ctx.Done():\n\t\t\tlogger.Debug(\"done - stop (exiting)\")\n\t\t\treturn\n\t\tdefault:\n\t\t}\n\n\t\tif doSyscall {\n\t\t\tlogger.Tracef(\"trace syscall (pid=%v sig=%v)\", callPid, callSig)\n\t\t\terr := syscall.PtraceSyscall(callPid, callSig)\n\t\t\tif err != nil {\n\t\t\t\tif strings.Contains(strings.ToLower(err.Error()), \"no such process\") {\n\t\t\t\t\t// This is kinda-sorta normal situtaion when ptrace-ing:\n\t\t\t\t\t//   - The tracee process might have been KILL-led\n\t\t\t\t\t//   - A group-stop event in a multi-threaded program can have\n\t\t\t\t\t//     a similar effect (see also https://linux.die.net/man/2/ptrace).\n\t\t\t\t\t//\n\t\t\t\t\t// We'd been observing this behavior a lot with short&fast Go programs,\n\t\t\t\t\t// and regular `strace -f ./app` would produce similar results.\n\t\t\t\t\t// Sending this error event back to the master process would make\n\t\t\t\t\t// the `slim build` command fail with the exit code -124.\n\t\t\t\t\tlogger.Debugf(\"trace syscall - (likely) tracee terminated pid=%v sig=%v error - %v (errno=%d)\", callPid, callSig, err, err.(syscall.Errno))\n\t\t\t\t} else {\n\t\t\t\t\tlogger.Errorf(\"trace syscall pid=%v sig=%v error - %v (errno=%d)\", callPid, callSig, err, err.(syscall.Errno))\n\t\t\t\t\tapp.errorCh <- errors.SE(\"ptrace.App.collect.ptsyscall\", \"call.error\", err)\n\t\t\t\t}\n\t\t\t\t//keep waiting for other syscalls\n\t\t\t}\n\t\t}\n\n\t\tlogger.Trace(\"waiting for syscall...\")\n\t\tvar ws syscall.WaitStatus\n\t\twpid, err := syscall.Wait4(waitFor, &ws, syscall.WALL, nil)\n\t\tif err != nil {\n\t\t\tif err.(syscall.Errno) == syscall.ECHILD {\n\t\t\t\tlogger.Debug(\"wait4 ECHILD error (ignoring)\")\n\t\t\t\tdoSyscall = false\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlogger.Debugf(\"wait4 error - %v (errno=%d)\", err, err.(syscall.Errno))\n\t\t\tapp.errorCh <- errors.SE(\"ptrace.App.collect.wait4\", \"call.error\", err)\n\t\t\tapp.StateCh <- AppFailed\n\t\t\tapp.collectorDoneCh <- 2\n\t\t\treturn\n\t\t}\n\n\t\tlogger.Tracef(\"wait4 -> wpid=%v wstatus=%v (Exited=%v Signaled=%v Signal='%v' Stopped=%v StopSignalInfo=%s TrapCause=%s)\",\n\t\t\twpid,\n\t\t\tws,\n\t\t\tws.Exited(),\n\t\t\tws.Signaled(),\n\t\t\tws.Signal(),\n\t\t\tws.Stopped(),\n\t\t\tStopSignalInfo(ws.StopSignal()),\n\t\t\tSigTrapCauseInfo(ws.TrapCause()))\n\n\t\tif wpid == -1 {\n\t\t\tlogger.Error(\"wpid = -1\")\n\t\t\tapp.StateCh <- AppFailed\n\t\t\tapp.errorCh <- errors.SE(\"ptrace.App.collect.wpid\", \"call.error\", fmt.Errorf(\"wpid is -1\"))\n\t\t\t// TODO(ivan): Investigate if this code branch leads to sensor becoming stuck.\n\t\t\t//             Should we collectorDoneCh <- 42?\n\t\t\treturn\n\t\t}\n\n\t\tcallSig = 0 // reset\n\t\tterminated := false\n\t\teventStop := false\n\t\thandleCall := false\n\t\teventCode := 0\n\t\tstatusCode := 0\n\t\tswitch {\n\t\tcase ws.Exited():\n\t\t\tterminated = true\n\t\t\tstatusCode = ws.ExitStatus()\n\t\tcase ws.Signaled():\n\t\t\tterminated = true\n\t\t\tstatusCode = int(ws.Signal())\n\t\tcase ws.Stopped():\n\t\t\tstatusCode = int(ws.StopSignal())\n\t\t\tif statusCode == int(syscall.SIGTRAP|traceSysGoodStatusBit) {\n\t\t\t\thandleCall = true\n\t\t\t} else if statusCode == int(syscall.SIGTRAP) {\n\t\t\t\teventStop = true\n\t\t\t\teventCode = ws.TrapCause()\n\t\t\t} else {\n\t\t\t\tcallSig = statusCode\n\t\t\t}\n\t\t}\n\n\t\tif terminated {\n\t\t\tif _, ok := pidSyscallState[wpid]; !ok {\n\t\t\t\tlogger.Debugf(\"[%d/%d]: unknown process is terminated (pid=%v)\",\n\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid)\n\t\t\t} else {\n\t\t\t\tif !pidSyscallState[wpid].exiting {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: unexpected process termination (pid=%v)\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdelete(pidSyscallState, wpid)\n\t\t\tif app.MainPID() == wpid {\n\t\t\t\tlogger.Debugf(\"[%d/%d]: wpid(%v) is main PID and terminated...\",\n\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid)\n\t\t\t\tif !mainExiting {\n\t\t\t\t\tlogger.Debug(\"unexpected main PID termination...\")\n\t\t\t\t}\n\n\t\t\t\tif len(pidSyscallState) > 0 && app.reportOnMainPidExit {\n\t\t\t\t\t// Announce the end of event collection but don't stop the tracing loop.\n\t\t\t\t\t//\n\t\t\t\t\t// This makes the monitor report the tracing results unblocking the sensor\n\t\t\t\t\t// and allowing it to start dumping the artifacts (while giving an extra\n\t\t\t\t\t// chance for the child processes to terminate gracefully).\n\t\t\t\t\tapp.collectorDoneCh <- 0\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(pidSyscallState) == 0 {\n\t\t\t\tlogger.Debugf(\"[%d/%d]: all processes terminated...\", app.cmd.Process.Pid, app.pgid)\n\t\t\t\tapp.collectorDoneCh <- 0 // TODO(ivan): Should it be collectorDoneCh <- statusCode instead?\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tdoSyscall = false\n\t\t\tcontinue\n\t\t}\n\n\t\tif handleCall {\n\t\t\tvar cstate *syscallState\n\t\t\tif _, ok := pidSyscallState[wpid]; ok {\n\t\t\t\tcstate = pidSyscallState[wpid]\n\t\t\t} else {\n\t\t\t\tlogger.Debugf(\"[%d/%d]: collector loop - new pid - mainPid=%v pid=%v (prevPid=%v) - add state\",\n\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, app.MainPID(), wpid, prevPid)\n\t\t\t\t//TODO: create new process records from clones/forks\n\t\t\t\tcstate = &syscallState{pid: wpid}\n\t\t\t\tpidSyscallState[wpid] = cstate\n\t\t\t}\n\n\t\t\tif !cstate.expectReturn {\n\t\t\t\tgenEvent, err := onSyscall(wpid, cstate)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: wpid=%v onSyscall error - %v\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif genEvent {\n\t\t\t\t\t//not waiting for the return call for the 'exec' syscalls (mostly)\n\t\t\t\t\tevt := syscallEvent{\n\t\t\t\t\t\treturned:  false,\n\t\t\t\t\t\tpid:       wpid,\n\t\t\t\t\t\tcallNum:   uint32(cstate.callNum),\n\t\t\t\t\t\tpathParam: cstate.pathParam,\n\t\t\t\t\t}\n\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: event.onSyscall - wpid=%v (evt=%#v)\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid, evt)\n\t\t\t\t\tselect {\n\t\t\t\t\tcase app.eventCh <- evt:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlogger.Warnf(\"[%d/%d]: event.onSyscall - wpid=%v app.eventCh send error (evt=%#v)\",\n\t\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid, evt)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err := onSyscallReturn(wpid, cstate); err != nil {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: wpid=%v onSyscallReturn error - %v\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid, err)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif cstate.gotCallNum && cstate.gotRetVal {\n\t\t\t\tevt := syscallEvent{\n\t\t\t\t\treturned:  true,\n\t\t\t\t\tpid:       wpid,\n\t\t\t\t\tcallNum:   uint32(cstate.callNum),\n\t\t\t\t\tretVal:    cstate.retVal,\n\t\t\t\t\tpathParam: cstate.pathParam,\n\t\t\t\t}\n\n\t\t\t\tcstate.gotCallNum = false\n\t\t\t\tcstate.gotRetVal = false\n\t\t\t\tcstate.pathParam = \"\"\n\t\t\t\tcstate.pathParamErr = nil\n\n\t\t\t\t_, ok := app.origPaths[evt.pathParam]\n\t\t\t\tif app.includeNew {\n\t\t\t\t\tok = true\n\t\t\t\t}\n\n\t\t\t\tif ok {\n\t\t\t\t\tselect {\n\t\t\t\t\tcase app.eventCh <- evt:\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tlogger.Warnf(\"[%d/%d]: wpid=%v app.eventCh send error (evt=%#v)\",\n\t\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid, evt)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif eventStop {\n\t\t\tlogger.Debugf(\"[%d/%d]: eventStop eventCode=%d(0x%04x)\",\n\t\t\t\tapp.cmd.Process.Pid, app.pgid, eventCode, eventCode)\n\n\t\t\tswitch eventCode {\n\t\t\tcase syscall.PTRACE_EVENT_CLONE,\n\t\t\t\tsyscall.PTRACE_EVENT_FORK,\n\t\t\t\tsyscall.PTRACE_EVENT_VFORK,\n\t\t\t\tsyscall.PTRACE_EVENT_VFORK_DONE:\n\t\t\t\tnewPid, err := syscall.PtraceGetEventMsg(wpid)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: PTRACE_EVENT_CLONE/[V]FORK[_DONE] - error getting cloned pid - %v\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, err)\n\t\t\t\t} else {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: PTRACE_EVENT_CLONE/[V]FORK[_DONE] - cloned pid - %v\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, newPid)\n\t\t\t\t\tif _, ok := pidSyscallState[int(newPid)]; ok {\n\t\t\t\t\t\tlogger.Debugf(\"[%d/%d]: PTRACE_EVENT_CLONE/[V]FORK[_DONE] - pid already exists - %v\",\n\t\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, newPid)\n\t\t\t\t\t\tpidSyscallState[int(newPid)].started = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpidSyscallState[int(newPid)] = &syscallState{pid: int(newPid), started: true}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase syscall.PTRACE_EVENT_EXEC:\n\t\t\t\toldPid, err := syscall.PtraceGetEventMsg(wpid)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: PTRACE_EVENT_EXEC - error getting old pid - %v\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, err)\n\t\t\t\t} else {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: PTRACE_EVENT_EXEC - old pid - %v\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, oldPid)\n\t\t\t\t}\n\n\t\t\tcase syscall.PTRACE_EVENT_EXIT:\n\t\t\t\tlogger.Debugf(\"[%d/%d]: PTRACE_EVENT_EXIT - process exiting pid=%v\",\n\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid)\n\t\t\t\tif app.MainPID() == wpid {\n\t\t\t\t\tmainExiting = true\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: main process is exiting (%v)\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid)\n\t\t\t\t}\n\n\t\t\t\tif _, ok := pidSyscallState[wpid]; ok {\n\t\t\t\t\tpidSyscallState[wpid].exiting = true\n\t\t\t\t} else {\n\t\t\t\t\tlogger.Debugf(\"[%d/%d]: unknown process is exiting (pid=%v)\",\n\t\t\t\t\t\tapp.cmd.Process.Pid, app.pgid, wpid)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdoSyscall = true\n\t\tcallPid = wpid\n\t} // eof: main for loop\n}\n\nfunc (app *App) startSignalForwarding() context.CancelFunc {\n\tlogger := app.logger.WithField(\"op\", \"startSignalForwarding\")\n\tlogger.Debug(\"call\")\n\tdefer logger.Debug(\"exit\")\n\n\tctx, cancel := context.WithCancel(app.ctx)\n\n\tgo func() {\n\t\tlogger := app.logger.WithField(\"op\", \"startSignalForwarding.worker\")\n\t\tlogger.Debug(\"call\")\n\t\tdefer logger.Debug(\"exit\")\n\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\n\t\t\tcase s := <-app.signalCh:\n\t\t\t\tif s == syscall.SIGCHLD {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tlogger.WithField(\"signal\", s).Debug(\"forwarding signal\")\n\n\t\t\t\tss, ok := s.(syscall.Signal)\n\t\t\t\tif !ok {\n\t\t\t\t\tlogger.WithField(\"signal\", s).Debug(\"unsupported signal type\")\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// app.cmd.Process.Signal(s) can't be used because due to ptrace-ing\n\t\t\t\t// the target processes' status becomes set before the actual\n\t\t\t\t// process termination making Signal() think the process exited and\n\t\t\t\t// not even trying to deliver the signal.\n\t\t\t\tif err := syscall.Kill(app.cmd.Process.Pid, ss); err != nil {\n\t\t\t\t\tlogger.\n\t\t\t\t\t\tWithError(err).\n\t\t\t\t\t\tWithField(\"signal\", ss).\n\t\t\t\t\t\tDebug(\"failed to signal target app\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn cancel\n}\n\nfunc onSyscall(pid int, cstate *syscallState) (bool, error) {\n\tvar regs syscall.PtraceRegs\n\tif err := syscall.PtraceGetRegs(pid, &regs); err != nil {\n\t\treturn false, err\n\t}\n\n\tcstate.callNum = system.CallNumber(regs)\n\tcstate.expectReturn = true\n\tcstate.gotCallNum = true\n\n\tif processor, found := syscallProcessors[int(cstate.callNum)]; found && processor != nil {\n\t\tprocessor.OnCall(pid, regs, cstate)\n\t\tdoGenEvent := processor.EventOnCall()\n\t\treturn doGenEvent, nil\n\t}\n\n\treturn false, nil\n}\n\nfunc onSyscallReturn(pid int, cstate *syscallState) error {\n\tvar regs syscall.PtraceRegs\n\tif err := syscall.PtraceGetRegs(pid, &regs); err != nil {\n\t\treturn err\n\t}\n\n\tcstate.retVal = system.CallReturnValue(regs)\n\tcstate.expectReturn = false\n\tcstate.gotRetVal = true\n\n\tif processor, found := syscallProcessors[int(cstate.callNum)]; found {\n\t\tprocessor.OnReturn(pid, regs, cstate)\n\t}\n\n\treturn nil\n}\n\n///////////////////////////////////\n\nfunc fdName(fd int) string {\n\tswitch fd {\n\tcase 0:\n\t\treturn \"STDIN\"\n\tcase 1:\n\t\treturn \"STDOUT\"\n\tcase 2:\n\t\treturn \"STDERR\"\n\tcase cwdFD:\n\t\treturn \"AT_FDCWD\"\n\t}\n\n\treturn \"\"\n}\n\nfunc getIntVal(ptr uint64) int {\n\treturn int(int32(ptr))\n}\n\nfunc errnoName(ptr uint64) string {\n\tval := int(int32(ptr))\n\tif val >= 0 {\n\t\treturn \"\"\n\t}\n\n\tval *= -1\n\treturn unix.ErrnoName(syscall.Errno(val))\n}\n\nfunc getIntParam(pid int, ptr uint64) int {\n\treturn int(int32(ptr))\n}\n\nfunc getStringParam(pid int, ptr uint64) string {\n\tvar out [256]byte\n\tvar data []byte\n\tfor {\n\t\tcount, err := syscall.PtracePeekData(pid, uintptr(ptr), out[:])\n\t\tif err != nil && err != syscall.EIO {\n\t\t\tfmt.Printf(\"readString: syscall.PtracePeekData error - '%v'\\v\", err)\n\t\t}\n\n\t\tidx := bytes.IndexByte(out[:count], 0)\n\t\tvar foundNull bool\n\t\tif idx == -1 {\n\t\t\tidx = count\n\t\t\tptr += uint64(count)\n\t\t} else {\n\t\t\tfoundNull = true\n\t\t}\n\n\t\tdata = append(data, out[:idx]...)\n\t\tif foundNull {\n\t\t\treturn string(data)\n\t\t}\n\t}\n}\n\ntype SyscallTypeName string\n\nconst (\n\tCheckFileType SyscallTypeName = \"type.checkfile\"\n\tOpenFileType  SyscallTypeName = \"type.openfile\"\n\tExecType      SyscallTypeName = \"type.exec\"\n)\n\ntype SyscallProcessor interface {\n\tSyscallNumber() uint64\n\tSetSyscallNumber(uint64)\n\tSyscallType() SyscallTypeName\n\tSyscallName() string\n\tEventOnCall() bool\n\tOnCall(pid int, regs syscall.PtraceRegs, cstate *syscallState)\n\tOnReturn(pid int, regs syscall.PtraceRegs, cstate *syscallState)\n\tFailedCall(cstate *syscallState) bool\n\tFailedReturnStatus(retVal uint64) bool\n\tOKCall(cstate *syscallState) bool\n\tOKReturnStatus(retVal uint64) bool\n}\n\ntype StringParamPos int\n\ntype syscallProcessorCore struct {\n\tNum         uint64\n\tName        string\n\tType        SyscallTypeName\n\tStringParam StringParamPos\n}\n\nconst (\n\tSPPNo  StringParamPos = 0\n\tSPPOne StringParamPos = 1\n\tSPPTwo StringParamPos = 2\n)\n\nfunc (ref *syscallProcessorCore) SyscallNumber() uint64 {\n\treturn ref.Num\n}\n\nfunc (ref *syscallProcessorCore) SetSyscallNumber(num uint64) {\n\tref.Num = num\n}\n\nfunc (ref *syscallProcessorCore) SyscallType() SyscallTypeName {\n\treturn ref.Type\n}\n\nfunc (ref *syscallProcessorCore) SyscallName() string {\n\treturn ref.Name\n}\n\nfunc (ref *syscallProcessorCore) OnCall(pid int, regs syscall.PtraceRegs, cstate *syscallState) {\n\tpth := \"\"\n\tdir := \"\"\n\tvar fd int\n\n\tswitch ref.StringParam {\n\tcase SPPNo:\n\t\tlog.Tracef(\"syscallProcessorCore.OnCall[%s/%d]: pid=%d - no string param\", ref.Name, ref.Num, pid)\n\t\treturn\n\tcase SPPOne:\n\t\tpth = getStringParam(pid, system.CallFirstParam(regs))\n\tcase SPPTwo:\n\t\tfd = getIntParam(pid, system.CallFirstParam(regs))\n\t\t//cwdFD < 0 / (stdin=0/stdout=1/stderr=2)\n\t\tif fd > 2 {\n\t\t\tdir, _ = os.Readlink(fmt.Sprintf(\"/proc/%d/fd/%d\", pid, fd))\n\t\t}\n\t\tpth = getStringParam(pid, system.CallSecondParam(regs))\n\tdefault:\n\t\tpanic(\"unreachable\")\n\t}\n\n\t//fmt.Printf(\"[pid=%d][1]ptrace.SPC.OnCall[%v/%v](fd=[%x/%d/%s]/pth:'%s')\\n\",\n\t//\tpid, ref.Num, ref.Name, fd, fd, fdName(fd), pth)\n\n\tif len(pth) == 0 || (len(pth) > 0 && pth[0] != '/') {\n\t\tif dir != \"\" {\n\t\t\tpth = path.Join(dir, pth)\n\t\t} else if fd == cwdFD {\n\t\t\t//todo: track cwd with process/pid (so we don't need to look it up later for each call)\n\t\t\tcwd, _ := os.Readlink(fmt.Sprintf(\"/proc/%d/cwd\", pid))\n\t\t\tif cwd != \"\" {\n\t\t\t\tpth = path.Join(cwd, pth)\n\t\t\t}\n\t\t}\n\t}\n\n\tcstate.pathParam = filepath.Clean(pth)\n\t//fmt.Printf(\"[pid=%d][2]ptrace.SPC.OnCall[%v/%v](fd=[%x/%d/%s]/pp:'%s')\\n\",\n\t//\tpid, ref.Num, ref.Name, fd, fd, fdName(fd), cstate.pathParam)\n}\n\nfunc (ref *syscallProcessorCore) OnReturn(pid int, regs syscall.PtraceRegs, cstate *syscallState) {\n\t//for stat/check syscalls:\n\t//-2 => -ENOENT (No such file or directory)\n\tintRetVal := getIntVal(cstate.retVal)\n\terrnoStr := errnoName(cstate.retVal)\n\n\tif cstate.pathParamErr == nil {\n\t\t//fmt.Printf(\"[pid=%d][3]ptrace.SPC.OnReturn[%v/%v](pp:'%s') = %x/%d/%s\\n\",\n\t\t//\tpid, cstate.callNum, ref.Name, cstate.pathParam, cstate.retVal, intRetVal, errnoStr)\n\n\t\tlog.Tracef(\"checkFileSyscallProcessor.OnReturn: [%d] {%d}%s('%s') = %x/%d/%s\", pid, cstate.callNum, ref.Name, cstate.pathParam, cstate.retVal, intRetVal, errnoStr)\n\t} else {\n\t\tlog.Debugf(\"checkFileSyscallProcessor.OnReturn: [%d] {%d}%s(<unknown>/'%s') = %x/%d/%s [pp err => %v]\", pid, cstate.callNum, ref.Name, cstate.pathParam, cstate.retVal, intRetVal, errnoStr, cstate.pathParamErr)\n\n\t\t//fmt.Printf(\"[pid=%d][3err]ptrace.SPC.OnReturn[%v/%v](pp:'%s'/ppe: '%v') = %x/%d/%s\\n\",\n\t\t//\tpid, cstate.callNum, ref.Name, cstate.pathParam, cstate.pathParamErr, cstate.retVal, intRetVal, errnoStr)\n\t}\n}\n\ntype checkFileSyscallProcessor struct {\n\t*syscallProcessorCore\n}\n\nfunc (ref *checkFileSyscallProcessor) FailedCall(cstate *syscallState) bool {\n\treturn cstate.retVal != 0\n}\n\nfunc (ref *checkFileSyscallProcessor) FailedReturnStatus(retVal uint64) bool {\n\treturn retVal != 0\n}\n\nfunc (ref *checkFileSyscallProcessor) OKCall(cstate *syscallState) bool {\n\treturn cstate.retVal == 0\n}\n\nfunc (ref *checkFileSyscallProcessor) OKReturnStatus(retVal uint64) bool {\n\treturn retVal == 0\n}\n\nfunc (ref *checkFileSyscallProcessor) EventOnCall() bool {\n\treturn false\n}\n\ntype openFileSyscallProcessor struct {\n\t*syscallProcessorCore\n}\n\nfunc (ref *openFileSyscallProcessor) FailedCall(cstate *syscallState) bool {\n\tfd := getIntVal(cstate.retVal)\n\treturn fd < 0\n}\n\nfunc (ref *openFileSyscallProcessor) FailedReturnStatus(retVal uint64) bool {\n\tfd := getIntVal(retVal)\n\treturn fd < 0\n}\n\nfunc (ref *openFileSyscallProcessor) OKCall(cstate *syscallState) bool {\n\tfd := getIntVal(cstate.retVal)\n\t//need to make sure it works for readlink which returns the number of read bytes\n\t//(later: has its own processor)\n\treturn fd >= 0\n}\n\nfunc (ref *openFileSyscallProcessor) OKReturnStatus(retVal uint64) bool {\n\tfd := getIntVal(retVal)\n\t//need to make sure it works for readlink which returns the number of read bytes\n\t//(later: has its own processor)\n\treturn fd >= 0\n}\n\nfunc (ref *openFileSyscallProcessor) EventOnCall() bool {\n\treturn false\n}\n\ntype execSyscallProcessor struct {\n\t*syscallProcessorCore\n}\n\nfunc (ref *execSyscallProcessor) FailedCall(cstate *syscallState) bool {\n\tfd := getIntVal(cstate.retVal)\n\treturn fd < 0\n}\n\nfunc (ref *execSyscallProcessor) FailedReturnStatus(retVal uint64) bool {\n\tfd := getIntVal(retVal)\n\treturn fd < 0\n}\n\nfunc (ref *execSyscallProcessor) OKCall(cstate *syscallState) bool {\n\tfd := getIntVal(cstate.retVal)\n\treturn fd >= 0\n}\n\nfunc (ref *execSyscallProcessor) OKReturnStatus(retVal uint64) bool {\n\tfd := getIntVal(retVal)\n\treturn fd >= 0\n}\n\nfunc (ref *execSyscallProcessor) EventOnCall() bool {\n\treturn true\n}\n\n// TODO: introduce syscall num and name consts to use instead of liternal values\nvar syscallProcessors = map[int]SyscallProcessor{}\n\nfunc init() {\n\t//readlink(const char *path, char *buf, int bufsiz)\n\t//on success, returns the number of bytes placed in buf. On error, returns -1\n\t//reusing \"open\" processor because the call error return values are similar\n\taddSyscallProcessor(&openFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"readlink\",\n\t\t\tType:        OpenFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//utime(char *filename, struct utimbuf *times)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"utime\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//utimes(char *filename, struct timeval *utimes)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"utimes\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//chdir(const char *filename)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"chdir\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//open(const char *filename, int flags, int mode)\n\taddSyscallProcessor(&openFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"open\",\n\t\t\tType:        OpenFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//readlinkat(int dfd, const char *pathname, char *buf, int bufsiz)\n\t//on success, returns the number of bytes placed in buf. On error, returns -1\n\t//reusing \"open\" processor because the call error return values are similar\n\taddSyscallProcessor(&openFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"readlinkat\",\n\t\t\tType:        OpenFileType,\n\t\t\tStringParam: SPPTwo,\n\t\t},\n\t})\n\n\t//openat(int dfd, const char *filename, int flags, int mode)\n\taddSyscallProcessor(&openFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"openat\",\n\t\t\tType:        OpenFileType,\n\t\t\tStringParam: SPPTwo,\n\t\t},\n\t})\n\t//futimesat(int dfd, const char *filename, struct timeval *utimes)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"futimesat\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPTwo,\n\t\t},\n\t})\n\n\t//\"check\" system calls with file paths:\n\n\t//access(const char *filename, int mode)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"access\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//faccessat(int dfd, const char *filename, int mode)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"faccessat\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPTwo,\n\t\t},\n\t})\n\t//stat(const char *filename,struct stat *statbuf)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"stat\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//lstat(fconst char *filename, struct stat *statbuf)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"lstat\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//statfs(const char *pathname, struct statfs *buf)\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"statfs\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf)\n\t//dirfd: AT_FDCWD\n\t//flags: AT_EMPTY_PATH\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"statx\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPTwo,\n\t\t},\n\t})\n\t//newfstatat/fstatat(int dirfd, const char *restrict pathname, struct stat *restrict statbuf, int flags)\n\t//dirfd: AT_FDCWD\n\taddSyscallProcessor(&checkFileSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"newfstatat\",\n\t\t\tType:        CheckFileType,\n\t\t\tStringParam: SPPTwo,\n\t\t},\n\t})\n\n\t//execve(const char *pathname, char *const argv[], char *const envp[])\n\taddSyscallProcessor(&execSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"execve\",\n\t\t\tType:        ExecType,\n\t\t\tStringParam: SPPOne,\n\t\t},\n\t})\n\t//execveat(int dirfd, const char *pathname, const char *const argv[], const char *const envp[], int flags)\n\taddSyscallProcessor(&execSyscallProcessor{\n\t\tsyscallProcessorCore: &syscallProcessorCore{\n\t\t\tName:        \"execveat\",\n\t\t\tType:        ExecType,\n\t\t\tStringParam: SPPTwo,\n\t\t},\n\t})\n}\n\nfunc addSyscallProcessor(p SyscallProcessor) {\n\tnum, found := system.LookupCallNumber(p.SyscallName())\n\tif !found {\n\t\tlog.Errorf(\"addSyscallProcessor: unknown syscall='%s'\", p.SyscallName())\n\t\treturn\n\t}\n\n\tp.SetSyscallNumber(uint64(num))\n\tsyscallProcessors[int(p.SyscallNumber())] = p\n}\n\n///////////////////////////////////\n\nfunc SignalEnum(sigNum int) string {\n\tif sigNum >= len(sigEnums) || sigNum < 0 {\n\t\treturn fmt.Sprintf(\"BAD(%d)\", sigNum)\n\t}\n\n\te := sigEnums[sigNum]\n\tif e == \"\" {\n\t\te = fmt.Sprintf(\"UNKNOWN(%d)\", sigNum)\n\t}\n\n\treturn e\n}\n\nvar sigEnums = [...]string{\n\t0:                 \"(NOSIGNAL)\",\n\tsyscall.SIGABRT:   \"SIGABRT/SIGIOT\",\n\tsyscall.SIGALRM:   \"SIGALRM\",\n\tsyscall.SIGBUS:    \"SIGBUS\",\n\tsyscall.SIGCHLD:   \"SIGCHLD\",\n\tsyscall.SIGCONT:   \"SIGCONT\",\n\tsyscall.SIGFPE:    \"SIGFPE\",\n\tsyscall.SIGHUP:    \"SIGHUP\",\n\tsyscall.SIGILL:    \"SIGILL\",\n\tsyscall.SIGINT:    \"SIGINT\",\n\tsyscall.SIGKILL:   \"SIGKILL\",\n\tsyscall.SIGPIPE:   \"SIGPIPE\",\n\tsyscall.SIGPOLL:   \"SIGIO/SIGPOLL\",\n\tsyscall.SIGPROF:   \"SIGPROF\",\n\tsyscall.SIGPWR:    \"SIGPWR\",\n\tsyscall.SIGQUIT:   \"SIGQUIT\",\n\tsyscall.SIGSEGV:   \"SIGSEGV\",\n\tsyscall.SIGSTKFLT: \"SIGSTKFLT\",\n\tsyscall.SIGSTOP:   \"SIGSTOP\",\n\tsyscall.SIGSYS:    \"SIGSYS\",\n\tsyscall.SIGTERM:   \"SIGTERM\",\n\tsyscall.SIGTRAP:   \"SIGTRAP\",\n\tsyscall.SIGTSTP:   \"SIGTSTP\",\n\tsyscall.SIGTTIN:   \"SIGTTIN\",\n\tsyscall.SIGTTOU:   \"SIGTTOU\",\n\tsyscall.SIGURG:    \"SIGURG\",\n\tsyscall.SIGUSR1:   \"SIGUSR1\",\n\tsyscall.SIGUSR2:   \"SIGUSR2\",\n\tsyscall.SIGVTALRM: \"SIGVTALRM\",\n\tsyscall.SIGWINCH:  \"SIGWINCH\",\n\tsyscall.SIGXCPU:   \"SIGXCPU\",\n\tsyscall.SIGXFSZ:   \"SIGXFSZ\",\n}\n"
  },
  {
    "path": "pkg/monitor/ptrace/types.go",
    "content": "package ptrace\n\nimport (\n\t\"io\"\n)\n\ntype AppRunOpt struct {\n\tCmd                 string\n\tArgs                []string\n\tAppStdout           io.Writer\n\tAppStderr           io.Writer\n\tWorkDir             string\n\tUser                string\n\tRunAsUser           bool\n\tRTASourcePT         bool\n\tReportOnMainPidExit bool\n}\n"
  },
  {
    "path": "pkg/pdiscover/pevents.go",
    "content": "// hacked up code from CloudFoundry\n\npackage pdiscover\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\ntype ProcEventFork struct {\n\tParentPid int // Pid of the process that called fork()\n\tChildPid  int // Child process pid created by fork()\n}\n\ntype ProcEventExec struct {\n\tPid int // Pid of the process that called exec()\n}\n\ntype ProcEventExit struct {\n\tPid int // Pid of the process that called exit()\n}\n\ntype watch struct {\n\tflags uint32 // Saved value of Watch() flags param\n}\n\ntype eventListener interface {\n\tclose() error // Watch.Close() closes the OS specific listener\n}\n\ntype Watcher struct {\n\tallFlags uint32\n\tlistener eventListener       // OS specifics (kqueue or netlink)\n\twatches  map[int]*watch      // Map of watched process ids\n\tError    chan error          // Errors are sent on this channel\n\tFork     chan *ProcEventFork // Fork events are sent on this channel\n\tExec     chan *ProcEventExec // Exec events are sent on this channel\n\tExit     chan *ProcEventExit // Exit events are sent on this channel\n\tdone     chan bool           // Used to stop the readEvents() goroutine\n\tisClosed bool                // Set to true when Close() is first called\n}\n\nfunc NewAllWatcher(flags uint32) (*Watcher, error) {\n\tlistener, err := createListener()\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tw := &Watcher{\n\t\tallFlags: flags,\n\t\tlistener: listener,\n\t\twatches:  map[int]*watch{},\n\t\tFork:     make(chan *ProcEventFork),\n\t\tExec:     make(chan *ProcEventExec),\n\t\tExit:     make(chan *ProcEventExit),\n\t\tError:    make(chan error),\n\t\tdone:     make(chan bool, 1),\n\t}\n\n\tgo w.readAllEvents()\n\treturn w, nil\n}\n\n// Initialize event listener and channels\nfunc NewWatcher() (*Watcher, error) {\n\tlistener, err := createListener()\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tw := &Watcher{\n\t\tlistener: listener,\n\t\twatches:  map[int]*watch{},\n\t\tFork:     make(chan *ProcEventFork),\n\t\tExec:     make(chan *ProcEventExec),\n\t\tExit:     make(chan *ProcEventExit),\n\t\tError:    make(chan error),\n\t\tdone:     make(chan bool, 1),\n\t}\n\n\tgo w.readEvents()\n\treturn w, nil\n}\n\n// Close event channels when done message is received\nfunc (w *Watcher) finish() {\n\tclose(w.Fork)\n\tclose(w.Exec)\n\tclose(w.Exit)\n\tclose(w.Error)\n}\n\n// Closes the OS specific event listener,\n// removes all watches and closes all event channels.\nfunc (w *Watcher) Close() error {\n\tif w.isClosed {\n\t\treturn nil\n\t}\n\tw.isClosed = true\n\n\tfor pid := range w.watches {\n\t\tw.RemoveWatch(pid)\n\t}\n\n\tw.done <- true\n\n\tw.listener.close()\n\n\treturn nil\n}\n\n// Add pid to the watched process set.\n// The flags param is a bitmask of process events to capture,\n// must be one or more of: PROC_EVENT_FORK, PROC_EVENT_EXEC, PROC_EVENT_EXIT\nfunc (w *Watcher) Watch(pid int, flags uint32) error {\n\tif w.isClosed {\n\t\treturn errors.New(\"psnotify watcher is closed\")\n\t}\n\n\twatchEntry, found := w.watches[pid]\n\n\tif found {\n\t\twatchEntry.flags |= flags\n\t} else {\n\t\tif err := w.register(pid, flags); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tw.watches[pid] = &watch{flags: flags}\n\t}\n\n\treturn nil\n}\n\nfunc (w *Watcher) WatchAll() error {\n\tif w.isClosed {\n\t\treturn errors.New(\"psnotify watcher is closed\")\n\t}\n\n\treturn nil\n}\n\n// Remove pid from the watched process set.\nfunc (w *Watcher) RemoveWatch(pid int) error {\n\t_, ok := w.watches[pid]\n\tif !ok {\n\t\tmsg := fmt.Sprintf(\"watch for pid=%d does not exist\", pid)\n\t\treturn errors.New(msg)\n\t}\n\tdelete(w.watches, pid)\n\treturn w.unregister(pid)\n}\n\n// Internal helper to check if there is a message on the \"done\" channel.\n// The \"done\" message is sent by the Close() method; when received here,\n// the Watcher.finish method is called to close all channels and return\n// true - in which case the caller should break from the readEvents loop.\nfunc (w *Watcher) isDone() bool {\n\tvar done bool\n\tselect {\n\tcase done = <-w.done:\n\t\tw.finish()\n\tdefault:\n\t}\n\treturn done\n}\n"
  },
  {
    "path": "pkg/pdiscover/pevents_darwin.go",
    "content": "package pdiscover\n\n// stubs, so 'go get' doesn't show errors on Macs...\n\nfunc createListener() (eventListener, error) {\n\treturn nil, nil\n}\n\nfunc (w *Watcher) unregister(pid int) error {\n\treturn nil\n}\n\nfunc (w *Watcher) register(pid int, flags uint32) error {\n\treturn nil\n}\n\nfunc (w *Watcher) readEvents() {\n}\n\nfunc (w *Watcher) readAllEvents() {\n}\n\nfunc (w *Watcher) isWatching(pid int, event uint32) bool {\n\treturn false\n}\n"
  },
  {
    "path": "pkg/pdiscover/pevents_linux.go",
    "content": "// hacked up code from CloudFoundry\n\n// Go interface to the Linux netlink process connector.\n// See Documentation/connector/connector.txt in the linux kernel source tree.\npackage pdiscover\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"os\"\n\t\"syscall\"\n)\n\nconst (\n\t// internal flags (from <linux/connector.h>)\n\t_CN_IDX_PROC = 0x1\n\t_CN_VAL_PROC = 0x1\n\n\t// internal flags (from <linux/cn_proc.h>)\n\t_PROC_CN_MCAST_LISTEN = 1\n\t_PROC_CN_MCAST_IGNORE = 2\n\n\t// Flags (from <linux/cn_proc.h>)\n\tPROC_EVENT_FORK = 0x00000001 // fork() events\n\tPROC_EVENT_EXEC = 0x00000002 // exec() events\n\tPROC_EVENT_EXIT = 0x80000000 // exit() events\n\t//KCQ:\n\t//NEED TO ADD MORE EVENTS (TBD)\n\n\t// Watch for all process events\n\tPROC_EVENT_ALL = PROC_EVENT_FORK | PROC_EVENT_EXEC | PROC_EVENT_EXIT\n)\n\nvar (\n\tbyteOrder = binary.LittleEndian\n)\n\n// linux/connector.h: struct cb_id\ntype cbId struct {\n\tIdx uint32\n\tVal uint32\n}\n\n// linux/connector.h: struct cb_msg\ntype cnMsg struct {\n\tId    cbId\n\tSeq   uint32\n\tAck   uint32\n\tLen   uint16\n\tFlags uint16\n}\n\n// linux/cn_proc.h: struct proc_event.{what,cpu,timestamp_ns}\ntype procEventHeader struct {\n\tWhat      uint32\n\tCpu       uint32\n\tTimestamp uint64\n}\n\n// linux/cn_proc.h: struct proc_event.fork\ntype forkProcEvent struct {\n\tParentPid  uint32\n\tParentTgid uint32\n\tChildPid   uint32\n\tChildTgid  uint32\n}\n\n// linux/cn_proc.h: struct proc_event.exec\ntype execProcEvent struct {\n\tProcessPid  uint32\n\tProcessTgid uint32\n}\n\n// linux/cn_proc.h: struct proc_event.exit\ntype exitProcEvent struct {\n\tProcessPid  uint32\n\tProcessTgid uint32\n\tExitCode    uint32\n\tExitSignal  uint32\n}\n\n// standard netlink header + connector header\ntype netlinkProcMessage struct {\n\tHeader syscall.NlMsghdr\n\tData   cnMsg\n}\n\ntype netlinkListener struct {\n\taddr *syscall.SockaddrNetlink // Netlink socket address\n\tsock int                      // The syscall.Socket() file descriptor\n\tseq  uint32                   // struct cn_msg.seq\n}\n\n// Initialize linux implementation of the eventListener interface\nfunc createListener() (eventListener, error) {\n\tlistener := &netlinkListener{}\n\terr := listener.bind()\n\treturn listener, err\n}\n\n// noop on linux\nfunc (w *Watcher) unregister(pid int) error {\n\treturn nil\n}\n\n// noop on linux\nfunc (w *Watcher) register(pid int, flags uint32) error {\n\treturn nil\n}\n\n// Read events from the netlink socket\nfunc (w *Watcher) readEvents() {\n\tbuf := make([]byte, syscall.Getpagesize())\n\n\tlistener, _ := w.listener.(*netlinkListener)\n\n\tfor {\n\t\tif w.isDone() {\n\t\t\treturn\n\t\t}\n\n\t\tnr, _, err := syscall.Recvfrom(listener.sock, buf, 0)\n\n\t\tif err != nil {\n\t\t\tw.Error <- err\n\t\t\tcontinue\n\t\t}\n\t\tif nr < syscall.NLMSG_HDRLEN {\n\t\t\tw.Error <- syscall.EINVAL\n\t\t\tcontinue\n\t\t}\n\n\t\tmsgs, _ := syscall.ParseNetlinkMessage(buf[:nr])\n\n\t\tfor _, m := range msgs {\n\t\t\tif m.Header.Type == syscall.NLMSG_DONE {\n\t\t\t\tw.handleEvent(m.Data)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (w *Watcher) readAllEvents() {\n\tbuf := make([]byte, syscall.Getpagesize())\n\n\tlistener, _ := w.listener.(*netlinkListener)\n\n\tfor {\n\t\tif w.isDone() {\n\t\t\treturn\n\t\t}\n\n\t\tnr, _, err := syscall.Recvfrom(listener.sock, buf, 0)\n\n\t\tif err != nil {\n\t\t\tw.Error <- err\n\t\t\tcontinue\n\t\t}\n\t\tif nr < syscall.NLMSG_HDRLEN {\n\t\t\tw.Error <- syscall.EINVAL\n\t\t\tcontinue\n\t\t}\n\n\t\tmsgs, _ := syscall.ParseNetlinkMessage(buf[:nr])\n\n\t\tfor _, m := range msgs {\n\t\t\tif m.Header.Type == syscall.NLMSG_DONE {\n\t\t\t\tw.handleEventAll(m.Data)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Internal helper to check if pid && event is being watched\nfunc (w *Watcher) isWatching(pid int, event uint32) bool {\n\tif watch, ok := w.watches[pid]; ok {\n\t\treturn (watch.flags & event) == event\n\t}\n\treturn false\n}\n\n// Dispatch events from the netlink socket to the Event channels.\n// Unlike bsd kqueue, netlink receives events for all pids,\n// so we apply filtering based on the watch table via isWatching()\nfunc (w *Watcher) handleEvent(data []byte) {\n\tbuf := bytes.NewBuffer(data)\n\tmsg := &cnMsg{}\n\thdr := &procEventHeader{}\n\n\tbinary.Read(buf, byteOrder, msg)\n\tbinary.Read(buf, byteOrder, hdr)\n\n\tswitch hdr.What {\n\tcase PROC_EVENT_FORK:\n\t\tevent := &forkProcEvent{}\n\t\tbinary.Read(buf, byteOrder, event)\n\t\tppid := int(event.ParentTgid)\n\t\tpid := int(event.ChildTgid)\n\n\t\tif w.isWatching(ppid, PROC_EVENT_EXEC) {\n\t\t\t// follow forks\n\t\t\twatch, _ := w.watches[ppid]\n\t\t\tw.Watch(pid, watch.flags)\n\t\t}\n\n\t\tif w.isWatching(ppid, PROC_EVENT_FORK) {\n\t\t\tw.Fork <- &ProcEventFork{ParentPid: ppid, ChildPid: pid}\n\t\t}\n\tcase PROC_EVENT_EXEC:\n\t\tevent := &execProcEvent{}\n\t\tbinary.Read(buf, byteOrder, event)\n\t\tpid := int(event.ProcessTgid)\n\n\t\tif w.isWatching(pid, PROC_EVENT_EXEC) {\n\t\t\tw.Exec <- &ProcEventExec{Pid: pid}\n\t\t}\n\tcase PROC_EVENT_EXIT:\n\t\tevent := &exitProcEvent{}\n\t\tbinary.Read(buf, byteOrder, event)\n\t\tpid := int(event.ProcessTgid)\n\n\t\tif w.isWatching(pid, PROC_EVENT_EXIT) {\n\t\t\tw.RemoveWatch(pid)\n\t\t\tw.Exit <- &ProcEventExit{Pid: pid}\n\t\t}\n\t}\n}\n\nfunc (w *Watcher) handleEventAll(data []byte) {\n\tbuf := bytes.NewBuffer(data)\n\tmsg := &cnMsg{}\n\thdr := &procEventHeader{}\n\n\tbinary.Read(buf, byteOrder, msg)\n\tbinary.Read(buf, byteOrder, hdr)\n\n\tswitch hdr.What {\n\tcase PROC_EVENT_FORK:\n\t\tevent := &forkProcEvent{}\n\t\tbinary.Read(buf, byteOrder, event)\n\t\tppid := int(event.ParentTgid)\n\t\tpid := int(event.ChildTgid)\n\n\t\tw.Fork <- &ProcEventFork{ParentPid: ppid, ChildPid: pid}\n\tcase PROC_EVENT_EXEC:\n\t\tevent := &execProcEvent{}\n\t\tbinary.Read(buf, byteOrder, event)\n\t\tpid := int(event.ProcessTgid)\n\n\t\tw.Exec <- &ProcEventExec{Pid: pid}\n\tcase PROC_EVENT_EXIT:\n\t\tevent := &exitProcEvent{}\n\t\tbinary.Read(buf, byteOrder, event)\n\t\tpid := int(event.ProcessTgid)\n\n\t\tw.Exit <- &ProcEventExit{Pid: pid}\n\t}\n}\n\n// Bind our netlink socket and\n// send a listen control message to the connector driver.\nfunc (listener *netlinkListener) bind() error {\n\tsock, err := syscall.Socket(\n\t\tsyscall.AF_NETLINK,\n\t\tsyscall.SOCK_DGRAM,\n\t\tsyscall.NETLINK_CONNECTOR)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlistener.sock = sock\n\tlistener.addr = &syscall.SockaddrNetlink{\n\t\tFamily: syscall.AF_NETLINK,\n\t\tGroups: _CN_IDX_PROC,\n\t}\n\n\terr = syscall.Bind(listener.sock, listener.addr)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn listener.send(_PROC_CN_MCAST_LISTEN)\n}\n\n// Send an ignore control message to the connector driver\n// and close our netlink socket.\nfunc (listener *netlinkListener) close() error {\n\terr := listener.send(_PROC_CN_MCAST_IGNORE)\n\tsyscall.Close(listener.sock)\n\treturn err\n}\n\n// Generic method for sending control messages to the connector\n// driver; where op is one of PROC_CN_MCAST_{LISTEN,IGNORE}\nfunc (listener *netlinkListener) send(op uint32) error {\n\tlistener.seq++\n\tpr := &netlinkProcMessage{}\n\tplen := binary.Size(pr.Data) + binary.Size(op)\n\tpr.Header.Len = syscall.NLMSG_HDRLEN + uint32(plen)\n\tpr.Header.Type = uint16(syscall.NLMSG_DONE)\n\tpr.Header.Flags = 0\n\tpr.Header.Seq = listener.seq\n\tpr.Header.Pid = uint32(os.Getpid())\n\n\tpr.Data.Id.Idx = _CN_IDX_PROC\n\tpr.Data.Id.Val = _CN_VAL_PROC\n\n\tpr.Data.Len = uint16(binary.Size(op))\n\n\tbuf := bytes.NewBuffer(make([]byte, 0, pr.Header.Len))\n\tbinary.Write(buf, byteOrder, pr)\n\tbinary.Write(buf, byteOrder, op)\n\n\treturn syscall.Sendto(listener.sock, buf.Bytes(), 0, listener.addr)\n}\n"
  },
  {
    "path": "pkg/pdiscover/pinfo.go",
    "content": "package pdiscover\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\tErrInvalidProcArgsLen = errors.New(\"invalid ProcArgs length\")\n\tErrInvalidProcInfo    = errors.New(\"invalid proc info\")\n)\n"
  },
  {
    "path": "pkg/pdiscover/pinfo_darwin.go",
    "content": "package pdiscover\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst (\n\tCTLKern      = 1\n\tKernProcArgs = 38\n)\n\nfunc GetOwnProcPath() (string, error) {\n\treturn GetProcPath(os.Getpid())\n}\n\nfunc GetProcPath(pid int) (string, error) {\n\tnameMib := []int32{CTLKern, KernProcArgs, int32(pid), -1}\n\n\tprocArgsLen := uintptr(0)\n\n\tif err := getSysCtlInfo(nameMib, nil, &procArgsLen); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif procArgsLen == 0 {\n\t\treturn \"\", ErrInvalidProcArgsLen\n\t}\n\n\tprocArgs := make([]byte, procArgsLen)\n\n\tif err := getSysCtlInfo(nameMib, &procArgs[0], &procArgsLen); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif procArgsLen == 0 {\n\t\treturn \"\", ErrInvalidProcArgsLen\n\t}\n\n\texePath := exePathFromProcArgs(procArgs)\n\n\texePath, err := filepath.Abs(exePath)\n\tif err != nil {\n\t\treturn exePath, err\n\t}\n\n\tif exePath, err := filepath.EvalSymlinks(exePath); err != nil {\n\t\treturn exePath, err\n\t}\n\n\treturn exePath, nil\n}\n\nfunc getSysCtlInfo(name []int32, value *byte, valueLen *uintptr) error {\n\t_, _, errNum := syscall.Syscall6(syscall.SYS___SYSCTL,\n\t\tuintptr(unsafe.Pointer(&name[0])),\n\t\tuintptr(len(name)),\n\t\tuintptr(unsafe.Pointer(value)),\n\t\tuintptr(unsafe.Pointer(valueLen)),\n\t\t0, 0)\n\tif errNum != 0 {\n\t\treturn errNum\n\t}\n\n\treturn nil\n}\n\nfunc GetProcInfo(pid int) map[string]string {\n\treturn nil\n}\n\nfunc exePathFromProcArgs(raw []byte) string {\n\tfor i, byteVal := range raw {\n\t\tif byteVal == 0 {\n\t\t\treturn string(raw[:i])\n\t\t}\n\t}\n\n\treturn \"\"\n}\n"
  },
  {
    "path": "pkg/pdiscover/pinfo_linux.go",
    "content": "package pdiscover\n\nimport (\n\t\"os\"\n\t\"strconv\"\n)\n\nfunc procFileName(pid int, name string) string {\n\treturn \"/proc/\" + strconv.Itoa(pid) + \"/\" + name\n}\n\nfunc GetProcInfo(pid int) map[string]string {\n\tlinkFields := []string{\"exe\", \"cwd\", \"root\"}\n\tvalFields := []string{\"cmdline\", \"environ\"}\n\n\tfields := map[string]string{}\n\n\tfor _, name := range linkFields {\n\t\tval, err := os.Readlink(procFileName(pid, name))\n\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tfields[name] = val\n\t}\n\n\tfor _, name := range valFields {\n\t\tval, err := os.ReadFile(procFileName(pid, name))\n\n\t\tif err != nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tfields[name] = string(val)\n\t}\n\n\treturn fields\n}\n\nfunc GetOwnProcPath() (string, error) {\n\treturn os.Readlink(\"/proc/self/exe\")\n}\n\nfunc GetProcPath(pid int) (string, error) {\n\tprocInfo := GetProcInfo(pid)\n\n\tif procInfo == nil {\n\t\treturn \"\", ErrInvalidProcInfo\n\t}\n\n\treturn procInfo[\"exe\"], nil\n}\n"
  },
  {
    "path": "pkg/report/command_report.go",
    "content": "package report\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/command\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerfile/reverse\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/dockerimage\"\n\t\"github.com/slimtoolkit/slim/pkg/docker/linter/check\"\n\t\"github.com/slimtoolkit/slim/pkg/system\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\t\"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// DefaultFilename is the default name for the command report\nconst DefaultFilename = \"slim.report.json\"\n\nconst tmpPath = \"/tmp\"\n\n// Command is the common command report data\ntype Command struct {\n\treportLocation string\n\tVersion        string     `json:\"version\"`\n\tEngine         string     `json:\"engine\"`\n\tContainerized  bool       `json:\"containerized\"`\n\tHostDistro     DistroInfo `json:\"host_distro\"`\n\t//Docker         string  `json:\"docker,omitempty\"`\n\tType  command.Type  `json:\"type\"`\n\tState command.State `json:\"state\"`\n\tError string        `json:\"error,omitempty\"`\n}\n\n// ImageIdentity includes the container image identity fields\ntype ImageIdentity struct {\n\tID          string   `json:\"id\"`\n\tTags        []string `json:\"tags,omitempty\"`\n\tNames       []string `json:\"names,omitempty\"`\n\tDigests     []string `json:\"digests,omitempty\"`\n\tFullDigests []string `json:\"full_digests,omitempty\"`\n}\n\n// ImageMetadata provides basic image metadata\ntype ImageMetadata struct {\n\tIdentity              ImageIdentity     `json:\"identity\"`\n\tSize                  int64             `json:\"size\"`\n\tSizeHuman             string            `json:\"size_human\"`\n\tCreateTime            string            `json:\"create_time\"`\n\tAuthor                string            `json:\"author,omitempty\"`\n\tMaintainers           []string          `json:\"maintainers,omitempty\"`\n\tDockerVersion         string            `json:\"docker_version\"`\n\tArchitecture          string            `json:\"architecture\"`\n\tUser                  string            `json:\"user,omitempty\"`\n\tExposedPorts          []string          `json:\"exposed_ports,omitempty\"`\n\tOS                    string            `json:\"os,omitempty\"`\n\tVolumes               []string          `json:\"volumes,omitempty\"`\n\tLabels                map[string]string `json:\"labels,omitempty\"`\n\tEnvVars               []string          `json:\"env_vars,omitempty\"`\n\tWorkDir               string            `json:\"workdir,omitempty\"`\n\tInheritedInstructions []string          `json:\"inherited_instructions,omitempty\"`\n\n\t//TODO:\n\t//Should be in ImageReport dockerimage.ImageReport\n\t//because it's additional info discovered during analysis\n\t//BUT also need to find a way to make it available\n\t//for the 'build' command (at least, distro)\n\tDistro         *DistroInfo        `json:\"distro,omitempty\"`\n\tBuildpack      *BuildpackInfo     `json:\"buildpack,omitempty\"`\n\tContainerEntry ContainerEntryInfo `json:\"container_entry\"`\n\n\t//Base image info\n\tBaseImageDigest string `json:\"base_image_digest,omitempty\"`\n\tBaseImageName   string `json:\"base_image_name,omitempty\"`\n}\n\ntype ContainerEntryInfo struct {\n\tEntrypoint  []string             `json:\"entrypoint,omitempty\"`\n\tCmd         []string             `json:\"cmd,omitempty\"`\n\tExePath     string               `json:\"exe_path\"`\n\tFullExePath *ContainerFileInfo   `json:\"full_exe_path,omitempty\"`\n\tExeArgs     []string             `json:\"exe_args,omitempty\"`\n\tArgFiles    []*ContainerFileInfo `json:\"arg_files,omitempty\"`\n}\n\ntype ContainerFileInfo struct {\n\tName  string `json:\"name\"`\n\tLayer int    `json:\"layer\"`\n}\n\ntype BuildpackInfo struct {\n\tStack     string `json:\"stack\"`\n\tVendor    string `json:\"vendor,omitempty\"`\n\tBuildpack string `json:\"buildpack,omitempty\"`\n}\n\n// SystemMetadata provides basic system metadata\ntype SystemMetadata struct {\n\tType    string     `json:\"type\"`\n\tRelease string     `json:\"release\"`\n\tDistro  DistroInfo `json:\"distro\"`\n}\n\n// Output Version for 'build'\nconst OVBuildCommand = \"1.1\"\n\n// BuildCommand is the 'build' command report data\ntype BuildCommand struct {\n\tCommand\n\tTargetReference        string               `json:\"target_reference\"`\n\tSystem                 SystemMetadata       `json:\"system\"`\n\tSourceImage            ImageMetadata        `json:\"source_image\"`\n\tMinifiedImageSize      int64                `json:\"minified_image_size\"`\n\tMinifiedImageSizeHuman string               `json:\"minified_image_size_human\"`\n\tMinifiedImage          string               `json:\"minified_image\"`\n\tMinifiedImageID        string               `json:\"minified_image_id\"`\n\tMinifiedImageDigest    string               `json:\"minified_image_digest\"`\n\tMinifiedImageHasData   bool                 `json:\"minified_image_has_data\"`\n\tMinifiedBy             float64              `json:\"minified_by\"`\n\tArtifactLocation       string               `json:\"artifact_location\"`\n\tContainerReportName    string               `json:\"container_report_name\"`\n\tSeccompProfileName     string               `json:\"seccomp_profile_name\"`\n\tAppArmorProfileName    string               `json:\"apparmor_profile_name\"`\n\tImageStack             []*reverse.ImageInfo `json:\"image_stack\"`\n\tImageCreated           bool                 `json:\"image_created\"`\n\tImageBuildEngine       string               `json:\"image_build_engine\"`\n}\n\n// Output Version for 'profile'\nconst OVProfileCommand = \"1.0\"\n\n// ProfileCommand is the 'profile' command report data\ntype ProfileCommand struct {\n\tCommand\n\tOriginalImage          string  `json:\"original_image\"`\n\tOriginalImageSize      int64   `json:\"original_image_size\"`\n\tOriginalImageSizeHuman string  `json:\"original_image_size_human\"`\n\tMinifiedImageSize      int64   `json:\"minified_image_size\"`\n\tMinifiedImageSizeHuman string  `json:\"minified_image_size_human\"`\n\tMinifiedImage          string  `json:\"minified_image\"`\n\tMinifiedImageHasData   bool    `json:\"minified_image_has_data\"`\n\tMinifiedBy             float64 `json:\"minified_by\"`\n\tArtifactLocation       string  `json:\"artifact_location\"`\n\tContainerReportName    string  `json:\"container_report_name\"`\n\tSeccompProfileName     string  `json:\"seccomp_profile_name\"`\n\tAppArmorProfileName    string  `json:\"apparmor_profile_name\"`\n}\n\n// Output Version for 'xray'\nconst OVXrayCommand = \"1.2.3\"\n\n// XrayCommand is the 'xray' command report data\ntype XrayCommand struct {\n\tCommand\n\tTargetReference      string                            `json:\"target_reference\"`\n\tSourceImage          ImageMetadata                     `json:\"source_image\"`\n\tArtifactLocation     string                            `json:\"artifact_location\"`\n\tImageReport          *dockerimage.ImageReport          `json:\"image_report,omitempty\"`\n\tImageStack           []*reverse.ImageInfo              `json:\"image_stack\"`\n\tImageLayers          []*dockerimage.LayerReport        `json:\"image_layers\"`\n\tImageArchiveLocation string                            `json:\"image_archive_location\"`\n\tRawImageManifest     *dockerimage.DockerManifestObject `json:\"raw_image_manifest,omitempty\"`\n\tRawImageConfig       *dockerimage.ConfigObject         `json:\"raw_image_config,omitempty\"`\n}\n\n// Output Version for 'lint'\nconst OVLintCommand = \"1.0\"\n\n// LintCommand is the 'lint' command report data\ntype LintCommand struct {\n\tCommand\n\tTargetType      string                   `json:\"target_type\"`\n\tTargetReference string                   `json:\"target_reference\"`\n\tBuildContextDir string                   `json:\"build_context_dir,omitempty\"`\n\tHitsCount       int                      `json:\"hits_count\"`\n\tNoHitsCount     int                      `json:\"nohits_count\"`\n\tErrorsCount     int                      `json:\"errors_count\"`\n\tHits            map[string]*check.Result `json:\"hits,omitempty\"`   //map[CHECK_ID]CHECK_RESULT\n\tErrors          map[string]error         `json:\"errors,omitempty\"` //map[CHECK_ID]ERROR_INFO\n}\n\n// Output Version for 'images'\nconst OVImagesCommand = \"1.0\"\n\n// ImagesCommand is the 'images' command report data\ntype ImagesCommand struct {\n\tCommand\n}\n\n// Output Version for 'containerize'\nconst OVContainerizeCommand = \"1.0\"\n\n// ContainerizeCommand is the 'containerize' command report data\ntype ContainerizeCommand struct {\n\tCommand\n}\n\n// Output Version for 'convert'\nconst OVConvertCommand = \"1.0\"\n\n// ConvertCommand is the 'convert' command report data\ntype ConvertCommand struct {\n\tCommand\n}\n\n// Output Version for 'merge'\nconst OVMergeCommand = \"1.0\"\n\n// MergeCommand is the 'merge' command report data\ntype MergeCommand struct {\n\tCommand\n\tFirstImage           string `json:\"first_image\"`\n\tLastImage            string `json:\"last_image\"`\n\tUseLastImageMetadata bool   `json:\"use_last_image_metadata\"`\n}\n\n// Output Version for 'edit'\nconst OVEditCommand = \"1.0\"\n\n// EditCommand is the 'edit' command report data\ntype EditCommand struct {\n\tCommand\n}\n\n// Output Version for 'debug'\nconst OVDebugCommand = \"1.0\"\n\n// DebugCommand is the 'debug' command report data\ntype DebugCommand struct {\n\tCommand\n}\n\n// Output Version for 'probe'\nconst OVProbeCommand = \"1.0\"\n\n// ProbeCommand is the 'probe' command report data\ntype ProbeCommand struct {\n\tCommand\n}\n\n// Output Version for 'server'\nconst OVServerCommand = \"1.0\"\n\n// ServerCommand is the 'server' command report data\ntype ServerCommand struct {\n\tCommand\n}\n\n// Output Version for 'run'\nconst OVRunCommand = \"1.0\"\n\n// RunCommand is the 'run' command report data\ntype RunCommand struct {\n\tCommand\n\tTargetReference string `json:\"target_reference\"`\n}\n\n// Output Version for 'registry'\nconst OVRegistryCommand = \"1.0\"\n\n// RegistryCommand is the 'registry' command report data\ntype RegistryCommand struct {\n\tCommand\n\tTargetReference string `json:\"target_reference\"`\n}\n\n// Output Version for 'vulnerability'\nconst OVVulnerabilityCommand = \"1.0\"\n\n// VulnerabilityCommand is the 'vulnerability' command report data\ntype VulnerabilityCommand struct {\n\tCommand\n\tOperation string `json:\"operation\"`\n}\n\nfunc (cmd *Command) init(containerized bool) {\n\tcmd.Containerized = containerized\n\tcmd.Engine = version.Current()\n\n\thinfo := system.GetSystemInfo()\n\tcmd.HostDistro = DistroInfo{\n\t\tName:        hinfo.Distro.Name,\n\t\tVersion:     hinfo.Distro.Version,\n\t\tDisplayName: hinfo.Distro.DisplayName,\n\t}\n}\n\n// NewBuildCommand creates a new 'build' command report\nfunc NewBuildCommand(reportLocation string, containerized bool) *BuildCommand {\n\tcmd := &BuildCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVBuildCommand, //build command 'results' version (report and artifacts)\n\t\t\tType:           command.Build,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewProfileCommand creates a new 'profile' command report\nfunc NewProfileCommand(reportLocation string, containerized bool) *ProfileCommand {\n\tcmd := &ProfileCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVProfileCommand, //profile command 'results' version (report and artifacts)\n\t\t\tType:           command.Profile,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewXrayCommand creates a new 'xray' command report\nfunc NewXrayCommand(reportLocation string, containerized bool) *XrayCommand {\n\tcmd := &XrayCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVXrayCommand, //xray command 'results' version (report and artifacts)\n\t\t\tType:           command.Xray,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewLintCommand creates a new 'lint' command report\nfunc NewLintCommand(reportLocation string, containerized bool) *LintCommand {\n\tcmd := &LintCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVLintCommand, //lint command 'results' version (report and artifacts)\n\t\t\tType:           command.Lint,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewImagesCommand creates a new 'images' command report\nfunc NewImagesCommand(reportLocation string, containerized bool) *ImagesCommand {\n\tcmd := &ImagesCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVImagesCommand, //images command 'results' version (report and artifacts)\n\t\t\tType:           command.Images,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewContainerizeCommand creates a new 'containerize' command report\nfunc NewContainerizeCommand(reportLocation string, containerized bool) *ContainerizeCommand {\n\tcmd := &ContainerizeCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVContainerizeCommand, //containerize command 'results' version (report and artifacts)\n\t\t\tType:           command.Containerize,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewConvertCommand creates a new 'convert' command report\nfunc NewConvertCommand(reportLocation string, containerized bool) *ConvertCommand {\n\tcmd := &ConvertCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVConvertCommand, //convert command 'results' version (report and artifacts)\n\t\t\tType:           command.Convert,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewMergeCommand creates a new 'edit' command report\nfunc NewMergeCommand(reportLocation string, containerized bool) *MergeCommand {\n\tcmd := &MergeCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVMergeCommand, //edit command 'results' version (report and artifacts)\n\t\t\tType:           command.Merge,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewEditCommand creates a new 'edit' command report\nfunc NewEditCommand(reportLocation string, containerized bool) *EditCommand {\n\tcmd := &EditCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVEditCommand, //edit command 'results' version (report and artifacts)\n\t\t\tType:           command.Edit,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewDebugCommand creates a new 'debug' command report\nfunc NewDebugCommand(reportLocation string, containerized bool) *DebugCommand {\n\tcmd := &DebugCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVDebugCommand, //debug command 'results' version (report and artifacts)\n\t\t\tType:           command.Debug,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewProbeCommand creates a new 'probe' command report\nfunc NewProbeCommand(reportLocation string, containerized bool) *ProbeCommand {\n\tcmd := &ProbeCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVProbeCommand, //probe command 'results' version (report and artifacts)\n\t\t\tType:           command.Probe,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewServerCommand creates a new 'server' command report\nfunc NewServerCommand(reportLocation string, containerized bool) *ServerCommand {\n\tcmd := &ServerCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVServerCommand, //server command 'results' version (report and artifacts)\n\t\t\tType:           command.Server,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewRunCommand creates a new 'run' command report\nfunc NewRunCommand(reportLocation string, containerized bool) *RunCommand {\n\tcmd := &RunCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVRunCommand, //run command 'results' version (report and artifacts)\n\t\t\tType:           command.Run,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewRegistryCommand creates a new 'registry' command report\nfunc NewRegistryCommand(reportLocation string, containerized bool) *RegistryCommand {\n\tcmd := &RegistryCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVRegistryCommand, //registry command 'results' version (report and artifacts)\n\t\t\tType:           command.Registry,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\n// NewVulnerabilityCommand creates a new 'registry' command report\nfunc NewVulnerabilityCommand(reportLocation string, containerized bool) *VulnerabilityCommand {\n\tcmd := &VulnerabilityCommand{\n\t\tCommand: Command{\n\t\t\treportLocation: reportLocation,\n\t\t\tVersion:        OVVulnerabilityCommand,\n\t\t\tType:           command.Vulnerability,\n\t\t\tState:          command.StateUnknown,\n\t\t},\n\t}\n\n\tcmd.Command.init(containerized)\n\treturn cmd\n}\n\nfunc (p *Command) ReportLocation() string {\n\treturn p.reportLocation\n}\n\nfunc (p *Command) saveInfo(info interface{}) bool {\n\tif p.reportLocation != \"\" {\n\t\tdirName := filepath.Dir(p.reportLocation)\n\t\tbaseName := filepath.Base(p.reportLocation)\n\n\t\tif baseName == \".\" {\n\t\t\tfmt.Printf(\"no build command report location: %v\\n\", p.reportLocation)\n\t\t\treturn false\n\t\t}\n\n\t\tif dirName != \".\" {\n\t\t\t_, err := os.Stat(dirName)\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tos.MkdirAll(dirName, 0777)\n\t\t\t\t_, err = os.Stat(dirName)\n\t\t\t\terrutil.FailOn(err)\n\t\t\t}\n\t\t}\n\n\t\tvar reportData bytes.Buffer\n\t\tencoder := json.NewEncoder(&reportData)\n\t\tencoder.SetEscapeHTML(false)\n\t\tencoder.SetIndent(\"\", \"  \")\n\t\terr := encoder.Encode(info)\n\t\terrutil.FailOn(err)\n\n\t\terr = os.WriteFile(p.reportLocation, reportData.Bytes(), 0644)\n\t\tif err != nil && os.IsPermission(err) {\n\t\t\tif pinfo, tmpErr := os.Stat(tmpPath); tmpErr == nil && pinfo.IsDir() {\n\t\t\t\tp.reportLocation = filepath.Join(tmpPath, DefaultFilename)\n\t\t\t\tlog.Debugf(\"report.saveInfo - overriding command report file path to %v\", p.reportLocation)\n\t\t\t\terr = os.WriteFile(p.reportLocation, reportData.Bytes(), 0644)\n\t\t\t} else {\n\t\t\t\tfmt.Printf(\"report.Command.saveInfo: not saving report file - '%s'\\n\", p.reportLocation)\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\terrutil.FailOn(err)\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// Save saves the report data to the configured location\nfunc (p *Command) Save() bool {\n\treturn p.saveInfo(p)\n}\n\n// Save saves the Build command report data to the configured location\nfunc (p *BuildCommand) Save() bool {\n\treturn p.saveInfo(p)\n}\n\n// Save saves the Profile command report data to the configured location\nfunc (p *ProfileCommand) Save() bool {\n\treturn p.saveInfo(p)\n}\n\n// Save saves the Xray command report data to the configured location\nfunc (p *XrayCommand) Save() bool {\n\treturn p.saveInfo(p)\n}\n\n// Save saves the Lint command report data to the configured location\nfunc (p *LintCommand) Save() bool {\n\treturn p.saveInfo(p)\n}\n"
  },
  {
    "path": "pkg/report/container_report.go",
    "content": "package report\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"os\"\n)\n\n// ArtifactType is an artifact type ID\ntype ArtifactType int\n\n// Artifact type ID constants\nconst (\n\tDirArtifactType     ArtifactType = 1\n\tFileArtifactType    ArtifactType = 2\n\tSymlinkArtifactType ArtifactType = 3\n\tUnknownArtifactType ArtifactType = 99\n)\n\nconst (\n\tDirArtifactTypeName        = \"dir\"\n\tFileArtifactTypeName       = \"file\"\n\tSymlinkArtifactTypeName    = \"symlink\"\n\tHardlinkArtifactTypeName   = \"hardlink\"\n\tUnknownArtifactTypeName    = \"unknown\"\n\tUnexpectedArtifactTypeName = \"unexpected\"\n)\n\n// DefaultContainerReportFileName is the default container report file name\nconst DefaultContainerReportFileName = \"creport.json\"\n\nvar artifactTypeNames = map[ArtifactType]string{\n\tDirArtifactType:     DirArtifactTypeName,\n\tFileArtifactType:    FileArtifactTypeName,\n\tSymlinkArtifactType: SymlinkArtifactTypeName,\n\tUnknownArtifactType: UnknownArtifactTypeName,\n}\n\n// String converts the artifact type ID to a string\nfunc (t ArtifactType) String() string {\n\treturn artifactTypeNames[t]\n}\n\nvar artifactTypeValues = map[string]ArtifactType{\n\tDirArtifactTypeName:     DirArtifactType,\n\tFileArtifactTypeName:    FileArtifactType,\n\tSymlinkArtifactTypeName: SymlinkArtifactType,\n\tUnknownArtifactTypeName: UnknownArtifactType,\n}\n\n// GetArtifactTypeValue maps an artifact type name to an artifact type ID\nfunc GetArtifactTypeValue(s string) ArtifactType {\n\treturn artifactTypeValues[s]\n}\n\n// ProcessInfo contains various process object metadata\ntype ProcessInfo struct {\n\tPid       int32  `json:\"pid\"`\n\tName      string `json:\"name\"`\n\tPath      string `json:\"path\"`\n\tCmd       string `json:\"cmd\"`\n\tCwd       string `json:\"cwd\"`\n\tRoot      string `json:\"root\"`\n\tParentPid int32  `json:\"ppid\"`\n}\n\n// FileInfo contains various file object and activity metadata\ntype FileInfo struct {\n\tEventCount   uint32 `json:\"event_count\"`\n\tFirstEventID uint32 `json:\"first_eid\"`\n\tName         string `json:\"-\"`\n\tReadCount    uint32 `json:\"reads,omitempty\"`\n\tWriteCount   uint32 `json:\"writes,omitempty\"`\n\tExeCount     uint32 `json:\"execs,omitempty\"`\n}\n\n// FanMonitorReport is a file monitoring report\ntype FanMonitorReport struct {\n\tMonitorPid       int                             `json:\"monitor_pid\"`\n\tMonitorParentPid int                             `json:\"monitor_ppid\"`\n\tEventCount       uint32                          `json:\"event_count\"`\n\tMainProcess      *ProcessInfo                    `json:\"main_process\"`\n\tProcesses        map[string]*ProcessInfo         `json:\"processes\"`\n\tProcessFiles     map[string]map[string]*FileInfo `json:\"process_files\"`\n}\n\n// PeMonitorReport is a processing monitoring report\ntype PeMonitorReport struct {\n\tChildren map[int][]int\n\tParents  map[int]int\n}\n\n// SyscallStatInfo contains various system call activity metadata\ntype SyscallStatInfo struct {\n\tNumber uint32 `json:\"num\"`\n\tName   string `json:\"name\"`\n\tCount  uint64 `json:\"count\"`\n}\n\n// PtMonitorReport contains various process execution metadata\ntype PtMonitorReport struct {\n\tEnabled      bool                       `json:\"enabled\"`\n\tArchName     string                     `json:\"arch_name\"`\n\tSyscallCount uint64                     `json:\"syscall_count\"`\n\tSyscallNum   uint32                     `json:\"syscall_num\"`\n\tSyscallStats map[string]SyscallStatInfo `json:\"syscall_stats\"`\n\tFSActivity   map[string]*FSActivityInfo `json:\"fs_activity\"`\n}\n\ntype FSActivityInfo struct {\n\tOpsAll       uint64           `json:\"ops_all\"`\n\tOpsCheckFile uint64           `json:\"ops_checkfile\"`\n\tSyscalls     map[int]struct{} `json:\"syscalls\"`\n\tPids         map[int]struct{} `json:\"pids\"`\n\tIsSubdir     bool             `json:\"is_subdir\"`\n}\n\n// ArtifactProps contains various file system artifact properties\ntype ArtifactProps struct {\n\tFileType   ArtifactType    `json:\"-\"` //todo\n\tFilePath   string          `json:\"file_path\"`\n\tMode       os.FileMode     `json:\"-\"` //todo\n\tModeText   string          `json:\"mode\"`\n\tLinkRef    string          `json:\"link_ref,omitempty\"`\n\tFlags      map[string]bool `json:\"flags,omitempty\"`\n\tDataType   string          `json:\"data_type,omitempty\"`\n\tFileSize   int64           `json:\"file_size\"`\n\tSha1Hash   string          `json:\"sha1_hash,omitempty\"`\n\tAppType    string          `json:\"app_type,omitempty\"`\n\tFileInode  uint64          `json:\"-\"` //todo\n\tFSActivity *FSActivityInfo `json:\"-\"`\n}\n\n// UnmarshalJSON decodes artifact property data\nfunc (p *ArtifactProps) UnmarshalJSON(data []byte) error {\n\ttype artifactPropsType ArtifactProps\n\tprops := &struct {\n\t\tFileTypeStr string `json:\"file_type\"`\n\t\t*artifactPropsType\n\t}{\n\t\tartifactPropsType: (*artifactPropsType)(p),\n\t}\n\n\tif err := json.Unmarshal(data, &props); err != nil {\n\t\treturn err\n\t}\n\tp.FileType = GetArtifactTypeValue(props.FileTypeStr)\n\n\treturn nil\n}\n\n// MarshalJSON encodes artifact property data\nfunc (p *ArtifactProps) MarshalJSON() ([]byte, error) {\n\ttype artifactPropsType ArtifactProps\n\tvar out bytes.Buffer\n\tencoder := json.NewEncoder(&out)\n\tencoder.SetEscapeHTML(false)\n\terr := encoder.Encode(\n\t\t&struct {\n\t\t\tFileTypeStr string `json:\"file_type\"`\n\t\t\t*artifactPropsType\n\t\t}{\n\t\t\tFileTypeStr:       p.FileType.String(),\n\t\t\tartifactPropsType: (*artifactPropsType)(p),\n\t\t})\n\n\treturn out.Bytes(), err\n}\n\n// ImageReport contains image report fields\ntype ImageReport struct {\n\tFiles []*ArtifactProps `json:\"files\"`\n}\n\n// MonitorReports contains monitoring report fields\ntype MonitorReports struct {\n\tFan *FanMonitorReport `json:\"fan\"`\n\tPt  *PtMonitorReport  `json:\"pt\"`\n}\n\n// SystemReport provides a basic system report for the container environment\ntype SystemReport struct {\n\tType    string     `json:\"type\"`\n\tRelease string     `json:\"release\"`\n\tDistro  DistroInfo `json:\"distro\"`\n}\n\n// SensorReport provides a basic sensor report for the container environment\ntype SensorReport struct {\n\tVersion string   `json:\"version\"`\n\tArgs    []string `json:\"args\"`\n}\n\n// StartCommandReport provides a basic start command report for the container environment\ntype StartCommandReport struct {\n\tAppName       string   `json:\"app_name\"`\n\tAppArgs       []string `json:\"app_args,omitempty\"`\n\tAppEntrypoint []string `json:\"app_entrypoint,omitempty\"`\n\tAppCmd        []string `json:\"app_cmd,omitempty\"`\n\tAppUser       string   `json:\"app_user,omitempty\"`\n}\n\n// ContainerReport contains container report fields\ntype ContainerReport struct {\n\tStartCommand *StartCommandReport `json:\"start_command\"`\n\tSensor       *SensorReport       `json:\"sensor\"`\n\tSystem       SystemReport        `json:\"system\"`\n\tMonitors     MonitorReports      `json:\"monitors\"`\n\tImage        ImageReport         `json:\"image\"`\n}\n\n// PermSetFromFlags maps artifact flags to permissions\nfunc PermSetFromFlags(flags map[string]bool) string {\n\tvar b bytes.Buffer\n\tif flags[\"R\"] {\n\t\tb.WriteString(\"r\")\n\t}\n\n\tif flags[\"W\"] {\n\t\tb.WriteString(\"w\")\n\t}\n\n\tif flags[\"X\"] {\n\t\tb.WriteString(\"ix\")\n\t}\n\n\treturn b.String()\n}\n"
  },
  {
    "path": "pkg/report/mondel_report.go",
    "content": "package report\n\n// DefaultContainerReportFileName is the default Monitor Data Event Log file name\nconst DefaultMonDelFileName = \"mondel.ndjson\"\n\n// Event source\nconst (\n\tMDESourceDel = \".del\" //Data Event Logger event\n\tMDESourceFan = \"m.fa\" //FaNotify monitor event\n\tMDESourcePT  = \"m.pt\" //PTrace monitor event\n)\n\n// Event types\nconst (\n\tMDETypeArtifact = \"a\" //Artifact event type\n\tMDETypeProcess  = \"p\" //Process event type\n\tMDETypeState    = \"s\" //State event\n)\n\n// Operation types\nconst (\n\tOpTypeRead  = \"r\"\n\tOpTypeWrite = \"w\"\n\tOpTypeExec  = \"x\"\n\tOpTypeCheck = \"c\"\n)\n\ntype MonitorDataEvent struct {\n\tTimestamp int64  `json:\"ts\"`\n\tSeqNumber uint64 `json:\"sn\"`\n\tSource    string `json:\"s\"`\n\tType      string `json:\"t\"`\n\tPid       int32  `json:\"p,omitempty\"`\n\tParentPid int32  `json:\"pp,omitempty\"`\n\tArtifact  string `json:\"a,omitempty\"`  // used for exe path for process events\n\tOpType    string `json:\"o,omitempty\"`  // operation type\n\tOp        string `json:\"op,omitempty\"` // operation\n\tOpNum     uint32 `json:\"n,omitempty\"`\n\tWorkDir   string `json:\"w,omitempty\"`\n\tRoot      string `json:\"r,omitempty\"`\n\tCmd       string `json:\"c,omitempty\"`\n\tState     string `json:\"st,omitempty\"`\n}\n"
  },
  {
    "path": "pkg/report/report.go",
    "content": "package report\n\ntype DistroInfo struct {\n\tName        string `json:\"name\"`\n\tVersion     string `json:\"version\"`\n\tDisplayName string `json:\"display_name\"`\n}\n\n//copy from system.DistroInfo\n"
  },
  {
    "path": "pkg/sysenv/sysenv_darwin.go",
    "content": "package sysenv\n\nfunc HasDSImageFlag() bool {\n\treturn false\n}\n\nfunc InDSContainer() (bool, bool) {\n\treturn false, false\n}\n"
  },
  {
    "path": "pkg/sysenv/sysenv_linux.go",
    "content": "package sysenv\n\nimport (\n\t\"fmt\"\n\t\"golang.org/x/sys/unix\"\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/syndtr/gocapability/capability\"\n)\n\nconst (\n\tprocSelfCgroup  = \"/proc/self/cgroup\"\n\tdockerEnvPath   = \"/.dockerenv\"\n\tdsImageFlagPath = \"/.ds.container.d3e2c84f976743bdb92a7044ef12e381\"\n)\n\nfunc HasDSImageFlag() bool {\n\t_, err := os.Stat(dsImageFlagPath)\n\treturn err == nil\n}\n\nfunc HasDockerEnvPath() bool {\n\t_, err := os.Stat(dockerEnvPath)\n\treturn err == nil\n}\n\nfunc HasContainerCgroups() bool {\n\tif bdata, err := os.ReadFile(procSelfCgroup); err == nil {\n\t\treturn strings.Contains(string(bdata), \":/docker/\")\n\t}\n\n\treturn false\n}\n\nfunc InDSContainer() (bool, bool) {\n\tisDSImage := HasDSImageFlag()\n\tinContainer := InContainer()\n\n\treturn inContainer, isDSImage\n}\n\nfunc InContainer() bool {\n\tif HasDockerEnvPath() {\n\t\treturn true\n\t}\n\n\tif HasContainerCgroups() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc IsPrivileged() bool {\n\tmode, err := SeccompMode(0)\n\tif err != nil {\n\t\tfmt.Printf(\"sysenv.IsPrivileged: error - %v\\n\", err)\n\t\treturn false\n\t}\n\n\tif WithAllCapabilities() &&\n\t\tmode == SeccompMNDisabled {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc WithAllCapabilities() bool {\n\tcaps, err := capability.NewPid(0)\n\tif err != nil {\n\t\tfmt.Printf(\"sysenv.WithAllCapabilities: error - %v\\n\", err)\n\t\treturn false\n\t}\n\n\tif caps.Full(capability.PERMITTED) &&\n\t\tcaps.Full(capability.EFFECTIVE) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc Capabilities(pid int) (map[string]struct{}, map[string]struct{}, error) {\n\tcaps, err := capability.NewPid(pid)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tall := capability.List()\n\n\tactive := map[string]struct{}{}\n\tfor _, cap := range all {\n\t\tif caps.Get(capability.EFFECTIVE, cap) {\n\t\t\tactive[cap.String()] = struct{}{}\n\t\t}\n\t}\n\n\tmax := map[string]struct{}{}\n\tfor _, cap := range all {\n\t\tif caps.Get(capability.PERMITTED, cap) {\n\t\t\tmax[cap.String()] = struct{}{}\n\t\t}\n\t}\n\n\treturn active, max, nil\n}\n\nfunc IsDefaultCapSet(set map[string]struct{}) bool {\n\tif len(set) != len(DefaultCapStrings) {\n\t\treturn false\n\t}\n\n\tfor k := range set {\n\t\tif _, ok := DefaultCapStrings[k]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n//default Docker container capabilities: 14\n//https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities\n\nvar DefaultCapStrings = map[string]struct{}{\n\tcapability.CAP_SETPCAP.String():          {},\n\tcapability.CAP_MKNOD.String():            {},\n\tcapability.CAP_AUDIT_WRITE.String():      {},\n\tcapability.CAP_CHOWN.String():            {},\n\tcapability.CAP_NET_RAW.String():          {},\n\tcapability.CAP_DAC_OVERRIDE.String():     {},\n\tcapability.CAP_FOWNER.String():           {},\n\tcapability.CAP_FSETID.String():           {},\n\tcapability.CAP_KILL.String():             {},\n\tcapability.CAP_SETGID.String():           {},\n\tcapability.CAP_SETUID.String():           {},\n\tcapability.CAP_NET_BIND_SERVICE.String(): {},\n\tcapability.CAP_SYS_CHROOT.String():       {},\n\tcapability.CAP_SETFCAP.String():          {},\n}\n\nvar DefaultCapNums = map[capability.Cap]string{\n\tcapability.CAP_SETPCAP:          capability.CAP_SETPCAP.String(),\n\tcapability.CAP_MKNOD:            capability.CAP_MKNOD.String(),\n\tcapability.CAP_AUDIT_WRITE:      capability.CAP_AUDIT_WRITE.String(),\n\tcapability.CAP_CHOWN:            capability.CAP_CHOWN.String(),\n\tcapability.CAP_NET_RAW:          capability.CAP_NET_RAW.String(),\n\tcapability.CAP_DAC_OVERRIDE:     capability.CAP_DAC_OVERRIDE.String(),\n\tcapability.CAP_FOWNER:           capability.CAP_FOWNER.String(),\n\tcapability.CAP_FSETID:           capability.CAP_FSETID.String(),\n\tcapability.CAP_KILL:             capability.CAP_KILL.String(),\n\tcapability.CAP_SETGID:           capability.CAP_SETGID.String(),\n\tcapability.CAP_SETUID:           capability.CAP_SETUID.String(),\n\tcapability.CAP_NET_BIND_SERVICE: capability.CAP_NET_BIND_SERVICE.String(),\n\tcapability.CAP_SYS_CHROOT:       capability.CAP_SYS_CHROOT.String(),\n\tcapability.CAP_SETFCAP:          capability.CAP_SETFCAP.String(),\n}\n\ntype SeccompModeName string\n\nconst (\n\tSMDisabled        string          = \"0\"\n\tSeccompMNDisabled SeccompModeName = \"disabled\"\n\tSMStrict          string          = \"1\"\n\tSeccompMNStrict   SeccompModeName = \"strict\"\n\tSMFiltering       string          = \"2\"\n\tSeccompMFiltering SeccompModeName = \"filtering\"\n)\n\nvar seccompModes = map[string]SeccompModeName{\n\tSMDisabled:  SeccompMNDisabled,\n\tSMStrict:    SeccompMNStrict,\n\tSMFiltering: SeccompMFiltering,\n}\n\nconst procStatusPat = \"/proc/%s/status\"\n\nfunc SeccompMode(pid int) (SeccompModeName, error) {\n\tfname := procFileName(pid, \"status\")\n\tfdata, err := fileData(fname)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tmode := procSeccompMode(fdata)\n\tif mode != \"\" {\n\t\treturn mode, nil\n\t}\n\n\tmode = sysSeccompMode()\n\treturn mode, nil\n}\n\nfunc procSeccompMode(data string) SeccompModeName {\n\tmodeNum := procStatusField(data, \"Seccomp:\")\n\tif mode, ok := seccompModes[modeNum]; ok {\n\t\treturn mode\n\t}\n\n\treturn \"\"\n}\n\nconst procStatusFieldValueRegexStr = \":(.*)\"\n\nvar procStatusFieldValueMatcher = regexp.MustCompile(procStatusFieldValueRegexStr)\n\nfunc procStatusField(data, fname string) string {\n\tif !strings.HasSuffix(fname, \":\") {\n\t\tfname = fmt.Sprintf(\"%s:\", fname)\n\t}\n\n\tlines := strings.Split(data, \"\\n\")\n\tfor _, line := range lines {\n\t\tline := cleanLine(line)\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasPrefix(line, fname) {\n\t\t\tmatches := procStatusFieldValueMatcher.FindStringSubmatch(line)\n\t\t\tif len(matches) > 1 {\n\t\t\t\treturn strings.TrimSpace(matches[1])\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\nfunc cleanLine(line string) string {\n\treturn strings.TrimSpace(line)\n}\n\nfunc sysSeccompMode() SeccompModeName {\n\tif err := unix.Prctl(unix.PR_GET_SECCOMP, 0, 0, 0, 0); err != unix.EINVAL {\n\t\tif err := unix.Prctl(unix.PR_SET_SECCOMP, unix.SECCOMP_MODE_FILTER, 0, 0, 0); err != unix.EINVAL {\n\t\t\treturn SeccompMNStrict\n\t\t}\n\t}\n\n\treturn SeccompMNDisabled\n}\n\nfunc fileData(fname string) (string, error) {\n\tbdata, err := os.ReadFile(fname)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tdata := strings.TrimSpace(string(bdata))\n\treturn data, nil\n}\n\nfunc procFileName(pid int, name string) string {\n\ttarget := \"self\"\n\tif pid > 0 {\n\t\ttarget = fmt.Sprintf(\"%d\", pid)\n\t}\n\n\treturn fmt.Sprintf(\"/proc/%s/%s\", target, name)\n}\n"
  },
  {
    "path": "pkg/sysidentity/sysidentity.go",
    "content": "package sysidentity\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\nconst (\n\tPasswdFilePath    = \"/etc/passwd\"\n\tShadowFilePath    = \"/etc/shadow\"\n\tGshadowFilePath   = \"/etc/gshadow\"\n\tGroupFilePath     = \"/etc/group\"\n\tLoginDefsFilePath = \"/etc/login.defs\"\n\tSudoersFilePath   = \"/etc/sudoers\"\n\tAuthKeysFileName  = \"authorized_keys\"\n\n\t//todo: move to one of the runtime detection packages\n\tAuthLogFilePath = \"/var/log/auth.log\"\n)\n\nfunc IsSourceFile(fullPath string) bool {\n\tif IsAuthKeyFile(fullPath) {\n\t\treturn true\n\t}\n\n\tswitch fullPath {\n\tcase PasswdFilePath, ShadowFilePath, GroupFilePath:\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc IsAuthKeyFile(fullPath string) bool {\n\tif filepath.Base(fullPath) == AuthKeysFileName {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc NewDataSet() *DataSet {\n\tref := &DataSet{\n\t\tAuthKeysData: map[string][]byte{},\n\t}\n\n\treturn ref\n}\n\ntype DataSet struct {\n\tPasswdFilePath string\n\tPasswdData     []byte\n\tShadowFilePath string\n\tShadowData     []byte\n\tGroupFilePath  string\n\tGroupData      []byte\n\tAuthKeysData   map[string][]byte\n}\n\nfunc (ref *DataSet) AddData(filePath string, data []byte) bool {\n\tswitch filePath {\n\tcase PasswdFilePath:\n\t\tref.PasswdFilePath = filePath\n\t\tref.PasswdData = data\n\t\treturn true\n\tcase ShadowFilePath:\n\t\tref.ShadowFilePath = filePath\n\t\tref.ShadowData = data\n\t\treturn true\n\tcase GroupFilePath:\n\t\tref.GroupFilePath = filePath\n\t\tref.GroupData = data\n\t\treturn true\n\tdefault:\n\t\tif IsAuthKeyFile(filePath) {\n\t\t\tif ref.AuthKeysData == nil {\n\t\t\t\tref.AuthKeysData = map[string][]byte{}\n\t\t\t}\n\n\t\t\tref.AuthKeysData[filePath] = data\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc NewReportFromData(data *DataSet) (*Report, error) {\n\tpinfo, err := ReadPasswdData(data.PasswdData)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tsinfo, err := ReadShadowData(data.ShadowData)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tginfo, err := ReadGroupData(data.GroupData)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treport := Report{\n\t\tSources: []*DataSource{\n\t\t\t{FilePath: data.PasswdFilePath},\n\t\t\t{FilePath: data.ShadowFilePath},\n\t\t\t{FilePath: data.GroupFilePath},\n\t\t},\n\t\tUsers:  map[string]*UserInfo{},\n\t\tGroups: map[string]*GroupInfo{},\n\t}\n\n\tfor _, record := range pinfo.Records {\n\t\tuserInfo := &UserInfo{\n\t\t\tUsername:       record.Username,\n\t\t\tPasswdPassword: record.Password,\n\t\t\tUID:            record.UID,\n\t\t\tGID:            record.GID,\n\t\t\tExtraInfo:      record.Info,\n\t\t\tHome:           record.Home,\n\t\t\tShell:          record.Shell,\n\t\t\tNoLoginShell:   record.NoLoginShell,\n\t\t}\n\n\t\treport.Users[userInfo.Username] = userInfo\n\t}\n\n\tfor _, record := range sinfo.Records {\n\t\tuserInfo, found := report.Users[record.Username]\n\t\tif !found {\n\t\t\tuserInfo := &UserInfo{\n\t\t\t\tUsername: record.Username,\n\t\t\t}\n\n\t\t\treport.Users[record.Username] = userInfo\n\t\t}\n\n\t\tuserInfo.ShadowPassword = record.Password\n\t\tuserInfo.LastChangeRaw = record.LastChangeRaw\n\t\tuserInfo.LastChangeDate = record.LastChangeDate\n\t\tuserInfo.MinimumAge = record.MinimumAge\n\t\tuserInfo.MaximumAge = record.MaximumAge\n\t\tuserInfo.WarningPeriod = record.WarningPeriod\n\t\tuserInfo.InactiveDays = record.InactiveDays\n\t\tuserInfo.ExpirationRaw = record.ExpirationRaw\n\t\tuserInfo.ExpirationDate = record.ExpirationDate\n\n\t}\n\n\tfor _, record := range ginfo.Records {\n\t\tgroupInfo := &GroupInfo{\n\t\t\tName:     record.Group,\n\t\t\tID:       record.GID,\n\t\t\tMembers:  record.Members,\n\t\t\tPassword: record.Password, //todo: get the actual password infor from gshadow (if any)\n\t\t}\n\n\t\treport.Groups[groupInfo.Name] = groupInfo\n\t}\n\n\tfor fileName, data := range data.AuthKeysData {\n\t\t//tmp\n\t\tfmt.Printf(\"%s -> %v\\n\", fileName, data)\n\t}\n\n\treturn &report, nil\n}\n\ntype Report struct {\n\tUsers   map[string]*UserInfo  `json:\"users\"`\n\tGroups  map[string]*GroupInfo `json:\"groups\"`\n\tSources []*DataSource         `json:\"sources\"`\n}\n\ntype DataSource struct {\n\tFilePath string             `json:\"file_path\"`\n\tMetadata DataSourceMetadata `json:\"metadata\"`\n}\n\ntype DataSourceMetadata struct {\n\tSha1Hash string `json:\"sha1_hash,omitempty\"`\n\tFileSize int64  `json:\"file_size\"`\n\tModeText string `json:\"mode\"`\n\t//ModTime time.Time `json:\"mod_time,omitempty\"`\n\t//ChangeTime time.Time `json:\"change_time,omitempty\"`\n\t//CreateTime time.Time `json:\"create_time,omitempty\"`\n}\n\nfunc (ref *Report) StringJSONPretty() string {\n\tvar out bytes.Buffer\n\tencoder := json.NewEncoder(&out)\n\tencoder.SetEscapeHTML(false)\n\tencoder.SetIndent(\" \", \" \")\n\t_ = encoder.Encode(ref)\n\treturn out.String()\n}\n\ntype GroupInfo struct {\n\tName     string   `json:\"name\"`\n\tID       int      `json:\"id\"`\n\tMembers  []string `json:\"members\"`\n\tPassword string   `json:\"password,omitempty\"`\n}\n\ntype UserInfo struct {\n\tUsername       string       `json:\"username\"`\n\tPasswdPassword string       `json:\"passwd_password\"`\n\tShadowPassword PasswordHash `json:\"shadow_password\"`\n\tUID            int          `json:\"uid\"`\n\tGID            int          `json:\"gid\"`\n\tExtraInfo      string       `json:\"extra_info\"`\n\tHome           string       `json:\"home\"`\n\tShell          string       `json:\"shell\"`\n\tNoLoginShell   bool         `json:\"no_login_shell\"`\n\n\tLastChangeRaw  int       `json:\"last_change_raw\"`\n\tLastChangeDate time.Time `json:\"last_change_date\"`\n\tMinimumAge     int       `json:\"minimum_age\"`\n\tMaximumAge     int       `json:\"maximum_age\"`\n\tWarningPeriod  int       `json:\"warning_period\"`\n\tInactiveDays   int       `json:\"inactive_days\"`\n\tExpirationRaw  int       `json:\"expiration_raw\"`\n\tExpirationDate time.Time `json:\"expiration_date\"`\n\n\tSshKeys []*SshKeyRecord `json:\"ssh_keys,omitempty\"`\n}\n\ntype AuthorizedKeysFileInfo struct {\n\tRecords []SshKeyRecord `json:\"records\"`\n}\n\ntype SshKeyRecord struct {\n\tKeyType      string   `json:\"key_type\"`\n\tKey          string   `json:\"key\"` //base64 encoded\n\tComment      string   `json:\"comment\"`\n\tCommand      string   `json:\"command,omitempty\"`\n\tEnvironments []string `json:\"environments,omitempty\"`\n\tOtherOptions []string `json:\"other_options,omitempty\"`\n\tRawData      string   `json:\"raw_data\"`\n\tFilePath     string   `json:\"file_path\"`\n}\n\n/*\n\"golang.org/x/crypto/ssh\"\nfunc ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error)\nssh.ParseAuthorizedKey([]byte(foreverUserCertString))\n*/\n\n//Raw data structs\n\ntype PasswdFileInfo struct {\n\tRecords []PasswdRecord `json:\"records\"`\n}\n\ntype PasswdRecord struct {\n\tUsername     string `json:\"username\"`\n\tPassword     string `json:\"password\"` //password hash, \"x\" if the actual password hash is in the shadow file\n\tUID          int    `json:\"uid\"`\n\tGID          int    `json:\"gid\"`\n\tInfo         string `json:\"info\"`  //additional user identity info / GECOS\n\tHome         string `json:\"home\"`  //home directory\n\tShell        string `json:\"shell\"` //shell exected when user logs in\n\tRawData      string `json:\"raw_data\"`\n\tNoLoginShell bool   `json:\"no_login_shell\"`\n}\n\nfunc ReadPasswdFile(filePath string) (*PasswdFileInfo, error) {\n\t//todo: have an option to skip bad records\n\tdata, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ReadPasswdData(data)\n}\n\nfunc ReadPasswdData(data []byte) (*PasswdFileInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(data))\n\n\tvar info PasswdFileInfo\n\tfor scanner.Scan() {\n\t\trecord, err := ParsePasswdRecord(scanner.Text())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tinfo.Records = append(info.Records, record)\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &info, nil\n}\n\nfunc ParsePasswdRecord(line string) (PasswdRecord, error) {\n\tline = strings.TrimSpace(line)\n\trecord := PasswdRecord{\n\t\tRawData: line,\n\t}\n\n\tparts := strings.Split(line, \":\")\n\tif len(parts) != 7 {\n\t\treturn record, errors.New(\"unexpected field count\")\n\t}\n\n\trecord.Username = parts[0]\n\trecord.Password = parts[1]\n\trecord.Info = parts[4]\n\trecord.Home = parts[5]\n\trecord.Shell = strings.TrimSpace(parts[6])\n\n\tif _, found := NoLoginShells[record.Shell]; found {\n\t\trecord.NoLoginShell = true\n\t}\n\n\tvar err error\n\trecord.UID, err = strconv.Atoi(parts[2])\n\tif err != nil {\n\t\treturn record, fmt.Errorf(\"error parsing UID field - %s (%v)\", parts[2], err)\n\t}\n\n\trecord.GID, err = strconv.Atoi(parts[3])\n\tif err != nil {\n\t\treturn record, fmt.Errorf(\"error parsing GID field - %s (%v)\", parts[3], err)\n\t}\n\n\treturn record, nil\n}\n\nconst (\n\tHasShadowFileRecord = \"x\"\n)\n\nfunc (ref PasswdRecord) UsesShadow() bool {\n\tif ref.Password == HasShadowFileRecord {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nvar NoLoginShells = map[string]struct{}{\n\t\"/sbin/nologin\":     {},\n\t\"/usr/sbin/nologin\": {},\n\t\"/bin/false\":        {},\n}\n\nconst (\n\tHashTypeDES          = \"\" //yes, it's empty\n\tHashTypeMD5          = \"1\"\n\tHashTypeBlowfish     = \"2a\"\n\tHashTypeBcrypt       = \"2b\"\n\tHashTypeEksblowfish  = \"2y\"\n\tHashTypeSHA256       = \"5\"\n\tHashTypeSHA512       = \"6\"\n\tHashTypeYescrypt     = \"y\"\n\tHashTypeGostYescrypt = \"gy\"\n\tHashTypeScrypt       = \"7\"\n)\n\nvar HashTypes = map[string]string{\n\tHashTypeDES:          \"DES\",\n\tHashTypeMD5:          \"MD5\",\n\tHashTypeBlowfish:     \"blowfish\",\n\tHashTypeBcrypt:       \"bcrypt\",\n\tHashTypeEksblowfish:  \"eksblowfish\",\n\tHashTypeSHA256:       \"SHA256\",\n\tHashTypeSHA512:       \"SHA512\",\n\tHashTypeYescrypt:     \"yescrypt\",\n\tHashTypeGostYescrypt: \"gost-yescrypt\",\n\tHashTypeScrypt:       \"scrypt\",\n}\n\nconst (\n\tNoPasswordLoginUser    = \"!\"\n\tNoPasswordLoginService = \"*\"\n)\n\nfunc NewPasswordHash(data string) PasswordHash {\n\tvar out PasswordHash\n\n\tswitch data {\n\tcase NoPasswordLoginUser, NoPasswordLoginService:\n\t\tout.NoPasswordLogin = true\n\t\treturn out\n\t}\n\n\tparts := strings.Split(data, \"$\")\n\n\tif len(parts) < 4 {\n\t\treturn out\n\t}\n\n\tout.AlgoTypeRaw = parts[1]\n\tout.Salt = parts[len(parts)-2]\n\tout.Hash = parts[len(parts)-1]\n\n\tout.AlgoType = AlgoNameFromType(out.AlgoTypeRaw)\n\n\tif len(parts) > 4 {\n\t\tout.AlgoParam = parts[2]\n\t}\n\n\treturn out\n}\n\nfunc AlgoNameFromType(data string) string {\n\tname, found := HashTypes[data]\n\tif found {\n\t\treturn name\n\t}\n\n\treturn \"other\"\n}\n\ntype PasswordHash struct {\n\tAlgoTypeRaw     string `json:\"algo_type_raw,omitempty\"`\n\tAlgoType        string `json:\"algo_type,omitempty\"`\n\tAlgoParam       string `json:\"algo_param,omitempty\"` //encoded (need to decode)\n\tSalt            string `json:\"salt,omitempty\"`\n\tHash            string `json:\"hash,omitempty\"`\n\tNoPasswordLogin bool   `json:\"no_password_login\"`\n}\n\nfunc (ref PasswordHash) UsesWeakAlgo() bool {\n\tswitch ref.AlgoTypeRaw {\n\tcase HashTypeDES, HashTypeMD5:\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc (ref ShadowRecord) LoginWithoutPassword() bool {\n\tif ref.PasswordRaw == \"\" {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\ntype ShadowFileInfo struct {\n\tRecords []ShadowRecord `json:\"records\"`\n}\n\nconst FieldNotSet = -1\n\ntype ShadowRecord struct {\n\tUsername       string\n\tPasswordRaw    string\n\tPassword       PasswordHash\n\tLastChangeRaw  int\n\tLastChangeDate time.Time\n\tMinimumAge     int\n\tMaximumAge     int\n\tWarningPeriod  int\n\tInactiveDays   int\n\tExpirationRaw  int\n\tExpirationDate time.Time\n\tReserved       string\n\tRawData        string\n}\n\nfunc ReadShadowFile(filePath string) (*ShadowFileInfo, error) {\n\t//todo: have an option to skip bad records\n\tdata, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ReadShadowData(data)\n}\n\nfunc ReadShadowData(data []byte) (*ShadowFileInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(data))\n\n\tvar info ShadowFileInfo\n\tfor scanner.Scan() {\n\t\trecord, err := ParseShadowRecord(scanner.Text())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tinfo.Records = append(info.Records, record)\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &info, nil\n}\n\nfunc ParseShadowRecord(line string) (ShadowRecord, error) {\n\tline = strings.TrimSpace(line)\n\trecord := ShadowRecord{\n\t\tRawData: line,\n\t}\n\n\tparts := strings.Split(line, \":\")\n\tif len(parts) != 9 {\n\t\treturn record, errors.New(\"unexpected field count\")\n\t}\n\n\trecord.Username = parts[0]\n\trecord.PasswordRaw = parts[1]\n\trecord.Reserved = parts[8]\n\n\tintFields := [...]*int{\n\t\t&record.LastChangeRaw,\n\t\t&record.MinimumAge,\n\t\t&record.MaximumAge,\n\t\t&record.WarningPeriod,\n\t\t&record.InactiveDays,\n\t\t&record.ExpirationRaw,\n\t}\n\n\tfor idx, val := range intFields {\n\t\tfield := parts[idx+2]\n\t\tif field == \"\" {\n\t\t\t*val = FieldNotSet\n\t\t} else {\n\t\t\tvar err error\n\t\t\t*val, err = strconv.Atoi(field)\n\t\t\tif err != nil {\n\t\t\t\treturn record, fmt.Errorf(\"error parsing field - %s (%v)\", field, err)\n\t\t\t}\n\t\t}\n\t}\n\n\trecord.Password = NewPasswordHash(record.PasswordRaw)\n\tvar err error\n\trecord.LastChangeDate, err = daysToDate(record.LastChangeRaw)\n\tif err != nil {\n\t\treturn record, err\n\t}\n\n\trecord.ExpirationDate, err = daysToDate(record.ExpirationRaw)\n\tif err != nil {\n\t\treturn record, err\n\t}\n\n\treturn record, nil\n}\n\nfunc daysToDate(days int) (time.Time, error) {\n\tif days == FieldNotSet {\n\t\treturn time.Time{}, nil\n\t}\n\n\treturn time.Date(1970, 0, 0, 0, 0, 0, 0, time.UTC).AddDate(0, 0, days), nil\n}\n\n////////////\n\ntype GroupRecord struct {\n\tGroup      string   `json:\"gid\"`      //group name\n\tPassword   string   `json:\"password\"` //password hash, usually empty / unused (actual password hashes are in gshadow)\n\tGID        int      `json:\"gid\"`\n\tMembersRaw string   `json:\"members_raw\"`\n\tMembers    []string `json:\"members\"`\n\tRawData    string   `json:\"raw_data\"`\n}\n\ntype GroupFileInfo struct {\n\tRecords []GroupRecord `json:\"records\"`\n}\n\nfunc ReadGroupFile(filePath string) (*GroupFileInfo, error) {\n\t//todo: have an option to skip bad records\n\tdata, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ReadGroupData(data)\n}\n\nfunc ReadGroupData(data []byte) (*GroupFileInfo, error) {\n\tscanner := bufio.NewScanner(bytes.NewReader(data))\n\n\tvar info GroupFileInfo\n\tfor scanner.Scan() {\n\t\trecord, err := ParseGroupRecord(scanner.Text())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tinfo.Records = append(info.Records, record)\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &info, nil\n}\n\nfunc ParseGroupRecord(line string) (GroupRecord, error) {\n\tline = strings.TrimSpace(line)\n\trecord := GroupRecord{\n\t\tRawData: line,\n\t}\n\n\tparts := strings.Split(line, \":\")\n\tif len(parts) != 4 {\n\t\treturn record, errors.New(\"unexpected field count\")\n\t}\n\n\trecord.Group = parts[0]\n\trecord.Password = parts[1]\n\trecord.MembersRaw = parts[3]\n\tif record.MembersRaw != \"\" {\n\t\trecord.Members = strings.Split(record.MembersRaw, \",\")\n\t}\n\n\tvar err error\n\trecord.GID, err = strconv.Atoi(parts[2])\n\tif err != nil {\n\t\treturn record, fmt.Errorf(\"error parsing GID field - %s (%v)\", parts[2], err)\n\t}\n\n\treturn record, nil\n}\n"
  },
  {
    "path": "pkg/system/architecture.go",
    "content": "package system\n\ntype ArchName string\n\nconst (\n\tArchNameUnknown     ArchName = \"unknown\"\n\tArchNameUnsupported ArchName = \"unsupported\"\n\tArchName386         ArchName = \"386\"\n\tArchNameAmd64       ArchName = \"amd64\"\n\tArchNameArm32       ArchName = \"armhf\"\n\tArchNameArm64       ArchName = \"aarch64\"\n)\n\ntype MachineName string\n\nconst (\n\tMachineNameNamei386   MachineName = \"i386\"\n\tMachineNameNamei586   MachineName = \"i586\"\n\tMachineNameNamei686   MachineName = \"i686\"\n\tMachineNameNamex86_64 MachineName = \"x86_64\"\n\tMachineNameNameArm    MachineName = \"armv7l\"\n\tMachineNameNameArm64  MachineName = \"aarch64\"\n)\n\ntype ArchBits uint8\n\nconst (\n\tArchBits32 ArchBits = 32\n\tArchBits64 ArchBits = 64\n)\n\ntype ArchFamily string\n\nconst (\n\tArchFamilyX86   ArchFamily = \"x86\"\n\tArchFamilyArm   ArchFamily = \"arm\"\n\tArchFamilyArm64 ArchFamily = \"arm64\"\n)\n\ntype ArchInfo struct {\n\tName   ArchName\n\tFamily ArchFamily\n\tBits   ArchBits\n}\n\nvar x86Family64Arch = ArchInfo{\n\tName:   ArchNameAmd64,\n\tFamily: ArchFamilyX86,\n\tBits:   ArchBits64,\n}\n\nvar x86Family32Arch = ArchInfo{\n\tName:   ArchName386,\n\tFamily: ArchFamilyX86,\n\tBits:   ArchBits32,\n}\n\nvar ArmFamily32Arch = ArchInfo{\n\tName:   ArchNameArm32,\n\tFamily: ArchFamilyArm,\n\tBits:   ArchBits32,\n}\n\nvar ArmFamily64Arch = ArchInfo{\n\tName:   ArchNameArm64,\n\tFamily: ArchFamilyArm,\n\tBits:   ArchBits64,\n}\n\nvar unsupportedArch = ArchInfo{\n\tName: ArchNameUnsupported,\n}\n\nvar unknownArch = ArchInfo{\n\tName: ArchNameUnknown,\n}\n\nvar archMap = map[MachineName]*ArchInfo{\n\tMachineNameNamei386:   &x86Family32Arch,\n\tMachineNameNamei586:   &x86Family32Arch,\n\tMachineNameNamei686:   &x86Family32Arch,\n\tMachineNameNamex86_64: &x86Family64Arch,\n\tMachineNameNameArm:    &ArmFamily32Arch,\n\tMachineNameNameArm64:  &ArmFamily64Arch,\n}\n\nfunc MachineToArchName(mtype string) ArchName {\n\tif archInfo, ok := archMap[MachineName(mtype)]; ok {\n\t\treturn archInfo.Name\n\t}\n\n\treturn ArchNameUnknown\n}\n\nfunc MachineToArch(mtype string) *ArchInfo {\n\tif archInfo, ok := archMap[MachineName(mtype)]; ok {\n\t\treturn archInfo\n\t}\n\n\treturn &unknownArch\n}\n"
  },
  {
    "path": "pkg/system/errors.go",
    "content": "package system\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\tErrNotConfigured    = errors.New(\"feature is not configured\")\n\tErrNoConfigs        = errors.New(\"no kernel configs\")\n\tErrArchNotSupported = errors.New(\"unsupported architecture\")\n)\n"
  },
  {
    "path": "pkg/system/kernel_linux.go",
    "content": "package system\n\nimport (\n\t\"bufio\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\ntype KernelFeatures struct {\n\tRaw   map[string]string\n\tError string\n}\n\nfunc (p *KernelFeatures) IsConfigured(name string) bool {\n\tif _, ok := p.Raw[name]; ok {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc (p *KernelFeatures) RawValue(name string) (string, error) {\n\tif val, ok := p.Raw[name]; ok {\n\t\treturn val, nil\n\t}\n\n\treturn \"\", ErrNotConfigured\n}\n\nfunc (p *KernelFeatures) IsFlag(name string) (bool, error) {\n\tif val, ok := p.Raw[name]; ok {\n\t\tif (val == \"y\") || (val == \"m\") {\n\t\t\treturn true, nil\n\t\t}\n\n\t\treturn false, nil\n\t}\n\n\treturn false, ErrNotConfigured\n}\n\nfunc (p *KernelFeatures) isFlagSet(name string, flag string) (bool, error) {\n\tif val, ok := p.Raw[name]; ok {\n\t\tif val == flag {\n\t\t\treturn true, nil\n\t\t}\n\n\t\treturn false, nil\n\t}\n\n\treturn false, ErrNotConfigured\n}\n\nfunc (p *KernelFeatures) IsCompiled(name string) (bool, error) {\n\treturn p.isFlagSet(name, \"y\")\n}\n\nfunc (p *KernelFeatures) IsLoadable(name string) (bool, error) {\n\treturn p.isFlagSet(name, \"m\")\n}\n\nfunc NewKernelFeatures() (KernelFeatures, error) {\n\treturn NewKernelFeaturesWithProps(\"\")\n}\n\nfunc NewKernelFeaturesWithProps(location string) (KernelFeatures, error) {\n\tvar kfeatures KernelFeatures\n\n\tif location == \"\" {\n\t\tbootConfigWithVersion := fmt.Sprintf(\"/boot/config-%s\", defaultSysInfo.Machine)\n\t\tkernelConfigLocations := []string{\n\t\t\t\"/proc/config.gz\",\n\t\t\t\"/boot/config\",\n\t\t}\n\n\t\tkernelConfigLocations = append(kernelConfigLocations, bootConfigWithVersion)\n\n\t\tlocation = findKernelConfigs(kernelConfigLocations)\n\t\tif location == \"\" {\n\t\t\tkfeatures.Error = ErrNoConfigs.Error()\n\t\t\treturn kfeatures, ErrNoConfigs\n\t\t}\n\t} else {\n\t\tif !fileExists(location) {\n\t\t\tkfeatures.Error = os.ErrNotExist.Error()\n\t\t\treturn kfeatures, os.ErrNotExist\n\t\t}\n\t}\n\n\trawFeatures, err := readKernelFeatures(location)\n\tif err != nil {\n\t\tkfeatures.Error = err.Error()\n\t\treturn kfeatures, err\n\t}\n\n\tkfeatures.Raw = rawFeatures\n\n\treturn kfeatures, nil\n}\n\nvar DefaultKernelFeatures, _ = NewKernelFeatures()\n\nfunc findKernelConfigs(locations []string) string {\n\tfor _, loc := range locations {\n\t\tif fileExists(loc) {\n\t\t\treturn loc\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\nfunc fileExists(filePath string) bool {\n\tfileInfo, err := os.Stat(filePath)\n\tif err == nil && (fileInfo.Mode().IsRegular()) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc readKernelFeatures(filename string) (map[string]string, error) {\n\tfreader, err := os.Open(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer freader.Close()\n\n\tareader, err := gzip.NewReader(freader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer areader.Close()\n\n\tvar lines []string\n\n\tscanner := bufio.NewScanner(areader)\n\tkernelFeatures := map[string]string{}\n\tfor scanner.Scan() {\n\t\tline := strings.TrimSpace(scanner.Text())\n\t\tif line == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif line[0] == '#' {\n\t\t\t//todo: extract section metadata from comments\n\t\t\tcontinue\n\t\t}\n\n\t\tlineParts := strings.Split(line, \"=\")\n\t\tif len(lineParts) == 2 {\n\t\t\tflagKey := strings.TrimSpace(lineParts[0])\n\t\t\tflagValue := strings.TrimSpace(lineParts[1])\n\t\t\tflagValue = strings.Trim(flagValue, \"\\\"\")\n\n\t\t\tlines = append(lines, line)\n\t\t\tkernelFeatures[flagKey] = flagValue\n\t\t}\n\t}\n\n\tif err = scanner.Err(); err != nil {\n\t\t//if err == bufio.ErrTooLong {\n\t\t//\tlog.Println(\"line length error:\", err)\n\t\t//} else {\n\t\t//\tlog.Println(\"other scanner error:\", err)\n\t\t//}\n\t\treturn kernelFeatures, err\n\t}\n\n\treturn kernelFeatures, nil\n}\n"
  },
  {
    "path": "pkg/system/nstring_int8.go",
    "content": "//go:build (linux && 386) || (linux && amd64) || (linux && arm64)\n// +build linux,386 linux,amd64 linux,arm64\n\npackage system\n\nfunc nativeCharsToString(cstr [65]int8) string {\n\tmax := len(cstr)\n\tdata := make([]byte, max)\n\n\tvar pos int\n\tfor ; (pos < max) && (cstr[pos] != 0); pos++ {\n\t\tdata[pos] = byte(cstr[pos])\n\t}\n\n\treturn string(data[0:pos])\n}\n"
  },
  {
    "path": "pkg/system/nstring_uint8.go",
    "content": "//go:build (linux && arm) || (linux && ppc64) || (linux && ppc64le) || s390x\n// +build linux,arm linux,ppc64 linux,ppc64le s390x\n\npackage system\n\nfunc nativeCharsToString(cstr [65]uint8) string {\n\tmax := len(cstr)\n\tdata := make([]byte, max)\n\n\tvar pos int\n\tfor ; (pos < max) && (cstr[pos] != 0); pos++ {\n\t\tdata[pos] = cstr[pos]\n\t}\n\n\treturn string(data[0:pos])\n}\n"
  },
  {
    "path": "pkg/system/os_release.go",
    "content": "package system\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"log\"\n)\n\nconst (\n\tOSReleaseFile    = \"/etc/os-release\"\n\tOSReleaseFileNew = \"/usr/lib/os-release\"\n\tLSBReleaseFile   = \"/etc/lsb-release\"\n\tIssueFile        = \"/etc/issue\"\n\tIssueNetFile     = \"/etc/issue.net\"\n)\n\nfunc IsOSReleaseFile(name string) bool {\n\tswitch name {\n\tcase OSReleaseFile, OSReleaseFileNew:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n//NOTE:\n//copied from https://github.com/docker/machine/blob/master/libmachine/provision/os_release.go\n\n// The /etc/os-release file contains operating system identification data\n// See http://www.freedesktop.org/software/systemd/man/os-release.html for more details\n\n// OsRelease reflects values in /etc/os-release\n// Values in this struct must always be string\n// or the reflection will not work properly.\ntype OsRelease struct {\n\tAnsiColor    string `osr:\"ANSI_COLOR\"`\n\tName         string `osr:\"NAME\"`\n\tVersion      string `osr:\"VERSION\"`\n\tVariant      string `osr:\"VARIANT\"`\n\tVariantID    string `osr:\"VARIANT_ID\"`\n\tID           string `osr:\"ID\"`\n\tIDLike       string `osr:\"ID_LIKE\"`\n\tPrettyName   string `osr:\"PRETTY_NAME\"`\n\tVersionID    string `osr:\"VERSION_ID\"`\n\tHomeURL      string `osr:\"HOME_URL\"`\n\tSupportURL   string `osr:\"SUPPORT_URL\"`\n\tBugReportURL string `osr:\"BUG_REPORT_URL\"`\n}\n\nfunc stripQuotes(val string) string {\n\tif len(val) > 0 && val[0] == '\"' {\n\t\treturn val[1 : len(val)-1]\n\t}\n\treturn val\n}\n\nfunc (osr *OsRelease) setIfPossible(key, val string) error {\n\tv := reflect.ValueOf(osr).Elem()\n\tfor i := 0; i < v.NumField(); i++ {\n\t\tfieldValue := v.Field(i)\n\t\tfieldType := v.Type().Field(i)\n\t\toriginalName := fieldType.Tag.Get(\"osr\")\n\t\tif key == originalName && fieldValue.Kind() == reflect.String {\n\t\t\tfieldValue.SetString(val)\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn fmt.Errorf(\"Couldn't set key %s, no corresponding struct field found\", key)\n}\n\nfunc parseLine(osrLine string) (string, string, error) {\n\tif osrLine == \"\" {\n\t\treturn \"\", \"\", nil\n\t}\n\n\tvals := strings.Split(osrLine, \"=\")\n\tif len(vals) != 2 {\n\t\treturn \"\", \"\", fmt.Errorf(\"Expected %s to split by '=' char into two strings, instead got %d strings\", osrLine, len(vals))\n\t}\n\tkey := vals[0]\n\tval := stripQuotes(vals[1])\n\treturn key, val, nil\n}\n\nfunc (osr *OsRelease) ParseOsRelease(osReleaseContents []byte) error {\n\tr := bytes.NewReader(osReleaseContents)\n\tscanner := bufio.NewScanner(r)\n\tfor scanner.Scan() {\n\t\tkey, val, err := parseLine(scanner.Text())\n\t\tif err != nil {\n\t\t\tlog.Printf(\"Warning: got an invalid line error parsing /etc/os-release: %s\", err)\n\t\t\tcontinue\n\t\t}\n\t\tif err := osr.setIfPossible(key, val); err != nil {\n\t\t\t//log.Printf(\"Info: %s\\n\",err)\n\t\t\t//note: ignore, printing these messages causes more confusion...\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc NewOsRelease(contents []byte) (*OsRelease, error) {\n\tosr := &OsRelease{}\n\tif err := osr.ParseOsRelease(contents); err != nil {\n\t\treturn nil, err\n\t}\n\treturn osr, nil\n}\n\n//TODO: Add LSB Release and Issue file parsers\n\n/*\ncat /etc/os-release\n\nNAME=\"Ubuntu\"\nVERSION=\"14.04.5 LTS, Trusty Tahr\"\nID=ubuntu\nID_LIKE=debian\nPRETTY_NAME=\"Ubuntu 14.04.5 LTS\"\nVERSION_ID=\"14.04\"\nHOME_URL=\"http://www.ubuntu.com/\"\nSUPPORT_URL=\"http://help.ubuntu.com/\"\nBUG_REPORT_URL=\"http://bugs.launchpad.net/ubuntu/\"\n\ncat /etc/os-release\n\nNAME=\"Alpine Linux\"\nID=alpine\nVERSION_ID=3.5.2\nPRETTY_NAME=\"Alpine Linux v3.5\"\nHOME_URL=\"http://alpinelinux.org\"\nBUG_REPORT_URL=\"http://bugs.alpinelinux.org\"\n\n\ncat /etc/os-release\n\nNAME=\"CentOS Linux\"\nVERSION=\"7 (Core)\"\nID=\"centos\"\nID_LIKE=\"rhel fedora\"\nVERSION_ID=\"7\"\nPRETTY_NAME=\"CentOS Linux 7 (Core)\"\nANSI_COLOR=\"0;31\"\nCPE_NAME=\"cpe:/o:centos:centos:7\"\nHOME_URL=\"https://www.centos.org/\"\nBUG_REPORT_URL=\"https://bugs.centos.org/\"\nCENTOS_MANTISBT_PROJECT=\"CentOS-7\"\nCENTOS_MANTISBT_PROJECT_VERSION=\"7\"\nREDHAT_SUPPORT_PRODUCT=\"centos\"\nREDHAT_SUPPORT_PRODUCT_VERSION=\"7\"\n\ncat /etc/os-release\n\nPRETTY_NAME=\"Debian GNU/Linux 9 (stretch)\"\nNAME=\"Debian GNU/Linux\"\nVERSION_ID=\"9\"\nVERSION=\"9 (stretch)\"\nID=debian\nHOME_URL=\"https://www.debian.org/\"\nSUPPORT_URL=\"https://www.debian.org/support\"\nBUG_REPORT_URL=\"https://bugs.debian.org/\"\n*/\n"
  },
  {
    "path": "pkg/system/os_shells.go",
    "content": "package system\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nconst (\n\tOSShellsFile = \"/etc/shells\"\n)\n\n// Common linux shell exe paths\nconst (\n\tOSShellAshExePath    = \"/bin/ash\"\n\tOSShellBourneExePath = \"/bin/sh\"\n\tOSShellKornExePath   = \"/bin/ksh93\"\n\t//usually a link to /bin/ksh93\n\tOSShellRestrictedKornExePath = \"/bin/rksh93\"\n\t//usually a link to /etc/alternatives/ksh\n\t//which links to /bin/ksh93\n\tOSShellKorn2ExePath = \"/bin/ksh\"\n\tOSShellBashExePath  = \"/bin/bash\"\n\t//usually a link to /bin/bash\n\tOSShellRestrictedBashExePath = \"/bin/rbash\"\n\tOSShellDashExePath           = \"/bin/dash\"\n\tOSShellZExePath              = \"/bin/zsh\"\n\t//usually a link to /bin/zsh\n\tOSShellZ2ExePath       = \"/usr/bin/zsh\"\n\tOSShellCExePath        = \"/bin/csh\"\n\tOSShellTCExePath       = \"/bin/tcsh\"\n\tOSShellFishExePath     = \"/usr/bin/fish\"\n\tOSShellElvishExePath   = \"/usr/bin/elvish\"\n\tOSShellXonshExePath    = \"/usr/bin/xonsh\"\n\tOSShellYashExePath     = \"/usr/bin/yash\"\n\tOSShellGitShellExePath = \"/usr/bin/git-shell\"\n\tOSShellScreenExePath   = \"/usr/bin/screen\"\n\tOSShellTmuxExePath     = \"/usr/bin/tmux\"\n)\n\nvar OSShellReferences = map[string]string{\n\tOSShellBourneExePath:         OSShellBourneExePath,\n\tOSShellKornExePath:           OSShellKornExePath,\n\tOSShellKorn2ExePath:          OSShellKornExePath,\n\tOSShellRestrictedKornExePath: OSShellKornExePath,\n\tOSShellBashExePath:           OSShellBashExePath,\n\tOSShellRestrictedBashExePath: OSShellBashExePath,\n\tOSShellDashExePath:           OSShellDashExePath,\n\tOSShellZExePath:              OSShellZExePath,\n\tOSShellZ2ExePath:             OSShellZExePath,\n\tOSShellCExePath:              OSShellCExePath,\n\tOSShellTCExePath:             OSShellTCExePath,\n\tOSShellFishExePath:           OSShellFishExePath,\n\tOSShellElvishExePath:         OSShellElvishExePath,\n\tOSShellXonshExePath:          OSShellXonshExePath,\n\tOSShellYashExePath:           OSShellYashExePath,\n\tOSShellAshExePath:            OSShellAshExePath,\n\tOSShellGitShellExePath:       OSShellGitShellExePath,\n\tOSShellScreenExePath:         OSShellScreenExePath,\n\tOSShellTmuxExePath:           OSShellTmuxExePath,\n}\n\nvar OSShells = map[string]OSShell{\n\tOSShellBourneExePath: {\n\t\tFullName:  \"Bourne shell\",\n\t\tShortName: \"sh\",\n\t\tExePath:   OSShellBourneExePath,\n\t},\n\tOSShellKornExePath: {\n\t\tFullName:  \"Korn shell\",\n\t\tShortName: \"ksh\",\n\t\tExePath:   OSShellKornExePath,\n\t},\n\tOSShellBashExePath: {\n\t\tFullName:  \"Bash shell\",\n\t\tShortName: \"bash\",\n\t\tExePath:   OSShellBashExePath,\n\t},\n\tOSShellDashExePath: {\n\t\tFullName:  \"Dash shell\",\n\t\tShortName: \"dash\",\n\t\tExePath:   OSShellDashExePath,\n\t},\n\tOSShellZExePath: {\n\t\tFullName:  \"Z shell\",\n\t\tShortName: \"zsh\",\n\t\tExePath:   OSShellZExePath,\n\t},\n\tOSShellCExePath: {\n\t\tFullName:  \"C shell\",\n\t\tShortName: \"csh\",\n\t\tExePath:   OSShellCExePath,\n\t},\n\tOSShellTCExePath: {\n\t\tFullName:  \"TC shell\",\n\t\tShortName: \"tcsh\",\n\t\tExePath:   OSShellTCExePath,\n\t},\n\tOSShellFishExePath: {\n\t\tFullName:  \"Fish shell\",\n\t\tShortName: \"fish\",\n\t\tExePath:   OSShellFishExePath,\n\t},\n\tOSShellElvishExePath: {\n\t\tFullName:  \"Elvish shell\",\n\t\tShortName: \"elvish\",\n\t\tExePath:   OSShellElvishExePath,\n\t},\n\tOSShellXonshExePath: {\n\t\tFullName:  \"Xonsh shell\",\n\t\tShortName: \"xonsh\",\n\t\tExePath:   OSShellXonshExePath,\n\t},\n\tOSShellYashExePath: {\n\t\tFullName:  \"Yash shell\",\n\t\tShortName: \"yash\",\n\t\tExePath:   OSShellYashExePath,\n\t},\n\tOSShellAshExePath: {\n\t\tFullName:  \"Ash shell\",\n\t\tShortName: \"ash\",\n\t\tExePath:   OSShellAshExePath,\n\t},\n\t//Restricted login shell for Git-only SSH access\n\t//installed with git\n\tOSShellGitShellExePath: {\n\t\tFullName:  \"Git shell\",\n\t\tShortName: \"git-shell\",\n\t\tExePath:   OSShellGitShellExePath,\n\t},\n\tOSShellScreenExePath: {\n\t\tFullName:  \"Screen\",\n\t\tShortName: \"screen\",\n\t\tExePath:   OSShellScreenExePath,\n\t},\n\tOSShellTmuxExePath: {\n\t\tFullName:  \"Tmux\",\n\t\tShortName: \"tmux\",\n\t\tExePath:   OSShellTmuxExePath,\n\t},\n}\n\ntype OSShell struct {\n\tFullName  string `json:\"full_name\"`\n\tShortName string `json:\"short_name,omitempty\"`\n\tExePath   string `json:\"exe_path\"`\n\tLinkPath  string `json:\"link_path,omitempty\"`\n\tReference string `json:\"reference,omitempty\"`\n\tVerified  bool   `json:\"verified,omitempty\"`\n}\n\nfunc IsOSShellsFile(name string) bool {\n\tif name == OSShellsFile {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc IsShellExePath(name string) bool {\n\t_, found := OSShellReferences[name]\n\tif found {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc LookupShellByExePath(name string) *OSShell {\n\tmainPath, found := OSShellReferences[name]\n\tif !found {\n\t\treturn nil\n\t}\n\n\tif info, found := OSShells[mainPath]; found {\n\t\tif name != mainPath {\n\t\t\tinfo.Reference = name\n\t\t}\n\n\t\treturn &info\n\t}\n\n\treturn nil\n}\n\nfunc parseOSShellsLine(line string) string {\n\tline = strings.TrimSpace(line)\n\tif strings.HasPrefix(line, \"#\") {\n\t\treturn \"\"\n\t}\n\n\treturn line\n}\n\nfunc ParseOSShells(raw []byte) []*OSShell {\n\tvar shells []*OSShell\n\tr := bytes.NewReader(raw)\n\tscanner := bufio.NewScanner(r)\n\tfor scanner.Scan() {\n\t\texePath := parseOSShellsLine(scanner.Text())\n\t\tif exePath != \"\" {\n\t\t\tshellInfo := LookupShellByExePath(exePath)\n\t\t\tif shellInfo != nil {\n\t\t\t\tinfo := *shellInfo\n\t\t\t\tshells = append(shells, &info)\n\t\t\t} else {\n\t\t\t\tunknown := &OSShell{\n\t\t\t\t\tFullName: \"Unknown shell\",\n\t\t\t\t\tExePath:  exePath,\n\t\t\t\t}\n\n\t\t\t\tshells = append(shells, unknown)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn shells\n}\n\nfunc NewOSShellsFromData(raw []byte) ([]*OSShell, error) {\n\tshells := ParseOSShells(raw)\n\treturn shells, nil\n}\n\nfunc NewOSShells(verify bool) ([]*OSShell, error) {\n\traw, err := os.ReadFile(OSShellsFile)\n\tif err == nil {\n\t\treturn nil, err\n\t}\n\n\tresult, err := NewOSShellsFromData(raw)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif verify {\n\t\tfor _, info := range result {\n\t\t\tif fsutil.Exists(info.ExePath) &&\n\t\t\t\t!fsutil.IsDir(info.ExePath) {\n\t\t\t\tinfo.Verified = true\n\n\t\t\t\tif fsutil.IsSymlink(info.ExePath) {\n\t\t\t\t\tif linkRef, err := os.Readlink(info.ExePath); err == nil {\n\t\t\t\t\t\tinfo.LinkPath = linkRef\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "pkg/system/syscalls.go",
    "content": "package system\n\n//NOTES:\n//* syscall constants in the \"syscall\" package are nice, but some syscalls there are missing\n//* future versions will include more than just the syscall name\n//* 32bit (x86/i386) and 64bit (x86_64) syscall numbers are different\n\nconst (\n\tSyscallX86MinNum      = 0\n\tSyscallX86UnknownNum  = -1\n\tSyscallX86UnknownName = \"unknown_syscall\"\n)\n\ntype NumberResolverFunc func(uint32) string\ntype NameResolverFunc func(string) (uint32, bool)\n\nfunc CallNumberResolver(arch ArchName) NumberResolverFunc {\n\tswitch arch {\n\tcase ArchName386:\n\t\treturn callNameX86Family32\n\tcase ArchNameAmd64:\n\t\treturn callNameX86Family64\n\tcase ArchNameArm32:\n\t\treturn callNameArmFamily32\n\tcase ArchNameArm64:\n\t\treturn callNameArmFamily64\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc CallNameResolver(arch ArchName) NameResolverFunc {\n\tswitch arch {\n\tcase ArchName386:\n\t\treturn callNumberX86Family32\n\tcase ArchNameAmd64:\n\t\treturn callNumberX86Family64\n\tcase ArchNameArm32:\n\t\treturn callNumberArmFamily32\n\tcase ArchNameArm64:\n\t\treturn callNumberArmFamily64\n\tdefault:\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "pkg/system/syscalls_armf32.go",
    "content": "package system\n\nconst (\n\tSyscallArmUnknownNum  = -1\n\tSyscallArmUnknownName = \"unknown_syscall\"\n\tSyscallArmMinNum32    = 0\n\tSyscallArmMaxNum32    = 377\n\tSyscallArmLastName32  = \"process_vm_writev\"\n)\n\nvar syscallNumTableArmFamily32 = map[uint32]string{\n\t0:   \"restart_syscall\",\n\t1:   \"exit\",\n\t2:   \"fork\",\n\t3:   \"read\",\n\t4:   \"write\",\n\t5:   \"open\",\n\t6:   \"close\",\n\t8:   \"creat\",\n\t9:   \"link\",\n\t10:  \"unlink\",\n\t11:  \"execve\",\n\t12:  \"chdir\",\n\t13:  \"time\",\n\t14:  \"mknod\",\n\t15:  \"chmod\",\n\t16:  \"lchown\",\n\t19:  \"lseek\",\n\t20:  \"getpid\",\n\t21:  \"mount\",\n\t22:  \"umount\",\n\t23:  \"setuid\",\n\t24:  \"getuid\",\n\t25:  \"stime\",\n\t26:  \"ptrace\",\n\t27:  \"alarm\",\n\t29:  \"pause\",\n\t30:  \"utime\",\n\t33:  \"access\",\n\t34:  \"nice\",\n\t36:  \"sync\",\n\t37:  \"kill\",\n\t38:  \"rename\",\n\t39:  \"mkdir\",\n\t40:  \"rmdir\",\n\t41:  \"dup\",\n\t42:  \"pipe\",\n\t43:  \"times\",\n\t45:  \"brk\",\n\t46:  \"setgid\",\n\t47:  \"getgid\",\n\t49:  \"geteuid\",\n\t50:  \"getegid\",\n\t51:  \"acct\",\n\t52:  \"umount2\",\n\t54:  \"ioctl\",\n\t55:  \"fcntl\",\n\t57:  \"setpgid\",\n\t60:  \"umask\",\n\t61:  \"chroot\",\n\t62:  \"ustat\",\n\t63:  \"dup2\",\n\t64:  \"getppid\",\n\t65:  \"getpgrp\",\n\t66:  \"setsid\",\n\t67:  \"sigaction\",\n\t70:  \"setreuid\",\n\t71:  \"setregid\",\n\t72:  \"sigsuspend\",\n\t73:  \"sigpending\",\n\t74:  \"sethostname\",\n\t75:  \"setrlimit\",\n\t76:  \"getrlimit\",\n\t77:  \"getrusage\",\n\t78:  \"gettimeofday\",\n\t79:  \"settimeofday\",\n\t80:  \"getgroups\",\n\t81:  \"setgroups\",\n\t82:  \"select\",\n\t83:  \"symlink\",\n\t85:  \"readlink\",\n\t86:  \"uselib\",\n\t87:  \"swapon\",\n\t88:  \"reboot\",\n\t89:  \"readdir\",\n\t90:  \"mmap\",\n\t91:  \"munmap\",\n\t92:  \"truncate\",\n\t93:  \"ftruncate\",\n\t94:  \"fchmod\",\n\t95:  \"fchown\",\n\t96:  \"getpriority\",\n\t97:  \"setpriority\",\n\t99:  \"statfs\",\n\t100: \"fstatfs\",\n\t102: \"socketcall\",\n\t103: \"syslog\",\n\t104: \"setitimer\",\n\t105: \"getitimer\",\n\t106: \"stat\",\n\t107: \"lstat\",\n\t108: \"fstat\",\n\t111: \"vhangup\",\n\t113: \"syscall\",\n\t114: \"wait4\",\n\t115: \"swapoff\",\n\t116: \"sysinfo\",\n\t117: \"ipc\",\n\t118: \"fsync\",\n\t119: \"sigreturn\",\n\t120: \"clone\",\n\t121: \"setdomainname\",\n\t122: \"uname\",\n\t124: \"adjtimex\",\n\t125: \"mprotect\",\n\t126: \"sigprocmask\",\n\t128: \"init_module\",\n\t129: \"delete_module\",\n\t131: \"quotactl\",\n\t132: \"getpgid\",\n\t133: \"fchdir\",\n\t134: \"bdflush\",\n\t135: \"sysfs\",\n\t136: \"personality\",\n\t138: \"setfsuid\",\n\t139: \"setfsgid\",\n\t140: \"_llseek\",\n\t141: \"getdents\",\n\t142: \"_newselect\",\n\t143: \"flock\",\n\t144: \"msync\",\n\t145: \"readv\",\n\t146: \"writev\",\n\t147: \"getsid\",\n\t148: \"fdatasync\",\n\t149: \"_sysctl\",\n\t150: \"mlock\",\n\t151: \"munlock\",\n\t152: \"mlockall\",\n\t153: \"munlockall\",\n\t154: \"sched_setparam\",\n\t155: \"sched_getparam\",\n\t156: \"sched_setscheduler\",\n\t157: \"sched_getscheduler\",\n\t158: \"sched_yield\",\n\t159: \"sched_get_priority_max\",\n\t160: \"sched_get_priority_min\",\n\t161: \"sched_rr_get_interval\",\n\t162: \"nanosleep\",\n\t163: \"mremap\",\n\t164: \"setresuid\",\n\t165: \"getresuid\",\n\t168: \"poll\",\n\t169: \"nfsservctl\",\n\t170: \"setresgid\",\n\t171: \"getresgid\",\n\t172: \"prctl\",\n\t173: \"rt_sigreturn\",\n\t174: \"rt_sigaction\",\n\t175: \"rt_sigprocmask\",\n\t176: \"rt_sigpending\",\n\t177: \"rt_sigtimedwait\",\n\t178: \"rt_sigqueueinfo\",\n\t179: \"rt_sigsuspend\",\n\t180: \"pread64\",\n\t181: \"pwrite64\",\n\t182: \"chown\",\n\t183: \"getcwd\",\n\t184: \"capget\",\n\t185: \"capset\",\n\t186: \"sigaltstack\",\n\t187: \"sendfile\",\n\t190: \"vfork\",\n\t191: \"ugetrlimit\",\n\t192: \"mmap2\",\n\t193: \"truncate64\",\n\t194: \"ftruncate64\",\n\t195: \"stat64\",\n\t196: \"lstat64\",\n\t197: \"fstat64\",\n\t198: \"lchown32\",\n\t199: \"getuid32\",\n\t200: \"getgid32\",\n\t201: \"geteuid32\",\n\t202: \"getegid32\",\n\t203: \"setreuid32\",\n\t204: \"setregid32\",\n\t205: \"getgroups32\",\n\t206: \"setgroups32\",\n\t207: \"fchown32\",\n\t208: \"setresuid32\",\n\t209: \"getresuid32\",\n\t210: \"setresgid32\",\n\t211: \"getresgid32\",\n\t212: \"chown32\",\n\t213: \"setuid32\",\n\t214: \"setgid32\",\n\t215: \"setfsuid32\",\n\t216: \"setfsgid32\",\n\t217: \"getdents64\",\n\t218: \"pivot_root\",\n\t219: \"mincore\",\n\t220: \"madvise\",\n\t221: \"fcntl64\",\n\t224: \"gettid\",\n\t225: \"readahead\",\n\t226: \"setxattr\",\n\t227: \"lsetxattr\",\n\t228: \"fsetxattr\",\n\t229: \"getxattr\",\n\t230: \"lgetxattr\",\n\t231: \"fgetxattr\",\n\t232: \"listxattr\",\n\t233: \"llistxattr\",\n\t234: \"flistxattr\",\n\t235: \"removexattr\",\n\t236: \"lremovexattr\",\n\t237: \"fremovexattr\",\n\t238: \"tkill\",\n\t239: \"sendfile64\",\n\t240: \"futex\",\n\t241: \"sched_setaffinity\",\n\t242: \"sched_getaffinity\",\n\t243: \"io_setup\",\n\t244: \"io_destroy\",\n\t245: \"io_getevents\",\n\t246: \"io_submit\",\n\t247: \"io_cancel\",\n\t248: \"exit_group\",\n\t249: \"lookup_dcookie\",\n\t250: \"epoll_create\",\n\t251: \"epoll_ctl\",\n\t252: \"epoll_wait\",\n\t253: \"remap_file_pages\",\n\t256: \"set_tid_address\",\n\t257: \"timer_create\",\n\t258: \"timer_settime\",\n\t259: \"timer_gettime\",\n\t260: \"timer_getoverrun\",\n\t261: \"timer_delete\",\n\t262: \"clock_settime\",\n\t263: \"clock_gettime\",\n\t264: \"clock_getres\",\n\t265: \"clock_nanosleep\",\n\t266: \"statfs64\",\n\t267: \"fstatfs64\",\n\t268: \"tgkill\",\n\t269: \"utimes\",\n\t270: \"arm_fadvise64_64\",\n\t271: \"pciconfig_iobase\",\n\t272: \"pciconfig_read\",\n\t273: \"pciconfig_write\",\n\t274: \"mq_open\",\n\t275: \"mq_unlink\",\n\t276: \"mq_timedsend\",\n\t277: \"mq_timedreceive\",\n\t278: \"mq_notify\",\n\t279: \"mq_getsetattr\",\n\t280: \"waitid\",\n\t281: \"socket\",\n\t282: \"bind\",\n\t283: \"connect\",\n\t284: \"listen\",\n\t285: \"accept\",\n\t286: \"getsockname\",\n\t287: \"getpeername\",\n\t288: \"socketpair\",\n\t289: \"send\",\n\t290: \"sendto\",\n\t291: \"recv\",\n\t292: \"recvfrom\",\n\t293: \"shutdown\",\n\t294: \"setsockopt\",\n\t295: \"getsockopt\",\n\t296: \"sendmsg\",\n\t297: \"recvmsg\",\n\t298: \"semop\",\n\t299: \"semget\",\n\t300: \"semctl\",\n\t301: \"msgsnd\",\n\t302: \"msgrcv\",\n\t303: \"msgget\",\n\t304: \"msgctl\",\n\t305: \"shmat\",\n\t306: \"shmdt\",\n\t307: \"shmget\",\n\t308: \"shmctl\",\n\t309: \"add_key\",\n\t310: \"request_key\",\n\t311: \"keyctl\",\n\t312: \"semtimedop\",\n\t313: \"vserver\",\n\t314: \"ioprio_set\",\n\t315: \"ioprio_get\",\n\t316: \"inotify_init\",\n\t317: \"inotify_add_watch\",\n\t318: \"inotify_rm_watch\",\n\t319: \"mbind\",\n\t320: \"get_mempolicy\",\n\t321: \"set_mempolicy\",\n\t322: \"openat\",\n\t323: \"mkdirat\",\n\t324: \"mknodat\",\n\t325: \"fchownat\",\n\t326: \"futimesat\",\n\t327: \"fstatat64\",\n\t328: \"unlinkat\",\n\t329: \"renameat\",\n\t330: \"linkat\",\n\t331: \"symlinkat\",\n\t332: \"readlinkat\",\n\t333: \"fchmodat\",\n\t334: \"faccessat\",\n\t335: \"pselect6\",\n\t336: \"ppoll\",\n\t337: \"unshare\",\n\t338: \"set_robust_list\",\n\t339: \"get_robust_list\",\n\t340: \"splice\",\n\t341: \"sync_file_range2\",\n\t342: \"tee\",\n\t343: \"vmsplice\",\n\t344: \"move_pages\",\n\t345: \"getcpu\",\n\t346: \"epoll_pwait\",\n\t347: \"kexec_load\",\n\t348: \"utimensat\",\n\t349: \"signalfd\",\n\t350: \"timerfd_create\",\n\t351: \"eventfd\",\n\t352: \"fallocate\",\n\t353: \"timerfd_settime\",\n\t354: \"timerfd_gettime\",\n\t355: \"signalfd4\",\n\t356: \"eventfd2\",\n\t357: \"epoll_create1\",\n\t358: \"dup3\",\n\t359: \"pipe2\",\n\t360: \"inotify_init1\",\n\t361: \"preadv\",\n\t362: \"pwritev\",\n\t363: \"rt_tgsigqueueinfo\",\n\t364: \"perf_event_open\",\n\t365: \"recvmmsg\",\n\t366: \"accept4\",\n\t367: \"fanotify_init\",\n\t368: \"fanotify_mark\",\n\t369: \"prlimit64\",\n\t370: \"name_to_handle_at\",\n\t371: \"open_by_handle_at\",\n\t372: \"clock_adjtime\",\n\t373: \"syncfs\",\n\t374: \"sendmmsg\",\n\t375: \"setns\",\n\t376: \"process_vm_readv\",\n\t377: \"process_vm_writev\",\n}\n\nfunc callNameArmFamily32(num uint32) string {\n\tif num > SyscallArmMaxNum32 {\n\t\treturn SyscallArmUnknownName\n\t}\n\n\treturn syscallNumTableArmFamily32[num]\n}\n\nfunc callNumTableIsOkArmFamily32() bool {\n\tif (len(syscallNumTableArmFamily32) == SyscallArmMaxNum32+1) &&\n\t\tsyscallNumTableArmFamily32[SyscallArmMaxNum32] == SyscallArmLastName32 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc callNumberArmFamily32(name string) (uint32, bool) {\n\tnum, ok := syscallNameTableArmFamily32[name]\n\treturn num, ok\n}\n\nvar syscallNameTableArmFamily32 map[string]uint32\n\nfunc init() {\n\tsyscallNameTableArmFamily32 = make(map[string]uint32, len(syscallNumTableArmFamily32))\n\n\tfor callNum, callName := range syscallNumTableArmFamily32 {\n\t\tsyscallNameTableArmFamily32[callName] = uint32(callNum)\n\t}\n}\n"
  },
  {
    "path": "pkg/system/syscalls_armf64.go",
    "content": "package system\n\nconst (\n\tSyscallArmUnknownNum64  = -1\n\tSyscallArmUnknownName64 = \"unknown_syscall\"\n\tSyscallArmMinNum64      = 0\n\tSyscallArmMaxNum64      = 294\n\tSyscallArmLastName64    = \"kexec_file_load\"\n)\n\nvar syscallNumTableArmFamily64 = map[uint32]string{\n\t0:   \"io_setup\",\n\t1:   \"io_destroy\",\n\t2:   \"io_submit\",\n\t3:   \"io_cancel\",\n\t4:   \"io_getevents\",\n\t5:   \"setxattr\",\n\t6:   \"lsetxattr\",\n\t7:   \"fsetxattr\",\n\t8:   \"getxattr\",\n\t9:   \"lgetxattr\",\n\t10:  \"fgetxattr\",\n\t11:  \"listxattr\",\n\t12:  \"llistxattr\",\n\t13:  \"flistxattr\",\n\t14:  \"removexattr\",\n\t15:  \"lremovexattr\",\n\t16:  \"fremovexattr\",\n\t17:  \"getcwd\",\n\t18:  \"lookup_dcookie\",\n\t19:  \"eventfd2\",\n\t20:  \"epoll_create1\",\n\t21:  \"epoll_ctl\",\n\t22:  \"epoll_pwait\",\n\t23:  \"dup\",\n\t24:  \"dup3\",\n\t25:  \"fcntl\",\n\t26:  \"inotify_init1\",\n\t27:  \"inotify_add_watch\",\n\t28:  \"inotify_rm_watch\",\n\t29:  \"ioctl\",\n\t30:  \"ioprio_set\",\n\t31:  \"ioprio_get\",\n\t32:  \"flock\",\n\t33:  \"mknodat\",\n\t34:  \"mkdirat\",\n\t35:  \"unlinkat\",\n\t36:  \"symlinkat\",\n\t37:  \"linkat\",\n\t38:  \"renameat\",\n\t39:  \"umount2\",\n\t40:  \"mount\",\n\t41:  \"pivot_root\",\n\t42:  \"nfsservctl\",\n\t43:  \"statfs\",\n\t44:  \"fstatfs\",\n\t45:  \"truncate\",\n\t46:  \"ftruncate\",\n\t47:  \"fallocate\",\n\t48:  \"faccessat\",\n\t49:  \"chdir\",\n\t50:  \"fchdir\",\n\t51:  \"chroot\",\n\t52:  \"fchmod\",\n\t53:  \"fchmodat\",\n\t54:  \"fchownat\",\n\t55:  \"fchown\",\n\t56:  \"openat\",\n\t57:  \"close\",\n\t58:  \"vhangup\",\n\t59:  \"pipe2\",\n\t60:  \"quotactl\",\n\t61:  \"getdents64\",\n\t62:  \"lseek\",\n\t63:  \"read\",\n\t64:  \"write\",\n\t65:  \"readv\",\n\t66:  \"writev\",\n\t67:  \"pread64\",\n\t68:  \"pwrite64\",\n\t69:  \"preadv\",\n\t70:  \"pwritev\",\n\t71:  \"sendfile\",\n\t72:  \"pselect6\",\n\t73:  \"ppoll\",\n\t74:  \"signalfd4\",\n\t75:  \"vmsplice\",\n\t76:  \"splice\",\n\t77:  \"tee\",\n\t78:  \"readlinkat\",\n\t79:  \"fstatat\",\n\t80:  \"fstat\",\n\t81:  \"sync\",\n\t82:  \"fsync\",\n\t83:  \"fdatasync\",\n\t84:  \"sync_file_range\",\n\t85:  \"timerfd_create\",\n\t86:  \"timerfd_settime\",\n\t87:  \"timerfd_gettime\",\n\t88:  \"utimensat\",\n\t89:  \"acct\",\n\t90:  \"capget\",\n\t91:  \"capset\",\n\t92:  \"personality\",\n\t93:  \"exit\",\n\t94:  \"exit_group\",\n\t95:  \"waitid\",\n\t96:  \"set_tid_address\",\n\t97:  \"unshare\",\n\t98:  \"futex\",\n\t99:  \"set_robust_list\",\n\t100: \"get_robust_list\",\n\t101: \"nanosleep\",\n\t102: \"getitimer\",\n\t103: \"setitimer\",\n\t104: \"kexec_load\",\n\t105: \"init_module\",\n\t106: \"delete_module\",\n\t107: \"timer_create\",\n\t108: \"timer_gettime\",\n\t109: \"timer_getoverrun\",\n\t110: \"timer_settime\",\n\t111: \"timer_delete\",\n\t112: \"clock_settime\",\n\t113: \"clock_gettime\",\n\t114: \"clock_getres\",\n\t115: \"clock_nanosleep\",\n\t116: \"syslog\",\n\t117: \"ptrace\",\n\t118: \"sched_setparam\",\n\t119: \"sched_setscheduler\",\n\t120: \"sched_getscheduler\",\n\t121: \"sched_getparam\",\n\t122: \"sched_setaffinity\",\n\t123: \"sched_getaffinity\",\n\t124: \"sched_yield\",\n\t125: \"sched_get_priority_max\",\n\t126: \"sched_get_priority_min\",\n\t127: \"sched_rr_get_interval\",\n\t128: \"restart_syscall\",\n\t129: \"kill\",\n\t130: \"tkill\",\n\t131: \"tgkill\",\n\t132: \"sigaltstack\",\n\t133: \"rt_sigsuspend\",\n\t134: \"rt_sigaction\",\n\t135: \"rt_sigprocmask\",\n\t136: \"rt_sigpending\",\n\t137: \"rt_sigtimedwait\",\n\t138: \"rt_sigqueueinfo\",\n\t139: \"rt_sigreturn\",\n\t140: \"setpriority\",\n\t141: \"getpriority\",\n\t142: \"reboot\",\n\t143: \"setregid\",\n\t144: \"setgid\",\n\t145: \"setreuid\",\n\t146: \"setuid\",\n\t147: \"setresuid\",\n\t148: \"getresuid\",\n\t149: \"setresgid\",\n\t150: \"getresgid\",\n\t151: \"setfsuid\",\n\t152: \"setfsgid\",\n\t153: \"times\",\n\t154: \"setpgid\",\n\t155: \"getpgid\",\n\t156: \"getsid\",\n\t157: \"setsid\",\n\t158: \"getgroups\",\n\t159: \"setgroups\",\n\t160: \"uname\",\n\t161: \"sethostname\",\n\t162: \"setdomainname\",\n\t163: \"getrlimit\",\n\t164: \"setrlimit\",\n\t165: \"getrusage\",\n\t166: \"umask\",\n\t167: \"prctl\",\n\t168: \"getcpu\",\n\t169: \"gettimeofday\",\n\t170: \"settimeofday\",\n\t171: \"adjtimex\",\n\t172: \"getpid\",\n\t173: \"getppid\",\n\t174: \"getuid\",\n\t175: \"geteuid\",\n\t176: \"getgid\",\n\t177: \"getegid\",\n\t178: \"gettid\",\n\t179: \"sysinfo\",\n\t180: \"mq_open\",\n\t181: \"mq_unlink\",\n\t182: \"mq_timedsend\",\n\t183: \"mq_timedreceive\",\n\t184: \"mq_notify\",\n\t185: \"mq_getsetattr\",\n\t186: \"msgget\",\n\t187: \"msgctl\",\n\t188: \"msgrcv\",\n\t189: \"msgsnd\",\n\t190: \"semget\",\n\t191: \"semctl\",\n\t192: \"semtimedop\",\n\t193: \"semop\",\n\t194: \"shmget\",\n\t195: \"shmctl\",\n\t196: \"shmat\",\n\t197: \"shmdt\",\n\t198: \"socket\",\n\t199: \"socketpair\",\n\t200: \"bind\",\n\t201: \"listen\",\n\t202: \"accept\",\n\t203: \"connect\",\n\t204: \"getsockname\",\n\t205: \"getpeername\",\n\t206: \"sendto\",\n\t207: \"recvfrom\",\n\t208: \"setsockopt\",\n\t209: \"getsockopt\",\n\t210: \"shutdown\",\n\t211: \"sendmsg\",\n\t212: \"recvmsg\",\n\t213: \"readahead\",\n\t214: \"brk\",\n\t215: \"munmap\",\n\t216: \"mremap\",\n\t217: \"add_key\",\n\t218: \"request_key\",\n\t219: \"keyctl\",\n\t220: \"clone\",\n\t221: \"execve\",\n\t222: \"mmap\",\n\t223: \"fadvise64\",\n\t224: \"swapon\",\n\t225: \"swapoff\",\n\t226: \"mprotect\",\n\t227: \"msync\",\n\t228: \"mlock\",\n\t229: \"munlock\",\n\t230: \"mlockall\",\n\t231: \"munlockall\",\n\t232: \"mincore\",\n\t233: \"madvise\",\n\t234: \"remap_file_pages\",\n\t235: \"mbind\",\n\t236: \"get_mempolicy\",\n\t237: \"set_mempolicy\",\n\t238: \"migrate_pages\",\n\t239: \"move_pages\",\n\t240: \"rt_tgsigqueueinfo\",\n\t241: \"perf_event_open\",\n\t242: \"accept4\",\n\t243: \"recvmmsg\",\n\t244: \"arch_specific_syscall\",\n\t260: \"wait4\",\n\t261: \"prlimit64\",\n\t262: \"fanotify_init\",\n\t263: \"fanotify_mark\",\n\t264: \"name_to_handle_at\",\n\t265: \"open_by_handle_at\",\n\t266: \"clock_adjtime\",\n\t267: \"syncfs\",\n\t268: \"setns\",\n\t269: \"sendmmsg\",\n\t270: \"process_vm_readv\",\n\t271: \"process_vm_writev\",\n\t272: \"kcmp\",\n\t273: \"finit_module\",\n\t274: \"sched_setattr\",\n\t275: \"sched_getattr\",\n\t276: \"renameat2\",\n\t277: \"seccomp\",\n\t278: \"getrandom\",\n\t279: \"memfd_create\",\n\t280: \"bpf\",\n\t281: \"execveat\",\n\t282: \"userfaultfd\",\n\t283: \"membarrier\",\n\t284: \"mlock2\",\n\t285: \"copy_file_range\",\n\t286: \"preadv2\",\n\t287: \"pwritev2\",\n\t288: \"pkey_mprotect\",\n\t289: \"pkey_alloc\",\n\t290: \"pkey_free\",\n\t291: \"statx\",\n\t292: \"io_pgetevents\",\n\t293: \"rseq\",\n\t294: \"kexec_file_load\",\n}\n\nfunc callNameArmFamily64(num uint32) string {\n\tif num > SyscallArmMaxNum64 {\n\t\treturn SyscallArmUnknownName64\n\t}\n\n\treturn syscallNumTableArmFamily64[num]\n}\n\nfunc callNumTableIsOkArmFamily64() bool {\n\tif (len(syscallNumTableArmFamily64) == SyscallArmMaxNum64+1) &&\n\t\tsyscallNumTableArmFamily64[SyscallArmMaxNum64] == SyscallArmLastName64 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc callNumberArmFamily64(name string) (uint32, bool) {\n\tnum, ok := syscallNameTableArmFamily64[name]\n\treturn num, ok\n}\n\nvar syscallNameTableArmFamily64 map[string]uint32\n\nfunc init() {\n\tsyscallNameTableArmFamily64 = make(map[string]uint32, len(syscallNumTableArmFamily64))\n\n\tfor callNum, callName := range syscallNumTableArmFamily64 {\n\t\tsyscallNameTableArmFamily64[callName] = uint32(callNum)\n\t}\n}\n"
  },
  {
    "path": "pkg/system/syscalls_x86f32.go",
    "content": "package system\n\nconst (\n\tSyscallX86MaxNum32   = 435\n\tSyscallX86LastName32 = \"clone3\"\n)\n\n// line numbers are aligned with the syscall number (-10)\nvar syscallNumTableX86Family32 = [...]string{\n\t\"restart_syscall\",\n\t\"exit\",\n\t\"fork\",\n\t\"read\",\n\t\"write\",\n\t\"open\",\n\t\"close\",\n\t\"waitpid\",\n\t\"creat\",\n\t\"link\",\n\t\"unlink\",\n\t\"execve\",\n\t\"chdir\",\n\t\"time\",\n\t\"mknod\",\n\t\"chmod\",\n\t\"lchown\",\n\t\"break\",\n\t\"oldstat\",\n\t\"lseek\",\n\t\"getpid\",\n\t\"mount\",\n\t\"umount\",\n\t\"setuid\",\n\t\"getuid\",\n\t\"stime\",\n\t\"ptrace\",\n\t\"alarm\",\n\t\"oldfstat\",\n\t\"pause\",\n\t\"utime\",\n\t\"stty\",\n\t\"gtty\",\n\t\"access\",\n\t\"nice\",\n\t\"ftime\",\n\t\"sync\",\n\t\"kill\",\n\t\"rename\",\n\t\"mkdir\",\n\t\"rmdir\",\n\t\"dup\",\n\t\"pipe\",\n\t\"times\",\n\t\"prof\",\n\t\"brk\",\n\t\"setgid\",\n\t\"getgid\",\n\t\"signal\",\n\t\"geteuid\",\n\t\"getegid\",\n\t\"acct\",\n\t\"umount2\",\n\t\"lock\",\n\t\"ioctl\",\n\t\"fcntl\",\n\t\"mpx\",\n\t\"setpgid\",\n\t\"ulimit\",\n\t\"oldolduname\",\n\t\"umask\",\n\t\"chroot\",\n\t\"ustat\",\n\t\"dup2\",\n\t\"getppid\",\n\t\"getpgrp\",\n\t\"setsid\",\n\t\"sigaction\",\n\t\"sgetmask\",\n\t\"ssetmask\",\n\t\"setreuid\",\n\t\"setregid\",\n\t\"sigsuspend\",\n\t\"sigpending\",\n\t\"sethostname\",\n\t\"setrlimit\",\n\t\"getrlimit\",\n\t\"getrusage\",\n\t\"gettimeofday\",\n\t\"settimeofday\",\n\t\"getgroups\",\n\t\"setgroups\",\n\t\"select\",\n\t\"symlink\",\n\t\"oldlstat\",\n\t\"readlink\",\n\t\"uselib\",\n\t\"swapon\",\n\t\"reboot\",\n\t\"readdir\",\n\t\"mmap\",\n\t\"munmap\",\n\t\"truncate\",\n\t\"ftruncate\",\n\t\"fchmod\",\n\t\"fchown\",\n\t\"getpriority\",\n\t\"setpriority\",\n\t\"profil\",\n\t\"statfs\",\n\t\"fstatfs\",\n\t\"ioperm\",\n\t\"socketcall\",\n\t\"syslog\",\n\t\"setitimer\",\n\t\"getitimer\",\n\t\"stat\",\n\t\"lstat\",\n\t\"fstat\",\n\t\"olduname\",\n\t\"iopl\",\n\t\"vhangup\",\n\t\"idle\",\n\t\"vm86old\",\n\t\"wait4\",\n\t\"swapoff\",\n\t\"sysinfo\",\n\t\"ipc\",\n\t\"fsync\",\n\t\"sigreturn\",\n\t\"clone\",\n\t\"setdomainname\",\n\t\"uname\",\n\t\"modify_ldt\",\n\t\"adjtimex\",\n\t\"mprotect\",\n\t\"sigprocmask\",\n\t\"create_module\",\n\t\"init_module\",\n\t\"delete_module\",\n\t\"get_kernel_syms\",\n\t\"quotactl\",\n\t\"getpgid\",\n\t\"fchdir\",\n\t\"bdflush\",\n\t\"sysfs\",\n\t\"personality\",\n\t\"afs_syscall\",\n\t\"setfsuid\",\n\t\"setfsgid\",\n\t\"_llseek\",\n\t\"getdents\",\n\t\"_newselect\",\n\t\"flock\",\n\t\"msync\",\n\t\"readv\",\n\t\"writev\",\n\t\"getsid\",\n\t\"fdatasync\",\n\t\"_sysctl\",\n\t\"mlock\",\n\t\"munlock\",\n\t\"mlockall\",\n\t\"munlockall\",\n\t\"sched_setparam\",\n\t\"sched_getparam\",\n\t\"sched_setscheduler\",\n\t\"sched_getscheduler\",\n\t\"sched_yield\",\n\t\"sched_get_priority_max\",\n\t\"sched_get_priority_min\",\n\t\"sched_rr_get_interval\",\n\t\"nanosleep\",\n\t\"mremap\",\n\t\"setresuid\",\n\t\"getresuid\",\n\t\"vm86\",\n\t\"query_module\",\n\t\"poll\",\n\t\"nfsservctl\",\n\t\"setresgid\",\n\t\"getresgid\",\n\t\"prctl\",\n\t\"rt_sigreturn\",\n\t\"rt_sigaction\",\n\t\"rt_sigprocmask\",\n\t\"rt_sigpending\",\n\t\"rt_sigtimedwait\",\n\t\"rt_sigqueueinfo\",\n\t\"rt_sigsuspend\",\n\t\"pread64\",\n\t\"pwrite64\",\n\t\"chown\",\n\t\"getcwd\",\n\t\"capget\",\n\t\"capset\",\n\t\"sigaltstack\",\n\t\"sendfile\",\n\t\"getpmsg\",\n\t\"putpmsg\",\n\t\"vfork\",\n\t\"ugetrlimit\",\n\t\"mmap2\",\n\t\"truncate64\",\n\t\"ftruncate64\",\n\t\"stat64\",\n\t\"lstat64\",\n\t\"fstat64\",\n\t\"lchown32\",\n\t\"getuid32\",\n\t\"getgid32\",\n\t\"geteuid32\",\n\t\"getegid32\",\n\t\"setreuid32\",\n\t\"setregid32\",\n\t\"getgroups32\",\n\t\"setgroups32\",\n\t\"fchown32\",\n\t\"setresuid32\",\n\t\"getresuid32\",\n\t\"setresgid32\",\n\t\"getresgid32\",\n\t\"chown32\",\n\t\"setuid32\",\n\t\"setgid32\",\n\t\"setfsuid32\",\n\t\"setfsgid32\",\n\t\"pivot_root\",\n\t\"mincore\",\n\t\"madvise\",\n\t\"getdents64\",\n\t\"fcntl64\",\n\t\"unused.222\", //222 - unused\n\t\"unused.223\", //223 - unused\n\t\"gettid\",\n\t\"readahead\",\n\t\"setxattr\",\n\t\"lsetxattr\",\n\t\"fsetxattr\",\n\t\"getxattr\",\n\t\"lgetxattr\",\n\t\"fgetxattr\",\n\t\"listxattr\",\n\t\"llistxattr\",\n\t\"flistxattr\",\n\t\"removexattr\",\n\t\"lremovexattr\",\n\t\"fremovexattr\",\n\t\"tkill\",\n\t\"sendfile64\",\n\t\"futex\",\n\t\"sched_setaffinity\",\n\t\"sched_getaffinity\",\n\t\"set_thread_area\",\n\t\"get_thread_area\",\n\t\"io_setup\",\n\t\"io_destroy\",\n\t\"io_getevents\",\n\t\"io_submit\",\n\t\"io_cancel\",\n\t\"fadvise64\",\n\t\"unused.251\", //251 - unused (available for reuse) was used by sys_set_zone_reclaim\n\t\"exit_group\",\n\t\"lookup_dcookie\",\n\t\"epoll_create\",\n\t\"epoll_ctl\",\n\t\"epoll_wait\",\n\t\"remap_file_pages\",\n\t\"set_tid_address\",\n\t\"timer_create\",\n\t\"timer_settime\",\n\t\"timer_gettime\",\n\t\"timer_getoverrun\",\n\t\"timer_delete\",\n\t\"clock_settime\",\n\t\"clock_gettime\",\n\t\"clock_getres\",\n\t\"clock_nanosleep\",\n\t\"statfs64\",\n\t\"fstatfs64\",\n\t\"tgkill\",\n\t\"utimes\",\n\t\"fadvise64_64\",\n\t\"vserver\",\n\t\"mbind\",\n\t\"get_mempolicy\",\n\t\"set_mempolicy\",\n\t\"mq_open\",\n\t\"mq_unlink\",\n\t\"mq_timedsend\",\n\t\"mq_timedreceive\",\n\t\"mq_notify\",\n\t\"mq_getsetattr\",\n\t\"kexec_load\",\n\t\"waitid\",\n\t\"setaltroot\", //285 - sys_setaltroot (sort of used :))\n\t\"add_key\",\n\t\"request_key\",\n\t\"keyctl\",\n\t\"ioprio_set\",\n\t\"ioprio_get\",\n\t\"inotify_init\",\n\t\"inotify_add_watch\",\n\t\"inotify_rm_watch\",\n\t\"migrate_pages\",\n\t\"openat\",\n\t\"mkdirat\",\n\t\"mknodat\",\n\t\"fchownat\",\n\t\"futimesat\",\n\t\"fstatat64\",\n\t\"unlinkat\",\n\t\"renameat\",\n\t\"linkat\",\n\t\"symlinkat\",\n\t\"readlinkat\",\n\t\"fchmodat\",\n\t\"faccessat\",\n\t\"pselect6\",\n\t\"ppoll\",\n\t\"unshare\",\n\t\"set_robust_list\",\n\t\"get_robust_list\",\n\t\"splice\",\n\t\"sync_file_range\",\n\t\"tee\",\n\t\"vmsplice\",\n\t\"move_pages\",\n\t\"getcpu\",\n\t\"epoll_pwait\",\n\t\"utimensat\",\n\t\"signalfd\",\n\t\"timerfd_create\",\n\t\"eventfd\",\n\t\"fallocate\",\n\t\"timerfd_settime\",\n\t\"timerfd_gettime\",\n\t\"signalfd4\",\n\t\"eventfd2\",\n\t\"epoll_create1\",\n\t\"dup3\",\n\t\"pipe2\",\n\t\"inotify_init1\",\n\t\"preadv\",\n\t\"pwritev\",\n\t\"rt_tgsigqueueinfo\",\n\t\"perf_event_open\",\n\t\"recvmmsg\",\n\t\"fanotify_init\",\n\t\"fanotify_mark\",\n\t\"prlimit64\",\n\t\"name_to_handle_at\",\n\t\"open_by_handle_at\",\n\t\"clock_adjtime\",\n\t\"syncfs\",\n\t\"sendmmsg\",\n\t\"setns\",\n\t\"process_vm_readv\",\n\t\"process_vm_writev\",\n\t\"kcmp\",\n\t\"finit_module\",\n\t\"sched_setattr\",\n\t\"sched_getattr\",\n\t\"renameat2\",\n\t\"seccomp\",\n\t\"getrandom\",\n\t\"memfd_create\",\n\t\"bpf\",\n\t\"execveat\", //358\n\t\"socket\",\n\t\"socketpair\",\n\t\"bind\",\n\t\"connect\",\n\t\"listen\",\n\t\"accept4\",\n\t\"getsockopt\",\n\t\"setsockopt\",\n\t\"getsockname\",\n\t\"getpeername\",\n\t\"sendto\",\n\t\"sendmsg\",\n\t\"recvfrom\",\n\t\"recvmsg\",\n\t\"shutdown\",\n\t\"userfaultfd\",\n\t\"membarrier\",\n\t\"mlock2\",\n\t\"copy_file_range\",\n\t\"preadv2\",\n\t\"pwritev2\",\n\t\"pkey_mprotect\",\n\t\"pkey_alloc\",\n\t\"pkey_free\",\n\t\"statx\",\n\t\"arch_prctl\",\n\t\"io_pgetevents\",\n\t\"rseq\",\n\t\"unused.387\",\n\t\"unused.388\",\n\t\"unused.389\",\n\t\"unused.390\",\n\t\"unused.391\",\n\t\"unused.392\",\n\t\"semget\",\n\t\"semctl\",\n\t\"shmget\",\n\t\"shmctl\",\n\t\"shmat\",\n\t\"shmdt\",\n\t\"msgget\",\n\t\"msgsnd\",\n\t\"msgrcv\",\n\t\"msgctl\",\n\t\"clock_gettime64\",\n\t\"clock_settime64\",\n\t\"clock_adjtime64\",\n\t\"clock_getres_time64\",\n\t\"clock_nanosleep_time64\",\n\t\"timer_gettime64\",\n\t\"timer_settime64\",\n\t\"timerfd_gettime64\",\n\t\"timerfd_settime64\",\n\t\"utimensat_time64\",\n\t\"pselect6_time64\",\n\t\"ppoll_time64\",\n\t\"unused.415\",\n\t\"io_pgetevents_time64\",\n\t\"recvmmsg_time64\",\n\t\"mq_timedsend_time64\",\n\t\"mq_timedreceive_time64\",\n\t\"semtimedop_time64\",\n\t\"rt_sigtimedwait_time64\",\n\t\"futex_time64\",\n\t\"sched_rr_get_interval_time64\",\n\t\"pidfd_send_signal\",\n\t\"io_uring_setup\",\n\t\"io_uring_enter\",\n\t\"io_uring_register\",\n\t\"open_tree\",\n\t\"move_mount\",\n\t\"fsopen\",\n\t\"fsconfig\",\n\t\"fsmount\",\n\t\"fspick\",\n\t\"pidfd_open\",\n\t\"clone3\", //435\n}\n\nfunc callNameX86Family32(num uint32) string {\n\tif num > SyscallX86MaxNum32 {\n\t\treturn SyscallX86UnknownName\n\t}\n\n\treturn syscallNumTableX86Family32[num]\n}\n\nfunc callNumTableIsOkX86Family32() bool {\n\tif (len(syscallNumTableX86Family32) == SyscallX86MaxNum32+1) &&\n\t\tsyscallNumTableX86Family32[SyscallX86MaxNum32] == SyscallX86LastName32 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc callNumberX86Family32(name string) (uint32, bool) {\n\tnum, ok := syscallNameTableX86Family32[name]\n\treturn num, ok\n}\n\nvar syscallNameTableX86Family32 map[string]uint32\n\nfunc init() {\n\tsyscallNameTableX86Family32 = make(map[string]uint32, len(syscallNumTableX86Family32))\n\n\tfor callNum, callName := range syscallNumTableX86Family32 {\n\t\tsyscallNameTableX86Family32[callName] = uint32(callNum)\n\t}\n}\n"
  },
  {
    "path": "pkg/system/syscalls_x86f64.go",
    "content": "package system\n\nconst (\n\tSyscallX86MaxNum64   = 435\n\tSyscallX86LastName64 = \"clone3\"\n)\n\n// line numbers are aligned with the syscall number (-10)\nvar syscallNumTableX86Family64 = [...]string{\n\t\"read\",\n\t\"write\",\n\t\"open\",\n\t\"close\",\n\t\"stat\",\n\t\"fstat\",\n\t\"lstat\",\n\t\"poll\",\n\t\"lseek\",\n\t\"mmap\",\n\t\"mprotect\",\n\t\"munmap\",\n\t\"brk\",\n\t\"rt_sigaction\",\n\t\"rt_sigprocmask\",\n\t\"rt_sigreturn\",\n\t\"ioctl\",\n\t\"pread64\",\n\t\"pwrite64\",\n\t\"readv\",\n\t\"writev\",\n\t\"access\",\n\t\"pipe\",\n\t\"select\",\n\t\"sched_yield\",\n\t\"mremap\",\n\t\"msync\",\n\t\"mincore\",\n\t\"madvise\",\n\t\"shmget\",\n\t\"shmat\",\n\t\"shmctl\",\n\t\"dup\",\n\t\"dup2\",\n\t\"pause\",\n\t\"nanosleep\",\n\t\"getitimer\",\n\t\"alarm\",\n\t\"setitimer\",\n\t\"getpid\",\n\t\"sendfile\",\n\t\"socket\",\n\t\"connect\",\n\t\"accept\",\n\t\"sendto\",\n\t\"recvfrom\",\n\t\"sendmsg\",\n\t\"recvmsg\",\n\t\"shutdown\",\n\t\"bind\",\n\t\"listen\",\n\t\"getsockname\",\n\t\"getpeername\",\n\t\"socketpair\",\n\t\"setsockopt\",\n\t\"getsockopt\",\n\t\"clone\",\n\t\"fork\",\n\t\"vfork\",\n\t\"execve\",\n\t\"exit\",\n\t\"wait4\",\n\t\"kill\",\n\t\"uname\",\n\t\"semget\",\n\t\"semop\",\n\t\"semctl\",\n\t\"shmdt\",\n\t\"msgget\",\n\t\"msgsnd\",\n\t\"msgrcv\",\n\t\"msgctl\",\n\t\"fcntl\",\n\t\"flock\",\n\t\"fsync\",\n\t\"fdatasync\",\n\t\"truncate\",\n\t\"ftruncate\",\n\t\"getdents\",\n\t\"getcwd\",\n\t\"chdir\",\n\t\"fchdir\",\n\t\"rename\",\n\t\"mkdir\",\n\t\"rmdir\",\n\t\"creat\",\n\t\"link\",\n\t\"unlink\",\n\t\"symlink\",\n\t\"readlink\",\n\t\"chmod\",\n\t\"fchmod\",\n\t\"chown\",\n\t\"fchown\",\n\t\"lchown\",\n\t\"umask\",\n\t\"gettimeofday\",\n\t\"getrlimit\",\n\t\"getrusage\",\n\t\"sysinfo\",\n\t\"times\",\n\t\"ptrace\",\n\t\"getuid\",\n\t\"syslog\",\n\t\"getgid\",\n\t\"setuid\",\n\t\"setgid\",\n\t\"geteuid\",\n\t\"getegid\",\n\t\"setpgid\",\n\t\"getppid\",\n\t\"getpgrp\",\n\t\"setsid\",\n\t\"setreuid\",\n\t\"setregid\",\n\t\"getgroups\",\n\t\"setgroups\",\n\t\"setresuid\",\n\t\"getresuid\",\n\t\"setresgid\",\n\t\"getresgid\",\n\t\"getpgid\",\n\t\"setfsuid\",\n\t\"setfsgid\",\n\t\"getsid\",\n\t\"capget\",\n\t\"capset\",\n\t\"rt_sigpending\",\n\t\"rt_sigtimedwait\",\n\t\"rt_sigqueueinfo\",\n\t\"rt_sigsuspend\",\n\t\"sigaltstack\",\n\t\"utime\",\n\t\"mknod\",\n\t\"uselib\",\n\t\"personality\",\n\t\"ustat\",\n\t\"statfs\",\n\t\"fstatfs\",\n\t\"sysfs\",\n\t\"getpriority\",\n\t\"setpriority\",\n\t\"sched_setparam\",\n\t\"sched_getparam\",\n\t\"sched_setscheduler\",\n\t\"sched_getscheduler\",\n\t\"sched_get_priority_max\",\n\t\"sched_get_priority_min\",\n\t\"sched_rr_get_interval\",\n\t\"mlock\",\n\t\"munlock\",\n\t\"mlockall\",\n\t\"munlockall\",\n\t\"vhangup\",\n\t\"modify_ldt\",\n\t\"pivot_root\",\n\t\"_sysctl\",\n\t\"prctl\",\n\t\"arch_prctl\",\n\t\"adjtimex\",\n\t\"setrlimit\",\n\t\"chroot\",\n\t\"sync\",\n\t\"acct\",\n\t\"settimeofday\",\n\t\"mount\",\n\t\"umount2\",\n\t\"swapon\",\n\t\"swapoff\",\n\t\"reboot\",\n\t\"sethostname\",\n\t\"setdomainname\",\n\t\"iopl\",\n\t\"ioperm\",\n\t\"create_module\",\n\t\"init_module\",\n\t\"delete_module\",\n\t\"get_kernel_syms\",\n\t\"query_module\",\n\t\"quotactl\",\n\t\"nfsservctl\",\n\t\"getpmsg\",\n\t\"putpmsg\",\n\t\"afs_syscall\",\n\t\"tuxcall\",\n\t\"security\",\n\t\"gettid\",\n\t\"readahead\",\n\t\"setxattr\",\n\t\"lsetxattr\",\n\t\"fsetxattr\",\n\t\"getxattr\",\n\t\"lgetxattr\",\n\t\"fgetxattr\",\n\t\"listxattr\",\n\t\"llistxattr\",\n\t\"flistxattr\",\n\t\"removexattr\",\n\t\"lremovexattr\",\n\t\"fremovexattr\",\n\t\"tkill\",\n\t\"time\",\n\t\"futex\",\n\t\"sched_setaffinity\",\n\t\"sched_getaffinity\",\n\t\"set_thread_area\",\n\t\"io_setup\",\n\t\"io_destroy\",\n\t\"io_getevents\",\n\t\"io_submit\",\n\t\"io_cancel\",\n\t\"get_thread_area\",\n\t\"lookup_dcookie\",\n\t\"epoll_create\",\n\t\"epoll_ctl_old\",\n\t\"epoll_wait_old\",\n\t\"remap_file_pages\",\n\t\"getdents64\",\n\t\"set_tid_address\",\n\t\"restart_syscall\",\n\t\"semtimedop\",\n\t\"fadvise64\",\n\t\"timer_create\",\n\t\"timer_settime\",\n\t\"timer_gettime\",\n\t\"timer_getoverrun\",\n\t\"timer_delete\",\n\t\"clock_settime\",\n\t\"clock_gettime\",\n\t\"clock_getres\",\n\t\"clock_nanosleep\",\n\t\"exit_group\",\n\t\"epoll_wait\",\n\t\"epoll_ctl\",\n\t\"tgkill\",\n\t\"utimes\",\n\t\"vserver\",\n\t\"mbind\",\n\t\"set_mempolicy\",\n\t\"get_mempolicy\",\n\t\"mq_open\",\n\t\"mq_unlink\",\n\t\"mq_timedsend\",\n\t\"mq_timedreceive\",\n\t\"mq_notify\",\n\t\"mq_getsetattr\",\n\t\"kexec_load\",\n\t\"waitid\",\n\t\"add_key\",\n\t\"request_key\",\n\t\"keyctl\",\n\t\"ioprio_set\",\n\t\"ioprio_get\",\n\t\"inotify_init\",\n\t\"inotify_add_watch\",\n\t\"inotify_rm_watch\",\n\t\"migrate_pages\",\n\t\"openat\",\n\t\"mkdirat\",\n\t\"mknodat\",\n\t\"fchownat\",\n\t\"futimesat\",\n\t\"newfstatat\",\n\t\"unlinkat\",\n\t\"renameat\",\n\t\"linkat\",\n\t\"symlinkat\",\n\t\"readlinkat\",\n\t\"fchmodat\",\n\t\"faccessat\",\n\t\"pselect6\",\n\t\"ppoll\",\n\t\"unshare\",\n\t\"set_robust_list\",\n\t\"get_robust_list\",\n\t\"splice\",\n\t\"tee\",\n\t\"sync_file_range\",\n\t\"vmsplice\",\n\t\"move_pages\",\n\t\"utimensat\",\n\t\"epoll_pwait\",\n\t\"signalfd\",\n\t\"timerfd_create\",\n\t\"eventfd\",\n\t\"fallocate\",\n\t\"timerfd_settime\",\n\t\"timerfd_gettime\",\n\t\"accept4\",\n\t\"signalfd4\",\n\t\"eventfd2\",\n\t\"epoll_create1\",\n\t\"dup3\",\n\t\"pipe2\",\n\t\"inotify_init1\",\n\t\"preadv\",\n\t\"pwritev\",\n\t\"rt_tgsigqueueinfo\",\n\t\"perf_event_open\",\n\t\"recvmmsg\",\n\t\"fanotify_init\",\n\t\"fanotify_mark\",\n\t\"prlimit64\",\n\t\"name_to_handle_at\",\n\t\"open_by_handle_at\",\n\t\"clock_adjtime\",\n\t\"syncfs\",\n\t\"sendmmsg\",\n\t\"setns\",\n\t\"getcpu\",\n\t\"process_vm_readv\",\n\t\"process_vm_writev\",\n\t\"kcmp\",\n\t\"finit_module\",\n\t\"sched_setattr\",\n\t\"sched_getattr\",\n\t\"renameat2\",\n\t\"seccomp\",\n\t\"getrandom\",\n\t\"memfd_create\",\n\t\"kexec_file_load\",\n\t\"bpf\",\n\t\"execveat\",\n\t\"userfaultfd\",\n\t\"membarrier\",\n\t\"mlock2\",\n\t\"copy_file_range\",\n\t\"preadv2\",\n\t\"pwritev2\",\n\t\"pkey_mprotect\",\n\t\"pkey_alloc\",\n\t\"pkey_free\",\n\t\"statx\",\n\t\"io_pgetevents\",\n\t\"rseq\",\n\t\"reserved.335\",\n\t\"reserved.336\",\n\t\"reserved.337\",\n\t\"reserved.338\",\n\t\"reserved.339\",\n\t\"reserved.340\",\n\t\"reserved.341\",\n\t\"reserved.342\",\n\t\"reserved.343\",\n\t\"reserved.344\",\n\t\"reserved.345\",\n\t\"reserved.346\",\n\t\"reserved.347\",\n\t\"reserved.348\",\n\t\"reserved.349\",\n\t\"reserved.350\",\n\t\"reserved.351\",\n\t\"reserved.352\",\n\t\"reserved.353\",\n\t\"reserved.354\",\n\t\"reserved.355\",\n\t\"reserved.356\",\n\t\"reserved.357\",\n\t\"reserved.358\",\n\t\"reserved.359\",\n\t\"reserved.360\",\n\t\"reserved.361\",\n\t\"reserved.362\",\n\t\"reserved.363\",\n\t\"reserved.364\",\n\t\"reserved.365\",\n\t\"reserved.366\",\n\t\"reserved.367\",\n\t\"reserved.368\",\n\t\"reserved.369\",\n\t\"reserved.370\",\n\t\"reserved.371\",\n\t\"reserved.372\",\n\t\"reserved.373\",\n\t\"reserved.374\",\n\t\"reserved.375\",\n\t\"reserved.376\",\n\t\"reserved.377\",\n\t\"reserved.378\",\n\t\"reserved.379\",\n\t\"reserved.380\",\n\t\"reserved.381\",\n\t\"reserved.382\",\n\t\"reserved.383\",\n\t\"reserved.384\",\n\t\"reserved.385\",\n\t\"reserved.386\",\n\t\"reserved.387\",\n\t\"reserved.388\",\n\t\"reserved.389\",\n\t\"reserved.390\",\n\t\"reserved.391\",\n\t\"reserved.392\",\n\t\"reserved.393\",\n\t\"reserved.394\",\n\t\"reserved.395\",\n\t\"reserved.396\",\n\t\"reserved.397\",\n\t\"reserved.398\",\n\t\"reserved.399\",\n\t\"reserved.400\",\n\t\"reserved.401\",\n\t\"reserved.402\",\n\t\"reserved.403\",\n\t\"reserved.404\",\n\t\"reserved.405\",\n\t\"reserved.406\",\n\t\"reserved.407\",\n\t\"reserved.408\",\n\t\"reserved.409\",\n\t\"reserved.410\",\n\t\"reserved.411\",\n\t\"reserved.412\",\n\t\"reserved.413\",\n\t\"reserved.414\",\n\t\"reserved.415\",\n\t\"reserved.416\",\n\t\"reserved.417\",\n\t\"reserved.418\",\n\t\"reserved.419\",\n\t\"reserved.420\",\n\t\"reserved.421\",\n\t\"reserved.422\",\n\t\"reserved.423\",\n\t\"pidfd_send_signal\",\n\t\"io_uring_setup\",\n\t\"io_uring_enter\",\n\t\"io_uring_register\",\n\t\"open_tree\",\n\t\"move_mount\",\n\t\"fsopen\",\n\t\"fsconfig\",\n\t\"fsmount\",\n\t\"fspick\",\n\t\"pidfd_open\",\n\t\"clone3\", //435\n}\n\nfunc callNameX86Family64(num uint32) string {\n\tif num > SyscallX86MaxNum64 {\n\t\treturn SyscallX86UnknownName\n\t}\n\n\treturn syscallNumTableX86Family64[num]\n}\n\nfunc callNumTableIsOkX86Family64() bool {\n\tif (len(syscallNumTableX86Family64) == SyscallX86MaxNum64+1) &&\n\t\tsyscallNumTableX86Family64[SyscallX86MaxNum64] == SyscallX86LastName64 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc callNumberX86Family64(name string) (uint32, bool) {\n\tnum, ok := syscallNameTableX86Family64[name]\n\treturn num, ok\n}\n\nvar syscallNameTableX86Family64 map[string]uint32\n\nfunc init() {\n\tsyscallNameTableX86Family64 = make(map[string]uint32, len(syscallNumTableX86Family64))\n\n\tfor callNum, callName := range syscallNumTableX86Family64 {\n\t\tsyscallNameTableX86Family64[callName] = uint32(callNum)\n\t}\n}\n"
  },
  {
    "path": "pkg/system/system.go",
    "content": "package system\n\nimport (\n\t\"os/user\"\n\t\"strconv\"\n)\n\ntype SystemInfo struct {\n\tSysname    string\n\tNodename   string\n\tRelease    string\n\tVersion    string\n\tMachine    string\n\tDomainname string\n\tOsBuild    string\n\tDistro     DistroInfo\n}\n\ntype DistroInfo struct {\n\tName        string `json:\"name\"`\n\tVersion     string `json:\"version\"`\n\tDisplayName string `json:\"display_name\"`\n}\n\nfunc ResolveUser(identity string) (uid uint32, gid uint32, home string, err error) {\n\tvar userInfo *user.User\n\tif _, err := strconv.ParseUint(identity, 10, 32); err == nil {\n\t\tuserInfo, err = user.LookupId(identity)\n\t\tif err != nil {\n\t\t\treturn 0, 0, \"\", err\n\t\t}\n\t} else {\n\t\tuserInfo, err = user.Lookup(identity)\n\t\tif err != nil {\n\t\t\treturn 0, 0, \"\", err\n\t\t}\n\t}\n\n\tuid64, err := strconv.ParseUint(userInfo.Uid, 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, \"\", err\n\t}\n\n\tgid64, err := strconv.ParseUint(userInfo.Gid, 10, 32)\n\tif err != nil {\n\t\treturn 0, 0, \"\", err\n\t}\n\n\treturn uint32(uid64), uint32(gid64), userInfo.HomeDir, nil\n}\n\nfunc ResolveGroup(identity string) (uint32, error) {\n\tvar groupInfo *user.Group\n\tif _, err := strconv.ParseUint(identity, 10, 32); err == nil {\n\t\tgroupInfo, err = user.LookupGroupId(identity)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t} else {\n\t\tgroupInfo, err = user.LookupGroup(identity)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\n\tgid, err := strconv.ParseUint(groupInfo.Gid, 10, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn uint32(gid), nil\n}\n"
  },
  {
    "path": "pkg/system/system_darwin.go",
    "content": "package system\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n)\n\nfunc newSystemInfo() SystemInfo {\n\tvar sysInfo SystemInfo\n\n\tsysInfo.Sysname = runtime.GOOS\n\tsysInfo.Nodename, _ = os.Hostname()\n\n\tif machineInfo, err := syscall.Sysctl(\"hw.machine\"); err == nil {\n\t\tsysInfo.Machine = machineInfo\n\t}\n\n\tif releaseInfo, err := syscall.Sysctl(\"kern.osrelease\"); err == nil {\n\t\trparts := strings.SplitN(releaseInfo, \".\", 3)\n\t\tif len(rparts) == 3 {\n\t\t\tmajor, _ := strconv.ParseUint(rparts[0], 10, 64)\n\t\t\tminor, _ := strconv.ParseUint(rparts[1], 10, 64)\n\n\t\t\tsysInfo.Distro = DistroInfo{\n\t\t\t\tDisplayName: osName(major, minor),\n\t\t\t}\n\t\t}\n\n\t\tsysInfo.Release = releaseInfo\n\t}\n\n\tif versionInfo, err := syscall.Sysctl(\"kern.version\"); err == nil {\n\t\tvparts := strings.SplitN(versionInfo, \":\", 2)\n\t\tif len(vparts) == 2 {\n\t\t\tsysInfo.Version = vparts[1]\n\t\t}\n\t}\n\n\tif buildInfo, err := syscall.Sysctl(\"kern.osversion\"); err == nil {\n\t\tsysInfo.OsBuild = buildInfo\n\t}\n\n\treturn sysInfo\n}\n\nvar defaultSysInfo = newSystemInfo()\n\nfunc GetSystemInfo() SystemInfo {\n\treturn defaultSysInfo\n}\n\nfunc osName(major, minor uint64) string {\n\tif info, ok := osNames[major]; ok {\n\t\treturn fmt.Sprintf(\"%v (%v%v)\", info.name, info.numPrefix, minor)\n\t}\n\n\treturn \"other\"\n}\n\n// Mac OS X version names and numbers:\n// https://support.apple.com/en-us/HT201260\n// https://en.wikipedia.org/wiki/MacOS_version_history\nvar osNames = map[uint64]struct {\n\tname, numPrefix string\n}{\n\t4:  {\"Cheetah\", \"10.0.\"},\n\t5:  {\"Puma\", \"10.1.\"},\n\t6:  {\"Jaguar\", \"10.2.\"},\n\t7:  {\"Panther\", \"10.3.\"},\n\t8:  {\"Tiger\", \"10.4.\"},\n\t9:  {\"Leopard\", \"10.5.\"},\n\t10: {\"Snow Leopard\", \"10.6.\"},\n\t11: {\"Lion\", \"10.7.\"},\n\t12: {\"Mountain Lion\", \"10.8.\"},\n\t13: {\"Mavericks\", \"10.9.\"},\n\t14: {\"Yosemite\", \"10.10.\"},\n\t15: {\"El Capitan\", \"10.11.\"},\n\t16: {\"Sierra\", \"10.12.\"},\n\t17: {\"High Sierra\", \"10.13.\"},\n\t18: {\"Mojave\", \"10.14.\"},\n\t19: {\"Catalina\", \"10.15.\"},\n\t20: {\"Big Sur\", \"11.\"},\n\t21: {\"Monterey\", \"12.\"},\n\t22: {\"Ventura\", \"13.\"},\n\t23: {\"Sonoma\", \"14.\"},\n}\n"
  },
  {
    "path": "pkg/system/system_linux.go",
    "content": "package system\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc newSystemInfo() SystemInfo {\n\tvar sysInfo SystemInfo\n\tvar unameInfo syscall.Utsname\n\n\tif err := syscall.Uname(&unameInfo); err != nil {\n\t\treturn sysInfo\n\t}\n\n\tsysInfo.Sysname = nativeCharsToString(unameInfo.Sysname)\n\tsysInfo.Nodename = nativeCharsToString(unameInfo.Nodename)\n\tsysInfo.Machine = nativeCharsToString(unameInfo.Machine)\n\tsysInfo.Domainname = nativeCharsToString(unameInfo.Domainname)\n\t//kernel info\n\tsysInfo.Release = nativeCharsToString(unameInfo.Release)\n\tsysInfo.Version = nativeCharsToString(unameInfo.Version)\n\t//distro info\n\tsysInfo.Distro = distroInfo()\n\n\treturn sysInfo\n}\n\nvar defaultSysInfo = newSystemInfo()\n\nfunc GetSystemInfo() SystemInfo {\n\treturn defaultSysInfo\n}\n\nfunc distroInfo() DistroInfo {\n\tdistro := DistroInfo{\n\t\tName:        \"unknown\",\n\t\tDisplayName: \"unknown\",\n\t}\n\n\tbdata, err := os.ReadFile(OSReleaseFile)\n\tif err != nil {\n\t\treturn distro\n\t}\n\n\tif osr, err := NewOsRelease(bdata); err == nil {\n\t\tvar nameMain, nameVersion string\n\n\t\tdistro.Name = osr.Name\n\t\tdistro.Version = osr.VersionID\n\t\tif distro.Version == \"\" {\n\t\t\tdistro.Version = osr.Version\n\t\t}\n\n\t\tdistro.DisplayName = osr.PrettyName\n\t\tif distro.DisplayName == \"\" {\n\t\t\tnameMain = osr.Name\n\t\t\tif len(osr.Version) > 0 {\n\t\t\t\tnameVersion = osr.Version\n\t\t\t} else {\n\t\t\t\tnameVersion = osr.VersionID\n\t\t\t}\n\n\t\t\tdistro.DisplayName = fmt.Sprintf(\"%v %v\", nameMain, nameVersion)\n\t\t}\n\n\t\treturn distro\n\t}\n\n\tdistro.Name = \"other\"\n\tdistro.DisplayName = \"other\"\n\n\treturn distro\n}\n\n/*\nfunc getOperatingSystem() string {\n\tbdata, err := os.ReadFile(\"/etc/os-release\")\n\tif err != nil {\n\t\tprint(\"error reading /etc/os-release\")\n\t\treturn \"\"\n\t}\n\n\tvar nameMain, nameVersion string\n\n\tif i := bytes.Index(bdata, []byte(\"NAME\")); i >= 0 {\n\t\toffset := i+ len(\"NAME\") + 2\n\t\tnameData = bdata[offset:]\n\t\tnameMain = string(nameData[:bytes.IndexByte(nameData, '\"')])\n\t}\n\n\tif i := bytes.Index(bdata, []byte(\"VERSION\")); i >= 0 {\n\t\toffset := i+ len(\"VERSION\") + 2\n\t\tnameData = bdata[offset:]\n\t\tnameMain = string(nameData[:bytes.IndexByte(nameData, '\"')])\n\t} else {\n\t\tif i := bytes.Index(bdata, []byte(\"VERSION_ID\")); i >= 0 {\n\t\t\t//version id could be with or without quotes\n\t\t\toffset := i+ len(\"VERSION_ID\") + 2\n\t\t\tnameData = bdata[offset:]\n\t\t\tnameMain = string(nameData[:bytes.IndexByte(nameData, '\"')])\n\t\t}\n\t}\n\n\treturn fmt.Sprintf(\"%v %v\",nameMain,nameVersion)\n}\n*/\n"
  },
  {
    "path": "pkg/system/system_linux_amd64.go",
    "content": "package system\n\nimport (\n\t\"syscall\"\n)\n\n/*\nAMD64/X86_64 SYSCALL REGISTER USE:\n\nSyscall Number:   rax\nReturn Value:     rax\n1st Param (arg0): rdi\n2nd Param (arg1): rsi\n3rd Param (arg2): rdx\n4th Param (arg3): r10\n5th Param (arg4): r8\n6th Param (arg5): r9\n\n*/\n\nfunc LookupCallName(num uint32) string {\n\treturn callNameX86Family64(num)\n}\n\nfunc LookupCallNumber(name string) (uint32, bool) {\n\treturn callNumberX86Family64(name)\n}\n\nfunc CallNumber(regs syscall.PtraceRegs) uint64 {\n\treturn regs.Orig_rax\n}\n\nfunc CallReturnValue(regs syscall.PtraceRegs) uint64 {\n\treturn regs.Rax\n}\n\nfunc CallFirstParam(regs syscall.PtraceRegs) uint64 {\n\treturn regs.Rdi\n}\n\nfunc CallSecondParam(regs syscall.PtraceRegs) uint64 {\n\treturn regs.Rsi\n}\n\nfunc CallThirdParam(regs syscall.PtraceRegs) uint64 {\n\treturn regs.Rdx\n}\n\nfunc CallFourthParam(regs syscall.PtraceRegs) uint64 {\n\treturn regs.Rcx\n}\n\n/*\nX86_32 SYSCALL REGISTER USE:\n\nSyscall Number:   eax\nReturn Value:     eax\n1st Param (arg0): ebx\n2nd Param (arg1): ecx\n3rd Param (arg2): edx\n4th Param (arg3): esi\n5th Param (arg4): edi\n6th Param (arg5): ebp\n\n*/\n"
  },
  {
    "path": "pkg/system/system_linux_arm.go",
    "content": "package system\n\nimport (\n\t\"syscall\"\n)\n\n/*\nARM SYSCALL REGISTER USE:\n\nSyscall Number:   r7\nReturn Value:     r0\n1st Param (arg0): r0\n2nd Param (arg1): r1\n3rd Param (arg2): r2\n4th Param (arg3): r3\n5th Param (arg4): r4\n6th Param (arg5): r5\n\n*/\n\nfunc LookupCallName(num uint32) string {\n\treturn callNameArmFamily32(num)\n}\n\nfunc LookupCallNumber(name string) (uint32, bool) {\n\treturn callNumberArmFamily32(name)\n}\n\nfunc CallNumber(regs syscall.PtraceRegs) uint64 {\n\treturn uint64(regs.Uregs[7])\n}\n\nfunc CallReturnValue(regs syscall.PtraceRegs) uint64 {\n\treturn uint64(regs.Uregs[0])\n}\n\nfunc CallFirstParam(regs syscall.PtraceRegs) uint64 {\n\treturn uint64(regs.Uregs[0])\n}\n\nfunc CallSecondParam(regs syscall.PtraceRegs) uint64 {\n\treturn uint64(regs.Uregs[1])\n}\n"
  },
  {
    "path": "pkg/system/system_linux_arm64.go",
    "content": "package system\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\n/*\nARM64 SYSCALL REGISTER USE:\n\nSyscall Number:   x8\nReturn Value:     x0\n1st Param (arg0): x0\n2nd Param (arg1): x1\n3rd Param (arg2): x2\n4th Param (arg3): x3\n5th Param (arg4): x4\n6th Param (arg5): x5\n\n*/\n\nfunc LookupCallName(num uint32) string {\n\treturn callNameArmFamily64(num)\n}\n\nfunc LookupCallNumber(name string) (uint32, bool) {\n\treturn callNumberArmFamily64(name)\n}\n\nfunc CallNumber(regs unix.PtraceRegsArm64) uint64 {\n\treturn uint64(regs.Regs[8])\n}\n\nfunc CallReturnValue(regs unix.PtraceRegsArm64) uint64 {\n\treturn uint64(regs.Regs[0])\n}\n\nfunc CallFirstParam(regs unix.PtraceRegsArm64) uint64 {\n\treturn uint64(regs.Regs[0])\n}\n\nfunc CallSecondParam(regs unix.PtraceRegsArm64) uint64 {\n\treturn uint64(regs.Regs[1])\n}\n"
  },
  {
    "path": "pkg/test/e2e/sensor/docker.go",
    "content": "package sensor\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strconv\"\n\t\"syscall\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc imagePull(ctx context.Context, name string) error {\n\t_, err := docker(ctx, \"image\", \"pull\", name)\n\treturn err\n}\n\nfunc imageInspect(ctx context.Context, name string) (dockerapi.Image, error) {\n\tout, err := docker(ctx, \"image\", \"inspect\", name)\n\tif err != nil {\n\t\treturn dockerapi.Image{}, err\n\t}\n\n\tvar images []dockerapi.Image\n\tif err := json.Unmarshal([]byte(out), &images); err != nil {\n\t\treturn dockerapi.Image{}, fmt.Errorf(\"cannot decode docker command output %q: %w\", out, err)\n\t}\n\n\tif len(images) > 1 {\n\t\treturn dockerapi.Image{}, fmt.Errorf(\"ambiguous image name %q\", name)\n\t}\n\n\treturn images[0], nil\n}\n\nfunc containerCreate(\n\tctx context.Context,\n\tflags []string,\n\timage string,\n\targ ...string,\n) (string, error) {\n\ttail := append([]string{\"create\"}, flags...)\n\ttail = append(tail, image)\n\ttail = append(tail, arg...)\n\treturn docker(ctx, \"container\", tail...)\n}\n\nfunc containerStart(ctx context.Context, contID string) error {\n\t_, err := docker(ctx, \"container\", \"start\", contID)\n\treturn err\n}\n\nfunc containerWait(ctx context.Context, contID string) (int, error) {\n\tout, err := docker(ctx, \"container\", \"wait\", contID)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\n\texitCode, err := strconv.Atoi(string(out))\n\tif err != nil {\n\t\treturn -1, fmt.Errorf(\"unexpected container wait output %q - expected number (exit code)\", string(out))\n\t}\n\treturn exitCode, nil\n}\n\nfunc containerKill(ctx context.Context, contID string, sig syscall.Signal) error {\n\t_, err := docker(ctx, \"container\", \"kill\", \"-s\", unix.SignalName(sig), contID)\n\treturn err\n}\n\nfunc containerRemove(ctx context.Context, contID string) error {\n\t_, err := docker(ctx, \"container\", \"rm\", contID)\n\treturn err\n}\n\nfunc containerInspect(ctx context.Context, contID string) (dockerapi.Container, error) {\n\tout, err := docker(ctx, \"container\", \"inspect\", contID)\n\tif err != nil {\n\t\treturn dockerapi.Container{}, err\n\t}\n\n\tvar conts []dockerapi.Container\n\tif err := json.Unmarshal([]byte(out), &conts); err != nil {\n\t\treturn dockerapi.Container{}, fmt.Errorf(\"cannot decode docker command output %q: %w\", out, err)\n\t}\n\n\tif len(conts) > 1 {\n\t\treturn dockerapi.Container{}, fmt.Errorf(\"ambiguous container id/name %q\", contID)\n\t}\n\n\treturn conts[0], nil\n}\n\nfunc containerExec(ctx context.Context, contID string, arg ...string) (string, error) {\n\tcmd := exec.CommandContext(ctx, \"docker\", append([]string{\"container\", \"exec\", contID}, arg...)...)\n\n\tlog.Debug(\"Executing: \", cmd.String())\n\n\tout, err := cmd.CombinedOutput()\n\treturn string(out), err\n}\n\nfunc containerLogs(ctx context.Context, contID string) (string, error) {\n\tcmd := exec.CommandContext(ctx, \"docker\", \"container\", \"logs\", contID)\n\n\tlog.Debug(\"Executing: \", cmd.String())\n\n\tout, err := cmd.CombinedOutput()\n\treturn string(out), err\n}\n\nfunc containerCopyFrom(ctx context.Context, contID, orig, dest string) error {\n\t_, err := docker(ctx, \"container\", \"cp\", contID+\":\"+orig, dest)\n\treturn err\n}\n\nfunc docker(ctx context.Context, command string, arg ...string) (string, error) {\n\tcmd := exec.CommandContext(ctx, \"docker\", append([]string{command}, arg...)...)\n\tcmd.Stderr = os.Stderr\n\n\tlog.Debug(\"Executing: \", cmd.String())\n\n\tout, err := cmd.Output()\n\tif len(out) > 0 {\n\t\treturn string(bytes.Trim(out, \" \\t\\r\\n\")), err\n\t}\n\treturn \"\", err\n}\n"
  },
  {
    "path": "pkg/test/e2e/sensor/monitor.go",
    "content": "package sensor\n\nimport (\n\tmastercommand \"github.com/slimtoolkit/slim/pkg/app/master/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n)\n\ntype StartMonitorOpt func(*command.StartMonitor)\n\nfunc WithSaneDefaults() StartMonitorOpt {\n\treturn func(cmd *command.StartMonitor) {\n\t\tcmd.RTASourcePT = true\n\t\tcmd.KeepPerms = true\n\t\tcmd.IncludeCertAll = true\n\t\tcmd.IncludeCertBundles = true\n\t\tcmd.IncludeCertDirs = true\n\t\tcmd.IncludeCertPKAll = true\n\t\tcmd.IncludeCertPKDirs = true\n\t\tcmd.IncludeNew = true\n\t}\n}\n\nfunc WithAppNameArgs(name string, arg ...string) StartMonitorOpt {\n\treturn func(cmd *command.StartMonitor) {\n\t\tcmd.AppName = name\n\t\tcmd.AppArgs = arg\n\t}\n}\n\nfunc WithAppUser(user string) StartMonitorOpt {\n\treturn func(cmd *command.StartMonitor) {\n\t\tcmd.AppUser = user\n\t\tcmd.RunTargetAsUser = true\n\t}\n}\n\nfunc WithAppStdoutToFile() StartMonitorOpt {\n\treturn func(cmd *command.StartMonitor) {\n\t\tcmd.AppStdoutToFile = true\n\t}\n}\n\nfunc WithAppStderrToFile() StartMonitorOpt {\n\treturn func(cmd *command.StartMonitor) {\n\t\tcmd.AppStderrToFile = true\n\t}\n}\n\nfunc WithPreserves(path ...string) StartMonitorOpt {\n\treturn func(cmd *command.StartMonitor) {\n\t\tcmd.Preserves = mastercommand.ParsePaths(path)\n\t}\n}\n\nfunc NewMonitorStartCommand(opts ...StartMonitorOpt) command.StartMonitor {\n\tcmd := command.StartMonitor{}\n\n\tfor _, opt := range opts {\n\t\topt(&cmd)\n\t}\n\n\treturn cmd\n}\n"
  },
  {
    "path": "pkg/test/e2e/sensor/sensor.go",
    "content": "package sensor\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\t\"testing\"\n\t\"time\"\n\n\tdockerapi \"github.com/fsouza/go-dockerclient\"\n\tlog \"github.com/sirupsen/logrus\"\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/ipc\"\n\t\"github.com/slimtoolkit/slim/pkg/app/master/inspectors/sensor\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/standalone/control\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/channel\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n\t\"github.com/slimtoolkit/slim/pkg/util/fsutil\"\n)\n\nconst (\n\t// Intentionally duplicating values here since to make sure a refactoing\n\t// of the paths on the sensor side won't be unnoticed.\n\tCommandsFileName  = \"commands.json\"\n\tSensorLogFileName = \"sensor.log\"\n\tMondelFileName    = \"mondel.ndjson\"\n\tAppStdoutFileName = \"app_stdout.log\"\n\tAppStderrFileName = \"app_stderr.log\"\n\tEventsFileName    = \"events.json\"\n\trunArchiveName    = \"run.tar\"\n\n\tsensorExePath = \"/opt/_slim/sensor\"\n)\n\nvar (\n\terrNotStarted error = errors.New(\"test sensor container hasn't been started yet\")\n)\n\ntype sensorOpt func(*Sensor)\n\nfunc WithSensorLogsToFile() sensorOpt {\n\treturn func(s *Sensor) {\n\t\ts.useLogFile = true\n\t}\n}\n\nfunc WithEnableMondel() sensorOpt {\n\treturn func(s *Sensor) {\n\t\ts.enableMondel = true\n\t}\n}\n\nfunc WithSensorArtifactsDir(dir string) sensorOpt {\n\treturn func(s *Sensor) {\n\t\ts.artifactsDirPath = dir\n\t}\n}\n\nfunc WithSensorLifecycleHook(cmd string) sensorOpt {\n\treturn func(s *Sensor) {\n\t\ts.lifecycleHook = cmd\n\t}\n}\n\nfunc WithSensorCapabilities(caps ...string) sensorOpt {\n\treturn func(s *Sensor) {\n\t\ts.capAdd = caps\n\t}\n}\n\nfunc WithoutSensorCapabilities(caps ...string) sensorOpt {\n\treturn func(s *Sensor) {\n\t\ts.capDrop = caps\n\t}\n}\n\nfunc WithStopSignal(sig syscall.Signal) sensorOpt {\n\treturn func(s *Sensor) {\n\t\ts.stopSignal = sig\n\t}\n}\n\ntype Sensor struct {\n\timage          dockerapi.Image\n\tcontName       string\n\tsensorExePath  string\n\tcontextDirPath string\n\n\t// \"Opts\"\n\tuseLogFile       bool\n\tenableMondel     bool\n\tartifactsDirPath string\n\tlifecycleHook    string\n\tcapAdd           []string\n\tcapDrop          []string\n\tuser             string\n\tstopSignal       syscall.Signal\n\n\t// \"Nullable\"\n\tcontID      string\n\trawCommands string\n\tclient      *ipc.Client\n\tstopped     bool\n\n\t// \"Artifacts\"\n\tcreport    *report.ContainerReport\n\trawCReport string\n\trawEvents  string\n\tmondel     []report.MonitorDataEvent\n\trawMondel  string\n}\n\nfunc NewSensor(\n\tctx context.Context,\n\tcontextDirPath string,\n\tcontName string,\n\timageName string,\n\topts ...sensorOpt,\n) (*Sensor, error) {\n\tsensorExePath, err := exec.LookPath(sensor.LocalBinFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot locate %s executable on the host system\", sensor.LocalBinFile)\n\t}\n\n\tif err := imagePull(ctx, imageName); err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot pull image %q: %w\", imageName, err)\n\t}\n\n\timage, err := imageInspect(ctx, imageName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot inspect image %q: %w\", imageName, err)\n\t}\n\n\tlog.\n\t\tWithField(\"image\", imageName).\n\t\tWithField(\"context\", contextDirPath).\n\t\tWithField(\"exe\", sensorExePath).\n\t\tDebug(\"New test sensor created\")\n\n\ts := &Sensor{\n\t\timage:          image,\n\t\tcontName:       strings.ToLower(contName),\n\t\tsensorExePath:  sensorExePath,\n\t\tcontextDirPath: contextDirPath,\n\t\tcapAdd:         []string{\"ALL\"},\n\t\tuser:           \"0\",\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(s)\n\t}\n\n\treturn s, nil\n}\n\nfunc NewSensorOrFail(\n\tt *testing.T,\n\tctx context.Context,\n\tcontextDirPath string,\n\tcontName string,\n\timageName string,\n\topts ...sensorOpt,\n) *Sensor {\n\ts, err := NewSensor(ctx, contextDirPath, contName, imageName, opts...)\n\tif err != nil {\n\t\tt.Fatal(\"Cannot initialize sensor:\", err)\n\t}\n\treturn s\n}\n\nfunc (s *Sensor) StartControlled(ctx context.Context) error {\n\tlog.Debug(\"Starting test sensor (controlled mode)...\")\n\n\tcontID, err := containerCreate(\n\t\tctx,\n\t\tflatten(\n\t\t\ts.capabilities(),\n\t\t\t[]string{\n\t\t\t\t\"--name\", s.contName,\n\t\t\t\t\"--user\", s.user,\n\t\t\t\t\"--volume\", s.sensorExePath + \":\" + sensorExePath,\n\t\t\t\t\"--publish\", fmt.Sprintf(\"%d\", channel.CmdPort),\n\t\t\t\t\"--publish\", fmt.Sprintf(\"%d\", channel.EvtPort),\n\t\t\t\t\"--entrypoint\", sensorExePath,\n\t\t\t},\n\t\t),\n\t\ts.image.ID,\n\t\ts.commonStartFlags()...,\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot create target container (controlled mode): %w\", err)\n\t}\n\n\tlog.WithField(\"containerId\", contID).Debug(\"Test sensor container created (controlled mode)\")\n\ts.contID = contID\n\n\tif err := containerStart(ctx, s.contID); err != nil {\n\t\treturn fmt.Errorf(\"cannot start target container (controlled mode): %w\", err)\n\t}\n\n\tlog.WithField(\"containerId\", contID).Debug(\"Test sensor container started (controlled mode)\")\n\n\tcont, err := containerInspect(ctx, s.contID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot inspect container %q: %w\", s.contID, err)\n\t}\n\n\tcmdPort, ok := hostPort(cont, channel.CmdPort)\n\tif !ok {\n\t\treturn fmt.Errorf(\"container %q - no host port found for port %d\", s.contID, channel.CmdPort)\n\t}\n\tevtPort, ok := hostPort(cont, channel.EvtPort)\n\tif !ok {\n\t\treturn fmt.Errorf(\"container %q - no host port found for port %d\", s.contID, channel.EvtPort)\n\t}\n\n\t// TODO: Refactor the IPC code to use context with a deadline.\n\tclient, err := ipc.NewClient(\"127.0.0.1\", cmdPort, evtPort, 10) // Seconds, I guess\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot start IPC client: %w\", err)\n\t}\n\n\tlog.\n\t\tWithField(\"containerId\", contID).\n\t\tDebug(\"IPC client connected to the target container\")\n\ts.client = client\n\n\treturn nil\n}\n\nfunc (s *Sensor) StartControlledOrFail(t *testing.T, ctx context.Context) {\n\tif err := s.StartControlled(ctx); err != nil {\n\t\tt.Fatal(\"Cannot start sensor (controlled mode):\", err)\n\t}\n}\n\nfunc (s *Sensor) StartStandalone(\n\tctx context.Context,\n\trunArgs []string,\n\tcmdOverride ...command.StartMonitor,\n) error {\n\tcmd := startCommandStandalone(s.image, cmdOverride...)\n\tlog.\n\t\tWithField(\"command\", fmt.Sprintf(\"%+v\", cmd)).\n\t\tDebug(\"Starting test sensor (standalone mode)...\")\n\n\tcommandsFilePath := filepath.Join(s.contextDirPath, CommandsFileName)\n\tif err := jsonDump(commandsFilePath, cmd); err != nil {\n\t\treturn fmt.Errorf(\"cannot create %s file: %w\", CommandsFileName, err)\n\t}\n\n\trawCommands, err := os.ReadFile(commandsFilePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot re-read %s file: %w\", CommandsFileName, err)\n\t}\n\ts.rawCommands = string(rawCommands)\n\n\tstopSignal := \"SIGTERM\"\n\tif s.stopSignal != 0 {\n\t\tstopSignal = unix.SignalName(s.stopSignal)\n\t} else if len(s.image.Config.StopSignal) > 0 {\n\t\tstopSignal = s.image.Config.StopSignal\n\t}\n\n\tstopTimeout := 5 * time.Second\n\tif s.image.Config.StopTimeout != 0 {\n\t\t// TODO: Make sure we never pass 0s.\n\t\tstopTimeout = time.Duration(s.image.Config.StopTimeout/2) * time.Second\n\t}\n\n\tcontID, err := containerCreate(\n\t\tctx,\n\t\tflatten(\n\t\t\ts.capabilities(),\n\t\t\t[]string{\n\t\t\t\t\"--name\", s.contName,\n\t\t\t\t\"--user\", s.user,\n\t\t\t\t\"--volume\", s.sensorExePath + \":\" + sensorExePath,\n\t\t\t\t\"--volume\", commandsFilePath + \":/opt/_slim/commands.json\",\n\t\t\t\t\"--entrypoint\", sensorExePath,\n\t\t\t},\n\t\t),\n\t\ts.image.ID,\n\t\tflatten(\n\t\t\ts.commonStartFlags(),\n\t\t\t// Standalone flags\n\t\t\t[]string{\n\t\t\t\t\"-m\", \"standalone\",\n\t\t\t\t\"-c\", \"/opt/_slim/commands.json\",\n\t\t\t\t\"-s\", stopSignal,\n\t\t\t\t\"-w\", stopTimeout.String(),\n\t\t\t\t\"--\",\n\t\t\t},\n\t\t\trunArgs,\n\t\t)...,\n\t)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot create target container (standalone mode): %w\", err)\n\t}\n\n\tlog.WithField(\"containerId\", contID).Debug(\"Test sensor container created (standalone mode)\")\n\ts.contID = contID\n\n\tif err := containerStart(ctx, s.contID); err != nil {\n\t\treturn fmt.Errorf(\"cannot start target container (standalone mode): %w\", err)\n\t}\n\n\tlog.WithField(\"containerId\", contID).Debug(\"Test sensor container started (standalone mode)\")\n\n\treturn nil\n}\n\nfunc (s *Sensor) StartStandaloneOrFail(\n\tt *testing.T,\n\tctx context.Context,\n\trunArgs []string,\n\tcmdOverride ...command.StartMonitor,\n) {\n\tif err := s.StartStandalone(ctx, runArgs, cmdOverride...); err != nil {\n\t\tt.Fatal(\"Cannot start sensor (standalone mode):\", err)\n\t}\n}\n\nfunc (s *Sensor) SendCommand(ctx context.Context, cmd command.Message) error {\n\tmsg, err := command.Encode(cmd)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"cannot encode command %q: %w\", cmd, err)\n\t}\n\tlog.Debugf(\"Sending command to the test sensor: %s\", string(msg))\n\n\tif len(s.contID) == 0 {\n\t\treturn errNotStarted\n\t}\n\n\tif s.client == nil {\n\t\treturn errors.New(\"IPC client isn't initialized - is sensor running?\")\n\t}\n\n\t// TODO: Use timeout from ctx.\n\tresp, err := s.client.SendCommand(cmd)\n\tif err != nil || resp.Status != command.ResponseStatusOk {\n\t\treturn fmt.Errorf(\"IPC client.SendCommand() failed with response %q: %w\", resp, err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Sensor) SendStartCommand(\n\tctx context.Context,\n\tcmdOverride ...command.StartMonitor,\n) error {\n\tcmd := startCommandControlled(s.image, cmdOverride...)\n\treturn s.SendCommand(ctx, &cmd)\n}\n\nfunc (s *Sensor) SendStartCommandOrFail(\n\tt *testing.T,\n\tctx context.Context,\n\tcmdOverride ...command.StartMonitor,\n) {\n\tif err := s.SendStartCommand(ctx, cmdOverride...); err != nil {\n\t\tt.Fatal(\"Failed sending StartMonitor command:\", err)\n\t}\n}\n\nfunc (s *Sensor) SendStopCommand(ctx context.Context) error {\n\treturn s.SendCommand(ctx, &command.StopMonitor{})\n}\n\nfunc (s *Sensor) SendStopCommandOrFail(t *testing.T, ctx context.Context) {\n\tif err := s.SendStopCommand(ctx); err != nil {\n\t\tt.Fatal(\"Failed sending StopMonitor command:\", err)\n\t}\n}\n\nfunc (s *Sensor) ExecuteControlCommand(ctx context.Context, cmd control.Command) error {\n\tif len(s.contID) == 0 {\n\t\treturn errNotStarted\n\t}\n\n\tif s.client != nil {\n\t\treturn fmt.Errorf(\"cannot execute control command - sensor is not in the standalone mode\")\n\t}\n\n\tif out, err := containerExec(\n\t\tctx,\n\t\ts.contID,\n\t\tsensorExePath,\n\t\t\"control\",\n\t\tstring(cmd),\n\t); err != nil {\n\t\treturn fmt.Errorf(\"cannot execute control command: %w\\n%s\", err, string(out))\n\t}\n\n\treturn nil\n}\n\nfunc (s *Sensor) ExecuteControlCommandOrFail(t *testing.T, ctx context.Context, cmd control.Command) {\n\tif err := s.ExecuteControlCommand(ctx, cmd); err != nil {\n\t\tt.Fatalf(\"Failed executing control command %s: %v\", cmd, err)\n\t}\n}\n\nfunc (s *Sensor) WaitForEvent(ctx context.Context, evt event.Type) error {\n\tif len(s.contID) == 0 {\n\t\treturn errNotStarted\n\t}\n\n\tif out, err := containerExec(\n\t\tctx,\n\t\ts.contID,\n\t\tsensorExePath,\n\t\t\"control\",\n\t\tstring(control.WaitForEventCommand),\n\t\tstring(evt),\n\t); err != nil {\n\t\treturn fmt.Errorf(\"cannot wait for sensor event %s: %w\\n%s\", evt, err, string(out))\n\t}\n\n\treturn nil\n}\n\nfunc (s *Sensor) WaitForEventOrFail(t *testing.T, ctx context.Context, evt event.Type) {\n\tif err := s.WaitForEvent(ctx, evt); err != nil {\n\t\tt.Fatalf(\"Failed waiting for sensor event %s: %v\", evt, err)\n\t}\n}\n\nfunc (s *Sensor) Shutdown(ctx context.Context) error {\n\tif err := s.SendCommand(ctx, &command.ShutdownSensor{}); err != nil {\n\t\treturn err\n\t}\n\n\tif err := s.client.Stop(); err != nil {\n\t\treturn fmt.Errorf(\"IPC client.Stop() failed: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Sensor) ShutdownOrFail(t *testing.T, ctx context.Context) {\n\tif err := s.Shutdown(ctx); err != nil {\n\t\tt.Fatal(\"Test sensor shutdown failed:\", err)\n\t}\n}\n\nfunc (s *Sensor) Wait(ctx context.Context) (int, error) {\n\tif len(s.contID) == 0 {\n\t\treturn -1, errNotStarted\n\t}\n\n\texitCode, err := containerWait(ctx, s.contID)\n\tif err == nil {\n\t\ts.stopped = true\n\t\treturn exitCode, nil\n\t}\n\n\treturn -1, err\n}\n\nfunc (s *Sensor) WaitOrFail(t *testing.T, ctx context.Context) int {\n\texitCode, err := s.Wait(ctx)\n\tif err != nil {\n\t\tt.Fatal(\"Failed waiting for test sensor container:\", err)\n\t}\n\treturn exitCode\n}\n\nfunc (s *Sensor) Signal(ctx context.Context, sig syscall.Signal) error {\n\tif len(s.contID) == 0 {\n\t\treturn errNotStarted\n\t}\n\n\treturn containerKill(ctx, s.contID, sig)\n}\n\nfunc (s *Sensor) SignalOrFail(t *testing.T, ctx context.Context, sig syscall.Signal) {\n\tif err := s.Signal(ctx, sig); err != nil {\n\t\tt.Fatal(\"Cannot signal test sensor container:\", err)\n\t}\n}\n\nfunc (s *Sensor) DownloadArtifacts(ctx context.Context) error {\n\tif len(s.contID) == 0 {\n\t\treturn errNotStarted\n\t}\n\n\tif err := containerCopyFrom(\n\t\tctx,\n\t\ts.contID,\n\t\ts.remoteArtifactsDirPath(),\n\t\ts.localArtifactsDirPath(),\n\t); err != nil {\n\t\treturn fmt.Errorf(\"cannot download test sensor's artifacts: %w\", err)\n\t}\n\n\tcreportFilePath := filepath.Join(s.localArtifactsDirPath(), report.DefaultContainerReportFileName)\n\trawCReport, err := os.ReadFile(creportFilePath)\n\tif err == nil {\n\t\ts.rawCReport = string(rawCReport)\n\n\t\tvar creport report.ContainerReport\n\t\tif err := fsutil.LoadStructFromFile(creportFilePath, &creport); err != nil {\n\t\t\treturn fmt.Errorf(\"cannot decode test sensor's report: %w\", err)\n\t\t}\n\t\ts.creport = &creport\n\t}\n\n\tif s.enableMondel {\n\t\tmondelFilePath := filepath.Join(s.localArtifactsDirPath(), MondelFileName)\n\t\trawMondel, err := os.ReadFile(mondelFilePath)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot read %s file: %w\", MondelFileName, err)\n\t\t}\n\n\t\ts.rawMondel = string(rawMondel)\n\n\t\tfor _, line := range strings.Split(strings.TrimSpace(s.rawMondel), \"\\n\") {\n\t\t\tvar evt report.MonitorDataEvent\n\t\t\tif err := json.Unmarshal([]byte(line), &evt); err != nil {\n\t\t\t\treturn fmt.Errorf(\"cannot decode test sensor's mondel line %#q: %w\", line, err)\n\t\t\t}\n\t\t\ts.mondel = append(s.mondel, evt)\n\t\t}\n\t}\n\n\tif s.client == nil {\n\t\trawEvents, err := os.ReadFile(filepath.Join(s.localArtifactsDirPath(), EventsFileName))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot read %s file: %w\", EventsFileName, err)\n\t\t}\n\t\ts.rawEvents = string(rawEvents)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Sensor) DownloadArtifactsOrFail(t *testing.T, ctx context.Context) {\n\tif err := s.DownloadArtifacts(ctx); err != nil {\n\t\tt.Fatal(\"Cannot download test sensor's artifacts:\", err)\n\t}\n}\n\nfunc (s *Sensor) Cleanup(t *testing.T, ctx context.Context) {\n\tif t.Failed() {\n\t\ts.PrintState(ctx)\n\t}\n\n\tif len(s.contID) == 0 || s.stopped {\n\t\treturn\n\t}\n\n\tif err := s.Signal(ctx, syscall.SIGKILL); err != nil {\n\t\tlog.WithError(err).Warnf(\"Sensor cleanup: cannot signal container %q\", s.contID)\n\t} else {\n\t\ttime.Sleep(2 * time.Second)\n\t}\n\n\tif err := containerRemove(ctx, s.contID); err != nil {\n\t\tlog.WithError(err).Warnf(\"Sensor cleanup: cannot remove container %q\", s.contID)\n\t}\n}\n\nfunc (s *Sensor) ContainerLogs(ctx context.Context) (string, error) {\n\treturn containerLogs(ctx, s.contID)\n}\n\nfunc (s *Sensor) ContainerLogsOrFail(t *testing.T, ctx context.Context) string {\n\tlogs, err := s.ContainerLogs(ctx)\n\tif err != nil {\n\t\tt.Fatal(\"Cannot retrieve target container logs:\", err)\n\t}\n\treturn logs\n}\n\nfunc (s *Sensor) SensorLogs(ctx context.Context) (string, error) {\n\tif s.useLogFile {\n\t\tbytes, err := os.ReadFile(\n\t\t\tfilepath.Join(s.localArtifactsDirPath(), SensorLogFileName),\n\t\t)\n\t\treturn string(bytes), err\n\t}\n\treturn s.ContainerLogs(ctx)\n}\n\nfunc (s *Sensor) SensorLogsOrFail(t *testing.T, ctx context.Context) string {\n\tlogs, err := s.SensorLogs(ctx)\n\tif err != nil {\n\t\tt.Fatal(\"Cannot retrieve sensor logs:\", err)\n\t}\n\treturn logs\n}\n\nfunc (s *Sensor) PrintState(ctx context.Context) {\n\tlog.\n\t\tWithField(\"image\", s.image).\n\t\tWithField(\"container\", s.contID).\n\t\tWithField(\"context\", s.contextDirPath).\n\t\tWithField(\"exe\", s.sensorExePath).\n\t\tWithField(\"creport downloaded\", s.creport != nil).\n\t\tInfo(\"Printing out test sensor state\")\n\n\tif len(s.rawCReport) > 0 {\n\t\tfmt.Fprintln(os.Stderr, \"-=== Container report ===-\")\n\t\tfmt.Fprintln(os.Stderr, s.rawCReport)\n\t\tfmt.Fprintln(os.Stderr, \"-=== eof: Container report ===-\")\n\t}\n\n\tif len(s.rawMondel) > 0 {\n\t\tfmt.Fprintln(os.Stderr, \"-=== Container MonDEL ===-\")\n\t\tfmt.Fprintln(os.Stderr, s.rawMondel)\n\t\tfmt.Fprintln(os.Stderr, \"-=== eof: Container MonDEL ===-\")\n\t}\n\n\tif len(s.rawEvents) > 0 {\n\t\tfmt.Fprintln(os.Stderr, \"-=== events.json ===-\")\n\t\tfmt.Fprintln(os.Stderr, s.rawEvents)\n\t\tfmt.Fprintln(os.Stderr, \"-=== eof: events.json ===-\")\n\t}\n\n\tif len(s.contID) > 0 && s.useLogFile {\n\t\tfmt.Fprintln(os.Stderr, \"-=== Sensor logs ===-\")\n\t\tif sensorLogs, err := s.SensorLogs(ctx); err == nil {\n\t\t\tfmt.Fprintln(os.Stderr, sensorLogs)\n\t\t} else {\n\t\t\tlog.WithError(err).Error(\"Cannot obtain sensor logs\")\n\t\t}\n\t\tfmt.Fprintln(os.Stderr, \"-=== eof: Sensor logs ===-\")\n\t}\n\n\tif len(s.contID) > 0 {\n\t\tfmt.Fprintln(os.Stderr, \"-=== Container logs ===-\")\n\t\tif contLogs, err := s.ContainerLogs(ctx); err == nil {\n\t\t\tfmt.Fprintln(os.Stderr, contLogs)\n\t\t} else {\n\t\t\tlog.WithError(err).Error(\"Cannot obtain target container logs\")\n\t\t}\n\t\tfmt.Fprintln(os.Stderr, \"-=== eof: Container logs ===-\")\n\t}\n}\n\nfunc (s *Sensor) ExpectEvent(t *testing.T, name event.Type) {\n\tif s.client == nil {\n\t\tt.Fatal(\"IPC client isn't initialized - is sensor running?\")\n\t}\n\n\tevt, err := s.client.GetEvent()\n\tif err != nil {\n\t\tt.Fatalf(\"IPC client.GetEvent() failed with response %q: %v\", evt, err)\n\t}\n\n\tif evt.Name != name {\n\t\tt.Fatalf(\"Unexpected event type %q (expected %q)\", evt.Name, name)\n\t}\n}\n\nfunc (s *Sensor) AssertSensorLogsContain(t *testing.T, ctx context.Context, what ...string) {\n\tif len(s.contID) == 0 {\n\t\tt.Fatal(\"Test sensor container hasn't been started yet\")\n\t}\n\n\tcontLogs := s.SensorLogsOrFail(t, ctx)\n\tfor _, w := range what {\n\t\tif strings.Index(contLogs, w) == -1 {\n\t\t\tt.Errorf(\"Cannot find string %q in sensor logs\", w)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) AssertTargetAppLogsContain(t *testing.T, ctx context.Context, what ...string) {\n\tif len(s.contID) == 0 {\n\t\tt.Fatal(\"Test sensor container hasn't been started yet\")\n\t}\n\n\tcontLogs := s.ContainerLogsOrFail(t, ctx)\n\tfor _, w := range what {\n\t\tif strings.Index(contLogs, w) == -1 {\n\t\t\tt.Errorf(\"Cannot find string %q in container logs\", w)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) AssertTargetAppLogsEqualTo(t *testing.T, ctx context.Context, what string) {\n\tif len(s.contID) == 0 {\n\t\tt.Fatal(\"Test sensor container hasn't been started yet\")\n\t}\n\n\tcontLogs := strings.TrimSpace(s.ContainerLogsOrFail(t, ctx))\n\tif contLogs != what {\n\t\tt.Errorf(\"Unexpected container logs %q. Expected %q.\", contLogs, what)\n\t}\n}\n\nfunc (s *Sensor) AssertTargetAppStdoutFileEqualsTo(t *testing.T, ctx context.Context, expected string) {\n\ts.assertTargetAppStdFileEqualsTo(t, ctx, AppStdoutFileName, expected)\n}\n\nfunc (s *Sensor) AssertTargetAppStderrFileEqualsTo(t *testing.T, ctx context.Context, expected string) {\n\ts.assertTargetAppStdFileEqualsTo(t, ctx, AppStderrFileName, expected)\n}\n\nfunc (s *Sensor) assertTargetAppStdFileEqualsTo(\n\tt *testing.T,\n\tctx context.Context,\n\tkind string,\n\texpected string,\n) {\n\tif len(s.contID) == 0 {\n\t\tt.Fatal(\"Test sensor container hasn't been started yet\")\n\t}\n\n\tdata, err := os.ReadFile(filepath.Join(s.localArtifactsDirPath(), kind))\n\tif err != nil {\n\t\tt.Fatalf(\"cannot read %s file: %v\", kind, err)\n\t}\n\n\tactual := strings.TrimSpace(string(data))\n\tif actual != expected {\n\t\tt.Errorf(\"Unexpected target app %s content %q. Expected %q.\", kind, actual, expected)\n\t}\n}\n\n// Checks the presense of the expected events AND the occurrence order.\nfunc (s *Sensor) AssertSensorEventsFileContains(\n\tt *testing.T,\n\tctx context.Context,\n\texpected ...event.Type,\n) {\n\tif len(s.rawEvents) == 0 {\n\t\tt.Fatal(\"No events found\")\n\t}\n\n\tactual := parseEvents(s.rawEvents)\n\n\t// Orders matter!\n\tfor len(expected) > 0 && len(actual) > 0 {\n\t\tif expected[0] == actual[0].Name {\n\t\t\texpected = expected[1:]\n\t\t}\n\t\tactual = actual[1:]\n\t}\n\n\tif len(expected) > 0 {\n\t\tt.Errorf(\"Some of the expected events weren't found in event file: %q\", expected)\n\t}\n}\n\nfunc (s *Sensor) AssertReportIncludesFiles(t *testing.T, filepath ...string) {\n\tif s.creport == nil {\n\t\tt.Fatal(\"No sensor report found\")\n\t}\n\n\tindex := artifactsByFilePath(s.creport.Image.Files)\n\tfor _, f := range filepath {\n\t\tif index[f] == nil {\n\t\t\tt.Errorf(\"Expected file %q not found in the container report\", f)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) AssertReportNotIncludesFiles(t *testing.T, filepath ...string) {\n\tif s.creport == nil {\n\t\tt.Fatal(\"No sensor report found\")\n\t}\n\n\tindex := artifactsByFilePath(s.creport.Image.Files)\n\tfor _, f := range filepath {\n\t\tif index[f] != nil {\n\t\t\tt.Errorf(\"Unexpected file %q found in the container report\", f)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) AssertMondelIncludesFiles(t *testing.T, filepath ...string) {\n\tif s.mondel == nil {\n\t\tt.Fatal(\"No sensor mondel file found\")\n\t}\n\n\tindex := mondelEventByFilePath(s.mondel)\n\tfor _, f := range filepath {\n\t\tif _, found := index[f]; !found {\n\t\t\tt.Errorf(\"Expected file %q not found in the mondel file\", f)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) AssertMondelNotIncludesFiles(t *testing.T, filepath ...string) {\n\tif s.mondel == nil {\n\t\tt.Fatal(\"No sensor mondel file found\")\n\t}\n\n\tindex := mondelEventByFilePath(s.mondel)\n\tfor _, f := range filepath {\n\t\tif _, found := index[f]; found {\n\t\t\tt.Errorf(\"Unexpected file %q found in the mondel file\", f)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) AssertReportAndMondelFileListsMatch(t *testing.T) {\n\tif s.creport == nil {\n\t\tt.Fatal(\"No sensor report found\")\n\t}\n\n\tif len(s.mondel) == 0 {\n\t\tt.Fatal(\"No sensor mondel file found\")\n\t}\n\n\tuniqMondelFiles := mondelEventByFilePath(s.mondel)\n\tuniqCReportFiles := artifactsByFilePath(s.creport.Image.Files)\n\n\tfor f := range uniqMondelFiles {\n\t\tif _, found := uniqCReportFiles[f]; !found {\n\t\t\tt.Errorf(\"File %q found in mondel but not in container report\", f)\n\t\t}\n\t}\n\n\tfor f := range uniqCReportFiles {\n\t\tif _, found := uniqMondelFiles[f]; !found {\n\t\t\tt.Errorf(\"File %q found in container report but not in mondel\", f)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) AssertArtifactsArchiveContains(\n\tt *testing.T,\n\tctx context.Context,\n\tfilename ...string,\n) {\n\tarchiveFilePath := filepath.Join(s.localArtifactsDirPath(), runArchiveName)\n\tarchiveFile, err := os.Open(archiveFilePath)\n\tif err != nil {\n\t\tt.Errorf(\"Cannot open report archive %q: %v\", archiveFilePath, err)\n\t\treturn\n\t}\n\tdefer archiveFile.Close()\n\n\tfound := map[string]bool{}\n\tfor _, f := range filename {\n\t\tfound[f] = false\n\t}\n\n\treader := tar.NewReader(archiveFile)\n\tfor {\n\t\theader, err := reader.Next()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Failed reading tar archive header: %v\", err)\n\t\t\tcontinue\n\t\t}\n\n\t\tif _, expected := found[header.Name]; !expected {\n\t\t\tcontinue\n\t\t}\n\n\t\t_, err = io.ReadAll(reader)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Failed reading expected tar archive entry %q: %v\", header.Name, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tfound[header.Name] = true\n\t}\n\n\tfor name := range found {\n\t\tif !found[name] {\n\t\t\tt.Errorf(\"Artifacts archive doesn't contain entry %q\", name)\n\t\t}\n\t}\n}\n\nfunc (s *Sensor) commonStartFlags() []string {\n\tflags := []string{\"-l\", \"debug\", \"-d\"}\n\tif len(s.artifactsDirPath) > 0 {\n\t\tflags = append(flags, \"-e\", s.artifactsDirPath)\n\t}\n\tif s.useLogFile {\n\t\tflags = append(flags, \"-o\", filepath.Join(s.remoteArtifactsDirPath(), SensorLogFileName))\n\t}\n\tif s.enableMondel {\n\t\tflags = append(flags, \"-n\")\n\t}\n\tif len(s.lifecycleHook) > 0 {\n\t\tflags = append(flags, \"-a\", s.lifecycleHook)\n\t}\n\treturn flags\n}\n\nfunc (s *Sensor) capabilities() (caps []string) {\n\tfor _, c := range s.capAdd {\n\t\tcaps = append(caps, \"--cap-add=\"+c)\n\t}\n\tfor _, c := range s.capDrop {\n\t\tcaps = append(caps, \"--cap-drop=\"+c)\n\t}\n\treturn caps\n}\n\nfunc (s *Sensor) localArtifactsDirPath() string {\n\treturn filepath.Join(s.contextDirPath, filepath.Base(s.remoteArtifactsDirPath()))\n}\n\nfunc (s *Sensor) remoteArtifactsDirPath() string {\n\tif len(s.artifactsDirPath) > 0 {\n\t\treturn s.artifactsDirPath\n\t}\n\treturn app.DefaultArtifactsDirPath\n}\n\nfunc startCommandControlled(\n\timage dockerapi.Image,\n\tcmdOverride ...command.StartMonitor,\n) command.StartMonitor {\n\tcmd := NewMonitorStartCommand(WithSaneDefaults())\n\tif len(cmdOverride) > 0 {\n\t\tcmd = cmdOverride[0]\n\t}\n\n\tif len(cmd.AppName) == 0 {\n\t\tif len(image.Config.Entrypoint) > 0 {\n\t\t\tcmd.AppName = image.Config.Entrypoint[0]\n\t\t\tcmd.AppArgs = append(image.Config.Entrypoint[1:], image.Config.Cmd...)\n\t\t} else {\n\t\t\tcmd.AppName = image.Config.Cmd[0]\n\t\t\tcmd.AppArgs = image.Config.Cmd[1:]\n\t\t}\n\t}\n\n\tif len(image.Config.User) > 0 {\n\t\tcmd.AppUser = image.Config.User\n\t\tcmd.RunTargetAsUser = true\n\t}\n\n\treturn cmd\n}\n\nfunc startCommandStandalone(\n\timage dockerapi.Image,\n\tcmdOverride ...command.StartMonitor,\n) command.StartMonitor {\n\tcmd := NewMonitorStartCommand(WithSaneDefaults())\n\tif len(cmdOverride) > 0 {\n\t\tcmd = cmdOverride[0]\n\t}\n\n\tcmd.AppEntrypoint = image.Config.Entrypoint\n\tcmd.AppCmd = image.Config.Cmd\n\n\tif len(image.Config.User) > 0 {\n\t\tcmd.AppUser = image.Config.User\n\t\tcmd.RunTargetAsUser = true\n\t}\n\n\tcmd.ReportOnMainPidExit = true\n\n\treturn cmd\n}\n\nfunc parseEvents(rawEvents string) (events []event.Message) {\n\tfor _, line := range strings.Split(rawEvents, \"\\n\") {\n\t\tif len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tvar event event.Message\n\t\tif err := json.Unmarshal([]byte(line), &event); err != nil {\n\t\t\tlog.WithError(err).Errorf(\"Cannot parse event file entry: %q\", line)\n\t\t}\n\n\t\tevents = append(events, event)\n\t}\n\treturn events\n}\n\nfunc jsonDump(filename string, val interface{}) error {\n\tf, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"JSON dump failed: cannot create|open file %q: %w\", filename, err)\n\t}\n\n\tencoder := json.NewEncoder(f)\n\tencoder.SetEscapeHTML(false)\n\n\tif err := encoder.Encode(val); err != nil {\n\t\treturn fmt.Errorf(\"JSON dump failed: encoding of value %q failed: %w\", val, err)\n\t}\n\n\treturn nil\n}\n\nfunc artifactsByFilePath(files []*report.ArtifactProps) map[string]*report.ArtifactProps {\n\tdict := make(map[string]*report.ArtifactProps)\n\tfor _, props := range files {\n\t\tif props != nil {\n\t\t\tdict[props.FilePath] = props\n\t\t}\n\t}\n\treturn dict\n}\n\nfunc mondelEventByFilePath(events []report.MonitorDataEvent) map[string]report.MonitorDataEvent {\n\tdict := make(map[string]report.MonitorDataEvent)\n\tfor _, evt := range events {\n\t\tdict[evt.Artifact] = evt\n\t}\n\treturn dict\n}\n\nfunc hostPort(cont dockerapi.Container, contPort int) (string, bool) {\n\tif cont.NetworkSettings != nil {\n\t\tfor port, bindings := range cont.NetworkSettings.Ports {\n\t\t\tif port.Port() == fmt.Sprintf(\"%d\", contPort) && len(bindings) > 0 {\n\t\t\t\treturn bindings[0].HostPort, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", false\n}\n\nfunc flatten(arrs ...[]string) []string {\n\tres := []string{}\n\tfor _, arr := range arrs {\n\t\tres = append(res, arr...)\n\t}\n\treturn res\n}\n"
  },
  {
    "path": "pkg/test/stub/sensor/execution/execution.go",
    "content": "package execution\n\nimport (\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/execution\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/command\"\n\t\"github.com/slimtoolkit/slim/pkg/ipc/event\"\n)\n\ntype executionStub struct {\n\tcommands chan command.Message\n}\n\nvar _ execution.Interface = &executionStub{}\n\nfunc NewExecution() *executionStub {\n\treturn &executionStub{\n\t\tcommands: make(chan command.Message),\n\t}\n}\n\nfunc (e *executionStub) State() string {\n\treturn \"\"\n}\n\nfunc (e *executionStub) Commands() <-chan command.Message {\n\treturn e.commands\n}\n\nfunc (e *executionStub) SendCommand(cmd command.Message) {\n\te.commands <- cmd\n}\n\nfunc (e *executionStub) PubEvent(etype event.Type, data ...interface{}) {\n\tlog.\n\t\tWithField(\"type\", etype).\n\t\tWithField(\"data\", data).\n\t\tDebug(\"execution stub - new event\")\n}\n\nfunc (e *executionStub) Close() {\n\tclose(e.commands)\n}\n\nfunc (e *executionStub) HookSensorPostStart() {\n\t// noop\n}\n\nfunc (e *executionStub) HookSensorPreShutdown() {\n\t// noop\n}\n\nfunc (e *executionStub) HookMonitorPreStart() {\n\t// noop\n}\n\nfunc (e *executionStub) HookTargetAppRunning() {\n\t// noop\n}\n\nfunc (e *executionStub) HookMonitorPostShutdown() {\n\t// noop\n}\n\nfunc (e *executionStub) HookMonitorFailed() {\n\t// noop\n}\n"
  },
  {
    "path": "pkg/test/stub/sensor/monitor/monitor.go",
    "content": "package monitor\n\nimport (\n\t\"context\"\n\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor/fanotify\"\n\t\"github.com/slimtoolkit/slim/pkg/app/sensor/monitor/ptrace\"\n\t\"github.com/slimtoolkit/slim/pkg/report\"\n)\n\n// Base monitor stub.\ntype monitorStub struct {\n\tctx      context.Context\n\tcancelFn context.CancelFunc\n\terrorCh  chan error\n}\n\nfunc newMonitorStub(ctx context.Context) *monitorStub {\n\tctx, cancelFn := context.WithCancel(ctx)\n\treturn &monitorStub{\n\t\tctx:      ctx,\n\t\tcancelFn: cancelFn,\n\t\terrorCh:  make(chan error),\n\t}\n}\n\nfunc (m *monitorStub) Start() error {\n\treturn nil\n}\n\nfunc (m *monitorStub) Cancel() {\n\tselect {\n\tcase <-m.ctx.Done():\n\t\treturn\n\tdefault:\n\t}\n\n\tm.cancelFn()\n\tclose(m.errorCh)\n}\n\nfunc (m *monitorStub) Done() <-chan struct{} {\n\treturn m.ctx.Done()\n}\n\n// fan monitor stub implements fanotify.Monitor\ntype FanMonitorStub struct {\n\t*monitorStub\n}\n\nvar _ fanotify.Monitor = &FanMonitorStub{}\n\nfunc NewFanMonitor(ctx context.Context) *FanMonitorStub {\n\treturn &FanMonitorStub{\n\t\tmonitorStub: newMonitorStub(ctx),\n\t}\n}\n\nfunc (m *FanMonitorStub) Status() (*report.FanMonitorReport, error) {\n\treturn nil, nil\n}\n\n// ptrace monitor stub implements ptrace.Monitor\ntype PtMonitorStub struct {\n\t*monitorStub\n}\n\nvar _ ptrace.Monitor = &PtMonitorStub{}\n\nfunc NewPtMonitor(ctx context.Context) *PtMonitorStub {\n\treturn &PtMonitorStub{\n\t\tmonitorStub: newMonitorStub(ctx),\n\t}\n}\n\nfunc (m *PtMonitorStub) Status() (*report.PtMonitorReport, error) {\n\treturn nil, nil\n}\n"
  },
  {
    "path": "pkg/test/util/time.go",
    "content": "package util\n\nimport (\n\t\"context\"\n\t\"time\"\n)\n\nfunc Delayed(ctx context.Context, delay time.Duration, fn func()) {\n\ttimer := time.NewTimer(delay)\n\tselect {\n\tcase <-ctx.Done():\n\t\tif !timer.Stop() {\n\t\t\t<-timer.C\n\t\t}\n\t\treturn\n\tcase <-timer.C:\n\t\tfn()\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/.github/CODEOWNERS",
    "content": "*   @ndeloof\n\n"
  },
  {
    "path": "pkg/third_party/compose-go/.github/dependabot.yml",
    "content": "version: 2\nupdates:\n- package-ecosystem: gomod\n  directory: \"/\"\n  schedule:\n    interval: weekly\n  open-pull-requests-limit: 10\n  ignore:\n  - dependency-name: github.com/sirupsen/logrus\n    versions:\n    - 1.8.0\n    - 1.8.1\n  - dependency-name: github.com/google/go-cmp\n    versions:\n    - 0.5.5\n"
  },
  {
    "path": "pkg/third_party/compose-go/.github/workflows/ci.yml",
    "content": "on: [push, pull_request]\nname: Continuous integration\njobs:\n  validate:\n    name: validate\n    runs-on: ubuntu-latest\n    timeout-minutes: 5\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v2\n      - name: Lint code\n        run: DOCKER_BUILDKIT=1 make lint\n      - name: Check license\n        run: DOCKER_BUILDKIT=1 make check-license\n\n  test:\n    strategy:\n      matrix:\n        go-version: [1.16.x]\n        platform: [ubuntu-latest, macos-latest, windows-latest]\n    runs-on: ${{ matrix.platform }}\n    timeout-minutes: 5\n    steps:\n    - name: Install Go\n      uses: actions/setup-go@v2\n      with:\n        go-version: ${{ matrix.go-version }}\n    - name: Checkout code\n      uses: actions/checkout@v2\n    - name: Test\n      run: go test ./...\n"
  },
  {
    "path": "pkg/third_party/compose-go/.github/workflows/release.yml",
    "content": "name: Release\non:\n  push:\n    tags:\n      - \"v1*\"\n\njobs:\n  release:\n    runs-on: ubuntu-latest      \n    steps:\n      - uses: ncipollo/release-action@v1\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}"
  },
  {
    "path": "pkg/third_party/compose-go/.gitignore",
    "content": "### IDEs ###\n.idea/*\n"
  },
  {
    "path": "pkg/third_party/compose-go/.pre-commit-config.yaml",
    "content": "repos:\n    -   repo: https://github.com/pre-commit/pre-commit-hooks\n        rev: v2.4.0\n        hooks:\n        -   id: check-yaml\n            exclude: '^vendor/'\n        -   id: end-of-file-fixer\n            exclude: '^vendor/'\n        -   id: trailing-whitespace\n            exclude: '^vendor/'\n    -   repo: https://github.com/dnephin/pre-commit-golang\n        rev: v0.3.5\n        hooks:\n          - id: go-fmt\n          - id: golangci-lint\n          - id: go-imports\n"
  },
  {
    "path": "pkg/third_party/compose-go/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the\n  overall community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or\n  advances of any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email\n  address, without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders.\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series\nof actions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or\npermanent ban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior,  harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within\nthe community.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.0, available at\nhttps://www.contributor-covenant.org/version/2/0/code_of_conduct.html.\n\nCommunity Impact Guidelines were inspired by [Mozilla's code of conduct\nenforcement ladder](https://github.com/mozilla/diversity).\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see the FAQ at\nhttps://www.contributor-covenant.org/faq. Translations are available at\nhttps://www.contributor-covenant.org/translations.\n"
  },
  {
    "path": "pkg/third_party/compose-go/CONTRIBUTING.md",
    "content": "# Contributing\n\nContributions should be made via pull requests. Pull requests will be reviewed\nby one or more maintainers and merged when acceptable.\n\nThe goal of the Compose Go library is to facilitate parsing and loading Compose\nfiles.\n\n## Commit Messages\n\nCommit messages should follow best practices and explain the context of the\nproblem and how it was solved– including any caveats or follow up changes\nrequired. They should tell the story of the change and provide readers an\nunderstanding of what led to it.\n\n[How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/)\nprovides a good guide for how to do so.\n\nIn practice, the best approach to maintaining a nice commit message is to\nleverage a `git add -p` and `git commit --amend` to formulate a solid\nchange set. This allows one to piece together a change, as information becomes\navailable.\n\nIf you squash a series of commits, don't just submit that. Re-write the commit\nmessage, as if the series of commits was a single stroke of brilliance.\n\nThat said, there is no requirement to have a single commit for a pull request,\nas long as each commit tells the story. For example, if there is a feature that\nrequires a package, it might make sense to have the package in a separate commit\nthen have a subsequent commit that uses it.\n\nRemember, you're telling part of the story with the commit message. Don't make\nyour chapter weird.\n\n## Sign your work\n\nThe sign-off is a simple line at the end of the explanation for the patch. Your\nsignature certifies that you wrote the patch or otherwise have the right to pass\nit on as an open-source patch. The rules are pretty simple: if you can certify\nthe below (from [developercertificate.org](http://developercertificate.org/)):\n\n```\nDeveloper Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n660 York Street, Suite 102,\nSan Francisco, CA 94110 USA\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n    have the right to submit it under the open source license\n    indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n    of my knowledge, is covered under an appropriate open source\n    license and I have the right under that license to submit that\n    work with modifications, whether created in whole or in part\n    by me, under the same open source license (unless I am\n    permitted to submit under a different license), as indicated\n    in the file; or\n\n(c) The contribution was provided directly to me by some other\n    person who certified (a), (b) or (c) and I have not modified\n    it.\n\n(d) I understand and agree that this project and the contribution\n    are public and that a record of the contribution (including all\n    personal information I submit with it, including my sign-off) is\n    maintained indefinitely and may be redistributed consistent with\n    this project or the open source license(s) involved.\n```\n\nThen you just add a line to every git commit message:\n\n    Signed-off-by: Joe Smith <joe.smith@email.com>\n\nUse your real name (sorry, no pseudonyms or anonymous contributions.)\n\nIf you set your `user.name` and `user.email` git configs, you can sign your\ncommit automatically with `git commit -s`.\n\n"
  },
  {
    "path": "pkg/third_party/compose-go/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/third_party/compose-go/MAINTENANCE.md",
    "content": "# Maintenance\n\nThe compose-go library has to be kept up-to-date with approved changes in the [Compose specification](https://github.com/compose-spec/compose-spec).\nAs we define new attributes to be added to the spec, this typically requires:\n\n1. Updating `schema` to latest version from compose-spec\n1. Creating the matching struct/field in `types`\n1. Creating the matching `CheckXX` method in `compatibility`\n1. If the new attribute replaces a legacy one we want to deprecate, creating the adequate logic in `normalize.go`"
  },
  {
    "path": "pkg/third_party/compose-go/Makefile",
    "content": "#   Copyright 2020 The Compose Specification Authors.\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#       http://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\nIMAGE_PREFIX=composespec/conformance-tests-\n\n.PHONY: build\nbuild: ## Run tests\n\tgo build ./...\n\n.PHONY: test\ntest: ## Run tests\n\tgotestsum ./...\n\n.PHONY: fmt\nfmt: ## Format go files\n\tgo fmt ./...\n\n.PHONY: build-validate-image\nbuild-validate-image:\n\tdocker build . -f ci/Dockerfile -t $(IMAGE_PREFIX)validate\n\n.PHONY: lint\nlint: build-validate-image\n\tdocker run --rm $(IMAGE_PREFIX)validate bash -c \"golangci-lint run --config ./golangci.yml ./...\"\n\n.PHONY: check-license\ncheck-license: build-validate-image\n\tdocker run --rm $(IMAGE_PREFIX)validate bash -c \"./scripts/validate/fileheader\"\n\n.PHONY: setup\nsetup: ## Setup the precommit hook\n\t@which pre-commit > /dev/null 2>&1 || (echo \"pre-commit not installed see README.\" && false)\n\t@pre-commit install\n"
  },
  {
    "path": "pkg/third_party/compose-go/NOTICE",
    "content": "The Compose Specification\nCopyright 2020 The Compose Specification Authors\n"
  },
  {
    "path": "pkg/third_party/compose-go/README.md",
    "content": "# compose-go\n![Continuous integration](https://github.com/compose-spec/compose-go/workflows/Continuous%20integration/badge.svg)\n\nGo reference library for parsing and loading Compose files as specified by the\n[Compose specification](https://github.com/compose-spec/compose-spec).\n\n## Used by\n\n* [compose-ref](https://github.com/compose-spec/compose-ref)\n* [containerd/nerdctl](https://github.com/containerd/nerdctl)\n* [compose-cli](https://github.com/docker/compose-cli)\n"
  },
  {
    "path": "pkg/third_party/compose-go/ci/Dockerfile",
    "content": "#   Copyright 2020 The Compose Specification Authors.\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#       http://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\nFROM golang:1.16\n\nWORKDIR /go/src\n\nARG GOLANGCILINT_VERSION=v1.24.0\nRUN curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin ${GOLANGCILINT_VERSION}\nRUN go get -v -u github.com/kunalkushwaha/ltag && rm -rf /go/src/github.com/kunalkushwaha\n\nCOPY . .\n"
  },
  {
    "path": "pkg/third_party/compose-go/cli/options.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage cli\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/compose-spec/compose-go/loader\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/ulyssessouza/godotenv\"\n)\n\n// ProjectOptions groups the command line options recommended for a Compose implementation\ntype ProjectOptions struct {\n\tName        string\n\tWorkingDir  string\n\tConfigPaths []string\n\tEnvironment map[string]string\n\tEnvFile     string\n\tloadOptions []func(*loader.Options)\n}\n\ntype ProjectOptionsFn func(*ProjectOptions) error\n\n// NewProjectOptions creates ProjectOptions\nfunc NewProjectOptions(configs []string, opts ...ProjectOptionsFn) (*ProjectOptions, error) {\n\toptions := &ProjectOptions{\n\t\tConfigPaths: configs,\n\t\tEnvironment: map[string]string{},\n\t}\n\tfor _, o := range opts {\n\t\terr := o(options)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn options, nil\n}\n\n// WithName defines ProjectOptions' name\nfunc WithName(name string) ProjectOptionsFn {\n\treturn func(o *ProjectOptions) error {\n\t\to.Name = name\n\t\treturn nil\n\t}\n}\n\n// WithWorkingDirectory defines ProjectOptions' working directory\nfunc WithWorkingDirectory(wd string) ProjectOptionsFn {\n\treturn func(o *ProjectOptions) error {\n\t\tif wd == \"\" {\n\t\t\treturn nil\n\t\t}\n\t\tabs, err := filepath.Abs(wd)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\to.WorkingDir = abs\n\t\treturn nil\n\t}\n}\n\n// WithConfigFileEnv allow to set compose config file paths by COMPOSE_FILE environment variable\nfunc WithConfigFileEnv(o *ProjectOptions) error {\n\tif len(o.ConfigPaths) > 0 {\n\t\treturn nil\n\t}\n\tsep := o.Environment[ComposePathSeparator]\n\tif sep == \"\" {\n\t\tsep = string(os.PathListSeparator)\n\t}\n\tf, ok := o.Environment[ComposeFilePath]\n\tif ok {\n\t\tpaths, err := absolutePaths(strings.Split(f, sep))\n\t\to.ConfigPaths = paths\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// WithDefaultConfigPath searches for default config files from working directory\nfunc WithDefaultConfigPath(o *ProjectOptions) error {\n\tif len(o.ConfigPaths) > 0 {\n\t\treturn nil\n\t}\n\tpwd, err := o.GetWorkingDir()\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor {\n\t\tcandidates := findFiles(DefaultFileNames, pwd)\n\t\tif len(candidates) > 0 {\n\t\t\twinner := candidates[0]\n\t\t\tif len(candidates) > 1 {\n\t\t\t\tlogrus.Warnf(\"Found multiple config files with supported names: %s\", strings.Join(candidates, \", \"))\n\t\t\t\tlogrus.Warnf(\"Using %s\", winner)\n\t\t\t}\n\t\t\to.ConfigPaths = append(o.ConfigPaths, winner)\n\n\t\t\toverrides := findFiles(DefaultOverrideFileNames, pwd)\n\t\t\tif len(overrides) > 0 {\n\t\t\t\tif len(overrides) > 1 {\n\t\t\t\t\tlogrus.Warnf(\"Found multiple override files with supported names: %s\", strings.Join(overrides, \", \"))\n\t\t\t\t\tlogrus.Warnf(\"Using %s\", overrides[0])\n\t\t\t\t}\n\t\t\t\to.ConfigPaths = append(o.ConfigPaths, overrides[0])\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\tparent := filepath.Dir(pwd)\n\t\tif parent == pwd {\n\t\t\treturn errors.Wrap(errdefs.ErrNotFound, \"can't find a suitable configuration file in this directory or any parent\")\n\t\t}\n\t\tpwd = parent\n\t}\n}\n\n// WithEnv defines a key=value set of variables used for compose file interpolation\nfunc WithEnv(env []string) ProjectOptionsFn {\n\treturn func(o *ProjectOptions) error {\n\t\tfor k, v := range getAsEqualsMap(env) {\n\t\t\to.Environment[k] = v\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithDiscardEnvFile sets discards the `env_file` section after resolving to\n// the `environment` section\nfunc WithDiscardEnvFile(o *ProjectOptions) error {\n\to.loadOptions = append(o.loadOptions, loader.WithDiscardEnvFiles)\n\treturn nil\n}\n\n// WithLoadOptions provides a hook to control how compose files are loaded\nfunc WithLoadOptions(loadOptions ...func(*loader.Options)) ProjectOptionsFn {\n\treturn func(o *ProjectOptions) error {\n\t\to.loadOptions = append(o.loadOptions, loadOptions...)\n\t\treturn nil\n\t}\n}\n\n// WithOsEnv imports environment variables from OS\nfunc WithOsEnv(o *ProjectOptions) error {\n\tfor k, v := range getAsEqualsMap(os.Environ()) {\n\t\to.Environment[k] = v\n\t}\n\treturn nil\n}\n\n// WithEnvFile set an alternate env file\nfunc WithEnvFile(file string) ProjectOptionsFn {\n\treturn func(options *ProjectOptions) error {\n\t\toptions.EnvFile = file\n\t\treturn nil\n\t}\n}\n\n// WithDotEnv imports environment variables from .env file\nfunc WithDotEnv(o *ProjectOptions) error {\n\tdotEnvFile := o.EnvFile\n\tif dotEnvFile == \"\" {\n\t\twd, err := o.GetWorkingDir()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdotEnvFile = filepath.Join(wd, \".env\")\n\t}\n\tabs, err := filepath.Abs(dotEnvFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdotEnvFile = abs\n\n\ts, err := os.Stat(dotEnvFile)\n\tif os.IsNotExist(err) {\n\t\tif o.EnvFile != \"\" {\n\t\t\treturn errors.Errorf(\"Couldn't find env file: %s\", o.EnvFile)\n\t\t}\n\t\treturn nil\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif s.IsDir() {\n\t\tif o.EnvFile != \"\" {\n\t\t\treturn errors.Errorf(\"%s is a directory\", dotEnvFile)\n\t\t}\n\t}\n\n\tfile, err := os.Open(dotEnvFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\n\tnotInEnvSet := make(map[string]interface{})\n\tenv, err := godotenv.ParseWithLookup(file, func(k string) (string, bool) {\n\t\tv, ok := os.LookupEnv(k)\n\t\tif !ok {\n\t\t\tnotInEnvSet[k] = nil\n\t\t\treturn \"\", true\n\t\t}\n\t\treturn v, true\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor k, v := range env {\n\t\tif _, ok := notInEnvSet[k]; ok {\n\t\t\tcontinue\n\t\t}\n\t\to.Environment[k] = v\n\t}\n\treturn nil\n}\n\n// WithInterpolation set ProjectOptions to enable/skip interpolation\nfunc WithInterpolation(interpolation bool) ProjectOptionsFn {\n\treturn func(o *ProjectOptions) error {\n\t\to.loadOptions = append(o.loadOptions, func(options *loader.Options) {\n\t\t\toptions.SkipInterpolation = !interpolation\n\t\t})\n\t\treturn nil\n\t}\n}\n\n// WithResolvedPaths set ProjectOptions to enable paths resolution\nfunc WithResolvedPaths(resolve bool) ProjectOptionsFn {\n\treturn func(o *ProjectOptions) error {\n\t\to.loadOptions = append(o.loadOptions, func(options *loader.Options) {\n\t\t\toptions.ResolvePaths = resolve\n\t\t})\n\t\treturn nil\n\t}\n}\n\n// DefaultFileNames defines the Compose file names for auto-discovery (in order of preference)\nvar DefaultFileNames = []string{\"compose.yaml\", \"compose.yml\", \"docker-compose.yml\", \"docker-compose.yaml\"}\n\n// DefaultOverrideFileNames defines the Compose override file names for auto-discovery (in order of preference)\nvar DefaultOverrideFileNames = []string{\"compose.override.yml\", \"compose.override.yaml\", \"docker-compose.override.yml\", \"docker-compose.override.yaml\"}\n\nconst (\n\tComposeProjectName   = \"COMPOSE_PROJECT_NAME\"\n\tComposePathSeparator = \"COMPOSE_PATH_SEPARATOR\"\n\tComposeFilePath      = \"COMPOSE_FILE\"\n)\n\nfunc (o ProjectOptions) GetWorkingDir() (string, error) {\n\tif o.WorkingDir != \"\" {\n\t\treturn o.WorkingDir, nil\n\t}\n\tfor _, path := range o.ConfigPaths {\n\t\tif path != \"-\" {\n\t\t\tabsPath, err := filepath.Abs(path)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\treturn filepath.Dir(absPath), nil\n\t\t}\n\t}\n\treturn os.Getwd()\n}\n\n// ProjectFromOptions load a compose project based on command line options\nfunc ProjectFromOptions(options *ProjectOptions) (*types.Project, error) {\n\tconfigPaths, err := getConfigPathsFromOptions(options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar configs []types.ConfigFile\n\tfor _, f := range configPaths {\n\t\tvar b []byte\n\t\tif f == \"-\" {\n\t\t\tb, err = ioutil.ReadAll(os.Stdin)\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 := filepath.Abs(f)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb, err = ioutil.ReadFile(f)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tconfigs = append(configs, types.ConfigFile{\n\t\t\tFilename: f,\n\t\t\tContent:  b,\n\t\t})\n\t}\n\n\tworkingDir, err := options.GetWorkingDir()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tabsWorkingDir, err := filepath.Abs(workingDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar nameLoadOpt = func(opts *loader.Options) {\n\t\tif options.Name != \"\" {\n\t\t\topts.Name = options.Name\n\t\t} else if nameFromEnv, ok := options.Environment[ComposeProjectName]; ok && nameFromEnv != \"\" {\n\t\t\topts.Name = nameFromEnv\n\t\t} else {\n\t\t\topts.Name = regexp.MustCompile(`(?m)[a-z]+[-_a-z0-9]*`).FindString(strings.ToLower(filepath.Base(absWorkingDir)))\n\t\t}\n\t\topts.Name = strings.ToLower(opts.Name)\n\t}\n\toptions.loadOptions = append(options.loadOptions, nameLoadOpt)\n\n\tproject, err := loader.Load(types.ConfigDetails{\n\t\tConfigFiles: configs,\n\t\tWorkingDir:  workingDir,\n\t\tEnvironment: options.Environment,\n\t}, options.loadOptions...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tproject.ComposeFiles = configPaths\n\treturn project, nil\n}\n\n// getConfigPathsFromOptions retrieves the config files for project based on project options\nfunc getConfigPathsFromOptions(options *ProjectOptions) ([]string, error) {\n\tif len(options.ConfigPaths) != 0 {\n\t\treturn absolutePaths(options.ConfigPaths)\n\t}\n\n\treturn nil, errors.New(\"no configuration file provided\")\n}\n\nfunc findFiles(names []string, pwd string) []string {\n\tcandidates := []string{}\n\tfor _, n := range names {\n\t\tf := filepath.Join(pwd, n)\n\t\tif _, err := os.Stat(f); err == nil {\n\t\t\tcandidates = append(candidates, f)\n\t\t}\n\t}\n\treturn candidates\n}\n\nfunc absolutePaths(p []string) ([]string, error) {\n\tvar paths []string\n\tfor _, f := range p {\n\t\tif f == \"-\" {\n\t\t\tpaths = append(paths, f)\n\t\t\tcontinue\n\t\t}\n\t\tabs, err := filepath.Abs(f)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tf = abs\n\t\tif _, err := os.Stat(f); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpaths = append(paths, f)\n\t}\n\treturn paths, nil\n}\n\n// getAsEqualsMap split key=value formatted strings into a key : value map\nfunc getAsEqualsMap(em []string) map[string]string {\n\tm := make(map[string]string)\n\tfor _, v := range em {\n\t\tkv := strings.SplitN(v, \"=\", 2)\n\t\tm[kv[0]] = kv[1]\n\t}\n\treturn m\n}\n\n// getAsStringList format a key : value map into key=value strings\nfunc getAsStringList(em map[string]string) []string {\n\tm := make([]string, 0, len(em))\n\tfor k, v := range em {\n\t\tm = append(m, fmt.Sprintf(\"%s=%s\", k, v))\n\t}\n\treturn m\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/cli/options_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage cli\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"gotest.tools/v3/assert\"\n)\n\nfunc TestProjectName(t *testing.T) {\n\tt.Run(\"by name\", func(t *testing.T) {\n\t\topts, err := NewProjectOptions([]string{\"testdata/simple/compose.yaml\"}, WithName(\"my_project\"))\n\t\tassert.NilError(t, err)\n\t\tp, err := ProjectFromOptions(opts)\n\t\tassert.NilError(t, err)\n\t\tassert.Equal(t, p.Name, \"my_project\")\n\t})\n\n\tt.Run(\"by working dir\", func(t *testing.T) {\n\t\topts, err := NewProjectOptions([]string{\"testdata/simple/compose.yaml\"}, WithWorkingDirectory(\".\"))\n\t\tassert.NilError(t, err)\n\t\tp, err := ProjectFromOptions(opts)\n\t\tassert.NilError(t, err)\n\t\tassert.Equal(t, p.Name, \"cli\")\n\t})\n\n\tt.Run(\"by compose file parent dir\", func(t *testing.T) {\n\t\topts, err := NewProjectOptions([]string{\"testdata/simple/compose.yaml\"})\n\t\tassert.NilError(t, err)\n\t\tp, err := ProjectFromOptions(opts)\n\t\tassert.NilError(t, err)\n\t\tassert.Equal(t, p.Name, \"simple\")\n\t})\n\n\tt.Run(\"by COMPOSE_PROJECT_NAME\", func(t *testing.T) {\n\t\tos.Setenv(\"COMPOSE_PROJECT_NAME\", \"my_project_from_env\")\n\t\tdefer os.Unsetenv(\"COMPOSE_PROJECT_NAME\")\n\t\topts, err := NewProjectOptions([]string{\"testdata/simple/compose.yaml\"}, WithOsEnv)\n\t\tassert.NilError(t, err)\n\t\tp, err := ProjectFromOptions(opts)\n\t\tassert.NilError(t, err)\n\t\tassert.Equal(t, p.Name, \"my_project_from_env\")\n\t})\n\n\tt.Run(\"by .env\", func(t *testing.T) {\n\t\twd, err := os.Getwd()\n\t\tassert.NilError(t, err)\n\t\terr = os.Chdir(\"testdata/env-file\")\n\t\tassert.NilError(t, err)\n\t\tdefer os.Chdir(wd)\n\n\t\topts, err := NewProjectOptions(nil, WithDotEnv, WithConfigFileEnv)\n\t\tassert.NilError(t, err)\n\t\tp, err := ProjectFromOptions(opts)\n\t\tassert.NilError(t, err)\n\t\tassert.Equal(t, p.Name, \"my_project_from_dot_env\")\n\t})\n\n}\n\nfunc TestProjectFromSetOfFiles(t *testing.T) {\n\topts, err := NewProjectOptions([]string{\n\t\t\"testdata/simple/compose.yaml\",\n\t\t\"testdata/simple/compose-with-overrides.yaml\",\n\t}, WithName(\"my_project\"))\n\tassert.NilError(t, err)\n\tp, err := ProjectFromOptions(opts)\n\tassert.NilError(t, err)\n\tservice, err := p.GetService(\"simple\")\n\tassert.NilError(t, err)\n\tassert.Equal(t, service.Image, \"haproxy\")\n}\n\nfunc TestProjectComposefilesFromSetOfFiles(t *testing.T) {\n\topts, err := NewProjectOptions([]string{},\n\t\tWithWorkingDirectory(\"testdata/simple/\"),\n\t\tWithName(\"my_project\"),\n\t\tWithDefaultConfigPath,\n\t)\n\tassert.NilError(t, err)\n\tp, err := ProjectFromOptions(opts)\n\tassert.NilError(t, err)\n\tabsPath, _ := filepath.Abs(filepath.Join(\"testdata\", \"simple\", \"compose.yaml\"))\n\tassert.DeepEqual(t, p.ComposeFiles, []string{absPath})\n}\n\nfunc TestProjectComposefilesFromWorkingDir(t *testing.T) {\n\topts, err := NewProjectOptions([]string{\n\t\t\"testdata/simple/compose.yaml\",\n\t\t\"testdata/simple/compose-with-overrides.yaml\",\n\t}, WithName(\"my_project\"))\n\tassert.NilError(t, err)\n\tp, err := ProjectFromOptions(opts)\n\tassert.NilError(t, err)\n\tcurrentDir, _ := os.Getwd()\n\tassert.DeepEqual(t, p.ComposeFiles, []string{\n\t\tfilepath.Join(currentDir, \"testdata/simple/compose.yaml\"),\n\t\tfilepath.Join(currentDir, \"testdata/simple/compose-with-overrides.yaml\"),\n\t})\n}\n\nfunc TestProjectWithDotEnv(t *testing.T) {\n\twd, err := os.Getwd()\n\tassert.NilError(t, err)\n\terr = os.Chdir(\"testdata/simple\")\n\tassert.NilError(t, err)\n\tdefer os.Chdir(wd)\n\n\topts, err := NewProjectOptions([]string{\n\t\t\"compose-with-variables.yaml\",\n\t}, WithName(\"my_project\"), WithDotEnv)\n\tassert.NilError(t, err)\n\tp, err := ProjectFromOptions(opts)\n\tassert.NilError(t, err)\n\tservice, err := p.GetService(\"simple\")\n\tassert.NilError(t, err)\n\tassert.Equal(t, service.Ports[0].Published, uint32(8000))\n}\n\nfunc TestProjectWithDiscardEnvFile(t *testing.T) {\n\topts, err := NewProjectOptions([]string{\n\t\t\"testdata/env-file/compose-with-env-file.yaml\",\n\t}, WithDiscardEnvFile)\n\n\tassert.NilError(t, err)\n\tp, err := ProjectFromOptions(opts)\n\tassert.NilError(t, err)\n\tservice, err := p.GetService(\"simple\")\n\tassert.NilError(t, err)\n\tassert.Equal(t, *service.Environment[\"DEFAULT_PORT\"], \"8080\")\n\tassert.Assert(t, service.EnvFile == nil)\n}\n\nfunc TestProjectNameFromWorkingDir(t *testing.T) {\n\topts, err := NewProjectOptions([]string{\n\t\t\"testdata/env-file/compose-with-env-file.yaml\",\n\t})\n\tassert.NilError(t, err)\n\tp, err := ProjectFromOptions(opts)\n\tassert.NilError(t, err)\n\tassert.Equal(t, p.Name, \"env-file\")\n}\n\nfunc TestEnvMap(t *testing.T) {\n\tm := map[string]string{}\n\tm[\"foo\"] = \"bar\"\n\tl := getAsStringList(m)\n\tassert.Equal(t, l[0], \"foo=bar\")\n\tm = getAsEqualsMap(l)\n\tassert.Equal(t, m[\"foo\"], \"bar\")\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/cli/testdata/env-file/compose-with-env-file.yaml",
    "content": "version: \"3\"\nservices:\n  simple:\n    image: nginx\n    env_file:\n      - ./simple-env\n    ports:\n    - 8000:80\n"
  },
  {
    "path": "pkg/third_party/compose-go/cli/testdata/env-file/simple-env",
    "content": "DEFAULT_PORT=8080"
  },
  {
    "path": "pkg/third_party/compose-go/cli/testdata/simple/compose-with-overrides.yaml",
    "content": "services:\n  simple:\n    image: haproxy\n"
  },
  {
    "path": "pkg/third_party/compose-go/cli/testdata/simple/compose-with-variables.yaml",
    "content": "services:\n  simple:\n    image: nginx\n    ports:\n    - ${PUBLIC_PORT}:80\n"
  },
  {
    "path": "pkg/third_party/compose-go/cli/testdata/simple/compose.yaml",
    "content": "services:\n  simple:\n    image: nginx\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/allowlist.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/pkg/errors\"\n)\n\n// AllowList implements the Checker interface by rejecting all attributes that are not listed as \"supported\".\ntype AllowList struct {\n\tSupported []string\n\terrors    []error\n}\n\n// Errors returns the list of errors encountered when checking against the allow list\nfunc (c *AllowList) Errors() []error {\n\treturn c.errors\n}\n\nfunc (c *AllowList) supported(attributes ...string) bool {\n\tfor _, a := range attributes {\n\t\tfor _, s := range c.Supported {\n\t\t\tif s == a {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *AllowList) Unsupported(message string, args ...interface{}) {\n\tc.errors = append(c.errors, errors.Wrap(errdefs.ErrUnsupported, fmt.Sprintf(message, args...)))\n}\n\nfunc (c *AllowList) Incompatible(message string, args ...interface{}) {\n\tc.errors = append(c.errors, errors.Wrap(errdefs.ErrIncompatible, fmt.Sprintf(message, args...)))\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/allowlist_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport (\n\t\"testing\"\n\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/compose-spec/compose-go/loader\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"gotest.tools/v3/assert\"\n)\n\nfunc TestAllowList(t *testing.T) {\n\tvar checker Checker = customChecker{\n\t\t&AllowList{\n\t\t\tSupported: []string{\n\t\t\t\t\"services.image\",\n\t\t\t\t\"services.network_mode\",\n\t\t\t\t\"services.privileged\",\n\t\t\t\t\"services.networks\",\n\t\t\t\t\"services.scale\",\n\t\t\t},\n\t\t},\n\t}\n\tdict := []byte(`\nservices:\n  foo:\n    image: busybox\n    network_mode: host\n    privileged: true\n    mac_address: \"a:b:c:d\"\n`)\n\n\tproject, err := loader.Load(types.ConfigDetails{\n\t\tConfigFiles: []types.ConfigFile{\n\t\t\t{Filename: \"filename.yml\", Content: dict},\n\t\t},\n\t})\n\tassert.NilError(t, err)\n\n\tCheck(project, checker)\n\terrors := checker.Errors()\n\tassert.Check(t, len(errors) == 2)\n\tassert.Check(t, errdefs.IsUnsupportedError(errors[0]))\n\tassert.Equal(t, errors[0].Error(), \"services.mac_address: unsupported attribute\")\n\n\tassert.Check(t, errdefs.IsUnsupportedError(errors[1]))\n\tassert.Equal(t, errors[1].Error(), \"services.network_mode=host: unsupported attribute\")\n\n\tservice, err := project.GetService(\"foo\")\n\tassert.NilError(t, err)\n\tassert.Check(t, service.MacAddress == \"\")\n}\n\ntype customChecker struct {\n\t*AllowList\n}\n\nfunc (c customChecker) CheckNetworkMode(service *types.ServiceConfig) {\n\tif service.NetworkMode == \"host\" {\n\t\tc.Unsupported(\"services.network_mode=host\")\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/build.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport \"github.com/compose-spec/compose-go/types\"\n\nfunc (c *AllowList) CheckBuild(service *types.ServiceConfig) bool {\n\tif !c.supported(\"services.build\") && service.Build != nil {\n\t\tservice.Build = nil\n\t\tc.Unsupported(\"services.build\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckBuildArgs(build *types.BuildConfig) {\n\tif !c.supported(\"services.build.args\") && len(build.Args) != 0 {\n\t\tbuild.Args = nil\n\t\tc.Unsupported(\"services.build.args\")\n\t}\n}\n\nfunc (c *AllowList) CheckBuildLabels(build *types.BuildConfig) {\n\tif !c.supported(\"services.build.labels\") && len(build.Labels) != 0 {\n\t\tbuild.Labels = nil\n\t\tc.Unsupported(\"services.build.labels\")\n\t}\n}\n\nfunc (c *AllowList) CheckBuildCacheFrom(build *types.BuildConfig) {\n\tif !c.supported(\"services.build.cache_from\") && len(build.CacheFrom) != 0 {\n\t\tbuild.CacheFrom = nil\n\t\tc.Unsupported(\"services.build.cache_from\")\n\t}\n}\n\nfunc (c *AllowList) CheckBuildExtraHosts(build *types.BuildConfig) {\n\tif !c.supported(\"services.build.extra_hosts\") && len(build.ExtraHosts) != 0 {\n\t\tbuild.ExtraHosts = nil\n\t\tc.Unsupported(\"services.build.extra_hosts\")\n\t}\n}\n\nfunc (c *AllowList) CheckBuildIsolation(build *types.BuildConfig) {\n\tif !c.supported(\"services.build.isolation\") && build.Isolation != \"\" {\n\t\tbuild.Isolation = \"\"\n\t\tc.Unsupported(\"services.build.isolation\")\n\t}\n}\n\nfunc (c *AllowList) CheckBuildNetwork(build *types.BuildConfig) {\n\tif !c.supported(\"services.build.network\") && build.Network != \"\" {\n\t\tbuild.Network = \"\"\n\t\tc.Unsupported(\"services.build.network\")\n\t}\n}\n\nfunc (c *AllowList) CheckBuildTarget(build *types.BuildConfig) {\n\tif !c.supported(\"services.build.target\") && build.Target != \"\" {\n\t\tbuild.Target = \"\"\n\t\tc.Unsupported(\"services.build.target\")\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/checker.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport (\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/compose-spec/compose-go/types\"\n)\n\ntype Checker interface {\n\tErrors() []error\n\tCheckBlkioConfig(build *types.ServiceConfig)\n\tCheckBlkioWeight(build *types.BlkioConfig)\n\tCheckBlkioWeightDevice(build *types.BlkioConfig)\n\tCheckBlkioDeviceReadBps(build *types.BlkioConfig)\n\tCheckBlkioDeviceReadIOps(build *types.BlkioConfig)\n\tCheckBlkioDeviceWriteBps(build *types.BlkioConfig)\n\tCheckBlkioDeviceWriteIOps(build *types.BlkioConfig)\n\tCheckBuild(build *types.ServiceConfig) bool\n\tCheckBuildArgs(build *types.BuildConfig)\n\tCheckBuildLabels(build *types.BuildConfig)\n\tCheckBuildCacheFrom(build *types.BuildConfig)\n\tCheckBuildExtraHosts(build *types.BuildConfig)\n\tCheckBuildIsolation(build *types.BuildConfig)\n\tCheckBuildNetwork(build *types.BuildConfig)\n\tCheckBuildTarget(build *types.BuildConfig)\n\tCheckCapAdd(service *types.ServiceConfig)\n\tCheckCapDrop(service *types.ServiceConfig)\n\tCheckCgroupParent(service *types.ServiceConfig)\n\tCheckCPUCount(service *types.ServiceConfig)\n\tCheckCPUPercent(service *types.ServiceConfig)\n\tCheckCPUPeriod(service *types.ServiceConfig)\n\tCheckCPUQuota(service *types.ServiceConfig)\n\tCheckCPURTRuntime(service *types.ServiceConfig)\n\tCheckCPURTPeriod(service *types.ServiceConfig)\n\tCheckCPUs(service *types.ServiceConfig)\n\tCheckCPUSet(service *types.ServiceConfig)\n\tCheckCPUShares(service *types.ServiceConfig)\n\tCheckCommand(service *types.ServiceConfig)\n\tCheckConfigs(service *types.ServiceConfig)\n\tCheckContainerName(service *types.ServiceConfig)\n\tCheckCredentialSpec(service *types.ServiceConfig)\n\tCheckDependsOn(service *types.ServiceConfig)\n\tCheckDevices(service *types.ServiceConfig)\n\tCheckDNS(service *types.ServiceConfig)\n\tCheckDNSOpts(service *types.ServiceConfig)\n\tCheckDNSSearch(service *types.ServiceConfig)\n\tCheckDomainName(service *types.ServiceConfig)\n\tCheckEntrypoint(service *types.ServiceConfig)\n\tCheckEnvironment(service *types.ServiceConfig)\n\tCheckEnvFile(service *types.ServiceConfig)\n\tCheckExpose(service *types.ServiceConfig)\n\tCheckExtends(service *types.ServiceConfig)\n\tCheckExternalLinks(service *types.ServiceConfig)\n\tCheckExtraHosts(service *types.ServiceConfig)\n\tCheckGroupAdd(service *types.ServiceConfig)\n\tCheckHostname(service *types.ServiceConfig)\n\tCheckHealthCheckTest(h *types.HealthCheckConfig)\n\tCheckHealthCheckTimeout(h *types.HealthCheckConfig)\n\tCheckHealthCheckInterval(h *types.HealthCheckConfig)\n\tCheckHealthCheckRetries(h *types.HealthCheckConfig)\n\tCheckHealthCheckStartPeriod(h *types.HealthCheckConfig)\n\tCheckImage(service *types.ServiceConfig)\n\tCheckInit(service *types.ServiceConfig)\n\tCheckIpc(service *types.ServiceConfig)\n\tCheckIsolation(service *types.ServiceConfig)\n\tCheckLabels(service *types.ServiceConfig)\n\tCheckLinks(service *types.ServiceConfig)\n\tCheckLoggingDriver(logging *types.LoggingConfig)\n\tCheckLoggingOptions(logging *types.LoggingConfig)\n\tCheckMemLimit(service *types.ServiceConfig)\n\tCheckMemReservation(service *types.ServiceConfig)\n\tCheckMemSwapLimit(service *types.ServiceConfig)\n\tCheckMemSwappiness(service *types.ServiceConfig)\n\tCheckMacAddress(service *types.ServiceConfig)\n\tCheckNet(service *types.ServiceConfig)\n\tCheckNetworkMode(service *types.ServiceConfig)\n\tCheckNetworkAliases(n *types.ServiceNetworkConfig)\n\tCheckNetworkIpv4Address(n *types.ServiceNetworkConfig)\n\tCheckNetworkIpv6Address(n *types.ServiceNetworkConfig)\n\tCheckOomKillDisable(service *types.ServiceConfig)\n\tCheckOomScoreAdj(service *types.ServiceConfig)\n\tCheckPid(service *types.ServiceConfig)\n\tCheckPidsLimit(service *types.ServiceConfig)\n\tCheckPlatform(service *types.ServiceConfig)\n\tCheckPortsMode(p *types.ServicePortConfig)\n\tCheckPortsTarget(p *types.ServicePortConfig)\n\tCheckPortsPublished(p *types.ServicePortConfig)\n\tCheckPortsProtocol(p *types.ServicePortConfig)\n\tCheckPrivileged(service *types.ServiceConfig)\n\tCheckPullPolicy(service *types.ServiceConfig)\n\tCheckReadOnly(service *types.ServiceConfig)\n\tCheckRestart(service *types.ServiceConfig)\n\tCheckRuntime(service *types.ServiceConfig)\n\tCheckScale(service *types.ServiceConfig)\n\tCheckSecrets(service *types.ServiceConfig)\n\tCheckFileReferenceSource(s string, config *types.FileReferenceConfig)\n\tCheckFileReferenceTarget(s string, config *types.FileReferenceConfig)\n\tCheckFileReferenceUID(s string, config *types.FileReferenceConfig)\n\tCheckFileReferenceGID(s string, config *types.FileReferenceConfig)\n\tCheckFileReferenceMode(s string, config *types.FileReferenceConfig)\n\tCheckSecurityOpt(service *types.ServiceConfig)\n\tCheckShmSize(service *types.ServiceConfig)\n\tCheckStdinOpen(service *types.ServiceConfig)\n\tCheckStopGracePeriod(service *types.ServiceConfig)\n\tCheckStopSignal(service *types.ServiceConfig)\n\tCheckSysctls(service *types.ServiceConfig)\n\tCheckTmpfs(service *types.ServiceConfig)\n\tCheckTty(service *types.ServiceConfig)\n\tCheckUlimits(service *types.ServiceConfig)\n\tCheckUser(service *types.ServiceConfig)\n\tCheckUserNSMode(service *types.ServiceConfig)\n\tCheckUts(service *types.ServiceConfig)\n\tCheckVolumeDriver(service *types.ServiceConfig)\n\tCheckVolumesSource(config *types.ServiceVolumeConfig)\n\tCheckVolumesTarget(config *types.ServiceVolumeConfig)\n\tCheckVolumesReadOnly(config *types.ServiceVolumeConfig)\n\tCheckVolumesConsistency(config *types.ServiceVolumeConfig)\n\tCheckVolumesBind(config *types.ServiceVolumeBind)\n\tCheckVolumesVolume(config *types.ServiceVolumeVolume)\n\tCheckVolumesTmpfs(config *types.ServiceVolumeTmpfs)\n\tCheckVolumesFrom(service *types.ServiceConfig)\n\tCheckWorkingDir(service *types.ServiceConfig)\n\tCheckVolumeConfigDriver(config *types.VolumeConfig)\n\tCheckVolumeConfigDriverOpts(config *types.VolumeConfig)\n\tCheckVolumeConfigExternal(config *types.VolumeConfig)\n\tCheckVolumeConfigLabels(config *types.VolumeConfig)\n\tCheckFileObjectConfigFile(s string, config *types.FileObjectConfig)\n\tCheckFileObjectConfigExternal(s string, config *types.FileObjectConfig)\n\tCheckFileObjectConfigLabels(s string, config *types.FileObjectConfig)\n\tCheckFileObjectConfigDriver(s string, config *types.FileObjectConfig)\n\tCheckFileObjectConfigDriverOpts(s string, config *types.FileObjectConfig)\n\tCheckFileObjectConfigTemplateDriver(s string, config *types.FileObjectConfig)\n\tCheckDeploy(deploy *types.ServiceConfig) bool\n\tCheckDeployEndpointMode(deploy *types.DeployConfig)\n\tCheckDeployLabels(deploy *types.DeployConfig)\n\tCheckDeployMode(deploy *types.DeployConfig)\n\tCheckDeployReplicas(deploy *types.DeployConfig)\n\tCheckDeployRestartPolicy(deploy *types.DeployConfig) bool\n\tCheckDeployRollbackConfig(deploy *types.DeployConfig) bool\n\tCheckDeployUpdateConfig(deploy *types.DeployConfig) bool\n\tCheckPlacementConstraints(p *types.Placement)\n\tCheckPlacementMaxReplicas(p *types.Placement)\n\tCheckPlacementPreferences(p *types.Placement)\n\tCheckRestartPolicyDelay(policy *types.RestartPolicy)\n\tCheckRestartPolicyCondition(policy *types.RestartPolicy)\n\tCheckRestartPolicyMaxAttempts(policy *types.RestartPolicy)\n\tCheckRestartPolicyWindow(policy *types.RestartPolicy)\n\tCheckUpdateConfigDelay(rollback string, config *types.UpdateConfig)\n\tCheckUpdateConfigFailureAction(rollback string, config *types.UpdateConfig)\n\tCheckUpdateConfigMaxFailureRatio(rollback string, config *types.UpdateConfig)\n\tCheckUpdateConfigMonitor(rollback string, config *types.UpdateConfig)\n\tCheckUpdateConfigOrder(rollback string, config *types.UpdateConfig)\n\tCheckUpdateConfigParallelism(rollback string, config *types.UpdateConfig)\n\tCheckDeployResourcesNanoCPUs(s string, resource *types.Resource)\n\tCheckDeployResourcesMemoryBytes(s string, resource *types.Resource)\n\tCheckDeployResourcesDevices(s string, resource *types.Resource)\n\tCheckDeployResourcesDevicesCapabilities(s string, r types.DeviceRequest)\n\tCheckDeployResourcesDevicesCount(s string, r types.DeviceRequest)\n\tCheckDeployResourcesDevicesIDs(s string, r types.DeviceRequest)\n\tCheckDeployResourcesDevicesDriver(s string, r types.DeviceRequest)\n\tCheckDeployResourcesGenericResources(s string, resource *types.Resource)\n\tCheckDeployResourcesLimits(deploy *types.DeployConfig) bool\n\tCheckDeployResourcesReservations(deploy *types.DeployConfig) bool\n\tCheckHealthCheck(service *types.ServiceConfig) bool\n\tCheckLogging(service *types.ServiceConfig) bool\n\tCheckNetworks(service *types.ServiceConfig) bool\n\tCheckPorts(service *types.ServiceConfig) bool\n\tCheckServiceVolumes(service *types.ServiceConfig) bool\n\tCheckNetworkConfigIpam(network *types.NetworkConfig)\n\tCheckNetworkConfigIpamSubnet(config *types.IPAMPool)\n\tCheckNetworkConfigIpamGateway(config *types.IPAMPool)\n\tCheckNetworkConfigIpamIPRange(config *types.IPAMPool)\n\tCheckNetworkConfigIpamAuxiliaryAddresses(config *types.IPAMPool)\n\tCheckNetworkConfigDriver(network *types.NetworkConfig)\n\tCheckNetworkConfigDriverOpts(network *types.NetworkConfig)\n\tCheckNetworkConfigExternal(network *types.NetworkConfig)\n\tCheckNetworkConfigInternal(network *types.NetworkConfig)\n\tCheckNetworkConfigAttachable(network *types.NetworkConfig)\n\tCheckNetworkConfigLabels(network *types.NetworkConfig)\n}\n\nfunc Check(project *types.Project, c Checker) {\n\tfor i, service := range project.Services {\n\t\tCheckServiceConfig(&service, c)\n\t\tproject.Services[i] = service\n\t}\n\n\tfor i, network := range project.Networks {\n\t\tCheckNetworkConfig(&network, c)\n\t\tproject.Networks[i] = network\n\t}\n\n\tfor i, volume := range project.Volumes {\n\t\tCheckVolumeConfig(&volume, c)\n\t\tproject.Volumes[i] = volume\n\t}\n\n\tfor i, config := range project.Configs {\n\t\tCheckConfigsConfig(&config, c)\n\t\tproject.Configs[i] = config\n\t}\n\n\tfor i, secret := range project.Secrets {\n\t\tCheckSecretsConfig(&secret, c)\n\t\tproject.Secrets[i] = secret\n\t}\n}\n\n// IsCompatible return true if the checker didn't reported any incompatibility error\nfunc IsCompatible(c Checker) bool {\n\tfor _, err := range c.Errors() {\n\t\tif errdefs.IsIncompatibleError(err) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc CheckServiceConfig(service *types.ServiceConfig, c Checker) {\n\tc.CheckBlkioConfig(service)\n\tif service.Build != nil && c.CheckBuild(service) {\n\t\tc.CheckBuildArgs(service.Build)\n\t\tc.CheckBuildLabels(service.Build)\n\t\tc.CheckBuildCacheFrom(service.Build)\n\t\tc.CheckBuildNetwork(service.Build)\n\t\tc.CheckBuildTarget(service.Build)\n\t}\n\tc.CheckCapAdd(service)\n\tc.CheckCapDrop(service)\n\tc.CheckCgroupParent(service)\n\tc.CheckCPUCount(service)\n\tc.CheckCPUPercent(service)\n\tc.CheckCPUPeriod(service)\n\tc.CheckCPUQuota(service)\n\tc.CheckCPURTPeriod(service)\n\tc.CheckCPURTRuntime(service)\n\tc.CheckCPUs(service)\n\tc.CheckCPUSet(service)\n\tc.CheckCPUShares(service)\n\tc.CheckCommand(service)\n\tc.CheckConfigs(service)\n\tc.CheckContainerName(service)\n\tc.CheckCredentialSpec(service)\n\tc.CheckDependsOn(service)\n\tif service.Deploy != nil && c.CheckDeploy(service) {\n\t\tc.CheckDeployEndpointMode(service.Deploy)\n\t\tc.CheckDeployLabels(service.Deploy)\n\t\tc.CheckDeployMode(service.Deploy)\n\t\tc.CheckPlacementConstraints(&service.Deploy.Placement)\n\t\tc.CheckPlacementMaxReplicas(&service.Deploy.Placement)\n\t\tc.CheckPlacementPreferences(&service.Deploy.Placement)\n\t\tc.CheckDeployReplicas(service.Deploy)\n\t\tif service.Deploy.Resources.Limits != nil && c.CheckDeployResourcesLimits(service.Deploy) {\n\t\t\tc.CheckDeployResourcesNanoCPUs(ResourceLimits, service.Deploy.Resources.Limits)\n\t\t\tc.CheckDeployResourcesMemoryBytes(ResourceLimits, service.Deploy.Resources.Limits)\n\t\t\tc.CheckDeployResourcesGenericResources(ResourceLimits, service.Deploy.Resources.Limits)\n\t\t}\n\t\tif service.Deploy.Resources.Reservations != nil && c.CheckDeployResourcesReservations(service.Deploy) {\n\t\t\tc.CheckDeployResourcesNanoCPUs(ResourceReservations, service.Deploy.Resources.Reservations)\n\t\t\tc.CheckDeployResourcesMemoryBytes(ResourceReservations, service.Deploy.Resources.Reservations)\n\t\t\tc.CheckDeployResourcesGenericResources(ResourceReservations, service.Deploy.Resources.Reservations)\n\t\t\tc.CheckDeployResourcesDevices(ResourceReservations, service.Deploy.Resources.Reservations)\n\t\t}\n\t\tif service.Deploy.RestartPolicy != nil && c.CheckDeployRestartPolicy(service.Deploy) {\n\t\t\tc.CheckRestartPolicyCondition(service.Deploy.RestartPolicy)\n\t\t\tc.CheckRestartPolicyDelay(service.Deploy.RestartPolicy)\n\t\t\tc.CheckRestartPolicyMaxAttempts(service.Deploy.RestartPolicy)\n\t\t\tc.CheckRestartPolicyWindow(service.Deploy.RestartPolicy)\n\t\t}\n\t\tif service.Deploy.UpdateConfig != nil && c.CheckDeployUpdateConfig(service.Deploy) {\n\t\t\tc.CheckUpdateConfigDelay(UpdateConfigUpdate, service.Deploy.UpdateConfig)\n\t\t\tc.CheckUpdateConfigFailureAction(UpdateConfigUpdate, service.Deploy.UpdateConfig)\n\t\t\tc.CheckUpdateConfigMaxFailureRatio(UpdateConfigUpdate, service.Deploy.UpdateConfig)\n\t\t\tc.CheckUpdateConfigMonitor(UpdateConfigUpdate, service.Deploy.UpdateConfig)\n\t\t\tc.CheckUpdateConfigOrder(UpdateConfigUpdate, service.Deploy.UpdateConfig)\n\t\t\tc.CheckUpdateConfigParallelism(UpdateConfigUpdate, service.Deploy.UpdateConfig)\n\t\t}\n\t\tif service.Deploy.RollbackConfig != nil && c.CheckDeployRollbackConfig(service.Deploy) {\n\t\t\tc.CheckUpdateConfigDelay(UpdateConfigRollback, service.Deploy.RollbackConfig)\n\t\t\tc.CheckUpdateConfigFailureAction(UpdateConfigRollback, service.Deploy.RollbackConfig)\n\t\t\tc.CheckUpdateConfigMaxFailureRatio(UpdateConfigRollback, service.Deploy.RollbackConfig)\n\t\t\tc.CheckUpdateConfigMonitor(UpdateConfigRollback, service.Deploy.RollbackConfig)\n\t\t\tc.CheckUpdateConfigOrder(UpdateConfigRollback, service.Deploy.RollbackConfig)\n\t\t\tc.CheckUpdateConfigParallelism(UpdateConfigRollback, service.Deploy.RollbackConfig)\n\t\t}\n\t}\n\tc.CheckDevices(service)\n\tc.CheckDNS(service)\n\tc.CheckDNSOpts(service)\n\tc.CheckDNSSearch(service)\n\tc.CheckDomainName(service)\n\tc.CheckEntrypoint(service)\n\tc.CheckEnvironment(service)\n\tc.CheckEnvFile(service)\n\tc.CheckExpose(service)\n\tc.CheckExtends(service)\n\tc.CheckExternalLinks(service)\n\tc.CheckExtraHosts(service)\n\tc.CheckGroupAdd(service)\n\tc.CheckHostname(service)\n\tif service.HealthCheck != nil && c.CheckHealthCheck(service) {\n\t\tc.CheckHealthCheckInterval(service.HealthCheck)\n\t\tc.CheckHealthCheckRetries(service.HealthCheck)\n\t\tc.CheckHealthCheckStartPeriod(service.HealthCheck)\n\t\tc.CheckHealthCheckTest(service.HealthCheck)\n\t\tc.CheckHealthCheckTimeout(service.HealthCheck)\n\t}\n\tc.CheckImage(service)\n\tc.CheckInit(service)\n\tc.CheckIpc(service)\n\tc.CheckIsolation(service)\n\tc.CheckLabels(service)\n\tc.CheckLinks(service)\n\tif service.Logging != nil && c.CheckLogging(service) {\n\t\tc.CheckLoggingDriver(service.Logging)\n\t\tc.CheckLoggingOptions(service.Logging)\n\t}\n\tc.CheckMemLimit(service)\n\tc.CheckMemReservation(service)\n\tc.CheckMemSwapLimit(service)\n\tc.CheckMemSwappiness(service)\n\tc.CheckMacAddress(service)\n\tc.CheckNet(service)\n\tc.CheckNetworkMode(service)\n\tif len(service.Networks) > 0 && c.CheckNetworks(service) {\n\t\tfor _, n := range service.Networks {\n\t\t\tif n != nil {\n\t\t\t\tc.CheckNetworkAliases(n)\n\t\t\t\tc.CheckNetworkIpv4Address(n)\n\t\t\t\tc.CheckNetworkIpv6Address(n)\n\t\t\t}\n\t\t}\n\t}\n\tc.CheckOomKillDisable(service)\n\tc.CheckOomScoreAdj(service)\n\tc.CheckPid(service)\n\tc.CheckPidsLimit(service)\n\tc.CheckPlatform(service)\n\tif len(service.Ports) > 0 && c.CheckPorts(service) {\n\t\tfor i, p := range service.Ports {\n\t\t\tc.CheckPortsMode(&p)\n\t\t\tc.CheckPortsTarget(&p)\n\t\t\tc.CheckPortsProtocol(&p)\n\t\t\tc.CheckPortsPublished(&p)\n\t\t\tservice.Ports[i] = p\n\t\t}\n\t}\n\tc.CheckPrivileged(service)\n\tc.CheckPullPolicy(service)\n\tc.CheckReadOnly(service)\n\tc.CheckRestart(service)\n\tc.CheckRuntime(service)\n\tc.CheckScale(service)\n\tc.CheckSecrets(service)\n\tc.CheckSecurityOpt(service)\n\tc.CheckShmSize(service)\n\tc.CheckStdinOpen(service)\n\tc.CheckStopGracePeriod(service)\n\tc.CheckStopSignal(service)\n\tc.CheckSysctls(service)\n\tc.CheckTmpfs(service)\n\tc.CheckTty(service)\n\tc.CheckUlimits(service)\n\tc.CheckUser(service)\n\tc.CheckUserNSMode(service)\n\tc.CheckUts(service)\n\tc.CheckVolumeDriver(service)\n\tif len(service.Volumes) > 0 && c.CheckServiceVolumes(service) {\n\t\tfor i, v := range service.Volumes {\n\t\t\tc.CheckVolumesSource(&v)\n\t\t\tc.CheckVolumesTarget(&v)\n\t\t\tc.CheckVolumesReadOnly(&v)\n\t\t\tswitch v.Type {\n\t\t\tcase types.VolumeTypeBind:\n\t\t\t\tc.CheckVolumesBind(v.Bind)\n\t\t\tcase types.VolumeTypeVolume:\n\t\t\t\tc.CheckVolumesVolume(v.Volume)\n\t\t\tcase types.VolumeTypeTmpfs:\n\t\t\t\tc.CheckVolumesTmpfs(v.Tmpfs)\n\t\t\t}\n\t\t\tservice.Volumes[i] = v\n\t\t}\n\t}\n\tc.CheckVolumesFrom(service)\n\tc.CheckWorkingDir(service)\n}\n\nfunc CheckNetworkConfig(network *types.NetworkConfig, c Checker) {\n\tc.CheckNetworkConfigDriver(network)\n\tc.CheckNetworkConfigDriverOpts(network)\n\tc.CheckNetworkConfigIpam(network)\n\tc.CheckNetworkConfigExternal(network)\n\tc.CheckNetworkConfigInternal(network)\n\tc.CheckNetworkConfigAttachable(network)\n\tc.CheckNetworkConfigLabels(network)\n}\n\nfunc CheckVolumeConfig(config *types.VolumeConfig, c Checker) {\n\tc.CheckVolumeConfigDriver(config)\n\tc.CheckVolumeConfigDriverOpts(config)\n\tc.CheckVolumeConfigExternal(config)\n\tc.CheckVolumeConfigLabels(config)\n}\n\nfunc CheckConfigsConfig(config *types.ConfigObjConfig, c Checker) {\n\tref := types.FileObjectConfig(*config)\n\tCheckFileObjectConfig(\"configs\", &ref, c)\n}\n\nfunc CheckSecretsConfig(config *types.SecretConfig, c Checker) {\n\tref := types.FileObjectConfig(*config)\n\tCheckFileObjectConfig(\"secrets\", &ref, c)\n}\n\nfunc CheckFileObjectConfig(s string, config *types.FileObjectConfig, c Checker) {\n\tc.CheckFileObjectConfigDriver(s, config)\n\tc.CheckFileObjectConfigDriverOpts(s, config)\n\tc.CheckFileObjectConfigExternal(s, config)\n\tc.CheckFileObjectConfigFile(s, config)\n\tc.CheckFileObjectConfigLabels(s, config)\n\tc.CheckFileObjectConfigTemplateDriver(s, config)\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/configs.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n)\n\nfunc (c *AllowList) CheckFileObjectConfigFile(s string, config *types.FileObjectConfig) {\n\tk := fmt.Sprintf(\"%s.file\", s)\n\tif !c.supported(k) && config.File != \"\" {\n\t\tconfig.File = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileObjectConfigExternal(s string, config *types.FileObjectConfig) {\n\tk := fmt.Sprintf(\"%s.external\", s)\n\tif !c.supported(k) && config.External.External {\n\t\tconfig.External.External = false\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileObjectConfigLabels(s string, config *types.FileObjectConfig) {\n\tk := fmt.Sprintf(\"%s.labels\", s)\n\tif !c.supported(k) && len(config.Labels) != 0 {\n\t\tconfig.Labels = nil\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileObjectConfigDriver(s string, config *types.FileObjectConfig) {\n\tk := fmt.Sprintf(\"%s.driver\", s)\n\tif !c.supported(k) && config.Driver != \"\" {\n\t\tconfig.Driver = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileObjectConfigDriverOpts(s string, config *types.FileObjectConfig) {\n\tk := fmt.Sprintf(\"%s.driver_opts\", s)\n\tif !c.supported(k) && len(config.DriverOpts) != 0 {\n\t\tconfig.DriverOpts = nil\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileObjectConfigTemplateDriver(s string, config *types.FileObjectConfig) {\n\tk := fmt.Sprintf(\"%s.template_driver\", s)\n\tif !c.supported(k) && config.TemplateDriver != \"\" {\n\t\tconfig.TemplateDriver = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/deploy.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n)\n\nfunc (c *AllowList) CheckDeploy(service *types.ServiceConfig) bool {\n\tif !c.supported(\"services.deploy\") && service.Deploy != nil {\n\t\tservice.Deploy = nil\n\t\tc.Unsupported(\"services.deploy\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckDeployMode(config *types.DeployConfig) {\n\tif !c.supported(\"services.deploy.mode\") && config.Mode != \"\" {\n\t\tconfig.Mode = \"\"\n\t\tc.Unsupported(\"services.deploy.mode\")\n\t}\n}\nfunc (c *AllowList) CheckDeployReplicas(config *types.DeployConfig) {\n\tif !c.supported(\"services.deploy.replicas\") && config.Replicas != nil {\n\t\tconfig.Replicas = nil\n\t\tc.Unsupported(\"services.deploy.replicas\")\n\t}\n}\nfunc (c *AllowList) CheckDeployLabels(config *types.DeployConfig) {\n\tif !c.supported(\"services.deploy.labels\") && len(config.Labels) != 0 {\n\t\tconfig.Labels = nil\n\t\tc.Unsupported(\"services.deploy.labels\")\n\t}\n}\n\nconst (\n\tUpdateConfigUpdate   = \"update_config\"\n\tUpdateConfigRollback = \"rolback_config\"\n)\n\nfunc (c *AllowList) CheckDeployUpdateConfig(config *types.DeployConfig) bool {\n\tif !c.supported(\"services.deploy.update_config\") {\n\t\tconfig.UpdateConfig = nil\n\t\tc.Unsupported(\"services.deploy.update_config\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckDeployRollbackConfig(config *types.DeployConfig) bool {\n\tif !c.supported(\"services.deploy.rollback_config\") {\n\t\tconfig.RollbackConfig = nil\n\t\tc.Unsupported(\"services.deploy.rollback_config\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckUpdateConfigParallelism(s string, config *types.UpdateConfig) {\n\tk := fmt.Sprintf(\"services.deploy.%s.parallelism\", s)\n\tif !c.supported(k) && config.Parallelism != nil {\n\t\tconfig.Parallelism = nil\n\t\tc.Unsupported(k)\n\t}\n}\nfunc (c *AllowList) CheckUpdateConfigDelay(s string, config *types.UpdateConfig) {\n\tk := fmt.Sprintf(\"services.deploy.%s.delay\", s)\n\tif !c.supported(k) && config.Delay != 0 {\n\t\tconfig.Delay = 0\n\t\tc.Unsupported(k)\n\t}\n}\nfunc (c *AllowList) CheckUpdateConfigFailureAction(s string, config *types.UpdateConfig) {\n\tk := fmt.Sprintf(\"services.deploy.%s.failure_action\", s)\n\tif !c.supported(k) && config.FailureAction != \"\" {\n\t\tconfig.FailureAction = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\nfunc (c *AllowList) CheckUpdateConfigMonitor(s string, config *types.UpdateConfig) {\n\tk := fmt.Sprintf(\"services.deploy.%s.monitor\", s)\n\tif !c.supported(k) && config.Monitor != 0 {\n\t\tconfig.Monitor = 0\n\t\tc.Unsupported(k)\n\t}\n}\nfunc (c *AllowList) CheckUpdateConfigMaxFailureRatio(s string, config *types.UpdateConfig) {\n\tk := fmt.Sprintf(\"services.deploy.%s.max_failure_ratio\", s)\n\tif !c.supported(k) && config.MaxFailureRatio != 0 {\n\t\tconfig.MaxFailureRatio = 0\n\t\tc.Unsupported(k)\n\t}\n}\nfunc (c *AllowList) CheckUpdateConfigOrder(s string, config *types.UpdateConfig) {\n\tk := fmt.Sprintf(\"services.deploy.%s.order\", s)\n\tif !c.supported(k) && config.Order != \"\" {\n\t\tconfig.Order = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nconst (\n\tResourceLimits       = \"limits\"\n\tResourceReservations = \"reservations\"\n)\n\nfunc (c *AllowList) CheckDeployResourcesLimits(config *types.DeployConfig) bool {\n\tif !c.supported(\"services.deploy.resources.limits\") {\n\t\tconfig.Resources.Limits = nil\n\t\tc.Unsupported(\"services.deploy.resources.limits\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckDeployResourcesReservations(config *types.DeployConfig) bool {\n\tif !c.supported(\"services.deploy.resources.reservations\") {\n\t\tconfig.Resources.Reservations = nil\n\t\tc.Unsupported(\"services.deploy.resources.reservations\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckDeployResourcesNanoCPUs(s string, r *types.Resource) {\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.cpus\", s)\n\tif !c.supported(k) && r.NanoCPUs != \"\" {\n\t\tr.NanoCPUs = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\nfunc (c *AllowList) CheckDeployResourcesMemoryBytes(s string, r *types.Resource) {\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.memory\", s)\n\tif !c.supported(k) && r.MemoryBytes != 0 {\n\t\tr.MemoryBytes = 0\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckDeployResourcesDevices(s string, r *types.Resource) {\n\tif len(r.Devices) == 0 {\n\t\treturn\n\t}\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.devices\", s)\n\tif !c.supported(k) {\n\t\tr.Devices = nil\n\t\tc.Unsupported(k)\n\t\treturn\n\t}\n\tfor _, d := range r.Devices {\n\t\tc.CheckDeployResourcesDevicesCapabilities(s, d)\n\t\tc.CheckDeployResourcesDevicesCount(s, d)\n\t\tc.CheckDeployResourcesDevicesIDs(s, d)\n\t\tc.CheckDeployResourcesDevicesDriver(s, d)\n\t}\n}\n\nfunc (c *AllowList) CheckDeployResourcesDevicesCapabilities(s string, r types.DeviceRequest) {\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.devices.capabilities\", s)\n\tif !c.supported(k) && len(r.Capabilities) != 0 {\n\t\tr.Capabilities = nil\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckDeployResourcesDevicesCount(s string, r types.DeviceRequest) {\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.devices.count\", s)\n\tif !c.supported(k) && r.Count != 0 {\n\t\tr.Count = 0\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckDeployResourcesDevicesIDs(s string, r types.DeviceRequest) {\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.devices.device_ids\", s)\n\tif !c.supported(k) && len(r.IDs) != 0 {\n\t\tr.IDs = nil\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckDeployResourcesDevicesDriver(s string, r types.DeviceRequest) {\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.devices.driver\", s)\n\tif !c.supported(k) && r.Driver != \"\" {\n\t\tr.Driver = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckDeployResourcesGenericResources(s string, r *types.Resource) {\n\tk := fmt.Sprintf(\"services.deploy.resources.%s.generic_resources\", s)\n\tif !c.supported(k) && len(r.GenericResources) != 0 {\n\t\tr.GenericResources = nil\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckDeployRestartPolicy(config *types.DeployConfig) bool {\n\tif !c.supported(\"services.deploy.restart_policy\") {\n\t\tconfig.RestartPolicy = nil\n\t\tc.Unsupported(\"services.deploy.restart_policy\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckRestartPolicyCondition(p *types.RestartPolicy) {\n\tif !c.supported(\"services.deploy.restart_policy.condition\") && p.Condition != \"\" {\n\t\tp.Condition = \"\"\n\t\tc.Unsupported(\"services.deploy.restart_policy.condition\")\n\t}\n}\nfunc (c *AllowList) CheckRestartPolicyDelay(p *types.RestartPolicy) {\n\tif !c.supported(\"services.deploy.restart_policy.delay\") && p.Delay != nil {\n\t\tp.Delay = nil\n\t\tc.Unsupported(\"services.deploy.restart_policy.delay\")\n\t}\n}\nfunc (c *AllowList) CheckRestartPolicyMaxAttempts(p *types.RestartPolicy) {\n\tif !c.supported(\"services.deploy.restart_policy.max_attempts\") && p.MaxAttempts != nil {\n\t\tp.MaxAttempts = nil\n\t\tc.Unsupported(\"services.deploy.restart_policy.max_attempts\")\n\t}\n}\nfunc (c *AllowList) CheckRestartPolicyWindow(p *types.RestartPolicy) {\n\tif !c.supported(\"services.deploy.restart_policy.window\") && p.Window != nil {\n\t\tp.Window = nil\n\t\tc.Unsupported(\"services.deploy.restart_policy.window\")\n\t}\n}\n\nfunc (c *AllowList) CheckPlacementConstraints(p *types.Placement) {\n\tif !c.supported(\"services.deploy.placement\", \"services.deploy.placement.constraints\") && len(p.Constraints) != 0 {\n\t\tp.Constraints = nil\n\t\tc.Unsupported(\"services.deploy.restart_policy.constraints\")\n\t}\n}\n\nfunc (c *AllowList) CheckPlacementPreferences(p *types.Placement) {\n\tif !c.supported(\"services.deploy.placement\", \"services.deploy.placement.preferences\") && p.Preferences != nil {\n\t\tp.Preferences = nil\n\t\tc.Unsupported(\"services.deploy.restart_policy.preferences\")\n\t}\n}\n\nfunc (c *AllowList) CheckPlacementMaxReplicas(p *types.Placement) {\n\tif !c.supported(\"services.deploy.placement\", \"services.deploy.placement.max_replicas_per_node\") && p.MaxReplicas != 0 {\n\t\tp.MaxReplicas = 0\n\t\tc.Unsupported(\"services.deploy.restart_policy.max_replicas_per_node\")\n\t}\n}\n\nfunc (c *AllowList) CheckDeployEndpointMode(config *types.DeployConfig) {\n\tif !c.supported(\"services.deploy.endpoint_mode\") && config.EndpointMode != \"\" {\n\t\tconfig.EndpointMode = \"\"\n\t\tc.Unsupported(\"services.deploy.endpoint_mode\")\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/networks.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport \"github.com/compose-spec/compose-go/types\"\n\nfunc (c *AllowList) CheckNetworkConfig(network *types.NetworkConfig) {\n\tc.CheckNetworkConfigDriver(network)\n\tc.CheckNetworkConfigDriverOpts(network)\n\tc.CheckNetworkConfigIpam(network)\n\tc.CheckNetworkConfigExternal(network)\n\tc.CheckNetworkConfigInternal(network)\n\tc.CheckNetworkConfigAttachable(network)\n\tc.CheckNetworkConfigLabels(network)\n}\n\nfunc (c *AllowList) CheckNetworkConfigDriver(config *types.NetworkConfig) {\n\tif !c.supported(\"networks.driver\") && config.Driver != \"\" {\n\t\tconfig.Driver = \"\"\n\t\tc.Unsupported(\"networks.driver\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigDriverOpts(config *types.NetworkConfig) {\n\tif !c.supported(\"networks.driver_opts\") && len(config.DriverOpts) != 0 {\n\t\tconfig.DriverOpts = nil\n\t\tc.Unsupported(\"networks.driver_opts\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigIpam(config *types.NetworkConfig) {\n\tc.CheckNetworkConfigIpamDriver(&config.Ipam)\n\tif len(config.Ipam.Config) != 0 {\n\t\tif !c.supported(\"networks.ipam.config\") {\n\t\t\tc.Unsupported(\"networks.ipam.config\")\n\t\t\treturn\n\t\t}\n\t\tfor _, p := range config.Ipam.Config {\n\t\t\tc.CheckNetworkConfigIpamSubnet(p)\n\t\t\tc.CheckNetworkConfigIpamGateway(p)\n\t\t\tc.CheckNetworkConfigIpamIPRange(p)\n\t\t\tc.CheckNetworkConfigIpamAuxiliaryAddresses(p)\n\t\t}\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigIpamDriver(config *types.IPAMConfig) {\n\tif !c.supported(\"networks.ipam.driver\") && config.Driver != \"\" {\n\t\tconfig.Driver = \"\"\n\t\tc.Unsupported(\"networks.ipam.driver\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigIpamSubnet(config *types.IPAMPool) {\n\tif !c.supported(\"networks.ipam.config.subnet\") && config.Subnet != \"\" {\n\t\tconfig.Subnet = \"\"\n\t\tc.Unsupported(\"networks.ipam.config.subnet\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigIpamGateway(config *types.IPAMPool) {\n\tif !c.supported(\"networks.ipam.config.gateway\") && config.Gateway != \"\" {\n\t\tconfig.Gateway = \"\"\n\t\tc.Unsupported(\"networks.ipam.config.gateway\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigIpamIPRange(config *types.IPAMPool) {\n\tif !c.supported(\"networks.ipam.config.ip_range\") && config.IPRange != \"\" {\n\t\tconfig.IPRange = \"\"\n\t\tc.Unsupported(\"networks.ipam.config.ip_range\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigIpamAuxiliaryAddresses(config *types.IPAMPool) {\n\tif !c.supported(\"networks.ipam.config.aux_addresses\") && len(config.AuxiliaryAddresses) > 0 {\n\t\tconfig.AuxiliaryAddresses = nil\n\t\tc.Unsupported(\"networks.ipam.config.aux_addresses\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigExternal(config *types.NetworkConfig) {\n\tif !c.supported(\"networks.external\") && config.External.External {\n\t\tconfig.External.External = false\n\t\tc.Unsupported(\"networks.external\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigInternal(config *types.NetworkConfig) {\n\tif !c.supported(\"networks.internal\") && config.Internal {\n\t\tconfig.Internal = false\n\t\tc.Unsupported(\"networks.internal\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigAttachable(config *types.NetworkConfig) {\n\tif !c.supported(\"networks.attachable\") && config.Attachable {\n\t\tconfig.Attachable = false\n\t\tc.Unsupported(\"networks.attachable\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkConfigLabels(config *types.NetworkConfig) {\n\tif !c.supported(\"networks.labels\") && len(config.Labels) != 0 {\n\t\tconfig.Labels = nil\n\t\tc.Unsupported(\"networks.labels\")\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/services.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n)\n\nfunc (c *AllowList) CheckBlkioConfig(service *types.ServiceConfig) {\n\tif !c.supported(\"services.blkio_config\") && service.BlkioConfig != nil {\n\t\tservice.BlkioConfig = nil\n\t\tc.Unsupported(\"services.blkio_config\")\n\t}\n}\n\nfunc (c *AllowList) CheckBlkioWeight(config *types.BlkioConfig) {\n\tif !c.supported(\"services.blkio_config.weight\") && config.Weight != 0 {\n\t\tconfig.Weight = 0\n\t\tc.Unsupported(\"services.blkio_config.weight\")\n\t}\n}\n\nfunc (c *AllowList) CheckBlkioWeightDevice(config *types.BlkioConfig) {\n\tif !c.supported(\"services.blkio_config.weight_device\") && len(config.WeightDevice) != 0 {\n\t\tconfig.WeightDevice = nil\n\t\tc.Unsupported(\"services.blkio_config.weight_device\")\n\t}\n}\n\nfunc (c *AllowList) CheckBlkioDeviceReadBps(config *types.BlkioConfig) {\n\tif !c.supported(\"services.blkio_config.device_read_bps\") && len(config.DeviceWriteBps) != 0 {\n\t\tconfig.DeviceWriteBps = nil\n\t\tc.Unsupported(\"services.blkio_config.device_read_bps\")\n\t}\n}\n\nfunc (c *AllowList) CheckBlkioDeviceReadIOps(config *types.BlkioConfig) {\n\tif !c.supported(\"services.blkio_config.device_read_iops\") && len(config.DeviceReadIOps) != 0 {\n\t\tconfig.DeviceReadIOps = nil\n\t\tc.Unsupported(\"services.blkio_config.device_read_iops\")\n\t}\n}\n\nfunc (c *AllowList) CheckBlkioDeviceWriteBps(config *types.BlkioConfig) {\n\tif !c.supported(\"services.blkio_config.device_write_bps\") && len(config.DeviceWriteBps) != 0 {\n\t\tconfig.DeviceWriteBps = nil\n\t\tc.Unsupported(\"services.blkio_config.device_write_bps\")\n\t}\n}\n\nfunc (c *AllowList) CheckBlkioDeviceWriteIOps(config *types.BlkioConfig) {\n\tif !c.supported(\"services.blkio_config.device_write_iops\") && len(config.DeviceWriteIOps) != 0 {\n\t\tconfig.DeviceWriteIOps = nil\n\t\tc.Unsupported(\"services.blkio_config.device_write_iops\")\n\t}\n}\n\nfunc (c *AllowList) CheckCapAdd(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cap_add\") && len(service.CapAdd) != 0 {\n\t\tservice.CapAdd = nil\n\t\tc.Unsupported(\"services.cap_add\")\n\t}\n}\n\nfunc (c *AllowList) CheckCapDrop(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cap_drop\") && len(service.CapDrop) != 0 {\n\t\tservice.CapDrop = nil\n\t\tc.Unsupported(\"services.cap_drop\")\n\t}\n}\n\nfunc (c *AllowList) CheckCgroupParent(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cgroup_parent\") && service.CgroupParent != \"\" {\n\t\tservice.CgroupParent = \"\"\n\t\tc.Unsupported(\"services.cgroup_parent\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPUQuota(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpu_quota\") && service.CPUQuota != 0 {\n\t\tservice.CPUQuota = 0\n\t\tc.Unsupported(\"services.cpu_quota\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPUCount(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpu_count\") && service.CPUCount != 0 {\n\t\tservice.CPUCount = 0\n\t\tc.Unsupported(\"services.cpu_count\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPUPercent(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpu_percent\") && service.CPUPercent != 0 {\n\t\tservice.CPUPercent = 0\n\t\tc.Unsupported(\"services.cpu_percent\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPUPeriod(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpu_period\") && service.CPUPeriod != 0 {\n\t\tservice.CPUPeriod = 0\n\t\tc.Unsupported(\"services.cpu_period\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPURTRuntime(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpu_rt_runtime\") && service.CPURTRuntime != 0 {\n\t\tservice.CPURTRuntime = 0\n\t\tc.Unsupported(\"services.cpu_rt_period\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPURTPeriod(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpu_rt_period\") && service.CPURTPeriod != 0 {\n\t\tservice.CPURTPeriod = 0\n\t\tc.Unsupported(\"services.cpu_rt_period\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPUs(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpus\") && service.CPUS != 0 {\n\t\tservice.CPUS = 0\n\t\tc.Unsupported(\"services.cpus\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPUSet(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpuset\") && service.CPUSet != \"\" {\n\t\tservice.CPUSet = \"\"\n\t\tc.Unsupported(\"services.cpuset\")\n\t}\n}\n\nfunc (c *AllowList) CheckCPUShares(service *types.ServiceConfig) {\n\tif !c.supported(\"services.cpu_shares\") && service.CPUShares != 0 {\n\t\tservice.CPUShares = 0\n\t\tc.Unsupported(\"services.cpu_shares\")\n\t}\n}\n\nfunc (c *AllowList) CheckCommand(service *types.ServiceConfig) {\n\tif !c.supported(\"services.command\") && len(service.Command) != 0 {\n\t\tservice.Command = nil\n\t\tc.Unsupported(\"services.command\")\n\t}\n}\n\nfunc (c *AllowList) CheckConfigs(service *types.ServiceConfig) {\n\tif len(service.Configs) != 0 {\n\t\tif !c.supported(\"services.configs\") {\n\t\t\tservice.Configs = nil\n\t\t\tc.Unsupported(\"services.configs\")\n\t\t\treturn\n\t\t}\n\t\tfor i, s := range service.Secrets {\n\t\t\tref := types.FileReferenceConfig(s)\n\t\t\tc.CheckFileReference(\"configs\", &ref)\n\t\t\tservice.Secrets[i] = s\n\t\t}\n\t}\n}\n\nfunc (c *AllowList) CheckContainerName(service *types.ServiceConfig) {\n\tif !c.supported(\"services.container_name\") && service.ContainerName != \"\" {\n\t\tservice.ContainerName = \"\"\n\t\tc.Unsupported(\"services.container_name\")\n\t}\n}\n\nfunc (c *AllowList) CheckCredentialSpec(service *types.ServiceConfig) {\n\tif !c.supported(\"services.credential_spec\") && service.CredentialSpec != nil {\n\t\tservice.CredentialSpec = nil\n\t\tc.Unsupported(\"services.credential_spec\")\n\t}\n}\n\nfunc (c *AllowList) CheckDependsOn(service *types.ServiceConfig) {\n\tif !c.supported(\"services.depends_on\") && len(service.DependsOn) != 0 {\n\t\tservice.DependsOn = nil\n\t\tc.Unsupported(\"services.depends_on\")\n\t}\n}\n\nfunc (c *AllowList) CheckDevices(service *types.ServiceConfig) {\n\tif !c.supported(\"services.devices\") && len(service.Devices) != 0 {\n\t\tservice.Devices = nil\n\t\tc.Unsupported(\"services.devices\")\n\t}\n}\n\nfunc (c *AllowList) CheckDNS(service *types.ServiceConfig) {\n\tif !c.supported(\"services.dns\") && service.DNS != nil {\n\t\tservice.DNS = nil\n\t\tc.Unsupported(\"services.dns\")\n\t}\n}\n\nfunc (c *AllowList) CheckDNSOpts(service *types.ServiceConfig) {\n\tif !c.supported(\"services.dns_opt\") && len(service.DNSOpts) != 0 {\n\t\tservice.DNSOpts = nil\n\t\tc.Unsupported(\"services.dns_opt\")\n\t}\n}\n\nfunc (c *AllowList) CheckDNSSearch(service *types.ServiceConfig) {\n\tif !c.supported(\"services.dns_search\") && len(service.DNSSearch) != 0 {\n\t\tservice.DNSSearch = nil\n\t\tc.Unsupported(\"services.dns_search\")\n\t}\n}\n\nfunc (c *AllowList) CheckDomainName(service *types.ServiceConfig) {\n\tif !c.supported(\"services.domainname\") && service.DomainName != \"\" {\n\t\tservice.DomainName = \"\"\n\t\tc.Unsupported(\"services.domainname\")\n\t}\n}\n\nfunc (c *AllowList) CheckEntrypoint(service *types.ServiceConfig) {\n\tif !c.supported(\"services.entrypoint\") && len(service.Entrypoint) != 0 {\n\t\tservice.Entrypoint = nil\n\t\tc.Unsupported(\"services.entrypoint\")\n\t}\n}\n\nfunc (c *AllowList) CheckEnvironment(service *types.ServiceConfig) {\n\tif !c.supported(\"services.environment\") && len(service.Environment) != 0 {\n\t\tservice.Environment = nil\n\t\tc.Unsupported(\"services.environment\")\n\t}\n}\n\nfunc (c *AllowList) CheckEnvFile(service *types.ServiceConfig) {\n\tif !c.supported(\"services.env_file\") && len(service.EnvFile) != 0 {\n\t\tservice.EnvFile = nil\n\t\tc.Unsupported(\"services.env_file\")\n\t}\n}\n\nfunc (c *AllowList) CheckExpose(service *types.ServiceConfig) {\n\tif !c.supported(\"services.expose\") && len(service.Expose) != 0 {\n\t\tservice.Expose = nil\n\t\tc.Unsupported(\"services.expose\")\n\t}\n}\n\nfunc (c *AllowList) CheckExtends(service *types.ServiceConfig) {\n\tif !c.supported(\"services.extends\") && len(service.Extends) != 0 {\n\t\tservice.Extends = nil\n\t\tc.Unsupported(\"services.extends\")\n\t}\n}\n\nfunc (c *AllowList) CheckExternalLinks(service *types.ServiceConfig) {\n\tif !c.supported(\"services.external_links\") && len(service.ExternalLinks) != 0 {\n\t\tservice.ExternalLinks = nil\n\t\tc.Unsupported(\"services.external_links\")\n\t}\n}\n\nfunc (c *AllowList) CheckExtraHosts(service *types.ServiceConfig) {\n\tif !c.supported(\"services.extra_hosts\") && len(service.ExtraHosts) != 0 {\n\t\tservice.ExtraHosts = nil\n\t\tc.Unsupported(\"services.extra_hosts\")\n\t}\n}\n\nfunc (c *AllowList) CheckGroupAdd(service *types.ServiceConfig) {\n\tif !c.supported(\"services.group_app\") && len(service.GroupAdd) != 0 {\n\t\tservice.GroupAdd = nil\n\t\tc.Unsupported(\"services.group_app\")\n\t}\n}\n\nfunc (c *AllowList) CheckHostname(service *types.ServiceConfig) {\n\tif !c.supported(\"services.hostname\") && service.Hostname != \"\" {\n\t\tservice.Hostname = \"\"\n\t\tc.Unsupported(\"services.hostname\")\n\t}\n}\n\nfunc (c *AllowList) CheckHealthCheck(service *types.ServiceConfig) bool {\n\tif !c.supported(\"services.healthcheck\") {\n\t\tservice.HealthCheck = nil\n\t\tc.Unsupported(\"services.healthcheck\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckHealthCheckTest(h *types.HealthCheckConfig) {\n\tif !c.supported(\"services.healthcheck.test\") && len(h.Test) != 0 {\n\t\th.Test = nil\n\t\tc.Unsupported(\"services.healthcheck.test\")\n\t}\n}\n\nfunc (c *AllowList) CheckHealthCheckTimeout(h *types.HealthCheckConfig) {\n\tif !c.supported(\"services.healthcheck.timeout\") && h.Timeout != nil {\n\t\th.Timeout = nil\n\t\tc.Unsupported(\"services.healthcheck.timeout\")\n\t}\n}\n\nfunc (c *AllowList) CheckHealthCheckInterval(h *types.HealthCheckConfig) {\n\tif !c.supported(\"services.healthcheck.interval\") && h.Interval != nil {\n\t\th.Interval = nil\n\t\tc.Unsupported(\"services.healthcheck.interval\")\n\t}\n}\n\nfunc (c *AllowList) CheckHealthCheckRetries(h *types.HealthCheckConfig) {\n\tif !c.supported(\"services.healthcheck.retries\") && h.Retries != nil {\n\t\th.Retries = nil\n\t\tc.Unsupported(\"services.healthcheck.retries\")\n\t}\n}\n\nfunc (c *AllowList) CheckHealthCheckStartPeriod(h *types.HealthCheckConfig) {\n\tif !c.supported(\"services.healthcheck.start_period\") && h.StartPeriod != nil {\n\t\th.StartPeriod = nil\n\t\tc.Unsupported(\"services.healthcheck.start_period\")\n\t}\n}\n\nfunc (c *AllowList) CheckImage(service *types.ServiceConfig) {\n\tif !c.supported(\"services.image\") && service.Image != \"\" {\n\t\tservice.Image = \"\"\n\t\tc.Unsupported(\"services.image\")\n\t}\n}\n\nfunc (c *AllowList) CheckInit(service *types.ServiceConfig) {\n\tif !c.supported(\"services.init\") && service.Init != nil {\n\t\tservice.Init = nil\n\t\tc.Unsupported(\"services.init\")\n\t}\n}\n\nfunc (c *AllowList) CheckIpc(service *types.ServiceConfig) {\n\tif !c.supported(\"services.ipc\") && service.Ipc != \"\" {\n\t\tservice.Ipc = \"\"\n\t\tc.Unsupported(\"services.ipc\")\n\t}\n}\n\nfunc (c *AllowList) CheckIsolation(service *types.ServiceConfig) {\n\tif !c.supported(\"services.isolation\") && service.Isolation != \"\" {\n\t\tservice.Isolation = \"\"\n\t\tc.Unsupported(\"services.isolation\")\n\t}\n}\n\nfunc (c *AllowList) CheckLabels(service *types.ServiceConfig) {\n\tif !c.supported(\"services.labels\") && len(service.Labels) != 0 {\n\t\tservice.Labels = nil\n\t\tc.Unsupported(\"services.labels\")\n\t}\n}\n\nfunc (c *AllowList) CheckLinks(service *types.ServiceConfig) {\n\tif !c.supported(\"services.links\") && len(service.Links) != 0 {\n\t\tservice.Links = nil\n\t\tc.Unsupported(\"services.links\")\n\t}\n}\n\nfunc (c *AllowList) CheckLogging(service *types.ServiceConfig) bool {\n\tif !c.supported(\"services.logging\") {\n\t\tservice.Logging = nil\n\t\tc.Unsupported(\"services.logging\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckLoggingDriver(logging *types.LoggingConfig) {\n\tif !c.supported(\"services.logging.driver\") && logging.Driver != \"\" {\n\t\tlogging.Driver = \"\"\n\t\tc.Unsupported(\"services.logging.driver\")\n\t}\n}\n\nfunc (c *AllowList) CheckLoggingOptions(logging *types.LoggingConfig) {\n\tif !c.supported(\"services.logging.options\") && len(logging.Options) != 0 {\n\t\tlogging.Options = nil\n\t\tc.Unsupported(\"services.logging.options\")\n\t}\n}\n\nfunc (c *AllowList) CheckMemLimit(service *types.ServiceConfig) {\n\tif !c.supported(\"services.mem_limit\") && service.MemLimit != 0 {\n\t\tservice.MemLimit = 0\n\t\tc.Unsupported(\"services.mem_limit\")\n\t}\n}\n\nfunc (c *AllowList) CheckMemReservation(service *types.ServiceConfig) {\n\tif !c.supported(\"services.mem_reservation\") && service.MemReservation != 0 {\n\t\tservice.MemReservation = 0\n\t\tc.Unsupported(\"services.mem_reservation\")\n\t}\n}\n\nfunc (c *AllowList) CheckMemSwapLimit(service *types.ServiceConfig) {\n\tif !c.supported(\"services.memswap_limit\") && service.MemSwapLimit != 0 {\n\t\tservice.MemSwapLimit = 0\n\t\tc.Unsupported(\"services.memswap_limit\")\n\t}\n}\n\nfunc (c *AllowList) CheckMemSwappiness(service *types.ServiceConfig) {\n\tif !c.supported(\"services.mem_swappiness\") && service.MemSwappiness != 0 {\n\t\tservice.MemSwappiness = 0\n\t\tc.Unsupported(\"services.mem_swappiness\")\n\t}\n}\n\nfunc (c *AllowList) CheckMacAddress(service *types.ServiceConfig) {\n\tif !c.supported(\"services.mac_address\") && service.MacAddress != \"\" {\n\t\tservice.MacAddress = \"\"\n\t\tc.Unsupported(\"services.mac_address\")\n\t}\n}\n\nfunc (c *AllowList) CheckNet(service *types.ServiceConfig) {\n\tif !c.supported(\"services.net\") && service.Net != \"\" {\n\t\tservice.Net = \"\"\n\t\tc.Unsupported(\"services.net\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkMode(service *types.ServiceConfig) {\n\tif !c.supported(\"services.network_mode\") && service.NetworkMode != \"\" {\n\t\tservice.NetworkMode = \"\"\n\t\tc.Unsupported(\"services.network_mode\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworks(service *types.ServiceConfig) bool {\n\tif !c.supported(\"services.networks\") {\n\t\tservice.Networks = nil\n\t\tc.Unsupported(\"services.networks\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckNetworkAliases(n *types.ServiceNetworkConfig) {\n\tif !c.supported(\"services.networks.aliases\") && len(n.Aliases) != 0 {\n\t\tn.Aliases = nil\n\t\tc.Unsupported(\"services.networks.aliases\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkIpv4Address(n *types.ServiceNetworkConfig) {\n\tif !c.supported(\"services.networks.ipv4_address\") && n.Ipv4Address != \"\" {\n\t\tn.Ipv4Address = \"\"\n\t\tc.Unsupported(\"services.networks.ipv4_address\")\n\t}\n}\n\nfunc (c *AllowList) CheckNetworkIpv6Address(n *types.ServiceNetworkConfig) {\n\tif !c.supported(\"services.networks.ipv6_address\") && n.Ipv6Address != \"\" {\n\t\tn.Ipv6Address = \"\"\n\t\tc.Unsupported(\"services.networks.ipv6_address\")\n\t}\n}\n\nfunc (c *AllowList) CheckOomKillDisable(service *types.ServiceConfig) {\n\tif !c.supported(\"services.oom_kill_disable\") && service.OomKillDisable {\n\t\tservice.OomKillDisable = false\n\t\tc.Unsupported(\"services.oom_kill_disable\")\n\t}\n}\n\nfunc (c *AllowList) CheckOomScoreAdj(service *types.ServiceConfig) {\n\tif !c.supported(\"services.oom_score_adj\") && service.OomScoreAdj != 0 {\n\t\tservice.OomScoreAdj = 0\n\t\tc.Unsupported(\"services.oom_score_adj\")\n\t}\n}\n\nfunc (c *AllowList) CheckPid(service *types.ServiceConfig) {\n\tif !c.supported(\"services.pid\") && service.Pid != \"\" {\n\t\tservice.Pid = \"\"\n\t\tc.Unsupported(\"services.pid\")\n\t}\n}\n\nfunc (c *AllowList) CheckPidsLimit(service *types.ServiceConfig) {\n\tif !c.supported(\"services.pids_limit\") && service.PidsLimit != 0 {\n\t\tservice.PidsLimit = 0\n\t\tc.Unsupported(\"services.pids_limit\")\n\t}\n}\n\nfunc (c *AllowList) CheckPlatform(service *types.ServiceConfig) {\n\tif !c.supported(\"services.platform\") && service.Platform != \"\" {\n\t\tservice.Platform = \"\"\n\t\tc.Unsupported(\"services.platform\")\n\t}\n}\n\nfunc (c *AllowList) CheckPorts(service *types.ServiceConfig) bool {\n\tif !c.supported(\"services.ports\") {\n\t\tservice.Ports = nil\n\t\tc.Unsupported(\"services.ports\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckPortsMode(p *types.ServicePortConfig) {\n\tif !c.supported(\"services.ports.mode\") && p.Mode != \"\" {\n\t\tp.Mode = \"\"\n\t\tc.Unsupported(\"services.ports.mode\")\n\t}\n}\n\nfunc (c *AllowList) CheckPortsTarget(p *types.ServicePortConfig) {\n\tif !c.supported(\"services.ports.target\") && p.Target != 0 {\n\t\tp.Target = 0\n\t\tc.Unsupported(\"services.ports.target\")\n\t}\n}\n\nfunc (c *AllowList) CheckPortsPublished(p *types.ServicePortConfig) {\n\tif !c.supported(\"services.ports.published\") && p.Published != 0 {\n\t\tp.Published = 0\n\t\tc.Unsupported(\"services.ports.published\")\n\t}\n}\n\nfunc (c *AllowList) CheckPortsProtocol(p *types.ServicePortConfig) {\n\tif !c.supported(\"services.ports.protocol\") && p.Protocol != \"\" {\n\t\tp.Protocol = \"\"\n\t\tc.Unsupported(\"services.ports.protocol\")\n\t}\n}\n\nfunc (c *AllowList) CheckPrivileged(service *types.ServiceConfig) {\n\tif !c.supported(\"services.privileged\") && service.Privileged {\n\t\tservice.Privileged = false\n\t\tc.Unsupported(\"services.privileged\")\n\t}\n}\n\nfunc (c *AllowList) CheckPullPolicy(service *types.ServiceConfig) {\n\tif !c.supported(\"services.pull_policy\") && service.PullPolicy != \"\" {\n\t\tservice.PullPolicy = \"false\"\n\t\tc.Unsupported(\"services.pull_policy\")\n\t}\n}\n\nfunc (c *AllowList) CheckReadOnly(service *types.ServiceConfig) {\n\tif !c.supported(\"services.read_only\") && service.ReadOnly {\n\t\tservice.ReadOnly = false\n\t\tc.Unsupported(\"services.read_only\")\n\t}\n}\n\nfunc (c *AllowList) CheckRestart(service *types.ServiceConfig) {\n\tif !c.supported(\"services.restart\") && service.Restart != \"\" {\n\t\tservice.Restart = \"\"\n\t\tc.Unsupported(\"services.restart\")\n\t}\n}\n\nfunc (c *AllowList) CheckRuntime(service *types.ServiceConfig) {\n\tif !c.supported(\"services.runtime\") && service.Runtime != \"\" {\n\t\tservice.Runtime = \"\"\n\t\tc.Unsupported(\"services.runtime\")\n\t}\n}\n\nfunc (c *AllowList) CheckScale(service *types.ServiceConfig) {\n\tif !c.supported(\"services.scale\") && service.Scale != 0 {\n\t\tservice.Scale = 0\n\t\tc.Unsupported(\"services.scale\")\n\t}\n}\n\nfunc (c *AllowList) CheckSecrets(service *types.ServiceConfig) {\n\tif len(service.Secrets) != 0 {\n\t\tif !c.supported(\"services.secrets\") {\n\t\t\tservice.Secrets = nil\n\t\t\tc.Unsupported(\"services.secrets\")\n\t\t}\n\t\tfor i, s := range service.Secrets {\n\t\t\tref := types.FileReferenceConfig(s)\n\t\t\tc.CheckFileReference(\"services.secrets\", &ref)\n\t\t\tservice.Secrets[i] = s\n\t\t}\n\t}\n}\n\nfunc (c *AllowList) CheckFileReference(s string, config *types.FileReferenceConfig) {\n\tc.CheckFileReferenceSource(s, config)\n\tc.CheckFileReferenceTarget(s, config)\n\tc.CheckFileReferenceGID(s, config)\n\tc.CheckFileReferenceUID(s, config)\n\tc.CheckFileReferenceMode(s, config)\n}\n\nfunc (c *AllowList) CheckFileReferenceSource(s string, config *types.FileReferenceConfig) {\n\tk := fmt.Sprintf(\"%s.source\", s)\n\tif !c.supported(k) && config.Source != \"\" {\n\t\tconfig.Source = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileReferenceTarget(s string, config *types.FileReferenceConfig) {\n\tk := fmt.Sprintf(\"%s.target\", s)\n\tif !c.supported(k) && config.Target == \"\" {\n\t\tconfig.Target = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileReferenceUID(s string, config *types.FileReferenceConfig) {\n\tk := fmt.Sprintf(\"%s.uid\", s)\n\tif !c.supported(k) && config.UID != \"\" {\n\t\tconfig.UID = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileReferenceGID(s string, config *types.FileReferenceConfig) {\n\tk := fmt.Sprintf(\"%s.gid\", s)\n\tif !c.supported(k) && config.GID != \"\" {\n\t\tconfig.GID = \"\"\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckFileReferenceMode(s string, config *types.FileReferenceConfig) {\n\tk := fmt.Sprintf(\"%s.mode\", s)\n\tif !c.supported(k) && config.Mode != nil {\n\t\tconfig.Mode = nil\n\t\tc.Unsupported(k)\n\t}\n}\n\nfunc (c *AllowList) CheckSecurityOpt(service *types.ServiceConfig) {\n\tif !c.supported(\"services.security_opt\") && len(service.SecurityOpt) != 0 {\n\t\tservice.SecurityOpt = nil\n\t\tc.Unsupported(\"services.security_opt\")\n\t}\n}\n\nfunc (c *AllowList) CheckShmSize(service *types.ServiceConfig) {\n\tif !c.supported(\"services.shm_size\") && service.ShmSize != 0 {\n\t\tservice.ShmSize = 0\n\t\tc.Unsupported(\"services.shm_size\")\n\t}\n}\n\nfunc (c *AllowList) CheckStdinOpen(service *types.ServiceConfig) {\n\tif !c.supported(\"services.stdin_open\") && service.StdinOpen {\n\t\tservice.StdinOpen = true\n\t\tc.Unsupported(\"services.stdin_open\")\n\t}\n}\n\nfunc (c *AllowList) CheckStopGracePeriod(service *types.ServiceConfig) {\n\tif !c.supported(\"services.stop_grace_period\") && service.StopGracePeriod != nil {\n\t\tservice.StopGracePeriod = nil\n\t\tc.Unsupported(\"services.stop_grace_period\")\n\t}\n}\n\nfunc (c *AllowList) CheckStopSignal(service *types.ServiceConfig) {\n\tif !c.supported(\"services.stop_signal\") && service.StopSignal != \"\" {\n\t\tservice.StopSignal = \"\"\n\t\tc.Unsupported(\"services.stop_signal\")\n\t}\n}\n\nfunc (c *AllowList) CheckSysctls(service *types.ServiceConfig) {\n\tif !c.supported(\"services.sysctls\") && len(service.Sysctls) != 0 {\n\t\tservice.Sysctls = nil\n\t\tc.Unsupported(\"services.sysctls\")\n\t}\n}\n\nfunc (c *AllowList) CheckTmpfs(service *types.ServiceConfig) {\n\tif !c.supported(\"services.tmpfs\") && len(service.Tmpfs) != 0 {\n\t\tservice.Tmpfs = nil\n\t\tc.Unsupported(\"services.tmpfs\")\n\t}\n}\n\nfunc (c *AllowList) CheckTty(service *types.ServiceConfig) {\n\tif !c.supported(\"services.tty\") && service.Tty {\n\t\tservice.Tty = false\n\t\tc.Unsupported(\"services.tty\")\n\t}\n}\n\nfunc (c *AllowList) CheckUlimits(service *types.ServiceConfig) {\n\tif !c.supported(\"services.ulimits\") && len(service.Ulimits) != 0 {\n\t\tservice.Ulimits = nil\n\t\tc.Unsupported(\"services.ulimits\")\n\t}\n}\n\nfunc (c *AllowList) CheckUser(service *types.ServiceConfig) {\n\tif !c.supported(\"services.user\") && service.User != \"\" {\n\t\tservice.User = \"\"\n\t\tc.Unsupported(\"services.user\")\n\t}\n}\n\nfunc (c *AllowList) CheckUserNSMode(service *types.ServiceConfig) {\n\tif !c.supported(\"services.userns_mode\") && service.UserNSMode != \"\" {\n\t\tservice.UserNSMode = \"\"\n\t\tc.Unsupported(\"services.userns_mode\")\n\t}\n}\n\nfunc (c *AllowList) CheckUts(service *types.ServiceConfig) {\n\tif !c.supported(\"services.build\") && service.Uts != \"\" {\n\t\tservice.Uts = \"\"\n\t\tc.Unsupported(\"services.uts\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumeDriver(service *types.ServiceConfig) {\n\tif !c.supported(\"services.volume_driver\") && service.VolumeDriver != \"\" {\n\t\tservice.VolumeDriver = \"\"\n\t\tc.Unsupported(\"services.volume_driver\")\n\t}\n}\n\nfunc (c *AllowList) CheckServiceVolumes(service *types.ServiceConfig) bool {\n\tif !c.supported(\"services.volumes\") {\n\t\tservice.Volumes = nil\n\t\tc.Unsupported(\"services.volumes\")\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (c *AllowList) CheckVolumesSource(config *types.ServiceVolumeConfig) {\n\tif !c.supported(\"services.volumes.source\") && config.Source != \"\" {\n\t\tconfig.Source = \"\"\n\t\tc.Unsupported(\"services.volumes.source\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumesTarget(config *types.ServiceVolumeConfig) {\n\tif !c.supported(\"services.volumes.target\") && config.Target != \"\" {\n\t\tconfig.Target = \"\"\n\t\tc.Unsupported(\"services.volumes.target\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumesReadOnly(config *types.ServiceVolumeConfig) {\n\tif !c.supported(\"services.volumes.read_only\") && config.ReadOnly {\n\t\tconfig.ReadOnly = false\n\t\tc.Unsupported(\"services.volumes.read_only\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumesConsistency(config *types.ServiceVolumeConfig) {\n\tif !c.supported(\"services.volumes.consistency\") && config.Consistency != \"\" {\n\t\tconfig.Consistency = \"\"\n\t\tc.Unsupported(\"services.volumes.consistency\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumesBind(config *types.ServiceVolumeBind) {\n\tif config == nil {\n\t\treturn\n\t}\n\tif !c.supported(\"services.volumes.bind.propagation\") && config.Propagation != \"\" {\n\t\tconfig.Propagation = \"\"\n\t\tc.Unsupported(\"services.volumes.bind.propagation\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumesVolume(config *types.ServiceVolumeVolume) {\n\tif config == nil {\n\t\treturn\n\t}\n\tif !c.supported(\"services.volumes.nocopy\") && config.NoCopy {\n\t\tconfig.NoCopy = false\n\t\tc.Unsupported(\"services.volumes.nocopy\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumesTmpfs(config *types.ServiceVolumeTmpfs) {\n\tif config == nil {\n\t\treturn\n\t}\n\tif !c.supported(\"services.volumes.tmpfs.size\") && config.Size != 0 {\n\t\tconfig.Size = 0\n\t\tc.Unsupported(\"services.volumes.tmpfs.size\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumesFrom(service *types.ServiceConfig) {\n\tif !c.supported(\"services.volumes_from\") && len(service.VolumesFrom) != 0 {\n\t\tservice.VolumesFrom = nil\n\t\tc.Unsupported(\"services.volumes_from\")\n\t}\n}\n\nfunc (c *AllowList) CheckWorkingDir(service *types.ServiceConfig) {\n\tif !c.supported(\"services.working_dir\") && service.WorkingDir != \"\" {\n\t\tservice.WorkingDir = \"\"\n\t\tc.Unsupported(\"services.working_dir\")\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/compatibility/volumes.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage compatibility\n\nimport \"github.com/compose-spec/compose-go/types\"\n\nfunc (c *AllowList) CheckVolumeConfigDriver(config *types.VolumeConfig) {\n\tif !c.supported(\"volumes.driver\") && config.Driver != \"\" {\n\t\tconfig.Driver = \"\"\n\t\tc.Unsupported(\"volumes.driver\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumeConfigDriverOpts(config *types.VolumeConfig) {\n\tif !c.supported(\"volumes.driver_opts\") && len(config.DriverOpts) != 0 {\n\t\tconfig.DriverOpts = nil\n\t\tc.Unsupported(\"volumes.driver_opts\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumeConfigExternal(config *types.VolumeConfig) {\n\tif !c.supported(\"volumes.external\") && config.External.External {\n\t\tconfig.External.External = false\n\t\tc.Unsupported(\"volumes.external\")\n\t}\n}\n\nfunc (c *AllowList) CheckVolumeConfigLabels(config *types.VolumeConfig) {\n\tif !c.supported(\"volumes.labels\") && len(config.Labels) != 0 {\n\t\tconfig.Labels = nil\n\t\tc.Unsupported(\"volumes.labels\")\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/errdefs/errors.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage errdefs\n\nimport \"errors\"\n\nvar (\n\t// ErrNotFound is returned when an object is not found\n\tErrNotFound = errors.New(\"not found\")\n\n\t// ErrInvalid is returned when a compose project is invalid\n\tErrInvalid = errors.New(\"invalid compose project\")\n\n\t// ErrUnsupported is returned when a compose project uses an unsupported attribute\n\tErrUnsupported = errors.New(\"unsupported attribute\")\n\n\t// ErrIncompatible is returned when a compose project uses an incompatible attribute\n\tErrIncompatible = errors.New(\"incompatible attribute\")\n)\n\n// IsNotFoundError returns true if the unwrapped error is ErrNotFound\nfunc IsNotFoundError(err error) bool {\n\treturn errors.Is(err, ErrNotFound)\n}\n\n// IsInvalidError returns true if the unwrapped error is ErrInvalid\nfunc IsInvalidError(err error) bool {\n\treturn errors.Is(err, ErrInvalid)\n}\n\n// IsUnsupportedError returns true if the unwrapped error is ErrUnsupported\nfunc IsUnsupportedError(err error) bool {\n\treturn errors.Is(err, ErrUnsupported)\n}\n\n// IsIncompatibleError returns true if the unwrapped error is ErrIncompatible\nfunc IsIncompatibleError(err error) bool {\n\treturn errors.Is(err, ErrIncompatible)\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/go.mod",
    "content": "module github.com/compose-spec/compose-go\n\ngo 1.16\n\nrequire (\n\tgithub.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e\n\tgithub.com/docker/go-connections v0.4.0\n\tgithub.com/docker/go-units v0.4.0\n\tgithub.com/google/go-cmp v0.5.5\n\tgithub.com/imdario/mergo v0.3.12\n\tgithub.com/mattn/go-shellwords v1.0.12\n\tgithub.com/mitchellh/mapstructure v1.4.1\n\tgithub.com/opencontainers/go-digest v1.0.0\n\tgithub.com/pkg/errors v0.9.1\n\tgithub.com/sirupsen/logrus v1.8.1\n\tgithub.com/ulyssessouza/godotenv v1.3.1-0.20210806120901-e417b721114e\n\tgithub.com/xeipuuv/gojsonschema v1.2.0\n\tgolang.org/x/sync v0.0.0-20210220032951-036812b2e83c\n\tgolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect\n\tgopkg.in/yaml.v2 v2.4.0\n\tgotest.tools/v3 v3.0.3\n)\n"
  },
  {
    "path": "pkg/third_party/compose-go/go.sum",
    "content": "cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=\ngithub.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=\ngithub.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/aws/aws-sdk-go v1.34.9/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=\ngithub.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=\ngithub.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=\ngithub.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=\ngithub.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=\ngithub.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=\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/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=\ngithub.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=\ngithub.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e h1:n81KvOMrLZa+VWHwST7dun9f0G98X3zREHS1ztYzZKU=\ngithub.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e/go.mod h1:xpWTC2KnJMiDLkoawhsPQcXjvwATEBcbq0xevG2YR9M=\ngithub.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=\ngithub.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=\ngithub.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=\ngithub.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=\ngithub.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=\ngithub.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=\ngithub.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=\ngithub.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=\ngithub.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=\ngithub.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=\ngithub.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=\ngithub.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\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/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=\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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=\ngithub.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=\ngithub.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=\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.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=\ngithub.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=\ngithub.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\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.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=\ngithub.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=\ngithub.com/ulyssessouza/godotenv v1.3.1-0.20210806120901-e417b721114e h1:byEYm3QADv5mDUesYKstWwRodf2RoxxC/YuGOxtdqJw=\ngithub.com/ulyssessouza/godotenv v1.3.1-0.20210806120901-e417b721114e/go.mod h1:9JN/BuU6Agy5aHyEoA5EIPkBsYbk0+2R42zJgYi/SlI=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=\ngithub.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/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/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=\ngithub.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=\ngithub.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=\ngolang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=\ngoogle.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20141024133853-64131543e789 h1:NMiUjDZiD6qDVeBOzpImftxXzQHCp2Y2QLdmaqU9MRk=\ngopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=\ngotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=\n"
  },
  {
    "path": "pkg/third_party/compose-go/golangci.yml",
    "content": "run:\n  deadline: 2m\n\nlinters:\n  disable-all: true\n  enable:\n  - gofmt\n  - goimports\n  - golint\n  - gosimple\n  - ineffassign\n  - misspell\n  - govet\n"
  },
  {
    "path": "pkg/third_party/compose-go/interpolation/interpolation.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage interpolation\n\nimport (\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/compose-spec/compose-go/template\"\n\t\"github.com/pkg/errors\"\n)\n\n// Options supported by Interpolate\ntype Options struct {\n\t// LookupValue from a key\n\tLookupValue LookupValue\n\t// TypeCastMapping maps key paths to functions to cast to a type\n\tTypeCastMapping map[Path]Cast\n\t// Substitution function to use\n\tSubstitute func(string, template.Mapping) (string, error)\n}\n\n// LookupValue is a function which maps from variable names to values.\n// Returns the value as a string and a bool indicating whether\n// the value is present, to distinguish between an empty string\n// and the absence of a value.\ntype LookupValue func(key string) (string, bool)\n\n// Cast a value to a new type, or return an error if the value can't be cast\ntype Cast func(value string) (interface{}, error)\n\n// Interpolate replaces variables in a string with the values from a mapping\nfunc Interpolate(config map[string]interface{}, opts Options) (map[string]interface{}, error) {\n\tif opts.LookupValue == nil {\n\t\topts.LookupValue = os.LookupEnv\n\t}\n\tif opts.TypeCastMapping == nil {\n\t\topts.TypeCastMapping = make(map[Path]Cast)\n\t}\n\tif opts.Substitute == nil {\n\t\topts.Substitute = template.Substitute\n\t}\n\n\tout := map[string]interface{}{}\n\n\tfor key, value := range config {\n\t\tinterpolatedValue, err := recursiveInterpolate(value, NewPath(key), opts)\n\t\tif err != nil {\n\t\t\treturn out, err\n\t\t}\n\t\tout[key] = interpolatedValue\n\t}\n\n\treturn out, nil\n}\n\nfunc recursiveInterpolate(value interface{}, path Path, opts Options) (interface{}, error) {\n\tswitch value := value.(type) {\n\tcase string:\n\t\tnewValue, err := opts.Substitute(value, template.Mapping(opts.LookupValue))\n\t\tif err != nil || newValue == value {\n\t\t\treturn value, newPathError(path, err)\n\t\t}\n\t\tcaster, ok := opts.getCasterForPath(path)\n\t\tif !ok {\n\t\t\treturn newValue, nil\n\t\t}\n\t\tcasted, err := caster(newValue)\n\t\treturn casted, newPathError(path, errors.Wrap(err, \"failed to cast to expected type\"))\n\n\tcase map[string]interface{}:\n\t\tout := map[string]interface{}{}\n\t\tfor key, elem := range value {\n\t\t\tinterpolatedElem, err := recursiveInterpolate(elem, path.Next(key), opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tout[key] = interpolatedElem\n\t\t}\n\t\treturn out, nil\n\n\tcase []interface{}:\n\t\tout := make([]interface{}, len(value))\n\t\tfor i, elem := range value {\n\t\t\tinterpolatedElem, err := recursiveInterpolate(elem, path.Next(PathMatchList), opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tout[i] = interpolatedElem\n\t\t}\n\t\treturn out, nil\n\n\tdefault:\n\t\treturn value, nil\n\t}\n}\n\nfunc newPathError(path Path, err error) error {\n\tswitch err := err.(type) {\n\tcase nil:\n\t\treturn nil\n\tcase *template.InvalidTemplateError:\n\t\treturn errors.Errorf(\n\t\t\t\"invalid interpolation format for %s: %#v. You may need to escape any $ with another $.\",\n\t\t\tpath, err.Template)\n\tdefault:\n\t\treturn errors.Wrapf(err, \"error while interpolating %s\", path)\n\t}\n}\n\nconst pathSeparator = \".\"\n\n// PathMatchAll is a token used as part of a Path to match any key at that level\n// in the nested structure\nconst PathMatchAll = \"*\"\n\n// PathMatchList is a token used as part of a Path to match items in a list\nconst PathMatchList = \"[]\"\n\n// Path is a dotted path of keys to a value in a nested mapping structure. A *\n// section in a path will match any key in the mapping structure.\ntype Path string\n\n// NewPath returns a new Path\nfunc NewPath(items ...string) Path {\n\treturn Path(strings.Join(items, pathSeparator))\n}\n\n// Next returns a new path by append part to the current path\nfunc (p Path) Next(part string) Path {\n\treturn Path(string(p) + pathSeparator + part)\n}\n\nfunc (p Path) parts() []string {\n\treturn strings.Split(string(p), pathSeparator)\n}\n\nfunc (p Path) matches(pattern Path) bool {\n\tpatternParts := pattern.parts()\n\tparts := p.parts()\n\n\tif len(patternParts) != len(parts) {\n\t\treturn false\n\t}\n\tfor index, part := range parts {\n\t\tswitch patternParts[index] {\n\t\tcase PathMatchAll, part:\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (o Options) getCasterForPath(path Path) (Cast, bool) {\n\tfor pattern, caster := range o.TypeCastMapping {\n\t\tif path.matches(pattern) {\n\t\t\treturn caster, true\n\t\t}\n\t}\n\treturn nil, false\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/interpolation/interpolation_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage interpolation\n\nimport (\n\t\"testing\"\n\n\t\"strconv\"\n\n\t\"gotest.tools/v3/assert\"\n\tis \"gotest.tools/v3/assert/cmp\"\n\t\"gotest.tools/v3/env\"\n)\n\nvar defaults = map[string]string{\n\t\"USER\":  \"jenny\",\n\t\"FOO\":   \"bar\",\n\t\"count\": \"5\",\n}\n\nfunc defaultMapping(name string) (string, bool) {\n\tval, ok := defaults[name]\n\treturn val, ok\n}\n\nfunc TestInterpolate(t *testing.T) {\n\tservices := map[string]interface{}{\n\t\t\"servicea\": map[string]interface{}{\n\t\t\t\"image\":   \"example:${USER}\",\n\t\t\t\"volumes\": []interface{}{\"$FOO:/target\"},\n\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\"driver\": \"${FOO}\",\n\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\"user\": \"$USER\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\texpected := map[string]interface{}{\n\t\t\"servicea\": map[string]interface{}{\n\t\t\t\"image\":   \"example:jenny\",\n\t\t\t\"volumes\": []interface{}{\"bar:/target\"},\n\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\"driver\": \"bar\",\n\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\"user\": \"jenny\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tresult, err := Interpolate(services, Options{LookupValue: defaultMapping})\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(expected, result))\n}\n\nfunc TestInvalidInterpolation(t *testing.T) {\n\tservices := map[string]interface{}{\n\t\t\"servicea\": map[string]interface{}{\n\t\t\t\"image\": \"${\",\n\t\t},\n\t}\n\t_, err := Interpolate(services, Options{LookupValue: defaultMapping})\n\tassert.Error(t, err, `invalid interpolation format for servicea.image: \"${\". You may need to escape any $ with another $.`)\n}\n\nfunc TestInterpolateWithDefaults(t *testing.T) {\n\tdefer env.Patch(t, \"FOO\", \"BARZ\")()\n\n\tconfig := map[string]interface{}{\n\t\t\"networks\": map[string]interface{}{\n\t\t\t\"foo\": \"thing_${FOO}\",\n\t\t},\n\t}\n\texpected := map[string]interface{}{\n\t\t\"networks\": map[string]interface{}{\n\t\t\t\"foo\": \"thing_BARZ\",\n\t\t},\n\t}\n\tresult, err := Interpolate(config, Options{})\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(expected, result))\n}\n\nfunc TestInterpolateWithCast(t *testing.T) {\n\tconfig := map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"replicas\": \"$count\",\n\t\t},\n\t}\n\ttoInt := func(value string) (interface{}, error) {\n\t\treturn strconv.Atoi(value)\n\t}\n\tresult, err := Interpolate(config, Options{\n\t\tLookupValue:     defaultMapping,\n\t\tTypeCastMapping: map[Path]Cast{NewPath(PathMatchAll, \"replicas\"): toInt},\n\t})\n\tassert.NilError(t, err)\n\texpected := map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"replicas\": 5,\n\t\t},\n\t}\n\tassert.Check(t, is.DeepEqual(expected, result))\n}\n\nfunc TestPathMatches(t *testing.T) {\n\tvar testcases = []struct {\n\t\tdoc      string\n\t\tpath     Path\n\t\tpattern  Path\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tdoc:     \"pattern too short\",\n\t\t\tpath:    NewPath(\"one\", \"two\", \"three\"),\n\t\t\tpattern: NewPath(\"one\", \"two\"),\n\t\t},\n\t\t{\n\t\t\tdoc:     \"pattern too long\",\n\t\t\tpath:    NewPath(\"one\", \"two\"),\n\t\t\tpattern: NewPath(\"one\", \"two\", \"three\"),\n\t\t},\n\t\t{\n\t\t\tdoc:     \"pattern mismatch\",\n\t\t\tpath:    NewPath(\"one\", \"three\", \"two\"),\n\t\t\tpattern: NewPath(\"one\", \"two\", \"three\"),\n\t\t},\n\t\t{\n\t\t\tdoc:     \"pattern mismatch with match-all part\",\n\t\t\tpath:    NewPath(\"one\", \"three\", \"two\"),\n\t\t\tpattern: NewPath(PathMatchAll, \"two\", \"three\"),\n\t\t},\n\t\t{\n\t\t\tdoc:      \"pattern match with match-all part\",\n\t\t\tpath:     NewPath(\"one\", \"two\", \"three\"),\n\t\t\tpattern:  NewPath(\"one\", \"*\", \"three\"),\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tdoc:      \"pattern match\",\n\t\t\tpath:     NewPath(\"one\", \"two\", \"three\"),\n\t\t\tpattern:  NewPath(\"one\", \"two\", \"three\"),\n\t\t\texpected: true,\n\t\t},\n\t}\n\tfor _, testcase := range testcases {\n\t\tassert.Check(t, is.Equal(testcase.expected, testcase.path.matches(testcase.pattern)))\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/example1.env",
    "content": "# passed through\nFOO=foo_from_env_file\n\n# overridden in example2.env\nBAR=bar_from_env_file\n\n# overridden in full-example.yml\nBAZ=baz_from_env_file\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/example2.env",
    "content": "BAR=bar_from_env_file_2\n\n# overridden in configDetails.Environment\nQUX=quz_from_env_file_2\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/full-example.yml",
    "content": "services:\n  foo:\n\n    build:\n      context: ./dir\n      dockerfile: Dockerfile\n      args:\n        foo: bar\n      target: foo\n      network: foo\n      cache_from:\n        - foo\n        - bar\n      labels: [FOO=BAR]\n\n\n    cap_add:\n      - ALL\n\n    cap_drop:\n      - NET_ADMIN\n      - SYS_ADMIN\n\n    cgroup_parent: m-executor-abcd\n\n    # String or list\n    command: bundle exec thin -p 3000\n    # command: [\"bundle\", \"exec\", \"thin\", \"-p\", \"3000\"]\n\n    configs:\n      - config1\n      - source: config2\n        target: /my_config\n        uid: '103'\n        gid: '103'\n        mode: 0440\n\n    container_name: my-web-container\n\n    depends_on:\n      - db\n      - redis\n\n    deploy:\n      mode: replicated\n      replicas: 6\n      labels: [FOO=BAR]\n      rollback_config:\n        parallelism: 3\n        delay: 10s\n        failure_action: continue\n        monitor: 60s\n        max_failure_ratio: 0.3\n        order: start-first\n      update_config:\n        parallelism: 3\n        delay: 10s\n        failure_action: continue\n        monitor: 60s\n        max_failure_ratio: 0.3\n        order: start-first\n      resources:\n        limits:\n          cpus: '0.001'\n          memory: 50M\n        reservations:\n          cpus: '0.0001'\n          memory: 20M\n          generic_resources:\n            - discrete_resource_spec:\n                kind: 'gpu'\n                value: 2\n            - discrete_resource_spec:\n                kind: 'ssd'\n                value: 1\n      restart_policy:\n        condition: on-failure\n        delay: 5s\n        max_attempts: 3\n        window: 120s\n      placement:\n        constraints: [node=foo]\n        max_replicas_per_node: 5\n        preferences:\n          - spread: node.labels.az\n      endpoint_mode: dnsrr\n\n    devices:\n      - \"/dev/ttyUSB0:/dev/ttyUSB0\"\n\n    # String or list\n    # dns: 8.8.8.8\n    dns:\n      - 8.8.8.8\n      - 9.9.9.9\n\n    # String or list\n    # dns_search: example.com\n    dns_search:\n      - dc1.example.com\n      - dc2.example.com\n\n    domainname: foo.com\n\n    # String or list\n    # entrypoint: /code/entrypoint.sh -p 3000\n    entrypoint: [\"/code/entrypoint.sh\", \"-p\", \"3000\"]\n\n    # String or list\n    # env_file: .env\n    env_file:\n      - ./example1.env\n      - ./example2.env\n\n    # Mapping or list\n    # Mapping values can be strings, numbers or null\n    # Booleans are not allowed - must be quoted\n    environment:\n      BAZ: baz_from_service_def\n      QUX:\n    # environment:\n    #   - RACK_ENV=development\n    #   - SHOW=true\n    #   - SESSION_SECRET\n\n    # Items can be strings or numbers\n    expose:\n     - \"3000\"\n     - 8000\n\n    external_links:\n      - redis_1\n      - project_db_1:mysql\n      - project_db_1:postgresql\n\n    # Mapping or list\n    # Mapping values must be strings\n    # extra_hosts:\n    #   somehost: \"162.242.195.82\"\n    #   otherhost: \"50.31.209.229\"\n    extra_hosts:\n      - \"somehost:162.242.195.82\"\n      - \"otherhost:50.31.209.229\"\n\n    hostname: foo\n\n    healthcheck:\n      test: echo \"hello world\"\n      interval: 10s\n      timeout: 1s\n      retries: 5\n      start_period: 15s\n\n    # Any valid image reference - repo, tag, id, sha\n    image: redis\n    # image: ubuntu:14.04\n    # image: tutum/influxdb\n    # image: example-registry.com:4000/postgresql\n    # image: a4bc65fd\n    # image: busybox@sha256:38a203e1986cf79639cfb9b2e1d6e773de84002feea2d4eb006b52004ee8502d\n\n    ipc: host\n\n    # Mapping or list\n    # Mapping values can be strings, numbers or null\n    labels:\n      com.example.description: \"Accounting webapp\"\n      com.example.number: 42\n      com.example.empty-label:\n    # labels:\n    #   - \"com.example.description=Accounting webapp\"\n    #   - \"com.example.number=42\"\n    #   - \"com.example.empty-label\"\n\n    links:\n     - db\n     - db:database\n     - redis\n\n    logging:\n      driver: syslog\n      options:\n        syslog-address: \"tcp://192.168.0.42:123\"\n\n    mac_address: 02:42:ac:11:65:43\n\n    # network_mode: \"bridge\"\n    # network_mode: \"host\"\n    # network_mode: \"none\"\n    # Use the network mode of an arbitrary container from another service\n    # network_mode: \"service:db\"\n    # Use the network mode of another container, specified by name or id\n    # network_mode: \"container:some-container\"\n    network_mode: \"container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b\"\n\n    networks:\n      some-network:\n        aliases:\n         - alias1\n         - alias3\n      other-network:\n        ipv4_address: 172.16.238.10\n        ipv6_address: 2001:3984:3989::10\n      other-other-network:\n\n    pid: \"host\"\n\n    ports:\n      - 3000\n      - \"3001-3005\"\n      - \"8000:8000\"\n      - \"9090-9091:8080-8081\"\n      - \"49100:22\"\n      - \"127.0.0.1:8001:8001\"\n      - \"127.0.0.1:5000-5010:5000-5010\"\n\n    privileged: true\n\n    read_only: true\n\n    restart: always\n\n    secrets:\n      - secret1\n      - source: secret2\n        target: my_secret\n        uid: '103'\n        gid: '103'\n        mode: 0440\n\n    security_opt:\n      - label=level:s0:c100,c200\n      - label=type:svirt_apache_t\n\n    stdin_open: true\n\n    stop_grace_period: 20s\n\n    stop_signal: SIGUSR1\n\n    sysctls:\n      net.core.somaxconn: 1024\n      net.ipv4.tcp_syncookies: 0\n\n    # String or list\n    # tmpfs: /run\n    tmpfs:\n      - /run\n      - /tmp\n\n    tty: true\n\n    ulimits:\n      # Single number or mapping with soft + hard limits\n      nproc: 65535\n      nofile:\n        soft: 20000\n        hard: 40000\n\n    user: someone\n\n    volumes:\n      # Just specify a path and let the Engine create a volume\n      - /var/lib/mysql\n      # Specify an absolute path mapping\n      - /opt/data:/var/lib/mysql\n      # Path on the host, relative to the Compose file\n      - .:/code\n      - ./static:/var/www/html\n      # User-relative path\n      - ~/configs:/etc/configs/:ro\n      # Named volume\n      - datavolume:/var/lib/mysql\n      - type: bind\n        source: ./opt\n        target: /opt\n        consistency: cached\n      - type: tmpfs\n        target: /opt\n        tmpfs:\n          size: 10000\n\n    working_dir: /code\n    x-bar: baz\n    x-foo: bar\n\nnetworks:\n  # Entries can be null, which specifies simply that a network\n  # called \"{project name}_some-network\" should be created and\n  # use the default driver\n  some-network:\n\n  other-network:\n    driver: overlay\n\n    driver_opts:\n      # Values can be strings or numbers\n      foo: \"bar\"\n      baz: 1\n\n    ipam:\n      driver: overlay\n      # driver_opts:\n      #   # Values can be strings or numbers\n      #   com.docker.network.enable_ipv6: \"true\"\n      #   com.docker.network.numeric_value: 1\n      config:\n      - subnet: 172.28.0.0/16\n        ip_range: 172.28.5.0/24\n        gateway: 172.28.5.254\n        aux_addresses:\n          host1: 172.28.1.5\n          host2: 172.28.1.6\n          host3: 172.28.1.7\n      - subnet: 2001:3984:3989::/64\n        gateway: 2001:3984:3989::1\n\n    labels:\n      foo: bar\n\n  external-network:\n    # Specifies that a pre-existing network called \"external-network\"\n    # can be referred to within this file as \"external-network\"\n    external: true\n\n  other-external-network:\n    # Specifies that a pre-existing network called \"my-cool-network\"\n    # can be referred to within this file as \"other-external-network\"\n    external:\n      name: my-cool-network\n    x-bar: baz\n    x-foo: bar\n\nvolumes:\n  # Entries can be null, which specifies simply that a volume\n  # called \"{project name}_some-volume\" should be created and\n  # use the default driver\n  some-volume:\n\n  other-volume:\n    driver: flocker\n\n    driver_opts:\n      # Values can be strings or numbers\n      foo: \"bar\"\n      baz: 1\n    labels:\n      foo: bar\n\n  another-volume:\n    name: \"user_specified_name\"\n    driver: vsphere\n\n    driver_opts:\n      # Values can be strings or numbers\n      foo: \"bar\"\n      baz: 1\n\n  external-volume:\n    # Specifies that a pre-existing volume called \"external-volume\"\n    # can be referred to within this file as \"external-volume\"\n    external: true\n\n  other-external-volume:\n    # Specifies that a pre-existing volume called \"my-cool-volume\"\n    # can be referred to within this file as \"other-external-volume\"\n    # This example uses the deprecated \"volume.external.name\" (replaced by \"volume.name\")\n    external:\n      name: my-cool-volume\n\n  external-volume3:\n    # Specifies that a pre-existing volume called \"this-is-volume3\"\n    # can be referred to within this file as \"external-volume3\"\n    name: this-is-volume3\n    external: true\n    x-bar: baz\n    x-foo: bar\n\nconfigs:\n  config1:\n    file: ./config_data\n    labels:\n      foo: bar\n  config2:\n    external:\n      name: my_config\n  config3:\n    external: true\n  config4:\n    name: foo\n    x-bar: baz\n    x-foo: bar\n\nsecrets:\n  secret1:\n    file: ./secret_data\n    labels:\n      foo: bar\n  secret2:\n    external:\n      name: my_secret\n  secret3:\n    external: true\n  secret4:\n    name: bar\n    x-bar: baz\n    x-foo: bar\nx-bar: baz\nx-foo: bar\nx-nested:\n  bar: baz\n  foo: bar\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/full-struct_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n)\n\nfunc fullExampleConfig(workingDir, homeDir string) *types.Config {\n\treturn &types.Config{\n\t\tServices: services(workingDir, homeDir),\n\t\tNetworks: networks(),\n\t\tVolumes:  volumes(),\n\t\tConfigs:  configs(workingDir),\n\t\tSecrets:  secrets(workingDir),\n\t\tExtensions: map[string]interface{}{\n\t\t\t\"x-foo\": \"bar\",\n\t\t\t\"x-bar\": \"baz\",\n\t\t\t\"x-nested\": map[string]interface{}{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t\"bar\": \"baz\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc services(workingDir, homeDir string) []types.ServiceConfig {\n\treturn []types.ServiceConfig{\n\t\t{\n\t\t\tName: \"foo\",\n\n\t\t\tBuild: &types.BuildConfig{\n\t\t\t\tContext:    \"./dir\",\n\t\t\t\tDockerfile: \"Dockerfile\",\n\t\t\t\tArgs:       map[string]*string{\"foo\": strPtr(\"bar\")},\n\t\t\t\tTarget:     \"foo\",\n\t\t\t\tNetwork:    \"foo\",\n\t\t\t\tCacheFrom:  []string{\"foo\", \"bar\"},\n\t\t\t\tLabels:     map[string]string{\"FOO\": \"BAR\"},\n\t\t\t},\n\t\t\tCapAdd:       []string{\"ALL\"},\n\t\t\tCapDrop:      []string{\"NET_ADMIN\", \"SYS_ADMIN\"},\n\t\t\tCgroupParent: \"m-executor-abcd\",\n\t\t\tCommand:      []string{\"bundle\", \"exec\", \"thin\", \"-p\", \"3000\"},\n\t\t\tConfigs: []types.ServiceConfigObjConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"config1\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"config2\",\n\t\t\t\t\tTarget: \"/my_config\",\n\t\t\t\t\tUID:    \"103\",\n\t\t\t\t\tGID:    \"103\",\n\t\t\t\t\tMode:   uint32Ptr(0440),\n\t\t\t\t},\n\t\t\t},\n\t\t\tContainerName: \"my-web-container\",\n\t\t\tDependsOn: types.DependsOnConfig{\n\t\t\t\t\"db\":    {Condition: types.ServiceConditionStarted},\n\t\t\t\t\"redis\": {Condition: types.ServiceConditionStarted},\n\t\t\t},\n\t\t\tDeploy: &types.DeployConfig{\n\t\t\t\tMode:     \"replicated\",\n\t\t\t\tReplicas: uint64Ptr(6),\n\t\t\t\tLabels:   map[string]string{\"FOO\": \"BAR\"},\n\t\t\t\tRollbackConfig: &types.UpdateConfig{\n\t\t\t\t\tParallelism:     uint64Ptr(3),\n\t\t\t\t\tDelay:           types.Duration(10 * time.Second),\n\t\t\t\t\tFailureAction:   \"continue\",\n\t\t\t\t\tMonitor:         types.Duration(60 * time.Second),\n\t\t\t\t\tMaxFailureRatio: 0.3,\n\t\t\t\t\tOrder:           \"start-first\",\n\t\t\t\t},\n\t\t\t\tUpdateConfig: &types.UpdateConfig{\n\t\t\t\t\tParallelism:     uint64Ptr(3),\n\t\t\t\t\tDelay:           types.Duration(10 * time.Second),\n\t\t\t\t\tFailureAction:   \"continue\",\n\t\t\t\t\tMonitor:         types.Duration(60 * time.Second),\n\t\t\t\t\tMaxFailureRatio: 0.3,\n\t\t\t\t\tOrder:           \"start-first\",\n\t\t\t\t},\n\t\t\t\tResources: types.Resources{\n\t\t\t\t\tLimits: &types.Resource{\n\t\t\t\t\t\tNanoCPUs:    \"0.001\",\n\t\t\t\t\t\tMemoryBytes: 50 * 1024 * 1024,\n\t\t\t\t\t},\n\t\t\t\t\tReservations: &types.Resource{\n\t\t\t\t\t\tNanoCPUs:    \"0.0001\",\n\t\t\t\t\t\tMemoryBytes: 20 * 1024 * 1024,\n\t\t\t\t\t\tGenericResources: []types.GenericResource{\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tDiscreteResourceSpec: &types.DiscreteGenericResource{\n\t\t\t\t\t\t\t\t\tKind:  \"gpu\",\n\t\t\t\t\t\t\t\t\tValue: 2,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tDiscreteResourceSpec: &types.DiscreteGenericResource{\n\t\t\t\t\t\t\t\t\tKind:  \"ssd\",\n\t\t\t\t\t\t\t\t\tValue: 1,\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\tRestartPolicy: &types.RestartPolicy{\n\t\t\t\t\tCondition:   types.RestartPolicyOnFailure,\n\t\t\t\t\tDelay:       durationPtr(5 * time.Second),\n\t\t\t\t\tMaxAttempts: uint64Ptr(3),\n\t\t\t\t\tWindow:      durationPtr(2 * time.Minute),\n\t\t\t\t},\n\t\t\t\tPlacement: types.Placement{\n\t\t\t\t\tConstraints: []string{\"node=foo\"},\n\t\t\t\t\tMaxReplicas: uint64(5),\n\t\t\t\t\tPreferences: []types.PlacementPreferences{\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tSpread: \"node.labels.az\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tEndpointMode: \"dnsrr\",\n\t\t\t},\n\t\t\tDevices:    []string{\"/dev/ttyUSB0:/dev/ttyUSB0\"},\n\t\t\tDNS:        []string{\"8.8.8.8\", \"9.9.9.9\"},\n\t\t\tDNSSearch:  []string{\"dc1.example.com\", \"dc2.example.com\"},\n\t\t\tDomainName: \"foo.com\",\n\t\t\tEntrypoint: []string{\"/code/entrypoint.sh\", \"-p\", \"3000\"},\n\t\t\tEnvironment: map[string]*string{\n\t\t\t\t\"FOO\": strPtr(\"foo_from_env_file\"),\n\t\t\t\t\"BAR\": strPtr(\"bar_from_env_file_2\"),\n\t\t\t\t\"BAZ\": strPtr(\"baz_from_service_def\"),\n\t\t\t\t\"QUX\": strPtr(\"qux_from_environment\"),\n\t\t\t},\n\t\t\tEnvFile: []string{\n\t\t\t\t\"./example1.env\",\n\t\t\t\t\"./example2.env\",\n\t\t\t},\n\t\t\tExpose: []string{\"3000\", \"8000\"},\n\t\t\tExternalLinks: []string{\n\t\t\t\t\"redis_1\",\n\t\t\t\t\"project_db_1:mysql\",\n\t\t\t\t\"project_db_1:postgresql\",\n\t\t\t},\n\t\t\tExtraHosts: []string{\n\t\t\t\t\"somehost:162.242.195.82\",\n\t\t\t\t\"otherhost:50.31.209.229\",\n\t\t\t},\n\t\t\tExtensions: map[string]interface{}{\n\t\t\t\t\"x-bar\": \"baz\",\n\t\t\t\t\"x-foo\": \"bar\",\n\t\t\t},\n\t\t\tHealthCheck: &types.HealthCheckConfig{\n\t\t\t\tTest:        types.HealthCheckTest([]string{\"CMD-SHELL\", \"echo \\\"hello world\\\"\"}),\n\t\t\t\tInterval:    durationPtr(10 * time.Second),\n\t\t\t\tTimeout:     durationPtr(1 * time.Second),\n\t\t\t\tRetries:     uint64Ptr(5),\n\t\t\t\tStartPeriod: durationPtr(15 * time.Second),\n\t\t\t},\n\t\t\tHostname: \"foo\",\n\t\t\tImage:    \"redis\",\n\t\t\tIpc:      \"host\",\n\t\t\tLabels: map[string]string{\n\t\t\t\t\"com.example.description\": \"Accounting webapp\",\n\t\t\t\t\"com.example.number\":      \"42\",\n\t\t\t\t\"com.example.empty-label\": \"\",\n\t\t\t},\n\t\t\tLinks: []string{\n\t\t\t\t\"db\",\n\t\t\t\t\"db:database\",\n\t\t\t\t\"redis\",\n\t\t\t},\n\t\t\tLogging: &types.LoggingConfig{\n\t\t\t\tDriver: \"syslog\",\n\t\t\t\tOptions: map[string]string{\n\t\t\t\t\t\"syslog-address\": \"tcp://192.168.0.42:123\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tMacAddress:  \"02:42:ac:11:65:43\",\n\t\t\tNetworkMode: \"container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b\",\n\t\t\tNetworks: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\"some-network\": {\n\t\t\t\t\tAliases:     []string{\"alias1\", \"alias3\"},\n\t\t\t\t\tIpv4Address: \"\",\n\t\t\t\t\tIpv6Address: \"\",\n\t\t\t\t},\n\t\t\t\t\"other-network\": {\n\t\t\t\t\tIpv4Address: \"172.16.238.10\",\n\t\t\t\t\tIpv6Address: \"2001:3984:3989::10\",\n\t\t\t\t},\n\t\t\t\t\"other-other-network\": nil,\n\t\t\t},\n\t\t\tPid: \"host\",\n\t\t\tPorts: []types.ServicePortConfig{\n\t\t\t\t//\"3000\",\n\t\t\t\t{\n\t\t\t\t\tMode:     \"ingress\",\n\t\t\t\t\tTarget:   3000,\n\t\t\t\t\tProtocol: \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:     \"ingress\",\n\t\t\t\t\tTarget:   3001,\n\t\t\t\t\tProtocol: \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:     \"ingress\",\n\t\t\t\t\tTarget:   3002,\n\t\t\t\t\tProtocol: \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:     \"ingress\",\n\t\t\t\t\tTarget:   3003,\n\t\t\t\t\tProtocol: \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:     \"ingress\",\n\t\t\t\t\tTarget:   3004,\n\t\t\t\t\tProtocol: \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:     \"ingress\",\n\t\t\t\t\tTarget:   3005,\n\t\t\t\t\tProtocol: \"tcp\",\n\t\t\t\t},\n\t\t\t\t//\"8000:8000\",\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tTarget:    8000,\n\t\t\t\t\tPublished: 8000,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t//\"9090-9091:8080-8081\",\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 9090,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tTarget:    8081,\n\t\t\t\t\tPublished: 9091,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t//\"49100:22\",\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tTarget:    22,\n\t\t\t\t\tPublished: 49100,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t//\"127.0.0.1:8001:8001\",\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    8001,\n\t\t\t\t\tPublished: 8001,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t//\"127.0.0.1:5000-5010:5000-5010\",\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5000,\n\t\t\t\t\tPublished: 5000,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5001,\n\t\t\t\t\tPublished: 5001,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5002,\n\t\t\t\t\tPublished: 5002,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5003,\n\t\t\t\t\tPublished: 5003,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5004,\n\t\t\t\t\tPublished: 5004,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5005,\n\t\t\t\t\tPublished: 5005,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5006,\n\t\t\t\t\tPublished: 5006,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5007,\n\t\t\t\t\tPublished: 5007,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5008,\n\t\t\t\t\tPublished: 5008,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5009,\n\t\t\t\t\tPublished: 5009,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tHostIP:    \"127.0.0.1\",\n\t\t\t\t\tTarget:    5010,\n\t\t\t\t\tPublished: 5010,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tPrivileged: true,\n\t\t\tReadOnly:   true,\n\t\t\tRestart:    types.RestartPolicyAlways,\n\t\t\tScale:      1,\n\t\t\tSecrets: []types.ServiceSecretConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"secret1\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"secret2\",\n\t\t\t\t\tTarget: \"my_secret\",\n\t\t\t\t\tUID:    \"103\",\n\t\t\t\t\tGID:    \"103\",\n\t\t\t\t\tMode:   uint32Ptr(0440),\n\t\t\t\t},\n\t\t\t},\n\t\t\tSecurityOpt: []string{\n\t\t\t\t\"label=level:s0:c100,c200\",\n\t\t\t\t\"label=type:svirt_apache_t\",\n\t\t\t},\n\t\t\tStdinOpen:       true,\n\t\t\tStopSignal:      \"SIGUSR1\",\n\t\t\tStopGracePeriod: durationPtr(20 * time.Second),\n\t\t\tSysctls: map[string]string{\n\t\t\t\t\"net.core.somaxconn\":      \"1024\",\n\t\t\t\t\"net.ipv4.tcp_syncookies\": \"0\",\n\t\t\t},\n\t\t\tTmpfs: []string{\"/run\", \"/tmp\"},\n\t\t\tTty:   true,\n\t\t\tUlimits: map[string]*types.UlimitsConfig{\n\t\t\t\t\"nproc\": {\n\t\t\t\t\tSingle: 65535,\n\t\t\t\t},\n\t\t\t\t\"nofile\": {\n\t\t\t\t\tSoft: 20000,\n\t\t\t\t\tHard: 40000,\n\t\t\t\t},\n\t\t\t},\n\t\t\tUser: \"someone\",\n\t\t\tVolumes: []types.ServiceVolumeConfig{\n\t\t\t\t{Target: \"/var/lib/mysql\", Type: \"volume\", Volume: &types.ServiceVolumeVolume{}},\n\t\t\t\t{Source: \"/opt/data\", Target: \"/var/lib/mysql\", Type: \"bind\", Bind: &types.ServiceVolumeBind{CreateHostPath: true}},\n\t\t\t\t{Source: workingDir, Target: \"/code\", Type: \"bind\", Bind: &types.ServiceVolumeBind{CreateHostPath: true}},\n\t\t\t\t{Source: filepath.Join(workingDir, \"static\"), Target: \"/var/www/html\", Type: \"bind\", Bind: &types.ServiceVolumeBind{CreateHostPath: true}},\n\t\t\t\t{Source: filepath.Join(homeDir, \"/configs\"), Target: \"/etc/configs/\", Type: \"bind\", ReadOnly: true, Bind: &types.ServiceVolumeBind{CreateHostPath: true}},\n\t\t\t\t{Source: \"datavolume\", Target: \"/var/lib/mysql\", Type: \"volume\", Volume: &types.ServiceVolumeVolume{}},\n\t\t\t\t{Source: filepath.Join(workingDir, \"opt\"), Target: \"/opt\", Consistency: \"cached\", Type: \"bind\"},\n\t\t\t\t{Target: \"/opt\", Type: \"tmpfs\", Tmpfs: &types.ServiceVolumeTmpfs{\n\t\t\t\t\tSize: int64(10000),\n\t\t\t\t}},\n\t\t\t},\n\t\t\tWorkingDir: \"/code\",\n\t\t},\n\t}\n}\n\nfunc networks() map[string]types.NetworkConfig {\n\treturn map[string]types.NetworkConfig{\n\t\t\"some-network\": {},\n\n\t\t\"other-network\": {\n\t\t\tDriver: \"overlay\",\n\t\t\tDriverOpts: map[string]string{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t\"baz\": \"1\",\n\t\t\t},\n\t\t\tIpam: types.IPAMConfig{\n\t\t\t\tDriver: \"overlay\",\n\t\t\t\tConfig: []*types.IPAMPool{\n\t\t\t\t\t{\n\t\t\t\t\t\tSubnet:  \"172.28.0.0/16\",\n\t\t\t\t\t\tIPRange: \"172.28.5.0/24\",\n\t\t\t\t\t\tGateway: \"172.28.5.254\",\n\t\t\t\t\t\tAuxiliaryAddresses: map[string]string{\n\t\t\t\t\t\t\t\"host1\": \"172.28.1.5\",\n\t\t\t\t\t\t\t\"host2\": \"172.28.1.6\",\n\t\t\t\t\t\t\t\"host3\": \"172.28.1.7\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tSubnet:  \"2001:3984:3989::/64\",\n\t\t\t\t\t\tGateway: \"2001:3984:3989::1\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tLabels: map[string]string{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t},\n\t\t},\n\n\t\t\"external-network\": {\n\t\t\tName:     \"external-network\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\n\t\t\"other-external-network\": {\n\t\t\tName:     \"my-cool-network\",\n\t\t\tExternal: types.External{External: true},\n\t\t\tExtensions: map[string]interface{}{\n\t\t\t\t\"x-bar\": \"baz\",\n\t\t\t\t\"x-foo\": \"bar\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc volumes() map[string]types.VolumeConfig {\n\treturn map[string]types.VolumeConfig{\n\t\t\"some-volume\": {},\n\t\t\"other-volume\": {\n\t\t\tDriver: \"flocker\",\n\t\t\tDriverOpts: map[string]string{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t\"baz\": \"1\",\n\t\t\t},\n\t\t\tLabels: map[string]string{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t},\n\t\t},\n\t\t\"another-volume\": {\n\t\t\tName:   \"user_specified_name\",\n\t\t\tDriver: \"vsphere\",\n\t\t\tDriverOpts: map[string]string{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t\t\"baz\": \"1\",\n\t\t\t},\n\t\t},\n\t\t\"external-volume\": {\n\t\t\tName:     \"external-volume\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t\t\"other-external-volume\": {\n\t\t\tName:     \"my-cool-volume\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t\t\"external-volume3\": {\n\t\t\tName:     \"this-is-volume3\",\n\t\t\tExternal: types.External{External: true},\n\t\t\tExtensions: map[string]interface{}{\n\t\t\t\t\"x-bar\": \"baz\",\n\t\t\t\t\"x-foo\": \"bar\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc configs(workingDir string) map[string]types.ConfigObjConfig {\n\treturn map[string]types.ConfigObjConfig{\n\t\t\"config1\": {\n\t\t\tFile: filepath.Join(workingDir, \"config_data\"),\n\t\t\tLabels: map[string]string{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t},\n\t\t},\n\t\t\"config2\": {\n\t\t\tName:     \"my_config\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t\t\"config3\": {\n\t\t\tName:     \"config3\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t\t\"config4\": {\n\t\t\tName: \"foo\",\n\t\t\tFile: workingDir,\n\t\t\tExtensions: map[string]interface{}{\n\t\t\t\t\"x-bar\": \"baz\",\n\t\t\t\t\"x-foo\": \"bar\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc secrets(workingDir string) map[string]types.SecretConfig {\n\treturn map[string]types.SecretConfig{\n\t\t\"secret1\": {\n\t\t\tFile: filepath.Join(workingDir, \"secret_data\"),\n\t\t\tLabels: map[string]string{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t},\n\t\t},\n\t\t\"secret2\": {\n\t\t\tName:     \"my_secret\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t\t\"secret3\": {\n\t\t\tName:     \"secret3\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t\t\"secret4\": {\n\t\t\tName: \"bar\",\n\t\t\tFile: workingDir,\n\t\t\tExtensions: map[string]interface{}{\n\t\t\t\t\"x-bar\": \"baz\",\n\t\t\t\t\"x-foo\": \"bar\",\n\t\t\t},\n\t\t},\n\t}\n}\n\nfunc fullExampleYAML(workingDir, homeDir string) string {\n\treturn fmt.Sprintf(`services:\n  foo:\n    build:\n      context: ./dir\n      dockerfile: Dockerfile\n      args:\n        foo: bar\n      labels:\n        FOO: BAR\n      cache_from:\n      - foo\n      - bar\n      network: foo\n      target: foo\n    cap_add:\n    - ALL\n    cap_drop:\n    - NET_ADMIN\n    - SYS_ADMIN\n    cgroup_parent: m-executor-abcd\n    command:\n    - bundle\n    - exec\n    - thin\n    - -p\n    - \"3000\"\n    configs:\n    - source: config1\n    - source: config2\n      target: /my_config\n      uid: \"103\"\n      gid: \"103\"\n      mode: 288\n    container_name: my-web-container\n    depends_on:\n      db:\n        condition: service_started\n      redis:\n        condition: service_started\n    deploy:\n      mode: replicated\n      replicas: 6\n      labels:\n        FOO: BAR\n      update_config:\n        parallelism: 3\n        delay: 10s\n        failure_action: continue\n        monitor: 1m0s\n        max_failure_ratio: 0.3\n        order: start-first\n      rollback_config:\n        parallelism: 3\n        delay: 10s\n        failure_action: continue\n        monitor: 1m0s\n        max_failure_ratio: 0.3\n        order: start-first\n      resources:\n        limits:\n          cpus: \"0.001\"\n          memory: \"52428800\"\n        reservations:\n          cpus: \"0.0001\"\n          memory: \"20971520\"\n          generic_resources:\n          - discrete_resource_spec:\n              kind: gpu\n              value: 2\n          - discrete_resource_spec:\n              kind: ssd\n              value: 1\n      restart_policy:\n        condition: on-failure\n        delay: 5s\n        max_attempts: 3\n        window: 2m0s\n      placement:\n        constraints:\n        - node=foo\n        preferences:\n        - spread: node.labels.az\n        max_replicas_per_node: 5\n      endpoint_mode: dnsrr\n    devices:\n    - /dev/ttyUSB0:/dev/ttyUSB0\n    dns:\n    - 8.8.8.8\n    - 9.9.9.9\n    dns_search:\n    - dc1.example.com\n    - dc2.example.com\n    domainname: foo.com\n    entrypoint:\n    - /code/entrypoint.sh\n    - -p\n    - \"3000\"\n    environment:\n      BAR: bar_from_env_file_2\n      BAZ: baz_from_service_def\n      FOO: foo_from_env_file\n      QUX: qux_from_environment\n    env_file:\n    - ./example1.env\n    - ./example2.env\n    expose:\n    - \"3000\"\n    - \"8000\"\n    external_links:\n    - redis_1\n    - project_db_1:mysql\n    - project_db_1:postgresql\n    extra_hosts:\n    - somehost:162.242.195.82\n    - otherhost:50.31.209.229\n    hostname: foo\n    healthcheck:\n      test:\n      - CMD-SHELL\n      - echo \"hello world\"\n      timeout: 1s\n      interval: 10s\n      retries: 5\n      start_period: 15s\n    image: redis\n    ipc: host\n    labels:\n      com.example.description: Accounting webapp\n      com.example.empty-label: \"\"\n      com.example.number: \"42\"\n    links:\n    - db\n    - db:database\n    - redis\n    logging:\n      driver: syslog\n      options:\n        syslog-address: tcp://192.168.0.42:123\n    mac_address: 02:42:ac:11:65:43\n    network_mode: container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b\n    networks:\n      other-network:\n        ipv4_address: 172.16.238.10\n        ipv6_address: 2001:3984:3989::10\n      other-other-network: null\n      some-network:\n        aliases:\n        - alias1\n        - alias3\n    pid: host\n    ports:\n    - mode: ingress\n      target: 3000\n      protocol: tcp\n    - mode: ingress\n      target: 3001\n      protocol: tcp\n    - mode: ingress\n      target: 3002\n      protocol: tcp\n    - mode: ingress\n      target: 3003\n      protocol: tcp\n    - mode: ingress\n      target: 3004\n      protocol: tcp\n    - mode: ingress\n      target: 3005\n      protocol: tcp\n    - mode: ingress\n      target: 8000\n      published: 8000\n      protocol: tcp\n    - mode: ingress\n      target: 8080\n      published: 9090\n      protocol: tcp\n    - mode: ingress\n      target: 8081\n      published: 9091\n      protocol: tcp\n    - mode: ingress\n      target: 22\n      published: 49100\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 8001\n      published: 8001\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5000\n      published: 5000\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5001\n      published: 5001\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5002\n      published: 5002\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5003\n      published: 5003\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5004\n      published: 5004\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5005\n      published: 5005\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5006\n      published: 5006\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5007\n      published: 5007\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5008\n      published: 5008\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5009\n      published: 5009\n      protocol: tcp\n    - mode: ingress\n      host_ip: 127.0.0.1\n      target: 5010\n      published: 5010\n      protocol: tcp\n    privileged: true\n    read_only: true\n    restart: always\n    secrets:\n    - source: secret1\n    - source: secret2\n      target: my_secret\n      uid: \"103\"\n      gid: \"103\"\n      mode: 288\n    security_opt:\n    - label=level:s0:c100,c200\n    - label=type:svirt_apache_t\n    stdin_open: true\n    stop_grace_period: 20s\n    stop_signal: SIGUSR1\n    sysctls:\n      net.core.somaxconn: \"1024\"\n      net.ipv4.tcp_syncookies: \"0\"\n    tmpfs:\n    - /run\n    - /tmp\n    tty: true\n    ulimits:\n      nofile:\n        soft: 20000\n        hard: 40000\n      nproc: 65535\n    user: someone\n    volumes:\n    - type: volume\n      target: /var/lib/mysql\n      volume: {}\n    - type: bind\n      source: /opt/data\n      target: /var/lib/mysql\n      bind:\n        create_host_path: true\n    - type: bind\n      source: %s\n      target: /code\n      bind:\n        create_host_path: true\n    - type: bind\n      source: %s\n      target: /var/www/html\n      bind:\n        create_host_path: true\n    - type: bind\n      source: %s\n      target: /etc/configs/\n      read_only: true\n      bind:\n        create_host_path: true\n    - type: volume\n      source: datavolume\n      target: /var/lib/mysql\n      volume: {}\n    - type: bind\n      source: %s\n      target: /opt\n      consistency: cached\n    - type: tmpfs\n      target: /opt\n      tmpfs:\n        size: 10000\n    working_dir: /code\n    x-bar: baz\n    x-foo: bar\nnetworks:\n  external-network:\n    name: external-network\n    external: true\n  other-external-network:\n    name: my-cool-network\n    external: true\n    x-bar: baz\n    x-foo: bar\n  other-network:\n    driver: overlay\n    driver_opts:\n      baz: \"1\"\n      foo: bar\n    ipam:\n      driver: overlay\n      config:\n      - subnet: 172.28.0.0/16\n        gateway: 172.28.5.254\n        ip_range: 172.28.5.0/24\n        aux_addresses:\n          host1: 172.28.1.5\n          host2: 172.28.1.6\n          host3: 172.28.1.7\n      - subnet: 2001:3984:3989::/64\n        gateway: 2001:3984:3989::1\n    labels:\n      foo: bar\n  some-network: {}\nvolumes:\n  another-volume:\n    name: user_specified_name\n    driver: vsphere\n    driver_opts:\n      baz: \"1\"\n      foo: bar\n  external-volume:\n    name: external-volume\n    external: true\n  external-volume3:\n    name: this-is-volume3\n    external: true\n    x-bar: baz\n    x-foo: bar\n  other-external-volume:\n    name: my-cool-volume\n    external: true\n  other-volume:\n    driver: flocker\n    driver_opts:\n      baz: \"1\"\n      foo: bar\n    labels:\n      foo: bar\n  some-volume: {}\nsecrets:\n  secret1:\n    file: %s\n    labels:\n      foo: bar\n  secret2:\n    name: my_secret\n    external: true\n  secret3:\n    name: secret3\n    external: true\n  secret4:\n    name: bar\n    file: %s\n    x-bar: baz\n    x-foo: bar\nconfigs:\n  config1:\n    file: %s\n    labels:\n      foo: bar\n  config2:\n    name: my_config\n    external: true\n  config3:\n    name: config3\n    external: true\n  config4:\n    name: foo\n    file: %s\n    x-bar: baz\n    x-foo: bar\nx-bar: baz\nx-foo: bar\nx-nested:\n  bar: baz\n  foo: bar\n`,\n\t\tfilepath.Join(workingDir),\n\t\tfilepath.Join(workingDir, \"static\"),\n\t\tfilepath.Join(homeDir, \"configs\"),\n\t\tfilepath.Join(workingDir, \"opt\"),\n\t\tfilepath.Join(workingDir, \"secret_data\"),\n\t\tfilepath.Join(workingDir),\n\t\tfilepath.Join(workingDir, \"config_data\"),\n\t\tfilepath.Join(workingDir))\n}\n\nfunc fullExampleJSON(workingDir, homeDir string) string {\n\treturn fmt.Sprintf(`{\n  \"configs\": {\n    \"config1\": {\n      \"file\": \"%s\",\n      \"external\": false,\n      \"labels\": {\n        \"foo\": \"bar\"\n      }\n    },\n    \"config2\": {\n      \"name\": \"my_config\",\n      \"external\": true\n    },\n    \"config3\": {\n      \"name\": \"config3\",\n      \"external\": true\n    },\n    \"config4\": {\n      \"name\": \"foo\",\n      \"file\": \"%s\",\n      \"external\": false\n    }\n  },\n  \"networks\": {\n    \"external-network\": {\n      \"name\": \"external-network\",\n      \"ipam\": {},\n      \"external\": true\n    },\n    \"other-external-network\": {\n      \"name\": \"my-cool-network\",\n      \"ipam\": {},\n      \"external\": true\n    },\n    \"other-network\": {\n      \"driver\": \"overlay\",\n      \"driver_opts\": {\n        \"baz\": \"1\",\n        \"foo\": \"bar\"\n      },\n      \"ipam\": {\n        \"driver\": \"overlay\",\n        \"config\": [\n          {\n            \"subnet\": \"172.28.0.0/16\",\n            \"gateway\": \"172.28.5.254\",\n            \"ip_range\": \"172.28.5.0/24\",\n            \"aux_addresses\": {\n              \"host1\": \"172.28.1.5\",\n              \"host2\": \"172.28.1.6\",\n              \"host3\": \"172.28.1.7\"\n            }\n          },\n          {\n            \"subnet\": \"2001:3984:3989::/64\",\n            \"gateway\": \"2001:3984:3989::1\"\n          }\n        ]\n      },\n      \"external\": false,\n      \"labels\": {\n        \"foo\": \"bar\"\n      }\n    },\n    \"some-network\": {\n      \"ipam\": {},\n      \"external\": false\n    }\n  },\n  \"secrets\": {\n    \"secret1\": {\n      \"file\": \"%s\",\n      \"external\": false,\n      \"labels\": {\n        \"foo\": \"bar\"\n      }\n    },\n    \"secret2\": {\n      \"name\": \"my_secret\",\n      \"external\": true\n    },\n    \"secret3\": {\n      \"name\": \"secret3\",\n      \"external\": true\n    },\n    \"secret4\": {\n      \"name\": \"bar\",\n      \"file\": \"%s\",\n      \"external\": false\n    }\n  },\n  \"services\": {\n    \"foo\": {\n      \"build\": {\n        \"context\": \"./dir\",\n        \"dockerfile\": \"Dockerfile\",\n        \"args\": {\n          \"foo\": \"bar\"\n        },\n        \"labels\": {\n          \"FOO\": \"BAR\"\n        },\n        \"cache_from\": [\n          \"foo\",\n          \"bar\"\n        ],\n        \"network\": \"foo\",\n        \"target\": \"foo\"\n      },\n      \"cap_add\": [\n        \"ALL\"\n      ],\n      \"cap_drop\": [\n        \"NET_ADMIN\",\n        \"SYS_ADMIN\"\n      ],\n      \"cgroup_parent\": \"m-executor-abcd\",\n      \"command\": [\n        \"bundle\",\n        \"exec\",\n        \"thin\",\n        \"-p\",\n        \"3000\"\n      ],\n      \"configs\": [\n        {\n          \"source\": \"config1\"\n        },\n        {\n          \"source\": \"config2\",\n          \"target\": \"/my_config\",\n          \"uid\": \"103\",\n          \"gid\": \"103\",\n          \"mode\": 288\n        }\n      ],\n      \"container_name\": \"my-web-container\",\n      \"depends_on\": {\n        \"db\": {\n          \"condition\": \"service_started\"\n        },\n        \"redis\": {\n          \"condition\": \"service_started\"\n        }\n      },\n      \"deploy\": {\n        \"mode\": \"replicated\",\n        \"replicas\": 6,\n        \"labels\": {\n          \"FOO\": \"BAR\"\n        },\n        \"update_config\": {\n          \"parallelism\": 3,\n          \"delay\": \"10s\",\n          \"failure_action\": \"continue\",\n          \"monitor\": \"1m0s\",\n          \"max_failure_ratio\": 0.3,\n          \"order\": \"start-first\"\n        },\n        \"rollback_config\": {\n          \"parallelism\": 3,\n          \"delay\": \"10s\",\n          \"failure_action\": \"continue\",\n          \"monitor\": \"1m0s\",\n          \"max_failure_ratio\": 0.3,\n          \"order\": \"start-first\"\n        },\n        \"resources\": {\n          \"limits\": {\n            \"cpus\": \"0.001\",\n            \"memory\": \"52428800\"\n          },\n          \"reservations\": {\n            \"cpus\": \"0.0001\",\n            \"memory\": \"20971520\",\n            \"generic_resources\": [\n              {\n                \"discrete_resource_spec\": {\n                  \"kind\": \"gpu\",\n                  \"value\": 2\n                }\n              },\n              {\n                \"discrete_resource_spec\": {\n                  \"kind\": \"ssd\",\n                  \"value\": 1\n                }\n              }\n            ]\n          }\n        },\n        \"restart_policy\": {\n          \"condition\": \"on-failure\",\n          \"delay\": \"5s\",\n          \"max_attempts\": 3,\n          \"window\": \"2m0s\"\n        },\n        \"placement\": {\n          \"constraints\": [\n            \"node=foo\"\n          ],\n          \"preferences\": [\n            {\n              \"spread\": \"node.labels.az\"\n            }\n          ],\n          \"max_replicas_per_node\": 5\n        },\n        \"endpoint_mode\": \"dnsrr\"\n      },\n      \"devices\": [\n        \"/dev/ttyUSB0:/dev/ttyUSB0\"\n      ],\n      \"dns\": [\n        \"8.8.8.8\",\n        \"9.9.9.9\"\n      ],\n      \"dns_search\": [\n        \"dc1.example.com\",\n        \"dc2.example.com\"\n      ],\n      \"domainname\": \"foo.com\",\n      \"entrypoint\": [\n        \"/code/entrypoint.sh\",\n        \"-p\",\n        \"3000\"\n      ],\n      \"environment\": {\n        \"BAR\": \"bar_from_env_file_2\",\n        \"BAZ\": \"baz_from_service_def\",\n        \"FOO\": \"foo_from_env_file\",\n        \"QUX\": \"qux_from_environment\"\n      },\n      \"env_file\": [\n        \"./example1.env\",\n        \"./example2.env\"\n      ],\n      \"expose\": [\n        \"3000\",\n        \"8000\"\n      ],\n      \"external_links\": [\n        \"redis_1\",\n        \"project_db_1:mysql\",\n        \"project_db_1:postgresql\"\n      ],\n      \"extra_hosts\": [\n        \"somehost:162.242.195.82\",\n        \"otherhost:50.31.209.229\"\n      ],\n      \"hostname\": \"foo\",\n      \"healthcheck\": {\n        \"test\": [\n          \"CMD-SHELL\",\n          \"echo \\\"hello world\\\"\"\n        ],\n        \"timeout\": \"1s\",\n        \"interval\": \"10s\",\n        \"retries\": 5,\n        \"start_period\": \"15s\"\n      },\n      \"image\": \"redis\",\n      \"ipc\": \"host\",\n      \"labels\": {\n        \"com.example.description\": \"Accounting webapp\",\n        \"com.example.empty-label\": \"\",\n        \"com.example.number\": \"42\"\n      },\n      \"links\": [\n        \"db\",\n        \"db:database\",\n        \"redis\"\n      ],\n      \"logging\": {\n        \"driver\": \"syslog\",\n        \"options\": {\n          \"syslog-address\": \"tcp://192.168.0.42:123\"\n        }\n      },\n      \"mac_address\": \"02:42:ac:11:65:43\",\n      \"network_mode\": \"container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b\",\n      \"networks\": {\n        \"other-network\": {\n          \"ipv4_address\": \"172.16.238.10\",\n          \"ipv6_address\": \"2001:3984:3989::10\"\n        },\n        \"other-other-network\": null,\n        \"some-network\": {\n          \"aliases\": [\n            \"alias1\",\n            \"alias3\"\n          ]\n        }\n      },\n      \"pid\": \"host\",\n      \"ports\": [\n        {\n          \"mode\": \"ingress\",\n          \"target\": 3000,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 3001,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 3002,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 3003,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 3004,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 3005,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 8000,\n          \"published\": 8000,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 8080,\n          \"published\": 9090,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 8081,\n          \"published\": 9091,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"target\": 22,\n          \"published\": 49100,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 8001,\n          \"published\": 8001,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5000,\n          \"published\": 5000,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5001,\n          \"published\": 5001,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5002,\n          \"published\": 5002,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5003,\n          \"published\": 5003,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5004,\n          \"published\": 5004,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5005,\n          \"published\": 5005,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5006,\n          \"published\": 5006,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5007,\n          \"published\": 5007,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5008,\n          \"published\": 5008,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5009,\n          \"published\": 5009,\n          \"protocol\": \"tcp\"\n        },\n        {\n          \"mode\": \"ingress\",\n          \"host_ip\": \"127.0.0.1\",\n          \"target\": 5010,\n          \"published\": 5010,\n          \"protocol\": \"tcp\"\n        }\n      ],\n      \"privileged\": true,\n      \"read_only\": true,\n      \"restart\": \"always\",\n      \"secrets\": [\n        {\n          \"source\": \"secret1\"\n        },\n        {\n          \"source\": \"secret2\",\n          \"target\": \"my_secret\",\n          \"uid\": \"103\",\n          \"gid\": \"103\",\n          \"mode\": 288\n        }\n      ],\n      \"security_opt\": [\n        \"label=level:s0:c100,c200\",\n        \"label=type:svirt_apache_t\"\n      ],\n      \"stdin_open\": true,\n      \"stop_grace_period\": \"20s\",\n      \"stop_signal\": \"SIGUSR1\",\n      \"sysctls\": {\n        \"net.core.somaxconn\": \"1024\",\n        \"net.ipv4.tcp_syncookies\": \"0\"\n      },\n      \"tmpfs\": [\n        \"/run\",\n        \"/tmp\"\n      ],\n      \"tty\": true,\n      \"ulimits\": {\n        \"nofile\": {\n          \"soft\": 20000,\n          \"hard\": 40000\n        },\n        \"nproc\": 65535\n      },\n      \"user\": \"someone\",\n      \"volumes\": [\n        {\n          \"type\": \"volume\",\n          \"target\": \"/var/lib/mysql\",\n          \"volume\": {}\n        },\n        {\n          \"type\": \"bind\",\n          \"source\": \"/opt/data\",\n          \"target\": \"/var/lib/mysql\",\n          \"bind\": {\n            \"create_host_path\": true\n          }\n        },\n        {\n          \"type\": \"bind\",\n          \"source\": \"%s\",\n          \"target\": \"/code\",\n          \"bind\": {\n            \"create_host_path\": true\n          }\n        },\n        {\n          \"type\": \"bind\",\n          \"source\": \"%s\",\n          \"target\": \"/var/www/html\",\n          \"bind\": {\n            \"create_host_path\": true\n          }\n        },\n        {\n          \"type\": \"bind\",\n          \"source\": \"%s\",\n          \"target\": \"/etc/configs/\",\n          \"read_only\": true,\n          \"bind\": {\n            \"create_host_path\": true\n          }\n        },\n        {\n          \"type\": \"volume\",\n          \"source\": \"datavolume\",\n          \"target\": \"/var/lib/mysql\",\n          \"volume\": {}\n        },\n        {\n          \"type\": \"bind\",\n          \"source\": \"%s\",\n          \"target\": \"/opt\",\n          \"consistency\": \"cached\"\n        },\n        {\n          \"type\": \"tmpfs\",\n          \"target\": \"/opt\",\n          \"tmpfs\": {\n            \"size\": 10000\n          }\n        }\n      ],\n      \"working_dir\": \"/code\"\n    }\n  },\n  \"volumes\": {\n    \"another-volume\": {\n      \"name\": \"user_specified_name\",\n      \"driver\": \"vsphere\",\n      \"driver_opts\": {\n        \"baz\": \"1\",\n        \"foo\": \"bar\"\n      },\n      \"external\": false\n    },\n    \"external-volume\": {\n      \"name\": \"external-volume\",\n      \"external\": true\n    },\n    \"external-volume3\": {\n      \"name\": \"this-is-volume3\",\n      \"external\": true\n    },\n    \"other-external-volume\": {\n      \"name\": \"my-cool-volume\",\n      \"external\": true\n    },\n    \"other-volume\": {\n      \"driver\": \"flocker\",\n      \"driver_opts\": {\n        \"baz\": \"1\",\n        \"foo\": \"bar\"\n      },\n      \"external\": false,\n      \"labels\": {\n        \"foo\": \"bar\"\n      }\n    },\n    \"some-volume\": {\n      \"external\": false\n    }\n  },\n  \"x-bar\": \"baz\",\n  \"x-foo\": \"bar\",\n  \"x-nested\": {\n    \"bar\": \"baz\",\n    \"foo\": \"bar\"\n  }\n}`,\n\t\ttoPath(workingDir, \"config_data\"),\n\t\ttoPath(workingDir),\n\t\ttoPath(workingDir, \"secret_data\"),\n\t\ttoPath(workingDir),\n\t\ttoPath(workingDir),\n\t\ttoPath(workingDir, \"static\"),\n\t\ttoPath(homeDir, \"configs\"),\n\t\ttoPath(workingDir, \"opt\"))\n}\n\nfunc toPath(path ...string) string {\n\treturn strings.ReplaceAll(filepath.Join(path...), \"\\\\\", \"\\\\\\\\\")\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/interpolate.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\tinterp \"github.com/compose-spec/compose-go/interpolation\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n)\n\nvar interpolateTypeCastMapping = map[interp.Path]interp.Cast{\n\tservicePath(\"configs\", interp.PathMatchList, \"mode\"):             toInt,\n\tservicePath(\"cpu_count\"):                                         toInt64,\n\tservicePath(\"cpu_percent\"):                                       toFloat,\n\tservicePath(\"cpu_period\"):                                        toInt64,\n\tservicePath(\"cpu_quota\"):                                         toInt64,\n\tservicePath(\"cpu_rt_period\"):                                     toInt64,\n\tservicePath(\"cpu_rt_runtime\"):                                    toInt64,\n\tservicePath(\"cpus\"):                                              toFloat32,\n\tservicePath(\"cpu_shares\"):                                        toInt64,\n\tservicePath(\"init\"):                                              toBoolean,\n\tservicePath(\"deploy\", \"replicas\"):                                toInt,\n\tservicePath(\"deploy\", \"update_config\", \"parallelism\"):            toInt,\n\tservicePath(\"deploy\", \"update_config\", \"max_failure_ratio\"):      toFloat,\n\tservicePath(\"deploy\", \"rollback_config\", \"parallelism\"):          toInt,\n\tservicePath(\"deploy\", \"rollback_config\", \"max_failure_ratio\"):    toFloat,\n\tservicePath(\"deploy\", \"restart_policy\", \"max_attempts\"):          toInt,\n\tservicePath(\"deploy\", \"placement\", \"max_replicas_per_node\"):      toInt,\n\tservicePath(\"healthcheck\", \"retries\"):                            toInt,\n\tservicePath(\"healthcheck\", \"disable\"):                            toBoolean,\n\tservicePath(\"mem_limit\"):                                         toUnitBytes,\n\tservicePath(\"mem_reservation\"):                                   toUnitBytes,\n\tservicePath(\"memswap_limit\"):                                     toUnitBytes,\n\tservicePath(\"mem_swappiness\"):                                    toUnitBytes,\n\tservicePath(\"oom_kill_disable\"):                                  toBoolean,\n\tservicePath(\"oom_score_adj\"):                                     toInt64,\n\tservicePath(\"pids_limit\"):                                        toInt64,\n\tservicePath(\"ports\", interp.PathMatchList, \"target\"):             toInt,\n\tservicePath(\"ports\", interp.PathMatchList, \"published\"):          toInt,\n\tservicePath(\"privileged\"):                                        toBoolean,\n\tservicePath(\"read_only\"):                                         toBoolean,\n\tservicePath(\"scale\"):                                             toInt,\n\tservicePath(\"secrets\", interp.PathMatchList, \"mode\"):             toInt,\n\tservicePath(\"shm_size\"):                                          toUnitBytes,\n\tservicePath(\"stdin_open\"):                                        toBoolean,\n\tservicePath(\"stop_grace_period\"):                                 toDuration,\n\tservicePath(\"tty\"):                                               toBoolean,\n\tservicePath(\"ulimits\", interp.PathMatchAll):                      toInt,\n\tservicePath(\"ulimits\", interp.PathMatchAll, \"hard\"):              toInt,\n\tservicePath(\"ulimits\", interp.PathMatchAll, \"soft\"):              toInt,\n\tservicePath(\"volumes\", interp.PathMatchList, \"read_only\"):        toBoolean,\n\tservicePath(\"volumes\", interp.PathMatchList, \"volume\", \"nocopy\"): toBoolean,\n\tiPath(\"networks\", interp.PathMatchAll, \"external\"):               toBoolean,\n\tiPath(\"networks\", interp.PathMatchAll, \"internal\"):               toBoolean,\n\tiPath(\"networks\", interp.PathMatchAll, \"attachable\"):             toBoolean,\n\tiPath(\"volumes\", interp.PathMatchAll, \"external\"):                toBoolean,\n\tiPath(\"secrets\", interp.PathMatchAll, \"external\"):                toBoolean,\n\tiPath(\"configs\", interp.PathMatchAll, \"external\"):                toBoolean,\n}\n\nfunc iPath(parts ...string) interp.Path {\n\treturn interp.NewPath(parts...)\n}\n\nfunc servicePath(parts ...string) interp.Path {\n\treturn iPath(append([]string{\"services\", interp.PathMatchAll}, parts...)...)\n}\n\nfunc toInt(value string) (interface{}, error) {\n\treturn strconv.Atoi(value)\n}\n\nfunc toInt64(value string) (interface{}, error) {\n\treturn strconv.ParseInt(value, 10, 64)\n}\n\nfunc toUnitBytes(value string) (interface{}, error) {\n\ti, err := strconv.ParseInt(value, 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn types.UnitBytes(i), nil\n}\n\nfunc toDuration(value string) (interface{}, error) {\n\ti, err := strconv.ParseInt(value, 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn types.Duration(i), nil\n}\n\nfunc toFloat(value string) (interface{}, error) {\n\treturn strconv.ParseFloat(value, 64)\n}\n\nfunc toFloat32(value string) (interface{}, error) {\n\tf, err := strconv.ParseFloat(value, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn float32(f), nil\n}\n\n// should match http://yaml.org/type/bool.html\nfunc toBoolean(value string) (interface{}, error) {\n\tswitch strings.ToLower(value) {\n\tcase \"y\", \"yes\", \"true\", \"on\":\n\t\treturn true, nil\n\tcase \"n\", \"no\", \"false\", \"off\":\n\t\treturn false, nil\n\tdefault:\n\t\treturn nil, errors.Errorf(\"invalid boolean: %s\", value)\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/loader.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\tinterp \"github.com/compose-spec/compose-go/interpolation\"\n\t//\"github.com/compose-spec/compose-go/schema\"\n\t\"github.com/compose-spec/compose-go/template\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/docker/go-units\"\n\t\"github.com/mattn/go-shellwords\"\n\t\"github.com/mitchellh/mapstructure\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/ulyssessouza/godotenv\"\n\t\"gopkg.in/yaml.v2\"\n)\n\n// Options supported by Load\ntype Options struct {\n\t// Skip schema validation\n\tSkipValidation bool\n\t// Skip interpolation\n\tSkipInterpolation bool\n\t// Skip normalization\n\tSkipNormalization bool\n\t// Resolve paths\n\tResolvePaths bool\n\t// Skip consistency check\n\tSkipConsistencyCheck bool\n\t// Skip extends\n\tSkipExtends bool\n\t// Interpolation options\n\tInterpolate *interp.Options\n\t// Discard 'env_file' entries after resolving to 'environment' section\n\tdiscardEnvFiles bool\n\t// Set project name\n\tName string\n}\n\n// serviceRef identifies a reference to a service. It's used to detect cyclic\n// references in \"extends\".\ntype serviceRef struct {\n\tfilename string\n\tservice  string\n}\n\ntype cycleTracker struct {\n\tloaded []serviceRef\n}\n\nfunc (ct *cycleTracker) Add(filename, service string) error {\n\ttoAdd := serviceRef{filename: filename, service: service}\n\tfor _, loaded := range ct.loaded {\n\t\tif toAdd == loaded {\n\t\t\t// Create an error message of the form:\n\t\t\t// Circular reference:\n\t\t\t//   service-a in docker-compose.yml\n\t\t\t//   extends service-b in docker-compose.yml\n\t\t\t//   extends service-a in docker-compose.yml\n\t\t\terrLines := []string{\n\t\t\t\t\"Circular reference:\",\n\t\t\t\tfmt.Sprintf(\"  %s in %s\", ct.loaded[0].service, ct.loaded[0].filename),\n\t\t\t}\n\t\t\tfor _, service := range append(ct.loaded[1:], toAdd) {\n\t\t\t\terrLines = append(errLines, fmt.Sprintf(\"  extends %s in %s\", service.service, service.filename))\n\t\t\t}\n\n\t\t\treturn errors.New(strings.Join(errLines, \"\\n\"))\n\t\t}\n\t}\n\n\tct.loaded = append(ct.loaded, toAdd)\n\treturn nil\n}\n\n// WithDiscardEnvFiles sets the Options to discard the `env_file` section after resolving to\n// the `environment` section\nfunc WithDiscardEnvFiles(opts *Options) {\n\topts.discardEnvFiles = true\n}\n\n// WithSkipValidation sets the Options to skip validation when loading sections\nfunc WithSkipValidation(opts *Options) {\n\topts.SkipValidation = true\n}\n\n// ParseYAML reads the bytes from a file, parses the bytes into a mapping\n// structure, and returns it.\nfunc ParseYAML(source []byte) (map[string]interface{}, error) {\n\tvar cfg interface{}\n\tif err := yaml.Unmarshal(source, &cfg); err != nil {\n\t\treturn nil, err\n\t}\n\tcfgMap, ok := cfg.(map[interface{}]interface{})\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"Top-level object must be a mapping\")\n\t}\n\tconverted, err := convertToStringKeysRecursive(cfgMap, \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn converted.(map[string]interface{}), nil\n}\n\n// Load reads a ConfigDetails and returns a fully loaded configuration\nfunc Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.Project, error) {\n\tif len(configDetails.ConfigFiles) < 1 {\n\t\treturn nil, errors.Errorf(\"No files specified\")\n\t}\n\n\topts := &Options{\n\t\tInterpolate: &interp.Options{\n\t\t\tSubstitute:      template.Substitute,\n\t\t\tLookupValue:     configDetails.LookupEnv,\n\t\t\tTypeCastMapping: interpolateTypeCastMapping,\n\t\t},\n\t}\n\n\tfor _, op := range options {\n\t\top(opts)\n\t}\n\n\tconfigs := []*types.Config{}\n\tfor i, file := range configDetails.ConfigFiles {\n\t\tconfigDict := file.Config\n\t\tif configDict == nil {\n\t\t\tdict, err := parseConfig(file.Content, opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconfigDict = dict\n\t\t\tfile.Config = dict\n\t\t\tconfigDetails.ConfigFiles[i] = file\n\t\t}\n\n\t\t//QTMP\n\t\t//if !opts.SkipValidation {\n\t\t//\tif err := schema.Validate(configDict); err != nil {\n\t\t//\t\treturn nil, err\n\t\t//\t}\n\t\t//}\n\n\t\tconfigDict = groupXFieldsIntoExtensions(configDict)\n\n\t\tcfg, err := loadSections(file.Filename, configDict, configDetails, opts)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif opts.discardEnvFiles {\n\t\t\tfor i := range cfg.Services {\n\t\t\t\tcfg.Services[i].EnvFile = nil\n\t\t\t}\n\t\t}\n\n\t\tconfigs = append(configs, cfg)\n\t}\n\n\tmodel, err := merge(configs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, s := range model.Services {\n\t\tvar newEnvFiles types.StringList\n\t\tfor _, ef := range s.EnvFile {\n\t\t\tnewEnvFiles = append(newEnvFiles, absPath(configDetails.WorkingDir, ef))\n\t\t}\n\t\ts.EnvFile = newEnvFiles\n\t}\n\n\tproject := &types.Project{\n\t\tName:        opts.Name,\n\t\tWorkingDir:  configDetails.WorkingDir,\n\t\tServices:    model.Services,\n\t\tNetworks:    model.Networks,\n\t\tVolumes:     model.Volumes,\n\t\tSecrets:     model.Secrets,\n\t\tConfigs:     model.Configs,\n\t\tEnvironment: configDetails.Environment,\n\t\tExtensions:  model.Extensions,\n\t}\n\n\tif !opts.SkipNormalization {\n\t\terr = normalize(project, opts.ResolvePaths)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif !opts.SkipConsistencyCheck {\n\t\terr = checkConsistency(project)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn project, nil\n}\n\nfunc parseConfig(b []byte, opts *Options) (map[string]interface{}, error) {\n\tyaml, err := ParseYAML(b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !opts.SkipInterpolation {\n\t\treturn interp.Interpolate(yaml, *opts.Interpolate)\n\t}\n\treturn yaml, err\n}\n\nfunc groupXFieldsIntoExtensions(dict map[string]interface{}) map[string]interface{} {\n\textras := map[string]interface{}{}\n\tfor key, value := range dict {\n\t\tif strings.HasPrefix(key, \"x-\") {\n\t\t\textras[key] = value\n\t\t\tdelete(dict, key)\n\t\t}\n\t\tif d, ok := value.(map[string]interface{}); ok {\n\t\t\tdict[key] = groupXFieldsIntoExtensions(d)\n\t\t}\n\t}\n\tif len(extras) > 0 {\n\t\tdict[\"extensions\"] = extras\n\t}\n\treturn dict\n}\n\nfunc loadSections(filename string, config map[string]interface{}, configDetails types.ConfigDetails, opts *Options) (*types.Config, error) {\n\tvar err error\n\tcfg := types.Config{\n\t\tFilename: filename,\n\t}\n\n\tcfg.Services, err = LoadServices(filename, getSection(config, \"services\"), configDetails.WorkingDir, configDetails.LookupEnv, opts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcfg.Networks, err = LoadNetworks(getSection(config, \"networks\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Volumes, err = LoadVolumes(getSection(config, \"volumes\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Secrets, err = LoadSecrets(getSection(config, \"secrets\"), configDetails, opts.ResolvePaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Configs, err = LoadConfigObjs(getSection(config, \"configs\"), configDetails, opts.ResolvePaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\textensions := getSection(config, \"extensions\")\n\tif len(extensions) > 0 {\n\t\tcfg.Extensions = extensions\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cfg, nil\n}\n\nfunc getSection(config map[string]interface{}, key string) map[string]interface{} {\n\tsection, ok := config[key]\n\tif !ok {\n\t\treturn map[string]interface{}{}\n\t}\n\treturn section.(map[string]interface{})\n}\n\n// ForbiddenPropertiesError is returned when there are properties in the Compose\n// file that are forbidden.\ntype ForbiddenPropertiesError struct {\n\tProperties map[string]string\n}\n\nfunc (e *ForbiddenPropertiesError) Error() string {\n\treturn \"Configuration contains forbidden properties\"\n}\n\n// Transform converts the source into the target struct with compose types transformer\n// and the specified transformers if any.\nfunc Transform(source interface{}, target interface{}, additionalTransformers ...Transformer) error {\n\tdata := mapstructure.Metadata{}\n\tconfig := &mapstructure.DecoderConfig{\n\t\tDecodeHook: mapstructure.ComposeDecodeHookFunc(\n\t\t\tcreateTransformHook(additionalTransformers...),\n\t\t\tmapstructure.StringToTimeDurationHookFunc()),\n\t\tResult:   target,\n\t\tMetadata: &data,\n\t}\n\tdecoder, err := mapstructure.NewDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn decoder.Decode(source)\n}\n\n// TransformerFunc defines a function to perform the actual transformation\ntype TransformerFunc func(interface{}) (interface{}, error)\n\n// Transformer defines a map to type transformer\ntype Transformer struct {\n\tTypeOf reflect.Type\n\tFunc   TransformerFunc\n}\n\nfunc createTransformHook(additionalTransformers ...Transformer) mapstructure.DecodeHookFuncType {\n\ttransforms := map[reflect.Type]func(interface{}) (interface{}, error){\n\t\treflect.TypeOf(types.External{}):                         transformExternal,\n\t\treflect.TypeOf(types.HealthCheckTest{}):                  transformHealthCheckTest,\n\t\treflect.TypeOf(types.ShellCommand{}):                     transformShellCommand,\n\t\treflect.TypeOf(types.StringList{}):                       transformStringList,\n\t\treflect.TypeOf(map[string]string{}):                      transformMapStringString,\n\t\treflect.TypeOf(types.UlimitsConfig{}):                    transformUlimits,\n\t\treflect.TypeOf(types.UnitBytes(0)):                       transformSize,\n\t\treflect.TypeOf([]types.ServicePortConfig{}):              transformServicePort,\n\t\treflect.TypeOf(types.ServiceSecretConfig{}):              transformStringSourceMap,\n\t\treflect.TypeOf(types.ServiceConfigObjConfig{}):           transformStringSourceMap,\n\t\treflect.TypeOf(types.StringOrNumberList{}):               transformStringOrNumberList,\n\t\treflect.TypeOf(map[string]*types.ServiceNetworkConfig{}): transformServiceNetworkMap,\n\t\treflect.TypeOf(types.Mapping{}):                          transformMappingOrListFunc(\"=\", false),\n\t\treflect.TypeOf(types.MappingWithEquals{}):                transformMappingOrListFunc(\"=\", true),\n\t\treflect.TypeOf(types.Labels{}):                           transformMappingOrListFunc(\"=\", false),\n\t\treflect.TypeOf(types.MappingWithColon{}):                 transformMappingOrListFunc(\":\", false),\n\t\treflect.TypeOf(types.HostsList{}):                        transformListOrMappingFunc(\":\", false),\n\t\treflect.TypeOf(types.ServiceVolumeConfig{}):              transformServiceVolumeConfig,\n\t\treflect.TypeOf(types.BuildConfig{}):                      transformBuildConfig,\n\t\treflect.TypeOf(types.Duration(0)):                        transformStringToDuration,\n\t\treflect.TypeOf(types.DependsOnConfig{}):                  transformDependsOnConfig,\n\t\treflect.TypeOf(types.ExtendsConfig{}):                    transformExtendsConfig,\n\t\treflect.TypeOf(types.DeviceRequest{}):                    transformServiceDeviceRequest,\n\t}\n\n\tfor _, transformer := range additionalTransformers {\n\t\ttransforms[transformer.TypeOf] = transformer.Func\n\t}\n\n\treturn func(_ reflect.Type, target reflect.Type, data interface{}) (interface{}, error) {\n\t\ttransform, ok := transforms[target]\n\t\tif !ok {\n\t\t\treturn data, nil\n\t\t}\n\t\treturn transform(data)\n\t}\n}\n\n// keys needs to be converted to strings for jsonschema\nfunc convertToStringKeysRecursive(value interface{}, keyPrefix string) (interface{}, error) {\n\tif mapping, ok := value.(map[interface{}]interface{}); ok {\n\t\tdict := map[string]interface{}{}\n\t\tfor key, entry := range mapping {\n\t\t\tstr, ok := key.(string)\n\t\t\tif !ok {\n\t\t\t\treturn nil, formatInvalidKeyError(keyPrefix, key)\n\t\t\t}\n\t\t\tvar newKeyPrefix string\n\t\t\tif keyPrefix == \"\" {\n\t\t\t\tnewKeyPrefix = str\n\t\t\t} else {\n\t\t\t\tnewKeyPrefix = fmt.Sprintf(\"%s.%s\", keyPrefix, str)\n\t\t\t}\n\t\t\tconvertedEntry, err := convertToStringKeysRecursive(entry, newKeyPrefix)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdict[str] = convertedEntry\n\t\t}\n\t\treturn dict, nil\n\t}\n\tif list, ok := value.([]interface{}); ok {\n\t\tconvertedList := []interface{}{}\n\t\tfor index, entry := range list {\n\t\t\tnewKeyPrefix := fmt.Sprintf(\"%s[%d]\", keyPrefix, index)\n\t\t\tconvertedEntry, err := convertToStringKeysRecursive(entry, newKeyPrefix)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconvertedList = append(convertedList, convertedEntry)\n\t\t}\n\t\treturn convertedList, nil\n\t}\n\treturn value, nil\n}\n\nfunc formatInvalidKeyError(keyPrefix string, key interface{}) error {\n\tvar location string\n\tif keyPrefix == \"\" {\n\t\tlocation = \"at top level\"\n\t} else {\n\t\tlocation = fmt.Sprintf(\"in %s\", keyPrefix)\n\t}\n\treturn errors.Errorf(\"Non-string key %s: %#v\", location, key)\n}\n\n// LoadServices produces a ServiceConfig map from a compose file Dict\n// the servicesDict is not validated if directly used. Use Load() to enable validation\nfunc LoadServices(filename string, servicesDict map[string]interface{}, workingDir string, lookupEnv template.Mapping, opts *Options) ([]types.ServiceConfig, error) {\n\tvar services []types.ServiceConfig\n\n\tx, ok := servicesDict[\"extensions\"]\n\tif ok {\n\t\t// as a top-level attribute, \"services\" doesn't support extensions, and a service can be named `x-foo`\n\t\tfor k, v := range x.(map[string]interface{}) {\n\t\t\tservicesDict[k] = v\n\t\t}\n\t}\n\n\tfor name := range servicesDict {\n\t\tserviceConfig, err := loadServiceWithExtends(filename, name, servicesDict, workingDir, lookupEnv, opts, &cycleTracker{})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tservices = append(services, *serviceConfig)\n\t}\n\n\treturn services, nil\n}\n\nfunc loadServiceWithExtends(filename, name string, servicesDict map[string]interface{}, workingDir string, lookupEnv template.Mapping, opts *Options, ct *cycleTracker) (*types.ServiceConfig, error) {\n\tif err := ct.Add(filename, name); err != nil {\n\t\treturn nil, err\n\t}\n\n\tserviceConfig, err := LoadService(name, servicesDict[name].(map[string]interface{}), workingDir, lookupEnv, opts.ResolvePaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif serviceConfig.Extends != nil && !opts.SkipExtends {\n\t\tbaseServiceName := *serviceConfig.Extends[\"service\"]\n\t\tvar baseService *types.ServiceConfig\n\t\tif file := serviceConfig.Extends[\"file\"]; file == nil {\n\t\t\tbaseService, err = loadServiceWithExtends(filename, baseServiceName, servicesDict, workingDir, lookupEnv, opts, ct)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\t// Resolve the path to the imported file, and load it.\n\t\t\tbaseFilePath := absPath(workingDir, *file)\n\n\t\t\tbytes, err := ioutil.ReadFile(baseFilePath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tbaseFile, err := parseConfig(bytes, opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tbaseFileServices := getSection(baseFile, \"services\")\n\t\t\tbaseService, err = loadServiceWithExtends(baseFilePath, baseServiceName, baseFileServices, filepath.Dir(baseFilePath), lookupEnv, opts, ct)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Make paths relative to the importing Compose file. Note that we\n\t\t\t// make the paths relative to `*file` rather than `baseFilePath` so\n\t\t\t// that the resulting paths won't be absolute if `*file` isn't an\n\t\t\t// absolute path.\n\t\t\tbaseFileParent := filepath.Dir(*file)\n\t\t\tif baseService.Build != nil {\n\t\t\t\t// Note that the Dockerfile is always defined relative to the\n\t\t\t\t// build context, so there's no need to update the Dockerfile field.\n\t\t\t\tbaseService.Build.Context = absPath(baseFileParent, baseService.Build.Context)\n\t\t\t}\n\n\t\t\tfor i, vol := range baseService.Volumes {\n\t\t\t\tif vol.Type != types.VolumeTypeBind {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbaseService.Volumes[i].Source = absPath(baseFileParent, vol.Source)\n\t\t\t}\n\t\t}\n\n\t\tserviceConfig, err = _merge(baseService, serviceConfig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn serviceConfig, nil\n}\n\n// LoadService produces a single ServiceConfig from a compose file Dict\n// the serviceDict is not validated if directly used. Use Load() to enable validation\nfunc LoadService(name string, serviceDict map[string]interface{}, workingDir string, lookupEnv template.Mapping, resolvePaths bool) (*types.ServiceConfig, error) {\n\tserviceConfig := &types.ServiceConfig{\n\t\tScale: 1,\n\t}\n\tif err := Transform(serviceDict, serviceConfig); err != nil {\n\t\treturn nil, err\n\t}\n\tserviceConfig.Name = name\n\n\tif err := resolveEnvironment(serviceConfig, workingDir, lookupEnv); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor i, volume := range serviceConfig.Volumes {\n\t\tif volume.Type != \"bind\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif volume.Source == \"\" {\n\t\t\treturn nil, errors.New(`invalid mount config for type \"bind\": field Source must not be empty`)\n\t\t}\n\n\t\tif resolvePaths {\n\t\t\tserviceConfig.Volumes[i] = resolveVolumePath(volume, workingDir, lookupEnv)\n\t\t}\n\t}\n\n\treturn serviceConfig, nil\n}\n\nfunc resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string, lookupEnv template.Mapping) error {\n\tenvironment := types.MappingWithEquals{}\n\n\tif len(serviceConfig.EnvFile) > 0 {\n\t\tfor _, file := range serviceConfig.EnvFile {\n\t\t\tfilePath := absPath(workingDir, file)\n\t\t\tfile, err := os.Open(filePath)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer file.Close()\n\t\t\tfileVars, err := godotenv.Parse(file)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tenv := types.MappingWithEquals{}\n\t\t\tfor k, v := range fileVars {\n\t\t\t\tv := v\n\t\t\t\tenv[k] = &v\n\t\t\t}\n\t\t\tenvironment.OverrideBy(env.Resolve(lookupEnv).RemoveEmpty())\n\t\t}\n\t}\n\n\tenvironment.OverrideBy(serviceConfig.Environment.Resolve(lookupEnv))\n\tserviceConfig.Environment = environment\n\treturn nil\n}\n\nfunc resolveVolumePath(volume types.ServiceVolumeConfig, workingDir string, lookupEnv template.Mapping) types.ServiceVolumeConfig {\n\tfilePath := expandUser(volume.Source, lookupEnv)\n\t// Check if source is an absolute path (either Unix or Windows), to\n\t// handle a Windows client with a Unix daemon or vice-versa.\n\t//\n\t// Note that this is not required for Docker for Windows when specifying\n\t// a local Windows path, because Docker for Windows translates the Windows\n\t// path into a valid path within the VM.\n\tif !path.IsAbs(filePath) && !isAbs(filePath) {\n\t\tfilePath = absPath(workingDir, filePath)\n\t}\n\tvolume.Source = filePath\n\treturn volume\n}\n\n// TODO: make this more robust\nfunc expandUser(path string, lookupEnv template.Mapping) string {\n\tif strings.HasPrefix(path, \"~\") {\n\t\thome, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\tlogrus.Warn(\"cannot expand '~', because the environment lacks HOME\")\n\t\t\treturn path\n\t\t}\n\t\treturn filepath.Join(home, path[1:])\n\t}\n\treturn path\n}\n\nfunc transformUlimits(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase int:\n\t\treturn types.UlimitsConfig{Single: value}, nil\n\tcase map[string]interface{}:\n\t\tulimit := types.UlimitsConfig{}\n\t\tif v, ok := value[\"soft\"]; ok {\n\t\t\tulimit.Soft = v.(int)\n\t\t}\n\t\tif v, ok := value[\"hard\"]; ok {\n\t\t\tulimit.Hard = v.(int)\n\t\t}\n\t\treturn ulimit, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for ulimits\", value)\n\t}\n}\n\n// LoadNetworks produces a NetworkConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadNetworks(source map[string]interface{}) (map[string]types.NetworkConfig, error) {\n\tnetworks := map[string]types.NetworkConfig{}\n\terr := Transform(source, &networks)\n\tif err != nil {\n\t\treturn networks, err\n\t}\n\tfor name, network := range networks {\n\t\tif !network.External.External {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase network.External.Name != \"\":\n\t\t\tif network.Name != \"\" {\n\t\t\t\treturn nil, errors.Errorf(\"network %s: network.external.name and network.name conflict; only use network.name\", name)\n\t\t\t}\n\t\t\tlogrus.Warnf(\"network %s: network.external.name is deprecated in favor of network.name\", name)\n\t\t\tnetwork.Name = network.External.Name\n\t\t\tnetwork.External.Name = \"\"\n\t\tcase network.Name == \"\":\n\t\t\tnetwork.Name = name\n\t\t}\n\t\tnetworks[name] = network\n\t}\n\treturn networks, nil\n}\n\nfunc externalVolumeError(volume, key string) error {\n\treturn errors.Errorf(\n\t\t\"conflicting parameters \\\"external\\\" and %q specified for volume %q\",\n\t\tkey, volume)\n}\n\n// LoadVolumes produces a VolumeConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig, error) {\n\tvolumes := make(map[string]types.VolumeConfig)\n\tif err := Transform(source, &volumes); err != nil {\n\t\treturn volumes, err\n\t}\n\n\tfor name, volume := range volumes {\n\t\tif !volume.External.External {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase volume.Driver != \"\":\n\t\t\treturn nil, externalVolumeError(name, \"driver\")\n\t\tcase len(volume.DriverOpts) > 0:\n\t\t\treturn nil, externalVolumeError(name, \"driver_opts\")\n\t\tcase len(volume.Labels) > 0:\n\t\t\treturn nil, externalVolumeError(name, \"labels\")\n\t\tcase volume.External.Name != \"\":\n\t\t\tif volume.Name != \"\" {\n\t\t\t\treturn nil, errors.Errorf(\"volume %s: volume.external.name and volume.name conflict; only use volume.name\", name)\n\t\t\t}\n\t\t\tlogrus.Warnf(\"volume %s: volume.external.name is deprecated in favor of volume.name\", name)\n\t\t\tvolume.Name = volume.External.Name\n\t\t\tvolume.External.Name = \"\"\n\t\tcase volume.Name == \"\":\n\t\t\tvolume.Name = name\n\t\t}\n\t\tvolumes[name] = volume\n\t}\n\treturn volumes, nil\n}\n\n// LoadSecrets produces a SecretConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadSecrets(source map[string]interface{}, details types.ConfigDetails, resolvePaths bool) (map[string]types.SecretConfig, error) {\n\tsecrets := make(map[string]types.SecretConfig)\n\tif err := Transform(source, &secrets); err != nil {\n\t\treturn secrets, err\n\t}\n\tfor name, secret := range secrets {\n\t\tobj, err := loadFileObjectConfig(name, \"secret\", types.FileObjectConfig(secret), details, resolvePaths)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsecretConfig := types.SecretConfig(obj)\n\t\tsecrets[name] = secretConfig\n\t}\n\treturn secrets, nil\n}\n\n// LoadConfigObjs produces a ConfigObjConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadConfigObjs(source map[string]interface{}, details types.ConfigDetails, resolvePaths bool) (map[string]types.ConfigObjConfig, error) {\n\tconfigs := make(map[string]types.ConfigObjConfig)\n\tif err := Transform(source, &configs); err != nil {\n\t\treturn configs, err\n\t}\n\tfor name, config := range configs {\n\t\tobj, err := loadFileObjectConfig(name, \"config\", types.FileObjectConfig(config), details, resolvePaths)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfigConfig := types.ConfigObjConfig(obj)\n\t\tconfigs[name] = configConfig\n\t}\n\treturn configs, nil\n}\n\nfunc loadFileObjectConfig(name string, objType string, obj types.FileObjectConfig, details types.ConfigDetails, resolvePaths bool) (types.FileObjectConfig, error) {\n\t// if \"external: true\"\n\tswitch {\n\tcase obj.External.External:\n\t\t// handle deprecated external.name\n\t\tif obj.External.Name != \"\" {\n\t\t\tif obj.Name != \"\" {\n\t\t\t\treturn obj, errors.Errorf(\"%[1]s %[2]s: %[1]s.external.name and %[1]s.name conflict; only use %[1]s.name\", objType, name)\n\t\t\t}\n\t\t\tlogrus.Warnf(\"%[1]s %[2]s: %[1]s.external.name is deprecated in favor of %[1]s.name\", objType, name)\n\t\t\tobj.Name = obj.External.Name\n\t\t\tobj.External.Name = \"\"\n\t\t} else {\n\t\t\tif obj.Name == \"\" {\n\t\t\t\tobj.Name = name\n\t\t\t}\n\t\t}\n\t\t// if not \"external: true\"\n\tcase obj.Driver != \"\":\n\t\tif obj.File != \"\" {\n\t\t\treturn obj, errors.Errorf(\"%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver\", objType, name)\n\t\t}\n\tdefault:\n\t\tif resolvePaths {\n\t\t\tobj.File = absPath(details.WorkingDir, obj.File)\n\t\t}\n\t}\n\n\treturn obj, nil\n}\n\nfunc absPath(workingDir string, filePath string) string {\n\tif strings.HasPrefix(filePath, \"~\") {\n\t\thome, _ := os.UserHomeDir()\n\t\treturn filepath.Join(home, filePath[1:])\n\t}\n\tif filepath.IsAbs(filePath) {\n\t\treturn filePath\n\t}\n\treturn filepath.Join(workingDir, filePath)\n}\n\nvar transformMapStringString TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase map[string]interface{}:\n\t\treturn toMapStringString(value, false), nil\n\tcase map[string]string:\n\t\treturn value, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for map[string]string\", value)\n\t}\n}\n\nvar transformExternal TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase bool:\n\t\treturn map[string]interface{}{\"external\": value}, nil\n\tcase map[string]interface{}:\n\t\treturn map[string]interface{}{\"external\": true, \"name\": value[\"name\"]}, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for external\", value)\n\t}\n}\n\nvar transformServicePort TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch entries := data.(type) {\n\tcase []interface{}:\n\t\t// We process the list instead of individual items here.\n\t\t// The reason is that one entry might be mapped to multiple ServicePortConfig.\n\t\t// Therefore we take an input of a list and return an output of a list.\n\t\tports := []interface{}{}\n\t\tfor _, entry := range entries {\n\t\t\tswitch value := entry.(type) {\n\t\t\tcase int:\n\t\t\t\tparsed, err := types.ParsePortConfig(fmt.Sprint(value))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn data, err\n\t\t\t\t}\n\t\t\t\tfor _, v := range parsed {\n\t\t\t\t\tports = append(ports, v)\n\t\t\t\t}\n\t\t\tcase string:\n\t\t\t\tparsed, err := types.ParsePortConfig(value)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn data, err\n\t\t\t\t}\n\t\t\t\tfor _, v := range parsed {\n\t\t\t\t\tports = append(ports, v)\n\t\t\t\t}\n\t\t\tcase map[string]interface{}:\n\t\t\t\tports = append(ports, groupXFieldsIntoExtensions(value))\n\t\t\tdefault:\n\t\t\t\treturn data, errors.Errorf(\"invalid type %T for port\", value)\n\t\t\t}\n\t\t}\n\t\treturn ports, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for port\", entries)\n\t}\n}\n\nvar transformServiceDeviceRequest TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase map[string]interface{}:\n\t\tcount, ok := value[\"count\"]\n\t\tif ok {\n\t\t\tswitch val := count.(type) {\n\t\t\tcase int:\n\t\t\t\treturn value, nil\n\t\t\tcase string:\n\t\t\t\tif strings.ToLower(val) == \"all\" {\n\t\t\t\t\tvalue[\"count\"] = -1\n\t\t\t\t\treturn value, nil\n\t\t\t\t}\n\t\t\t\treturn data, errors.Errorf(\"invalid string value for 'count' (the only value allowed is 'all')\")\n\t\t\tdefault:\n\t\t\t\treturn data, errors.Errorf(\"invalid type %T for device count\", val)\n\t\t\t}\n\t\t}\n\t\treturn data, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for resource reservation\", value)\n\t}\n}\n\nvar transformStringSourceMap TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn map[string]interface{}{\"source\": value}, nil\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for secret\", value)\n\t}\n}\n\nvar transformBuildConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn map[string]interface{}{\"context\": value}, nil\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for service build\", value)\n\t}\n}\n\nvar transformDependsOnConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase []interface{}:\n\t\ttransformed := map[string]interface{}{}\n\t\tfor _, serviceIntf := range value {\n\t\t\tservice, ok := serviceIntf.(string)\n\t\t\tif !ok {\n\t\t\t\treturn data, errors.Errorf(\"invalid type %T for service depends_on element. Expected string.\", value)\n\t\t\t}\n\t\t\ttransformed[service] = map[string]interface{}{\"condition\": types.ServiceConditionStarted}\n\t\t}\n\t\treturn transformed, nil\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for service depends_on\", value)\n\t}\n}\n\nvar transformExtendsConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch data.(type) {\n\tcase string:\n\t\tdata = map[string]interface{}{\n\t\t\t\"service\": data,\n\t\t}\n\t}\n\treturn transformMappingOrListFunc(\"=\", true)(data)\n}\n\nvar transformServiceVolumeConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn ParseVolume(value)\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for service volume\", value)\n\t}\n}\n\nvar transformServiceNetworkMap TransformerFunc = func(value interface{}) (interface{}, error) {\n\tif list, ok := value.([]interface{}); ok {\n\t\tmapValue := map[interface{}]interface{}{}\n\t\tfor _, name := range list {\n\t\t\tmapValue[name] = nil\n\t\t}\n\t\treturn mapValue, nil\n\t}\n\treturn value, nil\n}\n\nvar transformStringOrNumberList TransformerFunc = func(value interface{}) (interface{}, error) {\n\tlist := value.([]interface{})\n\tresult := make([]string, len(list))\n\tfor i, item := range list {\n\t\tresult[i] = fmt.Sprint(item)\n\t}\n\treturn result, nil\n}\n\nvar transformStringList TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn []string{value}, nil\n\tcase []interface{}:\n\t\treturn value, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for string list\", value)\n\t}\n}\n\nfunc transformMappingOrListFunc(sep string, allowNil bool) TransformerFunc {\n\treturn func(data interface{}) (interface{}, error) {\n\t\treturn transformMappingOrList(data, sep, allowNil), nil\n\t}\n}\n\nfunc transformListOrMappingFunc(sep string, allowNil bool) TransformerFunc {\n\treturn func(data interface{}) (interface{}, error) {\n\t\treturn transformListOrMapping(data, sep, allowNil), nil\n\t}\n}\n\nfunc transformListOrMapping(listOrMapping interface{}, sep string, allowNil bool) interface{} {\n\tswitch value := listOrMapping.(type) {\n\tcase map[string]interface{}:\n\t\treturn toStringList(value, sep, allowNil)\n\tcase []interface{}:\n\t\treturn listOrMapping\n\t}\n\tpanic(errors.Errorf(\"expected a map or a list, got %T: %#v\", listOrMapping, listOrMapping))\n}\n\nfunc transformMappingOrList(mappingOrList interface{}, sep string, allowNil bool) interface{} {\n\tswitch value := mappingOrList.(type) {\n\tcase map[string]interface{}:\n\t\treturn toMapStringString(value, allowNil)\n\tcase ([]interface{}):\n\t\tresult := make(map[string]interface{})\n\t\tfor _, value := range value {\n\t\t\tparts := strings.SplitN(value.(string), sep, 2)\n\t\t\tkey := parts[0]\n\t\t\tswitch {\n\t\t\tcase len(parts) == 1 && allowNil:\n\t\t\t\tresult[key] = nil\n\t\t\tcase len(parts) == 1 && !allowNil:\n\t\t\t\tresult[key] = \"\"\n\t\t\tdefault:\n\t\t\t\tresult[key] = parts[1]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\tpanic(errors.Errorf(\"expected a map or a list, got %T: %#v\", mappingOrList, mappingOrList))\n}\n\nvar transformShellCommand TransformerFunc = func(value interface{}) (interface{}, error) {\n\tif str, ok := value.(string); ok {\n\t\treturn shellwords.Parse(str)\n\t}\n\treturn value, nil\n}\n\nvar transformHealthCheckTest TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn append([]string{\"CMD-SHELL\"}, value), nil\n\tcase []interface{}:\n\t\treturn value, nil\n\tdefault:\n\t\treturn value, errors.Errorf(\"invalid type %T for healthcheck.test\", value)\n\t}\n}\n\nvar transformSize TransformerFunc = func(value interface{}) (interface{}, error) {\n\tswitch value := value.(type) {\n\tcase int:\n\t\treturn int64(value), nil\n\tcase int64, types.UnitBytes:\n\t\treturn value, nil\n\tcase string:\n\t\treturn units.RAMInBytes(value)\n\tdefault:\n\t\treturn value, errors.Errorf(\"invalid type for size %T\", value)\n\t}\n}\n\nvar transformStringToDuration TransformerFunc = func(value interface{}) (interface{}, error) {\n\tswitch value := value.(type) {\n\tcase string:\n\t\td, err := time.ParseDuration(value)\n\t\tif err != nil {\n\t\t\treturn value, err\n\t\t}\n\t\treturn types.Duration(d), nil\n\tdefault:\n\t\treturn value, errors.Errorf(\"invalid type %T for duration\", value)\n\t}\n}\n\nfunc toMapStringString(value map[string]interface{}, allowNil bool) map[string]interface{} {\n\toutput := make(map[string]interface{})\n\tfor key, value := range value {\n\t\toutput[key] = toString(value, allowNil)\n\t}\n\treturn output\n}\n\nfunc toString(value interface{}, allowNil bool) interface{} {\n\tswitch {\n\tcase value != nil:\n\t\treturn fmt.Sprint(value)\n\tcase allowNil:\n\t\treturn nil\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc toStringList(value map[string]interface{}, separator string, allowNil bool) []string {\n\toutput := []string{}\n\tfor key, value := range value {\n\t\tif value == nil && !allowNil {\n\t\t\tcontinue\n\t\t}\n\t\toutput = append(output, fmt.Sprintf(\"%s%s%s\", key, separator, value))\n\t}\n\tsort.Strings(output)\n\treturn output\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/loader_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"bytes\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\t\"github.com/sirupsen/logrus\"\n\t\"gotest.tools/v3/assert\"\n\tis \"gotest.tools/v3/assert/cmp\"\n)\n\nfunc buildConfigDetails(yaml string, env map[string]string) types.ConfigDetails {\n\tworkingDir, err := os.Getwd()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn types.ConfigDetails{\n\t\tWorkingDir: workingDir,\n\t\tConfigFiles: []types.ConfigFile{\n\t\t\t{Filename: \"filename.yml\", Content: []byte(yaml)},\n\t\t},\n\t\tEnvironment: env,\n\t}\n}\n\nfunc loadYAML(yaml string) (*types.Project, error) {\n\treturn loadYAMLWithEnv(yaml, nil)\n}\n\nfunc loadYAMLWithEnv(yaml string, env map[string]string) (*types.Project, error) {\n\treturn Load(buildConfigDetails(yaml, env), func(options *Options) {\n\t\toptions.SkipConsistencyCheck = true\n\t\toptions.SkipNormalization = true\n\t\toptions.ResolvePaths = true\n\t})\n}\n\nvar sampleYAML = `\nservices:\n  foo:\n    image: busybox\n    networks:\n      with_me:\n  bar:\n    image: busybox\n    environment:\n      - FOO=1\n    networks:\n      - with_ipam\nvolumes:\n  hello:\n    driver: default\n    driver_opts:\n      beep: boop\nnetworks:\n  default:\n    driver: bridge\n    driver_opts:\n      beep: boop\n  with_ipam:\n    ipam:\n      driver: default\n      config:\n        - subnet: 172.28.0.0/16\n`\n\nvar sampleDict = map[string]interface{}{\n\t\"services\": map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"image\":    \"busybox\",\n\t\t\t\"networks\": map[string]interface{}{\"with_me\": nil},\n\t\t},\n\t\t\"bar\": map[string]interface{}{\n\t\t\t\"image\":       \"busybox\",\n\t\t\t\"environment\": []interface{}{\"FOO=1\"},\n\t\t\t\"networks\":    []interface{}{\"with_ipam\"},\n\t\t},\n\t},\n\t\"volumes\": map[string]interface{}{\n\t\t\"hello\": map[string]interface{}{\n\t\t\t\"driver\": \"default\",\n\t\t\t\"driver_opts\": map[string]interface{}{\n\t\t\t\t\"beep\": \"boop\",\n\t\t\t},\n\t\t},\n\t},\n\t\"networks\": map[string]interface{}{\n\t\t\"default\": map[string]interface{}{\n\t\t\t\"driver\": \"bridge\",\n\t\t\t\"driver_opts\": map[string]interface{}{\n\t\t\t\t\"beep\": \"boop\",\n\t\t\t},\n\t\t},\n\t\t\"with_ipam\": map[string]interface{}{\n\t\t\t\"ipam\": map[string]interface{}{\n\t\t\t\t\"driver\": \"default\",\n\t\t\t\t\"config\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"subnet\": \"172.28.0.0/16\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n}\n\nvar samplePortsConfig = []types.ServicePortConfig{\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8080,\n\t\tPublished: 80,\n\t\tProtocol:  \"tcp\",\n\t},\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8081,\n\t\tPublished: 81,\n\t\tProtocol:  \"tcp\",\n\t},\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8082,\n\t\tPublished: 82,\n\t\tProtocol:  \"tcp\",\n\t},\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8090,\n\t\tPublished: 90,\n\t\tProtocol:  \"udp\",\n\t},\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8091,\n\t\tPublished: 91,\n\t\tProtocol:  \"udp\",\n\t},\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8092,\n\t\tPublished: 92,\n\t\tProtocol:  \"udp\",\n\t},\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8500,\n\t\tPublished: 85,\n\t\tProtocol:  \"tcp\",\n\t},\n\t{\n\t\tMode:      \"ingress\",\n\t\tTarget:    8600,\n\t\tPublished: 0,\n\t\tProtocol:  \"tcp\",\n\t},\n\t{\n\t\tTarget:    53,\n\t\tPublished: 10053,\n\t\tProtocol:  \"udp\",\n\t},\n\t{\n\t\tMode:      \"host\",\n\t\tTarget:    22,\n\t\tPublished: 10022,\n\t},\n}\n\nfunc strPtr(val string) *string {\n\treturn &val\n}\n\nvar sampleConfig = types.Config{\n\tServices: []types.ServiceConfig{\n\t\t{\n\t\t\tName:        \"foo\",\n\t\t\tImage:       \"busybox\",\n\t\t\tEnvironment: map[string]*string{},\n\t\t\tNetworks: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\"with_me\": nil,\n\t\t\t},\n\t\t\tScale: 1,\n\t\t},\n\t\t{\n\t\t\tName:        \"bar\",\n\t\t\tImage:       \"busybox\",\n\t\t\tEnvironment: map[string]*string{\"FOO\": strPtr(\"1\")},\n\t\t\tNetworks: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\"with_ipam\": nil,\n\t\t\t},\n\t\t\tScale: 1,\n\t\t},\n\t},\n\tNetworks: map[string]types.NetworkConfig{\n\t\t\"default\": {\n\t\t\tDriver: \"bridge\",\n\t\t\tDriverOpts: map[string]string{\n\t\t\t\t\"beep\": \"boop\",\n\t\t\t},\n\t\t},\n\t\t\"with_ipam\": {\n\t\t\tIpam: types.IPAMConfig{\n\t\t\t\tDriver: \"default\",\n\t\t\t\tConfig: []*types.IPAMPool{\n\t\t\t\t\t{\n\t\t\t\t\t\tSubnet: \"172.28.0.0/16\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\tVolumes: map[string]types.VolumeConfig{\n\t\t\"hello\": {\n\t\t\tDriver: \"default\",\n\t\t\tDriverOpts: map[string]string{\n\t\t\t\t\"beep\": \"boop\",\n\t\t\t},\n\t\t},\n\t},\n}\n\nfunc TestParseYAML(t *testing.T) {\n\tdict, err := ParseYAML([]byte(sampleYAML))\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(sampleDict, dict))\n}\n\nfunc TestLoad(t *testing.T) {\n\tactual, err := Load(buildConfigDetails(sampleYAML, nil), func(options *Options) {\n\t\toptions.SkipNormalization = true\n\t\toptions.SkipConsistencyCheck = true\n\t})\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(serviceSort(sampleConfig.Services), serviceSort(actual.Services)))\n\tassert.Check(t, is.DeepEqual(sampleConfig.Networks, actual.Networks))\n\tassert.Check(t, is.DeepEqual(sampleConfig.Volumes, actual.Volumes))\n}\n\nfunc TestLoadExtensions(t *testing.T) {\n\tactual, err := loadYAML(`\nservices:\n  foo:\n    image: busybox\n    x-foo: bar`)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Len(actual.Services, 1))\n\tservice := actual.Services[0]\n\tassert.Check(t, is.Equal(\"busybox\", service.Image))\n\textras := map[string]interface{}{\n\t\t\"x-foo\": \"bar\",\n\t}\n\tassert.Check(t, is.DeepEqual(extras, service.Extensions))\n}\n\nfunc TestLoadExtends(t *testing.T) {\n\tactual, err := loadYAML(`\nservices:\n  foo:\n    image: busybox\n    extends:\n      service: bar\n  bar:\n    image: alpine\n    command: echo`)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Len(actual.Services, 2))\n\tservice, err := actual.GetService(\"foo\")\n\tassert.NilError(t, err)\n\tassert.Check(t, service.Image == \"busybox\")\n\tassert.Check(t, service.Command[0] == \"echo\")\n}\n\nfunc TestLoadExtendsOverrideCommand(t *testing.T) {\n\tactual, err := loadYAML(`\nservices:\n  foo:\n    image: busybox\n    extends:\n      service: bar\n    command: \"/bin/ash -c \\\"rm -rf /tmp/might-not-exist\\\"\"\n  bar:\n    image: alpine\n    command: \"/bin/ash -c \\\"echo Oh no...\\\"\"`)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Len(actual.Services, 2))\n\tservice, err := actual.GetService(\"foo\")\n\tassert.NilError(t, err)\n\tassert.Check(t, service.Image == \"busybox\")\n\tassert.DeepEqual(t, service.Command, types.ShellCommand{\"/bin/ash\", \"-c\", \"rm -rf /tmp/might-not-exist\"})\n}\n\nfunc TestLoadCredentialSpec(t *testing.T) {\n\tactual, err := loadYAML(`\nservices:\n  foo:\n    image: busybox\n    credential_spec:\n      config: \"0bt9dmxjvjiqermk6xrop3ekq\"\n`)\n\tassert.NilError(t, err)\n\tassert.Assert(t, is.Len(actual.Services, 1))\n\tassert.Check(t, is.Equal(actual.Services[0].CredentialSpec.Config, \"0bt9dmxjvjiqermk6xrop3ekq\"))\n}\n\nfunc TestParseAndLoad(t *testing.T) {\n\tactual, err := loadYAML(sampleYAML)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(serviceSort(sampleConfig.Services), serviceSort(actual.Services)))\n\tassert.Check(t, is.DeepEqual(sampleConfig.Networks, actual.Networks))\n\tassert.Check(t, is.DeepEqual(sampleConfig.Volumes, actual.Volumes))\n}\n\nfunc TestInvalidTopLevelObjectType(t *testing.T) {\n\t_, err := loadYAML(\"1\")\n\tassert.ErrorContains(t, err, \"Top-level object must be a mapping\")\n\n\t_, err = loadYAML(\"\\\"hello\\\"\")\n\tassert.ErrorContains(t, err, \"Top-level object must be a mapping\")\n\n\t_, err = loadYAML(\"[\\\"hello\\\"]\")\n\tassert.ErrorContains(t, err, \"Top-level object must be a mapping\")\n}\n\nfunc TestNonStringKeys(t *testing.T) {\n\t_, err := loadYAML(`\n123:\n  foo:\n    image: busybox\n`)\n\tassert.ErrorContains(t, err, \"Non-string key at top level: 123\")\n\n\t_, err = loadYAML(`\nservices:\n  foo:\n    image: busybox\n  123:\n    image: busybox\n`)\n\tassert.ErrorContains(t, err, \"Non-string key in services: 123\")\n\n\t_, err = loadYAML(`\nservices:\n  foo:\n    image: busybox\nnetworks:\n  default:\n    ipam:\n      config:\n        - 123: oh dear\n`)\n\tassert.ErrorContains(t, err, \"Non-string key in networks.default.ipam.config[0]: 123\")\n\n\t_, err = loadYAML(`\nservices:\n  dict-env:\n    image: busybox\n    environment:\n      1: FOO\n`)\n\tassert.ErrorContains(t, err, \"Non-string key in services.dict-env.environment: 1\")\n}\n\nfunc TestV1Unsupported(t *testing.T) {\n\t_, err := loadYAML(`\nfoo:\n  image: busybox\n`)\n\tassert.Check(t, err != nil)\n}\n\nfunc TestNonMappingObject(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  - foo:\n      image: busybox\n`)\n\tassert.ErrorContains(t, err, \"services must be a mapping\")\n\n\t_, err = loadYAML(`\nservices:\n  foo: busybox\n`)\n\tassert.ErrorContains(t, err, \"services.foo must be a mapping\")\n\n\t_, err = loadYAML(`\nnetworks:\n  - default:\n      driver: bridge\n`)\n\tassert.ErrorContains(t, err, \"networks must be a mapping\")\n\n\t_, err = loadYAML(`\nnetworks:\n  default: bridge\n`)\n\tassert.ErrorContains(t, err, \"networks.default must be a mapping\")\n\n\t_, err = loadYAML(`\nvolumes:\n  - data:\n      driver: local\n`)\n\tassert.ErrorContains(t, err, \"volumes must be a mapping\")\n\n\t_, err = loadYAML(`\nvolumes:\n  data: local\n`)\n\tassert.ErrorContains(t, err, \"volumes.data must be a mapping\")\n}\n\nfunc TestNonStringImage(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  foo:\n    image: [\"busybox\", \"latest\"]\n`)\n\tassert.ErrorContains(t, err, \"services.foo.image must be a string\")\n}\n\nfunc TestLoadWithEnvironment(t *testing.T) {\n\tconfig, err := loadYAMLWithEnv(`\nservices:\n  dict-env:\n    image: busybox\n    environment:\n      FOO: \"1\"\n      BAR: 2\n      GA: 2.5\n      BU: \"\"\n      ZO:\n      MEU:\n  list-env:\n    image: busybox\n    environment:\n      - FOO=1\n      - BAR=2\n      - GA=2.5\n      - BU=\n      - ZO\n      - MEU\n`, map[string]string{\"MEU\": \"Shadoks\"})\n\tassert.NilError(t, err)\n\n\texpected := types.MappingWithEquals{\n\t\t\"FOO\": strPtr(\"1\"),\n\t\t\"BAR\": strPtr(\"2\"),\n\t\t\"GA\":  strPtr(\"2.5\"),\n\t\t\"BU\":  strPtr(\"\"),\n\t\t\"ZO\":  nil,\n\t\t\"MEU\": strPtr(\"Shadoks\"),\n\t}\n\n\tassert.Check(t, is.Equal(2, len(config.Services)))\n\n\tfor _, service := range config.Services {\n\t\tassert.Check(t, is.DeepEqual(expected, service.Environment))\n\t}\n}\n\nfunc TestLoadEnvironmentWithBoolean(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  dict-env:\n    image: busybox\n    environment:\n      FOO: true\n      BAR: false\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.MappingWithEquals{\n\t\t\"FOO\": strPtr(\"true\"),\n\t\t\"BAR\": strPtr(\"false\"),\n\t}\n\n\tassert.Check(t, is.Equal(1, len(config.Services)))\n\n\tfor _, service := range config.Services {\n\t\tassert.Check(t, is.DeepEqual(expected, service.Environment))\n\t}\n}\n\nfunc TestInvalidEnvironmentValue(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  dict-env:\n    image: busybox\n    environment:\n      FOO: [\"1\"]\n`)\n\tassert.ErrorContains(t, err, \"services.dict-env.environment.FOO must be a string, number, boolean or null\")\n}\n\nfunc TestInvalidEnvironmentObject(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  dict-env:\n    image: busybox\n    environment: \"FOO=1\"\n`)\n\tassert.ErrorContains(t, err, \"services.dict-env.environment must be a mapping\")\n}\n\nfunc TestLoadWithEnvironmentInterpolation(t *testing.T) {\n\thome := \"/home/foo\"\n\tconfig, err := loadYAMLWithEnv(`\n# This is a comment, so using variable syntax here ${SHOULD_NOT_BREAK} parsing\nservices:\n  test:\n    image: busybox\n    labels:\n      - home1=$HOME\n      - home2=${HOME}\n      - nonexistent=$NONEXISTENT\n      - default=${NONEXISTENT-default}\nnetworks:\n  test:\n    driver: $HOME\nvolumes:\n  test:\n    driver: $HOME\n`, map[string]string{\n\t\t\"HOME\": home,\n\t\t\"FOO\":  \"foo\",\n\t})\n\n\tassert.NilError(t, err)\n\n\texpectedLabels := types.Labels{\n\t\t\"home1\":       home,\n\t\t\"home2\":       home,\n\t\t\"nonexistent\": \"\",\n\t\t\"default\":     \"default\",\n\t}\n\n\tassert.Check(t, is.DeepEqual(expectedLabels, config.Services[0].Labels))\n\tassert.Check(t, is.Equal(home, config.Networks[\"test\"].Driver))\n\tassert.Check(t, is.Equal(home, config.Volumes[\"test\"].Driver))\n}\n\nfunc TestLoadWithInterpolationCastFull(t *testing.T) {\n\tdict := `\nservices:\n  web:\n    configs:\n      - source: appconfig\n        mode: $theint\n    secrets:\n      - source: super\n        mode: $theint\n    healthcheck:\n      retries: ${theint}\n      disable: $thebool\n    deploy:\n      replicas: $theint\n      update_config:\n        parallelism: $theint\n        max_failure_ratio: $thefloat\n      rollback_config:\n        parallelism: $theint\n        max_failure_ratio: $thefloat\n      restart_policy:\n        max_attempts: $theint\n      placement:\n        max_replicas_per_node: $theint\n    ports:\n      - $theint\n      - \"34567\"\n      - target: $theint\n        published: $theint\n        x-foo-bar: true\n    ulimits:\n      nproc: $theint\n      nofile:\n        hard: $theint\n        soft: $theint\n    privileged: $thebool\n    read_only: $thebool\n    shm_size: 2gb\n    stdin_open: ${thebool}\n    tty: $thebool\n    volumes:\n      - source: data\n        type: volume\n        read_only: $thebool\n        volume:\n          nocopy: $thebool\n\nconfigs:\n  appconfig:\n    external: $thebool\nsecrets:\n  super:\n    external: $thebool\nvolumes:\n  data:\n    external: $thebool\nnetworks:\n  front:\n    external: $thebool\n    internal: $thebool\n    attachable: $thebool\n  back:\n`\n\tenv := map[string]string{\n\t\t\"theint\":   \"555\",\n\t\t\"thefloat\": \"3.14\",\n\t\t\"thebool\":  \"true\",\n\t}\n\n\tconfig, err := Load(buildConfigDetails(dict, env), func(options *Options) {\n\t\toptions.SkipNormalization = true\n\t\toptions.SkipConsistencyCheck = true\n\t})\n\tassert.NilError(t, err)\n\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\texpected := &types.Project{\n\t\tName:        \"\",\n\t\tEnvironment: map[string]string{\"thebool\": \"true\", \"thefloat\": \"3.14\", \"theint\": \"555\"},\n\t\tWorkingDir:  workingDir,\n\t\tServices: []types.ServiceConfig{\n\t\t\t{\n\t\t\t\tName: \"web\",\n\t\t\t\tConfigs: []types.ServiceConfigObjConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSource: \"appconfig\",\n\t\t\t\t\t\tMode:   uint32Ptr(555),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSecrets: []types.ServiceSecretConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSource: \"super\",\n\t\t\t\t\t\tMode:   uint32Ptr(555),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tHealthCheck: &types.HealthCheckConfig{\n\t\t\t\t\tRetries: uint64Ptr(555),\n\t\t\t\t\tDisable: true,\n\t\t\t\t},\n\t\t\t\tDeploy: &types.DeployConfig{\n\t\t\t\t\tReplicas: uint64Ptr(555),\n\t\t\t\t\tUpdateConfig: &types.UpdateConfig{\n\t\t\t\t\t\tParallelism:     uint64Ptr(555),\n\t\t\t\t\t\tMaxFailureRatio: 3.14,\n\t\t\t\t\t},\n\t\t\t\t\tRollbackConfig: &types.UpdateConfig{\n\t\t\t\t\t\tParallelism:     uint64Ptr(555),\n\t\t\t\t\t\tMaxFailureRatio: 3.14,\n\t\t\t\t\t},\n\t\t\t\t\tRestartPolicy: &types.RestartPolicy{\n\t\t\t\t\t\tMaxAttempts: uint64Ptr(555),\n\t\t\t\t\t},\n\t\t\t\t\tPlacement: types.Placement{\n\t\t\t\t\t\tMaxReplicas: 555,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPorts: []types.ServicePortConfig{\n\t\t\t\t\t{Target: 555, Mode: \"ingress\", Protocol: \"tcp\"},\n\t\t\t\t\t{Target: 34567, Mode: \"ingress\", Protocol: \"tcp\"},\n\t\t\t\t\t{Target: 555, Published: 555, Extensions: map[string]interface{}{\"x-foo-bar\": true}},\n\t\t\t\t},\n\t\t\t\tUlimits: map[string]*types.UlimitsConfig{\n\t\t\t\t\t\"nproc\":  {Single: 555},\n\t\t\t\t\t\"nofile\": {Hard: 555, Soft: 555},\n\t\t\t\t},\n\t\t\t\tPrivileged: true,\n\t\t\t\tReadOnly:   true,\n\t\t\t\tScale:      1,\n\t\t\t\tShmSize:    types.UnitBytes(2 * 1024 * 1024 * 1024),\n\t\t\t\tStdinOpen:  true,\n\t\t\t\tTty:        true,\n\t\t\t\tVolumes: []types.ServiceVolumeConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSource:   \"data\",\n\t\t\t\t\t\tType:     \"volume\",\n\t\t\t\t\t\tReadOnly: true,\n\t\t\t\t\t\tVolume:   &types.ServiceVolumeVolume{NoCopy: true},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t},\n\t\t},\n\t\tConfigs: map[string]types.ConfigObjConfig{\n\t\t\t\"appconfig\": {External: types.External{External: true}, Name: \"appconfig\"},\n\t\t},\n\t\tSecrets: map[string]types.SecretConfig{\n\t\t\t\"super\": {External: types.External{External: true}, Name: \"super\"},\n\t\t},\n\t\tVolumes: map[string]types.VolumeConfig{\n\t\t\t\"data\": {External: types.External{External: true}, Name: \"data\"},\n\t\t},\n\t\tNetworks: map[string]types.NetworkConfig{\n\t\t\t\"back\": {},\n\t\t\t\"front\": {\n\t\t\t\tExternal:   types.External{External: true},\n\t\t\t\tName:       \"front\",\n\t\t\t\tInternal:   true,\n\t\t\t\tAttachable: true,\n\t\t\t},\n\t\t},\n\t}\n\n\tassert.Check(t, is.DeepEqual(expected, config))\n}\n\nfunc TestUnsupportedProperties(t *testing.T) {\n\tdict := `\nservices:\n  web:\n    image: web\n    build:\n     context: ./web\n    links:\n      - bar\n    pid: host\n  db:\n    image: db\n    build:\n     context: ./db\n`\n\tconfigDetails := buildConfigDetails(dict, nil)\n\n\t_, err := Load(configDetails)\n\tassert.NilError(t, err)\n}\n\nfunc TestDiscardEnvFileOption(t *testing.T) {\n\tdict := `services:\n  web:\n    image: nginx\n    env_file:\n     - example1.env\n     - example2.env\n`\n\texpectedEnvironmentMap := types.MappingWithEquals{\n\t\t\"FOO\": strPtr(\"foo_from_env_file\"),\n\t\t\"BAZ\": strPtr(\"baz_from_env_file\"),\n\t\t\"BAR\": strPtr(\"bar_from_env_file_2\"), // Original value is overwritten by example2.env\n\t\t\"QUX\": strPtr(\"quz_from_env_file_2\"),\n\t}\n\tconfigDetails := buildConfigDetails(dict, nil)\n\n\t// Default behavior keeps the `env_file` entries\n\tconfigWithEnvFiles, err := Load(configDetails)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, configWithEnvFiles.Services[0].EnvFile, types.StringList{\"example1.env\",\n\t\t\"example2.env\"})\n\tassert.DeepEqual(t, configWithEnvFiles.Services[0].Environment, expectedEnvironmentMap)\n\n\t// Custom behavior removes the `env_file` entries\n\tconfigWithoutEnvFiles, err := Load(configDetails, WithDiscardEnvFiles)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, configWithoutEnvFiles.Services[0].EnvFile, types.StringList(nil))\n\tassert.DeepEqual(t, configWithoutEnvFiles.Services[0].Environment, expectedEnvironmentMap)\n}\n\nfunc TestBuildProperties(t *testing.T) {\n\tdict := `\nservices:\n  web:\n    image: web\n    build: .\n    links:\n      - bar\n  db:\n    image: db\n    build:\n     context: ./db\n`\n\tconfigDetails := buildConfigDetails(dict, nil)\n\t_, err := Load(configDetails)\n\tassert.NilError(t, err)\n}\n\nfunc TestDeprecatedProperties(t *testing.T) {\n\tdict := `\nservices:\n  web:\n    image: web\n    container_name: web\n  db:\n    image: db\n    container_name: db\n    expose: [\"5434\"]\n`\n\tconfigDetails := buildConfigDetails(dict, nil)\n\n\t_, err := Load(configDetails)\n\tassert.NilError(t, err)\n}\n\nfunc TestInvalidResource(t *testing.T) {\n\t_, err := loadYAML(`\n        services:\n          foo:\n            image: busybox\n            deploy:\n              resources:\n                impossible:\n                  x: 1\n`)\n\tassert.ErrorContains(t, err, \"Additional property impossible is not allowed\")\n}\n\nfunc TestInvalidExternalAndDriverCombination(t *testing.T) {\n\t_, err := loadYAML(`\nvolumes:\n  external_volume:\n    external: true\n    driver: foobar\n`)\n\n\tassert.ErrorContains(t, err, \"conflicting parameters \\\"external\\\" and \\\"driver\\\" specified for volume\")\n\tassert.ErrorContains(t, err, \"external_volume\")\n}\n\nfunc TestInvalidExternalAndDirverOptsCombination(t *testing.T) {\n\t_, err := loadYAML(`\nvolumes:\n  external_volume:\n    external: true\n    driver_opts:\n      beep: boop\n`)\n\n\tassert.ErrorContains(t, err, \"conflicting parameters \\\"external\\\" and \\\"driver_opts\\\" specified for volume\")\n\tassert.ErrorContains(t, err, \"external_volume\")\n}\n\nfunc TestInvalidExternalAndLabelsCombination(t *testing.T) {\n\t_, err := loadYAML(`\nvolumes:\n  external_volume:\n    external: true\n    labels:\n      - beep=boop\n`)\n\n\tassert.ErrorContains(t, err, \"conflicting parameters \\\"external\\\" and \\\"labels\\\" specified for volume\")\n\tassert.ErrorContains(t, err, \"external_volume\")\n}\n\nfunc TestLoadVolumeInvalidExternalNameAndNameCombination(t *testing.T) {\n\t_, err := loadYAML(`\nvolumes:\n  external_volume:\n    name: user_specified_name\n    external:\n      name: external_name\n`)\n\n\tassert.ErrorContains(t, err, \"volume.external.name and volume.name conflict; only use volume.name\")\n\tassert.ErrorContains(t, err, \"external_volume\")\n}\n\nfunc TestInterpolateInt(t *testing.T) {\n\tproject, err := loadYAMLWithEnv(`\nservices:\n  foo:\n    image: foo\n    scale: ${FOO_SCALE}\n`, map[string]string{\"FOO_SCALE\": \"2\"})\n\n\tassert.NilError(t, err)\n\tassert.Equal(t, project.Services[0].Scale, 2)\n}\n\nfunc durationPtr(value time.Duration) *types.Duration {\n\tresult := types.Duration(value)\n\treturn &result\n}\n\nfunc uint64Ptr(value uint64) *uint64 {\n\treturn &value\n}\n\nfunc uint32Ptr(value uint32) *uint32 {\n\treturn &value\n}\n\nfunc TestFullExample(t *testing.T) {\n\tbytes, err := ioutil.ReadFile(\"full-example.yml\")\n\tassert.NilError(t, err)\n\n\thomeDir, err := os.UserHomeDir()\n\tassert.NilError(t, err)\n\tenv := map[string]string{\"HOME\": homeDir, \"QUX\": \"qux_from_environment\"}\n\tconfig, err := loadYAMLWithEnv(string(bytes), env)\n\tassert.NilError(t, err)\n\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\n\texpectedConfig := fullExampleConfig(workingDir, homeDir)\n\n\tassert.Check(t, is.DeepEqual(expectedConfig.Services, config.Services))\n\tassert.Check(t, is.DeepEqual(expectedConfig.Networks, config.Networks))\n\tassert.Check(t, is.DeepEqual(expectedConfig.Volumes, config.Volumes))\n\tassert.Check(t, is.DeepEqual(expectedConfig.Secrets, config.Secrets))\n\tassert.Check(t, is.DeepEqual(expectedConfig.Configs, config.Configs))\n\tassert.Check(t, is.DeepEqual(expectedConfig.Extensions, config.Extensions))\n}\n\nfunc TestLoadTmpfsVolume(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  tmpfs:\n    image: nginx:latest\n    volumes:\n      - type: tmpfs\n        target: /app\n        tmpfs:\n          size: 10000\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.ServiceVolumeConfig{\n\t\tTarget: \"/app\",\n\t\tType:   \"tmpfs\",\n\t\tTmpfs: &types.ServiceVolumeTmpfs{\n\t\t\tSize: int64(10000),\n\t\t},\n\t}\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.Len(config.Services[0].Volumes, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].Volumes[0]))\n}\n\nfunc TestLoadTmpfsVolumeAdditionalPropertyNotAllowed(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  tmpfs:\n    image: nginx:latest\n    volumes:\n      - type: tmpfs\n        target: /app\n        foo:\n          bar: zot\n`)\n\tassert.ErrorContains(t, err, \"services.tmpfs.volumes.0 Additional property foo is not allowed\")\n}\n\nfunc TestLoadBindMountSourceMustNotBeEmpty(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  tmpfs:\n    image: nginx:latest\n    volumes:\n      - type: bind\n        target: /app\n`)\n\tassert.Error(t, err, `invalid mount config for type \"bind\": field Source must not be empty`)\n}\n\nfunc TestLoadBindMountSourceIsWindowsAbsolute(t *testing.T) {\n\ttests := []struct {\n\t\tdoc      string\n\t\tyaml     string\n\t\texpected types.ServiceVolumeConfig\n\t}{\n\t\t{\n\t\t\tdoc: \"Z-drive lowercase\",\n\t\t\tyaml: `\nservices:\n  windows:\n    image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019\n    volumes:\n      - type: bind\n        source: z:\\\n        target: c:\\data\n`,\n\t\t\texpected: types.ServiceVolumeConfig{Type: \"bind\", Source: `z:\\`, Target: `c:\\data`},\n\t\t},\n\t\t{\n\t\t\tdoc: \"Z-drive uppercase\",\n\t\t\tyaml: `\nservices:\n  windows:\n    image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019\n    volumes:\n      - type: bind\n        source: Z:\\\n        target: C:\\data\n`,\n\t\t\texpected: types.ServiceVolumeConfig{Type: \"bind\", Source: `Z:\\`, Target: `C:\\data`},\n\t\t},\n\t\t{\n\t\t\tdoc: \"Z-drive subdirectory\",\n\t\t\tyaml: `\nservices:\n  windows:\n    image: mcr.microsoft.com/windows/servercore/iis:windowsservercore-ltsc2019\n    volumes:\n      - type: bind\n        source: Z:\\some-dir\n        target: C:\\data\n`,\n\t\t\texpected: types.ServiceVolumeConfig{Type: \"bind\", Source: `Z:\\some-dir`, Target: `C:\\data`},\n\t\t},\n\t\t{\n\t\t\tdoc: \"forward-slashes\",\n\t\t\tyaml: `\nservices:\n  app:\n    image: app:latest\n    volumes:\n      - type: bind\n        source: /z/some-dir\n        target: /c/data\n`,\n\t\t\texpected: types.ServiceVolumeConfig{Type: \"bind\", Source: `/z/some-dir`, Target: `/c/data`},\n\t\t},\n\t}\n\n\tfor _, tc := range tests {\n\t\tt.Run(tc.doc, func(t *testing.T) {\n\t\t\tconfig, err := loadYAML(tc.yaml)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.Check(t, is.Len(config.Services[0].Volumes, 1))\n\t\t\tassert.Check(t, is.DeepEqual(tc.expected, config.Services[0].Volumes[0]))\n\t\t})\n\t}\n}\n\nfunc TestLoadBindMountWithSource(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  bind:\n    image: nginx:latest\n    volumes:\n      - type: bind\n        target: /app\n        source: \".\"\n`)\n\tassert.NilError(t, err)\n\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\n\texpected := types.ServiceVolumeConfig{\n\t\tType:   \"bind\",\n\t\tSource: workingDir,\n\t\tTarget: \"/app\",\n\t}\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.Len(config.Services[0].Volumes, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].Volumes[0]))\n}\n\nfunc TestLoadTmpfsVolumeSizeCanBeZero(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  tmpfs:\n    image: nginx:latest\n    volumes:\n      - type: tmpfs\n        target: /app\n        tmpfs:\n          size: 0\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.ServiceVolumeConfig{\n\t\tTarget: \"/app\",\n\t\tType:   \"tmpfs\",\n\t\tTmpfs:  &types.ServiceVolumeTmpfs{},\n\t}\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.Len(config.Services[0].Volumes, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].Volumes[0]))\n}\n\nfunc TestLoadTmpfsVolumeSizeMustBeGTEQZero(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  tmpfs:\n    image: nginx:latest\n    volumes:\n      - type: tmpfs\n        target: /app\n        tmpfs:\n          size: -1\n`)\n\tassert.ErrorContains(t, err, \"services.tmpfs.volumes.0.tmpfs.size Must be greater than or equal to 0\")\n}\n\nfunc TestLoadTmpfsVolumeSizeMustBeInteger(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  tmpfs:\n    image: nginx:latest\n    volumes:\n      - type: tmpfs\n        target: /app\n        tmpfs:\n          size: 0.0001\n`)\n\tassert.ErrorContains(t, err, \"services.tmpfs.volumes.0.tmpfs.size must be a integer\")\n}\n\nfunc serviceSort(services []types.ServiceConfig) []types.ServiceConfig {\n\tsort.Slice(services, func(i, j int) bool {\n\t\treturn services[i].Name < services[j].Name\n\t})\n\treturn services\n}\n\nfunc TestLoadAttachableNetwork(t *testing.T) {\n\tconfig, err := loadYAML(`\nnetworks:\n  mynet1:\n    driver: overlay\n    attachable: true\n  mynet2:\n    driver: bridge\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.Networks{\n\t\t\"mynet1\": {\n\t\t\tDriver:     \"overlay\",\n\t\t\tAttachable: true,\n\t\t},\n\t\t\"mynet2\": {\n\t\t\tDriver:     \"bridge\",\n\t\t\tAttachable: false,\n\t\t},\n\t}\n\n\tassert.Check(t, is.DeepEqual(expected, config.Networks))\n}\n\nfunc TestLoadExpandedPortFormat(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  web:\n    image: busybox\n    ports:\n      - \"80-82:8080-8082\"\n      - \"90-92:8090-8092/udp\"\n      - \"85:8500\"\n      - 8600\n      - protocol: udp\n        target: 53\n        published: 10053\n      - mode: host\n        target: 22\n        published: 10022\n`)\n\tassert.NilError(t, err)\n\n\tassert.Check(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.DeepEqual(samplePortsConfig, config.Services[0].Ports))\n}\n\nfunc TestLoadExpandedMountFormat(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  web:\n    image: busybox\n    volumes:\n      - type: volume\n        source: foo\n        target: /target\n        read_only: true\nvolumes:\n  foo: {}\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.ServiceVolumeConfig{\n\t\tType:     \"volume\",\n\t\tSource:   \"foo\",\n\t\tTarget:   \"/target\",\n\t\tReadOnly: true,\n\t}\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.Len(config.Services[0].Volumes, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].Volumes[0]))\n}\n\nfunc TestLoadExtraHostsMap(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  web:\n    image: busybox\n    extra_hosts:\n      \"zulu\": \"162.242.195.82\"\n      \"alpha\": \"50.31.209.229\"\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.HostsList{\n\t\t\"alpha:50.31.209.229\",\n\t\t\"zulu:162.242.195.82\",\n\t}\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].ExtraHosts))\n}\n\nfunc TestLoadExtraHostsList(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  web:\n    image: busybox\n    extra_hosts:\n      - \"zulu:162.242.195.82\"\n      - \"alpha:50.31.209.229\"\n      - \"zulu:ff02::1\"\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.HostsList{\n\t\t\"zulu:162.242.195.82\",\n\t\t\"alpha:50.31.209.229\",\n\t\t\"zulu:ff02::1\",\n\t}\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].ExtraHosts))\n}\n\nfunc TestLoadVolumesWarnOnDeprecatedExternalNameVersion34(t *testing.T) {\n\tbuf, cleanup := patchLogrus()\n\tdefer cleanup()\n\n\tsource := map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"external\": map[string]interface{}{\n\t\t\t\t\"name\": \"oops\",\n\t\t\t},\n\t\t},\n\t}\n\tvolumes, err := LoadVolumes(source)\n\tassert.NilError(t, err)\n\texpected := map[string]types.VolumeConfig{\n\t\t\"foo\": {\n\t\t\tName:     \"oops\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t}\n\tassert.Check(t, is.DeepEqual(expected, volumes))\n\tassert.Check(t, is.Contains(buf.String(), \"volume.external.name is deprecated\"))\n\n}\n\nfunc patchLogrus() (*bytes.Buffer, func()) {\n\tbuf := new(bytes.Buffer)\n\tout := logrus.StandardLogger().Out\n\tlogrus.SetOutput(buf)\n\treturn buf, func() { logrus.SetOutput(out) }\n}\n\nfunc TestLoadVolumesWarnOnDeprecatedExternalName(t *testing.T) {\n\tbuf, cleanup := patchLogrus()\n\tdefer cleanup()\n\n\tsource := map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"external\": map[string]interface{}{\n\t\t\t\t\"name\": \"oops\",\n\t\t\t},\n\t\t},\n\t}\n\tvolumes, err := LoadVolumes(source)\n\tassert.NilError(t, err)\n\texpected := map[string]types.VolumeConfig{\n\t\t\"foo\": {\n\t\t\tName:     \"oops\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t}\n\tassert.Check(t, is.DeepEqual(expected, volumes))\n\tassert.Check(t, strings.Contains(buf.String(), \"volume foo: volume.external.name is deprecated in favor of volume.name\"))\n}\n\nfunc TestLoadInvalidIsolation(t *testing.T) {\n\t// validation should be done only on the daemon side\n\tactual, err := loadYAML(`\nservices:\n  foo:\n    image: busybox\n    isolation: invalid\nconfigs:\n  super:\n    external: true\n`)\n\tassert.NilError(t, err)\n\tassert.Assert(t, is.Len(actual.Services, 1))\n\tassert.Check(t, is.Equal(\"invalid\", actual.Services[0].Isolation))\n}\n\nfunc TestLoadSecretInvalidExternalNameAndNameCombination(t *testing.T) {\n\t_, err := loadYAML(`\nsecrets:\n  external_secret:\n    name: user_specified_name\n    external:\n      name: external_name\n`)\n\n\tassert.ErrorContains(t, err, \"secret.external.name and secret.name conflict; only use secret.name\")\n\tassert.ErrorContains(t, err, \"external_secret\")\n}\n\nfunc TestLoadSecretsWarnOnDeprecatedExternalNameVersion35(t *testing.T) {\n\tbuf, cleanup := patchLogrus()\n\tdefer cleanup()\n\n\tsource := map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"external\": map[string]interface{}{\n\t\t\t\t\"name\": \"oops\",\n\t\t\t},\n\t\t},\n\t}\n\tdetails := types.ConfigDetails{}\n\tsecrets, err := LoadSecrets(source, details, true)\n\tassert.NilError(t, err)\n\texpected := map[string]types.SecretConfig{\n\t\t\"foo\": {\n\t\t\tName:     \"oops\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t}\n\tassert.Check(t, is.DeepEqual(expected, secrets))\n\tassert.Check(t, is.Contains(buf.String(), \"secret.external.name is deprecated\"))\n}\n\nfunc TestLoadNetworksWarnOnDeprecatedExternalNameVersion35(t *testing.T) {\n\tbuf, cleanup := patchLogrus()\n\tdefer cleanup()\n\n\tsource := map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"external\": map[string]interface{}{\n\t\t\t\t\"name\": \"oops\",\n\t\t\t},\n\t\t},\n\t}\n\tnetworks, err := LoadNetworks(source)\n\tassert.NilError(t, err)\n\texpected := map[string]types.NetworkConfig{\n\t\t\"foo\": {\n\t\t\tName:     \"oops\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t}\n\tassert.Check(t, is.DeepEqual(expected, networks))\n\tassert.Check(t, is.Contains(buf.String(), \"network.external.name is deprecated\"))\n\n}\n\nfunc TestLoadNetworksWarnOnDeprecatedExternalName(t *testing.T) {\n\tbuf, cleanup := patchLogrus()\n\tdefer cleanup()\n\n\tsource := map[string]interface{}{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"external\": map[string]interface{}{\n\t\t\t\t\"name\": \"oops\",\n\t\t\t},\n\t\t},\n\t}\n\tnetworks, err := LoadNetworks(source)\n\tassert.NilError(t, err)\n\texpected := map[string]types.NetworkConfig{\n\t\t\"foo\": {\n\t\t\tName:     \"oops\",\n\t\t\tExternal: types.External{External: true},\n\t\t},\n\t}\n\tassert.Check(t, is.DeepEqual(expected, networks))\n\tassert.Check(t, strings.Contains(buf.String(), \"network foo: network.external.name is deprecated in favor of network.name\"))\n}\n\nfunc TestLoadNetworkInvalidExternalNameAndNameCombination(t *testing.T) {\n\t_, err := loadYAML(`\nnetworks:\n  foo:\n    name: user_specified_name\n    external:\n      name: external_name\n`)\n\n\tassert.ErrorContains(t, err, \"network.external.name and network.name conflict; only use network.name\")\n\tassert.ErrorContains(t, err, \"foo\")\n}\n\nfunc TestLoadNetworkWithName(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  hello-world:\n    image: redis:alpine\n    networks:\n      - network1\n      - network3\n\nnetworks:\n  network1:\n    name: network2\n  network3:\n`)\n\tassert.NilError(t, err)\n\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\texpected := &types.Project{\n\t\tName:       \"\",\n\t\tWorkingDir: workingDir,\n\t\tServices: types.Services{\n\t\t\t{\n\t\t\t\tName:  \"hello-world\",\n\t\t\t\tImage: \"redis:alpine\",\n\t\t\t\tScale: 1,\n\t\t\t\tNetworks: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\t\"network1\": nil,\n\t\t\t\t\t\"network3\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tNetworks: map[string]types.NetworkConfig{\n\t\t\t\"network1\": {Name: \"network2\"},\n\t\t\t\"network3\": {},\n\t\t},\n\t}\n\tassert.DeepEqual(t, config, expected, cmpopts.EquateEmpty())\n}\n\nfunc TestLoadInit(t *testing.T) {\n\tbooleanTrue := true\n\tbooleanFalse := false\n\n\tvar testcases = []struct {\n\t\tdoc  string\n\t\tyaml string\n\t\tinit *bool\n\t}{\n\t\t{\n\t\t\tdoc: \"no init defined\",\n\t\t\tyaml: `\nservices:\n  foo:\n    image: alpine`,\n\t\t},\n\t\t{\n\t\t\tdoc: \"has true init\",\n\t\t\tyaml: `\nservices:\n  foo:\n    image: alpine\n    init: true`,\n\t\t\tinit: &booleanTrue,\n\t\t},\n\t\t{\n\t\t\tdoc: \"has false init\",\n\t\t\tyaml: `\nservices:\n  foo:\n    image: alpine\n    init: false`,\n\t\t\tinit: &booleanFalse,\n\t\t},\n\t}\n\tfor _, testcase := range testcases {\n\t\ttestcase := testcase\n\t\tt.Run(testcase.doc, func(t *testing.T) {\n\t\t\tconfig, err := loadYAML(testcase.yaml)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.Check(t, is.Len(config.Services, 1))\n\t\t\tassert.Check(t, is.DeepEqual(config.Services[0].Init, testcase.init))\n\t\t})\n\t}\n}\n\nfunc TestLoadSysctls(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  web:\n    image: busybox\n    sysctls:\n      - net.core.somaxconn=1024\n      - net.ipv4.tcp_syncookies=0\n      - testing.one.one=\n      - testing.one.two\n`)\n\tassert.NilError(t, err)\n\n\texpected := types.Mapping{\n\t\t\"net.core.somaxconn\":      \"1024\",\n\t\t\"net.ipv4.tcp_syncookies\": \"0\",\n\t\t\"testing.one.one\":         \"\",\n\t\t\"testing.one.two\":         \"\",\n\t}\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].Sysctls))\n\n\tconfig, err = loadYAML(`\nservices:\n  web:\n    image: busybox\n    sysctls:\n      net.core.somaxconn: 1024\n      net.ipv4.tcp_syncookies: 0\n      testing.one.one: \"\"\n      testing.one.two:\n`)\n\tassert.NilError(t, err)\n\n\tassert.Assert(t, is.Len(config.Services, 1))\n\tassert.Check(t, is.DeepEqual(expected, config.Services[0].Sysctls))\n}\n\nfunc TestTransform(t *testing.T) {\n\tvar source = []interface{}{\n\t\t\"80-82:8080-8082\",\n\t\t\"90-92:8090-8092/udp\",\n\t\t\"85:8500\",\n\t\t8600,\n\t\tmap[string]interface{}{\n\t\t\t\"protocol\":  \"udp\",\n\t\t\t\"target\":    53,\n\t\t\t\"published\": 10053,\n\t\t},\n\t\tmap[string]interface{}{\n\t\t\t\"mode\":      \"host\",\n\t\t\t\"target\":    22,\n\t\t\t\"published\": 10022,\n\t\t},\n\t}\n\tvar ports []types.ServicePortConfig\n\terr := Transform(source, &ports)\n\tassert.NilError(t, err)\n\n\tassert.Check(t, is.DeepEqual(samplePortsConfig, ports))\n}\n\nfunc TestLoadTemplateDriver(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  hello-world:\n    image: redis:alpine\n    secrets:\n      - secret\n    configs:\n      - config\n\nconfigs:\n  config:\n    name: config\n    external: true\n    template_driver: config-driver\n\nsecrets:\n  secret:\n    name: secret\n    external: true\n    template_driver: secret-driver\n`)\n\tassert.NilError(t, err)\n\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\n\texpected := &types.Project{\n\t\tName:       \"\",\n\t\tWorkingDir: workingDir,\n\t\tServices: types.Services{\n\t\t\t{\n\t\t\t\tName:  \"hello-world\",\n\t\t\t\tImage: \"redis:alpine\",\n\t\t\t\tConfigs: []types.ServiceConfigObjConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSource: \"config\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tScale: 1,\n\t\t\t\tSecrets: []types.ServiceSecretConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSource: \"secret\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tConfigs: map[string]types.ConfigObjConfig{\n\t\t\t\"config\": {\n\t\t\t\tName:           \"config\",\n\t\t\t\tExternal:       types.External{External: true},\n\t\t\t\tTemplateDriver: \"config-driver\",\n\t\t\t},\n\t\t},\n\t\tSecrets: map[string]types.SecretConfig{\n\t\t\t\"secret\": {\n\t\t\t\tName:           \"secret\",\n\t\t\t\tExternal:       types.External{External: true},\n\t\t\t\tTemplateDriver: \"secret-driver\",\n\t\t\t},\n\t\t},\n\t}\n\tassert.DeepEqual(t, config, expected, cmpopts.EquateEmpty())\n}\n\nfunc TestLoadSecretDriver(t *testing.T) {\n\tconfig, err := loadYAML(`\nservices:\n  hello-world:\n    image: redis:alpine\n    secrets:\n      - secret\n    configs:\n      - config\n\nconfigs:\n  config:\n    name: config\n    external: true\n\nsecrets:\n  secret:\n    name: secret\n    driver: secret-bucket\n    driver_opts:\n      OptionA: value for driver option A\n      OptionB: value for driver option B\n`)\n\tassert.NilError(t, err)\n\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\n\texpected := &types.Project{\n\t\tName:       \"\",\n\t\tWorkingDir: workingDir,\n\t\tServices: types.Services{\n\t\t\t{\n\t\t\t\tName:  \"hello-world\",\n\t\t\t\tImage: \"redis:alpine\",\n\t\t\t\tConfigs: []types.ServiceConfigObjConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSource: \"config\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tScale: 1,\n\t\t\t\tSecrets: []types.ServiceSecretConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tSource: \"secret\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tConfigs: map[string]types.ConfigObjConfig{\n\t\t\t\"config\": {\n\t\t\t\tName:     \"config\",\n\t\t\t\tExternal: types.External{External: true},\n\t\t\t},\n\t\t},\n\t\tSecrets: map[string]types.SecretConfig{\n\t\t\t\"secret\": {\n\t\t\t\tName:   \"secret\",\n\t\t\t\tDriver: \"secret-bucket\",\n\t\t\t\tDriverOpts: map[string]string{\n\t\t\t\t\t\"OptionA\": \"value for driver option A\",\n\t\t\t\t\t\"OptionB\": \"value for driver option B\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tassert.DeepEqual(t, config, expected, cmpopts.EquateEmpty())\n}\n\nfunc TestComposeFileWithVersion(t *testing.T) {\n\tbytes, err := ioutil.ReadFile(\"testdata/compose-test-with-version.yaml\")\n\tassert.NilError(t, err)\n\n\thomeDir, err := os.UserHomeDir()\n\tassert.NilError(t, err)\n\tenv := map[string]string{\"HOME\": homeDir, \"QUX\": \"qux_from_environment\"}\n\tconfig, err := loadYAMLWithEnv(string(bytes), env)\n\tassert.NilError(t, err)\n\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\n\texpectedConfig := withVersionExampleConfig(workingDir, homeDir)\n\n\tsort.Slice(config.Services, func(i, j int) bool {\n\t\treturn config.Services[i].Name > config.Services[j].Name\n\t})\n\tassert.Check(t, is.DeepEqual(expectedConfig.Services, config.Services))\n\tassert.Check(t, is.DeepEqual(expectedConfig.Networks, config.Networks))\n\tassert.Check(t, is.DeepEqual(expectedConfig.Volumes, config.Volumes))\n}\n\nfunc TestLoadWithExtends(t *testing.T) {\n\tbytes, err := ioutil.ReadFile(\"testdata/compose-test-extends.yaml\")\n\tassert.NilError(t, err)\n\n\tconfigDetails := types.ConfigDetails{\n\t\tWorkingDir: \"testdata\",\n\t\tConfigFiles: []types.ConfigFile{\n\t\t\t{Filename: \"testdata/compose-test-extends.yaml\", Content: bytes},\n\t\t},\n\t}\n\n\tactual, err := Load(configDetails)\n\tassert.NilError(t, err)\n\n\texpServices := types.Services{\n\t\t{\n\t\t\tName:  \"importer\",\n\t\t\tImage: \"nginx\",\n\t\t\tExtends: types.ExtendsConfig{\n\t\t\t\t\"file\":    strPtr(\"compose-test-extends-imported.yaml\"),\n\t\t\t\t\"service\": strPtr(\"imported\"),\n\t\t\t},\n\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\tNetworks:    map[string]*types.ServiceNetworkConfig{\"default\": nil},\n\t\t\tScale:       1,\n\t\t},\n\t}\n\tassert.Check(t, is.DeepEqual(expServices, actual.Services))\n}\n\nfunc TestServiceDeviceRequestCount(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  hello-world:\n    image: redis:alpine\n    deploy:\n      resources:\n        reservations:\n          devices:\n            - driver: nvidia\n              capabilities: [gpu]\n              count: all\n`)\n\tassert.NilError(t, err)\n}\n\nfunc TestServiceDeviceRequestCountType(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  hello-world:\n    image: redis:alpine\n    deploy:\n      resources:\n        reservations:\n          devices:\n            - driver: nvidia\n              capabilities: [gpu]\n              count: somestring\n`)\n\tassert.ErrorContains(t, err, \"invalid string value for 'count' (the only value allowed is 'all')\")\n}\n\nfunc TestServicePullPolicy(t *testing.T) {\n\tactual, err := loadYAML(`\nservices:\n  hello-world:\n    image: redis:alpine\n    pull_policy: always\n`)\n\tassert.NilError(t, err)\n\tsvc, err := actual.GetService(\"hello-world\")\n\tassert.NilError(t, err)\n\tassert.Equal(t, \"always\", svc.PullPolicy)\n}\n\nfunc TestEmptyList(t *testing.T) {\n\t_, err := loadYAML(`\nservices:\n  test:\n    image: nginx:latest\n    ports: []\n`)\n\tassert.NilError(t, err)\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/merge.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"reflect\"\n\t\"sort\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/imdario/mergo\"\n\t\"github.com/pkg/errors\"\n)\n\ntype specials struct {\n\tm map[reflect.Type]func(dst, src reflect.Value) error\n}\n\nvar serviceSpecials = &specials{\n\tm: map[reflect.Type]func(dst, src reflect.Value) error{\n\t\treflect.TypeOf(&types.LoggingConfig{}):           safelyMerge(mergeLoggingConfig),\n\t\treflect.TypeOf(&types.UlimitsConfig{}):           safelyMerge(mergeUlimitsConfig),\n\t\treflect.TypeOf([]types.ServiceVolumeConfig{}):    mergeSlice(toServiceVolumeConfigsMap, toServiceVolumeConfigsSlice),\n\t\treflect.TypeOf([]types.ServicePortConfig{}):      mergeSlice(toServicePortConfigsMap, toServicePortConfigsSlice),\n\t\treflect.TypeOf([]types.ServiceSecretConfig{}):    mergeSlice(toServiceSecretConfigsMap, toServiceSecretConfigsSlice),\n\t\treflect.TypeOf([]types.ServiceConfigObjConfig{}): mergeSlice(toServiceConfigObjConfigsMap, toSServiceConfigObjConfigsSlice),\n\t\treflect.TypeOf(&types.UlimitsConfig{}):           mergeUlimitsConfig,\n\t\treflect.TypeOf(&types.ServiceNetworkConfig{}):    mergeServiceNetworkConfig,\n\t},\n}\n\nfunc (s *specials) Transformer(t reflect.Type) func(dst, src reflect.Value) error {\n\tif fn, ok := s.m[t]; ok {\n\t\treturn fn\n\t}\n\treturn nil\n}\n\nfunc merge(configs []*types.Config) (*types.Config, error) {\n\tbase := configs[0]\n\tfor _, override := range configs[1:] {\n\t\tvar err error\n\t\tbase.Services, err = mergeServices(base.Services, override.Services)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge services from %s\", override.Filename)\n\t\t}\n\t\tbase.Volumes, err = mergeVolumes(base.Volumes, override.Volumes)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge volumes from %s\", override.Filename)\n\t\t}\n\t\tbase.Networks, err = mergeNetworks(base.Networks, override.Networks)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge networks from %s\", override.Filename)\n\t\t}\n\t\tbase.Secrets, err = mergeSecrets(base.Secrets, override.Secrets)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge secrets from %s\", override.Filename)\n\t\t}\n\t\tbase.Configs, err = mergeConfigs(base.Configs, override.Configs)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge configs from %s\", override.Filename)\n\t\t}\n\t\tbase.Extensions, err = mergeExtensions(base.Extensions, override.Extensions)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge extensions from %s\", override.Filename)\n\t\t}\n\t}\n\treturn base, nil\n}\n\nfunc mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig, error) {\n\tbaseServices := mapByName(base)\n\toverrideServices := mapByName(override)\n\tfor name, overrideService := range overrideServices {\n\t\toverrideService := overrideService\n\t\tif baseService, ok := baseServices[name]; ok {\n\t\t\tmerged, err := _merge(&baseService, &overrideService)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrapf(err, \"cannot merge service %s\", name)\n\t\t\t}\n\t\t\tbaseServices[name] = *merged\n\t\t\tcontinue\n\t\t}\n\t\tbaseServices[name] = overrideService\n\t}\n\tservices := []types.ServiceConfig{}\n\tfor _, baseService := range baseServices {\n\t\tservices = append(services, baseService)\n\t}\n\tsort.Slice(services, func(i, j int) bool { return services[i].Name < services[j].Name })\n\treturn services, nil\n}\n\nfunc _merge(baseService *types.ServiceConfig, overrideService *types.ServiceConfig) (*types.ServiceConfig, error) {\n\tif err := mergo.Merge(baseService, overrideService, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithTransformers(serviceSpecials)); err != nil {\n\t\treturn nil, err\n\t}\n\tif overrideService.Command != nil {\n\t\tbaseService.Command = overrideService.Command\n\t}\n\tif overrideService.Entrypoint != nil {\n\t\tbaseService.Entrypoint = overrideService.Entrypoint\n\t}\n\treturn baseService, nil\n}\n\nfunc toServiceSecretConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tsecrets, ok := s.([]types.ServiceSecretConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a serviceSecretConfig: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\tfor _, secret := range secrets {\n\t\tm[secret.Source] = secret\n\t}\n\treturn m, nil\n}\n\nfunc toServiceConfigObjConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tsecrets, ok := s.([]types.ServiceConfigObjConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a serviceSecretConfig: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\tfor _, secret := range secrets {\n\t\tm[secret.Source] = secret\n\t}\n\treturn m, nil\n}\n\nfunc toServicePortConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tports, ok := s.([]types.ServicePortConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a servicePortConfig slice: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\ttype port struct {\n\t\ttarget    uint32\n\t\tpublished uint32\n\t\tip        string\n\t\tprotocol  string\n\t}\n\n\tfor _, p := range ports {\n\t\tmergeKey := port{\n\t\t\ttarget:    p.Target,\n\t\t\tpublished: p.Published,\n\t\t\tip:        p.HostIP,\n\t\t\tprotocol:  p.Protocol,\n\t\t}\n\t\tm[mergeKey] = p\n\t}\n\treturn m, nil\n}\n\nfunc toServiceVolumeConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tvolumes, ok := s.([]types.ServiceVolumeConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a ServiceVolumeConfig slice: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\tfor _, v := range volumes {\n\t\tm[v.Target] = v\n\t}\n\treturn m, nil\n}\n\nfunc toServiceSecretConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServiceSecretConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServiceSecretConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool { return s[i].Source < s[j].Source })\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\nfunc toSServiceConfigObjConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServiceConfigObjConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServiceConfigObjConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool { return s[i].Source < s[j].Source })\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\nfunc toServicePortConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServicePortConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServicePortConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool {\n\t\tif s[i].Target != s[j].Target {\n\t\t\treturn s[i].Target < s[j].Target\n\t\t}\n\t\tif s[i].Published != s[j].Published {\n\t\t\treturn s[i].Published < s[j].Published\n\t\t}\n\t\tif s[i].HostIP != s[j].HostIP {\n\t\t\treturn s[i].HostIP < s[j].HostIP\n\t\t}\n\t\treturn s[i].Protocol < s[j].Protocol\n\t})\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\nfunc toServiceVolumeConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServiceVolumeConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServiceVolumeConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool { return s[i].Target < s[j].Target })\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\ntype tomapFn func(s interface{}) (map[interface{}]interface{}, error)\ntype writeValueFromMapFn func(reflect.Value, map[interface{}]interface{}) error\n\nfunc safelyMerge(mergeFn func(dst, src reflect.Value) error) func(dst, src reflect.Value) error {\n\treturn func(dst, src reflect.Value) error {\n\t\tif src.IsNil() {\n\t\t\treturn nil\n\t\t}\n\t\tif dst.IsNil() {\n\t\t\tdst.Set(src)\n\t\t\treturn nil\n\t\t}\n\t\treturn mergeFn(dst, src)\n\t}\n}\n\nfunc mergeSlice(tomap tomapFn, writeValue writeValueFromMapFn) func(dst, src reflect.Value) error {\n\treturn func(dst, src reflect.Value) error {\n\t\tdstMap, err := sliceToMap(tomap, dst)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsrcMap, err := sliceToMap(tomap, src)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := mergo.Map(&dstMap, srcMap, mergo.WithOverride); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn writeValue(dst, dstMap)\n\t}\n}\n\nfunc sliceToMap(tomap tomapFn, v reflect.Value) (map[interface{}]interface{}, error) {\n\t// check if valid\n\tif !v.IsValid() {\n\t\treturn nil, errors.Errorf(\"invalid value : %+v\", v)\n\t}\n\treturn tomap(v.Interface())\n}\n\nfunc mergeLoggingConfig(dst, src reflect.Value) error {\n\t// Same driver, merging options\n\tif getLoggingDriver(dst.Elem()) == getLoggingDriver(src.Elem()) ||\n\t\tgetLoggingDriver(dst.Elem()) == \"\" || getLoggingDriver(src.Elem()) == \"\" {\n\t\tif getLoggingDriver(dst.Elem()) == \"\" {\n\t\t\tdst.Elem().FieldByName(\"Driver\").SetString(getLoggingDriver(src.Elem()))\n\t\t}\n\t\tdstOptions := dst.Elem().FieldByName(\"Options\").Interface().(map[string]string)\n\t\tsrcOptions := src.Elem().FieldByName(\"Options\").Interface().(map[string]string)\n\t\treturn mergo.Merge(&dstOptions, srcOptions, mergo.WithOverride)\n\t}\n\t// Different driver, override with src\n\tdst.Set(src)\n\treturn nil\n}\n\n// nolint: unparam\nfunc mergeUlimitsConfig(dst, src reflect.Value) error {\n\tif src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {\n\t\tdst.Elem().Set(src.Elem())\n\t}\n\treturn nil\n}\n\n// nolint: unparam\nfunc mergeServiceNetworkConfig(dst, src reflect.Value) error {\n\tif src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {\n\t\tdst.Elem().FieldByName(\"Aliases\").Set(src.Elem().FieldByName(\"Aliases\"))\n\t\tif ipv4 := src.Elem().FieldByName(\"Ipv4Address\").Interface().(string); ipv4 != \"\" {\n\t\t\tdst.Elem().FieldByName(\"Ipv4Address\").SetString(ipv4)\n\t\t}\n\t\tif ipv6 := src.Elem().FieldByName(\"Ipv6Address\").Interface().(string); ipv6 != \"\" {\n\t\t\tdst.Elem().FieldByName(\"Ipv6Address\").SetString(ipv6)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc getLoggingDriver(v reflect.Value) string {\n\treturn v.FieldByName(\"Driver\").String()\n}\n\nfunc mapByName(services []types.ServiceConfig) map[string]types.ServiceConfig {\n\tm := map[string]types.ServiceConfig{}\n\tfor _, service := range services {\n\t\tm[service.Name] = service\n\t}\n\treturn m\n}\n\nfunc mergeVolumes(base, override map[string]types.VolumeConfig) (map[string]types.VolumeConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeNetworks(base, override map[string]types.NetworkConfig) (map[string]types.NetworkConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeSecrets(base, override map[string]types.SecretConfig) (map[string]types.SecretConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeConfigs(base, override map[string]types.ConfigObjConfig) (map[string]types.ConfigObjConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeExtensions(base, override map[string]interface{}) (map[string]interface{}, error) {\n\tif base == nil {\n\t\tbase = map[string]interface{}{}\n\t}\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/merge_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/imdario/mergo\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"gotest.tools/v3/assert\"\n)\n\nfunc TestLoadLogging(t *testing.T) {\n\tloggingCases := []struct {\n\t\tname            string\n\t\tloggingBase     map[string]interface{}\n\t\tloggingOverride map[string]interface{}\n\t\texpected        *types.LoggingConfig\n\t}{\n\t\t{\n\t\t\tname: \"no_override_driver\",\n\t\t\tloggingBase: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"json-file\",\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"frequency\": \"2000\",\n\t\t\t\t\t\t\"timeout\":   \"23\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tloggingOverride: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: &types.LoggingConfig{\n\t\t\t\tDriver: \"json-file\",\n\t\t\t\tOptions: map[string]string{\n\t\t\t\t\t\"frequency\":    \"2000\",\n\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_driver\",\n\t\t\tloggingBase: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"json-file\",\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"frequency\": \"2000\",\n\t\t\t\t\t\t\"timeout\":   \"23\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tloggingOverride: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"syslog\",\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: &types.LoggingConfig{\n\t\t\t\tDriver: \"syslog\",\n\t\t\t\tOptions: map[string]string{\n\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"no_base_driver\",\n\t\t\tloggingBase: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"frequency\": \"2000\",\n\t\t\t\t\t\t\"timeout\":   \"23\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tloggingOverride: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"json-file\",\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: &types.LoggingConfig{\n\t\t\t\tDriver: \"json-file\",\n\t\t\t\tOptions: map[string]string{\n\t\t\t\t\t\"frequency\":    \"2000\",\n\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"no_driver\",\n\t\t\tloggingBase: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"frequency\": \"2000\",\n\t\t\t\t\t\t\"timeout\":   \"23\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tloggingOverride: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: &types.LoggingConfig{\n\t\t\t\tOptions: map[string]string{\n\t\t\t\t\t\"frequency\":    \"2000\",\n\t\t\t\t\t\"timeout\":      \"360\",\n\t\t\t\t\t\"pretty-print\": \"on\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"no_override_options\",\n\t\t\tloggingBase: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"json-file\",\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"frequency\": \"2000\",\n\t\t\t\t\t\t\"timeout\":   \"23\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tloggingOverride: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"syslog\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: &types.LoggingConfig{\n\t\t\t\tDriver: \"syslog\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:        \"no_base\",\n\t\t\tloggingBase: map[string]interface{}{},\n\t\t\tloggingOverride: map[string]interface{}{\n\t\t\t\t\"logging\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"json-file\",\n\t\t\t\t\t\"options\": map[string]interface{}{\n\t\t\t\t\t\t\"frequency\": \"2000\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: &types.LoggingConfig{\n\t\t\t\tDriver: \"json-file\",\n\t\t\t\tOptions: map[string]string{\n\t\t\t\t\t\"frequency\": \"2000\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range loggingCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tconfigDetails := types.ConfigDetails{\n\t\t\t\tConfigFiles: []types.ConfigFile{\n\t\t\t\t\t{\n\t\t\t\t\t\tFilename: \"base.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.loggingBase,\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\t{\n\t\t\t\t\t\tFilename: \"override.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.loggingOverride,\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\tconfig, err := loadTestProject(configDetails)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.DeepEqual(t, &types.Project{\n\t\t\t\tName:       \"\",\n\t\t\t\tWorkingDir: \"\",\n\t\t\t\tServices: []types.ServiceConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tName:        \"foo\",\n\t\t\t\t\t\tLogging:     tc.expected,\n\t\t\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\t\t\tScale:       1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNetworks:   types.Networks{},\n\t\t\t\tVolumes:    types.Volumes{},\n\t\t\t\tSecrets:    types.Secrets{},\n\t\t\t\tConfigs:    types.Configs{},\n\t\t\t\tExtensions: types.Extensions{},\n\t\t\t}, config)\n\t\t})\n\t}\n}\n\nfunc loadTestProject(configDetails types.ConfigDetails) (*types.Project, error) {\n\treturn Load(configDetails, func(options *Options) {\n\t\toptions.SkipNormalization = true\n\t\toptions.SkipConsistencyCheck = true\n\t})\n}\n\nfunc TestLoadMultipleServicePorts(t *testing.T) {\n\tportsCases := []struct {\n\t\tname         string\n\t\tportBase     map[string]interface{}\n\t\tportOverride map[string]interface{}\n\t\texpected     []types.ServicePortConfig\n\t}{\n\t\t{\n\t\t\tname: \"no_override\",\n\t\t\tportBase: map[string]interface{}{\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\t\"8080:80\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tportOverride: map[string]interface{}{},\n\t\t\texpected: []types.ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tPublished: 8080,\n\t\t\t\t\tTarget:    80,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_different_published\",\n\t\t\tportBase: map[string]interface{}{\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\t\"8080:80\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tportOverride: map[string]interface{}{\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\t\"8081:80\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: []types.ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tPublished: 8080,\n\t\t\t\t\tTarget:    80,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tPublished: 8081,\n\t\t\t\t\tTarget:    80,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_distinct_protocols\",\n\t\t\tportBase: map[string]interface{}{\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\t\"8080:80/tcp\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tportOverride: map[string]interface{}{\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\t\"8080:80/udp\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: []types.ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tPublished: 8080,\n\t\t\t\t\tTarget:    80,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tPublished: 8080,\n\t\t\t\t\tTarget:    80,\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_one_sided\",\n\t\t\tportBase: map[string]interface{}{\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\t\"5000\",\n\t\t\t\t\t\"6000\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tportOverride: map[string]interface{}{},\n\t\t\texpected: []types.ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tPublished: 0,\n\t\t\t\t\tTarget:    5000,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\tPublished: 0,\n\t\t\t\t\tTarget:    6000,\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range portsCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tconfigDetails := types.ConfigDetails{\n\t\t\t\tConfigFiles: []types.ConfigFile{\n\t\t\t\t\t{\n\t\t\t\t\t\tFilename: \"base.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.portBase,\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\t{\n\t\t\t\t\t\tFilename: \"override.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.portOverride,\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\tconfig, err := loadTestProject(configDetails)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.DeepEqual(t, &types.Project{\n\t\t\t\tName:       \"\",\n\t\t\t\tWorkingDir: \"\",\n\t\t\t\tServices: []types.ServiceConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tName:        \"foo\",\n\t\t\t\t\t\tPorts:       tc.expected,\n\t\t\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\t\t\tScale:       1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNetworks:   types.Networks{},\n\t\t\t\tVolumes:    types.Volumes{},\n\t\t\t\tSecrets:    types.Secrets{},\n\t\t\t\tConfigs:    types.Configs{},\n\t\t\t\tExtensions: types.Extensions{},\n\t\t\t}, config)\n\t\t})\n\t}\n}\n\nfunc TestLoadMultipleSecretsConfig(t *testing.T) {\n\tportsCases := []struct {\n\t\tname           string\n\t\tsecretBase     map[string]interface{}\n\t\tsecretOverride map[string]interface{}\n\t\texpected       []types.ServiceSecretConfig\n\t}{\n\t\t{\n\t\t\tname: \"no_override\",\n\t\t\tsecretBase: map[string]interface{}{\n\t\t\t\t\"secrets\": []interface{}{\n\t\t\t\t\t\"my_secret\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tsecretOverride: map[string]interface{}{},\n\t\t\texpected: []types.ServiceSecretConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"my_secret\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_simple\",\n\t\t\tsecretBase: map[string]interface{}{\n\t\t\t\t\"secrets\": []interface{}{\n\t\t\t\t\t\"foo_secret\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tsecretOverride: map[string]interface{}{\n\t\t\t\t\"secrets\": []interface{}{\n\t\t\t\t\t\"bar_secret\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: []types.ServiceSecretConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"bar_secret\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"foo_secret\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_same_source\",\n\t\t\tsecretBase: map[string]interface{}{\n\t\t\t\t\"secrets\": []interface{}{\n\t\t\t\t\t\"foo_secret\",\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"source\": \"bar_secret\",\n\t\t\t\t\t\t\"target\": \"waw_secret\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tsecretOverride: map[string]interface{}{\n\t\t\t\t\"secrets\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"source\": \"bar_secret\",\n\t\t\t\t\t\t\"target\": \"bof_secret\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"source\": \"baz_secret\",\n\t\t\t\t\t\t\"target\": \"waw_secret\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: []types.ServiceSecretConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"bar_secret\",\n\t\t\t\t\tTarget: \"bof_secret\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"baz_secret\",\n\t\t\t\t\tTarget: \"waw_secret\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"foo_secret\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range portsCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tconfigDetails := types.ConfigDetails{\n\t\t\t\tConfigFiles: []types.ConfigFile{\n\t\t\t\t\t{\n\t\t\t\t\t\tFilename: \"base.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.secretBase,\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\t{\n\t\t\t\t\t\tFilename: \"override.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.secretOverride,\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\tconfig, err := loadTestProject(configDetails)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.DeepEqual(t, &types.Project{\n\t\t\t\tName:       \"\",\n\t\t\t\tWorkingDir: \"\",\n\t\t\t\tServices: []types.ServiceConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tName:        \"foo\",\n\t\t\t\t\t\tSecrets:     tc.expected,\n\t\t\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\t\t\tScale:       1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNetworks:   types.Networks{},\n\t\t\t\tVolumes:    types.Volumes{},\n\t\t\t\tSecrets:    types.Secrets{},\n\t\t\t\tConfigs:    types.Configs{},\n\t\t\t\tExtensions: types.Extensions{},\n\t\t\t}, config)\n\t\t})\n\t}\n}\n\nfunc TestLoadMultipleConfigobjsConfig(t *testing.T) {\n\tportsCases := []struct {\n\t\tname           string\n\t\tconfigBase     map[string]interface{}\n\t\tconfigOverride map[string]interface{}\n\t\texpected       []types.ServiceConfigObjConfig\n\t}{\n\t\t{\n\t\t\tname: \"no_override\",\n\t\t\tconfigBase: map[string]interface{}{\n\t\t\t\t\"configs\": []interface{}{\n\t\t\t\t\t\"my_config\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tconfigOverride: map[string]interface{}{},\n\t\t\texpected: []types.ServiceConfigObjConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"my_config\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_simple\",\n\t\t\tconfigBase: map[string]interface{}{\n\t\t\t\t\"configs\": []interface{}{\n\t\t\t\t\t\"foo_config\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tconfigOverride: map[string]interface{}{\n\t\t\t\t\"configs\": []interface{}{\n\t\t\t\t\t\"bar_config\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: []types.ServiceConfigObjConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"bar_config\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"foo_config\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_same_source\",\n\t\t\tconfigBase: map[string]interface{}{\n\t\t\t\t\"configs\": []interface{}{\n\t\t\t\t\t\"foo_config\",\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"source\": \"bar_config\",\n\t\t\t\t\t\t\"target\": \"waw_config\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\tconfigOverride: map[string]interface{}{\n\t\t\t\t\"configs\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"source\": \"bar_config\",\n\t\t\t\t\t\t\"target\": \"bof_config\",\n\t\t\t\t\t},\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"source\": \"baz_config\",\n\t\t\t\t\t\t\"target\": \"waw_config\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: []types.ServiceConfigObjConfig{\n\t\t\t\t{\n\t\t\t\t\tSource: \"bar_config\",\n\t\t\t\t\tTarget: \"bof_config\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"baz_config\",\n\t\t\t\t\tTarget: \"waw_config\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tSource: \"foo_config\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range portsCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tconfigDetails := types.ConfigDetails{\n\t\t\t\tConfigFiles: []types.ConfigFile{\n\t\t\t\t\t{\n\t\t\t\t\t\tFilename: \"base.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.configBase,\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\t{\n\t\t\t\t\t\tFilename: \"override.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.configOverride,\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\tconfig, err := loadTestProject(configDetails)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.DeepEqual(t, &types.Project{\n\t\t\t\tName:       \"\",\n\t\t\t\tWorkingDir: \"\",\n\t\t\t\tServices: []types.ServiceConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tName:        \"foo\",\n\t\t\t\t\t\tConfigs:     tc.expected,\n\t\t\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\t\t\tScale:       1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNetworks:   types.Networks{},\n\t\t\t\tVolumes:    types.Volumes{},\n\t\t\t\tSecrets:    types.Secrets{},\n\t\t\t\tConfigs:    types.Configs{},\n\t\t\t\tExtensions: types.Extensions{},\n\t\t\t}, config)\n\t\t})\n\t}\n}\n\nfunc TestLoadMultipleUlimits(t *testing.T) {\n\tulimitCases := []struct {\n\t\tname           string\n\t\tulimitBase     map[string]interface{}\n\t\tulimitOverride map[string]interface{}\n\t\texpected       map[string]*types.UlimitsConfig\n\t}{\n\t\t{\n\t\t\tname: \"no_override\",\n\t\t\tulimitBase: map[string]interface{}{\n\t\t\t\t\"ulimits\": map[string]interface{}{\n\t\t\t\t\t\"noproc\": 65535,\n\t\t\t\t},\n\t\t\t},\n\t\t\tulimitOverride: map[string]interface{}{},\n\t\t\texpected: map[string]*types.UlimitsConfig{\n\t\t\t\t\"noproc\": {\n\t\t\t\t\tSingle: 65535,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_simple\",\n\t\t\tulimitBase: map[string]interface{}{\n\t\t\t\t\"ulimits\": map[string]interface{}{\n\t\t\t\t\t\"noproc\": 65535,\n\t\t\t\t},\n\t\t\t},\n\t\t\tulimitOverride: map[string]interface{}{\n\t\t\t\t\"ulimits\": map[string]interface{}{\n\t\t\t\t\t\"noproc\": 44444,\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: map[string]*types.UlimitsConfig{\n\t\t\t\t\"noproc\": {\n\t\t\t\t\tSingle: 44444,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_different_notation\",\n\t\t\tulimitBase: map[string]interface{}{\n\t\t\t\t\"ulimits\": map[string]interface{}{\n\t\t\t\t\t\"nofile\": map[string]interface{}{\n\t\t\t\t\t\t\"soft\": 11111,\n\t\t\t\t\t\t\"hard\": 99999,\n\t\t\t\t\t},\n\t\t\t\t\t\"noproc\": 44444,\n\t\t\t\t},\n\t\t\t},\n\t\t\tulimitOverride: map[string]interface{}{\n\t\t\t\t\"ulimits\": map[string]interface{}{\n\t\t\t\t\t\"nofile\": 55555,\n\t\t\t\t\t\"noproc\": map[string]interface{}{\n\t\t\t\t\t\t\"soft\": 22222,\n\t\t\t\t\t\t\"hard\": 33333,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: map[string]*types.UlimitsConfig{\n\t\t\t\t\"noproc\": {\n\t\t\t\t\tSoft: 22222,\n\t\t\t\t\tHard: 33333,\n\t\t\t\t},\n\t\t\t\t\"nofile\": {\n\t\t\t\t\tSingle: 55555,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range ulimitCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tconfigDetails := types.ConfigDetails{\n\t\t\t\tConfigFiles: []types.ConfigFile{\n\t\t\t\t\t{\n\t\t\t\t\t\tFilename: \"base.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.ulimitBase,\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\t{\n\t\t\t\t\t\tFilename: \"override.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.ulimitOverride,\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\tconfig, err := loadTestProject(configDetails)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.DeepEqual(t, &types.Project{\n\t\t\t\tName:       \"\",\n\t\t\t\tWorkingDir: \"\",\n\t\t\t\tServices: []types.ServiceConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tName:        \"foo\",\n\t\t\t\t\t\tUlimits:     tc.expected,\n\t\t\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\t\t\tScale:       1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNetworks:   types.Networks{},\n\t\t\t\tVolumes:    types.Volumes{},\n\t\t\t\tSecrets:    types.Secrets{},\n\t\t\t\tConfigs:    types.Configs{},\n\t\t\t\tExtensions: types.Extensions{},\n\t\t\t}, config)\n\t\t})\n\t}\n}\n\nfunc TestLoadMultipleServiceNetworks(t *testing.T) {\n\tnetworkCases := []struct {\n\t\tname            string\n\t\tnetworkBase     map[string]interface{}\n\t\tnetworkOverride map[string]interface{}\n\t\texpected        map[string]*types.ServiceNetworkConfig\n\t}{\n\t\t{\n\t\t\tname: \"no_override\",\n\t\t\tnetworkBase: map[string]interface{}{\n\t\t\t\t\"networks\": []interface{}{\n\t\t\t\t\t\"net1\",\n\t\t\t\t\t\"net2\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tnetworkOverride: map[string]interface{}{},\n\t\t\texpected: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\"net1\": nil,\n\t\t\t\t\"net2\": nil,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_simple\",\n\t\t\tnetworkBase: map[string]interface{}{\n\t\t\t\t\"networks\": []interface{}{\n\t\t\t\t\t\"net1\",\n\t\t\t\t\t\"net2\",\n\t\t\t\t},\n\t\t\t},\n\t\t\tnetworkOverride: map[string]interface{}{\n\t\t\t\t\"networks\": []interface{}{\n\t\t\t\t\t\"net1\",\n\t\t\t\t\t\"net3\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\"net1\": nil,\n\t\t\t\t\"net2\": nil,\n\t\t\t\t\"net3\": nil,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"override_with_aliases\",\n\t\t\tnetworkBase: map[string]interface{}{\n\t\t\t\t\"networks\": map[string]interface{}{\n\t\t\t\t\t\"net1\": map[string]interface{}{\n\t\t\t\t\t\t\"aliases\": []interface{}{\n\t\t\t\t\t\t\t\"alias1\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"net2\": nil,\n\t\t\t\t},\n\t\t\t},\n\t\t\tnetworkOverride: map[string]interface{}{\n\t\t\t\t\"networks\": map[string]interface{}{\n\t\t\t\t\t\"net1\": map[string]interface{}{\n\t\t\t\t\t\t\"aliases\": []interface{}{\n\t\t\t\t\t\t\t\"alias2\",\n\t\t\t\t\t\t\t\"alias3\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t\"net3\": map[string]interface{}{},\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\"net1\": {\n\t\t\t\t\tAliases: []string{\"alias2\", \"alias3\"},\n\t\t\t\t},\n\t\t\t\t\"net2\": nil,\n\t\t\t\t\"net3\": {},\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tc := range networkCases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tconfigDetails := types.ConfigDetails{\n\t\t\t\tConfigFiles: []types.ConfigFile{\n\t\t\t\t\t{\n\t\t\t\t\t\tFilename: \"base.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.networkBase,\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\t{\n\t\t\t\t\t\tFilename: \"override.yml\",\n\t\t\t\t\t\tConfig: map[string]interface{}{\n\t\t\t\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\t\t\t\"foo\": tc.networkOverride,\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\tconfig, err := loadTestProject(configDetails)\n\t\t\tassert.NilError(t, err)\n\t\t\tassert.DeepEqual(t, &types.Project{\n\t\t\t\tName:       \"\",\n\t\t\t\tWorkingDir: \"\",\n\t\t\t\tServices: []types.ServiceConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tName:        \"foo\",\n\t\t\t\t\t\tNetworks:    tc.expected,\n\t\t\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\t\t\tScale:       1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tNetworks:   types.Networks{},\n\t\t\t\tVolumes:    types.Volumes{},\n\t\t\t\tSecrets:    types.Secrets{},\n\t\t\t\tConfigs:    types.Configs{},\n\t\t\t\tExtensions: types.Extensions{},\n\t\t\t}, config)\n\t\t})\n\t}\n}\n\nfunc TestLoadMultipleConfigs(t *testing.T) {\n\tbase := map[string]interface{}{\n\t\t\"services\": map[string]interface{}{\n\t\t\t\"foo\": map[string]interface{}{\n\t\t\t\t\"image\":      \"foo\",\n\t\t\t\t\"entrypoint\": \"echo\",\n\t\t\t\t\"command\":    \"hellow world\",\n\t\t\t\t\"build\": map[string]interface{}{\n\t\t\t\t\t\"context\":    \".\",\n\t\t\t\t\t\"dockerfile\": \"bar.Dockerfile\",\n\t\t\t\t},\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\t\"8080:80\",\n\t\t\t\t\t\"9090:90\",\n\t\t\t\t},\n\t\t\t\t\"labels\": []interface{}{\n\t\t\t\t\t\"foo=bar\",\n\t\t\t\t},\n\t\t\t\t\"cap_add\": []interface{}{\n\t\t\t\t\t\"NET_ADMIN\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"volumes\":  map[string]interface{}{},\n\t\t\"networks\": map[string]interface{}{},\n\t\t\"secrets\":  map[string]interface{}{},\n\t\t\"configs\":  map[string]interface{}{},\n\t}\n\toverride := map[string]interface{}{\n\t\t\"services\": map[string]interface{}{\n\t\t\t\"foo\": map[string]interface{}{\n\t\t\t\t\"image\":      \"baz\",\n\t\t\t\t\"entrypoint\": \"ping\",\n\t\t\t\t\"command\":    \"localhost\",\n\t\t\t\t\"build\": map[string]interface{}{\n\t\t\t\t\t\"dockerfile\": \"foo.Dockerfile\",\n\t\t\t\t\t\"args\": []interface{}{\n\t\t\t\t\t\t\"buildno=1\",\n\t\t\t\t\t\t\"password=secret\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"ports\": []interface{}{\n\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\"target\":    81,\n\t\t\t\t\t\t\"published\": 8080,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t\"labels\": map[string]interface{}{\n\t\t\t\t\t\"foo\": \"baz\",\n\t\t\t\t},\n\t\t\t\t\"cap_add\": []interface{}{\n\t\t\t\t\t\"SYS_ADMIN\",\n\t\t\t\t},\n\t\t\t},\n\t\t\t\"bar\": map[string]interface{}{\n\t\t\t\t\"image\": \"bar\",\n\t\t\t},\n\t\t},\n\t\t\"volumes\":  map[string]interface{}{},\n\t\t\"networks\": map[string]interface{}{},\n\t\t\"secrets\":  map[string]interface{}{},\n\t\t\"configs\":  map[string]interface{}{},\n\t}\n\tconfigDetails := types.ConfigDetails{\n\t\tConfigFiles: []types.ConfigFile{\n\t\t\t{Filename: \"base.yml\", Config: base},\n\t\t\t{Filename: \"override.yml\", Config: override},\n\t\t},\n\t}\n\tconfig, err := loadTestProject(configDetails)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, &types.Project{\n\t\tName:       \"\",\n\t\tWorkingDir: \"\",\n\t\tServices: []types.ServiceConfig{\n\t\t\t{\n\t\t\t\tName:        \"bar\",\n\t\t\t\tImage:       \"bar\",\n\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\tScale:       1,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:       \"foo\",\n\t\t\t\tImage:      \"baz\",\n\t\t\t\tEntrypoint: types.ShellCommand{\"ping\"},\n\t\t\t\tCommand:    types.ShellCommand{\"localhost\"},\n\t\t\t\tBuild: &types.BuildConfig{\n\t\t\t\t\tContext:    \".\",\n\t\t\t\t\tDockerfile: \"foo.Dockerfile\",\n\t\t\t\t\tArgs: types.MappingWithEquals{\n\t\t\t\t\t\t\"buildno\":  strPtr(\"1\"),\n\t\t\t\t\t\t\"password\": strPtr(\"secret\"),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tPorts: []types.ServicePortConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\t\tTarget:    80,\n\t\t\t\t\t\tPublished: 8080,\n\t\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tTarget:    81,\n\t\t\t\t\t\tPublished: 8080,\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t\t\tTarget:    90,\n\t\t\t\t\t\tPublished: 9090,\n\t\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tLabels: types.Labels{\n\t\t\t\t\t\"foo\": \"baz\",\n\t\t\t\t},\n\t\t\t\tCapAdd:      []string{\"NET_ADMIN\", \"SYS_ADMIN\"},\n\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\tScale:       1,\n\t\t\t}},\n\t\tNetworks:   types.Networks{},\n\t\tVolumes:    types.Volumes{},\n\t\tSecrets:    types.Secrets{},\n\t\tConfigs:    types.Configs{},\n\t\tExtensions: types.Extensions{},\n\t}, config)\n}\n\n// Issue#972\nfunc TestLoadMultipleNetworks(t *testing.T) {\n\tbase := map[string]interface{}{\n\t\t\"services\": map[string]interface{}{\n\t\t\t\"foo\": map[string]interface{}{\n\t\t\t\t\"image\": \"baz\",\n\t\t\t},\n\t\t},\n\t\t\"volumes\": map[string]interface{}{},\n\t\t\"networks\": map[string]interface{}{\n\t\t\t\"hostnet\": map[string]interface{}{\n\t\t\t\t\"driver\": \"overlay\",\n\t\t\t\t\"ipam\": map[string]interface{}{\n\t\t\t\t\t\"driver\": \"default\",\n\t\t\t\t\t\"config\": []interface{}{\n\t\t\t\t\t\tmap[string]interface{}{\n\t\t\t\t\t\t\t\"subnet\": \"10.0.0.0/20\",\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\t\"secrets\": map[string]interface{}{},\n\t\t\"configs\": map[string]interface{}{},\n\t}\n\toverride := map[string]interface{}{\n\t\t\"services\": map[string]interface{}{},\n\t\t\"volumes\":  map[string]interface{}{},\n\t\t\"networks\": map[string]interface{}{\n\t\t\t\"hostnet\": map[string]interface{}{\n\t\t\t\t\"external\": map[string]interface{}{\n\t\t\t\t\t\"name\": \"host\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t\"secrets\": map[string]interface{}{},\n\t\t\"configs\": map[string]interface{}{},\n\t}\n\tconfigDetails := types.ConfigDetails{\n\t\tConfigFiles: []types.ConfigFile{\n\t\t\t{Filename: \"base.yml\", Config: base},\n\t\t\t{Filename: \"override.yml\", Config: override},\n\t\t},\n\t}\n\tconfig, err := loadTestProject(configDetails)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, &types.Project{\n\t\tName:       \"\",\n\t\tWorkingDir: \"\",\n\t\tServices: []types.ServiceConfig{\n\t\t\t{\n\t\t\t\tName:        \"foo\",\n\t\t\t\tImage:       \"baz\",\n\t\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\t\tScale:       1,\n\t\t\t}},\n\t\tNetworks: map[string]types.NetworkConfig{\n\t\t\t\"hostnet\": {\n\t\t\t\tName: \"host\",\n\t\t\t\tExternal: types.External{\n\t\t\t\t\tExternal: true,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tVolumes:    types.Volumes{},\n\t\tSecrets:    types.Secrets{},\n\t\tConfigs:    types.Configs{},\n\t\tExtensions: types.Extensions{},\n\t}, config)\n}\n\nfunc TestMergeUlimitsConfig(t *testing.T) {\n\tspecials := &specials{\n\t\tm: map[reflect.Type]func(dst, src reflect.Value) error{\n\t\t\treflect.TypeOf(&types.UlimitsConfig{}): mergeUlimitsConfig,\n\t\t},\n\t}\n\tbase := map[string]*types.UlimitsConfig{\n\t\t\"override-single\":                {Single: 100},\n\t\t\"override-single-with-soft-hard\": {Single: 200},\n\t\t\"override-soft-hard\":             {Soft: 300, Hard: 301},\n\t\t\"override-soft-hard-with-single\": {Soft: 400, Hard: 401},\n\t\t\"dont-override\":                  {Single: 500},\n\t}\n\toverride := map[string]*types.UlimitsConfig{\n\t\t\"override-single\":                {Single: 110},\n\t\t\"override-single-with-soft-hard\": {Soft: 210, Hard: 211},\n\t\t\"override-soft-hard\":             {Soft: 310, Hard: 311},\n\t\t\"override-soft-hard-with-single\": {Single: 410},\n\t\t\"add\":                            {Single: 610},\n\t}\n\terr := mergo.Merge(&base, &override, mergo.WithOverride, mergo.WithTransformers(specials))\n\tassert.NilError(t, err)\n\tassert.DeepEqual(\n\t\tt,\n\t\tbase,\n\t\tmap[string]*types.UlimitsConfig{\n\t\t\t\"override-single\":                {Single: 110},\n\t\t\t\"override-single-with-soft-hard\": {Soft: 210, Hard: 211},\n\t\t\t\"override-soft-hard\":             {Soft: 310, Hard: 311},\n\t\t\t\"override-soft-hard-with-single\": {Single: 410},\n\t\t\t\"dont-override\":                  {Single: 500},\n\t\t\t\"add\":                            {Single: 610},\n\t\t},\n\t)\n}\n\nfunc TestMergeServiceNetworkConfig(t *testing.T) {\n\tspecials := &specials{\n\t\tm: map[reflect.Type]func(dst, src reflect.Value) error{\n\t\t\treflect.TypeOf(&types.ServiceNetworkConfig{}): mergeServiceNetworkConfig,\n\t\t},\n\t}\n\tbase := map[string]*types.ServiceNetworkConfig{\n\t\t\"override-aliases\": {\n\t\t\tAliases:     []string{\"100\", \"101\"},\n\t\t\tIpv4Address: \"127.0.0.1\",\n\t\t\tIpv6Address: \"0:0:0:0:0:0:0:1\",\n\t\t},\n\t\t\"dont-override\": {\n\t\t\tAliases:     []string{\"200\", \"201\"},\n\t\t\tIpv4Address: \"127.0.0.2\",\n\t\t\tIpv6Address: \"0:0:0:0:0:0:0:2\",\n\t\t},\n\t}\n\toverride := map[string]*types.ServiceNetworkConfig{\n\t\t\"override-aliases\": {\n\t\t\tAliases:     []string{\"110\", \"111\"},\n\t\t\tIpv4Address: \"127.0.1.1\",\n\t\t\tIpv6Address: \"0:0:0:0:0:0:1:1\",\n\t\t},\n\t\t\"add\": {\n\t\t\tAliases:     []string{\"310\", \"311\"},\n\t\t\tIpv4Address: \"127.0.3.1\",\n\t\t\tIpv6Address: \"0:0:0:0:0:0:3:1\",\n\t\t},\n\t}\n\terr := mergo.Merge(&base, &override, mergo.WithOverride, mergo.WithTransformers(specials))\n\tassert.NilError(t, err)\n\tassert.DeepEqual(\n\t\tt,\n\t\tbase,\n\t\tmap[string]*types.ServiceNetworkConfig{\n\t\t\t\"override-aliases\": {\n\t\t\t\tAliases:     []string{\"110\", \"111\"},\n\t\t\t\tIpv4Address: \"127.0.1.1\",\n\t\t\t\tIpv6Address: \"0:0:0:0:0:0:1:1\",\n\t\t\t},\n\t\t\t\"dont-override\": {\n\t\t\t\tAliases:     []string{\"200\", \"201\"},\n\t\t\t\tIpv4Address: \"127.0.0.2\",\n\t\t\t\tIpv6Address: \"0:0:0:0:0:0:0:2\",\n\t\t\t},\n\t\t\t\"add\": {\n\t\t\t\tAliases:     []string{\"310\", \"311\"},\n\t\t\t\tIpv4Address: \"127.0.3.1\",\n\t\t\t\tIpv6Address: \"0:0:0:0:0:0:3:1\",\n\t\t\t},\n\t\t},\n\t)\n}\n\nfunc TestMergeTopLevelExtensions(t *testing.T) {\n\tbase := map[string]interface{}{\n\t\t\"x-foo\": \"foo\",\n\t\t\"x-bar\": map[string]interface{}{\n\t\t\t\"base\": map[string]interface{}{},\n\t\t},\n\t}\n\toverride := map[string]interface{}{\n\t\t\"x-bar\": map[string]interface{}{\n\t\t\t\"base\": \"qix\",\n\t\t},\n\t\t\"x-zot\": \"zot\",\n\t}\n\tconfigDetails := types.ConfigDetails{\n\t\tConfigFiles: []types.ConfigFile{\n\t\t\t{Filename: \"base.yml\", Config: base},\n\t\t\t{Filename: \"override.yml\", Config: override},\n\t\t},\n\t}\n\tconfig, err := loadTestProject(configDetails)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, &types.Project{\n\t\tName:       \"\",\n\t\tWorkingDir: \"\",\n\t\tServices:   types.Services{},\n\t\tNetworks:   types.Networks{},\n\t\tVolumes:    types.Volumes{},\n\t\tSecrets:    types.Secrets{},\n\t\tConfigs:    types.Configs{},\n\t\tExtensions: types.Extensions{\n\t\t\t\"x-foo\": \"foo\",\n\t\t\t\"x-bar\": map[string]interface{}{\n\t\t\t\t\"base\": \"qix\",\n\t\t\t},\n\t\t\t\"x-zot\": \"zot\",\n\t\t},\n\t}, config)\n}\n\nfunc TestMergeCommands(t *testing.T) {\n\tconfigDetails := types.ConfigDetails{\n\t\tConfigFiles: []types.ConfigFile{\n\t\t\t{Filename: \"base.yml\", Config: map[string]interface{}{\n\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\"foo\": map[string]interface{}{\n\t\t\t\t\t\t\"image\":   \"alpine\",\n\t\t\t\t\t\t\"command\": \"/bin/bash -c \\\"echo 'hello'\\\"\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}},\n\t\t\t{Filename: \"override.yml\", Config: map[string]interface{}{\n\t\t\t\t\"services\": map[string]interface{}{\n\t\t\t\t\t\"foo\": map[string]interface{}{\n\t\t\t\t\t\t\"image\":   \"alpine\",\n\t\t\t\t\t\t\"command\": \"/bin/ash -c \\\"echo 'world'\\\"\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}},\n\t\t},\n\t}\n\tmerged, err := loadTestProject(configDetails)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, merged.Services[0].Command, types.ShellCommand{\"/bin/ash\", \"-c\", \"echo 'world'\"})\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/normalize.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n)\n\n// normalize compose project by moving deprecated attributes to their canonical position and injecting implicit defaults\nfunc normalize(project *types.Project, resolvePaths bool) error {\n\tabsWorkingDir, err := filepath.Abs(project.WorkingDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\tproject.WorkingDir = absWorkingDir\n\n\tabsComposeFiles, err := absComposeFiles(project.ComposeFiles)\n\tif err != nil {\n\t\treturn err\n\t}\n\tproject.ComposeFiles = absComposeFiles\n\n\t// If not declared explicitly, Compose model involves an implicit \"default\" network\n\tif _, ok := project.Networks[\"default\"]; !ok {\n\t\tproject.Networks[\"default\"] = types.NetworkConfig{}\n\t}\n\n\terr = relocateExternalName(project)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor i, s := range project.Services {\n\t\tif len(s.Networks) == 0 && s.NetworkMode == \"\" {\n\t\t\t// Service without explicit network attachment are implicitly exposed on default network\n\t\t\ts.Networks = map[string]*types.ServiceNetworkConfig{\"default\": nil}\n\t\t}\n\n\t\tif s.PullPolicy == types.PullPolicyIfNotPresent {\n\t\t\ts.PullPolicy = types.PullPolicyMissing\n\t\t}\n\n\t\tfn := func(s string) (string, bool) {\n\t\t\tv, ok := project.Environment[s]\n\t\t\treturn v, ok\n\t\t}\n\n\t\tif s.Build != nil {\n\t\t\tif s.Build.Dockerfile == \"\" {\n\t\t\t\ts.Build.Dockerfile = \"Dockerfile\"\n\t\t\t}\n\t\t\tlocalContext := absPath(project.WorkingDir, s.Build.Context)\n\t\t\tif _, err := os.Stat(localContext); err == nil {\n\t\t\t\tif resolvePaths {\n\t\t\t\t\ts.Build.Context = localContext\n\t\t\t\t\ts.Build.Dockerfile = absPath(localContext, s.Build.Dockerfile)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// might be a remote http/git context. Unfortunately supported \"remote\" syntax is highly ambiguous\n\t\t\t\t// in moby/moby and not defined by compose-spec, so let's assume runtime will check\n\t\t\t}\n\t\t\ts.Build.Args = s.Build.Args.Resolve(fn)\n\t\t}\n\t\ts.Environment = s.Environment.Resolve(fn)\n\n\t\terr := relocateLogDriver(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = relocateLogOpt(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = relocateDockerfile(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = relocateScale(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tproject.Services[i] = s\n\t}\n\n\tsetNameFromKey(project)\n\n\treturn nil\n}\n\nfunc relocateScale(s *types.ServiceConfig) error {\n\tscale := uint64(s.Scale)\n\tif scale != 1 {\n\t\tlogrus.Warn(\"`scale` is deprecated. Use the `deploy.replicas` element\")\n\t\tif s.Deploy == nil {\n\t\t\ts.Deploy = &types.DeployConfig{}\n\t\t}\n\t\tif s.Deploy.Replicas != nil && *s.Deploy.Replicas != scale {\n\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'scale' (deprecated) and 'deploy.replicas'\")\n\t\t}\n\t\ts.Deploy.Replicas = &scale\n\t}\n\treturn nil\n}\n\nfunc absComposeFiles(composeFiles []string) ([]string, error) {\n\tabsComposeFiles := make([]string, len(composeFiles))\n\tfor i, composeFile := range composeFiles {\n\t\tabsComposefile, err := filepath.Abs(composeFile)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tabsComposeFiles[i] = absComposefile\n\t}\n\treturn absComposeFiles, nil\n}\n\n// Resources with no explicit name are actually named by their key in map\nfunc setNameFromKey(project *types.Project) {\n\tfor i, n := range project.Networks {\n\t\tif n.Name == \"\" {\n\t\t\tn.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Networks[i] = n\n\t\t}\n\t}\n\n\tfor i, v := range project.Volumes {\n\t\tif v.Name == \"\" {\n\t\t\tv.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Volumes[i] = v\n\t\t}\n\t}\n\n\tfor i, c := range project.Configs {\n\t\tif c.Name == \"\" {\n\t\t\tc.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Configs[i] = c\n\t\t}\n\t}\n\n\tfor i, s := range project.Secrets {\n\t\tif s.Name == \"\" {\n\t\t\ts.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Secrets[i] = s\n\t\t}\n\t}\n}\n\nfunc relocateExternalName(project *types.Project) error {\n\tfor i, n := range project.Networks {\n\t\tif n.External.Name != \"\" {\n\t\t\tif n.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'networks.external.name' (deprecated) and 'networks.name'\")\n\t\t\t}\n\t\t\tn.Name = n.External.Name\n\t\t}\n\t\tproject.Networks[i] = n\n\t}\n\n\tfor i, v := range project.Volumes {\n\t\tif v.External.Name != \"\" {\n\t\t\tif v.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'volumes.external.name' (deprecated) and 'volumes.name'\")\n\t\t\t}\n\t\t\tv.Name = v.External.Name\n\t\t}\n\t\tproject.Volumes[i] = v\n\t}\n\n\tfor i, s := range project.Secrets {\n\t\tif s.External.Name != \"\" {\n\t\t\tif s.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'secrets.external.name' (deprecated) and 'secrets.name'\")\n\t\t\t}\n\t\t\ts.Name = s.External.Name\n\t\t}\n\t\tproject.Secrets[i] = s\n\t}\n\n\tfor i, c := range project.Configs {\n\t\tif c.External.Name != \"\" {\n\t\t\tif c.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'configs.external.name' (deprecated) and 'configs.name'\")\n\t\t\t}\n\t\t\tc.Name = c.External.Name\n\t\t}\n\t\tproject.Configs[i] = c\n\t}\n\treturn nil\n}\n\nfunc relocateLogOpt(s *types.ServiceConfig) error {\n\tif len(s.LogOpt) != 0 {\n\t\tlogrus.Warn(\"`log_opts` is deprecated. Use the `logging` element\")\n\t\tif s.Logging == nil {\n\t\t\ts.Logging = &types.LoggingConfig{}\n\t\t}\n\t\tfor k, v := range s.LogOpt {\n\t\t\tif _, ok := s.Logging.Options[k]; !ok {\n\t\t\t\ts.Logging.Options[k] = v\n\t\t\t} else {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'log_opt' (deprecated) and 'logging.options'\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc relocateLogDriver(s *types.ServiceConfig) error {\n\tif s.LogDriver != \"\" {\n\t\tlogrus.Warn(\"`log_driver` is deprecated. Use the `logging` element\")\n\t\tif s.Logging == nil {\n\t\t\ts.Logging = &types.LoggingConfig{}\n\t\t}\n\t\tif s.Logging.Driver == \"\" {\n\t\t\ts.Logging.Driver = s.LogDriver\n\t\t} else {\n\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'log_driver' (deprecated) and 'logging.driver'\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc relocateDockerfile(s *types.ServiceConfig) error {\n\tif s.Dockerfile != \"\" {\n\t\tlogrus.Warn(\"`dockerfile` is deprecated. Use the `build` element\")\n\t\tif s.Build == nil {\n\t\t\ts.Build = &types.BuildConfig{}\n\t\t}\n\t\tif s.Dockerfile == \"\" {\n\t\t\ts.Build.Dockerfile = s.Dockerfile\n\t\t} else {\n\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'dockerfile' (deprecated) and 'build.dockerfile'\")\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/normalize_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"gopkg.in/yaml.v2\"\n\t\"gotest.tools/v3/assert\"\n)\n\nfunc TestNormalizeNetworkNames(t *testing.T) {\n\twd, _ := os.Getwd()\n\tproject := types.Project{\n\t\tName:       \"myProject\",\n\t\tWorkingDir: wd,\n\t\tEnvironment: map[string]string{\n\t\t\t\"FOO\": \"BAR\",\n\t\t},\n\t\tNetworks: types.Networks{\n\t\t\t\"myExternalnet\": {\n\t\t\t\tName:     \"myExternalnet\", // this is automaticaly setup by loader for externa networks before reaching normalization\n\t\t\t\tExternal: types.External{External: true},\n\t\t\t},\n\t\t\t\"mynet\": {},\n\t\t\t\"myNamedNet\": {\n\t\t\t\tName: \"CustomName\",\n\t\t\t},\n\t\t},\n\t\tServices: []types.ServiceConfig{\n\t\t\t{\n\t\t\t\tName: \"foo\",\n\t\t\t\tBuild: &types.BuildConfig{\n\t\t\t\t\tContext: \"./testdata\",\n\t\t\t\t\tArgs: map[string]*string{\n\t\t\t\t\t\t\"FOO\": nil,\n\t\t\t\t\t\t\"ZOT\": nil,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tScale: 1,\n\t\t\t},\n\t\t},\n\t}\n\n\texpected := `services:\n  foo:\n    build:\n      context: ./testdata\n      dockerfile: Dockerfile\n      args:\n        FOO: BAR\n        ZOT: null\n    networks:\n      default: null\nnetworks:\n  default:\n    name: myProject_default\n  myExternalnet:\n    name: myExternalnet\n    external: true\n  myNamedNet:\n    name: CustomName\n  mynet:\n    name: myProject_mynet\n`\n\terr := normalize(&project, false)\n\tassert.NilError(t, err)\n\tmarshal, err := yaml.Marshal(project)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, expected, string(marshal))\n}\n\nfunc TestNormalizeAbsolutePaths(t *testing.T) {\n\tproject := types.Project{\n\t\tName:         \"myProject\",\n\t\tWorkingDir:   \"testdata\",\n\t\tNetworks:     types.Networks{},\n\t\tComposeFiles: []string{filepath.Join(\"testdata\", \"simple\", \"compose.yaml\"), filepath.Join(\"testdata\", \"simple\", \"compose-with-overrides.yaml\")},\n\t}\n\tabsWorkingDir, _ := filepath.Abs(\"testdata\")\n\tabsComposeFile, _ := filepath.Abs(filepath.Join(\"testdata\", \"simple\", \"compose.yaml\"))\n\tabsOverrideFile, _ := filepath.Abs(filepath.Join(\"testdata\", \"simple\", \"compose-with-overrides.yaml\"))\n\n\texpected := types.Project{\n\t\tName:         \"myProject\",\n\t\tNetworks:     types.Networks{\"default\": {Name: \"myProject_default\"}},\n\t\tWorkingDir:   absWorkingDir,\n\t\tComposeFiles: []string{absComposeFile, absOverrideFile},\n\t}\n\terr := normalize(&project, false)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, expected, project)\n}\n\nfunc TestNormalizeVolumes(t *testing.T) {\n\tproject := types.Project{\n\t\tName:     \"myProject\",\n\t\tNetworks: types.Networks{},\n\t\tVolumes: types.Volumes{\n\t\t\t\"myExternalVol\": {\n\t\t\t\tName:     \"myExternalVol\", // this is automaticaly setup by loader for externa networks before reaching normalization\n\t\t\t\tExternal: types.External{External: true},\n\t\t\t},\n\t\t\t\"myvol\": {},\n\t\t\t\"myNamedVol\": {\n\t\t\t\tName: \"CustomName\",\n\t\t\t},\n\t\t},\n\t}\n\n\tabsCwd, _ := filepath.Abs(\".\")\n\texpected := types.Project{\n\t\tName:     \"myProject\",\n\t\tNetworks: types.Networks{\"default\": {Name: \"myProject_default\"}},\n\t\tVolumes: types.Volumes{\n\t\t\t\"myExternalVol\": {\n\t\t\t\tName:     \"myExternalVol\",\n\t\t\t\tExternal: types.External{External: true},\n\t\t\t},\n\t\t\t\"myvol\": {Name: \"myProject_myvol\"},\n\t\t\t\"myNamedVol\": {\n\t\t\t\tName: \"CustomName\",\n\t\t\t},\n\t\t},\n\t\tWorkingDir:   absCwd,\n\t\tComposeFiles: []string{},\n\t}\n\terr := normalize(&project, false)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, expected, project)\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/testdata/Dockerfile",
    "content": "#   Copyright 2020 The Compose Specification Authors.\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#       http://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\nFROM busybox:1.31.0-uclibc\nRUN  echo something\nCMD  top\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/testdata/compose-test-extends-imported.yaml",
    "content": "services:\n  imported:\n    image: nginx\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/testdata/compose-test-extends.yaml",
    "content": "services:\n  importer:\n    extends:\n      file: compose-test-extends-imported.yaml\n      service: imported\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/testdata/compose-test-with-version.yaml",
    "content": "version: \"2\"\n\nvolumes:\n  data:\n    driver: local\n\nnetworks:\n  front: {}\n\nservices:\n  web:\n    build: ./Dockerfile\n    networks:\n      - front\n      - default\n    volumes_from:\n      - other\n\n  other:\n    image: busybox:1.31.0-uclibc\n    command: top\n    volumes:\n      - /data\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/types_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"encoding/json\"\n\t\"os\"\n\t\"testing\"\n\n\tyaml \"gopkg.in/yaml.v2\"\n\t\"gotest.tools/v3/assert\"\n\tis \"gotest.tools/v3/assert/cmp\"\n)\n\nfunc TestMarshallConfig(t *testing.T) {\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\thomeDir, err := os.UserHomeDir()\n\tassert.NilError(t, err)\n\tcfg := fullExampleConfig(workingDir, homeDir)\n\texpected := fullExampleYAML(workingDir, homeDir)\n\n\tactual, err := yaml.Marshal(cfg)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(expected, string(actual)))\n\n\t// Make sure the expected still\n\t_, err = Load(buildConfigDetails(expected, map[string]string{}), func(options *Options) {\n\t\toptions.SkipNormalization = true\n\t\toptions.SkipConsistencyCheck = true\n\t})\n\tassert.NilError(t, err)\n}\n\nfunc TestJSONMarshallConfig(t *testing.T) {\n\tworkingDir, err := os.Getwd()\n\tassert.NilError(t, err)\n\thomeDir, err := os.UserHomeDir()\n\tassert.NilError(t, err)\n\n\tcfg := fullExampleConfig(workingDir, homeDir)\n\texpected := fullExampleJSON(workingDir, homeDir)\n\n\tactual, err := json.MarshalIndent(cfg, \"\", \"  \")\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(expected, string(actual)))\n\n\t_, err = Load(buildConfigDetails(expected, map[string]string{}), func(options *Options) {\n\t\toptions.SkipNormalization = true\n\t\toptions.SkipConsistencyCheck = true\n\t})\n\tassert.NilError(t, err)\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/validate.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n)\n\n// checkConsistency validate a compose model is consistent\nfunc checkConsistency(project *types.Project) error {\n\tfor _, s := range project.Services {\n\t\tif s.Build == nil && s.Image == \"\" {\n\t\t\treturn errors.Wrapf(errdefs.ErrInvalid, \"service %q has neither an image nor a build context specified\", s.Name)\n\t\t}\n\n\t\tfor network := range s.Networks {\n\t\t\tif _, ok := project.Networks[network]; !ok {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined network %s\", s.Name, network))\n\t\t\t}\n\t\t}\n\n\t\tif strings.HasPrefix(s.NetworkMode, types.ServicePrefix) {\n\t\t\tserviceName := s.NetworkMode[len(types.ServicePrefix):]\n\t\t\tif _, err := project.GetServices(serviceName); err != nil {\n\t\t\t\treturn fmt.Errorf(\"service %q not found for network_mode 'service:%s'\", serviceName, serviceName)\n\t\t\t}\n\t\t}\n\n\t\tfor _, volume := range s.Volumes {\n\t\t\tswitch volume.Type {\n\t\t\tcase types.VolumeTypeVolume:\n\t\t\t\tif volume.Source != \"\" { // non anonymous volumes\n\t\t\t\t\tif _, ok := project.Volumes[volume.Source]; !ok {\n\t\t\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined volume %s\", s.Name, volume.Source))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor _, secret := range s.Secrets {\n\t\t\tif _, ok := project.Secrets[secret.Source]; !ok {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined secret %s\", s.Name, secret.Source))\n\t\t\t}\n\t\t}\n\t\tfor _, config := range s.Configs {\n\t\t\tif _, ok := project.Configs[config.Source]; !ok {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined config %s\", s.Name, config.Source))\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/validate_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"testing\"\n\n\t\"gotest.tools/v3/assert\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n)\n\nfunc TestValidateAnonymousVolume(t *testing.T) {\n\tproject := &types.Project{\n\t\tServices: types.Services([]types.ServiceConfig{\n\t\t\t{\n\t\t\t\tName:  \"myservice\",\n\t\t\t\tImage: \"my/service\",\n\t\t\t\tVolumes: []types.ServiceVolumeConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   types.VolumeTypeVolume,\n\t\t\t\t\t\tTarget: \"/use/local\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t}\n\terr := checkConsistency(project)\n\tassert.NilError(t, err)\n}\n\nfunc TestValidateNamedVolume(t *testing.T) {\n\tproject := &types.Project{\n\t\tServices: types.Services([]types.ServiceConfig{\n\t\t\t{\n\t\t\t\tName:  \"myservice\",\n\t\t\t\tImage: \"my/service\",\n\t\t\t\tVolumes: []types.ServiceVolumeConfig{\n\t\t\t\t\t{\n\t\t\t\t\t\tType:   types.VolumeTypeVolume,\n\t\t\t\t\t\tSource: \"myVolume\",\n\t\t\t\t\t\tTarget: \"/use/local\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}),\n\t}\n\terr := checkConsistency(project)\n\tassert.Error(t, err, `service \"myservice\" refers to undefined volume myVolume: invalid compose project`)\n\n\tproject.Volumes = types.Volumes(map[string]types.VolumeConfig{\n\t\t\"myVolume\": {\n\t\t\tName: \"myVolume\",\n\t\t},\n\t})\n\terr = checkConsistency(project)\n\tassert.NilError(t, err)\n}\n\nfunc TestValidateNoBuildNoImage(t *testing.T) {\n\tproject := &types.Project{\n\t\tServices: types.Services([]types.ServiceConfig{\n\t\t\t{\n\t\t\t\tName: \"myservice\",\n\t\t\t},\n\t\t}),\n\t}\n\terr := checkConsistency(project)\n\tassert.Error(t, err, `service \"myservice\" has neither an image nor a build context specified: invalid compose project`)\n}\n\nfunc TestValidateNetworkMode(t *testing.T) {\n\tt.Run(\"network_mode service fail\", func(t *testing.T) {\n\t\tproject := &types.Project{\n\t\t\tServices: types.Services([]types.ServiceConfig{\n\t\t\t\t{\n\t\t\t\t\tName:  \"myservice1\",\n\t\t\t\t\tImage: \"scratch\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:        \"myservice2\",\n\t\t\t\t\tImage:       \"scratch\",\n\t\t\t\t\tNetworkMode: \"service:myservice1\",\n\t\t\t\t},\n\t\t\t}),\n\t\t}\n\t\terr := checkConsistency(project)\n\t\tassert.NilError(t, err)\n\t})\n\n\tt.Run(\"network_mode service fail\", func(t *testing.T) {\n\t\tproject := &types.Project{\n\t\t\tServices: types.Services([]types.ServiceConfig{\n\t\t\t\t{\n\t\t\t\t\tName:  \"myservice1\",\n\t\t\t\t\tImage: \"scratch\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:        \"myservice2\",\n\t\t\t\t\tImage:       \"scratch\",\n\t\t\t\t\tNetworkMode: \"service:nonexistentservice\",\n\t\t\t\t},\n\t\t\t}),\n\t\t}\n\t\terr := checkConsistency(project)\n\t\tassert.Error(t, err, `service \"nonexistentservice\" not found for network_mode 'service:nonexistentservice'`)\n\t})\n\n\tt.Run(\"network_mode container\", func(t *testing.T) {\n\t\tproject := &types.Project{\n\t\t\tServices: types.Services([]types.ServiceConfig{\n\t\t\t\t{\n\t\t\t\t\tName:          \"myservice1\",\n\t\t\t\t\tContainerName: \"mycontainer_name\",\n\t\t\t\t\tImage:         \"scratch\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:        \"myservice2\",\n\t\t\t\t\tImage:       \"scratch\",\n\t\t\t\t\tNetworkMode: \"container:mycontainer_name\",\n\t\t\t\t},\n\t\t\t}),\n\t\t}\n\t\terr := checkConsistency(project)\n\t\tassert.NilError(t, err)\n\t})\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/volume.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n)\n\nconst endOfSpec = rune(0)\n\n// ParseVolume parses a volume spec without any knowledge of the target platform\nfunc ParseVolume(spec string) (types.ServiceVolumeConfig, error) {\n\tvolume := types.ServiceVolumeConfig{}\n\n\tswitch len(spec) {\n\tcase 0:\n\t\treturn volume, errors.New(\"invalid empty volume spec\")\n\tcase 1, 2:\n\t\tvolume.Target = spec\n\t\tvolume.Type = string(types.VolumeTypeVolume)\n\t\treturn volume, nil\n\t}\n\n\tbuffer := []rune{}\n\tfor _, char := range spec + string(endOfSpec) {\n\t\tswitch {\n\t\tcase isWindowsDrive(buffer, char):\n\t\t\tbuffer = append(buffer, char)\n\t\tcase char == ':' || char == endOfSpec:\n\t\t\tif err := populateFieldFromBuffer(char, buffer, &volume); err != nil {\n\t\t\t\tpopulateType(&volume)\n\t\t\t\treturn volume, errors.Wrapf(err, \"invalid spec: %s\", spec)\n\t\t\t}\n\t\t\tbuffer = []rune{}\n\t\tdefault:\n\t\t\tbuffer = append(buffer, char)\n\t\t}\n\t}\n\n\tpopulateType(&volume)\n\treturn volume, nil\n}\n\nfunc isWindowsDrive(buffer []rune, char rune) bool {\n\treturn char == ':' && len(buffer) == 1 && unicode.IsLetter(buffer[0])\n}\n\nfunc populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolumeConfig) error {\n\tstrBuffer := string(buffer)\n\tswitch {\n\tcase len(buffer) == 0:\n\t\treturn errors.New(\"empty section between colons\")\n\t// Anonymous volume\n\tcase volume.Source == \"\" && char == endOfSpec:\n\t\tvolume.Target = strBuffer\n\t\treturn nil\n\tcase volume.Source == \"\":\n\t\tvolume.Source = strBuffer\n\t\treturn nil\n\tcase volume.Target == \"\":\n\t\tvolume.Target = strBuffer\n\t\treturn nil\n\tcase char == ':':\n\t\treturn errors.New(\"too many colons\")\n\t}\n\tfor _, option := range strings.Split(strBuffer, \",\") {\n\t\tswitch option {\n\t\tcase \"ro\":\n\t\t\tvolume.ReadOnly = true\n\t\tcase \"rw\":\n\t\t\tvolume.ReadOnly = false\n\t\tcase \"nocopy\":\n\t\t\tvolume.Volume = &types.ServiceVolumeVolume{NoCopy: true}\n\t\tdefault:\n\t\t\tif isBindOption(option) {\n\t\t\t\tvolume.Bind = &types.ServiceVolumeBind{Propagation: option}\n\t\t\t}\n\t\t\t// ignore unknown options\n\t\t}\n\t}\n\treturn nil\n}\n\nvar Propagations = []string{\n\ttypes.PropagationRPrivate,\n\ttypes.PropagationPrivate,\n\ttypes.PropagationRShared,\n\ttypes.PropagationShared,\n\ttypes.PropagationRSlave,\n\ttypes.PropagationSlave,\n}\n\nfunc isBindOption(option string) bool {\n\tfor _, propagation := range Propagations {\n\t\tif option == propagation {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc populateType(volume *types.ServiceVolumeConfig) {\n\tif isFilePath(volume.Source) {\n\t\tvolume.Type = types.VolumeTypeBind\n\t\tif volume.Bind == nil {\n\t\t\tvolume.Bind = &types.ServiceVolumeBind{}\n\t\t}\n\t\t// For backward compatibility with docker-compose legacy, using short notation involves\n\t\t// bind will create missing host path\n\t\tvolume.Bind.CreateHostPath = true\n\t} else {\n\t\tvolume.Type = types.VolumeTypeVolume\n\t\tif volume.Volume == nil {\n\t\t\tvolume.Volume = &types.ServiceVolumeVolume{}\n\t\t}\n\t}\n}\n\nfunc isFilePath(source string) bool {\n\tif source == \"\" {\n\t\treturn false\n\t}\n\tswitch source[0] {\n\tcase '.', '/', '~':\n\t\treturn true\n\t}\n\n\t// windows named pipes\n\tif strings.HasPrefix(source, `\\\\`) {\n\t\treturn true\n\t}\n\n\tfirst, nextIndex := utf8.DecodeRuneInString(source)\n\treturn isWindowsDrive([]rune{first}, rune(source[nextIndex]))\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/volume_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"gotest.tools/v3/assert\"\n\tis \"gotest.tools/v3/assert/cmp\"\n)\n\nfunc TestParseVolumeAnonymousVolume(t *testing.T) {\n\tfor _, path := range []string{\"/path\", \"/path/foo\"} {\n\t\tvolume, err := ParseVolume(path)\n\t\texpected := types.ServiceVolumeConfig{Type: \"volume\", Target: path, Volume: &types.ServiceVolumeVolume{}}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.DeepEqual(expected, volume))\n\t}\n}\n\nfunc TestParseVolumeAnonymousVolumeWindows(t *testing.T) {\n\tfor _, path := range []string{\"C:\\\\path\", \"Z:\\\\path\\\\foo\"} {\n\t\tvolume, err := ParseVolume(path)\n\t\texpected := types.ServiceVolumeConfig{Type: \"volume\", Target: path, Volume: &types.ServiceVolumeVolume{}}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.DeepEqual(expected, volume))\n\t}\n}\n\nfunc TestParseVolumeTooManyColons(t *testing.T) {\n\t_, err := ParseVolume(\"/foo:/foo:ro:foo\")\n\tassert.Error(t, err, \"invalid spec: /foo:/foo:ro:foo: too many colons\")\n}\n\nfunc TestParseVolumeShortVolumes(t *testing.T) {\n\tfor _, path := range []string{\".\", \"/a\"} {\n\t\tvolume, err := ParseVolume(path)\n\t\texpected := types.ServiceVolumeConfig{Type: \"volume\", Target: path}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.DeepEqual(expected, volume))\n\t}\n}\n\nfunc TestParseVolumeMissingSource(t *testing.T) {\n\tfor _, spec := range []string{\":foo\", \"/foo::ro\"} {\n\t\t_, err := ParseVolume(spec)\n\t\tassert.ErrorContains(t, err, \"empty section between colons\")\n\t}\n}\n\nfunc TestParseVolumeBindMount(t *testing.T) {\n\tfor _, path := range []string{\"./foo\", \"~/thing\", \"../other\", \"/foo\", \"/home/user\"} {\n\t\tvolume, err := ParseVolume(path + \":/target\")\n\t\texpected := types.ServiceVolumeConfig{\n\t\t\tType:   \"bind\",\n\t\t\tSource: path,\n\t\t\tTarget: \"/target\",\n\t\t\tBind:   &types.ServiceVolumeBind{CreateHostPath: true},\n\t\t}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.DeepEqual(expected, volume))\n\t}\n}\n\nfunc TestParseVolumeRelativeBindMountWindows(t *testing.T) {\n\tfor _, path := range []string{\n\t\t\"./foo\",\n\t\t\"~/thing\",\n\t\t\"../other\",\n\t\t\"D:\\\\path\", \"/home/user\",\n\t} {\n\t\tvolume, err := ParseVolume(path + \":d:\\\\target\")\n\t\texpected := types.ServiceVolumeConfig{\n\t\t\tType:   \"bind\",\n\t\t\tSource: path,\n\t\t\tTarget: \"d:\\\\target\",\n\t\t\tBind:   &types.ServiceVolumeBind{CreateHostPath: true},\n\t\t}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.DeepEqual(expected, volume))\n\t}\n}\n\nfunc TestParseVolumeWithBindOptions(t *testing.T) {\n\tvolume, err := ParseVolume(\"/source:/target:slave\")\n\texpected := types.ServiceVolumeConfig{\n\t\tType:   \"bind\",\n\t\tSource: \"/source\",\n\t\tTarget: \"/target\",\n\t\tBind: &types.ServiceVolumeBind{\n\t\t\tCreateHostPath: true,\n\t\t\tPropagation:    \"slave\",\n\t\t},\n\t}\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(expected, volume))\n}\n\nfunc TestParseVolumeWithBindOptionsWindows(t *testing.T) {\n\tvolume, err := ParseVolume(\"C:\\\\source\\\\foo:D:\\\\target:ro,rprivate\")\n\texpected := types.ServiceVolumeConfig{\n\t\tType:     \"bind\",\n\t\tSource:   \"C:\\\\source\\\\foo\",\n\t\tTarget:   \"D:\\\\target\",\n\t\tReadOnly: true,\n\t\tBind: &types.ServiceVolumeBind{\n\t\t\tCreateHostPath: true,\n\t\t\tPropagation:    \"rprivate\",\n\t\t},\n\t}\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(expected, volume))\n}\n\nfunc TestParseVolumeWithInvalidVolumeOptions(t *testing.T) {\n\t_, err := ParseVolume(\"name:/target:bogus\")\n\tassert.NilError(t, err)\n}\n\nfunc TestParseVolumeWithVolumeOptions(t *testing.T) {\n\tvolume, err := ParseVolume(\"name:/target:nocopy\")\n\texpected := types.ServiceVolumeConfig{\n\t\tType:   \"volume\",\n\t\tSource: \"name\",\n\t\tTarget: \"/target\",\n\t\tVolume: &types.ServiceVolumeVolume{NoCopy: true},\n\t}\n\tassert.NilError(t, err)\n\tassert.Check(t, is.DeepEqual(expected, volume))\n}\n\nfunc TestParseVolumeWithReadOnly(t *testing.T) {\n\tfor _, path := range []string{\"./foo\", \"/home/user\"} {\n\t\tvolume, err := ParseVolume(path + \":/target:ro\")\n\t\texpected := types.ServiceVolumeConfig{\n\t\t\tType:     \"bind\",\n\t\t\tSource:   path,\n\t\t\tTarget:   \"/target\",\n\t\t\tReadOnly: true,\n\t\t\tBind:     &types.ServiceVolumeBind{CreateHostPath: true},\n\t\t}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.DeepEqual(expected, volume))\n\t}\n}\n\nfunc TestParseVolumeWithRW(t *testing.T) {\n\tfor _, path := range []string{\"./foo\", \"/home/user\"} {\n\t\tvolume, err := ParseVolume(path + \":/target:rw\")\n\t\texpected := types.ServiceVolumeConfig{\n\t\t\tType:     \"bind\",\n\t\t\tSource:   path,\n\t\t\tTarget:   \"/target\",\n\t\t\tReadOnly: false,\n\t\t\tBind:     &types.ServiceVolumeBind{CreateHostPath: true},\n\t\t}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.DeepEqual(expected, volume))\n\t}\n}\n\nfunc TestParseVolumeWindowsNamedPipe(t *testing.T) {\n\tvolume, err := ParseVolume(`\\\\.\\pipe\\docker_engine:\\\\.\\pipe\\inside`)\n\tassert.NilError(t, err)\n\texpected := types.ServiceVolumeConfig{\n\t\tType:   \"bind\",\n\t\tSource: `\\\\.\\pipe\\docker_engine`,\n\t\tTarget: `\\\\.\\pipe\\inside`,\n\t\tBind:   &types.ServiceVolumeBind{CreateHostPath: true},\n\t}\n\tassert.Check(t, is.DeepEqual(expected, volume))\n}\n\nfunc TestIsFilePath(t *testing.T) {\n\tassert.Check(t, !isFilePath(\"a界\"))\n}\n\n// Preserve the test cases for VolumeSplitN\nfunc TestParseVolumeSplitCases(t *testing.T) {\n\tfor casenumber, x := range []struct {\n\t\tinput    string\n\t\tn        int\n\t\texpected []string\n\t}{\n\t\t{`C:\\foo:d:`, -1, []string{`C:\\foo`, `d:`}},\n\t\t{`:C:\\foo:d:`, -1, nil},\n\t\t{`/foo:/bar:ro`, 3, []string{`/foo`, `/bar`, `ro`}},\n\t\t{`/foo:/bar:ro`, 2, []string{`/foo`, `/bar:ro`}},\n\t\t{`C:\\foo\\:/foo`, -1, []string{`C:\\foo\\`, `/foo`}},\n\t\t{`d:\\`, -1, []string{`d:\\`}},\n\t\t{`d:`, -1, []string{`d:`}},\n\t\t{`d:\\path`, -1, []string{`d:\\path`}},\n\t\t{`d:\\path with space`, -1, []string{`d:\\path with space`}},\n\t\t{`d:\\pathandmode:rw`, -1, []string{`d:\\pathandmode`, `rw`}},\n\n\t\t{`c:\\:d:\\`, -1, []string{`c:\\`, `d:\\`}},\n\t\t{`c:\\windows\\:d:`, -1, []string{`c:\\windows\\`, `d:`}},\n\t\t{`c:\\windows:d:\\s p a c e`, -1, []string{`c:\\windows`, `d:\\s p a c e`}},\n\t\t{`c:\\windows:d:\\s p a c e:RW`, -1, []string{`c:\\windows`, `d:\\s p a c e`, `RW`}},\n\t\t{`c:\\program files:d:\\s p a c e i n h o s t d i r`, -1, []string{`c:\\program files`, `d:\\s p a c e i n h o s t d i r`}},\n\t\t{`0123456789name:d:`, -1, []string{`0123456789name`, `d:`}},\n\t\t{`MiXeDcAsEnAmE:d:`, -1, []string{`MiXeDcAsEnAmE`, `d:`}},\n\t\t{`name:D:`, -1, []string{`name`, `D:`}},\n\t\t{`name:D::rW`, -1, []string{`name`, `D:`, `rW`}},\n\t\t{`name:D::RW`, -1, []string{`name`, `D:`, `RW`}},\n\n\t\t{`c:/:d:/forward/slashes/are/good/too`, -1, []string{`c:/`, `d:/forward/slashes/are/good/too`}},\n\t\t{`c:\\Windows`, -1, []string{`c:\\Windows`}},\n\t\t{`c:\\Program Files (x86)`, -1, []string{`c:\\Program Files (x86)`}},\n\t\t{``, -1, nil},\n\t\t{`.`, -1, []string{`.`}},\n\t\t{`..\\`, -1, []string{`..\\`}},\n\t\t{`c:\\:..\\`, -1, []string{`c:\\`, `..\\`}},\n\t\t{`c:\\:d:\\:xyzzy`, -1, []string{`c:\\`, `d:\\`, `xyzzy`}},\n\t\t// Cover directories with one-character name\n\t\t{`/tmp/x/y:/foo/x/y`, -1, []string{`/tmp/x/y`, `/foo/x/y`}},\n\t} {\n\t\tparsed, _ := ParseVolume(x.input)\n\n\t\texpected := len(x.expected) > 1\n\t\tmsg := fmt.Sprintf(\"Case %d: %s\", casenumber, x.input)\n\t\tassert.Check(t, is.Equal(expected, parsed.Source != \"\"), msg)\n\t}\n}\n\nfunc TestParseVolumeInvalidEmptySpec(t *testing.T) {\n\t_, err := ParseVolume(\"\")\n\tassert.ErrorContains(t, err, \"invalid empty volume spec\")\n}\n\nfunc TestParseVolumeInvalidSections(t *testing.T) {\n\t_, err := ParseVolume(\"/foo::rw\")\n\tassert.ErrorContains(t, err, \"invalid spec\")\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/windows_path.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\n// 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// https://github.com/golang/go/blob/master/LICENSE\n\n// This file contains utilities to check for Windows absolute paths on Linux.\n// The code in this file was largely copied from the Golang filepath package\n// https://github.com/golang/go/blob/1d0e94b1e13d5e8a323a63cd1cc1ef95290c9c36/src/path/filepath/path_windows.go#L12-L65\n\nfunc isSlash(c uint8) bool {\n\treturn c == '\\\\' || c == '/'\n}\n\n// isAbs reports whether the path is a Windows absolute path.\nfunc isAbs(path string) (b bool) {\n\tl := volumeNameLen(path)\n\tif l == 0 {\n\t\treturn false\n\t}\n\tpath = path[l:]\n\tif path == \"\" {\n\t\treturn false\n\t}\n\treturn isSlash(path[0])\n}\n\n// volumeNameLen returns length of the leading volume name on Windows.\n// It returns 0 elsewhere.\n// nolint: gocyclo\nfunc volumeNameLen(path string) int {\n\tif len(path) < 2 {\n\t\treturn 0\n\t}\n\t// with drive letter\n\tc := path[0]\n\tif path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {\n\t\treturn 2\n\t}\n\t// is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx\n\tif l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&\n\t\t!isSlash(path[2]) && path[2] != '.' {\n\t\t// first, leading `\\\\` and next shouldn't be `\\`. its server name.\n\t\tfor n := 3; n < l-1; n++ {\n\t\t\t// second, next '\\' shouldn't be repeated.\n\t\t\tif isSlash(path[n]) {\n\t\t\t\tn++\n\t\t\t\t// third, following something characters. its share name.\n\t\t\t\tif !isSlash(path[n]) {\n\t\t\t\t\tif path[n] == '.' {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tfor ; n < l; n++ {\n\t\t\t\t\t\tif isSlash(path[n]) {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn n\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/windows_path_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\n// 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// https://github.com/golang/go/blob/master/LICENSE\n\n// The code in this file was copied from the Golang filepath package with some\n// small modifications to run it on non-Windows platforms.\n// https://github.com/golang/go/blob/1d0e94b1e13d5e8a323a63cd1cc1ef95290c9c36/src/path/filepath/path_test.go#L711-L763\n\nimport \"testing\"\n\ntype IsAbsTest struct {\n\tpath  string\n\tisAbs bool\n}\n\nvar isabstests = []IsAbsTest{\n\t{\"\", false},\n\t{\"/\", true},\n\t{\"/usr/bin/gcc\", true},\n\t{\"..\", false},\n\t{\"/a/../bb\", true},\n\t{\".\", false},\n\t{\"./\", false},\n\t{\"lala\", false},\n}\n\nvar winisabstests = []IsAbsTest{\n\t{`C:\\`, true},\n\t{`c\\`, false},\n\t{`c::`, false},\n\t{`c:`, false},\n\t{`/`, false},\n\t{`\\`, false},\n\t{`\\Windows`, false},\n\t{`c:a\\b`, false},\n\t{`c:\\a\\b`, true},\n\t{`c:/a/b`, true},\n\t{`\\\\host\\share\\foo`, true},\n\t{`//host/share/foo/bar`, true},\n}\n\nfunc TestIsAbs(t *testing.T) {\n\ttests := winisabstests\n\n\t// All non-windows tests should fail, because they have no volume letter.\n\tfor _, test := range isabstests {\n\t\ttests = append(tests, IsAbsTest{test.path, false})\n\t}\n\t// All non-windows test should work as intended if prefixed with volume letter.\n\tfor _, test := range isabstests {\n\t\ttests = append(tests, IsAbsTest{\"c:\" + test.path, test.isAbs})\n\t}\n\n\tfor _, test := range tests {\n\t\tif r := isAbs(test.path); r != test.isAbs {\n\t\t\tt.Errorf(\"IsAbs(%q) = %v, want %v\", test.path, r, test.isAbs)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/loader/with-version-struct_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"github.com/compose-spec/compose-go/types\"\n)\n\nfunc withVersionExampleConfig(workingDir, homeDir string) *types.Config {\n\treturn &types.Config{\n\t\tServices: withVersionServices(workingDir, homeDir),\n\t\tNetworks: withVersionNetworks(),\n\t\tVolumes:  withVersionVolumes(),\n\t}\n}\n\nfunc withVersionServices(workingDir, homeDir string) []types.ServiceConfig {\n\treturn []types.ServiceConfig{\n\t\t{\n\t\t\tName: \"web\",\n\n\t\t\tBuild: &types.BuildConfig{\n\t\t\t\tContext: \"./Dockerfile\",\n\t\t\t},\n\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\tNetworks: map[string]*types.ServiceNetworkConfig{\n\t\t\t\t\"front\":   nil,\n\t\t\t\t\"default\": nil,\n\t\t\t},\n\t\t\tVolumesFrom: []string{\"other\"},\n\t\t\tScale:       1,\n\t\t},\n\t\t{\n\t\t\tName: \"other\",\n\n\t\t\tImage:       \"busybox:1.31.0-uclibc\",\n\t\t\tCommand:     []string{\"top\"},\n\t\t\tEnvironment: types.MappingWithEquals{},\n\t\t\tVolumes: []types.ServiceVolumeConfig{\n\t\t\t\t{Target: \"/data\", Type: \"volume\", Volume: &types.ServiceVolumeVolume{}},\n\t\t\t},\n\t\t\tScale: 1,\n\t\t},\n\t}\n}\n\nfunc withVersionNetworks() map[string]types.NetworkConfig {\n\treturn map[string]types.NetworkConfig{\n\t\t\"front\": {},\n\t}\n}\n\nfunc withVersionVolumes() map[string]types.VolumeConfig {\n\treturn map[string]types.VolumeConfig{\n\t\t\"data\": {\n\t\t\tDriver: \"local\",\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/schema/compose-spec.json",
    "content": "{\n  \"$schema\": \"http://json-schema.org/draft/2019-09/schema#\",\n  \"id\": \"compose_spec.json\",\n  \"type\": \"object\",\n  \"title\": \"Compose Specification\",\n  \"description\": \"The Compose file is a YAML file defining a multi-containers based application.\",\n\n  \"properties\": {\n    \"version\": {\n      \"type\": \"string\",\n      \"description\": \"Version of the Compose specification used. Tools not implementing required version MUST reject the configuration file.\"\n    },\n\n    \"services\": {\n      \"id\": \"#/properties/services\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^[a-zA-Z0-9._-]+$\": {\n          \"$ref\": \"#/definitions/service\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n\n    \"networks\": {\n      \"id\": \"#/properties/networks\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^[a-zA-Z0-9._-]+$\": {\n          \"$ref\": \"#/definitions/network\"\n        }\n      }\n    },\n\n    \"volumes\": {\n      \"id\": \"#/properties/volumes\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^[a-zA-Z0-9._-]+$\": {\n          \"$ref\": \"#/definitions/volume\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n\n    \"secrets\": {\n      \"id\": \"#/properties/secrets\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^[a-zA-Z0-9._-]+$\": {\n          \"$ref\": \"#/definitions/secret\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n\n    \"configs\": {\n      \"id\": \"#/properties/configs\",\n      \"type\": \"object\",\n      \"patternProperties\": {\n        \"^[a-zA-Z0-9._-]+$\": {\n          \"$ref\": \"#/definitions/config\"\n        }\n      },\n      \"additionalProperties\": false\n    }\n  },\n\n  \"patternProperties\": {\"^x-\": {}},\n  \"additionalProperties\": false,\n\n  \"definitions\": {\n\n    \"service\": {\n      \"id\": \"#/definitions/service\",\n      \"type\": \"object\",\n\n      \"properties\": {\n        \"deploy\": {\"$ref\": \"#/definitions/deployment\"},\n        \"build\": {\n          \"oneOf\": [\n            {\"type\": \"string\"},\n            {\n              \"type\": \"object\",\n              \"properties\": {\n                \"context\": {\"type\": \"string\"},\n                \"dockerfile\": {\"type\": \"string\"},\n                \"args\": {\"$ref\": \"#/definitions/list_or_dict\"},\n                \"labels\": {\"$ref\": \"#/definitions/list_or_dict\"},\n                \"cache_from\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}},\n                \"network\": {\"type\": \"string\"},\n                \"target\": {\"type\": \"string\"},\n                \"shm_size\": {\"type\": [\"integer\", \"string\"]},\n                \"extra_hosts\": {\"$ref\": \"#/definitions/list_or_dict\"},\n                \"isolation\": {\"type\": \"string\"}\n              },\n              \"additionalProperties\": false,\n              \"patternProperties\": {\"^x-\": {}}\n            }\n          ]\n        },\n        \"blkio_config\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"device_read_bps\": {\n              \"type\": \"array\",\n              \"items\": {\"$ref\": \"#/definitions/blkio_limit\"}\n            },\n            \"device_read_iops\": {\n              \"type\": \"array\",\n              \"items\": {\"$ref\": \"#/definitions/blkio_limit\"}\n            },\n            \"device_write_bps\": {\n              \"type\": \"array\",\n              \"items\": {\"$ref\": \"#/definitions/blkio_limit\"}\n            },\n            \"device_write_iops\": {\n              \"type\": \"array\",\n              \"items\": {\"$ref\": \"#/definitions/blkio_limit\"}\n            },\n            \"weight\": {\"type\": \"integer\"},\n            \"weight_device\": {\n              \"type\": \"array\",\n              \"items\": {\"$ref\": \"#/definitions/blkio_weight\"}\n            }\n          },\n          \"additionalProperties\": false\n        },\n        \"cap_add\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}, \"uniqueItems\": true},\n        \"cap_drop\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}, \"uniqueItems\": true},\n        \"cgroup_parent\": {\"type\": \"string\"},\n        \"command\": {\n          \"oneOf\": [\n            {\"type\": \"string\"},\n            {\"type\": \"array\", \"items\": {\"type\": \"string\"}}\n          ]\n        },\n        \"configs\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\"type\": \"string\"},\n              {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"source\": {\"type\": \"string\"},\n                  \"target\": {\"type\": \"string\"},\n                  \"uid\": {\"type\": \"string\"},\n                  \"gid\": {\"type\": \"string\"},\n                  \"mode\": {\"type\": \"number\"}\n                },\n                \"additionalProperties\": false,\n                \"patternProperties\": {\"^x-\": {}}\n              }\n            ]\n          }\n        },\n        \"container_name\": {\"type\": \"string\"},\n        \"cpu_count\": {\"type\": \"integer\", \"minimum\": 0},\n        \"cpu_percent\": {\"type\": \"integer\", \"minimum\": 0, \"maximum\": 100},\n        \"cpu_shares\": {\"type\": [\"number\", \"string\"]},\n        \"cpu_quota\": {\"type\": [\"number\", \"string\"]},\n        \"cpu_period\": {\"type\": [\"number\", \"string\"]},\n        \"cpu_rt_period\": {\"type\": [\"number\", \"string\"]},\n        \"cpu_rt_runtime\": {\"type\": [\"number\", \"string\"]},\n        \"cpus\": {\"type\": [\"number\", \"string\"]},\n        \"cpuset\": {\"type\": \"string\"},\n        \"credential_spec\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"config\": {\"type\": \"string\"},\n            \"file\": {\"type\": \"string\"},\n            \"registry\": {\"type\": \"string\"}\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"depends_on\": {\n          \"oneOf\": [\n            {\"$ref\": \"#/definitions/list_of_strings\"},\n            {\n              \"type\": \"object\",\n              \"additionalProperties\": false,\n              \"patternProperties\": {\n                \"^[a-zA-Z0-9._-]+$\": {\n                  \"type\": \"object\",\n                  \"additionalProperties\": false,\n                  \"properties\": {\n                    \"condition\": {\n                      \"type\": \"string\",\n                      \"enum\": [\"service_started\", \"service_healthy\", \"service_completed_successfully\"]\n                    }\n                  },\n                  \"required\": [\"condition\"]\n                }\n              }\n            }\n          ]\n        },\n        \"device_cgroup_rules\": {\"$ref\": \"#/definitions/list_of_strings\"},\n        \"devices\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}, \"uniqueItems\": true},\n        \"dns\": {\"$ref\": \"#/definitions/string_or_list\"},\n        \"dns_opt\": {\"type\": \"array\",\"items\": {\"type\": \"string\"}, \"uniqueItems\": true},\n        \"dns_search\": {\"$ref\": \"#/definitions/string_or_list\"},\n        \"domainname\": {\"type\": \"string\"},\n        \"entrypoint\": {\n          \"oneOf\": [\n            {\"type\": \"string\"},\n            {\"type\": \"array\", \"items\": {\"type\": \"string\"}}\n          ]\n        },\n        \"env_file\": {\"$ref\": \"#/definitions/string_or_list\"},\n        \"environment\": {\"$ref\": \"#/definitions/list_or_dict\"},\n\n        \"expose\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": [\"string\", \"number\"],\n            \"format\": \"expose\"\n          },\n          \"uniqueItems\": true\n        },\n        \"extends\": {\n          \"oneOf\": [\n            {\"type\": \"string\"},\n            {\n              \"type\": \"object\",\n\n              \"properties\": {\n                \"service\": {\"type\": \"string\"},\n                \"file\": {\"type\": \"string\"}\n              },\n              \"required\": [\"service\"],\n              \"additionalProperties\": false\n            }\n          ]\n        },\n        \"external_links\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}, \"uniqueItems\": true},\n        \"extra_hosts\": {\"$ref\": \"#/definitions/list_or_dict\"},\n        \"group_add\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": [\"string\", \"number\"]\n          },\n          \"uniqueItems\": true\n        },\n        \"healthcheck\": {\"$ref\": \"#/definitions/healthcheck\"},\n        \"hostname\": {\"type\": \"string\"},\n        \"image\": {\"type\": \"string\"},\n        \"init\": {\"type\": \"boolean\"},\n        \"ipc\": {\"type\": \"string\"},\n        \"isolation\": {\"type\": \"string\"},\n        \"labels\": {\"$ref\": \"#/definitions/list_or_dict\"},\n        \"links\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}, \"uniqueItems\": true},\n        \"logging\": {\n          \"type\": \"object\",\n\n          \"properties\": {\n            \"driver\": {\"type\": \"string\"},\n            \"options\": {\n              \"type\": \"object\",\n              \"patternProperties\": {\n                \"^.+$\": {\"type\": [\"string\", \"number\", \"null\"]}\n              }\n            }\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"mac_address\": {\"type\": \"string\"},\n        \"mem_limit\": {\"type\": [\"number\", \"string\"]},\n        \"mem_reservation\": {\"type\": [\"string\", \"integer\"]},\n        \"mem_swappiness\": {\"type\": \"integer\"},\n        \"memswap_limit\": {\"type\": [\"number\", \"string\"]},\n        \"network_mode\": {\"type\": \"string\"},\n        \"networks\": {\n          \"oneOf\": [\n            {\"$ref\": \"#/definitions/list_of_strings\"},\n            {\n              \"type\": \"object\",\n              \"patternProperties\": {\n                \"^[a-zA-Z0-9._-]+$\": {\n                  \"oneOf\": [\n                    {\n                      \"type\": \"object\",\n                      \"properties\": {\n                        \"aliases\": {\"$ref\": \"#/definitions/list_of_strings\"},\n                        \"ipv4_address\": {\"type\": \"string\"},\n                        \"ipv6_address\": {\"type\": \"string\"},\n                        \"link_local_ips\": {\"$ref\": \"#/definitions/list_of_strings\"},\n                        \"priority\": {\"type\": \"number\"}\n                      },\n                      \"additionalProperties\": false,\n                      \"patternProperties\": {\"^x-\": {}}\n                    },\n                    {\"type\": \"null\"}\n                  ]\n                }\n              },\n              \"additionalProperties\": false\n            }\n          ]\n        },\n        \"oom_kill_disable\": {\"type\": \"boolean\"},\n        \"oom_score_adj\": {\"type\": \"integer\", \"minimum\": -1000, \"maximum\": 1000},\n        \"pid\": {\"type\": [\"string\", \"null\"]},\n        \"pids_limit\": {\"type\": [\"number\", \"string\"]},\n        \"platform\": {\"type\": \"string\"},\n        \"ports\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\"type\": \"number\", \"format\": \"ports\"},\n              {\"type\": \"string\", \"format\": \"ports\"},\n              {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"mode\": {\"type\": \"string\"},\n                  \"host_ip\": {\"type\": \"string\"},\n                  \"target\": {\"type\": \"integer\"},\n                  \"published\": {\"type\": \"integer\"},\n                  \"protocol\": {\"type\": \"string\"}\n                },\n                \"additionalProperties\": false,\n                \"patternProperties\": {\"^x-\": {}}\n              }\n            ]\n          },\n          \"uniqueItems\": true\n        },\n        \"privileged\": {\"type\": \"boolean\"},\n        \"profiles\": {\"$ref\": \"#/definitions/list_of_strings\"},\n        \"pull_policy\": {\"type\": \"string\", \"enum\": [\n          \"always\", \"never\", \"if_not_present\", \"build\"\n        ]},\n        \"read_only\": {\"type\": \"boolean\"},\n        \"restart\": {\"type\": \"string\"},\n        \"runtime\": {\n          \"type\": \"string\"\n        },\n        \"scale\": {\n          \"type\": \"integer\"\n        },\n        \"security_opt\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}, \"uniqueItems\": true},\n        \"shm_size\": {\"type\": [\"number\", \"string\"]},\n        \"secrets\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\"type\": \"string\"},\n              {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"source\": {\"type\": \"string\"},\n                  \"target\": {\"type\": \"string\"},\n                  \"uid\": {\"type\": \"string\"},\n                  \"gid\": {\"type\": \"string\"},\n                  \"mode\": {\"type\": \"number\"}\n                },\n                \"additionalProperties\": false,\n                \"patternProperties\": {\"^x-\": {}}\n              }\n            ]\n          }\n        },\n        \"sysctls\": {\"$ref\": \"#/definitions/list_or_dict\"},\n        \"stdin_open\": {\"type\": \"boolean\"},\n        \"stop_grace_period\": {\"type\": \"string\", \"format\": \"duration\"},\n        \"stop_signal\": {\"type\": \"string\"},\n        \"tmpfs\": {\"$ref\": \"#/definitions/string_or_list\"},\n        \"tty\": {\"type\": \"boolean\"},\n        \"ulimits\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^[a-z]+$\": {\n              \"oneOf\": [\n                {\"type\": \"integer\"},\n                {\n                  \"type\": \"object\",\n                  \"properties\": {\n                    \"hard\": {\"type\": \"integer\"},\n                    \"soft\": {\"type\": \"integer\"}\n                  },\n                  \"required\": [\"soft\", \"hard\"],\n                  \"additionalProperties\": false,\n                  \"patternProperties\": {\"^x-\": {}}\n                }\n              ]\n            }\n          }\n        },\n        \"user\": {\"type\": \"string\"},\n        \"userns_mode\": {\"type\": \"string\"},\n        \"volumes\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"oneOf\": [\n              {\"type\": \"string\"},\n              {\n                \"type\": \"object\",\n                \"required\": [\"type\"],\n                \"properties\": {\n                  \"type\": {\"type\": \"string\"},\n                  \"source\": {\"type\": \"string\"},\n                  \"target\": {\"type\": \"string\"},\n                  \"read_only\": {\"type\": \"boolean\"},\n                  \"consistency\": {\"type\": \"string\"},\n                  \"bind\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"propagation\": {\"type\": \"string\"},\n                      \"create_host_path\": {\"type\": \"boolean\"}\n                    },\n                    \"additionalProperties\": false,\n                    \"patternProperties\": {\"^x-\": {}}\n                  },\n                  \"volume\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"nocopy\": {\"type\": \"boolean\"}\n                    },\n                    \"additionalProperties\": false,\n                    \"patternProperties\": {\"^x-\": {}}\n                  },\n                  \"tmpfs\": {\n                    \"type\": \"object\",\n                    \"properties\": {\n                      \"size\": {\n                        \"type\": \"integer\",\n                        \"minimum\": 0\n                      }\n                    },\n                    \"additionalProperties\": false,\n                    \"patternProperties\": {\"^x-\": {}}\n                  }\n                },\n                \"additionalProperties\": false,\n                \"patternProperties\": {\"^x-\": {}}\n              }\n            ]\n          },\n          \"uniqueItems\": true\n        },\n        \"volumes_from\": {\n          \"type\": \"array\",\n          \"items\": {\"type\": \"string\"},\n          \"uniqueItems\": true\n        },\n        \"working_dir\": {\"type\": \"string\"}\n      },\n      \"patternProperties\": {\"^x-\": {}},\n      \"additionalProperties\": false\n    },\n\n    \"healthcheck\": {\n      \"id\": \"#/definitions/healthcheck\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"disable\": {\"type\": \"boolean\"},\n        \"interval\": {\"type\": \"string\", \"format\": \"duration\"},\n        \"retries\": {\"type\": \"number\"},\n        \"test\": {\n          \"oneOf\": [\n            {\"type\": \"string\"},\n            {\"type\": \"array\", \"items\": {\"type\": \"string\"}}\n          ]\n        },\n        \"timeout\": {\"type\": \"string\", \"format\": \"duration\"},\n        \"start_period\": {\"type\": \"string\", \"format\": \"duration\"}\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\"^x-\": {}}\n    },\n    \"deployment\": {\n      \"id\": \"#/definitions/deployment\",\n      \"type\": [\"object\", \"null\"],\n      \"properties\": {\n        \"mode\": {\"type\": \"string\"},\n        \"endpoint_mode\": {\"type\": \"string\"},\n        \"replicas\": {\"type\": \"integer\"},\n        \"labels\": {\"$ref\": \"#/definitions/list_or_dict\"},\n        \"rollback_config\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"parallelism\": {\"type\": \"integer\"},\n            \"delay\": {\"type\": \"string\", \"format\": \"duration\"},\n            \"failure_action\": {\"type\": \"string\"},\n            \"monitor\": {\"type\": \"string\", \"format\": \"duration\"},\n            \"max_failure_ratio\": {\"type\": \"number\"},\n            \"order\": {\"type\": \"string\", \"enum\": [\n              \"start-first\", \"stop-first\"\n            ]}\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"update_config\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"parallelism\": {\"type\": \"integer\"},\n            \"delay\": {\"type\": \"string\", \"format\": \"duration\"},\n            \"failure_action\": {\"type\": \"string\"},\n            \"monitor\": {\"type\": \"string\", \"format\": \"duration\"},\n            \"max_failure_ratio\": {\"type\": \"number\"},\n            \"order\": {\"type\": \"string\", \"enum\": [\n              \"start-first\", \"stop-first\"\n            ]}\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"resources\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"limits\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"cpus\": {\"type\": [\"number\", \"string\"]},\n                \"memory\": {\"type\": \"string\"}\n              },\n              \"additionalProperties\": false,\n              \"patternProperties\": {\"^x-\": {}}\n            },\n            \"reservations\": {\n              \"type\": \"object\",\n              \"properties\": {\n                \"cpus\": {\"type\": [\"number\", \"string\"]},\n                \"memory\": {\"type\": \"string\"},\n                \"generic_resources\": {\"$ref\": \"#/definitions/generic_resources\"},\n                \"devices\": {\"$ref\": \"#/definitions/devices\"}\n              },\n              \"additionalProperties\": false,\n              \"patternProperties\": {\"^x-\": {}}\n            }\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"restart_policy\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"condition\": {\"type\": \"string\"},\n            \"delay\": {\"type\": \"string\", \"format\": \"duration\"},\n            \"max_attempts\": {\"type\": \"integer\"},\n            \"window\": {\"type\": \"string\", \"format\": \"duration\"}\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"placement\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"constraints\": {\"type\": \"array\", \"items\": {\"type\": \"string\"}},\n            \"preferences\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"spread\": {\"type\": \"string\"}\n                },\n                \"additionalProperties\": false,\n                \"patternProperties\": {\"^x-\": {}}\n              }\n            },\n            \"max_replicas_per_node\": {\"type\": \"integer\"}\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        }\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\"^x-\": {}}\n    },\n\n    \"generic_resources\": {\n      \"id\": \"#/definitions/generic_resources\",\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"discrete_resource_spec\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"kind\": {\"type\": \"string\"},\n              \"value\": {\"type\": \"number\"}\n            },\n            \"additionalProperties\": false,\n            \"patternProperties\": {\"^x-\": {}}\n          }\n        },\n        \"additionalProperties\": false,\n        \"patternProperties\": {\"^x-\": {}}\n      }\n    },\n\n    \"devices\": {\n      \"id\": \"#/definitions/devices\",\n      \"type\": \"array\",\n      \"items\": {\n        \"type\": \"object\",\n        \"properties\": {\n          \"capabilities\": {\"$ref\": \"#/definitions/list_of_strings\"},\n          \"count\": {\"type\": [\"string\", \"integer\"]},\n          \"device_ids\": {\"$ref\": \"#/definitions/list_of_strings\"},\n          \"driver\":{\"type\": \"string\"},\n          \"options\":{\"$ref\": \"#/definitions/list_or_dict\"}\n        },\n        \"additionalProperties\": false,\n        \"patternProperties\": {\"^x-\": {}}\n      }\n    },\n\n    \"network\": {\n      \"id\": \"#/definitions/network\",\n      \"type\": [\"object\", \"null\"],\n      \"properties\": {\n        \"name\": {\"type\": \"string\"},\n        \"driver\": {\"type\": \"string\"},\n        \"driver_opts\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^.+$\": {\"type\": [\"string\", \"number\"]}\n          }\n        },\n        \"ipam\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"driver\": {\"type\": \"string\"},\n            \"config\": {\n              \"type\": \"array\",\n              \"items\": {\n                \"type\": \"object\",\n                \"properties\": {\n                  \"subnet\": {\"type\": \"string\", \"format\": \"subnet_ip_address\"},\n                  \"ip_range\": {\"type\": \"string\"},\n                  \"gateway\": {\"type\": \"string\"},\n                  \"aux_addresses\": {\n                    \"type\": \"object\",\n                    \"additionalProperties\": false,\n                    \"patternProperties\": {\"^.+$\": {\"type\": \"string\"}}\n                  }\n                },\n                \"additionalProperties\": false,\n                \"patternProperties\": {\"^x-\": {}}\n              }\n            },\n            \"options\": {\n              \"type\": \"object\",\n              \"additionalProperties\": false,\n              \"patternProperties\": {\"^.+$\": {\"type\": \"string\"}}\n            }\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"external\": {\n          \"type\": [\"boolean\", \"object\"],\n          \"properties\": {\n            \"name\": {\n              \"deprecated\": true,\n              \"type\": \"string\"\n            }\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"internal\": {\"type\": \"boolean\"},\n        \"enable_ipv6\": {\"type\": \"boolean\"},\n        \"attachable\": {\"type\": \"boolean\"},\n        \"labels\": {\"$ref\": \"#/definitions/list_or_dict\"}\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\"^x-\": {}}\n    },\n\n    \"volume\": {\n      \"id\": \"#/definitions/volume\",\n      \"type\": [\"object\", \"null\"],\n      \"properties\": {\n        \"name\": {\"type\": \"string\"},\n        \"driver\": {\"type\": \"string\"},\n        \"driver_opts\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^.+$\": {\"type\": [\"string\", \"number\"]}\n          }\n        },\n        \"external\": {\n          \"type\": [\"boolean\", \"object\"],\n          \"properties\": {\n            \"name\": {\n              \"deprecated\": true,\n              \"type\": \"string\"\n            }\n          },\n          \"additionalProperties\": false,\n          \"patternProperties\": {\"^x-\": {}}\n        },\n        \"labels\": {\"$ref\": \"#/definitions/list_or_dict\"}\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\"^x-\": {}}\n    },\n\n    \"secret\": {\n      \"id\": \"#/definitions/secret\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\"type\": \"string\"},\n        \"file\": {\"type\": \"string\"},\n        \"external\": {\n          \"type\": [\"boolean\", \"object\"],\n          \"properties\": {\n            \"name\": {\"type\": \"string\"}\n          }\n        },\n        \"labels\": {\"$ref\": \"#/definitions/list_or_dict\"},\n        \"driver\": {\"type\": \"string\"},\n        \"driver_opts\": {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \"^.+$\": {\"type\": [\"string\", \"number\"]}\n          }\n        },\n        \"template_driver\": {\"type\": \"string\"}\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\"^x-\": {}}\n    },\n\n    \"config\": {\n      \"id\": \"#/definitions/config\",\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {\"type\": \"string\"},\n        \"file\": {\"type\": \"string\"},\n        \"external\": {\n          \"type\": [\"boolean\", \"object\"],\n          \"properties\": {\n            \"name\": {\n              \"deprecated\": true,\n              \"type\": \"string\"\n            }\n          }\n        },\n        \"labels\": {\"$ref\": \"#/definitions/list_or_dict\"},\n        \"template_driver\": {\"type\": \"string\"}\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\"^x-\": {}}\n    },\n\n    \"string_or_list\": {\n      \"oneOf\": [\n        {\"type\": \"string\"},\n        {\"$ref\": \"#/definitions/list_of_strings\"}\n      ]\n    },\n\n    \"list_of_strings\": {\n      \"type\": \"array\",\n      \"items\": {\"type\": \"string\"},\n      \"uniqueItems\": true\n    },\n\n    \"list_or_dict\": {\n      \"oneOf\": [\n        {\n          \"type\": \"object\",\n          \"patternProperties\": {\n            \".+\": {\n              \"type\": [\"string\", \"number\", \"boolean\", \"null\"]\n            }\n          },\n          \"additionalProperties\": false\n        },\n        {\"type\": \"array\", \"items\": {\"type\": \"string\"}, \"uniqueItems\": true}\n      ]\n    },\n\n    \"blkio_limit\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"path\": {\"type\": \"string\"},\n        \"rate\": {\"type\": [\"integer\", \"string\"]}\n      },\n      \"additionalProperties\": false\n    },\n    \"blkio_weight\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"path\": {\"type\": \"string\"},\n        \"weight\": {\"type\": \"integer\"}\n      },\n      \"additionalProperties\": false\n    },\n\n    \"constraints\": {\n      \"service\": {\n        \"id\": \"#/definitions/constraints/service\",\n        \"anyOf\": [\n          {\"required\": [\"build\"]},\n          {\"required\": [\"image\"]}\n        ],\n        \"properties\": {\n          \"build\": {\n            \"required\": [\"context\"]\n          }\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "pkg/third_party/compose-go/schema/schema.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage schema\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/xeipuuv/gojsonschema\"\n\n\t// Enable support for embedded static resources\n\t_ \"embed\"\n)\n\nconst (\n\tdefaultVersion = \"1.0\"\n\tversionField   = \"version\"\n)\n\ntype portsFormatChecker struct{}\n\nfunc (checker portsFormatChecker) IsFormat(input interface{}) bool {\n\t// TODO: implement this\n\treturn true\n}\n\ntype durationFormatChecker struct{}\n\nfunc (checker durationFormatChecker) IsFormat(input interface{}) bool {\n\tvalue, ok := input.(string)\n\tif !ok {\n\t\treturn false\n\t}\n\t_, err := time.ParseDuration(value)\n\treturn err == nil\n}\n\nfunc init() {\n\tgojsonschema.FormatCheckers.Add(\"expose\", portsFormatChecker{})\n\tgojsonschema.FormatCheckers.Add(\"ports\", portsFormatChecker{})\n\tgojsonschema.FormatCheckers.Add(\"duration\", durationFormatChecker{})\n}\n\n// Schema is the compose-spec JSON schema\n//\n//go:embed compose-spec.json\nvar Schema string\n\n// Validate uses the jsonschema to validate the configuration\nfunc Validate(config map[string]interface{}) error {\n\tschemaLoader := gojsonschema.NewStringLoader(Schema)\n\tdataLoader := gojsonschema.NewGoLoader(config)\n\n\tresult, err := gojsonschema.Validate(schemaLoader, dataLoader)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !result.Valid() {\n\t\treturn toError(result)\n\t}\n\n\treturn nil\n}\n\nfunc toError(result *gojsonschema.Result) error {\n\terr := getMostSpecificError(result.Errors())\n\treturn err\n}\n\nconst (\n\tjsonschemaOneOf = \"number_one_of\"\n\tjsonschemaAnyOf = \"number_any_of\"\n)\n\nfunc getDescription(err validationError) string {\n\tswitch err.parent.Type() {\n\tcase \"invalid_type\":\n\t\tif expectedType, ok := err.parent.Details()[\"expected\"].(string); ok {\n\t\t\treturn fmt.Sprintf(\"must be a %s\", humanReadableType(expectedType))\n\t\t}\n\tcase jsonschemaOneOf, jsonschemaAnyOf:\n\t\tif err.child == nil {\n\t\t\treturn err.parent.Description()\n\t\t}\n\t\treturn err.child.Description()\n\t}\n\treturn err.parent.Description()\n}\n\nfunc humanReadableType(definition string) string {\n\tif definition[0:1] == \"[\" {\n\t\tallTypes := strings.Split(definition[1:len(definition)-1], \",\")\n\t\tfor i, t := range allTypes {\n\t\t\tallTypes[i] = humanReadableType(t)\n\t\t}\n\t\treturn fmt.Sprintf(\n\t\t\t\"%s or %s\",\n\t\t\tstrings.Join(allTypes[0:len(allTypes)-1], \", \"),\n\t\t\tallTypes[len(allTypes)-1],\n\t\t)\n\t}\n\tif definition == \"object\" {\n\t\treturn \"mapping\"\n\t}\n\tif definition == \"array\" {\n\t\treturn \"list\"\n\t}\n\treturn definition\n}\n\ntype validationError struct {\n\tparent gojsonschema.ResultError\n\tchild  gojsonschema.ResultError\n}\n\nfunc (err validationError) Error() string {\n\tdescription := getDescription(err)\n\treturn fmt.Sprintf(\"%s %s\", err.parent.Field(), description)\n}\n\nfunc getMostSpecificError(errors []gojsonschema.ResultError) validationError {\n\tmostSpecificError := 0\n\tfor i, err := range errors {\n\t\tif specificity(err) > specificity(errors[mostSpecificError]) {\n\t\t\tmostSpecificError = i\n\t\t\tcontinue\n\t\t}\n\n\t\tif specificity(err) == specificity(errors[mostSpecificError]) {\n\t\t\t// Invalid type errors win in a tie-breaker for most specific field name\n\t\t\tif err.Type() == \"invalid_type\" && errors[mostSpecificError].Type() != \"invalid_type\" {\n\t\t\t\tmostSpecificError = i\n\t\t\t}\n\t\t}\n\t}\n\n\tif mostSpecificError+1 == len(errors) {\n\t\treturn validationError{parent: errors[mostSpecificError]}\n\t}\n\n\tswitch errors[mostSpecificError].Type() {\n\tcase \"number_one_of\", \"number_any_of\":\n\t\treturn validationError{\n\t\t\tparent: errors[mostSpecificError],\n\t\t\tchild:  errors[mostSpecificError+1],\n\t\t}\n\tdefault:\n\t\treturn validationError{parent: errors[mostSpecificError]}\n\t}\n}\n\nfunc specificity(err gojsonschema.ResultError) int {\n\treturn len(strings.Split(err.Field(), \".\"))\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/schema/schema_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage schema\n\nimport (\n\t\"testing\"\n\n\t\"gotest.tools/v3/assert\"\n)\n\ntype dict map[string]interface{}\n\nfunc TestValidate(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\": \"busybox\",\n\t\t\t},\n\t\t},\n\t}\n\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateUndefinedTopLevelOption(t *testing.T) {\n\tconfig := dict{\n\t\t\"helicopters\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\": \"busybox\",\n\t\t\t},\n\t\t},\n\t}\n\n\terr := Validate(config)\n\tassert.ErrorContains(t, err, \"Additional property helicopters is not allowed\")\n}\n\nfunc TestValidateAllowsXTopLevelFields(t *testing.T) {\n\tconfig := dict{\n\t\t\"x-extra-stuff\": dict{},\n\t}\n\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateAllowsXFields(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"bar\": dict{\n\t\t\t\t\"x-extra-stuff\": dict{},\n\t\t\t},\n\t\t},\n\t\t\"volumes\": dict{\n\t\t\t\"bar\": dict{\n\t\t\t\t\"x-extra-stuff\": dict{},\n\t\t\t},\n\t\t},\n\t\t\"networks\": dict{\n\t\t\t\"bar\": dict{\n\t\t\t\t\"x-extra-stuff\": dict{},\n\t\t\t},\n\t\t},\n\t\t\"configs\": dict{\n\t\t\t\"bar\": dict{\n\t\t\t\t\"x-extra-stuff\": dict{},\n\t\t\t},\n\t\t},\n\t\t\"secrets\": dict{\n\t\t\t\"bar\": dict{\n\t\t\t\t\"x-extra-stuff\": dict{},\n\t\t\t},\n\t\t},\n\t}\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateSecretConfigNames(t *testing.T) {\n\tconfig := dict{\n\t\t\"configs\": dict{\n\t\t\t\"bar\": dict{\n\t\t\t\t\"name\": \"foobar\",\n\t\t\t},\n\t\t},\n\t\t\"secrets\": dict{\n\t\t\t\"baz\": dict{\n\t\t\t\t\"name\": \"foobaz\",\n\t\t\t},\n\t\t},\n\t}\n\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\ntype array []interface{}\n\nfunc TestValidatePlacement(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\": \"busybox\",\n\t\t\t\t\"deploy\": dict{\n\t\t\t\t\t\"placement\": dict{\n\t\t\t\t\t\t\"preferences\": array{\n\t\t\t\t\t\t\tdict{\n\t\t\t\t\t\t\t\t\"spread\": \"node.labels.az\",\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},\n\t}\n\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateIsolation(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\":     \"busybox\",\n\t\t\t\t\"isolation\": \"some-isolation-value\",\n\t\t\t},\n\t\t},\n\t}\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateRollbackConfig(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\": \"busybox\",\n\t\t\t\t\"deploy\": dict{\n\t\t\t\t\t\"rollback_config\": dict{\n\t\t\t\t\t\t\"parallelism\": 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateRollbackConfigWithOrder(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\": \"busybox\",\n\t\t\t\t\"deploy\": dict{\n\t\t\t\t\t\"rollback_config\": dict{\n\t\t\t\t\t\t\"parallelism\": 1,\n\t\t\t\t\t\t\"order\":       \"start-first\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateRollbackConfigWithUpdateConfig(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\": \"busybox\",\n\t\t\t\t\"deploy\": dict{\n\t\t\t\t\t\"update_config\": dict{\n\t\t\t\t\t\t\"parallelism\": 1,\n\t\t\t\t\t\t\"order\":       \"start-first\",\n\t\t\t\t\t},\n\t\t\t\t\t\"rollback_config\": dict{\n\t\t\t\t\t\t\"parallelism\": 1,\n\t\t\t\t\t\t\"order\":       \"start-first\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n\nfunc TestValidateRollbackConfigWithUpdateConfigFull(t *testing.T) {\n\tconfig := dict{\n\t\t\"services\": dict{\n\t\t\t\"foo\": dict{\n\t\t\t\t\"image\": \"busybox\",\n\t\t\t\t\"deploy\": dict{\n\t\t\t\t\t\"update_config\": dict{\n\t\t\t\t\t\t\"parallelism\":    1,\n\t\t\t\t\t\t\"order\":          \"start-first\",\n\t\t\t\t\t\t\"delay\":          \"10s\",\n\t\t\t\t\t\t\"failure_action\": \"pause\",\n\t\t\t\t\t\t\"monitor\":        \"10s\",\n\t\t\t\t\t},\n\t\t\t\t\t\"rollback_config\": dict{\n\t\t\t\t\t\t\"parallelism\":    1,\n\t\t\t\t\t\t\"order\":          \"start-first\",\n\t\t\t\t\t\t\"delay\":          \"10s\",\n\t\t\t\t\t\t\"failure_action\": \"pause\",\n\t\t\t\t\t\t\"monitor\":        \"10s\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\n\tassert.NilError(t, Validate(config))\n\tassert.NilError(t, Validate(config))\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/scripts/validate/fileheader",
    "content": "#!/usr/bin/env bash\n\n#   Copyright The Compose Specification Authors.\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#       http://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\n\nset -eu -o pipefail\n\nif ! command -v ltag; then\n    >&2 echo \"ERROR: ltag not found. Install with:\"\n    >&2 echo \"    go get -u github.com/kunalkushwaha/ltag\"\n    exit 1\nfi\n\nBASEPATH=\"${1-}\"\n\nltag -t \"${BASEPATH}scripts/validate/template\" --excludes \"validate\" --check -v\n"
  },
  {
    "path": "pkg/third_party/compose-go/scripts/validate/template/bash.txt",
    "content": "#   Copyright 2020 The Compose Specification Authors.\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#       http://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\n"
  },
  {
    "path": "pkg/third_party/compose-go/scripts/validate/template/dockerfile.txt",
    "content": "#   Copyright 2020 The Compose Specification Authors.\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#       http://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\n"
  },
  {
    "path": "pkg/third_party/compose-go/scripts/validate/template/go.txt",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\n"
  },
  {
    "path": "pkg/third_party/compose-go/scripts/validate/template/makefile.txt",
    "content": "#   Copyright 2020 The Compose Specification Authors.\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#       http://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\n"
  },
  {
    "path": "pkg/third_party/compose-go/template/template.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage template\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\nvar delimiter = \"\\\\$\"\nvar substitutionNamed = \"[_a-z][_a-z0-9]*\"\nvar substitutionBraced = \"[_a-z][_a-z0-9]*(?::?[-?][^}]*)?\"\n\nvar patternString = fmt.Sprintf(\n\t\"%s(?i:(?P<escaped>%s)|(?P<named>%s)|{(?P<braced>%s)}|(?P<invalid>))\",\n\tdelimiter, delimiter, substitutionNamed, substitutionBraced,\n)\n\nvar defaultPattern = regexp.MustCompile(patternString)\n\n// DefaultSubstituteFuncs contains the default SubstituteFunc used by the docker cli\nvar DefaultSubstituteFuncs = []SubstituteFunc{\n\tsoftDefault,\n\thardDefault,\n\trequiredNonEmpty,\n\trequired,\n}\n\n// InvalidTemplateError is returned when a variable template is not in a valid\n// format\ntype InvalidTemplateError struct {\n\tTemplate string\n}\n\nfunc (e InvalidTemplateError) Error() string {\n\treturn fmt.Sprintf(\"Invalid template: %#v\", e.Template)\n}\n\n// Mapping is a user-supplied function which maps from variable names to values.\n// Returns the value as a string and a bool indicating whether\n// the value is present, to distinguish between an empty string\n// and the absence of a value.\ntype Mapping func(string) (string, bool)\n\n// SubstituteFunc is a user-supplied function that apply substitution.\n// Returns the value as a string, a bool indicating if the function could apply\n// the substitution and an error.\ntype SubstituteFunc func(string, Mapping) (string, bool, error)\n\n// SubstituteWith substitute variables in the string with their values.\n// It accepts additional substitute function.\nfunc SubstituteWith(template string, mapping Mapping, pattern *regexp.Regexp, subsFuncs ...SubstituteFunc) (string, error) {\n\tvar err error\n\tresult := pattern.ReplaceAllStringFunc(template, func(substring string) string {\n\t\tmatches := pattern.FindStringSubmatch(substring)\n\t\tgroups := matchGroups(matches, pattern)\n\t\tif escaped := groups[\"escaped\"]; escaped != \"\" {\n\t\t\treturn escaped\n\t\t}\n\n\t\tbraced := false\n\t\tsubstitution := groups[\"named\"]\n\t\tif substitution == \"\" {\n\t\t\tsubstitution = groups[\"braced\"]\n\t\t\tbraced = true\n\t\t}\n\n\t\tif substitution == \"\" {\n\t\t\terr = &InvalidTemplateError{Template: template}\n\t\t\treturn \"\"\n\t\t}\n\n\t\tif braced {\n\t\t\tfor _, f := range subsFuncs {\n\t\t\t\tvar (\n\t\t\t\t\tvalue   string\n\t\t\t\t\tapplied bool\n\t\t\t\t)\n\t\t\t\tvalue, applied, err = f(substitution, mapping)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn \"\"\n\t\t\t\t}\n\t\t\t\tif !applied {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn value\n\t\t\t}\n\t\t}\n\n\t\tvalue, ok := mapping(substitution)\n\t\tif !ok {\n\t\t\tlogrus.Warnf(\"The %q variable is not set. Defaulting to a blank string.\", substitution)\n\t\t}\n\t\treturn value\n\t})\n\n\treturn result, err\n}\n\n// Substitute variables in the string with their values\nfunc Substitute(template string, mapping Mapping) (string, error) {\n\treturn SubstituteWith(template, mapping, defaultPattern, DefaultSubstituteFuncs...)\n}\n\n// ExtractVariables returns a map of all the variables defined in the specified\n// composefile (dict representation) and their default value if any.\nfunc ExtractVariables(configDict map[string]interface{}, pattern *regexp.Regexp) map[string]Variable {\n\tif pattern == nil {\n\t\tpattern = defaultPattern\n\t}\n\treturn recurseExtract(configDict, pattern)\n}\n\nfunc recurseExtract(value interface{}, pattern *regexp.Regexp) map[string]Variable {\n\tm := map[string]Variable{}\n\n\tswitch value := value.(type) {\n\tcase string:\n\t\tif values, is := extractVariable(value, pattern); is {\n\t\t\tfor _, v := range values {\n\t\t\t\tm[v.Name] = v\n\t\t\t}\n\t\t}\n\tcase map[string]interface{}:\n\t\tfor _, elem := range value {\n\t\t\tsubmap := recurseExtract(elem, pattern)\n\t\t\tfor key, value := range submap {\n\t\t\t\tm[key] = value\n\t\t\t}\n\t\t}\n\n\tcase []interface{}:\n\t\tfor _, elem := range value {\n\t\t\tif values, is := extractVariable(elem, pattern); is {\n\t\t\t\tfor _, v := range values {\n\t\t\t\t\tm[v.Name] = v\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn m\n}\n\ntype Variable struct {\n\tName         string\n\tDefaultValue string\n\tRequired     bool\n}\n\nfunc extractVariable(value interface{}, pattern *regexp.Regexp) ([]Variable, bool) {\n\tsValue, ok := value.(string)\n\tif !ok {\n\t\treturn []Variable{}, false\n\t}\n\tmatches := pattern.FindAllStringSubmatch(sValue, -1)\n\tif len(matches) == 0 {\n\t\treturn []Variable{}, false\n\t}\n\tvalues := []Variable{}\n\tfor _, match := range matches {\n\t\tgroups := matchGroups(match, pattern)\n\t\tif escaped := groups[\"escaped\"]; escaped != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tval := groups[\"named\"]\n\t\tif val == \"\" {\n\t\t\tval = groups[\"braced\"]\n\t\t}\n\t\tname := val\n\t\tvar defaultValue string\n\t\tvar required bool\n\t\tswitch {\n\t\tcase strings.Contains(val, \":?\"):\n\t\t\tname, _ = partition(val, \":?\")\n\t\t\trequired = true\n\t\tcase strings.Contains(val, \"?\"):\n\t\t\tname, _ = partition(val, \"?\")\n\t\t\trequired = true\n\t\tcase strings.Contains(val, \":-\"):\n\t\t\tname, defaultValue = partition(val, \":-\")\n\t\tcase strings.Contains(val, \"-\"):\n\t\t\tname, defaultValue = partition(val, \"-\")\n\t\t}\n\t\tvalues = append(values, Variable{\n\t\t\tName:         name,\n\t\t\tDefaultValue: defaultValue,\n\t\t\tRequired:     required,\n\t\t})\n\t}\n\treturn values, len(values) > 0\n}\n\n// Soft default (fall back if unset or empty)\nfunc softDefault(substitution string, mapping Mapping) (string, bool, error) {\n\tsep := \":-\"\n\tif !strings.Contains(substitution, sep) {\n\t\treturn \"\", false, nil\n\t}\n\tname, defaultValue := partition(substitution, sep)\n\tvalue, ok := mapping(name)\n\tif !ok || value == \"\" {\n\t\treturn defaultValue, true, nil\n\t}\n\treturn value, true, nil\n}\n\n// Hard default (fall back if-and-only-if empty)\nfunc hardDefault(substitution string, mapping Mapping) (string, bool, error) {\n\tsep := \"-\"\n\tif !strings.Contains(substitution, sep) {\n\t\treturn \"\", false, nil\n\t}\n\tname, defaultValue := partition(substitution, sep)\n\tvalue, ok := mapping(name)\n\tif !ok {\n\t\treturn defaultValue, true, nil\n\t}\n\treturn value, true, nil\n}\n\nfunc requiredNonEmpty(substitution string, mapping Mapping) (string, bool, error) {\n\treturn withRequired(substitution, mapping, \":?\", func(v string) bool { return v != \"\" })\n}\n\nfunc required(substitution string, mapping Mapping) (string, bool, error) {\n\treturn withRequired(substitution, mapping, \"?\", func(_ string) bool { return true })\n}\n\nfunc withRequired(substitution string, mapping Mapping, sep string, valid func(string) bool) (string, bool, error) {\n\tif !strings.Contains(substitution, sep) {\n\t\treturn \"\", false, nil\n\t}\n\tname, errorMessage := partition(substitution, sep)\n\tvalue, ok := mapping(name)\n\tif !ok || !valid(value) {\n\t\treturn \"\", true, &InvalidTemplateError{\n\t\t\tTemplate: fmt.Sprintf(\"required variable %s is missing a value: %s\", name, errorMessage),\n\t\t}\n\t}\n\treturn value, true, nil\n}\n\nfunc matchGroups(matches []string, pattern *regexp.Regexp) map[string]string {\n\tgroups := make(map[string]string)\n\tfor i, name := range pattern.SubexpNames()[1:] {\n\t\tgroups[name] = matches[i+1]\n\t}\n\treturn groups\n}\n\n// Split the string at the first occurrence of sep, and return the part before the separator,\n// and the part after the separator.\n//\n// If the separator is not found, return the string itself, followed by an empty string.\nfunc partition(s, sep string) (string, string) {\n\tif strings.Contains(s, sep) {\n\t\tparts := strings.SplitN(s, sep, 2)\n\t\treturn parts[0], parts[1]\n\t}\n\treturn s, \"\"\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/template/template_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage template\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"gotest.tools/v3/assert\"\n\tis \"gotest.tools/v3/assert/cmp\"\n)\n\nvar defaults = map[string]string{\n\t\"FOO\": \"first\",\n\t\"BAR\": \"\",\n}\n\nfunc defaultMapping(name string) (string, bool) {\n\tval, ok := defaults[name]\n\treturn val, ok\n}\n\nfunc TestEscaped(t *testing.T) {\n\tresult, err := Substitute(\"$${foo}\", defaultMapping)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(\"${foo}\", result))\n}\n\nfunc TestSubstituteNoMatch(t *testing.T) {\n\tresult, err := Substitute(\"foo\", defaultMapping)\n\tassert.NilError(t, err)\n\tassert.Equal(t, \"foo\", result)\n}\n\nfunc TestInvalid(t *testing.T) {\n\tinvalidTemplates := []string{\n\t\t\"${\",\n\t\t\"$}\",\n\t\t\"${}\",\n\t\t\"${ }\",\n\t\t\"${ foo}\",\n\t\t\"${foo }\",\n\t\t\"${foo!}\",\n\t}\n\n\tfor _, template := range invalidTemplates {\n\t\t_, err := Substitute(template, defaultMapping)\n\t\tassert.ErrorContains(t, err, \"Invalid template\")\n\t}\n}\n\n// see https://github.com/docker/compose/issues/8601\nfunc TestNonBraced(t *testing.T) {\n\tsubstituted, err := Substitute(\"$FOO-bar\", defaultMapping)\n\tassert.NilError(t, err)\n\tassert.Equal(t, substituted, \"first-bar\")\n}\n\nfunc TestNoValueNoDefault(t *testing.T) {\n\tfor _, template := range []string{\"This ${missing} var\", \"This ${BAR} var\"} {\n\t\tresult, err := Substitute(template, defaultMapping)\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.Equal(\"This  var\", result))\n\t}\n}\n\nfunc TestValueNoDefault(t *testing.T) {\n\tfor _, template := range []string{\"This $FOO var\", \"This ${FOO} var\"} {\n\t\tresult, err := Substitute(template, defaultMapping)\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.Equal(\"This first var\", result))\n\t}\n}\n\nfunc TestNoValueWithDefault(t *testing.T) {\n\tfor _, template := range []string{\"ok ${missing:-def}\", \"ok ${missing-def}\"} {\n\t\tresult, err := Substitute(template, defaultMapping)\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.Equal(\"ok def\", result))\n\t}\n}\n\nfunc TestEmptyValueWithSoftDefault(t *testing.T) {\n\tresult, err := Substitute(\"ok ${BAR:-def}\", defaultMapping)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(\"ok def\", result))\n}\n\nfunc TestValueWithSoftDefault(t *testing.T) {\n\tresult, err := Substitute(\"ok ${FOO:-def}\", defaultMapping)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(\"ok first\", result))\n}\n\nfunc TestEmptyValueWithHardDefault(t *testing.T) {\n\tresult, err := Substitute(\"ok ${BAR-def}\", defaultMapping)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(\"ok \", result))\n}\n\nfunc TestNonAlphanumericDefault(t *testing.T) {\n\tresult, err := Substitute(\"ok ${BAR:-/non:-alphanumeric}\", defaultMapping)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(\"ok /non:-alphanumeric\", result))\n}\n\nfunc TestMandatoryVariableErrors(t *testing.T) {\n\ttestCases := []struct {\n\t\ttemplate      string\n\t\texpectedError string\n\t}{\n\t\t{\n\t\t\ttemplate:      \"not ok ${UNSET_VAR:?Mandatory Variable Unset}\",\n\t\t\texpectedError: \"required variable UNSET_VAR is missing a value: Mandatory Variable Unset\",\n\t\t},\n\t\t{\n\t\t\ttemplate:      \"not ok ${BAR:?Mandatory Variable Empty}\",\n\t\t\texpectedError: \"required variable BAR is missing a value: Mandatory Variable Empty\",\n\t\t},\n\t\t{\n\t\t\ttemplate:      \"not ok ${UNSET_VAR:?}\",\n\t\t\texpectedError: \"required variable UNSET_VAR is missing a value\",\n\t\t},\n\t\t{\n\t\t\ttemplate:      \"not ok ${UNSET_VAR?Mandatory Variable Unset}\",\n\t\t\texpectedError: \"required variable UNSET_VAR is missing a value: Mandatory Variable Unset\",\n\t\t},\n\t\t{\n\t\t\ttemplate:      \"not ok ${UNSET_VAR?}\",\n\t\t\texpectedError: \"required variable UNSET_VAR is missing a value\",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\t_, err := Substitute(tc.template, defaultMapping)\n\t\tassert.ErrorContains(t, err, tc.expectedError)\n\t\tassert.ErrorType(t, err, reflect.TypeOf(&InvalidTemplateError{}))\n\t}\n}\n\nfunc TestDefaultsForMandatoryVariables(t *testing.T) {\n\ttestCases := []struct {\n\t\ttemplate string\n\t\texpected string\n\t}{\n\t\t{\n\t\t\ttemplate: \"ok ${FOO:?err}\",\n\t\t\texpected: \"ok first\",\n\t\t},\n\t\t{\n\t\t\ttemplate: \"ok ${FOO?err}\",\n\t\t\texpected: \"ok first\",\n\t\t},\n\t\t{\n\t\t\ttemplate: \"ok ${BAR?err}\",\n\t\t\texpected: \"ok \",\n\t\t},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tresult, err := Substitute(tc.template, defaultMapping)\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.Equal(tc.expected, result))\n\t}\n}\n\nfunc TestSubstituteWithCustomFunc(t *testing.T) {\n\terrIsMissing := func(substitution string, mapping Mapping) (string, bool, error) {\n\t\tvalue, found := mapping(substitution)\n\t\tif !found {\n\t\t\treturn \"\", true, &InvalidTemplateError{\n\t\t\t\tTemplate: fmt.Sprintf(\"required variable %s is missing a value\", substitution),\n\t\t\t}\n\t\t}\n\t\treturn value, true, nil\n\t}\n\n\tresult, err := SubstituteWith(\"ok ${FOO}\", defaultMapping, defaultPattern, errIsMissing)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(\"ok first\", result))\n\n\tresult, err = SubstituteWith(\"ok ${BAR}\", defaultMapping, defaultPattern, errIsMissing)\n\tassert.NilError(t, err)\n\tassert.Check(t, is.Equal(\"ok \", result))\n\n\t_, err = SubstituteWith(\"ok ${NOTHERE}\", defaultMapping, defaultPattern, errIsMissing)\n\tassert.Check(t, is.ErrorContains(err, \"required variable\"))\n}\n\nfunc TestExtractVariables(t *testing.T) {\n\ttestCases := []struct {\n\t\tname     string\n\t\tdict     map[string]interface{}\n\t\texpected map[string]Variable\n\t}{\n\t\t{\n\t\t\tname:     \"empty\",\n\t\t\tdict:     map[string]interface{}{},\n\t\t\texpected: map[string]Variable{},\n\t\t},\n\t\t{\n\t\t\tname: \"no-variables\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"bar\",\n\t\t\t},\n\t\t\texpected: map[string]Variable{},\n\t\t},\n\t\t{\n\t\t\tname: \"variable-without-curly-braces\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"$bar\",\n\t\t\t},\n\t\t\texpected: map[string]Variable{\n\t\t\t\t\"bar\": {Name: \"bar\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"variable\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"${bar}\",\n\t\t\t},\n\t\t\texpected: map[string]Variable{\n\t\t\t\t\"bar\": {Name: \"bar\", DefaultValue: \"\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"required-variable\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"${bar?:foo}\",\n\t\t\t},\n\t\t\texpected: map[string]Variable{\n\t\t\t\t\"bar\": {Name: \"bar\", DefaultValue: \"\", Required: true},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"required-variable2\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"${bar?foo}\",\n\t\t\t},\n\t\t\texpected: map[string]Variable{\n\t\t\t\t\"bar\": {Name: \"bar\", DefaultValue: \"\", Required: true},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"default-variable\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"${bar:-foo}\",\n\t\t\t},\n\t\t\texpected: map[string]Variable{\n\t\t\t\t\"bar\": {Name: \"bar\", DefaultValue: \"foo\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"default-variable2\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"${bar-foo}\",\n\t\t\t},\n\t\t\texpected: map[string]Variable{\n\t\t\t\t\"bar\": {Name: \"bar\", DefaultValue: \"foo\"},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"multiple-values\",\n\t\t\tdict: map[string]interface{}{\n\t\t\t\t\"foo\": \"${bar:-foo}\",\n\t\t\t\t\"bar\": map[string]interface{}{\n\t\t\t\t\t\"foo\": \"${fruit:-banana}\",\n\t\t\t\t\t\"bar\": \"vegetable\",\n\t\t\t\t},\n\t\t\t\t\"baz\": []interface{}{\n\t\t\t\t\t\"foo\",\n\t\t\t\t\t\"$docker:${project:-cli}\",\n\t\t\t\t\t\"$toto\",\n\t\t\t\t},\n\t\t\t},\n\t\t\texpected: map[string]Variable{\n\t\t\t\t\"bar\":     {Name: \"bar\", DefaultValue: \"foo\"},\n\t\t\t\t\"fruit\":   {Name: \"fruit\", DefaultValue: \"banana\"},\n\t\t\t\t\"toto\":    {Name: \"toto\", DefaultValue: \"\"},\n\t\t\t\t\"docker\":  {Name: \"docker\", DefaultValue: \"\"},\n\t\t\t\t\"project\": {Name: \"project\", DefaultValue: \"cli\"},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tc := range testCases {\n\t\ttc := tc\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tactual := ExtractVariables(tc.dict, defaultPattern)\n\t\t\tassert.Check(t, is.DeepEqual(actual, tc.expected))\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/types/config.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/mitchellh/mapstructure\"\n)\n\n// ConfigDetails are the details about a group of ConfigFiles\ntype ConfigDetails struct {\n\tVersion     string\n\tWorkingDir  string\n\tConfigFiles []ConfigFile\n\tEnvironment map[string]string\n}\n\n// LookupEnv provides a lookup function for environment variables\nfunc (cd ConfigDetails) LookupEnv(key string) (string, bool) {\n\tv, ok := cd.Environment[key]\n\treturn v, ok\n}\n\n// ConfigFile is a filename and the contents of the file as a Dict\ntype ConfigFile struct {\n\t// Filename is the name of the yaml configuration file\n\tFilename string\n\t// Content is the raw yaml content. Will be loaded from Filename if not set\n\tContent []byte\n\t// Config if the yaml tree for this config file. Will be parsed from Content if not set\n\tConfig map[string]interface{}\n}\n\n// Config is a full compose file configuration and model\ntype Config struct {\n\tFilename   string     `yaml:\"-\" json:\"-\"`\n\tServices   Services   `json:\"services\"`\n\tNetworks   Networks   `yaml:\",omitempty\" json:\"networks,omitempty\"`\n\tVolumes    Volumes    `yaml:\",omitempty\" json:\"volumes,omitempty\"`\n\tSecrets    Secrets    `yaml:\",omitempty\" json:\"secrets,omitempty\"`\n\tConfigs    Configs    `yaml:\",omitempty\" json:\"configs,omitempty\"`\n\tExtensions Extensions `yaml:\",inline\" json:\"-\"`\n}\n\n// Volumes is a map of VolumeConfig\ntype Volumes map[string]VolumeConfig\n\n// Networks is a map of NetworkConfig\ntype Networks map[string]NetworkConfig\n\n// Secrets is a map of SecretConfig\ntype Secrets map[string]SecretConfig\n\n// Configs is a map of ConfigObjConfig\ntype Configs map[string]ConfigObjConfig\n\n// Extensions is a map of custom extension\ntype Extensions map[string]interface{}\n\n// MarshalJSON makes Config implement json.Marshaler\nfunc (c Config) MarshalJSON() ([]byte, error) {\n\tm := map[string]interface{}{\n\t\t\"services\": c.Services,\n\t}\n\n\tif len(c.Networks) > 0 {\n\t\tm[\"networks\"] = c.Networks\n\t}\n\tif len(c.Volumes) > 0 {\n\t\tm[\"volumes\"] = c.Volumes\n\t}\n\tif len(c.Secrets) > 0 {\n\t\tm[\"secrets\"] = c.Secrets\n\t}\n\tif len(c.Configs) > 0 {\n\t\tm[\"configs\"] = c.Configs\n\t}\n\tfor k, v := range c.Extensions {\n\t\tm[k] = v\n\t}\n\treturn json.Marshal(m)\n}\n\nfunc (e Extensions) Get(name string, target interface{}) (bool, error) {\n\tif v, ok := e[name]; ok {\n\t\terr := mapstructure.Decode(v, target)\n\t\treturn true, err\n\t}\n\treturn false, nil\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/types/config_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"testing\"\n\n\t\"gotest.tools/v3/assert\"\n)\n\nfunc Test_WithServices(t *testing.T) {\n\tp := Project{\n\t\tServices: append(Services{},\n\t\t\tServiceConfig{\n\t\t\t\tName: \"service_1\",\n\t\t\t\tDependsOn: map[string]ServiceDependency{\n\t\t\t\t\t\"service_3\": {\n\t\t\t\t\t\tCondition: ServiceConditionStarted,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}, ServiceConfig{\n\t\t\t\tName: \"service_2\",\n\t\t\t}, ServiceConfig{\n\t\t\t\tName: \"service_3\",\n\t\t\t\tDependsOn: map[string]ServiceDependency{\n\t\t\t\t\t\"service_2\": {\n\t\t\t\t\t\tCondition: ServiceConditionStarted,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t}\n\torder := []string{}\n\tfn := func(service ServiceConfig) error {\n\t\torder = append(order, service.Name)\n\t\treturn nil\n\t}\n\n\terr := p.WithServices(nil, fn)\n\tassert.NilError(t, err)\n\tassert.DeepEqual(t, order, []string{\"service_2\", \"service_3\", \"service_1\"})\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/types/project.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\n\t\"github.com/distribution/distribution/v3/reference\"\n\t\"github.com/opencontainers/go-digest\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// Project is the result of loading a set of compose files\ntype Project struct {\n\tName         string            `yaml:\"-\" json:\"-\"`\n\tWorkingDir   string            `yaml:\"-\" json:\"-\"`\n\tServices     Services          `json:\"services\"`\n\tNetworks     Networks          `yaml:\",omitempty\" json:\"networks,omitempty\"`\n\tVolumes      Volumes           `yaml:\",omitempty\" json:\"volumes,omitempty\"`\n\tSecrets      Secrets           `yaml:\",omitempty\" json:\"secrets,omitempty\"`\n\tConfigs      Configs           `yaml:\",omitempty\" json:\"configs,omitempty\"`\n\tExtensions   Extensions        `yaml:\",inline\" json:\"-\"` // https://github.com/golang/go/issues/6213\n\tComposeFiles []string          `yaml:\"-\" json:\"-\"`\n\tEnvironment  map[string]string `yaml:\"-\" json:\"-\"`\n\n\t// DisabledServices track services which have been disable as profile is not active\n\tDisabledServices Services `yaml:\"-\" json:\"-\"`\n}\n\n// ServiceNames return names for all services in this Compose config\nfunc (p Project) ServiceNames() []string {\n\tnames := []string{}\n\tfor _, s := range p.Services {\n\t\tnames = append(names, s.Name)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// VolumeNames return names for all volumes in this Compose config\nfunc (p Project) VolumeNames() []string {\n\tnames := []string{}\n\tfor k := range p.Volumes {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// NetworkNames return names for all volumes in this Compose config\nfunc (p Project) NetworkNames() []string {\n\tnames := []string{}\n\tfor k := range p.Networks {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// SecretNames return names for all secrets in this Compose config\nfunc (p Project) SecretNames() []string {\n\tnames := []string{}\n\tfor k := range p.Secrets {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// ConfigNames return names for all configs in this Compose config\nfunc (p Project) ConfigNames() []string {\n\tnames := []string{}\n\tfor k := range p.Configs {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// GetServices retrieve services by names, or return all services if no name specified\nfunc (p Project) GetServices(names ...string) (Services, error) {\n\tif len(names) == 0 {\n\t\treturn p.Services, nil\n\t}\n\tservices := Services{}\n\tfor _, name := range names {\n\t\tvar serviceConfig *ServiceConfig\n\t\tfor _, s := range p.Services {\n\t\t\tif s.Name == name {\n\t\t\t\tserviceConfig = &s\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif serviceConfig == nil {\n\t\t\treturn services, fmt.Errorf(\"no such service: %s\", name)\n\t\t}\n\t\tservices = append(services, *serviceConfig)\n\t}\n\treturn services, nil\n}\n\n// GetService retrieve a specific service by name\nfunc (p Project) GetService(name string) (ServiceConfig, error) {\n\tservices, err := p.GetServices(name)\n\tif err != nil {\n\t\treturn ServiceConfig{}, err\n\t}\n\tif len(services) == 0 {\n\t\treturn ServiceConfig{}, fmt.Errorf(\"no such service: %s\", name)\n\t}\n\treturn services[0], nil\n}\n\nfunc (p Project) AllServices() Services {\n\tvar all Services\n\tall = append(all, p.Services...)\n\tall = append(all, p.DisabledServices...)\n\treturn all\n}\n\ntype ServiceFunc func(service ServiceConfig) error\n\n// WithServices run ServiceFunc on each service and dependencies in dependency order\nfunc (p Project) WithServices(names []string, fn ServiceFunc) error {\n\treturn p.withServices(names, fn, map[string]bool{})\n}\n\nfunc (p Project) withServices(names []string, fn ServiceFunc, done map[string]bool) error {\n\tservices, err := p.GetServices(names...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, service := range services {\n\t\tif done[service.Name] {\n\t\t\tcontinue\n\t\t}\n\t\t//KCQ\n\t\tdone[service.Name] = true\n\t\tdependencies := service.GetDependencies()\n\t\tif len(dependencies) > 0 {\n\t\t\terr := p.withServices(dependencies, fn, done)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err := fn(service); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// RelativePath resolve a relative path based project's working directory\nfunc (p *Project) RelativePath(path string) string {\n\tif path[0] == '~' {\n\t\thome, _ := os.UserHomeDir()\n\t\tpath = filepath.Join(home, path[1:])\n\t}\n\tif filepath.IsAbs(path) {\n\t\treturn path\n\t}\n\treturn filepath.Join(p.WorkingDir, path)\n}\n\n// HasProfile return true if service has no profile declared or has at least one profile matching\nfunc (service ServiceConfig) HasProfile(profiles []string) bool {\n\tif len(service.Profiles) == 0 {\n\t\treturn true\n\t}\n\tfor _, p := range profiles {\n\t\tfor _, sp := range service.Profiles {\n\t\t\tif sp == p {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// GetProfiles retrieve the profiles implicitly enabled by explicitly targeting selected services\nfunc (s Services) GetProfiles() []string {\n\tset := map[string]struct{}{}\n\tfor _, service := range s {\n\t\tfor _, p := range service.Profiles {\n\t\t\tset[p] = struct{}{}\n\t\t}\n\t}\n\tvar profiles []string\n\tfor k := range set {\n\t\tprofiles = append(profiles, k)\n\t}\n\treturn profiles\n}\n\n// ApplyProfiles disables service which don't match selected profiles\nfunc (p *Project) ApplyProfiles(profiles []string) {\n\tfor _, p := range profiles {\n\t\tif p == \"*\" {\n\t\t\treturn\n\t\t}\n\t}\n\tvar enabled, disabled Services\n\tfor _, service := range p.Services {\n\t\tif service.HasProfile(profiles) {\n\t\t\tenabled = append(enabled, service)\n\t\t} else {\n\t\t\tdisabled = append(disabled, service)\n\t\t}\n\t}\n\tp.Services = enabled\n\tp.DisabledServices = disabled\n}\n\n// WithoutUnnecessaryResources drops networks/volumes/secrets/configs that are not referenced by active services\nfunc (p *Project) WithoutUnnecessaryResources() {\n\trequiredNetworks := map[string]struct{}{}\n\trequiredVolumes := map[string]struct{}{}\n\trequiredSecrets := map[string]struct{}{}\n\trequiredConfigs := map[string]struct{}{}\n\tfor _, s := range p.Services {\n\t\tfor k := range s.Networks {\n\t\t\trequiredNetworks[k] = struct{}{}\n\t\t}\n\t\tfor _, v := range s.Volumes {\n\t\t\tif v.Type != VolumeTypeVolume || v.Source == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trequiredVolumes[v.Source] = struct{}{}\n\t\t}\n\t\tfor _, v := range s.Secrets {\n\t\t\trequiredSecrets[v.Source] = struct{}{}\n\t\t}\n\t\tfor _, v := range s.Configs {\n\t\t\trequiredConfigs[v.Source] = struct{}{}\n\t\t}\n\t}\n\n\tnetworks := Networks{}\n\tfor k := range requiredNetworks {\n\t\tnetworks[k] = p.Networks[k]\n\t}\n\tp.Networks = networks\n\n\tvolumes := Volumes{}\n\tfor k := range requiredVolumes {\n\t\tvolumes[k] = p.Volumes[k]\n\t}\n\tp.Volumes = volumes\n\n\tsecrets := Secrets{}\n\tfor k := range requiredSecrets {\n\t\tsecrets[k] = p.Secrets[k]\n\t}\n\tp.Secrets = secrets\n\n\tconfigs := Configs{}\n\tfor k := range requiredConfigs {\n\t\tconfigs[k] = p.Configs[k]\n\t}\n\tp.Configs = configs\n}\n\n// ForServices restrict the project model to a subset of services\nfunc (p *Project) ForServices(names []string) error {\n\tif len(names) == 0 {\n\t\t// All services\n\t\treturn nil\n\t}\n\n\tset := map[string]struct{}{}\n\terr := p.WithServices(names, func(service ServiceConfig) error {\n\t\tset[service.Name] = struct{}{}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Disable all services which are not explicit target or dependencies\n\tvar enabled Services\n\tfor _, s := range p.Services {\n\t\tif _, ok := set[s.Name]; ok {\n\t\t\tenabled = append(enabled, s)\n\t\t} else {\n\t\t\tp.DisabledServices = append(p.DisabledServices, s)\n\t\t}\n\t}\n\tp.Services = enabled\n\treturn nil\n}\n\n// ResolveImages updates services images to include digest computed by a resolver function\nfunc (p *Project) ResolveImages(resolver func(named reference.Named) (digest.Digest, error)) error {\n\teg := errgroup.Group{}\n\tfor i, s := range p.Services {\n\t\tidx := i\n\t\tservice := s\n\n\t\tif service.Image == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\teg.Go(func() error {\n\t\t\tnamed, err := reference.ParseDockerRef(service.Image)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif _, ok := named.(reference.Canonical); !ok {\n\t\t\t\t// image is named but not digested reference\n\t\t\t\tdigest, err := resolver(named)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tnamed, err = reference.WithDigest(named, digest)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tservice.Image = named.String()\n\t\t\tp.Services[idx] = service\n\t\t\treturn nil\n\t\t})\n\t}\n\treturn eg.Wait()\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/types/project_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t_ \"crypto/sha256\"\n\t\"testing\"\n\n\t\"github.com/distribution/distribution/v3/reference\"\n\t\"github.com/opencontainers/go-digest\"\n\t\"gotest.tools/v3/assert\"\n)\n\nfunc Test_ApplyProfiles(t *testing.T) {\n\tp := makeProject()\n\tp.ApplyProfiles([]string{\"foo\"})\n\tassert.Equal(t, len(p.Services), 2)\n\tassert.Equal(t, p.Services[0].Name, \"service_1\")\n\tassert.Equal(t, p.Services[1].Name, \"service_2\")\n\tassert.Equal(t, len(p.DisabledServices), 1)\n\tassert.Equal(t, p.DisabledServices[0].Name, \"service_3\")\n}\n\nfunc Test_WithoutUnnecessaryResources(t *testing.T) {\n\tp := makeProject()\n\tp.Networks[\"unused\"] = NetworkConfig{}\n\tp.Volumes[\"unused\"] = VolumeConfig{}\n\tp.Secrets[\"unused\"] = SecretConfig{}\n\tp.Configs[\"unused\"] = ConfigObjConfig{}\n\tp.WithoutUnnecessaryResources()\n\tif _, ok := p.Networks[\"unused\"]; ok {\n\t\tt.Fail()\n\t}\n\tif _, ok := p.Volumes[\"unused\"]; ok {\n\t\tt.Fail()\n\t}\n\tif _, ok := p.Secrets[\"unused\"]; ok {\n\t\tt.Fail()\n\t}\n\tif _, ok := p.Configs[\"unused\"]; ok {\n\t\tt.Fail()\n\t}\n}\n\nfunc Test_NoProfiles(t *testing.T) {\n\tp := makeProject()\n\tp.ApplyProfiles(nil)\n\tassert.Equal(t, len(p.Services), 1)\n\tassert.Equal(t, len(p.DisabledServices), 2)\n\tassert.Equal(t, p.Services[0].Name, \"service_1\")\n}\n\nfunc Test_ServiceProfiles(t *testing.T) {\n\tp := makeProject()\n\tservices, err := p.GetServices(\"service_1\", \"service_2\")\n\tassert.NilError(t, err)\n\n\tprofiles := services.GetProfiles()\n\tassert.Equal(t, len(profiles), 1)\n\tassert.Equal(t, profiles[0], \"foo\")\n}\n\nfunc Test_ForServices(t *testing.T) {\n\tp := makeProject()\n\terr := p.ForServices([]string{\"service_2\"})\n\tassert.NilError(t, err)\n\n\tassert.Equal(t, len(p.DisabledServices), 1)\n\tassert.Equal(t, p.DisabledServices[0].Name, \"service_3\")\n}\n\nfunc makeProject() Project {\n\treturn Project{\n\t\tServices: append(Services{},\n\t\t\tServiceConfig{\n\t\t\t\tName: \"service_1\",\n\t\t\t}, ServiceConfig{\n\t\t\t\tName:      \"service_2\",\n\t\t\t\tProfiles:  []string{\"foo\"},\n\t\t\t\tDependsOn: map[string]ServiceDependency{\"service_1\": {}},\n\t\t\t}, ServiceConfig{\n\t\t\t\tName:     \"service_3\",\n\t\t\t\tProfiles: []string{\"bar\"},\n\t\t\t}),\n\t\tNetworks: Networks{},\n\t\tVolumes:  Volumes{},\n\t\tSecrets:  Secrets{},\n\t\tConfigs:  Configs{},\n\t}\n}\n\nfunc Test_ResolveImages(t *testing.T) {\n\tp := makeProject()\n\tresolver := func(named reference.Named) (digest.Digest, error) {\n\t\treturn \"sha256:1234567890123456789012345678901234567890123456789012345678901234\", nil\n\t}\n\n\ttests := []struct {\n\t\timage    string\n\t\tresolved string\n\t}{\n\t\t{\n\t\t\timage:    \"com.acme/long:tag\",\n\t\t\tresolved: \"com.acme/long:tag@sha256:1234567890123456789012345678901234567890123456789012345678901234\",\n\t\t},\n\t\t{\n\t\t\timage:    \"com.acme/long\",\n\t\t\tresolved: \"com.acme/long:latest@sha256:1234567890123456789012345678901234567890123456789012345678901234\",\n\t\t},\n\t\t{\n\t\t\timage:    \"short\",\n\t\t\tresolved: \"docker.io/library/short:latest@sha256:1234567890123456789012345678901234567890123456789012345678901234\",\n\t\t},\n\t\t{\n\t\t\timage:    \"com.acme/digested:tag@sha256:1234567890123456789012345678901234567890123456789012345678901234\",\n\t\t\tresolved: \"com.acme/digested@sha256:1234567890123456789012345678901234567890123456789012345678901234\",\n\t\t},\n\t\t{\n\t\t\timage:    \"com.acme/digested@sha256:1234567890123456789012345678901234567890123456789012345678901234\",\n\t\t\tresolved: \"com.acme/digested@sha256:1234567890123456789012345678901234567890123456789012345678901234\",\n\t\t},\n\t}\n\n\tfor _, test := range tests {\n\t\tp.Services[0].Image = test.image\n\t\terr := p.ResolveImages(resolver)\n\t\tassert.NilError(t, err)\n\t\tassert.Equal(t, p.Services[0].Image, test.resolved)\n\t}\n}\n"
  },
  {
    "path": "pkg/third_party/compose-go/types/types.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/docker/go-connections/nat\"\n)\n\n// Duration is a thin wrapper around time.Duration with improved JSON marshalling\ntype Duration time.Duration\n\nfunc (d Duration) String() string {\n\treturn time.Duration(d).String()\n}\n\n// ConvertDurationPtr converts a typedefined Duration pointer to a time.Duration pointer with the same value.\nfunc ConvertDurationPtr(d *Duration) *time.Duration {\n\tif d == nil {\n\t\treturn nil\n\t}\n\tres := time.Duration(*d)\n\treturn &res\n}\n\n// MarshalJSON makes Duration implement json.Marshaler\nfunc (d Duration) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(d.String())\n}\n\n// MarshalYAML makes Duration implement yaml.Marshaler\nfunc (d Duration) MarshalYAML() (interface{}, error) {\n\treturn d.String(), nil\n}\n\nfunc (d *Duration) UnmarshalJSON(b []byte) error {\n\ts := strings.Trim(string(b), \"\\\"\")\n\ttimeDuration, err := time.ParseDuration(s)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*d = Duration(timeDuration)\n\treturn nil\n}\n\n// Services is a list of ServiceConfig\ntype Services []ServiceConfig\n\n// MarshalYAML makes Services implement yaml.Marshaller\nfunc (s Services) MarshalYAML() (interface{}, error) {\n\tservices := map[string]ServiceConfig{}\n\tfor _, service := range s {\n\t\tservices[service.Name] = service\n\t}\n\treturn services, nil\n}\n\n// MarshalJSON makes Services implement json.Marshaler\nfunc (s Services) MarshalJSON() ([]byte, error) {\n\tdata, err := s.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.MarshalIndent(data, \"\", \"  \")\n}\n\n// ServiceConfig is the configuration of one service\ntype ServiceConfig struct {\n\tName     string   `yaml:\"-\" json:\"-\"`\n\tProfiles []string `mapstructure:\"profiles\" yaml:\"profiles,omitempty\" json:\"profiles,omitempty\"`\n\n\tBuild           *BuildConfig                     `yaml:\",omitempty\" json:\"build,omitempty\"`\n\tBlkioConfig     *BlkioConfig                     `yaml:\",omitempty\" json:\"blkio_config,omitempty\"`\n\tCapAdd          []string                         `mapstructure:\"cap_add\" yaml:\"cap_add,omitempty\" json:\"cap_add,omitempty\"`\n\tCapDrop         []string                         `mapstructure:\"cap_drop\" yaml:\"cap_drop,omitempty\" json:\"cap_drop,omitempty\"`\n\tCgroupParent    string                           `mapstructure:\"cgroup_parent\" yaml:\"cgroup_parent,omitempty\" json:\"cgroup_parent,omitempty\"`\n\tCPUCount        int64                            `mapstructure:\"cpu_count\" yaml:\"cpu_count,omitempty\" json:\"cpu_count,omitempty\"`\n\tCPUPercent      float32                          `mapstructure:\"cpu_percent\" yaml:\"cpu_percent,omitempty\" json:\"cpu_percent,omitempty\"`\n\tCPUPeriod       int64                            `mapstructure:\"cpu_period\" yaml:\"cpu_period,omitempty\" json:\"cpu_period,omitempty\"`\n\tCPUQuota        int64                            `mapstructure:\"cpu_quota\" yaml:\"cpu_quota,omitempty\" json:\"cpu_quota,omitempty\"`\n\tCPURTPeriod     int64                            `mapstructure:\"cpu_rt_period\" yaml:\"cpu_rt_period,omitempty\" json:\"cpu_rt_period,omitempty\"`\n\tCPURTRuntime    int64                            `mapstructure:\"cpu_rt_runtime\" yaml:\"cpu_rt_runtime,omitempty\" json:\"cpu_rt_runtime,omitempty\"`\n\tCPUS            float32                          `mapstructure:\"cpus\" yaml:\"cpus,omitempty\" json:\"cpus,omitempty\"`\n\tCPUSet          string                           `mapstructure:\"cpuset\" yaml:\"cpuset,omitempty\" json:\"cpuset,omitempty\"`\n\tCPUShares       int64                            `mapstructure:\"cpu_shares\" yaml:\"cpu_shares,omitempty\" json:\"cpu_shares,omitempty\"`\n\tCommand         ShellCommand                     `yaml:\",omitempty\" json:\"command,omitempty\"`\n\tConfigs         []ServiceConfigObjConfig         `yaml:\",omitempty\" json:\"configs,omitempty\"`\n\tContainerName   string                           `mapstructure:\"container_name\" yaml:\"container_name,omitempty\" json:\"container_name,omitempty\"`\n\tCredentialSpec  *CredentialSpecConfig            `mapstructure:\"credential_spec\" yaml:\"credential_spec,omitempty\" json:\"credential_spec,omitempty\"`\n\tDependsOn       DependsOnConfig                  `mapstructure:\"depends_on\" yaml:\"depends_on,omitempty\" json:\"depends_on,omitempty\"`\n\tDeploy          *DeployConfig                    `yaml:\",omitempty\" json:\"deploy,omitempty\"`\n\tDevices         []string                         `yaml:\",omitempty\" json:\"devices,omitempty\"`\n\tDNS             StringList                       `yaml:\",omitempty\" json:\"dns,omitempty\"`\n\tDNSOpts         []string                         `mapstructure:\"dns_opt\" yaml:\"dns_opt,omitempty\" json:\"dns_opt,omitempty\"`\n\tDNSSearch       StringList                       `mapstructure:\"dns_search\" yaml:\"dns_search,omitempty\" json:\"dns_search,omitempty\"`\n\tDockerfile      string                           `yaml:\"dockerfile,omitempty\" json:\"dockerfile,omitempty\"`\n\tDomainName      string                           `mapstructure:\"domainname\" yaml:\"domainname,omitempty\" json:\"domainname,omitempty\"`\n\tEntrypoint      ShellCommand                     `yaml:\",omitempty\" json:\"entrypoint,omitempty\"`\n\tEnvironment     MappingWithEquals                `yaml:\",omitempty\" json:\"environment,omitempty\"`\n\tEnvFile         StringList                       `mapstructure:\"env_file\" yaml:\"env_file,omitempty\" json:\"env_file,omitempty\"`\n\tExpose          StringOrNumberList               `yaml:\",omitempty\" json:\"expose,omitempty\"`\n\tExtends         ExtendsConfig                    `yaml:\"extends,omitempty\" json:\"extends,omitempty\"`\n\tExternalLinks   []string                         `mapstructure:\"external_links\" yaml:\"external_links,omitempty\" json:\"external_links,omitempty\"`\n\tExtraHosts      HostsList                        `mapstructure:\"extra_hosts\" yaml:\"extra_hosts,omitempty\" json:\"extra_hosts,omitempty\"`\n\tGroupAdd        []string                         `mapstructure:\"group_app\" yaml:\"group_add,omitempty\" json:\"group_add,omitempty\"`\n\tHostname        string                           `yaml:\",omitempty\" json:\"hostname,omitempty\"`\n\tHealthCheck     *HealthCheckConfig               `yaml:\",omitempty\" json:\"healthcheck,omitempty\"`\n\tImage           string                           `yaml:\",omitempty\" json:\"image,omitempty\"`\n\tInit            *bool                            `yaml:\",omitempty\" json:\"init,omitempty\"`\n\tIpc             string                           `yaml:\",omitempty\" json:\"ipc,omitempty\"`\n\tIsolation       string                           `mapstructure:\"isolation\" yaml:\"isolation,omitempty\" json:\"isolation,omitempty\"`\n\tLabels          Labels                           `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tLinks           []string                         `yaml:\",omitempty\" json:\"links,omitempty\"`\n\tLogging         *LoggingConfig                   `yaml:\",omitempty\" json:\"logging,omitempty\"`\n\tLogDriver       string                           `mapstructure:\"log_driver\" yaml:\"log_driver,omitempty\" json:\"log_driver,omitempty\"`\n\tLogOpt          map[string]string                `mapstructure:\"log_opt\" yaml:\"log_opt,omitempty\" json:\"log_opt,omitempty\"`\n\tMemLimit        UnitBytes                        `mapstructure:\"mem_limit\" yaml:\"mem_limit,omitempty\" json:\"mem_limit,omitempty\"`\n\tMemReservation  UnitBytes                        `mapstructure:\"mem_reservation\" yaml:\"mem_reservation,omitempty\" json:\"mem_reservation,omitempty\"`\n\tMemSwapLimit    UnitBytes                        `mapstructure:\"memswap_limit\" yaml:\"memswap_limit,omitempty\" json:\"memswap_limit,omitempty\"`\n\tMemSwappiness   UnitBytes                        `mapstructure:\"mem_swappiness\" yaml:\"mem_swappiness,omitempty\" json:\"mem_swappiness,omitempty\"`\n\tMacAddress      string                           `mapstructure:\"mac_address\" yaml:\"mac_address,omitempty\" json:\"mac_address,omitempty\"`\n\tNet             string                           `yaml:\"net,omitempty\" json:\"net,omitempty\"`\n\tNetworkMode     string                           `mapstructure:\"network_mode\" yaml:\"network_mode,omitempty\" json:\"network_mode,omitempty\"`\n\tNetworks        map[string]*ServiceNetworkConfig `yaml:\",omitempty\" json:\"networks,omitempty\"`\n\tOomKillDisable  bool                             `mapstructure:\"oom_kill_disable\" yaml:\"oom_kill_disable,omitempty\" json:\"oom_kill_disable,omitempty\"`\n\tOomScoreAdj     int64                            `mapstructure:\"oom_score_adj\" yaml:\"oom_score_adj,omitempty\" json:\"oom_score_adj,omitempty\"`\n\tPid             string                           `yaml:\",omitempty\" json:\"pid,omitempty\"`\n\tPidsLimit       int64                            `mapstructure:\"pids_limit\" yaml:\"pids_limit,omitempty\" json:\"pids_limit,omitempty\"`\n\tPlatform        string                           `yaml:\",omitempty\" json:\"platform,omitempty\"`\n\tPorts           []ServicePortConfig              `yaml:\",omitempty\" json:\"ports,omitempty\"`\n\tPrivileged      bool                             `yaml:\",omitempty\" json:\"privileged,omitempty\"`\n\tPullPolicy      string                           `mapstructure:\"pull_policy\" yaml:\"pull_policy,omitempty\" json:\"pull_policy,omitempty\"`\n\tReadOnly        bool                             `mapstructure:\"read_only\" yaml:\"read_only,omitempty\" json:\"read_only,omitempty\"`\n\tRestart         string                           `yaml:\",omitempty\" json:\"restart,omitempty\"`\n\tRuntime         string                           `yaml:\",omitempty\" json:\"runtime,omitempty\"`\n\tScale           int                              `yaml:\"-\" json:\"-\"`\n\tSecrets         []ServiceSecretConfig            `yaml:\",omitempty\" json:\"secrets,omitempty\"`\n\tSecurityOpt     []string                         `mapstructure:\"security_opt\" yaml:\"security_opt,omitempty\" json:\"security_opt,omitempty\"`\n\tShmSize         UnitBytes                        `mapstructure:\"shm_size\" yaml:\"shm_size,omitempty\" json:\"shm_size,omitempty\"`\n\tStdinOpen       bool                             `mapstructure:\"stdin_open\" yaml:\"stdin_open,omitempty\" json:\"stdin_open,omitempty\"`\n\tStopGracePeriod *Duration                        `mapstructure:\"stop_grace_period\" yaml:\"stop_grace_period,omitempty\" json:\"stop_grace_period,omitempty\"`\n\tStopSignal      string                           `mapstructure:\"stop_signal\" yaml:\"stop_signal,omitempty\" json:\"stop_signal,omitempty\"`\n\tSysctls         Mapping                          `yaml:\",omitempty\" json:\"sysctls,omitempty\"`\n\tTmpfs           StringList                       `yaml:\",omitempty\" json:\"tmpfs,omitempty\"`\n\tTty             bool                             `mapstructure:\"tty\" yaml:\"tty,omitempty\" json:\"tty,omitempty\"`\n\tUlimits         map[string]*UlimitsConfig        `yaml:\",omitempty\" json:\"ulimits,omitempty\"`\n\tUser            string                           `yaml:\",omitempty\" json:\"user,omitempty\"`\n\tUserNSMode      string                           `mapstructure:\"userns_mode\" yaml:\"userns_mode,omitempty\" json:\"userns_mode,omitempty\"`\n\tUts             string                           `yaml:\"uts,omitempty\" json:\"uts,omitempty\"`\n\tVolumeDriver    string                           `mapstructure:\"volume_driver\" yaml:\"volume_driver,omitempty\" json:\"volume_driver,omitempty\"`\n\tVolumes         []ServiceVolumeConfig            `yaml:\",omitempty\" json:\"volumes,omitempty\"`\n\tVolumesFrom     []string                         `mapstructure:\"volumes_from\" yaml:\"volumes_from,omitempty\" json:\"volumes_from,omitempty\"`\n\tWorkingDir      string                           `mapstructure:\"working_dir\" yaml:\"working_dir,omitempty\" json:\"working_dir,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// NetworksByPriority return the service networks IDs sorted according to Priority\nfunc (s *ServiceConfig) NetworksByPriority() []string {\n\ttype key struct {\n\t\tname     string\n\t\tpriority int\n\t}\n\tvar keys []key\n\tfor k, v := range s.Networks {\n\t\tpriority := 0\n\t\tif v != nil {\n\t\t\tpriority = v.Priority\n\t\t}\n\t\tkeys = append(keys, key{\n\t\t\tname:     k,\n\t\t\tpriority: priority,\n\t\t})\n\t}\n\tsort.Slice(keys, func(i, j int) bool {\n\t\treturn keys[i].priority > keys[j].priority\n\t})\n\tvar sorted []string\n\tfor _, k := range keys {\n\t\tsorted = append(sorted, k.name)\n\t}\n\treturn sorted\n}\n\nconst (\n\t//PullPolicyAlways always pull images\n\tPullPolicyAlways = \"always\"\n\t//PullPolicyNever never pull images\n\tPullPolicyNever = \"never\"\n\t//PullPolicyIfNotPresent pull missing images\n\tPullPolicyIfNotPresent = \"if_not_present\"\n\t//PullPolicyIfNotPresent pull missing images\n\tPullPolicyMissing = \"missing\"\n\t//PullPolicyBuild force building images\n\tPullPolicyBuild = \"build\"\n)\n\nconst (\n\t//RestartPolicyAlways always restart the container if it stops\n\tRestartPolicyAlways = \"always\"\n\t//RestartPolicyOnFailure restart the container if it exits due to an error\n\tRestartPolicyOnFailure = \"on-failure\"\n\t//RestartPolicyNo do not automatically restart the container\n\tRestartPolicyNo = \"no\"\n\t//RestartPolicyUnlessStopped always restart the container unless the container is stopped (manually or otherwise)\n\tRestartPolicyUnlessStopped = \"unless-stopped\"\n)\n\nconst (\n\t// ServicePrefix is the prefix for references pointing to a service\n\tServicePrefix = \"service:\"\n\t// ContainerPrefix is the prefix for references pointing to a container\n\tContainerPrefix = \"container:\"\n\n\t// NetworkModeServicePrefix is the prefix for network_mode pointing to a service\n\t// Deprecated prefer ServicePrefix\n\tNetworkModeServicePrefix = ServicePrefix\n\t// NetworkModeContainerPrefix is the prefix for network_mode pointing to a container\n\t// Deprecated prefer ContainerPrefix\n\tNetworkModeContainerPrefix = ContainerPrefix\n)\n\n// GetDependencies retrieve all services this service depends on\nfunc (s ServiceConfig) GetDependencies() []string {\n\tdependencies := make(set)\n\tfor dependency := range s.DependsOn {\n\t\tdependencies.append(dependency)\n\t}\n\tfor _, link := range s.Links {\n\t\tparts := strings.Split(link, \":\")\n\t\tif len(parts) == 2 {\n\t\t\tdependencies.append(parts[0])\n\t\t} else {\n\t\t\tdependencies.append(link)\n\t\t}\n\t}\n\tif strings.HasPrefix(s.NetworkMode, ServicePrefix) {\n\t\tdependencies.append(s.NetworkMode[len(ServicePrefix):])\n\t}\n\tif strings.HasPrefix(s.Ipc, ServicePrefix) {\n\t\tdependencies.append(s.Ipc[len(ServicePrefix):])\n\t}\n\tif strings.HasPrefix(s.Pid, ServicePrefix) {\n\t\tdependencies.append(s.Pid[len(ServicePrefix):])\n\t}\n\tfor _, vol := range s.VolumesFrom {\n\t\tif !strings.HasPrefix(s.Pid, ContainerPrefix) {\n\t\t\tdependencies.append(vol)\n\t\t}\n\t}\n\n\treturn dependencies.toSlice()\n}\n\ntype set map[string]struct{}\n\nfunc (s set) append(strings ...string) {\n\tfor _, str := range strings {\n\t\ts[str] = struct{}{}\n\t}\n}\n\nfunc (s set) toSlice() []string {\n\tslice := make([]string, 0, len(s))\n\tfor v := range s {\n\t\tslice = append(slice, v)\n\t}\n\treturn slice\n}\n\n// BuildConfig is a type for build\ntype BuildConfig struct {\n\tContext    string            `yaml:\",omitempty\" json:\"context,omitempty\"`\n\tDockerfile string            `yaml:\",omitempty\" json:\"dockerfile,omitempty\"`\n\tArgs       MappingWithEquals `yaml:\",omitempty\" json:\"args,omitempty\"`\n\tLabels     Labels            `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tCacheFrom  StringList        `mapstructure:\"cache_from\" yaml:\"cache_from,omitempty\" json:\"cache_from,omitempty\"`\n\tExtraHosts HostsList         `mapstructure:\"extra_hosts\" yaml:\"extra_hosts,omitempty\" json:\"extra_hosts,omitempty\"`\n\tIsolation  string            `yaml:\",omitempty\" json:\"isolation,omitempty\"`\n\tNetwork    string            `yaml:\",omitempty\" json:\"network,omitempty\"`\n\tTarget     string            `yaml:\",omitempty\" json:\"target,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// BlkioConfig define blkio config\ntype BlkioConfig struct {\n\tWeight          uint16           `yaml:\",omitempty\" json:\"weight,omitempty\"`\n\tWeightDevice    []WeightDevice   `yaml:\",omitempty\" json:\"weight_device,omitempty\"`\n\tDeviceReadBps   []ThrottleDevice `yaml:\",omitempty\" json:\"device_read_bps,omitempty\"`\n\tDeviceReadIOps  []ThrottleDevice `yaml:\",omitempty\" json:\"device_read_iops,omitempty\"`\n\tDeviceWriteBps  []ThrottleDevice `yaml:\",omitempty\" json:\"device_write_bps,omitempty\"`\n\tDeviceWriteIOps []ThrottleDevice `yaml:\",omitempty\" json:\"device_write_iops,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// WeightDevice is a structure that holds device:weight pair\ntype WeightDevice struct {\n\tPath   string\n\tWeight uint16\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ThrottleDevice is a structure that holds device:rate_per_second pair\ntype ThrottleDevice struct {\n\tPath string\n\tRate uint64\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ShellCommand is a string or list of string args\ntype ShellCommand []string\n\n// StringList is a type for fields that can be a string or list of strings\ntype StringList []string\n\n// StringOrNumberList is a type for fields that can be a list of strings or\n// numbers\ntype StringOrNumberList []string\n\n// MappingWithEquals is a mapping type that can be converted from a list of\n// key[=value] strings.\n// For the key with an empty value (`key=`), the mapped value is set to a pointer to `\"\"`.\n// For the key without value (`key`), the mapped value is set to nil.\ntype MappingWithEquals map[string]*string\n\n// NewMappingWithEquals build a new Mapping from a set of KEY=VALUE strings\nfunc NewMappingWithEquals(values []string) MappingWithEquals {\n\tmapping := MappingWithEquals{}\n\tfor _, env := range values {\n\t\ttokens := strings.SplitN(env, \"=\", 2)\n\t\tif len(tokens) > 1 {\n\t\t\tmapping[tokens[0]] = &tokens[1]\n\t\t} else {\n\t\t\tmapping[env] = nil\n\t\t}\n\t}\n\treturn mapping\n}\n\n// OverrideBy update MappingWithEquals with values from another MappingWithEquals\nfunc (e MappingWithEquals) OverrideBy(other MappingWithEquals) MappingWithEquals {\n\tfor k, v := range other {\n\t\te[k] = v\n\t}\n\treturn e\n}\n\n// Resolve update a MappingWithEquals for keys without value (`key`, but not `key=`)\nfunc (e MappingWithEquals) Resolve(lookupFn func(string) (string, bool)) MappingWithEquals {\n\tfor k, v := range e {\n\t\tif v == nil {\n\t\t\tif value, ok := lookupFn(k); ok {\n\t\t\t\te[k] = &value\n\t\t\t}\n\t\t}\n\t}\n\treturn e\n}\n\n// RemoveEmpty excludes keys that are not associated with a value\nfunc (e MappingWithEquals) RemoveEmpty() MappingWithEquals {\n\tfor k, v := range e {\n\t\tif v == nil {\n\t\t\tdelete(e, k)\n\t\t}\n\t}\n\treturn e\n}\n\n// Mapping is a mapping type that can be converted from a list of\n// key[=value] strings.\n// For the key with an empty value (`key=`), or key without value (`key`), the\n// mapped value is set to an empty string `\"\"`.\ntype Mapping map[string]string\n\n// NewMapping build a new Mapping from a set of KEY=VALUE strings\nfunc NewMapping(values []string) Mapping {\n\tmapping := Mapping{}\n\tfor _, value := range values {\n\t\tparts := strings.SplitN(value, \"=\", 2)\n\t\tkey := parts[0]\n\t\tswitch {\n\t\tcase len(parts) == 1:\n\t\t\tmapping[key] = \"\"\n\t\tdefault:\n\t\t\tmapping[key] = parts[1]\n\t\t}\n\t}\n\treturn mapping\n}\n\n// Labels is a mapping type for labels\ntype Labels map[string]string\n\nfunc (l Labels) Add(key, value string) Labels {\n\tif l == nil {\n\t\tl = Labels{}\n\t}\n\tl[key] = value\n\treturn l\n}\n\n// MappingWithColon is a mapping type that can be converted from a list of\n// 'key: value' strings\ntype MappingWithColon map[string]string\n\n// HostsList is a list of colon-separated host-ip mappings\ntype HostsList []string\n\n// LoggingConfig the logging configuration for a service\ntype LoggingConfig struct {\n\tDriver  string            `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tOptions map[string]string `yaml:\",omitempty\" json:\"options,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// DeployConfig the deployment configuration for a service\ntype DeployConfig struct {\n\tMode           string         `yaml:\",omitempty\" json:\"mode,omitempty\"`\n\tReplicas       *uint64        `yaml:\",omitempty\" json:\"replicas,omitempty\"`\n\tLabels         Labels         `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tUpdateConfig   *UpdateConfig  `mapstructure:\"update_config\" yaml:\"update_config,omitempty\" json:\"update_config,omitempty\"`\n\tRollbackConfig *UpdateConfig  `mapstructure:\"rollback_config\" yaml:\"rollback_config,omitempty\" json:\"rollback_config,omitempty\"`\n\tResources      Resources      `yaml:\",omitempty\" json:\"resources,omitempty\"`\n\tRestartPolicy  *RestartPolicy `mapstructure:\"restart_policy\" yaml:\"restart_policy,omitempty\" json:\"restart_policy,omitempty\"`\n\tPlacement      Placement      `yaml:\",omitempty\" json:\"placement,omitempty\"`\n\tEndpointMode   string         `mapstructure:\"endpoint_mode\" yaml:\"endpoint_mode,omitempty\" json:\"endpoint_mode,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// HealthCheckConfig the healthcheck configuration for a service\ntype HealthCheckConfig struct {\n\tTest        HealthCheckTest `yaml:\",omitempty\" json:\"test,omitempty\"`\n\tTimeout     *Duration       `yaml:\",omitempty\" json:\"timeout,omitempty\"`\n\tInterval    *Duration       `yaml:\",omitempty\" json:\"interval,omitempty\"`\n\tRetries     *uint64         `yaml:\",omitempty\" json:\"retries,omitempty\"`\n\tStartPeriod *Duration       `mapstructure:\"start_period\" yaml:\"start_period,omitempty\" json:\"start_period,omitempty\"`\n\tDisable     bool            `yaml:\",omitempty\" json:\"disable,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// HealthCheckTest is the command run to test the health of a service\ntype HealthCheckTest []string\n\n// UpdateConfig the service update configuration\ntype UpdateConfig struct {\n\tParallelism     *uint64  `yaml:\",omitempty\" json:\"parallelism,omitempty\"`\n\tDelay           Duration `yaml:\",omitempty\" json:\"delay,omitempty\"`\n\tFailureAction   string   `mapstructure:\"failure_action\" yaml:\"failure_action,omitempty\" json:\"failure_action,omitempty\"`\n\tMonitor         Duration `yaml:\",omitempty\" json:\"monitor,omitempty\"`\n\tMaxFailureRatio float32  `mapstructure:\"max_failure_ratio\" yaml:\"max_failure_ratio,omitempty\" json:\"max_failure_ratio,omitempty\"`\n\tOrder           string   `yaml:\",omitempty\" json:\"order,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Resources the resource limits and reservations\ntype Resources struct {\n\tLimits       *Resource `yaml:\",omitempty\" json:\"limits,omitempty\"`\n\tReservations *Resource `yaml:\",omitempty\" json:\"reservations,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Resource is a resource to be limited or reserved\ntype Resource struct {\n\t// TODO: types to convert from units and ratios\n\tNanoCPUs         string            `mapstructure:\"cpus\" yaml:\"cpus,omitempty\" json:\"cpus,omitempty\"`\n\tMemoryBytes      UnitBytes         `mapstructure:\"memory\" yaml:\"memory,omitempty\" json:\"memory,omitempty\"`\n\tDevices          []DeviceRequest   `mapstructure:\"devices\" yaml:\"devices,omitempty\" json:\"devices,omitempty\"`\n\tGenericResources []GenericResource `mapstructure:\"generic_resources\" yaml:\"generic_resources,omitempty\" json:\"generic_resources,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\ntype DeviceRequest struct {\n\tCapabilities []string `mapstructure:\"capabilities\" yaml:\"capabilities,omitempty\" json:\"capabilities,omitempty\"`\n\tDriver       string   `mapstructure:\"driver\" yaml:\"driver,omitempty\" json:\"driver,omitempty\"`\n\tCount        int64    `mapstructure:\"count\" yaml:\"count,omitempty\" json:\"count,omitempty\"`\n\tIDs          []string `mapstructure:\"device_ids\" yaml:\"device_ids,omitempty\" json:\"device_ids,omitempty\"`\n}\n\n// GenericResource represents a \"user defined\" resource which can\n// only be an integer (e.g: SSD=3) for a service\ntype GenericResource struct {\n\tDiscreteResourceSpec *DiscreteGenericResource `mapstructure:\"discrete_resource_spec\" yaml:\"discrete_resource_spec,omitempty\" json:\"discrete_resource_spec,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// DiscreteGenericResource represents a \"user defined\" resource which is defined\n// as an integer\n// \"Kind\" is used to describe the Kind of a resource (e.g: \"GPU\", \"FPGA\", \"SSD\", ...)\n// Value is used to count the resource (SSD=5, HDD=3, ...)\ntype DiscreteGenericResource struct {\n\tKind  string `json:\"kind\"`\n\tValue int64  `json:\"value\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// UnitBytes is the bytes type\ntype UnitBytes int64\n\n// MarshalYAML makes UnitBytes implement yaml.Marshaller\nfunc (u UnitBytes) MarshalYAML() (interface{}, error) {\n\treturn fmt.Sprintf(\"%d\", u), nil\n}\n\n// MarshalJSON makes UnitBytes implement json.Marshaler\nfunc (u UnitBytes) MarshalJSON() ([]byte, error) {\n\treturn []byte(fmt.Sprintf(`\"%d\"`, u)), nil\n}\n\n// RestartPolicy the service restart policy\ntype RestartPolicy struct {\n\tCondition   string    `yaml:\",omitempty\" json:\"condition,omitempty\"`\n\tDelay       *Duration `yaml:\",omitempty\" json:\"delay,omitempty\"`\n\tMaxAttempts *uint64   `mapstructure:\"max_attempts\" yaml:\"max_attempts,omitempty\" json:\"max_attempts,omitempty\"`\n\tWindow      *Duration `yaml:\",omitempty\" json:\"window,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Placement constraints for the service\ntype Placement struct {\n\tConstraints []string               `yaml:\",omitempty\" json:\"constraints,omitempty\"`\n\tPreferences []PlacementPreferences `yaml:\",omitempty\" json:\"preferences,omitempty\"`\n\tMaxReplicas uint64                 `mapstructure:\"max_replicas_per_node\" yaml:\"max_replicas_per_node,omitempty\" json:\"max_replicas_per_node,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// PlacementPreferences is the preferences for a service placement\ntype PlacementPreferences struct {\n\tSpread string `yaml:\",omitempty\" json:\"spread,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServiceNetworkConfig is the network configuration for a service\ntype ServiceNetworkConfig struct {\n\tPriority    int      `yaml:\",omitempty\" json:\"priotirt,omitempty\"`\n\tAliases     []string `yaml:\",omitempty\" json:\"aliases,omitempty\"`\n\tIpv4Address string   `mapstructure:\"ipv4_address\" yaml:\"ipv4_address,omitempty\" json:\"ipv4_address,omitempty\"`\n\tIpv6Address string   `mapstructure:\"ipv6_address\" yaml:\"ipv6_address,omitempty\" json:\"ipv6_address,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServicePortConfig is the port configuration for a service\ntype ServicePortConfig struct {\n\tMode      string `yaml:\",omitempty\" json:\"mode,omitempty\"`\n\tHostIP    string `mapstructure:\"host_ip\" yaml:\"host_ip,omitempty\" json:\"host_ip,omitempty\"`\n\tTarget    uint32 `yaml:\",omitempty\" json:\"target,omitempty\"`\n\tPublished uint32 `yaml:\",omitempty\" json:\"published,omitempty\"`\n\tProtocol  string `yaml:\",omitempty\" json:\"protocol,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ParsePortConfig parse short syntax for service port configuration\nfunc ParsePortConfig(value string) ([]ServicePortConfig, error) {\n\tvar portConfigs []ServicePortConfig\n\tports, portBindings, err := nat.ParsePortSpecs([]string{value})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// We need to sort the key of the ports to make sure it is consistent\n\tkeys := []string{}\n\tfor port := range ports {\n\t\tkeys = append(keys, string(port))\n\t}\n\tsort.Strings(keys)\n\n\tfor _, key := range keys {\n\t\tport := nat.Port(key)\n\t\tconverted, err := convertPortToPortConfig(port, portBindings)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tportConfigs = append(portConfigs, converted...)\n\t}\n\treturn portConfigs, nil\n}\n\nfunc convertPortToPortConfig(port nat.Port, portBindings map[nat.Port][]nat.PortBinding) ([]ServicePortConfig, error) {\n\tportConfigs := []ServicePortConfig{}\n\tfor _, binding := range portBindings[port] {\n\t\tstartHostPort, endHostPort, err := nat.ParsePortRange(binding.HostPort)\n\n\t\tif err != nil && binding.HostPort != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid hostport binding (%s) for port (%s)\", binding.HostPort, port.Port())\n\t\t}\n\n\t\tfor i := startHostPort; i <= endHostPort; i++ {\n\t\t\tportConfigs = append(portConfigs, ServicePortConfig{\n\t\t\t\tHostIP:    binding.HostIP,\n\t\t\t\tProtocol:  strings.ToLower(port.Proto()),\n\t\t\t\tTarget:    uint32(port.Int()),\n\t\t\t\tPublished: uint32(i),\n\t\t\t\tMode:      \"ingress\",\n\t\t\t})\n\t\t}\n\t}\n\treturn portConfigs, nil\n}\n\n// ServiceVolumeConfig are references to a volume used by a service\ntype ServiceVolumeConfig struct {\n\tType        string               `yaml:\",omitempty\" json:\"type,omitempty\"`\n\tSource      string               `yaml:\",omitempty\" json:\"source,omitempty\"`\n\tTarget      string               `yaml:\",omitempty\" json:\"target,omitempty\"`\n\tReadOnly    bool                 `mapstructure:\"read_only\" yaml:\"read_only,omitempty\" json:\"read_only,omitempty\"`\n\tConsistency string               `yaml:\",omitempty\" json:\"consistency,omitempty\"`\n\tBind        *ServiceVolumeBind   `yaml:\",omitempty\" json:\"bind,omitempty\"`\n\tVolume      *ServiceVolumeVolume `yaml:\",omitempty\" json:\"volume,omitempty\"`\n\tTmpfs       *ServiceVolumeTmpfs  `yaml:\",omitempty\" json:\"tmpfs,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\nconst (\n\t// TypeBind is the type for mounting host dir\n\tVolumeTypeBind = \"bind\"\n\t// TypeVolume is the type for remote storage volumes\n\tVolumeTypeVolume = \"volume\"\n\t// TypeTmpfs is the type for mounting tmpfs\n\tVolumeTypeTmpfs = \"tmpfs\"\n\t// TypeNamedPipe is the type for mounting Windows named pipes\n\tVolumeTypeNamedPipe = \"npipe\"\n)\n\n// ServiceVolumeBind are options for a service volume of type bind\ntype ServiceVolumeBind struct {\n\tPropagation    string `yaml:\",omitempty\" json:\"propagation,omitempty\"`\n\tCreateHostPath bool   `mapstructure:\"create_host_path\" yaml:\"create_host_path,omitempty\" json:\"create_host_path,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Propagation represents the propagation of a mount.\nconst (\n\t// PropagationRPrivate RPRIVATE\n\tPropagationRPrivate string = \"rprivate\"\n\t// PropagationPrivate PRIVATE\n\tPropagationPrivate string = \"private\"\n\t// PropagationRShared RSHARED\n\tPropagationRShared string = \"rshared\"\n\t// PropagationShared SHARED\n\tPropagationShared string = \"shared\"\n\t// PropagationRSlave RSLAVE\n\tPropagationRSlave string = \"rslave\"\n\t// PropagationSlave SLAVE\n\tPropagationSlave string = \"slave\"\n)\n\n// ServiceVolumeVolume are options for a service volume of type volume\ntype ServiceVolumeVolume struct {\n\tNoCopy bool `mapstructure:\"nocopy\" yaml:\"nocopy,omitempty\" json:\"nocopy,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServiceVolumeTmpfs are options for a service volume of type tmpfs\ntype ServiceVolumeTmpfs struct {\n\tSize int64 `yaml:\",omitempty\" json:\"size,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// FileReferenceConfig for a reference to a swarm file object\ntype FileReferenceConfig struct {\n\tSource string  `yaml:\",omitempty\" json:\"source,omitempty\"`\n\tTarget string  `yaml:\",omitempty\" json:\"target,omitempty\"`\n\tUID    string  `yaml:\",omitempty\" json:\"uid,omitempty\"`\n\tGID    string  `yaml:\",omitempty\" json:\"gid,omitempty\"`\n\tMode   *uint32 `yaml:\",omitempty\" json:\"mode,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServiceConfigObjConfig is the config obj configuration for a service\ntype ServiceConfigObjConfig FileReferenceConfig\n\n// ServiceSecretConfig is the secret configuration for a service\ntype ServiceSecretConfig FileReferenceConfig\n\n// UlimitsConfig the ulimit configuration\ntype UlimitsConfig struct {\n\tSingle int `yaml:\",omitempty\" json:\"single,omitempty\"`\n\tSoft   int `yaml:\",omitempty\" json:\"soft,omitempty\"`\n\tHard   int `yaml:\",omitempty\" json:\"hard,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// MarshalYAML makes UlimitsConfig implement yaml.Marshaller\nfunc (u *UlimitsConfig) MarshalYAML() (interface{}, error) {\n\tif u.Single != 0 {\n\t\treturn u.Single, nil\n\t}\n\treturn u, nil\n}\n\n// MarshalJSON makes UlimitsConfig implement json.Marshaller\nfunc (u *UlimitsConfig) MarshalJSON() ([]byte, error) {\n\tif u.Single != 0 {\n\t\treturn json.Marshal(u.Single)\n\t}\n\t// Pass as a value to avoid re-entering this method and use the default implementation\n\treturn json.Marshal(*u)\n}\n\n// NetworkConfig for a network\ntype NetworkConfig struct {\n\tName       string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tDriver     string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tDriverOpts map[string]string      `mapstructure:\"driver_opts\" yaml:\"driver_opts,omitempty\" json:\"driver_opts,omitempty\"`\n\tIpam       IPAMConfig             `yaml:\",omitempty\" json:\"ipam,omitempty\"`\n\tExternal   External               `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tInternal   bool                   `yaml:\",omitempty\" json:\"internal,omitempty\"`\n\tAttachable bool                   `yaml:\",omitempty\" json:\"attachable,omitempty\"`\n\tLabels     Labels                 `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// IPAMConfig for a network\ntype IPAMConfig struct {\n\tDriver     string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tConfig     []*IPAMPool            `yaml:\",omitempty\" json:\"config,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// IPAMPool for a network\ntype IPAMPool struct {\n\tSubnet             string                 `yaml:\",omitempty\" json:\"subnet,omitempty\"`\n\tGateway            string                 `yaml:\",omitempty\" json:\"gateway,omitempty\"`\n\tIPRange            string                 `mapstructure:\"ip_range\" yaml:\"ip_range,omitempty\" json:\"ip_range,omitempty\"`\n\tAuxiliaryAddresses map[string]string      `mapstructure:\"aux_addresses\" yaml:\"aux_addresses,omitempty\" json:\"aux_addresses,omitempty\"`\n\tExtensions         map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// VolumeConfig for a volume\ntype VolumeConfig struct {\n\tName       string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tDriver     string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tDriverOpts map[string]string      `mapstructure:\"driver_opts\" yaml:\"driver_opts,omitempty\" json:\"driver_opts,omitempty\"`\n\tExternal   External               `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tLabels     Labels                 `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// External identifies a Volume or Network as a reference to a resource that is\n// not managed, and should already exist.\n// External.name is deprecated and replaced by Volume.name\ntype External struct {\n\tName       string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tExternal   bool                   `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// MarshalYAML makes External implement yaml.Marshaller\nfunc (e External) MarshalYAML() (interface{}, error) {\n\tif e.Name == \"\" {\n\t\treturn e.External, nil\n\t}\n\treturn External{Name: e.Name}, nil\n}\n\n// MarshalJSON makes External implement json.Marshaller\nfunc (e External) MarshalJSON() ([]byte, error) {\n\tif e.Name == \"\" {\n\t\treturn []byte(fmt.Sprintf(\"%v\", e.External)), nil\n\t}\n\treturn []byte(fmt.Sprintf(`{\"name\": %q}`, e.Name)), nil\n}\n\n// CredentialSpecConfig for credential spec on Windows\ntype CredentialSpecConfig struct {\n\tConfig     string                 `yaml:\",omitempty\" json:\"config,omitempty\"` // Config was added in API v1.40\n\tFile       string                 `yaml:\",omitempty\" json:\"file,omitempty\"`\n\tRegistry   string                 `yaml:\",omitempty\" json:\"registry,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// FileObjectConfig is a config type for a file used by a service\ntype FileObjectConfig struct {\n\tName           string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tFile           string                 `yaml:\",omitempty\" json:\"file,omitempty\"`\n\tExternal       External               `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tLabels         Labels                 `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tDriver         string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tDriverOpts     map[string]string      `mapstructure:\"driver_opts\" yaml:\"driver_opts,omitempty\" json:\"driver_opts,omitempty\"`\n\tTemplateDriver string                 `mapstructure:\"template_driver\" yaml:\"template_driver,omitempty\" json:\"template_driver,omitempty\"`\n\tExtensions     map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\nconst (\n\t// ServiceConditionCompletedSuccessfully is the type for waiting until a service has completed successfully (exit code 0).\n\tServiceConditionCompletedSuccessfully = \"service_completed_successfully\"\n\n\t// ServiceConditionHealthy is the type for waiting until a service is healthy.\n\tServiceConditionHealthy = \"service_healthy\"\n\n\t// ServiceConditionStarted is the type for waiting until a service has started (default).\n\tServiceConditionStarted = \"service_started\"\n)\n\ntype DependsOnConfig map[string]ServiceDependency\n\ntype ServiceDependency struct {\n\tCondition  string                 `yaml:\",omitempty\" json:\"condition,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\ntype ExtendsConfig MappingWithEquals\n\n// SecretConfig for a secret\ntype SecretConfig FileObjectConfig\n\n// ConfigObjConfig is the config for the swarm \"Config\" object\ntype ConfigObjConfig FileObjectConfig\n"
  },
  {
    "path": "pkg/third_party/compose-go/types/types_test.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"testing\"\n\n\t\"gotest.tools/v3/assert\"\n\tis \"gotest.tools/v3/assert/cmp\"\n)\n\nfunc TestParsePortConfig(t *testing.T) {\n\ttestCases := []struct {\n\t\tvalue         string\n\t\texpectedError string\n\t\texpected      []ServicePortConfig\n\t}{\n\t\t{\n\t\t\tvalue: \"80\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol: \"tcp\",\n\t\t\t\t\tTarget:   80,\n\t\t\t\t\tMode:     \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue: \"80:8080\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 80,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue: \"8080:80/tcp\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\tTarget:    80,\n\t\t\t\t\tPublished: 8080,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue: \"80:8080/udp\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 80,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue: \"80-81:8080-8081/tcp\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 80,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\tTarget:    8081,\n\t\t\t\t\tPublished: 81,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue: \"80-82:8080-8082/udp\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 80,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t\tTarget:    8081,\n\t\t\t\t\tPublished: 81,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t\tTarget:    8082,\n\t\t\t\t\tPublished: 82,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue: \"80-82:8080/udp\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 80,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 81,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"udp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 82,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue: \"80-80:8080/tcp\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\tTarget:    8080,\n\t\t\t\t\tPublished: 80,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tvalue:         \"9999999\",\n\t\t\texpectedError: \"Invalid containerPort: 9999999\",\n\t\t},\n\t\t{\n\t\t\tvalue:         \"80/xyz\",\n\t\t\texpectedError: \"Invalid proto: xyz\",\n\t\t},\n\t\t{\n\t\t\tvalue:         \"tcp\",\n\t\t\texpectedError: \"Invalid containerPort: tcp\",\n\t\t},\n\t\t{\n\t\t\tvalue:         \"udp\",\n\t\t\texpectedError: \"Invalid containerPort: udp\",\n\t\t},\n\t\t{\n\t\t\tvalue:         \"\",\n\t\t\texpectedError: \"No port specified: <empty>\",\n\t\t},\n\t\t{\n\t\t\tvalue: \"1.1.1.1:80:80\",\n\t\t\texpected: []ServicePortConfig{\n\t\t\t\t{\n\t\t\t\t\tHostIP:    \"1.1.1.1\",\n\t\t\t\t\tProtocol:  \"tcp\",\n\t\t\t\t\tTarget:    80,\n\t\t\t\t\tPublished: 80,\n\t\t\t\t\tMode:      \"ingress\",\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n\tfor _, tc := range testCases {\n\t\tports, err := ParsePortConfig(tc.value)\n\t\tif tc.expectedError != \"\" {\n\t\t\tassert.Error(t, err, tc.expectedError)\n\t\t\tcontinue\n\t\t}\n\t\tassert.NilError(t, err)\n\t\tassert.Check(t, is.Len(ports, len(tc.expected)))\n\t\tfor _, expectedPortConfig := range tc.expected {\n\t\t\tassertContains(t, ports, expectedPortConfig)\n\t\t}\n\t}\n}\n\nfunc assertContains(t *testing.T, portConfigs []ServicePortConfig, expected ServicePortConfig) {\n\tvar contains = false\n\tfor _, portConfig := range portConfigs {\n\t\tif is.DeepEqual(portConfig, expected)().Success() {\n\t\t\tcontains = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !contains {\n\t\tt.Errorf(\"expected %v to contain %v, did not\", portConfigs, expected)\n\t}\n}\n\nfunc TestSet(t *testing.T) {\n\ts := make(set)\n\ts.append(\"one\")\n\ts.append(\"two\")\n\ts.append(\"three\")\n\ts.append(\"two\")\n\tassert.Equal(t, len(s.toSlice()), 3)\n}\n\ntype foo struct {\n\tBar string\n}\n\nfunc TestExtension(t *testing.T) {\n\tx := Extensions{\n\t\t\"foo\": map[string]interface{}{\n\t\t\t\"bar\": \"zot\",\n\t\t},\n\t}\n\tvar foo foo\n\tok, err := x.Get(\"foo\", &foo)\n\tassert.NilError(t, err)\n\tassert.Check(t, ok == true)\n\tassert.Check(t, foo.Bar == \"zot\")\n\n\tok, err = x.Get(\"qiz\", &foo)\n\tassert.NilError(t, err)\n\tassert.Check(t, ok == false)\n}\n\nfunc TestNewMapping(t *testing.T) {\n\tm := NewMapping([]string{\n\t\t\"FOO=BAR\",\n\t\t\"ZOT=\",\n\t\t\"QIX\",\n\t})\n\tmw := NewMappingWithEquals([]string{\n\t\t\"FOO=BAR\",\n\t\t\"ZOT=\",\n\t\t\"QIX\",\n\t})\n\tassert.Check(t, m[\"FOO\"] == \"BAR\")\n\tassert.Check(t, m[\"ZOT\"] == \"\")\n\tassert.Check(t, m[\"QIX\"] == \"\")\n\tassert.Check(t, *mw[\"FOO\"] == \"BAR\")\n\tassert.Check(t, *mw[\"ZOT\"] == \"\")\n\tassert.Check(t, mw[\"QIX\"] == nil)\n}\n\nfunc TestNetworksByPriority(t *testing.T) {\n\ts := ServiceConfig{\n\t\tNetworks: map[string]*ServiceNetworkConfig{\n\t\t\t\"foo\": nil,\n\t\t\t\"bar\": {\n\t\t\t\tPriority: 10,\n\t\t\t},\n\t\t\t\"zot\": {\n\t\t\t\tPriority: 100,\n\t\t\t},\n\t\t\t\"qix\": {\n\t\t\t\tPriority: 1000,\n\t\t\t},\n\t\t},\n\t}\n\tassert.DeepEqual(t, s.NetworksByPriority(), []string{\"qix\", \"zot\", \"bar\", \"foo\"})\n}\n"
  },
  {
    "path": "pkg/third_party/madmo/fanotify/fanotify.go",
    "content": "// Copyright (c) 2012, Moritz Bitsch <moritzbitsch@googlemail.com>\n//\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// The fanotify package provides a simple fanotify api\npackage fanotify\n\nimport (\n\t\"bufio\"\n\t\"encoding/binary\"\n\t\"os\"\n\t\"syscall\"\n)\n\n// Flags used as first parameter to Initiliaze\nconst (\n\t/* flags used for fanotify_init() */\n\tFAN_CLOEXEC  = 0x00000001\n\tFAN_NONBLOCK = 0x00000002\n\n\t/* These are NOT bitwise flags.  Both bits are used togther.  */\n\tFAN_CLASS_NOTIF       = 0x00000000\n\tFAN_CLASS_CONTENT     = 0x00000004\n\tFAN_CLASS_PRE_CONTENT = 0x00000008\n\n\tFAN_ALL_CLASS_BITS = FAN_CLASS_NOTIF |\n\t\tFAN_CLASS_CONTENT |\n\t\tFAN_CLASS_PRE_CONTENT\n\n\tFAN_UNLIMITED_QUEUE = 0x00000010\n\tFAN_UNLIMITED_MARKS = 0x00000020\n\n\tFAN_ALL_INIT_FLAGS = FAN_CLOEXEC |\n\t\tFAN_NONBLOCK |\n\t\tFAN_ALL_CLASS_BITS |\n\t\tFAN_UNLIMITED_QUEUE |\n\t\tFAN_UNLIMITED_MARKS\n)\n\n// Flags used for the Mark Method\nconst (\n\t/* flags used for fanotify_modify_mark() */\n\tFAN_MARK_ADD                 = 0x00000001\n\tFAN_MARK_REMOVE              = 0x00000002\n\tFAN_MARK_DONT_FOLLOW         = 0x00000004\n\tFAN_MARK_ONLYDIR             = 0x00000008\n\tFAN_MARK_MOUNT               = 0x00000010\n\tFAN_MARK_IGNORED_MASK        = 0x00000020\n\tFAN_MARK_IGNORED_SURV_MODIFY = 0x00000040\n\tFAN_MARK_FLUSH               = 0x00000080\n\n\tFAN_ALL_MARK_FLAGS = FAN_MARK_ADD |\n\t\tFAN_MARK_REMOVE |\n\t\tFAN_MARK_DONT_FOLLOW |\n\t\tFAN_MARK_ONLYDIR |\n\t\tFAN_MARK_MOUNT |\n\t\tFAN_MARK_IGNORED_MASK |\n\t\tFAN_MARK_IGNORED_SURV_MODIFY |\n\t\tFAN_MARK_FLUSH\n)\n\n// Event types\nconst (\n\tFAN_ACCESS        = 0x00000001 /* File was accessed */\n\tFAN_MODIFY        = 0x00000002 /* File was modified */\n\tFAN_CLOSE_WRITE   = 0x00000008 /* Writtable file closed */\n\tFAN_CLOSE_NOWRITE = 0x00000010 /* Unwrittable file closed */\n\tFAN_OPEN          = 0x00000020 /* File was opened */\n\n\tFAN_Q_OVERFLOW = 0x00004000 /* Event queued overflowed */\n\n\tFAN_OPEN_PERM   = 0x00010000 /* File open in perm check */\n\tFAN_ACCESS_PERM = 0x00020000 /* File accessed in perm check */\n\n\tFAN_ONDIR = 0x40000000 /* event occurred against dir */\n\n\tFAN_EVENT_ON_CHILD = 0x08000000 /* interested in child events */\n\n\t/* helper events */\n\tFAN_CLOSE = FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE /* close */\n\n\t/*\n\t * All of the events - we build the list by hand so that we can add flags in\n\t * the future and not break backward compatibility.  Apps will get only the\n\t * events that they originally wanted.  Be sure to add new events here!\n\t */\n\tFAN_ALL_EVENTS = FAN_ACCESS |\n\t\tFAN_MODIFY |\n\t\tFAN_CLOSE |\n\t\tFAN_OPEN\n\n\t\t/*\n\t\t * All events which require a permission response from userspace\n\t\t */\n\tFAN_ALL_PERM_EVENTS = FAN_OPEN_PERM |\n\t\tFAN_ACCESS_PERM\n\n\tFAN_ALL_OUTGOING_EVENTS = FAN_ALL_EVENTS |\n\t\tFAN_ALL_PERM_EVENTS |\n\t\tFAN_Q_OVERFLOW\n\n\tFANOTIFY_METADATA_VERSION = 3\n\n\tFAN_ALLOW = 0x01\n\tFAN_DENY  = 0x02\n\tFAN_NOFD  = -1\n)\n\n// Internal eventMetadata struct, used for fanotify comm\ntype eventMetadata struct {\n\tLen         uint32\n\tVersion     uint8\n\tReserved    uint8\n\tMetadataLen uint16\n\tMask        uint64\n\tFd          int32\n\tPid         int32\n}\n\n// Internal response struct, used for fanotify comm\ntype response struct {\n\tFd       int32\n\tResponse uint32\n}\n\n// Event struct returned from NotifyFD.GetEvent\n//\n// The File member needs to be Closed after usage, to prevent\n// an Fd leak\ntype EventMetadata struct {\n\tLen         uint32\n\tVersion     uint8\n\tReserved    uint8\n\tMetadataLen uint16\n\tMask        uint64\n\tFile        *os.File\n\tPid         int32\n}\n\n// A notify handle, used by all notify functions\ntype NotifyFD struct {\n\tf *os.File\n\tr *bufio.Reader\n}\n\n// Initialize the notify support\nfunc Initialize(faflags, openflags int) (*NotifyFD, error) {\n\tfd, _, errno := syscall.Syscall(syscall.SYS_FANOTIFY_INIT, uintptr(faflags), uintptr(openflags), uintptr(0))\n\n\tvar err error\n\tif errno != 0 {\n\t\terr = errno\n\t}\n\n\tf := os.NewFile(fd, \"\")\n\treturn &NotifyFD{f, bufio.NewReader(f)}, err\n}\n\n// Get an event from the fanotify handle\nfunc (nd *NotifyFD) GetEvent() (*EventMetadata, error) {\n\tev := &eventMetadata{}\n\n\terr := binary.Read(nd.r, binary.LittleEndian, ev)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tres := &EventMetadata{ev.Len, ev.Version, ev.Reserved, ev.MetadataLen, ev.Mask, os.NewFile(uintptr(ev.Fd), \"\"), ev.Pid}\n\n\treturn res, nil\n}\n\n// Send an allow message back to fanotify, used for permission checks\n// If allow is set to true, access is granted\nfunc (nd *NotifyFD) Response(ev *EventMetadata, allow bool) error {\n\tresp := &response{Fd: int32(ev.File.Fd())}\n\n\tif allow {\n\t\tresp.Response = FAN_ALLOW\n\t} else {\n\t\tresp.Response = FAN_DENY\n\t}\n\n\treturn binary.Write(nd.f, binary.LittleEndian, resp)\n}\n"
  },
  {
    "path": "pkg/third_party/madmo/fanotify/fanotify_386.go",
    "content": "// Copyright (c) 2012, Moritz Bitsch <moritzbitsch@googlemail.com>\n//\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\npackage fanotify\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Add/Delete/Modify an Fanotify mark\nfunc (nd *NotifyFD) Mark(flags int, mask uint64, dfd int, path string) error {\n\t_, _, errno := syscall.Syscall6(syscall.SYS_FANOTIFY_MARK, uintptr(nd.f.Fd()), uintptr(flags), uintptr(mask), uintptr(mask>>32), uintptr(dfd), uintptr(unsafe.Pointer(syscall.StringBytePtr(path))))\n\n\tvar err error\n\tif errno != 0 {\n\t\terr = errno\n\t}\n\n\treturn err\n}\n"
  },
  {
    "path": "pkg/third_party/madmo/fanotify/fanotify_amd64.go",
    "content": "// Copyright (c) 2012, Moritz Bitsch <moritzbitsch@googlemail.com>\n//\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\npackage fanotify\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Add/Delete/Modify an Fanotify mark\nfunc (nd *NotifyFD) Mark(flags int, mask uint64, dfd int, path string) error {\n\t_, _, errno := syscall.Syscall6(syscall.SYS_FANOTIFY_MARK, uintptr(nd.f.Fd()), uintptr(flags), uintptr(mask), uintptr(dfd), uintptr(unsafe.Pointer(syscall.StringBytePtr(path))), 0)\n\n\tvar err error\n\tif errno != 0 {\n\t\terr = errno\n\t}\n\n\treturn err\n}\n"
  },
  {
    "path": "pkg/third_party/madmo/fanotify/fanotify_arm.go",
    "content": "// Copyright (c) 2012, Moritz Bitsch <moritzbitsch@googlemail.com>\n//\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\npackage fanotify\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Add/Delete/Modify an Fanotify mark\nfunc (nd *NotifyFD) Mark(flags int, mask uint64, dfd int, path string) error {\n\t_, _, errno := syscall.Syscall6(syscall.SYS_FANOTIFY_MARK, uintptr(nd.f.Fd()), uintptr(flags), uintptr(mask), uintptr(mask>>32), uintptr(dfd), uintptr(unsafe.Pointer(syscall.StringBytePtr(path))))\n\n\tvar err error\n\tif errno != 0 {\n\t\terr = errno\n\t}\n\n\treturn err\n}\n"
  },
  {
    "path": "pkg/third_party/madmo/fanotify/fanotify_arm64.go",
    "content": "// Copyright (c) 2012, Moritz Bitsch <moritzbitsch@googlemail.com>\n//\n// Permission to use, copy, modify, and/or distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\npackage fanotify\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Add/Delete/Modify an Fanotify mark\nfunc (nd *NotifyFD) Mark(flags int, mask uint64, dfd int, path string) error {\n\t_, _, errno := syscall.Syscall6(syscall.SYS_FANOTIFY_MARK, uintptr(nd.f.Fd()), uintptr(flags), uintptr(mask), uintptr(dfd), uintptr(unsafe.Pointer(syscall.StringBytePtr(path))), 0)\n\n\tvar err error\n\tif errno != 0 {\n\t\terr = errno\n\t}\n\n\treturn err\n}\n"
  },
  {
    "path": "pkg/third_party/opencontainers/specs/seccomp.go",
    "content": "package specs\n\n// Seccomp represents syscall restrictions\ntype Seccomp struct {\n\tDefaultAction Action         `json:\"defaultAction\"`\n\tArchitectures []Arch         `json:\"architectures,omitempty\"`\n\tArchMap       []Architecture `json:\"archMap,omitempty\"`\n\tSyscalls      []*Syscall     `json:\"syscalls,omitempty\"`\n}\n\n//ArchMap - in Docker, but not in the Opencontainers spec (yet)\n\ntype Architecture struct {\n\tArch      Arch   `json:\"architecture\"`\n\tSubArches []Arch `json:\"subArchitectures\"`\n}\n\n// Arch - architecture type\n// Additional architectures permitted to be used for system calls\n// By default only the native architecture of the kernel is permitted\ntype Arch string\n\n// Architecture types\nconst (\n\tArchX86     Arch = \"SCMP_ARCH_X86\"\n\tArchX86_64  Arch = \"SCMP_ARCH_X86_64\"\n\tArchX32     Arch = \"SCMP_ARCH_X32\"\n\tArchARM     Arch = \"SCMP_ARCH_ARM\"\n\tArchAARCH64 Arch = \"SCMP_ARCH_AARCH64\"\n)\n\n// Action taken upon Seccomp rule match\ntype Action string\n\n// Action types\nconst (\n\tActKill  Action = \"SCMP_ACT_KILL\"\n\tActTrap  Action = \"SCMP_ACT_TRAP\"\n\tActErrno Action = \"SCMP_ACT_ERRNO\"\n\tActTrace Action = \"SCMP_ACT_TRACE\"\n\tActAllow Action = \"SCMP_ACT_ALLOW\"\n)\n\n// Operator used to match syscall arguments in Seccomp\ntype Operator string\n\n// Operator types\nconst (\n\tOpNotEqual     Operator = \"SCMP_CMP_NE\"\n\tOpLessThan     Operator = \"SCMP_CMP_LT\"\n\tOpLessEqual    Operator = \"SCMP_CMP_LE\"\n\tOpEqualTo      Operator = \"SCMP_CMP_EQ\"\n\tOpGreaterEqual Operator = \"SCMP_CMP_GE\"\n\tOpGreaterThan  Operator = \"SCMP_CMP_GT\"\n\tOpMaskedEqual  Operator = \"SCMP_CMP_MASKED_EQ\"\n)\n\n// Arg used for matching specific syscall arguments in Seccomp\ntype Arg struct {\n\tIndex    uint     `json:\"index\"`\n\tValue    uint64   `json:\"value\"`\n\tValueTwo uint64   `json:\"valueTwo,omitempty\"`\n\tOp       Operator `json:\"op\"`\n}\n\n// Syscall is used to match a syscall in Seccomp\ntype Syscall struct {\n\tName     string   `json:\"name,omitempty\"`\n\tNames    []string `json:\"names,omitempty\"`\n\tAction   Action   `json:\"action\"`\n\tArgs     []*Arg   `json:\"args,omitempty\"`\n\tComment  string   `json:\"comment,omitempty\"`\n\tIncludes Filter   `json:\"includes,omitempty\"`\n\tExcludes Filter   `json:\"excludes,omitempty\"`\n}\n\n//Opencontainers spec only includes the 'Names' field\n//Docker also includes the old/original 'Name' field\n//Docker only: Comment, Includes, Excludes\n\n// Filter is used to conditionally apply Seccomp rules\ntype Filter struct {\n\tCaps      []string `json:\"caps,omitempty\"`\n\tArches    []string `json:\"arches,omitempty\"`\n\tMinKernel string   `json:\"minKernel,omitempty\"`\n}\n"
  },
  {
    "path": "pkg/util/errutil/errutil.go",
    "content": "package errutil\n\nimport (\n\t\"fmt\"\n\t\"runtime/debug\"\n\t\"strings\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n\t\"github.com/slimtoolkit/slim/pkg/version\"\n)\n\n// FailOnWithInfo logs the error information with additional context info (terminates the application)\nfunc FailOnWithInfo(err error, info map[string]string) {\n\tif err != nil {\n\t\tshowInfo(info)\n\n\t\tstackData := debug.Stack()\n\t\tlog.WithError(err).WithFields(log.Fields{\n\t\t\t\"version\": version.Current(),\n\t\t\t\"stack\":   string(stackData),\n\t\t}).Fatal(\"slim: failure\")\n\n\t\tshowCommunityInfo()\n\t}\n}\n\n// FailOn logs the error information (terminates the application)\nfunc FailOn(err error) {\n\tif err != nil {\n\t\tstackData := debug.Stack()\n\t\tlog.WithError(err).WithFields(log.Fields{\n\t\t\t\"version\": version.Current(),\n\t\t\t\"stack\":   string(stackData),\n\t\t}).Fatal(\"slim: failure\")\n\n\t\tshowCommunityInfo()\n\t}\n}\n\n// WarnOn logs the error information as a warning\nfunc WarnOn(err error) {\n\tif err != nil {\n\t\tstackData := debug.Stack()\n\t\tlog.WithError(err).WithFields(log.Fields{\n\t\t\t\"version\": version.Current(),\n\t\t\t\"stack\":   string(stackData),\n\t\t}).Warn(\"slim: warning\")\n\t}\n}\n\n// FailWhen logs the given message if the condition is true (terminates the application)\nfunc FailWhen(cond bool, msg string) {\n\tif cond {\n\t\tstackData := debug.Stack()\n\t\tlog.WithFields(log.Fields{\n\t\t\t\"version\": version.Current(),\n\t\t\t\"error\":   msg,\n\t\t\t\"stack\":   string(stackData),\n\t\t}).Fatal(\"slim: failure\")\n\n\t\tshowCommunityInfo()\n\t}\n}\n\n// Fail logs the given messages and terminates the application\nfunc Fail(msg string) {\n\tstackData := debug.Stack()\n\tlog.WithFields(log.Fields{\n\t\t\"version\": version.Current(),\n\t\t\"error\":   msg,\n\t\t\"stack\":   string(stackData),\n\t}).Fatal(\"slim: failure\")\n\n\tshowCommunityInfo()\n}\n\nfunc showInfo(info map[string]string) {\n\tif len(info) > 0 {\n\t\tfmt.Println(\"Error Context Info:\")\n\t\tfor k, v := range info {\n\t\t\tfmt.Printf(\"'%s': '%s'\\n\", k, v)\n\t\t}\n\t}\n}\n\nfunc showCommunityInfo() {\n\tfmt.Printf(\"slim: message='Github discussions' info='%s'\\n\", consts.CommunityDiscussions)\n\tfmt.Printf(\"slim: message='CNCF Slack' info='%s'\\n\", consts.CommunityCNCFSlack)\n\tfmt.Printf(\"slim: message='join the Discord server to get help with this failure' info='%s'\\n\", consts.CommunityDiscord)\n\tfmt.Printf(\"slim: message='join the Gitter channel to get help with this failure' info='%s'\\n\", consts.CommunityGitter)\n}\n\n// exec.Command().Run() and its derivatives sometimes return\n// \"wait: no child processes\" or \"waitid: no child processes\"\n// even for successful runs. It's a race condition between the\n// Start() + Wait() calls and the actual underlying command\n// execution. The shorter the execution time, the higher are\n// the chances to get this error.\n//\n// Some examples from the wild:\n//   - https://github.com/gitpod-io/gitpod/blob/405d44b74b5ac1dffe20e076d59c2b5986f18960/components/common-go/process/process.go#L18.\nfunc IsNoChildProcesses(err error) bool {\n\tif err == nil {\n\t\treturn false\n\t}\n\n\treturn strings.HasSuffix(err.Error(), \": no child processes\")\n}\n"
  },
  {
    "path": "pkg/util/fsutil/fsutil.go",
    "content": "package fsutil\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"golang.org/x/sys/unix\"\n\n\t\"github.com/slimtoolkit/slim/pkg/pdiscover\"\n\t\"github.com/slimtoolkit/slim/pkg/util/errutil\"\n\n\t\"github.com/bmatcuk/doublestar\"\n\tlog \"github.com/sirupsen/logrus\"\n)\n\n// File permission bits (execute bits only)\nconst (\n\tFilePermUserExe  = 0100\n\tFilePermGroupExe = 0010\n\tFilePermOtherExe = 0001\n)\n\n// Native FileMode special bits mask\nconst FMSpecialBits = os.ModeSticky | os.ModeSetgid | os.ModeSetuid\n\n// Native FileModes for extra flags\nconst (\n\tFMSticky = 01000\n\tFMSetgid = 02000\n\tFMSetuid = 04000\n)\n\n// Native FileMode bits for extra flags\nconst (\n\tBitSticky = 1\n\tBitSetgid = 2\n\tBitSetuid = 4\n)\n\n// Directory and file related errors\nvar (\n\tErrNoFileData                = errors.New(\"no file data\")\n\tErrNoSrcDir                  = errors.New(\"no source directory path\")\n\tErrNoDstDir                  = errors.New(\"no destination directory path\")\n\tErrSameDir                   = errors.New(\"source and destination directories are the same\")\n\tErrSrcDirNotExist            = errors.New(\"source directory doesn't exist\")\n\tErrSrcNotDir                 = errors.New(\"source is not a directory\")\n\tErrSrcNotRegularFile         = errors.New(\"source is not a regular file\")\n\tErrUnsupportedFileObjectType = errors.New(\"unsupported file object type\")\n)\n\n// FileModeExtraUnix2Go converts the standard unix filemode for the extra flags to the Go version\nfunc FileModeExtraUnix2Go(mode uint32) os.FileMode {\n\tswitch mode {\n\tcase FMSticky:\n\t\treturn os.ModeSticky\n\tcase FMSetgid:\n\t\treturn os.ModeSetgid\n\tcase FMSetuid:\n\t\treturn os.ModeSetuid\n\t}\n\n\treturn 0\n}\n\n// FileModeExtraBitUnix2Go converts the standard unix filemode bit for the extra flags to the filemode in Go\nfunc FileModeExtraBitUnix2Go(bit uint32) os.FileMode {\n\tswitch bit {\n\tcase BitSticky:\n\t\treturn os.ModeSticky\n\tcase BitSetgid:\n\t\treturn os.ModeSetgid\n\tcase BitSetuid:\n\t\treturn os.ModeSetuid\n\t}\n\n\treturn 0\n}\n\n// FileModeExtraBitsUnix2Go converts the standard unix filemode bits for the extra flags to the filemode flags in Go\nfunc FileModeExtraBitsUnix2Go(bits uint32) os.FileMode {\n\tvar mode os.FileMode\n\n\tif bits&BitSticky != 0 {\n\t\tmode |= os.ModeSticky\n\t}\n\n\tif bits&BitSetgid != 0 {\n\t\tmode |= os.ModeSetgid\n\t}\n\n\tif bits&BitSetuid != 0 {\n\t\tmode |= os.ModeSetuid\n\t}\n\n\treturn mode\n}\n\n// FileModeIsSticky checks if FileMode has the sticky bit set\nfunc FileModeIsSticky(mode os.FileMode) bool {\n\tif mode&os.ModeSticky != 0 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// FileModeIsSetgid checks if FileMode has the setgid bit set\nfunc FileModeIsSetgid(mode os.FileMode) bool {\n\tif mode&os.ModeSetgid != 0 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// FileModeIsSetuid checks if FileMode has the setuid bit set\nfunc FileModeIsSetuid(mode os.FileMode) bool {\n\tif mode&os.ModeSetuid != 0 {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nconst (\n\trootStateKey           = \".slim-state\"\n\treleasesStateKey       = \"releases\"\n\timageStateBaseKey      = \"images\"\n\timageStateArtifactsKey = \"artifacts\"\n\tstateArtifactsPerms    = 0777\n\treleaseArtifactsPerms  = 0740\n)\n\nvar badInstallPaths = [...]string{\n\t\"/usr/local/bin\",\n\t\"/usr/local/sbin\",\n\t\"/usr/bin\",\n\t\"/usr/sbin\",\n\t\"/bin\",\n\t\"/sbin\",\n}\n\nconst (\n\ttmpPath        = \"/tmp\"\n\tstateTmpPath   = \"/tmp/slim-state\"\n\tsensorFileName = \"slim-sensor\"\n)\n\n// AccessInfo provides the file object access properties\ntype AccessInfo struct {\n\tFlags     os.FileMode\n\tPermsOnly bool\n\tUID       int\n\tGID       int\n}\n\nfunc NewAccessInfo() *AccessInfo {\n\treturn &AccessInfo{\n\t\tFlags: 0,\n\t\tUID:   -1,\n\t\tGID:   -1,\n\t}\n}\n\n// Remove removes the artifacts generated during the current application execution\nfunc Remove(artifactLocation string) error {\n\treturn os.RemoveAll(artifactLocation)\n}\n\n// Touch creates the target file or updates its timestamp\nfunc Touch(target string) error {\n\ttargetDirPath := FileDir(target)\n\tif _, err := os.Stat(targetDirPath); err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\terr = os.MkdirAll(targetDirPath, 0777)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\treturn err\n\t\t}\n\t}\n\n\ttf, err := os.OpenFile(target, os.O_RDONLY|os.O_CREATE, 0644)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttf.Close()\n\n\ttnow := time.Now().UTC()\n\terr = os.Chtimes(target, tnow, tnow)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// Exists returns true if the target file system object exists\nfunc Exists(target string) bool {\n\tif _, err := os.Stat(target); err != nil {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// DirExists returns true if the target exists and it's a directory\nfunc DirExists(target string) bool {\n\tif info, err := os.Stat(target); err == nil && info.IsDir() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// IsDir returns true if the target file system object is a directory\nfunc IsDir(target string) bool {\n\tinfo, err := os.Stat(target)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn info.IsDir()\n}\n\n// IsRegularFile returns true if the target file system object is a regular file\nfunc IsRegularFile(target string) bool {\n\tinfo, err := os.Lstat(target)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn info.Mode().IsRegular()\n}\n\n// IsSymlink returns true if the target file system object is a symlink\nfunc IsSymlink(target string) bool {\n\tinfo, err := os.Lstat(target)\n\tif err != nil {\n\t\treturn false\n\t}\n\n\treturn (info.Mode() & os.ModeSymlink) == os.ModeSymlink\n}\n\n// IsTarFile returns true if the target file system object is a tar archive\nfunc IsTarFile(target string) bool {\n\ttf, err := os.Open(target)\n\tif err != nil {\n\t\tlog.Debugf(\"fsutil.IsTarFile(%s): error - %v\", target, err)\n\t\treturn false\n\t}\n\n\tdefer tf.Close()\n\ttr := tar.NewReader(tf)\n\t_, err = tr.Next()\n\tif err != nil {\n\t\tlog.Debugf(\"fsutil.IsTarFile(%s): error - %v\", target, err)\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nfunc HasReadAccess(dst string) (bool, error) {\n\terr := unix.Access(dst, unix.R_OK)\n\tif err == nil {\n\t\treturn true, nil\n\t}\n\n\tif err == unix.EACCES {\n\t\treturn false, nil\n\t}\n\n\treturn false, err\n}\n\nfunc HasWriteAccess(dst string) (bool, error) {\n\terr := unix.Access(dst, unix.W_OK)\n\tif err == nil {\n\t\treturn true, nil\n\t}\n\n\tif err == unix.EACCES {\n\t\treturn false, nil\n\t}\n\n\treturn false, err\n}\n\n// SetAccess updates the access permissions on the destination\nfunc SetAccess(dst string, access *AccessInfo) error {\n\tif dst == \"\" || access == nil {\n\t\treturn nil\n\t}\n\n\tif access.Flags != 0 {\n\t\tdstInfo, err := os.Stat(dst)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfmode := dstInfo.Mode()\n\t\tfmode = fmode &^ os.ModePerm\n\t\tfmode |= (access.Flags & os.ModePerm)\n\n\t\tif !access.PermsOnly {\n\t\t\tfmode = fmode &^ FMSpecialBits\n\t\t\tfmode |= (access.Flags & FMSpecialBits)\n\t\t}\n\n\t\tif err := os.Chmod(dst, fmode); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif access.UID > -1 || access.GID > -1 {\n\t\tif err := os.Chown(dst, access.UID, access.GID); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CopyFile copies the source file system object to the desired destination\nfunc CopyFile(clone bool, src, dst string, makeDir bool) error {\n\tlog.Debugf(\"CopyFile(%v,%v,%v,%v)\", clone, src, dst, makeDir)\n\n\tinfo, err := os.Lstat(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch {\n\tcase info.Mode().IsRegular():\n\t\treturn CopyRegularFile(clone, src, dst, makeDir)\n\tcase (info.Mode() & os.ModeSymlink) == os.ModeSymlink:\n\t\treturn CopySymlinkFile(clone, src, dst, makeDir)\n\tdefault:\n\t\treturn ErrUnsupportedFileObjectType\n\t}\n}\n\n// CopySymlinkFile copies a symlink file\nfunc CopySymlinkFile(clone bool, src, dst string, makeDir bool) error {\n\tlog.Debugf(\"CopySymlinkFile(%v,%v,%v)\", src, dst, makeDir)\n\n\tif makeDir {\n\t\t//srcDirName := FileDir(src)\n\t\tdstDirName := FileDir(dst)\n\n\t\tif _, err := os.Stat(dstDirName); err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tvar dirMode os.FileMode = 0777\n\t\t\t\t//need to make it work for non-default user use cases\n\t\t\t\t//if clone {\n\t\t\t\t//\tsrcDirInfo, err := os.Stat(srcDirName)\n\t\t\t\t//\tif err != nil {\n\t\t\t\t//\t\treturn err\n\t\t\t\t//\t}\n\t\t\t\t//\n\t\t\t\t//\tdirMode = srcDirInfo.Mode()\n\t\t\t\t//}\n\n\t\t\t\terr = os.MkdirAll(dstDirName, dirMode)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\tlinkRef, err := os.Readlink(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = os.Symlink(linkRef, dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif clone {\n\t\tsrcInfo, err := os.Lstat(src)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif sysStat, ok := srcInfo.Sys().(*syscall.Stat_t); ok {\n\t\t\tssi := SysStatInfo(sysStat)\n\t\t\tif ssi.Ok {\n\t\t\t\tif err := UpdateSymlinkTimes(dst, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\t\t\tlog.Warnf(\"CopySymlinkFile(%v,%v) - UpdateSymlinkTimes error\", src, dst)\n\t\t\t\t}\n\n\t\t\t\tif err := os.Lchown(dst, int(ssi.Uid), int(ssi.Gid)); err != nil {\n\t\t\t\t\tlog.Warnf(\"CopySymlinkFile(%v,%v)- unable to change owner\", src, dst)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Warnf(\"CopySymlinkFile(%v,%v)- unable to get Stat_t\", src, dst)\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype dirInfo struct {\n\tsrc   string\n\tdst   string\n\tperms os.FileMode\n\tsys   SysStat\n}\n\nfunc cloneDirPath(src, dst string) {\n\tsrc, err := filepath.Abs(src)\n\tif err != nil {\n\t\terrutil.FailOn(err)\n\t}\n\tdst, err = filepath.Abs(dst)\n\tif err != nil {\n\t\terrutil.FailOn(err)\n\t}\n\n\tvar dirs []dirInfo\n\tfor {\n\t\tif src == \"/\" {\n\t\t\tbreak\n\t\t}\n\n\t\tsrcDirName := filepath.Base(src)\n\t\tdstDirName := filepath.Base(dst)\n\n\t\tif srcDirName != dstDirName {\n\t\t\tbreak\n\t\t}\n\n\t\tsrcInfo, err := os.Stat(src)\n\t\tif err != nil {\n\t\t\terrutil.FailOn(err)\n\t\t}\n\n\t\tif !srcInfo.IsDir() {\n\t\t\terrutil.Fail(\"not a directory\")\n\t\t}\n\n\t\tif Exists(dst) {\n\t\t\tbreak\n\t\t}\n\n\t\tdi := dirInfo{\n\t\t\tsrc:   src,\n\t\t\tdst:   dst,\n\t\t\tperms: srcInfo.Mode(),\n\t\t}\n\n\t\tif sysStat, ok := srcInfo.Sys().(*syscall.Stat_t); ok {\n\t\t\tdi.sys = SysStatInfo(sysStat)\n\t\t}\n\n\t\tdirs = append([]dirInfo{di}, dirs...)\n\n\t\tsrc = FileDir(src)\n\t\tdst = FileDir(dst)\n\t}\n\n\tfor _, dir := range dirs {\n\t\tif Exists(dir.dst) {\n\t\t\tlog.Debugf(\"cloneDirPath() - dst dir exists - %v\", dir.dst)\n\t\t\tcontinue\n\t\t}\n\n\t\t//using os.MkdirAll instead of os.Mkdir to make sure we don't miss any intermediate directories\n\t\t//need to research when we might miss intermediate directories\n\t\terr = os.MkdirAll(dir.dst, 0777)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"cloneDirPath() - os.MkdirAll(%v) error - %v\", dir.dst, err)\n\t\t}\n\t\t//if err != nil && !os.IsExist(err) {\n\t\t//\terrutil.FailOn(err)\n\t\t//}\n\n\t\tif err == nil {\n\t\t\tif err := os.Chmod(dir.dst, dir.perms); err != nil {\n\t\t\t\tlog.Warnf(\"cloneDirPath() - unable to set perms (%v) - %v\", dir.dst, err)\n\t\t\t}\n\n\t\t\tif dir.sys.Ok {\n\t\t\t\tif err := UpdateFileTimes(dir.dst, dir.sys.Atime, dir.sys.Mtime); err != nil {\n\t\t\t\t\tlog.Warnf(\"cloneDirPath() - UpdateFileTimes error (%v) - %v\", dir.dst, err)\n\t\t\t\t}\n\n\t\t\t\tif err := os.Chown(dir.dst, int(dir.sys.Uid), int(dir.sys.Gid)); err != nil {\n\t\t\t\t\tlog.Warnf(\"cloneDirPath()- unable to change owner (%v) - %v\", dir.dst, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// CopyRegularFile copies a regular file\nfunc CopyRegularFile(clone bool, src, dst string, makeDir bool) error {\n\tlog.Debugf(\"CopyRegularFile(%v,%v,%v,%v)\", clone, src, dst, makeDir)\n\t//'clone' should be true only for the dst files that need to clone the dir properties from src\n\ts, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer s.Close()\n\n\tsrcFileInfo, err := s.Stat()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !srcFileInfo.Mode().IsRegular() {\n\t\treturn ErrSrcNotRegularFile\n\t}\n\n\tif makeDir {\n\t\tdstDirPath := FileDir(dst)\n\t\tif _, err := os.Stat(dstDirPath); err != nil {\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\tsrcDirPath := FileDir(src)\n\n\t\t\t\tif clone {\n\t\t\t\t\tcloneDirPath(srcDirPath, dstDirPath)\n\t\t\t\t} else {\n\t\t\t\t\tvar dirMode os.FileMode = 0777\n\t\t\t\t\terr = os.MkdirAll(dstDirPath, dirMode)\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\t//try copying the timestamps too (even without cloning)\n\t\t\t\t\tsrcDirInfo, err := os.Stat(srcDirPath)\n\t\t\t\t\tif err == nil {\n\t\t\t\t\t\tif sysStat, ok := srcDirInfo.Sys().(*syscall.Stat_t); ok {\n\t\t\t\t\t\t\tssi := SysStatInfo(sysStat)\n\t\t\t\t\t\t\tif ssi.Ok {\n\t\t\t\t\t\t\t\tif err := UpdateFileTimes(dstDirPath, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\t\t\t\t\t\t\tlog.Warnf(\"CopyRegularFile() - UpdateFileTimes(%v) error - %v\", dstDirPath, 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} else {\n\t\t\t\t\t\tlog.Warnf(\"CopyRegularFile() - os.Stat(%v) error - %v\", srcDirPath, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\td, err := os.Create(dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif srcFileInfo.Size() > 0 {\n\t\twritten, err := io.Copy(d, s)\n\t\tif err != nil {\n\t\t\td.Close()\n\t\t\treturn err\n\t\t}\n\n\t\tif written != srcFileInfo.Size() {\n\t\t\tlog.Debugf(\"CopyRegularFile(%v,%v,%v) - copy data mismatch - %v/%v\",\n\t\t\t\tsrc, dst, makeDir, written, srcFileInfo.Size())\n\t\t\td.Close()\n\t\t\treturn fmt.Errorf(\"%s -> %s: partial copy - %d/%d\",\n\t\t\t\tsrc, dst, written, srcFileInfo.Size())\n\t\t}\n\t}\n\n\t//Need to close dst file before chmod works the right way\n\tif err := d.Close(); err != nil {\n\t\tlog.Debugf(\"CopyRegularFile() - d.Close error - %v\", err)\n\t\treturn err\n\t}\n\n\tif clone {\n\t\tif err := os.Chmod(dst, srcFileInfo.Mode()); err != nil {\n\t\t\tlog.Warnf(\"CopyRegularFile(%v,%v) - unable to set mode\", src, dst)\n\t\t\treturn err\n\t\t}\n\n\t\tif sysStat, ok := srcFileInfo.Sys().(*syscall.Stat_t); ok {\n\t\t\tssi := SysStatInfo(sysStat)\n\t\t\tif ssi.Ok {\n\t\t\t\tif err := UpdateFileTimes(dst, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\t\t\tlog.Warnf(\"CopyRegularFile(%v,%v) - UpdateFileTimes error\", src, dst)\n\t\t\t\t}\n\n\t\t\t\tif err := os.Chown(dst, int(ssi.Uid), int(ssi.Gid)); err != nil {\n\t\t\t\t\tlog.Warnf(\"CopyRegularFile(%v,%v)- unable to change owner\", src, dst)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Warnf(\"CopyRegularFile(%v,%v)- unable to get Stat_t\", src, dst)\n\t\t}\n\t} else {\n\t\tif err := os.Chmod(dst, 0777); err != nil {\n\t\t\tlog.Warnf(\"CopyRegularFile(%v,%v) - unable to set mode\", src, dst)\n\t\t}\n\n\t\tif sysStat, ok := srcFileInfo.Sys().(*syscall.Stat_t); ok {\n\t\t\tssi := SysStatInfo(sysStat)\n\t\t\tif ssi.Ok {\n\t\t\t\tif err := UpdateFileTimes(dst, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\t\t\tlog.Warnf(\"CopyRegularFile(%v,%v) - UpdateFileTimes error\", src, dst)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Warnf(\"CopyRegularFile(%v,%v)- unable to get Stat_t\", src, dst)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CopyAndObfuscateFile copies a regular file and performs basic file reference obfuscation\nfunc CopyAndObfuscateFile(\n\tclone bool,\n\tsrc string,\n\tdst string,\n\tmakeDir bool) error {\n\tlog.Debugf(\"CopyAndObfuscateFile(%v,%v,%v,%v)\", clone, src, dst, makeDir)\n\n\t//need to preserve the extension because some of the app stacks\n\t//depend on it for its compile/run time behavior\n\tbase := filepath.Base(dst)\n\text := filepath.Ext(base)\n\tbase = strings.ReplaceAll(base, \".\", \"..\")\n\tbase = fmt.Sprintf(\".d.%s\", base)\n\tif ext != \"\" {\n\t\tbase = fmt.Sprintf(\"%s%s\", base, ext)\n\t}\n\n\tdirPart := filepath.Dir(dst)\n\tdstData := filepath.Join(dirPart, base)\n\terr := CopyRegularFile(clone, src, dstData, makeDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = os.Symlink(base, dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// AppendToFile appends the provided data to the target file\nfunc AppendToFile(target string, data []byte, preserveTimes bool) error {\n\tif target == \"\" || len(data) == 0 {\n\t\treturn nil\n\t}\n\n\ttfi, err := os.Stat(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar ssi SysStat\n\tif rawSysStat, ok := tfi.Sys().(*syscall.Stat_t); ok {\n\t\tssi = SysStatInfo(rawSysStat)\n\t}\n\n\ttf, err := os.OpenFile(target, os.O_WRONLY|os.O_APPEND, 0644)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer tf.Close()\n\n\t_, err = tf.Write(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif preserveTimes && ssi.Ok {\n\t\tif err := UpdateFileTimes(target, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\tlog.Warnf(\"AppendToFile(%v) - UpdateFileTimes error\", target)\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype ReplaceInfo struct {\n\tPathSuffix   string\n\tIsMatchRegex string\n\tMatch        string\n\tReplace      string\n}\n\n// ReplaceFileData replaces the selected file bytes with the caller provided bytes\nfunc ReplaceFileData(target string, replace []ReplaceInfo, preserveTimes bool) error {\n\tif target == \"\" || len(replace) == 0 {\n\t\treturn nil\n\t}\n\n\ttfi, err := os.Stat(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar ssi SysStat\n\tif rawSysStat, ok := tfi.Sys().(*syscall.Stat_t); ok {\n\t\tssi = SysStatInfo(rawSysStat)\n\t}\n\n\traw, err := os.ReadFile(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar replaced bool\n\tfor _, r := range replace {\n\t\tif r.PathSuffix != \"\" {\n\t\t\tif !strings.HasSuffix(target, r.PathSuffix) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif r.Match == \"\" || r.Replace == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\traw = bytes.ReplaceAll(raw, []byte(r.Match), []byte(r.Replace))\n\t\treplaced = true\n\t}\n\n\tif replaced {\n\t\terr = os.WriteFile(target, raw, 0644)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif preserveTimes && ssi.Ok {\n\t\t\tif err := UpdateFileTimes(target, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\t\tlog.Warnf(\"ReplaceFileData(%v) - UpdateFileTimes error\", target)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype DataUpdaterFn func(target string, data []byte) ([]byte, error)\n\n// UpdateFileData updates all file data in target file using the updater function\nfunc UpdateFileData(target string, updater DataUpdaterFn, preserveTimes bool) error {\n\tif target == \"\" || updater == nil {\n\t\treturn nil\n\t}\n\n\ttfi, err := os.Stat(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar ssi SysStat\n\tif rawSysStat, ok := tfi.Sys().(*syscall.Stat_t); ok {\n\t\tssi = SysStatInfo(rawSysStat)\n\t}\n\n\traw, err := os.ReadFile(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\traw, err = updater(target, raw)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = os.WriteFile(target, raw, 0644)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif preserveTimes && ssi.Ok {\n\t\tif err := UpdateFileTimes(target, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\tlog.Warnf(\"ReplaceFileData(%v) - UpdateFileTimes error\", target)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc copyFileObjectHandler(\n\tclone bool,\n\tsrcBase, dstBase string,\n\tcopyRelPath, skipErrors bool,\n\texcludePatterns []string, ignoreDirNames, ignoreFileNames map[string]struct{},\n\terrs *[]error) filepath.WalkFunc {\n\tvar foCount uint64\n\n\treturn func(path string, info os.FileInfo, err error) error {\n\t\tfoCount++\n\n\t\tif err != nil {\n\n\t\t\tif skipErrors {\n\t\t\t\t*errs = append(*errs, err)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\treturn err\n\t\t}\n\n\t\tfoBase := filepath.Base(path)\n\n\t\tvar isIgnored bool\n\t\tfor _, xpattern := range excludePatterns {\n\t\t\tfound, err := doublestar.Match(xpattern, path)\n\t\t\tif err != nil {\n\t\t\t\tlog.Warnf(\"copyFileObjectHandler - [%v] excludePatterns Match error - %v\\n\", path, err)\n\t\t\t\t//should only happen when the pattern is malformed\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif found {\n\t\t\t\tisIgnored = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\t/*\n\t\t\tif _, ok := ignorePaths[path]; ok {\n\t\t\t\tisIgnored = true\n\t\t\t}\n\n\t\t\tfor prefix := range ignorePrefixes {\n\t\t\t\tif strings.HasPrefix(path, prefix) {\n\t\t\t\t\tisIgnored = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t*/\n\n\t\tvar targetPath string\n\t\tif copyRelPath {\n\t\t\ttargetPath = filepath.Join(dstBase, strings.TrimPrefix(path, srcBase))\n\t\t} else {\n\t\t\ttargetPath = filepath.Join(dstBase, path)\n\t\t}\n\n\t\tswitch {\n\t\tcase info.Mode().IsDir():\n\t\t\tif isIgnored {\n\t\t\t\tlog.Debugf(\"dir path (%v) is ignored (skipping dir)...\", path)\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\t//todo: refactor\n\t\t\tif _, ok := ignoreDirNames[foBase]; ok {\n\t\t\t\tlog.Debugf(\"dir name (%v) in ignoreDirNames list (skipping dir)...\", foBase)\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tif _, err := os.Stat(targetPath); err != nil {\n\t\t\t\tif os.IsNotExist(err) {\n\t\t\t\t\tif clone {\n\t\t\t\t\t\tcloneDirPath(path, targetPath)\n\t\t\t\t\t} else {\n\t\t\t\t\t\terr = os.MkdirAll(targetPath, 0777)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\tif skipErrors {\n\t\t\t\t\t\t\t\t*errs = append(*errs, err)\n\t\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tsrcDirInfo, err := os.Stat(path)\n\t\t\t\t\t\tif err == nil {\n\t\t\t\t\t\t\tif sysStat, ok := srcDirInfo.Sys().(*syscall.Stat_t); ok {\n\t\t\t\t\t\t\t\tssi := SysStatInfo(sysStat)\n\t\t\t\t\t\t\t\tif ssi.Ok {\n\t\t\t\t\t\t\t\t\tif err := UpdateFileTimes(targetPath, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\t\t\t\t\t\t\t\tlog.Warnf(\"copyFileObjectHandler() - UpdateFileTimes(%v) error - %v\", targetPath, err)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlog.Warnf(\"copyFileObjectHandler() - os.Stat(%v) error - %v\", path, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tlog.Warnf(\"copyFileObjectHandler() - os.Stat(%v) error - %v\", targetPath, err)\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase info.Mode().IsRegular():\n\t\t\tif isIgnored {\n\t\t\t\tlog.Debugf(\"file path (%v) is ignored (skipping file)...\", path)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\t//todo: refactor\n\t\t\tif _, ok := ignoreFileNames[foBase]; ok {\n\t\t\t\tlog.Debugf(\"file name (%v) in ignoreFileNames list (skipping file)...\", foBase)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\terr = CopyRegularFile(clone, path, targetPath, true)\n\t\t\tif err != nil {\n\t\t\t\tif skipErrors {\n\t\t\t\t\t*errs = append(*errs, err)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase (info.Mode() & os.ModeSymlink) == os.ModeSymlink:\n\t\t\tif isIgnored {\n\t\t\t\tlog.Debugf(\"link path (%v) is ignored (skipping file)...\", path)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\t//todo: refactor\n\t\t\tif _, ok := ignoreFileNames[foBase]; ok {\n\t\t\t\tlog.Debugf(\"link file name (%v) in ignoreFileNames list (skipping file)...\", foBase)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\t//TODO: should call CopySymlinkFile() here (instead of using os.Readlink/os.Symlink directly)\n\n\t\t\t//TODO: (add a flag)\n\t\t\t//to make it more generic need to support absolute path link rewriting\n\t\t\t//if they point to other copied file objects\n\t\t\tlinkRef, err := os.Readlink(path)\n\t\t\tif err != nil {\n\t\t\t\tif skipErrors {\n\t\t\t\t\t*errs = append(*errs, err)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\terr = os.Symlink(linkRef, targetPath)\n\t\t\tif err != nil {\n\t\t\t\tif skipErrors {\n\t\t\t\t\t*errs = append(*errs, err)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\treturn err\n\t\t\t}\n\t\tdefault:\n\t\t\tlog.Debug(\"is other file object type... (ignoring)\")\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\n// CopyDirOnly copies a directory without any files\nfunc CopyDirOnly(clone bool, src, dst string) error {\n\tlog.Debugf(\"CopyDirOnly(%v,%v,%v)\", clone, src, dst)\n\n\tif src == \"\" {\n\t\treturn ErrNoSrcDir\n\t}\n\n\tif dst == \"\" {\n\t\treturn ErrNoDstDir\n\t}\n\n\tvar err error\n\tif src, err = filepath.Abs(src); err != nil {\n\t\treturn err\n\t}\n\n\tif dst, err = filepath.Abs(dst); err != nil {\n\t\treturn err\n\t}\n\n\tif src == dst {\n\t\treturn ErrSameDir\n\t}\n\n\t//TODO: better symlink support\n\t//when 'src' is a directory (need to better define the expected behavior)\n\t//should use Lstat() first\n\tsrcInfo, err := os.Stat(src)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn ErrSrcDirNotExist\n\t\t}\n\n\t\treturn err\n\t}\n\n\tif !srcInfo.IsDir() {\n\t\treturn ErrSrcNotDir\n\t}\n\n\tif !DirExists(dst) {\n\t\tif clone {\n\t\t\tcloneDirPath(src, dst)\n\t\t} else {\n\t\t\tvar dirMode os.FileMode = 0777\n\t\t\terr = os.MkdirAll(dst, dirMode)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t//try copying the timestamps too (even without cloning)\n\t\t\tif sysStat, ok := srcInfo.Sys().(*syscall.Stat_t); ok {\n\t\t\t\tssi := SysStatInfo(sysStat)\n\t\t\t\tif ssi.Ok {\n\t\t\t\t\tif err := UpdateFileTimes(dst, ssi.Atime, ssi.Mtime); err != nil {\n\t\t\t\t\t\tlog.Warnf(\"CopyDirOnly() - UpdateFileTimes(%v) error - %v\", dst, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// CopyDir copies a directory\nfunc CopyDir(clone bool,\n\tsrc string,\n\tdst string,\n\tcopyRelPath bool,\n\tskipErrors bool,\n\texcludePatterns []string,\n\tignoreDirNames map[string]struct{},\n\tignoreFileNames map[string]struct{}) (error, []error) {\n\tlog.Debugf(\"CopyDir(%v,%v,%v,%v,%#v,...)\", src, dst, copyRelPath, skipErrors, excludePatterns)\n\n\tif src == \"\" {\n\t\treturn ErrNoSrcDir, nil\n\t}\n\n\tif dst == \"\" {\n\t\treturn ErrNoDstDir, nil\n\t}\n\n\tvar err error\n\tif src, err = filepath.Abs(src); err != nil {\n\t\treturn err, nil\n\t}\n\n\tif dst, err = filepath.Abs(dst); err != nil {\n\t\treturn err, nil\n\t}\n\n\tif src == dst {\n\t\treturn ErrSameDir, nil\n\t}\n\n\t//TODO: better symlink support\n\t//when 'src' is a directory (need to better define the expected behavior)\n\t//should use Lstat() first\n\tsrcInfo, err := os.Stat(src)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn ErrSrcDirNotExist, nil\n\t\t}\n\n\t\treturn err, nil\n\t}\n\n\tif !srcInfo.IsDir() {\n\t\treturn ErrSrcNotDir, nil\n\t}\n\n\t//TODO: should clone directory permission, ownership and timestamps info\n\n\tvar errs []error\n\terr = filepath.Walk(src, copyFileObjectHandler(\n\t\tclone, src, dst, copyRelPath, skipErrors, excludePatterns, ignoreDirNames, ignoreFileNames, &errs))\n\tif err != nil {\n\t\treturn err, nil\n\t}\n\n\treturn nil, errs\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc FileMode(fileName string) string {\n\tfinfo, err := os.Lstat(fileName)\n\tif err != nil {\n\t\tlog.Errorf(\"fsutil.FileMode(%s) - os.Lstat error - %v\", fileName, err)\n\t\treturn \"\"\n\t}\n\n\treturn finfo.Mode().String()\n}\n\n// ExeDir returns the directory information for the application\nfunc ExeDir() string {\n\texePath, err := pdiscover.GetOwnProcPath()\n\terrutil.FailOn(err)\n\treturn filepath.Dir(exePath)\n}\n\n// FileDir returns the directory information for the given file\nfunc FileDir(fileName string) string {\n\tabs, err := filepath.Abs(fileName)\n\terrutil.FailOn(err)\n\treturn filepath.Dir(abs)\n}\n\n// PreparePostUpdateStateDir ensures that the updated sensor is copied to the state directory if necessary\nfunc PreparePostUpdateStateDir(statePrefix string) {\n\tlog.Debugf(\"PreparePostUpdateStateDir(%v)\", statePrefix)\n\n\tappDir := ExeDir()\n\tif statePrefix == \"\" {\n\t\tstatePrefix = appDir\n\t}\n\n\tfor _, badPath := range badInstallPaths {\n\t\tif appDir == badPath {\n\t\t\tif pinfo, err := os.Stat(tmpPath); err == nil && pinfo.IsDir() {\n\t\t\t\tlog.Debugf(\"PreparePostUpdateStateDir - overriding state path to %v\", stateTmpPath)\n\n\t\t\t\tsrcSensorPath := filepath.Join(appDir, sensorFileName)\n\t\t\t\tdstSensorPath := filepath.Join(stateTmpPath, sensorFileName)\n\t\t\t\tif Exists(dstSensorPath) {\n\t\t\t\t\tlog.Debugf(\"PreparePostUpdateStateDir - remove existing sensor binary - %v\", dstSensorPath)\n\t\t\t\t\tif err := Remove(dstSensorPath); err != nil {\n\t\t\t\t\t\tlog.Debugf(\"PreparePostUpdateStateDir - error removing existing sensor binary - %v\", err)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\terr = CopyRegularFile(false, srcSensorPath, dstSensorPath, true)\n\t\t\t\terrutil.FailOn(err)\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"PreparePostUpdateStateDir - did not find tmp\")\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ResolveImageStateBasePath resolves the base path for the state path\nfunc ResolveImageStateBasePath(statePrefix string) string {\n\tlog.Debugf(\"ResolveImageStateBasePath(%s)\", statePrefix)\n\n\tappDir := ExeDir()\n\tif statePrefix == \"\" {\n\t\tstatePrefix = appDir\n\t}\n\n\tfor _, badPath := range badInstallPaths {\n\t\tif strings.HasPrefix(statePrefix, badPath) {\n\t\t\tlog.Debugf(\"ResolveImageStateBasePath - statePrefix=%s appDir=%s badPath=%s\", statePrefix, appDir, badPath)\n\t\t\tif pinfo, err := os.Stat(tmpPath); err == nil && pinfo.IsDir() {\n\t\t\t\tlog.Debugf(\"ResolveImageStateBasePath - overriding state path to %v\", stateTmpPath)\n\t\t\t\tstatePrefix = stateTmpPath\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"ResolveImageStateBasePath - did not find tmp\")\n\t\t\t}\n\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn statePrefix\n}\n\n// PrepareImageStateDirs ensures that the required application directories exist\nfunc PrepareImageStateDirs(statePrefix, imageID string) (string, string, string, string) {\n\t//prepares the image processing directories\n\t//creating the root state directory if it doesn't exist\n\tlog.Debugf(\"PrepareImageStateDirs(%v,%v)\", statePrefix, imageID)\n\n\tstateKey := imageID\n\t//images IDs in Docker 1.9+ are prefixed with a hash type...\n\tif strings.Contains(stateKey, \":\") {\n\t\tparts := strings.Split(stateKey, \":\")\n\t\tstateKey = parts[1]\n\t}\n\n\tappDir := ExeDir()\n\tif statePrefix == \"\" {\n\t\tstatePrefix = appDir\n\t}\n\n\tfor _, badPath := range badInstallPaths {\n\t\t//Note:\n\t\t//Should be a prefix check ideally\n\t\t//and should check if it's actually one of the 'shared' directories in Docker for Mac (on Macs)\n\t\tif statePrefix == badPath {\n\t\t\tlog.Debugf(\"PrepareImageStateDirs - statePrefix=%s appDir=%s badPath=%s\", statePrefix, appDir, badPath)\n\t\t\tif pinfo, err := os.Stat(tmpPath); err == nil && pinfo.IsDir() {\n\t\t\t\tlog.Debugf(\"PrepareImageStateDirs - overriding state path to %v\", stateTmpPath)\n\t\t\t\tstatePrefix = stateTmpPath\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"PrepareImageStateDirs - did not find tmp\")\n\t\t\t}\n\t\t}\n\n\t\tif appDir == badPath {\n\t\t\tlog.Debugf(\"PrepareImageStateDirs - statePrefix=%s appDir=%s badPath=%s\", statePrefix, appDir, badPath)\n\t\t\tif pinfo, err := os.Stat(tmpPath); err == nil && pinfo.IsDir() {\n\t\t\t\tlog.Debugf(\"PrepareImageStateDirs - copying sensor to state path (to %v)\", stateTmpPath)\n\n\t\t\t\tsrcSensorPath := filepath.Join(appDir, sensorFileName)\n\t\t\t\tdstSensorPath := filepath.Join(statePrefix, sensorFileName)\n\t\t\t\terr = CopyRegularFile(false, srcSensorPath, dstSensorPath, true)\n\t\t\t\terrInfo := map[string]string{\n\t\t\t\t\t\"op\":            \"PrepareImageStateDirs\",\n\t\t\t\t\t\"call\":          \"CopyRegularFile\",\n\t\t\t\t\t\"srcSensorPath\": srcSensorPath,\n\t\t\t\t\t\"dstSensorPath\": dstSensorPath,\n\t\t\t\t}\n\n\t\t\t\terrutil.FailOnWithInfo(err, errInfo)\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"PrepareImageStateDirs - did not find tmp\")\n\t\t\t}\n\t\t}\n\t}\n\n\tlocalVolumePath := filepath.Join(statePrefix, rootStateKey, imageStateBaseKey, stateKey)\n\tartifactLocation := filepath.Join(localVolumePath, imageStateArtifactsKey)\n\tartifactDir, err := os.Stat(artifactLocation)\n\n\tswitch {\n\tcase err == nil:\n\t\tlog.Debugf(\"PrepareImageStateDirs - removing existing state location: %v\", artifactLocation)\n\t\terr = Remove(artifactLocation)\n\t\tif err != nil {\n\t\t\tlog.Debugf(\"PrepareImageStateDirs - failed to remove existing state location: %v\", artifactLocation)\n\t\t\terrutil.FailOn(err)\n\t\t}\n\tcase os.IsNotExist(err):\n\t\tlog.Debugf(\"PrepareImageStateDirs - will create new state location: %v\", artifactLocation)\n\tdefault:\n\t\terrutil.FailOn(err)\n\t}\n\n\terr = os.MkdirAll(artifactLocation, stateArtifactsPerms)\n\terrutil.FailOn(err)\n\tartifactDir, err = os.Stat(artifactLocation)\n\terrutil.FailOn(err)\n\tlog.Debug(\"PrepareImageStateDirs - created new image state location: \", artifactLocation)\n\n\terrutil.FailWhen(!artifactDir.IsDir(), \"artifact location is not a directory\")\n\n\treturn localVolumePath, artifactLocation, statePrefix, stateKey\n}\n\n// PrepareReleaseStateDirs ensures that the required app release directories exist\nfunc PrepareReleaseStateDirs(statePrefix, version string) (string, string) {\n\t//prepares the app release directories (used to update the app binaries)\n\t//creating the root state directory if it doesn't exist\n\tlog.Debugf(\"PrepareReleaseStateDirs(%v,%v)\", statePrefix, version)\n\n\tif statePrefix == \"\" {\n\t\tstatePrefix = ExeDir()\n\t}\n\n\tfor _, badPath := range badInstallPaths {\n\t\tif statePrefix == badPath {\n\t\t\tif pinfo, err := os.Stat(tmpPath); err == nil && pinfo.IsDir() {\n\t\t\t\tlog.Debugf(\"PrepareReleaseStateDirs - overriding state path to %v\", stateTmpPath)\n\t\t\t\tstatePrefix = stateTmpPath\n\t\t\t} else {\n\t\t\t\tlog.Debugf(\"PrepareReleaseStateDirs - did not find tmp\")\n\t\t\t}\n\t\t}\n\t}\n\n\treleaseDirPath := filepath.Join(statePrefix, rootStateKey, releasesStateKey, version)\n\treleaseDir, err := os.Stat(releaseDirPath)\n\n\tswitch {\n\tcase err == nil:\n\t\tlog.Debugf(\"PrepareReleaseStateDirs - release state location already exists: %v\", releaseDirPath)\n\t\t//not deleting existing release artifacts (todo: revisit this feature in the future)\n\tcase os.IsNotExist(err):\n\t\tlog.Debugf(\"PrepareReleaseStateDirs - will create new release state location: %v\", releaseDirPath)\n\tdefault:\n\t\terrutil.FailOn(err)\n\t}\n\n\terr = os.MkdirAll(releaseDirPath, releaseArtifactsPerms)\n\terrutil.FailOn(err)\n\treleaseDir, err = os.Stat(releaseDirPath)\n\terrutil.FailOn(err)\n\tlog.Debug(\"PrepareReleaseStateDirs - created new release state location: \", releaseDirPath)\n\n\terrutil.FailWhen(!releaseDir.IsDir(), \"release state location is not a directory\")\n\n\treturn releaseDirPath, statePrefix\n}\n\n/* use - TBD\nfunc createDummyFile(src, dst string) error {\n\t_, err := os.Stat(dst)\n\tif err != nil && os.IsNotExist(err) {\n\n\t\tf, err := os.Create(dst)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tdefer f.Close()\n\t\tf.WriteString(\" \")\n\n\t\ts, err := os.Open(src)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer s.Close()\n\n\t\tsrcFileInfo, err := s.Stat()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tf.Chmod(srcFileInfo.Mode())\n\n\t\tsysStat, ok := srcFileInfo.Sys().(*syscall.Stat_t)\n\t\tif !ok {\n\t\t\tlog.Warnln(\"sensor: createDummyFile - unable to get Stat_t =>\", src)\n\t\t\treturn nil\n\t\t}\n\n\t\t//note: doing it only for regular files\n\t\tif srcFileInfo.Mode()&os.ModeSymlink != 0 {\n\t\t\tlog.Warnln(\"sensor: createDummyFile - source is a symlink =>\", src)\n\t\t\treturn nil\n\t\t}\n\n\t\t//note: need to do the same for symlinks too\n\t\tif err := fsutil.UpdateFileTimes(dst, sysStat.Mtim, sysStat.Atim); err != nil {\n\t\t\tlog.Warnln(\"sensor: createDummyFile - UpdateFileTimes error =>\", dst)\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n*/\n\n///////////////////////////////////////////////////////////////////////////////\n\nfunc ArchiveFiles(afname string,\n\tfiles []string,\n\tremovePath bool,\n\taddPrefix string) error {\n\ttf, err := os.Create(afname)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer close(tf)\n\n\ttw := tar.NewWriter(tf)\n\tdefer close(tw)\n\n\tfpRewrite := func(filePath string,\n\t\tremovePath bool,\n\t\taddPrefix string) string {\n\t\tif removePath {\n\t\t\tfilePath = filepath.Base(filePath)\n\t\t}\n\n\t\tif addPrefix != \"\" {\n\t\t\tfilePath = fmt.Sprintf(\"%s%s\", addPrefix, filePath)\n\t\t}\n\n\t\treturn filePath\n\t}\n\n\tfor _, fname := range files {\n\t\tif Exists(fname) && IsRegularFile(fname) {\n\t\t\tinfo, err := os.Stat(fname)\n\t\t\tif err != nil {\n\t\t\t\tlog.Errorf(\"fsutil.ArchiveFiles: bad file - %s - %v\", fname, err)\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tth, err := tar.FileInfoHeader(info, \"\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tth.Name = fpRewrite(fname, true, addPrefix)\n\t\t\tif err := tw.WriteHeader(th); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tf, err := os.Open(fname)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tdefer close(f)\n\t\t\tif _, err := io.CopyN(tw, f, th.Size); err != nil {\n\t\t\t\treturn fmt.Errorf(\"cannot write %s file: %w\", fname, err)\n\t\t\t}\n\t\t} else {\n\t\t\tlog.Errorf(\"fsutil.ArchiveFiles: bad file - %s\", fname)\n\t\t\treturn fmt.Errorf(\"bad file - %s\", fname)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc ArchiveDir(afname string,\n\td2aname string,\n\ttrimPrefix string,\n\taddPrefix string) error {\n\tdirInfo, err := os.Stat(d2aname)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !dirInfo.IsDir() {\n\t\treturn fmt.Errorf(\"not a directory\")\n\t}\n\n\ttf, err := os.Create(afname)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer close(tf)\n\n\ttw := tar.NewWriter(tf)\n\tdefer close(tw)\n\n\tonFSObject := func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"fsutil.ArchiveDir.onFSObject: path=%q err=%q\", path, err)\n\t\t\treturn err\n\t\t}\n\n\t\tif info == nil {\n\t\t\tlog.Errorf(\"fsutil.ArchiveDir.onFSObject: path=%q skipping... no file info\", path)\n\t\t\treturn nil\n\t\t}\n\n\t\tlog.Debugf(\"fsutil.ArchiveDir.onFSObject: path=%q name=%v size=%v mode=%o isDir=%v isReg=%v\",\n\t\t\tpath, info.Name(), info.Size(), info.Mode(), info.IsDir(), info.Mode().IsRegular())\n\n\t\tswitch {\n\t\tcase info.IsDir():\n\t\t\tth, err := tar.FileInfoHeader(info, \"\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tth.Name = fmt.Sprintf(\"%s/\", fpUpdate(path, trimPrefix, addPrefix))\n\t\t\tif err := tw.WriteHeader(th); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase info.Mode().IsRegular():\n\t\t\tth, err := tar.FileInfoHeader(info, \"\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tth.Name = fpUpdate(path, trimPrefix, addPrefix)\n\t\t\tif err := tw.WriteHeader(th); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tf, err := os.Open(path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tdefer close(f)\n\t\t\tif _, err := io.Copy(tw, f); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase info.Mode()&os.ModeSymlink != 0:\n\t\t\tlinkRef, err := os.Readlink(path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tth, err := tar.FileInfoHeader(info, linkRef)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tth.Name = fpUpdate(path, trimPrefix, addPrefix)\n\t\t\tif err := tw.WriteHeader(th); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tdefault:\n\t\t\tlog.Debugf(\"fsutil.ArchiveDir.onFSObject: ignoring other file object types - %q\", path)\n\t\t\treturn nil\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tfilepath.Walk(d2aname, onFSObject)\n\n\treturn nil\n}\n\nfunc close(ref io.Closer) {\n\tif err := ref.Close(); err != nil {\n\t\tlog.Errorf(\"close - error closing: %v\", err)\n\t}\n}\n\nfunc fpUpdate(filePath string,\n\ttrimPrefix string,\n\taddPrefix string) string {\n\tif trimPrefix != \"\" {\n\t\tfilePath = strings.TrimPrefix(filePath, trimPrefix)\n\t}\n\n\tif addPrefix != \"\" {\n\t\tfilePath = fmt.Sprintf(\"%s%s\", addPrefix, filePath)\n\t}\n\n\treturn filePath\n}\n\n///////////////////////////////////////////////////////////////////////////////\n\n// UpdateFileTimes updates the atime and mtime timestamps on the target file\nfunc UpdateFileTimes(target string, atime, mtime syscall.Timespec) error {\n\tts := []syscall.Timespec{atime, mtime}\n\treturn syscall.UtimesNano(target, ts)\n}\n\n// UpdateSymlinkTimes updates the atime and mtime timestamps on the target symlink\nfunc UpdateSymlinkTimes(target string, atime, mtime syscall.Timespec) error {\n\tts := []unix.Timespec{unix.Timespec(atime), unix.Timespec(mtime)}\n\treturn unix.UtimesNanoAt(unix.AT_FDCWD, target, ts, unix.AT_SYMLINK_NOFOLLOW)\n}\n\n// LoadStructFromFile creates a struct from a file\nfunc LoadStructFromFile(filePath string, out interface{}) error {\n\tif _, err := os.Stat(filePath); err != nil {\n\t\treturn err\n\t}\n\n\traw, err := os.ReadFile(filePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif len(raw) == 0 {\n\t\treturn ErrNoFileData\n\t}\n\n\tdecoder := json.NewDecoder(bytes.NewReader(raw))\n\terr = decoder.Decode(out)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "pkg/util/fsutil/sysstat.go",
    "content": "package fsutil\n\nimport (\n\t\"syscall\"\n)\n\ntype SysStat struct {\n\tOk    bool\n\tUid   uint32\n\tGid   uint32\n\tAtime syscall.Timespec\n\tMtime syscall.Timespec\n\tCtime syscall.Timespec\n}\n\n/*\nLinux:\n\tAtim      Timespec\n\tMtim      Timespec\nMac:\n\tAtimespec     Timespec\n\tMtimespec     Timespec\n\nMAC:\ntype Stat_t struct {\n\tDev           int32\n\tMode          uint16\n\tNlink         uint16\n\tIno           uint64\n\tUid           uint32\n\tGid           uint32\n\tRdev          int32\n\tPad_cgo_0     [4]byte\n\tAtimespec     Timespec\n\tMtimespec     Timespec\n\tCtimespec     Timespec\n\tBirthtimespec Timespec\n\tSize          int64\n\tBlocks        int64\n\tBlksize       int32\n\tFlags         uint32\n\tGen           uint32\n\tLspare        int32\n\tQspare        [2]int64\n}\nLINUX:\ntype Stat_t struct {\n\tDev       uint64\n\tIno       uint64\n\tNlink     uint64\n\tMode      uint32\n\tUid       uint32\n\tGid       uint32\n\tX__pad0   int32\n\tRdev      uint64\n\tSize      int64\n\tBlksize   int64\n\tBlocks    int64\n\tAtim      Timespec\n\tMtim      Timespec\n\tCtim      Timespec\n\tX__unused [3]int64\n}\n*/\n"
  },
  {
    "path": "pkg/util/fsutil/sysstat_darwin.go",
    "content": "package fsutil\n\nimport (\n\t\"syscall\"\n)\n\nfunc SysStatInfo(raw *syscall.Stat_t) SysStat {\n\treturn SysStat{\n\t\tOk:    true,\n\t\tUid:   raw.Uid,\n\t\tGid:   raw.Gid,\n\t\tAtime: raw.Atimespec,\n\t\tMtime: raw.Mtimespec,\n\t\tCtime: raw.Ctimespec,\n\t}\n}\n"
  },
  {
    "path": "pkg/util/fsutil/sysstat_linux.go",
    "content": "package fsutil\n\nimport (\n\t\"syscall\"\n)\n\nfunc SysStatInfo(raw *syscall.Stat_t) SysStat {\n\treturn SysStat{\n\t\tOk:    true,\n\t\tUid:   raw.Uid,\n\t\tGid:   raw.Gid,\n\t\tAtime: raw.Atim,\n\t\tMtime: raw.Mtim,\n\t\tCtime: raw.Ctim,\n\t}\n}\n"
  },
  {
    "path": "pkg/util/jsonutil/jsonutil.go",
    "content": "package jsonutil\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n)\n\nfunc ToString(input interface{}) string {\n\treturn toString(input, false)\n}\n\nfunc ToPretty(input interface{}) string {\n\treturn toString(input, true)\n}\n\nfunc toString(input interface{}, pretty bool) string {\n\tvar out bytes.Buffer\n\tencoder := json.NewEncoder(&out)\n\tencoder.SetEscapeHTML(false)\n\tif pretty {\n\t\tencoder.SetIndent(\" \", \" \")\n\t}\n\t_ = encoder.Encode(input)\n\treturn out.String()\n}\n"
  },
  {
    "path": "pkg/util/printbuffer/printbuffer.go",
    "content": "package printbuffer\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n)\n\ntype PrintBuffer struct {\n\tPrefix string\n}\n\nfunc (b *PrintBuffer) Write(p []byte) (n int, err error) {\n\tfor _, line := range bytes.Split(bytes.TrimRight(p, \"\\n\"), []byte{'\\n'}) {\n\t\tif len(line) > 0 {\n\t\t\tfmt.Println(b.Prefix, string(line))\n\t\t}\n\t}\n\treturn len(p), nil\n}\n"
  },
  {
    "path": "pkg/version/version.go",
    "content": "package version\n\nimport (\n\t\"fmt\"\n\t\"runtime\"\n\n\t\"github.com/slimtoolkit/slim/pkg/consts\"\n)\n\nvar (\n\tappVersionTag  = \"latest\"\n\tappVersionRev  = \"latest\"\n\tappVersionTime = \"latest\"\n\tcurrentVersion = \"v\"\n)\n\nfunc init() {\n\tcurrentVersion = fmt.Sprintf(\"%s/%s|%s|%s|%s|%s\",\n\t\truntime.GOOS,\n\t\truntime.GOARCH,\n\t\tconsts.AppVersionName,\n\t\tappVersionTag,\n\t\tappVersionRev,\n\t\tappVersionTime)\n}\n\n// Current returns the current version information\nfunc Current() string {\n\treturn currentVersion\n}\n\nfunc Tag() string {\n\treturn appVersionTag\n}\n"
  },
  {
    "path": "pkg/vulnerability/epss/api/api.go",
    "content": "package api\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/vulnerability/epss\"\n)\n\nconst (\n\tcallPath = \"https://api.first.org/data/v1/epss\"\n\n\ttrueStr  = \"true\"\n\tfalseStr = \"false\"\n\n\t// GLOBAL PARAMETERS:\n\n\t// Comma-separated list of fieldnames to be retrieved.\n\t// Used only for limiting the available resultset.\n\tqsFields = \"fields\" // type: string\n\n\t// Limits the maximun number of records to be shown.\n\t// Should be a number between 1 and 100.\n\tqsLimit = \"limit\" // type: integer\n\n\t// Offsets the list of records by this number.\n\t// The first item is 0.\n\tqsOffset = \"offset\" // type: integer\n\n\t// Comma-separated list of fieldnames to be used to sort the resultset.\n\t// Fields starting with - (minus sign) indicate a descending order.\n\t// Each application should define its default sorting options.\n\tqsSort = \"sort\" // type: string\n\n\t// Use true, false, 0 or 1. If set to true will add an object wrapping\n\t// the resultset, with details on the status, total records found,\n\t// offset and limit. When false this information is returned\n\t//at the response header. Defaults to true.\n\tqsEnvelope = \"envelope\" // type: bool\n\n\t// Use true, false, 0 or 1. If the result should be\n\t// pretty-printed or no. Defaults to false.\n\tqsPretty = \"pretty\" // type: bool\n\n\t// Collection of fieldnames to retrieve. Affects the resultset and\n\t// the possible options for the parameter fields. Each data model\n\t// can specify multiple available scopes.\n\tqsScope = \"scope\" // type: string\n\t// Shows the last 30 days (or what is available)\n\t// of the EPSS score and percentile for any CVE.\n\ttsScopeVal = \"time-series\"\n\t// Shows the basic EPSS data (cve, epss, percentile, created).\n\tpubScopeVal = \"public\" // default scope value\n\n\t// EPSS CALL PARAMETERS:\n\n\t// Filters by EPSS CVE ID. Multiple values are supported separated by commas.\n\t// The maximum size accepted for this parameter is 2000 characters (including commas).\n\tqsCVE           = \"cve\" // type: string\n\tmaxCVEValueSize = 2000\n\n\t// Date in the format YYYY-MM-DD (since April 14, 2021),\n\t// shows the historic values for epss and percentile attributes.\n\tqsDate = \"date\" // type: date\n\n\t// Number of days since the EPSS score was added to the database\n\t// (starting at 1, not affected by the date parameter).\n\tqsDays = \"days\" // type: int\n\n\t// Only display CVEs with EPSS score greater or equal than the parameter.\n\tqsEPSSGt = \"epss-gt\" // type: decimal\n\n\t// Only display CVEs with percentile greater or equal than the parameter.\n\tqsPctGt = \"percentile-gt\" // type: decimal\n\n\t// Only display CVEs with EPSS score lower or equal than the parameter.\n\tqsEPSSLt = \"epss-lt\" // type: decimal\n\n\t// Only display CVEs with percentile lower or equal than the parameter.\n\tqsPctLt = \"percentile-lt\" // type: decimal\n\n\t// Free text search at the CVE ID (allows partial matches).\n\tqsQuery = \"q\" // type: string\n\n\t// note: not fully documented\n\tqsOrder           = \"order\"\n\torderScoreDescVal = \"!epss\"\n\torderScoreAscVal  = \"epss\"\n\torderPctDescVal   = \"!percentile\"\n\torderPctAscVal    = \"percentile\"\n)\n\n//reminder:\n//var _ connector.APIInt   = (*API)(nil)\n\ntype Instance struct {\n\tclient   *http.Client\n\tpretty   bool\n\tpageSize uint64\n\tdebug    bool\n\tlogger   *log.Entry\n}\n\ntype Options struct {\n\tAPITimeout int\n\tPretty     bool\n\tPageSize   uint64 //will be used as the default 'limit' value\n\tDebug      bool\n\tLogger     *log.Entry\n}\n\ntype CallOptions struct {\n\tDate         string\n\tPageSize     uint64 //will be used as the default 'limit' value\n\tOffset       uint64\n\tOutputFields []string\n\tWithHistory  bool\n\tOutput       interface{}\n}\n\ntype FilteredCallOptions struct {\n\tCallOptions\n\tCveIDPattern   string\n\tDaysSinceAdded uint\n\tScoreGt        float64\n\tScoreLt        float64\n\tPercentileGt   float64\n\tPercentileLt   float64\n\tOrderRecords   epss.OrderType\n}\n\nfunc New(options ...Options) *Instance {\n\tvar ref Instance\n\tvar logger *log.Entry\n\n\ttimeoutSec := time.Duration(epss.APITimeout)\n\tif len(options) > 0 {\n\t\tref.debug = options[0].Debug\n\t\tref.pretty = options[0].Pretty\n\n\t\tif options[0].APITimeout > 0 {\n\t\t\ttimeoutSec = time.Duration(options[0].APITimeout)\n\t\t}\n\n\t\tif options[0].PageSize > 0 {\n\t\t\tref.pageSize = options[0].PageSize\n\t\t} else {\n\t\t\tref.pageSize = epss.PageSize\n\t\t}\n\n\t\tlogger = options[0].Logger\n\t}\n\n\tif logger == nil {\n\t\tlogger = log.NewEntry(log.StandardLogger())\n\t}\n\n\tref.logger = logger.WithField(\"com\", \"epss.api\")\n\tref.client = &http.Client{\n\t\tTimeout: timeoutSec * time.Second,\n\t}\n\n\treturn &ref\n}\n\nfunc (ref *Instance) ListCall(\n\tctx context.Context,\n\toptions ...FilteredCallOptions) (epss.ReplyType, error) {\n\tvar output epss.ReplyType\n\n\tif len(options) == 0 {\n\t\toptions = append(options, FilteredCallOptions{})\n\t}\n\n\tif options[0].Output == nil {\n\t\toutput = allocOutput(options[0].WithHistory)\n\t\toptions[0].Output = output\n\t} else {\n\t\toutput = options[0].Output.(epss.ReplyType)\n\t}\n\n\t_, err := ref.GenericListCall(ctx, epss.OutJSON, options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn output, nil\n}\n\nfunc (ref *Instance) GenericListCall(\n\tctx context.Context,\n\tformat string,\n\toptions ...FilteredCallOptions) (string, error) {\n\toutput := callOutput{\n\t\tformat: format,\n\t}\n\n\tinput := &callInput{}\n\tif len(options) > 0 {\n\t\tif options[0].ScoreGt > 0 {\n\t\t\tinput.scoreGt = options[0].ScoreGt\n\t\t}\n\n\t\tif options[0].ScoreLt > 0 {\n\t\t\tinput.scoreLt = options[0].ScoreLt\n\t\t}\n\n\t\tif options[0].PercentileGt > 0 {\n\t\t\tinput.percentileGt = options[0].PercentileGt\n\t\t}\n\n\t\tif options[0].PercentileLt > 0 {\n\t\t\tinput.percentileLt = options[0].PercentileLt\n\t\t}\n\n\t\tif options[0].DaysSinceAdded > 0 {\n\t\t\tinput.days = options[0].DaysSinceAdded\n\t\t}\n\n\t\tif options[0].CveIDPattern != \"\" {\n\t\t\tinput.query = options[0].CveIDPattern\n\t\t}\n\n\t\tif options[0].OrderRecords != epss.NoOrder {\n\t\t\tswitch options[0].OrderRecords {\n\t\t\tcase epss.ScoreDescOrder:\n\t\t\t\tinput.order = orderScoreDescVal\n\t\t\tcase epss.ScoreAscOrder:\n\t\t\t\tinput.order = orderScoreAscVal\n\t\t\tcase epss.PercentileDescOrder:\n\t\t\t\tinput.order = orderPctDescVal\n\t\t\tcase epss.PercentileAscOrder:\n\t\t\t\tinput.order = orderPctAscVal\n\t\t\t}\n\t\t}\n\n\t\tinput.offset = options[0].Offset\n\t\tif options[0].PageSize > 0 {\n\t\t\tinput.limit = options[0].PageSize\n\t\t} else {\n\t\t\tinput.limit = ref.pageSize\n\t\t}\n\n\t\tinput.date = options[0].Date\n\t\tinput.fields = options[0].OutputFields\n\t\tinput.history = options[0].WithHistory\n\n\t\tif options[0].Output != nil {\n\t\t\toutput.decoded = options[0].Output\n\t\t}\n\t}\n\n\t_, err := ref.call(ctx, input, &output)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn output.raw, nil\n}\n\nfunc allocOutput(withHistory bool) epss.ReplyType {\n\tvar output epss.ReplyType\n\n\tif withHistory {\n\t\toutput = &epss.APIResultWithHistory{\n\t\t\tReply: epss.Reply{\n\t\t\t\tReplyMetadata: &epss.ReplyMetadata{},\n\t\t\t},\n\t\t}\n\t} else {\n\t\toutput = &epss.APIResult{\n\t\t\tReply: epss.Reply{\n\t\t\t\tReplyMetadata: &epss.ReplyMetadata{},\n\t\t\t},\n\t\t}\n\t}\n\n\treturn output\n}\n\nfunc (ref *Instance) LookupCall(\n\tctx context.Context,\n\tcveIDs []string,\n\toptions ...CallOptions) (epss.ReplyType, error) {\n\tvar output epss.ReplyType\n\n\tif len(options) == 0 {\n\t\toptions = append(options, CallOptions{})\n\t}\n\n\tif options[0].Output == nil {\n\t\toutput = allocOutput(options[0].WithHistory)\n\t\toptions[0].Output = output\n\t} else {\n\t\toutput = options[0].Output.(epss.ReplyType)\n\t}\n\n\t_, err := ref.GenericLookupCall(ctx, cveIDs, epss.OutJSON, options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn output, nil\n}\n\nfunc (ref *Instance) GenericLookupCall(\n\tctx context.Context,\n\tcveIDs []string,\n\tformat string,\n\toptions ...CallOptions) (string, error) {\n\toutput := callOutput{\n\t\tformat: format,\n\t}\n\n\tinput := &callInput{\n\t\tcveList: cveIDs,\n\t}\n\n\tif len(options) > 0 {\n\t\tinput.offset = options[0].Offset\n\t\tif options[0].PageSize > 0 {\n\t\t\tinput.limit = options[0].PageSize\n\t\t} else {\n\t\t\tinput.limit = ref.pageSize\n\t\t}\n\n\t\tinput.date = options[0].Date\n\t\tinput.fields = options[0].OutputFields\n\t\tinput.history = options[0].WithHistory\n\n\t\tif options[0].Output != nil {\n\t\t\toutput.decoded = options[0].Output\n\t\t}\n\t}\n\n\t_, err := ref.call(ctx,\n\t\tinput,\n\t\t&output)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn output.raw, nil\n}\n\ntype callInput struct {\n\tcve     string\n\tcveList []string\n\toffset  uint64\n\tlimit   uint64\n\tdate    string\n\tfields  []string\n\thistory bool\n\t//filter fields\n\torder        string\n\tquery        string\n\tscoreGt      float64\n\tscoreLt      float64\n\tpercentileGt float64\n\tpercentileLt float64\n\tdays         uint\n}\n\ntype callOutput struct {\n\tformat      string\n\tdecoded     interface{}\n\tdecodedOnly bool\n\traw         string\n}\n\nfunc (ref *Instance) call(\n\tctx context.Context,\n\tinput *callInput,\n\toutput *callOutput) (*http.Response, error) {\n\tlogger := ref.logger.WithField(\"op\", \"epss.api.Instance.call\")\n\toutFormat := epss.OutJSON\n\tif output != nil {\n\t\tif output.format == \"\" {\n\t\t\toutput.format = outFormat\n\t\t}\n\n\t\tif !epss.IsValidOutput(output.format) {\n\t\t\tlogger.WithFields(log.Fields{\n\t\t\t\t\"error\":         epss.ErrInvalidParams,\n\t\t\t\t\"output.format\": output.format,\n\t\t\t}).Error(\"epss.IsValidOutput\")\n\t\t\treturn nil, epss.ErrInvalidParams\n\t\t}\n\n\t\toutFormat = output.format\n\t}\n\n\tvar body io.Reader //no call param to put in the body (yet)\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, callPath, body)\n\tif err != nil {\n\t\tlogger.WithError(err).Error(\"http.NewRequestWithContext\")\n\t\treturn nil, err\n\t}\n\n\treq.Header.Set(\"Accept\", outFormat)\n\n\tqs := url.Values{}\n\t//always setting envelope because response headers don't include all fields\n\tqs.Set(qsEnvelope, trueStr)\n\n\tif ref.pretty {\n\t\tqs.Set(qsPretty, trueStr)\n\t}\n\n\tif input != nil {\n\t\tif input.query != \"\" {\n\t\t\tqs.Set(qsQuery, input.query)\n\t\t}\n\n\t\tif input.cve != \"\" {\n\t\t\tinput.cveList = append(input.cveList, input.cve)\n\t\t}\n\n\t\tif len(input.cveList) > 0 {\n\t\t\tif err := epss.IsValidCveList(input.cveList); err != nil {\n\t\t\t\tlogger.WithFields(log.Fields{\n\t\t\t\t\t\"error\":         err,\n\t\t\t\t\t\"input.cveList\": input.cveList,\n\t\t\t\t}).Error(\"epss.IsValidCveList\")\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tcveValue := strings.Join(input.cveList, \",\")\n\t\t\tif len(cveValue) > maxCVEValueSize {\n\t\t\t\tlogger.WithFields(log.Fields{\n\t\t\t\t\t\"error\":         epss.ErrTooManyCVEs,\n\t\t\t\t\t\"input.cveList\": input.cveList,\n\t\t\t\t}).Error(\"maxCVEValueSize\")\n\t\t\t\treturn nil, epss.ErrTooManyCVEs\n\t\t\t}\n\n\t\t\tqs.Set(qsCVE, cveValue)\n\t\t}\n\n\t\tif input.date != \"\" {\n\t\t\tdate, err := epss.DateFromString(input.date)\n\t\t\tif err != nil {\n\t\t\t\tlogger.WithFields(log.Fields{\n\t\t\t\t\t\"error\":      err,\n\t\t\t\t\t\"input.date\": input.date,\n\t\t\t\t}).Error(\"epss.DateFromString\")\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif !date.IsZero() {\n\t\t\t\tif !epss.IsValidDate(date) {\n\t\t\t\t\tlogger.WithFields(log.Fields{\n\t\t\t\t\t\t\"error\": epss.ErrInvalidDateParam,\n\t\t\t\t\t\t\"date\":  date,\n\t\t\t\t\t}).Error(\"epss.IsValidDate\")\n\t\t\t\t\treturn nil, epss.ErrInvalidDateParam\n\t\t\t\t}\n\n\t\t\t\tqs.Set(qsDate, input.date)\n\t\t\t}\n\t\t}\n\n\t\tif len(input.fields) > 0 {\n\t\t\t//todo: add field name validation\n\t\t\tqs.Set(qsFields, strings.Join(input.fields, \",\"))\n\t\t}\n\n\t\tif input.history {\n\t\t\tqs.Set(qsScope, tsScopeVal)\n\t\t}\n\n\t\tif input.order != \"\" {\n\t\t\tqs.Set(qsOrder, input.order)\n\t\t}\n\n\t\tif input.scoreGt > 0 {\n\t\t\tqs.Set(qsEPSSGt, fmt.Sprintf(\"%v\", input.scoreGt))\n\t\t}\n\n\t\tif input.scoreLt > 0 {\n\t\t\tqs.Set(qsEPSSLt, fmt.Sprintf(\"%v\", input.scoreLt))\n\t\t}\n\n\t\tif input.percentileGt > 0 {\n\t\t\tqs.Set(qsPctGt, fmt.Sprintf(\"%v\", input.percentileGt))\n\t\t}\n\n\t\tif input.percentileLt > 0 {\n\t\t\tqs.Set(qsPctLt, fmt.Sprintf(\"%v\", input.percentileLt))\n\t\t}\n\n\t\tif input.days > 0 {\n\t\t\tqs.Set(qsDays, fmt.Sprintf(\"%v\", input.days))\n\t\t}\n\n\t\tif input.limit > 0 {\n\t\t\tqs.Set(qsLimit, fmt.Sprintf(\"%v\", input.limit))\n\t\t}\n\n\t\tif input.offset > 0 {\n\t\t\tqs.Set(qsOffset, fmt.Sprintf(\"%v\", input.offset))\n\t\t}\n\t}\n\n\treq.URL.RawQuery = qs.Encode()\n\n\tref.logger.WithFields(log.Fields{\n\t\t\"path\": callPath,\n\t\t\"qs\":   req.URL.RawQuery,\n\t}).Trace(\"ref.client.Do\")\n\n\tresp, err := ref.client.Do(req)\n\tif resp != nil && resp.Body != nil {\n\t\tif output != nil {\n\t\t\tdefer resp.Body.Close()\n\t\t}\n\n\t\tif err != nil {\n\t\t\tlogger.WithError(err).Error(\"ref.client.Do\")\n\t\t\treturn resp, err\n\t\t}\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tlogger.WithField(\"status.code\", resp.StatusCode).Error(\"ref.client.Do\")\n\n\t\t\tif resp.StatusCode == http.StatusNotFound {\n\t\t\t\treturn resp, epss.ErrNotFound\n\t\t\t}\n\t\t\tif resp.StatusCode == http.StatusForbidden {\n\t\t\t\treturn resp, epss.ErrNotAuthorized\n\t\t\t}\n\n\t\t\treturn resp, fmt.Errorf(\"bad http status - %d\", resp.StatusCode)\n\t\t}\n\n\t\tif output != nil {\n\t\t\tvar b bytes.Buffer\n\t\t\tb.ReadFrom(resp.Body)\n\n\t\t\tif output.decoded != nil && outFormat == epss.OutJSON {\n\t\t\t\t//non-json responses are returned as raw strings\n\t\t\t\tdecoder := json.NewDecoder(bytes.NewReader(b.Bytes()))\n\t\t\t\terr = decoder.Decode(output.decoded)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlogger.WithFields(log.Fields{\n\t\t\t\t\t\t\"error\":          err,\n\t\t\t\t\t\t\"output.decoded\": output.decoded,\n\t\t\t\t\t}).Error(\"decoder.Decode\")\n\t\t\t\t\treturn resp, err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif output.decoded == nil || !output.decodedOnly {\n\t\t\t\toutput.raw = b.String()\n\t\t\t}\n\t\t}\n\n\t\treturn resp, nil\n\t}\n\n\treturn resp, err\n}\n"
  },
  {
    "path": "pkg/vulnerability/epss/client/client.go",
    "content": "package client\n\nimport (\n\t\"context\"\n\t\"time\"\n\n\tlog \"github.com/sirupsen/logrus\"\n\n\t\"github.com/slimtoolkit/slim/pkg/vulnerability/epss\"\n\t\"github.com/slimtoolkit/slim/pkg/vulnerability/epss/api\"\n)\n\ntype Instance struct {\n\tclient *api.Instance\n\tdebug  bool\n\tlogger *log.Entry\n}\n\ntype Options struct {\n\tAPITimeout int\n\tPretty     bool\n\tPageSize   uint64 //will be used as the default 'limit' value\n\tDebug      bool\n\tLogger     *log.Entry\n}\n\ntype CallOptions struct {\n\tDate         time.Time\n\tPageSize     uint64 //will be used as the default 'limit' value\n\tOffset       uint64\n\tOutputFields []string\n}\n\ntype FilteredCallOptions struct {\n\tCallOptions\n\tCveIDPattern   string\n\tDaysSinceAdded uint\n\tScoreGt        float64\n\tScoreLt        float64\n\tPercentileGt   float64\n\tPercentileLt   float64\n\tOrderRecords   epss.OrderType\n}\n\nfunc New(options ...Options) *Instance {\n\tvar apiOptions []api.Options\n\tif len(options) > 0 {\n\t\tapiOptions = append(apiOptions, api.Options{\n\t\t\tAPITimeout: options[0].APITimeout,\n\t\t\tPretty:     options[0].Pretty,\n\t\t\tPageSize:   options[0].PageSize,\n\t\t\tDebug:      options[0].Debug,\n\t\t\tLogger:     options[0].Logger,\n\t\t})\n\t}\n\n\tref := Instance{\n\t\tclient: api.New(apiOptions...),\n\t}\n\n\tvar logger *log.Entry\n\tif len(options) > 0 {\n\t\tref.debug = options[0].Debug\n\t\tlogger = options[0].Logger\n\t}\n\n\tif logger == nil {\n\t\tlogger = log.NewEntry(log.StandardLogger())\n\t}\n\n\tref.logger = logger.WithField(\"com\", \"epss.client\")\n\treturn &ref\n}\n\nfunc apiCallOptions(input []CallOptions) []api.CallOptions {\n\tvar output []api.CallOptions\n\tif len(input) > 0 {\n\t\toutput = append(output, api.CallOptions{\n\t\t\tDate:         epss.DateToString(input[0].Date),\n\t\t\tPageSize:     input[0].PageSize,\n\t\t\tOffset:       input[0].Offset,\n\t\t\tOutputFields: input[0].OutputFields,\n\t\t})\n\t}\n\n\treturn output\n}\n\nfunc (ref *Instance) LookupScore(\n\tctx context.Context,\n\tcveID string,\n\toptions ...CallOptions) (*epss.Score, *epss.Result, error) {\n\tapiOptions := apiCallOptions(options)\n\tapiReply, err := ref.client.LookupCall(ctx, []string{cveID}, apiOptions...)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tapiResult := apiReply.(*epss.APIResult)\n\tresult, err := epss.NewResult(apiResult)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif len(apiResult.Data) == 0 {\n\t\treturn nil, result, nil\n\t}\n\n\treturn result.Data[0], result, nil\n}\n\nfunc (ref *Instance) LookupScoreWithHistory(\n\tctx context.Context,\n\tcveID string,\n\toptions ...CallOptions) (*epss.ScoreWithHistory, *epss.ResultWithHistory, error) {\n\tapiOptions := apiCallOptions(options)\n\tif len(options) == 0 {\n\t\tapiOptions = append(apiOptions, api.CallOptions{})\n\t}\n\n\tapiOptions[0].WithHistory = true\n\tapiReply, err := ref.client.LookupCall(ctx, []string{cveID}, apiOptions...)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tapiResult := apiReply.(*epss.APIResultWithHistory)\n\tif len(apiResult.Data) == 0 {\n\t\treturn nil, nil, nil\n\t}\n\n\tresult, err := epss.NewResultWithHistory(apiResult)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn result.Data[0], result, nil\n}\n\nfunc (ref *Instance) LookupScores(\n\tctx context.Context,\n\tcveIDs []string,\n\toptions ...CallOptions) ([]*epss.Score, *epss.Result, error) {\n\tapiOptions := apiCallOptions(options)\n\tapiReply, err := ref.client.LookupCall(ctx, cveIDs, apiOptions...)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tresult, err := epss.NewResult(apiReply.(*epss.APIResult))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn result.Data, result, nil\n}\n\nfunc (ref *Instance) LookupScoresWithHistory(\n\tctx context.Context,\n\tcveIDs []string,\n\toptions ...CallOptions) ([]*epss.ScoreWithHistory, *epss.ResultWithHistory, error) {\n\tapiOptions := apiCallOptions(options)\n\tif len(options) == 0 {\n\t\tapiOptions = append(apiOptions, api.CallOptions{})\n\t}\n\n\tapiOptions[0].WithHistory = true\n\tapiReply, err := ref.client.LookupCall(ctx, cveIDs, apiOptions...)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tresult, err := epss.NewResultWithHistory(apiReply.(*epss.APIResultWithHistory))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn result.Data, result, nil\n}\n\nfunc (ref *Instance) ListScores(\n\tctx context.Context,\n\toptions ...FilteredCallOptions) ([]*epss.Score, *epss.Result, error) {\n\tapiOptions := apiFilteredCallOptions(options)\n\tapiReply, err := ref.client.ListCall(ctx, apiOptions...)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tresult, err := epss.NewResult(apiReply.(*epss.APIResult))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn result.Data, result, nil\n}\n\nfunc (ref *Instance) ListScoresWithHistory(\n\tctx context.Context,\n\toptions ...FilteredCallOptions) ([]*epss.ScoreWithHistory, *epss.ResultWithHistory, error) {\n\tapiOptions := apiFilteredCallOptions(options)\n\tif len(options) == 0 {\n\t\tapiOptions = append(apiOptions, api.FilteredCallOptions{})\n\t}\n\n\tapiOptions[0].WithHistory = true\n\tapiReply, err := ref.client.ListCall(ctx, apiOptions...)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tresult, err := epss.NewResultWithHistory(apiReply.(*epss.APIResultWithHistory))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn result.Data, result, nil\n}\n\nfunc apiFilteredCallOptions(input []FilteredCallOptions) []api.FilteredCallOptions {\n\tvar output []api.FilteredCallOptions\n\tif len(input) > 0 {\n\t\toutput = append(output, api.FilteredCallOptions{\n\t\t\tCallOptions: api.CallOptions{\n\t\t\t\tDate:         epss.DateToString(input[0].Date),\n\t\t\t\tPageSize:     input[0].PageSize,\n\t\t\t\tOffset:       input[0].Offset,\n\t\t\t\tOutputFields: input[0].OutputFields,\n\t\t\t},\n\t\t\tCveIDPattern:   input[0].CveIDPattern,\n\t\t\tDaysSinceAdded: input[0].DaysSinceAdded,\n\t\t\tScoreGt:        input[0].ScoreGt,\n\t\t\tScoreLt:        input[0].ScoreLt,\n\t\t\tPercentileGt:   input[0].PercentileGt,\n\t\t\tPercentileLt:   input[0].PercentileLt,\n\t\t\tOrderRecords:   input[0].OrderRecords,\n\t\t})\n\t}\n\n\treturn output\n}\n"
  },
  {
    "path": "pkg/vulnerability/epss/data.go",
    "content": "package epss\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n/////////////////////////////////////////////////////////////\n//\n// EPSS API DOCS:\n//\n// https://api.first.org/epss\n// https://www.first.org/epss/api\n//\n// EPSS OFFLINE DATA:\n//\n// ALL EPSS scores for all CVEs for a particular date (yyyy-mm-dd).\n// For this request, simply request the full csv directly as\n// https://epss.cyentia.com/epss_scores-YYYY-MM-DD.csv.gz\n//\n/////////////////////////////////////////////////////////////\n\ntype ReplyMetadata struct {\n\tStatus     string `json:\"status\"`\n\tStatusCode int    `json:\"status-code\"`\n\tVersion    string `json:\"version\"`\n\tAccess     string `json:\"access\"`\n\tTotal      uint64 `json:\"total\"`\n\tOffset     uint64 `json:\"offset\"`\n\tLimit      uint64 `json:\"limit\"`\n}\n\ntype ReplyType interface {\n\tMetadata() *ReplyMetadata\n}\n\ntype Reply struct {\n\t*ReplyMetadata\n}\n\nfunc (ref *Reply) Metadata() *ReplyMetadata {\n\treturn ref.ReplyMetadata\n}\n\nconst (\n\tAPITimeout = 20\n\tPageSize   = uint64(100)\n)\n\nconst (\n\tOutJSON = \"application/json\"\n\tOutYAML = \"application/yaml\"\n\tOutXML  = \"application/xml\"\n\tOutCSV  = \"application/csv\"\n)\n\nvar (\n\tErrInvalidParams    = errors.New(\"invalid params\")\n\tErrInvalidDateParam = errors.New(\"invalid date param\")\n\tErrInvalidCVEParam  = errors.New(\"invalid CVE param\")\n\tErrNotFound         = errors.New(\"not found\")\n\tErrNotAuthorized    = errors.New(\"not authorized\")\n\tErrTooManyCVEs      = errors.New(\"too many CVEs\")\n)\n\ntype OrderType string\n\nconst (\n\tNoOrder             = \"\"\n\tScoreDescOrder      = \"ot.score.desc\"\n\tScoreAscOrder       = \"ot.score.asc\"\n\tPercentileDescOrder = \"ot.percentile.desc\"\n\tPercentileAscOrder  = \"ot.percentile.asc\"\n)\n\ntype APIScoreData struct {\n\tDate       string `json:\"date\"`\n\tEPSS       string `json:\"epss\"`\n\tPercentile string `json:\"percentile\"`\n}\n\ntype APIScore struct {\n\tAPIScoreData\n\tCVE string `json:\"cve\"`\n}\n\ntype APIScoreWithHistory struct {\n\tAPIScore\n\tTimeSeries []APIScoreData `json:\"time-series,omitempty\"`\n}\n\ntype APIResult struct {\n\tReply\n\tData []*APIScore `json:\"data\"`\n}\n\ntype APIResultWithHistory struct {\n\tReply\n\tData []*APIScoreWithHistory `json:\"data\"`\n}\n\ntype Result struct {\n\tReply\n\tData []*Score `json:\"data\"`\n}\n\ntype ResultWithHistory struct {\n\tReply\n\tData []*ScoreWithHistory `json:\"data\"`\n}\n\ntype ScoreData struct {\n\tDate       time.Time `json:\"date\"`\n\tEPSS       float64   `json:\"epss\"`\n\tPercentile float64   `json:\"percentile\"`\n}\n\ntype Score struct {\n\tScoreData\n\tCVE string `json:\"cve\"`\n}\n\ntype ScoreWithHistory struct {\n\tScore\n\tHistory []ScoreData `json:\"history,omitempty\"`\n}\n\nfunc (ref *ScoreData) MarshalJSON() ([]byte, error) {\n\ttype ScoreDataAlias ScoreData\n\treturn json.Marshal(&struct {\n\t\t*ScoreDataAlias\n\t\tDate string `json:\"date\"`\n\t}{\n\t\tScoreDataAlias: (*ScoreDataAlias)(ref),\n\t\tDate:           ref.Date.Format(time.DateOnly),\n\t})\n}\n\nfunc (ref *Score) MarshalJSON() ([]byte, error) {\n\t//embedding gotcha workaround\n\treturn json.Marshal(&struct {\n\t\tEPSS       float64 `json:\"epss\"`\n\t\tPercentile float64 `json:\"percentile\"`\n\t\tDate       string  `json:\"date\"`\n\t\tCVE        string  `json:\"cve\"`\n\t}{\n\t\tEPSS:       ref.EPSS,\n\t\tPercentile: ref.Percentile,\n\t\tDate:       ref.Date.Format(time.DateOnly),\n\t\tCVE:        ref.CVE,\n\t})\n}\n\nfunc (ref *ScoreWithHistory) MarshalJSON() ([]byte, error) {\n\t//embedding gotcha workaround\n\treturn json.Marshal(&struct {\n\t\tEPSS       float64     `json:\"epss\"`\n\t\tPercentile float64     `json:\"percentile\"`\n\t\tDate       string      `json:\"date\"`\n\t\tCVE        string      `json:\"cve\"`\n\t\tHistory    []ScoreData `json:\"history,omitempty\"`\n\t}{\n\t\tEPSS:       ref.EPSS,\n\t\tPercentile: ref.Percentile,\n\t\tDate:       ref.Date.Format(time.DateOnly),\n\t\tCVE:        ref.CVE,\n\t\tHistory:    ref.History,\n\t})\n}\n\nfunc NewResult(input *APIResult) (*Result, error) {\n\tif input == nil {\n\t\treturn nil, nil\n\t}\n\n\toutput := Result{\n\t\tReply: Reply{\n\t\t\tReplyMetadata: input.ReplyMetadata,\n\t\t},\n\t}\n\n\tif len(input.Data) == 0 {\n\t\treturn &output, nil\n\t}\n\n\toutput.Data = make([]*Score, 0, len(input.Data))\n\tfor _, rawScore := range input.Data {\n\t\tscore := Score{\n\t\t\tCVE: rawScore.CVE,\n\t\t}\n\n\t\tvar err error\n\t\tscore.Date, err = DateFromString(rawScore.Date)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tscore.EPSS, err = strconv.ParseFloat(rawScore.EPSS, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tscore.Percentile, err = strconv.ParseFloat(rawScore.Percentile, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\toutput.Data = append(output.Data, &score)\n\t}\n\n\treturn &output, nil\n}\n\nfunc NewResultWithHistory(input *APIResultWithHistory) (*ResultWithHistory, error) {\n\tif input == nil {\n\t\treturn nil, nil\n\t}\n\n\toutput := ResultWithHistory{\n\t\tReply: Reply{\n\t\t\tReplyMetadata: input.ReplyMetadata,\n\t\t},\n\t}\n\n\tif len(input.Data) == 0 {\n\t\treturn &output, nil\n\t}\n\n\toutput.Data = make([]*ScoreWithHistory, 0, len(input.Data))\n\tfor _, rawScore := range input.Data {\n\t\tscore := ScoreWithHistory{\n\t\t\tScore: Score{\n\t\t\t\tCVE: rawScore.CVE,\n\t\t\t},\n\t\t}\n\n\t\tvar err error\n\t\tscore.Date, err = DateFromString(rawScore.Date)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tscore.EPSS, err = strconv.ParseFloat(rawScore.EPSS, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tscore.Percentile, err = strconv.ParseFloat(rawScore.Percentile, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif len(rawScore.TimeSeries) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tscore.History = make([]ScoreData, 0, len(rawScore.TimeSeries))\n\t\tfor _, rawData := range rawScore.TimeSeries {\n\t\t\tvar scoreData ScoreData\n\t\t\tscoreData.Date, err = DateFromString(rawData.Date)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tscoreData.EPSS, err = strconv.ParseFloat(rawData.EPSS, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tscoreData.Percentile, err = strconv.ParseFloat(rawData.Percentile, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tscore.History = append(score.History, scoreData)\n\t\t}\n\n\t\toutput.Data = append(output.Data, &score)\n\t}\n\n\treturn &output, nil\n}\n\nfunc Date(year int, month time.Month, day int) time.Time {\n\treturn time.Date(year, month, day, 0, 0, 0, 0, time.UTC)\n}\n\nfunc DateFromString(input string) (time.Time, error) {\n\tdate, err := time.Parse(time.DateOnly, input)\n\tif err != nil {\n\t\treturn time.Time{}, err\n\t}\n\n\treturn date, nil\n}\n\nfunc DateFromStringOrNow(input string) time.Time {\n\tdate, err := DateFromString(input)\n\tif err == nil {\n\t\treturn date\n\t}\n\n\treturn time.Now()\n}\n\nfunc DateToString(input time.Time) string {\n\treturn input.Format(time.DateOnly)\n}\n\nfunc IsValidDate(input time.Time) bool {\n\tif input.Before(EarliestDate) ||\n\t\tinput.After(time.Now().UTC()) {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\nvar EarliestDate = Date(2021, 4, 14)\n\nfunc IsValidOutput(input string) bool {\n\tswitch input {\n\tcase OutJSON, OutYAML, OutXML, OutCSV:\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc IsValidCveID(input string) error {\n\tparts := strings.Split(input, \"-\")\n\tif len(parts) != 3 {\n\t\treturn ErrInvalidCVEParam\n\t}\n\n\tif strings.ToUpper(parts[0]) != \"CVE\" {\n\t\treturn ErrInvalidCVEParam\n\t}\n\n\tif len(parts[1]) != 4 {\n\t\treturn ErrInvalidCVEParam\n\t}\n\n\tif len(parts[2]) < 4 {\n\t\treturn ErrInvalidCVEParam\n\t}\n\n\tyr, err := strconv.Atoi(parts[1])\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif yr < 1999 || yr > time.Now().Year() {\n\t\treturn ErrInvalidCVEParam\n\t}\n\n\tsn, err := strconv.Atoi(parts[2])\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif sn < 1 {\n\t\treturn ErrInvalidCVEParam\n\t}\n\n\treturn nil\n}\n\nfunc IsValidCveList(input []string) error {\n\tfor idx, cve := range input {\n\t\tif err := IsValidCveID(cve); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid CVE ID: index=%d cve='%s' (%w)\", idx, cve, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nvar (\n\t_ ReplyType = (*APIResult)(nil)\n\t_ ReplyType = (*APIResultWithHistory)(nil)\n\t_ ReplyType = (*Result)(nil)\n\t_ ReplyType = (*ResultWithHistory)(nil)\n)\n"
  },
  {
    "path": "scripts/docker-builder-m1.run.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\npushd $BDIR\ndocker run -v $(pwd):/go/src/github.com/slimtoolkit/slim -w /go/src/github.com/slimtoolkit/slim -it --rm --name=\"slim-builder\" golang:1.21 make build_m1\n\nif [ ! -f dist_mac_m1.zip ]; then\nif hash zip 2> /dev/null; then\n\tzip -r dist_mac_m1.zip dist_mac_m1 -x \"*.DS_Store\"\nfi\nfi\n"
  },
  {
    "path": "scripts/docker-builder.run.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\npushd $BDIR\ndocker run -v $(pwd):/go/src/github.com/slimtoolkit/slim -w /go/src/github.com/slimtoolkit/slim -it --rm --name=\"slim-builder\" golang:1.21 make build\n\nif [ ! -f dist_mac.zip ]; then\nif hash zip 2> /dev/null; then\n\tzip -r dist_mac.zip dist_mac -x \"*.DS_Store\"\nfi\nfi\n"
  },
  {
    "path": "scripts/govulncheck.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\nGOBIN=${GOBIN:=$(go env GOBIN)}\n\nif [ -z \"$GOBIN\" ]; then\n    GOBIN=\"$(go env GOPATH)/bin\"\nfi\n\nGOVULNCHECK=\"${GOBIN}/govulncheck\"\n\nif [ ! -f \"$GOVULNCHECK\" ]; then\n    echo \"Tools: No govulncheck. Installing....\"\n    go install golang.org/x/vuln/cmd/govulncheck@latest\nfi\n\npushd $BDIR\n$GOVULNCHECK ./...\npopd\n"
  },
  {
    "path": "scripts/install-slim.sh",
    "content": "#!/usr/bin/env bash\n\nfunction get_mint() {\n  local DIST=\"\"\n  local EXT=\"\"\n  local FILENAME=\"\"\n  local KERNEL=\"\"\n  local MACHINE=\"\"\n  local TMP_DIR=\"\"\n  local URL=\"\"\n  local VER=\"\"\n\n  if [ -n \"$1\" ]; then\n    VER=$1\n  else\n    # Get the current released tag_name\n    VER=$(curl -sL https://api.github.com/repos/mintoolkit/mint/releases \\\n        | grep tag_name | head -n1 | cut -d'\"' -f4)\n  fi\n\n  if [ -n \"${VER}\" ]; then\n    URL=\"https://github.com/mintoolkit/mint/releases/download/${VER}\"\n  else\n    echo \"ERROR! Could not retrieve the current Mint version number.\"\n    exit 1\n  fi\n\n  # Get kernel name and machine architecture.\n  KERNEL=$(uname -s)\n  MACHINE=$(uname -m)\n\n  # Determine the target distrubution\n  if [ \"${KERNEL}\" == \"Linux\" ]; then\n    EXT=\"tar.gz\"\n    if [ \"${MACHINE}\" == \"x86_64\" ]; then\n      DIST=\"linux\"\n    elif [ \"${MACHINE}\" == \"armv7l\" ]; then\n      DIST=\"linux_arm\"\n    elif [ \"${MACHINE}\" == \"aarch64\" ]; then\n      DIST=\"linux_arm64\"\n    fi\n  elif [ \"${KERNEL}\" == \"Darwin\" ]; then\n    EXT=\"zip\"\n    if [ \"${MACHINE}\" == \"x86_64\" ]; then\n      DIST=\"mac\"\n    elif [ \"${MACHINE}\" == \"arm64\" ]; then\n      DIST=\"mac_m1\"\n    fi\n  else\n    echo \"ERROR! ${KERNEL} is not a supported platform.\"\n    exit 1\n  fi\n\n  # Was a known distribution detected?\n  if [ -z \"${DIST}\" ]; then\n    echo \"ERROR! ${MACHINE} is not a supported architecture.\"\n    exit 1\n  fi\n\n  # Derive the filename\n  FILENAME=\"dist_${DIST}.${EXT}\"\n\n  echo \" - Downloading ${URL}/${FILENAME}\"\n  TMP_DIR=$(mktemp -d)\n  curl -sLo \"${TMP_DIR}/${FILENAME}\" \"${URL}/${FILENAME}\"\n\n  echo \" - Unpacking ${FILENAME}\"\n  if [ \"${EXT}\" == \"zip\" ]; then\n    unzip -qq -o \"${TMP_DIR}/${FILENAME}\" -d \"${TMP_DIR}\"\n  elif [ \"${EXT}\" == \"tar.gz\" ]; then\n    tar -xf \"${TMP_DIR}/${FILENAME}\" --directory \"${TMP_DIR}\"\n  else\n    echo \"ERROR! Unexpected file extension.\"\n    exit 1\n  fi\n\n  # /usr/local/bin should be present on Linux and macOS hosts. Just be sure.\n  if [ -d /usr/local/bin ]; then\n    echo \" - Placing mint in /usr/local/bin\"\n    mv \"${TMP_DIR}/dist_${DIST}/mint\" /usr/local/bin/\n    mv \"${TMP_DIR}/dist_${DIST}/mint-sensor\" /usr/local/bin/\n    chmod +x /usr/local/bin/mint\n    chmod +x /usr/local/bin/mint-sensor\n    mv \"${TMP_DIR}/dist_${DIST}/slim\" /usr/local/bin/\n    mv \"${TMP_DIR}/dist_${DIST}/docker-slim\" /usr/local/bin/\n    chmod +x /usr/local/bin/slim\n    chmod +x /usr/local/bin/docker-slim\n\n    echo \" - Cleaning up\"\n    rm -rf \"${TMP_DIR}\"\n    echo -en \" - \"\n    mint --version\n  else\n    echo \"ERROR! /usr/local/bin is not present. Install aborted.\"\n    rm -rf \"${TMP_DIR}\"\n    exit 1\n  fi\n}\n\necho \"Mint scripted install\"\n\nif [ \"$(id -u)\" -ne 0 ]; then\n  echo \"ERROR! You must run this script as root.\"\n  exit 1\nfi\n\nget_mint $1\n\n# You can pass a specific version to install otherwise the latest version will be installed\n"
  },
  {
    "path": "scripts/mac/bom.gen.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./bom.gen.sh\n"
  },
  {
    "path": "scripts/mac/docker-builder-m1.run.command",
    "content": "#!/usr/bin/env bash\n\nhere=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n\n./docker-builder-m1.run.sh\n\n"
  },
  {
    "path": "scripts/mac/docker-builder.run.command",
    "content": "#!/usr/bin/env bash\n\nhere=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n\n./docker-builder.run.sh\n\n"
  },
  {
    "path": "scripts/mac/govulncheck.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./govulncheck.sh\n\n\n\n\n\n"
  },
  {
    "path": "scripts/mac/src.build.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./src.build.sh\n\n\n\n\n\n\n"
  },
  {
    "path": "scripts/mac/src.cleanup.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./src.cleanup.sh\n\n"
  },
  {
    "path": "scripts/mac/src.fmt.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./src.fmt.sh\n\n\n\n\n\n"
  },
  {
    "path": "scripts/mac/src.inspect.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./src.inspect.sh\n\n\n\n\n\n"
  },
  {
    "path": "scripts/mac/src.test.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./src.test.sh\n"
  },
  {
    "path": "scripts/mac/tools.get.command",
    "content": "here=\"$(dirname \"$BASH_SOURCE\")\"\ncd $here/..\n./tools.get.sh\n"
  },
  {
    "path": "scripts/src.build.m1.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\nexport CGO_ENABLED=0\n\npushd $BDIR\n\nBUILD_TIME=\"$(date -u '+%Y-%m-%d_%I:%M:%S%p')\"\nTAG=\"current\"\nREVISION=\"current\"\nif hash git 2>/dev/null && [ -e $BDIR/.git ]; then\n  TAG=\"$(git describe --tags --always)\"\n  REVISION=\"$(git rev-parse HEAD)\"\nfi\n\nLD_FLAGS=\"-s -w -X github.com/slimtoolkit/slim/pkg/version.appVersionTag=${TAG} -X github.com/slimtoolkit/slim/pkg/version.appVersionRev=${REVISION} -X github.com/slimtoolkit/slim/pkg/version.appVersionTime=${BUILD_TIME}\"\n\ngo generate github.com/slimtoolkit/slim/pkg/appbom\n\npushd ${BDIR}/cmd/slim\nGOOS=darwin GOARCH=arm64 go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"${BDIR}/bin/mac_m1/slim\"\npopd\n\npushd ${BDIR}/cmd/slim-sensor\nGOOS=linux GOARCH=arm64 go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"$BDIR/bin/linux_arm64/slim-sensor\"\nchmod a+x \"$BDIR/bin/linux_arm64/slim-sensor\"\npopd\n\nrm -rfv ${BDIR}/dist_mac_m1\nmkdir ${BDIR}/dist_mac_m1\ncp ${BDIR}/bin/mac_m1/slim ${BDIR}/dist_mac_m1/slim\ncp ${BDIR}/bin/linux_arm64/slim-sensor ${BDIR}/dist_mac_m1/slim-sensor\npushd ${BDIR}/dist_mac_m1\nln -s slim docker-slim\npopd\npushd ${BDIR}\n\nif hash zip 2> /dev/null; then\n\tzip -r dist_mac_m1.zip dist_mac_m1 -x \"*.DS_Store\"\nfi\n\nrm -rfv ${BDIR}/bin\n"
  },
  {
    "path": "scripts/src.build.quick.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\nBUILD_TIME=\"$(date -u '+%Y-%m-%d_%I:%M:%S%p')\"\nTAG=\"current\"\nREVISION=\"current\"\nif hash git 2>/dev/null && [ -e $BDIR/.git ]; then\n  TAG=\"$(git describe --tags)\"\n  REVISION=\"$(git rev-parse HEAD)\"\nfi\n\nLD_FLAGS=\"-s -w -X github.com/slimtoolkit/slim/pkg/version.appVersionTag=${TAG} -X github.com/slimtoolkit/slim/pkg/version.appVersionRev=${REVISION} -X github.com/slimtoolkit/slim/pkg/version.appVersionTime=${BUILD_TIME}\"\n\ngo generate github.com/slimtoolkit/slim/pkg/appbom\n\nBINDIR=\"${BDIR}/bin\"\nmkdir -p \"$BINDIR\"\nrm -rf \"${BINDIR}/\"*\n\nCGO_ENABLED=0 go build -ldflags=\"${LD_FLAGS}\" -mod=vendor -o \"${BINDIR}/slim\" \"${BDIR}/cmd/slim/main.go\"\nCGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags=\"${LD_FLAGS}\" -mod=vendor -o \"${BINDIR}/slim-sensor\" \"${BDIR}/cmd/slim-sensor/main.go\"\n"
  },
  {
    "path": "scripts/src.build.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\nexport CGO_ENABLED=0\n\npushd $BDIR\n\nBUILD_TIME=\"$(date -u '+%Y-%m-%d_%I:%M:%S%p')\"\nTAG=\"current\"\nREVISION=\"current\"\nif hash git 2>/dev/null && [ -e $BDIR/.git ]; then\n  TAG=\"$(git describe --tags --always)\"\n  REVISION=\"$(git rev-parse HEAD)\"\nfi\n\nLD_FLAGS=\"-s -w -X github.com/slimtoolkit/slim/pkg/version.appVersionTag=${TAG} -X github.com/slimtoolkit/slim/pkg/version.appVersionRev=${REVISION} -X github.com/slimtoolkit/slim/pkg/version.appVersionTime=${BUILD_TIME}\"\n\ngo generate github.com/slimtoolkit/slim/pkg/appbom\n\npushd ${BDIR}/cmd/slim\nGOOS=linux GOARCH=amd64 go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"${BDIR}/bin/linux/slim\" \nGOOS=darwin GOARCH=amd64 go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"${BDIR}/bin/mac/slim\"\nGOOS=linux GOARCH=arm go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"$BDIR/bin/linux_arm/slim\"\nGOOS=linux GOARCH=arm64 go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"$BDIR/bin/linux_arm64/slim\"\npopd\n\npushd ${BDIR}/cmd/slim-sensor\nGOOS=linux GOARCH=amd64 go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"${BDIR}/bin/linux/slim-sensor\"\nGOOS=linux GOARCH=arm go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"$BDIR/bin/linux_arm/slim-sensor\"\nGOOS=linux GOARCH=arm64 go build -mod=vendor -trimpath -ldflags=\"${LD_FLAGS}\" -a -tags 'netgo osusergo' -o \"$BDIR/bin/linux_arm64/slim-sensor\"\nchmod a+x \"${BDIR}/bin/linux/slim-sensor\"\nchmod a+x \"$BDIR/bin/linux_arm/slim-sensor\"\nchmod a+x \"$BDIR/bin/linux_arm64/slim-sensor\"\npopd\n\nrm -rfv ${BDIR}/dist_mac\nmkdir ${BDIR}/dist_mac\ncp ${BDIR}/bin/mac/slim ${BDIR}/dist_mac/slim\ncp ${BDIR}/bin/linux/slim-sensor ${BDIR}/dist_mac/slim-sensor\npushd ${BDIR}/dist_mac\nln -s slim docker-slim\npopd\npushd ${BDIR}\nif hash zip 2> /dev/null; then\n\tzip -r dist_mac.zip dist_mac -x \"*.DS_Store\"\nfi\npopd\n\nrm -rfv ${BDIR}/dist_linux\nmkdir ${BDIR}/dist_linux\ncp ${BDIR}/bin/linux/slim ${BDIR}/dist_linux/slim\ncp ${BDIR}/bin/linux/slim-sensor ${BDIR}/dist_linux/slim-sensor\npushd ${BDIR}/dist_linux\nln -s slim docker-slim\npopd\npushd ${BDIR}\ntar -czvf dist_linux.tar.gz dist_linux\npopd\n\nrm -rfv $BDIR/dist_linux_arm\nmkdir $BDIR/dist_linux_arm\ncp $BDIR/bin/linux_arm/slim $BDIR/dist_linux_arm/slim\ncp $BDIR/bin/linux_arm/slim-sensor $BDIR/dist_linux_arm/slim-sensor\npushd ${BDIR}/dist_linux_arm\nln -s slim docker-slim\npopd\npushd ${BDIR}\ntar -czvf dist_linux_arm.tar.gz dist_linux_arm\npopd\n\nrm -rfv $BDIR/dist_linux_arm64\nmkdir $BDIR/dist_linux_arm64\ncp $BDIR/bin/linux_arm64/slim $BDIR/dist_linux_arm64/slim\ncp $BDIR/bin/linux_arm64/slim-sensor $BDIR/dist_linux_arm64/slim-sensor\npushd ${BDIR}/dist_linux_arm64\nln -s slim docker-slim\npopd\npushd ${BDIR}\ntar -czvf dist_linux_arm64.tar.gz dist_linux_arm64\npopd\n\nrm -rfv ${BDIR}/bin\n"
  },
  {
    "path": "scripts/src.cleanup.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\nrm -rfv $BDIR/_gopath\nrm -rfv $BDIR/dist_linux\nrm -fv $BDIR/dist_linux.tar.gz\nrm -rfv $BDIR/dist_linux_arm\nrm -fv $BDIR/dist_linux_arm.tar.gz\nrm -rfv $BDIR/dist_linux_arm64\nrm -fv $BDIR/dist_linux_arm64.tar.gz\nrm -rfv $BDIR/dist_mac\nrm -fv $BDIR/dist_mac.zip\nrm -rfv $BDIR/dist_mac_m1\nrm -fv $BDIR/dist_mac_m1.zip\nrm -rfv $BDIR/bin\n"
  },
  {
    "path": "scripts/src.fmt.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\npushd ${BDIR}/cmd\ngofmt -l -w -s .\npopd\npushd ${BDIR}/pkg\ngofmt -l -w -s .\npopd\n"
  },
  {
    "path": "scripts/src.inspect.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\nexport GOOS=linux\nexport GOARCH=amd64 \n\npushd ${BDIR}/cmd\ngo vet ./...\ngo vet -vettool=$(which shadow) ./...\ngolint ./...\npopd\npushd ${BDIR}/pkg\ngo vet ./...\ngo vet -vettool=$(which shadow) ./...\ngolint ./...\npopd\n"
  },
  {
    "path": "scripts/src.test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\n\nSOURCE=\"${BASH_SOURCE[0]}\"\nwhile [ -h \"$SOURCE\" ] ; do SOURCE=\"$(readlink \"$SOURCE\")\"; done\nBDIR=\"$( cd -P \"$( dirname \"$SOURCE\" )/..\" && pwd )\"\n\npushd ${BDIR}\nset -x\ngo generate ./...\ngo test -v -count 10 ${GO_TEST_FLAGS} ./...\npopd\n"
  },
  {
    "path": "scripts/tools.get.sh",
    "content": "#!/usr/bin/env bash\n\n#tmp until Go has better support for installing tools with modules\nexport GO111MODULE=off\n\ngo get -u golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow\n\nif ! which golint > /dev/null; then\n    echo \"Tools - Installing golint...\"\n    go get -u golang.org/x/lint/golint\nfi\n\nif ! which license-bill-of-materials > /dev/null; then\n    echo \"Tools - Installing bom tool...\"\n\tgo get -v -u github.com/cloudimmunity/license-bill-of-materials\nfi\n"
  },
  {
    "path": "scripts/uninstall-slim.sh",
    "content": "#!/usr/bin/env bash\n\nfunction uninstall_slim() {\n  local VER=\"\"\n\n  # /usr/local/bin should be present on Linux and macOS hosts. Just be sure.\n  if [ -d /usr/local/bin ]; then\n    VER=$(slim --version | cut -d'|' -f3)\n    echo \" - Uninstalling version - ${VER}\"\n\n    echo \" - Removing slim slim binaries from /usr/local/bin\"\n    rm /usr/local/bin/slim\n    rm /usr/local/bin/slim-sensor\n\n    echo \" - Removing local state directory\"\n    rm -rfv /tmp/slim-state\n\n    echo \" - Removing state volume\"\n    docker volume rm slim-state\n\n    echo \" - Removing sensor volume\"\n    docker volume rm slim-sensor.${VER}\n  else\n    echo \"ERROR! /usr/local/bin is not present. Uninstall aborted.\"\n    exit 1\n  fi\n}\n\necho \"Slim scripted uninstall\"\n\nif [ \"$(id -u)\" -ne 0 ]; then\n  echo \"ERROR! You must run this script as root.\"\n  exit 1\nfi\n\nuninstall_slim\n"
  },
  {
    "path": "test/debug.bats",
    "content": "setup() {\n    load 'test_helper/bats-support/load'\n    load 'test_helper/bats-assert/load'\n\n    DIR=\"$( cd \"$( dirname \"$BATS_TEST_FILENAME\" )\" >/dev/null 2>&1 && pwd )\"\n    PATH=\"$DIR/../bin:$PATH\"\n\n    docker run --ipc 'shareable' --name debug_me --rm -d alpine tail -f /dev/null\n}\n\nteardown() {\n    docker rm -f debug_me\n}\n\nfunction debug_command_with_default_image_works { # @test\n    run slim debug debug_me -- ps\n\n    assert [ $status -eq 0 ]\n\n    assert_output --partial '1 root      0:00 tail -f /dev/null'\n}\n\nfunction debug_command_with_custom_image_works { # @test\n    run slim debug --debug-image busybox debug_me -- cat /proc/1/root/etc/os-release\n\n    assert [ $status -eq 0 ]\n\n    assert_output --partial 'NAME=\"Alpine Linux\"'\n    assert_output --partial 'ID=alpine'\n}\n"
  },
  {
    "path": "test/e2e-tests.mk",
    "content": "ARCH ?= $(shell uname -m)\nDSLIM_EXAMPLES_DIR ?= '$(CURDIR)/../examples'\n\nGO_TEST_FLAGS =  # E.g.: make test-e2e-sensor GO_TEST_FLAGS='-run TestXyz'\n\n# run sensor only e2e tests\ntest-e2e-sensor:\n\tgo generate github.com/slimtoolkit/slim/pkg/appbom\n\tgo test -v -tags e2e -count 5 -timeout 30m $(GO_TEST_FLAGS) $(CURDIR)/pkg/app/sensor\n\n# run all e2e tests at once\n.PHONY:\ntest-e2e-all: test-e2e-compose\ntest-e2e-all: test-e2e-distroless\ntest-e2e-all: test-e2e-dotnet\ntest-e2e-all: test-e2e-elixir\ntest-e2e-all: test-e2e-golang\ntest-e2e-all: test-e2e-haskell\ntest-e2e-all: test-e2e-http-probe\ntest-e2e-all: test-e2e-image-edit\ntest-e2e-all: test-e2e-java\ntest-e2e-all: test-e2e-node\ntest-e2e-all: test-e2e-php\ntest-e2e-all: test-e2e-python\ntest-e2e-all: test-e2e-ruby\ntest-e2e-all: test-e2e-rust\ntest-e2e-all:\n\t@echo \"OK\"\n\n.PHONY:\ntest-e2e-compose:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/node_compose/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/node_redis_compose/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/vuejs-compose/Makefile test-e2e\n\n.PHONY:\ntest-e2e-distroless:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/distroless/nodejs/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/distroless/python2.7/Makefile test-e2e\n\n.PHONY:\ntest-e2e-dotnet:\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/dotnet_alpine/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/dotnet_aspnetcore_ubuntu/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/dotnet_debian/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/dotnet_ubuntu/Makefile test-e2e\n\n.PHONY:\ntest-e2e-elixir:\n\ttrue || make -f $(DSLIM_EXAMPLES_DIR)/elixir_phx_standard/Makefile test-e2e  # TODO: Broken one!\n\n.PHONY:\ntest-e2e-golang:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/golang_alpine/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/golang_centos/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/golang_gin_standard/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/golang_standard/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/golang_ubuntu/Makefile test-e2e\n\n.PHONY:\ntest-e2e-haskell:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/haskell_scotty_standard/Makefile test-e2e\n\n.PHONY:\ntest-e2e-http-probe:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/http_probe_cmd_file/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/http_probe_swagger/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/http_probe_swagger_http2_https/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/http_probe_swagger_http2_plain/Makefile test-e2e\n\n.PHONY:\ntest-e2e-image-edit:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/image_edit_basic/Makefile test-e2e\n\n.PHONY:\ntest-e2e-java:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/java_corretto/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/java_standard/Makefile test-e2e\n\n.PHONY:\ntest-e2e-node:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/node17_express_yarn_standard/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/node_alpine/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/node_ubuntu/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/node_ubuntu_focal/Makefile test-e2e\n\n.PHONY:\ntest-e2e-php:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/php7_fpm_fastcgi/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/php7_fpm_nginx/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/php7_builtin_web_server/Makefile test-e2e\n\n.PHONY:\ntest-e2e-python:\n\tmake -f $(DSLIM_EXAMPLES_DIR)/python2_flask_alpine/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/python2_flask_standard/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/python_ubuntu_18.04_user/Makefile test-e2e\n\tmake -f $(DSLIM_EXAMPLES_DIR)/python_ubuntu_18_py27_from_dockerfile/Makefile test-e2e\n\n.PHONY:\ntest-e2e-ruby:\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/ruby2_rails5_alpine/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/ruby2_rails5_alpine_puma/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/ruby2_rails5_alpine_puma_sh/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/ruby2_rails5_alpine_unicorn_rails/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/ruby2_rails5_standard/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/ruby2_rails5_standard_puma/Makefile test-e2e\n\t[ \"${ARCH}\" = \"arm64\" ] || make -f $(DSLIM_EXAMPLES_DIR)/ruby2_sinatra_ubuntu/Makefile test-e2e\n\n.PHONY:\ntest-e2e-rust:\n\t[ \"${GITHUB_ACTIONS}\" = \"true\" ] || make -f $(DSLIM_EXAMPLES_DIR)/rust_standard/Makefile test-e2e  # TODO: HTTP probe always fails on CI - need to investigate more.\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Microsoft Corporation\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/README.md",
    "content": "# go-ansiterm\n\nThis is a cross platform Ansi Terminal Emulation library.  It reads a stream of Ansi characters and produces the appropriate function calls.  The results of the function calls are platform dependent.\n\nFor example the parser might receive \"ESC, [, A\" as a stream of three characters.  This is the code for Cursor Up (http://www.vt100.net/docs/vt510-rm/CUU).  The parser then calls the cursor up function (CUU()) on an event handler.  The event handler determines what platform specific work must be done to cause the cursor to move up one position.\n\nThe parser (parser.go) is a partial implementation of this state machine (http://vt100.net/emu/vt500_parser.png).  There are also two event handler implementations, one for tests (test_event_handler.go) to validate that the expected events are being produced and called, the other is a Windows implementation (winterm/win_event_handler.go).\n\nSee parser_test.go for examples exercising the state machine and generating appropriate function calls.\n\n-----\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/SECURITY.md",
    "content": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.8 BLOCK -->\n\n## Security\n\nMicrosoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).\n\nIf you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.\n\n## Reporting Security Issues\n\n**Please do not report security vulnerabilities through public GitHub issues.**\n\nInstead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).\n\nIf you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).\n\nYou should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). \n\nPlease include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:\n\n  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)\n  * Full paths of source file(s) related to the manifestation of the issue\n  * The location of the affected source code (tag/branch/commit or direct URL)\n  * Any special configuration required to reproduce the issue\n  * Step-by-step instructions to reproduce the issue\n  * Proof-of-concept or exploit code (if possible)\n  * Impact of the issue, including how an attacker might exploit the issue\n\nThis information will help us triage your report more quickly.\n\nIf you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.\n\n## Preferred Languages\n\nWe prefer all communications to be in English.\n\n## Policy\n\nMicrosoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).\n\n<!-- END MICROSOFT SECURITY.MD BLOCK -->\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/constants.go",
    "content": "package ansiterm\n\nconst LogEnv = \"DEBUG_TERMINAL\"\n\n// ANSI constants\n// References:\n// -- http://www.ecma-international.org/publications/standards/Ecma-048.htm\n// -- http://man7.org/linux/man-pages/man4/console_codes.4.html\n// -- http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html\n// -- http://en.wikipedia.org/wiki/ANSI_escape_code\n// -- http://vt100.net/emu/dec_ansi_parser\n// -- http://vt100.net/emu/vt500_parser.svg\n// -- http://invisible-island.net/xterm/ctlseqs/ctlseqs.html\n// -- http://www.inwap.com/pdp10/ansicode.txt\nconst (\n\t// ECMA-48 Set Graphics Rendition\n\t// Note:\n\t// -- Constants leading with an underscore (e.g., _ANSI_xxx) are unsupported or reserved\n\t// -- Fonts could possibly be supported via SetCurrentConsoleFontEx\n\t// -- Windows does not expose the per-window cursor (i.e., caret) blink times\n\tANSI_SGR_RESET              = 0\n\tANSI_SGR_BOLD               = 1\n\tANSI_SGR_DIM                = 2\n\t_ANSI_SGR_ITALIC            = 3\n\tANSI_SGR_UNDERLINE          = 4\n\t_ANSI_SGR_BLINKSLOW         = 5\n\t_ANSI_SGR_BLINKFAST         = 6\n\tANSI_SGR_REVERSE            = 7\n\t_ANSI_SGR_INVISIBLE         = 8\n\t_ANSI_SGR_LINETHROUGH       = 9\n\t_ANSI_SGR_FONT_00           = 10\n\t_ANSI_SGR_FONT_01           = 11\n\t_ANSI_SGR_FONT_02           = 12\n\t_ANSI_SGR_FONT_03           = 13\n\t_ANSI_SGR_FONT_04           = 14\n\t_ANSI_SGR_FONT_05           = 15\n\t_ANSI_SGR_FONT_06           = 16\n\t_ANSI_SGR_FONT_07           = 17\n\t_ANSI_SGR_FONT_08           = 18\n\t_ANSI_SGR_FONT_09           = 19\n\t_ANSI_SGR_FONT_10           = 20\n\t_ANSI_SGR_DOUBLEUNDERLINE   = 21\n\tANSI_SGR_BOLD_DIM_OFF       = 22\n\t_ANSI_SGR_ITALIC_OFF        = 23\n\tANSI_SGR_UNDERLINE_OFF      = 24\n\t_ANSI_SGR_BLINK_OFF         = 25\n\t_ANSI_SGR_RESERVED_00       = 26\n\tANSI_SGR_REVERSE_OFF        = 27\n\t_ANSI_SGR_INVISIBLE_OFF     = 28\n\t_ANSI_SGR_LINETHROUGH_OFF   = 29\n\tANSI_SGR_FOREGROUND_BLACK   = 30\n\tANSI_SGR_FOREGROUND_RED     = 31\n\tANSI_SGR_FOREGROUND_GREEN   = 32\n\tANSI_SGR_FOREGROUND_YELLOW  = 33\n\tANSI_SGR_FOREGROUND_BLUE    = 34\n\tANSI_SGR_FOREGROUND_MAGENTA = 35\n\tANSI_SGR_FOREGROUND_CYAN    = 36\n\tANSI_SGR_FOREGROUND_WHITE   = 37\n\t_ANSI_SGR_RESERVED_01       = 38\n\tANSI_SGR_FOREGROUND_DEFAULT = 39\n\tANSI_SGR_BACKGROUND_BLACK   = 40\n\tANSI_SGR_BACKGROUND_RED     = 41\n\tANSI_SGR_BACKGROUND_GREEN   = 42\n\tANSI_SGR_BACKGROUND_YELLOW  = 43\n\tANSI_SGR_BACKGROUND_BLUE    = 44\n\tANSI_SGR_BACKGROUND_MAGENTA = 45\n\tANSI_SGR_BACKGROUND_CYAN    = 46\n\tANSI_SGR_BACKGROUND_WHITE   = 47\n\t_ANSI_SGR_RESERVED_02       = 48\n\tANSI_SGR_BACKGROUND_DEFAULT = 49\n\t// 50 - 65: Unsupported\n\n\tANSI_MAX_CMD_LENGTH = 4096\n\n\tMAX_INPUT_EVENTS = 128\n\tDEFAULT_WIDTH    = 80\n\tDEFAULT_HEIGHT   = 24\n\n\tANSI_BEL              = 0x07\n\tANSI_BACKSPACE        = 0x08\n\tANSI_TAB              = 0x09\n\tANSI_LINE_FEED        = 0x0A\n\tANSI_VERTICAL_TAB     = 0x0B\n\tANSI_FORM_FEED        = 0x0C\n\tANSI_CARRIAGE_RETURN  = 0x0D\n\tANSI_ESCAPE_PRIMARY   = 0x1B\n\tANSI_ESCAPE_SECONDARY = 0x5B\n\tANSI_OSC_STRING_ENTRY = 0x5D\n\tANSI_COMMAND_FIRST    = 0x40\n\tANSI_COMMAND_LAST     = 0x7E\n\tDCS_ENTRY             = 0x90\n\tCSI_ENTRY             = 0x9B\n\tOSC_STRING            = 0x9D\n\tANSI_PARAMETER_SEP    = \";\"\n\tANSI_CMD_G0           = '('\n\tANSI_CMD_G1           = ')'\n\tANSI_CMD_G2           = '*'\n\tANSI_CMD_G3           = '+'\n\tANSI_CMD_DECPNM       = '>'\n\tANSI_CMD_DECPAM       = '='\n\tANSI_CMD_OSC          = ']'\n\tANSI_CMD_STR_TERM     = '\\\\'\n\n\tKEY_CONTROL_PARAM_2 = \";2\"\n\tKEY_CONTROL_PARAM_3 = \";3\"\n\tKEY_CONTROL_PARAM_4 = \";4\"\n\tKEY_CONTROL_PARAM_5 = \";5\"\n\tKEY_CONTROL_PARAM_6 = \";6\"\n\tKEY_CONTROL_PARAM_7 = \";7\"\n\tKEY_CONTROL_PARAM_8 = \";8\"\n\tKEY_ESC_CSI         = \"\\x1B[\"\n\tKEY_ESC_N           = \"\\x1BN\"\n\tKEY_ESC_O           = \"\\x1BO\"\n\n\tFILL_CHARACTER = ' '\n)\n\nfunc getByteRange(start byte, end byte) []byte {\n\tbytes := make([]byte, 0, 32)\n\tfor i := start; i <= end; i++ {\n\t\tbytes = append(bytes, byte(i))\n\t}\n\n\treturn bytes\n}\n\nvar toGroundBytes = getToGroundBytes()\nvar executors = getExecuteBytes()\n\n// SPACE\t\t  20+A0 hex  Always and everywhere a blank space\n// Intermediate\t  20-2F hex   !\"#$%&'()*+,-./\nvar intermeds = getByteRange(0x20, 0x2F)\n\n// Parameters\t  30-3F hex  0123456789:;<=>?\n// CSI Parameters 30-39, 3B hex 0123456789;\nvar csiParams = getByteRange(0x30, 0x3F)\n\nvar csiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...)\n\n// Uppercase\t  40-5F hex  @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\nvar upperCase = getByteRange(0x40, 0x5F)\n\n// Lowercase\t  60-7E hex  `abcdefghijlkmnopqrstuvwxyz{|}~\nvar lowerCase = getByteRange(0x60, 0x7E)\n\n// Alphabetics\t  40-7E hex  (all of upper and lower case)\nvar alphabetics = append(upperCase, lowerCase...)\n\nvar printables = getByteRange(0x20, 0x7F)\n\nvar escapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E)\nvar escapeToGroundBytes = getEscapeToGroundBytes()\n\n// See http://www.vt100.net/emu/vt500_parser.png for description of the complex\n// byte ranges below\n\nfunc getEscapeToGroundBytes() []byte {\n\tescapeToGroundBytes := getByteRange(0x30, 0x4F)\n\tescapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x51, 0x57)...)\n\tescapeToGroundBytes = append(escapeToGroundBytes, 0x59)\n\tescapeToGroundBytes = append(escapeToGroundBytes, 0x5A)\n\tescapeToGroundBytes = append(escapeToGroundBytes, 0x5C)\n\tescapeToGroundBytes = append(escapeToGroundBytes, getByteRange(0x60, 0x7E)...)\n\treturn escapeToGroundBytes\n}\n\nfunc getExecuteBytes() []byte {\n\texecuteBytes := getByteRange(0x00, 0x17)\n\texecuteBytes = append(executeBytes, 0x19)\n\texecuteBytes = append(executeBytes, getByteRange(0x1C, 0x1F)...)\n\treturn executeBytes\n}\n\nfunc getToGroundBytes() []byte {\n\tgroundBytes := []byte{0x18}\n\tgroundBytes = append(groundBytes, 0x1A)\n\tgroundBytes = append(groundBytes, getByteRange(0x80, 0x8F)...)\n\tgroundBytes = append(groundBytes, getByteRange(0x91, 0x97)...)\n\tgroundBytes = append(groundBytes, 0x99)\n\tgroundBytes = append(groundBytes, 0x9A)\n\tgroundBytes = append(groundBytes, 0x9C)\n\treturn groundBytes\n}\n\n// Delete\t\t     7F hex  Always and everywhere ignored\n// C1 Control\t  80-9F hex  32 additional control characters\n// G1 Displayable A1-FE hex  94 additional displayable characters\n// Special\t\t  A0+FF hex  Same as SPACE and DELETE\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/context.go",
    "content": "package ansiterm\n\ntype ansiContext struct {\n\tcurrentChar byte\n\tparamBuffer []byte\n\tinterBuffer []byte\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/csi_entry_state.go",
    "content": "package ansiterm\n\ntype csiEntryState struct {\n\tbaseState\n}\n\nfunc (csiState csiEntryState) Handle(b byte) (s state, e error) {\n\tcsiState.parser.logf(\"CsiEntry::Handle %#x\", b)\n\n\tnextState, err := csiState.baseState.Handle(b)\n\tif nextState != nil || err != nil {\n\t\treturn nextState, err\n\t}\n\n\tswitch {\n\tcase sliceContains(alphabetics, b):\n\t\treturn csiState.parser.ground, nil\n\tcase sliceContains(csiCollectables, b):\n\t\treturn csiState.parser.csiParam, nil\n\tcase sliceContains(executors, b):\n\t\treturn csiState, csiState.parser.execute()\n\t}\n\n\treturn csiState, nil\n}\n\nfunc (csiState csiEntryState) Transition(s state) error {\n\tcsiState.parser.logf(\"CsiEntry::Transition %s --> %s\", csiState.Name(), s.Name())\n\tcsiState.baseState.Transition(s)\n\n\tswitch s {\n\tcase csiState.parser.ground:\n\t\treturn csiState.parser.csiDispatch()\n\tcase csiState.parser.csiParam:\n\t\tswitch {\n\t\tcase sliceContains(csiParams, csiState.parser.context.currentChar):\n\t\t\tcsiState.parser.collectParam()\n\t\tcase sliceContains(intermeds, csiState.parser.context.currentChar):\n\t\t\tcsiState.parser.collectInter()\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (csiState csiEntryState) Enter() error {\n\tcsiState.parser.clear()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/csi_param_state.go",
    "content": "package ansiterm\n\ntype csiParamState struct {\n\tbaseState\n}\n\nfunc (csiState csiParamState) Handle(b byte) (s state, e error) {\n\tcsiState.parser.logf(\"CsiParam::Handle %#x\", b)\n\n\tnextState, err := csiState.baseState.Handle(b)\n\tif nextState != nil || err != nil {\n\t\treturn nextState, err\n\t}\n\n\tswitch {\n\tcase sliceContains(alphabetics, b):\n\t\treturn csiState.parser.ground, nil\n\tcase sliceContains(csiCollectables, b):\n\t\tcsiState.parser.collectParam()\n\t\treturn csiState, nil\n\tcase sliceContains(executors, b):\n\t\treturn csiState, csiState.parser.execute()\n\t}\n\n\treturn csiState, nil\n}\n\nfunc (csiState csiParamState) Transition(s state) error {\n\tcsiState.parser.logf(\"CsiParam::Transition %s --> %s\", csiState.Name(), s.Name())\n\tcsiState.baseState.Transition(s)\n\n\tswitch s {\n\tcase csiState.parser.ground:\n\t\treturn csiState.parser.csiDispatch()\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/escape_intermediate_state.go",
    "content": "package ansiterm\n\ntype escapeIntermediateState struct {\n\tbaseState\n}\n\nfunc (escState escapeIntermediateState) Handle(b byte) (s state, e error) {\n\tescState.parser.logf(\"escapeIntermediateState::Handle %#x\", b)\n\tnextState, err := escState.baseState.Handle(b)\n\tif nextState != nil || err != nil {\n\t\treturn nextState, err\n\t}\n\n\tswitch {\n\tcase sliceContains(intermeds, b):\n\t\treturn escState, escState.parser.collectInter()\n\tcase sliceContains(executors, b):\n\t\treturn escState, escState.parser.execute()\n\tcase sliceContains(escapeIntermediateToGroundBytes, b):\n\t\treturn escState.parser.ground, nil\n\t}\n\n\treturn escState, nil\n}\n\nfunc (escState escapeIntermediateState) Transition(s state) error {\n\tescState.parser.logf(\"escapeIntermediateState::Transition %s --> %s\", escState.Name(), s.Name())\n\tescState.baseState.Transition(s)\n\n\tswitch s {\n\tcase escState.parser.ground:\n\t\treturn escState.parser.escDispatch()\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/escape_state.go",
    "content": "package ansiterm\n\ntype escapeState struct {\n\tbaseState\n}\n\nfunc (escState escapeState) Handle(b byte) (s state, e error) {\n\tescState.parser.logf(\"escapeState::Handle %#x\", b)\n\tnextState, err := escState.baseState.Handle(b)\n\tif nextState != nil || err != nil {\n\t\treturn nextState, err\n\t}\n\n\tswitch {\n\tcase b == ANSI_ESCAPE_SECONDARY:\n\t\treturn escState.parser.csiEntry, nil\n\tcase b == ANSI_OSC_STRING_ENTRY:\n\t\treturn escState.parser.oscString, nil\n\tcase sliceContains(executors, b):\n\t\treturn escState, escState.parser.execute()\n\tcase sliceContains(escapeToGroundBytes, b):\n\t\treturn escState.parser.ground, nil\n\tcase sliceContains(intermeds, b):\n\t\treturn escState.parser.escapeIntermediate, nil\n\t}\n\n\treturn escState, nil\n}\n\nfunc (escState escapeState) Transition(s state) error {\n\tescState.parser.logf(\"Escape::Transition %s --> %s\", escState.Name(), s.Name())\n\tescState.baseState.Transition(s)\n\n\tswitch s {\n\tcase escState.parser.ground:\n\t\treturn escState.parser.escDispatch()\n\tcase escState.parser.escapeIntermediate:\n\t\treturn escState.parser.collectInter()\n\t}\n\n\treturn nil\n}\n\nfunc (escState escapeState) Enter() error {\n\tescState.parser.clear()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/event_handler.go",
    "content": "package ansiterm\n\ntype AnsiEventHandler interface {\n\t// Print\n\tPrint(b byte) error\n\n\t// Execute C0 commands\n\tExecute(b byte) error\n\n\t// CUrsor Up\n\tCUU(int) error\n\n\t// CUrsor Down\n\tCUD(int) error\n\n\t// CUrsor Forward\n\tCUF(int) error\n\n\t// CUrsor Backward\n\tCUB(int) error\n\n\t// Cursor to Next Line\n\tCNL(int) error\n\n\t// Cursor to Previous Line\n\tCPL(int) error\n\n\t// Cursor Horizontal position Absolute\n\tCHA(int) error\n\n\t// Vertical line Position Absolute\n\tVPA(int) error\n\n\t// CUrsor Position\n\tCUP(int, int) error\n\n\t// Horizontal and Vertical Position (depends on PUM)\n\tHVP(int, int) error\n\n\t// Text Cursor Enable Mode\n\tDECTCEM(bool) error\n\n\t// Origin Mode\n\tDECOM(bool) error\n\n\t// 132 Column Mode\n\tDECCOLM(bool) error\n\n\t// Erase in Display\n\tED(int) error\n\n\t// Erase in Line\n\tEL(int) error\n\n\t// Insert Line\n\tIL(int) error\n\n\t// Delete Line\n\tDL(int) error\n\n\t// Insert Character\n\tICH(int) error\n\n\t// Delete Character\n\tDCH(int) error\n\n\t// Set Graphics Rendition\n\tSGR([]int) error\n\n\t// Pan Down\n\tSU(int) error\n\n\t// Pan Up\n\tSD(int) error\n\n\t// Device Attributes\n\tDA([]string) error\n\n\t// Set Top and Bottom Margins\n\tDECSTBM(int, int) error\n\n\t// Index\n\tIND() error\n\n\t// Reverse Index\n\tRI() error\n\n\t// Flush updates from previous commands\n\tFlush() error\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/ground_state.go",
    "content": "package ansiterm\n\ntype groundState struct {\n\tbaseState\n}\n\nfunc (gs groundState) Handle(b byte) (s state, e error) {\n\tgs.parser.context.currentChar = b\n\n\tnextState, err := gs.baseState.Handle(b)\n\tif nextState != nil || err != nil {\n\t\treturn nextState, err\n\t}\n\n\tswitch {\n\tcase sliceContains(printables, b):\n\t\treturn gs, gs.parser.print()\n\n\tcase sliceContains(executors, b):\n\t\treturn gs, gs.parser.execute()\n\t}\n\n\treturn gs, nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/osc_string_state.go",
    "content": "package ansiterm\n\ntype oscStringState struct {\n\tbaseState\n}\n\nfunc (oscState oscStringState) Handle(b byte) (s state, e error) {\n\toscState.parser.logf(\"OscString::Handle %#x\", b)\n\tnextState, err := oscState.baseState.Handle(b)\n\tif nextState != nil || err != nil {\n\t\treturn nextState, err\n\t}\n\n\tswitch {\n\tcase isOscStringTerminator(b):\n\t\treturn oscState.parser.ground, nil\n\t}\n\n\treturn oscState, nil\n}\n\n// See below for OSC string terminators for linux\n// http://man7.org/linux/man-pages/man4/console_codes.4.html\nfunc isOscStringTerminator(b byte) bool {\n\n\tif b == ANSI_BEL || b == 0x5C {\n\t\treturn true\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/parser.go",
    "content": "package ansiterm\n\nimport (\n\t\"errors\"\n\t\"log\"\n\t\"os\"\n)\n\ntype AnsiParser struct {\n\tcurrState          state\n\teventHandler       AnsiEventHandler\n\tcontext            *ansiContext\n\tcsiEntry           state\n\tcsiParam           state\n\tdcsEntry           state\n\tescape             state\n\tescapeIntermediate state\n\terror              state\n\tground             state\n\toscString          state\n\tstateMap           []state\n\n\tlogf func(string, ...interface{})\n}\n\ntype Option func(*AnsiParser)\n\nfunc WithLogf(f func(string, ...interface{})) Option {\n\treturn func(ap *AnsiParser) {\n\t\tap.logf = f\n\t}\n}\n\nfunc CreateParser(initialState string, evtHandler AnsiEventHandler, opts ...Option) *AnsiParser {\n\tap := &AnsiParser{\n\t\teventHandler: evtHandler,\n\t\tcontext:      &ansiContext{},\n\t}\n\tfor _, o := range opts {\n\t\to(ap)\n\t}\n\n\tif isDebugEnv := os.Getenv(LogEnv); isDebugEnv == \"1\" {\n\t\tlogFile, _ := os.Create(\"ansiParser.log\")\n\t\tlogger := log.New(logFile, \"\", log.LstdFlags)\n\t\tif ap.logf != nil {\n\t\t\tl := ap.logf\n\t\t\tap.logf = func(s string, v ...interface{}) {\n\t\t\t\tl(s, v...)\n\t\t\t\tlogger.Printf(s, v...)\n\t\t\t}\n\t\t} else {\n\t\t\tap.logf = logger.Printf\n\t\t}\n\t}\n\n\tif ap.logf == nil {\n\t\tap.logf = func(string, ...interface{}) {}\n\t}\n\n\tap.csiEntry = csiEntryState{baseState{name: \"CsiEntry\", parser: ap}}\n\tap.csiParam = csiParamState{baseState{name: \"CsiParam\", parser: ap}}\n\tap.dcsEntry = dcsEntryState{baseState{name: \"DcsEntry\", parser: ap}}\n\tap.escape = escapeState{baseState{name: \"Escape\", parser: ap}}\n\tap.escapeIntermediate = escapeIntermediateState{baseState{name: \"EscapeIntermediate\", parser: ap}}\n\tap.error = errorState{baseState{name: \"Error\", parser: ap}}\n\tap.ground = groundState{baseState{name: \"Ground\", parser: ap}}\n\tap.oscString = oscStringState{baseState{name: \"OscString\", parser: ap}}\n\n\tap.stateMap = []state{\n\t\tap.csiEntry,\n\t\tap.csiParam,\n\t\tap.dcsEntry,\n\t\tap.escape,\n\t\tap.escapeIntermediate,\n\t\tap.error,\n\t\tap.ground,\n\t\tap.oscString,\n\t}\n\n\tap.currState = getState(initialState, ap.stateMap)\n\n\tap.logf(\"CreateParser: parser %p\", ap)\n\treturn ap\n}\n\nfunc getState(name string, states []state) state {\n\tfor _, el := range states {\n\t\tif el.Name() == name {\n\t\t\treturn el\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (ap *AnsiParser) Parse(bytes []byte) (int, error) {\n\tfor i, b := range bytes {\n\t\tif err := ap.handle(b); err != nil {\n\t\t\treturn i, err\n\t\t}\n\t}\n\n\treturn len(bytes), ap.eventHandler.Flush()\n}\n\nfunc (ap *AnsiParser) handle(b byte) error {\n\tap.context.currentChar = b\n\tnewState, err := ap.currState.Handle(b)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif newState == nil {\n\t\tap.logf(\"WARNING: newState is nil\")\n\t\treturn errors.New(\"New state of 'nil' is invalid.\")\n\t}\n\n\tif newState != ap.currState {\n\t\tif err := ap.changeState(newState); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (ap *AnsiParser) changeState(newState state) error {\n\tap.logf(\"ChangeState %s --> %s\", ap.currState.Name(), newState.Name())\n\n\t// Exit old state\n\tif err := ap.currState.Exit(); err != nil {\n\t\tap.logf(\"Exit state '%s' failed with : '%v'\", ap.currState.Name(), err)\n\t\treturn err\n\t}\n\n\t// Perform transition action\n\tif err := ap.currState.Transition(newState); err != nil {\n\t\tap.logf(\"Transition from '%s' to '%s' failed with: '%v'\", ap.currState.Name(), newState.Name, err)\n\t\treturn err\n\t}\n\n\t// Enter new state\n\tif err := newState.Enter(); err != nil {\n\t\tap.logf(\"Enter state '%s' failed with: '%v'\", newState.Name(), err)\n\t\treturn err\n\t}\n\n\tap.currState = newState\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/parser_action_helpers.go",
    "content": "package ansiterm\n\nimport (\n\t\"strconv\"\n)\n\nfunc parseParams(bytes []byte) ([]string, error) {\n\tparamBuff := make([]byte, 0, 0)\n\tparams := []string{}\n\n\tfor _, v := range bytes {\n\t\tif v == ';' {\n\t\t\tif len(paramBuff) > 0 {\n\t\t\t\t// Completed parameter, append it to the list\n\t\t\t\ts := string(paramBuff)\n\t\t\t\tparams = append(params, s)\n\t\t\t\tparamBuff = make([]byte, 0, 0)\n\t\t\t}\n\t\t} else {\n\t\t\tparamBuff = append(paramBuff, v)\n\t\t}\n\t}\n\n\t// Last parameter may not be terminated with ';'\n\tif len(paramBuff) > 0 {\n\t\ts := string(paramBuff)\n\t\tparams = append(params, s)\n\t}\n\n\treturn params, nil\n}\n\nfunc parseCmd(context ansiContext) (string, error) {\n\treturn string(context.currentChar), nil\n}\n\nfunc getInt(params []string, dflt int) int {\n\ti := getInts(params, 1, dflt)[0]\n\treturn i\n}\n\nfunc getInts(params []string, minCount int, dflt int) []int {\n\tints := []int{}\n\n\tfor _, v := range params {\n\t\ti, _ := strconv.Atoi(v)\n\t\t// Zero is mapped to the default value in VT100.\n\t\tif i == 0 {\n\t\t\ti = dflt\n\t\t}\n\t\tints = append(ints, i)\n\t}\n\n\tif len(ints) < minCount {\n\t\tremaining := minCount - len(ints)\n\t\tfor i := 0; i < remaining; i++ {\n\t\t\tints = append(ints, dflt)\n\t\t}\n\t}\n\n\treturn ints\n}\n\nfunc (ap *AnsiParser) modeDispatch(param string, set bool) error {\n\tswitch param {\n\tcase \"?3\":\n\t\treturn ap.eventHandler.DECCOLM(set)\n\tcase \"?6\":\n\t\treturn ap.eventHandler.DECOM(set)\n\tcase \"?25\":\n\t\treturn ap.eventHandler.DECTCEM(set)\n\t}\n\treturn nil\n}\n\nfunc (ap *AnsiParser) hDispatch(params []string) error {\n\tif len(params) == 1 {\n\t\treturn ap.modeDispatch(params[0], true)\n\t}\n\n\treturn nil\n}\n\nfunc (ap *AnsiParser) lDispatch(params []string) error {\n\tif len(params) == 1 {\n\t\treturn ap.modeDispatch(params[0], false)\n\t}\n\n\treturn nil\n}\n\nfunc getEraseParam(params []string) int {\n\tparam := getInt(params, 0)\n\tif param < 0 || 3 < param {\n\t\tparam = 0\n\t}\n\n\treturn param\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/parser_actions.go",
    "content": "package ansiterm\n\nfunc (ap *AnsiParser) collectParam() error {\n\tcurrChar := ap.context.currentChar\n\tap.logf(\"collectParam %#x\", currChar)\n\tap.context.paramBuffer = append(ap.context.paramBuffer, currChar)\n\treturn nil\n}\n\nfunc (ap *AnsiParser) collectInter() error {\n\tcurrChar := ap.context.currentChar\n\tap.logf(\"collectInter %#x\", currChar)\n\tap.context.paramBuffer = append(ap.context.interBuffer, currChar)\n\treturn nil\n}\n\nfunc (ap *AnsiParser) escDispatch() error {\n\tcmd, _ := parseCmd(*ap.context)\n\tintermeds := ap.context.interBuffer\n\tap.logf(\"escDispatch currentChar: %#x\", ap.context.currentChar)\n\tap.logf(\"escDispatch: %v(%v)\", cmd, intermeds)\n\n\tswitch cmd {\n\tcase \"D\": // IND\n\t\treturn ap.eventHandler.IND()\n\tcase \"E\": // NEL, equivalent to CRLF\n\t\terr := ap.eventHandler.Execute(ANSI_CARRIAGE_RETURN)\n\t\tif err == nil {\n\t\t\terr = ap.eventHandler.Execute(ANSI_LINE_FEED)\n\t\t}\n\t\treturn err\n\tcase \"M\": // RI\n\t\treturn ap.eventHandler.RI()\n\t}\n\n\treturn nil\n}\n\nfunc (ap *AnsiParser) csiDispatch() error {\n\tcmd, _ := parseCmd(*ap.context)\n\tparams, _ := parseParams(ap.context.paramBuffer)\n\tap.logf(\"Parsed params: %v with length: %d\", params, len(params))\n\n\tap.logf(\"csiDispatch: %v(%v)\", cmd, params)\n\n\tswitch cmd {\n\tcase \"@\":\n\t\treturn ap.eventHandler.ICH(getInt(params, 1))\n\tcase \"A\":\n\t\treturn ap.eventHandler.CUU(getInt(params, 1))\n\tcase \"B\":\n\t\treturn ap.eventHandler.CUD(getInt(params, 1))\n\tcase \"C\":\n\t\treturn ap.eventHandler.CUF(getInt(params, 1))\n\tcase \"D\":\n\t\treturn ap.eventHandler.CUB(getInt(params, 1))\n\tcase \"E\":\n\t\treturn ap.eventHandler.CNL(getInt(params, 1))\n\tcase \"F\":\n\t\treturn ap.eventHandler.CPL(getInt(params, 1))\n\tcase \"G\":\n\t\treturn ap.eventHandler.CHA(getInt(params, 1))\n\tcase \"H\":\n\t\tints := getInts(params, 2, 1)\n\t\tx, y := ints[0], ints[1]\n\t\treturn ap.eventHandler.CUP(x, y)\n\tcase \"J\":\n\t\tparam := getEraseParam(params)\n\t\treturn ap.eventHandler.ED(param)\n\tcase \"K\":\n\t\tparam := getEraseParam(params)\n\t\treturn ap.eventHandler.EL(param)\n\tcase \"L\":\n\t\treturn ap.eventHandler.IL(getInt(params, 1))\n\tcase \"M\":\n\t\treturn ap.eventHandler.DL(getInt(params, 1))\n\tcase \"P\":\n\t\treturn ap.eventHandler.DCH(getInt(params, 1))\n\tcase \"S\":\n\t\treturn ap.eventHandler.SU(getInt(params, 1))\n\tcase \"T\":\n\t\treturn ap.eventHandler.SD(getInt(params, 1))\n\tcase \"c\":\n\t\treturn ap.eventHandler.DA(params)\n\tcase \"d\":\n\t\treturn ap.eventHandler.VPA(getInt(params, 1))\n\tcase \"f\":\n\t\tints := getInts(params, 2, 1)\n\t\tx, y := ints[0], ints[1]\n\t\treturn ap.eventHandler.HVP(x, y)\n\tcase \"h\":\n\t\treturn ap.hDispatch(params)\n\tcase \"l\":\n\t\treturn ap.lDispatch(params)\n\tcase \"m\":\n\t\treturn ap.eventHandler.SGR(getInts(params, 1, 0))\n\tcase \"r\":\n\t\tints := getInts(params, 2, 1)\n\t\ttop, bottom := ints[0], ints[1]\n\t\treturn ap.eventHandler.DECSTBM(top, bottom)\n\tdefault:\n\t\tap.logf(\"ERROR: Unsupported CSI command: '%s', with full context:  %v\", cmd, ap.context)\n\t\treturn nil\n\t}\n\n}\n\nfunc (ap *AnsiParser) print() error {\n\treturn ap.eventHandler.Print(ap.context.currentChar)\n}\n\nfunc (ap *AnsiParser) clear() error {\n\tap.context = &ansiContext{}\n\treturn nil\n}\n\nfunc (ap *AnsiParser) execute() error {\n\treturn ap.eventHandler.Execute(ap.context.currentChar)\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/states.go",
    "content": "package ansiterm\n\ntype stateID int\n\ntype state interface {\n\tEnter() error\n\tExit() error\n\tHandle(byte) (state, error)\n\tName() string\n\tTransition(state) error\n}\n\ntype baseState struct {\n\tname   string\n\tparser *AnsiParser\n}\n\nfunc (base baseState) Enter() error {\n\treturn nil\n}\n\nfunc (base baseState) Exit() error {\n\treturn nil\n}\n\nfunc (base baseState) Handle(b byte) (s state, e error) {\n\n\tswitch {\n\tcase b == CSI_ENTRY:\n\t\treturn base.parser.csiEntry, nil\n\tcase b == DCS_ENTRY:\n\t\treturn base.parser.dcsEntry, nil\n\tcase b == ANSI_ESCAPE_PRIMARY:\n\t\treturn base.parser.escape, nil\n\tcase b == OSC_STRING:\n\t\treturn base.parser.oscString, nil\n\tcase sliceContains(toGroundBytes, b):\n\t\treturn base.parser.ground, nil\n\t}\n\n\treturn nil, nil\n}\n\nfunc (base baseState) Name() string {\n\treturn base.name\n}\n\nfunc (base baseState) Transition(s state) error {\n\tif s == base.parser.ground {\n\t\texecBytes := []byte{0x18}\n\t\texecBytes = append(execBytes, 0x1A)\n\t\texecBytes = append(execBytes, getByteRange(0x80, 0x8F)...)\n\t\texecBytes = append(execBytes, getByteRange(0x91, 0x97)...)\n\t\texecBytes = append(execBytes, 0x99)\n\t\texecBytes = append(execBytes, 0x9A)\n\n\t\tif sliceContains(execBytes, base.parser.context.currentChar) {\n\t\t\treturn base.parser.execute()\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype dcsEntryState struct {\n\tbaseState\n}\n\ntype errorState struct {\n\tbaseState\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/utilities.go",
    "content": "package ansiterm\n\nimport (\n\t\"strconv\"\n)\n\nfunc sliceContains(bytes []byte, b byte) bool {\n\tfor _, v := range bytes {\n\t\tif v == b {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc convertBytesToInteger(bytes []byte) int {\n\ts := string(bytes)\n\ti, _ := strconv.Atoi(s)\n\treturn i\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/ansi.go",
    "content": "// +build windows\n\npackage winterm\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/Azure/go-ansiterm\"\n\twindows \"golang.org/x/sys/windows\"\n)\n\n// Windows keyboard constants\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx.\nconst (\n\tVK_PRIOR    = 0x21 // PAGE UP key\n\tVK_NEXT     = 0x22 // PAGE DOWN key\n\tVK_END      = 0x23 // END key\n\tVK_HOME     = 0x24 // HOME key\n\tVK_LEFT     = 0x25 // LEFT ARROW key\n\tVK_UP       = 0x26 // UP ARROW key\n\tVK_RIGHT    = 0x27 // RIGHT ARROW key\n\tVK_DOWN     = 0x28 // DOWN ARROW key\n\tVK_SELECT   = 0x29 // SELECT key\n\tVK_PRINT    = 0x2A // PRINT key\n\tVK_EXECUTE  = 0x2B // EXECUTE key\n\tVK_SNAPSHOT = 0x2C // PRINT SCREEN key\n\tVK_INSERT   = 0x2D // INS key\n\tVK_DELETE   = 0x2E // DEL key\n\tVK_HELP     = 0x2F // HELP key\n\tVK_F1       = 0x70 // F1 key\n\tVK_F2       = 0x71 // F2 key\n\tVK_F3       = 0x72 // F3 key\n\tVK_F4       = 0x73 // F4 key\n\tVK_F5       = 0x74 // F5 key\n\tVK_F6       = 0x75 // F6 key\n\tVK_F7       = 0x76 // F7 key\n\tVK_F8       = 0x77 // F8 key\n\tVK_F9       = 0x78 // F9 key\n\tVK_F10      = 0x79 // F10 key\n\tVK_F11      = 0x7A // F11 key\n\tVK_F12      = 0x7B // F12 key\n\n\tRIGHT_ALT_PRESSED  = 0x0001\n\tLEFT_ALT_PRESSED   = 0x0002\n\tRIGHT_CTRL_PRESSED = 0x0004\n\tLEFT_CTRL_PRESSED  = 0x0008\n\tSHIFT_PRESSED      = 0x0010\n\tNUMLOCK_ON         = 0x0020\n\tSCROLLLOCK_ON      = 0x0040\n\tCAPSLOCK_ON        = 0x0080\n\tENHANCED_KEY       = 0x0100\n)\n\ntype ansiCommand struct {\n\tCommandBytes []byte\n\tCommand      string\n\tParameters   []string\n\tIsSpecial    bool\n}\n\nfunc newAnsiCommand(command []byte) *ansiCommand {\n\n\tif isCharacterSelectionCmdChar(command[1]) {\n\t\t// Is Character Set Selection commands\n\t\treturn &ansiCommand{\n\t\t\tCommandBytes: command,\n\t\t\tCommand:      string(command),\n\t\t\tIsSpecial:    true,\n\t\t}\n\t}\n\n\t// last char is command character\n\tlastCharIndex := len(command) - 1\n\n\tac := &ansiCommand{\n\t\tCommandBytes: command,\n\t\tCommand:      string(command[lastCharIndex]),\n\t\tIsSpecial:    false,\n\t}\n\n\t// more than a single escape\n\tif lastCharIndex != 0 {\n\t\tstart := 1\n\t\t// skip if double char escape sequence\n\t\tif command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_ESCAPE_SECONDARY {\n\t\t\tstart++\n\t\t}\n\t\t// convert this to GetNextParam method\n\t\tac.Parameters = strings.Split(string(command[start:lastCharIndex]), ansiterm.ANSI_PARAMETER_SEP)\n\t}\n\n\treturn ac\n}\n\nfunc (ac *ansiCommand) paramAsSHORT(index int, defaultValue int16) int16 {\n\tif index < 0 || index >= len(ac.Parameters) {\n\t\treturn defaultValue\n\t}\n\n\tparam, err := strconv.ParseInt(ac.Parameters[index], 10, 16)\n\tif err != nil {\n\t\treturn defaultValue\n\t}\n\n\treturn int16(param)\n}\n\nfunc (ac *ansiCommand) String() string {\n\treturn fmt.Sprintf(\"0x%v \\\"%v\\\" (\\\"%v\\\")\",\n\t\tbytesToHex(ac.CommandBytes),\n\t\tac.Command,\n\t\tstrings.Join(ac.Parameters, \"\\\",\\\"\"))\n}\n\n// isAnsiCommandChar returns true if the passed byte falls within the range of ANSI commands.\n// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html.\nfunc isAnsiCommandChar(b byte) bool {\n\tswitch {\n\tcase ansiterm.ANSI_COMMAND_FIRST <= b && b <= ansiterm.ANSI_COMMAND_LAST && b != ansiterm.ANSI_ESCAPE_SECONDARY:\n\t\treturn true\n\tcase b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_OSC || b == ansiterm.ANSI_CMD_DECPAM || b == ansiterm.ANSI_CMD_DECPNM:\n\t\t// non-CSI escape sequence terminator\n\t\treturn true\n\tcase b == ansiterm.ANSI_CMD_STR_TERM || b == ansiterm.ANSI_BEL:\n\t\t// String escape sequence terminator\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isXtermOscSequence(command []byte, current byte) bool {\n\treturn (len(command) >= 2 && command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_CMD_OSC && current != ansiterm.ANSI_BEL)\n}\n\nfunc isCharacterSelectionCmdChar(b byte) bool {\n\treturn (b == ansiterm.ANSI_CMD_G0 || b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_G2 || b == ansiterm.ANSI_CMD_G3)\n}\n\n// bytesToHex converts a slice of bytes to a human-readable string.\nfunc bytesToHex(b []byte) string {\n\thex := make([]string, len(b))\n\tfor i, ch := range b {\n\t\thex[i] = fmt.Sprintf(\"%X\", ch)\n\t}\n\treturn strings.Join(hex, \"\")\n}\n\n// ensureInRange adjusts the passed value, if necessary, to ensure it is within\n// the passed min / max range.\nfunc ensureInRange(n int16, min int16, max int16) int16 {\n\tif n < min {\n\t\treturn min\n\t} else if n > max {\n\t\treturn max\n\t} else {\n\t\treturn n\n\t}\n}\n\nfunc GetStdFile(nFile int) (*os.File, uintptr) {\n\tvar file *os.File\n\n\t// syscall uses negative numbers\n\t// windows package uses very big uint32\n\t// Keep these switches split so we don't have to convert ints too much.\n\tswitch uint32(nFile) {\n\tcase windows.STD_INPUT_HANDLE:\n\t\tfile = os.Stdin\n\tcase windows.STD_OUTPUT_HANDLE:\n\t\tfile = os.Stdout\n\tcase windows.STD_ERROR_HANDLE:\n\t\tfile = os.Stderr\n\tdefault:\n\t\tswitch nFile {\n\t\tcase syscall.STD_INPUT_HANDLE:\n\t\t\tfile = os.Stdin\n\t\tcase syscall.STD_OUTPUT_HANDLE:\n\t\t\tfile = os.Stdout\n\t\tcase syscall.STD_ERROR_HANDLE:\n\t\t\tfile = os.Stderr\n\t\tdefault:\n\t\t\tpanic(fmt.Errorf(\"Invalid standard handle identifier: %v\", nFile))\n\t\t}\n\t}\n\n\tfd, err := syscall.GetStdHandle(nFile)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"Invalid standard handle identifier: %v -- %v\", nFile, err))\n\t}\n\n\treturn file, uintptr(fd)\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/api.go",
    "content": "// +build windows\n\npackage winterm\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n//===========================================================================================================\n// IMPORTANT NOTE:\n//\n//\tThe methods below make extensive use of the \"unsafe\" package to obtain the required pointers.\n//\tBeginning in Go 1.3, the garbage collector may release local variables (e.g., incoming arguments, stack\n//\tvariables) the pointers reference *before* the API completes.\n//\n//  As a result, in those cases, the code must hint that the variables remain in active by invoking the\n//\tdummy method \"use\" (see below). Newer versions of Go are planned to change the mechanism to no longer\n//\trequire unsafe pointers.\n//\n//\tIf you add or modify methods, ENSURE protection of local variables through the \"use\" builtin to inform\n//\tthe garbage collector the variables remain in use if:\n//\n//\t-- The value is not a pointer (e.g., int32, struct)\n//\t-- The value is not referenced by the method after passing the pointer to Windows\n//\n//\tSee http://golang.org/doc/go1.3.\n//===========================================================================================================\n\nvar (\n\tkernel32DLL = syscall.NewLazyDLL(\"kernel32.dll\")\n\n\tgetConsoleCursorInfoProc       = kernel32DLL.NewProc(\"GetConsoleCursorInfo\")\n\tsetConsoleCursorInfoProc       = kernel32DLL.NewProc(\"SetConsoleCursorInfo\")\n\tsetConsoleCursorPositionProc   = kernel32DLL.NewProc(\"SetConsoleCursorPosition\")\n\tsetConsoleModeProc             = kernel32DLL.NewProc(\"SetConsoleMode\")\n\tgetConsoleScreenBufferInfoProc = kernel32DLL.NewProc(\"GetConsoleScreenBufferInfo\")\n\tsetConsoleScreenBufferSizeProc = kernel32DLL.NewProc(\"SetConsoleScreenBufferSize\")\n\tscrollConsoleScreenBufferProc  = kernel32DLL.NewProc(\"ScrollConsoleScreenBufferA\")\n\tsetConsoleTextAttributeProc    = kernel32DLL.NewProc(\"SetConsoleTextAttribute\")\n\tsetConsoleWindowInfoProc       = kernel32DLL.NewProc(\"SetConsoleWindowInfo\")\n\twriteConsoleOutputProc         = kernel32DLL.NewProc(\"WriteConsoleOutputW\")\n\treadConsoleInputProc           = kernel32DLL.NewProc(\"ReadConsoleInputW\")\n\twaitForSingleObjectProc        = kernel32DLL.NewProc(\"WaitForSingleObject\")\n)\n\n// Windows Console constants\nconst (\n\t// Console modes\n\t// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx.\n\tENABLE_PROCESSED_INPUT        = 0x0001\n\tENABLE_LINE_INPUT             = 0x0002\n\tENABLE_ECHO_INPUT             = 0x0004\n\tENABLE_WINDOW_INPUT           = 0x0008\n\tENABLE_MOUSE_INPUT            = 0x0010\n\tENABLE_INSERT_MODE            = 0x0020\n\tENABLE_QUICK_EDIT_MODE        = 0x0040\n\tENABLE_EXTENDED_FLAGS         = 0x0080\n\tENABLE_AUTO_POSITION          = 0x0100\n\tENABLE_VIRTUAL_TERMINAL_INPUT = 0x0200\n\n\tENABLE_PROCESSED_OUTPUT            = 0x0001\n\tENABLE_WRAP_AT_EOL_OUTPUT          = 0x0002\n\tENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004\n\tDISABLE_NEWLINE_AUTO_RETURN        = 0x0008\n\tENABLE_LVB_GRID_WORLDWIDE          = 0x0010\n\n\t// Character attributes\n\t// Note:\n\t// -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan).\n\t//    Clearing all foreground or background colors results in black; setting all creates white.\n\t// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes.\n\tFOREGROUND_BLUE      uint16 = 0x0001\n\tFOREGROUND_GREEN     uint16 = 0x0002\n\tFOREGROUND_RED       uint16 = 0x0004\n\tFOREGROUND_INTENSITY uint16 = 0x0008\n\tFOREGROUND_MASK      uint16 = 0x000F\n\n\tBACKGROUND_BLUE      uint16 = 0x0010\n\tBACKGROUND_GREEN     uint16 = 0x0020\n\tBACKGROUND_RED       uint16 = 0x0040\n\tBACKGROUND_INTENSITY uint16 = 0x0080\n\tBACKGROUND_MASK      uint16 = 0x00F0\n\n\tCOMMON_LVB_MASK          uint16 = 0xFF00\n\tCOMMON_LVB_REVERSE_VIDEO uint16 = 0x4000\n\tCOMMON_LVB_UNDERSCORE    uint16 = 0x8000\n\n\t// Input event types\n\t// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.\n\tKEY_EVENT                = 0x0001\n\tMOUSE_EVENT              = 0x0002\n\tWINDOW_BUFFER_SIZE_EVENT = 0x0004\n\tMENU_EVENT               = 0x0008\n\tFOCUS_EVENT              = 0x0010\n\n\t// WaitForSingleObject return codes\n\tWAIT_ABANDONED = 0x00000080\n\tWAIT_FAILED    = 0xFFFFFFFF\n\tWAIT_SIGNALED  = 0x0000000\n\tWAIT_TIMEOUT   = 0x00000102\n\n\t// WaitForSingleObject wait duration\n\tWAIT_INFINITE       = 0xFFFFFFFF\n\tWAIT_ONE_SECOND     = 1000\n\tWAIT_HALF_SECOND    = 500\n\tWAIT_QUARTER_SECOND = 250\n)\n\n// Windows API Console types\n// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD)\n// -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment\ntype (\n\tCHAR_INFO struct {\n\t\tUnicodeChar uint16\n\t\tAttributes  uint16\n\t}\n\n\tCONSOLE_CURSOR_INFO struct {\n\t\tSize    uint32\n\t\tVisible int32\n\t}\n\n\tCONSOLE_SCREEN_BUFFER_INFO struct {\n\t\tSize              COORD\n\t\tCursorPosition    COORD\n\t\tAttributes        uint16\n\t\tWindow            SMALL_RECT\n\t\tMaximumWindowSize COORD\n\t}\n\n\tCOORD struct {\n\t\tX int16\n\t\tY int16\n\t}\n\n\tSMALL_RECT struct {\n\t\tLeft   int16\n\t\tTop    int16\n\t\tRight  int16\n\t\tBottom int16\n\t}\n\n\t// INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest\n\t// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.\n\tINPUT_RECORD struct {\n\t\tEventType uint16\n\t\tKeyEvent  KEY_EVENT_RECORD\n\t}\n\n\tKEY_EVENT_RECORD struct {\n\t\tKeyDown         int32\n\t\tRepeatCount     uint16\n\t\tVirtualKeyCode  uint16\n\t\tVirtualScanCode uint16\n\t\tUnicodeChar     uint16\n\t\tControlKeyState uint32\n\t}\n\n\tWINDOW_BUFFER_SIZE struct {\n\t\tSize COORD\n\t}\n)\n\n// boolToBOOL converts a Go bool into a Windows int32.\nfunc boolToBOOL(f bool) int32 {\n\tif f {\n\t\treturn int32(1)\n\t} else {\n\t\treturn int32(0)\n\t}\n}\n\n// GetConsoleCursorInfo retrieves information about the size and visiblity of the console cursor.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683163(v=vs.85).aspx.\nfunc GetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error {\n\tr1, r2, err := getConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)\n\treturn checkError(r1, r2, err)\n}\n\n// SetConsoleCursorInfo sets the size and visiblity of the console cursor.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686019(v=vs.85).aspx.\nfunc SetConsoleCursorInfo(handle uintptr, cursorInfo *CONSOLE_CURSOR_INFO) error {\n\tr1, r2, err := setConsoleCursorInfoProc.Call(handle, uintptr(unsafe.Pointer(cursorInfo)), 0)\n\treturn checkError(r1, r2, err)\n}\n\n// SetConsoleCursorPosition location of the console cursor.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx.\nfunc SetConsoleCursorPosition(handle uintptr, coord COORD) error {\n\tr1, r2, err := setConsoleCursorPositionProc.Call(handle, coordToPointer(coord))\n\tuse(coord)\n\treturn checkError(r1, r2, err)\n}\n\n// GetConsoleMode gets the console mode for given file descriptor\n// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx.\nfunc GetConsoleMode(handle uintptr) (mode uint32, err error) {\n\terr = syscall.GetConsoleMode(syscall.Handle(handle), &mode)\n\treturn mode, err\n}\n\n// SetConsoleMode sets the console mode for given file descriptor\n// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx.\nfunc SetConsoleMode(handle uintptr, mode uint32) error {\n\tr1, r2, err := setConsoleModeProc.Call(handle, uintptr(mode), 0)\n\tuse(mode)\n\treturn checkError(r1, r2, err)\n}\n\n// GetConsoleScreenBufferInfo retrieves information about the specified console screen buffer.\n// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx.\nfunc GetConsoleScreenBufferInfo(handle uintptr) (*CONSOLE_SCREEN_BUFFER_INFO, error) {\n\tinfo := CONSOLE_SCREEN_BUFFER_INFO{}\n\terr := checkError(getConsoleScreenBufferInfoProc.Call(handle, uintptr(unsafe.Pointer(&info)), 0))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &info, nil\n}\n\nfunc ScrollConsoleScreenBuffer(handle uintptr, scrollRect SMALL_RECT, clipRect SMALL_RECT, destOrigin COORD, char CHAR_INFO) error {\n\tr1, r2, err := scrollConsoleScreenBufferProc.Call(handle, uintptr(unsafe.Pointer(&scrollRect)), uintptr(unsafe.Pointer(&clipRect)), coordToPointer(destOrigin), uintptr(unsafe.Pointer(&char)))\n\tuse(scrollRect)\n\tuse(clipRect)\n\tuse(destOrigin)\n\tuse(char)\n\treturn checkError(r1, r2, err)\n}\n\n// SetConsoleScreenBufferSize sets the size of the console screen buffer.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686044(v=vs.85).aspx.\nfunc SetConsoleScreenBufferSize(handle uintptr, coord COORD) error {\n\tr1, r2, err := setConsoleScreenBufferSizeProc.Call(handle, coordToPointer(coord))\n\tuse(coord)\n\treturn checkError(r1, r2, err)\n}\n\n// SetConsoleTextAttribute sets the attributes of characters written to the\n// console screen buffer by the WriteFile or WriteConsole function.\n// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx.\nfunc SetConsoleTextAttribute(handle uintptr, attribute uint16) error {\n\tr1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0)\n\tuse(attribute)\n\treturn checkError(r1, r2, err)\n}\n\n// SetConsoleWindowInfo sets the size and position of the console screen buffer's window.\n// Note that the size and location must be within and no larger than the backing console screen buffer.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx.\nfunc SetConsoleWindowInfo(handle uintptr, isAbsolute bool, rect SMALL_RECT) error {\n\tr1, r2, err := setConsoleWindowInfoProc.Call(handle, uintptr(boolToBOOL(isAbsolute)), uintptr(unsafe.Pointer(&rect)))\n\tuse(isAbsolute)\n\tuse(rect)\n\treturn checkError(r1, r2, err)\n}\n\n// WriteConsoleOutput writes the CHAR_INFOs from the provided buffer to the active console buffer.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687404(v=vs.85).aspx.\nfunc WriteConsoleOutput(handle uintptr, buffer []CHAR_INFO, bufferSize COORD, bufferCoord COORD, writeRegion *SMALL_RECT) error {\n\tr1, r2, err := writeConsoleOutputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), coordToPointer(bufferSize), coordToPointer(bufferCoord), uintptr(unsafe.Pointer(writeRegion)))\n\tuse(buffer)\n\tuse(bufferSize)\n\tuse(bufferCoord)\n\treturn checkError(r1, r2, err)\n}\n\n// ReadConsoleInput reads (and removes) data from the console input buffer.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx.\nfunc ReadConsoleInput(handle uintptr, buffer []INPUT_RECORD, count *uint32) error {\n\tr1, r2, err := readConsoleInputProc.Call(handle, uintptr(unsafe.Pointer(&buffer[0])), uintptr(len(buffer)), uintptr(unsafe.Pointer(count)))\n\tuse(buffer)\n\treturn checkError(r1, r2, err)\n}\n\n// WaitForSingleObject waits for the passed handle to be signaled.\n// It returns true if the handle was signaled; false otherwise.\n// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx.\nfunc WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) {\n\tr1, _, err := waitForSingleObjectProc.Call(handle, uintptr(uint32(msWait)))\n\tswitch r1 {\n\tcase WAIT_ABANDONED, WAIT_TIMEOUT:\n\t\treturn false, nil\n\tcase WAIT_SIGNALED:\n\t\treturn true, nil\n\t}\n\tuse(msWait)\n\treturn false, err\n}\n\n// String helpers\nfunc (info CONSOLE_SCREEN_BUFFER_INFO) String() string {\n\treturn fmt.Sprintf(\"Size(%v) Cursor(%v) Window(%v) Max(%v)\", info.Size, info.CursorPosition, info.Window, info.MaximumWindowSize)\n}\n\nfunc (coord COORD) String() string {\n\treturn fmt.Sprintf(\"%v,%v\", coord.X, coord.Y)\n}\n\nfunc (rect SMALL_RECT) String() string {\n\treturn fmt.Sprintf(\"(%v,%v),(%v,%v)\", rect.Left, rect.Top, rect.Right, rect.Bottom)\n}\n\n// checkError evaluates the results of a Windows API call and returns the error if it failed.\nfunc checkError(r1, r2 uintptr, err error) error {\n\t// Windows APIs return non-zero to indicate success\n\tif r1 != 0 {\n\t\treturn nil\n\t}\n\n\t// Return the error if provided, otherwise default to EINVAL\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn syscall.EINVAL\n}\n\n// coordToPointer converts a COORD into a uintptr (by fooling the type system).\nfunc coordToPointer(c COORD) uintptr {\n\t// Note: This code assumes the two SHORTs are correctly laid out; the \"cast\" to uint32 is just to get a pointer to pass.\n\treturn uintptr(*((*uint32)(unsafe.Pointer(&c))))\n}\n\n// use is a no-op, but the compiler cannot see that it is.\n// Calling use(p) ensures that p is kept live until that point.\nfunc use(p interface{}) {}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/attr_translation.go",
    "content": "// +build windows\n\npackage winterm\n\nimport \"github.com/Azure/go-ansiterm\"\n\nconst (\n\tFOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE\n\tBACKGROUND_COLOR_MASK = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE\n)\n\n// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the\n// request represented by the passed ANSI mode.\nfunc collectAnsiIntoWindowsAttributes(windowsMode uint16, inverted bool, baseMode uint16, ansiMode int16) (uint16, bool) {\n\tswitch ansiMode {\n\n\t// Mode styles\n\tcase ansiterm.ANSI_SGR_BOLD:\n\t\twindowsMode = windowsMode | FOREGROUND_INTENSITY\n\n\tcase ansiterm.ANSI_SGR_DIM, ansiterm.ANSI_SGR_BOLD_DIM_OFF:\n\t\twindowsMode &^= FOREGROUND_INTENSITY\n\n\tcase ansiterm.ANSI_SGR_UNDERLINE:\n\t\twindowsMode = windowsMode | COMMON_LVB_UNDERSCORE\n\n\tcase ansiterm.ANSI_SGR_REVERSE:\n\t\tinverted = true\n\n\tcase ansiterm.ANSI_SGR_REVERSE_OFF:\n\t\tinverted = false\n\n\tcase ansiterm.ANSI_SGR_UNDERLINE_OFF:\n\t\twindowsMode &^= COMMON_LVB_UNDERSCORE\n\n\t\t// Foreground colors\n\tcase ansiterm.ANSI_SGR_FOREGROUND_DEFAULT:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK)\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_BLACK:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK)\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_RED:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_GREEN:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_YELLOW:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_BLUE:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_MAGENTA:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_CYAN:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE\n\n\tcase ansiterm.ANSI_SGR_FOREGROUND_WHITE:\n\t\twindowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE\n\n\t\t// Background colors\n\tcase ansiterm.ANSI_SGR_BACKGROUND_DEFAULT:\n\t\t// Black with no intensity\n\t\twindowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK)\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_BLACK:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK)\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_RED:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_GREEN:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_YELLOW:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_BLUE:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_MAGENTA:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_CYAN:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE\n\n\tcase ansiterm.ANSI_SGR_BACKGROUND_WHITE:\n\t\twindowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE\n\t}\n\n\treturn windowsMode, inverted\n}\n\n// invertAttributes inverts the foreground and background colors of a Windows attributes value\nfunc invertAttributes(windowsMode uint16) uint16 {\n\treturn (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4)\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/cursor_helpers.go",
    "content": "// +build windows\n\npackage winterm\n\nconst (\n\thorizontal = iota\n\tvertical\n)\n\nfunc (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT {\n\tif h.originMode {\n\t\tsr := h.effectiveSr(info.Window)\n\t\treturn SMALL_RECT{\n\t\t\tTop:    sr.top,\n\t\t\tBottom: sr.bottom,\n\t\t\tLeft:   0,\n\t\t\tRight:  info.Size.X - 1,\n\t\t}\n\t} else {\n\t\treturn SMALL_RECT{\n\t\t\tTop:    info.Window.Top,\n\t\t\tBottom: info.Window.Bottom,\n\t\t\tLeft:   0,\n\t\t\tRight:  info.Size.X - 1,\n\t\t}\n\t}\n}\n\n// setCursorPosition sets the cursor to the specified position, bounded to the screen size\nfunc (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error {\n\tposition.X = ensureInRange(position.X, window.Left, window.Right)\n\tposition.Y = ensureInRange(position.Y, window.Top, window.Bottom)\n\terr := SetConsoleCursorPosition(h.fd, position)\n\tif err != nil {\n\t\treturn err\n\t}\n\th.logf(\"Cursor position set: (%d, %d)\", position.X, position.Y)\n\treturn err\n}\n\nfunc (h *windowsAnsiEventHandler) moveCursorVertical(param int) error {\n\treturn h.moveCursor(vertical, param)\n}\n\nfunc (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error {\n\treturn h.moveCursor(horizontal, param)\n}\n\nfunc (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error {\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tposition := info.CursorPosition\n\tswitch moveMode {\n\tcase horizontal:\n\t\tposition.X += int16(param)\n\tcase vertical:\n\t\tposition.Y += int16(param)\n\t}\n\n\tif err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) moveCursorLine(param int) error {\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tposition := info.CursorPosition\n\tposition.X = 0\n\tposition.Y += int16(param)\n\n\tif err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) moveCursorColumn(param int) error {\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tposition := info.CursorPosition\n\tposition.X = int16(param) - 1\n\n\tif err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/erase_helpers.go",
    "content": "// +build windows\n\npackage winterm\n\nimport \"github.com/Azure/go-ansiterm\"\n\nfunc (h *windowsAnsiEventHandler) clearRange(attributes uint16, fromCoord COORD, toCoord COORD) error {\n\t// Ignore an invalid (negative area) request\n\tif toCoord.Y < fromCoord.Y {\n\t\treturn nil\n\t}\n\n\tvar err error\n\n\tvar coordStart = COORD{}\n\tvar coordEnd = COORD{}\n\n\txCurrent, yCurrent := fromCoord.X, fromCoord.Y\n\txEnd, yEnd := toCoord.X, toCoord.Y\n\n\t// Clear any partial initial line\n\tif xCurrent > 0 {\n\t\tcoordStart.X, coordStart.Y = xCurrent, yCurrent\n\t\tcoordEnd.X, coordEnd.Y = xEnd, yCurrent\n\n\t\terr = h.clearRect(attributes, coordStart, coordEnd)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\txCurrent = 0\n\t\tyCurrent += 1\n\t}\n\n\t// Clear intervening rectangular section\n\tif yCurrent < yEnd {\n\t\tcoordStart.X, coordStart.Y = xCurrent, yCurrent\n\t\tcoordEnd.X, coordEnd.Y = xEnd, yEnd-1\n\n\t\terr = h.clearRect(attributes, coordStart, coordEnd)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\txCurrent = 0\n\t\tyCurrent = yEnd\n\t}\n\n\t// Clear remaining partial ending line\n\tcoordStart.X, coordStart.Y = xCurrent, yCurrent\n\tcoordEnd.X, coordEnd.Y = xEnd, yEnd\n\n\terr = h.clearRect(attributes, coordStart, coordEnd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) clearRect(attributes uint16, fromCoord COORD, toCoord COORD) error {\n\tregion := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X}\n\twidth := toCoord.X - fromCoord.X + 1\n\theight := toCoord.Y - fromCoord.Y + 1\n\tsize := uint32(width) * uint32(height)\n\n\tif size <= 0 {\n\t\treturn nil\n\t}\n\n\tbuffer := make([]CHAR_INFO, size)\n\n\tchar := CHAR_INFO{ansiterm.FILL_CHARACTER, attributes}\n\tfor i := 0; i < int(size); i++ {\n\t\tbuffer[i] = char\n\t}\n\n\terr := WriteConsoleOutput(h.fd, buffer, COORD{X: width, Y: height}, COORD{X: 0, Y: 0}, &region)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/scroll_helper.go",
    "content": "// +build windows\n\npackage winterm\n\n// effectiveSr gets the current effective scroll region in buffer coordinates\nfunc (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {\n\ttop := addInRange(window.Top, h.sr.top, window.Top, window.Bottom)\n\tbottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom)\n\tif top >= bottom {\n\t\ttop = window.Top\n\t\tbottom = window.Bottom\n\t}\n\treturn scrollRegion{top: top, bottom: bottom}\n}\n\nfunc (h *windowsAnsiEventHandler) scrollUp(param int) error {\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsr := h.effectiveSr(info.Window)\n\treturn h.scroll(param, sr, info)\n}\n\nfunc (h *windowsAnsiEventHandler) scrollDown(param int) error {\n\treturn h.scrollUp(-param)\n}\n\nfunc (h *windowsAnsiEventHandler) deleteLines(param int) error {\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tstart := info.CursorPosition.Y\n\tsr := h.effectiveSr(info.Window)\n\t// Lines cannot be inserted or deleted outside the scrolling region.\n\tif start >= sr.top && start <= sr.bottom {\n\t\tsr.top = start\n\t\treturn h.scroll(param, sr, info)\n\t} else {\n\t\treturn nil\n\t}\n}\n\nfunc (h *windowsAnsiEventHandler) insertLines(param int) error {\n\treturn h.deleteLines(-param)\n}\n\n// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.\nfunc (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {\n\th.logf(\"scroll: scrollTop: %d, scrollBottom: %d\", sr.top, sr.bottom)\n\th.logf(\"scroll: windowTop: %d, windowBottom: %d\", info.Window.Top, info.Window.Bottom)\n\n\t// Copy from and clip to the scroll region (full buffer width)\n\tscrollRect := SMALL_RECT{\n\t\tTop:    sr.top,\n\t\tBottom: sr.bottom,\n\t\tLeft:   0,\n\t\tRight:  info.Size.X - 1,\n\t}\n\n\t// Origin to which area should be copied\n\tdestOrigin := COORD{\n\t\tX: 0,\n\t\tY: sr.top - int16(param),\n\t}\n\n\tchar := CHAR_INFO{\n\t\tUnicodeChar: ' ',\n\t\tAttributes:  h.attributes,\n\t}\n\n\tif err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) deleteCharacters(param int) error {\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn h.scrollLine(param, info.CursorPosition, info)\n}\n\nfunc (h *windowsAnsiEventHandler) insertCharacters(param int) error {\n\treturn h.deleteCharacters(-param)\n}\n\n// scrollLine scrolls a line horizontally starting at the provided position by a number of columns.\nfunc (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error {\n\t// Copy from and clip to the scroll region (full buffer width)\n\tscrollRect := SMALL_RECT{\n\t\tTop:    position.Y,\n\t\tBottom: position.Y,\n\t\tLeft:   position.X,\n\t\tRight:  info.Size.X - 1,\n\t}\n\n\t// Origin to which area should be copied\n\tdestOrigin := COORD{\n\t\tX: position.X - int16(columns),\n\t\tY: position.Y,\n\t}\n\n\tchar := CHAR_INFO{\n\t\tUnicodeChar: ' ',\n\t\tAttributes:  h.attributes,\n\t}\n\n\tif err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/utilities.go",
    "content": "// +build windows\n\npackage winterm\n\n// AddInRange increments a value by the passed quantity while ensuring the values\n// always remain within the supplied min / max range.\nfunc addInRange(n int16, increment int16, min int16, max int16) int16 {\n\treturn ensureInRange(n+increment, min, max)\n}\n"
  },
  {
    "path": "vendor/github.com/Azure/go-ansiterm/winterm/win_event_handler.go",
    "content": "// +build windows\n\npackage winterm\n\nimport (\n\t\"bytes\"\n\t\"log\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"github.com/Azure/go-ansiterm\"\n)\n\ntype windowsAnsiEventHandler struct {\n\tfd             uintptr\n\tfile           *os.File\n\tinfoReset      *CONSOLE_SCREEN_BUFFER_INFO\n\tsr             scrollRegion\n\tbuffer         bytes.Buffer\n\tattributes     uint16\n\tinverted       bool\n\twrapNext       bool\n\tdrewMarginByte bool\n\toriginMode     bool\n\tmarginByte     byte\n\tcurInfo        *CONSOLE_SCREEN_BUFFER_INFO\n\tcurPos         COORD\n\tlogf           func(string, ...interface{})\n}\n\ntype Option func(*windowsAnsiEventHandler)\n\nfunc WithLogf(f func(string, ...interface{})) Option {\n\treturn func(w *windowsAnsiEventHandler) {\n\t\tw.logf = f\n\t}\n}\n\nfunc CreateWinEventHandler(fd uintptr, file *os.File, opts ...Option) ansiterm.AnsiEventHandler {\n\tinfoReset, err := GetConsoleScreenBufferInfo(fd)\n\tif err != nil {\n\t\treturn nil\n\t}\n\n\th := &windowsAnsiEventHandler{\n\t\tfd:         fd,\n\t\tfile:       file,\n\t\tinfoReset:  infoReset,\n\t\tattributes: infoReset.Attributes,\n\t}\n\tfor _, o := range opts {\n\t\to(h)\n\t}\n\n\tif isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == \"1\" {\n\t\tlogFile, _ := os.Create(\"winEventHandler.log\")\n\t\tlogger := log.New(logFile, \"\", log.LstdFlags)\n\t\tif h.logf != nil {\n\t\t\tl := h.logf\n\t\t\th.logf = func(s string, v ...interface{}) {\n\t\t\t\tl(s, v...)\n\t\t\t\tlogger.Printf(s, v...)\n\t\t\t}\n\t\t} else {\n\t\t\th.logf = logger.Printf\n\t\t}\n\t}\n\n\tif h.logf == nil {\n\t\th.logf = func(string, ...interface{}) {}\n\t}\n\n\treturn h\n}\n\ntype scrollRegion struct {\n\ttop    int16\n\tbottom int16\n}\n\n// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the\n// current cursor position and scroll region settings, in which case it returns\n// true. If no special handling is necessary, then it does nothing and returns\n// false.\n//\n// In the false case, the caller should ensure that a carriage return\n// and line feed are inserted or that the text is otherwise wrapped.\nfunc (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {\n\tif h.wrapNext {\n\t\tif err := h.Flush(); err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\th.clearWrap()\n\t}\n\tpos, info, err := h.getCurrentInfo()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tsr := h.effectiveSr(info.Window)\n\tif pos.Y == sr.bottom {\n\t\t// Scrolling is necessary. Let Windows automatically scroll if the scrolling region\n\t\t// is the full window.\n\t\tif sr.top == info.Window.Top && sr.bottom == info.Window.Bottom {\n\t\t\tif includeCR {\n\t\t\t\tpos.X = 0\n\t\t\t\th.updatePos(pos)\n\t\t\t}\n\t\t\treturn false, nil\n\t\t}\n\n\t\t// A custom scroll region is active. Scroll the window manually to simulate\n\t\t// the LF.\n\t\tif err := h.Flush(); err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\th.logf(\"Simulating LF inside scroll region\")\n\t\tif err := h.scrollUp(1); err != nil {\n\t\t\treturn false, err\n\t\t}\n\t\tif includeCR {\n\t\t\tpos.X = 0\n\t\t\tif err := SetConsoleCursorPosition(h.fd, pos); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\t} else if pos.Y < info.Window.Bottom {\n\t\t// Let Windows handle the LF.\n\t\tpos.Y++\n\t\tif includeCR {\n\t\t\tpos.X = 0\n\t\t}\n\t\th.updatePos(pos)\n\t\treturn false, nil\n\t} else {\n\t\t// The cursor is at the bottom of the screen but outside the scroll\n\t\t// region. Skip the LF.\n\t\th.logf(\"Simulating LF outside scroll region\")\n\t\tif includeCR {\n\t\t\tif err := h.Flush(); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tpos.X = 0\n\t\t\tif err := SetConsoleCursorPosition(h.fd, pos); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\t}\n}\n\n// executeLF executes a LF without a CR.\nfunc (h *windowsAnsiEventHandler) executeLF() error {\n\thandled, err := h.simulateLF(false)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !handled {\n\t\t// Windows LF will reset the cursor column position. Write the LF\n\t\t// and restore the cursor position.\n\t\tpos, _, err := h.getCurrentInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\th.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)\n\t\tif pos.X != 0 {\n\t\t\tif err := h.Flush(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\th.logf(\"Resetting cursor position for LF without CR\")\n\t\t\tif err := SetConsoleCursorPosition(h.fd, pos); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) Print(b byte) error {\n\tif h.wrapNext {\n\t\th.buffer.WriteByte(h.marginByte)\n\t\th.clearWrap()\n\t\tif _, err := h.simulateLF(true); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tpos, info, err := h.getCurrentInfo()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif pos.X == info.Size.X-1 {\n\t\th.wrapNext = true\n\t\th.marginByte = b\n\t} else {\n\t\tpos.X++\n\t\th.updatePos(pos)\n\t\th.buffer.WriteByte(b)\n\t}\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) Execute(b byte) error {\n\tswitch b {\n\tcase ansiterm.ANSI_TAB:\n\t\th.logf(\"Execute(TAB)\")\n\t\t// Move to the next tab stop, but preserve auto-wrap if already set.\n\t\tif !h.wrapNext {\n\t\t\tpos, info, err := h.getCurrentInfo()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tpos.X = (pos.X + 8) - pos.X%8\n\t\t\tif pos.X >= info.Size.X {\n\t\t\t\tpos.X = info.Size.X - 1\n\t\t\t}\n\t\t\tif err := h.Flush(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := SetConsoleCursorPosition(h.fd, pos); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\n\tcase ansiterm.ANSI_BEL:\n\t\th.buffer.WriteByte(ansiterm.ANSI_BEL)\n\t\treturn nil\n\n\tcase ansiterm.ANSI_BACKSPACE:\n\t\tif h.wrapNext {\n\t\t\tif err := h.Flush(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\th.clearWrap()\n\t\t}\n\t\tpos, _, err := h.getCurrentInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif pos.X > 0 {\n\t\t\tpos.X--\n\t\t\th.updatePos(pos)\n\t\t\th.buffer.WriteByte(ansiterm.ANSI_BACKSPACE)\n\t\t}\n\t\treturn nil\n\n\tcase ansiterm.ANSI_VERTICAL_TAB, ansiterm.ANSI_FORM_FEED:\n\t\t// Treat as true LF.\n\t\treturn h.executeLF()\n\n\tcase ansiterm.ANSI_LINE_FEED:\n\t\t// Simulate a CR and LF for now since there is no way in go-ansiterm\n\t\t// to tell if the LF should include CR (and more things break when it's\n\t\t// missing than when it's incorrectly added).\n\t\thandled, err := h.simulateLF(true)\n\t\tif handled || err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)\n\n\tcase ansiterm.ANSI_CARRIAGE_RETURN:\n\t\tif h.wrapNext {\n\t\t\tif err := h.Flush(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\th.clearWrap()\n\t\t}\n\t\tpos, _, err := h.getCurrentInfo()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif pos.X != 0 {\n\t\t\tpos.X = 0\n\t\t\th.updatePos(pos)\n\t\t\th.buffer.WriteByte(ansiterm.ANSI_CARRIAGE_RETURN)\n\t\t}\n\t\treturn nil\n\n\tdefault:\n\t\treturn nil\n\t}\n}\n\nfunc (h *windowsAnsiEventHandler) CUU(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CUU: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.moveCursorVertical(-param)\n}\n\nfunc (h *windowsAnsiEventHandler) CUD(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CUD: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.moveCursorVertical(param)\n}\n\nfunc (h *windowsAnsiEventHandler) CUF(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CUF: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.moveCursorHorizontal(param)\n}\n\nfunc (h *windowsAnsiEventHandler) CUB(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CUB: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.moveCursorHorizontal(-param)\n}\n\nfunc (h *windowsAnsiEventHandler) CNL(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CNL: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.moveCursorLine(param)\n}\n\nfunc (h *windowsAnsiEventHandler) CPL(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CPL: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.moveCursorLine(-param)\n}\n\nfunc (h *windowsAnsiEventHandler) CHA(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CHA: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.moveCursorColumn(param)\n}\n\nfunc (h *windowsAnsiEventHandler) VPA(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"VPA: [[%d]]\", param)\n\th.clearWrap()\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\twindow := h.getCursorWindow(info)\n\tposition := info.CursorPosition\n\tposition.Y = window.Top + int16(param) - 1\n\treturn h.setCursorPosition(position, window)\n}\n\nfunc (h *windowsAnsiEventHandler) CUP(row int, col int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"CUP: [[%d %d]]\", row, col)\n\th.clearWrap()\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\twindow := h.getCursorWindow(info)\n\tposition := COORD{window.Left + int16(col) - 1, window.Top + int16(row) - 1}\n\treturn h.setCursorPosition(position, window)\n}\n\nfunc (h *windowsAnsiEventHandler) HVP(row int, col int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"HVP: [[%d %d]]\", row, col)\n\th.clearWrap()\n\treturn h.CUP(row, col)\n}\n\nfunc (h *windowsAnsiEventHandler) DECTCEM(visible bool) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"DECTCEM: [%v]\", []string{strconv.FormatBool(visible)})\n\th.clearWrap()\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) DECOM(enable bool) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"DECOM: [%v]\", []string{strconv.FormatBool(enable)})\n\th.clearWrap()\n\th.originMode = enable\n\treturn h.CUP(1, 1)\n}\n\nfunc (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"DECCOLM: [%v]\", []string{strconv.FormatBool(use132)})\n\th.clearWrap()\n\tif err := h.ED(2); err != nil {\n\t\treturn err\n\t}\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\ttargetWidth := int16(80)\n\tif use132 {\n\t\ttargetWidth = 132\n\t}\n\tif info.Size.X < targetWidth {\n\t\tif err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil {\n\t\t\th.logf(\"set buffer failed: %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\twindow := info.Window\n\twindow.Left = 0\n\twindow.Right = targetWidth - 1\n\tif err := SetConsoleWindowInfo(h.fd, true, window); err != nil {\n\t\th.logf(\"set window failed: %v\", err)\n\t\treturn err\n\t}\n\tif info.Size.X > targetWidth {\n\t\tif err := SetConsoleScreenBufferSize(h.fd, COORD{targetWidth, info.Size.Y}); err != nil {\n\t\t\th.logf(\"set buffer failed: %v\", err)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn SetConsoleCursorPosition(h.fd, COORD{0, 0})\n}\n\nfunc (h *windowsAnsiEventHandler) ED(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"ED: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\n\t// [J  -- Erases from the cursor to the end of the screen, including the cursor position.\n\t// [1J -- Erases from the beginning of the screen to the cursor, including the cursor position.\n\t// [2J -- Erases the complete display. The cursor does not move.\n\t// Notes:\n\t// -- Clearing the entire buffer, versus just the Window, works best for Windows Consoles\n\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar start COORD\n\tvar end COORD\n\n\tswitch param {\n\tcase 0:\n\t\tstart = info.CursorPosition\n\t\tend = COORD{info.Size.X - 1, info.Size.Y - 1}\n\n\tcase 1:\n\t\tstart = COORD{0, 0}\n\t\tend = info.CursorPosition\n\n\tcase 2:\n\t\tstart = COORD{0, 0}\n\t\tend = COORD{info.Size.X - 1, info.Size.Y - 1}\n\t}\n\n\terr = h.clearRange(h.attributes, start, end)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// If the whole buffer was cleared, move the window to the top while preserving\n\t// the window-relative cursor position.\n\tif param == 2 {\n\t\tpos := info.CursorPosition\n\t\twindow := info.Window\n\t\tpos.Y -= window.Top\n\t\twindow.Bottom -= window.Top\n\t\twindow.Top = 0\n\t\tif err := SetConsoleCursorPosition(h.fd, pos); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := SetConsoleWindowInfo(h.fd, true, window); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) EL(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"EL: [%v]\", strconv.Itoa(param))\n\th.clearWrap()\n\n\t// [K  -- Erases from the cursor to the end of the line, including the cursor position.\n\t// [1K -- Erases from the beginning of the line to the cursor, including the cursor position.\n\t// [2K -- Erases the complete line.\n\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar start COORD\n\tvar end COORD\n\n\tswitch param {\n\tcase 0:\n\t\tstart = info.CursorPosition\n\t\tend = COORD{info.Size.X, info.CursorPosition.Y}\n\n\tcase 1:\n\t\tstart = COORD{0, info.CursorPosition.Y}\n\t\tend = info.CursorPosition\n\n\tcase 2:\n\t\tstart = COORD{0, info.CursorPosition.Y}\n\t\tend = COORD{info.Size.X, info.CursorPosition.Y}\n\t}\n\n\terr = h.clearRange(h.attributes, start, end)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) IL(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"IL: [%v]\", strconv.Itoa(param))\n\th.clearWrap()\n\treturn h.insertLines(param)\n}\n\nfunc (h *windowsAnsiEventHandler) DL(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"DL: [%v]\", strconv.Itoa(param))\n\th.clearWrap()\n\treturn h.deleteLines(param)\n}\n\nfunc (h *windowsAnsiEventHandler) ICH(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"ICH: [%v]\", strconv.Itoa(param))\n\th.clearWrap()\n\treturn h.insertCharacters(param)\n}\n\nfunc (h *windowsAnsiEventHandler) DCH(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"DCH: [%v]\", strconv.Itoa(param))\n\th.clearWrap()\n\treturn h.deleteCharacters(param)\n}\n\nfunc (h *windowsAnsiEventHandler) SGR(params []int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\tstrings := []string{}\n\tfor _, v := range params {\n\t\tstrings = append(strings, strconv.Itoa(v))\n\t}\n\n\th.logf(\"SGR: [%v]\", strings)\n\n\tif len(params) <= 0 {\n\t\th.attributes = h.infoReset.Attributes\n\t\th.inverted = false\n\t} else {\n\t\tfor _, attr := range params {\n\n\t\t\tif attr == ansiterm.ANSI_SGR_RESET {\n\t\t\t\th.attributes = h.infoReset.Attributes\n\t\t\t\th.inverted = false\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\th.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, int16(attr))\n\t\t}\n\t}\n\n\tattributes := h.attributes\n\tif h.inverted {\n\t\tattributes = invertAttributes(attributes)\n\t}\n\terr := SetConsoleTextAttribute(h.fd, attributes)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) SU(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"SU: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.scrollUp(param)\n}\n\nfunc (h *windowsAnsiEventHandler) SD(param int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"SD: [%v]\", []string{strconv.Itoa(param)})\n\th.clearWrap()\n\treturn h.scrollDown(param)\n}\n\nfunc (h *windowsAnsiEventHandler) DA(params []string) error {\n\th.logf(\"DA: [%v]\", params)\n\t// DA cannot be implemented because it must send data on the VT100 input stream,\n\t// which is not available to go-ansiterm.\n\treturn nil\n}\n\nfunc (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"DECSTBM: [%d, %d]\", top, bottom)\n\n\t// Windows is 0 indexed, Linux is 1 indexed\n\th.sr.top = int16(top - 1)\n\th.sr.bottom = int16(bottom - 1)\n\n\t// This command also moves the cursor to the origin.\n\th.clearWrap()\n\treturn h.CUP(1, 1)\n}\n\nfunc (h *windowsAnsiEventHandler) RI() error {\n\tif err := h.Flush(); err != nil {\n\t\treturn err\n\t}\n\th.logf(\"RI: []\")\n\th.clearWrap()\n\n\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tsr := h.effectiveSr(info.Window)\n\tif info.CursorPosition.Y == sr.top {\n\t\treturn h.scrollDown(1)\n\t}\n\n\treturn h.moveCursorVertical(-1)\n}\n\nfunc (h *windowsAnsiEventHandler) IND() error {\n\th.logf(\"IND: []\")\n\treturn h.executeLF()\n}\n\nfunc (h *windowsAnsiEventHandler) Flush() error {\n\th.curInfo = nil\n\tif h.buffer.Len() > 0 {\n\t\th.logf(\"Flush: [%s]\", h.buffer.Bytes())\n\t\tif _, err := h.buffer.WriteTo(h.file); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif h.wrapNext && !h.drewMarginByte {\n\t\th.logf(\"Flush: drawing margin byte '%c'\", h.marginByte)\n\n\t\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcharInfo := []CHAR_INFO{{UnicodeChar: uint16(h.marginByte), Attributes: info.Attributes}}\n\t\tsize := COORD{1, 1}\n\t\tposition := COORD{0, 0}\n\t\tregion := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y}\n\t\tif err := WriteConsoleOutput(h.fd, charInfo, size, position, &region); err != nil {\n\t\t\treturn err\n\t\t}\n\t\th.drewMarginByte = true\n\t}\n\treturn nil\n}\n\n// cacheConsoleInfo ensures that the current console screen information has been queried\n// since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos.\nfunc (h *windowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) {\n\tif h.curInfo == nil {\n\t\tinfo, err := GetConsoleScreenBufferInfo(h.fd)\n\t\tif err != nil {\n\t\t\treturn COORD{}, nil, err\n\t\t}\n\t\th.curInfo = info\n\t\th.curPos = info.CursorPosition\n\t}\n\treturn h.curPos, h.curInfo, nil\n}\n\nfunc (h *windowsAnsiEventHandler) updatePos(pos COORD) {\n\tif h.curInfo == nil {\n\t\tpanic(\"failed to call getCurrentInfo before calling updatePos\")\n\t}\n\th.curPos = pos\n}\n\n// clearWrap clears the state where the cursor is in the margin\n// waiting for the next character before wrapping the line. This must\n// be done before most operations that act on the cursor.\nfunc (h *windowsAnsiEventHandler) clearWrap() {\n\th.wrapNext = false\n\th.drewMarginByte = false\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/.gitattributes",
    "content": "* text=auto eol=lf"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/.gitignore",
    "content": ".vscode/\n\n*.exe\n\n# testing\ntestdata\n\n# go workspaces\ngo.work\ngo.work.sum\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/.golangci.yml",
    "content": "run:\n  skip-dirs:\n    - pkg/etw/sample\n\nlinters:\n  enable:\n    # style\n    - containedctx # struct contains a context\n    - dupl # duplicate code\n    - errname # erorrs are named correctly\n    - nolintlint # \"//nolint\" directives are properly explained\n    - revive # golint replacement\n    - unconvert # unnecessary conversions\n    - wastedassign\n\n    # bugs, performance, unused, etc ...\n    - contextcheck # function uses a non-inherited context\n    - errorlint # errors not wrapped for 1.13\n    - exhaustive # check exhaustiveness of enum switch statements\n    - gofmt # files are gofmt'ed\n    - gosec # security\n    - nilerr # returns nil even with non-nil error\n    - unparam # unused function params\n\nissues:\n  exclude-rules:\n    # err is very often shadowed in nested scopes\n    - linters:\n        - govet\n      text: '^shadow: declaration of \"err\" shadows declaration'\n\n    # ignore long lines for skip autogen directives\n    - linters:\n        - revive\n      text: \"^line-length-limit: \"\n      source: \"^//(go:generate|sys) \"\n\n    #TODO: remove after upgrading to go1.18\n    # ignore comment spacing for nolint and sys directives\n    - linters:\n        - revive\n      text: \"^comment-spacings: no space between comment delimiter and comment text\"\n      source: \"//(cspell:|nolint:|sys |todo)\"\n\n    # not on go 1.18 yet, so no any\n    - linters:\n        - revive\n      text: \"^use-any: since GO 1.18 'interface{}' can be replaced by 'any'\"\n\n    # allow unjustified ignores of error checks in defer statements\n    - linters:\n        - nolintlint\n      text: \"^directive `//nolint:errcheck` should provide explanation\"\n      source: '^\\s*defer '\n\n    # allow unjustified ignores of error lints for io.EOF\n    - linters:\n        - nolintlint\n      text: \"^directive `//nolint:errorlint` should provide explanation\"\n      source: '[=|!]= io.EOF'\n\n\nlinters-settings:\n  exhaustive:\n    default-signifies-exhaustive: true\n  govet:\n    enable-all: true\n    disable:\n      # struct order is often for Win32 compat\n      # also, ignore pointer bytes/GC issues for now until performance becomes an issue\n      - fieldalignment\n    check-shadowing: true\n  nolintlint:\n    allow-leading-space: false\n    require-explanation: true\n    require-specific: true\n  revive:\n    # revive is more configurable than static check, so likely the preferred alternative to static-check\n    # (once the perf issue is solved: https://github.com/golangci/golangci-lint/issues/2997)\n    enable-all-rules:\n      true\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md\n    rules:\n      # rules with required arguments\n      - name: argument-limit\n        disabled: true\n      - name: banned-characters\n        disabled: true\n      - name: cognitive-complexity\n        disabled: true\n      - name: cyclomatic\n        disabled: true\n      - name: file-header\n        disabled: true\n      - name: function-length\n        disabled: true\n      - name: function-result-limit\n        disabled: true\n      - name: max-public-structs\n        disabled: true\n      # geneally annoying rules\n      - name: add-constant # complains about any and all strings and integers\n        disabled: true\n      - name: confusing-naming # we frequently use \"Foo()\" and \"foo()\" together\n        disabled: true\n      - name: flag-parameter # excessive, and a common idiom we use\n        disabled: true\n      - name: unhandled-error # warns over common fmt.Print* and io.Close; rely on errcheck instead\n        disabled: true\n      # general config\n      - name: line-length-limit\n        arguments:\n          - 140\n      - name: var-naming\n        arguments:\n          - []\n          - - CID\n            - CRI\n            - CTRD\n            - DACL\n            - DLL\n            - DOS\n            - ETW\n            - FSCTL\n            - GCS\n            - GMSA\n            - HCS\n            - HV\n            - IO\n            - LCOW\n            - LDAP\n            - LPAC\n            - LTSC\n            - MMIO\n            - NT\n            - OCI\n            - PMEM\n            - PWSH\n            - RX\n            - SACl\n            - SID\n            - SMB\n            - TX\n            - VHD\n            - VHDX\n            - VMID\n            - VPCI\n            - WCOW\n            - WIM\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/CODEOWNERS",
    "content": "  * @microsoft/containerplat\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Microsoft\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\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/README.md",
    "content": "# go-winio [![Build Status](https://github.com/microsoft/go-winio/actions/workflows/ci.yml/badge.svg)](https://github.com/microsoft/go-winio/actions/workflows/ci.yml)\n\nThis repository contains utilities for efficiently performing Win32 IO operations in\nGo. Currently, this is focused on accessing named pipes and other file handles, and\nfor using named pipes as a net transport.\n\nThis code relies on IO completion ports to avoid blocking IO on system threads, allowing Go\nto reuse the thread to schedule another goroutine. This limits support to Windows Vista and\nnewer operating systems. This is similar to the implementation of network sockets in Go's net\npackage.\n\nPlease see the LICENSE file for licensing information.\n\n## Contributing\n\nThis project welcomes contributions and suggestions.\nMost contributions require you to agree to a Contributor License Agreement (CLA) declaring that\nyou have the right to, and actually do, grant us the rights to use your contribution.\nFor details, visit [Microsoft CLA](https://cla.microsoft.com).\n\nWhen you submit a pull request, a CLA-bot will automatically determine whether you need to\nprovide a CLA and decorate the PR appropriately (e.g., label, comment).\nSimply follow the instructions provided by the bot.\nYou will only need to do this once across all repos using our CLA.\n\nAdditionally, the pull request pipeline requires the following steps to be performed before\nmergining.\n\n### Code Sign-Off\n\nWe require that contributors sign their commits using [`git commit --signoff`][git-commit-s]\nto certify they either authored the work themselves or otherwise have permission to use it in this project.\n\nA range of commits can be signed off using [`git rebase --signoff`][git-rebase-s].\n\nPlease see [the developer certificate](https://developercertificate.org) for more info,\nas well as to make sure that you can attest to the rules listed.\nOur CI uses the DCO Github app to ensure that all commits in a given PR are signed-off.\n\n### Linting\n\nCode must pass a linting stage, which uses [`golangci-lint`][lint].\nThe linting settings are stored in [`.golangci.yaml`](./.golangci.yaml), and can be run\nautomatically with VSCode by adding the following to your workspace or folder settings:\n\n```json\n    \"go.lintTool\": \"golangci-lint\",\n    \"go.lintOnSave\": \"package\",\n```\n\nAdditional editor [integrations options are also available][lint-ide].\n\nAlternatively, `golangci-lint` can be [installed locally][lint-install] and run from the repo root:\n\n```shell\n# use . or specify a path to only lint a package\n# to show all lint errors, use flags \"--max-issues-per-linter=0 --max-same-issues=0\"\n> golangci-lint run ./...\n```\n\n### Go Generate\n\nThe pipeline checks that auto-generated code, via `go generate`, are up to date.\n\nThis can be done for the entire repo:\n\n```shell\n> go generate ./...\n```\n\n## Code of Conduct\n\nThis project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).\nFor more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or\ncontact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.\n\n## Special Thanks\n\nThanks to [natefinch][natefinch] for the inspiration for this library.\nSee [npipe](https://github.com/natefinch/npipe) for another named pipe implementation.\n\n[lint]: https://golangci-lint.run/\n[lint-ide]: https://golangci-lint.run/usage/integrations/#editor-integration\n[lint-install]: https://golangci-lint.run/usage/install/#local-installation\n\n[git-commit-s]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s\n[git-rebase-s]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---signoff\n\n[natefinch]: https://github.com/natefinch\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/SECURITY.md",
    "content": "<!-- BEGIN MICROSOFT SECURITY.MD V0.0.7 BLOCK -->\n\n## Security\n\nMicrosoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).\n\nIf you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.\n\n## Reporting Security Issues\n\n**Please do not report security vulnerabilities through public GitHub issues.**\n\nInstead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).\n\nIf you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com).  If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).\n\nYou should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). \n\nPlease include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:\n\n  * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)\n  * Full paths of source file(s) related to the manifestation of the issue\n  * The location of the affected source code (tag/branch/commit or direct URL)\n  * Any special configuration required to reproduce the issue\n  * Step-by-step instructions to reproduce the issue\n  * Proof-of-concept or exploit code (if possible)\n  * Impact of the issue, including how an attacker might exploit the issue\n\nThis information will help us triage your report more quickly.\n\nIf you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.\n\n## Preferred Languages\n\nWe prefer all communications to be in English.\n\n## Policy\n\nMicrosoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).\n\n<!-- END MICROSOFT SECURITY.MD BLOCK -->\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/backup.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime\"\n\t\"syscall\"\n\t\"unicode/utf16\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead\n//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite\n\nconst (\n\tBackupData = uint32(iota + 1)\n\tBackupEaData\n\tBackupSecurity\n\tBackupAlternateData\n\tBackupLink\n\tBackupPropertyData\n\tBackupObjectId //revive:disable-line:var-naming ID, not Id\n\tBackupReparseData\n\tBackupSparseBlock\n\tBackupTxfsData\n)\n\nconst (\n\tStreamSparseAttributes = uint32(8)\n)\n\n//nolint:revive // var-naming: ALL_CAPS\nconst (\n\tWRITE_DAC              = windows.WRITE_DAC\n\tWRITE_OWNER            = windows.WRITE_OWNER\n\tACCESS_SYSTEM_SECURITY = windows.ACCESS_SYSTEM_SECURITY\n)\n\n// BackupHeader represents a backup stream of a file.\ntype BackupHeader struct {\n\t//revive:disable-next-line:var-naming ID, not Id\n\tId         uint32 // The backup stream ID\n\tAttributes uint32 // Stream attributes\n\tSize       int64  // The size of the stream in bytes\n\tName       string // The name of the stream (for BackupAlternateData only).\n\tOffset     int64  // The offset of the stream in the file (for BackupSparseBlock only).\n}\n\ntype win32StreamID struct {\n\tStreamID   uint32\n\tAttributes uint32\n\tSize       uint64\n\tNameSize   uint32\n}\n\n// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series\n// of BackupHeader values.\ntype BackupStreamReader struct {\n\tr         io.Reader\n\tbytesLeft int64\n}\n\n// NewBackupStreamReader produces a BackupStreamReader from any io.Reader.\nfunc NewBackupStreamReader(r io.Reader) *BackupStreamReader {\n\treturn &BackupStreamReader{r, 0}\n}\n\n// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if\n// it was not completely read.\nfunc (r *BackupStreamReader) Next() (*BackupHeader, error) {\n\tif r.bytesLeft > 0 { //nolint:nestif // todo: flatten this\n\t\tif s, ok := r.r.(io.Seeker); ok {\n\t\t\t// Make sure Seek on io.SeekCurrent sometimes succeeds\n\t\t\t// before trying the actual seek.\n\t\t\tif _, err := s.Seek(0, io.SeekCurrent); err == nil {\n\t\t\t\tif _, err = s.Seek(r.bytesLeft, io.SeekCurrent); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tr.bytesLeft = 0\n\t\t\t}\n\t\t}\n\t\tif _, err := io.Copy(io.Discard, r); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tvar wsi win32StreamID\n\tif err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil {\n\t\treturn nil, err\n\t}\n\thdr := &BackupHeader{\n\t\tId:         wsi.StreamID,\n\t\tAttributes: wsi.Attributes,\n\t\tSize:       int64(wsi.Size),\n\t}\n\tif wsi.NameSize != 0 {\n\t\tname := make([]uint16, int(wsi.NameSize/2))\n\t\tif err := binary.Read(r.r, binary.LittleEndian, name); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\thdr.Name = syscall.UTF16ToString(name)\n\t}\n\tif wsi.StreamID == BackupSparseBlock {\n\t\tif err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\thdr.Size -= 8\n\t}\n\tr.bytesLeft = hdr.Size\n\treturn hdr, nil\n}\n\n// Read reads from the current backup stream.\nfunc (r *BackupStreamReader) Read(b []byte) (int, error) {\n\tif r.bytesLeft == 0 {\n\t\treturn 0, io.EOF\n\t}\n\tif int64(len(b)) > r.bytesLeft {\n\t\tb = b[:r.bytesLeft]\n\t}\n\tn, err := r.r.Read(b)\n\tr.bytesLeft -= int64(n)\n\tif err == io.EOF {\n\t\terr = io.ErrUnexpectedEOF\n\t} else if r.bytesLeft == 0 && err == nil {\n\t\terr = io.EOF\n\t}\n\treturn n, err\n}\n\n// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API.\ntype BackupStreamWriter struct {\n\tw         io.Writer\n\tbytesLeft int64\n}\n\n// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer.\nfunc NewBackupStreamWriter(w io.Writer) *BackupStreamWriter {\n\treturn &BackupStreamWriter{w, 0}\n}\n\n// WriteHeader writes the next backup stream header and prepares for calls to Write().\nfunc (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error {\n\tif w.bytesLeft != 0 {\n\t\treturn fmt.Errorf(\"missing %d bytes\", w.bytesLeft)\n\t}\n\tname := utf16.Encode([]rune(hdr.Name))\n\twsi := win32StreamID{\n\t\tStreamID:   hdr.Id,\n\t\tAttributes: hdr.Attributes,\n\t\tSize:       uint64(hdr.Size),\n\t\tNameSize:   uint32(len(name) * 2),\n\t}\n\tif hdr.Id == BackupSparseBlock {\n\t\t// Include space for the int64 block offset\n\t\twsi.Size += 8\n\t}\n\tif err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil {\n\t\treturn err\n\t}\n\tif len(name) != 0 {\n\t\tif err := binary.Write(w.w, binary.LittleEndian, name); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif hdr.Id == BackupSparseBlock {\n\t\tif err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tw.bytesLeft = hdr.Size\n\treturn nil\n}\n\n// Write writes to the current backup stream.\nfunc (w *BackupStreamWriter) Write(b []byte) (int, error) {\n\tif w.bytesLeft < int64(len(b)) {\n\t\treturn 0, fmt.Errorf(\"too many bytes by %d\", int64(len(b))-w.bytesLeft)\n\t}\n\tn, err := w.w.Write(b)\n\tw.bytesLeft -= int64(n)\n\treturn n, err\n}\n\n// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API.\ntype BackupFileReader struct {\n\tf               *os.File\n\tincludeSecurity bool\n\tctx             uintptr\n}\n\n// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true,\n// Read will attempt to read the security descriptor of the file.\nfunc NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {\n\tr := &BackupFileReader{f, includeSecurity, 0}\n\treturn r\n}\n\n// Read reads a backup stream from the file by calling the Win32 API BackupRead().\nfunc (r *BackupFileReader) Read(b []byte) (int, error) {\n\tvar bytesRead uint32\n\terr := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)\n\tif err != nil {\n\t\treturn 0, &os.PathError{Op: \"BackupRead\", Path: r.f.Name(), Err: err}\n\t}\n\truntime.KeepAlive(r.f)\n\tif bytesRead == 0 {\n\t\treturn 0, io.EOF\n\t}\n\treturn int(bytesRead), nil\n}\n\n// Close frees Win32 resources associated with the BackupFileReader. It does not close\n// the underlying file.\nfunc (r *BackupFileReader) Close() error {\n\tif r.ctx != 0 {\n\t\t_ = backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)\n\t\truntime.KeepAlive(r.f)\n\t\tr.ctx = 0\n\t}\n\treturn nil\n}\n\n// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API.\ntype BackupFileWriter struct {\n\tf               *os.File\n\tincludeSecurity bool\n\tctx             uintptr\n}\n\n// NewBackupFileWriter returns a new BackupFileWriter from a file handle. If includeSecurity is true,\n// Write() will attempt to restore the security descriptor from the stream.\nfunc NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {\n\tw := &BackupFileWriter{f, includeSecurity, 0}\n\treturn w\n}\n\n// Write restores a portion of the file using the provided backup stream.\nfunc (w *BackupFileWriter) Write(b []byte) (int, error) {\n\tvar bytesWritten uint32\n\terr := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)\n\tif err != nil {\n\t\treturn 0, &os.PathError{Op: \"BackupWrite\", Path: w.f.Name(), Err: err}\n\t}\n\truntime.KeepAlive(w.f)\n\tif int(bytesWritten) != len(b) {\n\t\treturn int(bytesWritten), errors.New(\"not all bytes could be written\")\n\t}\n\treturn len(b), nil\n}\n\n// Close frees Win32 resources associated with the BackupFileWriter. It does not\n// close the underlying file.\nfunc (w *BackupFileWriter) Close() error {\n\tif w.ctx != 0 {\n\t\t_ = backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)\n\t\truntime.KeepAlive(w.f)\n\t\tw.ctx = 0\n\t}\n\treturn nil\n}\n\n// OpenForBackup opens a file or directory, potentially skipping access checks if the backup\n// or restore privileges have been acquired.\n//\n// If the file opened was a directory, it cannot be used with Readdir().\nfunc OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) {\n\twinPath, err := syscall.UTF16FromString(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\th, err := syscall.CreateFile(&winPath[0],\n\t\taccess,\n\t\tshare,\n\t\tnil,\n\t\tcreatemode,\n\t\tsyscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT,\n\t\t0)\n\tif err != nil {\n\t\terr = &os.PathError{Op: \"open\", Path: path, Err: err}\n\t\treturn nil, err\n\t}\n\treturn os.NewFile(uintptr(h), path), nil\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/doc.go",
    "content": "// This package provides utilities for efficiently performing Win32 IO operations in Go.\n// Currently, this package is provides support for genreal IO and management of\n//   - named pipes\n//   - files\n//   - [Hyper-V sockets]\n//\n// This code is similar to Go's [net] package, and uses IO completion ports to avoid\n// blocking IO on system threads, allowing Go to reuse the thread to schedule other goroutines.\n//\n// This limits support to Windows Vista and newer operating systems.\n//\n// Additionally, this package provides support for:\n//   - creating and managing GUIDs\n//   - writing to [ETW]\n//   - opening and manageing VHDs\n//   - parsing [Windows Image files]\n//   - auto-generating Win32 API code\n//\n// [Hyper-V sockets]: https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service\n// [ETW]: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/event-tracing-for-windows--etw-\n// [Windows Image files]: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/work-with-windows-images\npackage winio\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/ea.go",
    "content": "package winio\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n)\n\ntype fileFullEaInformation struct {\n\tNextEntryOffset uint32\n\tFlags           uint8\n\tNameLength      uint8\n\tValueLength     uint16\n}\n\nvar (\n\tfileFullEaInformationSize = binary.Size(&fileFullEaInformation{})\n\n\terrInvalidEaBuffer = errors.New(\"invalid extended attribute buffer\")\n\terrEaNameTooLarge  = errors.New(\"extended attribute name too large\")\n\terrEaValueTooLarge = errors.New(\"extended attribute value too large\")\n)\n\n// ExtendedAttribute represents a single Windows EA.\ntype ExtendedAttribute struct {\n\tName  string\n\tValue []byte\n\tFlags uint8\n}\n\nfunc parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) {\n\tvar info fileFullEaInformation\n\terr = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info)\n\tif err != nil {\n\t\terr = errInvalidEaBuffer\n\t\treturn ea, nb, err\n\t}\n\n\tnameOffset := fileFullEaInformationSize\n\tnameLen := int(info.NameLength)\n\tvalueOffset := nameOffset + int(info.NameLength) + 1\n\tvalueLen := int(info.ValueLength)\n\tnextOffset := int(info.NextEntryOffset)\n\tif valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) {\n\t\terr = errInvalidEaBuffer\n\t\treturn ea, nb, err\n\t}\n\n\tea.Name = string(b[nameOffset : nameOffset+nameLen])\n\tea.Value = b[valueOffset : valueOffset+valueLen]\n\tea.Flags = info.Flags\n\tif info.NextEntryOffset != 0 {\n\t\tnb = b[info.NextEntryOffset:]\n\t}\n\treturn ea, nb, err\n}\n\n// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION\n// buffer retrieved from BackupRead, ZwQueryEaFile, etc.\nfunc DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) {\n\tfor len(b) != 0 {\n\t\tea, nb, err := parseEa(b)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\teas = append(eas, ea)\n\t\tb = nb\n\t}\n\treturn eas, err\n}\n\nfunc writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error {\n\tif int(uint8(len(ea.Name))) != len(ea.Name) {\n\t\treturn errEaNameTooLarge\n\t}\n\tif int(uint16(len(ea.Value))) != len(ea.Value) {\n\t\treturn errEaValueTooLarge\n\t}\n\tentrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value))\n\twithPadding := (entrySize + 3) &^ 3\n\tnextOffset := uint32(0)\n\tif !last {\n\t\tnextOffset = withPadding\n\t}\n\tinfo := fileFullEaInformation{\n\t\tNextEntryOffset: nextOffset,\n\t\tFlags:           ea.Flags,\n\t\tNameLength:      uint8(len(ea.Name)),\n\t\tValueLength:     uint16(len(ea.Value)),\n\t}\n\n\terr := binary.Write(buf, binary.LittleEndian, &info)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = buf.Write([]byte(ea.Name))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = buf.WriteByte(0)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = buf.Write(ea.Value)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize])\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION\n// buffer for use with BackupWrite, ZwSetEaFile, etc.\nfunc EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) {\n\tvar buf bytes.Buffer\n\tfor i := range eas {\n\t\tlast := false\n\t\tif i == len(eas)-1 {\n\t\t\tlast = true\n\t\t}\n\n\t\terr := writeEa(&buf, &eas[i], last)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn buf.Bytes(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/file.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"runtime\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx\n//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort\n//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus\n//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes\n//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult\n\ntype atomicBool int32\n\nfunc (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }\nfunc (b *atomicBool) setFalse()   { atomic.StoreInt32((*int32)(b), 0) }\nfunc (b *atomicBool) setTrue()    { atomic.StoreInt32((*int32)(b), 1) }\n\n//revive:disable-next-line:predeclared Keep \"new\" to maintain consistency with \"atomic\" pkg\nfunc (b *atomicBool) swap(new bool) bool {\n\tvar newInt int32\n\tif new {\n\t\tnewInt = 1\n\t}\n\treturn atomic.SwapInt32((*int32)(b), newInt) == 1\n}\n\nvar (\n\tErrFileClosed = errors.New(\"file has already been closed\")\n\tErrTimeout    = &timeoutError{}\n)\n\ntype timeoutError struct{}\n\nfunc (*timeoutError) Error() string   { return \"i/o timeout\" }\nfunc (*timeoutError) Timeout() bool   { return true }\nfunc (*timeoutError) Temporary() bool { return true }\n\ntype timeoutChan chan struct{}\n\nvar ioInitOnce sync.Once\nvar ioCompletionPort syscall.Handle\n\n// ioResult contains the result of an asynchronous IO operation.\ntype ioResult struct {\n\tbytes uint32\n\terr   error\n}\n\n// ioOperation represents an outstanding asynchronous Win32 IO.\ntype ioOperation struct {\n\to  syscall.Overlapped\n\tch chan ioResult\n}\n\nfunc initIO() {\n\th, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tioCompletionPort = h\n\tgo ioCompletionProcessor(h)\n}\n\n// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.\n// It takes ownership of this handle and will close it if it is garbage collected.\ntype win32File struct {\n\thandle        syscall.Handle\n\twg            sync.WaitGroup\n\twgLock        sync.RWMutex\n\tclosing       atomicBool\n\tsocket        bool\n\treadDeadline  deadlineHandler\n\twriteDeadline deadlineHandler\n}\n\ntype deadlineHandler struct {\n\tsetLock     sync.Mutex\n\tchannel     timeoutChan\n\tchannelLock sync.RWMutex\n\ttimer       *time.Timer\n\ttimedout    atomicBool\n}\n\n// makeWin32File makes a new win32File from an existing file handle.\nfunc makeWin32File(h syscall.Handle) (*win32File, error) {\n\tf := &win32File{handle: h}\n\tioInitOnce.Do(initIO)\n\t_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = setFileCompletionNotificationModes(h, windows.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS|windows.FILE_SKIP_SET_EVENT_ON_HANDLE)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tf.readDeadline.channel = make(timeoutChan)\n\tf.writeDeadline.channel = make(timeoutChan)\n\treturn f, nil\n}\n\nfunc MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {\n\t// If we return the result of makeWin32File directly, it can result in an\n\t// interface-wrapped nil, rather than a nil interface value.\n\tf, err := makeWin32File(h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn f, nil\n}\n\n// closeHandle closes the resources associated with a Win32 handle.\nfunc (f *win32File) closeHandle() {\n\tf.wgLock.Lock()\n\t// Atomically set that we are closing, releasing the resources only once.\n\tif !f.closing.swap(true) {\n\t\tf.wgLock.Unlock()\n\t\t// cancel all IO and wait for it to complete\n\t\t_ = cancelIoEx(f.handle, nil)\n\t\tf.wg.Wait()\n\t\t// at this point, no new IO can start\n\t\tsyscall.Close(f.handle)\n\t\tf.handle = 0\n\t} else {\n\t\tf.wgLock.Unlock()\n\t}\n}\n\n// Close closes a win32File.\nfunc (f *win32File) Close() error {\n\tf.closeHandle()\n\treturn nil\n}\n\n// IsClosed checks if the file has been closed.\nfunc (f *win32File) IsClosed() bool {\n\treturn f.closing.isSet()\n}\n\n// prepareIO prepares for a new IO operation.\n// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.\nfunc (f *win32File) prepareIO() (*ioOperation, error) {\n\tf.wgLock.RLock()\n\tif f.closing.isSet() {\n\t\tf.wgLock.RUnlock()\n\t\treturn nil, ErrFileClosed\n\t}\n\tf.wg.Add(1)\n\tf.wgLock.RUnlock()\n\tc := &ioOperation{}\n\tc.ch = make(chan ioResult)\n\treturn c, nil\n}\n\n// ioCompletionProcessor processes completed async IOs forever.\nfunc ioCompletionProcessor(h syscall.Handle) {\n\tfor {\n\t\tvar bytes uint32\n\t\tvar key uintptr\n\t\tvar op *ioOperation\n\t\terr := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)\n\t\tif op == nil {\n\t\t\tpanic(err)\n\t\t}\n\t\top.ch <- ioResult{bytes, err}\n\t}\n}\n\n// todo: helsaawy - create an asyncIO version that takes a context\n\n// asyncIO processes the return value from ReadFile or WriteFile, blocking until\n// the operation has actually completed.\nfunc (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {\n\tif err != syscall.ERROR_IO_PENDING { //nolint:errorlint // err is Errno\n\t\treturn int(bytes), err\n\t}\n\n\tif f.closing.isSet() {\n\t\t_ = cancelIoEx(f.handle, &c.o)\n\t}\n\n\tvar timeout timeoutChan\n\tif d != nil {\n\t\td.channelLock.Lock()\n\t\ttimeout = d.channel\n\t\td.channelLock.Unlock()\n\t}\n\n\tvar r ioResult\n\tselect {\n\tcase r = <-c.ch:\n\t\terr = r.err\n\t\tif err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno\n\t\t\tif f.closing.isSet() {\n\t\t\t\terr = ErrFileClosed\n\t\t\t}\n\t\t} else if err != nil && f.socket {\n\t\t\t// err is from Win32. Query the overlapped structure to get the winsock error.\n\t\t\tvar bytes, flags uint32\n\t\t\terr = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags)\n\t\t}\n\tcase <-timeout:\n\t\t_ = cancelIoEx(f.handle, &c.o)\n\t\tr = <-c.ch\n\t\terr = r.err\n\t\tif err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno\n\t\t\terr = ErrTimeout\n\t\t}\n\t}\n\n\t// runtime.KeepAlive is needed, as c is passed via native\n\t// code to ioCompletionProcessor, c must remain alive\n\t// until the channel read is complete.\n\t// todo: (de)allocate *ioOperation via win32 heap functions, instead of needing to KeepAlive?\n\truntime.KeepAlive(c)\n\treturn int(r.bytes), err\n}\n\n// Read reads from a file handle.\nfunc (f *win32File) Read(b []byte) (int, error) {\n\tc, err := f.prepareIO()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer f.wg.Done()\n\n\tif f.readDeadline.timedout.isSet() {\n\t\treturn 0, ErrTimeout\n\t}\n\n\tvar bytes uint32\n\terr = syscall.ReadFile(f.handle, b, &bytes, &c.o)\n\tn, err := f.asyncIO(c, &f.readDeadline, bytes, err)\n\truntime.KeepAlive(b)\n\n\t// Handle EOF conditions.\n\tif err == nil && n == 0 && len(b) != 0 {\n\t\treturn 0, io.EOF\n\t} else if err == syscall.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno\n\t\treturn 0, io.EOF\n\t} else {\n\t\treturn n, err\n\t}\n}\n\n// Write writes to a file handle.\nfunc (f *win32File) Write(b []byte) (int, error) {\n\tc, err := f.prepareIO()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer f.wg.Done()\n\n\tif f.writeDeadline.timedout.isSet() {\n\t\treturn 0, ErrTimeout\n\t}\n\n\tvar bytes uint32\n\terr = syscall.WriteFile(f.handle, b, &bytes, &c.o)\n\tn, err := f.asyncIO(c, &f.writeDeadline, bytes, err)\n\truntime.KeepAlive(b)\n\treturn n, err\n}\n\nfunc (f *win32File) SetReadDeadline(deadline time.Time) error {\n\treturn f.readDeadline.set(deadline)\n}\n\nfunc (f *win32File) SetWriteDeadline(deadline time.Time) error {\n\treturn f.writeDeadline.set(deadline)\n}\n\nfunc (f *win32File) Flush() error {\n\treturn syscall.FlushFileBuffers(f.handle)\n}\n\nfunc (f *win32File) Fd() uintptr {\n\treturn uintptr(f.handle)\n}\n\nfunc (d *deadlineHandler) set(deadline time.Time) error {\n\td.setLock.Lock()\n\tdefer d.setLock.Unlock()\n\n\tif d.timer != nil {\n\t\tif !d.timer.Stop() {\n\t\t\t<-d.channel\n\t\t}\n\t\td.timer = nil\n\t}\n\td.timedout.setFalse()\n\n\tselect {\n\tcase <-d.channel:\n\t\td.channelLock.Lock()\n\t\td.channel = make(chan struct{})\n\t\td.channelLock.Unlock()\n\tdefault:\n\t}\n\n\tif deadline.IsZero() {\n\t\treturn nil\n\t}\n\n\ttimeoutIO := func() {\n\t\td.timedout.setTrue()\n\t\tclose(d.channel)\n\t}\n\n\tnow := time.Now()\n\tduration := deadline.Sub(now)\n\tif deadline.After(now) {\n\t\t// Deadline is in the future, set a timer to wait\n\t\td.timer = time.AfterFunc(duration, timeoutIO)\n\t} else {\n\t\t// Deadline is in the past. Cancel all pending IO now.\n\t\ttimeoutIO()\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/fileinfo.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n// FileBasicInfo contains file access time and file attributes information.\ntype FileBasicInfo struct {\n\tCreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime\n\tFileAttributes                                          uint32\n\t_                                                       uint32 // padding\n}\n\n// GetFileBasicInfo retrieves times and attributes for a file.\nfunc GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {\n\tbi := &FileBasicInfo{}\n\tif err := windows.GetFileInformationByHandleEx(\n\t\twindows.Handle(f.Fd()),\n\t\twindows.FileBasicInfo,\n\t\t(*byte)(unsafe.Pointer(bi)),\n\t\tuint32(unsafe.Sizeof(*bi)),\n\t); err != nil {\n\t\treturn nil, &os.PathError{Op: \"GetFileInformationByHandleEx\", Path: f.Name(), Err: err}\n\t}\n\truntime.KeepAlive(f)\n\treturn bi, nil\n}\n\n// SetFileBasicInfo sets times and attributes for a file.\nfunc SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {\n\tif err := windows.SetFileInformationByHandle(\n\t\twindows.Handle(f.Fd()),\n\t\twindows.FileBasicInfo,\n\t\t(*byte)(unsafe.Pointer(bi)),\n\t\tuint32(unsafe.Sizeof(*bi)),\n\t); err != nil {\n\t\treturn &os.PathError{Op: \"SetFileInformationByHandle\", Path: f.Name(), Err: err}\n\t}\n\truntime.KeepAlive(f)\n\treturn nil\n}\n\n// FileStandardInfo contains extended information for the file.\n// FILE_STANDARD_INFO in WinBase.h\n// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info\ntype FileStandardInfo struct {\n\tAllocationSize, EndOfFile int64\n\tNumberOfLinks             uint32\n\tDeletePending, Directory  bool\n}\n\n// GetFileStandardInfo retrieves ended information for the file.\nfunc GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) {\n\tsi := &FileStandardInfo{}\n\tif err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()),\n\t\twindows.FileStandardInfo,\n\t\t(*byte)(unsafe.Pointer(si)),\n\t\tuint32(unsafe.Sizeof(*si))); err != nil {\n\t\treturn nil, &os.PathError{Op: \"GetFileInformationByHandleEx\", Path: f.Name(), Err: err}\n\t}\n\truntime.KeepAlive(f)\n\treturn si, nil\n}\n\n// FileIDInfo contains the volume serial number and file ID for a file. This pair should be\n// unique on a system.\ntype FileIDInfo struct {\n\tVolumeSerialNumber uint64\n\tFileID             [16]byte\n}\n\n// GetFileID retrieves the unique (volume, file ID) pair for a file.\nfunc GetFileID(f *os.File) (*FileIDInfo, error) {\n\tfileID := &FileIDInfo{}\n\tif err := windows.GetFileInformationByHandleEx(\n\t\twindows.Handle(f.Fd()),\n\t\twindows.FileIdInfo,\n\t\t(*byte)(unsafe.Pointer(fileID)),\n\t\tuint32(unsafe.Sizeof(*fileID)),\n\t); err != nil {\n\t\treturn nil, &os.PathError{Op: \"GetFileInformationByHandleEx\", Path: f.Name(), Err: err}\n\t}\n\truntime.KeepAlive(f)\n\treturn fileID, nil\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/hvsock.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n\n\t\"github.com/Microsoft/go-winio/internal/socket\"\n\t\"github.com/Microsoft/go-winio/pkg/guid\"\n)\n\nconst afHVSock = 34 // AF_HYPERV\n\n// Well known Service and VM IDs\n// https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service#vmid-wildcards\n\n// HvsockGUIDWildcard is the wildcard VmId for accepting connections from all partitions.\nfunc HvsockGUIDWildcard() guid.GUID { // 00000000-0000-0000-0000-000000000000\n\treturn guid.GUID{}\n}\n\n// HvsockGUIDBroadcast is the wildcard VmId for broadcasting sends to all partitions.\nfunc HvsockGUIDBroadcast() guid.GUID { // ffffffff-ffff-ffff-ffff-ffffffffffff\n\treturn guid.GUID{\n\t\tData1: 0xffffffff,\n\t\tData2: 0xffff,\n\t\tData3: 0xffff,\n\t\tData4: [8]uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t}\n}\n\n// HvsockGUIDLoopback is the Loopback VmId for accepting connections to the same partition as the connector.\nfunc HvsockGUIDLoopback() guid.GUID { // e0e16197-dd56-4a10-9195-5ee7a155a838\n\treturn guid.GUID{\n\t\tData1: 0xe0e16197,\n\t\tData2: 0xdd56,\n\t\tData3: 0x4a10,\n\t\tData4: [8]uint8{0x91, 0x95, 0x5e, 0xe7, 0xa1, 0x55, 0xa8, 0x38},\n\t}\n}\n\n// HvsockGUIDSiloHost is the address of a silo's host partition:\n//   - The silo host of a hosted silo is the utility VM.\n//   - The silo host of a silo on a physical host is the physical host.\nfunc HvsockGUIDSiloHost() guid.GUID { // 36bd0c5c-7276-4223-88ba-7d03b654c568\n\treturn guid.GUID{\n\t\tData1: 0x36bd0c5c,\n\t\tData2: 0x7276,\n\t\tData3: 0x4223,\n\t\tData4: [8]byte{0x88, 0xba, 0x7d, 0x03, 0xb6, 0x54, 0xc5, 0x68},\n\t}\n}\n\n// HvsockGUIDChildren is the wildcard VmId for accepting connections from the connector's child partitions.\nfunc HvsockGUIDChildren() guid.GUID { // 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd\n\treturn guid.GUID{\n\t\tData1: 0x90db8b89,\n\t\tData2: 0xd35,\n\t\tData3: 0x4f79,\n\t\tData4: [8]uint8{0x8c, 0xe9, 0x49, 0xea, 0xa, 0xc8, 0xb7, 0xcd},\n\t}\n}\n\n// HvsockGUIDParent is the wildcard VmId for accepting connections from the connector's parent partition.\n// Listening on this VmId accepts connection from:\n//   - Inside silos: silo host partition.\n//   - Inside hosted silo: host of the VM.\n//   - Inside VM: VM host.\n//   - Physical host: Not supported.\nfunc HvsockGUIDParent() guid.GUID { // a42e7cda-d03f-480c-9cc2-a4de20abb878\n\treturn guid.GUID{\n\t\tData1: 0xa42e7cda,\n\t\tData2: 0xd03f,\n\t\tData3: 0x480c,\n\t\tData4: [8]uint8{0x9c, 0xc2, 0xa4, 0xde, 0x20, 0xab, 0xb8, 0x78},\n\t}\n}\n\n// hvsockVsockServiceTemplate is the Service GUID used for the VSOCK protocol.\nfunc hvsockVsockServiceTemplate() guid.GUID { // 00000000-facb-11e6-bd58-64006a7986d3\n\treturn guid.GUID{\n\t\tData2: 0xfacb,\n\t\tData3: 0x11e6,\n\t\tData4: [8]uint8{0xbd, 0x58, 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3},\n\t}\n}\n\n// An HvsockAddr is an address for a AF_HYPERV socket.\ntype HvsockAddr struct {\n\tVMID      guid.GUID\n\tServiceID guid.GUID\n}\n\ntype rawHvsockAddr struct {\n\tFamily    uint16\n\t_         uint16\n\tVMID      guid.GUID\n\tServiceID guid.GUID\n}\n\nvar _ socket.RawSockaddr = &rawHvsockAddr{}\n\n// Network returns the address's network name, \"hvsock\".\nfunc (*HvsockAddr) Network() string {\n\treturn \"hvsock\"\n}\n\nfunc (addr *HvsockAddr) String() string {\n\treturn fmt.Sprintf(\"%s:%s\", &addr.VMID, &addr.ServiceID)\n}\n\n// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port.\nfunc VsockServiceID(port uint32) guid.GUID {\n\tg := hvsockVsockServiceTemplate() // make a copy\n\tg.Data1 = port\n\treturn g\n}\n\nfunc (addr *HvsockAddr) raw() rawHvsockAddr {\n\treturn rawHvsockAddr{\n\t\tFamily:    afHVSock,\n\t\tVMID:      addr.VMID,\n\t\tServiceID: addr.ServiceID,\n\t}\n}\n\nfunc (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) {\n\taddr.VMID = raw.VMID\n\taddr.ServiceID = raw.ServiceID\n}\n\n// Sockaddr returns a pointer to and the size of this struct.\n//\n// Implements the [socket.RawSockaddr] interface, and allows use in\n// [socket.Bind] and [socket.ConnectEx].\nfunc (r *rawHvsockAddr) Sockaddr() (unsafe.Pointer, int32, error) {\n\treturn unsafe.Pointer(r), int32(unsafe.Sizeof(rawHvsockAddr{})), nil\n}\n\n// Sockaddr interface allows use with `sockets.Bind()` and `.ConnectEx()`.\nfunc (r *rawHvsockAddr) FromBytes(b []byte) error {\n\tn := int(unsafe.Sizeof(rawHvsockAddr{}))\n\n\tif len(b) < n {\n\t\treturn fmt.Errorf(\"got %d, want %d: %w\", len(b), n, socket.ErrBufferSize)\n\t}\n\n\tcopy(unsafe.Slice((*byte)(unsafe.Pointer(r)), n), b[:n])\n\tif r.Family != afHVSock {\n\t\treturn fmt.Errorf(\"got %d, want %d: %w\", r.Family, afHVSock, socket.ErrAddrFamily)\n\t}\n\n\treturn nil\n}\n\n// HvsockListener is a socket listener for the AF_HYPERV address family.\ntype HvsockListener struct {\n\tsock *win32File\n\taddr HvsockAddr\n}\n\nvar _ net.Listener = &HvsockListener{}\n\n// HvsockConn is a connected socket of the AF_HYPERV address family.\ntype HvsockConn struct {\n\tsock          *win32File\n\tlocal, remote HvsockAddr\n}\n\nvar _ net.Conn = &HvsockConn{}\n\nfunc newHVSocket() (*win32File, error) {\n\tfd, err := syscall.Socket(afHVSock, syscall.SOCK_STREAM, 1)\n\tif err != nil {\n\t\treturn nil, os.NewSyscallError(\"socket\", err)\n\t}\n\tf, err := makeWin32File(fd)\n\tif err != nil {\n\t\tsyscall.Close(fd)\n\t\treturn nil, err\n\t}\n\tf.socket = true\n\treturn f, nil\n}\n\n// ListenHvsock listens for connections on the specified hvsock address.\nfunc ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {\n\tl := &HvsockListener{addr: *addr}\n\tsock, err := newHVSocket()\n\tif err != nil {\n\t\treturn nil, l.opErr(\"listen\", err)\n\t}\n\tsa := addr.raw()\n\terr = socket.Bind(windows.Handle(sock.handle), &sa)\n\tif err != nil {\n\t\treturn nil, l.opErr(\"listen\", os.NewSyscallError(\"socket\", err))\n\t}\n\terr = syscall.Listen(sock.handle, 16)\n\tif err != nil {\n\t\treturn nil, l.opErr(\"listen\", os.NewSyscallError(\"listen\", err))\n\t}\n\treturn &HvsockListener{sock: sock, addr: *addr}, nil\n}\n\nfunc (l *HvsockListener) opErr(op string, err error) error {\n\treturn &net.OpError{Op: op, Net: \"hvsock\", Addr: &l.addr, Err: err}\n}\n\n// Addr returns the listener's network address.\nfunc (l *HvsockListener) Addr() net.Addr {\n\treturn &l.addr\n}\n\n// Accept waits for the next connection and returns it.\nfunc (l *HvsockListener) Accept() (_ net.Conn, err error) {\n\tsock, err := newHVSocket()\n\tif err != nil {\n\t\treturn nil, l.opErr(\"accept\", err)\n\t}\n\tdefer func() {\n\t\tif sock != nil {\n\t\t\tsock.Close()\n\t\t}\n\t}()\n\tc, err := l.sock.prepareIO()\n\tif err != nil {\n\t\treturn nil, l.opErr(\"accept\", err)\n\t}\n\tdefer l.sock.wg.Done()\n\n\t// AcceptEx, per documentation, requires an extra 16 bytes per address.\n\t//\n\t// https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex\n\tconst addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{}))\n\tvar addrbuf [addrlen * 2]byte\n\n\tvar bytes uint32\n\terr = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o)\n\tif _, err = l.sock.asyncIO(c, nil, bytes, err); err != nil {\n\t\treturn nil, l.opErr(\"accept\", os.NewSyscallError(\"acceptex\", err))\n\t}\n\n\tconn := &HvsockConn{\n\t\tsock: sock,\n\t}\n\t// The local address returned in the AcceptEx buffer is the same as the Listener socket's\n\t// address. However, the service GUID reported by GetSockName is different from the Listeners\n\t// socket, and is sometimes the same as the local address of the socket that dialed the\n\t// address, with the service GUID.Data1 incremented, but othertimes is different.\n\t// todo: does the local address matter? is the listener's address or the actual address appropriate?\n\tconn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0])))\n\tconn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))\n\n\t// initialize the accepted socket and update its properties with those of the listening socket\n\tif err = windows.Setsockopt(windows.Handle(sock.handle),\n\t\twindows.SOL_SOCKET, windows.SO_UPDATE_ACCEPT_CONTEXT,\n\t\t(*byte)(unsafe.Pointer(&l.sock.handle)), int32(unsafe.Sizeof(l.sock.handle))); err != nil {\n\t\treturn nil, conn.opErr(\"accept\", os.NewSyscallError(\"setsockopt\", err))\n\t}\n\n\tsock = nil\n\treturn conn, nil\n}\n\n// Close closes the listener, causing any pending Accept calls to fail.\nfunc (l *HvsockListener) Close() error {\n\treturn l.sock.Close()\n}\n\n// HvsockDialer configures and dials a Hyper-V Socket (ie, [HvsockConn]).\ntype HvsockDialer struct {\n\t// Deadline is the time the Dial operation must connect before erroring.\n\tDeadline time.Time\n\n\t// Retries is the number of additional connects to try if the connection times out, is refused,\n\t// or the host is unreachable\n\tRetries uint\n\n\t// RetryWait is the time to wait after a connection error to retry\n\tRetryWait time.Duration\n\n\trt *time.Timer // redial wait timer\n}\n\n// Dial the Hyper-V socket at addr.\n//\n// See [HvsockDialer.Dial] for more information.\nfunc Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {\n\treturn (&HvsockDialer{}).Dial(ctx, addr)\n}\n\n// Dial attempts to connect to the Hyper-V socket at addr, and returns a connection if successful.\n// Will attempt (HvsockDialer).Retries if dialing fails, waiting (HvsockDialer).RetryWait between\n// retries.\n//\n// Dialing can be cancelled either by providing (HvsockDialer).Deadline, or cancelling ctx.\nfunc (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) {\n\top := \"dial\"\n\t// create the conn early to use opErr()\n\tconn = &HvsockConn{\n\t\tremote: *addr,\n\t}\n\n\tif !d.Deadline.IsZero() {\n\t\tvar cancel context.CancelFunc\n\t\tctx, cancel = context.WithDeadline(ctx, d.Deadline)\n\t\tdefer cancel()\n\t}\n\n\t// preemptive timeout/cancellation check\n\tif err = ctx.Err(); err != nil {\n\t\treturn nil, conn.opErr(op, err)\n\t}\n\n\tsock, err := newHVSocket()\n\tif err != nil {\n\t\treturn nil, conn.opErr(op, err)\n\t}\n\tdefer func() {\n\t\tif sock != nil {\n\t\t\tsock.Close()\n\t\t}\n\t}()\n\n\tsa := addr.raw()\n\terr = socket.Bind(windows.Handle(sock.handle), &sa)\n\tif err != nil {\n\t\treturn nil, conn.opErr(op, os.NewSyscallError(\"bind\", err))\n\t}\n\n\tc, err := sock.prepareIO()\n\tif err != nil {\n\t\treturn nil, conn.opErr(op, err)\n\t}\n\tdefer sock.wg.Done()\n\tvar bytes uint32\n\tfor i := uint(0); i <= d.Retries; i++ {\n\t\terr = socket.ConnectEx(\n\t\t\twindows.Handle(sock.handle),\n\t\t\t&sa,\n\t\t\tnil, // sendBuf\n\t\t\t0,   // sendDataLen\n\t\t\t&bytes,\n\t\t\t(*windows.Overlapped)(unsafe.Pointer(&c.o)))\n\t\t_, err = sock.asyncIO(c, nil, bytes, err)\n\t\tif i < d.Retries && canRedial(err) {\n\t\t\tif err = d.redialWait(ctx); err == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tbreak\n\t}\n\tif err != nil {\n\t\treturn nil, conn.opErr(op, os.NewSyscallError(\"connectex\", err))\n\t}\n\n\t// update the connection properties, so shutdown can be used\n\tif err = windows.Setsockopt(\n\t\twindows.Handle(sock.handle),\n\t\twindows.SOL_SOCKET,\n\t\twindows.SO_UPDATE_CONNECT_CONTEXT,\n\t\tnil, // optvalue\n\t\t0,   // optlen\n\t); err != nil {\n\t\treturn nil, conn.opErr(op, os.NewSyscallError(\"setsockopt\", err))\n\t}\n\n\t// get the local name\n\tvar sal rawHvsockAddr\n\terr = socket.GetSockName(windows.Handle(sock.handle), &sal)\n\tif err != nil {\n\t\treturn nil, conn.opErr(op, os.NewSyscallError(\"getsockname\", err))\n\t}\n\tconn.local.fromRaw(&sal)\n\n\t// one last check for timeout, since asyncIO doesn't check the context\n\tif err = ctx.Err(); err != nil {\n\t\treturn nil, conn.opErr(op, err)\n\t}\n\n\tconn.sock = sock\n\tsock = nil\n\n\treturn conn, nil\n}\n\n// redialWait waits before attempting to redial, resetting the timer as appropriate.\nfunc (d *HvsockDialer) redialWait(ctx context.Context) (err error) {\n\tif d.RetryWait == 0 {\n\t\treturn nil\n\t}\n\n\tif d.rt == nil {\n\t\td.rt = time.NewTimer(d.RetryWait)\n\t} else {\n\t\t// should already be stopped and drained\n\t\td.rt.Reset(d.RetryWait)\n\t}\n\n\tselect {\n\tcase <-ctx.Done():\n\tcase <-d.rt.C:\n\t\treturn nil\n\t}\n\n\t// stop and drain the timer\n\tif !d.rt.Stop() {\n\t\t<-d.rt.C\n\t}\n\treturn ctx.Err()\n}\n\n// assumes error is a plain, unwrapped syscall.Errno provided by direct syscall.\nfunc canRedial(err error) bool {\n\t//nolint:errorlint // guaranteed to be an Errno\n\tswitch err {\n\tcase windows.WSAECONNREFUSED, windows.WSAENETUNREACH, windows.WSAETIMEDOUT,\n\t\twindows.ERROR_CONNECTION_REFUSED, windows.ERROR_CONNECTION_UNAVAIL:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (conn *HvsockConn) opErr(op string, err error) error {\n\t// translate from \"file closed\" to \"socket closed\"\n\tif errors.Is(err, ErrFileClosed) {\n\t\terr = socket.ErrSocketClosed\n\t}\n\treturn &net.OpError{Op: op, Net: \"hvsock\", Source: &conn.local, Addr: &conn.remote, Err: err}\n}\n\nfunc (conn *HvsockConn) Read(b []byte) (int, error) {\n\tc, err := conn.sock.prepareIO()\n\tif err != nil {\n\t\treturn 0, conn.opErr(\"read\", err)\n\t}\n\tdefer conn.sock.wg.Done()\n\tbuf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}\n\tvar flags, bytes uint32\n\terr = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)\n\tn, err := conn.sock.asyncIO(c, &conn.sock.readDeadline, bytes, err)\n\tif err != nil {\n\t\tvar eno windows.Errno\n\t\tif errors.As(err, &eno) {\n\t\t\terr = os.NewSyscallError(\"wsarecv\", eno)\n\t\t}\n\t\treturn 0, conn.opErr(\"read\", err)\n\t} else if n == 0 {\n\t\terr = io.EOF\n\t}\n\treturn n, err\n}\n\nfunc (conn *HvsockConn) Write(b []byte) (int, error) {\n\tt := 0\n\tfor len(b) != 0 {\n\t\tn, err := conn.write(b)\n\t\tif err != nil {\n\t\t\treturn t + n, err\n\t\t}\n\t\tt += n\n\t\tb = b[n:]\n\t}\n\treturn t, nil\n}\n\nfunc (conn *HvsockConn) write(b []byte) (int, error) {\n\tc, err := conn.sock.prepareIO()\n\tif err != nil {\n\t\treturn 0, conn.opErr(\"write\", err)\n\t}\n\tdefer conn.sock.wg.Done()\n\tbuf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}\n\tvar bytes uint32\n\terr = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)\n\tn, err := conn.sock.asyncIO(c, &conn.sock.writeDeadline, bytes, err)\n\tif err != nil {\n\t\tvar eno windows.Errno\n\t\tif errors.As(err, &eno) {\n\t\t\terr = os.NewSyscallError(\"wsasend\", eno)\n\t\t}\n\t\treturn 0, conn.opErr(\"write\", err)\n\t}\n\treturn n, err\n}\n\n// Close closes the socket connection, failing any pending read or write calls.\nfunc (conn *HvsockConn) Close() error {\n\treturn conn.sock.Close()\n}\n\nfunc (conn *HvsockConn) IsClosed() bool {\n\treturn conn.sock.IsClosed()\n}\n\n// shutdown disables sending or receiving on a socket.\nfunc (conn *HvsockConn) shutdown(how int) error {\n\tif conn.IsClosed() {\n\t\treturn socket.ErrSocketClosed\n\t}\n\n\terr := syscall.Shutdown(conn.sock.handle, how)\n\tif err != nil {\n\t\t// If the connection was closed, shutdowns fail with \"not connected\"\n\t\tif errors.Is(err, windows.WSAENOTCONN) ||\n\t\t\terrors.Is(err, windows.WSAESHUTDOWN) {\n\t\t\terr = socket.ErrSocketClosed\n\t\t}\n\t\treturn os.NewSyscallError(\"shutdown\", err)\n\t}\n\treturn nil\n}\n\n// CloseRead shuts down the read end of the socket, preventing future read operations.\nfunc (conn *HvsockConn) CloseRead() error {\n\terr := conn.shutdown(syscall.SHUT_RD)\n\tif err != nil {\n\t\treturn conn.opErr(\"closeread\", err)\n\t}\n\treturn nil\n}\n\n// CloseWrite shuts down the write end of the socket, preventing future write operations and\n// notifying the other endpoint that no more data will be written.\nfunc (conn *HvsockConn) CloseWrite() error {\n\terr := conn.shutdown(syscall.SHUT_WR)\n\tif err != nil {\n\t\treturn conn.opErr(\"closewrite\", err)\n\t}\n\treturn nil\n}\n\n// LocalAddr returns the local address of the connection.\nfunc (conn *HvsockConn) LocalAddr() net.Addr {\n\treturn &conn.local\n}\n\n// RemoteAddr returns the remote address of the connection.\nfunc (conn *HvsockConn) RemoteAddr() net.Addr {\n\treturn &conn.remote\n}\n\n// SetDeadline implements the net.Conn SetDeadline method.\nfunc (conn *HvsockConn) SetDeadline(t time.Time) error {\n\t// todo: implement `SetDeadline` for `win32File`\n\tif err := conn.SetReadDeadline(t); err != nil {\n\t\treturn fmt.Errorf(\"set read deadline: %w\", err)\n\t}\n\tif err := conn.SetWriteDeadline(t); err != nil {\n\t\treturn fmt.Errorf(\"set write deadline: %w\", err)\n\t}\n\treturn nil\n}\n\n// SetReadDeadline implements the net.Conn SetReadDeadline method.\nfunc (conn *HvsockConn) SetReadDeadline(t time.Time) error {\n\treturn conn.sock.SetReadDeadline(t)\n}\n\n// SetWriteDeadline implements the net.Conn SetWriteDeadline method.\nfunc (conn *HvsockConn) SetWriteDeadline(t time.Time) error {\n\treturn conn.sock.SetWriteDeadline(t)\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/fs/doc.go",
    "content": "// This package contains Win32 filesystem functionality.\npackage fs\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/fs/fs.go",
    "content": "//go:build windows\n\npackage fs\n\nimport (\n\t\"golang.org/x/sys/windows\"\n\n\t\"github.com/Microsoft/go-winio/internal/stringbuffer\"\n)\n\n//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go\n\n// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew\n//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW\n\nconst NullHandle windows.Handle = 0\n\n// AccessMask defines standard, specific, and generic rights.\n//\n//\tBitmask:\n//\t 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1\n//\t 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0\n//\t+---------------+---------------+-------------------------------+\n//\t|G|G|G|G|Resvd|A| StandardRights|         SpecificRights        |\n//\t|R|W|E|A|     |S|               |                               |\n//\t+-+-------------+---------------+-------------------------------+\n//\n//\tGR     Generic Read\n//\tGW     Generic Write\n//\tGE     Generic Exectue\n//\tGA     Generic All\n//\tResvd  Reserved\n//\tAS     Access Security System\n//\n// https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask\n//\n// https://learn.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights\n//\n// https://learn.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants\ntype AccessMask = windows.ACCESS_MASK\n\n//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.\nconst (\n\t// Not actually any.\n\t//\n\t// For CreateFile: \"query certain metadata such as file, directory, or device attributes without accessing that file or device\"\n\t// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters\n\tFILE_ANY_ACCESS AccessMask = 0\n\n\t// Specific Object Access\n\t// from ntioapi.h\n\n\tFILE_READ_DATA      AccessMask = (0x0001) // file & pipe\n\tFILE_LIST_DIRECTORY AccessMask = (0x0001) // directory\n\n\tFILE_WRITE_DATA AccessMask = (0x0002) // file & pipe\n\tFILE_ADD_FILE   AccessMask = (0x0002) // directory\n\n\tFILE_APPEND_DATA          AccessMask = (0x0004) // file\n\tFILE_ADD_SUBDIRECTORY     AccessMask = (0x0004) // directory\n\tFILE_CREATE_PIPE_INSTANCE AccessMask = (0x0004) // named pipe\n\n\tFILE_READ_EA         AccessMask = (0x0008) // file & directory\n\tFILE_READ_PROPERTIES AccessMask = FILE_READ_EA\n\n\tFILE_WRITE_EA         AccessMask = (0x0010) // file & directory\n\tFILE_WRITE_PROPERTIES AccessMask = FILE_WRITE_EA\n\n\tFILE_EXECUTE  AccessMask = (0x0020) // file\n\tFILE_TRAVERSE AccessMask = (0x0020) // directory\n\n\tFILE_DELETE_CHILD AccessMask = (0x0040) // directory\n\n\tFILE_READ_ATTRIBUTES AccessMask = (0x0080) // all\n\n\tFILE_WRITE_ATTRIBUTES AccessMask = (0x0100) // all\n\n\tFILE_ALL_ACCESS      AccessMask = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)\n\tFILE_GENERIC_READ    AccessMask = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)\n\tFILE_GENERIC_WRITE   AccessMask = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)\n\tFILE_GENERIC_EXECUTE AccessMask = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)\n\n\tSPECIFIC_RIGHTS_ALL AccessMask = 0x0000FFFF\n\n\t// Standard Access\n\t// from ntseapi.h\n\n\tDELETE       AccessMask = 0x0001_0000\n\tREAD_CONTROL AccessMask = 0x0002_0000\n\tWRITE_DAC    AccessMask = 0x0004_0000\n\tWRITE_OWNER  AccessMask = 0x0008_0000\n\tSYNCHRONIZE  AccessMask = 0x0010_0000\n\n\tSTANDARD_RIGHTS_REQUIRED AccessMask = 0x000F_0000\n\n\tSTANDARD_RIGHTS_READ    AccessMask = READ_CONTROL\n\tSTANDARD_RIGHTS_WRITE   AccessMask = READ_CONTROL\n\tSTANDARD_RIGHTS_EXECUTE AccessMask = READ_CONTROL\n\n\tSTANDARD_RIGHTS_ALL AccessMask = 0x001F_0000\n)\n\ntype FileShareMode uint32\n\n//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.\nconst (\n\tFILE_SHARE_NONE        FileShareMode = 0x00\n\tFILE_SHARE_READ        FileShareMode = 0x01\n\tFILE_SHARE_WRITE       FileShareMode = 0x02\n\tFILE_SHARE_DELETE      FileShareMode = 0x04\n\tFILE_SHARE_VALID_FLAGS FileShareMode = 0x07\n)\n\ntype FileCreationDisposition uint32\n\n//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.\nconst (\n\t// from winbase.h\n\n\tCREATE_NEW        FileCreationDisposition = 0x01\n\tCREATE_ALWAYS     FileCreationDisposition = 0x02\n\tOPEN_EXISTING     FileCreationDisposition = 0x03\n\tOPEN_ALWAYS       FileCreationDisposition = 0x04\n\tTRUNCATE_EXISTING FileCreationDisposition = 0x05\n)\n\n// CreateFile and co. take flags or attributes together as one parameter.\n// Define alias until we can use generics to allow both\n\n// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants\ntype FileFlagOrAttribute uint32\n\n//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.\nconst ( // from winnt.h\n\tFILE_FLAG_WRITE_THROUGH       FileFlagOrAttribute = 0x8000_0000\n\tFILE_FLAG_OVERLAPPED          FileFlagOrAttribute = 0x4000_0000\n\tFILE_FLAG_NO_BUFFERING        FileFlagOrAttribute = 0x2000_0000\n\tFILE_FLAG_RANDOM_ACCESS       FileFlagOrAttribute = 0x1000_0000\n\tFILE_FLAG_SEQUENTIAL_SCAN     FileFlagOrAttribute = 0x0800_0000\n\tFILE_FLAG_DELETE_ON_CLOSE     FileFlagOrAttribute = 0x0400_0000\n\tFILE_FLAG_BACKUP_SEMANTICS    FileFlagOrAttribute = 0x0200_0000\n\tFILE_FLAG_POSIX_SEMANTICS     FileFlagOrAttribute = 0x0100_0000\n\tFILE_FLAG_OPEN_REPARSE_POINT  FileFlagOrAttribute = 0x0020_0000\n\tFILE_FLAG_OPEN_NO_RECALL      FileFlagOrAttribute = 0x0010_0000\n\tFILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000\n)\n\ntype FileSQSFlag = FileFlagOrAttribute\n\n//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.\nconst ( // from winbase.h\n\tSECURITY_ANONYMOUS      FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16)\n\tSECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16)\n\tSECURITY_IMPERSONATION  FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16)\n\tSECURITY_DELEGATION     FileSQSFlag = FileSQSFlag(SecurityDelegation << 16)\n\n\tSECURITY_SQOS_PRESENT     FileSQSFlag = 0x00100000\n\tSECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F0000\n)\n\n// GetFinalPathNameByHandle flags\n//\n// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew#parameters\ntype GetFinalPathFlag uint32\n\n//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.\nconst (\n\tGetFinalPathDefaultFlag GetFinalPathFlag = 0x0\n\n\tFILE_NAME_NORMALIZED GetFinalPathFlag = 0x0\n\tFILE_NAME_OPENED     GetFinalPathFlag = 0x8\n\n\tVOLUME_NAME_DOS  GetFinalPathFlag = 0x0\n\tVOLUME_NAME_GUID GetFinalPathFlag = 0x1\n\tVOLUME_NAME_NT   GetFinalPathFlag = 0x2\n\tVOLUME_NAME_NONE GetFinalPathFlag = 0x4\n)\n\n// getFinalPathNameByHandle facilitates calling the Windows API GetFinalPathNameByHandle\n// with the given handle and flags. It transparently takes care of creating a buffer of the\n// correct size for the call.\n//\n// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew\nfunc GetFinalPathNameByHandle(h windows.Handle, flags GetFinalPathFlag) (string, error) {\n\tb := stringbuffer.NewWString()\n\t//TODO: can loop infinitely if Win32 keeps returning the same (or a larger) n?\n\tfor {\n\t\tn, err := windows.GetFinalPathNameByHandle(h, b.Pointer(), b.Cap(), uint32(flags))\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\t// If the buffer wasn't large enough, n will be the total size needed (including null terminator).\n\t\t// Resize and try again.\n\t\tif n > b.Cap() {\n\t\t\tb.ResizeTo(n)\n\t\t\tcontinue\n\t\t}\n\t\t// If the buffer is large enough, n will be the size not including the null terminator.\n\t\t// Convert to a Go string and return.\n\t\treturn b.String(), nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/fs/security.go",
    "content": "package fs\n\n// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level\ntype SecurityImpersonationLevel int32 // C default enums underlying type is `int`, which is Go `int32`\n\n// Impersonation levels\nconst (\n\tSecurityAnonymous      SecurityImpersonationLevel = 0\n\tSecurityIdentification SecurityImpersonationLevel = 1\n\tSecurityImpersonation  SecurityImpersonationLevel = 2\n\tSecurityDelegation     SecurityImpersonationLevel = 3\n)\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go",
    "content": "//go:build windows\n\n// Code generated by 'go generate' using \"github.com/Microsoft/go-winio/tools/mkwinsyscall\"; DO NOT EDIT.\n\npackage fs\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nvar _ unsafe.Pointer\n\n// Do the interface allocations only once for common\n// Errno values.\nconst (\n\terrnoERROR_IO_PENDING = 997\n)\n\nvar (\n\terrERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)\n\terrERROR_EINVAL     error = syscall.EINVAL\n)\n\n// errnoErr returns common boxed Errno values, to prevent\n// allocations at runtime.\nfunc errnoErr(e syscall.Errno) error {\n\tswitch e {\n\tcase 0:\n\t\treturn errERROR_EINVAL\n\tcase errnoERROR_IO_PENDING:\n\t\treturn errERROR_IO_PENDING\n\t}\n\t// TODO: add more here, after collecting data on the common\n\t// error values see on Windows. (perhaps when running\n\t// all.bat?)\n\treturn e\n}\n\nvar (\n\tmodkernel32 = windows.NewLazySystemDLL(\"kernel32.dll\")\n\n\tprocCreateFileW = modkernel32.NewProc(\"CreateFileW\")\n)\n\nfunc CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {\n\tvar _p0 *uint16\n\t_p0, err = syscall.UTF16PtrFromString(name)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn _CreateFile(_p0, access, mode, sa, createmode, attrs, templatefile)\n}\n\nfunc _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {\n\tr0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)\n\thandle = windows.Handle(r0)\n\tif handle == windows.InvalidHandle {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go",
    "content": "package socket\n\nimport (\n\t\"unsafe\"\n)\n\n// RawSockaddr allows structs to be used with [Bind] and [ConnectEx]. The\n// struct must meet the Win32 sockaddr requirements specified here:\n// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2\n//\n// Specifically, the struct size must be least larger than an int16 (unsigned short)\n// for the address family.\ntype RawSockaddr interface {\n\t// Sockaddr returns a pointer to the RawSockaddr and its struct size, allowing\n\t// for the RawSockaddr's data to be overwritten by syscalls (if necessary).\n\t//\n\t// It is the callers responsibility to validate that the values are valid; invalid\n\t// pointers or size can cause a panic.\n\tSockaddr() (unsafe.Pointer, int32, error)\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/socket/socket.go",
    "content": "//go:build windows\n\npackage socket\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/Microsoft/go-winio/pkg/guid\"\n\t\"golang.org/x/sys/windows\"\n)\n\n//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go socket.go\n\n//sys getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getsockname\n//sys getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getpeername\n//sys bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind\n\nconst socketError = uintptr(^uint32(0))\n\nvar (\n\t// todo(helsaawy): create custom error types to store the desired vs actual size and addr family?\n\n\tErrBufferSize     = errors.New(\"buffer size\")\n\tErrAddrFamily     = errors.New(\"address family\")\n\tErrInvalidPointer = errors.New(\"invalid pointer\")\n\tErrSocketClosed   = fmt.Errorf(\"socket closed: %w\", net.ErrClosed)\n)\n\n// todo(helsaawy): replace these with generics, ie: GetSockName[S RawSockaddr](s windows.Handle) (S, error)\n\n// GetSockName writes the local address of socket s to the [RawSockaddr] rsa.\n// If rsa is not large enough, the [windows.WSAEFAULT] is returned.\nfunc GetSockName(s windows.Handle, rsa RawSockaddr) error {\n\tptr, l, err := rsa.Sockaddr()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not retrieve socket pointer and size: %w\", err)\n\t}\n\n\t// although getsockname returns WSAEFAULT if the buffer is too small, it does not set\n\t// &l to the correct size, so--apart from doubling the buffer repeatedly--there is no remedy\n\treturn getsockname(s, ptr, &l)\n}\n\n// GetPeerName returns the remote address the socket is connected to.\n//\n// See [GetSockName] for more information.\nfunc GetPeerName(s windows.Handle, rsa RawSockaddr) error {\n\tptr, l, err := rsa.Sockaddr()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not retrieve socket pointer and size: %w\", err)\n\t}\n\n\treturn getpeername(s, ptr, &l)\n}\n\nfunc Bind(s windows.Handle, rsa RawSockaddr) (err error) {\n\tptr, l, err := rsa.Sockaddr()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"could not retrieve socket pointer and size: %w\", err)\n\t}\n\n\treturn bind(s, ptr, l)\n}\n\n// \"golang.org/x/sys/windows\".ConnectEx and .Bind only accept internal implementations of the\n// their sockaddr interface, so they cannot be used with HvsockAddr\n// Replicate functionality here from\n// https://cs.opensource.google/go/x/sys/+/master:windows/syscall_windows.go\n\n// The function pointers to `AcceptEx`, `ConnectEx` and `GetAcceptExSockaddrs` must be loaded at\n// runtime via a WSAIoctl call:\n// https://docs.microsoft.com/en-us/windows/win32/api/Mswsock/nc-mswsock-lpfn_connectex#remarks\n\ntype runtimeFunc struct {\n\tid   guid.GUID\n\tonce sync.Once\n\taddr uintptr\n\terr  error\n}\n\nfunc (f *runtimeFunc) Load() error {\n\tf.once.Do(func() {\n\t\tvar s windows.Handle\n\t\ts, f.err = windows.Socket(windows.AF_INET, windows.SOCK_STREAM, windows.IPPROTO_TCP)\n\t\tif f.err != nil {\n\t\t\treturn\n\t\t}\n\t\tdefer windows.CloseHandle(s) //nolint:errcheck\n\n\t\tvar n uint32\n\t\tf.err = windows.WSAIoctl(s,\n\t\t\twindows.SIO_GET_EXTENSION_FUNCTION_POINTER,\n\t\t\t(*byte)(unsafe.Pointer(&f.id)),\n\t\t\tuint32(unsafe.Sizeof(f.id)),\n\t\t\t(*byte)(unsafe.Pointer(&f.addr)),\n\t\t\tuint32(unsafe.Sizeof(f.addr)),\n\t\t\t&n,\n\t\t\tnil, // overlapped\n\t\t\t0,   // completionRoutine\n\t\t)\n\t})\n\treturn f.err\n}\n\nvar (\n\t// todo: add `AcceptEx` and `GetAcceptExSockaddrs`\n\tWSAID_CONNECTEX = guid.GUID{ //revive:disable-line:var-naming ALL_CAPS\n\t\tData1: 0x25a207b9,\n\t\tData2: 0xddf3,\n\t\tData3: 0x4660,\n\t\tData4: [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},\n\t}\n\n\tconnectExFunc = runtimeFunc{id: WSAID_CONNECTEX}\n)\n\nfunc ConnectEx(\n\tfd windows.Handle,\n\trsa RawSockaddr,\n\tsendBuf *byte,\n\tsendDataLen uint32,\n\tbytesSent *uint32,\n\toverlapped *windows.Overlapped,\n) error {\n\tif err := connectExFunc.Load(); err != nil {\n\t\treturn fmt.Errorf(\"failed to load ConnectEx function pointer: %w\", err)\n\t}\n\tptr, n, err := rsa.Sockaddr()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)\n}\n\n// BOOL LpfnConnectex(\n//   [in]           SOCKET s,\n//   [in]           const sockaddr *name,\n//   [in]           int namelen,\n//   [in, optional] PVOID lpSendBuffer,\n//   [in]           DWORD dwSendDataLength,\n//   [out]          LPDWORD lpdwBytesSent,\n//   [in]           LPOVERLAPPED lpOverlapped\n// )\n\nfunc connectEx(\n\ts windows.Handle,\n\tname unsafe.Pointer,\n\tnamelen int32,\n\tsendBuf *byte,\n\tsendDataLen uint32,\n\tbytesSent *uint32,\n\toverlapped *windows.Overlapped,\n) (err error) {\n\t// todo: after upgrading to 1.18, switch from syscall.Syscall9 to syscall.SyscallN\n\tr1, _, e1 := syscall.Syscall9(connectExFunc.addr,\n\t\t7,\n\t\tuintptr(s),\n\t\tuintptr(name),\n\t\tuintptr(namelen),\n\t\tuintptr(unsafe.Pointer(sendBuf)),\n\t\tuintptr(sendDataLen),\n\t\tuintptr(unsafe.Pointer(bytesSent)),\n\t\tuintptr(unsafe.Pointer(overlapped)),\n\t\t0,\n\t\t0)\n\tif r1 == 0 {\n\t\tif e1 != 0 {\n\t\t\terr = error(e1)\n\t\t} else {\n\t\t\terr = syscall.EINVAL\n\t\t}\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go",
    "content": "//go:build windows\n\n// Code generated by 'go generate' using \"github.com/Microsoft/go-winio/tools/mkwinsyscall\"; DO NOT EDIT.\n\npackage socket\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nvar _ unsafe.Pointer\n\n// Do the interface allocations only once for common\n// Errno values.\nconst (\n\terrnoERROR_IO_PENDING = 997\n)\n\nvar (\n\terrERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)\n\terrERROR_EINVAL     error = syscall.EINVAL\n)\n\n// errnoErr returns common boxed Errno values, to prevent\n// allocations at runtime.\nfunc errnoErr(e syscall.Errno) error {\n\tswitch e {\n\tcase 0:\n\t\treturn errERROR_EINVAL\n\tcase errnoERROR_IO_PENDING:\n\t\treturn errERROR_IO_PENDING\n\t}\n\t// TODO: add more here, after collecting data on the common\n\t// error values see on Windows. (perhaps when running\n\t// all.bat?)\n\treturn e\n}\n\nvar (\n\tmodws2_32 = windows.NewLazySystemDLL(\"ws2_32.dll\")\n\n\tprocbind        = modws2_32.NewProc(\"bind\")\n\tprocgetpeername = modws2_32.NewProc(\"getpeername\")\n\tprocgetsockname = modws2_32.NewProc(\"getsockname\")\n)\n\nfunc bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) {\n\tr1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))\n\tif r1 == socketError {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {\n\tr1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))\n\tif r1 == socketError {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {\n\tr1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))\n\tif r1 == socketError {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go",
    "content": "package stringbuffer\n\nimport (\n\t\"sync\"\n\t\"unicode/utf16\"\n)\n\n// TODO: worth exporting and using in mkwinsyscall?\n\n// Uint16BufferSize is the buffer size in the pool, chosen somewhat arbitrarily to accommodate\n// large path strings:\n// MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310.\nconst MinWStringCap = 310\n\n// use *[]uint16 since []uint16 creates an extra allocation where the slice header\n// is copied to heap and then referenced via pointer in the interface header that sync.Pool\n// stores.\nvar pathPool = sync.Pool{ // if go1.18+ adds Pool[T], use that to store []uint16 directly\n\tNew: func() interface{} {\n\t\tb := make([]uint16, MinWStringCap)\n\t\treturn &b\n\t},\n}\n\nfunc newBuffer() []uint16 { return *(pathPool.Get().(*[]uint16)) }\n\n// freeBuffer copies the slice header data, and puts a pointer to that in the pool.\n// This avoids taking a pointer to the slice header in WString, which can be set to nil.\nfunc freeBuffer(b []uint16) { pathPool.Put(&b) }\n\n// WString is a wide string buffer ([]uint16) meant for storing UTF-16 encoded strings\n// for interacting with Win32 APIs.\n// Sizes are specified as uint32 and not int.\n//\n// It is not thread safe.\ntype WString struct {\n\t// type-def allows casting to []uint16 directly, use struct to prevent that and allow adding fields in the future.\n\n\t// raw buffer\n\tb []uint16\n}\n\n// NewWString returns a [WString] allocated from a shared pool with an\n// initial capacity of at least [MinWStringCap].\n// Since the buffer may have been previously used, its contents are not guaranteed to be empty.\n//\n// The buffer should be freed via [WString.Free]\nfunc NewWString() *WString {\n\treturn &WString{\n\t\tb: newBuffer(),\n\t}\n}\n\nfunc (b *WString) Free() {\n\tif b.empty() {\n\t\treturn\n\t}\n\tfreeBuffer(b.b)\n\tb.b = nil\n}\n\n// ResizeTo grows the buffer to at least c and returns the new capacity, freeing the\n// previous buffer back into pool.\nfunc (b *WString) ResizeTo(c uint32) uint32 {\n\t// allready sufficient (or n is 0)\n\tif c <= b.Cap() {\n\t\treturn b.Cap()\n\t}\n\n\tif c <= MinWStringCap {\n\t\tc = MinWStringCap\n\t}\n\t// allocate at-least double buffer size, as is done in [bytes.Buffer] and other places\n\tif c <= 2*b.Cap() {\n\t\tc = 2 * b.Cap()\n\t}\n\n\tb2 := make([]uint16, c)\n\tif !b.empty() {\n\t\tcopy(b2, b.b)\n\t\tfreeBuffer(b.b)\n\t}\n\tb.b = b2\n\treturn c\n}\n\n// Buffer returns the underlying []uint16 buffer.\nfunc (b *WString) Buffer() []uint16 {\n\tif b.empty() {\n\t\treturn nil\n\t}\n\treturn b.b\n}\n\n// Pointer returns a pointer to the first uint16 in the buffer.\n// If the [WString.Free] has already been called, the pointer will be nil.\nfunc (b *WString) Pointer() *uint16 {\n\tif b.empty() {\n\t\treturn nil\n\t}\n\treturn &b.b[0]\n}\n\n// String returns the returns the UTF-8 encoding of the UTF-16 string in the buffer.\n//\n// It assumes that the data is null-terminated.\nfunc (b *WString) String() string {\n\t// Using [windows.UTF16ToString] would require importing \"golang.org/x/sys/windows\"\n\t// and would make this code Windows-only, which makes no sense.\n\t// So copy UTF16ToString code into here.\n\t// If other windows-specific code is added, switch to [windows.UTF16ToString]\n\n\ts := b.b\n\tfor i, v := range s {\n\t\tif v == 0 {\n\t\t\ts = s[:i]\n\t\t\tbreak\n\t\t}\n\t}\n\treturn string(utf16.Decode(s))\n}\n\n// Cap returns the underlying buffer capacity.\nfunc (b *WString) Cap() uint32 {\n\tif b.empty() {\n\t\treturn 0\n\t}\n\treturn b.cap()\n}\n\nfunc (b *WString) cap() uint32 { return uint32(cap(b.b)) }\nfunc (b *WString) empty() bool { return b == nil || b.cap() == 0 }\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/pipe.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"os\"\n\t\"runtime\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n\n\t\"github.com/Microsoft/go-winio/internal/fs\"\n)\n\n//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe\n//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error)  [failretval==syscall.InvalidHandle] = CreateNamedPipeW\n//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo\n//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW\n//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc\n//sys ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile\n//sys rtlNtStatusToDosError(status ntStatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb\n//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) = ntdll.RtlDosPathNameToNtPathName_U\n//sys rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) = ntdll.RtlDefaultNpAcl\n\ntype ioStatusBlock struct {\n\tStatus, Information uintptr\n}\n\ntype objectAttributes struct {\n\tLength             uintptr\n\tRootDirectory      uintptr\n\tObjectName         *unicodeString\n\tAttributes         uintptr\n\tSecurityDescriptor *securityDescriptor\n\tSecurityQoS        uintptr\n}\n\ntype unicodeString struct {\n\tLength        uint16\n\tMaximumLength uint16\n\tBuffer        uintptr\n}\n\ntype securityDescriptor struct {\n\tRevision byte\n\tSbz1     byte\n\tControl  uint16\n\tOwner    uintptr\n\tGroup    uintptr\n\tSacl     uintptr //revive:disable-line:var-naming SACL, not Sacl\n\tDacl     uintptr //revive:disable-line:var-naming DACL, not Dacl\n}\n\ntype ntStatus int32\n\nfunc (status ntStatus) Err() error {\n\tif status >= 0 {\n\t\treturn nil\n\t}\n\treturn rtlNtStatusToDosError(status)\n}\n\nvar (\n\t// ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed.\n\tErrPipeListenerClosed = net.ErrClosed\n\n\terrPipeWriteClosed = errors.New(\"pipe has been closed for write\")\n)\n\ntype win32Pipe struct {\n\t*win32File\n\tpath string\n}\n\ntype win32MessageBytePipe struct {\n\twin32Pipe\n\twriteClosed bool\n\treadEOF     bool\n}\n\ntype pipeAddress string\n\nfunc (f *win32Pipe) LocalAddr() net.Addr {\n\treturn pipeAddress(f.path)\n}\n\nfunc (f *win32Pipe) RemoteAddr() net.Addr {\n\treturn pipeAddress(f.path)\n}\n\nfunc (f *win32Pipe) SetDeadline(t time.Time) error {\n\tif err := f.SetReadDeadline(t); err != nil {\n\t\treturn err\n\t}\n\treturn f.SetWriteDeadline(t)\n}\n\n// CloseWrite closes the write side of a message pipe in byte mode.\nfunc (f *win32MessageBytePipe) CloseWrite() error {\n\tif f.writeClosed {\n\t\treturn errPipeWriteClosed\n\t}\n\terr := f.win32File.Flush()\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = f.win32File.Write(nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tf.writeClosed = true\n\treturn nil\n}\n\n// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since\n// they are used to implement CloseWrite().\nfunc (f *win32MessageBytePipe) Write(b []byte) (int, error) {\n\tif f.writeClosed {\n\t\treturn 0, errPipeWriteClosed\n\t}\n\tif len(b) == 0 {\n\t\treturn 0, nil\n\t}\n\treturn f.win32File.Write(b)\n}\n\n// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message\n// mode pipe will return io.EOF, as will all subsequent reads.\nfunc (f *win32MessageBytePipe) Read(b []byte) (int, error) {\n\tif f.readEOF {\n\t\treturn 0, io.EOF\n\t}\n\tn, err := f.win32File.Read(b)\n\tif err == io.EOF { //nolint:errorlint\n\t\t// If this was the result of a zero-byte read, then\n\t\t// it is possible that the read was due to a zero-size\n\t\t// message. Since we are simulating CloseWrite with a\n\t\t// zero-byte message, ensure that all future Read() calls\n\t\t// also return EOF.\n\t\tf.readEOF = true\n\t} else if err == syscall.ERROR_MORE_DATA { //nolint:errorlint // err is Errno\n\t\t// ERROR_MORE_DATA indicates that the pipe's read mode is message mode\n\t\t// and the message still has more bytes. Treat this as a success, since\n\t\t// this package presents all named pipes as byte streams.\n\t\terr = nil\n\t}\n\treturn n, err\n}\n\nfunc (pipeAddress) Network() string {\n\treturn \"pipe\"\n}\n\nfunc (s pipeAddress) String() string {\n\treturn string(s)\n}\n\n// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.\nfunc tryDialPipe(ctx context.Context, path *string, access fs.AccessMask) (syscall.Handle, error) {\n\tfor {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn syscall.Handle(0), ctx.Err()\n\t\tdefault:\n\t\t\twh, err := fs.CreateFile(*path,\n\t\t\t\taccess,\n\t\t\t\t0,   // mode\n\t\t\t\tnil, // security attributes\n\t\t\t\tfs.OPEN_EXISTING,\n\t\t\t\tfs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.SECURITY_ANONYMOUS,\n\t\t\t\t0, // template file handle\n\t\t\t)\n\t\t\th := syscall.Handle(wh)\n\t\t\tif err == nil {\n\t\t\t\treturn h, nil\n\t\t\t}\n\t\t\tif err != windows.ERROR_PIPE_BUSY { //nolint:errorlint // err is Errno\n\t\t\t\treturn h, &os.PathError{Err: err, Op: \"open\", Path: *path}\n\t\t\t}\n\t\t\t// Wait 10 msec and try again. This is a rather simplistic\n\t\t\t// view, as we always try each 10 milliseconds.\n\t\t\ttime.Sleep(10 * time.Millisecond)\n\t\t}\n\t}\n}\n\n// DialPipe connects to a named pipe by path, timing out if the connection\n// takes longer than the specified duration. If timeout is nil, then we use\n// a default timeout of 2 seconds.  (We do not use WaitNamedPipe.)\nfunc DialPipe(path string, timeout *time.Duration) (net.Conn, error) {\n\tvar absTimeout time.Time\n\tif timeout != nil {\n\t\tabsTimeout = time.Now().Add(*timeout)\n\t} else {\n\t\tabsTimeout = time.Now().Add(2 * time.Second)\n\t}\n\tctx, cancel := context.WithDeadline(context.Background(), absTimeout)\n\tdefer cancel()\n\tconn, err := DialPipeContext(ctx, path)\n\tif errors.Is(err, context.DeadlineExceeded) {\n\t\treturn nil, ErrTimeout\n\t}\n\treturn conn, err\n}\n\n// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`\n// cancellation or timeout.\nfunc DialPipeContext(ctx context.Context, path string) (net.Conn, error) {\n\treturn DialPipeAccess(ctx, path, syscall.GENERIC_READ|syscall.GENERIC_WRITE)\n}\n\n// DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx`\n// cancellation or timeout.\nfunc DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, error) {\n\tvar err error\n\tvar h syscall.Handle\n\th, err = tryDialPipe(ctx, &path, fs.AccessMask(access))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar flags uint32\n\terr = getNamedPipeInfo(h, &flags, nil, nil, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tf, err := makeWin32File(h)\n\tif err != nil {\n\t\tsyscall.Close(h)\n\t\treturn nil, err\n\t}\n\n\t// If the pipe is in message mode, return a message byte pipe, which\n\t// supports CloseWrite().\n\tif flags&windows.PIPE_TYPE_MESSAGE != 0 {\n\t\treturn &win32MessageBytePipe{\n\t\t\twin32Pipe: win32Pipe{win32File: f, path: path},\n\t\t}, nil\n\t}\n\treturn &win32Pipe{win32File: f, path: path}, nil\n}\n\ntype acceptResponse struct {\n\tf   *win32File\n\terr error\n}\n\ntype win32PipeListener struct {\n\tfirstHandle syscall.Handle\n\tpath        string\n\tconfig      PipeConfig\n\tacceptCh    chan (chan acceptResponse)\n\tcloseCh     chan int\n\tdoneCh      chan int\n}\n\nfunc makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {\n\tpath16, err := syscall.UTF16FromString(path)\n\tif err != nil {\n\t\treturn 0, &os.PathError{Op: \"open\", Path: path, Err: err}\n\t}\n\n\tvar oa objectAttributes\n\toa.Length = unsafe.Sizeof(oa)\n\n\tvar ntPath unicodeString\n\tif err := rtlDosPathNameToNtPathName(&path16[0],\n\t\t&ntPath,\n\t\t0,\n\t\t0,\n\t).Err(); err != nil {\n\t\treturn 0, &os.PathError{Op: \"open\", Path: path, Err: err}\n\t}\n\tdefer localFree(ntPath.Buffer)\n\toa.ObjectName = &ntPath\n\toa.Attributes = windows.OBJ_CASE_INSENSITIVE\n\n\t// The security descriptor is only needed for the first pipe.\n\tif first {\n\t\tif sd != nil {\n\t\t\tl := uint32(len(sd))\n\t\t\tsdb := localAlloc(0, l)\n\t\t\tdefer localFree(sdb)\n\t\t\tcopy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)\n\t\t\toa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))\n\t\t} else {\n\t\t\t// Construct the default named pipe security descriptor.\n\t\t\tvar dacl uintptr\n\t\t\tif err := rtlDefaultNpAcl(&dacl).Err(); err != nil {\n\t\t\t\treturn 0, fmt.Errorf(\"getting default named pipe ACL: %w\", err)\n\t\t\t}\n\t\t\tdefer localFree(dacl)\n\n\t\t\tsdb := &securityDescriptor{\n\t\t\t\tRevision: 1,\n\t\t\t\tControl:  windows.SE_DACL_PRESENT,\n\t\t\t\tDacl:     dacl,\n\t\t\t}\n\t\t\toa.SecurityDescriptor = sdb\n\t\t}\n\t}\n\n\ttyp := uint32(windows.FILE_PIPE_REJECT_REMOTE_CLIENTS)\n\tif c.MessageMode {\n\t\ttyp |= windows.FILE_PIPE_MESSAGE_TYPE\n\t}\n\n\tdisposition := uint32(windows.FILE_OPEN)\n\taccess := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE)\n\tif first {\n\t\tdisposition = windows.FILE_CREATE\n\t\t// By not asking for read or write access, the named pipe file system\n\t\t// will put this pipe into an initially disconnected state, blocking\n\t\t// client connections until the next call with first == false.\n\t\taccess = syscall.SYNCHRONIZE\n\t}\n\n\ttimeout := int64(-50 * 10000) // 50ms\n\n\tvar (\n\t\th    syscall.Handle\n\t\tiosb ioStatusBlock\n\t)\n\terr = ntCreateNamedPipeFile(&h,\n\t\taccess,\n\t\t&oa,\n\t\t&iosb,\n\t\tsyscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE,\n\t\tdisposition,\n\t\t0,\n\t\ttyp,\n\t\t0,\n\t\t0,\n\t\t0xffffffff,\n\t\tuint32(c.InputBufferSize),\n\t\tuint32(c.OutputBufferSize),\n\t\t&timeout).Err()\n\tif err != nil {\n\t\treturn 0, &os.PathError{Op: \"open\", Path: path, Err: err}\n\t}\n\n\truntime.KeepAlive(ntPath)\n\treturn h, nil\n}\n\nfunc (l *win32PipeListener) makeServerPipe() (*win32File, error) {\n\th, err := makeServerPipeHandle(l.path, nil, &l.config, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tf, err := makeWin32File(h)\n\tif err != nil {\n\t\tsyscall.Close(h)\n\t\treturn nil, err\n\t}\n\treturn f, nil\n}\n\nfunc (l *win32PipeListener) makeConnectedServerPipe() (*win32File, error) {\n\tp, err := l.makeServerPipe()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Wait for the client to connect.\n\tch := make(chan error)\n\tgo func(p *win32File) {\n\t\tch <- connectPipe(p)\n\t}(p)\n\n\tselect {\n\tcase err = <-ch:\n\t\tif err != nil {\n\t\t\tp.Close()\n\t\t\tp = nil\n\t\t}\n\tcase <-l.closeCh:\n\t\t// Abort the connect request by closing the handle.\n\t\tp.Close()\n\t\tp = nil\n\t\terr = <-ch\n\t\tif err == nil || err == ErrFileClosed { //nolint:errorlint // err is Errno\n\t\t\terr = ErrPipeListenerClosed\n\t\t}\n\t}\n\treturn p, err\n}\n\nfunc (l *win32PipeListener) listenerRoutine() {\n\tclosed := false\n\tfor !closed {\n\t\tselect {\n\t\tcase <-l.closeCh:\n\t\t\tclosed = true\n\t\tcase responseCh := <-l.acceptCh:\n\t\t\tvar (\n\t\t\t\tp   *win32File\n\t\t\t\terr error\n\t\t\t)\n\t\t\tfor {\n\t\t\t\tp, err = l.makeConnectedServerPipe()\n\t\t\t\t// If the connection was immediately closed by the client, try\n\t\t\t\t// again.\n\t\t\t\tif err != windows.ERROR_NO_DATA { //nolint:errorlint // err is Errno\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tresponseCh <- acceptResponse{p, err}\n\t\t\tclosed = err == ErrPipeListenerClosed //nolint:errorlint // err is Errno\n\t\t}\n\t}\n\tsyscall.Close(l.firstHandle)\n\tl.firstHandle = 0\n\t// Notify Close() and Accept() callers that the handle has been closed.\n\tclose(l.doneCh)\n}\n\n// PipeConfig contain configuration for the pipe listener.\ntype PipeConfig struct {\n\t// SecurityDescriptor contains a Windows security descriptor in SDDL format.\n\tSecurityDescriptor string\n\n\t// MessageMode determines whether the pipe is in byte or message mode. In either\n\t// case the pipe is read in byte mode by default. The only practical difference in\n\t// this implementation is that CloseWrite() is only supported for message mode pipes;\n\t// CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only\n\t// transferred to the reader (and returned as io.EOF in this implementation)\n\t// when the pipe is in message mode.\n\tMessageMode bool\n\n\t// InputBufferSize specifies the size of the input buffer, in bytes.\n\tInputBufferSize int32\n\n\t// OutputBufferSize specifies the size of the output buffer, in bytes.\n\tOutputBufferSize int32\n}\n\n// ListenPipe creates a listener on a Windows named pipe path, e.g. \\\\.\\pipe\\mypipe.\n// The pipe must not already exist.\nfunc ListenPipe(path string, c *PipeConfig) (net.Listener, error) {\n\tvar (\n\t\tsd  []byte\n\t\terr error\n\t)\n\tif c == nil {\n\t\tc = &PipeConfig{}\n\t}\n\tif c.SecurityDescriptor != \"\" {\n\t\tsd, err = SddlToSecurityDescriptor(c.SecurityDescriptor)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\th, err := makeServerPipeHandle(path, sd, c, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tl := &win32PipeListener{\n\t\tfirstHandle: h,\n\t\tpath:        path,\n\t\tconfig:      *c,\n\t\tacceptCh:    make(chan (chan acceptResponse)),\n\t\tcloseCh:     make(chan int),\n\t\tdoneCh:      make(chan int),\n\t}\n\tgo l.listenerRoutine()\n\treturn l, nil\n}\n\nfunc connectPipe(p *win32File) error {\n\tc, err := p.prepareIO()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer p.wg.Done()\n\n\terr = connectNamedPipe(p.handle, &c.o)\n\t_, err = p.asyncIO(c, nil, 0, err)\n\tif err != nil && err != windows.ERROR_PIPE_CONNECTED { //nolint:errorlint // err is Errno\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (l *win32PipeListener) Accept() (net.Conn, error) {\n\tch := make(chan acceptResponse)\n\tselect {\n\tcase l.acceptCh <- ch:\n\t\tresponse := <-ch\n\t\terr := response.err\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif l.config.MessageMode {\n\t\t\treturn &win32MessageBytePipe{\n\t\t\t\twin32Pipe: win32Pipe{win32File: response.f, path: l.path},\n\t\t\t}, nil\n\t\t}\n\t\treturn &win32Pipe{win32File: response.f, path: l.path}, nil\n\tcase <-l.doneCh:\n\t\treturn nil, ErrPipeListenerClosed\n\t}\n}\n\nfunc (l *win32PipeListener) Close() error {\n\tselect {\n\tcase l.closeCh <- 1:\n\t\t<-l.doneCh\n\tcase <-l.doneCh:\n\t}\n\treturn nil\n}\n\nfunc (l *win32PipeListener) Addr() net.Addr {\n\treturn pipeAddress(l.path)\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go",
    "content": "// Package guid provides a GUID type. The backing structure for a GUID is\n// identical to that used by the golang.org/x/sys/windows GUID type.\n// There are two main binary encodings used for a GUID, the big-endian encoding,\n// and the Windows (mixed-endian) encoding. See here for details:\n// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding\npackage guid\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/sha1\" //nolint:gosec // not used for secure application\n\t\"encoding\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\n//go:generate go run golang.org/x/tools/cmd/stringer -type=Variant -trimprefix=Variant -linecomment\n\n// Variant specifies which GUID variant (or \"type\") of the GUID. It determines\n// how the entirety of the rest of the GUID is interpreted.\ntype Variant uint8\n\n// The variants specified by RFC 4122 section 4.1.1.\nconst (\n\t// VariantUnknown specifies a GUID variant which does not conform to one of\n\t// the variant encodings specified in RFC 4122.\n\tVariantUnknown Variant = iota\n\tVariantNCS\n\tVariantRFC4122 // RFC 4122\n\tVariantMicrosoft\n\tVariantFuture\n)\n\n// Version specifies how the bits in the GUID were generated. For instance, a\n// version 4 GUID is randomly generated, and a version 5 is generated from the\n// hash of an input string.\ntype Version uint8\n\nfunc (v Version) String() string {\n\treturn strconv.FormatUint(uint64(v), 10)\n}\n\nvar _ = (encoding.TextMarshaler)(GUID{})\nvar _ = (encoding.TextUnmarshaler)(&GUID{})\n\n// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.\nfunc NewV4() (GUID, error) {\n\tvar b [16]byte\n\tif _, err := rand.Read(b[:]); err != nil {\n\t\treturn GUID{}, err\n\t}\n\n\tg := FromArray(b)\n\tg.setVersion(4) // Version 4 means randomly generated.\n\tg.setVariant(VariantRFC4122)\n\n\treturn g, nil\n}\n\n// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing)\n// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name,\n// and the sample code treats it as a series of bytes, so we do the same here.\n//\n// Some implementations, such as those found on Windows, treat the name as a\n// big-endian UTF16 stream of bytes. If that is desired, the string can be\n// encoded as such before being passed to this function.\nfunc NewV5(namespace GUID, name []byte) (GUID, error) {\n\tb := sha1.New() //nolint:gosec // not used for secure application\n\tnamespaceBytes := namespace.ToArray()\n\tb.Write(namespaceBytes[:])\n\tb.Write(name)\n\n\ta := [16]byte{}\n\tcopy(a[:], b.Sum(nil))\n\n\tg := FromArray(a)\n\tg.setVersion(5) // Version 5 means generated from a string.\n\tg.setVariant(VariantRFC4122)\n\n\treturn g, nil\n}\n\nfunc fromArray(b [16]byte, order binary.ByteOrder) GUID {\n\tvar g GUID\n\tg.Data1 = order.Uint32(b[0:4])\n\tg.Data2 = order.Uint16(b[4:6])\n\tg.Data3 = order.Uint16(b[6:8])\n\tcopy(g.Data4[:], b[8:16])\n\treturn g\n}\n\nfunc (g GUID) toArray(order binary.ByteOrder) [16]byte {\n\tb := [16]byte{}\n\torder.PutUint32(b[0:4], g.Data1)\n\torder.PutUint16(b[4:6], g.Data2)\n\torder.PutUint16(b[6:8], g.Data3)\n\tcopy(b[8:16], g.Data4[:])\n\treturn b\n}\n\n// FromArray constructs a GUID from a big-endian encoding array of 16 bytes.\nfunc FromArray(b [16]byte) GUID {\n\treturn fromArray(b, binary.BigEndian)\n}\n\n// ToArray returns an array of 16 bytes representing the GUID in big-endian\n// encoding.\nfunc (g GUID) ToArray() [16]byte {\n\treturn g.toArray(binary.BigEndian)\n}\n\n// FromWindowsArray constructs a GUID from a Windows encoding array of bytes.\nfunc FromWindowsArray(b [16]byte) GUID {\n\treturn fromArray(b, binary.LittleEndian)\n}\n\n// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows\n// encoding.\nfunc (g GUID) ToWindowsArray() [16]byte {\n\treturn g.toArray(binary.LittleEndian)\n}\n\nfunc (g GUID) String() string {\n\treturn fmt.Sprintf(\n\t\t\"%08x-%04x-%04x-%04x-%012x\",\n\t\tg.Data1,\n\t\tg.Data2,\n\t\tg.Data3,\n\t\tg.Data4[:2],\n\t\tg.Data4[2:])\n}\n\n// FromString parses a string containing a GUID and returns the GUID. The only\n// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`\n// format.\nfunc FromString(s string) (GUID, error) {\n\tif len(s) != 36 {\n\t\treturn GUID{}, fmt.Errorf(\"invalid GUID %q\", s)\n\t}\n\tif s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {\n\t\treturn GUID{}, fmt.Errorf(\"invalid GUID %q\", s)\n\t}\n\n\tvar g GUID\n\n\tdata1, err := strconv.ParseUint(s[0:8], 16, 32)\n\tif err != nil {\n\t\treturn GUID{}, fmt.Errorf(\"invalid GUID %q\", s)\n\t}\n\tg.Data1 = uint32(data1)\n\n\tdata2, err := strconv.ParseUint(s[9:13], 16, 16)\n\tif err != nil {\n\t\treturn GUID{}, fmt.Errorf(\"invalid GUID %q\", s)\n\t}\n\tg.Data2 = uint16(data2)\n\n\tdata3, err := strconv.ParseUint(s[14:18], 16, 16)\n\tif err != nil {\n\t\treturn GUID{}, fmt.Errorf(\"invalid GUID %q\", s)\n\t}\n\tg.Data3 = uint16(data3)\n\n\tfor i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {\n\t\tv, err := strconv.ParseUint(s[x:x+2], 16, 8)\n\t\tif err != nil {\n\t\t\treturn GUID{}, fmt.Errorf(\"invalid GUID %q\", s)\n\t\t}\n\t\tg.Data4[i] = uint8(v)\n\t}\n\n\treturn g, nil\n}\n\nfunc (g *GUID) setVariant(v Variant) {\n\td := g.Data4[0]\n\tswitch v {\n\tcase VariantNCS:\n\t\td = (d & 0x7f)\n\tcase VariantRFC4122:\n\t\td = (d & 0x3f) | 0x80\n\tcase VariantMicrosoft:\n\t\td = (d & 0x1f) | 0xc0\n\tcase VariantFuture:\n\t\td = (d & 0x0f) | 0xe0\n\tcase VariantUnknown:\n\t\tfallthrough\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"invalid variant: %d\", v))\n\t}\n\tg.Data4[0] = d\n}\n\n// Variant returns the GUID variant, as defined in RFC 4122.\nfunc (g GUID) Variant() Variant {\n\tb := g.Data4[0]\n\tif b&0x80 == 0 {\n\t\treturn VariantNCS\n\t} else if b&0xc0 == 0x80 {\n\t\treturn VariantRFC4122\n\t} else if b&0xe0 == 0xc0 {\n\t\treturn VariantMicrosoft\n\t} else if b&0xe0 == 0xe0 {\n\t\treturn VariantFuture\n\t}\n\treturn VariantUnknown\n}\n\nfunc (g *GUID) setVersion(v Version) {\n\tg.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12)\n}\n\n// Version returns the GUID version, as defined in RFC 4122.\nfunc (g GUID) Version() Version {\n\treturn Version((g.Data3 & 0xF000) >> 12)\n}\n\n// MarshalText returns the textual representation of the GUID.\nfunc (g GUID) MarshalText() ([]byte, error) {\n\treturn []byte(g.String()), nil\n}\n\n// UnmarshalText takes the textual representation of a GUID, and unmarhals it\n// into this GUID.\nfunc (g *GUID) UnmarshalText(text []byte) error {\n\tg2, err := FromString(string(text))\n\tif err != nil {\n\t\treturn err\n\t}\n\t*g = g2\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage guid\n\n// GUID represents a GUID/UUID. It has the same structure as\n// golang.org/x/sys/windows.GUID so that it can be used with functions expecting\n// that type. It is defined as its own type as that is only available to builds\n// targeted at `windows`. The representation matches that used by native Windows\n// code.\ntype GUID struct {\n\tData1 uint32\n\tData2 uint16\n\tData3 uint16\n\tData4 [8]byte\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage guid\n\nimport \"golang.org/x/sys/windows\"\n\n// GUID represents a GUID/UUID. It has the same structure as\n// golang.org/x/sys/windows.GUID so that it can be used with functions expecting\n// that type. It is defined as its own type so that stringification and\n// marshaling can be supported. The representation matches that used by native\n// Windows code.\ntype GUID windows.GUID\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go",
    "content": "// Code generated by \"stringer -type=Variant -trimprefix=Variant -linecomment\"; DO NOT EDIT.\n\npackage guid\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[VariantUnknown-0]\n\t_ = x[VariantNCS-1]\n\t_ = x[VariantRFC4122-2]\n\t_ = x[VariantMicrosoft-3]\n\t_ = x[VariantFuture-4]\n}\n\nconst _Variant_name = \"UnknownNCSRFC 4122MicrosoftFuture\"\n\nvar _Variant_index = [...]uint8{0, 7, 10, 18, 27, 33}\n\nfunc (i Variant) String() string {\n\tif i >= Variant(len(_Variant_index)-1) {\n\t\treturn \"Variant(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _Variant_name[_Variant_index[i]:_Variant_index[i+1]]\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/privilege.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unicode/utf16\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n//sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges\n//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf\n//sys revertToSelf() (err error) = advapi32.RevertToSelf\n//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken\n//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread\n//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW\n//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW\n//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW\n\nconst (\n\t//revive:disable-next-line:var-naming ALL_CAPS\n\tSE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED\n\n\t//revive:disable-next-line:var-naming ALL_CAPS\n\tERROR_NOT_ALL_ASSIGNED syscall.Errno = windows.ERROR_NOT_ALL_ASSIGNED\n\n\tSeBackupPrivilege   = \"SeBackupPrivilege\"\n\tSeRestorePrivilege  = \"SeRestorePrivilege\"\n\tSeSecurityPrivilege = \"SeSecurityPrivilege\"\n)\n\nvar (\n\tprivNames     = make(map[string]uint64)\n\tprivNameMutex sync.Mutex\n)\n\n// PrivilegeError represents an error enabling privileges.\ntype PrivilegeError struct {\n\tprivileges []uint64\n}\n\nfunc (e *PrivilegeError) Error() string {\n\ts := \"Could not enable privilege \"\n\tif len(e.privileges) > 1 {\n\t\ts = \"Could not enable privileges \"\n\t}\n\tfor i, p := range e.privileges {\n\t\tif i != 0 {\n\t\t\ts += \", \"\n\t\t}\n\t\ts += `\"`\n\t\ts += getPrivilegeName(p)\n\t\ts += `\"`\n\t}\n\treturn s\n}\n\n// RunWithPrivilege enables a single privilege for a function call.\nfunc RunWithPrivilege(name string, fn func() error) error {\n\treturn RunWithPrivileges([]string{name}, fn)\n}\n\n// RunWithPrivileges enables privileges for a function call.\nfunc RunWithPrivileges(names []string, fn func() error) error {\n\tprivileges, err := mapPrivileges(names)\n\tif err != nil {\n\t\treturn err\n\t}\n\truntime.LockOSThread()\n\tdefer runtime.UnlockOSThread()\n\ttoken, err := newThreadToken()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer releaseThreadToken(token)\n\terr = adjustPrivileges(token, privileges, SE_PRIVILEGE_ENABLED)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn fn()\n}\n\nfunc mapPrivileges(names []string) ([]uint64, error) {\n\tprivileges := make([]uint64, 0, len(names))\n\tprivNameMutex.Lock()\n\tdefer privNameMutex.Unlock()\n\tfor _, name := range names {\n\t\tp, ok := privNames[name]\n\t\tif !ok {\n\t\t\terr := lookupPrivilegeValue(\"\", name, &p)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tprivNames[name] = p\n\t\t}\n\t\tprivileges = append(privileges, p)\n\t}\n\treturn privileges, nil\n}\n\n// EnableProcessPrivileges enables privileges globally for the process.\nfunc EnableProcessPrivileges(names []string) error {\n\treturn enableDisableProcessPrivilege(names, SE_PRIVILEGE_ENABLED)\n}\n\n// DisableProcessPrivileges disables privileges globally for the process.\nfunc DisableProcessPrivileges(names []string) error {\n\treturn enableDisableProcessPrivilege(names, 0)\n}\n\nfunc enableDisableProcessPrivilege(names []string, action uint32) error {\n\tprivileges, err := mapPrivileges(names)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tp := windows.CurrentProcess()\n\tvar token windows.Token\n\terr = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer token.Close()\n\treturn adjustPrivileges(token, privileges, action)\n}\n\nfunc adjustPrivileges(token windows.Token, privileges []uint64, action uint32) error {\n\tvar b bytes.Buffer\n\t_ = binary.Write(&b, binary.LittleEndian, uint32(len(privileges)))\n\tfor _, p := range privileges {\n\t\t_ = binary.Write(&b, binary.LittleEndian, p)\n\t\t_ = binary.Write(&b, binary.LittleEndian, action)\n\t}\n\tprevState := make([]byte, b.Len())\n\treqSize := uint32(0)\n\tsuccess, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize)\n\tif !success {\n\t\treturn err\n\t}\n\tif err == ERROR_NOT_ALL_ASSIGNED { //nolint:errorlint // err is Errno\n\t\treturn &PrivilegeError{privileges}\n\t}\n\treturn nil\n}\n\nfunc getPrivilegeName(luid uint64) string {\n\tvar nameBuffer [256]uint16\n\tbufSize := uint32(len(nameBuffer))\n\terr := lookupPrivilegeName(\"\", &luid, &nameBuffer[0], &bufSize)\n\tif err != nil {\n\t\treturn fmt.Sprintf(\"<unknown privilege %d>\", luid)\n\t}\n\n\tvar displayNameBuffer [256]uint16\n\tdisplayBufSize := uint32(len(displayNameBuffer))\n\tvar langID uint32\n\terr = lookupPrivilegeDisplayName(\"\", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langID)\n\tif err != nil {\n\t\treturn fmt.Sprintf(\"<unknown privilege %s>\", string(utf16.Decode(nameBuffer[:bufSize])))\n\t}\n\n\treturn string(utf16.Decode(displayNameBuffer[:displayBufSize]))\n}\n\nfunc newThreadToken() (windows.Token, error) {\n\terr := impersonateSelf(windows.SecurityImpersonation)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tvar token windows.Token\n\terr = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token)\n\tif err != nil {\n\t\trerr := revertToSelf()\n\t\tif rerr != nil {\n\t\t\tpanic(rerr)\n\t\t}\n\t\treturn 0, err\n\t}\n\treturn token, nil\n}\n\nfunc releaseThreadToken(h windows.Token) {\n\terr := revertToSelf()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\th.Close()\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/reparse.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf16\"\n\t\"unsafe\"\n)\n\nconst (\n\treparseTagMountPoint = 0xA0000003\n\treparseTagSymlink    = 0xA000000C\n)\n\ntype reparseDataBuffer struct {\n\tReparseTag           uint32\n\tReparseDataLength    uint16\n\tReserved             uint16\n\tSubstituteNameOffset uint16\n\tSubstituteNameLength uint16\n\tPrintNameOffset      uint16\n\tPrintNameLength      uint16\n}\n\n// ReparsePoint describes a Win32 symlink or mount point.\ntype ReparsePoint struct {\n\tTarget       string\n\tIsMountPoint bool\n}\n\n// UnsupportedReparsePointError is returned when trying to decode a non-symlink or\n// mount point reparse point.\ntype UnsupportedReparsePointError struct {\n\tTag uint32\n}\n\nfunc (e *UnsupportedReparsePointError) Error() string {\n\treturn fmt.Sprintf(\"unsupported reparse point %x\", e.Tag)\n}\n\n// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink\n// or a mount point.\nfunc DecodeReparsePoint(b []byte) (*ReparsePoint, error) {\n\ttag := binary.LittleEndian.Uint32(b[0:4])\n\treturn DecodeReparsePointData(tag, b[8:])\n}\n\nfunc DecodeReparsePointData(tag uint32, b []byte) (*ReparsePoint, error) {\n\tisMountPoint := false\n\tswitch tag {\n\tcase reparseTagMountPoint:\n\t\tisMountPoint = true\n\tcase reparseTagSymlink:\n\tdefault:\n\t\treturn nil, &UnsupportedReparsePointError{tag}\n\t}\n\tnameOffset := 8 + binary.LittleEndian.Uint16(b[4:6])\n\tif !isMountPoint {\n\t\tnameOffset += 4\n\t}\n\tnameLength := binary.LittleEndian.Uint16(b[6:8])\n\tname := make([]uint16, nameLength/2)\n\terr := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil\n}\n\nfunc isDriveLetter(c byte) bool {\n\treturn (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')\n}\n\n// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or\n// mount point.\nfunc EncodeReparsePoint(rp *ReparsePoint) []byte {\n\t// Generate an NT path and determine if this is a relative path.\n\tvar ntTarget string\n\trelative := false\n\tif strings.HasPrefix(rp.Target, `\\\\?\\`) {\n\t\tntTarget = `\\??\\` + rp.Target[4:]\n\t} else if strings.HasPrefix(rp.Target, `\\\\`) {\n\t\tntTarget = `\\??\\UNC\\` + rp.Target[2:]\n\t} else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' {\n\t\tntTarget = `\\??\\` + rp.Target\n\t} else {\n\t\tntTarget = rp.Target\n\t\trelative = true\n\t}\n\n\t// The paths must be NUL-terminated even though they are counted strings.\n\ttarget16 := utf16.Encode([]rune(rp.Target + \"\\x00\"))\n\tntTarget16 := utf16.Encode([]rune(ntTarget + \"\\x00\"))\n\n\tsize := int(unsafe.Sizeof(reparseDataBuffer{})) - 8\n\tsize += len(ntTarget16)*2 + len(target16)*2\n\n\ttag := uint32(reparseTagMountPoint)\n\tif !rp.IsMountPoint {\n\t\ttag = reparseTagSymlink\n\t\tsize += 4 // Add room for symlink flags\n\t}\n\n\tdata := reparseDataBuffer{\n\t\tReparseTag:           tag,\n\t\tReparseDataLength:    uint16(size),\n\t\tSubstituteNameOffset: 0,\n\t\tSubstituteNameLength: uint16((len(ntTarget16) - 1) * 2),\n\t\tPrintNameOffset:      uint16(len(ntTarget16) * 2),\n\t\tPrintNameLength:      uint16((len(target16) - 1) * 2),\n\t}\n\n\tvar b bytes.Buffer\n\t_ = binary.Write(&b, binary.LittleEndian, &data)\n\tif !rp.IsMountPoint {\n\t\tflags := uint32(0)\n\t\tif relative {\n\t\t\tflags |= 1\n\t\t}\n\t\t_ = binary.Write(&b, binary.LittleEndian, flags)\n\t}\n\n\t_ = binary.Write(&b, binary.LittleEndian, ntTarget16)\n\t_ = binary.Write(&b, binary.LittleEndian, target16)\n\treturn b.Bytes()\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/sd.go",
    "content": "//go:build windows\n// +build windows\n\npackage winio\n\nimport (\n\t\"errors\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW\n//sys lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountSidW\n//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW\n//sys convertStringSidToSid(str *uint16, sid **byte) (err error) = advapi32.ConvertStringSidToSidW\n//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW\n//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW\n//sys localFree(mem uintptr) = LocalFree\n//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength\n\ntype AccountLookupError struct {\n\tName string\n\tErr  error\n}\n\nfunc (e *AccountLookupError) Error() string {\n\tif e.Name == \"\" {\n\t\treturn \"lookup account: empty account name specified\"\n\t}\n\tvar s string\n\tswitch {\n\tcase errors.Is(e.Err, windows.ERROR_INVALID_SID):\n\t\ts = \"the security ID structure is invalid\"\n\tcase errors.Is(e.Err, windows.ERROR_NONE_MAPPED):\n\t\ts = \"not found\"\n\tdefault:\n\t\ts = e.Err.Error()\n\t}\n\treturn \"lookup account \" + e.Name + \": \" + s\n}\n\nfunc (e *AccountLookupError) Unwrap() error { return e.Err }\n\ntype SddlConversionError struct {\n\tSddl string\n\tErr  error\n}\n\nfunc (e *SddlConversionError) Error() string {\n\treturn \"convert \" + e.Sddl + \": \" + e.Err.Error()\n}\n\nfunc (e *SddlConversionError) Unwrap() error { return e.Err }\n\n// LookupSidByName looks up the SID of an account by name\n//\n//revive:disable-next-line:var-naming SID, not Sid\nfunc LookupSidByName(name string) (sid string, err error) {\n\tif name == \"\" {\n\t\treturn \"\", &AccountLookupError{name, windows.ERROR_NONE_MAPPED}\n\t}\n\n\tvar sidSize, sidNameUse, refDomainSize uint32\n\terr = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)\n\tif err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno\n\t\treturn \"\", &AccountLookupError{name, err}\n\t}\n\tsidBuffer := make([]byte, sidSize)\n\trefDomainBuffer := make([]uint16, refDomainSize)\n\terr = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)\n\tif err != nil {\n\t\treturn \"\", &AccountLookupError{name, err}\n\t}\n\tvar strBuffer *uint16\n\terr = convertSidToStringSid(&sidBuffer[0], &strBuffer)\n\tif err != nil {\n\t\treturn \"\", &AccountLookupError{name, err}\n\t}\n\tsid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])\n\tlocalFree(uintptr(unsafe.Pointer(strBuffer)))\n\treturn sid, nil\n}\n\n// LookupNameBySid looks up the name of an account by SID\n//\n//revive:disable-next-line:var-naming SID, not Sid\nfunc LookupNameBySid(sid string) (name string, err error) {\n\tif sid == \"\" {\n\t\treturn \"\", &AccountLookupError{sid, windows.ERROR_NONE_MAPPED}\n\t}\n\n\tsidBuffer, err := windows.UTF16PtrFromString(sid)\n\tif err != nil {\n\t\treturn \"\", &AccountLookupError{sid, err}\n\t}\n\n\tvar sidPtr *byte\n\tif err = convertStringSidToSid(sidBuffer, &sidPtr); err != nil {\n\t\treturn \"\", &AccountLookupError{sid, err}\n\t}\n\tdefer localFree(uintptr(unsafe.Pointer(sidPtr)))\n\n\tvar nameSize, refDomainSize, sidNameUse uint32\n\terr = lookupAccountSid(nil, sidPtr, nil, &nameSize, nil, &refDomainSize, &sidNameUse)\n\tif err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno\n\t\treturn \"\", &AccountLookupError{sid, err}\n\t}\n\n\tnameBuffer := make([]uint16, nameSize)\n\trefDomainBuffer := make([]uint16, refDomainSize)\n\terr = lookupAccountSid(nil, sidPtr, &nameBuffer[0], &nameSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse)\n\tif err != nil {\n\t\treturn \"\", &AccountLookupError{sid, err}\n\t}\n\n\tname = windows.UTF16ToString(nameBuffer)\n\treturn name, nil\n}\n\nfunc SddlToSecurityDescriptor(sddl string) ([]byte, error) {\n\tvar sdBuffer uintptr\n\terr := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)\n\tif err != nil {\n\t\treturn nil, &SddlConversionError{sddl, err}\n\t}\n\tdefer localFree(sdBuffer)\n\tsd := make([]byte, getSecurityDescriptorLength(sdBuffer))\n\tcopy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)])\n\treturn sd, nil\n}\n\nfunc SecurityDescriptorToSddl(sd []byte) (string, error) {\n\tvar sddl *uint16\n\t// The returned string length seems to include an arbitrary number of terminating NULs.\n\t// Don't use it.\n\terr := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer localFree(uintptr(unsafe.Pointer(sddl)))\n\treturn syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil\n}\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/syscall.go",
    "content": "//go:build windows\n\npackage winio\n\n//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./*.go\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/tools.go",
    "content": "//go:build tools\n\npackage winio\n\nimport _ \"golang.org/x/tools/cmd/stringer\"\n"
  },
  {
    "path": "vendor/github.com/Microsoft/go-winio/zsyscall_windows.go",
    "content": "//go:build windows\n\n// Code generated by 'go generate' using \"github.com/Microsoft/go-winio/tools/mkwinsyscall\"; DO NOT EDIT.\n\npackage winio\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nvar _ unsafe.Pointer\n\n// Do the interface allocations only once for common\n// Errno values.\nconst (\n\terrnoERROR_IO_PENDING = 997\n)\n\nvar (\n\terrERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)\n\terrERROR_EINVAL     error = syscall.EINVAL\n)\n\n// errnoErr returns common boxed Errno values, to prevent\n// allocations at runtime.\nfunc errnoErr(e syscall.Errno) error {\n\tswitch e {\n\tcase 0:\n\t\treturn errERROR_EINVAL\n\tcase errnoERROR_IO_PENDING:\n\t\treturn errERROR_IO_PENDING\n\t}\n\t// TODO: add more here, after collecting data on the common\n\t// error values see on Windows. (perhaps when running\n\t// all.bat?)\n\treturn e\n}\n\nvar (\n\tmodadvapi32 = windows.NewLazySystemDLL(\"advapi32.dll\")\n\tmodkernel32 = windows.NewLazySystemDLL(\"kernel32.dll\")\n\tmodntdll    = windows.NewLazySystemDLL(\"ntdll.dll\")\n\tmodws2_32   = windows.NewLazySystemDLL(\"ws2_32.dll\")\n\n\tprocAdjustTokenPrivileges                                = modadvapi32.NewProc(\"AdjustTokenPrivileges\")\n\tprocConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc(\"ConvertSecurityDescriptorToStringSecurityDescriptorW\")\n\tprocConvertSidToStringSidW                               = modadvapi32.NewProc(\"ConvertSidToStringSidW\")\n\tprocConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc(\"ConvertStringSecurityDescriptorToSecurityDescriptorW\")\n\tprocConvertStringSidToSidW                               = modadvapi32.NewProc(\"ConvertStringSidToSidW\")\n\tprocGetSecurityDescriptorLength                          = modadvapi32.NewProc(\"GetSecurityDescriptorLength\")\n\tprocImpersonateSelf                                      = modadvapi32.NewProc(\"ImpersonateSelf\")\n\tprocLookupAccountNameW                                   = modadvapi32.NewProc(\"LookupAccountNameW\")\n\tprocLookupAccountSidW                                    = modadvapi32.NewProc(\"LookupAccountSidW\")\n\tprocLookupPrivilegeDisplayNameW                          = modadvapi32.NewProc(\"LookupPrivilegeDisplayNameW\")\n\tprocLookupPrivilegeNameW                                 = modadvapi32.NewProc(\"LookupPrivilegeNameW\")\n\tprocLookupPrivilegeValueW                                = modadvapi32.NewProc(\"LookupPrivilegeValueW\")\n\tprocOpenThreadToken                                      = modadvapi32.NewProc(\"OpenThreadToken\")\n\tprocRevertToSelf                                         = modadvapi32.NewProc(\"RevertToSelf\")\n\tprocBackupRead                                           = modkernel32.NewProc(\"BackupRead\")\n\tprocBackupWrite                                          = modkernel32.NewProc(\"BackupWrite\")\n\tprocCancelIoEx                                           = modkernel32.NewProc(\"CancelIoEx\")\n\tprocConnectNamedPipe                                     = modkernel32.NewProc(\"ConnectNamedPipe\")\n\tprocCreateIoCompletionPort                               = modkernel32.NewProc(\"CreateIoCompletionPort\")\n\tprocCreateNamedPipeW                                     = modkernel32.NewProc(\"CreateNamedPipeW\")\n\tprocGetCurrentThread                                     = modkernel32.NewProc(\"GetCurrentThread\")\n\tprocGetNamedPipeHandleStateW                             = modkernel32.NewProc(\"GetNamedPipeHandleStateW\")\n\tprocGetNamedPipeInfo                                     = modkernel32.NewProc(\"GetNamedPipeInfo\")\n\tprocGetQueuedCompletionStatus                            = modkernel32.NewProc(\"GetQueuedCompletionStatus\")\n\tprocLocalAlloc                                           = modkernel32.NewProc(\"LocalAlloc\")\n\tprocLocalFree                                            = modkernel32.NewProc(\"LocalFree\")\n\tprocSetFileCompletionNotificationModes                   = modkernel32.NewProc(\"SetFileCompletionNotificationModes\")\n\tprocNtCreateNamedPipeFile                                = modntdll.NewProc(\"NtCreateNamedPipeFile\")\n\tprocRtlDefaultNpAcl                                      = modntdll.NewProc(\"RtlDefaultNpAcl\")\n\tprocRtlDosPathNameToNtPathName_U                         = modntdll.NewProc(\"RtlDosPathNameToNtPathName_U\")\n\tprocRtlNtStatusToDosErrorNoTeb                           = modntdll.NewProc(\"RtlNtStatusToDosErrorNoTeb\")\n\tprocWSAGetOverlappedResult                               = modws2_32.NewProc(\"WSAGetOverlappedResult\")\n)\n\nfunc adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {\n\tvar _p0 uint32\n\tif releaseAll {\n\t\t_p0 = 1\n\t}\n\tr0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))\n\tsuccess = r0 != 0\n\tif true {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc convertSidToStringSid(sid *byte, str **uint16) (err error) {\n\tr1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {\n\tvar _p0 *uint16\n\t_p0, err = syscall.UTF16PtrFromString(str)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)\n}\n\nfunc _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc convertStringSidToSid(str *uint16, sid **byte) (err error) {\n\tr1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc getSecurityDescriptorLength(sd uintptr) (len uint32) {\n\tr0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)\n\tlen = uint32(r0)\n\treturn\n}\n\nfunc impersonateSelf(level uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {\n\tvar _p0 *uint16\n\t_p0, err = syscall.UTF16PtrFromString(accountName)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse)\n}\n\nfunc _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {\n\tvar _p0 *uint16\n\t_p0, err = syscall.UTF16PtrFromString(systemName)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId)\n}\n\nfunc _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) {\n\tvar _p0 *uint16\n\t_p0, err = syscall.UTF16PtrFromString(systemName)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn _lookupPrivilegeName(_p0, luid, buffer, size)\n}\n\nfunc _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) {\n\tvar _p0 *uint16\n\t_p0, err = syscall.UTF16PtrFromString(systemName)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar _p1 *uint16\n\t_p1, err = syscall.UTF16PtrFromString(name)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn _lookupPrivilegeValue(_p0, _p1, luid)\n}\n\nfunc _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {\n\tr1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {\n\tvar _p0 uint32\n\tif openAsSelf {\n\t\t_p0 = 1\n\t}\n\tr1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc revertToSelf() (err error) {\n\tr1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {\n\tvar _p0 *byte\n\tif len(b) > 0 {\n\t\t_p0 = &b[0]\n\t}\n\tvar _p1 uint32\n\tif abort {\n\t\t_p1 = 1\n\t}\n\tvar _p2 uint32\n\tif processSecurity {\n\t\t_p2 = 1\n\t}\n\tr1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {\n\tvar _p0 *byte\n\tif len(b) > 0 {\n\t\t_p0 = &b[0]\n\t}\n\tvar _p1 uint32\n\tif abort {\n\t\t_p1 = 1\n\t}\n\tvar _p2 uint32\n\tif processSecurity {\n\t\t_p2 = 1\n\t}\n\tr1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {\n\tr1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {\n\tr1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {\n\tr0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)\n\tnewport = syscall.Handle(r0)\n\tif newport == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {\n\tvar _p0 *uint16\n\t_p0, err = syscall.UTF16PtrFromString(name)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)\n}\n\nfunc _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {\n\tr0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)\n\thandle = syscall.Handle(r0)\n\tif handle == syscall.InvalidHandle {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc getCurrentThread() (h syscall.Handle) {\n\tr0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)\n\th = syscall.Handle(r0)\n\treturn\n}\n\nfunc getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {\n\tr1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc localAlloc(uFlags uint32, length uint32) (ptr uintptr) {\n\tr0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)\n\tptr = uintptr(r0)\n\treturn\n}\n\nfunc localFree(mem uintptr) {\n\tsyscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)\n\treturn\n}\n\nfunc setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {\n\tr1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n\nfunc ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) {\n\tr0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)\n\tstatus = ntStatus(r0)\n\treturn\n}\n\nfunc rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) {\n\tr0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)\n\tstatus = ntStatus(r0)\n\treturn\n}\n\nfunc rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) {\n\tr0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)\n\tstatus = ntStatus(r0)\n\treturn\n}\n\nfunc rtlNtStatusToDosError(status ntStatus) (winerr error) {\n\tr0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)\n\tif r0 != 0 {\n\t\twinerr = syscall.Errno(r0)\n\t}\n\treturn\n}\n\nfunc wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {\n\tvar _p0 uint32\n\tif wait {\n\t\t_p0 = 1\n\t}\n\tr1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)\n\tif r1 == 0 {\n\t\terr = errnoErr(e1)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/.gitattributes",
    "content": "testdata/* linguist-vendored\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/.gitignore",
    "content": "# editor temporary files\n*.sublime-*\n.DS_Store\n*.swp\n#*.*#\ntags\n\n# direnv config\n.env*\n\n# test binaries\n*.test\n\n# coverage and profilte outputs\n*.out\n\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/LICENSE",
    "content": "Copyright (c) 2012-2021, Martin Angers & Contributors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\n* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/README.md",
    "content": "# goquery - a little like that j-thing, only in Go\n\n[![Build Status](https://github.com/PuerkitoBio/goquery/actions/workflows/test.yml/badge.svg?branch=master)](https://github.com/PuerkitoBio/goquery/actions)\n[![Go Reference](https://pkg.go.dev/badge/github.com/PuerkitoBio/goquery.svg)](https://pkg.go.dev/github.com/PuerkitoBio/goquery)\n[![Sourcegraph Badge](https://sourcegraph.com/github.com/PuerkitoBio/goquery/-/badge.svg)](https://sourcegraph.com/github.com/PuerkitoBio/goquery?badge)\n\ngoquery brings a syntax and a set of features similar to [jQuery][] to the [Go language][go]. It is based on Go's [net/html package][html] and the CSS Selector library [cascadia][]. Since the net/html parser returns nodes, and not a full-featured DOM tree, jQuery's stateful manipulation functions (like height(), css(), detach()) have been left off.\n\nAlso, because the net/html parser requires UTF-8 encoding, so does goquery: it is the caller's responsibility to ensure that the source document provides UTF-8 encoded HTML. See the [wiki][] for various options to do this.\n\nSyntax-wise, it is as close as possible to jQuery, with the same function names when possible, and that warm and fuzzy chainable interface. jQuery being the ultra-popular library that it is, I felt that writing a similar HTML-manipulating library was better to follow its API than to start anew (in the same spirit as Go's `fmt` package), even though some of its methods are less than intuitive (looking at you, [index()][index]...).\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Changelog](#changelog)\n* [API](#api)\n* [Examples](#examples)\n* [Related Projects](#related-projects)\n* [Support](#support)\n* [License](#license)\n\n## Installation\n\nPlease note that because of the net/html dependency, goquery requires Go1.1+ and is tested on Go1.7+.\n\n    $ go get github.com/PuerkitoBio/goquery\n\n(optional) To run unit tests:\n\n    $ cd $GOPATH/src/github.com/PuerkitoBio/goquery\n    $ go test\n\n(optional) To run benchmarks (warning: it runs for a few minutes):\n\n    $ cd $GOPATH/src/github.com/PuerkitoBio/goquery\n    $ go test -bench=\".*\"\n\n## Changelog\n\n**Note that goquery's API is now stable, and will not break.**\n\n*    **2023-02-18 (v1.8.1)** : Update `go.mod` dependencies, update CI workflow.\n*    **2021-10-25 (v1.8.0)** : Add `Render` function to render a `Selection` to an `io.Writer` (thanks [@anthonygedeon](https://github.com/anthonygedeon)).\n*    **2021-07-11 (v1.7.1)** : Update go.mod dependencies and add dependabot config (thanks [@jauderho](https://github.com/jauderho)).\n*    **2021-06-14 (v1.7.0)** : Add `Single` and `SingleMatcher` functions to optimize first-match selection (thanks [@gdollardollar](https://github.com/gdollardollar)).\n*    **2021-01-11 (v1.6.1)** : Fix panic when calling `{Prepend,Append,Set}Html` on a `Selection` that contains non-Element nodes.\n*    **2020-10-08 (v1.6.0)** : Parse html in context of the container node for all functions that deal with html strings (`AfterHtml`, `AppendHtml`, etc.). Thanks to [@thiemok][thiemok] and [@davidjwilkins][djw] for their work on this.\n*    **2020-02-04 (v1.5.1)** : Update module dependencies.\n*    **2018-11-15 (v1.5.0)** : Go module support (thanks @Zaba505).\n*    **2018-06-07 (v1.4.1)** : Add `NewDocumentFromReader` examples.\n*    **2018-03-24 (v1.4.0)** : Deprecate `NewDocument(url)` and `NewDocumentFromResponse(response)`.\n*    **2018-01-28 (v1.3.0)** : Add `ToEnd` constant to `Slice` until the end of the selection (thanks to @davidjwilkins for raising the issue).\n*    **2018-01-11 (v1.2.0)** : Add `AddBack*` and deprecate `AndSelf` (thanks to @davidjwilkins).\n*    **2017-02-12 (v1.1.0)** : Add `SetHtml` and `SetText` (thanks to @glebtv).\n*    **2016-12-29 (v1.0.2)** : Optimize allocations for `Selection.Text` (thanks to @radovskyb).\n*    **2016-08-28 (v1.0.1)** : Optimize performance for large documents.\n*    **2016-07-27 (v1.0.0)** : Tag version 1.0.0.\n*    **2016-06-15** : Invalid selector strings internally compile to a `Matcher` implementation that never matches any node (instead of a panic). So for example, `doc.Find(\"~\")` returns an empty `*Selection` object.\n*    **2016-02-02** : Add `NodeName` utility function similar to the DOM's `nodeName` property. It returns the tag name of the first element in a selection, and other relevant values of non-element nodes (see [doc][] for details). Add `OuterHtml` utility function similar to the DOM's `outerHTML` property (named `OuterHtml` in small caps for consistency with the existing `Html` method on the `Selection`).\n*    **2015-04-20** : Add `AttrOr` helper method to return the attribute's value or a default value if absent. Thanks to [piotrkowalczuk][piotr].\n*    **2015-02-04** : Add more manipulation functions - Prepend* - thanks again to [Andrew Stone][thatguystone].\n*    **2014-11-28** : Add more manipulation functions - ReplaceWith*, Wrap* and Unwrap - thanks again to [Andrew Stone][thatguystone].\n*    **2014-11-07** : Add manipulation functions (thanks to [Andrew Stone][thatguystone]) and `*Matcher` functions, that receive compiled cascadia selectors instead of selector strings, thus avoiding potential panics thrown by goquery via `cascadia.MustCompile` calls. This results in better performance (selectors can be compiled once and reused) and more idiomatic error handling (you can handle cascadia's compilation errors, instead of recovering from panics, which had been bugging me for a long time). Note that the actual type expected is a `Matcher` interface, that `cascadia.Selector` implements. Other matcher implementations could be used.\n*    **2014-11-06** : Change import paths of net/html to golang.org/x/net/html (see https://groups.google.com/forum/#!topic/golang-nuts/eD8dh3T9yyA). Make sure to update your code to use the new import path too when you call goquery with `html.Node`s.\n*    **v0.3.2** : Add `NewDocumentFromReader()` (thanks jweir) which allows creating a goquery document from an io.Reader.\n*    **v0.3.1** : Add `NewDocumentFromResponse()` (thanks assassingj) which allows creating a goquery document from an http response.\n*    **v0.3.0** : Add `EachWithBreak()` which allows to break out of an `Each()` loop by returning false. This function was added instead of changing the existing `Each()` to avoid breaking compatibility.\n*    **v0.2.1** : Make go-getable, now that [go.net/html is Go1.0-compatible][gonet] (thanks to @matrixik for pointing this out).\n*    **v0.2.0** : Add support for negative indices in Slice(). **BREAKING CHANGE** `Document.Root` is removed, `Document` is now a `Selection` itself (a selection of one, the root element, just like `Document.Root` was before). Add jQuery's Closest() method.\n*    **v0.1.1** : Add benchmarks to use as baseline for refactorings, refactor Next...() and Prev...() methods to use the new html package's linked list features (Next/PrevSibling, FirstChild). Good performance boost (40+% in some cases).\n*    **v0.1.0** : Initial release.\n\n## API\n\ngoquery exposes two structs, `Document` and `Selection`, and the `Matcher` interface. Unlike jQuery, which is loaded as part of a DOM document, and thus acts on its containing document, goquery doesn't know which HTML document to act upon. So it needs to be told, and that's what the `Document` type is for. It holds the root document node as the initial Selection value to manipulate.\n\njQuery often has many variants for the same function (no argument, a selector string argument, a jQuery object argument, a DOM element argument, ...). Instead of exposing the same features in goquery as a single method with variadic empty interface arguments, statically-typed signatures are used following this naming convention:\n\n*    When the jQuery equivalent can be called with no argument, it has the same name as jQuery for the no argument signature (e.g.: `Prev()`), and the version with a selector string argument is called `XxxFiltered()` (e.g.: `PrevFiltered()`)\n*    When the jQuery equivalent **requires** one argument, the same name as jQuery is used for the selector string version (e.g.: `Is()`)\n*    The signatures accepting a jQuery object as argument are defined in goquery as `XxxSelection()` and take a `*Selection` object as argument (e.g.: `FilterSelection()`)\n*    The signatures accepting a DOM element as argument in jQuery are defined in goquery as `XxxNodes()` and take a variadic argument of type `*html.Node` (e.g.: `FilterNodes()`)\n*    The signatures accepting a function as argument in jQuery are defined in goquery as `XxxFunction()` and take a function as argument (e.g.: `FilterFunction()`)\n*    The goquery methods that can be called with a selector string have a corresponding version that take a `Matcher` interface and are defined as `XxxMatcher()` (e.g.: `IsMatcher()`)\n\nUtility functions that are not in jQuery but are useful in Go are implemented as functions (that take a `*Selection` as parameter), to avoid a potential naming clash on the `*Selection`'s methods (reserved for jQuery-equivalent behaviour).\n\nThe complete [package reference documentation can be found here][doc].\n\nPlease note that Cascadia's selectors do not necessarily match all supported selectors of jQuery (Sizzle). See the [cascadia project][cascadia] for details. Invalid selector strings compile to a `Matcher` that fails to match any node. Behaviour of the various functions that take a selector string as argument follows from that fact, e.g. (where `~` is an invalid selector string):\n\n* `Find(\"~\")` returns an empty selection because the selector string doesn't match anything.\n* `Add(\"~\")` returns a new selection that holds the same nodes as the original selection, because it didn't add any node (selector string didn't match anything).\n* `ParentsFiltered(\"~\")` returns an empty selection because the selector string doesn't match anything.\n* `ParentsUntil(\"~\")` returns all parents of the selection because the selector string didn't match any element to stop before the top element.\n\n## Examples\n\nSee some tips and tricks in the [wiki][].\n\nAdapted from example_test.go:\n\n```Go\npackage main\n\nimport (\n  \"fmt\"\n  \"log\"\n  \"net/http\"\n\n  \"github.com/PuerkitoBio/goquery\"\n)\n\nfunc ExampleScrape() {\n  // Request the HTML page.\n  res, err := http.Get(\"http://metalsucks.net\")\n  if err != nil {\n    log.Fatal(err)\n  }\n  defer res.Body.Close()\n  if res.StatusCode != 200 {\n    log.Fatalf(\"status code error: %d %s\", res.StatusCode, res.Status)\n  }\n\n  // Load the HTML document\n  doc, err := goquery.NewDocumentFromReader(res.Body)\n  if err != nil {\n    log.Fatal(err)\n  }\n\n  // Find the review items\n  doc.Find(\".left-content article .post-title\").Each(func(i int, s *goquery.Selection) {\n\t\t// For each item found, get the title\n\t\ttitle := s.Find(\"a\").Text()\n\t\tfmt.Printf(\"Review %d: %s\\n\", i, title)\n\t})\n}\n\nfunc main() {\n  ExampleScrape()\n}\n```\n\n## Related Projects\n\n- [Goq][goq], an HTML deserialization and scraping library based on goquery and struct tags.\n- [andybalholm/cascadia][cascadia], the CSS selector library used by goquery.\n- [suntong/cascadia][cascadiacli], a command-line interface to the cascadia CSS selector library, useful to test selectors.\n- [gocolly/colly](https://github.com/gocolly/colly), a lightning fast and elegant Scraping Framework\n- [gnulnx/goperf](https://github.com/gnulnx/goperf), a website performance test tool that also fetches static assets.\n- [MontFerret/ferret](https://github.com/MontFerret/ferret), declarative web scraping.\n- [tacusci/berrycms](https://github.com/tacusci/berrycms), a modern simple to use CMS with easy to write plugins\n- [Dataflow kit](https://github.com/slotix/dataflowkit), Web Scraping framework for Gophers.\n- [Geziyor](https://github.com/geziyor/geziyor), a fast web crawling & scraping framework for Go. Supports JS rendering.\n- [Pagser](https://github.com/foolin/pagser), a simple, easy, extensible, configurable HTML parser to struct based on goquery and struct tags.\n- [stitcherd](https://github.com/vhodges/stitcherd), A server for doing server side includes using css selectors and DOM updates.\n- [goskyr](https://github.com/jakopako/goskyr), an easily configurable command-line scraper written in Go.\n- [goGetJS](https://github.com/davemolk/goGetJS), a tool for extracting, searching, and saving JavaScript files (with optional headless browser).\n\n## Support\n\nThere are a number of ways you can support the project:\n\n* Use it, star it, build something with it, spread the word!\n  - If you do build something open-source or otherwise publicly-visible, let me know so I can add it to the [Related Projects](#related-projects) section!\n* Raise issues to improve the project (note: doc typos and clarifications are issues too!)\n  - Please search existing issues before opening a new one - it may have already been adressed.\n* Pull requests: please discuss new code in an issue first, unless the fix is really trivial.\n  - Make sure new code is tested.\n  - Be mindful of existing code - PRs that break existing code have a high probability of being declined, unless it fixes a serious issue.\n* Sponsor the developer\n  - See the Github Sponsor button at the top of the repo on github\n  - or via BuyMeACoffee.com, below\n\n<a href=\"https://www.buymeacoffee.com/mna\" target=\"_blank\"><img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me A Coffee\" style=\"height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;\" ></a>\n\n## License\n\nThe [BSD 3-Clause license][bsd], the same as the [Go language][golic]. Cascadia's license is [here][caslic].\n\n[jquery]: http://jquery.com/\n[go]: http://golang.org/\n[cascadia]: https://github.com/andybalholm/cascadia\n[cascadiacli]: https://github.com/suntong/cascadia\n[bsd]: http://opensource.org/licenses/BSD-3-Clause\n[golic]: http://golang.org/LICENSE\n[caslic]: https://github.com/andybalholm/cascadia/blob/master/LICENSE\n[doc]: https://pkg.go.dev/github.com/PuerkitoBio/goquery\n[index]: http://api.jquery.com/index/\n[gonet]: https://github.com/golang/net/\n[html]: https://pkg.go.dev/golang.org/x/net/html\n[wiki]: https://github.com/PuerkitoBio/goquery/wiki/Tips-and-tricks\n[thatguystone]: https://github.com/thatguystone\n[piotr]: https://github.com/piotrkowalczuk\n[goq]: https://github.com/andrewstuart/goq\n[thiemok]: https://github.com/thiemok\n[djw]: https://github.com/davidjwilkins\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/array.go",
    "content": "package goquery\n\nimport (\n\t\"golang.org/x/net/html\"\n)\n\nconst (\n\tmaxUint = ^uint(0)\n\tmaxInt  = int(maxUint >> 1)\n\n\t// ToEnd is a special index value that can be used as end index in a call\n\t// to Slice so that all elements are selected until the end of the Selection.\n\t// It is equivalent to passing (*Selection).Length().\n\tToEnd = maxInt\n)\n\n// First reduces the set of matched elements to the first in the set.\n// It returns a new Selection object, and an empty Selection object if the\n// the selection is empty.\nfunc (s *Selection) First() *Selection {\n\treturn s.Eq(0)\n}\n\n// Last reduces the set of matched elements to the last in the set.\n// It returns a new Selection object, and an empty Selection object if\n// the selection is empty.\nfunc (s *Selection) Last() *Selection {\n\treturn s.Eq(-1)\n}\n\n// Eq reduces the set of matched elements to the one at the specified index.\n// If a negative index is given, it counts backwards starting at the end of the\n// set. It returns a new Selection object, and an empty Selection object if the\n// index is invalid.\nfunc (s *Selection) Eq(index int) *Selection {\n\tif index < 0 {\n\t\tindex += len(s.Nodes)\n\t}\n\n\tif index >= len(s.Nodes) || index < 0 {\n\t\treturn newEmptySelection(s.document)\n\t}\n\n\treturn s.Slice(index, index+1)\n}\n\n// Slice reduces the set of matched elements to a subset specified by a range\n// of indices. The start index is 0-based and indicates the index of the first\n// element to select. The end index is 0-based and indicates the index at which\n// the elements stop being selected (the end index is not selected).\n//\n// The indices may be negative, in which case they represent an offset from the\n// end of the selection.\n//\n// The special value ToEnd may be specified as end index, in which case all elements\n// until the end are selected. This works both for a positive and negative start\n// index.\nfunc (s *Selection) Slice(start, end int) *Selection {\n\tif start < 0 {\n\t\tstart += len(s.Nodes)\n\t}\n\tif end == ToEnd {\n\t\tend = len(s.Nodes)\n\t} else if end < 0 {\n\t\tend += len(s.Nodes)\n\t}\n\treturn pushStack(s, s.Nodes[start:end])\n}\n\n// Get retrieves the underlying node at the specified index.\n// Get without parameter is not implemented, since the node array is available\n// on the Selection object.\nfunc (s *Selection) Get(index int) *html.Node {\n\tif index < 0 {\n\t\tindex += len(s.Nodes) // Negative index gets from the end\n\t}\n\treturn s.Nodes[index]\n}\n\n// Index returns the position of the first element within the Selection object\n// relative to its sibling elements.\nfunc (s *Selection) Index() int {\n\tif len(s.Nodes) > 0 {\n\t\treturn newSingleSelection(s.Nodes[0], s.document).PrevAll().Length()\n\t}\n\treturn -1\n}\n\n// IndexSelector returns the position of the first element within the\n// Selection object relative to the elements matched by the selector, or -1 if\n// not found.\nfunc (s *Selection) IndexSelector(selector string) int {\n\tif len(s.Nodes) > 0 {\n\t\tsel := s.document.Find(selector)\n\t\treturn indexInSlice(sel.Nodes, s.Nodes[0])\n\t}\n\treturn -1\n}\n\n// IndexMatcher returns the position of the first element within the\n// Selection object relative to the elements matched by the matcher, or -1 if\n// not found.\nfunc (s *Selection) IndexMatcher(m Matcher) int {\n\tif len(s.Nodes) > 0 {\n\t\tsel := s.document.FindMatcher(m)\n\t\treturn indexInSlice(sel.Nodes, s.Nodes[0])\n\t}\n\treturn -1\n}\n\n// IndexOfNode returns the position of the specified node within the Selection\n// object, or -1 if not found.\nfunc (s *Selection) IndexOfNode(node *html.Node) int {\n\treturn indexInSlice(s.Nodes, node)\n}\n\n// IndexOfSelection returns the position of the first node in the specified\n// Selection object within this Selection object, or -1 if not found.\nfunc (s *Selection) IndexOfSelection(sel *Selection) int {\n\tif sel != nil && len(sel.Nodes) > 0 {\n\t\treturn indexInSlice(s.Nodes, sel.Nodes[0])\n\t}\n\treturn -1\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/doc.go",
    "content": "// Copyright (c) 2012-2016, Martin Angers & Contributors\n// All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without modification,\n// are permitted provided that the following conditions are met:\n//\n// * Redistributions of source code must retain the above copyright notice,\n// this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above copyright notice,\n// this list of conditions and the following disclaimer in the documentation and/or\n// other materials provided with the distribution.\n// * Neither the name of the author nor the names of its contributors may be used to\n// endorse or promote products derived from this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS\n// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\n// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR\n// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n// DAMAGES (INCLUDING, 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 OF LIABILITY,\n// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY\n// WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n/*\nPackage goquery implements features similar to jQuery, including the chainable\nsyntax, to manipulate and query an HTML document.\n\nIt brings a syntax and a set of features similar to jQuery to the Go language.\nIt is based on Go's net/html package and the CSS Selector library cascadia.\nSince the net/html parser returns nodes, and not a full-featured DOM\ntree, jQuery's stateful manipulation functions (like height(), css(), detach())\nhave been left off.\n\nAlso, because the net/html parser requires UTF-8 encoding, so does goquery: it is\nthe caller's responsibility to ensure that the source document provides UTF-8 encoded HTML.\nSee the repository's wiki for various options on how to do this.\n\nSyntax-wise, it is as close as possible to jQuery, with the same method names when\npossible, and that warm and fuzzy chainable interface. jQuery being the\nultra-popular library that it is, writing a similar HTML-manipulating\nlibrary was better to follow its API than to start anew (in the same spirit as\nGo's fmt package), even though some of its methods are less than intuitive (looking\nat you, index()...).\n\nIt is hosted on GitHub, along with additional documentation in the README.md\nfile: https://github.com/puerkitobio/goquery\n\nPlease note that because of the net/html dependency, goquery requires Go1.1+.\n\nThe various methods are split into files based on the category of behavior.\nThe three dots (...) indicate that various \"overloads\" are available.\n\n* array.go : array-like positional manipulation of the selection.\n    - Eq()\n    - First()\n    - Get()\n    - Index...()\n    - Last()\n    - Slice()\n\n* expand.go : methods that expand or augment the selection's set.\n    - Add...()\n    - AndSelf()\n    - Union(), which is an alias for AddSelection()\n\n* filter.go : filtering methods, that reduce the selection's set.\n    - End()\n    - Filter...()\n    - Has...()\n    - Intersection(), which is an alias of FilterSelection()\n    - Not...()\n\n* iteration.go : methods to loop over the selection's nodes.\n    - Each()\n    - EachWithBreak()\n    - Map()\n\n* manipulation.go : methods for modifying the document\n    - After...()\n    - Append...()\n    - Before...()\n    - Clone()\n    - Empty()\n    - Prepend...()\n    - Remove...()\n    - ReplaceWith...()\n    - Unwrap()\n    - Wrap...()\n    - WrapAll...()\n    - WrapInner...()\n\n* property.go : methods that inspect and get the node's properties values.\n    - Attr*(), RemoveAttr(), SetAttr()\n    - AddClass(), HasClass(), RemoveClass(), ToggleClass()\n    - Html()\n    - Length()\n    - Size(), which is an alias for Length()\n    - Text()\n\n* query.go : methods that query, or reflect, a node's identity.\n    - Contains()\n    - Is...()\n\n* traversal.go : methods to traverse the HTML document tree.\n    - Children...()\n    - Contents()\n    - Find...()\n    - Next...()\n    - Parent[s]...()\n    - Prev...()\n    - Siblings...()\n\n* type.go : definition of the types exposed by goquery.\n    - Document\n    - Selection\n    - Matcher\n\n* utilities.go : definition of helper functions (and not methods on a *Selection)\nthat are not part of jQuery, but are useful to goquery.\n    - NodeName\n    - OuterHtml\n*/\npackage goquery\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/expand.go",
    "content": "package goquery\n\nimport \"golang.org/x/net/html\"\n\n// Add adds the selector string's matching nodes to those in the current\n// selection and returns a new Selection object.\n// The selector string is run in the context of the document of the current\n// Selection object.\nfunc (s *Selection) Add(selector string) *Selection {\n\treturn s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, compileMatcher(selector))...)\n}\n\n// AddMatcher adds the matcher's matching nodes to those in the current\n// selection and returns a new Selection object.\n// The matcher is run in the context of the document of the current\n// Selection object.\nfunc (s *Selection) AddMatcher(m Matcher) *Selection {\n\treturn s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, m)...)\n}\n\n// AddSelection adds the specified Selection object's nodes to those in the\n// current selection and returns a new Selection object.\nfunc (s *Selection) AddSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.AddNodes()\n\t}\n\treturn s.AddNodes(sel.Nodes...)\n}\n\n// Union is an alias for AddSelection.\nfunc (s *Selection) Union(sel *Selection) *Selection {\n\treturn s.AddSelection(sel)\n}\n\n// AddNodes adds the specified nodes to those in the\n// current selection and returns a new Selection object.\nfunc (s *Selection) AddNodes(nodes ...*html.Node) *Selection {\n\treturn pushStack(s, appendWithoutDuplicates(s.Nodes, nodes, nil))\n}\n\n// AndSelf adds the previous set of elements on the stack to the current set.\n// It returns a new Selection object containing the current Selection combined\n// with the previous one.\n// Deprecated: This function has been deprecated and is now an alias for AddBack().\nfunc (s *Selection) AndSelf() *Selection {\n\treturn s.AddBack()\n}\n\n// AddBack adds the previous set of elements on the stack to the current set.\n// It returns a new Selection object containing the current Selection combined\n// with the previous one.\nfunc (s *Selection) AddBack() *Selection {\n\treturn s.AddSelection(s.prevSel)\n}\n\n// AddBackFiltered reduces the previous set of elements on the stack to those that\n// match the selector string, and adds them to the current set.\n// It returns a new Selection object containing the current Selection combined\n// with the filtered previous one\nfunc (s *Selection) AddBackFiltered(selector string) *Selection {\n\treturn s.AddSelection(s.prevSel.Filter(selector))\n}\n\n// AddBackMatcher reduces the previous set of elements on the stack to those that match\n// the mateher, and adds them to the curernt set.\n// It returns a new Selection object containing the current Selection combined\n// with the filtered previous one\nfunc (s *Selection) AddBackMatcher(m Matcher) *Selection {\n\treturn s.AddSelection(s.prevSel.FilterMatcher(m))\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/filter.go",
    "content": "package goquery\n\nimport \"golang.org/x/net/html\"\n\n// Filter reduces the set of matched elements to those that match the selector string.\n// It returns a new Selection object for this subset of matching elements.\nfunc (s *Selection) Filter(selector string) *Selection {\n\treturn s.FilterMatcher(compileMatcher(selector))\n}\n\n// FilterMatcher reduces the set of matched elements to those that match\n// the given matcher. It returns a new Selection object for this subset\n// of matching elements.\nfunc (s *Selection) FilterMatcher(m Matcher) *Selection {\n\treturn pushStack(s, winnow(s, m, true))\n}\n\n// Not removes elements from the Selection that match the selector string.\n// It returns a new Selection object with the matching elements removed.\nfunc (s *Selection) Not(selector string) *Selection {\n\treturn s.NotMatcher(compileMatcher(selector))\n}\n\n// NotMatcher removes elements from the Selection that match the given matcher.\n// It returns a new Selection object with the matching elements removed.\nfunc (s *Selection) NotMatcher(m Matcher) *Selection {\n\treturn pushStack(s, winnow(s, m, false))\n}\n\n// FilterFunction reduces the set of matched elements to those that pass the function's test.\n// It returns a new Selection object for this subset of elements.\nfunc (s *Selection) FilterFunction(f func(int, *Selection) bool) *Selection {\n\treturn pushStack(s, winnowFunction(s, f, true))\n}\n\n// NotFunction removes elements from the Selection that pass the function's test.\n// It returns a new Selection object with the matching elements removed.\nfunc (s *Selection) NotFunction(f func(int, *Selection) bool) *Selection {\n\treturn pushStack(s, winnowFunction(s, f, false))\n}\n\n// FilterNodes reduces the set of matched elements to those that match the specified nodes.\n// It returns a new Selection object for this subset of elements.\nfunc (s *Selection) FilterNodes(nodes ...*html.Node) *Selection {\n\treturn pushStack(s, winnowNodes(s, nodes, true))\n}\n\n// NotNodes removes elements from the Selection that match the specified nodes.\n// It returns a new Selection object with the matching elements removed.\nfunc (s *Selection) NotNodes(nodes ...*html.Node) *Selection {\n\treturn pushStack(s, winnowNodes(s, nodes, false))\n}\n\n// FilterSelection reduces the set of matched elements to those that match a\n// node in the specified Selection object.\n// It returns a new Selection object for this subset of elements.\nfunc (s *Selection) FilterSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn pushStack(s, winnowNodes(s, nil, true))\n\t}\n\treturn pushStack(s, winnowNodes(s, sel.Nodes, true))\n}\n\n// NotSelection removes elements from the Selection that match a node in the specified\n// Selection object. It returns a new Selection object with the matching elements removed.\nfunc (s *Selection) NotSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn pushStack(s, winnowNodes(s, nil, false))\n\t}\n\treturn pushStack(s, winnowNodes(s, sel.Nodes, false))\n}\n\n// Intersection is an alias for FilterSelection.\nfunc (s *Selection) Intersection(sel *Selection) *Selection {\n\treturn s.FilterSelection(sel)\n}\n\n// Has reduces the set of matched elements to those that have a descendant\n// that matches the selector.\n// It returns a new Selection object with the matching elements.\nfunc (s *Selection) Has(selector string) *Selection {\n\treturn s.HasSelection(s.document.Find(selector))\n}\n\n// HasMatcher reduces the set of matched elements to those that have a descendant\n// that matches the matcher.\n// It returns a new Selection object with the matching elements.\nfunc (s *Selection) HasMatcher(m Matcher) *Selection {\n\treturn s.HasSelection(s.document.FindMatcher(m))\n}\n\n// HasNodes reduces the set of matched elements to those that have a\n// descendant that matches one of the nodes.\n// It returns a new Selection object with the matching elements.\nfunc (s *Selection) HasNodes(nodes ...*html.Node) *Selection {\n\treturn s.FilterFunction(func(_ int, sel *Selection) bool {\n\t\t// Add all nodes that contain one of the specified nodes\n\t\tfor _, n := range nodes {\n\t\t\tif sel.Contains(n) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t})\n}\n\n// HasSelection reduces the set of matched elements to those that have a\n// descendant that matches one of the nodes of the specified Selection object.\n// It returns a new Selection object with the matching elements.\nfunc (s *Selection) HasSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.HasNodes()\n\t}\n\treturn s.HasNodes(sel.Nodes...)\n}\n\n// End ends the most recent filtering operation in the current chain and\n// returns the set of matched elements to its previous state.\nfunc (s *Selection) End() *Selection {\n\tif s.prevSel != nil {\n\t\treturn s.prevSel\n\t}\n\treturn newEmptySelection(s.document)\n}\n\n// Filter based on the matcher, and the indicator to keep (Filter) or\n// to get rid of (Not) the matching elements.\nfunc winnow(sel *Selection, m Matcher, keep bool) []*html.Node {\n\t// Optimize if keep is requested\n\tif keep {\n\t\treturn m.Filter(sel.Nodes)\n\t}\n\t// Use grep\n\treturn grep(sel, func(i int, s *Selection) bool {\n\t\treturn !m.Match(s.Get(0))\n\t})\n}\n\n// Filter based on an array of nodes, and the indicator to keep (Filter) or\n// to get rid of (Not) the matching elements.\nfunc winnowNodes(sel *Selection, nodes []*html.Node, keep bool) []*html.Node {\n\tif len(nodes)+len(sel.Nodes) < minNodesForSet {\n\t\treturn grep(sel, func(i int, s *Selection) bool {\n\t\t\treturn isInSlice(nodes, s.Get(0)) == keep\n\t\t})\n\t}\n\n\tset := make(map[*html.Node]bool)\n\tfor _, n := range nodes {\n\t\tset[n] = true\n\t}\n\treturn grep(sel, func(i int, s *Selection) bool {\n\t\treturn set[s.Get(0)] == keep\n\t})\n}\n\n// Filter based on a function test, and the indicator to keep (Filter) or\n// to get rid of (Not) the matching elements.\nfunc winnowFunction(sel *Selection, f func(int, *Selection) bool, keep bool) []*html.Node {\n\treturn grep(sel, func(i int, s *Selection) bool {\n\t\treturn f(i, s) == keep\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/iteration.go",
    "content": "package goquery\n\n// Each iterates over a Selection object, executing a function for each\n// matched element. It returns the current Selection object. The function\n// f is called for each element in the selection with the index of the\n// element in that selection starting at 0, and a *Selection that contains\n// only that element.\nfunc (s *Selection) Each(f func(int, *Selection)) *Selection {\n\tfor i, n := range s.Nodes {\n\t\tf(i, newSingleSelection(n, s.document))\n\t}\n\treturn s\n}\n\n// EachWithBreak iterates over a Selection object, executing a function for each\n// matched element. It is identical to Each except that it is possible to break\n// out of the loop by returning false in the callback function. It returns the\n// current Selection object.\nfunc (s *Selection) EachWithBreak(f func(int, *Selection) bool) *Selection {\n\tfor i, n := range s.Nodes {\n\t\tif !f(i, newSingleSelection(n, s.document)) {\n\t\t\treturn s\n\t\t}\n\t}\n\treturn s\n}\n\n// Map passes each element in the current matched set through a function,\n// producing a slice of string holding the returned values. The function\n// f is called for each element in the selection with the index of the\n// element in that selection starting at 0, and a *Selection that contains\n// only that element.\nfunc (s *Selection) Map(f func(int, *Selection) string) (result []string) {\n\tfor i, n := range s.Nodes {\n\t\tresult = append(result, f(i, newSingleSelection(n, s.document)))\n\t}\n\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/manipulation.go",
    "content": "package goquery\n\nimport (\n\t\"strings\"\n\n\t\"golang.org/x/net/html\"\n)\n\n// After applies the selector from the root document and inserts the matched elements\n// after the elements in the set of matched elements.\n//\n// If one of the matched elements in the selection is not currently in the\n// document, it's impossible to insert nodes after it, so it will be ignored.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) After(selector string) *Selection {\n\treturn s.AfterMatcher(compileMatcher(selector))\n}\n\n// AfterMatcher applies the matcher from the root document and inserts the matched elements\n// after the elements in the set of matched elements.\n//\n// If one of the matched elements in the selection is not currently in the\n// document, it's impossible to insert nodes after it, so it will be ignored.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) AfterMatcher(m Matcher) *Selection {\n\treturn s.AfterNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// AfterSelection inserts the elements in the selection after each element in the set of matched\n// elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) AfterSelection(sel *Selection) *Selection {\n\treturn s.AfterNodes(sel.Nodes...)\n}\n\n// AfterHtml parses the html and inserts it after the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) AfterHtml(htmlStr string) *Selection {\n\treturn s.eachNodeHtml(htmlStr, true, func(node *html.Node, nodes []*html.Node) {\n\t\tnextSibling := node.NextSibling\n\t\tfor _, n := range nodes {\n\t\t\tif node.Parent != nil {\n\t\t\t\tnode.Parent.InsertBefore(n, nextSibling)\n\t\t\t}\n\t\t}\n\t})\n}\n\n// AfterNodes inserts the nodes after each element in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) AfterNodes(ns ...*html.Node) *Selection {\n\treturn s.manipulateNodes(ns, true, func(sn *html.Node, n *html.Node) {\n\t\tif sn.Parent != nil {\n\t\t\tsn.Parent.InsertBefore(n, sn.NextSibling)\n\t\t}\n\t})\n}\n\n// Append appends the elements specified by the selector to the end of each element\n// in the set of matched elements, following those rules:\n//\n// 1) The selector is applied to the root document.\n//\n// 2) Elements that are part of the document will be moved to the new location.\n//\n// 3) If there are multiple locations to append to, cloned nodes will be\n// appended to all target locations except the last one, which will be moved\n// as noted in (2).\nfunc (s *Selection) Append(selector string) *Selection {\n\treturn s.AppendMatcher(compileMatcher(selector))\n}\n\n// AppendMatcher appends the elements specified by the matcher to the end of each element\n// in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) AppendMatcher(m Matcher) *Selection {\n\treturn s.AppendNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// AppendSelection appends the elements in the selection to the end of each element\n// in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) AppendSelection(sel *Selection) *Selection {\n\treturn s.AppendNodes(sel.Nodes...)\n}\n\n// AppendHtml parses the html and appends it to the set of matched elements.\nfunc (s *Selection) AppendHtml(htmlStr string) *Selection {\n\treturn s.eachNodeHtml(htmlStr, false, func(node *html.Node, nodes []*html.Node) {\n\t\tfor _, n := range nodes {\n\t\t\tnode.AppendChild(n)\n\t\t}\n\t})\n}\n\n// AppendNodes appends the specified nodes to each node in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) AppendNodes(ns ...*html.Node) *Selection {\n\treturn s.manipulateNodes(ns, false, func(sn *html.Node, n *html.Node) {\n\t\tsn.AppendChild(n)\n\t})\n}\n\n// Before inserts the matched elements before each element in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) Before(selector string) *Selection {\n\treturn s.BeforeMatcher(compileMatcher(selector))\n}\n\n// BeforeMatcher inserts the matched elements before each element in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) BeforeMatcher(m Matcher) *Selection {\n\treturn s.BeforeNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// BeforeSelection inserts the elements in the selection before each element in the set of matched\n// elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) BeforeSelection(sel *Selection) *Selection {\n\treturn s.BeforeNodes(sel.Nodes...)\n}\n\n// BeforeHtml parses the html and inserts it before the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) BeforeHtml(htmlStr string) *Selection {\n\treturn s.eachNodeHtml(htmlStr, true, func(node *html.Node, nodes []*html.Node) {\n\t\tfor _, n := range nodes {\n\t\t\tif node.Parent != nil {\n\t\t\t\tnode.Parent.InsertBefore(n, node)\n\t\t\t}\n\t\t}\n\t})\n}\n\n// BeforeNodes inserts the nodes before each element in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) BeforeNodes(ns ...*html.Node) *Selection {\n\treturn s.manipulateNodes(ns, false, func(sn *html.Node, n *html.Node) {\n\t\tif sn.Parent != nil {\n\t\t\tsn.Parent.InsertBefore(n, sn)\n\t\t}\n\t})\n}\n\n// Clone creates a deep copy of the set of matched nodes. The new nodes will not be\n// attached to the document.\nfunc (s *Selection) Clone() *Selection {\n\tns := newEmptySelection(s.document)\n\tns.Nodes = cloneNodes(s.Nodes)\n\treturn ns\n}\n\n// Empty removes all children nodes from the set of matched elements.\n// It returns the children nodes in a new Selection.\nfunc (s *Selection) Empty() *Selection {\n\tvar nodes []*html.Node\n\n\tfor _, n := range s.Nodes {\n\t\tfor c := n.FirstChild; c != nil; c = n.FirstChild {\n\t\t\tn.RemoveChild(c)\n\t\t\tnodes = append(nodes, c)\n\t\t}\n\t}\n\n\treturn pushStack(s, nodes)\n}\n\n// Prepend prepends the elements specified by the selector to each element in\n// the set of matched elements, following the same rules as Append.\nfunc (s *Selection) Prepend(selector string) *Selection {\n\treturn s.PrependMatcher(compileMatcher(selector))\n}\n\n// PrependMatcher prepends the elements specified by the matcher to each\n// element in the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) PrependMatcher(m Matcher) *Selection {\n\treturn s.PrependNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// PrependSelection prepends the elements in the selection to each element in\n// the set of matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) PrependSelection(sel *Selection) *Selection {\n\treturn s.PrependNodes(sel.Nodes...)\n}\n\n// PrependHtml parses the html and prepends it to the set of matched elements.\nfunc (s *Selection) PrependHtml(htmlStr string) *Selection {\n\treturn s.eachNodeHtml(htmlStr, false, func(node *html.Node, nodes []*html.Node) {\n\t\tfirstChild := node.FirstChild\n\t\tfor _, n := range nodes {\n\t\t\tnode.InsertBefore(n, firstChild)\n\t\t}\n\t})\n}\n\n// PrependNodes prepends the specified nodes to each node in the set of\n// matched elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) PrependNodes(ns ...*html.Node) *Selection {\n\treturn s.manipulateNodes(ns, true, func(sn *html.Node, n *html.Node) {\n\t\t// sn.FirstChild may be nil, in which case this functions like\n\t\t// sn.AppendChild()\n\t\tsn.InsertBefore(n, sn.FirstChild)\n\t})\n}\n\n// Remove removes the set of matched elements from the document.\n// It returns the same selection, now consisting of nodes not in the document.\nfunc (s *Selection) Remove() *Selection {\n\tfor _, n := range s.Nodes {\n\t\tif n.Parent != nil {\n\t\t\tn.Parent.RemoveChild(n)\n\t\t}\n\t}\n\n\treturn s\n}\n\n// RemoveFiltered removes from the current set of matched elements those that\n// match the selector filter. It returns the Selection of removed nodes.\n//\n// For example if the selection s contains \"<h1>\", \"<h2>\" and \"<h3>\"\n// and s.RemoveFiltered(\"h2\") is called, only the \"<h2>\" node is removed\n// (and returned), while \"<h1>\" and \"<h3>\" are kept in the document.\nfunc (s *Selection) RemoveFiltered(selector string) *Selection {\n\treturn s.RemoveMatcher(compileMatcher(selector))\n}\n\n// RemoveMatcher removes from the current set of matched elements those that\n// match the Matcher filter. It returns the Selection of removed nodes.\n// See RemoveFiltered for additional information.\nfunc (s *Selection) RemoveMatcher(m Matcher) *Selection {\n\treturn s.FilterMatcher(m).Remove()\n}\n\n// ReplaceWith replaces each element in the set of matched elements with the\n// nodes matched by the given selector.\n// It returns the removed elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) ReplaceWith(selector string) *Selection {\n\treturn s.ReplaceWithMatcher(compileMatcher(selector))\n}\n\n// ReplaceWithMatcher replaces each element in the set of matched elements with\n// the nodes matched by the given Matcher.\n// It returns the removed elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) ReplaceWithMatcher(m Matcher) *Selection {\n\treturn s.ReplaceWithNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// ReplaceWithSelection replaces each element in the set of matched elements with\n// the nodes from the given Selection.\n// It returns the removed elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) ReplaceWithSelection(sel *Selection) *Selection {\n\treturn s.ReplaceWithNodes(sel.Nodes...)\n}\n\n// ReplaceWithHtml replaces each element in the set of matched elements with\n// the parsed HTML.\n// It returns the removed elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) ReplaceWithHtml(htmlStr string) *Selection {\n\ts.eachNodeHtml(htmlStr, true, func(node *html.Node, nodes []*html.Node) {\n\t\tnextSibling := node.NextSibling\n\t\tfor _, n := range nodes {\n\t\t\tif node.Parent != nil {\n\t\t\t\tnode.Parent.InsertBefore(n, nextSibling)\n\t\t\t}\n\t\t}\n\t})\n\treturn s.Remove()\n}\n\n// ReplaceWithNodes replaces each element in the set of matched elements with\n// the given nodes.\n// It returns the removed elements.\n//\n// This follows the same rules as Selection.Append.\nfunc (s *Selection) ReplaceWithNodes(ns ...*html.Node) *Selection {\n\ts.AfterNodes(ns...)\n\treturn s.Remove()\n}\n\n// SetHtml sets the html content of each element in the selection to\n// specified html string.\nfunc (s *Selection) SetHtml(htmlStr string) *Selection {\n\tfor _, context := range s.Nodes {\n\t\tfor c := context.FirstChild; c != nil; c = context.FirstChild {\n\t\t\tcontext.RemoveChild(c)\n\t\t}\n\t}\n\treturn s.eachNodeHtml(htmlStr, false, func(node *html.Node, nodes []*html.Node) {\n\t\tfor _, n := range nodes {\n\t\t\tnode.AppendChild(n)\n\t\t}\n\t})\n}\n\n// SetText sets the content of each element in the selection to specified content.\n// The provided text string is escaped.\nfunc (s *Selection) SetText(text string) *Selection {\n\treturn s.SetHtml(html.EscapeString(text))\n}\n\n// Unwrap removes the parents of the set of matched elements, leaving the matched\n// elements (and their siblings, if any) in their place.\n// It returns the original selection.\nfunc (s *Selection) Unwrap() *Selection {\n\ts.Parent().Each(func(i int, ss *Selection) {\n\t\t// For some reason, jquery allows unwrap to remove the <head> element, so\n\t\t// allowing it here too. Same for <html>. Why it allows those elements to\n\t\t// be unwrapped while not allowing body is a mystery to me.\n\t\tif ss.Nodes[0].Data != \"body\" {\n\t\t\tss.ReplaceWithSelection(ss.Contents())\n\t\t}\n\t})\n\n\treturn s\n}\n\n// Wrap wraps each element in the set of matched elements inside the first\n// element matched by the given selector. The matched child is cloned before\n// being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) Wrap(selector string) *Selection {\n\treturn s.WrapMatcher(compileMatcher(selector))\n}\n\n// WrapMatcher wraps each element in the set of matched elements inside the\n// first element matched by the given matcher. The matched child is cloned\n// before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapMatcher(m Matcher) *Selection {\n\treturn s.wrapNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// WrapSelection wraps each element in the set of matched elements inside the\n// first element in the given Selection. The element is cloned before being\n// inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapSelection(sel *Selection) *Selection {\n\treturn s.wrapNodes(sel.Nodes...)\n}\n\n// WrapHtml wraps each element in the set of matched elements inside the inner-\n// most child of the given HTML.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapHtml(htmlStr string) *Selection {\n\tnodesMap := make(map[string][]*html.Node)\n\tfor _, context := range s.Nodes {\n\t\tvar parent *html.Node\n\t\tif context.Parent != nil {\n\t\t\tparent = context.Parent\n\t\t} else {\n\t\t\tparent = &html.Node{Type: html.ElementNode}\n\t\t}\n\t\tnodes, found := nodesMap[nodeName(parent)]\n\t\tif !found {\n\t\t\tnodes = parseHtmlWithContext(htmlStr, parent)\n\t\t\tnodesMap[nodeName(parent)] = nodes\n\t\t}\n\t\tnewSingleSelection(context, s.document).wrapAllNodes(cloneNodes(nodes)...)\n\t}\n\treturn s\n}\n\n// WrapNode wraps each element in the set of matched elements inside the inner-\n// most child of the given node. The given node is copied before being inserted\n// into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapNode(n *html.Node) *Selection {\n\treturn s.wrapNodes(n)\n}\n\nfunc (s *Selection) wrapNodes(ns ...*html.Node) *Selection {\n\ts.Each(func(i int, ss *Selection) {\n\t\tss.wrapAllNodes(ns...)\n\t})\n\n\treturn s\n}\n\n// WrapAll wraps a single HTML structure, matched by the given selector, around\n// all elements in the set of matched elements. The matched child is cloned\n// before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapAll(selector string) *Selection {\n\treturn s.WrapAllMatcher(compileMatcher(selector))\n}\n\n// WrapAllMatcher wraps a single HTML structure, matched by the given Matcher,\n// around all elements in the set of matched elements. The matched child is\n// cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapAllMatcher(m Matcher) *Selection {\n\treturn s.wrapAllNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// WrapAllSelection wraps a single HTML structure, the first node of the given\n// Selection, around all elements in the set of matched elements. The matched\n// child is cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapAllSelection(sel *Selection) *Selection {\n\treturn s.wrapAllNodes(sel.Nodes...)\n}\n\n// WrapAllHtml wraps the given HTML structure around all elements in the set of\n// matched elements. The matched child is cloned before being inserted into the\n// document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapAllHtml(htmlStr string) *Selection {\n\tvar context *html.Node\n\tvar nodes []*html.Node\n\tif len(s.Nodes) > 0 {\n\t\tcontext = s.Nodes[0]\n\t\tif context.Parent != nil {\n\t\t\tnodes = parseHtmlWithContext(htmlStr, context)\n\t\t} else {\n\t\t\tnodes = parseHtml(htmlStr)\n\t\t}\n\t}\n\treturn s.wrapAllNodes(nodes...)\n}\n\nfunc (s *Selection) wrapAllNodes(ns ...*html.Node) *Selection {\n\tif len(ns) > 0 {\n\t\treturn s.WrapAllNode(ns[0])\n\t}\n\treturn s\n}\n\n// WrapAllNode wraps the given node around the first element in the Selection,\n// making all other nodes in the Selection children of the given node. The node\n// is cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapAllNode(n *html.Node) *Selection {\n\tif s.Size() == 0 {\n\t\treturn s\n\t}\n\n\twrap := cloneNode(n)\n\n\tfirst := s.Nodes[0]\n\tif first.Parent != nil {\n\t\tfirst.Parent.InsertBefore(wrap, first)\n\t\tfirst.Parent.RemoveChild(first)\n\t}\n\n\tfor c := getFirstChildEl(wrap); c != nil; c = getFirstChildEl(wrap) {\n\t\twrap = c\n\t}\n\n\tnewSingleSelection(wrap, s.document).AppendSelection(s)\n\n\treturn s\n}\n\n// WrapInner wraps an HTML structure, matched by the given selector, around the\n// content of element in the set of matched elements. The matched child is\n// cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapInner(selector string) *Selection {\n\treturn s.WrapInnerMatcher(compileMatcher(selector))\n}\n\n// WrapInnerMatcher wraps an HTML structure, matched by the given selector,\n// around the content of element in the set of matched elements. The matched\n// child is cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapInnerMatcher(m Matcher) *Selection {\n\treturn s.wrapInnerNodes(m.MatchAll(s.document.rootNode)...)\n}\n\n// WrapInnerSelection wraps an HTML structure, matched by the given selector,\n// around the content of element in the set of matched elements. The matched\n// child is cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapInnerSelection(sel *Selection) *Selection {\n\treturn s.wrapInnerNodes(sel.Nodes...)\n}\n\n// WrapInnerHtml wraps an HTML structure, matched by the given selector, around\n// the content of element in the set of matched elements. The matched child is\n// cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapInnerHtml(htmlStr string) *Selection {\n\tnodesMap := make(map[string][]*html.Node)\n\tfor _, context := range s.Nodes {\n\t\tnodes, found := nodesMap[nodeName(context)]\n\t\tif !found {\n\t\t\tnodes = parseHtmlWithContext(htmlStr, context)\n\t\t\tnodesMap[nodeName(context)] = nodes\n\t\t}\n\t\tnewSingleSelection(context, s.document).wrapInnerNodes(cloneNodes(nodes)...)\n\t}\n\treturn s\n}\n\n// WrapInnerNode wraps an HTML structure, matched by the given selector, around\n// the content of element in the set of matched elements. The matched child is\n// cloned before being inserted into the document.\n//\n// It returns the original set of elements.\nfunc (s *Selection) WrapInnerNode(n *html.Node) *Selection {\n\treturn s.wrapInnerNodes(n)\n}\n\nfunc (s *Selection) wrapInnerNodes(ns ...*html.Node) *Selection {\n\tif len(ns) == 0 {\n\t\treturn s\n\t}\n\n\ts.Each(func(i int, s *Selection) {\n\t\tcontents := s.Contents()\n\n\t\tif contents.Size() > 0 {\n\t\t\tcontents.wrapAllNodes(ns...)\n\t\t} else {\n\t\t\ts.AppendNodes(cloneNode(ns[0]))\n\t\t}\n\t})\n\n\treturn s\n}\n\nfunc parseHtml(h string) []*html.Node {\n\t// Errors are only returned when the io.Reader returns any error besides\n\t// EOF, but strings.Reader never will\n\tnodes, err := html.ParseFragment(strings.NewReader(h), &html.Node{Type: html.ElementNode})\n\tif err != nil {\n\t\tpanic(\"goquery: failed to parse HTML: \" + err.Error())\n\t}\n\treturn nodes\n}\n\nfunc parseHtmlWithContext(h string, context *html.Node) []*html.Node {\n\t// Errors are only returned when the io.Reader returns any error besides\n\t// EOF, but strings.Reader never will\n\tnodes, err := html.ParseFragment(strings.NewReader(h), context)\n\tif err != nil {\n\t\tpanic(\"goquery: failed to parse HTML: \" + err.Error())\n\t}\n\treturn nodes\n}\n\n// Get the first child that is an ElementNode\nfunc getFirstChildEl(n *html.Node) *html.Node {\n\tc := n.FirstChild\n\tfor c != nil && c.Type != html.ElementNode {\n\t\tc = c.NextSibling\n\t}\n\treturn c\n}\n\n// Deep copy a slice of nodes.\nfunc cloneNodes(ns []*html.Node) []*html.Node {\n\tcns := make([]*html.Node, 0, len(ns))\n\n\tfor _, n := range ns {\n\t\tcns = append(cns, cloneNode(n))\n\t}\n\n\treturn cns\n}\n\n// Deep copy a node. The new node has clones of all the original node's\n// children but none of its parents or siblings.\nfunc cloneNode(n *html.Node) *html.Node {\n\tnn := &html.Node{\n\t\tType:     n.Type,\n\t\tDataAtom: n.DataAtom,\n\t\tData:     n.Data,\n\t\tAttr:     make([]html.Attribute, len(n.Attr)),\n\t}\n\n\tcopy(nn.Attr, n.Attr)\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tnn.AppendChild(cloneNode(c))\n\t}\n\n\treturn nn\n}\n\nfunc (s *Selection) manipulateNodes(ns []*html.Node, reverse bool,\n\tf func(sn *html.Node, n *html.Node)) *Selection {\n\n\tlasti := s.Size() - 1\n\n\t// net.Html doesn't provide document fragments for insertion, so to get\n\t// things in the correct order with After() and Prepend(), the callback\n\t// needs to be called on the reverse of the nodes.\n\tif reverse {\n\t\tfor i, j := 0, len(ns)-1; i < j; i, j = i+1, j-1 {\n\t\t\tns[i], ns[j] = ns[j], ns[i]\n\t\t}\n\t}\n\n\tfor i, sn := range s.Nodes {\n\t\tfor _, n := range ns {\n\t\t\tif i != lasti {\n\t\t\t\tf(sn, cloneNode(n))\n\t\t\t} else {\n\t\t\t\tif n.Parent != nil {\n\t\t\t\t\tn.Parent.RemoveChild(n)\n\t\t\t\t}\n\t\t\t\tf(sn, n)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn s\n}\n\n// eachNodeHtml parses the given html string and inserts the resulting nodes in the dom with the mergeFn.\n// The parsed nodes are inserted for each element of the selection.\n// isParent can be used to indicate that the elements of the selection should be treated as the parent for the parsed html.\n// A cache is used to avoid parsing the html multiple times should the elements of the selection result in the same context.\nfunc (s *Selection) eachNodeHtml(htmlStr string, isParent bool, mergeFn func(n *html.Node, nodes []*html.Node)) *Selection {\n\t// cache to avoid parsing the html for the same context multiple times\n\tnodeCache := make(map[string][]*html.Node)\n\tvar context *html.Node\n\tfor _, n := range s.Nodes {\n\t\tif isParent {\n\t\t\tcontext = n.Parent\n\t\t} else {\n\t\t\tif n.Type != html.ElementNode {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcontext = n\n\t\t}\n\t\tif context != nil {\n\t\t\tnodes, found := nodeCache[nodeName(context)]\n\t\t\tif !found {\n\t\t\t\tnodes = parseHtmlWithContext(htmlStr, context)\n\t\t\t\tnodeCache[nodeName(context)] = nodes\n\t\t\t}\n\t\t\tmergeFn(n, cloneNodes(nodes))\n\t\t}\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/property.go",
    "content": "package goquery\n\nimport (\n\t\"bytes\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"golang.org/x/net/html\"\n)\n\nvar rxClassTrim = regexp.MustCompile(\"[\\t\\r\\n]\")\n\n// Attr gets the specified attribute's value for the first element in the\n// Selection. To get the value for each element individually, use a looping\n// construct such as Each or Map method.\nfunc (s *Selection) Attr(attrName string) (val string, exists bool) {\n\tif len(s.Nodes) == 0 {\n\t\treturn\n\t}\n\treturn getAttributeValue(attrName, s.Nodes[0])\n}\n\n// AttrOr works like Attr but returns default value if attribute is not present.\nfunc (s *Selection) AttrOr(attrName, defaultValue string) string {\n\tif len(s.Nodes) == 0 {\n\t\treturn defaultValue\n\t}\n\n\tval, exists := getAttributeValue(attrName, s.Nodes[0])\n\tif !exists {\n\t\treturn defaultValue\n\t}\n\n\treturn val\n}\n\n// RemoveAttr removes the named attribute from each element in the set of matched elements.\nfunc (s *Selection) RemoveAttr(attrName string) *Selection {\n\tfor _, n := range s.Nodes {\n\t\tremoveAttr(n, attrName)\n\t}\n\n\treturn s\n}\n\n// SetAttr sets the given attribute on each element in the set of matched elements.\nfunc (s *Selection) SetAttr(attrName, val string) *Selection {\n\tfor _, n := range s.Nodes {\n\t\tattr := getAttributePtr(attrName, n)\n\t\tif attr == nil {\n\t\t\tn.Attr = append(n.Attr, html.Attribute{Key: attrName, Val: val})\n\t\t} else {\n\t\t\tattr.Val = val\n\t\t}\n\t}\n\n\treturn s\n}\n\n// Text gets the combined text contents of each element in the set of matched\n// elements, including their descendants.\nfunc (s *Selection) Text() string {\n\tvar buf bytes.Buffer\n\n\t// Slightly optimized vs calling Each: no single selection object created\n\tvar f func(*html.Node)\n\tf = func(n *html.Node) {\n\t\tif n.Type == html.TextNode {\n\t\t\t// Keep newlines and spaces, like jQuery\n\t\t\tbuf.WriteString(n.Data)\n\t\t}\n\t\tif n.FirstChild != nil {\n\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\tf(c)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, n := range s.Nodes {\n\t\tf(n)\n\t}\n\n\treturn buf.String()\n}\n\n// Size is an alias for Length.\nfunc (s *Selection) Size() int {\n\treturn s.Length()\n}\n\n// Length returns the number of elements in the Selection object.\nfunc (s *Selection) Length() int {\n\treturn len(s.Nodes)\n}\n\n// Html gets the HTML contents of the first element in the set of matched\n// elements. It includes text and comment nodes.\nfunc (s *Selection) Html() (ret string, e error) {\n\t// Since there is no .innerHtml, the HTML content must be re-created from\n\t// the nodes using html.Render.\n\tvar buf bytes.Buffer\n\n\tif len(s.Nodes) > 0 {\n\t\tfor c := s.Nodes[0].FirstChild; c != nil; c = c.NextSibling {\n\t\t\te = html.Render(&buf, c)\n\t\t\tif e != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tret = buf.String()\n\t}\n\n\treturn\n}\n\n// AddClass adds the given class(es) to each element in the set of matched elements.\n// Multiple class names can be specified, separated by a space or via multiple arguments.\nfunc (s *Selection) AddClass(class ...string) *Selection {\n\tclassStr := strings.TrimSpace(strings.Join(class, \" \"))\n\n\tif classStr == \"\" {\n\t\treturn s\n\t}\n\n\ttcls := getClassesSlice(classStr)\n\tfor _, n := range s.Nodes {\n\t\tcurClasses, attr := getClassesAndAttr(n, true)\n\t\tfor _, newClass := range tcls {\n\t\t\tif !strings.Contains(curClasses, \" \"+newClass+\" \") {\n\t\t\t\tcurClasses += newClass + \" \"\n\t\t\t}\n\t\t}\n\n\t\tsetClasses(n, attr, curClasses)\n\t}\n\n\treturn s\n}\n\n// HasClass determines whether any of the matched elements are assigned the\n// given class.\nfunc (s *Selection) HasClass(class string) bool {\n\tclass = \" \" + class + \" \"\n\tfor _, n := range s.Nodes {\n\t\tclasses, _ := getClassesAndAttr(n, false)\n\t\tif strings.Contains(classes, class) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// RemoveClass removes the given class(es) from each element in the set of matched elements.\n// Multiple class names can be specified, separated by a space or via multiple arguments.\n// If no class name is provided, all classes are removed.\nfunc (s *Selection) RemoveClass(class ...string) *Selection {\n\tvar rclasses []string\n\n\tclassStr := strings.TrimSpace(strings.Join(class, \" \"))\n\tremove := classStr == \"\"\n\n\tif !remove {\n\t\trclasses = getClassesSlice(classStr)\n\t}\n\n\tfor _, n := range s.Nodes {\n\t\tif remove {\n\t\t\tremoveAttr(n, \"class\")\n\t\t} else {\n\t\t\tclasses, attr := getClassesAndAttr(n, true)\n\t\t\tfor _, rcl := range rclasses {\n\t\t\t\tclasses = strings.Replace(classes, \" \"+rcl+\" \", \" \", -1)\n\t\t\t}\n\n\t\t\tsetClasses(n, attr, classes)\n\t\t}\n\t}\n\n\treturn s\n}\n\n// ToggleClass adds or removes the given class(es) for each element in the set of matched elements.\n// Multiple class names can be specified, separated by a space or via multiple arguments.\nfunc (s *Selection) ToggleClass(class ...string) *Selection {\n\tclassStr := strings.TrimSpace(strings.Join(class, \" \"))\n\n\tif classStr == \"\" {\n\t\treturn s\n\t}\n\n\ttcls := getClassesSlice(classStr)\n\n\tfor _, n := range s.Nodes {\n\t\tclasses, attr := getClassesAndAttr(n, true)\n\t\tfor _, tcl := range tcls {\n\t\t\tif strings.Contains(classes, \" \"+tcl+\" \") {\n\t\t\t\tclasses = strings.Replace(classes, \" \"+tcl+\" \", \" \", -1)\n\t\t\t} else {\n\t\t\t\tclasses += tcl + \" \"\n\t\t\t}\n\t\t}\n\n\t\tsetClasses(n, attr, classes)\n\t}\n\n\treturn s\n}\n\nfunc getAttributePtr(attrName string, n *html.Node) *html.Attribute {\n\tif n == nil {\n\t\treturn nil\n\t}\n\n\tfor i, a := range n.Attr {\n\t\tif a.Key == attrName {\n\t\t\treturn &n.Attr[i]\n\t\t}\n\t}\n\treturn nil\n}\n\n// Private function to get the specified attribute's value from a node.\nfunc getAttributeValue(attrName string, n *html.Node) (val string, exists bool) {\n\tif a := getAttributePtr(attrName, n); a != nil {\n\t\tval = a.Val\n\t\texists = true\n\t}\n\treturn\n}\n\n// Get and normalize the \"class\" attribute from the node.\nfunc getClassesAndAttr(n *html.Node, create bool) (classes string, attr *html.Attribute) {\n\t// Applies only to element nodes\n\tif n.Type == html.ElementNode {\n\t\tattr = getAttributePtr(\"class\", n)\n\t\tif attr == nil && create {\n\t\t\tn.Attr = append(n.Attr, html.Attribute{\n\t\t\t\tKey: \"class\",\n\t\t\t\tVal: \"\",\n\t\t\t})\n\t\t\tattr = &n.Attr[len(n.Attr)-1]\n\t\t}\n\t}\n\n\tif attr == nil {\n\t\tclasses = \" \"\n\t} else {\n\t\tclasses = rxClassTrim.ReplaceAllString(\" \"+attr.Val+\" \", \" \")\n\t}\n\n\treturn\n}\n\nfunc getClassesSlice(classes string) []string {\n\treturn strings.Split(rxClassTrim.ReplaceAllString(\" \"+classes+\" \", \" \"), \" \")\n}\n\nfunc removeAttr(n *html.Node, attrName string) {\n\tfor i, a := range n.Attr {\n\t\tif a.Key == attrName {\n\t\t\tn.Attr[i], n.Attr[len(n.Attr)-1], n.Attr =\n\t\t\t\tn.Attr[len(n.Attr)-1], html.Attribute{}, n.Attr[:len(n.Attr)-1]\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc setClasses(n *html.Node, attr *html.Attribute, classes string) {\n\tclasses = strings.TrimSpace(classes)\n\tif classes == \"\" {\n\t\tremoveAttr(n, \"class\")\n\t\treturn\n\t}\n\n\tattr.Val = classes\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/query.go",
    "content": "package goquery\n\nimport \"golang.org/x/net/html\"\n\n// Is checks the current matched set of elements against a selector and\n// returns true if at least one of these elements matches.\nfunc (s *Selection) Is(selector string) bool {\n\treturn s.IsMatcher(compileMatcher(selector))\n}\n\n// IsMatcher checks the current matched set of elements against a matcher and\n// returns true if at least one of these elements matches.\nfunc (s *Selection) IsMatcher(m Matcher) bool {\n\tif len(s.Nodes) > 0 {\n\t\tif len(s.Nodes) == 1 {\n\t\t\treturn m.Match(s.Nodes[0])\n\t\t}\n\t\treturn len(m.Filter(s.Nodes)) > 0\n\t}\n\n\treturn false\n}\n\n// IsFunction checks the current matched set of elements against a predicate and\n// returns true if at least one of these elements matches.\nfunc (s *Selection) IsFunction(f func(int, *Selection) bool) bool {\n\treturn s.FilterFunction(f).Length() > 0\n}\n\n// IsSelection checks the current matched set of elements against a Selection object\n// and returns true if at least one of these elements matches.\nfunc (s *Selection) IsSelection(sel *Selection) bool {\n\treturn s.FilterSelection(sel).Length() > 0\n}\n\n// IsNodes checks the current matched set of elements against the specified nodes\n// and returns true if at least one of these elements matches.\nfunc (s *Selection) IsNodes(nodes ...*html.Node) bool {\n\treturn s.FilterNodes(nodes...).Length() > 0\n}\n\n// Contains returns true if the specified Node is within,\n// at any depth, one of the nodes in the Selection object.\n// It is NOT inclusive, to behave like jQuery's implementation, and\n// unlike Javascript's .contains, so if the contained\n// node is itself in the selection, it returns false.\nfunc (s *Selection) Contains(n *html.Node) bool {\n\treturn sliceContains(s.Nodes, n)\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/traversal.go",
    "content": "package goquery\n\nimport \"golang.org/x/net/html\"\n\ntype siblingType int\n\n// Sibling type, used internally when iterating over children at the same\n// level (siblings) to specify which nodes are requested.\nconst (\n\tsiblingPrevUntil siblingType = iota - 3\n\tsiblingPrevAll\n\tsiblingPrev\n\tsiblingAll\n\tsiblingNext\n\tsiblingNextAll\n\tsiblingNextUntil\n\tsiblingAllIncludingNonElements\n)\n\n// Find gets the descendants of each element in the current set of matched\n// elements, filtered by a selector. It returns a new Selection object\n// containing these matched elements.\nfunc (s *Selection) Find(selector string) *Selection {\n\treturn pushStack(s, findWithMatcher(s.Nodes, compileMatcher(selector)))\n}\n\n// FindMatcher gets the descendants of each element in the current set of matched\n// elements, filtered by the matcher. It returns a new Selection object\n// containing these matched elements.\nfunc (s *Selection) FindMatcher(m Matcher) *Selection {\n\treturn pushStack(s, findWithMatcher(s.Nodes, m))\n}\n\n// FindSelection gets the descendants of each element in the current\n// Selection, filtered by a Selection. It returns a new Selection object\n// containing these matched elements.\nfunc (s *Selection) FindSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn pushStack(s, nil)\n\t}\n\treturn s.FindNodes(sel.Nodes...)\n}\n\n// FindNodes gets the descendants of each element in the current\n// Selection, filtered by some nodes. It returns a new Selection object\n// containing these matched elements.\nfunc (s *Selection) FindNodes(nodes ...*html.Node) *Selection {\n\treturn pushStack(s, mapNodes(nodes, func(i int, n *html.Node) []*html.Node {\n\t\tif sliceContains(s.Nodes, n) {\n\t\t\treturn []*html.Node{n}\n\t\t}\n\t\treturn nil\n\t}))\n}\n\n// Contents gets the children of each element in the Selection,\n// including text and comment nodes. It returns a new Selection object\n// containing these elements.\nfunc (s *Selection) Contents() *Selection {\n\treturn pushStack(s, getChildrenNodes(s.Nodes, siblingAllIncludingNonElements))\n}\n\n// ContentsFiltered gets the children of each element in the Selection,\n// filtered by the specified selector. It returns a new Selection\n// object containing these elements. Since selectors only act on Element nodes,\n// this function is an alias to ChildrenFiltered unless the selector is empty,\n// in which case it is an alias to Contents.\nfunc (s *Selection) ContentsFiltered(selector string) *Selection {\n\tif selector != \"\" {\n\t\treturn s.ChildrenFiltered(selector)\n\t}\n\treturn s.Contents()\n}\n\n// ContentsMatcher gets the children of each element in the Selection,\n// filtered by the specified matcher. It returns a new Selection\n// object containing these elements. Since matchers only act on Element nodes,\n// this function is an alias to ChildrenMatcher.\nfunc (s *Selection) ContentsMatcher(m Matcher) *Selection {\n\treturn s.ChildrenMatcher(m)\n}\n\n// Children gets the child elements of each element in the Selection.\n// It returns a new Selection object containing these elements.\nfunc (s *Selection) Children() *Selection {\n\treturn pushStack(s, getChildrenNodes(s.Nodes, siblingAll))\n}\n\n// ChildrenFiltered gets the child elements of each element in the Selection,\n// filtered by the specified selector. It returns a new\n// Selection object containing these elements.\nfunc (s *Selection) ChildrenFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), compileMatcher(selector))\n}\n\n// ChildrenMatcher gets the child elements of each element in the Selection,\n// filtered by the specified matcher. It returns a new\n// Selection object containing these elements.\nfunc (s *Selection) ChildrenMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), m)\n}\n\n// Parent gets the parent of each element in the Selection. It returns a\n// new Selection object containing the matched elements.\nfunc (s *Selection) Parent() *Selection {\n\treturn pushStack(s, getParentNodes(s.Nodes))\n}\n\n// ParentFiltered gets the parent of each element in the Selection filtered by a\n// selector. It returns a new Selection object containing the matched elements.\nfunc (s *Selection) ParentFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getParentNodes(s.Nodes), compileMatcher(selector))\n}\n\n// ParentMatcher gets the parent of each element in the Selection filtered by a\n// matcher. It returns a new Selection object containing the matched elements.\nfunc (s *Selection) ParentMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getParentNodes(s.Nodes), m)\n}\n\n// Closest gets the first element that matches the selector by testing the\n// element itself and traversing up through its ancestors in the DOM tree.\nfunc (s *Selection) Closest(selector string) *Selection {\n\tcs := compileMatcher(selector)\n\treturn s.ClosestMatcher(cs)\n}\n\n// ClosestMatcher gets the first element that matches the matcher by testing the\n// element itself and traversing up through its ancestors in the DOM tree.\nfunc (s *Selection) ClosestMatcher(m Matcher) *Selection {\n\treturn pushStack(s, mapNodes(s.Nodes, func(i int, n *html.Node) []*html.Node {\n\t\t// For each node in the selection, test the node itself, then each parent\n\t\t// until a match is found.\n\t\tfor ; n != nil; n = n.Parent {\n\t\t\tif m.Match(n) {\n\t\t\t\treturn []*html.Node{n}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}))\n}\n\n// ClosestNodes gets the first element that matches one of the nodes by testing the\n// element itself and traversing up through its ancestors in the DOM tree.\nfunc (s *Selection) ClosestNodes(nodes ...*html.Node) *Selection {\n\tset := make(map[*html.Node]bool)\n\tfor _, n := range nodes {\n\t\tset[n] = true\n\t}\n\treturn pushStack(s, mapNodes(s.Nodes, func(i int, n *html.Node) []*html.Node {\n\t\t// For each node in the selection, test the node itself, then each parent\n\t\t// until a match is found.\n\t\tfor ; n != nil; n = n.Parent {\n\t\t\tif set[n] {\n\t\t\t\treturn []*html.Node{n}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}))\n}\n\n// ClosestSelection gets the first element that matches one of the nodes in the\n// Selection by testing the element itself and traversing up through its ancestors\n// in the DOM tree.\nfunc (s *Selection) ClosestSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn pushStack(s, nil)\n\t}\n\treturn s.ClosestNodes(sel.Nodes...)\n}\n\n// Parents gets the ancestors of each element in the current Selection. It\n// returns a new Selection object with the matched elements.\nfunc (s *Selection) Parents() *Selection {\n\treturn pushStack(s, getParentsNodes(s.Nodes, nil, nil))\n}\n\n// ParentsFiltered gets the ancestors of each element in the current\n// Selection. It returns a new Selection object with the matched elements.\nfunc (s *Selection) ParentsFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), compileMatcher(selector))\n}\n\n// ParentsMatcher gets the ancestors of each element in the current\n// Selection. It returns a new Selection object with the matched elements.\nfunc (s *Selection) ParentsMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), m)\n}\n\n// ParentsUntil gets the ancestors of each element in the Selection, up to but\n// not including the element matched by the selector. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) ParentsUntil(selector string) *Selection {\n\treturn pushStack(s, getParentsNodes(s.Nodes, compileMatcher(selector), nil))\n}\n\n// ParentsUntilMatcher gets the ancestors of each element in the Selection, up to but\n// not including the element matched by the matcher. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) ParentsUntilMatcher(m Matcher) *Selection {\n\treturn pushStack(s, getParentsNodes(s.Nodes, m, nil))\n}\n\n// ParentsUntilSelection gets the ancestors of each element in the Selection,\n// up to but not including the elements in the specified Selection. It returns a\n// new Selection object containing the matched elements.\nfunc (s *Selection) ParentsUntilSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.Parents()\n\t}\n\treturn s.ParentsUntilNodes(sel.Nodes...)\n}\n\n// ParentsUntilNodes gets the ancestors of each element in the Selection,\n// up to but not including the specified nodes. It returns a\n// new Selection object containing the matched elements.\nfunc (s *Selection) ParentsUntilNodes(nodes ...*html.Node) *Selection {\n\treturn pushStack(s, getParentsNodes(s.Nodes, nil, nodes))\n}\n\n// ParentsFilteredUntil is like ParentsUntil, with the option to filter the\n// results based on a selector string. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) ParentsFilteredUntil(filterSelector, untilSelector string) *Selection {\n\treturn filterAndPush(s, getParentsNodes(s.Nodes, compileMatcher(untilSelector), nil), compileMatcher(filterSelector))\n}\n\n// ParentsFilteredUntilMatcher is like ParentsUntilMatcher, with the option to filter the\n// results based on a matcher. It returns a new Selection object containing the matched elements.\nfunc (s *Selection) ParentsFilteredUntilMatcher(filter, until Matcher) *Selection {\n\treturn filterAndPush(s, getParentsNodes(s.Nodes, until, nil), filter)\n}\n\n// ParentsFilteredUntilSelection is like ParentsUntilSelection, with the\n// option to filter the results based on a selector string. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) ParentsFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {\n\treturn s.ParentsMatcherUntilSelection(compileMatcher(filterSelector), sel)\n}\n\n// ParentsMatcherUntilSelection is like ParentsUntilSelection, with the\n// option to filter the results based on a matcher. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) ParentsMatcherUntilSelection(filter Matcher, sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.ParentsMatcher(filter)\n\t}\n\treturn s.ParentsMatcherUntilNodes(filter, sel.Nodes...)\n}\n\n// ParentsFilteredUntilNodes is like ParentsUntilNodes, with the\n// option to filter the results based on a selector string. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) ParentsFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {\n\treturn filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), compileMatcher(filterSelector))\n}\n\n// ParentsMatcherUntilNodes is like ParentsUntilNodes, with the\n// option to filter the results based on a matcher. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) ParentsMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {\n\treturn filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), filter)\n}\n\n// Siblings gets the siblings of each element in the Selection. It returns\n// a new Selection object containing the matched elements.\nfunc (s *Selection) Siblings() *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil))\n}\n\n// SiblingsFiltered gets the siblings of each element in the Selection\n// filtered by a selector. It returns a new Selection object containing the\n// matched elements.\nfunc (s *Selection) SiblingsFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), compileMatcher(selector))\n}\n\n// SiblingsMatcher gets the siblings of each element in the Selection\n// filtered by a matcher. It returns a new Selection object containing the\n// matched elements.\nfunc (s *Selection) SiblingsMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), m)\n}\n\n// Next gets the immediately following sibling of each element in the\n// Selection. It returns a new Selection object containing the matched elements.\nfunc (s *Selection) Next() *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil))\n}\n\n// NextFiltered gets the immediately following sibling of each element in the\n// Selection filtered by a selector. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) NextFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), compileMatcher(selector))\n}\n\n// NextMatcher gets the immediately following sibling of each element in the\n// Selection filtered by a matcher. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) NextMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), m)\n}\n\n// NextAll gets all the following siblings of each element in the\n// Selection. It returns a new Selection object containing the matched elements.\nfunc (s *Selection) NextAll() *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil))\n}\n\n// NextAllFiltered gets all the following siblings of each element in the\n// Selection filtered by a selector. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) NextAllFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), compileMatcher(selector))\n}\n\n// NextAllMatcher gets all the following siblings of each element in the\n// Selection filtered by a matcher. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) NextAllMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), m)\n}\n\n// Prev gets the immediately preceding sibling of each element in the\n// Selection. It returns a new Selection object containing the matched elements.\nfunc (s *Selection) Prev() *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil))\n}\n\n// PrevFiltered gets the immediately preceding sibling of each element in the\n// Selection filtered by a selector. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) PrevFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), compileMatcher(selector))\n}\n\n// PrevMatcher gets the immediately preceding sibling of each element in the\n// Selection filtered by a matcher. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) PrevMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), m)\n}\n\n// PrevAll gets all the preceding siblings of each element in the\n// Selection. It returns a new Selection object containing the matched elements.\nfunc (s *Selection) PrevAll() *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil))\n}\n\n// PrevAllFiltered gets all the preceding siblings of each element in the\n// Selection filtered by a selector. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) PrevAllFiltered(selector string) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), compileMatcher(selector))\n}\n\n// PrevAllMatcher gets all the preceding siblings of each element in the\n// Selection filtered by a matcher. It returns a new Selection object\n// containing the matched elements.\nfunc (s *Selection) PrevAllMatcher(m Matcher) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), m)\n}\n\n// NextUntil gets all following siblings of each element up to but not\n// including the element matched by the selector. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) NextUntil(selector string) *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,\n\t\tcompileMatcher(selector), nil))\n}\n\n// NextUntilMatcher gets all following siblings of each element up to but not\n// including the element matched by the matcher. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) NextUntilMatcher(m Matcher) *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,\n\t\tm, nil))\n}\n\n// NextUntilSelection gets all following siblings of each element up to but not\n// including the element matched by the Selection. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) NextUntilSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.NextAll()\n\t}\n\treturn s.NextUntilNodes(sel.Nodes...)\n}\n\n// NextUntilNodes gets all following siblings of each element up to but not\n// including the element matched by the nodes. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) NextUntilNodes(nodes ...*html.Node) *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,\n\t\tnil, nodes))\n}\n\n// PrevUntil gets all preceding siblings of each element up to but not\n// including the element matched by the selector. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) PrevUntil(selector string) *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,\n\t\tcompileMatcher(selector), nil))\n}\n\n// PrevUntilMatcher gets all preceding siblings of each element up to but not\n// including the element matched by the matcher. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) PrevUntilMatcher(m Matcher) *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,\n\t\tm, nil))\n}\n\n// PrevUntilSelection gets all preceding siblings of each element up to but not\n// including the element matched by the Selection. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) PrevUntilSelection(sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.PrevAll()\n\t}\n\treturn s.PrevUntilNodes(sel.Nodes...)\n}\n\n// PrevUntilNodes gets all preceding siblings of each element up to but not\n// including the element matched by the nodes. It returns a new Selection\n// object containing the matched elements.\nfunc (s *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection {\n\treturn pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,\n\t\tnil, nodes))\n}\n\n// NextFilteredUntil is like NextUntil, with the option to filter\n// the results based on a selector string.\n// It returns a new Selection object containing the matched elements.\nfunc (s *Selection) NextFilteredUntil(filterSelector, untilSelector string) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,\n\t\tcompileMatcher(untilSelector), nil), compileMatcher(filterSelector))\n}\n\n// NextFilteredUntilMatcher is like NextUntilMatcher, with the option to filter\n// the results based on a matcher.\n// It returns a new Selection object containing the matched elements.\nfunc (s *Selection) NextFilteredUntilMatcher(filter, until Matcher) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,\n\t\tuntil, nil), filter)\n}\n\n// NextFilteredUntilSelection is like NextUntilSelection, with the\n// option to filter the results based on a selector string. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) NextFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {\n\treturn s.NextMatcherUntilSelection(compileMatcher(filterSelector), sel)\n}\n\n// NextMatcherUntilSelection is like NextUntilSelection, with the\n// option to filter the results based on a matcher. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) NextMatcherUntilSelection(filter Matcher, sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.NextMatcher(filter)\n\t}\n\treturn s.NextMatcherUntilNodes(filter, sel.Nodes...)\n}\n\n// NextFilteredUntilNodes is like NextUntilNodes, with the\n// option to filter the results based on a selector string. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,\n\t\tnil, nodes), compileMatcher(filterSelector))\n}\n\n// NextMatcherUntilNodes is like NextUntilNodes, with the\n// option to filter the results based on a matcher. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) NextMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,\n\t\tnil, nodes), filter)\n}\n\n// PrevFilteredUntil is like PrevUntil, with the option to filter\n// the results based on a selector string.\n// It returns a new Selection object containing the matched elements.\nfunc (s *Selection) PrevFilteredUntil(filterSelector, untilSelector string) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,\n\t\tcompileMatcher(untilSelector), nil), compileMatcher(filterSelector))\n}\n\n// PrevFilteredUntilMatcher is like PrevUntilMatcher, with the option to filter\n// the results based on a matcher.\n// It returns a new Selection object containing the matched elements.\nfunc (s *Selection) PrevFilteredUntilMatcher(filter, until Matcher) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,\n\t\tuntil, nil), filter)\n}\n\n// PrevFilteredUntilSelection is like PrevUntilSelection, with the\n// option to filter the results based on a selector string. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) PrevFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {\n\treturn s.PrevMatcherUntilSelection(compileMatcher(filterSelector), sel)\n}\n\n// PrevMatcherUntilSelection is like PrevUntilSelection, with the\n// option to filter the results based on a matcher. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) PrevMatcherUntilSelection(filter Matcher, sel *Selection) *Selection {\n\tif sel == nil {\n\t\treturn s.PrevMatcher(filter)\n\t}\n\treturn s.PrevMatcherUntilNodes(filter, sel.Nodes...)\n}\n\n// PrevFilteredUntilNodes is like PrevUntilNodes, with the\n// option to filter the results based on a selector string. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,\n\t\tnil, nodes), compileMatcher(filterSelector))\n}\n\n// PrevMatcherUntilNodes is like PrevUntilNodes, with the\n// option to filter the results based on a matcher. It returns a new\n// Selection object containing the matched elements.\nfunc (s *Selection) PrevMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {\n\treturn filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,\n\t\tnil, nodes), filter)\n}\n\n// Filter and push filters the nodes based on a matcher, and pushes the results\n// on the stack, with the srcSel as previous selection.\nfunc filterAndPush(srcSel *Selection, nodes []*html.Node, m Matcher) *Selection {\n\t// Create a temporary Selection with the specified nodes to filter using winnow\n\tsel := &Selection{nodes, srcSel.document, nil}\n\t// Filter based on matcher and push on stack\n\treturn pushStack(srcSel, winnow(sel, m, true))\n}\n\n// Internal implementation of Find that return raw nodes.\nfunc findWithMatcher(nodes []*html.Node, m Matcher) []*html.Node {\n\t// Map nodes to find the matches within the children of each node\n\treturn mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) {\n\t\t// Go down one level, becausejQuery's Find selects only within descendants\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif c.Type == html.ElementNode {\n\t\t\t\tresult = append(result, m.MatchAll(c)...)\n\t\t\t}\n\t\t}\n\t\treturn\n\t})\n}\n\n// Internal implementation to get all parent nodes, stopping at the specified\n// node (or nil if no stop).\nfunc getParentsNodes(nodes []*html.Node, stopm Matcher, stopNodes []*html.Node) []*html.Node {\n\treturn mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) {\n\t\tfor p := n.Parent; p != nil; p = p.Parent {\n\t\t\tsel := newSingleSelection(p, nil)\n\t\t\tif stopm != nil {\n\t\t\t\tif sel.IsMatcher(stopm) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t} else if len(stopNodes) > 0 {\n\t\t\t\tif sel.IsNodes(stopNodes...) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif p.Type == html.ElementNode {\n\t\t\t\tresult = append(result, p)\n\t\t\t}\n\t\t}\n\t\treturn\n\t})\n}\n\n// Internal implementation of sibling nodes that return a raw slice of matches.\nfunc getSiblingNodes(nodes []*html.Node, st siblingType, untilm Matcher, untilNodes []*html.Node) []*html.Node {\n\tvar f func(*html.Node) bool\n\n\t// If the requested siblings are ...Until, create the test function to\n\t// determine if the until condition is reached (returns true if it is)\n\tif st == siblingNextUntil || st == siblingPrevUntil {\n\t\tf = func(n *html.Node) bool {\n\t\t\tif untilm != nil {\n\t\t\t\t// Matcher-based condition\n\t\t\t\tsel := newSingleSelection(n, nil)\n\t\t\t\treturn sel.IsMatcher(untilm)\n\t\t\t} else if len(untilNodes) > 0 {\n\t\t\t\t// Nodes-based condition\n\t\t\t\tsel := newSingleSelection(n, nil)\n\t\t\t\treturn sel.IsNodes(untilNodes...)\n\t\t\t}\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn mapNodes(nodes, func(i int, n *html.Node) []*html.Node {\n\t\treturn getChildrenWithSiblingType(n.Parent, st, n, f)\n\t})\n}\n\n// Gets the children nodes of each node in the specified slice of nodes,\n// based on the sibling type request.\nfunc getChildrenNodes(nodes []*html.Node, st siblingType) []*html.Node {\n\treturn mapNodes(nodes, func(i int, n *html.Node) []*html.Node {\n\t\treturn getChildrenWithSiblingType(n, st, nil, nil)\n\t})\n}\n\n// Gets the children of the specified parent, based on the requested sibling\n// type, skipping a specified node if required.\nfunc getChildrenWithSiblingType(parent *html.Node, st siblingType, skipNode *html.Node,\n\tuntilFunc func(*html.Node) bool) (result []*html.Node) {\n\n\t// Create the iterator function\n\tvar iter = func(cur *html.Node) (ret *html.Node) {\n\t\t// Based on the sibling type requested, iterate the right way\n\t\tfor {\n\t\t\tswitch st {\n\t\t\tcase siblingAll, siblingAllIncludingNonElements:\n\t\t\t\tif cur == nil {\n\t\t\t\t\t// First iteration, start with first child of parent\n\t\t\t\t\t// Skip node if required\n\t\t\t\t\tif ret = parent.FirstChild; ret == skipNode && skipNode != nil {\n\t\t\t\t\t\tret = skipNode.NextSibling\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Skip node if required\n\t\t\t\t\tif ret = cur.NextSibling; ret == skipNode && skipNode != nil {\n\t\t\t\t\t\tret = skipNode.NextSibling\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase siblingPrev, siblingPrevAll, siblingPrevUntil:\n\t\t\t\tif cur == nil {\n\t\t\t\t\t// Start with previous sibling of the skip node\n\t\t\t\t\tret = skipNode.PrevSibling\n\t\t\t\t} else {\n\t\t\t\t\tret = cur.PrevSibling\n\t\t\t\t}\n\t\t\tcase siblingNext, siblingNextAll, siblingNextUntil:\n\t\t\t\tif cur == nil {\n\t\t\t\t\t// Start with next sibling of the skip node\n\t\t\t\t\tret = skipNode.NextSibling\n\t\t\t\t} else {\n\t\t\t\t\tret = cur.NextSibling\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tpanic(\"Invalid sibling type.\")\n\t\t\t}\n\t\t\tif ret == nil || ret.Type == html.ElementNode || st == siblingAllIncludingNonElements {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Not a valid node, try again from this one\n\t\t\tcur = ret\n\t\t}\n\t}\n\n\tfor c := iter(nil); c != nil; c = iter(c) {\n\t\t// If this is an ...Until case, test before append (returns true\n\t\t// if the until condition is reached)\n\t\tif st == siblingNextUntil || st == siblingPrevUntil {\n\t\t\tif untilFunc(c) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tresult = append(result, c)\n\t\tif st == siblingNext || st == siblingPrev {\n\t\t\t// Only one node was requested (immediate next or previous), so exit\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\n// Internal implementation of parent nodes that return a raw slice of Nodes.\nfunc getParentNodes(nodes []*html.Node) []*html.Node {\n\treturn mapNodes(nodes, func(i int, n *html.Node) []*html.Node {\n\t\tif n.Parent != nil && n.Parent.Type == html.ElementNode {\n\t\t\treturn []*html.Node{n.Parent}\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// Internal map function used by many traversing methods. Takes the source nodes\n// to iterate on and the mapping function that returns an array of nodes.\n// Returns an array of nodes mapped by calling the callback function once for\n// each node in the source nodes.\nfunc mapNodes(nodes []*html.Node, f func(int, *html.Node) []*html.Node) (result []*html.Node) {\n\tset := make(map[*html.Node]bool)\n\tfor i, n := range nodes {\n\t\tif vals := f(i, n); len(vals) > 0 {\n\t\t\tresult = appendWithoutDuplicates(result, vals, set)\n\t\t}\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/type.go",
    "content": "package goquery\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/andybalholm/cascadia\"\n\t\"golang.org/x/net/html\"\n)\n\n// Document represents an HTML document to be manipulated. Unlike jQuery, which\n// is loaded as part of a DOM document, and thus acts upon its containing\n// document, GoQuery doesn't know which HTML document to act upon. So it needs\n// to be told, and that's what the Document class is for. It holds the root\n// document node to manipulate, and can make selections on this document.\ntype Document struct {\n\t*Selection\n\tUrl      *url.URL\n\trootNode *html.Node\n}\n\n// NewDocumentFromNode is a Document constructor that takes a root html Node\n// as argument.\nfunc NewDocumentFromNode(root *html.Node) *Document {\n\treturn newDocument(root, nil)\n}\n\n// NewDocument is a Document constructor that takes a string URL as argument.\n// It loads the specified document, parses it, and stores the root Document\n// node, ready to be manipulated.\n//\n// Deprecated: Use the net/http standard library package to make the request\n// and validate the response before calling goquery.NewDocumentFromReader\n// with the response's body.\nfunc NewDocument(url string) (*Document, error) {\n\t// Load the URL\n\tres, e := http.Get(url)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\treturn NewDocumentFromResponse(res)\n}\n\n// NewDocumentFromReader returns a Document from an io.Reader.\n// It returns an error as second value if the reader's data cannot be parsed\n// as html. It does not check if the reader is also an io.Closer, the\n// provided reader is never closed by this call. It is the responsibility\n// of the caller to close it if required.\nfunc NewDocumentFromReader(r io.Reader) (*Document, error) {\n\troot, e := html.Parse(r)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\treturn newDocument(root, nil), nil\n}\n\n// NewDocumentFromResponse is another Document constructor that takes an http response as argument.\n// It loads the specified response's document, parses it, and stores the root Document\n// node, ready to be manipulated. The response's body is closed on return.\n//\n// Deprecated: Use goquery.NewDocumentFromReader with the response's body.\nfunc NewDocumentFromResponse(res *http.Response) (*Document, error) {\n\tif res == nil {\n\t\treturn nil, errors.New(\"Response is nil\")\n\t}\n\tdefer res.Body.Close()\n\tif res.Request == nil {\n\t\treturn nil, errors.New(\"Response.Request is nil\")\n\t}\n\n\t// Parse the HTML into nodes\n\troot, e := html.Parse(res.Body)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\n\t// Create and fill the document\n\treturn newDocument(root, res.Request.URL), nil\n}\n\n// CloneDocument creates a deep-clone of a document.\nfunc CloneDocument(doc *Document) *Document {\n\treturn newDocument(cloneNode(doc.rootNode), doc.Url)\n}\n\n// Private constructor, make sure all fields are correctly filled.\nfunc newDocument(root *html.Node, url *url.URL) *Document {\n\t// Create and fill the document\n\td := &Document{nil, url, root}\n\td.Selection = newSingleSelection(root, d)\n\treturn d\n}\n\n// Selection represents a collection of nodes matching some criteria. The\n// initial Selection can be created by using Document.Find, and then\n// manipulated using the jQuery-like chainable syntax and methods.\ntype Selection struct {\n\tNodes    []*html.Node\n\tdocument *Document\n\tprevSel  *Selection\n}\n\n// Helper constructor to create an empty selection\nfunc newEmptySelection(doc *Document) *Selection {\n\treturn &Selection{nil, doc, nil}\n}\n\n// Helper constructor to create a selection of only one node\nfunc newSingleSelection(node *html.Node, doc *Document) *Selection {\n\treturn &Selection{[]*html.Node{node}, doc, nil}\n}\n\n// Matcher is an interface that defines the methods to match\n// HTML nodes against a compiled selector string. Cascadia's\n// Selector implements this interface.\ntype Matcher interface {\n\tMatch(*html.Node) bool\n\tMatchAll(*html.Node) []*html.Node\n\tFilter([]*html.Node) []*html.Node\n}\n\n// Single compiles a selector string to a Matcher that stops after the first\n// match is found.\n//\n// By default, Selection.Find and other functions that accept a selector string\n// to select nodes will use all matches corresponding to that selector. By\n// using the Matcher returned by Single, at most the first match will be\n// selected.\n//\n// For example, those two statements are semantically equivalent:\n//\n//     sel1 := doc.Find(\"a\").First()\n//     sel2 := doc.FindMatcher(goquery.Single(\"a\"))\n//\n// The one using Single is optimized to be potentially much faster on large\n// documents.\n//\n// Only the behaviour of the MatchAll method of the Matcher interface is\n// altered compared to standard Matchers. This means that the single-selection\n// property of the Matcher only applies for Selection methods where the Matcher\n// is used to select nodes, not to filter or check if a node matches the\n// Matcher - in those cases, the behaviour of the Matcher is unchanged (e.g.\n// FilterMatcher(Single(\"div\")) will still result in a Selection with multiple\n// \"div\"s if there were many \"div\"s in the Selection to begin with).\nfunc Single(selector string) Matcher {\n\treturn singleMatcher{compileMatcher(selector)}\n}\n\n// SingleMatcher returns a Matcher matches the same nodes as m, but that stops\n// after the first match is found.\n//\n// See the documentation of function Single for more details.\nfunc SingleMatcher(m Matcher) Matcher {\n\tif _, ok := m.(singleMatcher); ok {\n\t\t// m is already a singleMatcher\n\t\treturn m\n\t}\n\treturn singleMatcher{m}\n}\n\n// compileMatcher compiles the selector string s and returns\n// the corresponding Matcher. If s is an invalid selector string,\n// it returns a Matcher that fails all matches.\nfunc compileMatcher(s string) Matcher {\n\tcs, err := cascadia.Compile(s)\n\tif err != nil {\n\t\treturn invalidMatcher{}\n\t}\n\treturn cs\n}\n\ntype singleMatcher struct {\n\tMatcher\n}\n\nfunc (m singleMatcher) MatchAll(n *html.Node) []*html.Node {\n\t// Optimized version - stops finding at the first match (cascadia-compiled\n\t// matchers all use this code path).\n\tif mm, ok := m.Matcher.(interface{ MatchFirst(*html.Node) *html.Node }); ok {\n\t\tnode := mm.MatchFirst(n)\n\t\tif node == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn []*html.Node{node}\n\t}\n\n\t// Fallback version, for e.g. test mocks that don't provide the MatchFirst\n\t// method.\n\tnodes := m.Matcher.MatchAll(n)\n\tif len(nodes) > 0 {\n\t\treturn nodes[:1:1]\n\t}\n\treturn nil\n}\n\n// invalidMatcher is a Matcher that always fails to match.\ntype invalidMatcher struct{}\n\nfunc (invalidMatcher) Match(n *html.Node) bool             { return false }\nfunc (invalidMatcher) MatchAll(n *html.Node) []*html.Node  { return nil }\nfunc (invalidMatcher) Filter(ns []*html.Node) []*html.Node { return nil }\n"
  },
  {
    "path": "vendor/github.com/PuerkitoBio/goquery/utilities.go",
    "content": "package goquery\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\n\t\"golang.org/x/net/html\"\n)\n\n// used to determine if a set (map[*html.Node]bool) should be used\n// instead of iterating over a slice. The set uses more memory and\n// is slower than slice iteration for small N.\nconst minNodesForSet = 1000\n\nvar nodeNames = []string{\n\thtml.ErrorNode:    \"#error\",\n\thtml.TextNode:     \"#text\",\n\thtml.DocumentNode: \"#document\",\n\thtml.CommentNode:  \"#comment\",\n}\n\n// NodeName returns the node name of the first element in the selection.\n// It tries to behave in a similar way as the DOM's nodeName property\n// (https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName).\n//\n// Go's net/html package defines the following node types, listed with\n// the corresponding returned value from this function:\n//\n//     ErrorNode : #error\n//     TextNode : #text\n//     DocumentNode : #document\n//     ElementNode : the element's tag name\n//     CommentNode : #comment\n//     DoctypeNode : the name of the document type\n//\nfunc NodeName(s *Selection) string {\n\tif s.Length() == 0 {\n\t\treturn \"\"\n\t}\n\treturn nodeName(s.Get(0))\n}\n\n// nodeName returns the node name of the given html node.\n// See NodeName for additional details on behaviour.\nfunc nodeName(node *html.Node) string {\n\tif node == nil {\n\t\treturn \"\"\n\t}\n\n\tswitch node.Type {\n\tcase html.ElementNode, html.DoctypeNode:\n\t\treturn node.Data\n\tdefault:\n\t\tif int(node.Type) < len(nodeNames) {\n\t\t\treturn nodeNames[node.Type]\n\t\t}\n\t\treturn \"\"\n\t}\n}\n\n// Render renders the HTML of the first item in the selection and writes it to\n// the writer. It behaves the same as OuterHtml but writes to w instead of\n// returning the string.\nfunc Render(w io.Writer, s *Selection) error {\n\tif s.Length() == 0 {\n\t\treturn nil\n\t}\n\tn := s.Get(0)\n\treturn html.Render(w, n)\n}\n\n// OuterHtml returns the outer HTML rendering of the first item in\n// the selection - that is, the HTML including the first element's\n// tag and attributes.\n//\n// Unlike Html, this is a function and not a method on the Selection,\n// because this is not a jQuery method (in javascript-land, this is\n// a property provided by the DOM).\nfunc OuterHtml(s *Selection) (string, error) {\n\tvar buf bytes.Buffer\n\tif err := Render(&buf, s); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn buf.String(), nil\n}\n\n// Loop through all container nodes to search for the target node.\nfunc sliceContains(container []*html.Node, contained *html.Node) bool {\n\tfor _, n := range container {\n\t\tif nodeContains(n, contained) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\n// Checks if the contained node is within the container node.\nfunc nodeContains(container *html.Node, contained *html.Node) bool {\n\t// Check if the parent of the contained node is the container node, traversing\n\t// upward until the top is reached, or the container is found.\n\tfor contained = contained.Parent; contained != nil; contained = contained.Parent {\n\t\tif container == contained {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Checks if the target node is in the slice of nodes.\nfunc isInSlice(slice []*html.Node, node *html.Node) bool {\n\treturn indexInSlice(slice, node) > -1\n}\n\n// Returns the index of the target node in the slice, or -1.\nfunc indexInSlice(slice []*html.Node, node *html.Node) int {\n\tif node != nil {\n\t\tfor i, n := range slice {\n\t\t\tif n == node {\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\t}\n\treturn -1\n}\n\n// Appends the new nodes to the target slice, making sure no duplicate is added.\n// There is no check to the original state of the target slice, so it may still\n// contain duplicates. The target slice is returned because append() may create\n// a new underlying array. If targetSet is nil, a local set is created with the\n// target if len(target) + len(nodes) is greater than minNodesForSet.\nfunc appendWithoutDuplicates(target []*html.Node, nodes []*html.Node, targetSet map[*html.Node]bool) []*html.Node {\n\t// if there are not that many nodes, don't use the map, faster to just use nested loops\n\t// (unless a non-nil targetSet is passed, in which case the caller knows better).\n\tif targetSet == nil && len(target)+len(nodes) < minNodesForSet {\n\t\tfor _, n := range nodes {\n\t\t\tif !isInSlice(target, n) {\n\t\t\t\ttarget = append(target, n)\n\t\t\t}\n\t\t}\n\t\treturn target\n\t}\n\n\t// if a targetSet is passed, then assume it is reliable, otherwise create one\n\t// and initialize it with the current target contents.\n\tif targetSet == nil {\n\t\ttargetSet = make(map[*html.Node]bool, len(target))\n\t\tfor _, n := range target {\n\t\t\ttargetSet[n] = true\n\t\t}\n\t}\n\tfor _, n := range nodes {\n\t\tif !targetSet[n] {\n\t\t\ttarget = append(target, n)\n\t\t\ttargetSet[n] = true\n\t\t}\n\t}\n\n\treturn target\n}\n\n// Loop through a selection, returning only those nodes that pass the predicate\n// function.\nfunc grep(sel *Selection, predicate func(i int, s *Selection) bool) (result []*html.Node) {\n\tfor i, n := range sel.Nodes {\n\t\tif predicate(i, newSingleSelection(n, sel.document)) {\n\t\t\tresult = append(result, n)\n\t\t}\n\t}\n\treturn result\n}\n\n// Creates a new Selection object based on the specified nodes, and keeps the\n// source Selection object on the stack (linked list).\nfunc pushStack(fromSel *Selection, nodes []*html.Node) *Selection {\n\tresult := &Selection{nodes, fromSel.document, fromSel}\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/andybalholm/cascadia/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.3\n  - 1.4\n\ninstall:\n  - go get github.com/andybalholm/cascadia\n\nscript:\n - go test -v\n\nnotifications:\n  email: false\n"
  },
  {
    "path": "vendor/github.com/andybalholm/cascadia/LICENSE",
    "content": "Copyright (c) 2011 Andy Balholm. 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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\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": "vendor/github.com/andybalholm/cascadia/README.md",
    "content": "# cascadia\n\n[![](https://travis-ci.org/andybalholm/cascadia.svg)](https://travis-ci.org/andybalholm/cascadia)\n\nThe Cascadia package implements CSS selectors for use with the parse trees produced by the html package.\n\nTo test CSS selectors without writing Go code, check out [cascadia](https://github.com/suntong/cascadia) the command line tool, a thin wrapper around this package.\n\n[Refer to godoc here](https://godoc.org/github.com/andybalholm/cascadia).\n\n## Example\n\nThe following is an example of how you can use Cascadia.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\n\t\"github.com/andybalholm/cascadia\"\n\t\"golang.org/x/net/html\"\n)\n\nvar pricingHtml string = `\n<div class=\"card mb-4 box-shadow\">\n\t<div class=\"card-header\">\n\t\t<h4 class=\"my-0 font-weight-normal\">Free</h4>\n\t</div>\n\t<div class=\"card-body\">\n\t\t<h1 class=\"card-title pricing-card-title\">$0/mo</h1>\n\t\t<ul class=\"list-unstyled mt-3 mb-4\">\n\t\t\t<li>10 users included</li>\n\t\t\t<li>2 GB of storage</li>\n\t\t\t<li><a href=\"https://example.com\">See more</a></li>\n\t\t</ul>\n\t</div>\n</div>\n\n<div class=\"card mb-4 box-shadow\">\n\t<div class=\"card-header\">\n\t\t<h4 class=\"my-0 font-weight-normal\">Pro</h4>\n\t</div>\n\t<div class=\"card-body\">\n\t\t<h1 class=\"card-title pricing-card-title\">$15/mo</h1>\n\t\t<ul class=\"list-unstyled mt-3 mb-4\">\n\t\t\t<li>20 users included</li>\n\t\t\t<li>10 GB of storage</li>\n\t\t\t<li><a href=\"https://example.com\">See more</a></li>\n\t\t</ul>\n\t</div>\n</div>\n\n<div class=\"card mb-4 box-shadow\">\n\t<div class=\"card-header\">\n\t\t<h4 class=\"my-0 font-weight-normal\">Enterprise</h4>\n\t</div>\n\t<div class=\"card-body\">\n\t\t<h1 class=\"card-title pricing-card-title\">$29/mo</h1>\n\t\t<ul class=\"list-unstyled mt-3 mb-4\">\n\t\t\t<li>30 users included</li>\n\t\t\t<li>15 GB of storage</li>\n\t\t\t<li><a>See more</a></li>\n\t\t</ul>\n\t</div>\n</div>\n`\n\nfunc Query(n *html.Node, query string) *html.Node {\n\tsel, err := cascadia.Parse(query)\n\tif err != nil {\n\t\treturn &html.Node{}\n\t}\n\treturn cascadia.Query(n, sel)\n}\n\nfunc QueryAll(n *html.Node, query string) []*html.Node {\n\tsel, err := cascadia.Parse(query)\n\tif err != nil {\n\t\treturn []*html.Node{}\n\t}\n\treturn cascadia.QueryAll(n, sel)\n}\n\nfunc AttrOr(n *html.Node, attrName, or string) string {\n\tfor _, a := range n.Attr {\n\t\tif a.Key == attrName {\n\t\t\treturn a.Val\n\t\t}\n\t}\n\treturn or\n}\n\nfunc main() {\n\tdoc, err := html.Parse(strings.NewReader(pricingHtml))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Printf(\"List of pricing plans:\\n\\n\")\n\tfor i, p := range QueryAll(doc, \"div.card.mb-4.box-shadow\") {\n\t\tplanName := Query(p, \"h4\").FirstChild.Data\n\t\tprice := Query(p, \".pricing-card-title\").FirstChild.Data\n\t\tusersIncluded := Query(p, \"li:first-child\").FirstChild.Data\n\t\tstorage := Query(p, \"li:nth-child(2)\").FirstChild.Data\n\t\tdetailsUrl := AttrOr(Query(p, \"li:last-child a\"), \"href\", \"(No link available)\")\n\t\tfmt.Printf(\n\t\t\t\"Plan #%d\\nName: %s\\nPrice: %s\\nUsers: %s\\nStorage: %s\\nDetails: %s\\n\\n\",\n\t\t\ti+1,\n\t\t\tplanName,\n\t\t\tprice,\n\t\t\tusersIncluded,\n\t\t\tstorage,\n\t\t\tdetailsUrl,\n\t\t)\n\t}\n}\n```\nThe output is:\n```\nList of pricing plans:\n\nPlan #1\nName: Free\nPrice: $0/mo\nUsers: 10 users included\nStorage: 2 GB of storage\nDetails: https://example.com\n\nPlan #2\nName: Pro\nPrice: $15/mo\nUsers: 20 users included\nStorage: 10 GB of storage\nDetails: https://example.com\n\nPlan #3\nName: Enterprise\nPrice: $29/mo\nUsers: 30 users included\nStorage: 15 GB of storage\nDetails: (No link available)\n```\n"
  },
  {
    "path": "vendor/github.com/andybalholm/cascadia/parser.go",
    "content": "// Package cascadia is an implementation of CSS selectors.\npackage cascadia\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// a parser for CSS selectors\ntype parser struct {\n\ts string // the source text\n\ti int    // the current position\n\n\t// if `false`, parsing a pseudo-element\n\t// returns an error.\n\tacceptPseudoElements bool\n}\n\n// parseEscape parses a backslash escape.\nfunc (p *parser) parseEscape() (result string, err error) {\n\tif len(p.s) < p.i+2 || p.s[p.i] != '\\\\' {\n\t\treturn \"\", errors.New(\"invalid escape sequence\")\n\t}\n\n\tstart := p.i + 1\n\tc := p.s[start]\n\tswitch {\n\tcase c == '\\r' || c == '\\n' || c == '\\f':\n\t\treturn \"\", errors.New(\"escaped line ending outside string\")\n\tcase hexDigit(c):\n\t\t// unicode escape (hex)\n\t\tvar i int\n\t\tfor i = start; i < start+6 && i < len(p.s) && hexDigit(p.s[i]); i++ {\n\t\t\t// empty\n\t\t}\n\t\tv, _ := strconv.ParseUint(p.s[start:i], 16, 64)\n\t\tif len(p.s) > i {\n\t\t\tswitch p.s[i] {\n\t\t\tcase '\\r':\n\t\t\t\ti++\n\t\t\t\tif len(p.s) > i && p.s[i] == '\\n' {\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\tcase ' ', '\\t', '\\n', '\\f':\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t\tp.i = i\n\t\treturn string(rune(v)), nil\n\t}\n\n\t// Return the literal character after the backslash.\n\tresult = p.s[start : start+1]\n\tp.i += 2\n\treturn result, nil\n}\n\n// toLowerASCII returns s with all ASCII capital letters lowercased.\nfunc toLowerASCII(s string) string {\n\tvar b []byte\n\tfor i := 0; i < len(s); i++ {\n\t\tif c := s[i]; 'A' <= c && c <= 'Z' {\n\t\t\tif b == nil {\n\t\t\t\tb = make([]byte, len(s))\n\t\t\t\tcopy(b, s)\n\t\t\t}\n\t\t\tb[i] = s[i] + ('a' - 'A')\n\t\t}\n\t}\n\n\tif b == nil {\n\t\treturn s\n\t}\n\n\treturn string(b)\n}\n\nfunc hexDigit(c byte) bool {\n\treturn '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F'\n}\n\n// nameStart returns whether c can be the first character of an identifier\n// (not counting an initial hyphen, or an escape sequence).\nfunc nameStart(c byte) bool {\n\treturn 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c > 127\n}\n\n// nameChar returns whether c can be a character within an identifier\n// (not counting an escape sequence).\nfunc nameChar(c byte) bool {\n\treturn 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c > 127 ||\n\t\tc == '-' || '0' <= c && c <= '9'\n}\n\n// parseIdentifier parses an identifier.\nfunc (p *parser) parseIdentifier() (result string, err error) {\n\tconst prefix = '-'\n\tvar numPrefix int\n\n\tfor len(p.s) > p.i && p.s[p.i] == prefix {\n\t\tp.i++\n\t\tnumPrefix++\n\t}\n\n\tif len(p.s) <= p.i {\n\t\treturn \"\", errors.New(\"expected identifier, found EOF instead\")\n\t}\n\n\tif c := p.s[p.i]; !(nameStart(c) || c == '\\\\') {\n\t\treturn \"\", fmt.Errorf(\"expected identifier, found %c instead\", c)\n\t}\n\n\tresult, err = p.parseName()\n\tif numPrefix > 0 && err == nil {\n\t\tresult = strings.Repeat(string(prefix), numPrefix) + result\n\t}\n\treturn\n}\n\n// parseName parses a name (which is like an identifier, but doesn't have\n// extra restrictions on the first character).\nfunc (p *parser) parseName() (result string, err error) {\n\ti := p.i\nloop:\n\tfor i < len(p.s) {\n\t\tc := p.s[i]\n\t\tswitch {\n\t\tcase nameChar(c):\n\t\t\tstart := i\n\t\t\tfor i < len(p.s) && nameChar(p.s[i]) {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tresult += p.s[start:i]\n\t\tcase c == '\\\\':\n\t\t\tp.i = i\n\t\t\tval, err := p.parseEscape()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\ti = p.i\n\t\t\tresult += val\n\t\tdefault:\n\t\t\tbreak loop\n\t\t}\n\t}\n\n\tif result == \"\" {\n\t\treturn \"\", errors.New(\"expected name, found EOF instead\")\n\t}\n\n\tp.i = i\n\treturn result, nil\n}\n\n// parseString parses a single- or double-quoted string.\nfunc (p *parser) parseString() (result string, err error) {\n\ti := p.i\n\tif len(p.s) < i+2 {\n\t\treturn \"\", errors.New(\"expected string, found EOF instead\")\n\t}\n\n\tquote := p.s[i]\n\ti++\n\nloop:\n\tfor i < len(p.s) {\n\t\tswitch p.s[i] {\n\t\tcase '\\\\':\n\t\t\tif len(p.s) > i+1 {\n\t\t\t\tswitch c := p.s[i+1]; c {\n\t\t\t\tcase '\\r':\n\t\t\t\t\tif len(p.s) > i+2 && p.s[i+2] == '\\n' {\n\t\t\t\t\t\ti += 3\n\t\t\t\t\t\tcontinue loop\n\t\t\t\t\t}\n\t\t\t\t\tfallthrough\n\t\t\t\tcase '\\n', '\\f':\n\t\t\t\t\ti += 2\n\t\t\t\t\tcontinue loop\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.i = i\n\t\t\tval, err := p.parseEscape()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\ti = p.i\n\t\t\tresult += val\n\t\tcase quote:\n\t\t\tbreak loop\n\t\tcase '\\r', '\\n', '\\f':\n\t\t\treturn \"\", errors.New(\"unexpected end of line in string\")\n\t\tdefault:\n\t\t\tstart := i\n\t\t\tfor i < len(p.s) {\n\t\t\t\tif c := p.s[i]; c == quote || c == '\\\\' || c == '\\r' || c == '\\n' || c == '\\f' {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\tresult += p.s[start:i]\n\t\t}\n\t}\n\n\tif i >= len(p.s) {\n\t\treturn \"\", errors.New(\"EOF in string\")\n\t}\n\n\t// Consume the final quote.\n\ti++\n\n\tp.i = i\n\treturn result, nil\n}\n\n// parseRegex parses a regular expression; the end is defined by encountering an\n// unmatched closing ')' or ']' which is not consumed\nfunc (p *parser) parseRegex() (rx *regexp.Regexp, err error) {\n\ti := p.i\n\tif len(p.s) < i+2 {\n\t\treturn nil, errors.New(\"expected regular expression, found EOF instead\")\n\t}\n\n\t// number of open parens or brackets;\n\t// when it becomes negative, finished parsing regex\n\topen := 0\n\nloop:\n\tfor i < len(p.s) {\n\t\tswitch p.s[i] {\n\t\tcase '(', '[':\n\t\t\topen++\n\t\tcase ')', ']':\n\t\t\topen--\n\t\t\tif open < 0 {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t}\n\t\ti++\n\t}\n\n\tif i >= len(p.s) {\n\t\treturn nil, errors.New(\"EOF in regular expression\")\n\t}\n\trx, err = regexp.Compile(p.s[p.i:i])\n\tp.i = i\n\treturn rx, err\n}\n\n// skipWhitespace consumes whitespace characters and comments.\n// It returns true if there was actually anything to skip.\nfunc (p *parser) skipWhitespace() bool {\n\ti := p.i\n\tfor i < len(p.s) {\n\t\tswitch p.s[i] {\n\t\tcase ' ', '\\t', '\\r', '\\n', '\\f':\n\t\t\ti++\n\t\t\tcontinue\n\t\tcase '/':\n\t\t\tif strings.HasPrefix(p.s[i:], \"/*\") {\n\t\t\t\tend := strings.Index(p.s[i+len(\"/*\"):], \"*/\")\n\t\t\t\tif end != -1 {\n\t\t\t\t\ti += end + len(\"/**/\")\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak\n\t}\n\n\tif i > p.i {\n\t\tp.i = i\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// consumeParenthesis consumes an opening parenthesis and any following\n// whitespace. It returns true if there was actually a parenthesis to skip.\nfunc (p *parser) consumeParenthesis() bool {\n\tif p.i < len(p.s) && p.s[p.i] == '(' {\n\t\tp.i++\n\t\tp.skipWhitespace()\n\t\treturn true\n\t}\n\treturn false\n}\n\n// consumeClosingParenthesis consumes a closing parenthesis and any preceding\n// whitespace. It returns true if there was actually a parenthesis to skip.\nfunc (p *parser) consumeClosingParenthesis() bool {\n\ti := p.i\n\tp.skipWhitespace()\n\tif p.i < len(p.s) && p.s[p.i] == ')' {\n\t\tp.i++\n\t\treturn true\n\t}\n\tp.i = i\n\treturn false\n}\n\n// parseTypeSelector parses a type selector (one that matches by tag name).\nfunc (p *parser) parseTypeSelector() (result tagSelector, err error) {\n\ttag, err := p.parseIdentifier()\n\tif err != nil {\n\t\treturn\n\t}\n\treturn tagSelector{tag: toLowerASCII(tag)}, nil\n}\n\n// parseIDSelector parses a selector that matches by id attribute.\nfunc (p *parser) parseIDSelector() (idSelector, error) {\n\tif p.i >= len(p.s) {\n\t\treturn idSelector{}, fmt.Errorf(\"expected id selector (#id), found EOF instead\")\n\t}\n\tif p.s[p.i] != '#' {\n\t\treturn idSelector{}, fmt.Errorf(\"expected id selector (#id), found '%c' instead\", p.s[p.i])\n\t}\n\n\tp.i++\n\tid, err := p.parseName()\n\tif err != nil {\n\t\treturn idSelector{}, err\n\t}\n\n\treturn idSelector{id: id}, nil\n}\n\n// parseClassSelector parses a selector that matches by class attribute.\nfunc (p *parser) parseClassSelector() (classSelector, error) {\n\tif p.i >= len(p.s) {\n\t\treturn classSelector{}, fmt.Errorf(\"expected class selector (.class), found EOF instead\")\n\t}\n\tif p.s[p.i] != '.' {\n\t\treturn classSelector{}, fmt.Errorf(\"expected class selector (.class), found '%c' instead\", p.s[p.i])\n\t}\n\n\tp.i++\n\tclass, err := p.parseIdentifier()\n\tif err != nil {\n\t\treturn classSelector{}, err\n\t}\n\n\treturn classSelector{class: class}, nil\n}\n\n// parseAttributeSelector parses a selector that matches by attribute value.\nfunc (p *parser) parseAttributeSelector() (attrSelector, error) {\n\tif p.i >= len(p.s) {\n\t\treturn attrSelector{}, fmt.Errorf(\"expected attribute selector ([attribute]), found EOF instead\")\n\t}\n\tif p.s[p.i] != '[' {\n\t\treturn attrSelector{}, fmt.Errorf(\"expected attribute selector ([attribute]), found '%c' instead\", p.s[p.i])\n\t}\n\n\tp.i++\n\tp.skipWhitespace()\n\tkey, err := p.parseIdentifier()\n\tif err != nil {\n\t\treturn attrSelector{}, err\n\t}\n\tkey = toLowerASCII(key)\n\n\tp.skipWhitespace()\n\tif p.i >= len(p.s) {\n\t\treturn attrSelector{}, errors.New(\"unexpected EOF in attribute selector\")\n\t}\n\n\tif p.s[p.i] == ']' {\n\t\tp.i++\n\t\treturn attrSelector{key: key, operation: \"\"}, nil\n\t}\n\n\tif p.i+2 >= len(p.s) {\n\t\treturn attrSelector{}, errors.New(\"unexpected EOF in attribute selector\")\n\t}\n\n\top := p.s[p.i : p.i+2]\n\tif op[0] == '=' {\n\t\top = \"=\"\n\t} else if op[1] != '=' {\n\t\treturn attrSelector{}, fmt.Errorf(`expected equality operator, found \"%s\" instead`, op)\n\t}\n\tp.i += len(op)\n\n\tp.skipWhitespace()\n\tif p.i >= len(p.s) {\n\t\treturn attrSelector{}, errors.New(\"unexpected EOF in attribute selector\")\n\t}\n\tvar val string\n\tvar rx *regexp.Regexp\n\tif op == \"#=\" {\n\t\trx, err = p.parseRegex()\n\t} else {\n\t\tswitch p.s[p.i] {\n\t\tcase '\\'', '\"':\n\t\t\tval, err = p.parseString()\n\t\tdefault:\n\t\t\tval, err = p.parseIdentifier()\n\t\t}\n\t}\n\tif err != nil {\n\t\treturn attrSelector{}, err\n\t}\n\n\tp.skipWhitespace()\n\tif p.i >= len(p.s) {\n\t\treturn attrSelector{}, errors.New(\"unexpected EOF in attribute selector\")\n\t}\n\n\t// check if the attribute contains an ignore case flag\n\tignoreCase := false\n\tif p.s[p.i] == 'i' || p.s[p.i] == 'I' {\n\t\tignoreCase = true\n\t\tp.i++\n\t}\n\n\tp.skipWhitespace()\n\tif p.i >= len(p.s) {\n\t\treturn attrSelector{}, errors.New(\"unexpected EOF in attribute selector\")\n\t}\n\n\tif p.s[p.i] != ']' {\n\t\treturn attrSelector{}, fmt.Errorf(\"expected ']', found '%c' instead\", p.s[p.i])\n\t}\n\tp.i++\n\n\tswitch op {\n\tcase \"=\", \"!=\", \"~=\", \"|=\", \"^=\", \"$=\", \"*=\", \"#=\":\n\t\treturn attrSelector{key: key, val: val, operation: op, regexp: rx, insensitive: ignoreCase}, nil\n\tdefault:\n\t\treturn attrSelector{}, fmt.Errorf(\"attribute operator %q is not supported\", op)\n\t}\n}\n\nvar (\n\terrExpectedParenthesis        = errors.New(\"expected '(' but didn't find it\")\n\terrExpectedClosingParenthesis = errors.New(\"expected ')' but didn't find it\")\n\terrUnmatchedParenthesis       = errors.New(\"unmatched '('\")\n)\n\n// parsePseudoclassSelector parses a pseudoclass selector like :not(p) or a pseudo-element\n// For backwards compatibility, both ':' and '::' prefix are allowed for pseudo-elements.\n// https://drafts.csswg.org/selectors-3/#pseudo-elements\n// Returning a nil `Sel` (and a nil `error`) means we found a pseudo-element.\nfunc (p *parser) parsePseudoclassSelector() (out Sel, pseudoElement string, err error) {\n\tif p.i >= len(p.s) {\n\t\treturn nil, \"\", fmt.Errorf(\"expected pseudoclass selector (:pseudoclass), found EOF instead\")\n\t}\n\tif p.s[p.i] != ':' {\n\t\treturn nil, \"\", fmt.Errorf(\"expected attribute selector (:pseudoclass), found '%c' instead\", p.s[p.i])\n\t}\n\n\tp.i++\n\tvar mustBePseudoElement bool\n\tif p.i >= len(p.s) {\n\t\treturn nil, \"\", fmt.Errorf(\"got empty pseudoclass (or pseudoelement)\")\n\t}\n\tif p.s[p.i] == ':' { // we found a pseudo-element\n\t\tmustBePseudoElement = true\n\t\tp.i++\n\t}\n\n\tname, err := p.parseIdentifier()\n\tif err != nil {\n\t\treturn\n\t}\n\tname = toLowerASCII(name)\n\tif mustBePseudoElement && (name != \"after\" && name != \"backdrop\" && name != \"before\" &&\n\t\tname != \"cue\" && name != \"first-letter\" && name != \"first-line\" && name != \"grammar-error\" &&\n\t\tname != \"marker\" && name != \"placeholder\" && name != \"selection\" && name != \"spelling-error\") {\n\t\treturn out, \"\", fmt.Errorf(\"unknown pseudoelement :%s\", name)\n\t}\n\n\tswitch name {\n\tcase \"not\", \"has\", \"haschild\":\n\t\tif !p.consumeParenthesis() {\n\t\t\treturn out, \"\", errExpectedParenthesis\n\t\t}\n\t\tsel, parseErr := p.parseSelectorGroup()\n\t\tif parseErr != nil {\n\t\t\treturn out, \"\", parseErr\n\t\t}\n\t\tif !p.consumeClosingParenthesis() {\n\t\t\treturn out, \"\", errExpectedClosingParenthesis\n\t\t}\n\n\t\tout = relativePseudoClassSelector{name: name, match: sel}\n\n\tcase \"contains\", \"containsown\":\n\t\tif !p.consumeParenthesis() {\n\t\t\treturn out, \"\", errExpectedParenthesis\n\t\t}\n\t\tif p.i == len(p.s) {\n\t\t\treturn out, \"\", errUnmatchedParenthesis\n\t\t}\n\t\tvar val string\n\t\tswitch p.s[p.i] {\n\t\tcase '\\'', '\"':\n\t\t\tval, err = p.parseString()\n\t\tdefault:\n\t\t\tval, err = p.parseIdentifier()\n\t\t}\n\t\tif err != nil {\n\t\t\treturn out, \"\", err\n\t\t}\n\t\tval = strings.ToLower(val)\n\t\tp.skipWhitespace()\n\t\tif p.i >= len(p.s) {\n\t\t\treturn out, \"\", errors.New(\"unexpected EOF in pseudo selector\")\n\t\t}\n\t\tif !p.consumeClosingParenthesis() {\n\t\t\treturn out, \"\", errExpectedClosingParenthesis\n\t\t}\n\n\t\tout = containsPseudoClassSelector{own: name == \"containsown\", value: val}\n\n\tcase \"matches\", \"matchesown\":\n\t\tif !p.consumeParenthesis() {\n\t\t\treturn out, \"\", errExpectedParenthesis\n\t\t}\n\t\trx, err := p.parseRegex()\n\t\tif err != nil {\n\t\t\treturn out, \"\", err\n\t\t}\n\t\tif p.i >= len(p.s) {\n\t\t\treturn out, \"\", errors.New(\"unexpected EOF in pseudo selector\")\n\t\t}\n\t\tif !p.consumeClosingParenthesis() {\n\t\t\treturn out, \"\", errExpectedClosingParenthesis\n\t\t}\n\n\t\tout = regexpPseudoClassSelector{own: name == \"matchesown\", regexp: rx}\n\n\tcase \"nth-child\", \"nth-last-child\", \"nth-of-type\", \"nth-last-of-type\":\n\t\tif !p.consumeParenthesis() {\n\t\t\treturn out, \"\", errExpectedParenthesis\n\t\t}\n\t\ta, b, err := p.parseNth()\n\t\tif err != nil {\n\t\t\treturn out, \"\", err\n\t\t}\n\t\tif !p.consumeClosingParenthesis() {\n\t\t\treturn out, \"\", errExpectedClosingParenthesis\n\t\t}\n\t\tlast := name == \"nth-last-child\" || name == \"nth-last-of-type\"\n\t\tofType := name == \"nth-of-type\" || name == \"nth-last-of-type\"\n\t\tout = nthPseudoClassSelector{a: a, b: b, last: last, ofType: ofType}\n\n\tcase \"first-child\":\n\t\tout = nthPseudoClassSelector{a: 0, b: 1, ofType: false, last: false}\n\tcase \"last-child\":\n\t\tout = nthPseudoClassSelector{a: 0, b: 1, ofType: false, last: true}\n\tcase \"first-of-type\":\n\t\tout = nthPseudoClassSelector{a: 0, b: 1, ofType: true, last: false}\n\tcase \"last-of-type\":\n\t\tout = nthPseudoClassSelector{a: 0, b: 1, ofType: true, last: true}\n\tcase \"only-child\":\n\t\tout = onlyChildPseudoClassSelector{ofType: false}\n\tcase \"only-of-type\":\n\t\tout = onlyChildPseudoClassSelector{ofType: true}\n\tcase \"input\":\n\t\tout = inputPseudoClassSelector{}\n\tcase \"empty\":\n\t\tout = emptyElementPseudoClassSelector{}\n\tcase \"root\":\n\t\tout = rootPseudoClassSelector{}\n\tcase \"link\":\n\t\tout = linkPseudoClassSelector{}\n\tcase \"lang\":\n\t\tif !p.consumeParenthesis() {\n\t\t\treturn out, \"\", errExpectedParenthesis\n\t\t}\n\t\tif p.i == len(p.s) {\n\t\t\treturn out, \"\", errUnmatchedParenthesis\n\t\t}\n\t\tval, err := p.parseIdentifier()\n\t\tif err != nil {\n\t\t\treturn out, \"\", err\n\t\t}\n\t\tval = strings.ToLower(val)\n\t\tp.skipWhitespace()\n\t\tif p.i >= len(p.s) {\n\t\t\treturn out, \"\", errors.New(\"unexpected EOF in pseudo selector\")\n\t\t}\n\t\tif !p.consumeClosingParenthesis() {\n\t\t\treturn out, \"\", errExpectedClosingParenthesis\n\t\t}\n\t\tout = langPseudoClassSelector{lang: val}\n\tcase \"enabled\":\n\t\tout = enabledPseudoClassSelector{}\n\tcase \"disabled\":\n\t\tout = disabledPseudoClassSelector{}\n\tcase \"checked\":\n\t\tout = checkedPseudoClassSelector{}\n\tcase \"visited\", \"hover\", \"active\", \"focus\", \"target\":\n\t\t// Not applicable in a static context: never match.\n\t\tout = neverMatchSelector{value: \":\" + name}\n\tcase \"after\", \"backdrop\", \"before\", \"cue\", \"first-letter\", \"first-line\", \"grammar-error\", \"marker\", \"placeholder\", \"selection\", \"spelling-error\":\n\t\treturn nil, name, nil\n\tdefault:\n\t\treturn out, \"\", fmt.Errorf(\"unknown pseudoclass or pseudoelement :%s\", name)\n\t}\n\treturn\n}\n\n// parseInteger parses a  decimal integer.\nfunc (p *parser) parseInteger() (int, error) {\n\ti := p.i\n\tstart := i\n\tfor i < len(p.s) && '0' <= p.s[i] && p.s[i] <= '9' {\n\t\ti++\n\t}\n\tif i == start {\n\t\treturn 0, errors.New(\"expected integer, but didn't find it\")\n\t}\n\tp.i = i\n\n\tval, err := strconv.Atoi(p.s[start:i])\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn val, nil\n}\n\n// parseNth parses the argument for :nth-child (normally of the form an+b).\nfunc (p *parser) parseNth() (a, b int, err error) {\n\t// initial state\n\tif p.i >= len(p.s) {\n\t\tgoto eof\n\t}\n\tswitch p.s[p.i] {\n\tcase '-':\n\t\tp.i++\n\t\tgoto negativeA\n\tcase '+':\n\t\tp.i++\n\t\tgoto positiveA\n\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\tgoto positiveA\n\tcase 'n', 'N':\n\t\ta = 1\n\t\tp.i++\n\t\tgoto readN\n\tcase 'o', 'O', 'e', 'E':\n\t\tid, nameErr := p.parseName()\n\t\tif nameErr != nil {\n\t\t\treturn 0, 0, nameErr\n\t\t}\n\t\tid = toLowerASCII(id)\n\t\tif id == \"odd\" {\n\t\t\treturn 2, 1, nil\n\t\t}\n\t\tif id == \"even\" {\n\t\t\treturn 2, 0, nil\n\t\t}\n\t\treturn 0, 0, fmt.Errorf(\"expected 'odd' or 'even', but found '%s' instead\", id)\n\tdefault:\n\t\tgoto invalid\n\t}\n\npositiveA:\n\tif p.i >= len(p.s) {\n\t\tgoto eof\n\t}\n\tswitch p.s[p.i] {\n\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\ta, err = p.parseInteger()\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tgoto readA\n\tcase 'n', 'N':\n\t\ta = 1\n\t\tp.i++\n\t\tgoto readN\n\tdefault:\n\t\tgoto invalid\n\t}\n\nnegativeA:\n\tif p.i >= len(p.s) {\n\t\tgoto eof\n\t}\n\tswitch p.s[p.i] {\n\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\ta, err = p.parseInteger()\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\ta = -a\n\t\tgoto readA\n\tcase 'n', 'N':\n\t\ta = -1\n\t\tp.i++\n\t\tgoto readN\n\tdefault:\n\t\tgoto invalid\n\t}\n\nreadA:\n\tif p.i >= len(p.s) {\n\t\tgoto eof\n\t}\n\tswitch p.s[p.i] {\n\tcase 'n', 'N':\n\t\tp.i++\n\t\tgoto readN\n\tdefault:\n\t\t// The number we read as a is actually b.\n\t\treturn 0, a, nil\n\t}\n\nreadN:\n\tp.skipWhitespace()\n\tif p.i >= len(p.s) {\n\t\tgoto eof\n\t}\n\tswitch p.s[p.i] {\n\tcase '+':\n\t\tp.i++\n\t\tp.skipWhitespace()\n\t\tb, err = p.parseInteger()\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn a, b, nil\n\tcase '-':\n\t\tp.i++\n\t\tp.skipWhitespace()\n\t\tb, err = p.parseInteger()\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn a, -b, nil\n\tdefault:\n\t\treturn a, 0, nil\n\t}\n\neof:\n\treturn 0, 0, errors.New(\"unexpected EOF while attempting to parse expression of form an+b\")\n\ninvalid:\n\treturn 0, 0, errors.New(\"unexpected character while attempting to parse expression of form an+b\")\n}\n\n// parseSimpleSelectorSequence parses a selector sequence that applies to\n// a single element.\nfunc (p *parser) parseSimpleSelectorSequence() (Sel, error) {\n\tvar selectors []Sel\n\n\tif p.i >= len(p.s) {\n\t\treturn nil, errors.New(\"expected selector, found EOF instead\")\n\t}\n\n\tswitch p.s[p.i] {\n\tcase '*':\n\t\t// It's the universal selector. Just skip over it, since it doesn't affect the meaning.\n\t\tp.i++\n\t\tif p.i+2 < len(p.s) && p.s[p.i:p.i+2] == \"|*\" { // other version of universal selector\n\t\t\tp.i += 2\n\t\t}\n\tcase '#', '.', '[', ':':\n\t\t// There's no type selector. Wait to process the other till the main loop.\n\tdefault:\n\t\tr, err := p.parseTypeSelector()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tselectors = append(selectors, r)\n\t}\n\n\tvar pseudoElement string\nloop:\n\tfor p.i < len(p.s) {\n\t\tvar (\n\t\t\tns               Sel\n\t\t\tnewPseudoElement string\n\t\t\terr              error\n\t\t)\n\t\tswitch p.s[p.i] {\n\t\tcase '#':\n\t\t\tns, err = p.parseIDSelector()\n\t\tcase '.':\n\t\t\tns, err = p.parseClassSelector()\n\t\tcase '[':\n\t\t\tns, err = p.parseAttributeSelector()\n\t\tcase ':':\n\t\t\tns, newPseudoElement, err = p.parsePseudoclassSelector()\n\t\tdefault:\n\t\t\tbreak loop\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// From https://drafts.csswg.org/selectors-3/#pseudo-elements :\n\t\t// \"Only one pseudo-element may appear per selector, and if present\n\t\t// it must appear after the sequence of simple selectors that\n\t\t// represents the subjects of the selector.\"\"\n\t\tif ns == nil { // we found a pseudo-element\n\t\t\tif pseudoElement != \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"only one pseudo-element is accepted per selector, got %s and %s\", pseudoElement, newPseudoElement)\n\t\t\t}\n\t\t\tif !p.acceptPseudoElements {\n\t\t\t\treturn nil, fmt.Errorf(\"pseudo-element %s found, but pseudo-elements support is disabled\", newPseudoElement)\n\t\t\t}\n\t\t\tpseudoElement = newPseudoElement\n\t\t} else {\n\t\t\tif pseudoElement != \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"pseudo-element %s must be at the end of selector\", pseudoElement)\n\t\t\t}\n\t\t\tselectors = append(selectors, ns)\n\t\t}\n\n\t}\n\tif len(selectors) == 1 && pseudoElement == \"\" { // no need wrap the selectors in compoundSelector\n\t\treturn selectors[0], nil\n\t}\n\treturn compoundSelector{selectors: selectors, pseudoElement: pseudoElement}, nil\n}\n\n// parseSelector parses a selector that may include combinators.\nfunc (p *parser) parseSelector() (Sel, error) {\n\tp.skipWhitespace()\n\tresult, err := p.parseSimpleSelectorSequence()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor {\n\t\tvar (\n\t\t\tcombinator byte\n\t\t\tc          Sel\n\t\t)\n\t\tif p.skipWhitespace() {\n\t\t\tcombinator = ' '\n\t\t}\n\t\tif p.i >= len(p.s) {\n\t\t\treturn result, nil\n\t\t}\n\n\t\tswitch p.s[p.i] {\n\t\tcase '+', '>', '~':\n\t\t\tcombinator = p.s[p.i]\n\t\t\tp.i++\n\t\t\tp.skipWhitespace()\n\t\tcase ',', ')':\n\t\t\t// These characters can't begin a selector, but they can legally occur after one.\n\t\t\treturn result, nil\n\t\t}\n\n\t\tif combinator == 0 {\n\t\t\treturn result, nil\n\t\t}\n\n\t\tc, err = p.parseSimpleSelectorSequence()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresult = combinedSelector{first: result, combinator: combinator, second: c}\n\t}\n}\n\n// parseSelectorGroup parses a group of selectors, separated by commas.\nfunc (p *parser) parseSelectorGroup() (SelectorGroup, error) {\n\tcurrent, err := p.parseSelector()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tresult := SelectorGroup{current}\n\n\tfor p.i < len(p.s) {\n\t\tif p.s[p.i] != ',' {\n\t\t\tbreak\n\t\t}\n\t\tp.i++\n\t\tc, err := p.parseSelector()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresult = append(result, c)\n\t}\n\treturn result, nil\n}\n"
  },
  {
    "path": "vendor/github.com/andybalholm/cascadia/pseudo_classes.go",
    "content": "package cascadia\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"golang.org/x/net/html\"\n\t\"golang.org/x/net/html/atom\"\n)\n\n// This file implements the pseudo classes selectors,\n// which share the implementation of PseudoElement() and Specificity()\n\ntype abstractPseudoClass struct{}\n\nfunc (s abstractPseudoClass) Specificity() Specificity {\n\treturn Specificity{0, 1, 0}\n}\n\nfunc (c abstractPseudoClass) PseudoElement() string {\n\treturn \"\"\n}\n\ntype relativePseudoClassSelector struct {\n\tname  string // one of \"not\", \"has\", \"haschild\"\n\tmatch SelectorGroup\n}\n\nfunc (s relativePseudoClassSelector) Match(n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\tswitch s.name {\n\tcase \"not\":\n\t\t// matches elements that do not match a.\n\t\treturn !s.match.Match(n)\n\tcase \"has\":\n\t\t//  matches elements with any descendant that matches a.\n\t\treturn hasDescendantMatch(n, s.match)\n\tcase \"haschild\":\n\t\t// matches elements with a child that matches a.\n\t\treturn hasChildMatch(n, s.match)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unsupported relative pseudo class selector : %s\", s.name))\n\t}\n}\n\n// hasChildMatch returns whether n has any child that matches a.\nfunc hasChildMatch(n *html.Node, a Matcher) bool {\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tif a.Match(c) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// hasDescendantMatch performs a depth-first search of n's descendants,\n// testing whether any of them match a. It returns true as soon as a match is\n// found, or false if no match is found.\nfunc hasDescendantMatch(n *html.Node, a Matcher) bool {\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tif a.Match(c) || (c.Type == html.ElementNode && hasDescendantMatch(c, a)) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Specificity returns the specificity of the most specific selectors\n// in the pseudo-class arguments.\n// See https://www.w3.org/TR/selectors/#specificity-rules\nfunc (s relativePseudoClassSelector) Specificity() Specificity {\n\tvar max Specificity\n\tfor _, sel := range s.match {\n\t\tnewSpe := sel.Specificity()\n\t\tif max.Less(newSpe) {\n\t\t\tmax = newSpe\n\t\t}\n\t}\n\treturn max\n}\n\nfunc (c relativePseudoClassSelector) PseudoElement() string {\n\treturn \"\"\n}\n\ntype containsPseudoClassSelector struct {\n\tabstractPseudoClass\n\tvalue string\n\town   bool\n}\n\nfunc (s containsPseudoClassSelector) Match(n *html.Node) bool {\n\tvar text string\n\tif s.own {\n\t\t// matches nodes that directly contain the given text\n\t\ttext = strings.ToLower(nodeOwnText(n))\n\t} else {\n\t\t// matches nodes that contain the given text.\n\t\ttext = strings.ToLower(nodeText(n))\n\t}\n\treturn strings.Contains(text, s.value)\n}\n\ntype regexpPseudoClassSelector struct {\n\tabstractPseudoClass\n\tregexp *regexp.Regexp\n\town    bool\n}\n\nfunc (s regexpPseudoClassSelector) Match(n *html.Node) bool {\n\tvar text string\n\tif s.own {\n\t\t// matches nodes whose text directly matches the specified regular expression\n\t\ttext = nodeOwnText(n)\n\t} else {\n\t\t// matches nodes whose text matches the specified regular expression\n\t\ttext = nodeText(n)\n\t}\n\treturn s.regexp.MatchString(text)\n}\n\n// writeNodeText writes the text contained in n and its descendants to b.\nfunc writeNodeText(n *html.Node, b *bytes.Buffer) {\n\tswitch n.Type {\n\tcase html.TextNode:\n\t\tb.WriteString(n.Data)\n\tcase html.ElementNode:\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\twriteNodeText(c, b)\n\t\t}\n\t}\n}\n\n// nodeText returns the text contained in n and its descendants.\nfunc nodeText(n *html.Node) string {\n\tvar b bytes.Buffer\n\twriteNodeText(n, &b)\n\treturn b.String()\n}\n\n// nodeOwnText returns the contents of the text nodes that are direct\n// children of n.\nfunc nodeOwnText(n *html.Node) string {\n\tvar b bytes.Buffer\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tif c.Type == html.TextNode {\n\t\t\tb.WriteString(c.Data)\n\t\t}\n\t}\n\treturn b.String()\n}\n\ntype nthPseudoClassSelector struct {\n\tabstractPseudoClass\n\ta, b         int\n\tlast, ofType bool\n}\n\nfunc (s nthPseudoClassSelector) Match(n *html.Node) bool {\n\tif s.a == 0 {\n\t\tif s.last {\n\t\t\treturn simpleNthLastChildMatch(s.b, s.ofType, n)\n\t\t} else {\n\t\t\treturn simpleNthChildMatch(s.b, s.ofType, n)\n\t\t}\n\t}\n\treturn nthChildMatch(s.a, s.b, s.last, s.ofType, n)\n}\n\n// nthChildMatch implements :nth-child(an+b).\n// If last is true, implements :nth-last-child instead.\n// If ofType is true, implements :nth-of-type instead.\nfunc nthChildMatch(a, b int, last, ofType bool, n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\n\tparent := n.Parent\n\tif parent == nil {\n\t\treturn false\n\t}\n\n\ti := -1\n\tcount := 0\n\tfor c := parent.FirstChild; c != nil; c = c.NextSibling {\n\t\tif (c.Type != html.ElementNode) || (ofType && c.Data != n.Data) {\n\t\t\tcontinue\n\t\t}\n\t\tcount++\n\t\tif c == n {\n\t\t\ti = count\n\t\t\tif !last {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif i == -1 {\n\t\t// This shouldn't happen, since n should always be one of its parent's children.\n\t\treturn false\n\t}\n\n\tif last {\n\t\ti = count - i + 1\n\t}\n\n\ti -= b\n\tif a == 0 {\n\t\treturn i == 0\n\t}\n\n\treturn i%a == 0 && i/a >= 0\n}\n\n// simpleNthChildMatch implements :nth-child(b).\n// If ofType is true, implements :nth-of-type instead.\nfunc simpleNthChildMatch(b int, ofType bool, n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\n\tparent := n.Parent\n\tif parent == nil {\n\t\treturn false\n\t}\n\n\tcount := 0\n\tfor c := parent.FirstChild; c != nil; c = c.NextSibling {\n\t\tif c.Type != html.ElementNode || (ofType && c.Data != n.Data) {\n\t\t\tcontinue\n\t\t}\n\t\tcount++\n\t\tif c == n {\n\t\t\treturn count == b\n\t\t}\n\t\tif count >= b {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n\n// simpleNthLastChildMatch implements :nth-last-child(b).\n// If ofType is true, implements :nth-last-of-type instead.\nfunc simpleNthLastChildMatch(b int, ofType bool, n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\n\tparent := n.Parent\n\tif parent == nil {\n\t\treturn false\n\t}\n\n\tcount := 0\n\tfor c := parent.LastChild; c != nil; c = c.PrevSibling {\n\t\tif c.Type != html.ElementNode || (ofType && c.Data != n.Data) {\n\t\t\tcontinue\n\t\t}\n\t\tcount++\n\t\tif c == n {\n\t\t\treturn count == b\n\t\t}\n\t\tif count >= b {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n\ntype onlyChildPseudoClassSelector struct {\n\tabstractPseudoClass\n\tofType bool\n}\n\n// Match implements :only-child.\n// If `ofType` is true, it implements :only-of-type instead.\nfunc (s onlyChildPseudoClassSelector) Match(n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\n\tparent := n.Parent\n\tif parent == nil {\n\t\treturn false\n\t}\n\n\tcount := 0\n\tfor c := parent.FirstChild; c != nil; c = c.NextSibling {\n\t\tif (c.Type != html.ElementNode) || (s.ofType && c.Data != n.Data) {\n\t\t\tcontinue\n\t\t}\n\t\tcount++\n\t\tif count > 1 {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn count == 1\n}\n\ntype inputPseudoClassSelector struct {\n\tabstractPseudoClass\n}\n\n// Matches input, select, textarea and button elements.\nfunc (s inputPseudoClassSelector) Match(n *html.Node) bool {\n\treturn n.Type == html.ElementNode && (n.Data == \"input\" || n.Data == \"select\" || n.Data == \"textarea\" || n.Data == \"button\")\n}\n\ntype emptyElementPseudoClassSelector struct {\n\tabstractPseudoClass\n}\n\n// Matches empty elements.\nfunc (s emptyElementPseudoClassSelector) Match(n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tswitch c.Type {\n\t\tcase html.ElementNode:\n\t\t\treturn false\n\t\tcase html.TextNode:\n\t\t\tif strings.TrimSpace(nodeText(c)) == \"\" {\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype rootPseudoClassSelector struct {\n\tabstractPseudoClass\n}\n\n// Match implements :root\nfunc (s rootPseudoClassSelector) Match(n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\tif n.Parent == nil {\n\t\treturn false\n\t}\n\treturn n.Parent.Type == html.DocumentNode\n}\n\nfunc hasAttr(n *html.Node, attr string) bool {\n\treturn matchAttribute(n, attr, func(string) bool { return true })\n}\n\ntype linkPseudoClassSelector struct {\n\tabstractPseudoClass\n}\n\n// Match implements :link\nfunc (s linkPseudoClassSelector) Match(n *html.Node) bool {\n\treturn (n.DataAtom == atom.A || n.DataAtom == atom.Area || n.DataAtom == atom.Link) && hasAttr(n, \"href\")\n}\n\ntype langPseudoClassSelector struct {\n\tabstractPseudoClass\n\tlang string\n}\n\nfunc (s langPseudoClassSelector) Match(n *html.Node) bool {\n\town := matchAttribute(n, \"lang\", func(val string) bool {\n\t\treturn val == s.lang || strings.HasPrefix(val, s.lang+\"-\")\n\t})\n\tif n.Parent == nil {\n\t\treturn own\n\t}\n\treturn own || s.Match(n.Parent)\n}\n\ntype enabledPseudoClassSelector struct {\n\tabstractPseudoClass\n}\n\nfunc (s enabledPseudoClassSelector) Match(n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\tswitch n.DataAtom {\n\tcase atom.A, atom.Area, atom.Link:\n\t\treturn hasAttr(n, \"href\")\n\tcase atom.Optgroup, atom.Menuitem, atom.Fieldset:\n\t\treturn !hasAttr(n, \"disabled\")\n\tcase atom.Button, atom.Input, atom.Select, atom.Textarea, atom.Option:\n\t\treturn !hasAttr(n, \"disabled\") && !inDisabledFieldset(n)\n\t}\n\treturn false\n}\n\ntype disabledPseudoClassSelector struct {\n\tabstractPseudoClass\n}\n\nfunc (s disabledPseudoClassSelector) Match(n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\tswitch n.DataAtom {\n\tcase atom.Optgroup, atom.Menuitem, atom.Fieldset:\n\t\treturn hasAttr(n, \"disabled\")\n\tcase atom.Button, atom.Input, atom.Select, atom.Textarea, atom.Option:\n\t\treturn hasAttr(n, \"disabled\") || inDisabledFieldset(n)\n\t}\n\treturn false\n}\n\nfunc hasLegendInPreviousSiblings(n *html.Node) bool {\n\tfor s := n.PrevSibling; s != nil; s = s.PrevSibling {\n\t\tif s.DataAtom == atom.Legend {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc inDisabledFieldset(n *html.Node) bool {\n\tif n.Parent == nil {\n\t\treturn false\n\t}\n\tif n.Parent.DataAtom == atom.Fieldset && hasAttr(n.Parent, \"disabled\") &&\n\t\t(n.DataAtom != atom.Legend || hasLegendInPreviousSiblings(n)) {\n\t\treturn true\n\t}\n\treturn inDisabledFieldset(n.Parent)\n}\n\ntype checkedPseudoClassSelector struct {\n\tabstractPseudoClass\n}\n\nfunc (s checkedPseudoClassSelector) Match(n *html.Node) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\tswitch n.DataAtom {\n\tcase atom.Input, atom.Menuitem:\n\t\treturn hasAttr(n, \"checked\") && matchAttribute(n, \"type\", func(val string) bool {\n\t\t\tt := toLowerASCII(val)\n\t\t\treturn t == \"checkbox\" || t == \"radio\"\n\t\t})\n\tcase atom.Option:\n\t\treturn hasAttr(n, \"selected\")\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/andybalholm/cascadia/selector.go",
    "content": "package cascadia\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"golang.org/x/net/html\"\n)\n\n// Matcher is the interface for basic selector functionality.\n// Match returns whether a selector matches n.\ntype Matcher interface {\n\tMatch(n *html.Node) bool\n}\n\n// Sel is the interface for all the functionality provided by selectors.\ntype Sel interface {\n\tMatcher\n\tSpecificity() Specificity\n\n\t// Returns a CSS input compiling to this selector.\n\tString() string\n\n\t// Returns a pseudo-element, or an empty string.\n\tPseudoElement() string\n}\n\n// Parse parses a selector. Use `ParseWithPseudoElement`\n// if you need support for pseudo-elements.\nfunc Parse(sel string) (Sel, error) {\n\tp := &parser{s: sel}\n\tcompiled, err := p.parseSelector()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif p.i < len(sel) {\n\t\treturn nil, fmt.Errorf(\"parsing %q: %d bytes left over\", sel, len(sel)-p.i)\n\t}\n\n\treturn compiled, nil\n}\n\n// ParseWithPseudoElement parses a single selector,\n// with support for pseudo-element.\nfunc ParseWithPseudoElement(sel string) (Sel, error) {\n\tp := &parser{s: sel, acceptPseudoElements: true}\n\tcompiled, err := p.parseSelector()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif p.i < len(sel) {\n\t\treturn nil, fmt.Errorf(\"parsing %q: %d bytes left over\", sel, len(sel)-p.i)\n\t}\n\n\treturn compiled, nil\n}\n\n// ParseGroup parses a selector, or a group of selectors separated by commas.\n// Use `ParseGroupWithPseudoElements`\n// if you need support for pseudo-elements.\nfunc ParseGroup(sel string) (SelectorGroup, error) {\n\tp := &parser{s: sel}\n\tcompiled, err := p.parseSelectorGroup()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif p.i < len(sel) {\n\t\treturn nil, fmt.Errorf(\"parsing %q: %d bytes left over\", sel, len(sel)-p.i)\n\t}\n\n\treturn compiled, nil\n}\n\n// ParseGroupWithPseudoElements parses a selector, or a group of selectors separated by commas.\n// It supports pseudo-elements.\nfunc ParseGroupWithPseudoElements(sel string) (SelectorGroup, error) {\n\tp := &parser{s: sel, acceptPseudoElements: true}\n\tcompiled, err := p.parseSelectorGroup()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif p.i < len(sel) {\n\t\treturn nil, fmt.Errorf(\"parsing %q: %d bytes left over\", sel, len(sel)-p.i)\n\t}\n\n\treturn compiled, nil\n}\n\n// A Selector is a function which tells whether a node matches or not.\n//\n// This type is maintained for compatibility; I recommend using the newer and\n// more idiomatic interfaces Sel and Matcher.\ntype Selector func(*html.Node) bool\n\n// Compile parses a selector and returns, if successful, a Selector object\n// that can be used to match against html.Node objects.\nfunc Compile(sel string) (Selector, error) {\n\tcompiled, err := ParseGroup(sel)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn Selector(compiled.Match), nil\n}\n\n// MustCompile is like Compile, but panics instead of returning an error.\nfunc MustCompile(sel string) Selector {\n\tcompiled, err := Compile(sel)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn compiled\n}\n\n// MatchAll returns a slice of the nodes that match the selector,\n// from n and its children.\nfunc (s Selector) MatchAll(n *html.Node) []*html.Node {\n\treturn s.matchAllInto(n, nil)\n}\n\nfunc (s Selector) matchAllInto(n *html.Node, storage []*html.Node) []*html.Node {\n\tif s(n) {\n\t\tstorage = append(storage, n)\n\t}\n\n\tfor child := n.FirstChild; child != nil; child = child.NextSibling {\n\t\tstorage = s.matchAllInto(child, storage)\n\t}\n\n\treturn storage\n}\n\nfunc queryInto(n *html.Node, m Matcher, storage []*html.Node) []*html.Node {\n\tfor child := n.FirstChild; child != nil; child = child.NextSibling {\n\t\tif m.Match(child) {\n\t\t\tstorage = append(storage, child)\n\t\t}\n\t\tstorage = queryInto(child, m, storage)\n\t}\n\n\treturn storage\n}\n\n// QueryAll returns a slice of all the nodes that match m, from the descendants\n// of n.\nfunc QueryAll(n *html.Node, m Matcher) []*html.Node {\n\treturn queryInto(n, m, nil)\n}\n\n// Match returns true if the node matches the selector.\nfunc (s Selector) Match(n *html.Node) bool {\n\treturn s(n)\n}\n\n// MatchFirst returns the first node that matches s, from n and its children.\nfunc (s Selector) MatchFirst(n *html.Node) *html.Node {\n\tif s.Match(n) {\n\t\treturn n\n\t}\n\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tm := s.MatchFirst(c)\n\t\tif m != nil {\n\t\t\treturn m\n\t\t}\n\t}\n\treturn nil\n}\n\n// Query returns the first node that matches m, from the descendants of n.\n// If none matches, it returns nil.\nfunc Query(n *html.Node, m Matcher) *html.Node {\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\tif m.Match(c) {\n\t\t\treturn c\n\t\t}\n\t\tif matched := Query(c, m); matched != nil {\n\t\t\treturn matched\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Filter returns the nodes in nodes that match the selector.\nfunc (s Selector) Filter(nodes []*html.Node) (result []*html.Node) {\n\tfor _, n := range nodes {\n\t\tif s(n) {\n\t\t\tresult = append(result, n)\n\t\t}\n\t}\n\treturn result\n}\n\n// Filter returns the nodes that match m.\nfunc Filter(nodes []*html.Node, m Matcher) (result []*html.Node) {\n\tfor _, n := range nodes {\n\t\tif m.Match(n) {\n\t\t\tresult = append(result, n)\n\t\t}\n\t}\n\treturn result\n}\n\ntype tagSelector struct {\n\ttag string\n}\n\n// Matches elements with a given tag name.\nfunc (t tagSelector) Match(n *html.Node) bool {\n\treturn n.Type == html.ElementNode && n.Data == t.tag\n}\n\nfunc (c tagSelector) Specificity() Specificity {\n\treturn Specificity{0, 0, 1}\n}\n\nfunc (c tagSelector) PseudoElement() string {\n\treturn \"\"\n}\n\ntype classSelector struct {\n\tclass string\n}\n\n// Matches elements by class attribute.\nfunc (t classSelector) Match(n *html.Node) bool {\n\treturn matchAttribute(n, \"class\", func(s string) bool {\n\t\treturn matchInclude(t.class, s, false)\n\t})\n}\n\nfunc (c classSelector) Specificity() Specificity {\n\treturn Specificity{0, 1, 0}\n}\n\nfunc (c classSelector) PseudoElement() string {\n\treturn \"\"\n}\n\ntype idSelector struct {\n\tid string\n}\n\n// Matches elements by id attribute.\nfunc (t idSelector) Match(n *html.Node) bool {\n\treturn matchAttribute(n, \"id\", func(s string) bool {\n\t\treturn s == t.id\n\t})\n}\n\nfunc (c idSelector) Specificity() Specificity {\n\treturn Specificity{1, 0, 0}\n}\n\nfunc (c idSelector) PseudoElement() string {\n\treturn \"\"\n}\n\ntype attrSelector struct {\n\tkey, val, operation string\n\tregexp              *regexp.Regexp\n\tinsensitive         bool\n}\n\n// Matches elements by attribute value.\nfunc (t attrSelector) Match(n *html.Node) bool {\n\tswitch t.operation {\n\tcase \"\":\n\t\treturn matchAttribute(n, t.key, func(string) bool { return true })\n\tcase \"=\":\n\t\treturn matchAttribute(n, t.key, func(s string) bool { return matchInsensitiveValue(s, t.val, t.insensitive) })\n\tcase \"!=\":\n\t\treturn attributeNotEqualMatch(t.key, t.val, n, t.insensitive)\n\tcase \"~=\":\n\t\t// matches elements where the attribute named key is a whitespace-separated list that includes val.\n\t\treturn matchAttribute(n, t.key, func(s string) bool { return matchInclude(t.val, s, t.insensitive) })\n\tcase \"|=\":\n\t\treturn attributeDashMatch(t.key, t.val, n, t.insensitive)\n\tcase \"^=\":\n\t\treturn attributePrefixMatch(t.key, t.val, n, t.insensitive)\n\tcase \"$=\":\n\t\treturn attributeSuffixMatch(t.key, t.val, n, t.insensitive)\n\tcase \"*=\":\n\t\treturn attributeSubstringMatch(t.key, t.val, n, t.insensitive)\n\tcase \"#=\":\n\t\treturn attributeRegexMatch(t.key, t.regexp, n)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unsuported operation : %s\", t.operation))\n\t}\n}\n\n// matches elements where we ignore (or not) the case of the attribute value\n// the user attribute is the value set by the user to match elements\n// the real attribute is the attribute value found in the code parsed\nfunc matchInsensitiveValue(userAttr string, realAttr string, ignoreCase bool) bool {\n\tif ignoreCase {\n\t\treturn strings.EqualFold(userAttr, realAttr)\n\t}\n\treturn userAttr == realAttr\n\n}\n\n// matches elements where the attribute named key satisifes the function f.\nfunc matchAttribute(n *html.Node, key string, f func(string) bool) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\tfor _, a := range n.Attr {\n\t\tif a.Key == key && f(a.Val) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// attributeNotEqualMatch matches elements where\n// the attribute named key does not have the value val.\nfunc attributeNotEqualMatch(key, val string, n *html.Node, ignoreCase bool) bool {\n\tif n.Type != html.ElementNode {\n\t\treturn false\n\t}\n\tfor _, a := range n.Attr {\n\t\tif a.Key == key && matchInsensitiveValue(a.Val, val, ignoreCase) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// returns true if s is a whitespace-separated list that includes val.\nfunc matchInclude(val string, s string, ignoreCase bool) bool {\n\tfor s != \"\" {\n\t\ti := strings.IndexAny(s, \" \\t\\r\\n\\f\")\n\t\tif i == -1 {\n\t\t\treturn matchInsensitiveValue(s, val, ignoreCase)\n\t\t}\n\t\tif matchInsensitiveValue(s[:i], val, ignoreCase) {\n\t\t\treturn true\n\t\t}\n\t\ts = s[i+1:]\n\t}\n\treturn false\n}\n\n//  matches elements where the attribute named key equals val or starts with val plus a hyphen.\nfunc attributeDashMatch(key, val string, n *html.Node, ignoreCase bool) bool {\n\treturn matchAttribute(n, key,\n\t\tfunc(s string) bool {\n\t\t\tif matchInsensitiveValue(s, val, ignoreCase) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif len(s) <= len(val) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif matchInsensitiveValue(s[:len(val)], val, ignoreCase) && s[len(val)] == '-' {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t})\n}\n\n// attributePrefixMatch returns a Selector that matches elements where\n// the attribute named key starts with val.\nfunc attributePrefixMatch(key, val string, n *html.Node, ignoreCase bool) bool {\n\treturn matchAttribute(n, key,\n\t\tfunc(s string) bool {\n\t\t\tif strings.TrimSpace(s) == \"\" {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif ignoreCase {\n\t\t\t\treturn strings.HasPrefix(strings.ToLower(s), strings.ToLower(val))\n\t\t\t}\n\t\t\treturn strings.HasPrefix(s, val)\n\t\t})\n}\n\n// attributeSuffixMatch matches elements where\n// the attribute named key ends with val.\nfunc attributeSuffixMatch(key, val string, n *html.Node, ignoreCase bool) bool {\n\treturn matchAttribute(n, key,\n\t\tfunc(s string) bool {\n\t\t\tif strings.TrimSpace(s) == \"\" {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif ignoreCase {\n\t\t\t\treturn strings.HasSuffix(strings.ToLower(s), strings.ToLower(val))\n\t\t\t}\n\t\t\treturn strings.HasSuffix(s, val)\n\t\t})\n}\n\n// attributeSubstringMatch matches nodes where\n// the attribute named key contains val.\nfunc attributeSubstringMatch(key, val string, n *html.Node, ignoreCase bool) bool {\n\treturn matchAttribute(n, key,\n\t\tfunc(s string) bool {\n\t\t\tif strings.TrimSpace(s) == \"\" {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif ignoreCase {\n\t\t\t\treturn strings.Contains(strings.ToLower(s), strings.ToLower(val))\n\t\t\t}\n\t\t\treturn strings.Contains(s, val)\n\t\t})\n}\n\n// attributeRegexMatch  matches nodes where\n// the attribute named key matches the regular expression rx\nfunc attributeRegexMatch(key string, rx *regexp.Regexp, n *html.Node) bool {\n\treturn matchAttribute(n, key,\n\t\tfunc(s string) bool {\n\t\t\treturn rx.MatchString(s)\n\t\t})\n}\n\nfunc (c attrSelector) Specificity() Specificity {\n\treturn Specificity{0, 1, 0}\n}\n\nfunc (c attrSelector) PseudoElement() string {\n\treturn \"\"\n}\n\n// see pseudo_classes.go for pseudo classes selectors\n\n// on a static context, some selectors can't match anything\ntype neverMatchSelector struct {\n\tvalue string\n}\n\nfunc (s neverMatchSelector) Match(n *html.Node) bool {\n\treturn false\n}\n\nfunc (s neverMatchSelector) Specificity() Specificity {\n\treturn Specificity{0, 0, 0}\n}\n\nfunc (c neverMatchSelector) PseudoElement() string {\n\treturn \"\"\n}\n\ntype compoundSelector struct {\n\tselectors     []Sel\n\tpseudoElement string\n}\n\n// Matches elements if each sub-selectors matches.\nfunc (t compoundSelector) Match(n *html.Node) bool {\n\tif len(t.selectors) == 0 {\n\t\treturn n.Type == html.ElementNode\n\t}\n\n\tfor _, sel := range t.selectors {\n\t\tif !sel.Match(n) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (s compoundSelector) Specificity() Specificity {\n\tvar out Specificity\n\tfor _, sel := range s.selectors {\n\t\tout = out.Add(sel.Specificity())\n\t}\n\tif s.pseudoElement != \"\" {\n\t\t// https://drafts.csswg.org/selectors-3/#specificity\n\t\tout = out.Add(Specificity{0, 0, 1})\n\t}\n\treturn out\n}\n\nfunc (c compoundSelector) PseudoElement() string {\n\treturn c.pseudoElement\n}\n\ntype combinedSelector struct {\n\tfirst      Sel\n\tcombinator byte\n\tsecond     Sel\n}\n\nfunc (t combinedSelector) Match(n *html.Node) bool {\n\tif t.first == nil {\n\t\treturn false // maybe we should panic\n\t}\n\tswitch t.combinator {\n\tcase 0:\n\t\treturn t.first.Match(n)\n\tcase ' ':\n\t\treturn descendantMatch(t.first, t.second, n)\n\tcase '>':\n\t\treturn childMatch(t.first, t.second, n)\n\tcase '+':\n\t\treturn siblingMatch(t.first, t.second, true, n)\n\tcase '~':\n\t\treturn siblingMatch(t.first, t.second, false, n)\n\tdefault:\n\t\tpanic(\"unknown combinator\")\n\t}\n}\n\n// matches an element if it matches d and has an ancestor that matches a.\nfunc descendantMatch(a, d Matcher, n *html.Node) bool {\n\tif !d.Match(n) {\n\t\treturn false\n\t}\n\n\tfor p := n.Parent; p != nil; p = p.Parent {\n\t\tif a.Match(p) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\n// matches an element if it matches d and its parent matches a.\nfunc childMatch(a, d Matcher, n *html.Node) bool {\n\treturn d.Match(n) && n.Parent != nil && a.Match(n.Parent)\n}\n\n// matches an element if it matches s2 and is preceded by an element that matches s1.\n// If adjacent is true, the sibling must be immediately before the element.\nfunc siblingMatch(s1, s2 Matcher, adjacent bool, n *html.Node) bool {\n\tif !s2.Match(n) {\n\t\treturn false\n\t}\n\n\tif adjacent {\n\t\tfor n = n.PrevSibling; n != nil; n = n.PrevSibling {\n\t\t\tif n.Type == html.TextNode || n.Type == html.CommentNode {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn s1.Match(n)\n\t\t}\n\t\treturn false\n\t}\n\n\t// Walk backwards looking for element that matches s1\n\tfor c := n.PrevSibling; c != nil; c = c.PrevSibling {\n\t\tif s1.Match(c) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (s combinedSelector) Specificity() Specificity {\n\tspec := s.first.Specificity()\n\tif s.second != nil {\n\t\tspec = spec.Add(s.second.Specificity())\n\t}\n\treturn spec\n}\n\n// on combinedSelector, a pseudo-element only makes sens on the last\n// selector, although others increase specificity.\nfunc (c combinedSelector) PseudoElement() string {\n\tif c.second == nil {\n\t\treturn \"\"\n\t}\n\treturn c.second.PseudoElement()\n}\n\n// A SelectorGroup is a list of selectors, which matches if any of the\n// individual selectors matches.\ntype SelectorGroup []Sel\n\n// Match returns true if the node matches one of the single selectors.\nfunc (s SelectorGroup) Match(n *html.Node) bool {\n\tfor _, sel := range s {\n\t\tif sel.Match(n) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/andybalholm/cascadia/serialize.go",
    "content": "package cascadia\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// implements the reverse operation Sel -> string\n\nvar specialCharReplacer *strings.Replacer\n\nfunc init() {\n\tvar pairs []string\n\tfor _, s := range \",!\\\"#$%&'()*+ -./:;<=>?@[\\\\]^`{|}~\" {\n\t\tpairs = append(pairs, string(s), \"\\\\\"+string(s))\n\t}\n\tspecialCharReplacer = strings.NewReplacer(pairs...)\n}\n\n// espace special CSS char\nfunc escape(s string) string { return specialCharReplacer.Replace(s) }\n\nfunc (c tagSelector) String() string {\n\treturn c.tag\n}\n\nfunc (c idSelector) String() string {\n\treturn \"#\" + escape(c.id)\n}\n\nfunc (c classSelector) String() string {\n\treturn \".\" + escape(c.class)\n}\n\nfunc (c attrSelector) String() string {\n\tval := c.val\n\tif c.operation == \"#=\" {\n\t\tval = c.regexp.String()\n\t} else if c.operation != \"\" {\n\t\tval = fmt.Sprintf(`\"%s\"`, val)\n\t}\n\n\tignoreCase := \"\"\n\n\tif c.insensitive {\n\t\tignoreCase = \" i\"\n\t}\n\n\treturn fmt.Sprintf(`[%s%s%s%s]`, c.key, c.operation, val, ignoreCase)\n}\n\nfunc (c relativePseudoClassSelector) String() string {\n\treturn fmt.Sprintf(\":%s(%s)\", c.name, c.match.String())\n}\n\nfunc (c containsPseudoClassSelector) String() string {\n\ts := \"contains\"\n\tif c.own {\n\t\ts += \"Own\"\n\t}\n\treturn fmt.Sprintf(`:%s(\"%s\")`, s, c.value)\n}\n\nfunc (c regexpPseudoClassSelector) String() string {\n\ts := \"matches\"\n\tif c.own {\n\t\ts += \"Own\"\n\t}\n\treturn fmt.Sprintf(\":%s(%s)\", s, c.regexp.String())\n}\n\nfunc (c nthPseudoClassSelector) String() string {\n\tif c.a == 0 && c.b == 1 { // special cases\n\t\ts := \":first-\"\n\t\tif c.last {\n\t\t\ts = \":last-\"\n\t\t}\n\t\tif c.ofType {\n\t\t\ts += \"of-type\"\n\t\t} else {\n\t\t\ts += \"child\"\n\t\t}\n\t\treturn s\n\t}\n\tvar name string\n\tswitch [2]bool{c.last, c.ofType} {\n\tcase [2]bool{true, true}:\n\t\tname = \"nth-last-of-type\"\n\tcase [2]bool{true, false}:\n\t\tname = \"nth-last-child\"\n\tcase [2]bool{false, true}:\n\t\tname = \"nth-of-type\"\n\tcase [2]bool{false, false}:\n\t\tname = \"nth-child\"\n\t}\n\ts := fmt.Sprintf(\"+%d\", c.b)\n\tif c.b < 0 { // avoid +-8 invalid syntax\n\t\ts = strconv.Itoa(c.b)\n\t}\n\treturn fmt.Sprintf(\":%s(%dn%s)\", name, c.a, s)\n}\n\nfunc (c onlyChildPseudoClassSelector) String() string {\n\tif c.ofType {\n\t\treturn \":only-of-type\"\n\t}\n\treturn \":only-child\"\n}\n\nfunc (c inputPseudoClassSelector) String() string {\n\treturn \":input\"\n}\n\nfunc (c emptyElementPseudoClassSelector) String() string {\n\treturn \":empty\"\n}\n\nfunc (c rootPseudoClassSelector) String() string {\n\treturn \":root\"\n}\n\nfunc (c linkPseudoClassSelector) String() string {\n\treturn \":link\"\n}\n\nfunc (c langPseudoClassSelector) String() string {\n\treturn fmt.Sprintf(\":lang(%s)\", c.lang)\n}\n\nfunc (c neverMatchSelector) String() string {\n\treturn c.value\n}\n\nfunc (c enabledPseudoClassSelector) String() string {\n\treturn \":enabled\"\n}\n\nfunc (c disabledPseudoClassSelector) String() string {\n\treturn \":disabled\"\n}\n\nfunc (c checkedPseudoClassSelector) String() string {\n\treturn \":checked\"\n}\n\nfunc (c compoundSelector) String() string {\n\tif len(c.selectors) == 0 && c.pseudoElement == \"\" {\n\t\treturn \"*\"\n\t}\n\tchunks := make([]string, len(c.selectors))\n\tfor i, sel := range c.selectors {\n\t\tchunks[i] = sel.String()\n\t}\n\ts := strings.Join(chunks, \"\")\n\tif c.pseudoElement != \"\" {\n\t\ts += \"::\" + c.pseudoElement\n\t}\n\treturn s\n}\n\nfunc (c combinedSelector) String() string {\n\tstart := c.first.String()\n\tif c.second != nil {\n\t\tstart += fmt.Sprintf(\" %s %s\", string(c.combinator), c.second.String())\n\t}\n\treturn start\n}\n\nfunc (c SelectorGroup) String() string {\n\tck := make([]string, len(c))\n\tfor i, s := range c {\n\t\tck[i] = s.String()\n\t}\n\treturn strings.Join(ck, \", \")\n}\n"
  },
  {
    "path": "vendor/github.com/andybalholm/cascadia/specificity.go",
    "content": "package cascadia\n\n// Specificity is the CSS specificity as defined in\n// https://www.w3.org/TR/selectors/#specificity-rules\n// with the convention Specificity = [A,B,C].\ntype Specificity [3]int\n\n// returns `true` if s < other (strictly), false otherwise\nfunc (s Specificity) Less(other Specificity) bool {\n\tfor i := range s {\n\t\tif s[i] < other[i] {\n\t\t\treturn true\n\t\t}\n\t\tif s[i] > other[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (s Specificity) Add(other Specificity) Specificity {\n\tfor i, sp := range other {\n\t\ts[i] += sp\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/htmlquery/.gitignore",
    "content": "# vscode\n.vscode\ndebug\n*.test\n\n./build\n\n# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof"
  },
  {
    "path": "vendor/github.com/antchfx/htmlquery/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.9.x\n  - 1.12.x\n  - 1.13.x\n\ninstall:\n  - go get golang.org/x/net/html/charset\n  - go get golang.org/x/net/html\n  - go get github.com/antchfx/xpath\n  - go get github.com/mattn/goveralls\n  - go get github.com/golang/groupcache\n\nscript:\n  - $HOME/gopath/bin/goveralls -service=travis-ci"
  },
  {
    "path": "vendor/github.com/antchfx/htmlquery/LICENSE",
    "content": "Permission 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\nall copies 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\nTHE SOFTWARE."
  },
  {
    "path": "vendor/github.com/antchfx/htmlquery/README.md",
    "content": "htmlquery\n====\n[![Build Status](https://travis-ci.org/antchfx/htmlquery.svg?branch=master)](https://travis-ci.org/antchfx/htmlquery)\n[![Coverage Status](https://coveralls.io/repos/github/antchfx/htmlquery/badge.svg?branch=master)](https://coveralls.io/github/antchfx/htmlquery?branch=master)\n[![GoDoc](https://godoc.org/github.com/antchfx/htmlquery?status.svg)](https://godoc.org/github.com/antchfx/htmlquery)\n[![Go Report Card](https://goreportcard.com/badge/github.com/antchfx/htmlquery)](https://goreportcard.com/report/github.com/antchfx/htmlquery)\n\nOverview\n====\n\n`htmlquery` is an XPath query package for HTML, lets you extract data or evaluate from HTML documents by an XPath expression.\n\n`htmlquery` built-in the query object caching feature based on [LRU](https://godoc.org/github.com/golang/groupcache/lru), this feature will caching the recently used XPATH query string. Enable query caching can avoid re-compile XPath expression each query. \n\nYou can visit this page to learn about the supported XPath(1.0/2.0) syntax. https://github.com/antchfx/xpath\n\nXPath query packages for Go\n===\n| Name                                              | Description                               |\n| ------------------------------------------------- | ----------------------------------------- |\n| [htmlquery](https://github.com/antchfx/htmlquery) | XPath query package for the HTML document |\n| [xmlquery](https://github.com/antchfx/xmlquery)   | XPath query package for the XML document  |\n| [jsonquery](https://github.com/antchfx/jsonquery) | XPath query package for the JSON document |\n\nInstallation\n====\n\n```\ngo get github.com/antchfx/htmlquery\n```\n\nGetting Started\n====\n\n#### Query, returns matched elements or error.\n\n```go\nnodes, err := htmlquery.QueryAll(doc, \"//a\")\nif err != nil {\n\tpanic(`not a valid XPath expression.`)\n}\n```\n\n#### Load HTML document from URL.\n\n```go\ndoc, err := htmlquery.LoadURL(\"http://example.com/\")\n```\n\n#### Load HTML from document.\n\n```go\nfilePath := \"/home/user/sample.html\"\ndoc, err := htmlquery.LoadDoc(filePath)\n```\n\n#### Load HTML document from string.\n\n```go\ns := `<html>....</html>`\ndoc, err := htmlquery.Parse(strings.NewReader(s))\n```\n\n#### Find all A elements.\n\n```go\nlist := htmlquery.Find(doc, \"//a\")\n```\n\n#### Find all A elements that have `href` attribute.\n\n```go\nlist := htmlquery.Find(doc, \"//a[@href]\")\t\n```\n\n#### Find all A elements with `href` attribute and only return `href` value.\n\n```go\nlist := htmlquery.Find(doc, \"//a/@href\")\t\nfor _ , n := range list{\n\tfmt.Println(htmlquery.SelectAttr(n, \"href\")) // output @href value\n}\n```\n\n### Find the third A element.\n\n```go\na := htmlquery.FindOne(doc, \"//a[3]\")\n```\n\n### Find children element (img) under A `href` and print the source\n```go\na := htmlquery.FindOne(doc, \"//a\")\nimg := htmlquery.FindOne(a, \"//img\")\nfmt.Prinln(htmlquery.SelectAttr(img, \"src\")) // output @src value\n```\n\n#### Evaluate the number of all IMG element.\n\n```go\nexpr, _ := xpath.Compile(\"count(//img)\")\nv := expr.Evaluate(htmlquery.CreateXPathNavigator(doc)).(float64)\nfmt.Printf(\"total count is %f\", v)\n```\n\n\nQuick Starts\n===\n\n```go\nfunc main() {\n\tdoc, err := htmlquery.LoadURL(\"https://www.bing.com/search?q=golang\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// Find all news item.\n\tlist, err := htmlquery.QueryAll(doc, \"//ol/li\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfor i, n := range list {\n\t\ta := htmlquery.FindOne(n, \"//a\")\n\t\tif a != nil {\n\t\t    fmt.Printf(\"%d %s(%s)\\n\", i, htmlquery.InnerText(a), htmlquery.SelectAttr(a, \"href\"))\n\t\t}\n\t}\n}\n```\n\n\nFAQ\n====\n\n#### `Find()` vs `QueryAll()`, which is better?\n\n`Find` and `QueryAll` both do the same things, searches all of matched html nodes.\nThe `Find` will panics if you give an error XPath query, but `QueryAll` will return an error for you.\n\n#### Can I save my query expression object for the next query?\n\nYes, you can. We offer the `QuerySelector` and `QuerySelectorAll` methods, It will accept your query expression object.\n\nCache a query expression object(or reused) will avoid re-compile XPath query expression, improve your query performance.\n\n#### XPath query object cache performance\n\n```\ngoos: windows\ngoarch: amd64\npkg: github.com/antchfx/htmlquery\nBenchmarkSelectorCache-4                20000000                55.2 ns/op\nBenchmarkDisableSelectorCache-4           500000              3162 ns/op\n```\n\n#### How to disable caching?\n\n```\nhtmlquery.DisableSelectorCache = true\n```\n\nQuestions\n===\nPlease let me know if you have any questions.\n"
  },
  {
    "path": "vendor/github.com/antchfx/htmlquery/cache.go",
    "content": "package htmlquery\n\nimport (\n\t\"sync\"\n\n\t\"github.com/antchfx/xpath\"\n\t\"github.com/golang/groupcache/lru\"\n)\n\n// DisableSelectorCache will disable caching for the query selector if value is true.\nvar DisableSelectorCache = false\n\n// SelectorCacheMaxEntries allows how many selector object can be caching. Default is 50.\n// Will disable caching if SelectorCacheMaxEntries <= 0.\nvar SelectorCacheMaxEntries = 50\n\nvar (\n\tcacheOnce  sync.Once\n\tcache      *lru.Cache\n\tcacheMutex sync.Mutex\n)\n\nfunc getQuery(expr string) (*xpath.Expr, error) {\n\tif DisableSelectorCache || SelectorCacheMaxEntries <= 0 {\n\t\treturn xpath.Compile(expr)\n\t}\n\tcacheOnce.Do(func() {\n\t\tcache = lru.New(SelectorCacheMaxEntries)\n\t})\n\tcacheMutex.Lock()\n\tdefer cacheMutex.Unlock()\n\tif v, ok := cache.Get(expr); ok {\n\t\treturn v.(*xpath.Expr), nil\n\t}\n\tv, err := xpath.Compile(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcache.Add(expr, v)\n\treturn v, nil\n\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/htmlquery/query.go",
    "content": "/*\nPackage htmlquery provides extract data from HTML documents using XPath expression.\n*/\npackage htmlquery\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/antchfx/xpath\"\n\t\"golang.org/x/net/html\"\n\t\"golang.org/x/net/html/charset\"\n)\n\nvar _ xpath.NodeNavigator = &NodeNavigator{}\n\n// CreateXPathNavigator creates a new xpath.NodeNavigator for the specified html.Node.\nfunc CreateXPathNavigator(top *html.Node) *NodeNavigator {\n\treturn &NodeNavigator{curr: top, root: top, attr: -1}\n}\n\n// Find is like QueryAll but Will panics if the expression `expr` cannot be parsed.\n//\n// See `QueryAll()` function.\nfunc Find(top *html.Node, expr string) []*html.Node {\n\tnodes, err := QueryAll(top, expr)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn nodes\n}\n\n// FindOne is like Query but will panics if the expression `expr` cannot be parsed.\n// See `Query()` function.\nfunc FindOne(top *html.Node, expr string) *html.Node {\n\tnode, err := Query(top, expr)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn node\n}\n\n// QueryAll searches the html.Node that matches by the specified XPath expr.\n// Return an error if the expression `expr` cannot be parsed.\nfunc QueryAll(top *html.Node, expr string) ([]*html.Node, error) {\n\texp, err := getQuery(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnodes := QuerySelectorAll(top, exp)\n\treturn nodes, nil\n}\n\n// Query runs the given XPath expression against the given html.Node and\n// returns the first matching html.Node, or nil if no matches are found.\n//\n// Returns an error if the expression `expr` cannot be parsed.\nfunc Query(top *html.Node, expr string) (*html.Node, error) {\n\texp, err := getQuery(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn QuerySelector(top, exp), nil\n}\n\n// QuerySelector returns the first matched html.Node by the specified XPath selector.\nfunc QuerySelector(top *html.Node, selector *xpath.Expr) *html.Node {\n\tt := selector.Select(CreateXPathNavigator(top))\n\tif t.MoveNext() {\n\t\treturn getCurrentNode(t.Current().(*NodeNavigator))\n\t}\n\treturn nil\n}\n\n// QuerySelectorAll searches all of the html.Node that matches the specified XPath selectors.\nfunc QuerySelectorAll(top *html.Node, selector *xpath.Expr) []*html.Node {\n\tvar elems []*html.Node\n\tt := selector.Select(CreateXPathNavigator(top))\n\tfor t.MoveNext() {\n\t\tnav := t.Current().(*NodeNavigator)\n\t\tn := getCurrentNode(nav)\n\t\telems = append(elems, n)\n\t}\n\treturn elems\n}\n\n// LoadURL loads the HTML document from the specified URL.\nfunc LoadURL(url string) (*html.Node, error) {\n\tresp, err := http.Get(url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tr, err := charset.NewReader(resp.Body, resp.Header.Get(\"Content-Type\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn html.Parse(r)\n}\n\n// LoadDoc loads the HTML document from the specified file path.\nfunc LoadDoc(path string) (*html.Node, error) {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\treturn html.Parse(bufio.NewReader(f))\n}\n\nfunc getCurrentNode(n *NodeNavigator) *html.Node {\n\tif n.NodeType() == xpath.AttributeNode {\n\t\tchildNode := &html.Node{\n\t\t\tType: html.TextNode,\n\t\t\tData: n.Value(),\n\t\t}\n\t\treturn &html.Node{\n\t\t\tType:       html.ElementNode,\n\t\t\tData:       n.LocalName(),\n\t\t\tFirstChild: childNode,\n\t\t\tLastChild:  childNode,\n\t\t}\n\n\t}\n\treturn n.curr\n}\n\n// Parse returns the parse tree for the HTML from the given Reader.\nfunc Parse(r io.Reader) (*html.Node, error) {\n\treturn html.Parse(r)\n}\n\n// InnerText returns the text between the start and end tags of the object.\nfunc InnerText(n *html.Node) string {\n\tvar output func(*strings.Builder, *html.Node)\n\toutput = func(b *strings.Builder, n *html.Node) {\n\t\tswitch n.Type {\n\t\tcase html.TextNode:\n\t\t\tb.WriteString(n.Data)\n\t\t\treturn\n\t\tcase html.CommentNode:\n\t\t\treturn\n\t\t}\n\t\tfor child := n.FirstChild; child != nil; child = child.NextSibling {\n\t\t\toutput(b, child)\n\t\t}\n\t}\n\n\tvar b strings.Builder\n\toutput(&b, n)\n\treturn b.String()\n}\n\n// SelectAttr returns the attribute value with the specified name.\nfunc SelectAttr(n *html.Node, name string) (val string) {\n\tif n == nil {\n\t\treturn\n\t}\n\tif n.Type == html.ElementNode && n.Parent == nil && name == n.Data {\n\t\treturn InnerText(n)\n\t}\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == name {\n\t\t\tval = attr.Val\n\t\t\tbreak\n\t\t}\n\t}\n\treturn\n}\n\n// ExistsAttr returns whether attribute with specified name exists.\nfunc ExistsAttr(n *html.Node, name string) bool {\n\tif n == nil {\n\t\treturn false\n\t}\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// OutputHTML returns the text including tags name.\nfunc OutputHTML(n *html.Node, self bool) string {\n\tvar b strings.Builder\n\tif self {\n\t\thtml.Render(&b, n)\n\t} else {\n\t\tfor n := n.FirstChild; n != nil; n = n.NextSibling {\n\t\t\thtml.Render(&b, n)\n\t\t}\n\t}\n\treturn b.String()\n}\n\ntype NodeNavigator struct {\n\troot, curr *html.Node\n\tattr       int\n}\n\nfunc (h *NodeNavigator) Current() *html.Node {\n\treturn h.curr\n}\n\nfunc (h *NodeNavigator) NodeType() xpath.NodeType {\n\tswitch h.curr.Type {\n\tcase html.CommentNode:\n\t\treturn xpath.CommentNode\n\tcase html.TextNode:\n\t\treturn xpath.TextNode\n\tcase html.DocumentNode:\n\t\treturn xpath.RootNode\n\tcase html.ElementNode:\n\t\tif h.attr != -1 {\n\t\t\treturn xpath.AttributeNode\n\t\t}\n\t\treturn xpath.ElementNode\n\tcase html.DoctypeNode:\n\t\t// ignored <!DOCTYPE HTML> declare and as Root-Node type.\n\t\treturn xpath.RootNode\n\t}\n\tpanic(fmt.Sprintf(\"unknown HTML node type: %v\", h.curr.Type))\n}\n\nfunc (h *NodeNavigator) LocalName() string {\n\tif h.attr != -1 {\n\t\treturn h.curr.Attr[h.attr].Key\n\t}\n\treturn h.curr.Data\n}\n\nfunc (*NodeNavigator) Prefix() string {\n\treturn \"\"\n}\n\nfunc (h *NodeNavigator) Value() string {\n\tswitch h.curr.Type {\n\tcase html.CommentNode:\n\t\treturn h.curr.Data\n\tcase html.ElementNode:\n\t\tif h.attr != -1 {\n\t\t\treturn h.curr.Attr[h.attr].Val\n\t\t}\n\t\treturn InnerText(h.curr)\n\tcase html.TextNode:\n\t\treturn h.curr.Data\n\t}\n\treturn \"\"\n}\n\nfunc (h *NodeNavigator) Copy() xpath.NodeNavigator {\n\tn := *h\n\treturn &n\n}\n\nfunc (h *NodeNavigator) MoveToRoot() {\n\th.curr = h.root\n}\n\nfunc (h *NodeNavigator) MoveToParent() bool {\n\tif h.attr != -1 {\n\t\th.attr = -1\n\t\treturn true\n\t} else if node := h.curr.Parent; node != nil {\n\t\th.curr = node\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (h *NodeNavigator) MoveToNextAttribute() bool {\n\tif h.attr >= len(h.curr.Attr)-1 {\n\t\treturn false\n\t}\n\th.attr++\n\treturn true\n}\n\nfunc (h *NodeNavigator) MoveToChild() bool {\n\tif h.attr != -1 {\n\t\treturn false\n\t}\n\tif node := h.curr.FirstChild; node != nil {\n\t\th.curr = node\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (h *NodeNavigator) MoveToFirst() bool {\n\tif h.attr != -1 || h.curr.PrevSibling == nil {\n\t\treturn false\n\t}\n\tfor {\n\t\tnode := h.curr.PrevSibling\n\t\tif node == nil {\n\t\t\tbreak\n\t\t}\n\t\th.curr = node\n\t}\n\treturn true\n}\n\nfunc (h *NodeNavigator) String() string {\n\treturn h.Value()\n}\n\nfunc (h *NodeNavigator) MoveToNext() bool {\n\tif h.attr != -1 {\n\t\treturn false\n\t}\n\tif node := h.curr.NextSibling; node != nil {\n\t\th.curr = node\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (h *NodeNavigator) MoveToPrevious() bool {\n\tif h.attr != -1 {\n\t\treturn false\n\t}\n\tif node := h.curr.PrevSibling; node != nil {\n\t\th.curr = node\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (h *NodeNavigator) MoveTo(other xpath.NodeNavigator) bool {\n\tnode, ok := other.(*NodeNavigator)\n\tif !ok || node.root != h.root {\n\t\treturn false\n\t}\n\n\th.curr = node.curr\n\th.attr = node.attr\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/.gitignore",
    "content": "# vscode\n.vscode\ndebug\n*.test\n\n./build\n\n# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.9.x\n  - 1.12.x\n  - 1.13.x\n  - 1.14.x\n  - 1.15.x\n\ninstall:\n  - go get golang.org/x/net/html/charset\n  - go get github.com/antchfx/xpath\n  - go get github.com/mattn/goveralls\n  - go get github.com/golang/groupcache\n\nscript:\n  - $HOME/gopath/bin/goveralls -service=travis-ci\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/LICENSE",
    "content": "Permission 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\nall copies 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\nTHE SOFTWARE."
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/README.md",
    "content": "xmlquery\n====\n[![Build Status](https://travis-ci.org/antchfx/xmlquery.svg?branch=master)](https://travis-ci.org/antchfx/xmlquery)\n[![Coverage Status](https://coveralls.io/repos/github/antchfx/xmlquery/badge.svg?branch=master)](https://coveralls.io/github/antchfx/xmlquery?branch=master)\n[![GoDoc](https://godoc.org/github.com/antchfx/xmlquery?status.svg)](https://godoc.org/github.com/antchfx/xmlquery)\n[![Go Report Card](https://goreportcard.com/badge/github.com/antchfx/xmlquery)](https://goreportcard.com/report/github.com/antchfx/xmlquery)\n\nOverview\n===\n\n`xmlquery` is an XPath query package for XML documents, allowing you to extract \ndata or evaluate from XML documents with an XPath expression.\n\n`xmlquery` has a built-in query object caching feature that caches recently used\nXPATH query strings. Enabling caching can avoid recompile XPath expression for \neach query. \n\nYou can visit this page to learn about the supported XPath(1.0/2.0) syntax. https://github.com/antchfx/xpath\n\n[htmlquery](https://github.com/antchfx/htmlquery)\t- Package for the HTML document query.\n\n[xmlquery](https://github.com/antchfx/xmlquery)\t- Package for the XML document query.\n\n[jsonquery](https://github.com/antchfx/jsonquery)\t- Package for the JSON document query.\n\nInstallation\n====\n```\n $ go get github.com/antchfx/xmlquery\n```\n\n\nQuick Starts\n===\n\n```go\nimport (\n\t\"github.com/antchfx/xmlquery\"\n)\n\nfunc main(){\n\ts := `<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<rss version=\"2.0\">\n<channel>\n  <title>W3Schools Home Page</title>\n  <link>https://www.w3schools.com</link>\n  <description>Free web building tutorials</description>\n  <item>\n    <title>RSS Tutorial</title>\n    <link>https://www.w3schools.com/xml/xml_rss.asp</link>\n    <description>New RSS tutorial on W3Schools</description>\n  </item>\n  <item>\n    <title>XML Tutorial</title>\n    <link>https://www.w3schools.com/xml</link>\n    <description>New XML tutorial on W3Schools</description>\n  </item>\n</channel>\n</rss>`\n\n\tdoc, err := xmlquery.Parse(strings.NewReader(s))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tchannel := xmlquery.FindOne(doc, \"//channel\")\n\tif n := channel.SelectElement(\"title\"); n != nil {\n\t\tfmt.Printf(\"title: %s\\n\", n.InnerText())\n\t}\n\tif n := channel.SelectElement(\"link\"); n != nil {\n\t\tfmt.Printf(\"link: %s\\n\", n.InnerText())\n\t}\n\tfor i, n := range xmlquery.Find(doc, \"//item/title\") {\n\t\tfmt.Printf(\"#%d %s\\n\", i, n.InnerText())\n\t}\n}\n```\n\nGetting Started\n===\n\n### Find specified XPath query.\n\n```go\nlist, err := xmlquery.QueryAll(doc, \"a\")\nif err != nil {\n\tpanic(err)\n}\n```\n\n#### Parse an XML from URL.\n\n```go\ndoc, err := xmlquery.LoadURL(\"http://www.example.com/sitemap.xml\")\n```\n\n#### Parse an XML from string.\n\n```go\ns := `<?xml version=\"1.0\" encoding=\"utf-8\"?><rss version=\"2.0\"></rss>`\ndoc, err := xmlquery.Parse(strings.NewReader(s))\n```\n\n#### Parse an XML from io.Reader.\n\n```go\nf, err := os.Open(\"../books.xml\")\ndoc, err := xmlquery.Parse(f)\n```\n\n#### Parse an XML in a stream fashion (simple case without elements filtering).\n\n```go\nf, _ := os.Open(\"../books.xml\")\np, err := xmlquery.CreateStreamParser(f, \"/bookstore/book\")\nfor {\n\tn, err := p.Read()\n\tif err == io.EOF {\n\t\tbreak\n\t}\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(n)\n}\n```\n\nNotes: `CreateStreamParser()` used for saving memory if your had a large XML file to parse.\n\n#### Parse an XML in a stream fashion (simple case advanced element filtering).\n\n```go\nf, _ := os.Open(\"../books.xml\")\np, err := xmlquery.CreateStreamParser(f, \"/bookstore/book\", \"/bookstore/book[price>=10]\")\nfor {\n\tn, err := p.Read()\n\tif err == io.EOF {\n\t\tbreak\n\t}\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(n)\n}\n```\n\n#### Find authors of all books in the bookstore.\n\n```go\nlist := xmlquery.Find(doc, \"//book//author\")\n// or\nlist := xmlquery.Find(doc, \"//author\")\n```\n\n#### Find the second book.\n\n```go\nbook := xmlquery.FindOne(doc, \"//book[2]\")\n```\n\n#### Find all book elements and only get `id` attribute. (New Feature)\n\n```go\nlist := xmlquery.Find(doc,\"//book/@id\")\n```\n\n#### Find all books with id `bk104`.\n\n```go\nlist := xmlquery.Find(doc, \"//book[@id='bk104']\")\n```\n\n#### Find all books with price less than 5.\n\n```go\nlist := xmlquery.Find(doc, \"//book[price<5]\")\n```\n\n#### Evaluate total price of all books.\n\n```go\nexpr, err := xpath.Compile(\"sum(//book/price)\")\nprice := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)\nfmt.Printf(\"total price: %f\\n\", price)\n```\n\n#### Evaluate number of all book elements.\n\n```go\nexpr, err := xpath.Compile(\"count(//book)\")\nprice := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)\n```\n\nAdvanced Features\n====\n\n### Parse `UTF-16` XML file with `ParseWithOptions()`.\n\n```go\nf, _ := os.Open(`UTF-16.XML`)\n// Convert UTF-16 XML to UTF-8\nutf16ToUtf8Transformer := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder()\nutf8Reader := transform.NewReader(f, utf16ToUtf8Transformer)\n// Sets `CharsetReader`\noptions := xmlquery.ParserOptions{\n\tDecoder: &xmlquery.DecoderOptions{\n\t\tCharsetReader: func(charset string, input io.Reader) (io.Reader, error) {\n\t\t\treturn input, nil\n\t\t},\n\t},\n}\ndoc, err := xmlquery.ParseWithOptions(utf8Reader, options)\n```\n\n### Query with custom namespace prefix.\n\n```go\ns := `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<pd:ProcessDefinition xmlns:pd=\"http://xmlns.xyz.com/process/2003\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\n<pd:activity name=\"Invoke Request-Response Service\">\n<pd:type>RequestReplyActivity</pd:type>\n<pd:resourceType>OpClientReqActivity</pd:resourceType>\n<pd:x>300</pd:x>\n<pd:y>80</pd:y>\n</pd:activity>\n</pd:ProcessDefinition>`\nnsMap := map[string]string{\n\t\"q\": \"http://xmlns.xyz.com/process/2003\",\n\t\"r\": \"http://www.w3.org/1999/XSL/Transform\",\n\t\"s\": \"http://www.w3.org/2001/XMLSchema\",\n}\nexpr, _ := xpath.CompileWithNS(\"//q:activity\", nsMap)\nnode := xmlquery.QuerySelector(doc, expr)\n```\n\n#### Create XML document without call `xml.Marshal`.\n\n```go\ndoc := &xmlquery.Node{\n\tType: xmlquery.DeclarationNode,\n\tData: \"xml\",\n\tAttr: []xml.Attr{\n\t\txml.Attr{Name: xml.Name{Local: \"version\"}, Value: \"1.0\"},\n\t},\n}\nroot := &xmlquery.Node{\n\tData: \"rss\",\n\tType: xmlquery.ElementNode,\n}\ndoc.FirstChild = root\nchannel := &xmlquery.Node{\n\tData: \"channel\",\n\tType: xmlquery.ElementNode,\n}\nroot.FirstChild = channel\ntitle := &xmlquery.Node{\n\tData: \"title\",\n\tType: xmlquery.ElementNode,\n}\ntitle_text := &xmlquery.Node{\n\tData: \"W3Schools Home Page\",\n\tType: xmlquery.TextNode,\n}\ntitle.FirstChild = title_text\nchannel.FirstChild = title\n\nfmt.Println(doc.OutputXML(true))\nfmt.Println(doc.OutputXMLWithOptions(WithOutputSelf()))\n```\n\nOutput:\n\n```xml\n<?xml version=\"1.0\"?><rss><channel><title>W3Schools Home Page</title></channel></rss>\n```\n\nFAQ\n====\n\n#### `Find()` vs `QueryAll()`, which is better?\n\n`Find` and `QueryAll` both do the same thing: searches all of matched XML nodes.\n`Find` panics if provided with an invalid XPath query, while `QueryAll` returns\nan error.\n\n#### Can I save my query expression object for the next query?\n\nYes, you can. We provide `QuerySelector` and `QuerySelectorAll` methods; they \naccept your query expression object.\n\nCaching a query expression object avoids recompiling the XPath query \nexpression, improving query performance.\n\nQuestions\n===\nPlease let me know if you have any questions\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/books.xml",
    "content": "<?xml version=\"1.0\"?>\n<?xml-stylesheet type=\"text/xsl\" ?>\n<bookstore specialty=\"novel\">\n   <book id=\"bk101\">\n      <author>Gambardella, Matthew</author>\n      <title>XML Developer's Guide</title>\n      <genre>Computer</genre>\n      <price>44.95</price>\n      <publish_date>2000-10-01</publish_date>\n      <description>An in-depth look at creating applications \n      with XML.</description>\n   </book>\n   <book id=\"bk102\">\n      <author>Ralls, Kim</author>\n      <title>Midnight Rain</title>\n      <genre>Fantasy</genre>\n      <price>5.95</price>\n      <publish_date>2000-12-16</publish_date>\n      <description>A former architect battles corporate zombies, \n      an evil sorceress, and her own childhood to become queen \n      of the world.</description>\n   </book>\n   <book id=\"bk103\">\n      <author>Corets, Eva</author>\n      <title>Maeve Ascendant</title>\n      <genre>Fantasy</genre>\n      <price>5.95</price>\n      <publish_date>2000-11-17</publish_date>\n      <description>After the collapse of a nanotechnology \n      society in England, the young survivors lay the \n      foundation for a new society.</description>\n   </book>\n   <book id=\"bk104\">\n      <author>Corets, Eva</author>\n      <title>Oberon's Legacy</title>\n      <genre>Fantasy</genre>\n      <price>5.95</price>\n      <publish_date>2001-03-10</publish_date>\n      <description>In post-apocalypse England, the mysterious \n      agent known only as Oberon helps to create a new life \n      for the inhabitants of London. Sequel to Maeve \n      Ascendant.</description>\n   </book>\n   <book id=\"bk105\">\n      <author>Corets, Eva</author>\n      <title>The Sundered Grail</title>\n      <genre>Fantasy</genre>\n      <price>5.95</price>\n      <publish_date>2001-09-10</publish_date>\n      <description>The two daughters of Maeve, half-sisters, \n      battle one another for control of England. Sequel to \n      Oberon's Legacy.</description>\n   </book>\n   <book id=\"bk106\">\n      <author>Randall, Cynthia</author>\n      <title>Lover Birds</title>\n      <genre>Romance</genre>\n      <price>4.95</price>\n      <publish_date>2000-09-02</publish_date>\n      <description>When Carla meets Paul at an ornithology \n      conference, tempers fly as feathers get ruffled.</description>\n   </book>\n   <book id=\"bk107\">\n      <author>Thurman, Paula</author>\n      <title>Splish Splash</title>\n      <genre>Romance</genre>\n      <price>4.95</price>\n      <publish_date>2000-11-02</publish_date>\n      <description>A deep sea diver finds true love twenty \n      thousand leagues beneath the sea.</description>\n   </book>\n   <book id=\"bk108\">\n      <author>Knorr, Stefan</author>\n      <title>Creepy Crawlies</title>\n      <genre>Horror</genre>\n      <price>4.95</price>\n      <publish_date>2000-12-06</publish_date>\n      <description>An anthology of horror stories about roaches,\n      centipedes, scorpions  and other insects.</description>\n   </book>\n   <book id=\"bk109\">\n      <author>Kress, Peter</author>\n      <title>Paradox Lost</title>\n      <genre>Science Fiction</genre>\n      <price>6.95</price>\n      <publish_date>2000-11-02</publish_date>\n      <description>After an inadvertant trip through a Heisenberg\n      Uncertainty Device, James Salway discovers the problems \n      of being quantum.</description>\n   </book>\n   <book id=\"bk110\">\n      <author>O'Brien, Tim</author>\n      <title>Microsoft .NET: The Programming Bible</title>\n      <genre>Computer</genre>\n      <price>36.95</price>\n      <publish_date>2000-12-09</publish_date>\n      <description>Microsoft's .NET initiative is explored in \n      detail in this deep programmer's reference.</description>\n   </book>\n   <book id=\"bk111\">\n      <author>O'Brien, Tim</author>\n      <title>MSXML3: A Comprehensive Guide</title>\n      <genre>Computer</genre>\n      <price>36.95</price>\n      <publish_date>2000-12-01</publish_date>\n      <description>The Microsoft MSXML3 parser is covered in \n      detail, with attention to XML DOM interfaces, XSLT processing, \n      SAX and more.</description>\n   </book>\n   <book id=\"bk112\">\n      <author>Galos, Mike</author>\n      <title>Visual Studio 7: A Comprehensive Guide</title>\n      <genre>Computer</genre>\n      <price>49.95</price>\n      <publish_date>2001-04-16</publish_date>\n      <description>Microsoft Visual Studio 7 is explored in depth,\n      looking at how Visual Basic, Visual C++, C#, and ASP+ are \n      integrated into a comprehensive development \n      environment.</description>\n   </book>\n</bookstore>"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/cache.go",
    "content": "package xmlquery\n\nimport (\n\t\"sync\"\n\n\t\"github.com/golang/groupcache/lru\"\n\n\t\"github.com/antchfx/xpath\"\n)\n\n// DisableSelectorCache will disable caching for the query selector if value is true.\nvar DisableSelectorCache = false\n\n// SelectorCacheMaxEntries allows how many selector object can be caching. Default is 50.\n// Will disable caching if SelectorCacheMaxEntries <= 0.\nvar SelectorCacheMaxEntries = 50\n\nvar (\n\tcacheOnce  sync.Once\n\tcache      *lru.Cache\n\tcacheMutex sync.Mutex\n)\n\nfunc getQuery(expr string) (*xpath.Expr, error) {\n\tif DisableSelectorCache || SelectorCacheMaxEntries <= 0 {\n\t\treturn xpath.Compile(expr)\n\t}\n\tcacheOnce.Do(func() {\n\t\tcache = lru.New(SelectorCacheMaxEntries)\n\t})\n\tcacheMutex.Lock()\n\tdefer cacheMutex.Unlock()\n\tif v, ok := cache.Get(expr); ok {\n\t\treturn v.(*xpath.Expr), nil\n\t}\n\tv, err := xpath.Compile(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcache.Add(expr, v)\n\treturn v, nil\n\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/cached_reader.go",
    "content": "package xmlquery\n\nimport (\n\t\"bufio\"\n)\n\ntype cachedReader struct {\n\tbuffer *bufio.Reader\n\tcache []byte\n\tcacheCap int\n\tcacheLen int\n\tcaching bool\n}\n\nfunc newCachedReader(r *bufio.Reader) *cachedReader {\n\treturn &cachedReader{\n\t\tbuffer:   r,\n\t\tcache:    make([]byte, 4096),\n\t\tcacheCap: 4096,\n\t\tcacheLen: 0,\n\t\tcaching:  false,\n\t}\n}\n\nfunc (c *cachedReader) StartCaching() {\n\tc.cacheLen = 0\n\tc.caching = true\n}\n\nfunc (c *cachedReader) ReadByte() (byte, error) {\n\tif !c.caching {\n\t\treturn c.buffer.ReadByte()\n\t}\n\tb, err := c.buffer.ReadByte()\n\tif err != nil {\n\t\treturn b, err\n\t}\n\tif c.cacheLen < c.cacheCap {\n\t\tc.cache[c.cacheLen] = b\n\t\tc.cacheLen++\n\t}\n\treturn b, err\n}\n\nfunc (c *cachedReader) Cache() []byte {\n\treturn c.cache[:c.cacheLen]\n}\n\nfunc (c *cachedReader) StopCaching() {\n\tc.caching = false\n}\n\nfunc (c *cachedReader) Read(p []byte) (int, error) {\n\tn, err := c.buffer.Read(p)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\tif c.caching && c.cacheLen < c.cacheCap {\n\t\tfor i := 0; i < n; i++ {\n\t\t\tc.cache[c.cacheLen] = p[i]\n\t\t\tc.cacheLen++\n\t\t\tif c.cacheLen >= c.cacheCap {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn n, err\n}\n\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/node.go",
    "content": "package xmlquery\n\nimport (\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"html\"\n\t\"strings\"\n)\n\n// A NodeType is the type of a Node.\ntype NodeType uint\n\nconst (\n\t// DocumentNode is a document object that, as the root of the document tree,\n\t// provides access to the entire XML document.\n\tDocumentNode NodeType = iota\n\t// DeclarationNode is the document type declaration, indicated by the\n\t// following tag (for example, <!DOCTYPE...> ).\n\tDeclarationNode\n\t// ElementNode is an element (for example, <item> ).\n\tElementNode\n\t// TextNode is the text content of a node.\n\tTextNode\n\t// CharDataNode node <![CDATA[content]]>\n\tCharDataNode\n\t// CommentNode a comment (for example, <!-- my comment --> ).\n\tCommentNode\n\t// AttributeNode is an attribute of element.\n\tAttributeNode\n)\n\ntype Attr struct {\n\tName         xml.Name\n\tValue        string\n\tNamespaceURI string\n}\n\n// A Node consists of a NodeType and some Data (tag name for\n// element nodes, content for text) and are part of a tree of Nodes.\ntype Node struct {\n\tParent, FirstChild, LastChild, PrevSibling, NextSibling *Node\n\n\tType         NodeType\n\tData         string\n\tPrefix       string\n\tNamespaceURI string\n\tAttr         []Attr\n\n\tlevel int // node level in the tree\n}\n\ntype outputConfiguration struct {\n\tprintSelf              bool\n\tpreserveSpaces         bool\n\temptyElementTagSupport bool\n\tskipComments           bool\n}\n\ntype OutputOption func(*outputConfiguration)\n\n// WithOutputSelf configures the Node to print the root node itself\nfunc WithOutputSelf() OutputOption {\n\treturn func(oc *outputConfiguration) {\n\t\toc.printSelf = true\n\t}\n}\n\n// WithEmptyTagSupport empty tags should be written as <empty/> and\n// not as <empty></empty>\nfunc WithEmptyTagSupport() OutputOption {\n\treturn func(oc *outputConfiguration) {\n\t\toc.emptyElementTagSupport = true\n\t}\n}\n\n// WithoutComments will skip comments in output\nfunc WithoutComments() OutputOption {\n\treturn func(oc *outputConfiguration) {\n\t\toc.skipComments = true\n\t}\n}\n\nfunc newXMLName(name string) xml.Name {\n\tif i := strings.IndexByte(name, ':'); i > 0 {\n\t\treturn xml.Name{\n\t\t\tSpace: name[:i],\n\t\t\tLocal: name[i+1:],\n\t\t}\n\t}\n\treturn xml.Name{\n\t\tLocal: name,\n\t}\n}\n\n// InnerText returns the text between the start and end tags of the object.\nfunc (n *Node) InnerText() string {\n\tvar output func(*strings.Builder, *Node)\n\toutput = func(b *strings.Builder, n *Node) {\n\t\tswitch n.Type {\n\t\tcase TextNode, CharDataNode:\n\t\t\tb.WriteString(n.Data)\n\t\tcase CommentNode:\n\t\tdefault:\n\t\t\tfor child := n.FirstChild; child != nil; child = child.NextSibling {\n\t\t\t\toutput(b, child)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar b strings.Builder\n\toutput(&b, n)\n\treturn b.String()\n}\n\nfunc (n *Node) sanitizedData(preserveSpaces bool) string {\n\tif preserveSpaces {\n\t\treturn n.Data\n\t}\n\treturn strings.TrimSpace(n.Data)\n}\n\nfunc calculatePreserveSpaces(n *Node, pastValue bool) bool {\n\tif attr := n.SelectAttr(\"xml:space\"); attr == \"preserve\" {\n\t\treturn true\n\t} else if attr == \"default\" {\n\t\treturn false\n\t}\n\treturn pastValue\n}\n\nfunc outputXML(b *strings.Builder, n *Node, preserveSpaces bool, config *outputConfiguration) {\n\tpreserveSpaces = calculatePreserveSpaces(n, preserveSpaces)\n\tswitch n.Type {\n\tcase TextNode:\n\t\tb.WriteString(html.EscapeString(n.sanitizedData(preserveSpaces)))\n\t\treturn\n\tcase CharDataNode:\n\t\tb.WriteString(\"<![CDATA[\")\n\t\tb.WriteString(n.Data)\n\t\tb.WriteString(\"]]>\")\n\t\treturn\n\tcase CommentNode:\n\t\tif !config.skipComments {\n\t\t\tb.WriteString(\"<!--\")\n\t\t\tb.WriteString(n.Data)\n\t\t\tb.WriteString(\"-->\")\n\t\t}\n\t\treturn\n\tcase DeclarationNode:\n\t\tb.WriteString(\"<?\" + n.Data)\n\tdefault:\n\t\tif n.Prefix == \"\" {\n\t\t\tb.WriteString(\"<\" + n.Data)\n\t\t} else {\n\t\t\tfmt.Fprintf(b, \"<%s:%s\", n.Prefix, n.Data)\n\t\t}\n\t}\n\n\tfor _, attr := range n.Attr {\n\t\tif attr.Name.Space != \"\" {\n\t\t\tfmt.Fprintf(b, ` %s:%s=`, attr.Name.Space, attr.Name.Local)\n\t\t} else {\n\t\t\tfmt.Fprintf(b, ` %s=`, attr.Name.Local)\n\t\t}\n\t\tb.WriteByte('\"')\n\t\tb.WriteString(html.EscapeString(attr.Value))\n\t\tb.WriteByte('\"')\n\t}\n\tif n.Type == DeclarationNode {\n\t\tb.WriteString(\"?>\")\n\t} else {\n\t\tif n.FirstChild != nil || !config.emptyElementTagSupport {\n\t\t\tb.WriteString(\">\")\n\t\t} else {\n\t\t\tb.WriteString(\"/>\")\n\t\t\treturn\n\t\t}\n\t}\n\tfor child := n.FirstChild; child != nil; child = child.NextSibling {\n\t\toutputXML(b, child, preserveSpaces, config)\n\t}\n\tif n.Type != DeclarationNode {\n\t\tif n.Prefix == \"\" {\n\t\t\tfmt.Fprintf(b, \"</%s>\", n.Data)\n\t\t} else {\n\t\t\tfmt.Fprintf(b, \"</%s:%s>\", n.Prefix, n.Data)\n\t\t}\n\t}\n}\n\n// OutputXML returns the text that including tags name.\nfunc (n *Node) OutputXML(self bool) string {\n\n\tconfig := &outputConfiguration{\n\t\tprintSelf:              true,\n\t\temptyElementTagSupport: false,\n\t}\n\tpreserveSpaces := calculatePreserveSpaces(n, false)\n\tvar b strings.Builder\n\tif self && n.Type != DocumentNode {\n\t\toutputXML(&b, n, preserveSpaces, config)\n\t} else {\n\t\tfor n := n.FirstChild; n != nil; n = n.NextSibling {\n\t\t\toutputXML(&b, n, preserveSpaces, config)\n\t\t}\n\t}\n\n\treturn b.String()\n}\n\n// OutputXMLWithOptions returns the text that including tags name.\nfunc (n *Node) OutputXMLWithOptions(opts ...OutputOption) string {\n\n\tconfig := &outputConfiguration{}\n\t// Set the options\n\tfor _, opt := range opts {\n\t\topt(config)\n\t}\n\n\tpreserveSpaces := calculatePreserveSpaces(n, false)\n\tvar b strings.Builder\n\tif config.printSelf && n.Type != DocumentNode {\n\t\toutputXML(&b, n, preserveSpaces, config)\n\t} else {\n\t\tfor n := n.FirstChild; n != nil; n = n.NextSibling {\n\t\t\toutputXML(&b, n, preserveSpaces, config)\n\t\t}\n\t}\n\n\treturn b.String()\n}\n\n// AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'.\nfunc AddAttr(n *Node, key, val string) {\n\tattr := Attr{\n\t\tName:  newXMLName(key),\n\t\tValue: val,\n\t}\n\tn.Attr = append(n.Attr, attr)\n}\n\n// SetAttr allows an attribute value with the specified name to be changed.\n// If the attribute did not previously exist, it will be created.\nfunc (n *Node) SetAttr(key, value string) {\n\tname := newXMLName(key)\n\tfor i, attr := range n.Attr {\n\t\tif attr.Name == name {\n\t\t\tn.Attr[i].Value = value\n\t\t\treturn\n\t\t}\n\t}\n\tAddAttr(n, key, value)\n}\n\n// RemoveAttr removes the attribute with the specified name.\nfunc (n *Node) RemoveAttr(key string) {\n\tname := newXMLName(key)\n\tfor i, attr := range n.Attr {\n\t\tif attr.Name == name {\n\t\t\tn.Attr = append(n.Attr[:i], n.Attr[i+1:]...)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// AddChild adds a new node 'n' to a node 'parent' as its last child.\nfunc AddChild(parent, n *Node) {\n\tn.Parent = parent\n\tn.NextSibling = nil\n\tif parent.FirstChild == nil {\n\t\tparent.FirstChild = n\n\t\tn.PrevSibling = nil\n\t} else {\n\t\tparent.LastChild.NextSibling = n\n\t\tn.PrevSibling = parent.LastChild\n\t}\n\n\tparent.LastChild = n\n}\n\n// AddSibling adds a new node 'n' as a sibling of a given node 'sibling'.\n// Note it is not necessarily true that the new node 'n' would be added\n// immediately after 'sibling'. If 'sibling' isn't the last child of its\n// parent, then the new node 'n' will be added at the end of the sibling\n// chain of their parent.\nfunc AddSibling(sibling, n *Node) {\n\tfor t := sibling.NextSibling; t != nil; t = t.NextSibling {\n\t\tsibling = t\n\t}\n\tn.Parent = sibling.Parent\n\tsibling.NextSibling = n\n\tn.PrevSibling = sibling\n\tn.NextSibling = nil\n\tif sibling.Parent != nil {\n\t\tsibling.Parent.LastChild = n\n\t}\n}\n\n// RemoveFromTree removes a node and its subtree from the document\n// tree it is in. If the node is the root of the tree, then it's no-op.\nfunc RemoveFromTree(n *Node) {\n\tif n.Parent == nil {\n\t\treturn\n\t}\n\tif n.Parent.FirstChild == n {\n\t\tif n.Parent.LastChild == n {\n\t\t\tn.Parent.FirstChild = nil\n\t\t\tn.Parent.LastChild = nil\n\t\t} else {\n\t\t\tn.Parent.FirstChild = n.NextSibling\n\t\t\tn.NextSibling.PrevSibling = nil\n\t\t}\n\t} else {\n\t\tif n.Parent.LastChild == n {\n\t\t\tn.Parent.LastChild = n.PrevSibling\n\t\t\tn.PrevSibling.NextSibling = nil\n\t\t} else {\n\t\t\tn.PrevSibling.NextSibling = n.NextSibling\n\t\t\tn.NextSibling.PrevSibling = n.PrevSibling\n\t\t}\n\t}\n\tn.Parent = nil\n\tn.PrevSibling = nil\n\tn.NextSibling = nil\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/options.go",
    "content": "package xmlquery\n\nimport (\n\t\"encoding/xml\"\n\t\"io\"\n)\n\ntype ParserOptions struct {\n\tDecoder *DecoderOptions\n}\n\nfunc (options ParserOptions) apply(parser *parser) {\n\tif options.Decoder != nil {\n\t\t(*options.Decoder).apply(parser.decoder)\n\t}\n}\n\n// DecoderOptions implement the very same options than the standard\n// encoding/xml package. Please refer to this documentation:\n// https://golang.org/pkg/encoding/xml/#Decoder\ntype DecoderOptions struct {\n\tStrict        bool\n\tAutoClose     []string\n\tEntity        map[string]string\n\tCharsetReader func(charset string, input io.Reader) (io.Reader, error)\n}\n\nfunc (options DecoderOptions) apply(decoder *xml.Decoder) {\n\tdecoder.Strict = options.Strict\n\tdecoder.AutoClose = options.AutoClose\n\tdecoder.Entity = options.Entity\n\tdecoder.CharsetReader = options.CharsetReader\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/parse.go",
    "content": "package xmlquery\n\nimport (\n\t\"bufio\"\n\t\"encoding/xml\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/antchfx/xpath\"\n\t\"golang.org/x/net/html/charset\"\n)\n\nvar xmlMIMERegex = regexp.MustCompile(`(?i)((application|image|message|model)/((\\w|\\.|-)+\\+?)?|text/)(wb)?xml`)\n\n// LoadURL loads the XML document from the specified URL.\nfunc LoadURL(url string) (*Node, error) {\n\tresp, err := http.Get(url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\t// Make sure the Content-Type has a valid XML MIME type\n\tif xmlMIMERegex.MatchString(resp.Header.Get(\"Content-Type\")) {\n\t\treturn Parse(resp.Body)\n\t}\n\treturn nil, fmt.Errorf(\"invalid XML document(%s)\", resp.Header.Get(\"Content-Type\"))\n}\n\n// Parse returns the parse tree for the XML from the given Reader.\nfunc Parse(r io.Reader) (*Node, error) {\n\treturn ParseWithOptions(r, ParserOptions{})\n}\n\n// ParseWithOptions is like parse, but with custom options\nfunc ParseWithOptions(r io.Reader, options ParserOptions) (*Node, error) {\n\tp := createParser(r)\n\toptions.apply(p)\n\tfor {\n\t\t_, err := p.parse()\n\t\tif err == io.EOF {\n\t\t\treturn p.doc, nil\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n}\n\ntype parser struct {\n\tdecoder             *xml.Decoder\n\tdoc                 *Node\n\tlevel               int\n\tprev                *Node\n\tstreamElementXPath  *xpath.Expr   // Under streaming mode, this specifies the xpath to the target element node(s).\n\tstreamElementFilter *xpath.Expr   // If specified, it provides further filtering on the target element.\n\tstreamNode          *Node         // Need to remember the last target node So we can clean it up upon next Read() call.\n\tstreamNodePrev      *Node         // Need to remember target node's prev so upon target node removal, we can restore correct prev.\n\treader              *cachedReader // Need to maintain a reference to the reader, so we can determine whether a node contains CDATA.\n}\n\nfunc createParser(r io.Reader) *parser {\n\treader := newCachedReader(bufio.NewReader(r))\n\tp := &parser{\n\t\tdecoder: xml.NewDecoder(reader),\n\t\tdoc:     &Node{Type: DocumentNode},\n\t\tlevel:   0,\n\t\treader:  reader,\n\t}\n\tif p.decoder.CharsetReader == nil {\n\t\tp.decoder.CharsetReader = charset.NewReaderLabel\n\t}\n\tp.prev = p.doc\n\treturn p\n}\n\nfunc (p *parser) parse() (*Node, error) {\n\tvar streamElementNodeCounter int\n\tspace2prefix := map[string]string{\"http://www.w3.org/XML/1998/namespace\": \"xml\"}\n\n\tfor {\n\t\tp.reader.StartCaching()\n\t\ttok, err := p.decoder.Token()\n\t\tp.reader.StopCaching()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tswitch tok := tok.(type) {\n\t\tcase xml.StartElement:\n\t\t\tif p.level == 0 {\n\t\t\t\t// mising XML declaration\n\t\t\t\tattributes := make([]Attr, 1)\n\t\t\t\tattributes[0].Name = xml.Name{Local: \"version\"}\n\t\t\t\tattributes[0].Value = \"1.0\"\n\t\t\t\tnode := &Node{\n\t\t\t\t\tType:  DeclarationNode,\n\t\t\t\t\tData:  \"xml\",\n\t\t\t\t\tAttr:  attributes,\n\t\t\t\t\tlevel: 1,\n\t\t\t\t}\n\t\t\t\tAddChild(p.prev, node)\n\t\t\t\tp.level = 1\n\t\t\t\tp.prev = node\n\t\t\t}\n\n\t\t\tfor _, att := range tok.Attr {\n\t\t\t\tif att.Name.Local == \"xmlns\" {\n\t\t\t\t\tspace2prefix[att.Value] = \"\" // reset empty if exist the default namespace\n\t\t\t\t\t//\tdefaultNamespaceURL = att.Value\n\t\t\t\t} else if att.Name.Space == \"xmlns\" {\n\t\t\t\t\t// maybe there are have duplicate NamespaceURL?\n\t\t\t\t\tspace2prefix[att.Value] = att.Name.Local\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif space := tok.Name.Space; space != \"\" {\n\t\t\t\tif _, found := space2prefix[space]; !found && p.decoder.Strict {\n\t\t\t\t\treturn nil, fmt.Errorf(\"xmlquery: invalid XML document, namespace %s is missing\", space)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tattributes := make([]Attr, len(tok.Attr))\n\t\t\tfor i, att := range tok.Attr {\n\t\t\t\tname := att.Name\n\t\t\t\tif prefix, ok := space2prefix[name.Space]; ok {\n\t\t\t\t\tname.Space = prefix\n\t\t\t\t}\n\t\t\t\tattributes[i] = Attr{\n\t\t\t\t\tName:         name,\n\t\t\t\t\tValue:        att.Value,\n\t\t\t\t\tNamespaceURI: att.Name.Space,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnode := &Node{\n\t\t\t\tType:         ElementNode,\n\t\t\t\tData:         tok.Name.Local,\n\t\t\t\tNamespaceURI: tok.Name.Space,\n\t\t\t\tAttr:         attributes,\n\t\t\t\tlevel:        p.level,\n\t\t\t}\n\n\t\t\tif p.level == p.prev.level {\n\t\t\t\tAddSibling(p.prev, node)\n\t\t\t} else if p.level > p.prev.level {\n\t\t\t\tAddChild(p.prev, node)\n\t\t\t} else if p.level < p.prev.level {\n\t\t\t\tfor i := p.prev.level - p.level; i > 1; i-- {\n\t\t\t\t\tp.prev = p.prev.Parent\n\t\t\t\t}\n\t\t\t\tAddSibling(p.prev.Parent, node)\n\t\t\t}\n\n\t\t\tif node.NamespaceURI != \"\" {\n\t\t\t\tif v, ok := space2prefix[node.NamespaceURI]; ok {\n\t\t\t\t\tcached := string(p.reader.Cache())\n\t\t\t\t\tif strings.HasPrefix(cached, fmt.Sprintf(\"%s:%s\", v, node.Data)) || strings.HasPrefix(cached, fmt.Sprintf(\"<%s:%s\", v, node.Data)) {\n\t\t\t\t\t\tnode.Prefix = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we're in the streaming mode, we need to remember the node if it is the target node\n\t\t\t// so that when we finish processing the node's EndElement, we know how/what to return to\n\t\t\t// caller. Also we need to remove the target node from the tree upon next Read() call so\n\t\t\t// memory doesn't grow unbounded.\n\t\t\tif p.streamElementXPath != nil {\n\t\t\t\tif p.streamNode == nil {\n\t\t\t\t\tif QuerySelector(p.doc, p.streamElementXPath) != nil {\n\t\t\t\t\t\tp.streamNode = node\n\t\t\t\t\t\tp.streamNodePrev = p.prev\n\t\t\t\t\t\tstreamElementNodeCounter = 1\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tstreamElementNodeCounter++\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.prev = node\n\t\t\tp.level++\n\t\tcase xml.EndElement:\n\t\t\tp.level--\n\t\t\t// If we're in streaming mode, and we already have a potential streaming\n\t\t\t// target node identified (p.streamNode != nil) then we need to check if\n\t\t\t// this is the real one we want to return to caller.\n\t\t\tif p.streamNode != nil {\n\t\t\t\tstreamElementNodeCounter--\n\t\t\t\tif streamElementNodeCounter == 0 {\n\t\t\t\t\t// Now we know this element node is the at least passing the initial\n\t\t\t\t\t// p.streamElementXPath check and is a potential target node candidate.\n\t\t\t\t\t// We need to have 1 more check with p.streamElementFilter (if given) to\n\t\t\t\t\t// ensure it is really the element node we want.\n\t\t\t\t\t// The reason we need a two-step check process is because the following\n\t\t\t\t\t// situation:\n\t\t\t\t\t//   <AAA><BBB>b1</BBB></AAA>\n\t\t\t\t\t// And say the p.streamElementXPath = \"/AAA/BBB[. != 'b1']\". Now during\n\t\t\t\t\t// xml.StartElement time, the <BBB> node is still empty, so it will pass\n\t\t\t\t\t// the p.streamElementXPath check. However, eventually we know this <BBB>\n\t\t\t\t\t// shouldn't be returned to the caller. Having a second more fine-grained\n\t\t\t\t\t// filter check ensures that. So in this case, the caller should really\n\t\t\t\t\t// setup the stream parser with:\n\t\t\t\t\t//   streamElementXPath = \"/AAA/BBB[\"\n\t\t\t\t\t//   streamElementFilter = \"/AAA/BBB[. != 'b1']\"\n\t\t\t\t\tif p.streamElementFilter == nil || QuerySelector(p.doc, p.streamElementFilter) != nil {\n\t\t\t\t\t\treturn p.streamNode, nil\n\t\t\t\t\t}\n\t\t\t\t\t// otherwise, this isn't our target node, clean things up.\n\t\t\t\t\t// note we also remove the underlying *Node from the node tree, to prevent\n\t\t\t\t\t// future stream node candidate selection error.\n\t\t\t\t\tRemoveFromTree(p.streamNode)\n\t\t\t\t\tp.prev = p.streamNodePrev\n\t\t\t\t\tp.streamNode = nil\n\t\t\t\t\tp.streamNodePrev = nil\n\t\t\t\t}\n\t\t\t}\n\t\tcase xml.CharData:\n\t\t\t// First, normalize the cache...\n\t\t\tcached := strings.ToUpper(string(p.reader.Cache()))\n\t\t\tnodeType := TextNode\n\t\t\tif strings.HasPrefix(cached, \"<![CDATA[\") || strings.HasPrefix(cached, \"![CDATA[\") {\n\t\t\t\tnodeType = CharDataNode\n\t\t\t}\n\n\t\t\tnode := &Node{Type: nodeType, Data: string(tok), level: p.level}\n\t\t\tif p.level == p.prev.level {\n\t\t\t\tAddSibling(p.prev, node)\n\t\t\t} else if p.level > p.prev.level {\n\t\t\t\tAddChild(p.prev, node)\n\t\t\t} else if p.level < p.prev.level {\n\t\t\t\tfor i := p.prev.level - p.level; i > 1; i-- {\n\t\t\t\t\tp.prev = p.prev.Parent\n\t\t\t\t}\n\t\t\t\tAddSibling(p.prev.Parent, node)\n\t\t\t}\n\t\tcase xml.Comment:\n\t\t\tnode := &Node{Type: CommentNode, Data: string(tok), level: p.level}\n\t\t\tif p.level == p.prev.level {\n\t\t\t\tAddSibling(p.prev, node)\n\t\t\t} else if p.level > p.prev.level {\n\t\t\t\tAddChild(p.prev, node)\n\t\t\t} else if p.level < p.prev.level {\n\t\t\t\tfor i := p.prev.level - p.level; i > 1; i-- {\n\t\t\t\t\tp.prev = p.prev.Parent\n\t\t\t\t}\n\t\t\t\tAddSibling(p.prev.Parent, node)\n\t\t\t}\n\t\tcase xml.ProcInst: // Processing Instruction\n\t\t\tif p.prev.Type != DeclarationNode {\n\t\t\t\tp.level++\n\t\t\t}\n\t\t\tnode := &Node{Type: DeclarationNode, Data: tok.Target, level: p.level}\n\t\t\tpairs := strings.Split(string(tok.Inst), \" \")\n\t\t\tfor _, pair := range pairs {\n\t\t\t\tpair = strings.TrimSpace(pair)\n\t\t\t\tif i := strings.Index(pair, \"=\"); i > 0 {\n\t\t\t\t\tAddAttr(node, pair[:i], strings.Trim(pair[i+1:], `\"`))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif p.level == p.prev.level {\n\t\t\t\tAddSibling(p.prev, node)\n\t\t\t} else if p.level > p.prev.level {\n\t\t\t\tAddChild(p.prev, node)\n\t\t\t} else if p.level < p.prev.level {\n\t\t\t\tfor i := p.prev.level - p.level; i > 1; i-- {\n\t\t\t\t\tp.prev = p.prev.Parent\n\t\t\t\t}\n\t\t\t\tAddSibling(p.prev.Parent, node)\n\t\t\t}\n\t\t\tp.prev = node\n\t\tcase xml.Directive:\n\t\t}\n\t}\n}\n\n// StreamParser enables loading and parsing an XML document in a streaming\n// fashion.\ntype StreamParser struct {\n\tp *parser\n}\n\n// CreateStreamParser creates a StreamParser. Argument streamElementXPath is\n// required.\n// Argument streamElementFilter is optional and should only be used in advanced\n// scenarios.\n//\n// Scenario 1: simple case:\n//  xml := `<AAA><BBB>b1</BBB><BBB>b2</BBB></AAA>`\n//  sp, err := CreateStreamParser(strings.NewReader(xml), \"/AAA/BBB\")\n//  if err != nil {\n//      panic(err)\n//  }\n//  for {\n//      n, err := sp.Read()\n//      if err != nil {\n//          break\n//      }\n//      fmt.Println(n.OutputXML(true))\n//  }\n// Output will be:\n//   <BBB>b1</BBB>\n//   <BBB>b2</BBB>\n//\n// Scenario 2: advanced case:\n//  xml := `<AAA><BBB>b1</BBB><BBB>b2</BBB></AAA>`\n//  sp, err := CreateStreamParser(strings.NewReader(xml), \"/AAA/BBB\", \"/AAA/BBB[. != 'b1']\")\n//  if err != nil {\n//      panic(err)\n//  }\n//  for {\n//      n, err := sp.Read()\n//      if err != nil {\n//          break\n//      }\n//      fmt.Println(n.OutputXML(true))\n//  }\n// Output will be:\n//   <BBB>b2</BBB>\n//\n// As the argument names indicate, streamElementXPath should be used for\n// providing xpath query pointing to the target element node only, no extra\n// filtering on the element itself or its children; while streamElementFilter,\n// if needed, can provide additional filtering on the target element and its\n// children.\n//\n// CreateStreamParser returns an error if either streamElementXPath or\n// streamElementFilter, if provided, cannot be successfully parsed and compiled\n// into a valid xpath query.\nfunc CreateStreamParser(r io.Reader, streamElementXPath string, streamElementFilter ...string) (*StreamParser, error) {\n\treturn CreateStreamParserWithOptions(r, ParserOptions{}, streamElementXPath, streamElementFilter...)\n}\n\n// CreateStreamParserWithOptions is like CreateStreamParser, but with custom options\nfunc CreateStreamParserWithOptions(\n\tr io.Reader,\n\toptions ParserOptions,\n\tstreamElementXPath string,\n\tstreamElementFilter ...string,\n) (*StreamParser, error) {\n\telemXPath, err := getQuery(streamElementXPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid streamElementXPath '%s', err: %s\", streamElementXPath, err.Error())\n\t}\n\telemFilter := (*xpath.Expr)(nil)\n\tif len(streamElementFilter) > 0 {\n\t\telemFilter, err = getQuery(streamElementFilter[0])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid streamElementFilter '%s', err: %s\", streamElementFilter[0], err.Error())\n\t\t}\n\t}\n\tparser := createParser(r)\n\toptions.apply(parser)\n\tsp := &StreamParser{\n\t\tp: parser,\n\t}\n\tsp.p.streamElementXPath = elemXPath\n\tsp.p.streamElementFilter = elemFilter\n\treturn sp, nil\n}\n\n// Read returns a target node that satisfies the XPath specified by caller at\n// StreamParser creation time. If there is no more satisfying target nodes after\n// reading the rest of the XML document, io.EOF will be returned. At any time,\n// any XML parsing error encountered will be returned, and the stream parsing\n// stopped. Calling Read() after an error is returned (including io.EOF) results\n// undefined behavior. Also note, due to the streaming nature, calling Read()\n// will automatically remove any previous target node(s) from the document tree.\nfunc (sp *StreamParser) Read() (*Node, error) {\n\t// Because this is a streaming read, we need to release/remove last\n\t// target node from the node tree to free up memory.\n\tif sp.p.streamNode != nil {\n\t\t// We need to remove all siblings before the current stream node,\n\t\t// because the document may contain unwanted nodes between the target\n\t\t// ones (for example new line text node), which would otherwise\n\t\t// accumulate as first childs, and slow down the stream over time\n\t\tfor sp.p.streamNode.PrevSibling != nil {\n\t\t\tRemoveFromTree(sp.p.streamNode.PrevSibling)\n\t\t}\n\t\tsp.p.prev = sp.p.streamNode.Parent\n\t\tRemoveFromTree(sp.p.streamNode)\n\t\tsp.p.streamNode = nil\n\t\tsp.p.streamNodePrev = nil\n\t}\n\treturn sp.p.parse()\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xmlquery/query.go",
    "content": "/*\nPackage xmlquery provides extract data from XML documents using XPath expression.\n*/\npackage xmlquery\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/antchfx/xpath\"\n)\n\n// SelectElements finds child elements with the specified name.\nfunc (n *Node) SelectElements(name string) []*Node {\n\treturn Find(n, name)\n}\n\n// SelectElement finds child elements with the specified name.\nfunc (n *Node) SelectElement(name string) *Node {\n\treturn FindOne(n, name)\n}\n\n// SelectAttr returns the attribute value with the specified name.\nfunc (n *Node) SelectAttr(name string) string {\n\tif n.Type == AttributeNode {\n\t\tif n.Data == name {\n\t\t\treturn n.InnerText()\n\t\t}\n\t\treturn \"\"\n\t}\n\txmlName := newXMLName(name)\n\tfor _, attr := range n.Attr {\n\t\tif attr.Name == xmlName {\n\t\t\treturn attr.Value\n\t\t}\n\t}\n\treturn \"\"\n}\n\nvar _ xpath.NodeNavigator = &NodeNavigator{}\n\n// CreateXPathNavigator creates a new xpath.NodeNavigator for the specified\n// XML Node.\nfunc CreateXPathNavigator(top *Node) *NodeNavigator {\n\treturn &NodeNavigator{curr: top, root: top, attr: -1}\n}\n\nfunc getCurrentNode(it *xpath.NodeIterator) *Node {\n\tn := it.Current().(*NodeNavigator)\n\tif n.NodeType() == xpath.AttributeNode {\n\t\tchildNode := &Node{\n\t\t\tType: TextNode,\n\t\t\tData: n.Value(),\n\t\t}\n\t\treturn &Node{\n\t\t\tParent:     n.curr,\n\t\t\tType:       AttributeNode,\n\t\t\tData:       n.LocalName(),\n\t\t\tFirstChild: childNode,\n\t\t\tLastChild:  childNode,\n\t\t}\n\t}\n\treturn n.curr\n}\n\n// Find is like QueryAll but panics if `expr` is not a valid XPath expression.\n// See `QueryAll()` function.\nfunc Find(top *Node, expr string) []*Node {\n\tnodes, err := QueryAll(top, expr)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn nodes\n}\n\n// FindOne is like Query but panics if `expr` is not a valid XPath expression.\n// See `Query()` function.\nfunc FindOne(top *Node, expr string) *Node {\n\tnode, err := Query(top, expr)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn node\n}\n\n// QueryAll searches the XML Node that matches by the specified XPath expr.\n// Returns an error if the expression `expr` cannot be parsed.\nfunc QueryAll(top *Node, expr string) ([]*Node, error) {\n\texp, err := getQuery(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn QuerySelectorAll(top, exp), nil\n}\n\n// Query searches the XML Node that matches by the specified XPath expr,\n// and returns first matched element.\nfunc Query(top *Node, expr string) (*Node, error) {\n\texp, err := getQuery(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn QuerySelector(top, exp), nil\n}\n\n// QuerySelectorAll searches all of the XML Node that matches the specified\n// XPath selectors.\nfunc QuerySelectorAll(top *Node, selector *xpath.Expr) []*Node {\n\tt := selector.Select(CreateXPathNavigator(top))\n\tvar elems []*Node\n\tfor t.MoveNext() {\n\t\telems = append(elems, getCurrentNode(t))\n\t}\n\treturn elems\n}\n\n// QuerySelector returns the first matched XML Node by the specified XPath\n// selector.\nfunc QuerySelector(top *Node, selector *xpath.Expr) *Node {\n\tt := selector.Select(CreateXPathNavigator(top))\n\tif t.MoveNext() {\n\t\treturn getCurrentNode(t)\n\t}\n\treturn nil\n}\n\n// FindEach searches the html.Node and calls functions cb.\n// Important: this method is deprecated, instead, use for .. = range Find(){}.\nfunc FindEach(top *Node, expr string, cb func(int, *Node)) {\n\tfor i, n := range Find(top, expr) {\n\t\tcb(i, n)\n\t}\n}\n\n// FindEachWithBreak functions the same as FindEach but allows to break the loop\n// by returning false from the callback function `cb`.\n// Important: this method is deprecated, instead, use .. = range Find(){}.\nfunc FindEachWithBreak(top *Node, expr string, cb func(int, *Node) bool) {\n\tfor i, n := range Find(top, expr) {\n\t\tif !cb(i, n) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\ntype NodeNavigator struct {\n\troot, curr *Node\n\tattr       int\n}\n\nfunc (x *NodeNavigator) Current() *Node {\n\treturn x.curr\n}\n\nfunc (x *NodeNavigator) NodeType() xpath.NodeType {\n\tswitch x.curr.Type {\n\tcase CommentNode:\n\t\treturn xpath.CommentNode\n\tcase TextNode, CharDataNode:\n\t\treturn xpath.TextNode\n\tcase DeclarationNode, DocumentNode:\n\t\treturn xpath.RootNode\n\tcase ElementNode:\n\t\tif x.attr != -1 {\n\t\t\treturn xpath.AttributeNode\n\t\t}\n\t\treturn xpath.ElementNode\n\t}\n\tpanic(fmt.Sprintf(\"unknown XML node type: %v\", x.curr.Type))\n}\n\nfunc (x *NodeNavigator) LocalName() string {\n\tif x.attr != -1 {\n\t\treturn x.curr.Attr[x.attr].Name.Local\n\t}\n\treturn x.curr.Data\n\n}\n\nfunc (x *NodeNavigator) Prefix() string {\n\tif x.NodeType() == xpath.AttributeNode {\n\t\tif x.attr != -1 {\n\t\t\treturn x.curr.Attr[x.attr].Name.Space\n\t\t}\n\t\treturn \"\"\n\t}\n\treturn x.curr.Prefix\n}\n\nfunc (x *NodeNavigator) NamespaceURL() string {\n\tif x.attr != -1 {\n\t\treturn x.curr.Attr[x.attr].NamespaceURI\n\t}\n\treturn x.curr.NamespaceURI\n}\n\nfunc (x *NodeNavigator) Value() string {\n\tswitch x.curr.Type {\n\tcase CommentNode:\n\t\treturn x.curr.Data\n\tcase ElementNode:\n\t\tif x.attr != -1 {\n\t\t\treturn x.curr.Attr[x.attr].Value\n\t\t}\n\t\treturn x.curr.InnerText()\n\tcase TextNode:\n\t\treturn x.curr.Data\n\t}\n\treturn \"\"\n}\n\nfunc (x *NodeNavigator) Copy() xpath.NodeNavigator {\n\tn := *x\n\treturn &n\n}\n\nfunc (x *NodeNavigator) MoveToRoot() {\n\tx.curr = x.root\n}\n\nfunc (x *NodeNavigator) MoveToParent() bool {\n\tif x.attr != -1 {\n\t\tx.attr = -1\n\t\treturn true\n\t} else if node := x.curr.Parent; node != nil {\n\t\tx.curr = node\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (x *NodeNavigator) MoveToNextAttribute() bool {\n\tif x.attr >= len(x.curr.Attr)-1 {\n\t\treturn false\n\t}\n\tx.attr++\n\treturn true\n}\n\nfunc (x *NodeNavigator) MoveToChild() bool {\n\tif x.attr != -1 {\n\t\treturn false\n\t}\n\tif node := x.curr.FirstChild; node != nil {\n\t\tx.curr = node\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (x *NodeNavigator) MoveToFirst() bool {\n\tif x.attr != -1 || x.curr.PrevSibling == nil {\n\t\treturn false\n\t}\n\tfor {\n\t\tnode := x.curr.PrevSibling\n\t\tif node == nil {\n\t\t\tbreak\n\t\t}\n\t\tx.curr = node\n\t}\n\treturn true\n}\n\nfunc (x *NodeNavigator) String() string {\n\treturn x.Value()\n}\n\nfunc (x *NodeNavigator) MoveToNext() bool {\n\tif x.attr != -1 {\n\t\treturn false\n\t}\n\tfor node := x.curr.NextSibling; node != nil; node = x.curr.NextSibling {\n\t\tx.curr = node\n\t\tif x.curr.Type != TextNode || strings.TrimSpace(x.curr.Data) != \"\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (x *NodeNavigator) MoveToPrevious() bool {\n\tif x.attr != -1 {\n\t\treturn false\n\t}\n\tfor node := x.curr.PrevSibling; node != nil; node = x.curr.PrevSibling {\n\t\tx.curr = node\n\t\tif x.curr.Type != TextNode || strings.TrimSpace(x.curr.Data) != \"\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (x *NodeNavigator) MoveTo(other xpath.NodeNavigator) bool {\n\tnode, ok := other.(*NodeNavigator)\n\tif !ok || node.root != x.root {\n\t\treturn false\n\t}\n\n\tx.curr = node.curr\n\tx.attr = node.attr\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/.gitignore",
    "content": "# vscode\n.vscode\ndebug\n*.test\n\n./build\n\n# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.6\n  - 1.9\n  - '1.10'\n\ninstall:\n  - go get github.com/mattn/goveralls\n\nscript:\n  - $HOME/gopath/bin/goveralls -service=travis-ci"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/LICENSE",
    "content": "Permission 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\nall copies 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\nTHE SOFTWARE."
  },
  {
    "path": "vendor/github.com/antchfx/xpath/README.md",
    "content": "XPath\n====\n[![GoDoc](https://godoc.org/github.com/antchfx/xpath?status.svg)](https://godoc.org/github.com/antchfx/xpath)\n[![Coverage Status](https://coveralls.io/repos/github/antchfx/xpath/badge.svg?branch=master)](https://coveralls.io/github/antchfx/xpath?branch=master)\n[![Build Status](https://travis-ci.org/antchfx/xpath.svg?branch=master)](https://travis-ci.org/antchfx/xpath)\n[![Go Report Card](https://goreportcard.com/badge/github.com/antchfx/xpath)](https://goreportcard.com/report/github.com/antchfx/xpath)\n\nXPath is Go package provides selecting nodes from XML, HTML or other documents using XPath expression.\n\nImplementation\n===\n\n- [htmlquery](https://github.com/antchfx/htmlquery) - an XPath query package for HTML document\n\n- [xmlquery](https://github.com/antchfx/xmlquery) - an XPath query package for XML document.\n\n- [jsonquery](https://github.com/antchfx/jsonquery) - an XPath query package for JSON document\n\nSupported Features\n===\n\n#### The basic XPath patterns.\n\n> The basic XPath patterns cover 90% of the cases that most stylesheets will need.\n\n- `node` : Selects all child elements with nodeName of node.\n\n- `*` : Selects all child elements.\n\n- `@attr` : Selects the attribute attr.\n\n- `@*` : Selects all attributes.\n\n- `node()` : Matches an org.w3c.dom.Node.\n\n- `text()` : Matches a org.w3c.dom.Text node.\n\n- `comment()` : Matches a comment.\n\n- `.` : Selects the current node.\n\n- `..` : Selects the parent of current node.\n\n- `/` : Selects the document node.\n\n- `a[expr]` : Select only those nodes matching a which also satisfy the expression expr.\n\n- `a[n]` : Selects the nth matching node matching a When a filter's expression is a number, XPath selects based on position.\n\n- `a/b` : For each node matching a, add the nodes matching b to the result.\n\n- `a//b` : For each node matching a, add the descendant nodes matching b to the result. \n\n- `//b` : Returns elements in the entire document matching b.\n\n- `a|b` : All nodes matching a or b, union operation(not boolean or).\n\n- `(a, b, c)` : Evaluates each of its operands and concatenates the resulting sequences, in order, into a single result sequence\n\n- `(a/b)` : Selects all matches nodes as grouping set.\n\n#### Node Axes \n\n- `child::*` : The child axis selects children of the current node.\n\n- `descendant::*` : The descendant axis selects descendants of the current node. It is equivalent to '//'.\n\n- `descendant-or-self::*` : Selects descendants including the current node.\n\n- `attribute::*` : Selects attributes of the current element. It is equivalent to @*\n\n- `following-sibling::*` : Selects nodes after the current node.\n\n- `preceding-sibling::*` : Selects nodes before the current node.\n\n- `following::*` : Selects the first matching node following in document order, excluding descendants. \n\n- `preceding::*` : Selects the first matching node preceding in document order, excluding ancestors. \n\n- `parent::*` : Selects the parent if it matches. The '..' pattern from the core is equivalent to 'parent::node()'.\n\n- `ancestor::*` : Selects matching ancestors.\n\n- `ancestor-or-self::*` : Selects ancestors including the current node.\n\n- `self::*` : Selects the current node. '.' is equivalent to 'self::node()'.\n\n#### Expressions\n\n The gxpath supported three types: number, boolean, string.\n\n- `path` : Selects nodes based on the path.\n\n- `a = b` : Standard comparisons.\n\n    * a = b\t    True if a equals b.\n    * a != b\tTrue if a is not equal to b.\n    * a < b\t    True if a is less than b.\n    * a <= b\tTrue if a is less than or equal to b.\n    * a > b\t    True if a is greater than b.\n    * a >= b\tTrue if a is greater than or equal to b.\n\n- `a + b` : Arithmetic expressions.\n\n    * `- a`\tUnary minus\n    * a + b\tAdd\n    * a - b\tSubstract\n    * a * b\tMultiply\n    * a div b\tDivide\n    * a mod b\tFloating point mod, like Java.\n\n- `a or b` : Boolean `or` operation.\n\n- `a and b` : Boolean `and` operation.\n\n- `(expr)` : Parenthesized expressions.\n\n- `fun(arg1, ..., argn)` : Function calls:\n\n| Function | Supported |\n| --- | --- |\n`boolean()`| ✓ |\n`ceiling()`| ✓ |\n`choose()`| ✗ |\n`concat()`| ✓ |\n`contains()`| ✓ |\n`count()`| ✓ |\n`current()`| ✗ |\n`document()`| ✗ |\n`element-available()`| ✗ |\n`ends-with()`| ✓ |\n`false()`| ✓ |\n`floor()`| ✓ |\n`format-number()`| ✗ |\n`function-available()`| ✗ |\n`generate-id()`| ✗ |\n`id()`| ✗ |\n`key()`| ✗ |\n`lang()`| ✗ |\n`last()`| ✓ |\n`local-name()`| ✓ |\n`matches()`| ✓ |\n`name()`| ✓ |\n`namespace-uri()`| ✓ |\n`normalize-space()`| ✓ |\n`not()`| ✓ |\n`number()`| ✓ |\n`position()`| ✓ |\n`replace()`| ✓ |\n`reverse()`| ✓ |\n`round()`| ✓ |\n`starts-with()`| ✓ |\n`string()`| ✓ |\n`string-length()`| ✓ |\n`substring()`| ✓ |\n`substring-after()`| ✓ |\n`substring-before()`| ✓ |\n`sum()`| ✓ |\n`system-property()`| ✗ |\n`translate()`| ✓ |\n`true()`| ✓ |\n`unparsed-entity-url()` | ✗ |"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/build.go",
    "content": "package xpath\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\ntype flag int\n\nconst (\n\tnoneFlag flag = iota\n\tfilterFlag\n)\n\n// builder provides building an XPath expressions.\ntype builder struct {\n\tdepth      int\n\tflag       flag\n\tfirstInput query\n}\n\n// axisPredicate creates a predicate to predicating for this axis node.\nfunc axisPredicate(root *axisNode) func(NodeNavigator) bool {\n\t// get current axix node type.\n\ttyp := ElementNode\n\tswitch root.AxeType {\n\tcase \"attribute\":\n\t\ttyp = AttributeNode\n\tcase \"self\", \"parent\":\n\t\ttyp = allNode\n\tdefault:\n\t\tswitch root.Prop {\n\t\tcase \"comment\":\n\t\t\ttyp = CommentNode\n\t\tcase \"text\":\n\t\t\ttyp = TextNode\n\t\t\t//\tcase \"processing-instruction\":\n\t\t//\ttyp = ProcessingInstructionNode\n\t\tcase \"node\":\n\t\t\ttyp = allNode\n\t\t}\n\t}\n\tnametest := root.LocalName != \"\" || root.Prefix != \"\"\n\tpredicate := func(n NodeNavigator) bool {\n\t\tif typ == n.NodeType() || typ == allNode {\n\t\t\tif nametest {\n\t\t\t\ttype namespaceURL interface {\n\t\t\t\t\tNamespaceURL() string\n\t\t\t\t}\n\t\t\t\tif ns, ok := n.(namespaceURL); ok && root.hasNamespaceURI {\n\t\t\t\t\treturn root.LocalName == n.LocalName() && root.namespaceURI == ns.NamespaceURL()\n\t\t\t\t}\n\t\t\t\tif root.LocalName == n.LocalName() && root.Prefix == n.Prefix() {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\treturn predicate\n}\n\n// processAxisNode processes a query for the XPath axis node.\nfunc (b *builder) processAxisNode(root *axisNode) (query, error) {\n\tvar (\n\t\terr       error\n\t\tqyInput   query\n\t\tqyOutput  query\n\t\tpredicate = axisPredicate(root)\n\t)\n\n\tif root.Input == nil {\n\t\tqyInput = &contextQuery{}\n\t} else {\n\t\tif root.AxeType == \"child\" && (root.Input.Type() == nodeAxis) {\n\t\t\tif input := root.Input.(*axisNode); input.AxeType == \"descendant-or-self\" {\n\t\t\t\tvar qyGrandInput query\n\t\t\t\tif input.Input != nil {\n\t\t\t\t\tqyGrandInput, _ = b.processNode(input.Input)\n\t\t\t\t} else {\n\t\t\t\t\tqyGrandInput = &contextQuery{}\n\t\t\t\t}\n\t\t\t\t// fix #20: https://github.com/antchfx/htmlquery/issues/20\n\t\t\t\tfilter := func(n NodeNavigator) bool {\n\t\t\t\t\tv := predicate(n)\n\t\t\t\t\tswitch root.Prop {\n\t\t\t\t\tcase \"text\":\n\t\t\t\t\t\tv = v && n.NodeType() == TextNode\n\t\t\t\t\tcase \"comment\":\n\t\t\t\t\t\tv = v && n.NodeType() == CommentNode\n\t\t\t\t\t}\n\t\t\t\t\treturn v\n\t\t\t\t}\n\t\t\t\t// fix `//*[contains(@id,\"food\")]//*[contains(@id,\"food\")]`, see https://github.com/antchfx/htmlquery/issues/52\n\t\t\t\t// Skip the current node(Self:false) for the next descendants nodes.\n\t\t\t\t_, ok := qyGrandInput.(*contextQuery)\n\t\t\t\tqyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: ok}\n\t\t\t\treturn qyOutput, nil\n\t\t\t}\n\t\t}\n\t\tqyInput, err = b.processNode(root.Input)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tswitch root.AxeType {\n\tcase \"ancestor\":\n\t\tqyOutput = &ancestorQuery{Input: qyInput, Predicate: predicate}\n\tcase \"ancestor-or-self\":\n\t\tqyOutput = &ancestorQuery{Input: qyInput, Predicate: predicate, Self: true}\n\tcase \"attribute\":\n\t\tqyOutput = &attributeQuery{Input: qyInput, Predicate: predicate}\n\tcase \"child\":\n\t\tfilter := func(n NodeNavigator) bool {\n\t\t\tv := predicate(n)\n\t\t\tswitch root.Prop {\n\t\t\tcase \"text\":\n\t\t\t\tv = v && n.NodeType() == TextNode\n\t\t\tcase \"node\":\n\t\t\t\tv = v && (n.NodeType() == ElementNode || n.NodeType() == TextNode)\n\t\t\tcase \"comment\":\n\t\t\t\tv = v && n.NodeType() == CommentNode\n\t\t\t}\n\t\t\treturn v\n\t\t}\n\t\tqyOutput = &childQuery{Input: qyInput, Predicate: filter}\n\tcase \"descendant\":\n\t\tqyOutput = &descendantQuery{Input: qyInput, Predicate: predicate}\n\tcase \"descendant-or-self\":\n\t\tqyOutput = &descendantQuery{Input: qyInput, Predicate: predicate, Self: true}\n\tcase \"following\":\n\t\tqyOutput = &followingQuery{Input: qyInput, Predicate: predicate}\n\tcase \"following-sibling\":\n\t\tqyOutput = &followingQuery{Input: qyInput, Predicate: predicate, Sibling: true}\n\tcase \"parent\":\n\t\tqyOutput = &parentQuery{Input: qyInput, Predicate: predicate}\n\tcase \"preceding\":\n\t\tqyOutput = &precedingQuery{Input: qyInput, Predicate: predicate}\n\tcase \"preceding-sibling\":\n\t\tqyOutput = &precedingQuery{Input: qyInput, Predicate: predicate, Sibling: true}\n\tcase \"self\":\n\t\tqyOutput = &selfQuery{Input: qyInput, Predicate: predicate}\n\tcase \"namespace\":\n\t\t// haha,what will you do someting??\n\tdefault:\n\t\terr = fmt.Errorf(\"unknown axe type: %s\", root.AxeType)\n\t\treturn nil, err\n\t}\n\treturn qyOutput, nil\n}\n\n// processFilterNode builds query for the XPath filter predicate.\nfunc (b *builder) processFilterNode(root *filterNode) (query, error) {\n\tb.flag |= filterFlag\n\n\tqyInput, err := b.processNode(root.Input)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tqyCond, err := b.processNode(root.Condition)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tqyOutput := &filterQuery{Input: qyInput, Predicate: qyCond}\n\treturn qyOutput, nil\n}\n\n// processFunctionNode processes query for the XPath function node.\nfunc (b *builder) processFunctionNode(root *functionNode) (query, error) {\n\tvar qyOutput query\n\tswitch root.FuncName {\n\tcase \"starts-with\":\n\t\targ1, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\targ2, err := b.processNode(root.Args[1])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: startwithFunc(arg1, arg2)}\n\tcase \"ends-with\":\n\t\targ1, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\targ2, err := b.processNode(root.Args[1])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: endwithFunc(arg1, arg2)}\n\tcase \"contains\":\n\t\targ1, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\targ2, err := b.processNode(root.Args[1])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: containsFunc(arg1, arg2)}\n\tcase \"matches\":\n\t\t//matches(string , pattern)\n\t\tif len(root.Args) != 2 {\n\t\t\treturn nil, errors.New(\"xpath: matches function must have two parameters\")\n\t\t}\n\t\tvar (\n\t\t\targ1, arg2 query\n\t\t\terr        error\n\t\t)\n\t\tif arg1, err = b.processNode(root.Args[0]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif arg2, err = b.processNode(root.Args[1]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: matchesFunc(arg1, arg2)}\n\tcase \"substring\":\n\t\t//substring( string , start [, length] )\n\t\tif len(root.Args) < 2 {\n\t\t\treturn nil, errors.New(\"xpath: substring function must have at least two parameter\")\n\t\t}\n\t\tvar (\n\t\t\targ1, arg2, arg3 query\n\t\t\terr              error\n\t\t)\n\t\tif arg1, err = b.processNode(root.Args[0]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif arg2, err = b.processNode(root.Args[1]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(root.Args) == 3 {\n\t\t\tif arg3, err = b.processNode(root.Args[2]); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: substringFunc(arg1, arg2, arg3)}\n\tcase \"substring-before\", \"substring-after\":\n\t\t//substring-xxxx( haystack, needle )\n\t\tif len(root.Args) != 2 {\n\t\t\treturn nil, errors.New(\"xpath: substring-before function must have two parameters\")\n\t\t}\n\t\tvar (\n\t\t\targ1, arg2 query\n\t\t\terr        error\n\t\t)\n\t\tif arg1, err = b.processNode(root.Args[0]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif arg2, err = b.processNode(root.Args[1]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{\n\t\t\tInput: b.firstInput,\n\t\t\tFunc:  substringIndFunc(arg1, arg2, root.FuncName == \"substring-after\"),\n\t\t}\n\tcase \"string-length\":\n\t\t// string-length( [string] )\n\t\tif len(root.Args) < 1 {\n\t\t\treturn nil, errors.New(\"xpath: string-length function must have at least one parameter\")\n\t\t}\n\t\targ1, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: stringLengthFunc(arg1)}\n\tcase \"normalize-space\":\n\t\tif len(root.Args) == 0 {\n\t\t\treturn nil, errors.New(\"xpath: normalize-space function must have at least one parameter\")\n\t\t}\n\t\targQuery, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: argQuery, Func: normalizespaceFunc}\n\tcase \"replace\":\n\t\t//replace( string , string, string )\n\t\tif len(root.Args) != 3 {\n\t\t\treturn nil, errors.New(\"xpath: replace function must have three parameters\")\n\t\t}\n\t\tvar (\n\t\t\targ1, arg2, arg3 query\n\t\t\terr              error\n\t\t)\n\t\tif arg1, err = b.processNode(root.Args[0]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif arg2, err = b.processNode(root.Args[1]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif arg3, err = b.processNode(root.Args[2]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: replaceFunc(arg1, arg2, arg3)}\n\tcase \"translate\":\n\t\t//translate( string , string, string )\n\t\tif len(root.Args) != 3 {\n\t\t\treturn nil, errors.New(\"xpath: translate function must have three parameters\")\n\t\t}\n\t\tvar (\n\t\t\targ1, arg2, arg3 query\n\t\t\terr              error\n\t\t)\n\t\tif arg1, err = b.processNode(root.Args[0]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif arg2, err = b.processNode(root.Args[1]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif arg3, err = b.processNode(root.Args[2]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: translateFunc(arg1, arg2, arg3)}\n\tcase \"not\":\n\t\tif len(root.Args) == 0 {\n\t\t\treturn nil, errors.New(\"xpath: not function must have at least one parameter\")\n\t\t}\n\t\targQuery, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: argQuery, Func: notFunc}\n\tcase \"name\", \"local-name\", \"namespace-uri\":\n\t\tif len(root.Args) > 1 {\n\t\t\treturn nil, fmt.Errorf(\"xpath: %s function must have at most one parameter\", root.FuncName)\n\t\t}\n\t\tvar (\n\t\t\targ query\n\t\t\terr error\n\t\t)\n\t\tif len(root.Args) == 1 {\n\t\t\targ, err = b.processNode(root.Args[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tswitch root.FuncName {\n\t\tcase \"name\":\n\t\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: nameFunc(arg)}\n\t\tcase \"local-name\":\n\t\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: localNameFunc(arg)}\n\t\tcase \"namespace-uri\":\n\t\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: namespaceFunc(arg)}\n\t\t}\n\tcase \"true\", \"false\":\n\t\tval := root.FuncName == \"true\"\n\t\tqyOutput = &functionQuery{\n\t\t\tInput: b.firstInput,\n\t\t\tFunc: func(_ query, _ iterator) interface{} {\n\t\t\t\treturn val\n\t\t\t},\n\t\t}\n\tcase \"last\":\n\t\tswitch typ := b.firstInput.(type) {\n\t\tcase *groupQuery, *filterQuery:\n\t\t\t// https://github.com/antchfx/xpath/issues/76\n\t\t\t// https://github.com/antchfx/xpath/issues/78\n\t\t\tqyOutput = &lastQuery{Input: typ}\n\t\tdefault:\n\t\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc}\n\t\t}\n\n\tcase \"position\":\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: positionFunc}\n\tcase \"boolean\", \"number\", \"string\":\n\t\tinp := b.firstInput\n\t\tif len(root.Args) > 1 {\n\t\t\treturn nil, fmt.Errorf(\"xpath: %s function must have at most one parameter\", root.FuncName)\n\t\t}\n\t\tif len(root.Args) == 1 {\n\t\t\targQuery, err := b.processNode(root.Args[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tinp = argQuery\n\t\t}\n\t\tf := &functionQuery{Input: inp}\n\t\tswitch root.FuncName {\n\t\tcase \"boolean\":\n\t\t\tf.Func = booleanFunc\n\t\tcase \"string\":\n\t\t\tf.Func = stringFunc\n\t\tcase \"number\":\n\t\t\tf.Func = numberFunc\n\t\t}\n\t\tqyOutput = f\n\tcase \"count\":\n\t\t//if b.firstInput == nil {\n\t\t//\treturn nil, errors.New(\"xpath: expression must evaluate to node-set\")\n\t\t//}\n\t\tif len(root.Args) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"xpath: count(node-sets) function must with have parameters node-sets\")\n\t\t}\n\t\targQuery, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: argQuery, Func: countFunc}\n\tcase \"sum\":\n\t\tif len(root.Args) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"xpath: sum(node-sets) function must with have parameters node-sets\")\n\t\t}\n\t\targQuery, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &functionQuery{Input: argQuery, Func: sumFunc}\n\tcase \"ceiling\", \"floor\", \"round\":\n\t\tif len(root.Args) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"xpath: ceiling(node-sets) function must with have parameters node-sets\")\n\t\t}\n\t\targQuery, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tf := &functionQuery{Input: argQuery}\n\t\tswitch root.FuncName {\n\t\tcase \"ceiling\":\n\t\t\tf.Func = ceilingFunc\n\t\tcase \"floor\":\n\t\t\tf.Func = floorFunc\n\t\tcase \"round\":\n\t\t\tf.Func = roundFunc\n\t\t}\n\t\tqyOutput = f\n\tcase \"concat\":\n\t\tif len(root.Args) < 2 {\n\t\t\treturn nil, fmt.Errorf(\"xpath: concat() must have at least two arguments\")\n\t\t}\n\t\tvar args []query\n\t\tfor _, v := range root.Args {\n\t\t\tq, err := b.processNode(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\targs = append(args, q)\n\t\t}\n\t\tqyOutput = &functionQuery{Input: b.firstInput, Func: concatFunc(args...)}\n\tcase \"reverse\":\n\t\tif len(root.Args) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"xpath: reverse(node-sets) function must with have parameters node-sets\")\n\t\t}\n\t\targQuery, err := b.processNode(root.Args[0])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tqyOutput = &transformFunctionQuery{Input: argQuery, Func: reverseFunc}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"not yet support this function %s()\", root.FuncName)\n\t}\n\treturn qyOutput, nil\n}\n\nfunc (b *builder) processOperatorNode(root *operatorNode) (query, error) {\n\tleft, err := b.processNode(root.Left)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tright, err := b.processNode(root.Right)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar qyOutput query\n\tswitch root.Op {\n\tcase \"+\", \"-\", \"*\", \"div\", \"mod\": // Numeric operator\n\t\tvar exprFunc func(interface{}, interface{}) interface{}\n\t\tswitch root.Op {\n\t\tcase \"+\":\n\t\t\texprFunc = plusFunc\n\t\tcase \"-\":\n\t\t\texprFunc = minusFunc\n\t\tcase \"*\":\n\t\t\texprFunc = mulFunc\n\t\tcase \"div\":\n\t\t\texprFunc = divFunc\n\t\tcase \"mod\":\n\t\t\texprFunc = modFunc\n\t\t}\n\t\tqyOutput = &numericQuery{Left: left, Right: right, Do: exprFunc}\n\tcase \"=\", \">\", \">=\", \"<\", \"<=\", \"!=\":\n\t\tvar exprFunc func(iterator, interface{}, interface{}) interface{}\n\t\tswitch root.Op {\n\t\tcase \"=\":\n\t\t\texprFunc = eqFunc\n\t\tcase \">\":\n\t\t\texprFunc = gtFunc\n\t\tcase \">=\":\n\t\t\texprFunc = geFunc\n\t\tcase \"<\":\n\t\t\texprFunc = ltFunc\n\t\tcase \"<=\":\n\t\t\texprFunc = leFunc\n\t\tcase \"!=\":\n\t\t\texprFunc = neFunc\n\t\t}\n\t\tqyOutput = &logicalQuery{Left: left, Right: right, Do: exprFunc}\n\tcase \"or\", \"and\":\n\t\tisOr := false\n\t\tif root.Op == \"or\" {\n\t\t\tisOr = true\n\t\t}\n\t\tqyOutput = &booleanQuery{Left: left, Right: right, IsOr: isOr}\n\tcase \"|\":\n\t\tqyOutput = &unionQuery{Left: left, Right: right}\n\t}\n\treturn qyOutput, nil\n}\n\nfunc (b *builder) processNode(root node) (q query, err error) {\n\tif b.depth = b.depth + 1; b.depth > 1024 {\n\t\terr = errors.New(\"the xpath expressions is too complex\")\n\t\treturn\n\t}\n\n\tswitch root.Type() {\n\tcase nodeConstantOperand:\n\t\tn := root.(*operandNode)\n\t\tq = &constantQuery{Val: n.Val}\n\tcase nodeRoot:\n\t\tq = &contextQuery{Root: true}\n\tcase nodeAxis:\n\t\tq, err = b.processAxisNode(root.(*axisNode))\n\t\tb.firstInput = q\n\tcase nodeFilter:\n\t\tq, err = b.processFilterNode(root.(*filterNode))\n\t\tb.firstInput = q\n\tcase nodeFunction:\n\t\tq, err = b.processFunctionNode(root.(*functionNode))\n\tcase nodeOperator:\n\t\tq, err = b.processOperatorNode(root.(*operatorNode))\n\tcase nodeGroup:\n\t\tq, err = b.processNode(root.(*groupNode).Input)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tq = &groupQuery{Input: q}\n\t\tb.firstInput = q\n\t}\n\treturn\n}\n\n// build builds a specified XPath expressions expr.\nfunc build(expr string, namespaces map[string]string) (q query, err error) {\n\tdefer func() {\n\t\tif e := recover(); e != nil {\n\t\t\tswitch x := e.(type) {\n\t\t\tcase string:\n\t\t\t\terr = errors.New(x)\n\t\t\tcase error:\n\t\t\t\terr = x\n\t\t\tdefault:\n\t\t\t\terr = errors.New(\"unknown panic\")\n\t\t\t}\n\t\t}\n\t}()\n\troot := parse(expr, namespaces)\n\tb := &builder{}\n\treturn b.processNode(root)\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/cache.go",
    "content": "package xpath\n\nimport (\n\t\"regexp\"\n\t\"sync\"\n)\n\ntype loadFunc func(key interface{}) (interface{}, error)\n\nconst (\n\tdefaultCap = 65536\n)\n\n// The reason we're building a simple capacity-resetting loading cache (when capacity reached) instead of using\n// something like github.com/hashicorp/golang-lru is primarily due to (not wanting to create) external dependency.\n// Currently this library has 0 external dep (other than go sdk), and supports go 1.6, 1.9, and 1.10 (and later).\n// Creating external lib dependencies (plus their transitive dependencies) would make things hard if not impossible.\n// We expect under most circumstances, the defaultCap is big enough for any long running services that use this\n// library if their xpath regexp cardinality is low. However, in extreme cases when the capacity is reached, we\n// simply reset the cache, taking a small subsequent perf hit (next to nothing considering amortization) in trade\n// of more complex and less performant LRU type of construct.\ntype loadingCache struct {\n\tsync.RWMutex\n\tcap   int\n\tload  loadFunc\n\tm     map[interface{}]interface{}\n\treset int\n}\n\n// NewLoadingCache creates a new instance of a loading cache with capacity. Capacity must be >= 0, or\n// it will panic. Capacity == 0 means the cache growth is unbounded.\nfunc NewLoadingCache(load loadFunc, capacity int) *loadingCache {\n\tif capacity < 0 {\n\t\tpanic(\"capacity must be >= 0\")\n\t}\n\treturn &loadingCache{cap: capacity, load: load, m: make(map[interface{}]interface{})}\n}\n\nfunc (c *loadingCache) get(key interface{}) (interface{}, error) {\n\tc.RLock()\n\tv, found := c.m[key]\n\tc.RUnlock()\n\tif found {\n\t\treturn v, nil\n\t}\n\tv, err := c.load(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc.Lock()\n\tif c.cap > 0 && len(c.m) >= c.cap {\n\t\tc.m = map[interface{}]interface{}{key: v}\n\t\tc.reset++\n\t} else {\n\t\tc.m[key] = v\n\t}\n\tc.Unlock()\n\treturn v, nil\n}\n\nvar (\n\t// RegexpCache is a loading cache for string -> *regexp.Regexp mapping. It is exported so that in rare cases\n\t// client can customize load func and/or capacity.\n\tRegexpCache = defaultRegexpCache()\n)\n\nfunc defaultRegexpCache() *loadingCache {\n\treturn NewLoadingCache(\n\t\tfunc(key interface{}) (interface{}, error) {\n\t\t\treturn regexp.Compile(key.(string))\n\t\t}, defaultCap)\n}\n\nfunc getRegexp(pattern string) (*regexp.Regexp, error) {\n\texp, err := RegexpCache.get(pattern)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn exp.(*regexp.Regexp), nil\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/func.go",
    "content": "package xpath\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode\"\n)\n\n// Defined an interface of stringBuilder that compatible with\n// strings.Builder(go 1.10) and bytes.Buffer(< go 1.10)\ntype stringBuilder interface {\n\tWriteRune(r rune) (n int, err error)\n\tWriteString(s string) (int, error)\n\tReset()\n\tGrow(n int)\n\tString() string\n}\n\nvar builderPool = sync.Pool{New: func() interface{} {\n\treturn newStringBuilder()\n}}\n\n// The XPath function list.\n\nfunc predicate(q query) func(NodeNavigator) bool {\n\ttype Predicater interface {\n\t\tTest(NodeNavigator) bool\n\t}\n\tif p, ok := q.(Predicater); ok {\n\t\treturn p.Test\n\t}\n\treturn func(NodeNavigator) bool { return true }\n}\n\n// positionFunc is a XPath Node Set functions position().\nfunc positionFunc(q query, t iterator) interface{} {\n\tvar (\n\t\tcount = 1\n\t\tnode  = t.Current().Copy()\n\t)\n\ttest := predicate(q)\n\tfor node.MoveToPrevious() {\n\t\tif test(node) {\n\t\t\tcount++\n\t\t}\n\t}\n\treturn float64(count)\n}\n\n// lastFunc is a XPath Node Set functions last().\nfunc lastFunc(q query, t iterator) interface{} {\n\tvar (\n\t\tcount = 0\n\t\tnode  = t.Current().Copy()\n\t)\n\tnode.MoveToFirst()\n\ttest := predicate(q)\n\tfor {\n\t\tif test(node) {\n\t\t\tcount++\n\t\t}\n\t\tif !node.MoveToNext() {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn float64(count)\n}\n\n// countFunc is a XPath Node Set functions count(node-set).\nfunc countFunc(q query, t iterator) interface{} {\n\tvar count = 0\n\tq = functionArgs(q)\n\ttest := predicate(q)\n\tswitch typ := q.Evaluate(t).(type) {\n\tcase query:\n\t\tfor node := typ.Select(t); node != nil; node = typ.Select(t) {\n\t\t\tif test(node) {\n\t\t\t\tcount++\n\t\t\t}\n\t\t}\n\t}\n\treturn float64(count)\n}\n\n// sumFunc is a XPath Node Set functions sum(node-set).\nfunc sumFunc(q query, t iterator) interface{} {\n\tvar sum float64\n\tswitch typ := functionArgs(q).Evaluate(t).(type) {\n\tcase query:\n\t\tfor node := typ.Select(t); node != nil; node = typ.Select(t) {\n\t\t\tif v, err := strconv.ParseFloat(node.Value(), 64); err == nil {\n\t\t\t\tsum += v\n\t\t\t}\n\t\t}\n\tcase float64:\n\t\tsum = typ\n\tcase string:\n\t\tv, err := strconv.ParseFloat(typ, 64)\n\t\tif err != nil {\n\t\t\tpanic(errors.New(\"sum() function argument type must be a node-set or number\"))\n\t\t}\n\t\tsum = v\n\t}\n\treturn sum\n}\n\nfunc asNumber(t iterator, o interface{}) float64 {\n\tswitch typ := o.(type) {\n\tcase query:\n\t\tnode := typ.Select(t)\n\t\tif node == nil {\n\t\t\treturn float64(0)\n\t\t}\n\t\tif v, err := strconv.ParseFloat(node.Value(), 64); err == nil {\n\t\t\treturn v\n\t\t}\n\tcase float64:\n\t\treturn typ\n\tcase string:\n\t\tv, err := strconv.ParseFloat(typ, 64)\n\t\tif err == nil {\n\t\t\treturn v\n\t\t}\n\t}\n\treturn math.NaN()\n}\n\n// ceilingFunc is a XPath Node Set functions ceiling(node-set).\nfunc ceilingFunc(q query, t iterator) interface{} {\n\tval := asNumber(t, functionArgs(q).Evaluate(t))\n\t// if math.IsNaN(val) {\n\t// \tpanic(errors.New(\"ceiling() function argument type must be a valid number\"))\n\t// }\n\treturn math.Ceil(val)\n}\n\n// floorFunc is a XPath Node Set functions floor(node-set).\nfunc floorFunc(q query, t iterator) interface{} {\n\tval := asNumber(t, functionArgs(q).Evaluate(t))\n\treturn math.Floor(val)\n}\n\n// roundFunc is a XPath Node Set functions round(node-set).\nfunc roundFunc(q query, t iterator) interface{} {\n\tval := asNumber(t, functionArgs(q).Evaluate(t))\n\t//return math.Round(val)\n\treturn round(val)\n}\n\n// nameFunc is a XPath functions name([node-set]).\nfunc nameFunc(arg query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar v NodeNavigator\n\t\tif arg == nil {\n\t\t\tv = t.Current()\n\t\t} else {\n\t\t\tv = arg.Clone().Select(t)\n\t\t\tif v == nil {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t\tns := v.Prefix()\n\t\tif ns == \"\" {\n\t\t\treturn v.LocalName()\n\t\t}\n\t\treturn ns + \":\" + v.LocalName()\n\t}\n}\n\n// localNameFunc is a XPath functions local-name([node-set]).\nfunc localNameFunc(arg query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar v NodeNavigator\n\t\tif arg == nil {\n\t\t\tv = t.Current()\n\t\t} else {\n\t\t\tv = arg.Clone().Select(t)\n\t\t\tif v == nil {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t\treturn v.LocalName()\n\t}\n}\n\n// namespaceFunc is a XPath functions namespace-uri([node-set]).\nfunc namespaceFunc(arg query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar v NodeNavigator\n\t\tif arg == nil {\n\t\t\tv = t.Current()\n\t\t} else {\n\t\t\t// Get the first node in the node-set if specified.\n\t\t\tv = arg.Clone().Select(t)\n\t\t\tif v == nil {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t}\n\t\t// fix about namespace-uri() bug: https://github.com/antchfx/xmlquery/issues/22\n\t\t// TODO: In the next version, add NamespaceURL() to the NodeNavigator interface.\n\t\ttype namespaceURL interface {\n\t\t\tNamespaceURL() string\n\t\t}\n\t\tif f, ok := v.(namespaceURL); ok {\n\t\t\treturn f.NamespaceURL()\n\t\t}\n\t\treturn v.Prefix()\n\t}\n}\n\nfunc asBool(t iterator, v interface{}) bool {\n\tswitch v := v.(type) {\n\tcase nil:\n\t\treturn false\n\tcase *NodeIterator:\n\t\treturn v.MoveNext()\n\tcase bool:\n\t\treturn v\n\tcase float64:\n\t\treturn v != 0\n\tcase string:\n\t\treturn v != \"\"\n\tcase query:\n\t\treturn v.Select(t) != nil\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected type: %T\", v))\n\t}\n}\n\nfunc asString(t iterator, v interface{}) string {\n\tswitch v := v.(type) {\n\tcase nil:\n\t\treturn \"\"\n\tcase bool:\n\t\tif v {\n\t\t\treturn \"true\"\n\t\t}\n\t\treturn \"false\"\n\tcase float64:\n\t\treturn strconv.FormatFloat(v, 'g', -1, 64)\n\tcase string:\n\t\treturn v\n\tcase query:\n\t\tnode := v.Select(t)\n\t\tif node == nil {\n\t\t\treturn \"\"\n\t\t}\n\t\treturn node.Value()\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected type: %T\", v))\n\t}\n}\n\n// booleanFunc is a XPath functions boolean([node-set]).\nfunc booleanFunc(q query, t iterator) interface{} {\n\tv := functionArgs(q).Evaluate(t)\n\treturn asBool(t, v)\n}\n\n// numberFunc is a XPath functions number([node-set]).\nfunc numberFunc(q query, t iterator) interface{} {\n\tv := functionArgs(q).Evaluate(t)\n\treturn asNumber(t, v)\n}\n\n// stringFunc is a XPath functions string([node-set]).\nfunc stringFunc(q query, t iterator) interface{} {\n\tv := functionArgs(q).Evaluate(t)\n\treturn asString(t, v)\n}\n\n// startwithFunc is a XPath functions starts-with(string, string).\nfunc startwithFunc(arg1, arg2 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar (\n\t\t\tm, n string\n\t\t\tok   bool\n\t\t)\n\t\tswitch typ := functionArgs(arg1).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\tm = typ\n\t\tcase query:\n\t\t\tnode := typ.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm = node.Value()\n\t\tdefault:\n\t\t\tpanic(errors.New(\"starts-with() function argument type must be string\"))\n\t\t}\n\t\tn, ok = functionArgs(arg2).Evaluate(t).(string)\n\t\tif !ok {\n\t\t\tpanic(errors.New(\"starts-with() function argument type must be string\"))\n\t\t}\n\t\treturn strings.HasPrefix(m, n)\n\t}\n}\n\n// endwithFunc is a XPath functions ends-with(string, string).\nfunc endwithFunc(arg1, arg2 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar (\n\t\t\tm, n string\n\t\t\tok   bool\n\t\t)\n\t\tswitch typ := functionArgs(arg1).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\tm = typ\n\t\tcase query:\n\t\t\tnode := typ.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm = node.Value()\n\t\tdefault:\n\t\t\tpanic(errors.New(\"ends-with() function argument type must be string\"))\n\t\t}\n\t\tn, ok = functionArgs(arg2).Evaluate(t).(string)\n\t\tif !ok {\n\t\t\tpanic(errors.New(\"ends-with() function argument type must be string\"))\n\t\t}\n\t\treturn strings.HasSuffix(m, n)\n\t}\n}\n\n// containsFunc is a XPath functions contains(string or @attr, string).\nfunc containsFunc(arg1, arg2 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar (\n\t\t\tm, n string\n\t\t\tok   bool\n\t\t)\n\t\tswitch typ := functionArgs(arg1).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\tm = typ\n\t\tcase query:\n\t\t\tnode := typ.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tm = node.Value()\n\t\tdefault:\n\t\t\tpanic(errors.New(\"contains() function argument type must be string\"))\n\t\t}\n\n\t\tn, ok = functionArgs(arg2).Evaluate(t).(string)\n\t\tif !ok {\n\t\t\tpanic(errors.New(\"contains() function argument type must be string\"))\n\t\t}\n\n\t\treturn strings.Contains(m, n)\n\t}\n}\n\n// matchesFunc is an XPath function that tests a given string against a regexp pattern.\n// Note: does not support https://www.w3.org/TR/xpath-functions-31/#func-matches 3rd optional `flags` argument; if\n// needed, directly put flags in the regexp pattern, such as `(?i)^pattern$` for `i` flag.\nfunc matchesFunc(arg1, arg2 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar s string\n\t\tswitch typ := functionArgs(arg1).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\ts = typ\n\t\tcase query:\n\t\t\tnode := typ.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\ts = node.Value()\n\t\t}\n\t\tvar pattern string\n\t\tvar ok bool\n\t\tif pattern, ok = functionArgs(arg2).Evaluate(t).(string); !ok {\n\t\t\tpanic(errors.New(\"matches() function second argument type must be string\"))\n\t\t}\n\t\tre, err := getRegexp(pattern)\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"matches() function second argument is not a valid regexp pattern, err: %s\", err.Error()))\n\t\t}\n\t\treturn re.MatchString(s)\n\t}\n}\n\n// normalizespaceFunc is XPath functions normalize-space(string?)\nfunc normalizespaceFunc(q query, t iterator) interface{} {\n\tvar m string\n\tswitch typ := functionArgs(q).Evaluate(t).(type) {\n\tcase string:\n\t\tm = typ\n\tcase query:\n\t\tnode := typ.Select(t)\n\t\tif node == nil {\n\t\t\treturn \"\"\n\t\t}\n\t\tm = node.Value()\n\t}\n\tvar b = builderPool.Get().(stringBuilder)\n\tb.Grow(len(m))\n\n\truneStr := []rune(strings.TrimSpace(m))\n\tl := len(runeStr)\n\tfor i := range runeStr {\n\t\tr := runeStr[i]\n\t\tisSpace := unicode.IsSpace(r)\n\t\tif !(isSpace && (i+1 < l && unicode.IsSpace(runeStr[i+1]))) {\n\t\t\tif isSpace {\n\t\t\t\tr = ' '\n\t\t\t}\n\t\t\tb.WriteRune(r)\n\t\t}\n\t}\n\tresult := b.String()\n\tb.Reset()\n\tbuilderPool.Put(b)\n\n\treturn result\n}\n\n// substringFunc is XPath functions substring function returns a part of a given string.\nfunc substringFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar m string\n\t\tswitch typ := functionArgs(arg1).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\tm = typ\n\t\tcase query:\n\t\t\tnode := typ.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\tm = node.Value()\n\t\t}\n\n\t\tvar start, length float64\n\t\tvar ok bool\n\n\t\tif start, ok = functionArgs(arg2).Evaluate(t).(float64); !ok {\n\t\t\tpanic(errors.New(\"substring() function first argument type must be int\"))\n\t\t} else if start < 1 {\n\t\t\tpanic(errors.New(\"substring() function first argument type must be >= 1\"))\n\t\t}\n\t\tstart--\n\t\tif arg3 != nil {\n\t\t\tif length, ok = functionArgs(arg3).Evaluate(t).(float64); !ok {\n\t\t\t\tpanic(errors.New(\"substring() function second argument type must be int\"))\n\t\t\t}\n\t\t}\n\t\tif (len(m) - int(start)) < int(length) {\n\t\t\tpanic(errors.New(\"substring() function start and length argument out of range\"))\n\t\t}\n\t\tif length > 0 {\n\t\t\treturn m[int(start):int(length+start)]\n\t\t}\n\t\treturn m[int(start):]\n\t}\n}\n\n// substringIndFunc is XPath functions substring-before/substring-after function returns a part of a given string.\nfunc substringIndFunc(arg1, arg2 query, after bool) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tvar str string\n\t\tswitch v := functionArgs(arg1).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\tstr = v\n\t\tcase query:\n\t\t\tnode := v.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\tstr = node.Value()\n\t\t}\n\t\tvar word string\n\t\tswitch v := functionArgs(arg2).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\tword = v\n\t\tcase query:\n\t\t\tnode := v.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\tword = node.Value()\n\t\t}\n\t\tif word == \"\" {\n\t\t\treturn \"\"\n\t\t}\n\n\t\ti := strings.Index(str, word)\n\t\tif i < 0 {\n\t\t\treturn \"\"\n\t\t}\n\t\tif after {\n\t\t\treturn str[i+len(word):]\n\t\t}\n\t\treturn str[:i]\n\t}\n}\n\n// stringLengthFunc is XPATH string-length( [string] ) function that returns a number\n// equal to the number of characters in a given string.\nfunc stringLengthFunc(arg1 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tswitch v := functionArgs(arg1).Evaluate(t).(type) {\n\t\tcase string:\n\t\t\treturn float64(len(v))\n\t\tcase query:\n\t\t\tnode := v.Select(t)\n\t\t\tif node == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn float64(len(node.Value()))\n\t\t}\n\t\treturn float64(0)\n\t}\n}\n\n// translateFunc is XPath functions translate() function returns a replaced string.\nfunc translateFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tstr := asString(t, functionArgs(arg1).Evaluate(t))\n\t\tsrc := asString(t, functionArgs(arg2).Evaluate(t))\n\t\tdst := asString(t, functionArgs(arg3).Evaluate(t))\n\n\t\treplace := make([]string, 0, len(src))\n\t\tfor i, s := range src {\n\t\t\td := \"\"\n\t\t\tif i < len(dst) {\n\t\t\t\td = string(dst[i])\n\t\t\t}\n\t\t\treplace = append(replace, string(s), d)\n\t\t}\n\t\treturn strings.NewReplacer(replace...).Replace(str)\n\t}\n}\n\n// replaceFunc is XPath functions replace() function returns a replaced string.\nfunc replaceFunc(arg1, arg2, arg3 query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tstr := asString(t, functionArgs(arg1).Evaluate(t))\n\t\tsrc := asString(t, functionArgs(arg2).Evaluate(t))\n\t\tdst := asString(t, functionArgs(arg3).Evaluate(t))\n\n\t\treturn strings.Replace(str, src, dst, -1)\n\t}\n}\n\n// notFunc is XPATH functions not(expression) function operation.\nfunc notFunc(q query, t iterator) interface{} {\n\tswitch v := functionArgs(q).Evaluate(t).(type) {\n\tcase bool:\n\t\treturn !v\n\tcase query:\n\t\tnode := v.Select(t)\n\t\treturn node == nil\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// concatFunc is the concat function concatenates two or more\n// strings and returns the resulting string.\n// concat( string1 , string2 [, stringn]* )\nfunc concatFunc(args ...query) func(query, iterator) interface{} {\n\treturn func(q query, t iterator) interface{} {\n\t\tb := builderPool.Get().(stringBuilder)\n\t\tfor _, v := range args {\n\t\t\tv = functionArgs(v)\n\n\t\t\tswitch v := v.Evaluate(t).(type) {\n\t\t\tcase string:\n\t\t\t\tb.WriteString(v)\n\t\t\tcase query:\n\t\t\t\tnode := v.Select(t)\n\t\t\t\tif node != nil {\n\t\t\t\t\tb.WriteString(node.Value())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tresult := b.String()\n\t\tb.Reset()\n\t\tbuilderPool.Put(b)\n\n\t\treturn result\n\t}\n}\n\n// https://github.com/antchfx/xpath/issues/43\nfunc functionArgs(q query) query {\n\tif _, ok := q.(*functionQuery); ok {\n\t\treturn q\n\t}\n\treturn q.Clone()\n}\n\nfunc reverseFunc(q query, t iterator) func() NodeNavigator {\n\tvar list []NodeNavigator\n\tfor {\n\t\tnode := q.Select(t)\n\t\tif node == nil {\n\t\t\tbreak\n\t\t}\n\t\tlist = append(list, node.Copy())\n\t}\n\ti := len(list)\n\treturn func() NodeNavigator {\n\t\tif i <= 0 {\n\t\t\treturn nil\n\t\t}\n\t\ti--\n\t\tnode := list[i]\n\t\treturn node\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/func_go110.go",
    "content": "// +build go1.10\n\npackage xpath\n\nimport (\n\t\"math\"\n\t\"strings\"\n)\n\nfunc round(f float64) int {\n\treturn int(math.Round(f))\n}\n\nfunc newStringBuilder() stringBuilder {\n\treturn &strings.Builder{}\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/func_pre_go110.go",
    "content": "// +build !go1.10\n\npackage xpath\n\nimport (\n\t\"bytes\"\n\t\"math\"\n)\n\n// math.Round() is supported by Go 1.10+,\n// This method just compatible for version <1.10.\n// https://github.com/golang/go/issues/20100\nfunc round(f float64) int {\n\tif math.Abs(f) < 0.5 {\n\t\treturn 0\n\t}\n\treturn int(f + math.Copysign(0.5, f))\n}\n\nfunc newStringBuilder() stringBuilder {\n\treturn &bytes.Buffer{}\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/operator.go",
    "content": "package xpath\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n)\n\n// The XPath number operator function list.\n\n// valueType is a return value type.\ntype valueType int\n\nconst (\n\tbooleanType valueType = iota\n\tnumberType\n\tstringType\n\tnodeSetType\n)\n\nfunc getValueType(i interface{}) valueType {\n\tv := reflect.ValueOf(i)\n\tswitch v.Kind() {\n\tcase reflect.Float64:\n\t\treturn numberType\n\tcase reflect.String:\n\t\treturn stringType\n\tcase reflect.Bool:\n\t\treturn booleanType\n\tdefault:\n\t\tif _, ok := i.(query); ok {\n\t\t\treturn nodeSetType\n\t\t}\n\t}\n\tpanic(fmt.Errorf(\"xpath unknown value type: %v\", v.Kind()))\n}\n\ntype logical func(iterator, string, interface{}, interface{}) bool\n\nvar logicalFuncs = [][]logical{\n\t{cmpBooleanBoolean, nil, nil, nil},\n\t{nil, cmpNumericNumeric, cmpNumericString, cmpNumericNodeSet},\n\t{nil, cmpStringNumeric, cmpStringString, cmpStringNodeSet},\n\t{nil, cmpNodeSetNumeric, cmpNodeSetString, cmpNodeSetNodeSet},\n}\n\n// number vs number\nfunc cmpNumberNumberF(op string, a, b float64) bool {\n\tswitch op {\n\tcase \"=\":\n\t\treturn a == b\n\tcase \">\":\n\t\treturn a > b\n\tcase \"<\":\n\t\treturn a < b\n\tcase \">=\":\n\t\treturn a >= b\n\tcase \"<=\":\n\t\treturn a <= b\n\tcase \"!=\":\n\t\treturn a != b\n\t}\n\treturn false\n}\n\n// string vs string\nfunc cmpStringStringF(op string, a, b string) bool {\n\tswitch op {\n\tcase \"=\":\n\t\treturn a == b\n\tcase \">\":\n\t\treturn a > b\n\tcase \"<\":\n\t\treturn a < b\n\tcase \">=\":\n\t\treturn a >= b\n\tcase \"<=\":\n\t\treturn a <= b\n\tcase \"!=\":\n\t\treturn a != b\n\t}\n\treturn false\n}\n\nfunc cmpBooleanBooleanF(op string, a, b bool) bool {\n\tswitch op {\n\tcase \"or\":\n\t\treturn a || b\n\tcase \"and\":\n\t\treturn a && b\n\t}\n\treturn false\n}\n\nfunc cmpNumericNumeric(t iterator, op string, m, n interface{}) bool {\n\ta := m.(float64)\n\tb := n.(float64)\n\treturn cmpNumberNumberF(op, a, b)\n}\n\nfunc cmpNumericString(t iterator, op string, m, n interface{}) bool {\n\ta := m.(float64)\n\tb := n.(string)\n\tnum, err := strconv.ParseFloat(b, 64)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn cmpNumberNumberF(op, a, num)\n}\n\nfunc cmpNumericNodeSet(t iterator, op string, m, n interface{}) bool {\n\ta := m.(float64)\n\tb := n.(query)\n\n\tfor {\n\t\tnode := b.Select(t)\n\t\tif node == nil {\n\t\t\tbreak\n\t\t}\n\t\tnum, err := strconv.ParseFloat(node.Value(), 64)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif cmpNumberNumberF(op, a, num) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc cmpNodeSetNumeric(t iterator, op string, m, n interface{}) bool {\n\ta := m.(query)\n\tb := n.(float64)\n\tfor {\n\t\tnode := a.Select(t)\n\t\tif node == nil {\n\t\t\tbreak\n\t\t}\n\t\tnum, err := strconv.ParseFloat(node.Value(), 64)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif cmpNumberNumberF(op, num, b) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc cmpNodeSetString(t iterator, op string, m, n interface{}) bool {\n\ta := m.(query)\n\tb := n.(string)\n\tfor {\n\t\tnode := a.Select(t)\n\t\tif node == nil {\n\t\t\tbreak\n\t\t}\n\t\tif cmpStringStringF(op, b, node.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc cmpNodeSetNodeSet(t iterator, op string, m, n interface{}) bool {\n\ta := m.(query)\n\tb := n.(query)\n\tfor {\n\t\tx := a.Select(t)\n\t\tif x == nil {\n\t\t\treturn false\n\t\t}\n\n\t\ty := b.Select(t)\n\t\tif y == nil {\n\t\t\treturn false\n\t\t}\n\n\t\tfor {\n\t\t\tif cmpStringStringF(op, x.Value(), y.Value()) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif y = b.Select(t); y == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\t// reset\n\t\tb.Evaluate(t)\n\t}\n}\n\nfunc cmpStringNumeric(t iterator, op string, m, n interface{}) bool {\n\ta := m.(string)\n\tb := n.(float64)\n\tnum, err := strconv.ParseFloat(a, 64)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn cmpNumberNumberF(op, b, num)\n}\n\nfunc cmpStringString(t iterator, op string, m, n interface{}) bool {\n\ta := m.(string)\n\tb := n.(string)\n\treturn cmpStringStringF(op, a, b)\n}\n\nfunc cmpStringNodeSet(t iterator, op string, m, n interface{}) bool {\n\ta := m.(string)\n\tb := n.(query)\n\tfor {\n\t\tnode := b.Select(t)\n\t\tif node == nil {\n\t\t\tbreak\n\t\t}\n\t\tif cmpStringStringF(op, a, node.Value()) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc cmpBooleanBoolean(t iterator, op string, m, n interface{}) bool {\n\ta := m.(bool)\n\tb := n.(bool)\n\treturn cmpBooleanBooleanF(op, a, b)\n}\n\n// eqFunc is an `=` operator.\nfunc eqFunc(t iterator, m, n interface{}) interface{} {\n\tt1 := getValueType(m)\n\tt2 := getValueType(n)\n\treturn logicalFuncs[t1][t2](t, \"=\", m, n)\n}\n\n// gtFunc is an `>` operator.\nfunc gtFunc(t iterator, m, n interface{}) interface{} {\n\tt1 := getValueType(m)\n\tt2 := getValueType(n)\n\treturn logicalFuncs[t1][t2](t, \">\", m, n)\n}\n\n// geFunc is an `>=` operator.\nfunc geFunc(t iterator, m, n interface{}) interface{} {\n\tt1 := getValueType(m)\n\tt2 := getValueType(n)\n\treturn logicalFuncs[t1][t2](t, \">=\", m, n)\n}\n\n// ltFunc is an `<` operator.\nfunc ltFunc(t iterator, m, n interface{}) interface{} {\n\tt1 := getValueType(m)\n\tt2 := getValueType(n)\n\treturn logicalFuncs[t1][t2](t, \"<\", m, n)\n}\n\n// leFunc is an `<=` operator.\nfunc leFunc(t iterator, m, n interface{}) interface{} {\n\tt1 := getValueType(m)\n\tt2 := getValueType(n)\n\treturn logicalFuncs[t1][t2](t, \"<=\", m, n)\n}\n\n// neFunc is an `!=` operator.\nfunc neFunc(t iterator, m, n interface{}) interface{} {\n\tt1 := getValueType(m)\n\tt2 := getValueType(n)\n\treturn logicalFuncs[t1][t2](t, \"!=\", m, n)\n}\n\n// orFunc is an `or` operator.\nvar orFunc = func(t iterator, m, n interface{}) interface{} {\n\tt1 := getValueType(m)\n\tt2 := getValueType(n)\n\treturn logicalFuncs[t1][t2](t, \"or\", m, n)\n}\n\nfunc numericExpr(m, n interface{}, cb func(float64, float64) float64) float64 {\n\ttyp := reflect.TypeOf(float64(0))\n\ta := reflect.ValueOf(m).Convert(typ)\n\tb := reflect.ValueOf(n).Convert(typ)\n\treturn cb(a.Float(), b.Float())\n}\n\n// plusFunc is an `+` operator.\nvar plusFunc = func(m, n interface{}) interface{} {\n\treturn numericExpr(m, n, func(a, b float64) float64 {\n\t\treturn a + b\n\t})\n}\n\n// minusFunc is an `-` operator.\nvar minusFunc = func(m, n interface{}) interface{} {\n\treturn numericExpr(m, n, func(a, b float64) float64 {\n\t\treturn a - b\n\t})\n}\n\n// mulFunc is an `*` operator.\nvar mulFunc = func(m, n interface{}) interface{} {\n\treturn numericExpr(m, n, func(a, b float64) float64 {\n\t\treturn a * b\n\t})\n}\n\n// divFunc is an `DIV` operator.\nvar divFunc = func(m, n interface{}) interface{} {\n\treturn numericExpr(m, n, func(a, b float64) float64 {\n\t\treturn a / b\n\t})\n}\n\n// modFunc is an 'MOD' operator.\nvar modFunc = func(m, n interface{}) interface{} {\n\treturn numericExpr(m, n, func(a, b float64) float64 {\n\t\treturn float64(int(a) % int(b))\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/parse.go",
    "content": "package xpath\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"unicode\"\n)\n\n// A XPath expression token type.\ntype itemType int\n\nconst (\n\titemComma      itemType = iota // ','\n\titemSlash                      // '/'\n\titemAt                         // '@'\n\titemDot                        // '.'\n\titemLParens                    // '('\n\titemRParens                    // ')'\n\titemLBracket                   // '['\n\titemRBracket                   // ']'\n\titemStar                       // '*'\n\titemPlus                       // '+'\n\titemMinus                      // '-'\n\titemEq                         // '='\n\titemLt                         // '<'\n\titemGt                         // '>'\n\titemBang                       // '!'\n\titemDollar                     // '$'\n\titemApos                       // '\\''\n\titemQuote                      // '\"'\n\titemUnion                      // '|'\n\titemNe                         // '!='\n\titemLe                         // '<='\n\titemGe                         // '>='\n\titemAnd                        // '&&'\n\titemOr                         // '||'\n\titemDotDot                     // '..'\n\titemSlashSlash                 // '//'\n\titemName                       // XML Name\n\titemString                     // Quoted string constant\n\titemNumber                     // Number constant\n\titemAxe                        // Axe (like child::)\n\titemEOF                        // END\n)\n\n// A node is an XPath node in the parse tree.\ntype node interface {\n\tType() nodeType\n}\n\n// nodeType identifies the type of a parse tree node.\ntype nodeType int\n\nfunc (t nodeType) Type() nodeType {\n\treturn t\n}\n\nconst (\n\tnodeRoot nodeType = iota\n\tnodeAxis\n\tnodeFilter\n\tnodeFunction\n\tnodeOperator\n\tnodeVariable\n\tnodeConstantOperand\n\tnodeGroup\n)\n\ntype parser struct {\n\tr          *scanner\n\td          int\n\tnamespaces map[string]string\n}\n\n// newOperatorNode returns new operator node OperatorNode.\nfunc newOperatorNode(op string, left, right node) node {\n\treturn &operatorNode{nodeType: nodeOperator, Op: op, Left: left, Right: right}\n}\n\n// newOperand returns new constant operand node OperandNode.\nfunc newOperandNode(v interface{}) node {\n\treturn &operandNode{nodeType: nodeConstantOperand, Val: v}\n}\n\n// newAxisNode returns new axis node AxisNode.\nfunc newAxisNode(axeTyp, localName, prefix, prop string, n node, opts ...func(p *axisNode)) node {\n\ta := axisNode{\n\t\tnodeType:  nodeAxis,\n\t\tLocalName: localName,\n\t\tPrefix:    prefix,\n\t\tAxeType:   axeTyp,\n\t\tProp:      prop,\n\t\tInput:     n,\n\t}\n\tfor _, o := range opts {\n\t\to(&a)\n\t}\n\treturn &a\n}\n\n// newVariableNode returns new variable node VariableNode.\nfunc newVariableNode(prefix, name string) node {\n\treturn &variableNode{nodeType: nodeVariable, Name: name, Prefix: prefix}\n}\n\n// newFilterNode returns a new filter node FilterNode.\nfunc newFilterNode(n, m node) node {\n\treturn &filterNode{nodeType: nodeFilter, Input: n, Condition: m}\n}\n\nfunc newGroupNode(n node) node {\n\treturn &groupNode{nodeType: nodeGroup, Input: n}\n}\n\n// newRootNode returns a root node.\nfunc newRootNode(s string) node {\n\treturn &rootNode{nodeType: nodeRoot, slash: s}\n}\n\n// newFunctionNode returns function call node.\nfunc newFunctionNode(name, prefix string, args []node) node {\n\treturn &functionNode{nodeType: nodeFunction, Prefix: prefix, FuncName: name, Args: args}\n}\n\n// testOp reports whether current item name is an operand op.\nfunc testOp(r *scanner, op string) bool {\n\treturn r.typ == itemName && r.prefix == \"\" && r.name == op\n}\n\nfunc isPrimaryExpr(r *scanner) bool {\n\tswitch r.typ {\n\tcase itemString, itemNumber, itemDollar, itemLParens:\n\t\treturn true\n\tcase itemName:\n\t\treturn r.canBeFunc && !isNodeType(r)\n\t}\n\treturn false\n}\n\nfunc isNodeType(r *scanner) bool {\n\tswitch r.name {\n\tcase \"node\", \"text\", \"processing-instruction\", \"comment\":\n\t\treturn r.prefix == \"\"\n\t}\n\treturn false\n}\n\nfunc isStep(item itemType) bool {\n\tswitch item {\n\tcase itemDot, itemDotDot, itemAt, itemAxe, itemStar, itemName:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc checkItem(r *scanner, typ itemType) {\n\tif r.typ != typ {\n\t\tpanic(fmt.Sprintf(\"%s has an invalid token\", r.text))\n\t}\n}\n\n// parseExpression parsing the expression with input node n.\nfunc (p *parser) parseExpression(n node) node {\n\tif p.d = p.d + 1; p.d > 200 {\n\t\tpanic(\"the xpath query is too complex(depth > 200)\")\n\t}\n\tn = p.parseOrExpr(n)\n\tp.d--\n\treturn n\n}\n\n// next scanning next item on forward.\nfunc (p *parser) next() bool {\n\treturn p.r.nextItem()\n}\n\nfunc (p *parser) skipItem(typ itemType) {\n\tcheckItem(p.r, typ)\n\tp.next()\n}\n\n// OrExpr ::= AndExpr | OrExpr 'or' AndExpr\nfunc (p *parser) parseOrExpr(n node) node {\n\topnd := p.parseAndExpr(n)\n\tfor {\n\t\tif !testOp(p.r, \"or\") {\n\t\t\tbreak\n\t\t}\n\t\tp.next()\n\t\topnd = newOperatorNode(\"or\", opnd, p.parseAndExpr(n))\n\t}\n\treturn opnd\n}\n\n// AndExpr ::= EqualityExpr\t| AndExpr 'and' EqualityExpr\nfunc (p *parser) parseAndExpr(n node) node {\n\topnd := p.parseEqualityExpr(n)\n\tfor {\n\t\tif !testOp(p.r, \"and\") {\n\t\t\tbreak\n\t\t}\n\t\tp.next()\n\t\topnd = newOperatorNode(\"and\", opnd, p.parseEqualityExpr(n))\n\t}\n\treturn opnd\n}\n\n// EqualityExpr ::= RelationalExpr | EqualityExpr '=' RelationalExpr | EqualityExpr '!=' RelationalExpr\nfunc (p *parser) parseEqualityExpr(n node) node {\n\topnd := p.parseRelationalExpr(n)\nLoop:\n\tfor {\n\t\tvar op string\n\t\tswitch p.r.typ {\n\t\tcase itemEq:\n\t\t\top = \"=\"\n\t\tcase itemNe:\n\t\t\top = \"!=\"\n\t\tdefault:\n\t\t\tbreak Loop\n\t\t}\n\t\tp.next()\n\t\topnd = newOperatorNode(op, opnd, p.parseRelationalExpr(n))\n\t}\n\treturn opnd\n}\n\n// RelationalExpr ::= AdditiveExpr\t| RelationalExpr '<' AdditiveExpr | RelationalExpr '>' AdditiveExpr\n//\t\t\t\t\t| RelationalExpr '<=' AdditiveExpr\n//\t\t\t\t\t| RelationalExpr '>=' AdditiveExpr\nfunc (p *parser) parseRelationalExpr(n node) node {\n\topnd := p.parseAdditiveExpr(n)\nLoop:\n\tfor {\n\t\tvar op string\n\t\tswitch p.r.typ {\n\t\tcase itemLt:\n\t\t\top = \"<\"\n\t\tcase itemGt:\n\t\t\top = \">\"\n\t\tcase itemLe:\n\t\t\top = \"<=\"\n\t\tcase itemGe:\n\t\t\top = \">=\"\n\t\tdefault:\n\t\t\tbreak Loop\n\t\t}\n\t\tp.next()\n\t\topnd = newOperatorNode(op, opnd, p.parseAdditiveExpr(n))\n\t}\n\treturn opnd\n}\n\n// AdditiveExpr\t::= MultiplicativeExpr\t| AdditiveExpr '+' MultiplicativeExpr | AdditiveExpr '-' MultiplicativeExpr\nfunc (p *parser) parseAdditiveExpr(n node) node {\n\topnd := p.parseMultiplicativeExpr(n)\nLoop:\n\tfor {\n\t\tvar op string\n\t\tswitch p.r.typ {\n\t\tcase itemPlus:\n\t\t\top = \"+\"\n\t\tcase itemMinus:\n\t\t\top = \"-\"\n\t\tdefault:\n\t\t\tbreak Loop\n\t\t}\n\t\tp.next()\n\t\topnd = newOperatorNode(op, opnd, p.parseMultiplicativeExpr(n))\n\t}\n\treturn opnd\n}\n\n// MultiplicativeExpr ::= UnaryExpr\t| MultiplicativeExpr MultiplyOperator(*) UnaryExpr\n//\t\t\t\t\t\t| MultiplicativeExpr 'div' UnaryExpr | MultiplicativeExpr 'mod' UnaryExpr\nfunc (p *parser) parseMultiplicativeExpr(n node) node {\n\topnd := p.parseUnaryExpr(n)\nLoop:\n\tfor {\n\t\tvar op string\n\t\tif p.r.typ == itemStar {\n\t\t\top = \"*\"\n\t\t} else if testOp(p.r, \"div\") || testOp(p.r, \"mod\") {\n\t\t\top = p.r.name\n\t\t} else {\n\t\t\tbreak Loop\n\t\t}\n\t\tp.next()\n\t\topnd = newOperatorNode(op, opnd, p.parseUnaryExpr(n))\n\t}\n\treturn opnd\n}\n\n// UnaryExpr ::= UnionExpr | '-' UnaryExpr\nfunc (p *parser) parseUnaryExpr(n node) node {\n\tminus := false\n\t// ignore '-' sequence\n\tfor p.r.typ == itemMinus {\n\t\tp.next()\n\t\tminus = !minus\n\t}\n\topnd := p.parseUnionExpr(n)\n\tif minus {\n\t\topnd = newOperatorNode(\"*\", opnd, newOperandNode(float64(-1)))\n\t}\n\treturn opnd\n}\n\n// \tUnionExpr ::= PathExpr | UnionExpr '|' PathExpr\nfunc (p *parser) parseUnionExpr(n node) node {\n\topnd := p.parsePathExpr(n)\nLoop:\n\tfor {\n\t\tif p.r.typ != itemUnion {\n\t\t\tbreak Loop\n\t\t}\n\t\tp.next()\n\t\topnd2 := p.parsePathExpr(n)\n\t\t// Checking the node type that must be is node set type?\n\t\topnd = newOperatorNode(\"|\", opnd, opnd2)\n\t}\n\treturn opnd\n}\n\n// PathExpr ::= LocationPath | FilterExpr | FilterExpr '/' RelativeLocationPath\t| FilterExpr '//' RelativeLocationPath\nfunc (p *parser) parsePathExpr(n node) node {\n\tvar opnd node\n\tif isPrimaryExpr(p.r) {\n\t\topnd = p.parseFilterExpr(n)\n\t\tswitch p.r.typ {\n\t\tcase itemSlash:\n\t\t\tp.next()\n\t\t\topnd = p.parseRelativeLocationPath(opnd)\n\t\tcase itemSlashSlash:\n\t\t\tp.next()\n\t\t\topnd = p.parseRelativeLocationPath(newAxisNode(\"descendant-or-self\", \"\", \"\", \"\", opnd))\n\t\t}\n\t} else {\n\t\topnd = p.parseLocationPath(nil)\n\t}\n\treturn opnd\n}\n\n// FilterExpr ::= PrimaryExpr | FilterExpr Predicate\nfunc (p *parser) parseFilterExpr(n node) node {\n\topnd := p.parsePrimaryExpr(n)\n\tif p.r.typ == itemLBracket {\n\t\topnd = newFilterNode(opnd, p.parsePredicate(opnd))\n\t}\n\treturn opnd\n}\n\n// \tPredicate ::=  '[' PredicateExpr ']'\nfunc (p *parser) parsePredicate(n node) node {\n\tp.skipItem(itemLBracket)\n\topnd := p.parseExpression(n)\n\tp.skipItem(itemRBracket)\n\treturn opnd\n}\n\n// LocationPath ::= RelativeLocationPath | AbsoluteLocationPath\nfunc (p *parser) parseLocationPath(n node) (opnd node) {\n\tswitch p.r.typ {\n\tcase itemSlash:\n\t\tp.next()\n\t\topnd = newRootNode(\"/\")\n\t\tif isStep(p.r.typ) {\n\t\t\topnd = p.parseRelativeLocationPath(opnd) // ?? child:: or self ??\n\t\t}\n\tcase itemSlashSlash:\n\t\tp.next()\n\t\topnd = newRootNode(\"//\")\n\t\topnd = p.parseRelativeLocationPath(newAxisNode(\"descendant-or-self\", \"\", \"\", \"\", opnd))\n\tdefault:\n\t\topnd = p.parseRelativeLocationPath(n)\n\t}\n\treturn opnd\n}\n\n// RelativeLocationPath\t ::= Step | RelativeLocationPath '/' Step | AbbreviatedRelativeLocationPath\nfunc (p *parser) parseRelativeLocationPath(n node) node {\n\topnd := n\nLoop:\n\tfor {\n\t\topnd = p.parseStep(opnd)\n\t\tswitch p.r.typ {\n\t\tcase itemSlashSlash:\n\t\t\tp.next()\n\t\t\topnd = newAxisNode(\"descendant-or-self\", \"\", \"\", \"\", opnd)\n\t\tcase itemSlash:\n\t\t\tp.next()\n\t\tdefault:\n\t\t\tbreak Loop\n\t\t}\n\t}\n\treturn opnd\n}\n\n// Step\t::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep\nfunc (p *parser) parseStep(n node) (opnd node) {\n\taxeTyp := \"child\" // default axes value.\n\tif p.r.typ == itemDot || p.r.typ == itemDotDot {\n\t\tif p.r.typ == itemDot {\n\t\t\taxeTyp = \"self\"\n\t\t} else {\n\t\t\taxeTyp = \"parent\"\n\t\t}\n\t\tp.next()\n\t\topnd = newAxisNode(axeTyp, \"\", \"\", \"\", n)\n\t\tif p.r.typ != itemLBracket {\n\t\t\treturn opnd\n\t\t}\n\t} else {\n\t\tswitch p.r.typ {\n\t\tcase itemAt:\n\t\t\tp.next()\n\t\t\taxeTyp = \"attribute\"\n\t\tcase itemAxe:\n\t\t\taxeTyp = p.r.name\n\t\t\tp.next()\n\t\tcase itemLParens:\n\t\t\treturn p.parseSequence(n)\n\t\t}\n\t\topnd = p.parseNodeTest(n, axeTyp)\n\t}\n\tfor p.r.typ == itemLBracket {\n\t\topnd = newFilterNode(opnd, p.parsePredicate(opnd))\n\t}\n\treturn opnd\n}\n\n// Expr ::= '(' Step (\",\" Step)* ')'\nfunc (p *parser) parseSequence(n node) (opnd node) {\n\tp.skipItem(itemLParens)\n\topnd = p.parseStep(n)\n\tfor {\n\t\tif p.r.typ != itemComma {\n\t\t\tbreak\n\t\t}\n\t\tp.next()\n\t\topnd2 := p.parseStep(n)\n\t\topnd = newOperatorNode(\"|\", opnd, opnd2)\n\t}\n\tp.skipItem(itemRParens)\n\treturn opnd\n}\n\n// \tNodeTest ::= NameTest | nodeType '(' ')' | 'processing-instruction' '(' Literal ')'\nfunc (p *parser) parseNodeTest(n node, axeTyp string) (opnd node) {\n\tswitch p.r.typ {\n\tcase itemName:\n\t\tif p.r.canBeFunc && isNodeType(p.r) {\n\t\t\tvar prop string\n\t\t\tswitch p.r.name {\n\t\t\tcase \"comment\", \"text\", \"processing-instruction\", \"node\":\n\t\t\t\tprop = p.r.name\n\t\t\t}\n\t\t\tvar name string\n\t\t\tp.next()\n\t\t\tp.skipItem(itemLParens)\n\t\t\tif prop == \"processing-instruction\" && p.r.typ != itemRParens {\n\t\t\t\tcheckItem(p.r, itemString)\n\t\t\t\tname = p.r.strval\n\t\t\t\tp.next()\n\t\t\t}\n\t\t\tp.skipItem(itemRParens)\n\t\t\topnd = newAxisNode(axeTyp, name, \"\", prop, n)\n\t\t} else {\n\t\t\tprefix := p.r.prefix\n\t\t\tname := p.r.name\n\t\t\tp.next()\n\t\t\tif p.r.name == \"*\" {\n\t\t\t\tname = \"\"\n\t\t\t}\n\t\t\topnd = newAxisNode(axeTyp, name, prefix, \"\", n, func(a *axisNode) {\n\t\t\t\tif prefix != \"\" && p.namespaces != nil {\n\t\t\t\t\tif ns, ok := p.namespaces[prefix]; ok {\n\t\t\t\t\t\ta.hasNamespaceURI = true\n\t\t\t\t\t\ta.namespaceURI = ns\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpanic(fmt.Sprintf(\"prefix %s not defined.\", prefix))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\tcase itemStar:\n\t\topnd = newAxisNode(axeTyp, \"\", \"\", \"\", n)\n\t\tp.next()\n\tdefault:\n\t\tpanic(\"expression must evaluate to a node-set\")\n\t}\n\treturn opnd\n}\n\n// PrimaryExpr ::= VariableReference | '(' Expr ')'\t| Literal | Number | FunctionCall\nfunc (p *parser) parsePrimaryExpr(n node) (opnd node) {\n\tswitch p.r.typ {\n\tcase itemString:\n\t\topnd = newOperandNode(p.r.strval)\n\t\tp.next()\n\tcase itemNumber:\n\t\topnd = newOperandNode(p.r.numval)\n\t\tp.next()\n\tcase itemDollar:\n\t\tp.next()\n\t\tcheckItem(p.r, itemName)\n\t\topnd = newVariableNode(p.r.prefix, p.r.name)\n\t\tp.next()\n\tcase itemLParens:\n\t\tp.next()\n\t\topnd = p.parseExpression(n)\n\t\tif opnd.Type() != nodeConstantOperand {\n\t\t\topnd = newGroupNode(opnd)\n\t\t}\n\t\tp.skipItem(itemRParens)\n\tcase itemName:\n\t\tif p.r.canBeFunc && !isNodeType(p.r) {\n\t\t\topnd = p.parseMethod(nil)\n\t\t}\n\t}\n\treturn opnd\n}\n\n// FunctionCall\t ::=  FunctionName '(' ( Argument ( ',' Argument )* )? ')'\nfunc (p *parser) parseMethod(n node) node {\n\tvar args []node\n\tname := p.r.name\n\tprefix := p.r.prefix\n\n\tp.skipItem(itemName)\n\tp.skipItem(itemLParens)\n\tif p.r.typ != itemRParens {\n\t\tfor {\n\t\t\targs = append(args, p.parseExpression(n))\n\t\t\tif p.r.typ == itemRParens {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.skipItem(itemComma)\n\t\t}\n\t}\n\tp.skipItem(itemRParens)\n\treturn newFunctionNode(name, prefix, args)\n}\n\n// Parse parsing the XPath express string expr and returns a tree node.\nfunc parse(expr string, namespaces map[string]string) node {\n\tr := &scanner{text: expr}\n\tr.nextChar()\n\tr.nextItem()\n\tp := &parser{r: r, namespaces: namespaces}\n\treturn p.parseExpression(nil)\n}\n\n// rootNode holds a top-level node of tree.\ntype rootNode struct {\n\tnodeType\n\tslash string\n}\n\nfunc (r *rootNode) String() string {\n\treturn r.slash\n}\n\n// operatorNode holds two Nodes operator.\ntype operatorNode struct {\n\tnodeType\n\tOp          string\n\tLeft, Right node\n}\n\nfunc (o *operatorNode) String() string {\n\treturn fmt.Sprintf(\"%v%s%v\", o.Left, o.Op, o.Right)\n}\n\n// axisNode holds a location step.\ntype axisNode struct {\n\tnodeType\n\tInput           node\n\tProp            string // node-test name.[comment|text|processing-instruction|node]\n\tAxeType         string // name of the axes.[attribute|ancestor|child|....]\n\tLocalName       string // local part name of node.\n\tPrefix          string // prefix name of node.\n\tnamespaceURI    string // namespace URI of node\n\thasNamespaceURI bool   // if namespace URI is set (can be \"\")\n}\n\nfunc (a *axisNode) String() string {\n\tvar b bytes.Buffer\n\tif a.AxeType != \"\" {\n\t\tb.Write([]byte(a.AxeType + \"::\"))\n\t}\n\tif a.Prefix != \"\" {\n\t\tb.Write([]byte(a.Prefix + \":\"))\n\t}\n\tb.Write([]byte(a.LocalName))\n\tif a.Prop != \"\" {\n\t\tb.Write([]byte(\"/\" + a.Prop + \"()\"))\n\t}\n\treturn b.String()\n}\n\n// operandNode holds a constant operand.\ntype operandNode struct {\n\tnodeType\n\tVal interface{}\n}\n\nfunc (o *operandNode) String() string {\n\treturn fmt.Sprintf(\"%v\", o.Val)\n}\n\n// groupNode holds a set of node expression\ntype groupNode struct {\n\tnodeType\n\tInput node\n}\n\nfunc (g *groupNode) String() string {\n\treturn fmt.Sprintf(\"%s\", g.Input)\n}\n\n// filterNode holds a condition filter.\ntype filterNode struct {\n\tnodeType\n\tInput, Condition node\n}\n\nfunc (f *filterNode) String() string {\n\treturn fmt.Sprintf(\"%s[%s]\", f.Input, f.Condition)\n}\n\n// variableNode holds a variable.\ntype variableNode struct {\n\tnodeType\n\tName, Prefix string\n}\n\nfunc (v *variableNode) String() string {\n\tif v.Prefix == \"\" {\n\t\treturn v.Name\n\t}\n\treturn fmt.Sprintf(\"%s:%s\", v.Prefix, v.Name)\n}\n\n// functionNode holds a function call.\ntype functionNode struct {\n\tnodeType\n\tArgs     []node\n\tPrefix   string\n\tFuncName string // function name\n}\n\nfunc (f *functionNode) String() string {\n\tvar b bytes.Buffer\n\t// fun(arg1, ..., argn)\n\tb.Write([]byte(f.FuncName))\n\tb.Write([]byte(\"(\"))\n\tfor i, arg := range f.Args {\n\t\tif i > 0 {\n\t\t\tb.Write([]byte(\",\"))\n\t\t}\n\t\tb.Write([]byte(fmt.Sprintf(\"%s\", arg)))\n\t}\n\tb.Write([]byte(\")\"))\n\treturn b.String()\n}\n\ntype scanner struct {\n\ttext, name, prefix string\n\n\tpos       int\n\tcurr      rune\n\ttyp       itemType\n\tstrval    string  // text value at current pos\n\tnumval    float64 // number value at current pos\n\tcanBeFunc bool\n}\n\nfunc (s *scanner) nextChar() bool {\n\tif s.pos >= len(s.text) {\n\t\ts.curr = rune(0)\n\t\treturn false\n\t}\n\ts.curr = rune(s.text[s.pos])\n\ts.pos++\n\treturn true\n}\n\nfunc (s *scanner) nextItem() bool {\n\ts.skipSpace()\n\tswitch s.curr {\n\tcase 0:\n\t\ts.typ = itemEOF\n\t\treturn false\n\tcase ',', '@', '(', ')', '|', '*', '[', ']', '+', '-', '=', '#', '$':\n\t\ts.typ = asItemType(s.curr)\n\t\ts.nextChar()\n\tcase '<':\n\t\ts.typ = itemLt\n\t\ts.nextChar()\n\t\tif s.curr == '=' {\n\t\t\ts.typ = itemLe\n\t\t\ts.nextChar()\n\t\t}\n\tcase '>':\n\t\ts.typ = itemGt\n\t\ts.nextChar()\n\t\tif s.curr == '=' {\n\t\t\ts.typ = itemGe\n\t\t\ts.nextChar()\n\t\t}\n\tcase '!':\n\t\ts.typ = itemBang\n\t\ts.nextChar()\n\t\tif s.curr == '=' {\n\t\t\ts.typ = itemNe\n\t\t\ts.nextChar()\n\t\t}\n\tcase '.':\n\t\ts.typ = itemDot\n\t\ts.nextChar()\n\t\tif s.curr == '.' {\n\t\t\ts.typ = itemDotDot\n\t\t\ts.nextChar()\n\t\t} else if isDigit(s.curr) {\n\t\t\ts.typ = itemNumber\n\t\t\ts.numval = s.scanFraction()\n\t\t}\n\tcase '/':\n\t\ts.typ = itemSlash\n\t\ts.nextChar()\n\t\tif s.curr == '/' {\n\t\t\ts.typ = itemSlashSlash\n\t\t\ts.nextChar()\n\t\t}\n\tcase '\"', '\\'':\n\t\ts.typ = itemString\n\t\ts.strval = s.scanString()\n\tdefault:\n\t\tif isDigit(s.curr) {\n\t\t\ts.typ = itemNumber\n\t\t\ts.numval = s.scanNumber()\n\t\t} else if isName(s.curr) {\n\t\t\ts.typ = itemName\n\t\t\ts.name = s.scanName()\n\t\t\ts.prefix = \"\"\n\t\t\t// \"foo:bar\" is one itemem not three because it doesn't allow spaces in between\n\t\t\t// We should distinct it from \"foo::\" and need process \"foo ::\" as well\n\t\t\tif s.curr == ':' {\n\t\t\t\ts.nextChar()\n\t\t\t\t// can be \"foo:bar\" or \"foo::\"\n\t\t\t\tif s.curr == ':' {\n\t\t\t\t\t// \"foo::\"\n\t\t\t\t\ts.nextChar()\n\t\t\t\t\ts.typ = itemAxe\n\t\t\t\t} else { // \"foo:*\", \"foo:bar\" or \"foo: \"\n\t\t\t\t\ts.prefix = s.name\n\t\t\t\t\tif s.curr == '*' {\n\t\t\t\t\t\ts.nextChar()\n\t\t\t\t\t\ts.name = \"*\"\n\t\t\t\t\t} else if isName(s.curr) {\n\t\t\t\t\t\ts.name = s.scanName()\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpanic(fmt.Sprintf(\"%s has an invalid qualified name.\", s.text))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ts.skipSpace()\n\t\t\t\tif s.curr == ':' {\n\t\t\t\t\ts.nextChar()\n\t\t\t\t\t// it can be \"foo ::\" or just \"foo :\"\n\t\t\t\t\tif s.curr == ':' {\n\t\t\t\t\t\ts.nextChar()\n\t\t\t\t\t\ts.typ = itemAxe\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpanic(fmt.Sprintf(\"%s has an invalid qualified name.\", s.text))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\ts.skipSpace()\n\t\t\ts.canBeFunc = s.curr == '('\n\t\t} else {\n\t\t\tpanic(fmt.Sprintf(\"%s has an invalid token.\", s.text))\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (s *scanner) skipSpace() {\nLoop:\n\tfor {\n\t\tif !unicode.IsSpace(s.curr) || !s.nextChar() {\n\t\t\tbreak Loop\n\t\t}\n\t}\n}\n\nfunc (s *scanner) scanFraction() float64 {\n\tvar (\n\t\ti = s.pos - 2\n\t\tc = 1 // '.'\n\t)\n\tfor isDigit(s.curr) {\n\t\ts.nextChar()\n\t\tc++\n\t}\n\tv, err := strconv.ParseFloat(s.text[i:i+c], 64)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"xpath: scanFraction parse float got error: %v\", err))\n\t}\n\treturn v\n}\n\nfunc (s *scanner) scanNumber() float64 {\n\tvar (\n\t\tc int\n\t\ti = s.pos - 1\n\t)\n\tfor isDigit(s.curr) {\n\t\ts.nextChar()\n\t\tc++\n\t}\n\tif s.curr == '.' {\n\t\ts.nextChar()\n\t\tc++\n\t\tfor isDigit(s.curr) {\n\t\t\ts.nextChar()\n\t\t\tc++\n\t\t}\n\t}\n\tv, err := strconv.ParseFloat(s.text[i:i+c], 64)\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"xpath: scanNumber parse float got error: %v\", err))\n\t}\n\treturn v\n}\n\nfunc (s *scanner) scanString() string {\n\tvar (\n\t\tc   = 0\n\t\tend = s.curr\n\t)\n\ts.nextChar()\n\ti := s.pos - 1\n\tfor s.curr != end {\n\t\tif !s.nextChar() {\n\t\t\tpanic(errors.New(\"xpath: scanString got unclosed string\"))\n\t\t}\n\t\tc++\n\t}\n\ts.nextChar()\n\treturn s.text[i : i+c]\n}\n\nfunc (s *scanner) scanName() string {\n\tvar (\n\t\tc int\n\t\ti = s.pos - 1\n\t)\n\tfor isName(s.curr) {\n\t\tc++\n\t\tif !s.nextChar() {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s.text[i : i+c]\n}\n\nfunc isName(r rune) bool {\n\treturn string(r) != \":\" && string(r) != \"/\" &&\n\t\t(unicode.Is(first, r) || unicode.Is(second, r) || string(r) == \"*\")\n}\n\nfunc isDigit(r rune) bool {\n\treturn unicode.IsDigit(r)\n}\n\nfunc asItemType(r rune) itemType {\n\tswitch r {\n\tcase ',':\n\t\treturn itemComma\n\tcase '@':\n\t\treturn itemAt\n\tcase '(':\n\t\treturn itemLParens\n\tcase ')':\n\t\treturn itemRParens\n\tcase '|':\n\t\treturn itemUnion\n\tcase '*':\n\t\treturn itemStar\n\tcase '[':\n\t\treturn itemLBracket\n\tcase ']':\n\t\treturn itemRBracket\n\tcase '+':\n\t\treturn itemPlus\n\tcase '-':\n\t\treturn itemMinus\n\tcase '=':\n\t\treturn itemEq\n\tcase '$':\n\t\treturn itemDollar\n\t}\n\tpanic(fmt.Errorf(\"unknown item: %v\", r))\n}\n\nvar first = &unicode.RangeTable{\n\tR16: []unicode.Range16{\n\t\t{0x003A, 0x003A, 1},\n\t\t{0x0041, 0x005A, 1},\n\t\t{0x005F, 0x005F, 1},\n\t\t{0x0061, 0x007A, 1},\n\t\t{0x00C0, 0x00D6, 1},\n\t\t{0x00D8, 0x00F6, 1},\n\t\t{0x00F8, 0x00FF, 1},\n\t\t{0x0100, 0x0131, 1},\n\t\t{0x0134, 0x013E, 1},\n\t\t{0x0141, 0x0148, 1},\n\t\t{0x014A, 0x017E, 1},\n\t\t{0x0180, 0x01C3, 1},\n\t\t{0x01CD, 0x01F0, 1},\n\t\t{0x01F4, 0x01F5, 1},\n\t\t{0x01FA, 0x0217, 1},\n\t\t{0x0250, 0x02A8, 1},\n\t\t{0x02BB, 0x02C1, 1},\n\t\t{0x0386, 0x0386, 1},\n\t\t{0x0388, 0x038A, 1},\n\t\t{0x038C, 0x038C, 1},\n\t\t{0x038E, 0x03A1, 1},\n\t\t{0x03A3, 0x03CE, 1},\n\t\t{0x03D0, 0x03D6, 1},\n\t\t{0x03DA, 0x03E0, 2},\n\t\t{0x03E2, 0x03F3, 1},\n\t\t{0x0401, 0x040C, 1},\n\t\t{0x040E, 0x044F, 1},\n\t\t{0x0451, 0x045C, 1},\n\t\t{0x045E, 0x0481, 1},\n\t\t{0x0490, 0x04C4, 1},\n\t\t{0x04C7, 0x04C8, 1},\n\t\t{0x04CB, 0x04CC, 1},\n\t\t{0x04D0, 0x04EB, 1},\n\t\t{0x04EE, 0x04F5, 1},\n\t\t{0x04F8, 0x04F9, 1},\n\t\t{0x0531, 0x0556, 1},\n\t\t{0x0559, 0x0559, 1},\n\t\t{0x0561, 0x0586, 1},\n\t\t{0x05D0, 0x05EA, 1},\n\t\t{0x05F0, 0x05F2, 1},\n\t\t{0x0621, 0x063A, 1},\n\t\t{0x0641, 0x064A, 1},\n\t\t{0x0671, 0x06B7, 1},\n\t\t{0x06BA, 0x06BE, 1},\n\t\t{0x06C0, 0x06CE, 1},\n\t\t{0x06D0, 0x06D3, 1},\n\t\t{0x06D5, 0x06D5, 1},\n\t\t{0x06E5, 0x06E6, 1},\n\t\t{0x0905, 0x0939, 1},\n\t\t{0x093D, 0x093D, 1},\n\t\t{0x0958, 0x0961, 1},\n\t\t{0x0985, 0x098C, 1},\n\t\t{0x098F, 0x0990, 1},\n\t\t{0x0993, 0x09A8, 1},\n\t\t{0x09AA, 0x09B0, 1},\n\t\t{0x09B2, 0x09B2, 1},\n\t\t{0x09B6, 0x09B9, 1},\n\t\t{0x09DC, 0x09DD, 1},\n\t\t{0x09DF, 0x09E1, 1},\n\t\t{0x09F0, 0x09F1, 1},\n\t\t{0x0A05, 0x0A0A, 1},\n\t\t{0x0A0F, 0x0A10, 1},\n\t\t{0x0A13, 0x0A28, 1},\n\t\t{0x0A2A, 0x0A30, 1},\n\t\t{0x0A32, 0x0A33, 1},\n\t\t{0x0A35, 0x0A36, 1},\n\t\t{0x0A38, 0x0A39, 1},\n\t\t{0x0A59, 0x0A5C, 1},\n\t\t{0x0A5E, 0x0A5E, 1},\n\t\t{0x0A72, 0x0A74, 1},\n\t\t{0x0A85, 0x0A8B, 1},\n\t\t{0x0A8D, 0x0A8D, 1},\n\t\t{0x0A8F, 0x0A91, 1},\n\t\t{0x0A93, 0x0AA8, 1},\n\t\t{0x0AAA, 0x0AB0, 1},\n\t\t{0x0AB2, 0x0AB3, 1},\n\t\t{0x0AB5, 0x0AB9, 1},\n\t\t{0x0ABD, 0x0AE0, 0x23},\n\t\t{0x0B05, 0x0B0C, 1},\n\t\t{0x0B0F, 0x0B10, 1},\n\t\t{0x0B13, 0x0B28, 1},\n\t\t{0x0B2A, 0x0B30, 1},\n\t\t{0x0B32, 0x0B33, 1},\n\t\t{0x0B36, 0x0B39, 1},\n\t\t{0x0B3D, 0x0B3D, 1},\n\t\t{0x0B5C, 0x0B5D, 1},\n\t\t{0x0B5F, 0x0B61, 1},\n\t\t{0x0B85, 0x0B8A, 1},\n\t\t{0x0B8E, 0x0B90, 1},\n\t\t{0x0B92, 0x0B95, 1},\n\t\t{0x0B99, 0x0B9A, 1},\n\t\t{0x0B9C, 0x0B9C, 1},\n\t\t{0x0B9E, 0x0B9F, 1},\n\t\t{0x0BA3, 0x0BA4, 1},\n\t\t{0x0BA8, 0x0BAA, 1},\n\t\t{0x0BAE, 0x0BB5, 1},\n\t\t{0x0BB7, 0x0BB9, 1},\n\t\t{0x0C05, 0x0C0C, 1},\n\t\t{0x0C0E, 0x0C10, 1},\n\t\t{0x0C12, 0x0C28, 1},\n\t\t{0x0C2A, 0x0C33, 1},\n\t\t{0x0C35, 0x0C39, 1},\n\t\t{0x0C60, 0x0C61, 1},\n\t\t{0x0C85, 0x0C8C, 1},\n\t\t{0x0C8E, 0x0C90, 1},\n\t\t{0x0C92, 0x0CA8, 1},\n\t\t{0x0CAA, 0x0CB3, 1},\n\t\t{0x0CB5, 0x0CB9, 1},\n\t\t{0x0CDE, 0x0CDE, 1},\n\t\t{0x0CE0, 0x0CE1, 1},\n\t\t{0x0D05, 0x0D0C, 1},\n\t\t{0x0D0E, 0x0D10, 1},\n\t\t{0x0D12, 0x0D28, 1},\n\t\t{0x0D2A, 0x0D39, 1},\n\t\t{0x0D60, 0x0D61, 1},\n\t\t{0x0E01, 0x0E2E, 1},\n\t\t{0x0E30, 0x0E30, 1},\n\t\t{0x0E32, 0x0E33, 1},\n\t\t{0x0E40, 0x0E45, 1},\n\t\t{0x0E81, 0x0E82, 1},\n\t\t{0x0E84, 0x0E84, 1},\n\t\t{0x0E87, 0x0E88, 1},\n\t\t{0x0E8A, 0x0E8D, 3},\n\t\t{0x0E94, 0x0E97, 1},\n\t\t{0x0E99, 0x0E9F, 1},\n\t\t{0x0EA1, 0x0EA3, 1},\n\t\t{0x0EA5, 0x0EA7, 2},\n\t\t{0x0EAA, 0x0EAB, 1},\n\t\t{0x0EAD, 0x0EAE, 1},\n\t\t{0x0EB0, 0x0EB0, 1},\n\t\t{0x0EB2, 0x0EB3, 1},\n\t\t{0x0EBD, 0x0EBD, 1},\n\t\t{0x0EC0, 0x0EC4, 1},\n\t\t{0x0F40, 0x0F47, 1},\n\t\t{0x0F49, 0x0F69, 1},\n\t\t{0x10A0, 0x10C5, 1},\n\t\t{0x10D0, 0x10F6, 1},\n\t\t{0x1100, 0x1100, 1},\n\t\t{0x1102, 0x1103, 1},\n\t\t{0x1105, 0x1107, 1},\n\t\t{0x1109, 0x1109, 1},\n\t\t{0x110B, 0x110C, 1},\n\t\t{0x110E, 0x1112, 1},\n\t\t{0x113C, 0x1140, 2},\n\t\t{0x114C, 0x1150, 2},\n\t\t{0x1154, 0x1155, 1},\n\t\t{0x1159, 0x1159, 1},\n\t\t{0x115F, 0x1161, 1},\n\t\t{0x1163, 0x1169, 2},\n\t\t{0x116D, 0x116E, 1},\n\t\t{0x1172, 0x1173, 1},\n\t\t{0x1175, 0x119E, 0x119E - 0x1175},\n\t\t{0x11A8, 0x11AB, 0x11AB - 0x11A8},\n\t\t{0x11AE, 0x11AF, 1},\n\t\t{0x11B7, 0x11B8, 1},\n\t\t{0x11BA, 0x11BA, 1},\n\t\t{0x11BC, 0x11C2, 1},\n\t\t{0x11EB, 0x11F0, 0x11F0 - 0x11EB},\n\t\t{0x11F9, 0x11F9, 1},\n\t\t{0x1E00, 0x1E9B, 1},\n\t\t{0x1EA0, 0x1EF9, 1},\n\t\t{0x1F00, 0x1F15, 1},\n\t\t{0x1F18, 0x1F1D, 1},\n\t\t{0x1F20, 0x1F45, 1},\n\t\t{0x1F48, 0x1F4D, 1},\n\t\t{0x1F50, 0x1F57, 1},\n\t\t{0x1F59, 0x1F5B, 0x1F5B - 0x1F59},\n\t\t{0x1F5D, 0x1F5D, 1},\n\t\t{0x1F5F, 0x1F7D, 1},\n\t\t{0x1F80, 0x1FB4, 1},\n\t\t{0x1FB6, 0x1FBC, 1},\n\t\t{0x1FBE, 0x1FBE, 1},\n\t\t{0x1FC2, 0x1FC4, 1},\n\t\t{0x1FC6, 0x1FCC, 1},\n\t\t{0x1FD0, 0x1FD3, 1},\n\t\t{0x1FD6, 0x1FDB, 1},\n\t\t{0x1FE0, 0x1FEC, 1},\n\t\t{0x1FF2, 0x1FF4, 1},\n\t\t{0x1FF6, 0x1FFC, 1},\n\t\t{0x2126, 0x2126, 1},\n\t\t{0x212A, 0x212B, 1},\n\t\t{0x212E, 0x212E, 1},\n\t\t{0x2180, 0x2182, 1},\n\t\t{0x3007, 0x3007, 1},\n\t\t{0x3021, 0x3029, 1},\n\t\t{0x3041, 0x3094, 1},\n\t\t{0x30A1, 0x30FA, 1},\n\t\t{0x3105, 0x312C, 1},\n\t\t{0x4E00, 0x9FA5, 1},\n\t\t{0xAC00, 0xD7A3, 1},\n\t},\n}\n\nvar second = &unicode.RangeTable{\n\tR16: []unicode.Range16{\n\t\t{0x002D, 0x002E, 1},\n\t\t{0x0030, 0x0039, 1},\n\t\t{0x00B7, 0x00B7, 1},\n\t\t{0x02D0, 0x02D1, 1},\n\t\t{0x0300, 0x0345, 1},\n\t\t{0x0360, 0x0361, 1},\n\t\t{0x0387, 0x0387, 1},\n\t\t{0x0483, 0x0486, 1},\n\t\t{0x0591, 0x05A1, 1},\n\t\t{0x05A3, 0x05B9, 1},\n\t\t{0x05BB, 0x05BD, 1},\n\t\t{0x05BF, 0x05BF, 1},\n\t\t{0x05C1, 0x05C2, 1},\n\t\t{0x05C4, 0x0640, 0x0640 - 0x05C4},\n\t\t{0x064B, 0x0652, 1},\n\t\t{0x0660, 0x0669, 1},\n\t\t{0x0670, 0x0670, 1},\n\t\t{0x06D6, 0x06DC, 1},\n\t\t{0x06DD, 0x06DF, 1},\n\t\t{0x06E0, 0x06E4, 1},\n\t\t{0x06E7, 0x06E8, 1},\n\t\t{0x06EA, 0x06ED, 1},\n\t\t{0x06F0, 0x06F9, 1},\n\t\t{0x0901, 0x0903, 1},\n\t\t{0x093C, 0x093C, 1},\n\t\t{0x093E, 0x094C, 1},\n\t\t{0x094D, 0x094D, 1},\n\t\t{0x0951, 0x0954, 1},\n\t\t{0x0962, 0x0963, 1},\n\t\t{0x0966, 0x096F, 1},\n\t\t{0x0981, 0x0983, 1},\n\t\t{0x09BC, 0x09BC, 1},\n\t\t{0x09BE, 0x09BF, 1},\n\t\t{0x09C0, 0x09C4, 1},\n\t\t{0x09C7, 0x09C8, 1},\n\t\t{0x09CB, 0x09CD, 1},\n\t\t{0x09D7, 0x09D7, 1},\n\t\t{0x09E2, 0x09E3, 1},\n\t\t{0x09E6, 0x09EF, 1},\n\t\t{0x0A02, 0x0A3C, 0x3A},\n\t\t{0x0A3E, 0x0A3F, 1},\n\t\t{0x0A40, 0x0A42, 1},\n\t\t{0x0A47, 0x0A48, 1},\n\t\t{0x0A4B, 0x0A4D, 1},\n\t\t{0x0A66, 0x0A6F, 1},\n\t\t{0x0A70, 0x0A71, 1},\n\t\t{0x0A81, 0x0A83, 1},\n\t\t{0x0ABC, 0x0ABC, 1},\n\t\t{0x0ABE, 0x0AC5, 1},\n\t\t{0x0AC7, 0x0AC9, 1},\n\t\t{0x0ACB, 0x0ACD, 1},\n\t\t{0x0AE6, 0x0AEF, 1},\n\t\t{0x0B01, 0x0B03, 1},\n\t\t{0x0B3C, 0x0B3C, 1},\n\t\t{0x0B3E, 0x0B43, 1},\n\t\t{0x0B47, 0x0B48, 1},\n\t\t{0x0B4B, 0x0B4D, 1},\n\t\t{0x0B56, 0x0B57, 1},\n\t\t{0x0B66, 0x0B6F, 1},\n\t\t{0x0B82, 0x0B83, 1},\n\t\t{0x0BBE, 0x0BC2, 1},\n\t\t{0x0BC6, 0x0BC8, 1},\n\t\t{0x0BCA, 0x0BCD, 1},\n\t\t{0x0BD7, 0x0BD7, 1},\n\t\t{0x0BE7, 0x0BEF, 1},\n\t\t{0x0C01, 0x0C03, 1},\n\t\t{0x0C3E, 0x0C44, 1},\n\t\t{0x0C46, 0x0C48, 1},\n\t\t{0x0C4A, 0x0C4D, 1},\n\t\t{0x0C55, 0x0C56, 1},\n\t\t{0x0C66, 0x0C6F, 1},\n\t\t{0x0C82, 0x0C83, 1},\n\t\t{0x0CBE, 0x0CC4, 1},\n\t\t{0x0CC6, 0x0CC8, 1},\n\t\t{0x0CCA, 0x0CCD, 1},\n\t\t{0x0CD5, 0x0CD6, 1},\n\t\t{0x0CE6, 0x0CEF, 1},\n\t\t{0x0D02, 0x0D03, 1},\n\t\t{0x0D3E, 0x0D43, 1},\n\t\t{0x0D46, 0x0D48, 1},\n\t\t{0x0D4A, 0x0D4D, 1},\n\t\t{0x0D57, 0x0D57, 1},\n\t\t{0x0D66, 0x0D6F, 1},\n\t\t{0x0E31, 0x0E31, 1},\n\t\t{0x0E34, 0x0E3A, 1},\n\t\t{0x0E46, 0x0E46, 1},\n\t\t{0x0E47, 0x0E4E, 1},\n\t\t{0x0E50, 0x0E59, 1},\n\t\t{0x0EB1, 0x0EB1, 1},\n\t\t{0x0EB4, 0x0EB9, 1},\n\t\t{0x0EBB, 0x0EBC, 1},\n\t\t{0x0EC6, 0x0EC6, 1},\n\t\t{0x0EC8, 0x0ECD, 1},\n\t\t{0x0ED0, 0x0ED9, 1},\n\t\t{0x0F18, 0x0F19, 1},\n\t\t{0x0F20, 0x0F29, 1},\n\t\t{0x0F35, 0x0F39, 2},\n\t\t{0x0F3E, 0x0F3F, 1},\n\t\t{0x0F71, 0x0F84, 1},\n\t\t{0x0F86, 0x0F8B, 1},\n\t\t{0x0F90, 0x0F95, 1},\n\t\t{0x0F97, 0x0F97, 1},\n\t\t{0x0F99, 0x0FAD, 1},\n\t\t{0x0FB1, 0x0FB7, 1},\n\t\t{0x0FB9, 0x0FB9, 1},\n\t\t{0x20D0, 0x20DC, 1},\n\t\t{0x20E1, 0x3005, 0x3005 - 0x20E1},\n\t\t{0x302A, 0x302F, 1},\n\t\t{0x3031, 0x3035, 1},\n\t\t{0x3099, 0x309A, 1},\n\t\t{0x309D, 0x309E, 1},\n\t\t{0x30FC, 0x30FE, 1},\n\t},\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/query.go",
    "content": "package xpath\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"hash/fnv\"\n\t\"reflect\"\n)\n\ntype iterator interface {\n\tCurrent() NodeNavigator\n}\n\n// An XPath query interface.\ntype query interface {\n\t// Select traversing iterator returns a query matched node NodeNavigator.\n\tSelect(iterator) NodeNavigator\n\n\t// Evaluate evaluates query and returns values of the current query.\n\tEvaluate(iterator) interface{}\n\n\tClone() query\n}\n\n// nopQuery is an empty query that always return nil for any query.\ntype nopQuery struct {\n\tquery\n}\n\nfunc (nopQuery) Select(iterator) NodeNavigator { return nil }\n\nfunc (nopQuery) Evaluate(iterator) interface{} { return nil }\n\nfunc (nopQuery) Clone() query { return nopQuery{} }\n\n// contextQuery is returns current node on the iterator object query.\ntype contextQuery struct {\n\tcount int\n\tRoot  bool // Moving to root-level node in the current context iterator.\n}\n\nfunc (c *contextQuery) Select(t iterator) (n NodeNavigator) {\n\tif c.count == 0 {\n\t\tc.count++\n\t\tn = t.Current().Copy()\n\t\tif c.Root {\n\t\t\tn.MoveToRoot()\n\t\t}\n\t}\n\treturn n\n}\n\nfunc (c *contextQuery) Evaluate(iterator) interface{} {\n\tc.count = 0\n\treturn c\n}\n\nfunc (c *contextQuery) Clone() query {\n\treturn &contextQuery{Root: c.Root}\n}\n\n// ancestorQuery is an XPath ancestor node query.(ancestor::*|ancestor-self::*)\ntype ancestorQuery struct {\n\titerator func() NodeNavigator\n\n\tSelf      bool\n\tInput     query\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (a *ancestorQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tif a.iterator == nil {\n\t\t\tnode := a.Input.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tfirst := true\n\t\t\tnode = node.Copy()\n\t\t\ta.iterator = func() NodeNavigator {\n\t\t\t\tif first && a.Self {\n\t\t\t\t\tfirst = false\n\t\t\t\t\tif a.Predicate(node) {\n\t\t\t\t\t\treturn node\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor node.MoveToParent() {\n\t\t\t\t\tif !a.Predicate(node) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\treturn node\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t\tif node := a.iterator(); node != nil {\n\t\t\treturn node\n\t\t}\n\t\ta.iterator = nil\n\t}\n}\n\nfunc (a *ancestorQuery) Evaluate(t iterator) interface{} {\n\ta.Input.Evaluate(t)\n\ta.iterator = nil\n\treturn a\n}\n\nfunc (a *ancestorQuery) Test(n NodeNavigator) bool {\n\treturn a.Predicate(n)\n}\n\nfunc (a *ancestorQuery) Clone() query {\n\treturn &ancestorQuery{Self: a.Self, Input: a.Input.Clone(), Predicate: a.Predicate}\n}\n\n// attributeQuery is an XPath attribute node query.(@*)\ntype attributeQuery struct {\n\titerator func() NodeNavigator\n\n\tInput     query\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (a *attributeQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tif a.iterator == nil {\n\t\t\tnode := a.Input.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tnode = node.Copy()\n\t\t\ta.iterator = func() NodeNavigator {\n\t\t\t\tfor {\n\t\t\t\t\tonAttr := node.MoveToNextAttribute()\n\t\t\t\t\tif !onAttr {\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t\tif a.Predicate(node) {\n\t\t\t\t\t\treturn node\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif node := a.iterator(); node != nil {\n\t\t\treturn node\n\t\t}\n\t\ta.iterator = nil\n\t}\n}\n\nfunc (a *attributeQuery) Evaluate(t iterator) interface{} {\n\ta.Input.Evaluate(t)\n\ta.iterator = nil\n\treturn a\n}\n\nfunc (a *attributeQuery) Test(n NodeNavigator) bool {\n\treturn a.Predicate(n)\n}\n\nfunc (a *attributeQuery) Clone() query {\n\treturn &attributeQuery{Input: a.Input.Clone(), Predicate: a.Predicate}\n}\n\n// childQuery is an XPath child node query.(child::*)\ntype childQuery struct {\n\tposit    int\n\titerator func() NodeNavigator\n\n\tInput     query\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (c *childQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tif c.iterator == nil {\n\t\t\tc.posit = 0\n\t\t\tnode := c.Input.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tnode = node.Copy()\n\t\t\tfirst := true\n\t\t\tc.iterator = func() NodeNavigator {\n\t\t\t\tfor {\n\t\t\t\t\tif (first && !node.MoveToChild()) || (!first && !node.MoveToNext()) {\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t\tfirst = false\n\t\t\t\t\tif c.Predicate(node) {\n\t\t\t\t\t\treturn node\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif node := c.iterator(); node != nil {\n\t\t\tc.posit++\n\t\t\treturn node\n\t\t}\n\t\tc.iterator = nil\n\t}\n}\n\nfunc (c *childQuery) Evaluate(t iterator) interface{} {\n\tc.Input.Evaluate(t)\n\tc.iterator = nil\n\treturn c\n}\n\nfunc (c *childQuery) Test(n NodeNavigator) bool {\n\treturn c.Predicate(n)\n}\n\nfunc (c *childQuery) Clone() query {\n\treturn &childQuery{Input: c.Input.Clone(), Predicate: c.Predicate}\n}\n\n// position returns a position of current NodeNavigator.\nfunc (c *childQuery) position() int {\n\treturn c.posit\n}\n\n// descendantQuery is an XPath descendant node query.(descendant::* | descendant-or-self::*)\ntype descendantQuery struct {\n\titerator func() NodeNavigator\n\tposit    int\n\tlevel    int\n\n\tSelf      bool\n\tInput     query\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (d *descendantQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tif d.iterator == nil {\n\t\t\td.posit = 0\n\t\t\tnode := d.Input.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tnode = node.Copy()\n\t\t\td.level = 0\n\t\t\tpositmap := make(map[int]int)\n\t\t\tfirst := true\n\t\t\td.iterator = func() NodeNavigator {\n\t\t\t\tif first && d.Self {\n\t\t\t\t\tfirst = false\n\t\t\t\t\tif d.Predicate(node) {\n\t\t\t\t\t\td.posit = 1\n\t\t\t\t\t\tpositmap[d.level] = 1\n\t\t\t\t\t\treturn node\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor {\n\t\t\t\t\tif node.MoveToChild() {\n\t\t\t\t\t\td.level = d.level + 1\n\t\t\t\t\t\tpositmap[d.level] = 0\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor {\n\t\t\t\t\t\t\tif d.level == 0 {\n\t\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif node.MoveToNext() {\n\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnode.MoveToParent()\n\t\t\t\t\t\t\td.level = d.level - 1\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif d.Predicate(node) {\n\t\t\t\t\t\tpositmap[d.level]++\n\t\t\t\t\t\td.posit = positmap[d.level]\n\t\t\t\t\t\treturn node\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif node := d.iterator(); node != nil {\n\t\t\treturn node\n\t\t}\n\t\td.iterator = nil\n\t}\n}\n\nfunc (d *descendantQuery) Evaluate(t iterator) interface{} {\n\td.Input.Evaluate(t)\n\td.iterator = nil\n\treturn d\n}\n\nfunc (d *descendantQuery) Test(n NodeNavigator) bool {\n\treturn d.Predicate(n)\n}\n\n// position returns a position of current NodeNavigator.\nfunc (d *descendantQuery) position() int {\n\treturn d.posit\n}\n\nfunc (d *descendantQuery) depth() int {\n\treturn d.level\n}\n\nfunc (d *descendantQuery) Clone() query {\n\treturn &descendantQuery{Self: d.Self, Input: d.Input.Clone(), Predicate: d.Predicate}\n}\n\n// followingQuery is an XPath following node query.(following::*|following-sibling::*)\ntype followingQuery struct {\n\tposit    int\n\titerator func() NodeNavigator\n\n\tInput     query\n\tSibling   bool // The matching sibling node of current node.\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (f *followingQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tif f.iterator == nil {\n\t\t\tf.posit = 0\n\t\t\tnode := f.Input.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tnode = node.Copy()\n\t\t\tif f.Sibling {\n\t\t\t\tf.iterator = func() NodeNavigator {\n\t\t\t\t\tfor {\n\t\t\t\t\t\tif !node.MoveToNext() {\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif f.Predicate(node) {\n\t\t\t\t\t\t\tf.posit++\n\t\t\t\t\t\t\treturn node\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvar q *descendantQuery // descendant query\n\t\t\t\tf.iterator = func() NodeNavigator {\n\t\t\t\t\tfor {\n\t\t\t\t\t\tif q == nil {\n\t\t\t\t\t\t\tfor !node.MoveToNext() {\n\t\t\t\t\t\t\t\tif !node.MoveToParent() {\n\t\t\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tq = &descendantQuery{\n\t\t\t\t\t\t\t\tSelf:      true,\n\t\t\t\t\t\t\t\tInput:     &contextQuery{},\n\t\t\t\t\t\t\t\tPredicate: f.Predicate,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tt.Current().MoveTo(node)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif node := q.Select(t); node != nil {\n\t\t\t\t\t\t\tf.posit = q.posit\n\t\t\t\t\t\t\treturn node\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq = nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif node := f.iterator(); node != nil {\n\t\t\treturn node\n\t\t}\n\t\tf.iterator = nil\n\t}\n}\n\nfunc (f *followingQuery) Evaluate(t iterator) interface{} {\n\tf.Input.Evaluate(t)\n\treturn f\n}\n\nfunc (f *followingQuery) Test(n NodeNavigator) bool {\n\treturn f.Predicate(n)\n}\n\nfunc (f *followingQuery) Clone() query {\n\treturn &followingQuery{Input: f.Input.Clone(), Sibling: f.Sibling, Predicate: f.Predicate}\n}\n\nfunc (f *followingQuery) position() int {\n\treturn f.posit\n}\n\n// precedingQuery is an XPath preceding node query.(preceding::*)\ntype precedingQuery struct {\n\titerator  func() NodeNavigator\n\tposit     int\n\tInput     query\n\tSibling   bool // The matching sibling node of current node.\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (p *precedingQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tif p.iterator == nil {\n\t\t\tp.posit = 0\n\t\t\tnode := p.Input.Select(t)\n\t\t\tif node == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tnode = node.Copy()\n\t\t\tif p.Sibling {\n\t\t\t\tp.iterator = func() NodeNavigator {\n\t\t\t\t\tfor {\n\t\t\t\t\t\tfor !node.MoveToPrevious() {\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif p.Predicate(node) {\n\t\t\t\t\t\t\tp.posit++\n\t\t\t\t\t\t\treturn node\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvar q query\n\t\t\t\tp.iterator = func() NodeNavigator {\n\t\t\t\t\tfor {\n\t\t\t\t\t\tif q == nil {\n\t\t\t\t\t\t\tfor !node.MoveToPrevious() {\n\t\t\t\t\t\t\t\tif !node.MoveToParent() {\n\t\t\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tp.posit = 0\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tq = &descendantQuery{\n\t\t\t\t\t\t\t\tSelf:      true,\n\t\t\t\t\t\t\t\tInput:     &contextQuery{},\n\t\t\t\t\t\t\t\tPredicate: p.Predicate,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tt.Current().MoveTo(node)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif node := q.Select(t); node != nil {\n\t\t\t\t\t\t\tp.posit++\n\t\t\t\t\t\t\treturn node\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq = nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif node := p.iterator(); node != nil {\n\t\t\treturn node\n\t\t}\n\t\tp.iterator = nil\n\t}\n}\n\nfunc (p *precedingQuery) Evaluate(t iterator) interface{} {\n\tp.Input.Evaluate(t)\n\treturn p\n}\n\nfunc (p *precedingQuery) Test(n NodeNavigator) bool {\n\treturn p.Predicate(n)\n}\n\nfunc (p *precedingQuery) Clone() query {\n\treturn &precedingQuery{Input: p.Input.Clone(), Sibling: p.Sibling, Predicate: p.Predicate}\n}\n\nfunc (p *precedingQuery) position() int {\n\treturn p.posit\n}\n\n// parentQuery is an XPath parent node query.(parent::*)\ntype parentQuery struct {\n\tInput     query\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (p *parentQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tnode := p.Input.Select(t)\n\t\tif node == nil {\n\t\t\treturn nil\n\t\t}\n\t\tnode = node.Copy()\n\t\tif node.MoveToParent() && p.Predicate(node) {\n\t\t\treturn node\n\t\t}\n\t}\n}\n\nfunc (p *parentQuery) Evaluate(t iterator) interface{} {\n\tp.Input.Evaluate(t)\n\treturn p\n}\n\nfunc (p *parentQuery) Clone() query {\n\treturn &parentQuery{Input: p.Input.Clone(), Predicate: p.Predicate}\n}\n\nfunc (p *parentQuery) Test(n NodeNavigator) bool {\n\treturn p.Predicate(n)\n}\n\n// selfQuery is an Self node query.(self::*)\ntype selfQuery struct {\n\tInput     query\n\tPredicate func(NodeNavigator) bool\n}\n\nfunc (s *selfQuery) Select(t iterator) NodeNavigator {\n\tfor {\n\t\tnode := s.Input.Select(t)\n\t\tif node == nil {\n\t\t\treturn nil\n\t\t}\n\n\t\tif s.Predicate(node) {\n\t\t\treturn node\n\t\t}\n\t}\n}\n\nfunc (s *selfQuery) Evaluate(t iterator) interface{} {\n\ts.Input.Evaluate(t)\n\treturn s\n}\n\nfunc (s *selfQuery) Test(n NodeNavigator) bool {\n\treturn s.Predicate(n)\n}\n\nfunc (s *selfQuery) Clone() query {\n\treturn &selfQuery{Input: s.Input.Clone(), Predicate: s.Predicate}\n}\n\n// filterQuery is an XPath query for predicate filter.\ntype filterQuery struct {\n\tInput     query\n\tPredicate query\n\tposit     int\n\tpositmap  map[int]int\n}\n\nfunc (f *filterQuery) do(t iterator) bool {\n\tval := reflect.ValueOf(f.Predicate.Evaluate(t))\n\tswitch val.Kind() {\n\tcase reflect.Bool:\n\t\treturn val.Bool()\n\tcase reflect.String:\n\t\treturn len(val.String()) > 0\n\tcase reflect.Float64:\n\t\tpt := getNodePosition(f.Input)\n\t\treturn int(val.Float()) == pt\n\tdefault:\n\t\tif f.Predicate != nil {\n\t\t\treturn f.Predicate.Select(t) != nil\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (f *filterQuery) position() int {\n\treturn f.posit\n}\n\nfunc (f *filterQuery) Select(t iterator) NodeNavigator {\n\tif f.positmap == nil {\n\t\tf.positmap = make(map[int]int)\n\t}\n\tfor {\n\n\t\tnode := f.Input.Select(t)\n\t\tif node == nil {\n\t\t\treturn nil\n\t\t}\n\t\tnode = node.Copy()\n\n\t\tt.Current().MoveTo(node)\n\t\tif f.do(t) {\n\t\t\t// fix https://github.com/antchfx/htmlquery/issues/26\n\t\t\t// Calculate and keep the each of matching node's position in the same depth.\n\t\t\tlevel := getNodeDepth(f.Input)\n\t\t\tf.positmap[level]++\n\t\t\tf.posit = f.positmap[level]\n\t\t\treturn node\n\t\t}\n\t}\n}\n\nfunc (f *filterQuery) Evaluate(t iterator) interface{} {\n\tf.Input.Evaluate(t)\n\treturn f\n}\n\nfunc (f *filterQuery) Clone() query {\n\treturn &filterQuery{Input: f.Input.Clone(), Predicate: f.Predicate.Clone()}\n}\n\n// functionQuery is an XPath function that returns a computed value for\n// the Evaluate call of the current NodeNavigator node. Select call isn't\n// applicable for functionQuery.\ntype functionQuery struct {\n\tInput query                             // Node Set\n\tFunc  func(query, iterator) interface{} // The xpath function.\n}\n\nfunc (f *functionQuery) Select(t iterator) NodeNavigator {\n\treturn nil\n}\n\n// Evaluate call a specified function that will returns the\n// following value type: number,string,boolean.\nfunc (f *functionQuery) Evaluate(t iterator) interface{} {\n\treturn f.Func(f.Input, t)\n}\n\nfunc (f *functionQuery) Clone() query {\n\treturn &functionQuery{Input: f.Input.Clone(), Func: f.Func}\n}\n\n// transformFunctionQuery diffs from functionQuery where the latter computes a scalar\n// value (number,string,boolean) for the current NodeNavigator node while the former\n// (transformFunctionQuery) performs a mapping or transform of the current NodeNavigator\n// and returns a new NodeNavigator. It is used for non-scalar XPath functions such as\n// reverse(), remove(), subsequence(), unordered(), etc.\ntype transformFunctionQuery struct {\n\tInput    query\n\tFunc     func(query, iterator) func() NodeNavigator\n\titerator func() NodeNavigator\n}\n\nfunc (f *transformFunctionQuery) Select(t iterator) NodeNavigator {\n\tif f.iterator == nil {\n\t\tf.iterator = f.Func(f.Input, t)\n\t}\n\treturn f.iterator()\n}\n\nfunc (f *transformFunctionQuery) Evaluate(t iterator) interface{} {\n\tf.Input.Evaluate(t)\n\tf.iterator = nil\n\treturn f\n}\n\nfunc (f *transformFunctionQuery) Clone() query {\n\treturn &transformFunctionQuery{Input: f.Input.Clone(), Func: f.Func}\n}\n\n// constantQuery is an XPath constant operand.\ntype constantQuery struct {\n\tVal interface{}\n}\n\nfunc (c *constantQuery) Select(t iterator) NodeNavigator {\n\treturn nil\n}\n\nfunc (c *constantQuery) Evaluate(t iterator) interface{} {\n\treturn c.Val\n}\n\nfunc (c *constantQuery) Clone() query {\n\treturn c\n}\n\ntype groupQuery struct {\n\tposit int\n\n\tInput query\n}\n\nfunc (g *groupQuery) Select(t iterator) NodeNavigator {\n\tnode := g.Input.Select(t)\n\tif node == nil {\n\t\treturn nil\n\t}\n\tg.posit++\n\treturn node\n}\n\nfunc (g *groupQuery) Evaluate(t iterator) interface{} {\n\treturn g.Input.Evaluate(t)\n}\n\nfunc (g *groupQuery) Clone() query {\n\treturn &groupQuery{Input: g.Input.Clone()}\n}\n\nfunc (g *groupQuery) position() int {\n\treturn g.posit\n}\n\n// logicalQuery is an XPath logical expression.\ntype logicalQuery struct {\n\tLeft, Right query\n\n\tDo func(iterator, interface{}, interface{}) interface{}\n}\n\nfunc (l *logicalQuery) Select(t iterator) NodeNavigator {\n\t// When a XPath expr is logical expression.\n\tnode := t.Current().Copy()\n\tval := l.Evaluate(t)\n\tswitch val.(type) {\n\tcase bool:\n\t\tif val.(bool) == true {\n\t\t\treturn node\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (l *logicalQuery) Evaluate(t iterator) interface{} {\n\tm := l.Left.Evaluate(t)\n\tn := l.Right.Evaluate(t)\n\treturn l.Do(t, m, n)\n}\n\nfunc (l *logicalQuery) Clone() query {\n\treturn &logicalQuery{Left: l.Left.Clone(), Right: l.Right.Clone(), Do: l.Do}\n}\n\n// numericQuery is an XPath numeric operator expression.\ntype numericQuery struct {\n\tLeft, Right query\n\n\tDo func(interface{}, interface{}) interface{}\n}\n\nfunc (n *numericQuery) Select(t iterator) NodeNavigator {\n\treturn nil\n}\n\nfunc (n *numericQuery) Evaluate(t iterator) interface{} {\n\tm := n.Left.Evaluate(t)\n\tk := n.Right.Evaluate(t)\n\treturn n.Do(m, k)\n}\n\nfunc (n *numericQuery) Clone() query {\n\treturn &numericQuery{Left: n.Left.Clone(), Right: n.Right.Clone(), Do: n.Do}\n}\n\ntype booleanQuery struct {\n\tIsOr        bool\n\tLeft, Right query\n\titerator    func() NodeNavigator\n}\n\nfunc (b *booleanQuery) Select(t iterator) NodeNavigator {\n\tif b.iterator == nil {\n\t\tvar list []NodeNavigator\n\t\ti := 0\n\t\troot := t.Current().Copy()\n\t\tif b.IsOr {\n\t\t\tfor {\n\t\t\t\tnode := b.Left.Select(t)\n\t\t\t\tif node == nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnode = node.Copy()\n\t\t\t\tlist = append(list, node)\n\t\t\t}\n\t\t\tt.Current().MoveTo(root)\n\t\t\tfor {\n\t\t\t\tnode := b.Right.Select(t)\n\t\t\t\tif node == nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnode = node.Copy()\n\t\t\t\tlist = append(list, node)\n\t\t\t}\n\t\t} else {\n\t\t\tvar m []NodeNavigator\n\t\t\tvar n []NodeNavigator\n\t\t\tfor {\n\t\t\t\tnode := b.Left.Select(t)\n\t\t\t\tif node == nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnode = node.Copy()\n\t\t\t\tlist = append(m, node)\n\t\t\t}\n\t\t\tt.Current().MoveTo(root)\n\t\t\tfor {\n\t\t\t\tnode := b.Right.Select(t)\n\t\t\t\tif node == nil {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnode = node.Copy()\n\t\t\t\tlist = append(n, node)\n\t\t\t}\n\t\t\tfor _, k := range m {\n\t\t\t\tfor _, j := range n {\n\t\t\t\t\tif k == j {\n\t\t\t\t\t\tlist = append(list, k)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tb.iterator = func() NodeNavigator {\n\t\t\tif i >= len(list) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tnode := list[i]\n\t\t\ti++\n\t\t\treturn node\n\t\t}\n\t}\n\treturn b.iterator()\n}\n\nfunc (b *booleanQuery) Evaluate(t iterator) interface{} {\n\tn := t.Current().Copy()\n\n\tm := b.Left.Evaluate(t)\n\tleft := asBool(t, m)\n\tif b.IsOr && left {\n\t\treturn true\n\t} else if !b.IsOr && !left {\n\t\treturn false\n\t}\n\n\tt.Current().MoveTo(n)\n\tm = b.Right.Evaluate(t)\n\treturn asBool(t, m)\n}\n\nfunc (b *booleanQuery) Clone() query {\n\treturn &booleanQuery{IsOr: b.IsOr, Left: b.Left.Clone(), Right: b.Right.Clone()}\n}\n\ntype unionQuery struct {\n\tLeft, Right query\n\titerator    func() NodeNavigator\n}\n\nfunc (u *unionQuery) Select(t iterator) NodeNavigator {\n\tif u.iterator == nil {\n\t\tvar list []NodeNavigator\n\t\tvar m = make(map[uint64]bool)\n\t\troot := t.Current().Copy()\n\t\tfor {\n\t\t\tnode := u.Left.Select(t)\n\t\t\tif node == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcode := getHashCode(node.Copy())\n\t\t\tif _, ok := m[code]; !ok {\n\t\t\t\tm[code] = true\n\t\t\t\tlist = append(list, node.Copy())\n\t\t\t}\n\t\t}\n\t\tt.Current().MoveTo(root)\n\t\tfor {\n\t\t\tnode := u.Right.Select(t)\n\t\t\tif node == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcode := getHashCode(node.Copy())\n\t\t\tif _, ok := m[code]; !ok {\n\t\t\t\tm[code] = true\n\t\t\t\tlist = append(list, node.Copy())\n\t\t\t}\n\t\t}\n\t\tvar i int\n\t\tu.iterator = func() NodeNavigator {\n\t\t\tif i >= len(list) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tnode := list[i]\n\t\t\ti++\n\t\t\treturn node\n\t\t}\n\t}\n\treturn u.iterator()\n}\n\nfunc (u *unionQuery) Evaluate(t iterator) interface{} {\n\tu.iterator = nil\n\tu.Left.Evaluate(t)\n\tu.Right.Evaluate(t)\n\treturn u\n}\n\nfunc (u *unionQuery) Clone() query {\n\treturn &unionQuery{Left: u.Left.Clone(), Right: u.Right.Clone()}\n}\n\ntype lastQuery struct {\n\tbuffer  []NodeNavigator\n\tcounted bool\n\n\tInput query\n}\n\nfunc (q *lastQuery) Select(t iterator) NodeNavigator {\n\treturn nil\n}\n\nfunc (q *lastQuery) Evaluate(t iterator) interface{} {\n\tif !q.counted {\n\t\tfor {\n\t\t\tnode := q.Input.Select(t)\n\t\t\tif node == nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tq.buffer = append(q.buffer, node.Copy())\n\t\t}\n\t\tq.counted = true\n\t}\n\treturn float64(len(q.buffer))\n}\n\nfunc (q *lastQuery) Clone() query {\n\treturn &lastQuery{Input: q.Input.Clone()}\n}\n\nfunc getHashCode(n NodeNavigator) uint64 {\n\tvar sb bytes.Buffer\n\tswitch n.NodeType() {\n\tcase AttributeNode, TextNode, CommentNode:\n\t\tsb.WriteString(fmt.Sprintf(\"%s=%s\", n.LocalName(), n.Value()))\n\t\t// https://github.com/antchfx/htmlquery/issues/25\n\t\td := 1\n\t\tfor n.MoveToPrevious() {\n\t\t\td++\n\t\t}\n\t\tsb.WriteString(fmt.Sprintf(\"-%d\", d))\n\t\tfor n.MoveToParent() {\n\t\t\td = 1\n\t\t\tfor n.MoveToPrevious() {\n\t\t\t\td++\n\t\t\t}\n\t\t\tsb.WriteString(fmt.Sprintf(\"-%d\", d))\n\t\t}\n\tcase ElementNode:\n\t\tsb.WriteString(n.Prefix() + n.LocalName())\n\t\td := 1\n\t\tfor n.MoveToPrevious() {\n\t\t\td++\n\t\t}\n\t\tsb.WriteString(fmt.Sprintf(\"-%d\", d))\n\n\t\tfor n.MoveToParent() {\n\t\t\td = 1\n\t\t\tfor n.MoveToPrevious() {\n\t\t\t\td++\n\t\t\t}\n\t\t\tsb.WriteString(fmt.Sprintf(\"-%d\", d))\n\t\t}\n\t}\n\th := fnv.New64a()\n\th.Write([]byte(sb.String()))\n\treturn h.Sum64()\n}\n\nfunc getNodePosition(q query) int {\n\ttype Position interface {\n\t\tposition() int\n\t}\n\tif count, ok := q.(Position); ok {\n\t\treturn count.position()\n\t}\n\treturn 1\n}\n\nfunc getNodeDepth(q query) int {\n\ttype Depth interface {\n\t\tdepth() int\n\t}\n\tif count, ok := q.(Depth); ok {\n\t\treturn count.depth()\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/github.com/antchfx/xpath/xpath.go",
    "content": "package xpath\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// NodeType represents a type of XPath node.\ntype NodeType int\n\nconst (\n\t// RootNode is a root node of the XML document or node tree.\n\tRootNode NodeType = iota\n\n\t// ElementNode is an element, such as <element>.\n\tElementNode\n\n\t// AttributeNode is an attribute, such as id='123'.\n\tAttributeNode\n\n\t// TextNode is the text content of a node.\n\tTextNode\n\n\t// CommentNode is a comment node, such as <!-- my comment -->\n\tCommentNode\n\n\t// allNode is any types of node, used by xpath package only to predicate match.\n\tallNode\n)\n\n// NodeNavigator provides cursor model for navigating XML data.\ntype NodeNavigator interface {\n\t// NodeType returns the XPathNodeType of the current node.\n\tNodeType() NodeType\n\n\t// LocalName gets the Name of the current node.\n\tLocalName() string\n\n\t// Prefix returns namespace prefix associated with the current node.\n\tPrefix() string\n\n\t// Value gets the value of current node.\n\tValue() string\n\n\t// Copy does a deep copy of the NodeNavigator and all its components.\n\tCopy() NodeNavigator\n\n\t// MoveToRoot moves the NodeNavigator to the root node of the current node.\n\tMoveToRoot()\n\n\t// MoveToParent moves the NodeNavigator to the parent node of the current node.\n\tMoveToParent() bool\n\n\t// MoveToNextAttribute moves the NodeNavigator to the next attribute on current node.\n\tMoveToNextAttribute() bool\n\n\t// MoveToChild moves the NodeNavigator to the first child node of the current node.\n\tMoveToChild() bool\n\n\t// MoveToFirst moves the NodeNavigator to the first sibling node of the current node.\n\tMoveToFirst() bool\n\n\t// MoveToNext moves the NodeNavigator to the next sibling node of the current node.\n\tMoveToNext() bool\n\n\t// MoveToPrevious moves the NodeNavigator to the previous sibling node of the current node.\n\tMoveToPrevious() bool\n\n\t// MoveTo moves the NodeNavigator to the same position as the specified NodeNavigator.\n\tMoveTo(NodeNavigator) bool\n}\n\n// NodeIterator holds all matched Node object.\ntype NodeIterator struct {\n\tnode  NodeNavigator\n\tquery query\n}\n\n// Current returns current node which matched.\nfunc (t *NodeIterator) Current() NodeNavigator {\n\treturn t.node\n}\n\n// MoveNext moves Navigator to the next match node.\nfunc (t *NodeIterator) MoveNext() bool {\n\tn := t.query.Select(t)\n\tif n != nil {\n\t\tif !t.node.MoveTo(n) {\n\t\t\tt.node = n.Copy()\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Select selects a node set using the specified XPath expression.\n// This method is deprecated, recommend using Expr.Select() method instead.\nfunc Select(root NodeNavigator, expr string) *NodeIterator {\n\texp, err := Compile(expr)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn exp.Select(root)\n}\n\n// Expr is an XPath expression for query.\ntype Expr struct {\n\ts string\n\tq query\n}\n\ntype iteratorFunc func() NodeNavigator\n\nfunc (f iteratorFunc) Current() NodeNavigator {\n\treturn f()\n}\n\n// Evaluate returns the result of the expression.\n// The result type of the expression is one of the follow: bool,float64,string,NodeIterator).\nfunc (expr *Expr) Evaluate(root NodeNavigator) interface{} {\n\tval := expr.q.Evaluate(iteratorFunc(func() NodeNavigator { return root }))\n\tswitch val.(type) {\n\tcase query:\n\t\treturn &NodeIterator{query: expr.q.Clone(), node: root}\n\t}\n\treturn val\n}\n\n// Select selects a node set using the specified XPath expression.\nfunc (expr *Expr) Select(root NodeNavigator) *NodeIterator {\n\treturn &NodeIterator{query: expr.q.Clone(), node: root}\n}\n\n// String returns XPath expression string.\nfunc (expr *Expr) String() string {\n\treturn expr.s\n}\n\n// Compile compiles an XPath expression string.\nfunc Compile(expr string) (*Expr, error) {\n\tif expr == \"\" {\n\t\treturn nil, errors.New(\"expr expression is nil\")\n\t}\n\tqy, err := build(expr, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif qy == nil {\n\t\treturn nil, fmt.Errorf(fmt.Sprintf(\"undeclared variable in XPath expression: %s\", expr))\n\t}\n\treturn &Expr{s: expr, q: qy}, nil\n}\n\n// MustCompile compiles an XPath expression string and ignored error.\nfunc MustCompile(expr string) *Expr {\n\texp, err := Compile(expr)\n\tif err != nil {\n\t\treturn &Expr{s: expr, q: nopQuery{}}\n\t}\n\treturn exp\n}\n\n// CompileWithNS compiles an XPath expression string, using given namespaces map.\nfunc CompileWithNS(expr string, namespaces map[string]string) (*Expr, error) {\n\tif expr == \"\" {\n\t\treturn nil, errors.New(\"expr expression is nil\")\n\t}\n\tqy, err := build(expr, namespaces)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif qy == nil {\n\t\treturn nil, fmt.Errorf(fmt.Sprintf(\"undeclared variable in XPath expression: %s\", expr))\n\t}\n\treturn &Expr{s: expr, q: qy}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/armon/go-radix/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n"
  },
  {
    "path": "vendor/github.com/armon/go-radix/.travis.yml",
    "content": "language: go\ngo:\n  - tip\n"
  },
  {
    "path": "vendor/github.com/armon/go-radix/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Armon Dadgar\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject 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, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/armon/go-radix/README.md",
    "content": "go-radix [![Build Status](https://travis-ci.org/armon/go-radix.png)](https://travis-ci.org/armon/go-radix)\n=========\n\nProvides the `radix` package that implements a [radix tree](http://en.wikipedia.org/wiki/Radix_tree).\nThe package only provides a single `Tree` implementation, optimized for sparse nodes.\n\nAs a radix tree, it provides the following:\n * O(k) operations. In many cases, this can be faster than a hash table since\n   the hash function is an O(k) operation, and hash tables have very poor cache locality.\n * Minimum / Maximum value lookups\n * Ordered iteration\n\nFor an immutable variant, see [go-immutable-radix](https://github.com/hashicorp/go-immutable-radix).\n\nDocumentation\n=============\n\nThe full documentation is available on [Godoc](http://godoc.org/github.com/armon/go-radix).\n\nExample\n=======\n\nBelow is a simple example of usage\n\n```go\n// Create a tree\nr := radix.New()\nr.Insert(\"foo\", 1)\nr.Insert(\"bar\", 2)\nr.Insert(\"foobar\", 2)\n\n// Find the longest prefix match\nm, _, _ := r.LongestPrefix(\"foozip\")\nif m != \"foo\" {\n    panic(\"should be foo\")\n}\n```\n\n"
  },
  {
    "path": "vendor/github.com/armon/go-radix/radix.go",
    "content": "package radix\n\nimport (\n\t\"sort\"\n\t\"strings\"\n)\n\n// WalkFn is used when walking the tree. Takes a\n// key and value, returning if iteration should\n// be terminated.\ntype WalkFn func(s string, v interface{}) bool\n\n// leafNode is used to represent a value\ntype leafNode struct {\n\tkey string\n\tval interface{}\n}\n\n// edge is used to represent an edge node\ntype edge struct {\n\tlabel byte\n\tnode  *node\n}\n\ntype node struct {\n\t// leaf is used to store possible leaf\n\tleaf *leafNode\n\n\t// prefix is the common prefix we ignore\n\tprefix string\n\n\t// Edges should be stored in-order for iteration.\n\t// We avoid a fully materialized slice to save memory,\n\t// since in most cases we expect to be sparse\n\tedges edges\n}\n\nfunc (n *node) isLeaf() bool {\n\treturn n.leaf != nil\n}\n\nfunc (n *node) addEdge(e edge) {\n\tn.edges = append(n.edges, e)\n\tn.edges.Sort()\n}\n\nfunc (n *node) updateEdge(label byte, node *node) {\n\tnum := len(n.edges)\n\tidx := sort.Search(num, func(i int) bool {\n\t\treturn n.edges[i].label >= label\n\t})\n\tif idx < num && n.edges[idx].label == label {\n\t\tn.edges[idx].node = node\n\t\treturn\n\t}\n\tpanic(\"replacing missing edge\")\n}\n\nfunc (n *node) getEdge(label byte) *node {\n\tnum := len(n.edges)\n\tidx := sort.Search(num, func(i int) bool {\n\t\treturn n.edges[i].label >= label\n\t})\n\tif idx < num && n.edges[idx].label == label {\n\t\treturn n.edges[idx].node\n\t}\n\treturn nil\n}\n\nfunc (n *node) delEdge(label byte) {\n\tnum := len(n.edges)\n\tidx := sort.Search(num, func(i int) bool {\n\t\treturn n.edges[i].label >= label\n\t})\n\tif idx < num && n.edges[idx].label == label {\n\t\tcopy(n.edges[idx:], n.edges[idx+1:])\n\t\tn.edges[len(n.edges)-1] = edge{}\n\t\tn.edges = n.edges[:len(n.edges)-1]\n\t}\n}\n\ntype edges []edge\n\nfunc (e edges) Len() int {\n\treturn len(e)\n}\n\nfunc (e edges) Less(i, j int) bool {\n\treturn e[i].label < e[j].label\n}\n\nfunc (e edges) Swap(i, j int) {\n\te[i], e[j] = e[j], e[i]\n}\n\nfunc (e edges) Sort() {\n\tsort.Sort(e)\n}\n\n// Tree implements a radix tree. This can be treated as a\n// Dictionary abstract data type. The main advantage over\n// a standard hash map is prefix-based lookups and\n// ordered iteration,\ntype Tree struct {\n\troot *node\n\tsize int\n}\n\n// New returns an empty Tree\nfunc New() *Tree {\n\treturn NewFromMap(nil)\n}\n\n// NewFromMap returns a new tree containing the keys\n// from an existing map\nfunc NewFromMap(m map[string]interface{}) *Tree {\n\tt := &Tree{root: &node{}}\n\tfor k, v := range m {\n\t\tt.Insert(k, v)\n\t}\n\treturn t\n}\n\n// Len is used to return the number of elements in the tree\nfunc (t *Tree) Len() int {\n\treturn t.size\n}\n\n// longestPrefix finds the length of the shared prefix\n// of two strings\nfunc longestPrefix(k1, k2 string) int {\n\tmax := len(k1)\n\tif l := len(k2); l < max {\n\t\tmax = l\n\t}\n\tvar i int\n\tfor i = 0; i < max; i++ {\n\t\tif k1[i] != k2[i] {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn i\n}\n\n// Insert is used to add a newentry or update\n// an existing entry. Returns if updated.\nfunc (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {\n\tvar parent *node\n\tn := t.root\n\tsearch := s\n\tfor {\n\t\t// Handle key exhaution\n\t\tif len(search) == 0 {\n\t\t\tif n.isLeaf() {\n\t\t\t\told := n.leaf.val\n\t\t\t\tn.leaf.val = v\n\t\t\t\treturn old, true\n\t\t\t}\n\n\t\t\tn.leaf = &leafNode{\n\t\t\t\tkey: s,\n\t\t\t\tval: v,\n\t\t\t}\n\t\t\tt.size++\n\t\t\treturn nil, false\n\t\t}\n\n\t\t// Look for the edge\n\t\tparent = n\n\t\tn = n.getEdge(search[0])\n\n\t\t// No edge, create one\n\t\tif n == nil {\n\t\t\te := edge{\n\t\t\t\tlabel: search[0],\n\t\t\t\tnode: &node{\n\t\t\t\t\tleaf: &leafNode{\n\t\t\t\t\t\tkey: s,\n\t\t\t\t\t\tval: v,\n\t\t\t\t\t},\n\t\t\t\t\tprefix: search,\n\t\t\t\t},\n\t\t\t}\n\t\t\tparent.addEdge(e)\n\t\t\tt.size++\n\t\t\treturn nil, false\n\t\t}\n\n\t\t// Determine longest prefix of the search key on match\n\t\tcommonPrefix := longestPrefix(search, n.prefix)\n\t\tif commonPrefix == len(n.prefix) {\n\t\t\tsearch = search[commonPrefix:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// Split the node\n\t\tt.size++\n\t\tchild := &node{\n\t\t\tprefix: search[:commonPrefix],\n\t\t}\n\t\tparent.updateEdge(search[0], child)\n\n\t\t// Restore the existing node\n\t\tchild.addEdge(edge{\n\t\t\tlabel: n.prefix[commonPrefix],\n\t\t\tnode:  n,\n\t\t})\n\t\tn.prefix = n.prefix[commonPrefix:]\n\n\t\t// Create a new leaf node\n\t\tleaf := &leafNode{\n\t\t\tkey: s,\n\t\t\tval: v,\n\t\t}\n\n\t\t// If the new key is a subset, add to to this node\n\t\tsearch = search[commonPrefix:]\n\t\tif len(search) == 0 {\n\t\t\tchild.leaf = leaf\n\t\t\treturn nil, false\n\t\t}\n\n\t\t// Create a new edge for the node\n\t\tchild.addEdge(edge{\n\t\t\tlabel: search[0],\n\t\t\tnode: &node{\n\t\t\t\tleaf:   leaf,\n\t\t\t\tprefix: search,\n\t\t\t},\n\t\t})\n\t\treturn nil, false\n\t}\n}\n\n// Delete is used to delete a key, returning the previous\n// value and if it was deleted\nfunc (t *Tree) Delete(s string) (interface{}, bool) {\n\tvar parent *node\n\tvar label byte\n\tn := t.root\n\tsearch := s\n\tfor {\n\t\t// Check for key exhaution\n\t\tif len(search) == 0 {\n\t\t\tif !n.isLeaf() {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tgoto DELETE\n\t\t}\n\n\t\t// Look for an edge\n\t\tparent = n\n\t\tlabel = search[0]\n\t\tn = n.getEdge(label)\n\t\tif n == nil {\n\t\t\tbreak\n\t\t}\n\n\t\t// Consume the search prefix\n\t\tif strings.HasPrefix(search, n.prefix) {\n\t\t\tsearch = search[len(n.prefix):]\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn nil, false\n\nDELETE:\n\t// Delete the leaf\n\tleaf := n.leaf\n\tn.leaf = nil\n\tt.size--\n\n\t// Check if we should delete this node from the parent\n\tif parent != nil && len(n.edges) == 0 {\n\t\tparent.delEdge(label)\n\t}\n\n\t// Check if we should merge this node\n\tif n != t.root && len(n.edges) == 1 {\n\t\tn.mergeChild()\n\t}\n\n\t// Check if we should merge the parent's other child\n\tif parent != nil && parent != t.root && len(parent.edges) == 1 && !parent.isLeaf() {\n\t\tparent.mergeChild()\n\t}\n\n\treturn leaf.val, true\n}\n\n// DeletePrefix is used to delete the subtree under a prefix\n// Returns how many nodes were deleted\n// Use this to delete large subtrees efficiently\nfunc (t *Tree) DeletePrefix(s string) int {\n\treturn t.deletePrefix(nil, t.root, s)\n}\n\n// delete does a recursive deletion\nfunc (t *Tree) deletePrefix(parent, n *node, prefix string) int {\n\t// Check for key exhaustion\n\tif len(prefix) == 0 {\n\t\t// Remove the leaf node\n\t\tsubTreeSize := 0\n\t\t//recursively walk from all edges of the node to be deleted\n\t\trecursiveWalk(n, func(s string, v interface{}) bool {\n\t\t\tsubTreeSize++\n\t\t\treturn false\n\t\t})\n\t\tif n.isLeaf() {\n\t\t\tn.leaf = nil\n\t\t}\n\t\tn.edges = nil // deletes the entire subtree\n\n\t\t// Check if we should merge the parent's other child\n\t\tif parent != nil && parent != t.root && len(parent.edges) == 1 && !parent.isLeaf() {\n\t\t\tparent.mergeChild()\n\t\t}\n\t\tt.size -= subTreeSize\n\t\treturn subTreeSize\n\t}\n\n\t// Look for an edge\n\tlabel := prefix[0]\n\tchild := n.getEdge(label)\n\tif child == nil || (!strings.HasPrefix(child.prefix, prefix) && !strings.HasPrefix(prefix, child.prefix)) {\n\t\treturn 0\n\t}\n\n\t// Consume the search prefix\n\tif len(child.prefix) > len(prefix) {\n\t\tprefix = prefix[len(prefix):]\n\t} else {\n\t\tprefix = prefix[len(child.prefix):]\n\t}\n\treturn t.deletePrefix(n, child, prefix)\n}\n\nfunc (n *node) mergeChild() {\n\te := n.edges[0]\n\tchild := e.node\n\tn.prefix = n.prefix + child.prefix\n\tn.leaf = child.leaf\n\tn.edges = child.edges\n}\n\n// Get is used to lookup a specific key, returning\n// the value and if it was found\nfunc (t *Tree) Get(s string) (interface{}, bool) {\n\tn := t.root\n\tsearch := s\n\tfor {\n\t\t// Check for key exhaution\n\t\tif len(search) == 0 {\n\t\t\tif n.isLeaf() {\n\t\t\t\treturn n.leaf.val, true\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\t// Look for an edge\n\t\tn = n.getEdge(search[0])\n\t\tif n == nil {\n\t\t\tbreak\n\t\t}\n\n\t\t// Consume the search prefix\n\t\tif strings.HasPrefix(search, n.prefix) {\n\t\t\tsearch = search[len(n.prefix):]\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// LongestPrefix is like Get, but instead of an\n// exact match, it will return the longest prefix match.\nfunc (t *Tree) LongestPrefix(s string) (string, interface{}, bool) {\n\tvar last *leafNode\n\tn := t.root\n\tsearch := s\n\tfor {\n\t\t// Look for a leaf node\n\t\tif n.isLeaf() {\n\t\t\tlast = n.leaf\n\t\t}\n\n\t\t// Check for key exhaution\n\t\tif len(search) == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\t// Look for an edge\n\t\tn = n.getEdge(search[0])\n\t\tif n == nil {\n\t\t\tbreak\n\t\t}\n\n\t\t// Consume the search prefix\n\t\tif strings.HasPrefix(search, n.prefix) {\n\t\t\tsearch = search[len(n.prefix):]\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\tif last != nil {\n\t\treturn last.key, last.val, true\n\t}\n\treturn \"\", nil, false\n}\n\n// Minimum is used to return the minimum value in the tree\nfunc (t *Tree) Minimum() (string, interface{}, bool) {\n\tn := t.root\n\tfor {\n\t\tif n.isLeaf() {\n\t\t\treturn n.leaf.key, n.leaf.val, true\n\t\t}\n\t\tif len(n.edges) > 0 {\n\t\t\tn = n.edges[0].node\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn \"\", nil, false\n}\n\n// Maximum is used to return the maximum value in the tree\nfunc (t *Tree) Maximum() (string, interface{}, bool) {\n\tn := t.root\n\tfor {\n\t\tif num := len(n.edges); num > 0 {\n\t\t\tn = n.edges[num-1].node\n\t\t\tcontinue\n\t\t}\n\t\tif n.isLeaf() {\n\t\t\treturn n.leaf.key, n.leaf.val, true\n\t\t}\n\t\tbreak\n\t}\n\treturn \"\", nil, false\n}\n\n// Walk is used to walk the tree\nfunc (t *Tree) Walk(fn WalkFn) {\n\trecursiveWalk(t.root, fn)\n}\n\n// WalkPrefix is used to walk the tree under a prefix\nfunc (t *Tree) WalkPrefix(prefix string, fn WalkFn) {\n\tn := t.root\n\tsearch := prefix\n\tfor {\n\t\t// Check for key exhaution\n\t\tif len(search) == 0 {\n\t\t\trecursiveWalk(n, fn)\n\t\t\treturn\n\t\t}\n\n\t\t// Look for an edge\n\t\tn = n.getEdge(search[0])\n\t\tif n == nil {\n\t\t\tbreak\n\t\t}\n\n\t\t// Consume the search prefix\n\t\tif strings.HasPrefix(search, n.prefix) {\n\t\t\tsearch = search[len(n.prefix):]\n\n\t\t} else if strings.HasPrefix(n.prefix, search) {\n\t\t\t// Child may be under our search prefix\n\t\t\trecursiveWalk(n, fn)\n\t\t\treturn\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\n}\n\n// WalkPath is used to walk the tree, but only visiting nodes\n// from the root down to a given leaf. Where WalkPrefix walks\n// all the entries *under* the given prefix, this walks the\n// entries *above* the given prefix.\nfunc (t *Tree) WalkPath(path string, fn WalkFn) {\n\tn := t.root\n\tsearch := path\n\tfor {\n\t\t// Visit the leaf values if any\n\t\tif n.leaf != nil && fn(n.leaf.key, n.leaf.val) {\n\t\t\treturn\n\t\t}\n\n\t\t// Check for key exhaution\n\t\tif len(search) == 0 {\n\t\t\treturn\n\t\t}\n\n\t\t// Look for an edge\n\t\tn = n.getEdge(search[0])\n\t\tif n == nil {\n\t\t\treturn\n\t\t}\n\n\t\t// Consume the search prefix\n\t\tif strings.HasPrefix(search, n.prefix) {\n\t\t\tsearch = search[len(n.prefix):]\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// recursiveWalk is used to do a pre-order walk of a node\n// recursively. Returns true if the walk should be aborted\nfunc recursiveWalk(n *node, fn WalkFn) bool {\n\t// Visit the leaf values if any\n\tif n.leaf != nil && fn(n.leaf.key, n.leaf.val) {\n\t\treturn true\n\t}\n\n\t// Recurse on the children\n\tfor _, e := range n.edges {\n\t\tif recursiveWalk(e.node, fn) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// ToMap is used to walk the tree and convert it into a map\nfunc (t *Tree) ToMap() map[string]interface{} {\n\tout := make(map[string]interface{}, t.size)\n\tt.Walk(func(k string, v interface{}) bool {\n\t\tout[k] = v\n\t\treturn false\n\t})\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/.gitignore",
    "content": "# vi\n*~\n*.swp\n*.swo\n\n# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n\n# test directory\ntest/\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.12\n  - 1.13\n  - 1.14\n\nos:\n  - linux\n  - windows\n\nbefore_install:\n  - go get -t -v ./...\n\nscript:\n  - go test -race -coverprofile=coverage.txt -covermode=atomic\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Bob Matcuk\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\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/README.md",
    "content": "# doublestar\n\nPath pattern matching and globbing supporting `doublestar` (`**`) patterns.\n\n![Release](https://img.shields.io/github/release/bmatcuk/doublestar.svg?branch=master)\n[![Build Status](https://travis-ci.org/bmatcuk/doublestar.svg?branch=master)](https://travis-ci.org/bmatcuk/doublestar)\n[![codecov.io](https://img.shields.io/codecov/c/github/bmatcuk/doublestar.svg?branch=master)](https://codecov.io/github/bmatcuk/doublestar?branch=master)\n\n## About\n\n**doublestar** is a [golang](http://golang.org/) implementation of path pattern\nmatching and globbing with support for \"doublestar\" (aka globstar: `**`)\npatterns.\n\ndoublestar patterns match files and directories recursively. For example, if\nyou had the following directory structure:\n\n```bash\ngrandparent\n`-- parent\n    |-- child1\n    `-- child2\n```\n\nYou could find the children with patterns such as: `**/child*`,\n`grandparent/**/child?`, `**/parent/*`, or even just `**` by itself (which will\nreturn all files and directories recursively).\n\nBash's globstar is doublestar's inspiration and, as such, works similarly.\nNote that the doublestar must appear as a path component by itself. A pattern\nsuch as `/path**` is invalid and will be treated the same as `/path*`, but\n`/path*/**` should achieve the desired result. Additionally, `/path/**` will\nmatch all directories and files under the path directory, but `/path/**/` will\nonly match directories.\n\n## Installation\n\n**doublestar** can be installed via `go get`:\n\n```bash\ngo get github.com/bmatcuk/doublestar\n```\n\nTo use it in your code, you must import it:\n\n```go\nimport \"github.com/bmatcuk/doublestar\"\n```\n\n## Usage\n\n### Match\n\n```go\nfunc Match(pattern, name string) (bool, error)\n```\n\nMatch returns true if `name` matches the file name `pattern`\n([see below](#patterns)). `name` and `pattern` are split on forward slash (`/`)\ncharacters and may be relative or absolute.\n\nNote: `Match()` is meant to be a drop-in replacement for `path.Match()`. As\nsuch, it always uses `/` as the path separator. If you are writing code that\nwill run on systems where `/` is not the path separator (such as Windows), you\nwant to use `PathMatch()` (below) instead.\n\n\n### PathMatch\n\n```go\nfunc PathMatch(pattern, name string) (bool, error)\n```\n\nPathMatch returns true if `name` matches the file name `pattern`\n([see below](#patterns)). The difference between Match and PathMatch is that\nPathMatch will automatically use your system's path separator to split `name`\nand `pattern`.\n\n`PathMatch()` is meant to be a drop-in replacement for `filepath.Match()`.\n\n### Glob\n\n```go\nfunc Glob(pattern string) ([]string, error)\n```\n\nGlob finds all files and directories in the filesystem that match `pattern`\n([see below](#patterns)). `pattern` may be relative (to the current working\ndirectory), or absolute.\n\n`Glob()` is meant to be a drop-in replacement for `filepath.Glob()`.\n\n### Patterns\n\n**doublestar** supports the following special terms in the patterns:\n\nSpecial Terms | Meaning\n------------- | -------\n`*`           | matches any sequence of non-path-separators\n`**`          | matches any sequence of characters, including path separators\n`?`           | matches any single non-path-separator character\n`[class]`     | matches any single non-path-separator character against a class of characters ([see below](#character-classes))\n`{alt1,...}`  | matches a sequence of characters if one of the comma-separated alternatives matches\n\nAny character with a special meaning can be escaped with a backslash (`\\`).\n\n#### Character Classes\n\nCharacter classes support the following:\n\nClass      | Meaning\n---------- | -------\n`[abc]`    | matches any single character within the set\n`[a-z]`    | matches any single character in the range\n`[^class]` | matches any single character which does *not* match the class\n\n### Abstracting the `os` package\n\n**doublestar** by default uses the `Open`, `Stat`, and `Lstat`, functions and\n`PathSeparator` value from the standard library's `os` package. To abstract\nthis, for example to be able to perform tests of Windows paths on Linux, or to\ninteroperate with your own filesystem code, it includes the functions `GlobOS`\nand `PathMatchOS` which are identical to `Glob` and `PathMatch` except that they\noperate on an `OS` interface:\n\n```go\ntype OS interface {\n    Lstat(name string) (os.FileInfo, error)\n    Open(name string) (*os.File, error)\n    PathSeparator() rune\n    Stat(name string) (os.FileInfo, error)\n}\n```\n\n`StandardOS` is a value that implements this interface by calling functions in\nthe standard library's `os` package.\n\n## License\n\n[MIT License](LICENSE)\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/doublestar.go",
    "content": "package doublestar\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// An OS abstracts functions in the standard library's os package.\ntype OS interface {\n\tLstat(name string) (os.FileInfo, error)\n\tOpen(name string) (*os.File, error)\n\tPathSeparator() rune\n\tStat(name string) (os.FileInfo, error)\n}\n\n// StandardOS is a value that implements the OS interface by calling functions\n// in the standard libray's os package.\nvar StandardOS OS = standardOS{}\n\n// A standardOS implements OS by calling functions in the standard library's os\n// package.\ntype standardOS struct{}\n\nfunc (standardOS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) }\nfunc (standardOS) Open(name string) (*os.File, error)     { return os.Open(name) }\nfunc (standardOS) PathSeparator() rune                    { return os.PathSeparator }\nfunc (standardOS) Stat(name string) (os.FileInfo, error)  { return os.Stat(name) }\n\n// ErrBadPattern indicates a pattern was malformed.\nvar ErrBadPattern = path.ErrBadPattern\n\n// Split a path on the given separator, respecting escaping.\nfunc splitPathOnSeparator(path string, separator rune) (ret []string) {\n\tidx := 0\n\tif separator == '\\\\' {\n\t\t// if the separator is '\\\\', then we can just split...\n\t\tret = strings.Split(path, string(separator))\n\t\tidx = len(ret)\n\t} else {\n\t\t// otherwise, we need to be careful of situations where the separator was escaped\n\t\tcnt := strings.Count(path, string(separator))\n\t\tif cnt == 0 {\n\t\t\treturn []string{path}\n\t\t}\n\n\t\tret = make([]string, cnt+1)\n\t\tpathlen := len(path)\n\t\tseparatorLen := utf8.RuneLen(separator)\n\t\temptyEnd := false\n\t\tfor start := 0; start < pathlen; {\n\t\t\tend := indexRuneWithEscaping(path[start:], separator)\n\t\t\tif end == -1 {\n\t\t\t\temptyEnd = false\n\t\t\t\tend = pathlen\n\t\t\t} else {\n\t\t\t\temptyEnd = true\n\t\t\t\tend += start\n\t\t\t}\n\t\t\tret[idx] = path[start:end]\n\t\t\tstart = end + separatorLen\n\t\t\tidx++\n\t\t}\n\n\t\t// If the last rune is a path separator, we need to append an empty string to\n\t\t// represent the last, empty path component. By default, the strings from\n\t\t// make([]string, ...) will be empty, so we just need to icrement the count\n\t\tif emptyEnd {\n\t\t\tidx++\n\t\t}\n\t}\n\n\treturn ret[:idx]\n}\n\n// Find the first index of a rune in a string,\n// ignoring any times the rune is escaped using \"\\\".\nfunc indexRuneWithEscaping(s string, r rune) int {\n\tend := strings.IndexRune(s, r)\n\tif end == -1 {\n\t\treturn -1\n\t}\n\tif end > 0 && s[end-1] == '\\\\' {\n\t\tstart := end + utf8.RuneLen(r)\n\t\tend = indexRuneWithEscaping(s[start:], r)\n\t\tif end != -1 {\n\t\t\tend += start\n\t\t}\n\t}\n\treturn end\n}\n\n// Find the last index of a rune in a string,\n// ignoring any times the rune is escaped using \"\\\".\nfunc lastIndexRuneWithEscaping(s string, r rune) int {\n\tend := strings.LastIndex(s, string(r))\n\tif end == -1 {\n\t\treturn -1\n\t}\n\tif end > 0 && s[end-1] == '\\\\' {\n\t\tend = lastIndexRuneWithEscaping(s[:end-1], r)\n\t}\n\treturn end\n}\n\n// Find the index of the first instance of one of the unicode characters in\n// chars, ignoring any times those characters are escaped using \"\\\".\nfunc indexAnyWithEscaping(s, chars string) int {\n\tend := strings.IndexAny(s, chars)\n\tif end == -1 {\n\t\treturn -1\n\t}\n\tif end > 0 && s[end-1] == '\\\\' {\n\t\t_, adj := utf8.DecodeRuneInString(s[end:])\n\t\tstart := end + adj\n\t\tend = indexAnyWithEscaping(s[start:], chars)\n\t\tif end != -1 {\n\t\t\tend += start\n\t\t}\n\t}\n\treturn end\n}\n\n// Split a set of alternatives such as {alt1,alt2,...} and returns the index of\n// the rune after the closing curly brace. Respects nested alternatives and\n// escaped runes.\nfunc splitAlternatives(s string) (ret []string, idx int) {\n\tret = make([]string, 0, 2)\n\tidx = 0\n\tslen := len(s)\n\tbraceCnt := 1\n\tesc := false\n\tstart := 0\n\tfor braceCnt > 0 {\n\t\tif idx >= slen {\n\t\t\treturn nil, -1\n\t\t}\n\n\t\tsRune, adj := utf8.DecodeRuneInString(s[idx:])\n\t\tif esc {\n\t\t\tesc = false\n\t\t} else if sRune == '\\\\' {\n\t\t\tesc = true\n\t\t} else if sRune == '{' {\n\t\t\tbraceCnt++\n\t\t} else if sRune == '}' {\n\t\t\tbraceCnt--\n\t\t} else if sRune == ',' && braceCnt == 1 {\n\t\t\tret = append(ret, s[start:idx])\n\t\t\tstart = idx + adj\n\t\t}\n\n\t\tidx += adj\n\t}\n\tret = append(ret, s[start:idx-1])\n\treturn\n}\n\n// Returns true if the pattern is \"zero length\", meaning\n// it could match zero or more characters.\nfunc isZeroLengthPattern(pattern string) (ret bool, err error) {\n\t// * can match zero\n\tif pattern == \"\" || pattern == \"*\" || pattern == \"**\" {\n\t\treturn true, nil\n\t}\n\n\t// an alternative with zero length can match zero, for example {,x} - the\n\t// first alternative has zero length\n\tr, adj := utf8.DecodeRuneInString(pattern)\n\tif r == '{' {\n\t\toptions, endOptions := splitAlternatives(pattern[adj:])\n\t\tif endOptions == -1 {\n\t\t\treturn false, ErrBadPattern\n\t\t}\n\t\tif ret, err = isZeroLengthPattern(pattern[adj+endOptions:]); !ret || err != nil {\n\t\t\treturn\n\t\t}\n\t\tfor _, o := range options {\n\t\t\tif ret, err = isZeroLengthPattern(o); ret || err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\n// Match returns true if name matches the shell file name pattern.\n// The pattern syntax is:\n//\n//  pattern:\n//    { term }\n//  term:\n//    '*'         matches any sequence of non-path-separators\n//    '**'        matches any sequence of characters, including\n//                path separators.\n//    '?'         matches any single non-path-separator character\n//    '[' [ '^' ] { character-range } ']'\n//          character class (must be non-empty)\n//    '{' { term } [ ',' { term } ... ] '}'\n//    c           matches character c (c != '*', '?', '\\\\', '[')\n//    '\\\\' c      matches character c\n//\n//  character-range:\n//    c           matches character c (c != '\\\\', '-', ']')\n//    '\\\\' c      matches character c\n//    lo '-' hi   matches character c for lo <= c <= hi\n//\n// Match requires pattern to match all of name, not just a substring.\n// The path-separator defaults to the '/' character. The only possible\n// returned error is ErrBadPattern, when pattern is malformed.\n//\n// Note: this is meant as a drop-in replacement for path.Match() which\n// always uses '/' as the path separator. If you want to support systems\n// which use a different path separator (such as Windows), what you want\n// is the PathMatch() function below.\n//\nfunc Match(pattern, name string) (bool, error) {\n\treturn matchWithSeparator(pattern, name, '/')\n}\n\n// PathMatch is like Match except that it uses your system's path separator.\n// For most systems, this will be '/'. However, for Windows, it would be '\\\\'.\n// Note that for systems where the path separator is '\\\\', escaping is\n// disabled.\n//\n// Note: this is meant as a drop-in replacement for filepath.Match().\n//\nfunc PathMatch(pattern, name string) (bool, error) {\n\treturn PathMatchOS(StandardOS, pattern, name)\n}\n\n// PathMatchOS is like PathMatch except that it uses vos's path separator.\nfunc PathMatchOS(vos OS, pattern, name string) (bool, error) {\n\tpattern = filepath.ToSlash(pattern)\n\treturn matchWithSeparator(pattern, name, vos.PathSeparator())\n}\n\n// Match returns true if name matches the shell file name pattern.\n// The pattern syntax is:\n//\n//  pattern:\n//    { term }\n//  term:\n//    '*'         matches any sequence of non-path-separators\n//              '**'        matches any sequence of characters, including\n//                          path separators.\n//    '?'         matches any single non-path-separator character\n//    '[' [ '^' ] { character-range } ']'\n//          character class (must be non-empty)\n//    '{' { term } [ ',' { term } ... ] '}'\n//    c           matches character c (c != '*', '?', '\\\\', '[')\n//    '\\\\' c      matches character c\n//\n//  character-range:\n//    c           matches character c (c != '\\\\', '-', ']')\n//    '\\\\' c      matches character c, unless separator is '\\\\'\n//    lo '-' hi   matches character c for lo <= c <= hi\n//\n// Match requires pattern to match all of name, not just a substring.\n// The only possible returned error is ErrBadPattern, when pattern\n// is malformed.\n//\nfunc matchWithSeparator(pattern, name string, separator rune) (bool, error) {\n\tnameComponents := splitPathOnSeparator(name, separator)\n\treturn doMatching(pattern, nameComponents)\n}\n\nfunc doMatching(pattern string, nameComponents []string) (matched bool, err error) {\n\t// check for some base-cases\n\tpatternLen, nameLen := len(pattern), len(nameComponents)\n\tif patternLen == 0 && nameLen == 0 {\n\t\treturn true, nil\n\t}\n\tif patternLen == 0 {\n\t\tif nameLen == 1 && nameComponents[0] == \"\" {\n\t\t\treturn true, nil\n\t\t} else if nameLen == 0 {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\n\tslashIdx := indexRuneWithEscaping(pattern, '/')\n\tlastComponent := slashIdx == -1\n\tif lastComponent {\n\t\tslashIdx = len(pattern)\n\t}\n\tif pattern[:slashIdx] == \"**\" {\n\t\t// if our last pattern component is a doublestar, we're done -\n\t\t// doublestar will match any remaining name components, if any.\n\t\tif lastComponent {\n\t\t\treturn true, nil\n\t\t}\n\n\t\t// otherwise, try matching remaining components\n\t\tfor nameIdx := 0; nameIdx < nameLen; nameIdx++ {\n\t\t\tif m, _ := doMatching(pattern[slashIdx+1:], nameComponents[nameIdx:]); m {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t}\n\t\treturn false, nil\n\t}\n\n\tvar matches []string\n\tmatches, err = matchComponent(pattern, nameComponents[0])\n\tif matches == nil || err != nil {\n\t\treturn\n\t}\n\tif len(matches) == 0 && nameLen == 1 {\n\t\treturn true, nil\n\t}\n\n\tif nameLen > 1 {\n\t\tfor _, alt := range matches {\n\t\t\tmatched, err = doMatching(alt, nameComponents[1:])\n\t\t\tif matched || err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\n// Glob returns the names of all files matching pattern or nil\n// if there is no matching file. The syntax of pattern is the same\n// as in Match. The pattern may describe hierarchical names such as\n// /usr/*/bin/ed (assuming the Separator is '/').\n//\n// Glob ignores file system errors such as I/O errors reading directories.\n// The only possible returned error is ErrBadPattern, when pattern\n// is malformed.\n//\n// Your system path separator is automatically used. This means on\n// systems where the separator is '\\\\' (Windows), escaping will be\n// disabled.\n//\n// Note: this is meant as a drop-in replacement for filepath.Glob().\n//\nfunc Glob(pattern string) (matches []string, err error) {\n\treturn GlobOS(StandardOS, pattern)\n}\n\n// GlobOS is like Glob except that it operates on vos.\nfunc GlobOS(vos OS, pattern string) (matches []string, err error) {\n\tif len(pattern) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// if the pattern starts with alternatives, we need to handle that here - the\n\t// alternatives may be a mix of relative and absolute\n\tif pattern[0] == '{' {\n\t\toptions, endOptions := splitAlternatives(pattern[1:])\n\t\tif endOptions == -1 {\n\t\t\treturn nil, ErrBadPattern\n\t\t}\n\t\tfor _, o := range options {\n\t\t\tm, e := GlobOS(vos, o+pattern[endOptions+1:])\n\t\t\tif e != nil {\n\t\t\t\treturn nil, e\n\t\t\t}\n\t\t\tmatches = append(matches, m...)\n\t\t}\n\t\treturn matches, nil\n\t}\n\n\t// If the pattern is relative or absolute and we're on a non-Windows machine,\n\t// volumeName will be an empty string. If it is absolute and we're on a\n\t// Windows machine, volumeName will be a drive letter (\"C:\") for filesystem\n\t// paths or \\\\<server>\\<share> for UNC paths.\n\tisAbs := filepath.IsAbs(pattern) || pattern[0] == '\\\\' || pattern[0] == '/'\n\tvolumeName := filepath.VolumeName(pattern)\n\tisWindowsUNC := strings.HasPrefix(volumeName, `\\\\`)\n\tif isWindowsUNC || isAbs {\n\t\tstartIdx := len(volumeName) + 1\n\t\treturn doGlob(vos, fmt.Sprintf(\"%s%s\", volumeName, string(vos.PathSeparator())), filepath.ToSlash(pattern[startIdx:]), matches)\n\t}\n\n\t// otherwise, it's a relative pattern\n\treturn doGlob(vos, \".\", filepath.ToSlash(pattern), matches)\n}\n\n// Perform a glob\nfunc doGlob(vos OS, basedir, pattern string, matches []string) (m []string, e error) {\n\tm = matches\n\te = nil\n\n\t// if the pattern starts with any path components that aren't globbed (ie,\n\t// `path/to/glob*`), we can skip over the un-globbed components (`path/to` in\n\t// our example).\n\tglobIdx := indexAnyWithEscaping(pattern, \"*?[{\\\\\")\n\tif globIdx > 0 {\n\t\tglobIdx = lastIndexRuneWithEscaping(pattern[:globIdx], '/')\n\t} else if globIdx == -1 {\n\t\tglobIdx = lastIndexRuneWithEscaping(pattern, '/')\n\t}\n\tif globIdx > 0 {\n\t\tbasedir = filepath.Join(basedir, pattern[:globIdx])\n\t\tpattern = pattern[globIdx+1:]\n\t}\n\n\t// Lstat will return an error if the file/directory doesn't exist\n\tfi, err := vos.Lstat(basedir)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// if the pattern is empty, we've found a match\n\tif len(pattern) == 0 {\n\t\tm = append(m, basedir)\n\t\treturn\n\t}\n\n\t// otherwise, we need to check each item in the directory...\n\n\t// first, if basedir is a symlink, follow it...\n\tif (fi.Mode() & os.ModeSymlink) != 0 {\n\t\tfi, err = vos.Stat(basedir)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// confirm it's a directory...\n\tif !fi.IsDir() {\n\t\treturn\n\t}\n\n\tfiles, err := filesInDir(vos, basedir)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tsort.Slice(files, func(i, j int) bool { return files[i].Name() < files[j].Name() })\n\n\tslashIdx := indexRuneWithEscaping(pattern, '/')\n\tlastComponent := slashIdx == -1\n\tif lastComponent {\n\t\tslashIdx = len(pattern)\n\t}\n\tif pattern[:slashIdx] == \"**\" {\n\t\t// if the current component is a doublestar, we'll try depth-first\n\t\tfor _, file := range files {\n\t\t\t// if symlink, we may want to follow\n\t\t\tif (file.Mode() & os.ModeSymlink) != 0 {\n\t\t\t\tfile, err = vos.Stat(filepath.Join(basedir, file.Name()))\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif file.IsDir() {\n\t\t\t\t// recurse into directories\n\t\t\t\tif lastComponent {\n\t\t\t\t\tm = append(m, filepath.Join(basedir, file.Name()))\n\t\t\t\t}\n\t\t\t\tm, e = doGlob(vos, filepath.Join(basedir, file.Name()), pattern, m)\n\t\t\t} else if lastComponent {\n\t\t\t\t// if the pattern's last component is a doublestar, we match filenames, too\n\t\t\t\tm = append(m, filepath.Join(basedir, file.Name()))\n\t\t\t}\n\t\t}\n\t\tif lastComponent {\n\t\t\treturn // we're done\n\t\t}\n\n\t\tpattern = pattern[slashIdx+1:]\n\t}\n\n\t// check items in current directory and recurse\n\tvar match []string\n\tfor _, file := range files {\n\t\tmatch, e = matchComponent(pattern, file.Name())\n\t\tif e != nil {\n\t\t\treturn\n\t\t}\n\t\tif match != nil {\n\t\t\tif len(match) == 0 {\n\t\t\t\tm = append(m, filepath.Join(basedir, file.Name()))\n\t\t\t} else {\n\t\t\t\tfor _, alt := range match {\n\t\t\t\t\tm, e = doGlob(vos, filepath.Join(basedir, file.Name()), alt, m)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc filesInDir(vos OS, dirPath string) (files []os.FileInfo, e error) {\n\tdir, err := vos.Open(dirPath)\n\tif err != nil {\n\t\treturn nil, nil\n\t}\n\tdefer func() {\n\t\tif err := dir.Close(); e == nil {\n\t\t\te = err\n\t\t}\n\t}()\n\n\tfiles, err = dir.Readdir(-1)\n\tif err != nil {\n\t\treturn nil, nil\n\t}\n\n\treturn\n}\n\n// Attempt to match a single path component with a pattern. Note that the\n// pattern may include multiple components but that the \"name\" is just a single\n// path component. The return value is a slice of patterns that should be\n// checked against subsequent path components or nil, indicating that the\n// pattern does not match this path. It is assumed that pattern components are\n// separated by '/'\nfunc matchComponent(pattern, name string) ([]string, error) {\n\t// check for matches one rune at a time\n\tpatternLen, nameLen := len(pattern), len(name)\n\tpatIdx, nameIdx := 0, 0\n\tfor patIdx < patternLen && nameIdx < nameLen {\n\t\tpatRune, patAdj := utf8.DecodeRuneInString(pattern[patIdx:])\n\t\tnameRune, nameAdj := utf8.DecodeRuneInString(name[nameIdx:])\n\t\tif patRune == '/' {\n\t\t\tpatIdx++\n\t\t\tbreak\n\t\t} else if patRune == '\\\\' {\n\t\t\t// handle escaped runes, only if separator isn't '\\\\'\n\t\t\tpatIdx += patAdj\n\t\t\tpatRune, patAdj = utf8.DecodeRuneInString(pattern[patIdx:])\n\t\t\tif patRune == utf8.RuneError {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t} else if patRune == nameRune {\n\t\t\t\tpatIdx += patAdj\n\t\t\t\tnameIdx += nameAdj\n\t\t\t} else {\n\t\t\t\treturn nil, nil\n\t\t\t}\n\t\t} else if patRune == '*' {\n\t\t\t// handle stars - a star at the end of the pattern or before a separator\n\t\t\t// will always match the rest of the path component\n\t\t\tif patIdx += patAdj; patIdx >= patternLen {\n\t\t\t\treturn []string{}, nil\n\t\t\t}\n\t\t\tif patRune, patAdj = utf8.DecodeRuneInString(pattern[patIdx:]); patRune == '/' {\n\t\t\t\treturn []string{pattern[patIdx+patAdj:]}, nil\n\t\t\t}\n\n\t\t\t// check if we can make any matches\n\t\t\tfor ; nameIdx < nameLen; nameIdx += nameAdj {\n\t\t\t\tif m, e := matchComponent(pattern[patIdx:], name[nameIdx:]); m != nil || e != nil {\n\t\t\t\t\treturn m, e\n\t\t\t\t}\n\t\t\t\t_, nameAdj = utf8.DecodeRuneInString(name[nameIdx:])\n\t\t\t}\n\t\t\treturn nil, nil\n\t\t} else if patRune == '[' {\n\t\t\t// handle character sets\n\t\t\tpatIdx += patAdj\n\t\t\tendClass := indexRuneWithEscaping(pattern[patIdx:], ']')\n\t\t\tif endClass == -1 {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t}\n\t\t\tendClass += patIdx\n\t\t\tclassRunes := []rune(pattern[patIdx:endClass])\n\t\t\tclassRunesLen := len(classRunes)\n\t\t\tif classRunesLen > 0 {\n\t\t\t\tclassIdx := 0\n\t\t\t\tmatchClass := false\n\t\t\t\tif classRunes[0] == '^' {\n\t\t\t\t\tclassIdx++\n\t\t\t\t}\n\t\t\t\tfor classIdx < classRunesLen {\n\t\t\t\t\tlow := classRunes[classIdx]\n\t\t\t\t\tif low == '-' {\n\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t}\n\t\t\t\t\tclassIdx++\n\t\t\t\t\tif low == '\\\\' {\n\t\t\t\t\t\tif classIdx < classRunesLen {\n\t\t\t\t\t\t\tlow = classRunes[classIdx]\n\t\t\t\t\t\t\tclassIdx++\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\thigh := low\n\t\t\t\t\tif classIdx < classRunesLen && classRunes[classIdx] == '-' {\n\t\t\t\t\t\t// we have a range of runes\n\t\t\t\t\t\tif classIdx++; classIdx >= classRunesLen {\n\t\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t\t}\n\t\t\t\t\t\thigh = classRunes[classIdx]\n\t\t\t\t\t\tif high == '-' {\n\t\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclassIdx++\n\t\t\t\t\t\tif high == '\\\\' {\n\t\t\t\t\t\t\tif classIdx < classRunesLen {\n\t\t\t\t\t\t\t\thigh = classRunes[classIdx]\n\t\t\t\t\t\t\t\tclassIdx++\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn nil, ErrBadPattern\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\tif low <= nameRune && nameRune <= high {\n\t\t\t\t\t\tmatchClass = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif matchClass == (classRunes[0] == '^') {\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t}\n\t\t\tpatIdx = endClass + 1\n\t\t\tnameIdx += nameAdj\n\t\t} else if patRune == '{' {\n\t\t\t// handle alternatives such as {alt1,alt2,...}\n\t\t\tpatIdx += patAdj\n\t\t\toptions, endOptions := splitAlternatives(pattern[patIdx:])\n\t\t\tif endOptions == -1 {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t}\n\t\t\tpatIdx += endOptions\n\n\t\t\tresults := make([][]string, 0, len(options))\n\t\t\ttotalResults := 0\n\t\t\tfor _, o := range options {\n\t\t\t\tm, e := matchComponent(o+pattern[patIdx:], name[nameIdx:])\n\t\t\t\tif e != nil {\n\t\t\t\t\treturn nil, e\n\t\t\t\t}\n\t\t\t\tif m != nil {\n\t\t\t\t\tresults = append(results, m)\n\t\t\t\t\ttotalResults += len(m)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(results) > 0 {\n\t\t\t\tlst := make([]string, 0, totalResults)\n\t\t\t\tfor _, m := range results {\n\t\t\t\t\tlst = append(lst, m...)\n\t\t\t\t}\n\t\t\t\treturn lst, nil\n\t\t\t}\n\n\t\t\treturn nil, nil\n\t\t} else if patRune == '?' || patRune == nameRune {\n\t\t\t// handle single-rune wildcard\n\t\t\tpatIdx += patAdj\n\t\t\tnameIdx += nameAdj\n\t\t} else {\n\t\t\treturn nil, nil\n\t\t}\n\t}\n\tif nameIdx >= nameLen {\n\t\tif patIdx >= patternLen {\n\t\t\treturn []string{}, nil\n\t\t}\n\n\t\tpattern = pattern[patIdx:]\n\t\tslashIdx := indexRuneWithEscaping(pattern, '/')\n\t\ttestPattern := pattern\n\t\tif slashIdx >= 0 {\n\t\t\ttestPattern = pattern[:slashIdx]\n\t\t}\n\n\t\tzeroLength, err := isZeroLengthPattern(testPattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif zeroLength {\n\t\t\tif slashIdx == -1 {\n\t\t\t\treturn []string{}, nil\n\t\t\t} else {\n\t\t\t\treturn []string{pattern[slashIdx+1:]}, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, nil\n}\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/v3/.gitignore",
    "content": "# vi\n*~\n*.swp\n*.swo\n\n# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n\n# test directory\ntest/\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/v3/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.13\n  - 1.14\n  - 1.15\n\nos:\n  - linux\n  - windows\n\nbefore_install:\n  - go get -t -v ./...\n\nscript:\n  - go test -race -coverprofile=coverage.txt -covermode=atomic\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/v3/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Bob Matcuk\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\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/v3/README.md",
    "content": "# doublestar\n\nPath pattern matching and globbing supporting `doublestar` (`**`) patterns.\n\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/bmatcuk/doublestar)](https://pkg.go.dev/github.com/bmatcuk/doublestar/v2)\n[![Release](https://img.shields.io/github/release/bmatcuk/doublestar.svg?branch=master)](https://github.com/bmatcuk/doublestar/releases)\n[![Build Status](https://travis-ci.org/bmatcuk/doublestar.svg?branch=master)](https://travis-ci.org/bmatcuk/doublestar)\n[![codecov.io](https://img.shields.io/codecov/c/github/bmatcuk/doublestar.svg?branch=master)](https://codecov.io/github/bmatcuk/doublestar?branch=master)\n\n## About\n\n#### [Upgrading to v2? To v3?](UPGRADING.md)\n\n**doublestar** is a [golang](http://golang.org/) implementation of path pattern\nmatching and globbing with support for \"doublestar\" (aka globstar: `**`)\npatterns.\n\ndoublestar patterns match files and directories recursively. For example, if\nyou had the following directory structure:\n\n```bash\ngrandparent\n`-- parent\n    |-- child1\n    `-- child2\n```\n\nYou could find the children with patterns such as: `**/child*`,\n`grandparent/**/child?`, `**/parent/*`, or even just `**` by itself (which will\nreturn all files and directories recursively).\n\nBash's globstar is doublestar's inspiration and, as such, works similarly.\nNote that the doublestar must appear as a path component by itself. A pattern\nsuch as `/path**` is invalid and will be treated the same as `/path*`, but\n`/path*/**` should achieve the desired result. Additionally, `/path/**` will\nmatch all directories and files under the path directory, but `/path/**/` will\nonly match directories.\n\n## Installation\n\n**doublestar** can be installed via `go get`:\n\n```bash\ngo get github.com/bmatcuk/doublestar/v2\n```\n\nTo use it in your code, you must import it:\n\n```go\nimport \"github.com/bmatcuk/doublestar/v2\"\n```\n\n## Usage\n\n### Match\n\n```go\nfunc Match(pattern, name string) (bool, error)\n```\n\nMatch returns true if `name` matches the file name `pattern`\n([see below](#patterns)). `name` and `pattern` are split on forward slash (`/`)\ncharacters and may be relative or absolute.\n\nNote: `Match()` is meant to be a drop-in replacement for `path.Match()`. As\nsuch, it always uses `/` as the path separator. If you are writing code that\nwill run on systems where `/` is not the path separator (such as Windows), you\nwant to use `PathMatch()` (below) instead.\n\n\n### PathMatch\n\n```go\nfunc PathMatch(pattern, name string) (bool, error)\n```\n\nPathMatch returns true if `name` matches the file name `pattern`\n([see below](#patterns)). The difference between Match and PathMatch is that\nPathMatch will automatically use your system's path separator to split `name`\nand `pattern`.\n\n`PathMatch()` is meant to be a drop-in replacement for `filepath.Match()`.\n\n### Glob\n\n```go\nfunc Glob(pattern string) ([]string, error)\n```\n\nGlob finds all files and directories in the filesystem that match `pattern`\n([see below](#patterns)). `pattern` may be relative (to the current working\ndirectory), or absolute.\n\n`Glob()` is meant to be a drop-in replacement for `filepath.Glob()`.\n\n### Patterns\n\n**doublestar** supports the following special terms in the patterns:\n\nSpecial Terms | Meaning\n------------- | -------\n`*`           | matches any sequence of non-path-separators\n`**`          | matches any sequence of characters, including path separators\n`?`           | matches any single non-path-separator character\n`[class]`     | matches any single non-path-separator character against a class of characters ([see below](#character-classes))\n`{alt1,...}`  | matches a sequence of characters if one of the comma-separated alternatives matches\n\nAny character with a special meaning can be escaped with a backslash (`\\`).\n\nA mid-pattern doublestar (`**`) behaves like bash's globstar option: a pattern\nsuch as `path/to/**.txt` would return the same results as `path/to/*.txt`. The\npattern you're looking for is `path/to/**/*.txt`.\n\n#### Character Classes\n\nCharacter classes support the following:\n\nClass      | Meaning\n---------- | -------\n`[abc]`    | matches any single character within the set\n`[a-z]`    | matches any single character in the range\n`[^class]` | matches any single character which does *not* match the class\n\n### Abstracting the `os` package\n\n**doublestar** by default uses the `Open`, `Stat`, and `Lstat`, functions and\n`PathSeparator` value from the standard library's `os` package. To abstract\nthis, for example to be able to perform tests of Windows paths on Linux, or to\ninteroperate with your own filesystem code, it includes the functions `GlobOS`\nand `PathMatchOS` which are identical to `Glob` and `PathMatch` except that they\noperate on an `OS` interface:\n\n```go\ntype OS interface {\n    Lstat(name string) (os.FileInfo, error)\n    Open(name string) (*os.File, error)\n    PathSeparator() rune\n    Stat(name string) (os.FileInfo, error)\n}\n```\n\n`StandardOS` is a value that implements this interface by calling functions in\nthe standard library's `os` package.\n\n## License\n\n[MIT License](LICENSE)\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/v3/UPGRADING.md",
    "content": "# Upgrading from v2 to v3\n\nv3 introduced using `!` to negate character classes, in addition to `^`. If any\nof your patterns include a character class that starts with an exclamation mark\n(ie, `[!...]`), you'll need to update the pattern to escape or move the\nexclamation mark. Note that, like the caret (`^`), it only negates the\ncharacter class if it is the first character in the character class.\n\n# Upgrading from v1 to v2\n\nThe change from v1 to v2 was fairly minor: the return type of the `Open` method\non the `OS` interface was changed from `*os.File` to `File`, a new interface\nexported by doublestar. The new `File` interface only defines the functionality\ndoublestar actually needs (`io.Closer` and `Readdir`), making it easier to use\ndoublestar with [go-billy](https://github.com/src-d/go-billy),\n[afero](https://github.com/spf13/afero), or something similar. If you were\nusing this functionality, updating should be as easy as updating `Open's`\nreturn type, since `os.File` already implements `doublestar.File`.\n\nIf you weren't using this functionality, updating should be as easy as changing\nyour dependencies to point to v2.\n"
  },
  {
    "path": "vendor/github.com/bmatcuk/doublestar/v3/doublestar.go",
    "content": "package doublestar\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// File defines a subset of file operations\ntype File interface {\n\tio.Closer\n\tReaddir(count int) ([]os.FileInfo, error)\n}\n\n// An OS abstracts functions in the standard library's os package.\ntype OS interface {\n\tLstat(name string) (os.FileInfo, error)\n\tOpen(name string) (File, error)\n\tPathSeparator() rune\n\tStat(name string) (os.FileInfo, error)\n}\n\n// A standardOS implements OS by calling functions in the standard library's os\n// package.\ntype standardOS struct{}\n\nfunc (standardOS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) }\nfunc (standardOS) Open(name string) (File, error)         { return os.Open(name) }\nfunc (standardOS) PathSeparator() rune                    { return os.PathSeparator }\nfunc (standardOS) Stat(name string) (os.FileInfo, error)  { return os.Stat(name) }\n\n// StandardOS is a value that implements the OS interface by calling functions\n// in the standard libray's os package.\nvar StandardOS OS = standardOS{}\n\n// ErrBadPattern indicates a pattern was malformed.\nvar ErrBadPattern = path.ErrBadPattern\n\n// Find the first index of a rune in a string,\n// ignoring any times the rune is escaped using \"\\\".\nfunc indexRuneWithEscaping(s string, r rune) int {\n\tend := strings.IndexRune(s, r)\n\tif end == -1 || r == '\\\\' {\n\t\treturn end\n\t}\n\tif end > 0 && s[end-1] == '\\\\' {\n\t\tstart := end + utf8.RuneLen(r)\n\t\tend = indexRuneWithEscaping(s[start:], r)\n\t\tif end != -1 {\n\t\t\tend += start\n\t\t}\n\t}\n\treturn end\n}\n\n// Find the last index of a rune in a string,\n// ignoring any times the rune is escaped using \"\\\".\nfunc lastIndexRuneWithEscaping(s string, r rune) int {\n\tend := strings.LastIndex(s, string(r))\n\tif end == -1 {\n\t\treturn -1\n\t}\n\tif end > 0 && s[end-1] == '\\\\' {\n\t\tend = lastIndexRuneWithEscaping(s[:end-1], r)\n\t}\n\treturn end\n}\n\n// Find the index of the first instance of one of the unicode characters in\n// chars, ignoring any times those characters are escaped using \"\\\".\nfunc indexAnyWithEscaping(s, chars string) int {\n\tend := strings.IndexAny(s, chars)\n\tif end == -1 {\n\t\treturn -1\n\t}\n\tif end > 0 && s[end-1] == '\\\\' {\n\t\t_, adj := utf8.DecodeRuneInString(s[end:])\n\t\tstart := end + adj\n\t\tend = indexAnyWithEscaping(s[start:], chars)\n\t\tif end != -1 {\n\t\t\tend += start\n\t\t}\n\t}\n\treturn end\n}\n\n// Split a set of alternatives such as {alt1,alt2,...} and returns the index of\n// the rune after the closing curly brace. Respects nested alternatives and\n// escaped runes.\nfunc splitAlternatives(s string) (ret []string, idx int) {\n\tret = make([]string, 0, 2)\n\tidx = 0\n\tslen := len(s)\n\tbraceCnt := 1\n\tesc := false\n\tstart := 0\n\tfor braceCnt > 0 {\n\t\tif idx >= slen {\n\t\t\treturn nil, -1\n\t\t}\n\n\t\tsRune, adj := utf8.DecodeRuneInString(s[idx:])\n\t\tif esc {\n\t\t\tesc = false\n\t\t} else if sRune == '\\\\' {\n\t\t\tesc = true\n\t\t} else if sRune == '{' {\n\t\t\tbraceCnt++\n\t\t} else if sRune == '}' {\n\t\t\tbraceCnt--\n\t\t} else if sRune == ',' && braceCnt == 1 {\n\t\t\tret = append(ret, s[start:idx])\n\t\t\tstart = idx + adj\n\t\t}\n\n\t\tidx += adj\n\t}\n\tret = append(ret, s[start:idx-1])\n\treturn\n}\n\n// Returns true if the pattern is \"zero length\", meaning\n// it could match zero or more characters.\nfunc isZeroLengthPattern(pattern string) (ret bool, err error) {\n\t// * can match zero\n\tif pattern == \"\" || pattern == \"*\" || pattern == \"**\" {\n\t\treturn true, nil\n\t}\n\n\t// an alternative with zero length can match zero, for example {,x} - the\n\t// first alternative has zero length\n\tr, adj := utf8.DecodeRuneInString(pattern)\n\tif r == '{' {\n\t\toptions, endOptions := splitAlternatives(pattern[adj:])\n\t\tif endOptions == -1 {\n\t\t\treturn false, ErrBadPattern\n\t\t}\n\t\tif ret, err = isZeroLengthPattern(pattern[adj+endOptions:]); !ret || err != nil {\n\t\t\treturn\n\t\t}\n\t\tfor _, o := range options {\n\t\t\tif ret, err = isZeroLengthPattern(o); ret || err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\n// Match returns true if name matches the shell file name pattern.\n// The pattern syntax is:\n//\n//  pattern:\n//    { term }\n//  term:\n//    '*'         matches any sequence of non-path-separators\n//    '**'        matches any sequence of characters, including\n//                path separators.\n//    '?'         matches any single non-path-separator character\n//    '[' [ '^' '!' ] { character-range } ']'\n//          character class (must be non-empty)\n//    '{' { term } [ ',' { term } ... ] '}'\n//    c           matches character c (c != '*', '?', '\\\\', '[')\n//    '\\\\' c      matches character c\n//\n//  character-range:\n//    c           matches character c (c != '\\\\', '-', ']')\n//    '\\\\' c      matches character c\n//    lo '-' hi   matches character c for lo <= c <= hi\n//\n// Match requires pattern to match all of name, not just a substring.\n// The path-separator defaults to the '/' character. The only possible\n// returned error is ErrBadPattern, when pattern is malformed.\n//\n// Note: this is meant as a drop-in replacement for path.Match() which\n// always uses '/' as the path separator. If you want to support systems\n// which use a different path separator (such as Windows), what you want\n// is the PathMatch() function below.\n//\nfunc Match(pattern, name string) (bool, error) {\n\treturn doMatching(pattern, name, '/')\n}\n\n// PathMatch is like Match except that it uses your system's path separator.\n// For most systems, this will be '/'. However, for Windows, it would be '\\\\'.\n// Note that for systems where the path separator is '\\\\', escaping is\n// disabled.\n//\n// Note: this is meant as a drop-in replacement for filepath.Match().\n//\nfunc PathMatch(pattern, name string) (bool, error) {\n\treturn PathMatchOS(StandardOS, pattern, name)\n}\n\n// PathMatchOS is like PathMatch except that it uses vos's path separator.\nfunc PathMatchOS(vos OS, pattern, name string) (bool, error) {\n\tpattern = filepath.ToSlash(pattern)\n\treturn doMatching(pattern, name, vos.PathSeparator())\n}\n\nfunc doMatching(pattern, name string, separator rune) (matched bool, err error) {\n\t// check for some base-cases\n\tpatternLen, nameLen := len(pattern), len(name)\n\tif patternLen == 0 {\n\t\treturn nameLen == 0, nil\n\t} else if nameLen == 0 {\n\t\treturn isZeroLengthPattern(pattern)\n\t}\n\n\tseparatorAdj := utf8.RuneLen(separator)\n\n\tpatIdx := indexRuneWithEscaping(pattern, '/')\n\tlastPat := patIdx == -1\n\tif lastPat {\n\t\tpatIdx = len(pattern)\n\t}\n\tif pattern[:patIdx] == \"**\" {\n\t\t// if our last pattern component is a doublestar, we're done -\n\t\t// doublestar will match any remaining name components, if any.\n\t\tif lastPat {\n\t\t\treturn true, nil\n\t\t}\n\n\t\t// otherwise, try matching remaining components\n\t\tnameIdx := 0\n\t\tpatIdx += 1\n\t\tfor {\n\t\t\tif m, _ := doMatching(pattern[patIdx:], name[nameIdx:], separator); m {\n\t\t\t\treturn true, nil\n\t\t\t}\n\n\t\t\tnextNameIdx := 0\n\t\t\tif nextNameIdx = indexRuneWithEscaping(name[nameIdx:], separator); nextNameIdx == -1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnameIdx += separatorAdj + nextNameIdx\n\t\t}\n\t\treturn false, nil\n\t}\n\n\tnameIdx := indexRuneWithEscaping(name, separator)\n\tlastName := nameIdx == -1\n\tif lastName {\n\t\tnameIdx = nameLen\n\t}\n\n\tvar matches []string\n\tmatches, err = matchComponent(pattern, name[:nameIdx])\n\tif matches == nil || err != nil {\n\t\treturn\n\t}\n\tif len(matches) == 0 && lastName {\n\t\treturn true, nil\n\t}\n\n\tif !lastName {\n\t\tnameIdx += separatorAdj\n\t\tfor _, alt := range matches {\n\t\t\tmatched, err = doMatching(alt, name[nameIdx:], separator)\n\t\t\tif matched || err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false, nil\n}\n\n// Glob returns the names of all files matching pattern or nil\n// if there is no matching file. The syntax of pattern is the same\n// as in Match. The pattern may describe hierarchical names such as\n// /usr/*/bin/ed (assuming the Separator is '/').\n//\n// Glob ignores file system errors such as I/O errors reading directories.\n// The only possible returned error is ErrBadPattern, when pattern\n// is malformed.\n//\n// Your system path separator is automatically used. This means on\n// systems where the separator is '\\\\' (Windows), escaping will be\n// disabled.\n//\n// Note: this is meant as a drop-in replacement for filepath.Glob().\n//\nfunc Glob(pattern string) (matches []string, err error) {\n\treturn GlobOS(StandardOS, pattern)\n}\n\n// GlobOS is like Glob except that it operates on vos.\nfunc GlobOS(vos OS, pattern string) (matches []string, err error) {\n\tif len(pattern) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// if the pattern starts with alternatives, we need to handle that here - the\n\t// alternatives may be a mix of relative and absolute\n\tif pattern[0] == '{' {\n\t\toptions, endOptions := splitAlternatives(pattern[1:])\n\t\tif endOptions == -1 {\n\t\t\treturn nil, ErrBadPattern\n\t\t}\n\t\tfor _, o := range options {\n\t\t\tm, e := GlobOS(vos, o+pattern[endOptions+1:])\n\t\t\tif e != nil {\n\t\t\t\treturn nil, e\n\t\t\t}\n\t\t\tmatches = append(matches, m...)\n\t\t}\n\t\treturn matches, nil\n\t}\n\n\t// If the pattern is relative or absolute and we're on a non-Windows machine,\n\t// volumeName will be an empty string. If it is absolute and we're on a\n\t// Windows machine, volumeName will be a drive letter (\"C:\") for filesystem\n\t// paths or \\\\<server>\\<share> for UNC paths.\n\tisAbs := filepath.IsAbs(pattern) || pattern[0] == '\\\\' || pattern[0] == '/'\n\tvolumeName := filepath.VolumeName(pattern)\n\tisWindowsUNC := strings.HasPrefix(volumeName, `\\\\`)\n\tif isWindowsUNC || isAbs {\n\t\tstartIdx := len(volumeName) + 1\n\t\treturn doGlob(vos, fmt.Sprintf(\"%s%s\", volumeName, string(vos.PathSeparator())), filepath.ToSlash(pattern[startIdx:]), matches)\n\t}\n\n\t// otherwise, it's a relative pattern\n\treturn doGlob(vos, \".\", filepath.ToSlash(pattern), matches)\n}\n\n// Perform a glob\nfunc doGlob(vos OS, basedir, pattern string, matches []string) (m []string, e error) {\n\tm = matches\n\te = nil\n\n\t// if the pattern starts with any path components that aren't globbed (ie,\n\t// `path/to/glob*`), we can skip over the un-globbed components (`path/to` in\n\t// our example).\n\tglobIdx := indexAnyWithEscaping(pattern, \"*?[{\\\\\")\n\tif globIdx > 0 {\n\t\tglobIdx = lastIndexRuneWithEscaping(pattern[:globIdx], '/')\n\t} else if globIdx == -1 {\n\t\tglobIdx = lastIndexRuneWithEscaping(pattern, '/')\n\t}\n\tif globIdx > 0 {\n\t\tbasedir = filepath.Join(basedir, pattern[:globIdx])\n\t\tpattern = pattern[globIdx+1:]\n\t}\n\n\t// Lstat will return an error if the file/directory doesn't exist\n\tfi, err := vos.Lstat(basedir)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// if the pattern is empty, we've found a match\n\tif len(pattern) == 0 {\n\t\tm = append(m, basedir)\n\t\treturn\n\t}\n\n\t// otherwise, we need to check each item in the directory...\n\n\t// first, if basedir is a symlink, follow it...\n\tif (fi.Mode() & os.ModeSymlink) != 0 {\n\t\tfi, err = vos.Stat(basedir)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// confirm it's a directory...\n\tif !fi.IsDir() {\n\t\treturn\n\t}\n\n\tfiles, err := filesInDir(vos, basedir)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tsort.Slice(files, func(i, j int) bool { return files[i].Name() < files[j].Name() })\n\n\tslashIdx := indexRuneWithEscaping(pattern, '/')\n\tlastComponent := slashIdx == -1\n\tif lastComponent {\n\t\tslashIdx = len(pattern)\n\t}\n\tif pattern[:slashIdx] == \"**\" {\n\t\t// if the current component is a doublestar, we'll try depth-first\n\t\tfor _, file := range files {\n\t\t\t// if symlink, we may want to follow\n\t\t\tif (file.Mode() & os.ModeSymlink) != 0 {\n\t\t\t\tfile, err = vos.Stat(filepath.Join(basedir, file.Name()))\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif file.IsDir() {\n\t\t\t\t// recurse into directories\n\t\t\t\tif lastComponent {\n\t\t\t\t\tm = append(m, filepath.Join(basedir, file.Name()))\n\t\t\t\t}\n\t\t\t\tm, e = doGlob(vos, filepath.Join(basedir, file.Name()), pattern, m)\n\t\t\t} else if lastComponent {\n\t\t\t\t// if the pattern's last component is a doublestar, we match filenames, too\n\t\t\t\tm = append(m, filepath.Join(basedir, file.Name()))\n\t\t\t}\n\t\t}\n\t\tif lastComponent {\n\t\t\treturn // we're done\n\t\t}\n\n\t\tpattern = pattern[slashIdx+1:]\n\t}\n\n\t// check items in current directory and recurse\n\tvar match []string\n\tfor _, file := range files {\n\t\tmatch, e = matchComponent(pattern, file.Name())\n\t\tif e != nil {\n\t\t\treturn\n\t\t}\n\t\tif match != nil {\n\t\t\tif len(match) == 0 {\n\t\t\t\tm = append(m, filepath.Join(basedir, file.Name()))\n\t\t\t} else {\n\t\t\t\tfor _, alt := range match {\n\t\t\t\t\tm, e = doGlob(vos, filepath.Join(basedir, file.Name()), alt, m)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc filesInDir(vos OS, dirPath string) (files []os.FileInfo, e error) {\n\tdir, err := vos.Open(dirPath)\n\tif err != nil {\n\t\treturn nil, nil\n\t}\n\tdefer func() {\n\t\tif err := dir.Close(); e == nil {\n\t\t\te = err\n\t\t}\n\t}()\n\n\tfiles, err = dir.Readdir(-1)\n\tif err != nil {\n\t\treturn nil, nil\n\t}\n\n\treturn\n}\n\n// Attempt to match a single path component with a pattern. Note that the\n// pattern may include multiple components but that the \"name\" is just a single\n// path component. The return value is a slice of patterns that should be\n// checked against subsequent path components or nil, indicating that the\n// pattern does not match this path. It is assumed that pattern components are\n// separated by '/'\nfunc matchComponent(pattern, name string) ([]string, error) {\n\t// check for matches one rune at a time\n\tpatternLen, nameLen := len(pattern), len(name)\n\tpatIdx, nameIdx := 0, 0\n\tfor patIdx < patternLen && nameIdx < nameLen {\n\t\tpatRune, patAdj := utf8.DecodeRuneInString(pattern[patIdx:])\n\t\tnameRune, nameAdj := utf8.DecodeRuneInString(name[nameIdx:])\n\t\tif patRune == '/' {\n\t\t\tpatIdx++\n\t\t\tbreak\n\t\t} else if patRune == '\\\\' {\n\t\t\t// handle escaped runes, only if separator isn't '\\\\'\n\t\t\tpatIdx += patAdj\n\t\t\tpatRune, patAdj = utf8.DecodeRuneInString(pattern[patIdx:])\n\t\t\tif patRune == utf8.RuneError {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t} else if patRune == nameRune {\n\t\t\t\tpatIdx += patAdj\n\t\t\t\tnameIdx += nameAdj\n\t\t\t} else {\n\t\t\t\treturn nil, nil\n\t\t\t}\n\t\t} else if patRune == '*' {\n\t\t\t// handle stars - a star at the end of the pattern or before a separator\n\t\t\t// will always match the rest of the path component\n\t\t\tif patIdx += patAdj; patIdx >= patternLen {\n\t\t\t\treturn []string{}, nil\n\t\t\t}\n\t\t\tif patRune, patAdj = utf8.DecodeRuneInString(pattern[patIdx:]); patRune == '/' {\n\t\t\t\treturn []string{pattern[patIdx+patAdj:]}, nil\n\t\t\t}\n\n\t\t\t// check if we can make any matches\n\t\t\tfor ; nameIdx < nameLen; nameIdx += nameAdj {\n\t\t\t\tif m, e := matchComponent(pattern[patIdx:], name[nameIdx:]); m != nil || e != nil {\n\t\t\t\t\treturn m, e\n\t\t\t\t}\n\t\t\t\t_, nameAdj = utf8.DecodeRuneInString(name[nameIdx:])\n\t\t\t}\n\t\t\treturn nil, nil\n\t\t} else if patRune == '[' {\n\t\t\t// handle character sets\n\t\t\tpatIdx += patAdj\n\t\t\tendClass := indexRuneWithEscaping(pattern[patIdx:], ']')\n\t\t\tif endClass == -1 {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t}\n\t\t\tendClass += patIdx\n\t\t\tclassRunes := []rune(pattern[patIdx:endClass])\n\t\t\tclassRunesLen := len(classRunes)\n\t\t\tif classRunesLen > 0 {\n\t\t\t\tclassIdx := 0\n\t\t\t\tmatchClass := false\n\t\t\t\tnegate := classRunes[0] == '^' || classRunes[0] == '!'\n\t\t\t\tif negate {\n\t\t\t\t\tclassIdx++\n\t\t\t\t}\n\t\t\t\tfor classIdx < classRunesLen {\n\t\t\t\t\tlow := classRunes[classIdx]\n\t\t\t\t\tif low == '-' {\n\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t}\n\t\t\t\t\tclassIdx++\n\t\t\t\t\tif low == '\\\\' {\n\t\t\t\t\t\tif classIdx < classRunesLen {\n\t\t\t\t\t\t\tlow = classRunes[classIdx]\n\t\t\t\t\t\t\tclassIdx++\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\thigh := low\n\t\t\t\t\tif classIdx < classRunesLen && classRunes[classIdx] == '-' {\n\t\t\t\t\t\t// we have a range of runes\n\t\t\t\t\t\tif classIdx++; classIdx >= classRunesLen {\n\t\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t\t}\n\t\t\t\t\t\thigh = classRunes[classIdx]\n\t\t\t\t\t\tif high == '-' {\n\t\t\t\t\t\t\treturn nil, ErrBadPattern\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclassIdx++\n\t\t\t\t\t\tif high == '\\\\' {\n\t\t\t\t\t\t\tif classIdx < classRunesLen {\n\t\t\t\t\t\t\t\thigh = classRunes[classIdx]\n\t\t\t\t\t\t\t\tclassIdx++\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn nil, ErrBadPattern\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\tif low <= nameRune && nameRune <= high {\n\t\t\t\t\t\tmatchClass = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif matchClass == negate {\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t}\n\t\t\tpatIdx = endClass + 1\n\t\t\tnameIdx += nameAdj\n\t\t} else if patRune == '{' {\n\t\t\t// handle alternatives such as {alt1,alt2,...}\n\t\t\tpatIdx += patAdj\n\t\t\toptions, endOptions := splitAlternatives(pattern[patIdx:])\n\t\t\tif endOptions == -1 {\n\t\t\t\treturn nil, ErrBadPattern\n\t\t\t}\n\t\t\tpatIdx += endOptions\n\n\t\t\tresults := make([][]string, 0, len(options))\n\t\t\ttotalResults := 0\n\t\t\tfor _, o := range options {\n\t\t\t\tm, e := matchComponent(o+pattern[patIdx:], name[nameIdx:])\n\t\t\t\tif e != nil {\n\t\t\t\t\treturn nil, e\n\t\t\t\t}\n\t\t\t\tif m != nil {\n\t\t\t\t\tresults = append(results, m)\n\t\t\t\t\ttotalResults += len(m)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(results) > 0 {\n\t\t\t\tlst := make([]string, 0, totalResults)\n\t\t\t\tfor _, m := range results {\n\t\t\t\t\tlst = append(lst, m...)\n\t\t\t\t}\n\t\t\t\treturn lst, nil\n\t\t\t}\n\n\t\t\treturn nil, nil\n\t\t} else if patRune == '?' || patRune == nameRune {\n\t\t\t// handle single-rune wildcard\n\t\t\tpatIdx += patAdj\n\t\t\tnameIdx += nameAdj\n\t\t} else {\n\t\t\treturn nil, nil\n\t\t}\n\t}\n\tif nameIdx >= nameLen {\n\t\tif patIdx >= patternLen {\n\t\t\treturn []string{}, nil\n\t\t}\n\n\t\tpattern = pattern[patIdx:]\n\t\tslashIdx := indexRuneWithEscaping(pattern, '/')\n\t\ttestPattern := pattern\n\t\tif slashIdx >= 0 {\n\t\t\ttestPattern = pattern[:slashIdx]\n\t\t}\n\n\t\tzeroLength, err := isZeroLengthPattern(testPattern)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif zeroLength {\n\t\t\tif slashIdx == -1 {\n\t\t\t\treturn []string{}, nil\n\t\t\t} else {\n\t\t\t\treturn []string{pattern[slashIdx+1:]}, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, nil\n}\n"
  },
  {
    "path": "vendor/github.com/c4milo/unpackit/.editorconfig",
    "content": "root = true\n\n; Unix-style newlines with a newline ending every file\n[*]\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\ncharset = utf-8\n\n; Golang\n[*.go]\nindent_style = tab\nindent_size = 4\n\n; C\n[*.c]\nindent_style = space\nindent_size = 4\n\n; YAML\n[*.yaml]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": "vendor/github.com/c4milo/unpackit/.travis.yml",
    "content": "sudo: false\nlanguage: go\n\ngo:\n  - 1.8\n  - tip\n"
  },
  {
    "path": "vendor/github.com/c4milo/unpackit/AUTHORS",
    "content": "     3\tAlexandre Normand\n    48\tCamilo Aguilar\n     2\tDavid Siefert\n     1\tMatthias Kalb\n     1\tbogdannechyporenko\n"
  },
  {
    "path": "vendor/github.com/c4milo/unpackit/CONTRIBUTING.md",
    "content": "### Thanks for your interest in contributing to this project and for taking the time to read this guide.\n\n## Code of conduct\n\n*Taken from http://libvirt.org/governance.html with minor adjustments.*\n\nThe open source community covers people from a wide variety of countries, backgrounds and positions. This global diversity is a great strength for this project, but can also lead to communication issues, which may in turn cause unhappiness. To maximise happiness of the project community taken as a whole, all members (whether users, contributors or committers) are expected to abide by the project's code of conduct. At a high level the code can be summarized as \"be excellent to each other\". Expanding on this:\n\n**Be respectful:** disagreements between people are to be expected and are usually the sign of healthy debate and engagement. Disagreements can lead to frustration and even anger for some members. Turning to personal insults, intimidation or threatening behaviour does not improve the situation. Participants should thus take care to ensure all communications / interactions stay professional at all times.\n\n**Be considerate:** remember that the community has members with a diverse background many of whom have English as a second language. What might appear impolite, may simply be a result of a lack of knowledge of the English language. Bear in mind that actions will have an impact on other community members and the project as a whole, so take potential consequences into account before pursuing a course of action.\n\n**Be forgiving:** humans are fallible and as such prone to make mistakes and inexplicably change their positions at times. Don't assume that other members are acting with malicious intent. Be prepared to forgive people who make mistakes and assist each other in learning from them. Playing a blame game doesn't help anyone.\n\n## Issues\n\n* Before reporting an issue make sure you search first if anybody has already reported a similar issue and whether or not it has been fixed.\n* Make sure your issue report sufficiently details the problem.\n* Include code samples reproducing the issue.\n* Please do not derail or troll issues. Keep the discussion on topic and respect the Code of conduct.\n* If you want to tackle any open issue, make sure you let people know you are working on it.\n\n## Development workflow\n\nGo is unlike any other language in that it forces a specific development workflow and project structure. Trying to fight it is useless, frustrating and time consuming. So, you better be prepare to adapt your workflow when contributing to Go projects.\n\n### Prerequisites\n\n* **Go**: To install Go, please follow its installation guide at https://golang.org/doc/install\n* **Git:**\n   * **Debian-based distros:** `apt-get install git-core`\n   * **OSX:** `brew install git`\n\n### Pull Requests\n\n* Please be generous describing your changes.\n* Although it is highly suggested to include tests, they are not a hard requirement in order to get your contributions accepted.\n* Keep pull requets small so core developers can review them quickly.\n* Unlike other projects, we are not going to nitpick your contributions. If your pull request is correct, we are going to merge and address the small details by ourselves. There is no point on delaying contributions due to little and unimportant details.\n\n### Workflow for third-party code contributions\n\n* In Github, fork `https://github.com/c4milo/unpackit` to your own account\n* Get the package using \"go get\": `go get github.com/c4milo/unpackit`\n* Move to where the package was cloned: `cd $GOPATH/src/github.com/c4milo/unpackit`\n* Add a git remote pointing to your own fork: `git remote add downstream git@github.com:<your_account>/unpackit.git`\n* Create a branch for making your changes, then commit them.\n* Push changes to downstream repository, this is your own fork: `git push <mybranch> downstream`\n* In Github, from your fork, create the Pull Request and send it upstream.\n* You are done.\n\n\n### Workflow for core developers\n\nSince core developers usually have access to the upstream repository, there is no need for having a workflow like the one for thid-party contributors.\n\n* Get the package using \"go get\": `go get github.com/c4milo/unpackit`\n* Create a branch for making your changes, then commit them.\n* Push changes to the repository: `git push origin <mybranch>`\n* In Github, create the Pull Request from your branch to master.\n* Before merging into master, wait for at least two developers to code review your contribution.\n\n"
  },
  {
    "path": "vendor/github.com/c4milo/unpackit/LICENSE",
    "content": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n    means each individual or legal entity that creates, contributes to\n    the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n    means the combination of the Contributions of others (if any) used\n    by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n    means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n    means Source Code Form to which the initial Contributor has attached\n    the notice in Exhibit A, the Executable Form of such Source Code\n    Form, and Modifications of such Source Code Form, in each case\n    including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n    means\n\n    (a) that the initial Contributor has attached the notice described\n        in Exhibit B to the Covered Software; or\n\n    (b) that the Covered Software was made available under the terms of\n        version 1.1 or earlier of the License, but not also under the\n        terms of a Secondary License.\n\n1.6. \"Executable Form\"\n    means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n    means a work that combines Covered Software with other material, in \n    a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n    means this document.\n\n1.9. \"Licensable\"\n    means having the right to grant, to the maximum extent possible,\n    whether at the time of the initial grant or subsequently, any and\n    all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n    means any of the following:\n\n    (a) any file in Source Code Form that results from an addition to,\n        deletion from, or modification of the contents of Covered\n        Software; or\n\n    (b) any new file in Source Code Form that contains any Covered\n        Software.\n\n1.11. \"Patent Claims\" of a Contributor\n    means any patent claim(s), including without limitation, method,\n    process, and apparatus claims, in any patent Licensable by such\n    Contributor that would be infringed, but for the grant of the\n    License, by the making, using, selling, offering for sale, having\n    made, import, or transfer of either its Contributions or its\n    Contributor Version.\n\n1.12. \"Secondary License\"\n    means either the GNU General Public License, Version 2.0, the GNU\n    Lesser General Public License, Version 2.1, the GNU Affero General\n    Public License, Version 3.0, or any later versions of those\n    licenses.\n\n1.13. \"Source Code Form\"\n    means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n    means an individual or a legal entity exercising rights under this\n    License. For legal entities, \"You\" includes any entity that\n    controls, is controlled by, or is under common control with You. For\n    purposes of this definition, \"control\" means (a) the power, direct\n    or indirect, to cause the direction or management of such entity,\n    whether by contract or otherwise, or (b) ownership of more than\n    fifty percent (50%) of the outstanding shares or beneficial\n    ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n    Licensable by such Contributor to use, reproduce, make available,\n    modify, display, perform, distribute, and otherwise exploit its\n    Contributions, either on an unmodified basis, with Modifications, or\n    as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n    for sale, have made, import, and otherwise transfer either its\n    Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n    or\n\n(b) for infringements caused by: (i) Your and any other third party's\n    modifications of Covered Software, or (ii) the combination of its\n    Contributions with other software (except as part of its Contributor\n    Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n    its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n    Form, as described in Section 3.1, and You must inform recipients of\n    the Executable Form how they can obtain a copy of such Source Code\n    Form by reasonable means in a timely manner, at a charge no more\n    than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n    License, or sublicense it under different terms, provided that the\n    license for the Executable Form does not attempt to limit or alter\n    the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n*                                                                      *\n*  6. Disclaimer of Warranty                                           *\n*  -------------------------                                           *\n*                                                                      *\n*  Covered Software is provided under this License on an \"as is\"       *\n*  basis, without warranty of any kind, either expressed, implied, or  *\n*  statutory, including, without limitation, warranties that the       *\n*  Covered Software is free of defects, merchantable, fit for a        *\n*  particular purpose or non-infringing. The entire risk as to the     *\n*  quality and performance of the Covered Software is with You.        *\n*  Should any Covered Software prove defective in any respect, You     *\n*  (not any Contributor) assume the cost of any necessary servicing,   *\n*  repair, or correction. This disclaimer of warranty constitutes an   *\n*  essential part of this License. No use of any Covered Software is   *\n*  authorized under this License except under this disclaimer.         *\n*                                                                      *\n************************************************************************\n\n************************************************************************\n*                                                                      *\n*  7. Limitation of Liability                                          *\n*  --------------------------                                          *\n*                                                                      *\n*  Under no circumstances and under no legal theory, whether tort      *\n*  (including negligence), contract, or otherwise, shall any           *\n*  Contributor, or anyone who distributes Covered Software as          *\n*  permitted above, be liable to You for any direct, indirect,         *\n*  special, incidental, or consequential damages of any character      *\n*  including, without limitation, damages for lost profits, loss of    *\n*  goodwill, work stoppage, computer failure or malfunction, or any    *\n*  and all other commercial damages or losses, even if such party      *\n*  shall have been informed of the possibility of such damages. This   *\n*  limitation of liability shall not apply to liability for death or   *\n*  personal injury resulting from such party's negligence to the       *\n*  extent applicable law prohibits such limitation. Some               *\n*  jurisdictions do not allow the exclusion or limitation of           *\n*  incidental or consequential damages, so this exclusion and          *\n*  limitation may not apply to You.                                    *\n*                                                                      *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n  This Source Code Form is subject to the terms of the Mozilla Public\n  License, v. 2.0. If a copy of the MPL was not distributed with this\n  file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n  This Source Code Form is \"Incompatible With Secondary Licenses\", as\n  defined by the Mozilla Public License, v. 2.0.\n\n"
  },
  {
    "path": "vendor/github.com/c4milo/unpackit/README.md",
    "content": "# UnpackIt\n\n[![GoDoc](https://godoc.org/github.com/c4milo/unpackit?status.svg)](https://godoc.org/github.com/c4milo/unpackit)\n[![Build Status](https://travis-ci.org/c4milo/unpackit.svg?branch=master)](https://travis-ci.org/c4milo/unpackit)\n\nThis Go library allows you to easily unpack the following files using magic numbers:\n\n* tar.gz\n* tar.bzip2\n* tar.xz\n* zip\n* tar\n\n## Usage\n\nUnpack a file:\n\n```go\n    file, _ := os.Open(test.filepath)\n    destPath, err := unpackit.Unpack(file, tempDir)\n```\n\nUnpack a stream (such as a http.Response):\n\n```go\n    res, err := http.Get(url)\n    destPath, err := unpackit.Unpack(res.Body, tempDir)\n```\n\n"
  },
  {
    "path": "vendor/github.com/c4milo/unpackit/unpackit.go",
    "content": "// This Source Code Form is subject to the terms of the Mozilla Public\n// License, v. 2.0. If a copy of the MPL was not distributed with this\n// file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n// Package unpackit allows you to easily unpack *.tar.gz, *.tar.bzip2, *.tar.xz, *.zip and *.tar files.\n// There are not CGO involved nor hard dependencies of any type.\npackage unpackit\n\nimport (\n\t\"archive/tar\"\n\t\"archive/zip\"\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/dsnet/compress/bzip2\"\n\tgzip \"github.com/klauspost/pgzip\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/ulikunitz/xz\"\n)\n\nvar (\n\tmagicZIP  = []byte{0x50, 0x4b, 0x03, 0x04}\n\tmagicGZ   = []byte{0x1f, 0x8b}\n\tmagicBZIP = []byte{0x42, 0x5a}\n\tmagicTAR  = []byte{0x75, 0x73, 0x74, 0x61, 0x72} // at offset 257\n\tmagicXZ   = []byte{0xfd, 0x37, 0x7a, 0x58, 0x5a, 0x00}\n)\n\n// Check whether a file has the magic number for tar, gzip, bzip2 or zip files\n//\n// Note that this function does not advance the Reader.\n//\n// 50 4b 03 04 for pkzip format\n// 1f 8b for .gz format\n// 42 5a for .bzip format\n// 75 73 74 61 72 at offset 257 for tar files\n// fd 37 7a 58 5a 00 for .xz format\nfunc magicNumber(reader *bufio.Reader, offset int) (string, error) {\n\theaderBytes, err := reader.Peek(offset + 6)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tmagic := headerBytes[offset : offset+6]\n\n\tif bytes.Equal(magicTAR, magic[0:5]) {\n\t\treturn \"tar\", nil\n\t}\n\n\tif bytes.Equal(magicZIP, magic[0:4]) {\n\t\treturn \"zip\", nil\n\t}\n\n\tif bytes.Equal(magicGZ, magic[0:2]) {\n\t\treturn \"gzip\", nil\n\t} else if bytes.Equal(magicBZIP, magic[0:2]) {\n\t\treturn \"bzip\", nil\n\t}\n\n\tif bytes.Equal(magicXZ, magic) {\n\t\treturn \"xz\", nil\n\t}\n\n\treturn \"\", nil\n}\n\n// Unpack unpacks a compressed stream. Magic numbers are used to determine what\n// decompressor and/or unarchiver to use.\nfunc Unpack(reader io.Reader, destPath string) (string, error) {\n\tvar err error\n\tif destPath == \"\" {\n\t\tdestPath, err = ioutil.TempDir(os.TempDir(), \"unpackit-\")\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\n\t// Makes sure destPath exists\n\tif err := os.MkdirAll(destPath, 0740); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tr := bufio.NewReader(reader)\n\n\t// Reads magic number from the stream so we can better determine how to proceed\n\tftype, err := magicNumber(r, 0)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar decompressingReader *bufio.Reader\n\tswitch ftype {\n\tcase \"gzip\":\n\t\tgzr, err := gzip.NewReader(r)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tdefer func() {\n\t\t\tif err := gzr.Close(); err != nil {\n\t\t\t\tfmt.Printf(\"%+v\", errors.Wrapf(err, \"unpackit: failed closing gzip reader\"))\n\t\t\t}\n\t\t}()\n\n\t\tdecompressingReader = bufio.NewReader(gzr)\n\tcase \"xz\":\n\t\txzr, err := xz.NewReader(r)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tdecompressingReader = bufio.NewReader(xzr)\n\tcase \"bzip\":\n\t\tbr, err := bzip2.NewReader(r, nil)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\n\t\tdefer func() {\n\t\t\tif err := br.Close(); err != nil {\n\t\t\t\tfmt.Printf(\"%+v\", errors.Wrapf(err, \"unpackit: failed closing bzip2 reader\"))\n\t\t\t}\n\t\t}()\n\n\t\tdecompressingReader = bufio.NewReader(br)\n\tcase \"zip\":\n\t\t// Like TAR, ZIP is also an archiving format, therefore we can just return\n\t\t// after it finishes\n\t\treturn Unzip(r, destPath)\n\tdefault:\n\t\t// maybe it is a tarball file\n\t\tdecompressingReader = r\n\t}\n\n\t// Check magic number in offset 257 too see if this is also a TAR file\n\tftype, err = magicNumber(decompressingReader, 257)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif ftype == \"tar\" {\n\t\treturn Untar(decompressingReader, destPath)\n\t}\n\n\t// If it's not a TAR archive then save it to disk as is.\n\tdestRawFile := filepath.Join(destPath, sanitize(path.Base(\"unknown-pack\")))\n\n\t// Creates destination file\n\tdestFile, err := os.Create(destRawFile)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer func() {\n\t\tif err := destFile.Close(); err != nil {\n\t\t\tlog.Println(err)\n\t\t}\n\t}()\n\n\t// Copies data to destination file\n\tif _, err := io.Copy(destFile, decompressingReader); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn destPath, nil\n}\n\n// Unzip unpacks a ZIP stream. When given a os.File reader it will get its size without\n// reading the entire zip file in memory.\nfunc Unzip(r io.Reader, destPath string) (string, error) {\n\tvar (\n\t\tzr  *zip.Reader\n\t\terr error\n\t)\n\n\tif f, ok := r.(*os.File); ok {\n\t\tfstat, err := f.Stat()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tzr, err = zip.NewReader(f, fstat.Size())\n\t} else {\n\t\tdata, err := ioutil.ReadAll(r)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tmemReader := bytes.NewReader(data)\n\t\tzr, err = zip.NewReader(memReader, memReader.Size())\n\t}\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn unpackZip(zr, destPath)\n}\n\nfunc unpackZip(zr *zip.Reader, destPath string) (string, error) {\n\tfor _, f := range zr.File {\n\t\terr := unzipFile(f, destPath)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\treturn destPath, nil\n}\n\nfunc unzipFile(f *zip.File, destPath string) error {\n\tif f.FileInfo().IsDir() {\n\t\tif err := os.MkdirAll(filepath.Join(destPath, f.Name), f.Mode().Perm()); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\n\trc, err := f.Open()\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\tif err := rc.Close(); err != nil {\n\t\t\tlog.Println(err)\n\t\t}\n\t}()\n\n\tfilePath := sanitize(f.Name)\n\tdestPath = filepath.Join(destPath, filePath)\n\n\t// If directories were not included in the archive but are part of the file name,\n\t// we create them relative to the destination path.\n\tfileDir := filepath.Dir(destPath)\n\t_, err = os.Lstat(fileDir)\n\tif err != nil {\n\t\tif err := os.MkdirAll(fileDir, 0700); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfile, err := os.Create(destPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer func() {\n\t\tif err := file.Close(); err != nil {\n\t\t\tlog.Println(err)\n\t\t}\n\t}()\n\n\tif err := file.Chmod(f.Mode()); err != nil {\n\t\tlog.Printf(\"warn: failed setting file permissions for %q: %#v\", file.Name(), err)\n\t}\n\n\tif err := os.Chtimes(file.Name(), time.Now(), f.ModTime()); err != nil {\n\t\tlog.Printf(\"warn: failed setting file atime and mtime for %q: %#v\", file.Name(), err)\n\t}\n\n\tif _, err := io.CopyN(file, rc, int64(f.UncompressedSize64)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// Untar unarchives a TAR archive and returns the final destination path or an error\nfunc Untar(data io.Reader, destPath string) (string, error) {\n\t// Makes sure destPath exists\n\tif err := os.MkdirAll(destPath, 0740); err != nil {\n\t\treturn \"\", err\n\t}\n\n\ttr := tar.NewReader(data)\n\n\t// Iterate through the files in the archive.\n\trootdir := destPath\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\t// end of tar archive\n\t\t\tbreak\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn rootdir, err\n\t\t}\n\n\t\t// Skip pax_global_header with the commit ID this archive was created from\n\t\tif hdr.Name == \"pax_global_header\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tfp := filepath.Join(destPath, sanitize(hdr.Name))\n\t\tif hdr.FileInfo().IsDir() {\n\t\t\tif rootdir == destPath {\n\t\t\t\trootdir = fp\n\t\t\t}\n\n\t\t\tif err := os.MkdirAll(fp, os.FileMode(hdr.Mode)); err != nil {\n\t\t\t\treturn rootdir, err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t_, untarErr := untarFile(hdr, tr, fp, rootdir)\n\t\tif untarErr != nil {\n\t\t\treturn rootdir, untarErr\n\t\t}\n\t}\n\n\treturn rootdir, nil\n}\n\nfunc untarFile(hdr *tar.Header, tr *tar.Reader, fp, rootdir string) (string, error) {\n\tparentDir, _ := filepath.Split(fp)\n\n\tif err := os.MkdirAll(parentDir, 0740); err != nil {\n\t\treturn rootdir, err\n\t}\n\n\tfile, err := os.Create(fp)\n\tif err != nil {\n\t\treturn rootdir, err\n\t}\n\n\tdefer func() {\n\t\tif err := file.Close(); err != nil {\n\t\t\tlog.Println(err)\n\t\t}\n\t}()\n\n\tif err := file.Chmod(os.FileMode(hdr.Mode)); err != nil {\n\t\tlog.Printf(\"warn: failed setting file permissions for %q: %#v\", file.Name(), err)\n\t}\n\n\tif err := os.Chtimes(file.Name(), time.Now(), hdr.ModTime); err != nil {\n\t\tlog.Printf(\"warn: failed setting file atime and mtime for %q: %#v\", file.Name(), err)\n\t}\n\n\tif _, err := io.Copy(file, tr); err != nil {\n\t\treturn rootdir, err\n\t}\n\n\treturn rootdir, nil\n}\n\n// Sanitizes name to avoid overwriting sensitive system files when unarchiving\nfunc sanitize(name string) string {\n\t// Gets rid of volume drive label in Windows\n\tif len(name) > 1 && name[1] == ':' && runtime.GOOS == \"windows\" {\n\t\tname = name[2:]\n\t}\n\n\tname = filepath.Clean(name)\n\tname = filepath.ToSlash(name)\n\tfor strings.HasPrefix(name, \"../\") {\n\t\tname = name[3:]\n\t}\n\n\treturn name\n}\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/LICENSE.txt",
    "content": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/README.md",
    "content": "# xxhash\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/cespare/xxhash/v2.svg)](https://pkg.go.dev/github.com/cespare/xxhash/v2)\n[![Test](https://github.com/cespare/xxhash/actions/workflows/test.yml/badge.svg)](https://github.com/cespare/xxhash/actions/workflows/test.yml)\n\nxxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a\nhigh-quality hashing algorithm that is much faster than anything in the Go\nstandard library.\n\nThis package provides a straightforward API:\n\n```\nfunc Sum64(b []byte) uint64\nfunc Sum64String(s string) uint64\ntype Digest struct{ ... }\n    func New() *Digest\n```\n\nThe `Digest` type implements hash.Hash64. Its key methods are:\n\n```\nfunc (*Digest) Write([]byte) (int, error)\nfunc (*Digest) WriteString(string) (int, error)\nfunc (*Digest) Sum64() uint64\n```\n\nThe package is written with optimized pure Go and also contains even faster\nassembly implementations for amd64 and arm64. If desired, the `purego` build tag\nopts into using the Go code even on those architectures.\n\n[xxHash]: http://cyan4973.github.io/xxHash/\n\n## Compatibility\n\nThis package is in a module and the latest code is in version 2 of the module.\nYou need a version of Go with at least \"minimal module compatibility\" to use\ngithub.com/cespare/xxhash/v2:\n\n* 1.9.7+ for Go 1.9\n* 1.10.3+ for Go 1.10\n* Go 1.11 or later\n\nI recommend using the latest release of Go.\n\n## Benchmarks\n\nHere are some quick benchmarks comparing the pure-Go and assembly\nimplementations of Sum64.\n\n| input size | purego    | asm       |\n| ---------- | --------- | --------- |\n| 4 B        |  1.3 GB/s |  1.2 GB/s |\n| 16 B       |  2.9 GB/s |  3.5 GB/s |\n| 100 B      |  6.9 GB/s |  8.1 GB/s |\n| 4 KB       | 11.7 GB/s | 16.7 GB/s |\n| 10 MB      | 12.0 GB/s | 17.3 GB/s |\n\nThese numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C\nCPU using the following commands under Go 1.19.2:\n\n```\nbenchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')\nbenchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')\n```\n\n## Projects using this package\n\n- [InfluxDB](https://github.com/influxdata/influxdb)\n- [Prometheus](https://github.com/prometheus/prometheus)\n- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)\n- [FreeCache](https://github.com/coocood/freecache)\n- [FastCache](https://github.com/VictoriaMetrics/fastcache)\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/testall.sh",
    "content": "#!/bin/bash\nset -eu -o pipefail\n\n# Small convenience script for running the tests with various combinations of\n# arch/tags. This assumes we're running on amd64 and have qemu available.\n\ngo test ./...\ngo test -tags purego ./...\nGOARCH=arm64 go test\nGOARCH=arm64 go test -tags purego\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash.go",
    "content": "// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described\n// at http://cyan4973.github.io/xxHash/.\npackage xxhash\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math/bits\"\n)\n\nconst (\n\tprime1 uint64 = 11400714785074694791\n\tprime2 uint64 = 14029467366897019727\n\tprime3 uint64 = 1609587929392839161\n\tprime4 uint64 = 9650029242287828579\n\tprime5 uint64 = 2870177450012600261\n)\n\n// Store the primes in an array as well.\n//\n// The consts are used when possible in Go code to avoid MOVs but we need a\n// contiguous array of the assembly code.\nvar primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}\n\n// Digest implements hash.Hash64.\ntype Digest struct {\n\tv1    uint64\n\tv2    uint64\n\tv3    uint64\n\tv4    uint64\n\ttotal uint64\n\tmem   [32]byte\n\tn     int // how much of mem is used\n}\n\n// New creates a new Digest that computes the 64-bit xxHash algorithm.\nfunc New() *Digest {\n\tvar d Digest\n\td.Reset()\n\treturn &d\n}\n\n// Reset clears the Digest's state so that it can be reused.\nfunc (d *Digest) Reset() {\n\td.v1 = primes[0] + prime2\n\td.v2 = prime2\n\td.v3 = 0\n\td.v4 = -primes[0]\n\td.total = 0\n\td.n = 0\n}\n\n// Size always returns 8 bytes.\nfunc (d *Digest) Size() int { return 8 }\n\n// BlockSize always returns 32 bytes.\nfunc (d *Digest) BlockSize() int { return 32 }\n\n// Write adds more data to d. It always returns len(b), nil.\nfunc (d *Digest) Write(b []byte) (n int, err error) {\n\tn = len(b)\n\td.total += uint64(n)\n\n\tmemleft := d.mem[d.n&(len(d.mem)-1):]\n\n\tif d.n+n < 32 {\n\t\t// This new data doesn't even fill the current block.\n\t\tcopy(memleft, b)\n\t\td.n += n\n\t\treturn\n\t}\n\n\tif d.n > 0 {\n\t\t// Finish off the partial block.\n\t\tc := copy(memleft, b)\n\t\td.v1 = round(d.v1, u64(d.mem[0:8]))\n\t\td.v2 = round(d.v2, u64(d.mem[8:16]))\n\t\td.v3 = round(d.v3, u64(d.mem[16:24]))\n\t\td.v4 = round(d.v4, u64(d.mem[24:32]))\n\t\tb = b[c:]\n\t\td.n = 0\n\t}\n\n\tif len(b) >= 32 {\n\t\t// One or more full blocks left.\n\t\tnw := writeBlocks(d, b)\n\t\tb = b[nw:]\n\t}\n\n\t// Store any remaining partial block.\n\tcopy(d.mem[:], b)\n\td.n = len(b)\n\n\treturn\n}\n\n// Sum appends the current hash to b and returns the resulting slice.\nfunc (d *Digest) Sum(b []byte) []byte {\n\ts := d.Sum64()\n\treturn append(\n\t\tb,\n\t\tbyte(s>>56),\n\t\tbyte(s>>48),\n\t\tbyte(s>>40),\n\t\tbyte(s>>32),\n\t\tbyte(s>>24),\n\t\tbyte(s>>16),\n\t\tbyte(s>>8),\n\t\tbyte(s),\n\t)\n}\n\n// Sum64 returns the current hash.\nfunc (d *Digest) Sum64() uint64 {\n\tvar h uint64\n\n\tif d.total >= 32 {\n\t\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = d.v3 + prime5\n\t}\n\n\th += d.total\n\n\tb := d.mem[:d.n&(len(d.mem)-1)]\n\tfor ; len(b) >= 8; b = b[8:] {\n\t\tk1 := round(0, u64(b[:8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif len(b) >= 4 {\n\t\th ^= uint64(u32(b[:4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\tb = b[4:]\n\t}\n\tfor ; len(b) > 0; b = b[1:] {\n\t\th ^= uint64(b[0]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nconst (\n\tmagic         = \"xxh\\x06\"\n\tmarshaledSize = len(magic) + 8*5 + 32\n)\n\n// MarshalBinary implements the encoding.BinaryMarshaler interface.\nfunc (d *Digest) MarshalBinary() ([]byte, error) {\n\tb := make([]byte, 0, marshaledSize)\n\tb = append(b, magic...)\n\tb = appendUint64(b, d.v1)\n\tb = appendUint64(b, d.v2)\n\tb = appendUint64(b, d.v3)\n\tb = appendUint64(b, d.v4)\n\tb = appendUint64(b, d.total)\n\tb = append(b, d.mem[:d.n]...)\n\tb = b[:len(b)+len(d.mem)-d.n]\n\treturn b, nil\n}\n\n// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.\nfunc (d *Digest) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic) || string(b[:len(magic)]) != magic {\n\t\treturn errors.New(\"xxhash: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize {\n\t\treturn errors.New(\"xxhash: invalid hash state size\")\n\t}\n\tb = b[len(magic):]\n\tb, d.v1 = consumeUint64(b)\n\tb, d.v2 = consumeUint64(b)\n\tb, d.v3 = consumeUint64(b)\n\tb, d.v4 = consumeUint64(b)\n\tb, d.total = consumeUint64(b)\n\tcopy(d.mem[:], b)\n\td.n = int(d.total % uint64(len(d.mem)))\n\treturn nil\n}\n\nfunc appendUint64(b []byte, x uint64) []byte {\n\tvar a [8]byte\n\tbinary.LittleEndian.PutUint64(a[:], x)\n\treturn append(b, a[:]...)\n}\n\nfunc consumeUint64(b []byte) ([]byte, uint64) {\n\tx := u64(b)\n\treturn b[8:], x\n}\n\nfunc u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }\nfunc u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }\n\nfunc round(acc, input uint64) uint64 {\n\tacc += input * prime2\n\tacc = rol31(acc)\n\tacc *= prime1\n\treturn acc\n}\n\nfunc mergeRound(acc, val uint64) uint64 {\n\tval = round(0, val)\n\tacc ^= val\n\tacc = acc*prime1 + prime4\n\treturn acc\n}\n\nfunc rol1(x uint64) uint64  { return bits.RotateLeft64(x, 1) }\nfunc rol7(x uint64) uint64  { return bits.RotateLeft64(x, 7) }\nfunc rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) }\nfunc rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) }\nfunc rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) }\nfunc rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) }\nfunc rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) }\nfunc rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) }\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s",
    "content": "//go:build !appengine && gc && !purego\n// +build !appengine\n// +build gc\n// +build !purego\n\n#include \"textflag.h\"\n\n// Registers:\n#define h      AX\n#define d      AX\n#define p      SI // pointer to advance through b\n#define n      DX\n#define end    BX // loop end\n#define v1     R8\n#define v2     R9\n#define v3     R10\n#define v4     R11\n#define x      R12\n#define prime1 R13\n#define prime2 R14\n#define prime4 DI\n\n#define round(acc, x) \\\n\tIMULQ prime2, x   \\\n\tADDQ  x, acc      \\\n\tROLQ  $31, acc    \\\n\tIMULQ prime1, acc\n\n// round0 performs the operation x = round(0, x).\n#define round0(x) \\\n\tIMULQ prime2, x \\\n\tROLQ  $31, x    \\\n\tIMULQ prime1, x\n\n// mergeRound applies a merge round on the two registers acc and x.\n// It assumes that prime1, prime2, and prime4 have been loaded.\n#define mergeRound(acc, x) \\\n\tround0(x)         \\\n\tXORQ  x, acc      \\\n\tIMULQ prime1, acc \\\n\tADDQ  prime4, acc\n\n// blockLoop processes as many 32-byte blocks as possible,\n// updating v1, v2, v3, and v4. It assumes that there is at least one block\n// to process.\n#define blockLoop() \\\nloop:  \\\n\tMOVQ +0(p), x  \\\n\tround(v1, x)   \\\n\tMOVQ +8(p), x  \\\n\tround(v2, x)   \\\n\tMOVQ +16(p), x \\\n\tround(v3, x)   \\\n\tMOVQ +24(p), x \\\n\tround(v4, x)   \\\n\tADDQ $32, p    \\\n\tCMPQ p, end    \\\n\tJLE  loop\n\n// func Sum64(b []byte) uint64\nTEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32\n\t// Load fixed primes.\n\tMOVQ ·primes+0(SB), prime1\n\tMOVQ ·primes+8(SB), prime2\n\tMOVQ ·primes+24(SB), prime4\n\n\t// Load slice.\n\tMOVQ b_base+0(FP), p\n\tMOVQ b_len+8(FP), n\n\tLEAQ (p)(n*1), end\n\n\t// The first loop limit will be len(b)-32.\n\tSUBQ $32, end\n\n\t// Check whether we have at least one block.\n\tCMPQ n, $32\n\tJLT  noBlocks\n\n\t// Set up initial state (v1, v2, v3, v4).\n\tMOVQ prime1, v1\n\tADDQ prime2, v1\n\tMOVQ prime2, v2\n\tXORQ v3, v3\n\tXORQ v4, v4\n\tSUBQ prime1, v4\n\n\tblockLoop()\n\n\tMOVQ v1, h\n\tROLQ $1, h\n\tMOVQ v2, x\n\tROLQ $7, x\n\tADDQ x, h\n\tMOVQ v3, x\n\tROLQ $12, x\n\tADDQ x, h\n\tMOVQ v4, x\n\tROLQ $18, x\n\tADDQ x, h\n\n\tmergeRound(h, v1)\n\tmergeRound(h, v2)\n\tmergeRound(h, v3)\n\tmergeRound(h, v4)\n\n\tJMP afterBlocks\n\nnoBlocks:\n\tMOVQ ·primes+32(SB), h\n\nafterBlocks:\n\tADDQ n, h\n\n\tADDQ $24, end\n\tCMPQ p, end\n\tJG   try4\n\nloop8:\n\tMOVQ  (p), x\n\tADDQ  $8, p\n\tround0(x)\n\tXORQ  x, h\n\tROLQ  $27, h\n\tIMULQ prime1, h\n\tADDQ  prime4, h\n\n\tCMPQ p, end\n\tJLE  loop8\n\ntry4:\n\tADDQ $4, end\n\tCMPQ p, end\n\tJG   try1\n\n\tMOVL  (p), x\n\tADDQ  $4, p\n\tIMULQ prime1, x\n\tXORQ  x, h\n\n\tROLQ  $23, h\n\tIMULQ prime2, h\n\tADDQ  ·primes+16(SB), h\n\ntry1:\n\tADDQ $4, end\n\tCMPQ p, end\n\tJGE  finalize\n\nloop1:\n\tMOVBQZX (p), x\n\tADDQ    $1, p\n\tIMULQ   ·primes+32(SB), x\n\tXORQ    x, h\n\tROLQ    $11, h\n\tIMULQ   prime1, h\n\n\tCMPQ p, end\n\tJL   loop1\n\nfinalize:\n\tMOVQ  h, x\n\tSHRQ  $33, x\n\tXORQ  x, h\n\tIMULQ prime2, h\n\tMOVQ  h, x\n\tSHRQ  $29, x\n\tXORQ  x, h\n\tIMULQ ·primes+16(SB), h\n\tMOVQ  h, x\n\tSHRQ  $32, x\n\tXORQ  x, h\n\n\tMOVQ h, ret+24(FP)\n\tRET\n\n// func writeBlocks(d *Digest, b []byte) int\nTEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40\n\t// Load fixed primes needed for round.\n\tMOVQ ·primes+0(SB), prime1\n\tMOVQ ·primes+8(SB), prime2\n\n\t// Load slice.\n\tMOVQ b_base+8(FP), p\n\tMOVQ b_len+16(FP), n\n\tLEAQ (p)(n*1), end\n\tSUBQ $32, end\n\n\t// Load vN from d.\n\tMOVQ s+0(FP), d\n\tMOVQ 0(d), v1\n\tMOVQ 8(d), v2\n\tMOVQ 16(d), v3\n\tMOVQ 24(d), v4\n\n\t// We don't need to check the loop condition here; this function is\n\t// always called with at least one block of data to process.\n\tblockLoop()\n\n\t// Copy vN back to d.\n\tMOVQ v1, 0(d)\n\tMOVQ v2, 8(d)\n\tMOVQ v3, 16(d)\n\tMOVQ v4, 24(d)\n\n\t// The number of bytes written is p minus the old base pointer.\n\tSUBQ b_base+8(FP), p\n\tMOVQ p, ret+32(FP)\n\n\tRET\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s",
    "content": "//go:build !appengine && gc && !purego\n// +build !appengine\n// +build gc\n// +build !purego\n\n#include \"textflag.h\"\n\n// Registers:\n#define digest\tR1\n#define h\tR2 // return value\n#define p\tR3 // input pointer\n#define n\tR4 // input length\n#define nblocks\tR5 // n / 32\n#define prime1\tR7\n#define prime2\tR8\n#define prime3\tR9\n#define prime4\tR10\n#define prime5\tR11\n#define v1\tR12\n#define v2\tR13\n#define v3\tR14\n#define v4\tR15\n#define x1\tR20\n#define x2\tR21\n#define x3\tR22\n#define x4\tR23\n\n#define round(acc, x) \\\n\tMADD prime2, acc, x, acc \\\n\tROR  $64-31, acc         \\\n\tMUL  prime1, acc\n\n// round0 performs the operation x = round(0, x).\n#define round0(x) \\\n\tMUL prime2, x \\\n\tROR $64-31, x \\\n\tMUL prime1, x\n\n#define mergeRound(acc, x) \\\n\tround0(x)                     \\\n\tEOR  x, acc                   \\\n\tMADD acc, prime4, prime1, acc\n\n// blockLoop processes as many 32-byte blocks as possible,\n// updating v1, v2, v3, and v4. It assumes that n >= 32.\n#define blockLoop() \\\n\tLSR     $5, n, nblocks  \\\n\tPCALIGN $16             \\\n\tloop:                   \\\n\tLDP.P   16(p), (x1, x2) \\\n\tLDP.P   16(p), (x3, x4) \\\n\tround(v1, x1)           \\\n\tround(v2, x2)           \\\n\tround(v3, x3)           \\\n\tround(v4, x4)           \\\n\tSUB     $1, nblocks     \\\n\tCBNZ    nblocks, loop\n\n// func Sum64(b []byte) uint64\nTEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32\n\tLDP b_base+0(FP), (p, n)\n\n\tLDP  ·primes+0(SB), (prime1, prime2)\n\tLDP  ·primes+16(SB), (prime3, prime4)\n\tMOVD ·primes+32(SB), prime5\n\n\tCMP  $32, n\n\tCSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 }\n\tBLT  afterLoop\n\n\tADD  prime1, prime2, v1\n\tMOVD prime2, v2\n\tMOVD $0, v3\n\tNEG  prime1, v4\n\n\tblockLoop()\n\n\tROR $64-1, v1, x1\n\tROR $64-7, v2, x2\n\tADD x1, x2\n\tROR $64-12, v3, x3\n\tROR $64-18, v4, x4\n\tADD x3, x4\n\tADD x2, x4, h\n\n\tmergeRound(h, v1)\n\tmergeRound(h, v2)\n\tmergeRound(h, v3)\n\tmergeRound(h, v4)\n\nafterLoop:\n\tADD n, h\n\n\tTBZ   $4, n, try8\n\tLDP.P 16(p), (x1, x2)\n\n\tround0(x1)\n\n\t// NOTE: here and below, sequencing the EOR after the ROR (using a\n\t// rotated register) is worth a small but measurable speedup for small\n\t// inputs.\n\tROR  $64-27, h\n\tEOR  x1 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\n\tround0(x2)\n\tROR  $64-27, h\n\tEOR  x2 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\ntry8:\n\tTBZ    $3, n, try4\n\tMOVD.P 8(p), x1\n\n\tround0(x1)\n\tROR  $64-27, h\n\tEOR  x1 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\ntry4:\n\tTBZ     $2, n, try2\n\tMOVWU.P 4(p), x2\n\n\tMUL  prime1, x2\n\tROR  $64-23, h\n\tEOR  x2 @> 64-23, h, h\n\tMADD h, prime3, prime2, h\n\ntry2:\n\tTBZ     $1, n, try1\n\tMOVHU.P 2(p), x3\n\tAND     $255, x3, x1\n\tLSR     $8, x3, x2\n\n\tMUL prime5, x1\n\tROR $64-11, h\n\tEOR x1 @> 64-11, h, h\n\tMUL prime1, h\n\n\tMUL prime5, x2\n\tROR $64-11, h\n\tEOR x2 @> 64-11, h, h\n\tMUL prime1, h\n\ntry1:\n\tTBZ   $0, n, finalize\n\tMOVBU (p), x4\n\n\tMUL prime5, x4\n\tROR $64-11, h\n\tEOR x4 @> 64-11, h, h\n\tMUL prime1, h\n\nfinalize:\n\tEOR h >> 33, h\n\tMUL prime2, h\n\tEOR h >> 29, h\n\tMUL prime3, h\n\tEOR h >> 32, h\n\n\tMOVD h, ret+24(FP)\n\tRET\n\n// func writeBlocks(d *Digest, b []byte) int\nTEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40\n\tLDP ·primes+0(SB), (prime1, prime2)\n\n\t// Load state. Assume v[1-4] are stored contiguously.\n\tMOVD d+0(FP), digest\n\tLDP  0(digest), (v1, v2)\n\tLDP  16(digest), (v3, v4)\n\n\tLDP b_base+8(FP), (p, n)\n\n\tblockLoop()\n\n\t// Store updated state.\n\tSTP (v1, v2), 0(digest)\n\tSTP (v3, v4), 16(digest)\n\n\tBIC  $31, n\n\tMOVD n, ret+32(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_asm.go",
    "content": "//go:build (amd64 || arm64) && !appengine && gc && !purego\n// +build amd64 arm64\n// +build !appengine\n// +build gc\n// +build !purego\n\npackage xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b.\n//\n//go:noescape\nfunc Sum64(b []byte) uint64\n\n//go:noescape\nfunc writeBlocks(d *Digest, b []byte) int\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_other.go",
    "content": "//go:build (!amd64 && !arm64) || appengine || !gc || purego\n// +build !amd64,!arm64 appengine !gc purego\n\npackage xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b.\nfunc Sum64(b []byte) uint64 {\n\t// A simpler version would be\n\t//   d := New()\n\t//   d.Write(b)\n\t//   return d.Sum64()\n\t// but this is faster, particularly for small inputs.\n\n\tn := len(b)\n\tvar h uint64\n\n\tif n >= 32 {\n\t\tv1 := primes[0] + prime2\n\t\tv2 := prime2\n\t\tv3 := uint64(0)\n\t\tv4 := -primes[0]\n\t\tfor len(b) >= 32 {\n\t\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\t\tb = b[32:len(b):len(b)]\n\t\t}\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = prime5\n\t}\n\n\th += uint64(n)\n\n\tfor ; len(b) >= 8; b = b[8:] {\n\t\tk1 := round(0, u64(b[:8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif len(b) >= 4 {\n\t\th ^= uint64(u32(b[:4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\tb = b[4:]\n\t}\n\tfor ; len(b) > 0; b = b[1:] {\n\t\th ^= uint64(b[0]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nfunc writeBlocks(d *Digest, b []byte) int {\n\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\tn := len(b)\n\tfor len(b) >= 32 {\n\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\tb = b[32:len(b):len(b)]\n\t}\n\td.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4\n\treturn n - len(b)\n}\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_safe.go",
    "content": "//go:build appengine\n// +build appengine\n\n// This file contains the safe implementations of otherwise unsafe-using code.\n\npackage xxhash\n\n// Sum64String computes the 64-bit xxHash digest of s.\nfunc Sum64String(s string) uint64 {\n\treturn Sum64([]byte(s))\n}\n\n// WriteString adds more data to d. It always returns len(s), nil.\nfunc (d *Digest) WriteString(s string) (n int, err error) {\n\treturn d.Write([]byte(s))\n}\n"
  },
  {
    "path": "vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go",
    "content": "//go:build !appengine\n// +build !appengine\n\n// This file encapsulates usage of unsafe.\n// xxhash_safe.go contains the safe implementations.\n\npackage xxhash\n\nimport (\n\t\"unsafe\"\n)\n\n// In the future it's possible that compiler optimizations will make these\n// XxxString functions unnecessary by realizing that calls such as\n// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205.\n// If that happens, even if we keep these functions they can be replaced with\n// the trivial safe code.\n\n// NOTE: The usual way of doing an unsafe string-to-[]byte conversion is:\n//\n//   var b []byte\n//   bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))\n//   bh.Data = (*reflect.StringHeader)(unsafe.Pointer(&s)).Data\n//   bh.Len = len(s)\n//   bh.Cap = len(s)\n//\n// Unfortunately, as of Go 1.15.3 the inliner's cost model assigns a high enough\n// weight to this sequence of expressions that any function that uses it will\n// not be inlined. Instead, the functions below use a different unsafe\n// conversion designed to minimize the inliner weight and allow both to be\n// inlined. There is also a test (TestInlining) which verifies that these are\n// inlined.\n//\n// See https://github.com/golang/go/issues/42739 for discussion.\n\n// Sum64String computes the 64-bit xxHash digest of s.\n// It may be faster than Sum64([]byte(s)) by avoiding a copy.\nfunc Sum64String(s string) uint64 {\n\tb := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))\n\treturn Sum64(b)\n}\n\n// WriteString adds more data to d. It always returns len(s), nil.\n// It may be faster than Write([]byte(s)) by avoiding a copy.\nfunc (d *Digest) WriteString(s string) (n int, err error) {\n\td.Write(*(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)})))\n\t// d.Write always returns len(s), nil.\n\t// Ignoring the return output and returning these fixed values buys a\n\t// savings of 6 in the inliner's cost model.\n\treturn len(s), nil\n}\n\n// sliceHeader is similar to reflect.SliceHeader, but it assumes that the layout\n// of the first two words is the same as the layout of a string.\ntype sliceHeader struct {\n\ts   string\n\tcap int\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/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": "vendor/github.com/compose-spec/compose-go/NOTICE",
    "content": "The Compose Specification\nCopyright 2020 The Compose Specification Authors\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/errdefs/errors.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage errdefs\n\nimport \"errors\"\n\nvar (\n\t// ErrNotFound is returned when an object is not found\n\tErrNotFound = errors.New(\"not found\")\n\n\t// ErrInvalid is returned when a compose project is invalid\n\tErrInvalid = errors.New(\"invalid compose project\")\n\n\t// ErrUnsupported is returned when a compose project uses an unsupported attribute\n\tErrUnsupported = errors.New(\"unsupported attribute\")\n\n\t// ErrIncompatible is returned when a compose project uses an incompatible attribute\n\tErrIncompatible = errors.New(\"incompatible attribute\")\n)\n\n// IsNotFoundError returns true if the unwrapped error is ErrNotFound\nfunc IsNotFoundError(err error) bool {\n\treturn errors.Is(err, ErrNotFound)\n}\n\n// IsInvalidError returns true if the unwrapped error is ErrInvalid\nfunc IsInvalidError(err error) bool {\n\treturn errors.Is(err, ErrInvalid)\n}\n\n// IsUnsupportedError returns true if the unwrapped error is ErrUnsupported\nfunc IsUnsupportedError(err error) bool {\n\treturn errors.Is(err, ErrUnsupported)\n}\n\n// IsIncompatibleError returns true if the unwrapped error is ErrIncompatible\nfunc IsIncompatibleError(err error) bool {\n\treturn errors.Is(err, ErrIncompatible)\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/interpolation/interpolation.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage interpolation\n\nimport (\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/compose-spec/compose-go/template\"\n\t\"github.com/pkg/errors\"\n)\n\n// Options supported by Interpolate\ntype Options struct {\n\t// LookupValue from a key\n\tLookupValue LookupValue\n\t// TypeCastMapping maps key paths to functions to cast to a type\n\tTypeCastMapping map[Path]Cast\n\t// Substitution function to use\n\tSubstitute func(string, template.Mapping) (string, error)\n}\n\n// LookupValue is a function which maps from variable names to values.\n// Returns the value as a string and a bool indicating whether\n// the value is present, to distinguish between an empty string\n// and the absence of a value.\ntype LookupValue func(key string) (string, bool)\n\n// Cast a value to a new type, or return an error if the value can't be cast\ntype Cast func(value string) (interface{}, error)\n\n// Interpolate replaces variables in a string with the values from a mapping\nfunc Interpolate(config map[string]interface{}, opts Options) (map[string]interface{}, error) {\n\tif opts.LookupValue == nil {\n\t\topts.LookupValue = os.LookupEnv\n\t}\n\tif opts.TypeCastMapping == nil {\n\t\topts.TypeCastMapping = make(map[Path]Cast)\n\t}\n\tif opts.Substitute == nil {\n\t\topts.Substitute = template.Substitute\n\t}\n\n\tout := map[string]interface{}{}\n\n\tfor key, value := range config {\n\t\tinterpolatedValue, err := recursiveInterpolate(value, NewPath(key), opts)\n\t\tif err != nil {\n\t\t\treturn out, err\n\t\t}\n\t\tout[key] = interpolatedValue\n\t}\n\n\treturn out, nil\n}\n\nfunc recursiveInterpolate(value interface{}, path Path, opts Options) (interface{}, error) {\n\tswitch value := value.(type) {\n\tcase string:\n\t\tnewValue, err := opts.Substitute(value, template.Mapping(opts.LookupValue))\n\t\tif err != nil || newValue == value {\n\t\t\treturn value, newPathError(path, err)\n\t\t}\n\t\tcaster, ok := opts.getCasterForPath(path)\n\t\tif !ok {\n\t\t\treturn newValue, nil\n\t\t}\n\t\tcasted, err := caster(newValue)\n\t\treturn casted, newPathError(path, errors.Wrap(err, \"failed to cast to expected type\"))\n\n\tcase map[string]interface{}:\n\t\tout := map[string]interface{}{}\n\t\tfor key, elem := range value {\n\t\t\tinterpolatedElem, err := recursiveInterpolate(elem, path.Next(key), opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tout[key] = interpolatedElem\n\t\t}\n\t\treturn out, nil\n\n\tcase []interface{}:\n\t\tout := make([]interface{}, len(value))\n\t\tfor i, elem := range value {\n\t\t\tinterpolatedElem, err := recursiveInterpolate(elem, path.Next(PathMatchList), opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tout[i] = interpolatedElem\n\t\t}\n\t\treturn out, nil\n\n\tdefault:\n\t\treturn value, nil\n\t}\n}\n\nfunc newPathError(path Path, err error) error {\n\tswitch err := err.(type) {\n\tcase nil:\n\t\treturn nil\n\tcase *template.InvalidTemplateError:\n\t\treturn errors.Errorf(\n\t\t\t\"invalid interpolation format for %s: %#v. You may need to escape any $ with another $.\",\n\t\t\tpath, err.Template)\n\tdefault:\n\t\treturn errors.Wrapf(err, \"error while interpolating %s\", path)\n\t}\n}\n\nconst pathSeparator = \".\"\n\n// PathMatchAll is a token used as part of a Path to match any key at that level\n// in the nested structure\nconst PathMatchAll = \"*\"\n\n// PathMatchList is a token used as part of a Path to match items in a list\nconst PathMatchList = \"[]\"\n\n// Path is a dotted path of keys to a value in a nested mapping structure. A *\n// section in a path will match any key in the mapping structure.\ntype Path string\n\n// NewPath returns a new Path\nfunc NewPath(items ...string) Path {\n\treturn Path(strings.Join(items, pathSeparator))\n}\n\n// Next returns a new path by append part to the current path\nfunc (p Path) Next(part string) Path {\n\treturn Path(string(p) + pathSeparator + part)\n}\n\nfunc (p Path) parts() []string {\n\treturn strings.Split(string(p), pathSeparator)\n}\n\nfunc (p Path) matches(pattern Path) bool {\n\tpatternParts := pattern.parts()\n\tparts := p.parts()\n\n\tif len(patternParts) != len(parts) {\n\t\treturn false\n\t}\n\tfor index, part := range parts {\n\t\tswitch patternParts[index] {\n\t\tcase PathMatchAll, part:\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (o Options) getCasterForPath(path Path) (Cast, bool) {\n\tfor pattern, caster := range o.TypeCastMapping {\n\t\tif path.matches(pattern) {\n\t\t\treturn caster, true\n\t\t}\n\t}\n\treturn nil, false\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/example1.env",
    "content": "# passed through\nFOO=foo_from_env_file\n\n# overridden in example2.env\nBAR=bar_from_env_file\n\n# overridden in full-example.yml\nBAZ=baz_from_env_file\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/example2.env",
    "content": "BAR=bar_from_env_file_2\n\n# overridden in configDetails.Environment\nQUX=quz_from_env_file_2\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/full-example.yml",
    "content": "services:\n  foo:\n\n    build:\n      context: ./dir\n      dockerfile: Dockerfile\n      args:\n        foo: bar\n      target: foo\n      network: foo\n      cache_from:\n        - foo\n        - bar\n      labels: [FOO=BAR]\n\n\n    cap_add:\n      - ALL\n\n    cap_drop:\n      - NET_ADMIN\n      - SYS_ADMIN\n\n    cgroup_parent: m-executor-abcd\n\n    # String or list\n    command: bundle exec thin -p 3000\n    # command: [\"bundle\", \"exec\", \"thin\", \"-p\", \"3000\"]\n\n    configs:\n      - config1\n      - source: config2\n        target: /my_config\n        uid: '103'\n        gid: '103'\n        mode: 0440\n\n    container_name: my-web-container\n\n    depends_on:\n      - db\n      - redis\n\n    deploy:\n      mode: replicated\n      replicas: 6\n      labels: [FOO=BAR]\n      rollback_config:\n        parallelism: 3\n        delay: 10s\n        failure_action: continue\n        monitor: 60s\n        max_failure_ratio: 0.3\n        order: start-first\n      update_config:\n        parallelism: 3\n        delay: 10s\n        failure_action: continue\n        monitor: 60s\n        max_failure_ratio: 0.3\n        order: start-first\n      resources:\n        limits:\n          cpus: '0.001'\n          memory: 50M\n        reservations:\n          cpus: '0.0001'\n          memory: 20M\n          generic_resources:\n            - discrete_resource_spec:\n                kind: 'gpu'\n                value: 2\n            - discrete_resource_spec:\n                kind: 'ssd'\n                value: 1\n      restart_policy:\n        condition: on-failure\n        delay: 5s\n        max_attempts: 3\n        window: 120s\n      placement:\n        constraints: [node=foo]\n        max_replicas_per_node: 5\n        preferences:\n          - spread: node.labels.az\n      endpoint_mode: dnsrr\n\n    devices:\n      - \"/dev/ttyUSB0:/dev/ttyUSB0\"\n\n    # String or list\n    # dns: 8.8.8.8\n    dns:\n      - 8.8.8.8\n      - 9.9.9.9\n\n    # String or list\n    # dns_search: example.com\n    dns_search:\n      - dc1.example.com\n      - dc2.example.com\n\n    domainname: foo.com\n\n    # String or list\n    # entrypoint: /code/entrypoint.sh -p 3000\n    entrypoint: [\"/code/entrypoint.sh\", \"-p\", \"3000\"]\n\n    # String or list\n    # env_file: .env\n    env_file:\n      - ./example1.env\n      - ./example2.env\n\n    # Mapping or list\n    # Mapping values can be strings, numbers or null\n    # Booleans are not allowed - must be quoted\n    environment:\n      BAZ: baz_from_service_def\n      QUX:\n    # environment:\n    #   - RACK_ENV=development\n    #   - SHOW=true\n    #   - SESSION_SECRET\n\n    # Items can be strings or numbers\n    expose:\n     - \"3000\"\n     - 8000\n\n    external_links:\n      - redis_1\n      - project_db_1:mysql\n      - project_db_1:postgresql\n\n    # Mapping or list\n    # Mapping values must be strings\n    # extra_hosts:\n    #   somehost: \"162.242.195.82\"\n    #   otherhost: \"50.31.209.229\"\n    extra_hosts:\n      - \"somehost:162.242.195.82\"\n      - \"otherhost:50.31.209.229\"\n\n    hostname: foo\n\n    healthcheck:\n      test: echo \"hello world\"\n      interval: 10s\n      timeout: 1s\n      retries: 5\n      start_period: 15s\n\n    # Any valid image reference - repo, tag, id, sha\n    image: redis\n    # image: ubuntu:14.04\n    # image: tutum/influxdb\n    # image: example-registry.com:4000/postgresql\n    # image: a4bc65fd\n    # image: busybox@sha256:38a203e1986cf79639cfb9b2e1d6e773de84002feea2d4eb006b52004ee8502d\n\n    ipc: host\n\n    # Mapping or list\n    # Mapping values can be strings, numbers or null\n    labels:\n      com.example.description: \"Accounting webapp\"\n      com.example.number: 42\n      com.example.empty-label:\n    # labels:\n    #   - \"com.example.description=Accounting webapp\"\n    #   - \"com.example.number=42\"\n    #   - \"com.example.empty-label\"\n\n    links:\n     - db\n     - db:database\n     - redis\n\n    logging:\n      driver: syslog\n      options:\n        syslog-address: \"tcp://192.168.0.42:123\"\n\n    mac_address: 02:42:ac:11:65:43\n\n    # network_mode: \"bridge\"\n    # network_mode: \"host\"\n    # network_mode: \"none\"\n    # Use the network mode of an arbitrary container from another service\n    # network_mode: \"service:db\"\n    # Use the network mode of another container, specified by name or id\n    # network_mode: \"container:some-container\"\n    network_mode: \"container:0cfeab0f748b9a743dc3da582046357c6ef497631c1a016d28d2bf9b4f899f7b\"\n\n    networks:\n      some-network:\n        aliases:\n         - alias1\n         - alias3\n      other-network:\n        ipv4_address: 172.16.238.10\n        ipv6_address: 2001:3984:3989::10\n      other-other-network:\n\n    pid: \"host\"\n\n    ports:\n      - 3000\n      - \"3001-3005\"\n      - \"8000:8000\"\n      - \"9090-9091:8080-8081\"\n      - \"49100:22\"\n      - \"127.0.0.1:8001:8001\"\n      - \"127.0.0.1:5000-5010:5000-5010\"\n\n    privileged: true\n\n    read_only: true\n\n    restart: always\n\n    secrets:\n      - secret1\n      - source: secret2\n        target: my_secret\n        uid: '103'\n        gid: '103'\n        mode: 0440\n\n    security_opt:\n      - label=level:s0:c100,c200\n      - label=type:svirt_apache_t\n\n    stdin_open: true\n\n    stop_grace_period: 20s\n\n    stop_signal: SIGUSR1\n\n    sysctls:\n      net.core.somaxconn: 1024\n      net.ipv4.tcp_syncookies: 0\n\n    # String or list\n    # tmpfs: /run\n    tmpfs:\n      - /run\n      - /tmp\n\n    tty: true\n\n    ulimits:\n      # Single number or mapping with soft + hard limits\n      nproc: 65535\n      nofile:\n        soft: 20000\n        hard: 40000\n\n    user: someone\n\n    volumes:\n      # Just specify a path and let the Engine create a volume\n      - /var/lib/mysql\n      # Specify an absolute path mapping\n      - /opt/data:/var/lib/mysql\n      # Path on the host, relative to the Compose file\n      - .:/code\n      - ./static:/var/www/html\n      # User-relative path\n      - ~/configs:/etc/configs/:ro\n      # Named volume\n      - datavolume:/var/lib/mysql\n      - type: bind\n        source: ./opt\n        target: /opt\n        consistency: cached\n      - type: tmpfs\n        target: /opt\n        tmpfs:\n          size: 10000\n\n    working_dir: /code\n    x-bar: baz\n    x-foo: bar\n\nnetworks:\n  # Entries can be null, which specifies simply that a network\n  # called \"{project name}_some-network\" should be created and\n  # use the default driver\n  some-network:\n\n  other-network:\n    driver: overlay\n\n    driver_opts:\n      # Values can be strings or numbers\n      foo: \"bar\"\n      baz: 1\n\n    ipam:\n      driver: overlay\n      # driver_opts:\n      #   # Values can be strings or numbers\n      #   com.docker.network.enable_ipv6: \"true\"\n      #   com.docker.network.numeric_value: 1\n      config:\n      - subnet: 172.28.0.0/16\n        ip_range: 172.28.5.0/24\n        gateway: 172.28.5.254\n        aux_addresses:\n          host1: 172.28.1.5\n          host2: 172.28.1.6\n          host3: 172.28.1.7\n      - subnet: 2001:3984:3989::/64\n        gateway: 2001:3984:3989::1\n\n    labels:\n      foo: bar\n\n  external-network:\n    # Specifies that a pre-existing network called \"external-network\"\n    # can be referred to within this file as \"external-network\"\n    external: true\n\n  other-external-network:\n    # Specifies that a pre-existing network called \"my-cool-network\"\n    # can be referred to within this file as \"other-external-network\"\n    external:\n      name: my-cool-network\n    x-bar: baz\n    x-foo: bar\n\nvolumes:\n  # Entries can be null, which specifies simply that a volume\n  # called \"{project name}_some-volume\" should be created and\n  # use the default driver\n  some-volume:\n\n  other-volume:\n    driver: flocker\n\n    driver_opts:\n      # Values can be strings or numbers\n      foo: \"bar\"\n      baz: 1\n    labels:\n      foo: bar\n\n  another-volume:\n    name: \"user_specified_name\"\n    driver: vsphere\n\n    driver_opts:\n      # Values can be strings or numbers\n      foo: \"bar\"\n      baz: 1\n\n  external-volume:\n    # Specifies that a pre-existing volume called \"external-volume\"\n    # can be referred to within this file as \"external-volume\"\n    external: true\n\n  other-external-volume:\n    # Specifies that a pre-existing volume called \"my-cool-volume\"\n    # can be referred to within this file as \"other-external-volume\"\n    # This example uses the deprecated \"volume.external.name\" (replaced by \"volume.name\")\n    external:\n      name: my-cool-volume\n\n  external-volume3:\n    # Specifies that a pre-existing volume called \"this-is-volume3\"\n    # can be referred to within this file as \"external-volume3\"\n    name: this-is-volume3\n    external: true\n    x-bar: baz\n    x-foo: bar\n\nconfigs:\n  config1:\n    file: ./config_data\n    labels:\n      foo: bar\n  config2:\n    external:\n      name: my_config\n  config3:\n    external: true\n  config4:\n    name: foo\n    x-bar: baz\n    x-foo: bar\n\nsecrets:\n  secret1:\n    file: ./secret_data\n    labels:\n      foo: bar\n  secret2:\n    external:\n      name: my_secret\n  secret3:\n    external: true\n  secret4:\n    name: bar\n    x-bar: baz\n    x-foo: bar\nx-bar: baz\nx-foo: bar\nx-nested:\n  bar: baz\n  foo: bar\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/interpolate.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\tinterp \"github.com/compose-spec/compose-go/interpolation\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n)\n\nvar interpolateTypeCastMapping = map[interp.Path]interp.Cast{\n\tservicePath(\"configs\", interp.PathMatchList, \"mode\"):             toInt,\n\tservicePath(\"cpu_count\"):                                         toInt64,\n\tservicePath(\"cpu_percent\"):                                       toFloat,\n\tservicePath(\"cpu_period\"):                                        toInt64,\n\tservicePath(\"cpu_quota\"):                                         toInt64,\n\tservicePath(\"cpu_rt_period\"):                                     toInt64,\n\tservicePath(\"cpu_rt_runtime\"):                                    toInt64,\n\tservicePath(\"cpus\"):                                              toFloat32,\n\tservicePath(\"cpu_shares\"):                                        toInt64,\n\tservicePath(\"init\"):                                              toBoolean,\n\tservicePath(\"deploy\", \"replicas\"):                                toInt,\n\tservicePath(\"deploy\", \"update_config\", \"parallelism\"):            toInt,\n\tservicePath(\"deploy\", \"update_config\", \"max_failure_ratio\"):      toFloat,\n\tservicePath(\"deploy\", \"rollback_config\", \"parallelism\"):          toInt,\n\tservicePath(\"deploy\", \"rollback_config\", \"max_failure_ratio\"):    toFloat,\n\tservicePath(\"deploy\", \"restart_policy\", \"max_attempts\"):          toInt,\n\tservicePath(\"deploy\", \"placement\", \"max_replicas_per_node\"):      toInt,\n\tservicePath(\"healthcheck\", \"retries\"):                            toInt,\n\tservicePath(\"healthcheck\", \"disable\"):                            toBoolean,\n\tservicePath(\"mem_limit\"):                                         toUnitBytes,\n\tservicePath(\"mem_reservation\"):                                   toUnitBytes,\n\tservicePath(\"memswap_limit\"):                                     toUnitBytes,\n\tservicePath(\"mem_swappiness\"):                                    toUnitBytes,\n\tservicePath(\"oom_kill_disable\"):                                  toBoolean,\n\tservicePath(\"oom_score_adj\"):                                     toInt64,\n\tservicePath(\"pids_limit\"):                                        toInt64,\n\tservicePath(\"ports\", interp.PathMatchList, \"target\"):             toInt,\n\tservicePath(\"ports\", interp.PathMatchList, \"published\"):          toInt,\n\tservicePath(\"privileged\"):                                        toBoolean,\n\tservicePath(\"read_only\"):                                         toBoolean,\n\tservicePath(\"scale\"):                                             toInt,\n\tservicePath(\"secrets\", interp.PathMatchList, \"mode\"):             toInt,\n\tservicePath(\"shm_size\"):                                          toUnitBytes,\n\tservicePath(\"stdin_open\"):                                        toBoolean,\n\tservicePath(\"stop_grace_period\"):                                 toDuration,\n\tservicePath(\"tty\"):                                               toBoolean,\n\tservicePath(\"ulimits\", interp.PathMatchAll):                      toInt,\n\tservicePath(\"ulimits\", interp.PathMatchAll, \"hard\"):              toInt,\n\tservicePath(\"ulimits\", interp.PathMatchAll, \"soft\"):              toInt,\n\tservicePath(\"volumes\", interp.PathMatchList, \"read_only\"):        toBoolean,\n\tservicePath(\"volumes\", interp.PathMatchList, \"volume\", \"nocopy\"): toBoolean,\n\tiPath(\"networks\", interp.PathMatchAll, \"external\"):               toBoolean,\n\tiPath(\"networks\", interp.PathMatchAll, \"internal\"):               toBoolean,\n\tiPath(\"networks\", interp.PathMatchAll, \"attachable\"):             toBoolean,\n\tiPath(\"volumes\", interp.PathMatchAll, \"external\"):                toBoolean,\n\tiPath(\"secrets\", interp.PathMatchAll, \"external\"):                toBoolean,\n\tiPath(\"configs\", interp.PathMatchAll, \"external\"):                toBoolean,\n}\n\nfunc iPath(parts ...string) interp.Path {\n\treturn interp.NewPath(parts...)\n}\n\nfunc servicePath(parts ...string) interp.Path {\n\treturn iPath(append([]string{\"services\", interp.PathMatchAll}, parts...)...)\n}\n\nfunc toInt(value string) (interface{}, error) {\n\treturn strconv.Atoi(value)\n}\n\nfunc toInt64(value string) (interface{}, error) {\n\treturn strconv.ParseInt(value, 10, 64)\n}\n\nfunc toUnitBytes(value string) (interface{}, error) {\n\ti, err := strconv.ParseInt(value, 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn types.UnitBytes(i), nil\n}\n\nfunc toDuration(value string) (interface{}, error) {\n\ti, err := strconv.ParseInt(value, 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn types.Duration(i), nil\n}\n\nfunc toFloat(value string) (interface{}, error) {\n\treturn strconv.ParseFloat(value, 64)\n}\n\nfunc toFloat32(value string) (interface{}, error) {\n\tf, err := strconv.ParseFloat(value, 32)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn float32(f), nil\n}\n\n// should match http://yaml.org/type/bool.html\nfunc toBoolean(value string) (interface{}, error) {\n\tswitch strings.ToLower(value) {\n\tcase \"y\", \"yes\", \"true\", \"on\":\n\t\treturn true, nil\n\tcase \"n\", \"no\", \"false\", \"off\":\n\t\treturn false, nil\n\tdefault:\n\t\treturn nil, errors.Errorf(\"invalid boolean: %s\", value)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/loader.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\tinterp \"github.com/compose-spec/compose-go/interpolation\"\n\t//\"github.com/compose-spec/compose-go/schema\"\n\t\"github.com/compose-spec/compose-go/template\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/docker/go-units\"\n\t\"github.com/mattn/go-shellwords\"\n\t\"github.com/mitchellh/mapstructure\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/ulyssessouza/godotenv\"\n\t\"gopkg.in/yaml.v2\"\n)\n\n// Options supported by Load\ntype Options struct {\n\t// Skip schema validation\n\tSkipValidation bool\n\t// Skip interpolation\n\tSkipInterpolation bool\n\t// Skip normalization\n\tSkipNormalization bool\n\t// Resolve paths\n\tResolvePaths bool\n\t// Skip consistency check\n\tSkipConsistencyCheck bool\n\t// Skip extends\n\tSkipExtends bool\n\t// Interpolation options\n\tInterpolate *interp.Options\n\t// Discard 'env_file' entries after resolving to 'environment' section\n\tdiscardEnvFiles bool\n\t// Set project name\n\tName string\n}\n\n// serviceRef identifies a reference to a service. It's used to detect cyclic\n// references in \"extends\".\ntype serviceRef struct {\n\tfilename string\n\tservice  string\n}\n\ntype cycleTracker struct {\n\tloaded []serviceRef\n}\n\nfunc (ct *cycleTracker) Add(filename, service string) error {\n\ttoAdd := serviceRef{filename: filename, service: service}\n\tfor _, loaded := range ct.loaded {\n\t\tif toAdd == loaded {\n\t\t\t// Create an error message of the form:\n\t\t\t// Circular reference:\n\t\t\t//   service-a in docker-compose.yml\n\t\t\t//   extends service-b in docker-compose.yml\n\t\t\t//   extends service-a in docker-compose.yml\n\t\t\terrLines := []string{\n\t\t\t\t\"Circular reference:\",\n\t\t\t\tfmt.Sprintf(\"  %s in %s\", ct.loaded[0].service, ct.loaded[0].filename),\n\t\t\t}\n\t\t\tfor _, service := range append(ct.loaded[1:], toAdd) {\n\t\t\t\terrLines = append(errLines, fmt.Sprintf(\"  extends %s in %s\", service.service, service.filename))\n\t\t\t}\n\n\t\t\treturn errors.New(strings.Join(errLines, \"\\n\"))\n\t\t}\n\t}\n\n\tct.loaded = append(ct.loaded, toAdd)\n\treturn nil\n}\n\n// WithDiscardEnvFiles sets the Options to discard the `env_file` section after resolving to\n// the `environment` section\nfunc WithDiscardEnvFiles(opts *Options) {\n\topts.discardEnvFiles = true\n}\n\n// WithSkipValidation sets the Options to skip validation when loading sections\nfunc WithSkipValidation(opts *Options) {\n\topts.SkipValidation = true\n}\n\n// ParseYAML reads the bytes from a file, parses the bytes into a mapping\n// structure, and returns it.\nfunc ParseYAML(source []byte) (map[string]interface{}, error) {\n\tvar cfg interface{}\n\tif err := yaml.Unmarshal(source, &cfg); err != nil {\n\t\treturn nil, err\n\t}\n\tcfgMap, ok := cfg.(map[interface{}]interface{})\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"Top-level object must be a mapping\")\n\t}\n\tconverted, err := convertToStringKeysRecursive(cfgMap, \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn converted.(map[string]interface{}), nil\n}\n\n// Load reads a ConfigDetails and returns a fully loaded configuration\nfunc Load(configDetails types.ConfigDetails, options ...func(*Options)) (*types.Project, error) {\n\tif len(configDetails.ConfigFiles) < 1 {\n\t\treturn nil, errors.Errorf(\"No files specified\")\n\t}\n\n\topts := &Options{\n\t\tInterpolate: &interp.Options{\n\t\t\tSubstitute:      template.Substitute,\n\t\t\tLookupValue:     configDetails.LookupEnv,\n\t\t\tTypeCastMapping: interpolateTypeCastMapping,\n\t\t},\n\t}\n\n\tfor _, op := range options {\n\t\top(opts)\n\t}\n\n\tconfigs := []*types.Config{}\n\tfor i, file := range configDetails.ConfigFiles {\n\t\tconfigDict := file.Config\n\t\tif configDict == nil {\n\t\t\tdict, err := parseConfig(file.Content, opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconfigDict = dict\n\t\t\tfile.Config = dict\n\t\t\tconfigDetails.ConfigFiles[i] = file\n\t\t}\n\n\t\t//QTMP\n\t\t//if !opts.SkipValidation {\n\t\t//\tif err := schema.Validate(configDict); err != nil {\n\t\t//\t\treturn nil, err\n\t\t//\t}\n\t\t//}\n\n\t\tconfigDict = groupXFieldsIntoExtensions(configDict)\n\n\t\tcfg, err := loadSections(file.Filename, configDict, configDetails, opts)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif opts.discardEnvFiles {\n\t\t\tfor i := range cfg.Services {\n\t\t\t\tcfg.Services[i].EnvFile = nil\n\t\t\t}\n\t\t}\n\n\t\tconfigs = append(configs, cfg)\n\t}\n\n\tmodel, err := merge(configs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, s := range model.Services {\n\t\tvar newEnvFiles types.StringList\n\t\tfor _, ef := range s.EnvFile {\n\t\t\tnewEnvFiles = append(newEnvFiles, absPath(configDetails.WorkingDir, ef))\n\t\t}\n\t\ts.EnvFile = newEnvFiles\n\t}\n\n\tproject := &types.Project{\n\t\tName:        opts.Name,\n\t\tWorkingDir:  configDetails.WorkingDir,\n\t\tServices:    model.Services,\n\t\tNetworks:    model.Networks,\n\t\tVolumes:     model.Volumes,\n\t\tSecrets:     model.Secrets,\n\t\tConfigs:     model.Configs,\n\t\tEnvironment: configDetails.Environment,\n\t\tExtensions:  model.Extensions,\n\t}\n\n\tif !opts.SkipNormalization {\n\t\terr = normalize(project, opts.ResolvePaths)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif !opts.SkipConsistencyCheck {\n\t\terr = checkConsistency(project)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn project, nil\n}\n\nfunc parseConfig(b []byte, opts *Options) (map[string]interface{}, error) {\n\tyaml, err := ParseYAML(b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !opts.SkipInterpolation {\n\t\treturn interp.Interpolate(yaml, *opts.Interpolate)\n\t}\n\treturn yaml, err\n}\n\nfunc groupXFieldsIntoExtensions(dict map[string]interface{}) map[string]interface{} {\n\textras := map[string]interface{}{}\n\tfor key, value := range dict {\n\t\tif strings.HasPrefix(key, \"x-\") {\n\t\t\textras[key] = value\n\t\t\tdelete(dict, key)\n\t\t}\n\t\tif d, ok := value.(map[string]interface{}); ok {\n\t\t\tdict[key] = groupXFieldsIntoExtensions(d)\n\t\t}\n\t}\n\tif len(extras) > 0 {\n\t\tdict[\"extensions\"] = extras\n\t}\n\treturn dict\n}\n\nfunc loadSections(filename string, config map[string]interface{}, configDetails types.ConfigDetails, opts *Options) (*types.Config, error) {\n\tvar err error\n\tcfg := types.Config{\n\t\tFilename: filename,\n\t}\n\n\tcfg.Services, err = LoadServices(filename, getSection(config, \"services\"), configDetails.WorkingDir, configDetails.LookupEnv, opts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcfg.Networks, err = LoadNetworks(getSection(config, \"networks\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Volumes, err = LoadVolumes(getSection(config, \"volumes\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Secrets, err = LoadSecrets(getSection(config, \"secrets\"), configDetails, opts.ResolvePaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcfg.Configs, err = LoadConfigObjs(getSection(config, \"configs\"), configDetails, opts.ResolvePaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\textensions := getSection(config, \"extensions\")\n\tif len(extensions) > 0 {\n\t\tcfg.Extensions = extensions\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &cfg, nil\n}\n\nfunc getSection(config map[string]interface{}, key string) map[string]interface{} {\n\tsection, ok := config[key]\n\tif !ok {\n\t\treturn map[string]interface{}{}\n\t}\n\treturn section.(map[string]interface{})\n}\n\n// ForbiddenPropertiesError is returned when there are properties in the Compose\n// file that are forbidden.\ntype ForbiddenPropertiesError struct {\n\tProperties map[string]string\n}\n\nfunc (e *ForbiddenPropertiesError) Error() string {\n\treturn \"Configuration contains forbidden properties\"\n}\n\n// Transform converts the source into the target struct with compose types transformer\n// and the specified transformers if any.\nfunc Transform(source interface{}, target interface{}, additionalTransformers ...Transformer) error {\n\tdata := mapstructure.Metadata{}\n\tconfig := &mapstructure.DecoderConfig{\n\t\tDecodeHook: mapstructure.ComposeDecodeHookFunc(\n\t\t\tcreateTransformHook(additionalTransformers...),\n\t\t\tmapstructure.StringToTimeDurationHookFunc()),\n\t\tResult:   target,\n\t\tMetadata: &data,\n\t}\n\tdecoder, err := mapstructure.NewDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn decoder.Decode(source)\n}\n\n// TransformerFunc defines a function to perform the actual transformation\ntype TransformerFunc func(interface{}) (interface{}, error)\n\n// Transformer defines a map to type transformer\ntype Transformer struct {\n\tTypeOf reflect.Type\n\tFunc   TransformerFunc\n}\n\nfunc createTransformHook(additionalTransformers ...Transformer) mapstructure.DecodeHookFuncType {\n\ttransforms := map[reflect.Type]func(interface{}) (interface{}, error){\n\t\treflect.TypeOf(types.External{}):                         transformExternal,\n\t\treflect.TypeOf(types.HealthCheckTest{}):                  transformHealthCheckTest,\n\t\treflect.TypeOf(types.ShellCommand{}):                     transformShellCommand,\n\t\treflect.TypeOf(types.StringList{}):                       transformStringList,\n\t\treflect.TypeOf(map[string]string{}):                      transformMapStringString,\n\t\treflect.TypeOf(types.UlimitsConfig{}):                    transformUlimits,\n\t\treflect.TypeOf(types.UnitBytes(0)):                       transformSize,\n\t\treflect.TypeOf([]types.ServicePortConfig{}):              transformServicePort,\n\t\treflect.TypeOf(types.ServiceSecretConfig{}):              transformStringSourceMap,\n\t\treflect.TypeOf(types.ServiceConfigObjConfig{}):           transformStringSourceMap,\n\t\treflect.TypeOf(types.StringOrNumberList{}):               transformStringOrNumberList,\n\t\treflect.TypeOf(map[string]*types.ServiceNetworkConfig{}): transformServiceNetworkMap,\n\t\treflect.TypeOf(types.Mapping{}):                          transformMappingOrListFunc(\"=\", false),\n\t\treflect.TypeOf(types.MappingWithEquals{}):                transformMappingOrListFunc(\"=\", true),\n\t\treflect.TypeOf(types.Labels{}):                           transformMappingOrListFunc(\"=\", false),\n\t\treflect.TypeOf(types.MappingWithColon{}):                 transformMappingOrListFunc(\":\", false),\n\t\treflect.TypeOf(types.HostsList{}):                        transformListOrMappingFunc(\":\", false),\n\t\treflect.TypeOf(types.ServiceVolumeConfig{}):              transformServiceVolumeConfig,\n\t\treflect.TypeOf(types.BuildConfig{}):                      transformBuildConfig,\n\t\treflect.TypeOf(types.Duration(0)):                        transformStringToDuration,\n\t\treflect.TypeOf(types.DependsOnConfig{}):                  transformDependsOnConfig,\n\t\treflect.TypeOf(types.ExtendsConfig{}):                    transformExtendsConfig,\n\t\treflect.TypeOf(types.DeviceRequest{}):                    transformServiceDeviceRequest,\n\t}\n\n\tfor _, transformer := range additionalTransformers {\n\t\ttransforms[transformer.TypeOf] = transformer.Func\n\t}\n\n\treturn func(_ reflect.Type, target reflect.Type, data interface{}) (interface{}, error) {\n\t\ttransform, ok := transforms[target]\n\t\tif !ok {\n\t\t\treturn data, nil\n\t\t}\n\t\treturn transform(data)\n\t}\n}\n\n// keys needs to be converted to strings for jsonschema\nfunc convertToStringKeysRecursive(value interface{}, keyPrefix string) (interface{}, error) {\n\tif mapping, ok := value.(map[interface{}]interface{}); ok {\n\t\tdict := map[string]interface{}{}\n\t\tfor key, entry := range mapping {\n\t\t\tstr, ok := key.(string)\n\t\t\tif !ok {\n\t\t\t\treturn nil, formatInvalidKeyError(keyPrefix, key)\n\t\t\t}\n\t\t\tvar newKeyPrefix string\n\t\t\tif keyPrefix == \"\" {\n\t\t\t\tnewKeyPrefix = str\n\t\t\t} else {\n\t\t\t\tnewKeyPrefix = fmt.Sprintf(\"%s.%s\", keyPrefix, str)\n\t\t\t}\n\t\t\tconvertedEntry, err := convertToStringKeysRecursive(entry, newKeyPrefix)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdict[str] = convertedEntry\n\t\t}\n\t\treturn dict, nil\n\t}\n\tif list, ok := value.([]interface{}); ok {\n\t\tconvertedList := []interface{}{}\n\t\tfor index, entry := range list {\n\t\t\tnewKeyPrefix := fmt.Sprintf(\"%s[%d]\", keyPrefix, index)\n\t\t\tconvertedEntry, err := convertToStringKeysRecursive(entry, newKeyPrefix)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tconvertedList = append(convertedList, convertedEntry)\n\t\t}\n\t\treturn convertedList, nil\n\t}\n\treturn value, nil\n}\n\nfunc formatInvalidKeyError(keyPrefix string, key interface{}) error {\n\tvar location string\n\tif keyPrefix == \"\" {\n\t\tlocation = \"at top level\"\n\t} else {\n\t\tlocation = fmt.Sprintf(\"in %s\", keyPrefix)\n\t}\n\treturn errors.Errorf(\"Non-string key %s: %#v\", location, key)\n}\n\n// LoadServices produces a ServiceConfig map from a compose file Dict\n// the servicesDict is not validated if directly used. Use Load() to enable validation\nfunc LoadServices(filename string, servicesDict map[string]interface{}, workingDir string, lookupEnv template.Mapping, opts *Options) ([]types.ServiceConfig, error) {\n\tvar services []types.ServiceConfig\n\n\tx, ok := servicesDict[\"extensions\"]\n\tif ok {\n\t\t// as a top-level attribute, \"services\" doesn't support extensions, and a service can be named `x-foo`\n\t\tfor k, v := range x.(map[string]interface{}) {\n\t\t\tservicesDict[k] = v\n\t\t}\n\t}\n\n\tfor name := range servicesDict {\n\t\tserviceConfig, err := loadServiceWithExtends(filename, name, servicesDict, workingDir, lookupEnv, opts, &cycleTracker{})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tservices = append(services, *serviceConfig)\n\t}\n\n\treturn services, nil\n}\n\nfunc loadServiceWithExtends(filename, name string, servicesDict map[string]interface{}, workingDir string, lookupEnv template.Mapping, opts *Options, ct *cycleTracker) (*types.ServiceConfig, error) {\n\tif err := ct.Add(filename, name); err != nil {\n\t\treturn nil, err\n\t}\n\n\tserviceConfig, err := LoadService(name, servicesDict[name].(map[string]interface{}), workingDir, lookupEnv, opts.ResolvePaths)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif serviceConfig.Extends != nil && !opts.SkipExtends {\n\t\tbaseServiceName := *serviceConfig.Extends[\"service\"]\n\t\tvar baseService *types.ServiceConfig\n\t\tif file := serviceConfig.Extends[\"file\"]; file == nil {\n\t\t\tbaseService, err = loadServiceWithExtends(filename, baseServiceName, servicesDict, workingDir, lookupEnv, opts, ct)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\t// Resolve the path to the imported file, and load it.\n\t\t\tbaseFilePath := absPath(workingDir, *file)\n\n\t\t\tbytes, err := ioutil.ReadFile(baseFilePath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tbaseFile, err := parseConfig(bytes, opts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tbaseFileServices := getSection(baseFile, \"services\")\n\t\t\tbaseService, err = loadServiceWithExtends(baseFilePath, baseServiceName, baseFileServices, filepath.Dir(baseFilePath), lookupEnv, opts, ct)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Make paths relative to the importing Compose file. Note that we\n\t\t\t// make the paths relative to `*file` rather than `baseFilePath` so\n\t\t\t// that the resulting paths won't be absolute if `*file` isn't an\n\t\t\t// absolute path.\n\t\t\tbaseFileParent := filepath.Dir(*file)\n\t\t\tif baseService.Build != nil {\n\t\t\t\t// Note that the Dockerfile is always defined relative to the\n\t\t\t\t// build context, so there's no need to update the Dockerfile field.\n\t\t\t\tbaseService.Build.Context = absPath(baseFileParent, baseService.Build.Context)\n\t\t\t}\n\n\t\t\tfor i, vol := range baseService.Volumes {\n\t\t\t\tif vol.Type != types.VolumeTypeBind {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbaseService.Volumes[i].Source = absPath(baseFileParent, vol.Source)\n\t\t\t}\n\t\t}\n\n\t\tserviceConfig, err = _merge(baseService, serviceConfig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn serviceConfig, nil\n}\n\n// LoadService produces a single ServiceConfig from a compose file Dict\n// the serviceDict is not validated if directly used. Use Load() to enable validation\nfunc LoadService(name string, serviceDict map[string]interface{}, workingDir string, lookupEnv template.Mapping, resolvePaths bool) (*types.ServiceConfig, error) {\n\tserviceConfig := &types.ServiceConfig{\n\t\tScale: 1,\n\t}\n\tif err := Transform(serviceDict, serviceConfig); err != nil {\n\t\treturn nil, err\n\t}\n\tserviceConfig.Name = name\n\n\tif err := resolveEnvironment(serviceConfig, workingDir, lookupEnv); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor i, volume := range serviceConfig.Volumes {\n\t\tif volume.Type != \"bind\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif volume.Source == \"\" {\n\t\t\treturn nil, errors.New(`invalid mount config for type \"bind\": field Source must not be empty`)\n\t\t}\n\n\t\tif resolvePaths {\n\t\t\tserviceConfig.Volumes[i] = resolveVolumePath(volume, workingDir, lookupEnv)\n\t\t}\n\t}\n\n\treturn serviceConfig, nil\n}\n\nfunc resolveEnvironment(serviceConfig *types.ServiceConfig, workingDir string, lookupEnv template.Mapping) error {\n\tenvironment := types.MappingWithEquals{}\n\n\tif len(serviceConfig.EnvFile) > 0 {\n\t\tfor _, file := range serviceConfig.EnvFile {\n\t\t\tfilePath := absPath(workingDir, file)\n\t\t\tfile, err := os.Open(filePath)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer file.Close()\n\t\t\tfileVars, err := godotenv.Parse(file)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tenv := types.MappingWithEquals{}\n\t\t\tfor k, v := range fileVars {\n\t\t\t\tv := v\n\t\t\t\tenv[k] = &v\n\t\t\t}\n\t\t\tenvironment.OverrideBy(env.Resolve(lookupEnv).RemoveEmpty())\n\t\t}\n\t}\n\n\tenvironment.OverrideBy(serviceConfig.Environment.Resolve(lookupEnv))\n\tserviceConfig.Environment = environment\n\treturn nil\n}\n\nfunc resolveVolumePath(volume types.ServiceVolumeConfig, workingDir string, lookupEnv template.Mapping) types.ServiceVolumeConfig {\n\tfilePath := expandUser(volume.Source, lookupEnv)\n\t// Check if source is an absolute path (either Unix or Windows), to\n\t// handle a Windows client with a Unix daemon or vice-versa.\n\t//\n\t// Note that this is not required for Docker for Windows when specifying\n\t// a local Windows path, because Docker for Windows translates the Windows\n\t// path into a valid path within the VM.\n\tif !path.IsAbs(filePath) && !isAbs(filePath) {\n\t\tfilePath = absPath(workingDir, filePath)\n\t}\n\tvolume.Source = filePath\n\treturn volume\n}\n\n// TODO: make this more robust\nfunc expandUser(path string, lookupEnv template.Mapping) string {\n\tif strings.HasPrefix(path, \"~\") {\n\t\thome, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\tlogrus.Warn(\"cannot expand '~', because the environment lacks HOME\")\n\t\t\treturn path\n\t\t}\n\t\treturn filepath.Join(home, path[1:])\n\t}\n\treturn path\n}\n\nfunc transformUlimits(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase int:\n\t\treturn types.UlimitsConfig{Single: value}, nil\n\tcase map[string]interface{}:\n\t\tulimit := types.UlimitsConfig{}\n\t\tif v, ok := value[\"soft\"]; ok {\n\t\t\tulimit.Soft = v.(int)\n\t\t}\n\t\tif v, ok := value[\"hard\"]; ok {\n\t\t\tulimit.Hard = v.(int)\n\t\t}\n\t\treturn ulimit, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for ulimits\", value)\n\t}\n}\n\n// LoadNetworks produces a NetworkConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadNetworks(source map[string]interface{}) (map[string]types.NetworkConfig, error) {\n\tnetworks := map[string]types.NetworkConfig{}\n\terr := Transform(source, &networks)\n\tif err != nil {\n\t\treturn networks, err\n\t}\n\tfor name, network := range networks {\n\t\tif !network.External.External {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase network.External.Name != \"\":\n\t\t\tif network.Name != \"\" {\n\t\t\t\treturn nil, errors.Errorf(\"network %s: network.external.name and network.name conflict; only use network.name\", name)\n\t\t\t}\n\t\t\tlogrus.Warnf(\"network %s: network.external.name is deprecated in favor of network.name\", name)\n\t\t\tnetwork.Name = network.External.Name\n\t\t\tnetwork.External.Name = \"\"\n\t\tcase network.Name == \"\":\n\t\t\tnetwork.Name = name\n\t\t}\n\t\tnetworks[name] = network\n\t}\n\treturn networks, nil\n}\n\nfunc externalVolumeError(volume, key string) error {\n\treturn errors.Errorf(\n\t\t\"conflicting parameters \\\"external\\\" and %q specified for volume %q\",\n\t\tkey, volume)\n}\n\n// LoadVolumes produces a VolumeConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadVolumes(source map[string]interface{}) (map[string]types.VolumeConfig, error) {\n\tvolumes := make(map[string]types.VolumeConfig)\n\tif err := Transform(source, &volumes); err != nil {\n\t\treturn volumes, err\n\t}\n\n\tfor name, volume := range volumes {\n\t\tif !volume.External.External {\n\t\t\tcontinue\n\t\t}\n\t\tswitch {\n\t\tcase volume.Driver != \"\":\n\t\t\treturn nil, externalVolumeError(name, \"driver\")\n\t\tcase len(volume.DriverOpts) > 0:\n\t\t\treturn nil, externalVolumeError(name, \"driver_opts\")\n\t\tcase len(volume.Labels) > 0:\n\t\t\treturn nil, externalVolumeError(name, \"labels\")\n\t\tcase volume.External.Name != \"\":\n\t\t\tif volume.Name != \"\" {\n\t\t\t\treturn nil, errors.Errorf(\"volume %s: volume.external.name and volume.name conflict; only use volume.name\", name)\n\t\t\t}\n\t\t\tlogrus.Warnf(\"volume %s: volume.external.name is deprecated in favor of volume.name\", name)\n\t\t\tvolume.Name = volume.External.Name\n\t\t\tvolume.External.Name = \"\"\n\t\tcase volume.Name == \"\":\n\t\t\tvolume.Name = name\n\t\t}\n\t\tvolumes[name] = volume\n\t}\n\treturn volumes, nil\n}\n\n// LoadSecrets produces a SecretConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadSecrets(source map[string]interface{}, details types.ConfigDetails, resolvePaths bool) (map[string]types.SecretConfig, error) {\n\tsecrets := make(map[string]types.SecretConfig)\n\tif err := Transform(source, &secrets); err != nil {\n\t\treturn secrets, err\n\t}\n\tfor name, secret := range secrets {\n\t\tobj, err := loadFileObjectConfig(name, \"secret\", types.FileObjectConfig(secret), details, resolvePaths)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsecretConfig := types.SecretConfig(obj)\n\t\tsecrets[name] = secretConfig\n\t}\n\treturn secrets, nil\n}\n\n// LoadConfigObjs produces a ConfigObjConfig map from a compose file Dict\n// the source Dict is not validated if directly used. Use Load() to enable validation\nfunc LoadConfigObjs(source map[string]interface{}, details types.ConfigDetails, resolvePaths bool) (map[string]types.ConfigObjConfig, error) {\n\tconfigs := make(map[string]types.ConfigObjConfig)\n\tif err := Transform(source, &configs); err != nil {\n\t\treturn configs, err\n\t}\n\tfor name, config := range configs {\n\t\tobj, err := loadFileObjectConfig(name, \"config\", types.FileObjectConfig(config), details, resolvePaths)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tconfigConfig := types.ConfigObjConfig(obj)\n\t\tconfigs[name] = configConfig\n\t}\n\treturn configs, nil\n}\n\nfunc loadFileObjectConfig(name string, objType string, obj types.FileObjectConfig, details types.ConfigDetails, resolvePaths bool) (types.FileObjectConfig, error) {\n\t// if \"external: true\"\n\tswitch {\n\tcase obj.External.External:\n\t\t// handle deprecated external.name\n\t\tif obj.External.Name != \"\" {\n\t\t\tif obj.Name != \"\" {\n\t\t\t\treturn obj, errors.Errorf(\"%[1]s %[2]s: %[1]s.external.name and %[1]s.name conflict; only use %[1]s.name\", objType, name)\n\t\t\t}\n\t\t\tlogrus.Warnf(\"%[1]s %[2]s: %[1]s.external.name is deprecated in favor of %[1]s.name\", objType, name)\n\t\t\tobj.Name = obj.External.Name\n\t\t\tobj.External.Name = \"\"\n\t\t} else {\n\t\t\tif obj.Name == \"\" {\n\t\t\t\tobj.Name = name\n\t\t\t}\n\t\t}\n\t\t// if not \"external: true\"\n\tcase obj.Driver != \"\":\n\t\tif obj.File != \"\" {\n\t\t\treturn obj, errors.Errorf(\"%[1]s %[2]s: %[1]s.driver and %[1]s.file conflict; only use %[1]s.driver\", objType, name)\n\t\t}\n\tdefault:\n\t\tif resolvePaths {\n\t\t\tobj.File = absPath(details.WorkingDir, obj.File)\n\t\t}\n\t}\n\n\treturn obj, nil\n}\n\nfunc absPath(workingDir string, filePath string) string {\n\tif strings.HasPrefix(filePath, \"~\") {\n\t\thome, _ := os.UserHomeDir()\n\t\treturn filepath.Join(home, filePath[1:])\n\t}\n\tif filepath.IsAbs(filePath) {\n\t\treturn filePath\n\t}\n\treturn filepath.Join(workingDir, filePath)\n}\n\nvar transformMapStringString TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase map[string]interface{}:\n\t\treturn toMapStringString(value, false), nil\n\tcase map[string]string:\n\t\treturn value, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for map[string]string\", value)\n\t}\n}\n\nvar transformExternal TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase bool:\n\t\treturn map[string]interface{}{\"external\": value}, nil\n\tcase map[string]interface{}:\n\t\treturn map[string]interface{}{\"external\": true, \"name\": value[\"name\"]}, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for external\", value)\n\t}\n}\n\nvar transformServicePort TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch entries := data.(type) {\n\tcase []interface{}:\n\t\t// We process the list instead of individual items here.\n\t\t// The reason is that one entry might be mapped to multiple ServicePortConfig.\n\t\t// Therefore we take an input of a list and return an output of a list.\n\t\tports := []interface{}{}\n\t\tfor _, entry := range entries {\n\t\t\tswitch value := entry.(type) {\n\t\t\tcase int:\n\t\t\t\tparsed, err := types.ParsePortConfig(fmt.Sprint(value))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn data, err\n\t\t\t\t}\n\t\t\t\tfor _, v := range parsed {\n\t\t\t\t\tports = append(ports, v)\n\t\t\t\t}\n\t\t\tcase string:\n\t\t\t\tparsed, err := types.ParsePortConfig(value)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn data, err\n\t\t\t\t}\n\t\t\t\tfor _, v := range parsed {\n\t\t\t\t\tports = append(ports, v)\n\t\t\t\t}\n\t\t\tcase map[string]interface{}:\n\t\t\t\tports = append(ports, groupXFieldsIntoExtensions(value))\n\t\t\tdefault:\n\t\t\t\treturn data, errors.Errorf(\"invalid type %T for port\", value)\n\t\t\t}\n\t\t}\n\t\treturn ports, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for port\", entries)\n\t}\n}\n\nvar transformServiceDeviceRequest TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase map[string]interface{}:\n\t\tcount, ok := value[\"count\"]\n\t\tif ok {\n\t\t\tswitch val := count.(type) {\n\t\t\tcase int:\n\t\t\t\treturn value, nil\n\t\t\tcase string:\n\t\t\t\tif strings.ToLower(val) == \"all\" {\n\t\t\t\t\tvalue[\"count\"] = -1\n\t\t\t\t\treturn value, nil\n\t\t\t\t}\n\t\t\t\treturn data, errors.Errorf(\"invalid string value for 'count' (the only value allowed is 'all')\")\n\t\t\tdefault:\n\t\t\t\treturn data, errors.Errorf(\"invalid type %T for device count\", val)\n\t\t\t}\n\t\t}\n\t\treturn data, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for resource reservation\", value)\n\t}\n}\n\nvar transformStringSourceMap TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn map[string]interface{}{\"source\": value}, nil\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for secret\", value)\n\t}\n}\n\nvar transformBuildConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn map[string]interface{}{\"context\": value}, nil\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for service build\", value)\n\t}\n}\n\nvar transformDependsOnConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase []interface{}:\n\t\ttransformed := map[string]interface{}{}\n\t\tfor _, serviceIntf := range value {\n\t\t\tservice, ok := serviceIntf.(string)\n\t\t\tif !ok {\n\t\t\t\treturn data, errors.Errorf(\"invalid type %T for service depends_on element. Expected string.\", value)\n\t\t\t}\n\t\t\ttransformed[service] = map[string]interface{}{\"condition\": types.ServiceConditionStarted}\n\t\t}\n\t\treturn transformed, nil\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for service depends_on\", value)\n\t}\n}\n\nvar transformExtendsConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch data.(type) {\n\tcase string:\n\t\tdata = map[string]interface{}{\n\t\t\t\"service\": data,\n\t\t}\n\t}\n\treturn transformMappingOrListFunc(\"=\", true)(data)\n}\n\nvar transformServiceVolumeConfig TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn ParseVolume(value)\n\tcase map[string]interface{}:\n\t\treturn groupXFieldsIntoExtensions(data.(map[string]interface{})), nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for service volume\", value)\n\t}\n}\n\nvar transformServiceNetworkMap TransformerFunc = func(value interface{}) (interface{}, error) {\n\tif list, ok := value.([]interface{}); ok {\n\t\tmapValue := map[interface{}]interface{}{}\n\t\tfor _, name := range list {\n\t\t\tmapValue[name] = nil\n\t\t}\n\t\treturn mapValue, nil\n\t}\n\treturn value, nil\n}\n\nvar transformStringOrNumberList TransformerFunc = func(value interface{}) (interface{}, error) {\n\tlist := value.([]interface{})\n\tresult := make([]string, len(list))\n\tfor i, item := range list {\n\t\tresult[i] = fmt.Sprint(item)\n\t}\n\treturn result, nil\n}\n\nvar transformStringList TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn []string{value}, nil\n\tcase []interface{}:\n\t\treturn value, nil\n\tdefault:\n\t\treturn data, errors.Errorf(\"invalid type %T for string list\", value)\n\t}\n}\n\nfunc transformMappingOrListFunc(sep string, allowNil bool) TransformerFunc {\n\treturn func(data interface{}) (interface{}, error) {\n\t\treturn transformMappingOrList(data, sep, allowNil), nil\n\t}\n}\n\nfunc transformListOrMappingFunc(sep string, allowNil bool) TransformerFunc {\n\treturn func(data interface{}) (interface{}, error) {\n\t\treturn transformListOrMapping(data, sep, allowNil), nil\n\t}\n}\n\nfunc transformListOrMapping(listOrMapping interface{}, sep string, allowNil bool) interface{} {\n\tswitch value := listOrMapping.(type) {\n\tcase map[string]interface{}:\n\t\treturn toStringList(value, sep, allowNil)\n\tcase []interface{}:\n\t\treturn listOrMapping\n\t}\n\tpanic(errors.Errorf(\"expected a map or a list, got %T: %#v\", listOrMapping, listOrMapping))\n}\n\nfunc transformMappingOrList(mappingOrList interface{}, sep string, allowNil bool) interface{} {\n\tswitch value := mappingOrList.(type) {\n\tcase map[string]interface{}:\n\t\treturn toMapStringString(value, allowNil)\n\tcase ([]interface{}):\n\t\tresult := make(map[string]interface{})\n\t\tfor _, value := range value {\n\t\t\tparts := strings.SplitN(value.(string), sep, 2)\n\t\t\tkey := parts[0]\n\t\t\tswitch {\n\t\t\tcase len(parts) == 1 && allowNil:\n\t\t\t\tresult[key] = nil\n\t\t\tcase len(parts) == 1 && !allowNil:\n\t\t\t\tresult[key] = \"\"\n\t\t\tdefault:\n\t\t\t\tresult[key] = parts[1]\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\tpanic(errors.Errorf(\"expected a map or a list, got %T: %#v\", mappingOrList, mappingOrList))\n}\n\nvar transformShellCommand TransformerFunc = func(value interface{}) (interface{}, error) {\n\tif str, ok := value.(string); ok {\n\t\treturn shellwords.Parse(str)\n\t}\n\treturn value, nil\n}\n\nvar transformHealthCheckTest TransformerFunc = func(data interface{}) (interface{}, error) {\n\tswitch value := data.(type) {\n\tcase string:\n\t\treturn append([]string{\"CMD-SHELL\"}, value), nil\n\tcase []interface{}:\n\t\treturn value, nil\n\tdefault:\n\t\treturn value, errors.Errorf(\"invalid type %T for healthcheck.test\", value)\n\t}\n}\n\nvar transformSize TransformerFunc = func(value interface{}) (interface{}, error) {\n\tswitch value := value.(type) {\n\tcase int:\n\t\treturn int64(value), nil\n\tcase int64, types.UnitBytes:\n\t\treturn value, nil\n\tcase string:\n\t\treturn units.RAMInBytes(value)\n\tdefault:\n\t\treturn value, errors.Errorf(\"invalid type for size %T\", value)\n\t}\n}\n\nvar transformStringToDuration TransformerFunc = func(value interface{}) (interface{}, error) {\n\tswitch value := value.(type) {\n\tcase string:\n\t\td, err := time.ParseDuration(value)\n\t\tif err != nil {\n\t\t\treturn value, err\n\t\t}\n\t\treturn types.Duration(d), nil\n\tdefault:\n\t\treturn value, errors.Errorf(\"invalid type %T for duration\", value)\n\t}\n}\n\nfunc toMapStringString(value map[string]interface{}, allowNil bool) map[string]interface{} {\n\toutput := make(map[string]interface{})\n\tfor key, value := range value {\n\t\toutput[key] = toString(value, allowNil)\n\t}\n\treturn output\n}\n\nfunc toString(value interface{}, allowNil bool) interface{} {\n\tswitch {\n\tcase value != nil:\n\t\treturn fmt.Sprint(value)\n\tcase allowNil:\n\t\treturn nil\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc toStringList(value map[string]interface{}, separator string, allowNil bool) []string {\n\toutput := []string{}\n\tfor key, value := range value {\n\t\tif value == nil && !allowNil {\n\t\t\tcontinue\n\t\t}\n\t\toutput = append(output, fmt.Sprintf(\"%s%s%s\", key, separator, value))\n\t}\n\tsort.Strings(output)\n\treturn output\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/merge.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"reflect\"\n\t\"sort\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/imdario/mergo\"\n\t\"github.com/pkg/errors\"\n)\n\ntype specials struct {\n\tm map[reflect.Type]func(dst, src reflect.Value) error\n}\n\nvar serviceSpecials = &specials{\n\tm: map[reflect.Type]func(dst, src reflect.Value) error{\n\t\treflect.TypeOf(&types.LoggingConfig{}):           safelyMerge(mergeLoggingConfig),\n\t\treflect.TypeOf(&types.UlimitsConfig{}):           safelyMerge(mergeUlimitsConfig),\n\t\treflect.TypeOf([]types.ServiceVolumeConfig{}):    mergeSlice(toServiceVolumeConfigsMap, toServiceVolumeConfigsSlice),\n\t\treflect.TypeOf([]types.ServicePortConfig{}):      mergeSlice(toServicePortConfigsMap, toServicePortConfigsSlice),\n\t\treflect.TypeOf([]types.ServiceSecretConfig{}):    mergeSlice(toServiceSecretConfigsMap, toServiceSecretConfigsSlice),\n\t\treflect.TypeOf([]types.ServiceConfigObjConfig{}): mergeSlice(toServiceConfigObjConfigsMap, toSServiceConfigObjConfigsSlice),\n\t\treflect.TypeOf(&types.UlimitsConfig{}):           mergeUlimitsConfig,\n\t\treflect.TypeOf(&types.ServiceNetworkConfig{}):    mergeServiceNetworkConfig,\n\t},\n}\n\nfunc (s *specials) Transformer(t reflect.Type) func(dst, src reflect.Value) error {\n\tif fn, ok := s.m[t]; ok {\n\t\treturn fn\n\t}\n\treturn nil\n}\n\nfunc merge(configs []*types.Config) (*types.Config, error) {\n\tbase := configs[0]\n\tfor _, override := range configs[1:] {\n\t\tvar err error\n\t\tbase.Services, err = mergeServices(base.Services, override.Services)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge services from %s\", override.Filename)\n\t\t}\n\t\tbase.Volumes, err = mergeVolumes(base.Volumes, override.Volumes)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge volumes from %s\", override.Filename)\n\t\t}\n\t\tbase.Networks, err = mergeNetworks(base.Networks, override.Networks)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge networks from %s\", override.Filename)\n\t\t}\n\t\tbase.Secrets, err = mergeSecrets(base.Secrets, override.Secrets)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge secrets from %s\", override.Filename)\n\t\t}\n\t\tbase.Configs, err = mergeConfigs(base.Configs, override.Configs)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge configs from %s\", override.Filename)\n\t\t}\n\t\tbase.Extensions, err = mergeExtensions(base.Extensions, override.Extensions)\n\t\tif err != nil {\n\t\t\treturn base, errors.Wrapf(err, \"cannot merge extensions from %s\", override.Filename)\n\t\t}\n\t}\n\treturn base, nil\n}\n\nfunc mergeServices(base, override []types.ServiceConfig) ([]types.ServiceConfig, error) {\n\tbaseServices := mapByName(base)\n\toverrideServices := mapByName(override)\n\tfor name, overrideService := range overrideServices {\n\t\toverrideService := overrideService\n\t\tif baseService, ok := baseServices[name]; ok {\n\t\t\tmerged, err := _merge(&baseService, &overrideService)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrapf(err, \"cannot merge service %s\", name)\n\t\t\t}\n\t\t\tbaseServices[name] = *merged\n\t\t\tcontinue\n\t\t}\n\t\tbaseServices[name] = overrideService\n\t}\n\tservices := []types.ServiceConfig{}\n\tfor _, baseService := range baseServices {\n\t\tservices = append(services, baseService)\n\t}\n\tsort.Slice(services, func(i, j int) bool { return services[i].Name < services[j].Name })\n\treturn services, nil\n}\n\nfunc _merge(baseService *types.ServiceConfig, overrideService *types.ServiceConfig) (*types.ServiceConfig, error) {\n\tif err := mergo.Merge(baseService, overrideService, mergo.WithAppendSlice, mergo.WithOverride, mergo.WithTransformers(serviceSpecials)); err != nil {\n\t\treturn nil, err\n\t}\n\tif overrideService.Command != nil {\n\t\tbaseService.Command = overrideService.Command\n\t}\n\tif overrideService.Entrypoint != nil {\n\t\tbaseService.Entrypoint = overrideService.Entrypoint\n\t}\n\treturn baseService, nil\n}\n\nfunc toServiceSecretConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tsecrets, ok := s.([]types.ServiceSecretConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a serviceSecretConfig: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\tfor _, secret := range secrets {\n\t\tm[secret.Source] = secret\n\t}\n\treturn m, nil\n}\n\nfunc toServiceConfigObjConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tsecrets, ok := s.([]types.ServiceConfigObjConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a serviceSecretConfig: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\tfor _, secret := range secrets {\n\t\tm[secret.Source] = secret\n\t}\n\treturn m, nil\n}\n\nfunc toServicePortConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tports, ok := s.([]types.ServicePortConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a servicePortConfig slice: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\ttype port struct {\n\t\ttarget    uint32\n\t\tpublished uint32\n\t\tip        string\n\t\tprotocol  string\n\t}\n\n\tfor _, p := range ports {\n\t\tmergeKey := port{\n\t\t\ttarget:    p.Target,\n\t\t\tpublished: p.Published,\n\t\t\tip:        p.HostIP,\n\t\t\tprotocol:  p.Protocol,\n\t\t}\n\t\tm[mergeKey] = p\n\t}\n\treturn m, nil\n}\n\nfunc toServiceVolumeConfigsMap(s interface{}) (map[interface{}]interface{}, error) {\n\tvolumes, ok := s.([]types.ServiceVolumeConfig)\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"not a ServiceVolumeConfig slice: %v\", s)\n\t}\n\tm := map[interface{}]interface{}{}\n\tfor _, v := range volumes {\n\t\tm[v.Target] = v\n\t}\n\treturn m, nil\n}\n\nfunc toServiceSecretConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServiceSecretConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServiceSecretConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool { return s[i].Source < s[j].Source })\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\nfunc toSServiceConfigObjConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServiceConfigObjConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServiceConfigObjConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool { return s[i].Source < s[j].Source })\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\nfunc toServicePortConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServicePortConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServicePortConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool {\n\t\tif s[i].Target != s[j].Target {\n\t\t\treturn s[i].Target < s[j].Target\n\t\t}\n\t\tif s[i].Published != s[j].Published {\n\t\t\treturn s[i].Published < s[j].Published\n\t\t}\n\t\tif s[i].HostIP != s[j].HostIP {\n\t\t\treturn s[i].HostIP < s[j].HostIP\n\t\t}\n\t\treturn s[i].Protocol < s[j].Protocol\n\t})\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\nfunc toServiceVolumeConfigsSlice(dst reflect.Value, m map[interface{}]interface{}) error {\n\ts := []types.ServiceVolumeConfig{}\n\tfor _, v := range m {\n\t\ts = append(s, v.(types.ServiceVolumeConfig))\n\t}\n\tsort.Slice(s, func(i, j int) bool { return s[i].Target < s[j].Target })\n\tdst.Set(reflect.ValueOf(s))\n\treturn nil\n}\n\ntype tomapFn func(s interface{}) (map[interface{}]interface{}, error)\ntype writeValueFromMapFn func(reflect.Value, map[interface{}]interface{}) error\n\nfunc safelyMerge(mergeFn func(dst, src reflect.Value) error) func(dst, src reflect.Value) error {\n\treturn func(dst, src reflect.Value) error {\n\t\tif src.IsNil() {\n\t\t\treturn nil\n\t\t}\n\t\tif dst.IsNil() {\n\t\t\tdst.Set(src)\n\t\t\treturn nil\n\t\t}\n\t\treturn mergeFn(dst, src)\n\t}\n}\n\nfunc mergeSlice(tomap tomapFn, writeValue writeValueFromMapFn) func(dst, src reflect.Value) error {\n\treturn func(dst, src reflect.Value) error {\n\t\tdstMap, err := sliceToMap(tomap, dst)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsrcMap, err := sliceToMap(tomap, src)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := mergo.Map(&dstMap, srcMap, mergo.WithOverride); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn writeValue(dst, dstMap)\n\t}\n}\n\nfunc sliceToMap(tomap tomapFn, v reflect.Value) (map[interface{}]interface{}, error) {\n\t// check if valid\n\tif !v.IsValid() {\n\t\treturn nil, errors.Errorf(\"invalid value : %+v\", v)\n\t}\n\treturn tomap(v.Interface())\n}\n\nfunc mergeLoggingConfig(dst, src reflect.Value) error {\n\t// Same driver, merging options\n\tif getLoggingDriver(dst.Elem()) == getLoggingDriver(src.Elem()) ||\n\t\tgetLoggingDriver(dst.Elem()) == \"\" || getLoggingDriver(src.Elem()) == \"\" {\n\t\tif getLoggingDriver(dst.Elem()) == \"\" {\n\t\t\tdst.Elem().FieldByName(\"Driver\").SetString(getLoggingDriver(src.Elem()))\n\t\t}\n\t\tdstOptions := dst.Elem().FieldByName(\"Options\").Interface().(map[string]string)\n\t\tsrcOptions := src.Elem().FieldByName(\"Options\").Interface().(map[string]string)\n\t\treturn mergo.Merge(&dstOptions, srcOptions, mergo.WithOverride)\n\t}\n\t// Different driver, override with src\n\tdst.Set(src)\n\treturn nil\n}\n\n// nolint: unparam\nfunc mergeUlimitsConfig(dst, src reflect.Value) error {\n\tif src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {\n\t\tdst.Elem().Set(src.Elem())\n\t}\n\treturn nil\n}\n\n// nolint: unparam\nfunc mergeServiceNetworkConfig(dst, src reflect.Value) error {\n\tif src.Interface() != reflect.Zero(reflect.TypeOf(src.Interface())).Interface() {\n\t\tdst.Elem().FieldByName(\"Aliases\").Set(src.Elem().FieldByName(\"Aliases\"))\n\t\tif ipv4 := src.Elem().FieldByName(\"Ipv4Address\").Interface().(string); ipv4 != \"\" {\n\t\t\tdst.Elem().FieldByName(\"Ipv4Address\").SetString(ipv4)\n\t\t}\n\t\tif ipv6 := src.Elem().FieldByName(\"Ipv6Address\").Interface().(string); ipv6 != \"\" {\n\t\t\tdst.Elem().FieldByName(\"Ipv6Address\").SetString(ipv6)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc getLoggingDriver(v reflect.Value) string {\n\treturn v.FieldByName(\"Driver\").String()\n}\n\nfunc mapByName(services []types.ServiceConfig) map[string]types.ServiceConfig {\n\tm := map[string]types.ServiceConfig{}\n\tfor _, service := range services {\n\t\tm[service.Name] = service\n\t}\n\treturn m\n}\n\nfunc mergeVolumes(base, override map[string]types.VolumeConfig) (map[string]types.VolumeConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeNetworks(base, override map[string]types.NetworkConfig) (map[string]types.NetworkConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeSecrets(base, override map[string]types.SecretConfig) (map[string]types.SecretConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeConfigs(base, override map[string]types.ConfigObjConfig) (map[string]types.ConfigObjConfig, error) {\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n\nfunc mergeExtensions(base, override map[string]interface{}) (map[string]interface{}, error) {\n\tif base == nil {\n\t\tbase = map[string]interface{}{}\n\t}\n\terr := mergo.Map(&base, &override, mergo.WithOverride)\n\treturn base, err\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/normalize.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n)\n\n// normalize compose project by moving deprecated attributes to their canonical position and injecting implicit defaults\nfunc normalize(project *types.Project, resolvePaths bool) error {\n\tabsWorkingDir, err := filepath.Abs(project.WorkingDir)\n\tif err != nil {\n\t\treturn err\n\t}\n\tproject.WorkingDir = absWorkingDir\n\n\tabsComposeFiles, err := absComposeFiles(project.ComposeFiles)\n\tif err != nil {\n\t\treturn err\n\t}\n\tproject.ComposeFiles = absComposeFiles\n\n\t// If not declared explicitly, Compose model involves an implicit \"default\" network\n\tif _, ok := project.Networks[\"default\"]; !ok {\n\t\tproject.Networks[\"default\"] = types.NetworkConfig{}\n\t}\n\n\terr = relocateExternalName(project)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor i, s := range project.Services {\n\t\tif len(s.Networks) == 0 && s.NetworkMode == \"\" {\n\t\t\t// Service without explicit network attachment are implicitly exposed on default network\n\t\t\ts.Networks = map[string]*types.ServiceNetworkConfig{\"default\": nil}\n\t\t}\n\n\t\tif s.PullPolicy == types.PullPolicyIfNotPresent {\n\t\t\ts.PullPolicy = types.PullPolicyMissing\n\t\t}\n\n\t\tfn := func(s string) (string, bool) {\n\t\t\tv, ok := project.Environment[s]\n\t\t\treturn v, ok\n\t\t}\n\n\t\tif s.Build != nil {\n\t\t\tif s.Build.Dockerfile == \"\" {\n\t\t\t\ts.Build.Dockerfile = \"Dockerfile\"\n\t\t\t}\n\t\t\tlocalContext := absPath(project.WorkingDir, s.Build.Context)\n\t\t\tif _, err := os.Stat(localContext); err == nil {\n\t\t\t\tif resolvePaths {\n\t\t\t\t\ts.Build.Context = localContext\n\t\t\t\t\ts.Build.Dockerfile = absPath(localContext, s.Build.Dockerfile)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// might be a remote http/git context. Unfortunately supported \"remote\" syntax is highly ambiguous\n\t\t\t\t// in moby/moby and not defined by compose-spec, so let's assume runtime will check\n\t\t\t}\n\t\t\ts.Build.Args = s.Build.Args.Resolve(fn)\n\t\t}\n\t\ts.Environment = s.Environment.Resolve(fn)\n\n\t\terr := relocateLogDriver(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = relocateLogOpt(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = relocateDockerfile(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\terr = relocateScale(&s)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tproject.Services[i] = s\n\t}\n\n\tsetNameFromKey(project)\n\n\treturn nil\n}\n\nfunc relocateScale(s *types.ServiceConfig) error {\n\tscale := uint64(s.Scale)\n\tif scale != 1 {\n\t\tlogrus.Warn(\"`scale` is deprecated. Use the `deploy.replicas` element\")\n\t\tif s.Deploy == nil {\n\t\t\ts.Deploy = &types.DeployConfig{}\n\t\t}\n\t\tif s.Deploy.Replicas != nil && *s.Deploy.Replicas != scale {\n\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'scale' (deprecated) and 'deploy.replicas'\")\n\t\t}\n\t\ts.Deploy.Replicas = &scale\n\t}\n\treturn nil\n}\n\nfunc absComposeFiles(composeFiles []string) ([]string, error) {\n\tabsComposeFiles := make([]string, len(composeFiles))\n\tfor i, composeFile := range composeFiles {\n\t\tabsComposefile, err := filepath.Abs(composeFile)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tabsComposeFiles[i] = absComposefile\n\t}\n\treturn absComposeFiles, nil\n}\n\n// Resources with no explicit name are actually named by their key in map\nfunc setNameFromKey(project *types.Project) {\n\tfor i, n := range project.Networks {\n\t\tif n.Name == \"\" {\n\t\t\tn.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Networks[i] = n\n\t\t}\n\t}\n\n\tfor i, v := range project.Volumes {\n\t\tif v.Name == \"\" {\n\t\t\tv.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Volumes[i] = v\n\t\t}\n\t}\n\n\tfor i, c := range project.Configs {\n\t\tif c.Name == \"\" {\n\t\t\tc.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Configs[i] = c\n\t\t}\n\t}\n\n\tfor i, s := range project.Secrets {\n\t\tif s.Name == \"\" {\n\t\t\ts.Name = fmt.Sprintf(\"%s_%s\", project.Name, i)\n\t\t\tproject.Secrets[i] = s\n\t\t}\n\t}\n}\n\nfunc relocateExternalName(project *types.Project) error {\n\tfor i, n := range project.Networks {\n\t\tif n.External.Name != \"\" {\n\t\t\tif n.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'networks.external.name' (deprecated) and 'networks.name'\")\n\t\t\t}\n\t\t\tn.Name = n.External.Name\n\t\t}\n\t\tproject.Networks[i] = n\n\t}\n\n\tfor i, v := range project.Volumes {\n\t\tif v.External.Name != \"\" {\n\t\t\tif v.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'volumes.external.name' (deprecated) and 'volumes.name'\")\n\t\t\t}\n\t\t\tv.Name = v.External.Name\n\t\t}\n\t\tproject.Volumes[i] = v\n\t}\n\n\tfor i, s := range project.Secrets {\n\t\tif s.External.Name != \"\" {\n\t\t\tif s.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'secrets.external.name' (deprecated) and 'secrets.name'\")\n\t\t\t}\n\t\t\ts.Name = s.External.Name\n\t\t}\n\t\tproject.Secrets[i] = s\n\t}\n\n\tfor i, c := range project.Configs {\n\t\tif c.External.Name != \"\" {\n\t\t\tif c.Name != \"\" {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'configs.external.name' (deprecated) and 'configs.name'\")\n\t\t\t}\n\t\t\tc.Name = c.External.Name\n\t\t}\n\t\tproject.Configs[i] = c\n\t}\n\treturn nil\n}\n\nfunc relocateLogOpt(s *types.ServiceConfig) error {\n\tif len(s.LogOpt) != 0 {\n\t\tlogrus.Warn(\"`log_opts` is deprecated. Use the `logging` element\")\n\t\tif s.Logging == nil {\n\t\t\ts.Logging = &types.LoggingConfig{}\n\t\t}\n\t\tfor k, v := range s.LogOpt {\n\t\t\tif _, ok := s.Logging.Options[k]; !ok {\n\t\t\t\ts.Logging.Options[k] = v\n\t\t\t} else {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'log_opt' (deprecated) and 'logging.options'\")\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc relocateLogDriver(s *types.ServiceConfig) error {\n\tif s.LogDriver != \"\" {\n\t\tlogrus.Warn(\"`log_driver` is deprecated. Use the `logging` element\")\n\t\tif s.Logging == nil {\n\t\t\ts.Logging = &types.LoggingConfig{}\n\t\t}\n\t\tif s.Logging.Driver == \"\" {\n\t\t\ts.Logging.Driver = s.LogDriver\n\t\t} else {\n\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'log_driver' (deprecated) and 'logging.driver'\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc relocateDockerfile(s *types.ServiceConfig) error {\n\tif s.Dockerfile != \"\" {\n\t\tlogrus.Warn(\"`dockerfile` is deprecated. Use the `build` element\")\n\t\tif s.Build == nil {\n\t\t\ts.Build = &types.BuildConfig{}\n\t\t}\n\t\tif s.Dockerfile == \"\" {\n\t\t\ts.Build.Dockerfile = s.Dockerfile\n\t\t} else {\n\t\t\treturn errors.Wrap(errdefs.ErrInvalid, \"can't use both 'dockerfile' (deprecated) and 'build.dockerfile'\")\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/validate.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/compose-spec/compose-go/errdefs\"\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n)\n\n// checkConsistency validate a compose model is consistent\nfunc checkConsistency(project *types.Project) error {\n\tfor _, s := range project.Services {\n\t\tif s.Build == nil && s.Image == \"\" {\n\t\t\treturn errors.Wrapf(errdefs.ErrInvalid, \"service %q has neither an image nor a build context specified\", s.Name)\n\t\t}\n\n\t\tfor network := range s.Networks {\n\t\t\tif _, ok := project.Networks[network]; !ok {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined network %s\", s.Name, network))\n\t\t\t}\n\t\t}\n\n\t\tif strings.HasPrefix(s.NetworkMode, types.ServicePrefix) {\n\t\t\tserviceName := s.NetworkMode[len(types.ServicePrefix):]\n\t\t\tif _, err := project.GetServices(serviceName); err != nil {\n\t\t\t\treturn fmt.Errorf(\"service %q not found for network_mode 'service:%s'\", serviceName, serviceName)\n\t\t\t}\n\t\t}\n\n\t\tfor _, volume := range s.Volumes {\n\t\t\tswitch volume.Type {\n\t\t\tcase types.VolumeTypeVolume:\n\t\t\t\tif volume.Source != \"\" { // non anonymous volumes\n\t\t\t\t\tif _, ok := project.Volumes[volume.Source]; !ok {\n\t\t\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined volume %s\", s.Name, volume.Source))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor _, secret := range s.Secrets {\n\t\t\tif _, ok := project.Secrets[secret.Source]; !ok {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined secret %s\", s.Name, secret.Source))\n\t\t\t}\n\t\t}\n\t\tfor _, config := range s.Configs {\n\t\t\tif _, ok := project.Configs[config.Source]; !ok {\n\t\t\t\treturn errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf(\"service %q refers to undefined config %s\", s.Name, config.Source))\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/volume.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\nimport (\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/compose-spec/compose-go/types\"\n\t\"github.com/pkg/errors\"\n)\n\nconst endOfSpec = rune(0)\n\n// ParseVolume parses a volume spec without any knowledge of the target platform\nfunc ParseVolume(spec string) (types.ServiceVolumeConfig, error) {\n\tvolume := types.ServiceVolumeConfig{}\n\n\tswitch len(spec) {\n\tcase 0:\n\t\treturn volume, errors.New(\"invalid empty volume spec\")\n\tcase 1, 2:\n\t\tvolume.Target = spec\n\t\tvolume.Type = string(types.VolumeTypeVolume)\n\t\treturn volume, nil\n\t}\n\n\tbuffer := []rune{}\n\tfor _, char := range spec + string(endOfSpec) {\n\t\tswitch {\n\t\tcase isWindowsDrive(buffer, char):\n\t\t\tbuffer = append(buffer, char)\n\t\tcase char == ':' || char == endOfSpec:\n\t\t\tif err := populateFieldFromBuffer(char, buffer, &volume); err != nil {\n\t\t\t\tpopulateType(&volume)\n\t\t\t\treturn volume, errors.Wrapf(err, \"invalid spec: %s\", spec)\n\t\t\t}\n\t\t\tbuffer = []rune{}\n\t\tdefault:\n\t\t\tbuffer = append(buffer, char)\n\t\t}\n\t}\n\n\tpopulateType(&volume)\n\treturn volume, nil\n}\n\nfunc isWindowsDrive(buffer []rune, char rune) bool {\n\treturn char == ':' && len(buffer) == 1 && unicode.IsLetter(buffer[0])\n}\n\nfunc populateFieldFromBuffer(char rune, buffer []rune, volume *types.ServiceVolumeConfig) error {\n\tstrBuffer := string(buffer)\n\tswitch {\n\tcase len(buffer) == 0:\n\t\treturn errors.New(\"empty section between colons\")\n\t// Anonymous volume\n\tcase volume.Source == \"\" && char == endOfSpec:\n\t\tvolume.Target = strBuffer\n\t\treturn nil\n\tcase volume.Source == \"\":\n\t\tvolume.Source = strBuffer\n\t\treturn nil\n\tcase volume.Target == \"\":\n\t\tvolume.Target = strBuffer\n\t\treturn nil\n\tcase char == ':':\n\t\treturn errors.New(\"too many colons\")\n\t}\n\tfor _, option := range strings.Split(strBuffer, \",\") {\n\t\tswitch option {\n\t\tcase \"ro\":\n\t\t\tvolume.ReadOnly = true\n\t\tcase \"rw\":\n\t\t\tvolume.ReadOnly = false\n\t\tcase \"nocopy\":\n\t\t\tvolume.Volume = &types.ServiceVolumeVolume{NoCopy: true}\n\t\tdefault:\n\t\t\tif isBindOption(option) {\n\t\t\t\tvolume.Bind = &types.ServiceVolumeBind{Propagation: option}\n\t\t\t}\n\t\t\t// ignore unknown options\n\t\t}\n\t}\n\treturn nil\n}\n\nvar Propagations = []string{\n\ttypes.PropagationRPrivate,\n\ttypes.PropagationPrivate,\n\ttypes.PropagationRShared,\n\ttypes.PropagationShared,\n\ttypes.PropagationRSlave,\n\ttypes.PropagationSlave,\n}\n\nfunc isBindOption(option string) bool {\n\tfor _, propagation := range Propagations {\n\t\tif option == propagation {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc populateType(volume *types.ServiceVolumeConfig) {\n\tif isFilePath(volume.Source) {\n\t\tvolume.Type = types.VolumeTypeBind\n\t\tif volume.Bind == nil {\n\t\t\tvolume.Bind = &types.ServiceVolumeBind{}\n\t\t}\n\t\t// For backward compatibility with docker-compose legacy, using short notation involves\n\t\t// bind will create missing host path\n\t\tvolume.Bind.CreateHostPath = true\n\t} else {\n\t\tvolume.Type = types.VolumeTypeVolume\n\t\tif volume.Volume == nil {\n\t\t\tvolume.Volume = &types.ServiceVolumeVolume{}\n\t\t}\n\t}\n}\n\nfunc isFilePath(source string) bool {\n\tif source == \"\" {\n\t\treturn false\n\t}\n\tswitch source[0] {\n\tcase '.', '/', '~':\n\t\treturn true\n\t}\n\n\t// windows named pipes\n\tif strings.HasPrefix(source, `\\\\`) {\n\t\treturn true\n\t}\n\n\tfirst, nextIndex := utf8.DecodeRuneInString(source)\n\treturn isWindowsDrive([]rune{first}, rune(source[nextIndex]))\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/loader/windows_path.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage loader\n\n// 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// https://github.com/golang/go/blob/master/LICENSE\n\n// This file contains utilities to check for Windows absolute paths on Linux.\n// The code in this file was largely copied from the Golang filepath package\n// https://github.com/golang/go/blob/1d0e94b1e13d5e8a323a63cd1cc1ef95290c9c36/src/path/filepath/path_windows.go#L12-L65\n\nfunc isSlash(c uint8) bool {\n\treturn c == '\\\\' || c == '/'\n}\n\n// isAbs reports whether the path is a Windows absolute path.\nfunc isAbs(path string) (b bool) {\n\tl := volumeNameLen(path)\n\tif l == 0 {\n\t\treturn false\n\t}\n\tpath = path[l:]\n\tif path == \"\" {\n\t\treturn false\n\t}\n\treturn isSlash(path[0])\n}\n\n// volumeNameLen returns length of the leading volume name on Windows.\n// It returns 0 elsewhere.\n// nolint: gocyclo\nfunc volumeNameLen(path string) int {\n\tif len(path) < 2 {\n\t\treturn 0\n\t}\n\t// with drive letter\n\tc := path[0]\n\tif path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {\n\t\treturn 2\n\t}\n\t// is it UNC? https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx\n\tif l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&\n\t\t!isSlash(path[2]) && path[2] != '.' {\n\t\t// first, leading `\\\\` and next shouldn't be `\\`. its server name.\n\t\tfor n := 3; n < l-1; n++ {\n\t\t\t// second, next '\\' shouldn't be repeated.\n\t\t\tif isSlash(path[n]) {\n\t\t\t\tn++\n\t\t\t\t// third, following something characters. its share name.\n\t\t\t\tif !isSlash(path[n]) {\n\t\t\t\t\tif path[n] == '.' {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tfor ; n < l; n++ {\n\t\t\t\t\t\tif isSlash(path[n]) {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn n\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/template/template.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage template\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\nvar delimiter = \"\\\\$\"\nvar substitutionNamed = \"[_a-z][_a-z0-9]*\"\nvar substitutionBraced = \"[_a-z][_a-z0-9]*(?::?[-?][^}]*)?\"\n\nvar patternString = fmt.Sprintf(\n\t\"%s(?i:(?P<escaped>%s)|(?P<named>%s)|{(?P<braced>%s)}|(?P<invalid>))\",\n\tdelimiter, delimiter, substitutionNamed, substitutionBraced,\n)\n\nvar defaultPattern = regexp.MustCompile(patternString)\n\n// DefaultSubstituteFuncs contains the default SubstituteFunc used by the docker cli\nvar DefaultSubstituteFuncs = []SubstituteFunc{\n\tsoftDefault,\n\thardDefault,\n\trequiredNonEmpty,\n\trequired,\n}\n\n// InvalidTemplateError is returned when a variable template is not in a valid\n// format\ntype InvalidTemplateError struct {\n\tTemplate string\n}\n\nfunc (e InvalidTemplateError) Error() string {\n\treturn fmt.Sprintf(\"Invalid template: %#v\", e.Template)\n}\n\n// Mapping is a user-supplied function which maps from variable names to values.\n// Returns the value as a string and a bool indicating whether\n// the value is present, to distinguish between an empty string\n// and the absence of a value.\ntype Mapping func(string) (string, bool)\n\n// SubstituteFunc is a user-supplied function that apply substitution.\n// Returns the value as a string, a bool indicating if the function could apply\n// the substitution and an error.\ntype SubstituteFunc func(string, Mapping) (string, bool, error)\n\n// SubstituteWith substitute variables in the string with their values.\n// It accepts additional substitute function.\nfunc SubstituteWith(template string, mapping Mapping, pattern *regexp.Regexp, subsFuncs ...SubstituteFunc) (string, error) {\n\tvar err error\n\tresult := pattern.ReplaceAllStringFunc(template, func(substring string) string {\n\t\tmatches := pattern.FindStringSubmatch(substring)\n\t\tgroups := matchGroups(matches, pattern)\n\t\tif escaped := groups[\"escaped\"]; escaped != \"\" {\n\t\t\treturn escaped\n\t\t}\n\n\t\tbraced := false\n\t\tsubstitution := groups[\"named\"]\n\t\tif substitution == \"\" {\n\t\t\tsubstitution = groups[\"braced\"]\n\t\t\tbraced = true\n\t\t}\n\n\t\tif substitution == \"\" {\n\t\t\terr = &InvalidTemplateError{Template: template}\n\t\t\treturn \"\"\n\t\t}\n\n\t\tif braced {\n\t\t\tfor _, f := range subsFuncs {\n\t\t\t\tvar (\n\t\t\t\t\tvalue   string\n\t\t\t\t\tapplied bool\n\t\t\t\t)\n\t\t\t\tvalue, applied, err = f(substitution, mapping)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn \"\"\n\t\t\t\t}\n\t\t\t\tif !applied {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn value\n\t\t\t}\n\t\t}\n\n\t\tvalue, ok := mapping(substitution)\n\t\tif !ok {\n\t\t\tlogrus.Warnf(\"The %q variable is not set. Defaulting to a blank string.\", substitution)\n\t\t}\n\t\treturn value\n\t})\n\n\treturn result, err\n}\n\n// Substitute variables in the string with their values\nfunc Substitute(template string, mapping Mapping) (string, error) {\n\treturn SubstituteWith(template, mapping, defaultPattern, DefaultSubstituteFuncs...)\n}\n\n// ExtractVariables returns a map of all the variables defined in the specified\n// composefile (dict representation) and their default value if any.\nfunc ExtractVariables(configDict map[string]interface{}, pattern *regexp.Regexp) map[string]Variable {\n\tif pattern == nil {\n\t\tpattern = defaultPattern\n\t}\n\treturn recurseExtract(configDict, pattern)\n}\n\nfunc recurseExtract(value interface{}, pattern *regexp.Regexp) map[string]Variable {\n\tm := map[string]Variable{}\n\n\tswitch value := value.(type) {\n\tcase string:\n\t\tif values, is := extractVariable(value, pattern); is {\n\t\t\tfor _, v := range values {\n\t\t\t\tm[v.Name] = v\n\t\t\t}\n\t\t}\n\tcase map[string]interface{}:\n\t\tfor _, elem := range value {\n\t\t\tsubmap := recurseExtract(elem, pattern)\n\t\t\tfor key, value := range submap {\n\t\t\t\tm[key] = value\n\t\t\t}\n\t\t}\n\n\tcase []interface{}:\n\t\tfor _, elem := range value {\n\t\t\tif values, is := extractVariable(elem, pattern); is {\n\t\t\t\tfor _, v := range values {\n\t\t\t\t\tm[v.Name] = v\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn m\n}\n\ntype Variable struct {\n\tName         string\n\tDefaultValue string\n\tRequired     bool\n}\n\nfunc extractVariable(value interface{}, pattern *regexp.Regexp) ([]Variable, bool) {\n\tsValue, ok := value.(string)\n\tif !ok {\n\t\treturn []Variable{}, false\n\t}\n\tmatches := pattern.FindAllStringSubmatch(sValue, -1)\n\tif len(matches) == 0 {\n\t\treturn []Variable{}, false\n\t}\n\tvalues := []Variable{}\n\tfor _, match := range matches {\n\t\tgroups := matchGroups(match, pattern)\n\t\tif escaped := groups[\"escaped\"]; escaped != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tval := groups[\"named\"]\n\t\tif val == \"\" {\n\t\t\tval = groups[\"braced\"]\n\t\t}\n\t\tname := val\n\t\tvar defaultValue string\n\t\tvar required bool\n\t\tswitch {\n\t\tcase strings.Contains(val, \":?\"):\n\t\t\tname, _ = partition(val, \":?\")\n\t\t\trequired = true\n\t\tcase strings.Contains(val, \"?\"):\n\t\t\tname, _ = partition(val, \"?\")\n\t\t\trequired = true\n\t\tcase strings.Contains(val, \":-\"):\n\t\t\tname, defaultValue = partition(val, \":-\")\n\t\tcase strings.Contains(val, \"-\"):\n\t\t\tname, defaultValue = partition(val, \"-\")\n\t\t}\n\t\tvalues = append(values, Variable{\n\t\t\tName:         name,\n\t\t\tDefaultValue: defaultValue,\n\t\t\tRequired:     required,\n\t\t})\n\t}\n\treturn values, len(values) > 0\n}\n\n// Soft default (fall back if unset or empty)\nfunc softDefault(substitution string, mapping Mapping) (string, bool, error) {\n\tsep := \":-\"\n\tif !strings.Contains(substitution, sep) {\n\t\treturn \"\", false, nil\n\t}\n\tname, defaultValue := partition(substitution, sep)\n\tvalue, ok := mapping(name)\n\tif !ok || value == \"\" {\n\t\treturn defaultValue, true, nil\n\t}\n\treturn value, true, nil\n}\n\n// Hard default (fall back if-and-only-if empty)\nfunc hardDefault(substitution string, mapping Mapping) (string, bool, error) {\n\tsep := \"-\"\n\tif !strings.Contains(substitution, sep) {\n\t\treturn \"\", false, nil\n\t}\n\tname, defaultValue := partition(substitution, sep)\n\tvalue, ok := mapping(name)\n\tif !ok {\n\t\treturn defaultValue, true, nil\n\t}\n\treturn value, true, nil\n}\n\nfunc requiredNonEmpty(substitution string, mapping Mapping) (string, bool, error) {\n\treturn withRequired(substitution, mapping, \":?\", func(v string) bool { return v != \"\" })\n}\n\nfunc required(substitution string, mapping Mapping) (string, bool, error) {\n\treturn withRequired(substitution, mapping, \"?\", func(_ string) bool { return true })\n}\n\nfunc withRequired(substitution string, mapping Mapping, sep string, valid func(string) bool) (string, bool, error) {\n\tif !strings.Contains(substitution, sep) {\n\t\treturn \"\", false, nil\n\t}\n\tname, errorMessage := partition(substitution, sep)\n\tvalue, ok := mapping(name)\n\tif !ok || !valid(value) {\n\t\treturn \"\", true, &InvalidTemplateError{\n\t\t\tTemplate: fmt.Sprintf(\"required variable %s is missing a value: %s\", name, errorMessage),\n\t\t}\n\t}\n\treturn value, true, nil\n}\n\nfunc matchGroups(matches []string, pattern *regexp.Regexp) map[string]string {\n\tgroups := make(map[string]string)\n\tfor i, name := range pattern.SubexpNames()[1:] {\n\t\tgroups[name] = matches[i+1]\n\t}\n\treturn groups\n}\n\n// Split the string at the first occurrence of sep, and return the part before the separator,\n// and the part after the separator.\n//\n// If the separator is not found, return the string itself, followed by an empty string.\nfunc partition(s, sep string) (string, string) {\n\tif strings.Contains(s, sep) {\n\t\tparts := strings.SplitN(s, sep, 2)\n\t\treturn parts[0], parts[1]\n\t}\n\treturn s, \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/types/config.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/mitchellh/mapstructure\"\n)\n\n// ConfigDetails are the details about a group of ConfigFiles\ntype ConfigDetails struct {\n\tVersion     string\n\tWorkingDir  string\n\tConfigFiles []ConfigFile\n\tEnvironment map[string]string\n}\n\n// LookupEnv provides a lookup function for environment variables\nfunc (cd ConfigDetails) LookupEnv(key string) (string, bool) {\n\tv, ok := cd.Environment[key]\n\treturn v, ok\n}\n\n// ConfigFile is a filename and the contents of the file as a Dict\ntype ConfigFile struct {\n\t// Filename is the name of the yaml configuration file\n\tFilename string\n\t// Content is the raw yaml content. Will be loaded from Filename if not set\n\tContent []byte\n\t// Config if the yaml tree for this config file. Will be parsed from Content if not set\n\tConfig map[string]interface{}\n}\n\n// Config is a full compose file configuration and model\ntype Config struct {\n\tFilename   string     `yaml:\"-\" json:\"-\"`\n\tServices   Services   `json:\"services\"`\n\tNetworks   Networks   `yaml:\",omitempty\" json:\"networks,omitempty\"`\n\tVolumes    Volumes    `yaml:\",omitempty\" json:\"volumes,omitempty\"`\n\tSecrets    Secrets    `yaml:\",omitempty\" json:\"secrets,omitempty\"`\n\tConfigs    Configs    `yaml:\",omitempty\" json:\"configs,omitempty\"`\n\tExtensions Extensions `yaml:\",inline\" json:\"-\"`\n}\n\n// Volumes is a map of VolumeConfig\ntype Volumes map[string]VolumeConfig\n\n// Networks is a map of NetworkConfig\ntype Networks map[string]NetworkConfig\n\n// Secrets is a map of SecretConfig\ntype Secrets map[string]SecretConfig\n\n// Configs is a map of ConfigObjConfig\ntype Configs map[string]ConfigObjConfig\n\n// Extensions is a map of custom extension\ntype Extensions map[string]interface{}\n\n// MarshalJSON makes Config implement json.Marshaler\nfunc (c Config) MarshalJSON() ([]byte, error) {\n\tm := map[string]interface{}{\n\t\t\"services\": c.Services,\n\t}\n\n\tif len(c.Networks) > 0 {\n\t\tm[\"networks\"] = c.Networks\n\t}\n\tif len(c.Volumes) > 0 {\n\t\tm[\"volumes\"] = c.Volumes\n\t}\n\tif len(c.Secrets) > 0 {\n\t\tm[\"secrets\"] = c.Secrets\n\t}\n\tif len(c.Configs) > 0 {\n\t\tm[\"configs\"] = c.Configs\n\t}\n\tfor k, v := range c.Extensions {\n\t\tm[k] = v\n\t}\n\treturn json.Marshal(m)\n}\n\nfunc (e Extensions) Get(name string, target interface{}) (bool, error) {\n\tif v, ok := e[name]; ok {\n\t\terr := mapstructure.Decode(v, target)\n\t\treturn true, err\n\t}\n\treturn false, nil\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/types/project.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\n\t\"github.com/distribution/distribution/v3/reference\"\n\t\"github.com/opencontainers/go-digest\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// Project is the result of loading a set of compose files\ntype Project struct {\n\tName         string            `yaml:\"-\" json:\"-\"`\n\tWorkingDir   string            `yaml:\"-\" json:\"-\"`\n\tServices     Services          `json:\"services\"`\n\tNetworks     Networks          `yaml:\",omitempty\" json:\"networks,omitempty\"`\n\tVolumes      Volumes           `yaml:\",omitempty\" json:\"volumes,omitempty\"`\n\tSecrets      Secrets           `yaml:\",omitempty\" json:\"secrets,omitempty\"`\n\tConfigs      Configs           `yaml:\",omitempty\" json:\"configs,omitempty\"`\n\tExtensions   Extensions        `yaml:\",inline\" json:\"-\"` // https://github.com/golang/go/issues/6213\n\tComposeFiles []string          `yaml:\"-\" json:\"-\"`\n\tEnvironment  map[string]string `yaml:\"-\" json:\"-\"`\n\n\t// DisabledServices track services which have been disable as profile is not active\n\tDisabledServices Services `yaml:\"-\" json:\"-\"`\n}\n\n// ServiceNames return names for all services in this Compose config\nfunc (p Project) ServiceNames() []string {\n\tnames := []string{}\n\tfor _, s := range p.Services {\n\t\tnames = append(names, s.Name)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// VolumeNames return names for all volumes in this Compose config\nfunc (p Project) VolumeNames() []string {\n\tnames := []string{}\n\tfor k := range p.Volumes {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// NetworkNames return names for all volumes in this Compose config\nfunc (p Project) NetworkNames() []string {\n\tnames := []string{}\n\tfor k := range p.Networks {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// SecretNames return names for all secrets in this Compose config\nfunc (p Project) SecretNames() []string {\n\tnames := []string{}\n\tfor k := range p.Secrets {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// ConfigNames return names for all configs in this Compose config\nfunc (p Project) ConfigNames() []string {\n\tnames := []string{}\n\tfor k := range p.Configs {\n\t\tnames = append(names, k)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// GetServices retrieve services by names, or return all services if no name specified\nfunc (p Project) GetServices(names ...string) (Services, error) {\n\tif len(names) == 0 {\n\t\treturn p.Services, nil\n\t}\n\tservices := Services{}\n\tfor _, name := range names {\n\t\tvar serviceConfig *ServiceConfig\n\t\tfor _, s := range p.Services {\n\t\t\tif s.Name == name {\n\t\t\t\tserviceConfig = &s\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif serviceConfig == nil {\n\t\t\treturn services, fmt.Errorf(\"no such service: %s\", name)\n\t\t}\n\t\tservices = append(services, *serviceConfig)\n\t}\n\treturn services, nil\n}\n\n// GetService retrieve a specific service by name\nfunc (p Project) GetService(name string) (ServiceConfig, error) {\n\tservices, err := p.GetServices(name)\n\tif err != nil {\n\t\treturn ServiceConfig{}, err\n\t}\n\tif len(services) == 0 {\n\t\treturn ServiceConfig{}, fmt.Errorf(\"no such service: %s\", name)\n\t}\n\treturn services[0], nil\n}\n\nfunc (p Project) AllServices() Services {\n\tvar all Services\n\tall = append(all, p.Services...)\n\tall = append(all, p.DisabledServices...)\n\treturn all\n}\n\ntype ServiceFunc func(service ServiceConfig) error\n\n// WithServices run ServiceFunc on each service and dependencies in dependency order\nfunc (p Project) WithServices(names []string, fn ServiceFunc) error {\n\treturn p.withServices(names, fn, map[string]bool{})\n}\n\nfunc (p Project) withServices(names []string, fn ServiceFunc, done map[string]bool) error {\n\tservices, err := p.GetServices(names...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, service := range services {\n\t\tif done[service.Name] {\n\t\t\tcontinue\n\t\t}\n\t\t//KCQ\n\t\tdone[service.Name] = true\n\t\tdependencies := service.GetDependencies()\n\t\tif len(dependencies) > 0 {\n\t\t\terr := p.withServices(dependencies, fn, done)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err := fn(service); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// RelativePath resolve a relative path based project's working directory\nfunc (p *Project) RelativePath(path string) string {\n\tif path[0] == '~' {\n\t\thome, _ := os.UserHomeDir()\n\t\tpath = filepath.Join(home, path[1:])\n\t}\n\tif filepath.IsAbs(path) {\n\t\treturn path\n\t}\n\treturn filepath.Join(p.WorkingDir, path)\n}\n\n// HasProfile return true if service has no profile declared or has at least one profile matching\nfunc (service ServiceConfig) HasProfile(profiles []string) bool {\n\tif len(service.Profiles) == 0 {\n\t\treturn true\n\t}\n\tfor _, p := range profiles {\n\t\tfor _, sp := range service.Profiles {\n\t\t\tif sp == p {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// GetProfiles retrieve the profiles implicitly enabled by explicitly targeting selected services\nfunc (s Services) GetProfiles() []string {\n\tset := map[string]struct{}{}\n\tfor _, service := range s {\n\t\tfor _, p := range service.Profiles {\n\t\t\tset[p] = struct{}{}\n\t\t}\n\t}\n\tvar profiles []string\n\tfor k := range set {\n\t\tprofiles = append(profiles, k)\n\t}\n\treturn profiles\n}\n\n// ApplyProfiles disables service which don't match selected profiles\nfunc (p *Project) ApplyProfiles(profiles []string) {\n\tfor _, p := range profiles {\n\t\tif p == \"*\" {\n\t\t\treturn\n\t\t}\n\t}\n\tvar enabled, disabled Services\n\tfor _, service := range p.Services {\n\t\tif service.HasProfile(profiles) {\n\t\t\tenabled = append(enabled, service)\n\t\t} else {\n\t\t\tdisabled = append(disabled, service)\n\t\t}\n\t}\n\tp.Services = enabled\n\tp.DisabledServices = disabled\n}\n\n// WithoutUnnecessaryResources drops networks/volumes/secrets/configs that are not referenced by active services\nfunc (p *Project) WithoutUnnecessaryResources() {\n\trequiredNetworks := map[string]struct{}{}\n\trequiredVolumes := map[string]struct{}{}\n\trequiredSecrets := map[string]struct{}{}\n\trequiredConfigs := map[string]struct{}{}\n\tfor _, s := range p.Services {\n\t\tfor k := range s.Networks {\n\t\t\trequiredNetworks[k] = struct{}{}\n\t\t}\n\t\tfor _, v := range s.Volumes {\n\t\t\tif v.Type != VolumeTypeVolume || v.Source == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\trequiredVolumes[v.Source] = struct{}{}\n\t\t}\n\t\tfor _, v := range s.Secrets {\n\t\t\trequiredSecrets[v.Source] = struct{}{}\n\t\t}\n\t\tfor _, v := range s.Configs {\n\t\t\trequiredConfigs[v.Source] = struct{}{}\n\t\t}\n\t}\n\n\tnetworks := Networks{}\n\tfor k := range requiredNetworks {\n\t\tnetworks[k] = p.Networks[k]\n\t}\n\tp.Networks = networks\n\n\tvolumes := Volumes{}\n\tfor k := range requiredVolumes {\n\t\tvolumes[k] = p.Volumes[k]\n\t}\n\tp.Volumes = volumes\n\n\tsecrets := Secrets{}\n\tfor k := range requiredSecrets {\n\t\tsecrets[k] = p.Secrets[k]\n\t}\n\tp.Secrets = secrets\n\n\tconfigs := Configs{}\n\tfor k := range requiredConfigs {\n\t\tconfigs[k] = p.Configs[k]\n\t}\n\tp.Configs = configs\n}\n\n// ForServices restrict the project model to a subset of services\nfunc (p *Project) ForServices(names []string) error {\n\tif len(names) == 0 {\n\t\t// All services\n\t\treturn nil\n\t}\n\n\tset := map[string]struct{}{}\n\terr := p.WithServices(names, func(service ServiceConfig) error {\n\t\tset[service.Name] = struct{}{}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Disable all services which are not explicit target or dependencies\n\tvar enabled Services\n\tfor _, s := range p.Services {\n\t\tif _, ok := set[s.Name]; ok {\n\t\t\tenabled = append(enabled, s)\n\t\t} else {\n\t\t\tp.DisabledServices = append(p.DisabledServices, s)\n\t\t}\n\t}\n\tp.Services = enabled\n\treturn nil\n}\n\n// ResolveImages updates services images to include digest computed by a resolver function\nfunc (p *Project) ResolveImages(resolver func(named reference.Named) (digest.Digest, error)) error {\n\teg := errgroup.Group{}\n\tfor i, s := range p.Services {\n\t\tidx := i\n\t\tservice := s\n\n\t\tif service.Image == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\teg.Go(func() error {\n\t\t\tnamed, err := reference.ParseDockerRef(service.Image)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif _, ok := named.(reference.Canonical); !ok {\n\t\t\t\t// image is named but not digested reference\n\t\t\t\tdigest, err := resolver(named)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tnamed, err = reference.WithDigest(named, digest)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tservice.Image = named.String()\n\t\t\tp.Services[idx] = service\n\t\t\treturn nil\n\t\t})\n\t}\n\treturn eg.Wait()\n}\n"
  },
  {
    "path": "vendor/github.com/compose-spec/compose-go/types/types.go",
    "content": "/*\n   Copyright 2020 The Compose Specification Authors.\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       http://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*/\n\npackage types\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/docker/go-connections/nat\"\n)\n\n// Duration is a thin wrapper around time.Duration with improved JSON marshalling\ntype Duration time.Duration\n\nfunc (d Duration) String() string {\n\treturn time.Duration(d).String()\n}\n\n// ConvertDurationPtr converts a typedefined Duration pointer to a time.Duration pointer with the same value.\nfunc ConvertDurationPtr(d *Duration) *time.Duration {\n\tif d == nil {\n\t\treturn nil\n\t}\n\tres := time.Duration(*d)\n\treturn &res\n}\n\n// MarshalJSON makes Duration implement json.Marshaler\nfunc (d Duration) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(d.String())\n}\n\n// MarshalYAML makes Duration implement yaml.Marshaler\nfunc (d Duration) MarshalYAML() (interface{}, error) {\n\treturn d.String(), nil\n}\n\nfunc (d *Duration) UnmarshalJSON(b []byte) error {\n\ts := strings.Trim(string(b), \"\\\"\")\n\ttimeDuration, err := time.ParseDuration(s)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*d = Duration(timeDuration)\n\treturn nil\n}\n\n// Services is a list of ServiceConfig\ntype Services []ServiceConfig\n\n// MarshalYAML makes Services implement yaml.Marshaller\nfunc (s Services) MarshalYAML() (interface{}, error) {\n\tservices := map[string]ServiceConfig{}\n\tfor _, service := range s {\n\t\tservices[service.Name] = service\n\t}\n\treturn services, nil\n}\n\n// MarshalJSON makes Services implement json.Marshaler\nfunc (s Services) MarshalJSON() ([]byte, error) {\n\tdata, err := s.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.MarshalIndent(data, \"\", \"  \")\n}\n\n// ServiceConfig is the configuration of one service\ntype ServiceConfig struct {\n\tName     string   `yaml:\"-\" json:\"-\"`\n\tProfiles []string `mapstructure:\"profiles\" yaml:\"profiles,omitempty\" json:\"profiles,omitempty\"`\n\n\tBuild           *BuildConfig                     `yaml:\",omitempty\" json:\"build,omitempty\"`\n\tBlkioConfig     *BlkioConfig                     `yaml:\",omitempty\" json:\"blkio_config,omitempty\"`\n\tCapAdd          []string                         `mapstructure:\"cap_add\" yaml:\"cap_add,omitempty\" json:\"cap_add,omitempty\"`\n\tCapDrop         []string                         `mapstructure:\"cap_drop\" yaml:\"cap_drop,omitempty\" json:\"cap_drop,omitempty\"`\n\tCgroupParent    string                           `mapstructure:\"cgroup_parent\" yaml:\"cgroup_parent,omitempty\" json:\"cgroup_parent,omitempty\"`\n\tCPUCount        int64                            `mapstructure:\"cpu_count\" yaml:\"cpu_count,omitempty\" json:\"cpu_count,omitempty\"`\n\tCPUPercent      float32                          `mapstructure:\"cpu_percent\" yaml:\"cpu_percent,omitempty\" json:\"cpu_percent,omitempty\"`\n\tCPUPeriod       int64                            `mapstructure:\"cpu_period\" yaml:\"cpu_period,omitempty\" json:\"cpu_period,omitempty\"`\n\tCPUQuota        int64                            `mapstructure:\"cpu_quota\" yaml:\"cpu_quota,omitempty\" json:\"cpu_quota,omitempty\"`\n\tCPURTPeriod     int64                            `mapstructure:\"cpu_rt_period\" yaml:\"cpu_rt_period,omitempty\" json:\"cpu_rt_period,omitempty\"`\n\tCPURTRuntime    int64                            `mapstructure:\"cpu_rt_runtime\" yaml:\"cpu_rt_runtime,omitempty\" json:\"cpu_rt_runtime,omitempty\"`\n\tCPUS            float32                          `mapstructure:\"cpus\" yaml:\"cpus,omitempty\" json:\"cpus,omitempty\"`\n\tCPUSet          string                           `mapstructure:\"cpuset\" yaml:\"cpuset,omitempty\" json:\"cpuset,omitempty\"`\n\tCPUShares       int64                            `mapstructure:\"cpu_shares\" yaml:\"cpu_shares,omitempty\" json:\"cpu_shares,omitempty\"`\n\tCommand         ShellCommand                     `yaml:\",omitempty\" json:\"command,omitempty\"`\n\tConfigs         []ServiceConfigObjConfig         `yaml:\",omitempty\" json:\"configs,omitempty\"`\n\tContainerName   string                           `mapstructure:\"container_name\" yaml:\"container_name,omitempty\" json:\"container_name,omitempty\"`\n\tCredentialSpec  *CredentialSpecConfig            `mapstructure:\"credential_spec\" yaml:\"credential_spec,omitempty\" json:\"credential_spec,omitempty\"`\n\tDependsOn       DependsOnConfig                  `mapstructure:\"depends_on\" yaml:\"depends_on,omitempty\" json:\"depends_on,omitempty\"`\n\tDeploy          *DeployConfig                    `yaml:\",omitempty\" json:\"deploy,omitempty\"`\n\tDevices         []string                         `yaml:\",omitempty\" json:\"devices,omitempty\"`\n\tDNS             StringList                       `yaml:\",omitempty\" json:\"dns,omitempty\"`\n\tDNSOpts         []string                         `mapstructure:\"dns_opt\" yaml:\"dns_opt,omitempty\" json:\"dns_opt,omitempty\"`\n\tDNSSearch       StringList                       `mapstructure:\"dns_search\" yaml:\"dns_search,omitempty\" json:\"dns_search,omitempty\"`\n\tDockerfile      string                           `yaml:\"dockerfile,omitempty\" json:\"dockerfile,omitempty\"`\n\tDomainName      string                           `mapstructure:\"domainname\" yaml:\"domainname,omitempty\" json:\"domainname,omitempty\"`\n\tEntrypoint      ShellCommand                     `yaml:\",omitempty\" json:\"entrypoint,omitempty\"`\n\tEnvironment     MappingWithEquals                `yaml:\",omitempty\" json:\"environment,omitempty\"`\n\tEnvFile         StringList                       `mapstructure:\"env_file\" yaml:\"env_file,omitempty\" json:\"env_file,omitempty\"`\n\tExpose          StringOrNumberList               `yaml:\",omitempty\" json:\"expose,omitempty\"`\n\tExtends         ExtendsConfig                    `yaml:\"extends,omitempty\" json:\"extends,omitempty\"`\n\tExternalLinks   []string                         `mapstructure:\"external_links\" yaml:\"external_links,omitempty\" json:\"external_links,omitempty\"`\n\tExtraHosts      HostsList                        `mapstructure:\"extra_hosts\" yaml:\"extra_hosts,omitempty\" json:\"extra_hosts,omitempty\"`\n\tGroupAdd        []string                         `mapstructure:\"group_app\" yaml:\"group_add,omitempty\" json:\"group_add,omitempty\"`\n\tHostname        string                           `yaml:\",omitempty\" json:\"hostname,omitempty\"`\n\tHealthCheck     *HealthCheckConfig               `yaml:\",omitempty\" json:\"healthcheck,omitempty\"`\n\tImage           string                           `yaml:\",omitempty\" json:\"image,omitempty\"`\n\tInit            *bool                            `yaml:\",omitempty\" json:\"init,omitempty\"`\n\tIpc             string                           `yaml:\",omitempty\" json:\"ipc,omitempty\"`\n\tIsolation       string                           `mapstructure:\"isolation\" yaml:\"isolation,omitempty\" json:\"isolation,omitempty\"`\n\tLabels          Labels                           `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tLinks           []string                         `yaml:\",omitempty\" json:\"links,omitempty\"`\n\tLogging         *LoggingConfig                   `yaml:\",omitempty\" json:\"logging,omitempty\"`\n\tLogDriver       string                           `mapstructure:\"log_driver\" yaml:\"log_driver,omitempty\" json:\"log_driver,omitempty\"`\n\tLogOpt          map[string]string                `mapstructure:\"log_opt\" yaml:\"log_opt,omitempty\" json:\"log_opt,omitempty\"`\n\tMemLimit        UnitBytes                        `mapstructure:\"mem_limit\" yaml:\"mem_limit,omitempty\" json:\"mem_limit,omitempty\"`\n\tMemReservation  UnitBytes                        `mapstructure:\"mem_reservation\" yaml:\"mem_reservation,omitempty\" json:\"mem_reservation,omitempty\"`\n\tMemSwapLimit    UnitBytes                        `mapstructure:\"memswap_limit\" yaml:\"memswap_limit,omitempty\" json:\"memswap_limit,omitempty\"`\n\tMemSwappiness   UnitBytes                        `mapstructure:\"mem_swappiness\" yaml:\"mem_swappiness,omitempty\" json:\"mem_swappiness,omitempty\"`\n\tMacAddress      string                           `mapstructure:\"mac_address\" yaml:\"mac_address,omitempty\" json:\"mac_address,omitempty\"`\n\tNet             string                           `yaml:\"net,omitempty\" json:\"net,omitempty\"`\n\tNetworkMode     string                           `mapstructure:\"network_mode\" yaml:\"network_mode,omitempty\" json:\"network_mode,omitempty\"`\n\tNetworks        map[string]*ServiceNetworkConfig `yaml:\",omitempty\" json:\"networks,omitempty\"`\n\tOomKillDisable  bool                             `mapstructure:\"oom_kill_disable\" yaml:\"oom_kill_disable,omitempty\" json:\"oom_kill_disable,omitempty\"`\n\tOomScoreAdj     int64                            `mapstructure:\"oom_score_adj\" yaml:\"oom_score_adj,omitempty\" json:\"oom_score_adj,omitempty\"`\n\tPid             string                           `yaml:\",omitempty\" json:\"pid,omitempty\"`\n\tPidsLimit       int64                            `mapstructure:\"pids_limit\" yaml:\"pids_limit,omitempty\" json:\"pids_limit,omitempty\"`\n\tPlatform        string                           `yaml:\",omitempty\" json:\"platform,omitempty\"`\n\tPorts           []ServicePortConfig              `yaml:\",omitempty\" json:\"ports,omitempty\"`\n\tPrivileged      bool                             `yaml:\",omitempty\" json:\"privileged,omitempty\"`\n\tPullPolicy      string                           `mapstructure:\"pull_policy\" yaml:\"pull_policy,omitempty\" json:\"pull_policy,omitempty\"`\n\tReadOnly        bool                             `mapstructure:\"read_only\" yaml:\"read_only,omitempty\" json:\"read_only,omitempty\"`\n\tRestart         string                           `yaml:\",omitempty\" json:\"restart,omitempty\"`\n\tRuntime         string                           `yaml:\",omitempty\" json:\"runtime,omitempty\"`\n\tScale           int                              `yaml:\"-\" json:\"-\"`\n\tSecrets         []ServiceSecretConfig            `yaml:\",omitempty\" json:\"secrets,omitempty\"`\n\tSecurityOpt     []string                         `mapstructure:\"security_opt\" yaml:\"security_opt,omitempty\" json:\"security_opt,omitempty\"`\n\tShmSize         UnitBytes                        `mapstructure:\"shm_size\" yaml:\"shm_size,omitempty\" json:\"shm_size,omitempty\"`\n\tStdinOpen       bool                             `mapstructure:\"stdin_open\" yaml:\"stdin_open,omitempty\" json:\"stdin_open,omitempty\"`\n\tStopGracePeriod *Duration                        `mapstructure:\"stop_grace_period\" yaml:\"stop_grace_period,omitempty\" json:\"stop_grace_period,omitempty\"`\n\tStopSignal      string                           `mapstructure:\"stop_signal\" yaml:\"stop_signal,omitempty\" json:\"stop_signal,omitempty\"`\n\tSysctls         Mapping                          `yaml:\",omitempty\" json:\"sysctls,omitempty\"`\n\tTmpfs           StringList                       `yaml:\",omitempty\" json:\"tmpfs,omitempty\"`\n\tTty             bool                             `mapstructure:\"tty\" yaml:\"tty,omitempty\" json:\"tty,omitempty\"`\n\tUlimits         map[string]*UlimitsConfig        `yaml:\",omitempty\" json:\"ulimits,omitempty\"`\n\tUser            string                           `yaml:\",omitempty\" json:\"user,omitempty\"`\n\tUserNSMode      string                           `mapstructure:\"userns_mode\" yaml:\"userns_mode,omitempty\" json:\"userns_mode,omitempty\"`\n\tUts             string                           `yaml:\"uts,omitempty\" json:\"uts,omitempty\"`\n\tVolumeDriver    string                           `mapstructure:\"volume_driver\" yaml:\"volume_driver,omitempty\" json:\"volume_driver,omitempty\"`\n\tVolumes         []ServiceVolumeConfig            `yaml:\",omitempty\" json:\"volumes,omitempty\"`\n\tVolumesFrom     []string                         `mapstructure:\"volumes_from\" yaml:\"volumes_from,omitempty\" json:\"volumes_from,omitempty\"`\n\tWorkingDir      string                           `mapstructure:\"working_dir\" yaml:\"working_dir,omitempty\" json:\"working_dir,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// NetworksByPriority return the service networks IDs sorted according to Priority\nfunc (s *ServiceConfig) NetworksByPriority() []string {\n\ttype key struct {\n\t\tname     string\n\t\tpriority int\n\t}\n\tvar keys []key\n\tfor k, v := range s.Networks {\n\t\tpriority := 0\n\t\tif v != nil {\n\t\t\tpriority = v.Priority\n\t\t}\n\t\tkeys = append(keys, key{\n\t\t\tname:     k,\n\t\t\tpriority: priority,\n\t\t})\n\t}\n\tsort.Slice(keys, func(i, j int) bool {\n\t\treturn keys[i].priority > keys[j].priority\n\t})\n\tvar sorted []string\n\tfor _, k := range keys {\n\t\tsorted = append(sorted, k.name)\n\t}\n\treturn sorted\n}\n\nconst (\n\t//PullPolicyAlways always pull images\n\tPullPolicyAlways = \"always\"\n\t//PullPolicyNever never pull images\n\tPullPolicyNever = \"never\"\n\t//PullPolicyIfNotPresent pull missing images\n\tPullPolicyIfNotPresent = \"if_not_present\"\n\t//PullPolicyIfNotPresent pull missing images\n\tPullPolicyMissing = \"missing\"\n\t//PullPolicyBuild force building images\n\tPullPolicyBuild = \"build\"\n)\n\nconst (\n\t//RestartPolicyAlways always restart the container if it stops\n\tRestartPolicyAlways = \"always\"\n\t//RestartPolicyOnFailure restart the container if it exits due to an error\n\tRestartPolicyOnFailure = \"on-failure\"\n\t//RestartPolicyNo do not automatically restart the container\n\tRestartPolicyNo = \"no\"\n\t//RestartPolicyUnlessStopped always restart the container unless the container is stopped (manually or otherwise)\n\tRestartPolicyUnlessStopped = \"unless-stopped\"\n)\n\nconst (\n\t// ServicePrefix is the prefix for references pointing to a service\n\tServicePrefix = \"service:\"\n\t// ContainerPrefix is the prefix for references pointing to a container\n\tContainerPrefix = \"container:\"\n\n\t// NetworkModeServicePrefix is the prefix for network_mode pointing to a service\n\t// Deprecated prefer ServicePrefix\n\tNetworkModeServicePrefix = ServicePrefix\n\t// NetworkModeContainerPrefix is the prefix for network_mode pointing to a container\n\t// Deprecated prefer ContainerPrefix\n\tNetworkModeContainerPrefix = ContainerPrefix\n)\n\n// GetDependencies retrieve all services this service depends on\nfunc (s ServiceConfig) GetDependencies() []string {\n\tdependencies := make(set)\n\tfor dependency := range s.DependsOn {\n\t\tdependencies.append(dependency)\n\t}\n\tfor _, link := range s.Links {\n\t\tparts := strings.Split(link, \":\")\n\t\tif len(parts) == 2 {\n\t\t\tdependencies.append(parts[0])\n\t\t} else {\n\t\t\tdependencies.append(link)\n\t\t}\n\t}\n\tif strings.HasPrefix(s.NetworkMode, ServicePrefix) {\n\t\tdependencies.append(s.NetworkMode[len(ServicePrefix):])\n\t}\n\tif strings.HasPrefix(s.Ipc, ServicePrefix) {\n\t\tdependencies.append(s.Ipc[len(ServicePrefix):])\n\t}\n\tif strings.HasPrefix(s.Pid, ServicePrefix) {\n\t\tdependencies.append(s.Pid[len(ServicePrefix):])\n\t}\n\tfor _, vol := range s.VolumesFrom {\n\t\tif !strings.HasPrefix(s.Pid, ContainerPrefix) {\n\t\t\tdependencies.append(vol)\n\t\t}\n\t}\n\n\treturn dependencies.toSlice()\n}\n\ntype set map[string]struct{}\n\nfunc (s set) append(strings ...string) {\n\tfor _, str := range strings {\n\t\ts[str] = struct{}{}\n\t}\n}\n\nfunc (s set) toSlice() []string {\n\tslice := make([]string, 0, len(s))\n\tfor v := range s {\n\t\tslice = append(slice, v)\n\t}\n\treturn slice\n}\n\n// BuildConfig is a type for build\ntype BuildConfig struct {\n\tContext    string            `yaml:\",omitempty\" json:\"context,omitempty\"`\n\tDockerfile string            `yaml:\",omitempty\" json:\"dockerfile,omitempty\"`\n\tArgs       MappingWithEquals `yaml:\",omitempty\" json:\"args,omitempty\"`\n\tLabels     Labels            `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tCacheFrom  StringList        `mapstructure:\"cache_from\" yaml:\"cache_from,omitempty\" json:\"cache_from,omitempty\"`\n\tExtraHosts HostsList         `mapstructure:\"extra_hosts\" yaml:\"extra_hosts,omitempty\" json:\"extra_hosts,omitempty\"`\n\tIsolation  string            `yaml:\",omitempty\" json:\"isolation,omitempty\"`\n\tNetwork    string            `yaml:\",omitempty\" json:\"network,omitempty\"`\n\tTarget     string            `yaml:\",omitempty\" json:\"target,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// BlkioConfig define blkio config\ntype BlkioConfig struct {\n\tWeight          uint16           `yaml:\",omitempty\" json:\"weight,omitempty\"`\n\tWeightDevice    []WeightDevice   `yaml:\",omitempty\" json:\"weight_device,omitempty\"`\n\tDeviceReadBps   []ThrottleDevice `yaml:\",omitempty\" json:\"device_read_bps,omitempty\"`\n\tDeviceReadIOps  []ThrottleDevice `yaml:\",omitempty\" json:\"device_read_iops,omitempty\"`\n\tDeviceWriteBps  []ThrottleDevice `yaml:\",omitempty\" json:\"device_write_bps,omitempty\"`\n\tDeviceWriteIOps []ThrottleDevice `yaml:\",omitempty\" json:\"device_write_iops,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// WeightDevice is a structure that holds device:weight pair\ntype WeightDevice struct {\n\tPath   string\n\tWeight uint16\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ThrottleDevice is a structure that holds device:rate_per_second pair\ntype ThrottleDevice struct {\n\tPath string\n\tRate uint64\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ShellCommand is a string or list of string args\ntype ShellCommand []string\n\n// StringList is a type for fields that can be a string or list of strings\ntype StringList []string\n\n// StringOrNumberList is a type for fields that can be a list of strings or\n// numbers\ntype StringOrNumberList []string\n\n// MappingWithEquals is a mapping type that can be converted from a list of\n// key[=value] strings.\n// For the key with an empty value (`key=`), the mapped value is set to a pointer to `\"\"`.\n// For the key without value (`key`), the mapped value is set to nil.\ntype MappingWithEquals map[string]*string\n\n// NewMappingWithEquals build a new Mapping from a set of KEY=VALUE strings\nfunc NewMappingWithEquals(values []string) MappingWithEquals {\n\tmapping := MappingWithEquals{}\n\tfor _, env := range values {\n\t\ttokens := strings.SplitN(env, \"=\", 2)\n\t\tif len(tokens) > 1 {\n\t\t\tmapping[tokens[0]] = &tokens[1]\n\t\t} else {\n\t\t\tmapping[env] = nil\n\t\t}\n\t}\n\treturn mapping\n}\n\n// OverrideBy update MappingWithEquals with values from another MappingWithEquals\nfunc (e MappingWithEquals) OverrideBy(other MappingWithEquals) MappingWithEquals {\n\tfor k, v := range other {\n\t\te[k] = v\n\t}\n\treturn e\n}\n\n// Resolve update a MappingWithEquals for keys without value (`key`, but not `key=`)\nfunc (e MappingWithEquals) Resolve(lookupFn func(string) (string, bool)) MappingWithEquals {\n\tfor k, v := range e {\n\t\tif v == nil {\n\t\t\tif value, ok := lookupFn(k); ok {\n\t\t\t\te[k] = &value\n\t\t\t}\n\t\t}\n\t}\n\treturn e\n}\n\n// RemoveEmpty excludes keys that are not associated with a value\nfunc (e MappingWithEquals) RemoveEmpty() MappingWithEquals {\n\tfor k, v := range e {\n\t\tif v == nil {\n\t\t\tdelete(e, k)\n\t\t}\n\t}\n\treturn e\n}\n\n// Mapping is a mapping type that can be converted from a list of\n// key[=value] strings.\n// For the key with an empty value (`key=`), or key without value (`key`), the\n// mapped value is set to an empty string `\"\"`.\ntype Mapping map[string]string\n\n// NewMapping build a new Mapping from a set of KEY=VALUE strings\nfunc NewMapping(values []string) Mapping {\n\tmapping := Mapping{}\n\tfor _, value := range values {\n\t\tparts := strings.SplitN(value, \"=\", 2)\n\t\tkey := parts[0]\n\t\tswitch {\n\t\tcase len(parts) == 1:\n\t\t\tmapping[key] = \"\"\n\t\tdefault:\n\t\t\tmapping[key] = parts[1]\n\t\t}\n\t}\n\treturn mapping\n}\n\n// Labels is a mapping type for labels\ntype Labels map[string]string\n\nfunc (l Labels) Add(key, value string) Labels {\n\tif l == nil {\n\t\tl = Labels{}\n\t}\n\tl[key] = value\n\treturn l\n}\n\n// MappingWithColon is a mapping type that can be converted from a list of\n// 'key: value' strings\ntype MappingWithColon map[string]string\n\n// HostsList is a list of colon-separated host-ip mappings\ntype HostsList []string\n\n// LoggingConfig the logging configuration for a service\ntype LoggingConfig struct {\n\tDriver  string            `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tOptions map[string]string `yaml:\",omitempty\" json:\"options,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// DeployConfig the deployment configuration for a service\ntype DeployConfig struct {\n\tMode           string         `yaml:\",omitempty\" json:\"mode,omitempty\"`\n\tReplicas       *uint64        `yaml:\",omitempty\" json:\"replicas,omitempty\"`\n\tLabels         Labels         `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tUpdateConfig   *UpdateConfig  `mapstructure:\"update_config\" yaml:\"update_config,omitempty\" json:\"update_config,omitempty\"`\n\tRollbackConfig *UpdateConfig  `mapstructure:\"rollback_config\" yaml:\"rollback_config,omitempty\" json:\"rollback_config,omitempty\"`\n\tResources      Resources      `yaml:\",omitempty\" json:\"resources,omitempty\"`\n\tRestartPolicy  *RestartPolicy `mapstructure:\"restart_policy\" yaml:\"restart_policy,omitempty\" json:\"restart_policy,omitempty\"`\n\tPlacement      Placement      `yaml:\",omitempty\" json:\"placement,omitempty\"`\n\tEndpointMode   string         `mapstructure:\"endpoint_mode\" yaml:\"endpoint_mode,omitempty\" json:\"endpoint_mode,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// HealthCheckConfig the healthcheck configuration for a service\ntype HealthCheckConfig struct {\n\tTest        HealthCheckTest `yaml:\",omitempty\" json:\"test,omitempty\"`\n\tTimeout     *Duration       `yaml:\",omitempty\" json:\"timeout,omitempty\"`\n\tInterval    *Duration       `yaml:\",omitempty\" json:\"interval,omitempty\"`\n\tRetries     *uint64         `yaml:\",omitempty\" json:\"retries,omitempty\"`\n\tStartPeriod *Duration       `mapstructure:\"start_period\" yaml:\"start_period,omitempty\" json:\"start_period,omitempty\"`\n\tDisable     bool            `yaml:\",omitempty\" json:\"disable,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// HealthCheckTest is the command run to test the health of a service\ntype HealthCheckTest []string\n\n// UpdateConfig the service update configuration\ntype UpdateConfig struct {\n\tParallelism     *uint64  `yaml:\",omitempty\" json:\"parallelism,omitempty\"`\n\tDelay           Duration `yaml:\",omitempty\" json:\"delay,omitempty\"`\n\tFailureAction   string   `mapstructure:\"failure_action\" yaml:\"failure_action,omitempty\" json:\"failure_action,omitempty\"`\n\tMonitor         Duration `yaml:\",omitempty\" json:\"monitor,omitempty\"`\n\tMaxFailureRatio float32  `mapstructure:\"max_failure_ratio\" yaml:\"max_failure_ratio,omitempty\" json:\"max_failure_ratio,omitempty\"`\n\tOrder           string   `yaml:\",omitempty\" json:\"order,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Resources the resource limits and reservations\ntype Resources struct {\n\tLimits       *Resource `yaml:\",omitempty\" json:\"limits,omitempty\"`\n\tReservations *Resource `yaml:\",omitempty\" json:\"reservations,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Resource is a resource to be limited or reserved\ntype Resource struct {\n\t// TODO: types to convert from units and ratios\n\tNanoCPUs         string            `mapstructure:\"cpus\" yaml:\"cpus,omitempty\" json:\"cpus,omitempty\"`\n\tMemoryBytes      UnitBytes         `mapstructure:\"memory\" yaml:\"memory,omitempty\" json:\"memory,omitempty\"`\n\tDevices          []DeviceRequest   `mapstructure:\"devices\" yaml:\"devices,omitempty\" json:\"devices,omitempty\"`\n\tGenericResources []GenericResource `mapstructure:\"generic_resources\" yaml:\"generic_resources,omitempty\" json:\"generic_resources,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\ntype DeviceRequest struct {\n\tCapabilities []string `mapstructure:\"capabilities\" yaml:\"capabilities,omitempty\" json:\"capabilities,omitempty\"`\n\tDriver       string   `mapstructure:\"driver\" yaml:\"driver,omitempty\" json:\"driver,omitempty\"`\n\tCount        int64    `mapstructure:\"count\" yaml:\"count,omitempty\" json:\"count,omitempty\"`\n\tIDs          []string `mapstructure:\"device_ids\" yaml:\"device_ids,omitempty\" json:\"device_ids,omitempty\"`\n}\n\n// GenericResource represents a \"user defined\" resource which can\n// only be an integer (e.g: SSD=3) for a service\ntype GenericResource struct {\n\tDiscreteResourceSpec *DiscreteGenericResource `mapstructure:\"discrete_resource_spec\" yaml:\"discrete_resource_spec,omitempty\" json:\"discrete_resource_spec,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// DiscreteGenericResource represents a \"user defined\" resource which is defined\n// as an integer\n// \"Kind\" is used to describe the Kind of a resource (e.g: \"GPU\", \"FPGA\", \"SSD\", ...)\n// Value is used to count the resource (SSD=5, HDD=3, ...)\ntype DiscreteGenericResource struct {\n\tKind  string `json:\"kind\"`\n\tValue int64  `json:\"value\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// UnitBytes is the bytes type\ntype UnitBytes int64\n\n// MarshalYAML makes UnitBytes implement yaml.Marshaller\nfunc (u UnitBytes) MarshalYAML() (interface{}, error) {\n\treturn fmt.Sprintf(\"%d\", u), nil\n}\n\n// MarshalJSON makes UnitBytes implement json.Marshaler\nfunc (u UnitBytes) MarshalJSON() ([]byte, error) {\n\treturn []byte(fmt.Sprintf(`\"%d\"`, u)), nil\n}\n\n// RestartPolicy the service restart policy\ntype RestartPolicy struct {\n\tCondition   string    `yaml:\",omitempty\" json:\"condition,omitempty\"`\n\tDelay       *Duration `yaml:\",omitempty\" json:\"delay,omitempty\"`\n\tMaxAttempts *uint64   `mapstructure:\"max_attempts\" yaml:\"max_attempts,omitempty\" json:\"max_attempts,omitempty\"`\n\tWindow      *Duration `yaml:\",omitempty\" json:\"window,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Placement constraints for the service\ntype Placement struct {\n\tConstraints []string               `yaml:\",omitempty\" json:\"constraints,omitempty\"`\n\tPreferences []PlacementPreferences `yaml:\",omitempty\" json:\"preferences,omitempty\"`\n\tMaxReplicas uint64                 `mapstructure:\"max_replicas_per_node\" yaml:\"max_replicas_per_node,omitempty\" json:\"max_replicas_per_node,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// PlacementPreferences is the preferences for a service placement\ntype PlacementPreferences struct {\n\tSpread string `yaml:\",omitempty\" json:\"spread,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServiceNetworkConfig is the network configuration for a service\ntype ServiceNetworkConfig struct {\n\tPriority    int      `yaml:\",omitempty\" json:\"priotirt,omitempty\"`\n\tAliases     []string `yaml:\",omitempty\" json:\"aliases,omitempty\"`\n\tIpv4Address string   `mapstructure:\"ipv4_address\" yaml:\"ipv4_address,omitempty\" json:\"ipv4_address,omitempty\"`\n\tIpv6Address string   `mapstructure:\"ipv6_address\" yaml:\"ipv6_address,omitempty\" json:\"ipv6_address,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServicePortConfig is the port configuration for a service\ntype ServicePortConfig struct {\n\tMode      string `yaml:\",omitempty\" json:\"mode,omitempty\"`\n\tHostIP    string `mapstructure:\"host_ip\" yaml:\"host_ip,omitempty\" json:\"host_ip,omitempty\"`\n\tTarget    uint32 `yaml:\",omitempty\" json:\"target,omitempty\"`\n\tPublished uint32 `yaml:\",omitempty\" json:\"published,omitempty\"`\n\tProtocol  string `yaml:\",omitempty\" json:\"protocol,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ParsePortConfig parse short syntax for service port configuration\nfunc ParsePortConfig(value string) ([]ServicePortConfig, error) {\n\tvar portConfigs []ServicePortConfig\n\tports, portBindings, err := nat.ParsePortSpecs([]string{value})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// We need to sort the key of the ports to make sure it is consistent\n\tkeys := []string{}\n\tfor port := range ports {\n\t\tkeys = append(keys, string(port))\n\t}\n\tsort.Strings(keys)\n\n\tfor _, key := range keys {\n\t\tport := nat.Port(key)\n\t\tconverted, err := convertPortToPortConfig(port, portBindings)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tportConfigs = append(portConfigs, converted...)\n\t}\n\treturn portConfigs, nil\n}\n\nfunc convertPortToPortConfig(port nat.Port, portBindings map[nat.Port][]nat.PortBinding) ([]ServicePortConfig, error) {\n\tportConfigs := []ServicePortConfig{}\n\tfor _, binding := range portBindings[port] {\n\t\tstartHostPort, endHostPort, err := nat.ParsePortRange(binding.HostPort)\n\n\t\tif err != nil && binding.HostPort != \"\" {\n\t\t\treturn nil, fmt.Errorf(\"invalid hostport binding (%s) for port (%s)\", binding.HostPort, port.Port())\n\t\t}\n\n\t\tfor i := startHostPort; i <= endHostPort; i++ {\n\t\t\tportConfigs = append(portConfigs, ServicePortConfig{\n\t\t\t\tHostIP:    binding.HostIP,\n\t\t\t\tProtocol:  strings.ToLower(port.Proto()),\n\t\t\t\tTarget:    uint32(port.Int()),\n\t\t\t\tPublished: uint32(i),\n\t\t\t\tMode:      \"ingress\",\n\t\t\t})\n\t\t}\n\t}\n\treturn portConfigs, nil\n}\n\n// ServiceVolumeConfig are references to a volume used by a service\ntype ServiceVolumeConfig struct {\n\tType        string               `yaml:\",omitempty\" json:\"type,omitempty\"`\n\tSource      string               `yaml:\",omitempty\" json:\"source,omitempty\"`\n\tTarget      string               `yaml:\",omitempty\" json:\"target,omitempty\"`\n\tReadOnly    bool                 `mapstructure:\"read_only\" yaml:\"read_only,omitempty\" json:\"read_only,omitempty\"`\n\tConsistency string               `yaml:\",omitempty\" json:\"consistency,omitempty\"`\n\tBind        *ServiceVolumeBind   `yaml:\",omitempty\" json:\"bind,omitempty\"`\n\tVolume      *ServiceVolumeVolume `yaml:\",omitempty\" json:\"volume,omitempty\"`\n\tTmpfs       *ServiceVolumeTmpfs  `yaml:\",omitempty\" json:\"tmpfs,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\nconst (\n\t// TypeBind is the type for mounting host dir\n\tVolumeTypeBind = \"bind\"\n\t// TypeVolume is the type for remote storage volumes\n\tVolumeTypeVolume = \"volume\"\n\t// TypeTmpfs is the type for mounting tmpfs\n\tVolumeTypeTmpfs = \"tmpfs\"\n\t// TypeNamedPipe is the type for mounting Windows named pipes\n\tVolumeTypeNamedPipe = \"npipe\"\n)\n\n// ServiceVolumeBind are options for a service volume of type bind\ntype ServiceVolumeBind struct {\n\tPropagation    string `yaml:\",omitempty\" json:\"propagation,omitempty\"`\n\tCreateHostPath bool   `mapstructure:\"create_host_path\" yaml:\"create_host_path,omitempty\" json:\"create_host_path,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// Propagation represents the propagation of a mount.\nconst (\n\t// PropagationRPrivate RPRIVATE\n\tPropagationRPrivate string = \"rprivate\"\n\t// PropagationPrivate PRIVATE\n\tPropagationPrivate string = \"private\"\n\t// PropagationRShared RSHARED\n\tPropagationRShared string = \"rshared\"\n\t// PropagationShared SHARED\n\tPropagationShared string = \"shared\"\n\t// PropagationRSlave RSLAVE\n\tPropagationRSlave string = \"rslave\"\n\t// PropagationSlave SLAVE\n\tPropagationSlave string = \"slave\"\n)\n\n// ServiceVolumeVolume are options for a service volume of type volume\ntype ServiceVolumeVolume struct {\n\tNoCopy bool `mapstructure:\"nocopy\" yaml:\"nocopy,omitempty\" json:\"nocopy,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServiceVolumeTmpfs are options for a service volume of type tmpfs\ntype ServiceVolumeTmpfs struct {\n\tSize int64 `yaml:\",omitempty\" json:\"size,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// FileReferenceConfig for a reference to a swarm file object\ntype FileReferenceConfig struct {\n\tSource string  `yaml:\",omitempty\" json:\"source,omitempty\"`\n\tTarget string  `yaml:\",omitempty\" json:\"target,omitempty\"`\n\tUID    string  `yaml:\",omitempty\" json:\"uid,omitempty\"`\n\tGID    string  `yaml:\",omitempty\" json:\"gid,omitempty\"`\n\tMode   *uint32 `yaml:\",omitempty\" json:\"mode,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// ServiceConfigObjConfig is the config obj configuration for a service\ntype ServiceConfigObjConfig FileReferenceConfig\n\n// ServiceSecretConfig is the secret configuration for a service\ntype ServiceSecretConfig FileReferenceConfig\n\n// UlimitsConfig the ulimit configuration\ntype UlimitsConfig struct {\n\tSingle int `yaml:\",omitempty\" json:\"single,omitempty\"`\n\tSoft   int `yaml:\",omitempty\" json:\"soft,omitempty\"`\n\tHard   int `yaml:\",omitempty\" json:\"hard,omitempty\"`\n\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// MarshalYAML makes UlimitsConfig implement yaml.Marshaller\nfunc (u *UlimitsConfig) MarshalYAML() (interface{}, error) {\n\tif u.Single != 0 {\n\t\treturn u.Single, nil\n\t}\n\treturn u, nil\n}\n\n// MarshalJSON makes UlimitsConfig implement json.Marshaller\nfunc (u *UlimitsConfig) MarshalJSON() ([]byte, error) {\n\tif u.Single != 0 {\n\t\treturn json.Marshal(u.Single)\n\t}\n\t// Pass as a value to avoid re-entering this method and use the default implementation\n\treturn json.Marshal(*u)\n}\n\n// NetworkConfig for a network\ntype NetworkConfig struct {\n\tName       string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tDriver     string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tDriverOpts map[string]string      `mapstructure:\"driver_opts\" yaml:\"driver_opts,omitempty\" json:\"driver_opts,omitempty\"`\n\tIpam       IPAMConfig             `yaml:\",omitempty\" json:\"ipam,omitempty\"`\n\tExternal   External               `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tInternal   bool                   `yaml:\",omitempty\" json:\"internal,omitempty\"`\n\tAttachable bool                   `yaml:\",omitempty\" json:\"attachable,omitempty\"`\n\tLabels     Labels                 `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// IPAMConfig for a network\ntype IPAMConfig struct {\n\tDriver     string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tConfig     []*IPAMPool            `yaml:\",omitempty\" json:\"config,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// IPAMPool for a network\ntype IPAMPool struct {\n\tSubnet             string                 `yaml:\",omitempty\" json:\"subnet,omitempty\"`\n\tGateway            string                 `yaml:\",omitempty\" json:\"gateway,omitempty\"`\n\tIPRange            string                 `mapstructure:\"ip_range\" yaml:\"ip_range,omitempty\" json:\"ip_range,omitempty\"`\n\tAuxiliaryAddresses map[string]string      `mapstructure:\"aux_addresses\" yaml:\"aux_addresses,omitempty\" json:\"aux_addresses,omitempty\"`\n\tExtensions         map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// VolumeConfig for a volume\ntype VolumeConfig struct {\n\tName       string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tDriver     string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tDriverOpts map[string]string      `mapstructure:\"driver_opts\" yaml:\"driver_opts,omitempty\" json:\"driver_opts,omitempty\"`\n\tExternal   External               `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tLabels     Labels                 `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// External identifies a Volume or Network as a reference to a resource that is\n// not managed, and should already exist.\n// External.name is deprecated and replaced by Volume.name\ntype External struct {\n\tName       string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tExternal   bool                   `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// MarshalYAML makes External implement yaml.Marshaller\nfunc (e External) MarshalYAML() (interface{}, error) {\n\tif e.Name == \"\" {\n\t\treturn e.External, nil\n\t}\n\treturn External{Name: e.Name}, nil\n}\n\n// MarshalJSON makes External implement json.Marshaller\nfunc (e External) MarshalJSON() ([]byte, error) {\n\tif e.Name == \"\" {\n\t\treturn []byte(fmt.Sprintf(\"%v\", e.External)), nil\n\t}\n\treturn []byte(fmt.Sprintf(`{\"name\": %q}`, e.Name)), nil\n}\n\n// CredentialSpecConfig for credential spec on Windows\ntype CredentialSpecConfig struct {\n\tConfig     string                 `yaml:\",omitempty\" json:\"config,omitempty\"` // Config was added in API v1.40\n\tFile       string                 `yaml:\",omitempty\" json:\"file,omitempty\"`\n\tRegistry   string                 `yaml:\",omitempty\" json:\"registry,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\n// FileObjectConfig is a config type for a file used by a service\ntype FileObjectConfig struct {\n\tName           string                 `yaml:\",omitempty\" json:\"name,omitempty\"`\n\tFile           string                 `yaml:\",omitempty\" json:\"file,omitempty\"`\n\tExternal       External               `yaml:\",omitempty\" json:\"external,omitempty\"`\n\tLabels         Labels                 `yaml:\",omitempty\" json:\"labels,omitempty\"`\n\tDriver         string                 `yaml:\",omitempty\" json:\"driver,omitempty\"`\n\tDriverOpts     map[string]string      `mapstructure:\"driver_opts\" yaml:\"driver_opts,omitempty\" json:\"driver_opts,omitempty\"`\n\tTemplateDriver string                 `mapstructure:\"template_driver\" yaml:\"template_driver,omitempty\" json:\"template_driver,omitempty\"`\n\tExtensions     map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\nconst (\n\t// ServiceConditionCompletedSuccessfully is the type for waiting until a service has completed successfully (exit code 0).\n\tServiceConditionCompletedSuccessfully = \"service_completed_successfully\"\n\n\t// ServiceConditionHealthy is the type for waiting until a service is healthy.\n\tServiceConditionHealthy = \"service_healthy\"\n\n\t// ServiceConditionStarted is the type for waiting until a service has started (default).\n\tServiceConditionStarted = \"service_started\"\n)\n\ntype DependsOnConfig map[string]ServiceDependency\n\ntype ServiceDependency struct {\n\tCondition  string                 `yaml:\",omitempty\" json:\"condition,omitempty\"`\n\tExtensions map[string]interface{} `yaml:\",inline\" json:\"-\"`\n}\n\ntype ExtendsConfig MappingWithEquals\n\n// SecretConfig for a secret\ntype SecretConfig FileObjectConfig\n\n// ConfigObjConfig is the config for the swarm \"Config\" object\ntype ConfigObjConfig FileObjectConfig\n"
  },
  {
    "path": "vendor/github.com/containerd/containerd/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 The containerd Authors\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": "vendor/github.com/containerd/containerd/NOTICE",
    "content": "Docker\nCopyright 2012-2015 Docker, Inc.\n\nThis product includes software developed at Docker, Inc. (https://www.docker.com).\n\nThe following is courtesy of our legal counsel:\n\n\nUse and transfer of Docker may be subject to certain restrictions by the\nUnited States and other governments.\nIt is your responsibility to ensure that your use and/or transfer does not\nviolate applicable laws.\n\nFor more information, please see https://www.bis.doc.gov\n\nSee also https://www.apache.org/dev/crypto.html and/or seek legal counsel.\n"
  },
  {
    "path": "vendor/github.com/containerd/containerd/pkg/userns/userns_linux.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\npackage userns\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n)\n\nvar (\n\tinUserNS bool\n\tnsOnce   sync.Once\n)\n\n// RunningInUserNS detects whether we are currently running in a user namespace.\n// Originally copied from github.com/lxc/lxd/shared/util.go\nfunc RunningInUserNS() bool {\n\tnsOnce.Do(func() {\n\t\tfile, err := os.Open(\"/proc/self/uid_map\")\n\t\tif err != nil {\n\t\t\t// This kernel-provided file only exists if user namespaces are supported\n\t\t\treturn\n\t\t}\n\t\tdefer file.Close()\n\n\t\tbuf := bufio.NewReader(file)\n\t\tl, _, err := buf.ReadLine()\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tline := string(l)\n\t\tvar a, b, c int64\n\t\tfmt.Sscanf(line, \"%d %d %d\", &a, &b, &c)\n\n\t\t/*\n\t\t * We assume we are in the initial user namespace if we have a full\n\t\t * range - 4294967295 uids starting at uid 0.\n\t\t */\n\t\tif a == 0 && b == 0 && c == 4294967295 {\n\t\t\treturn\n\t\t}\n\t\tinUserNS = true\n\t})\n\treturn inUserNS\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/containerd/pkg/userns/userns_unsupported.go",
    "content": "//go:build !linux\n\n/*\n   Copyright The containerd Authors.\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       http://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*/\n\npackage userns\n\n// RunningInUserNS is a stub for non-Linux systems\n// Always returns false\nfunc RunningInUserNS() bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/log/.golangci.yml",
    "content": "linters:\n  enable:\n    - exportloopref # Checks for pointers to enclosing loop variables\n    - gofmt\n    - goimports\n    - gosec\n    - ineffassign\n    - misspell\n    - nolintlint\n    - revive\n    - staticcheck\n    - tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17\n    - unconvert\n    - unused\n    - vet\n    - dupword # Checks for duplicate words in the source code\n  disable:\n    - errcheck\n\nrun:\n  timeout: 5m\n  skip-dirs:\n    - api\n    - cluster\n    - design\n    - docs\n    - docs/man\n    - releases\n    - reports\n    - test # e2e scripts\n"
  },
  {
    "path": "vendor/github.com/containerd/log/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 The containerd Authors\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": "vendor/github.com/containerd/log/README.md",
    "content": "# log\n\nA Go package providing a common logging interface across containerd repositories and a way for clients to use and configure logging in containerd packages.\n\nThis package is not intended to be used as a standalone logging package outside of the containerd ecosystem and is intended as an interface wrapper around a logging implementation.\nIn the future this package may be replaced with a common go logging interface.\n\n## Project details\n\n**log** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).\nAs a containerd sub-project, you will find the:\n * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md),\n * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS),\n * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md)\n\ninformation in our [`containerd/project`](https://github.com/containerd/project) repository.\n\n"
  },
  {
    "path": "vendor/github.com/containerd/log/context.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\n// Package log provides types and functions related to logging, passing\n// loggers through a context, and attaching context to the logger.\n//\n// # Transitional types\n//\n// This package contains various types that are aliases for types in [logrus].\n// These aliases are intended for transitioning away from hard-coding logrus\n// as logging implementation. Consumers of this package are encouraged to use\n// the type-aliases from this package instead of directly using their logrus\n// equivalent.\n//\n// The intent is to replace these aliases with locally defined types and\n// interfaces once all consumers are no longer directly importing logrus\n// types.\n//\n// IMPORTANT: due to the transitional purpose of this package, it is not\n// guaranteed for the full logrus API to be provided in the future. As\n// outlined, these aliases are provided as a step to transition away from\n// a specific implementation which, as a result, exposes the full logrus API.\n// While no decisions have been made on the ultimate design and interface\n// provided by this package, we do not expect carrying \"less common\" features.\npackage log\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/sirupsen/logrus\"\n)\n\n// G is a shorthand for [GetLogger].\n//\n// We may want to define this locally to a package to get package tagged log\n// messages.\nvar G = GetLogger\n\n// L is an alias for the standard logger.\nvar L = &Entry{\n\tLogger: logrus.StandardLogger(),\n\t// Default is three fields plus a little extra room.\n\tData: make(Fields, 6),\n}\n\ntype loggerKey struct{}\n\n// Fields type to pass to \"WithFields\".\ntype Fields = map[string]any\n\n// Entry is a logging entry. It contains all the fields passed with\n// [Entry.WithFields]. It's finally logged when Trace, Debug, Info, Warn,\n// Error, Fatal or Panic is called on it. These objects can be reused and\n// passed around as much as you wish to avoid field duplication.\n//\n// Entry is a transitional type, and currently an alias for [logrus.Entry].\ntype Entry = logrus.Entry\n\n// RFC3339NanoFixed is [time.RFC3339Nano] with nanoseconds padded using\n// zeros to ensure the formatted time is always the same number of\n// characters.\nconst RFC3339NanoFixed = \"2006-01-02T15:04:05.000000000Z07:00\"\n\n// Level is a logging level.\ntype Level = logrus.Level\n\n// Supported log levels.\nconst (\n\t// TraceLevel level. Designates finer-grained informational events\n\t// than [DebugLevel].\n\tTraceLevel Level = logrus.TraceLevel\n\n\t// DebugLevel level. Usually only enabled when debugging. Very verbose\n\t// logging.\n\tDebugLevel Level = logrus.DebugLevel\n\n\t// InfoLevel level. General operational entries about what's going on\n\t// inside the application.\n\tInfoLevel Level = logrus.InfoLevel\n\n\t// WarnLevel level. Non-critical entries that deserve eyes.\n\tWarnLevel Level = logrus.WarnLevel\n\n\t// ErrorLevel level. Logs errors that should definitely be noted.\n\t// Commonly used for hooks to send errors to an error tracking service.\n\tErrorLevel Level = logrus.ErrorLevel\n\n\t// FatalLevel level. Logs and then calls \"logger.Exit(1)\". It exits\n\t// even if the logging level is set to Panic.\n\tFatalLevel Level = logrus.FatalLevel\n\n\t// PanicLevel level. This is the highest level of severity. Logs and\n\t// then calls panic with the message passed to Debug, Info, ...\n\tPanicLevel Level = logrus.PanicLevel\n)\n\n// SetLevel sets log level globally. It returns an error if the given\n// level is not supported.\n//\n// level can be one of:\n//\n//   - \"trace\" ([TraceLevel])\n//   - \"debug\" ([DebugLevel])\n//   - \"info\" ([InfoLevel])\n//   - \"warn\" ([WarnLevel])\n//   - \"error\" ([ErrorLevel])\n//   - \"fatal\" ([FatalLevel])\n//   - \"panic\" ([PanicLevel])\nfunc SetLevel(level string) error {\n\tlvl, err := logrus.ParseLevel(level)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tL.Logger.SetLevel(lvl)\n\treturn nil\n}\n\n// GetLevel returns the current log level.\nfunc GetLevel() Level {\n\treturn L.Logger.GetLevel()\n}\n\n// OutputFormat specifies a log output format.\ntype OutputFormat string\n\n// Supported log output formats.\nconst (\n\t// TextFormat represents the text logging format.\n\tTextFormat OutputFormat = \"text\"\n\n\t// JSONFormat represents the JSON logging format.\n\tJSONFormat OutputFormat = \"json\"\n)\n\n// SetFormat sets the log output format ([TextFormat] or [JSONFormat]).\nfunc SetFormat(format OutputFormat) error {\n\tswitch format {\n\tcase TextFormat:\n\t\tL.Logger.SetFormatter(&logrus.TextFormatter{\n\t\t\tTimestampFormat: RFC3339NanoFixed,\n\t\t\tFullTimestamp:   true,\n\t\t})\n\t\treturn nil\n\tcase JSONFormat:\n\t\tL.Logger.SetFormatter(&logrus.JSONFormatter{\n\t\t\tTimestampFormat: RFC3339NanoFixed,\n\t\t})\n\t\treturn nil\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown log format: %s\", format)\n\t}\n}\n\n// WithLogger returns a new context with the provided logger. Use in\n// combination with logger.WithField(s) for great effect.\nfunc WithLogger(ctx context.Context, logger *Entry) context.Context {\n\treturn context.WithValue(ctx, loggerKey{}, logger.WithContext(ctx))\n}\n\n// GetLogger retrieves the current logger from the context. If no logger is\n// available, the default logger is returned.\nfunc GetLogger(ctx context.Context) *Entry {\n\tif logger := ctx.Value(loggerKey{}); logger != nil {\n\t\treturn logger.(*Entry)\n\t}\n\treturn L.WithContext(ctx)\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/stargz-snapshotter/estargz/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/containerd/stargz-snapshotter/estargz/build.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\n/*\n   Copyright 2019 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\npackage estargz\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/containerd/stargz-snapshotter/estargz/errorutil\"\n\t\"github.com/klauspost/compress/zstd\"\n\tdigest \"github.com/opencontainers/go-digest\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\ntype options struct {\n\tchunkSize              int\n\tcompressionLevel       int\n\tprioritizedFiles       []string\n\tmissedPrioritizedFiles *[]string\n\tcompression            Compression\n\tctx                    context.Context\n\tminChunkSize           int\n}\n\ntype Option func(o *options) error\n\n// WithChunkSize option specifies the chunk size of eStargz blob to build.\nfunc WithChunkSize(chunkSize int) Option {\n\treturn func(o *options) error {\n\t\to.chunkSize = chunkSize\n\t\treturn nil\n\t}\n}\n\n// WithCompressionLevel option specifies the gzip compression level.\n// The default is gzip.BestCompression.\n// This option will be ignored if WithCompression option is used.\n// See also: https://godoc.org/compress/gzip#pkg-constants\nfunc WithCompressionLevel(level int) Option {\n\treturn func(o *options) error {\n\t\to.compressionLevel = level\n\t\treturn nil\n\t}\n}\n\n// WithPrioritizedFiles option specifies the list of prioritized files.\n// These files must be complete paths that are absolute or relative to \"/\"\n// For example, all of \"foo/bar\", \"/foo/bar\", \"./foo/bar\" and \"../foo/bar\"\n// are treated as \"/foo/bar\".\nfunc WithPrioritizedFiles(files []string) Option {\n\treturn func(o *options) error {\n\t\to.prioritizedFiles = files\n\t\treturn nil\n\t}\n}\n\n// WithAllowPrioritizeNotFound makes Build continue the execution even if some\n// of prioritized files specified by WithPrioritizedFiles option aren't found\n// in the input tar. Instead, this records all missed file names to the passed\n// slice.\nfunc WithAllowPrioritizeNotFound(missedFiles *[]string) Option {\n\treturn func(o *options) error {\n\t\tif missedFiles == nil {\n\t\t\treturn fmt.Errorf(\"WithAllowPrioritizeNotFound: slice must be passed\")\n\t\t}\n\t\to.missedPrioritizedFiles = missedFiles\n\t\treturn nil\n\t}\n}\n\n// WithCompression specifies compression algorithm to be used.\n// Default is gzip.\nfunc WithCompression(compression Compression) Option {\n\treturn func(o *options) error {\n\t\to.compression = compression\n\t\treturn nil\n\t}\n}\n\n// WithContext specifies a context that can be used for clean canceleration.\nfunc WithContext(ctx context.Context) Option {\n\treturn func(o *options) error {\n\t\to.ctx = ctx\n\t\treturn nil\n\t}\n}\n\n// WithMinChunkSize option specifies the minimal number of bytes of data\n// must be written in one gzip stream.\n// By increasing this number, one gzip stream can contain multiple files\n// and it hopefully leads to smaller result blob.\n// NOTE: This adds a TOC property that old reader doesn't understand.\nfunc WithMinChunkSize(minChunkSize int) Option {\n\treturn func(o *options) error {\n\t\to.minChunkSize = minChunkSize\n\t\treturn nil\n\t}\n}\n\n// Blob is an eStargz blob.\ntype Blob struct {\n\tio.ReadCloser\n\tdiffID    digest.Digester\n\ttocDigest digest.Digest\n}\n\n// DiffID returns the digest of uncompressed blob.\n// It is only valid to call DiffID after Close.\nfunc (b *Blob) DiffID() digest.Digest {\n\treturn b.diffID.Digest()\n}\n\n// TOCDigest returns the digest of uncompressed TOC JSON.\nfunc (b *Blob) TOCDigest() digest.Digest {\n\treturn b.tocDigest\n}\n\n// Build builds an eStargz blob which is an extended version of stargz, from a blob (gzip, zstd\n// or plain tar) passed through the argument. If there are some prioritized files are listed in\n// the option, these files are grouped as \"prioritized\" and can be used for runtime optimization\n// (e.g. prefetch). This function builds a blob in parallel, with dividing that blob into several\n// (at least the number of runtime.GOMAXPROCS(0)) sub-blobs.\nfunc Build(tarBlob *io.SectionReader, opt ...Option) (_ *Blob, rErr error) {\n\tvar opts options\n\topts.compressionLevel = gzip.BestCompression // BestCompression by default\n\tfor _, o := range opt {\n\t\tif err := o(&opts); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif opts.compression == nil {\n\t\topts.compression = newGzipCompressionWithLevel(opts.compressionLevel)\n\t}\n\tlayerFiles := newTempFiles()\n\tctx := opts.ctx\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}\n\tdone := make(chan struct{})\n\tdefer close(done)\n\tgo func() {\n\t\tselect {\n\t\tcase <-done:\n\t\t\t// nop\n\t\tcase <-ctx.Done():\n\t\t\tlayerFiles.CleanupAll()\n\t\t}\n\t}()\n\tdefer func() {\n\t\tif rErr != nil {\n\t\t\tif err := layerFiles.CleanupAll(); err != nil {\n\t\t\t\trErr = fmt.Errorf(\"failed to cleanup tmp files: %v: %w\", err, rErr)\n\t\t\t}\n\t\t}\n\t\tif cErr := ctx.Err(); cErr != nil {\n\t\t\trErr = fmt.Errorf(\"error from context %q: %w\", cErr, rErr)\n\t\t}\n\t}()\n\ttarBlob, err := decompressBlob(tarBlob, layerFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tentries, err := sortEntries(tarBlob, opts.prioritizedFiles, opts.missedPrioritizedFiles)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar tarParts [][]*entry\n\tif opts.minChunkSize > 0 {\n\t\t// Each entry needs to know the size of the current gzip stream so they\n\t\t// cannot be processed in parallel.\n\t\ttarParts = [][]*entry{entries}\n\t} else {\n\t\ttarParts = divideEntries(entries, runtime.GOMAXPROCS(0))\n\t}\n\twriters := make([]*Writer, len(tarParts))\n\tpayloads := make([]*os.File, len(tarParts))\n\tvar mu sync.Mutex\n\tvar eg errgroup.Group\n\tfor i, parts := range tarParts {\n\t\ti, parts := i, parts\n\t\t// builds verifiable stargz sub-blobs\n\t\teg.Go(func() error {\n\t\t\tesgzFile, err := layerFiles.TempFile(\"\", \"esgzdata\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tsw := NewWriterWithCompressor(esgzFile, opts.compression)\n\t\t\tsw.ChunkSize = opts.chunkSize\n\t\t\tsw.MinChunkSize = opts.minChunkSize\n\t\t\tif sw.needsOpenGzEntries == nil {\n\t\t\t\tsw.needsOpenGzEntries = make(map[string]struct{})\n\t\t\t}\n\t\t\tfor _, f := range []string{PrefetchLandmark, NoPrefetchLandmark} {\n\t\t\t\tsw.needsOpenGzEntries[f] = struct{}{}\n\t\t\t}\n\t\t\tif err := sw.AppendTar(readerFromEntries(parts...)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tmu.Lock()\n\t\t\twriters[i] = sw\n\t\t\tpayloads[i] = esgzFile\n\t\t\tmu.Unlock()\n\t\t\treturn nil\n\t\t})\n\t}\n\tif err := eg.Wait(); err != nil {\n\t\trErr = err\n\t\treturn nil, err\n\t}\n\ttocAndFooter, tocDgst, err := closeWithCombine(writers...)\n\tif err != nil {\n\t\trErr = err\n\t\treturn nil, err\n\t}\n\tvar rs []io.Reader\n\tfor _, p := range payloads {\n\t\tfs, err := fileSectionReader(p)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trs = append(rs, fs)\n\t}\n\tdiffID := digest.Canonical.Digester()\n\tpr, pw := io.Pipe()\n\tgo func() {\n\t\tr, err := opts.compression.Reader(io.TeeReader(io.MultiReader(append(rs, tocAndFooter)...), pw))\n\t\tif err != nil {\n\t\t\tpw.CloseWithError(err)\n\t\t\treturn\n\t\t}\n\t\tdefer r.Close()\n\t\tif _, err := io.Copy(diffID.Hash(), r); err != nil {\n\t\t\tpw.CloseWithError(err)\n\t\t\treturn\n\t\t}\n\t\tpw.Close()\n\t}()\n\treturn &Blob{\n\t\tReadCloser: readCloser{\n\t\t\tReader:    pr,\n\t\t\tcloseFunc: layerFiles.CleanupAll,\n\t\t},\n\t\ttocDigest: tocDgst,\n\t\tdiffID:    diffID,\n\t}, nil\n}\n\n// closeWithCombine takes unclosed Writers and close them. This also returns the\n// toc that combined all Writers into.\n// Writers doesn't write TOC and footer to the underlying writers so they can be\n// combined into a single eStargz and tocAndFooter returned by this function can\n// be appended at the tail of that combined blob.\nfunc closeWithCombine(ws ...*Writer) (tocAndFooterR io.Reader, tocDgst digest.Digest, err error) {\n\tif len(ws) == 0 {\n\t\treturn nil, \"\", fmt.Errorf(\"at least one writer must be passed\")\n\t}\n\tfor _, w := range ws {\n\t\tif w.closed {\n\t\t\treturn nil, \"\", fmt.Errorf(\"writer must be unclosed\")\n\t\t}\n\t\tdefer func(w *Writer) { w.closed = true }(w)\n\t\tif err := w.closeGz(); err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\t\tif err := w.bw.Flush(); err != nil {\n\t\t\treturn nil, \"\", err\n\t\t}\n\t}\n\tvar (\n\t\tmtoc          = new(JTOC)\n\t\tcurrentOffset int64\n\t)\n\tmtoc.Version = ws[0].toc.Version\n\tfor _, w := range ws {\n\t\tfor _, e := range w.toc.Entries {\n\t\t\t// Recalculate Offset of non-empty files/chunks\n\t\t\tif (e.Type == \"reg\" && e.Size > 0) || e.Type == \"chunk\" {\n\t\t\t\te.Offset += currentOffset\n\t\t\t}\n\t\t\tmtoc.Entries = append(mtoc.Entries, e)\n\t\t}\n\t\tif w.toc.Version > mtoc.Version {\n\t\t\tmtoc.Version = w.toc.Version\n\t\t}\n\t\tcurrentOffset += w.cw.n\n\t}\n\n\treturn tocAndFooter(ws[0].compressor, mtoc, currentOffset)\n}\n\nfunc tocAndFooter(compressor Compressor, toc *JTOC, offset int64) (io.Reader, digest.Digest, error) {\n\tbuf := new(bytes.Buffer)\n\ttocDigest, err := compressor.WriteTOCAndFooter(buf, offset, toc, nil)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\treturn buf, tocDigest, nil\n}\n\n// divideEntries divides passed entries to the parts at least the number specified by the\n// argument.\nfunc divideEntries(entries []*entry, minPartsNum int) (set [][]*entry) {\n\tvar estimatedSize int64\n\tfor _, e := range entries {\n\t\testimatedSize += e.header.Size\n\t}\n\tunitSize := estimatedSize / int64(minPartsNum)\n\tvar (\n\t\tnextEnd = unitSize\n\t\toffset  int64\n\t)\n\tset = append(set, []*entry{})\n\tfor _, e := range entries {\n\t\tset[len(set)-1] = append(set[len(set)-1], e)\n\t\toffset += e.header.Size\n\t\tif offset > nextEnd {\n\t\t\tset = append(set, []*entry{})\n\t\t\tnextEnd += unitSize\n\t\t}\n\t}\n\treturn\n}\n\nvar errNotFound = errors.New(\"not found\")\n\n// sortEntries reads the specified tar blob and returns a list of tar entries.\n// If some of prioritized files are specified, the list starts from these\n// files with keeping the order specified by the argument.\nfunc sortEntries(in io.ReaderAt, prioritized []string, missedPrioritized *[]string) ([]*entry, error) {\n\n\t// Import tar file.\n\tintar, err := importTar(in)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to sort: %w\", err)\n\t}\n\n\t// Sort the tar file respecting to the prioritized files list.\n\tsorted := &tarFile{}\n\tfor _, l := range prioritized {\n\t\tif err := moveRec(l, intar, sorted); err != nil {\n\t\t\tif errors.Is(err, errNotFound) && missedPrioritized != nil {\n\t\t\t\t*missedPrioritized = append(*missedPrioritized, l)\n\t\t\t\tcontinue // allow not found\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"failed to sort tar entries: %w\", err)\n\t\t}\n\t}\n\tif len(prioritized) == 0 {\n\t\tsorted.add(&entry{\n\t\t\theader: &tar.Header{\n\t\t\t\tName:     NoPrefetchLandmark,\n\t\t\t\tTypeflag: tar.TypeReg,\n\t\t\t\tSize:     int64(len([]byte{landmarkContents})),\n\t\t\t},\n\t\t\tpayload: bytes.NewReader([]byte{landmarkContents}),\n\t\t})\n\t} else {\n\t\tsorted.add(&entry{\n\t\t\theader: &tar.Header{\n\t\t\t\tName:     PrefetchLandmark,\n\t\t\t\tTypeflag: tar.TypeReg,\n\t\t\t\tSize:     int64(len([]byte{landmarkContents})),\n\t\t\t},\n\t\t\tpayload: bytes.NewReader([]byte{landmarkContents}),\n\t\t})\n\t}\n\n\t// Dump all entry and concatinate them.\n\treturn append(sorted.dump(), intar.dump()...), nil\n}\n\n// readerFromEntries returns a reader of tar archive that contains entries passed\n// through the arguments.\nfunc readerFromEntries(entries ...*entry) io.Reader {\n\tpr, pw := io.Pipe()\n\tgo func() {\n\t\ttw := tar.NewWriter(pw)\n\t\tdefer tw.Close()\n\t\tfor _, entry := range entries {\n\t\t\tif err := tw.WriteHeader(entry.header); err != nil {\n\t\t\t\tpw.CloseWithError(fmt.Errorf(\"Failed to write tar header: %v\", err))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif _, err := io.Copy(tw, entry.payload); err != nil {\n\t\t\t\tpw.CloseWithError(fmt.Errorf(\"Failed to write tar payload: %v\", err))\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tpw.Close()\n\t}()\n\treturn pr\n}\n\nfunc importTar(in io.ReaderAt) (*tarFile, error) {\n\ttf := &tarFile{}\n\tpw, err := newCountReadSeeker(in)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to make position watcher: %w\", err)\n\t}\n\ttr := tar.NewReader(pw)\n\n\t// Walk through all nodes.\n\tfor {\n\t\t// Fetch and parse next header.\n\t\th, err := tr.Next()\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to parse tar file, %w\", err)\n\t\t\t}\n\t\t}\n\t\tswitch cleanEntryName(h.Name) {\n\t\tcase PrefetchLandmark, NoPrefetchLandmark:\n\t\t\t// Ignore existing landmark\n\t\t\tcontinue\n\t\t}\n\n\t\t// Add entry. If it already exists, replace it.\n\t\tif _, ok := tf.get(h.Name); ok {\n\t\t\ttf.remove(h.Name)\n\t\t}\n\t\ttf.add(&entry{\n\t\t\theader:  h,\n\t\t\tpayload: io.NewSectionReader(in, pw.currentPos(), h.Size),\n\t\t})\n\t}\n\n\treturn tf, nil\n}\n\nfunc moveRec(name string, in *tarFile, out *tarFile) error {\n\tname = cleanEntryName(name)\n\tif name == \"\" { // root directory. stop recursion.\n\t\tif e, ok := in.get(name); ok {\n\t\t\t// entry of the root directory exists. we should move it as well.\n\t\t\t// this case will occur if tar entries are prefixed with \"./\", \"/\", etc.\n\t\t\tout.add(e)\n\t\t\tin.remove(name)\n\t\t}\n\t\treturn nil\n\t}\n\n\t_, okIn := in.get(name)\n\t_, okOut := out.get(name)\n\tif !okIn && !okOut {\n\t\treturn fmt.Errorf(\"file: %q: %w\", name, errNotFound)\n\t}\n\n\tparent, _ := path.Split(strings.TrimSuffix(name, \"/\"))\n\tif err := moveRec(parent, in, out); err != nil {\n\t\treturn err\n\t}\n\tif e, ok := in.get(name); ok && e.header.Typeflag == tar.TypeLink {\n\t\tif err := moveRec(e.header.Linkname, in, out); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif e, ok := in.get(name); ok {\n\t\tout.add(e)\n\t\tin.remove(name)\n\t}\n\treturn nil\n}\n\ntype entry struct {\n\theader  *tar.Header\n\tpayload io.ReadSeeker\n}\n\ntype tarFile struct {\n\tindex  map[string]*entry\n\tstream []*entry\n}\n\nfunc (f *tarFile) add(e *entry) {\n\tif f.index == nil {\n\t\tf.index = make(map[string]*entry)\n\t}\n\tf.index[cleanEntryName(e.header.Name)] = e\n\tf.stream = append(f.stream, e)\n}\n\nfunc (f *tarFile) remove(name string) {\n\tname = cleanEntryName(name)\n\tif f.index != nil {\n\t\tdelete(f.index, name)\n\t}\n\tvar filtered []*entry\n\tfor _, e := range f.stream {\n\t\tif cleanEntryName(e.header.Name) == name {\n\t\t\tcontinue\n\t\t}\n\t\tfiltered = append(filtered, e)\n\t}\n\tf.stream = filtered\n}\n\nfunc (f *tarFile) get(name string) (e *entry, ok bool) {\n\tif f.index == nil {\n\t\treturn nil, false\n\t}\n\te, ok = f.index[cleanEntryName(name)]\n\treturn\n}\n\nfunc (f *tarFile) dump() []*entry {\n\treturn f.stream\n}\n\ntype readCloser struct {\n\tio.Reader\n\tcloseFunc func() error\n}\n\nfunc (rc readCloser) Close() error {\n\treturn rc.closeFunc()\n}\n\nfunc fileSectionReader(file *os.File) (*io.SectionReader, error) {\n\tinfo, err := file.Stat()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn io.NewSectionReader(file, 0, info.Size()), nil\n}\n\nfunc newTempFiles() *tempFiles {\n\treturn &tempFiles{}\n}\n\ntype tempFiles struct {\n\tfiles       []*os.File\n\tfilesMu     sync.Mutex\n\tcleanupOnce sync.Once\n}\n\nfunc (tf *tempFiles) TempFile(dir, pattern string) (*os.File, error) {\n\tf, err := os.CreateTemp(dir, pattern)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttf.filesMu.Lock()\n\ttf.files = append(tf.files, f)\n\ttf.filesMu.Unlock()\n\treturn f, nil\n}\n\nfunc (tf *tempFiles) CleanupAll() (err error) {\n\ttf.cleanupOnce.Do(func() {\n\t\terr = tf.cleanupAll()\n\t})\n\treturn\n}\n\nfunc (tf *tempFiles) cleanupAll() error {\n\ttf.filesMu.Lock()\n\tdefer tf.filesMu.Unlock()\n\tvar allErr []error\n\tfor _, f := range tf.files {\n\t\tif err := f.Close(); err != nil {\n\t\t\tallErr = append(allErr, err)\n\t\t}\n\t\tif err := os.Remove(f.Name()); err != nil {\n\t\t\tallErr = append(allErr, err)\n\t\t}\n\t}\n\ttf.files = nil\n\treturn errorutil.Aggregate(allErr)\n}\n\nfunc newCountReadSeeker(r io.ReaderAt) (*countReadSeeker, error) {\n\tpos := int64(0)\n\treturn &countReadSeeker{r: r, cPos: &pos}, nil\n}\n\ntype countReadSeeker struct {\n\tr    io.ReaderAt\n\tcPos *int64\n\n\tmu sync.Mutex\n}\n\nfunc (cr *countReadSeeker) Read(p []byte) (int, error) {\n\tcr.mu.Lock()\n\tdefer cr.mu.Unlock()\n\n\tn, err := cr.r.ReadAt(p, *cr.cPos)\n\tif err == nil {\n\t\t*cr.cPos += int64(n)\n\t}\n\treturn n, err\n}\n\nfunc (cr *countReadSeeker) Seek(offset int64, whence int) (int64, error) {\n\tcr.mu.Lock()\n\tdefer cr.mu.Unlock()\n\n\tswitch whence {\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"Unknown whence: %v\", whence)\n\tcase io.SeekStart:\n\tcase io.SeekCurrent:\n\t\toffset += *cr.cPos\n\tcase io.SeekEnd:\n\t\treturn 0, fmt.Errorf(\"Unsupported whence: %v\", whence)\n\t}\n\n\tif offset < 0 {\n\t\treturn 0, fmt.Errorf(\"invalid offset\")\n\t}\n\t*cr.cPos = offset\n\treturn offset, nil\n}\n\nfunc (cr *countReadSeeker) currentPos() int64 {\n\tcr.mu.Lock()\n\tdefer cr.mu.Unlock()\n\n\treturn *cr.cPos\n}\n\nfunc decompressBlob(org *io.SectionReader, tmp *tempFiles) (*io.SectionReader, error) {\n\tif org.Size() < 4 {\n\t\treturn org, nil\n\t}\n\tsrc := make([]byte, 4)\n\tif _, err := org.Read(src); err != nil && err != io.EOF {\n\t\treturn nil, err\n\t}\n\tvar dR io.Reader\n\tif bytes.Equal([]byte{0x1F, 0x8B, 0x08}, src[:3]) {\n\t\t// gzip\n\t\tdgR, err := gzip.NewReader(io.NewSectionReader(org, 0, org.Size()))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer dgR.Close()\n\t\tdR = io.Reader(dgR)\n\t} else if bytes.Equal([]byte{0x28, 0xb5, 0x2f, 0xfd}, src[:4]) {\n\t\t// zstd\n\t\tdzR, err := zstd.NewReader(io.NewSectionReader(org, 0, org.Size()))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer dzR.Close()\n\t\tdR = io.Reader(dzR)\n\t} else {\n\t\t// uncompressed\n\t\treturn io.NewSectionReader(org, 0, org.Size()), nil\n\t}\n\tb, err := tmp.TempFile(\"\", \"uncompresseddata\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err := io.Copy(b, dR); err != nil {\n\t\treturn nil, err\n\t}\n\treturn fileSectionReader(b)\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/stargz-snapshotter/estargz/errorutil/errors.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\npackage errorutil\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// Aggregate combines a list of errors into a single new error.\nfunc Aggregate(errs []error) error {\n\tswitch len(errs) {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\treturn errs[0]\n\tdefault:\n\t\tpoints := make([]string, len(errs)+1)\n\t\tpoints[0] = fmt.Sprintf(\"%d error(s) occurred:\", len(errs))\n\t\tfor i, err := range errs {\n\t\t\tpoints[i+1] = fmt.Sprintf(\"* %s\", err)\n\t\t}\n\t\treturn errors.New(strings.Join(points, \"\\n\\t\"))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\n/*\n   Copyright 2019 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\npackage estargz\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"crypto/sha256\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/containerd/stargz-snapshotter/estargz/errorutil\"\n\tdigest \"github.com/opencontainers/go-digest\"\n\t\"github.com/vbatts/tar-split/archive/tar\"\n)\n\n// A Reader permits random access reads from a stargz file.\ntype Reader struct {\n\tsr        *io.SectionReader\n\ttoc       *JTOC\n\ttocDigest digest.Digest\n\n\t// m stores all non-chunk entries, keyed by name.\n\tm map[string]*TOCEntry\n\n\t// chunks stores all TOCEntry values for regular files that\n\t// are split up. For a file with a single chunk, it's only\n\t// stored in m.\n\tchunks map[string][]*TOCEntry\n\n\tdecompressor Decompressor\n}\n\ntype openOpts struct {\n\ttocOffset     int64\n\tdecompressors []Decompressor\n\ttelemetry     *Telemetry\n}\n\n// OpenOption is an option used during opening the layer\ntype OpenOption func(o *openOpts) error\n\n// WithTOCOffset option specifies the offset of TOC\nfunc WithTOCOffset(tocOffset int64) OpenOption {\n\treturn func(o *openOpts) error {\n\t\to.tocOffset = tocOffset\n\t\treturn nil\n\t}\n}\n\n// WithDecompressors option specifies decompressors to use.\n// Default is gzip-based decompressor.\nfunc WithDecompressors(decompressors ...Decompressor) OpenOption {\n\treturn func(o *openOpts) error {\n\t\to.decompressors = decompressors\n\t\treturn nil\n\t}\n}\n\n// WithTelemetry option specifies the telemetry hooks\nfunc WithTelemetry(telemetry *Telemetry) OpenOption {\n\treturn func(o *openOpts) error {\n\t\to.telemetry = telemetry\n\t\treturn nil\n\t}\n}\n\n// MeasureLatencyHook is a func which takes start time and records the diff\ntype MeasureLatencyHook func(time.Time)\n\n// Telemetry is a struct which defines telemetry hooks. By implementing these hooks you should be able to record\n// the latency metrics of the respective steps of estargz open operation. To be used with estargz.OpenWithTelemetry(...)\ntype Telemetry struct {\n\tGetFooterLatency      MeasureLatencyHook // measure time to get stargz footer (in milliseconds)\n\tGetTocLatency         MeasureLatencyHook // measure time to GET TOC JSON (in milliseconds)\n\tDeserializeTocLatency MeasureLatencyHook // measure time to deserialize TOC JSON (in milliseconds)\n}\n\n// Open opens a stargz file for reading.\n// The behavior is configurable using options.\n//\n// Note that each entry name is normalized as the path that is relative to root.\nfunc Open(sr *io.SectionReader, opt ...OpenOption) (*Reader, error) {\n\tvar opts openOpts\n\tfor _, o := range opt {\n\t\tif err := o(&opts); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tgzipCompressors := []Decompressor{new(GzipDecompressor), new(LegacyGzipDecompressor)}\n\tdecompressors := append(gzipCompressors, opts.decompressors...)\n\n\t// Determine the size to fetch. Try to fetch as many bytes as possible.\n\tfetchSize := maxFooterSize(sr.Size(), decompressors...)\n\tif maybeTocOffset := opts.tocOffset; maybeTocOffset > fetchSize {\n\t\tif maybeTocOffset > sr.Size() {\n\t\t\treturn nil, fmt.Errorf(\"blob size %d is smaller than the toc offset\", sr.Size())\n\t\t}\n\t\tfetchSize = sr.Size() - maybeTocOffset\n\t}\n\n\tstart := time.Now() // before getting layer footer\n\tfooter := make([]byte, fetchSize)\n\tif _, err := sr.ReadAt(footer, sr.Size()-fetchSize); err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading footer: %v\", err)\n\t}\n\tif opts.telemetry != nil && opts.telemetry.GetFooterLatency != nil {\n\t\topts.telemetry.GetFooterLatency(start)\n\t}\n\n\tvar allErr []error\n\tvar found bool\n\tvar r *Reader\n\tfor _, d := range decompressors {\n\t\tfSize := d.FooterSize()\n\t\tfOffset := positive(int64(len(footer)) - fSize)\n\t\tmaybeTocBytes := footer[:fOffset]\n\t\t_, tocOffset, tocSize, err := d.ParseFooter(footer[fOffset:])\n\t\tif err != nil {\n\t\t\tallErr = append(allErr, err)\n\t\t\tcontinue\n\t\t}\n\t\tif tocOffset >= 0 && tocSize <= 0 {\n\t\t\ttocSize = sr.Size() - tocOffset - fSize\n\t\t}\n\t\tif tocOffset >= 0 && tocSize < int64(len(maybeTocBytes)) {\n\t\t\tmaybeTocBytes = maybeTocBytes[:tocSize]\n\t\t}\n\t\tr, err = parseTOC(d, sr, tocOffset, tocSize, maybeTocBytes, opts)\n\t\tif err == nil {\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}\n\t\tallErr = append(allErr, err)\n\t}\n\tif !found {\n\t\treturn nil, errorutil.Aggregate(allErr)\n\t}\n\tif err := r.initFields(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to initialize fields of entries: %v\", err)\n\t}\n\treturn r, nil\n}\n\n// OpenFooter extracts and parses footer from the given blob.\n// only supports gzip-based eStargz.\nfunc OpenFooter(sr *io.SectionReader) (tocOffset int64, footerSize int64, rErr error) {\n\tif sr.Size() < FooterSize && sr.Size() < legacyFooterSize {\n\t\treturn 0, 0, fmt.Errorf(\"blob size %d is smaller than the footer size\", sr.Size())\n\t}\n\tvar footer [FooterSize]byte\n\tif _, err := sr.ReadAt(footer[:], sr.Size()-FooterSize); err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"error reading footer: %v\", err)\n\t}\n\tvar allErr []error\n\tfor _, d := range []Decompressor{new(GzipDecompressor), new(LegacyGzipDecompressor)} {\n\t\tfSize := d.FooterSize()\n\t\tfOffset := positive(int64(len(footer)) - fSize)\n\t\t_, tocOffset, _, err := d.ParseFooter(footer[fOffset:])\n\t\tif err == nil {\n\t\t\treturn tocOffset, fSize, err\n\t\t}\n\t\tallErr = append(allErr, err)\n\t}\n\treturn 0, 0, errorutil.Aggregate(allErr)\n}\n\n// initFields populates the Reader from r.toc after decoding it from\n// JSON.\n//\n// Unexported fields are populated and TOCEntry fields that were\n// implicit in the JSON are populated.\nfunc (r *Reader) initFields() error {\n\tr.m = make(map[string]*TOCEntry, len(r.toc.Entries))\n\tr.chunks = make(map[string][]*TOCEntry)\n\tvar lastPath string\n\tuname := map[int]string{}\n\tgname := map[int]string{}\n\tvar lastRegEnt *TOCEntry\n\tvar chunkTopIndex int\n\tfor i, ent := range r.toc.Entries {\n\t\tent.Name = cleanEntryName(ent.Name)\n\t\tswitch ent.Type {\n\t\tcase \"reg\", \"chunk\":\n\t\t\tif ent.Offset != r.toc.Entries[chunkTopIndex].Offset {\n\t\t\t\tchunkTopIndex = i\n\t\t\t}\n\t\t\tent.chunkTopIndex = chunkTopIndex\n\t\t}\n\t\tif ent.Type == \"reg\" {\n\t\t\tlastRegEnt = ent\n\t\t}\n\t\tif ent.Type == \"chunk\" {\n\t\t\tent.Name = lastPath\n\t\t\tr.chunks[ent.Name] = append(r.chunks[ent.Name], ent)\n\t\t\tif ent.ChunkSize == 0 && lastRegEnt != nil {\n\t\t\t\tent.ChunkSize = lastRegEnt.Size - ent.ChunkOffset\n\t\t\t}\n\t\t} else {\n\t\t\tlastPath = ent.Name\n\n\t\t\tif ent.Uname != \"\" {\n\t\t\t\tuname[ent.UID] = ent.Uname\n\t\t\t} else {\n\t\t\t\tent.Uname = uname[ent.UID]\n\t\t\t}\n\t\t\tif ent.Gname != \"\" {\n\t\t\t\tgname[ent.GID] = ent.Gname\n\t\t\t} else {\n\t\t\t\tent.Gname = uname[ent.GID]\n\t\t\t}\n\n\t\t\tent.modTime, _ = time.Parse(time.RFC3339, ent.ModTime3339)\n\n\t\t\tif ent.Type == \"dir\" {\n\t\t\t\tent.NumLink++ // Parent dir links to this directory\n\t\t\t}\n\t\t\tr.m[ent.Name] = ent\n\t\t}\n\t\tif ent.Type == \"reg\" && ent.ChunkSize > 0 && ent.ChunkSize < ent.Size {\n\t\t\tr.chunks[ent.Name] = make([]*TOCEntry, 0, ent.Size/ent.ChunkSize+1)\n\t\t\tr.chunks[ent.Name] = append(r.chunks[ent.Name], ent)\n\t\t}\n\t\tif ent.ChunkSize == 0 && ent.Size != 0 {\n\t\t\tent.ChunkSize = ent.Size\n\t\t}\n\t}\n\n\t// Populate children, add implicit directories:\n\tfor _, ent := range r.toc.Entries {\n\t\tif ent.Type == \"chunk\" {\n\t\t\tcontinue\n\t\t}\n\t\t// add \"foo/\":\n\t\t//    add \"foo\" child to \"\" (creating \"\" if necessary)\n\t\t//\n\t\t// add \"foo/bar/\":\n\t\t//    add \"bar\" child to \"foo\" (creating \"foo\" if necessary)\n\t\t//\n\t\t// add \"foo/bar.txt\":\n\t\t//    add \"bar.txt\" child to \"foo\" (creating \"foo\" if necessary)\n\t\t//\n\t\t// add \"a/b/c/d/e/f.txt\":\n\t\t//    create \"a/b/c/d/e\" node\n\t\t//    add \"f.txt\" child to \"e\"\n\n\t\tname := ent.Name\n\t\tpdirName := parentDir(name)\n\t\tif name == pdirName {\n\t\t\t// This entry and its parent are the same.\n\t\t\t// Ignore this for avoiding infinite loop of the reference.\n\t\t\t// The example case where this can occur is when tar contains the root\n\t\t\t// directory itself (e.g. \"./\", \"/\").\n\t\t\tcontinue\n\t\t}\n\t\tpdir := r.getOrCreateDir(pdirName)\n\t\tent.NumLink++ // at least one name(ent.Name) references this entry.\n\t\tif ent.Type == \"hardlink\" {\n\t\t\torg, err := r.getSource(ent)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\torg.NumLink++ // original entry is referenced by this ent.Name.\n\t\t\tent = org\n\t\t}\n\t\tpdir.addChild(path.Base(name), ent)\n\t}\n\n\tlastOffset := r.sr.Size()\n\tfor i := len(r.toc.Entries) - 1; i >= 0; i-- {\n\t\te := r.toc.Entries[i]\n\t\tif e.isDataType() {\n\t\t\te.nextOffset = lastOffset\n\t\t}\n\t\tif e.Offset != 0 && e.InnerOffset == 0 {\n\t\t\tlastOffset = e.Offset\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (r *Reader) getSource(ent *TOCEntry) (_ *TOCEntry, err error) {\n\tif ent.Type == \"hardlink\" {\n\t\torg, ok := r.m[cleanEntryName(ent.LinkName)]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"%q is a hardlink but the linkname %q isn't found\", ent.Name, ent.LinkName)\n\t\t}\n\t\tent, err = r.getSource(org)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn ent, nil\n}\n\nfunc parentDir(p string) string {\n\tdir, _ := path.Split(p)\n\treturn strings.TrimSuffix(dir, \"/\")\n}\n\nfunc (r *Reader) getOrCreateDir(d string) *TOCEntry {\n\te, ok := r.m[d]\n\tif !ok {\n\t\te = &TOCEntry{\n\t\t\tName:    d,\n\t\t\tType:    \"dir\",\n\t\t\tMode:    0755,\n\t\t\tNumLink: 2, // The directory itself(.) and the parent link to this directory.\n\t\t}\n\t\tr.m[d] = e\n\t\tif d != \"\" {\n\t\t\tpdir := r.getOrCreateDir(parentDir(d))\n\t\t\tpdir.addChild(path.Base(d), e)\n\t\t}\n\t}\n\treturn e\n}\n\nfunc (r *Reader) TOCDigest() digest.Digest {\n\treturn r.tocDigest\n}\n\n// VerifyTOC checks that the TOC JSON in the passed blob matches the\n// passed digests and that the TOC JSON contains digests for all chunks\n// contained in the blob. If the verification succceeds, this function\n// returns TOCEntryVerifier which holds all chunk digests in the stargz blob.\nfunc (r *Reader) VerifyTOC(tocDigest digest.Digest) (TOCEntryVerifier, error) {\n\t// Verify the digest of TOC JSON\n\tif r.tocDigest != tocDigest {\n\t\treturn nil, fmt.Errorf(\"invalid TOC JSON %q; want %q\", r.tocDigest, tocDigest)\n\t}\n\treturn r.Verifiers()\n}\n\n// Verifiers returns TOCEntryVerifier of this chunk. Use VerifyTOC instead in most cases\n// because this doesn't verify TOC.\nfunc (r *Reader) Verifiers() (TOCEntryVerifier, error) {\n\tchunkDigestMap := make(map[int64]digest.Digest) // map from chunk offset to the chunk digest\n\tregDigestMap := make(map[int64]digest.Digest)   // map from chunk offset to the reg file digest\n\tvar chunkDigestMapIncomplete bool\n\tvar regDigestMapIncomplete bool\n\tvar containsChunk bool\n\tfor _, e := range r.toc.Entries {\n\t\tif e.Type != \"reg\" && e.Type != \"chunk\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// offset must be unique in stargz blob\n\t\t_, dOK := chunkDigestMap[e.Offset]\n\t\t_, rOK := regDigestMap[e.Offset]\n\t\tif dOK || rOK {\n\t\t\treturn nil, fmt.Errorf(\"offset %d found twice\", e.Offset)\n\t\t}\n\n\t\tif e.Type == \"reg\" {\n\t\t\tif e.Size == 0 {\n\t\t\t\tcontinue // ignores empty file\n\t\t\t}\n\n\t\t\t// record the digest of regular file payload\n\t\t\tif e.Digest != \"\" {\n\t\t\t\td, err := digest.Parse(e.Digest)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"failed to parse regular file digest %q: %w\", e.Digest, err)\n\t\t\t\t}\n\t\t\t\tregDigestMap[e.Offset] = d\n\t\t\t} else {\n\t\t\t\tregDigestMapIncomplete = true\n\t\t\t}\n\t\t} else {\n\t\t\tcontainsChunk = true // this layer contains \"chunk\" entries.\n\t\t}\n\n\t\t// \"reg\" also can contain ChunkDigest (e.g. when \"reg\" is the first entry of\n\t\t// chunked file)\n\t\tif e.ChunkDigest != \"\" {\n\t\t\td, err := digest.Parse(e.ChunkDigest)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to parse chunk digest %q: %w\", e.ChunkDigest, err)\n\t\t\t}\n\t\t\tchunkDigestMap[e.Offset] = d\n\t\t} else {\n\t\t\tchunkDigestMapIncomplete = true\n\t\t}\n\t}\n\n\tif chunkDigestMapIncomplete {\n\t\t// Though some chunk digests are not found, if this layer doesn't contain\n\t\t// \"chunk\"s and all digest of \"reg\" files are recorded, we can use them instead.\n\t\tif !containsChunk && !regDigestMapIncomplete {\n\t\t\treturn &verifier{digestMap: regDigestMap}, nil\n\t\t}\n\t\treturn nil, fmt.Errorf(\"some ChunkDigest not found in TOC JSON\")\n\t}\n\n\treturn &verifier{digestMap: chunkDigestMap}, nil\n}\n\n// verifier is an implementation of TOCEntryVerifier which holds verifiers keyed by\n// offset of the chunk.\ntype verifier struct {\n\tdigestMap   map[int64]digest.Digest\n\tdigestMapMu sync.Mutex\n}\n\n// Verifier returns a content verifier specified by TOCEntry.\nfunc (v *verifier) Verifier(ce *TOCEntry) (digest.Verifier, error) {\n\tv.digestMapMu.Lock()\n\tdefer v.digestMapMu.Unlock()\n\td, ok := v.digestMap[ce.Offset]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"verifier for offset=%d,size=%d hasn't been registered\",\n\t\t\tce.Offset, ce.ChunkSize)\n\t}\n\treturn d.Verifier(), nil\n}\n\n// ChunkEntryForOffset returns the TOCEntry containing the byte of the\n// named file at the given offset within the file.\n// Name must be absolute path or one that is relative to root.\nfunc (r *Reader) ChunkEntryForOffset(name string, offset int64) (e *TOCEntry, ok bool) {\n\tname = cleanEntryName(name)\n\te, ok = r.Lookup(name)\n\tif !ok || !e.isDataType() {\n\t\treturn nil, false\n\t}\n\tents := r.chunks[name]\n\tif len(ents) < 2 {\n\t\tif offset >= e.ChunkSize {\n\t\t\treturn nil, false\n\t\t}\n\t\treturn e, true\n\t}\n\ti := sort.Search(len(ents), func(i int) bool {\n\t\te := ents[i]\n\t\treturn e.ChunkOffset >= offset || (offset > e.ChunkOffset && offset < e.ChunkOffset+e.ChunkSize)\n\t})\n\tif i == len(ents) {\n\t\treturn nil, false\n\t}\n\treturn ents[i], true\n}\n\n// Lookup returns the Table of Contents entry for the given path.\n//\n// To get the root directory, use the empty string.\n// Path must be absolute path or one that is relative to root.\nfunc (r *Reader) Lookup(path string) (e *TOCEntry, ok bool) {\n\tpath = cleanEntryName(path)\n\tif r == nil {\n\t\treturn\n\t}\n\te, ok = r.m[path]\n\tif ok && e.Type == \"hardlink\" {\n\t\tvar err error\n\t\te, err = r.getSource(e)\n\t\tif err != nil {\n\t\t\treturn nil, false\n\t\t}\n\t}\n\treturn\n}\n\n// OpenFile returns the reader of the specified file payload.\n//\n// Name must be absolute path or one that is relative to root.\nfunc (r *Reader) OpenFile(name string) (*io.SectionReader, error) {\n\tfr, err := r.newFileReader(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn io.NewSectionReader(fr, 0, fr.size), nil\n}\n\nfunc (r *Reader) newFileReader(name string) (*fileReader, error) {\n\tname = cleanEntryName(name)\n\tent, ok := r.Lookup(name)\n\tif !ok {\n\t\t// TODO: come up with some error plan. This is lazy:\n\t\treturn nil, &os.PathError{\n\t\t\tPath: name,\n\t\t\tOp:   \"OpenFile\",\n\t\t\tErr:  os.ErrNotExist,\n\t\t}\n\t}\n\tif ent.Type != \"reg\" {\n\t\treturn nil, &os.PathError{\n\t\t\tPath: name,\n\t\t\tOp:   \"OpenFile\",\n\t\t\tErr:  errors.New(\"not a regular file\"),\n\t\t}\n\t}\n\treturn &fileReader{\n\t\tr:    r,\n\t\tsize: ent.Size,\n\t\tents: r.getChunks(ent),\n\t}, nil\n}\n\nfunc (r *Reader) OpenFileWithPreReader(name string, preRead func(*TOCEntry, io.Reader) error) (*io.SectionReader, error) {\n\tfr, err := r.newFileReader(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfr.preRead = preRead\n\treturn io.NewSectionReader(fr, 0, fr.size), nil\n}\n\nfunc (r *Reader) getChunks(ent *TOCEntry) []*TOCEntry {\n\tif ents, ok := r.chunks[ent.Name]; ok {\n\t\treturn ents\n\t}\n\treturn []*TOCEntry{ent}\n}\n\ntype fileReader struct {\n\tr       *Reader\n\tsize    int64\n\tents    []*TOCEntry // 1 or more reg/chunk entries\n\tpreRead func(*TOCEntry, io.Reader) error\n}\n\nfunc (fr *fileReader) ReadAt(p []byte, off int64) (n int, err error) {\n\tif off >= fr.size {\n\t\treturn 0, io.EOF\n\t}\n\tif off < 0 {\n\t\treturn 0, errors.New(\"invalid offset\")\n\t}\n\tvar i int\n\tif len(fr.ents) > 1 {\n\t\ti = sort.Search(len(fr.ents), func(i int) bool {\n\t\t\treturn fr.ents[i].ChunkOffset >= off\n\t\t})\n\t\tif i == len(fr.ents) {\n\t\t\ti = len(fr.ents) - 1\n\t\t}\n\t}\n\tent := fr.ents[i]\n\tif ent.ChunkOffset > off {\n\t\tif i == 0 {\n\t\t\treturn 0, errors.New(\"internal error; first chunk offset is non-zero\")\n\t\t}\n\t\tent = fr.ents[i-1]\n\t}\n\n\t//  If ent is a chunk of a large file, adjust the ReadAt\n\t//  offset by the chunk's offset.\n\toff -= ent.ChunkOffset\n\n\tfinalEnt := fr.ents[len(fr.ents)-1]\n\tcompressedOff := ent.Offset\n\t// compressedBytesRemain is the number of compressed bytes in this\n\t// file remaining, over 1+ chunks.\n\tcompressedBytesRemain := finalEnt.NextOffset() - compressedOff\n\n\tsr := io.NewSectionReader(fr.r.sr, compressedOff, compressedBytesRemain)\n\n\tconst maxRead = 2 << 20\n\tvar bufSize = maxRead\n\tif compressedBytesRemain < maxRead {\n\t\tbufSize = int(compressedBytesRemain)\n\t}\n\n\tbr := bufio.NewReaderSize(sr, bufSize)\n\tif _, err := br.Peek(bufSize); err != nil {\n\t\treturn 0, fmt.Errorf(\"fileReader.ReadAt.peek: %v\", err)\n\t}\n\n\tdr, err := fr.r.decompressor.Reader(br)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"fileReader.ReadAt.decompressor.Reader: %v\", err)\n\t}\n\tdefer dr.Close()\n\n\tif fr.preRead == nil {\n\t\tif n, err := io.CopyN(io.Discard, dr, ent.InnerOffset+off); n != ent.InnerOffset+off || err != nil {\n\t\t\treturn 0, fmt.Errorf(\"discard of %d bytes != %v, %v\", ent.InnerOffset+off, n, err)\n\t\t}\n\t\treturn io.ReadFull(dr, p)\n\t}\n\n\tvar retN int\n\tvar retErr error\n\tvar found bool\n\tvar nr int64\n\tfor _, e := range fr.r.toc.Entries[ent.chunkTopIndex:] {\n\t\tif !e.isDataType() {\n\t\t\tcontinue\n\t\t}\n\t\tif e.Offset != fr.r.toc.Entries[ent.chunkTopIndex].Offset {\n\t\t\tbreak\n\t\t}\n\t\tif in, err := io.CopyN(io.Discard, dr, e.InnerOffset-nr); err != nil || in != e.InnerOffset-nr {\n\t\t\treturn 0, fmt.Errorf(\"discard of remaining %d bytes != %v, %v\", e.InnerOffset-nr, in, err)\n\t\t}\n\t\tnr = e.InnerOffset\n\t\tif e == ent {\n\t\t\tfound = true\n\t\t\tif n, err := io.CopyN(io.Discard, dr, off); n != off || err != nil {\n\t\t\t\treturn 0, fmt.Errorf(\"discard of offset %d bytes != %v, %v\", off, n, err)\n\t\t\t}\n\t\t\tretN, retErr = io.ReadFull(dr, p)\n\t\t\tnr += off + int64(retN)\n\t\t\tcontinue\n\t\t}\n\t\tcr := &countReader{r: io.LimitReader(dr, e.ChunkSize)}\n\t\tif err := fr.preRead(e, cr); err != nil {\n\t\t\treturn 0, fmt.Errorf(\"failed to pre read: %w\", err)\n\t\t}\n\t\tnr += cr.n\n\t}\n\tif !found {\n\t\treturn 0, fmt.Errorf(\"fileReader.ReadAt: target entry not found\")\n\t}\n\treturn retN, retErr\n}\n\n// A Writer writes stargz files.\n//\n// Use NewWriter to create a new Writer.\ntype Writer struct {\n\tbw       *bufio.Writer\n\tcw       *countWriter\n\ttoc      *JTOC\n\tdiffHash hash.Hash // SHA-256 of uncompressed tar\n\n\tclosed        bool\n\tgz            io.WriteCloser\n\tlastUsername  map[int]string\n\tlastGroupname map[int]string\n\tcompressor    Compressor\n\n\tuncompressedCounter *countWriteFlusher\n\n\t// ChunkSize optionally controls the maximum number of bytes\n\t// of data of a regular file that can be written in one gzip\n\t// stream before a new gzip stream is started.\n\t// Zero means to use a default, currently 4 MiB.\n\tChunkSize int\n\n\t// MinChunkSize optionally controls the minimum number of bytes\n\t// of data must be written in one gzip stream before a new gzip\n\t// NOTE: This adds a TOC property that stargz snapshotter < v0.13.0 doesn't understand.\n\tMinChunkSize int\n\n\tneedsOpenGzEntries map[string]struct{}\n}\n\n// currentCompressionWriter writes to the current w.gz field, which can\n// change throughout writing a tar entry.\n//\n// Additionally, it updates w's SHA-256 of the uncompressed bytes\n// of the tar file.\ntype currentCompressionWriter struct{ w *Writer }\n\nfunc (ccw currentCompressionWriter) Write(p []byte) (int, error) {\n\tccw.w.diffHash.Write(p)\n\tif ccw.w.gz == nil {\n\t\tif err := ccw.w.condOpenGz(); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\treturn ccw.w.gz.Write(p)\n}\n\nfunc (w *Writer) chunkSize() int {\n\tif w.ChunkSize <= 0 {\n\t\treturn 4 << 20\n\t}\n\treturn w.ChunkSize\n}\n\n// Unpack decompresses the given estargz blob and returns a ReadCloser of the tar blob.\n// TOC JSON and footer are removed.\nfunc Unpack(sr *io.SectionReader, c Decompressor) (io.ReadCloser, error) {\n\tfooterSize := c.FooterSize()\n\tif sr.Size() < footerSize {\n\t\treturn nil, fmt.Errorf(\"blob is too small; %d < %d\", sr.Size(), footerSize)\n\t}\n\tfooterOffset := sr.Size() - footerSize\n\tfooter := make([]byte, footerSize)\n\tif _, err := sr.ReadAt(footer, footerOffset); err != nil {\n\t\treturn nil, err\n\t}\n\tblobPayloadSize, _, _, err := c.ParseFooter(footer)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse footer: %w\", err)\n\t}\n\tif blobPayloadSize < 0 {\n\t\tblobPayloadSize = sr.Size()\n\t}\n\treturn c.Reader(io.LimitReader(sr, blobPayloadSize))\n}\n\n// NewWriter returns a new stargz writer (gzip-based) writing to w.\n//\n// The writer must be closed to write its trailing table of contents.\nfunc NewWriter(w io.Writer) *Writer {\n\treturn NewWriterLevel(w, gzip.BestCompression)\n}\n\n// NewWriterLevel returns a new stargz writer (gzip-based) writing to w.\n// The compression level is configurable.\n//\n// The writer must be closed to write its trailing table of contents.\nfunc NewWriterLevel(w io.Writer, compressionLevel int) *Writer {\n\treturn NewWriterWithCompressor(w, NewGzipCompressorWithLevel(compressionLevel))\n}\n\n// NewWriterWithCompressor returns a new stargz writer writing to w.\n// The compression method is configurable.\n//\n// The writer must be closed to write its trailing table of contents.\nfunc NewWriterWithCompressor(w io.Writer, c Compressor) *Writer {\n\tbw := bufio.NewWriter(w)\n\tcw := &countWriter{w: bw}\n\treturn &Writer{\n\t\tbw:                  bw,\n\t\tcw:                  cw,\n\t\ttoc:                 &JTOC{Version: 1},\n\t\tdiffHash:            sha256.New(),\n\t\tcompressor:          c,\n\t\tuncompressedCounter: &countWriteFlusher{},\n\t}\n}\n\n// Close writes the stargz's table of contents and flushes all the\n// buffers, returning any error.\nfunc (w *Writer) Close() (digest.Digest, error) {\n\tif w.closed {\n\t\treturn \"\", nil\n\t}\n\tdefer func() { w.closed = true }()\n\n\tif err := w.closeGz(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// Write the TOC index and footer.\n\ttocDigest, err := w.compressor.WriteTOCAndFooter(w.cw, w.cw.n, w.toc, w.diffHash)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif err := w.bw.Flush(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn tocDigest, nil\n}\n\nfunc (w *Writer) closeGz() error {\n\tif w.closed {\n\t\treturn errors.New(\"write on closed Writer\")\n\t}\n\tif w.gz != nil {\n\t\tif err := w.gz.Close(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tw.gz = nil\n\t}\n\treturn nil\n}\n\nfunc (w *Writer) flushGz() error {\n\tif w.closed {\n\t\treturn errors.New(\"flush on closed Writer\")\n\t}\n\tif w.gz != nil {\n\t\tif f, ok := w.gz.(interface {\n\t\t\tFlush() error\n\t\t}); ok {\n\t\t\treturn f.Flush()\n\t\t}\n\t}\n\treturn nil\n}\n\n// nameIfChanged returns name, unless it was the already the value of (*mp)[id],\n// in which case it returns the empty string.\nfunc (w *Writer) nameIfChanged(mp *map[int]string, id int, name string) string {\n\tif name == \"\" {\n\t\treturn \"\"\n\t}\n\tif *mp == nil {\n\t\t*mp = make(map[int]string)\n\t}\n\tif (*mp)[id] == name {\n\t\treturn \"\"\n\t}\n\t(*mp)[id] = name\n\treturn name\n}\n\nfunc (w *Writer) condOpenGz() (err error) {\n\tif w.gz == nil {\n\t\tw.gz, err = w.compressor.Writer(w.cw)\n\t\tif w.gz != nil {\n\t\t\tw.gz = w.uncompressedCounter.register(w.gz)\n\t\t}\n\t}\n\treturn\n}\n\n// AppendTar reads the tar or tar.gz file from r and appends\n// each of its contents to w.\n//\n// The input r can optionally be gzip compressed but the output will\n// always be compressed by the specified compressor.\nfunc (w *Writer) AppendTar(r io.Reader) error {\n\treturn w.appendTar(r, false)\n}\n\n// AppendTarLossLess reads the tar or tar.gz file from r and appends\n// each of its contents to w.\n//\n// The input r can optionally be gzip compressed but the output will\n// always be compressed by the specified compressor.\n//\n// The difference of this func with AppendTar is that this writes\n// the input tar stream into w without any modification (e.g. to header bytes).\n//\n// Note that if the input tar stream already contains TOC JSON, this returns\n// error because w cannot overwrite the TOC JSON to the one generated by w without\n// lossy modification. To avoid this error, if the input stream is known to be stargz/estargz,\n// you shoud decompress it and remove TOC JSON in advance.\nfunc (w *Writer) AppendTarLossLess(r io.Reader) error {\n\treturn w.appendTar(r, true)\n}\n\nfunc (w *Writer) appendTar(r io.Reader, lossless bool) error {\n\tvar src io.Reader\n\tbr := bufio.NewReader(r)\n\tif isGzip(br) {\n\t\tzr, _ := gzip.NewReader(br)\n\t\tsrc = zr\n\t} else {\n\t\tsrc = io.Reader(br)\n\t}\n\tdst := currentCompressionWriter{w}\n\tvar tw *tar.Writer\n\tif !lossless {\n\t\ttw = tar.NewWriter(dst) // use tar writer only when this isn't lossless mode.\n\t}\n\ttr := tar.NewReader(src)\n\tif lossless {\n\t\ttr.RawAccounting = true\n\t}\n\tprevOffset := w.cw.n\n\tvar prevOffsetUncompressed int64\n\tfor {\n\t\th, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\tif lossless {\n\t\t\t\tif remain := tr.RawBytes(); len(remain) > 0 {\n\t\t\t\t\t// Collect the remaining null bytes.\n\t\t\t\t\t// https://github.com/vbatts/tar-split/blob/80a436fd6164c557b131f7c59ed69bd81af69761/concept/main.go#L49-L53\n\t\t\t\t\tif _, err := dst.Write(remain); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error reading from source tar: tar.Reader.Next: %v\", err)\n\t\t}\n\t\tif cleanEntryName(h.Name) == TOCTarName {\n\t\t\t// It is possible for a layer to be \"stargzified\" twice during the\n\t\t\t// distribution lifecycle. So we reserve \"TOCTarName\" here to avoid\n\t\t\t// duplicated entries in the resulting layer.\n\t\t\tif lossless {\n\t\t\t\t// We cannot handle this in lossless way.\n\t\t\t\treturn fmt.Errorf(\"existing TOC JSON is not allowed; decompress layer before append\")\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\txattrs := make(map[string][]byte)\n\t\tconst xattrPAXRecordsPrefix = \"SCHILY.xattr.\"\n\t\tif h.PAXRecords != nil {\n\t\t\tfor k, v := range h.PAXRecords {\n\t\t\t\tif strings.HasPrefix(k, xattrPAXRecordsPrefix) {\n\t\t\t\t\txattrs[k[len(xattrPAXRecordsPrefix):]] = []byte(v)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tent := &TOCEntry{\n\t\t\tName:        h.Name,\n\t\t\tMode:        h.Mode,\n\t\t\tUID:         h.Uid,\n\t\t\tGID:         h.Gid,\n\t\t\tUname:       w.nameIfChanged(&w.lastUsername, h.Uid, h.Uname),\n\t\t\tGname:       w.nameIfChanged(&w.lastGroupname, h.Gid, h.Gname),\n\t\t\tModTime3339: formatModtime(h.ModTime),\n\t\t\tXattrs:      xattrs,\n\t\t}\n\t\tif err := w.condOpenGz(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif tw != nil {\n\t\t\tif err := tw.WriteHeader(h); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tif _, err := dst.Write(tr.RawBytes()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tswitch h.Typeflag {\n\t\tcase tar.TypeLink:\n\t\t\tent.Type = \"hardlink\"\n\t\t\tent.LinkName = h.Linkname\n\t\tcase tar.TypeSymlink:\n\t\t\tent.Type = \"symlink\"\n\t\t\tent.LinkName = h.Linkname\n\t\tcase tar.TypeDir:\n\t\t\tent.Type = \"dir\"\n\t\tcase tar.TypeReg:\n\t\t\tent.Type = \"reg\"\n\t\t\tent.Size = h.Size\n\t\tcase tar.TypeChar:\n\t\t\tent.Type = \"char\"\n\t\t\tent.DevMajor = int(h.Devmajor)\n\t\t\tent.DevMinor = int(h.Devminor)\n\t\tcase tar.TypeBlock:\n\t\t\tent.Type = \"block\"\n\t\t\tent.DevMajor = int(h.Devmajor)\n\t\t\tent.DevMinor = int(h.Devminor)\n\t\tcase tar.TypeFifo:\n\t\t\tent.Type = \"fifo\"\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unsupported input tar entry %q\", h.Typeflag)\n\t\t}\n\n\t\t// We need to keep a reference to the TOC entry for regular files, so that we\n\t\t// can fill the digest later.\n\t\tvar regFileEntry *TOCEntry\n\t\tvar payloadDigest digest.Digester\n\t\tif h.Typeflag == tar.TypeReg {\n\t\t\tregFileEntry = ent\n\t\t\tpayloadDigest = digest.Canonical.Digester()\n\t\t}\n\n\t\tif h.Typeflag == tar.TypeReg && ent.Size > 0 {\n\t\t\tvar written int64\n\t\t\ttotalSize := ent.Size // save it before we destroy ent\n\t\t\ttee := io.TeeReader(tr, payloadDigest.Hash())\n\t\t\tfor written < totalSize {\n\t\t\t\tchunkSize := int64(w.chunkSize())\n\t\t\t\tremain := totalSize - written\n\t\t\t\tif remain < chunkSize {\n\t\t\t\t\tchunkSize = remain\n\t\t\t\t} else {\n\t\t\t\t\tent.ChunkSize = chunkSize\n\t\t\t\t}\n\n\t\t\t\t// We flush the underlying compression writer here to correctly calculate \"w.cw.n\".\n\t\t\t\tif err := w.flushGz(); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif w.needsOpenGz(ent) || w.cw.n-prevOffset >= int64(w.MinChunkSize) {\n\t\t\t\t\tif err := w.closeGz(); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tent.Offset = w.cw.n\n\t\t\t\t\tprevOffset = ent.Offset\n\t\t\t\t\tprevOffsetUncompressed = w.uncompressedCounter.n\n\t\t\t\t} else {\n\t\t\t\t\tent.Offset = prevOffset\n\t\t\t\t\tent.InnerOffset = w.uncompressedCounter.n - prevOffsetUncompressed\n\t\t\t\t}\n\n\t\t\t\tent.ChunkOffset = written\n\t\t\t\tchunkDigest := digest.Canonical.Digester()\n\n\t\t\t\tif err := w.condOpenGz(); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tteeChunk := io.TeeReader(tee, chunkDigest.Hash())\n\t\t\t\tvar out io.Writer\n\t\t\t\tif tw != nil {\n\t\t\t\t\tout = tw\n\t\t\t\t} else {\n\t\t\t\t\tout = dst\n\t\t\t\t}\n\t\t\t\tif _, err := io.CopyN(out, teeChunk, chunkSize); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error copying %q: %v\", h.Name, err)\n\t\t\t\t}\n\t\t\t\tent.ChunkDigest = chunkDigest.Digest().String()\n\t\t\t\tw.toc.Entries = append(w.toc.Entries, ent)\n\t\t\t\twritten += chunkSize\n\t\t\t\tent = &TOCEntry{\n\t\t\t\t\tName: h.Name,\n\t\t\t\t\tType: \"chunk\",\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tw.toc.Entries = append(w.toc.Entries, ent)\n\t\t}\n\t\tif payloadDigest != nil {\n\t\t\tregFileEntry.Digest = payloadDigest.Digest().String()\n\t\t}\n\t\tif tw != nil {\n\t\t\tif err := tw.Flush(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tremainDest := io.Discard\n\tif lossless {\n\t\tremainDest = dst // Preserve the remaining bytes in lossless mode\n\t}\n\t_, err := io.Copy(remainDest, src)\n\treturn err\n}\n\nfunc (w *Writer) needsOpenGz(ent *TOCEntry) bool {\n\tif ent.Type != \"reg\" {\n\t\treturn false\n\t}\n\tif w.needsOpenGzEntries == nil {\n\t\treturn false\n\t}\n\t_, ok := w.needsOpenGzEntries[ent.Name]\n\treturn ok\n}\n\n// DiffID returns the SHA-256 of the uncompressed tar bytes.\n// It is only valid to call DiffID after Close.\nfunc (w *Writer) DiffID() string {\n\treturn fmt.Sprintf(\"sha256:%x\", w.diffHash.Sum(nil))\n}\n\nfunc maxFooterSize(blobSize int64, decompressors ...Decompressor) (res int64) {\n\tfor _, d := range decompressors {\n\t\tif s := d.FooterSize(); res < s && s <= blobSize {\n\t\t\tres = s\n\t\t}\n\t}\n\treturn\n}\n\nfunc parseTOC(d Decompressor, sr *io.SectionReader, tocOff, tocSize int64, tocBytes []byte, opts openOpts) (*Reader, error) {\n\tif tocOff < 0 {\n\t\t// This means that TOC isn't contained in the blob.\n\t\t// We pass nil reader to ParseTOC and expect that ParseTOC acquire TOC from\n\t\t// the external location.\n\t\tstart := time.Now()\n\t\ttoc, tocDgst, err := d.ParseTOC(nil)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif opts.telemetry != nil && opts.telemetry.GetTocLatency != nil {\n\t\t\topts.telemetry.GetTocLatency(start)\n\t\t}\n\t\tif opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil {\n\t\t\topts.telemetry.DeserializeTocLatency(start)\n\t\t}\n\t\treturn &Reader{\n\t\t\tsr:           sr,\n\t\t\ttoc:          toc,\n\t\t\ttocDigest:    tocDgst,\n\t\t\tdecompressor: d,\n\t\t}, nil\n\t}\n\tif len(tocBytes) > 0 {\n\t\tstart := time.Now()\n\t\ttoc, tocDgst, err := d.ParseTOC(bytes.NewReader(tocBytes))\n\t\tif err == nil {\n\t\t\tif opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil {\n\t\t\t\topts.telemetry.DeserializeTocLatency(start)\n\t\t\t}\n\t\t\treturn &Reader{\n\t\t\t\tsr:           sr,\n\t\t\t\ttoc:          toc,\n\t\t\t\ttocDigest:    tocDgst,\n\t\t\t\tdecompressor: d,\n\t\t\t}, nil\n\t\t}\n\t}\n\n\tstart := time.Now()\n\ttocBytes = make([]byte, tocSize)\n\tif _, err := sr.ReadAt(tocBytes, tocOff); err != nil {\n\t\treturn nil, fmt.Errorf(\"error reading %d byte TOC targz: %v\", len(tocBytes), err)\n\t}\n\tif opts.telemetry != nil && opts.telemetry.GetTocLatency != nil {\n\t\topts.telemetry.GetTocLatency(start)\n\t}\n\tstart = time.Now()\n\ttoc, tocDgst, err := d.ParseTOC(bytes.NewReader(tocBytes))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif opts.telemetry != nil && opts.telemetry.DeserializeTocLatency != nil {\n\t\topts.telemetry.DeserializeTocLatency(start)\n\t}\n\treturn &Reader{\n\t\tsr:           sr,\n\t\ttoc:          toc,\n\t\ttocDigest:    tocDgst,\n\t\tdecompressor: d,\n\t}, nil\n}\n\nfunc formatModtime(t time.Time) string {\n\tif t.IsZero() || t.Unix() == 0 {\n\t\treturn \"\"\n\t}\n\treturn t.UTC().Round(time.Second).Format(time.RFC3339)\n}\n\nfunc cleanEntryName(name string) string {\n\t// Use path.Clean to consistently deal with path separators across platforms.\n\treturn strings.TrimPrefix(path.Clean(\"/\"+name), \"/\")\n}\n\n// countWriter counts how many bytes have been written to its wrapped\n// io.Writer.\ntype countWriter struct {\n\tw io.Writer\n\tn int64\n}\n\nfunc (cw *countWriter) Write(p []byte) (n int, err error) {\n\tn, err = cw.w.Write(p)\n\tcw.n += int64(n)\n\treturn\n}\n\ntype countWriteFlusher struct {\n\tio.WriteCloser\n\tn int64\n}\n\nfunc (wc *countWriteFlusher) register(w io.WriteCloser) io.WriteCloser {\n\twc.WriteCloser = w\n\treturn wc\n}\n\nfunc (wc *countWriteFlusher) Write(p []byte) (n int, err error) {\n\tn, err = wc.WriteCloser.Write(p)\n\twc.n += int64(n)\n\treturn\n}\n\nfunc (wc *countWriteFlusher) Flush() error {\n\tif f, ok := wc.WriteCloser.(interface {\n\t\tFlush() error\n\t}); ok {\n\t\treturn f.Flush()\n\t}\n\treturn nil\n}\n\nfunc (wc *countWriteFlusher) Close() error {\n\terr := wc.WriteCloser.Close()\n\twc.WriteCloser = nil\n\treturn err\n}\n\n// isGzip reports whether br is positioned right before an upcoming gzip stream.\n// It does not consume any bytes from br.\nfunc isGzip(br *bufio.Reader) bool {\n\tconst (\n\t\tgzipID1     = 0x1f\n\t\tgzipID2     = 0x8b\n\t\tgzipDeflate = 8\n\t)\n\tpeek, _ := br.Peek(3)\n\treturn len(peek) >= 3 && peek[0] == gzipID1 && peek[1] == gzipID2 && peek[2] == gzipDeflate\n}\n\nfunc positive(n int64) int64 {\n\tif n < 0 {\n\t\treturn 0\n\t}\n\treturn n\n}\n\ntype countReader struct {\n\tr io.Reader\n\tn int64\n}\n\nfunc (cr *countReader) Read(p []byte) (n int, err error) {\n\tn, err = cr.r.Read(p)\n\tcr.n += int64(n)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\n/*\n   Copyright 2019 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\npackage estargz\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"encoding/binary\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"strconv\"\n\n\tdigest \"github.com/opencontainers/go-digest\"\n)\n\ntype gzipCompression struct {\n\t*GzipCompressor\n\t*GzipDecompressor\n}\n\nfunc newGzipCompressionWithLevel(level int) Compression {\n\treturn &gzipCompression{\n\t\t&GzipCompressor{level},\n\t\t&GzipDecompressor{},\n\t}\n}\n\nfunc NewGzipCompressor() *GzipCompressor {\n\treturn &GzipCompressor{gzip.BestCompression}\n}\n\nfunc NewGzipCompressorWithLevel(level int) *GzipCompressor {\n\treturn &GzipCompressor{level}\n}\n\ntype GzipCompressor struct {\n\tcompressionLevel int\n}\n\nfunc (gc *GzipCompressor) Writer(w io.Writer) (WriteFlushCloser, error) {\n\treturn gzip.NewWriterLevel(w, gc.compressionLevel)\n}\n\nfunc (gc *GzipCompressor) WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (digest.Digest, error) {\n\ttocJSON, err := json.MarshalIndent(toc, \"\", \"\\t\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tgz, _ := gzip.NewWriterLevel(w, gc.compressionLevel)\n\tgw := io.Writer(gz)\n\tif diffHash != nil {\n\t\tgw = io.MultiWriter(gz, diffHash)\n\t}\n\ttw := tar.NewWriter(gw)\n\tif err := tw.WriteHeader(&tar.Header{\n\t\tTypeflag: tar.TypeReg,\n\t\tName:     TOCTarName,\n\t\tSize:     int64(len(tocJSON)),\n\t}); err != nil {\n\t\treturn \"\", err\n\t}\n\tif _, err := tw.Write(tocJSON); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif err := tw.Close(); err != nil {\n\t\treturn \"\", err\n\t}\n\tif err := gz.Close(); err != nil {\n\t\treturn \"\", err\n\t}\n\tif _, err := w.Write(gzipFooterBytes(off)); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn digest.FromBytes(tocJSON), nil\n}\n\n// gzipFooterBytes returns the 51 bytes footer.\nfunc gzipFooterBytes(tocOff int64) []byte {\n\tbuf := bytes.NewBuffer(make([]byte, 0, FooterSize))\n\tgz, _ := gzip.NewWriterLevel(buf, gzip.NoCompression) // MUST be NoCompression to keep 51 bytes\n\n\t// Extra header indicating the offset of TOCJSON\n\t// https://tools.ietf.org/html/rfc1952#section-2.3.1.1\n\theader := make([]byte, 4)\n\theader[0], header[1] = 'S', 'G'\n\tsubfield := fmt.Sprintf(\"%016xSTARGZ\", tocOff)\n\tbinary.LittleEndian.PutUint16(header[2:4], uint16(len(subfield))) // little-endian per RFC1952\n\tgz.Header.Extra = append(header, []byte(subfield)...)\n\tgz.Close()\n\tif buf.Len() != FooterSize {\n\t\tpanic(fmt.Sprintf(\"footer buffer = %d, not %d\", buf.Len(), FooterSize))\n\t}\n\treturn buf.Bytes()\n}\n\ntype GzipDecompressor struct{}\n\nfunc (gz *GzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) {\n\treturn gzip.NewReader(r)\n}\n\nfunc (gz *GzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) {\n\treturn parseTOCEStargz(r)\n}\n\nfunc (gz *GzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) {\n\tif len(p) != FooterSize {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid length %d cannot be parsed\", len(p))\n\t}\n\tzr, err := gzip.NewReader(bytes.NewReader(p))\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\tdefer zr.Close()\n\textra := zr.Header.Extra\n\tsi1, si2, subfieldlen, subfield := extra[0], extra[1], extra[2:4], extra[4:]\n\tif si1 != 'S' || si2 != 'G' {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid subfield IDs: %q, %q; want E, S\", si1, si2)\n\t}\n\tif slen := binary.LittleEndian.Uint16(subfieldlen); slen != uint16(16+len(\"STARGZ\")) {\n\t\treturn 0, 0, 0, fmt.Errorf(\"invalid length of subfield %d; want %d\", slen, 16+len(\"STARGZ\"))\n\t}\n\tif string(subfield[16:]) != \"STARGZ\" {\n\t\treturn 0, 0, 0, fmt.Errorf(\"STARGZ magic string must be included in the footer subfield\")\n\t}\n\ttocOffset, err = strconv.ParseInt(string(subfield[:16]), 16, 64)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"legacy: failed to parse toc offset: %w\", err)\n\t}\n\treturn tocOffset, tocOffset, 0, nil\n}\n\nfunc (gz *GzipDecompressor) FooterSize() int64 {\n\treturn FooterSize\n}\n\nfunc (gz *GzipDecompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) {\n\treturn decompressTOCEStargz(r)\n}\n\ntype LegacyGzipDecompressor struct{}\n\nfunc (gz *LegacyGzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) {\n\treturn gzip.NewReader(r)\n}\n\nfunc (gz *LegacyGzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) {\n\treturn parseTOCEStargz(r)\n}\n\nfunc (gz *LegacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) {\n\tif len(p) != legacyFooterSize {\n\t\treturn 0, 0, 0, fmt.Errorf(\"legacy: invalid length %d cannot be parsed\", len(p))\n\t}\n\tzr, err := gzip.NewReader(bytes.NewReader(p))\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"legacy: failed to get footer gzip reader: %w\", err)\n\t}\n\tdefer zr.Close()\n\textra := zr.Header.Extra\n\tif len(extra) != 16+len(\"STARGZ\") {\n\t\treturn 0, 0, 0, fmt.Errorf(\"legacy: invalid stargz's extra field size\")\n\t}\n\tif string(extra[16:]) != \"STARGZ\" {\n\t\treturn 0, 0, 0, fmt.Errorf(\"legacy: magic string STARGZ not found\")\n\t}\n\ttocOffset, err = strconv.ParseInt(string(extra[:16]), 16, 64)\n\tif err != nil {\n\t\treturn 0, 0, 0, fmt.Errorf(\"legacy: failed to parse toc offset: %w\", err)\n\t}\n\treturn tocOffset, tocOffset, 0, nil\n}\n\nfunc (gz *LegacyGzipDecompressor) FooterSize() int64 {\n\treturn legacyFooterSize\n}\n\nfunc (gz *LegacyGzipDecompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) {\n\treturn decompressTOCEStargz(r)\n}\n\nfunc parseTOCEStargz(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) {\n\ttr, err := decompressTOCEStargz(r)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tdgstr := digest.Canonical.Digester()\n\ttoc = new(JTOC)\n\tif err := json.NewDecoder(io.TeeReader(tr, dgstr.Hash())).Decode(&toc); err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"error decoding TOC JSON: %v\", err)\n\t}\n\tif err := tr.Close(); err != nil {\n\t\treturn nil, \"\", err\n\t}\n\treturn toc, dgstr.Digest(), nil\n}\n\nfunc decompressTOCEStargz(r io.Reader) (tocJSON io.ReadCloser, err error) {\n\tzr, err := gzip.NewReader(r)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed TOC gzip header: %v\", err)\n\t}\n\tzr.Multistream(false)\n\ttr := tar.NewReader(zr)\n\th, err := tr.Next()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to find tar header in TOC gzip stream: %v\", err)\n\t}\n\tif h.Name != TOCTarName {\n\t\treturn nil, fmt.Errorf(\"TOC tar entry had name %q; expected %q\", h.Name, TOCTarName)\n\t}\n\treturn readCloser{tr, zr.Close}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/stargz-snapshotter/estargz/testutil.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\n/*\n   Copyright 2019 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\npackage estargz\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"crypto/sha256\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/rand\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/containerd/stargz-snapshotter/estargz/errorutil\"\n\t\"github.com/klauspost/compress/zstd\"\n\tdigest \"github.com/opencontainers/go-digest\"\n)\n\nfunc init() {\n\trand.Seed(time.Now().UnixNano())\n}\n\n// TestingController is Compression with some helper methods necessary for testing.\ntype TestingController interface {\n\tCompression\n\tTestStreams(t *testing.T, b []byte, streams []int64)\n\tDiffIDOf(*testing.T, []byte) string\n\tString() string\n}\n\n// CompressionTestSuite tests this pkg with controllers can build valid eStargz blobs and parse them.\nfunc CompressionTestSuite(t *testing.T, controllers ...TestingControllerFactory) {\n\tt.Run(\"testBuild\", func(t *testing.T) { t.Parallel(); testBuild(t, controllers...) })\n\tt.Run(\"testDigestAndVerify\", func(t *testing.T) { t.Parallel(); testDigestAndVerify(t, controllers...) })\n\tt.Run(\"testWriteAndOpen\", func(t *testing.T) { t.Parallel(); testWriteAndOpen(t, controllers...) })\n}\n\ntype TestingControllerFactory func() TestingController\n\nconst (\n\tuncompressedType int = iota\n\tgzipType\n\tzstdType\n)\n\nvar srcCompressions = []int{\n\tuncompressedType,\n\tgzipType,\n\tzstdType,\n}\n\nvar allowedPrefix = [4]string{\"\", \"./\", \"/\", \"../\"}\n\n// testBuild tests the resulting stargz blob built by this pkg has the same\n// contents as the normal stargz blob.\nfunc testBuild(t *testing.T, controllers ...TestingControllerFactory) {\n\ttests := []struct {\n\t\tname         string\n\t\tchunkSize    int\n\t\tminChunkSize []int\n\t\tin           []tarEntry\n\t}{\n\t\t{\n\t\t\tname:      \"regfiles and directories\",\n\t\t\tchunkSize: 4,\n\t\t\tin: tarOf(\n\t\t\t\tfile(\"foo\", \"test1\"),\n\t\t\t\tdir(\"foo2/\"),\n\t\t\t\tfile(\"foo2/bar\", \"test2\", xAttr(map[string]string{\"test\": \"sample\"})),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname:      \"empty files\",\n\t\t\tchunkSize: 4,\n\t\t\tin: tarOf(\n\t\t\t\tfile(\"foo\", \"tttttt\"),\n\t\t\t\tfile(\"foo_empty\", \"\"),\n\t\t\t\tfile(\"foo2\", \"tttttt\"),\n\t\t\t\tfile(\"foo_empty2\", \"\"),\n\t\t\t\tfile(\"foo3\", \"tttttt\"),\n\t\t\t\tfile(\"foo_empty3\", \"\"),\n\t\t\t\tfile(\"foo4\", \"tttttt\"),\n\t\t\t\tfile(\"foo_empty4\", \"\"),\n\t\t\t\tfile(\"foo5\", \"tttttt\"),\n\t\t\t\tfile(\"foo_empty5\", \"\"),\n\t\t\t\tfile(\"foo6\", \"tttttt\"),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname:         \"various files\",\n\t\t\tchunkSize:    4,\n\t\t\tminChunkSize: []int{0, 64000},\n\t\t\tin: tarOf(\n\t\t\t\tfile(\"baz.txt\", \"bazbazbazbazbazbazbaz\"),\n\t\t\t\tfile(\"foo1.txt\", \"a\"),\n\t\t\t\tfile(\"bar/foo2.txt\", \"b\"),\n\t\t\t\tfile(\"foo3.txt\", \"c\"),\n\t\t\t\tsymlink(\"barlink\", \"test/bar.txt\"),\n\t\t\t\tdir(\"test/\"),\n\t\t\t\tdir(\"dev/\"),\n\t\t\t\tblockdev(\"dev/testblock\", 3, 4),\n\t\t\t\tfifo(\"dev/testfifo\"),\n\t\t\t\tchardev(\"dev/testchar1\", 5, 6),\n\t\t\t\tfile(\"test/bar.txt\", \"testbartestbar\", xAttr(map[string]string{\"test2\": \"sample2\"})),\n\t\t\t\tdir(\"test2/\"),\n\t\t\t\tlink(\"test2/bazlink\", \"baz.txt\"),\n\t\t\t\tchardev(\"dev/testchar2\", 1, 2),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname:      \"no contents\",\n\t\t\tchunkSize: 4,\n\t\t\tin: tarOf(\n\t\t\t\tfile(\"baz.txt\", \"\"),\n\t\t\t\tsymlink(\"barlink\", \"test/bar.txt\"),\n\t\t\t\tdir(\"test/\"),\n\t\t\t\tdir(\"dev/\"),\n\t\t\t\tblockdev(\"dev/testblock\", 3, 4),\n\t\t\t\tfifo(\"dev/testfifo\"),\n\t\t\t\tchardev(\"dev/testchar1\", 5, 6),\n\t\t\t\tfile(\"test/bar.txt\", \"\", xAttr(map[string]string{\"test2\": \"sample2\"})),\n\t\t\t\tdir(\"test2/\"),\n\t\t\t\tlink(\"test2/bazlink\", \"baz.txt\"),\n\t\t\t\tchardev(\"dev/testchar2\", 1, 2),\n\t\t\t),\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tif len(tt.minChunkSize) == 0 {\n\t\t\ttt.minChunkSize = []int{0}\n\t\t}\n\t\tfor _, srcCompression := range srcCompressions {\n\t\t\tsrcCompression := srcCompression\n\t\t\tfor _, newCL := range controllers {\n\t\t\t\tnewCL := newCL\n\t\t\t\tfor _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} {\n\t\t\t\t\tsrcTarFormat := srcTarFormat\n\t\t\t\t\tfor _, prefix := range allowedPrefix {\n\t\t\t\t\t\tprefix := prefix\n\t\t\t\t\t\tfor _, minChunkSize := range tt.minChunkSize {\n\t\t\t\t\t\t\tminChunkSize := minChunkSize\n\t\t\t\t\t\t\tt.Run(tt.name+\"-\"+fmt.Sprintf(\"compression=%v,prefix=%q,src=%d,format=%s,minChunkSize=%d\", newCL(), prefix, srcCompression, srcTarFormat, minChunkSize), func(t *testing.T) {\n\t\t\t\t\t\t\t\ttarBlob := buildTar(t, tt.in, prefix, srcTarFormat)\n\t\t\t\t\t\t\t\t// Test divideEntries()\n\t\t\t\t\t\t\t\tentries, err := sortEntries(tarBlob, nil, nil) // identical order\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to parse tar: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tvar merged []*entry\n\t\t\t\t\t\t\t\tfor _, part := range divideEntries(entries, 4) {\n\t\t\t\t\t\t\t\t\tmerged = append(merged, part...)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif !reflect.DeepEqual(entries, merged) {\n\t\t\t\t\t\t\t\t\tfor _, e := range entries {\n\t\t\t\t\t\t\t\t\t\tt.Logf(\"Original: %v\", e.header)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tfor _, e := range merged {\n\t\t\t\t\t\t\t\t\t\tt.Logf(\"Merged: %v\", e.header)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tt.Errorf(\"divided entries couldn't be merged\")\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Prepare sample data\n\t\t\t\t\t\t\t\tcl1 := newCL()\n\t\t\t\t\t\t\t\twantBuf := new(bytes.Buffer)\n\t\t\t\t\t\t\t\tsw := NewWriterWithCompressor(wantBuf, cl1)\n\t\t\t\t\t\t\t\tsw.MinChunkSize = minChunkSize\n\t\t\t\t\t\t\t\tsw.ChunkSize = tt.chunkSize\n\t\t\t\t\t\t\t\tif err := sw.AppendTar(tarBlob); err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to append tar to want stargz: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif _, err := sw.Close(); err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to prepare want stargz: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twantData := wantBuf.Bytes()\n\t\t\t\t\t\t\t\twant, err := Open(io.NewSectionReader(\n\t\t\t\t\t\t\t\t\tbytes.NewReader(wantData), 0, int64(len(wantData))),\n\t\t\t\t\t\t\t\t\tWithDecompressors(cl1),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to parse the want stargz: %v\", err)\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Prepare testing data\n\t\t\t\t\t\t\t\tvar opts []Option\n\t\t\t\t\t\t\t\tif minChunkSize > 0 {\n\t\t\t\t\t\t\t\t\topts = append(opts, WithMinChunkSize(minChunkSize))\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcl2 := newCL()\n\t\t\t\t\t\t\t\trc, err := Build(compressBlob(t, tarBlob, srcCompression),\n\t\t\t\t\t\t\t\t\tappend(opts, WithChunkSize(tt.chunkSize), WithCompression(cl2))...)\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to build stargz: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdefer rc.Close()\n\t\t\t\t\t\t\t\tgotBuf := new(bytes.Buffer)\n\t\t\t\t\t\t\t\tif _, err := io.Copy(gotBuf, rc); err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to copy built stargz blob: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tgotData := gotBuf.Bytes()\n\t\t\t\t\t\t\t\tgot, err := Open(io.NewSectionReader(\n\t\t\t\t\t\t\t\t\tbytes.NewReader(gotBuf.Bytes()), 0, int64(len(gotData))),\n\t\t\t\t\t\t\t\t\tWithDecompressors(cl2),\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to parse the got stargz: %v\", err)\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Check DiffID is properly calculated\n\t\t\t\t\t\t\t\trc.Close()\n\t\t\t\t\t\t\t\tdiffID := rc.DiffID()\n\t\t\t\t\t\t\t\twantDiffID := cl2.DiffIDOf(t, gotData)\n\t\t\t\t\t\t\t\tif diffID.String() != wantDiffID {\n\t\t\t\t\t\t\t\t\tt.Errorf(\"DiffID = %q; want %q\", diffID, wantDiffID)\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Compare as stargz\n\t\t\t\t\t\t\t\tif !isSameVersion(t, cl1, wantData, cl2, gotData) {\n\t\t\t\t\t\t\t\t\tt.Errorf(\"built stargz hasn't same json\")\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif !isSameEntries(t, want, got) {\n\t\t\t\t\t\t\t\t\tt.Errorf(\"built stargz isn't same as the original\")\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Compare as tar.gz\n\t\t\t\t\t\t\t\tif !isSameTarGz(t, cl1, wantData, cl2, gotData) {\n\t\t\t\t\t\t\t\t\tt.Errorf(\"built stargz isn't same tar.gz\")\n\t\t\t\t\t\t\t\t\treturn\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}\n\t}\n}\n\nfunc isSameTarGz(t *testing.T, cla TestingController, a []byte, clb TestingController, b []byte) bool {\n\taGz, err := cla.Reader(bytes.NewReader(a))\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read A\")\n\t}\n\tdefer aGz.Close()\n\tbGz, err := clb.Reader(bytes.NewReader(b))\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read B\")\n\t}\n\tdefer bGz.Close()\n\n\t// Same as tar's Next() method but ignores landmarks and TOCJSON file\n\tnext := func(r *tar.Reader) (h *tar.Header, err error) {\n\t\tfor {\n\t\t\tif h, err = r.Next(); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif h.Name != PrefetchLandmark &&\n\t\t\t\th.Name != NoPrefetchLandmark &&\n\t\t\t\th.Name != TOCTarName {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\taTar := tar.NewReader(aGz)\n\tbTar := tar.NewReader(bGz)\n\tfor {\n\t\t// Fetch and parse next header.\n\t\taH, aErr := next(aTar)\n\t\tbH, bErr := next(bTar)\n\t\tif aErr != nil || bErr != nil {\n\t\t\tif aErr == io.EOF && bErr == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tt.Fatalf(\"Failed to parse tar file: A: %v, B: %v\", aErr, bErr)\n\t\t}\n\t\tif !reflect.DeepEqual(aH, bH) {\n\t\t\tt.Logf(\"different header (A = %v; B = %v)\", aH, bH)\n\t\t\treturn false\n\n\t\t}\n\t\taFile, err := io.ReadAll(aTar)\n\t\tif err != nil {\n\t\t\tt.Fatal(\"failed to read tar payload of A\")\n\t\t}\n\t\tbFile, err := io.ReadAll(bTar)\n\t\tif err != nil {\n\t\t\tt.Fatal(\"failed to read tar payload of B\")\n\t\t}\n\t\tif !bytes.Equal(aFile, bFile) {\n\t\t\tt.Logf(\"different tar payload (A = %q; B = %q)\", string(a), string(b))\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc isSameVersion(t *testing.T, cla TestingController, a []byte, clb TestingController, b []byte) bool {\n\taJTOC, _, err := parseStargz(io.NewSectionReader(bytes.NewReader(a), 0, int64(len(a))), cla)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to parse A: %v\", err)\n\t}\n\tbJTOC, _, err := parseStargz(io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), clb)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to parse B: %v\", err)\n\t}\n\tt.Logf(\"A: TOCJSON: %v\", dumpTOCJSON(t, aJTOC))\n\tt.Logf(\"B: TOCJSON: %v\", dumpTOCJSON(t, bJTOC))\n\treturn aJTOC.Version == bJTOC.Version\n}\n\nfunc isSameEntries(t *testing.T, a, b *Reader) bool {\n\taroot, ok := a.Lookup(\"\")\n\tif !ok {\n\t\tt.Fatalf(\"failed to get root of A\")\n\t}\n\tbroot, ok := b.Lookup(\"\")\n\tif !ok {\n\t\tt.Fatalf(\"failed to get root of B\")\n\t}\n\taEntry := stargzEntry{aroot, a}\n\tbEntry := stargzEntry{broot, b}\n\treturn contains(t, aEntry, bEntry) && contains(t, bEntry, aEntry)\n}\n\nfunc compressBlob(t *testing.T, src *io.SectionReader, srcCompression int) *io.SectionReader {\n\tbuf := new(bytes.Buffer)\n\tvar w io.WriteCloser\n\tvar err error\n\tif srcCompression == gzipType {\n\t\tw = gzip.NewWriter(buf)\n\t} else if srcCompression == zstdType {\n\t\tw, err = zstd.NewWriter(buf)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to init zstd writer: %v\", err)\n\t\t}\n\t} else {\n\t\treturn src\n\t}\n\tsrc.Seek(0, io.SeekStart)\n\tif _, err := io.Copy(w, src); err != nil {\n\t\tt.Fatalf(\"failed to compress source\")\n\t}\n\tif err := w.Close(); err != nil {\n\t\tt.Fatalf(\"failed to finalize compress source\")\n\t}\n\tdata := buf.Bytes()\n\treturn io.NewSectionReader(bytes.NewReader(data), 0, int64(len(data)))\n\n}\n\ntype stargzEntry struct {\n\te *TOCEntry\n\tr *Reader\n}\n\n// contains checks if all child entries in \"b\" are also contained in \"a\".\n// This function also checks if the files/chunks contain the same contents among \"a\" and \"b\".\nfunc contains(t *testing.T, a, b stargzEntry) bool {\n\tae, ar := a.e, a.r\n\tbe, br := b.e, b.r\n\tt.Logf(\"Comparing: %q vs %q\", ae.Name, be.Name)\n\tif !equalEntry(ae, be) {\n\t\tt.Logf(\"%q != %q: entry: a: %v, b: %v\", ae.Name, be.Name, ae, be)\n\t\treturn false\n\t}\n\tif ae.Type == \"dir\" {\n\t\tt.Logf(\"Directory: %q vs %q: %v vs %v\", ae.Name, be.Name,\n\t\t\tallChildrenName(ae), allChildrenName(be))\n\t\tiscontain := true\n\t\tae.ForeachChild(func(aBaseName string, aChild *TOCEntry) bool {\n\t\t\t// Walk through all files on this stargz file.\n\n\t\t\tif aChild.Name == PrefetchLandmark ||\n\t\t\t\taChild.Name == NoPrefetchLandmark {\n\t\t\t\treturn true // Ignore landmarks\n\t\t\t}\n\n\t\t\t// Ignore a TOCEntry of \"./\" (formated as \"\" by stargz lib) on root directory\n\t\t\t// because this points to the root directory itself.\n\t\t\tif aChild.Name == \"\" && ae.Name == \"\" {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tbChild, ok := be.LookupChild(aBaseName)\n\t\t\tif !ok {\n\t\t\t\tt.Logf(\"%q (base: %q): not found in b: %v\",\n\t\t\t\t\tae.Name, aBaseName, allChildrenName(be))\n\t\t\t\tiscontain = false\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tchildcontain := contains(t, stargzEntry{aChild, a.r}, stargzEntry{bChild, b.r})\n\t\t\tif !childcontain {\n\t\t\t\tt.Logf(\"%q != %q: non-equal dir\", ae.Name, be.Name)\n\t\t\t\tiscontain = false\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t\treturn iscontain\n\t} else if ae.Type == \"reg\" {\n\t\taf, err := ar.OpenFile(ae.Name)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to open file %q on A: %v\", ae.Name, err)\n\t\t}\n\t\tbf, err := br.OpenFile(be.Name)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to open file %q on B: %v\", be.Name, err)\n\t\t}\n\n\t\tvar nr int64\n\t\tfor nr < ae.Size {\n\t\t\tabytes, anext, aok := readOffset(t, af, nr, a)\n\t\t\tbbytes, bnext, bok := readOffset(t, bf, nr, b)\n\t\t\tif !aok && !bok {\n\t\t\t\tbreak\n\t\t\t} else if !(aok && bok) || anext != bnext {\n\t\t\t\tt.Logf(\"%q != %q (offset=%d): chunk existence a=%v vs b=%v, anext=%v vs bnext=%v\",\n\t\t\t\t\tae.Name, be.Name, nr, aok, bok, anext, bnext)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tnr = anext\n\t\t\tif !bytes.Equal(abytes, bbytes) {\n\t\t\t\tt.Logf(\"%q != %q: different contents %v vs %v\",\n\t\t\t\t\tae.Name, be.Name, string(abytes), string(bbytes))\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\n\treturn true\n}\n\nfunc allChildrenName(e *TOCEntry) (children []string) {\n\te.ForeachChild(func(baseName string, _ *TOCEntry) bool {\n\t\tchildren = append(children, baseName)\n\t\treturn true\n\t})\n\treturn\n}\n\nfunc equalEntry(a, b *TOCEntry) bool {\n\t// Here, we selectively compare fileds that we are interested in.\n\treturn a.Name == b.Name &&\n\t\ta.Type == b.Type &&\n\t\ta.Size == b.Size &&\n\t\ta.ModTime3339 == b.ModTime3339 &&\n\t\ta.Stat().ModTime().Equal(b.Stat().ModTime()) && // modTime     time.Time\n\t\ta.LinkName == b.LinkName &&\n\t\ta.Mode == b.Mode &&\n\t\ta.UID == b.UID &&\n\t\ta.GID == b.GID &&\n\t\ta.Uname == b.Uname &&\n\t\ta.Gname == b.Gname &&\n\t\t(a.Offset >= 0) == (b.Offset >= 0) &&\n\t\t(a.NextOffset() > 0) == (b.NextOffset() > 0) &&\n\t\ta.DevMajor == b.DevMajor &&\n\t\ta.DevMinor == b.DevMinor &&\n\t\ta.NumLink == b.NumLink &&\n\t\treflect.DeepEqual(a.Xattrs, b.Xattrs) &&\n\t\t// chunk-related infomations aren't compared in this function.\n\t\t// ChunkOffset int64 `json:\"chunkOffset,omitempty\"`\n\t\t// ChunkSize   int64 `json:\"chunkSize,omitempty\"`\n\t\t// children map[string]*TOCEntry\n\t\ta.Digest == b.Digest\n}\n\nfunc readOffset(t *testing.T, r *io.SectionReader, offset int64, e stargzEntry) ([]byte, int64, bool) {\n\tce, ok := e.r.ChunkEntryForOffset(e.e.Name, offset)\n\tif !ok {\n\t\treturn nil, 0, false\n\t}\n\tdata := make([]byte, ce.ChunkSize)\n\tt.Logf(\"Offset: %v, NextOffset: %v\", ce.Offset, ce.NextOffset())\n\tn, err := r.ReadAt(data, ce.ChunkOffset)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to read file payload of %q (offset:%d,size:%d): %v\",\n\t\t\te.e.Name, ce.ChunkOffset, ce.ChunkSize, err)\n\t}\n\tif int64(n) != ce.ChunkSize {\n\t\tt.Fatalf(\"unexpected copied data size %d; want %d\",\n\t\t\tn, ce.ChunkSize)\n\t}\n\treturn data[:n], offset + ce.ChunkSize, true\n}\n\nfunc dumpTOCJSON(t *testing.T, tocJSON *JTOC) string {\n\tjtocData, err := json.Marshal(*tocJSON)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to marshal TOC JSON: %v\", err)\n\t}\n\tbuf := new(bytes.Buffer)\n\tif _, err := io.Copy(buf, bytes.NewReader(jtocData)); err != nil {\n\t\tt.Fatalf(\"failed to read toc json blob: %v\", err)\n\t}\n\treturn buf.String()\n}\n\nconst chunkSize = 3\n\n// type check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, compressionLevel int)\ntype check func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory)\n\n// testDigestAndVerify runs specified checks against sample stargz blobs.\nfunc testDigestAndVerify(t *testing.T, controllers ...TestingControllerFactory) {\n\ttests := []struct {\n\t\tname         string\n\t\ttarInit      func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry)\n\t\tchecks       []check\n\t\tminChunkSize []int\n\t}{\n\t\t{\n\t\t\tname: \"no-regfile\",\n\t\t\ttarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) {\n\t\t\t\treturn tarOf(\n\t\t\t\t\tdir(\"test/\"),\n\t\t\t\t)\n\t\t\t},\n\t\t\tchecks: []check{\n\t\t\t\tcheckStargzTOC,\n\t\t\t\tcheckVerifyTOC,\n\t\t\t\tcheckVerifyInvalidStargzFail(buildTar(t, tarOf(\n\t\t\t\t\tdir(\"test2/\"), // modified\n\t\t\t\t), allowedPrefix[0])),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"small-files\",\n\t\t\ttarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) {\n\t\t\t\treturn tarOf(\n\t\t\t\t\tregDigest(t, \"baz.txt\", \"\", dgstMap),\n\t\t\t\t\tregDigest(t, \"foo.txt\", \"a\", dgstMap),\n\t\t\t\t\tdir(\"test/\"),\n\t\t\t\t\tregDigest(t, \"test/bar.txt\", \"bbb\", dgstMap),\n\t\t\t\t)\n\t\t\t},\n\t\t\tminChunkSize: []int{0, 64000},\n\t\t\tchecks: []check{\n\t\t\t\tcheckStargzTOC,\n\t\t\t\tcheckVerifyTOC,\n\t\t\t\tcheckVerifyInvalidStargzFail(buildTar(t, tarOf(\n\t\t\t\t\tfile(\"baz.txt\", \"\"),\n\t\t\t\t\tfile(\"foo.txt\", \"M\"), // modified\n\t\t\t\t\tdir(\"test/\"),\n\t\t\t\t\tfile(\"test/bar.txt\", \"bbb\"),\n\t\t\t\t), allowedPrefix[0])),\n\t\t\t\t// checkVerifyInvalidTOCEntryFail(\"foo.txt\"), // TODO\n\t\t\t\tcheckVerifyBrokenContentFail(\"foo.txt\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"big-files\",\n\t\t\ttarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) {\n\t\t\t\treturn tarOf(\n\t\t\t\t\tregDigest(t, \"baz.txt\", \"bazbazbazbazbazbazbaz\", dgstMap),\n\t\t\t\t\tregDigest(t, \"foo.txt\", \"a\", dgstMap),\n\t\t\t\t\tdir(\"test/\"),\n\t\t\t\t\tregDigest(t, \"test/bar.txt\", \"testbartestbar\", dgstMap),\n\t\t\t\t)\n\t\t\t},\n\t\t\tchecks: []check{\n\t\t\t\tcheckStargzTOC,\n\t\t\t\tcheckVerifyTOC,\n\t\t\t\tcheckVerifyInvalidStargzFail(buildTar(t, tarOf(\n\t\t\t\t\tfile(\"baz.txt\", \"bazbazbazMMMbazbazbaz\"), // modified\n\t\t\t\t\tfile(\"foo.txt\", \"a\"),\n\t\t\t\t\tdir(\"test/\"),\n\t\t\t\t\tfile(\"test/bar.txt\", \"testbartestbar\"),\n\t\t\t\t), allowedPrefix[0])),\n\t\t\t\tcheckVerifyInvalidTOCEntryFail(\"test/bar.txt\"),\n\t\t\t\tcheckVerifyBrokenContentFail(\"test/bar.txt\"),\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:         \"with-non-regfiles\",\n\t\t\tminChunkSize: []int{0, 64000},\n\t\t\ttarInit: func(t *testing.T, dgstMap map[string]digest.Digest) (blob []tarEntry) {\n\t\t\t\treturn tarOf(\n\t\t\t\t\tregDigest(t, \"baz.txt\", \"bazbazbazbazbazbazbaz\", dgstMap),\n\t\t\t\t\tregDigest(t, \"foo.txt\", \"a\", dgstMap),\n\t\t\t\t\tregDigest(t, \"bar/foo2.txt\", \"b\", dgstMap),\n\t\t\t\t\tregDigest(t, \"foo3.txt\", \"c\", dgstMap),\n\t\t\t\t\tsymlink(\"barlink\", \"test/bar.txt\"),\n\t\t\t\t\tdir(\"test/\"),\n\t\t\t\t\tregDigest(t, \"test/bar.txt\", \"testbartestbar\", dgstMap),\n\t\t\t\t\tdir(\"test2/\"),\n\t\t\t\t\tlink(\"test2/bazlink\", \"baz.txt\"),\n\t\t\t\t)\n\t\t\t},\n\t\t\tchecks: []check{\n\t\t\t\tcheckStargzTOC,\n\t\t\t\tcheckVerifyTOC,\n\t\t\t\tcheckVerifyInvalidStargzFail(buildTar(t, tarOf(\n\t\t\t\t\tfile(\"baz.txt\", \"bazbazbazbazbazbazbaz\"),\n\t\t\t\t\tfile(\"foo.txt\", \"a\"),\n\t\t\t\t\tfile(\"bar/foo2.txt\", \"b\"),\n\t\t\t\t\tfile(\"foo3.txt\", \"c\"),\n\t\t\t\t\tsymlink(\"barlink\", \"test/bar.txt\"),\n\t\t\t\t\tdir(\"test/\"),\n\t\t\t\t\tfile(\"test/bar.txt\", \"testbartestbar\"),\n\t\t\t\t\tdir(\"test2/\"),\n\t\t\t\t\tlink(\"test2/bazlink\", \"foo.txt\"), // modified\n\t\t\t\t), allowedPrefix[0])),\n\t\t\t\tcheckVerifyInvalidTOCEntryFail(\"test/bar.txt\"),\n\t\t\t\tcheckVerifyBrokenContentFail(\"test/bar.txt\"),\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tif len(tt.minChunkSize) == 0 {\n\t\t\ttt.minChunkSize = []int{0}\n\t\t}\n\t\tfor _, srcCompression := range srcCompressions {\n\t\t\tsrcCompression := srcCompression\n\t\t\tfor _, newCL := range controllers {\n\t\t\t\tnewCL := newCL\n\t\t\t\tfor _, prefix := range allowedPrefix {\n\t\t\t\t\tprefix := prefix\n\t\t\t\t\tfor _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} {\n\t\t\t\t\t\tsrcTarFormat := srcTarFormat\n\t\t\t\t\t\tfor _, minChunkSize := range tt.minChunkSize {\n\t\t\t\t\t\t\tminChunkSize := minChunkSize\n\t\t\t\t\t\t\tt.Run(tt.name+\"-\"+fmt.Sprintf(\"compression=%v,prefix=%q,format=%s,minChunkSize=%d\", newCL(), prefix, srcTarFormat, minChunkSize), func(t *testing.T) {\n\t\t\t\t\t\t\t\t// Get original tar file and chunk digests\n\t\t\t\t\t\t\t\tdgstMap := make(map[string]digest.Digest)\n\t\t\t\t\t\t\t\ttarBlob := buildTar(t, tt.tarInit(t, dgstMap), prefix, srcTarFormat)\n\n\t\t\t\t\t\t\t\tcl := newCL()\n\t\t\t\t\t\t\t\trc, err := Build(compressBlob(t, tarBlob, srcCompression),\n\t\t\t\t\t\t\t\t\tWithChunkSize(chunkSize), WithCompression(cl))\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to convert stargz: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttocDigest := rc.TOCDigest()\n\t\t\t\t\t\t\t\tdefer rc.Close()\n\t\t\t\t\t\t\t\tbuf := new(bytes.Buffer)\n\t\t\t\t\t\t\t\tif _, err := io.Copy(buf, rc); err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"failed to copy built stargz blob: %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tnewStargz := buf.Bytes()\n\t\t\t\t\t\t\t\t// NoPrefetchLandmark is added during `Bulid`, which is expected behaviour.\n\t\t\t\t\t\t\t\tdgstMap[chunkID(NoPrefetchLandmark, 0, int64(len([]byte{landmarkContents})))] = digest.FromBytes([]byte{landmarkContents})\n\n\t\t\t\t\t\t\t\tfor _, check := range tt.checks {\n\t\t\t\t\t\t\t\t\tcheck(t, newStargz, tocDigest, dgstMap, cl, newCL)\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}\n\t}\n}\n\n// checkStargzTOC checks the TOC JSON of the passed stargz has the expected\n// digest and contains valid chunks. It walks all entries in the stargz and\n// checks all chunk digests stored to the TOC JSON match the actual contents.\nfunc checkStargzTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) {\n\tsgz, err := Open(\n\t\tio.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))),\n\t\tWithDecompressors(controller),\n\t)\n\tif err != nil {\n\t\tt.Errorf(\"failed to parse converted stargz: %v\", err)\n\t\treturn\n\t}\n\tdigestMapTOC, err := listDigests(io.NewSectionReader(\n\t\tbytes.NewReader(sgzData), 0, int64(len(sgzData))),\n\t\tcontroller,\n\t)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to list digest: %v\", err)\n\t}\n\tfound := make(map[string]bool)\n\tfor id := range dgstMap {\n\t\tfound[id] = false\n\t}\n\tzr, err := controller.Reader(bytes.NewReader(sgzData))\n\tif err != nil {\n\t\tt.Fatalf(\"failed to decompress converted stargz: %v\", err)\n\t}\n\tdefer zr.Close()\n\ttr := tar.NewReader(zr)\n\tfor {\n\t\th, err := tr.Next()\n\t\tif err != nil {\n\t\t\tif err != io.EOF {\n\t\t\t\tt.Errorf(\"failed to read tar entry: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif h.Name == TOCTarName {\n\t\t\t// Check the digest of TOC JSON based on the actual contents\n\t\t\t// It's sure that TOC JSON exists in this archive because\n\t\t\t// Open succeeded.\n\t\t\tdgstr := digest.Canonical.Digester()\n\t\t\tif _, err := io.Copy(dgstr.Hash(), tr); err != nil {\n\t\t\t\tt.Fatalf(\"failed to calculate digest of TOC JSON: %v\",\n\t\t\t\t\terr)\n\t\t\t}\n\t\t\tif dgstr.Digest() != tocDigest {\n\t\t\t\tt.Errorf(\"invalid TOC JSON %q; want %q\", tocDigest, dgstr.Digest())\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := sgz.Lookup(h.Name); !ok {\n\t\t\tt.Errorf(\"lost stargz entry %q in the converted TOC\", h.Name)\n\t\t\treturn\n\t\t}\n\t\tvar n int64\n\t\tfor n < h.Size {\n\t\t\tce, ok := sgz.ChunkEntryForOffset(h.Name, n)\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"lost chunk %q(offset=%d) in the converted TOC\",\n\t\t\t\t\th.Name, n)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Get the original digest to make sure the file contents are kept unchanged\n\t\t\t// from the original tar, during the whole conversion steps.\n\t\t\tid := chunkID(h.Name, n, ce.ChunkSize)\n\t\t\twant, ok := dgstMap[id]\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"Unexpected chunk %q(offset=%d,size=%d): %v\",\n\t\t\t\t\th.Name, n, ce.ChunkSize, dgstMap)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tfound[id] = true\n\n\t\t\t// Check the file contents\n\t\t\tdgstr := digest.Canonical.Digester()\n\t\t\tif _, err := io.CopyN(dgstr.Hash(), tr, ce.ChunkSize); err != nil {\n\t\t\t\tt.Fatalf(\"failed to calculate digest of %q (offset=%d,size=%d)\",\n\t\t\t\t\th.Name, n, ce.ChunkSize)\n\t\t\t}\n\t\t\tif want != dgstr.Digest() {\n\t\t\t\tt.Errorf(\"Invalid contents in converted stargz %q: %q; want %q\",\n\t\t\t\t\th.Name, dgstr.Digest(), want)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Check the digest stored in TOC JSON\n\t\t\tdgstTOC, ok := digestMapTOC[ce.Offset]\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"digest of %q(offset=%d,size=%d,chunkOffset=%d) isn't registered\",\n\t\t\t\t\th.Name, ce.Offset, ce.ChunkSize, ce.ChunkOffset)\n\t\t\t}\n\t\t\tif want != dgstTOC {\n\t\t\t\tt.Errorf(\"Invalid digest in TOCEntry %q: %q; want %q\",\n\t\t\t\t\th.Name, dgstTOC, want)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tn += ce.ChunkSize\n\t\t}\n\t}\n\n\tfor id, ok := range found {\n\t\tif !ok {\n\t\t\tt.Errorf(\"required chunk %q not found in the converted stargz: %v\", id, found)\n\t\t}\n\t}\n}\n\n// checkVerifyTOC checks the verification works for the TOC JSON of the passed\n// stargz. It walks all entries in the stargz and checks the verifications for\n// all chunks work.\nfunc checkVerifyTOC(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) {\n\tsgz, err := Open(\n\t\tio.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))),\n\t\tWithDecompressors(controller),\n\t)\n\tif err != nil {\n\t\tt.Errorf(\"failed to parse converted stargz: %v\", err)\n\t\treturn\n\t}\n\tev, err := sgz.VerifyTOC(tocDigest)\n\tif err != nil {\n\t\tt.Errorf(\"failed to verify stargz: %v\", err)\n\t\treturn\n\t}\n\n\tfound := make(map[string]bool)\n\tfor id := range dgstMap {\n\t\tfound[id] = false\n\t}\n\tzr, err := controller.Reader(bytes.NewReader(sgzData))\n\tif err != nil {\n\t\tt.Fatalf(\"failed to decompress converted stargz: %v\", err)\n\t}\n\tdefer zr.Close()\n\ttr := tar.NewReader(zr)\n\tfor {\n\t\th, err := tr.Next()\n\t\tif err != nil {\n\t\t\tif err != io.EOF {\n\t\t\t\tt.Errorf(\"failed to read tar entry: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif h.Name == TOCTarName {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := sgz.Lookup(h.Name); !ok {\n\t\t\tt.Errorf(\"lost stargz entry %q in the converted TOC\", h.Name)\n\t\t\treturn\n\t\t}\n\t\tvar n int64\n\t\tfor n < h.Size {\n\t\t\tce, ok := sgz.ChunkEntryForOffset(h.Name, n)\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"lost chunk %q(offset=%d) in the converted TOC\",\n\t\t\t\t\th.Name, n)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tv, err := ev.Verifier(ce)\n\t\t\tif err != nil {\n\t\t\t\tt.Errorf(\"failed to get verifier for %q(offset=%d)\", h.Name, n)\n\t\t\t}\n\n\t\t\tfound[chunkID(h.Name, n, ce.ChunkSize)] = true\n\n\t\t\t// Check the file contents\n\t\t\tif _, err := io.CopyN(v, tr, ce.ChunkSize); err != nil {\n\t\t\t\tt.Fatalf(\"failed to get chunk of %q (offset=%d,size=%d)\",\n\t\t\t\t\th.Name, n, ce.ChunkSize)\n\t\t\t}\n\t\t\tif !v.Verified() {\n\t\t\t\tt.Errorf(\"Invalid contents in converted stargz %q (should be succeeded)\",\n\t\t\t\t\th.Name)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tn += ce.ChunkSize\n\t\t}\n\t}\n\n\tfor id, ok := range found {\n\t\tif !ok {\n\t\t\tt.Errorf(\"required chunk %q not found in the converted stargz: %v\", id, found)\n\t\t}\n\t}\n}\n\n// checkVerifyInvalidTOCEntryFail checks if misconfigured TOC JSON can be\n// detected during the verification and the verification returns an error.\nfunc checkVerifyInvalidTOCEntryFail(filename string) check {\n\treturn func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) {\n\t\tfuncs := map[string]rewriteFunc{\n\t\t\t\"lost digest in a entry\": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) {\n\t\t\t\tvar found bool\n\t\t\t\tfor _, e := range toc.Entries {\n\t\t\t\t\tif cleanEntryName(e.Name) == filename {\n\t\t\t\t\t\tif e.Type != \"reg\" && e.Type != \"chunk\" {\n\t\t\t\t\t\t\tt.Fatalf(\"entry %q to break must be regfile or chunk\", filename)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif e.ChunkDigest == \"\" {\n\t\t\t\t\t\t\tt.Fatalf(\"entry %q is already invalid\", filename)\n\t\t\t\t\t\t}\n\t\t\t\t\t\te.ChunkDigest = \"\"\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !found {\n\t\t\t\t\tt.Fatalf(\"rewrite target not found\")\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"duplicated entry offset\": func(t *testing.T, toc *JTOC, sgz *io.SectionReader) {\n\t\t\t\tvar (\n\t\t\t\t\tsampleEntry *TOCEntry\n\t\t\t\t\ttargetEntry *TOCEntry\n\t\t\t\t)\n\t\t\t\tfor _, e := range toc.Entries {\n\t\t\t\t\tif e.Type == \"reg\" || e.Type == \"chunk\" {\n\t\t\t\t\t\tif cleanEntryName(e.Name) == filename {\n\t\t\t\t\t\t\ttargetEntry = e\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsampleEntry = e\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif sampleEntry == nil {\n\t\t\t\t\tt.Fatalf(\"TOC must contain at least one regfile or chunk entry other than the rewrite target\")\n\t\t\t\t}\n\t\t\t\tif targetEntry == nil {\n\t\t\t\t\tt.Fatalf(\"rewrite target not found\")\n\t\t\t\t}\n\t\t\t\ttargetEntry.Offset = sampleEntry.Offset\n\t\t\t},\n\t\t}\n\n\t\tfor name, rFunc := range funcs {\n\t\t\tt.Run(name, func(t *testing.T) {\n\t\t\t\tnewSgz, newTocDigest := rewriteTOCJSON(t, io.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))), rFunc, controller)\n\t\t\t\tbuf := new(bytes.Buffer)\n\t\t\t\tif _, err := io.Copy(buf, newSgz); err != nil {\n\t\t\t\t\tt.Fatalf(\"failed to get converted stargz\")\n\t\t\t\t}\n\t\t\t\tisgz := buf.Bytes()\n\n\t\t\t\tsgz, err := Open(\n\t\t\t\t\tio.NewSectionReader(bytes.NewReader(isgz), 0, int64(len(isgz))),\n\t\t\t\t\tWithDecompressors(controller),\n\t\t\t\t)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatalf(\"failed to parse converted stargz: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t_, err = sgz.VerifyTOC(newTocDigest)\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Errorf(\"must fail for invalid TOC\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n}\n\n// checkVerifyInvalidStargzFail checks if the verification detects that the\n// given stargz file doesn't match to the expected digest and returns error.\nfunc checkVerifyInvalidStargzFail(invalid *io.SectionReader) check {\n\treturn func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) {\n\t\tcl := newController()\n\t\trc, err := Build(invalid, WithChunkSize(chunkSize), WithCompression(cl))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to convert stargz: %v\", err)\n\t\t}\n\t\tdefer rc.Close()\n\t\tbuf := new(bytes.Buffer)\n\t\tif _, err := io.Copy(buf, rc); err != nil {\n\t\t\tt.Fatalf(\"failed to copy built stargz blob: %v\", err)\n\t\t}\n\t\tmStargz := buf.Bytes()\n\n\t\tsgz, err := Open(\n\t\t\tio.NewSectionReader(bytes.NewReader(mStargz), 0, int64(len(mStargz))),\n\t\t\tWithDecompressors(cl),\n\t\t)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to parse converted stargz: %v\", err)\n\t\t\treturn\n\t\t}\n\t\t_, err = sgz.VerifyTOC(tocDigest)\n\t\tif err == nil {\n\t\t\tt.Errorf(\"must fail for invalid TOC\")\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// checkVerifyBrokenContentFail checks if the verifier detects broken contents\n// that doesn't match to the expected digest and returns error.\nfunc checkVerifyBrokenContentFail(filename string) check {\n\treturn func(t *testing.T, sgzData []byte, tocDigest digest.Digest, dgstMap map[string]digest.Digest, controller TestingController, newController TestingControllerFactory) {\n\t\t// Parse stargz file\n\t\tsgz, err := Open(\n\t\t\tio.NewSectionReader(bytes.NewReader(sgzData), 0, int64(len(sgzData))),\n\t\t\tWithDecompressors(controller),\n\t\t)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to parse converted stargz: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tev, err := sgz.VerifyTOC(tocDigest)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to verify stargz: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\t// Open the target file\n\t\tsr, err := sgz.OpenFile(filename)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to open file %q\", filename)\n\t\t}\n\t\tce, ok := sgz.ChunkEntryForOffset(filename, 0)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"lost chunk %q(offset=%d) in the converted TOC\", filename, 0)\n\t\t\treturn\n\t\t}\n\t\tif ce.ChunkSize == 0 {\n\t\t\tt.Fatalf(\"file mustn't be empty\")\n\t\t\treturn\n\t\t}\n\t\tdata := make([]byte, ce.ChunkSize)\n\t\tif _, err := sr.ReadAt(data, ce.ChunkOffset); err != nil {\n\t\t\tt.Errorf(\"failed to get data of a chunk of %q(offset=%q)\",\n\t\t\t\tfilename, ce.ChunkOffset)\n\t\t}\n\n\t\t// Check the broken chunk (must fail)\n\t\tv, err := ev.Verifier(ce)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"failed to get verifier for %q\", filename)\n\t\t}\n\t\tbroken := append([]byte{^data[0]}, data[1:]...)\n\t\tif _, err := io.CopyN(v, bytes.NewReader(broken), ce.ChunkSize); err != nil {\n\t\t\tt.Fatalf(\"failed to get chunk of %q (offset=%d,size=%d)\",\n\t\t\t\tfilename, ce.ChunkOffset, ce.ChunkSize)\n\t\t}\n\t\tif v.Verified() {\n\t\t\tt.Errorf(\"verification must fail for broken file chunk %q(org:%q,broken:%q)\",\n\t\t\t\tfilename, data, broken)\n\t\t}\n\t}\n}\n\nfunc chunkID(name string, offset, size int64) string {\n\treturn fmt.Sprintf(\"%s-%d-%d\", cleanEntryName(name), offset, size)\n}\n\ntype rewriteFunc func(t *testing.T, toc *JTOC, sgz *io.SectionReader)\n\nfunc rewriteTOCJSON(t *testing.T, sgz *io.SectionReader, rewrite rewriteFunc, controller TestingController) (newSgz io.Reader, tocDigest digest.Digest) {\n\tdecodedJTOC, jtocOffset, err := parseStargz(sgz, controller)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to extract TOC JSON: %v\", err)\n\t}\n\n\trewrite(t, decodedJTOC, sgz)\n\n\ttocFooter, tocDigest, err := tocAndFooter(controller, decodedJTOC, jtocOffset)\n\tif err != nil {\n\t\tt.Fatalf(\"failed to create toc and footer: %v\", err)\n\t}\n\n\t// Reconstruct stargz file with the modified TOC JSON\n\tif _, err := sgz.Seek(0, io.SeekStart); err != nil {\n\t\tt.Fatalf(\"failed to reset the seek position of stargz: %v\", err)\n\t}\n\treturn io.MultiReader(\n\t\tio.LimitReader(sgz, jtocOffset), // Original stargz (before TOC JSON)\n\t\ttocFooter,                       // Rewritten TOC and footer\n\t), tocDigest\n}\n\nfunc listDigests(sgz *io.SectionReader, controller TestingController) (map[int64]digest.Digest, error) {\n\tdecodedJTOC, _, err := parseStargz(sgz, controller)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdigestMap := make(map[int64]digest.Digest)\n\tfor _, e := range decodedJTOC.Entries {\n\t\tif e.Type == \"reg\" || e.Type == \"chunk\" {\n\t\t\tif e.Type == \"reg\" && e.Size == 0 {\n\t\t\t\tcontinue // ignores empty file\n\t\t\t}\n\t\t\tif e.ChunkDigest == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"ChunkDigest of %q(off=%d) not found in TOC JSON\",\n\t\t\t\t\te.Name, e.Offset)\n\t\t\t}\n\t\t\td, err := digest.Parse(e.ChunkDigest)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdigestMap[e.Offset] = d\n\t\t}\n\t}\n\treturn digestMap, nil\n}\n\nfunc parseStargz(sgz *io.SectionReader, controller TestingController) (decodedJTOC *JTOC, jtocOffset int64, err error) {\n\tfSize := controller.FooterSize()\n\tfooter := make([]byte, fSize)\n\tif _, err := sgz.ReadAt(footer, sgz.Size()-fSize); err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"error reading footer: %w\", err)\n\t}\n\t_, tocOffset, _, err := controller.ParseFooter(footer[positive(int64(len(footer))-fSize):])\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"failed to parse footer: %w\", err)\n\t}\n\n\t// Decode the TOC JSON\n\tvar tocReader io.Reader\n\tif tocOffset >= 0 {\n\t\ttocReader = io.NewSectionReader(sgz, tocOffset, sgz.Size()-tocOffset-fSize)\n\t}\n\tdecodedJTOC, _, err = controller.ParseTOC(tocReader)\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"failed to parse TOC: %w\", err)\n\t}\n\treturn decodedJTOC, tocOffset, nil\n}\n\nfunc testWriteAndOpen(t *testing.T, controllers ...TestingControllerFactory) {\n\tconst content = \"Some contents\"\n\tinvalidUtf8 := \"\\xff\\xfe\\xfd\"\n\n\txAttrFile := xAttr{\"foo\": \"bar\", \"invalid-utf8\": invalidUtf8}\n\tsampleOwner := owner{uid: 50, gid: 100}\n\n\tdata64KB := randomContents(64000)\n\n\ttests := []struct {\n\t\tname         string\n\t\tchunkSize    int\n\t\tminChunkSize int\n\t\tin           []tarEntry\n\t\twant         []stargzCheck\n\t\twantNumGz    int // expected number of streams\n\n\t\twantNumGzLossLess  int // expected number of streams (> 0) in lossless mode if it's different from wantNumGz\n\t\twantFailOnLossLess bool\n\t\twantTOCVersion     int // default = 1\n\t}{\n\t\t{\n\t\t\tname:      \"empty\",\n\t\t\tin:        tarOf(),\n\t\t\twantNumGz: 2, // (empty tar) + TOC + footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(0),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"1dir_1empty_file\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tfile(\"foo/bar.txt\", \"\"),\n\t\t\t),\n\t\t\twantNumGz: 3, // dir, TOC, footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(2),\n\t\t\t\thasDir(\"foo/\"),\n\t\t\t\thasFileLen(\"foo/bar.txt\", 0),\n\t\t\t\tentryHasChildren(\"foo\", \"bar.txt\"),\n\t\t\t\thasFileDigest(\"foo/bar.txt\", digestFor(\"\")),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"1dir_1file\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tfile(\"foo/bar.txt\", content, xAttrFile),\n\t\t\t),\n\t\t\twantNumGz: 4, // var dir, foo.txt alone, TOC, footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(2),\n\t\t\t\thasDir(\"foo/\"),\n\t\t\t\thasFileLen(\"foo/bar.txt\", len(content)),\n\t\t\t\thasFileDigest(\"foo/bar.txt\", digestFor(content)),\n\t\t\t\thasFileContentsRange(\"foo/bar.txt\", 0, content),\n\t\t\t\thasFileContentsRange(\"foo/bar.txt\", 1, content[1:]),\n\t\t\t\tentryHasChildren(\"\", \"foo\"),\n\t\t\t\tentryHasChildren(\"foo\", \"bar.txt\"),\n\t\t\t\thasFileXattrs(\"foo/bar.txt\", \"foo\", \"bar\"),\n\t\t\t\thasFileXattrs(\"foo/bar.txt\", \"invalid-utf8\", invalidUtf8),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"2meta_2file\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"bar/\", sampleOwner),\n\t\t\t\tdir(\"foo/\", sampleOwner),\n\t\t\t\tfile(\"foo/bar.txt\", content, sampleOwner),\n\t\t\t),\n\t\t\twantNumGz: 4, // both dirs, foo.txt alone, TOC, footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(3),\n\t\t\t\thasDir(\"bar/\"),\n\t\t\t\thasDir(\"foo/\"),\n\t\t\t\thasFileLen(\"foo/bar.txt\", len(content)),\n\t\t\t\tentryHasChildren(\"\", \"bar\", \"foo\"),\n\t\t\t\tentryHasChildren(\"foo\", \"bar.txt\"),\n\t\t\t\thasChunkEntries(\"foo/bar.txt\", 1),\n\t\t\t\thasEntryOwner(\"bar/\", sampleOwner),\n\t\t\t\thasEntryOwner(\"foo/\", sampleOwner),\n\t\t\t\thasEntryOwner(\"foo/bar.txt\", sampleOwner),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"3dir\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"bar/\"),\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tdir(\"foo/bar/\"),\n\t\t\t),\n\t\t\twantNumGz: 3, // 3 dirs, TOC, footer\n\t\t\twant: checks(\n\t\t\t\thasDirLinkCount(\"bar/\", 2),\n\t\t\t\thasDirLinkCount(\"foo/\", 3),\n\t\t\t\thasDirLinkCount(\"foo/bar/\", 2),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"symlink\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tsymlink(\"foo/bar\", \"../../x\"),\n\t\t\t),\n\t\t\twantNumGz: 3, // metas + TOC + footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(2),\n\t\t\t\thasSymlink(\"foo/bar\", \"../../x\"),\n\t\t\t\tentryHasChildren(\"\", \"foo\"),\n\t\t\t\tentryHasChildren(\"foo\", \"bar\"),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname:      \"chunked_file\",\n\t\t\tchunkSize: 4,\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tfile(\"foo/big.txt\", \"This \"+\"is s\"+\"uch \"+\"a bi\"+\"g fi\"+\"le\"),\n\t\t\t),\n\t\t\twantNumGz: 9, // dir + big.txt(6 chunks) + TOC + footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(7), // 1 for foo dir, 6 for the foo/big.txt file\n\t\t\t\thasDir(\"foo/\"),\n\t\t\t\thasFileLen(\"foo/big.txt\", len(\"This is such a big file\")),\n\t\t\t\thasFileDigest(\"foo/big.txt\", digestFor(\"This is such a big file\")),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 0, \"This is such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 1, \"his is such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 2, \"is is such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 3, \"s is such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 4, \" is such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 5, \"is such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 6, \"s such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 7, \" such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 8, \"such a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 9, \"uch a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 10, \"ch a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 11, \"h a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", 12, \" a big file\"),\n\t\t\t\thasFileContentsRange(\"foo/big.txt\", len(\"This is such a big file\")-1, \"\"),\n\t\t\t\thasChunkEntries(\"foo/big.txt\", 6),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"recursive\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"/\", sampleOwner),\n\t\t\t\tdir(\"bar/\", sampleOwner),\n\t\t\t\tdir(\"foo/\", sampleOwner),\n\t\t\t\tfile(\"foo/bar.txt\", content, sampleOwner),\n\t\t\t),\n\t\t\twantNumGz: 4, // dirs, bar.txt alone, TOC, footer\n\t\t\twant: checks(\n\t\t\t\tmaxDepth(2), // 0: root directory, 1: \"foo/\", 2: \"bar.txt\"\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"block_char_fifo\",\n\t\t\tin: tarOf(\n\t\t\t\ttarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\t\t\t\treturn w.WriteHeader(&tar.Header{\n\t\t\t\t\t\tName:     prefix + \"b\",\n\t\t\t\t\t\tTypeflag: tar.TypeBlock,\n\t\t\t\t\t\tDevmajor: 123,\n\t\t\t\t\t\tDevminor: 456,\n\t\t\t\t\t\tFormat:   format,\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\ttarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\t\t\t\treturn w.WriteHeader(&tar.Header{\n\t\t\t\t\t\tName:     prefix + \"c\",\n\t\t\t\t\t\tTypeflag: tar.TypeChar,\n\t\t\t\t\t\tDevmajor: 111,\n\t\t\t\t\t\tDevminor: 222,\n\t\t\t\t\t\tFormat:   format,\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t\ttarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\t\t\t\treturn w.WriteHeader(&tar.Header{\n\t\t\t\t\t\tName:     prefix + \"f\",\n\t\t\t\t\t\tTypeflag: tar.TypeFifo,\n\t\t\t\t\t\tFormat:   format,\n\t\t\t\t\t})\n\t\t\t\t}),\n\t\t\t),\n\t\t\twantNumGz: 3,\n\t\t\twant: checks(\n\t\t\t\tlookupMatch(\"b\", &TOCEntry{Name: \"b\", Type: \"block\", DevMajor: 123, DevMinor: 456, NumLink: 1}),\n\t\t\t\tlookupMatch(\"c\", &TOCEntry{Name: \"c\", Type: \"char\", DevMajor: 111, DevMinor: 222, NumLink: 1}),\n\t\t\t\tlookupMatch(\"f\", &TOCEntry{Name: \"f\", Type: \"fifo\", NumLink: 1}),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"modes\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo1/\", 0755|os.ModeDir|os.ModeSetgid),\n\t\t\t\tfile(\"foo1/bar1\", content, 0700|os.ModeSetuid),\n\t\t\t\tfile(\"foo1/bar2\", content, 0755|os.ModeSetgid),\n\t\t\t\tdir(\"foo2/\", 0755|os.ModeDir|os.ModeSticky),\n\t\t\t\tfile(\"foo2/bar3\", content, 0755|os.ModeSticky),\n\t\t\t\tdir(\"foo3/\", 0755|os.ModeDir),\n\t\t\t\tfile(\"foo3/bar4\", content, os.FileMode(0700)),\n\t\t\t\tfile(\"foo3/bar5\", content, os.FileMode(0755)),\n\t\t\t),\n\t\t\twantNumGz: 8, // dir, bar1 alone, bar2 alone + dir, bar3 alone + dir, bar4 alone, bar5 alone, TOC, footer\n\t\t\twant: checks(\n\t\t\t\thasMode(\"foo1/\", 0755|os.ModeDir|os.ModeSetgid),\n\t\t\t\thasMode(\"foo1/bar1\", 0700|os.ModeSetuid),\n\t\t\t\thasMode(\"foo1/bar2\", 0755|os.ModeSetgid),\n\t\t\t\thasMode(\"foo2/\", 0755|os.ModeDir|os.ModeSticky),\n\t\t\t\thasMode(\"foo2/bar3\", 0755|os.ModeSticky),\n\t\t\t\thasMode(\"foo3/\", 0755|os.ModeDir),\n\t\t\t\thasMode(\"foo3/bar4\", os.FileMode(0700)),\n\t\t\t\thasMode(\"foo3/bar5\", os.FileMode(0755)),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname: \"lossy\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"bar/\", sampleOwner),\n\t\t\t\tdir(\"foo/\", sampleOwner),\n\t\t\t\tfile(\"foo/bar.txt\", content, sampleOwner),\n\t\t\t\tfile(TOCTarName, \"dummy\"), // ignored by the writer. (lossless write returns error)\n\t\t\t),\n\t\t\twantNumGz: 4, // both dirs, foo.txt alone, TOC, footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(3),\n\t\t\t\thasDir(\"bar/\"),\n\t\t\t\thasDir(\"foo/\"),\n\t\t\t\thasFileLen(\"foo/bar.txt\", len(content)),\n\t\t\t\tentryHasChildren(\"\", \"bar\", \"foo\"),\n\t\t\t\tentryHasChildren(\"foo\", \"bar.txt\"),\n\t\t\t\thasChunkEntries(\"foo/bar.txt\", 1),\n\t\t\t\thasEntryOwner(\"bar/\", sampleOwner),\n\t\t\t\thasEntryOwner(\"foo/\", sampleOwner),\n\t\t\t\thasEntryOwner(\"foo/bar.txt\", sampleOwner),\n\t\t\t),\n\t\t\twantFailOnLossLess: true,\n\t\t},\n\t\t{\n\t\t\tname: \"hardlink should be replaced to the destination entry\",\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tfile(\"foo/foo1\", \"test\"),\n\t\t\t\tlink(\"foolink\", \"foo/foo1\"),\n\t\t\t),\n\t\t\twantNumGz: 4, // dir, foo1 + link, TOC, footer\n\t\t\twant: checks(\n\t\t\t\tmustSameEntry(\"foo/foo1\", \"foolink\"),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname:         \"several_files_in_chunk\",\n\t\t\tminChunkSize: 8000,\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tfile(\"foo/foo1\", data64KB),\n\t\t\t\tfile(\"foo2\", \"bb\"),\n\t\t\t\tfile(\"foo22\", \"ccc\"),\n\t\t\t\tdir(\"bar/\"),\n\t\t\t\tfile(\"bar/bar.txt\", \"aaa\"),\n\t\t\t\tfile(\"foo3\", data64KB),\n\t\t\t),\n\t\t\t// NOTE: we assume that the compressed \"data64KB\" is still larger than 8KB\n\t\t\twantNumGz: 4, // dir+foo1, foo2+foo22+dir+bar.txt+foo3, TOC, footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(7), // dir, foo1, foo2, foo22, dir, bar.txt, foo3\n\t\t\t\thasDir(\"foo/\"),\n\t\t\t\thasDir(\"bar/\"),\n\t\t\t\thasFileLen(\"foo/foo1\", len(data64KB)),\n\t\t\t\thasFileLen(\"foo2\", len(\"bb\")),\n\t\t\t\thasFileLen(\"foo22\", len(\"ccc\")),\n\t\t\t\thasFileLen(\"bar/bar.txt\", len(\"aaa\")),\n\t\t\t\thasFileLen(\"foo3\", len(data64KB)),\n\t\t\t\thasFileDigest(\"foo/foo1\", digestFor(data64KB)),\n\t\t\t\thasFileDigest(\"foo2\", digestFor(\"bb\")),\n\t\t\t\thasFileDigest(\"foo22\", digestFor(\"ccc\")),\n\t\t\t\thasFileDigest(\"bar/bar.txt\", digestFor(\"aaa\")),\n\t\t\t\thasFileDigest(\"foo3\", digestFor(data64KB)),\n\t\t\t\thasFileContentsWithPreRead(\"foo22\", 0, \"ccc\", chunkInfo{\"foo2\", \"bb\"}, chunkInfo{\"bar/bar.txt\", \"aaa\"}, chunkInfo{\"foo3\", data64KB}),\n\t\t\t\thasFileContentsRange(\"foo/foo1\", 0, data64KB),\n\t\t\t\thasFileContentsRange(\"foo2\", 0, \"bb\"),\n\t\t\t\thasFileContentsRange(\"foo2\", 1, \"b\"),\n\t\t\t\thasFileContentsRange(\"foo22\", 0, \"ccc\"),\n\t\t\t\thasFileContentsRange(\"foo22\", 1, \"cc\"),\n\t\t\t\thasFileContentsRange(\"foo22\", 2, \"c\"),\n\t\t\t\thasFileContentsRange(\"bar/bar.txt\", 0, \"aaa\"),\n\t\t\t\thasFileContentsRange(\"bar/bar.txt\", 1, \"aa\"),\n\t\t\t\thasFileContentsRange(\"bar/bar.txt\", 2, \"a\"),\n\t\t\t\thasFileContentsRange(\"foo3\", 0, data64KB),\n\t\t\t\thasFileContentsRange(\"foo3\", 1, data64KB[1:]),\n\t\t\t\thasFileContentsRange(\"foo3\", 2, data64KB[2:]),\n\t\t\t\thasFileContentsRange(\"foo3\", len(data64KB)/2, data64KB[len(data64KB)/2:]),\n\t\t\t\thasFileContentsRange(\"foo3\", len(data64KB)-1, data64KB[len(data64KB)-1:]),\n\t\t\t),\n\t\t},\n\t\t{\n\t\t\tname:         \"several_files_in_chunk_chunked\",\n\t\t\tminChunkSize: 8000,\n\t\t\tchunkSize:    32000,\n\t\t\tin: tarOf(\n\t\t\t\tdir(\"foo/\"),\n\t\t\t\tfile(\"foo/foo1\", data64KB),\n\t\t\t\tfile(\"foo2\", \"bb\"),\n\t\t\t\tdir(\"bar/\"),\n\t\t\t\tfile(\"foo3\", data64KB),\n\t\t\t),\n\t\t\t// NOTE: we assume that the compressed chunk of \"data64KB\" is still larger than 8KB\n\t\t\twantNumGz: 6, // dir+foo1(1), foo1(2), foo2+dir+foo3(1), foo3(2), TOC, footer\n\t\t\twant: checks(\n\t\t\t\tnumTOCEntries(7), // dir, foo1(2 chunks), foo2, dir, foo3(2 chunks)\n\t\t\t\thasDir(\"foo/\"),\n\t\t\t\thasDir(\"bar/\"),\n\t\t\t\thasFileLen(\"foo/foo1\", len(data64KB)),\n\t\t\t\thasFileLen(\"foo2\", len(\"bb\")),\n\t\t\t\thasFileLen(\"foo3\", len(data64KB)),\n\t\t\t\thasFileDigest(\"foo/foo1\", digestFor(data64KB)),\n\t\t\t\thasFileDigest(\"foo2\", digestFor(\"bb\")),\n\t\t\t\thasFileDigest(\"foo3\", digestFor(data64KB)),\n\t\t\t\thasFileContentsWithPreRead(\"foo2\", 0, \"bb\", chunkInfo{\"foo3\", data64KB[:32000]}),\n\t\t\t\thasFileContentsRange(\"foo/foo1\", 0, data64KB),\n\t\t\t\thasFileContentsRange(\"foo/foo1\", 1, data64KB[1:]),\n\t\t\t\thasFileContentsRange(\"foo/foo1\", 2, data64KB[2:]),\n\t\t\t\thasFileContentsRange(\"foo/foo1\", len(data64KB)/2, data64KB[len(data64KB)/2:]),\n\t\t\t\thasFileContentsRange(\"foo/foo1\", len(data64KB)-1, data64KB[len(data64KB)-1:]),\n\t\t\t\thasFileContentsRange(\"foo2\", 0, \"bb\"),\n\t\t\t\thasFileContentsRange(\"foo2\", 1, \"b\"),\n\t\t\t\thasFileContentsRange(\"foo3\", 0, data64KB),\n\t\t\t\thasFileContentsRange(\"foo3\", 1, data64KB[1:]),\n\t\t\t\thasFileContentsRange(\"foo3\", 2, data64KB[2:]),\n\t\t\t\thasFileContentsRange(\"foo3\", len(data64KB)/2, data64KB[len(data64KB)/2:]),\n\t\t\t\thasFileContentsRange(\"foo3\", len(data64KB)-1, data64KB[len(data64KB)-1:]),\n\t\t\t),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tfor _, newCL := range controllers {\n\t\t\tnewCL := newCL\n\t\t\tfor _, prefix := range allowedPrefix {\n\t\t\t\tprefix := prefix\n\t\t\t\tfor _, srcTarFormat := range []tar.Format{tar.FormatUSTAR, tar.FormatPAX, tar.FormatGNU} {\n\t\t\t\t\tsrcTarFormat := srcTarFormat\n\t\t\t\t\tfor _, lossless := range []bool{true, false} {\n\t\t\t\t\t\tt.Run(tt.name+\"-\"+fmt.Sprintf(\"compression=%v,prefix=%q,lossless=%v,format=%s\", newCL(), prefix, lossless, srcTarFormat), func(t *testing.T) {\n\t\t\t\t\t\t\tvar tr io.Reader = buildTar(t, tt.in, prefix, srcTarFormat)\n\t\t\t\t\t\t\torigTarDgstr := digest.Canonical.Digester()\n\t\t\t\t\t\t\ttr = io.TeeReader(tr, origTarDgstr.Hash())\n\t\t\t\t\t\t\tvar stargzBuf bytes.Buffer\n\t\t\t\t\t\t\tcl1 := newCL()\n\t\t\t\t\t\t\tw := NewWriterWithCompressor(&stargzBuf, cl1)\n\t\t\t\t\t\t\tw.ChunkSize = tt.chunkSize\n\t\t\t\t\t\t\tw.MinChunkSize = tt.minChunkSize\n\t\t\t\t\t\t\tif lossless {\n\t\t\t\t\t\t\t\terr := w.AppendTarLossLess(tr)\n\t\t\t\t\t\t\t\tif tt.wantFailOnLossLess {\n\t\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\t\treturn // expected to fail\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"Append wanted to fail on lossless\")\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"Append(lossless): %v\", err)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif err := w.AppendTar(tr); err != nil {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"Append: %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\tif _, err := w.Close(); err != nil {\n\t\t\t\t\t\t\t\tt.Fatalf(\"Writer.Close: %v\", err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tb := stargzBuf.Bytes()\n\n\t\t\t\t\t\t\tif lossless {\n\t\t\t\t\t\t\t\t// Check if the result blob reserves original tar metadata\n\t\t\t\t\t\t\t\trc, err := Unpack(io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b))), cl1)\n\t\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\t\tt.Errorf(\"failed to decompress blob: %v\", err)\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdefer rc.Close()\n\t\t\t\t\t\t\t\tresultDgstr := digest.Canonical.Digester()\n\t\t\t\t\t\t\t\tif _, err := io.Copy(resultDgstr.Hash(), rc); err != nil {\n\t\t\t\t\t\t\t\t\tt.Errorf(\"failed to read result decompressed blob: %v\", err)\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif resultDgstr.Digest() != origTarDgstr.Digest() {\n\t\t\t\t\t\t\t\t\tt.Errorf(\"lossy compression occurred: digest=%v; want %v\",\n\t\t\t\t\t\t\t\t\t\tresultDgstr.Digest(), origTarDgstr.Digest())\n\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdiffID := w.DiffID()\n\t\t\t\t\t\t\twantDiffID := cl1.DiffIDOf(t, b)\n\t\t\t\t\t\t\tif diffID != wantDiffID {\n\t\t\t\t\t\t\t\tt.Errorf(\"DiffID = %q; want %q\", diffID, wantDiffID)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\ttelemetry, checkCalled := newCalledTelemetry()\n\t\t\t\t\t\t\tsr := io.NewSectionReader(bytes.NewReader(b), 0, int64(len(b)))\n\t\t\t\t\t\t\tr, err := Open(\n\t\t\t\t\t\t\t\tsr,\n\t\t\t\t\t\t\t\tWithDecompressors(cl1),\n\t\t\t\t\t\t\t\tWithTelemetry(telemetry),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tt.Fatalf(\"stargz.Open: %v\", err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twantTOCVersion := 1\n\t\t\t\t\t\t\tif tt.wantTOCVersion > 0 {\n\t\t\t\t\t\t\t\twantTOCVersion = tt.wantTOCVersion\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif r.toc.Version != wantTOCVersion {\n\t\t\t\t\t\t\t\tt.Fatalf(\"invalid TOC Version %d; wanted %d\", r.toc.Version, wantTOCVersion)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tfooterSize := cl1.FooterSize()\n\t\t\t\t\t\t\tfooterOffset := sr.Size() - footerSize\n\t\t\t\t\t\t\tfooter := make([]byte, footerSize)\n\t\t\t\t\t\t\tif _, err := sr.ReadAt(footer, footerOffset); err != nil {\n\t\t\t\t\t\t\t\tt.Errorf(\"failed to read footer: %v\", err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t_, tocOffset, _, err := cl1.ParseFooter(footer)\n\t\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\t\tt.Errorf(\"failed to parse footer: %v\", err)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif err := checkCalled(tocOffset >= 0); err != nil {\n\t\t\t\t\t\t\t\tt.Errorf(\"telemetry failure: %v\", err)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\twantNumGz := tt.wantNumGz\n\t\t\t\t\t\t\tif lossless && tt.wantNumGzLossLess > 0 {\n\t\t\t\t\t\t\t\twantNumGz = tt.wantNumGzLossLess\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstreamOffsets := []int64{0}\n\t\t\t\t\t\t\tprevOffset := int64(-1)\n\t\t\t\t\t\t\tstreams := 0\n\t\t\t\t\t\t\tfor _, e := range r.toc.Entries {\n\t\t\t\t\t\t\t\tif e.Offset > prevOffset {\n\t\t\t\t\t\t\t\t\tstreamOffsets = append(streamOffsets, e.Offset)\n\t\t\t\t\t\t\t\t\tprevOffset = e.Offset\n\t\t\t\t\t\t\t\t\tstreams++\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstreams++ // TOC\n\t\t\t\t\t\t\tif tocOffset >= 0 {\n\t\t\t\t\t\t\t\t// toc is in the blob\n\t\t\t\t\t\t\t\tstreamOffsets = append(streamOffsets, tocOffset)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstreams++ // footer\n\t\t\t\t\t\t\tstreamOffsets = append(streamOffsets, footerOffset)\n\t\t\t\t\t\t\tif streams != wantNumGz {\n\t\t\t\t\t\t\t\tt.Errorf(\"number of streams in TOC = %d; want %d\", streams, wantNumGz)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tt.Logf(\"testing streams: %+v\", streamOffsets)\n\t\t\t\t\t\t\tcl1.TestStreams(t, b, streamOffsets)\n\n\t\t\t\t\t\t\tfor _, want := range tt.want {\n\t\t\t\t\t\t\t\twant.check(t, r)\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}\n\t}\n}\n\ntype chunkInfo struct {\n\tname string\n\tdata string\n}\n\nfunc newCalledTelemetry() (telemetry *Telemetry, check func(needsGetTOC bool) error) {\n\tvar getFooterLatencyCalled bool\n\tvar getTocLatencyCalled bool\n\tvar deserializeTocLatencyCalled bool\n\treturn &Telemetry{\n\t\t\tfunc(time.Time) { getFooterLatencyCalled = true },\n\t\t\tfunc(time.Time) { getTocLatencyCalled = true },\n\t\t\tfunc(time.Time) { deserializeTocLatencyCalled = true },\n\t\t}, func(needsGetTOC bool) error {\n\t\t\tvar allErr []error\n\t\t\tif !getFooterLatencyCalled {\n\t\t\t\tallErr = append(allErr, fmt.Errorf(\"metrics GetFooterLatency isn't called\"))\n\t\t\t}\n\t\t\tif needsGetTOC {\n\t\t\t\tif !getTocLatencyCalled {\n\t\t\t\t\tallErr = append(allErr, fmt.Errorf(\"metrics GetTocLatency isn't called\"))\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !deserializeTocLatencyCalled {\n\t\t\t\tallErr = append(allErr, fmt.Errorf(\"metrics DeserializeTocLatency isn't called\"))\n\t\t\t}\n\t\t\treturn errorutil.Aggregate(allErr)\n\t\t}\n}\n\nfunc digestFor(content string) string {\n\tsum := sha256.Sum256([]byte(content))\n\treturn fmt.Sprintf(\"sha256:%x\", sum)\n}\n\ntype numTOCEntries int\n\nfunc (n numTOCEntries) check(t *testing.T, r *Reader) {\n\tif r.toc == nil {\n\t\tt.Fatal(\"nil TOC\")\n\t}\n\tif got, want := len(r.toc.Entries), int(n); got != want {\n\t\tt.Errorf(\"got %d TOC entries; want %d\", got, want)\n\t}\n\tt.Logf(\"got TOC entries:\")\n\tfor i, ent := range r.toc.Entries {\n\t\tentj, _ := json.Marshal(ent)\n\t\tt.Logf(\"  [%d]: %s\\n\", i, entj)\n\t}\n\tif t.Failed() {\n\t\tt.FailNow()\n\t}\n}\n\nfunc checks(s ...stargzCheck) []stargzCheck { return s }\n\ntype stargzCheck interface {\n\tcheck(t *testing.T, r *Reader)\n}\n\ntype stargzCheckFn func(*testing.T, *Reader)\n\nfunc (f stargzCheckFn) check(t *testing.T, r *Reader) { f(t, r) }\n\nfunc maxDepth(max int) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\te, ok := r.Lookup(\"\")\n\t\tif !ok {\n\t\t\tt.Fatal(\"root directory not found\")\n\t\t}\n\t\td, err := getMaxDepth(t, e, 0, 10*max)\n\t\tif err != nil {\n\t\t\tt.Errorf(\"failed to get max depth (wanted %d): %v\", max, err)\n\t\t\treturn\n\t\t}\n\t\tif d != max {\n\t\t\tt.Errorf(\"invalid depth %d; want %d\", d, max)\n\t\t\treturn\n\t\t}\n\t})\n}\n\nfunc getMaxDepth(t *testing.T, e *TOCEntry, current, limit int) (max int, rErr error) {\n\tif current > limit {\n\t\treturn -1, fmt.Errorf(\"walkMaxDepth: exceeds limit: current:%d > limit:%d\",\n\t\t\tcurrent, limit)\n\t}\n\tmax = current\n\te.ForeachChild(func(baseName string, ent *TOCEntry) bool {\n\t\tt.Logf(\"%q(basename:%q) is child of %q\\n\", ent.Name, baseName, e.Name)\n\t\td, err := getMaxDepth(t, ent, current+1, limit)\n\t\tif err != nil {\n\t\t\trErr = err\n\t\t\treturn false\n\t\t}\n\t\tif d > max {\n\t\t\tmax = d\n\t\t}\n\t\treturn true\n\t})\n\treturn\n}\n\nfunc hasFileLen(file string, wantLen int) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tfor _, ent := range r.toc.Entries {\n\t\t\tif ent.Name == file {\n\t\t\t\tif ent.Type != \"reg\" {\n\t\t\t\t\tt.Errorf(\"file type of %q is %q; want \\\"reg\\\"\", file, ent.Type)\n\t\t\t\t} else if ent.Size != int64(wantLen) {\n\t\t\t\t\tt.Errorf(\"file size of %q = %d; want %d\", file, ent.Size, wantLen)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"file %q not found\", file)\n\t})\n}\n\nfunc hasFileXattrs(file, name, value string) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tfor _, ent := range r.toc.Entries {\n\t\t\tif ent.Name == file {\n\t\t\t\tif ent.Type != \"reg\" {\n\t\t\t\t\tt.Errorf(\"file type of %q is %q; want \\\"reg\\\"\", file, ent.Type)\n\t\t\t\t}\n\t\t\t\tif ent.Xattrs == nil {\n\t\t\t\t\tt.Errorf(\"file %q has no xattrs\", file)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tvalueFound, found := ent.Xattrs[name]\n\t\t\t\tif !found {\n\t\t\t\t\tt.Errorf(\"file %q has no xattr %q\", file, name)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif string(valueFound) != value {\n\t\t\t\t\tt.Errorf(\"file %q has xattr %q with value %q instead of %q\", file, name, valueFound, value)\n\t\t\t\t}\n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"file %q not found\", file)\n\t})\n}\n\nfunc hasFileDigest(file string, digest string) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tent, ok := r.Lookup(file)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"didn't find TOCEntry for file %q\", file)\n\t\t}\n\t\tif ent.Digest != digest {\n\t\t\tt.Fatalf(\"Digest(%q) = %q, want %q\", file, ent.Digest, digest)\n\t\t}\n\t})\n}\n\nfunc hasFileContentsWithPreRead(file string, offset int, want string, extra ...chunkInfo) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\textraMap := make(map[string]chunkInfo)\n\t\tfor _, e := range extra {\n\t\t\textraMap[e.name] = e\n\t\t}\n\t\tvar extraNames []string\n\t\tfor n := range extraMap {\n\t\t\textraNames = append(extraNames, n)\n\t\t}\n\t\tf, err := r.OpenFileWithPreReader(file, func(e *TOCEntry, cr io.Reader) error {\n\t\t\tt.Logf(\"On %q: got preread of %q\", file, e.Name)\n\t\t\tex, ok := extraMap[e.Name]\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"fail on %q: unexpected entry %q: %+v, %+v\", file, e.Name, e, extraNames)\n\t\t\t}\n\t\t\tgot, err := io.ReadAll(cr)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatalf(\"fail on %q: failed to read %q: %v\", file, e.Name, err)\n\t\t\t}\n\t\t\tif ex.data != string(got) {\n\t\t\t\tt.Fatalf(\"fail on %q: unexpected contents of %q: len=%d; want=%d\", file, e.Name, len(got), len(ex.data))\n\t\t\t}\n\t\t\tdelete(extraMap, e.Name)\n\t\t\treturn nil\n\t\t})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tgot := make([]byte, len(want))\n\t\tn, err := f.ReadAt(got, int64(offset))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"ReadAt(len %d, offset %d, size %d) = %v, %v\", len(got), offset, f.Size(), n, err)\n\t\t}\n\t\tif string(got) != want {\n\t\t\tt.Fatalf(\"ReadAt(len %d, offset %d) = %q, want %q\", len(got), offset, viewContent(got), viewContent([]byte(want)))\n\t\t}\n\t\tif len(extraMap) != 0 {\n\t\t\tvar exNames []string\n\t\t\tfor _, ex := range extraMap {\n\t\t\t\texNames = append(exNames, ex.name)\n\t\t\t}\n\t\t\tt.Fatalf(\"fail on %q: some entries aren't read: %+v\", file, exNames)\n\t\t}\n\t})\n}\n\nfunc hasFileContentsRange(file string, offset int, want string) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tf, err := r.OpenFile(file)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tgot := make([]byte, len(want))\n\t\tn, err := f.ReadAt(got, int64(offset))\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"ReadAt(len %d, offset %d) = %v, %v\", len(got), offset, n, err)\n\t\t}\n\t\tif string(got) != want {\n\t\t\tt.Fatalf(\"ReadAt(len %d, offset %d) = %q, want %q\", len(got), offset, viewContent(got), viewContent([]byte(want)))\n\t\t}\n\t})\n}\n\nfunc hasChunkEntries(file string, wantChunks int) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tent, ok := r.Lookup(file)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"no file for %q\", file)\n\t\t}\n\t\tif ent.Type != \"reg\" {\n\t\t\tt.Fatalf(\"file %q has unexpected type %q; want reg\", file, ent.Type)\n\t\t}\n\t\tchunks := r.getChunks(ent)\n\t\tif len(chunks) != wantChunks {\n\t\t\tt.Errorf(\"len(r.getChunks(%q)) = %d; want %d\", file, len(chunks), wantChunks)\n\t\t\treturn\n\t\t}\n\t\tf := chunks[0]\n\n\t\tvar gotChunks []*TOCEntry\n\t\tvar last *TOCEntry\n\t\tfor off := int64(0); off < f.Size; off++ {\n\t\t\te, ok := r.ChunkEntryForOffset(file, off)\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"no ChunkEntryForOffset at %d\", off)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif last != e {\n\t\t\t\tgotChunks = append(gotChunks, e)\n\t\t\t\tlast = e\n\t\t\t}\n\t\t}\n\t\tif !reflect.DeepEqual(chunks, gotChunks) {\n\t\t\tt.Errorf(\"gotChunks=%d, want=%d; contents mismatch\", len(gotChunks), wantChunks)\n\t\t}\n\n\t\t// And verify the NextOffset\n\t\tfor i := 0; i < len(gotChunks)-1; i++ {\n\t\t\tci := gotChunks[i]\n\t\t\tcnext := gotChunks[i+1]\n\t\t\tif ci.NextOffset() != cnext.Offset {\n\t\t\t\tt.Errorf(\"chunk %d NextOffset %d != next chunk's Offset of %d\", i, ci.NextOffset(), cnext.Offset)\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc entryHasChildren(dir string, want ...string) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\twant := append([]string(nil), want...)\n\t\tvar got []string\n\t\tent, ok := r.Lookup(dir)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"didn't find TOCEntry for dir node %q\", dir)\n\t\t}\n\t\tfor baseName := range ent.children {\n\t\t\tgot = append(got, baseName)\n\t\t}\n\t\tsort.Strings(got)\n\t\tsort.Strings(want)\n\t\tif !reflect.DeepEqual(got, want) {\n\t\t\tt.Errorf(\"children of %q = %q; want %q\", dir, got, want)\n\t\t}\n\t})\n}\n\nfunc hasDir(file string) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tfor _, ent := range r.toc.Entries {\n\t\t\tif ent.Name == cleanEntryName(file) {\n\t\t\t\tif ent.Type != \"dir\" {\n\t\t\t\t\tt.Errorf(\"file type of %q is %q; want \\\"dir\\\"\", file, ent.Type)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"directory %q not found\", file)\n\t})\n}\n\nfunc hasDirLinkCount(file string, count int) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tfor _, ent := range r.toc.Entries {\n\t\t\tif ent.Name == cleanEntryName(file) {\n\t\t\t\tif ent.Type != \"dir\" {\n\t\t\t\t\tt.Errorf(\"file type of %q is %q; want \\\"dir\\\"\", file, ent.Type)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif ent.NumLink != count {\n\t\t\t\t\tt.Errorf(\"link count of %q = %d; want %d\", file, ent.NumLink, count)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"directory %q not found\", file)\n\t})\n}\n\nfunc hasMode(file string, mode os.FileMode) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tfor _, ent := range r.toc.Entries {\n\t\t\tif ent.Name == cleanEntryName(file) {\n\t\t\t\tif ent.Stat().Mode() != mode {\n\t\t\t\t\tt.Errorf(\"invalid mode: got %v; want %v\", ent.Stat().Mode(), mode)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"file %q not found\", file)\n\t})\n}\n\nfunc hasSymlink(file, target string) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tfor _, ent := range r.toc.Entries {\n\t\t\tif ent.Name == file {\n\t\t\t\tif ent.Type != \"symlink\" {\n\t\t\t\t\tt.Errorf(\"file type of %q is %q; want \\\"symlink\\\"\", file, ent.Type)\n\t\t\t\t} else if ent.LinkName != target {\n\t\t\t\t\tt.Errorf(\"link target of symlink %q is %q; want %q\", file, ent.LinkName, target)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tt.Errorf(\"symlink %q not found\", file)\n\t})\n}\n\nfunc lookupMatch(name string, want *TOCEntry) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\te, ok := r.Lookup(name)\n\t\tif !ok {\n\t\t\tt.Fatalf(\"failed to Lookup entry %q\", name)\n\t\t}\n\t\tif !reflect.DeepEqual(e, want) {\n\t\t\tt.Errorf(\"entry %q mismatch.\\n got: %+v\\nwant: %+v\\n\", name, e, want)\n\t\t}\n\n\t})\n}\n\nfunc hasEntryOwner(entry string, owner owner) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tent, ok := r.Lookup(strings.TrimSuffix(entry, \"/\"))\n\t\tif !ok {\n\t\t\tt.Errorf(\"entry %q not found\", entry)\n\t\t\treturn\n\t\t}\n\t\tif ent.UID != owner.uid || ent.GID != owner.gid {\n\t\t\tt.Errorf(\"entry %q has invalid owner (uid:%d, gid:%d) instead of (uid:%d, gid:%d)\", entry, ent.UID, ent.GID, owner.uid, owner.gid)\n\t\t\treturn\n\t\t}\n\t})\n}\n\nfunc mustSameEntry(files ...string) stargzCheck {\n\treturn stargzCheckFn(func(t *testing.T, r *Reader) {\n\t\tvar first *TOCEntry\n\t\tfor _, f := range files {\n\t\t\tif first == nil {\n\t\t\t\tvar ok bool\n\t\t\t\tfirst, ok = r.Lookup(f)\n\t\t\t\tif !ok {\n\t\t\t\t\tt.Errorf(\"unknown first file on Lookup: %q\", f)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Test Lookup\n\t\t\te, ok := r.Lookup(f)\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"unknown file on Lookup: %q\", f)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif e != first {\n\t\t\t\tt.Errorf(\"Lookup: %+v(%p) != %+v(%p)\", e, e, first, first)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Test LookupChild\n\t\t\tpe, ok := r.Lookup(filepath.Dir(filepath.Clean(f)))\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"failed to get parent of %q\", f)\n\t\t\t\treturn\n\t\t\t}\n\t\t\te, ok = pe.LookupChild(filepath.Base(filepath.Clean(f)))\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"failed to get %q as the child of %+v\", f, pe)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif e != first {\n\t\t\t\tt.Errorf(\"LookupChild: %+v(%p) != %+v(%p)\", e, e, first, first)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Test ForeachChild\n\t\t\tpe.ForeachChild(func(baseName string, e *TOCEntry) bool {\n\t\t\t\tif baseName == filepath.Base(filepath.Clean(f)) {\n\t\t\t\t\tif e != first {\n\t\t\t\t\t\tt.Errorf(\"ForeachChild: %+v(%p) != %+v(%p)\", e, e, first, first)\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\t\t}\n\t})\n}\n\nfunc viewContent(c []byte) string {\n\tif len(c) < 100 {\n\t\treturn string(c)\n\t}\n\treturn string(c[:50]) + \"...(omit)...\" + string(c[50:100])\n}\n\nfunc tarOf(s ...tarEntry) []tarEntry { return s }\n\ntype tarEntry interface {\n\tappendTar(tw *tar.Writer, prefix string, format tar.Format) error\n}\n\ntype tarEntryFunc func(*tar.Writer, string, tar.Format) error\n\nfunc (f tarEntryFunc) appendTar(tw *tar.Writer, prefix string, format tar.Format) error {\n\treturn f(tw, prefix, format)\n}\n\nfunc buildTar(t *testing.T, ents []tarEntry, prefix string, opts ...interface{}) *io.SectionReader {\n\tformat := tar.FormatUnknown\n\tfor _, opt := range opts {\n\t\tswitch v := opt.(type) {\n\t\tcase tar.Format:\n\t\t\tformat = v\n\t\tdefault:\n\t\t\tpanic(fmt.Errorf(\"unsupported opt for buildTar: %v\", opt))\n\t\t}\n\t}\n\tbuf := new(bytes.Buffer)\n\ttw := tar.NewWriter(buf)\n\tfor _, ent := range ents {\n\t\tif err := ent.appendTar(tw, prefix, format); err != nil {\n\t\t\tt.Fatalf(\"building input tar: %v\", err)\n\t\t}\n\t}\n\tif err := tw.Close(); err != nil {\n\t\tt.Errorf(\"closing write of input tar: %v\", err)\n\t}\n\tdata := append(buf.Bytes(), make([]byte, 100)...) // append empty bytes at the tail to see lossless works\n\treturn io.NewSectionReader(bytes.NewReader(data), 0, int64(len(data)))\n}\n\nfunc dir(name string, opts ...interface{}) tarEntry {\n\treturn tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error {\n\t\tvar o owner\n\t\tmode := os.FileMode(0755)\n\t\tfor _, opt := range opts {\n\t\t\tswitch v := opt.(type) {\n\t\t\tcase owner:\n\t\t\t\to = v\n\t\t\tcase os.FileMode:\n\t\t\t\tmode = v\n\t\t\tdefault:\n\t\t\t\treturn errors.New(\"unsupported opt\")\n\t\t\t}\n\t\t}\n\t\tif !strings.HasSuffix(name, \"/\") {\n\t\t\tpanic(fmt.Sprintf(\"missing trailing slash in dir %q \", name))\n\t\t}\n\t\ttm, err := fileModeToTarMode(mode)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn tw.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeDir,\n\t\t\tName:     prefix + name,\n\t\t\tMode:     tm,\n\t\t\tUid:      o.uid,\n\t\t\tGid:      o.gid,\n\t\t\tFormat:   format,\n\t\t})\n\t})\n}\n\n// xAttr are extended attributes to set on test files created with the file func.\ntype xAttr map[string]string\n\n// owner is owner ot set on test files and directories with the file and dir functions.\ntype owner struct {\n\tuid int\n\tgid int\n}\n\nfunc file(name, contents string, opts ...interface{}) tarEntry {\n\treturn tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error {\n\t\tvar xattrs xAttr\n\t\tvar o owner\n\t\tmode := os.FileMode(0644)\n\t\tfor _, opt := range opts {\n\t\t\tswitch v := opt.(type) {\n\t\t\tcase xAttr:\n\t\t\t\txattrs = v\n\t\t\tcase owner:\n\t\t\t\to = v\n\t\t\tcase os.FileMode:\n\t\t\t\tmode = v\n\t\t\tdefault:\n\t\t\t\treturn errors.New(\"unsupported opt\")\n\t\t\t}\n\t\t}\n\t\tif strings.HasSuffix(name, \"/\") {\n\t\t\treturn fmt.Errorf(\"bogus trailing slash in file %q\", name)\n\t\t}\n\t\ttm, err := fileModeToTarMode(mode)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(xattrs) > 0 {\n\t\t\tformat = tar.FormatPAX // only PAX supports xattrs\n\t\t}\n\t\tif err := tw.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeReg,\n\t\t\tName:     prefix + name,\n\t\t\tMode:     tm,\n\t\t\tXattrs:   xattrs,\n\t\t\tSize:     int64(len(contents)),\n\t\t\tUid:      o.uid,\n\t\t\tGid:      o.gid,\n\t\t\tFormat:   format,\n\t\t}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = io.WriteString(tw, contents)\n\t\treturn err\n\t})\n}\n\nfunc symlink(name, target string) tarEntry {\n\treturn tarEntryFunc(func(tw *tar.Writer, prefix string, format tar.Format) error {\n\t\treturn tw.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeSymlink,\n\t\t\tName:     prefix + name,\n\t\t\tLinkname: target,\n\t\t\tMode:     0644,\n\t\t\tFormat:   format,\n\t\t})\n\t})\n}\n\nfunc link(name string, linkname string) tarEntry {\n\tnow := time.Now()\n\treturn tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\treturn w.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeLink,\n\t\t\tName:     prefix + name,\n\t\t\tLinkname: linkname,\n\t\t\tModTime:  now,\n\t\t\tFormat:   format,\n\t\t})\n\t})\n}\n\nfunc chardev(name string, major, minor int64) tarEntry {\n\tnow := time.Now()\n\treturn tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\treturn w.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeChar,\n\t\t\tName:     prefix + name,\n\t\t\tDevmajor: major,\n\t\t\tDevminor: minor,\n\t\t\tModTime:  now,\n\t\t\tFormat:   format,\n\t\t})\n\t})\n}\n\nfunc blockdev(name string, major, minor int64) tarEntry {\n\tnow := time.Now()\n\treturn tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\treturn w.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeBlock,\n\t\t\tName:     prefix + name,\n\t\t\tDevmajor: major,\n\t\t\tDevminor: minor,\n\t\t\tModTime:  now,\n\t\t\tFormat:   format,\n\t\t})\n\t})\n}\nfunc fifo(name string) tarEntry {\n\tnow := time.Now()\n\treturn tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\treturn w.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeFifo,\n\t\t\tName:     prefix + name,\n\t\t\tModTime:  now,\n\t\t\tFormat:   format,\n\t\t})\n\t})\n}\n\nfunc prefetchLandmark() tarEntry {\n\treturn tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\tif err := w.WriteHeader(&tar.Header{\n\t\t\tName:     PrefetchLandmark,\n\t\t\tTypeflag: tar.TypeReg,\n\t\t\tSize:     int64(len([]byte{landmarkContents})),\n\t\t\tFormat:   format,\n\t\t}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcontents := []byte{landmarkContents}\n\t\tif _, err := io.CopyN(w, bytes.NewReader(contents), int64(len(contents))); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc noPrefetchLandmark() tarEntry {\n\treturn tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\tif err := w.WriteHeader(&tar.Header{\n\t\t\tName:     NoPrefetchLandmark,\n\t\t\tTypeflag: tar.TypeReg,\n\t\t\tSize:     int64(len([]byte{landmarkContents})),\n\t\t\tFormat:   format,\n\t\t}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcontents := []byte{landmarkContents}\n\t\tif _, err := io.CopyN(w, bytes.NewReader(contents), int64(len(contents))); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc regDigest(t *testing.T, name string, contentStr string, digestMap map[string]digest.Digest) tarEntry {\n\tif digestMap == nil {\n\t\tt.Fatalf(\"digest map mustn't be nil\")\n\t}\n\tcontent := []byte(contentStr)\n\n\tvar n int64\n\tfor n < int64(len(content)) {\n\t\tsize := int64(chunkSize)\n\t\tremain := int64(len(content)) - n\n\t\tif remain < size {\n\t\t\tsize = remain\n\t\t}\n\t\tdgstr := digest.Canonical.Digester()\n\t\tif _, err := io.CopyN(dgstr.Hash(), bytes.NewReader(content[n:n+size]), size); err != nil {\n\t\t\tt.Fatalf(\"failed to calculate digest of %q (name=%q,offset=%d,size=%d)\",\n\t\t\t\tstring(content[n:n+size]), name, n, size)\n\t\t}\n\t\tdigestMap[chunkID(name, n, size)] = dgstr.Digest()\n\t\tn += size\n\t}\n\n\treturn tarEntryFunc(func(w *tar.Writer, prefix string, format tar.Format) error {\n\t\tif err := w.WriteHeader(&tar.Header{\n\t\t\tTypeflag: tar.TypeReg,\n\t\t\tName:     prefix + name,\n\t\t\tSize:     int64(len(content)),\n\t\t\tFormat:   format,\n\t\t}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := io.CopyN(w, bytes.NewReader(content), int64(len(content))); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t})\n}\n\nvar runes = []rune(\"1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\")\n\nfunc randomContents(n int) string {\n\tb := make([]rune, n)\n\tfor i := range b {\n\t\tb[i] = runes[rand.Intn(len(runes))]\n\t}\n\treturn string(b)\n}\n\nfunc fileModeToTarMode(mode os.FileMode) (int64, error) {\n\th, err := tar.FileInfoHeader(fileInfoOnlyMode(mode), \"\")\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn h.Mode, nil\n}\n\n// fileInfoOnlyMode is os.FileMode that populates only file mode.\ntype fileInfoOnlyMode os.FileMode\n\nfunc (f fileInfoOnlyMode) Name() string       { return \"\" }\nfunc (f fileInfoOnlyMode) Size() int64        { return 0 }\nfunc (f fileInfoOnlyMode) Mode() os.FileMode  { return os.FileMode(f) }\nfunc (f fileInfoOnlyMode) ModTime() time.Time { return time.Now() }\nfunc (f fileInfoOnlyMode) IsDir() bool        { return os.FileMode(f).IsDir() }\nfunc (f fileInfoOnlyMode) Sys() interface{}   { return nil }\n\nfunc CheckGzipHasStreams(t *testing.T, b []byte, streams []int64) {\n\tif len(streams) == 0 {\n\t\treturn // nop\n\t}\n\n\twants := map[int64]struct{}{}\n\tfor _, s := range streams {\n\t\twants[s] = struct{}{}\n\t}\n\n\tlen0 := len(b)\n\tbr := bytes.NewReader(b)\n\tzr := new(gzip.Reader)\n\tt.Logf(\"got gzip streams:\")\n\tnumStreams := 0\n\tfor {\n\t\tzoff := len0 - br.Len()\n\t\tif err := zr.Reset(br); err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tt.Fatalf(\"countStreams(gzip), Reset: %v\", err)\n\t\t}\n\t\tzr.Multistream(false)\n\t\tn, err := io.Copy(io.Discard, zr)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"countStreams(gzip), Copy: %v\", err)\n\t\t}\n\t\tvar extra string\n\t\tif len(zr.Header.Extra) > 0 {\n\t\t\textra = fmt.Sprintf(\"; extra=%q\", zr.Header.Extra)\n\t\t}\n\t\tt.Logf(\"  [%d] at %d in stargz, uncompressed length %d%s\", numStreams, zoff, n, extra)\n\t\tdelete(wants, int64(zoff))\n\t\tnumStreams++\n\t}\n}\n\nfunc GzipDiffIDOf(t *testing.T, b []byte) string {\n\th := sha256.New()\n\tzr, err := gzip.NewReader(bytes.NewReader(b))\n\tif err != nil {\n\t\tt.Fatalf(\"diffIDOf(gzip): %v\", err)\n\t}\n\tdefer zr.Close()\n\tif _, err := io.Copy(h, zr); err != nil {\n\t\tt.Fatalf(\"diffIDOf(gzip).Copy: %v\", err)\n\t}\n\treturn fmt.Sprintf(\"sha256:%x\", h.Sum(nil))\n}\n"
  },
  {
    "path": "vendor/github.com/containerd/stargz-snapshotter/estargz/types.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\n/*\n   Copyright 2019 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\npackage estargz\n\nimport (\n\t\"archive/tar\"\n\t\"hash\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"time\"\n\n\tdigest \"github.com/opencontainers/go-digest\"\n)\n\nconst (\n\t// TOCTarName is the name of the JSON file in the tar archive in the\n\t// table of contents gzip stream.\n\tTOCTarName = \"stargz.index.json\"\n\n\t// FooterSize is the number of bytes in the footer\n\t//\n\t// The footer is an empty gzip stream with no compression and an Extra\n\t// header of the form \"%016xSTARGZ\", where the 64 bit hex-encoded\n\t// number is the offset to the gzip stream of JSON TOC.\n\t//\n\t// 51 comes from:\n\t//\n\t// 10 bytes  gzip header\n\t// 2  bytes  XLEN (length of Extra field) = 26 (4 bytes header + 16 hex digits + len(\"STARGZ\"))\n\t// 2  bytes  Extra: SI1 = 'S', SI2 = 'G'\n\t// 2  bytes  Extra: LEN = 22 (16 hex digits + len(\"STARGZ\"))\n\t// 22 bytes  Extra: subfield = fmt.Sprintf(\"%016xSTARGZ\", offsetOfTOC)\n\t// 5  bytes  flate header\n\t// 8  bytes  gzip footer\n\t// (End of the eStargz blob)\n\t//\n\t// NOTE: For Extra fields, subfield IDs SI1='S' SI2='G' is used for eStargz.\n\tFooterSize = 51\n\n\t// legacyFooterSize is the number of bytes in the legacy stargz footer.\n\t//\n\t// 47 comes from:\n\t//\n\t//   10 byte gzip header +\n\t//   2 byte (LE16) length of extra, encoding 22 (16 hex digits + len(\"STARGZ\")) == \"\\x16\\x00\" +\n\t//   22 bytes of extra (fmt.Sprintf(\"%016xSTARGZ\", tocGzipOffset))\n\t//   5 byte flate header\n\t//   8 byte gzip footer (two little endian uint32s: digest, size)\n\tlegacyFooterSize = 47\n\n\t// TOCJSONDigestAnnotation is an annotation for an image layer. This stores the\n\t// digest of the TOC JSON.\n\t// This annotation is valid only when it is specified in `.[]layers.annotations`\n\t// of an image manifest.\n\tTOCJSONDigestAnnotation = \"containerd.io/snapshot/stargz/toc.digest\"\n\n\t// StoreUncompressedSizeAnnotation is an additional annotation key for eStargz to enable lazy\n\t// pulling on containers/storage. Stargz Store is required to expose the layer's uncompressed size\n\t// to the runtime but current OCI image doesn't ship this information by default. So we store this\n\t// to the special annotation.\n\tStoreUncompressedSizeAnnotation = \"io.containers.estargz.uncompressed-size\"\n\n\t// PrefetchLandmark is a file entry which indicates the end position of\n\t// prefetch in the stargz file.\n\tPrefetchLandmark = \".prefetch.landmark\"\n\n\t// NoPrefetchLandmark is a file entry which indicates that no prefetch should\n\t// occur in the stargz file.\n\tNoPrefetchLandmark = \".no.prefetch.landmark\"\n\n\tlandmarkContents = 0xf\n)\n\n// JTOC is the JSON-serialized table of contents index of the files in the stargz file.\ntype JTOC struct {\n\tVersion int         `json:\"version\"`\n\tEntries []*TOCEntry `json:\"entries\"`\n}\n\n// TOCEntry is an entry in the stargz file's TOC (Table of Contents).\ntype TOCEntry struct {\n\t// Name is the tar entry's name. It is the complete path\n\t// stored in the tar file, not just the base name.\n\tName string `json:\"name\"`\n\n\t// Type is one of \"dir\", \"reg\", \"symlink\", \"hardlink\", \"char\",\n\t// \"block\", \"fifo\", or \"chunk\".\n\t// The \"chunk\" type is used for regular file data chunks past the first\n\t// TOCEntry; the 2nd chunk and on have only Type (\"chunk\"), Offset,\n\t// ChunkOffset, and ChunkSize populated.\n\tType string `json:\"type\"`\n\n\t// Size, for regular files, is the logical size of the file.\n\tSize int64 `json:\"size,omitempty\"`\n\n\t// ModTime3339 is the modification time of the tar entry. Empty\n\t// means zero or unknown. Otherwise it's in UTC RFC3339\n\t// format. Use the ModTime method to access the time.Time value.\n\tModTime3339 string `json:\"modtime,omitempty\"`\n\tmodTime     time.Time\n\n\t// LinkName, for symlinks and hardlinks, is the link target.\n\tLinkName string `json:\"linkName,omitempty\"`\n\n\t// Mode is the permission and mode bits.\n\tMode int64 `json:\"mode,omitempty\"`\n\n\t// UID is the user ID of the owner.\n\tUID int `json:\"uid,omitempty\"`\n\n\t// GID is the group ID of the owner.\n\tGID int `json:\"gid,omitempty\"`\n\n\t// Uname is the username of the owner.\n\t//\n\t// In the serialized JSON, this field may only be present for\n\t// the first entry with the same UID.\n\tUname string `json:\"userName,omitempty\"`\n\n\t// Gname is the group name of the owner.\n\t//\n\t// In the serialized JSON, this field may only be present for\n\t// the first entry with the same GID.\n\tGname string `json:\"groupName,omitempty\"`\n\n\t// Offset, for regular files, provides the offset in the\n\t// stargz file to the file's data bytes. See ChunkOffset and\n\t// ChunkSize.\n\tOffset int64 `json:\"offset,omitempty\"`\n\n\t// InnerOffset is an optional field indicates uncompressed offset\n\t// of this \"reg\" or \"chunk\" payload in a stream starts from Offset.\n\t// This field enables to put multiple \"reg\" or \"chunk\" payloads\n\t// in one chunk with having the same Offset but different InnerOffset.\n\tInnerOffset int64 `json:\"innerOffset,omitempty\"`\n\n\tnextOffset int64 // the Offset of the next entry with a non-zero Offset\n\n\t// DevMajor is the major device number for \"char\" and \"block\" types.\n\tDevMajor int `json:\"devMajor,omitempty\"`\n\n\t// DevMinor is the major device number for \"char\" and \"block\" types.\n\tDevMinor int `json:\"devMinor,omitempty\"`\n\n\t// NumLink is the number of entry names pointing to this entry.\n\t// Zero means one name references this entry.\n\t// This field is calculated during runtime and not recorded in TOC JSON.\n\tNumLink int `json:\"-\"`\n\n\t// Xattrs are the extended attribute for the entry.\n\tXattrs map[string][]byte `json:\"xattrs,omitempty\"`\n\n\t// Digest stores the OCI checksum for regular files payload.\n\t// It has the form \"sha256:abcdef01234....\".\n\tDigest string `json:\"digest,omitempty\"`\n\n\t// ChunkOffset is non-zero if this is a chunk of a large,\n\t// regular file. If so, the Offset is where the gzip header of\n\t// ChunkSize bytes at ChunkOffset in Name begin.\n\t//\n\t// In serialized form, a \"chunkSize\" JSON field of zero means\n\t// that the chunk goes to the end of the file. After reading\n\t// from the stargz TOC, though, the ChunkSize is initialized\n\t// to a non-zero file for when Type is either \"reg\" or\n\t// \"chunk\".\n\tChunkOffset int64 `json:\"chunkOffset,omitempty\"`\n\tChunkSize   int64 `json:\"chunkSize,omitempty\"`\n\n\t// ChunkDigest stores an OCI digest of the chunk. This must be formed\n\t// as \"sha256:0123abcd...\".\n\tChunkDigest string `json:\"chunkDigest,omitempty\"`\n\n\tchildren map[string]*TOCEntry\n\n\t// chunkTopIndex is index of the entry where Offset starts in the blob.\n\tchunkTopIndex int\n}\n\n// ModTime returns the entry's modification time.\nfunc (e *TOCEntry) ModTime() time.Time { return e.modTime }\n\n// NextOffset returns the position (relative to the start of the\n// stargz file) of the next gzip boundary after e.Offset.\nfunc (e *TOCEntry) NextOffset() int64 { return e.nextOffset }\n\nfunc (e *TOCEntry) addChild(baseName string, child *TOCEntry) {\n\tif e.children == nil {\n\t\te.children = make(map[string]*TOCEntry)\n\t}\n\tif child.Type == \"dir\" {\n\t\te.NumLink++ // Entry \"..\" in the subdirectory links to this directory\n\t}\n\te.children[baseName] = child\n}\n\n// isDataType reports whether TOCEntry is a regular file or chunk (something that\n// contains regular file data).\nfunc (e *TOCEntry) isDataType() bool { return e.Type == \"reg\" || e.Type == \"chunk\" }\n\n// Stat returns a FileInfo value representing e.\nfunc (e *TOCEntry) Stat() os.FileInfo { return fileInfo{e} }\n\n// ForeachChild calls f for each child item. If f returns false, iteration ends.\n// If e is not a directory, f is not called.\nfunc (e *TOCEntry) ForeachChild(f func(baseName string, ent *TOCEntry) bool) {\n\tfor name, ent := range e.children {\n\t\tif !f(name, ent) {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// LookupChild returns the directory e's child by its base name.\nfunc (e *TOCEntry) LookupChild(baseName string) (child *TOCEntry, ok bool) {\n\tchild, ok = e.children[baseName]\n\treturn\n}\n\n// fileInfo implements os.FileInfo using the wrapped *TOCEntry.\ntype fileInfo struct{ e *TOCEntry }\n\nvar _ os.FileInfo = fileInfo{}\n\nfunc (fi fileInfo) Name() string       { return path.Base(fi.e.Name) }\nfunc (fi fileInfo) IsDir() bool        { return fi.e.Type == \"dir\" }\nfunc (fi fileInfo) Size() int64        { return fi.e.Size }\nfunc (fi fileInfo) ModTime() time.Time { return fi.e.ModTime() }\nfunc (fi fileInfo) Sys() interface{}   { return fi.e }\nfunc (fi fileInfo) Mode() (m os.FileMode) {\n\t// TOCEntry.Mode is tar.Header.Mode so we can understand the these bits using `tar` pkg.\n\tm = (&tar.Header{Mode: fi.e.Mode}).FileInfo().Mode() &\n\t\t(os.ModePerm | os.ModeSetuid | os.ModeSetgid | os.ModeSticky)\n\tswitch fi.e.Type {\n\tcase \"dir\":\n\t\tm |= os.ModeDir\n\tcase \"symlink\":\n\t\tm |= os.ModeSymlink\n\tcase \"char\":\n\t\tm |= os.ModeDevice | os.ModeCharDevice\n\tcase \"block\":\n\t\tm |= os.ModeDevice\n\tcase \"fifo\":\n\t\tm |= os.ModeNamedPipe\n\t}\n\treturn m\n}\n\n// TOCEntryVerifier holds verifiers that are usable for verifying chunks contained\n// in a eStargz blob.\ntype TOCEntryVerifier interface {\n\n\t// Verifier provides a content verifier that can be used for verifying the\n\t// contents of the specified TOCEntry.\n\tVerifier(ce *TOCEntry) (digest.Verifier, error)\n}\n\n// Compression provides the compression helper to be used creating and parsing eStargz.\n// This package provides gzip-based Compression by default, but any compression\n// algorithm (e.g. zstd) can be used as long as it implements Compression.\ntype Compression interface {\n\tCompressor\n\tDecompressor\n}\n\n// Compressor represents the helper mothods to be used for creating eStargz.\ntype Compressor interface {\n\t// Writer returns WriteCloser to be used for writing a chunk to eStargz.\n\t// Everytime a chunk is written, the WriteCloser is closed and Writer is\n\t// called again for writing the next chunk.\n\t//\n\t// The returned writer should implement \"Flush() error\" function that flushes\n\t// any pending compressed data to the underlying writer.\n\tWriter(w io.Writer) (WriteFlushCloser, error)\n\n\t// WriteTOCAndFooter is called to write JTOC to the passed Writer.\n\t// diffHash calculates the DiffID (uncompressed sha256 hash) of the blob\n\t// WriteTOCAndFooter can optionally write anything that affects DiffID calculation\n\t// (e.g. uncompressed TOC JSON).\n\t//\n\t// This function returns tocDgst that represents the digest of TOC that will be used\n\t// to verify this blob when it's parsed.\n\tWriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (tocDgst digest.Digest, err error)\n}\n\n// Decompressor represents the helper mothods to be used for parsing eStargz.\ntype Decompressor interface {\n\t// Reader returns ReadCloser to be used for decompressing file payload.\n\tReader(r io.Reader) (io.ReadCloser, error)\n\n\t// FooterSize returns the size of the footer of this blob.\n\tFooterSize() int64\n\n\t// ParseFooter parses the footer and returns the offset and (compressed) size of TOC.\n\t// payloadBlobSize is the (compressed) size of the blob payload (i.e. the size between\n\t// the top until the TOC JSON).\n\t//\n\t// If tocOffset < 0, we assume that TOC isn't contained in the blob and pass nil reader\n\t// to ParseTOC. We expect that ParseTOC acquire TOC from the external location and return it.\n\t//\n\t// tocSize is optional. If tocSize <= 0, it's by default the size of the range from tocOffset until the beginning of the\n\t// footer (blob size - tocOff - FooterSize).\n\t// If blobPayloadSize < 0, blobPayloadSize become the blob size.\n\tParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error)\n\n\t// ParseTOC parses TOC from the passed reader. The reader provides the partial contents\n\t// of the underlying blob that has the range specified by ParseFooter method.\n\t//\n\t// This function returns tocDgst that represents the digest of TOC that will be used\n\t// to verify this blob. This must match to the value returned from\n\t// Compressor.WriteTOCAndFooter that is used when creating this blob.\n\t//\n\t// If tocOffset returned by ParseFooter is < 0, we assume that TOC isn't contained in the blob.\n\t// Pass nil reader to ParseTOC then we expect that ParseTOC acquire TOC from the external location\n\t// and return it.\n\tParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error)\n}\n\ntype WriteFlushCloser interface {\n\tio.WriteCloser\n\tFlush() error\n}\n"
  },
  {
    "path": "vendor/github.com/cpuguy83/go-md2man/v2/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Brian Goff\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": "vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go",
    "content": "package md2man\n\nimport (\n\t\"github.com/russross/blackfriday/v2\"\n)\n\n// Render converts a markdown document into a roff formatted document.\nfunc Render(doc []byte) []byte {\n\trenderer := NewRoffRenderer()\n\n\treturn blackfriday.Run(doc,\n\t\t[]blackfriday.Option{\n\t\t\tblackfriday.WithRenderer(renderer),\n\t\t\tblackfriday.WithExtensions(renderer.GetExtensions()),\n\t\t}...)\n}\n"
  },
  {
    "path": "vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go",
    "content": "package md2man\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/russross/blackfriday/v2\"\n)\n\n// roffRenderer implements the blackfriday.Renderer interface for creating\n// roff format (manpages) from markdown text\ntype roffRenderer struct {\n\textensions   blackfriday.Extensions\n\tlistCounters []int\n\tfirstHeader  bool\n\tfirstDD      bool\n\tlistDepth    int\n}\n\nconst (\n\ttitleHeader      = \".TH \"\n\ttopLevelHeader   = \"\\n\\n.SH \"\n\tsecondLevelHdr   = \"\\n.SH \"\n\totherHeader      = \"\\n.SS \"\n\tcrTag            = \"\\n\"\n\temphTag          = \"\\\\fI\"\n\temphCloseTag     = \"\\\\fP\"\n\tstrongTag        = \"\\\\fB\"\n\tstrongCloseTag   = \"\\\\fP\"\n\tbreakTag         = \"\\n.br\\n\"\n\tparaTag          = \"\\n.PP\\n\"\n\thruleTag         = \"\\n.ti 0\\n\\\\l'\\\\n(.lu'\\n\"\n\tlinkTag          = \"\\n\\\\[la]\"\n\tlinkCloseTag     = \"\\\\[ra]\"\n\tcodespanTag      = \"\\\\fB\"\n\tcodespanCloseTag = \"\\\\fR\"\n\tcodeTag          = \"\\n.EX\\n\"\n\tcodeCloseTag     = \"\\n.EE\\n\"\n\tquoteTag         = \"\\n.PP\\n.RS\\n\"\n\tquoteCloseTag    = \"\\n.RE\\n\"\n\tlistTag          = \"\\n.RS\\n\"\n\tlistCloseTag     = \"\\n.RE\\n\"\n\tdtTag            = \"\\n.TP\\n\"\n\tdd2Tag           = \"\\n\"\n\ttableStart       = \"\\n.TS\\nallbox;\\n\"\n\ttableEnd         = \".TE\\n\"\n\ttableCellStart   = \"T{\\n\"\n\ttableCellEnd     = \"\\nT}\\n\"\n)\n\n// NewRoffRenderer creates a new blackfriday Renderer for generating roff documents\n// from markdown\nfunc NewRoffRenderer() *roffRenderer { // nolint: golint\n\tvar extensions blackfriday.Extensions\n\n\textensions |= blackfriday.NoIntraEmphasis\n\textensions |= blackfriday.Tables\n\textensions |= blackfriday.FencedCode\n\textensions |= blackfriday.SpaceHeadings\n\textensions |= blackfriday.Footnotes\n\textensions |= blackfriday.Titleblock\n\textensions |= blackfriday.DefinitionLists\n\treturn &roffRenderer{\n\t\textensions: extensions,\n\t}\n}\n\n// GetExtensions returns the list of extensions used by this renderer implementation\nfunc (r *roffRenderer) GetExtensions() blackfriday.Extensions {\n\treturn r.extensions\n}\n\n// RenderHeader handles outputting the header at document start\nfunc (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) {\n\t// disable hyphenation\n\tout(w, \".nh\\n\")\n}\n\n// RenderFooter handles outputting the footer at the document end; the roff\n// renderer has no footer information\nfunc (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {\n}\n\n// RenderNode is called for each node in a markdown document; based on the node\n// type the equivalent roff output is sent to the writer\nfunc (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {\n\twalkAction := blackfriday.GoToNext\n\n\tswitch node.Type {\n\tcase blackfriday.Text:\n\t\tescapeSpecialChars(w, node.Literal)\n\tcase blackfriday.Softbreak:\n\t\tout(w, crTag)\n\tcase blackfriday.Hardbreak:\n\t\tout(w, breakTag)\n\tcase blackfriday.Emph:\n\t\tif entering {\n\t\t\tout(w, emphTag)\n\t\t} else {\n\t\t\tout(w, emphCloseTag)\n\t\t}\n\tcase blackfriday.Strong:\n\t\tif entering {\n\t\t\tout(w, strongTag)\n\t\t} else {\n\t\t\tout(w, strongCloseTag)\n\t\t}\n\tcase blackfriday.Link:\n\t\t// Don't render the link text for automatic links, because this\n\t\t// will only duplicate the URL in the roff output.\n\t\t// See https://daringfireball.net/projects/markdown/syntax#autolink\n\t\tif !bytes.Equal(node.LinkData.Destination, node.FirstChild.Literal) {\n\t\t\tout(w, string(node.FirstChild.Literal))\n\t\t}\n\t\t// Hyphens in a link must be escaped to avoid word-wrap in the rendered man page.\n\t\tescapedLink := strings.ReplaceAll(string(node.LinkData.Destination), \"-\", \"\\\\-\")\n\t\tout(w, linkTag+escapedLink+linkCloseTag)\n\t\twalkAction = blackfriday.SkipChildren\n\tcase blackfriday.Image:\n\t\t// ignore images\n\t\twalkAction = blackfriday.SkipChildren\n\tcase blackfriday.Code:\n\t\tout(w, codespanTag)\n\t\tescapeSpecialChars(w, node.Literal)\n\t\tout(w, codespanCloseTag)\n\tcase blackfriday.Document:\n\t\tbreak\n\tcase blackfriday.Paragraph:\n\t\t// roff .PP markers break lists\n\t\tif r.listDepth > 0 {\n\t\t\treturn blackfriday.GoToNext\n\t\t}\n\t\tif entering {\n\t\t\tout(w, paraTag)\n\t\t} else {\n\t\t\tout(w, crTag)\n\t\t}\n\tcase blackfriday.BlockQuote:\n\t\tif entering {\n\t\t\tout(w, quoteTag)\n\t\t} else {\n\t\t\tout(w, quoteCloseTag)\n\t\t}\n\tcase blackfriday.Heading:\n\t\tr.handleHeading(w, node, entering)\n\tcase blackfriday.HorizontalRule:\n\t\tout(w, hruleTag)\n\tcase blackfriday.List:\n\t\tr.handleList(w, node, entering)\n\tcase blackfriday.Item:\n\t\tr.handleItem(w, node, entering)\n\tcase blackfriday.CodeBlock:\n\t\tout(w, codeTag)\n\t\tescapeSpecialChars(w, node.Literal)\n\t\tout(w, codeCloseTag)\n\tcase blackfriday.Table:\n\t\tr.handleTable(w, node, entering)\n\tcase blackfriday.TableHead:\n\tcase blackfriday.TableBody:\n\tcase blackfriday.TableRow:\n\t\t// no action as cell entries do all the nroff formatting\n\t\treturn blackfriday.GoToNext\n\tcase blackfriday.TableCell:\n\t\tr.handleTableCell(w, node, entering)\n\tcase blackfriday.HTMLSpan:\n\t\t// ignore other HTML tags\n\tcase blackfriday.HTMLBlock:\n\t\tif bytes.HasPrefix(node.Literal, []byte(\"<!--\")) {\n\t\t\tbreak // ignore comments, no warning\n\t\t}\n\t\tfmt.Fprintln(os.Stderr, \"WARNING: go-md2man does not handle node type \"+node.Type.String())\n\tdefault:\n\t\tfmt.Fprintln(os.Stderr, \"WARNING: go-md2man does not handle node type \"+node.Type.String())\n\t}\n\treturn walkAction\n}\n\nfunc (r *roffRenderer) handleHeading(w io.Writer, node *blackfriday.Node, entering bool) {\n\tif entering {\n\t\tswitch node.Level {\n\t\tcase 1:\n\t\t\tif !r.firstHeader {\n\t\t\t\tout(w, titleHeader)\n\t\t\t\tr.firstHeader = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tout(w, topLevelHeader)\n\t\tcase 2:\n\t\t\tout(w, secondLevelHdr)\n\t\tdefault:\n\t\t\tout(w, otherHeader)\n\t\t}\n\t}\n}\n\nfunc (r *roffRenderer) handleList(w io.Writer, node *blackfriday.Node, entering bool) {\n\topenTag := listTag\n\tcloseTag := listCloseTag\n\tif node.ListFlags&blackfriday.ListTypeDefinition != 0 {\n\t\t// tags for definition lists handled within Item node\n\t\topenTag = \"\"\n\t\tcloseTag = \"\"\n\t}\n\tif entering {\n\t\tr.listDepth++\n\t\tif node.ListFlags&blackfriday.ListTypeOrdered != 0 {\n\t\t\tr.listCounters = append(r.listCounters, 1)\n\t\t}\n\t\tout(w, openTag)\n\t} else {\n\t\tif node.ListFlags&blackfriday.ListTypeOrdered != 0 {\n\t\t\tr.listCounters = r.listCounters[:len(r.listCounters)-1]\n\t\t}\n\t\tout(w, closeTag)\n\t\tr.listDepth--\n\t}\n}\n\nfunc (r *roffRenderer) handleItem(w io.Writer, node *blackfriday.Node, entering bool) {\n\tif entering {\n\t\tif node.ListFlags&blackfriday.ListTypeOrdered != 0 {\n\t\t\tout(w, fmt.Sprintf(\".IP \\\"%3d.\\\" 5\\n\", r.listCounters[len(r.listCounters)-1]))\n\t\t\tr.listCounters[len(r.listCounters)-1]++\n\t\t} else if node.ListFlags&blackfriday.ListTypeTerm != 0 {\n\t\t\t// DT (definition term): line just before DD (see below).\n\t\t\tout(w, dtTag)\n\t\t\tr.firstDD = true\n\t\t} else if node.ListFlags&blackfriday.ListTypeDefinition != 0 {\n\t\t\t// DD (definition description): line that starts with \": \".\n\t\t\t//\n\t\t\t// We have to distinguish between the first DD and the\n\t\t\t// subsequent ones, as there should be no vertical\n\t\t\t// whitespace between the DT and the first DD.\n\t\t\tif r.firstDD {\n\t\t\t\tr.firstDD = false\n\t\t\t} else {\n\t\t\t\tout(w, dd2Tag)\n\t\t\t}\n\t\t} else {\n\t\t\tout(w, \".IP \\\\(bu 2\\n\")\n\t\t}\n\t} else {\n\t\tout(w, \"\\n\")\n\t}\n}\n\nfunc (r *roffRenderer) handleTable(w io.Writer, node *blackfriday.Node, entering bool) {\n\tif entering {\n\t\tout(w, tableStart)\n\t\t// call walker to count cells (and rows?) so format section can be produced\n\t\tcolumns := countColumns(node)\n\t\tout(w, strings.Repeat(\"l \", columns)+\"\\n\")\n\t\tout(w, strings.Repeat(\"l \", columns)+\".\\n\")\n\t} else {\n\t\tout(w, tableEnd)\n\t}\n}\n\nfunc (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, entering bool) {\n\tif entering {\n\t\tvar start string\n\t\tif node.Prev != nil && node.Prev.Type == blackfriday.TableCell {\n\t\t\tstart = \"\\t\"\n\t\t}\n\t\tif node.IsHeader {\n\t\t\tstart += strongTag\n\t\t} else if nodeLiteralSize(node) > 30 {\n\t\t\tstart += tableCellStart\n\t\t}\n\t\tout(w, start)\n\t} else {\n\t\tvar end string\n\t\tif node.IsHeader {\n\t\t\tend = strongCloseTag\n\t\t} else if nodeLiteralSize(node) > 30 {\n\t\t\tend = tableCellEnd\n\t\t}\n\t\tif node.Next == nil && end != tableCellEnd {\n\t\t\t// Last cell: need to carriage return if we are at the end of the\n\t\t\t// header row and content isn't wrapped in a \"tablecell\"\n\t\t\tend += crTag\n\t\t}\n\t\tout(w, end)\n\t}\n}\n\nfunc nodeLiteralSize(node *blackfriday.Node) int {\n\ttotal := 0\n\tfor n := node.FirstChild; n != nil; n = n.FirstChild {\n\t\ttotal += len(n.Literal)\n\t}\n\treturn total\n}\n\n// because roff format requires knowing the column count before outputting any table\n// data we need to walk a table tree and count the columns\nfunc countColumns(node *blackfriday.Node) int {\n\tvar columns int\n\n\tnode.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus {\n\t\tswitch node.Type {\n\t\tcase blackfriday.TableRow:\n\t\t\tif !entering {\n\t\t\t\treturn blackfriday.Terminate\n\t\t\t}\n\t\tcase blackfriday.TableCell:\n\t\t\tif entering {\n\t\t\t\tcolumns++\n\t\t\t}\n\t\tdefault:\n\t\t}\n\t\treturn blackfriday.GoToNext\n\t})\n\treturn columns\n}\n\nfunc out(w io.Writer, output string) {\n\tio.WriteString(w, output) // nolint: errcheck\n}\n\nfunc escapeSpecialChars(w io.Writer, text []byte) {\n\tfor i := 0; i < len(text); i++ {\n\t\t// escape initial apostrophe or period\n\t\tif len(text) >= 1 && (text[0] == '\\'' || text[0] == '.') {\n\t\t\tout(w, \"\\\\&\")\n\t\t}\n\n\t\t// directly copy normal characters\n\t\torg := i\n\n\t\tfor i < len(text) && text[i] != '\\\\' {\n\t\t\ti++\n\t\t}\n\t\tif i > org {\n\t\t\tw.Write(text[org:i]) // nolint: errcheck\n\t\t}\n\n\t\t// escape a character\n\t\tif i >= len(text) {\n\t\t\tbreak\n\t\t}\n\n\t\tw.Write([]byte{'\\\\', text[i]}) // nolint: errcheck\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/LICENSE",
    "content": "ISC License\n\nCopyright (c) 2012-2016 Dave Collins <dave@davec.name>\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/bypass.go",
    "content": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// NOTE: Due to the following build constraints, this file will only be compiled\n// when the code is not running on Google App Engine, compiled by GopherJS, and\n// \"-tags safe\" is not added to the go build command line.  The \"disableunsafe\"\n// tag is deprecated and thus should not be used.\n// Go versions prior to 1.4 are disabled because they use a different layout\n// for interfaces which make the implementation of unsafeReflectValue more complex.\n// +build !js,!appengine,!safe,!disableunsafe,go1.4\n\npackage spew\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\nconst (\n\t// UnsafeDisabled is a build-time constant which specifies whether or\n\t// not access to the unsafe package is available.\n\tUnsafeDisabled = false\n\n\t// ptrSize is the size of a pointer on the current arch.\n\tptrSize = unsafe.Sizeof((*byte)(nil))\n)\n\ntype flag uintptr\n\nvar (\n\t// flagRO indicates whether the value field of a reflect.Value\n\t// is read-only.\n\tflagRO flag\n\n\t// flagAddr indicates whether the address of the reflect.Value's\n\t// value may be taken.\n\tflagAddr flag\n)\n\n// flagKindMask holds the bits that make up the kind\n// part of the flags field. In all the supported versions,\n// it is in the lower 5 bits.\nconst flagKindMask = flag(0x1f)\n\n// Different versions of Go have used different\n// bit layouts for the flags type. This table\n// records the known combinations.\nvar okFlags = []struct {\n\tro, addr flag\n}{{\n\t// From Go 1.4 to 1.5\n\tro:   1 << 5,\n\taddr: 1 << 7,\n}, {\n\t// Up to Go tip.\n\tro:   1<<5 | 1<<6,\n\taddr: 1 << 8,\n}}\n\nvar flagValOffset = func() uintptr {\n\tfield, ok := reflect.TypeOf(reflect.Value{}).FieldByName(\"flag\")\n\tif !ok {\n\t\tpanic(\"reflect.Value has no flag field\")\n\t}\n\treturn field.Offset\n}()\n\n// flagField returns a pointer to the flag field of a reflect.Value.\nfunc flagField(v *reflect.Value) *flag {\n\treturn (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))\n}\n\n// unsafeReflectValue converts the passed reflect.Value into a one that bypasses\n// the typical safety restrictions preventing access to unaddressable and\n// unexported data.  It works by digging the raw pointer to the underlying\n// value out of the protected value and generating a new unprotected (unsafe)\n// reflect.Value to it.\n//\n// This allows us to check for implementations of the Stringer and error\n// interfaces to be used for pretty printing ordinarily unaddressable and\n// inaccessible values such as unexported struct fields.\nfunc unsafeReflectValue(v reflect.Value) reflect.Value {\n\tif !v.IsValid() || (v.CanInterface() && v.CanAddr()) {\n\t\treturn v\n\t}\n\tflagFieldPtr := flagField(&v)\n\t*flagFieldPtr &^= flagRO\n\t*flagFieldPtr |= flagAddr\n\treturn v\n}\n\n// Sanity checks against future reflect package changes\n// to the type or semantics of the Value.flag field.\nfunc init() {\n\tfield, ok := reflect.TypeOf(reflect.Value{}).FieldByName(\"flag\")\n\tif !ok {\n\t\tpanic(\"reflect.Value has no flag field\")\n\t}\n\tif field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {\n\t\tpanic(\"reflect.Value flag field has changed kind\")\n\t}\n\ttype t0 int\n\tvar t struct {\n\t\tA t0\n\t\t// t0 will have flagEmbedRO set.\n\t\tt0\n\t\t// a will have flagStickyRO set\n\t\ta t0\n\t}\n\tvA := reflect.ValueOf(t).FieldByName(\"A\")\n\tva := reflect.ValueOf(t).FieldByName(\"a\")\n\tvt0 := reflect.ValueOf(t).FieldByName(\"t0\")\n\n\t// Infer flagRO from the difference between the flags\n\t// for the (otherwise identical) fields in t.\n\tflagPublic := *flagField(&vA)\n\tflagWithRO := *flagField(&va) | *flagField(&vt0)\n\tflagRO = flagPublic ^ flagWithRO\n\n\t// Infer flagAddr from the difference between a value\n\t// taken from a pointer and not.\n\tvPtrA := reflect.ValueOf(&t).Elem().FieldByName(\"A\")\n\tflagNoPtr := *flagField(&vA)\n\tflagPtr := *flagField(&vPtrA)\n\tflagAddr = flagNoPtr ^ flagPtr\n\n\t// Check that the inferred flags tally with one of the known versions.\n\tfor _, f := range okFlags {\n\t\tif flagRO == f.ro && flagAddr == f.addr {\n\t\t\treturn\n\t\t}\n\t}\n\tpanic(\"reflect.Value read-only flag has changed semantics\")\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/bypasssafe.go",
    "content": "// Copyright (c) 2015-2016 Dave Collins <dave@davec.name>\n//\n// Permission to use, copy, modify, and distribute this software for any\n// purpose with or without fee is hereby granted, provided that the above\n// copyright notice and this permission notice appear in all copies.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n\n// NOTE: Due to the following build constraints, this file will only be compiled\n// when the code is running on Google App Engine, compiled by GopherJS, or\n// \"-tags safe\" is added to the go build command line.  The \"disableunsafe\"\n// tag is deprecated and thus should not be used.\n// +build js appengine safe disableunsafe !go1.4\n\npackage spew\n\nimport \"reflect\"\n\nconst (\n\t// UnsafeDisabled is a build-time constant which specifies whether or\n\t// not access to the unsafe package is available.\n\tUnsafeDisabled = true\n)\n\n// unsafeReflectValue typically converts the passed reflect.Value into a one\n// that bypasses the typical safety restrictions preventing access to\n// unaddressable and unexported data.  However, doing this relies on access to\n// the unsafe package.  This is a stub version which simply returns the passed\n// reflect.Value when the unsafe package is not available.\nfunc unsafeReflectValue(v reflect.Value) reflect.Value {\n\treturn v\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/common.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n)\n\n// Some constants in the form of bytes to avoid string overhead.  This mirrors\n// the technique used in the fmt package.\nvar (\n\tpanicBytes            = []byte(\"(PANIC=\")\n\tplusBytes             = []byte(\"+\")\n\tiBytes                = []byte(\"i\")\n\ttrueBytes             = []byte(\"true\")\n\tfalseBytes            = []byte(\"false\")\n\tinterfaceBytes        = []byte(\"(interface {})\")\n\tcommaNewlineBytes     = []byte(\",\\n\")\n\tnewlineBytes          = []byte(\"\\n\")\n\topenBraceBytes        = []byte(\"{\")\n\topenBraceNewlineBytes = []byte(\"{\\n\")\n\tcloseBraceBytes       = []byte(\"}\")\n\tasteriskBytes         = []byte(\"*\")\n\tcolonBytes            = []byte(\":\")\n\tcolonSpaceBytes       = []byte(\": \")\n\topenParenBytes        = []byte(\"(\")\n\tcloseParenBytes       = []byte(\")\")\n\tspaceBytes            = []byte(\" \")\n\tpointerChainBytes     = []byte(\"->\")\n\tnilAngleBytes         = []byte(\"<nil>\")\n\tmaxNewlineBytes       = []byte(\"<max depth reached>\\n\")\n\tmaxShortBytes         = []byte(\"<max>\")\n\tcircularBytes         = []byte(\"<already shown>\")\n\tcircularShortBytes    = []byte(\"<shown>\")\n\tinvalidAngleBytes     = []byte(\"<invalid>\")\n\topenBracketBytes      = []byte(\"[\")\n\tcloseBracketBytes     = []byte(\"]\")\n\tpercentBytes          = []byte(\"%\")\n\tprecisionBytes        = []byte(\".\")\n\topenAngleBytes        = []byte(\"<\")\n\tcloseAngleBytes       = []byte(\">\")\n\topenMapBytes          = []byte(\"map[\")\n\tcloseMapBytes         = []byte(\"]\")\n\tlenEqualsBytes        = []byte(\"len=\")\n\tcapEqualsBytes        = []byte(\"cap=\")\n)\n\n// hexDigits is used to map a decimal value to a hex digit.\nvar hexDigits = \"0123456789abcdef\"\n\n// catchPanic handles any panics that might occur during the handleMethods\n// calls.\nfunc catchPanic(w io.Writer, v reflect.Value) {\n\tif err := recover(); err != nil {\n\t\tw.Write(panicBytes)\n\t\tfmt.Fprintf(w, \"%v\", err)\n\t\tw.Write(closeParenBytes)\n\t}\n}\n\n// handleMethods attempts to call the Error and String methods on the underlying\n// type the passed reflect.Value represents and outputes the result to Writer w.\n//\n// It handles panics in any called methods by catching and displaying the error\n// as the formatted value.\nfunc handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {\n\t// We need an interface to check if the type implements the error or\n\t// Stringer interface.  However, the reflect package won't give us an\n\t// interface on certain things like unexported struct fields in order\n\t// to enforce visibility rules.  We use unsafe, when it's available,\n\t// to bypass these restrictions since this package does not mutate the\n\t// values.\n\tif !v.CanInterface() {\n\t\tif UnsafeDisabled {\n\t\t\treturn false\n\t\t}\n\n\t\tv = unsafeReflectValue(v)\n\t}\n\n\t// Choose whether or not to do error and Stringer interface lookups against\n\t// the base type or a pointer to the base type depending on settings.\n\t// Technically calling one of these methods with a pointer receiver can\n\t// mutate the value, however, types which choose to satisify an error or\n\t// Stringer interface with a pointer receiver should not be mutating their\n\t// state inside these interface methods.\n\tif !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {\n\t\tv = unsafeReflectValue(v)\n\t}\n\tif v.CanAddr() {\n\t\tv = v.Addr()\n\t}\n\n\t// Is it an error or Stringer?\n\tswitch iface := v.Interface().(type) {\n\tcase error:\n\t\tdefer catchPanic(w, v)\n\t\tif cs.ContinueOnMethod {\n\t\t\tw.Write(openParenBytes)\n\t\t\tw.Write([]byte(iface.Error()))\n\t\t\tw.Write(closeParenBytes)\n\t\t\tw.Write(spaceBytes)\n\t\t\treturn false\n\t\t}\n\n\t\tw.Write([]byte(iface.Error()))\n\t\treturn true\n\n\tcase fmt.Stringer:\n\t\tdefer catchPanic(w, v)\n\t\tif cs.ContinueOnMethod {\n\t\t\tw.Write(openParenBytes)\n\t\t\tw.Write([]byte(iface.String()))\n\t\t\tw.Write(closeParenBytes)\n\t\t\tw.Write(spaceBytes)\n\t\t\treturn false\n\t\t}\n\t\tw.Write([]byte(iface.String()))\n\t\treturn true\n\t}\n\treturn false\n}\n\n// printBool outputs a boolean value as true or false to Writer w.\nfunc printBool(w io.Writer, val bool) {\n\tif val {\n\t\tw.Write(trueBytes)\n\t} else {\n\t\tw.Write(falseBytes)\n\t}\n}\n\n// printInt outputs a signed integer value to Writer w.\nfunc printInt(w io.Writer, val int64, base int) {\n\tw.Write([]byte(strconv.FormatInt(val, base)))\n}\n\n// printUint outputs an unsigned integer value to Writer w.\nfunc printUint(w io.Writer, val uint64, base int) {\n\tw.Write([]byte(strconv.FormatUint(val, base)))\n}\n\n// printFloat outputs a floating point value using the specified precision,\n// which is expected to be 32 or 64bit, to Writer w.\nfunc printFloat(w io.Writer, val float64, precision int) {\n\tw.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))\n}\n\n// printComplex outputs a complex value using the specified float precision\n// for the real and imaginary parts to Writer w.\nfunc printComplex(w io.Writer, c complex128, floatPrecision int) {\n\tr := real(c)\n\tw.Write(openParenBytes)\n\tw.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))\n\ti := imag(c)\n\tif i >= 0 {\n\t\tw.Write(plusBytes)\n\t}\n\tw.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))\n\tw.Write(iBytes)\n\tw.Write(closeParenBytes)\n}\n\n// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'\n// prefix to Writer w.\nfunc printHexPtr(w io.Writer, p uintptr) {\n\t// Null pointer.\n\tnum := uint64(p)\n\tif num == 0 {\n\t\tw.Write(nilAngleBytes)\n\t\treturn\n\t}\n\n\t// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix\n\tbuf := make([]byte, 18)\n\n\t// It's simpler to construct the hex string right to left.\n\tbase := uint64(16)\n\ti := len(buf) - 1\n\tfor num >= base {\n\t\tbuf[i] = hexDigits[num%base]\n\t\tnum /= base\n\t\ti--\n\t}\n\tbuf[i] = hexDigits[num]\n\n\t// Add '0x' prefix.\n\ti--\n\tbuf[i] = 'x'\n\ti--\n\tbuf[i] = '0'\n\n\t// Strip unused leading bytes.\n\tbuf = buf[i:]\n\tw.Write(buf)\n}\n\n// valuesSorter implements sort.Interface to allow a slice of reflect.Value\n// elements to be sorted.\ntype valuesSorter struct {\n\tvalues  []reflect.Value\n\tstrings []string // either nil or same len and values\n\tcs      *ConfigState\n}\n\n// newValuesSorter initializes a valuesSorter instance, which holds a set of\n// surrogate keys on which the data should be sorted.  It uses flags in\n// ConfigState to decide if and how to populate those surrogate keys.\nfunc newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {\n\tvs := &valuesSorter{values: values, cs: cs}\n\tif canSortSimply(vs.values[0].Kind()) {\n\t\treturn vs\n\t}\n\tif !cs.DisableMethods {\n\t\tvs.strings = make([]string, len(values))\n\t\tfor i := range vs.values {\n\t\t\tb := bytes.Buffer{}\n\t\t\tif !handleMethods(cs, &b, vs.values[i]) {\n\t\t\t\tvs.strings = nil\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tvs.strings[i] = b.String()\n\t\t}\n\t}\n\tif vs.strings == nil && cs.SpewKeys {\n\t\tvs.strings = make([]string, len(values))\n\t\tfor i := range vs.values {\n\t\t\tvs.strings[i] = Sprintf(\"%#v\", vs.values[i].Interface())\n\t\t}\n\t}\n\treturn vs\n}\n\n// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted\n// directly, or whether it should be considered for sorting by surrogate keys\n// (if the ConfigState allows it).\nfunc canSortSimply(kind reflect.Kind) bool {\n\t// This switch parallels valueSortLess, except for the default case.\n\tswitch kind {\n\tcase reflect.Bool:\n\t\treturn true\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\treturn true\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\treturn true\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn true\n\tcase reflect.String:\n\t\treturn true\n\tcase reflect.Uintptr:\n\t\treturn true\n\tcase reflect.Array:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Len returns the number of values in the slice.  It is part of the\n// sort.Interface implementation.\nfunc (s *valuesSorter) Len() int {\n\treturn len(s.values)\n}\n\n// Swap swaps the values at the passed indices.  It is part of the\n// sort.Interface implementation.\nfunc (s *valuesSorter) Swap(i, j int) {\n\ts.values[i], s.values[j] = s.values[j], s.values[i]\n\tif s.strings != nil {\n\t\ts.strings[i], s.strings[j] = s.strings[j], s.strings[i]\n\t}\n}\n\n// valueSortLess returns whether the first value should sort before the second\n// value.  It is used by valueSorter.Less as part of the sort.Interface\n// implementation.\nfunc valueSortLess(a, b reflect.Value) bool {\n\tswitch a.Kind() {\n\tcase reflect.Bool:\n\t\treturn !a.Bool() && b.Bool()\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\treturn a.Int() < b.Int()\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\treturn a.Uint() < b.Uint()\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn a.Float() < b.Float()\n\tcase reflect.String:\n\t\treturn a.String() < b.String()\n\tcase reflect.Uintptr:\n\t\treturn a.Uint() < b.Uint()\n\tcase reflect.Array:\n\t\t// Compare the contents of both arrays.\n\t\tl := a.Len()\n\t\tfor i := 0; i < l; i++ {\n\t\t\tav := a.Index(i)\n\t\t\tbv := b.Index(i)\n\t\t\tif av.Interface() == bv.Interface() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn valueSortLess(av, bv)\n\t\t}\n\t}\n\treturn a.String() < b.String()\n}\n\n// Less returns whether the value at index i should sort before the\n// value at index j.  It is part of the sort.Interface implementation.\nfunc (s *valuesSorter) Less(i, j int) bool {\n\tif s.strings == nil {\n\t\treturn valueSortLess(s.values[i], s.values[j])\n\t}\n\treturn s.strings[i] < s.strings[j]\n}\n\n// sortValues is a sort function that handles both native types and any type that\n// can be converted to error or Stringer.  Other inputs are sorted according to\n// their Value.String() value to ensure display stability.\nfunc sortValues(values []reflect.Value, cs *ConfigState) {\n\tif len(values) == 0 {\n\t\treturn\n\t}\n\tsort.Sort(newValuesSorter(values, cs))\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/config.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\n// ConfigState houses the configuration options used by spew to format and\n// display values.  There is a global instance, Config, that is used to control\n// all top-level Formatter and Dump functionality.  Each ConfigState instance\n// provides methods equivalent to the top-level functions.\n//\n// The zero value for ConfigState provides no indentation.  You would typically\n// want to set it to a space or a tab.\n//\n// Alternatively, you can use NewDefaultConfig to get a ConfigState instance\n// with default settings.  See the documentation of NewDefaultConfig for default\n// values.\ntype ConfigState struct {\n\t// Indent specifies the string to use for each indentation level.  The\n\t// global config instance that all top-level functions use set this to a\n\t// single space by default.  If you would like more indentation, you might\n\t// set this to a tab with \"\\t\" or perhaps two spaces with \"  \".\n\tIndent string\n\n\t// MaxDepth controls the maximum number of levels to descend into nested\n\t// data structures.  The default, 0, means there is no limit.\n\t//\n\t// NOTE: Circular data structures are properly detected, so it is not\n\t// necessary to set this value unless you specifically want to limit deeply\n\t// nested data structures.\n\tMaxDepth int\n\n\t// DisableMethods specifies whether or not error and Stringer interfaces are\n\t// invoked for types that implement them.\n\tDisableMethods bool\n\n\t// DisablePointerMethods specifies whether or not to check for and invoke\n\t// error and Stringer interfaces on types which only accept a pointer\n\t// receiver when the current type is not a pointer.\n\t//\n\t// NOTE: This might be an unsafe action since calling one of these methods\n\t// with a pointer receiver could technically mutate the value, however,\n\t// in practice, types which choose to satisify an error or Stringer\n\t// interface with a pointer receiver should not be mutating their state\n\t// inside these interface methods.  As a result, this option relies on\n\t// access to the unsafe package, so it will not have any effect when\n\t// running in environments without access to the unsafe package such as\n\t// Google App Engine or with the \"safe\" build tag specified.\n\tDisablePointerMethods bool\n\n\t// DisablePointerAddresses specifies whether to disable the printing of\n\t// pointer addresses. This is useful when diffing data structures in tests.\n\tDisablePointerAddresses bool\n\n\t// DisableCapacities specifies whether to disable the printing of capacities\n\t// for arrays, slices, maps and channels. This is useful when diffing\n\t// data structures in tests.\n\tDisableCapacities bool\n\n\t// ContinueOnMethod specifies whether or not recursion should continue once\n\t// a custom error or Stringer interface is invoked.  The default, false,\n\t// means it will print the results of invoking the custom error or Stringer\n\t// interface and return immediately instead of continuing to recurse into\n\t// the internals of the data type.\n\t//\n\t// NOTE: This flag does not have any effect if method invocation is disabled\n\t// via the DisableMethods or DisablePointerMethods options.\n\tContinueOnMethod bool\n\n\t// SortKeys specifies map keys should be sorted before being printed. Use\n\t// this to have a more deterministic, diffable output.  Note that only\n\t// native types (bool, int, uint, floats, uintptr and string) and types\n\t// that support the error or Stringer interfaces (if methods are\n\t// enabled) are supported, with other types sorted according to the\n\t// reflect.Value.String() output which guarantees display stability.\n\tSortKeys bool\n\n\t// SpewKeys specifies that, as a last resort attempt, map keys should\n\t// be spewed to strings and sorted by those strings.  This is only\n\t// considered if SortKeys is true.\n\tSpewKeys bool\n}\n\n// Config is the active configuration of the top-level functions.\n// The configuration can be changed by modifying the contents of spew.Config.\nvar Config = ConfigState{Indent: \" \"}\n\n// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the formatted string as a value that satisfies error.  See NewFormatter\n// for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {\n\treturn fmt.Errorf(format, c.convertArgs(a)...)\n}\n\n// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprint(w, c.convertArgs(a)...)\n}\n\n// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintf(w, format, c.convertArgs(a)...)\n}\n\n// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it\n// passed with a Formatter interface returned by c.NewFormatter.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintln(w, c.convertArgs(a)...)\n}\n\n// Print is a wrapper for fmt.Print that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Print(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Print(a ...interface{}) (n int, err error) {\n\treturn fmt.Print(c.convertArgs(a)...)\n}\n\n// Printf is a wrapper for fmt.Printf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Printf(format, c.convertArgs(a)...)\n}\n\n// Println is a wrapper for fmt.Println that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Println(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Println(a ...interface{}) (n int, err error) {\n\treturn fmt.Println(c.convertArgs(a)...)\n}\n\n// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Sprint(a ...interface{}) string {\n\treturn fmt.Sprint(c.convertArgs(a)...)\n}\n\n// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were\n// passed with a Formatter interface returned by c.NewFormatter.  It returns\n// the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Sprintf(format string, a ...interface{}) string {\n\treturn fmt.Sprintf(format, c.convertArgs(a)...)\n}\n\n// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it\n// were passed with a Formatter interface returned by c.NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))\nfunc (c *ConfigState) Sprintln(a ...interface{}) string {\n\treturn fmt.Sprintln(c.convertArgs(a)...)\n}\n\n/*\nNewFormatter returns a custom formatter that satisfies the fmt.Formatter\ninterface.  As a result, it integrates cleanly with standard fmt package\nprinting functions.  The formatter is useful for inline printing of smaller data\ntypes similar to the standard %v format specifier.\n\nThe custom formatter only responds to the %v (most compact), %+v (adds pointer\naddresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb\ncombinations.  Any other verbs such as %x and %q will be sent to the the\nstandard fmt package for formatting.  In addition, the custom formatter ignores\nthe width and precision arguments (however they will still work on the format\nspecifiers not handled by the custom formatter).\n\nTypically this function shouldn't be called directly.  It is much easier to make\nuse of the custom formatter by calling one of the convenience functions such as\nc.Printf, c.Println, or c.Printf.\n*/\nfunc (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {\n\treturn newFormatter(c, v)\n}\n\n// Fdump formats and displays the passed arguments to io.Writer w.  It formats\n// exactly the same as Dump.\nfunc (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {\n\tfdump(c, w, a...)\n}\n\n/*\nDump displays the passed parameters to standard out with newlines, customizable\nindentation, and additional debug information such as complete types and all\npointer addresses used to indirect to the final value.  It provides the\nfollowing features over the built-in printing facilities provided by the fmt\npackage:\n\n\t* Pointers are dereferenced and followed\n\t* Circular data structures are detected and handled properly\n\t* Custom Stringer/error interfaces are optionally invoked, including\n\t  on unexported types\n\t* Custom types which only implement the Stringer/error interfaces via\n\t  a pointer receiver are optionally invoked when passing non-pointer\n\t  variables\n\t* Byte arrays and slices are dumped like the hexdump -C command which\n\t  includes offsets, byte values in hex, and ASCII output\n\nThe configuration options are controlled by modifying the public members\nof c.  See ConfigState for options documentation.\n\nSee Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to\nget the formatted result as a string.\n*/\nfunc (c *ConfigState) Dump(a ...interface{}) {\n\tfdump(c, os.Stdout, a...)\n}\n\n// Sdump returns a string with the passed arguments formatted exactly the same\n// as Dump.\nfunc (c *ConfigState) Sdump(a ...interface{}) string {\n\tvar buf bytes.Buffer\n\tfdump(c, &buf, a...)\n\treturn buf.String()\n}\n\n// convertArgs accepts a slice of arguments and returns a slice of the same\n// length with each argument converted to a spew Formatter interface using\n// the ConfigState associated with s.\nfunc (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {\n\tformatters = make([]interface{}, len(args))\n\tfor index, arg := range args {\n\t\tformatters[index] = newFormatter(c, arg)\n\t}\n\treturn formatters\n}\n\n// NewDefaultConfig returns a ConfigState with the following default settings.\n//\n// \tIndent: \" \"\n// \tMaxDepth: 0\n// \tDisableMethods: false\n// \tDisablePointerMethods: false\n// \tContinueOnMethod: false\n// \tSortKeys: false\nfunc NewDefaultConfig() *ConfigState {\n\treturn &ConfigState{Indent: \" \"}\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/doc.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n/*\nPackage spew implements a deep pretty printer for Go data structures to aid in\ndebugging.\n\nA quick overview of the additional features spew provides over the built-in\nprinting facilities for Go data types are as follows:\n\n\t* Pointers are dereferenced and followed\n\t* Circular data structures are detected and handled properly\n\t* Custom Stringer/error interfaces are optionally invoked, including\n\t  on unexported types\n\t* Custom types which only implement the Stringer/error interfaces via\n\t  a pointer receiver are optionally invoked when passing non-pointer\n\t  variables\n\t* Byte arrays and slices are dumped like the hexdump -C command which\n\t  includes offsets, byte values in hex, and ASCII output (only when using\n\t  Dump style)\n\nThere are two different approaches spew allows for dumping Go data structures:\n\n\t* Dump style which prints with newlines, customizable indentation,\n\t  and additional debug information such as types and all pointer addresses\n\t  used to indirect to the final value\n\t* A custom Formatter interface that integrates cleanly with the standard fmt\n\t  package and replaces %v, %+v, %#v, and %#+v to provide inline printing\n\t  similar to the default %v while providing the additional functionality\n\t  outlined above and passing unsupported format verbs such as %x and %q\n\t  along to fmt\n\nQuick Start\n\nThis section demonstrates how to quickly get started with spew.  See the\nsections below for further details on formatting and configuration options.\n\nTo dump a variable with full newlines, indentation, type, and pointer\ninformation use Dump, Fdump, or Sdump:\n\tspew.Dump(myVar1, myVar2, ...)\n\tspew.Fdump(someWriter, myVar1, myVar2, ...)\n\tstr := spew.Sdump(myVar1, myVar2, ...)\n\nAlternatively, if you would prefer to use format strings with a compacted inline\nprinting style, use the convenience wrappers Printf, Fprintf, etc with\n%v (most compact), %+v (adds pointer addresses), %#v (adds types), or\n%#+v (adds types and pointer addresses):\n\tspew.Printf(\"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Printf(\"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\tspew.Fprintf(someWriter, \"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Fprintf(someWriter, \"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\nConfiguration Options\n\nConfiguration of spew is handled by fields in the ConfigState type.  For\nconvenience, all of the top-level functions use a global state available\nvia the spew.Config global.\n\nIt is also possible to create a ConfigState instance that provides methods\nequivalent to the top-level functions.  This allows concurrent configuration\noptions.  See the ConfigState documentation for more details.\n\nThe following configuration options are available:\n\t* Indent\n\t\tString to use for each indentation level for Dump functions.\n\t\tIt is a single space by default.  A popular alternative is \"\\t\".\n\n\t* MaxDepth\n\t\tMaximum number of levels to descend into nested data structures.\n\t\tThere is no limit by default.\n\n\t* DisableMethods\n\t\tDisables invocation of error and Stringer interface methods.\n\t\tMethod invocation is enabled by default.\n\n\t* DisablePointerMethods\n\t\tDisables invocation of error and Stringer interface methods on types\n\t\twhich only accept pointer receivers from non-pointer variables.\n\t\tPointer method invocation is enabled by default.\n\n\t* DisablePointerAddresses\n\t\tDisablePointerAddresses specifies whether to disable the printing of\n\t\tpointer addresses. This is useful when diffing data structures in tests.\n\n\t* DisableCapacities\n\t\tDisableCapacities specifies whether to disable the printing of\n\t\tcapacities for arrays, slices, maps and channels. This is useful when\n\t\tdiffing data structures in tests.\n\n\t* ContinueOnMethod\n\t\tEnables recursion into types after invoking error and Stringer interface\n\t\tmethods. Recursion after method invocation is disabled by default.\n\n\t* SortKeys\n\t\tSpecifies map keys should be sorted before being printed. Use\n\t\tthis to have a more deterministic, diffable output.  Note that\n\t\tonly native types (bool, int, uint, floats, uintptr and string)\n\t\tand types which implement error or Stringer interfaces are\n\t\tsupported with other types sorted according to the\n\t\treflect.Value.String() output which guarantees display\n\t\tstability.  Natural map order is used by default.\n\n\t* SpewKeys\n\t\tSpecifies that, as a last resort attempt, map keys should be\n\t\tspewed to strings and sorted by those strings.  This is only\n\t\tconsidered if SortKeys is true.\n\nDump Usage\n\nSimply call spew.Dump with a list of variables you want to dump:\n\n\tspew.Dump(myVar1, myVar2, ...)\n\nYou may also call spew.Fdump if you would prefer to output to an arbitrary\nio.Writer.  For example, to dump to standard error:\n\n\tspew.Fdump(os.Stderr, myVar1, myVar2, ...)\n\nA third option is to call spew.Sdump to get the formatted output as a string:\n\n\tstr := spew.Sdump(myVar1, myVar2, ...)\n\nSample Dump Output\n\nSee the Dump example for details on the setup of the types and variables being\nshown here.\n\n\t(main.Foo) {\n\t unexportedField: (*main.Bar)(0xf84002e210)({\n\t  flag: (main.Flag) flagTwo,\n\t  data: (uintptr) <nil>\n\t }),\n\t ExportedField: (map[interface {}]interface {}) (len=1) {\n\t  (string) (len=3) \"one\": (bool) true\n\t }\n\t}\n\nByte (and uint8) arrays and slices are displayed uniquely like the hexdump -C\ncommand as shown.\n\t([]uint8) (len=32 cap=32) {\n\t 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |\n\t 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!\"#$%&'()*+,-./0|\n\t 00000020  31 32                                             |12|\n\t}\n\nCustom Formatter\n\nSpew provides a custom formatter that implements the fmt.Formatter interface\nso that it integrates cleanly with standard fmt package printing functions. The\nformatter is useful for inline printing of smaller data types similar to the\nstandard %v format specifier.\n\nThe custom formatter only responds to the %v (most compact), %+v (adds pointer\naddresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb\ncombinations.  Any other verbs such as %x and %q will be sent to the the\nstandard fmt package for formatting.  In addition, the custom formatter ignores\nthe width and precision arguments (however they will still work on the format\nspecifiers not handled by the custom formatter).\n\nCustom Formatter Usage\n\nThe simplest way to make use of the spew custom formatter is to call one of the\nconvenience functions such as spew.Printf, spew.Println, or spew.Printf.  The\nfunctions have syntax you are most likely already familiar with:\n\n\tspew.Printf(\"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Printf(\"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\tspew.Println(myVar, myVar2)\n\tspew.Fprintf(os.Stderr, \"myVar1: %v -- myVar2: %+v\", myVar1, myVar2)\n\tspew.Fprintf(os.Stderr, \"myVar3: %#v -- myVar4: %#+v\", myVar3, myVar4)\n\nSee the Index for the full list convenience functions.\n\nSample Formatter Output\n\nDouble pointer to a uint8:\n\t  %v: <**>5\n\t %+v: <**>(0xf8400420d0->0xf8400420c8)5\n\t %#v: (**uint8)5\n\t%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5\n\nPointer to circular struct with a uint8 field and a pointer to itself:\n\t  %v: <*>{1 <*><shown>}\n\t %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}\n\t %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}\n\t%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}\n\nSee the Printf example for details on the setup of variables being shown\nhere.\n\nErrors\n\nSince it is possible for custom Stringer/error interfaces to panic, spew\ndetects them and handles them internally by printing the panic information\ninline with the output.  Since spew is intended to provide deep pretty printing\ncapabilities on structures, it intentionally does not return any errors.\n*/\npackage spew\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/dump.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\t// uint8Type is a reflect.Type representing a uint8.  It is used to\n\t// convert cgo types to uint8 slices for hexdumping.\n\tuint8Type = reflect.TypeOf(uint8(0))\n\n\t// cCharRE is a regular expression that matches a cgo char.\n\t// It is used to detect character arrays to hexdump them.\n\tcCharRE = regexp.MustCompile(`^.*\\._Ctype_char$`)\n\n\t// cUnsignedCharRE is a regular expression that matches a cgo unsigned\n\t// char.  It is used to detect unsigned character arrays to hexdump\n\t// them.\n\tcUnsignedCharRE = regexp.MustCompile(`^.*\\._Ctype_unsignedchar$`)\n\n\t// cUint8tCharRE is a regular expression that matches a cgo uint8_t.\n\t// It is used to detect uint8_t arrays to hexdump them.\n\tcUint8tCharRE = regexp.MustCompile(`^.*\\._Ctype_uint8_t$`)\n)\n\n// dumpState contains information about the state of a dump operation.\ntype dumpState struct {\n\tw                io.Writer\n\tdepth            int\n\tpointers         map[uintptr]int\n\tignoreNextType   bool\n\tignoreNextIndent bool\n\tcs               *ConfigState\n}\n\n// indent performs indentation according to the depth level and cs.Indent\n// option.\nfunc (d *dumpState) indent() {\n\tif d.ignoreNextIndent {\n\t\td.ignoreNextIndent = false\n\t\treturn\n\t}\n\td.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))\n}\n\n// unpackValue returns values inside of non-nil interfaces when possible.\n// This is useful for data types like structs, arrays, slices, and maps which\n// can contain varying types packed inside an interface.\nfunc (d *dumpState) unpackValue(v reflect.Value) reflect.Value {\n\tif v.Kind() == reflect.Interface && !v.IsNil() {\n\t\tv = v.Elem()\n\t}\n\treturn v\n}\n\n// dumpPtr handles formatting of pointers by indirecting them as necessary.\nfunc (d *dumpState) dumpPtr(v reflect.Value) {\n\t// Remove pointers at or below the current depth from map used to detect\n\t// circular refs.\n\tfor k, depth := range d.pointers {\n\t\tif depth >= d.depth {\n\t\t\tdelete(d.pointers, k)\n\t\t}\n\t}\n\n\t// Keep list of all dereferenced pointers to show later.\n\tpointerChain := make([]uintptr, 0)\n\n\t// Figure out how many levels of indirection there are by dereferencing\n\t// pointers and unpacking interfaces down the chain while detecting circular\n\t// references.\n\tnilFound := false\n\tcycleFound := false\n\tindirects := 0\n\tve := v\n\tfor ve.Kind() == reflect.Ptr {\n\t\tif ve.IsNil() {\n\t\t\tnilFound = true\n\t\t\tbreak\n\t\t}\n\t\tindirects++\n\t\taddr := ve.Pointer()\n\t\tpointerChain = append(pointerChain, addr)\n\t\tif pd, ok := d.pointers[addr]; ok && pd < d.depth {\n\t\t\tcycleFound = true\n\t\t\tindirects--\n\t\t\tbreak\n\t\t}\n\t\td.pointers[addr] = d.depth\n\n\t\tve = ve.Elem()\n\t\tif ve.Kind() == reflect.Interface {\n\t\t\tif ve.IsNil() {\n\t\t\t\tnilFound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tve = ve.Elem()\n\t\t}\n\t}\n\n\t// Display type information.\n\td.w.Write(openParenBytes)\n\td.w.Write(bytes.Repeat(asteriskBytes, indirects))\n\td.w.Write([]byte(ve.Type().String()))\n\td.w.Write(closeParenBytes)\n\n\t// Display pointer information.\n\tif !d.cs.DisablePointerAddresses && len(pointerChain) > 0 {\n\t\td.w.Write(openParenBytes)\n\t\tfor i, addr := range pointerChain {\n\t\t\tif i > 0 {\n\t\t\t\td.w.Write(pointerChainBytes)\n\t\t\t}\n\t\t\tprintHexPtr(d.w, addr)\n\t\t}\n\t\td.w.Write(closeParenBytes)\n\t}\n\n\t// Display dereferenced value.\n\td.w.Write(openParenBytes)\n\tswitch {\n\tcase nilFound:\n\t\td.w.Write(nilAngleBytes)\n\n\tcase cycleFound:\n\t\td.w.Write(circularBytes)\n\n\tdefault:\n\t\td.ignoreNextType = true\n\t\td.dump(ve)\n\t}\n\td.w.Write(closeParenBytes)\n}\n\n// dumpSlice handles formatting of arrays and slices.  Byte (uint8 under\n// reflection) arrays and slices are dumped in hexdump -C fashion.\nfunc (d *dumpState) dumpSlice(v reflect.Value) {\n\t// Determine whether this type should be hex dumped or not.  Also,\n\t// for types which should be hexdumped, try to use the underlying data\n\t// first, then fall back to trying to convert them to a uint8 slice.\n\tvar buf []uint8\n\tdoConvert := false\n\tdoHexDump := false\n\tnumEntries := v.Len()\n\tif numEntries > 0 {\n\t\tvt := v.Index(0).Type()\n\t\tvts := vt.String()\n\t\tswitch {\n\t\t// C types that need to be converted.\n\t\tcase cCharRE.MatchString(vts):\n\t\t\tfallthrough\n\t\tcase cUnsignedCharRE.MatchString(vts):\n\t\t\tfallthrough\n\t\tcase cUint8tCharRE.MatchString(vts):\n\t\t\tdoConvert = true\n\n\t\t// Try to use existing uint8 slices and fall back to converting\n\t\t// and copying if that fails.\n\t\tcase vt.Kind() == reflect.Uint8:\n\t\t\t// We need an addressable interface to convert the type\n\t\t\t// to a byte slice.  However, the reflect package won't\n\t\t\t// give us an interface on certain things like\n\t\t\t// unexported struct fields in order to enforce\n\t\t\t// visibility rules.  We use unsafe, when available, to\n\t\t\t// bypass these restrictions since this package does not\n\t\t\t// mutate the values.\n\t\t\tvs := v\n\t\t\tif !vs.CanInterface() || !vs.CanAddr() {\n\t\t\t\tvs = unsafeReflectValue(vs)\n\t\t\t}\n\t\t\tif !UnsafeDisabled {\n\t\t\t\tvs = vs.Slice(0, numEntries)\n\n\t\t\t\t// Use the existing uint8 slice if it can be\n\t\t\t\t// type asserted.\n\t\t\t\tiface := vs.Interface()\n\t\t\t\tif slice, ok := iface.([]uint8); ok {\n\t\t\t\t\tbuf = slice\n\t\t\t\t\tdoHexDump = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The underlying data needs to be converted if it can't\n\t\t\t// be type asserted to a uint8 slice.\n\t\t\tdoConvert = true\n\t\t}\n\n\t\t// Copy and convert the underlying type if needed.\n\t\tif doConvert && vt.ConvertibleTo(uint8Type) {\n\t\t\t// Convert and copy each element into a uint8 byte\n\t\t\t// slice.\n\t\t\tbuf = make([]uint8, numEntries)\n\t\t\tfor i := 0; i < numEntries; i++ {\n\t\t\t\tvv := v.Index(i)\n\t\t\t\tbuf[i] = uint8(vv.Convert(uint8Type).Uint())\n\t\t\t}\n\t\t\tdoHexDump = true\n\t\t}\n\t}\n\n\t// Hexdump the entire slice as needed.\n\tif doHexDump {\n\t\tindent := strings.Repeat(d.cs.Indent, d.depth)\n\t\tstr := indent + hex.Dump(buf)\n\t\tstr = strings.Replace(str, \"\\n\", \"\\n\"+indent, -1)\n\t\tstr = strings.TrimRight(str, d.cs.Indent)\n\t\td.w.Write([]byte(str))\n\t\treturn\n\t}\n\n\t// Recursively call dump for each item.\n\tfor i := 0; i < numEntries; i++ {\n\t\td.dump(d.unpackValue(v.Index(i)))\n\t\tif i < (numEntries - 1) {\n\t\t\td.w.Write(commaNewlineBytes)\n\t\t} else {\n\t\t\td.w.Write(newlineBytes)\n\t\t}\n\t}\n}\n\n// dump is the main workhorse for dumping a value.  It uses the passed reflect\n// value to figure out what kind of object we are dealing with and formats it\n// appropriately.  It is a recursive function, however circular data structures\n// are detected and handled properly.\nfunc (d *dumpState) dump(v reflect.Value) {\n\t// Handle invalid reflect values immediately.\n\tkind := v.Kind()\n\tif kind == reflect.Invalid {\n\t\td.w.Write(invalidAngleBytes)\n\t\treturn\n\t}\n\n\t// Handle pointers specially.\n\tif kind == reflect.Ptr {\n\t\td.indent()\n\t\td.dumpPtr(v)\n\t\treturn\n\t}\n\n\t// Print type information unless already handled elsewhere.\n\tif !d.ignoreNextType {\n\t\td.indent()\n\t\td.w.Write(openParenBytes)\n\t\td.w.Write([]byte(v.Type().String()))\n\t\td.w.Write(closeParenBytes)\n\t\td.w.Write(spaceBytes)\n\t}\n\td.ignoreNextType = false\n\n\t// Display length and capacity if the built-in len and cap functions\n\t// work with the value's kind and the len/cap itself is non-zero.\n\tvalueLen, valueCap := 0, 0\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Slice, reflect.Chan:\n\t\tvalueLen, valueCap = v.Len(), v.Cap()\n\tcase reflect.Map, reflect.String:\n\t\tvalueLen = v.Len()\n\t}\n\tif valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 {\n\t\td.w.Write(openParenBytes)\n\t\tif valueLen != 0 {\n\t\t\td.w.Write(lenEqualsBytes)\n\t\t\tprintInt(d.w, int64(valueLen), 10)\n\t\t}\n\t\tif !d.cs.DisableCapacities && valueCap != 0 {\n\t\t\tif valueLen != 0 {\n\t\t\t\td.w.Write(spaceBytes)\n\t\t\t}\n\t\t\td.w.Write(capEqualsBytes)\n\t\t\tprintInt(d.w, int64(valueCap), 10)\n\t\t}\n\t\td.w.Write(closeParenBytes)\n\t\td.w.Write(spaceBytes)\n\t}\n\n\t// Call Stringer/error interfaces if they exist and the handle methods flag\n\t// is enabled\n\tif !d.cs.DisableMethods {\n\t\tif (kind != reflect.Invalid) && (kind != reflect.Interface) {\n\t\t\tif handled := handleMethods(d.cs, d.w, v); handled {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase reflect.Invalid:\n\t\t// Do nothing.  We should never get here since invalid has already\n\t\t// been handled above.\n\n\tcase reflect.Bool:\n\t\tprintBool(d.w, v.Bool())\n\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\tprintInt(d.w, v.Int(), 10)\n\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\tprintUint(d.w, v.Uint(), 10)\n\n\tcase reflect.Float32:\n\t\tprintFloat(d.w, v.Float(), 32)\n\n\tcase reflect.Float64:\n\t\tprintFloat(d.w, v.Float(), 64)\n\n\tcase reflect.Complex64:\n\t\tprintComplex(d.w, v.Complex(), 32)\n\n\tcase reflect.Complex128:\n\t\tprintComplex(d.w, v.Complex(), 64)\n\n\tcase reflect.Slice:\n\t\tif v.IsNil() {\n\t\t\td.w.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\t\tfallthrough\n\n\tcase reflect.Array:\n\t\td.w.Write(openBraceNewlineBytes)\n\t\td.depth++\n\t\tif (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {\n\t\t\td.indent()\n\t\t\td.w.Write(maxNewlineBytes)\n\t\t} else {\n\t\t\td.dumpSlice(v)\n\t\t}\n\t\td.depth--\n\t\td.indent()\n\t\td.w.Write(closeBraceBytes)\n\n\tcase reflect.String:\n\t\td.w.Write([]byte(strconv.Quote(v.String())))\n\n\tcase reflect.Interface:\n\t\t// The only time we should get here is for nil interfaces due to\n\t\t// unpackValue calls.\n\t\tif v.IsNil() {\n\t\t\td.w.Write(nilAngleBytes)\n\t\t}\n\n\tcase reflect.Ptr:\n\t\t// Do nothing.  We should never get here since pointers have already\n\t\t// been handled above.\n\n\tcase reflect.Map:\n\t\t// nil maps should be indicated as different than empty maps\n\t\tif v.IsNil() {\n\t\t\td.w.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\n\t\td.w.Write(openBraceNewlineBytes)\n\t\td.depth++\n\t\tif (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {\n\t\t\td.indent()\n\t\t\td.w.Write(maxNewlineBytes)\n\t\t} else {\n\t\t\tnumEntries := v.Len()\n\t\t\tkeys := v.MapKeys()\n\t\t\tif d.cs.SortKeys {\n\t\t\t\tsortValues(keys, d.cs)\n\t\t\t}\n\t\t\tfor i, key := range keys {\n\t\t\t\td.dump(d.unpackValue(key))\n\t\t\t\td.w.Write(colonSpaceBytes)\n\t\t\t\td.ignoreNextIndent = true\n\t\t\t\td.dump(d.unpackValue(v.MapIndex(key)))\n\t\t\t\tif i < (numEntries - 1) {\n\t\t\t\t\td.w.Write(commaNewlineBytes)\n\t\t\t\t} else {\n\t\t\t\t\td.w.Write(newlineBytes)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\td.depth--\n\t\td.indent()\n\t\td.w.Write(closeBraceBytes)\n\n\tcase reflect.Struct:\n\t\td.w.Write(openBraceNewlineBytes)\n\t\td.depth++\n\t\tif (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {\n\t\t\td.indent()\n\t\t\td.w.Write(maxNewlineBytes)\n\t\t} else {\n\t\t\tvt := v.Type()\n\t\t\tnumFields := v.NumField()\n\t\t\tfor i := 0; i < numFields; i++ {\n\t\t\t\td.indent()\n\t\t\t\tvtf := vt.Field(i)\n\t\t\t\td.w.Write([]byte(vtf.Name))\n\t\t\t\td.w.Write(colonSpaceBytes)\n\t\t\t\td.ignoreNextIndent = true\n\t\t\t\td.dump(d.unpackValue(v.Field(i)))\n\t\t\t\tif i < (numFields - 1) {\n\t\t\t\t\td.w.Write(commaNewlineBytes)\n\t\t\t\t} else {\n\t\t\t\t\td.w.Write(newlineBytes)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\td.depth--\n\t\td.indent()\n\t\td.w.Write(closeBraceBytes)\n\n\tcase reflect.Uintptr:\n\t\tprintHexPtr(d.w, uintptr(v.Uint()))\n\n\tcase reflect.UnsafePointer, reflect.Chan, reflect.Func:\n\t\tprintHexPtr(d.w, v.Pointer())\n\n\t// There were not any other types at the time this code was written, but\n\t// fall back to letting the default fmt package handle it in case any new\n\t// types are added.\n\tdefault:\n\t\tif v.CanInterface() {\n\t\t\tfmt.Fprintf(d.w, \"%v\", v.Interface())\n\t\t} else {\n\t\t\tfmt.Fprintf(d.w, \"%v\", v.String())\n\t\t}\n\t}\n}\n\n// fdump is a helper function to consolidate the logic from the various public\n// methods which take varying writers and config states.\nfunc fdump(cs *ConfigState, w io.Writer, a ...interface{}) {\n\tfor _, arg := range a {\n\t\tif arg == nil {\n\t\t\tw.Write(interfaceBytes)\n\t\t\tw.Write(spaceBytes)\n\t\t\tw.Write(nilAngleBytes)\n\t\t\tw.Write(newlineBytes)\n\t\t\tcontinue\n\t\t}\n\n\t\td := dumpState{w: w, cs: cs}\n\t\td.pointers = make(map[uintptr]int)\n\t\td.dump(reflect.ValueOf(arg))\n\t\td.w.Write(newlineBytes)\n\t}\n}\n\n// Fdump formats and displays the passed arguments to io.Writer w.  It formats\n// exactly the same as Dump.\nfunc Fdump(w io.Writer, a ...interface{}) {\n\tfdump(&Config, w, a...)\n}\n\n// Sdump returns a string with the passed arguments formatted exactly the same\n// as Dump.\nfunc Sdump(a ...interface{}) string {\n\tvar buf bytes.Buffer\n\tfdump(&Config, &buf, a...)\n\treturn buf.String()\n}\n\n/*\nDump displays the passed parameters to standard out with newlines, customizable\nindentation, and additional debug information such as complete types and all\npointer addresses used to indirect to the final value.  It provides the\nfollowing features over the built-in printing facilities provided by the fmt\npackage:\n\n\t* Pointers are dereferenced and followed\n\t* Circular data structures are detected and handled properly\n\t* Custom Stringer/error interfaces are optionally invoked, including\n\t  on unexported types\n\t* Custom types which only implement the Stringer/error interfaces via\n\t  a pointer receiver are optionally invoked when passing non-pointer\n\t  variables\n\t* Byte arrays and slices are dumped like the hexdump -C command which\n\t  includes offsets, byte values in hex, and ASCII output\n\nThe configuration options are controlled by an exported package global,\nspew.Config.  See ConfigState for options documentation.\n\nSee Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to\nget the formatted result as a string.\n*/\nfunc Dump(a ...interface{}) {\n\tfdump(&Config, os.Stdout, a...)\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/format.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// supportedFlags is a list of all the character flags supported by fmt package.\nconst supportedFlags = \"0-+# \"\n\n// formatState implements the fmt.Formatter interface and contains information\n// about the state of a formatting operation.  The NewFormatter function can\n// be used to get a new Formatter which can be used directly as arguments\n// in standard fmt package printing calls.\ntype formatState struct {\n\tvalue          interface{}\n\tfs             fmt.State\n\tdepth          int\n\tpointers       map[uintptr]int\n\tignoreNextType bool\n\tcs             *ConfigState\n}\n\n// buildDefaultFormat recreates the original format string without precision\n// and width information to pass in to fmt.Sprintf in the case of an\n// unrecognized type.  Unless new types are added to the language, this\n// function won't ever be called.\nfunc (f *formatState) buildDefaultFormat() (format string) {\n\tbuf := bytes.NewBuffer(percentBytes)\n\n\tfor _, flag := range supportedFlags {\n\t\tif f.fs.Flag(int(flag)) {\n\t\t\tbuf.WriteRune(flag)\n\t\t}\n\t}\n\n\tbuf.WriteRune('v')\n\n\tformat = buf.String()\n\treturn format\n}\n\n// constructOrigFormat recreates the original format string including precision\n// and width information to pass along to the standard fmt package.  This allows\n// automatic deferral of all format strings this package doesn't support.\nfunc (f *formatState) constructOrigFormat(verb rune) (format string) {\n\tbuf := bytes.NewBuffer(percentBytes)\n\n\tfor _, flag := range supportedFlags {\n\t\tif f.fs.Flag(int(flag)) {\n\t\t\tbuf.WriteRune(flag)\n\t\t}\n\t}\n\n\tif width, ok := f.fs.Width(); ok {\n\t\tbuf.WriteString(strconv.Itoa(width))\n\t}\n\n\tif precision, ok := f.fs.Precision(); ok {\n\t\tbuf.Write(precisionBytes)\n\t\tbuf.WriteString(strconv.Itoa(precision))\n\t}\n\n\tbuf.WriteRune(verb)\n\n\tformat = buf.String()\n\treturn format\n}\n\n// unpackValue returns values inside of non-nil interfaces when possible and\n// ensures that types for values which have been unpacked from an interface\n// are displayed when the show types flag is also set.\n// This is useful for data types like structs, arrays, slices, and maps which\n// can contain varying types packed inside an interface.\nfunc (f *formatState) unpackValue(v reflect.Value) reflect.Value {\n\tif v.Kind() == reflect.Interface {\n\t\tf.ignoreNextType = false\n\t\tif !v.IsNil() {\n\t\t\tv = v.Elem()\n\t\t}\n\t}\n\treturn v\n}\n\n// formatPtr handles formatting of pointers by indirecting them as necessary.\nfunc (f *formatState) formatPtr(v reflect.Value) {\n\t// Display nil if top level pointer is nil.\n\tshowTypes := f.fs.Flag('#')\n\tif v.IsNil() && (!showTypes || f.ignoreNextType) {\n\t\tf.fs.Write(nilAngleBytes)\n\t\treturn\n\t}\n\n\t// Remove pointers at or below the current depth from map used to detect\n\t// circular refs.\n\tfor k, depth := range f.pointers {\n\t\tif depth >= f.depth {\n\t\t\tdelete(f.pointers, k)\n\t\t}\n\t}\n\n\t// Keep list of all dereferenced pointers to possibly show later.\n\tpointerChain := make([]uintptr, 0)\n\n\t// Figure out how many levels of indirection there are by derferencing\n\t// pointers and unpacking interfaces down the chain while detecting circular\n\t// references.\n\tnilFound := false\n\tcycleFound := false\n\tindirects := 0\n\tve := v\n\tfor ve.Kind() == reflect.Ptr {\n\t\tif ve.IsNil() {\n\t\t\tnilFound = true\n\t\t\tbreak\n\t\t}\n\t\tindirects++\n\t\taddr := ve.Pointer()\n\t\tpointerChain = append(pointerChain, addr)\n\t\tif pd, ok := f.pointers[addr]; ok && pd < f.depth {\n\t\t\tcycleFound = true\n\t\t\tindirects--\n\t\t\tbreak\n\t\t}\n\t\tf.pointers[addr] = f.depth\n\n\t\tve = ve.Elem()\n\t\tif ve.Kind() == reflect.Interface {\n\t\t\tif ve.IsNil() {\n\t\t\t\tnilFound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tve = ve.Elem()\n\t\t}\n\t}\n\n\t// Display type or indirection level depending on flags.\n\tif showTypes && !f.ignoreNextType {\n\t\tf.fs.Write(openParenBytes)\n\t\tf.fs.Write(bytes.Repeat(asteriskBytes, indirects))\n\t\tf.fs.Write([]byte(ve.Type().String()))\n\t\tf.fs.Write(closeParenBytes)\n\t} else {\n\t\tif nilFound || cycleFound {\n\t\t\tindirects += strings.Count(ve.Type().String(), \"*\")\n\t\t}\n\t\tf.fs.Write(openAngleBytes)\n\t\tf.fs.Write([]byte(strings.Repeat(\"*\", indirects)))\n\t\tf.fs.Write(closeAngleBytes)\n\t}\n\n\t// Display pointer information depending on flags.\n\tif f.fs.Flag('+') && (len(pointerChain) > 0) {\n\t\tf.fs.Write(openParenBytes)\n\t\tfor i, addr := range pointerChain {\n\t\t\tif i > 0 {\n\t\t\t\tf.fs.Write(pointerChainBytes)\n\t\t\t}\n\t\t\tprintHexPtr(f.fs, addr)\n\t\t}\n\t\tf.fs.Write(closeParenBytes)\n\t}\n\n\t// Display dereferenced value.\n\tswitch {\n\tcase nilFound:\n\t\tf.fs.Write(nilAngleBytes)\n\n\tcase cycleFound:\n\t\tf.fs.Write(circularShortBytes)\n\n\tdefault:\n\t\tf.ignoreNextType = true\n\t\tf.format(ve)\n\t}\n}\n\n// format is the main workhorse for providing the Formatter interface.  It\n// uses the passed reflect value to figure out what kind of object we are\n// dealing with and formats it appropriately.  It is a recursive function,\n// however circular data structures are detected and handled properly.\nfunc (f *formatState) format(v reflect.Value) {\n\t// Handle invalid reflect values immediately.\n\tkind := v.Kind()\n\tif kind == reflect.Invalid {\n\t\tf.fs.Write(invalidAngleBytes)\n\t\treturn\n\t}\n\n\t// Handle pointers specially.\n\tif kind == reflect.Ptr {\n\t\tf.formatPtr(v)\n\t\treturn\n\t}\n\n\t// Print type information unless already handled elsewhere.\n\tif !f.ignoreNextType && f.fs.Flag('#') {\n\t\tf.fs.Write(openParenBytes)\n\t\tf.fs.Write([]byte(v.Type().String()))\n\t\tf.fs.Write(closeParenBytes)\n\t}\n\tf.ignoreNextType = false\n\n\t// Call Stringer/error interfaces if they exist and the handle methods\n\t// flag is enabled.\n\tif !f.cs.DisableMethods {\n\t\tif (kind != reflect.Invalid) && (kind != reflect.Interface) {\n\t\t\tif handled := handleMethods(f.cs, f.fs, v); handled {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase reflect.Invalid:\n\t\t// Do nothing.  We should never get here since invalid has already\n\t\t// been handled above.\n\n\tcase reflect.Bool:\n\t\tprintBool(f.fs, v.Bool())\n\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\tprintInt(f.fs, v.Int(), 10)\n\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\tprintUint(f.fs, v.Uint(), 10)\n\n\tcase reflect.Float32:\n\t\tprintFloat(f.fs, v.Float(), 32)\n\n\tcase reflect.Float64:\n\t\tprintFloat(f.fs, v.Float(), 64)\n\n\tcase reflect.Complex64:\n\t\tprintComplex(f.fs, v.Complex(), 32)\n\n\tcase reflect.Complex128:\n\t\tprintComplex(f.fs, v.Complex(), 64)\n\n\tcase reflect.Slice:\n\t\tif v.IsNil() {\n\t\t\tf.fs.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\t\tfallthrough\n\n\tcase reflect.Array:\n\t\tf.fs.Write(openBracketBytes)\n\t\tf.depth++\n\t\tif (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {\n\t\t\tf.fs.Write(maxShortBytes)\n\t\t} else {\n\t\t\tnumEntries := v.Len()\n\t\t\tfor i := 0; i < numEntries; i++ {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tf.fs.Write(spaceBytes)\n\t\t\t\t}\n\t\t\t\tf.ignoreNextType = true\n\t\t\t\tf.format(f.unpackValue(v.Index(i)))\n\t\t\t}\n\t\t}\n\t\tf.depth--\n\t\tf.fs.Write(closeBracketBytes)\n\n\tcase reflect.String:\n\t\tf.fs.Write([]byte(v.String()))\n\n\tcase reflect.Interface:\n\t\t// The only time we should get here is for nil interfaces due to\n\t\t// unpackValue calls.\n\t\tif v.IsNil() {\n\t\t\tf.fs.Write(nilAngleBytes)\n\t\t}\n\n\tcase reflect.Ptr:\n\t\t// Do nothing.  We should never get here since pointers have already\n\t\t// been handled above.\n\n\tcase reflect.Map:\n\t\t// nil maps should be indicated as different than empty maps\n\t\tif v.IsNil() {\n\t\t\tf.fs.Write(nilAngleBytes)\n\t\t\tbreak\n\t\t}\n\n\t\tf.fs.Write(openMapBytes)\n\t\tf.depth++\n\t\tif (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {\n\t\t\tf.fs.Write(maxShortBytes)\n\t\t} else {\n\t\t\tkeys := v.MapKeys()\n\t\t\tif f.cs.SortKeys {\n\t\t\t\tsortValues(keys, f.cs)\n\t\t\t}\n\t\t\tfor i, key := range keys {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tf.fs.Write(spaceBytes)\n\t\t\t\t}\n\t\t\t\tf.ignoreNextType = true\n\t\t\t\tf.format(f.unpackValue(key))\n\t\t\t\tf.fs.Write(colonBytes)\n\t\t\t\tf.ignoreNextType = true\n\t\t\t\tf.format(f.unpackValue(v.MapIndex(key)))\n\t\t\t}\n\t\t}\n\t\tf.depth--\n\t\tf.fs.Write(closeMapBytes)\n\n\tcase reflect.Struct:\n\t\tnumFields := v.NumField()\n\t\tf.fs.Write(openBraceBytes)\n\t\tf.depth++\n\t\tif (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {\n\t\t\tf.fs.Write(maxShortBytes)\n\t\t} else {\n\t\t\tvt := v.Type()\n\t\t\tfor i := 0; i < numFields; i++ {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tf.fs.Write(spaceBytes)\n\t\t\t\t}\n\t\t\t\tvtf := vt.Field(i)\n\t\t\t\tif f.fs.Flag('+') || f.fs.Flag('#') {\n\t\t\t\t\tf.fs.Write([]byte(vtf.Name))\n\t\t\t\t\tf.fs.Write(colonBytes)\n\t\t\t\t}\n\t\t\t\tf.format(f.unpackValue(v.Field(i)))\n\t\t\t}\n\t\t}\n\t\tf.depth--\n\t\tf.fs.Write(closeBraceBytes)\n\n\tcase reflect.Uintptr:\n\t\tprintHexPtr(f.fs, uintptr(v.Uint()))\n\n\tcase reflect.UnsafePointer, reflect.Chan, reflect.Func:\n\t\tprintHexPtr(f.fs, v.Pointer())\n\n\t// There were not any other types at the time this code was written, but\n\t// fall back to letting the default fmt package handle it if any get added.\n\tdefault:\n\t\tformat := f.buildDefaultFormat()\n\t\tif v.CanInterface() {\n\t\t\tfmt.Fprintf(f.fs, format, v.Interface())\n\t\t} else {\n\t\t\tfmt.Fprintf(f.fs, format, v.String())\n\t\t}\n\t}\n}\n\n// Format satisfies the fmt.Formatter interface. See NewFormatter for usage\n// details.\nfunc (f *formatState) Format(fs fmt.State, verb rune) {\n\tf.fs = fs\n\n\t// Use standard formatting for verbs that are not v.\n\tif verb != 'v' {\n\t\tformat := f.constructOrigFormat(verb)\n\t\tfmt.Fprintf(fs, format, f.value)\n\t\treturn\n\t}\n\n\tif f.value == nil {\n\t\tif fs.Flag('#') {\n\t\t\tfs.Write(interfaceBytes)\n\t\t}\n\t\tfs.Write(nilAngleBytes)\n\t\treturn\n\t}\n\n\tf.format(reflect.ValueOf(f.value))\n}\n\n// newFormatter is a helper function to consolidate the logic from the various\n// public methods which take varying config states.\nfunc newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {\n\tfs := &formatState{value: v, cs: cs}\n\tfs.pointers = make(map[uintptr]int)\n\treturn fs\n}\n\n/*\nNewFormatter returns a custom formatter that satisfies the fmt.Formatter\ninterface.  As a result, it integrates cleanly with standard fmt package\nprinting functions.  The formatter is useful for inline printing of smaller data\ntypes similar to the standard %v format specifier.\n\nThe custom formatter only responds to the %v (most compact), %+v (adds pointer\naddresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb\ncombinations.  Any other verbs such as %x and %q will be sent to the the\nstandard fmt package for formatting.  In addition, the custom formatter ignores\nthe width and precision arguments (however they will still work on the format\nspecifiers not handled by the custom formatter).\n\nTypically this function shouldn't be called directly.  It is much easier to make\nuse of the custom formatter by calling one of the convenience functions such as\nPrintf, Println, or Fprintf.\n*/\nfunc NewFormatter(v interface{}) fmt.Formatter {\n\treturn newFormatter(&Config, v)\n}\n"
  },
  {
    "path": "vendor/github.com/davecgh/go-spew/spew/spew.go",
    "content": "/*\n * Copyright (c) 2013-2016 Dave Collins <dave@davec.name>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\npackage spew\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the formatted string as a value that satisfies error.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Errorf(format string, a ...interface{}) (err error) {\n\treturn fmt.Errorf(format, convertArgs(a)...)\n}\n\n// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Fprint(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprint(w, convertArgs(a)...)\n}\n\n// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintf(w, format, convertArgs(a)...)\n}\n\n// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it\n// passed with a default Formatter interface returned by NewFormatter.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Fprintln(w io.Writer, a ...interface{}) (n int, err error) {\n\treturn fmt.Fprintln(w, convertArgs(a)...)\n}\n\n// Print is a wrapper for fmt.Print that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Print(a ...interface{}) (n int, err error) {\n\treturn fmt.Print(convertArgs(a)...)\n}\n\n// Printf is a wrapper for fmt.Printf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Printf(format string, a ...interface{}) (n int, err error) {\n\treturn fmt.Printf(format, convertArgs(a)...)\n}\n\n// Println is a wrapper for fmt.Println that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the number of bytes written and any write error encountered.  See\n// NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Println(a ...interface{}) (n int, err error) {\n\treturn fmt.Println(convertArgs(a)...)\n}\n\n// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Sprint(a ...interface{}) string {\n\treturn fmt.Sprint(convertArgs(a)...)\n}\n\n// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were\n// passed with a default Formatter interface returned by NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Sprintf(format string, a ...interface{}) string {\n\treturn fmt.Sprintf(format, convertArgs(a)...)\n}\n\n// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it\n// were passed with a default Formatter interface returned by NewFormatter.  It\n// returns the resulting string.  See NewFormatter for formatting details.\n//\n// This function is shorthand for the following syntax:\n//\n//\tfmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))\nfunc Sprintln(a ...interface{}) string {\n\treturn fmt.Sprintln(convertArgs(a)...)\n}\n\n// convertArgs accepts a slice of arguments and returns a slice of the same\n// length with each argument converted to a default spew Formatter interface.\nfunc convertArgs(args []interface{}) (formatters []interface{}) {\n\tformatters = make([]interface{}, len(args))\n\tfor index, arg := range args {\n\t\tformatters[index] = NewFormatter(arg)\n\t}\n\treturn formatters\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/distribution/v3/LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\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       http://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\n"
  },
  {
    "path": "vendor/github.com/distribution/distribution/v3/digestset/set.go",
    "content": "package digestset\n\nimport (\n\t\"errors\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\n\tdigest \"github.com/opencontainers/go-digest\"\n)\n\nvar (\n\t// ErrDigestNotFound is used when a matching digest\n\t// could not be found in a set.\n\tErrDigestNotFound = errors.New(\"digest not found\")\n\n\t// ErrDigestAmbiguous is used when multiple digests\n\t// are found in a set. None of the matching digests\n\t// should be considered valid matches.\n\tErrDigestAmbiguous = errors.New(\"ambiguous digest string\")\n)\n\n// Set is used to hold a unique set of digests which\n// may be easily referenced by easily  referenced by a string\n// representation of the digest as well as short representation.\n// The uniqueness of the short representation is based on other\n// digests in the set. If digests are omitted from this set,\n// collisions in a larger set may not be detected, therefore it\n// is important to always do short representation lookups on\n// the complete set of digests. To mitigate collisions, an\n// appropriately long short code should be used.\ntype Set struct {\n\tmutex   sync.RWMutex\n\tentries digestEntries\n}\n\n// NewSet creates an empty set of digests\n// which may have digests added.\nfunc NewSet() *Set {\n\treturn &Set{\n\t\tentries: digestEntries{},\n\t}\n}\n\n// checkShortMatch checks whether two digests match as either whole\n// values or short values. This function does not test equality,\n// rather whether the second value could match against the first\n// value.\nfunc checkShortMatch(alg digest.Algorithm, hex, shortAlg, shortHex string) bool {\n\tif len(hex) == len(shortHex) {\n\t\tif hex != shortHex {\n\t\t\treturn false\n\t\t}\n\t\tif len(shortAlg) > 0 && string(alg) != shortAlg {\n\t\t\treturn false\n\t\t}\n\t} else if !strings.HasPrefix(hex, shortHex) {\n\t\treturn false\n\t} else if len(shortAlg) > 0 && string(alg) != shortAlg {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Lookup looks for a digest matching the given string representation.\n// If no digests could be found ErrDigestNotFound will be returned\n// with an empty digest value. If multiple matches are found\n// ErrDigestAmbiguous will be returned with an empty digest value.\nfunc (dst *Set) Lookup(d string) (digest.Digest, error) {\n\tdst.mutex.RLock()\n\tdefer dst.mutex.RUnlock()\n\tif len(dst.entries) == 0 {\n\t\treturn \"\", ErrDigestNotFound\n\t}\n\tvar (\n\t\tsearchFunc func(int) bool\n\t\talg        digest.Algorithm\n\t\thex        string\n\t)\n\tdgst, err := digest.Parse(d)\n\tif err == digest.ErrDigestInvalidFormat {\n\t\thex = d\n\t\tsearchFunc = func(i int) bool {\n\t\t\treturn dst.entries[i].val >= d\n\t\t}\n\t} else {\n\t\thex = dgst.Hex()\n\t\talg = dgst.Algorithm()\n\t\tsearchFunc = func(i int) bool {\n\t\t\tif dst.entries[i].val == hex {\n\t\t\t\treturn dst.entries[i].alg >= alg\n\t\t\t}\n\t\t\treturn dst.entries[i].val >= hex\n\t\t}\n\t}\n\tidx := sort.Search(len(dst.entries), searchFunc)\n\tif idx == len(dst.entries) || !checkShortMatch(dst.entries[idx].alg, dst.entries[idx].val, string(alg), hex) {\n\t\treturn \"\", ErrDigestNotFound\n\t}\n\tif dst.entries[idx].alg == alg && dst.entries[idx].val == hex {\n\t\treturn dst.entries[idx].digest, nil\n\t}\n\tif idx+1 < len(dst.entries) && checkShortMatch(dst.entries[idx+1].alg, dst.entries[idx+1].val, string(alg), hex) {\n\t\treturn \"\", ErrDigestAmbiguous\n\t}\n\n\treturn dst.entries[idx].digest, nil\n}\n\n// Add adds the given digest to the set. An error will be returned\n// if the given digest is invalid. If the digest already exists in the\n// set, this operation will be a no-op.\nfunc (dst *Set) Add(d digest.Digest) error {\n\tif err := d.Validate(); err != nil {\n\t\treturn err\n\t}\n\tdst.mutex.Lock()\n\tdefer dst.mutex.Unlock()\n\tentry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}\n\tsearchFunc := func(i int) bool {\n\t\tif dst.entries[i].val == entry.val {\n\t\t\treturn dst.entries[i].alg >= entry.alg\n\t\t}\n\t\treturn dst.entries[i].val >= entry.val\n\t}\n\tidx := sort.Search(len(dst.entries), searchFunc)\n\tif idx == len(dst.entries) {\n\t\tdst.entries = append(dst.entries, entry)\n\t\treturn nil\n\t} else if dst.entries[idx].digest == d {\n\t\treturn nil\n\t}\n\n\tentries := append(dst.entries, nil)\n\tcopy(entries[idx+1:], entries[idx:len(entries)-1])\n\tentries[idx] = entry\n\tdst.entries = entries\n\treturn nil\n}\n\n// Remove removes the given digest from the set. An err will be\n// returned if the given digest is invalid. If the digest does\n// not exist in the set, this operation will be a no-op.\nfunc (dst *Set) Remove(d digest.Digest) error {\n\tif err := d.Validate(); err != nil {\n\t\treturn err\n\t}\n\tdst.mutex.Lock()\n\tdefer dst.mutex.Unlock()\n\tentry := &digestEntry{alg: d.Algorithm(), val: d.Hex(), digest: d}\n\tsearchFunc := func(i int) bool {\n\t\tif dst.entries[i].val == entry.val {\n\t\t\treturn dst.entries[i].alg >= entry.alg\n\t\t}\n\t\treturn dst.entries[i].val >= entry.val\n\t}\n\tidx := sort.Search(len(dst.entries), searchFunc)\n\t// Not found if idx is after or value at idx is not digest\n\tif idx == len(dst.entries) || dst.entries[idx].digest != d {\n\t\treturn nil\n\t}\n\n\tentries := dst.entries\n\tcopy(entries[idx:], entries[idx+1:])\n\tentries = entries[:len(entries)-1]\n\tdst.entries = entries\n\n\treturn nil\n}\n\n// All returns all the digests in the set\nfunc (dst *Set) All() []digest.Digest {\n\tdst.mutex.RLock()\n\tdefer dst.mutex.RUnlock()\n\tretValues := make([]digest.Digest, len(dst.entries))\n\tfor i := range dst.entries {\n\t\tretValues[i] = dst.entries[i].digest\n\t}\n\n\treturn retValues\n}\n\n// ShortCodeTable returns a map of Digest to unique short codes. The\n// length represents the minimum value, the maximum length may be the\n// entire value of digest if uniqueness cannot be achieved without the\n// full value. This function will attempt to make short codes as short\n// as possible to be unique.\nfunc ShortCodeTable(dst *Set, length int) map[digest.Digest]string {\n\tdst.mutex.RLock()\n\tdefer dst.mutex.RUnlock()\n\tm := make(map[digest.Digest]string, len(dst.entries))\n\tl := length\n\tresetIdx := 0\n\tfor i := 0; i < len(dst.entries); i++ {\n\t\tvar short string\n\t\textended := true\n\t\tfor extended {\n\t\t\textended = false\n\t\t\tif len(dst.entries[i].val) <= l {\n\t\t\t\tshort = dst.entries[i].digest.String()\n\t\t\t} else {\n\t\t\t\tshort = dst.entries[i].val[:l]\n\t\t\t\tfor j := i + 1; j < len(dst.entries); j++ {\n\t\t\t\t\tif checkShortMatch(dst.entries[j].alg, dst.entries[j].val, \"\", short) {\n\t\t\t\t\t\tif j > resetIdx {\n\t\t\t\t\t\t\tresetIdx = j\n\t\t\t\t\t\t}\n\t\t\t\t\t\textended = true\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif extended {\n\t\t\t\t\tl++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tm[dst.entries[i].digest] = short\n\t\tif i >= resetIdx {\n\t\t\tl = length\n\t\t}\n\t}\n\treturn m\n}\n\ntype digestEntry struct {\n\talg    digest.Algorithm\n\tval    string\n\tdigest digest.Digest\n}\n\ntype digestEntries []*digestEntry\n\nfunc (d digestEntries) Len() int {\n\treturn len(d)\n}\n\nfunc (d digestEntries) Less(i, j int) bool {\n\tif d[i].val != d[j].val {\n\t\treturn d[i].val < d[j].val\n\t}\n\treturn d[i].alg < d[j].alg\n}\n\nfunc (d digestEntries) Swap(i, j int) {\n\td[i], d[j] = d[j], d[i]\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/distribution/v3/reference/helpers.go",
    "content": "package reference\n\nimport \"path\"\n\n// IsNameOnly returns true if reference only contains a repo name.\nfunc IsNameOnly(ref Named) bool {\n\tif _, ok := ref.(NamedTagged); ok {\n\t\treturn false\n\t}\n\tif _, ok := ref.(Canonical); ok {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// FamiliarName returns the familiar name string\n// for the given named, familiarizing if needed.\nfunc FamiliarName(ref Named) string {\n\tif nn, ok := ref.(normalizedNamed); ok {\n\t\treturn nn.Familiar().Name()\n\t}\n\treturn ref.Name()\n}\n\n// FamiliarString returns the familiar string representation\n// for the given reference, familiarizing if needed.\nfunc FamiliarString(ref Reference) string {\n\tif nn, ok := ref.(normalizedNamed); ok {\n\t\treturn nn.Familiar().String()\n\t}\n\treturn ref.String()\n}\n\n// FamiliarMatch reports whether ref matches the specified pattern.\n// See https://godoc.org/path#Match for supported patterns.\nfunc FamiliarMatch(pattern string, ref Reference) (bool, error) {\n\tmatched, err := path.Match(pattern, FamiliarString(ref))\n\tif namedRef, isNamed := ref.(Named); isNamed && !matched {\n\t\tmatched, _ = path.Match(pattern, FamiliarName(namedRef))\n\t}\n\treturn matched, err\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/distribution/v3/reference/normalize.go",
    "content": "package reference\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/distribution/distribution/v3/digestset\"\n\t\"github.com/opencontainers/go-digest\"\n)\n\nvar (\n\tlegacyDefaultDomain = \"index.docker.io\"\n\tdefaultDomain       = \"docker.io\"\n\tofficialRepoName    = \"library\"\n\tdefaultTag          = \"latest\"\n)\n\n// normalizedNamed represents a name which has been\n// normalized and has a familiar form. A familiar name\n// is what is used in Docker UI. An example normalized\n// name is \"docker.io/library/ubuntu\" and corresponding\n// familiar name of \"ubuntu\".\ntype normalizedNamed interface {\n\tNamed\n\tFamiliar() Named\n}\n\n// ParseNormalizedNamed parses a string into a named reference\n// transforming a familiar name from Docker UI to a fully\n// qualified reference. If the value may be an identifier\n// use ParseAnyReference.\nfunc ParseNormalizedNamed(s string) (Named, error) {\n\tif ok := anchoredIdentifierRegexp.MatchString(s); ok {\n\t\treturn nil, fmt.Errorf(\"invalid repository name (%s), cannot specify 64-byte hexadecimal strings\", s)\n\t}\n\tdomain, remainder := splitDockerDomain(s)\n\tvar remoteName string\n\tif tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {\n\t\tremoteName = remainder[:tagSep]\n\t} else {\n\t\tremoteName = remainder\n\t}\n\tif strings.ToLower(remoteName) != remoteName {\n\t\treturn nil, fmt.Errorf(\"invalid reference format: repository name (%s) must be lowercase\", remoteName)\n\t}\n\n\tref, err := Parse(domain + \"/\" + remainder)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnamed, isNamed := ref.(Named)\n\tif !isNamed {\n\t\treturn nil, fmt.Errorf(\"reference %s has no name\", ref.String())\n\t}\n\treturn named, nil\n}\n\n// ParseDockerRef normalizes the image reference following the docker convention. This is added\n// mainly for backward compatibility.\n// The reference returned can only be either tagged or digested. For reference contains both tag\n// and digest, the function returns digested reference, e.g. docker.io/library/busybox:latest@\n// sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa will be returned as\n// docker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa.\nfunc ParseDockerRef(ref string) (Named, error) {\n\tnamed, err := ParseNormalizedNamed(ref)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif _, ok := named.(NamedTagged); ok {\n\t\tif canonical, ok := named.(Canonical); ok {\n\t\t\t// The reference is both tagged and digested, only\n\t\t\t// return digested.\n\t\t\tnewNamed, err := WithName(canonical.Name())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tnewCanonical, err := WithDigest(newNamed, canonical.Digest())\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn newCanonical, nil\n\t\t}\n\t}\n\treturn TagNameOnly(named), nil\n}\n\n// splitDockerDomain splits a repository name to domain and remotename string.\n// If no valid domain is found, the default domain is used. Repository name\n// needs to be already validated before.\nfunc splitDockerDomain(name string) (domain, remainder string) {\n\ti := strings.IndexRune(name, '/')\n\tif i == -1 || (!strings.ContainsAny(name[:i], \".:\") && name[:i] != \"localhost\" && strings.ToLower(name[:i]) == name[:i]) {\n\t\tdomain, remainder = defaultDomain, name\n\t} else {\n\t\tdomain, remainder = name[:i], name[i+1:]\n\t}\n\tif domain == legacyDefaultDomain {\n\t\tdomain = defaultDomain\n\t}\n\tif domain == defaultDomain && !strings.ContainsRune(remainder, '/') {\n\t\tremainder = officialRepoName + \"/\" + remainder\n\t}\n\treturn\n}\n\n// familiarizeName returns a shortened version of the name familiar\n// to to the Docker UI. Familiar names have the default domain\n// \"docker.io\" and \"library/\" repository prefix removed.\n// For example, \"docker.io/library/redis\" will have the familiar\n// name \"redis\" and \"docker.io/dmcgowan/myapp\" will be \"dmcgowan/myapp\".\n// Returns a familiarized named only reference.\nfunc familiarizeName(named namedRepository) repository {\n\trepo := repository{\n\t\tdomain: named.Domain(),\n\t\tpath:   named.Path(),\n\t}\n\n\tif repo.domain == defaultDomain {\n\t\trepo.domain = \"\"\n\t\t// Handle official repositories which have the pattern \"library/<official repo name>\"\n\t\tif split := strings.Split(repo.path, \"/\"); len(split) == 2 && split[0] == officialRepoName {\n\t\t\trepo.path = split[1]\n\t\t}\n\t}\n\treturn repo\n}\n\nfunc (r reference) Familiar() Named {\n\treturn reference{\n\t\tnamedRepository: familiarizeName(r.namedRepository),\n\t\ttag:             r.tag,\n\t\tdigest:          r.digest,\n\t}\n}\n\nfunc (r repository) Familiar() Named {\n\treturn familiarizeName(r)\n}\n\nfunc (t taggedReference) Familiar() Named {\n\treturn taggedReference{\n\t\tnamedRepository: familiarizeName(t.namedRepository),\n\t\ttag:             t.tag,\n\t}\n}\n\nfunc (c canonicalReference) Familiar() Named {\n\treturn canonicalReference{\n\t\tnamedRepository: familiarizeName(c.namedRepository),\n\t\tdigest:          c.digest,\n\t}\n}\n\n// TagNameOnly adds the default tag \"latest\" to a reference if it only has\n// a repo name.\nfunc TagNameOnly(ref Named) Named {\n\tif IsNameOnly(ref) {\n\t\tnamedTagged, err := WithTag(ref, defaultTag)\n\t\tif err != nil {\n\t\t\t// Default tag must be valid, to create a NamedTagged\n\t\t\t// type with non-validated input the WithTag function\n\t\t\t// should be used instead\n\t\t\tpanic(err)\n\t\t}\n\t\treturn namedTagged\n\t}\n\treturn ref\n}\n\n// ParseAnyReference parses a reference string as a possible identifier,\n// full digest, or familiar name.\nfunc ParseAnyReference(ref string) (Reference, error) {\n\tif ok := anchoredIdentifierRegexp.MatchString(ref); ok {\n\t\treturn digestReference(\"sha256:\" + ref), nil\n\t}\n\tif dgst, err := digest.Parse(ref); err == nil {\n\t\treturn digestReference(dgst), nil\n\t}\n\n\treturn ParseNormalizedNamed(ref)\n}\n\n// ParseAnyReferenceWithSet parses a reference string as a possible short\n// identifier to be matched in a digest set, a full digest, or familiar name.\nfunc ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) {\n\tif ok := anchoredShortIdentifierRegexp.MatchString(ref); ok {\n\t\tdgst, err := ds.Lookup(ref)\n\t\tif err == nil {\n\t\t\treturn digestReference(dgst), nil\n\t\t}\n\t} else {\n\t\tif dgst, err := digest.Parse(ref); err == nil {\n\t\t\treturn digestReference(dgst), nil\n\t\t}\n\t}\n\n\treturn ParseNormalizedNamed(ref)\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/distribution/v3/reference/reference.go",
    "content": "// Package reference provides a general type to represent any way of referencing images within the registry.\n// Its main purpose is to abstract tags and digests (content-addressable hash).\n//\n// Grammar\n//\n// \treference                       := name [ \":\" tag ] [ \"@\" digest ]\n//\tname                            := [domain '/'] path-component ['/' path-component]*\n//\tdomain                          := domain-component ['.' domain-component]* [':' port-number]\n//\tdomain-component                := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/\n//\tport-number                     := /[0-9]+/\n//\tpath-component                  := alpha-numeric [separator alpha-numeric]*\n// \talpha-numeric                   := /[a-z0-9]+/\n//\tseparator                       := /[_.]|__|[-]*/\n//\n//\ttag                             := /[\\w][\\w.-]{0,127}/\n//\n//\tdigest                          := digest-algorithm \":\" digest-hex\n//\tdigest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*\n//\tdigest-algorithm-separator      := /[+.-_]/\n//\tdigest-algorithm-component      := /[A-Za-z][A-Za-z0-9]*/\n//\tdigest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value\n//\n//\tidentifier                      := /[a-f0-9]{64}/\n//\tshort-identifier                := /[a-f0-9]{6,64}/\npackage reference\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/opencontainers/go-digest\"\n)\n\nconst (\n\t// NameTotalLengthMax is the maximum total number of characters in a repository name.\n\tNameTotalLengthMax = 255\n)\n\nvar (\n\t// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.\n\tErrReferenceInvalidFormat = errors.New(\"invalid reference format\")\n\n\t// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.\n\tErrTagInvalidFormat = errors.New(\"invalid tag format\")\n\n\t// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.\n\tErrDigestInvalidFormat = errors.New(\"invalid digest format\")\n\n\t// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.\n\tErrNameContainsUppercase = errors.New(\"repository name must be lowercase\")\n\n\t// ErrNameEmpty is returned for empty, invalid repository names.\n\tErrNameEmpty = errors.New(\"repository name must have at least one component\")\n\n\t// ErrNameTooLong is returned when a repository name is longer than NameTotalLengthMax.\n\tErrNameTooLong = fmt.Errorf(\"repository name must not be more than %v characters\", NameTotalLengthMax)\n\n\t// ErrNameNotCanonical is returned when a name is not canonical.\n\tErrNameNotCanonical = errors.New(\"repository name must be canonical\")\n)\n\n// Reference is an opaque object reference identifier that may include\n// modifiers such as a hostname, name, tag, and digest.\ntype Reference interface {\n\t// String returns the full reference\n\tString() string\n}\n\n// Field provides a wrapper type for resolving correct reference types when\n// working with encoding.\ntype Field struct {\n\treference Reference\n}\n\n// AsField wraps a reference in a Field for encoding.\nfunc AsField(reference Reference) Field {\n\treturn Field{reference}\n}\n\n// Reference unwraps the reference type from the field to\n// return the Reference object. This object should be\n// of the appropriate type to further check for different\n// reference types.\nfunc (f Field) Reference() Reference {\n\treturn f.reference\n}\n\n// MarshalText serializes the field to byte text which\n// is the string of the reference.\nfunc (f Field) MarshalText() (p []byte, err error) {\n\treturn []byte(f.reference.String()), nil\n}\n\n// UnmarshalText parses text bytes by invoking the\n// reference parser to ensure the appropriately\n// typed reference object is wrapped by field.\nfunc (f *Field) UnmarshalText(p []byte) error {\n\tr, err := Parse(string(p))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tf.reference = r\n\treturn nil\n}\n\n// Named is an object with a full name\ntype Named interface {\n\tReference\n\tName() string\n}\n\n// Tagged is an object which has a tag\ntype Tagged interface {\n\tReference\n\tTag() string\n}\n\n// NamedTagged is an object including a name and tag.\ntype NamedTagged interface {\n\tNamed\n\tTag() string\n}\n\n// Digested is an object which has a digest\n// in which it can be referenced by\ntype Digested interface {\n\tReference\n\tDigest() digest.Digest\n}\n\n// Canonical reference is an object with a fully unique\n// name including a name with domain and digest\ntype Canonical interface {\n\tNamed\n\tDigest() digest.Digest\n}\n\n// namedRepository is a reference to a repository with a name.\n// A namedRepository has both domain and path components.\ntype namedRepository interface {\n\tNamed\n\tDomain() string\n\tPath() string\n}\n\n// Domain returns the domain part of the Named reference\nfunc Domain(named Named) string {\n\tif r, ok := named.(namedRepository); ok {\n\t\treturn r.Domain()\n\t}\n\tdomain, _ := splitDomain(named.Name())\n\treturn domain\n}\n\n// Path returns the name without the domain part of the Named reference\nfunc Path(named Named) (name string) {\n\tif r, ok := named.(namedRepository); ok {\n\t\treturn r.Path()\n\t}\n\t_, path := splitDomain(named.Name())\n\treturn path\n}\n\nfunc splitDomain(name string) (string, string) {\n\tmatch := anchoredNameRegexp.FindStringSubmatch(name)\n\tif len(match) != 3 {\n\t\treturn \"\", name\n\t}\n\treturn match[1], match[2]\n}\n\n// SplitHostname splits a named reference into a\n// hostname and name string. If no valid hostname is\n// found, the hostname is empty and the full value\n// is returned as name\n// DEPRECATED: Use Domain or Path\nfunc SplitHostname(named Named) (string, string) {\n\tif r, ok := named.(namedRepository); ok {\n\t\treturn r.Domain(), r.Path()\n\t}\n\treturn splitDomain(named.Name())\n}\n\n// Parse parses s and returns a syntactically valid Reference.\n// If an error was encountered it is returned, along with a nil Reference.\n// NOTE: Parse will not handle short digests.\nfunc Parse(s string) (Reference, error) {\n\tmatches := ReferenceRegexp.FindStringSubmatch(s)\n\tif matches == nil {\n\t\tif s == \"\" {\n\t\t\treturn nil, ErrNameEmpty\n\t\t}\n\t\tif ReferenceRegexp.FindStringSubmatch(strings.ToLower(s)) != nil {\n\t\t\treturn nil, ErrNameContainsUppercase\n\t\t}\n\t\treturn nil, ErrReferenceInvalidFormat\n\t}\n\n\tif len(matches[1]) > NameTotalLengthMax {\n\t\treturn nil, ErrNameTooLong\n\t}\n\n\tvar repo repository\n\n\tnameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])\n\tif len(nameMatch) == 3 {\n\t\trepo.domain = nameMatch[1]\n\t\trepo.path = nameMatch[2]\n\t} else {\n\t\trepo.domain = \"\"\n\t\trepo.path = matches[1]\n\t}\n\n\tref := reference{\n\t\tnamedRepository: repo,\n\t\ttag:             matches[2],\n\t}\n\tif matches[3] != \"\" {\n\t\tvar err error\n\t\tref.digest, err = digest.Parse(matches[3])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tr := getBestReferenceType(ref)\n\tif r == nil {\n\t\treturn nil, ErrNameEmpty\n\t}\n\n\treturn r, nil\n}\n\n// ParseNamed parses s and returns a syntactically valid reference implementing\n// the Named interface. The reference must have a name and be in the canonical\n// form, otherwise an error is returned.\n// If an error was encountered it is returned, along with a nil Reference.\n// NOTE: ParseNamed will not handle short digests.\nfunc ParseNamed(s string) (Named, error) {\n\tnamed, err := ParseNormalizedNamed(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif named.String() != s {\n\t\treturn nil, ErrNameNotCanonical\n\t}\n\treturn named, nil\n}\n\n// WithName returns a named object representing the given string. If the input\n// is invalid ErrReferenceInvalidFormat will be returned.\nfunc WithName(name string) (Named, error) {\n\tif len(name) > NameTotalLengthMax {\n\t\treturn nil, ErrNameTooLong\n\t}\n\n\tmatch := anchoredNameRegexp.FindStringSubmatch(name)\n\tif match == nil || len(match) != 3 {\n\t\treturn nil, ErrReferenceInvalidFormat\n\t}\n\treturn repository{\n\t\tdomain: match[1],\n\t\tpath:   match[2],\n\t}, nil\n}\n\n// WithTag combines the name from \"name\" and the tag from \"tag\" to form a\n// reference incorporating both the name and the tag.\nfunc WithTag(name Named, tag string) (NamedTagged, error) {\n\tif !anchoredTagRegexp.MatchString(tag) {\n\t\treturn nil, ErrTagInvalidFormat\n\t}\n\tvar repo repository\n\tif r, ok := name.(namedRepository); ok {\n\t\trepo.domain = r.Domain()\n\t\trepo.path = r.Path()\n\t} else {\n\t\trepo.path = name.Name()\n\t}\n\tif canonical, ok := name.(Canonical); ok {\n\t\treturn reference{\n\t\t\tnamedRepository: repo,\n\t\t\ttag:             tag,\n\t\t\tdigest:          canonical.Digest(),\n\t\t}, nil\n\t}\n\treturn taggedReference{\n\t\tnamedRepository: repo,\n\t\ttag:             tag,\n\t}, nil\n}\n\n// WithDigest combines the name from \"name\" and the digest from \"digest\" to form\n// a reference incorporating both the name and the digest.\nfunc WithDigest(name Named, digest digest.Digest) (Canonical, error) {\n\tif !anchoredDigestRegexp.MatchString(digest.String()) {\n\t\treturn nil, ErrDigestInvalidFormat\n\t}\n\tvar repo repository\n\tif r, ok := name.(namedRepository); ok {\n\t\trepo.domain = r.Domain()\n\t\trepo.path = r.Path()\n\t} else {\n\t\trepo.path = name.Name()\n\t}\n\tif tagged, ok := name.(Tagged); ok {\n\t\treturn reference{\n\t\t\tnamedRepository: repo,\n\t\t\ttag:             tagged.Tag(),\n\t\t\tdigest:          digest,\n\t\t}, nil\n\t}\n\treturn canonicalReference{\n\t\tnamedRepository: repo,\n\t\tdigest:          digest,\n\t}, nil\n}\n\n// TrimNamed removes any tag or digest from the named reference.\nfunc TrimNamed(ref Named) Named {\n\tdomain, path := SplitHostname(ref)\n\treturn repository{\n\t\tdomain: domain,\n\t\tpath:   path,\n\t}\n}\n\nfunc getBestReferenceType(ref reference) Reference {\n\tif ref.Name() == \"\" {\n\t\t// Allow digest only references\n\t\tif ref.digest != \"\" {\n\t\t\treturn digestReference(ref.digest)\n\t\t}\n\t\treturn nil\n\t}\n\tif ref.tag == \"\" {\n\t\tif ref.digest != \"\" {\n\t\t\treturn canonicalReference{\n\t\t\t\tnamedRepository: ref.namedRepository,\n\t\t\t\tdigest:          ref.digest,\n\t\t\t}\n\t\t}\n\t\treturn ref.namedRepository\n\t}\n\tif ref.digest == \"\" {\n\t\treturn taggedReference{\n\t\t\tnamedRepository: ref.namedRepository,\n\t\t\ttag:             ref.tag,\n\t\t}\n\t}\n\n\treturn ref\n}\n\ntype reference struct {\n\tnamedRepository\n\ttag    string\n\tdigest digest.Digest\n}\n\nfunc (r reference) String() string {\n\treturn r.Name() + \":\" + r.tag + \"@\" + r.digest.String()\n}\n\nfunc (r reference) Tag() string {\n\treturn r.tag\n}\n\nfunc (r reference) Digest() digest.Digest {\n\treturn r.digest\n}\n\ntype repository struct {\n\tdomain string\n\tpath   string\n}\n\nfunc (r repository) String() string {\n\treturn r.Name()\n}\n\nfunc (r repository) Name() string {\n\tif r.domain == \"\" {\n\t\treturn r.path\n\t}\n\treturn r.domain + \"/\" + r.path\n}\n\nfunc (r repository) Domain() string {\n\treturn r.domain\n}\n\nfunc (r repository) Path() string {\n\treturn r.path\n}\n\ntype digestReference digest.Digest\n\nfunc (d digestReference) String() string {\n\treturn digest.Digest(d).String()\n}\n\nfunc (d digestReference) Digest() digest.Digest {\n\treturn digest.Digest(d)\n}\n\ntype taggedReference struct {\n\tnamedRepository\n\ttag string\n}\n\nfunc (t taggedReference) String() string {\n\treturn t.Name() + \":\" + t.tag\n}\n\nfunc (t taggedReference) Tag() string {\n\treturn t.tag\n}\n\ntype canonicalReference struct {\n\tnamedRepository\n\tdigest digest.Digest\n}\n\nfunc (c canonicalReference) String() string {\n\treturn c.Name() + \"@\" + c.digest.String()\n}\n\nfunc (c canonicalReference) Digest() digest.Digest {\n\treturn c.digest\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/distribution/v3/reference/regexp.go",
    "content": "package reference\n\nimport \"regexp\"\n\nvar (\n\t// alphaNumericRegexp defines the alpha numeric atom, typically a\n\t// component of names. This only allows lower case characters and digits.\n\talphaNumericRegexp = match(`[a-z0-9]+`)\n\n\t// separatorRegexp defines the separators allowed to be embedded in name\n\t// components. This allow one period, one or two underscore and multiple\n\t// dashes. Repeated dashes and underscores are intentionally treated\n\t// differently. In order to support valid hostnames as name components,\n\t// supporting repeated dash was added. Additionally double underscore is\n\t// now allowed as a separator to loosen the restriction for previously\n\t// supported names.\n\tseparatorRegexp = match(`(?:[._]|__|[-]*)`)\n\n\t// nameComponentRegexp restricts registry path component names to start\n\t// with at least one letter or number, with following parts able to be\n\t// separated by one period, one or two underscore and multiple dashes.\n\tnameComponentRegexp = expression(\n\t\talphaNumericRegexp,\n\t\toptional(repeated(separatorRegexp, alphaNumericRegexp)))\n\n\t// domainComponentRegexp restricts the registry domain component of a\n\t// repository name to start with a component as defined by DomainRegexp\n\t// and followed by an optional port.\n\tdomainComponentRegexp = match(`(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`)\n\n\t// DomainRegexp defines the structure of potential domain components\n\t// that may be part of image names. This is purposely a subset of what is\n\t// allowed by DNS to ensure backwards compatibility with Docker image\n\t// names.\n\tDomainRegexp = expression(\n\t\tdomainComponentRegexp,\n\t\toptional(repeated(literal(`.`), domainComponentRegexp)),\n\t\toptional(literal(`:`), match(`[0-9]+`)))\n\n\t// TagRegexp matches valid tag names. From docker/docker:graph/tags.go.\n\tTagRegexp = match(`[\\w][\\w.-]{0,127}`)\n\n\t// anchoredTagRegexp matches valid tag names, anchored at the start and\n\t// end of the matched string.\n\tanchoredTagRegexp = anchored(TagRegexp)\n\n\t// DigestRegexp matches valid digests.\n\tDigestRegexp = match(`[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`)\n\n\t// anchoredDigestRegexp matches valid digests, anchored at the start and\n\t// end of the matched string.\n\tanchoredDigestRegexp = anchored(DigestRegexp)\n\n\t// NameRegexp is the format for the name component of references. The\n\t// regexp has capturing groups for the domain and name part omitting\n\t// the separating forward slash from either.\n\tNameRegexp = expression(\n\t\toptional(DomainRegexp, literal(`/`)),\n\t\tnameComponentRegexp,\n\t\toptional(repeated(literal(`/`), nameComponentRegexp)))\n\n\t// anchoredNameRegexp is used to parse a name value, capturing the\n\t// domain and trailing components.\n\tanchoredNameRegexp = anchored(\n\t\toptional(capture(DomainRegexp), literal(`/`)),\n\t\tcapture(nameComponentRegexp,\n\t\t\toptional(repeated(literal(`/`), nameComponentRegexp))))\n\n\t// ReferenceRegexp is the full supported format of a reference. The regexp\n\t// is anchored and has capturing groups for name, tag, and digest\n\t// components.\n\tReferenceRegexp = anchored(capture(NameRegexp),\n\t\toptional(literal(\":\"), capture(TagRegexp)),\n\t\toptional(literal(\"@\"), capture(DigestRegexp)))\n\n\t// IdentifierRegexp is the format for string identifier used as a\n\t// content addressable identifier using sha256. These identifiers\n\t// are like digests without the algorithm, since sha256 is used.\n\tIdentifierRegexp = match(`([a-f0-9]{64})`)\n\n\t// ShortIdentifierRegexp is the format used to represent a prefix\n\t// of an identifier. A prefix may be used to match a sha256 identifier\n\t// within a list of trusted identifiers.\n\tShortIdentifierRegexp = match(`([a-f0-9]{6,64})`)\n\n\t// anchoredIdentifierRegexp is used to check or match an\n\t// identifier value, anchored at start and end of string.\n\tanchoredIdentifierRegexp = anchored(IdentifierRegexp)\n\n\t// anchoredShortIdentifierRegexp is used to check if a value\n\t// is a possible identifier prefix, anchored at start and end\n\t// of string.\n\tanchoredShortIdentifierRegexp = anchored(ShortIdentifierRegexp)\n)\n\n// match compiles the string to a regular expression.\nvar match = regexp.MustCompile\n\n// literal compiles s into a literal regular expression, escaping any regexp\n// reserved characters.\nfunc literal(s string) *regexp.Regexp {\n\tre := match(regexp.QuoteMeta(s))\n\n\tif _, complete := re.LiteralPrefix(); !complete {\n\t\tpanic(\"must be a literal\")\n\t}\n\n\treturn re\n}\n\n// expression defines a full expression, where each regular expression must\n// follow the previous.\nfunc expression(res ...*regexp.Regexp) *regexp.Regexp {\n\tvar s string\n\tfor _, re := range res {\n\t\ts += re.String()\n\t}\n\n\treturn match(s)\n}\n\n// optional wraps the expression in a non-capturing group and makes the\n// production optional.\nfunc optional(res ...*regexp.Regexp) *regexp.Regexp {\n\treturn match(group(expression(res...)).String() + `?`)\n}\n\n// repeated wraps the regexp in a non-capturing group to get one or more\n// matches.\nfunc repeated(res ...*regexp.Regexp) *regexp.Regexp {\n\treturn match(group(expression(res...)).String() + `+`)\n}\n\n// group wraps the regexp in a non-capturing group.\nfunc group(res ...*regexp.Regexp) *regexp.Regexp {\n\treturn match(`(?:` + expression(res...).String() + `)`)\n}\n\n// capture wraps the expression in a capturing group.\nfunc capture(res ...*regexp.Regexp) *regexp.Regexp {\n\treturn match(`(` + expression(res...).String() + `)`)\n}\n\n// anchored anchors the regular expression by adding start and end delimiters.\nfunc anchored(res ...*regexp.Regexp) *regexp.Regexp {\n\treturn match(`^` + expression(res...).String() + `$`)\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/.gitattributes",
    "content": "*.go text eol=lf\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/.gitignore",
    "content": "# Cover profiles\n*.out\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/.golangci.yml",
    "content": "linters:\n  enable:\n    - bodyclose\n    - dupword # Checks for duplicate words in the source code\n    - gofmt\n    - goimports\n    - ineffassign\n    - misspell\n    - revive\n    - staticcheck\n    - unconvert\n    - unused\n    - vet\n  disable:\n    - errcheck\n\nrun:\n  deadline: 2m\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/CODE-OF-CONDUCT.md",
    "content": "# Code of Conduct\n\nWe follow the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).\n\nPlease contact the [CNCF Code of Conduct Committee](mailto:conduct@cncf.io) in order to report violations of the Code of Conduct.\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/CONTRIBUTING.md",
    "content": "# Contributing to the reference library\n\n## Community help\n\nIf you need help, please ask in the [#distribution](https://cloud-native.slack.com/archives/C01GVR8SY4R) channel on CNCF community slack.\n[Click here for an invite to the CNCF community slack](https://slack.cncf.io/)\n\n## Reporting security issues\n\nThe maintainers take security seriously. If you discover a security\nissue, please bring it to their attention right away!\n\nPlease **DO NOT** file a public issue, instead send your report privately to\n[cncf-distribution-security@lists.cncf.io](mailto:cncf-distribution-security@lists.cncf.io).\n\n## Reporting an issue properly\n\nBy following these simple rules you will get better and faster feedback on your issue.\n\n - search the bugtracker for an already reported issue\n\n### If you found an issue that describes your problem:\n\n - please read other user comments first, and confirm this is the same issue: a given error condition might be indicative of different problems - you may also find a workaround in the comments\n - please refrain from adding \"same thing here\" or \"+1\" comments\n - you don't need to comment on an issue to get notified of updates: just hit the \"subscribe\" button\n - comment if you have some new, technical and relevant information to add to the case\n - __DO NOT__ comment on closed issues or merged PRs. If you think you have a related problem, open up a new issue and reference the PR or issue.\n\n### If you have not found an existing issue that describes your problem:\n\n 1. create a new issue, with a succinct title that describes your issue:\n   - bad title: \"It doesn't work with my docker\"\n   - good title: \"Private registry push fail: 400 error with E_INVALID_DIGEST\"\n 2. copy the output of (or similar for other container tools):\n   - `docker version`\n   - `docker info`\n   - `docker exec <registry-container> registry --version`\n 3. copy the command line you used to launch your Registry\n 4. restart your docker daemon in debug mode (add `-D` to the daemon launch arguments)\n 5. reproduce your problem and get your docker daemon logs showing the error\n 6. if relevant, copy your registry logs that show the error\n 7. provide any relevant detail about your specific Registry configuration (e.g., storage backend used)\n 8. indicate if you are using an enterprise proxy, Nginx, or anything else between you and your Registry\n\n## Contributing Code\n\nContributions should be made via pull requests. Pull requests will be reviewed\nby one or more maintainers or reviewers and merged when acceptable.\n\nYou should follow the basic GitHub workflow:\n\n 1. Use your own [fork](https://help.github.com/en/articles/about-forks)\n 2. Create your [change](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)\n 3. Test your code\n 4. [Commit](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages) your work, always [sign your commits](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#commit-messages)\n 5. Push your change to your fork and create a [Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork)\n\nRefer to [containerd's contribution guide](https://github.com/containerd/project/blob/master/CONTRIBUTING.md#successful-changes)\nfor tips on creating a successful contribution.\n\n## Sign your work\n\nThe sign-off is a simple line at the end of the explanation for the patch. Your\nsignature certifies that you wrote the patch or otherwise have the right to pass\nit on as an open-source patch. The rules are pretty simple: if you can certify\nthe below (from [developercertificate.org](http://developercertificate.org/)):\n\n```\nDeveloper Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n660 York Street, Suite 102,\nSan Francisco, CA 94110 USA\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n    have the right to submit it under the open source license\n    indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n    of my knowledge, is covered under an appropriate open source\n    license and I have the right under that license to submit that\n    work with modifications, whether created in whole or in part\n    by me, under the same open source license (unless I am\n    permitted to submit under a different license), as indicated\n    in the file; or\n\n(c) The contribution was provided directly to me by some other\n    person who certified (a), (b) or (c) and I have not modified\n    it.\n\n(d) I understand and agree that this project and the contribution\n    are public and that a record of the contribution (including all\n    personal information I submit with it, including my sign-off) is\n    maintained indefinitely and may be redistributed consistent with\n    this project or the open source license(s) involved.\n```\n\nThen you just add a line to every git commit message:\n\n    Signed-off-by: Joe Smith <joe.smith@email.com>\n\nUse your real name (sorry, no pseudonyms or anonymous contributions.)\n\nIf you set your `user.name` and `user.email` git configs, you can sign your\ncommit automatically with `git commit -s`.\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/GOVERNANCE.md",
    "content": "# distribution/reference Project Governance\n\nDistribution [Code of Conduct](./CODE-OF-CONDUCT.md) can be found here.\n\nFor specific guidance on practical contribution steps please\nsee our [CONTRIBUTING.md](./CONTRIBUTING.md) guide.\n\n## Maintainership\n\nThere are different types of maintainers, with different responsibilities, but\nall maintainers have 3 things in common:\n\n1) They share responsibility in the project's success.\n2) They have made a long-term, recurring time investment to improve the project.\n3) They spend that time doing whatever needs to be done, not necessarily what\nis the most interesting or fun.\n\nMaintainers are often under-appreciated, because their work is harder to appreciate.\nIt's easy to appreciate a really cool and technically advanced feature. It's harder\nto appreciate the absence of bugs, the slow but steady improvement in stability,\nor the reliability of a release process. But those things distinguish a good\nproject from a great one.\n\n## Reviewers\n\nA reviewer is a core role within the project.\nThey share in reviewing issues and pull requests and their LGTM counts towards the\nrequired LGTM count to merge a code change into the project.\n\nReviewers are part of the organization but do not have write access.\nBecoming a reviewer is a core aspect in the journey to becoming a maintainer.\n\n## Adding maintainers\n\nMaintainers are first and foremost contributors that have shown they are\ncommitted to the long term success of a project. Contributors wanting to become\nmaintainers are expected to be deeply involved in contributing code, pull\nrequest review, and triage of issues in the project for more than three months.\n\nJust contributing does not make you a maintainer, it is about building trust\nwith the current maintainers of the project and being a person that they can\ndepend on and trust to make decisions in the best interest of the project.\n\nPeriodically, the existing maintainers curate a list of contributors that have\nshown regular activity on the project over the prior months. From this list,\nmaintainer candidates are selected and proposed in a pull request or a\nmaintainers communication channel.\n\nAfter a candidate has been announced to the maintainers, the existing\nmaintainers are given five business days to discuss the candidate, raise\nobjections and cast their vote. Votes may take place on the communication\nchannel or via pull request comment. Candidates must be approved by at least 66%\nof the current maintainers by adding their vote on the mailing list. The\nreviewer role has the same process but only requires 33% of current maintainers.\nOnly maintainers of the repository that the candidate is proposed for are\nallowed to vote.\n\nIf a candidate is approved, a maintainer will contact the candidate to invite\nthe candidate to open a pull request that adds the contributor to the\nMAINTAINERS file. The voting process may take place inside a pull request if a\nmaintainer has already discussed the candidacy with the candidate and a\nmaintainer is willing to be a sponsor by opening the pull request. The candidate\nbecomes a maintainer once the pull request is merged.\n\n## Stepping down policy\n\nLife priorities, interests, and passions can change. If you're a maintainer but\nfeel you must remove yourself from the list, inform other maintainers that you\nintend to step down, and if possible, help find someone to pick up your work.\nAt the very least, ensure your work can be continued where you left off.\n\nAfter you've informed other maintainers, create a pull request to remove\nyourself from the MAINTAINERS file.\n\n## Removal of inactive maintainers\n\nSimilar to the procedure for adding new maintainers, existing maintainers can\nbe removed from the list if they do not show significant activity on the\nproject. Periodically, the maintainers review the list of maintainers and their\nactivity over the last three months.\n\nIf a maintainer has shown insufficient activity over this period, a neutral\nperson will contact the maintainer to ask if they want to continue being\na maintainer. If the maintainer decides to step down as a maintainer, they\nopen a pull request to be removed from the MAINTAINERS file.\n\nIf the maintainer wants to remain a maintainer, but is unable to perform the\nrequired duties they can be removed with a vote of at least 66% of the current\nmaintainers. In this case, maintainers should first propose the change to\nmaintainers via the maintainers communication channel, then open a pull request\nfor voting. The voting period is five business days. The voting pull request\nshould not come as a surpise to any maintainer and any discussion related to\nperformance must not be discussed on the pull request.\n\n## How are decisions made?\n\nDocker distribution is an open-source project with an open design philosophy.\nThis means that the repository is the source of truth for EVERY aspect of the\nproject, including its philosophy, design, road map, and APIs. *If it's part of\nthe project, it's in the repo. If it's in the repo, it's part of the project.*\n\nAs a result, all decisions can be expressed as changes to the repository. An\nimplementation change is a change to the source code. An API change is a change\nto the API specification. A philosophy change is a change to the philosophy\nmanifesto, and so on.\n\nAll decisions affecting distribution, big and small, follow the same 3 steps:\n\n* Step 1: Open a pull request. Anyone can do this.\n\n* Step 2: Discuss the pull request. Anyone can do this.\n\n* Step 3: Merge or refuse the pull request. Who does this depends on the nature\nof the pull request and which areas of the project it affects.\n\n## Helping contributors with the DCO\n\nThe [DCO or `Sign your work`](./CONTRIBUTING.md#sign-your-work)\nrequirement is not intended as a roadblock or speed bump.\n\nSome contributors are not as familiar with `git`, or have used a web\nbased editor, and thus asking them to `git commit --amend -s` is not the best\nway forward.\n\nIn this case, maintainers can update the commits based on clause (c) of the DCO.\nThe most trivial way for a contributor to allow the maintainer to do this, is to\nadd a DCO signature in a pull requests's comment, or a maintainer can simply\nnote that the change is sufficiently trivial that it does not substantially\nchange the existing contribution - i.e., a spelling change.\n\nWhen you add someone's DCO, please also add your own to keep a log.\n\n## I'm a maintainer. Should I make pull requests too?\n\nYes. Nobody should ever push to master directly. All changes should be\nmade through a pull request.\n\n## Conflict Resolution\n\nIf you have a technical dispute that you feel has reached an impasse with a\nsubset of the community, any contributor may open an issue, specifically\ncalling for a resolution vote of the current core maintainers to resolve the\ndispute. The same voting quorums required (2/3) for adding and removing\nmaintainers will apply to conflict resolution.\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\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       http://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\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/MAINTAINERS",
    "content": "# Distribution project maintainers & reviewers\n#\n# See GOVERNANCE.md for maintainer versus reviewer roles\n#\n# MAINTAINERS (cncf-distribution-maintainers@lists.cncf.io)\n# GitHub ID, Name, Email address\n\"chrispat\",\"Chris Patterson\",\"chrispat@github.com\"\n\"clarkbw\",\"Bryan Clark\",\"clarkbw@github.com\"\n\"corhere\",\"Cory Snider\",\"csnider@mirantis.com\"\n\"deleteriousEffect\",\"Hayley Swimelar\",\"hswimelar@gitlab.com\"\n\"heww\",\"He Weiwei\",\"hweiwei@vmware.com\"\n\"joaodrp\",\"João Pereira\",\"jpereira@gitlab.com\"\n\"justincormack\",\"Justin Cormack\",\"justin.cormack@docker.com\"\n\"squizzi\",\"Kyle Squizzato\",\"ksquizzato@mirantis.com\"\n\"milosgajdos\",\"Milos Gajdos\",\"milosthegajdos@gmail.com\"\n\"sargun\",\"Sargun Dhillon\",\"sargun@sargun.me\"\n\"wy65701436\",\"Wang Yan\",\"wangyan@vmware.com\"\n\"stevelasker\",\"Steve Lasker\",\"steve.lasker@microsoft.com\"\n#\n# REVIEWERS\n# GitHub ID, Name, Email address\n\"dmcgowan\",\"Derek McGowan\",\"derek@mcgstyle.net\"\n\"stevvooe\",\"Stephen Day\",\"stevvooe@gmail.com\"\n\"thajeztah\",\"Sebastiaan van Stijn\",\"github@gone.nl\"\n\"DavidSpek\", \"David van der Spek\", \"vanderspek.david@gmail.com\"\n\"Jamstah\", \"James Hewitt\", \"james.hewitt@gmail.com\"\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/Makefile",
    "content": "# Project packages.\nPACKAGES=$(shell go list ./...)\n\n# Flags passed to `go test`\nBUILDFLAGS ?= \nTESTFLAGS ?= \n\n.PHONY: all build test coverage\n.DEFAULT: all\n\nall: build\n\nbuild: ## no binaries to build, so just check compilation suceeds\n\tgo build ${BUILDFLAGS} ./...\n\ntest: ## run tests\n\tgo test ${TESTFLAGS} ./...\n\ncoverage: ## generate coverprofiles from the unit tests\n\trm -f coverage.txt\n\tgo test ${TESTFLAGS} -cover -coverprofile=cover.out ./...\n\n.PHONY: help\nhelp:\n\t@awk 'BEGIN {FS = \":.*##\"; printf \"\\nUsage:\\n  make \\033[36m\\033[0m\\n\"} /^[a-zA-Z_\\/%-]+:.*?##/ { printf \"  \\033[36m%-27s\\033[0m %s\\n\", $$1, $$2 } /^##@/ { printf \"\\n\\033[1m%s\\033[0m\\n\", substr($$0, 5) } ' $(MAKEFILE_LIST)\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/README.md",
    "content": "# Distribution reference\n\nGo library to handle references to container images.\n\n<img src=\"/distribution-logo.svg\" width=\"200px\" />\n\n[![Build Status](https://github.com/distribution/reference/actions/workflows/test.yml/badge.svg?branch=main&event=push)](https://github.com/distribution/reference/actions?query=workflow%3ACI)\n[![GoDoc](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/distribution/reference)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)\n[![codecov](https://codecov.io/gh/distribution/reference/branch/main/graph/badge.svg)](https://codecov.io/gh/distribution/reference)\n[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference.svg?type=shield)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fdistribution%2Freference?ref=badge_shield)\n\nThis repository contains a library for handling references to container images held in container registries. Please see [godoc](https://pkg.go.dev/github.com/distribution/reference) for details.\n\n## Contribution\n\nPlease see [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute\nissues, fixes, and patches to this project.\n\n## Communication\n\nFor async communication and long running discussions please use issues and pull requests on the github repo.\nThis will be the best place to discuss design and implementation.\n\nFor sync communication we have a #distribution channel in the [CNCF Slack](https://slack.cncf.io/)\nthat everyone is welcome to join and chat about development.\n\n## Licenses\n\nThe distribution codebase is released under the [Apache 2.0 license](LICENSE).\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/SECURITY.md",
    "content": "# Security Policy\n\n## Reporting a Vulnerability\n\nThe maintainers take security seriously. If you discover a security issue, please bring it to their attention right away!\n\nPlease DO NOT file a public issue, instead send your report privately to cncf-distribution-security@lists.cncf.io.\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/helpers.go",
    "content": "package reference\n\nimport \"path\"\n\n// IsNameOnly returns true if reference only contains a repo name.\nfunc IsNameOnly(ref Named) bool {\n\tif _, ok := ref.(NamedTagged); ok {\n\t\treturn false\n\t}\n\tif _, ok := ref.(Canonical); ok {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// FamiliarName returns the familiar name string\n// for the given named, familiarizing if needed.\nfunc FamiliarName(ref Named) string {\n\tif nn, ok := ref.(normalizedNamed); ok {\n\t\treturn nn.Familiar().Name()\n\t}\n\treturn ref.Name()\n}\n\n// FamiliarString returns the familiar string representation\n// for the given reference, familiarizing if needed.\nfunc FamiliarString(ref Reference) string {\n\tif nn, ok := ref.(normalizedNamed); ok {\n\t\treturn nn.Familiar().String()\n\t}\n\treturn ref.String()\n}\n\n// FamiliarMatch reports whether ref matches the specified pattern.\n// See [path.Match] for supported patterns.\nfunc FamiliarMatch(pattern string, ref Reference) (bool, error) {\n\tmatched, err := path.Match(pattern, FamiliarString(ref))\n\tif namedRef, isNamed := ref.(Named); isNamed && !matched {\n\t\tmatched, _ = path.Match(pattern, FamiliarName(namedRef))\n\t}\n\treturn matched, err\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/normalize.go",
    "content": "package reference\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/opencontainers/go-digest\"\n)\n\nconst (\n\t// legacyDefaultDomain is the legacy domain for Docker Hub (which was\n\t// originally named \"the Docker Index\"). This domain is still used for\n\t// authentication and image search, which were part of the \"v1\" Docker\n\t// registry specification.\n\t//\n\t// This domain will continue to be supported, but there are plans to consolidate\n\t// legacy domains to new \"canonical\" domains. Once those domains are decided\n\t// on, we must update the normalization functions, but preserve compatibility\n\t// with existing installs, clients, and user configuration.\n\tlegacyDefaultDomain = \"index.docker.io\"\n\n\t// defaultDomain is the default domain used for images on Docker Hub.\n\t// It is used to normalize \"familiar\" names to canonical names, for example,\n\t// to convert \"ubuntu\" to \"docker.io/library/ubuntu:latest\".\n\t//\n\t// Note that actual domain of Docker Hub's registry is registry-1.docker.io.\n\t// This domain will continue to be supported, but there are plans to consolidate\n\t// legacy domains to new \"canonical\" domains. Once those domains are decided\n\t// on, we must update the normalization functions, but preserve compatibility\n\t// with existing installs, clients, and user configuration.\n\tdefaultDomain = \"docker.io\"\n\n\t// officialRepoPrefix is the namespace used for official images on Docker Hub.\n\t// It is used to normalize \"familiar\" names to canonical names, for example,\n\t// to convert \"ubuntu\" to \"docker.io/library/ubuntu:latest\".\n\tofficialRepoPrefix = \"library/\"\n\n\t// defaultTag is the default tag if no tag is provided.\n\tdefaultTag = \"latest\"\n)\n\n// normalizedNamed represents a name which has been\n// normalized and has a familiar form. A familiar name\n// is what is used in Docker UI. An example normalized\n// name is \"docker.io/library/ubuntu\" and corresponding\n// familiar name of \"ubuntu\".\ntype normalizedNamed interface {\n\tNamed\n\tFamiliar() Named\n}\n\n// ParseNormalizedNamed parses a string into a named reference\n// transforming a familiar name from Docker UI to a fully\n// qualified reference. If the value may be an identifier\n// use ParseAnyReference.\nfunc ParseNormalizedNamed(s string) (Named, error) {\n\tif ok := anchoredIdentifierRegexp.MatchString(s); ok {\n\t\treturn nil, fmt.Errorf(\"invalid repository name (%s), cannot specify 64-byte hexadecimal strings\", s)\n\t}\n\tdomain, remainder := splitDockerDomain(s)\n\tvar remote string\n\tif tagSep := strings.IndexRune(remainder, ':'); tagSep > -1 {\n\t\tremote = remainder[:tagSep]\n\t} else {\n\t\tremote = remainder\n\t}\n\tif strings.ToLower(remote) != remote {\n\t\treturn nil, fmt.Errorf(\"invalid reference format: repository name (%s) must be lowercase\", remote)\n\t}\n\n\tref, err := Parse(domain + \"/\" + remainder)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tnamed, isNamed := ref.(Named)\n\tif !isNamed {\n\t\treturn nil, fmt.Errorf(\"reference %s has no name\", ref.String())\n\t}\n\treturn named, nil\n}\n\n// namedTaggedDigested is a reference that has both a tag and a digest.\ntype namedTaggedDigested interface {\n\tNamedTagged\n\tDigested\n}\n\n// ParseDockerRef normalizes the image reference following the docker convention,\n// which allows for references to contain both a tag and a digest. It returns a\n// reference that is either tagged or digested. For references containing both\n// a tag and a digest, it returns a digested reference. For example, the following\n// reference:\n//\n//\tdocker.io/library/busybox:latest@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa\n//\n// Is returned as a digested reference (with the \":latest\" tag removed):\n//\n//\tdocker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa\n//\n// References that are already \"tagged\" or \"digested\" are returned unmodified:\n//\n//\t// Already a digested reference\n//\tdocker.io/library/busybox@sha256:7cc4b5aefd1d0cadf8d97d4350462ba51c694ebca145b08d7d41b41acc8db5aa\n//\n//\t// Already a named reference\n//\tdocker.io/library/busybox:latest\nfunc ParseDockerRef(ref string) (Named, error) {\n\tnamed, err := ParseNormalizedNamed(ref)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif canonical, ok := named.(namedTaggedDigested); ok {\n\t\t// The reference is both tagged and digested; only return digested.\n\t\tnewNamed, err := WithName(canonical.Name())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn WithDigest(newNamed, canonical.Digest())\n\t}\n\treturn TagNameOnly(named), nil\n}\n\n// splitDockerDomain splits a repository name to domain and remote-name.\n// If no valid domain is found, the default domain is used. Repository name\n// needs to be already validated before.\nfunc splitDockerDomain(name string) (domain, remoteName string) {\n\tmaybeDomain, maybeRemoteName, ok := strings.Cut(name, \"/\")\n\tif !ok {\n\t\t// Fast-path for single element (\"familiar\" names), such as \"ubuntu\"\n\t\t// or \"ubuntu:latest\". Familiar names must be handled separately, to\n\t\t// prevent them from being handled as \"hostname:port\".\n\t\t//\n\t\t// Canonicalize them as \"docker.io/library/name[:tag]\"\n\n\t\t// FIXME(thaJeztah): account for bare \"localhost\" or \"example.com\" names, which SHOULD be considered a domain.\n\t\treturn defaultDomain, officialRepoPrefix + name\n\t}\n\n\tswitch {\n\tcase maybeDomain == localhost:\n\t\t// localhost is a reserved namespace and always considered a domain.\n\t\tdomain, remoteName = maybeDomain, maybeRemoteName\n\tcase maybeDomain == legacyDefaultDomain:\n\t\t// canonicalize the Docker Hub and legacy \"Docker Index\" domains.\n\t\tdomain, remoteName = defaultDomain, maybeRemoteName\n\tcase strings.ContainsAny(maybeDomain, \".:\"):\n\t\t// Likely a domain or IP-address:\n\t\t//\n\t\t// - contains a \".\" (e.g., \"example.com\" or \"127.0.0.1\")\n\t\t// - contains a \":\" (e.g., \"example:5000\", \"::1\", or \"[::1]:5000\")\n\t\tdomain, remoteName = maybeDomain, maybeRemoteName\n\tcase strings.ToLower(maybeDomain) != maybeDomain:\n\t\t// Uppercase namespaces are not allowed, so if the first element\n\t\t// is not lowercase, we assume it to be a domain-name.\n\t\tdomain, remoteName = maybeDomain, maybeRemoteName\n\tdefault:\n\t\t// None of the above: it's not a domain, so use the default, and\n\t\t// use the name input the remote-name.\n\t\tdomain, remoteName = defaultDomain, name\n\t}\n\n\tif domain == defaultDomain && !strings.ContainsRune(remoteName, '/') {\n\t\t// Canonicalize \"familiar\" names, but only on Docker Hub, not\n\t\t// on other domains:\n\t\t//\n\t\t// \"docker.io/ubuntu[:tag]\" => \"docker.io/library/ubuntu[:tag]\"\n\t\tremoteName = officialRepoPrefix + remoteName\n\t}\n\n\treturn domain, remoteName\n}\n\n// familiarizeName returns a shortened version of the name familiar\n// to the Docker UI. Familiar names have the default domain\n// \"docker.io\" and \"library/\" repository prefix removed.\n// For example, \"docker.io/library/redis\" will have the familiar\n// name \"redis\" and \"docker.io/dmcgowan/myapp\" will be \"dmcgowan/myapp\".\n// Returns a familiarized named only reference.\nfunc familiarizeName(named namedRepository) repository {\n\trepo := repository{\n\t\tdomain: named.Domain(),\n\t\tpath:   named.Path(),\n\t}\n\n\tif repo.domain == defaultDomain {\n\t\trepo.domain = \"\"\n\t\t// Handle official repositories which have the pattern \"library/<official repo name>\"\n\t\tif strings.HasPrefix(repo.path, officialRepoPrefix) {\n\t\t\t// TODO(thaJeztah): this check may be too strict, as it assumes the\n\t\t\t//  \"library/\" namespace does not have nested namespaces. While this\n\t\t\t//  is true (currently), technically it would be possible for Docker\n\t\t\t//  Hub to use those (e.g. \"library/distros/ubuntu:latest\").\n\t\t\t//  See https://github.com/distribution/distribution/pull/3769#issuecomment-1302031785.\n\t\t\tif remainder := strings.TrimPrefix(repo.path, officialRepoPrefix); !strings.ContainsRune(remainder, '/') {\n\t\t\t\trepo.path = remainder\n\t\t\t}\n\t\t}\n\t}\n\treturn repo\n}\n\nfunc (r reference) Familiar() Named {\n\treturn reference{\n\t\tnamedRepository: familiarizeName(r.namedRepository),\n\t\ttag:             r.tag,\n\t\tdigest:          r.digest,\n\t}\n}\n\nfunc (r repository) Familiar() Named {\n\treturn familiarizeName(r)\n}\n\nfunc (t taggedReference) Familiar() Named {\n\treturn taggedReference{\n\t\tnamedRepository: familiarizeName(t.namedRepository),\n\t\ttag:             t.tag,\n\t}\n}\n\nfunc (c canonicalReference) Familiar() Named {\n\treturn canonicalReference{\n\t\tnamedRepository: familiarizeName(c.namedRepository),\n\t\tdigest:          c.digest,\n\t}\n}\n\n// TagNameOnly adds the default tag \"latest\" to a reference if it only has\n// a repo name.\nfunc TagNameOnly(ref Named) Named {\n\tif IsNameOnly(ref) {\n\t\tnamedTagged, err := WithTag(ref, defaultTag)\n\t\tif err != nil {\n\t\t\t// Default tag must be valid, to create a NamedTagged\n\t\t\t// type with non-validated input the WithTag function\n\t\t\t// should be used instead\n\t\t\tpanic(err)\n\t\t}\n\t\treturn namedTagged\n\t}\n\treturn ref\n}\n\n// ParseAnyReference parses a reference string as a possible identifier,\n// full digest, or familiar name.\nfunc ParseAnyReference(ref string) (Reference, error) {\n\tif ok := anchoredIdentifierRegexp.MatchString(ref); ok {\n\t\treturn digestReference(\"sha256:\" + ref), nil\n\t}\n\tif dgst, err := digest.Parse(ref); err == nil {\n\t\treturn digestReference(dgst), nil\n\t}\n\n\treturn ParseNormalizedNamed(ref)\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/reference.go",
    "content": "// Package reference provides a general type to represent any way of referencing images within the registry.\n// Its main purpose is to abstract tags and digests (content-addressable hash).\n//\n// Grammar\n//\n//\treference                       := name [ \":\" tag ] [ \"@\" digest ]\n//\tname                            := [domain '/'] remote-name\n//\tdomain                          := host [':' port-number]\n//\thost                            := domain-name | IPv4address | \\[ IPv6address \\]\t; rfc3986 appendix-A\n//\tdomain-name                     := domain-component ['.' domain-component]*\n//\tdomain-component                := /([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])/\n//\tport-number                     := /[0-9]+/\n//\tpath-component                  := alpha-numeric [separator alpha-numeric]*\n//\tpath (or \"remote-name\")         := path-component ['/' path-component]*\n//\talpha-numeric                   := /[a-z0-9]+/\n//\tseparator                       := /[_.]|__|[-]*/\n//\n//\ttag                             := /[\\w][\\w.-]{0,127}/\n//\n//\tdigest                          := digest-algorithm \":\" digest-hex\n//\tdigest-algorithm                := digest-algorithm-component [ digest-algorithm-separator digest-algorithm-component ]*\n//\tdigest-algorithm-separator      := /[+.-_]/\n//\tdigest-algorithm-component      := /[A-Za-z][A-Za-z0-9]*/\n//\tdigest-hex                      := /[0-9a-fA-F]{32,}/ ; At least 128 bit digest value\n//\n//\tidentifier                      := /[a-f0-9]{64}/\npackage reference\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/opencontainers/go-digest\"\n)\n\nconst (\n\t// RepositoryNameTotalLengthMax is the maximum total number of characters in a repository name.\n\tRepositoryNameTotalLengthMax = 255\n\n\t// NameTotalLengthMax is the maximum total number of characters in a repository name.\n\t//\n\t// Deprecated: use [RepositoryNameTotalLengthMax] instead.\n\tNameTotalLengthMax = RepositoryNameTotalLengthMax\n)\n\nvar (\n\t// ErrReferenceInvalidFormat represents an error while trying to parse a string as a reference.\n\tErrReferenceInvalidFormat = errors.New(\"invalid reference format\")\n\n\t// ErrTagInvalidFormat represents an error while trying to parse a string as a tag.\n\tErrTagInvalidFormat = errors.New(\"invalid tag format\")\n\n\t// ErrDigestInvalidFormat represents an error while trying to parse a string as a tag.\n\tErrDigestInvalidFormat = errors.New(\"invalid digest format\")\n\n\t// ErrNameContainsUppercase is returned for invalid repository names that contain uppercase characters.\n\tErrNameContainsUppercase = errors.New(\"repository name must be lowercase\")\n\n\t// ErrNameEmpty is returned for empty, invalid repository names.\n\tErrNameEmpty = errors.New(\"repository name must have at least one component\")\n\n\t// ErrNameTooLong is returned when a repository name is longer than RepositoryNameTotalLengthMax.\n\tErrNameTooLong = fmt.Errorf(\"repository name must not be more than %v characters\", RepositoryNameTotalLengthMax)\n\n\t// ErrNameNotCanonical is returned when a name is not canonical.\n\tErrNameNotCanonical = errors.New(\"repository name must be canonical\")\n)\n\n// Reference is an opaque object reference identifier that may include\n// modifiers such as a hostname, name, tag, and digest.\ntype Reference interface {\n\t// String returns the full reference\n\tString() string\n}\n\n// Field provides a wrapper type for resolving correct reference types when\n// working with encoding.\ntype Field struct {\n\treference Reference\n}\n\n// AsField wraps a reference in a Field for encoding.\nfunc AsField(reference Reference) Field {\n\treturn Field{reference}\n}\n\n// Reference unwraps the reference type from the field to\n// return the Reference object. This object should be\n// of the appropriate type to further check for different\n// reference types.\nfunc (f Field) Reference() Reference {\n\treturn f.reference\n}\n\n// MarshalText serializes the field to byte text which\n// is the string of the reference.\nfunc (f Field) MarshalText() (p []byte, err error) {\n\treturn []byte(f.reference.String()), nil\n}\n\n// UnmarshalText parses text bytes by invoking the\n// reference parser to ensure the appropriately\n// typed reference object is wrapped by field.\nfunc (f *Field) UnmarshalText(p []byte) error {\n\tr, err := Parse(string(p))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tf.reference = r\n\treturn nil\n}\n\n// Named is an object with a full name\ntype Named interface {\n\tReference\n\tName() string\n}\n\n// Tagged is an object which has a tag\ntype Tagged interface {\n\tReference\n\tTag() string\n}\n\n// NamedTagged is an object including a name and tag.\ntype NamedTagged interface {\n\tNamed\n\tTag() string\n}\n\n// Digested is an object which has a digest\n// in which it can be referenced by\ntype Digested interface {\n\tReference\n\tDigest() digest.Digest\n}\n\n// Canonical reference is an object with a fully unique\n// name including a name with domain and digest\ntype Canonical interface {\n\tNamed\n\tDigest() digest.Digest\n}\n\n// namedRepository is a reference to a repository with a name.\n// A namedRepository has both domain and path components.\ntype namedRepository interface {\n\tNamed\n\tDomain() string\n\tPath() string\n}\n\n// Domain returns the domain part of the [Named] reference.\nfunc Domain(named Named) string {\n\tif r, ok := named.(namedRepository); ok {\n\t\treturn r.Domain()\n\t}\n\tdomain, _ := splitDomain(named.Name())\n\treturn domain\n}\n\n// Path returns the name without the domain part of the [Named] reference.\nfunc Path(named Named) (name string) {\n\tif r, ok := named.(namedRepository); ok {\n\t\treturn r.Path()\n\t}\n\t_, path := splitDomain(named.Name())\n\treturn path\n}\n\n// splitDomain splits a named reference into a hostname and path string.\n// If no valid hostname is found, the hostname is empty and the full value\n// is returned as name\nfunc splitDomain(name string) (string, string) {\n\tmatch := anchoredNameRegexp.FindStringSubmatch(name)\n\tif len(match) != 3 {\n\t\treturn \"\", name\n\t}\n\treturn match[1], match[2]\n}\n\n// Parse parses s and returns a syntactically valid Reference.\n// If an error was encountered it is returned, along with a nil Reference.\nfunc Parse(s string) (Reference, error) {\n\tmatches := ReferenceRegexp.FindStringSubmatch(s)\n\tif matches == nil {\n\t\tif s == \"\" {\n\t\t\treturn nil, ErrNameEmpty\n\t\t}\n\t\tif ReferenceRegexp.FindStringSubmatch(strings.ToLower(s)) != nil {\n\t\t\treturn nil, ErrNameContainsUppercase\n\t\t}\n\t\treturn nil, ErrReferenceInvalidFormat\n\t}\n\n\tvar repo repository\n\n\tnameMatch := anchoredNameRegexp.FindStringSubmatch(matches[1])\n\tif len(nameMatch) == 3 {\n\t\trepo.domain = nameMatch[1]\n\t\trepo.path = nameMatch[2]\n\t} else {\n\t\trepo.domain = \"\"\n\t\trepo.path = matches[1]\n\t}\n\n\tif len(repo.path) > RepositoryNameTotalLengthMax {\n\t\treturn nil, ErrNameTooLong\n\t}\n\n\tref := reference{\n\t\tnamedRepository: repo,\n\t\ttag:             matches[2],\n\t}\n\tif matches[3] != \"\" {\n\t\tvar err error\n\t\tref.digest, err = digest.Parse(matches[3])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tr := getBestReferenceType(ref)\n\tif r == nil {\n\t\treturn nil, ErrNameEmpty\n\t}\n\n\treturn r, nil\n}\n\n// ParseNamed parses s and returns a syntactically valid reference implementing\n// the Named interface. The reference must have a name and be in the canonical\n// form, otherwise an error is returned.\n// If an error was encountered it is returned, along with a nil Reference.\nfunc ParseNamed(s string) (Named, error) {\n\tnamed, err := ParseNormalizedNamed(s)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif named.String() != s {\n\t\treturn nil, ErrNameNotCanonical\n\t}\n\treturn named, nil\n}\n\n// WithName returns a named object representing the given string. If the input\n// is invalid ErrReferenceInvalidFormat will be returned.\nfunc WithName(name string) (Named, error) {\n\tmatch := anchoredNameRegexp.FindStringSubmatch(name)\n\tif match == nil || len(match) != 3 {\n\t\treturn nil, ErrReferenceInvalidFormat\n\t}\n\n\tif len(match[2]) > RepositoryNameTotalLengthMax {\n\t\treturn nil, ErrNameTooLong\n\t}\n\n\treturn repository{\n\t\tdomain: match[1],\n\t\tpath:   match[2],\n\t}, nil\n}\n\n// WithTag combines the name from \"name\" and the tag from \"tag\" to form a\n// reference incorporating both the name and the tag.\nfunc WithTag(name Named, tag string) (NamedTagged, error) {\n\tif !anchoredTagRegexp.MatchString(tag) {\n\t\treturn nil, ErrTagInvalidFormat\n\t}\n\tvar repo repository\n\tif r, ok := name.(namedRepository); ok {\n\t\trepo.domain = r.Domain()\n\t\trepo.path = r.Path()\n\t} else {\n\t\trepo.path = name.Name()\n\t}\n\tif canonical, ok := name.(Canonical); ok {\n\t\treturn reference{\n\t\t\tnamedRepository: repo,\n\t\t\ttag:             tag,\n\t\t\tdigest:          canonical.Digest(),\n\t\t}, nil\n\t}\n\treturn taggedReference{\n\t\tnamedRepository: repo,\n\t\ttag:             tag,\n\t}, nil\n}\n\n// WithDigest combines the name from \"name\" and the digest from \"digest\" to form\n// a reference incorporating both the name and the digest.\nfunc WithDigest(name Named, digest digest.Digest) (Canonical, error) {\n\tif !anchoredDigestRegexp.MatchString(digest.String()) {\n\t\treturn nil, ErrDigestInvalidFormat\n\t}\n\tvar repo repository\n\tif r, ok := name.(namedRepository); ok {\n\t\trepo.domain = r.Domain()\n\t\trepo.path = r.Path()\n\t} else {\n\t\trepo.path = name.Name()\n\t}\n\tif tagged, ok := name.(Tagged); ok {\n\t\treturn reference{\n\t\t\tnamedRepository: repo,\n\t\t\ttag:             tagged.Tag(),\n\t\t\tdigest:          digest,\n\t\t}, nil\n\t}\n\treturn canonicalReference{\n\t\tnamedRepository: repo,\n\t\tdigest:          digest,\n\t}, nil\n}\n\n// TrimNamed removes any tag or digest from the named reference.\nfunc TrimNamed(ref Named) Named {\n\trepo := repository{}\n\tif r, ok := ref.(namedRepository); ok {\n\t\trepo.domain, repo.path = r.Domain(), r.Path()\n\t} else {\n\t\trepo.domain, repo.path = splitDomain(ref.Name())\n\t}\n\treturn repo\n}\n\nfunc getBestReferenceType(ref reference) Reference {\n\tif ref.Name() == \"\" {\n\t\t// Allow digest only references\n\t\tif ref.digest != \"\" {\n\t\t\treturn digestReference(ref.digest)\n\t\t}\n\t\treturn nil\n\t}\n\tif ref.tag == \"\" {\n\t\tif ref.digest != \"\" {\n\t\t\treturn canonicalReference{\n\t\t\t\tnamedRepository: ref.namedRepository,\n\t\t\t\tdigest:          ref.digest,\n\t\t\t}\n\t\t}\n\t\treturn ref.namedRepository\n\t}\n\tif ref.digest == \"\" {\n\t\treturn taggedReference{\n\t\t\tnamedRepository: ref.namedRepository,\n\t\t\ttag:             ref.tag,\n\t\t}\n\t}\n\n\treturn ref\n}\n\ntype reference struct {\n\tnamedRepository\n\ttag    string\n\tdigest digest.Digest\n}\n\nfunc (r reference) String() string {\n\treturn r.Name() + \":\" + r.tag + \"@\" + r.digest.String()\n}\n\nfunc (r reference) Tag() string {\n\treturn r.tag\n}\n\nfunc (r reference) Digest() digest.Digest {\n\treturn r.digest\n}\n\ntype repository struct {\n\tdomain string\n\tpath   string\n}\n\nfunc (r repository) String() string {\n\treturn r.Name()\n}\n\nfunc (r repository) Name() string {\n\tif r.domain == \"\" {\n\t\treturn r.path\n\t}\n\treturn r.domain + \"/\" + r.path\n}\n\nfunc (r repository) Domain() string {\n\treturn r.domain\n}\n\nfunc (r repository) Path() string {\n\treturn r.path\n}\n\ntype digestReference digest.Digest\n\nfunc (d digestReference) String() string {\n\treturn digest.Digest(d).String()\n}\n\nfunc (d digestReference) Digest() digest.Digest {\n\treturn digest.Digest(d)\n}\n\ntype taggedReference struct {\n\tnamedRepository\n\ttag string\n}\n\nfunc (t taggedReference) String() string {\n\treturn t.Name() + \":\" + t.tag\n}\n\nfunc (t taggedReference) Tag() string {\n\treturn t.tag\n}\n\ntype canonicalReference struct {\n\tnamedRepository\n\tdigest digest.Digest\n}\n\nfunc (c canonicalReference) String() string {\n\treturn c.Name() + \"@\" + c.digest.String()\n}\n\nfunc (c canonicalReference) Digest() digest.Digest {\n\treturn c.digest\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/regexp.go",
    "content": "package reference\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n)\n\n// DigestRegexp matches well-formed digests, including algorithm (e.g. \"sha256:<encoded>\").\nvar DigestRegexp = regexp.MustCompile(digestPat)\n\n// DomainRegexp matches hostname or IP-addresses, optionally including a port\n// number. It defines the structure of potential domain components that may be\n// part of image names. This is purposely a subset of what is allowed by DNS to\n// ensure backwards compatibility with Docker image names. It may be a subset of\n// DNS domain name, an IPv4 address in decimal format, or an IPv6 address between\n// square brackets (excluding zone identifiers as defined by [RFC 6874] or special\n// addresses such as IPv4-Mapped).\n//\n// [RFC 6874]: https://www.rfc-editor.org/rfc/rfc6874.\nvar DomainRegexp = regexp.MustCompile(domainAndPort)\n\n// IdentifierRegexp is the format for string identifier used as a\n// content addressable identifier using sha256. These identifiers\n// are like digests without the algorithm, since sha256 is used.\nvar IdentifierRegexp = regexp.MustCompile(identifier)\n\n// NameRegexp is the format for the name component of references, including\n// an optional domain and port, but without tag or digest suffix.\nvar NameRegexp = regexp.MustCompile(namePat)\n\n// ReferenceRegexp is the full supported format of a reference. The regexp\n// is anchored and has capturing groups for name, tag, and digest\n// components.\nvar ReferenceRegexp = regexp.MustCompile(referencePat)\n\n// TagRegexp matches valid tag names. From [docker/docker:graph/tags.go].\n//\n// [docker/docker:graph/tags.go]: https://github.com/moby/moby/blob/v1.6.0/graph/tags.go#L26-L28\nvar TagRegexp = regexp.MustCompile(tag)\n\nconst (\n\t// alphanumeric defines the alphanumeric atom, typically a\n\t// component of names. This only allows lower case characters and digits.\n\talphanumeric = `[a-z0-9]+`\n\n\t// separator defines the separators allowed to be embedded in name\n\t// components. This allows one period, one or two underscore and multiple\n\t// dashes. Repeated dashes and underscores are intentionally treated\n\t// differently. In order to support valid hostnames as name components,\n\t// supporting repeated dash was added. Additionally double underscore is\n\t// now allowed as a separator to loosen the restriction for previously\n\t// supported names.\n\tseparator = `(?:[._]|__|[-]+)`\n\n\t// localhost is treated as a special value for domain-name. Any other\n\t// domain-name without a \".\" or a \":port\" are considered a path component.\n\tlocalhost = `localhost`\n\n\t// domainNameComponent restricts the registry domain component of a\n\t// repository name to start with a component as defined by DomainRegexp.\n\tdomainNameComponent = `(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])`\n\n\t// optionalPort matches an optional port-number including the port separator\n\t// (e.g. \":80\").\n\toptionalPort = `(?::[0-9]+)?`\n\n\t// tag matches valid tag names. From docker/docker:graph/tags.go.\n\ttag = `[\\w][\\w.-]{0,127}`\n\n\t// digestPat matches well-formed digests, including algorithm (e.g. \"sha256:<encoded>\").\n\t//\n\t// TODO(thaJeztah): this should follow the same rules as https://pkg.go.dev/github.com/opencontainers/go-digest@v1.0.0#DigestRegexp\n\t// so that go-digest defines the canonical format. Note that the go-digest is\n\t// more relaxed:\n\t//   - it allows multiple algorithms (e.g. \"sha256+b64:<encoded>\") to allow\n\t//     future expansion of supported algorithms.\n\t//   - it allows the \"<encoded>\" value to use urlsafe base64 encoding as defined\n\t//     in [rfc4648, section 5].\n\t//\n\t// [rfc4648, section 5]: https://www.rfc-editor.org/rfc/rfc4648#section-5.\n\tdigestPat = `[A-Za-z][A-Za-z0-9]*(?:[-_+.][A-Za-z][A-Za-z0-9]*)*[:][[:xdigit:]]{32,}`\n\n\t// identifier is the format for a content addressable identifier using sha256.\n\t// These identifiers are like digests without the algorithm, since sha256 is used.\n\tidentifier = `([a-f0-9]{64})`\n\n\t// ipv6address are enclosed between square brackets and may be represented\n\t// in many ways, see rfc5952. Only IPv6 in compressed or uncompressed format\n\t// are allowed, IPv6 zone identifiers (rfc6874) or Special addresses such as\n\t// IPv4-Mapped are deliberately excluded.\n\tipv6address = `\\[(?:[a-fA-F0-9:]+)\\]`\n)\n\nvar (\n\t// domainName defines the structure of potential domain components\n\t// that may be part of image names. This is purposely a subset of what is\n\t// allowed by DNS to ensure backwards compatibility with Docker image\n\t// names. This includes IPv4 addresses on decimal format.\n\tdomainName = domainNameComponent + anyTimes(`\\.`+domainNameComponent)\n\n\t// host defines the structure of potential domains based on the URI\n\t// Host subcomponent on rfc3986. It may be a subset of DNS domain name,\n\t// or an IPv4 address in decimal format, or an IPv6 address between square\n\t// brackets (excluding zone identifiers as defined by rfc6874 or special\n\t// addresses such as IPv4-Mapped).\n\thost = `(?:` + domainName + `|` + ipv6address + `)`\n\n\t// allowed by the URI Host subcomponent on rfc3986 to ensure backwards\n\t// compatibility with Docker image names.\n\tdomainAndPort = host + optionalPort\n\n\t// anchoredTagRegexp matches valid tag names, anchored at the start and\n\t// end of the matched string.\n\tanchoredTagRegexp = regexp.MustCompile(anchored(tag))\n\n\t// anchoredDigestRegexp matches valid digests, anchored at the start and\n\t// end of the matched string.\n\tanchoredDigestRegexp = regexp.MustCompile(anchored(digestPat))\n\n\t// pathComponent restricts path-components to start with an alphanumeric\n\t// character, with following parts able to be separated by a separator\n\t// (one period, one or two underscore and multiple dashes).\n\tpathComponent = alphanumeric + anyTimes(separator+alphanumeric)\n\n\t// remoteName matches the remote-name of a repository. It consists of one\n\t// or more forward slash (/) delimited path-components:\n\t//\n\t//\tpathComponent[[/pathComponent] ...] // e.g., \"library/ubuntu\"\n\tremoteName = pathComponent + anyTimes(`/`+pathComponent)\n\tnamePat    = optional(domainAndPort+`/`) + remoteName\n\n\t// anchoredNameRegexp is used to parse a name value, capturing the\n\t// domain and trailing components.\n\tanchoredNameRegexp = regexp.MustCompile(anchored(optional(capture(domainAndPort), `/`), capture(remoteName)))\n\n\treferencePat = anchored(capture(namePat), optional(`:`, capture(tag)), optional(`@`, capture(digestPat)))\n\n\t// anchoredIdentifierRegexp is used to check or match an\n\t// identifier value, anchored at start and end of string.\n\tanchoredIdentifierRegexp = regexp.MustCompile(anchored(identifier))\n)\n\n// optional wraps the expression in a non-capturing group and makes the\n// production optional.\nfunc optional(res ...string) string {\n\treturn `(?:` + strings.Join(res, \"\") + `)?`\n}\n\n// anyTimes wraps the expression in a non-capturing group that can occur\n// any number of times.\nfunc anyTimes(res ...string) string {\n\treturn `(?:` + strings.Join(res, \"\") + `)*`\n}\n\n// capture wraps the expression in a capturing group.\nfunc capture(res ...string) string {\n\treturn `(` + strings.Join(res, \"\") + `)`\n}\n\n// anchored anchors the regular expression by adding start and end delimiters.\nfunc anchored(res ...string) string {\n\treturn `^` + strings.Join(res, \"\") + `$`\n}\n"
  },
  {
    "path": "vendor/github.com/distribution/reference/sort.go",
    "content": "/*\n   Copyright The containerd Authors.\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       http://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*/\n\npackage reference\n\nimport (\n\t\"sort\"\n)\n\n// Sort sorts string references preferring higher information references.\n//\n// The precedence is as follows:\n//\n//  1. [Named] + [Tagged] + [Digested] (e.g., \"docker.io/library/busybox:latest@sha256:<digest>\")\n//  2. [Named] + [Tagged]              (e.g., \"docker.io/library/busybox:latest\")\n//  3. [Named] + [Digested]            (e.g., \"docker.io/library/busybo@sha256:<digest>\")\n//  4. [Named]                         (e.g., \"docker.io/library/busybox\")\n//  5. [Digested]                      (e.g., \"docker.io@sha256:<digest>\")\n//  6. Parse error\nfunc Sort(references []string) []string {\n\tvar prefs []Reference\n\tvar bad []string\n\n\tfor _, ref := range references {\n\t\tpref, err := ParseAnyReference(ref)\n\t\tif err != nil {\n\t\t\tbad = append(bad, ref)\n\t\t} else {\n\t\t\tprefs = append(prefs, pref)\n\t\t}\n\t}\n\tsort.Slice(prefs, func(a, b int) bool {\n\t\tar := refRank(prefs[a])\n\t\tbr := refRank(prefs[b])\n\t\tif ar == br {\n\t\t\treturn prefs[a].String() < prefs[b].String()\n\t\t}\n\t\treturn ar < br\n\t})\n\tsort.Strings(bad)\n\tvar refs []string\n\tfor _, pref := range prefs {\n\t\trefs = append(refs, pref.String())\n\t}\n\treturn append(refs, bad...)\n}\n\nfunc refRank(ref Reference) uint8 {\n\tif _, ok := ref.(Named); ok {\n\t\tif _, ok = ref.(Tagged); ok {\n\t\t\tif _, ok = ref.(Digested); ok {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t\treturn 2\n\t\t}\n\t\tif _, ok = ref.(Digested); ok {\n\t\t\treturn 3\n\t\t}\n\t\treturn 4\n\t}\n\treturn 5\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/AUTHORS",
    "content": "# File @generated by scripts/docs/generate-authors.sh. DO NOT EDIT.\n# This file lists all contributors to the repository.\n# See scripts/docs/generate-authors.sh to make modifications.\n\nAanand Prasad <aanand.prasad@gmail.com>\nAaron L. Xu <liker.xu@foxmail.com>\nAaron Lehmann <alehmann@netflix.com>\nAaron.L.Xu <likexu@harmonycloud.cn>\nAbdur Rehman <abdur_rehman@mentor.com>\nAbhinandan Prativadi <abhi@docker.com>\nAbin Shahab <ashahab@altiscale.com>\nAbreto FU <public@abreto.email>\nAce Tang <aceapril@126.com>\nAddam Hardy <addam.hardy@gmail.com>\nAdolfo Ochagavía <aochagavia92@gmail.com>\nAdrian Plata <adrian.plata@docker.com>\nAdrien Duermael <adrien@duermael.com>\nAdrien Folie <folie.adrien@gmail.com>\nAhmet Alp Balkan <ahmetb@microsoft.com>\nAidan Feldman <aidan.feldman@gmail.com>\nAidan Hobson Sayers <aidanhs@cantab.net>\nAJ Bowen <aj@soulshake.net>\nAkhil Mohan <akhil.mohan@mayadata.io>\nAkihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>\nAkim Demaille <akim.demaille@docker.com>\nAlan Thompson <cloojure@gmail.com>\nAlbert Callarisa <shark234@gmail.com>\nAlberto Roura <mail@albertoroura.com>\nAlbin Kerouanton <albin@akerouanton.name>\nAleksa Sarai <asarai@suse.de>\nAleksander Piotrowski <apiotrowski312@gmail.com>\nAlessandro Boch <aboch@tetrationanalytics.com>\nAlex Couture-Beil <alex@earthly.dev>\nAlex Mavrogiannis <alex.mavrogiannis@docker.com>\nAlex Mayer <amayer5125@gmail.com>\nAlexander Boyd <alex@opengroove.org>\nAlexander Larsson <alexl@redhat.com>\nAlexander Morozov <lk4d4math@gmail.com>\nAlexander Ryabov <i@sepa.spb.ru>\nAlexandre González <agonzalezro@gmail.com>\nAlexey Igrychev <alexey.igrychev@flant.com>\nAlexis Couvreur <alexiscouvreur.pro@gmail.com>\nAlfred Landrum <alfred.landrum@docker.com>\nAlicia Lauerman <alicia@eta.im>\nAllen Sun <allensun.shl@alibaba-inc.com>\nAlvin Deng <alvin.q.deng@utexas.edu>\nAmen Belayneh <amenbelayneh@gmail.com>\nAmey Shrivastava <72866602+AmeyShrivastava@users.noreply.github.com>\nAmir Goldstein <amir73il@aquasec.com>\nAmit Krishnan <amit.krishnan@oracle.com>\nAmit Shukla <amit.shukla@docker.com>\nAmy Lindburg <amy.lindburg@docker.com>\nAnca Iordache <anca.iordache@docker.com>\nAnda Xu <anda.xu@docker.com>\nAndrea Luzzardi <aluzzardi@gmail.com>\nAndreas Köhler <andi5.py@gmx.net>\nAndres G. Aragoneses <knocte@gmail.com>\nAndres Leon Rangel <aleon1220@gmail.com>\nAndrew France <andrew@avito.co.uk>\nAndrew Hsu <andrewhsu@docker.com>\nAndrew Macpherson <hopscotch23@gmail.com>\nAndrew McDonnell <bugs@andrewmcdonnell.net>\nAndrew Po <absourd.noise@gmail.com>\nAndrey Petrov <andrey.petrov@shazow.net>\nAndrii Berehuliak <berkusandrew@gmail.com>\nAndré Martins <aanm90@gmail.com>\nAndy Goldstein <agoldste@redhat.com>\nAndy Rothfusz <github@developersupport.net>\nAnil Madhavapeddy <anil@recoil.org>\nAnkush Agarwal <ankushagarwal11@gmail.com>\nAnne Henmi <anne.henmi@docker.com>\nAnton Polonskiy <anton.polonskiy@gmail.com>\nAntonio Murdaca <antonio.murdaca@gmail.com>\nAntonis Kalipetis <akalipetis@gmail.com>\nAnusha Ragunathan <anusha.ragunathan@docker.com>\nAo Li <la9249@163.com>\nArash Deshmeh <adeshmeh@ca.ibm.com>\nArko Dasgupta <arko@tetrate.io>\nArnaud Porterie <icecrime@gmail.com>\nArnaud Rebillout <elboulangero@gmail.com>\nArthur Peka <arthur.peka@outlook.com>\nAshwini Oruganti <ashwini.oruganti@gmail.com>\nAzat Khuyiyakhmetov <shadow_uz@mail.ru>\nBardia Keyoumarsi <bkeyouma@ucsc.edu>\nBarnaby Gray <barnaby@pickle.me.uk>\nBastiaan Bakker <bbakker@xebia.com>\nBastianHofmann <bastianhofmann@me.com>\nBen Bodenmiller <bbodenmiller@gmail.com>\nBen Bonnefoy <frenchben@docker.com>\nBen Creasy <ben@bencreasy.com>\nBen Firshman <ben@firshman.co.uk>\nBenjamin Boudreau <boudreau.benjamin@gmail.com>\nBenjamin Böhmke <benjamin@boehmke.net>\nBenjamin Nater <me@bn4t.me>\nBenoit Sigoure <tsunanet@gmail.com>\nBhumika Bayani <bhumikabayani@gmail.com>\nBill Wang <ozbillwang@gmail.com>\nBin Liu <liubin0329@gmail.com>\nBingshen Wang <bingshen.wbs@alibaba-inc.com>\nBishal Das <bishalhnj127@gmail.com>\nBoaz Shuster <ripcurld.github@gmail.com>\nBogdan Anton <contact@bogdananton.ro>\nBoris Pruessmann <boris@pruessmann.org>\nBrad Baker <brad@brad.fi>\nBradley Cicenas <bradley.cicenas@gmail.com>\nBrandon Mitchell <git@bmitch.net>\nBrandon Philips <brandon.philips@coreos.com>\nBrent Salisbury <brent.salisbury@docker.com>\nBret Fisher <bret@bretfisher.com>\nBrian (bex) Exelbierd <bexelbie@redhat.com>\nBrian Goff <cpuguy83@gmail.com>\nBrian Wieder <brian@4wieders.com>\nBruno Sousa <bruno.sousa@docker.com>\nBryan Bess <squarejaw@bsbess.com>\nBryan Boreham <bjboreham@gmail.com>\nBryan Murphy <bmurphy1976@gmail.com>\nbryfry <bryon.fryer@gmail.com>\nCameron Spear <cameronspear@gmail.com>\nCao Weiwei <cao.weiwei30@zte.com.cn>\nCarlo Mion <mion00@gmail.com>\nCarlos Alexandro Becker <caarlos0@gmail.com>\nCarlos de Paula <me@carlosedp.com>\nCe Gao <ce.gao@outlook.com>\nCedric Davies <cedricda@microsoft.com>\nCezar Sa Espinola <cezarsa@gmail.com>\nChad Faragher <wyckster@hotmail.com>\nChao Wang <wangchao.fnst@cn.fujitsu.com>\nCharles Chan <charleswhchan@users.noreply.github.com>\nCharles Law <claw@conduce.com>\nCharles Smith <charles.smith@docker.com>\nCharlie Drage <charlie@charliedrage.com>\nCharlotte Mach <charlotte.mach@fs.lmu.de>\nChaYoung You <yousbe@gmail.com>\nChee Hau Lim <cheehau.lim@mobimeo.com>\nChen Chuanliang <chen.chuanliang@zte.com.cn>\nChen Hanxiao <chenhanxiao@cn.fujitsu.com>\nChen Mingjie <chenmingjie0828@163.com>\nChen Qiu <cheney-90@hotmail.com>\nChris Couzens <ccouzens@gmail.com>\nChris Gavin <chris@chrisgavin.me>\nChris Gibson <chris@chrisg.io>\nChris McKinnel <chrismckinnel@gmail.com>\nChris Snow <chsnow123@gmail.com>\nChris Vermilion <christopher.vermilion@gmail.com>\nChris Weyl <cweyl@alumni.drew.edu>\nChristian Persson <saser@live.se>\nChristian Stefanescu <st.chris@gmail.com>\nChristophe Robin <crobin@nekoo.com>\nChristophe Vidal <kriss@krizalys.com>\nChristopher Biscardi <biscarch@sketcht.com>\nChristopher Crone <christopher.crone@docker.com>\nChristopher Jones <tophj@linux.vnet.ibm.com>\nChristopher Svensson <stoffus@stoffus.com>\nChristy Norman <christy@linux.vnet.ibm.com>\nChun Chen <ramichen@tencent.com>\nClinton Kitson <clintonskitson@gmail.com>\nCoenraad Loubser <coenraad@wish.org.za>\nColin Hebert <hebert.colin@gmail.com>\nCollin Guarino <collin.guarino@gmail.com>\nColm Hally <colmhally@gmail.com>\nComical Derskeal <27731088+derskeal@users.noreply.github.com>\nConner Crosby <conner@cavcrosby.tech>\nCorey Farrell <git@cfware.com>\nCorey Quon <corey.quon@docker.com>\nCory Bennet <cbennett@netflix.com>\nCraig Wilhite <crwilhit@microsoft.com>\nCristian Staretu <cristian.staretu@gmail.com>\nDaehyeok Mun <daehyeok@gmail.com>\nDafydd Crosby <dtcrsby@gmail.com>\nDaisuke Ito <itodaisuke00@gmail.com>\ndalanlan <dalanlan925@gmail.com>\nDamien Nadé <github@livna.org>\nDan Cotora <dan@bluevision.ro>\nDaniel Artine <daniel.artine@ufrj.br>\nDaniel Cassidy <mail@danielcassidy.me.uk>\nDaniel Dao <dqminh@cloudflare.com>\nDaniel Farrell <dfarrell@redhat.com>\nDaniel Gasienica <daniel@gasienica.ch>\nDaniel Goosen <daniel.goosen@surveysampling.com>\nDaniel Helfand <dhelfand@redhat.com>\nDaniel Hiltgen <daniel.hiltgen@docker.com>\nDaniel J Walsh <dwalsh@redhat.com>\nDaniel Nephin <dnephin@docker.com>\nDaniel Norberg <dano@spotify.com>\nDaniel Watkins <daniel@daniel-watkins.co.uk>\nDaniel Zhang <jmzwcn@gmail.com>\nDaniil Nikolenko <qoo2p5@gmail.com>\nDanny Berger <dpb587@gmail.com>\nDarren Shepherd <darren.s.shepherd@gmail.com>\nDarren Stahl <darst@microsoft.com>\nDattatraya Kumbhar <dattatraya.kumbhar@gslab.com>\nDave Goodchild <buddhamagnet@gmail.com>\nDave Henderson <dhenderson@gmail.com>\nDave Tucker <dt@docker.com>\nDavid Alvarez <david.alvarez@flyeralarm.com>\nDavid Beitey <david@davidjb.com>\nDavid Calavera <david.calavera@gmail.com>\nDavid Cramer <davcrame@cisco.com>\nDavid Dooling <dooling@gmail.com>\nDavid Gageot <david@gageot.net>\nDavid Karlsson <david.karlsson@docker.com>\nDavid Lechner <david@lechnology.com>\nDavid Scott <dave@recoil.org>\nDavid Sheets <dsheets@docker.com>\nDavid Williamson <david.williamson@docker.com>\nDavid Xia <dxia@spotify.com>\nDavid Young <yangboh@cn.ibm.com>\nDeng Guangxing <dengguangxing@huawei.com>\nDenis Defreyne <denis@soundcloud.com>\nDenis Gladkikh <denis@gladkikh.email>\nDenis Ollier <larchunix@users.noreply.github.com>\nDennis Docter <dennis@d23.nl>\nDerek McGowan <derek@mcg.dev>\nDes Preston <despreston@gmail.com>\nDeshi Xiao <dxiao@redhat.com>\nDharmit Shah <shahdharmit@gmail.com>\nDhawal Yogesh Bhanushali <dbhanushali@vmware.com>\nDieter Reuter <dieter.reuter@me.com>\nDima Stopel <dima@twistlock.com>\nDimitry Andric <d.andric@activevideo.com>\nDing Fei <dingfei@stars.org.cn>\nDiogo Monica <diogo@docker.com>\nDjordje Lukic <djordje.lukic@docker.com>\nDmitriy Fishman <fishman.code@gmail.com>\nDmitry Gusev <dmitry.gusev@gmail.com>\nDmitry Smirnov <onlyjob@member.fsf.org>\nDmitry V. Krivenok <krivenok.dmitry@gmail.com>\nDominik Braun <dominik.braun@nbsp.de>\nDon Kjer <don.kjer@gmail.com>\nDong Chen <dongluo.chen@docker.com>\nDongGeon Lee <secmatth1996@gmail.com>\nDoug Davis <dug@us.ibm.com>\nDrew Erny <derny@mirantis.com>\nEd Costello <epc@epcostello.com>\nElango Sivanandam <elango.siva@docker.com>\nEli Uriegas <eli.uriegas@docker.com>\nEli Uriegas <seemethere101@gmail.com>\nElias Faxö <elias.faxo@tre.se>\nElliot Luo <956941328@qq.com>\nEric Curtin <ericcurtin17@gmail.com>\nEric Engestrom <eric@engestrom.ch>\nEric G. Noriega <enoriega@vizuri.com>\nEric Rosenberg <ehaydenr@gmail.com>\nEric Sage <eric.david.sage@gmail.com>\nEric-Olivier Lamey <eo@lamey.me>\nErica Windisch <erica@windisch.us>\nErik Hollensbe <github@hollensbe.org>\nErik Humphrey <erik.humphrey@carleton.ca>\nErik St. Martin <alakriti@gmail.com>\nEssam A. Hassan <es.hassan187@gmail.com>\nEthan Haynes <ethanhaynes@alumni.harvard.edu>\nEuan Kemp <euank@euank.com>\nEugene Yakubovich <eugene.yakubovich@coreos.com>\nEvan Allrich <evan@unguku.com>\nEvan Hazlett <ejhazlett@gmail.com>\nEvan Krall <krall@yelp.com>\nEvelyn Xu <evelynhsu21@gmail.com>\nEverett Toews <everett.toews@rackspace.com>\nFabio Falci <fabiofalci@gmail.com>\nFabrizio Soppelsa <fsoppelsa@mirantis.com>\nFelix Geyer <debfx@fobos.de>\nFelix Hupfeld <felix@quobyte.com>\nFelix Rabe <felix@rabe.io>\nfezzik1620 <fezzik1620@users.noreply.github.com>\nFilip Jareš <filipjares@gmail.com>\nFlavio Crisciani <flavio.crisciani@docker.com>\nFlorian Klein <florian.klein@free.fr>\nForest Johnson <fjohnson@peoplenetonline.com>\nFoysal Iqbal <foysal.iqbal.fb@gmail.com>\nFrançois Scala <francois.scala@swiss-as.com>\nFred Lifton <fred.lifton@docker.com>\nFrederic Hemberger <mail@frederic-hemberger.de>\nFrederick F. Kautz IV <fkautz@redhat.com>\nFrederik Nordahl Jul Sabroe <frederikns@gmail.com>\nFrieder Bluemle <frieder.bluemle@gmail.com>\nGabriel Gore <gabgore@cisco.com>\nGabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>\nGaetan de Villele <gdevillele@gmail.com>\nGang Qiao <qiaohai8866@gmail.com>\nGary Schaetz <gary@schaetzkc.com>\nGenki Takiuchi <genki@s21g.com>\nGeorge MacRorie <gmacr31@gmail.com>\nGeorge Xie <georgexsh@gmail.com>\nGianluca Borello <g.borello@gmail.com>\nGildas Cuisinier <gildas.cuisinier@gcuisinier.net>\nGio d'Amelio <giodamelio@gmail.com>\nGleb Stsenov <gleb.stsenov@gmail.com>\nGoksu Toprak <goksu.toprak@docker.com>\nGou Rao <gou@portworx.com>\nGovind Rai <raigovind93@gmail.com>\nGrant Reaber <grant.reaber@gmail.com>\nGreg Pflaum <gpflaum@users.noreply.github.com>\nGsealy <jiaojingwei1001@hotmail.com>\nGuilhem Lettron <guilhem+github@lettron.fr>\nGuillaume J. Charmes <guillaume.charmes@docker.com>\nGuillaume Le Floch <glfloch@gmail.com>\nGuillaume Tardif <guillaume.tardif@gmail.com>\ngwx296173 <gaojing3@huawei.com>\nGünther Jungbluth <gunther@gameslabs.net>\nHakan Özler <hakan.ozler@kodcu.com>\nHao Zhang <21521210@zju.edu.cn>\nHarald Albers <github@albersweb.de>\nHarold Cooper <hrldcpr@gmail.com>\nHarry Zhang <harryz@hyper.sh>\nHe Simei <hesimei@zju.edu.cn>\nHector S <hfsam88@gmail.com>\nHelen Xie <chenjg@harmonycloud.cn>\nHenning Sprang <henning.sprang@gmail.com>\nHenry N <henrynmail-github@yahoo.de>\nHernan Garcia <hernandanielg@gmail.com>\nHongbin Lu <hongbin034@gmail.com>\nHu Keping <hukeping@huawei.com>\nHuayi Zhang <irachex@gmail.com>\nHugo Gabriel Eyherabide <hugogabriel.eyherabide@gmail.com>\nhuqun <huqun@zju.edu.cn>\nHuu Nguyen <huu@prismskylabs.com>\nHyzhou Zhy <hyzhou.zhy@alibaba-inc.com>\nIain Samuel McLean Elder <iain@isme.es>\nIan Campbell <ian.campbell@docker.com>\nIan Philpot <ian.philpot@microsoft.com>\nIgnacio Capurro <icapurrofagian@gmail.com>\nIlya Dmitrichenko <errordeveloper@gmail.com>\nIlya Khlopotov <ilya.khlopotov@gmail.com>\nIlya Sotkov <ilya@sotkov.com>\nIoan Eugen Stan <eu@ieugen.ro>\nIsabel Jimenez <contact.isabeljimenez@gmail.com>\nIvan Grcic <igrcic@gmail.com>\nIvan Grund <ivan.grund@gmail.com>\nIvan Markin <sw@nogoegst.net>\nJacob Atzen <jacob@jacobatzen.dk>\nJacob Tomlinson <jacob@tom.linson.uk>\nJaivish Kothari <janonymous.codevulture@gmail.com>\nJake Lambert <jake.lambert@volusion.com>\nJake Sanders <jsand@google.com>\nJames Nesbitt <james.nesbitt@wunderkraut.com>\nJames Turnbull <james@lovedthanlost.net>\nJamie Hannaford <jamie@limetree.org>\nJan Koprowski <jan.koprowski@gmail.com>\nJan Pazdziora <jpazdziora@redhat.com>\nJan-Jaap Driessen <janjaapdriessen@gmail.com>\nJana Radhakrishnan <mrjana@docker.com>\nJared Hocutt <jaredh@netapp.com>\nJasmine Hegman <jasmine@jhegman.com>\nJason Hall <jason@chainguard.dev>\nJason Heiss <jheiss@aput.net>\nJason Plum <jplum@devonit.com>\nJay Kamat <github@jgkamat.33mail.com>\nJean Lecordier <jeanlecordier@hotmail.fr>\nJean Rouge <rougej+github@gmail.com>\nJean-Christophe Sirot <jean-christophe.sirot@docker.com>\nJean-Pierre Huynh <jean-pierre.huynh@ounet.fr>\nJeff Lindsay <progrium@gmail.com>\nJeff Nickoloff <jeff.nickoloff@gmail.com>\nJeff Silberman <jsilberm@gmail.com>\nJennings Zhang <jenni_zh@protonmail.com>\nJeremy Chambers <jeremy@thehipbot.com>\nJeremy Unruh <jeremybunruh@gmail.com>\nJeremy Yallop <yallop@docker.com>\nJeroen Franse <jeroenfranse@gmail.com>\nJesse Adametz <jesseadametz@gmail.com>\nJessica Frazelle <jess@oxide.computer>\nJezeniel Zapanta <jpzapanta22@gmail.com>\nJian Zhang <zhangjian.fnst@cn.fujitsu.com>\nJie Luo <luo612@zju.edu.cn>\nJilles Oldenbeuving <ojilles@gmail.com>\nJim Galasyn <jim.galasyn@docker.com>\nJim Lin <b04705003@ntu.edu.tw>\nJimmy Leger <jimmy.leger@gmail.com>\nJimmy Song <rootsongjc@gmail.com>\njimmyxian <jimmyxian2004@yahoo.com.cn>\nJintao Zhang <zhangjintao9020@gmail.com>\nJoao Fernandes <joao.fernandes@docker.com>\nJoe Abbey <joe.abbey@gmail.com>\nJoe Doliner <jdoliner@pachyderm.io>\nJoe Gordon <joe.gordon0@gmail.com>\nJoel Handwell <joelhandwell@gmail.com>\nJoey Geiger <jgeiger@gmail.com>\nJoffrey F <joffrey@docker.com>\nJohan Euphrosine <proppy@google.com>\nJohannes 'fish' Ziemke <github@freigeist.org>\nJohn Feminella <jxf@jxf.me>\nJohn Harris <john@johnharris.io>\nJohn Howard <github@lowenna.com>\nJohn Howard <howardjohn@google.com>\nJohn Laswell <john.n.laswell@gmail.com>\nJohn Maguire <jmaguire@duosecurity.com>\nJohn Mulhausen <john@docker.com>\nJohn Starks <jostarks@microsoft.com>\nJohn Stephens <johnstep@docker.com>\nJohn Tims <john.k.tims@gmail.com>\nJohn V. Martinez <jvmatl@gmail.com>\nJohn Willis <john.willis@docker.com>\nJon Johnson <jonjohnson@google.com>\nJon Zeolla <zeolla@gmail.com>\nJonatas Baldin <jonatas.baldin@gmail.com>\nJonathan Boulle <jonathanboulle@gmail.com>\nJonathan Lee <jonjohn1232009@gmail.com>\nJonathan Lomas <jonathan@floatinglomas.ca>\nJonathan McCrohan <jmccrohan@gmail.com>\nJonathan Warriss-Simmons <misterws@diogenes.ws>\nJonh Wendell <jonh.wendell@redhat.com>\nJordan Jennings <jjn2009@gmail.com>\nJorge Vallecillo <jorgevallecilloc@gmail.com>\nJose J. Escobar <53836904+jescobar-docker@users.noreply.github.com>\nJoseph Kern <jkern@semafour.net>\nJosh Bodah <jb3689@yahoo.com>\nJosh Chorlton <jchorlton@gmail.com>\nJosh Hawn <josh.hawn@docker.com>\nJosh Horwitz <horwitz@addthis.com>\nJosh Soref <jsoref@gmail.com>\nJulien Barbier <write0@gmail.com>\nJulien Kassar <github@kassisol.com>\nJulien Maitrehenry <julien.maitrehenry@me.com>\nJustas Brazauskas <brazauskasjustas@gmail.com>\nJustin Cormack <justin.cormack@docker.com>\nJustin Simonelis <justin.p.simonelis@gmail.com>\nJustyn Temme <justyntemme@gmail.com>\nJyrki Puttonen <jyrkiput@gmail.com>\nJérémie Drouet <jeremie.drouet@gmail.com>\nJérôme Petazzoni <jerome.petazzoni@docker.com>\nJörg Thalheim <joerg@higgsboson.tk>\nKai Blin <kai@samba.org>\nKai Qiang Wu (Kennan) <wkq5325@gmail.com>\nKara Alexandra <kalexandra@us.ibm.com>\nKareem Khazem <karkhaz@karkhaz.com>\nKarthik Nayak <Karthik.188@gmail.com>\nKat Samperi <kat.samperi@gmail.com>\nKathryn Spiers <kathryn@spiers.me>\nKatie McLaughlin <katie@glasnt.com>\nKe Xu <leonhartx.k@gmail.com>\nKei Ohmura <ohmura.kei@gmail.com>\nKeith Hudgins <greenman@greenman.org>\nKelton Bassingthwaite <KeltonBassingthwaite@gmail.com>\nKen Cochrane <kencochrane@gmail.com>\nKen ICHIKAWA <ichikawa.ken@jp.fujitsu.com>\nKenfe-Mickaël Laventure <mickael.laventure@gmail.com>\nKevin Alvarez <crazy-max@users.noreply.github.com>\nKevin Burke <kev@inburke.com>\nKevin Feyrer <kevin.feyrer@btinternet.com>\nKevin Kern <kaiwentan@harmonycloud.cn>\nKevin Kirsche <Kev.Kirsche+GitHub@gmail.com>\nKevin Meredith <kevin.m.meredith@gmail.com>\nKevin Richardson <kevin@kevinrichardson.co>\nKevin Woblick <mail@kovah.de>\nkhaled souf <khaled.souf@gmail.com>\nKim Eik <kim@heldig.org>\nKir Kolyshkin <kolyshkin@gmail.com>\nKotaro Yoshimatsu <kotaro.yoshimatsu@gmail.com>\nKrasi Georgiev <krasi@vip-consult.solutions>\nKris-Mikael Krister <krismikael@protonmail.com>\nKun Zhang <zkazure@gmail.com>\nKunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>\nKyle Mitofsky <Kylemit@gmail.com>\nLachlan Cooper <lachlancooper@gmail.com>\nLai Jiangshan <jiangshanlai@gmail.com>\nLars Kellogg-Stedman <lars@redhat.com>\nLaura Frank <ljfrank@gmail.com>\nLaurent Erignoux <lerignoux@gmail.com>\nLee Gaines <eightlimbed@gmail.com>\nLei Jitang <leijitang@huawei.com>\nLennie <github@consolejunkie.net>\nLeo Gallucci <elgalu3@gmail.com>\nLeonid Skorospelov <leosko94@gmail.com>\nLewis Daly <lewisdaly@me.com>\nLi Yi <denverdino@gmail.com>\nLi Yi <weiyuan.yl@alibaba-inc.com>\nLiang-Chi Hsieh <viirya@gmail.com>\nLifubang <lifubang@acmcoder.com>\nLihua Tang <lhtang@alauda.io>\nLily Guo <lily.guo@docker.com>\nLin Lu <doraalin@163.com>\nLinus Heckemann <lheckemann@twig-world.com>\nLiping Xue <lipingxue@gmail.com>\nLiron Levin <liron@twistlock.com>\nliwenqi <vikilwq@zju.edu.cn>\nlixiaobing10051267 <li.xiaobing1@zte.com.cn>\nLloyd Dewolf <foolswisdom@gmail.com>\nLorenzo Fontana <lo@linux.com>\nLouis Opter <kalessin@kalessin.fr>\nLuca Favatella <luca.favatella@erlang-solutions.com>\nLuca Marturana <lucamarturana@gmail.com>\nLucas Chan <lucas-github@lucaschan.com>\nLuka Hartwig <mail@lukahartwig.de>\nLukas Heeren <lukas-heeren@hotmail.com>\nLukasz Zajaczkowski <Lukasz.Zajaczkowski@ts.fujitsu.com>\nLydell Manganti <LydellManganti@users.noreply.github.com>\nLénaïc Huard <lhuard@amadeus.com>\nMa Shimiao <mashimiao.fnst@cn.fujitsu.com>\nMabin <bin.ma@huawei.com>\nMaciej Kalisz <maciej.d.kalisz@gmail.com>\nMadhav Puri <madhav.puri@gmail.com>\nMadhu Venugopal <madhu@socketplane.io>\nMadhur Batra <madhurbatra097@gmail.com>\nMalte Janduda <mail@janduda.net>\nManjunath A Kumatagi <mkumatag@in.ibm.com>\nMansi Nahar <mmn4185@rit.edu>\nmapk0y <mapk0y@gmail.com>\nMarc Bihlmaier <marc.bihlmaier@reddoxx.com>\nMarc Cornellà <hello@mcornella.com>\nMarco Mariani <marco.mariani@alterway.fr>\nMarco Vedovati <mvedovati@suse.com>\nMarcus Martins <marcus@docker.com>\nMarianna Tessel <mtesselh@gmail.com>\nMarius Ileana <marius.ileana@gmail.com>\nMarius Sturm <marius@graylog.com>\nMark Oates <fl0yd@me.com>\nMarsh Macy <marsma@microsoft.com>\nMartin Mosegaard Amdisen <martin.amdisen@praqma.com>\nMary Anthony <mary.anthony@docker.com>\nMason Fish <mason.fish@docker.com>\nMason Malone <mason.malone@gmail.com>\nMateusz Major <apkd@users.noreply.github.com>\nMathieu Champlon <mathieu.champlon@docker.com>\nMathieu Rollet <matletix@gmail.com>\nMatt Gucci <matt9ucci@gmail.com>\nMatt Robenolt <matt@ydekproductions.com>\nMatteo Orefice <matteo.orefice@bites4bits.software>\nMatthew Heon <mheon@redhat.com>\nMatthieu Hauglustaine <matt.hauglustaine@gmail.com>\nMauro Porras P <mauroporrasp@gmail.com>\nMax Shytikov <mshytikov@gmail.com>\nMaxime Petazzoni <max@signalfuse.com>\nMaximillian Fan Xavier <maximillianfx@gmail.com>\nMei ChunTao <mei.chuntao@zte.com.cn>\nMetal <2466052+tedhexaflow@users.noreply.github.com>\nMicah Zoltu <micah@newrelic.com>\nMichael A. Smith <michael@smith-li.com>\nMichael Bridgen <mikeb@squaremobius.net>\nMichael Crosby <crosbymichael@gmail.com>\nMichael Friis <friism@gmail.com>\nMichael Irwin <mikesir87@gmail.com>\nMichael Käufl <docker@c.michael-kaeufl.de>\nMichael Prokop <github@michael-prokop.at>\nMichael Scharf <github@scharf.gr>\nMichael Spetsiotis <michael_spets@hotmail.com>\nMichael Steinert <mike.steinert@gmail.com>\nMichael West <mwest@mdsol.com>\nMichal Minář <miminar@redhat.com>\nMichał Czeraszkiewicz <czerasz@gmail.com>\nMiguel Angel Alvarez Cabrerizo <doncicuto@gmail.com>\nMihai Borobocea <MihaiBorob@gmail.com>\nMihuleacc Sergiu <mihuleac.sergiu@gmail.com>\nMike Brown <brownwm@us.ibm.com>\nMike Casas <mkcsas0@gmail.com>\nMike Dalton <mikedalton@github.com>\nMike Danese <mikedanese@google.com>\nMike Dillon <mike@embody.org>\nMike Goelzer <mike.goelzer@docker.com>\nMike MacCana <mike.maccana@gmail.com>\nmikelinjie <294893458@qq.com>\nMikhail Vasin <vasin@cloud-tv.ru>\nMilind Chawre <milindchawre@gmail.com>\nMindaugas Rukas <momomg@gmail.com>\nMiroslav Gula <miroslav.gula@naytrolabs.com>\nMisty Stanley-Jones <misty@docker.com>\nMohammad Banikazemi <mb@us.ibm.com>\nMohammed Aaqib Ansari <maaquib@gmail.com>\nMohini Anne Dsouza <mohini3917@gmail.com>\nMoorthy RS <rsmoorthy@gmail.com>\nMorgan Bauer <mbauer@us.ibm.com>\nMorten Hekkvang <morten.hekkvang@sbab.se>\nMorten Linderud <morten@linderud.pw>\nMoysés Borges <moysesb@gmail.com>\nMozi <29089388+pzhlkj6612@users.noreply.github.com>\nMrunal Patel <mrunalp@gmail.com>\nmuicoder <muicoder@gmail.com>\nMurukesh Mohanan <murukesh.mohanan@gmail.com>\nMuthukumar R <muthur@gmail.com>\nMáximo Cuadros <mcuadros@gmail.com>\nMårten Cassel <marten.cassel@gmail.com>\nNace Oroz <orkica@gmail.com>\nNahum Shalman <nshalman@omniti.com>\nNalin Dahyabhai <nalin@redhat.com>\nNao YONASHIRO <owan.orisano@gmail.com>\nNassim 'Nass' Eddequiouaq <eddequiouaq.nassim@gmail.com>\nNatalie Parker <nparker@omnifone.com>\nNate Brennand <nate.brennand@clever.com>\nNathan Hsieh <hsieh.nathan@gmail.com>\nNathan LeClaire <nathan.leclaire@docker.com>\nNathan McCauley <nathan.mccauley@docker.com>\nNeil Peterson <neilpeterson@outlook.com>\nNick Adcock <nick.adcock@docker.com>\nNick Santos <nick.santos@docker.com>\nNico Stapelbroek <nstapelbroek@gmail.com>\nNicola Kabar <nicolaka@gmail.com>\nNicolas Borboën <ponsfrilus@gmail.com>\nNicolas De Loof <nicolas.deloof@gmail.com>\nNikhil Chawla <chawlanikhil24@gmail.com>\nNikolas Garofil <nikolas.garofil@uantwerpen.be>\nNikolay Milovanov <nmil@itransformers.net>\nNir Soffer <nsoffer@redhat.com>\nNishant Totla <nishanttotla@gmail.com>\nNIWA Hideyuki <niwa.niwa@nifty.ne.jp>\nNoah Treuhaft <noah.treuhaft@docker.com>\nO.S. Tezer <ostezer@gmail.com>\nOdin Ugedal <odin@ugedal.com>\nohmystack <jun.jiang02@ele.me>\nOKA Naoya <git@okanaoya.com>\nOliver Pomeroy <oppomeroy@gmail.com>\nOlle Jonsson <olle.jonsson@gmail.com>\nOlli Janatuinen <olli.janatuinen@gmail.com>\nOscar Wieman <oscrx@icloud.com>\nOtto Kekäläinen <otto@seravo.fi>\nOvidio Mallo <ovidio.mallo@gmail.com>\nPascal Borreli <pascal@borreli.com>\nPatrick Böänziger <patrick.baenziger@bsi-software.com>\nPatrick Hemmer <patrick.hemmer@gmail.com>\nPatrick Lang <plang@microsoft.com>\nPaul <paul9869@gmail.com>\nPaul Kehrer <paul.l.kehrer@gmail.com>\nPaul Lietar <paul@lietar.net>\nPaul Mulders <justinkb@gmail.com>\nPaul Weaver <pauweave@cisco.com>\nPavel Pospisil <pospispa@gmail.com>\nPaweł Gronowski <pawel.gronowski@docker.com>\nPaweł Pokrywka <pepawel@users.noreply.github.com>\nPaweł Szczekutowicz <pszczekutowicz@gmail.com>\nPeeyush Gupta <gpeeyush@linux.vnet.ibm.com>\nPer Lundberg <per.lundberg@ecraft.com>\nPeter Dave Hello <hsu@peterdavehello.org>\nPeter Edge <peter.edge@gmail.com>\nPeter Hsu <shhsu@microsoft.com>\nPeter Jaffe <pjaffe@nevo.com>\nPeter Kehl <peter.kehl@gmail.com>\nPeter Nagy <xificurC@gmail.com>\nPeter Salvatore <peter@psftw.com>\nPeter Waller <p@pwaller.net>\nPhil Estes <estesp@gmail.com>\nPhilip Alexander Etling <paetling@gmail.com>\nPhilipp Gillé <philipp.gille@gmail.com>\nPhilipp Schmied <pschmied@schutzwerk.com>\nPhong Tran <tran.pho@northeastern.edu>\npidster <pid@pidster.com>\nPieter E Smit <diepes@github.com>\npixelistik <pixelistik@users.noreply.github.com>\nPratik Karki <prertik@outlook.com>\nPrayag Verma <prayag.verma@gmail.com>\nPreston Cowley <preston.cowley@sony.com>\nPure White <daniel48@126.com>\nQiang Huang <h.huangqiang@huawei.com>\nQinglan Peng <qinglanpeng@zju.edu.cn>\nqudongfang <qudongfang@gmail.com>\nRaghavendra K T <raghavendra.kt@linux.vnet.ibm.com>\nRahul Kadyan <hi@znck.me>\nRahul Zoldyck <rahulzoldyck@gmail.com>\nRavi Shekhar Jethani <rsjethani@gmail.com>\nRay Tsang <rayt@google.com>\nReficul <xuzhenglun@gmail.com>\nRemy Suen <remy.suen@gmail.com>\nRenaud Gaubert <rgaubert@nvidia.com>\nRicardo N Feliciano <FelicianoTech@gmail.com>\nRich Moyse <rich@moyse.us>\nRichard Chen Zheng <58443436+rchenzheng@users.noreply.github.com>\nRichard Mathie <richard.mathie@amey.co.uk>\nRichard Scothern <richard.scothern@gmail.com>\nRick Wieman <git@rickw.nl>\nRitesh H Shukla <sritesh@vmware.com>\nRiyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>\nRob Gulewich <rgulewich@netflix.com>\nRobert Wallis <smilingrob@gmail.com>\nRobin Naundorf <r.naundorf@fh-muenster.de>\nRobin Speekenbrink <robin@kingsquare.nl>\nRoch Feuillade <roch.feuillade@pandobac.com>\nRodolfo Ortiz <rodolfo.ortiz@definityfirst.com>\nRogelio Canedo <rcanedo@mappy.priv>\nRohan Verma <hello@rohanverma.net>\nRoland Kammerer <roland.kammerer@linbit.com>\nRoman Dudin <katrmr@gmail.com>\nRory Hunter <roryhunter2@gmail.com>\nRoss Boucher <rboucher@gmail.com>\nRubens Figueiredo <r.figueiredo.52@gmail.com>\nRui Cao <ruicao@alauda.io>\nRyan Belgrave <rmb1993@gmail.com>\nRyan Detzel <ryan.detzel@gmail.com>\nRyan Stelly <ryan.stelly@live.com>\nRyan Wilson-Perkin <ryanwilsonperkin@gmail.com>\nRyan Zhang <ryan.zhang@docker.com>\nSainath Grandhi <sainath.grandhi@intel.com>\nSakeven Jiang <jc5930@sina.cn>\nSally O'Malley <somalley@redhat.com>\nSam Neirinck <sam@samneirinck.com>\nSam Thibault <sam.thibault@docker.com>\nSamarth Shah <samashah@microsoft.com>\nSambuddha Basu <sambuddhabasu1@gmail.com>\nSami Tabet <salph.tabet@gmail.com>\nSamuel Cochran <sj26@sj26.com>\nSamuel Karp <skarp@amazon.com>\nSandro Jäckel <sandro.jaeckel@gmail.com>\nSanthosh Manohar <santhosh@docker.com>\nSargun Dhillon <sargun@netflix.com>\nSaswat Bhattacharya <sas.saswat@gmail.com>\nScott Brenner <scott@scottbrenner.me>\nScott Collier <emailscottcollier@gmail.com>\nSean Christopherson <sean.j.christopherson@intel.com>\nSean Rodman <srodman7689@gmail.com>\nSebastiaan van Stijn <github@gone.nl>\nSergey Tryuber <Sergeant007@users.noreply.github.com>\nSerhat Gülçiçek <serhat25@gmail.com>\nSevki Hasirci <s@sevki.org>\nShaun Kaasten <shaunk@gmail.com>\nSheng Yang <sheng@yasker.org>\nShijiang Wei <mountkin@gmail.com>\nShishir Mahajan <shishir.mahajan@redhat.com>\nShoubhik Bose <sbose78@gmail.com>\nShukui Yang <yangshukui@huawei.com>\nSian Lerk Lau <kiawin@gmail.com>\nSidhartha Mani <sidharthamn@gmail.com>\nsidharthamani <sid@rancher.com>\nSilvin Lubecki <silvin.lubecki@docker.com>\nSimei He <hesimei@zju.edu.cn>\nSimon Ferquel <simon.ferquel@docker.com>\nSimon Heimberg <simon.heimberg@heimberg-ea.ch>\nSindhu S <sindhus@live.in>\nSlava Semushin <semushin@redhat.com>\nSolomon Hykes <solomon@docker.com>\nSong Gao <song@gao.io>\nSpencer Brown <spencer@spencerbrown.org>\nSpring Lee <xi.shuai@outlook.com>\nsqueegels <lmscrewy@gmail.com>\nSrini Brahmaroutu <srbrahma@us.ibm.com>\nStefan S. <tronicum@user.github.com>\nStefan Scherer <stefan.scherer@docker.com>\nStefan Weil <sw@weilnetz.de>\nStephane Jeandeaux <stephane.jeandeaux@gmail.com>\nStephen Day <stevvooe@gmail.com>\nStephen Rust <srust@blockbridge.com>\nSteve Durrheimer <s.durrheimer@gmail.com>\nSteve Richards <steve.richards@docker.com>\nSteven Burgess <steven.a.burgess@hotmail.com>\nStoica-Marcu Floris-Andrei <floris.sm@gmail.com>\nSubhajit Ghosh <isubuz.g@gmail.com>\nSun Jianbo <wonderflow.sun@gmail.com>\nSune Keller <absukl@almbrand.dk>\nSungwon Han <sungwon.han@navercorp.com>\nSunny Gogoi <indiasuny000@gmail.com>\nSven Dowideit <SvenDowideit@home.org.au>\nSylvain Baubeau <sbaubeau@redhat.com>\nSébastien HOUZÉ <cto@verylastroom.com>\nT K Sourabh <sourabhtk37@gmail.com>\nTAGOMORI Satoshi <tagomoris@gmail.com>\ntaiji-tech <csuhqg@foxmail.com>\nTakeshi Koenuma <t.koenuma2@gmail.com>\nTakuya Noguchi <takninnovationresearch@gmail.com>\nTaylor Jones <monitorjbl@gmail.com>\nTeiva Harsanyi <t.harsanyi@thebeat.co>\nTejaswini Duggaraju <naduggar@microsoft.com>\nTengfei Wang <tfwang@alauda.io>\nTeppei Fukuda <knqyf263@gmail.com>\nThatcher Peskens <thatcher@docker.com>\nThibault Coupin <thibault.coupin@gmail.com>\nThomas Gazagnaire <thomas@gazagnaire.org>\nThomas Krzero <thomas.kovatchitch@gmail.com>\nThomas Leonard <thomas.leonard@docker.com>\nThomas Léveil <thomasleveil@gmail.com>\nThomas Riccardi <thomas@deepomatic.com>\nThomas Swift <tgs242@gmail.com>\nTianon Gravi <admwiggin@gmail.com>\nTianyi Wang <capkurmagati@gmail.com>\nTibor Vass <teabee89@gmail.com>\nTim Dettrick <t.dettrick@uq.edu.au>\nTim Hockin <thockin@google.com>\nTim Sampson <tim@sampson.fi>\nTim Smith <timbot@google.com>\nTim Waugh <twaugh@redhat.com>\nTim Wraight <tim.wraight@tangentlabs.co.uk>\ntimfeirg <kkcocogogo@gmail.com>\nTimothy Hobbs <timothyhobbs@seznam.cz>\nTobias Bradtke <webwurst@gmail.com>\nTobias Gesellchen <tobias@gesellix.de>\nTodd Whiteman <todd.whiteman@joyent.com>\nTom Denham <tom@tomdee.co.uk>\nTom Fotherby <tom+github@peopleperhour.com>\nTom Klingenberg <tklingenberg@lastflood.net>\nTom Milligan <code@tommilligan.net>\nTom X. Tobin <tomxtobin@tomxtobin.com>\nTomas Bäckman <larstomas@gmail.com>\nTomas Tomecek <ttomecek@redhat.com>\nTomasz Kopczynski <tomek@kopczynski.net.pl>\nTomáš Hrčka <thrcka@redhat.com>\nTony Abboud <tdabboud@hotmail.com>\nTõnis Tiigi <tonistiigi@gmail.com>\nTrapier Marshall <trapier.marshall@docker.com>\nTravis Cline <travis.cline@gmail.com>\nTristan Carel <tristan@cogniteev.com>\nTycho Andersen <tycho@docker.com>\nTycho Andersen <tycho@tycho.ws>\nuhayate <uhayate.gong@daocloud.io>\nUlrich Bareth <ulrich.bareth@gmail.com>\nUlysses Souza <ulysses.souza@docker.com>\nUmesh Yadav <umesh4257@gmail.com>\nValentin Lorentz <progval+git@progval.net>\nVardan Pogosian <vardan.pogosyan@gmail.com>\nVenkateswara Reddy Bukkasamudram <bukkasamudram@outlook.com>\nVeres Lajos <vlajos@gmail.com>\nVictor Vieux <victor.vieux@docker.com>\nVictoria Bialas <victoria.bialas@docker.com>\nViktor Stanchev <me@viktorstanchev.com>\nVimal Raghubir <vraghubir0418@gmail.com>\nVincent Batts <vbatts@redhat.com>\nVincent Bernat <Vincent.Bernat@exoscale.ch>\nVincent Demeester <vincent.demeester@docker.com>\nVincent Woo <me@vincentwoo.com>\nVishnu Kannan <vishnuk@google.com>\nVivek Goyal <vgoyal@redhat.com>\nWang Jie <wangjie5@chinaskycloud.com>\nWang Lei <wanglei@tenxcloud.com>\nWang Long <long.wanglong@huawei.com>\nWang Ping <present.wp@icloud.com>\nWang Xing <hzwangxing@corp.netease.com>\nWang Yuexiao <wang.yuexiao@zte.com.cn>\nWang Yumu <37442693@qq.com>\nWataru Ishida <ishida.wataru@lab.ntt.co.jp>\nWayne Song <wsong@docker.com>\nWen Cheng Ma <wenchma@cn.ibm.com>\nWenzhi Liang <wenzhi.liang@gmail.com>\nWes Morgan <cap10morgan@gmail.com>\nWewang Xiaorenfine <wang.xiaoren@zte.com.cn>\nWilliam Henry <whenry@redhat.com>\nXianglin Gao <xlgao@zju.edu.cn>\nXiaodong Liu <liuxiaodong@loongson.cn>\nXiaodong Zhang <a4012017@sina.com>\nXiaoxi He <xxhe@alauda.io>\nXinbo Weng <xihuanbo_0521@zju.edu.cn>\nXuecong Liao <satorulogic@gmail.com>\nYan Feng <yanfeng2@huawei.com>\nYanqiang Miao <miao.yanqiang@zte.com.cn>\nYassine Tijani <yasstij11@gmail.com>\nYi EungJun <eungjun.yi@navercorp.com>\nYing Li <ying.li@docker.com>\nYong Tang <yong.tang.github@outlook.com>\nYosef Fertel <yfertel@gmail.com>\nYu Peng <yu.peng36@zte.com.cn>\nYuan Sun <sunyuan3@huawei.com>\nYue Zhang <zy675793960@yeah.net>\nYunxiang Huang <hyxqshk@vip.qq.com>\nZachary Romero <zacromero3@gmail.com>\nZander Mackie <zmackie@gmail.com>\nzebrilee <zebrilee@gmail.com>\nZeel B Patel <patel_zeel@iitgn.ac.in>\nZhang Kun <zkazure@gmail.com>\nZhang Wei <zhangwei555@huawei.com>\nZhang Wentao <zhangwentao234@huawei.com>\nZhangHang <stevezhang2014@gmail.com>\nzhenghenghuo <zhenghenghuo@zju.edu.cn>\nZhou Hao <zhouhao@cn.fujitsu.com>\nZhoulin Xie <zhoulin.xie@daocloud.io>\nZhu Guihua <zhugh.fnst@cn.fujitsu.com>\nÁlex González <agonzalezro@gmail.com>\nÁlvaro Lázaro <alvaro.lazaro.g@gmail.com>\nÁtila Camurça Alves <camurca.home@gmail.com>\nАлександр Менщиков <__Singleton__@hackerdom.ru>\n徐俊杰 <paco.xu@daocloud.io>\n"
  },
  {
    "path": "vendor/github.com/docker/cli/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": "vendor/github.com/docker/cli/NOTICE",
    "content": "Docker\nCopyright 2012-2017 Docker, Inc.\n\nThis product includes software developed at Docker, Inc. (https://www.docker.com).\n\nThis product contains software (https://github.com/creack/pty) developed\nby Keith Rarick, licensed under the MIT License.\n\nThe following is courtesy of our legal counsel:\n\n\nUse and transfer of Docker may be subject to certain restrictions by the\nUnited States and other governments.\nIt is your responsibility to ensure that your use and/or transfer does not\nviolate applicable laws.\n\nFor more information, please see https://www.bis.doc.gov\n\nSee also https://www.apache.org/dev/crypto.html and/or seek legal counsel.\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/config.go",
    "content": "package config\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/docker/cli/cli/config/configfile\"\n\t\"github.com/docker/cli/cli/config/credentials\"\n\t\"github.com/docker/cli/cli/config/types\"\n\t\"github.com/docker/docker/pkg/homedir\"\n\t\"github.com/pkg/errors\"\n)\n\nconst (\n\t// ConfigFileName is the name of config file\n\tConfigFileName = \"config.json\"\n\tconfigFileDir  = \".docker\"\n\toldConfigfile  = \".dockercfg\" // Deprecated: remove once we stop printing deprecation warning\n\tcontextsDir    = \"contexts\"\n)\n\nvar (\n\tinitConfigDir = new(sync.Once)\n\tconfigDir     string\n\thomeDir       string\n)\n\n// resetHomeDir is used in testing to reset the \"homeDir\" package variable to\n// force re-lookup of the home directory between tests.\nfunc resetHomeDir() {\n\thomeDir = \"\"\n}\n\nfunc getHomeDir() string {\n\tif homeDir == \"\" {\n\t\thomeDir = homedir.Get()\n\t}\n\treturn homeDir\n}\n\n// resetConfigDir is used in testing to reset the \"configDir\" package variable\n// and its sync.Once to force re-lookup between tests.\nfunc resetConfigDir() {\n\tconfigDir = \"\"\n\tinitConfigDir = new(sync.Once)\n}\n\nfunc setConfigDir() {\n\tif configDir != \"\" {\n\t\treturn\n\t}\n\tconfigDir = os.Getenv(\"DOCKER_CONFIG\")\n\tif configDir == \"\" {\n\t\tconfigDir = filepath.Join(getHomeDir(), configFileDir)\n\t}\n}\n\n// Dir returns the directory the configuration file is stored in\nfunc Dir() string {\n\tinitConfigDir.Do(setConfigDir)\n\treturn configDir\n}\n\n// ContextStoreDir returns the directory the docker contexts are stored in\nfunc ContextStoreDir() string {\n\treturn filepath.Join(Dir(), contextsDir)\n}\n\n// SetDir sets the directory the configuration file is stored in\nfunc SetDir(dir string) {\n\tconfigDir = filepath.Clean(dir)\n}\n\n// Path returns the path to a file relative to the config dir\nfunc Path(p ...string) (string, error) {\n\tpath := filepath.Join(append([]string{Dir()}, p...)...)\n\tif !strings.HasPrefix(path, Dir()+string(filepath.Separator)) {\n\t\treturn \"\", errors.Errorf(\"path %q is outside of root config directory %q\", path, Dir())\n\t}\n\treturn path, nil\n}\n\n// LoadFromReader is a convenience function that creates a ConfigFile object from\n// a reader\nfunc LoadFromReader(configData io.Reader) (*configfile.ConfigFile, error) {\n\tconfigFile := configfile.ConfigFile{\n\t\tAuthConfigs: make(map[string]types.AuthConfig),\n\t}\n\terr := configFile.LoadFromReader(configData)\n\treturn &configFile, err\n}\n\n// Load reads the configuration files in the given directory, and sets up\n// the auth config information and returns values.\n// FIXME: use the internal golang config parser\nfunc Load(configDir string) (*configfile.ConfigFile, error) {\n\tcfg, _, err := load(configDir)\n\treturn cfg, err\n}\n\n// TODO remove this temporary hack, which is used to warn about the deprecated ~/.dockercfg file\n// so we can remove the bool return value and collapse this back into `Load`\nfunc load(configDir string) (*configfile.ConfigFile, bool, error) {\n\tprintLegacyFileWarning := false\n\n\tif configDir == \"\" {\n\t\tconfigDir = Dir()\n\t}\n\n\tfilename := filepath.Join(configDir, ConfigFileName)\n\tconfigFile := configfile.New(filename)\n\n\t// Try happy path first - latest config file\n\tif file, err := os.Open(filename); err == nil {\n\t\tdefer file.Close()\n\t\terr = configFile.LoadFromReader(file)\n\t\tif err != nil {\n\t\t\terr = errors.Wrap(err, filename)\n\t\t}\n\t\treturn configFile, printLegacyFileWarning, err\n\t} else if !os.IsNotExist(err) {\n\t\t// if file is there but we can't stat it for any reason other\n\t\t// than it doesn't exist then stop\n\t\treturn configFile, printLegacyFileWarning, errors.Wrap(err, filename)\n\t}\n\n\t// Can't find latest config file so check for the old one\n\tfilename = filepath.Join(getHomeDir(), oldConfigfile)\n\tif _, err := os.Stat(filename); err == nil {\n\t\tprintLegacyFileWarning = true\n\t}\n\treturn configFile, printLegacyFileWarning, nil\n}\n\n// LoadDefaultConfigFile attempts to load the default config file and returns\n// an initialized ConfigFile struct if none is found.\nfunc LoadDefaultConfigFile(stderr io.Writer) *configfile.ConfigFile {\n\tconfigFile, printLegacyFileWarning, err := load(Dir())\n\tif err != nil {\n\t\tfmt.Fprintf(stderr, \"WARNING: Error loading config file: %v\\n\", err)\n\t}\n\tif printLegacyFileWarning {\n\t\t_, _ = fmt.Fprintln(stderr, \"WARNING: Support for the legacy ~/.dockercfg configuration file and file-format has been removed and the configuration file will be ignored\")\n\t}\n\tif !configFile.ContainsAuth() {\n\t\tconfigFile.CredentialsStore = credentials.DetectDefaultStore(configFile.CredentialsStore)\n\t}\n\treturn configFile\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/configfile/file.go",
    "content": "package configfile\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/docker/cli/cli/config/credentials\"\n\t\"github.com/docker/cli/cli/config/types\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/sirupsen/logrus\"\n)\n\n// ConfigFile ~/.docker/config.json file info\ntype ConfigFile struct {\n\tAuthConfigs          map[string]types.AuthConfig  `json:\"auths\"`\n\tHTTPHeaders          map[string]string            `json:\"HttpHeaders,omitempty\"`\n\tPsFormat             string                       `json:\"psFormat,omitempty\"`\n\tImagesFormat         string                       `json:\"imagesFormat,omitempty\"`\n\tNetworksFormat       string                       `json:\"networksFormat,omitempty\"`\n\tPluginsFormat        string                       `json:\"pluginsFormat,omitempty\"`\n\tVolumesFormat        string                       `json:\"volumesFormat,omitempty\"`\n\tStatsFormat          string                       `json:\"statsFormat,omitempty\"`\n\tDetachKeys           string                       `json:\"detachKeys,omitempty\"`\n\tCredentialsStore     string                       `json:\"credsStore,omitempty\"`\n\tCredentialHelpers    map[string]string            `json:\"credHelpers,omitempty\"`\n\tFilename             string                       `json:\"-\"` // Note: for internal use only\n\tServiceInspectFormat string                       `json:\"serviceInspectFormat,omitempty\"`\n\tServicesFormat       string                       `json:\"servicesFormat,omitempty\"`\n\tTasksFormat          string                       `json:\"tasksFormat,omitempty\"`\n\tSecretFormat         string                       `json:\"secretFormat,omitempty\"`\n\tConfigFormat         string                       `json:\"configFormat,omitempty\"`\n\tNodesFormat          string                       `json:\"nodesFormat,omitempty\"`\n\tPruneFilters         []string                     `json:\"pruneFilters,omitempty\"`\n\tProxies              map[string]ProxyConfig       `json:\"proxies,omitempty\"`\n\tExperimental         string                       `json:\"experimental,omitempty\"`\n\tCurrentContext       string                       `json:\"currentContext,omitempty\"`\n\tCLIPluginsExtraDirs  []string                     `json:\"cliPluginsExtraDirs,omitempty\"`\n\tPlugins              map[string]map[string]string `json:\"plugins,omitempty\"`\n\tAliases              map[string]string            `json:\"aliases,omitempty\"`\n}\n\n// ProxyConfig contains proxy configuration settings\ntype ProxyConfig struct {\n\tHTTPProxy  string `json:\"httpProxy,omitempty\"`\n\tHTTPSProxy string `json:\"httpsProxy,omitempty\"`\n\tNoProxy    string `json:\"noProxy,omitempty\"`\n\tFTPProxy   string `json:\"ftpProxy,omitempty\"`\n\tAllProxy   string `json:\"allProxy,omitempty\"`\n}\n\n// New initializes an empty configuration file for the given filename 'fn'\nfunc New(fn string) *ConfigFile {\n\treturn &ConfigFile{\n\t\tAuthConfigs: make(map[string]types.AuthConfig),\n\t\tHTTPHeaders: make(map[string]string),\n\t\tFilename:    fn,\n\t\tPlugins:     make(map[string]map[string]string),\n\t\tAliases:     make(map[string]string),\n\t}\n}\n\n// LoadFromReader reads the configuration data given and sets up the auth config\n// information with given directory and populates the receiver object\nfunc (configFile *ConfigFile) LoadFromReader(configData io.Reader) error {\n\tif err := json.NewDecoder(configData).Decode(configFile); err != nil && !errors.Is(err, io.EOF) {\n\t\treturn err\n\t}\n\tvar err error\n\tfor addr, ac := range configFile.AuthConfigs {\n\t\tif ac.Auth != \"\" {\n\t\t\tac.Username, ac.Password, err = decodeAuth(ac.Auth)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tac.Auth = \"\"\n\t\tac.ServerAddress = addr\n\t\tconfigFile.AuthConfigs[addr] = ac\n\t}\n\treturn nil\n}\n\n// ContainsAuth returns whether there is authentication configured\n// in this file or not.\nfunc (configFile *ConfigFile) ContainsAuth() bool {\n\treturn configFile.CredentialsStore != \"\" ||\n\t\tlen(configFile.CredentialHelpers) > 0 ||\n\t\tlen(configFile.AuthConfigs) > 0\n}\n\n// GetAuthConfigs returns the mapping of repo to auth configuration\nfunc (configFile *ConfigFile) GetAuthConfigs() map[string]types.AuthConfig {\n\treturn configFile.AuthConfigs\n}\n\n// SaveToWriter encodes and writes out all the authorization information to\n// the given writer\nfunc (configFile *ConfigFile) SaveToWriter(writer io.Writer) error {\n\t// Encode sensitive data into a new/temp struct\n\ttmpAuthConfigs := make(map[string]types.AuthConfig, len(configFile.AuthConfigs))\n\tfor k, authConfig := range configFile.AuthConfigs {\n\t\tauthCopy := authConfig\n\t\t// encode and save the authstring, while blanking out the original fields\n\t\tauthCopy.Auth = encodeAuth(&authCopy)\n\t\tauthCopy.Username = \"\"\n\t\tauthCopy.Password = \"\"\n\t\tauthCopy.ServerAddress = \"\"\n\t\ttmpAuthConfigs[k] = authCopy\n\t}\n\n\tsaveAuthConfigs := configFile.AuthConfigs\n\tconfigFile.AuthConfigs = tmpAuthConfigs\n\tdefer func() { configFile.AuthConfigs = saveAuthConfigs }()\n\n\t// User-Agent header is automatically set, and should not be stored in the configuration\n\tfor v := range configFile.HTTPHeaders {\n\t\tif strings.EqualFold(v, \"User-Agent\") {\n\t\t\tdelete(configFile.HTTPHeaders, v)\n\t\t}\n\t}\n\n\tdata, err := json.MarshalIndent(configFile, \"\", \"\\t\")\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = writer.Write(data)\n\treturn err\n}\n\n// Save encodes and writes out all the authorization information\nfunc (configFile *ConfigFile) Save() (retErr error) {\n\tif configFile.Filename == \"\" {\n\t\treturn errors.Errorf(\"Can't save config with empty filename\")\n\t}\n\n\tdir := filepath.Dir(configFile.Filename)\n\tif err := os.MkdirAll(dir, 0o700); err != nil {\n\t\treturn err\n\t}\n\ttemp, err := os.CreateTemp(dir, filepath.Base(configFile.Filename))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\ttemp.Close()\n\t\tif retErr != nil {\n\t\t\tif err := os.Remove(temp.Name()); err != nil {\n\t\t\t\tlogrus.WithError(err).WithField(\"file\", temp.Name()).Debug(\"Error cleaning up temp file\")\n\t\t\t}\n\t\t}\n\t}()\n\n\terr = configFile.SaveToWriter(temp)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := temp.Close(); err != nil {\n\t\treturn errors.Wrap(err, \"error closing temp file\")\n\t}\n\n\t// Handle situation where the configfile is a symlink\n\tcfgFile := configFile.Filename\n\tif f, err := os.Readlink(cfgFile); err == nil {\n\t\tcfgFile = f\n\t}\n\n\t// Try copying the current config file (if any) ownership and permissions\n\tcopyFilePermissions(cfgFile, temp.Name())\n\treturn os.Rename(temp.Name(), cfgFile)\n}\n\n// ParseProxyConfig computes proxy configuration by retrieving the config for the provided host and\n// then checking this against any environment variables provided to the container\nfunc (configFile *ConfigFile) ParseProxyConfig(host string, runOpts map[string]*string) map[string]*string {\n\tvar cfgKey string\n\n\tif _, ok := configFile.Proxies[host]; !ok {\n\t\tcfgKey = \"default\"\n\t} else {\n\t\tcfgKey = host\n\t}\n\n\tconfig := configFile.Proxies[cfgKey]\n\tpermitted := map[string]*string{\n\t\t\"HTTP_PROXY\":  &config.HTTPProxy,\n\t\t\"HTTPS_PROXY\": &config.HTTPSProxy,\n\t\t\"NO_PROXY\":    &config.NoProxy,\n\t\t\"FTP_PROXY\":   &config.FTPProxy,\n\t\t\"ALL_PROXY\":   &config.AllProxy,\n\t}\n\tm := runOpts\n\tif m == nil {\n\t\tm = make(map[string]*string)\n\t}\n\tfor k := range permitted {\n\t\tif *permitted[k] == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif _, ok := m[k]; !ok {\n\t\t\tm[k] = permitted[k]\n\t\t}\n\t\tif _, ok := m[strings.ToLower(k)]; !ok {\n\t\t\tm[strings.ToLower(k)] = permitted[k]\n\t\t}\n\t}\n\treturn m\n}\n\n// encodeAuth creates a base64 encoded string to containing authorization information\nfunc encodeAuth(authConfig *types.AuthConfig) string {\n\tif authConfig.Username == \"\" && authConfig.Password == \"\" {\n\t\treturn \"\"\n\t}\n\n\tauthStr := authConfig.Username + \":\" + authConfig.Password\n\tmsg := []byte(authStr)\n\tencoded := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))\n\tbase64.StdEncoding.Encode(encoded, msg)\n\treturn string(encoded)\n}\n\n// decodeAuth decodes a base64 encoded string and returns username and password\nfunc decodeAuth(authStr string) (string, string, error) {\n\tif authStr == \"\" {\n\t\treturn \"\", \"\", nil\n\t}\n\n\tdecLen := base64.StdEncoding.DecodedLen(len(authStr))\n\tdecoded := make([]byte, decLen)\n\tauthByte := []byte(authStr)\n\tn, err := base64.StdEncoding.Decode(decoded, authByte)\n\tif err != nil {\n\t\treturn \"\", \"\", err\n\t}\n\tif n > decLen {\n\t\treturn \"\", \"\", errors.Errorf(\"Something went wrong decoding auth config\")\n\t}\n\tuserName, password, ok := strings.Cut(string(decoded), \":\")\n\tif !ok || userName == \"\" {\n\t\treturn \"\", \"\", errors.Errorf(\"Invalid auth configuration file\")\n\t}\n\treturn userName, strings.Trim(password, \"\\x00\"), nil\n}\n\n// GetCredentialsStore returns a new credentials store from the settings in the\n// configuration file\nfunc (configFile *ConfigFile) GetCredentialsStore(registryHostname string) credentials.Store {\n\tif helper := getConfiguredCredentialStore(configFile, registryHostname); helper != \"\" {\n\t\treturn newNativeStore(configFile, helper)\n\t}\n\treturn credentials.NewFileStore(configFile)\n}\n\n// var for unit testing.\nvar newNativeStore = func(configFile *ConfigFile, helperSuffix string) credentials.Store {\n\treturn credentials.NewNativeStore(configFile, helperSuffix)\n}\n\n// GetAuthConfig for a repository from the credential store\nfunc (configFile *ConfigFile) GetAuthConfig(registryHostname string) (types.AuthConfig, error) {\n\treturn configFile.GetCredentialsStore(registryHostname).Get(registryHostname)\n}\n\n// getConfiguredCredentialStore returns the credential helper configured for the\n// given registry, the default credsStore, or the empty string if neither are\n// configured.\nfunc getConfiguredCredentialStore(c *ConfigFile, registryHostname string) string {\n\tif c.CredentialHelpers != nil && registryHostname != \"\" {\n\t\tif helper, exists := c.CredentialHelpers[registryHostname]; exists {\n\t\t\treturn helper\n\t\t}\n\t}\n\treturn c.CredentialsStore\n}\n\n// GetAllCredentials returns all of the credentials stored in all of the\n// configured credential stores.\nfunc (configFile *ConfigFile) GetAllCredentials() (map[string]types.AuthConfig, error) {\n\tauths := make(map[string]types.AuthConfig)\n\taddAll := func(from map[string]types.AuthConfig) {\n\t\tfor reg, ac := range from {\n\t\t\tauths[reg] = ac\n\t\t}\n\t}\n\n\tdefaultStore := configFile.GetCredentialsStore(\"\")\n\tnewAuths, err := defaultStore.GetAll()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\taddAll(newAuths)\n\n\t// Auth configs from a registry-specific helper should override those from the default store.\n\tfor registryHostname := range configFile.CredentialHelpers {\n\t\tnewAuth, err := configFile.GetAuthConfig(registryHostname)\n\t\tif err != nil {\n\t\t\tlogrus.WithError(err).Warnf(\"Failed to get credentials for registry: %s\", registryHostname)\n\t\t\tcontinue\n\t\t}\n\t\tauths[registryHostname] = newAuth\n\t}\n\treturn auths, nil\n}\n\n// GetFilename returns the file name that this config file is based on.\nfunc (configFile *ConfigFile) GetFilename() string {\n\treturn configFile.Filename\n}\n\n// PluginConfig retrieves the requested option for the given plugin.\nfunc (configFile *ConfigFile) PluginConfig(pluginname, option string) (string, bool) {\n\tif configFile.Plugins == nil {\n\t\treturn \"\", false\n\t}\n\tpluginConfig, ok := configFile.Plugins[pluginname]\n\tif !ok {\n\t\treturn \"\", false\n\t}\n\tvalue, ok := pluginConfig[option]\n\treturn value, ok\n}\n\n// SetPluginConfig sets the option to the given value for the given\n// plugin. Passing a value of \"\" will remove the option. If removing\n// the final config item for a given plugin then also cleans up the\n// overall plugin entry.\nfunc (configFile *ConfigFile) SetPluginConfig(pluginname, option, value string) {\n\tif configFile.Plugins == nil {\n\t\tconfigFile.Plugins = make(map[string]map[string]string)\n\t}\n\tpluginConfig, ok := configFile.Plugins[pluginname]\n\tif !ok {\n\t\tpluginConfig = make(map[string]string)\n\t\tconfigFile.Plugins[pluginname] = pluginConfig\n\t}\n\tif value != \"\" {\n\t\tpluginConfig[option] = value\n\t} else {\n\t\tdelete(pluginConfig, option)\n\t}\n\tif len(pluginConfig) == 0 {\n\t\tdelete(configFile.Plugins, pluginname)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/configfile/file_unix.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage configfile\n\nimport (\n\t\"os\"\n\t\"syscall\"\n)\n\n// copyFilePermissions copies file ownership and permissions from \"src\" to \"dst\",\n// ignoring any error during the process.\nfunc copyFilePermissions(src, dst string) {\n\tvar (\n\t\tmode     os.FileMode = 0o600\n\t\tuid, gid int\n\t)\n\n\tfi, err := os.Stat(src)\n\tif err != nil {\n\t\treturn\n\t}\n\tif fi.Mode().IsRegular() {\n\t\tmode = fi.Mode()\n\t}\n\tif err := os.Chmod(dst, mode); err != nil {\n\t\treturn\n\t}\n\n\tuid = int(fi.Sys().(*syscall.Stat_t).Uid)\n\tgid = int(fi.Sys().(*syscall.Stat_t).Gid)\n\n\tif uid > 0 && gid > 0 {\n\t\t_ = os.Chown(dst, uid, gid)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/configfile/file_windows.go",
    "content": "package configfile\n\nfunc copyFilePermissions(src, dst string) {\n\t// TODO implement for Windows\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/credentials.go",
    "content": "package credentials\n\nimport (\n\t\"github.com/docker/cli/cli/config/types\"\n)\n\n// Store is the interface that any credentials store must implement.\ntype Store interface {\n\t// Erase removes credentials from the store for a given server.\n\tErase(serverAddress string) error\n\t// Get retrieves credentials from the store for a given server.\n\tGet(serverAddress string) (types.AuthConfig, error)\n\t// GetAll retrieves all the credentials from the store.\n\tGetAll() (map[string]types.AuthConfig, error)\n\t// Store saves credentials in the store.\n\tStore(authConfig types.AuthConfig) error\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/default_store.go",
    "content": "package credentials\n\nimport (\n\texec \"golang.org/x/sys/execabs\"\n)\n\n// DetectDefaultStore return the default credentials store for the platform if\n// the store executable is available.\nfunc DetectDefaultStore(store string) string {\n\tplatformDefault := defaultCredentialsStore()\n\n\t// user defined or no default for platform\n\tif store != \"\" || platformDefault == \"\" {\n\t\treturn store\n\t}\n\n\tif _, err := exec.LookPath(remoteCredentialsPrefix + platformDefault); err == nil {\n\t\treturn platformDefault\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/default_store_darwin.go",
    "content": "package credentials\n\nfunc defaultCredentialsStore() string {\n\treturn \"osxkeychain\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/default_store_linux.go",
    "content": "package credentials\n\nimport (\n\t\"os/exec\"\n)\n\nfunc defaultCredentialsStore() string {\n\tif _, err := exec.LookPath(\"pass\"); err == nil {\n\t\treturn \"pass\"\n\t}\n\n\treturn \"secretservice\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/default_store_unsupported.go",
    "content": "//go:build !windows && !darwin && !linux\n// +build !windows,!darwin,!linux\n\npackage credentials\n\nfunc defaultCredentialsStore() string {\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/default_store_windows.go",
    "content": "package credentials\n\nfunc defaultCredentialsStore() string {\n\treturn \"wincred\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/file_store.go",
    "content": "package credentials\n\nimport (\n\t\"strings\"\n\n\t\"github.com/docker/cli/cli/config/types\"\n)\n\ntype store interface {\n\tSave() error\n\tGetAuthConfigs() map[string]types.AuthConfig\n\tGetFilename() string\n}\n\n// fileStore implements a credentials store using\n// the docker configuration file to keep the credentials in plain text.\ntype fileStore struct {\n\tfile store\n}\n\n// NewFileStore creates a new file credentials store.\nfunc NewFileStore(file store) Store {\n\treturn &fileStore{file: file}\n}\n\n// Erase removes the given credentials from the file store.\nfunc (c *fileStore) Erase(serverAddress string) error {\n\tdelete(c.file.GetAuthConfigs(), serverAddress)\n\treturn c.file.Save()\n}\n\n// Get retrieves credentials for a specific server from the file store.\nfunc (c *fileStore) Get(serverAddress string) (types.AuthConfig, error) {\n\tauthConfig, ok := c.file.GetAuthConfigs()[serverAddress]\n\tif !ok {\n\t\t// Maybe they have a legacy config file, we will iterate the keys converting\n\t\t// them to the new format and testing\n\t\tfor r, ac := range c.file.GetAuthConfigs() {\n\t\t\tif serverAddress == ConvertToHostname(r) {\n\t\t\t\treturn ac, nil\n\t\t\t}\n\t\t}\n\n\t\tauthConfig = types.AuthConfig{}\n\t}\n\treturn authConfig, nil\n}\n\nfunc (c *fileStore) GetAll() (map[string]types.AuthConfig, error) {\n\treturn c.file.GetAuthConfigs(), nil\n}\n\n// Store saves the given credentials in the file store.\nfunc (c *fileStore) Store(authConfig types.AuthConfig) error {\n\tc.file.GetAuthConfigs()[authConfig.ServerAddress] = authConfig\n\treturn c.file.Save()\n}\n\nfunc (c *fileStore) GetFilename() string {\n\treturn c.file.GetFilename()\n}\n\nfunc (c *fileStore) IsFileStore() bool {\n\treturn true\n}\n\n// ConvertToHostname converts a registry url which has http|https prepended\n// to just an hostname.\n// Copied from github.com/docker/docker/registry.ConvertToHostname to reduce dependencies.\nfunc ConvertToHostname(url string) string {\n\tstripped := url\n\tif strings.HasPrefix(url, \"http://\") {\n\t\tstripped = strings.TrimPrefix(url, \"http://\")\n\t} else if strings.HasPrefix(url, \"https://\") {\n\t\tstripped = strings.TrimPrefix(url, \"https://\")\n\t}\n\n\thostName, _, _ := strings.Cut(stripped, \"/\")\n\treturn hostName\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/credentials/native_store.go",
    "content": "package credentials\n\nimport (\n\t\"github.com/docker/cli/cli/config/types\"\n\t\"github.com/docker/docker-credential-helpers/client\"\n\t\"github.com/docker/docker-credential-helpers/credentials\"\n)\n\nconst (\n\tremoteCredentialsPrefix = \"docker-credential-\" //nolint:gosec // ignore G101: Potential hardcoded credentials\n\ttokenUsername           = \"<token>\"\n)\n\n// nativeStore implements a credentials store\n// using native keychain to keep credentials secure.\n// It piggybacks into a file store to keep users' emails.\ntype nativeStore struct {\n\tprogramFunc client.ProgramFunc\n\tfileStore   Store\n}\n\n// NewNativeStore creates a new native store that\n// uses a remote helper program to manage credentials.\nfunc NewNativeStore(file store, helperSuffix string) Store {\n\tname := remoteCredentialsPrefix + helperSuffix\n\treturn &nativeStore{\n\t\tprogramFunc: client.NewShellProgramFunc(name),\n\t\tfileStore:   NewFileStore(file),\n\t}\n}\n\n// Erase removes the given credentials from the native store.\nfunc (c *nativeStore) Erase(serverAddress string) error {\n\tif err := client.Erase(c.programFunc, serverAddress); err != nil {\n\t\treturn err\n\t}\n\n\t// Fallback to plain text store to remove email\n\treturn c.fileStore.Erase(serverAddress)\n}\n\n// Get retrieves credentials for a specific server from the native store.\nfunc (c *nativeStore) Get(serverAddress string) (types.AuthConfig, error) {\n\t// load user email if it exist or an empty auth config.\n\tauth, _ := c.fileStore.Get(serverAddress)\n\n\tcreds, err := c.getCredentialsFromStore(serverAddress)\n\tif err != nil {\n\t\treturn auth, err\n\t}\n\tauth.Username = creds.Username\n\tauth.IdentityToken = creds.IdentityToken\n\tauth.Password = creds.Password\n\n\treturn auth, nil\n}\n\n// GetAll retrieves all the credentials from the native store.\nfunc (c *nativeStore) GetAll() (map[string]types.AuthConfig, error) {\n\tauths, err := c.listCredentialsInStore()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Emails are only stored in the file store.\n\t// This call can be safely eliminated when emails are removed.\n\tfileConfigs, _ := c.fileStore.GetAll()\n\n\tauthConfigs := make(map[string]types.AuthConfig)\n\tfor registry := range auths {\n\t\tcreds, err := c.getCredentialsFromStore(registry)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tac := fileConfigs[registry] // might contain Email\n\t\tac.Username = creds.Username\n\t\tac.Password = creds.Password\n\t\tac.IdentityToken = creds.IdentityToken\n\t\tauthConfigs[registry] = ac\n\t}\n\n\treturn authConfigs, nil\n}\n\n// Store saves the given credentials in the file store.\nfunc (c *nativeStore) Store(authConfig types.AuthConfig) error {\n\tif err := c.storeCredentialsInStore(authConfig); err != nil {\n\t\treturn err\n\t}\n\tauthConfig.Username = \"\"\n\tauthConfig.Password = \"\"\n\tauthConfig.IdentityToken = \"\"\n\n\t// Fallback to old credential in plain text to save only the email\n\treturn c.fileStore.Store(authConfig)\n}\n\n// storeCredentialsInStore executes the command to store the credentials in the native store.\nfunc (c *nativeStore) storeCredentialsInStore(config types.AuthConfig) error {\n\tcreds := &credentials.Credentials{\n\t\tServerURL: config.ServerAddress,\n\t\tUsername:  config.Username,\n\t\tSecret:    config.Password,\n\t}\n\n\tif config.IdentityToken != \"\" {\n\t\tcreds.Username = tokenUsername\n\t\tcreds.Secret = config.IdentityToken\n\t}\n\n\treturn client.Store(c.programFunc, creds)\n}\n\n// getCredentialsFromStore executes the command to get the credentials from the native store.\nfunc (c *nativeStore) getCredentialsFromStore(serverAddress string) (types.AuthConfig, error) {\n\tvar ret types.AuthConfig\n\n\tcreds, err := client.Get(c.programFunc, serverAddress)\n\tif err != nil {\n\t\tif credentials.IsErrCredentialsNotFound(err) {\n\t\t\t// do not return an error if the credentials are not\n\t\t\t// in the keychain. Let docker ask for new credentials.\n\t\t\treturn ret, nil\n\t\t}\n\t\treturn ret, err\n\t}\n\n\tif creds.Username == tokenUsername {\n\t\tret.IdentityToken = creds.Secret\n\t} else {\n\t\tret.Password = creds.Secret\n\t\tret.Username = creds.Username\n\t}\n\n\tret.ServerAddress = serverAddress\n\treturn ret, nil\n}\n\n// listCredentialsInStore returns a listing of stored credentials as a map of\n// URL -> username.\nfunc (c *nativeStore) listCredentialsInStore() (map[string]string, error) {\n\treturn client.List(c.programFunc)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/cli/cli/config/types/authconfig.go",
    "content": "package types\n\n// AuthConfig contains authorization information for connecting to a Registry\ntype AuthConfig struct {\n\tUsername string `json:\"username,omitempty\"`\n\tPassword string `json:\"password,omitempty\"`\n\tAuth     string `json:\"auth,omitempty\"`\n\n\t// Email is an optional value associated with the username.\n\t// This field is deprecated and will be removed in a later\n\t// version of docker.\n\tEmail string `json:\"email,omitempty\"`\n\n\tServerAddress string `json:\"serveraddress,omitempty\"`\n\n\t// IdentityToken is used to authenticate the user and get\n\t// an access token for the registry.\n\tIdentityToken string `json:\"identitytoken,omitempty\"`\n\n\t// RegistryToken is a bearer token to be sent to a registry\n\tRegistryToken string `json:\"registrytoken,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/distribution/LICENSE",
    "content": "Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\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       http://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\n"
  },
  {
    "path": "vendor/github.com/docker/distribution/registry/client/auth/challenge/addr.go",
    "content": "package challenge\n\nimport (\n\t\"net/url\"\n\t\"strings\"\n)\n\n// FROM: https://golang.org/src/net/http/http.go\n// Given a string of the form \"host\", \"host:port\", or \"[ipv6::address]:port\",\n// return true if the string includes a port.\nfunc hasPort(s string) bool { return strings.LastIndex(s, \":\") > strings.LastIndex(s, \"]\") }\n\n// FROM: http://golang.org/src/net/http/transport.go\nvar portMap = map[string]string{\n\t\"http\":  \"80\",\n\t\"https\": \"443\",\n}\n\n// canonicalAddr returns url.Host but always with a \":port\" suffix\n// FROM: http://golang.org/src/net/http/transport.go\nfunc canonicalAddr(url *url.URL) string {\n\taddr := url.Host\n\tif !hasPort(addr) {\n\t\treturn addr + \":\" + portMap[url.Scheme]\n\t}\n\treturn addr\n}\n"
  },
  {
    "path": "vendor/github.com/docker/distribution/registry/client/auth/challenge/authchallenge.go",
    "content": "package challenge\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// Challenge carries information from a WWW-Authenticate response header.\n// See RFC 2617.\ntype Challenge struct {\n\t// Scheme is the auth-scheme according to RFC 2617\n\tScheme string\n\n\t// Parameters are the auth-params according to RFC 2617\n\tParameters map[string]string\n}\n\n// Manager manages the challenges for endpoints.\n// The challenges are pulled out of HTTP responses. Only\n// responses which expect challenges should be added to\n// the manager, since a non-unauthorized request will be\n// viewed as not requiring challenges.\ntype Manager interface {\n\t// GetChallenges returns the challenges for the given\n\t// endpoint URL.\n\tGetChallenges(endpoint url.URL) ([]Challenge, error)\n\n\t// AddResponse adds the response to the challenge\n\t// manager. The challenges will be parsed out of\n\t// the WWW-Authenicate headers and added to the\n\t// URL which was produced the response. If the\n\t// response was authorized, any challenges for the\n\t// endpoint will be cleared.\n\tAddResponse(resp *http.Response) error\n}\n\n// NewSimpleManager returns an instance of\n// Manger which only maps endpoints to challenges\n// based on the responses which have been added the\n// manager. The simple manager will make no attempt to\n// perform requests on the endpoints or cache the responses\n// to a backend.\nfunc NewSimpleManager() Manager {\n\treturn &simpleManager{\n\t\tChallenges: make(map[string][]Challenge),\n\t}\n}\n\ntype simpleManager struct {\n\tsync.RWMutex\n\tChallenges map[string][]Challenge\n}\n\nfunc normalizeURL(endpoint *url.URL) {\n\tendpoint.Host = strings.ToLower(endpoint.Host)\n\tendpoint.Host = canonicalAddr(endpoint)\n}\n\nfunc (m *simpleManager) GetChallenges(endpoint url.URL) ([]Challenge, error) {\n\tnormalizeURL(&endpoint)\n\n\tm.RLock()\n\tdefer m.RUnlock()\n\tchallenges := m.Challenges[endpoint.String()]\n\treturn challenges, nil\n}\n\nfunc (m *simpleManager) AddResponse(resp *http.Response) error {\n\tchallenges := ResponseChallenges(resp)\n\tif resp.Request == nil {\n\t\treturn fmt.Errorf(\"missing request reference\")\n\t}\n\turlCopy := url.URL{\n\t\tPath:   resp.Request.URL.Path,\n\t\tHost:   resp.Request.URL.Host,\n\t\tScheme: resp.Request.URL.Scheme,\n\t}\n\tnormalizeURL(&urlCopy)\n\n\tm.Lock()\n\tdefer m.Unlock()\n\tm.Challenges[urlCopy.String()] = challenges\n\treturn nil\n}\n\n// Octet types from RFC 2616.\ntype octetType byte\n\nvar octetTypes [256]octetType\n\nconst (\n\tisToken octetType = 1 << iota\n\tisSpace\n)\n\nfunc init() {\n\t// OCTET      = <any 8-bit sequence of data>\n\t// CHAR       = <any US-ASCII character (octets 0 - 127)>\n\t// CTL        = <any US-ASCII control character (octets 0 - 31) and DEL (127)>\n\t// CR         = <US-ASCII CR, carriage return (13)>\n\t// LF         = <US-ASCII LF, linefeed (10)>\n\t// SP         = <US-ASCII SP, space (32)>\n\t// HT         = <US-ASCII HT, horizontal-tab (9)>\n\t// <\">        = <US-ASCII double-quote mark (34)>\n\t// CRLF       = CR LF\n\t// LWS        = [CRLF] 1*( SP | HT )\n\t// TEXT       = <any OCTET except CTLs, but including LWS>\n\t// separators = \"(\" | \")\" | \"<\" | \">\" | \"@\" | \",\" | \";\" | \":\" | \"\\\" | <\">\n\t//              | \"/\" | \"[\" | \"]\" | \"?\" | \"=\" | \"{\" | \"}\" | SP | HT\n\t// token      = 1*<any CHAR except CTLs or separators>\n\t// qdtext     = <any TEXT except <\">>\n\n\tfor c := 0; c < 256; c++ {\n\t\tvar t octetType\n\t\tisCtl := c <= 31 || c == 127\n\t\tisChar := 0 <= c && c <= 127\n\t\tisSeparator := strings.ContainsRune(\" \\t\\\"(),/:;<=>?@[]\\\\{}\", rune(c))\n\t\tif strings.ContainsRune(\" \\t\\r\\n\", rune(c)) {\n\t\t\tt |= isSpace\n\t\t}\n\t\tif isChar && !isCtl && !isSeparator {\n\t\t\tt |= isToken\n\t\t}\n\t\toctetTypes[c] = t\n\t}\n}\n\n// ResponseChallenges returns a list of authorization challenges\n// for the given http Response. Challenges are only checked if\n// the response status code was a 401.\nfunc ResponseChallenges(resp *http.Response) []Challenge {\n\tif resp.StatusCode == http.StatusUnauthorized {\n\t\t// Parse the WWW-Authenticate Header and store the challenges\n\t\t// on this endpoint object.\n\t\treturn parseAuthHeader(resp.Header)\n\t}\n\n\treturn nil\n}\n\nfunc parseAuthHeader(header http.Header) []Challenge {\n\tchallenges := []Challenge{}\n\tfor _, h := range header[http.CanonicalHeaderKey(\"WWW-Authenticate\")] {\n\t\tv, p := parseValueAndParams(h)\n\t\tif v != \"\" {\n\t\t\tchallenges = append(challenges, Challenge{Scheme: v, Parameters: p})\n\t\t}\n\t}\n\treturn challenges\n}\n\nfunc parseValueAndParams(header string) (value string, params map[string]string) {\n\tparams = make(map[string]string)\n\tvalue, s := expectToken(header)\n\tif value == \"\" {\n\t\treturn\n\t}\n\tvalue = strings.ToLower(value)\n\ts = \",\" + skipSpace(s)\n\tfor strings.HasPrefix(s, \",\") {\n\t\tvar pkey string\n\t\tpkey, s = expectToken(skipSpace(s[1:]))\n\t\tif pkey == \"\" {\n\t\t\treturn\n\t\t}\n\t\tif !strings.HasPrefix(s, \"=\") {\n\t\t\treturn\n\t\t}\n\t\tvar pvalue string\n\t\tpvalue, s = expectTokenOrQuoted(s[1:])\n\t\tif pvalue == \"\" {\n\t\t\treturn\n\t\t}\n\t\tpkey = strings.ToLower(pkey)\n\t\tparams[pkey] = pvalue\n\t\ts = skipSpace(s)\n\t}\n\treturn\n}\n\nfunc skipSpace(s string) (rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif octetTypes[s[i]]&isSpace == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[i:]\n}\n\nfunc expectToken(s string) (token, rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif octetTypes[s[i]]&isToken == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[:i], s[i:]\n}\n\nfunc expectTokenOrQuoted(s string) (value string, rest string) {\n\tif !strings.HasPrefix(s, \"\\\"\") {\n\t\treturn expectToken(s)\n\t}\n\ts = s[1:]\n\tfor i := 0; i < len(s); i++ {\n\t\tswitch s[i] {\n\t\tcase '\"':\n\t\t\treturn s[:i], s[i+1:]\n\t\tcase '\\\\':\n\t\t\tp := make([]byte, len(s)-1)\n\t\t\tj := copy(p, s[:i])\n\t\t\tescape := true\n\t\t\tfor i = i + 1; i < len(s); i++ {\n\t\t\t\tb := s[i]\n\t\t\t\tswitch {\n\t\t\t\tcase escape:\n\t\t\t\t\tescape = false\n\t\t\t\t\tp[j] = b\n\t\t\t\t\tj++\n\t\t\t\tcase b == '\\\\':\n\t\t\t\t\tescape = true\n\t\t\t\tcase b == '\"':\n\t\t\t\t\treturn string(p[:j]), s[i+1:]\n\t\t\t\tdefault:\n\t\t\t\t\tp[j] = b\n\t\t\t\t\tj++\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn \"\", \"\"\n\t\t}\n\t}\n\treturn \"\", \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/AUTHORS",
    "content": "# File @generated by hack/generate-authors.sh. DO NOT EDIT.\n# This file lists all contributors to the repository.\n# See hack/generate-authors.sh to make modifications.\n\nAanand Prasad <aanand.prasad@gmail.com>\nAaron Davidson <aaron@databricks.com>\nAaron Feng <aaron.feng@gmail.com>\nAaron Hnatiw <aaron@griddio.com>\nAaron Huslage <huslage@gmail.com>\nAaron L. Xu <liker.xu@foxmail.com>\nAaron Lehmann <alehmann@netflix.com>\nAaron Welch <welch@packet.net>\nAbel Muiño <amuino@gmail.com>\nAbhijeet Kasurde <akasurde@redhat.com>\nAbhinandan Prativadi <aprativadi@gmail.com>\nAbhinav Ajgaonkar <abhinav316@gmail.com>\nAbhishek Chanda <abhishek.becs@gmail.com>\nAbhishek Sharma <abhishek@asharma.me>\nAbin Shahab <ashahab@altiscale.com>\nAbirdcfly <fp544037857@gmail.com>\nAda Mancini <ada@docker.com>\nAdam Avilla <aavilla@yp.com>\nAdam Dobrawy <naczelnik@jawnosc.tk>\nAdam Eijdenberg <adam.eijdenberg@gmail.com>\nAdam Kunk <adam.kunk@tiaa-cref.org>\nAdam Miller <admiller@redhat.com>\nAdam Mills <adam@armills.info>\nAdam Pointer <adam.pointer@skybettingandgaming.com>\nAdam Singer <financeCoding@gmail.com>\nAdam Thornton <adam.thornton@maryville.com>\nAdam Walz <adam@adamwalz.net>\nAdam Williams <awilliams@mirantis.com>\nAdamKorcz <adam@adalogics.com>\nAddam Hardy <addam.hardy@gmail.com>\nAditi Rajagopal <arajagopal@us.ibm.com>\nAditya <aditya@netroy.in>\nAdnan Khan <adnkha@amazon.com>\nAdolfo Ochagavía <aochagavia92@gmail.com>\nAdria Casas <adriacasas88@gmail.com>\nAdrian Moisey <adrian@changeover.za.net>\nAdrian Mouat <adrian.mouat@gmail.com>\nAdrian Oprea <adrian@codesi.nz>\nAdrien Folie <folie.adrien@gmail.com>\nAdrien Gallouët <adrien@gallouet.fr>\nAhmed Kamal <email.ahmedkamal@googlemail.com>\nAhmet Alp Balkan <ahmetb@microsoft.com>\nAidan Feldman <aidan.feldman@gmail.com>\nAidan Hobson Sayers <aidanhs@cantab.net>\nAJ Bowen <aj@soulshake.net>\nAjey Charantimath <ajey.charantimath@gmail.com>\najneu <ajneu@users.noreply.github.com>\nAkash Gupta <akagup@microsoft.com>\nAkhil Mohan <akhil.mohan@mayadata.io>\nAkihiro Matsushima <amatsusbit@gmail.com>\nAkihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>\nAkim Demaille <akim.demaille@docker.com>\nAkira Koyasu <mail@akirakoyasu.net>\nAkshay Karle <akshay.a.karle@gmail.com>\nAkshay Moghe <akshay.moghe@gmail.com>\nAl Tobey <al@ooyala.com>\nalambike <alambike@gmail.com>\nAlan Hoyle <alan@alanhoyle.com>\nAlan Scherger <flyinprogrammer@gmail.com>\nAlan Thompson <cloojure@gmail.com>\nAlbert Callarisa <shark234@gmail.com>\nAlbert Zhang <zhgwenming@gmail.com>\nAlbin Kerouanton <albinker@gmail.com>\nAlec Benson <albenson@redhat.com>\nAlejandro González Hevia <alejandrgh11@gmail.com>\nAleksa Sarai <asarai@suse.de>\nAleksandr Chebotov <v-aleche@microsoft.com>\nAleksandrs Fadins <aleks@s-ko.net>\nAlena Prokharchyk <alena@rancher.com>\nAlessandro Boch <aboch@tetrationanalytics.com>\nAlessio Biancalana <dottorblaster@gmail.com>\nAlex Chan <alex@alexwlchan.net>\nAlex Chen <alexchenunix@gmail.com>\nAlex Coventry <alx@empirical.com>\nAlex Crawford <alex.crawford@coreos.com>\nAlex Ellis <alexellis2@gmail.com>\nAlex Gaynor <alex.gaynor@gmail.com>\nAlex Goodman <wagoodman@gmail.com>\nAlex Nordlund <alexander.nordlund@nasdaq.com>\nAlex Olshansky <i@creagenics.com>\nAlex Samorukov <samm@os2.kiev.ua>\nAlex Stockinger <alex@atomicjar.com>\nAlex Warhawk <ax.warhawk@gmail.com>\nAlexander Artemenko <svetlyak.40wt@gmail.com>\nAlexander Boyd <alex@opengroove.org>\nAlexander Larsson <alexl@redhat.com>\nAlexander Midlash <amidlash@docker.com>\nAlexander Morozov <lk4d4math@gmail.com>\nAlexander Polakov <plhk@sdf.org>\nAlexander Shopov <ash@kambanaria.org>\nAlexandre Beslic <alexandre.beslic@gmail.com>\nAlexandre Garnier <zigarn@gmail.com>\nAlexandre González <agonzalezro@gmail.com>\nAlexandre Jomin <alexandrejomin@gmail.com>\nAlexandru Sfirlogea <alexandru.sfirlogea@gmail.com>\nAlexei Margasov <alexei38@yandex.ru>\nAlexey Guskov <lexag@mail.ru>\nAlexey Kotlyarov <alexey@infoxchange.net.au>\nAlexey Shamrin <shamrin@gmail.com>\nAlexis Ries <ries.alexis@gmail.com>\nAlexis Thomas <fr.alexisthomas@gmail.com>\nAlfred Landrum <alfred.landrum@docker.com>\nAli Dehghani <ali.dehghani.g@gmail.com>\nAlicia Lauerman <alicia@eta.im>\nAlihan Demir <alihan_6153@hotmail.com>\nAllen Madsen <blatyo@gmail.com>\nAllen Sun <allensun.shl@alibaba-inc.com>\nalmoehi <almoehi@users.noreply.github.com>\nAlvaro Saurin <alvaro.saurin@gmail.com>\nAlvin Deng <alvin.q.deng@utexas.edu>\nAlvin Richards <alvin.richards@docker.com>\namangoel <amangoel@gmail.com>\nAmen Belayneh <amenbelayneh@gmail.com>\nAmeya Gawde <agawde@mirantis.com>\nAmir Goldstein <amir73il@aquasec.com>\nAmit Bakshi <ambakshi@gmail.com>\nAmit Krishnan <amit.krishnan@oracle.com>\nAmit Shukla <amit.shukla@docker.com>\nAmr Gawish <amr.gawish@gmail.com>\nAmy Lindburg <amy.lindburg@docker.com>\nAnand Patil <anand.prabhakar.patil@gmail.com>\nAnandkumarPatel <anandkumarpatel@gmail.com>\nAnatoly Borodin <anatoly.borodin@gmail.com>\nAnca Iordache <anca.iordache@docker.com>\nAnchal Agrawal <aagrawa4@illinois.edu>\nAnda Xu <anda.xu@docker.com>\nAnders Janmyr <anders@janmyr.com>\nAndre Dublin <81dublin@gmail.com>\nAndre Granovsky <robotciti@live.com>\nAndrea Denisse Gómez <crypto.andrea@protonmail.ch>\nAndrea Luzzardi <aluzzardi@gmail.com>\nAndrea Turli <andrea.turli@gmail.com>\nAndreas Elvers <andreas@work.de>\nAndreas Köhler <andi5.py@gmx.net>\nAndreas Savvides <andreas@editd.com>\nAndreas Tiefenthaler <at@an-ti.eu>\nAndrei Gherzan <andrei@resin.io>\nAndrei Ushakov <aushakov@netflix.com>\nAndrei Vagin <avagin@gmail.com>\nAndrew C. Bodine <acbodine@us.ibm.com>\nAndrew Clay Shafer <andrewcshafer@gmail.com>\nAndrew Duckworth <grillopress@gmail.com>\nAndrew France <andrew@avito.co.uk>\nAndrew Gerrand <adg@golang.org>\nAndrew Guenther <guenther.andrew.j@gmail.com>\nAndrew He <he.andrew.mail@gmail.com>\nAndrew Hsu <andrewhsu@docker.com>\nAndrew Kim <taeyeonkim90@gmail.com>\nAndrew Kuklewicz <kookster@gmail.com>\nAndrew Macgregor <andrew.macgregor@agworld.com.au>\nAndrew Macpherson <hopscotch23@gmail.com>\nAndrew Martin <sublimino@gmail.com>\nAndrew McDonnell <bugs@andrewmcdonnell.net>\nAndrew Munsell <andrew@wizardapps.net>\nAndrew Pennebaker <andrew.pennebaker@gmail.com>\nAndrew Po <absourd.noise@gmail.com>\nAndrew Weiss <andrew.weiss@docker.com>\nAndrew Williams <williams.andrew@gmail.com>\nAndrews Medina <andrewsmedina@gmail.com>\nAndrey Kolomentsev <andrey.kolomentsev@docker.com>\nAndrey Petrov <andrey.petrov@shazow.net>\nAndrey Stolbovsky <andrey.stolbovsky@gmail.com>\nAndré Martins <aanm90@gmail.com>\nAndy Chambers <anchambers@paypal.com>\nandy diller <dillera@gmail.com>\nAndy Goldstein <agoldste@redhat.com>\nAndy Kipp <andy@rstudio.com>\nAndy Lindeman <alindeman@salesforce.com>\nAndy Rothfusz <github@developersupport.net>\nAndy Smith <github@anarkystic.com>\nAndy Wilson <wilson.andrew.j+github@gmail.com>\nAndy Zhang <andy.zhangtao@hotmail.com>\nAneesh Kulkarni <askthefactorcamera@gmail.com>\nAnes Hasicic <anes.hasicic@gmail.com>\nAngel Velazquez <angelcar@amazon.com>\nAnil Belur <askb23@gmail.com>\nAnil Madhavapeddy <anil@recoil.org>\nAnkit Jain <ajatkj@yahoo.co.in>\nAnkush Agarwal <ankushagarwal11@gmail.com>\nAnonmily <michelle@michelleliu.io>\nAnran Qiao <anran.qiao@daocloud.io>\nAnshul Pundir <anshul.pundir@docker.com>\nAnthon van der Neut <anthon@mnt.org>\nAnthony Baire <Anthony.Baire@irisa.fr>\nAnthony Bishopric <git@anthonybishopric.com>\nAnthony Dahanne <anthony.dahanne@gmail.com>\nAnthony Sottile <asottile@umich.edu>\nAnton Löfgren <anton.lofgren@gmail.com>\nAnton Nikitin <anton.k.nikitin@gmail.com>\nAnton Polonskiy <anton.polonskiy@gmail.com>\nAnton Tiurin <noxiouz@yandex.ru>\nAntonio Murdaca <antonio.murdaca@gmail.com>\nAntonis Kalipetis <akalipetis@gmail.com>\nAntony Messerli <amesserl@rackspace.com>\nAnuj Bahuguna <anujbahuguna.dev@gmail.com>\nAnuj Varma <anujvarma@thumbtack.com>\nAnusha Ragunathan <anusha.ragunathan@docker.com>\nAnyu Wang <wanganyu@outlook.com>\napocas <petermdias@gmail.com>\nArash Deshmeh <adeshmeh@ca.ibm.com>\narcosx <arcosx@outlook.com>\nArikaChen <eaglesora@gmail.com>\nArko Dasgupta <arko@tetrate.io>\nArnaud Lefebvre <a.lefebvre@outlook.fr>\nArnaud Porterie <icecrime@gmail.com>\nArnaud Rebillout <arnaud.rebillout@collabora.com>\nArtem Khramov <akhramov@pm.me>\nArthur Barr <arthur.barr@uk.ibm.com>\nArthur Gautier <baloo@gandi.net>\nArtur Meyster <arthurfbi@yahoo.com>\nArun Gupta <arun.gupta@gmail.com>\nAsad Saeeduddin <masaeedu@gmail.com>\nAsbjørn Enge <asbjorn@hanafjedle.net>\nAustin Vazquez <macedonv@amazon.com>\naveragehuman <averagehuman@users.noreply.github.com>\nAvi Das <andas222@gmail.com>\nAvi Kivity <avi@scylladb.com>\nAvi Miller <avi.miller@oracle.com>\nAvi Vaid <avaid1996@gmail.com>\nayoshitake <airandfingers@gmail.com>\nAzat Khuyiyakhmetov <shadow_uz@mail.ru>\nBao Yonglei <baoyonglei@huawei.com>\nBardia Keyoumarsi <bkeyouma@ucsc.edu>\nBarnaby Gray <barnaby@pickle.me.uk>\nBarry Allard <barry.allard@gmail.com>\nBartłomiej Piotrowski <b@bpiotrowski.pl>\nBastiaan Bakker <bbakker@xebia.com>\nBastien Pascard <bpascard@hotmail.com>\nbdevloed <boris.de.vloed@gmail.com>\nBearice Ren <bearice@gmail.com>\nBen Bonnefoy <frenchben@docker.com>\nBen Firshman <ben@firshman.co.uk>\nBen Golub <ben.golub@dotcloud.com>\nBen Gould <ben@bengould.co.uk>\nBen Hall <ben@benhall.me.uk>\nBen Langfeld <ben@langfeld.me>\nBen Lovy <ben@deciduously.com>\nBen Sargent <ben@brokendigits.com>\nBen Severson <BenSeverson@users.noreply.github.com>\nBen Toews <mastahyeti@gmail.com>\nBen Wiklund <ben@daisyowl.com>\nBenjamin Atkin <ben@benatkin.com>\nBenjamin Baker <Benjamin.baker@utexas.edu>\nBenjamin Boudreau <boudreau.benjamin@gmail.com>\nBenjamin Böhmke <benjamin@boehmke.net>\nBenjamin Wang <wachao@vmware.com>\nBenjamin Yolken <yolken@stripe.com>\nBenny Ng <benny.tpng@gmail.com>\nBenoit Chesneau <bchesneau@gmail.com>\nBernerd Schaefer <bj.schaefer@gmail.com>\nBernhard M. Wiedemann <bwiedemann@suse.de>\nBert Goethals <bert@bertg.be>\nBertrand Roussel <broussel@sierrawireless.com>\nBevisy Zhang <binbin36520@gmail.com>\nBharath Thiruveedula <bharath_ves@hotmail.com>\nBhiraj Butala <abhiraj.butala@gmail.com>\nBhumika Bayani <bhumikabayani@gmail.com>\nBilal Amarni <bilal.amarni@gmail.com>\nBill Wang <ozbillwang@gmail.com>\nBilly Ridgway <wrridgwa@us.ibm.com>\nBily Zhang <xcoder@tenxcloud.com>\nBin Liu <liubin0329@gmail.com>\nBingshen Wang <bingshen.wbs@alibaba-inc.com>\nBjorn Neergaard <bjorn@neersighted.com>\nBlake Geno <blakegeno@gmail.com>\nBoaz Shuster <ripcurld.github@gmail.com>\nbobby abbott <ttobbaybbob@gmail.com>\nBojun Zhu <bojun.zhu@foxmail.com>\nBoqin Qin <bobbqqin@gmail.com>\nBoris Pruessmann <boris@pruessmann.org>\nBoshi Lian <farmer1992@gmail.com>\nBouke Haarsma <bouke@webatoom.nl>\nBoyd Hemphill <boyd@feedmagnet.com>\nboynux <boynux@gmail.com>\nBradley Cicenas <bradley.cicenas@gmail.com>\nBradley Wright <brad@intranation.com>\nBrandon Liu <bdon@bdon.org>\nBrandon Philips <brandon.philips@coreos.com>\nBrandon Rhodes <brandon@rhodesmill.org>\nBrendan Dixon <brendand@microsoft.com>\nBrennan Kinney <5098581+polarathene@users.noreply.github.com>\nBrent Salisbury <brent.salisbury@docker.com>\nBrett Higgins <brhiggins@arbor.net>\nBrett Kochendorfer <brett.kochendorfer@gmail.com>\nBrett Milford <brettmilford@gmail.com>\nBrett Randall <javabrett@gmail.com>\nBrian (bex) Exelbierd <bexelbie@redhat.com>\nBrian Bland <brian.bland@docker.com>\nBrian DeHamer <brian@dehamer.com>\nBrian Dorsey <brian@dorseys.org>\nBrian Flad <bflad417@gmail.com>\nBrian Goff <cpuguy83@gmail.com>\nBrian McCallister <brianm@skife.org>\nBrian Olsen <brian@maven-group.org>\nBrian Schwind <brianmschwind@gmail.com>\nBrian Shumate <brian@couchbase.com>\nBrian Torres-Gil <brian@dralth.com>\nBrian Trump <btrump@yelp.com>\nBrice Jaglin <bjaglin@teads.tv>\nBriehan Lombaard <briehan.lombaard@gmail.com>\nBrielle Broder <bbroder@google.com>\nBruno Bigras <bigras.bruno@gmail.com>\nBruno Binet <bruno.binet@gmail.com>\nBruno Gazzera <bgazzera@paginar.com>\nBruno Renié <brutasse@gmail.com>\nBruno Tavares <btavare@thoughtworks.com>\nBryan Bess <squarejaw@bsbess.com>\nBryan Boreham <bjboreham@gmail.com>\nBryan Matsuo <bryan.matsuo@gmail.com>\nBryan Murphy <bmurphy1976@gmail.com>\nBurke Libbey <burke@libbey.me>\nByung Kang <byung.kang.ctr@amrdec.army.mil>\nCaleb Spare <cespare@gmail.com>\nCalen Pennington <cale@edx.org>\nCameron Boehmer <cameron.boehmer@gmail.com>\nCameron Sparr <gh@sparr.email>\nCameron Spear <cameronspear@gmail.com>\nCampbell Allen <campbell.allen@gmail.com>\nCandid Dauth <cdauth@cdauth.eu>\nCao Weiwei <cao.weiwei30@zte.com.cn>\nCarl Henrik Lunde <chlunde@ping.uio.no>\nCarl Loa Odin <carlodin@gmail.com>\nCarl X. Su <bcbcarl@gmail.com>\nCarlo Mion <mion00@gmail.com>\nCarlos Alexandro Becker <caarlos0@gmail.com>\nCarlos de Paula <me@carlosedp.com>\nCarlos Sanchez <carlos@apache.org>\nCarol Fager-Higgins <carol.fager-higgins@docker.com>\nCary <caryhartline@users.noreply.github.com>\nCasey Bisson <casey.bisson@joyent.com>\nCatalin Pirvu <pirvu.catalin94@gmail.com>\nCe Gao <ce.gao@outlook.com>\nCedric Davies <cedricda@microsoft.com>\nCezar Sa Espinola <cezarsa@gmail.com>\nChad Swenson <chadswen@gmail.com>\nChance Zibolski <chance.zibolski@gmail.com>\nChander Govindarajan <chandergovind@gmail.com>\nChanhun Jeong <keyolk@gmail.com>\nChao Wang <wangchao.fnst@cn.fujitsu.com>\nCharles Chan <charleswhchan@users.noreply.github.com>\nCharles Hooper <charles.hooper@dotcloud.com>\nCharles Law <claw@conduce.com>\nCharles Lindsay <chaz@chazomatic.us>\nCharles Merriam <charles.merriam@gmail.com>\nCharles Sarrazin <charles@sarraz.in>\nCharles Smith <charles.smith@docker.com>\nCharlie Drage <charlie@charliedrage.com>\nCharlie Lewis <charliel@lab41.org>\nChase Bolt <chase.bolt@gmail.com>\nChaYoung You <yousbe@gmail.com>\nChee Hau Lim <ch33hau@gmail.com>\nChen Chao <cc272309126@gmail.com>\nChen Chuanliang <chen.chuanliang@zte.com.cn>\nChen Hanxiao <chenhanxiao@cn.fujitsu.com>\nChen Min <chenmin46@huawei.com>\nChen Mingjie <chenmingjie0828@163.com>\nChen Qiu <cheney-90@hotmail.com>\nCheng-mean Liu <soccerl@microsoft.com>\nChengfei Shang <cfshang@alauda.io>\nChengguang Xu <cgxu519@gmx.com>\nChenyang Yan <memory.yancy@gmail.com>\nchenyuzhu <chenyuzhi@oschina.cn>\nChetan Birajdar <birajdar.chetan@gmail.com>\nChewey <prosto-chewey@users.noreply.github.com>\nChia-liang Kao <clkao@clkao.org>\nChiranjeevi Tirunagari <vchiranjeeviak.tirunagari@gmail.com>\nchli <chli@freewheel.tv>\nCholerae Hu <choleraehyq@gmail.com>\nChris Alfonso <calfonso@redhat.com>\nChris Armstrong <chris@opdemand.com>\nChris Dias <cdias@microsoft.com>\nChris Dituri <csdituri@gmail.com>\nChris Fordham <chris@fordham-nagy.id.au>\nChris Gavin <chris@chrisgavin.me>\nChris Gibson <chris@chrisg.io>\nChris Khoo <chris.khoo@gmail.com>\nChris Kreussling (Flatbush Gardener) <xrisfg@gmail.com>\nChris McKinnel <chris.mckinnel@tangentlabs.co.uk>\nChris McKinnel <chrismckinnel@gmail.com>\nChris Price <cprice@mirantis.com>\nChris Seto <chriskseto@gmail.com>\nChris Snow <chsnow123@gmail.com>\nChris St. Pierre <chris.a.st.pierre@gmail.com>\nChris Stivers <chris@stivers.us>\nChris Swan <chris.swan@iee.org>\nChris Telfer <ctelfer@docker.com>\nChris Wahl <github@wahlnetwork.com>\nChris Weyl <cweyl@alumni.drew.edu>\nChris White <me@cwprogram.com>\nChristian Becker <christian.becker@sixt.com>\nChristian Berendt <berendt@b1-systems.de>\nChristian Brauner <christian.brauner@ubuntu.com>\nChristian Böhme <developement@boehme3d.de>\nChristian Muehlhaeuser <muesli@gmail.com>\nChristian Persson <saser@live.se>\nChristian Rotzoll <ch.rotzoll@gmail.com>\nChristian Simon <simon@swine.de>\nChristian Stefanescu <st.chris@gmail.com>\nChristoph Ziebuhr <chris@codefrickler.de>\nChristophe Mehay <cmehay@online.net>\nChristophe Troestler <christophe.Troestler@umons.ac.be>\nChristophe Vidal <kriss@krizalys.com>\nChristopher Biscardi <biscarch@sketcht.com>\nChristopher Crone <christopher.crone@docker.com>\nChristopher Currie <codemonkey+github@gmail.com>\nChristopher Jones <tophj@linux.vnet.ibm.com>\nChristopher Latham <sudosurootdev@gmail.com>\nChristopher Rigor <crigor@gmail.com>\nChristy Norman <christy@linux.vnet.ibm.com>\nChun Chen <ramichen@tencent.com>\nCiro S. Costa <ciro.costa@usp.br>\nClayton Coleman <ccoleman@redhat.com>\nClint Armstrong <clint@clintarmstrong.net>\nClinton Kitson <clintonskitson@gmail.com>\nclubby789 <jamie@hill-daniel.co.uk>\nCody Roseborough <crrosebo@amazon.com>\nCoenraad Loubser <coenraad@wish.org.za>\nColin Dunklau <colin.dunklau@gmail.com>\nColin Hebert <hebert.colin@gmail.com>\nColin Panisset <github@clabber.com>\nColin Rice <colin@daedrum.net>\nColin Walters <walters@verbum.org>\nCollin Guarino <collin.guarino@gmail.com>\nColm Hally <colmhally@gmail.com>\ncompanycy <companycy@gmail.com>\nConor Evans <coevans@tcd.ie>\nCorbin Coleman <corbin.coleman@docker.com>\nCorey Farrell <git@cfware.com>\nCory Forsyth <cory.forsyth@gmail.com>\nCory Snider <csnider@mirantis.com>\ncressie176 <github@stephen-cresswell.net>\nCristian Ariza <dev@cristianrz.com>\nCristian Staretu <cristian.staretu@gmail.com>\ncristiano balducci <cristiano.balducci@gmail.com>\nCristina Yenyxe Gonzalez Garcia <cristina.yenyxe@gmail.com>\nCruceru Calin-Cristian <crucerucalincristian@gmail.com>\ncui fliter <imcusg@gmail.com>\nCUI Wei <ghostplant@qq.com>\nCuong Manh Le <cuong.manhle.vn@gmail.com>\nCyprian Gracz <cyprian.gracz@micro-jumbo.eu>\nCyril F <cyrilf7x@gmail.com>\nDa McGrady <dabkb@aol.com>\nDaan van Berkel <daan.v.berkel.1980@gmail.com>\nDaehyeok Mun <daehyeok@gmail.com>\nDafydd Crosby <dtcrsby@gmail.com>\ndalanlan <dalanlan925@gmail.com>\nDamian Smyth <damian@dsau.co>\nDamien Nadé <github@livna.org>\nDamien Nozay <damien.nozay@gmail.com>\nDamjan Georgievski <gdamjan@gmail.com>\nDan Anolik <dan@anolik.net>\nDan Buch <d.buch@modcloth.com>\nDan Cotora <dan@bluevision.ro>\nDan Feldman <danf@jfrog.com>\nDan Griffin <dgriffin@peer1.com>\nDan Hirsch <thequux@upstandinghackers.com>\nDan Keder <dan.keder@gmail.com>\nDan Levy <dan@danlevy.net>\nDan McPherson <dmcphers@redhat.com>\nDan Plamadeala <cornul11@gmail.com>\nDan Stine <sw@stinemail.com>\nDan Williams <me@deedubs.com>\nDani Hodovic <dani.hodovic@gmail.com>\nDani Louca <dani.louca@docker.com>\nDaniel Antlinger <d.antlinger@gmx.at>\nDaniel Black <daniel@linux.ibm.com>\nDaniel Dao <dqminh@cloudflare.com>\nDaniel Exner <dex@dragonslave.de>\nDaniel Farrell <dfarrell@redhat.com>\nDaniel Garcia <daniel@danielgarcia.info>\nDaniel Gasienica <daniel@gasienica.ch>\nDaniel Grunwell <mwgrunny@gmail.com>\nDaniel Helfand <helfand.4@gmail.com>\nDaniel Hiltgen <daniel.hiltgen@docker.com>\nDaniel J Walsh <dwalsh@redhat.com>\nDaniel Menet <membership@sontags.ch>\nDaniel Mizyrycki <daniel.mizyrycki@dotcloud.com>\nDaniel Nephin <dnephin@docker.com>\nDaniel Norberg <dano@spotify.com>\nDaniel Nordberg <dnordberg@gmail.com>\nDaniel P. Berrangé <berrange@redhat.com>\nDaniel Robinson <gottagetmac@gmail.com>\nDaniel S <dan.streby@gmail.com>\nDaniel Sweet <danieljsweet@icloud.com>\nDaniel Von Fange <daniel@leancoder.com>\nDaniel Watkins <daniel@daniel-watkins.co.uk>\nDaniel X Moore <yahivin@gmail.com>\nDaniel YC Lin <dlin.tw@gmail.com>\nDaniel Zhang <jmzwcn@gmail.com>\nDaniele Rondina <geaaru@sabayonlinux.org>\nDanny Berger <dpb587@gmail.com>\nDanny Milosavljevic <dannym@scratchpost.org>\nDanny Yates <danny@codeaholics.org>\nDanyal Khaliq <danyal.khaliq@tenpearls.com>\nDarren Coxall <darren@darrencoxall.com>\nDarren Shepherd <darren.s.shepherd@gmail.com>\nDarren Stahl <darst@microsoft.com>\nDattatraya Kumbhar <dattatraya.kumbhar@gslab.com>\nDavanum Srinivas <davanum@gmail.com>\nDave Barboza <dbarboza@datto.com>\nDave Goodchild <buddhamagnet@gmail.com>\nDave Henderson <dhenderson@gmail.com>\nDave MacDonald <mindlapse@gmail.com>\nDave Tucker <dt@docker.com>\nDavid Anderson <dave@natulte.net>\nDavid Bellotti <dbellotti@pivotal.io>\nDavid Calavera <david.calavera@gmail.com>\nDavid Chung <david.chung@docker.com>\nDavid Corking <dmc-source@dcorking.com>\nDavid Cramer <davcrame@cisco.com>\nDavid Currie <david_currie@uk.ibm.com>\nDavid Davis <daviddavis@redhat.com>\nDavid Dooling <dooling@gmail.com>\nDavid Gageot <david@gageot.net>\nDavid Gebler <davidgebler@gmail.com>\nDavid Glasser <glasser@davidglasser.net>\nDavid Karlsson <35727626+dvdksn@users.noreply.github.com>\nDavid Lawrence <david.lawrence@docker.com>\nDavid Lechner <david@lechnology.com>\nDavid M. Karr <davidmichaelkarr@gmail.com>\nDavid Mackey <tdmackey@booleanhaiku.com>\nDavid Manouchehri <manouchehri@riseup.net>\nDavid Mat <david@davidmat.com>\nDavid Mcanulty <github@hellspark.com>\nDavid McKay <david@rawkode.com>\nDavid O'Rourke <david@scalefactory.com>\nDavid P Hilton <david.hilton.p@gmail.com>\nDavid Pelaez <pelaez89@gmail.com>\nDavid R. Jenni <david.r.jenni@gmail.com>\nDavid Röthlisberger <david@rothlis.net>\nDavid Sheets <dsheets@docker.com>\nDavid Sissitka <me@dsissitka.com>\nDavid Trott <github@davidtrott.com>\nDavid Wang <00107082@163.com>\nDavid Williamson <david.williamson@docker.com>\nDavid Xia <dxia@spotify.com>\nDavid Young <yangboh@cn.ibm.com>\nDavide Ceretti <davide.ceretti@hogarthww.com>\nDawn Chen <dawnchen@google.com>\ndbdd <wangtong2712@gmail.com>\ndcylabs <dcylabs@gmail.com>\nDebayan De <debayande@users.noreply.github.com>\nDeborah Gertrude Digges <deborah.gertrude.digges@gmail.com>\ndeed02392 <georgehafiz@gmail.com>\nDeep Debroy <ddebroy@docker.com>\nDeng Guangxing <dengguangxing@huawei.com>\nDeni Bertovic <deni@kset.org>\nDenis Defreyne <denis@soundcloud.com>\nDenis Gladkikh <denis@gladkikh.email>\nDenis Ollier <larchunix@users.noreply.github.com>\nDennis Chen <barracks510@gmail.com>\nDennis Chen <dennis.chen@arm.com>\nDennis Docter <dennis@d23.nl>\nDerek <crq@kernel.org>\nDerek <crquan@gmail.com>\nDerek Ch <denc716@gmail.com>\nDerek McGowan <derek@mcg.dev>\nDeric Crago <deric.crago@gmail.com>\nDeshi Xiao <dxiao@redhat.com>\nDevon Estes <devon.estes@klarna.com>\nDevvyn Murphy <devvyn@devvyn.com>\nDharmit Shah <shahdharmit@gmail.com>\nDhawal Yogesh Bhanushali <dbhanushali@vmware.com>\nDhilip Kumars <dhilip.kumar.s@huawei.com>\nDiego Romero <idiegoromero@gmail.com>\nDiego Siqueira <dieg0@live.com>\nDieter Reuter <dieter.reuter@me.com>\nDillon Dixon <dillondixon@gmail.com>\nDima Stopel <dima@twistlock.com>\nDimitri John Ledkov <dimitri.j.ledkov@intel.com>\nDimitris Mandalidis <dimitris.mandalidis@gmail.com>\nDimitris Rozakis <dimrozakis@gmail.com>\nDimitry Andric <d.andric@activevideo.com>\nDinesh Subhraveti <dineshs@altiscale.com>\nDing Fei <dingfei@stars.org.cn>\ndingwei <dingwei@cmss.chinamobile.com>\nDiogo Monica <diogo@docker.com>\nDiuDiugirl <sophia.wang@pku.edu.cn>\nDjibril Koné <kone.djibril@gmail.com>\nDjordje Lukic <djordje.lukic@docker.com>\ndkumor <daniel@dkumor.com>\nDmitri Logvinenko <dmitri.logvinenko@gmail.com>\nDmitri Shuralyov <shurcooL@gmail.com>\nDmitry Demeshchuk <demeshchuk@gmail.com>\nDmitry Gusev <dmitry.gusev@gmail.com>\nDmitry Kononenko <d@dm42.ru>\nDmitry Sharshakov <d3dx12.xx@gmail.com>\nDmitry Shyshkin <dmitry@shyshkin.org.ua>\nDmitry Smirnov <onlyjob@member.fsf.org>\nDmitry V. Krivenok <krivenok.dmitry@gmail.com>\nDmitry Vorobev <dimahabr@gmail.com>\nDmytro Iakovliev <dmytro.iakovliev@zodiacsystems.com>\ndocker-unir[bot] <docker-unir[bot]@users.noreply.github.com>\nDolph Mathews <dolph.mathews@gmail.com>\nDominic Tubach <dominic.tubach@to.com>\nDominic Yin <yindongchao@inspur.com>\nDominik Dingel <dingel@linux.vnet.ibm.com>\nDominik Finkbeiner <finkes93@gmail.com>\nDominik Honnef <dominik@honnef.co>\nDon Kirkby <donkirkby@users.noreply.github.com>\nDon Kjer <don.kjer@gmail.com>\nDon Spaulding <donspauldingii@gmail.com>\nDonald Huang <don.hcd@gmail.com>\nDong Chen <dongluo.chen@docker.com>\nDonghwa Kim <shanytt@gmail.com>\nDonovan Jones <git@gamma.net.nz>\nDorin Geman <dorin.geman@docker.com>\nDoron Podoleanu <doronp@il.ibm.com>\nDoug Davis <dug@us.ibm.com>\nDoug MacEachern <dougm@vmware.com>\nDoug Tangren <d.tangren@gmail.com>\nDouglas Curtis <dougcurtis1@gmail.com>\nDr Nic Williams <drnicwilliams@gmail.com>\ndragon788 <dragon788@users.noreply.github.com>\nDražen Lučanin <kermit666@gmail.com>\nDrew Erny <derny@mirantis.com>\nDrew Hubl <drew.hubl@gmail.com>\nDustin Sallings <dustin@spy.net>\nEd Costello <epc@epcostello.com>\nEdmund Wagner <edmund-wagner@web.de>\nEiichi Tsukata <devel@etsukata.com>\nEike Herzbach <eike@herzbach.net>\nEivin Giske Skaaren <eivinsn@axis.com>\nEivind Uggedal <eivind@uggedal.com>\nElan Ruusamäe <glen@pld-linux.org>\nElango Sivanandam <elango.siva@docker.com>\nElena Morozova <lelenanam@gmail.com>\nEli Uriegas <seemethere101@gmail.com>\nElias Faxö <elias.faxo@tre.se>\nElias Koromilas <elias.koromilas@gmail.com>\nElias Probst <mail@eliasprobst.eu>\nElijah Zupancic <elijah@zupancic.name>\neluck <mail@eluck.me>\nElvir Kuric <elvirkuric@gmail.com>\nEmil Davtyan <emil2k@gmail.com>\nEmil Hernvall <emil@quench.at>\nEmily Maier <emily@emilymaier.net>\nEmily Rose <emily@contactvibe.com>\nEmir Ozer <emirozer@yandex.com>\nEng Zer Jun <engzerjun@gmail.com>\nEnguerran <engcolson@gmail.com>\nEnrico Weigelt, metux IT consult <info@metux.net>\nEohyung Lee <liquidnuker@gmail.com>\nepeterso <epeterson@breakpoint-labs.com>\ner0k <er0k@er0k.net>\nEric Barch <barch@tomesoftware.com>\nEric Curtin <ericcurtin17@gmail.com>\nEric G. Noriega <enoriega@vizuri.com>\nEric Hanchrow <ehanchrow@ine.com>\nEric Lee <thenorthsecedes@gmail.com>\nEric Mountain <eric.mountain@datadoghq.com>\nEric Myhre <hash@exultant.us>\nEric Paris <eparis@redhat.com>\nEric Rafaloff <erafaloff@gmail.com>\nEric Rosenberg <ehaydenr@gmail.com>\nEric Sage <eric.david.sage@gmail.com>\nEric Soderstrom <ericsoderstrom@gmail.com>\nEric Yang <windfarer@gmail.com>\nEric-Olivier Lamey <eo@lamey.me>\nErica Windisch <erica@windisch.us>\nErich Cordoba <erich.cm@yandex.com>\nErik Bray <erik.m.bray@gmail.com>\nErik Dubbelboer <erik@dubbelboer.com>\nErik Hollensbe <github@hollensbe.org>\nErik Inge Bolsø <knan@redpill-linpro.com>\nErik Kristensen <erik@erikkristensen.com>\nErik Sipsma <erik@sipsma.dev>\nErik St. Martin <alakriti@gmail.com>\nErik Weathers <erikdw@gmail.com>\nErno Hopearuoho <erno.hopearuoho@gmail.com>\nErwin van der Koogh <info@erronis.nl>\nEspen Suenson <mail@espensuenson.dk>\nEthan Bell <ebgamer29@gmail.com>\nEthan Mosbaugh <ethan@replicated.com>\nEuan Harris <euan.harris@docker.com>\nEuan Kemp <euan.kemp@coreos.com>\nEugen Krizo <eugen.krizo@gmail.com>\nEugene Yakubovich <eugene.yakubovich@coreos.com>\nEvan Allrich <evan@unguku.com>\nEvan Carmi <carmi@users.noreply.github.com>\nEvan Hazlett <ejhazlett@gmail.com>\nEvan Krall <krall@yelp.com>\nEvan Lezar <elezar@nvidia.com>\nEvan Phoenix <evan@fallingsnow.net>\nEvan Wies <evan@neomantra.net>\nEvelyn Xu <evelynhsu21@gmail.com>\nEverett Toews <everett.toews@rackspace.com>\nEvgeniy Makhrov <e.makhrov@corp.badoo.com>\nEvgeny Shmarnev <shmarnev@gmail.com>\nEvgeny Vereshchagin <evvers@ya.ru>\nEwa Czechowska <ewa@ai-traders.com>\nEystein Måløy Stenberg <eystein.maloy.stenberg@cfengine.com>\nezbercih <cem.ezberci@gmail.com>\nEzra Silvera <ezra@il.ibm.com>\nFabian Kramm <kramm@covexo.com>\nFabian Lauer <kontakt@softwareschmiede-saar.de>\nFabian Raetz <fabian.raetz@gmail.com>\nFabiano Rosas <farosas@br.ibm.com>\nFabio Falci <fabiofalci@gmail.com>\nFabio Kung <fabio.kung@gmail.com>\nFabio Rapposelli <fabio@vmware.com>\nFabio Rehm <fgrehm@gmail.com>\nFabrizio Regini <freegenie@gmail.com>\nFabrizio Soppelsa <fsoppelsa@mirantis.com>\nFaiz Khan <faizkhan00@gmail.com>\nfalmp <chico.lopes@gmail.com>\nFangming Fang <fangming.fang@arm.com>\nFangyuan Gao <21551127@zju.edu.cn>\nfanjiyun <fan.jiyun@zte.com.cn>\nFareed Dudhia <fareeddudhia@googlemail.com>\nFathi Boudra <fathi.boudra@linaro.org>\nFederico Gimenez <fgimenez@coit.es>\nFelipe Oliveira <felipeweb.programador@gmail.com>\nFelipe Ruhland <felipe.ruhland@gmail.com>\nFelix Abecassis <fabecassis@nvidia.com>\nFelix Geisendörfer <felix@debuggable.com>\nFelix Hupfeld <felix@quobyte.com>\nFelix Rabe <felix@rabe.io>\nFelix Ruess <felix.ruess@gmail.com>\nFelix Schindler <fschindler@weluse.de>\nFeng Yan <fy2462@gmail.com>\nFengtu Wang <wangfengtu@huawei.com>\nFerenc Szabo <pragmaticfrank@gmail.com>\nFernando <fermayo@gmail.com>\nFero Volar <alian@alian.info>\nFeroz Salam <feroz.salam@sourcegraph.com>\nFerran Rodenas <frodenas@gmail.com>\nFilipe Brandenburger <filbranden@google.com>\nFilipe Oliveira <contato@fmoliveira.com.br>\nFlavio Castelli <fcastelli@suse.com>\nFlavio Crisciani <flavio.crisciani@docker.com>\nFlorian <FWirtz@users.noreply.github.com>\nFlorian Klein <florian.klein@free.fr>\nFlorian Maier <marsmensch@users.noreply.github.com>\nFlorian Noeding <noeding@adobe.com>\nFlorian Schmaus <flo@geekplace.eu>\nFlorian Weingarten <flo@hackvalue.de>\nFlorin Asavoaie <florin.asavoaie@gmail.com>\nFlorin Patan <florinpatan@gmail.com>\nfonglh <fonglh@gmail.com>\nFoysal Iqbal <foysal.iqbal.fb@gmail.com>\nFrancesc Campoy <campoy@google.com>\nFrancesco Degrassi <francesco.degrassi@optionfactory.net>\nFrancesco Mari <mari.francesco@gmail.com>\nFrancis Chuang <francis.chuang@boostport.com>\nFrancisco Carriedo <fcarriedo@gmail.com>\nFrancisco Souza <f@souza.cc>\nFrank Groeneveld <frank@ivaldi.nl>\nFrank Herrmann <fgh@4gh.tv>\nFrank Macreery <frank@macreery.com>\nFrank Rosquin <frank.rosquin+github@gmail.com>\nFrank Villaro-Dixon <frank.villarodixon@merkle.com>\nFrank Yang <yyb196@gmail.com>\nFred Lifton <fred.lifton@docker.com>\nFrederick F. Kautz IV <fkautz@redhat.com>\nFrederico F. de Oliveira <FreddieOliveira@users.noreply.github.com>\nFrederik Loeffert <frederik@zitrusmedia.de>\nFrederik Nordahl Jul Sabroe <frederikns@gmail.com>\nFreek Kalter <freek@kalteronline.org>\nFrieder Bluemle <frieder.bluemle@gmail.com>\nfrobnicaty <92033765+frobnicaty@users.noreply.github.com>\nFrédéric Dalleau <frederic.dalleau@docker.com>\nFu JinLin <withlin@yeah.net>\nFélix Baylac-Jacqué <baylac.felix@gmail.com>\nFélix Cantournet <felix.cantournet@cloudwatt.com>\nGabe Rosenhouse <gabe@missionst.com>\nGabor Nagy <mail@aigeruth.hu>\nGabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>\nGabriel Goller <gabrielgoller123@gmail.com>\nGabriel L. Somlo <gsomlo@gmail.com>\nGabriel Linder <linder.gabriel@gmail.com>\nGabriel Monroy <gabriel@opdemand.com>\nGabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>\nGaetan de Villele <gdevillele@gmail.com>\nGalen Sampson <galen.sampson@gmail.com>\nGang Qiao <qiaohai8866@gmail.com>\nGareth Rushgrove <gareth@morethanseven.net>\nGarrett Barboza <garrett@garrettbarboza.com>\nGary Schaetz <gary@schaetzkc.com>\nGaurav <gaurav.gosec@gmail.com>\nGaurav Singh <gaurav1086@gmail.com>\nGaël PORTAY <gael.portay@savoirfairelinux.com>\nGenki Takiuchi <genki@s21g.com>\nGennadySpb <lipenkov@gmail.com>\nGeoff Levand <geoff@infradead.org>\nGeoffrey Bachelet <grosfrais@gmail.com>\nGeon Kim <geon0250@gmail.com>\nGeorge Kontridze <george@bugsnag.com>\nGeorge MacRorie <gmacr31@gmail.com>\nGeorge Xie <georgexsh@gmail.com>\nGeorgi Hristozov <georgi@forkbomb.nl>\nGeorgy Yakovlev <gyakovlev@gentoo.org>\nGereon Frey <gereon.frey@dynport.de>\nGerman DZ <germ@ndz.com.ar>\nGert van Valkenhoef <g.h.m.van.valkenhoef@rug.nl>\nGerwim Feiken <g.feiken@tfe.nl>\nGhislain Bourgeois <ghislain.bourgeois@gmail.com>\nGiampaolo Mancini <giampaolo@trampolineup.com>\nGianluca Borello <g.borello@gmail.com>\nGildas Cuisinier <gildas.cuisinier@gcuisinier.net>\nGiovan Isa Musthofa <giovanism@outlook.co.id>\ngissehel <public-devgit-dantus@gissehel.org>\nGiuseppe Mazzotta <gdm85@users.noreply.github.com>\nGiuseppe Scrivano <gscrivan@redhat.com>\nGleb Fotengauer-Malinovskiy <glebfm@altlinux.org>\nGleb M Borisov <borisov.gleb@gmail.com>\nGlyn Normington <gnormington@gopivotal.com>\nGoBella <caili_welcome@163.com>\nGoffert van Gool <goffert@phusion.nl>\nGoldwyn Rodrigues <rgoldwyn@suse.com>\nGopikannan Venugopalsamy <gopikannan.venugopalsamy@gmail.com>\nGosuke Miyashita <gosukenator@gmail.com>\nGou Rao <gou@portworx.com>\nGovinda Fichtner <govinda.fichtner@googlemail.com>\nGrant Millar <rid@cylo.io>\nGrant Reaber <grant.reaber@gmail.com>\nGraydon Hoare <graydon@pobox.com>\nGreg Fausak <greg@tacodata.com>\nGreg Pflaum <gpflaum@users.noreply.github.com>\nGreg Stephens <greg@udon.org>\nGreg Thornton <xdissent@me.com>\nGrzegorz Jaśkiewicz <gj.jaskiewicz@gmail.com>\nGuilhem Lettron <guilhem+github@lettron.fr>\nGuilherme Salgado <gsalgado@gmail.com>\nGuillaume Dufour <gdufour.prestataire@voyages-sncf.com>\nGuillaume J. Charmes <guillaume.charmes@docker.com>\nGunadhya S. <6939749+gunadhya@users.noreply.github.com>\nGuoqiang QI <guoqiang.qi1@gmail.com>\nguoxiuyan <guoxiuyan@huawei.com>\nGuri <odg0318@gmail.com>\nGurjeet Singh <gurjeet@singh.im>\nGuruprasad <lgp171188@gmail.com>\nGustav Sinder <gustav.sinder@gmail.com>\ngwx296173 <gaojing3@huawei.com>\nGünter Zöchbauer <guenter@gzoechbauer.com>\nHaichao Yang <yang.haichao@zte.com.cn>\nhaikuoliu <haikuo@amazon.com>\nhaining.cao <haining.cao@daocloud.io>\nHakan Özler <hakan.ozler@kodcu.com>\nHamish Hutchings <moredhel@aoeu.me>\nHannes Ljungberg <hannes@5monkeys.se>\nHans Kristian Flaatten <hans@starefossen.com>\nHans Rødtang <hansrodtang@gmail.com>\nHao Shu Wei <haoshuwei24@gmail.com>\nHao Zhang <21521210@zju.edu.cn>\nHarald Albers <github@albersweb.de>\nHarald Niesche <harald@niesche.de>\nHarley Laue <losinggeneration@gmail.com>\nHarold Cooper <hrldcpr@gmail.com>\nHarrison Turton <harrisonturton@gmail.com>\nHarry Zhang <harryz@hyper.sh>\nHarshal Patil <harshal.patil@in.ibm.com>\nHarshal Patil <harshalp@linux.vnet.ibm.com>\nHe Simei <hesimei@zju.edu.cn>\nHe Xiaoxi <tossmilestone@gmail.com>\nHe Xin <he_xinworld@126.com>\nheartlock <21521209@zju.edu.cn>\nHector Castro <hectcastro@gmail.com>\nHelen Xie <chenjg@harmonycloud.cn>\nHenning Sprang <henning.sprang@gmail.com>\nHiroshi Hatake <hatake@clear-code.com>\nHiroyuki Sasagawa <hs19870702@gmail.com>\nHobofan <goisser94@gmail.com>\nHollie Teal <hollie@docker.com>\nHong Xu <hong@topbug.net>\nHongbin Lu <hongbin034@gmail.com>\nHongxu Jia <hongxu.jia@windriver.com>\nHonza Pokorny <me@honza.ca>\nHsing-Hui Hsu <hsinghui@amazon.com>\nHsing-Yu (David) Chen <davidhsingyuchen@gmail.com>\nhsinko <21551195@zju.edu.cn>\nHu Keping <hukeping@huawei.com>\nHu Tao <hutao@cn.fujitsu.com>\nHuanHuan Ye <logindaveye@gmail.com>\nHuanzhong Zhang <zhanghuanzhong90@gmail.com>\nHuayi Zhang <irachex@gmail.com>\nHugo Barrera <hugo@barrera.io>\nHugo Duncan <hugo@hugoduncan.org>\nHugo Marisco <0x6875676f@gmail.com>\nHui Kang <hkang.sunysb@gmail.com>\nHunter Blanks <hunter@twilio.com>\nhuqun <huqun@zju.edu.cn>\nHuu Nguyen <huu@prismskylabs.com>\nHyeongkyu Lee <hyeongkyu.lee@navercorp.com>\nHyzhou Zhy <hyzhou.zhy@alibaba-inc.com>\nIago López Galeiras <iago@kinvolk.io>\nIan Bishop <ianbishop@pace7.com>\nIan Bull <irbull@gmail.com>\nIan Calvert <ianjcalvert@gmail.com>\nIan Campbell <ian.campbell@docker.com>\nIan Chen <ianre657@gmail.com>\nIan Lee <IanLee1521@gmail.com>\nIan Main <imain@redhat.com>\nIan Philpot <ian.philpot@microsoft.com>\nIan Truslove <ian.truslove@gmail.com>\nIavael <iavaelooeyt@gmail.com>\nIcaro Seara <icaro.seara@gmail.com>\nIgnacio Capurro <icapurrofagian@gmail.com>\nIgor Dolzhikov <bluesriverz@gmail.com>\nIgor Karpovich <i.karpovich@currencysolutions.com>\nIliana Weller <iweller@amazon.com>\nIlkka Laukkanen <ilkka@ilkka.io>\nIllia Antypenko <ilya@antipenko.pp.ua>\nIllo Abdulrahim <abdulrahim.illo@nokia.com>\nIlya Dmitrichenko <errordeveloper@gmail.com>\nIlya Gusev <mail@igusev.ru>\nIlya Khlopotov <ilya.khlopotov@gmail.com>\nimre Fitos <imre.fitos+github@gmail.com>\ninglesp <peter.inglesby@gmail.com>\nIngo Gottwald <in.gottwald@gmail.com>\nInnovimax <innovimax@gmail.com>\nIsaac Dupree <antispam@idupree.com>\nIsabel Jimenez <contact.isabeljimenez@gmail.com>\nIsaiah Grace <irgkenya4@gmail.com>\nIsao Jonas <isao.jonas@gmail.com>\nIskander Sharipov <quasilyte@gmail.com>\nIvan Babrou <ibobrik@gmail.com>\nIvan Fraixedes <ifcdev@gmail.com>\nIvan Grcic <igrcic@gmail.com>\nIvan Markin <sw@nogoegst.net>\nJ Bruni <joaohbruni@yahoo.com.br>\nJ. Nunn <jbnunn@gmail.com>\nJack Danger Canty <jackdanger@squareup.com>\nJack Laxson <jackjrabbit@gmail.com>\nJacob Atzen <jacob@jacobatzen.dk>\nJacob Edelman <edelman.jd@gmail.com>\nJacob Tomlinson <jacob@tom.linson.uk>\nJacob Vallejo <jakeev@amazon.com>\nJacob Wen <jian.w.wen@oracle.com>\nJaime Cepeda <jcepedavillamayor@gmail.com>\nJaivish Kothari <janonymous.codevulture@gmail.com>\nJake Champlin <jake.champlin.27@gmail.com>\nJake Moshenko <jake@devtable.com>\nJake Sanders <jsand@google.com>\nJakub Drahos <jdrahos@pulsepoint.com>\nJakub Guzik <jakubmguzik@gmail.com>\nJames Allen <jamesallen0108@gmail.com>\nJames Carey <jecarey@us.ibm.com>\nJames Carr <james.r.carr@gmail.com>\nJames DeFelice <james.defelice@ishisystems.com>\nJames Harrison Fisher <jameshfisher@gmail.com>\nJames Kyburz <james.kyburz@gmail.com>\nJames Kyle <james@jameskyle.org>\nJames Lal <james@lightsofapollo.com>\nJames Mills <prologic@shortcircuit.net.au>\nJames Nesbitt <jnesbitt@mirantis.com>\nJames Nugent <james@jen20.com>\nJames Sanders <james3sanders@gmail.com>\nJames Turnbull <james@lovedthanlost.net>\nJames Watkins-Harvey <jwatkins@progi-media.com>\nJamie Hannaford <jamie@limetree.org>\nJamshid Afshar <jafshar@yahoo.com>\nJan Breig <git@pygos.space>\nJan Chren <dev.rindeal@gmail.com>\nJan Garcia <github-public@n-garcia.com>\nJan Götte <jaseg@jaseg.net>\nJan Keromnes <janx@linux.com>\nJan Koprowski <jan.koprowski@gmail.com>\nJan Pazdziora <jpazdziora@redhat.com>\nJan Toebes <jan@toebes.info>\nJan-Gerd Tenberge <janten@gmail.com>\nJan-Jaap Driessen <janjaapdriessen@gmail.com>\nJana Radhakrishnan <mrjana@docker.com>\nJannick Fahlbusch <git@jf-projects.de>\nJanuar Wayong <januar@gmail.com>\nJared Biel <jared.biel@bolderthinking.com>\nJared Hocutt <jaredh@netapp.com>\nJaroslaw Zabiello <hipertracker@gmail.com>\nJasmine Hegman <jasmine@jhegman.com>\nJason A. Donenfeld <Jason@zx2c4.com>\nJason Divock <jdivock@gmail.com>\nJason Giedymin <jasong@apache.org>\nJason Green <Jason.Green@AverInformatics.Com>\nJason Hall <imjasonh@gmail.com>\nJason Heiss <jheiss@aput.net>\nJason Livesay <ithkuil@gmail.com>\nJason McVetta <jason.mcvetta@gmail.com>\nJason Plum <jplum@devonit.com>\nJason Shepherd <jason@jasonshepherd.net>\nJason Smith <jasonrichardsmith@gmail.com>\nJason Sommer <jsdirv@gmail.com>\nJason Stangroome <jason@codeassassin.com>\nJavier Bassi <javierbassi@gmail.com>\njaxgeller <jacksongeller@gmail.com>\nJay <teguhwpurwanto@gmail.com>\nJay Kamat <github@jgkamat.33mail.com>\nJay Lim <jay@imjching.com>\nJean Rouge <rougej+github@gmail.com>\nJean-Baptiste Barth <jeanbaptiste.barth@gmail.com>\nJean-Baptiste Dalido <jeanbaptiste@appgratis.com>\nJean-Christophe Berthon <huygens@berthon.eu>\nJean-Michel Rouet <jm.rouet@gmail.com>\nJean-Paul Calderone <exarkun@twistedmatrix.com>\nJean-Pierre Huynh <jean-pierre.huynh@ounet.fr>\nJean-Tiare Le Bigot <jt@yadutaf.fr>\nJeeva S. Chelladhurai <sjeeva@gmail.com>\nJeff Anderson <jeff@docker.com>\nJeff Hajewski <jeff.hajewski@gmail.com>\nJeff Johnston <jeff.johnston.mn@gmail.com>\nJeff Lindsay <progrium@gmail.com>\nJeff Mickey <j@codemac.net>\nJeff Minard <jeff@creditkarma.com>\nJeff Nickoloff <jeff.nickoloff@gmail.com>\nJeff Silberman <jsilberm@gmail.com>\nJeff Welch <whatthejeff@gmail.com>\nJeff Zvier <zvier20@gmail.com>\nJeffrey Bolle <jeffreybolle@gmail.com>\nJeffrey Morgan <jmorganca@gmail.com>\nJeffrey van Gogh <jvg@google.com>\nJenny Gebske <jennifer@gebske.de>\nJeremy Chambers <jeremy@thehipbot.com>\nJeremy Grosser <jeremy@synack.me>\nJeremy Huntwork <jhuntwork@lightcubesolutions.com>\nJeremy Price <jprice.rhit@gmail.com>\nJeremy Qian <vanpire110@163.com>\nJeremy Unruh <jeremybunruh@gmail.com>\nJeremy Yallop <yallop@docker.com>\nJeroen Franse <jeroenfranse@gmail.com>\nJeroen Jacobs <github@jeroenj.be>\nJesse Dearing <jesse.dearing@gmail.com>\nJesse Dubay <jesse@thefortytwo.net>\nJessica Frazelle <jess@oxide.computer>\nJeyanthinath Muthuram <jeyanthinath10@gmail.com>\nJezeniel Zapanta <jpzapanta22@gmail.com>\nJhon Honce <jhonce@redhat.com>\nJi.Zhilong <zhilongji@gmail.com>\nJian Liao <jliao@alauda.io>\nJian Zhang <zhangjian.fnst@cn.fujitsu.com>\nJiang Jinyang <jjyruby@gmail.com>\nJianyong Wu <jianyong.wu@arm.com>\nJie Luo <luo612@zju.edu.cn>\nJie Ma <jienius@outlook.com>\nJihyun Hwang <jhhwang@telcoware.com>\nJilles Oldenbeuving <ojilles@gmail.com>\nJim Alateras <jima@comware.com.au>\nJim Carroll <jim.carroll@docker.com>\nJim Ehrismann <jim.ehrismann@docker.com>\nJim Galasyn <jim.galasyn@docker.com>\nJim Lin <b04705003@ntu.edu.tw>\nJim Minter <jminter@redhat.com>\nJim Perrin <jperrin@centos.org>\nJimmy Cuadra <jimmy@jimmycuadra.com>\nJimmy Puckett <jimmy.puckett@spinen.com>\nJimmy Song <rootsongjc@gmail.com>\nJinsoo Park <cellpjs@gmail.com>\nJintao Zhang <zhangjintao9020@gmail.com>\nJiri Appl <jiria@microsoft.com>\nJiri Popelka <jpopelka@redhat.com>\nJiuyue Ma <majiuyue@huawei.com>\nJiří Župka <jzupka@redhat.com>\nJoakim Roubert <joakim.roubert@axis.com>\nJoao Fernandes <joao.fernandes@docker.com>\nJoao Trindade <trindade.joao@gmail.com>\nJoe Beda <joe.github@bedafamily.com>\nJoe Doliner <jdoliner@pachyderm.io>\nJoe Ferguson <joe@infosiftr.com>\nJoe Gordon <joe.gordon0@gmail.com>\nJoe Shaw <joe@joeshaw.org>\nJoe Van Dyk <joe@tanga.com>\nJoel Friedly <joelfriedly@gmail.com>\nJoel Handwell <joelhandwell@gmail.com>\nJoel Hansson <joel.hansson@ecraft.com>\nJoel Wurtz <jwurtz@jolicode.com>\nJoey Geiger <jgeiger@gmail.com>\nJoey Geiger <jgeiger@users.noreply.github.com>\nJoey Gibson <joey@joeygibson.com>\nJoffrey F <joffrey@docker.com>\nJohan Euphrosine <proppy@google.com>\nJohan Rydberg <johan.rydberg@gmail.com>\nJohanan Lieberman <johanan.lieberman@gmail.com>\nJohannes 'fish' Ziemke <github@freigeist.org>\nJohn Costa <john.costa@gmail.com>\nJohn Feminella <jxf@jxf.me>\nJohn Gardiner Myers <jgmyers@proofpoint.com>\nJohn Gossman <johngos@microsoft.com>\nJohn Harris <john@johnharris.io>\nJohn Howard <github@lowenna.com>\nJohn Laswell <john.n.laswell@gmail.com>\nJohn Maguire <jmaguire@duosecurity.com>\nJohn Mulhausen <john@docker.com>\nJohn OBrien III <jobrieniii@yahoo.com>\nJohn Starks <jostarks@microsoft.com>\nJohn Stephens <johnstep@docker.com>\nJohn Tims <john.k.tims@gmail.com>\nJohn V. Martinez <jvmatl@gmail.com>\nJohn Warwick <jwarwick@gmail.com>\nJohn Willis <john.willis@docker.com>\nJon Johnson <jonjohnson@google.com>\nJon Surrell <jon.surrell@gmail.com>\nJon Wedaman <jweede@gmail.com>\nJonas Dohse <jonas@dohse.ch>\nJonas Heinrich <Jonas@JonasHeinrich.com>\nJonas Pfenniger <jonas@pfenniger.name>\nJonathan A. Schweder <jonathanschweder@gmail.com>\nJonathan A. Sternberg <jonathansternberg@gmail.com>\nJonathan Boulle <jonathanboulle@gmail.com>\nJonathan Camp <jonathan@irondojo.com>\nJonathan Choy <jonathan.j.choy@gmail.com>\nJonathan Dowland <jon+github@alcopop.org>\nJonathan Lebon <jlebon@redhat.com>\nJonathan Lomas <jonathan@floatinglomas.ca>\nJonathan McCrohan <jmccrohan@gmail.com>\nJonathan Mueller <j.mueller@apoveda.ch>\nJonathan Pares <jonathanpa@users.noreply.github.com>\nJonathan Rudenberg <jonathan@titanous.com>\nJonathan Stoppani <jonathan.stoppani@divio.com>\nJonh Wendell <jonh.wendell@redhat.com>\nJoni Sar <yoni@cocycles.com>\nJoost Cassee <joost@cassee.net>\nJordan Arentsen <blissdev@gmail.com>\nJordan Jennings <jjn2009@gmail.com>\nJordan Sissel <jls@semicomplete.com>\nJordi Massaguer Pla <jmassaguerpla@suse.de>\nJorge Marin <chipironcin@users.noreply.github.com>\nJorit Kleine-Möllhoff <joppich@bricknet.de>\nJose Diaz-Gonzalez <email@josediazgonzalez.com>\nJoseph Anthony Pasquale Holsten <joseph@josephholsten.com>\nJoseph Hager <ajhager@gmail.com>\nJoseph Kern <jkern@semafour.net>\nJoseph Rothrock <rothrock@rothrock.org>\nJosh <jokajak@gmail.com>\nJosh Bodah <jb3689@yahoo.com>\nJosh Bonczkowski <josh.bonczkowski@gmail.com>\nJosh Chorlton <jchorlton@gmail.com>\nJosh Eveleth <joshe@opendns.com>\nJosh Hawn <josh.hawn@docker.com>\nJosh Horwitz <horwitz@addthis.com>\nJosh Poimboeuf <jpoimboe@redhat.com>\nJosh Soref <jsoref@gmail.com>\nJosh Wilson <josh.wilson@fivestars.com>\nJosiah Kiehl <jkiehl@riotgames.com>\nJosé Tomás Albornoz <jojo@eljojo.net>\nJoyce Jang <mail@joycejang.com>\nJP <jpellerin@leapfrogonline.com>\nJulian Taylor <jtaylor.debian@googlemail.com>\nJulien Barbier <write0@gmail.com>\nJulien Bisconti <veggiemonk@users.noreply.github.com>\nJulien Bordellier <julienbordellier@gmail.com>\nJulien Dubois <julien.dubois@gmail.com>\nJulien Kassar <github@kassisol.com>\nJulien Maitrehenry <julien.maitrehenry@me.com>\nJulien Pervillé <julien.perville@perfect-memory.com>\nJulien Pivotto <roidelapluie@inuits.eu>\nJulio Guerra <julio@sqreen.com>\nJulio Montes <imc.coder@gmail.com>\nJun Du <dujun5@huawei.com>\nJun-Ru Chang <jrjang@gmail.com>\njunxu <xujun@cmss.chinamobile.com>\nJussi Nummelin <jussi.nummelin@gmail.com>\nJustas Brazauskas <brazauskasjustas@gmail.com>\nJusten Martin <jmart@the-coder.com>\nJustin Chadwell <me@jedevc.com>\nJustin Cormack <justin.cormack@docker.com>\nJustin Force <justin.force@gmail.com>\nJustin Keller <85903732+jk-vb@users.noreply.github.com>\nJustin Menga <justin.menga@gmail.com>\nJustin Plock <jplock@users.noreply.github.com>\nJustin Simonelis <justin.p.simonelis@gmail.com>\nJustin Terry <juterry@microsoft.com>\nJustyn Temme <justyntemme@gmail.com>\nJyrki Puttonen <jyrkiput@gmail.com>\nJérémy Leherpeur <amenophis@leherpeur.net>\nJérôme Petazzoni <jerome.petazzoni@docker.com>\nJörg Thalheim <joerg@higgsboson.tk>\nK. Heller <pestophagous@gmail.com>\nKai Blin <kai@samba.org>\nKai Qiang Wu (Kennan) <wkq5325@gmail.com>\nKaijie Chen <chen@kaijie.org>\nKamil Domański <kamil@domanski.co>\nKamjar Gerami <kami.gerami@gmail.com>\nKanstantsin Shautsou <kanstantsin.sha@gmail.com>\nKara Alexandra <kalexandra@us.ibm.com>\nKaran Lyons <karan@karanlyons.com>\nKareem Khazem <karkhaz@karkhaz.com>\nkargakis <kargakis@users.noreply.github.com>\nKarl Grzeszczak <karlgrz@gmail.com>\nKarol Duleba <mr.fuxi@gmail.com>\nKarthik Karanth <karanth.karthik@gmail.com>\nKarthik Nayak <karthik.188@gmail.com>\nKasper Fabæch Brandt <poizan@poizan.dk>\nKate Heddleston <kate.heddleston@gmail.com>\nKatie McLaughlin <katie@glasnt.com>\nKato Kazuyoshi <kato.kazuyoshi@gmail.com>\nKatrina Owen <katrina.owen@gmail.com>\nKawsar Saiyeed <kawsar.saiyeed@projiris.com>\nKay Yan <kay.yan@daocloud.io>\nkayrus <kay.diam@gmail.com>\nKazuhiro Sera <seratch@gmail.com>\nKazuyoshi Kato <katokazu@amazon.com>\nKe Li <kel@splunk.com>\nKe Xu <leonhartx.k@gmail.com>\nKei Ohmura <ohmura.kei@gmail.com>\nKeith Hudgins <greenman@greenman.org>\nKeli Hu <dev@keli.hu>\nKen Bannister <kb2ma@runbox.com>\nKen Cochrane <kencochrane@gmail.com>\nKen Herner <kherner@progress.com>\nKen ICHIKAWA <ichikawa.ken@jp.fujitsu.com>\nKen Reese <krrgithub@gmail.com>\nKenfe-Mickaël Laventure <mickael.laventure@gmail.com>\nKenjiro Nakayama <nakayamakenjiro@gmail.com>\nKent Johnson <kentoj@gmail.com>\nKenta Tada <Kenta.Tada@sony.com>\nKevin \"qwazerty\" Houdebert <kevin.houdebert@gmail.com>\nKevin Alvarez <github@crazymax.dev>\nKevin Burke <kev@inburke.com>\nKevin Clark <kevin.clark@gmail.com>\nKevin Feyrer <kevin.feyrer@btinternet.com>\nKevin J. Lynagh <kevin@keminglabs.com>\nKevin Jing Qiu <kevin@idempotent.ca>\nKevin Kern <kaiwentan@harmonycloud.cn>\nKevin Menard <kevin@nirvdrum.com>\nKevin Meredith <kevin.m.meredith@gmail.com>\nKevin P. Kucharczyk <kevinkucharczyk@gmail.com>\nKevin Parsons <kevpar@microsoft.com>\nKevin Richardson <kevin@kevinrichardson.co>\nKevin Shi <kshi@andrew.cmu.edu>\nKevin Wallace <kevin@pentabarf.net>\nKevin Yap <me@kevinyap.ca>\nKeyvan Fatehi <keyvanfatehi@gmail.com>\nkies <lleelm@gmail.com>\nKim BKC Carlbacker <kim.carlbacker@gmail.com>\nKim Eik <kim@heldig.org>\nKimbro Staken <kstaken@kstaken.com>\nKir Kolyshkin <kolyshkin@gmail.com>\nKiran Gangadharan <kiran.daredevil@gmail.com>\nKirill SIbirev <l0kix2@gmail.com>\nKirk Easterson <kirk.easterson@gmail.com>\nknappe <tyler.knappe@gmail.com>\nKohei Tsuruta <coheyxyz@gmail.com>\nKoichi Shiraishi <k@zchee.io>\nKonrad Kleine <konrad.wilhelm.kleine@gmail.com>\nKonrad Ponichtera <konpon96@gmail.com>\nKonstantin Gribov <grossws@gmail.com>\nKonstantin L <sw.double@gmail.com>\nKonstantin Pelykh <kpelykh@zettaset.com>\nKostadin Plachkov <k.n.plachkov@gmail.com>\nkpcyrd <git@rxv.cc>\nKrasi Georgiev <krasi@vip-consult.solutions>\nKrasimir Georgiev <support@vip-consult.co.uk>\nKris-Mikael Krister <krismikael@protonmail.com>\nKristian Haugene <kristian.haugene@capgemini.com>\nKristina Zabunova <triara.xiii@gmail.com>\nKrystian Wojcicki <kwojcicki@sympatico.ca>\nKunal Kushwaha <kushwaha_kunal_v7@lab.ntt.co.jp>\nKunal Tyagi <tyagi.kunal@live.com>\nKyle Conroy <kyle.j.conroy@gmail.com>\nKyle Linden <linden.kyle@gmail.com>\nKyle Squizzato <ksquizz@gmail.com>\nKyle Wuolle <kyle.wuolle@gmail.com>\nkyu <leehk1227@gmail.com>\nLachlan Coote <lcoote@vmware.com>\nLai Jiangshan <jiangshanlai@gmail.com>\nLajos Papp <lajos.papp@sequenceiq.com>\nLakshan Perera <lakshan@laktek.com>\nLalatendu Mohanty <lmohanty@redhat.com>\nLance Chen <cyen0312@gmail.com>\nLance Kinley <lkinley@loyaltymethods.com>\nLars Butler <Lars.Butler@gmail.com>\nLars Kellogg-Stedman <lars@redhat.com>\nLars R. Damerow <lars@pixar.com>\nLars-Magnus Skog <ralphtheninja@riseup.net>\nLaszlo Meszaros <lacienator@gmail.com>\nLaura Brehm <laurabrehm@hey.com>\nLaura Frank <ljfrank@gmail.com>\nLaurent Bernaille <laurent.bernaille@datadoghq.com>\nLaurent Erignoux <lerignoux@gmail.com>\nLaurie Voss <github@seldo.com>\nLeandro Motta Barros <lmb@stackedboxes.org>\nLeandro Siqueira <leandro.siqueira@gmail.com>\nLee Calcote <leecalcote@gmail.com>\nLee Chao <932819864@qq.com>\nLee, Meng-Han <sunrisedm4@gmail.com>\nLei Gong <lgong@alauda.io>\nLei Jitang <leijitang@huawei.com>\nLeiiwang <u2takey@gmail.com>\nLen Weincier <len@cloudafrica.net>\nLennie <github@consolejunkie.net>\nLeo Gallucci <elgalu3@gmail.com>\nLeonardo Nodari <me@leonardonodari.it>\nLeonardo Taccari <leot@NetBSD.org>\nLeszek Kowalski <github@leszekkowalski.pl>\nLevi Blackstone <levi.blackstone@rackspace.com>\nLevi Gross <levi@levigross.com>\nLevi Harrison <levisamuelharrison@gmail.com>\nLewis Daly <lewisdaly@me.com>\nLewis Marshall <lewis@lmars.net>\nLewis Peckover <lew+github@lew.io>\nLi Yi <denverdino@gmail.com>\nLiam Macgillavry <liam@kumina.nl>\nLiana Lo <liana.lixia@gmail.com>\nLiang Mingqiang <mqliang.zju@gmail.com>\nLiang-Chi Hsieh <viirya@gmail.com>\nliangwei <liangwei14@huawei.com>\nLiao Qingwei <liaoqingwei@huawei.com>\nLifubang <lifubang@acmcoder.com>\nLihua Tang <lhtang@alauda.io>\nLily Guo <lily.guo@docker.com>\nlimeidan <limeidan@loongson.cn>\nLin Lu <doraalin@163.com>\nLingFaKe <lingfake@huawei.com>\nLinus Heckemann <lheckemann@twig-world.com>\nLiran Tal <liran.tal@gmail.com>\nLiron Levin <liron@twistlock.com>\nLiu Bo <bo.li.liu@oracle.com>\nLiu Hua <sdu.liu@huawei.com>\nliwenqi <vikilwq@zju.edu.cn>\nlixiaobing10051267 <li.xiaobing1@zte.com.cn>\nLiz Zhang <lizzha@microsoft.com>\nLIZAO LI <lzlarryli@gmail.com>\nLizzie Dixon <_@lizzie.io>\nLloyd Dewolf <foolswisdom@gmail.com>\nLokesh Mandvekar <lsm5@fedoraproject.org>\nlongliqiang88 <394564827@qq.com>\nLorenz Leutgeb <lorenz.leutgeb@gmail.com>\nLorenzo Fontana <fontanalorenz@gmail.com>\nLotus Fenn <fenn.lotus@gmail.com>\nLouis Delossantos <ldelossa.ld@gmail.com>\nLouis Opter <kalessin@kalessin.fr>\nLuboslav Pivarc <lpivarc@redhat.com>\nLuca Favatella <luca.favatella@erlang-solutions.com>\nLuca Marturana <lucamarturana@gmail.com>\nLuca Orlandi <luca.orlandi@gmail.com>\nLuca-Bogdan Grigorescu <Luca-Bogdan Grigorescu>\nLucas Chan <lucas-github@lucaschan.com>\nLucas Chi <lucas@teacherspayteachers.com>\nLucas Molas <lmolas@fundacionsadosky.org.ar>\nLucas Silvestre <lukas.silvestre@gmail.com>\nLuciano Mores <leslau@gmail.com>\nLuis Henrique Mulinari <luis.mulinari@gmail.com>\nLuis Martínez de Bartolomé Izquierdo <lmartinez@biicode.com>\nLuiz Svoboda <luizek@gmail.com>\nLukas Heeren <lukas-heeren@hotmail.com>\nLukas Waslowski <cr7pt0gr4ph7@gmail.com>\nlukaspustina <lukas.pustina@centerdevice.com>\nLukasz Zajaczkowski <Lukasz.Zajaczkowski@ts.fujitsu.com>\nLuke Marsden <me@lukemarsden.net>\nLyn <energylyn@zju.edu.cn>\nLynda O'Leary <lyndaoleary29@gmail.com>\nLénaïc Huard <lhuard@amadeus.com>\nMa Müller <mueller-ma@users.noreply.github.com>\nMa Shimiao <mashimiao.fnst@cn.fujitsu.com>\nMabin <bin.ma@huawei.com>\nMadhan Raj Mookkandy <MadhanRaj.Mookkandy@microsoft.com>\nMadhav Puri <madhav.puri@gmail.com>\nMadhu Venugopal <mavenugo@gmail.com>\nMageee <fangpuyi@foxmail.com>\nMahesh Tiyyagura <tmahesh@gmail.com>\nmalnick <malnick@gmail..com>\nMalte Janduda <mail@janduda.net>\nManfred Touron <m@42.am>\nManfred Zabarauskas <manfredas@zabarauskas.com>\nManjunath A Kumatagi <mkumatag@in.ibm.com>\nMansi Nahar <mmn4185@rit.edu>\nManuel Meurer <manuel@krautcomputing.com>\nManuel Rüger <manuel@rueg.eu>\nManuel Woelker <github@manuel.woelker.org>\nmapk0y <mapk0y@gmail.com>\nMarat Radchenko <marat@slonopotamus.org>\nMarc Abramowitz <marc@marc-abramowitz.com>\nMarc Kuo <kuomarc2@gmail.com>\nMarc Tamsky <mtamsky@gmail.com>\nMarcel Edmund Franke <marcel.edmund.franke@gmail.com>\nMarcelo Horacio Fortino <info@fortinux.com>\nMarcelo Salazar <chelosalazar@gmail.com>\nMarco Hennings <marco.hennings@freiheit.com>\nMarcus Cobden <mcobden@cisco.com>\nMarcus Farkas <toothlessgear@finitebox.com>\nMarcus Linke <marcus.linke@gmx.de>\nMarcus Martins <marcus@docker.com>\nMarcus Ramberg <marcus@nordaaker.com>\nMarek Goldmann <marek.goldmann@gmail.com>\nMarian Marinov <mm@yuhu.biz>\nMarianna Tessel <mtesselh@gmail.com>\nMario Loriedo <mario.loriedo@gmail.com>\nMarius Gundersen <me@mariusgundersen.net>\nMarius Sturm <marius@graylog.com>\nMarius Voila <marius.voila@gmail.com>\nMark Allen <mrallen1@yahoo.com>\nMark Feit <mfeit@internet2.edu>\nMark Jeromin <mark.jeromin@sysfrog.net>\nMark McGranaghan <mmcgrana@gmail.com>\nMark McKinstry <mmckinst@umich.edu>\nMark Milstein <mark@epiloque.com>\nMark Oates <fl0yd@me.com>\nMark Parker <godefroi@users.noreply.github.com>\nMark Vainomaa <mikroskeem@mikroskeem.eu>\nMark West <markewest@gmail.com>\nMarkan Patel <mpatel678@gmail.com>\nMarko Mikulicic <mmikulicic@gmail.com>\nMarko Tibold <marko@tibold.nl>\nMarkus Fix <lispmeister@gmail.com>\nMarkus Kortlang <hyp3rdino@googlemail.com>\nMartijn Dwars <ikben@martijndwars.nl>\nMartijn van Oosterhout <kleptog@svana.org>\nMartin Braun <braun@neuroforge.de>\nMartin Dojcak <martin.dojcak@lablabs.io>\nMartin Honermeyer <maze@strahlungsfrei.de>\nMartin Jirku <martin@jirku.sk>\nMartin Kelly <martin@surround.io>\nMartin Mosegaard Amdisen <martin.amdisen@praqma.com>\nMartin Muzatko <martin@happy-css.com>\nMartin Redmond <redmond.martin@gmail.com>\nMaru Newby <mnewby@thesprawl.net>\nMary Anthony <mary.anthony@docker.com>\nMasahito Zembutsu <zembutsu@users.noreply.github.com>\nMasato Ohba <over.rye@gmail.com>\nMasayuki Morita <minamijoyo@gmail.com>\nMason Malone <mason.malone@gmail.com>\nMateusz Sulima <sulima.mateusz@gmail.com>\nMathias Monnerville <mathias@monnerville.com>\nMathieu Champlon <mathieu.champlon@docker.com>\nMathieu Le Marec - Pasquet <kiorky@cryptelium.net>\nMathieu Parent <math.parent@gmail.com>\nMathieu Paturel <mathieu.paturel@gmail.com>\nMatt Apperson <me@mattapperson.com>\nMatt Bachmann <bachmann.matt@gmail.com>\nMatt Bajor <matt@notevenremotelydorky.com>\nMatt Bentley <matt.bentley@docker.com>\nMatt Haggard <haggardii@gmail.com>\nMatt Hoyle <matt@deployable.co>\nMatt McCormick <matt.mccormick@kitware.com>\nMatt Moore <mattmoor@google.com>\nMatt Morrison <3maven@gmail.com>\nMatt Richardson <matt@redgumtech.com.au>\nMatt Rickard <mrick@google.com>\nMatt Robenolt <matt@ydekproductions.com>\nMatt Schurenko <matt.schurenko@gmail.com>\nMatt Williams <mattyw@me.com>\nMatthew Heon <mheon@redhat.com>\nMatthew Lapworth <matthewl@bit-shift.net>\nMatthew Mayer <matthewkmayer@gmail.com>\nMatthew Mosesohn <raytrac3r@gmail.com>\nMatthew Mueller <mattmuelle@gmail.com>\nMatthew Riley <mattdr@google.com>\nMatthias Klumpp <matthias@tenstral.net>\nMatthias Kühnle <git.nivoc@neverbox.com>\nMatthias Rampke <mr@soundcloud.com>\nMatthieu Fronton <m@tthieu.fr>\nMatthieu Hauglustaine <matt.hauglustaine@gmail.com>\nMattias Jernberg <nostrad@gmail.com>\nMauricio Garavaglia <mauricio@medallia.com>\nmauriyouth <mauriyouth@gmail.com>\nMax Harmathy <max.harmathy@web.de>\nMax Shytikov <mshytikov@gmail.com>\nMax Timchenko <maxvt@pagerduty.com>\nMaxim Fedchyshyn <sevmax@gmail.com>\nMaxim Ivanov <ivanov.maxim@gmail.com>\nMaxim Kulkin <mkulkin@mirantis.com>\nMaxim Treskin <zerthurd@gmail.com>\nMaxime Petazzoni <max@signalfuse.com>\nMaximiliano Maccanti <maccanti@amazon.com>\nMaxwell <csuhp007@gmail.com>\nMeaglith Ma <genedna@gmail.com>\nmeejah <meejah@meejah.ca>\nMegan Kostick <mkostick@us.ibm.com>\nMehul Kar <mehul.kar@gmail.com>\nMei ChunTao <mei.chuntao@zte.com.cn>\nMengdi Gao <usrgdd@gmail.com>\nMenghui Chen <menghui.chen@alibaba-inc.com>\nMert Yazıcıoğlu <merty@users.noreply.github.com>\nmgniu <mgniu@dataman-inc.com>\nMicah Zoltu <micah@newrelic.com>\nMichael A. Smith <michael@smith-li.com>\nMichael Beskin <mrbeskin@gmail.com>\nMichael Bridgen <mikeb@squaremobius.net>\nMichael Brown <michael@netdirect.ca>\nMichael Chiang <mchiang@docker.com>\nMichael Crosby <crosbymichael@gmail.com>\nMichael Currie <mcurrie@bruceforceresearch.com>\nMichael Friis <friism@gmail.com>\nMichael Gorsuch <gorsuch@github.com>\nMichael Grauer <michael.grauer@kitware.com>\nMichael Holzheu <holzheu@linux.vnet.ibm.com>\nMichael Hudson-Doyle <michael.hudson@canonical.com>\nMichael Huettermann <michael@huettermann.net>\nMichael Irwin <mikesir87@gmail.com>\nMichael Kebe <michael.kebe@hkm.de>\nMichael Kuehn <micha@kuehn.io>\nMichael Käufl <docker@c.michael-kaeufl.de>\nMichael Neale <michael.neale@gmail.com>\nMichael Nussbaum <michael.nussbaum@getbraintree.com>\nMichael Prokop <github@michael-prokop.at>\nMichael Scharf <github@scharf.gr>\nMichael Spetsiotis <michael_spets@hotmail.com>\nMichael Stapelberg <michael+gh@stapelberg.de>\nMichael Steinert <mike.steinert@gmail.com>\nMichael Thies <michaelthies78@gmail.com>\nMichael Weidmann <michaelweidmann@web.de>\nMichael West <mwest@mdsol.com>\nMichael Zhao <michael.zhao@arm.com>\nMichal Fojtik <mfojtik@redhat.com>\nMichal Gebauer <mishak@mishak.net>\nMichal Jemala <michal.jemala@gmail.com>\nMichal Kostrzewa <michal.kostrzewa@codilime.com>\nMichal Minář <miminar@redhat.com>\nMichal Rostecki <mrostecki@opensuse.org>\nMichal Wieczorek <wieczorek-michal@wp.pl>\nMichaël Pailloncy <mpapo.dev@gmail.com>\nMichał Czeraszkiewicz <czerasz@gmail.com>\nMichał Gryko <github@odkurzacz.org>\nMichał Kosek <mihao@users.noreply.github.com>\nMichiel de Jong <michiel@unhosted.org>\nMickaël Fortunato <morsi.morsicus@gmail.com>\nMickaël Remars <mickael@remars.com>\nMiguel Angel Fernández <elmendalerenda@gmail.com>\nMiguel Morales <mimoralea@gmail.com>\nMiguel Perez <miguel@voyat.com>\nMihai Borobocea <MihaiBorob@gmail.com>\nMihuleacc Sergiu <mihuleac.sergiu@gmail.com>\nMikael Davranche <mikael.davranche@corp.ovh.com>\nMike Brown <brownwm@us.ibm.com>\nMike Bush <mpbush@gmail.com>\nMike Casas <mkcsas0@gmail.com>\nMike Chelen <michael.chelen@gmail.com>\nMike Danese <mikedanese@google.com>\nMike Dillon <mike@embody.org>\nMike Dougherty <mike.dougherty@docker.com>\nMike Estes <mike.estes@logos.com>\nMike Gaffney <mike@uberu.com>\nMike Goelzer <mike.goelzer@docker.com>\nMike Leone <mleone896@gmail.com>\nMike Lundy <mike@fluffypenguin.org>\nMike MacCana <mike.maccana@gmail.com>\nMike Naberezny <mike@naberezny.com>\nMike Snitzer <snitzer@redhat.com>\nMike Sul <mike.sul@foundries.io>\nmikelinjie <294893458@qq.com>\nMikhail Sobolev <mss@mawhrin.net>\nMiklos Szegedi <miklos.szegedi@cloudera.com>\nMilas Bowman <devnull@milas.dev>\nMilind Chawre <milindchawre@gmail.com>\nMiloslav Trmač <mitr@redhat.com>\nmingqing <limingqing@cyou-inc.com>\nMingzhen Feng <fmzhen@zju.edu.cn>\nMisty Stanley-Jones <misty@docker.com>\nMitch Capper <mitch.capper@gmail.com>\nMizuki Urushida <z11111001011@gmail.com>\nmlarcher <github@ringabell.org>\nMohammad Banikazemi <MBanikazemi@gmail.com>\nMohammad Nasirifar <farnasirim@gmail.com>\nMohammed Aaqib Ansari <maaquib@gmail.com>\nMohd Sadiq <mohdsadiq058@gmail.com>\nMohit Soni <mosoni@ebay.com>\nMoorthy RS <rsmoorthy@gmail.com>\nMorgan Bauer <mbauer@us.ibm.com>\nMorgante Pell <morgante.pell@morgante.net>\nMorgy93 <thomas@ulfertsprygoda.de>\nMorten Siebuhr <sbhr@sbhr.dk>\nMorton Fox <github@qslw.com>\nMoysés Borges <moysesb@gmail.com>\nmrfly <mr.wrfly@gmail.com>\nMrunal Patel <mrunalp@gmail.com>\nMuayyad Alsadi <alsadi@gmail.com>\nMuhammad Zohaib Aslam <zohaibse011@gmail.com>\nMustafa Akın <mustafa91@gmail.com>\nMuthukumar R <muthur@gmail.com>\nMáximo Cuadros <mcuadros@gmail.com>\nMédi-Rémi Hashim <medimatrix@users.noreply.github.com>\nNace Oroz <orkica@gmail.com>\nNahum Shalman <nshalman@omniti.com>\nNakul Pathak <nakulpathak3@hotmail.com>\nNalin Dahyabhai <nalin@redhat.com>\nNan Monnand Deng <monnand@gmail.com>\nNaoki Orii <norii@cs.cmu.edu>\nNatalie Parker <nparker@omnifone.com>\nNatanael Copa <natanael.copa@docker.com>\nNatasha Jarus <linuxmercedes@gmail.com>\nNate Brennand <nate.brennand@clever.com>\nNate Eagleson <nate@nateeag.com>\nNate Jones <nate@endot.org>\nNathan Carlson <carl4403@umn.edu>\nNathan Herald <me@nathanherald.com>\nNathan Hsieh <hsieh.nathan@gmail.com>\nNathan Kleyn <nathan@nathankleyn.com>\nNathan LeClaire <nathan.leclaire@docker.com>\nNathan McCauley <nathan.mccauley@docker.com>\nNathan Williams <nathan@teamtreehouse.com>\nNaveed Jamil <naveed.jamil@tenpearls.com>\nNeal McBurnett <neal@mcburnett.org>\nNeil Horman <nhorman@tuxdriver.com>\nNeil Peterson <neilpeterson@outlook.com>\nNelson Chen <crazysim@gmail.com>\nNeyazul Haque <nuhaque@gmail.com>\nNghia Tran <nghia@google.com>\nNiall O'Higgins <niallo@unworkable.org>\nNicholas E. Rabenau <nerab@gmx.at>\nNick Adcock <nick.adcock@docker.com>\nNick DeCoursin <n.decoursin@foodpanda.com>\nNick Irvine <nfirvine@nfirvine.com>\nNick Neisen <nwneisen@gmail.com>\nNick Parker <nikaios@gmail.com>\nNick Payne <nick@kurai.co.uk>\nNick Russo <nicholasjamesrusso@gmail.com>\nNick Santos <nick.santos@docker.com>\nNick Stenning <nick.stenning@digital.cabinet-office.gov.uk>\nNick Stinemates <nick@stinemates.org>\nNick Wood <nwood@microsoft.com>\nNickrenREN <yuquan.ren@easystack.cn>\nNicola Kabar <nicolaka@gmail.com>\nNicolas Borboën <ponsfrilus@gmail.com>\nNicolas De Loof <nicolas.deloof@gmail.com>\nNicolas Dudebout <nicolas.dudebout@gatech.edu>\nNicolas Goy <kuon@goyman.com>\nNicolas Kaiser <nikai@nikai.net>\nNicolas Sterchele <sterchele.nicolas@gmail.com>\nNicolas V Castet <nvcastet@us.ibm.com>\nNicolás Hock Isaza <nhocki@gmail.com>\nNiel Drummond <niel@drummond.lu>\nNigel Poulton <nigelpoulton@hotmail.com>\nNik Nyby <nikolas@gnu.org>\nNikhil Chawla <chawlanikhil24@gmail.com>\nNikolaMandic <mn080202@gmail.com>\nNikolas Garofil <nikolas.garofil@uantwerpen.be>\nNikolay Edigaryev <edigaryev@gmail.com>\nNikolay Milovanov <nmil@itransformers.net>\nningmingxiao <ning.mingxiao@zte.com.cn>\nNirmal Mehta <nirmalkmehta@gmail.com>\nNishant Totla <nishanttotla@gmail.com>\nNIWA Hideyuki <niwa.niwa@nifty.ne.jp>\nNoah Meyerhans <nmeyerha@amazon.com>\nNoah Treuhaft <noah.treuhaft@docker.com>\nNobodyOnSE <ich@sektor.selfip.com>\nnoducks <onemannoducks@gmail.com>\nNolan Darilek <nolan@thewordnerd.info>\nNolan Miles <nolanpmiles@gmail.com>\nNoriki Nakamura <noriki.nakamura@miraclelinux.com>\nnponeccop <andy.melnikov@gmail.com>\nNurahmadie <nurahmadie@gmail.com>\nNuutti Kotivuori <naked@iki.fi>\nnzwsch <hi@nzwsch.com>\nO.S. Tezer <ostezer@gmail.com>\nobjectified <objectified@gmail.com>\nOdin Ugedal <odin@ugedal.com>\nOguz Bilgic <fisyonet@gmail.com>\nOh Jinkyun <tintypemolly@gmail.com>\nOhad Schneider <ohadschn@users.noreply.github.com>\nohmystack <jun.jiang02@ele.me>\nOle Reifschneider <mail@ole-reifschneider.de>\nOliver Neal <ItsVeryWindy@users.noreply.github.com>\nOliver Reason <oli@overrateddev.co>\nOlivier Gambier <dmp42@users.noreply.github.com>\nOlle Jonsson <olle.jonsson@gmail.com>\nOlli Janatuinen <olli.janatuinen@gmail.com>\nOlly Pomeroy <oppomeroy@gmail.com>\nOmri Shiv <Omri.Shiv@teradata.com>\nOnur Filiz <onur.filiz@microsoft.com>\nOriol Francès <oriolfa@gmail.com>\nOscar Bonilla <6f6231@gmail.com>\noscar.chen <2972789494@qq.com>\nOskar Niburski <oskarniburski@gmail.com>\nOtto Kekäläinen <otto@seravo.fi>\nOuyang Liduo <oyld0210@163.com>\nOvidio Mallo <ovidio.mallo@gmail.com>\nPanagiotis Moustafellos <pmoust@elastic.co>\nPaolo G. Giarrusso <p.giarrusso@gmail.com>\nPascal <pascalgn@users.noreply.github.com>\nPascal Bach <pascal.bach@siemens.com>\nPascal Borreli <pascal@borreli.com>\nPascal Hartig <phartig@rdrei.net>\nPatrick Böänziger <patrick.baenziger@bsi-software.com>\nPatrick Devine <patrick.devine@docker.com>\nPatrick Haas <patrickhaas@google.com>\nPatrick Hemmer <patrick.hemmer@gmail.com>\nPatrick Stapleton <github@gdi2290.com>\nPatrik Cyvoct <patrik@ptrk.io>\npattichen <craftsbear@gmail.com>\nPaul \"TBBle\" Hampson <Paul.Hampson@Pobox.com>\nPaul <paul9869@gmail.com>\npaul <paul@inkling.com>\nPaul Annesley <paul@annesley.cc>\nPaul Bellamy <paul.a.bellamy@gmail.com>\nPaul Bowsher <pbowsher@globalpersonals.co.uk>\nPaul Furtado <pfurtado@hubspot.com>\nPaul Hammond <paul@paulhammond.org>\nPaul Jimenez <pj@place.org>\nPaul Kehrer <paul.l.kehrer@gmail.com>\nPaul Lietar <paul@lietar.net>\nPaul Liljenberg <liljenberg.paul@gmail.com>\nPaul Morie <pmorie@gmail.com>\nPaul Nasrat <pnasrat@gmail.com>\nPaul Seiffert <paul.seiffert@jimdo.com>\nPaul Weaver <pauweave@cisco.com>\nPaulo Gomes <pjbgf@linux.com>\nPaulo Ribeiro <paigr.io@gmail.com>\nPavel Lobashov <ShockwaveNN@gmail.com>\nPavel Matěja <pavel@verotel.cz>\nPavel Pletenev <cpp.create@gmail.com>\nPavel Pospisil <pospispa@gmail.com>\nPavel Sutyrin <pavel.sutyrin@gmail.com>\nPavel Tikhomirov <ptikhomirov@virtuozzo.com>\nPavlos Ratis <dastergon@gentoo.org>\nPavol Vargovcik <pallly.vargovcik@gmail.com>\nPawel Konczalski <mail@konczalski.de>\nPaweł Gronowski <pawel.gronowski@docker.com>\npayall4u <payall4u@qq.com>\nPeeyush Gupta <gpeeyush@linux.vnet.ibm.com>\nPeggy Li <peggyli.224@gmail.com>\nPei Su <sillyousu@gmail.com>\nPeng Tao <bergwolf@gmail.com>\nPenghan Wang <ph.wang@daocloud.io>\nPer Weijnitz <per.weijnitz@gmail.com>\nperhapszzy@sina.com <perhapszzy@sina.com>\nPete Woods <pete.woods@circleci.com>\nPeter Bourgon <peter@bourgon.org>\nPeter Braden <peterbraden@peterbraden.co.uk>\nPeter Bücker <peter.buecker@pressrelations.de>\nPeter Choi <phkchoi89@gmail.com>\nPeter Dave Hello <hsu@peterdavehello.org>\nPeter Edge <peter.edge@gmail.com>\nPeter Ericson <pdericson@gmail.com>\nPeter Esbensen <pkesbensen@gmail.com>\nPeter Jaffe <pjaffe@nevo.com>\nPeter Kang <peter@spell.run>\nPeter Malmgren <ptmalmgren@gmail.com>\nPeter Salvatore <peter@psftw.com>\nPeter Volpe <petervo@redhat.com>\nPeter Waller <p@pwaller.net>\nPetr Švihlík <svihlik.petr@gmail.com>\nPetros Angelatos <petrosagg@gmail.com>\nPhil <underscorephil@gmail.com>\nPhil Estes <estesp@gmail.com>\nPhil Sphicas <phil.sphicas@att.com>\nPhil Spitler <pspitler@gmail.com>\nPhilip Alexander Etling <paetling@gmail.com>\nPhilip K. Warren <pkwarren@gmail.com>\nPhilip Monroe <phil@philmonroe.com>\nPhilipp Fruck <dev@p-fruck.de>\nPhilipp Gillé <philipp.gille@gmail.com>\nPhilipp Wahala <philipp.wahala@gmail.com>\nPhilipp Weissensteiner <mail@philippweissensteiner.com>\nPhillip Alexander <git@phillipalexander.io>\nphineas <phin@phineas.io>\npidster <pid@pidster.com>\nPiergiuliano Bossi <pgbossi@gmail.com>\nPierre <py@poujade.org>\nPierre Carrier <pierre@meteor.com>\nPierre Dal-Pra <dalpra.pierre@gmail.com>\nPierre Wacrenier <pierre.wacrenier@gmail.com>\nPierre-Alain RIVIERE <pariviere@ippon.fr>\nPiotr Bogdan <ppbogdan@gmail.com>\nPiotr Karbowski <piotr.karbowski@protonmail.ch>\nPorjo <porjo38@yahoo.com.au>\nPoul Kjeldager Sørensen <pks@s-innovations.net>\nPradeep Chhetri <pradeep@indix.com>\nPradip Dhara <pradipd@microsoft.com>\nPradipta Kr. Banerjee <bpradip@in.ibm.com>\nPrasanna Gautam <prasannagautam@gmail.com>\nPratik Karki <prertik@outlook.com>\nPrayag Verma <prayag.verma@gmail.com>\nPriya Wadhwa <priyawadhwa@google.com>\nProjjol Banerji <probaner23@gmail.com>\nPrzemek Hejman <przemyslaw.hejman@gmail.com>\nPuneet Pruthi <puneet.pruthi@oracle.com>\nPure White <daniel48@126.com>\npysqz <randomq@126.com>\nQiang Huang <h.huangqiang@huawei.com>\nQin TianHuan <tianhuan@bingotree.cn>\nQinglan Peng <qinglanpeng@zju.edu.cn>\nQuan Tian <tianquan@cloudin.cn>\nqudongfang <qudongfang@gmail.com>\nQuentin Brossard <qbrossard@gmail.com>\nQuentin Perez <qperez@ocs.online.net>\nQuentin Tayssier <qtayssier@gmail.com>\nr0n22 <cameron.regan@gmail.com>\nRachit Sharma <rachitsharma613@gmail.com>\nRadostin Stoyanov <rstoyanov1@gmail.com>\nRafal Jeczalik <rjeczalik@gmail.com>\nRafe Colton <rafael.colton@gmail.com>\nRaghavendra K T <raghavendra.kt@linux.vnet.ibm.com>\nRaghuram Devarakonda <draghuram@gmail.com>\nRaja Sami <raja.sami@tenpearls.com>\nRajat Pandit <rp@rajatpandit.com>\nRajdeep Dua <dua_rajdeep@yahoo.com>\nRalf Sippl <ralf.sippl@gmail.com>\nRalle <spam@rasmusa.net>\nRalph Bean <rbean@redhat.com>\nRamkumar Ramachandra <artagnon@gmail.com>\nRamon Brooker <rbrooker@aetherealmind.com>\nRamon van Alteren <ramon@vanalteren.nl>\nRaviTeja Pothana <ravi-teja@live.com>\nRay Tsang <rayt@google.com>\nReadmeCritic <frankensteinbot@gmail.com>\nrealityone <realityone@me.com>\nRecursive Madman <recursive.madman@gmx.de>\nReficul <xuzhenglun@gmail.com>\nRegan McCooey <rmccooey27@aol.com>\nRemi Rampin <remirampin@gmail.com>\nRemy Suen <remy.suen@gmail.com>\nRenato Riccieri Santos Zannon <renato.riccieri@gmail.com>\nRenaud Gaubert <rgaubert@nvidia.com>\nRhys Hiltner <rhys@twitch.tv>\nRi Xu <xuri.me@gmail.com>\nRicardo N Feliciano <FelicianoTech@gmail.com>\nRich Horwood <rjhorwood@apple.com>\nRich Moyse <rich@moyse.us>\nRich Seymour <rseymour@gmail.com>\nRichard Burnison <rburnison@ebay.com>\nRichard Hansen <rhansen@rhansen.org>\nRichard Harvey <richard@squarecows.com>\nRichard Mathie <richard.mathie@amey.co.uk>\nRichard Metzler <richard@paadee.com>\nRichard Scothern <richard.scothern@gmail.com>\nRicho Healey <richo@psych0tik.net>\nRick Bradley <rick@users.noreply.github.com>\nRick van de Loo <rickvandeloo@gmail.com>\nRick Wieman <git@rickw.nl>\nRik Nijessen <rik@keefo.nl>\nRiku Voipio <riku.voipio@linaro.org>\nRiley Guerin <rileytg.dev@gmail.com>\nRitesh H Shukla <sritesh@vmware.com>\nRiyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>\nRob Cowsill <42620235+rcowsill@users.noreply.github.com>\nRob Gulewich <rgulewich@netflix.com>\nRob Murray <rob.murray@docker.com>\nRob Vesse <rvesse@dotnetrdf.org>\nRobert Bachmann <rb@robertbachmann.at>\nRobert Bittle <guywithnose@gmail.com>\nRobert Obryk <robryk@gmail.com>\nRobert Schneider <mail@shakeme.info>\nRobert Shade <robert.shade@gmail.com>\nRobert Stern <lexandro2000@gmail.com>\nRobert Terhaar <rterhaar@atlanticdynamic.com>\nRobert Wallis <smilingrob@gmail.com>\nRobert Wang <robert@arctic.tw>\nRoberto G. Hashioka <roberto.hashioka@docker.com>\nRoberto Muñoz Fernández <robertomf@gmail.com>\nRobin Naundorf <r.naundorf@fh-muenster.de>\nRobin Schneider <ypid@riseup.net>\nRobin Speekenbrink <robin@kingsquare.nl>\nRobin Thoni <robin@rthoni.com>\nrobpc <rpcann@gmail.com>\nRodolfo Carvalho <rhcarvalho@gmail.com>\nRodrigo Campos <rodrigo@kinvolk.io>\nRodrigo Vaz <rodrigo.vaz@gmail.com>\nRoel Van Nyen <roel.vannyen@gmail.com>\nRoger Peppe <rogpeppe@gmail.com>\nRohit Jnagal <jnagal@google.com>\nRohit Kadam <rohit.d.kadam@gmail.com>\nRohit Kapur <rkapur@flatiron.com>\nRojin George <rojingeorge@huawei.com>\nRoland Huß <roland@jolokia.org>\nRoland Kammerer <roland.kammerer@linbit.com>\nRoland Moriz <rmoriz@users.noreply.github.com>\nRoma Sokolov <sokolov.r.v@gmail.com>\nRoman Dudin <katrmr@gmail.com>\nRoman Mazur <roman@balena.io>\nRoman Strashkin <roman.strashkin@gmail.com>\nRoman Volosatovs <roman.volosatovs@docker.com>\nRoman Zabaluev <gpg@haarolean.dev>\nRon Smits <ron.smits@gmail.com>\nRon Williams <ron.a.williams@gmail.com>\nRong Gao <gaoronggood@163.com>\nRong Zhang <rongzhang@alauda.io>\nRongxiang Song <tinysong1226@gmail.com>\nRony Weng <ronyweng@synology.com>\nroot <docker-dummy@example.com>\nroot <root@lxdebmas.marist.edu>\nroot <root@ubuntu-14.04-amd64-vbox>\nroot <root@webm215.cluster016.ha.ovh.net>\nRory Hunter <roryhunter2@gmail.com>\nRory McCune <raesene@gmail.com>\nRoss Boucher <rboucher@gmail.com>\nRovanion Luckey <rovanion.luckey@gmail.com>\nRoy Reznik <roy@wiz.io>\nRoyce Remer <royceremer@gmail.com>\nRozhnov Alexandr <nox73@ya.ru>\nRudolph Gottesheim <r.gottesheim@loot.at>\nRui Cao <ruicao@alauda.io>\nRui Lopes <rgl@ruilopes.com>\nRuilin Li <liruilin4@huawei.com>\nRunshen Zhu <runshen.zhu@gmail.com>\nRuss Magee <rmagee@gmail.com>\nRyan Abrams <rdabrams@gmail.com>\nRyan Anderson <anderson.ryanc@gmail.com>\nRyan Aslett <github@mixologic.com>\nRyan Barry <rbarry@mirantis.com>\nRyan Belgrave <rmb1993@gmail.com>\nRyan Campbell <campbellr@gmail.com>\nRyan Detzel <ryan.detzel@gmail.com>\nRyan Fowler <rwfowler@gmail.com>\nRyan Liu <ryanlyy@me.com>\nRyan McLaughlin <rmclaughlin@insidesales.com>\nRyan O'Donnell <odonnellryanc@gmail.com>\nRyan Seto <ryanseto@yak.net>\nRyan Shea <sheabot03@gmail.com>\nRyan Simmen <ryan.simmen@gmail.com>\nRyan Stelly <ryan.stelly@live.com>\nRyan Thomas <rthomas@atlassian.com>\nRyan Trauntvein <rtrauntvein@novacoast.com>\nRyan Wallner <ryan.wallner@clusterhq.com>\nRyan Zhang <ryan.zhang@docker.com>\nryancooper7 <ryan.cooper7@gmail.com>\nRyanDeng <sheldon.d1018@gmail.com>\nRyo Nakao <nakabonne@gmail.com>\nRyoga Saito <contact@proelbtn.com>\nRégis Behmo <regis@behmo.com>\nRémy Greinhofer <remy.greinhofer@livelovely.com>\ns. rannou <mxs@sbrk.org>\nSabin Basyal <sabin.basyal@gmail.com>\nSachin Joshi <sachin_jayant_joshi@hotmail.com>\nSagar Hani <sagarhani33@gmail.com>\nSainath Grandhi <sainath.grandhi@intel.com>\nSakeven Jiang <jc5930@sina.cn>\nSalahuddin Khan <salah@docker.com>\nSally O'Malley <somalley@redhat.com>\nSam Abed <sam.abed@gmail.com>\nSam Alba <sam.alba@gmail.com>\nSam Bailey <cyprix@cyprix.com.au>\nSam J Sharpe <sam.sharpe@digital.cabinet-office.gov.uk>\nSam Neirinck <sam@samneirinck.com>\nSam Reis <sreis@atlassian.com>\nSam Rijs <srijs@airpost.net>\nSam Thibault <sam.thibault@docker.com>\nSam Whited <sam@samwhited.com>\nSambuddha Basu <sambuddhabasu1@gmail.com>\nSami Wagiaalla <swagiaal@redhat.com>\nSamuel Andaya <samuel@andaya.net>\nSamuel Dion-Girardeau <samuel.diongirardeau@gmail.com>\nSamuel Karp <me@samuelkarp.com>\nSamuel PHAN <samuel-phan@users.noreply.github.com>\nsanchayanghosh <sanchayanghosh@outlook.com>\nSandeep Bansal <sabansal@microsoft.com>\nSankar சங்கர் <sankar.curiosity@gmail.com>\nSanket Saurav <sanketsaurav@gmail.com>\nSanthosh Manohar <santhosh@docker.com>\nsapphiredev <se.imas.kr@gmail.com>\nSargun Dhillon <sargun@netflix.com>\nSascha Andres <sascha.andres@outlook.com>\nSascha Grunert <sgrunert@suse.com>\nSataQiu <qiushida@beyondcent.com>\nSatnam Singh <satnam@raintown.org>\nSatoshi Amemiya <satoshi_amemiya@voyagegroup.com>\nSatoshi Tagomori <tagomoris@gmail.com>\nScott Bessler <scottbessler@gmail.com>\nScott Collier <emailscottcollier@gmail.com>\nScott Johnston <scott@docker.com>\nScott Moser <smoser@brickies.net>\nScott Percival <scottp@lastyard.com>\nScott Stamp <scottstamp851@gmail.com>\nScott Walls <sawalls@umich.edu>\nsdreyesg <sdreyesg@gmail.com>\nSean Christopherson <sean.j.christopherson@intel.com>\nSean Cronin <seancron@gmail.com>\nSean Lee <seanlee@tw.ibm.com>\nSean McIntyre <s.mcintyre@xverba.ca>\nSean OMeara <sean@chef.io>\nSean P. Kane <skane@newrelic.com>\nSean Rodman <srodman7689@gmail.com>\nSebastiaan van Steenis <mail@superseb.nl>\nSebastiaan van Stijn <github@gone.nl>\nSebastian Höffner <sebastian.hoeffner@mevis.fraunhofer.de>\nSebastian Radloff <sradloff23@gmail.com>\nSebastian Thomschke <sebthom@users.noreply.github.com>\nSebastien Goasguen <runseb@gmail.com>\nSenthil Kumar Selvaraj <senthil.thecoder@gmail.com>\nSenthil Kumaran <senthil@uthcode.com>\nSeongJae Park <sj38.park@gmail.com>\nSeongyeol Lim <seongyeol37@gmail.com>\nSerge Hallyn <serge.hallyn@ubuntu.com>\nSergey Alekseev <sergey.alekseev.minsk@gmail.com>\nSergey Evstifeev <sergey.evstifeev@gmail.com>\nSergii Kabashniuk <skabashnyuk@codenvy.com>\nSergio Lopez <slp@redhat.com>\nSerhat Gülçiçek <serhat25@gmail.com>\nSeungUkLee <lsy931106@gmail.com>\nSevki Hasirci <s@sevki.org>\nShane Canon <scanon@lbl.gov>\nShane da Silva <shane@dasilva.io>\nShaun Kaasten <shaunk@gmail.com>\nshaunol <shaunol@gmail.com>\nShawn Landden <shawn@churchofgit.com>\nShawn Siefkas <shawn.siefkas@meredith.com>\nshawnhe <shawnhe@shawnhedeMacBook-Pro.local>\nShayan Pooya <shayan@liveve.org>\nShayne Wang <shaynexwang@gmail.com>\nShekhar Gulati <shekhargulati84@gmail.com>\nSheng Yang <sheng@yasker.org>\nShengbo Song <thomassong@tencent.com>\nShengjing Zhu <zhsj@debian.org>\nShev Yan <yandong_8212@163.com>\nShih-Yuan Lee <fourdollars@gmail.com>\nShihao Xia <charlesxsh@hotmail.com>\nShijiang Wei <mountkin@gmail.com>\nShijun Qin <qinshijun16@mails.ucas.ac.cn>\nShishir Mahajan <shishir.mahajan@redhat.com>\nShoubhik Bose <sbose78@gmail.com>\nShourya Sarcar <shourya.sarcar@gmail.com>\nShu-Wai Chow <shu-wai.chow@seattlechildrens.org>\nshuai-z <zs.broccoli@gmail.com>\nShukui Yang <yangshukui@huawei.com>\nSian Lerk Lau <kiawin@gmail.com>\nSiarhei Rasiukevich <s_rasiukevich@wargaming.net>\nSidhartha Mani <sidharthamn@gmail.com>\nsidharthamani <sid@rancher.com>\nSilas Sewell <silas@sewell.org>\nSilvan Jegen <s.jegen@gmail.com>\nSimão Reis <smnrsti@gmail.com>\nSimon Barendse <simon.barendse@gmail.com>\nSimon Eskildsen <sirup@sirupsen.com>\nSimon Ferquel <simon.ferquel@docker.com>\nSimon Leinen <simon.leinen@gmail.com>\nSimon Menke <simon.menke@gmail.com>\nSimon Taranto <simon.taranto@gmail.com>\nSimon Vikstrom <pullreq@devsn.se>\nSindhu S <sindhus@live.in>\nSjoerd Langkemper <sjoerd-github@linuxonly.nl>\nskanehira <sho19921005@gmail.com>\nSmark Meng <smark@freecoop.net>\nSolganik Alexander <solganik@gmail.com>\nSolomon Hykes <solomon@docker.com>\nSong Gao <song@gao.io>\nSoshi Katsuta <soshi.katsuta@gmail.com>\nSotiris Salloumis <sotiris.salloumis@gmail.com>\nSoulou <leo@unbekandt.eu>\nSpencer Brown <spencer@spencerbrown.org>\nSpencer Smith <robertspencersmith@gmail.com>\nSpike Curtis <spike.curtis@metaswitch.com>\nSridatta Thatipamala <sthatipamala@gmail.com>\nSridhar Ratnakumar <sridharr@activestate.com>\nSrini Brahmaroutu <srbrahma@us.ibm.com>\nSrinivasan Srivatsan <srinivasan.srivatsan@hpe.com>\nStaf Wagemakers <staf@wagemakers.be>\nStanislav Bondarenko <stanislav.bondarenko@gmail.com>\nStanislav Levin <slev@altlinux.org>\nSteeve Morin <steeve.morin@gmail.com>\nStefan Berger <stefanb@linux.vnet.ibm.com>\nStefan Gehrig <stefan.gehrig.hn@googlemail.com>\nStefan J. Wernli <swernli@microsoft.com>\nStefan Praszalowicz <stefan@greplin.com>\nStefan S. <tronicum@user.github.com>\nStefan Scherer <stefan.scherer@docker.com>\nStefan Staudenmeyer <doerte@instana.com>\nStefan Weil <sw@weilnetz.de>\nSteffen Butzer <steffen.butzer@outlook.com>\nStephan Henningsen <stephan-henningsen@users.noreply.github.com>\nStephan Spindler <shutefan@gmail.com>\nStephen Benjamin <stephen@redhat.com>\nStephen Crosby <stevecrozz@gmail.com>\nStephen Day <stevvooe@gmail.com>\nStephen Drake <stephen@xenolith.net>\nStephen Rust <srust@blockbridge.com>\nSteve Desmond <steve@vtsv.ca>\nSteve Dougherty <steve@asksteved.com>\nSteve Durrheimer <s.durrheimer@gmail.com>\nSteve Francia <steve.francia@gmail.com>\nSteve Koch <stevekochscience@gmail.com>\nSteven Burgess <steven.a.burgess@hotmail.com>\nSteven Erenst <stevenerenst@gmail.com>\nSteven Hartland <steven.hartland@multiplay.co.uk>\nSteven Iveson <sjiveson@outlook.com>\nSteven Merrill <steven.merrill@gmail.com>\nSteven Richards <steven@axiomzen.co>\nSteven Taylor <steven.taylor@me.com>\nStéphane Este-Gracias <sestegra@gmail.com>\nStig Larsson <stig@larsson.dev>\nSu Wang <su.wang@docker.com>\nSubhajit Ghosh <isubuz.g@gmail.com>\nSujith Haridasan <sujith.h@gmail.com>\nSun Gengze <690388648@qq.com>\nSun Jianbo <wonderflow.sun@gmail.com>\nSune Keller <sune.keller@gmail.com>\nSunny Gogoi <indiasuny000@gmail.com>\nSuryakumar Sudar <surya.trunks@gmail.com>\nSven Dowideit <SvenDowideit@home.org.au>\nSwapnil Daingade <swapnil.daingade@gmail.com>\nSylvain Baubeau <lebauce@gmail.com>\nSylvain Bellemare <sylvain@ascribe.io>\nSébastien <sebastien@yoozio.com>\nSébastien HOUZÉ <cto@verylastroom.com>\nSébastien Luttringer <seblu@seblu.net>\nSébastien Stormacq <sebsto@users.noreply.github.com>\nSören Tempel <soeren+git@soeren-tempel.net>\nTabakhase <mail@tabakhase.com>\nTadej Janež <tadej.j@nez.si>\nTakuto Sato <tockn.jp@gmail.com>\ntang0th <tang0th@gmx.com>\nTangi Colin <tangicolin@gmail.com>\nTatsuki Sugiura <sugi@nemui.org>\nTatsushi Inagaki <e29253@jp.ibm.com>\nTaylan Isikdemir <taylani@google.com>\nTaylor Jones <monitorjbl@gmail.com>\nTed M. Young <tedyoung@gmail.com>\nTehmasp Chaudhri <tehmasp@gmail.com>\nTejaswini Duggaraju <naduggar@microsoft.com>\nTejesh Mehta <tejesh.mehta@gmail.com>\nTerry Chu <zue.hterry@gmail.com>\nterryding77 <550147740@qq.com>\nThatcher Peskens <thatcher@docker.com>\ntheadactyl <thea.lamkin@gmail.com>\nThell 'Bo' Fowler <thell@tbfowler.name>\nThermionix <bond711@gmail.com>\nThiago Alves Silva <thiago.alves@aurea.com>\nThijs Terlouw <thijsterlouw@gmail.com>\nThomas Bikeev <thomas.bikeev@mac.com>\nThomas Frössman <thomasf@jossystem.se>\nThomas Gazagnaire <thomas@gazagnaire.org>\nThomas Graf <tgraf@suug.ch>\nThomas Grainger <tagrain@gmail.com>\nThomas Hansen <thomas.hansen@gmail.com>\nThomas Ledos <thomas.ledos92@gmail.com>\nThomas Leonard <thomas.leonard@docker.com>\nThomas Léveil <thomasleveil@gmail.com>\nThomas Orozco <thomas@orozco.fr>\nThomas Riccardi <riccardi@systran.fr>\nThomas Schroeter <thomas@cliqz.com>\nThomas Sjögren <konstruktoid@users.noreply.github.com>\nThomas Swift <tgs242@gmail.com>\nThomas Tanaka <thomas.tanaka@oracle.com>\nThomas Texier <sharkone@en-mousse.org>\nTi Zhou <tizhou1986@gmail.com>\nTiago Seabra <tlgs@users.noreply.github.com>\nTianon Gravi <admwiggin@gmail.com>\nTianyi Wang <capkurmagati@gmail.com>\nTibor Vass <teabee89@gmail.com>\nTiffany Jernigan <tiffany.f.j@gmail.com>\nTiffany Low <tiffany@box.com>\nTill Claassen <pixelistik@users.noreply.github.com>\nTill Wegmüller <toasterson@gmail.com>\nTim <elatllat@gmail.com>\nTim Bart <tim@fewagainstmany.com>\nTim Bosse <taim@bosboot.org>\nTim Dettrick <t.dettrick@uq.edu.au>\nTim Düsterhus <tim@bastelstu.be>\nTim Hockin <thockin@google.com>\nTim Potter <tpot@hpe.com>\nTim Ruffles <oi@truffles.me.uk>\nTim Smith <timbot@google.com>\nTim Terhorst <mynamewastaken+git@gmail.com>\nTim Wagner <tim.wagner@freenet.ag>\nTim Wang <timwangdev@gmail.com>\nTim Waugh <twaugh@redhat.com>\nTim Wraight <tim.wraight@tangentlabs.co.uk>\nTim Zju <21651152@zju.edu.cn>\ntimchenxiaoyu <837829664@qq.com>\ntimfeirg <kkcocogogo@gmail.com>\nTimo Rothenpieler <timo@rothenpieler.org>\nTimothy Hobbs <timothyhobbs@seznam.cz>\ntjwebb123 <tjwebb123@users.noreply.github.com>\ntobe <tobegit3hub@gmail.com>\nTobias Bieniek <Tobias.Bieniek@gmx.de>\nTobias Bradtke <webwurst@gmail.com>\nTobias Gesellchen <tobias@gesellix.de>\nTobias Klauser <tklauser@distanz.ch>\nTobias Munk <schmunk@usrbin.de>\nTobias Pfandzelter <tobias@pfandzelter.com>\nTobias Schmidt <ts@soundcloud.com>\nTobias Schwab <tobias.schwab@dynport.de>\nTodd Crane <todd@toddcrane.com>\nTodd Lunter <tlunter@gmail.com>\nTodd Whiteman <todd.whiteman@joyent.com>\nToli Kuznets <toli@docker.com>\nTom Barlow <tomwbarlow@gmail.com>\nTom Booth <tombooth@gmail.com>\nTom Denham <tom@tomdee.co.uk>\nTom Fotherby <tom+github@peopleperhour.com>\nTom Howe <tom.howe@enstratius.com>\nTom Hulihan <hulihan.tom159@gmail.com>\nTom Maaswinkel <tom.maaswinkel@12wiki.eu>\nTom Parker <palfrey@tevp.net>\nTom Sweeney <tsweeney@redhat.com>\nTom Wilkie <tom.wilkie@gmail.com>\nTom X. Tobin <tomxtobin@tomxtobin.com>\nTom Zhao <zlwangel@gmail.com>\nTomas Janousek <tomi@nomi.cz>\nTomas Kral <tomas.kral@gmail.com>\nTomas Tomecek <ttomecek@redhat.com>\nTomasz Kopczynski <tomek@kopczynski.net.pl>\nTomasz Lipinski <tlipinski@users.noreply.github.com>\nTomasz Nurkiewicz <nurkiewicz@gmail.com>\nTomek Mańko <tomek.manko@railgun-solutions.com>\nTommaso Visconti <tommaso.visconti@gmail.com>\nTomoya Tabuchi <t@tomoyat1.com>\nTomáš Hrčka <thrcka@redhat.com>\ntonic <tonicbupt@gmail.com>\nTonny Xu <tonny.xu@gmail.com>\nTony Abboud <tdabboud@hotmail.com>\nTony Daws <tony@daws.ca>\nTony Miller <mcfiredrill@gmail.com>\ntoogley <toogley@mailbox.org>\nTorstein Husebø <torstein@huseboe.net>\nToshiaki Makita <makita.toshiaki@lab.ntt.co.jp>\nTõnis Tiigi <tonistiigi@gmail.com>\nTrace Andreason <tandreason@gmail.com>\ntracylihui <793912329@qq.com>\nTrapier Marshall <tmarshall@mirantis.com>\nTravis Cline <travis.cline@gmail.com>\nTravis Thieman <travis.thieman@gmail.com>\nTrent Ogren <tedwardo2@gmail.com>\nTrevor <trevinwoodstock@gmail.com>\nTrevor Pounds <trevor.pounds@gmail.com>\nTrevor Sullivan <pcgeek86@gmail.com>\nTrishna Guha <trishnaguha17@gmail.com>\nTristan Carel <tristan@cogniteev.com>\nTroy Denton <trdenton@gmail.com>\nTudor Brindus <me@tbrindus.ca>\nTy Alexander <ty.alexander@sendgrid.com>\nTycho Andersen <tycho@docker.com>\nTyler Brock <tyler.brock@gmail.com>\nTyler Brown <tylers.pile@gmail.com>\nTzu-Jung Lee <roylee17@gmail.com>\nuhayate <uhayate.gong@daocloud.io>\nUlysse Carion <ulyssecarion@gmail.com>\nUmesh Yadav <umesh4257@gmail.com>\nUtz Bacher <utz.bacher@de.ibm.com>\nvagrant <vagrant@ubuntu-14.04-amd64-vbox>\nVaidas Jablonskis <jablonskis@gmail.com>\nValentin Kulesh <valentin.kulesh@virtuozzo.com>\nvanderliang <lansheng@meili-inc.com>\nVelko Ivanov <vivanov@deeperplane.com>\nVeres Lajos <vlajos@gmail.com>\nVictor Algaze <valgaze@gmail.com>\nVictor Coisne <victor.coisne@dotcloud.com>\nVictor Costan <costan@gmail.com>\nVictor I. Wood <viw@t2am.com>\nVictor Lyuboslavsky <victor@victoreda.com>\nVictor Marmol <vmarmol@google.com>\nVictor Palma <palma.victor@gmail.com>\nVictor Vieux <victor.vieux@docker.com>\nVictoria Bialas <victoria.bialas@docker.com>\nVijaya Kumar K <vijayak@caviumnetworks.com>\nVikas Choudhary <choudharyvikas16@gmail.com>\nVikram bir Singh <vsingh@mirantis.com>\nViktor Stanchev <me@viktorstanchev.com>\nViktor Vojnovski <viktor.vojnovski@amadeus.com>\nVinayRaghavanKS <raghavan.vinay@gmail.com>\nVincent Batts <vbatts@redhat.com>\nVincent Bernat <vincent@bernat.ch>\nVincent Boulineau <vincent.boulineau@datadoghq.com>\nVincent Demeester <vincent.demeester@docker.com>\nVincent Giersch <vincent.giersch@ovh.net>\nVincent Mayers <vincent.mayers@inbloom.org>\nVincent Woo <me@vincentwoo.com>\nVinod Kulkarni <vinod.kulkarni@gmail.com>\nVishal Doshi <vishal.doshi@gmail.com>\nVishnu Kannan <vishnuk@google.com>\nVitaly Ostrosablin <vostrosablin@virtuozzo.com>\nVitor Anjos <bartier@users.noreply.github.com>\nVitor Monteiro <vmrmonteiro@gmail.com>\nVivek Agarwal <me@vivek.im>\nVivek Dasgupta <vdasgupt@redhat.com>\nVivek Goyal <vgoyal@redhat.com>\nVladimir Bulyga <xx@ccxx.cc>\nVladimir Kirillov <proger@wilab.org.ua>\nVladimir Pouzanov <farcaller@google.com>\nVladimir Rutsky <altsysrq@gmail.com>\nVladimir Varankin <nek.narqo+git@gmail.com>\nVladimirAus <v_roudakov@yahoo.com>\nVladislav Kolesnikov <vkolesnikov@beget.ru>\nVlastimil Zeman <vlastimil.zeman@diffblue.com>\nVojtech Vitek (V-Teq) <vvitek@redhat.com>\nWalter Leibbrandt <github@wrl.co.za>\nWalter Stanish <walter@pratyeka.org>\nWang Chao <chao.wang@ucloud.cn>\nWang Guoliang <liangcszzu@163.com>\nWang Jie <wangjie5@chinaskycloud.com>\nWang Long <long.wanglong@huawei.com>\nWang Ping <present.wp@icloud.com>\nWang Xing <hzwangxing@corp.netease.com>\nWang Yuexiao <wang.yuexiao@zte.com.cn>\nWang Yumu <37442693@qq.com>\nwanghuaiqing <wanghuaiqing@loongson.cn>\nWard Vandewege <ward@jhvc.com>\nWarheadsSE <max@warheads.net>\nWassim Dhif <wassimdhif@gmail.com>\nWataru Ishida <ishida.wataru@lab.ntt.co.jp>\nWayne Chang <wayne@neverfear.org>\nWayne Song <wsong@docker.com>\nWeerasak Chongnguluam <singpor@gmail.com>\nWei Fu <fuweid89@gmail.com>\nWei Wu <wuwei4455@gmail.com>\nWei-Ting Kuo <waitingkuo0527@gmail.com>\nweipeng <weipeng@tuscloud.io>\nweiyan <weiyan3@huawei.com>\nWeiyang Zhu <cnresonant@gmail.com>\nWen Cheng Ma <wenchma@cn.ibm.com>\nWendel Fleming <wfleming@usc.edu>\nWenjun Tang <tangwj2@lenovo.com>\nWenkai Yin <yinw@vmware.com>\nwenlxie <wenlxie@ebay.com>\nWenxuan Zhao <viz@linux.com>\nWenyu You <21551128@zju.edu.cn>\nWenzhi Liang <wenzhi.liang@gmail.com>\nWes Morgan <cap10morgan@gmail.com>\nWesley Pettit <wppttt@amazon.com>\nWewang Xiaorenfine <wang.xiaoren@zte.com.cn>\nWiktor Kwapisiewicz <wiktor@metacode.biz>\nWill Dietz <w@wdtz.org>\nWill Rouesnel <w.rouesnel@gmail.com>\nWill Weaver <monkey@buildingbananas.com>\nwillhf <willhf@gmail.com>\nWilliam Delanoue <william.delanoue@gmail.com>\nWilliam Henry <whenry@redhat.com>\nWilliam Hubbs <w.d.hubbs@gmail.com>\nWilliam Martin <wmartin@pivotal.io>\nWilliam Riancho <wr.wllm@gmail.com>\nWilliam Thurston <thurstw@amazon.com>\nWilson Júnior <wilsonpjunior@gmail.com>\nWing-Kam Wong <wingkwong.code@gmail.com>\nWiseTrem <shepelyov.g@gmail.com>\nWolfgang Nagele <mail@wnagele.com>\nWolfgang Powisch <powo@powo.priv.at>\nWonjun Kim <wonjun.kim@navercorp.com>\nWuLonghui <wlh6666@qq.com>\nxamyzhao <x.amy.zhao@gmail.com>\nXia Wu <xwumzn@amazon.com>\nXian Chaobo <xianchaobo@huawei.com>\nXianglin Gao <xlgao@zju.edu.cn>\nXianjie <guxianjie@gmail.com>\nXianlu Bird <xianlubird@gmail.com>\nXiao YongBiao <xyb4638@gmail.com>\nXiao Zhang <xiaozhang0210@hotmail.com>\nXiaoBing Jiang <s7v7nislands@gmail.com>\nXiaodong Liu <liuxiaodong@loongson.cn>\nXiaodong Zhang <a4012017@sina.com>\nXiaohua Ding <xiao_hua_ding@sina.cn>\nXiaoxi He <xxhe@alauda.io>\nXiaoxu Chen <chenxiaoxu14@otcaix.iscas.ac.cn>\nXiaoyu Zhang <zhang.xiaoyu33@zte.com.cn>\nxichengliudui <1693291525@qq.com>\nxiekeyang <xiekeyang@huawei.com>\nXimo Guanter Gonzálbez <joaquin.guantergonzalbez@telefonica.com>\nxin.li <xin.li@daocloud.io>\nXinbo Weng <xihuanbo_0521@zju.edu.cn>\nXinfeng Liu <XinfengLiu@icloud.com>\nXinzi Zhou <imdreamrunner@gmail.com>\nXiuming Chen <cc@cxm.cc>\nXuecong Liao <satorulogic@gmail.com>\nxuzhaokui <cynicholas@gmail.com>\nYadnyawalkya Tale <ytale@redhat.com>\nYahya <ya7yaz@gmail.com>\nyalpul <yalpul@gmail.com>\nYAMADA Tsuyoshi <tyamada@minimum2scp.org>\nYamasaki Masahide <masahide.y@gmail.com>\nYamazaki Masashi <masi19bw@gmail.com>\nYan Feng <yanfeng2@huawei.com>\nYan Zhu <yanzhu@alauda.io>\nYang Bai <hamo.by@gmail.com>\nYang Li <idealhack@gmail.com>\nYang Pengfei <yangpengfei4@huawei.com>\nyangchenliang <yangchenliang@huawei.com>\nYann Autissier <yann.autissier@gmail.com>\nYanqiang Miao <miao.yanqiang@zte.com.cn>\nYao Zaiyong <yaozaiyong@hotmail.com>\nYash Murty <yashmurty@gmail.com>\nYassine Tijani <yasstij11@gmail.com>\nYasunori Mahata <nori@mahata.net>\nYazhong Liu <yorkiefixer@gmail.com>\nYestin Sun <sunyi0804@gmail.com>\nYi EungJun <eungjun.yi@navercorp.com>\nYibai Zhang <xm1994@gmail.com>\nYihang Ho <hoyihang5@gmail.com>\nYing Li <ying.li@docker.com>\nYohei Ueda <yohei@jp.ibm.com>\nYong Tang <yong.tang.github@outlook.com>\nYongxin Li <yxli@alauda.io>\nYongzhi Pan <panyongzhi@gmail.com>\nYosef Fertel <yfertel@gmail.com>\nYou-Sheng Yang (楊有勝) <vicamo@gmail.com>\nyoucai <omegacoleman@gmail.com>\nYoucef YEKHLEF <yyekhlef@gmail.com>\nYoufu Zhang <zhangyoufu@gmail.com>\nYu Changchun <yuchangchun1@huawei.com>\nYu Chengxia <yuchengxia@huawei.com>\nYu Peng <yu.peng36@zte.com.cn>\nYu-Ju Hong <yjhong@google.com>\nYuan Sun <sunyuan3@huawei.com>\nYuanhong Peng <pengyuanhong@huawei.com>\nYue Zhang <zy675793960@yeah.net>\nYufei Xiong <yufei.xiong@qq.com>\nYuhao Fang <fangyuhao@gmail.com>\nYuichiro Kaneko <spiketeika@gmail.com>\nYujiOshima <yuji.oshima0x3fd@gmail.com>\nYunxiang Huang <hyxqshk@vip.qq.com>\nYurii Rashkovskii <yrashk@gmail.com>\nYusuf Tarık Günaydın <yusuf_tarik@hotmail.com>\nYves Blusseau <90z7oey02@sneakemail.com>\nYves Junqueira <yves.junqueira@gmail.com>\nZac Dover <zdover@redhat.com>\nZach Borboa <zachborboa@gmail.com>\nZach Gershman <zachgersh@gmail.com>\nZachary Jaffee <zjaffee@us.ibm.com>\nZain Memon <zain@inzain.net>\nZaiste! <oh@zaiste.net>\nZane DeGraffenried <zane.deg@gmail.com>\nZefan Li <lizefan@huawei.com>\nZen Lin(Zhinan Lin) <linzhinan@huawei.com>\nZhang Kun <zkazure@gmail.com>\nZhang Wei <zhangwei555@huawei.com>\nZhang Wentao <zhangwentao234@huawei.com>\nzhangguanzhang <zhangguanzhang@qq.com>\nZhangHang <stevezhang2014@gmail.com>\nzhangxianwei <xianwei.zw@alibaba-inc.com>\nZhenan Ye <21551168@zju.edu.cn>\nzhenghenghuo <zhenghenghuo@zju.edu.cn>\nZhenhai Gao <gaozh1988@live.com>\nZhenkun Bi <bi.zhenkun@zte.com.cn>\nZhiPeng Lu <lu.zhipeng@zte.com.cn>\nzhipengzuo <zuozhipeng@baidu.com>\nZhou Hao <zhouhao@cn.fujitsu.com>\nZhoulin Xie <zhoulin.xie@daocloud.io>\nZhu Guihua <zhugh.fnst@cn.fujitsu.com>\nZhu Kunjia <zhu.kunjia@zte.com.cn>\nZhuoyun Wei <wzyboy@wzyboy.org>\nZiheng Liu <lzhfromustc@gmail.com>\nZilin Du <zilin.du@gmail.com>\nzimbatm <zimbatm@zimbatm.com>\nZiming Dong <bnudzm@foxmail.com>\nZJUshuaizhou <21551191@zju.edu.cn>\nzmarouf <zeid.marouf@gmail.com>\nZoltan Tombol <zoltan.tombol@gmail.com>\nZou Yu <zouyu7@huawei.com>\nzqh <zqhxuyuan@gmail.com>\nZuhayr Elahi <zuhayr.elahi@docker.com>\nZunayed Ali <zunayed@gmail.com>\nÁlvaro Lázaro <alvaro.lazaro.g@gmail.com>\nÁtila Camurça Alves <camurca.home@gmail.com>\n吴小白 <296015668@qq.com>\n尹吉峰 <jifeng.yin@gmail.com>\n屈骏 <qujun@tiduyun.com>\n徐俊杰 <paco.xu@daocloud.io>\n慕陶 <jihui.xjh@alibaba-inc.com>\n搏通 <yufeng.pyf@alibaba-inc.com>\n黄艳红00139573 <huang.yanhong@zte.com.cn>\n정재영 <jjy600901@gmail.com>\n"
  },
  {
    "path": "vendor/github.com/docker/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-2018 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": "vendor/github.com/docker/docker/NOTICE",
    "content": "Docker\nCopyright 2012-2017 Docker, Inc.\n\nThis product includes software developed at Docker, Inc. (https://www.docker.com).\n\nThis product contains software (https://github.com/creack/pty) developed\nby Keith Rarick, licensed under the MIT License.\n\nThe following is courtesy of our legal counsel:\n\n\nUse and transfer of Docker may be subject to certain restrictions by the\nUnited States and other governments.\nIt is your responsibility to ensure that your use and/or transfer does not\nviolate applicable laws.\n\nFor more information, please see https://www.bis.doc.gov\n\nSee also https://www.apache.org/dev/crypto.html and/or seek legal counsel.\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/README.md",
    "content": "# Working on the Engine API\n\nThe Engine API is an HTTP API used by the command-line client to communicate with the daemon. It can also be used by third-party software to control the daemon.\n\nIt consists of various components in this repository:\n\n- `api/swagger.yaml` A Swagger definition of the API.\n- `api/types/` Types shared by both the client and server, representing various objects, options, responses, etc. Most are written manually, but some are automatically generated from the Swagger definition. See [#27919](https://github.com/docker/docker/issues/27919) for progress on this.\n- `cli/` The command-line client.\n- `client/` The Go client used by the command-line client. It can also be used by third-party Go programs.\n- `daemon/` The daemon, which serves the API.\n\n## Swagger definition\n\nThe API is defined by the [Swagger](http://swagger.io/specification/) definition in `api/swagger.yaml`. This definition can be used to:\n\n1. Automatically generate documentation.\n2. Automatically generate the Go server and client. (A work-in-progress.)\n3. Provide a machine readable version of the API for introspecting what it can do, automatically generating clients for other languages, etc.\n\n## Updating the API documentation\n\nThe API documentation is generated entirely from `api/swagger.yaml`. If you make updates to the API, edit this file to represent the change in the documentation.\n\nThe file is split into two main sections:\n\n- `definitions`, which defines re-usable objects used in requests and responses\n- `paths`, which defines the API endpoints (and some inline objects which don't need to be reusable)\n\nTo make an edit, first look for the endpoint you want to edit under `paths`, then make the required edits. Endpoints may reference reusable objects with `$ref`, which can be found in the `definitions` section.\n\nThere is hopefully enough example material in the file for you to copy a similar pattern from elsewhere in the file (e.g. adding new fields or endpoints), but for the full reference, see the [Swagger specification](https://github.com/docker/docker/issues/27919).\n\n`swagger.yaml` is validated by `hack/validate/swagger` to ensure it is a valid Swagger definition. This is useful when making edits to ensure you are doing the right thing.\n\n## Viewing the API documentation\n\nWhen you make edits to `swagger.yaml`, you may want to check the generated API documentation to ensure it renders correctly.\n\nRun `make swagger-docs` and a preview will be running at `http://localhost:9000`. Some of the styling may be incorrect, but you'll be able to ensure that it is generating the correct documentation.\n\nThe production documentation is generated by vendoring `swagger.yaml` into [docker/docker.github.io](https://github.com/docker/docker.github.io).\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/common.go",
    "content": "package api // import \"github.com/docker/docker/api\"\n\n// Common constants for daemon and client.\nconst (\n\t// DefaultVersion of Current REST API\n\tDefaultVersion = \"1.44\"\n\n\t// NoBaseImageSpecifier is the symbol used by the FROM\n\t// command to specify that no base image is to be used.\n\tNoBaseImageSpecifier = \"scratch\"\n)\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/swagger-gen.yaml",
    "content": "\nlayout:\n  models:\n    - name: definition\n      source: asset:model\n      target: \"{{ joinFilePath .Target .ModelPackage }}\"\n      file_name: \"{{ (snakize (pascalize .Name)) }}.go\"\n  operations:\n    - name: handler\n      source: asset:serverOperation\n      target: \"{{ joinFilePath .Target .APIPackage .Package }}\"\n      file_name: \"{{ (snakize (pascalize .Name)) }}.go\"\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/swagger.yaml",
    "content": "# A Swagger 2.0 (a.k.a. OpenAPI) definition of the Engine API.\n#\n# This is used for generating API documentation and the types used by the\n# client/server. See api/README.md for more information.\n#\n# Some style notes:\n# - This file is used by ReDoc, which allows GitHub Flavored Markdown in\n#   descriptions.\n# - There is no maximum line length, for ease of editing and pretty diffs.\n# - operationIds are in the format \"NounVerb\", with a singular noun.\n\nswagger: \"2.0\"\nschemes:\n  - \"http\"\n  - \"https\"\nproduces:\n  - \"application/json\"\n  - \"text/plain\"\nconsumes:\n  - \"application/json\"\n  - \"text/plain\"\nbasePath: \"/v1.44\"\ninfo:\n  title: \"Docker Engine API\"\n  version: \"1.44\"\n  x-logo:\n    url: \"https://docs.docker.com/assets/images/logo-docker-main.png\"\n  description: |\n    The Engine API is an HTTP API served by Docker Engine. It is the API the\n    Docker client uses to communicate with the Engine, so everything the Docker\n    client can do can be done with the API.\n\n    Most of the client's commands map directly to API endpoints (e.g. `docker ps`\n    is `GET /containers/json`). The notable exception is running containers,\n    which consists of several API calls.\n\n    # Errors\n\n    The API uses standard HTTP status codes to indicate the success or failure\n    of the API call. The body of the response will be JSON in the following\n    format:\n\n    ```\n    {\n      \"message\": \"page not found\"\n    }\n    ```\n\n    # Versioning\n\n    The API is usually changed in each release, so API calls are versioned to\n    ensure that clients don't break. To lock to a specific version of the API,\n    you prefix the URL with its version, for example, call `/v1.30/info` to use\n    the v1.30 version of the `/info` endpoint. If the API version specified in\n    the URL is not supported by the daemon, a HTTP `400 Bad Request` error message\n    is returned.\n\n    If you omit the version-prefix, the current version of the API (v1.44) is used.\n    For example, calling `/info` is the same as calling `/v1.44/info`. Using the\n    API without a version-prefix is deprecated and will be removed in a future release.\n\n    Engine releases in the near future should support this version of the API,\n    so your client will continue to work even if it is talking to a newer Engine.\n\n    The API uses an open schema model, which means server may add extra properties\n    to responses. Likewise, the server will ignore any extra query parameters and\n    request body properties. When you write clients, you need to ignore additional\n    properties in responses to ensure they do not break when talking to newer\n    daemons.\n\n\n    # Authentication\n\n    Authentication for registries is handled client side. The client has to send\n    authentication details to various endpoints that need to communicate with\n    registries, such as `POST /images/(name)/push`. These are sent as\n    `X-Registry-Auth` header as a [base64url encoded](https://tools.ietf.org/html/rfc4648#section-5)\n    (JSON) string with the following structure:\n\n    ```\n    {\n      \"username\": \"string\",\n      \"password\": \"string\",\n      \"email\": \"string\",\n      \"serveraddress\": \"string\"\n    }\n    ```\n\n    The `serveraddress` is a domain/IP without a protocol. Throughout this\n    structure, double quotes are required.\n\n    If you have already got an identity token from the [`/auth` endpoint](#operation/SystemAuth),\n    you can just pass this instead of credentials:\n\n    ```\n    {\n      \"identitytoken\": \"9cbaf023786cd7...\"\n    }\n    ```\n\n# The tags on paths define the menu sections in the ReDoc documentation, so\n# the usage of tags must make sense for that:\n# - They should be singular, not plural.\n# - There should not be too many tags, or the menu becomes unwieldy. For\n#   example, it is preferable to add a path to the \"System\" tag instead of\n#   creating a tag with a single path in it.\n# - The order of tags in this list defines the order in the menu.\ntags:\n  # Primary objects\n  - name: \"Container\"\n    x-displayName: \"Containers\"\n    description: |\n      Create and manage containers.\n  - name: \"Image\"\n    x-displayName: \"Images\"\n  - name: \"Network\"\n    x-displayName: \"Networks\"\n    description: |\n      Networks are user-defined networks that containers can be attached to.\n      See the [networking documentation](https://docs.docker.com/network/)\n      for more information.\n  - name: \"Volume\"\n    x-displayName: \"Volumes\"\n    description: |\n      Create and manage persistent storage that can be attached to containers.\n  - name: \"Exec\"\n    x-displayName: \"Exec\"\n    description: |\n      Run new commands inside running containers. Refer to the\n      [command-line reference](https://docs.docker.com/engine/reference/commandline/exec/)\n      for more information.\n\n      To exec a command in a container, you first need to create an exec instance,\n      then start it. These two API endpoints are wrapped up in a single command-line\n      command, `docker exec`.\n\n  # Swarm things\n  - name: \"Swarm\"\n    x-displayName: \"Swarm\"\n    description: |\n      Engines can be clustered together in a swarm. Refer to the\n      [swarm mode documentation](https://docs.docker.com/engine/swarm/)\n      for more information.\n  - name: \"Node\"\n    x-displayName: \"Nodes\"\n    description: |\n      Nodes are instances of the Engine participating in a swarm. Swarm mode\n      must be enabled for these endpoints to work.\n  - name: \"Service\"\n    x-displayName: \"Services\"\n    description: |\n      Services are the definitions of tasks to run on a swarm. Swarm mode must\n      be enabled for these endpoints to work.\n  - name: \"Task\"\n    x-displayName: \"Tasks\"\n    description: |\n      A task is a container running on a swarm. It is the atomic scheduling unit\n      of swarm. Swarm mode must be enabled for these endpoints to work.\n  - name: \"Secret\"\n    x-displayName: \"Secrets\"\n    description: |\n      Secrets are sensitive data that can be used by services. Swarm mode must\n      be enabled for these endpoints to work.\n  - name: \"Config\"\n    x-displayName: \"Configs\"\n    description: |\n      Configs are application configurations that can be used by services. Swarm\n      mode must be enabled for these endpoints to work.\n  # System things\n  - name: \"Plugin\"\n    x-displayName: \"Plugins\"\n  - name: \"System\"\n    x-displayName: \"System\"\n\ndefinitions:\n  Port:\n    type: \"object\"\n    description: \"An open port on a container\"\n    required: [PrivatePort, Type]\n    properties:\n      IP:\n        type: \"string\"\n        format: \"ip-address\"\n        description: \"Host IP address that the container's port is mapped to\"\n      PrivatePort:\n        type: \"integer\"\n        format: \"uint16\"\n        x-nullable: false\n        description: \"Port on the container\"\n      PublicPort:\n        type: \"integer\"\n        format: \"uint16\"\n        description: \"Port exposed on the host\"\n      Type:\n        type: \"string\"\n        x-nullable: false\n        enum: [\"tcp\", \"udp\", \"sctp\"]\n    example:\n      PrivatePort: 8080\n      PublicPort: 80\n      Type: \"tcp\"\n\n  MountPoint:\n    type: \"object\"\n    description: |\n      MountPoint represents a mount point configuration inside the container.\n      This is used for reporting the mountpoints in use by a container.\n    properties:\n      Type:\n        description: |\n          The mount type:\n\n          - `bind` a mount of a file or directory from the host into the container.\n          - `volume` a docker volume with the given `Name`.\n          - `tmpfs` a `tmpfs`.\n          - `npipe` a named pipe from the host into the container.\n          - `cluster` a Swarm cluster volume\n        type: \"string\"\n        enum:\n          - \"bind\"\n          - \"volume\"\n          - \"tmpfs\"\n          - \"npipe\"\n          - \"cluster\"\n        example: \"volume\"\n      Name:\n        description: |\n          Name is the name reference to the underlying data defined by `Source`\n          e.g., the volume name.\n        type: \"string\"\n        example: \"myvolume\"\n      Source:\n        description: |\n          Source location of the mount.\n\n          For volumes, this contains the storage location of the volume (within\n          `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains\n          the source (host) part of the bind-mount. For `tmpfs` mount points, this\n          field is empty.\n        type: \"string\"\n        example: \"/var/lib/docker/volumes/myvolume/_data\"\n      Destination:\n        description: |\n          Destination is the path relative to the container root (`/`) where\n          the `Source` is mounted inside the container.\n        type: \"string\"\n        example: \"/usr/share/nginx/html/\"\n      Driver:\n        description: |\n          Driver is the volume driver used to create the volume (if it is a volume).\n        type: \"string\"\n        example: \"local\"\n      Mode:\n        description: |\n          Mode is a comma separated list of options supplied by the user when\n          creating the bind/volume mount.\n\n          The default is platform-specific (`\"z\"` on Linux, empty on Windows).\n        type: \"string\"\n        example: \"z\"\n      RW:\n        description: |\n          Whether the mount is mounted writable (read-write).\n        type: \"boolean\"\n        example: true\n      Propagation:\n        description: |\n          Propagation describes how mounts are propagated from the host into the\n          mount point, and vice-versa. Refer to the [Linux kernel documentation](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)\n          for details. This field is not used on Windows.\n        type: \"string\"\n        example: \"\"\n\n  DeviceMapping:\n    type: \"object\"\n    description: \"A device mapping between the host and container\"\n    properties:\n      PathOnHost:\n        type: \"string\"\n      PathInContainer:\n        type: \"string\"\n      CgroupPermissions:\n        type: \"string\"\n    example:\n      PathOnHost: \"/dev/deviceName\"\n      PathInContainer: \"/dev/deviceName\"\n      CgroupPermissions: \"mrw\"\n\n  DeviceRequest:\n    type: \"object\"\n    description: \"A request for devices to be sent to device drivers\"\n    properties:\n      Driver:\n        type: \"string\"\n        example: \"nvidia\"\n      Count:\n        type: \"integer\"\n        example: -1\n      DeviceIDs:\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"0\"\n          - \"1\"\n          - \"GPU-fef8089b-4820-abfc-e83e-94318197576e\"\n      Capabilities:\n        description: |\n          A list of capabilities; an OR list of AND lists of capabilities.\n        type: \"array\"\n        items:\n          type: \"array\"\n          items:\n            type: \"string\"\n        example:\n          # gpu AND nvidia AND compute\n          - [\"gpu\", \"nvidia\", \"compute\"]\n      Options:\n        description: |\n          Driver-specific options, specified as a key/value pairs. These options\n          are passed directly to the driver.\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n\n  ThrottleDevice:\n    type: \"object\"\n    properties:\n      Path:\n        description: \"Device path\"\n        type: \"string\"\n      Rate:\n        description: \"Rate\"\n        type: \"integer\"\n        format: \"int64\"\n        minimum: 0\n\n  Mount:\n    type: \"object\"\n    properties:\n      Target:\n        description: \"Container path.\"\n        type: \"string\"\n      Source:\n        description: \"Mount source (e.g. a volume name, a host path).\"\n        type: \"string\"\n      Type:\n        description: |\n          The mount type. Available types:\n\n          - `bind` Mounts a file or directory from the host into the container. Must exist prior to creating the container.\n          - `volume` Creates a volume with the given name and options (or uses a pre-existing volume with the same name and options). These are **not** removed when the container is removed.\n          - `tmpfs` Create a tmpfs with the given options. The mount source cannot be specified for tmpfs.\n          - `npipe` Mounts a named pipe from the host into the container. Must exist prior to creating the container.\n          - `cluster` a Swarm cluster volume\n        type: \"string\"\n        enum:\n          - \"bind\"\n          - \"volume\"\n          - \"tmpfs\"\n          - \"npipe\"\n          - \"cluster\"\n      ReadOnly:\n        description: \"Whether the mount should be read-only.\"\n        type: \"boolean\"\n      Consistency:\n        description: \"The consistency requirement for the mount: `default`, `consistent`, `cached`, or `delegated`.\"\n        type: \"string\"\n      BindOptions:\n        description: \"Optional configuration for the `bind` type.\"\n        type: \"object\"\n        properties:\n          Propagation:\n            description: \"A propagation mode with the value `[r]private`, `[r]shared`, or `[r]slave`.\"\n            type: \"string\"\n            enum:\n              - \"private\"\n              - \"rprivate\"\n              - \"shared\"\n              - \"rshared\"\n              - \"slave\"\n              - \"rslave\"\n          NonRecursive:\n            description: \"Disable recursive bind mount.\"\n            type: \"boolean\"\n            default: false\n          CreateMountpoint:\n            description: \"Create mount point on host if missing\"\n            type: \"boolean\"\n            default: false\n          ReadOnlyNonRecursive:\n            description: |\n               Make the mount non-recursively read-only, but still leave the mount recursive\n               (unless NonRecursive is set to `true` in conjunction).\n\n               Addded in v1.44, before that version all read-only mounts were\n               non-recursive by default. To match the previous behaviour this\n               will default to `true` for clients on versions prior to v1.44.\n            type: \"boolean\"\n            default: false\n          ReadOnlyForceRecursive:\n            description: \"Raise an error if the mount cannot be made recursively read-only.\"\n            type: \"boolean\"\n            default: false\n      VolumeOptions:\n        description: \"Optional configuration for the `volume` type.\"\n        type: \"object\"\n        properties:\n          NoCopy:\n            description: \"Populate volume with data from the target.\"\n            type: \"boolean\"\n            default: false\n          Labels:\n            description: \"User-defined key/value metadata.\"\n            type: \"object\"\n            additionalProperties:\n              type: \"string\"\n          DriverConfig:\n            description: \"Map of driver specific options\"\n            type: \"object\"\n            properties:\n              Name:\n                description: \"Name of the driver to use to create the volume.\"\n                type: \"string\"\n              Options:\n                description: \"key/value map of driver specific options.\"\n                type: \"object\"\n                additionalProperties:\n                  type: \"string\"\n      TmpfsOptions:\n        description: \"Optional configuration for the `tmpfs` type.\"\n        type: \"object\"\n        properties:\n          SizeBytes:\n            description: \"The size for the tmpfs mount in bytes.\"\n            type: \"integer\"\n            format: \"int64\"\n          Mode:\n            description: \"The permission mode for the tmpfs mount in an integer.\"\n            type: \"integer\"\n\n  RestartPolicy:\n    description: |\n      The behavior to apply when the container exits. The default is not to\n      restart.\n\n      An ever increasing delay (double the previous delay, starting at 100ms) is\n      added before each restart to prevent flooding the server.\n    type: \"object\"\n    properties:\n      Name:\n        type: \"string\"\n        description: |\n          - Empty string means not to restart\n          - `no` Do not automatically restart\n          - `always` Always restart\n          - `unless-stopped` Restart always except when the user has manually stopped the container\n          - `on-failure` Restart only when the container exit code is non-zero\n        enum:\n          - \"\"\n          - \"no\"\n          - \"always\"\n          - \"unless-stopped\"\n          - \"on-failure\"\n      MaximumRetryCount:\n        type: \"integer\"\n        description: |\n          If `on-failure` is used, the number of times to retry before giving up.\n\n  Resources:\n    description: \"A container's resources (cgroups config, ulimits, etc)\"\n    type: \"object\"\n    properties:\n      # Applicable to all platforms\n      CpuShares:\n        description: |\n          An integer value representing this container's relative CPU weight\n          versus other containers.\n        type: \"integer\"\n      Memory:\n        description: \"Memory limit in bytes.\"\n        type: \"integer\"\n        format: \"int64\"\n        default: 0\n      # Applicable to UNIX platforms\n      CgroupParent:\n        description: |\n          Path to `cgroups` under which the container's `cgroup` is created. If\n          the path is not absolute, the path is considered to be relative to the\n          `cgroups` path of the init process. Cgroups are created if they do not\n          already exist.\n        type: \"string\"\n      BlkioWeight:\n        description: \"Block IO weight (relative weight).\"\n        type: \"integer\"\n        minimum: 0\n        maximum: 1000\n      BlkioWeightDevice:\n        description: |\n          Block IO weight (relative device weight) in the form:\n\n          ```\n          [{\"Path\": \"device_path\", \"Weight\": weight}]\n          ```\n        type: \"array\"\n        items:\n          type: \"object\"\n          properties:\n            Path:\n              type: \"string\"\n            Weight:\n              type: \"integer\"\n              minimum: 0\n      BlkioDeviceReadBps:\n        description: |\n          Limit read rate (bytes per second) from a device, in the form:\n\n          ```\n          [{\"Path\": \"device_path\", \"Rate\": rate}]\n          ```\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/ThrottleDevice\"\n      BlkioDeviceWriteBps:\n        description: |\n          Limit write rate (bytes per second) to a device, in the form:\n\n          ```\n          [{\"Path\": \"device_path\", \"Rate\": rate}]\n          ```\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/ThrottleDevice\"\n      BlkioDeviceReadIOps:\n        description: |\n          Limit read rate (IO per second) from a device, in the form:\n\n          ```\n          [{\"Path\": \"device_path\", \"Rate\": rate}]\n          ```\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/ThrottleDevice\"\n      BlkioDeviceWriteIOps:\n        description: |\n          Limit write rate (IO per second) to a device, in the form:\n\n          ```\n          [{\"Path\": \"device_path\", \"Rate\": rate}]\n          ```\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/ThrottleDevice\"\n      CpuPeriod:\n        description: \"The length of a CPU period in microseconds.\"\n        type: \"integer\"\n        format: \"int64\"\n      CpuQuota:\n        description: |\n          Microseconds of CPU time that the container can get in a CPU period.\n        type: \"integer\"\n        format: \"int64\"\n      CpuRealtimePeriod:\n        description: |\n          The length of a CPU real-time period in microseconds. Set to 0 to\n          allocate no time allocated to real-time tasks.\n        type: \"integer\"\n        format: \"int64\"\n      CpuRealtimeRuntime:\n        description: |\n          The length of a CPU real-time runtime in microseconds. Set to 0 to\n          allocate no time allocated to real-time tasks.\n        type: \"integer\"\n        format: \"int64\"\n      CpusetCpus:\n        description: |\n          CPUs in which to allow execution (e.g., `0-3`, `0,1`).\n        type: \"string\"\n        example: \"0-3\"\n      CpusetMems:\n        description: |\n          Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only\n          effective on NUMA systems.\n        type: \"string\"\n      Devices:\n        description: \"A list of devices to add to the container.\"\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/DeviceMapping\"\n      DeviceCgroupRules:\n        description: \"a list of cgroup rules to apply to the container\"\n        type: \"array\"\n        items:\n          type: \"string\"\n          example: \"c 13:* rwm\"\n      DeviceRequests:\n        description: |\n          A list of requests for devices to be sent to device drivers.\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/DeviceRequest\"\n      KernelMemoryTCP:\n        description: |\n          Hard limit for kernel TCP buffer memory (in bytes). Depending on the\n          OCI runtime in use, this option may be ignored. It is no longer supported\n          by the default (runc) runtime.\n\n          This field is omitted when empty.\n        type: \"integer\"\n        format: \"int64\"\n      MemoryReservation:\n        description: \"Memory soft limit in bytes.\"\n        type: \"integer\"\n        format: \"int64\"\n      MemorySwap:\n        description: |\n          Total memory limit (memory + swap). Set as `-1` to enable unlimited\n          swap.\n        type: \"integer\"\n        format: \"int64\"\n      MemorySwappiness:\n        description: |\n          Tune a container's memory swappiness behavior. Accepts an integer\n          between 0 and 100.\n        type: \"integer\"\n        format: \"int64\"\n        minimum: 0\n        maximum: 100\n      NanoCpus:\n        description: \"CPU quota in units of 10<sup>-9</sup> CPUs.\"\n        type: \"integer\"\n        format: \"int64\"\n      OomKillDisable:\n        description: \"Disable OOM Killer for the container.\"\n        type: \"boolean\"\n      Init:\n        description: |\n          Run an init inside the container that forwards signals and reaps\n          processes. This field is omitted if empty, and the default (as\n          configured on the daemon) is used.\n        type: \"boolean\"\n        x-nullable: true\n      PidsLimit:\n        description: |\n          Tune a container's PIDs limit. Set `0` or `-1` for unlimited, or `null`\n          to not change.\n        type: \"integer\"\n        format: \"int64\"\n        x-nullable: true\n      Ulimits:\n        description: |\n          A list of resource limits to set in the container. For example:\n\n          ```\n          {\"Name\": \"nofile\", \"Soft\": 1024, \"Hard\": 2048}\n          ```\n        type: \"array\"\n        items:\n          type: \"object\"\n          properties:\n            Name:\n              description: \"Name of ulimit\"\n              type: \"string\"\n            Soft:\n              description: \"Soft limit\"\n              type: \"integer\"\n            Hard:\n              description: \"Hard limit\"\n              type: \"integer\"\n      # Applicable to Windows\n      CpuCount:\n        description: |\n          The number of usable CPUs (Windows only).\n\n          On Windows Server containers, the processor resource controls are\n          mutually exclusive. The order of precedence is `CPUCount` first, then\n          `CPUShares`, and `CPUPercent` last.\n        type: \"integer\"\n        format: \"int64\"\n      CpuPercent:\n        description: |\n          The usable percentage of the available CPUs (Windows only).\n\n          On Windows Server containers, the processor resource controls are\n          mutually exclusive. The order of precedence is `CPUCount` first, then\n          `CPUShares`, and `CPUPercent` last.\n        type: \"integer\"\n        format: \"int64\"\n      IOMaximumIOps:\n        description: \"Maximum IOps for the container system drive (Windows only)\"\n        type: \"integer\"\n        format: \"int64\"\n      IOMaximumBandwidth:\n        description: |\n          Maximum IO in bytes per second for the container system drive\n          (Windows only).\n        type: \"integer\"\n        format: \"int64\"\n\n  Limit:\n    description: |\n      An object describing a limit on resources which can be requested by a task.\n    type: \"object\"\n    properties:\n      NanoCPUs:\n        type: \"integer\"\n        format: \"int64\"\n        example: 4000000000\n      MemoryBytes:\n        type: \"integer\"\n        format: \"int64\"\n        example: 8272408576\n      Pids:\n        description: |\n          Limits the maximum number of PIDs in the container. Set `0` for unlimited.\n        type: \"integer\"\n        format: \"int64\"\n        default: 0\n        example: 100\n\n  ResourceObject:\n    description: |\n      An object describing the resources which can be advertised by a node and\n      requested by a task.\n    type: \"object\"\n    properties:\n      NanoCPUs:\n        type: \"integer\"\n        format: \"int64\"\n        example: 4000000000\n      MemoryBytes:\n        type: \"integer\"\n        format: \"int64\"\n        example: 8272408576\n      GenericResources:\n        $ref: \"#/definitions/GenericResources\"\n\n  GenericResources:\n    description: |\n      User-defined resources can be either Integer resources (e.g, `SSD=3`) or\n      String resources (e.g, `GPU=UUID1`).\n    type: \"array\"\n    items:\n      type: \"object\"\n      properties:\n        NamedResourceSpec:\n          type: \"object\"\n          properties:\n            Kind:\n              type: \"string\"\n            Value:\n              type: \"string\"\n        DiscreteResourceSpec:\n          type: \"object\"\n          properties:\n            Kind:\n              type: \"string\"\n            Value:\n              type: \"integer\"\n              format: \"int64\"\n    example:\n      - DiscreteResourceSpec:\n          Kind: \"SSD\"\n          Value: 3\n      - NamedResourceSpec:\n          Kind: \"GPU\"\n          Value: \"UUID1\"\n      - NamedResourceSpec:\n          Kind: \"GPU\"\n          Value: \"UUID2\"\n\n  HealthConfig:\n    description: \"A test to perform to check that the container is healthy.\"\n    type: \"object\"\n    properties:\n      Test:\n        description: |\n          The test to perform. Possible values are:\n\n          - `[]` inherit healthcheck from image or parent image\n          - `[\"NONE\"]` disable healthcheck\n          - `[\"CMD\", args...]` exec arguments directly\n          - `[\"CMD-SHELL\", command]` run command with system's default shell\n        type: \"array\"\n        items:\n          type: \"string\"\n      Interval:\n        description: |\n          The time to wait between checks in nanoseconds. It should be 0 or at\n          least 1000000 (1 ms). 0 means inherit.\n        type: \"integer\"\n        format: \"int64\"\n      Timeout:\n        description: |\n          The time to wait before considering the check to have hung. It should\n          be 0 or at least 1000000 (1 ms). 0 means inherit.\n        type: \"integer\"\n        format: \"int64\"\n      Retries:\n        description: |\n          The number of consecutive failures needed to consider a container as\n          unhealthy. 0 means inherit.\n        type: \"integer\"\n      StartPeriod:\n        description: |\n          Start period for the container to initialize before starting\n          health-retries countdown in nanoseconds. It should be 0 or at least\n          1000000 (1 ms). 0 means inherit.\n        type: \"integer\"\n        format: \"int64\"\n      StartInterval:\n        description: |\n          The time to wait between checks in nanoseconds during the start period.\n          It should be 0 or at least 1000000 (1 ms). 0 means inherit.\n        type: \"integer\"\n        format: \"int64\"\n\n  Health:\n    description: |\n      Health stores information about the container's healthcheck results.\n    type: \"object\"\n    x-nullable: true\n    properties:\n      Status:\n        description: |\n          Status is one of `none`, `starting`, `healthy` or `unhealthy`\n\n          - \"none\"      Indicates there is no healthcheck\n          - \"starting\"  Starting indicates that the container is not yet ready\n          - \"healthy\"   Healthy indicates that the container is running correctly\n          - \"unhealthy\" Unhealthy indicates that the container has a problem\n        type: \"string\"\n        enum:\n          - \"none\"\n          - \"starting\"\n          - \"healthy\"\n          - \"unhealthy\"\n        example: \"healthy\"\n      FailingStreak:\n        description: \"FailingStreak is the number of consecutive failures\"\n        type: \"integer\"\n        example: 0\n      Log:\n        type: \"array\"\n        description: |\n          Log contains the last few results (oldest first)\n        items:\n          $ref: \"#/definitions/HealthcheckResult\"\n\n  HealthcheckResult:\n    description: |\n      HealthcheckResult stores information about a single run of a healthcheck probe\n    type: \"object\"\n    x-nullable: true\n    properties:\n      Start:\n        description: |\n          Date and time at which this check started in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"date-time\"\n        example: \"2020-01-04T10:44:24.496525531Z\"\n      End:\n        description: |\n          Date and time at which this check ended in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2020-01-04T10:45:21.364524523Z\"\n      ExitCode:\n        description: |\n          ExitCode meanings:\n\n          - `0` healthy\n          - `1` unhealthy\n          - `2` reserved (considered unhealthy)\n          - other values: error running probe\n        type: \"integer\"\n        example: 0\n      Output:\n        description: \"Output from last check\"\n        type: \"string\"\n\n  HostConfig:\n    description: \"Container configuration that depends on the host we are running on\"\n    allOf:\n      - $ref: \"#/definitions/Resources\"\n      - type: \"object\"\n        properties:\n          # Applicable to all platforms\n          Binds:\n            type: \"array\"\n            description: |\n              A list of volume bindings for this container. Each volume binding\n              is a string in one of these forms:\n\n              - `host-src:container-dest[:options]` to bind-mount a host path\n                into the container. Both `host-src`, and `container-dest` must\n                be an _absolute_ path.\n              - `volume-name:container-dest[:options]` to bind-mount a volume\n                managed by a volume driver into the container. `container-dest`\n                must be an _absolute_ path.\n\n              `options` is an optional, comma-delimited list of:\n\n              - `nocopy` disables automatic copying of data from the container\n                path to the volume. The `nocopy` flag only applies to named volumes.\n              - `[ro|rw]` mounts a volume read-only or read-write, respectively.\n                If omitted or set to `rw`, volumes are mounted read-write.\n              - `[z|Z]` applies SELinux labels to allow or deny multiple containers\n                to read and write to the same volume.\n                  - `z`: a _shared_ content label is applied to the content. This\n                    label indicates that multiple containers can share the volume\n                    content, for both reading and writing.\n                  - `Z`: a _private unshared_ label is applied to the content.\n                    This label indicates that only the current container can use\n                    a private volume. Labeling systems such as SELinux require\n                    proper labels to be placed on volume content that is mounted\n                    into a container. Without a label, the security system can\n                    prevent a container's processes from using the content. By\n                    default, the labels set by the host operating system are not\n                    modified.\n              - `[[r]shared|[r]slave|[r]private]` specifies mount\n                [propagation behavior](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt).\n                This only applies to bind-mounted volumes, not internal volumes\n                or named volumes. Mount propagation requires the source mount\n                point (the location where the source directory is mounted in the\n                host operating system) to have the correct propagation properties.\n                For shared volumes, the source mount point must be set to `shared`.\n                For slave volumes, the mount must be set to either `shared` or\n                `slave`.\n            items:\n              type: \"string\"\n          ContainerIDFile:\n            type: \"string\"\n            description: \"Path to a file where the container ID is written\"\n          LogConfig:\n            type: \"object\"\n            description: \"The logging configuration for this container\"\n            properties:\n              Type:\n                type: \"string\"\n                enum:\n                  - \"json-file\"\n                  - \"syslog\"\n                  - \"journald\"\n                  - \"gelf\"\n                  - \"fluentd\"\n                  - \"awslogs\"\n                  - \"splunk\"\n                  - \"etwlogs\"\n                  - \"none\"\n              Config:\n                type: \"object\"\n                additionalProperties:\n                  type: \"string\"\n          NetworkMode:\n            type: \"string\"\n            description: |\n              Network mode to use for this container. Supported standard values\n              are: `bridge`, `host`, `none`, and `container:<name|id>`. Any\n              other value is taken as a custom network's name to which this\n              container should connect to.\n          PortBindings:\n            $ref: \"#/definitions/PortMap\"\n          RestartPolicy:\n            $ref: \"#/definitions/RestartPolicy\"\n          AutoRemove:\n            type: \"boolean\"\n            description: |\n              Automatically remove the container when the container's process\n              exits. This has no effect if `RestartPolicy` is set.\n          VolumeDriver:\n            type: \"string\"\n            description: \"Driver that this container uses to mount volumes.\"\n          VolumesFrom:\n            type: \"array\"\n            description: |\n              A list of volumes to inherit from another container, specified in\n              the form `<container name>[:<ro|rw>]`.\n            items:\n              type: \"string\"\n          Mounts:\n            description: |\n              Specification for mounts to be added to the container.\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Mount\"\n          ConsoleSize:\n            type: \"array\"\n            description: |\n              Initial console size, as an `[height, width]` array.\n            x-nullable: true\n            minItems: 2\n            maxItems: 2\n            items:\n              type: \"integer\"\n              minimum: 0\n          Annotations:\n            type: \"object\"\n            description: |\n              Arbitrary non-identifying metadata attached to container and\n              provided to the runtime when the container is started.\n            additionalProperties:\n              type: \"string\"\n\n          # Applicable to UNIX platforms\n          CapAdd:\n            type: \"array\"\n            description: |\n              A list of kernel capabilities to add to the container. Conflicts\n              with option 'Capabilities'.\n            items:\n              type: \"string\"\n          CapDrop:\n            type: \"array\"\n            description: |\n              A list of kernel capabilities to drop from the container. Conflicts\n              with option 'Capabilities'.\n            items:\n              type: \"string\"\n          CgroupnsMode:\n            type: \"string\"\n            enum:\n              - \"private\"\n              - \"host\"\n            description: |\n              cgroup namespace mode for the container. Possible values are:\n\n              - `\"private\"`: the container runs in its own private cgroup namespace\n              - `\"host\"`: use the host system's cgroup namespace\n\n              If not specified, the daemon default is used, which can either be `\"private\"`\n              or `\"host\"`, depending on daemon version, kernel support and configuration.\n          Dns:\n            type: \"array\"\n            description: \"A list of DNS servers for the container to use.\"\n            items:\n              type: \"string\"\n          DnsOptions:\n            type: \"array\"\n            description: \"A list of DNS options.\"\n            items:\n              type: \"string\"\n          DnsSearch:\n            type: \"array\"\n            description: \"A list of DNS search domains.\"\n            items:\n              type: \"string\"\n          ExtraHosts:\n            type: \"array\"\n            description: |\n              A list of hostnames/IP mappings to add to the container's `/etc/hosts`\n              file. Specified in the form `[\"hostname:IP\"]`.\n            items:\n              type: \"string\"\n          GroupAdd:\n            type: \"array\"\n            description: |\n              A list of additional groups that the container process will run as.\n            items:\n              type: \"string\"\n          IpcMode:\n            type: \"string\"\n            description: |\n              IPC sharing mode for the container. Possible values are:\n\n              - `\"none\"`: own private IPC namespace, with /dev/shm not mounted\n              - `\"private\"`: own private IPC namespace\n              - `\"shareable\"`: own private IPC namespace, with a possibility to share it with other containers\n              - `\"container:<name|id>\"`: join another (shareable) container's IPC namespace\n              - `\"host\"`: use the host system's IPC namespace\n\n              If not specified, daemon default is used, which can either be `\"private\"`\n              or `\"shareable\"`, depending on daemon version and configuration.\n          Cgroup:\n            type: \"string\"\n            description: \"Cgroup to use for the container.\"\n          Links:\n            type: \"array\"\n            description: |\n              A list of links for the container in the form `container_name:alias`.\n            items:\n              type: \"string\"\n          OomScoreAdj:\n            type: \"integer\"\n            description: |\n              An integer value containing the score given to the container in\n              order to tune OOM killer preferences.\n            example: 500\n          PidMode:\n            type: \"string\"\n            description: |\n              Set the PID (Process) Namespace mode for the container. It can be\n              either:\n\n              - `\"container:<name|id>\"`: joins another container's PID namespace\n              - `\"host\"`: use the host's PID namespace inside the container\n          Privileged:\n            type: \"boolean\"\n            description: \"Gives the container full access to the host.\"\n          PublishAllPorts:\n            type: \"boolean\"\n            description: |\n              Allocates an ephemeral host port for all of a container's\n              exposed ports.\n\n              Ports are de-allocated when the container stops and allocated when\n              the container starts. The allocated port might be changed when\n              restarting the container.\n\n              The port is selected from the ephemeral port range that depends on\n              the kernel. For example, on Linux the range is defined by\n              `/proc/sys/net/ipv4/ip_local_port_range`.\n          ReadonlyRootfs:\n            type: \"boolean\"\n            description: \"Mount the container's root filesystem as read only.\"\n          SecurityOpt:\n            type: \"array\"\n            description: |\n              A list of string values to customize labels for MLS systems, such\n              as SELinux.\n            items:\n              type: \"string\"\n          StorageOpt:\n            type: \"object\"\n            description: |\n              Storage driver options for this container, in the form `{\"size\": \"120G\"}`.\n            additionalProperties:\n              type: \"string\"\n          Tmpfs:\n            type: \"object\"\n            description: |\n              A map of container directories which should be replaced by tmpfs\n              mounts, and their corresponding mount options. For example:\n\n              ```\n              { \"/run\": \"rw,noexec,nosuid,size=65536k\" }\n              ```\n            additionalProperties:\n              type: \"string\"\n          UTSMode:\n            type: \"string\"\n            description: \"UTS namespace to use for the container.\"\n          UsernsMode:\n            type: \"string\"\n            description: |\n              Sets the usernamespace mode for the container when usernamespace\n              remapping option is enabled.\n          ShmSize:\n            type: \"integer\"\n            format: \"int64\"\n            description: |\n              Size of `/dev/shm` in bytes. If omitted, the system uses 64MB.\n            minimum: 0\n          Sysctls:\n            type: \"object\"\n            description: |\n              A list of kernel parameters (sysctls) to set in the container.\n              For example:\n\n              ```\n              {\"net.ipv4.ip_forward\": \"1\"}\n              ```\n            additionalProperties:\n              type: \"string\"\n          Runtime:\n            type: \"string\"\n            description: \"Runtime to use with this container.\"\n          # Applicable to Windows\n          Isolation:\n            type: \"string\"\n            description: |\n              Isolation technology of the container. (Windows only)\n            enum:\n              - \"default\"\n              - \"process\"\n              - \"hyperv\"\n          MaskedPaths:\n            type: \"array\"\n            description: |\n              The list of paths to be masked inside the container (this overrides\n              the default set of paths).\n            items:\n              type: \"string\"\n          ReadonlyPaths:\n            type: \"array\"\n            description: |\n              The list of paths to be set as read-only inside the container\n              (this overrides the default set of paths).\n            items:\n              type: \"string\"\n\n  ContainerConfig:\n    description: |\n      Configuration for a container that is portable between hosts.\n\n      When used as `ContainerConfig` field in an image, `ContainerConfig` is an\n      optional field containing the configuration of the container that was last\n      committed when creating the image.\n\n      Previous versions of Docker builder used this field to store build cache,\n      and it is not in active use anymore.\n    type: \"object\"\n    properties:\n      Hostname:\n        description: |\n          The hostname to use for the container, as a valid RFC 1123 hostname.\n        type: \"string\"\n        example: \"439f4e91bd1d\"\n      Domainname:\n        description: |\n          The domain name to use for the container.\n        type: \"string\"\n      User:\n        description: \"The user that commands are run as inside the container.\"\n        type: \"string\"\n      AttachStdin:\n        description: \"Whether to attach to `stdin`.\"\n        type: \"boolean\"\n        default: false\n      AttachStdout:\n        description: \"Whether to attach to `stdout`.\"\n        type: \"boolean\"\n        default: true\n      AttachStderr:\n        description: \"Whether to attach to `stderr`.\"\n        type: \"boolean\"\n        default: true\n      ExposedPorts:\n        description: |\n          An object mapping ports to an empty object in the form:\n\n          `{\"<port>/<tcp|udp|sctp>\": {}}`\n        type: \"object\"\n        x-nullable: true\n        additionalProperties:\n          type: \"object\"\n          enum:\n            - {}\n          default: {}\n        example: {\n          \"80/tcp\": {},\n          \"443/tcp\": {}\n        }\n      Tty:\n        description: |\n          Attach standard streams to a TTY, including `stdin` if it is not closed.\n        type: \"boolean\"\n        default: false\n      OpenStdin:\n        description: \"Open `stdin`\"\n        type: \"boolean\"\n        default: false\n      StdinOnce:\n        description: \"Close `stdin` after one attached client disconnects\"\n        type: \"boolean\"\n        default: false\n      Env:\n        description: |\n          A list of environment variables to set inside the container in the\n          form `[\"VAR=value\", ...]`. A variable without `=` is removed from the\n          environment, rather than to have an empty value.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\n      Cmd:\n        description: |\n          Command to run specified as a string or an array of strings.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"/bin/sh\"]\n      Healthcheck:\n        $ref: \"#/definitions/HealthConfig\"\n      ArgsEscaped:\n        description: \"Command is already escaped (Windows only)\"\n        type: \"boolean\"\n        default: false\n        example: false\n        x-nullable: true\n      Image:\n        description: |\n          The name (or reference) of the image to use when creating the container,\n          or which was used when the container was created.\n        type: \"string\"\n        example: \"example-image:1.0\"\n      Volumes:\n        description: |\n          An object mapping mount point paths inside the container to empty\n          objects.\n        type: \"object\"\n        additionalProperties:\n          type: \"object\"\n          enum:\n            - {}\n          default: {}\n      WorkingDir:\n        description: \"The working directory for commands to run in.\"\n        type: \"string\"\n        example: \"/public/\"\n      Entrypoint:\n        description: |\n          The entry point for the container as a string or an array of strings.\n\n          If the array consists of exactly one empty string (`[\"\"]`) then the\n          entry point is reset to system default (i.e., the entry point used by\n          docker when there is no `ENTRYPOINT` instruction in the `Dockerfile`).\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: []\n      NetworkDisabled:\n        description: \"Disable networking for the container.\"\n        type: \"boolean\"\n        x-nullable: true\n      MacAddress:\n        description: |\n          MAC address of the container.\n\n          Deprecated: this field is deprecated in API v1.44 and up. Use EndpointSettings.MacAddress instead.\n        type: \"string\"\n        x-nullable: true\n      OnBuild:\n        description: |\n          `ONBUILD` metadata that were defined in the image's `Dockerfile`.\n        type: \"array\"\n        x-nullable: true\n        items:\n          type: \"string\"\n        example: []\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.some-label: \"some-value\"\n          com.example.some-other-label: \"some-other-value\"\n      StopSignal:\n        description: |\n          Signal to stop a container as a string or unsigned integer.\n        type: \"string\"\n        example: \"SIGTERM\"\n        x-nullable: true\n      StopTimeout:\n        description: \"Timeout to stop a container in seconds.\"\n        type: \"integer\"\n        default: 10\n        x-nullable: true\n      Shell:\n        description: |\n          Shell for when `RUN`, `CMD`, and `ENTRYPOINT` uses a shell.\n        type: \"array\"\n        x-nullable: true\n        items:\n          type: \"string\"\n        example: [\"/bin/sh\", \"-c\"]\n\n  NetworkingConfig:\n    description: |\n      NetworkingConfig represents the container's networking configuration for\n      each of its interfaces.\n      It is used for the networking configs specified in the `docker create`\n      and `docker network connect` commands.\n    type: \"object\"\n    properties:\n      EndpointsConfig:\n        description: |\n          A mapping of network name to endpoint configuration for that network.\n          The endpoint configuration can be left empty to connect to that\n          network with no particular endpoint configuration.\n        type: \"object\"\n        additionalProperties:\n          $ref: \"#/definitions/EndpointSettings\"\n    example:\n      # putting an example here, instead of using the example values from\n      # /definitions/EndpointSettings, because EndpointSettings contains\n      # operational data returned when inspecting a container that we don't\n      # accept here.\n      EndpointsConfig:\n        isolated_nw:\n          IPAMConfig:\n            IPv4Address: \"172.20.30.33\"\n            IPv6Address: \"2001:db8:abcd::3033\"\n            LinkLocalIPs:\n              - \"169.254.34.68\"\n              - \"fe80::3468\"\n          MacAddress: \"02:42:ac:12:05:02\"\n          Links:\n            - \"container_1\"\n            - \"container_2\"\n          Aliases:\n            - \"server_x\"\n            - \"server_y\"\n        database_nw: {}\n\n  NetworkSettings:\n    description: \"NetworkSettings exposes the network settings in the API\"\n    type: \"object\"\n    properties:\n      Bridge:\n        description: |\n          Name of the default bridge interface when dockerd's --bridge flag is set.\n        type: \"string\"\n        example: \"docker0\"\n      SandboxID:\n        description: SandboxID uniquely represents a container's network stack.\n        type: \"string\"\n        example: \"9d12daf2c33f5959c8bf90aa513e4f65b561738661003029ec84830cd503a0c3\"\n      HairpinMode:\n        description: |\n          Indicates if hairpin NAT should be enabled on the virtual interface.\n\n          Deprecated: This field is never set and will be removed in a future release.\n        type: \"boolean\"\n        example: false\n      LinkLocalIPv6Address:\n        description: |\n          IPv6 unicast address using the link-local prefix.\n\n          Deprecated: This field is never set and will be removed in a future release.\n        type: \"string\"\n        example: \"\"\n      LinkLocalIPv6PrefixLen:\n        description: |\n          Prefix length of the IPv6 unicast address.\n\n          Deprecated: This field is never set and will be removed in a future release.\n        type: \"integer\"\n        example: \"\"\n      Ports:\n        $ref: \"#/definitions/PortMap\"\n      SandboxKey:\n        description: SandboxKey is the full path of the netns handle\n        type: \"string\"\n        example: \"/var/run/docker/netns/8ab54b426c38\"\n\n      SecondaryIPAddresses:\n        description: \"Deprecated: This field is never set and will be removed in a future release.\"\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/Address\"\n        x-nullable: true\n\n      SecondaryIPv6Addresses:\n        description: \"Deprecated: This field is never set and will be removed in a future release.\"\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/Address\"\n        x-nullable: true\n\n      # TODO properties below are part of DefaultNetworkSettings, which is\n      # marked as deprecated since Docker 1.9 and to be removed in Docker v17.12\n      EndpointID:\n        description: |\n          EndpointID uniquely represents a service endpoint in a Sandbox.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"string\"\n        example: \"b88f5b905aabf2893f3cbc4ee42d1ea7980bbc0a92e2c8922b1e1795298afb0b\"\n      Gateway:\n        description: |\n          Gateway address for the default \"bridge\" network.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"string\"\n        example: \"172.17.0.1\"\n      GlobalIPv6Address:\n        description: |\n          Global IPv6 address for the default \"bridge\" network.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"string\"\n        example: \"2001:db8::5689\"\n      GlobalIPv6PrefixLen:\n        description: |\n          Mask length of the global IPv6 address.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"integer\"\n        example: 64\n      IPAddress:\n        description: |\n          IPv4 address for the default \"bridge\" network.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"string\"\n        example: \"172.17.0.4\"\n      IPPrefixLen:\n        description: |\n          Mask length of the IPv4 address.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"integer\"\n        example: 16\n      IPv6Gateway:\n        description: |\n          IPv6 gateway address for this network.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"string\"\n        example: \"2001:db8:2::100\"\n      MacAddress:\n        description: |\n          MAC address for the container on the default \"bridge\" network.\n\n          <p><br /></p>\n\n          > **Deprecated**: This field is only propagated when attached to the\n          > default \"bridge\" network. Use the information from the \"bridge\"\n          > network inside the `Networks` map instead, which contains the same\n          > information. This field was deprecated in Docker 1.9 and is scheduled\n          > to be removed in Docker 17.12.0\n        type: \"string\"\n        example: \"02:42:ac:11:00:04\"\n      Networks:\n        description: |\n          Information about all networks that the container is connected to.\n        type: \"object\"\n        additionalProperties:\n          $ref: \"#/definitions/EndpointSettings\"\n\n  Address:\n    description: Address represents an IPv4 or IPv6 IP address.\n    type: \"object\"\n    properties:\n      Addr:\n        description: IP address.\n        type: \"string\"\n      PrefixLen:\n        description: Mask length of the IP address.\n        type: \"integer\"\n\n  PortMap:\n    description: |\n      PortMap describes the mapping of container ports to host ports, using the\n      container's port-number and protocol as key in the format `<port>/<protocol>`,\n      for example, `80/udp`.\n\n      If a container's port is mapped for multiple protocols, separate entries\n      are added to the mapping table.\n    type: \"object\"\n    additionalProperties:\n      type: \"array\"\n      x-nullable: true\n      items:\n        $ref: \"#/definitions/PortBinding\"\n    example:\n      \"443/tcp\":\n        - HostIp: \"127.0.0.1\"\n          HostPort: \"4443\"\n      \"80/tcp\":\n        - HostIp: \"0.0.0.0\"\n          HostPort: \"80\"\n        - HostIp: \"0.0.0.0\"\n          HostPort: \"8080\"\n      \"80/udp\":\n        - HostIp: \"0.0.0.0\"\n          HostPort: \"80\"\n      \"53/udp\":\n        - HostIp: \"0.0.0.0\"\n          HostPort: \"53\"\n      \"2377/tcp\": null\n\n  PortBinding:\n    description: |\n      PortBinding represents a binding between a host IP address and a host\n      port.\n    type: \"object\"\n    properties:\n      HostIp:\n        description: \"Host IP address that the container's port is mapped to.\"\n        type: \"string\"\n        example: \"127.0.0.1\"\n      HostPort:\n        description: \"Host port number that the container's port is mapped to.\"\n        type: \"string\"\n        example: \"4443\"\n\n  GraphDriverData:\n    description: |\n      Information about the storage driver used to store the container's and\n      image's filesystem.\n    type: \"object\"\n    required: [Name, Data]\n    properties:\n      Name:\n        description: \"Name of the storage driver.\"\n        type: \"string\"\n        x-nullable: false\n        example: \"overlay2\"\n      Data:\n        description: |\n          Low-level storage metadata, provided as key/value pairs.\n\n          This information is driver-specific, and depends on the storage-driver\n          in use, and should be used for informational purposes only.\n        type: \"object\"\n        x-nullable: false\n        additionalProperties:\n          type: \"string\"\n        example: {\n          \"MergedDir\": \"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/merged\",\n          \"UpperDir\": \"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/diff\",\n          \"WorkDir\": \"/var/lib/docker/overlay2/ef749362d13333e65fc95c572eb525abbe0052e16e086cb64bc3b98ae9aa6d74/work\"\n        }\n\n  FilesystemChange:\n    description: |\n      Change in the container's filesystem.\n    type: \"object\"\n    required: [Path, Kind]\n    properties:\n      Path:\n        description: |\n          Path to file or directory that has changed.\n        type: \"string\"\n        x-nullable: false\n      Kind:\n        $ref: \"#/definitions/ChangeType\"\n\n  ChangeType:\n    description: |\n      Kind of change\n\n      Can be one of:\n\n      - `0`: Modified (\"C\")\n      - `1`: Added (\"A\")\n      - `2`: Deleted (\"D\")\n    type: \"integer\"\n    format: \"uint8\"\n    enum: [0, 1, 2]\n    x-nullable: false\n\n  ImageInspect:\n    description: |\n      Information about an image in the local image cache.\n    type: \"object\"\n    properties:\n      Id:\n        description: |\n          ID is the content-addressable ID of an image.\n\n          This identifier is a content-addressable digest calculated from the\n          image's configuration (which includes the digests of layers used by\n          the image).\n\n          Note that this digest differs from the `RepoDigests` below, which\n          holds digests of image manifests that reference the image.\n        type: \"string\"\n        x-nullable: false\n        example: \"sha256:ec3f0931a6e6b6855d76b2d7b0be30e81860baccd891b2e243280bf1cd8ad710\"\n      RepoTags:\n        description: |\n          List of image names/tags in the local image cache that reference this\n          image.\n\n          Multiple image tags can refer to the same image, and this list may be\n          empty if no tags reference the image, in which case the image is\n          \"untagged\", in which case it can still be referenced by its ID.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"example:1.0\"\n          - \"example:latest\"\n          - \"example:stable\"\n          - \"internal.registry.example.com:5000/example:1.0\"\n      RepoDigests:\n        description: |\n          List of content-addressable digests of locally available image manifests\n          that the image is referenced from. Multiple manifests can refer to the\n          same image.\n\n          These digests are usually only available if the image was either pulled\n          from a registry, or if the image was pushed to a registry, which is when\n          the manifest is generated and its digest calculated.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb\"\n          - \"internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578\"\n      Parent:\n        description: |\n          ID of the parent image.\n\n          Depending on how the image was created, this field may be empty and\n          is only set for images that were built/created locally. This field\n          is empty if the image was pulled from an image registry.\n        type: \"string\"\n        x-nullable: false\n        example: \"\"\n      Comment:\n        description: |\n          Optional message that was set when committing or importing the image.\n        type: \"string\"\n        x-nullable: false\n        example: \"\"\n      Created:\n        description: |\n          Date and time at which the image was created, formatted in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n\n          This information is only available if present in the image,\n          and omitted otherwise.\n        type: \"string\"\n        format: \"dateTime\"\n        x-nullable: true\n        example: \"2022-02-04T21:20:12.497794809Z\"\n      Container:\n        description: |\n          The ID of the container that was used to create the image.\n\n          Depending on how the image was created, this field may be empty.\n\n          **Deprecated**: this field is kept for backward compatibility, but\n          will be removed in API v1.45.\n        type: \"string\"\n        example: \"65974bc86f1770ae4bff79f651ebdbce166ae9aada632ee3fa9af3a264911735\"\n      ContainerConfig:\n        description: |\n          **Deprecated**: this field is kept for backward compatibility, but\n          will be removed in API v1.45.\n        $ref: \"#/definitions/ContainerConfig\"\n      DockerVersion:\n        description: |\n          The version of Docker that was used to build the image.\n\n          Depending on how the image was created, this field may be empty.\n        type: \"string\"\n        x-nullable: false\n        example: \"20.10.7\"\n      Author:\n        description: |\n          Name of the author that was specified when committing the image, or as\n          specified through MAINTAINER (deprecated) in the Dockerfile.\n        type: \"string\"\n        x-nullable: false\n        example: \"\"\n      Config:\n        $ref: \"#/definitions/ContainerConfig\"\n      Architecture:\n        description: |\n          Hardware CPU architecture that the image runs on.\n        type: \"string\"\n        x-nullable: false\n        example: \"arm\"\n      Variant:\n        description: |\n          CPU architecture variant (presently ARM-only).\n        type: \"string\"\n        x-nullable: true\n        example: \"v7\"\n      Os:\n        description: |\n          Operating System the image is built to run on.\n        type: \"string\"\n        x-nullable: false\n        example: \"linux\"\n      OsVersion:\n        description: |\n          Operating System version the image is built to run on (especially\n          for Windows).\n        type: \"string\"\n        example: \"\"\n        x-nullable: true\n      Size:\n        description: |\n          Total size of the image including all layers it is composed of.\n        type: \"integer\"\n        format: \"int64\"\n        x-nullable: false\n        example: 1239828\n      VirtualSize:\n        description: |\n          Total size of the image including all layers it is composed of.\n\n          Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead.\n        type: \"integer\"\n        format: \"int64\"\n        example: 1239828\n      GraphDriver:\n        $ref: \"#/definitions/GraphDriverData\"\n      RootFS:\n        description: |\n          Information about the image's RootFS, including the layer IDs.\n        type: \"object\"\n        required: [Type]\n        properties:\n          Type:\n            type: \"string\"\n            x-nullable: false\n            example: \"layers\"\n          Layers:\n            type: \"array\"\n            items:\n              type: \"string\"\n            example:\n              - \"sha256:1834950e52ce4d5a88a1bbd131c537f4d0e56d10ff0dd69e66be3b7dfa9df7e6\"\n              - \"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef\"\n      Metadata:\n        description: |\n          Additional metadata of the image in the local cache. This information\n          is local to the daemon, and not part of the image itself.\n        type: \"object\"\n        properties:\n          LastTagTime:\n            description: |\n              Date and time at which the image was last tagged in\n              [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n\n              This information is only available if the image was tagged locally,\n              and omitted otherwise.\n            type: \"string\"\n            format: \"dateTime\"\n            example: \"2022-02-28T14:40:02.623929178Z\"\n            x-nullable: true\n  ImageSummary:\n    type: \"object\"\n    x-go-name: \"Summary\"\n    required:\n      - Id\n      - ParentId\n      - RepoTags\n      - RepoDigests\n      - Created\n      - Size\n      - SharedSize\n      - Labels\n      - Containers\n    properties:\n      Id:\n        description: |\n          ID is the content-addressable ID of an image.\n\n          This identifier is a content-addressable digest calculated from the\n          image's configuration (which includes the digests of layers used by\n          the image).\n\n          Note that this digest differs from the `RepoDigests` below, which\n          holds digests of image manifests that reference the image.\n        type: \"string\"\n        x-nullable: false\n        example: \"sha256:ec3f0931a6e6b6855d76b2d7b0be30e81860baccd891b2e243280bf1cd8ad710\"\n      ParentId:\n        description: |\n          ID of the parent image.\n\n          Depending on how the image was created, this field may be empty and\n          is only set for images that were built/created locally. This field\n          is empty if the image was pulled from an image registry.\n        type: \"string\"\n        x-nullable: false\n        example: \"\"\n      RepoTags:\n        description: |\n          List of image names/tags in the local image cache that reference this\n          image.\n\n          Multiple image tags can refer to the same image, and this list may be\n          empty if no tags reference the image, in which case the image is\n          \"untagged\", in which case it can still be referenced by its ID.\n        type: \"array\"\n        x-nullable: false\n        items:\n          type: \"string\"\n        example:\n          - \"example:1.0\"\n          - \"example:latest\"\n          - \"example:stable\"\n          - \"internal.registry.example.com:5000/example:1.0\"\n      RepoDigests:\n        description: |\n          List of content-addressable digests of locally available image manifests\n          that the image is referenced from. Multiple manifests can refer to the\n          same image.\n\n          These digests are usually only available if the image was either pulled\n          from a registry, or if the image was pushed to a registry, which is when\n          the manifest is generated and its digest calculated.\n        type: \"array\"\n        x-nullable: false\n        items:\n          type: \"string\"\n        example:\n          - \"example@sha256:afcc7f1ac1b49db317a7196c902e61c6c3c4607d63599ee1a82d702d249a0ccb\"\n          - \"internal.registry.example.com:5000/example@sha256:b69959407d21e8a062e0416bf13405bb2b71ed7a84dde4158ebafacfa06f5578\"\n      Created:\n        description: |\n          Date and time at which the image was created as a Unix timestamp\n          (number of seconds sinds EPOCH).\n        type: \"integer\"\n        x-nullable: false\n        example: \"1644009612\"\n      Size:\n        description: |\n          Total size of the image including all layers it is composed of.\n        type: \"integer\"\n        format: \"int64\"\n        x-nullable: false\n        example: 172064416\n      SharedSize:\n        description: |\n          Total size of image layers that are shared between this image and other\n          images.\n\n          This size is not calculated by default. `-1` indicates that the value\n          has not been set / calculated.\n        type: \"integer\"\n        format: \"int64\"\n        x-nullable: false\n        example: 1239828\n      VirtualSize:\n        description: |-\n          Total size of the image including all layers it is composed of.\n\n          Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead.\n        type: \"integer\"\n        format: \"int64\"\n        example: 172064416\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        x-nullable: false\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.some-label: \"some-value\"\n          com.example.some-other-label: \"some-other-value\"\n      Containers:\n        description: |\n          Number of containers using this image. Includes both stopped and running\n          containers.\n\n          This size is not calculated by default, and depends on which API endpoint\n          is used. `-1` indicates that the value has not been set / calculated.\n        x-nullable: false\n        type: \"integer\"\n        example: 2\n\n  AuthConfig:\n    type: \"object\"\n    properties:\n      username:\n        type: \"string\"\n      password:\n        type: \"string\"\n      email:\n        type: \"string\"\n      serveraddress:\n        type: \"string\"\n    example:\n      username: \"hannibal\"\n      password: \"xxxx\"\n      serveraddress: \"https://index.docker.io/v1/\"\n\n  ProcessConfig:\n    type: \"object\"\n    properties:\n      privileged:\n        type: \"boolean\"\n      user:\n        type: \"string\"\n      tty:\n        type: \"boolean\"\n      entrypoint:\n        type: \"string\"\n      arguments:\n        type: \"array\"\n        items:\n          type: \"string\"\n\n  Volume:\n    type: \"object\"\n    required: [Name, Driver, Mountpoint, Labels, Scope, Options]\n    properties:\n      Name:\n        type: \"string\"\n        description: \"Name of the volume.\"\n        x-nullable: false\n        example: \"tardis\"\n      Driver:\n        type: \"string\"\n        description: \"Name of the volume driver used by the volume.\"\n        x-nullable: false\n        example: \"custom\"\n      Mountpoint:\n        type: \"string\"\n        description: \"Mount path of the volume on the host.\"\n        x-nullable: false\n        example: \"/var/lib/docker/volumes/tardis\"\n      CreatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n        description: \"Date/Time the volume was created.\"\n        example: \"2016-06-07T20:31:11.853781916Z\"\n      Status:\n        type: \"object\"\n        description: |\n          Low-level details about the volume, provided by the volume driver.\n          Details are returned as a map with key/value pairs:\n          `{\"key\":\"value\",\"key2\":\"value2\"}`.\n\n          The `Status` field is optional, and is omitted if the volume driver\n          does not support this feature.\n        additionalProperties:\n          type: \"object\"\n        example:\n          hello: \"world\"\n      Labels:\n        type: \"object\"\n        description: \"User-defined key/value metadata.\"\n        x-nullable: false\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.some-label: \"some-value\"\n          com.example.some-other-label: \"some-other-value\"\n      Scope:\n        type: \"string\"\n        description: |\n          The level at which the volume exists. Either `global` for cluster-wide,\n          or `local` for machine level.\n        default: \"local\"\n        x-nullable: false\n        enum: [\"local\", \"global\"]\n        example: \"local\"\n      ClusterVolume:\n        $ref: \"#/definitions/ClusterVolume\"\n      Options:\n        type: \"object\"\n        description: |\n          The driver specific options used when creating the volume.\n        additionalProperties:\n          type: \"string\"\n        example:\n          device: \"tmpfs\"\n          o: \"size=100m,uid=1000\"\n          type: \"tmpfs\"\n      UsageData:\n        type: \"object\"\n        x-nullable: true\n        x-go-name: \"UsageData\"\n        required: [Size, RefCount]\n        description: |\n          Usage details about the volume. This information is used by the\n          `GET /system/df` endpoint, and omitted in other endpoints.\n        properties:\n          Size:\n            type: \"integer\"\n            format: \"int64\"\n            default: -1\n            description: |\n              Amount of disk space used by the volume (in bytes). This information\n              is only available for volumes created with the `\"local\"` volume\n              driver. For volumes created with other volume drivers, this field\n              is set to `-1` (\"not available\")\n            x-nullable: false\n          RefCount:\n            type: \"integer\"\n            format: \"int64\"\n            default: -1\n            description: |\n              The number of containers referencing this volume. This field\n              is set to `-1` if the reference-count is not available.\n            x-nullable: false\n\n  VolumeCreateOptions:\n    description: \"Volume configuration\"\n    type: \"object\"\n    title: \"VolumeConfig\"\n    x-go-name: \"CreateOptions\"\n    properties:\n      Name:\n        description: |\n          The new volume's name. If not specified, Docker generates a name.\n        type: \"string\"\n        x-nullable: false\n        example: \"tardis\"\n      Driver:\n        description: \"Name of the volume driver to use.\"\n        type: \"string\"\n        default: \"local\"\n        x-nullable: false\n        example: \"custom\"\n      DriverOpts:\n        description: |\n          A mapping of driver options and values. These options are\n          passed directly to the driver and are driver specific.\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n        example:\n          device: \"tmpfs\"\n          o: \"size=100m,uid=1000\"\n          type: \"tmpfs\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.some-label: \"some-value\"\n          com.example.some-other-label: \"some-other-value\"\n      ClusterVolumeSpec:\n        $ref: \"#/definitions/ClusterVolumeSpec\"\n\n  VolumeListResponse:\n    type: \"object\"\n    title: \"VolumeListResponse\"\n    x-go-name: \"ListResponse\"\n    description: \"Volume list response\"\n    properties:\n      Volumes:\n        type: \"array\"\n        description: \"List of volumes\"\n        items:\n          $ref: \"#/definitions/Volume\"\n      Warnings:\n        type: \"array\"\n        description: |\n          Warnings that occurred when fetching the list of volumes.\n        items:\n          type: \"string\"\n        example: []\n\n  Network:\n    type: \"object\"\n    properties:\n      Name:\n        type: \"string\"\n      Id:\n        type: \"string\"\n      Created:\n        type: \"string\"\n        format: \"dateTime\"\n      Scope:\n        type: \"string\"\n      Driver:\n        type: \"string\"\n      EnableIPv6:\n        type: \"boolean\"\n      IPAM:\n        $ref: \"#/definitions/IPAM\"\n      Internal:\n        type: \"boolean\"\n      Attachable:\n        type: \"boolean\"\n      Ingress:\n        type: \"boolean\"\n      Containers:\n        type: \"object\"\n        additionalProperties:\n          $ref: \"#/definitions/NetworkContainer\"\n      Options:\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n      Labels:\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n    example:\n      Name: \"net01\"\n      Id: \"7d86d31b1478e7cca9ebed7e73aa0fdeec46c5ca29497431d3007d2d9e15ed99\"\n      Created: \"2016-10-19T04:33:30.360899459Z\"\n      Scope: \"local\"\n      Driver: \"bridge\"\n      EnableIPv6: false\n      IPAM:\n        Driver: \"default\"\n        Config:\n          - Subnet: \"172.19.0.0/16\"\n            Gateway: \"172.19.0.1\"\n        Options:\n          foo: \"bar\"\n      Internal: false\n      Attachable: false\n      Ingress: false\n      Containers:\n        19a4d5d687db25203351ed79d478946f861258f018fe384f229f2efa4b23513c:\n          Name: \"test\"\n          EndpointID: \"628cadb8bcb92de107b2a1e516cbffe463e321f548feb37697cce00ad694f21a\"\n          MacAddress: \"02:42:ac:13:00:02\"\n          IPv4Address: \"172.19.0.2/16\"\n          IPv6Address: \"\"\n      Options:\n        com.docker.network.bridge.default_bridge: \"true\"\n        com.docker.network.bridge.enable_icc: \"true\"\n        com.docker.network.bridge.enable_ip_masquerade: \"true\"\n        com.docker.network.bridge.host_binding_ipv4: \"0.0.0.0\"\n        com.docker.network.bridge.name: \"docker0\"\n        com.docker.network.driver.mtu: \"1500\"\n      Labels:\n        com.example.some-label: \"some-value\"\n        com.example.some-other-label: \"some-other-value\"\n  IPAM:\n    type: \"object\"\n    properties:\n      Driver:\n        description: \"Name of the IPAM driver to use.\"\n        type: \"string\"\n        default: \"default\"\n      Config:\n        description: |\n          List of IPAM configuration options, specified as a map:\n\n          ```\n          {\"Subnet\": <CIDR>, \"IPRange\": <CIDR>, \"Gateway\": <IP address>, \"AuxAddress\": <device_name:IP address>}\n          ```\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/IPAMConfig\"\n      Options:\n        description: \"Driver-specific options, specified as a map.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n\n  IPAMConfig:\n    type: \"object\"\n    properties:\n      Subnet:\n        type: \"string\"\n      IPRange:\n        type: \"string\"\n      Gateway:\n        type: \"string\"\n      AuxiliaryAddresses:\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n\n  NetworkContainer:\n    type: \"object\"\n    properties:\n      Name:\n        type: \"string\"\n      EndpointID:\n        type: \"string\"\n      MacAddress:\n        type: \"string\"\n      IPv4Address:\n        type: \"string\"\n      IPv6Address:\n        type: \"string\"\n\n  BuildInfo:\n    type: \"object\"\n    properties:\n      id:\n        type: \"string\"\n      stream:\n        type: \"string\"\n      error:\n        type: \"string\"\n      errorDetail:\n        $ref: \"#/definitions/ErrorDetail\"\n      status:\n        type: \"string\"\n      progress:\n        type: \"string\"\n      progressDetail:\n        $ref: \"#/definitions/ProgressDetail\"\n      aux:\n        $ref: \"#/definitions/ImageID\"\n\n  BuildCache:\n    type: \"object\"\n    description: |\n      BuildCache contains information about a build cache record.\n    properties:\n      ID:\n        type: \"string\"\n        description: |\n          Unique ID of the build cache record.\n        example: \"ndlpt0hhvkqcdfkputsk4cq9c\"\n      Parent:\n        description: |\n          ID of the parent build cache record.\n\n          > **Deprecated**: This field is deprecated, and omitted if empty.\n        type: \"string\"\n        x-nullable: true\n        example: \"\"\n      Parents:\n        description: |\n          List of parent build cache record IDs.\n        type: \"array\"\n        items:\n          type: \"string\"\n        x-nullable: true\n        example: [\"hw53o5aio51xtltp5xjp8v7fx\"]\n      Type:\n        type: \"string\"\n        description: |\n          Cache record type.\n        example: \"regular\"\n        # see https://github.com/moby/buildkit/blob/fce4a32258dc9d9664f71a4831d5de10f0670677/client/diskusage.go#L75-L84\n        enum:\n          - \"internal\"\n          - \"frontend\"\n          - \"source.local\"\n          - \"source.git.checkout\"\n          - \"exec.cachemount\"\n          - \"regular\"\n      Description:\n        type: \"string\"\n        description: |\n          Description of the build-step that produced the build cache.\n        example: \"mount / from exec /bin/sh -c echo 'Binary::apt::APT::Keep-Downloaded-Packages \\\"true\\\";' > /etc/apt/apt.conf.d/keep-cache\"\n      InUse:\n        type: \"boolean\"\n        description: |\n          Indicates if the build cache is in use.\n        example: false\n      Shared:\n        type: \"boolean\"\n        description: |\n          Indicates if the build cache is shared.\n        example: true\n      Size:\n        description: |\n          Amount of disk space used by the build cache (in bytes).\n        type: \"integer\"\n        example: 51\n      CreatedAt:\n        description: |\n          Date and time at which the build cache was created in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2016-08-18T10:44:24.496525531Z\"\n      LastUsedAt:\n        description: |\n          Date and time at which the build cache was last used in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"dateTime\"\n        x-nullable: true\n        example: \"2017-08-09T07:09:37.632105588Z\"\n      UsageCount:\n        type: \"integer\"\n        example: 26\n\n  ImageID:\n    type: \"object\"\n    description: \"Image ID or Digest\"\n    properties:\n      ID:\n        type: \"string\"\n    example:\n      ID: \"sha256:85f05633ddc1c50679be2b16a0479ab6f7637f8884e0cfe0f4d20e1ebb3d6e7c\"\n\n  CreateImageInfo:\n    type: \"object\"\n    properties:\n      id:\n        type: \"string\"\n      error:\n        type: \"string\"\n      errorDetail:\n        $ref: \"#/definitions/ErrorDetail\"\n      status:\n        type: \"string\"\n      progress:\n        type: \"string\"\n      progressDetail:\n        $ref: \"#/definitions/ProgressDetail\"\n\n  PushImageInfo:\n    type: \"object\"\n    properties:\n      error:\n        type: \"string\"\n      status:\n        type: \"string\"\n      progress:\n        type: \"string\"\n      progressDetail:\n        $ref: \"#/definitions/ProgressDetail\"\n\n  ErrorDetail:\n    type: \"object\"\n    properties:\n      code:\n        type: \"integer\"\n      message:\n        type: \"string\"\n\n  ProgressDetail:\n    type: \"object\"\n    properties:\n      current:\n        type: \"integer\"\n      total:\n        type: \"integer\"\n\n  ErrorResponse:\n    description: \"Represents an error.\"\n    type: \"object\"\n    required: [\"message\"]\n    properties:\n      message:\n        description: \"The error message.\"\n        type: \"string\"\n        x-nullable: false\n    example:\n      message: \"Something went wrong.\"\n\n  IdResponse:\n    description: \"Response to an API call that returns just an Id\"\n    type: \"object\"\n    required: [\"Id\"]\n    properties:\n      Id:\n        description: \"The id of the newly created object.\"\n        type: \"string\"\n        x-nullable: false\n\n  EndpointSettings:\n    description: \"Configuration for a network endpoint.\"\n    type: \"object\"\n    properties:\n      # Configurations\n      IPAMConfig:\n        $ref: \"#/definitions/EndpointIPAMConfig\"\n      Links:\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"container_1\"\n          - \"container_2\"\n      MacAddress:\n        description: |\n          MAC address for the endpoint on this network. The network driver might ignore this parameter.\n        type: \"string\"\n        example: \"02:42:ac:11:00:04\"\n      Aliases:\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"server_x\"\n          - \"server_y\"\n\n      # Operational data\n      NetworkID:\n        description: |\n          Unique ID of the network.\n        type: \"string\"\n        example: \"08754567f1f40222263eab4102e1c733ae697e8e354aa9cd6e18d7402835292a\"\n      EndpointID:\n        description: |\n          Unique ID for the service endpoint in a Sandbox.\n        type: \"string\"\n        example: \"b88f5b905aabf2893f3cbc4ee42d1ea7980bbc0a92e2c8922b1e1795298afb0b\"\n      Gateway:\n        description: |\n          Gateway address for this network.\n        type: \"string\"\n        example: \"172.17.0.1\"\n      IPAddress:\n        description: |\n          IPv4 address.\n        type: \"string\"\n        example: \"172.17.0.4\"\n      IPPrefixLen:\n        description: |\n          Mask length of the IPv4 address.\n        type: \"integer\"\n        example: 16\n      IPv6Gateway:\n        description: |\n          IPv6 gateway address.\n        type: \"string\"\n        example: \"2001:db8:2::100\"\n      GlobalIPv6Address:\n        description: |\n          Global IPv6 address.\n        type: \"string\"\n        example: \"2001:db8::5689\"\n      GlobalIPv6PrefixLen:\n        description: |\n          Mask length of the global IPv6 address.\n        type: \"integer\"\n        format: \"int64\"\n        example: 64\n      DriverOpts:\n        description: |\n          DriverOpts is a mapping of driver options and values. These options\n          are passed directly to the driver and are driver specific.\n        type: \"object\"\n        x-nullable: true\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.some-label: \"some-value\"\n          com.example.some-other-label: \"some-other-value\"\n      DNSNames:\n        description: |\n          List of all DNS names an endpoint has on a specific network. This\n          list is based on the container name, network aliases, container short\n          ID, and hostname.\n\n          These DNS names are non-fully qualified but can contain several dots.\n          You can get fully qualified DNS names by appending `.<network-name>`.\n          For instance, if container name is `my.ctr` and the network is named\n          `testnet`, `DNSNames` will contain `my.ctr` and the FQDN will be\n          `my.ctr.testnet`.\n        type: array\n        items:\n          type: string\n        example: [\"foobar\", \"server_x\", \"server_y\", \"my.ctr\"]\n\n  EndpointIPAMConfig:\n    description: |\n      EndpointIPAMConfig represents an endpoint's IPAM configuration.\n    type: \"object\"\n    x-nullable: true\n    properties:\n      IPv4Address:\n        type: \"string\"\n        example: \"172.20.30.33\"\n      IPv6Address:\n        type: \"string\"\n        example: \"2001:db8:abcd::3033\"\n      LinkLocalIPs:\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"169.254.34.68\"\n          - \"fe80::3468\"\n\n  PluginMount:\n    type: \"object\"\n    x-nullable: false\n    required: [Name, Description, Settable, Source, Destination, Type, Options]\n    properties:\n      Name:\n        type: \"string\"\n        x-nullable: false\n        example: \"some-mount\"\n      Description:\n        type: \"string\"\n        x-nullable: false\n        example: \"This is a mount that's used by the plugin.\"\n      Settable:\n        type: \"array\"\n        items:\n          type: \"string\"\n      Source:\n        type: \"string\"\n        example: \"/var/lib/docker/plugins/\"\n      Destination:\n        type: \"string\"\n        x-nullable: false\n        example: \"/mnt/state\"\n      Type:\n        type: \"string\"\n        x-nullable: false\n        example: \"bind\"\n      Options:\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"rbind\"\n          - \"rw\"\n\n  PluginDevice:\n    type: \"object\"\n    required: [Name, Description, Settable, Path]\n    x-nullable: false\n    properties:\n      Name:\n        type: \"string\"\n        x-nullable: false\n      Description:\n        type: \"string\"\n        x-nullable: false\n      Settable:\n        type: \"array\"\n        items:\n          type: \"string\"\n      Path:\n        type: \"string\"\n        example: \"/dev/fuse\"\n\n  PluginEnv:\n    type: \"object\"\n    x-nullable: false\n    required: [Name, Description, Settable, Value]\n    properties:\n      Name:\n        x-nullable: false\n        type: \"string\"\n      Description:\n        x-nullable: false\n        type: \"string\"\n      Settable:\n        type: \"array\"\n        items:\n          type: \"string\"\n      Value:\n        type: \"string\"\n\n  PluginInterfaceType:\n    type: \"object\"\n    x-nullable: false\n    required: [Prefix, Capability, Version]\n    properties:\n      Prefix:\n        type: \"string\"\n        x-nullable: false\n      Capability:\n        type: \"string\"\n        x-nullable: false\n      Version:\n        type: \"string\"\n        x-nullable: false\n\n  PluginPrivilege:\n    description: |\n      Describes a permission the user has to accept upon installing\n      the plugin.\n    type: \"object\"\n    x-go-name: \"PluginPrivilege\"\n    properties:\n      Name:\n        type: \"string\"\n        example: \"network\"\n      Description:\n        type: \"string\"\n      Value:\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"host\"\n\n  Plugin:\n    description: \"A plugin for the Engine API\"\n    type: \"object\"\n    required: [Settings, Enabled, Config, Name]\n    properties:\n      Id:\n        type: \"string\"\n        example: \"5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078\"\n      Name:\n        type: \"string\"\n        x-nullable: false\n        example: \"tiborvass/sample-volume-plugin\"\n      Enabled:\n        description:\n          True if the plugin is running. False if the plugin is not running,\n          only installed.\n        type: \"boolean\"\n        x-nullable: false\n        example: true\n      Settings:\n        description: \"Settings that can be modified by users.\"\n        type: \"object\"\n        x-nullable: false\n        required: [Args, Devices, Env, Mounts]\n        properties:\n          Mounts:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginMount\"\n          Env:\n            type: \"array\"\n            items:\n              type: \"string\"\n            example:\n              - \"DEBUG=0\"\n          Args:\n            type: \"array\"\n            items:\n              type: \"string\"\n          Devices:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginDevice\"\n      PluginReference:\n        description: \"plugin remote reference used to push/pull the plugin\"\n        type: \"string\"\n        x-nullable: false\n        example: \"localhost:5000/tiborvass/sample-volume-plugin:latest\"\n      Config:\n        description: \"The config of a plugin.\"\n        type: \"object\"\n        x-nullable: false\n        required:\n          - Description\n          - Documentation\n          - Interface\n          - Entrypoint\n          - WorkDir\n          - Network\n          - Linux\n          - PidHost\n          - PropagatedMount\n          - IpcHost\n          - Mounts\n          - Env\n          - Args\n        properties:\n          DockerVersion:\n            description: \"Docker Version used to create the plugin\"\n            type: \"string\"\n            x-nullable: false\n            example: \"17.06.0-ce\"\n          Description:\n            type: \"string\"\n            x-nullable: false\n            example: \"A sample volume plugin for Docker\"\n          Documentation:\n            type: \"string\"\n            x-nullable: false\n            example: \"https://docs.docker.com/engine/extend/plugins/\"\n          Interface:\n            description: \"The interface between Docker and the plugin\"\n            x-nullable: false\n            type: \"object\"\n            required: [Types, Socket]\n            properties:\n              Types:\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/PluginInterfaceType\"\n                example:\n                  - \"docker.volumedriver/1.0\"\n              Socket:\n                type: \"string\"\n                x-nullable: false\n                example: \"plugins.sock\"\n              ProtocolScheme:\n                type: \"string\"\n                example: \"some.protocol/v1.0\"\n                description: \"Protocol to use for clients connecting to the plugin.\"\n                enum:\n                  - \"\"\n                  - \"moby.plugins.http/v1\"\n          Entrypoint:\n            type: \"array\"\n            items:\n              type: \"string\"\n            example:\n              - \"/usr/bin/sample-volume-plugin\"\n              - \"/data\"\n          WorkDir:\n            type: \"string\"\n            x-nullable: false\n            example: \"/bin/\"\n          User:\n            type: \"object\"\n            x-nullable: false\n            properties:\n              UID:\n                type: \"integer\"\n                format: \"uint32\"\n                example: 1000\n              GID:\n                type: \"integer\"\n                format: \"uint32\"\n                example: 1000\n          Network:\n            type: \"object\"\n            x-nullable: false\n            required: [Type]\n            properties:\n              Type:\n                x-nullable: false\n                type: \"string\"\n                example: \"host\"\n          Linux:\n            type: \"object\"\n            x-nullable: false\n            required: [Capabilities, AllowAllDevices, Devices]\n            properties:\n              Capabilities:\n                type: \"array\"\n                items:\n                  type: \"string\"\n                example:\n                  - \"CAP_SYS_ADMIN\"\n                  - \"CAP_SYSLOG\"\n              AllowAllDevices:\n                type: \"boolean\"\n                x-nullable: false\n                example: false\n              Devices:\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/PluginDevice\"\n          PropagatedMount:\n            type: \"string\"\n            x-nullable: false\n            example: \"/mnt/volumes\"\n          IpcHost:\n            type: \"boolean\"\n            x-nullable: false\n            example: false\n          PidHost:\n            type: \"boolean\"\n            x-nullable: false\n            example: false\n          Mounts:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginMount\"\n          Env:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginEnv\"\n            example:\n              - Name: \"DEBUG\"\n                Description: \"If set, prints debug messages\"\n                Settable: null\n                Value: \"0\"\n          Args:\n            type: \"object\"\n            x-nullable: false\n            required: [Name, Description, Settable, Value]\n            properties:\n              Name:\n                x-nullable: false\n                type: \"string\"\n                example: \"args\"\n              Description:\n                x-nullable: false\n                type: \"string\"\n                example: \"command line arguments\"\n              Settable:\n                type: \"array\"\n                items:\n                  type: \"string\"\n              Value:\n                type: \"array\"\n                items:\n                  type: \"string\"\n          rootfs:\n            type: \"object\"\n            properties:\n              type:\n                type: \"string\"\n                example: \"layers\"\n              diff_ids:\n                type: \"array\"\n                items:\n                  type: \"string\"\n                example:\n                  - \"sha256:675532206fbf3030b8458f88d6e26d4eb1577688a25efec97154c94e8b6b4887\"\n                  - \"sha256:e216a057b1cb1efc11f8a268f37ef62083e70b1b38323ba252e25ac88904a7e8\"\n\n  ObjectVersion:\n    description: |\n      The version number of the object such as node, service, etc. This is needed\n      to avoid conflicting writes. The client must send the version number along\n      with the modified specification when updating these objects.\n\n      This approach ensures safe concurrency and determinism in that the change\n      on the object may not be applied if the version number has changed from the\n      last read. In other words, if two update requests specify the same base\n      version, only one of the requests can succeed. As a result, two separate\n      update requests that happen at the same time will not unintentionally\n      overwrite each other.\n    type: \"object\"\n    properties:\n      Index:\n        type: \"integer\"\n        format: \"uint64\"\n        example: 373531\n\n  NodeSpec:\n    type: \"object\"\n    properties:\n      Name:\n        description: \"Name for the node.\"\n        type: \"string\"\n        example: \"my-node\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n      Role:\n        description: \"Role of the node.\"\n        type: \"string\"\n        enum:\n          - \"worker\"\n          - \"manager\"\n        example: \"manager\"\n      Availability:\n        description: \"Availability of the node.\"\n        type: \"string\"\n        enum:\n          - \"active\"\n          - \"pause\"\n          - \"drain\"\n        example: \"active\"\n    example:\n      Availability: \"active\"\n      Name: \"node-name\"\n      Role: \"manager\"\n      Labels:\n        foo: \"bar\"\n\n  Node:\n    type: \"object\"\n    properties:\n      ID:\n        type: \"string\"\n        example: \"24ifsmvkjbyhk\"\n      Version:\n        $ref: \"#/definitions/ObjectVersion\"\n      CreatedAt:\n        description: |\n          Date and time at which the node was added to the swarm in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2016-08-18T10:44:24.496525531Z\"\n      UpdatedAt:\n        description: |\n          Date and time at which the node was last updated in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2017-08-09T07:09:37.632105588Z\"\n      Spec:\n        $ref: \"#/definitions/NodeSpec\"\n      Description:\n        $ref: \"#/definitions/NodeDescription\"\n      Status:\n        $ref: \"#/definitions/NodeStatus\"\n      ManagerStatus:\n        $ref: \"#/definitions/ManagerStatus\"\n\n  NodeDescription:\n    description: |\n      NodeDescription encapsulates the properties of the Node as reported by the\n      agent.\n    type: \"object\"\n    properties:\n      Hostname:\n        type: \"string\"\n        example: \"bf3067039e47\"\n      Platform:\n        $ref: \"#/definitions/Platform\"\n      Resources:\n        $ref: \"#/definitions/ResourceObject\"\n      Engine:\n        $ref: \"#/definitions/EngineDescription\"\n      TLSInfo:\n        $ref: \"#/definitions/TLSInfo\"\n\n  Platform:\n    description: |\n      Platform represents the platform (Arch/OS).\n    type: \"object\"\n    properties:\n      Architecture:\n        description: |\n          Architecture represents the hardware architecture (for example,\n          `x86_64`).\n        type: \"string\"\n        example: \"x86_64\"\n      OS:\n        description: |\n          OS represents the Operating System (for example, `linux` or `windows`).\n        type: \"string\"\n        example: \"linux\"\n\n  EngineDescription:\n    description: \"EngineDescription provides information about an engine.\"\n    type: \"object\"\n    properties:\n      EngineVersion:\n        type: \"string\"\n        example: \"17.06.0\"\n      Labels:\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n        example:\n          foo: \"bar\"\n      Plugins:\n        type: \"array\"\n        items:\n          type: \"object\"\n          properties:\n            Type:\n              type: \"string\"\n            Name:\n              type: \"string\"\n        example:\n          - Type: \"Log\"\n            Name: \"awslogs\"\n          - Type: \"Log\"\n            Name: \"fluentd\"\n          - Type: \"Log\"\n            Name: \"gcplogs\"\n          - Type: \"Log\"\n            Name: \"gelf\"\n          - Type: \"Log\"\n            Name: \"journald\"\n          - Type: \"Log\"\n            Name: \"json-file\"\n          - Type: \"Log\"\n            Name: \"splunk\"\n          - Type: \"Log\"\n            Name: \"syslog\"\n          - Type: \"Network\"\n            Name: \"bridge\"\n          - Type: \"Network\"\n            Name: \"host\"\n          - Type: \"Network\"\n            Name: \"ipvlan\"\n          - Type: \"Network\"\n            Name: \"macvlan\"\n          - Type: \"Network\"\n            Name: \"null\"\n          - Type: \"Network\"\n            Name: \"overlay\"\n          - Type: \"Volume\"\n            Name: \"local\"\n          - Type: \"Volume\"\n            Name: \"localhost:5000/vieux/sshfs:latest\"\n          - Type: \"Volume\"\n            Name: \"vieux/sshfs:latest\"\n\n  TLSInfo:\n    description: |\n      Information about the issuer of leaf TLS certificates and the trusted root\n      CA certificate.\n    type: \"object\"\n    properties:\n      TrustRoot:\n        description: |\n          The root CA certificate(s) that are used to validate leaf TLS\n          certificates.\n        type: \"string\"\n      CertIssuerSubject:\n        description:\n          The base64-url-safe-encoded raw subject bytes of the issuer.\n        type: \"string\"\n      CertIssuerPublicKey:\n        description: |\n          The base64-url-safe-encoded raw public key bytes of the issuer.\n        type: \"string\"\n    example:\n      TrustRoot: |\n        -----BEGIN CERTIFICATE-----\n        MIIBajCCARCgAwIBAgIUbYqrLSOSQHoxD8CwG6Bi2PJi9c8wCgYIKoZIzj0EAwIw\n        EzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMTcwNDI0MjE0MzAwWhcNMzcwNDE5MjE0\n        MzAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\n        A0IABJk/VyMPYdaqDXJb/VXh5n/1Yuv7iNrxV3Qb3l06XD46seovcDWs3IZNV1lf\n        3Skyr0ofcchipoiHkXBODojJydSjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\n        Af8EBTADAQH/MB0GA1UdDgQWBBRUXxuRcnFjDfR/RIAUQab8ZV/n4jAKBggqhkjO\n        PQQDAgNIADBFAiAy+JTe6Uc3KyLCMiqGl2GyWGQqQDEcO3/YG36x7om65AIhAJvz\n        pxv6zFeVEkAEEkqIYi0omA9+CjanB/6Bz4n1uw8H\n        -----END CERTIFICATE-----\n      CertIssuerSubject: \"MBMxETAPBgNVBAMTCHN3YXJtLWNh\"\n      CertIssuerPublicKey: \"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmT9XIw9h1qoNclv9VeHmf/Vi6/uI2vFXdBveXTpcPjqx6i9wNazchk1XWV/dKTKvSh9xyGKmiIeRcE4OiMnJ1A==\"\n\n  NodeStatus:\n    description: |\n      NodeStatus represents the status of a node.\n\n      It provides the current status of the node, as seen by the manager.\n    type: \"object\"\n    properties:\n      State:\n        $ref: \"#/definitions/NodeState\"\n      Message:\n        type: \"string\"\n        example: \"\"\n      Addr:\n        description: \"IP address of the node.\"\n        type: \"string\"\n        example: \"172.17.0.2\"\n\n  NodeState:\n    description: \"NodeState represents the state of a node.\"\n    type: \"string\"\n    enum:\n      - \"unknown\"\n      - \"down\"\n      - \"ready\"\n      - \"disconnected\"\n    example: \"ready\"\n\n  ManagerStatus:\n    description: |\n      ManagerStatus represents the status of a manager.\n\n      It provides the current status of a node's manager component, if the node\n      is a manager.\n    x-nullable: true\n    type: \"object\"\n    properties:\n      Leader:\n        type: \"boolean\"\n        default: false\n        example: true\n      Reachability:\n        $ref: \"#/definitions/Reachability\"\n      Addr:\n        description: |\n          The IP address and port at which the manager is reachable.\n        type: \"string\"\n        example: \"10.0.0.46:2377\"\n\n  Reachability:\n    description: \"Reachability represents the reachability of a node.\"\n    type: \"string\"\n    enum:\n      - \"unknown\"\n      - \"unreachable\"\n      - \"reachable\"\n    example: \"reachable\"\n\n  SwarmSpec:\n    description: \"User modifiable swarm configuration.\"\n    type: \"object\"\n    properties:\n      Name:\n        description: \"Name of the swarm.\"\n        type: \"string\"\n        example: \"default\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.corp.type: \"production\"\n          com.example.corp.department: \"engineering\"\n      Orchestration:\n        description: \"Orchestration configuration.\"\n        type: \"object\"\n        x-nullable: true\n        properties:\n          TaskHistoryRetentionLimit:\n            description: |\n              The number of historic tasks to keep per instance or node. If\n              negative, never remove completed or failed tasks.\n            type: \"integer\"\n            format: \"int64\"\n            example: 10\n      Raft:\n        description: \"Raft configuration.\"\n        type: \"object\"\n        properties:\n          SnapshotInterval:\n            description: \"The number of log entries between snapshots.\"\n            type: \"integer\"\n            format: \"uint64\"\n            example: 10000\n          KeepOldSnapshots:\n            description: |\n              The number of snapshots to keep beyond the current snapshot.\n            type: \"integer\"\n            format: \"uint64\"\n          LogEntriesForSlowFollowers:\n            description: |\n              The number of log entries to keep around to sync up slow followers\n              after a snapshot is created.\n            type: \"integer\"\n            format: \"uint64\"\n            example: 500\n          ElectionTick:\n            description: |\n              The number of ticks that a follower will wait for a message from\n              the leader before becoming a candidate and starting an election.\n              `ElectionTick` must be greater than `HeartbeatTick`.\n\n              A tick currently defaults to one second, so these translate\n              directly to seconds currently, but this is NOT guaranteed.\n            type: \"integer\"\n            example: 3\n          HeartbeatTick:\n            description: |\n              The number of ticks between heartbeats. Every HeartbeatTick ticks,\n              the leader will send a heartbeat to the followers.\n\n              A tick currently defaults to one second, so these translate\n              directly to seconds currently, but this is NOT guaranteed.\n            type: \"integer\"\n            example: 1\n      Dispatcher:\n        description: \"Dispatcher configuration.\"\n        type: \"object\"\n        x-nullable: true\n        properties:\n          HeartbeatPeriod:\n            description: |\n              The delay for an agent to send a heartbeat to the dispatcher.\n            type: \"integer\"\n            format: \"int64\"\n            example: 5000000000\n      CAConfig:\n        description: \"CA configuration.\"\n        type: \"object\"\n        x-nullable: true\n        properties:\n          NodeCertExpiry:\n            description: \"The duration node certificates are issued for.\"\n            type: \"integer\"\n            format: \"int64\"\n            example: 7776000000000000\n          ExternalCAs:\n            description: |\n              Configuration for forwarding signing requests to an external\n              certificate authority.\n            type: \"array\"\n            items:\n              type: \"object\"\n              properties:\n                Protocol:\n                  description: |\n                    Protocol for communication with the external CA (currently\n                    only `cfssl` is supported).\n                  type: \"string\"\n                  enum:\n                    - \"cfssl\"\n                  default: \"cfssl\"\n                URL:\n                  description: |\n                    URL where certificate signing requests should be sent.\n                  type: \"string\"\n                Options:\n                  description: |\n                    An object with key/value pairs that are interpreted as\n                    protocol-specific options for the external CA driver.\n                  type: \"object\"\n                  additionalProperties:\n                    type: \"string\"\n                CACert:\n                  description: |\n                    The root CA certificate (in PEM format) this external CA uses\n                    to issue TLS certificates (assumed to be to the current swarm\n                    root CA certificate if not provided).\n                  type: \"string\"\n          SigningCACert:\n            description: |\n              The desired signing CA certificate for all swarm node TLS leaf\n              certificates, in PEM format.\n            type: \"string\"\n          SigningCAKey:\n            description: |\n              The desired signing CA key for all swarm node TLS leaf certificates,\n              in PEM format.\n            type: \"string\"\n          ForceRotate:\n            description: |\n              An integer whose purpose is to force swarm to generate a new\n              signing CA certificate and key, if none have been specified in\n              `SigningCACert` and `SigningCAKey`\n            format: \"uint64\"\n            type: \"integer\"\n      EncryptionConfig:\n        description: \"Parameters related to encryption-at-rest.\"\n        type: \"object\"\n        properties:\n          AutoLockManagers:\n            description: |\n              If set, generate a key and use it to lock data stored on the\n              managers.\n            type: \"boolean\"\n            example: false\n      TaskDefaults:\n        description: \"Defaults for creating tasks in this cluster.\"\n        type: \"object\"\n        properties:\n          LogDriver:\n            description: |\n              The log driver to use for tasks created in the orchestrator if\n              unspecified by a service.\n\n              Updating this value only affects new tasks. Existing tasks continue\n              to use their previously configured log driver until recreated.\n            type: \"object\"\n            properties:\n              Name:\n                description: |\n                  The log driver to use as a default for new tasks.\n                type: \"string\"\n                example: \"json-file\"\n              Options:\n                description: |\n                  Driver-specific options for the selectd log driver, specified\n                  as key/value pairs.\n                type: \"object\"\n                additionalProperties:\n                  type: \"string\"\n                example:\n                  \"max-file\": \"10\"\n                  \"max-size\": \"100m\"\n\n  # The Swarm information for `GET /info`. It is the same as `GET /swarm`, but\n  # without `JoinTokens`.\n  ClusterInfo:\n    description: |\n      ClusterInfo represents information about the swarm as is returned by the\n      \"/info\" endpoint. Join-tokens are not included.\n    x-nullable: true\n    type: \"object\"\n    properties:\n      ID:\n        description: \"The ID of the swarm.\"\n        type: \"string\"\n        example: \"abajmipo7b4xz5ip2nrla6b11\"\n      Version:\n        $ref: \"#/definitions/ObjectVersion\"\n      CreatedAt:\n        description: |\n          Date and time at which the swarm was initialised in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2016-08-18T10:44:24.496525531Z\"\n      UpdatedAt:\n        description: |\n          Date and time at which the swarm was last updated in\n          [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format with nano-seconds.\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2017-08-09T07:09:37.632105588Z\"\n      Spec:\n        $ref: \"#/definitions/SwarmSpec\"\n      TLSInfo:\n        $ref: \"#/definitions/TLSInfo\"\n      RootRotationInProgress:\n        description: |\n          Whether there is currently a root CA rotation in progress for the swarm\n        type: \"boolean\"\n        example: false\n      DataPathPort:\n        description: |\n          DataPathPort specifies the data path port number for data traffic.\n          Acceptable port range is 1024 to 49151.\n          If no port is set or is set to 0, the default port (4789) is used.\n        type: \"integer\"\n        format: \"uint32\"\n        default: 4789\n        example: 4789\n      DefaultAddrPool:\n        description: |\n          Default Address Pool specifies default subnet pools for global scope\n          networks.\n        type: \"array\"\n        items:\n          type: \"string\"\n          format: \"CIDR\"\n          example: [\"10.10.0.0/16\", \"20.20.0.0/16\"]\n      SubnetSize:\n        description: |\n          SubnetSize specifies the subnet size of the networks created from the\n          default subnet pool.\n        type: \"integer\"\n        format: \"uint32\"\n        maximum: 29\n        default: 24\n        example: 24\n\n  JoinTokens:\n    description: |\n      JoinTokens contains the tokens workers and managers need to join the swarm.\n    type: \"object\"\n    properties:\n      Worker:\n        description: |\n          The token workers can use to join the swarm.\n        type: \"string\"\n        example: \"SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-1awxwuwd3z9j1z3puu7rcgdbx\"\n      Manager:\n        description: |\n          The token managers can use to join the swarm.\n        type: \"string\"\n        example: \"SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2\"\n\n  Swarm:\n    type: \"object\"\n    allOf:\n      - $ref: \"#/definitions/ClusterInfo\"\n      - type: \"object\"\n        properties:\n          JoinTokens:\n            $ref: \"#/definitions/JoinTokens\"\n\n  TaskSpec:\n    description: \"User modifiable task configuration.\"\n    type: \"object\"\n    properties:\n      PluginSpec:\n        type: \"object\"\n        description: |\n          Plugin spec for the service.  *(Experimental release only.)*\n\n          <p><br /></p>\n\n          > **Note**: ContainerSpec, NetworkAttachmentSpec, and PluginSpec are\n          > mutually exclusive. PluginSpec is only used when the Runtime field\n          > is set to `plugin`. NetworkAttachmentSpec is used when the Runtime\n          > field is set to `attachment`.\n        properties:\n          Name:\n            description: \"The name or 'alias' to use for the plugin.\"\n            type: \"string\"\n          Remote:\n            description: \"The plugin image reference to use.\"\n            type: \"string\"\n          Disabled:\n            description: \"Disable the plugin once scheduled.\"\n            type: \"boolean\"\n          PluginPrivilege:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginPrivilege\"\n      ContainerSpec:\n        type: \"object\"\n        description: |\n          Container spec for the service.\n\n          <p><br /></p>\n\n          > **Note**: ContainerSpec, NetworkAttachmentSpec, and PluginSpec are\n          > mutually exclusive. PluginSpec is only used when the Runtime field\n          > is set to `plugin`. NetworkAttachmentSpec is used when the Runtime\n          > field is set to `attachment`.\n        properties:\n          Image:\n            description: \"The image name to use for the container\"\n            type: \"string\"\n          Labels:\n            description: \"User-defined key/value data.\"\n            type: \"object\"\n            additionalProperties:\n              type: \"string\"\n          Command:\n            description: \"The command to be run in the image.\"\n            type: \"array\"\n            items:\n              type: \"string\"\n          Args:\n            description: \"Arguments to the command.\"\n            type: \"array\"\n            items:\n              type: \"string\"\n          Hostname:\n            description: |\n              The hostname to use for the container, as a valid\n              [RFC 1123](https://tools.ietf.org/html/rfc1123) hostname.\n            type: \"string\"\n          Env:\n            description: |\n              A list of environment variables in the form `VAR=value`.\n            type: \"array\"\n            items:\n              type: \"string\"\n          Dir:\n            description: \"The working directory for commands to run in.\"\n            type: \"string\"\n          User:\n            description: \"The user inside the container.\"\n            type: \"string\"\n          Groups:\n            type: \"array\"\n            description: |\n              A list of additional groups that the container process will run as.\n            items:\n              type: \"string\"\n          Privileges:\n            type: \"object\"\n            description: \"Security options for the container\"\n            properties:\n              CredentialSpec:\n                type: \"object\"\n                description: \"CredentialSpec for managed service account (Windows only)\"\n                properties:\n                  Config:\n                    type: \"string\"\n                    example: \"0bt9dmxjvjiqermk6xrop3ekq\"\n                    description: |\n                      Load credential spec from a Swarm Config with the given ID.\n                      The specified config must also be present in the Configs\n                      field with the Runtime property set.\n\n                      <p><br /></p>\n\n\n                      > **Note**: `CredentialSpec.File`, `CredentialSpec.Registry`,\n                      > and `CredentialSpec.Config` are mutually exclusive.\n                  File:\n                    type: \"string\"\n                    example: \"spec.json\"\n                    description: |\n                      Load credential spec from this file. The file is read by\n                      the daemon, and must be present in the `CredentialSpecs`\n                      subdirectory in the docker data directory, which defaults\n                      to `C:\\ProgramData\\Docker\\` on Windows.\n\n                      For example, specifying `spec.json` loads\n                      `C:\\ProgramData\\Docker\\CredentialSpecs\\spec.json`.\n\n                      <p><br /></p>\n\n                      > **Note**: `CredentialSpec.File`, `CredentialSpec.Registry`,\n                      > and `CredentialSpec.Config` are mutually exclusive.\n                  Registry:\n                    type: \"string\"\n                    description: |\n                      Load credential spec from this value in the Windows\n                      registry. The specified registry value must be located in:\n\n                      `HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Virtualization\\Containers\\CredentialSpecs`\n\n                      <p><br /></p>\n\n\n                      > **Note**: `CredentialSpec.File`, `CredentialSpec.Registry`,\n                      > and `CredentialSpec.Config` are mutually exclusive.\n              SELinuxContext:\n                type: \"object\"\n                description: \"SELinux labels of the container\"\n                properties:\n                  Disable:\n                    type: \"boolean\"\n                    description: \"Disable SELinux\"\n                  User:\n                    type: \"string\"\n                    description: \"SELinux user label\"\n                  Role:\n                    type: \"string\"\n                    description: \"SELinux role label\"\n                  Type:\n                    type: \"string\"\n                    description: \"SELinux type label\"\n                  Level:\n                    type: \"string\"\n                    description: \"SELinux level label\"\n              Seccomp:\n                type: \"object\"\n                description: \"Options for configuring seccomp on the container\"\n                properties:\n                  Mode:\n                    type: \"string\"\n                    enum:\n                      - \"default\"\n                      - \"unconfined\"\n                      - \"custom\"\n                  Profile:\n                    description: \"The custom seccomp profile as a json object\"\n                    type: \"string\"\n              AppArmor:\n                type: \"object\"\n                description: \"Options for configuring AppArmor on the container\"\n                properties:\n                  Mode:\n                    type: \"string\"\n                    enum:\n                      - \"default\"\n                      - \"disabled\"\n              NoNewPrivileges:\n                type: \"boolean\"\n                description: \"Configuration of the no_new_privs bit in the container\"\n\n          TTY:\n            description: \"Whether a pseudo-TTY should be allocated.\"\n            type: \"boolean\"\n          OpenStdin:\n            description: \"Open `stdin`\"\n            type: \"boolean\"\n          ReadOnly:\n            description: \"Mount the container's root filesystem as read only.\"\n            type: \"boolean\"\n          Mounts:\n            description: |\n              Specification for mounts to be added to containers created as part\n              of the service.\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Mount\"\n          StopSignal:\n            description: \"Signal to stop the container.\"\n            type: \"string\"\n          StopGracePeriod:\n            description: |\n              Amount of time to wait for the container to terminate before\n              forcefully killing it.\n            type: \"integer\"\n            format: \"int64\"\n          HealthCheck:\n            $ref: \"#/definitions/HealthConfig\"\n          Hosts:\n            type: \"array\"\n            description: |\n              A list of hostname/IP mappings to add to the container's `hosts`\n              file. The format of extra hosts is specified in the\n              [hosts(5)](http://man7.org/linux/man-pages/man5/hosts.5.html)\n              man page:\n\n                  IP_address canonical_hostname [aliases...]\n            items:\n              type: \"string\"\n          DNSConfig:\n            description: |\n              Specification for DNS related configurations in resolver configuration\n              file (`resolv.conf`).\n            type: \"object\"\n            properties:\n              Nameservers:\n                description: \"The IP addresses of the name servers.\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n              Search:\n                description: \"A search list for host-name lookup.\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n              Options:\n                description: |\n                  A list of internal resolver variables to be modified (e.g.,\n                  `debug`, `ndots:3`, etc.).\n                type: \"array\"\n                items:\n                  type: \"string\"\n          Secrets:\n            description: |\n              Secrets contains references to zero or more secrets that will be\n              exposed to the service.\n            type: \"array\"\n            items:\n              type: \"object\"\n              properties:\n                File:\n                  description: |\n                    File represents a specific target that is backed by a file.\n                  type: \"object\"\n                  properties:\n                    Name:\n                      description: |\n                        Name represents the final filename in the filesystem.\n                      type: \"string\"\n                    UID:\n                      description: \"UID represents the file UID.\"\n                      type: \"string\"\n                    GID:\n                      description: \"GID represents the file GID.\"\n                      type: \"string\"\n                    Mode:\n                      description: \"Mode represents the FileMode of the file.\"\n                      type: \"integer\"\n                      format: \"uint32\"\n                SecretID:\n                  description: |\n                    SecretID represents the ID of the specific secret that we're\n                    referencing.\n                  type: \"string\"\n                SecretName:\n                  description: |\n                    SecretName is the name of the secret that this references,\n                    but this is just provided for lookup/display purposes. The\n                    secret in the reference will be identified by its ID.\n                  type: \"string\"\n          Configs:\n            description: |\n              Configs contains references to zero or more configs that will be\n              exposed to the service.\n            type: \"array\"\n            items:\n              type: \"object\"\n              properties:\n                File:\n                  description: |\n                    File represents a specific target that is backed by a file.\n\n                    <p><br /><p>\n\n                    > **Note**: `Configs.File` and `Configs.Runtime` are mutually exclusive\n                  type: \"object\"\n                  properties:\n                    Name:\n                      description: |\n                        Name represents the final filename in the filesystem.\n                      type: \"string\"\n                    UID:\n                      description: \"UID represents the file UID.\"\n                      type: \"string\"\n                    GID:\n                      description: \"GID represents the file GID.\"\n                      type: \"string\"\n                    Mode:\n                      description: \"Mode represents the FileMode of the file.\"\n                      type: \"integer\"\n                      format: \"uint32\"\n                Runtime:\n                  description: |\n                    Runtime represents a target that is not mounted into the\n                    container but is used by the task\n\n                    <p><br /><p>\n\n                    > **Note**: `Configs.File` and `Configs.Runtime` are mutually\n                    > exclusive\n                  type: \"object\"\n                ConfigID:\n                  description: |\n                    ConfigID represents the ID of the specific config that we're\n                    referencing.\n                  type: \"string\"\n                ConfigName:\n                  description: |\n                    ConfigName is the name of the config that this references,\n                    but this is just provided for lookup/display purposes. The\n                    config in the reference will be identified by its ID.\n                  type: \"string\"\n          Isolation:\n            type: \"string\"\n            description: |\n              Isolation technology of the containers running the service.\n              (Windows only)\n            enum:\n              - \"default\"\n              - \"process\"\n              - \"hyperv\"\n          Init:\n            description: |\n              Run an init inside the container that forwards signals and reaps\n              processes. This field is omitted if empty, and the default (as\n              configured on the daemon) is used.\n            type: \"boolean\"\n            x-nullable: true\n          Sysctls:\n            description: |\n              Set kernel namedspaced parameters (sysctls) in the container.\n              The Sysctls option on services accepts the same sysctls as the\n              are supported on containers. Note that while the same sysctls are\n              supported, no guarantees or checks are made about their\n              suitability for a clustered environment, and it's up to the user\n              to determine whether a given sysctl will work properly in a\n              Service.\n            type: \"object\"\n            additionalProperties:\n              type: \"string\"\n          # This option is not used by Windows containers\n          CapabilityAdd:\n            type: \"array\"\n            description: |\n              A list of kernel capabilities to add to the default set\n              for the container.\n            items:\n              type: \"string\"\n            example:\n              - \"CAP_NET_RAW\"\n              - \"CAP_SYS_ADMIN\"\n              - \"CAP_SYS_CHROOT\"\n              - \"CAP_SYSLOG\"\n          CapabilityDrop:\n            type: \"array\"\n            description: |\n              A list of kernel capabilities to drop from the default set\n              for the container.\n            items:\n              type: \"string\"\n            example:\n              - \"CAP_NET_RAW\"\n          Ulimits:\n            description: |\n              A list of resource limits to set in the container. For example: `{\"Name\": \"nofile\", \"Soft\": 1024, \"Hard\": 2048}`\"\n            type: \"array\"\n            items:\n              type: \"object\"\n              properties:\n                Name:\n                  description: \"Name of ulimit\"\n                  type: \"string\"\n                Soft:\n                  description: \"Soft limit\"\n                  type: \"integer\"\n                Hard:\n                  description: \"Hard limit\"\n                  type: \"integer\"\n      NetworkAttachmentSpec:\n        description: |\n          Read-only spec type for non-swarm containers attached to swarm overlay\n          networks.\n\n          <p><br /></p>\n\n          > **Note**: ContainerSpec, NetworkAttachmentSpec, and PluginSpec are\n          > mutually exclusive. PluginSpec is only used when the Runtime field\n          > is set to `plugin`. NetworkAttachmentSpec is used when the Runtime\n          > field is set to `attachment`.\n        type: \"object\"\n        properties:\n          ContainerID:\n            description: \"ID of the container represented by this task\"\n            type: \"string\"\n      Resources:\n        description: |\n          Resource requirements which apply to each individual container created\n          as part of the service.\n        type: \"object\"\n        properties:\n          Limits:\n            description: \"Define resources limits.\"\n            $ref: \"#/definitions/Limit\"\n          Reservations:\n            description: \"Define resources reservation.\"\n            $ref: \"#/definitions/ResourceObject\"\n      RestartPolicy:\n        description: |\n          Specification for the restart policy which applies to containers\n          created as part of this service.\n        type: \"object\"\n        properties:\n          Condition:\n            description: \"Condition for restart.\"\n            type: \"string\"\n            enum:\n              - \"none\"\n              - \"on-failure\"\n              - \"any\"\n          Delay:\n            description: \"Delay between restart attempts.\"\n            type: \"integer\"\n            format: \"int64\"\n          MaxAttempts:\n            description: |\n              Maximum attempts to restart a given container before giving up\n              (default value is 0, which is ignored).\n            type: \"integer\"\n            format: \"int64\"\n            default: 0\n          Window:\n            description: |\n              Windows is the time window used to evaluate the restart policy\n              (default value is 0, which is unbounded).\n            type: \"integer\"\n            format: \"int64\"\n            default: 0\n      Placement:\n        type: \"object\"\n        properties:\n          Constraints:\n            description: |\n              An array of constraint expressions to limit the set of nodes where\n              a task can be scheduled. Constraint expressions can either use a\n              _match_ (`==`) or _exclude_ (`!=`) rule. Multiple constraints find\n              nodes that satisfy every expression (AND match). Constraints can\n              match node or Docker Engine labels as follows:\n\n              node attribute       | matches                        | example\n              ---------------------|--------------------------------|-----------------------------------------------\n              `node.id`            | Node ID                        | `node.id==2ivku8v2gvtg4`\n              `node.hostname`      | Node hostname                  | `node.hostname!=node-2`\n              `node.role`          | Node role (`manager`/`worker`) | `node.role==manager`\n              `node.platform.os`   | Node operating system          | `node.platform.os==windows`\n              `node.platform.arch` | Node architecture              | `node.platform.arch==x86_64`\n              `node.labels`        | User-defined node labels       | `node.labels.security==high`\n              `engine.labels`      | Docker Engine's labels         | `engine.labels.operatingsystem==ubuntu-14.04`\n\n              `engine.labels` apply to Docker Engine labels like operating system,\n              drivers, etc. Swarm administrators add `node.labels` for operational\n              purposes by using the [`node update endpoint`](#operation/NodeUpdate).\n\n            type: \"array\"\n            items:\n              type: \"string\"\n            example:\n              - \"node.hostname!=node3.corp.example.com\"\n              - \"node.role!=manager\"\n              - \"node.labels.type==production\"\n              - \"node.platform.os==linux\"\n              - \"node.platform.arch==x86_64\"\n          Preferences:\n            description: |\n              Preferences provide a way to make the scheduler aware of factors\n              such as topology. They are provided in order from highest to\n              lowest precedence.\n            type: \"array\"\n            items:\n              type: \"object\"\n              properties:\n                Spread:\n                  type: \"object\"\n                  properties:\n                    SpreadDescriptor:\n                      description: |\n                        label descriptor, such as `engine.labels.az`.\n                      type: \"string\"\n            example:\n              - Spread:\n                  SpreadDescriptor: \"node.labels.datacenter\"\n              - Spread:\n                  SpreadDescriptor: \"node.labels.rack\"\n          MaxReplicas:\n            description: |\n              Maximum number of replicas for per node (default value is 0, which\n              is unlimited)\n            type: \"integer\"\n            format: \"int64\"\n            default: 0\n          Platforms:\n            description: |\n              Platforms stores all the platforms that the service's image can\n              run on. This field is used in the platform filter for scheduling.\n              If empty, then the platform filter is off, meaning there are no\n              scheduling restrictions.\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Platform\"\n      ForceUpdate:\n        description: |\n          A counter that triggers an update even if no relevant parameters have\n          been changed.\n        type: \"integer\"\n      Runtime:\n        description: |\n          Runtime is the type of runtime specified for the task executor.\n        type: \"string\"\n      Networks:\n        description: \"Specifies which networks the service should attach to.\"\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/NetworkAttachmentConfig\"\n      LogDriver:\n        description: |\n          Specifies the log driver to use for tasks created from this spec. If\n          not present, the default one for the swarm will be used, finally\n          falling back to the engine default if not specified.\n        type: \"object\"\n        properties:\n          Name:\n            type: \"string\"\n          Options:\n            type: \"object\"\n            additionalProperties:\n              type: \"string\"\n\n  TaskState:\n    type: \"string\"\n    enum:\n      - \"new\"\n      - \"allocated\"\n      - \"pending\"\n      - \"assigned\"\n      - \"accepted\"\n      - \"preparing\"\n      - \"ready\"\n      - \"starting\"\n      - \"running\"\n      - \"complete\"\n      - \"shutdown\"\n      - \"failed\"\n      - \"rejected\"\n      - \"remove\"\n      - \"orphaned\"\n\n  ContainerStatus:\n    type: \"object\"\n    description: \"represents the status of a container.\"\n    properties:\n      ContainerID:\n        type: \"string\"\n      PID:\n        type: \"integer\"\n      ExitCode:\n        type: \"integer\"\n\n  PortStatus:\n    type: \"object\"\n    description: \"represents the port status of a task's host ports whose service has published host ports\"\n    properties:\n      Ports:\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/EndpointPortConfig\"\n\n  TaskStatus:\n    type: \"object\"\n    description: \"represents the status of a task.\"\n    properties:\n      Timestamp:\n        type: \"string\"\n        format: \"dateTime\"\n      State:\n        $ref: \"#/definitions/TaskState\"\n      Message:\n        type: \"string\"\n      Err:\n        type: \"string\"\n      ContainerStatus:\n        $ref: \"#/definitions/ContainerStatus\"\n      PortStatus:\n        $ref: \"#/definitions/PortStatus\"\n\n  Task:\n    type: \"object\"\n    properties:\n      ID:\n        description: \"The ID of the task.\"\n        type: \"string\"\n      Version:\n        $ref: \"#/definitions/ObjectVersion\"\n      CreatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      UpdatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      Name:\n        description: \"Name of the task.\"\n        type: \"string\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n      Spec:\n        $ref: \"#/definitions/TaskSpec\"\n      ServiceID:\n        description: \"The ID of the service this task is part of.\"\n        type: \"string\"\n      Slot:\n        type: \"integer\"\n      NodeID:\n        description: \"The ID of the node that this task is on.\"\n        type: \"string\"\n      AssignedGenericResources:\n        $ref: \"#/definitions/GenericResources\"\n      Status:\n        $ref: \"#/definitions/TaskStatus\"\n      DesiredState:\n        $ref: \"#/definitions/TaskState\"\n      JobIteration:\n        description: |\n          If the Service this Task belongs to is a job-mode service, contains\n          the JobIteration of the Service this Task was created for. Absent if\n          the Task was created for a Replicated or Global Service.\n        $ref: \"#/definitions/ObjectVersion\"\n    example:\n      ID: \"0kzzo1i0y4jz6027t0k7aezc7\"\n      Version:\n        Index: 71\n      CreatedAt: \"2016-06-07T21:07:31.171892745Z\"\n      UpdatedAt: \"2016-06-07T21:07:31.376370513Z\"\n      Spec:\n        ContainerSpec:\n          Image: \"redis\"\n        Resources:\n          Limits: {}\n          Reservations: {}\n        RestartPolicy:\n          Condition: \"any\"\n          MaxAttempts: 0\n        Placement: {}\n      ServiceID: \"9mnpnzenvg8p8tdbtq4wvbkcz\"\n      Slot: 1\n      NodeID: \"60gvrl6tm78dmak4yl7srz94v\"\n      Status:\n        Timestamp: \"2016-06-07T21:07:31.290032978Z\"\n        State: \"running\"\n        Message: \"started\"\n        ContainerStatus:\n          ContainerID: \"e5d62702a1b48d01c3e02ca1e0212a250801fa8d67caca0b6f35919ebc12f035\"\n          PID: 677\n      DesiredState: \"running\"\n      NetworksAttachments:\n        - Network:\n            ID: \"4qvuz4ko70xaltuqbt8956gd1\"\n            Version:\n              Index: 18\n            CreatedAt: \"2016-06-07T20:31:11.912919752Z\"\n            UpdatedAt: \"2016-06-07T21:07:29.955277358Z\"\n            Spec:\n              Name: \"ingress\"\n              Labels:\n                com.docker.swarm.internal: \"true\"\n              DriverConfiguration: {}\n              IPAMOptions:\n                Driver: {}\n                Configs:\n                  - Subnet: \"10.255.0.0/16\"\n                    Gateway: \"10.255.0.1\"\n            DriverState:\n              Name: \"overlay\"\n              Options:\n                com.docker.network.driver.overlay.vxlanid_list: \"256\"\n            IPAMOptions:\n              Driver:\n                Name: \"default\"\n              Configs:\n                - Subnet: \"10.255.0.0/16\"\n                  Gateway: \"10.255.0.1\"\n          Addresses:\n            - \"10.255.0.10/16\"\n      AssignedGenericResources:\n        - DiscreteResourceSpec:\n            Kind: \"SSD\"\n            Value: 3\n        - NamedResourceSpec:\n            Kind: \"GPU\"\n            Value: \"UUID1\"\n        - NamedResourceSpec:\n            Kind: \"GPU\"\n            Value: \"UUID2\"\n\n  ServiceSpec:\n    description: \"User modifiable configuration for a service.\"\n    type: object\n    properties:\n      Name:\n        description: \"Name of the service.\"\n        type: \"string\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n      TaskTemplate:\n        $ref: \"#/definitions/TaskSpec\"\n      Mode:\n        description: \"Scheduling mode for the service.\"\n        type: \"object\"\n        properties:\n          Replicated:\n            type: \"object\"\n            properties:\n              Replicas:\n                type: \"integer\"\n                format: \"int64\"\n          Global:\n            type: \"object\"\n          ReplicatedJob:\n            description: |\n              The mode used for services with a finite number of tasks that run\n              to a completed state.\n            type: \"object\"\n            properties:\n              MaxConcurrent:\n                description: |\n                  The maximum number of replicas to run simultaneously.\n                type: \"integer\"\n                format: \"int64\"\n                default: 1\n              TotalCompletions:\n                description: |\n                  The total number of replicas desired to reach the Completed\n                  state. If unset, will default to the value of `MaxConcurrent`\n                type: \"integer\"\n                format: \"int64\"\n          GlobalJob:\n            description: |\n              The mode used for services which run a task to the completed state\n              on each valid node.\n            type: \"object\"\n      UpdateConfig:\n        description: \"Specification for the update strategy of the service.\"\n        type: \"object\"\n        properties:\n          Parallelism:\n            description: |\n              Maximum number of tasks to be updated in one iteration (0 means\n              unlimited parallelism).\n            type: \"integer\"\n            format: \"int64\"\n          Delay:\n            description: \"Amount of time between updates, in nanoseconds.\"\n            type: \"integer\"\n            format: \"int64\"\n          FailureAction:\n            description: |\n              Action to take if an updated task fails to run, or stops running\n              during the update.\n            type: \"string\"\n            enum:\n              - \"continue\"\n              - \"pause\"\n              - \"rollback\"\n          Monitor:\n            description: |\n              Amount of time to monitor each updated task for failures, in\n              nanoseconds.\n            type: \"integer\"\n            format: \"int64\"\n          MaxFailureRatio:\n            description: |\n              The fraction of tasks that may fail during an update before the\n              failure action is invoked, specified as a floating point number\n              between 0 and 1.\n            type: \"number\"\n            default: 0\n          Order:\n            description: |\n              The order of operations when rolling out an updated task. Either\n              the old task is shut down before the new task is started, or the\n              new task is started before the old task is shut down.\n            type: \"string\"\n            enum:\n              - \"stop-first\"\n              - \"start-first\"\n      RollbackConfig:\n        description: \"Specification for the rollback strategy of the service.\"\n        type: \"object\"\n        properties:\n          Parallelism:\n            description: |\n              Maximum number of tasks to be rolled back in one iteration (0 means\n              unlimited parallelism).\n            type: \"integer\"\n            format: \"int64\"\n          Delay:\n            description: |\n              Amount of time between rollback iterations, in nanoseconds.\n            type: \"integer\"\n            format: \"int64\"\n          FailureAction:\n            description: |\n              Action to take if an rolled back task fails to run, or stops\n              running during the rollback.\n            type: \"string\"\n            enum:\n              - \"continue\"\n              - \"pause\"\n          Monitor:\n            description: |\n              Amount of time to monitor each rolled back task for failures, in\n              nanoseconds.\n            type: \"integer\"\n            format: \"int64\"\n          MaxFailureRatio:\n            description: |\n              The fraction of tasks that may fail during a rollback before the\n              failure action is invoked, specified as a floating point number\n              between 0 and 1.\n            type: \"number\"\n            default: 0\n          Order:\n            description: |\n              The order of operations when rolling back a task. Either the old\n              task is shut down before the new task is started, or the new task\n              is started before the old task is shut down.\n            type: \"string\"\n            enum:\n              - \"stop-first\"\n              - \"start-first\"\n      Networks:\n        description: |\n          Specifies which networks the service should attach to.\n\n          Deprecated: This field is deprecated since v1.44. The Networks field in TaskSpec should be used instead.\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/NetworkAttachmentConfig\"\n\n      EndpointSpec:\n        $ref: \"#/definitions/EndpointSpec\"\n\n  EndpointPortConfig:\n    type: \"object\"\n    properties:\n      Name:\n        type: \"string\"\n      Protocol:\n        type: \"string\"\n        enum:\n          - \"tcp\"\n          - \"udp\"\n          - \"sctp\"\n      TargetPort:\n        description: \"The port inside the container.\"\n        type: \"integer\"\n      PublishedPort:\n        description: \"The port on the swarm hosts.\"\n        type: \"integer\"\n      PublishMode:\n        description: |\n          The mode in which port is published.\n\n          <p><br /></p>\n\n          - \"ingress\" makes the target port accessible on every node,\n            regardless of whether there is a task for the service running on\n            that node or not.\n          - \"host\" bypasses the routing mesh and publish the port directly on\n            the swarm node where that service is running.\n\n        type: \"string\"\n        enum:\n          - \"ingress\"\n          - \"host\"\n        default: \"ingress\"\n        example: \"ingress\"\n\n  EndpointSpec:\n    description: \"Properties that can be configured to access and load balance a service.\"\n    type: \"object\"\n    properties:\n      Mode:\n        description: |\n          The mode of resolution to use for internal load balancing between tasks.\n        type: \"string\"\n        enum:\n          - \"vip\"\n          - \"dnsrr\"\n        default: \"vip\"\n      Ports:\n        description: |\n          List of exposed ports that this service is accessible on from the\n          outside. Ports can only be provided if `vip` resolution mode is used.\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/EndpointPortConfig\"\n\n  Service:\n    type: \"object\"\n    properties:\n      ID:\n        type: \"string\"\n      Version:\n        $ref: \"#/definitions/ObjectVersion\"\n      CreatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      UpdatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      Spec:\n        $ref: \"#/definitions/ServiceSpec\"\n      Endpoint:\n        type: \"object\"\n        properties:\n          Spec:\n            $ref: \"#/definitions/EndpointSpec\"\n          Ports:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/EndpointPortConfig\"\n          VirtualIPs:\n            type: \"array\"\n            items:\n              type: \"object\"\n              properties:\n                NetworkID:\n                  type: \"string\"\n                Addr:\n                  type: \"string\"\n      UpdateStatus:\n        description: \"The status of a service update.\"\n        type: \"object\"\n        properties:\n          State:\n            type: \"string\"\n            enum:\n              - \"updating\"\n              - \"paused\"\n              - \"completed\"\n          StartedAt:\n            type: \"string\"\n            format: \"dateTime\"\n          CompletedAt:\n            type: \"string\"\n            format: \"dateTime\"\n          Message:\n            type: \"string\"\n      ServiceStatus:\n        description: |\n          The status of the service's tasks. Provided only when requested as\n          part of a ServiceList operation.\n        type: \"object\"\n        properties:\n          RunningTasks:\n            description: |\n              The number of tasks for the service currently in the Running state.\n            type: \"integer\"\n            format: \"uint64\"\n            example: 7\n          DesiredTasks:\n            description: |\n              The number of tasks for the service desired to be running.\n              For replicated services, this is the replica count from the\n              service spec. For global services, this is computed by taking\n              count of all tasks for the service with a Desired State other\n              than Shutdown.\n            type: \"integer\"\n            format: \"uint64\"\n            example: 10\n          CompletedTasks:\n            description: |\n              The number of tasks for a job that are in the Completed state.\n              This field must be cross-referenced with the service type, as the\n              value of 0 may mean the service is not in a job mode, or it may\n              mean the job-mode service has no tasks yet Completed.\n            type: \"integer\"\n            format: \"uint64\"\n      JobStatus:\n        description: |\n          The status of the service when it is in one of ReplicatedJob or\n          GlobalJob modes. Absent on Replicated and Global mode services. The\n          JobIteration is an ObjectVersion, but unlike the Service's version,\n          does not need to be sent with an update request.\n        type: \"object\"\n        properties:\n          JobIteration:\n            description: |\n              JobIteration is a value increased each time a Job is executed,\n              successfully or otherwise. \"Executed\", in this case, means the\n              job as a whole has been started, not that an individual Task has\n              been launched. A job is \"Executed\" when its ServiceSpec is\n              updated. JobIteration can be used to disambiguate Tasks belonging\n              to different executions of a job.  Though JobIteration will\n              increase with each subsequent execution, it may not necessarily\n              increase by 1, and so JobIteration should not be used to\n            $ref: \"#/definitions/ObjectVersion\"\n          LastExecution:\n            description: |\n              The last time, as observed by the server, that this job was\n              started.\n            type: \"string\"\n            format: \"dateTime\"\n    example:\n      ID: \"9mnpnzenvg8p8tdbtq4wvbkcz\"\n      Version:\n        Index: 19\n      CreatedAt: \"2016-06-07T21:05:51.880065305Z\"\n      UpdatedAt: \"2016-06-07T21:07:29.962229872Z\"\n      Spec:\n        Name: \"hopeful_cori\"\n        TaskTemplate:\n          ContainerSpec:\n            Image: \"redis\"\n          Resources:\n            Limits: {}\n            Reservations: {}\n          RestartPolicy:\n            Condition: \"any\"\n            MaxAttempts: 0\n          Placement: {}\n          ForceUpdate: 0\n        Mode:\n          Replicated:\n            Replicas: 1\n        UpdateConfig:\n          Parallelism: 1\n          Delay: 1000000000\n          FailureAction: \"pause\"\n          Monitor: 15000000000\n          MaxFailureRatio: 0.15\n        RollbackConfig:\n          Parallelism: 1\n          Delay: 1000000000\n          FailureAction: \"pause\"\n          Monitor: 15000000000\n          MaxFailureRatio: 0.15\n        EndpointSpec:\n          Mode: \"vip\"\n          Ports:\n            -\n              Protocol: \"tcp\"\n              TargetPort: 6379\n              PublishedPort: 30001\n      Endpoint:\n        Spec:\n          Mode: \"vip\"\n          Ports:\n            -\n              Protocol: \"tcp\"\n              TargetPort: 6379\n              PublishedPort: 30001\n        Ports:\n          -\n            Protocol: \"tcp\"\n            TargetPort: 6379\n            PublishedPort: 30001\n        VirtualIPs:\n          -\n            NetworkID: \"4qvuz4ko70xaltuqbt8956gd1\"\n            Addr: \"10.255.0.2/16\"\n          -\n            NetworkID: \"4qvuz4ko70xaltuqbt8956gd1\"\n            Addr: \"10.255.0.3/16\"\n\n  ImageDeleteResponseItem:\n    type: \"object\"\n    x-go-name: \"DeleteResponse\"\n    properties:\n      Untagged:\n        description: \"The image ID of an image that was untagged\"\n        type: \"string\"\n      Deleted:\n        description: \"The image ID of an image that was deleted\"\n        type: \"string\"\n\n  ServiceCreateResponse:\n    type: \"object\"\n    description: |\n      contains the information returned to a client on the\n      creation of a new service.\n    properties:\n      ID:\n        description: \"The ID of the created service.\"\n        type: \"string\"\n        x-nullable: false\n        example: \"ak7w3gjqoa3kuz8xcpnyy0pvl\"\n      Warnings:\n        description: |\n          Optional warning message.\n\n          FIXME(thaJeztah): this should have \"omitempty\" in the generated type.\n        type: \"array\"\n        x-nullable: true\n        items:\n          type: \"string\"\n        example:\n          - \"unable to pin image doesnotexist:latest to digest: image library/doesnotexist:latest not found\"\n\n  ServiceUpdateResponse:\n    type: \"object\"\n    properties:\n      Warnings:\n        description: \"Optional warning messages\"\n        type: \"array\"\n        items:\n          type: \"string\"\n    example:\n      Warnings:\n        - \"unable to pin image doesnotexist:latest to digest: image library/doesnotexist:latest not found\"\n\n  ContainerSummary:\n    type: \"object\"\n    properties:\n      Id:\n        description: \"The ID of this container\"\n        type: \"string\"\n        x-go-name: \"ID\"\n      Names:\n        description: \"The names that this container has been given\"\n        type: \"array\"\n        items:\n          type: \"string\"\n      Image:\n        description: \"The name of the image used when creating this container\"\n        type: \"string\"\n      ImageID:\n        description: \"The ID of the image that this container was created from\"\n        type: \"string\"\n      Command:\n        description: \"Command to run when starting the container\"\n        type: \"string\"\n      Created:\n        description: \"When the container was created\"\n        type: \"integer\"\n        format: \"int64\"\n      Ports:\n        description: \"The ports exposed by this container\"\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/Port\"\n      SizeRw:\n        description: \"The size of files that have been created or changed by this container\"\n        type: \"integer\"\n        format: \"int64\"\n      SizeRootFs:\n        description: \"The total size of all the files in this container\"\n        type: \"integer\"\n        format: \"int64\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n      State:\n        description: \"The state of this container (e.g. `Exited`)\"\n        type: \"string\"\n      Status:\n        description: \"Additional human-readable status of this container (e.g. `Exit 0`)\"\n        type: \"string\"\n      HostConfig:\n        type: \"object\"\n        properties:\n          NetworkMode:\n            type: \"string\"\n      NetworkSettings:\n        description: \"A summary of the container's network settings\"\n        type: \"object\"\n        properties:\n          Networks:\n            type: \"object\"\n            additionalProperties:\n              $ref: \"#/definitions/EndpointSettings\"\n      Mounts:\n        type: \"array\"\n        items:\n          $ref: \"#/definitions/MountPoint\"\n\n  Driver:\n    description: \"Driver represents a driver (network, logging, secrets).\"\n    type: \"object\"\n    required: [Name]\n    properties:\n      Name:\n        description: \"Name of the driver.\"\n        type: \"string\"\n        x-nullable: false\n        example: \"some-driver\"\n      Options:\n        description: \"Key/value map of driver-specific options.\"\n        type: \"object\"\n        x-nullable: false\n        additionalProperties:\n          type: \"string\"\n        example:\n          OptionA: \"value for driver-specific option A\"\n          OptionB: \"value for driver-specific option B\"\n\n  SecretSpec:\n    type: \"object\"\n    properties:\n      Name:\n        description: \"User-defined name of the secret.\"\n        type: \"string\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.some-label: \"some-value\"\n          com.example.some-other-label: \"some-other-value\"\n      Data:\n        description: |\n          Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-5))\n          data to store as secret.\n\n          This field is only used to _create_ a secret, and is not returned by\n          other endpoints.\n        type: \"string\"\n        example: \"\"\n      Driver:\n        description: |\n          Name of the secrets driver used to fetch the secret's value from an\n          external secret store.\n        $ref: \"#/definitions/Driver\"\n      Templating:\n        description: |\n          Templating driver, if applicable\n\n          Templating controls whether and how to evaluate the config payload as\n          a template. If no driver is set, no templating is used.\n        $ref: \"#/definitions/Driver\"\n\n  Secret:\n    type: \"object\"\n    properties:\n      ID:\n        type: \"string\"\n        example: \"blt1owaxmitz71s9v5zh81zun\"\n      Version:\n        $ref: \"#/definitions/ObjectVersion\"\n      CreatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2017-07-20T13:55:28.678958722Z\"\n      UpdatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n        example: \"2017-07-20T13:55:28.678958722Z\"\n      Spec:\n        $ref: \"#/definitions/SecretSpec\"\n\n  ConfigSpec:\n    type: \"object\"\n    properties:\n      Name:\n        description: \"User-defined name of the config.\"\n        type: \"string\"\n      Labels:\n        description: \"User-defined key/value metadata.\"\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n      Data:\n        description: |\n          Base64-url-safe-encoded ([RFC 4648](https://tools.ietf.org/html/rfc4648#section-5))\n          config data.\n        type: \"string\"\n      Templating:\n        description: |\n          Templating driver, if applicable\n\n          Templating controls whether and how to evaluate the config payload as\n          a template. If no driver is set, no templating is used.\n        $ref: \"#/definitions/Driver\"\n\n  Config:\n    type: \"object\"\n    properties:\n      ID:\n        type: \"string\"\n      Version:\n        $ref: \"#/definitions/ObjectVersion\"\n      CreatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      UpdatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      Spec:\n        $ref: \"#/definitions/ConfigSpec\"\n\n  ContainerState:\n    description: |\n      ContainerState stores container's running state. It's part of ContainerJSONBase\n      and will be returned by the \"inspect\" command.\n    type: \"object\"\n    x-nullable: true\n    properties:\n      Status:\n        description: |\n          String representation of the container state. Can be one of \"created\",\n          \"running\", \"paused\", \"restarting\", \"removing\", \"exited\", or \"dead\".\n        type: \"string\"\n        enum: [\"created\", \"running\", \"paused\", \"restarting\", \"removing\", \"exited\", \"dead\"]\n        example: \"running\"\n      Running:\n        description: |\n          Whether this container is running.\n\n          Note that a running container can be _paused_. The `Running` and `Paused`\n          booleans are not mutually exclusive:\n\n          When pausing a container (on Linux), the freezer cgroup is used to suspend\n          all processes in the container. Freezing the process requires the process to\n          be running. As a result, paused containers are both `Running` _and_ `Paused`.\n\n          Use the `Status` field instead to determine if a container's state is \"running\".\n        type: \"boolean\"\n        example: true\n      Paused:\n        description: \"Whether this container is paused.\"\n        type: \"boolean\"\n        example: false\n      Restarting:\n        description: \"Whether this container is restarting.\"\n        type: \"boolean\"\n        example: false\n      OOMKilled:\n        description: |\n          Whether a process within this container has been killed because it ran\n          out of memory since the container was last started.\n        type: \"boolean\"\n        example: false\n      Dead:\n        type: \"boolean\"\n        example: false\n      Pid:\n        description: \"The process ID of this container\"\n        type: \"integer\"\n        example: 1234\n      ExitCode:\n        description: \"The last exit code of this container\"\n        type: \"integer\"\n        example: 0\n      Error:\n        type: \"string\"\n      StartedAt:\n        description: \"The time when this container was last started.\"\n        type: \"string\"\n        example: \"2020-01-06T09:06:59.461876391Z\"\n      FinishedAt:\n        description: \"The time when this container last exited.\"\n        type: \"string\"\n        example: \"2020-01-06T09:07:59.461876391Z\"\n      Health:\n        $ref: \"#/definitions/Health\"\n\n  ContainerCreateResponse:\n    description: \"OK response to ContainerCreate operation\"\n    type: \"object\"\n    title: \"ContainerCreateResponse\"\n    x-go-name: \"CreateResponse\"\n    required: [Id, Warnings]\n    properties:\n      Id:\n        description: \"The ID of the created container\"\n        type: \"string\"\n        x-nullable: false\n        example: \"ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743\"\n      Warnings:\n        description: \"Warnings encountered when creating the container\"\n        type: \"array\"\n        x-nullable: false\n        items:\n          type: \"string\"\n        example: []\n\n  ContainerWaitResponse:\n    description: \"OK response to ContainerWait operation\"\n    type: \"object\"\n    x-go-name: \"WaitResponse\"\n    title: \"ContainerWaitResponse\"\n    required: [StatusCode]\n    properties:\n      StatusCode:\n        description: \"Exit code of the container\"\n        type: \"integer\"\n        format: \"int64\"\n        x-nullable: false\n      Error:\n        $ref: \"#/definitions/ContainerWaitExitError\"\n\n  ContainerWaitExitError:\n    description: \"container waiting error, if any\"\n    type: \"object\"\n    x-go-name: \"WaitExitError\"\n    properties:\n      Message:\n        description: \"Details of an error\"\n        type: \"string\"\n\n  SystemVersion:\n    type: \"object\"\n    description: |\n      Response of Engine API: GET \"/version\"\n    properties:\n      Platform:\n        type: \"object\"\n        required: [Name]\n        properties:\n          Name:\n            type: \"string\"\n      Components:\n        type: \"array\"\n        description: |\n          Information about system components\n        items:\n          type: \"object\"\n          x-go-name: ComponentVersion\n          required: [Name, Version]\n          properties:\n            Name:\n              description: |\n                Name of the component\n              type: \"string\"\n              example: \"Engine\"\n            Version:\n              description: |\n                Version of the component\n              type: \"string\"\n              x-nullable: false\n              example: \"19.03.12\"\n            Details:\n              description: |\n                Key/value pairs of strings with additional information about the\n                component. These values are intended for informational purposes\n                only, and their content is not defined, and not part of the API\n                specification.\n\n                These messages can be printed by the client as information to the user.\n              type: \"object\"\n              x-nullable: true\n      Version:\n        description: \"The version of the daemon\"\n        type: \"string\"\n        example: \"19.03.12\"\n      ApiVersion:\n        description: |\n          The default (and highest) API version that is supported by the daemon\n        type: \"string\"\n        example: \"1.40\"\n      MinAPIVersion:\n        description: |\n          The minimum API version that is supported by the daemon\n        type: \"string\"\n        example: \"1.12\"\n      GitCommit:\n        description: |\n          The Git commit of the source code that was used to build the daemon\n        type: \"string\"\n        example: \"48a66213fe\"\n      GoVersion:\n        description: |\n          The version Go used to compile the daemon, and the version of the Go\n          runtime in use.\n        type: \"string\"\n        example: \"go1.21.12\"\n      Os:\n        description: |\n          The operating system that the daemon is running on (\"linux\" or \"windows\")\n        type: \"string\"\n        example: \"linux\"\n      Arch:\n        description: |\n          The architecture that the daemon is running on\n        type: \"string\"\n        example: \"amd64\"\n      KernelVersion:\n        description: |\n          The kernel version (`uname -r`) that the daemon is running on.\n\n          This field is omitted when empty.\n        type: \"string\"\n        example: \"4.19.76-linuxkit\"\n      Experimental:\n        description: |\n          Indicates if the daemon is started with experimental features enabled.\n\n          This field is omitted when empty / false.\n        type: \"boolean\"\n        example: true\n      BuildTime:\n        description: |\n          The date and time that the daemon was compiled.\n        type: \"string\"\n        example: \"2020-06-22T15:49:27.000000000+00:00\"\n\n  SystemInfo:\n    type: \"object\"\n    properties:\n      ID:\n        description: |\n          Unique identifier of the daemon.\n\n          <p><br /></p>\n\n          > **Note**: The format of the ID itself is not part of the API, and\n          > should not be considered stable.\n        type: \"string\"\n        example: \"7TRN:IPZB:QYBB:VPBQ:UMPP:KARE:6ZNR:XE6T:7EWV:PKF4:ZOJD:TPYS\"\n      Containers:\n        description: \"Total number of containers on the host.\"\n        type: \"integer\"\n        example: 14\n      ContainersRunning:\n        description: |\n          Number of containers with status `\"running\"`.\n        type: \"integer\"\n        example: 3\n      ContainersPaused:\n        description: |\n          Number of containers with status `\"paused\"`.\n        type: \"integer\"\n        example: 1\n      ContainersStopped:\n        description: |\n          Number of containers with status `\"stopped\"`.\n        type: \"integer\"\n        example: 10\n      Images:\n        description: |\n          Total number of images on the host.\n\n          Both _tagged_ and _untagged_ (dangling) images are counted.\n        type: \"integer\"\n        example: 508\n      Driver:\n        description: \"Name of the storage driver in use.\"\n        type: \"string\"\n        example: \"overlay2\"\n      DriverStatus:\n        description: |\n          Information specific to the storage driver, provided as\n          \"label\" / \"value\" pairs.\n\n          This information is provided by the storage driver, and formatted\n          in a way consistent with the output of `docker info` on the command\n          line.\n\n          <p><br /></p>\n\n          > **Note**: The information returned in this field, including the\n          > formatting of values and labels, should not be considered stable,\n          > and may change without notice.\n        type: \"array\"\n        items:\n          type: \"array\"\n          items:\n            type: \"string\"\n        example:\n          - [\"Backing Filesystem\", \"extfs\"]\n          - [\"Supports d_type\", \"true\"]\n          - [\"Native Overlay Diff\", \"true\"]\n      DockerRootDir:\n        description: |\n          Root directory of persistent Docker state.\n\n          Defaults to `/var/lib/docker` on Linux, and `C:\\ProgramData\\docker`\n          on Windows.\n        type: \"string\"\n        example: \"/var/lib/docker\"\n      Plugins:\n        $ref: \"#/definitions/PluginsInfo\"\n      MemoryLimit:\n        description: \"Indicates if the host has memory limit support enabled.\"\n        type: \"boolean\"\n        example: true\n      SwapLimit:\n        description: \"Indicates if the host has memory swap limit support enabled.\"\n        type: \"boolean\"\n        example: true\n      KernelMemoryTCP:\n        description: |\n          Indicates if the host has kernel memory TCP limit support enabled. This\n          field is omitted if not supported.\n\n          Kernel memory TCP limits are not supported when using cgroups v2, which\n          does not support the corresponding `memory.kmem.tcp.limit_in_bytes` cgroup.\n        type: \"boolean\"\n        example: true\n      CpuCfsPeriod:\n        description: |\n          Indicates if CPU CFS(Completely Fair Scheduler) period is supported by\n          the host.\n        type: \"boolean\"\n        example: true\n      CpuCfsQuota:\n        description: |\n          Indicates if CPU CFS(Completely Fair Scheduler) quota is supported by\n          the host.\n        type: \"boolean\"\n        example: true\n      CPUShares:\n        description: |\n          Indicates if CPU Shares limiting is supported by the host.\n        type: \"boolean\"\n        example: true\n      CPUSet:\n        description: |\n          Indicates if CPUsets (cpuset.cpus, cpuset.mems) are supported by the host.\n\n          See [cpuset(7)](https://www.kernel.org/doc/Documentation/cgroup-v1/cpusets.txt)\n        type: \"boolean\"\n        example: true\n      PidsLimit:\n        description: \"Indicates if the host kernel has PID limit support enabled.\"\n        type: \"boolean\"\n        example: true\n      OomKillDisable:\n        description: \"Indicates if OOM killer disable is supported on the host.\"\n        type: \"boolean\"\n      IPv4Forwarding:\n        description: \"Indicates IPv4 forwarding is enabled.\"\n        type: \"boolean\"\n        example: true\n      BridgeNfIptables:\n        description: \"Indicates if `bridge-nf-call-iptables` is available on the host.\"\n        type: \"boolean\"\n        example: true\n      BridgeNfIp6tables:\n        description: \"Indicates if `bridge-nf-call-ip6tables` is available on the host.\"\n        type: \"boolean\"\n        example: true\n      Debug:\n        description: |\n          Indicates if the daemon is running in debug-mode / with debug-level\n          logging enabled.\n        type: \"boolean\"\n        example: true\n      NFd:\n        description: |\n          The total number of file Descriptors in use by the daemon process.\n\n          This information is only returned if debug-mode is enabled.\n        type: \"integer\"\n        example: 64\n      NGoroutines:\n        description: |\n          The  number of goroutines that currently exist.\n\n          This information is only returned if debug-mode is enabled.\n        type: \"integer\"\n        example: 174\n      SystemTime:\n        description: |\n          Current system-time in [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt)\n          format with nano-seconds.\n        type: \"string\"\n        example: \"2017-08-08T20:28:29.06202363Z\"\n      LoggingDriver:\n        description: |\n          The logging driver to use as a default for new containers.\n        type: \"string\"\n      CgroupDriver:\n        description: |\n          The driver to use for managing cgroups.\n        type: \"string\"\n        enum: [\"cgroupfs\", \"systemd\", \"none\"]\n        default: \"cgroupfs\"\n        example: \"cgroupfs\"\n      CgroupVersion:\n        description: |\n          The version of the cgroup.\n        type: \"string\"\n        enum: [\"1\", \"2\"]\n        default: \"1\"\n        example: \"1\"\n      NEventsListener:\n        description: \"Number of event listeners subscribed.\"\n        type: \"integer\"\n        example: 30\n      KernelVersion:\n        description: |\n          Kernel version of the host.\n\n          On Linux, this information obtained from `uname`. On Windows this\n          information is queried from the <kbd>HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\</kbd>\n          registry value, for example _\"10.0 14393 (14393.1198.amd64fre.rs1_release_sec.170427-1353)\"_.\n        type: \"string\"\n        example: \"4.9.38-moby\"\n      OperatingSystem:\n        description: |\n          Name of the host's operating system, for example: \"Ubuntu 16.04.2 LTS\"\n          or \"Windows Server 2016 Datacenter\"\n        type: \"string\"\n        example: \"Alpine Linux v3.5\"\n      OSVersion:\n        description: |\n          Version of the host's operating system\n\n          <p><br /></p>\n\n          > **Note**: The information returned in this field, including its\n          > very existence, and the formatting of values, should not be considered\n          > stable, and may change without notice.\n        type: \"string\"\n        example: \"16.04\"\n      OSType:\n        description: |\n          Generic type of the operating system of the host, as returned by the\n          Go runtime (`GOOS`).\n\n          Currently returned values are \"linux\" and \"windows\". A full list of\n          possible values can be found in the [Go documentation](https://go.dev/doc/install/source#environment).\n        type: \"string\"\n        example: \"linux\"\n      Architecture:\n        description: |\n          Hardware architecture of the host, as returned by the Go runtime\n          (`GOARCH`).\n\n          A full list of possible values can be found in the [Go documentation](https://go.dev/doc/install/source#environment).\n        type: \"string\"\n        example: \"x86_64\"\n      NCPU:\n        description: |\n          The number of logical CPUs usable by the daemon.\n\n          The number of available CPUs is checked by querying the operating\n          system when the daemon starts. Changes to operating system CPU\n          allocation after the daemon is started are not reflected.\n        type: \"integer\"\n        example: 4\n      MemTotal:\n        description: |\n          Total amount of physical memory available on the host, in bytes.\n        type: \"integer\"\n        format: \"int64\"\n        example: 2095882240\n\n      IndexServerAddress:\n        description: |\n          Address / URL of the index server that is used for image search,\n          and as a default for user authentication for Docker Hub and Docker Cloud.\n        default: \"https://index.docker.io/v1/\"\n        type: \"string\"\n        example: \"https://index.docker.io/v1/\"\n      RegistryConfig:\n        $ref: \"#/definitions/RegistryServiceConfig\"\n      GenericResources:\n        $ref: \"#/definitions/GenericResources\"\n      HttpProxy:\n        description: |\n          HTTP-proxy configured for the daemon. This value is obtained from the\n          [`HTTP_PROXY`](https://www.gnu.org/software/wget/manual/html_node/Proxies.html) environment variable.\n          Credentials ([user info component](https://tools.ietf.org/html/rfc3986#section-3.2.1)) in the proxy URL\n          are masked in the API response.\n\n          Containers do not automatically inherit this configuration.\n        type: \"string\"\n        example: \"http://xxxxx:xxxxx@proxy.corp.example.com:8080\"\n      HttpsProxy:\n        description: |\n          HTTPS-proxy configured for the daemon. This value is obtained from the\n          [`HTTPS_PROXY`](https://www.gnu.org/software/wget/manual/html_node/Proxies.html) environment variable.\n          Credentials ([user info component](https://tools.ietf.org/html/rfc3986#section-3.2.1)) in the proxy URL\n          are masked in the API response.\n\n          Containers do not automatically inherit this configuration.\n        type: \"string\"\n        example: \"https://xxxxx:xxxxx@proxy.corp.example.com:4443\"\n      NoProxy:\n        description: |\n          Comma-separated list of domain extensions for which no proxy should be\n          used. This value is obtained from the [`NO_PROXY`](https://www.gnu.org/software/wget/manual/html_node/Proxies.html)\n          environment variable.\n\n          Containers do not automatically inherit this configuration.\n        type: \"string\"\n        example: \"*.local, 169.254/16\"\n      Name:\n        description: \"Hostname of the host.\"\n        type: \"string\"\n        example: \"node5.corp.example.com\"\n      Labels:\n        description: |\n          User-defined labels (key/value metadata) as set on the daemon.\n\n          <p><br /></p>\n\n          > **Note**: When part of a Swarm, nodes can both have _daemon_ labels,\n          > set through the daemon configuration, and _node_ labels, set from a\n          > manager node in the Swarm. Node labels are not included in this\n          > field. Node labels can be retrieved using the `/nodes/(id)` endpoint\n          > on a manager node in the Swarm.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"storage=ssd\", \"production\"]\n      ExperimentalBuild:\n        description: |\n          Indicates if experimental features are enabled on the daemon.\n        type: \"boolean\"\n        example: true\n      ServerVersion:\n        description: |\n          Version string of the daemon.\n        type: \"string\"\n        example: \"24.0.2\"\n      Runtimes:\n        description: |\n          List of [OCI compliant](https://github.com/opencontainers/runtime-spec)\n          runtimes configured on the daemon. Keys hold the \"name\" used to\n          reference the runtime.\n\n          The Docker daemon relies on an OCI compliant runtime (invoked via the\n          `containerd` daemon) as its interface to the Linux kernel namespaces,\n          cgroups, and SELinux.\n\n          The default runtime is `runc`, and automatically configured. Additional\n          runtimes can be configured by the user and will be listed here.\n        type: \"object\"\n        additionalProperties:\n          $ref: \"#/definitions/Runtime\"\n        default:\n          runc:\n            path: \"runc\"\n        example:\n          runc:\n            path: \"runc\"\n          runc-master:\n            path: \"/go/bin/runc\"\n          custom:\n            path: \"/usr/local/bin/my-oci-runtime\"\n            runtimeArgs: [\"--debug\", \"--systemd-cgroup=false\"]\n      DefaultRuntime:\n        description: |\n          Name of the default OCI runtime that is used when starting containers.\n\n          The default can be overridden per-container at create time.\n        type: \"string\"\n        default: \"runc\"\n        example: \"runc\"\n      Swarm:\n        $ref: \"#/definitions/SwarmInfo\"\n      LiveRestoreEnabled:\n        description: |\n          Indicates if live restore is enabled.\n\n          If enabled, containers are kept running when the daemon is shutdown\n          or upon daemon start if running containers are detected.\n        type: \"boolean\"\n        default: false\n        example: false\n      Isolation:\n        description: |\n          Represents the isolation technology to use as a default for containers.\n          The supported values are platform-specific.\n\n          If no isolation value is specified on daemon start, on Windows client,\n          the default is `hyperv`, and on Windows server, the default is `process`.\n\n          This option is currently not used on other platforms.\n        default: \"default\"\n        type: \"string\"\n        enum:\n          - \"default\"\n          - \"hyperv\"\n          - \"process\"\n      InitBinary:\n        description: |\n          Name and, optional, path of the `docker-init` binary.\n\n          If the path is omitted, the daemon searches the host's `$PATH` for the\n          binary and uses the first result.\n        type: \"string\"\n        example: \"docker-init\"\n      ContainerdCommit:\n        $ref: \"#/definitions/Commit\"\n      RuncCommit:\n        $ref: \"#/definitions/Commit\"\n      InitCommit:\n        $ref: \"#/definitions/Commit\"\n      SecurityOptions:\n        description: |\n          List of security features that are enabled on the daemon, such as\n          apparmor, seccomp, SELinux, user-namespaces (userns), rootless and\n          no-new-privileges.\n\n          Additional configuration options for each security feature may\n          be present, and are included as a comma-separated list of key/value\n          pairs.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"name=apparmor\"\n          - \"name=seccomp,profile=default\"\n          - \"name=selinux\"\n          - \"name=userns\"\n          - \"name=rootless\"\n      ProductLicense:\n        description: |\n          Reports a summary of the product license on the daemon.\n\n          If a commercial license has been applied to the daemon, information\n          such as number of nodes, and expiration are included.\n        type: \"string\"\n        example: \"Community Engine\"\n      DefaultAddressPools:\n        description: |\n          List of custom default address pools for local networks, which can be\n          specified in the daemon.json file or dockerd option.\n\n          Example: a Base \"10.10.0.0/16\" with Size 24 will define the set of 256\n          10.10.[0-255].0/24 address pools.\n        type: \"array\"\n        items:\n          type: \"object\"\n          properties:\n            Base:\n              description: \"The network address in CIDR format\"\n              type: \"string\"\n              example: \"10.10.0.0/16\"\n            Size:\n              description: \"The network pool size\"\n              type: \"integer\"\n              example: \"24\"\n      Warnings:\n        description: |\n          List of warnings / informational messages about missing features, or\n          issues related to the daemon configuration.\n\n          These messages can be printed by the client as information to the user.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"WARNING: No memory limit support\"\n          - \"WARNING: bridge-nf-call-iptables is disabled\"\n          - \"WARNING: bridge-nf-call-ip6tables is disabled\"\n      CDISpecDirs:\n        description: |\n          List of directories where (Container Device Interface) CDI\n          specifications are located.\n\n          These specifications define vendor-specific modifications to an OCI\n          runtime specification for a container being created.\n\n          An empty list indicates that CDI device injection is disabled.\n\n          Note that since using CDI device injection requires the daemon to have\n          experimental enabled. For non-experimental daemons an empty list will\n          always be returned.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"/etc/cdi\"\n          - \"/var/run/cdi\"\n\n  # PluginsInfo is a temp struct holding Plugins name\n  # registered with docker daemon. It is used by Info struct\n  PluginsInfo:\n    description: |\n      Available plugins per type.\n\n      <p><br /></p>\n\n      > **Note**: Only unmanaged (V1) plugins are included in this list.\n      > V1 plugins are \"lazily\" loaded, and are not returned in this list\n      > if there is no resource using the plugin.\n    type: \"object\"\n    properties:\n      Volume:\n        description: \"Names of available volume-drivers, and network-driver plugins.\"\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"local\"]\n      Network:\n        description: \"Names of available network-drivers, and network-driver plugins.\"\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"bridge\", \"host\", \"ipvlan\", \"macvlan\", \"null\", \"overlay\"]\n      Authorization:\n        description: \"Names of available authorization plugins.\"\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"img-authz-plugin\", \"hbm\"]\n      Log:\n        description: \"Names of available logging-drivers, and logging-driver plugins.\"\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"awslogs\", \"fluentd\", \"gcplogs\", \"gelf\", \"journald\", \"json-file\", \"splunk\", \"syslog\"]\n\n\n  RegistryServiceConfig:\n    description: |\n      RegistryServiceConfig stores daemon registry services configuration.\n    type: \"object\"\n    x-nullable: true\n    properties:\n      AllowNondistributableArtifactsCIDRs:\n        description: |\n          List of IP ranges to which nondistributable artifacts can be pushed,\n          using the CIDR syntax [RFC 4632](https://tools.ietf.org/html/4632).\n\n          Some images (for example, Windows base images) contain artifacts\n          whose distribution is restricted by license. When these images are\n          pushed to a registry, restricted artifacts are not included.\n\n          This configuration override this behavior, and enables the daemon to\n          push nondistributable artifacts to all registries whose resolved IP\n          address is within the subnet described by the CIDR syntax.\n\n          This option is useful when pushing images containing\n          nondistributable artifacts to a registry on an air-gapped network so\n          hosts on that network can pull the images without connecting to\n          another server.\n\n          > **Warning**: Nondistributable artifacts typically have restrictions\n          > on how and where they can be distributed and shared. Only use this\n          > feature to push artifacts to private registries and ensure that you\n          > are in compliance with any terms that cover redistributing\n          > nondistributable artifacts.\n\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"::1/128\", \"127.0.0.0/8\"]\n      AllowNondistributableArtifactsHostnames:\n        description: |\n          List of registry hostnames to which nondistributable artifacts can be\n          pushed, using the format `<hostname>[:<port>]` or `<IP address>[:<port>]`.\n\n          Some images (for example, Windows base images) contain artifacts\n          whose distribution is restricted by license. When these images are\n          pushed to a registry, restricted artifacts are not included.\n\n          This configuration override this behavior for the specified\n          registries.\n\n          This option is useful when pushing images containing\n          nondistributable artifacts to a registry on an air-gapped network so\n          hosts on that network can pull the images without connecting to\n          another server.\n\n          > **Warning**: Nondistributable artifacts typically have restrictions\n          > on how and where they can be distributed and shared. Only use this\n          > feature to push artifacts to private registries and ensure that you\n          > are in compliance with any terms that cover redistributing\n          > nondistributable artifacts.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"registry.internal.corp.example.com:3000\", \"[2001:db8:a0b:12f0::1]:443\"]\n      InsecureRegistryCIDRs:\n        description: |\n          List of IP ranges of insecure registries, using the CIDR syntax\n          ([RFC 4632](https://tools.ietf.org/html/4632)). Insecure registries\n          accept un-encrypted (HTTP) and/or untrusted (HTTPS with certificates\n          from unknown CAs) communication.\n\n          By default, local registries (`127.0.0.0/8`) are configured as\n          insecure. All other registries are secure. Communicating with an\n          insecure registry is not possible if the daemon assumes that registry\n          is secure.\n\n          This configuration override this behavior, insecure communication with\n          registries whose resolved IP address is within the subnet described by\n          the CIDR syntax.\n\n          Registries can also be marked insecure by hostname. Those registries\n          are listed under `IndexConfigs` and have their `Secure` field set to\n          `false`.\n\n          > **Warning**: Using this option can be useful when running a local\n          > registry, but introduces security vulnerabilities. This option\n          > should therefore ONLY be used for testing purposes. For increased\n          > security, users should add their CA to their system's list of trusted\n          > CAs instead of enabling this option.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example: [\"::1/128\", \"127.0.0.0/8\"]\n      IndexConfigs:\n        type: \"object\"\n        additionalProperties:\n          $ref: \"#/definitions/IndexInfo\"\n        example:\n          \"127.0.0.1:5000\":\n            \"Name\": \"127.0.0.1:5000\"\n            \"Mirrors\": []\n            \"Secure\": false\n            \"Official\": false\n          \"[2001:db8:a0b:12f0::1]:80\":\n            \"Name\": \"[2001:db8:a0b:12f0::1]:80\"\n            \"Mirrors\": []\n            \"Secure\": false\n            \"Official\": false\n          \"docker.io\":\n            Name: \"docker.io\"\n            Mirrors: [\"https://hub-mirror.corp.example.com:5000/\"]\n            Secure: true\n            Official: true\n          \"registry.internal.corp.example.com:3000\":\n            Name: \"registry.internal.corp.example.com:3000\"\n            Mirrors: []\n            Secure: false\n            Official: false\n      Mirrors:\n        description: |\n          List of registry URLs that act as a mirror for the official\n          (`docker.io`) registry.\n\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"https://hub-mirror.corp.example.com:5000/\"\n          - \"https://[2001:db8:a0b:12f0::1]/\"\n\n  IndexInfo:\n    description:\n      IndexInfo contains information about a registry.\n    type: \"object\"\n    x-nullable: true\n    properties:\n      Name:\n        description: |\n          Name of the registry, such as \"docker.io\".\n        type: \"string\"\n        example: \"docker.io\"\n      Mirrors:\n        description: |\n          List of mirrors, expressed as URIs.\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"https://hub-mirror.corp.example.com:5000/\"\n          - \"https://registry-2.docker.io/\"\n          - \"https://registry-3.docker.io/\"\n      Secure:\n        description: |\n          Indicates if the registry is part of the list of insecure\n          registries.\n\n          If `false`, the registry is insecure. Insecure registries accept\n          un-encrypted (HTTP) and/or untrusted (HTTPS with certificates from\n          unknown CAs) communication.\n\n          > **Warning**: Insecure registries can be useful when running a local\n          > registry. However, because its use creates security vulnerabilities\n          > it should ONLY be enabled for testing purposes. For increased\n          > security, users should add their CA to their system's list of\n          > trusted CAs instead of enabling this option.\n        type: \"boolean\"\n        example: true\n      Official:\n        description: |\n          Indicates whether this is an official registry (i.e., Docker Hub / docker.io)\n        type: \"boolean\"\n        example: true\n\n  Runtime:\n    description: |\n      Runtime describes an [OCI compliant](https://github.com/opencontainers/runtime-spec)\n      runtime.\n\n      The runtime is invoked by the daemon via the `containerd` daemon. OCI\n      runtimes act as an interface to the Linux kernel namespaces, cgroups,\n      and SELinux.\n    type: \"object\"\n    properties:\n      path:\n        description: |\n          Name and, optional, path, of the OCI executable binary.\n\n          If the path is omitted, the daemon searches the host's `$PATH` for the\n          binary and uses the first result.\n        type: \"string\"\n        example: \"/usr/local/bin/my-oci-runtime\"\n      runtimeArgs:\n        description: |\n          List of command-line arguments to pass to the runtime when invoked.\n        type: \"array\"\n        x-nullable: true\n        items:\n          type: \"string\"\n        example: [\"--debug\", \"--systemd-cgroup=false\"]\n      status:\n        description: |\n          Information specific to the runtime.\n\n          While this API specification does not define data provided by runtimes,\n          the following well-known properties may be provided by runtimes:\n\n          `org.opencontainers.runtime-spec.features`: features structure as defined\n          in the [OCI Runtime Specification](https://github.com/opencontainers/runtime-spec/blob/main/features.md),\n          in a JSON string representation.\n\n          <p><br /></p>\n\n          > **Note**: The information returned in this field, including the\n          > formatting of values and labels, should not be considered stable,\n          > and may change without notice.\n        type: \"object\"\n        x-nullable: true\n        additionalProperties:\n          type: \"string\"\n        example:\n          \"org.opencontainers.runtime-spec.features\": \"{\\\"ociVersionMin\\\":\\\"1.0.0\\\",\\\"ociVersionMax\\\":\\\"1.1.0\\\",\\\"...\\\":\\\"...\\\"}\"\n\n  Commit:\n    description: |\n      Commit holds the Git-commit (SHA1) that a binary was built from, as\n      reported in the version-string of external tools, such as `containerd`,\n      or `runC`.\n    type: \"object\"\n    properties:\n      ID:\n        description: \"Actual commit ID of external tool.\"\n        type: \"string\"\n        example: \"cfb82a876ecc11b5ca0977d1733adbe58599088a\"\n      Expected:\n        description: |\n          Commit ID of external tool expected by dockerd as set at build time.\n        type: \"string\"\n        example: \"2d41c047c83e09a6d61d464906feb2a2f3c52aa4\"\n\n  SwarmInfo:\n    description: |\n      Represents generic information about swarm.\n    type: \"object\"\n    properties:\n      NodeID:\n        description: \"Unique identifier of for this node in the swarm.\"\n        type: \"string\"\n        default: \"\"\n        example: \"k67qz4598weg5unwwffg6z1m1\"\n      NodeAddr:\n        description: |\n          IP address at which this node can be reached by other nodes in the\n          swarm.\n        type: \"string\"\n        default: \"\"\n        example: \"10.0.0.46\"\n      LocalNodeState:\n        $ref: \"#/definitions/LocalNodeState\"\n      ControlAvailable:\n        type: \"boolean\"\n        default: false\n        example: true\n      Error:\n        type: \"string\"\n        default: \"\"\n      RemoteManagers:\n        description: |\n          List of ID's and addresses of other managers in the swarm.\n        type: \"array\"\n        default: null\n        x-nullable: true\n        items:\n          $ref: \"#/definitions/PeerNode\"\n        example:\n          - NodeID: \"71izy0goik036k48jg985xnds\"\n            Addr: \"10.0.0.158:2377\"\n          - NodeID: \"79y6h1o4gv8n120drcprv5nmc\"\n            Addr: \"10.0.0.159:2377\"\n          - NodeID: \"k67qz4598weg5unwwffg6z1m1\"\n            Addr: \"10.0.0.46:2377\"\n      Nodes:\n        description: \"Total number of nodes in the swarm.\"\n        type: \"integer\"\n        x-nullable: true\n        example: 4\n      Managers:\n        description: \"Total number of managers in the swarm.\"\n        type: \"integer\"\n        x-nullable: true\n        example: 3\n      Cluster:\n        $ref: \"#/definitions/ClusterInfo\"\n\n  LocalNodeState:\n    description: \"Current local status of this node.\"\n    type: \"string\"\n    default: \"\"\n    enum:\n      - \"\"\n      - \"inactive\"\n      - \"pending\"\n      - \"active\"\n      - \"error\"\n      - \"locked\"\n    example: \"active\"\n\n  PeerNode:\n    description: \"Represents a peer-node in the swarm\"\n    type: \"object\"\n    properties:\n      NodeID:\n        description: \"Unique identifier of for this node in the swarm.\"\n        type: \"string\"\n      Addr:\n        description: |\n          IP address and ports at which this node can be reached.\n        type: \"string\"\n\n  NetworkAttachmentConfig:\n    description: |\n      Specifies how a service should be attached to a particular network.\n    type: \"object\"\n    properties:\n      Target:\n        description: |\n          The target network for attachment. Must be a network name or ID.\n        type: \"string\"\n      Aliases:\n        description: |\n          Discoverable alternate names for the service on this network.\n        type: \"array\"\n        items:\n          type: \"string\"\n      DriverOpts:\n        description: |\n          Driver attachment options for the network target.\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n\n  EventActor:\n    description: |\n      Actor describes something that generates events, like a container, network,\n      or a volume.\n    type: \"object\"\n    properties:\n      ID:\n        description: \"The ID of the object emitting the event\"\n        type: \"string\"\n        example: \"ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743\"\n      Attributes:\n        description: |\n          Various key/value attributes of the object, depending on its type.\n        type: \"object\"\n        additionalProperties:\n          type: \"string\"\n        example:\n          com.example.some-label: \"some-label-value\"\n          image: \"alpine:latest\"\n          name: \"my-container\"\n\n  EventMessage:\n    description: |\n      EventMessage represents the information an event contains.\n    type: \"object\"\n    title: \"SystemEventsResponse\"\n    properties:\n      Type:\n        description: \"The type of object emitting the event\"\n        type: \"string\"\n        enum: [\"builder\", \"config\", \"container\", \"daemon\", \"image\", \"network\", \"node\", \"plugin\", \"secret\", \"service\", \"volume\"]\n        example: \"container\"\n      Action:\n        description: \"The type of event\"\n        type: \"string\"\n        example: \"create\"\n      Actor:\n        $ref: \"#/definitions/EventActor\"\n      scope:\n        description: |\n          Scope of the event. Engine events are `local` scope. Cluster (Swarm)\n          events are `swarm` scope.\n        type: \"string\"\n        enum: [\"local\", \"swarm\"]\n      time:\n        description: \"Timestamp of event\"\n        type: \"integer\"\n        format: \"int64\"\n        example: 1629574695\n      timeNano:\n        description: \"Timestamp of event, with nanosecond accuracy\"\n        type: \"integer\"\n        format: \"int64\"\n        example: 1629574695515050031\n\n  OCIDescriptor:\n    type: \"object\"\n    x-go-name: Descriptor\n    description: |\n      A descriptor struct containing digest, media type, and size, as defined in\n      the [OCI Content Descriptors Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/descriptor.md).\n    properties:\n      mediaType:\n        description: |\n          The media type of the object this schema refers to.\n        type: \"string\"\n        example: \"application/vnd.docker.distribution.manifest.v2+json\"\n      digest:\n        description: |\n          The digest of the targeted content.\n        type: \"string\"\n        example: \"sha256:c0537ff6a5218ef531ece93d4984efc99bbf3f7497c0a7726c88e2bb7584dc96\"\n      size:\n        description: |\n          The size in bytes of the blob.\n        type: \"integer\"\n        format: \"int64\"\n        example: 3987495\n        # TODO Not yet including these fields for now, as they are nil / omitted in our response.\n        # urls:\n        #   description: |\n        #     List of URLs from which this object MAY be downloaded.\n        #   type: \"array\"\n        #   items:\n        #     type: \"string\"\n        #     format: \"uri\"\n        # annotations:\n        #   description: |\n        #     Arbitrary metadata relating to the targeted content.\n        #   type: \"object\"\n        #   additionalProperties:\n        #     type: \"string\"\n        # platform:\n        #   $ref: \"#/definitions/OCIPlatform\"\n\n  OCIPlatform:\n    type: \"object\"\n    x-go-name: Platform\n    description: |\n      Describes the platform which the image in the manifest runs on, as defined\n      in the [OCI Image Index Specification](https://github.com/opencontainers/image-spec/blob/v1.0.1/image-index.md).\n    properties:\n      architecture:\n        description: |\n          The CPU architecture, for example `amd64` or `ppc64`.\n        type: \"string\"\n        example: \"arm\"\n      os:\n        description: |\n          The operating system, for example `linux` or `windows`.\n        type: \"string\"\n        example: \"windows\"\n      os.version:\n        description: |\n          Optional field specifying the operating system version, for example on\n          Windows `10.0.19041.1165`.\n        type: \"string\"\n        example: \"10.0.19041.1165\"\n      os.features:\n        description: |\n          Optional field specifying an array of strings, each listing a required\n          OS feature (for example on Windows `win32k`).\n        type: \"array\"\n        items:\n          type: \"string\"\n        example:\n          - \"win32k\"\n      variant:\n        description: |\n          Optional field specifying a variant of the CPU, for example `v7` to\n          specify ARMv7 when architecture is `arm`.\n        type: \"string\"\n        example: \"v7\"\n\n  DistributionInspect:\n    type: \"object\"\n    x-go-name: DistributionInspect\n    title: \"DistributionInspectResponse\"\n    required: [Descriptor, Platforms]\n    description: |\n      Describes the result obtained from contacting the registry to retrieve\n      image metadata.\n    properties:\n      Descriptor:\n        $ref: \"#/definitions/OCIDescriptor\"\n      Platforms:\n        type: \"array\"\n        description: |\n          An array containing all platforms supported by the image.\n        items:\n          $ref: \"#/definitions/OCIPlatform\"\n\n  ClusterVolume:\n    type: \"object\"\n    description: |\n      Options and information specific to, and only present on, Swarm CSI\n      cluster volumes.\n    properties:\n      ID:\n        type: \"string\"\n        description: |\n          The Swarm ID of this volume. Because cluster volumes are Swarm\n          objects, they have an ID, unlike non-cluster volumes. This ID can\n          be used to refer to the Volume instead of the name.\n      Version:\n        $ref: \"#/definitions/ObjectVersion\"\n      CreatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      UpdatedAt:\n        type: \"string\"\n        format: \"dateTime\"\n      Spec:\n        $ref: \"#/definitions/ClusterVolumeSpec\"\n      Info:\n        type: \"object\"\n        description: |\n          Information about the global status of the volume.\n        properties:\n          CapacityBytes:\n            type: \"integer\"\n            format: \"int64\"\n            description: |\n              The capacity of the volume in bytes. A value of 0 indicates that\n              the capacity is unknown.\n          VolumeContext:\n            type: \"object\"\n            description: |\n              A map of strings to strings returned from the storage plugin when\n              the volume is created.\n            additionalProperties:\n              type: \"string\"\n          VolumeID:\n            type: \"string\"\n            description: |\n              The ID of the volume as returned by the CSI storage plugin. This\n              is distinct from the volume's ID as provided by Docker. This ID\n              is never used by the user when communicating with Docker to refer\n              to this volume. If the ID is blank, then the Volume has not been\n              successfully created in the plugin yet.\n          AccessibleTopology:\n            type: \"array\"\n            description: |\n              The topology this volume is actually accessible from.\n            items:\n              $ref: \"#/definitions/Topology\"\n      PublishStatus:\n        type: \"array\"\n        description: |\n          The status of the volume as it pertains to its publishing and use on\n          specific nodes\n        items:\n          type: \"object\"\n          properties:\n            NodeID:\n              type: \"string\"\n              description: |\n                The ID of the Swarm node the volume is published on.\n            State:\n              type: \"string\"\n              description: |\n                The published state of the volume.\n                * `pending-publish` The volume should be published to this node, but the call to the controller plugin to do so has not yet been successfully completed.\n                * `published` The volume is published successfully to the node.\n                * `pending-node-unpublish` The volume should be unpublished from the node, and the manager is awaiting confirmation from the worker that it has done so.\n                * `pending-controller-unpublish` The volume is successfully unpublished from the node, but has not yet been successfully unpublished on the controller.\n              enum:\n                - \"pending-publish\"\n                - \"published\"\n                - \"pending-node-unpublish\"\n                - \"pending-controller-unpublish\"\n            PublishContext:\n              type: \"object\"\n              description: |\n                A map of strings to strings returned by the CSI controller\n                plugin when a volume is published.\n              additionalProperties:\n                type: \"string\"\n\n  ClusterVolumeSpec:\n    type: \"object\"\n    description: |\n      Cluster-specific options used to create the volume.\n    properties:\n      Group:\n        type: \"string\"\n        description: |\n          Group defines the volume group of this volume. Volumes belonging to\n          the same group can be referred to by group name when creating\n          Services.  Referring to a volume by group instructs Swarm to treat\n          volumes in that group interchangeably for the purpose of scheduling.\n          Volumes with an empty string for a group technically all belong to\n          the same, emptystring group.\n      AccessMode:\n        type: \"object\"\n        description: |\n          Defines how the volume is used by tasks.\n        properties:\n          Scope:\n            type: \"string\"\n            description: |\n              The set of nodes this volume can be used on at one time.\n              - `single` The volume may only be scheduled to one node at a time.\n              - `multi` the volume may be scheduled to any supported number of nodes at a time.\n            default: \"single\"\n            enum: [\"single\", \"multi\"]\n            x-nullable: false\n          Sharing:\n            type: \"string\"\n            description: |\n              The number and way that different tasks can use this volume\n              at one time.\n              - `none` The volume may only be used by one task at a time.\n              - `readonly` The volume may be used by any number of tasks, but they all must mount the volume as readonly\n              - `onewriter` The volume may be used by any number of tasks, but only one may mount it as read/write.\n              - `all` The volume may have any number of readers and writers.\n            default: \"none\"\n            enum: [\"none\", \"readonly\", \"onewriter\", \"all\"]\n            x-nullable: false\n          MountVolume:\n            type: \"object\"\n            description: |\n              Options for using this volume as a Mount-type volume.\n\n                  Either MountVolume or BlockVolume, but not both, must be\n                  present.\n                properties:\n                  FsType:\n                    type: \"string\"\n                    description: |\n                      Specifies the filesystem type for the mount volume.\n                      Optional.\n                  MountFlags:\n                    type: \"array\"\n                    description: |\n                      Flags to pass when mounting the volume. Optional.\n                    items:\n                      type: \"string\"\n              BlockVolume:\n                type: \"object\"\n                description: |\n                  Options for using this volume as a Block-type volume.\n                  Intentionally empty.\n          Secrets:\n            type: \"array\"\n            description: |\n              Swarm Secrets that are passed to the CSI storage plugin when\n              operating on this volume.\n            items:\n              type: \"object\"\n              description: |\n                One cluster volume secret entry. Defines a key-value pair that\n                is passed to the plugin.\n              properties:\n                Key:\n                  type: \"string\"\n                  description: |\n                    Key is the name of the key of the key-value pair passed to\n                    the plugin.\n                Secret:\n                  type: \"string\"\n                  description: |\n                    Secret is the swarm Secret object from which to read data.\n                    This can be a Secret name or ID. The Secret data is\n                    retrieved by swarm and used as the value of the key-value\n                    pair passed to the plugin.\n          AccessibilityRequirements:\n            type: \"object\"\n            description: |\n              Requirements for the accessible topology of the volume. These\n              fields are optional. For an in-depth description of what these\n              fields mean, see the CSI specification.\n            properties:\n              Requisite:\n                type: \"array\"\n                description: |\n                  A list of required topologies, at least one of which the\n                  volume must be accessible from.\n                items:\n                  $ref: \"#/definitions/Topology\"\n              Preferred:\n                type: \"array\"\n                description: |\n                  A list of topologies that the volume should attempt to be\n                  provisioned in.\n                items:\n                  $ref: \"#/definitions/Topology\"\n          CapacityRange:\n            type: \"object\"\n            description: |\n              The desired capacity that the volume should be created with. If\n              empty, the plugin will decide the capacity.\n            properties:\n              RequiredBytes:\n                type: \"integer\"\n                format: \"int64\"\n                description: |\n                  The volume must be at least this big. The value of 0\n                  indicates an unspecified minimum\n              LimitBytes:\n                type: \"integer\"\n                format: \"int64\"\n                description: |\n                  The volume must not be bigger than this. The value of 0\n                  indicates an unspecified maximum.\n          Availability:\n            type: \"string\"\n            description: |\n              The availability of the volume for use in tasks.\n              - `active` The volume is fully available for scheduling on the cluster\n              - `pause` No new workloads should use the volume, but existing workloads are not stopped.\n              - `drain` All workloads using this volume should be stopped and rescheduled, and no new ones should be started.\n            default: \"active\"\n            x-nullable: false\n            enum:\n              - \"active\"\n              - \"pause\"\n              - \"drain\"\n\n  Topology:\n    description: |\n      A map of topological domains to topological segments. For in depth\n      details, see documentation for the Topology object in the CSI\n      specification.\n    type: \"object\"\n    additionalProperties:\n      type: \"string\"\n\npaths:\n  /containers/json:\n    get:\n      summary: \"List containers\"\n      description: |\n        Returns a list of containers. For details on the format, see the\n        [inspect endpoint](#operation/ContainerInspect).\n\n        Note that it uses a different, smaller representation of a container\n        than inspecting a single container. For example, the list of linked\n        containers is not propagated .\n      operationId: \"ContainerList\"\n      produces:\n        - \"application/json\"\n      parameters:\n        - name: \"all\"\n          in: \"query\"\n          description: |\n            Return all containers. By default, only running containers are shown.\n          type: \"boolean\"\n          default: false\n        - name: \"limit\"\n          in: \"query\"\n          description: |\n            Return this number of most recently created containers, including\n            non-running ones.\n          type: \"integer\"\n        - name: \"size\"\n          in: \"query\"\n          description: |\n            Return the size of container as fields `SizeRw` and `SizeRootFs`.\n          type: \"boolean\"\n          default: false\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            Filters to process on the container list, encoded as JSON (a\n            `map[string][]string`). For example, `{\"status\": [\"paused\"]}` will\n            only return paused containers.\n\n            Available filters:\n\n            - `ancestor`=(`<image-name>[:<tag>]`, `<image id>`, or `<image@digest>`)\n            - `before`=(`<container id>` or `<container name>`)\n            - `expose`=(`<port>[/<proto>]`|`<startport-endport>/[<proto>]`)\n            - `exited=<int>` containers with exit code of `<int>`\n            - `health`=(`starting`|`healthy`|`unhealthy`|`none`)\n            - `id=<ID>` a container's ID\n            - `isolation=`(`default`|`process`|`hyperv`) (Windows daemon only)\n            - `is-task=`(`true`|`false`)\n            - `label=key` or `label=\"key=value\"` of a container label\n            - `name=<name>` a container's name\n            - `network`=(`<network id>` or `<network name>`)\n            - `publish`=(`<port>[/<proto>]`|`<startport-endport>/[<proto>]`)\n            - `since`=(`<container id>` or `<container name>`)\n            - `status=`(`created`|`restarting`|`running`|`removing`|`paused`|`exited`|`dead`)\n            - `volume`=(`<volume name>` or `<mount point destination>`)\n          type: \"string\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/ContainerSummary\"\n          examples:\n            application/json:\n              - Id: \"8dfafdbc3a40\"\n                Names:\n                  - \"/boring_feynman\"\n                Image: \"ubuntu:latest\"\n                ImageID: \"d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82\"\n                Command: \"echo 1\"\n                Created: 1367854155\n                State: \"Exited\"\n                Status: \"Exit 0\"\n                Ports:\n                  - PrivatePort: 2222\n                    PublicPort: 3333\n                    Type: \"tcp\"\n                Labels:\n                  com.example.vendor: \"Acme\"\n                  com.example.license: \"GPL\"\n                  com.example.version: \"1.0\"\n                SizeRw: 12288\n                SizeRootFs: 0\n                HostConfig:\n                  NetworkMode: \"default\"\n                NetworkSettings:\n                  Networks:\n                    bridge:\n                      NetworkID: \"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812\"\n                      EndpointID: \"2cdc4edb1ded3631c81f57966563e5c8525b81121bb3706a9a9a3ae102711f3f\"\n                      Gateway: \"172.17.0.1\"\n                      IPAddress: \"172.17.0.2\"\n                      IPPrefixLen: 16\n                      IPv6Gateway: \"\"\n                      GlobalIPv6Address: \"\"\n                      GlobalIPv6PrefixLen: 0\n                      MacAddress: \"02:42:ac:11:00:02\"\n                Mounts:\n                  - Name: \"fac362...80535\"\n                    Source: \"/data\"\n                    Destination: \"/data\"\n                    Driver: \"local\"\n                    Mode: \"ro,Z\"\n                    RW: false\n                    Propagation: \"\"\n              - Id: \"9cd87474be90\"\n                Names:\n                  - \"/coolName\"\n                Image: \"ubuntu:latest\"\n                ImageID: \"d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82\"\n                Command: \"echo 222222\"\n                Created: 1367854155\n                State: \"Exited\"\n                Status: \"Exit 0\"\n                Ports: []\n                Labels: {}\n                SizeRw: 12288\n                SizeRootFs: 0\n                HostConfig:\n                  NetworkMode: \"default\"\n                NetworkSettings:\n                  Networks:\n                    bridge:\n                      NetworkID: \"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812\"\n                      EndpointID: \"88eaed7b37b38c2a3f0c4bc796494fdf51b270c2d22656412a2ca5d559a64d7a\"\n                      Gateway: \"172.17.0.1\"\n                      IPAddress: \"172.17.0.8\"\n                      IPPrefixLen: 16\n                      IPv6Gateway: \"\"\n                      GlobalIPv6Address: \"\"\n                      GlobalIPv6PrefixLen: 0\n                      MacAddress: \"02:42:ac:11:00:08\"\n                Mounts: []\n              - Id: \"3176a2479c92\"\n                Names:\n                  - \"/sleepy_dog\"\n                Image: \"ubuntu:latest\"\n                ImageID: \"d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82\"\n                Command: \"echo 3333333333333333\"\n                Created: 1367854154\n                State: \"Exited\"\n                Status: \"Exit 0\"\n                Ports: []\n                Labels: {}\n                SizeRw: 12288\n                SizeRootFs: 0\n                HostConfig:\n                  NetworkMode: \"default\"\n                NetworkSettings:\n                  Networks:\n                    bridge:\n                      NetworkID: \"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812\"\n                      EndpointID: \"8b27c041c30326d59cd6e6f510d4f8d1d570a228466f956edf7815508f78e30d\"\n                      Gateway: \"172.17.0.1\"\n                      IPAddress: \"172.17.0.6\"\n                      IPPrefixLen: 16\n                      IPv6Gateway: \"\"\n                      GlobalIPv6Address: \"\"\n                      GlobalIPv6PrefixLen: 0\n                      MacAddress: \"02:42:ac:11:00:06\"\n                Mounts: []\n              - Id: \"4cb07b47f9fb\"\n                Names:\n                  - \"/running_cat\"\n                Image: \"ubuntu:latest\"\n                ImageID: \"d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82\"\n                Command: \"echo 444444444444444444444444444444444\"\n                Created: 1367854152\n                State: \"Exited\"\n                Status: \"Exit 0\"\n                Ports: []\n                Labels: {}\n                SizeRw: 12288\n                SizeRootFs: 0\n                HostConfig:\n                  NetworkMode: \"default\"\n                NetworkSettings:\n                  Networks:\n                    bridge:\n                      NetworkID: \"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812\"\n                      EndpointID: \"d91c7b2f0644403d7ef3095985ea0e2370325cd2332ff3a3225c4247328e66e9\"\n                      Gateway: \"172.17.0.1\"\n                      IPAddress: \"172.17.0.5\"\n                      IPPrefixLen: 16\n                      IPv6Gateway: \"\"\n                      GlobalIPv6Address: \"\"\n                      GlobalIPv6PrefixLen: 0\n                      MacAddress: \"02:42:ac:11:00:05\"\n                Mounts: []\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Container\"]\n  /containers/create:\n    post:\n      summary: \"Create a container\"\n      operationId: \"ContainerCreate\"\n      consumes:\n        - \"application/json\"\n        - \"application/octet-stream\"\n      produces:\n        - \"application/json\"\n      parameters:\n        - name: \"name\"\n          in: \"query\"\n          description: |\n            Assign the specified name to the container. Must match\n            `/?[a-zA-Z0-9][a-zA-Z0-9_.-]+`.\n          type: \"string\"\n          pattern: \"^/?[a-zA-Z0-9][a-zA-Z0-9_.-]+$\"\n        - name: \"platform\"\n          in: \"query\"\n          description: |\n            Platform in the format `os[/arch[/variant]]` used for image lookup.\n\n            When specified, the daemon checks if the requested image is present\n            in the local image cache with the given OS and Architecture, and\n            otherwise returns a `404` status.\n\n            If the option is not set, the host's native OS and Architecture are\n            used to look up the image in the image cache. However, if no platform\n            is passed and the given image does exist in the local image cache,\n            but its OS or architecture does not match, the container is created\n            with the available image, and a warning is added to the `Warnings`\n            field in the response, for example;\n\n                WARNING: The requested image's platform (linux/arm64/v8) does not\n                         match the detected host platform (linux/amd64) and no\n                         specific platform was requested\n\n          type: \"string\"\n          default: \"\"\n        - name: \"body\"\n          in: \"body\"\n          description: \"Container to create\"\n          schema:\n            allOf:\n              - $ref: \"#/definitions/ContainerConfig\"\n              - type: \"object\"\n                properties:\n                  HostConfig:\n                    $ref: \"#/definitions/HostConfig\"\n                  NetworkingConfig:\n                    $ref: \"#/definitions/NetworkingConfig\"\n            example:\n              Hostname: \"\"\n              Domainname: \"\"\n              User: \"\"\n              AttachStdin: false\n              AttachStdout: true\n              AttachStderr: true\n              Tty: false\n              OpenStdin: false\n              StdinOnce: false\n              Env:\n                - \"FOO=bar\"\n                - \"BAZ=quux\"\n              Cmd:\n                - \"date\"\n              Entrypoint: \"\"\n              Image: \"ubuntu\"\n              Labels:\n                com.example.vendor: \"Acme\"\n                com.example.license: \"GPL\"\n                com.example.version: \"1.0\"\n              Volumes:\n                /volumes/data: {}\n              WorkingDir: \"\"\n              NetworkDisabled: false\n              MacAddress: \"12:34:56:78:9a:bc\"\n              ExposedPorts:\n                22/tcp: {}\n              StopSignal: \"SIGTERM\"\n              StopTimeout: 10\n              HostConfig:\n                Binds:\n                  - \"/tmp:/tmp\"\n                Links:\n                  - \"redis3:redis\"\n                Memory: 0\n                MemorySwap: 0\n                MemoryReservation: 0\n                NanoCpus: 500000\n                CpuPercent: 80\n                CpuShares: 512\n                CpuPeriod: 100000\n                CpuRealtimePeriod: 1000000\n                CpuRealtimeRuntime: 10000\n                CpuQuota: 50000\n                CpusetCpus: \"0,1\"\n                CpusetMems: \"0,1\"\n                MaximumIOps: 0\n                MaximumIOBps: 0\n                BlkioWeight: 300\n                BlkioWeightDevice:\n                  - {}\n                BlkioDeviceReadBps:\n                  - {}\n                BlkioDeviceReadIOps:\n                  - {}\n                BlkioDeviceWriteBps:\n                  - {}\n                BlkioDeviceWriteIOps:\n                  - {}\n                DeviceRequests:\n                  - Driver: \"nvidia\"\n                    Count: -1\n                    DeviceIDs\": [\"0\", \"1\", \"GPU-fef8089b-4820-abfc-e83e-94318197576e\"]\n                    Capabilities: [[\"gpu\", \"nvidia\", \"compute\"]]\n                    Options:\n                      property1: \"string\"\n                      property2: \"string\"\n                MemorySwappiness: 60\n                OomKillDisable: false\n                OomScoreAdj: 500\n                PidMode: \"\"\n                PidsLimit: 0\n                PortBindings:\n                  22/tcp:\n                    - HostPort: \"11022\"\n                PublishAllPorts: false\n                Privileged: false\n                ReadonlyRootfs: false\n                Dns:\n                  - \"8.8.8.8\"\n                DnsOptions:\n                  - \"\"\n                DnsSearch:\n                  - \"\"\n                VolumesFrom:\n                  - \"parent\"\n                  - \"other:ro\"\n                CapAdd:\n                  - \"NET_ADMIN\"\n                CapDrop:\n                  - \"MKNOD\"\n                GroupAdd:\n                  - \"newgroup\"\n                RestartPolicy:\n                  Name: \"\"\n                  MaximumRetryCount: 0\n                AutoRemove: true\n                NetworkMode: \"bridge\"\n                Devices: []\n                Ulimits:\n                  - {}\n                LogConfig:\n                  Type: \"json-file\"\n                  Config: {}\n                SecurityOpt: []\n                StorageOpt: {}\n                CgroupParent: \"\"\n                VolumeDriver: \"\"\n                ShmSize: 67108864\n              NetworkingConfig:\n                EndpointsConfig:\n                  isolated_nw:\n                    IPAMConfig:\n                      IPv4Address: \"172.20.30.33\"\n                      IPv6Address: \"2001:db8:abcd::3033\"\n                      LinkLocalIPs:\n                        - \"169.254.34.68\"\n                        - \"fe80::3468\"\n                    Links:\n                      - \"container_1\"\n                      - \"container_2\"\n                    Aliases:\n                      - \"server_x\"\n                      - \"server_y\"\n                  database_nw: {}\n\n          required: true\n      responses:\n        201:\n          description: \"Container created successfully\"\n          schema:\n            $ref: \"#/definitions/ContainerCreateResponse\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such image\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such image: c2ada9df5af8\"\n        409:\n          description: \"conflict\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Container\"]\n  /containers/{id}/json:\n    get:\n      summary: \"Inspect a container\"\n      description: \"Return low-level information about a container.\"\n      operationId: \"ContainerInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"object\"\n            title: \"ContainerInspectResponse\"\n            properties:\n              Id:\n                description: \"The ID of the container\"\n                type: \"string\"\n              Created:\n                description: \"The time the container was created\"\n                type: \"string\"\n              Path:\n                description: \"The path to the command being run\"\n                type: \"string\"\n              Args:\n                description: \"The arguments to the command being run\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n              State:\n                $ref: \"#/definitions/ContainerState\"\n              Image:\n                description: \"The container's image ID\"\n                type: \"string\"\n              ResolvConfPath:\n                type: \"string\"\n              HostnamePath:\n                type: \"string\"\n              HostsPath:\n                type: \"string\"\n              LogPath:\n                type: \"string\"\n              Name:\n                type: \"string\"\n              RestartCount:\n                type: \"integer\"\n              Driver:\n                type: \"string\"\n              Platform:\n                type: \"string\"\n              MountLabel:\n                type: \"string\"\n              ProcessLabel:\n                type: \"string\"\n              AppArmorProfile:\n                type: \"string\"\n              ExecIDs:\n                description: \"IDs of exec instances that are running in the container.\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n                x-nullable: true\n              HostConfig:\n                $ref: \"#/definitions/HostConfig\"\n              GraphDriver:\n                $ref: \"#/definitions/GraphDriverData\"\n              SizeRw:\n                description: |\n                  The size of files that have been created or changed by this\n                  container.\n                type: \"integer\"\n                format: \"int64\"\n              SizeRootFs:\n                description: \"The total size of all the files in this container.\"\n                type: \"integer\"\n                format: \"int64\"\n              Mounts:\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/MountPoint\"\n              Config:\n                $ref: \"#/definitions/ContainerConfig\"\n              NetworkSettings:\n                $ref: \"#/definitions/NetworkSettings\"\n          examples:\n            application/json:\n              AppArmorProfile: \"\"\n              Args:\n                - \"-c\"\n                - \"exit 9\"\n              Config:\n                AttachStderr: true\n                AttachStdin: false\n                AttachStdout: true\n                Cmd:\n                  - \"/bin/sh\"\n                  - \"-c\"\n                  - \"exit 9\"\n                Domainname: \"\"\n                Env:\n                  - \"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\n                Healthcheck:\n                  Test: [\"CMD-SHELL\", \"exit 0\"]\n                Hostname: \"ba033ac44011\"\n                Image: \"ubuntu\"\n                Labels:\n                  com.example.vendor: \"Acme\"\n                  com.example.license: \"GPL\"\n                  com.example.version: \"1.0\"\n                MacAddress: \"\"\n                NetworkDisabled: false\n                OpenStdin: false\n                StdinOnce: false\n                Tty: false\n                User: \"\"\n                Volumes:\n                  /volumes/data: {}\n                WorkingDir: \"\"\n                StopSignal: \"SIGTERM\"\n                StopTimeout: 10\n              Created: \"2015-01-06T15:47:31.485331387Z\"\n              Driver: \"overlay2\"\n              ExecIDs:\n                - \"b35395de42bc8abd327f9dd65d913b9ba28c74d2f0734eeeae84fa1c616a0fca\"\n                - \"3fc1232e5cd20c8de182ed81178503dc6437f4e7ef12b52cc5e8de020652f1c4\"\n              HostConfig:\n                MaximumIOps: 0\n                MaximumIOBps: 0\n                BlkioWeight: 0\n                BlkioWeightDevice:\n                  - {}\n                BlkioDeviceReadBps:\n                  - {}\n                BlkioDeviceWriteBps:\n                  - {}\n                BlkioDeviceReadIOps:\n                  - {}\n                BlkioDeviceWriteIOps:\n                  - {}\n                ContainerIDFile: \"\"\n                CpusetCpus: \"\"\n                CpusetMems: \"\"\n                CpuPercent: 80\n                CpuShares: 0\n                CpuPeriod: 100000\n                CpuRealtimePeriod: 1000000\n                CpuRealtimeRuntime: 10000\n                Devices: []\n                DeviceRequests:\n                  - Driver: \"nvidia\"\n                    Count: -1\n                    DeviceIDs\": [\"0\", \"1\", \"GPU-fef8089b-4820-abfc-e83e-94318197576e\"]\n                    Capabilities: [[\"gpu\", \"nvidia\", \"compute\"]]\n                    Options:\n                      property1: \"string\"\n                      property2: \"string\"\n                IpcMode: \"\"\n                Memory: 0\n                MemorySwap: 0\n                MemoryReservation: 0\n                OomKillDisable: false\n                OomScoreAdj: 500\n                NetworkMode: \"bridge\"\n                PidMode: \"\"\n                PortBindings: {}\n                Privileged: false\n                ReadonlyRootfs: false\n                PublishAllPorts: false\n                RestartPolicy:\n                  MaximumRetryCount: 2\n                  Name: \"on-failure\"\n                LogConfig:\n                  Type: \"json-file\"\n                Sysctls:\n                  net.ipv4.ip_forward: \"1\"\n                Ulimits:\n                  - {}\n                VolumeDriver: \"\"\n                ShmSize: 67108864\n              HostnamePath: \"/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/hostname\"\n              HostsPath: \"/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/hosts\"\n              LogPath: \"/var/lib/docker/containers/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b/1eb5fabf5a03807136561b3c00adcd2992b535d624d5e18b6cdc6a6844d9767b-json.log\"\n              Id: \"ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39\"\n              Image: \"04c5d3b7b0656168630d3ba35d8889bd0e9caafcaeb3004d2bfbc47e7c5d35d2\"\n              MountLabel: \"\"\n              Name: \"/boring_euclid\"\n              NetworkSettings:\n                Bridge: \"\"\n                SandboxID: \"\"\n                HairpinMode: false\n                LinkLocalIPv6Address: \"\"\n                LinkLocalIPv6PrefixLen: 0\n                SandboxKey: \"\"\n                EndpointID: \"\"\n                Gateway: \"\"\n                GlobalIPv6Address: \"\"\n                GlobalIPv6PrefixLen: 0\n                IPAddress: \"\"\n                IPPrefixLen: 0\n                IPv6Gateway: \"\"\n                MacAddress: \"\"\n                Networks:\n                  bridge:\n                    NetworkID: \"7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812\"\n                    EndpointID: \"7587b82f0dada3656fda26588aee72630c6fab1536d36e394b2bfbcf898c971d\"\n                    Gateway: \"172.17.0.1\"\n                    IPAddress: \"172.17.0.2\"\n                    IPPrefixLen: 16\n                    IPv6Gateway: \"\"\n                    GlobalIPv6Address: \"\"\n                    GlobalIPv6PrefixLen: 0\n                    MacAddress: \"02:42:ac:12:00:02\"\n              Path: \"/bin/sh\"\n              ProcessLabel: \"\"\n              ResolvConfPath: \"/var/lib/docker/containers/ba033ac4401106a3b513bc9d639eee123ad78ca3616b921167cd74b20e25ed39/resolv.conf\"\n              RestartCount: 1\n              State:\n                Error: \"\"\n                ExitCode: 9\n                FinishedAt: \"2015-01-06T15:47:32.080254511Z\"\n                Health:\n                  Status: \"healthy\"\n                  FailingStreak: 0\n                  Log:\n                    - Start: \"2019-12-22T10:59:05.6385933Z\"\n                      End: \"2019-12-22T10:59:05.8078452Z\"\n                      ExitCode: 0\n                      Output: \"\"\n                OOMKilled: false\n                Dead: false\n                Paused: false\n                Pid: 0\n                Restarting: false\n                Running: true\n                StartedAt: \"2015-01-06T15:47:32.072697474Z\"\n                Status: \"running\"\n              Mounts:\n                - Name: \"fac362...80535\"\n                  Source: \"/data\"\n                  Destination: \"/data\"\n                  Driver: \"local\"\n                  Mode: \"ro,Z\"\n                  RW: false\n                  Propagation: \"\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"size\"\n          in: \"query\"\n          type: \"boolean\"\n          default: false\n          description: \"Return the size of container as fields `SizeRw` and `SizeRootFs`\"\n      tags: [\"Container\"]\n  /containers/{id}/top:\n    get:\n      summary: \"List processes running inside a container\"\n      description: |\n        On Unix systems, this is done by running the `ps` command. This endpoint\n        is not supported on Windows.\n      operationId: \"ContainerTop\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"object\"\n            title: \"ContainerTopResponse\"\n            description: \"OK response to ContainerTop operation\"\n            properties:\n              Titles:\n                description: \"The ps column titles\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n              Processes:\n                description: |\n                  Each process running in the container, where each is process\n                  is an array of values corresponding to the titles.\n                type: \"array\"\n                items:\n                  type: \"array\"\n                  items:\n                    type: \"string\"\n          examples:\n            application/json:\n              Titles:\n                - \"UID\"\n                - \"PID\"\n                - \"PPID\"\n                - \"C\"\n                - \"STIME\"\n                - \"TTY\"\n                - \"TIME\"\n                - \"CMD\"\n              Processes:\n                -\n                  - \"root\"\n                  - \"13642\"\n                  - \"882\"\n                  - \"0\"\n                  - \"17:03\"\n                  - \"pts/0\"\n                  - \"00:00:00\"\n                  - \"/bin/bash\"\n                -\n                  - \"root\"\n                  - \"13735\"\n                  - \"13642\"\n                  - \"0\"\n                  - \"17:06\"\n                  - \"pts/0\"\n                  - \"00:00:00\"\n                  - \"sleep 10\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"ps_args\"\n          in: \"query\"\n          description: \"The arguments to pass to `ps`. For example, `aux`\"\n          type: \"string\"\n          default: \"-ef\"\n      tags: [\"Container\"]\n  /containers/{id}/logs:\n    get:\n      summary: \"Get container logs\"\n      description: |\n        Get `stdout` and `stderr` logs from a container.\n\n        Note: This endpoint works only for containers with the `json-file` or\n        `journald` logging driver.\n      produces:\n        - \"application/vnd.docker.raw-stream\"\n        - \"application/vnd.docker.multiplexed-stream\"\n      operationId: \"ContainerLogs\"\n      responses:\n        200:\n          description: |\n            logs returned as a stream in response body.\n            For the stream format, [see the documentation for the attach endpoint](#operation/ContainerAttach).\n            Note that unlike the attach endpoint, the logs endpoint does not\n            upgrade the connection and does not set Content-Type.\n          schema:\n            type: \"string\"\n            format: \"binary\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"follow\"\n          in: \"query\"\n          description: \"Keep connection after returning logs.\"\n          type: \"boolean\"\n          default: false\n        - name: \"stdout\"\n          in: \"query\"\n          description: \"Return logs from `stdout`\"\n          type: \"boolean\"\n          default: false\n        - name: \"stderr\"\n          in: \"query\"\n          description: \"Return logs from `stderr`\"\n          type: \"boolean\"\n          default: false\n        - name: \"since\"\n          in: \"query\"\n          description: \"Only return logs since this time, as a UNIX timestamp\"\n          type: \"integer\"\n          default: 0\n        - name: \"until\"\n          in: \"query\"\n          description: \"Only return logs before this time, as a UNIX timestamp\"\n          type: \"integer\"\n          default: 0\n        - name: \"timestamps\"\n          in: \"query\"\n          description: \"Add timestamps to every log line\"\n          type: \"boolean\"\n          default: false\n        - name: \"tail\"\n          in: \"query\"\n          description: |\n            Only return this number of log lines from the end of the logs.\n            Specify as an integer or `all` to output all log lines.\n          type: \"string\"\n          default: \"all\"\n      tags: [\"Container\"]\n  /containers/{id}/changes:\n    get:\n      summary: \"Get changes on a container’s filesystem\"\n      description: |\n        Returns which files in a container's filesystem have been added, deleted,\n        or modified. The `Kind` of modification can be one of:\n\n        - `0`: Modified (\"C\")\n        - `1`: Added (\"A\")\n        - `2`: Deleted (\"D\")\n      operationId: \"ContainerChanges\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"The list of changes\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/FilesystemChange\"\n          examples:\n            application/json:\n              - Path: \"/dev\"\n                Kind: 0\n              - Path: \"/dev/kmsg\"\n                Kind: 1\n              - Path: \"/test\"\n                Kind: 1\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n      tags: [\"Container\"]\n  /containers/{id}/export:\n    get:\n      summary: \"Export a container\"\n      description: \"Export the contents of a container as a tarball.\"\n      operationId: \"ContainerExport\"\n      produces:\n        - \"application/octet-stream\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n      tags: [\"Container\"]\n  /containers/{id}/stats:\n    get:\n      summary: \"Get container stats based on resource usage\"\n      description: |\n        This endpoint returns a live stream of a container’s resource usage\n        statistics.\n\n        The `precpu_stats` is the CPU statistic of the *previous* read, and is\n        used to calculate the CPU usage percentage. It is not an exact copy\n        of the `cpu_stats` field.\n\n        If either `precpu_stats.online_cpus` or `cpu_stats.online_cpus` is\n        nil then for compatibility with older daemons the length of the\n        corresponding `cpu_usage.percpu_usage` array should be used.\n\n        On a cgroup v2 host, the following fields are not set\n        * `blkio_stats`: all fields other than `io_service_bytes_recursive`\n        * `cpu_stats`: `cpu_usage.percpu_usage`\n        * `memory_stats`: `max_usage` and `failcnt`\n        Also, `memory_stats.stats` fields are incompatible with cgroup v1.\n\n        To calculate the values shown by the `stats` command of the docker cli tool\n        the following formulas can be used:\n        * used_memory = `memory_stats.usage - memory_stats.stats.cache`\n        * available_memory = `memory_stats.limit`\n        * Memory usage % = `(used_memory / available_memory) * 100.0`\n        * cpu_delta = `cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage`\n        * system_cpu_delta = `cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage`\n        * number_cpus = `lenght(cpu_stats.cpu_usage.percpu_usage)` or `cpu_stats.online_cpus`\n        * CPU usage % = `(cpu_delta / system_cpu_delta) * number_cpus * 100.0`\n      operationId: \"ContainerStats\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"object\"\n          examples:\n            application/json:\n              read: \"2015-01-08T22:57:31.547920715Z\"\n              pids_stats:\n                current: 3\n              networks:\n                eth0:\n                  rx_bytes: 5338\n                  rx_dropped: 0\n                  rx_errors: 0\n                  rx_packets: 36\n                  tx_bytes: 648\n                  tx_dropped: 0\n                  tx_errors: 0\n                  tx_packets: 8\n                eth5:\n                  rx_bytes: 4641\n                  rx_dropped: 0\n                  rx_errors: 0\n                  rx_packets: 26\n                  tx_bytes: 690\n                  tx_dropped: 0\n                  tx_errors: 0\n                  tx_packets: 9\n              memory_stats:\n                stats:\n                  total_pgmajfault: 0\n                  cache: 0\n                  mapped_file: 0\n                  total_inactive_file: 0\n                  pgpgout: 414\n                  rss: 6537216\n                  total_mapped_file: 0\n                  writeback: 0\n                  unevictable: 0\n                  pgpgin: 477\n                  total_unevictable: 0\n                  pgmajfault: 0\n                  total_rss: 6537216\n                  total_rss_huge: 6291456\n                  total_writeback: 0\n                  total_inactive_anon: 0\n                  rss_huge: 6291456\n                  hierarchical_memory_limit: 67108864\n                  total_pgfault: 964\n                  total_active_file: 0\n                  active_anon: 6537216\n                  total_active_anon: 6537216\n                  total_pgpgout: 414\n                  total_cache: 0\n                  inactive_anon: 0\n                  active_file: 0\n                  pgfault: 964\n                  inactive_file: 0\n                  total_pgpgin: 477\n                max_usage: 6651904\n                usage: 6537216\n                failcnt: 0\n                limit: 67108864\n              blkio_stats: {}\n              cpu_stats:\n                cpu_usage:\n                  percpu_usage:\n                    - 8646879\n                    - 24472255\n                    - 36438778\n                    - 30657443\n                  usage_in_usermode: 50000000\n                  total_usage: 100215355\n                  usage_in_kernelmode: 30000000\n                system_cpu_usage: 739306590000000\n                online_cpus: 4\n                throttling_data:\n                  periods: 0\n                  throttled_periods: 0\n                  throttled_time: 0\n              precpu_stats:\n                cpu_usage:\n                  percpu_usage:\n                    - 8646879\n                    - 24350896\n                    - 36438778\n                    - 30657443\n                  usage_in_usermode: 50000000\n                  total_usage: 100093996\n                  usage_in_kernelmode: 30000000\n                system_cpu_usage: 9492140000000\n                online_cpus: 4\n                throttling_data:\n                  periods: 0\n                  throttled_periods: 0\n                  throttled_time: 0\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"stream\"\n          in: \"query\"\n          description: |\n            Stream the output. If false, the stats will be output once and then\n            it will disconnect.\n          type: \"boolean\"\n          default: true\n        - name: \"one-shot\"\n          in: \"query\"\n          description: |\n            Only get a single stat instead of waiting for 2 cycles. Must be used\n            with `stream=false`.\n          type: \"boolean\"\n          default: false\n      tags: [\"Container\"]\n  /containers/{id}/resize:\n    post:\n      summary: \"Resize a container TTY\"\n      description: \"Resize the TTY for a container.\"\n      operationId: \"ContainerResize\"\n      consumes:\n        - \"application/octet-stream\"\n      produces:\n        - \"text/plain\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"cannot resize container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"h\"\n          in: \"query\"\n          description: \"Height of the TTY session in characters\"\n          type: \"integer\"\n        - name: \"w\"\n          in: \"query\"\n          description: \"Width of the TTY session in characters\"\n          type: \"integer\"\n      tags: [\"Container\"]\n  /containers/{id}/start:\n    post:\n      summary: \"Start a container\"\n      operationId: \"ContainerStart\"\n      responses:\n        204:\n          description: \"no error\"\n        304:\n          description: \"container already started\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"detachKeys\"\n          in: \"query\"\n          description: |\n            Override the key sequence for detaching a container. Format is a\n            single character `[a-Z]` or `ctrl-<value>` where `<value>` is one\n            of: `a-z`, `@`, `^`, `[`, `,` or `_`.\n          type: \"string\"\n      tags: [\"Container\"]\n  /containers/{id}/stop:\n    post:\n      summary: \"Stop a container\"\n      operationId: \"ContainerStop\"\n      responses:\n        204:\n          description: \"no error\"\n        304:\n          description: \"container already stopped\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"signal\"\n          in: \"query\"\n          description: |\n            Signal to send to the container as an integer or string (e.g. `SIGINT`).\n          type: \"string\"\n        - name: \"t\"\n          in: \"query\"\n          description: \"Number of seconds to wait before killing the container\"\n          type: \"integer\"\n      tags: [\"Container\"]\n  /containers/{id}/restart:\n    post:\n      summary: \"Restart a container\"\n      operationId: \"ContainerRestart\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"signal\"\n          in: \"query\"\n          description: |\n            Signal to send to the container as an integer or string (e.g. `SIGINT`).\n          type: \"string\"\n        - name: \"t\"\n          in: \"query\"\n          description: \"Number of seconds to wait before killing the container\"\n          type: \"integer\"\n      tags: [\"Container\"]\n  /containers/{id}/kill:\n    post:\n      summary: \"Kill a container\"\n      description: |\n        Send a POSIX signal to a container, defaulting to killing to the\n        container.\n      operationId: \"ContainerKill\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        409:\n          description: \"container is not running\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"Container d37cde0fe4ad63c3a7252023b2f9800282894247d145cb5933ddf6e52cc03a28 is not running\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"signal\"\n          in: \"query\"\n          description: |\n            Signal to send to the container as an integer or string (e.g. `SIGINT`).\n          type: \"string\"\n          default: \"SIGKILL\"\n      tags: [\"Container\"]\n  /containers/{id}/update:\n    post:\n      summary: \"Update a container\"\n      description: |\n        Change various configuration options of a container without having to\n        recreate it.\n      operationId: \"ContainerUpdate\"\n      consumes: [\"application/json\"]\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"The container has been updated.\"\n          schema:\n            type: \"object\"\n            title: \"ContainerUpdateResponse\"\n            description: \"OK response to ContainerUpdate operation\"\n            properties:\n              Warnings:\n                type: \"array\"\n                items:\n                  type: \"string\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"update\"\n          in: \"body\"\n          required: true\n          schema:\n            allOf:\n              - $ref: \"#/definitions/Resources\"\n              - type: \"object\"\n                properties:\n                  RestartPolicy:\n                    $ref: \"#/definitions/RestartPolicy\"\n            example:\n              BlkioWeight: 300\n              CpuShares: 512\n              CpuPeriod: 100000\n              CpuQuota: 50000\n              CpuRealtimePeriod: 1000000\n              CpuRealtimeRuntime: 10000\n              CpusetCpus: \"0,1\"\n              CpusetMems: \"0\"\n              Memory: 314572800\n              MemorySwap: 514288000\n              MemoryReservation: 209715200\n              RestartPolicy:\n                MaximumRetryCount: 4\n                Name: \"on-failure\"\n      tags: [\"Container\"]\n  /containers/{id}/rename:\n    post:\n      summary: \"Rename a container\"\n      operationId: \"ContainerRename\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        409:\n          description: \"name already in use\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"name\"\n          in: \"query\"\n          required: true\n          description: \"New name for the container\"\n          type: \"string\"\n      tags: [\"Container\"]\n  /containers/{id}/pause:\n    post:\n      summary: \"Pause a container\"\n      description: |\n        Use the freezer cgroup to suspend all processes in a container.\n\n        Traditionally, when suspending a process the `SIGSTOP` signal is used,\n        which is observable by the process being suspended. With the freezer\n        cgroup the process is unaware, and unable to capture, that it is being\n        suspended, and subsequently resumed.\n      operationId: \"ContainerPause\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n      tags: [\"Container\"]\n  /containers/{id}/unpause:\n    post:\n      summary: \"Unpause a container\"\n      description: \"Resume a container which has been paused.\"\n      operationId: \"ContainerUnpause\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n      tags: [\"Container\"]\n  /containers/{id}/attach:\n    post:\n      summary: \"Attach to a container\"\n      description: |\n        Attach to a container to read its output or send it input. You can attach\n        to the same container multiple times and you can reattach to containers\n        that have been detached.\n\n        Either the `stream` or `logs` parameter must be `true` for this endpoint\n        to do anything.\n\n        See the [documentation for the `docker attach` command](https://docs.docker.com/engine/reference/commandline/attach/)\n        for more details.\n\n        ### Hijacking\n\n        This endpoint hijacks the HTTP connection to transport `stdin`, `stdout`,\n        and `stderr` on the same socket.\n\n        This is the response from the daemon for an attach request:\n\n        ```\n        HTTP/1.1 200 OK\n        Content-Type: application/vnd.docker.raw-stream\n\n        [STREAM]\n        ```\n\n        After the headers and two new lines, the TCP connection can now be used\n        for raw, bidirectional communication between the client and server.\n\n        To hint potential proxies about connection hijacking, the Docker client\n        can also optionally send connection upgrade headers.\n\n        For example, the client sends this request to upgrade the connection:\n\n        ```\n        POST /containers/16253994b7c4/attach?stream=1&stdout=1 HTTP/1.1\n        Upgrade: tcp\n        Connection: Upgrade\n        ```\n\n        The Docker daemon will respond with a `101 UPGRADED` response, and will\n        similarly follow with the raw stream:\n\n        ```\n        HTTP/1.1 101 UPGRADED\n        Content-Type: application/vnd.docker.raw-stream\n        Connection: Upgrade\n        Upgrade: tcp\n\n        [STREAM]\n        ```\n\n        ### Stream format\n\n        When the TTY setting is disabled in [`POST /containers/create`](#operation/ContainerCreate),\n        the HTTP Content-Type header is set to application/vnd.docker.multiplexed-stream\n        and the stream over the hijacked connected is multiplexed to separate out\n        `stdout` and `stderr`. The stream consists of a series of frames, each\n        containing a header and a payload.\n\n        The header contains the information which the stream writes (`stdout` or\n        `stderr`). It also contains the size of the associated frame encoded in\n        the last four bytes (`uint32`).\n\n        It is encoded on the first eight bytes like this:\n\n        ```go\n        header := [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}\n        ```\n\n        `STREAM_TYPE` can be:\n\n        - 0: `stdin` (is written on `stdout`)\n        - 1: `stdout`\n        - 2: `stderr`\n\n        `SIZE1, SIZE2, SIZE3, SIZE4` are the four bytes of the `uint32` size\n        encoded as big endian.\n\n        Following the header is the payload, which is the specified number of\n        bytes of `STREAM_TYPE`.\n\n        The simplest way to implement this protocol is the following:\n\n        1. Read 8 bytes.\n        2. Choose `stdout` or `stderr` depending on the first byte.\n        3. Extract the frame size from the last four bytes.\n        4. Read the extracted size and output it on the correct output.\n        5. Goto 1.\n\n        ### Stream format when using a TTY\n\n        When the TTY setting is enabled in [`POST /containers/create`](#operation/ContainerCreate),\n        the stream is not multiplexed. The data exchanged over the hijacked\n        connection is simply the raw data from the process PTY and client's\n        `stdin`.\n\n      operationId: \"ContainerAttach\"\n      produces:\n        - \"application/vnd.docker.raw-stream\"\n        - \"application/vnd.docker.multiplexed-stream\"\n      responses:\n        101:\n          description: \"no error, hints proxy about hijacking\"\n        200:\n          description: \"no error, no upgrade header found\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"detachKeys\"\n          in: \"query\"\n          description: |\n            Override the key sequence for detaching a container.Format is a single\n            character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`,\n            `@`, `^`, `[`, `,` or `_`.\n          type: \"string\"\n        - name: \"logs\"\n          in: \"query\"\n          description: |\n            Replay previous logs from the container.\n\n            This is useful for attaching to a container that has started and you\n            want to output everything since the container started.\n\n            If `stream` is also enabled, once all the previous output has been\n            returned, it will seamlessly transition into streaming current\n            output.\n          type: \"boolean\"\n          default: false\n        - name: \"stream\"\n          in: \"query\"\n          description: |\n            Stream attached streams from the time the request was made onwards.\n          type: \"boolean\"\n          default: false\n        - name: \"stdin\"\n          in: \"query\"\n          description: \"Attach to `stdin`\"\n          type: \"boolean\"\n          default: false\n        - name: \"stdout\"\n          in: \"query\"\n          description: \"Attach to `stdout`\"\n          type: \"boolean\"\n          default: false\n        - name: \"stderr\"\n          in: \"query\"\n          description: \"Attach to `stderr`\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Container\"]\n  /containers/{id}/attach/ws:\n    get:\n      summary: \"Attach to a container via a websocket\"\n      operationId: \"ContainerAttachWebsocket\"\n      responses:\n        101:\n          description: \"no error, hints proxy about hijacking\"\n        200:\n          description: \"no error, no upgrade header found\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"detachKeys\"\n          in: \"query\"\n          description: |\n            Override the key sequence for detaching a container.Format is a single\n            character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`,\n            `@`, `^`, `[`, `,`, or `_`.\n          type: \"string\"\n        - name: \"logs\"\n          in: \"query\"\n          description: \"Return logs\"\n          type: \"boolean\"\n          default: false\n        - name: \"stream\"\n          in: \"query\"\n          description: \"Return stream\"\n          type: \"boolean\"\n          default: false\n        - name: \"stdin\"\n          in: \"query\"\n          description: \"Attach to `stdin`\"\n          type: \"boolean\"\n          default: false\n        - name: \"stdout\"\n          in: \"query\"\n          description: \"Attach to `stdout`\"\n          type: \"boolean\"\n          default: false\n        - name: \"stderr\"\n          in: \"query\"\n          description: \"Attach to `stderr`\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Container\"]\n  /containers/{id}/wait:\n    post:\n      summary: \"Wait for a container\"\n      description: \"Block until a container stops, then returns the exit code.\"\n      operationId: \"ContainerWait\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"The container has exit.\"\n          schema:\n            $ref: \"#/definitions/ContainerWaitResponse\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"condition\"\n          in: \"query\"\n          description: |\n            Wait until a container state reaches the given condition.\n\n            Defaults to `not-running` if omitted or empty.\n          type: \"string\"\n          enum:\n            - \"not-running\"\n            - \"next-exit\"\n            - \"removed\"\n          default: \"not-running\"\n      tags: [\"Container\"]\n  /containers/{id}:\n    delete:\n      summary: \"Remove a container\"\n      operationId: \"ContainerDelete\"\n      responses:\n        204:\n          description: \"no error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        409:\n          description: \"conflict\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: |\n                You cannot remove a running container: c2ada9df5af8. Stop the\n                container before attempting removal or force remove\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"v\"\n          in: \"query\"\n          description: \"Remove anonymous volumes associated with the container.\"\n          type: \"boolean\"\n          default: false\n        - name: \"force\"\n          in: \"query\"\n          description: \"If the container is running, kill it before removing it.\"\n          type: \"boolean\"\n          default: false\n        - name: \"link\"\n          in: \"query\"\n          description: \"Remove the specified link associated with the container.\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Container\"]\n  /containers/{id}/archive:\n    head:\n      summary: \"Get information about files in a container\"\n      description: |\n        A response header `X-Docker-Container-Path-Stat` is returned, containing\n        a base64 - encoded JSON object with some filesystem header information\n        about the path.\n      operationId: \"ContainerArchiveInfo\"\n      responses:\n        200:\n          description: \"no error\"\n          headers:\n            X-Docker-Container-Path-Stat:\n              type: \"string\"\n              description: |\n                A base64 - encoded JSON object with some filesystem header\n                information about the path\n        400:\n          description: \"Bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"Container or path does not exist\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"path\"\n          in: \"query\"\n          required: true\n          description: \"Resource in the container’s filesystem to archive.\"\n          type: \"string\"\n      tags: [\"Container\"]\n    get:\n      summary: \"Get an archive of a filesystem resource in a container\"\n      description: \"Get a tar archive of a resource in the filesystem of container id.\"\n      operationId: \"ContainerArchive\"\n      produces: [\"application/x-tar\"]\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"Bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"Container or path does not exist\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"path\"\n          in: \"query\"\n          required: true\n          description: \"Resource in the container’s filesystem to archive.\"\n          type: \"string\"\n      tags: [\"Container\"]\n    put:\n      summary: \"Extract an archive of files or folders to a directory in a container\"\n      description: |\n        Upload a tar archive to be extracted to a path in the filesystem of container id.\n        `path` parameter is asserted to be a directory. If it exists as a file, 400 error\n        will be returned with message \"not a directory\".\n      operationId: \"PutContainerArchive\"\n      consumes: [\"application/x-tar\", \"application/octet-stream\"]\n      responses:\n        200:\n          description: \"The content was extracted successfully\"\n        400:\n          description: \"Bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"not a directory\"\n        403:\n          description: \"Permission denied, the volume or container rootfs is marked as read-only.\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"No such container or path does not exist inside the container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the container\"\n          type: \"string\"\n        - name: \"path\"\n          in: \"query\"\n          required: true\n          description: \"Path to a directory in the container to extract the archive’s contents into. \"\n          type: \"string\"\n        - name: \"noOverwriteDirNonDir\"\n          in: \"query\"\n          description: |\n            If `1`, `true`, or `True` then it will be an error if unpacking the\n            given content would cause an existing directory to be replaced with\n            a non-directory and vice versa.\n          type: \"string\"\n        - name: \"copyUIDGID\"\n          in: \"query\"\n          description: |\n            If `1`, `true`, then it will copy UID/GID maps to the dest file or\n            dir\n          type: \"string\"\n        - name: \"inputStream\"\n          in: \"body\"\n          required: true\n          description: |\n            The input stream must be a tar archive compressed with one of the\n            following algorithms: `identity` (no compression), `gzip`, `bzip2`,\n            or `xz`.\n          schema:\n            type: \"string\"\n            format: \"binary\"\n      tags: [\"Container\"]\n  /containers/prune:\n    post:\n      summary: \"Delete stopped containers\"\n      produces:\n        - \"application/json\"\n      operationId: \"ContainerPrune\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            Filters to process on the prune list, encoded as JSON (a `map[string][]string`).\n\n            Available filters:\n            - `until=<timestamp>` Prune containers created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time.\n            - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune containers with (or without, in case `label!=...` is used) the specified labels.\n          type: \"string\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"object\"\n            title: \"ContainerPruneResponse\"\n            properties:\n              ContainersDeleted:\n                description: \"Container IDs that were deleted\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n              SpaceReclaimed:\n                description: \"Disk space reclaimed in bytes\"\n                type: \"integer\"\n                format: \"int64\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Container\"]\n  /images/json:\n    get:\n      summary: \"List Images\"\n      description: \"Returns a list of images on the server. Note that it uses a different, smaller representation of an image than inspecting a single image.\"\n      operationId: \"ImageList\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"Summary image data for the images matching the query\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/ImageSummary\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"all\"\n          in: \"query\"\n          description: \"Show all images. Only images from a final layer (no children) are shown by default.\"\n          type: \"boolean\"\n          default: false\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to\n            process on the images list.\n\n            Available filters:\n\n            - `before`=(`<image-name>[:<tag>]`,  `<image id>` or `<image@digest>`)\n            - `dangling=true`\n            - `label=key` or `label=\"key=value\"` of an image label\n            - `reference`=(`<image-name>[:<tag>]`)\n            - `since`=(`<image-name>[:<tag>]`,  `<image id>` or `<image@digest>`)\n            - `until=<timestamp>`\n          type: \"string\"\n        - name: \"shared-size\"\n          in: \"query\"\n          description: \"Compute and show shared size as a `SharedSize` field on each image.\"\n          type: \"boolean\"\n          default: false\n        - name: \"digests\"\n          in: \"query\"\n          description: \"Show digest information as a `RepoDigests` field on each image.\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Image\"]\n  /build:\n    post:\n      summary: \"Build an image\"\n      description: |\n        Build an image from a tar archive with a `Dockerfile` in it.\n\n        The `Dockerfile` specifies how the image is built from the tar archive. It is typically in the archive's root, but can be at a different path or have a different name by specifying the `dockerfile` parameter. [See the `Dockerfile` reference for more information](https://docs.docker.com/engine/reference/builder/).\n\n        The Docker daemon performs a preliminary validation of the `Dockerfile` before starting the build, and returns an error if the syntax is incorrect. After that, each instruction is run one-by-one until the ID of the new image is output.\n\n        The build is canceled if the client drops the connection by quitting or being killed.\n      operationId: \"ImageBuild\"\n      consumes:\n        - \"application/octet-stream\"\n      produces:\n        - \"application/json\"\n      parameters:\n        - name: \"inputStream\"\n          in: \"body\"\n          description: \"A tar archive compressed with one of the following algorithms: identity (no compression), gzip, bzip2, xz.\"\n          schema:\n            type: \"string\"\n            format: \"binary\"\n        - name: \"dockerfile\"\n          in: \"query\"\n          description: \"Path within the build context to the `Dockerfile`. This is ignored if `remote` is specified and points to an external `Dockerfile`.\"\n          type: \"string\"\n          default: \"Dockerfile\"\n        - name: \"t\"\n          in: \"query\"\n          description: \"A name and optional tag to apply to the image in the `name:tag` format. If you omit the tag the default `latest` value is assumed. You can provide several `t` parameters.\"\n          type: \"string\"\n        - name: \"extrahosts\"\n          in: \"query\"\n          description: \"Extra hosts to add to /etc/hosts\"\n          type: \"string\"\n        - name: \"remote\"\n          in: \"query\"\n          description: \"A Git repository URI or HTTP/HTTPS context URI. If the URI points to a single text file, the file’s contents are placed into a file called `Dockerfile` and the image is built from that file. If the URI points to a tarball, the file is downloaded by the daemon and the contents therein used as the context for the build. If the URI points to a tarball and the `dockerfile` parameter is also specified, there must be a file with the corresponding path inside the tarball.\"\n          type: \"string\"\n        - name: \"q\"\n          in: \"query\"\n          description: \"Suppress verbose build output.\"\n          type: \"boolean\"\n          default: false\n        - name: \"nocache\"\n          in: \"query\"\n          description: \"Do not use the cache when building the image.\"\n          type: \"boolean\"\n          default: false\n        - name: \"cachefrom\"\n          in: \"query\"\n          description: \"JSON array of images used for build cache resolution.\"\n          type: \"string\"\n        - name: \"pull\"\n          in: \"query\"\n          description: \"Attempt to pull the image even if an older image exists locally.\"\n          type: \"string\"\n        - name: \"rm\"\n          in: \"query\"\n          description: \"Remove intermediate containers after a successful build.\"\n          type: \"boolean\"\n          default: true\n        - name: \"forcerm\"\n          in: \"query\"\n          description: \"Always remove intermediate containers, even upon failure.\"\n          type: \"boolean\"\n          default: false\n        - name: \"memory\"\n          in: \"query\"\n          description: \"Set memory limit for build.\"\n          type: \"integer\"\n        - name: \"memswap\"\n          in: \"query\"\n          description: \"Total memory (memory + swap). Set as `-1` to disable swap.\"\n          type: \"integer\"\n        - name: \"cpushares\"\n          in: \"query\"\n          description: \"CPU shares (relative weight).\"\n          type: \"integer\"\n        - name: \"cpusetcpus\"\n          in: \"query\"\n          description: \"CPUs in which to allow execution (e.g., `0-3`, `0,1`).\"\n          type: \"string\"\n        - name: \"cpuperiod\"\n          in: \"query\"\n          description: \"The length of a CPU period in microseconds.\"\n          type: \"integer\"\n        - name: \"cpuquota\"\n          in: \"query\"\n          description: \"Microseconds of CPU time that the container can get in a CPU period.\"\n          type: \"integer\"\n        - name: \"buildargs\"\n          in: \"query\"\n          description: >\n            JSON map of string pairs for build-time variables. Users pass these values at build-time. Docker\n            uses the buildargs as the environment context for commands run via the `Dockerfile` RUN\n            instruction, or for variable expansion in other `Dockerfile` instructions. This is not meant for\n            passing secret values.\n\n\n            For example, the build arg `FOO=bar` would become `{\"FOO\":\"bar\"}` in JSON. This would result in the\n            query parameter `buildargs={\"FOO\":\"bar\"}`. Note that `{\"FOO\":\"bar\"}` should be URI component encoded.\n\n\n            [Read more about the buildargs instruction.](https://docs.docker.com/engine/reference/builder/#arg)\n          type: \"string\"\n        - name: \"shmsize\"\n          in: \"query\"\n          description: \"Size of `/dev/shm` in bytes. The size must be greater than 0. If omitted the system uses 64MB.\"\n          type: \"integer\"\n        - name: \"squash\"\n          in: \"query\"\n          description: \"Squash the resulting images layers into a single layer. *(Experimental release only.)*\"\n          type: \"boolean\"\n        - name: \"labels\"\n          in: \"query\"\n          description: \"Arbitrary key/value labels to set on the image, as a JSON map of string pairs.\"\n          type: \"string\"\n        - name: \"networkmode\"\n          in: \"query\"\n          description: |\n            Sets the networking mode for the run commands during build. Supported\n            standard values are: `bridge`, `host`, `none`, and `container:<name|id>`.\n            Any other value is taken as a custom network's name or ID to which this\n            container should connect to.\n          type: \"string\"\n        - name: \"Content-type\"\n          in: \"header\"\n          type: \"string\"\n          enum:\n            - \"application/x-tar\"\n          default: \"application/x-tar\"\n        - name: \"X-Registry-Config\"\n          in: \"header\"\n          description: |\n            This is a base64-encoded JSON object with auth configurations for multiple registries that a build may refer to.\n\n            The key is a registry URL, and the value is an auth configuration object, [as described in the authentication section](#section/Authentication). For example:\n\n            ```\n            {\n              \"docker.example.com\": {\n                \"username\": \"janedoe\",\n                \"password\": \"hunter2\"\n              },\n              \"https://index.docker.io/v1/\": {\n                \"username\": \"mobydock\",\n                \"password\": \"conta1n3rize14\"\n              }\n            }\n            ```\n\n            Only the registry domain name (and port if not the default 443) are required. However, for legacy reasons, the Docker Hub registry must be specified with both a `https://` prefix and a `/v1/` suffix even though Docker will prefer to use the v2 registry API.\n          type: \"string\"\n        - name: \"platform\"\n          in: \"query\"\n          description: \"Platform in the format os[/arch[/variant]]\"\n          type: \"string\"\n          default: \"\"\n        - name: \"target\"\n          in: \"query\"\n          description: \"Target build stage\"\n          type: \"string\"\n          default: \"\"\n        - name: \"outputs\"\n          in: \"query\"\n          description: \"BuildKit output configuration\"\n          type: \"string\"\n          default: \"\"\n        - name: \"version\"\n          in: \"query\"\n          type: \"string\"\n          default: \"1\"\n          enum: [\"1\", \"2\"]\n          description: |\n            Version of the builder backend to use.\n\n            - `1` is the first generation classic (deprecated) builder in the Docker daemon (default)\n            - `2` is [BuildKit](https://github.com/moby/buildkit)\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"Bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Image\"]\n  /build/prune:\n    post:\n      summary: \"Delete builder cache\"\n      produces:\n        - \"application/json\"\n      operationId: \"BuildPrune\"\n      parameters:\n        - name: \"keep-storage\"\n          in: \"query\"\n          description: \"Amount of disk space in bytes to keep for cache\"\n          type: \"integer\"\n          format: \"int64\"\n        - name: \"all\"\n          in: \"query\"\n          type: \"boolean\"\n          description: \"Remove all types of build cache\"\n        - name: \"filters\"\n          in: \"query\"\n          type: \"string\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to\n            process on the list of build cache objects.\n\n            Available filters:\n\n            - `until=<timestamp>` remove cache older than `<timestamp>`. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon's local time.\n            - `id=<id>`\n            - `parent=<id>`\n            - `type=<string>`\n            - `description=<string>`\n            - `inuse`\n            - `shared`\n            - `private`\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"object\"\n            title: \"BuildPruneResponse\"\n            properties:\n              CachesDeleted:\n                type: \"array\"\n                items:\n                  description: \"ID of build cache object\"\n                  type: \"string\"\n              SpaceReclaimed:\n                description: \"Disk space reclaimed in bytes\"\n                type: \"integer\"\n                format: \"int64\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Image\"]\n  /images/create:\n    post:\n      summary: \"Create an image\"\n      description: \"Pull or import an image.\"\n      operationId: \"ImageCreate\"\n      consumes:\n        - \"text/plain\"\n        - \"application/octet-stream\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"repository does not exist or no read access\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"fromImage\"\n          in: \"query\"\n          description: \"Name of the image to pull. The name may include a tag or digest. This parameter may only be used when pulling an image. The pull is cancelled if the HTTP connection is closed.\"\n          type: \"string\"\n        - name: \"fromSrc\"\n          in: \"query\"\n          description: \"Source to import. The value may be a URL from which the image can be retrieved or `-` to read the image from the request body. This parameter may only be used when importing an image.\"\n          type: \"string\"\n        - name: \"repo\"\n          in: \"query\"\n          description: \"Repository name given to an image when it is imported. The repo may include a tag. This parameter may only be used when importing an image.\"\n          type: \"string\"\n        - name: \"tag\"\n          in: \"query\"\n          description: \"Tag or digest. If empty when pulling an image, this causes all tags for the given image to be pulled.\"\n          type: \"string\"\n        - name: \"message\"\n          in: \"query\"\n          description: \"Set commit message for imported image.\"\n          type: \"string\"\n        - name: \"inputImage\"\n          in: \"body\"\n          description: \"Image content if the value `-` has been specified in fromSrc query parameter\"\n          schema:\n            type: \"string\"\n          required: false\n        - name: \"X-Registry-Auth\"\n          in: \"header\"\n          description: |\n            A base64url-encoded auth configuration.\n\n            Refer to the [authentication section](#section/Authentication) for\n            details.\n          type: \"string\"\n        - name: \"changes\"\n          in: \"query\"\n          description: |\n            Apply `Dockerfile` instructions to the image that is created,\n            for example: `changes=ENV DEBUG=true`.\n            Note that `ENV DEBUG=true` should be URI component encoded.\n\n            Supported `Dockerfile` instructions:\n            `CMD`|`ENTRYPOINT`|`ENV`|`EXPOSE`|`ONBUILD`|`USER`|`VOLUME`|`WORKDIR`\n          type: \"array\"\n          items:\n            type: \"string\"\n        - name: \"platform\"\n          in: \"query\"\n          description: |\n            Platform in the format os[/arch[/variant]].\n\n            When used in combination with the `fromImage` option, the daemon checks\n            if the given image is present in the local image cache with the given\n            OS and Architecture, and otherwise attempts to pull the image. If the\n            option is not set, the host's native OS and Architecture are used.\n            If the given image does not exist in the local image cache, the daemon\n            attempts to pull the image with the host's native OS and Architecture.\n            If the given image does exists in the local image cache, but its OS or\n            architecture does not match, a warning is produced.\n\n            When used with the `fromSrc` option to import an image from an archive,\n            this option sets the platform information for the imported image. If\n            the option is not set, the host's native OS and Architecture are used\n            for the imported image.\n          type: \"string\"\n          default: \"\"\n      tags: [\"Image\"]\n  /images/{name}/json:\n    get:\n      summary: \"Inspect an image\"\n      description: \"Return low-level information about an image.\"\n      operationId: \"ImageInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            $ref: \"#/definitions/ImageInspect\"\n        404:\n          description: \"No such image\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such image: someimage (tag: latest)\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"Image name or id\"\n          type: \"string\"\n          required: true\n      tags: [\"Image\"]\n  /images/{name}/history:\n    get:\n      summary: \"Get the history of an image\"\n      description: \"Return parent layers of an image.\"\n      operationId: \"ImageHistory\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"List of image layers\"\n          schema:\n            type: \"array\"\n            items:\n              type: \"object\"\n              x-go-name: HistoryResponseItem\n              title: \"HistoryResponseItem\"\n              description: \"individual image layer information in response to ImageHistory operation\"\n              required: [Id, Created, CreatedBy, Tags, Size, Comment]\n              properties:\n                Id:\n                  type: \"string\"\n                  x-nullable: false\n                Created:\n                  type: \"integer\"\n                  format: \"int64\"\n                  x-nullable: false\n                CreatedBy:\n                  type: \"string\"\n                  x-nullable: false\n                Tags:\n                  type: \"array\"\n                  items:\n                    type: \"string\"\n                Size:\n                  type: \"integer\"\n                  format: \"int64\"\n                  x-nullable: false\n                Comment:\n                  type: \"string\"\n                  x-nullable: false\n          examples:\n            application/json:\n              - Id: \"3db9c44f45209632d6050b35958829c3a2aa256d81b9a7be45b362ff85c54710\"\n                Created: 1398108230\n                CreatedBy: \"/bin/sh -c #(nop) ADD file:eb15dbd63394e063b805a3c32ca7bf0266ef64676d5a6fab4801f2e81e2a5148 in /\"\n                Tags:\n                  - \"ubuntu:lucid\"\n                  - \"ubuntu:10.04\"\n                Size: 182964289\n                Comment: \"\"\n              - Id: \"6cfa4d1f33fb861d4d114f43b25abd0ac737509268065cdfd69d544a59c85ab8\"\n                Created: 1398108222\n                CreatedBy: \"/bin/sh -c #(nop) MAINTAINER Tianon Gravi <admwiggin@gmail.com> - mkimage-debootstrap.sh -i iproute,iputils-ping,ubuntu-minimal -t lucid.tar.xz lucid http://archive.ubuntu.com/ubuntu/\"\n                Tags: []\n                Size: 0\n                Comment: \"\"\n              - Id: \"511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158\"\n                Created: 1371157430\n                CreatedBy: \"\"\n                Tags:\n                  - \"scratch12:latest\"\n                  - \"scratch:latest\"\n                Size: 0\n                Comment: \"Imported from -\"\n        404:\n          description: \"No such image\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"Image name or ID\"\n          type: \"string\"\n          required: true\n      tags: [\"Image\"]\n  /images/{name}/push:\n    post:\n      summary: \"Push an image\"\n      description: |\n        Push an image to a registry.\n\n        If you wish to push an image on to a private registry, that image must\n        already have a tag which references the registry. For example,\n        `registry.example.com/myimage:latest`.\n\n        The push is cancelled if the HTTP connection is closed.\n      operationId: \"ImagePush\"\n      consumes:\n        - \"application/octet-stream\"\n      responses:\n        200:\n          description: \"No error\"\n        404:\n          description: \"No such image\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"Image name or ID.\"\n          type: \"string\"\n          required: true\n        - name: \"tag\"\n          in: \"query\"\n          description: \"The tag to associate with the image on the registry.\"\n          type: \"string\"\n        - name: \"X-Registry-Auth\"\n          in: \"header\"\n          description: |\n            A base64url-encoded auth configuration.\n\n            Refer to the [authentication section](#section/Authentication) for\n            details.\n          type: \"string\"\n          required: true\n      tags: [\"Image\"]\n  /images/{name}/tag:\n    post:\n      summary: \"Tag an image\"\n      description: \"Tag an image so that it becomes part of a repository.\"\n      operationId: \"ImageTag\"\n      responses:\n        201:\n          description: \"No error\"\n        400:\n          description: \"Bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"No such image\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        409:\n          description: \"Conflict\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"Image name or ID to tag.\"\n          type: \"string\"\n          required: true\n        - name: \"repo\"\n          in: \"query\"\n          description: \"The repository to tag in. For example, `someuser/someimage`.\"\n          type: \"string\"\n        - name: \"tag\"\n          in: \"query\"\n          description: \"The name of the new tag.\"\n          type: \"string\"\n      tags: [\"Image\"]\n  /images/{name}:\n    delete:\n      summary: \"Remove an image\"\n      description: |\n        Remove an image, along with any untagged parent images that were\n        referenced by that image.\n\n        Images can't be removed if they have descendant images, are being\n        used by a running container or are being used by a build.\n      operationId: \"ImageDelete\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"The image was deleted successfully\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/ImageDeleteResponseItem\"\n          examples:\n            application/json:\n              - Untagged: \"3e2f21a89f\"\n              - Deleted: \"3e2f21a89f\"\n              - Deleted: \"53b4f83ac9\"\n        404:\n          description: \"No such image\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        409:\n          description: \"Conflict\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"Image name or ID\"\n          type: \"string\"\n          required: true\n        - name: \"force\"\n          in: \"query\"\n          description: \"Remove the image even if it is being used by stopped containers or has other tags\"\n          type: \"boolean\"\n          default: false\n        - name: \"noprune\"\n          in: \"query\"\n          description: \"Do not delete untagged parent images\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Image\"]\n  /images/search:\n    get:\n      summary: \"Search images\"\n      description: \"Search for an image on Docker Hub.\"\n      operationId: \"ImageSearch\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"array\"\n            items:\n              type: \"object\"\n              title: \"ImageSearchResponseItem\"\n              properties:\n                description:\n                  type: \"string\"\n                is_official:\n                  type: \"boolean\"\n                is_automated:\n                  description: |\n                    Whether this repository has automated builds enabled.\n\n                    <p><br /></p>\n\n                    > **Deprecated**: This field is deprecated and will always\n                    > be \"false\" in future.\n                  type: \"boolean\"\n                  example: false\n                name:\n                  type: \"string\"\n                star_count:\n                  type: \"integer\"\n          examples:\n            application/json:\n              - description: \"A minimal Docker image based on Alpine Linux with a complete package index and only 5 MB in size!\"\n                is_official: true\n                is_automated: false\n                name: \"alpine\"\n                star_count: 10093\n              - description: \"Busybox base image.\"\n                is_official: true\n                is_automated: false\n                name: \"Busybox base image.\"\n                star_count: 3037\n              - description: \"The PostgreSQL object-relational database system provides reliability and data integrity.\"\n                is_official: true\n                is_automated: false\n                name: \"postgres\"\n                star_count: 12408\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"term\"\n          in: \"query\"\n          description: \"Term to search\"\n          type: \"string\"\n          required: true\n        - name: \"limit\"\n          in: \"query\"\n          description: \"Maximum number of results to return\"\n          type: \"integer\"\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to process on the images list. Available filters:\n\n            - `is-automated=(true|false)` (deprecated, see below)\n            - `is-official=(true|false)`\n            - `stars=<number>` Matches images that has at least 'number' stars.\n\n            The `is-automated` filter is deprecated. The `is_automated` field has\n            been deprecated by Docker Hub's search API. Consequently, searching\n            for `is-automated=true` will yield no results.\n          type: \"string\"\n      tags: [\"Image\"]\n  /images/prune:\n    post:\n      summary: \"Delete unused images\"\n      produces:\n        - \"application/json\"\n      operationId: \"ImagePrune\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            Filters to process on the prune list, encoded as JSON (a `map[string][]string`). Available filters:\n\n            - `dangling=<boolean>` When set to `true` (or `1`), prune only\n               unused *and* untagged images. When set to `false`\n               (or `0`), all unused images are pruned.\n            - `until=<string>` Prune images created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time.\n            - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune images with (or without, in case `label!=...` is used) the specified labels.\n          type: \"string\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"object\"\n            title: \"ImagePruneResponse\"\n            properties:\n              ImagesDeleted:\n                description: \"Images that were deleted\"\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/ImageDeleteResponseItem\"\n              SpaceReclaimed:\n                description: \"Disk space reclaimed in bytes\"\n                type: \"integer\"\n                format: \"int64\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Image\"]\n  /auth:\n    post:\n      summary: \"Check auth configuration\"\n      description: |\n        Validate credentials for a registry and, if available, get an identity\n        token for accessing the registry without password.\n      operationId: \"SystemAuth\"\n      consumes: [\"application/json\"]\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"An identity token was generated successfully.\"\n          schema:\n            type: \"object\"\n            title: \"SystemAuthResponse\"\n            required: [Status]\n            properties:\n              Status:\n                description: \"The status of the authentication\"\n                type: \"string\"\n                x-nullable: false\n              IdentityToken:\n                description: \"An opaque token used to authenticate a user after a successful login\"\n                type: \"string\"\n                x-nullable: false\n          examples:\n            application/json:\n              Status: \"Login Succeeded\"\n              IdentityToken: \"9cbaf023786cd7...\"\n        204:\n          description: \"No error\"\n        401:\n          description: \"Auth error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"authConfig\"\n          in: \"body\"\n          description: \"Authentication to check\"\n          schema:\n            $ref: \"#/definitions/AuthConfig\"\n      tags: [\"System\"]\n  /info:\n    get:\n      summary: \"Get system information\"\n      operationId: \"SystemInfo\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            $ref: \"#/definitions/SystemInfo\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"System\"]\n  /version:\n    get:\n      summary: \"Get version\"\n      description: \"Returns the version of Docker that is running and various information about the system that Docker is running on.\"\n      operationId: \"SystemVersion\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/SystemVersion\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"System\"]\n  /_ping:\n    get:\n      summary: \"Ping\"\n      description: \"This is a dummy endpoint you can use to test if the server is accessible.\"\n      operationId: \"SystemPing\"\n      produces: [\"text/plain\"]\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"string\"\n            example: \"OK\"\n          headers:\n            API-Version:\n              type: \"string\"\n              description: \"Max API Version the server supports\"\n            Builder-Version:\n              type: \"string\"\n              description: |\n                Default version of docker image builder\n\n                The default on Linux is version \"2\" (BuildKit), but the daemon\n                can be configured to recommend version \"1\" (classic Builder).\n                Windows does not yet support BuildKit for native Windows images,\n                and uses \"1\" (classic builder) as a default.\n\n                This value is a recommendation as advertised by the daemon, and\n                it is up to the client to choose which builder to use.\n              default: \"2\"\n            Docker-Experimental:\n              type: \"boolean\"\n              description: \"If the server is running with experimental mode enabled\"\n            Swarm:\n              type: \"string\"\n              enum: [\"inactive\", \"pending\", \"error\", \"locked\", \"active/worker\", \"active/manager\"]\n              description: |\n                Contains information about Swarm status of the daemon,\n                and if the daemon is acting as a manager or worker node.\n              default: \"inactive\"\n            Cache-Control:\n              type: \"string\"\n              default: \"no-cache, no-store, must-revalidate\"\n            Pragma:\n              type: \"string\"\n              default: \"no-cache\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          headers:\n            Cache-Control:\n              type: \"string\"\n              default: \"no-cache, no-store, must-revalidate\"\n            Pragma:\n              type: \"string\"\n              default: \"no-cache\"\n      tags: [\"System\"]\n    head:\n      summary: \"Ping\"\n      description: \"This is a dummy endpoint you can use to test if the server is accessible.\"\n      operationId: \"SystemPingHead\"\n      produces: [\"text/plain\"]\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"string\"\n            example: \"(empty)\"\n          headers:\n            API-Version:\n              type: \"string\"\n              description: \"Max API Version the server supports\"\n            Builder-Version:\n              type: \"string\"\n              description: \"Default version of docker image builder\"\n            Docker-Experimental:\n              type: \"boolean\"\n              description: \"If the server is running with experimental mode enabled\"\n            Swarm:\n              type: \"string\"\n              enum: [\"inactive\", \"pending\", \"error\", \"locked\", \"active/worker\", \"active/manager\"]\n              description: |\n                Contains information about Swarm status of the daemon,\n                and if the daemon is acting as a manager or worker node.\n              default: \"inactive\"\n            Cache-Control:\n              type: \"string\"\n              default: \"no-cache, no-store, must-revalidate\"\n            Pragma:\n              type: \"string\"\n              default: \"no-cache\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"System\"]\n  /commit:\n    post:\n      summary: \"Create a new image from a container\"\n      operationId: \"ImageCommit\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/json\"\n      responses:\n        201:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/IdResponse\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"containerConfig\"\n          in: \"body\"\n          description: \"The container configuration\"\n          schema:\n            $ref: \"#/definitions/ContainerConfig\"\n        - name: \"container\"\n          in: \"query\"\n          description: \"The ID or name of the container to commit\"\n          type: \"string\"\n        - name: \"repo\"\n          in: \"query\"\n          description: \"Repository name for the created image\"\n          type: \"string\"\n        - name: \"tag\"\n          in: \"query\"\n          description: \"Tag name for the create image\"\n          type: \"string\"\n        - name: \"comment\"\n          in: \"query\"\n          description: \"Commit message\"\n          type: \"string\"\n        - name: \"author\"\n          in: \"query\"\n          description: \"Author of the image (e.g., `John Hannibal Smith <hannibal@a-team.com>`)\"\n          type: \"string\"\n        - name: \"pause\"\n          in: \"query\"\n          description: \"Whether to pause the container before committing\"\n          type: \"boolean\"\n          default: true\n        - name: \"changes\"\n          in: \"query\"\n          description: \"`Dockerfile` instructions to apply while committing\"\n          type: \"string\"\n      tags: [\"Image\"]\n  /events:\n    get:\n      summary: \"Monitor events\"\n      description: |\n        Stream real-time events from the server.\n\n        Various objects within Docker report events when something happens to them.\n\n        Containers report these events: `attach`, `commit`, `copy`, `create`, `destroy`, `detach`, `die`, `exec_create`, `exec_detach`, `exec_start`, `exec_die`, `export`, `health_status`, `kill`, `oom`, `pause`, `rename`, `resize`, `restart`, `start`, `stop`, `top`, `unpause`, `update`, and `prune`\n\n        Images report these events: `delete`, `import`, `load`, `pull`, `push`, `save`, `tag`, `untag`, and `prune`\n\n        Volumes report these events: `create`, `mount`, `unmount`, `destroy`, and `prune`\n\n        Networks report these events: `create`, `connect`, `disconnect`, `destroy`, `update`, `remove`, and `prune`\n\n        The Docker daemon reports these events: `reload`\n\n        Services report these events: `create`, `update`, and `remove`\n\n        Nodes report these events: `create`, `update`, and `remove`\n\n        Secrets report these events: `create`, `update`, and `remove`\n\n        Configs report these events: `create`, `update`, and `remove`\n\n        The Builder reports `prune` events\n\n      operationId: \"SystemEvents\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/EventMessage\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"since\"\n          in: \"query\"\n          description: \"Show events created since this timestamp then stream new events.\"\n          type: \"string\"\n        - name: \"until\"\n          in: \"query\"\n          description: \"Show events created until this timestamp then stop streaming.\"\n          type: \"string\"\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            A JSON encoded value of filters (a `map[string][]string`) to process on the event list. Available filters:\n\n            - `config=<string>` config name or ID\n            - `container=<string>` container name or ID\n            - `daemon=<string>` daemon name or ID\n            - `event=<string>` event type\n            - `image=<string>` image name or ID\n            - `label=<string>` image or container label\n            - `network=<string>` network name or ID\n            - `node=<string>` node ID\n            - `plugin`=<string> plugin name or ID\n            - `scope`=<string> local or swarm\n            - `secret=<string>` secret name or ID\n            - `service=<string>` service name or ID\n            - `type=<string>` object to filter by, one of `container`, `image`, `volume`, `network`, `daemon`, `plugin`, `node`, `service`, `secret` or `config`\n            - `volume=<string>` volume name\n          type: \"string\"\n      tags: [\"System\"]\n  /system/df:\n    get:\n      summary: \"Get data usage information\"\n      operationId: \"SystemDataUsage\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"object\"\n            title: \"SystemDataUsageResponse\"\n            properties:\n              LayersSize:\n                type: \"integer\"\n                format: \"int64\"\n              Images:\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/ImageSummary\"\n              Containers:\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/ContainerSummary\"\n              Volumes:\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/Volume\"\n              BuildCache:\n                type: \"array\"\n                items:\n                  $ref: \"#/definitions/BuildCache\"\n            example:\n              LayersSize: 1092588\n              Images:\n                -\n                  Id: \"sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749\"\n                  ParentId: \"\"\n                  RepoTags:\n                    - \"busybox:latest\"\n                  RepoDigests:\n                    - \"busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6\"\n                  Created: 1466724217\n                  Size: 1092588\n                  SharedSize: 0\n                  Labels: {}\n                  Containers: 1\n              Containers:\n                -\n                  Id: \"e575172ed11dc01bfce087fb27bee502db149e1a0fad7c296ad300bbff178148\"\n                  Names:\n                    - \"/top\"\n                  Image: \"busybox\"\n                  ImageID: \"sha256:2b8fd9751c4c0f5dd266fcae00707e67a2545ef34f9a29354585f93dac906749\"\n                  Command: \"top\"\n                  Created: 1472592424\n                  Ports: []\n                  SizeRootFs: 1092588\n                  Labels: {}\n                  State: \"exited\"\n                  Status: \"Exited (0) 56 minutes ago\"\n                  HostConfig:\n                    NetworkMode: \"default\"\n                  NetworkSettings:\n                    Networks:\n                      bridge:\n                        IPAMConfig: null\n                        Links: null\n                        Aliases: null\n                        NetworkID: \"d687bc59335f0e5c9ee8193e5612e8aee000c8c62ea170cfb99c098f95899d92\"\n                        EndpointID: \"8ed5115aeaad9abb174f68dcf135b49f11daf597678315231a32ca28441dec6a\"\n                        Gateway: \"172.18.0.1\"\n                        IPAddress: \"172.18.0.2\"\n                        IPPrefixLen: 16\n                        IPv6Gateway: \"\"\n                        GlobalIPv6Address: \"\"\n                        GlobalIPv6PrefixLen: 0\n                        MacAddress: \"02:42:ac:12:00:02\"\n                  Mounts: []\n              Volumes:\n                -\n                  Name: \"my-volume\"\n                  Driver: \"local\"\n                  Mountpoint: \"/var/lib/docker/volumes/my-volume/_data\"\n                  Labels: null\n                  Scope: \"local\"\n                  Options: null\n                  UsageData:\n                    Size: 10920104\n                    RefCount: 2\n              BuildCache:\n                -\n                  ID: \"hw53o5aio51xtltp5xjp8v7fx\"\n                  Parents: []\n                  Type: \"regular\"\n                  Description: \"pulled from docker.io/library/debian@sha256:234cb88d3020898631af0ccbbcca9a66ae7306ecd30c9720690858c1b007d2a0\"\n                  InUse: false\n                  Shared: true\n                  Size: 0\n                  CreatedAt: \"2021-06-28T13:31:01.474619385Z\"\n                  LastUsedAt: \"2021-07-07T22:02:32.738075951Z\"\n                  UsageCount: 26\n                -\n                  ID: \"ndlpt0hhvkqcdfkputsk4cq9c\"\n                  Parents: [\"ndlpt0hhvkqcdfkputsk4cq9c\"]\n                  Type: \"regular\"\n                  Description: \"mount / from exec /bin/sh -c echo 'Binary::apt::APT::Keep-Downloaded-Packages \\\"true\\\";' > /etc/apt/apt.conf.d/keep-cache\"\n                  InUse: false\n                  Shared: true\n                  Size: 51\n                  CreatedAt: \"2021-06-28T13:31:03.002625487Z\"\n                  LastUsedAt: \"2021-07-07T22:02:32.773909517Z\"\n                  UsageCount: 26\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"type\"\n          in: \"query\"\n          description: |\n            Object types, for which to compute and return data.\n          type: \"array\"\n          collectionFormat: multi\n          items:\n            type: \"string\"\n            enum: [\"container\", \"image\", \"volume\", \"build-cache\"]\n      tags: [\"System\"]\n  /images/{name}/get:\n    get:\n      summary: \"Export an image\"\n      description: |\n        Get a tarball containing all images and metadata for a repository.\n\n        If `name` is a specific name and tag (e.g. `ubuntu:latest`), then only that image (and its parents) are returned. If `name` is an image ID, similarly only that image (and its parents) are returned, but with the exclusion of the `repositories` file in the tarball, as there were no image names referenced.\n\n        ### Image tarball format\n\n        An image tarball contains one directory per image layer (named using its long ID), each containing these files:\n\n        - `VERSION`: currently `1.0` - the file format version\n        - `json`: detailed layer information, similar to `docker inspect layer_id`\n        - `layer.tar`: A tarfile containing the filesystem changes in this layer\n\n        The `layer.tar` file contains `aufs` style `.wh..wh.aufs` files and directories for storing attribute changes and deletions.\n\n        If the tarball defines a repository, the tarball should also include a `repositories` file at the root that contains a list of repository and tag names mapped to layer IDs.\n\n        ```json\n        {\n          \"hello-world\": {\n            \"latest\": \"565a9d68a73f6706862bfe8409a7f659776d4d60a8d096eb4a3cbce6999cc2a1\"\n          }\n        }\n        ```\n      operationId: \"ImageGet\"\n      produces:\n        - \"application/x-tar\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"string\"\n            format: \"binary\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"Image name or ID\"\n          type: \"string\"\n          required: true\n      tags: [\"Image\"]\n  /images/get:\n    get:\n      summary: \"Export several images\"\n      description: |\n        Get a tarball containing all images and metadata for several image\n        repositories.\n\n        For each value of the `names` parameter: if it is a specific name and\n        tag (e.g. `ubuntu:latest`), then only that image (and its parents) are\n        returned; if it is an image ID, similarly only that image (and its parents)\n        are returned and there would be no names referenced in the 'repositories'\n        file for this image ID.\n\n        For details on the format, see the [export image endpoint](#operation/ImageGet).\n      operationId: \"ImageGetAll\"\n      produces:\n        - \"application/x-tar\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"string\"\n            format: \"binary\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"names\"\n          in: \"query\"\n          description: \"Image names to filter by\"\n          type: \"array\"\n          items:\n            type: \"string\"\n      tags: [\"Image\"]\n  /images/load:\n    post:\n      summary: \"Import images\"\n      description: |\n        Load a set of images and tags into a repository.\n\n        For details on the format, see the [export image endpoint](#operation/ImageGet).\n      operationId: \"ImageLoad\"\n      consumes:\n        - \"application/x-tar\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"imagesTarball\"\n          in: \"body\"\n          description: \"Tar archive containing images\"\n          schema:\n            type: \"string\"\n            format: \"binary\"\n        - name: \"quiet\"\n          in: \"query\"\n          description: \"Suppress progress details during load.\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Image\"]\n  /containers/{id}/exec:\n    post:\n      summary: \"Create an exec instance\"\n      description: \"Run a command inside a running container.\"\n      operationId: \"ContainerExec\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/json\"\n      responses:\n        201:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/IdResponse\"\n        404:\n          description: \"no such container\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such container: c2ada9df5af8\"\n        409:\n          description: \"container is paused\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"execConfig\"\n          in: \"body\"\n          description: \"Exec configuration\"\n          schema:\n            type: \"object\"\n            title: \"ExecConfig\"\n            properties:\n              AttachStdin:\n                type: \"boolean\"\n                description: \"Attach to `stdin` of the exec command.\"\n              AttachStdout:\n                type: \"boolean\"\n                description: \"Attach to `stdout` of the exec command.\"\n              AttachStderr:\n                type: \"boolean\"\n                description: \"Attach to `stderr` of the exec command.\"\n              ConsoleSize:\n                type: \"array\"\n                description: \"Initial console size, as an `[height, width]` array.\"\n                x-nullable: true\n                minItems: 2\n                maxItems: 2\n                items:\n                  type: \"integer\"\n                  minimum: 0\n              DetachKeys:\n                type: \"string\"\n                description: |\n                  Override the key sequence for detaching a container. Format is\n                  a single character `[a-Z]` or `ctrl-<value>` where `<value>`\n                  is one of: `a-z`, `@`, `^`, `[`, `,` or `_`.\n              Tty:\n                type: \"boolean\"\n                description: \"Allocate a pseudo-TTY.\"\n              Env:\n                description: |\n                  A list of environment variables in the form `[\"VAR=value\", ...]`.\n                type: \"array\"\n                items:\n                  type: \"string\"\n              Cmd:\n                type: \"array\"\n                description: \"Command to run, as a string or array of strings.\"\n                items:\n                  type: \"string\"\n              Privileged:\n                type: \"boolean\"\n                description: \"Runs the exec process with extended privileges.\"\n                default: false\n              User:\n                type: \"string\"\n                description: |\n                  The user, and optionally, group to run the exec process inside\n                  the container. Format is one of: `user`, `user:group`, `uid`,\n                  or `uid:gid`.\n              WorkingDir:\n                type: \"string\"\n                description: |\n                  The working directory for the exec process inside the container.\n            example:\n              AttachStdin: false\n              AttachStdout: true\n              AttachStderr: true\n              DetachKeys: \"ctrl-p,ctrl-q\"\n              Tty: false\n              Cmd:\n                - \"date\"\n              Env:\n                - \"FOO=bar\"\n                - \"BAZ=quux\"\n          required: true\n        - name: \"id\"\n          in: \"path\"\n          description: \"ID or name of container\"\n          type: \"string\"\n          required: true\n      tags: [\"Exec\"]\n  /exec/{id}/start:\n    post:\n      summary: \"Start an exec instance\"\n      description: |\n        Starts a previously set up exec instance. If detach is true, this endpoint\n        returns immediately after starting the command. Otherwise, it sets up an\n        interactive session with the command.\n      operationId: \"ExecStart\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/vnd.docker.raw-stream\"\n        - \"application/vnd.docker.multiplexed-stream\"\n      responses:\n        200:\n          description: \"No error\"\n        404:\n          description: \"No such exec instance\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        409:\n          description: \"Container is stopped or paused\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"execStartConfig\"\n          in: \"body\"\n          schema:\n            type: \"object\"\n            title: \"ExecStartConfig\"\n            properties:\n              Detach:\n                type: \"boolean\"\n                description: \"Detach from the command.\"\n              Tty:\n                type: \"boolean\"\n                description: \"Allocate a pseudo-TTY.\"\n              ConsoleSize:\n                type: \"array\"\n                description: \"Initial console size, as an `[height, width]` array.\"\n                x-nullable: true\n                minItems: 2\n                maxItems: 2\n                items:\n                  type: \"integer\"\n                  minimum: 0\n            example:\n              Detach: false\n              Tty: true\n              ConsoleSize: [80, 64]\n        - name: \"id\"\n          in: \"path\"\n          description: \"Exec instance ID\"\n          required: true\n          type: \"string\"\n      tags: [\"Exec\"]\n  /exec/{id}/resize:\n    post:\n      summary: \"Resize an exec instance\"\n      description: |\n        Resize the TTY session used by an exec instance. This endpoint only works\n        if `tty` was specified as part of creating and starting the exec instance.\n      operationId: \"ExecResize\"\n      responses:\n        200:\n          description: \"No error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"No such exec instance\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"Exec instance ID\"\n          required: true\n          type: \"string\"\n        - name: \"h\"\n          in: \"query\"\n          description: \"Height of the TTY session in characters\"\n          type: \"integer\"\n        - name: \"w\"\n          in: \"query\"\n          description: \"Width of the TTY session in characters\"\n          type: \"integer\"\n      tags: [\"Exec\"]\n  /exec/{id}/json:\n    get:\n      summary: \"Inspect an exec instance\"\n      description: \"Return low-level information about an exec instance.\"\n      operationId: \"ExecInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"object\"\n            title: \"ExecInspectResponse\"\n            properties:\n              CanRemove:\n                type: \"boolean\"\n              DetachKeys:\n                type: \"string\"\n              ID:\n                type: \"string\"\n              Running:\n                type: \"boolean\"\n              ExitCode:\n                type: \"integer\"\n              ProcessConfig:\n                $ref: \"#/definitions/ProcessConfig\"\n              OpenStdin:\n                type: \"boolean\"\n              OpenStderr:\n                type: \"boolean\"\n              OpenStdout:\n                type: \"boolean\"\n              ContainerID:\n                type: \"string\"\n              Pid:\n                type: \"integer\"\n                description: \"The system process ID for the exec process.\"\n          examples:\n            application/json:\n              CanRemove: false\n              ContainerID: \"b53ee82b53a40c7dca428523e34f741f3abc51d9f297a14ff874bf761b995126\"\n              DetachKeys: \"\"\n              ExitCode: 2\n              ID: \"f33bbfb39f5b142420f4759b2348913bd4a8d1a6d7fd56499cb41a1bb91d7b3b\"\n              OpenStderr: true\n              OpenStdin: true\n              OpenStdout: true\n              ProcessConfig:\n                arguments:\n                  - \"-c\"\n                  - \"exit 2\"\n                entrypoint: \"sh\"\n                privileged: false\n                tty: true\n                user: \"1000\"\n              Running: false\n              Pid: 42000\n        404:\n          description: \"No such exec instance\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"Exec instance ID\"\n          required: true\n          type: \"string\"\n      tags: [\"Exec\"]\n\n  /volumes:\n    get:\n      summary: \"List volumes\"\n      operationId: \"VolumeList\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"Summary volume data that matches the query\"\n          schema:\n            $ref: \"#/definitions/VolumeListResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            JSON encoded value of the filters (a `map[string][]string`) to\n            process on the volumes list. Available filters:\n\n            - `dangling=<boolean>` When set to `true` (or `1`), returns all\n               volumes that are not in use by a container. When set to `false`\n               (or `0`), only volumes that are in use by one or more\n               containers are returned.\n            - `driver=<volume-driver-name>` Matches volumes based on their driver.\n            - `label=<key>` or `label=<key>:<value>` Matches volumes based on\n               the presence of a `label` alone or a `label` and a value.\n            - `name=<volume-name>` Matches all or part of a volume name.\n          type: \"string\"\n          format: \"json\"\n      tags: [\"Volume\"]\n\n  /volumes/create:\n    post:\n      summary: \"Create a volume\"\n      operationId: \"VolumeCreate\"\n      consumes: [\"application/json\"]\n      produces: [\"application/json\"]\n      responses:\n        201:\n          description: \"The volume was created successfully\"\n          schema:\n            $ref: \"#/definitions/Volume\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"volumeConfig\"\n          in: \"body\"\n          required: true\n          description: \"Volume configuration\"\n          schema:\n            $ref: \"#/definitions/VolumeCreateOptions\"\n      tags: [\"Volume\"]\n\n  /volumes/{name}:\n    get:\n      summary: \"Inspect a volume\"\n      operationId: \"VolumeInspect\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            $ref: \"#/definitions/Volume\"\n        404:\n          description: \"No such volume\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          required: true\n          description: \"Volume name or ID\"\n          type: \"string\"\n      tags: [\"Volume\"]\n\n    put:\n      summary: |\n        \"Update a volume. Valid only for Swarm cluster volumes\"\n      operationId: \"VolumeUpdate\"\n      consumes: [\"application/json\"]\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such volume\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"The name or ID of the volume\"\n          type: \"string\"\n          required: true\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            # though the schema for is an object that contains only a\n            # ClusterVolumeSpec, wrapping the ClusterVolumeSpec in this object\n            # means that if, later on, we support things like changing the\n            # labels, we can do so without duplicating that information to the\n            # ClusterVolumeSpec.\n            type: \"object\"\n            description: \"Volume configuration\"\n            properties:\n              Spec:\n                $ref: \"#/definitions/ClusterVolumeSpec\"\n          description: |\n            The spec of the volume to update. Currently, only Availability may\n            change. All other fields must remain unchanged.\n        - name: \"version\"\n          in: \"query\"\n          description: |\n            The version number of the volume being updated. This is required to\n            avoid conflicting writes. Found in the volume's `ClusterVolume`\n            field.\n          type: \"integer\"\n          format: \"int64\"\n          required: true\n      tags: [\"Volume\"]\n\n    delete:\n      summary: \"Remove a volume\"\n      description: \"Instruct the driver to remove the volume.\"\n      operationId: \"VolumeDelete\"\n      responses:\n        204:\n          description: \"The volume was removed\"\n        404:\n          description: \"No such volume or volume driver\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        409:\n          description: \"Volume is in use and cannot be removed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          required: true\n          description: \"Volume name or ID\"\n          type: \"string\"\n        - name: \"force\"\n          in: \"query\"\n          description: \"Force the removal of the volume\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Volume\"]\n\n  /volumes/prune:\n    post:\n      summary: \"Delete unused volumes\"\n      produces:\n        - \"application/json\"\n      operationId: \"VolumePrune\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            Filters to process on the prune list, encoded as JSON (a `map[string][]string`).\n\n            Available filters:\n            - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune volumes with (or without, in case `label!=...` is used) the specified labels.\n            - `all` (`all=true`) - Consider all (local) volumes for pruning and not just anonymous volumes.\n          type: \"string\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"object\"\n            title: \"VolumePruneResponse\"\n            properties:\n              VolumesDeleted:\n                description: \"Volumes that were deleted\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n              SpaceReclaimed:\n                description: \"Disk space reclaimed in bytes\"\n                type: \"integer\"\n                format: \"int64\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Volume\"]\n  /networks:\n    get:\n      summary: \"List networks\"\n      description: |\n        Returns a list of networks. For details on the format, see the\n        [network inspect endpoint](#operation/NetworkInspect).\n\n        Note that it uses a different, smaller representation of a network than\n        inspecting a single network. For example, the list of containers attached\n        to the network is not propagated in API versions 1.28 and up.\n      operationId: \"NetworkList\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Network\"\n          examples:\n            application/json:\n              - Name: \"bridge\"\n                Id: \"f2de39df4171b0dc801e8002d1d999b77256983dfc63041c0f34030aa3977566\"\n                Created: \"2016-10-19T06:21:00.416543526Z\"\n                Scope: \"local\"\n                Driver: \"bridge\"\n                EnableIPv6: false\n                Internal: false\n                Attachable: false\n                Ingress: false\n                IPAM:\n                  Driver: \"default\"\n                  Config:\n                    -\n                      Subnet: \"172.17.0.0/16\"\n                Options:\n                  com.docker.network.bridge.default_bridge: \"true\"\n                  com.docker.network.bridge.enable_icc: \"true\"\n                  com.docker.network.bridge.enable_ip_masquerade: \"true\"\n                  com.docker.network.bridge.host_binding_ipv4: \"0.0.0.0\"\n                  com.docker.network.bridge.name: \"docker0\"\n                  com.docker.network.driver.mtu: \"1500\"\n              - Name: \"none\"\n                Id: \"e086a3893b05ab69242d3c44e49483a3bbbd3a26b46baa8f61ab797c1088d794\"\n                Created: \"0001-01-01T00:00:00Z\"\n                Scope: \"local\"\n                Driver: \"null\"\n                EnableIPv6: false\n                Internal: false\n                Attachable: false\n                Ingress: false\n                IPAM:\n                  Driver: \"default\"\n                  Config: []\n                Containers: {}\n                Options: {}\n              - Name: \"host\"\n                Id: \"13e871235c677f196c4e1ecebb9dc733b9b2d2ab589e30c539efeda84a24215e\"\n                Created: \"0001-01-01T00:00:00Z\"\n                Scope: \"local\"\n                Driver: \"host\"\n                EnableIPv6: false\n                Internal: false\n                Attachable: false\n                Ingress: false\n                IPAM:\n                  Driver: \"default\"\n                  Config: []\n                Containers: {}\n                Options: {}\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            JSON encoded value of the filters (a `map[string][]string`) to process\n            on the networks list.\n\n            Available filters:\n\n            - `dangling=<boolean>` When set to `true` (or `1`), returns all\n               networks that are not in use by a container. When set to `false`\n               (or `0`), only networks that are in use by one or more\n               containers are returned.\n            - `driver=<driver-name>` Matches a network's driver.\n            - `id=<network-id>` Matches all or part of a network ID.\n            - `label=<key>` or `label=<key>=<value>` of a network label.\n            - `name=<network-name>` Matches all or part of a network name.\n            - `scope=[\"swarm\"|\"global\"|\"local\"]` Filters networks by scope (`swarm`, `global`, or `local`).\n            - `type=[\"custom\"|\"builtin\"]` Filters networks by type. The `custom` keyword returns all user-defined networks.\n          type: \"string\"\n      tags: [\"Network\"]\n\n  /networks/{id}:\n    get:\n      summary: \"Inspect a network\"\n      operationId: \"NetworkInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            $ref: \"#/definitions/Network\"\n        404:\n          description: \"Network not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"Network ID or name\"\n          required: true\n          type: \"string\"\n        - name: \"verbose\"\n          in: \"query\"\n          description: \"Detailed inspect output for troubleshooting\"\n          type: \"boolean\"\n          default: false\n        - name: \"scope\"\n          in: \"query\"\n          description: \"Filter the network by scope (swarm, global, or local)\"\n          type: \"string\"\n      tags: [\"Network\"]\n\n    delete:\n      summary: \"Remove a network\"\n      operationId: \"NetworkDelete\"\n      responses:\n        204:\n          description: \"No error\"\n        403:\n          description: \"operation not supported for pre-defined networks\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such network\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"Network ID or name\"\n          required: true\n          type: \"string\"\n      tags: [\"Network\"]\n\n  /networks/create:\n    post:\n      summary: \"Create a network\"\n      operationId: \"NetworkCreate\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/json\"\n      responses:\n        201:\n          description: \"No error\"\n          schema:\n            type: \"object\"\n            title: \"NetworkCreateResponse\"\n            properties:\n              Id:\n                description: \"The ID of the created network.\"\n                type: \"string\"\n              Warning:\n                type: \"string\"\n            example:\n              Id: \"22be93d5babb089c5aab8dbc369042fad48ff791584ca2da2100db837a1c7c30\"\n              Warning: \"\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        403:\n          description: |\n            Forbidden operation. This happens when trying to create a network named after a pre-defined network,\n            or when trying to create an overlay network on a daemon which is not part of a Swarm cluster.\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"plugin not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"networkConfig\"\n          in: \"body\"\n          description: \"Network configuration\"\n          required: true\n          schema:\n            type: \"object\"\n            title: \"NetworkCreateRequest\"\n            required: [\"Name\"]\n            properties:\n              Name:\n                description: \"The network's name.\"\n                type: \"string\"\n              CheckDuplicate:\n                description: |\n                  Deprecated: CheckDuplicate is now always enabled.\n                type: \"boolean\"\n              Driver:\n                description: \"Name of the network driver plugin to use.\"\n                type: \"string\"\n                default: \"bridge\"\n              Internal:\n                description: \"Restrict external access to the network.\"\n                type: \"boolean\"\n              Attachable:\n                description: |\n                  Globally scoped network is manually attachable by regular\n                  containers from workers in swarm mode.\n                type: \"boolean\"\n              Ingress:\n                description: |\n                  Ingress network is the network which provides the routing-mesh\n                  in swarm mode.\n                type: \"boolean\"\n              IPAM:\n                description: \"Optional custom IP scheme for the network.\"\n                $ref: \"#/definitions/IPAM\"\n              EnableIPv6:\n                description: \"Enable IPv6 on the network.\"\n                type: \"boolean\"\n              Options:\n                description: \"Network specific options to be used by the drivers.\"\n                type: \"object\"\n                additionalProperties:\n                  type: \"string\"\n              Labels:\n                description: \"User-defined key/value metadata.\"\n                type: \"object\"\n                additionalProperties:\n                  type: \"string\"\n            example:\n              Name: \"isolated_nw\"\n              CheckDuplicate: false\n              Driver: \"bridge\"\n              EnableIPv6: true\n              IPAM:\n                Driver: \"default\"\n                Config:\n                  - Subnet: \"172.20.0.0/16\"\n                    IPRange: \"172.20.10.0/24\"\n                    Gateway: \"172.20.10.11\"\n                  - Subnet: \"2001:db8:abcd::/64\"\n                    Gateway: \"2001:db8:abcd::1011\"\n                Options:\n                  foo: \"bar\"\n              Internal: true\n              Attachable: false\n              Ingress: false\n              Options:\n                com.docker.network.bridge.default_bridge: \"true\"\n                com.docker.network.bridge.enable_icc: \"true\"\n                com.docker.network.bridge.enable_ip_masquerade: \"true\"\n                com.docker.network.bridge.host_binding_ipv4: \"0.0.0.0\"\n                com.docker.network.bridge.name: \"docker0\"\n                com.docker.network.driver.mtu: \"1500\"\n              Labels:\n                com.example.some-label: \"some-value\"\n                com.example.some-other-label: \"some-other-value\"\n      tags: [\"Network\"]\n\n  /networks/{id}/connect:\n    post:\n      summary: \"Connect a container to a network\"\n      description: \"The network must be either a local-scoped network or a swarm-scoped network with the `attachable` option set. A network cannot be re-attached to a running container\"\n      operationId: \"NetworkConnect\"\n      consumes:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        403:\n          description: \"Operation forbidden\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"Network or container not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"Network ID or name\"\n          required: true\n          type: \"string\"\n        - name: \"container\"\n          in: \"body\"\n          required: true\n          schema:\n            type: \"object\"\n            title: \"NetworkConnectRequest\"\n            properties:\n              Container:\n                type: \"string\"\n                description: \"The ID or name of the container to connect to the network.\"\n              EndpointConfig:\n                $ref: \"#/definitions/EndpointSettings\"\n            example:\n              Container: \"3613f73ba0e4\"\n              EndpointConfig:\n                IPAMConfig:\n                  IPv4Address: \"172.24.56.89\"\n                  IPv6Address: \"2001:db8::5689\"\n                MacAddress: \"02:42:ac:12:05:02\"\n      tags: [\"Network\"]\n\n  /networks/{id}/disconnect:\n    post:\n      summary: \"Disconnect a container from a network\"\n      operationId: \"NetworkDisconnect\"\n      consumes:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"No error\"\n        403:\n          description: \"Operation not supported for swarm scoped networks\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"Network or container not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"Network ID or name\"\n          required: true\n          type: \"string\"\n        - name: \"container\"\n          in: \"body\"\n          required: true\n          schema:\n            type: \"object\"\n            title: \"NetworkDisconnectRequest\"\n            properties:\n              Container:\n                type: \"string\"\n                description: |\n                  The ID or name of the container to disconnect from the network.\n              Force:\n                type: \"boolean\"\n                description: |\n                  Force the container to disconnect from the network.\n      tags: [\"Network\"]\n  /networks/prune:\n    post:\n      summary: \"Delete unused networks\"\n      produces:\n        - \"application/json\"\n      operationId: \"NetworkPrune\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            Filters to process on the prune list, encoded as JSON (a `map[string][]string`).\n\n            Available filters:\n            - `until=<timestamp>` Prune networks created before this timestamp. The `<timestamp>` can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. `10m`, `1h30m`) computed relative to the daemon machine’s time.\n            - `label` (`label=<key>`, `label=<key>=<value>`, `label!=<key>`, or `label!=<key>=<value>`) Prune networks with (or without, in case `label!=...` is used) the specified labels.\n          type: \"string\"\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"object\"\n            title: \"NetworkPruneResponse\"\n            properties:\n              NetworksDeleted:\n                description: \"Networks that were deleted\"\n                type: \"array\"\n                items:\n                  type: \"string\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Network\"]\n  /plugins:\n    get:\n      summary: \"List plugins\"\n      operationId: \"PluginList\"\n      description: \"Returns information about installed plugins.\"\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"No error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Plugin\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          type: \"string\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to\n            process on the plugin list.\n\n            Available filters:\n\n            - `capability=<capability name>`\n            - `enable=<true>|<false>`\n      tags: [\"Plugin\"]\n\n  /plugins/privileges:\n    get:\n      summary: \"Get plugin privileges\"\n      operationId: \"GetPluginPrivileges\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginPrivilege\"\n            example:\n              - Name: \"network\"\n                Description: \"\"\n                Value:\n                  - \"host\"\n              - Name: \"mount\"\n                Description: \"\"\n                Value:\n                  - \"/data\"\n              - Name: \"device\"\n                Description: \"\"\n                Value:\n                  - \"/dev/cpu_dma_latency\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"remote\"\n          in: \"query\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n      tags:\n        - \"Plugin\"\n\n  /plugins/pull:\n    post:\n      summary: \"Install a plugin\"\n      operationId: \"PluginPull\"\n      description: |\n        Pulls and installs a plugin. After the plugin is installed, it can be\n        enabled using the [`POST /plugins/{name}/enable` endpoint](#operation/PostPluginsEnable).\n      produces:\n        - \"application/json\"\n      responses:\n        204:\n          description: \"no error\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"remote\"\n          in: \"query\"\n          description: |\n            Remote reference for plugin to install.\n\n            The `:latest` tag is optional, and is used as the default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"name\"\n          in: \"query\"\n          description: |\n            Local name for the pulled plugin.\n\n            The `:latest` tag is optional, and is used as the default if omitted.\n          required: false\n          type: \"string\"\n        - name: \"X-Registry-Auth\"\n          in: \"header\"\n          description: |\n            A base64url-encoded auth configuration to use when pulling a plugin\n            from a registry.\n\n            Refer to the [authentication section](#section/Authentication) for\n            details.\n          type: \"string\"\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginPrivilege\"\n            example:\n              - Name: \"network\"\n                Description: \"\"\n                Value:\n                  - \"host\"\n              - Name: \"mount\"\n                Description: \"\"\n                Value:\n                  - \"/data\"\n              - Name: \"device\"\n                Description: \"\"\n                Value:\n                  - \"/dev/cpu_dma_latency\"\n      tags: [\"Plugin\"]\n  /plugins/{name}/json:\n    get:\n      summary: \"Inspect a plugin\"\n      operationId: \"PluginInspect\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Plugin\"\n        404:\n          description: \"plugin is not installed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n      tags: [\"Plugin\"]\n  /plugins/{name}:\n    delete:\n      summary: \"Remove a plugin\"\n      operationId: \"PluginDelete\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Plugin\"\n        404:\n          description: \"plugin is not installed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"force\"\n          in: \"query\"\n          description: |\n            Disable the plugin before removing. This may result in issues if the\n            plugin is in use by a container.\n          type: \"boolean\"\n          default: false\n      tags: [\"Plugin\"]\n  /plugins/{name}/enable:\n    post:\n      summary: \"Enable a plugin\"\n      operationId: \"PluginEnable\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"plugin is not installed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"timeout\"\n          in: \"query\"\n          description: \"Set the HTTP client timeout (in seconds)\"\n          type: \"integer\"\n          default: 0\n      tags: [\"Plugin\"]\n  /plugins/{name}/disable:\n    post:\n      summary: \"Disable a plugin\"\n      operationId: \"PluginDisable\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"plugin is not installed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"force\"\n          in: \"query\"\n          description: |\n            Force disable a plugin even if still in use.\n          required: false\n          type: \"boolean\"\n      tags: [\"Plugin\"]\n  /plugins/{name}/upgrade:\n    post:\n      summary: \"Upgrade a plugin\"\n      operationId: \"PluginUpgrade\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"plugin not installed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"remote\"\n          in: \"query\"\n          description: |\n            Remote reference to upgrade to.\n\n            The `:latest` tag is optional, and is used as the default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"X-Registry-Auth\"\n          in: \"header\"\n          description: |\n            A base64url-encoded auth configuration to use when pulling a plugin\n            from a registry.\n\n            Refer to the [authentication section](#section/Authentication) for\n            details.\n          type: \"string\"\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/PluginPrivilege\"\n            example:\n              - Name: \"network\"\n                Description: \"\"\n                Value:\n                  - \"host\"\n              - Name: \"mount\"\n                Description: \"\"\n                Value:\n                  - \"/data\"\n              - Name: \"device\"\n                Description: \"\"\n                Value:\n                  - \"/dev/cpu_dma_latency\"\n      tags: [\"Plugin\"]\n  /plugins/create:\n    post:\n      summary: \"Create a plugin\"\n      operationId: \"PluginCreate\"\n      consumes:\n        - \"application/x-tar\"\n      responses:\n        204:\n          description: \"no error\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"query\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"tarContext\"\n          in: \"body\"\n          description: \"Path to tar containing plugin rootfs and manifest\"\n          schema:\n            type: \"string\"\n            format: \"binary\"\n      tags: [\"Plugin\"]\n  /plugins/{name}/push:\n    post:\n      summary: \"Push a plugin\"\n      operationId: \"PluginPush\"\n      description: |\n        Push a plugin to the registry.\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"plugin not installed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Plugin\"]\n  /plugins/{name}/set:\n    post:\n      summary: \"Configure a plugin\"\n      operationId: \"PluginSet\"\n      consumes:\n        - \"application/json\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: |\n            The name of the plugin. The `:latest` tag is optional, and is the\n            default if omitted.\n          required: true\n          type: \"string\"\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            type: \"array\"\n            items:\n              type: \"string\"\n            example: [\"DEBUG=1\"]\n      responses:\n        204:\n          description: \"No error\"\n        404:\n          description: \"Plugin not installed\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Plugin\"]\n  /nodes:\n    get:\n      summary: \"List nodes\"\n      operationId: \"NodeList\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Node\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          description: |\n            Filters to process on the nodes list, encoded as JSON (a `map[string][]string`).\n\n            Available filters:\n            - `id=<node id>`\n            - `label=<engine label>`\n            - `membership=`(`accepted`|`pending`)`\n            - `name=<node name>`\n            - `node.label=<node label>`\n            - `role=`(`manager`|`worker`)`\n          type: \"string\"\n      tags: [\"Node\"]\n  /nodes/{id}:\n    get:\n      summary: \"Inspect a node\"\n      operationId: \"NodeInspect\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Node\"\n        404:\n          description: \"no such node\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"The ID or name of the node\"\n          type: \"string\"\n          required: true\n      tags: [\"Node\"]\n    delete:\n      summary: \"Delete a node\"\n      operationId: \"NodeDelete\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"no such node\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"The ID or name of the node\"\n          type: \"string\"\n          required: true\n        - name: \"force\"\n          in: \"query\"\n          description: \"Force remove a node from the swarm\"\n          default: false\n          type: \"boolean\"\n      tags: [\"Node\"]\n  /nodes/{id}/update:\n    post:\n      summary: \"Update a node\"\n      operationId: \"NodeUpdate\"\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such node\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"The ID of the node\"\n          type: \"string\"\n          required: true\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            $ref: \"#/definitions/NodeSpec\"\n        - name: \"version\"\n          in: \"query\"\n          description: |\n            The version number of the node object being updated. This is required\n            to avoid conflicting writes.\n          type: \"integer\"\n          format: \"int64\"\n          required: true\n      tags: [\"Node\"]\n  /swarm:\n    get:\n      summary: \"Inspect swarm\"\n      operationId: \"SwarmInspect\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Swarm\"\n        404:\n          description: \"no such swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Swarm\"]\n  /swarm/init:\n    post:\n      summary: \"Initialize a new swarm\"\n      operationId: \"SwarmInit\"\n      produces:\n        - \"application/json\"\n        - \"text/plain\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            description: \"The node ID\"\n            type: \"string\"\n            example: \"7v2t30z9blmxuhnyo6s4cpenp\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is already part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"body\"\n          in: \"body\"\n          required: true\n          schema:\n            type: \"object\"\n            title: \"SwarmInitRequest\"\n            properties:\n              ListenAddr:\n                description: |\n                  Listen address used for inter-manager communication, as well\n                  as determining the networking interface used for the VXLAN\n                  Tunnel Endpoint (VTEP). This can either be an address/port\n                  combination in the form `192.168.1.1:4567`, or an interface\n                  followed by a port number, like `eth0:4567`. If the port number\n                  is omitted, the default swarm listening port is used.\n                type: \"string\"\n              AdvertiseAddr:\n                description: |\n                  Externally reachable address advertised to other nodes. This\n                  can either be an address/port combination in the form\n                  `192.168.1.1:4567`, or an interface followed by a port number,\n                  like `eth0:4567`. If the port number is omitted, the port\n                  number from the listen address is used. If `AdvertiseAddr` is\n                  not specified, it will be automatically detected when possible.\n                type: \"string\"\n              DataPathAddr:\n                description: |\n                  Address or interface to use for data path traffic (format:\n                  `<ip|interface>`), for example,  `192.168.1.1`, or an interface,\n                  like `eth0`. If `DataPathAddr` is unspecified, the same address\n                  as `AdvertiseAddr` is used.\n\n                  The `DataPathAddr` specifies the address that global scope\n                  network drivers will publish towards other  nodes in order to\n                  reach the containers running on this node. Using this parameter\n                  it is possible to separate the container data traffic from the\n                  management traffic of the cluster.\n                type: \"string\"\n              DataPathPort:\n                description: |\n                  DataPathPort specifies the data path port number for data traffic.\n                  Acceptable port range is 1024 to 49151.\n                  if no port is set or is set to 0, default port 4789 will be used.\n                type: \"integer\"\n                format: \"uint32\"\n              DefaultAddrPool:\n                description: |\n                  Default Address Pool specifies default subnet pools for global\n                  scope networks.\n                type: \"array\"\n                items:\n                  type: \"string\"\n                  example: [\"10.10.0.0/16\", \"20.20.0.0/16\"]\n              ForceNewCluster:\n                description: \"Force creation of a new swarm.\"\n                type: \"boolean\"\n              SubnetSize:\n                description: |\n                  SubnetSize specifies the subnet size of the networks created\n                  from the default subnet pool.\n                type: \"integer\"\n                format: \"uint32\"\n              Spec:\n                $ref: \"#/definitions/SwarmSpec\"\n            example:\n              ListenAddr: \"0.0.0.0:2377\"\n              AdvertiseAddr: \"192.168.1.1:2377\"\n              DataPathPort: 4789\n              DefaultAddrPool: [\"10.10.0.0/8\", \"20.20.0.0/8\"]\n              SubnetSize: 24\n              ForceNewCluster: false\n              Spec:\n                Orchestration: {}\n                Raft: {}\n                Dispatcher: {}\n                CAConfig: {}\n                EncryptionConfig:\n                  AutoLockManagers: false\n      tags: [\"Swarm\"]\n  /swarm/join:\n    post:\n      summary: \"Join an existing swarm\"\n      operationId: \"SwarmJoin\"\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is already part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"body\"\n          in: \"body\"\n          required: true\n          schema:\n            type: \"object\"\n            title: \"SwarmJoinRequest\"\n            properties:\n              ListenAddr:\n                description: |\n                  Listen address used for inter-manager communication if the node\n                  gets promoted to manager, as well as determining the networking\n                  interface used for the VXLAN Tunnel Endpoint (VTEP).\n                type: \"string\"\n              AdvertiseAddr:\n                description: |\n                  Externally reachable address advertised to other nodes. This\n                  can either be an address/port combination in the form\n                  `192.168.1.1:4567`, or an interface followed by a port number,\n                  like `eth0:4567`. If the port number is omitted, the port\n                  number from the listen address is used. If `AdvertiseAddr` is\n                  not specified, it will be automatically detected when possible.\n                type: \"string\"\n              DataPathAddr:\n                description: |\n                  Address or interface to use for data path traffic (format:\n                  `<ip|interface>`), for example,  `192.168.1.1`, or an interface,\n                  like `eth0`. If `DataPathAddr` is unspecified, the same address\n                  as `AdvertiseAddr` is used.\n\n                  The `DataPathAddr` specifies the address that global scope\n                  network drivers will publish towards other nodes in order to\n                  reach the containers running on this node. Using this parameter\n                  it is possible to separate the container data traffic from the\n                  management traffic of the cluster.\n\n                type: \"string\"\n              RemoteAddrs:\n                description: |\n                  Addresses of manager nodes already participating in the swarm.\n                type: \"array\"\n                items:\n                  type: \"string\"\n              JoinToken:\n                description: \"Secret token for joining this swarm.\"\n                type: \"string\"\n            example:\n              ListenAddr: \"0.0.0.0:2377\"\n              AdvertiseAddr: \"192.168.1.1:2377\"\n              RemoteAddrs:\n                - \"node1:2377\"\n              JoinToken: \"SWMTKN-1-3pu6hszjas19xyp7ghgosyx9k8atbfcr8p2is99znpy26u2lkl-7p73s1dx5in4tatdymyhg9hu2\"\n      tags: [\"Swarm\"]\n  /swarm/leave:\n    post:\n      summary: \"Leave a swarm\"\n      operationId: \"SwarmLeave\"\n      responses:\n        200:\n          description: \"no error\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"force\"\n          description: |\n            Force leave swarm, even if this is the last manager or that it will\n            break the cluster.\n          in: \"query\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Swarm\"]\n  /swarm/update:\n    post:\n      summary: \"Update a swarm\"\n      operationId: \"SwarmUpdate\"\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"body\"\n          in: \"body\"\n          required: true\n          schema:\n            $ref: \"#/definitions/SwarmSpec\"\n        - name: \"version\"\n          in: \"query\"\n          description: |\n            The version number of the swarm object being updated. This is\n            required to avoid conflicting writes.\n          type: \"integer\"\n          format: \"int64\"\n          required: true\n        - name: \"rotateWorkerToken\"\n          in: \"query\"\n          description: \"Rotate the worker join token.\"\n          type: \"boolean\"\n          default: false\n        - name: \"rotateManagerToken\"\n          in: \"query\"\n          description: \"Rotate the manager join token.\"\n          type: \"boolean\"\n          default: false\n        - name: \"rotateManagerUnlockKey\"\n          in: \"query\"\n          description: \"Rotate the manager unlock key.\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Swarm\"]\n  /swarm/unlockkey:\n    get:\n      summary: \"Get the unlock key\"\n      operationId: \"SwarmUnlockkey\"\n      consumes:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"object\"\n            title: \"UnlockKeyResponse\"\n            properties:\n              UnlockKey:\n                description: \"The swarm's unlock key.\"\n                type: \"string\"\n            example:\n              UnlockKey: \"SWMKEY-1-7c37Cc8654o6p38HnroywCi19pllOnGtbdZEgtKxZu8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Swarm\"]\n  /swarm/unlock:\n    post:\n      summary: \"Unlock a locked manager\"\n      operationId: \"SwarmUnlock\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/json\"\n      parameters:\n        - name: \"body\"\n          in: \"body\"\n          required: true\n          schema:\n            type: \"object\"\n            title: \"SwarmUnlockRequest\"\n            properties:\n              UnlockKey:\n                description: \"The swarm's unlock key.\"\n                type: \"string\"\n            example:\n              UnlockKey: \"SWMKEY-1-7c37Cc8654o6p38HnroywCi19pllOnGtbdZEgtKxZu8\"\n      responses:\n        200:\n          description: \"no error\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Swarm\"]\n  /services:\n    get:\n      summary: \"List services\"\n      operationId: \"ServiceList\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Service\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          type: \"string\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to\n            process on the services list.\n\n            Available filters:\n\n            - `id=<service id>`\n            - `label=<service label>`\n            - `mode=[\"replicated\"|\"global\"]`\n            - `name=<service name>`\n        - name: \"status\"\n          in: \"query\"\n          type: \"boolean\"\n          description: |\n            Include service status, with count of running and desired tasks.\n      tags: [\"Service\"]\n  /services/create:\n    post:\n      summary: \"Create a service\"\n      operationId: \"ServiceCreate\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/json\"\n      responses:\n        201:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/ServiceCreateResponse\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        403:\n          description: \"network is not eligible for services\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        409:\n          description: \"name conflicts with an existing service\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"body\"\n          in: \"body\"\n          required: true\n          schema:\n            allOf:\n              - $ref: \"#/definitions/ServiceSpec\"\n              - type: \"object\"\n                example:\n                  Name: \"web\"\n                  TaskTemplate:\n                    ContainerSpec:\n                      Image: \"nginx:alpine\"\n                      Mounts:\n                        -\n                          ReadOnly: true\n                          Source: \"web-data\"\n                          Target: \"/usr/share/nginx/html\"\n                          Type: \"volume\"\n                          VolumeOptions:\n                            DriverConfig: {}\n                            Labels:\n                              com.example.something: \"something-value\"\n                      Hosts: [\"10.10.10.10 host1\", \"ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 host2\"]\n                      User: \"33\"\n                      DNSConfig:\n                        Nameservers: [\"8.8.8.8\"]\n                        Search: [\"example.org\"]\n                        Options: [\"timeout:3\"]\n                      Secrets:\n                        -\n                          File:\n                            Name: \"www.example.org.key\"\n                            UID: \"33\"\n                            GID: \"33\"\n                            Mode: 384\n                          SecretID: \"fpjqlhnwb19zds35k8wn80lq9\"\n                          SecretName: \"example_org_domain_key\"\n                    LogDriver:\n                      Name: \"json-file\"\n                      Options:\n                        max-file: \"3\"\n                        max-size: \"10M\"\n                    Placement: {}\n                    Resources:\n                      Limits:\n                        MemoryBytes: 104857600\n                      Reservations: {}\n                    RestartPolicy:\n                      Condition: \"on-failure\"\n                      Delay: 10000000000\n                      MaxAttempts: 10\n                  Mode:\n                    Replicated:\n                      Replicas: 4\n                  UpdateConfig:\n                    Parallelism: 2\n                    Delay: 1000000000\n                    FailureAction: \"pause\"\n                    Monitor: 15000000000\n                    MaxFailureRatio: 0.15\n                  RollbackConfig:\n                    Parallelism: 1\n                    Delay: 1000000000\n                    FailureAction: \"pause\"\n                    Monitor: 15000000000\n                    MaxFailureRatio: 0.15\n                  EndpointSpec:\n                    Ports:\n                      -\n                        Protocol: \"tcp\"\n                        PublishedPort: 8080\n                        TargetPort: 80\n                  Labels:\n                    foo: \"bar\"\n        - name: \"X-Registry-Auth\"\n          in: \"header\"\n          description: |\n            A base64url-encoded auth configuration for pulling from private\n            registries.\n\n            Refer to the [authentication section](#section/Authentication) for\n            details.\n          type: \"string\"\n      tags: [\"Service\"]\n  /services/{id}:\n    get:\n      summary: \"Inspect a service\"\n      operationId: \"ServiceInspect\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Service\"\n        404:\n          description: \"no such service\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"ID or name of service.\"\n          required: true\n          type: \"string\"\n        - name: \"insertDefaults\"\n          in: \"query\"\n          description: \"Fill empty fields with default values.\"\n          type: \"boolean\"\n          default: false\n      tags: [\"Service\"]\n    delete:\n      summary: \"Delete a service\"\n      operationId: \"ServiceDelete\"\n      responses:\n        200:\n          description: \"no error\"\n        404:\n          description: \"no such service\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"ID or name of service.\"\n          required: true\n          type: \"string\"\n      tags: [\"Service\"]\n  /services/{id}/update:\n    post:\n      summary: \"Update a service\"\n      operationId: \"ServiceUpdate\"\n      consumes: [\"application/json\"]\n      produces: [\"application/json\"]\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/ServiceUpdateResponse\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such service\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"ID or name of service.\"\n          required: true\n          type: \"string\"\n        - name: \"body\"\n          in: \"body\"\n          required: true\n          schema:\n            allOf:\n              - $ref: \"#/definitions/ServiceSpec\"\n              - type: \"object\"\n                example:\n                  Name: \"top\"\n                  TaskTemplate:\n                    ContainerSpec:\n                      Image: \"busybox\"\n                      Args:\n                        - \"top\"\n                    Resources:\n                      Limits: {}\n                      Reservations: {}\n                    RestartPolicy:\n                      Condition: \"any\"\n                      MaxAttempts: 0\n                    Placement: {}\n                    ForceUpdate: 0\n                  Mode:\n                    Replicated:\n                      Replicas: 1\n                  UpdateConfig:\n                    Parallelism: 2\n                    Delay: 1000000000\n                    FailureAction: \"pause\"\n                    Monitor: 15000000000\n                    MaxFailureRatio: 0.15\n                  RollbackConfig:\n                    Parallelism: 1\n                    Delay: 1000000000\n                    FailureAction: \"pause\"\n                    Monitor: 15000000000\n                    MaxFailureRatio: 0.15\n                  EndpointSpec:\n                    Mode: \"vip\"\n\n        - name: \"version\"\n          in: \"query\"\n          description: |\n            The version number of the service object being updated. This is\n            required to avoid conflicting writes.\n            This version number should be the value as currently set on the\n            service *before* the update. You can find the current version by\n            calling `GET /services/{id}`\n          required: true\n          type: \"integer\"\n        - name: \"registryAuthFrom\"\n          in: \"query\"\n          description: |\n            If the `X-Registry-Auth` header is not specified, this parameter\n            indicates where to find registry authorization credentials.\n          type: \"string\"\n          enum: [\"spec\", \"previous-spec\"]\n          default: \"spec\"\n        - name: \"rollback\"\n          in: \"query\"\n          description: |\n            Set to this parameter to `previous` to cause a server-side rollback\n            to the previous service spec. The supplied spec will be ignored in\n            this case.\n          type: \"string\"\n        - name: \"X-Registry-Auth\"\n          in: \"header\"\n          description: |\n            A base64url-encoded auth configuration for pulling from private\n            registries.\n\n            Refer to the [authentication section](#section/Authentication) for\n            details.\n          type: \"string\"\n\n      tags: [\"Service\"]\n  /services/{id}/logs:\n    get:\n      summary: \"Get service logs\"\n      description: |\n        Get `stdout` and `stderr` logs from a service. See also\n        [`/containers/{id}/logs`](#operation/ContainerLogs).\n\n        **Note**: This endpoint works only for services with the `local`,\n        `json-file` or `journald` logging drivers.\n      produces:\n        - \"application/vnd.docker.raw-stream\"\n        - \"application/vnd.docker.multiplexed-stream\"\n      operationId: \"ServiceLogs\"\n      responses:\n        200:\n          description: \"logs returned as a stream in response body\"\n          schema:\n            type: \"string\"\n            format: \"binary\"\n        404:\n          description: \"no such service\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such service: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID or name of the service\"\n          type: \"string\"\n        - name: \"details\"\n          in: \"query\"\n          description: \"Show service context and extra details provided to logs.\"\n          type: \"boolean\"\n          default: false\n        - name: \"follow\"\n          in: \"query\"\n          description: \"Keep connection after returning logs.\"\n          type: \"boolean\"\n          default: false\n        - name: \"stdout\"\n          in: \"query\"\n          description: \"Return logs from `stdout`\"\n          type: \"boolean\"\n          default: false\n        - name: \"stderr\"\n          in: \"query\"\n          description: \"Return logs from `stderr`\"\n          type: \"boolean\"\n          default: false\n        - name: \"since\"\n          in: \"query\"\n          description: \"Only return logs since this time, as a UNIX timestamp\"\n          type: \"integer\"\n          default: 0\n        - name: \"timestamps\"\n          in: \"query\"\n          description: \"Add timestamps to every log line\"\n          type: \"boolean\"\n          default: false\n        - name: \"tail\"\n          in: \"query\"\n          description: |\n            Only return this number of log lines from the end of the logs.\n            Specify as an integer or `all` to output all log lines.\n          type: \"string\"\n          default: \"all\"\n      tags: [\"Service\"]\n  /tasks:\n    get:\n      summary: \"List tasks\"\n      operationId: \"TaskList\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Task\"\n            example:\n              - ID: \"0kzzo1i0y4jz6027t0k7aezc7\"\n                Version:\n                  Index: 71\n                CreatedAt: \"2016-06-07T21:07:31.171892745Z\"\n                UpdatedAt: \"2016-06-07T21:07:31.376370513Z\"\n                Spec:\n                  ContainerSpec:\n                    Image: \"redis\"\n                  Resources:\n                    Limits: {}\n                    Reservations: {}\n                  RestartPolicy:\n                    Condition: \"any\"\n                    MaxAttempts: 0\n                  Placement: {}\n                ServiceID: \"9mnpnzenvg8p8tdbtq4wvbkcz\"\n                Slot: 1\n                NodeID: \"60gvrl6tm78dmak4yl7srz94v\"\n                Status:\n                  Timestamp: \"2016-06-07T21:07:31.290032978Z\"\n                  State: \"running\"\n                  Message: \"started\"\n                  ContainerStatus:\n                    ContainerID: \"e5d62702a1b48d01c3e02ca1e0212a250801fa8d67caca0b6f35919ebc12f035\"\n                    PID: 677\n                DesiredState: \"running\"\n                NetworksAttachments:\n                  - Network:\n                      ID: \"4qvuz4ko70xaltuqbt8956gd1\"\n                      Version:\n                        Index: 18\n                      CreatedAt: \"2016-06-07T20:31:11.912919752Z\"\n                      UpdatedAt: \"2016-06-07T21:07:29.955277358Z\"\n                      Spec:\n                        Name: \"ingress\"\n                        Labels:\n                          com.docker.swarm.internal: \"true\"\n                        DriverConfiguration: {}\n                        IPAMOptions:\n                          Driver: {}\n                          Configs:\n                            - Subnet: \"10.255.0.0/16\"\n                              Gateway: \"10.255.0.1\"\n                      DriverState:\n                        Name: \"overlay\"\n                        Options:\n                          com.docker.network.driver.overlay.vxlanid_list: \"256\"\n                      IPAMOptions:\n                        Driver:\n                          Name: \"default\"\n                        Configs:\n                          - Subnet: \"10.255.0.0/16\"\n                            Gateway: \"10.255.0.1\"\n                    Addresses:\n                      - \"10.255.0.10/16\"\n              - ID: \"1yljwbmlr8er2waf8orvqpwms\"\n                Version:\n                  Index: 30\n                CreatedAt: \"2016-06-07T21:07:30.019104782Z\"\n                UpdatedAt: \"2016-06-07T21:07:30.231958098Z\"\n                Name: \"hopeful_cori\"\n                Spec:\n                  ContainerSpec:\n                    Image: \"redis\"\n                  Resources:\n                    Limits: {}\n                    Reservations: {}\n                  RestartPolicy:\n                    Condition: \"any\"\n                    MaxAttempts: 0\n                  Placement: {}\n                ServiceID: \"9mnpnzenvg8p8tdbtq4wvbkcz\"\n                Slot: 1\n                NodeID: \"60gvrl6tm78dmak4yl7srz94v\"\n                Status:\n                  Timestamp: \"2016-06-07T21:07:30.202183143Z\"\n                  State: \"shutdown\"\n                  Message: \"shutdown\"\n                  ContainerStatus:\n                    ContainerID: \"1cf8d63d18e79668b0004a4be4c6ee58cddfad2dae29506d8781581d0688a213\"\n                DesiredState: \"shutdown\"\n                NetworksAttachments:\n                  - Network:\n                      ID: \"4qvuz4ko70xaltuqbt8956gd1\"\n                      Version:\n                        Index: 18\n                      CreatedAt: \"2016-06-07T20:31:11.912919752Z\"\n                      UpdatedAt: \"2016-06-07T21:07:29.955277358Z\"\n                      Spec:\n                        Name: \"ingress\"\n                        Labels:\n                          com.docker.swarm.internal: \"true\"\n                        DriverConfiguration: {}\n                        IPAMOptions:\n                          Driver: {}\n                          Configs:\n                            - Subnet: \"10.255.0.0/16\"\n                              Gateway: \"10.255.0.1\"\n                      DriverState:\n                        Name: \"overlay\"\n                        Options:\n                          com.docker.network.driver.overlay.vxlanid_list: \"256\"\n                      IPAMOptions:\n                        Driver:\n                          Name: \"default\"\n                        Configs:\n                          - Subnet: \"10.255.0.0/16\"\n                            Gateway: \"10.255.0.1\"\n                    Addresses:\n                      - \"10.255.0.5/16\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          type: \"string\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to\n            process on the tasks list.\n\n            Available filters:\n\n            - `desired-state=(running | shutdown | accepted)`\n            - `id=<task id>`\n            - `label=key` or `label=\"key=value\"`\n            - `name=<task name>`\n            - `node=<node id or name>`\n            - `service=<service name>`\n      tags: [\"Task\"]\n  /tasks/{id}:\n    get:\n      summary: \"Inspect a task\"\n      operationId: \"TaskInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Task\"\n        404:\n          description: \"no such task\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"ID of the task\"\n          required: true\n          type: \"string\"\n      tags: [\"Task\"]\n  /tasks/{id}/logs:\n    get:\n      summary: \"Get task logs\"\n      description: |\n        Get `stdout` and `stderr` logs from a task.\n        See also [`/containers/{id}/logs`](#operation/ContainerLogs).\n\n        **Note**: This endpoint works only for services with the `local`,\n        `json-file` or `journald` logging drivers.\n      operationId: \"TaskLogs\"\n      produces:\n        - \"application/vnd.docker.raw-stream\"\n        - \"application/vnd.docker.multiplexed-stream\"\n      responses:\n        200:\n          description: \"logs returned as a stream in response body\"\n          schema:\n            type: \"string\"\n            format: \"binary\"\n        404:\n          description: \"no such task\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such task: c2ada9df5af8\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          description: \"ID of the task\"\n          type: \"string\"\n        - name: \"details\"\n          in: \"query\"\n          description: \"Show task context and extra details provided to logs.\"\n          type: \"boolean\"\n          default: false\n        - name: \"follow\"\n          in: \"query\"\n          description: \"Keep connection after returning logs.\"\n          type: \"boolean\"\n          default: false\n        - name: \"stdout\"\n          in: \"query\"\n          description: \"Return logs from `stdout`\"\n          type: \"boolean\"\n          default: false\n        - name: \"stderr\"\n          in: \"query\"\n          description: \"Return logs from `stderr`\"\n          type: \"boolean\"\n          default: false\n        - name: \"since\"\n          in: \"query\"\n          description: \"Only return logs since this time, as a UNIX timestamp\"\n          type: \"integer\"\n          default: 0\n        - name: \"timestamps\"\n          in: \"query\"\n          description: \"Add timestamps to every log line\"\n          type: \"boolean\"\n          default: false\n        - name: \"tail\"\n          in: \"query\"\n          description: |\n            Only return this number of log lines from the end of the logs.\n            Specify as an integer or `all` to output all log lines.\n          type: \"string\"\n          default: \"all\"\n      tags: [\"Task\"]\n  /secrets:\n    get:\n      summary: \"List secrets\"\n      operationId: \"SecretList\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Secret\"\n            example:\n              - ID: \"blt1owaxmitz71s9v5zh81zun\"\n                Version:\n                  Index: 85\n                CreatedAt: \"2017-07-20T13:55:28.678958722Z\"\n                UpdatedAt: \"2017-07-20T13:55:28.678958722Z\"\n                Spec:\n                  Name: \"mysql-passwd\"\n                  Labels:\n                    some.label: \"some.value\"\n                  Driver:\n                    Name: \"secret-bucket\"\n                    Options:\n                      OptionA: \"value for driver option A\"\n                      OptionB: \"value for driver option B\"\n              - ID: \"ktnbjxoalbkvbvedmg1urrz8h\"\n                Version:\n                  Index: 11\n                CreatedAt: \"2016-11-05T01:20:17.327670065Z\"\n                UpdatedAt: \"2016-11-05T01:20:17.327670065Z\"\n                Spec:\n                  Name: \"app-dev.crt\"\n                  Labels:\n                    foo: \"bar\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          type: \"string\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to\n            process on the secrets list.\n\n            Available filters:\n\n            - `id=<secret id>`\n            - `label=<key> or label=<key>=value`\n            - `name=<secret name>`\n            - `names=<secret name>`\n      tags: [\"Secret\"]\n  /secrets/create:\n    post:\n      summary: \"Create a secret\"\n      operationId: \"SecretCreate\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/json\"\n      responses:\n        201:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/IdResponse\"\n        409:\n          description: \"name conflicts with an existing object\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            allOf:\n              - $ref: \"#/definitions/SecretSpec\"\n              - type: \"object\"\n                example:\n                  Name: \"app-key.crt\"\n                  Labels:\n                    foo: \"bar\"\n                  Data: \"VEhJUyBJUyBOT1QgQSBSRUFMIENFUlRJRklDQVRFCg==\"\n                  Driver:\n                    Name: \"secret-bucket\"\n                    Options:\n                      OptionA: \"value for driver option A\"\n                      OptionB: \"value for driver option B\"\n      tags: [\"Secret\"]\n  /secrets/{id}:\n    get:\n      summary: \"Inspect a secret\"\n      operationId: \"SecretInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Secret\"\n          examples:\n            application/json:\n              ID: \"ktnbjxoalbkvbvedmg1urrz8h\"\n              Version:\n                Index: 11\n              CreatedAt: \"2016-11-05T01:20:17.327670065Z\"\n              UpdatedAt: \"2016-11-05T01:20:17.327670065Z\"\n              Spec:\n                Name: \"app-dev.crt\"\n                Labels:\n                  foo: \"bar\"\n                Driver:\n                  Name: \"secret-bucket\"\n                  Options:\n                    OptionA: \"value for driver option A\"\n                    OptionB: \"value for driver option B\"\n\n        404:\n          description: \"secret not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          type: \"string\"\n          description: \"ID of the secret\"\n      tags: [\"Secret\"]\n    delete:\n      summary: \"Delete a secret\"\n      operationId: \"SecretDelete\"\n      produces:\n        - \"application/json\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"secret not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          type: \"string\"\n          description: \"ID of the secret\"\n      tags: [\"Secret\"]\n  /secrets/{id}/update:\n    post:\n      summary: \"Update a Secret\"\n      operationId: \"SecretUpdate\"\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such secret\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"The ID or name of the secret\"\n          type: \"string\"\n          required: true\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            $ref: \"#/definitions/SecretSpec\"\n          description: |\n            The spec of the secret to update. Currently, only the Labels field\n            can be updated. All other fields must remain unchanged from the\n            [SecretInspect endpoint](#operation/SecretInspect) response values.\n        - name: \"version\"\n          in: \"query\"\n          description: |\n            The version number of the secret object being updated. This is\n            required to avoid conflicting writes.\n          type: \"integer\"\n          format: \"int64\"\n          required: true\n      tags: [\"Secret\"]\n  /configs:\n    get:\n      summary: \"List configs\"\n      operationId: \"ConfigList\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            type: \"array\"\n            items:\n              $ref: \"#/definitions/Config\"\n            example:\n              - ID: \"ktnbjxoalbkvbvedmg1urrz8h\"\n                Version:\n                  Index: 11\n                CreatedAt: \"2016-11-05T01:20:17.327670065Z\"\n                UpdatedAt: \"2016-11-05T01:20:17.327670065Z\"\n                Spec:\n                  Name: \"server.conf\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"filters\"\n          in: \"query\"\n          type: \"string\"\n          description: |\n            A JSON encoded value of the filters (a `map[string][]string`) to\n            process on the configs list.\n\n            Available filters:\n\n            - `id=<config id>`\n            - `label=<key> or label=<key>=value`\n            - `name=<config name>`\n            - `names=<config name>`\n      tags: [\"Config\"]\n  /configs/create:\n    post:\n      summary: \"Create a config\"\n      operationId: \"ConfigCreate\"\n      consumes:\n        - \"application/json\"\n      produces:\n        - \"application/json\"\n      responses:\n        201:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/IdResponse\"\n        409:\n          description: \"name conflicts with an existing object\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            allOf:\n              - $ref: \"#/definitions/ConfigSpec\"\n              - type: \"object\"\n                example:\n                  Name: \"server.conf\"\n                  Labels:\n                    foo: \"bar\"\n                  Data: \"VEhJUyBJUyBOT1QgQSBSRUFMIENFUlRJRklDQVRFCg==\"\n      tags: [\"Config\"]\n  /configs/{id}:\n    get:\n      summary: \"Inspect a config\"\n      operationId: \"ConfigInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"no error\"\n          schema:\n            $ref: \"#/definitions/Config\"\n          examples:\n            application/json:\n              ID: \"ktnbjxoalbkvbvedmg1urrz8h\"\n              Version:\n                Index: 11\n              CreatedAt: \"2016-11-05T01:20:17.327670065Z\"\n              UpdatedAt: \"2016-11-05T01:20:17.327670065Z\"\n              Spec:\n                Name: \"app-dev.crt\"\n        404:\n          description: \"config not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          type: \"string\"\n          description: \"ID of the config\"\n      tags: [\"Config\"]\n    delete:\n      summary: \"Delete a config\"\n      operationId: \"ConfigDelete\"\n      produces:\n        - \"application/json\"\n      responses:\n        204:\n          description: \"no error\"\n        404:\n          description: \"config not found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          required: true\n          type: \"string\"\n          description: \"ID of the config\"\n      tags: [\"Config\"]\n  /configs/{id}/update:\n    post:\n      summary: \"Update a Config\"\n      operationId: \"ConfigUpdate\"\n      responses:\n        200:\n          description: \"no error\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        404:\n          description: \"no such config\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        503:\n          description: \"node is not part of a swarm\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"id\"\n          in: \"path\"\n          description: \"The ID or name of the config\"\n          type: \"string\"\n          required: true\n        - name: \"body\"\n          in: \"body\"\n          schema:\n            $ref: \"#/definitions/ConfigSpec\"\n          description: |\n            The spec of the config to update. Currently, only the Labels field\n            can be updated. All other fields must remain unchanged from the\n            [ConfigInspect endpoint](#operation/ConfigInspect) response values.\n        - name: \"version\"\n          in: \"query\"\n          description: |\n            The version number of the config object being updated. This is\n            required to avoid conflicting writes.\n          type: \"integer\"\n          format: \"int64\"\n          required: true\n      tags: [\"Config\"]\n  /distribution/{name}/json:\n    get:\n      summary: \"Get image information from the registry\"\n      description: |\n        Return image digest and platform information by contacting the registry.\n      operationId: \"DistributionInspect\"\n      produces:\n        - \"application/json\"\n      responses:\n        200:\n          description: \"descriptor and platform information\"\n          schema:\n            $ref: \"#/definitions/DistributionInspect\"\n        401:\n          description: \"Failed authentication or no image found\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n          examples:\n            application/json:\n              message: \"No such image: someimage (tag: latest)\"\n        500:\n          description: \"Server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      parameters:\n        - name: \"name\"\n          in: \"path\"\n          description: \"Image name or id\"\n          type: \"string\"\n          required: true\n      tags: [\"Distribution\"]\n  /session:\n    post:\n      summary: \"Initialize interactive session\"\n      description: |\n        Start a new interactive session with a server. Session allows server to\n        call back to the client for advanced capabilities.\n\n        ### Hijacking\n\n        This endpoint hijacks the HTTP connection to HTTP2 transport that allows\n        the client to expose gPRC services on that connection.\n\n        For example, the client sends this request to upgrade the connection:\n\n        ```\n        POST /session HTTP/1.1\n        Upgrade: h2c\n        Connection: Upgrade\n        ```\n\n        The Docker daemon responds with a `101 UPGRADED` response follow with\n        the raw stream:\n\n        ```\n        HTTP/1.1 101 UPGRADED\n        Connection: Upgrade\n        Upgrade: h2c\n        ```\n      operationId: \"Session\"\n      produces:\n        - \"application/vnd.docker.raw-stream\"\n      responses:\n        101:\n          description: \"no error, hijacking successful\"\n        400:\n          description: \"bad parameter\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n        500:\n          description: \"server error\"\n          schema:\n            $ref: \"#/definitions/ErrorResponse\"\n      tags: [\"Session\"]\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/blkiodev/blkio.go",
    "content": "package blkiodev // import \"github.com/docker/docker/api/types/blkiodev\"\n\nimport \"fmt\"\n\n// WeightDevice is a structure that holds device:weight pair\ntype WeightDevice struct {\n\tPath   string\n\tWeight uint16\n}\n\nfunc (w *WeightDevice) String() string {\n\treturn fmt.Sprintf(\"%s:%d\", w.Path, w.Weight)\n}\n\n// ThrottleDevice is a structure that holds device:rate_per_second pair\ntype ThrottleDevice struct {\n\tPath string\n\tRate uint64\n}\n\nfunc (t *ThrottleDevice) String() string {\n\treturn fmt.Sprintf(\"%s:%d\", t.Path, t.Rate)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/checkpoint/list.go",
    "content": "package checkpoint\n\n// Summary represents the details of a checkpoint when listing endpoints.\ntype Summary struct {\n\t// Name is the name of the checkpoint.\n\tName string\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/checkpoint/options.go",
    "content": "package checkpoint\n\n// CreateOptions holds parameters to create a checkpoint from a container.\ntype CreateOptions struct {\n\tCheckpointID  string\n\tCheckpointDir string\n\tExit          bool\n}\n\n// ListOptions holds parameters to list checkpoints for a container.\ntype ListOptions struct {\n\tCheckpointDir string\n}\n\n// DeleteOptions holds parameters to delete a checkpoint from a container.\ntype DeleteOptions struct {\n\tCheckpointID  string\n\tCheckpointDir string\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/client.go",
    "content": "package types // import \"github.com/docker/docker/api/types\"\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"net\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/registry\"\n\tunits \"github.com/docker/go-units\"\n)\n\n// ContainerExecInspect holds information returned by exec inspect.\ntype ContainerExecInspect struct {\n\tExecID      string `json:\"ID\"`\n\tContainerID string\n\tRunning     bool\n\tExitCode    int\n\tPid         int\n}\n\n// CopyToContainerOptions holds information\n// about files to copy into a container\ntype CopyToContainerOptions struct {\n\tAllowOverwriteDirWithFile bool\n\tCopyUIDGID                bool\n}\n\n// EventsOptions holds parameters to filter events with.\ntype EventsOptions struct {\n\tSince   string\n\tUntil   string\n\tFilters filters.Args\n}\n\n// NetworkListOptions holds parameters to filter the list of networks with.\ntype NetworkListOptions struct {\n\tFilters filters.Args\n}\n\n// NewHijackedResponse intializes a HijackedResponse type\nfunc NewHijackedResponse(conn net.Conn, mediaType string) HijackedResponse {\n\treturn HijackedResponse{Conn: conn, Reader: bufio.NewReader(conn), mediaType: mediaType}\n}\n\n// HijackedResponse holds connection information for a hijacked request.\ntype HijackedResponse struct {\n\tmediaType string\n\tConn      net.Conn\n\tReader    *bufio.Reader\n}\n\n// Close closes the hijacked connection and reader.\nfunc (h *HijackedResponse) Close() {\n\th.Conn.Close()\n}\n\n// MediaType let client know if HijackedResponse hold a raw or multiplexed stream.\n// returns false if HTTP Content-Type is not relevant, and container must be inspected\nfunc (h *HijackedResponse) MediaType() (string, bool) {\n\tif h.mediaType == \"\" {\n\t\treturn \"\", false\n\t}\n\treturn h.mediaType, true\n}\n\n// CloseWriter is an interface that implements structs\n// that close input streams to prevent from writing.\ntype CloseWriter interface {\n\tCloseWrite() error\n}\n\n// CloseWrite closes a readWriter for writing.\nfunc (h *HijackedResponse) CloseWrite() error {\n\tif conn, ok := h.Conn.(CloseWriter); ok {\n\t\treturn conn.CloseWrite()\n\t}\n\treturn nil\n}\n\n// ImageBuildOptions holds the information\n// necessary to build images.\ntype ImageBuildOptions struct {\n\tTags           []string\n\tSuppressOutput bool\n\tRemoteContext  string\n\tNoCache        bool\n\tRemove         bool\n\tForceRemove    bool\n\tPullParent     bool\n\tIsolation      container.Isolation\n\tCPUSetCPUs     string\n\tCPUSetMems     string\n\tCPUShares      int64\n\tCPUQuota       int64\n\tCPUPeriod      int64\n\tMemory         int64\n\tMemorySwap     int64\n\tCgroupParent   string\n\tNetworkMode    string\n\tShmSize        int64\n\tDockerfile     string\n\tUlimits        []*units.Ulimit\n\t// BuildArgs needs to be a *string instead of just a string so that\n\t// we can tell the difference between \"\" (empty string) and no value\n\t// at all (nil). See the parsing of buildArgs in\n\t// api/server/router/build/build_routes.go for even more info.\n\tBuildArgs   map[string]*string\n\tAuthConfigs map[string]registry.AuthConfig\n\tContext     io.Reader\n\tLabels      map[string]string\n\t// squash the resulting image's layers to the parent\n\t// preserves the original image and creates a new one from the parent with all\n\t// the changes applied to a single layer\n\tSquash bool\n\t// CacheFrom specifies images that are used for matching cache. Images\n\t// specified here do not need to have a valid parent chain to match cache.\n\tCacheFrom   []string\n\tSecurityOpt []string\n\tExtraHosts  []string // List of extra hosts\n\tTarget      string\n\tSessionID   string\n\tPlatform    string\n\t// Version specifies the version of the unerlying builder to use\n\tVersion BuilderVersion\n\t// BuildID is an optional identifier that can be passed together with the\n\t// build request. The same identifier can be used to gracefully cancel the\n\t// build with the cancel request.\n\tBuildID string\n\t// Outputs defines configurations for exporting build results. Only supported\n\t// in BuildKit mode\n\tOutputs []ImageBuildOutput\n}\n\n// ImageBuildOutput defines configuration for exporting a build result\ntype ImageBuildOutput struct {\n\tType  string\n\tAttrs map[string]string\n}\n\n// BuilderVersion sets the version of underlying builder to use\ntype BuilderVersion string\n\nconst (\n\t// BuilderV1 is the first generation builder in docker daemon\n\tBuilderV1 BuilderVersion = \"1\"\n\t// BuilderBuildKit is builder based on moby/buildkit project\n\tBuilderBuildKit BuilderVersion = \"2\"\n)\n\n// ImageBuildResponse holds information\n// returned by a server after building\n// an image.\ntype ImageBuildResponse struct {\n\tBody   io.ReadCloser\n\tOSType string\n}\n\n// ImageCreateOptions holds information to create images.\ntype ImageCreateOptions struct {\n\tRegistryAuth string // RegistryAuth is the base64 encoded credentials for the registry.\n\tPlatform     string // Platform is the target platform of the image if it needs to be pulled from the registry.\n}\n\n// ImageImportSource holds source information for ImageImport\ntype ImageImportSource struct {\n\tSource     io.Reader // Source is the data to send to the server to create this image from. You must set SourceName to \"-\" to leverage this.\n\tSourceName string    // SourceName is the name of the image to pull. Set to \"-\" to leverage the Source attribute.\n}\n\n// ImageImportOptions holds information to import images from the client host.\ntype ImageImportOptions struct {\n\tTag      string   // Tag is the name to tag this image with. This attribute is deprecated.\n\tMessage  string   // Message is the message to tag the image with\n\tChanges  []string // Changes are the raw changes to apply to this image\n\tPlatform string   // Platform is the target platform of the image\n}\n\n// ImageListOptions holds parameters to list images with.\ntype ImageListOptions struct {\n\t// All controls whether all images in the graph are filtered, or just\n\t// the heads.\n\tAll bool\n\n\t// Filters is a JSON-encoded set of filter arguments.\n\tFilters filters.Args\n\n\t// SharedSize indicates whether the shared size of images should be computed.\n\tSharedSize bool\n\n\t// ContainerCount indicates whether container count should be computed.\n\tContainerCount bool\n}\n\n// ImageLoadResponse returns information to the client about a load process.\ntype ImageLoadResponse struct {\n\t// Body must be closed to avoid a resource leak\n\tBody io.ReadCloser\n\tJSON bool\n}\n\n// ImagePullOptions holds information to pull images.\ntype ImagePullOptions struct {\n\tAll           bool\n\tRegistryAuth  string // RegistryAuth is the base64 encoded credentials for the registry\n\tPrivilegeFunc RequestPrivilegeFunc\n\tPlatform      string\n}\n\n// RequestPrivilegeFunc is a function interface that\n// clients can supply to retry operations after\n// getting an authorization error.\n// This function returns the registry authentication\n// header value in base 64 format, or an error\n// if the privilege request fails.\ntype RequestPrivilegeFunc func() (string, error)\n\n// ImagePushOptions holds information to push images.\ntype ImagePushOptions ImagePullOptions\n\n// ImageRemoveOptions holds parameters to remove images.\ntype ImageRemoveOptions struct {\n\tForce         bool\n\tPruneChildren bool\n}\n\n// ImageSearchOptions holds parameters to search images with.\ntype ImageSearchOptions struct {\n\tRegistryAuth  string\n\tPrivilegeFunc RequestPrivilegeFunc\n\tFilters       filters.Args\n\tLimit         int\n}\n\n// NodeListOptions holds parameters to list nodes with.\ntype NodeListOptions struct {\n\tFilters filters.Args\n}\n\n// NodeRemoveOptions holds parameters to remove nodes with.\ntype NodeRemoveOptions struct {\n\tForce bool\n}\n\n// ServiceCreateOptions contains the options to use when creating a service.\ntype ServiceCreateOptions struct {\n\t// EncodedRegistryAuth is the encoded registry authorization credentials to\n\t// use when updating the service.\n\t//\n\t// This field follows the format of the X-Registry-Auth header.\n\tEncodedRegistryAuth string\n\n\t// QueryRegistry indicates whether the service update requires\n\t// contacting a registry. A registry may be contacted to retrieve\n\t// the image digest and manifest, which in turn can be used to update\n\t// platform or other information about the service.\n\tQueryRegistry bool\n}\n\n// Values for RegistryAuthFrom in ServiceUpdateOptions\nconst (\n\tRegistryAuthFromSpec         = \"spec\"\n\tRegistryAuthFromPreviousSpec = \"previous-spec\"\n)\n\n// ServiceUpdateOptions contains the options to be used for updating services.\ntype ServiceUpdateOptions struct {\n\t// EncodedRegistryAuth is the encoded registry authorization credentials to\n\t// use when updating the service.\n\t//\n\t// This field follows the format of the X-Registry-Auth header.\n\tEncodedRegistryAuth string\n\n\t// TODO(stevvooe): Consider moving the version parameter of ServiceUpdate\n\t// into this field. While it does open API users up to racy writes, most\n\t// users may not need that level of consistency in practice.\n\n\t// RegistryAuthFrom specifies where to find the registry authorization\n\t// credentials if they are not given in EncodedRegistryAuth. Valid\n\t// values are \"spec\" and \"previous-spec\".\n\tRegistryAuthFrom string\n\n\t// Rollback indicates whether a server-side rollback should be\n\t// performed. When this is set, the provided spec will be ignored.\n\t// The valid values are \"previous\" and \"none\". An empty value is the\n\t// same as \"none\".\n\tRollback string\n\n\t// QueryRegistry indicates whether the service update requires\n\t// contacting a registry. A registry may be contacted to retrieve\n\t// the image digest and manifest, which in turn can be used to update\n\t// platform or other information about the service.\n\tQueryRegistry bool\n}\n\n// ServiceListOptions holds parameters to list services with.\ntype ServiceListOptions struct {\n\tFilters filters.Args\n\n\t// Status indicates whether the server should include the service task\n\t// count of running and desired tasks.\n\tStatus bool\n}\n\n// ServiceInspectOptions holds parameters related to the \"service inspect\"\n// operation.\ntype ServiceInspectOptions struct {\n\tInsertDefaults bool\n}\n\n// TaskListOptions holds parameters to list tasks with.\ntype TaskListOptions struct {\n\tFilters filters.Args\n}\n\n// PluginRemoveOptions holds parameters to remove plugins.\ntype PluginRemoveOptions struct {\n\tForce bool\n}\n\n// PluginEnableOptions holds parameters to enable plugins.\ntype PluginEnableOptions struct {\n\tTimeout int\n}\n\n// PluginDisableOptions holds parameters to disable plugins.\ntype PluginDisableOptions struct {\n\tForce bool\n}\n\n// PluginInstallOptions holds parameters to install a plugin.\ntype PluginInstallOptions struct {\n\tDisabled              bool\n\tAcceptAllPermissions  bool\n\tRegistryAuth          string // RegistryAuth is the base64 encoded credentials for the registry\n\tRemoteRef             string // RemoteRef is the plugin name on the registry\n\tPrivilegeFunc         RequestPrivilegeFunc\n\tAcceptPermissionsFunc func(PluginPrivileges) (bool, error)\n\tArgs                  []string\n}\n\n// SwarmUnlockKeyResponse contains the response for Engine API:\n// GET /swarm/unlockkey\ntype SwarmUnlockKeyResponse struct {\n\t// UnlockKey is the unlock key in ASCII-armored format.\n\tUnlockKey string\n}\n\n// PluginCreateOptions hold all options to plugin create.\ntype PluginCreateOptions struct {\n\tRepoName string\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/configs.go",
    "content": "package types // import \"github.com/docker/docker/api/types\"\n\n// ExecConfig is a small subset of the Config struct that holds the configuration\n// for the exec feature of docker.\ntype ExecConfig struct {\n\tUser         string   // User that will run the command\n\tPrivileged   bool     // Is the container in privileged mode\n\tTty          bool     // Attach standard streams to a tty.\n\tConsoleSize  *[2]uint `json:\",omitempty\"` // Initial console size [height, width]\n\tAttachStdin  bool     // Attach the standard input, makes possible user interaction\n\tAttachStderr bool     // Attach the standard error\n\tAttachStdout bool     // Attach the standard output\n\tDetach       bool     // Execute in detach mode\n\tDetachKeys   string   // Escape keys for detach\n\tEnv          []string // Environment variables\n\tWorkingDir   string   // Working directory\n\tCmd          []string // Execution commands and args\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/change_type.go",
    "content": "package container\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// ChangeType Kind of change\n//\n// Can be one of:\n//\n// - `0`: Modified (\"C\")\n// - `1`: Added (\"A\")\n// - `2`: Deleted (\"D\")\n//\n// swagger:model ChangeType\ntype ChangeType uint8\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/change_types.go",
    "content": "package container\n\nconst (\n\t// ChangeModify represents the modify operation.\n\tChangeModify ChangeType = 0\n\t// ChangeAdd represents the add operation.\n\tChangeAdd ChangeType = 1\n\t// ChangeDelete represents the delete operation.\n\tChangeDelete ChangeType = 2\n)\n\nfunc (ct ChangeType) String() string {\n\tswitch ct {\n\tcase ChangeModify:\n\t\treturn \"C\"\n\tcase ChangeAdd:\n\t\treturn \"A\"\n\tcase ChangeDelete:\n\t\treturn \"D\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/config.go",
    "content": "package container // import \"github.com/docker/docker/api/types/container\"\n\nimport (\n\t\"io\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/strslice\"\n\tdockerspec \"github.com/docker/docker/image/spec/specs-go/v1\"\n\t\"github.com/docker/go-connections/nat\"\n)\n\n// MinimumDuration puts a minimum on user configured duration.\n// This is to prevent API error on time unit. For example, API may\n// set 3 as healthcheck interval with intention of 3 seconds, but\n// Docker interprets it as 3 nanoseconds.\nconst MinimumDuration = 1 * time.Millisecond\n\n// StopOptions holds the options to stop or restart a container.\ntype StopOptions struct {\n\t// Signal (optional) is the signal to send to the container to (gracefully)\n\t// stop it before forcibly terminating the container with SIGKILL after the\n\t// timeout expires. If not value is set, the default (SIGTERM) is used.\n\tSignal string `json:\",omitempty\"`\n\n\t// Timeout (optional) is the timeout (in seconds) to wait for the container\n\t// to stop gracefully before forcibly terminating it with SIGKILL.\n\t//\n\t// - Use nil to use the default timeout (10 seconds).\n\t// - Use '-1' to wait indefinitely.\n\t// - Use '0' to not wait for the container to exit gracefully, and\n\t//   immediately proceeds to forcibly terminating the container.\n\t// - Other positive values are used as timeout (in seconds).\n\tTimeout *int `json:\",omitempty\"`\n}\n\n// HealthConfig holds configuration settings for the HEALTHCHECK feature.\ntype HealthConfig = dockerspec.HealthcheckConfig\n\n// ExecStartOptions holds the options to start container's exec.\ntype ExecStartOptions struct {\n\tStdin       io.Reader\n\tStdout      io.Writer\n\tStderr      io.Writer\n\tConsoleSize *[2]uint `json:\",omitempty\"`\n}\n\n// Config contains the configuration data about a container.\n// It should hold only portable information about the container.\n// Here, \"portable\" means \"independent from the host we are running on\".\n// Non-portable information *should* appear in HostConfig.\n// All fields added to this struct must be marked `omitempty` to keep getting\n// predictable hashes from the old `v1Compatibility` configuration.\ntype Config struct {\n\tHostname        string              // Hostname\n\tDomainname      string              // Domainname\n\tUser            string              // User that will run the command(s) inside the container, also support user:group\n\tAttachStdin     bool                // Attach the standard input, makes possible user interaction\n\tAttachStdout    bool                // Attach the standard output\n\tAttachStderr    bool                // Attach the standard error\n\tExposedPorts    nat.PortSet         `json:\",omitempty\"` // List of exposed ports\n\tTty             bool                // Attach standard streams to a tty, including stdin if it is not closed.\n\tOpenStdin       bool                // Open stdin\n\tStdinOnce       bool                // If true, close stdin after the 1 attached client disconnects.\n\tEnv             []string            // List of environment variable to set in the container\n\tCmd             strslice.StrSlice   // Command to run when starting the container\n\tHealthcheck     *HealthConfig       `json:\",omitempty\"` // Healthcheck describes how to check the container is healthy\n\tArgsEscaped     bool                `json:\",omitempty\"` // True if command is already escaped (meaning treat as a command line) (Windows specific).\n\tImage           string              // Name of the image as it was passed by the operator (e.g. could be symbolic)\n\tVolumes         map[string]struct{} // List of volumes (mounts) used for the container\n\tWorkingDir      string              // Current directory (PWD) in the command will be launched\n\tEntrypoint      strslice.StrSlice   // Entrypoint to run when starting the container\n\tNetworkDisabled bool                `json:\",omitempty\"` // Is network disabled\n\t// Mac Address of the container.\n\t//\n\t// Deprecated: this field is deprecated since API v1.44. Use EndpointSettings.MacAddress instead.\n\tMacAddress  string            `json:\",omitempty\"`\n\tOnBuild     []string          // ONBUILD metadata that were defined on the image Dockerfile\n\tLabels      map[string]string // List of labels set to this container\n\tStopSignal  string            `json:\",omitempty\"` // Signal to stop a container\n\tStopTimeout *int              `json:\",omitempty\"` // Timeout (in seconds) to stop a container\n\tShell       strslice.StrSlice `json:\",omitempty\"` // Shell for shell-form of RUN, CMD, ENTRYPOINT\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/container_top.go",
    "content": "package container // import \"github.com/docker/docker/api/types/container\"\n\n// ----------------------------------------------------------------------------\n// Code generated by `swagger generate operation`. DO NOT EDIT.\n//\n// See hack/generate-swagger-api.sh\n// ----------------------------------------------------------------------------\n\n// ContainerTopOKBody OK response to ContainerTop operation\n// swagger:model ContainerTopOKBody\ntype ContainerTopOKBody struct {\n\n\t// Each process running in the container, where each is process\n\t// is an array of values corresponding to the titles.\n\t//\n\t// Required: true\n\tProcesses [][]string `json:\"Processes\"`\n\n\t// The ps column titles\n\t// Required: true\n\tTitles []string `json:\"Titles\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/container_update.go",
    "content": "package container // import \"github.com/docker/docker/api/types/container\"\n\n// ----------------------------------------------------------------------------\n// Code generated by `swagger generate operation`. DO NOT EDIT.\n//\n// See hack/generate-swagger-api.sh\n// ----------------------------------------------------------------------------\n\n// ContainerUpdateOKBody OK response to ContainerUpdate operation\n// swagger:model ContainerUpdateOKBody\ntype ContainerUpdateOKBody struct {\n\n\t// warnings\n\t// Required: true\n\tWarnings []string `json:\"Warnings\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/create_response.go",
    "content": "package container\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// CreateResponse ContainerCreateResponse\n//\n// OK response to ContainerCreate operation\n// swagger:model CreateResponse\ntype CreateResponse struct {\n\n\t// The ID of the created container\n\t// Required: true\n\tID string `json:\"Id\"`\n\n\t// Warnings encountered when creating the container\n\t// Required: true\n\tWarnings []string `json:\"Warnings\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/errors.go",
    "content": "package container\n\ntype errInvalidParameter struct{ error }\n\nfunc (e *errInvalidParameter) InvalidParameter() {}\n\nfunc (e *errInvalidParameter) Unwrap() error {\n\treturn e.error\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/filesystem_change.go",
    "content": "package container\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// FilesystemChange Change in the container's filesystem.\n//\n// swagger:model FilesystemChange\ntype FilesystemChange struct {\n\n\t// kind\n\t// Required: true\n\tKind ChangeType `json:\"Kind\"`\n\n\t// Path to file or directory that has changed.\n\t//\n\t// Required: true\n\tPath string `json:\"Path\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/hostconfig.go",
    "content": "package container // import \"github.com/docker/docker/api/types/container\"\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/blkiodev\"\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/strslice\"\n\t\"github.com/docker/go-connections/nat\"\n\tunits \"github.com/docker/go-units\"\n)\n\n// CgroupnsMode represents the cgroup namespace mode of the container\ntype CgroupnsMode string\n\n// cgroup namespace modes for containers\nconst (\n\tCgroupnsModeEmpty   CgroupnsMode = \"\"\n\tCgroupnsModePrivate CgroupnsMode = \"private\"\n\tCgroupnsModeHost    CgroupnsMode = \"host\"\n)\n\n// IsPrivate indicates whether the container uses its own private cgroup namespace\nfunc (c CgroupnsMode) IsPrivate() bool {\n\treturn c == CgroupnsModePrivate\n}\n\n// IsHost indicates whether the container shares the host's cgroup namespace\nfunc (c CgroupnsMode) IsHost() bool {\n\treturn c == CgroupnsModeHost\n}\n\n// IsEmpty indicates whether the container cgroup namespace mode is unset\nfunc (c CgroupnsMode) IsEmpty() bool {\n\treturn c == CgroupnsModeEmpty\n}\n\n// Valid indicates whether the cgroup namespace mode is valid\nfunc (c CgroupnsMode) Valid() bool {\n\treturn c.IsEmpty() || c.IsPrivate() || c.IsHost()\n}\n\n// Isolation represents the isolation technology of a container. The supported\n// values are platform specific\ntype Isolation string\n\n// Isolation modes for containers\nconst (\n\tIsolationEmpty   Isolation = \"\"        // IsolationEmpty is unspecified (same behavior as default)\n\tIsolationDefault Isolation = \"default\" // IsolationDefault is the default isolation mode on current daemon\n\tIsolationProcess Isolation = \"process\" // IsolationProcess is process isolation mode\n\tIsolationHyperV  Isolation = \"hyperv\"  // IsolationHyperV is HyperV isolation mode\n)\n\n// IsDefault indicates the default isolation technology of a container. On Linux this\n// is the native driver. On Windows, this is a Windows Server Container.\nfunc (i Isolation) IsDefault() bool {\n\t// TODO consider making isolation-mode strict (case-sensitive)\n\tv := Isolation(strings.ToLower(string(i)))\n\treturn v == IsolationDefault || v == IsolationEmpty\n}\n\n// IsHyperV indicates the use of a Hyper-V partition for isolation\nfunc (i Isolation) IsHyperV() bool {\n\t// TODO consider making isolation-mode strict (case-sensitive)\n\treturn Isolation(strings.ToLower(string(i))) == IsolationHyperV\n}\n\n// IsProcess indicates the use of process isolation\nfunc (i Isolation) IsProcess() bool {\n\t// TODO consider making isolation-mode strict (case-sensitive)\n\treturn Isolation(strings.ToLower(string(i))) == IsolationProcess\n}\n\n// IpcMode represents the container ipc stack.\ntype IpcMode string\n\n// IpcMode constants\nconst (\n\tIPCModeNone      IpcMode = \"none\"\n\tIPCModeHost      IpcMode = \"host\"\n\tIPCModeContainer IpcMode = \"container\"\n\tIPCModePrivate   IpcMode = \"private\"\n\tIPCModeShareable IpcMode = \"shareable\"\n)\n\n// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared.\nfunc (n IpcMode) IsPrivate() bool {\n\treturn n == IPCModePrivate\n}\n\n// IsHost indicates whether the container shares the host's ipc namespace.\nfunc (n IpcMode) IsHost() bool {\n\treturn n == IPCModeHost\n}\n\n// IsShareable indicates whether the container's ipc namespace can be shared with another container.\nfunc (n IpcMode) IsShareable() bool {\n\treturn n == IPCModeShareable\n}\n\n// IsContainer indicates whether the container uses another container's ipc namespace.\nfunc (n IpcMode) IsContainer() bool {\n\t_, ok := containerID(string(n))\n\treturn ok\n}\n\n// IsNone indicates whether container IpcMode is set to \"none\".\nfunc (n IpcMode) IsNone() bool {\n\treturn n == IPCModeNone\n}\n\n// IsEmpty indicates whether container IpcMode is empty\nfunc (n IpcMode) IsEmpty() bool {\n\treturn n == \"\"\n}\n\n// Valid indicates whether the ipc mode is valid.\nfunc (n IpcMode) Valid() bool {\n\t// TODO(thaJeztah): align with PidMode, and consider container-mode without a container name/ID to be invalid.\n\treturn n.IsEmpty() || n.IsNone() || n.IsPrivate() || n.IsHost() || n.IsShareable() || n.IsContainer()\n}\n\n// Container returns the name of the container ipc stack is going to be used.\nfunc (n IpcMode) Container() (idOrName string) {\n\tidOrName, _ = containerID(string(n))\n\treturn idOrName\n}\n\n// NetworkMode represents the container network stack.\ntype NetworkMode string\n\n// IsNone indicates whether container isn't using a network stack.\nfunc (n NetworkMode) IsNone() bool {\n\treturn n == network.NetworkNone\n}\n\n// IsDefault indicates whether container uses the default network stack.\nfunc (n NetworkMode) IsDefault() bool {\n\treturn n == network.NetworkDefault\n}\n\n// IsPrivate indicates whether container uses its private network stack.\nfunc (n NetworkMode) IsPrivate() bool {\n\treturn !(n.IsHost() || n.IsContainer())\n}\n\n// IsContainer indicates whether container uses a container network stack.\nfunc (n NetworkMode) IsContainer() bool {\n\t_, ok := containerID(string(n))\n\treturn ok\n}\n\n// ConnectedContainer is the id of the container which network this container is connected to.\nfunc (n NetworkMode) ConnectedContainer() (idOrName string) {\n\tidOrName, _ = containerID(string(n))\n\treturn idOrName\n}\n\n// UserDefined indicates user-created network\nfunc (n NetworkMode) UserDefined() string {\n\tif n.IsUserDefined() {\n\t\treturn string(n)\n\t}\n\treturn \"\"\n}\n\n// UsernsMode represents userns mode in the container.\ntype UsernsMode string\n\n// IsHost indicates whether the container uses the host's userns.\nfunc (n UsernsMode) IsHost() bool {\n\treturn n == \"host\"\n}\n\n// IsPrivate indicates whether the container uses the a private userns.\nfunc (n UsernsMode) IsPrivate() bool {\n\treturn !n.IsHost()\n}\n\n// Valid indicates whether the userns is valid.\nfunc (n UsernsMode) Valid() bool {\n\treturn n == \"\" || n.IsHost()\n}\n\n// CgroupSpec represents the cgroup to use for the container.\ntype CgroupSpec string\n\n// IsContainer indicates whether the container is using another container cgroup\nfunc (c CgroupSpec) IsContainer() bool {\n\t_, ok := containerID(string(c))\n\treturn ok\n}\n\n// Valid indicates whether the cgroup spec is valid.\nfunc (c CgroupSpec) Valid() bool {\n\t// TODO(thaJeztah): align with PidMode, and consider container-mode without a container name/ID to be invalid.\n\treturn c == \"\" || c.IsContainer()\n}\n\n// Container returns the ID or name of the container whose cgroup will be used.\nfunc (c CgroupSpec) Container() (idOrName string) {\n\tidOrName, _ = containerID(string(c))\n\treturn idOrName\n}\n\n// UTSMode represents the UTS namespace of the container.\ntype UTSMode string\n\n// IsPrivate indicates whether the container uses its private UTS namespace.\nfunc (n UTSMode) IsPrivate() bool {\n\treturn !n.IsHost()\n}\n\n// IsHost indicates whether the container uses the host's UTS namespace.\nfunc (n UTSMode) IsHost() bool {\n\treturn n == \"host\"\n}\n\n// Valid indicates whether the UTS namespace is valid.\nfunc (n UTSMode) Valid() bool {\n\treturn n == \"\" || n.IsHost()\n}\n\n// PidMode represents the pid namespace of the container.\ntype PidMode string\n\n// IsPrivate indicates whether the container uses its own new pid namespace.\nfunc (n PidMode) IsPrivate() bool {\n\treturn !(n.IsHost() || n.IsContainer())\n}\n\n// IsHost indicates whether the container uses the host's pid namespace.\nfunc (n PidMode) IsHost() bool {\n\treturn n == \"host\"\n}\n\n// IsContainer indicates whether the container uses a container's pid namespace.\nfunc (n PidMode) IsContainer() bool {\n\t_, ok := containerID(string(n))\n\treturn ok\n}\n\n// Valid indicates whether the pid namespace is valid.\nfunc (n PidMode) Valid() bool {\n\treturn n == \"\" || n.IsHost() || validContainer(string(n))\n}\n\n// Container returns the name of the container whose pid namespace is going to be used.\nfunc (n PidMode) Container() (idOrName string) {\n\tidOrName, _ = containerID(string(n))\n\treturn idOrName\n}\n\n// DeviceRequest represents a request for devices from a device driver.\n// Used by GPU device drivers.\ntype DeviceRequest struct {\n\tDriver       string            // Name of device driver\n\tCount        int               // Number of devices to request (-1 = All)\n\tDeviceIDs    []string          // List of device IDs as recognizable by the device driver\n\tCapabilities [][]string        // An OR list of AND lists of device capabilities (e.g. \"gpu\")\n\tOptions      map[string]string // Options to pass onto the device driver\n}\n\n// DeviceMapping represents the device mapping between the host and the container.\ntype DeviceMapping struct {\n\tPathOnHost        string\n\tPathInContainer   string\n\tCgroupPermissions string\n}\n\n// RestartPolicy represents the restart policies of the container.\ntype RestartPolicy struct {\n\tName              RestartPolicyMode\n\tMaximumRetryCount int\n}\n\ntype RestartPolicyMode string\n\nconst (\n\tRestartPolicyDisabled      RestartPolicyMode = \"no\"\n\tRestartPolicyAlways        RestartPolicyMode = \"always\"\n\tRestartPolicyOnFailure     RestartPolicyMode = \"on-failure\"\n\tRestartPolicyUnlessStopped RestartPolicyMode = \"unless-stopped\"\n)\n\n// IsNone indicates whether the container has the \"no\" restart policy.\n// This means the container will not automatically restart when exiting.\nfunc (rp *RestartPolicy) IsNone() bool {\n\treturn rp.Name == RestartPolicyDisabled || rp.Name == \"\"\n}\n\n// IsAlways indicates whether the container has the \"always\" restart policy.\n// This means the container will automatically restart regardless of the exit status.\nfunc (rp *RestartPolicy) IsAlways() bool {\n\treturn rp.Name == RestartPolicyAlways\n}\n\n// IsOnFailure indicates whether the container has the \"on-failure\" restart policy.\n// This means the container will automatically restart of exiting with a non-zero exit status.\nfunc (rp *RestartPolicy) IsOnFailure() bool {\n\treturn rp.Name == RestartPolicyOnFailure\n}\n\n// IsUnlessStopped indicates whether the container has the\n// \"unless-stopped\" restart policy. This means the container will\n// automatically restart unless user has put it to stopped state.\nfunc (rp *RestartPolicy) IsUnlessStopped() bool {\n\treturn rp.Name == RestartPolicyUnlessStopped\n}\n\n// IsSame compares two RestartPolicy to see if they are the same\nfunc (rp *RestartPolicy) IsSame(tp *RestartPolicy) bool {\n\treturn rp.Name == tp.Name && rp.MaximumRetryCount == tp.MaximumRetryCount\n}\n\n// ValidateRestartPolicy validates the given RestartPolicy.\nfunc ValidateRestartPolicy(policy RestartPolicy) error {\n\tswitch policy.Name {\n\tcase RestartPolicyAlways, RestartPolicyUnlessStopped, RestartPolicyDisabled:\n\t\tif policy.MaximumRetryCount != 0 {\n\t\t\tmsg := \"invalid restart policy: maximum retry count can only be used with 'on-failure'\"\n\t\t\tif policy.MaximumRetryCount < 0 {\n\t\t\t\tmsg += \" and cannot be negative\"\n\t\t\t}\n\t\t\treturn &errInvalidParameter{fmt.Errorf(msg)}\n\t\t}\n\t\treturn nil\n\tcase RestartPolicyOnFailure:\n\t\tif policy.MaximumRetryCount < 0 {\n\t\t\treturn &errInvalidParameter{fmt.Errorf(\"invalid restart policy: maximum retry count cannot be negative\")}\n\t\t}\n\t\treturn nil\n\tcase \"\":\n\t\t// Versions before v25.0.0 created an empty restart-policy \"name\" as\n\t\t// default. Allow an empty name with \"any\" MaximumRetryCount for\n\t\t// backward-compatibility.\n\t\treturn nil\n\tdefault:\n\t\treturn &errInvalidParameter{fmt.Errorf(\"invalid restart policy: unknown policy '%s'; use one of '%s', '%s', '%s', or '%s'\", policy.Name, RestartPolicyDisabled, RestartPolicyAlways, RestartPolicyOnFailure, RestartPolicyUnlessStopped)}\n\t}\n}\n\n// LogMode is a type to define the available modes for logging\n// These modes affect how logs are handled when log messages start piling up.\ntype LogMode string\n\n// Available logging modes\nconst (\n\tLogModeUnset    LogMode = \"\"\n\tLogModeBlocking LogMode = \"blocking\"\n\tLogModeNonBlock LogMode = \"non-blocking\"\n)\n\n// LogConfig represents the logging configuration of the container.\ntype LogConfig struct {\n\tType   string\n\tConfig map[string]string\n}\n\n// Resources contains container's resources (cgroups config, ulimits...)\ntype Resources struct {\n\t// Applicable to all platforms\n\tCPUShares int64 `json:\"CpuShares\"` // CPU shares (relative weight vs. other containers)\n\tMemory    int64 // Memory limit (in bytes)\n\tNanoCPUs  int64 `json:\"NanoCpus\"` // CPU quota in units of 10<sup>-9</sup> CPUs.\n\n\t// Applicable to UNIX platforms\n\tCgroupParent         string // Parent cgroup.\n\tBlkioWeight          uint16 // Block IO weight (relative weight vs. other containers)\n\tBlkioWeightDevice    []*blkiodev.WeightDevice\n\tBlkioDeviceReadBps   []*blkiodev.ThrottleDevice\n\tBlkioDeviceWriteBps  []*blkiodev.ThrottleDevice\n\tBlkioDeviceReadIOps  []*blkiodev.ThrottleDevice\n\tBlkioDeviceWriteIOps []*blkiodev.ThrottleDevice\n\tCPUPeriod            int64           `json:\"CpuPeriod\"`          // CPU CFS (Completely Fair Scheduler) period\n\tCPUQuota             int64           `json:\"CpuQuota\"`           // CPU CFS (Completely Fair Scheduler) quota\n\tCPURealtimePeriod    int64           `json:\"CpuRealtimePeriod\"`  // CPU real-time period\n\tCPURealtimeRuntime   int64           `json:\"CpuRealtimeRuntime\"` // CPU real-time runtime\n\tCpusetCpus           string          // CpusetCpus 0-2, 0,1\n\tCpusetMems           string          // CpusetMems 0-2, 0,1\n\tDevices              []DeviceMapping // List of devices to map inside the container\n\tDeviceCgroupRules    []string        // List of rule to be added to the device cgroup\n\tDeviceRequests       []DeviceRequest // List of device requests for device drivers\n\n\t// KernelMemory specifies the kernel memory limit (in bytes) for the container.\n\t// Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes.\n\tKernelMemory      int64           `json:\",omitempty\"`\n\tKernelMemoryTCP   int64           `json:\",omitempty\"` // Hard limit for kernel TCP buffer memory (in bytes)\n\tMemoryReservation int64           // Memory soft limit (in bytes)\n\tMemorySwap        int64           // Total memory usage (memory + swap); set `-1` to enable unlimited swap\n\tMemorySwappiness  *int64          // Tuning container memory swappiness behaviour\n\tOomKillDisable    *bool           // Whether to disable OOM Killer or not\n\tPidsLimit         *int64          // Setting PIDs limit for a container; Set `0` or `-1` for unlimited, or `null` to not change.\n\tUlimits           []*units.Ulimit // List of ulimits to be set in the container\n\n\t// Applicable to Windows\n\tCPUCount           int64  `json:\"CpuCount\"`   // CPU count\n\tCPUPercent         int64  `json:\"CpuPercent\"` // CPU percent\n\tIOMaximumIOps      uint64 // Maximum IOps for the container system drive\n\tIOMaximumBandwidth uint64 // Maximum IO in bytes per second for the container system drive\n}\n\n// UpdateConfig holds the mutable attributes of a Container.\n// Those attributes can be updated at runtime.\ntype UpdateConfig struct {\n\t// Contains container's resources (cgroups, ulimits)\n\tResources\n\tRestartPolicy RestartPolicy\n}\n\n// HostConfig the non-portable Config structure of a container.\n// Here, \"non-portable\" means \"dependent of the host we are running on\".\n// Portable information *should* appear in Config.\ntype HostConfig struct {\n\t// Applicable to all platforms\n\tBinds           []string          // List of volume bindings for this container\n\tContainerIDFile string            // File (path) where the containerId is written\n\tLogConfig       LogConfig         // Configuration of the logs for this container\n\tNetworkMode     NetworkMode       // Network mode to use for the container\n\tPortBindings    nat.PortMap       // Port mapping between the exposed port (container) and the host\n\tRestartPolicy   RestartPolicy     // Restart policy to be used for the container\n\tAutoRemove      bool              // Automatically remove container when it exits\n\tVolumeDriver    string            // Name of the volume driver used to mount volumes\n\tVolumesFrom     []string          // List of volumes to take from other container\n\tConsoleSize     [2]uint           // Initial console size (height,width)\n\tAnnotations     map[string]string `json:\",omitempty\"` // Arbitrary non-identifying metadata attached to container and provided to the runtime\n\n\t// Applicable to UNIX platforms\n\tCapAdd          strslice.StrSlice // List of kernel capabilities to add to the container\n\tCapDrop         strslice.StrSlice // List of kernel capabilities to remove from the container\n\tCgroupnsMode    CgroupnsMode      // Cgroup namespace mode to use for the container\n\tDNS             []string          `json:\"Dns\"`        // List of DNS server to lookup\n\tDNSOptions      []string          `json:\"DnsOptions\"` // List of DNSOption to look for\n\tDNSSearch       []string          `json:\"DnsSearch\"`  // List of DNSSearch to look for\n\tExtraHosts      []string          // List of extra hosts\n\tGroupAdd        []string          // List of additional groups that the container process will run as\n\tIpcMode         IpcMode           // IPC namespace to use for the container\n\tCgroup          CgroupSpec        // Cgroup to use for the container\n\tLinks           []string          // List of links (in the name:alias form)\n\tOomScoreAdj     int               // Container preference for OOM-killing\n\tPidMode         PidMode           // PID namespace to use for the container\n\tPrivileged      bool              // Is the container in privileged mode\n\tPublishAllPorts bool              // Should docker publish all exposed port for the container\n\tReadonlyRootfs  bool              // Is the container root filesystem in read-only\n\tSecurityOpt     []string          // List of string values to customize labels for MLS systems, such as SELinux.\n\tStorageOpt      map[string]string `json:\",omitempty\"` // Storage driver options per container.\n\tTmpfs           map[string]string `json:\",omitempty\"` // List of tmpfs (mounts) used for the container\n\tUTSMode         UTSMode           // UTS namespace to use for the container\n\tUsernsMode      UsernsMode        // The user namespace to use for the container\n\tShmSize         int64             // Total shm memory usage\n\tSysctls         map[string]string `json:\",omitempty\"` // List of Namespaced sysctls used for the container\n\tRuntime         string            `json:\",omitempty\"` // Runtime to use with this container\n\n\t// Applicable to Windows\n\tIsolation Isolation // Isolation technology of the container (e.g. default, hyperv)\n\n\t// Contains container's resources (cgroups, ulimits)\n\tResources\n\n\t// Mounts specs used by the container\n\tMounts []mount.Mount `json:\",omitempty\"`\n\n\t// MaskedPaths is the list of paths to be masked inside the container (this overrides the default set of paths)\n\tMaskedPaths []string\n\n\t// ReadonlyPaths is the list of paths to be set as read-only inside the container (this overrides the default set of paths)\n\tReadonlyPaths []string\n\n\t// Run a custom init inside the container, if null, use the daemon's configured settings\n\tInit *bool `json:\",omitempty\"`\n}\n\n// containerID splits \"container:<ID|name>\" values. It returns the container\n// ID or name, and whether an ID/name was found. It returns an empty string and\n// a \"false\" if the value does not have a \"container:\" prefix. Further validation\n// of the returned, including checking if the value is empty, should be handled\n// by the caller.\nfunc containerID(val string) (idOrName string, ok bool) {\n\tk, v, hasSep := strings.Cut(val, \":\")\n\tif !hasSep || k != \"container\" {\n\t\treturn \"\", false\n\t}\n\treturn v, true\n}\n\n// validContainer checks if the given value is a \"container:\" mode with\n// a non-empty name/ID.\nfunc validContainer(val string) bool {\n\tid, ok := containerID(val)\n\treturn ok && id != \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/hostconfig_unix.go",
    "content": "//go:build !windows\n\npackage container // import \"github.com/docker/docker/api/types/container\"\n\nimport \"github.com/docker/docker/api/types/network\"\n\n// IsValid indicates if an isolation technology is valid\nfunc (i Isolation) IsValid() bool {\n\treturn i.IsDefault()\n}\n\n// NetworkName returns the name of the network stack.\nfunc (n NetworkMode) NetworkName() string {\n\tif n.IsBridge() {\n\t\treturn network.NetworkBridge\n\t} else if n.IsHost() {\n\t\treturn network.NetworkHost\n\t} else if n.IsContainer() {\n\t\treturn \"container\"\n\t} else if n.IsNone() {\n\t\treturn network.NetworkNone\n\t} else if n.IsDefault() {\n\t\treturn network.NetworkDefault\n\t} else if n.IsUserDefined() {\n\t\treturn n.UserDefined()\n\t}\n\treturn \"\"\n}\n\n// IsBridge indicates whether container uses the bridge network stack\nfunc (n NetworkMode) IsBridge() bool {\n\treturn n == network.NetworkBridge\n}\n\n// IsHost indicates whether container uses the host network stack.\nfunc (n NetworkMode) IsHost() bool {\n\treturn n == network.NetworkHost\n}\n\n// IsUserDefined indicates user-created network\nfunc (n NetworkMode) IsUserDefined() bool {\n\treturn !n.IsDefault() && !n.IsBridge() && !n.IsHost() && !n.IsNone() && !n.IsContainer()\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/hostconfig_windows.go",
    "content": "package container // import \"github.com/docker/docker/api/types/container\"\n\nimport \"github.com/docker/docker/api/types/network\"\n\n// IsBridge indicates whether container uses the bridge network stack\n// in windows it is given the name NAT\nfunc (n NetworkMode) IsBridge() bool {\n\treturn n == network.NetworkNat\n}\n\n// IsHost indicates whether container uses the host network stack.\n// returns false as this is not supported by windows\nfunc (n NetworkMode) IsHost() bool {\n\treturn false\n}\n\n// IsUserDefined indicates user-created network\nfunc (n NetworkMode) IsUserDefined() bool {\n\treturn !n.IsDefault() && !n.IsNone() && !n.IsBridge() && !n.IsContainer()\n}\n\n// IsValid indicates if an isolation technology is valid\nfunc (i Isolation) IsValid() bool {\n\treturn i.IsDefault() || i.IsHyperV() || i.IsProcess()\n}\n\n// NetworkName returns the name of the network stack.\nfunc (n NetworkMode) NetworkName() string {\n\tif n.IsDefault() {\n\t\treturn network.NetworkDefault\n\t} else if n.IsBridge() {\n\t\treturn network.NetworkNat\n\t} else if n.IsNone() {\n\t\treturn network.NetworkNone\n\t} else if n.IsContainer() {\n\t\treturn \"container\"\n\t} else if n.IsUserDefined() {\n\t\treturn n.UserDefined()\n\t}\n\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/options.go",
    "content": "package container\n\nimport \"github.com/docker/docker/api/types/filters\"\n\n// ResizeOptions holds parameters to resize a TTY.\n// It can be used to resize container TTYs and\n// exec process TTYs too.\ntype ResizeOptions struct {\n\tHeight uint\n\tWidth  uint\n}\n\n// AttachOptions holds parameters to attach to a container.\ntype AttachOptions struct {\n\tStream     bool\n\tStdin      bool\n\tStdout     bool\n\tStderr     bool\n\tDetachKeys string\n\tLogs       bool\n}\n\n// CommitOptions holds parameters to commit changes into a container.\ntype CommitOptions struct {\n\tReference string\n\tComment   string\n\tAuthor    string\n\tChanges   []string\n\tPause     bool\n\tConfig    *Config\n}\n\n// RemoveOptions holds parameters to remove containers.\ntype RemoveOptions struct {\n\tRemoveVolumes bool\n\tRemoveLinks   bool\n\tForce         bool\n}\n\n// StartOptions holds parameters to start containers.\ntype StartOptions struct {\n\tCheckpointID  string\n\tCheckpointDir string\n}\n\n// ListOptions holds parameters to list containers with.\ntype ListOptions struct {\n\tSize    bool\n\tAll     bool\n\tLatest  bool\n\tSince   string\n\tBefore  string\n\tLimit   int\n\tFilters filters.Args\n}\n\n// LogsOptions holds parameters to filter logs with.\ntype LogsOptions struct {\n\tShowStdout bool\n\tShowStderr bool\n\tSince      string\n\tUntil      string\n\tTimestamps bool\n\tFollow     bool\n\tTail       string\n\tDetails    bool\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/wait_exit_error.go",
    "content": "package container\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// WaitExitError container waiting error, if any\n// swagger:model WaitExitError\ntype WaitExitError struct {\n\n\t// Details of an error\n\tMessage string `json:\"Message,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/wait_response.go",
    "content": "package container\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// WaitResponse ContainerWaitResponse\n//\n// OK response to ContainerWait operation\n// swagger:model WaitResponse\ntype WaitResponse struct {\n\n\t// error\n\tError *WaitExitError `json:\"Error,omitempty\"`\n\n\t// Exit code of the container\n\t// Required: true\n\tStatusCode int64 `json:\"StatusCode\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/container/waitcondition.go",
    "content": "package container // import \"github.com/docker/docker/api/types/container\"\n\n// WaitCondition is a type used to specify a container state for which\n// to wait.\ntype WaitCondition string\n\n// Possible WaitCondition Values.\n//\n// WaitConditionNotRunning (default) is used to wait for any of the non-running\n// states: \"created\", \"exited\", \"dead\", \"removing\", or \"removed\".\n//\n// WaitConditionNextExit is used to wait for the next time the state changes\n// to a non-running state. If the state is currently \"created\" or \"exited\",\n// this would cause Wait() to block until either the container runs and exits\n// or is removed.\n//\n// WaitConditionRemoved is used to wait for the container to be removed.\nconst (\n\tWaitConditionNotRunning WaitCondition = \"not-running\"\n\tWaitConditionNextExit   WaitCondition = \"next-exit\"\n\tWaitConditionRemoved    WaitCondition = \"removed\"\n)\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/error_response.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// ErrorResponse Represents an error.\n// swagger:model ErrorResponse\ntype ErrorResponse struct {\n\n\t// The error message.\n\t// Required: true\n\tMessage string `json:\"message\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/error_response_ext.go",
    "content": "package types\n\n// Error returns the error message\nfunc (e ErrorResponse) Error() string {\n\treturn e.Message\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/events/events.go",
    "content": "package events // import \"github.com/docker/docker/api/types/events\"\n\n// Type is used for event-types.\ntype Type string\n\n// List of known event types.\nconst (\n\tBuilderEventType   Type = \"builder\"   // BuilderEventType is the event type that the builder generates.\n\tConfigEventType    Type = \"config\"    // ConfigEventType is the event type that configs generate.\n\tContainerEventType Type = \"container\" // ContainerEventType is the event type that containers generate.\n\tDaemonEventType    Type = \"daemon\"    // DaemonEventType is the event type that daemon generate.\n\tImageEventType     Type = \"image\"     // ImageEventType is the event type that images generate.\n\tNetworkEventType   Type = \"network\"   // NetworkEventType is the event type that networks generate.\n\tNodeEventType      Type = \"node\"      // NodeEventType is the event type that nodes generate.\n\tPluginEventType    Type = \"plugin\"    // PluginEventType is the event type that plugins generate.\n\tSecretEventType    Type = \"secret\"    // SecretEventType is the event type that secrets generate.\n\tServiceEventType   Type = \"service\"   // ServiceEventType is the event type that services generate.\n\tVolumeEventType    Type = \"volume\"    // VolumeEventType is the event type that volumes generate.\n)\n\n// Action is used for event-actions.\ntype Action string\n\nconst (\n\tActionCreate       Action = \"create\"\n\tActionStart        Action = \"start\"\n\tActionRestart      Action = \"restart\"\n\tActionStop         Action = \"stop\"\n\tActionCheckpoint   Action = \"checkpoint\"\n\tActionPause        Action = \"pause\"\n\tActionUnPause      Action = \"unpause\"\n\tActionAttach       Action = \"attach\"\n\tActionDetach       Action = \"detach\"\n\tActionResize       Action = \"resize\"\n\tActionUpdate       Action = \"update\"\n\tActionRename       Action = \"rename\"\n\tActionKill         Action = \"kill\"\n\tActionDie          Action = \"die\"\n\tActionOOM          Action = \"oom\"\n\tActionDestroy      Action = \"destroy\"\n\tActionRemove       Action = \"remove\"\n\tActionCommit       Action = \"commit\"\n\tActionTop          Action = \"top\"\n\tActionCopy         Action = \"copy\"\n\tActionArchivePath  Action = \"archive-path\"\n\tActionExtractToDir Action = \"extract-to-dir\"\n\tActionExport       Action = \"export\"\n\tActionImport       Action = \"import\"\n\tActionSave         Action = \"save\"\n\tActionLoad         Action = \"load\"\n\tActionTag          Action = \"tag\"\n\tActionUnTag        Action = \"untag\"\n\tActionPush         Action = \"push\"\n\tActionPull         Action = \"pull\"\n\tActionPrune        Action = \"prune\"\n\tActionDelete       Action = \"delete\"\n\tActionEnable       Action = \"enable\"\n\tActionDisable      Action = \"disable\"\n\tActionConnect      Action = \"connect\"\n\tActionDisconnect   Action = \"disconnect\"\n\tActionReload       Action = \"reload\"\n\tActionMount        Action = \"mount\"\n\tActionUnmount      Action = \"unmount\"\n\n\t// ActionExecCreate is the prefix used for exec_create events. These\n\t// event-actions are commonly followed by a colon and space (\": \"),\n\t// and the command that's defined for the exec, for example:\n\t//\n\t//\texec_create: /bin/sh -c 'echo hello'\n\t//\n\t// This is far from ideal; it's a compromise to allow filtering and\n\t// to preserve backward-compatibility.\n\tActionExecCreate Action = \"exec_create\"\n\t// ActionExecStart is the prefix used for exec_create events. These\n\t// event-actions are commonly followed by a colon and space (\": \"),\n\t// and the command that's defined for the exec, for example:\n\t//\n\t//\texec_start: /bin/sh -c 'echo hello'\n\t//\n\t// This is far from ideal; it's a compromise to allow filtering and\n\t// to preserve backward-compatibility.\n\tActionExecStart  Action = \"exec_start\"\n\tActionExecDie    Action = \"exec_die\"\n\tActionExecDetach Action = \"exec_detach\"\n\n\t// ActionHealthStatus is the prefix to use for health_status events.\n\t//\n\t// Health-status events can either have a pre-defined status, in which\n\t// case the \"health_status\" action is followed by a colon, or can be\n\t// \"free-form\", in which case they're followed by the output of the\n\t// health-check output.\n\t//\n\t// This is far form ideal, and a compromise to allow filtering, and\n\t// to preserve backward-compatibility.\n\tActionHealthStatus          Action = \"health_status\"\n\tActionHealthStatusRunning   Action = \"health_status: running\"\n\tActionHealthStatusHealthy   Action = \"health_status: healthy\"\n\tActionHealthStatusUnhealthy Action = \"health_status: unhealthy\"\n)\n\n// Actor describes something that generates events,\n// like a container, or a network, or a volume.\n// It has a defined name and a set of attributes.\n// The container attributes are its labels, other actors\n// can generate these attributes from other properties.\ntype Actor struct {\n\tID         string\n\tAttributes map[string]string\n}\n\n// Message represents the information an event contains\ntype Message struct {\n\t// Deprecated information from JSONMessage.\n\t// With data only in container events.\n\tStatus string `json:\"status,omitempty\"` // Deprecated: use Action instead.\n\tID     string `json:\"id,omitempty\"`     // Deprecated: use Actor.ID instead.\n\tFrom   string `json:\"from,omitempty\"`   // Deprecated: use Actor.Attributes[\"image\"] instead.\n\n\tType   Type\n\tAction Action\n\tActor  Actor\n\t// Engine events are local scope. Cluster events are swarm scope.\n\tScope string `json:\"scope,omitempty\"`\n\n\tTime     int64 `json:\"time,omitempty\"`\n\tTimeNano int64 `json:\"timeNano,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/filters/errors.go",
    "content": "package filters\n\nimport \"fmt\"\n\n// invalidFilter indicates that the provided filter or its value is invalid\ntype invalidFilter struct {\n\tFilter string\n\tValue  []string\n}\n\nfunc (e invalidFilter) Error() string {\n\tmsg := \"invalid filter\"\n\tif e.Filter != \"\" {\n\t\tmsg += \" '\" + e.Filter\n\t\tif e.Value != nil {\n\t\t\tmsg = fmt.Sprintf(\"%s=%s\", msg, e.Value)\n\t\t}\n\t\tmsg += \"'\"\n\t}\n\treturn msg\n}\n\n// InvalidParameter marks this error as ErrInvalidParameter\nfunc (e invalidFilter) InvalidParameter() {}\n\n// unreachableCode is an error indicating that the code path was not expected to be reached.\ntype unreachableCode struct {\n\tFilter string\n\tValue  []string\n}\n\n// System marks this error as ErrSystem\nfunc (e unreachableCode) System() {}\n\nfunc (e unreachableCode) Error() string {\n\treturn fmt.Sprintf(\"unreachable code reached for filter: %q with values: %s\", e.Filter, e.Value)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/filters/parse.go",
    "content": "/*\nPackage filters provides tools for encoding a mapping of keys to a set of\nmultiple values.\n*/\npackage filters // import \"github.com/docker/docker/api/types/filters\"\n\nimport (\n\t\"encoding/json\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// Args stores a mapping of keys to a set of multiple values.\ntype Args struct {\n\tfields map[string]map[string]bool\n}\n\n// KeyValuePair are used to initialize a new Args\ntype KeyValuePair struct {\n\tKey   string\n\tValue string\n}\n\n// Arg creates a new KeyValuePair for initializing Args\nfunc Arg(key, value string) KeyValuePair {\n\treturn KeyValuePair{Key: key, Value: value}\n}\n\n// NewArgs returns a new Args populated with the initial args\nfunc NewArgs(initialArgs ...KeyValuePair) Args {\n\targs := Args{fields: map[string]map[string]bool{}}\n\tfor _, arg := range initialArgs {\n\t\targs.Add(arg.Key, arg.Value)\n\t}\n\treturn args\n}\n\n// Keys returns all the keys in list of Args\nfunc (args Args) Keys() []string {\n\tkeys := make([]string, 0, len(args.fields))\n\tfor k := range args.fields {\n\t\tkeys = append(keys, k)\n\t}\n\treturn keys\n}\n\n// MarshalJSON returns a JSON byte representation of the Args\nfunc (args Args) MarshalJSON() ([]byte, error) {\n\tif len(args.fields) == 0 {\n\t\treturn []byte(\"{}\"), nil\n\t}\n\treturn json.Marshal(args.fields)\n}\n\n// ToJSON returns the Args as a JSON encoded string\nfunc ToJSON(a Args) (string, error) {\n\tif a.Len() == 0 {\n\t\treturn \"\", nil\n\t}\n\tbuf, err := json.Marshal(a)\n\treturn string(buf), err\n}\n\n// ToParamWithVersion encodes Args as a JSON string. If version is less than 1.22\n// then the encoded format will use an older legacy format where the values are a\n// list of strings, instead of a set.\n//\n// Deprecated: do not use in any new code; use ToJSON instead\nfunc ToParamWithVersion(version string, a Args) (string, error) {\n\tif a.Len() == 0 {\n\t\treturn \"\", nil\n\t}\n\n\tif version != \"\" && versions.LessThan(version, \"1.22\") {\n\t\tbuf, err := json.Marshal(convertArgsToSlice(a.fields))\n\t\treturn string(buf), err\n\t}\n\n\treturn ToJSON(a)\n}\n\n// FromJSON decodes a JSON encoded string into Args\nfunc FromJSON(p string) (Args, error) {\n\targs := NewArgs()\n\n\tif p == \"\" {\n\t\treturn args, nil\n\t}\n\n\traw := []byte(p)\n\terr := json.Unmarshal(raw, &args)\n\tif err == nil {\n\t\treturn args, nil\n\t}\n\n\t// Fallback to parsing arguments in the legacy slice format\n\tdeprecated := map[string][]string{}\n\tif legacyErr := json.Unmarshal(raw, &deprecated); legacyErr != nil {\n\t\treturn args, &invalidFilter{}\n\t}\n\n\targs.fields = deprecatedArgs(deprecated)\n\treturn args, nil\n}\n\n// UnmarshalJSON populates the Args from JSON encode bytes\nfunc (args Args) UnmarshalJSON(raw []byte) error {\n\treturn json.Unmarshal(raw, &args.fields)\n}\n\n// Get returns the list of values associated with the key\nfunc (args Args) Get(key string) []string {\n\tvalues := args.fields[key]\n\tif values == nil {\n\t\treturn make([]string, 0)\n\t}\n\tslice := make([]string, 0, len(values))\n\tfor key := range values {\n\t\tslice = append(slice, key)\n\t}\n\treturn slice\n}\n\n// Add a new value to the set of values\nfunc (args Args) Add(key, value string) {\n\tif _, ok := args.fields[key]; ok {\n\t\targs.fields[key][value] = true\n\t} else {\n\t\targs.fields[key] = map[string]bool{value: true}\n\t}\n}\n\n// Del removes a value from the set\nfunc (args Args) Del(key, value string) {\n\tif _, ok := args.fields[key]; ok {\n\t\tdelete(args.fields[key], value)\n\t\tif len(args.fields[key]) == 0 {\n\t\t\tdelete(args.fields, key)\n\t\t}\n\t}\n}\n\n// Len returns the number of keys in the mapping\nfunc (args Args) Len() int {\n\treturn len(args.fields)\n}\n\n// MatchKVList returns true if all the pairs in sources exist as key=value\n// pairs in the mapping at key, or if there are no values at key.\nfunc (args Args) MatchKVList(key string, sources map[string]string) bool {\n\tfieldValues := args.fields[key]\n\n\t// do not filter if there is no filter set or cannot determine filter\n\tif len(fieldValues) == 0 {\n\t\treturn true\n\t}\n\n\tif len(sources) == 0 {\n\t\treturn false\n\t}\n\n\tfor value := range fieldValues {\n\t\ttestK, testV, hasValue := strings.Cut(value, \"=\")\n\n\t\tv, ok := sources[testK]\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tif hasValue && testV != v {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n// Match returns true if any of the values at key match the source string\nfunc (args Args) Match(field, source string) bool {\n\tif args.ExactMatch(field, source) {\n\t\treturn true\n\t}\n\n\tfieldValues := args.fields[field]\n\tfor name2match := range fieldValues {\n\t\tmatch, err := regexp.MatchString(name2match, source)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif match {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// GetBoolOrDefault returns a boolean value of the key if the key is present\n// and is intepretable as a boolean value. Otherwise the default value is returned.\n// Error is not nil only if the filter values are not valid boolean or are conflicting.\nfunc (args Args) GetBoolOrDefault(key string, defaultValue bool) (bool, error) {\n\tfieldValues, ok := args.fields[key]\n\n\tif !ok {\n\t\treturn defaultValue, nil\n\t}\n\n\tif len(fieldValues) == 0 {\n\t\treturn defaultValue, &invalidFilter{key, nil}\n\t}\n\n\tisFalse := fieldValues[\"0\"] || fieldValues[\"false\"]\n\tisTrue := fieldValues[\"1\"] || fieldValues[\"true\"]\n\n\tconflicting := isFalse && isTrue\n\tinvalid := !isFalse && !isTrue\n\n\tif conflicting || invalid {\n\t\treturn defaultValue, &invalidFilter{key, args.Get(key)}\n\t} else if isFalse {\n\t\treturn false, nil\n\t} else if isTrue {\n\t\treturn true, nil\n\t}\n\n\t// This code shouldn't be reached.\n\treturn defaultValue, &unreachableCode{Filter: key, Value: args.Get(key)}\n}\n\n// ExactMatch returns true if the source matches exactly one of the values.\nfunc (args Args) ExactMatch(key, source string) bool {\n\tfieldValues, ok := args.fields[key]\n\t// do not filter if there is no filter set or cannot determine filter\n\tif !ok || len(fieldValues) == 0 {\n\t\treturn true\n\t}\n\n\t// try to match full name value to avoid O(N) regular expression matching\n\treturn fieldValues[source]\n}\n\n// UniqueExactMatch returns true if there is only one value and the source\n// matches exactly the value.\nfunc (args Args) UniqueExactMatch(key, source string) bool {\n\tfieldValues := args.fields[key]\n\t// do not filter if there is no filter set or cannot determine filter\n\tif len(fieldValues) == 0 {\n\t\treturn true\n\t}\n\tif len(args.fields[key]) != 1 {\n\t\treturn false\n\t}\n\n\t// try to match full name value to avoid O(N) regular expression matching\n\treturn fieldValues[source]\n}\n\n// FuzzyMatch returns true if the source matches exactly one value,  or the\n// source has one of the values as a prefix.\nfunc (args Args) FuzzyMatch(key, source string) bool {\n\tif args.ExactMatch(key, source) {\n\t\treturn true\n\t}\n\n\tfieldValues := args.fields[key]\n\tfor prefix := range fieldValues {\n\t\tif strings.HasPrefix(source, prefix) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Contains returns true if the key exists in the mapping\nfunc (args Args) Contains(field string) bool {\n\t_, ok := args.fields[field]\n\treturn ok\n}\n\n// Validate compared the set of accepted keys against the keys in the mapping.\n// An error is returned if any mapping keys are not in the accepted set.\nfunc (args Args) Validate(accepted map[string]bool) error {\n\tfor name := range args.fields {\n\t\tif !accepted[name] {\n\t\t\treturn &invalidFilter{name, nil}\n\t\t}\n\t}\n\treturn nil\n}\n\n// WalkValues iterates over the list of values for a key in the mapping and calls\n// op() for each value. If op returns an error the iteration stops and the\n// error is returned.\nfunc (args Args) WalkValues(field string, op func(value string) error) error {\n\tif _, ok := args.fields[field]; !ok {\n\t\treturn nil\n\t}\n\tfor v := range args.fields[field] {\n\t\tif err := op(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Clone returns a copy of args.\nfunc (args Args) Clone() (newArgs Args) {\n\tnewArgs.fields = make(map[string]map[string]bool, len(args.fields))\n\tfor k, m := range args.fields {\n\t\tvar mm map[string]bool\n\t\tif m != nil {\n\t\t\tmm = make(map[string]bool, len(m))\n\t\t\tfor kk, v := range m {\n\t\t\t\tmm[kk] = v\n\t\t\t}\n\t\t}\n\t\tnewArgs.fields[k] = mm\n\t}\n\treturn newArgs\n}\n\nfunc deprecatedArgs(d map[string][]string) map[string]map[string]bool {\n\tm := map[string]map[string]bool{}\n\tfor k, v := range d {\n\t\tvalues := map[string]bool{}\n\t\tfor _, vv := range v {\n\t\t\tvalues[vv] = true\n\t\t}\n\t\tm[k] = values\n\t}\n\treturn m\n}\n\nfunc convertArgsToSlice(f map[string]map[string]bool) map[string][]string {\n\tm := map[string][]string{}\n\tfor k, v := range f {\n\t\tvalues := []string{}\n\t\tfor kk := range v {\n\t\t\tif v[kk] {\n\t\t\t\tvalues = append(values, kk)\n\t\t\t}\n\t\t}\n\t\tm[k] = values\n\t}\n\treturn m\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/graph_driver_data.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// GraphDriverData Information about the storage driver used to store the container's and\n// image's filesystem.\n//\n// swagger:model GraphDriverData\ntype GraphDriverData struct {\n\n\t// Low-level storage metadata, provided as key/value pairs.\n\t//\n\t// This information is driver-specific, and depends on the storage-driver\n\t// in use, and should be used for informational purposes only.\n\t//\n\t// Required: true\n\tData map[string]string `json:\"Data\"`\n\n\t// Name of the storage driver.\n\t// Required: true\n\tName string `json:\"Name\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/id_response.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// IDResponse Response to an API call that returns just an Id\n// swagger:model IdResponse\ntype IDResponse struct {\n\n\t// The id of the newly created object.\n\t// Required: true\n\tID string `json:\"Id\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/image/delete_response.go",
    "content": "package image\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// DeleteResponse delete response\n// swagger:model DeleteResponse\ntype DeleteResponse struct {\n\n\t// The image ID of an image that was deleted\n\tDeleted string `json:\"Deleted,omitempty\"`\n\n\t// The image ID of an image that was untagged\n\tUntagged string `json:\"Untagged,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/image/image.go",
    "content": "package image\n\nimport \"time\"\n\n// Metadata contains engine-local data about the image.\ntype Metadata struct {\n\t// LastTagTime is the date and time at which the image was last tagged.\n\tLastTagTime time.Time `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/image/image_history.go",
    "content": "package image // import \"github.com/docker/docker/api/types/image\"\n\n// ----------------------------------------------------------------------------\n// Code generated by `swagger generate operation`. DO NOT EDIT.\n//\n// See hack/generate-swagger-api.sh\n// ----------------------------------------------------------------------------\n\n// HistoryResponseItem individual image layer information in response to ImageHistory operation\n// swagger:model HistoryResponseItem\ntype HistoryResponseItem struct {\n\n\t// comment\n\t// Required: true\n\tComment string `json:\"Comment\"`\n\n\t// created\n\t// Required: true\n\tCreated int64 `json:\"Created\"`\n\n\t// created by\n\t// Required: true\n\tCreatedBy string `json:\"CreatedBy\"`\n\n\t// Id\n\t// Required: true\n\tID string `json:\"Id\"`\n\n\t// size\n\t// Required: true\n\tSize int64 `json:\"Size\"`\n\n\t// tags\n\t// Required: true\n\tTags []string `json:\"Tags\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/image/opts.go",
    "content": "package image\n\nimport ocispec \"github.com/opencontainers/image-spec/specs-go/v1\"\n\n// GetImageOpts holds parameters to inspect an image.\ntype GetImageOpts struct {\n\tPlatform *ocispec.Platform\n\tDetails  bool\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/image/summary.go",
    "content": "package image\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// Summary summary\n// swagger:model Summary\ntype Summary struct {\n\n\t// Number of containers using this image. Includes both stopped and running\n\t// containers.\n\t//\n\t// This size is not calculated by default, and depends on which API endpoint\n\t// is used. `-1` indicates that the value has not been set / calculated.\n\t//\n\t// Required: true\n\tContainers int64 `json:\"Containers\"`\n\n\t// Date and time at which the image was created as a Unix timestamp\n\t// (number of seconds sinds EPOCH).\n\t//\n\t// Required: true\n\tCreated int64 `json:\"Created\"`\n\n\t// ID is the content-addressable ID of an image.\n\t//\n\t// This identifier is a content-addressable digest calculated from the\n\t// image's configuration (which includes the digests of layers used by\n\t// the image).\n\t//\n\t// Note that this digest differs from the `RepoDigests` below, which\n\t// holds digests of image manifests that reference the image.\n\t//\n\t// Required: true\n\tID string `json:\"Id\"`\n\n\t// User-defined key/value metadata.\n\t// Required: true\n\tLabels map[string]string `json:\"Labels\"`\n\n\t// ID of the parent image.\n\t//\n\t// Depending on how the image was created, this field may be empty and\n\t// is only set for images that were built/created locally. This field\n\t// is empty if the image was pulled from an image registry.\n\t//\n\t// Required: true\n\tParentID string `json:\"ParentId\"`\n\n\t// List of content-addressable digests of locally available image manifests\n\t// that the image is referenced from. Multiple manifests can refer to the\n\t// same image.\n\t//\n\t// These digests are usually only available if the image was either pulled\n\t// from a registry, or if the image was pushed to a registry, which is when\n\t// the manifest is generated and its digest calculated.\n\t//\n\t// Required: true\n\tRepoDigests []string `json:\"RepoDigests\"`\n\n\t// List of image names/tags in the local image cache that reference this\n\t// image.\n\t//\n\t// Multiple image tags can refer to the same image, and this list may be\n\t// empty if no tags reference the image, in which case the image is\n\t// \"untagged\", in which case it can still be referenced by its ID.\n\t//\n\t// Required: true\n\tRepoTags []string `json:\"RepoTags\"`\n\n\t// Total size of image layers that are shared between this image and other\n\t// images.\n\t//\n\t// This size is not calculated by default. `-1` indicates that the value\n\t// has not been set / calculated.\n\t//\n\t// Required: true\n\tSharedSize int64 `json:\"SharedSize\"`\n\n\t// Total size of the image including all layers it is composed of.\n\t//\n\t// Required: true\n\tSize int64 `json:\"Size\"`\n\n\t// Total size of the image including all layers it is composed of.\n\t//\n\t// Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead.\n\tVirtualSize int64 `json:\"VirtualSize,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/mount/mount.go",
    "content": "package mount // import \"github.com/docker/docker/api/types/mount\"\n\nimport (\n\t\"os\"\n)\n\n// Type represents the type of a mount.\ntype Type string\n\n// Type constants\nconst (\n\t// TypeBind is the type for mounting host dir\n\tTypeBind Type = \"bind\"\n\t// TypeVolume is the type for remote storage volumes\n\tTypeVolume Type = \"volume\"\n\t// TypeTmpfs is the type for mounting tmpfs\n\tTypeTmpfs Type = \"tmpfs\"\n\t// TypeNamedPipe is the type for mounting Windows named pipes\n\tTypeNamedPipe Type = \"npipe\"\n\t// TypeCluster is the type for Swarm Cluster Volumes.\n\tTypeCluster Type = \"cluster\"\n)\n\n// Mount represents a mount (volume).\ntype Mount struct {\n\tType Type `json:\",omitempty\"`\n\t// Source specifies the name of the mount. Depending on mount type, this\n\t// may be a volume name or a host path, or even ignored.\n\t// Source is not supported for tmpfs (must be an empty value)\n\tSource      string      `json:\",omitempty\"`\n\tTarget      string      `json:\",omitempty\"`\n\tReadOnly    bool        `json:\",omitempty\"` // attempts recursive read-only if possible\n\tConsistency Consistency `json:\",omitempty\"`\n\n\tBindOptions    *BindOptions    `json:\",omitempty\"`\n\tVolumeOptions  *VolumeOptions  `json:\",omitempty\"`\n\tTmpfsOptions   *TmpfsOptions   `json:\",omitempty\"`\n\tClusterOptions *ClusterOptions `json:\",omitempty\"`\n}\n\n// Propagation represents the propagation of a mount.\ntype Propagation string\n\nconst (\n\t// PropagationRPrivate RPRIVATE\n\tPropagationRPrivate Propagation = \"rprivate\"\n\t// PropagationPrivate PRIVATE\n\tPropagationPrivate Propagation = \"private\"\n\t// PropagationRShared RSHARED\n\tPropagationRShared Propagation = \"rshared\"\n\t// PropagationShared SHARED\n\tPropagationShared Propagation = \"shared\"\n\t// PropagationRSlave RSLAVE\n\tPropagationRSlave Propagation = \"rslave\"\n\t// PropagationSlave SLAVE\n\tPropagationSlave Propagation = \"slave\"\n)\n\n// Propagations is the list of all valid mount propagations\nvar Propagations = []Propagation{\n\tPropagationRPrivate,\n\tPropagationPrivate,\n\tPropagationRShared,\n\tPropagationShared,\n\tPropagationRSlave,\n\tPropagationSlave,\n}\n\n// Consistency represents the consistency requirements of a mount.\ntype Consistency string\n\nconst (\n\t// ConsistencyFull guarantees bind mount-like consistency\n\tConsistencyFull Consistency = \"consistent\"\n\t// ConsistencyCached mounts can cache read data and FS structure\n\tConsistencyCached Consistency = \"cached\"\n\t// ConsistencyDelegated mounts can cache read and written data and structure\n\tConsistencyDelegated Consistency = \"delegated\"\n\t// ConsistencyDefault provides \"consistent\" behavior unless overridden\n\tConsistencyDefault Consistency = \"default\"\n)\n\n// BindOptions defines options specific to mounts of type \"bind\".\ntype BindOptions struct {\n\tPropagation      Propagation `json:\",omitempty\"`\n\tNonRecursive     bool        `json:\",omitempty\"`\n\tCreateMountpoint bool        `json:\",omitempty\"`\n\t// ReadOnlyNonRecursive makes the mount non-recursively read-only, but still leaves the mount recursive\n\t// (unless NonRecursive is set to true in conjunction).\n\tReadOnlyNonRecursive bool `json:\",omitempty\"`\n\t// ReadOnlyForceRecursive raises an error if the mount cannot be made recursively read-only.\n\tReadOnlyForceRecursive bool `json:\",omitempty\"`\n}\n\n// VolumeOptions represents the options for a mount of type volume.\ntype VolumeOptions struct {\n\tNoCopy       bool              `json:\",omitempty\"`\n\tLabels       map[string]string `json:\",omitempty\"`\n\tDriverConfig *Driver           `json:\",omitempty\"`\n}\n\n// Driver represents a volume driver.\ntype Driver struct {\n\tName    string            `json:\",omitempty\"`\n\tOptions map[string]string `json:\",omitempty\"`\n}\n\n// TmpfsOptions defines options specific to mounts of type \"tmpfs\".\ntype TmpfsOptions struct {\n\t// Size sets the size of the tmpfs, in bytes.\n\t//\n\t// This will be converted to an operating system specific value\n\t// depending on the host. For example, on linux, it will be converted to\n\t// use a 'k', 'm' or 'g' syntax. BSD, though not widely supported with\n\t// docker, uses a straight byte value.\n\t//\n\t// Percentages are not supported.\n\tSizeBytes int64 `json:\",omitempty\"`\n\t// Mode of the tmpfs upon creation\n\tMode os.FileMode `json:\",omitempty\"`\n\n\t// TODO(stevvooe): There are several more tmpfs flags, specified in the\n\t// daemon, that are accepted. Only the most basic are added for now.\n\t//\n\t// From https://github.com/moby/sys/blob/mount/v0.1.1/mount/flags.go#L47-L56\n\t//\n\t// var validFlags = map[string]bool{\n\t// \t\"\":          true,\n\t// \t\"size\":      true, X\n\t// \t\"mode\":      true, X\n\t// \t\"uid\":       true,\n\t// \t\"gid\":       true,\n\t// \t\"nr_inodes\": true,\n\t// \t\"nr_blocks\": true,\n\t// \t\"mpol\":      true,\n\t// }\n\t//\n\t// Some of these may be straightforward to add, but others, such as\n\t// uid/gid have implications in a clustered system.\n}\n\n// ClusterOptions specifies options for a Cluster volume.\ntype ClusterOptions struct {\n\t// intentionally empty\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/network/endpoint.go",
    "content": "package network\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\n\t\"github.com/docker/docker/internal/multierror\"\n)\n\n// EndpointSettings stores the network endpoint details\ntype EndpointSettings struct {\n\t// Configurations\n\tIPAMConfig *EndpointIPAMConfig\n\tLinks      []string\n\tAliases    []string // Aliases holds the list of extra, user-specified DNS names for this endpoint.\n\t// MacAddress may be used to specify a MAC address when the container is created.\n\t// Once the container is running, it becomes operational data (it may contain a\n\t// generated address).\n\tMacAddress string\n\t// Operational data\n\tNetworkID           string\n\tEndpointID          string\n\tGateway             string\n\tIPAddress           string\n\tIPPrefixLen         int\n\tIPv6Gateway         string\n\tGlobalIPv6Address   string\n\tGlobalIPv6PrefixLen int\n\tDriverOpts          map[string]string\n\t// DNSNames holds all the (non fully qualified) DNS names associated to this endpoint. First entry is used to\n\t// generate PTR records.\n\tDNSNames []string\n}\n\n// Copy makes a deep copy of `EndpointSettings`\nfunc (es *EndpointSettings) Copy() *EndpointSettings {\n\tepCopy := *es\n\tif es.IPAMConfig != nil {\n\t\tepCopy.IPAMConfig = es.IPAMConfig.Copy()\n\t}\n\n\tif es.Links != nil {\n\t\tlinks := make([]string, 0, len(es.Links))\n\t\tepCopy.Links = append(links, es.Links...)\n\t}\n\n\tif es.Aliases != nil {\n\t\taliases := make([]string, 0, len(es.Aliases))\n\t\tepCopy.Aliases = append(aliases, es.Aliases...)\n\t}\n\n\tif len(es.DNSNames) > 0 {\n\t\tepCopy.DNSNames = make([]string, len(es.DNSNames))\n\t\tcopy(epCopy.DNSNames, es.DNSNames)\n\t}\n\n\treturn &epCopy\n}\n\n// EndpointIPAMConfig represents IPAM configurations for the endpoint\ntype EndpointIPAMConfig struct {\n\tIPv4Address  string   `json:\",omitempty\"`\n\tIPv6Address  string   `json:\",omitempty\"`\n\tLinkLocalIPs []string `json:\",omitempty\"`\n}\n\n// Copy makes a copy of the endpoint ipam config\nfunc (cfg *EndpointIPAMConfig) Copy() *EndpointIPAMConfig {\n\tcfgCopy := *cfg\n\tcfgCopy.LinkLocalIPs = make([]string, 0, len(cfg.LinkLocalIPs))\n\tcfgCopy.LinkLocalIPs = append(cfgCopy.LinkLocalIPs, cfg.LinkLocalIPs...)\n\treturn &cfgCopy\n}\n\n// NetworkSubnet describes a user-defined subnet for a specific network. It's only used to validate if an\n// EndpointIPAMConfig is valid for a specific network.\ntype NetworkSubnet interface {\n\t// Contains checks whether the NetworkSubnet contains [addr].\n\tContains(addr net.IP) bool\n\t// IsStatic checks whether the subnet was statically allocated (ie. user-defined).\n\tIsStatic() bool\n}\n\n// IsInRange checks whether static IP addresses are valid in a specific network.\nfunc (cfg *EndpointIPAMConfig) IsInRange(v4Subnets []NetworkSubnet, v6Subnets []NetworkSubnet) error {\n\tvar errs []error\n\n\tif err := validateEndpointIPAddress(cfg.IPv4Address, v4Subnets); err != nil {\n\t\terrs = append(errs, err)\n\t}\n\tif err := validateEndpointIPAddress(cfg.IPv6Address, v6Subnets); err != nil {\n\t\terrs = append(errs, err)\n\t}\n\n\treturn multierror.Join(errs...)\n}\n\nfunc validateEndpointIPAddress(epAddr string, ipamSubnets []NetworkSubnet) error {\n\tif epAddr == \"\" {\n\t\treturn nil\n\t}\n\n\tvar staticSubnet bool\n\tparsedAddr := net.ParseIP(epAddr)\n\tfor _, subnet := range ipamSubnets {\n\t\tif subnet.IsStatic() {\n\t\t\tstaticSubnet = true\n\t\t\tif subnet.Contains(parsedAddr) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\n\tif staticSubnet {\n\t\treturn fmt.Errorf(\"no configured subnet or ip-range contain the IP address %s\", epAddr)\n\t}\n\n\treturn errors.New(\"user specified IP address is supported only when connecting to networks with user configured subnets\")\n}\n\n// Validate checks whether cfg is valid.\nfunc (cfg *EndpointIPAMConfig) Validate() error {\n\tif cfg == nil {\n\t\treturn nil\n\t}\n\n\tvar errs []error\n\n\tif cfg.IPv4Address != \"\" {\n\t\tif addr := net.ParseIP(cfg.IPv4Address); addr == nil || addr.To4() == nil || addr.IsUnspecified() {\n\t\t\terrs = append(errs, fmt.Errorf(\"invalid IPv4 address: %s\", cfg.IPv4Address))\n\t\t}\n\t}\n\tif cfg.IPv6Address != \"\" {\n\t\tif addr := net.ParseIP(cfg.IPv6Address); addr == nil || addr.To4() != nil || addr.IsUnspecified() {\n\t\t\terrs = append(errs, fmt.Errorf(\"invalid IPv6 address: %s\", cfg.IPv6Address))\n\t\t}\n\t}\n\tfor _, addr := range cfg.LinkLocalIPs {\n\t\tif parsed := net.ParseIP(addr); parsed == nil || parsed.IsUnspecified() {\n\t\t\terrs = append(errs, fmt.Errorf(\"invalid link-local IP address: %s\", addr))\n\t\t}\n\t}\n\n\treturn multierror.Join(errs...)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/network/ipam.go",
    "content": "package network\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/netip\"\n\n\t\"github.com/docker/docker/internal/multierror\"\n)\n\n// IPAM represents IP Address Management\ntype IPAM struct {\n\tDriver  string\n\tOptions map[string]string // Per network IPAM driver options\n\tConfig  []IPAMConfig\n}\n\n// IPAMConfig represents IPAM configurations\ntype IPAMConfig struct {\n\tSubnet     string            `json:\",omitempty\"`\n\tIPRange    string            `json:\",omitempty\"`\n\tGateway    string            `json:\",omitempty\"`\n\tAuxAddress map[string]string `json:\"AuxiliaryAddresses,omitempty\"`\n}\n\ntype ipFamily string\n\nconst (\n\tip4 ipFamily = \"IPv4\"\n\tip6 ipFamily = \"IPv6\"\n)\n\n// ValidateIPAM checks whether the network's IPAM passed as argument is valid. It returns a joinError of the list of\n// errors found.\nfunc ValidateIPAM(ipam *IPAM, enableIPv6 bool) error {\n\tif ipam == nil {\n\t\treturn nil\n\t}\n\n\tvar errs []error\n\tfor _, cfg := range ipam.Config {\n\t\tsubnet, err := netip.ParsePrefix(cfg.Subnet)\n\t\tif err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"invalid subnet %s: invalid CIDR block notation\", cfg.Subnet))\n\t\t\tcontinue\n\t\t}\n\t\tsubnetFamily := ip4\n\t\tif subnet.Addr().Is6() {\n\t\t\tsubnetFamily = ip6\n\t\t}\n\n\t\tif !enableIPv6 && subnetFamily == ip6 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif subnet != subnet.Masked() {\n\t\t\terrs = append(errs, fmt.Errorf(\"invalid subnet %s: it should be %s\", subnet, subnet.Masked()))\n\t\t}\n\n\t\tif ipRangeErrs := validateIPRange(cfg.IPRange, subnet, subnetFamily); len(ipRangeErrs) > 0 {\n\t\t\terrs = append(errs, ipRangeErrs...)\n\t\t}\n\n\t\tif err := validateAddress(cfg.Gateway, subnet, subnetFamily); err != nil {\n\t\t\terrs = append(errs, fmt.Errorf(\"invalid gateway %s: %w\", cfg.Gateway, err))\n\t\t}\n\n\t\tfor auxName, aux := range cfg.AuxAddress {\n\t\t\tif err := validateAddress(aux, subnet, subnetFamily); err != nil {\n\t\t\t\terrs = append(errs, fmt.Errorf(\"invalid auxiliary address %s: %w\", auxName, err))\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := multierror.Join(errs...); err != nil {\n\t\treturn fmt.Errorf(\"invalid network config:\\n%w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc validateIPRange(ipRange string, subnet netip.Prefix, subnetFamily ipFamily) []error {\n\tif ipRange == \"\" {\n\t\treturn nil\n\t}\n\tprefix, err := netip.ParsePrefix(ipRange)\n\tif err != nil {\n\t\treturn []error{fmt.Errorf(\"invalid ip-range %s: invalid CIDR block notation\", ipRange)}\n\t}\n\tfamily := ip4\n\tif prefix.Addr().Is6() {\n\t\tfamily = ip6\n\t}\n\n\tif family != subnetFamily {\n\t\treturn []error{fmt.Errorf(\"invalid ip-range %s: parent subnet is an %s block\", ipRange, subnetFamily)}\n\t}\n\n\tvar errs []error\n\tif prefix.Bits() < subnet.Bits() {\n\t\terrs = append(errs, fmt.Errorf(\"invalid ip-range %s: CIDR block is bigger than its parent subnet %s\", ipRange, subnet))\n\t}\n\tif prefix != prefix.Masked() {\n\t\terrs = append(errs, fmt.Errorf(\"invalid ip-range %s: it should be %s\", prefix, prefix.Masked()))\n\t}\n\tif !subnet.Overlaps(prefix) {\n\t\terrs = append(errs, fmt.Errorf(\"invalid ip-range %s: parent subnet %s doesn't contain ip-range\", ipRange, subnet))\n\t}\n\n\treturn errs\n}\n\nfunc validateAddress(address string, subnet netip.Prefix, subnetFamily ipFamily) error {\n\tif address == \"\" {\n\t\treturn nil\n\t}\n\taddr, err := netip.ParseAddr(address)\n\tif err != nil {\n\t\treturn errors.New(\"invalid address\")\n\t}\n\tfamily := ip4\n\tif addr.Is6() {\n\t\tfamily = ip6\n\t}\n\n\tif family != subnetFamily {\n\t\treturn fmt.Errorf(\"parent subnet is an %s block\", subnetFamily)\n\t}\n\tif !subnet.Contains(addr) {\n\t\treturn fmt.Errorf(\"parent subnet %s doesn't contain this address\", subnet)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/network/network.go",
    "content": "package network // import \"github.com/docker/docker/api/types/network\"\n\nimport (\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\nconst (\n\t// NetworkDefault is a platform-independent alias to choose the platform-specific default network stack.\n\tNetworkDefault = \"default\"\n\t// NetworkHost is the name of the predefined network used when the NetworkMode host is selected (only available on Linux)\n\tNetworkHost = \"host\"\n\t// NetworkNone is the name of the predefined network used when the NetworkMode none is selected (available on both Linux and Windows)\n\tNetworkNone = \"none\"\n\t// NetworkBridge is the name of the default network on Linux\n\tNetworkBridge = \"bridge\"\n\t// NetworkNat is the name of the default network on Windows\n\tNetworkNat = \"nat\"\n)\n\n// Address represents an IP address\ntype Address struct {\n\tAddr      string\n\tPrefixLen int\n}\n\n// PeerInfo represents one peer of an overlay network\ntype PeerInfo struct {\n\tName string\n\tIP   string\n}\n\n// Task carries the information about one backend task\ntype Task struct {\n\tName       string\n\tEndpointID string\n\tEndpointIP string\n\tInfo       map[string]string\n}\n\n// ServiceInfo represents service parameters with the list of service's tasks\ntype ServiceInfo struct {\n\tVIP          string\n\tPorts        []string\n\tLocalLBIndex int\n\tTasks        []Task\n}\n\n// NetworkingConfig represents the container's networking configuration for each of its interfaces\n// Carries the networking configs specified in the `docker run` and `docker network connect` commands\ntype NetworkingConfig struct {\n\tEndpointsConfig map[string]*EndpointSettings // Endpoint configs for each connecting network\n}\n\n// ConfigReference specifies the source which provides a network's configuration\ntype ConfigReference struct {\n\tNetwork string\n}\n\nvar acceptedFilters = map[string]bool{\n\t\"dangling\": true,\n\t\"driver\":   true,\n\t\"id\":       true,\n\t\"label\":    true,\n\t\"name\":     true,\n\t\"scope\":    true,\n\t\"type\":     true,\n}\n\n// ValidateFilters validates the list of filter args with the available filters.\nfunc ValidateFilters(filter filters.Args) error {\n\treturn filter.Validate(acceptedFilters)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/plugin.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// Plugin A plugin for the Engine API\n// swagger:model Plugin\ntype Plugin struct {\n\n\t// config\n\t// Required: true\n\tConfig PluginConfig `json:\"Config\"`\n\n\t// True if the plugin is running. False if the plugin is not running, only installed.\n\t// Required: true\n\tEnabled bool `json:\"Enabled\"`\n\n\t// Id\n\tID string `json:\"Id,omitempty\"`\n\n\t// name\n\t// Required: true\n\tName string `json:\"Name\"`\n\n\t// plugin remote reference used to push/pull the plugin\n\tPluginReference string `json:\"PluginReference,omitempty\"`\n\n\t// settings\n\t// Required: true\n\tSettings PluginSettings `json:\"Settings\"`\n}\n\n// PluginConfig The config of a plugin.\n// swagger:model PluginConfig\ntype PluginConfig struct {\n\n\t// args\n\t// Required: true\n\tArgs PluginConfigArgs `json:\"Args\"`\n\n\t// description\n\t// Required: true\n\tDescription string `json:\"Description\"`\n\n\t// Docker Version used to create the plugin\n\tDockerVersion string `json:\"DockerVersion,omitempty\"`\n\n\t// documentation\n\t// Required: true\n\tDocumentation string `json:\"Documentation\"`\n\n\t// entrypoint\n\t// Required: true\n\tEntrypoint []string `json:\"Entrypoint\"`\n\n\t// env\n\t// Required: true\n\tEnv []PluginEnv `json:\"Env\"`\n\n\t// interface\n\t// Required: true\n\tInterface PluginConfigInterface `json:\"Interface\"`\n\n\t// ipc host\n\t// Required: true\n\tIpcHost bool `json:\"IpcHost\"`\n\n\t// linux\n\t// Required: true\n\tLinux PluginConfigLinux `json:\"Linux\"`\n\n\t// mounts\n\t// Required: true\n\tMounts []PluginMount `json:\"Mounts\"`\n\n\t// network\n\t// Required: true\n\tNetwork PluginConfigNetwork `json:\"Network\"`\n\n\t// pid host\n\t// Required: true\n\tPidHost bool `json:\"PidHost\"`\n\n\t// propagated mount\n\t// Required: true\n\tPropagatedMount string `json:\"PropagatedMount\"`\n\n\t// user\n\tUser PluginConfigUser `json:\"User,omitempty\"`\n\n\t// work dir\n\t// Required: true\n\tWorkDir string `json:\"WorkDir\"`\n\n\t// rootfs\n\tRootfs *PluginConfigRootfs `json:\"rootfs,omitempty\"`\n}\n\n// PluginConfigArgs plugin config args\n// swagger:model PluginConfigArgs\ntype PluginConfigArgs struct {\n\n\t// description\n\t// Required: true\n\tDescription string `json:\"Description\"`\n\n\t// name\n\t// Required: true\n\tName string `json:\"Name\"`\n\n\t// settable\n\t// Required: true\n\tSettable []string `json:\"Settable\"`\n\n\t// value\n\t// Required: true\n\tValue []string `json:\"Value\"`\n}\n\n// PluginConfigInterface The interface between Docker and the plugin\n// swagger:model PluginConfigInterface\ntype PluginConfigInterface struct {\n\n\t// Protocol to use for clients connecting to the plugin.\n\tProtocolScheme string `json:\"ProtocolScheme,omitempty\"`\n\n\t// socket\n\t// Required: true\n\tSocket string `json:\"Socket\"`\n\n\t// types\n\t// Required: true\n\tTypes []PluginInterfaceType `json:\"Types\"`\n}\n\n// PluginConfigLinux plugin config linux\n// swagger:model PluginConfigLinux\ntype PluginConfigLinux struct {\n\n\t// allow all devices\n\t// Required: true\n\tAllowAllDevices bool `json:\"AllowAllDevices\"`\n\n\t// capabilities\n\t// Required: true\n\tCapabilities []string `json:\"Capabilities\"`\n\n\t// devices\n\t// Required: true\n\tDevices []PluginDevice `json:\"Devices\"`\n}\n\n// PluginConfigNetwork plugin config network\n// swagger:model PluginConfigNetwork\ntype PluginConfigNetwork struct {\n\n\t// type\n\t// Required: true\n\tType string `json:\"Type\"`\n}\n\n// PluginConfigRootfs plugin config rootfs\n// swagger:model PluginConfigRootfs\ntype PluginConfigRootfs struct {\n\n\t// diff ids\n\tDiffIds []string `json:\"diff_ids\"`\n\n\t// type\n\tType string `json:\"type,omitempty\"`\n}\n\n// PluginConfigUser plugin config user\n// swagger:model PluginConfigUser\ntype PluginConfigUser struct {\n\n\t// g ID\n\tGID uint32 `json:\"GID,omitempty\"`\n\n\t// UID\n\tUID uint32 `json:\"UID,omitempty\"`\n}\n\n// PluginSettings Settings that can be modified by users.\n// swagger:model PluginSettings\ntype PluginSettings struct {\n\n\t// args\n\t// Required: true\n\tArgs []string `json:\"Args\"`\n\n\t// devices\n\t// Required: true\n\tDevices []PluginDevice `json:\"Devices\"`\n\n\t// env\n\t// Required: true\n\tEnv []string `json:\"Env\"`\n\n\t// mounts\n\t// Required: true\n\tMounts []PluginMount `json:\"Mounts\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/plugin_device.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// PluginDevice plugin device\n// swagger:model PluginDevice\ntype PluginDevice struct {\n\n\t// description\n\t// Required: true\n\tDescription string `json:\"Description\"`\n\n\t// name\n\t// Required: true\n\tName string `json:\"Name\"`\n\n\t// path\n\t// Required: true\n\tPath *string `json:\"Path\"`\n\n\t// settable\n\t// Required: true\n\tSettable []string `json:\"Settable\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/plugin_env.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// PluginEnv plugin env\n// swagger:model PluginEnv\ntype PluginEnv struct {\n\n\t// description\n\t// Required: true\n\tDescription string `json:\"Description\"`\n\n\t// name\n\t// Required: true\n\tName string `json:\"Name\"`\n\n\t// settable\n\t// Required: true\n\tSettable []string `json:\"Settable\"`\n\n\t// value\n\t// Required: true\n\tValue *string `json:\"Value\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/plugin_interface_type.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// PluginInterfaceType plugin interface type\n// swagger:model PluginInterfaceType\ntype PluginInterfaceType struct {\n\n\t// capability\n\t// Required: true\n\tCapability string `json:\"Capability\"`\n\n\t// prefix\n\t// Required: true\n\tPrefix string `json:\"Prefix\"`\n\n\t// version\n\t// Required: true\n\tVersion string `json:\"Version\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/plugin_mount.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// PluginMount plugin mount\n// swagger:model PluginMount\ntype PluginMount struct {\n\n\t// description\n\t// Required: true\n\tDescription string `json:\"Description\"`\n\n\t// destination\n\t// Required: true\n\tDestination string `json:\"Destination\"`\n\n\t// name\n\t// Required: true\n\tName string `json:\"Name\"`\n\n\t// options\n\t// Required: true\n\tOptions []string `json:\"Options\"`\n\n\t// settable\n\t// Required: true\n\tSettable []string `json:\"Settable\"`\n\n\t// source\n\t// Required: true\n\tSource *string `json:\"Source\"`\n\n\t// type\n\t// Required: true\n\tType string `json:\"Type\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/plugin_responses.go",
    "content": "package types // import \"github.com/docker/docker/api/types\"\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n)\n\n// PluginsListResponse contains the response for the Engine API\ntype PluginsListResponse []*Plugin\n\n// UnmarshalJSON implements json.Unmarshaler for PluginInterfaceType\nfunc (t *PluginInterfaceType) UnmarshalJSON(p []byte) error {\n\tversionIndex := len(p)\n\tprefixIndex := 0\n\tif len(p) < 2 || p[0] != '\"' || p[len(p)-1] != '\"' {\n\t\treturn fmt.Errorf(\"%q is not a plugin interface type\", p)\n\t}\n\tp = p[1 : len(p)-1]\nloop:\n\tfor i, b := range p {\n\t\tswitch b {\n\t\tcase '.':\n\t\t\tprefixIndex = i\n\t\tcase '/':\n\t\t\tversionIndex = i\n\t\t\tbreak loop\n\t\t}\n\t}\n\tt.Prefix = string(p[:prefixIndex])\n\tt.Capability = string(p[prefixIndex+1 : versionIndex])\n\tif versionIndex < len(p) {\n\t\tt.Version = string(p[versionIndex+1:])\n\t}\n\treturn nil\n}\n\n// MarshalJSON implements json.Marshaler for PluginInterfaceType\nfunc (t *PluginInterfaceType) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(t.String())\n}\n\n// String implements fmt.Stringer for PluginInterfaceType\nfunc (t PluginInterfaceType) String() string {\n\treturn fmt.Sprintf(\"%s.%s/%s\", t.Prefix, t.Capability, t.Version)\n}\n\n// PluginPrivilege describes a permission the user has to accept\n// upon installing a plugin.\ntype PluginPrivilege struct {\n\tName        string\n\tDescription string\n\tValue       []string\n}\n\n// PluginPrivileges is a list of PluginPrivilege\ntype PluginPrivileges []PluginPrivilege\n\nfunc (s PluginPrivileges) Len() int {\n\treturn len(s)\n}\n\nfunc (s PluginPrivileges) Less(i, j int) bool {\n\treturn s[i].Name < s[j].Name\n}\n\nfunc (s PluginPrivileges) Swap(i, j int) {\n\tsort.Strings(s[i].Value)\n\tsort.Strings(s[j].Value)\n\ts[i], s[j] = s[j], s[i]\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/port.go",
    "content": "package types\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// Port An open port on a container\n// swagger:model Port\ntype Port struct {\n\n\t// Host IP address that the container's port is mapped to\n\tIP string `json:\"IP,omitempty\"`\n\n\t// Port on the container\n\t// Required: true\n\tPrivatePort uint16 `json:\"PrivatePort\"`\n\n\t// Port exposed on the host\n\tPublicPort uint16 `json:\"PublicPort,omitempty\"`\n\n\t// type\n\t// Required: true\n\tType string `json:\"Type\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/registry/authconfig.go",
    "content": "package registry // import \"github.com/docker/docker/api/types/registry\"\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// AuthHeader is the name of the header used to send encoded registry\n// authorization credentials for registry operations (push/pull).\nconst AuthHeader = \"X-Registry-Auth\"\n\n// AuthConfig contains authorization information for connecting to a Registry.\ntype AuthConfig struct {\n\tUsername string `json:\"username,omitempty\"`\n\tPassword string `json:\"password,omitempty\"`\n\tAuth     string `json:\"auth,omitempty\"`\n\n\t// Email is an optional value associated with the username.\n\t// This field is deprecated and will be removed in a later\n\t// version of docker.\n\tEmail string `json:\"email,omitempty\"`\n\n\tServerAddress string `json:\"serveraddress,omitempty\"`\n\n\t// IdentityToken is used to authenticate the user and get\n\t// an access token for the registry.\n\tIdentityToken string `json:\"identitytoken,omitempty\"`\n\n\t// RegistryToken is a bearer token to be sent to a registry\n\tRegistryToken string `json:\"registrytoken,omitempty\"`\n}\n\n// EncodeAuthConfig serializes the auth configuration as a base64url encoded\n// RFC4648, section 5) JSON string for sending through the X-Registry-Auth header.\n//\n// For details on base64url encoding, see:\n// - RFC4648, section 5:   https://tools.ietf.org/html/rfc4648#section-5\nfunc EncodeAuthConfig(authConfig AuthConfig) (string, error) {\n\tbuf, err := json.Marshal(authConfig)\n\tif err != nil {\n\t\treturn \"\", errInvalidParameter{err}\n\t}\n\treturn base64.URLEncoding.EncodeToString(buf), nil\n}\n\n// DecodeAuthConfig decodes base64url encoded (RFC4648, section 5) JSON\n// authentication information as sent through the X-Registry-Auth header.\n//\n// This function always returns an AuthConfig, even if an error occurs. It is up\n// to the caller to decide if authentication is required, and if the error can\n// be ignored.\n//\n// For details on base64url encoding, see:\n// - RFC4648, section 5:   https://tools.ietf.org/html/rfc4648#section-5\nfunc DecodeAuthConfig(authEncoded string) (*AuthConfig, error) {\n\tif authEncoded == \"\" {\n\t\treturn &AuthConfig{}, nil\n\t}\n\n\tauthJSON := base64.NewDecoder(base64.URLEncoding, strings.NewReader(authEncoded))\n\treturn decodeAuthConfigFromReader(authJSON)\n}\n\n// DecodeAuthConfigBody decodes authentication information as sent as JSON in the\n// body of a request. This function is to provide backward compatibility with old\n// clients and API versions. Current clients and API versions expect authentication\n// to be provided through the X-Registry-Auth header.\n//\n// Like DecodeAuthConfig, this function always returns an AuthConfig, even if an\n// error occurs. It is up to the caller to decide if authentication is required,\n// and if the error can be ignored.\nfunc DecodeAuthConfigBody(rdr io.ReadCloser) (*AuthConfig, error) {\n\treturn decodeAuthConfigFromReader(rdr)\n}\n\nfunc decodeAuthConfigFromReader(rdr io.Reader) (*AuthConfig, error) {\n\tauthConfig := &AuthConfig{}\n\tif err := json.NewDecoder(rdr).Decode(authConfig); err != nil {\n\t\t// always return an (empty) AuthConfig to increase compatibility with\n\t\t// the existing API.\n\t\treturn &AuthConfig{}, invalid(err)\n\t}\n\treturn authConfig, nil\n}\n\nfunc invalid(err error) error {\n\treturn errInvalidParameter{errors.Wrap(err, \"invalid X-Registry-Auth header\")}\n}\n\ntype errInvalidParameter struct{ error }\n\nfunc (errInvalidParameter) InvalidParameter() {}\n\nfunc (e errInvalidParameter) Cause() error { return e.error }\n\nfunc (e errInvalidParameter) Unwrap() error { return e.error }\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/registry/authenticate.go",
    "content": "package registry // import \"github.com/docker/docker/api/types/registry\"\n\n// ----------------------------------------------------------------------------\n// DO NOT EDIT THIS FILE\n// This file was generated by `swagger generate operation`\n//\n// See hack/generate-swagger-api.sh\n// ----------------------------------------------------------------------------\n\n// AuthenticateOKBody authenticate o k body\n// swagger:model AuthenticateOKBody\ntype AuthenticateOKBody struct {\n\n\t// An opaque token used to authenticate a user after a successful login\n\t// Required: true\n\tIdentityToken string `json:\"IdentityToken\"`\n\n\t// The status of the authentication\n\t// Required: true\n\tStatus string `json:\"Status\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/registry/registry.go",
    "content": "package registry // import \"github.com/docker/docker/api/types/registry\"\n\nimport (\n\t\"encoding/json\"\n\t\"net\"\n\n\tocispec \"github.com/opencontainers/image-spec/specs-go/v1\"\n)\n\n// ServiceConfig stores daemon registry services configuration.\ntype ServiceConfig struct {\n\tAllowNondistributableArtifactsCIDRs     []*NetIPNet\n\tAllowNondistributableArtifactsHostnames []string\n\tInsecureRegistryCIDRs                   []*NetIPNet           `json:\"InsecureRegistryCIDRs\"`\n\tIndexConfigs                            map[string]*IndexInfo `json:\"IndexConfigs\"`\n\tMirrors                                 []string\n}\n\n// NetIPNet is the net.IPNet type, which can be marshalled and\n// unmarshalled to JSON\ntype NetIPNet net.IPNet\n\n// String returns the CIDR notation of ipnet\nfunc (ipnet *NetIPNet) String() string {\n\treturn (*net.IPNet)(ipnet).String()\n}\n\n// MarshalJSON returns the JSON representation of the IPNet\nfunc (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal((*net.IPNet)(ipnet).String())\n}\n\n// UnmarshalJSON sets the IPNet from a byte array of JSON\nfunc (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) {\n\tvar ipnetStr string\n\tif err = json.Unmarshal(b, &ipnetStr); err == nil {\n\t\tvar cidr *net.IPNet\n\t\tif _, cidr, err = net.ParseCIDR(ipnetStr); err == nil {\n\t\t\t*ipnet = NetIPNet(*cidr)\n\t\t}\n\t}\n\treturn\n}\n\n// IndexInfo contains information about a registry\n//\n// RepositoryInfo Examples:\n//\n//\t{\n//\t  \"Index\" : {\n//\t    \"Name\" : \"docker.io\",\n//\t    \"Mirrors\" : [\"https://registry-2.docker.io/v1/\", \"https://registry-3.docker.io/v1/\"],\n//\t    \"Secure\" : true,\n//\t    \"Official\" : true,\n//\t  },\n//\t  \"RemoteName\" : \"library/debian\",\n//\t  \"LocalName\" : \"debian\",\n//\t  \"CanonicalName\" : \"docker.io/debian\"\n//\t  \"Official\" : true,\n//\t}\n//\n//\t{\n//\t  \"Index\" : {\n//\t    \"Name\" : \"127.0.0.1:5000\",\n//\t    \"Mirrors\" : [],\n//\t    \"Secure\" : false,\n//\t    \"Official\" : false,\n//\t  },\n//\t  \"RemoteName\" : \"user/repo\",\n//\t  \"LocalName\" : \"127.0.0.1:5000/user/repo\",\n//\t  \"CanonicalName\" : \"127.0.0.1:5000/user/repo\",\n//\t  \"Official\" : false,\n//\t}\ntype IndexInfo struct {\n\t// Name is the name of the registry, such as \"docker.io\"\n\tName string\n\t// Mirrors is a list of mirrors, expressed as URIs\n\tMirrors []string\n\t// Secure is set to false if the registry is part of the list of\n\t// insecure registries. Insecure registries accept HTTP and/or accept\n\t// HTTPS with certificates from unknown CAs.\n\tSecure bool\n\t// Official indicates whether this is an official registry\n\tOfficial bool\n}\n\n// SearchResult describes a search result returned from a registry\ntype SearchResult struct {\n\t// StarCount indicates the number of stars this repository has\n\tStarCount int `json:\"star_count\"`\n\t// IsOfficial is true if the result is from an official repository.\n\tIsOfficial bool `json:\"is_official\"`\n\t// Name is the name of the repository\n\tName string `json:\"name\"`\n\t// IsAutomated indicates whether the result is automated.\n\t//\n\t// Deprecated: the \"is_automated\" field is deprecated and will always be \"false\" in the future.\n\tIsAutomated bool `json:\"is_automated\"`\n\t// Description is a textual description of the repository\n\tDescription string `json:\"description\"`\n}\n\n// SearchResults lists a collection search results returned from a registry\ntype SearchResults struct {\n\t// Query contains the query string that generated the search results\n\tQuery string `json:\"query\"`\n\t// NumResults indicates the number of results the query returned\n\tNumResults int `json:\"num_results\"`\n\t// Results is a slice containing the actual results for the search\n\tResults []SearchResult `json:\"results\"`\n}\n\n// DistributionInspect describes the result obtained from contacting the\n// registry to retrieve image metadata\ntype DistributionInspect struct {\n\t// Descriptor contains information about the manifest, including\n\t// the content addressable digest\n\tDescriptor ocispec.Descriptor\n\t// Platforms contains the list of platforms supported by the image,\n\t// obtained by parsing the manifest\n\tPlatforms []ocispec.Platform\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/stats.go",
    "content": "// Package types is used for API stability in the types and response to the\n// consumers of the API stats endpoint.\npackage types // import \"github.com/docker/docker/api/types\"\n\nimport \"time\"\n\n// ThrottlingData stores CPU throttling stats of one running container.\n// Not used on Windows.\ntype ThrottlingData struct {\n\t// Number of periods with throttling active\n\tPeriods uint64 `json:\"periods\"`\n\t// Number of periods when the container hits its throttling limit.\n\tThrottledPeriods uint64 `json:\"throttled_periods\"`\n\t// Aggregate time the container was throttled for in nanoseconds.\n\tThrottledTime uint64 `json:\"throttled_time\"`\n}\n\n// CPUUsage stores All CPU stats aggregated since container inception.\ntype CPUUsage struct {\n\t// Total CPU time consumed.\n\t// Units: nanoseconds (Linux)\n\t// Units: 100's of nanoseconds (Windows)\n\tTotalUsage uint64 `json:\"total_usage\"`\n\n\t// Total CPU time consumed per core (Linux). Not used on Windows.\n\t// Units: nanoseconds.\n\tPercpuUsage []uint64 `json:\"percpu_usage,omitempty\"`\n\n\t// Time spent by tasks of the cgroup in kernel mode (Linux).\n\t// Time spent by all container processes in kernel mode (Windows).\n\t// Units: nanoseconds (Linux).\n\t// Units: 100's of nanoseconds (Windows). Not populated for Hyper-V Containers.\n\tUsageInKernelmode uint64 `json:\"usage_in_kernelmode\"`\n\n\t// Time spent by tasks of the cgroup in user mode (Linux).\n\t// Time spent by all container processes in user mode (Windows).\n\t// Units: nanoseconds (Linux).\n\t// Units: 100's of nanoseconds (Windows). Not populated for Hyper-V Containers\n\tUsageInUsermode uint64 `json:\"usage_in_usermode\"`\n}\n\n// CPUStats aggregates and wraps all CPU related info of container\ntype CPUStats struct {\n\t// CPU Usage. Linux and Windows.\n\tCPUUsage CPUUsage `json:\"cpu_usage\"`\n\n\t// System Usage. Linux only.\n\tSystemUsage uint64 `json:\"system_cpu_usage,omitempty\"`\n\n\t// Online CPUs. Linux only.\n\tOnlineCPUs uint32 `json:\"online_cpus,omitempty\"`\n\n\t// Throttling Data. Linux only.\n\tThrottlingData ThrottlingData `json:\"throttling_data,omitempty\"`\n}\n\n// MemoryStats aggregates all memory stats since container inception on Linux.\n// Windows returns stats for commit and private working set only.\ntype MemoryStats struct {\n\t// Linux Memory Stats\n\n\t// current res_counter usage for memory\n\tUsage uint64 `json:\"usage,omitempty\"`\n\t// maximum usage ever recorded.\n\tMaxUsage uint64 `json:\"max_usage,omitempty\"`\n\t// TODO(vishh): Export these as stronger types.\n\t// all the stats exported via memory.stat.\n\tStats map[string]uint64 `json:\"stats,omitempty\"`\n\t// number of times memory usage hits limits.\n\tFailcnt uint64 `json:\"failcnt,omitempty\"`\n\tLimit   uint64 `json:\"limit,omitempty\"`\n\n\t// Windows Memory Stats\n\t// See https://technet.microsoft.com/en-us/magazine/ff382715.aspx\n\n\t// committed bytes\n\tCommit uint64 `json:\"commitbytes,omitempty\"`\n\t// peak committed bytes\n\tCommitPeak uint64 `json:\"commitpeakbytes,omitempty\"`\n\t// private working set\n\tPrivateWorkingSet uint64 `json:\"privateworkingset,omitempty\"`\n}\n\n// BlkioStatEntry is one small entity to store a piece of Blkio stats\n// Not used on Windows.\ntype BlkioStatEntry struct {\n\tMajor uint64 `json:\"major\"`\n\tMinor uint64 `json:\"minor\"`\n\tOp    string `json:\"op\"`\n\tValue uint64 `json:\"value\"`\n}\n\n// BlkioStats stores All IO service stats for data read and write.\n// This is a Linux specific structure as the differences between expressing\n// block I/O on Windows and Linux are sufficiently significant to make\n// little sense attempting to morph into a combined structure.\ntype BlkioStats struct {\n\t// number of bytes transferred to and from the block device\n\tIoServiceBytesRecursive []BlkioStatEntry `json:\"io_service_bytes_recursive\"`\n\tIoServicedRecursive     []BlkioStatEntry `json:\"io_serviced_recursive\"`\n\tIoQueuedRecursive       []BlkioStatEntry `json:\"io_queue_recursive\"`\n\tIoServiceTimeRecursive  []BlkioStatEntry `json:\"io_service_time_recursive\"`\n\tIoWaitTimeRecursive     []BlkioStatEntry `json:\"io_wait_time_recursive\"`\n\tIoMergedRecursive       []BlkioStatEntry `json:\"io_merged_recursive\"`\n\tIoTimeRecursive         []BlkioStatEntry `json:\"io_time_recursive\"`\n\tSectorsRecursive        []BlkioStatEntry `json:\"sectors_recursive\"`\n}\n\n// StorageStats is the disk I/O stats for read/write on Windows.\ntype StorageStats struct {\n\tReadCountNormalized  uint64 `json:\"read_count_normalized,omitempty\"`\n\tReadSizeBytes        uint64 `json:\"read_size_bytes,omitempty\"`\n\tWriteCountNormalized uint64 `json:\"write_count_normalized,omitempty\"`\n\tWriteSizeBytes       uint64 `json:\"write_size_bytes,omitempty\"`\n}\n\n// NetworkStats aggregates the network stats of one container\ntype NetworkStats struct {\n\t// Bytes received. Windows and Linux.\n\tRxBytes uint64 `json:\"rx_bytes\"`\n\t// Packets received. Windows and Linux.\n\tRxPackets uint64 `json:\"rx_packets\"`\n\t// Received errors. Not used on Windows. Note that we don't `omitempty` this\n\t// field as it is expected in the >=v1.21 API stats structure.\n\tRxErrors uint64 `json:\"rx_errors\"`\n\t// Incoming packets dropped. Windows and Linux.\n\tRxDropped uint64 `json:\"rx_dropped\"`\n\t// Bytes sent. Windows and Linux.\n\tTxBytes uint64 `json:\"tx_bytes\"`\n\t// Packets sent. Windows and Linux.\n\tTxPackets uint64 `json:\"tx_packets\"`\n\t// Sent errors. Not used on Windows. Note that we don't `omitempty` this\n\t// field as it is expected in the >=v1.21 API stats structure.\n\tTxErrors uint64 `json:\"tx_errors\"`\n\t// Outgoing packets dropped. Windows and Linux.\n\tTxDropped uint64 `json:\"tx_dropped\"`\n\t// Endpoint ID. Not used on Linux.\n\tEndpointID string `json:\"endpoint_id,omitempty\"`\n\t// Instance ID. Not used on Linux.\n\tInstanceID string `json:\"instance_id,omitempty\"`\n}\n\n// PidsStats contains the stats of a container's pids\ntype PidsStats struct {\n\t// Current is the number of pids in the cgroup\n\tCurrent uint64 `json:\"current,omitempty\"`\n\t// Limit is the hard limit on the number of pids in the cgroup.\n\t// A \"Limit\" of 0 means that there is no limit.\n\tLimit uint64 `json:\"limit,omitempty\"`\n}\n\n// Stats is Ultimate struct aggregating all types of stats of one container\ntype Stats struct {\n\t// Common stats\n\tRead    time.Time `json:\"read\"`\n\tPreRead time.Time `json:\"preread\"`\n\n\t// Linux specific stats, not populated on Windows.\n\tPidsStats  PidsStats  `json:\"pids_stats,omitempty\"`\n\tBlkioStats BlkioStats `json:\"blkio_stats,omitempty\"`\n\n\t// Windows specific stats, not populated on Linux.\n\tNumProcs     uint32       `json:\"num_procs\"`\n\tStorageStats StorageStats `json:\"storage_stats,omitempty\"`\n\n\t// Shared stats\n\tCPUStats    CPUStats    `json:\"cpu_stats,omitempty\"`\n\tPreCPUStats CPUStats    `json:\"precpu_stats,omitempty\"` // \"Pre\"=\"Previous\"\n\tMemoryStats MemoryStats `json:\"memory_stats,omitempty\"`\n}\n\n// StatsJSON is newly used Networks\ntype StatsJSON struct {\n\tStats\n\n\tName string `json:\"name,omitempty\"`\n\tID   string `json:\"id,omitempty\"`\n\n\t// Networks request version >=1.21\n\tNetworks map[string]NetworkStats `json:\"networks,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/strslice/strslice.go",
    "content": "package strslice // import \"github.com/docker/docker/api/types/strslice\"\n\nimport \"encoding/json\"\n\n// StrSlice represents a string or an array of strings.\n// We need to override the json decoder to accept both options.\ntype StrSlice []string\n\n// UnmarshalJSON decodes the byte slice whether it's a string or an array of\n// strings. This method is needed to implement json.Unmarshaler.\nfunc (e *StrSlice) UnmarshalJSON(b []byte) error {\n\tif len(b) == 0 {\n\t\t// With no input, we preserve the existing value by returning nil and\n\t\t// leaving the target alone. This allows defining default values for\n\t\t// the type.\n\t\treturn nil\n\t}\n\n\tp := make([]string, 0, 1)\n\tif err := json.Unmarshal(b, &p); err != nil {\n\t\tvar s string\n\t\tif err := json.Unmarshal(b, &s); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tp = append(p, s)\n\t}\n\n\t*e = p\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/common.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport (\n\t\"strconv\"\n\t\"time\"\n)\n\n// Version represents the internal object version.\ntype Version struct {\n\tIndex uint64 `json:\",omitempty\"`\n}\n\n// String implements fmt.Stringer interface.\nfunc (v Version) String() string {\n\treturn strconv.FormatUint(v.Index, 10)\n}\n\n// Meta is a base object inherited by most of the other once.\ntype Meta struct {\n\tVersion   Version   `json:\",omitempty\"`\n\tCreatedAt time.Time `json:\",omitempty\"`\n\tUpdatedAt time.Time `json:\",omitempty\"`\n}\n\n// Annotations represents how to describe an object.\ntype Annotations struct {\n\tName   string            `json:\",omitempty\"`\n\tLabels map[string]string `json:\"Labels\"`\n}\n\n// Driver represents a driver (network, logging, secrets backend).\ntype Driver struct {\n\tName    string            `json:\",omitempty\"`\n\tOptions map[string]string `json:\",omitempty\"`\n}\n\n// TLSInfo represents the TLS information about what CA certificate is trusted,\n// and who the issuer for a TLS certificate is\ntype TLSInfo struct {\n\t// TrustRoot is the trusted CA root certificate in PEM format\n\tTrustRoot string `json:\",omitempty\"`\n\n\t// CertIssuer is the raw subject bytes of the issuer\n\tCertIssuerSubject []byte `json:\",omitempty\"`\n\n\t// CertIssuerPublicKey is the raw public key bytes of the issuer\n\tCertIssuerPublicKey []byte `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/config.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport \"os\"\n\n// Config represents a config.\ntype Config struct {\n\tID string\n\tMeta\n\tSpec ConfigSpec\n}\n\n// ConfigSpec represents a config specification from a config in swarm\ntype ConfigSpec struct {\n\tAnnotations\n\tData []byte `json:\",omitempty\"`\n\n\t// Templating controls whether and how to evaluate the config payload as\n\t// a template. If it is not set, no templating is used.\n\tTemplating *Driver `json:\",omitempty\"`\n}\n\n// ConfigReferenceFileTarget is a file target in a config reference\ntype ConfigReferenceFileTarget struct {\n\tName string\n\tUID  string\n\tGID  string\n\tMode os.FileMode\n}\n\n// ConfigReferenceRuntimeTarget is a target for a config specifying that it\n// isn't mounted into the container but instead has some other purpose.\ntype ConfigReferenceRuntimeTarget struct{}\n\n// ConfigReference is a reference to a config in swarm\ntype ConfigReference struct {\n\tFile       *ConfigReferenceFileTarget    `json:\",omitempty\"`\n\tRuntime    *ConfigReferenceRuntimeTarget `json:\",omitempty\"`\n\tConfigID   string\n\tConfigName string\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/container.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport (\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/mount\"\n\t\"github.com/docker/go-units\"\n)\n\n// DNSConfig specifies DNS related configurations in resolver configuration file (resolv.conf)\n// Detailed documentation is available in:\n// http://man7.org/linux/man-pages/man5/resolv.conf.5.html\n// `nameserver`, `search`, `options` have been supported.\n// TODO: `domain` is not supported yet.\ntype DNSConfig struct {\n\t// Nameservers specifies the IP addresses of the name servers\n\tNameservers []string `json:\",omitempty\"`\n\t// Search specifies the search list for host-name lookup\n\tSearch []string `json:\",omitempty\"`\n\t// Options allows certain internal resolver variables to be modified\n\tOptions []string `json:\",omitempty\"`\n}\n\n// SELinuxContext contains the SELinux labels of the container.\ntype SELinuxContext struct {\n\tDisable bool\n\n\tUser  string\n\tRole  string\n\tType  string\n\tLevel string\n}\n\n// SeccompMode is the type used for the enumeration of possible seccomp modes\n// in SeccompOpts\ntype SeccompMode string\n\nconst (\n\tSeccompModeDefault    SeccompMode = \"default\"\n\tSeccompModeUnconfined SeccompMode = \"unconfined\"\n\tSeccompModeCustom     SeccompMode = \"custom\"\n)\n\n// SeccompOpts defines the options for configuring seccomp on a swarm-managed\n// container.\ntype SeccompOpts struct {\n\t// Mode is the SeccompMode used for the container.\n\tMode SeccompMode `json:\",omitempty\"`\n\t// Profile is the custom seccomp profile as a json object to be used with\n\t// the container. Mode should be set to SeccompModeCustom when using a\n\t// custom profile in this manner.\n\tProfile []byte `json:\",omitempty\"`\n}\n\n// AppArmorMode is type used for the enumeration of possible AppArmor modes in\n// AppArmorOpts\ntype AppArmorMode string\n\nconst (\n\tAppArmorModeDefault  AppArmorMode = \"default\"\n\tAppArmorModeDisabled AppArmorMode = \"disabled\"\n)\n\n// AppArmorOpts defines the options for configuring AppArmor on a swarm-managed\n// container.  Currently, custom AppArmor profiles are not supported.\ntype AppArmorOpts struct {\n\tMode AppArmorMode `json:\",omitempty\"`\n}\n\n// CredentialSpec for managed service account (Windows only)\ntype CredentialSpec struct {\n\tConfig   string\n\tFile     string\n\tRegistry string\n}\n\n// Privileges defines the security options for the container.\ntype Privileges struct {\n\tCredentialSpec  *CredentialSpec\n\tSELinuxContext  *SELinuxContext\n\tSeccomp         *SeccompOpts  `json:\",omitempty\"`\n\tAppArmor        *AppArmorOpts `json:\",omitempty\"`\n\tNoNewPrivileges bool\n}\n\n// ContainerSpec represents the spec of a container.\ntype ContainerSpec struct {\n\tImage           string                  `json:\",omitempty\"`\n\tLabels          map[string]string       `json:\",omitempty\"`\n\tCommand         []string                `json:\",omitempty\"`\n\tArgs            []string                `json:\",omitempty\"`\n\tHostname        string                  `json:\",omitempty\"`\n\tEnv             []string                `json:\",omitempty\"`\n\tDir             string                  `json:\",omitempty\"`\n\tUser            string                  `json:\",omitempty\"`\n\tGroups          []string                `json:\",omitempty\"`\n\tPrivileges      *Privileges             `json:\",omitempty\"`\n\tInit            *bool                   `json:\",omitempty\"`\n\tStopSignal      string                  `json:\",omitempty\"`\n\tTTY             bool                    `json:\",omitempty\"`\n\tOpenStdin       bool                    `json:\",omitempty\"`\n\tReadOnly        bool                    `json:\",omitempty\"`\n\tMounts          []mount.Mount           `json:\",omitempty\"`\n\tStopGracePeriod *time.Duration          `json:\",omitempty\"`\n\tHealthcheck     *container.HealthConfig `json:\",omitempty\"`\n\t// The format of extra hosts on swarmkit is specified in:\n\t// http://man7.org/linux/man-pages/man5/hosts.5.html\n\t//    IP_address canonical_hostname [aliases...]\n\tHosts          []string            `json:\",omitempty\"`\n\tDNSConfig      *DNSConfig          `json:\",omitempty\"`\n\tSecrets        []*SecretReference  `json:\",omitempty\"`\n\tConfigs        []*ConfigReference  `json:\",omitempty\"`\n\tIsolation      container.Isolation `json:\",omitempty\"`\n\tSysctls        map[string]string   `json:\",omitempty\"`\n\tCapabilityAdd  []string            `json:\",omitempty\"`\n\tCapabilityDrop []string            `json:\",omitempty\"`\n\tUlimits        []*units.Ulimit     `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/network.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport (\n\t\"github.com/docker/docker/api/types/network\"\n)\n\n// Endpoint represents an endpoint.\ntype Endpoint struct {\n\tSpec       EndpointSpec        `json:\",omitempty\"`\n\tPorts      []PortConfig        `json:\",omitempty\"`\n\tVirtualIPs []EndpointVirtualIP `json:\",omitempty\"`\n}\n\n// EndpointSpec represents the spec of an endpoint.\ntype EndpointSpec struct {\n\tMode  ResolutionMode `json:\",omitempty\"`\n\tPorts []PortConfig   `json:\",omitempty\"`\n}\n\n// ResolutionMode represents a resolution mode.\ntype ResolutionMode string\n\nconst (\n\t// ResolutionModeVIP VIP\n\tResolutionModeVIP ResolutionMode = \"vip\"\n\t// ResolutionModeDNSRR DNSRR\n\tResolutionModeDNSRR ResolutionMode = \"dnsrr\"\n)\n\n// PortConfig represents the config of a port.\ntype PortConfig struct {\n\tName     string             `json:\",omitempty\"`\n\tProtocol PortConfigProtocol `json:\",omitempty\"`\n\t// TargetPort is the port inside the container\n\tTargetPort uint32 `json:\",omitempty\"`\n\t// PublishedPort is the port on the swarm hosts\n\tPublishedPort uint32 `json:\",omitempty\"`\n\t// PublishMode is the mode in which port is published\n\tPublishMode PortConfigPublishMode `json:\",omitempty\"`\n}\n\n// PortConfigPublishMode represents the mode in which the port is to\n// be published.\ntype PortConfigPublishMode string\n\nconst (\n\t// PortConfigPublishModeIngress is used for ports published\n\t// for ingress load balancing using routing mesh.\n\tPortConfigPublishModeIngress PortConfigPublishMode = \"ingress\"\n\t// PortConfigPublishModeHost is used for ports published\n\t// for direct host level access on the host where the task is running.\n\tPortConfigPublishModeHost PortConfigPublishMode = \"host\"\n)\n\n// PortConfigProtocol represents the protocol of a port.\ntype PortConfigProtocol string\n\nconst (\n\t// TODO(stevvooe): These should be used generally, not just for PortConfig.\n\n\t// PortConfigProtocolTCP TCP\n\tPortConfigProtocolTCP PortConfigProtocol = \"tcp\"\n\t// PortConfigProtocolUDP UDP\n\tPortConfigProtocolUDP PortConfigProtocol = \"udp\"\n\t// PortConfigProtocolSCTP SCTP\n\tPortConfigProtocolSCTP PortConfigProtocol = \"sctp\"\n)\n\n// EndpointVirtualIP represents the virtual ip of a port.\ntype EndpointVirtualIP struct {\n\tNetworkID string `json:\",omitempty\"`\n\tAddr      string `json:\",omitempty\"`\n}\n\n// Network represents a network.\ntype Network struct {\n\tID string\n\tMeta\n\tSpec        NetworkSpec  `json:\",omitempty\"`\n\tDriverState Driver       `json:\",omitempty\"`\n\tIPAMOptions *IPAMOptions `json:\",omitempty\"`\n}\n\n// NetworkSpec represents the spec of a network.\ntype NetworkSpec struct {\n\tAnnotations\n\tDriverConfiguration *Driver                  `json:\",omitempty\"`\n\tIPv6Enabled         bool                     `json:\",omitempty\"`\n\tInternal            bool                     `json:\",omitempty\"`\n\tAttachable          bool                     `json:\",omitempty\"`\n\tIngress             bool                     `json:\",omitempty\"`\n\tIPAMOptions         *IPAMOptions             `json:\",omitempty\"`\n\tConfigFrom          *network.ConfigReference `json:\",omitempty\"`\n\tScope               string                   `json:\",omitempty\"`\n}\n\n// NetworkAttachmentConfig represents the configuration of a network attachment.\ntype NetworkAttachmentConfig struct {\n\tTarget     string            `json:\",omitempty\"`\n\tAliases    []string          `json:\",omitempty\"`\n\tDriverOpts map[string]string `json:\",omitempty\"`\n}\n\n// NetworkAttachment represents a network attachment.\ntype NetworkAttachment struct {\n\tNetwork   Network  `json:\",omitempty\"`\n\tAddresses []string `json:\",omitempty\"`\n}\n\n// IPAMOptions represents ipam options.\ntype IPAMOptions struct {\n\tDriver  Driver       `json:\",omitempty\"`\n\tConfigs []IPAMConfig `json:\",omitempty\"`\n}\n\n// IPAMConfig represents ipam configuration.\ntype IPAMConfig struct {\n\tSubnet  string `json:\",omitempty\"`\n\tRange   string `json:\",omitempty\"`\n\tGateway string `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/node.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\n// Node represents a node.\ntype Node struct {\n\tID string\n\tMeta\n\t// Spec defines the desired state of the node as specified by the user.\n\t// The system will honor this and will *never* modify it.\n\tSpec NodeSpec `json:\",omitempty\"`\n\t// Description encapsulates the properties of the Node as reported by the\n\t// agent.\n\tDescription NodeDescription `json:\",omitempty\"`\n\t// Status provides the current status of the node, as seen by the manager.\n\tStatus NodeStatus `json:\",omitempty\"`\n\t// ManagerStatus provides the current status of the node's manager\n\t// component, if the node is a manager.\n\tManagerStatus *ManagerStatus `json:\",omitempty\"`\n}\n\n// NodeSpec represents the spec of a node.\ntype NodeSpec struct {\n\tAnnotations\n\tRole         NodeRole         `json:\",omitempty\"`\n\tAvailability NodeAvailability `json:\",omitempty\"`\n}\n\n// NodeRole represents the role of a node.\ntype NodeRole string\n\nconst (\n\t// NodeRoleWorker WORKER\n\tNodeRoleWorker NodeRole = \"worker\"\n\t// NodeRoleManager MANAGER\n\tNodeRoleManager NodeRole = \"manager\"\n)\n\n// NodeAvailability represents the availability of a node.\ntype NodeAvailability string\n\nconst (\n\t// NodeAvailabilityActive ACTIVE\n\tNodeAvailabilityActive NodeAvailability = \"active\"\n\t// NodeAvailabilityPause PAUSE\n\tNodeAvailabilityPause NodeAvailability = \"pause\"\n\t// NodeAvailabilityDrain DRAIN\n\tNodeAvailabilityDrain NodeAvailability = \"drain\"\n)\n\n// NodeDescription represents the description of a node.\ntype NodeDescription struct {\n\tHostname  string            `json:\",omitempty\"`\n\tPlatform  Platform          `json:\",omitempty\"`\n\tResources Resources         `json:\",omitempty\"`\n\tEngine    EngineDescription `json:\",omitempty\"`\n\tTLSInfo   TLSInfo           `json:\",omitempty\"`\n\tCSIInfo   []NodeCSIInfo     `json:\",omitempty\"`\n}\n\n// Platform represents the platform (Arch/OS).\ntype Platform struct {\n\tArchitecture string `json:\",omitempty\"`\n\tOS           string `json:\",omitempty\"`\n}\n\n// EngineDescription represents the description of an engine.\ntype EngineDescription struct {\n\tEngineVersion string              `json:\",omitempty\"`\n\tLabels        map[string]string   `json:\",omitempty\"`\n\tPlugins       []PluginDescription `json:\",omitempty\"`\n}\n\n// NodeCSIInfo represents information about a CSI plugin available on the node\ntype NodeCSIInfo struct {\n\t// PluginName is the name of the CSI plugin.\n\tPluginName string `json:\",omitempty\"`\n\t// NodeID is the ID of the node as reported by the CSI plugin. This is\n\t// different from the swarm node ID.\n\tNodeID string `json:\",omitempty\"`\n\t// MaxVolumesPerNode is the maximum number of volumes that may be published\n\t// to this node\n\tMaxVolumesPerNode int64 `json:\",omitempty\"`\n\t// AccessibleTopology indicates the location of this node in the CSI\n\t// plugin's topology\n\tAccessibleTopology *Topology `json:\",omitempty\"`\n}\n\n// PluginDescription represents the description of an engine plugin.\ntype PluginDescription struct {\n\tType string `json:\",omitempty\"`\n\tName string `json:\",omitempty\"`\n}\n\n// NodeStatus represents the status of a node.\ntype NodeStatus struct {\n\tState   NodeState `json:\",omitempty\"`\n\tMessage string    `json:\",omitempty\"`\n\tAddr    string    `json:\",omitempty\"`\n}\n\n// Reachability represents the reachability of a node.\ntype Reachability string\n\nconst (\n\t// ReachabilityUnknown UNKNOWN\n\tReachabilityUnknown Reachability = \"unknown\"\n\t// ReachabilityUnreachable UNREACHABLE\n\tReachabilityUnreachable Reachability = \"unreachable\"\n\t// ReachabilityReachable REACHABLE\n\tReachabilityReachable Reachability = \"reachable\"\n)\n\n// ManagerStatus represents the status of a manager.\ntype ManagerStatus struct {\n\tLeader       bool         `json:\",omitempty\"`\n\tReachability Reachability `json:\",omitempty\"`\n\tAddr         string       `json:\",omitempty\"`\n}\n\n// NodeState represents the state of a node.\ntype NodeState string\n\nconst (\n\t// NodeStateUnknown UNKNOWN\n\tNodeStateUnknown NodeState = \"unknown\"\n\t// NodeStateDown DOWN\n\tNodeStateDown NodeState = \"down\"\n\t// NodeStateReady READY\n\tNodeStateReady NodeState = \"ready\"\n\t// NodeStateDisconnected DISCONNECTED\n\tNodeStateDisconnected NodeState = \"disconnected\"\n)\n\n// Topology defines the CSI topology of this node. This type is a duplicate of\n// github.com/docker/docker/api/types.Topology. Because the type definition\n// is so simple and to avoid complicated structure or circular imports, we just\n// duplicate it here. See that type for full documentation\ntype Topology struct {\n\tSegments map[string]string `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/runtime/gen.go",
    "content": "//go:generate protoc --gogofaster_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto\n\npackage runtime // import \"github.com/docker/docker/api/types/swarm/runtime\"\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.pb.go",
    "content": "// Code generated by protoc-gen-gogo. DO NOT EDIT.\n// source: plugin.proto\n\npackage runtime\n\nimport (\n\tfmt \"fmt\"\n\tproto \"github.com/gogo/protobuf/proto\"\n\tio \"io\"\n\tmath \"math\"\n\tmath_bits \"math/bits\"\n)\n\n// Reference imports to suppress errors if they are not otherwise used.\nvar _ = proto.Marshal\nvar _ = fmt.Errorf\nvar _ = math.Inf\n\n// This is a compile-time assertion to ensure that this generated file\n// is compatible with the proto package it is being compiled against.\n// A compilation error at this line likely means your copy of the\n// proto package needs to be updated.\nconst _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package\n\n// PluginSpec defines the base payload which clients can specify for creating\n// a service with the plugin runtime.\ntype PluginSpec struct {\n\tName       string             `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tRemote     string             `protobuf:\"bytes,2,opt,name=remote,proto3\" json:\"remote,omitempty\"`\n\tPrivileges []*PluginPrivilege `protobuf:\"bytes,3,rep,name=privileges,proto3\" json:\"privileges,omitempty\"`\n\tDisabled   bool               `protobuf:\"varint,4,opt,name=disabled,proto3\" json:\"disabled,omitempty\"`\n\tEnv        []string           `protobuf:\"bytes,5,rep,name=env,proto3\" json:\"env,omitempty\"`\n}\n\nfunc (m *PluginSpec) Reset()         { *m = PluginSpec{} }\nfunc (m *PluginSpec) String() string { return proto.CompactTextString(m) }\nfunc (*PluginSpec) ProtoMessage()    {}\nfunc (*PluginSpec) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_22a625af4bc1cc87, []int{0}\n}\nfunc (m *PluginSpec) XXX_Unmarshal(b []byte) error {\n\treturn m.Unmarshal(b)\n}\nfunc (m *PluginSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\tif deterministic {\n\t\treturn xxx_messageInfo_PluginSpec.Marshal(b, m, deterministic)\n\t} else {\n\t\tb = b[:cap(b)]\n\t\tn, err := m.MarshalToSizedBuffer(b)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn b[:n], nil\n\t}\n}\nfunc (m *PluginSpec) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PluginSpec.Merge(m, src)\n}\nfunc (m *PluginSpec) XXX_Size() int {\n\treturn m.Size()\n}\nfunc (m *PluginSpec) XXX_DiscardUnknown() {\n\txxx_messageInfo_PluginSpec.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PluginSpec proto.InternalMessageInfo\n\nfunc (m *PluginSpec) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *PluginSpec) GetRemote() string {\n\tif m != nil {\n\t\treturn m.Remote\n\t}\n\treturn \"\"\n}\n\nfunc (m *PluginSpec) GetPrivileges() []*PluginPrivilege {\n\tif m != nil {\n\t\treturn m.Privileges\n\t}\n\treturn nil\n}\n\nfunc (m *PluginSpec) GetDisabled() bool {\n\tif m != nil {\n\t\treturn m.Disabled\n\t}\n\treturn false\n}\n\nfunc (m *PluginSpec) GetEnv() []string {\n\tif m != nil {\n\t\treturn m.Env\n\t}\n\treturn nil\n}\n\n// PluginPrivilege describes a permission the user has to accept\n// upon installing a plugin.\ntype PluginPrivilege struct {\n\tName        string   `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tDescription string   `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tValue       []string `protobuf:\"bytes,3,rep,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *PluginPrivilege) Reset()         { *m = PluginPrivilege{} }\nfunc (m *PluginPrivilege) String() string { return proto.CompactTextString(m) }\nfunc (*PluginPrivilege) ProtoMessage()    {}\nfunc (*PluginPrivilege) Descriptor() ([]byte, []int) {\n\treturn fileDescriptor_22a625af4bc1cc87, []int{1}\n}\nfunc (m *PluginPrivilege) XXX_Unmarshal(b []byte) error {\n\treturn m.Unmarshal(b)\n}\nfunc (m *PluginPrivilege) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {\n\tif deterministic {\n\t\treturn xxx_messageInfo_PluginPrivilege.Marshal(b, m, deterministic)\n\t} else {\n\t\tb = b[:cap(b)]\n\t\tn, err := m.MarshalToSizedBuffer(b)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn b[:n], nil\n\t}\n}\nfunc (m *PluginPrivilege) XXX_Merge(src proto.Message) {\n\txxx_messageInfo_PluginPrivilege.Merge(m, src)\n}\nfunc (m *PluginPrivilege) XXX_Size() int {\n\treturn m.Size()\n}\nfunc (m *PluginPrivilege) XXX_DiscardUnknown() {\n\txxx_messageInfo_PluginPrivilege.DiscardUnknown(m)\n}\n\nvar xxx_messageInfo_PluginPrivilege proto.InternalMessageInfo\n\nfunc (m *PluginPrivilege) GetName() string {\n\tif m != nil {\n\t\treturn m.Name\n\t}\n\treturn \"\"\n}\n\nfunc (m *PluginPrivilege) GetDescription() string {\n\tif m != nil {\n\t\treturn m.Description\n\t}\n\treturn \"\"\n}\n\nfunc (m *PluginPrivilege) GetValue() []string {\n\tif m != nil {\n\t\treturn m.Value\n\t}\n\treturn nil\n}\n\nfunc init() {\n\tproto.RegisterType((*PluginSpec)(nil), \"PluginSpec\")\n\tproto.RegisterType((*PluginPrivilege)(nil), \"PluginPrivilege\")\n}\n\nfunc init() { proto.RegisterFile(\"plugin.proto\", fileDescriptor_22a625af4bc1cc87) }\n\nvar fileDescriptor_22a625af4bc1cc87 = []byte{\n\t// 225 bytes of a gzipped FileDescriptorProto\n\t0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,\n\t0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x9a, 0xc1, 0xc8, 0xc5, 0x15, 0x00, 0x16,\n\t0x08, 0x2e, 0x48, 0x4d, 0x16, 0x12, 0xe2, 0x62, 0xc9, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60,\n\t0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x85, 0xc4, 0xb8, 0xd8, 0x8a, 0x52, 0x73, 0xf3, 0x4b, 0x52, 0x25,\n\t0x98, 0xc0, 0xa2, 0x50, 0x9e, 0x90, 0x01, 0x17, 0x57, 0x41, 0x51, 0x66, 0x59, 0x66, 0x4e, 0x6a,\n\t0x7a, 0x6a, 0xb1, 0x04, 0xb3, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0x80, 0x1e, 0xc4, 0xb0, 0x00, 0x98,\n\t0x44, 0x10, 0x92, 0x1a, 0x21, 0x29, 0x2e, 0x8e, 0x94, 0xcc, 0xe2, 0xc4, 0xa4, 0x9c, 0xd4, 0x14,\n\t0x09, 0x16, 0x05, 0x46, 0x0d, 0x8e, 0x20, 0x38, 0x5f, 0x48, 0x80, 0x8b, 0x39, 0x35, 0xaf, 0x4c,\n\t0x82, 0x55, 0x81, 0x59, 0x83, 0x33, 0x08, 0xc4, 0x54, 0x8a, 0xe5, 0xe2, 0x47, 0x33, 0x0c, 0xab,\n\t0xf3, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0,\n\t0x6e, 0x44, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x91, 0x33,\n\t0x08, 0xc2, 0x71, 0x92, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,\n\t0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x24, 0x36,\n\t0x70, 0xd0, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x37, 0xea, 0xe2, 0xca, 0x2a, 0x01, 0x00,\n\t0x00,\n}\n\nfunc (m *PluginSpec) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalToSizedBuffer(dAtA[:size])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) {\n\tsize := m.Size()\n\treturn m.MarshalToSizedBuffer(dAtA[:size])\n}\n\nfunc (m *PluginSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {\n\ti := len(dAtA)\n\t_ = i\n\tvar l int\n\t_ = l\n\tif len(m.Env) > 0 {\n\t\tfor iNdEx := len(m.Env) - 1; iNdEx >= 0; iNdEx-- {\n\t\t\ti -= len(m.Env[iNdEx])\n\t\t\tcopy(dAtA[i:], m.Env[iNdEx])\n\t\t\ti = encodeVarintPlugin(dAtA, i, uint64(len(m.Env[iNdEx])))\n\t\t\ti--\n\t\t\tdAtA[i] = 0x2a\n\t\t}\n\t}\n\tif m.Disabled {\n\t\ti--\n\t\tif m.Disabled {\n\t\t\tdAtA[i] = 1\n\t\t} else {\n\t\t\tdAtA[i] = 0\n\t\t}\n\t\ti--\n\t\tdAtA[i] = 0x20\n\t}\n\tif len(m.Privileges) > 0 {\n\t\tfor iNdEx := len(m.Privileges) - 1; iNdEx >= 0; iNdEx-- {\n\t\t\t{\n\t\t\t\tsize, err := m.Privileges[iNdEx].MarshalToSizedBuffer(dAtA[:i])\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t\ti -= size\n\t\t\t\ti = encodeVarintPlugin(dAtA, i, uint64(size))\n\t\t\t}\n\t\t\ti--\n\t\t\tdAtA[i] = 0x1a\n\t\t}\n\t}\n\tif len(m.Remote) > 0 {\n\t\ti -= len(m.Remote)\n\t\tcopy(dAtA[i:], m.Remote)\n\t\ti = encodeVarintPlugin(dAtA, i, uint64(len(m.Remote)))\n\t\ti--\n\t\tdAtA[i] = 0x12\n\t}\n\tif len(m.Name) > 0 {\n\t\ti -= len(m.Name)\n\t\tcopy(dAtA[i:], m.Name)\n\t\ti = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))\n\t\ti--\n\t\tdAtA[i] = 0xa\n\t}\n\treturn len(dAtA) - i, nil\n}\n\nfunc (m *PluginPrivilege) Marshal() (dAtA []byte, err error) {\n\tsize := m.Size()\n\tdAtA = make([]byte, size)\n\tn, err := m.MarshalToSizedBuffer(dAtA[:size])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn dAtA[:n], nil\n}\n\nfunc (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) {\n\tsize := m.Size()\n\treturn m.MarshalToSizedBuffer(dAtA[:size])\n}\n\nfunc (m *PluginPrivilege) MarshalToSizedBuffer(dAtA []byte) (int, error) {\n\ti := len(dAtA)\n\t_ = i\n\tvar l int\n\t_ = l\n\tif len(m.Value) > 0 {\n\t\tfor iNdEx := len(m.Value) - 1; iNdEx >= 0; iNdEx-- {\n\t\t\ti -= len(m.Value[iNdEx])\n\t\t\tcopy(dAtA[i:], m.Value[iNdEx])\n\t\t\ti = encodeVarintPlugin(dAtA, i, uint64(len(m.Value[iNdEx])))\n\t\t\ti--\n\t\t\tdAtA[i] = 0x1a\n\t\t}\n\t}\n\tif len(m.Description) > 0 {\n\t\ti -= len(m.Description)\n\t\tcopy(dAtA[i:], m.Description)\n\t\ti = encodeVarintPlugin(dAtA, i, uint64(len(m.Description)))\n\t\ti--\n\t\tdAtA[i] = 0x12\n\t}\n\tif len(m.Name) > 0 {\n\t\ti -= len(m.Name)\n\t\tcopy(dAtA[i:], m.Name)\n\t\ti = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))\n\t\ti--\n\t\tdAtA[i] = 0xa\n\t}\n\treturn len(dAtA) - i, nil\n}\n\nfunc encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {\n\toffset -= sovPlugin(v)\n\tbase := offset\n\tfor v >= 1<<7 {\n\t\tdAtA[offset] = uint8(v&0x7f | 0x80)\n\t\tv >>= 7\n\t\toffset++\n\t}\n\tdAtA[offset] = uint8(v)\n\treturn base\n}\nfunc (m *PluginSpec) Size() (n int) {\n\tif m == nil {\n\t\treturn 0\n\t}\n\tvar l int\n\t_ = l\n\tl = len(m.Name)\n\tif l > 0 {\n\t\tn += 1 + l + sovPlugin(uint64(l))\n\t}\n\tl = len(m.Remote)\n\tif l > 0 {\n\t\tn += 1 + l + sovPlugin(uint64(l))\n\t}\n\tif len(m.Privileges) > 0 {\n\t\tfor _, e := range m.Privileges {\n\t\t\tl = e.Size()\n\t\t\tn += 1 + l + sovPlugin(uint64(l))\n\t\t}\n\t}\n\tif m.Disabled {\n\t\tn += 2\n\t}\n\tif len(m.Env) > 0 {\n\t\tfor _, s := range m.Env {\n\t\t\tl = len(s)\n\t\t\tn += 1 + l + sovPlugin(uint64(l))\n\t\t}\n\t}\n\treturn n\n}\n\nfunc (m *PluginPrivilege) Size() (n int) {\n\tif m == nil {\n\t\treturn 0\n\t}\n\tvar l int\n\t_ = l\n\tl = len(m.Name)\n\tif l > 0 {\n\t\tn += 1 + l + sovPlugin(uint64(l))\n\t}\n\tl = len(m.Description)\n\tif l > 0 {\n\t\tn += 1 + l + sovPlugin(uint64(l))\n\t}\n\tif len(m.Value) > 0 {\n\t\tfor _, s := range m.Value {\n\t\t\tl = len(s)\n\t\t\tn += 1 + l + sovPlugin(uint64(l))\n\t\t}\n\t}\n\treturn n\n}\n\nfunc sovPlugin(x uint64) (n int) {\n\treturn (math_bits.Len64(x|1) + 6) / 7\n}\nfunc sozPlugin(x uint64) (n int) {\n\treturn sovPlugin(uint64((x << 1) ^ uint64((int64(x) >> 63))))\n}\nfunc (m *PluginSpec) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= uint64(b&0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: PluginSpec: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: PluginSpec: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Name\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= uint64(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Name = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tcase 2:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Remote\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= uint64(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Remote = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tcase 3:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Privileges\", wireType)\n\t\t\t}\n\t\t\tvar msglen int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tmsglen |= int(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif msglen < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tpostIndex := iNdEx + msglen\n\t\t\tif postIndex < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Privileges = append(m.Privileges, &PluginPrivilege{})\n\t\t\tif err := m.Privileges[len(m.Privileges)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tiNdEx = postIndex\n\t\tcase 4:\n\t\t\tif wireType != 0 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Disabled\", wireType)\n\t\t\t}\n\t\t\tvar v int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tv |= int(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tm.Disabled = bool(v != 0)\n\t\tcase 5:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Env\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= uint64(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Env = append(m.Env, string(dAtA[iNdEx:postIndex]))\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipPlugin(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif (skippy < 0) || (iNdEx+skippy) < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc (m *PluginPrivilege) Unmarshal(dAtA []byte) error {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tfor iNdEx < l {\n\t\tpreIndex := iNdEx\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= uint64(b&0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfieldNum := int32(wire >> 3)\n\t\twireType := int(wire & 0x7)\n\t\tif wireType == 4 {\n\t\t\treturn fmt.Errorf(\"proto: PluginPrivilege: wiretype end group for non-group\")\n\t\t}\n\t\tif fieldNum <= 0 {\n\t\t\treturn fmt.Errorf(\"proto: PluginPrivilege: illegal tag %d (wire type %d)\", fieldNum, wire)\n\t\t}\n\t\tswitch fieldNum {\n\t\tcase 1:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Name\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= uint64(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Name = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tcase 2:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Description\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= uint64(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Description = string(dAtA[iNdEx:postIndex])\n\t\t\tiNdEx = postIndex\n\t\tcase 3:\n\t\t\tif wireType != 2 {\n\t\t\t\treturn fmt.Errorf(\"proto: wrong wireType = %d for field Value\", wireType)\n\t\t\t}\n\t\t\tvar stringLen uint64\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tstringLen |= uint64(b&0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tintStringLen := int(stringLen)\n\t\t\tif intStringLen < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tpostIndex := iNdEx + intStringLen\n\t\t\tif postIndex < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif postIndex > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tm.Value = append(m.Value, string(dAtA[iNdEx:postIndex]))\n\t\t\tiNdEx = postIndex\n\t\tdefault:\n\t\t\tiNdEx = preIndex\n\t\t\tskippy, err := skipPlugin(dAtA[iNdEx:])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif (skippy < 0) || (iNdEx+skippy) < 0 {\n\t\t\t\treturn ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tif (iNdEx + skippy) > l {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tiNdEx += skippy\n\t\t}\n\t}\n\n\tif iNdEx > l {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\nfunc skipPlugin(dAtA []byte) (n int, err error) {\n\tl := len(dAtA)\n\tiNdEx := 0\n\tdepth := 0\n\tfor iNdEx < l {\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif shift >= 64 {\n\t\t\t\treturn 0, ErrIntOverflowPlugin\n\t\t\t}\n\t\t\tif iNdEx >= l {\n\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := dAtA[iNdEx]\n\t\t\tiNdEx++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\twireType := int(wire & 0x7)\n\t\tswitch wireType {\n\t\tcase 0:\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn 0, ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tiNdEx++\n\t\t\t\tif dAtA[iNdEx-1] < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\tcase 1:\n\t\t\tiNdEx += 8\n\t\tcase 2:\n\t\t\tvar length int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif shift >= 64 {\n\t\t\t\t\treturn 0, ErrIntOverflowPlugin\n\t\t\t\t}\n\t\t\t\tif iNdEx >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := dAtA[iNdEx]\n\t\t\t\tiNdEx++\n\t\t\t\tlength |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif length < 0 {\n\t\t\t\treturn 0, ErrInvalidLengthPlugin\n\t\t\t}\n\t\t\tiNdEx += length\n\t\tcase 3:\n\t\t\tdepth++\n\t\tcase 4:\n\t\t\tif depth == 0 {\n\t\t\t\treturn 0, ErrUnexpectedEndOfGroupPlugin\n\t\t\t}\n\t\t\tdepth--\n\t\tcase 5:\n\t\t\tiNdEx += 4\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"proto: illegal wireType %d\", wireType)\n\t\t}\n\t\tif iNdEx < 0 {\n\t\t\treturn 0, ErrInvalidLengthPlugin\n\t\t}\n\t\tif depth == 0 {\n\t\t\treturn iNdEx, nil\n\t\t}\n\t}\n\treturn 0, io.ErrUnexpectedEOF\n}\n\nvar (\n\tErrInvalidLengthPlugin        = fmt.Errorf(\"proto: negative length found during unmarshaling\")\n\tErrIntOverflowPlugin          = fmt.Errorf(\"proto: integer overflow\")\n\tErrUnexpectedEndOfGroupPlugin = fmt.Errorf(\"proto: unexpected end of group\")\n)\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/runtime/plugin.proto",
    "content": "syntax = \"proto3\";\n\n// PluginSpec defines the base payload which clients can specify for creating\n// a service with the plugin runtime.\nmessage PluginSpec {\n\tstring name = 1;\n\tstring remote = 2;\n\trepeated PluginPrivilege privileges = 3;\n\tbool disabled = 4;\n\trepeated string env = 5;\n}\n\n// PluginPrivilege describes a permission the user has to accept\n// upon installing a plugin.\nmessage PluginPrivilege {\n\tstring name = 1;\n\tstring description = 2;\n\trepeated string value = 3;\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/runtime.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\n// RuntimeType is the type of runtime used for the TaskSpec\ntype RuntimeType string\n\n// RuntimeURL is the proto type url\ntype RuntimeURL string\n\nconst (\n\t// RuntimeContainer is the container based runtime\n\tRuntimeContainer RuntimeType = \"container\"\n\t// RuntimePlugin is the plugin based runtime\n\tRuntimePlugin RuntimeType = \"plugin\"\n\t// RuntimeNetworkAttachment is the network attachment runtime\n\tRuntimeNetworkAttachment RuntimeType = \"attachment\"\n\n\t// RuntimeURLContainer is the proto url for the container type\n\tRuntimeURLContainer RuntimeURL = \"types.docker.com/RuntimeContainer\"\n\t// RuntimeURLPlugin is the proto url for the plugin type\n\tRuntimeURLPlugin RuntimeURL = \"types.docker.com/RuntimePlugin\"\n)\n\n// NetworkAttachmentSpec represents the runtime spec type for network\n// attachment tasks\ntype NetworkAttachmentSpec struct {\n\tContainerID string\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/secret.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport \"os\"\n\n// Secret represents a secret.\ntype Secret struct {\n\tID string\n\tMeta\n\tSpec SecretSpec\n}\n\n// SecretSpec represents a secret specification from a secret in swarm\ntype SecretSpec struct {\n\tAnnotations\n\tData   []byte  `json:\",omitempty\"`\n\tDriver *Driver `json:\",omitempty\"` // name of the secrets driver used to fetch the secret's value from an external secret store\n\n\t// Templating controls whether and how to evaluate the secret payload as\n\t// a template. If it is not set, no templating is used.\n\tTemplating *Driver `json:\",omitempty\"`\n}\n\n// SecretReferenceFileTarget is a file target in a secret reference\ntype SecretReferenceFileTarget struct {\n\tName string\n\tUID  string\n\tGID  string\n\tMode os.FileMode\n}\n\n// SecretReference is a reference to a secret in swarm\ntype SecretReference struct {\n\tFile       *SecretReferenceFileTarget\n\tSecretID   string\n\tSecretName string\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/service.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport \"time\"\n\n// Service represents a service.\ntype Service struct {\n\tID string\n\tMeta\n\tSpec         ServiceSpec   `json:\",omitempty\"`\n\tPreviousSpec *ServiceSpec  `json:\",omitempty\"`\n\tEndpoint     Endpoint      `json:\",omitempty\"`\n\tUpdateStatus *UpdateStatus `json:\",omitempty\"`\n\n\t// ServiceStatus is an optional, extra field indicating the number of\n\t// desired and running tasks. It is provided primarily as a shortcut to\n\t// calculating these values client-side, which otherwise would require\n\t// listing all tasks for a service, an operation that could be\n\t// computation and network expensive.\n\tServiceStatus *ServiceStatus `json:\",omitempty\"`\n\n\t// JobStatus is the status of a Service which is in one of ReplicatedJob or\n\t// GlobalJob modes. It is absent on Replicated and Global services.\n\tJobStatus *JobStatus `json:\",omitempty\"`\n}\n\n// ServiceSpec represents the spec of a service.\ntype ServiceSpec struct {\n\tAnnotations\n\n\t// TaskTemplate defines how the service should construct new tasks when\n\t// orchestrating this service.\n\tTaskTemplate   TaskSpec      `json:\",omitempty\"`\n\tMode           ServiceMode   `json:\",omitempty\"`\n\tUpdateConfig   *UpdateConfig `json:\",omitempty\"`\n\tRollbackConfig *UpdateConfig `json:\",omitempty\"`\n\n\t// Networks specifies which networks the service should attach to.\n\t//\n\t// Deprecated: This field is deprecated since v1.44. The Networks field in TaskSpec should be used instead.\n\tNetworks     []NetworkAttachmentConfig `json:\",omitempty\"`\n\tEndpointSpec *EndpointSpec             `json:\",omitempty\"`\n}\n\n// ServiceMode represents the mode of a service.\ntype ServiceMode struct {\n\tReplicated    *ReplicatedService `json:\",omitempty\"`\n\tGlobal        *GlobalService     `json:\",omitempty\"`\n\tReplicatedJob *ReplicatedJob     `json:\",omitempty\"`\n\tGlobalJob     *GlobalJob         `json:\",omitempty\"`\n}\n\n// UpdateState is the state of a service update.\ntype UpdateState string\n\nconst (\n\t// UpdateStateUpdating is the updating state.\n\tUpdateStateUpdating UpdateState = \"updating\"\n\t// UpdateStatePaused is the paused state.\n\tUpdateStatePaused UpdateState = \"paused\"\n\t// UpdateStateCompleted is the completed state.\n\tUpdateStateCompleted UpdateState = \"completed\"\n\t// UpdateStateRollbackStarted is the state with a rollback in progress.\n\tUpdateStateRollbackStarted UpdateState = \"rollback_started\"\n\t// UpdateStateRollbackPaused is the state with a rollback in progress.\n\tUpdateStateRollbackPaused UpdateState = \"rollback_paused\"\n\t// UpdateStateRollbackCompleted is the state with a rollback in progress.\n\tUpdateStateRollbackCompleted UpdateState = \"rollback_completed\"\n)\n\n// UpdateStatus reports the status of a service update.\ntype UpdateStatus struct {\n\tState       UpdateState `json:\",omitempty\"`\n\tStartedAt   *time.Time  `json:\",omitempty\"`\n\tCompletedAt *time.Time  `json:\",omitempty\"`\n\tMessage     string      `json:\",omitempty\"`\n}\n\n// ReplicatedService is a kind of ServiceMode.\ntype ReplicatedService struct {\n\tReplicas *uint64 `json:\",omitempty\"`\n}\n\n// GlobalService is a kind of ServiceMode.\ntype GlobalService struct{}\n\n// ReplicatedJob is the a type of Service which executes a defined Tasks\n// in parallel until the specified number of Tasks have succeeded.\ntype ReplicatedJob struct {\n\t// MaxConcurrent indicates the maximum number of Tasks that should be\n\t// executing simultaneously for this job at any given time. There may be\n\t// fewer Tasks that MaxConcurrent executing simultaneously; for example, if\n\t// there are fewer than MaxConcurrent tasks needed to reach\n\t// TotalCompletions.\n\t//\n\t// If this field is empty, it will default to a max concurrency of 1.\n\tMaxConcurrent *uint64 `json:\",omitempty\"`\n\n\t// TotalCompletions is the total number of Tasks desired to run to\n\t// completion.\n\t//\n\t// If this field is empty, the value of MaxConcurrent will be used.\n\tTotalCompletions *uint64 `json:\",omitempty\"`\n}\n\n// GlobalJob is the type of a Service which executes a Task on every Node\n// matching the Service's placement constraints. These tasks run to completion\n// and then exit.\n//\n// This type is deliberately empty.\ntype GlobalJob struct{}\n\nconst (\n\t// UpdateFailureActionPause PAUSE\n\tUpdateFailureActionPause = \"pause\"\n\t// UpdateFailureActionContinue CONTINUE\n\tUpdateFailureActionContinue = \"continue\"\n\t// UpdateFailureActionRollback ROLLBACK\n\tUpdateFailureActionRollback = \"rollback\"\n\n\t// UpdateOrderStopFirst STOP_FIRST\n\tUpdateOrderStopFirst = \"stop-first\"\n\t// UpdateOrderStartFirst START_FIRST\n\tUpdateOrderStartFirst = \"start-first\"\n)\n\n// UpdateConfig represents the update configuration.\ntype UpdateConfig struct {\n\t// Maximum number of tasks to be updated in one iteration.\n\t// 0 means unlimited parallelism.\n\tParallelism uint64\n\n\t// Amount of time between updates.\n\tDelay time.Duration `json:\",omitempty\"`\n\n\t// FailureAction is the action to take when an update failures.\n\tFailureAction string `json:\",omitempty\"`\n\n\t// Monitor indicates how long to monitor a task for failure after it is\n\t// created. If the task fails by ending up in one of the states\n\t// REJECTED, COMPLETED, or FAILED, within Monitor from its creation,\n\t// this counts as a failure. If it fails after Monitor, it does not\n\t// count as a failure. If Monitor is unspecified, a default value will\n\t// be used.\n\tMonitor time.Duration `json:\",omitempty\"`\n\n\t// MaxFailureRatio is the fraction of tasks that may fail during\n\t// an update before the failure action is invoked. Any task created by\n\t// the current update which ends up in one of the states REJECTED,\n\t// COMPLETED or FAILED within Monitor from its creation counts as a\n\t// failure. The number of failures is divided by the number of tasks\n\t// being updated, and if this fraction is greater than\n\t// MaxFailureRatio, the failure action is invoked.\n\t//\n\t// If the failure action is CONTINUE, there is no effect.\n\t// If the failure action is PAUSE, no more tasks will be updated until\n\t// another update is started.\n\tMaxFailureRatio float32\n\n\t// Order indicates the order of operations when rolling out an updated\n\t// task. Either the old task is shut down before the new task is\n\t// started, or the new task is started before the old task is shut down.\n\tOrder string\n}\n\n// ServiceStatus represents the number of running tasks in a service and the\n// number of tasks desired to be running.\ntype ServiceStatus struct {\n\t// RunningTasks is the number of tasks for the service actually in the\n\t// Running state\n\tRunningTasks uint64\n\n\t// DesiredTasks is the number of tasks desired to be running by the\n\t// service. For replicated services, this is the replica count. For global\n\t// services, this is computed by taking the number of tasks with desired\n\t// state of not-Shutdown.\n\tDesiredTasks uint64\n\n\t// CompletedTasks is the number of tasks in the state Completed, if this\n\t// service is in ReplicatedJob or GlobalJob mode. This field must be\n\t// cross-referenced with the service type, because the default value of 0\n\t// may mean that a service is not in a job mode, or it may mean that the\n\t// job has yet to complete any tasks.\n\tCompletedTasks uint64\n}\n\n// JobStatus is the status of a job-type service.\ntype JobStatus struct {\n\t// JobIteration is a value increased each time a Job is executed,\n\t// successfully or otherwise. \"Executed\", in this case, means the job as a\n\t// whole has been started, not that an individual Task has been launched. A\n\t// job is \"Executed\" when its ServiceSpec is updated. JobIteration can be\n\t// used to disambiguate Tasks belonging to different executions of a job.\n\t//\n\t// Though JobIteration will increase with each subsequent execution, it may\n\t// not necessarily increase by 1, and so JobIteration should not be used to\n\t// keep track of the number of times a job has been executed.\n\tJobIteration Version\n\n\t// LastExecution is the time that the job was last executed, as observed by\n\t// Swarm manager.\n\tLastExecution time.Time `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/service_create_response.go",
    "content": "package swarm\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// ServiceCreateResponse contains the information returned to a client on the\n// creation of a new service.\n//\n// swagger:model ServiceCreateResponse\ntype ServiceCreateResponse struct {\n\n\t// The ID of the created service.\n\tID string `json:\"ID,omitempty\"`\n\n\t// Optional warning message.\n\t//\n\t// FIXME(thaJeztah): this should have \"omitempty\" in the generated type.\n\t//\n\tWarnings []string `json:\"Warnings\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/service_update_response.go",
    "content": "package swarm\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// ServiceUpdateResponse service update response\n// swagger:model ServiceUpdateResponse\ntype ServiceUpdateResponse struct {\n\n\t// Optional warning messages\n\tWarnings []string `json:\"Warnings\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/swarm.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport (\n\t\"time\"\n)\n\n// ClusterInfo represents info about the cluster for outputting in \"info\"\n// it contains the same information as \"Swarm\", but without the JoinTokens\ntype ClusterInfo struct {\n\tID string\n\tMeta\n\tSpec                   Spec\n\tTLSInfo                TLSInfo\n\tRootRotationInProgress bool\n\tDefaultAddrPool        []string\n\tSubnetSize             uint32\n\tDataPathPort           uint32\n}\n\n// Swarm represents a swarm.\ntype Swarm struct {\n\tClusterInfo\n\tJoinTokens JoinTokens\n}\n\n// JoinTokens contains the tokens workers and managers need to join the swarm.\ntype JoinTokens struct {\n\t// Worker is the join token workers may use to join the swarm.\n\tWorker string\n\t// Manager is the join token managers may use to join the swarm.\n\tManager string\n}\n\n// Spec represents the spec of a swarm.\ntype Spec struct {\n\tAnnotations\n\n\tOrchestration    OrchestrationConfig `json:\",omitempty\"`\n\tRaft             RaftConfig          `json:\",omitempty\"`\n\tDispatcher       DispatcherConfig    `json:\",omitempty\"`\n\tCAConfig         CAConfig            `json:\",omitempty\"`\n\tTaskDefaults     TaskDefaults        `json:\",omitempty\"`\n\tEncryptionConfig EncryptionConfig    `json:\",omitempty\"`\n}\n\n// OrchestrationConfig represents orchestration configuration.\ntype OrchestrationConfig struct {\n\t// TaskHistoryRetentionLimit is the number of historic tasks to keep per instance or\n\t// node. If negative, never remove completed or failed tasks.\n\tTaskHistoryRetentionLimit *int64 `json:\",omitempty\"`\n}\n\n// TaskDefaults parameterizes cluster-level task creation with default values.\ntype TaskDefaults struct {\n\t// LogDriver selects the log driver to use for tasks created in the\n\t// orchestrator if unspecified by a service.\n\t//\n\t// Updating this value will only have an affect on new tasks. Old tasks\n\t// will continue use their previously configured log driver until\n\t// recreated.\n\tLogDriver *Driver `json:\",omitempty\"`\n}\n\n// EncryptionConfig controls at-rest encryption of data and keys.\ntype EncryptionConfig struct {\n\t// AutoLockManagers specifies whether or not managers TLS keys and raft data\n\t// should be encrypted at rest in such a way that they must be unlocked\n\t// before the manager node starts up again.\n\tAutoLockManagers bool\n}\n\n// RaftConfig represents raft configuration.\ntype RaftConfig struct {\n\t// SnapshotInterval is the number of log entries between snapshots.\n\tSnapshotInterval uint64 `json:\",omitempty\"`\n\n\t// KeepOldSnapshots is the number of snapshots to keep beyond the\n\t// current snapshot.\n\tKeepOldSnapshots *uint64 `json:\",omitempty\"`\n\n\t// LogEntriesForSlowFollowers is the number of log entries to keep\n\t// around to sync up slow followers after a snapshot is created.\n\tLogEntriesForSlowFollowers uint64 `json:\",omitempty\"`\n\n\t// ElectionTick is the number of ticks that a follower will wait for a message\n\t// from the leader before becoming a candidate and starting an election.\n\t// ElectionTick must be greater than HeartbeatTick.\n\t//\n\t// A tick currently defaults to one second, so these translate directly to\n\t// seconds currently, but this is NOT guaranteed.\n\tElectionTick int\n\n\t// HeartbeatTick is the number of ticks between heartbeats. Every\n\t// HeartbeatTick ticks, the leader will send a heartbeat to the\n\t// followers.\n\t//\n\t// A tick currently defaults to one second, so these translate directly to\n\t// seconds currently, but this is NOT guaranteed.\n\tHeartbeatTick int\n}\n\n// DispatcherConfig represents dispatcher configuration.\ntype DispatcherConfig struct {\n\t// HeartbeatPeriod defines how often agent should send heartbeats to\n\t// dispatcher.\n\tHeartbeatPeriod time.Duration `json:\",omitempty\"`\n}\n\n// CAConfig represents CA configuration.\ntype CAConfig struct {\n\t// NodeCertExpiry is the duration certificates should be issued for\n\tNodeCertExpiry time.Duration `json:\",omitempty\"`\n\n\t// ExternalCAs is a list of CAs to which a manager node will make\n\t// certificate signing requests for node certificates.\n\tExternalCAs []*ExternalCA `json:\",omitempty\"`\n\n\t// SigningCACert and SigningCAKey specify the desired signing root CA and\n\t// root CA key for the swarm.  When inspecting the cluster, the key will\n\t// be redacted.\n\tSigningCACert string `json:\",omitempty\"`\n\tSigningCAKey  string `json:\",omitempty\"`\n\n\t// If this value changes, and there is no specified signing cert and key,\n\t// then the swarm is forced to generate a new root certificate ane key.\n\tForceRotate uint64 `json:\",omitempty\"`\n}\n\n// ExternalCAProtocol represents type of external CA.\ntype ExternalCAProtocol string\n\n// ExternalCAProtocolCFSSL CFSSL\nconst ExternalCAProtocolCFSSL ExternalCAProtocol = \"cfssl\"\n\n// ExternalCA defines external CA to be used by the cluster.\ntype ExternalCA struct {\n\t// Protocol is the protocol used by this external CA.\n\tProtocol ExternalCAProtocol\n\n\t// URL is the URL where the external CA can be reached.\n\tURL string\n\n\t// Options is a set of additional key/value pairs whose interpretation\n\t// depends on the specified CA type.\n\tOptions map[string]string `json:\",omitempty\"`\n\n\t// CACert specifies which root CA is used by this external CA.  This certificate must\n\t// be in PEM format.\n\tCACert string\n}\n\n// InitRequest is the request used to init a swarm.\ntype InitRequest struct {\n\tListenAddr       string\n\tAdvertiseAddr    string\n\tDataPathAddr     string\n\tDataPathPort     uint32\n\tForceNewCluster  bool\n\tSpec             Spec\n\tAutoLockManagers bool\n\tAvailability     NodeAvailability\n\tDefaultAddrPool  []string\n\tSubnetSize       uint32\n}\n\n// JoinRequest is the request used to join a swarm.\ntype JoinRequest struct {\n\tListenAddr    string\n\tAdvertiseAddr string\n\tDataPathAddr  string\n\tRemoteAddrs   []string\n\tJoinToken     string // accept by secret\n\tAvailability  NodeAvailability\n}\n\n// UnlockRequest is the request used to unlock a swarm.\ntype UnlockRequest struct {\n\t// UnlockKey is the unlock key in ASCII-armored format.\n\tUnlockKey string\n}\n\n// LocalNodeState represents the state of the local node.\ntype LocalNodeState string\n\nconst (\n\t// LocalNodeStateInactive INACTIVE\n\tLocalNodeStateInactive LocalNodeState = \"inactive\"\n\t// LocalNodeStatePending PENDING\n\tLocalNodeStatePending LocalNodeState = \"pending\"\n\t// LocalNodeStateActive ACTIVE\n\tLocalNodeStateActive LocalNodeState = \"active\"\n\t// LocalNodeStateError ERROR\n\tLocalNodeStateError LocalNodeState = \"error\"\n\t// LocalNodeStateLocked LOCKED\n\tLocalNodeStateLocked LocalNodeState = \"locked\"\n)\n\n// Info represents generic information about swarm.\ntype Info struct {\n\tNodeID   string\n\tNodeAddr string\n\n\tLocalNodeState   LocalNodeState\n\tControlAvailable bool\n\tError            string\n\n\tRemoteManagers []Peer\n\tNodes          int `json:\",omitempty\"`\n\tManagers       int `json:\",omitempty\"`\n\n\tCluster *ClusterInfo `json:\",omitempty\"`\n\n\tWarnings []string `json:\",omitempty\"`\n}\n\n// Status provides information about the current swarm status and role,\n// obtained from the \"Swarm\" header in the API response.\ntype Status struct {\n\t// NodeState represents the state of the node.\n\tNodeState LocalNodeState\n\n\t// ControlAvailable indicates if the node is a swarm manager.\n\tControlAvailable bool\n}\n\n// Peer represents a peer.\ntype Peer struct {\n\tNodeID string\n\tAddr   string\n}\n\n// UpdateFlags contains flags for SwarmUpdate.\ntype UpdateFlags struct {\n\tRotateWorkerToken      bool\n\tRotateManagerToken     bool\n\tRotateManagerUnlockKey bool\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/swarm/task.go",
    "content": "package swarm // import \"github.com/docker/docker/api/types/swarm\"\n\nimport (\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/swarm/runtime\"\n)\n\n// TaskState represents the state of a task.\ntype TaskState string\n\nconst (\n\t// TaskStateNew NEW\n\tTaskStateNew TaskState = \"new\"\n\t// TaskStateAllocated ALLOCATED\n\tTaskStateAllocated TaskState = \"allocated\"\n\t// TaskStatePending PENDING\n\tTaskStatePending TaskState = \"pending\"\n\t// TaskStateAssigned ASSIGNED\n\tTaskStateAssigned TaskState = \"assigned\"\n\t// TaskStateAccepted ACCEPTED\n\tTaskStateAccepted TaskState = \"accepted\"\n\t// TaskStatePreparing PREPARING\n\tTaskStatePreparing TaskState = \"preparing\"\n\t// TaskStateReady READY\n\tTaskStateReady TaskState = \"ready\"\n\t// TaskStateStarting STARTING\n\tTaskStateStarting TaskState = \"starting\"\n\t// TaskStateRunning RUNNING\n\tTaskStateRunning TaskState = \"running\"\n\t// TaskStateComplete COMPLETE\n\tTaskStateComplete TaskState = \"complete\"\n\t// TaskStateShutdown SHUTDOWN\n\tTaskStateShutdown TaskState = \"shutdown\"\n\t// TaskStateFailed FAILED\n\tTaskStateFailed TaskState = \"failed\"\n\t// TaskStateRejected REJECTED\n\tTaskStateRejected TaskState = \"rejected\"\n\t// TaskStateRemove REMOVE\n\tTaskStateRemove TaskState = \"remove\"\n\t// TaskStateOrphaned ORPHANED\n\tTaskStateOrphaned TaskState = \"orphaned\"\n)\n\n// Task represents a task.\ntype Task struct {\n\tID string\n\tMeta\n\tAnnotations\n\n\tSpec                TaskSpec            `json:\",omitempty\"`\n\tServiceID           string              `json:\",omitempty\"`\n\tSlot                int                 `json:\",omitempty\"`\n\tNodeID              string              `json:\",omitempty\"`\n\tStatus              TaskStatus          `json:\",omitempty\"`\n\tDesiredState        TaskState           `json:\",omitempty\"`\n\tNetworksAttachments []NetworkAttachment `json:\",omitempty\"`\n\tGenericResources    []GenericResource   `json:\",omitempty\"`\n\n\t// JobIteration is the JobIteration of the Service that this Task was\n\t// spawned from, if the Service is a ReplicatedJob or GlobalJob. This is\n\t// used to determine which Tasks belong to which run of the job. This field\n\t// is absent if the Service mode is Replicated or Global.\n\tJobIteration *Version `json:\",omitempty\"`\n\n\t// Volumes is the list of VolumeAttachments for this task. It specifies\n\t// which particular volumes are to be used by this particular task, and\n\t// fulfilling what mounts in the spec.\n\tVolumes []VolumeAttachment\n}\n\n// TaskSpec represents the spec of a task.\ntype TaskSpec struct {\n\t// ContainerSpec, NetworkAttachmentSpec, and PluginSpec are mutually exclusive.\n\t// PluginSpec is only used when the `Runtime` field is set to `plugin`\n\t// NetworkAttachmentSpec is used if the `Runtime` field is set to\n\t// `attachment`.\n\tContainerSpec         *ContainerSpec         `json:\",omitempty\"`\n\tPluginSpec            *runtime.PluginSpec    `json:\",omitempty\"`\n\tNetworkAttachmentSpec *NetworkAttachmentSpec `json:\",omitempty\"`\n\n\tResources     *ResourceRequirements     `json:\",omitempty\"`\n\tRestartPolicy *RestartPolicy            `json:\",omitempty\"`\n\tPlacement     *Placement                `json:\",omitempty\"`\n\tNetworks      []NetworkAttachmentConfig `json:\",omitempty\"`\n\n\t// LogDriver specifies the LogDriver to use for tasks created from this\n\t// spec. If not present, the one on cluster default on swarm.Spec will be\n\t// used, finally falling back to the engine default if not specified.\n\tLogDriver *Driver `json:\",omitempty\"`\n\n\t// ForceUpdate is a counter that triggers an update even if no relevant\n\t// parameters have been changed.\n\tForceUpdate uint64\n\n\tRuntime RuntimeType `json:\",omitempty\"`\n}\n\n// Resources represents resources (CPU/Memory) which can be advertised by a\n// node and requested to be reserved for a task.\ntype Resources struct {\n\tNanoCPUs         int64             `json:\",omitempty\"`\n\tMemoryBytes      int64             `json:\",omitempty\"`\n\tGenericResources []GenericResource `json:\",omitempty\"`\n}\n\n// Limit describes limits on resources which can be requested by a task.\ntype Limit struct {\n\tNanoCPUs    int64 `json:\",omitempty\"`\n\tMemoryBytes int64 `json:\",omitempty\"`\n\tPids        int64 `json:\",omitempty\"`\n}\n\n// GenericResource represents a \"user defined\" resource which can\n// be either an integer (e.g: SSD=3) or a string (e.g: SSD=sda1)\ntype GenericResource struct {\n\tNamedResourceSpec    *NamedGenericResource    `json:\",omitempty\"`\n\tDiscreteResourceSpec *DiscreteGenericResource `json:\",omitempty\"`\n}\n\n// NamedGenericResource represents a \"user defined\" resource which is defined\n// as a string.\n// \"Kind\" is used to describe the Kind of a resource (e.g: \"GPU\", \"FPGA\", \"SSD\", ...)\n// Value is used to identify the resource (GPU=\"UUID-1\", FPGA=\"/dev/sdb5\", ...)\ntype NamedGenericResource struct {\n\tKind  string `json:\",omitempty\"`\n\tValue string `json:\",omitempty\"`\n}\n\n// DiscreteGenericResource represents a \"user defined\" resource which is defined\n// as an integer\n// \"Kind\" is used to describe the Kind of a resource (e.g: \"GPU\", \"FPGA\", \"SSD\", ...)\n// Value is used to count the resource (SSD=5, HDD=3, ...)\ntype DiscreteGenericResource struct {\n\tKind  string `json:\",omitempty\"`\n\tValue int64  `json:\",omitempty\"`\n}\n\n// ResourceRequirements represents resources requirements.\ntype ResourceRequirements struct {\n\tLimits       *Limit     `json:\",omitempty\"`\n\tReservations *Resources `json:\",omitempty\"`\n}\n\n// Placement represents orchestration parameters.\ntype Placement struct {\n\tConstraints []string              `json:\",omitempty\"`\n\tPreferences []PlacementPreference `json:\",omitempty\"`\n\tMaxReplicas uint64                `json:\",omitempty\"`\n\n\t// Platforms stores all the platforms that the image can run on.\n\t// This field is used in the platform filter for scheduling. If empty,\n\t// then the platform filter is off, meaning there are no scheduling restrictions.\n\tPlatforms []Platform `json:\",omitempty\"`\n}\n\n// PlacementPreference provides a way to make the scheduler aware of factors\n// such as topology.\ntype PlacementPreference struct {\n\tSpread *SpreadOver\n}\n\n// SpreadOver is a scheduling preference that instructs the scheduler to spread\n// tasks evenly over groups of nodes identified by labels.\ntype SpreadOver struct {\n\t// label descriptor, such as engine.labels.az\n\tSpreadDescriptor string\n}\n\n// RestartPolicy represents the restart policy.\ntype RestartPolicy struct {\n\tCondition   RestartPolicyCondition `json:\",omitempty\"`\n\tDelay       *time.Duration         `json:\",omitempty\"`\n\tMaxAttempts *uint64                `json:\",omitempty\"`\n\tWindow      *time.Duration         `json:\",omitempty\"`\n}\n\n// RestartPolicyCondition represents when to restart.\ntype RestartPolicyCondition string\n\nconst (\n\t// RestartPolicyConditionNone NONE\n\tRestartPolicyConditionNone RestartPolicyCondition = \"none\"\n\t// RestartPolicyConditionOnFailure ON_FAILURE\n\tRestartPolicyConditionOnFailure RestartPolicyCondition = \"on-failure\"\n\t// RestartPolicyConditionAny ANY\n\tRestartPolicyConditionAny RestartPolicyCondition = \"any\"\n)\n\n// TaskStatus represents the status of a task.\ntype TaskStatus struct {\n\tTimestamp       time.Time        `json:\",omitempty\"`\n\tState           TaskState        `json:\",omitempty\"`\n\tMessage         string           `json:\",omitempty\"`\n\tErr             string           `json:\",omitempty\"`\n\tContainerStatus *ContainerStatus `json:\",omitempty\"`\n\tPortStatus      PortStatus       `json:\",omitempty\"`\n}\n\n// ContainerStatus represents the status of a container.\ntype ContainerStatus struct {\n\tContainerID string\n\tPID         int\n\tExitCode    int\n}\n\n// PortStatus represents the port status of a task's host ports whose\n// service has published host ports\ntype PortStatus struct {\n\tPorts []PortConfig `json:\",omitempty\"`\n}\n\n// VolumeAttachment contains the associating a Volume to a Task.\ntype VolumeAttachment struct {\n\t// ID is the Swarmkit ID of the Volume. This is not the CSI VolumeId.\n\tID string `json:\",omitempty\"`\n\n\t// Source, together with Target, indicates the Mount, as specified in the\n\t// ContainerSpec, that this volume fulfills.\n\tSource string `json:\",omitempty\"`\n\n\t// Target, together with Source, indicates the Mount, as specified\n\t// in the ContainerSpec, that this volume fulfills.\n\tTarget string `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/system/info.go",
    "content": "package system\n\nimport (\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// Info contains response of Engine API:\n// GET \"/info\"\ntype Info struct {\n\tID                 string\n\tContainers         int\n\tContainersRunning  int\n\tContainersPaused   int\n\tContainersStopped  int\n\tImages             int\n\tDriver             string\n\tDriverStatus       [][2]string\n\tSystemStatus       [][2]string `json:\",omitempty\"` // SystemStatus is only propagated by the Swarm standalone API\n\tPlugins            PluginsInfo\n\tMemoryLimit        bool\n\tSwapLimit          bool\n\tKernelMemory       bool `json:\",omitempty\"` // Deprecated: kernel 5.4 deprecated kmem.limit_in_bytes\n\tKernelMemoryTCP    bool `json:\",omitempty\"` // KernelMemoryTCP is not supported on cgroups v2.\n\tCPUCfsPeriod       bool `json:\"CpuCfsPeriod\"`\n\tCPUCfsQuota        bool `json:\"CpuCfsQuota\"`\n\tCPUShares          bool\n\tCPUSet             bool\n\tPidsLimit          bool\n\tIPv4Forwarding     bool\n\tBridgeNfIptables   bool\n\tBridgeNfIP6tables  bool `json:\"BridgeNfIp6tables\"`\n\tDebug              bool\n\tNFd                int\n\tOomKillDisable     bool\n\tNGoroutines        int\n\tSystemTime         string\n\tLoggingDriver      string\n\tCgroupDriver       string\n\tCgroupVersion      string `json:\",omitempty\"`\n\tNEventsListener    int\n\tKernelVersion      string\n\tOperatingSystem    string\n\tOSVersion          string\n\tOSType             string\n\tArchitecture       string\n\tIndexServerAddress string\n\tRegistryConfig     *registry.ServiceConfig\n\tNCPU               int\n\tMemTotal           int64\n\tGenericResources   []swarm.GenericResource\n\tDockerRootDir      string\n\tHTTPProxy          string `json:\"HttpProxy\"`\n\tHTTPSProxy         string `json:\"HttpsProxy\"`\n\tNoProxy            string\n\tName               string\n\tLabels             []string\n\tExperimentalBuild  bool\n\tServerVersion      string\n\tRuntimes           map[string]RuntimeWithStatus\n\tDefaultRuntime     string\n\tSwarm              swarm.Info\n\t// LiveRestoreEnabled determines whether containers should be kept\n\t// running when the daemon is shutdown or upon daemon start if\n\t// running containers are detected\n\tLiveRestoreEnabled  bool\n\tIsolation           container.Isolation\n\tInitBinary          string\n\tContainerdCommit    Commit\n\tRuncCommit          Commit\n\tInitCommit          Commit\n\tSecurityOptions     []string\n\tProductLicense      string               `json:\",omitempty\"`\n\tDefaultAddressPools []NetworkAddressPool `json:\",omitempty\"`\n\tCDISpecDirs         []string\n\n\t// Legacy API fields for older API versions.\n\tlegacyFields\n\n\t// Warnings contains a slice of warnings that occurred  while collecting\n\t// system information. These warnings are intended to be informational\n\t// messages for the user, and are not intended to be parsed / used for\n\t// other purposes, as they do not have a fixed format.\n\tWarnings []string\n}\n\ntype legacyFields struct {\n\tExecutionDriver string `json:\",omitempty\"` // Deprecated: deprecated since API v1.25, but returned for older versions.\n}\n\n// PluginsInfo is a temp struct holding Plugins name\n// registered with docker daemon. It is used by [Info] struct\ntype PluginsInfo struct {\n\t// List of Volume plugins registered\n\tVolume []string\n\t// List of Network plugins registered\n\tNetwork []string\n\t// List of Authorization plugins registered\n\tAuthorization []string\n\t// List of Log plugins registered\n\tLog []string\n}\n\n// Commit holds the Git-commit (SHA1) that a binary was built from, as reported\n// in the version-string of external tools, such as containerd, or runC.\ntype Commit struct {\n\tID       string // ID is the actual commit ID of external tool.\n\tExpected string // Expected is the commit ID of external tool expected by dockerd as set at build time.\n}\n\n// NetworkAddressPool is a temp struct used by [Info] struct.\ntype NetworkAddressPool struct {\n\tBase string\n\tSize int\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/system/runtime.go",
    "content": "package system\n\n// Runtime describes an OCI runtime\ntype Runtime struct {\n\t// \"Legacy\" runtime configuration for runc-compatible runtimes.\n\n\tPath string   `json:\"path,omitempty\"`\n\tArgs []string `json:\"runtimeArgs,omitempty\"`\n\n\t// Shimv2 runtime configuration. Mutually exclusive with the legacy config above.\n\n\tType    string                 `json:\"runtimeType,omitempty\"`\n\tOptions map[string]interface{} `json:\"options,omitempty\"`\n}\n\n// RuntimeWithStatus extends [Runtime] to hold [RuntimeStatus].\ntype RuntimeWithStatus struct {\n\tRuntime\n\tStatus map[string]string `json:\"status,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/system/security_opts.go",
    "content": "package system\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// SecurityOpt contains the name and options of a security option\ntype SecurityOpt struct {\n\tName    string\n\tOptions []KeyValue\n}\n\n// DecodeSecurityOptions decodes a security options string slice to a\n// type-safe [SecurityOpt].\nfunc DecodeSecurityOptions(opts []string) ([]SecurityOpt, error) {\n\tso := []SecurityOpt{}\n\tfor _, opt := range opts {\n\t\t// support output from a < 1.13 docker daemon\n\t\tif !strings.Contains(opt, \"=\") {\n\t\t\tso = append(so, SecurityOpt{Name: opt})\n\t\t\tcontinue\n\t\t}\n\t\tsecopt := SecurityOpt{}\n\t\tfor _, s := range strings.Split(opt, \",\") {\n\t\t\tk, v, ok := strings.Cut(s, \"=\")\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"invalid security option %q\", s)\n\t\t\t}\n\t\t\tif k == \"\" || v == \"\" {\n\t\t\t\treturn nil, errors.New(\"invalid empty security option\")\n\t\t\t}\n\t\t\tif k == \"name\" {\n\t\t\t\tsecopt.Name = v\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsecopt.Options = append(secopt.Options, KeyValue{Key: k, Value: v})\n\t\t}\n\t\tso = append(so, secopt)\n\t}\n\treturn so, nil\n}\n\n// KeyValue holds a key/value pair.\ntype KeyValue struct {\n\tKey, Value string\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/time/timestamp.go",
    "content": "package time // import \"github.com/docker/docker/api/types/time\"\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// These are additional predefined layouts for use in Time.Format and Time.Parse\n// with --since and --until parameters for `docker logs` and `docker events`\nconst (\n\trFC3339Local     = \"2006-01-02T15:04:05\"           // RFC3339 with local timezone\n\trFC3339NanoLocal = \"2006-01-02T15:04:05.999999999\" // RFC3339Nano with local timezone\n\tdateWithZone     = \"2006-01-02Z07:00\"              // RFC3339 with time at 00:00:00\n\tdateLocal        = \"2006-01-02\"                    // RFC3339 with local timezone and time at 00:00:00\n)\n\n// GetTimestamp tries to parse given string as golang duration,\n// then RFC3339 time and finally as a Unix timestamp. If\n// any of these were successful, it returns a Unix timestamp\n// as string otherwise returns the given value back.\n// In case of duration input, the returned timestamp is computed\n// as the given reference time minus the amount of the duration.\nfunc GetTimestamp(value string, reference time.Time) (string, error) {\n\tif d, err := time.ParseDuration(value); value != \"0\" && err == nil {\n\t\treturn strconv.FormatInt(reference.Add(-d).Unix(), 10), nil\n\t}\n\n\tvar format string\n\t// if the string has a Z or a + or three dashes use parse otherwise use parseinlocation\n\tparseInLocation := !(strings.ContainsAny(value, \"zZ+\") || strings.Count(value, \"-\") == 3)\n\n\tif strings.Contains(value, \".\") {\n\t\tif parseInLocation {\n\t\t\tformat = rFC3339NanoLocal\n\t\t} else {\n\t\t\tformat = time.RFC3339Nano\n\t\t}\n\t} else if strings.Contains(value, \"T\") {\n\t\t// we want the number of colons in the T portion of the timestamp\n\t\ttcolons := strings.Count(value, \":\")\n\t\t// if parseInLocation is off and we have a +/- zone offset (not Z) then\n\t\t// there will be an extra colon in the input for the tz offset subtract that\n\t\t// colon from the tcolons count\n\t\tif !parseInLocation && !strings.ContainsAny(value, \"zZ\") && tcolons > 0 {\n\t\t\ttcolons--\n\t\t}\n\t\tif parseInLocation {\n\t\t\tswitch tcolons {\n\t\t\tcase 0:\n\t\t\t\tformat = \"2006-01-02T15\"\n\t\t\tcase 1:\n\t\t\t\tformat = \"2006-01-02T15:04\"\n\t\t\tdefault:\n\t\t\t\tformat = rFC3339Local\n\t\t\t}\n\t\t} else {\n\t\t\tswitch tcolons {\n\t\t\tcase 0:\n\t\t\t\tformat = \"2006-01-02T15Z07:00\"\n\t\t\tcase 1:\n\t\t\t\tformat = \"2006-01-02T15:04Z07:00\"\n\t\t\tdefault:\n\t\t\t\tformat = time.RFC3339\n\t\t\t}\n\t\t}\n\t} else if parseInLocation {\n\t\tformat = dateLocal\n\t} else {\n\t\tformat = dateWithZone\n\t}\n\n\tvar t time.Time\n\tvar err error\n\n\tif parseInLocation {\n\t\tt, err = time.ParseInLocation(format, value, time.FixedZone(reference.Zone()))\n\t} else {\n\t\tt, err = time.Parse(format, value)\n\t}\n\n\tif err != nil {\n\t\t// if there is a `-` then it's an RFC3339 like timestamp\n\t\tif strings.Contains(value, \"-\") {\n\t\t\treturn \"\", err // was probably an RFC3339 like timestamp but the parser failed with an error\n\t\t}\n\t\tif _, _, err := parseTimestamp(value); err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to parse value as time or duration: %q\", value)\n\t\t}\n\t\treturn value, nil // unix timestamp in and out case (meaning: the value passed at the command line is already in the right format for passing to the server)\n\t}\n\n\treturn fmt.Sprintf(\"%d.%09d\", t.Unix(), int64(t.Nanosecond())), nil\n}\n\n// ParseTimestamps returns seconds and nanoseconds from a timestamp that has\n// the format (\"%d.%09d\", time.Unix(), int64(time.Nanosecond())).\n// If the incoming nanosecond portion is longer than 9 digits it is truncated.\n// The expectation is that the seconds and nanoseconds will be used to create a\n// time variable.  For example:\n//\n//\tseconds, nanoseconds, _ := ParseTimestamp(\"1136073600.000000001\",0)\n//\tsince := time.Unix(seconds, nanoseconds)\n//\n// returns seconds as defaultSeconds if value == \"\"\nfunc ParseTimestamps(value string, defaultSeconds int64) (seconds int64, nanoseconds int64, err error) {\n\tif value == \"\" {\n\t\treturn defaultSeconds, 0, nil\n\t}\n\treturn parseTimestamp(value)\n}\n\nfunc parseTimestamp(value string) (sec int64, nsec int64, err error) {\n\ts, n, ok := strings.Cut(value, \".\")\n\tsec, err = strconv.ParseInt(s, 10, 64)\n\tif err != nil {\n\t\treturn sec, 0, err\n\t}\n\tif !ok {\n\t\treturn sec, 0, nil\n\t}\n\tnsec, err = strconv.ParseInt(n, 10, 64)\n\tif err != nil {\n\t\treturn sec, nsec, err\n\t}\n\t// should already be in nanoseconds but just in case convert n to nanoseconds\n\tnsec = int64(float64(nsec) * math.Pow(float64(10), float64(9-len(n))))\n\treturn sec, nsec, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/types.go",
    "content": "package types // import \"github.com/docker/docker/api/types\"\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/image\"\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/swarm\"\n\t\"github.com/docker/docker/api/types/volume\"\n\t\"github.com/docker/go-connections/nat\"\n)\n\nconst (\n\t// MediaTypeRawStream is vendor specific MIME-Type set for raw TTY streams\n\tMediaTypeRawStream = \"application/vnd.docker.raw-stream\"\n\n\t// MediaTypeMultiplexedStream is vendor specific MIME-Type set for stdin/stdout/stderr multiplexed streams\n\tMediaTypeMultiplexedStream = \"application/vnd.docker.multiplexed-stream\"\n)\n\n// RootFS returns Image's RootFS description including the layer IDs.\ntype RootFS struct {\n\tType   string   `json:\",omitempty\"`\n\tLayers []string `json:\",omitempty\"`\n}\n\n// ImageInspect contains response of Engine API:\n// GET \"/images/{name:.*}/json\"\ntype ImageInspect struct {\n\t// ID is the content-addressable ID of an image.\n\t//\n\t// This identifier is a content-addressable digest calculated from the\n\t// image's configuration (which includes the digests of layers used by\n\t// the image).\n\t//\n\t// Note that this digest differs from the `RepoDigests` below, which\n\t// holds digests of image manifests that reference the image.\n\tID string `json:\"Id\"`\n\n\t// RepoTags is a list of image names/tags in the local image cache that\n\t// reference this image.\n\t//\n\t// Multiple image tags can refer to the same image, and this list may be\n\t// empty if no tags reference the image, in which case the image is\n\t// \"untagged\", in which case it can still be referenced by its ID.\n\tRepoTags []string\n\n\t// RepoDigests is a list of content-addressable digests of locally available\n\t// image manifests that the image is referenced from. Multiple manifests can\n\t// refer to the same image.\n\t//\n\t// These digests are usually only available if the image was either pulled\n\t// from a registry, or if the image was pushed to a registry, which is when\n\t// the manifest is generated and its digest calculated.\n\tRepoDigests []string\n\n\t// Parent is the ID of the parent image.\n\t//\n\t// Depending on how the image was created, this field may be empty and\n\t// is only set for images that were built/created locally. This field\n\t// is empty if the image was pulled from an image registry.\n\tParent string\n\n\t// Comment is an optional message that can be set when committing or\n\t// importing the image.\n\tComment string\n\n\t// Created is the date and time at which the image was created, formatted in\n\t// RFC 3339 nano-seconds (time.RFC3339Nano).\n\t//\n\t// This information is only available if present in the image,\n\t// and omitted otherwise.\n\tCreated string `json:\",omitempty\"`\n\n\t// Container is the ID of the container that was used to create the image.\n\t//\n\t// Depending on how the image was created, this field may be empty.\n\t//\n\t// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.\n\tContainer string\n\n\t// ContainerConfig is an optional field containing the configuration of the\n\t// container that was last committed when creating the image.\n\t//\n\t// Previous versions of Docker builder used this field to store build cache,\n\t// and it is not in active use anymore.\n\t//\n\t// Deprecated: this field is omitted in API v1.45, but kept for backward compatibility.\n\tContainerConfig *container.Config\n\n\t// DockerVersion is the version of Docker that was used to build the image.\n\t//\n\t// Depending on how the image was created, this field may be empty.\n\tDockerVersion string\n\n\t// Author is the name of the author that was specified when committing the\n\t// image, or as specified through MAINTAINER (deprecated) in the Dockerfile.\n\tAuthor string\n\tConfig *container.Config\n\n\t// Architecture is the hardware CPU architecture that the image runs on.\n\tArchitecture string\n\n\t// Variant is the CPU architecture variant (presently ARM-only).\n\tVariant string `json:\",omitempty\"`\n\n\t// OS is the Operating System the image is built to run on.\n\tOs string\n\n\t// OsVersion is the version of the Operating System the image is built to\n\t// run on (especially for Windows).\n\tOsVersion string `json:\",omitempty\"`\n\n\t// Size is the total size of the image including all layers it is composed of.\n\tSize int64\n\n\t// VirtualSize is the total size of the image including all layers it is\n\t// composed of.\n\t//\n\t// Deprecated: this field is omitted in API v1.44, but kept for backward compatibility. Use Size instead.\n\tVirtualSize int64 `json:\"VirtualSize,omitempty\"`\n\n\t// GraphDriver holds information about the storage driver used to store the\n\t// container's and image's filesystem.\n\tGraphDriver GraphDriverData\n\n\t// RootFS contains information about the image's RootFS, including the\n\t// layer IDs.\n\tRootFS RootFS\n\n\t// Metadata of the image in the local cache.\n\t//\n\t// This information is local to the daemon, and not part of the image itself.\n\tMetadata image.Metadata\n}\n\n// Container contains response of Engine API:\n// GET \"/containers/json\"\ntype Container struct {\n\tID         string `json:\"Id\"`\n\tNames      []string\n\tImage      string\n\tImageID    string\n\tCommand    string\n\tCreated    int64\n\tPorts      []Port\n\tSizeRw     int64 `json:\",omitempty\"`\n\tSizeRootFs int64 `json:\",omitempty\"`\n\tLabels     map[string]string\n\tState      string\n\tStatus     string\n\tHostConfig struct {\n\t\tNetworkMode string `json:\",omitempty\"`\n\t}\n\tNetworkSettings *SummaryNetworkSettings\n\tMounts          []MountPoint\n}\n\n// CopyConfig contains request body of Engine API:\n// POST \"/containers/\"+containerID+\"/copy\"\ntype CopyConfig struct {\n\tResource string\n}\n\n// ContainerPathStat is used to encode the header from\n// GET \"/containers/{name:.*}/archive\"\n// \"Name\" is the file or directory name.\ntype ContainerPathStat struct {\n\tName       string      `json:\"name\"`\n\tSize       int64       `json:\"size\"`\n\tMode       os.FileMode `json:\"mode\"`\n\tMtime      time.Time   `json:\"mtime\"`\n\tLinkTarget string      `json:\"linkTarget\"`\n}\n\n// ContainerStats contains response of Engine API:\n// GET \"/stats\"\ntype ContainerStats struct {\n\tBody   io.ReadCloser `json:\"body\"`\n\tOSType string        `json:\"ostype\"`\n}\n\n// Ping contains response of Engine API:\n// GET \"/_ping\"\ntype Ping struct {\n\tAPIVersion     string\n\tOSType         string\n\tExperimental   bool\n\tBuilderVersion BuilderVersion\n\n\t// SwarmStatus provides information about the current swarm status of the\n\t// engine, obtained from the \"Swarm\" header in the API response.\n\t//\n\t// It can be a nil struct if the API version does not provide this header\n\t// in the ping response, or if an error occurred, in which case the client\n\t// should use other ways to get the current swarm status, such as the /swarm\n\t// endpoint.\n\tSwarmStatus *swarm.Status\n}\n\n// ComponentVersion describes the version information for a specific component.\ntype ComponentVersion struct {\n\tName    string\n\tVersion string\n\tDetails map[string]string `json:\",omitempty\"`\n}\n\n// Version contains response of Engine API:\n// GET \"/version\"\ntype Version struct {\n\tPlatform   struct{ Name string } `json:\",omitempty\"`\n\tComponents []ComponentVersion    `json:\",omitempty\"`\n\n\t// The following fields are deprecated, they relate to the Engine component and are kept for backwards compatibility\n\n\tVersion       string\n\tAPIVersion    string `json:\"ApiVersion\"`\n\tMinAPIVersion string `json:\"MinAPIVersion,omitempty\"`\n\tGitCommit     string\n\tGoVersion     string\n\tOs            string\n\tArch          string\n\tKernelVersion string `json:\",omitempty\"`\n\tExperimental  bool   `json:\",omitempty\"`\n\tBuildTime     string `json:\",omitempty\"`\n}\n\n// ExecStartCheck is a temp struct used by execStart\n// Config fields is part of ExecConfig in runconfig package\ntype ExecStartCheck struct {\n\t// ExecStart will first check if it's detached\n\tDetach bool\n\t// Check if there's a tty\n\tTty bool\n\t// Terminal size [height, width], unused if Tty == false\n\tConsoleSize *[2]uint `json:\",omitempty\"`\n}\n\n// HealthcheckResult stores information about a single run of a healthcheck probe\ntype HealthcheckResult struct {\n\tStart    time.Time // Start is the time this check started\n\tEnd      time.Time // End is the time this check ended\n\tExitCode int       // ExitCode meanings: 0=healthy, 1=unhealthy, 2=reserved (considered unhealthy), else=error running probe\n\tOutput   string    // Output from last check\n}\n\n// Health states\nconst (\n\tNoHealthcheck = \"none\"      // Indicates there is no healthcheck\n\tStarting      = \"starting\"  // Starting indicates that the container is not yet ready\n\tHealthy       = \"healthy\"   // Healthy indicates that the container is running correctly\n\tUnhealthy     = \"unhealthy\" // Unhealthy indicates that the container has a problem\n)\n\n// Health stores information about the container's healthcheck results\ntype Health struct {\n\tStatus        string               // Status is one of Starting, Healthy or Unhealthy\n\tFailingStreak int                  // FailingStreak is the number of consecutive failures\n\tLog           []*HealthcheckResult // Log contains the last few results (oldest first)\n}\n\n// ContainerState stores container's running state\n// it's part of ContainerJSONBase and will return by \"inspect\" command\ntype ContainerState struct {\n\tStatus     string // String representation of the container state. Can be one of \"created\", \"running\", \"paused\", \"restarting\", \"removing\", \"exited\", or \"dead\"\n\tRunning    bool\n\tPaused     bool\n\tRestarting bool\n\tOOMKilled  bool\n\tDead       bool\n\tPid        int\n\tExitCode   int\n\tError      string\n\tStartedAt  string\n\tFinishedAt string\n\tHealth     *Health `json:\",omitempty\"`\n}\n\n// ContainerNode stores information about the node that a container\n// is running on.  It's only used by the Docker Swarm standalone API\ntype ContainerNode struct {\n\tID        string\n\tIPAddress string `json:\"IP\"`\n\tAddr      string\n\tName      string\n\tCpus      int\n\tMemory    int64\n\tLabels    map[string]string\n}\n\n// ContainerJSONBase contains response of Engine API:\n// GET \"/containers/{name:.*}/json\"\ntype ContainerJSONBase struct {\n\tID              string `json:\"Id\"`\n\tCreated         string\n\tPath            string\n\tArgs            []string\n\tState           *ContainerState\n\tImage           string\n\tResolvConfPath  string\n\tHostnamePath    string\n\tHostsPath       string\n\tLogPath         string\n\tNode            *ContainerNode `json:\",omitempty\"` // Node is only propagated by Docker Swarm standalone API\n\tName            string\n\tRestartCount    int\n\tDriver          string\n\tPlatform        string\n\tMountLabel      string\n\tProcessLabel    string\n\tAppArmorProfile string\n\tExecIDs         []string\n\tHostConfig      *container.HostConfig\n\tGraphDriver     GraphDriverData\n\tSizeRw          *int64 `json:\",omitempty\"`\n\tSizeRootFs      *int64 `json:\",omitempty\"`\n}\n\n// ContainerJSON is newly used struct along with MountPoint\ntype ContainerJSON struct {\n\t*ContainerJSONBase\n\tMounts          []MountPoint\n\tConfig          *container.Config\n\tNetworkSettings *NetworkSettings\n}\n\n// NetworkSettings exposes the network settings in the api\ntype NetworkSettings struct {\n\tNetworkSettingsBase\n\tDefaultNetworkSettings\n\tNetworks map[string]*network.EndpointSettings\n}\n\n// SummaryNetworkSettings provides a summary of container's networks\n// in /containers/json\ntype SummaryNetworkSettings struct {\n\tNetworks map[string]*network.EndpointSettings\n}\n\n// NetworkSettingsBase holds networking state for a container when inspecting it.\ntype NetworkSettingsBase struct {\n\tBridge     string      // Bridge contains the name of the default bridge interface iff it was set through the daemon --bridge flag.\n\tSandboxID  string      // SandboxID uniquely represents a container's network stack\n\tSandboxKey string      // SandboxKey identifies the sandbox\n\tPorts      nat.PortMap // Ports is a collection of PortBinding indexed by Port\n\n\t// HairpinMode specifies if hairpin NAT should be enabled on the virtual interface\n\t//\n\t// Deprecated: This field is never set and will be removed in a future release.\n\tHairpinMode bool\n\t// LinkLocalIPv6Address is an IPv6 unicast address using the link-local prefix\n\t//\n\t// Deprecated: This field is never set and will be removed in a future release.\n\tLinkLocalIPv6Address string\n\t// LinkLocalIPv6PrefixLen is the prefix length of an IPv6 unicast address\n\t//\n\t// Deprecated: This field is never set and will be removed in a future release.\n\tLinkLocalIPv6PrefixLen int\n\tSecondaryIPAddresses   []network.Address // Deprecated: This field is never set and will be removed in a future release.\n\tSecondaryIPv6Addresses []network.Address // Deprecated: This field is never set and will be removed in a future release.\n}\n\n// DefaultNetworkSettings holds network information\n// during the 2 release deprecation period.\n// It will be removed in Docker 1.11.\ntype DefaultNetworkSettings struct {\n\tEndpointID          string // EndpointID uniquely represents a service endpoint in a Sandbox\n\tGateway             string // Gateway holds the gateway address for the network\n\tGlobalIPv6Address   string // GlobalIPv6Address holds network's global IPv6 address\n\tGlobalIPv6PrefixLen int    // GlobalIPv6PrefixLen represents mask length of network's global IPv6 address\n\tIPAddress           string // IPAddress holds the IPv4 address for the network\n\tIPPrefixLen         int    // IPPrefixLen represents mask length of network's IPv4 address\n\tIPv6Gateway         string // IPv6Gateway holds gateway address specific for IPv6\n\tMacAddress          string // MacAddress holds the MAC address for the network\n}\n\n// MountPoint represents a mount point configuration inside the container.\n// This is used for reporting the mountpoints in use by a container.\ntype MountPoint struct {\n\t// Type is the type of mount, see `Type<foo>` definitions in\n\t// github.com/docker/docker/api/types/mount.Type\n\tType mount.Type `json:\",omitempty\"`\n\n\t// Name is the name reference to the underlying data defined by `Source`\n\t// e.g., the volume name.\n\tName string `json:\",omitempty\"`\n\n\t// Source is the source location of the mount.\n\t//\n\t// For volumes, this contains the storage location of the volume (within\n\t// `/var/lib/docker/volumes/`). For bind-mounts, and `npipe`, this contains\n\t// the source (host) part of the bind-mount. For `tmpfs` mount points, this\n\t// field is empty.\n\tSource string\n\n\t// Destination is the path relative to the container root (`/`) where the\n\t// Source is mounted inside the container.\n\tDestination string\n\n\t// Driver is the volume driver used to create the volume (if it is a volume).\n\tDriver string `json:\",omitempty\"`\n\n\t// Mode is a comma separated list of options supplied by the user when\n\t// creating the bind/volume mount.\n\t//\n\t// The default is platform-specific (`\"z\"` on Linux, empty on Windows).\n\tMode string\n\n\t// RW indicates whether the mount is mounted writable (read-write).\n\tRW bool\n\n\t// Propagation describes how mounts are propagated from the host into the\n\t// mount point, and vice-versa. Refer to the Linux kernel documentation\n\t// for details:\n\t// https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt\n\t//\n\t// This field is not used on Windows.\n\tPropagation mount.Propagation\n}\n\n// NetworkResource is the body of the \"get network\" http response message\ntype NetworkResource struct {\n\tName       string                         // Name is the requested name of the network\n\tID         string                         `json:\"Id\"` // ID uniquely identifies a network on a single machine\n\tCreated    time.Time                      // Created is the time the network created\n\tScope      string                         // Scope describes the level at which the network exists (e.g. `swarm` for cluster-wide or `local` for machine level)\n\tDriver     string                         // Driver is the Driver name used to create the network (e.g. `bridge`, `overlay`)\n\tEnableIPv6 bool                           // EnableIPv6 represents whether to enable IPv6\n\tIPAM       network.IPAM                   // IPAM is the network's IP Address Management\n\tInternal   bool                           // Internal represents if the network is used internal only\n\tAttachable bool                           // Attachable represents if the global scope is manually attachable by regular containers from workers in swarm mode.\n\tIngress    bool                           // Ingress indicates the network is providing the routing-mesh for the swarm cluster.\n\tConfigFrom network.ConfigReference        // ConfigFrom specifies the source which will provide the configuration for this network.\n\tConfigOnly bool                           // ConfigOnly networks are place-holder networks for network configurations to be used by other networks. ConfigOnly networks cannot be used directly to run containers or services.\n\tContainers map[string]EndpointResource    // Containers contains endpoints belonging to the network\n\tOptions    map[string]string              // Options holds the network specific options to use for when creating the network\n\tLabels     map[string]string              // Labels holds metadata specific to the network being created\n\tPeers      []network.PeerInfo             `json:\",omitempty\"` // List of peer nodes for an overlay network\n\tServices   map[string]network.ServiceInfo `json:\",omitempty\"`\n}\n\n// EndpointResource contains network resources allocated and used for a container in a network\ntype EndpointResource struct {\n\tName        string\n\tEndpointID  string\n\tMacAddress  string\n\tIPv4Address string\n\tIPv6Address string\n}\n\n// NetworkCreate is the expected body of the \"create network\" http request message\ntype NetworkCreate struct {\n\t// Deprecated: CheckDuplicate is deprecated since API v1.44, but it defaults to true when sent by the client\n\t// package to older daemons.\n\tCheckDuplicate bool `json:\",omitempty\"`\n\tDriver         string\n\tScope          string\n\tEnableIPv6     bool\n\tIPAM           *network.IPAM\n\tInternal       bool\n\tAttachable     bool\n\tIngress        bool\n\tConfigOnly     bool\n\tConfigFrom     *network.ConfigReference\n\tOptions        map[string]string\n\tLabels         map[string]string\n}\n\n// NetworkCreateRequest is the request message sent to the server for network create call.\ntype NetworkCreateRequest struct {\n\tNetworkCreate\n\tName string\n}\n\n// NetworkCreateResponse is the response message sent by the server for network create call\ntype NetworkCreateResponse struct {\n\tID      string `json:\"Id\"`\n\tWarning string\n}\n\n// NetworkConnect represents the data to be used to connect a container to the network\ntype NetworkConnect struct {\n\tContainer      string\n\tEndpointConfig *network.EndpointSettings `json:\",omitempty\"`\n}\n\n// NetworkDisconnect represents the data to be used to disconnect a container from the network\ntype NetworkDisconnect struct {\n\tContainer string\n\tForce     bool\n}\n\n// NetworkInspectOptions holds parameters to inspect network\ntype NetworkInspectOptions struct {\n\tScope   string\n\tVerbose bool\n}\n\n// DiskUsageObject represents an object type used for disk usage query filtering.\ntype DiskUsageObject string\n\nconst (\n\t// ContainerObject represents a container DiskUsageObject.\n\tContainerObject DiskUsageObject = \"container\"\n\t// ImageObject represents an image DiskUsageObject.\n\tImageObject DiskUsageObject = \"image\"\n\t// VolumeObject represents a volume DiskUsageObject.\n\tVolumeObject DiskUsageObject = \"volume\"\n\t// BuildCacheObject represents a build-cache DiskUsageObject.\n\tBuildCacheObject DiskUsageObject = \"build-cache\"\n)\n\n// DiskUsageOptions holds parameters for system disk usage query.\ntype DiskUsageOptions struct {\n\t// Types specifies what object types to include in the response. If empty,\n\t// all object types are returned.\n\tTypes []DiskUsageObject\n}\n\n// DiskUsage contains response of Engine API:\n// GET \"/system/df\"\ntype DiskUsage struct {\n\tLayersSize  int64\n\tImages      []*image.Summary\n\tContainers  []*Container\n\tVolumes     []*volume.Volume\n\tBuildCache  []*BuildCache\n\tBuilderSize int64 `json:\",omitempty\"` // Deprecated: deprecated in API 1.38, and no longer used since API 1.40.\n}\n\n// ContainersPruneReport contains the response for Engine API:\n// POST \"/containers/prune\"\ntype ContainersPruneReport struct {\n\tContainersDeleted []string\n\tSpaceReclaimed    uint64\n}\n\n// VolumesPruneReport contains the response for Engine API:\n// POST \"/volumes/prune\"\ntype VolumesPruneReport struct {\n\tVolumesDeleted []string\n\tSpaceReclaimed uint64\n}\n\n// ImagesPruneReport contains the response for Engine API:\n// POST \"/images/prune\"\ntype ImagesPruneReport struct {\n\tImagesDeleted  []image.DeleteResponse\n\tSpaceReclaimed uint64\n}\n\n// BuildCachePruneReport contains the response for Engine API:\n// POST \"/build/prune\"\ntype BuildCachePruneReport struct {\n\tCachesDeleted  []string\n\tSpaceReclaimed uint64\n}\n\n// NetworksPruneReport contains the response for Engine API:\n// POST \"/networks/prune\"\ntype NetworksPruneReport struct {\n\tNetworksDeleted []string\n}\n\n// SecretCreateResponse contains the information returned to a client\n// on the creation of a new secret.\ntype SecretCreateResponse struct {\n\t// ID is the id of the created secret.\n\tID string\n}\n\n// SecretListOptions holds parameters to list secrets\ntype SecretListOptions struct {\n\tFilters filters.Args\n}\n\n// ConfigCreateResponse contains the information returned to a client\n// on the creation of a new config.\ntype ConfigCreateResponse struct {\n\t// ID is the id of the created config.\n\tID string\n}\n\n// ConfigListOptions holds parameters to list configs\ntype ConfigListOptions struct {\n\tFilters filters.Args\n}\n\n// PushResult contains the tag, manifest digest, and manifest size from the\n// push. It's used to signal this information to the trust code in the client\n// so it can sign the manifest if necessary.\ntype PushResult struct {\n\tTag    string\n\tDigest string\n\tSize   int\n}\n\n// BuildResult contains the image id of a successful build\ntype BuildResult struct {\n\tID string\n}\n\n// BuildCache contains information about a build cache record.\ntype BuildCache struct {\n\t// ID is the unique ID of the build cache record.\n\tID string\n\t// Parent is the ID of the parent build cache record.\n\t//\n\t// Deprecated: deprecated in API v1.42 and up, as it was deprecated in BuildKit; use Parents instead.\n\tParent string `json:\"Parent,omitempty\"`\n\t// Parents is the list of parent build cache record IDs.\n\tParents []string `json:\" Parents,omitempty\"`\n\t// Type is the cache record type.\n\tType string\n\t// Description is a description of the build-step that produced the build cache.\n\tDescription string\n\t// InUse indicates if the build cache is in use.\n\tInUse bool\n\t// Shared indicates if the build cache is shared.\n\tShared bool\n\t// Size is the amount of disk space used by the build cache (in bytes).\n\tSize int64\n\t// CreatedAt is the date and time at which the build cache was created.\n\tCreatedAt time.Time\n\t// LastUsedAt is the date and time at which the build cache was last used.\n\tLastUsedAt *time.Time\n\tUsageCount int\n}\n\n// BuildCachePruneOptions hold parameters to prune the build cache\ntype BuildCachePruneOptions struct {\n\tAll         bool\n\tKeepStorage int64\n\tFilters     filters.Args\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/types_deprecated.go",
    "content": "package types\n\nimport (\n\t\"github.com/docker/docker/api/types/checkpoint\"\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/api/types/swarm\"\n\t\"github.com/docker/docker/api/types/system\"\n)\n\n// CheckpointCreateOptions holds parameters to create a checkpoint from a container.\n//\n// Deprecated: use [checkpoint.CreateOptions].\ntype CheckpointCreateOptions = checkpoint.CreateOptions\n\n// CheckpointListOptions holds parameters to list checkpoints for a container\n//\n// Deprecated: use [checkpoint.ListOptions].\ntype CheckpointListOptions = checkpoint.ListOptions\n\n// CheckpointDeleteOptions holds parameters to delete a checkpoint from a container\n//\n// Deprecated: use [checkpoint.DeleteOptions].\ntype CheckpointDeleteOptions = checkpoint.DeleteOptions\n\n// Checkpoint represents the details of a checkpoint when listing endpoints.\n//\n// Deprecated: use [checkpoint.Summary].\ntype Checkpoint = checkpoint.Summary\n\n// Info contains response of Engine API:\n// GET \"/info\"\n//\n// Deprecated: use [system.Info].\ntype Info = system.Info\n\n// Commit holds the Git-commit (SHA1) that a binary was built from, as reported\n// in the version-string of external tools, such as containerd, or runC.\n//\n// Deprecated: use [system.Commit].\ntype Commit = system.Commit\n\n// PluginsInfo is a temp struct holding Plugins name\n// registered with docker daemon. It is used by [system.Info] struct\n//\n// Deprecated: use [system.PluginsInfo].\ntype PluginsInfo = system.PluginsInfo\n\n// NetworkAddressPool is a temp struct used by [system.Info] struct.\n//\n// Deprecated: use [system.NetworkAddressPool].\ntype NetworkAddressPool = system.NetworkAddressPool\n\n// Runtime describes an OCI runtime.\n//\n// Deprecated: use [system.Runtime].\ntype Runtime = system.Runtime\n\n// SecurityOpt contains the name and options of a security option.\n//\n// Deprecated: use [system.SecurityOpt].\ntype SecurityOpt = system.SecurityOpt\n\n// KeyValue holds a key/value pair.\n//\n// Deprecated: use [system.KeyValue].\ntype KeyValue = system.KeyValue\n\n// ImageDeleteResponseItem image delete response item.\n//\n// Deprecated: use [image.DeleteResponse].\ntype ImageDeleteResponseItem = image.DeleteResponse\n\n// ImageSummary image summary.\n//\n// Deprecated: use [image.Summary].\ntype ImageSummary = image.Summary\n\n// ImageMetadata contains engine-local data about the image.\n//\n// Deprecated: use [image.Metadata].\ntype ImageMetadata = image.Metadata\n\n// ServiceCreateResponse contains the information returned to a client\n// on the creation of a new service.\n//\n// Deprecated: use [swarm.ServiceCreateResponse].\ntype ServiceCreateResponse = swarm.ServiceCreateResponse\n\n// ServiceUpdateResponse service update response.\n//\n// Deprecated: use [swarm.ServiceUpdateResponse].\ntype ServiceUpdateResponse = swarm.ServiceUpdateResponse\n\n// ContainerStartOptions holds parameters to start containers.\n//\n// Deprecated: use [container.StartOptions].\ntype ContainerStartOptions = container.StartOptions\n\n// ResizeOptions holds parameters to resize a TTY.\n// It can be used to resize container TTYs and\n// exec process TTYs too.\n//\n// Deprecated: use [container.ResizeOptions].\ntype ResizeOptions = container.ResizeOptions\n\n// ContainerAttachOptions holds parameters to attach to a container.\n//\n// Deprecated: use [container.AttachOptions].\ntype ContainerAttachOptions = container.AttachOptions\n\n// ContainerCommitOptions holds parameters to commit changes into a container.\n//\n// Deprecated: use [container.CommitOptions].\ntype ContainerCommitOptions = container.CommitOptions\n\n// ContainerListOptions holds parameters to list containers with.\n//\n// Deprecated: use [container.ListOptions].\ntype ContainerListOptions = container.ListOptions\n\n// ContainerLogsOptions holds parameters to filter logs with.\n//\n// Deprecated: use [container.LogsOptions].\ntype ContainerLogsOptions = container.LogsOptions\n\n// ContainerRemoveOptions holds parameters to remove containers.\n//\n// Deprecated: use [container.RemoveOptions].\ntype ContainerRemoveOptions = container.RemoveOptions\n\n// DecodeSecurityOptions decodes a security options string slice to a type safe\n// [system.SecurityOpt].\n//\n// Deprecated: use [system.DecodeSecurityOptions].\nfunc DecodeSecurityOptions(opts []string) ([]system.SecurityOpt, error) {\n\treturn system.DecodeSecurityOptions(opts)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/versions/README.md",
    "content": "# Legacy API type versions\n\nThis package includes types for legacy API versions. The stable version of the API types live in `api/types/*.go`.\n\nConsider moving a type here when you need to keep backwards compatibility in the API. This legacy types are organized by the latest API version they appear in. For instance, types in the `v1p19` package are valid for API versions below or equal `1.19`. Types in the `v1p20` package are valid for the API version `1.20`, since the versions below that will use the legacy types in `v1p19`.\n\n## Package name conventions\n\nThe package name convention is to use `v` as a prefix for the version number and `p`(patch) as a separator. We use this nomenclature due to a few restrictions in the Go package name convention:\n\n1. We cannot use `.` because it's interpreted by the language, think of `v1.20.CallFunction`.\n2. We cannot use `_` because golint complains about it. The code is actually valid, but it looks probably more weird: `v1_20.CallFunction`.\n\nFor instance, if you want to modify a type that was available in the version `1.21` of the API but it will have different fields in the version `1.22`, you want to create a new package under `api/types/versions/v1p21`.\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/versions/compare.go",
    "content": "package versions // import \"github.com/docker/docker/api/types/versions\"\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n)\n\n// compare compares two version strings\n// returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise.\nfunc compare(v1, v2 string) int {\n\tif v1 == v2 {\n\t\treturn 0\n\t}\n\tvar (\n\t\tcurrTab  = strings.Split(v1, \".\")\n\t\totherTab = strings.Split(v2, \".\")\n\t)\n\n\tmaxVer := len(currTab)\n\tif len(otherTab) > maxVer {\n\t\tmaxVer = len(otherTab)\n\t}\n\tfor i := 0; i < maxVer; i++ {\n\t\tvar currInt, otherInt int\n\n\t\tif len(currTab) > i {\n\t\t\tcurrInt, _ = strconv.Atoi(currTab[i])\n\t\t}\n\t\tif len(otherTab) > i {\n\t\t\totherInt, _ = strconv.Atoi(otherTab[i])\n\t\t}\n\t\tif currInt > otherInt {\n\t\t\treturn 1\n\t\t}\n\t\tif otherInt > currInt {\n\t\t\treturn -1\n\t\t}\n\t}\n\treturn 0\n}\n\n// LessThan checks if a version is less than another\nfunc LessThan(v, other string) bool {\n\treturn compare(v, other) == -1\n}\n\n// LessThanOrEqualTo checks if a version is less than or equal to another\nfunc LessThanOrEqualTo(v, other string) bool {\n\treturn compare(v, other) <= 0\n}\n\n// GreaterThan checks if a version is greater than another\nfunc GreaterThan(v, other string) bool {\n\treturn compare(v, other) == 1\n}\n\n// GreaterThanOrEqualTo checks if a version is greater than or equal to another\nfunc GreaterThanOrEqualTo(v, other string) bool {\n\treturn compare(v, other) >= 0\n}\n\n// Equal checks if a version is equal to another\nfunc Equal(v, other string) bool {\n\treturn compare(v, other) == 0\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/volume/cluster_volume.go",
    "content": "package volume\n\nimport (\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// ClusterVolume contains options and information specific to, and only present\n// on, Swarm CSI cluster volumes.\ntype ClusterVolume struct {\n\t// ID is the Swarm ID of the volume. Because cluster volumes are Swarm\n\t// objects, they have an ID, unlike non-cluster volumes, which only have a\n\t// Name. This ID can be used to refer to the cluster volume.\n\tID string\n\n\t// Meta is the swarm metadata about this volume.\n\tswarm.Meta\n\n\t// Spec is the cluster-specific options from which this volume is derived.\n\tSpec ClusterVolumeSpec\n\n\t// PublishStatus contains the status of the volume as it pertains to its\n\t// publishing on Nodes.\n\tPublishStatus []*PublishStatus `json:\",omitempty\"`\n\n\t// Info is information about the global status of the volume.\n\tInfo *Info `json:\",omitempty\"`\n}\n\n// ClusterVolumeSpec contains the spec used to create this volume.\ntype ClusterVolumeSpec struct {\n\t// Group defines the volume group of this volume. Volumes belonging to the\n\t// same group can be referred to by group name when creating Services.\n\t// Referring to a volume by group instructs swarm to treat volumes in that\n\t// group interchangeably for the purpose of scheduling. Volumes with an\n\t// empty string for a group technically all belong to the same, emptystring\n\t// group.\n\tGroup string `json:\",omitempty\"`\n\n\t// AccessMode defines how the volume is used by tasks.\n\tAccessMode *AccessMode `json:\",omitempty\"`\n\n\t// AccessibilityRequirements specifies where in the cluster a volume must\n\t// be accessible from.\n\t//\n\t// This field must be empty if the plugin does not support\n\t// VOLUME_ACCESSIBILITY_CONSTRAINTS capabilities. If it is present but the\n\t// plugin does not support it, volume will not be created.\n\t//\n\t// If AccessibilityRequirements is empty, but the plugin does support\n\t// VOLUME_ACCESSIBILITY_CONSTRAINTS, then Swarmkit will assume the entire\n\t// cluster is a valid target for the volume.\n\tAccessibilityRequirements *TopologyRequirement `json:\",omitempty\"`\n\n\t// CapacityRange defines the desired capacity that the volume should be\n\t// created with. If nil, the plugin will decide the capacity.\n\tCapacityRange *CapacityRange `json:\",omitempty\"`\n\n\t// Secrets defines Swarm Secrets that are passed to the CSI storage plugin\n\t// when operating on this volume.\n\tSecrets []Secret `json:\",omitempty\"`\n\n\t// Availability is the Volume's desired availability. Analogous to Node\n\t// Availability, this allows the user to take volumes offline in order to\n\t// update or delete them.\n\tAvailability Availability `json:\",omitempty\"`\n}\n\n// Availability specifies the availability of the volume.\ntype Availability string\n\nconst (\n\t// AvailabilityActive indicates that the volume is active and fully\n\t// schedulable on the cluster.\n\tAvailabilityActive Availability = \"active\"\n\n\t// AvailabilityPause indicates that no new workloads should use the\n\t// volume, but existing workloads can continue to use it.\n\tAvailabilityPause Availability = \"pause\"\n\n\t// AvailabilityDrain indicates that all workloads using this volume\n\t// should be rescheduled, and the volume unpublished from all nodes.\n\tAvailabilityDrain Availability = \"drain\"\n)\n\n// AccessMode defines the access mode of a volume.\ntype AccessMode struct {\n\t// Scope defines the set of nodes this volume can be used on at one time.\n\tScope Scope `json:\",omitempty\"`\n\n\t// Sharing defines the number and way that different tasks can use this\n\t// volume at one time.\n\tSharing SharingMode `json:\",omitempty\"`\n\n\t// MountVolume defines options for using this volume as a Mount-type\n\t// volume.\n\t//\n\t// Either BlockVolume or MountVolume, but not both, must be present.\n\tMountVolume *TypeMount `json:\",omitempty\"`\n\n\t// BlockVolume defines options for using this volume as a Block-type\n\t// volume.\n\t//\n\t// Either BlockVolume or MountVolume, but not both, must be present.\n\tBlockVolume *TypeBlock `json:\",omitempty\"`\n}\n\n// Scope defines the Scope of a Cluster Volume. This is how many nodes a\n// Volume can be accessed simultaneously on.\ntype Scope string\n\nconst (\n\t// ScopeSingleNode indicates the volume can be used on one node at a\n\t// time.\n\tScopeSingleNode Scope = \"single\"\n\n\t// ScopeMultiNode indicates the volume can be used on many nodes at\n\t// the same time.\n\tScopeMultiNode Scope = \"multi\"\n)\n\n// SharingMode defines the Sharing of a Cluster Volume. This is how Tasks using a\n// Volume at the same time can use it.\ntype SharingMode string\n\nconst (\n\t// SharingNone indicates that only one Task may use the Volume at a\n\t// time.\n\tSharingNone SharingMode = \"none\"\n\n\t// SharingReadOnly indicates that the Volume may be shared by any\n\t// number of Tasks, but they must be read-only.\n\tSharingReadOnly SharingMode = \"readonly\"\n\n\t// SharingOneWriter indicates that the Volume may be shared by any\n\t// number of Tasks, but all after the first must be read-only.\n\tSharingOneWriter SharingMode = \"onewriter\"\n\n\t// SharingAll means that the Volume may be shared by any number of\n\t// Tasks, as readers or writers.\n\tSharingAll SharingMode = \"all\"\n)\n\n// TypeBlock defines options for using a volume as a block-type volume.\n//\n// Intentionally empty.\ntype TypeBlock struct{}\n\n// TypeMount contains options for using a volume as a Mount-type\n// volume.\ntype TypeMount struct {\n\t// FsType specifies the filesystem type for the mount volume. Optional.\n\tFsType string `json:\",omitempty\"`\n\n\t// MountFlags defines flags to pass when mounting the volume. Optional.\n\tMountFlags []string `json:\",omitempty\"`\n}\n\n// TopologyRequirement expresses the user's requirements for a volume's\n// accessible topology.\ntype TopologyRequirement struct {\n\t// Requisite specifies a list of Topologies, at least one of which the\n\t// volume must be accessible from.\n\t//\n\t// Taken verbatim from the CSI Spec:\n\t//\n\t// Specifies the list of topologies the provisioned volume MUST be\n\t// accessible from.\n\t// This field is OPTIONAL. If TopologyRequirement is specified either\n\t// requisite or preferred or both MUST be specified.\n\t//\n\t// If requisite is specified, the provisioned volume MUST be\n\t// accessible from at least one of the requisite topologies.\n\t//\n\t// Given\n\t//   x = number of topologies provisioned volume is accessible from\n\t//   n = number of requisite topologies\n\t// The CO MUST ensure n >= 1. The SP MUST ensure x >= 1\n\t// If x==n, then the SP MUST make the provisioned volume available to\n\t// all topologies from the list of requisite topologies. If it is\n\t// unable to do so, the SP MUST fail the CreateVolume call.\n\t// For example, if a volume should be accessible from a single zone,\n\t// and requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"}\n\t// then the provisioned volume MUST be accessible from the \"region\"\n\t// \"R1\" and the \"zone\" \"Z2\".\n\t// Similarly, if a volume should be accessible from two zones, and\n\t// requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"}\n\t// then the provisioned volume MUST be accessible from the \"region\"\n\t// \"R1\" and both \"zone\" \"Z2\" and \"zone\" \"Z3\".\n\t//\n\t// If x<n, then the SP SHALL choose x unique topologies from the list\n\t// of requisite topologies. If it is unable to do so, the SP MUST fail\n\t// the CreateVolume call.\n\t// For example, if a volume should be accessible from a single zone,\n\t// and requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"}\n\t// then the SP may choose to make the provisioned volume available in\n\t// either the \"zone\" \"Z2\" or the \"zone\" \"Z3\" in the \"region\" \"R1\".\n\t// Similarly, if a volume should be accessible from two zones, and\n\t// requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z4\"}\n\t// then the provisioned volume MUST be accessible from any combination\n\t// of two unique topologies: e.g. \"R1/Z2\" and \"R1/Z3\", or \"R1/Z2\" and\n\t//  \"R1/Z4\", or \"R1/Z3\" and \"R1/Z4\".\n\t//\n\t// If x>n, then the SP MUST make the provisioned volume available from\n\t// all topologies from the list of requisite topologies and MAY choose\n\t// the remaining x-n unique topologies from the list of all possible\n\t// topologies. If it is unable to do so, the SP MUST fail the\n\t// CreateVolume call.\n\t// For example, if a volume should be accessible from two zones, and\n\t// requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"}\n\t// then the provisioned volume MUST be accessible from the \"region\"\n\t// \"R1\" and the \"zone\" \"Z2\" and the SP may select the second zone\n\t// independently, e.g. \"R1/Z4\".\n\tRequisite []Topology `json:\",omitempty\"`\n\n\t// Preferred is a list of Topologies that the volume should attempt to be\n\t// provisioned in.\n\t//\n\t// Taken from the CSI spec:\n\t//\n\t// Specifies the list of topologies the CO would prefer the volume to\n\t// be provisioned in.\n\t//\n\t// This field is OPTIONAL. If TopologyRequirement is specified either\n\t// requisite or preferred or both MUST be specified.\n\t//\n\t// An SP MUST attempt to make the provisioned volume available using\n\t// the preferred topologies in order from first to last.\n\t//\n\t// If requisite is specified, all topologies in preferred list MUST\n\t// also be present in the list of requisite topologies.\n\t//\n\t// If the SP is unable to to make the provisioned volume available\n\t// from any of the preferred topologies, the SP MAY choose a topology\n\t// from the list of requisite topologies.\n\t// If the list of requisite topologies is not specified, then the SP\n\t// MAY choose from the list of all possible topologies.\n\t// If the list of requisite topologies is specified and the SP is\n\t// unable to to make the provisioned volume available from any of the\n\t// requisite topologies it MUST fail the CreateVolume call.\n\t//\n\t// Example 1:\n\t// Given a volume should be accessible from a single zone, and\n\t// requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"}\n\t// preferred =\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"}\n\t// then the the SP SHOULD first attempt to make the provisioned volume\n\t// available from \"zone\" \"Z3\" in the \"region\" \"R1\" and fall back to\n\t// \"zone\" \"Z2\" in the \"region\" \"R1\" if that is not possible.\n\t//\n\t// Example 2:\n\t// Given a volume should be accessible from a single zone, and\n\t// requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z4\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z5\"}\n\t// preferred =\n\t//   {\"region\": \"R1\", \"zone\": \"Z4\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"}\n\t// then the the SP SHOULD first attempt to make the provisioned volume\n\t// accessible from \"zone\" \"Z4\" in the \"region\" \"R1\" and fall back to\n\t// \"zone\" \"Z2\" in the \"region\" \"R1\" if that is not possible. If that\n\t// is not possible, the SP may choose between either the \"zone\"\n\t// \"Z3\" or \"Z5\" in the \"region\" \"R1\".\n\t//\n\t// Example 3:\n\t// Given a volume should be accessible from TWO zones (because an\n\t// opaque parameter in CreateVolumeRequest, for example, specifies\n\t// the volume is accessible from two zones, aka synchronously\n\t// replicated), and\n\t// requisite =\n\t//   {\"region\": \"R1\", \"zone\": \"Z2\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z4\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z5\"}\n\t// preferred =\n\t//   {\"region\": \"R1\", \"zone\": \"Z5\"},\n\t//   {\"region\": \"R1\", \"zone\": \"Z3\"}\n\t// then the the SP SHOULD first attempt to make the provisioned volume\n\t// accessible from the combination of the two \"zones\" \"Z5\" and \"Z3\" in\n\t// the \"region\" \"R1\". If that's not possible, it should fall back to\n\t// a combination of \"Z5\" and other possibilities from the list of\n\t// requisite. If that's not possible, it should fall back  to a\n\t// combination of \"Z3\" and other possibilities from the list of\n\t// requisite. If that's not possible, it should fall back  to a\n\t// combination of other possibilities from the list of requisite.\n\tPreferred []Topology `json:\",omitempty\"`\n}\n\n// Topology is a map of topological domains to topological segments.\n//\n// This description is taken verbatim from the CSI Spec:\n//\n// A topological domain is a sub-division of a cluster, like \"region\",\n// \"zone\", \"rack\", etc.\n// A topological segment is a specific instance of a topological domain,\n// like \"zone3\", \"rack3\", etc.\n// For example {\"com.company/zone\": \"Z1\", \"com.company/rack\": \"R3\"}\n// Valid keys have two segments: an OPTIONAL prefix and name, separated\n// by a slash (/), for example: \"com.company.example/zone\".\n// The key name segment is REQUIRED. The prefix is OPTIONAL.\n// The key name MUST be 63 characters or less, begin and end with an\n// alphanumeric character ([a-z0-9A-Z]), and contain only dashes (-),\n// underscores (_), dots (.), or alphanumerics in between, for example\n// \"zone\".\n// The key prefix MUST be 63 characters or less, begin and end with a\n// lower-case alphanumeric character ([a-z0-9]), contain only\n// dashes (-), dots (.), or lower-case alphanumerics in between, and\n// follow domain name notation format\n// (https://tools.ietf.org/html/rfc1035#section-2.3.1).\n// The key prefix SHOULD include the plugin's host company name and/or\n// the plugin name, to minimize the possibility of collisions with keys\n// from other plugins.\n// If a key prefix is specified, it MUST be identical across all\n// topology keys returned by the SP (across all RPCs).\n// Keys MUST be case-insensitive. Meaning the keys \"Zone\" and \"zone\"\n// MUST not both exist.\n// Each value (topological segment) MUST contain 1 or more strings.\n// Each string MUST be 63 characters or less and begin and end with an\n// alphanumeric character with '-', '_', '.', or alphanumerics in\n// between.\ntype Topology struct {\n\tSegments map[string]string `json:\",omitempty\"`\n}\n\n// CapacityRange describes the minimum and maximum capacity a volume should be\n// created with\ntype CapacityRange struct {\n\t// RequiredBytes specifies that a volume must be at least this big. The\n\t// value of 0 indicates an unspecified minimum.\n\tRequiredBytes int64\n\n\t// LimitBytes specifies that a volume must not be bigger than this. The\n\t// value of 0 indicates an unspecified maximum\n\tLimitBytes int64\n}\n\n// Secret represents a Swarm Secret value that must be passed to the CSI\n// storage plugin when operating on this Volume. It represents one key-value\n// pair of possibly many.\ntype Secret struct {\n\t// Key is the name of the key of the key-value pair passed to the plugin.\n\tKey string\n\n\t// Secret is the swarm Secret object from which to read data. This can be a\n\t// Secret name or ID. The Secret data is retrieved by Swarm and used as the\n\t// value of the key-value pair passed to the plugin.\n\tSecret string\n}\n\n// PublishState represents the state of a Volume as it pertains to its\n// use on a particular Node.\ntype PublishState string\n\nconst (\n\t// StatePending indicates that the volume should be published on\n\t// this node, but the call to ControllerPublishVolume has not been\n\t// successfully completed yet and the result recorded by swarmkit.\n\tStatePending PublishState = \"pending-publish\"\n\n\t// StatePublished means the volume is published successfully to the node.\n\tStatePublished PublishState = \"published\"\n\n\t// StatePendingNodeUnpublish indicates that the Volume should be\n\t// unpublished on the Node, and we're waiting for confirmation that it has\n\t// done so.  After the Node has confirmed that the Volume has been\n\t// unpublished, the state will move to StatePendingUnpublish.\n\tStatePendingNodeUnpublish PublishState = \"pending-node-unpublish\"\n\n\t// StatePendingUnpublish means the volume is still published to the node\n\t// by the controller, awaiting the operation to unpublish it.\n\tStatePendingUnpublish PublishState = \"pending-controller-unpublish\"\n)\n\n// PublishStatus represents the status of the volume as published to an\n// individual node\ntype PublishStatus struct {\n\t// NodeID is the ID of the swarm node this Volume is published to.\n\tNodeID string `json:\",omitempty\"`\n\n\t// State is the publish state of the volume.\n\tState PublishState `json:\",omitempty\"`\n\n\t// PublishContext is the PublishContext returned by the CSI plugin when\n\t// a volume is published.\n\tPublishContext map[string]string `json:\",omitempty\"`\n}\n\n// Info contains information about the Volume as a whole as provided by\n// the CSI storage plugin.\ntype Info struct {\n\t// CapacityBytes is the capacity of the volume in bytes. A value of 0\n\t// indicates that the capacity is unknown.\n\tCapacityBytes int64 `json:\",omitempty\"`\n\n\t// VolumeContext is the context originating from the CSI storage plugin\n\t// when the Volume is created.\n\tVolumeContext map[string]string `json:\",omitempty\"`\n\n\t// VolumeID is the ID of the Volume as seen by the CSI storage plugin. This\n\t// is distinct from the Volume's Swarm ID, which is the ID used by all of\n\t// the Docker Engine to refer to the Volume. If this field is blank, then\n\t// the Volume has not been successfully created yet.\n\tVolumeID string `json:\",omitempty\"`\n\n\t// AccessibleTopolgoy is the topology this volume is actually accessible\n\t// from.\n\tAccessibleTopology []Topology `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/volume/create_options.go",
    "content": "package volume\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// CreateOptions VolumeConfig\n//\n// Volume configuration\n// swagger:model CreateOptions\ntype CreateOptions struct {\n\n\t// cluster volume spec\n\tClusterVolumeSpec *ClusterVolumeSpec `json:\"ClusterVolumeSpec,omitempty\"`\n\n\t// Name of the volume driver to use.\n\tDriver string `json:\"Driver,omitempty\"`\n\n\t// A mapping of driver options and values. These options are\n\t// passed directly to the driver and are driver specific.\n\t//\n\tDriverOpts map[string]string `json:\"DriverOpts,omitempty\"`\n\n\t// User-defined key/value metadata.\n\tLabels map[string]string `json:\"Labels,omitempty\"`\n\n\t// The new volume's name. If not specified, Docker generates a name.\n\t//\n\tName string `json:\"Name,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/volume/list_response.go",
    "content": "package volume\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// ListResponse VolumeListResponse\n//\n// Volume list response\n// swagger:model ListResponse\ntype ListResponse struct {\n\n\t// List of volumes\n\tVolumes []*Volume `json:\"Volumes\"`\n\n\t// Warnings that occurred when fetching the list of volumes.\n\t//\n\tWarnings []string `json:\"Warnings\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/volume/options.go",
    "content": "package volume // import \"github.com/docker/docker/api/types/volume\"\n\nimport \"github.com/docker/docker/api/types/filters\"\n\n// ListOptions holds parameters to list volumes.\ntype ListOptions struct {\n\tFilters filters.Args\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/volume/volume.go",
    "content": "package volume\n\n// This file was generated by the swagger tool.\n// Editing this file might prove futile when you re-run the swagger generate command\n\n// Volume volume\n// swagger:model Volume\ntype Volume struct {\n\n\t// cluster volume\n\tClusterVolume *ClusterVolume `json:\"ClusterVolume,omitempty\"`\n\n\t// Date/Time the volume was created.\n\tCreatedAt string `json:\"CreatedAt,omitempty\"`\n\n\t// Name of the volume driver used by the volume.\n\t// Required: true\n\tDriver string `json:\"Driver\"`\n\n\t// User-defined key/value metadata.\n\t// Required: true\n\tLabels map[string]string `json:\"Labels\"`\n\n\t// Mount path of the volume on the host.\n\t// Required: true\n\tMountpoint string `json:\"Mountpoint\"`\n\n\t// Name of the volume.\n\t// Required: true\n\tName string `json:\"Name\"`\n\n\t// The driver specific options used when creating the volume.\n\t//\n\t// Required: true\n\tOptions map[string]string `json:\"Options\"`\n\n\t// The level at which the volume exists. Either `global` for cluster-wide,\n\t// or `local` for machine level.\n\t//\n\t// Required: true\n\tScope string `json:\"Scope\"`\n\n\t// Low-level details about the volume, provided by the volume driver.\n\t// Details are returned as a map with key/value pairs:\n\t// `{\"key\":\"value\",\"key2\":\"value2\"}`.\n\t//\n\t// The `Status` field is optional, and is omitted if the volume driver\n\t// does not support this feature.\n\t//\n\tStatus map[string]interface{} `json:\"Status,omitempty\"`\n\n\t// usage data\n\tUsageData *UsageData `json:\"UsageData,omitempty\"`\n}\n\n// UsageData Usage details about the volume. This information is used by the\n// `GET /system/df` endpoint, and omitted in other endpoints.\n//\n// swagger:model UsageData\ntype UsageData struct {\n\n\t// The number of containers referencing this volume. This field\n\t// is set to `-1` if the reference-count is not available.\n\t//\n\t// Required: true\n\tRefCount int64 `json:\"RefCount\"`\n\n\t// Amount of disk space used by the volume (in bytes). This information\n\t// is only available for volumes created with the `\"local\"` volume\n\t// driver. For volumes created with other volume drivers, this field\n\t// is set to `-1` (\"not available\")\n\t//\n\t// Required: true\n\tSize int64 `json:\"Size\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/api/types/volume/volume_update.go",
    "content": "package volume // import \"github.com/docker/docker/api/types/volume\"\n\n// UpdateOptions is configuration to update a Volume with.\ntype UpdateOptions struct {\n\t// Spec is the ClusterVolumeSpec to update the volume to.\n\tSpec *ClusterVolumeSpec `json:\"Spec,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/README.md",
    "content": "# Go client for the Docker Engine API\n\nThe `docker` command uses this package to communicate with the daemon. It can\nalso be used by your own Go applications to do anything the command-line\ninterface does – running containers, pulling images, managing swarms, etc.\n\nFor example, to list all containers (the equivalent of `docker ps --all`):\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/client\"\n)\n\nfunc main() {\n\tapiClient, err := client.NewClientWithOpts(client.FromEnv)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer apiClient.Close()\n\n\tcontainers, err := apiClient.ContainerList(context.Background(), container.ListOptions{All: true})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfor _, ctr := range containers {\n\t\tfmt.Printf(\"%s %s (status: %s)\\n\", ctr.ID, ctr.Image, ctr.Status)\n\t}\n}\n```\n\n[Full documentation is available on pkg.go.dev.](https://pkg.go.dev/github.com/docker/docker/client)\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/build_cancel.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n)\n\n// BuildCancel requests the daemon to cancel the ongoing build request.\nfunc (cli *Client) BuildCancel(ctx context.Context, id string) error {\n\tquery := url.Values{}\n\tquery.Set(\"id\", id)\n\n\tserverResp, err := cli.post(ctx, \"/build/cancel\", query, nil, nil)\n\tensureReaderClosed(serverResp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/build_prune.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/pkg/errors\"\n)\n\n// BuildCachePrune requests the daemon to delete unused cache data\nfunc (cli *Client) BuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error) {\n\tif err := cli.NewVersionError(ctx, \"1.31\", \"build prune\"); err != nil {\n\t\treturn nil, err\n\t}\n\n\treport := types.BuildCachePruneReport{}\n\n\tquery := url.Values{}\n\tif opts.All {\n\t\tquery.Set(\"all\", \"1\")\n\t}\n\tquery.Set(\"keep-storage\", strconv.Itoa(int(opts.KeepStorage)))\n\tf, err := filters.ToJSON(opts.Filters)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"prune could not marshal filters option\")\n\t}\n\tquery.Set(\"filters\", f)\n\n\tserverResp, err := cli.post(ctx, \"/build/prune\", query, nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {\n\t\treturn nil, errors.Wrap(err, \"error retrieving disk usage\")\n\t}\n\n\treturn &report, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/checkpoint_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types/checkpoint\"\n)\n\n// CheckpointCreate creates a checkpoint from the given container with the given name\nfunc (cli *Client) CheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error {\n\tresp, err := cli.post(ctx, \"/containers/\"+container+\"/checkpoints\", nil, options, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/checkpoint_delete.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/checkpoint\"\n)\n\n// CheckpointDelete deletes the checkpoint with the given name from the given container\nfunc (cli *Client) CheckpointDelete(ctx context.Context, containerID string, options checkpoint.DeleteOptions) error {\n\tquery := url.Values{}\n\tif options.CheckpointDir != \"\" {\n\t\tquery.Set(\"dir\", options.CheckpointDir)\n\t}\n\n\tresp, err := cli.delete(ctx, \"/containers/\"+containerID+\"/checkpoints/\"+options.CheckpointID, query, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/checkpoint_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/checkpoint\"\n)\n\n// CheckpointList returns the checkpoints of the given container in the docker host\nfunc (cli *Client) CheckpointList(ctx context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {\n\tvar checkpoints []checkpoint.Summary\n\n\tquery := url.Values{}\n\tif options.CheckpointDir != \"\" {\n\t\tquery.Set(\"dir\", options.CheckpointDir)\n\t}\n\n\tresp, err := cli.get(ctx, \"/containers/\"+container+\"/checkpoints\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn checkpoints, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&checkpoints)\n\treturn checkpoints, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/client.go",
    "content": "/*\nPackage client is a Go client for the Docker Engine API.\n\nFor more information about the Engine API, see the documentation:\nhttps://docs.docker.com/engine/api/\n\n# Usage\n\nYou use the library by constructing a client object using [NewClientWithOpts]\nand calling methods on it. The client can be configured from environment\nvariables by passing the [FromEnv] option, or configured manually by passing any\nof the other available [Opts].\n\nFor example, to list running containers (the equivalent of \"docker ps\"):\n\n\tpackage main\n\n\timport (\n\t\t\"context\"\n\t\t\"fmt\"\n\n\t\t\"github.com/docker/docker/api/types/container\"\n\t\t\"github.com/docker/docker/client\"\n\t)\n\n\tfunc main() {\n\t\tcli, err := client.NewClientWithOpts(client.FromEnv)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tcontainers, err := cli.ContainerList(context.Background(), container.ListOptions{})\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tfor _, ctr := range containers {\n\t\t\tfmt.Printf(\"%s %s\\n\", ctr.ID, ctr.Image)\n\t\t}\n\t}\n*/\npackage client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/versions\"\n\t\"github.com/docker/go-connections/sockets\"\n\t\"github.com/pkg/errors\"\n\t\"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// DummyHost is a hostname used for local communication.\n//\n// It acts as a valid formatted hostname for local connections (such as \"unix://\"\n// or \"npipe://\") which do not require a hostname. It should never be resolved,\n// but uses the special-purpose \".localhost\" TLD (as defined in [RFC 2606, Section 2]\n// and [RFC 6761, Section 6.3]).\n//\n// [RFC 7230, Section 5.4] defines that an empty header must be used for such\n// cases:\n//\n//\tIf the authority component is missing or undefined for the target URI,\n//\tthen a client MUST send a Host header field with an empty field-value.\n//\n// However, [Go stdlib] enforces the semantics of HTTP(S) over TCP, does not\n// allow an empty header to be used, and requires req.URL.Scheme to be either\n// \"http\" or \"https\".\n//\n// For further details, refer to:\n//\n//   - https://github.com/docker/engine-api/issues/189\n//   - https://github.com/golang/go/issues/13624\n//   - https://github.com/golang/go/issues/61076\n//   - https://github.com/moby/moby/issues/45935\n//\n// [RFC 2606, Section 2]: https://www.rfc-editor.org/rfc/rfc2606.html#section-2\n// [RFC 6761, Section 6.3]: https://www.rfc-editor.org/rfc/rfc6761#section-6.3\n// [RFC 7230, Section 5.4]: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4\n// [Go stdlib]: https://github.com/golang/go/blob/6244b1946bc2101b01955468f1be502dbadd6807/src/net/http/transport.go#L558-L569\nconst DummyHost = \"api.moby.localhost\"\n\n// fallbackAPIVersion is the version to fallback to if API-version negotiation\n// fails. This version is the highest version of the API before API-version\n// negotiation was introduced. If negotiation fails (or no API version was\n// included in the API response), we assume the API server uses the most\n// recent version before negotiation was introduced.\nconst fallbackAPIVersion = \"1.24\"\n\n// Client is the API client that performs all operations\n// against a docker server.\ntype Client struct {\n\t// scheme sets the scheme for the client\n\tscheme string\n\t// host holds the server address to connect to\n\thost string\n\t// proto holds the client protocol i.e. unix.\n\tproto string\n\t// addr holds the client address.\n\taddr string\n\t// basePath holds the path to prepend to the requests.\n\tbasePath string\n\t// client used to send and receive http requests.\n\tclient *http.Client\n\t// version of the server to talk to.\n\tversion string\n\t// userAgent is the User-Agent header to use for HTTP requests. It takes\n\t// precedence over User-Agent headers set in customHTTPHeaders, and other\n\t// header variables. When set to an empty string, the User-Agent header\n\t// is removed, and no header is sent.\n\tuserAgent *string\n\t// custom HTTP headers configured by users.\n\tcustomHTTPHeaders map[string]string\n\t// manualOverride is set to true when the version was set by users.\n\tmanualOverride bool\n\n\t// negotiateVersion indicates if the client should automatically negotiate\n\t// the API version to use when making requests. API version negotiation is\n\t// performed on the first request, after which negotiated is set to \"true\"\n\t// so that subsequent requests do not re-negotiate.\n\tnegotiateVersion bool\n\n\t// negotiated indicates that API version negotiation took place\n\tnegotiated bool\n\n\ttp trace.TracerProvider\n\n\t// When the client transport is an *http.Transport (default) we need to do some extra things (like closing idle connections).\n\t// Store the original transport as the http.Client transport will be wrapped with tracing libs.\n\tbaseTransport *http.Transport\n}\n\n// ErrRedirect is the error returned by checkRedirect when the request is non-GET.\nvar ErrRedirect = errors.New(\"unexpected redirect in response\")\n\n// CheckRedirect specifies the policy for dealing with redirect responses. It\n// can be set on [http.Client.CheckRedirect] to prevent HTTP redirects for\n// non-GET requests. It returns an [ErrRedirect] for non-GET request, otherwise\n// returns a [http.ErrUseLastResponse], which is special-cased by http.Client\n// to use the last response.\n//\n// Go 1.8 changed behavior for HTTP redirects (specifically 301, 307, and 308)\n// in the client. The client (and by extension API client) can be made to send\n// a request like \"POST /containers//start\" where what would normally be in the\n// name section of the URL is empty. This triggers an HTTP 301 from the daemon.\n//\n// In go 1.8 this 301 is converted to a GET request, and ends up getting\n// a 404 from the daemon. This behavior change manifests in the client in that\n// before, the 301 was not followed and the client did not generate an error,\n// but now results in a message like \"Error response from daemon: page not found\".\nfunc CheckRedirect(_ *http.Request, via []*http.Request) error {\n\tif via[0].Method == http.MethodGet {\n\t\treturn http.ErrUseLastResponse\n\t}\n\treturn ErrRedirect\n}\n\n// NewClientWithOpts initializes a new API client with a default HTTPClient, and\n// default API host and version. It also initializes the custom HTTP headers to\n// add to each request.\n//\n// It takes an optional list of [Opt] functional arguments, which are applied in\n// the order they're provided, which allows modifying the defaults when creating\n// the client. For example, the following initializes a client that configures\n// itself with values from environment variables ([FromEnv]), and has automatic\n// API version negotiation enabled ([WithAPIVersionNegotiation]).\n//\n//\tcli, err := client.NewClientWithOpts(\n//\t\tclient.FromEnv,\n//\t\tclient.WithAPIVersionNegotiation(),\n//\t)\nfunc NewClientWithOpts(ops ...Opt) (*Client, error) {\n\thostURL, err := ParseHostURL(DefaultDockerHost)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclient, err := defaultHTTPClient(hostURL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc := &Client{\n\t\thost:    DefaultDockerHost,\n\t\tversion: api.DefaultVersion,\n\t\tclient:  client,\n\t\tproto:   hostURL.Scheme,\n\t\taddr:    hostURL.Host,\n\t}\n\n\tfor _, op := range ops {\n\t\tif err := op(c); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif tr, ok := c.client.Transport.(*http.Transport); ok {\n\t\t// Store the base transport before we wrap it in tracing libs below\n\t\t// This is used, as an example, to close idle connections when the client is closed\n\t\tc.baseTransport = tr\n\t}\n\n\tif c.scheme == \"\" {\n\t\t// TODO(stevvooe): This isn't really the right way to write clients in Go.\n\t\t// `NewClient` should probably only take an `*http.Client` and work from there.\n\t\t// Unfortunately, the model of having a host-ish/url-thingy as the connection\n\t\t// string has us confusing protocol and transport layers. We continue doing\n\t\t// this to avoid breaking existing clients but this should be addressed.\n\t\tif c.tlsConfig() != nil {\n\t\t\tc.scheme = \"https\"\n\t\t} else {\n\t\t\tc.scheme = \"http\"\n\t\t}\n\t}\n\n\tc.client.Transport = otelhttp.NewTransport(\n\t\tc.client.Transport,\n\t\totelhttp.WithTracerProvider(c.tp),\n\t\totelhttp.WithSpanNameFormatter(func(_ string, req *http.Request) string {\n\t\t\treturn req.Method + \" \" + req.URL.Path\n\t\t}),\n\t)\n\n\treturn c, nil\n}\n\nfunc (cli *Client) tlsConfig() *tls.Config {\n\tif cli.baseTransport == nil {\n\t\treturn nil\n\t}\n\treturn cli.baseTransport.TLSClientConfig\n}\n\nfunc defaultHTTPClient(hostURL *url.URL) (*http.Client, error) {\n\ttransport := &http.Transport{}\n\terr := sockets.ConfigureTransport(transport, hostURL.Scheme, hostURL.Host)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &http.Client{\n\t\tTransport:     transport,\n\t\tCheckRedirect: CheckRedirect,\n\t}, nil\n}\n\n// Close the transport used by the client\nfunc (cli *Client) Close() error {\n\tif cli.baseTransport != nil {\n\t\tcli.baseTransport.CloseIdleConnections()\n\t\treturn nil\n\t}\n\treturn nil\n}\n\n// checkVersion manually triggers API version negotiation (if configured).\n// This allows for version-dependent code to use the same version as will\n// be negotiated when making the actual requests, and for which cases\n// we cannot do the negotiation lazily.\nfunc (cli *Client) checkVersion(ctx context.Context) error {\n\tif !cli.manualOverride && cli.negotiateVersion && !cli.negotiated {\n\t\tping, err := cli.Ping(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcli.negotiateAPIVersionPing(ping)\n\t}\n\treturn nil\n}\n\n// getAPIPath returns the versioned request path to call the API.\n// It appends the query parameters to the path if they are not empty.\nfunc (cli *Client) getAPIPath(ctx context.Context, p string, query url.Values) string {\n\tvar apiPath string\n\t_ = cli.checkVersion(ctx)\n\tif cli.version != \"\" {\n\t\tv := strings.TrimPrefix(cli.version, \"v\")\n\t\tapiPath = path.Join(cli.basePath, \"/v\"+v, p)\n\t} else {\n\t\tapiPath = path.Join(cli.basePath, p)\n\t}\n\treturn (&url.URL{Path: apiPath, RawQuery: query.Encode()}).String()\n}\n\n// ClientVersion returns the API version used by this client.\nfunc (cli *Client) ClientVersion() string {\n\treturn cli.version\n}\n\n// NegotiateAPIVersion queries the API and updates the version to match the API\n// version. NegotiateAPIVersion downgrades the client's API version to match the\n// APIVersion if the ping version is lower than the default version. If the API\n// version reported by the server is higher than the maximum version supported\n// by the client, it uses the client's maximum version.\n//\n// If a manual override is in place, either through the \"DOCKER_API_VERSION\"\n// ([EnvOverrideAPIVersion]) environment variable, or if the client is initialized\n// with a fixed version ([WithVersion]), no negotiation is performed.\n//\n// If the API server's ping response does not contain an API version, or if the\n// client did not get a successful ping response, it assumes it is connected with\n// an old daemon that does not support API version negotiation, in which case it\n// downgrades to the latest version of the API before version negotiation was\n// added (1.24).\nfunc (cli *Client) NegotiateAPIVersion(ctx context.Context) {\n\tif !cli.manualOverride {\n\t\tping, err := cli.Ping(ctx)\n\t\tif err != nil {\n\t\t\t// FIXME(thaJeztah): Ping returns an error when failing to connect to the API; we should not swallow the error here, and instead returning it.\n\t\t\treturn\n\t\t}\n\t\tcli.negotiateAPIVersionPing(ping)\n\t}\n}\n\n// NegotiateAPIVersionPing downgrades the client's API version to match the\n// APIVersion in the ping response. If the API version in pingResponse is higher\n// than the maximum version supported by the client, it uses the client's maximum\n// version.\n//\n// If a manual override is in place, either through the \"DOCKER_API_VERSION\"\n// ([EnvOverrideAPIVersion]) environment variable, or if the client is initialized\n// with a fixed version ([WithVersion]), no negotiation is performed.\n//\n// If the API server's ping response does not contain an API version, we assume\n// we are connected with an old daemon without API version negotiation support,\n// and downgrade to the latest version of the API before version negotiation was\n// added (1.24).\nfunc (cli *Client) NegotiateAPIVersionPing(pingResponse types.Ping) {\n\tif !cli.manualOverride {\n\t\tcli.negotiateAPIVersionPing(pingResponse)\n\t}\n}\n\n// negotiateAPIVersionPing queries the API and updates the version to match the\n// API version from the ping response.\nfunc (cli *Client) negotiateAPIVersionPing(pingResponse types.Ping) {\n\t// default to the latest version before versioning headers existed\n\tif pingResponse.APIVersion == \"\" {\n\t\tpingResponse.APIVersion = fallbackAPIVersion\n\t}\n\n\t// if the client is not initialized with a version, start with the latest supported version\n\tif cli.version == \"\" {\n\t\tcli.version = api.DefaultVersion\n\t}\n\n\t// if server version is lower than the client version, downgrade\n\tif versions.LessThan(pingResponse.APIVersion, cli.version) {\n\t\tcli.version = pingResponse.APIVersion\n\t}\n\n\t// Store the results, so that automatic API version negotiation (if enabled)\n\t// won't be performed on the next request.\n\tif cli.negotiateVersion {\n\t\tcli.negotiated = true\n\t}\n}\n\n// DaemonHost returns the host address used by the client\nfunc (cli *Client) DaemonHost() string {\n\treturn cli.host\n}\n\n// HTTPClient returns a copy of the HTTP client bound to the server\nfunc (cli *Client) HTTPClient() *http.Client {\n\tc := *cli.client\n\treturn &c\n}\n\n// ParseHostURL parses a url string, validates the string is a host url, and\n// returns the parsed URL\nfunc ParseHostURL(host string) (*url.URL, error) {\n\tproto, addr, ok := strings.Cut(host, \"://\")\n\tif !ok || addr == \"\" {\n\t\treturn nil, errors.Errorf(\"unable to parse docker host `%s`\", host)\n\t}\n\n\tvar basePath string\n\tif proto == \"tcp\" {\n\t\tparsed, err := url.Parse(\"tcp://\" + addr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\taddr = parsed.Host\n\t\tbasePath = parsed.Path\n\t}\n\treturn &url.URL{\n\t\tScheme: proto,\n\t\tHost:   addr,\n\t\tPath:   basePath,\n\t}, nil\n}\n\nfunc (cli *Client) dialerFromTransport() func(context.Context, string, string) (net.Conn, error) {\n\tif cli.baseTransport == nil || cli.baseTransport.DialContext == nil {\n\t\treturn nil\n\t}\n\n\tif cli.baseTransport.TLSClientConfig != nil {\n\t\t// When using a tls config we don't use the configured dialer but instead a fallback dialer...\n\t\t// Note: It seems like this should use the normal dialer and wrap the returned net.Conn in a tls.Conn\n\t\t// I honestly don't know why it doesn't do that, but it doesn't and such a change is entirely unrelated to the change in this commit.\n\t\treturn nil\n\t}\n\treturn cli.baseTransport.DialContext\n}\n\n// Dialer returns a dialer for a raw stream connection, with an HTTP/1.1 header,\n// that can be used for proxying the daemon connection. It is used by\n// [\"docker dial-stdio\"].\n//\n// [\"docker dial-stdio\"]: https://github.com/docker/cli/pull/1014\nfunc (cli *Client) Dialer() func(context.Context) (net.Conn, error) {\n\treturn func(ctx context.Context) (net.Conn, error) {\n\t\tif dialFn := cli.dialerFromTransport(); dialFn != nil {\n\t\t\treturn dialFn(ctx, cli.proto, cli.addr)\n\t\t}\n\t\tswitch cli.proto {\n\t\tcase \"unix\":\n\t\t\treturn net.Dial(cli.proto, cli.addr)\n\t\tcase \"npipe\":\n\t\t\treturn sockets.DialPipe(cli.addr, 32*time.Second)\n\t\tdefault:\n\t\t\tif tlsConfig := cli.tlsConfig(); tlsConfig != nil {\n\t\t\t\treturn tls.Dial(cli.proto, cli.addr, tlsConfig)\n\t\t\t}\n\t\t\treturn net.Dial(cli.proto, cli.addr)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/client_deprecated.go",
    "content": "package client\n\nimport \"net/http\"\n\n// NewClient initializes a new API client for the given host and API version.\n// It uses the given http client as transport.\n// It also initializes the custom http headers to add to each request.\n//\n// It won't send any version information if the version number is empty. It is\n// highly recommended that you set a version or your client may break if the\n// server is upgraded.\n//\n// Deprecated: use [NewClientWithOpts] passing the [WithHost], [WithVersion],\n// [WithHTTPClient] and [WithHTTPHeaders] options. We recommend enabling API\n// version negotiation by passing the [WithAPIVersionNegotiation] option instead\n// of WithVersion.\nfunc NewClient(host string, version string, client *http.Client, httpHeaders map[string]string) (*Client, error) {\n\treturn NewClientWithOpts(WithHost(host), WithVersion(version), WithHTTPClient(client), WithHTTPHeaders(httpHeaders))\n}\n\n// NewEnvClient initializes a new API client based on environment variables.\n// See FromEnv for a list of support environment variables.\n//\n// Deprecated: use [NewClientWithOpts] passing the [FromEnv] option.\nfunc NewEnvClient() (*Client, error) {\n\treturn NewClientWithOpts(FromEnv)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/client_unix.go",
    "content": "//go:build !windows\n\npackage client // import \"github.com/docker/docker/client\"\n\n// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST\n// (EnvOverrideHost) environment variable is unset or empty.\nconst DefaultDockerHost = \"unix:///var/run/docker.sock\"\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/client_windows.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\n// DefaultDockerHost defines OS-specific default host if the DOCKER_HOST\n// (EnvOverrideHost) environment variable is unset or empty.\nconst DefaultDockerHost = \"npipe:////./pipe/docker_engine\"\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/config_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// ConfigCreate creates a new config.\nfunc (cli *Client) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (types.ConfigCreateResponse, error) {\n\tvar response types.ConfigCreateResponse\n\tif err := cli.NewVersionError(ctx, \"1.30\", \"config create\"); err != nil {\n\t\treturn response, err\n\t}\n\tresp, err := cli.post(ctx, \"/configs/create\", nil, config, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/config_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// ConfigInspectWithRaw returns the config information with raw data\nfunc (cli *Client) ConfigInspectWithRaw(ctx context.Context, id string) (swarm.Config, []byte, error) {\n\tif id == \"\" {\n\t\treturn swarm.Config{}, nil, objectNotFoundError{object: \"config\", id: id}\n\t}\n\tif err := cli.NewVersionError(ctx, \"1.30\", \"config inspect\"); err != nil {\n\t\treturn swarm.Config{}, nil, err\n\t}\n\tresp, err := cli.get(ctx, \"/configs/\"+id, nil, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn swarm.Config{}, nil, err\n\t}\n\n\tbody, err := io.ReadAll(resp.body)\n\tif err != nil {\n\t\treturn swarm.Config{}, nil, err\n\t}\n\n\tvar config swarm.Config\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&config)\n\n\treturn config, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/config_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// ConfigList returns the list of configs.\nfunc (cli *Client) ConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error) {\n\tif err := cli.NewVersionError(ctx, \"1.30\", \"config list\"); err != nil {\n\t\treturn nil, err\n\t}\n\tquery := url.Values{}\n\n\tif options.Filters.Len() > 0 {\n\t\tfilterJSON, err := filters.ToJSON(options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\tresp, err := cli.get(ctx, \"/configs\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar configs []swarm.Config\n\terr = json.NewDecoder(resp.body).Decode(&configs)\n\treturn configs, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/config_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport \"context\"\n\n// ConfigRemove removes a config.\nfunc (cli *Client) ConfigRemove(ctx context.Context, id string) error {\n\tif err := cli.NewVersionError(ctx, \"1.30\", \"config remove\"); err != nil {\n\t\treturn err\n\t}\n\tresp, err := cli.delete(ctx, \"/configs/\"+id, nil, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/config_update.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// ConfigUpdate attempts to update a config\nfunc (cli *Client) ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error {\n\tif err := cli.NewVersionError(ctx, \"1.30\", \"config update\"); err != nil {\n\t\treturn err\n\t}\n\tquery := url.Values{}\n\tquery.Set(\"version\", version.String())\n\tresp, err := cli.post(ctx, \"/configs/\"+id+\"/update\", query, config, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_attach.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerAttach attaches a connection to a container in the server.\n// It returns a types.HijackedConnection with the hijacked connection\n// and the a reader to get output. It's up to the called to close\n// the hijacked connection by calling types.HijackedResponse.Close.\n//\n// The stream format on the response will be in one of two formats:\n//\n// If the container is using a TTY, there is only a single stream (stdout), and\n// data is copied directly from the container output stream, no extra\n// multiplexing or headers.\n//\n// If the container is *not* using a TTY, streams for stdout and stderr are\n// multiplexed.\n// The format of the multiplexed stream is as follows:\n//\n//\t[8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}\n//\n// STREAM_TYPE can be 1 for stdout and 2 for stderr\n//\n// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.\n// This is the size of OUTPUT.\n//\n// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this\n// stream.\nfunc (cli *Client) ContainerAttach(ctx context.Context, container string, options container.AttachOptions) (types.HijackedResponse, error) {\n\tquery := url.Values{}\n\tif options.Stream {\n\t\tquery.Set(\"stream\", \"1\")\n\t}\n\tif options.Stdin {\n\t\tquery.Set(\"stdin\", \"1\")\n\t}\n\tif options.Stdout {\n\t\tquery.Set(\"stdout\", \"1\")\n\t}\n\tif options.Stderr {\n\t\tquery.Set(\"stderr\", \"1\")\n\t}\n\tif options.DetachKeys != \"\" {\n\t\tquery.Set(\"detachKeys\", options.DetachKeys)\n\t}\n\tif options.Logs {\n\t\tquery.Set(\"logs\", \"1\")\n\t}\n\n\treturn cli.postHijacked(ctx, \"/containers/\"+container+\"/attach\", query, nil, http.Header{\n\t\t\"Content-Type\": {\"text/plain\"},\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_commit.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/url\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerCommit applies changes to a container and creates a new tagged image.\nfunc (cli *Client) ContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error) {\n\tvar repository, tag string\n\tif options.Reference != \"\" {\n\t\tref, err := reference.ParseNormalizedNamed(options.Reference)\n\t\tif err != nil {\n\t\t\treturn types.IDResponse{}, err\n\t\t}\n\n\t\tif _, isCanonical := ref.(reference.Canonical); isCanonical {\n\t\t\treturn types.IDResponse{}, errors.New(\"refusing to create a tag with a digest reference\")\n\t\t}\n\t\tref = reference.TagNameOnly(ref)\n\n\t\tif tagged, ok := ref.(reference.Tagged); ok {\n\t\t\ttag = tagged.Tag()\n\t\t}\n\t\trepository = reference.FamiliarName(ref)\n\t}\n\n\tquery := url.Values{}\n\tquery.Set(\"container\", container)\n\tquery.Set(\"repo\", repository)\n\tquery.Set(\"tag\", tag)\n\tquery.Set(\"comment\", options.Comment)\n\tquery.Set(\"author\", options.Author)\n\tfor _, change := range options.Changes {\n\t\tquery.Add(\"changes\", change)\n\t}\n\tif !options.Pause {\n\t\tquery.Set(\"pause\", \"0\")\n\t}\n\n\tvar response types.IDResponse\n\tresp, err := cli.post(ctx, \"/commit\", query, options.Config, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_copy.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// ContainerStatPath returns stat information about a path inside the container filesystem.\nfunc (cli *Client) ContainerStatPath(ctx context.Context, containerID, path string) (types.ContainerPathStat, error) {\n\tquery := url.Values{}\n\tquery.Set(\"path\", filepath.ToSlash(path)) // Normalize the paths used in the API.\n\n\turlStr := \"/containers/\" + containerID + \"/archive\"\n\tresponse, err := cli.head(ctx, urlStr, query, nil)\n\tdefer ensureReaderClosed(response)\n\tif err != nil {\n\t\treturn types.ContainerPathStat{}, err\n\t}\n\treturn getContainerPathStatFromHeader(response.header)\n}\n\n// CopyToContainer copies content into the container filesystem.\n// Note that `content` must be a Reader for a TAR archive\nfunc (cli *Client) CopyToContainer(ctx context.Context, containerID, dstPath string, content io.Reader, options types.CopyToContainerOptions) error {\n\tquery := url.Values{}\n\tquery.Set(\"path\", filepath.ToSlash(dstPath)) // Normalize the paths used in the API.\n\t// Do not allow for an existing directory to be overwritten by a non-directory and vice versa.\n\tif !options.AllowOverwriteDirWithFile {\n\t\tquery.Set(\"noOverwriteDirNonDir\", \"true\")\n\t}\n\n\tif options.CopyUIDGID {\n\t\tquery.Set(\"copyUIDGID\", \"true\")\n\t}\n\n\tapiPath := \"/containers/\" + containerID + \"/archive\"\n\n\tresponse, err := cli.putRaw(ctx, apiPath, query, content, nil)\n\tdefer ensureReaderClosed(response)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// CopyFromContainer gets the content from the container and returns it as a Reader\n// for a TAR archive to manipulate it in the host. It's up to the caller to close the reader.\nfunc (cli *Client) CopyFromContainer(ctx context.Context, containerID, srcPath string) (io.ReadCloser, types.ContainerPathStat, error) {\n\tquery := make(url.Values, 1)\n\tquery.Set(\"path\", filepath.ToSlash(srcPath)) // Normalize the paths used in the API.\n\n\tapiPath := \"/containers/\" + containerID + \"/archive\"\n\tresponse, err := cli.get(ctx, apiPath, query, nil)\n\tif err != nil {\n\t\treturn nil, types.ContainerPathStat{}, err\n\t}\n\n\t// In order to get the copy behavior right, we need to know information\n\t// about both the source and the destination. The response headers include\n\t// stat info about the source that we can use in deciding exactly how to\n\t// copy it locally. Along with the stat info about the local destination,\n\t// we have everything we need to handle the multiple possibilities there\n\t// can be when copying a file/dir from one location to another file/dir.\n\tstat, err := getContainerPathStatFromHeader(response.header)\n\tif err != nil {\n\t\treturn nil, stat, fmt.Errorf(\"unable to get resource stat from response: %s\", err)\n\t}\n\treturn response.body, stat, err\n}\n\nfunc getContainerPathStatFromHeader(header http.Header) (types.ContainerPathStat, error) {\n\tvar stat types.ContainerPathStat\n\n\tencodedStat := header.Get(\"X-Docker-Container-Path-Stat\")\n\tstatDecoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(encodedStat))\n\n\terr := json.NewDecoder(statDecoder).Decode(&stat)\n\tif err != nil {\n\t\terr = fmt.Errorf(\"unable to decode container path stat header: %s\", err)\n\t}\n\n\treturn stat, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"path\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/network\"\n\t\"github.com/docker/docker/api/types/versions\"\n\tocispec \"github.com/opencontainers/image-spec/specs-go/v1\"\n)\n\ntype configWrapper struct {\n\t*container.Config\n\tHostConfig       *container.HostConfig\n\tNetworkingConfig *network.NetworkingConfig\n}\n\n// ContainerCreate creates a new container based on the given configuration.\n// It can be associated with a name, but it's not mandatory.\nfunc (cli *Client) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error) {\n\tvar response container.CreateResponse\n\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\treturn response, err\n\t}\n\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"stop timeout\"); config != nil && config.StopTimeout != nil && err != nil {\n\t\treturn response, err\n\t}\n\tif err := cli.NewVersionError(ctx, \"1.41\", \"specify container image platform\"); platform != nil && err != nil {\n\t\treturn response, err\n\t}\n\tif err := cli.NewVersionError(ctx, \"1.44\", \"specify health-check start interval\"); config != nil && config.Healthcheck != nil && config.Healthcheck.StartInterval != 0 && err != nil {\n\t\treturn response, err\n\t}\n\tif err := cli.NewVersionError(ctx, \"1.44\", \"specify mac-address per network\"); hasEndpointSpecificMacAddress(networkingConfig) && err != nil {\n\t\treturn response, err\n\t}\n\n\tif hostConfig != nil {\n\t\tif versions.LessThan(cli.ClientVersion(), \"1.25\") {\n\t\t\t// When using API 1.24 and under, the client is responsible for removing the container\n\t\t\thostConfig.AutoRemove = false\n\t\t}\n\t\tif versions.GreaterThanOrEqualTo(cli.ClientVersion(), \"1.42\") || versions.LessThan(cli.ClientVersion(), \"1.40\") {\n\t\t\t// KernelMemory was added in API 1.40, and deprecated in API 1.42\n\t\t\thostConfig.KernelMemory = 0\n\t\t}\n\t\tif platform != nil && platform.OS == \"linux\" && versions.LessThan(cli.ClientVersion(), \"1.42\") {\n\t\t\t// When using API under 1.42, the Linux daemon doesn't respect the ConsoleSize\n\t\t\thostConfig.ConsoleSize = [2]uint{0, 0}\n\t\t}\n\t}\n\n\t// Since API 1.44, the container-wide MacAddress is deprecated and will trigger a WARNING if it's specified.\n\tif versions.GreaterThanOrEqualTo(cli.ClientVersion(), \"1.44\") {\n\t\tconfig.MacAddress = \"\" //nolint:staticcheck // ignore SA1019: field is deprecated, but still used on API < v1.44.\n\t}\n\n\tquery := url.Values{}\n\tif p := formatPlatform(platform); p != \"\" {\n\t\tquery.Set(\"platform\", p)\n\t}\n\n\tif containerName != \"\" {\n\t\tquery.Set(\"name\", containerName)\n\t}\n\n\tbody := configWrapper{\n\t\tConfig:           config,\n\t\tHostConfig:       hostConfig,\n\t\tNetworkingConfig: networkingConfig,\n\t}\n\n\tserverResp, err := cli.post(ctx, \"/containers/create\", query, body, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(serverResp.body).Decode(&response)\n\treturn response, err\n}\n\n// formatPlatform returns a formatted string representing platform (e.g. linux/arm/v7).\n//\n// Similar to containerd's platforms.Format(), but does allow components to be\n// omitted (e.g. pass \"architecture\" only, without \"os\":\n// https://github.com/containerd/containerd/blob/v1.5.2/platforms/platforms.go#L243-L263\nfunc formatPlatform(platform *ocispec.Platform) string {\n\tif platform == nil {\n\t\treturn \"\"\n\t}\n\treturn path.Join(platform.OS, platform.Architecture, platform.Variant)\n}\n\n// hasEndpointSpecificMacAddress checks whether one of the endpoint in networkingConfig has a MacAddress defined.\nfunc hasEndpointSpecificMacAddress(networkingConfig *network.NetworkingConfig) bool {\n\tif networkingConfig == nil {\n\t\treturn false\n\t}\n\tfor _, endpoint := range networkingConfig.EndpointsConfig {\n\t\tif endpoint.MacAddress != \"\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_diff.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerDiff shows differences in a container filesystem since it was started.\nfunc (cli *Client) ContainerDiff(ctx context.Context, containerID string) ([]container.FilesystemChange, error) {\n\tvar changes []container.FilesystemChange\n\n\tserverResp, err := cli.get(ctx, \"/containers/\"+containerID+\"/changes\", url.Values{}, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn changes, err\n\t}\n\n\terr = json.NewDecoder(serverResp.body).Decode(&changes)\n\treturn changes, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_exec.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// ContainerExecCreate creates a new exec configuration to run an exec process.\nfunc (cli *Client) ContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error) {\n\tvar response types.IDResponse\n\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\treturn response, err\n\t}\n\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"env\"); len(config.Env) != 0 && err != nil {\n\t\treturn response, err\n\t}\n\tif versions.LessThan(cli.ClientVersion(), \"1.42\") {\n\t\tconfig.ConsoleSize = nil\n\t}\n\n\tresp, err := cli.post(ctx, \"/containers/\"+container+\"/exec\", nil, config, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\treturn response, err\n}\n\n// ContainerExecStart starts an exec process already created in the docker host.\nfunc (cli *Client) ContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error {\n\tif versions.LessThan(cli.ClientVersion(), \"1.42\") {\n\t\tconfig.ConsoleSize = nil\n\t}\n\tresp, err := cli.post(ctx, \"/exec/\"+execID+\"/start\", nil, config, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n\n// ContainerExecAttach attaches a connection to an exec process in the server.\n// It returns a types.HijackedConnection with the hijacked connection\n// and the a reader to get output. It's up to the called to close\n// the hijacked connection by calling types.HijackedResponse.Close.\nfunc (cli *Client) ContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error) {\n\tif versions.LessThan(cli.ClientVersion(), \"1.42\") {\n\t\tconfig.ConsoleSize = nil\n\t}\n\treturn cli.postHijacked(ctx, \"/exec/\"+execID+\"/start\", nil, config, http.Header{\n\t\t\"Content-Type\": {\"application/json\"},\n\t})\n}\n\n// ContainerExecInspect returns information about a specific exec process on the docker host.\nfunc (cli *Client) ContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error) {\n\tvar response types.ContainerExecInspect\n\tresp, err := cli.get(ctx, \"/exec/\"+execID+\"/json\", nil, nil)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\tensureReaderClosed(resp)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_export.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/url\"\n)\n\n// ContainerExport retrieves the raw contents of a container\n// and returns them as an io.ReadCloser. It's up to the caller\n// to close the stream.\nfunc (cli *Client) ContainerExport(ctx context.Context, containerID string) (io.ReadCloser, error) {\n\tserverResp, err := cli.get(ctx, \"/containers/\"+containerID+\"/export\", url.Values{}, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn serverResp.body, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// ContainerInspect returns the container information.\nfunc (cli *Client) ContainerInspect(ctx context.Context, containerID string) (types.ContainerJSON, error) {\n\tif containerID == \"\" {\n\t\treturn types.ContainerJSON{}, objectNotFoundError{object: \"container\", id: containerID}\n\t}\n\tserverResp, err := cli.get(ctx, \"/containers/\"+containerID+\"/json\", nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn types.ContainerJSON{}, err\n\t}\n\n\tvar response types.ContainerJSON\n\terr = json.NewDecoder(serverResp.body).Decode(&response)\n\treturn response, err\n}\n\n// ContainerInspectWithRaw returns the container information and its raw representation.\nfunc (cli *Client) ContainerInspectWithRaw(ctx context.Context, containerID string, getSize bool) (types.ContainerJSON, []byte, error) {\n\tif containerID == \"\" {\n\t\treturn types.ContainerJSON{}, nil, objectNotFoundError{object: \"container\", id: containerID}\n\t}\n\tquery := url.Values{}\n\tif getSize {\n\t\tquery.Set(\"size\", \"1\")\n\t}\n\tserverResp, err := cli.get(ctx, \"/containers/\"+containerID+\"/json\", query, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn types.ContainerJSON{}, nil, err\n\t}\n\n\tbody, err := io.ReadAll(serverResp.body)\n\tif err != nil {\n\t\treturn types.ContainerJSON{}, nil, err\n\t}\n\n\tvar response types.ContainerJSON\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&response)\n\treturn response, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_kill.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n)\n\n// ContainerKill terminates the container process but does not remove the container from the docker host.\nfunc (cli *Client) ContainerKill(ctx context.Context, containerID, signal string) error {\n\tquery := url.Values{}\n\tif signal != \"\" {\n\t\tquery.Set(\"signal\", signal)\n\t}\n\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/kill\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"strconv\"\n\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/filters\"\n)\n\n// ContainerList returns the list of containers in the docker host.\nfunc (cli *Client) ContainerList(ctx context.Context, options container.ListOptions) ([]types.Container, error) {\n\tquery := url.Values{}\n\n\tif options.All {\n\t\tquery.Set(\"all\", \"1\")\n\t}\n\n\tif options.Limit > 0 {\n\t\tquery.Set(\"limit\", strconv.Itoa(options.Limit))\n\t}\n\n\tif options.Since != \"\" {\n\t\tquery.Set(\"since\", options.Since)\n\t}\n\n\tif options.Before != \"\" {\n\t\tquery.Set(\"before\", options.Before)\n\t}\n\n\tif options.Size {\n\t\tquery.Set(\"size\", \"1\")\n\t}\n\n\tif options.Filters.Len() > 0 {\n\t\t//nolint:staticcheck // ignore SA1019 for old code\n\t\tfilterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\tresp, err := cli.get(ctx, \"/containers/json\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar containers []types.Container\n\terr = json.NewDecoder(resp.body).Decode(&containers)\n\treturn containers, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_logs.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\ttimetypes \"github.com/docker/docker/api/types/time\"\n\t\"github.com/pkg/errors\"\n)\n\n// ContainerLogs returns the logs generated by a container in an io.ReadCloser.\n// It's up to the caller to close the stream.\n//\n// The stream format on the response will be in one of two formats:\n//\n// If the container is using a TTY, there is only a single stream (stdout), and\n// data is copied directly from the container output stream, no extra\n// multiplexing or headers.\n//\n// If the container is *not* using a TTY, streams for stdout and stderr are\n// multiplexed.\n// The format of the multiplexed stream is as follows:\n//\n//\t[8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}\n//\n// STREAM_TYPE can be 1 for stdout and 2 for stderr\n//\n// SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian.\n// This is the size of OUTPUT.\n//\n// You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this\n// stream.\nfunc (cli *Client) ContainerLogs(ctx context.Context, container string, options container.LogsOptions) (io.ReadCloser, error) {\n\tquery := url.Values{}\n\tif options.ShowStdout {\n\t\tquery.Set(\"stdout\", \"1\")\n\t}\n\n\tif options.ShowStderr {\n\t\tquery.Set(\"stderr\", \"1\")\n\t}\n\n\tif options.Since != \"\" {\n\t\tts, err := timetypes.GetTimestamp(options.Since, time.Now())\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, `invalid value for \"since\"`)\n\t\t}\n\t\tquery.Set(\"since\", ts)\n\t}\n\n\tif options.Until != \"\" {\n\t\tts, err := timetypes.GetTimestamp(options.Until, time.Now())\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, `invalid value for \"until\"`)\n\t\t}\n\t\tquery.Set(\"until\", ts)\n\t}\n\n\tif options.Timestamps {\n\t\tquery.Set(\"timestamps\", \"1\")\n\t}\n\n\tif options.Details {\n\t\tquery.Set(\"details\", \"1\")\n\t}\n\n\tif options.Follow {\n\t\tquery.Set(\"follow\", \"1\")\n\t}\n\tquery.Set(\"tail\", options.Tail)\n\n\tresp, err := cli.get(ctx, \"/containers/\"+container+\"/logs\", query, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_pause.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport \"context\"\n\n// ContainerPause pauses the main process of a given container without terminating it.\nfunc (cli *Client) ContainerPause(ctx context.Context, containerID string) error {\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/pause\", nil, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_prune.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\n// ContainersPrune requests the daemon to delete unused data\nfunc (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error) {\n\tvar report types.ContainersPruneReport\n\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"container prune\"); err != nil {\n\t\treturn report, err\n\t}\n\n\tquery, err := getFiltersQuery(pruneFilters)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tserverResp, err := cli.post(ctx, \"/containers/prune\", query, nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tif err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {\n\t\treturn report, fmt.Errorf(\"Error retrieving disk usage: %v\", err)\n\t}\n\n\treturn report, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerRemove kills and removes a container from the docker host.\nfunc (cli *Client) ContainerRemove(ctx context.Context, containerID string, options container.RemoveOptions) error {\n\tquery := url.Values{}\n\tif options.RemoveVolumes {\n\t\tquery.Set(\"v\", \"1\")\n\t}\n\tif options.RemoveLinks {\n\t\tquery.Set(\"link\", \"1\")\n\t}\n\n\tif options.Force {\n\t\tquery.Set(\"force\", \"1\")\n\t}\n\n\tresp, err := cli.delete(ctx, \"/containers/\"+containerID, query, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_rename.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n)\n\n// ContainerRename changes the name of a given container.\nfunc (cli *Client) ContainerRename(ctx context.Context, containerID, newContainerName string) error {\n\tquery := url.Values{}\n\tquery.Set(\"name\", newContainerName)\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/rename\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_resize.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerResize changes the size of the tty for a container.\nfunc (cli *Client) ContainerResize(ctx context.Context, containerID string, options container.ResizeOptions) error {\n\treturn cli.resize(ctx, \"/containers/\"+containerID, options.Height, options.Width)\n}\n\n// ContainerExecResize changes the size of the tty for an exec process running inside a container.\nfunc (cli *Client) ContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error {\n\treturn cli.resize(ctx, \"/exec/\"+execID, options.Height, options.Width)\n}\n\nfunc (cli *Client) resize(ctx context.Context, basePath string, height, width uint) error {\n\tquery := url.Values{}\n\tquery.Set(\"h\", strconv.Itoa(int(height)))\n\tquery.Set(\"w\", strconv.Itoa(int(width)))\n\n\tresp, err := cli.post(ctx, basePath+\"/resize\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_restart.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// ContainerRestart stops and starts a container again.\n// It makes the daemon wait for the container to be up again for\n// a specific amount of time, given the timeout.\nfunc (cli *Client) ContainerRestart(ctx context.Context, containerID string, options container.StopOptions) error {\n\tquery := url.Values{}\n\tif options.Timeout != nil {\n\t\tquery.Set(\"t\", strconv.Itoa(*options.Timeout))\n\t}\n\tif options.Signal != \"\" {\n\t\t// Make sure we negotiated (if the client is configured to do so),\n\t\t// as code below contains API-version specific handling of options.\n\t\t//\n\t\t// Normally, version-negotiation (if enabled) would not happen until\n\t\t// the API request is made.\n\t\tif err := cli.checkVersion(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif versions.GreaterThanOrEqualTo(cli.version, \"1.42\") {\n\t\t\tquery.Set(\"signal\", options.Signal)\n\t\t}\n\t}\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/restart\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_start.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerStart sends a request to the docker daemon to start a container.\nfunc (cli *Client) ContainerStart(ctx context.Context, containerID string, options container.StartOptions) error {\n\tquery := url.Values{}\n\tif len(options.CheckpointID) != 0 {\n\t\tquery.Set(\"checkpoint\", options.CheckpointID)\n\t}\n\tif len(options.CheckpointDir) != 0 {\n\t\tquery.Set(\"checkpoint-dir\", options.CheckpointDir)\n\t}\n\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/start\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_stats.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// ContainerStats returns near realtime stats for a given container.\n// It's up to the caller to close the io.ReadCloser returned.\nfunc (cli *Client) ContainerStats(ctx context.Context, containerID string, stream bool) (types.ContainerStats, error) {\n\tquery := url.Values{}\n\tquery.Set(\"stream\", \"0\")\n\tif stream {\n\t\tquery.Set(\"stream\", \"1\")\n\t}\n\n\tresp, err := cli.get(ctx, \"/containers/\"+containerID+\"/stats\", query, nil)\n\tif err != nil {\n\t\treturn types.ContainerStats{}, err\n\t}\n\n\treturn types.ContainerStats{\n\t\tBody:   resp.body,\n\t\tOSType: getDockerOS(resp.header.Get(\"Server\")),\n\t}, nil\n}\n\n// ContainerStatsOneShot gets a single stat entry from a container.\n// It differs from `ContainerStats` in that the API should not wait to prime the stats\nfunc (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string) (types.ContainerStats, error) {\n\tquery := url.Values{}\n\tquery.Set(\"stream\", \"0\")\n\tquery.Set(\"one-shot\", \"1\")\n\n\tresp, err := cli.get(ctx, \"/containers/\"+containerID+\"/stats\", query, nil)\n\tif err != nil {\n\t\treturn types.ContainerStats{}, err\n\t}\n\n\treturn types.ContainerStats{\n\t\tBody:   resp.body,\n\t\tOSType: getDockerOS(resp.header.Get(\"Server\")),\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_stop.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// ContainerStop stops a container. In case the container fails to stop\n// gracefully within a time frame specified by the timeout argument,\n// it is forcefully terminated (killed).\n//\n// If the timeout is nil, the container's StopTimeout value is used, if set,\n// otherwise the engine default. A negative timeout value can be specified,\n// meaning no timeout, i.e. no forceful termination is performed.\nfunc (cli *Client) ContainerStop(ctx context.Context, containerID string, options container.StopOptions) error {\n\tquery := url.Values{}\n\tif options.Timeout != nil {\n\t\tquery.Set(\"t\", strconv.Itoa(*options.Timeout))\n\t}\n\tif options.Signal != \"\" {\n\t\t// Make sure we negotiated (if the client is configured to do so),\n\t\t// as code below contains API-version specific handling of options.\n\t\t//\n\t\t// Normally, version-negotiation (if enabled) would not happen until\n\t\t// the API request is made.\n\t\tif err := cli.checkVersion(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif versions.GreaterThanOrEqualTo(cli.version, \"1.42\") {\n\t\t\tquery.Set(\"signal\", options.Signal)\n\t\t}\n\t}\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/stop\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_top.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerTop shows process information from within a container.\nfunc (cli *Client) ContainerTop(ctx context.Context, containerID string, arguments []string) (container.ContainerTopOKBody, error) {\n\tvar response container.ContainerTopOKBody\n\tquery := url.Values{}\n\tif len(arguments) > 0 {\n\t\tquery.Set(\"ps_args\", strings.Join(arguments, \" \"))\n\t}\n\n\tresp, err := cli.get(ctx, \"/containers/\"+containerID+\"/top\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_unpause.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport \"context\"\n\n// ContainerUnpause resumes the process execution within a container\nfunc (cli *Client) ContainerUnpause(ctx context.Context, containerID string) error {\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/unpause\", nil, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_update.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ContainerUpdate updates the resources of a container.\nfunc (cli *Client) ContainerUpdate(ctx context.Context, containerID string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error) {\n\tvar response container.ContainerUpdateOKBody\n\tserverResp, err := cli.post(ctx, \"/containers/\"+containerID+\"/update\", nil, updateConfig, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(serverResp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/container_wait.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\nconst containerWaitErrorMsgLimit = 2 * 1024 /* Max: 2KiB */\n\n// ContainerWait waits until the specified container is in a certain state\n// indicated by the given condition, either \"not-running\" (default),\n// \"next-exit\", or \"removed\".\n//\n// If this client's API version is before 1.30, condition is ignored and\n// ContainerWait will return immediately with the two channels, as the server\n// will wait as if the condition were \"not-running\".\n//\n// If this client's API version is at least 1.30, ContainerWait blocks until\n// the request has been acknowledged by the server (with a response header),\n// then returns two channels on which the caller can wait for the exit status\n// of the container or an error if there was a problem either beginning the\n// wait request or in getting the response. This allows the caller to\n// synchronize ContainerWait with other calls, such as specifying a\n// \"next-exit\" condition before issuing a ContainerStart request.\nfunc (cli *Client) ContainerWait(ctx context.Context, containerID string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) {\n\tresultC := make(chan container.WaitResponse)\n\terrC := make(chan error, 1)\n\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\terrC <- err\n\t\treturn resultC, errC\n\t}\n\tif versions.LessThan(cli.ClientVersion(), \"1.30\") {\n\t\treturn cli.legacyContainerWait(ctx, containerID)\n\t}\n\n\tquery := url.Values{}\n\tif condition != \"\" {\n\t\tquery.Set(\"condition\", string(condition))\n\t}\n\n\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/wait\", query, nil, nil)\n\tif err != nil {\n\t\tdefer ensureReaderClosed(resp)\n\t\terrC <- err\n\t\treturn resultC, errC\n\t}\n\n\tgo func() {\n\t\tdefer ensureReaderClosed(resp)\n\n\t\tbody := resp.body\n\t\tresponseText := bytes.NewBuffer(nil)\n\t\tstream := io.TeeReader(body, responseText)\n\n\t\tvar res container.WaitResponse\n\t\tif err := json.NewDecoder(stream).Decode(&res); err != nil {\n\t\t\t// NOTE(nicks): The /wait API does not work well with HTTP proxies.\n\t\t\t// At any time, the proxy could cut off the response stream.\n\t\t\t//\n\t\t\t// But because the HTTP status has already been written, the proxy's\n\t\t\t// only option is to write a plaintext error message.\n\t\t\t//\n\t\t\t// If there's a JSON parsing error, read the real error message\n\t\t\t// off the body and send it to the client.\n\t\t\tif errors.As(err, new(*json.SyntaxError)) {\n\t\t\t\t_, _ = io.ReadAll(io.LimitReader(stream, containerWaitErrorMsgLimit))\n\t\t\t\terrC <- errors.New(responseText.String())\n\t\t\t} else {\n\t\t\t\terrC <- err\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tresultC <- res\n\t}()\n\n\treturn resultC, errC\n}\n\n// legacyContainerWait returns immediately and doesn't have an option to wait\n// until the container is removed.\nfunc (cli *Client) legacyContainerWait(ctx context.Context, containerID string) (<-chan container.WaitResponse, <-chan error) {\n\tresultC := make(chan container.WaitResponse)\n\terrC := make(chan error)\n\n\tgo func() {\n\t\tresp, err := cli.post(ctx, \"/containers/\"+containerID+\"/wait\", nil, nil, nil)\n\t\tif err != nil {\n\t\t\terrC <- err\n\t\t\treturn\n\t\t}\n\t\tdefer ensureReaderClosed(resp)\n\n\t\tvar res container.WaitResponse\n\t\tif err := json.NewDecoder(resp.body).Decode(&res); err != nil {\n\t\t\terrC <- err\n\t\t\treturn\n\t\t}\n\n\t\tresultC <- res\n\t}()\n\n\treturn resultC, errC\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/disk_usage.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// DiskUsage requests the current data usage from the daemon\nfunc (cli *Client) DiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error) {\n\tvar query url.Values\n\tif len(options.Types) > 0 {\n\t\tquery = url.Values{}\n\t\tfor _, t := range options.Types {\n\t\t\tquery.Add(\"type\", string(t))\n\t\t}\n\t}\n\n\tserverResp, err := cli.get(ctx, \"/system/df\", query, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn types.DiskUsage{}, err\n\t}\n\n\tvar du types.DiskUsage\n\tif err := json.NewDecoder(serverResp.body).Decode(&du); err != nil {\n\t\treturn types.DiskUsage{}, fmt.Errorf(\"Error retrieving disk usage: %v\", err)\n\t}\n\treturn du, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/distribution_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/registry\"\n)\n\n// DistributionInspect returns the image digest with the full manifest.\nfunc (cli *Client) DistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registry.DistributionInspect, error) {\n\t// Contact the registry to retrieve digest and platform information\n\tvar distributionInspect registry.DistributionInspect\n\tif image == \"\" {\n\t\treturn distributionInspect, objectNotFoundError{object: \"distribution\", id: image}\n\t}\n\n\tif err := cli.NewVersionError(ctx, \"1.30\", \"distribution inspect\"); err != nil {\n\t\treturn distributionInspect, err\n\t}\n\n\tvar headers http.Header\n\tif encodedRegistryAuth != \"\" {\n\t\theaders = http.Header{\n\t\t\tregistry.AuthHeader: {encodedRegistryAuth},\n\t\t}\n\t}\n\n\tresp, err := cli.get(ctx, \"/distribution/\"+image+\"/json\", url.Values{}, headers)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn distributionInspect, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&distributionInspect)\n\treturn distributionInspect, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/envvars.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nconst (\n\t// EnvOverrideHost is the name of the environment variable that can be used\n\t// to override the default host to connect to (DefaultDockerHost).\n\t//\n\t// This env-var is read by FromEnv and WithHostFromEnv and when set to a\n\t// non-empty value, takes precedence over the default host (which is platform\n\t// specific), or any host already set.\n\tEnvOverrideHost = \"DOCKER_HOST\"\n\n\t// EnvOverrideAPIVersion is the name of the environment variable that can\n\t// be used to override the API version to use. Value should be\n\t// formatted as MAJOR.MINOR, for example, \"1.19\".\n\t//\n\t// This env-var is read by FromEnv and WithVersionFromEnv and when set to a\n\t// non-empty value, takes precedence over API version negotiation.\n\t//\n\t// This environment variable should be used for debugging purposes only, as\n\t// it can set the client to use an incompatible (or invalid) API version.\n\tEnvOverrideAPIVersion = \"DOCKER_API_VERSION\"\n\n\t// EnvOverrideCertPath is the name of the environment variable that can be\n\t// used to specify the directory from which to load the TLS certificates\n\t// (ca.pem, cert.pem, key.pem) from. These certificates are used to configure\n\t// the Client for a TCP connection protected by TLS client authentication.\n\t//\n\t// TLS certificate verification is enabled by default if the Client is configured\n\t// to use a TLS connection. Refer to EnvTLSVerify below to learn how to\n\t// disable verification for testing purposes.\n\t//\n\t// WARNING: Access to the remote API is equivalent to root access to the\n\t// host where the daemon runs. Do not expose the API without protection,\n\t// and only if needed. Make sure you are familiar with the \"daemon attack\n\t// surface\" (https://docs.docker.com/go/attack-surface/).\n\t//\n\t// For local access to the API, it is recommended to connect with the daemon\n\t// using the default local socket connection (on Linux), or the named pipe\n\t// (on Windows).\n\t//\n\t// If you need to access the API of a remote daemon, consider using an SSH\n\t// (ssh://) connection, which is easier to set up, and requires no additional\n\t// configuration if the host is accessible using ssh.\n\t//\n\t// If you cannot use the alternatives above, and you must expose the API over\n\t// a TCP connection, refer to https://docs.docker.com/engine/security/protect-access/\n\t// to learn how to configure the daemon and client to use a TCP connection\n\t// with TLS client authentication. Make sure you know the differences between\n\t// a regular TLS connection and a TLS connection protected by TLS client\n\t// authentication, and verify that the API cannot be accessed by other clients.\n\tEnvOverrideCertPath = \"DOCKER_CERT_PATH\"\n\n\t// EnvTLSVerify is the name of the environment variable that can be used to\n\t// enable or disable TLS certificate verification. When set to a non-empty\n\t// value, TLS certificate verification is enabled, and the client is configured\n\t// to use a TLS connection, using certificates from the default directories\n\t// (within `~/.docker`); refer to EnvOverrideCertPath above for additional\n\t// details.\n\t//\n\t// WARNING: Access to the remote API is equivalent to root access to the\n\t// host where the daemon runs. Do not expose the API without protection,\n\t// and only if needed. Make sure you are familiar with the \"daemon attack\n\t// surface\" (https://docs.docker.com/go/attack-surface/).\n\t//\n\t// Before setting up your client and daemon to use a TCP connection with TLS\n\t// client authentication, consider using one of the alternatives mentioned\n\t// in EnvOverrideCertPath above.\n\t//\n\t// Disabling TLS certificate verification (for testing purposes)\n\t//\n\t// TLS certificate verification is enabled by default if the Client is configured\n\t// to use a TLS connection, and it is highly recommended to keep verification\n\t// enabled to prevent machine-in-the-middle attacks. Refer to the documentation\n\t// at https://docs.docker.com/engine/security/protect-access/ and pages linked\n\t// from that page to learn how to configure the daemon and client to use a\n\t// TCP connection with TLS client authentication enabled.\n\t//\n\t// Set the \"DOCKER_TLS_VERIFY\" environment to an empty string (\"\") to\n\t// disable TLS certificate verification. Disabling verification is insecure,\n\t// so should only be done for testing purposes. From the Go documentation\n\t// (https://pkg.go.dev/crypto/tls#Config):\n\t//\n\t// InsecureSkipVerify controls whether a client verifies the server's\n\t// certificate chain and host name. If InsecureSkipVerify is true, crypto/tls\n\t// accepts any certificate presented by the server and any host name in that\n\t// certificate. In this mode, TLS is susceptible to machine-in-the-middle\n\t// attacks unless custom verification is used. This should be used only for\n\t// testing or in combination with VerifyConnection or VerifyPeerCertificate.\n\tEnvTLSVerify = \"DOCKER_TLS_VERIFY\"\n)\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/errors.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\n\t\"github.com/docker/docker/api/types/versions\"\n\t\"github.com/docker/docker/errdefs\"\n\t\"github.com/pkg/errors\"\n)\n\n// errConnectionFailed implements an error returned when connection failed.\ntype errConnectionFailed struct {\n\terror\n}\n\n// Error returns a string representation of an errConnectionFailed\nfunc (e errConnectionFailed) Error() string {\n\treturn e.error.Error()\n}\n\nfunc (e errConnectionFailed) Unwrap() error {\n\treturn e.error\n}\n\n// IsErrConnectionFailed returns true if the error is caused by connection failed.\nfunc IsErrConnectionFailed(err error) bool {\n\treturn errors.As(err, &errConnectionFailed{})\n}\n\n// ErrorConnectionFailed returns an error with host in the error message when connection to docker daemon failed.\nfunc ErrorConnectionFailed(host string) error {\n\tvar err error\n\tif host == \"\" {\n\t\terr = fmt.Errorf(\"Cannot connect to the Docker daemon. Is the docker daemon running on this host?\")\n\t} else {\n\t\terr = fmt.Errorf(\"Cannot connect to the Docker daemon at %s. Is the docker daemon running?\", host)\n\t}\n\treturn errConnectionFailed{error: err}\n}\n\n// IsErrNotFound returns true if the error is a NotFound error, which is returned\n// by the API when some object is not found. It is an alias for [errdefs.IsNotFound].\nfunc IsErrNotFound(err error) bool {\n\treturn errdefs.IsNotFound(err)\n}\n\ntype objectNotFoundError struct {\n\tobject string\n\tid     string\n}\n\nfunc (e objectNotFoundError) NotFound() {}\n\nfunc (e objectNotFoundError) Error() string {\n\treturn fmt.Sprintf(\"Error: No such %s: %s\", e.object, e.id)\n}\n\n// NewVersionError returns an error if the APIVersion required is less than the\n// current supported version.\n//\n// It performs API-version negotiation if the Client is configured with this\n// option, otherwise it assumes the latest API version is used.\nfunc (cli *Client) NewVersionError(ctx context.Context, APIrequired, feature string) error {\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\treturn err\n\t}\n\tif cli.version != \"\" && versions.LessThan(cli.version, APIrequired) {\n\t\treturn fmt.Errorf(\"%q requires API version %s, but the Docker daemon API version is %s\", feature, APIrequired, cli.version)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/events.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/events\"\n\t\"github.com/docker/docker/api/types/filters\"\n\ttimetypes \"github.com/docker/docker/api/types/time\"\n)\n\n// Events returns a stream of events in the daemon. It's up to the caller to close the stream\n// by cancelling the context. Once the stream has been completely read an io.EOF error will\n// be sent over the error channel. If an error is sent all processing will be stopped. It's up\n// to the caller to reopen the stream in the event of an error by reinvoking this method.\nfunc (cli *Client) Events(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error) {\n\tmessages := make(chan events.Message)\n\terrs := make(chan error, 1)\n\n\tstarted := make(chan struct{})\n\tgo func() {\n\t\tdefer close(errs)\n\n\t\tquery, err := buildEventsQueryParams(cli.version, options)\n\t\tif err != nil {\n\t\t\tclose(started)\n\t\t\terrs <- err\n\t\t\treturn\n\t\t}\n\n\t\tresp, err := cli.get(ctx, \"/events\", query, nil)\n\t\tif err != nil {\n\t\t\tclose(started)\n\t\t\terrs <- err\n\t\t\treturn\n\t\t}\n\t\tdefer resp.body.Close()\n\n\t\tdecoder := json.NewDecoder(resp.body)\n\n\t\tclose(started)\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\terrs <- ctx.Err()\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t\tvar event events.Message\n\t\t\t\tif err := decoder.Decode(&event); err != nil {\n\t\t\t\t\terrs <- err\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tselect {\n\t\t\t\tcase messages <- event:\n\t\t\t\tcase <-ctx.Done():\n\t\t\t\t\terrs <- ctx.Err()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}()\n\t<-started\n\n\treturn messages, errs\n}\n\nfunc buildEventsQueryParams(cliVersion string, options types.EventsOptions) (url.Values, error) {\n\tquery := url.Values{}\n\tref := time.Now()\n\n\tif options.Since != \"\" {\n\t\tts, err := timetypes.GetTimestamp(options.Since, ref)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tquery.Set(\"since\", ts)\n\t}\n\n\tif options.Until != \"\" {\n\t\tts, err := timetypes.GetTimestamp(options.Until, ref)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tquery.Set(\"until\", ts)\n\t}\n\n\tif options.Filters.Len() > 0 {\n\t\t//nolint:staticcheck // ignore SA1019 for old code\n\t\tfilterJSON, err := filters.ToParamWithVersion(cliVersion, options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\treturn query, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/hijack.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bufio\"\n\t\"context\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/versions\"\n\t\"github.com/pkg/errors\"\n\t\"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n)\n\n// postHijacked sends a POST request and hijacks the connection.\nfunc (cli *Client) postHijacked(ctx context.Context, path string, query url.Values, body interface{}, headers map[string][]string) (types.HijackedResponse, error) {\n\tbodyEncoded, err := encodeData(body)\n\tif err != nil {\n\t\treturn types.HijackedResponse{}, err\n\t}\n\treq, err := cli.buildRequest(ctx, http.MethodPost, cli.getAPIPath(ctx, path, query), bodyEncoded, headers)\n\tif err != nil {\n\t\treturn types.HijackedResponse{}, err\n\t}\n\tconn, mediaType, err := cli.setupHijackConn(req, \"tcp\")\n\tif err != nil {\n\t\treturn types.HijackedResponse{}, err\n\t}\n\n\treturn types.NewHijackedResponse(conn, mediaType), err\n}\n\n// DialHijack returns a hijacked connection with negotiated protocol proto.\nfunc (cli *Client) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) {\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq = cli.addHeaders(req, meta)\n\n\tconn, _, err := cli.setupHijackConn(req, proto)\n\treturn conn, err\n}\n\nfunc (cli *Client) setupHijackConn(req *http.Request, proto string) (_ net.Conn, _ string, retErr error) {\n\tctx := req.Context()\n\treq.Header.Set(\"Connection\", \"Upgrade\")\n\treq.Header.Set(\"Upgrade\", proto)\n\n\tdialer := cli.Dialer()\n\tconn, err := dialer(ctx)\n\tif err != nil {\n\t\treturn nil, \"\", errors.Wrap(err, \"cannot connect to the Docker daemon. Is 'docker daemon' running on this host?\")\n\t}\n\tdefer func() {\n\t\tif retErr != nil {\n\t\t\tconn.Close()\n\t\t}\n\t}()\n\n\t// When we set up a TCP connection for hijack, there could be long periods\n\t// of inactivity (a long running command with no output) that in certain\n\t// network setups may cause ECONNTIMEOUT, leaving the client in an unknown\n\t// state. Setting TCP KeepAlive on the socket connection will prohibit\n\t// ECONNTIMEOUT unless the socket connection truly is broken\n\tif tcpConn, ok := conn.(*net.TCPConn); ok {\n\t\t_ = tcpConn.SetKeepAlive(true)\n\t\t_ = tcpConn.SetKeepAlivePeriod(30 * time.Second)\n\t}\n\n\thc := &hijackedConn{conn, bufio.NewReader(conn)}\n\n\t// Server hijacks the connection, error 'connection closed' expected\n\tresp, err := otelhttp.NewTransport(hc).RoundTrip(req)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tif resp.StatusCode != http.StatusSwitchingProtocols {\n\t\t_ = resp.Body.Close()\n\t\treturn nil, \"\", fmt.Errorf(\"unable to upgrade to %s, received %d\", proto, resp.StatusCode)\n\t}\n\n\tif hc.r.Buffered() > 0 {\n\t\t// If there is buffered content, wrap the connection.  We return an\n\t\t// object that implements CloseWrite if the underlying connection\n\t\t// implements it.\n\t\tif _, ok := hc.Conn.(types.CloseWriter); ok {\n\t\t\tconn = &hijackedConnCloseWriter{hc}\n\t\t} else {\n\t\t\tconn = hc\n\t\t}\n\t} else {\n\t\thc.r.Reset(nil)\n\t}\n\n\tvar mediaType string\n\tif versions.GreaterThanOrEqualTo(cli.ClientVersion(), \"1.42\") {\n\t\t// Prior to 1.42, Content-Type is always set to raw-stream and not relevant\n\t\tmediaType = resp.Header.Get(\"Content-Type\")\n\t}\n\n\treturn conn, mediaType, nil\n}\n\n// hijackedConn wraps a net.Conn and is returned by setupHijackConn in the case\n// that a) there was already buffered data in the http layer when Hijack() was\n// called, and b) the underlying net.Conn does *not* implement CloseWrite().\n// hijackedConn does not implement CloseWrite() either.\ntype hijackedConn struct {\n\tnet.Conn\n\tr *bufio.Reader\n}\n\nfunc (c *hijackedConn) RoundTrip(req *http.Request) (*http.Response, error) {\n\tif err := req.Write(c.Conn); err != nil {\n\t\treturn nil, err\n\t}\n\treturn http.ReadResponse(c.r, req)\n}\n\nfunc (c *hijackedConn) Read(b []byte) (int, error) {\n\treturn c.r.Read(b)\n}\n\n// hijackedConnCloseWriter is a hijackedConn which additionally implements\n// CloseWrite().  It is returned by setupHijackConn in the case that a) there\n// was already buffered data in the http layer when Hijack() was called, and b)\n// the underlying net.Conn *does* implement CloseWrite().\ntype hijackedConnCloseWriter struct {\n\t*hijackedConn\n}\n\nvar _ types.CloseWriter = &hijackedConnCloseWriter{}\n\nfunc (c *hijackedConnCloseWriter) CloseWrite() error {\n\tconn := c.Conn.(types.CloseWriter)\n\treturn conn.CloseWrite()\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_build.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/container\"\n)\n\n// ImageBuild sends a request to the daemon to build images.\n// The Body in the response implements an io.ReadCloser and it's up to the caller to\n// close it.\nfunc (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {\n\tquery, err := cli.imageBuildOptionsToQuery(ctx, options)\n\tif err != nil {\n\t\treturn types.ImageBuildResponse{}, err\n\t}\n\n\tbuf, err := json.Marshal(options.AuthConfigs)\n\tif err != nil {\n\t\treturn types.ImageBuildResponse{}, err\n\t}\n\n\theaders := http.Header{}\n\theaders.Add(\"X-Registry-Config\", base64.URLEncoding.EncodeToString(buf))\n\theaders.Set(\"Content-Type\", \"application/x-tar\")\n\n\tserverResp, err := cli.postRaw(ctx, \"/build\", query, buildContext, headers)\n\tif err != nil {\n\t\treturn types.ImageBuildResponse{}, err\n\t}\n\n\treturn types.ImageBuildResponse{\n\t\tBody:   serverResp.body,\n\t\tOSType: getDockerOS(serverResp.header.Get(\"Server\")),\n\t}, nil\n}\n\nfunc (cli *Client) imageBuildOptionsToQuery(ctx context.Context, options types.ImageBuildOptions) (url.Values, error) {\n\tquery := url.Values{\n\t\t\"t\":           options.Tags,\n\t\t\"securityopt\": options.SecurityOpt,\n\t\t\"extrahosts\":  options.ExtraHosts,\n\t}\n\tif options.SuppressOutput {\n\t\tquery.Set(\"q\", \"1\")\n\t}\n\tif options.RemoteContext != \"\" {\n\t\tquery.Set(\"remote\", options.RemoteContext)\n\t}\n\tif options.NoCache {\n\t\tquery.Set(\"nocache\", \"1\")\n\t}\n\tif options.Remove {\n\t\tquery.Set(\"rm\", \"1\")\n\t} else {\n\t\tquery.Set(\"rm\", \"0\")\n\t}\n\n\tif options.ForceRemove {\n\t\tquery.Set(\"forcerm\", \"1\")\n\t}\n\n\tif options.PullParent {\n\t\tquery.Set(\"pull\", \"1\")\n\t}\n\n\tif options.Squash {\n\t\tif err := cli.NewVersionError(ctx, \"1.25\", \"squash\"); err != nil {\n\t\t\treturn query, err\n\t\t}\n\t\tquery.Set(\"squash\", \"1\")\n\t}\n\n\tif !container.Isolation.IsDefault(options.Isolation) {\n\t\tquery.Set(\"isolation\", string(options.Isolation))\n\t}\n\n\tquery.Set(\"cpusetcpus\", options.CPUSetCPUs)\n\tquery.Set(\"networkmode\", options.NetworkMode)\n\tquery.Set(\"cpusetmems\", options.CPUSetMems)\n\tquery.Set(\"cpushares\", strconv.FormatInt(options.CPUShares, 10))\n\tquery.Set(\"cpuquota\", strconv.FormatInt(options.CPUQuota, 10))\n\tquery.Set(\"cpuperiod\", strconv.FormatInt(options.CPUPeriod, 10))\n\tquery.Set(\"memory\", strconv.FormatInt(options.Memory, 10))\n\tquery.Set(\"memswap\", strconv.FormatInt(options.MemorySwap, 10))\n\tquery.Set(\"cgroupparent\", options.CgroupParent)\n\tquery.Set(\"shmsize\", strconv.FormatInt(options.ShmSize, 10))\n\tquery.Set(\"dockerfile\", options.Dockerfile)\n\tquery.Set(\"target\", options.Target)\n\n\tulimitsJSON, err := json.Marshal(options.Ulimits)\n\tif err != nil {\n\t\treturn query, err\n\t}\n\tquery.Set(\"ulimits\", string(ulimitsJSON))\n\n\tbuildArgsJSON, err := json.Marshal(options.BuildArgs)\n\tif err != nil {\n\t\treturn query, err\n\t}\n\tquery.Set(\"buildargs\", string(buildArgsJSON))\n\n\tlabelsJSON, err := json.Marshal(options.Labels)\n\tif err != nil {\n\t\treturn query, err\n\t}\n\tquery.Set(\"labels\", string(labelsJSON))\n\n\tcacheFromJSON, err := json.Marshal(options.CacheFrom)\n\tif err != nil {\n\t\treturn query, err\n\t}\n\tquery.Set(\"cachefrom\", string(cacheFromJSON))\n\tif options.SessionID != \"\" {\n\t\tquery.Set(\"session\", options.SessionID)\n\t}\n\tif options.Platform != \"\" {\n\t\tif err := cli.NewVersionError(ctx, \"1.32\", \"platform\"); err != nil {\n\t\t\treturn query, err\n\t\t}\n\t\tquery.Set(\"platform\", strings.ToLower(options.Platform))\n\t}\n\tif options.BuildID != \"\" {\n\t\tquery.Set(\"buildid\", options.BuildID)\n\t}\n\tquery.Set(\"version\", string(options.Version))\n\n\tif options.Outputs != nil {\n\t\toutputsJSON, err := json.Marshal(options.Outputs)\n\t\tif err != nil {\n\t\t\treturn query, err\n\t\t}\n\t\tquery.Set(\"outputs\", string(outputsJSON))\n\t}\n\treturn query, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/registry\"\n)\n\n// ImageCreate creates a new image based on the parent options.\n// It returns the JSON content in the response body.\nfunc (cli *Client) ImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error) {\n\tref, err := reference.ParseNormalizedNamed(parentReference)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tquery := url.Values{}\n\tquery.Set(\"fromImage\", reference.FamiliarName(ref))\n\tquery.Set(\"tag\", getAPITagFromNamedRef(ref))\n\tif options.Platform != \"\" {\n\t\tquery.Set(\"platform\", strings.ToLower(options.Platform))\n\t}\n\tresp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n\nfunc (cli *Client) tryImageCreate(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {\n\treturn cli.post(ctx, \"/images/create\", query, nil, http.Header{\n\t\tregistry.AuthHeader: {registryAuth},\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_history.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/image\"\n)\n\n// ImageHistory returns the changes in an image in history format.\nfunc (cli *Client) ImageHistory(ctx context.Context, imageID string) ([]image.HistoryResponseItem, error) {\n\tvar history []image.HistoryResponseItem\n\tserverResp, err := cli.get(ctx, \"/images/\"+imageID+\"/history\", url.Values{}, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn history, err\n\t}\n\n\terr = json.NewDecoder(serverResp.body).Decode(&history)\n\treturn history, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_import.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n)\n\n// ImageImport creates a new image based on the source options.\n// It returns the JSON content in the response body.\nfunc (cli *Client) ImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {\n\tif ref != \"\" {\n\t\t// Check if the given image name can be resolved\n\t\tif _, err := reference.ParseNormalizedNamed(ref); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tquery := url.Values{}\n\tquery.Set(\"fromSrc\", source.SourceName)\n\tquery.Set(\"repo\", ref)\n\tquery.Set(\"tag\", options.Tag)\n\tquery.Set(\"message\", options.Message)\n\tif options.Platform != \"\" {\n\t\tquery.Set(\"platform\", strings.ToLower(options.Platform))\n\t}\n\tfor _, change := range options.Changes {\n\t\tquery.Add(\"changes\", change)\n\t}\n\n\tresp, err := cli.postRaw(ctx, \"/images/create\", query, source.Source, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// ImageInspectWithRaw returns the image information and its raw representation.\nfunc (cli *Client) ImageInspectWithRaw(ctx context.Context, imageID string) (types.ImageInspect, []byte, error) {\n\tif imageID == \"\" {\n\t\treturn types.ImageInspect{}, nil, objectNotFoundError{object: \"image\", id: imageID}\n\t}\n\tserverResp, err := cli.get(ctx, \"/images/\"+imageID+\"/json\", nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn types.ImageInspect{}, nil, err\n\t}\n\n\tbody, err := io.ReadAll(serverResp.body)\n\tif err != nil {\n\t\treturn types.ImageInspect{}, nil, err\n\t}\n\n\tvar response types.ImageInspect\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&response)\n\treturn response, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// ImageList returns a list of images in the docker host.\nfunc (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions) ([]image.Summary, error) {\n\tvar images []image.Summary\n\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\treturn images, err\n\t}\n\n\tquery := url.Values{}\n\n\toptionFilters := options.Filters\n\treferenceFilters := optionFilters.Get(\"reference\")\n\tif versions.LessThan(cli.version, \"1.25\") && len(referenceFilters) > 0 {\n\t\tquery.Set(\"filter\", referenceFilters[0])\n\t\tfor _, filterValue := range referenceFilters {\n\t\t\toptionFilters.Del(\"reference\", filterValue)\n\t\t}\n\t}\n\tif optionFilters.Len() > 0 {\n\t\t//nolint:staticcheck // ignore SA1019 for old code\n\t\tfilterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters)\n\t\tif err != nil {\n\t\t\treturn images, err\n\t\t}\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\tif options.All {\n\t\tquery.Set(\"all\", \"1\")\n\t}\n\tif options.SharedSize && versions.GreaterThanOrEqualTo(cli.version, \"1.42\") {\n\t\tquery.Set(\"shared-size\", \"1\")\n\t}\n\n\tserverResp, err := cli.get(ctx, \"/images/json\", query, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn images, err\n\t}\n\n\terr = json.NewDecoder(serverResp.body).Decode(&images)\n\treturn images, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_load.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// ImageLoad loads an image in the docker host from the client host.\n// It's up to the caller to close the io.ReadCloser in the\n// ImageLoadResponse returned by this function.\nfunc (cli *Client) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error) {\n\tv := url.Values{}\n\tv.Set(\"quiet\", \"0\")\n\tif quiet {\n\t\tv.Set(\"quiet\", \"1\")\n\t}\n\tresp, err := cli.postRaw(ctx, \"/images/load\", v, input, http.Header{\n\t\t\"Content-Type\": {\"application/x-tar\"},\n\t})\n\tif err != nil {\n\t\treturn types.ImageLoadResponse{}, err\n\t}\n\treturn types.ImageLoadResponse{\n\t\tBody: resp.body,\n\t\tJSON: resp.header.Get(\"Content-Type\") == \"application/json\",\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_prune.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\n// ImagesPrune requests the daemon to delete unused data\nfunc (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (types.ImagesPruneReport, error) {\n\tvar report types.ImagesPruneReport\n\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"image prune\"); err != nil {\n\t\treturn report, err\n\t}\n\n\tquery, err := getFiltersQuery(pruneFilters)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tserverResp, err := cli.post(ctx, \"/images/prune\", query, nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tif err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {\n\t\treturn report, fmt.Errorf(\"Error retrieving disk usage: %v\", err)\n\t}\n\n\treturn report, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_pull.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/errdefs\"\n)\n\n// ImagePull requests the docker host to pull an image from a remote registry.\n// It executes the privileged function if the operation is unauthorized\n// and it tries one more time.\n// It's up to the caller to handle the io.ReadCloser and close it properly.\n//\n// FIXME(vdemeester): there is currently used in a few way in docker/docker\n// - if not in trusted content, ref is used to pass the whole reference, and tag is empty\n// - if in trusted content, ref is used to pass the reference name, and tag for the digest\nfunc (cli *Client) ImagePull(ctx context.Context, refStr string, options types.ImagePullOptions) (io.ReadCloser, error) {\n\tref, err := reference.ParseNormalizedNamed(refStr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tquery := url.Values{}\n\tquery.Set(\"fromImage\", reference.FamiliarName(ref))\n\tif !options.All {\n\t\tquery.Set(\"tag\", getAPITagFromNamedRef(ref))\n\t}\n\tif options.Platform != \"\" {\n\t\tquery.Set(\"platform\", strings.ToLower(options.Platform))\n\t}\n\n\tresp, err := cli.tryImageCreate(ctx, query, options.RegistryAuth)\n\tif errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {\n\t\tnewAuthHeader, privilegeErr := options.PrivilegeFunc()\n\t\tif privilegeErr != nil {\n\t\t\treturn nil, privilegeErr\n\t\t}\n\t\tresp, err = cli.tryImageCreate(ctx, query, newAuthHeader)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n\n// getAPITagFromNamedRef returns a tag from the specified reference.\n// This function is necessary as long as the docker \"server\" api expects\n// digests to be sent as tags and makes a distinction between the name\n// and tag/digest part of a reference.\nfunc getAPITagFromNamedRef(ref reference.Named) string {\n\tif digested, ok := ref.(reference.Digested); ok {\n\t\treturn digested.Digest().String()\n\t}\n\tref = reference.TagNameOnly(ref)\n\tif tagged, ok := ref.(reference.Tagged); ok {\n\t\treturn tagged.Tag()\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_push.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/errdefs\"\n)\n\n// ImagePush requests the docker host to push an image to a remote registry.\n// It executes the privileged function if the operation is unauthorized\n// and it tries one more time.\n// It's up to the caller to handle the io.ReadCloser and close it properly.\nfunc (cli *Client) ImagePush(ctx context.Context, image string, options types.ImagePushOptions) (io.ReadCloser, error) {\n\tref, err := reference.ParseNormalizedNamed(image)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif _, isCanonical := ref.(reference.Canonical); isCanonical {\n\t\treturn nil, errors.New(\"cannot push a digest reference\")\n\t}\n\n\tname := reference.FamiliarName(ref)\n\tquery := url.Values{}\n\tif !options.All {\n\t\tref = reference.TagNameOnly(ref)\n\t\tif tagged, ok := ref.(reference.Tagged); ok {\n\t\t\tquery.Set(\"tag\", tagged.Tag())\n\t\t}\n\t}\n\n\tresp, err := cli.tryImagePush(ctx, name, query, options.RegistryAuth)\n\tif errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {\n\t\tnewAuthHeader, privilegeErr := options.PrivilegeFunc()\n\t\tif privilegeErr != nil {\n\t\t\treturn nil, privilegeErr\n\t\t}\n\t\tresp, err = cli.tryImagePush(ctx, name, query, newAuthHeader)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n\nfunc (cli *Client) tryImagePush(ctx context.Context, imageID string, query url.Values, registryAuth string) (serverResponse, error) {\n\treturn cli.post(ctx, \"/images/\"+imageID+\"/push\", query, nil, http.Header{\n\t\tregistry.AuthHeader: {registryAuth},\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/image\"\n)\n\n// ImageRemove removes an image from the docker host.\nfunc (cli *Client) ImageRemove(ctx context.Context, imageID string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error) {\n\tquery := url.Values{}\n\n\tif options.Force {\n\t\tquery.Set(\"force\", \"1\")\n\t}\n\tif !options.PruneChildren {\n\t\tquery.Set(\"noprune\", \"1\")\n\t}\n\n\tvar dels []image.DeleteResponse\n\tresp, err := cli.delete(ctx, \"/images/\"+imageID, query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn dels, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&dels)\n\treturn dels, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_save.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/url\"\n)\n\n// ImageSave retrieves one or more images from the docker host as an io.ReadCloser.\n// It's up to the caller to store the images and close the stream.\nfunc (cli *Client) ImageSave(ctx context.Context, imageIDs []string) (io.ReadCloser, error) {\n\tquery := url.Values{\n\t\t\"names\": imageIDs,\n\t}\n\n\tresp, err := cli.get(ctx, \"/images/get\", query, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_search.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/errdefs\"\n)\n\n// ImageSearch makes the docker host search by a term in a remote registry.\n// The list of results is not sorted in any fashion.\nfunc (cli *Client) ImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error) {\n\tvar results []registry.SearchResult\n\tquery := url.Values{}\n\tquery.Set(\"term\", term)\n\tif options.Limit > 0 {\n\t\tquery.Set(\"limit\", strconv.Itoa(options.Limit))\n\t}\n\n\tif options.Filters.Len() > 0 {\n\t\tfilterJSON, err := filters.ToJSON(options.Filters)\n\t\tif err != nil {\n\t\t\treturn results, err\n\t\t}\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\tresp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)\n\tdefer ensureReaderClosed(resp)\n\tif errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {\n\t\tnewAuthHeader, privilegeErr := options.PrivilegeFunc()\n\t\tif privilegeErr != nil {\n\t\t\treturn results, privilegeErr\n\t\t}\n\t\tresp, err = cli.tryImageSearch(ctx, query, newAuthHeader)\n\t}\n\tif err != nil {\n\t\treturn results, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&results)\n\treturn results, err\n}\n\nfunc (cli *Client) tryImageSearch(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {\n\treturn cli.get(ctx, \"/images/search\", query, http.Header{\n\t\tregistry.AuthHeader: {registryAuth},\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/image_tag.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/pkg/errors\"\n)\n\n// ImageTag tags an image in the docker host\nfunc (cli *Client) ImageTag(ctx context.Context, source, target string) error {\n\tif _, err := reference.ParseAnyReference(source); err != nil {\n\t\treturn errors.Wrapf(err, \"Error parsing reference: %q is not a valid repository/tag\", source)\n\t}\n\n\tref, err := reference.ParseNormalizedNamed(target)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"Error parsing reference: %q is not a valid repository/tag\", target)\n\t}\n\n\tif _, isCanonical := ref.(reference.Canonical); isCanonical {\n\t\treturn errors.New(\"refusing to create a tag with a digest reference\")\n\t}\n\n\tref = reference.TagNameOnly(ref)\n\n\tquery := url.Values{}\n\tquery.Set(\"repo\", reference.FamiliarName(ref))\n\tif tagged, ok := ref.(reference.Tagged); ok {\n\t\tquery.Set(\"tag\", tagged.Tag())\n\t}\n\n\tresp, err := cli.post(ctx, \"/images/\"+source+\"/tag\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/info.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/system\"\n)\n\n// Info returns information about the docker server.\nfunc (cli *Client) Info(ctx context.Context) (system.Info, error) {\n\tvar info system.Info\n\tserverResp, err := cli.get(ctx, \"/info\", url.Values{}, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn info, err\n\t}\n\n\tif err := json.NewDecoder(serverResp.body).Decode(&info); err != nil {\n\t\treturn info, fmt.Errorf(\"Error reading remote info: %v\", err)\n\t}\n\n\treturn info, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/interface.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\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/events\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/api/types/network\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/api/types/swarm\"\n\t\"github.com/docker/docker/api/types/system\"\n\t\"github.com/docker/docker/api/types/volume\"\n\tocispec \"github.com/opencontainers/image-spec/specs-go/v1\"\n)\n\n// CommonAPIClient is the common methods between stable and experimental versions of APIClient.\ntype CommonAPIClient interface {\n\tConfigAPIClient\n\tContainerAPIClient\n\tDistributionAPIClient\n\tImageAPIClient\n\tNodeAPIClient\n\tNetworkAPIClient\n\tPluginAPIClient\n\tServiceAPIClient\n\tSwarmAPIClient\n\tSecretAPIClient\n\tSystemAPIClient\n\tVolumeAPIClient\n\tClientVersion() string\n\tDaemonHost() string\n\tHTTPClient() *http.Client\n\tServerVersion(ctx context.Context) (types.Version, error)\n\tNegotiateAPIVersion(ctx context.Context)\n\tNegotiateAPIVersionPing(types.Ping)\n\tDialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error)\n\tDialer() func(context.Context) (net.Conn, error)\n\tClose() error\n}\n\n// ContainerAPIClient defines API client methods for the containers\ntype ContainerAPIClient interface {\n\tContainerAttach(ctx context.Context, container string, options container.AttachOptions) (types.HijackedResponse, error)\n\tContainerCommit(ctx context.Context, container string, options container.CommitOptions) (types.IDResponse, error)\n\tContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, containerName string) (container.CreateResponse, error)\n\tContainerDiff(ctx context.Context, container string) ([]container.FilesystemChange, error)\n\tContainerExecAttach(ctx context.Context, execID string, config types.ExecStartCheck) (types.HijackedResponse, error)\n\tContainerExecCreate(ctx context.Context, container string, config types.ExecConfig) (types.IDResponse, error)\n\tContainerExecInspect(ctx context.Context, execID string) (types.ContainerExecInspect, error)\n\tContainerExecResize(ctx context.Context, execID string, options container.ResizeOptions) error\n\tContainerExecStart(ctx context.Context, execID string, config types.ExecStartCheck) error\n\tContainerExport(ctx context.Context, container string) (io.ReadCloser, error)\n\tContainerInspect(ctx context.Context, container string) (types.ContainerJSON, error)\n\tContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (types.ContainerJSON, []byte, error)\n\tContainerKill(ctx context.Context, container, signal string) error\n\tContainerList(ctx context.Context, options container.ListOptions) ([]types.Container, error)\n\tContainerLogs(ctx context.Context, container string, options container.LogsOptions) (io.ReadCloser, error)\n\tContainerPause(ctx context.Context, container string) error\n\tContainerRemove(ctx context.Context, container string, options container.RemoveOptions) error\n\tContainerRename(ctx context.Context, container, newContainerName string) error\n\tContainerResize(ctx context.Context, container string, options container.ResizeOptions) error\n\tContainerRestart(ctx context.Context, container string, options container.StopOptions) error\n\tContainerStatPath(ctx context.Context, container, path string) (types.ContainerPathStat, error)\n\tContainerStats(ctx context.Context, container string, stream bool) (types.ContainerStats, error)\n\tContainerStatsOneShot(ctx context.Context, container string) (types.ContainerStats, error)\n\tContainerStart(ctx context.Context, container string, options container.StartOptions) error\n\tContainerStop(ctx context.Context, container string, options container.StopOptions) error\n\tContainerTop(ctx context.Context, container string, arguments []string) (container.ContainerTopOKBody, error)\n\tContainerUnpause(ctx context.Context, container string) error\n\tContainerUpdate(ctx context.Context, container string, updateConfig container.UpdateConfig) (container.ContainerUpdateOKBody, error)\n\tContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)\n\tCopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, types.ContainerPathStat, error)\n\tCopyToContainer(ctx context.Context, container, path string, content io.Reader, options types.CopyToContainerOptions) error\n\tContainersPrune(ctx context.Context, pruneFilters filters.Args) (types.ContainersPruneReport, error)\n}\n\n// DistributionAPIClient defines API client methods for the registry\ntype DistributionAPIClient interface {\n\tDistributionInspect(ctx context.Context, image, encodedRegistryAuth string) (registry.DistributionInspect, error)\n}\n\n// ImageAPIClient defines API client methods for the images\ntype ImageAPIClient interface {\n\tImageBuild(ctx context.Context, context io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error)\n\tBuildCachePrune(ctx context.Context, opts types.BuildCachePruneOptions) (*types.BuildCachePruneReport, error)\n\tBuildCancel(ctx context.Context, id string) error\n\tImageCreate(ctx context.Context, parentReference string, options types.ImageCreateOptions) (io.ReadCloser, error)\n\tImageHistory(ctx context.Context, image string) ([]image.HistoryResponseItem, error)\n\tImageImport(ctx context.Context, source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error)\n\tImageInspectWithRaw(ctx context.Context, image string) (types.ImageInspect, []byte, error)\n\tImageList(ctx context.Context, options types.ImageListOptions) ([]image.Summary, error)\n\tImageLoad(ctx context.Context, input io.Reader, quiet bool) (types.ImageLoadResponse, error)\n\tImagePull(ctx context.Context, ref string, options types.ImagePullOptions) (io.ReadCloser, error)\n\tImagePush(ctx context.Context, ref string, options types.ImagePushOptions) (io.ReadCloser, error)\n\tImageRemove(ctx context.Context, image string, options types.ImageRemoveOptions) ([]image.DeleteResponse, error)\n\tImageSearch(ctx context.Context, term string, options types.ImageSearchOptions) ([]registry.SearchResult, error)\n\tImageSave(ctx context.Context, images []string) (io.ReadCloser, error)\n\tImageTag(ctx context.Context, image, ref string) error\n\tImagesPrune(ctx context.Context, pruneFilter filters.Args) (types.ImagesPruneReport, error)\n}\n\n// NetworkAPIClient defines API client methods for the networks\ntype NetworkAPIClient interface {\n\tNetworkConnect(ctx context.Context, network, container string, config *network.EndpointSettings) error\n\tNetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error)\n\tNetworkDisconnect(ctx context.Context, network, container string, force bool) error\n\tNetworkInspect(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, error)\n\tNetworkInspectWithRaw(ctx context.Context, network string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error)\n\tNetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error)\n\tNetworkRemove(ctx context.Context, network string) error\n\tNetworksPrune(ctx context.Context, pruneFilter filters.Args) (types.NetworksPruneReport, error)\n}\n\n// NodeAPIClient defines API client methods for the nodes\ntype NodeAPIClient interface {\n\tNodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error)\n\tNodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error)\n\tNodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error\n\tNodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error\n}\n\n// PluginAPIClient defines API client methods for the plugins\ntype PluginAPIClient interface {\n\tPluginList(ctx context.Context, filter filters.Args) (types.PluginsListResponse, error)\n\tPluginRemove(ctx context.Context, name string, options types.PluginRemoveOptions) error\n\tPluginEnable(ctx context.Context, name string, options types.PluginEnableOptions) error\n\tPluginDisable(ctx context.Context, name string, options types.PluginDisableOptions) error\n\tPluginInstall(ctx context.Context, name string, options types.PluginInstallOptions) (io.ReadCloser, error)\n\tPluginUpgrade(ctx context.Context, name string, options types.PluginInstallOptions) (io.ReadCloser, error)\n\tPluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error)\n\tPluginSet(ctx context.Context, name string, args []string) error\n\tPluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error)\n\tPluginCreate(ctx context.Context, createContext io.Reader, options types.PluginCreateOptions) error\n}\n\n// ServiceAPIClient defines API client methods for the services\ntype ServiceAPIClient interface {\n\tServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (swarm.ServiceCreateResponse, error)\n\tServiceInspectWithRaw(ctx context.Context, serviceID string, options types.ServiceInspectOptions) (swarm.Service, []byte, error)\n\tServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error)\n\tServiceRemove(ctx context.Context, serviceID string) error\n\tServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error)\n\tServiceLogs(ctx context.Context, serviceID string, options container.LogsOptions) (io.ReadCloser, error)\n\tTaskLogs(ctx context.Context, taskID string, options container.LogsOptions) (io.ReadCloser, error)\n\tTaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error)\n\tTaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error)\n}\n\n// SwarmAPIClient defines API client methods for the swarm\ntype SwarmAPIClient interface {\n\tSwarmInit(ctx context.Context, req swarm.InitRequest) (string, error)\n\tSwarmJoin(ctx context.Context, req swarm.JoinRequest) error\n\tSwarmGetUnlockKey(ctx context.Context) (types.SwarmUnlockKeyResponse, error)\n\tSwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error\n\tSwarmLeave(ctx context.Context, force bool) error\n\tSwarmInspect(ctx context.Context) (swarm.Swarm, error)\n\tSwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error\n}\n\n// SystemAPIClient defines API client methods for the system\ntype SystemAPIClient interface {\n\tEvents(ctx context.Context, options types.EventsOptions) (<-chan events.Message, <-chan error)\n\tInfo(ctx context.Context) (system.Info, error)\n\tRegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error)\n\tDiskUsage(ctx context.Context, options types.DiskUsageOptions) (types.DiskUsage, error)\n\tPing(ctx context.Context) (types.Ping, error)\n}\n\n// VolumeAPIClient defines API client methods for the volumes\ntype VolumeAPIClient interface {\n\tVolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error)\n\tVolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error)\n\tVolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error)\n\tVolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error)\n\tVolumeRemove(ctx context.Context, volumeID string, force bool) error\n\tVolumesPrune(ctx context.Context, pruneFilter filters.Args) (types.VolumesPruneReport, error)\n\tVolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error\n}\n\n// SecretAPIClient defines API client methods for secrets\ntype SecretAPIClient interface {\n\tSecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error)\n\tSecretCreate(ctx context.Context, secret swarm.SecretSpec) (types.SecretCreateResponse, error)\n\tSecretRemove(ctx context.Context, id string) error\n\tSecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error)\n\tSecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error\n}\n\n// ConfigAPIClient defines API client methods for configs\ntype ConfigAPIClient interface {\n\tConfigList(ctx context.Context, options types.ConfigListOptions) ([]swarm.Config, error)\n\tConfigCreate(ctx context.Context, config swarm.ConfigSpec) (types.ConfigCreateResponse, error)\n\tConfigRemove(ctx context.Context, id string) error\n\tConfigInspectWithRaw(ctx context.Context, name string) (swarm.Config, []byte, error)\n\tConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/interface_experimental.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types/checkpoint\"\n)\n\ntype apiClientExperimental interface {\n\tCheckpointAPIClient\n}\n\n// CheckpointAPIClient defines API client methods for the checkpoints\ntype CheckpointAPIClient interface {\n\tCheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error\n\tCheckpointDelete(ctx context.Context, container string, options checkpoint.DeleteOptions) error\n\tCheckpointList(ctx context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/interface_stable.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\n// APIClient is an interface that clients that talk with a docker server must implement.\ntype APIClient interface {\n\tCommonAPIClient\n\tapiClientExperimental\n}\n\n// Ensure that Client always implements APIClient.\nvar _ APIClient = &Client{}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/login.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/registry\"\n)\n\n// RegistryLogin authenticates the docker server with a given docker registry.\n// It returns unauthorizedError when the authentication fails.\nfunc (cli *Client) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) {\n\tresp, err := cli.post(ctx, \"/auth\", url.Values{}, auth, nil)\n\tdefer ensureReaderClosed(resp)\n\n\tif err != nil {\n\t\treturn registry.AuthenticateOKBody{}, err\n\t}\n\n\tvar response registry.AuthenticateOKBody\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/network_connect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/network\"\n)\n\n// NetworkConnect connects a container to an existent network in the docker host.\nfunc (cli *Client) NetworkConnect(ctx context.Context, networkID, containerID string, config *network.EndpointSettings) error {\n\tnc := types.NetworkConnect{\n\t\tContainer:      containerID,\n\t\tEndpointConfig: config,\n\t}\n\tresp, err := cli.post(ctx, \"/networks/\"+networkID+\"/connect\", nil, nc, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/network_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// NetworkCreate creates a new network in the docker host.\nfunc (cli *Client) NetworkCreate(ctx context.Context, name string, options types.NetworkCreate) (types.NetworkCreateResponse, error) {\n\tvar response types.NetworkCreateResponse\n\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\treturn response, err\n\t}\n\n\tnetworkCreateRequest := types.NetworkCreateRequest{\n\t\tNetworkCreate: options,\n\t\tName:          name,\n\t}\n\tif versions.LessThan(cli.version, \"1.44\") {\n\t\tnetworkCreateRequest.CheckDuplicate = true //nolint:staticcheck // ignore SA1019: CheckDuplicate is deprecated since API v1.44.\n\t}\n\n\tserverResp, err := cli.post(ctx, \"/networks/create\", nil, networkCreateRequest, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(serverResp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/network_disconnect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// NetworkDisconnect disconnects a container from an existent network in the docker host.\nfunc (cli *Client) NetworkDisconnect(ctx context.Context, networkID, containerID string, force bool) error {\n\tnd := types.NetworkDisconnect{Container: containerID, Force: force}\n\tresp, err := cli.post(ctx, \"/networks/\"+networkID+\"/disconnect\", nil, nd, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/network_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// NetworkInspect returns the information for a specific network configured in the docker host.\nfunc (cli *Client) NetworkInspect(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, error) {\n\tnetworkResource, _, err := cli.NetworkInspectWithRaw(ctx, networkID, options)\n\treturn networkResource, err\n}\n\n// NetworkInspectWithRaw returns the information for a specific network configured in the docker host and its raw representation.\nfunc (cli *Client) NetworkInspectWithRaw(ctx context.Context, networkID string, options types.NetworkInspectOptions) (types.NetworkResource, []byte, error) {\n\tif networkID == \"\" {\n\t\treturn types.NetworkResource{}, nil, objectNotFoundError{object: \"network\", id: networkID}\n\t}\n\tvar (\n\t\tnetworkResource types.NetworkResource\n\t\tresp            serverResponse\n\t\terr             error\n\t)\n\tquery := url.Values{}\n\tif options.Verbose {\n\t\tquery.Set(\"verbose\", \"true\")\n\t}\n\tif options.Scope != \"\" {\n\t\tquery.Set(\"scope\", options.Scope)\n\t}\n\tresp, err = cli.get(ctx, \"/networks/\"+networkID, query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn networkResource, nil, err\n\t}\n\n\tbody, err := io.ReadAll(resp.body)\n\tif err != nil {\n\t\treturn networkResource, nil, err\n\t}\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&networkResource)\n\treturn networkResource, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/network_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\n// NetworkList returns the list of networks configured in the docker host.\nfunc (cli *Client) NetworkList(ctx context.Context, options types.NetworkListOptions) ([]types.NetworkResource, error) {\n\tquery := url.Values{}\n\tif options.Filters.Len() > 0 {\n\t\t//nolint:staticcheck // ignore SA1019 for old code\n\t\tfilterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\tvar networkResources []types.NetworkResource\n\tresp, err := cli.get(ctx, \"/networks\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn networkResources, err\n\t}\n\terr = json.NewDecoder(resp.body).Decode(&networkResources)\n\treturn networkResources, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/network_prune.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\n// NetworksPrune requests the daemon to delete unused networks\nfunc (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (types.NetworksPruneReport, error) {\n\tvar report types.NetworksPruneReport\n\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"network prune\"); err != nil {\n\t\treturn report, err\n\t}\n\n\tquery, err := getFiltersQuery(pruneFilters)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tserverResp, err := cli.post(ctx, \"/networks/prune\", query, nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tif err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {\n\t\treturn report, fmt.Errorf(\"Error retrieving network prune report: %v\", err)\n\t}\n\n\treturn report, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/network_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport \"context\"\n\n// NetworkRemove removes an existent network from the docker host.\nfunc (cli *Client) NetworkRemove(ctx context.Context, networkID string) error {\n\tresp, err := cli.delete(ctx, \"/networks/\"+networkID, nil, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/node_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NodeInspectWithRaw returns the node information.\nfunc (cli *Client) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) {\n\tif nodeID == \"\" {\n\t\treturn swarm.Node{}, nil, objectNotFoundError{object: \"node\", id: nodeID}\n\t}\n\tserverResp, err := cli.get(ctx, \"/nodes/\"+nodeID, nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn swarm.Node{}, nil, err\n\t}\n\n\tbody, err := io.ReadAll(serverResp.body)\n\tif err != nil {\n\t\treturn swarm.Node{}, nil, err\n\t}\n\n\tvar response swarm.Node\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&response)\n\treturn response, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/node_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NodeList returns the list of nodes.\nfunc (cli *Client) NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error) {\n\tquery := url.Values{}\n\n\tif options.Filters.Len() > 0 {\n\t\tfilterJSON, err := filters.ToJSON(options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\tresp, err := cli.get(ctx, \"/nodes\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar nodes []swarm.Node\n\terr = json.NewDecoder(resp.body).Decode(&nodes)\n\treturn nodes, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/node_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// NodeRemove removes a Node.\nfunc (cli *Client) NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error {\n\tquery := url.Values{}\n\tif options.Force {\n\t\tquery.Set(\"force\", \"1\")\n\t}\n\n\tresp, err := cli.delete(ctx, \"/nodes/\"+nodeID, query, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/node_update.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NodeUpdate updates a Node.\nfunc (cli *Client) NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error {\n\tquery := url.Values{}\n\tquery.Set(\"version\", version.String())\n\tresp, err := cli.post(ctx, \"/nodes/\"+nodeID+\"/update\", query, node, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/options.go",
    "content": "package client\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n\n\t\"github.com/docker/go-connections/sockets\"\n\t\"github.com/docker/go-connections/tlsconfig\"\n\t\"github.com/pkg/errors\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Opt is a configuration option to initialize a [Client].\ntype Opt func(*Client) error\n\n// FromEnv configures the client with values from environment variables. It\n// is the equivalent of using the [WithTLSClientConfigFromEnv], [WithHostFromEnv],\n// and [WithVersionFromEnv] options.\n//\n// FromEnv uses the following environment variables:\n//\n//   - DOCKER_HOST ([EnvOverrideHost]) to set the URL to the docker server.\n//   - DOCKER_API_VERSION ([EnvOverrideAPIVersion]) to set the version of the\n//     API to use, leave empty for latest.\n//   - DOCKER_CERT_PATH ([EnvOverrideCertPath]) to specify the directory from\n//     which to load the TLS certificates (\"ca.pem\", \"cert.pem\", \"key.pem').\n//   - DOCKER_TLS_VERIFY ([EnvTLSVerify]) to enable or disable TLS verification\n//     (off by default).\nfunc FromEnv(c *Client) error {\n\tops := []Opt{\n\t\tWithTLSClientConfigFromEnv(),\n\t\tWithHostFromEnv(),\n\t\tWithVersionFromEnv(),\n\t}\n\tfor _, op := range ops {\n\t\tif err := op(c); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// WithDialContext applies the dialer to the client transport. This can be\n// used to set the Timeout and KeepAlive settings of the client. It returns\n// an error if the client does not have a [http.Transport] configured.\nfunc WithDialContext(dialContext func(ctx context.Context, network, addr string) (net.Conn, error)) Opt {\n\treturn func(c *Client) error {\n\t\tif transport, ok := c.client.Transport.(*http.Transport); ok {\n\t\t\ttransport.DialContext = dialContext\n\t\t\treturn nil\n\t\t}\n\t\treturn errors.Errorf(\"cannot apply dialer to transport: %T\", c.client.Transport)\n\t}\n}\n\n// WithHost overrides the client host with the specified one.\nfunc WithHost(host string) Opt {\n\treturn func(c *Client) error {\n\t\thostURL, err := ParseHostURL(host)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tc.host = host\n\t\tc.proto = hostURL.Scheme\n\t\tc.addr = hostURL.Host\n\t\tc.basePath = hostURL.Path\n\t\tif transport, ok := c.client.Transport.(*http.Transport); ok {\n\t\t\treturn sockets.ConfigureTransport(transport, c.proto, c.addr)\n\t\t}\n\t\treturn errors.Errorf(\"cannot apply host to transport: %T\", c.client.Transport)\n\t}\n}\n\n// WithHostFromEnv overrides the client host with the host specified in the\n// DOCKER_HOST ([EnvOverrideHost]) environment variable. If DOCKER_HOST is not set,\n// or set to an empty value, the host is not modified.\nfunc WithHostFromEnv() Opt {\n\treturn func(c *Client) error {\n\t\tif host := os.Getenv(EnvOverrideHost); host != \"\" {\n\t\t\treturn WithHost(host)(c)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithHTTPClient overrides the client's HTTP client with the specified one.\nfunc WithHTTPClient(client *http.Client) Opt {\n\treturn func(c *Client) error {\n\t\tif client != nil {\n\t\t\tc.client = client\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithTimeout configures the time limit for requests made by the HTTP client.\nfunc WithTimeout(timeout time.Duration) Opt {\n\treturn func(c *Client) error {\n\t\tc.client.Timeout = timeout\n\t\treturn nil\n\t}\n}\n\n// WithUserAgent configures the User-Agent header to use for HTTP requests.\n// It overrides any User-Agent set in headers. When set to an empty string,\n// the User-Agent header is removed, and no header is sent.\nfunc WithUserAgent(ua string) Opt {\n\treturn func(c *Client) error {\n\t\tc.userAgent = &ua\n\t\treturn nil\n\t}\n}\n\n// WithHTTPHeaders appends custom HTTP headers to the client's default headers.\n// It does not allow for built-in headers (such as \"User-Agent\", if set) to\n// be overridden. Also see [WithUserAgent].\nfunc WithHTTPHeaders(headers map[string]string) Opt {\n\treturn func(c *Client) error {\n\t\tc.customHTTPHeaders = headers\n\t\treturn nil\n\t}\n}\n\n// WithScheme overrides the client scheme with the specified one.\nfunc WithScheme(scheme string) Opt {\n\treturn func(c *Client) error {\n\t\tc.scheme = scheme\n\t\treturn nil\n\t}\n}\n\n// WithTLSClientConfig applies a TLS config to the client transport.\nfunc WithTLSClientConfig(cacertPath, certPath, keyPath string) Opt {\n\treturn func(c *Client) error {\n\t\ttransport, ok := c.client.Transport.(*http.Transport)\n\t\tif !ok {\n\t\t\treturn errors.Errorf(\"cannot apply tls config to transport: %T\", c.client.Transport)\n\t\t}\n\t\tconfig, err := tlsconfig.Client(tlsconfig.Options{\n\t\t\tCAFile:             cacertPath,\n\t\t\tCertFile:           certPath,\n\t\t\tKeyFile:            keyPath,\n\t\t\tExclusiveRootPools: true,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"failed to create tls config\")\n\t\t}\n\t\ttransport.TLSClientConfig = config\n\t\treturn nil\n\t}\n}\n\n// WithTLSClientConfigFromEnv configures the client's TLS settings with the\n// settings in the DOCKER_CERT_PATH ([EnvOverrideCertPath]) and DOCKER_TLS_VERIFY\n// ([EnvTLSVerify]) environment variables. If DOCKER_CERT_PATH is not set or empty,\n// TLS configuration is not modified.\n//\n// WithTLSClientConfigFromEnv uses the following environment variables:\n//\n//   - DOCKER_CERT_PATH ([EnvOverrideCertPath]) to specify the directory from\n//     which to load the TLS certificates (\"ca.pem\", \"cert.pem\", \"key.pem\").\n//   - DOCKER_TLS_VERIFY ([EnvTLSVerify]) to enable or disable TLS verification\n//     (off by default).\nfunc WithTLSClientConfigFromEnv() Opt {\n\treturn func(c *Client) error {\n\t\tdockerCertPath := os.Getenv(EnvOverrideCertPath)\n\t\tif dockerCertPath == \"\" {\n\t\t\treturn nil\n\t\t}\n\t\ttlsc, err := tlsconfig.Client(tlsconfig.Options{\n\t\t\tCAFile:             filepath.Join(dockerCertPath, \"ca.pem\"),\n\t\t\tCertFile:           filepath.Join(dockerCertPath, \"cert.pem\"),\n\t\t\tKeyFile:            filepath.Join(dockerCertPath, \"key.pem\"),\n\t\t\tInsecureSkipVerify: os.Getenv(EnvTLSVerify) == \"\",\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tc.client = &http.Client{\n\t\t\tTransport:     &http.Transport{TLSClientConfig: tlsc},\n\t\t\tCheckRedirect: CheckRedirect,\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithVersion overrides the client version with the specified one. If an empty\n// version is provided, the value is ignored to allow version negotiation\n// (see [WithAPIVersionNegotiation]).\nfunc WithVersion(version string) Opt {\n\treturn func(c *Client) error {\n\t\tif version != \"\" {\n\t\t\tc.version = version\n\t\t\tc.manualOverride = true\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithVersionFromEnv overrides the client version with the version specified in\n// the DOCKER_API_VERSION ([EnvOverrideAPIVersion]) environment variable.\n// If DOCKER_API_VERSION is not set, or set to an empty value, the version\n// is not modified.\nfunc WithVersionFromEnv() Opt {\n\treturn func(c *Client) error {\n\t\treturn WithVersion(os.Getenv(EnvOverrideAPIVersion))(c)\n\t}\n}\n\n// WithAPIVersionNegotiation enables automatic API version negotiation for the client.\n// With this option enabled, the client automatically negotiates the API version\n// to use when making requests. API version negotiation is performed on the first\n// request; subsequent requests do not re-negotiate.\nfunc WithAPIVersionNegotiation() Opt {\n\treturn func(c *Client) error {\n\t\tc.negotiateVersion = true\n\t\treturn nil\n\t}\n}\n\n// WithTraceProvider sets the trace provider for the client.\n// If this is not set then the global trace provider will be used.\nfunc WithTraceProvider(provider trace.TracerProvider) Opt {\n\treturn func(c *Client) error {\n\t\tc.tp = provider\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/ping.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/swarm\"\n\t\"github.com/docker/docker/errdefs\"\n)\n\n// Ping pings the server and returns the value of the \"Docker-Experimental\",\n// \"Builder-Version\", \"OS-Type\" & \"API-Version\" headers. It attempts to use\n// a HEAD request on the endpoint, but falls back to GET if HEAD is not supported\n// by the daemon. It ignores internal server errors returned by the API, which\n// may be returned if the daemon is in an unhealthy state, but returns errors\n// for other non-success status codes, failing to connect to the API, or failing\n// to parse the API response.\nfunc (cli *Client) Ping(ctx context.Context) (types.Ping, error) {\n\tvar ping types.Ping\n\n\t// Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest()\n\t// because ping requests are used during API version negotiation, so we want\n\t// to hit the non-versioned /_ping endpoint, not /v1.xx/_ping\n\treq, err := cli.buildRequest(ctx, http.MethodHead, path.Join(cli.basePath, \"/_ping\"), nil, nil)\n\tif err != nil {\n\t\treturn ping, err\n\t}\n\tserverResp, err := cli.doRequest(req)\n\tif err == nil {\n\t\tdefer ensureReaderClosed(serverResp)\n\t\tswitch serverResp.statusCode {\n\t\tcase http.StatusOK, http.StatusInternalServerError:\n\t\t\t// Server handled the request, so parse the response\n\t\t\treturn parsePingResponse(cli, serverResp)\n\t\t}\n\t} else if IsErrConnectionFailed(err) {\n\t\treturn ping, err\n\t}\n\n\t// HEAD failed; fallback to GET.\n\treq.Method = http.MethodGet\n\tserverResp, err = cli.doRequest(req)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn ping, err\n\t}\n\treturn parsePingResponse(cli, serverResp)\n}\n\nfunc parsePingResponse(cli *Client, resp serverResponse) (types.Ping, error) {\n\tvar ping types.Ping\n\tif resp.header == nil {\n\t\terr := cli.checkResponseErr(resp)\n\t\treturn ping, errdefs.FromStatusCode(err, resp.statusCode)\n\t}\n\tping.APIVersion = resp.header.Get(\"API-Version\")\n\tping.OSType = resp.header.Get(\"OSType\")\n\tif resp.header.Get(\"Docker-Experimental\") == \"true\" {\n\t\tping.Experimental = true\n\t}\n\tif bv := resp.header.Get(\"Builder-Version\"); bv != \"\" {\n\t\tping.BuilderVersion = types.BuilderVersion(bv)\n\t}\n\tif si := resp.header.Get(\"Swarm\"); si != \"\" {\n\t\tstate, role, _ := strings.Cut(si, \"/\")\n\t\tping.SwarmStatus = &swarm.Status{\n\t\t\tNodeState:        swarm.LocalNodeState(state),\n\t\t\tControlAvailable: role == \"manager\",\n\t\t}\n\t}\n\terr := cli.checkResponseErr(resp)\n\treturn ping, errdefs.FromStatusCode(err, resp.statusCode)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// PluginCreate creates a plugin\nfunc (cli *Client) PluginCreate(ctx context.Context, createContext io.Reader, createOptions types.PluginCreateOptions) error {\n\theaders := http.Header(make(map[string][]string))\n\theaders.Set(\"Content-Type\", \"application/x-tar\")\n\n\tquery := url.Values{}\n\tquery.Set(\"name\", createOptions.RepoName)\n\n\tresp, err := cli.postRaw(ctx, \"/plugins/create\", query, createContext, headers)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_disable.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// PluginDisable disables a plugin\nfunc (cli *Client) PluginDisable(ctx context.Context, name string, options types.PluginDisableOptions) error {\n\tquery := url.Values{}\n\tif options.Force {\n\t\tquery.Set(\"force\", \"1\")\n\t}\n\tresp, err := cli.post(ctx, \"/plugins/\"+name+\"/disable\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_enable.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// PluginEnable enables a plugin\nfunc (cli *Client) PluginEnable(ctx context.Context, name string, options types.PluginEnableOptions) error {\n\tquery := url.Values{}\n\tquery.Set(\"timeout\", strconv.Itoa(options.Timeout))\n\n\tresp, err := cli.post(ctx, \"/plugins/\"+name+\"/enable\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// PluginInspectWithRaw inspects an existing plugin\nfunc (cli *Client) PluginInspectWithRaw(ctx context.Context, name string) (*types.Plugin, []byte, error) {\n\tif name == \"\" {\n\t\treturn nil, nil, objectNotFoundError{object: \"plugin\", id: name}\n\t}\n\tresp, err := cli.get(ctx, \"/plugins/\"+name+\"/json\", nil, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tbody, err := io.ReadAll(resp.body)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tvar p types.Plugin\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&p)\n\treturn &p, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_install.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/errdefs\"\n\t\"github.com/pkg/errors\"\n)\n\n// PluginInstall installs a plugin\nfunc (cli *Client) PluginInstall(ctx context.Context, name string, options types.PluginInstallOptions) (rc io.ReadCloser, err error) {\n\tquery := url.Values{}\n\tif _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {\n\t\treturn nil, errors.Wrap(err, \"invalid remote reference\")\n\t}\n\tquery.Set(\"remote\", options.RemoteRef)\n\n\tprivileges, err := cli.checkPluginPermissions(ctx, query, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// set name for plugin pull, if empty should default to remote reference\n\tquery.Set(\"name\", name)\n\n\tresp, err := cli.tryPluginPull(ctx, query, privileges, options.RegistryAuth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tname = resp.header.Get(\"Docker-Plugin-Name\")\n\n\tpr, pw := io.Pipe()\n\tgo func() { // todo: the client should probably be designed more around the actual api\n\t\t_, err := io.Copy(pw, resp.body)\n\t\tif err != nil {\n\t\t\tpw.CloseWithError(err)\n\t\t\treturn\n\t\t}\n\t\tdefer func() {\n\t\t\tif err != nil {\n\t\t\t\tdelResp, _ := cli.delete(ctx, \"/plugins/\"+name, nil, nil)\n\t\t\t\tensureReaderClosed(delResp)\n\t\t\t}\n\t\t}()\n\t\tif len(options.Args) > 0 {\n\t\t\tif err := cli.PluginSet(ctx, name, options.Args); err != nil {\n\t\t\t\tpw.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif options.Disabled {\n\t\t\tpw.Close()\n\t\t\treturn\n\t\t}\n\n\t\tenableErr := cli.PluginEnable(ctx, name, types.PluginEnableOptions{Timeout: 0})\n\t\tpw.CloseWithError(enableErr)\n\t}()\n\treturn pr, nil\n}\n\nfunc (cli *Client) tryPluginPrivileges(ctx context.Context, query url.Values, registryAuth string) (serverResponse, error) {\n\treturn cli.get(ctx, \"/plugins/privileges\", query, http.Header{\n\t\tregistry.AuthHeader: {registryAuth},\n\t})\n}\n\nfunc (cli *Client) tryPluginPull(ctx context.Context, query url.Values, privileges types.PluginPrivileges, registryAuth string) (serverResponse, error) {\n\treturn cli.post(ctx, \"/plugins/pull\", query, privileges, http.Header{\n\t\tregistry.AuthHeader: {registryAuth},\n\t})\n}\n\nfunc (cli *Client) checkPluginPermissions(ctx context.Context, query url.Values, options types.PluginInstallOptions) (types.PluginPrivileges, error) {\n\tresp, err := cli.tryPluginPrivileges(ctx, query, options.RegistryAuth)\n\tif errdefs.IsUnauthorized(err) && options.PrivilegeFunc != nil {\n\t\t// todo: do inspect before to check existing name before checking privileges\n\t\tnewAuthHeader, privilegeErr := options.PrivilegeFunc()\n\t\tif privilegeErr != nil {\n\t\t\tensureReaderClosed(resp)\n\t\t\treturn nil, privilegeErr\n\t\t}\n\t\toptions.RegistryAuth = newAuthHeader\n\t\tresp, err = cli.tryPluginPrivileges(ctx, query, options.RegistryAuth)\n\t}\n\tif err != nil {\n\t\tensureReaderClosed(resp)\n\t\treturn nil, err\n\t}\n\n\tvar privileges types.PluginPrivileges\n\tif err := json.NewDecoder(resp.body).Decode(&privileges); err != nil {\n\t\tensureReaderClosed(resp)\n\t\treturn nil, err\n\t}\n\tensureReaderClosed(resp)\n\n\tif !options.AcceptAllPermissions && options.AcceptPermissionsFunc != nil && len(privileges) > 0 {\n\t\taccept, err := options.AcceptPermissionsFunc(privileges)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !accept {\n\t\t\treturn nil, errors.Errorf(\"permission denied while installing plugin %s\", options.RemoteRef)\n\t\t}\n\t}\n\treturn privileges, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\n// PluginList returns the installed plugins\nfunc (cli *Client) PluginList(ctx context.Context, filter filters.Args) (types.PluginsListResponse, error) {\n\tvar plugins types.PluginsListResponse\n\tquery := url.Values{}\n\n\tif filter.Len() > 0 {\n\t\t//nolint:staticcheck // ignore SA1019 for old code\n\t\tfilterJSON, err := filters.ToParamWithVersion(cli.version, filter)\n\t\tif err != nil {\n\t\t\treturn plugins, err\n\t\t}\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\tresp, err := cli.get(ctx, \"/plugins\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn plugins, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&plugins)\n\treturn plugins, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_push.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\n\t\"github.com/docker/docker/api/types/registry\"\n)\n\n// PluginPush pushes a plugin to a registry\nfunc (cli *Client) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {\n\tresp, err := cli.post(ctx, \"/plugins/\"+name+\"/push\", nil, nil, http.Header{\n\t\tregistry.AuthHeader: {registryAuth},\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// PluginRemove removes a plugin\nfunc (cli *Client) PluginRemove(ctx context.Context, name string, options types.PluginRemoveOptions) error {\n\tquery := url.Values{}\n\tif options.Force {\n\t\tquery.Set(\"force\", \"1\")\n\t}\n\n\tresp, err := cli.delete(ctx, \"/plugins/\"+name, query, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_set.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n)\n\n// PluginSet modifies settings for an existing plugin\nfunc (cli *Client) PluginSet(ctx context.Context, name string, args []string) error {\n\tresp, err := cli.post(ctx, \"/plugins/\"+name+\"/set\", nil, args, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/plugin_upgrade.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/pkg/errors\"\n)\n\n// PluginUpgrade upgrades a plugin\nfunc (cli *Client) PluginUpgrade(ctx context.Context, name string, options types.PluginInstallOptions) (rc io.ReadCloser, err error) {\n\tif err := cli.NewVersionError(ctx, \"1.26\", \"plugin upgrade\"); err != nil {\n\t\treturn nil, err\n\t}\n\tquery := url.Values{}\n\tif _, err := reference.ParseNormalizedNamed(options.RemoteRef); err != nil {\n\t\treturn nil, errors.Wrap(err, \"invalid remote reference\")\n\t}\n\tquery.Set(\"remote\", options.RemoteRef)\n\n\tprivileges, err := cli.checkPluginPermissions(ctx, query, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := cli.tryPluginUpgrade(ctx, query, privileges, name, options.RegistryAuth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n\nfunc (cli *Client) tryPluginUpgrade(ctx context.Context, query url.Values, privileges types.PluginPrivileges, name, registryAuth string) (serverResponse, error) {\n\treturn cli.post(ctx, \"/plugins/\"+name+\"/upgrade\", query, privileges, http.Header{\n\t\tregistry.AuthHeader: {registryAuth},\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/request.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/versions\"\n\t\"github.com/docker/docker/errdefs\"\n\t\"github.com/pkg/errors\"\n)\n\n// serverResponse is a wrapper for http API responses.\ntype serverResponse struct {\n\tbody       io.ReadCloser\n\theader     http.Header\n\tstatusCode int\n\treqURL     *url.URL\n}\n\n// head sends an http request to the docker API using the method HEAD.\nfunc (cli *Client) head(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {\n\treturn cli.sendRequest(ctx, http.MethodHead, path, query, nil, headers)\n}\n\n// get sends an http request to the docker API using the method GET with a specific Go context.\nfunc (cli *Client) get(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {\n\treturn cli.sendRequest(ctx, http.MethodGet, path, query, nil, headers)\n}\n\n// post sends an http request to the docker API using the method POST with a specific Go context.\nfunc (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) {\n\tbody, headers, err := encodeBody(obj, headers)\n\tif err != nil {\n\t\treturn serverResponse{}, err\n\t}\n\treturn cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)\n}\n\nfunc (cli *Client) postRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {\n\treturn cli.sendRequest(ctx, http.MethodPost, path, query, body, headers)\n}\n\nfunc (cli *Client) put(ctx context.Context, path string, query url.Values, obj interface{}, headers http.Header) (serverResponse, error) {\n\tbody, headers, err := encodeBody(obj, headers)\n\tif err != nil {\n\t\treturn serverResponse{}, err\n\t}\n\treturn cli.putRaw(ctx, path, query, body, headers)\n}\n\n// putRaw sends an http request to the docker API using the method PUT.\nfunc (cli *Client) putRaw(ctx context.Context, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {\n\t// PUT requests are expected to always have a body (apparently)\n\t// so explicitly pass an empty body to sendRequest to signal that\n\t// it should set the Content-Type header if not already present.\n\tif body == nil {\n\t\tbody = http.NoBody\n\t}\n\treturn cli.sendRequest(ctx, http.MethodPut, path, query, body, headers)\n}\n\n// delete sends an http request to the docker API using the method DELETE.\nfunc (cli *Client) delete(ctx context.Context, path string, query url.Values, headers http.Header) (serverResponse, error) {\n\treturn cli.sendRequest(ctx, http.MethodDelete, path, query, nil, headers)\n}\n\nfunc encodeBody(obj interface{}, headers http.Header) (io.Reader, http.Header, error) {\n\tif obj == nil {\n\t\treturn nil, headers, nil\n\t}\n\t// encoding/json encodes a nil pointer as the JSON document `null`,\n\t// irrespective of whether the type implements json.Marshaler or encoding.TextMarshaler.\n\t// That is almost certainly not what the caller intended as the request body.\n\tif reflect.TypeOf(obj).Kind() == reflect.Ptr && reflect.ValueOf(obj).IsNil() {\n\t\treturn nil, headers, nil\n\t}\n\n\tbody, err := encodeData(obj)\n\tif err != nil {\n\t\treturn nil, headers, err\n\t}\n\tif headers == nil {\n\t\theaders = make(map[string][]string)\n\t}\n\theaders[\"Content-Type\"] = []string{\"application/json\"}\n\treturn body, headers, nil\n}\n\nfunc (cli *Client) buildRequest(ctx context.Context, method, path string, body io.Reader, headers http.Header) (*http.Request, error) {\n\treq, err := http.NewRequestWithContext(ctx, method, path, body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq = cli.addHeaders(req, headers)\n\treq.URL.Scheme = cli.scheme\n\treq.URL.Host = cli.addr\n\n\tif cli.proto == \"unix\" || cli.proto == \"npipe\" {\n\t\t// Override host header for non-tcp connections.\n\t\treq.Host = DummyHost\n\t}\n\n\tif body != nil && req.Header.Get(\"Content-Type\") == \"\" {\n\t\treq.Header.Set(\"Content-Type\", \"text/plain\")\n\t}\n\treturn req, nil\n}\n\nfunc (cli *Client) sendRequest(ctx context.Context, method, path string, query url.Values, body io.Reader, headers http.Header) (serverResponse, error) {\n\treq, err := cli.buildRequest(ctx, method, cli.getAPIPath(ctx, path, query), body, headers)\n\tif err != nil {\n\t\treturn serverResponse{}, err\n\t}\n\n\tresp, err := cli.doRequest(req)\n\tswitch {\n\tcase errors.Is(err, context.Canceled):\n\t\treturn serverResponse{}, errdefs.Cancelled(err)\n\tcase errors.Is(err, context.DeadlineExceeded):\n\t\treturn serverResponse{}, errdefs.Deadline(err)\n\tcase err == nil:\n\t\terr = cli.checkResponseErr(resp)\n\t}\n\treturn resp, errdefs.FromStatusCode(err, resp.statusCode)\n}\n\n// FIXME(thaJeztah): Should this actually return a serverResp when a connection error occurred?\nfunc (cli *Client) doRequest(req *http.Request) (serverResponse, error) {\n\tserverResp := serverResponse{statusCode: -1, reqURL: req.URL}\n\n\tresp, err := cli.client.Do(req)\n\tif err != nil {\n\t\tif cli.scheme != \"https\" && strings.Contains(err.Error(), \"malformed HTTP response\") {\n\t\t\treturn serverResp, errConnectionFailed{fmt.Errorf(\"%v.\\n* Are you trying to connect to a TLS-enabled daemon without TLS?\", err)}\n\t\t}\n\n\t\tif cli.scheme == \"https\" && strings.Contains(err.Error(), \"bad certificate\") {\n\t\t\treturn serverResp, errConnectionFailed{errors.Wrap(err, \"the server probably has client authentication (--tlsverify) enabled; check your TLS client certification settings\")}\n\t\t}\n\n\t\t// Don't decorate context sentinel errors; users may be comparing to\n\t\t// them directly.\n\t\tif errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {\n\t\t\treturn serverResp, err\n\t\t}\n\n\t\tif uErr, ok := err.(*url.Error); ok {\n\t\t\tif nErr, ok := uErr.Err.(*net.OpError); ok {\n\t\t\t\tif os.IsPermission(nErr.Err) {\n\t\t\t\t\treturn serverResp, errConnectionFailed{errors.Wrapf(err, \"permission denied while trying to connect to the Docker daemon socket at %v\", cli.host)}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif nErr, ok := err.(net.Error); ok {\n\t\t\t// FIXME(thaJeztah): any net.Error should be considered a connection error (but we should include the original error)?\n\t\t\tif nErr.Timeout() {\n\t\t\t\treturn serverResp, ErrorConnectionFailed(cli.host)\n\t\t\t}\n\t\t\tif strings.Contains(nErr.Error(), \"connection refused\") || strings.Contains(nErr.Error(), \"dial unix\") {\n\t\t\t\treturn serverResp, ErrorConnectionFailed(cli.host)\n\t\t\t}\n\t\t}\n\n\t\t// Although there's not a strongly typed error for this in go-winio,\n\t\t// lots of people are using the default configuration for the docker\n\t\t// daemon on Windows where the daemon is listening on a named pipe\n\t\t// `//./pipe/docker_engine, and the client must be running elevated.\n\t\t// Give users a clue rather than the not-overly useful message\n\t\t// such as `error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.26/info:\n\t\t// open //./pipe/docker_engine: The system cannot find the file specified.`.\n\t\t// Note we can't string compare \"The system cannot find the file specified\" as\n\t\t// this is localised - for example in French the error would be\n\t\t// `open //./pipe/docker_engine: Le fichier spécifié est introuvable.`\n\t\tif strings.Contains(err.Error(), `open //./pipe/docker_engine`) {\n\t\t\t// Checks if client is running with elevated privileges\n\t\t\tif f, elevatedErr := os.Open(\"\\\\\\\\.\\\\PHYSICALDRIVE0\"); elevatedErr == nil {\n\t\t\t\terr = errors.Wrap(err, \"in the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect\")\n\t\t\t} else {\n\t\t\t\tf.Close()\n\t\t\t\terr = errors.Wrap(err, \"this error may indicate that the docker daemon is not running\")\n\t\t\t}\n\t\t}\n\n\t\treturn serverResp, errConnectionFailed{errors.Wrap(err, \"error during connect\")}\n\t}\n\n\tif resp != nil {\n\t\tserverResp.statusCode = resp.StatusCode\n\t\tserverResp.body = resp.Body\n\t\tserverResp.header = resp.Header\n\t}\n\treturn serverResp, nil\n}\n\nfunc (cli *Client) checkResponseErr(serverResp serverResponse) error {\n\tif serverResp.statusCode >= 200 && serverResp.statusCode < 400 {\n\t\treturn nil\n\t}\n\n\tvar body []byte\n\tvar err error\n\tif serverResp.body != nil {\n\t\tbodyMax := 1 * 1024 * 1024 // 1 MiB\n\t\tbodyR := &io.LimitedReader{\n\t\t\tR: serverResp.body,\n\t\t\tN: int64(bodyMax),\n\t\t}\n\t\tbody, err = io.ReadAll(bodyR)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif bodyR.N == 0 {\n\t\t\treturn fmt.Errorf(\"request returned %s with a message (> %d bytes) for API route and version %s, check if the server supports the requested API version\", http.StatusText(serverResp.statusCode), bodyMax, serverResp.reqURL)\n\t\t}\n\t}\n\tif len(body) == 0 {\n\t\treturn fmt.Errorf(\"request returned %s for API route and version %s, check if the server supports the requested API version\", http.StatusText(serverResp.statusCode), serverResp.reqURL)\n\t}\n\n\tvar daemonErr error\n\tif serverResp.header.Get(\"Content-Type\") == \"application/json\" && (cli.version == \"\" || versions.GreaterThan(cli.version, \"1.23\")) {\n\t\tvar errorResponse types.ErrorResponse\n\t\tif err := json.Unmarshal(body, &errorResponse); err != nil {\n\t\t\treturn errors.Wrap(err, \"Error reading JSON\")\n\t\t}\n\t\tdaemonErr = errors.New(strings.TrimSpace(errorResponse.Message))\n\t} else {\n\t\tdaemonErr = errors.New(strings.TrimSpace(string(body)))\n\t}\n\treturn errors.Wrap(daemonErr, \"Error response from daemon\")\n}\n\nfunc (cli *Client) addHeaders(req *http.Request, headers http.Header) *http.Request {\n\t// Add CLI Config's HTTP Headers BEFORE we set the Docker headers\n\t// then the user can't change OUR headers\n\tfor k, v := range cli.customHTTPHeaders {\n\t\tif versions.LessThan(cli.version, \"1.25\") && http.CanonicalHeaderKey(k) == \"User-Agent\" {\n\t\t\tcontinue\n\t\t}\n\t\treq.Header.Set(k, v)\n\t}\n\n\tfor k, v := range headers {\n\t\treq.Header[http.CanonicalHeaderKey(k)] = v\n\t}\n\n\tif cli.userAgent != nil {\n\t\tif *cli.userAgent == \"\" {\n\t\t\treq.Header.Del(\"User-Agent\")\n\t\t} else {\n\t\t\treq.Header.Set(\"User-Agent\", *cli.userAgent)\n\t\t}\n\t}\n\treturn req\n}\n\nfunc encodeData(data interface{}) (*bytes.Buffer, error) {\n\tparams := bytes.NewBuffer(nil)\n\tif data != nil {\n\t\tif err := json.NewEncoder(params).Encode(data); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn params, nil\n}\n\nfunc ensureReaderClosed(response serverResponse) {\n\tif response.body != nil {\n\t\t// Drain up to 512 bytes and close the body to let the Transport reuse the connection\n\t\tio.CopyN(io.Discard, response.body, 512)\n\t\tresponse.body.Close()\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/secret_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SecretCreate creates a new secret.\nfunc (cli *Client) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (types.SecretCreateResponse, error) {\n\tvar response types.SecretCreateResponse\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"secret create\"); err != nil {\n\t\treturn response, err\n\t}\n\tresp, err := cli.post(ctx, \"/secrets/create\", nil, secret, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/secret_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SecretInspectWithRaw returns the secret information with raw data\nfunc (cli *Client) SecretInspectWithRaw(ctx context.Context, id string) (swarm.Secret, []byte, error) {\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"secret inspect\"); err != nil {\n\t\treturn swarm.Secret{}, nil, err\n\t}\n\tif id == \"\" {\n\t\treturn swarm.Secret{}, nil, objectNotFoundError{object: \"secret\", id: id}\n\t}\n\tresp, err := cli.get(ctx, \"/secrets/\"+id, nil, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn swarm.Secret{}, nil, err\n\t}\n\n\tbody, err := io.ReadAll(resp.body)\n\tif err != nil {\n\t\treturn swarm.Secret{}, nil, err\n\t}\n\n\tvar secret swarm.Secret\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&secret)\n\n\treturn secret, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/secret_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SecretList returns the list of secrets.\nfunc (cli *Client) SecretList(ctx context.Context, options types.SecretListOptions) ([]swarm.Secret, error) {\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"secret list\"); err != nil {\n\t\treturn nil, err\n\t}\n\tquery := url.Values{}\n\n\tif options.Filters.Len() > 0 {\n\t\tfilterJSON, err := filters.ToJSON(options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\tresp, err := cli.get(ctx, \"/secrets\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar secrets []swarm.Secret\n\terr = json.NewDecoder(resp.body).Decode(&secrets)\n\treturn secrets, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/secret_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport \"context\"\n\n// SecretRemove removes a secret.\nfunc (cli *Client) SecretRemove(ctx context.Context, id string) error {\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"secret remove\"); err != nil {\n\t\treturn err\n\t}\n\tresp, err := cli.delete(ctx, \"/secrets/\"+id, nil, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/secret_update.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SecretUpdate attempts to update a secret.\nfunc (cli *Client) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"secret update\"); err != nil {\n\t\treturn err\n\t}\n\tquery := url.Values{}\n\tquery.Set(\"version\", version.String())\n\tresp, err := cli.post(ctx, \"/secrets/\"+id+\"/update\", query, secret, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/service_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/distribution/reference\"\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/api/types/swarm\"\n\t\"github.com/docker/docker/api/types/versions\"\n\t\"github.com/opencontainers/go-digest\"\n\t\"github.com/pkg/errors\"\n)\n\n// ServiceCreate creates a new service.\nfunc (cli *Client) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options types.ServiceCreateOptions) (swarm.ServiceCreateResponse, error) {\n\tvar response swarm.ServiceCreateResponse\n\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\treturn response, err\n\t}\n\n\t// Make sure containerSpec is not nil when no runtime is set or the runtime is set to container\n\tif service.TaskTemplate.ContainerSpec == nil && (service.TaskTemplate.Runtime == \"\" || service.TaskTemplate.Runtime == swarm.RuntimeContainer) {\n\t\tservice.TaskTemplate.ContainerSpec = &swarm.ContainerSpec{}\n\t}\n\n\tif err := validateServiceSpec(service); err != nil {\n\t\treturn response, err\n\t}\n\n\t// ensure that the image is tagged\n\tvar resolveWarning string\n\tswitch {\n\tcase service.TaskTemplate.ContainerSpec != nil:\n\t\tif taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != \"\" {\n\t\t\tservice.TaskTemplate.ContainerSpec.Image = taggedImg\n\t\t}\n\t\tif options.QueryRegistry {\n\t\t\tresolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)\n\t\t}\n\tcase service.TaskTemplate.PluginSpec != nil:\n\t\tif taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != \"\" {\n\t\t\tservice.TaskTemplate.PluginSpec.Remote = taggedImg\n\t\t}\n\t\tif options.QueryRegistry {\n\t\t\tresolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)\n\t\t}\n\t}\n\n\theaders := http.Header{}\n\tif versions.LessThan(cli.version, \"1.30\") {\n\t\t// the custom \"version\" header was used by engine API before 20.10\n\t\t// (API 1.30) to switch between client- and server-side lookup of\n\t\t// image digests.\n\t\theaders[\"version\"] = []string{cli.version}\n\t}\n\tif options.EncodedRegistryAuth != \"\" {\n\t\theaders[registry.AuthHeader] = []string{options.EncodedRegistryAuth}\n\t}\n\tresp, err := cli.post(ctx, \"/services/create\", nil, service, headers)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\tif resolveWarning != \"\" {\n\t\tresponse.Warnings = append(response.Warnings, resolveWarning)\n\t}\n\n\treturn response, err\n}\n\nfunc resolveContainerSpecImage(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string {\n\tvar warning string\n\tif img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.ContainerSpec.Image, encodedAuth); err != nil {\n\t\twarning = digestWarning(taskSpec.ContainerSpec.Image)\n\t} else {\n\t\ttaskSpec.ContainerSpec.Image = img\n\t\tif len(imgPlatforms) > 0 {\n\t\t\tif taskSpec.Placement == nil {\n\t\t\t\ttaskSpec.Placement = &swarm.Placement{}\n\t\t\t}\n\t\t\ttaskSpec.Placement.Platforms = imgPlatforms\n\t\t}\n\t}\n\treturn warning\n}\n\nfunc resolvePluginSpecRemote(ctx context.Context, cli DistributionAPIClient, taskSpec *swarm.TaskSpec, encodedAuth string) string {\n\tvar warning string\n\tif img, imgPlatforms, err := imageDigestAndPlatforms(ctx, cli, taskSpec.PluginSpec.Remote, encodedAuth); err != nil {\n\t\twarning = digestWarning(taskSpec.PluginSpec.Remote)\n\t} else {\n\t\ttaskSpec.PluginSpec.Remote = img\n\t\tif len(imgPlatforms) > 0 {\n\t\t\tif taskSpec.Placement == nil {\n\t\t\t\ttaskSpec.Placement = &swarm.Placement{}\n\t\t\t}\n\t\t\ttaskSpec.Placement.Platforms = imgPlatforms\n\t\t}\n\t}\n\treturn warning\n}\n\nfunc imageDigestAndPlatforms(ctx context.Context, cli DistributionAPIClient, image, encodedAuth string) (string, []swarm.Platform, error) {\n\tdistributionInspect, err := cli.DistributionInspect(ctx, image, encodedAuth)\n\tvar platforms []swarm.Platform\n\tif err != nil {\n\t\treturn \"\", nil, err\n\t}\n\n\timageWithDigest := imageWithDigestString(image, distributionInspect.Descriptor.Digest)\n\n\tif len(distributionInspect.Platforms) > 0 {\n\t\tplatforms = make([]swarm.Platform, 0, len(distributionInspect.Platforms))\n\t\tfor _, p := range distributionInspect.Platforms {\n\t\t\t// clear architecture field for arm. This is a temporary patch to address\n\t\t\t// https://github.com/docker/swarmkit/issues/2294. The issue is that while\n\t\t\t// image manifests report \"arm\" as the architecture, the node reports\n\t\t\t// something like \"armv7l\" (includes the variant), which causes arm images\n\t\t\t// to stop working with swarm mode. This patch removes the architecture\n\t\t\t// constraint for arm images to ensure tasks get scheduled.\n\t\t\tarch := p.Architecture\n\t\t\tif strings.ToLower(arch) == \"arm\" {\n\t\t\t\tarch = \"\"\n\t\t\t}\n\t\t\tplatforms = append(platforms, swarm.Platform{\n\t\t\t\tArchitecture: arch,\n\t\t\t\tOS:           p.OS,\n\t\t\t})\n\t\t}\n\t}\n\treturn imageWithDigest, platforms, err\n}\n\n// imageWithDigestString takes an image string and a digest, and updates\n// the image string if it didn't originally contain a digest. It returns\n// image unmodified in other situations.\nfunc imageWithDigestString(image string, dgst digest.Digest) string {\n\tnamedRef, err := reference.ParseNormalizedNamed(image)\n\tif err == nil {\n\t\tif _, isCanonical := namedRef.(reference.Canonical); !isCanonical {\n\t\t\t// ensure that image gets a default tag if none is provided\n\t\t\timg, err := reference.WithDigest(namedRef, dgst)\n\t\t\tif err == nil {\n\t\t\t\treturn reference.FamiliarString(img)\n\t\t\t}\n\t\t}\n\t}\n\treturn image\n}\n\n// imageWithTagString takes an image string, and returns a tagged image\n// string, adding a 'latest' tag if one was not provided. It returns an\n// empty string if a canonical reference was provided\nfunc imageWithTagString(image string) string {\n\tnamedRef, err := reference.ParseNormalizedNamed(image)\n\tif err == nil {\n\t\treturn reference.FamiliarString(reference.TagNameOnly(namedRef))\n\t}\n\treturn \"\"\n}\n\n// digestWarning constructs a formatted warning string using the\n// image name that could not be pinned by digest. The formatting\n// is hardcoded, but could me made smarter in the future\nfunc digestWarning(image string) string {\n\treturn fmt.Sprintf(\"image %s could not be accessed on a registry to record\\nits digest. Each node will access %s independently,\\npossibly leading to different nodes running different\\nversions of the image.\\n\", image, image)\n}\n\nfunc validateServiceSpec(s swarm.ServiceSpec) error {\n\tif s.TaskTemplate.ContainerSpec != nil && s.TaskTemplate.PluginSpec != nil {\n\t\treturn errors.New(\"must not specify both a container spec and a plugin spec in the task template\")\n\t}\n\tif s.TaskTemplate.PluginSpec != nil && s.TaskTemplate.Runtime != swarm.RuntimePlugin {\n\t\treturn errors.New(\"mismatched runtime with plugin spec\")\n\t}\n\tif s.TaskTemplate.ContainerSpec != nil && (s.TaskTemplate.Runtime != \"\" && s.TaskTemplate.Runtime != swarm.RuntimeContainer) {\n\t\treturn errors.New(\"mismatched runtime with container spec\")\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/service_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// ServiceInspectWithRaw returns the service information and the raw data.\nfunc (cli *Client) ServiceInspectWithRaw(ctx context.Context, serviceID string, opts types.ServiceInspectOptions) (swarm.Service, []byte, error) {\n\tif serviceID == \"\" {\n\t\treturn swarm.Service{}, nil, objectNotFoundError{object: \"service\", id: serviceID}\n\t}\n\tquery := url.Values{}\n\tquery.Set(\"insertDefaults\", fmt.Sprintf(\"%v\", opts.InsertDefaults))\n\tserverResp, err := cli.get(ctx, \"/services/\"+serviceID, query, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn swarm.Service{}, nil, err\n\t}\n\n\tbody, err := io.ReadAll(serverResp.body)\n\tif err != nil {\n\t\treturn swarm.Service{}, nil, err\n\t}\n\n\tvar response swarm.Service\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&response)\n\treturn response, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/service_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// ServiceList returns the list of services.\nfunc (cli *Client) ServiceList(ctx context.Context, options types.ServiceListOptions) ([]swarm.Service, error) {\n\tquery := url.Values{}\n\n\tif options.Filters.Len() > 0 {\n\t\tfilterJSON, err := filters.ToJSON(options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\tif options.Status {\n\t\tquery.Set(\"status\", \"true\")\n\t}\n\n\tresp, err := cli.get(ctx, \"/services\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar services []swarm.Service\n\terr = json.NewDecoder(resp.body).Decode(&services)\n\treturn services, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/service_logs.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\ttimetypes \"github.com/docker/docker/api/types/time\"\n\t\"github.com/pkg/errors\"\n)\n\n// ServiceLogs returns the logs generated by a service in an io.ReadCloser.\n// It's up to the caller to close the stream.\nfunc (cli *Client) ServiceLogs(ctx context.Context, serviceID string, options container.LogsOptions) (io.ReadCloser, error) {\n\tquery := url.Values{}\n\tif options.ShowStdout {\n\t\tquery.Set(\"stdout\", \"1\")\n\t}\n\n\tif options.ShowStderr {\n\t\tquery.Set(\"stderr\", \"1\")\n\t}\n\n\tif options.Since != \"\" {\n\t\tts, err := timetypes.GetTimestamp(options.Since, time.Now())\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, `invalid value for \"since\"`)\n\t\t}\n\t\tquery.Set(\"since\", ts)\n\t}\n\n\tif options.Timestamps {\n\t\tquery.Set(\"timestamps\", \"1\")\n\t}\n\n\tif options.Details {\n\t\tquery.Set(\"details\", \"1\")\n\t}\n\n\tif options.Follow {\n\t\tquery.Set(\"follow\", \"1\")\n\t}\n\tquery.Set(\"tail\", options.Tail)\n\n\tresp, err := cli.get(ctx, \"/services/\"+serviceID+\"/logs\", query, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/service_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport \"context\"\n\n// ServiceRemove kills and removes a service.\nfunc (cli *Client) ServiceRemove(ctx context.Context, serviceID string) error {\n\tresp, err := cli.delete(ctx, \"/services/\"+serviceID, nil, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/service_update.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/registry\"\n\t\"github.com/docker/docker/api/types/swarm\"\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// ServiceUpdate updates a Service. The version number is required to avoid conflicting writes.\n// It should be the value as set *before* the update. You can find this value in the Meta field\n// of swarm.Service, which can be found using ServiceInspectWithRaw.\nfunc (cli *Client) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options types.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {\n\tresponse := swarm.ServiceUpdateResponse{}\n\n\t// Make sure we negotiated (if the client is configured to do so),\n\t// as code below contains API-version specific handling of options.\n\t//\n\t// Normally, version-negotiation (if enabled) would not happen until\n\t// the API request is made.\n\tif err := cli.checkVersion(ctx); err != nil {\n\t\treturn response, err\n\t}\n\n\tquery := url.Values{}\n\tif options.RegistryAuthFrom != \"\" {\n\t\tquery.Set(\"registryAuthFrom\", options.RegistryAuthFrom)\n\t}\n\n\tif options.Rollback != \"\" {\n\t\tquery.Set(\"rollback\", options.Rollback)\n\t}\n\n\tquery.Set(\"version\", version.String())\n\n\tif err := validateServiceSpec(service); err != nil {\n\t\treturn response, err\n\t}\n\n\t// ensure that the image is tagged\n\tvar resolveWarning string\n\tswitch {\n\tcase service.TaskTemplate.ContainerSpec != nil:\n\t\tif taggedImg := imageWithTagString(service.TaskTemplate.ContainerSpec.Image); taggedImg != \"\" {\n\t\t\tservice.TaskTemplate.ContainerSpec.Image = taggedImg\n\t\t}\n\t\tif options.QueryRegistry {\n\t\t\tresolveWarning = resolveContainerSpecImage(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)\n\t\t}\n\tcase service.TaskTemplate.PluginSpec != nil:\n\t\tif taggedImg := imageWithTagString(service.TaskTemplate.PluginSpec.Remote); taggedImg != \"\" {\n\t\t\tservice.TaskTemplate.PluginSpec.Remote = taggedImg\n\t\t}\n\t\tif options.QueryRegistry {\n\t\t\tresolveWarning = resolvePluginSpecRemote(ctx, cli, &service.TaskTemplate, options.EncodedRegistryAuth)\n\t\t}\n\t}\n\n\theaders := http.Header{}\n\tif versions.LessThan(cli.version, \"1.30\") {\n\t\t// the custom \"version\" header was used by engine API before 20.10\n\t\t// (API 1.30) to switch between client- and server-side lookup of\n\t\t// image digests.\n\t\theaders[\"version\"] = []string{cli.version}\n\t}\n\tif options.EncodedRegistryAuth != \"\" {\n\t\theaders[registry.AuthHeader] = []string{options.EncodedRegistryAuth}\n\t}\n\tresp, err := cli.post(ctx, \"/services/\"+serviceID+\"/update\", query, service, headers)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn response, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&response)\n\tif resolveWarning != \"\" {\n\t\tresponse.Warnings = append(response.Warnings, resolveWarning)\n\t}\n\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/swarm_get_unlock_key.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// SwarmGetUnlockKey retrieves the swarm's unlock key.\nfunc (cli *Client) SwarmGetUnlockKey(ctx context.Context) (types.SwarmUnlockKeyResponse, error) {\n\tserverResp, err := cli.get(ctx, \"/swarm/unlockkey\", nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn types.SwarmUnlockKeyResponse{}, err\n\t}\n\n\tvar response types.SwarmUnlockKeyResponse\n\terr = json.NewDecoder(serverResp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/swarm_init.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SwarmInit initializes the swarm.\nfunc (cli *Client) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) {\n\tserverResp, err := cli.post(ctx, \"/swarm/init\", nil, req, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar response string\n\terr = json.NewDecoder(serverResp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/swarm_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SwarmInspect inspects the swarm.\nfunc (cli *Client) SwarmInspect(ctx context.Context) (swarm.Swarm, error) {\n\tserverResp, err := cli.get(ctx, \"/swarm\", nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn swarm.Swarm{}, err\n\t}\n\n\tvar response swarm.Swarm\n\terr = json.NewDecoder(serverResp.body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/swarm_join.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SwarmJoin joins the swarm.\nfunc (cli *Client) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {\n\tresp, err := cli.post(ctx, \"/swarm/join\", nil, req, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/swarm_leave.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n)\n\n// SwarmLeave leaves the swarm.\nfunc (cli *Client) SwarmLeave(ctx context.Context, force bool) error {\n\tquery := url.Values{}\n\tif force {\n\t\tquery.Set(\"force\", \"1\")\n\t}\n\tresp, err := cli.post(ctx, \"/swarm/leave\", query, nil, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/swarm_unlock.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SwarmUnlock unlocks locked swarm.\nfunc (cli *Client) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {\n\tserverResp, err := cli.post(ctx, \"/swarm/unlock\", nil, req, nil)\n\tensureReaderClosed(serverResp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/swarm_update.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// SwarmUpdate updates the swarm.\nfunc (cli *Client) SwarmUpdate(ctx context.Context, version swarm.Version, swarm swarm.Spec, flags swarm.UpdateFlags) error {\n\tquery := url.Values{}\n\tquery.Set(\"version\", version.String())\n\tquery.Set(\"rotateWorkerToken\", strconv.FormatBool(flags.RotateWorkerToken))\n\tquery.Set(\"rotateManagerToken\", strconv.FormatBool(flags.RotateManagerToken))\n\tquery.Set(\"rotateManagerUnlockKey\", strconv.FormatBool(flags.RotateManagerUnlockKey))\n\tresp, err := cli.post(ctx, \"/swarm/update\", query, swarm, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/task_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// TaskInspectWithRaw returns the task information and its raw representation.\nfunc (cli *Client) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) {\n\tif taskID == \"\" {\n\t\treturn swarm.Task{}, nil, objectNotFoundError{object: \"task\", id: taskID}\n\t}\n\tserverResp, err := cli.get(ctx, \"/tasks/\"+taskID, nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn swarm.Task{}, nil, err\n\t}\n\n\tbody, err := io.ReadAll(serverResp.body)\n\tif err != nil {\n\t\treturn swarm.Task{}, nil, err\n\t}\n\n\tvar response swarm.Task\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&response)\n\treturn response, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/task_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// TaskList returns the list of tasks.\nfunc (cli *Client) TaskList(ctx context.Context, options types.TaskListOptions) ([]swarm.Task, error) {\n\tquery := url.Values{}\n\n\tif options.Filters.Len() > 0 {\n\t\tfilterJSON, err := filters.ToJSON(options.Filters)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\n\tresp, err := cli.get(ctx, \"/tasks\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar tasks []swarm.Task\n\terr = json.NewDecoder(resp.body).Decode(&tasks)\n\treturn tasks, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/task_logs.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/url\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/container\"\n\ttimetypes \"github.com/docker/docker/api/types/time\"\n)\n\n// TaskLogs returns the logs generated by a task in an io.ReadCloser.\n// It's up to the caller to close the stream.\nfunc (cli *Client) TaskLogs(ctx context.Context, taskID string, options container.LogsOptions) (io.ReadCloser, error) {\n\tquery := url.Values{}\n\tif options.ShowStdout {\n\t\tquery.Set(\"stdout\", \"1\")\n\t}\n\n\tif options.ShowStderr {\n\t\tquery.Set(\"stderr\", \"1\")\n\t}\n\n\tif options.Since != \"\" {\n\t\tts, err := timetypes.GetTimestamp(options.Since, time.Now())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tquery.Set(\"since\", ts)\n\t}\n\n\tif options.Timestamps {\n\t\tquery.Set(\"timestamps\", \"1\")\n\t}\n\n\tif options.Details {\n\t\tquery.Set(\"details\", \"1\")\n\t}\n\n\tif options.Follow {\n\t\tquery.Set(\"follow\", \"1\")\n\t}\n\tquery.Set(\"tail\", options.Tail)\n\n\tresp, err := cli.get(ctx, \"/tasks/\"+taskID+\"/logs\", query, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn resp.body, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/utils.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"net/url\"\n\t\"regexp\"\n\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\nvar headerRegexp = regexp.MustCompile(`\\ADocker/.+\\s\\((.+)\\)\\z`)\n\n// getDockerOS returns the operating system based on the server header from the daemon.\nfunc getDockerOS(serverHeader string) string {\n\tvar osType string\n\tmatches := headerRegexp.FindStringSubmatch(serverHeader)\n\tif len(matches) > 0 {\n\t\tosType = matches[1]\n\t}\n\treturn osType\n}\n\n// getFiltersQuery returns a url query with \"filters\" query term, based on the\n// filters provided.\nfunc getFiltersQuery(f filters.Args) (url.Values, error) {\n\tquery := url.Values{}\n\tif f.Len() > 0 {\n\t\tfilterJSON, err := filters.ToJSON(f)\n\t\tif err != nil {\n\t\t\treturn query, err\n\t\t}\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\treturn query, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/version.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types\"\n)\n\n// ServerVersion returns information of the docker client and server host.\nfunc (cli *Client) ServerVersion(ctx context.Context) (types.Version, error) {\n\tresp, err := cli.get(ctx, \"/version\", nil, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn types.Version{}, err\n\t}\n\n\tvar server types.Version\n\terr = json.NewDecoder(resp.body).Decode(&server)\n\treturn server, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/volume_create.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/docker/docker/api/types/volume\"\n)\n\n// VolumeCreate creates a volume in the docker host.\nfunc (cli *Client) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) {\n\tvar vol volume.Volume\n\tresp, err := cli.post(ctx, \"/volumes/create\", nil, options, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn vol, err\n\t}\n\terr = json.NewDecoder(resp.body).Decode(&vol)\n\treturn vol, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/volume_inspect.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types/volume\"\n)\n\n// VolumeInspect returns the information about a specific volume in the docker host.\nfunc (cli *Client) VolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error) {\n\tvol, _, err := cli.VolumeInspectWithRaw(ctx, volumeID)\n\treturn vol, err\n}\n\n// VolumeInspectWithRaw returns the information about a specific volume in the docker host and its raw representation\nfunc (cli *Client) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) {\n\tif volumeID == \"\" {\n\t\treturn volume.Volume{}, nil, objectNotFoundError{object: \"volume\", id: volumeID}\n\t}\n\n\tvar vol volume.Volume\n\tresp, err := cli.get(ctx, \"/volumes/\"+volumeID, nil, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn vol, nil, err\n\t}\n\n\tbody, err := io.ReadAll(resp.body)\n\tif err != nil {\n\t\treturn vol, nil, err\n\t}\n\trdr := bytes.NewReader(body)\n\terr = json.NewDecoder(rdr).Decode(&vol)\n\treturn vol, body, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/volume_list.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docker/docker/api/types/volume\"\n)\n\n// VolumeList returns the volumes configured in the docker host.\nfunc (cli *Client) VolumeList(ctx context.Context, options volume.ListOptions) (volume.ListResponse, error) {\n\tvar volumes volume.ListResponse\n\tquery := url.Values{}\n\n\tif options.Filters.Len() > 0 {\n\t\t//nolint:staticcheck // ignore SA1019 for old code\n\t\tfilterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters)\n\t\tif err != nil {\n\t\t\treturn volumes, err\n\t\t}\n\t\tquery.Set(\"filters\", filterJSON)\n\t}\n\tresp, err := cli.get(ctx, \"/volumes\", query, nil)\n\tdefer ensureReaderClosed(resp)\n\tif err != nil {\n\t\treturn volumes, err\n\t}\n\n\terr = json.NewDecoder(resp.body).Decode(&volumes)\n\treturn volumes, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/volume_prune.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/filters\"\n)\n\n// VolumesPrune requests the daemon to delete unused data\nfunc (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (types.VolumesPruneReport, error) {\n\tvar report types.VolumesPruneReport\n\n\tif err := cli.NewVersionError(ctx, \"1.25\", \"volume prune\"); err != nil {\n\t\treturn report, err\n\t}\n\n\tquery, err := getFiltersQuery(pruneFilters)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tserverResp, err := cli.post(ctx, \"/volumes/prune\", query, nil, nil)\n\tdefer ensureReaderClosed(serverResp)\n\tif err != nil {\n\t\treturn report, err\n\t}\n\n\tif err := json.NewDecoder(serverResp.body).Decode(&report); err != nil {\n\t\treturn report, fmt.Errorf(\"Error retrieving volume prune report: %v\", err)\n\t}\n\n\treturn report, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/volume_remove.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/versions\"\n)\n\n// VolumeRemove removes a volume from the docker host.\nfunc (cli *Client) VolumeRemove(ctx context.Context, volumeID string, force bool) error {\n\tquery := url.Values{}\n\tif force {\n\t\t// Make sure we negotiated (if the client is configured to do so),\n\t\t// as code below contains API-version specific handling of options.\n\t\t//\n\t\t// Normally, version-negotiation (if enabled) would not happen until\n\t\t// the API request is made.\n\t\tif err := cli.checkVersion(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif versions.GreaterThanOrEqualTo(cli.version, \"1.25\") {\n\t\t\tquery.Set(\"force\", \"1\")\n\t\t}\n\t}\n\tresp, err := cli.delete(ctx, \"/volumes/\"+volumeID, query, nil)\n\tdefer ensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/client/volume_update.go",
    "content": "package client // import \"github.com/docker/docker/client\"\n\nimport (\n\t\"context\"\n\t\"net/url\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n\t\"github.com/docker/docker/api/types/volume\"\n)\n\n// VolumeUpdate updates a volume. This only works for Cluster Volumes, and\n// only some fields can be updated.\nfunc (cli *Client) VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error {\n\tif err := cli.NewVersionError(ctx, \"1.42\", \"volume update\"); err != nil {\n\t\treturn err\n\t}\n\n\tquery := url.Values{}\n\tquery.Set(\"version\", version.String())\n\n\tresp, err := cli.put(ctx, \"/volumes/\"+volumeID, query, options, nil)\n\tensureReaderClosed(resp)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/errdefs/defs.go",
    "content": "package errdefs\n\n// ErrNotFound signals that the requested object doesn't exist\ntype ErrNotFound interface {\n\tNotFound()\n}\n\n// ErrInvalidParameter signals that the user input is invalid\ntype ErrInvalidParameter interface {\n\tInvalidParameter()\n}\n\n// ErrConflict signals that some internal state conflicts with the requested action and can't be performed.\n// A change in state should be able to clear this error.\ntype ErrConflict interface {\n\tConflict()\n}\n\n// ErrUnauthorized is used to signify that the user is not authorized to perform a specific action\ntype ErrUnauthorized interface {\n\tUnauthorized()\n}\n\n// ErrUnavailable signals that the requested action/subsystem is not available.\ntype ErrUnavailable interface {\n\tUnavailable()\n}\n\n// ErrForbidden signals that the requested action cannot be performed under any circumstances.\n// When a ErrForbidden is returned, the caller should never retry the action.\ntype ErrForbidden interface {\n\tForbidden()\n}\n\n// ErrSystem signals that some internal error occurred.\n// An example of this would be a failed mount request.\ntype ErrSystem interface {\n\tSystem()\n}\n\n// ErrNotModified signals that an action can't be performed because it's already in the desired state\ntype ErrNotModified interface {\n\tNotModified()\n}\n\n// ErrNotImplemented signals that the requested action/feature is not implemented on the system as configured.\ntype ErrNotImplemented interface {\n\tNotImplemented()\n}\n\n// ErrUnknown signals that the kind of error that occurred is not known.\ntype ErrUnknown interface {\n\tUnknown()\n}\n\n// ErrCancelled signals that the action was cancelled.\ntype ErrCancelled interface {\n\tCancelled()\n}\n\n// ErrDeadline signals that the deadline was reached before the action completed.\ntype ErrDeadline interface {\n\tDeadlineExceeded()\n}\n\n// ErrDataLoss indicates that data was lost or there is data corruption.\ntype ErrDataLoss interface {\n\tDataLoss()\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/errdefs/doc.go",
    "content": "// Package errdefs defines a set of error interfaces that packages should use for communicating classes of errors.\n// Errors that cross the package boundary should implement one (and only one) of these interfaces.\n//\n// Packages should not reference these interfaces directly, only implement them.\n// To check if a particular error implements one of these interfaces, there are helper\n// functions provided (e.g. `Is<SomeError>`) which can be used rather than asserting the interfaces directly.\n// If you must assert on these interfaces, be sure to check the causal chain (`err.Cause()`).\npackage errdefs // import \"github.com/docker/docker/errdefs\"\n"
  },
  {
    "path": "vendor/github.com/docker/docker/errdefs/helpers.go",
    "content": "package errdefs\n\nimport \"context\"\n\ntype errNotFound struct{ error }\n\nfunc (errNotFound) NotFound() {}\n\nfunc (e errNotFound) Cause() error {\n\treturn e.error\n}\n\nfunc (e errNotFound) Unwrap() error {\n\treturn e.error\n}\n\n// NotFound is a helper to create an error of the class with the same name from any error type\nfunc NotFound(err error) error {\n\tif err == nil || IsNotFound(err) {\n\t\treturn err\n\t}\n\treturn errNotFound{err}\n}\n\ntype errInvalidParameter struct{ error }\n\nfunc (errInvalidParameter) InvalidParameter() {}\n\nfunc (e errInvalidParameter) Cause() error {\n\treturn e.error\n}\n\nfunc (e errInvalidParameter) Unwrap() error {\n\treturn e.error\n}\n\n// InvalidParameter is a helper to create an error of the class with the same name from any error type\nfunc InvalidParameter(err error) error {\n\tif err == nil || IsInvalidParameter(err) {\n\t\treturn err\n\t}\n\treturn errInvalidParameter{err}\n}\n\ntype errConflict struct{ error }\n\nfunc (errConflict) Conflict() {}\n\nfunc (e errConflict) Cause() error {\n\treturn e.error\n}\n\nfunc (e errConflict) Unwrap() error {\n\treturn e.error\n}\n\n// Conflict is a helper to create an error of the class with the same name from any error type\nfunc Conflict(err error) error {\n\tif err == nil || IsConflict(err) {\n\t\treturn err\n\t}\n\treturn errConflict{err}\n}\n\ntype errUnauthorized struct{ error }\n\nfunc (errUnauthorized) Unauthorized() {}\n\nfunc (e errUnauthorized) Cause() error {\n\treturn e.error\n}\n\nfunc (e errUnauthorized) Unwrap() error {\n\treturn e.error\n}\n\n// Unauthorized is a helper to create an error of the class with the same name from any error type\nfunc Unauthorized(err error) error {\n\tif err == nil || IsUnauthorized(err) {\n\t\treturn err\n\t}\n\treturn errUnauthorized{err}\n}\n\ntype errUnavailable struct{ error }\n\nfunc (errUnavailable) Unavailable() {}\n\nfunc (e errUnavailable) Cause() error {\n\treturn e.error\n}\n\nfunc (e errUnavailable) Unwrap() error {\n\treturn e.error\n}\n\n// Unavailable is a helper to create an error of the class with the same name from any error type\nfunc Unavailable(err error) error {\n\tif err == nil || IsUnavailable(err) {\n\t\treturn err\n\t}\n\treturn errUnavailable{err}\n}\n\ntype errForbidden struct{ error }\n\nfunc (errForbidden) Forbidden() {}\n\nfunc (e errForbidden) Cause() error {\n\treturn e.error\n}\n\nfunc (e errForbidden) Unwrap() error {\n\treturn e.error\n}\n\n// Forbidden is a helper to create an error of the class with the same name from any error type\nfunc Forbidden(err error) error {\n\tif err == nil || IsForbidden(err) {\n\t\treturn err\n\t}\n\treturn errForbidden{err}\n}\n\ntype errSystem struct{ error }\n\nfunc (errSystem) System() {}\n\nfunc (e errSystem) Cause() error {\n\treturn e.error\n}\n\nfunc (e errSystem) Unwrap() error {\n\treturn e.error\n}\n\n// System is a helper to create an error of the class with the same name from any error type\nfunc System(err error) error {\n\tif err == nil || IsSystem(err) {\n\t\treturn err\n\t}\n\treturn errSystem{err}\n}\n\ntype errNotModified struct{ error }\n\nfunc (errNotModified) NotModified() {}\n\nfunc (e errNotModified) Cause() error {\n\treturn e.error\n}\n\nfunc (e errNotModified) Unwrap() error {\n\treturn e.error\n}\n\n// NotModified is a helper to create an error of the class with the same name from any error type\nfunc NotModified(err error) error {\n\tif err == nil || IsNotModified(err) {\n\t\treturn err\n\t}\n\treturn errNotModified{err}\n}\n\ntype errNotImplemented struct{ error }\n\nfunc (errNotImplemented) NotImplemented() {}\n\nfunc (e errNotImplemented) Cause() error {\n\treturn e.error\n}\n\nfunc (e errNotImplemented) Unwrap() error {\n\treturn e.error\n}\n\n// NotImplemented is a helper to create an error of the class with the same name from any error type\nfunc NotImplemented(err error) error {\n\tif err == nil || IsNotImplemented(err) {\n\t\treturn err\n\t}\n\treturn errNotImplemented{err}\n}\n\ntype errUnknown struct{ error }\n\nfunc (errUnknown) Unknown() {}\n\nfunc (e errUnknown) Cause() error {\n\treturn e.error\n}\n\nfunc (e errUnknown) Unwrap() error {\n\treturn e.error\n}\n\n// Unknown is a helper to create an error of the class with the same name from any error type\nfunc Unknown(err error) error {\n\tif err == nil || IsUnknown(err) {\n\t\treturn err\n\t}\n\treturn errUnknown{err}\n}\n\ntype errCancelled struct{ error }\n\nfunc (errCancelled) Cancelled() {}\n\nfunc (e errCancelled) Cause() error {\n\treturn e.error\n}\n\nfunc (e errCancelled) Unwrap() error {\n\treturn e.error\n}\n\n// Cancelled is a helper to create an error of the class with the same name from any error type\nfunc Cancelled(err error) error {\n\tif err == nil || IsCancelled(err) {\n\t\treturn err\n\t}\n\treturn errCancelled{err}\n}\n\ntype errDeadline struct{ error }\n\nfunc (errDeadline) DeadlineExceeded() {}\n\nfunc (e errDeadline) Cause() error {\n\treturn e.error\n}\n\nfunc (e errDeadline) Unwrap() error {\n\treturn e.error\n}\n\n// Deadline is a helper to create an error of the class with the same name from any error type\nfunc Deadline(err error) error {\n\tif err == nil || IsDeadline(err) {\n\t\treturn err\n\t}\n\treturn errDeadline{err}\n}\n\ntype errDataLoss struct{ error }\n\nfunc (errDataLoss) DataLoss() {}\n\nfunc (e errDataLoss) Cause() error {\n\treturn e.error\n}\n\nfunc (e errDataLoss) Unwrap() error {\n\treturn e.error\n}\n\n// DataLoss is a helper to create an error of the class with the same name from any error type\nfunc DataLoss(err error) error {\n\tif err == nil || IsDataLoss(err) {\n\t\treturn err\n\t}\n\treturn errDataLoss{err}\n}\n\n// FromContext returns the error class from the passed in context\nfunc FromContext(ctx context.Context) error {\n\te := ctx.Err()\n\tif e == nil {\n\t\treturn nil\n\t}\n\n\tif e == context.Canceled {\n\t\treturn Cancelled(e)\n\t}\n\tif e == context.DeadlineExceeded {\n\t\treturn Deadline(e)\n\t}\n\treturn Unknown(e)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/errdefs/http_helpers.go",
    "content": "package errdefs\n\nimport (\n\t\"net/http\"\n)\n\n// FromStatusCode creates an errdef error, based on the provided HTTP status-code\nfunc FromStatusCode(err error, statusCode int) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\tswitch statusCode {\n\tcase http.StatusNotFound:\n\t\terr = NotFound(err)\n\tcase http.StatusBadRequest:\n\t\terr = InvalidParameter(err)\n\tcase http.StatusConflict:\n\t\terr = Conflict(err)\n\tcase http.StatusUnauthorized:\n\t\terr = Unauthorized(err)\n\tcase http.StatusServiceUnavailable:\n\t\terr = Unavailable(err)\n\tcase http.StatusForbidden:\n\t\terr = Forbidden(err)\n\tcase http.StatusNotModified:\n\t\terr = NotModified(err)\n\tcase http.StatusNotImplemented:\n\t\terr = NotImplemented(err)\n\tcase http.StatusInternalServerError:\n\t\tif !IsSystem(err) && !IsUnknown(err) && !IsDataLoss(err) && !IsDeadline(err) && !IsCancelled(err) {\n\t\t\terr = System(err)\n\t\t}\n\tdefault:\n\t\tswitch {\n\t\tcase statusCode >= 200 && statusCode < 400:\n\t\t\t// it's a client error\n\t\tcase statusCode >= 400 && statusCode < 500:\n\t\t\terr = InvalidParameter(err)\n\t\tcase statusCode >= 500 && statusCode < 600:\n\t\t\terr = System(err)\n\t\tdefault:\n\t\t\terr = Unknown(err)\n\t\t}\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/errdefs/is.go",
    "content": "package errdefs\n\nimport (\n\t\"context\"\n\t\"errors\"\n)\n\ntype causer interface {\n\tCause() error\n}\n\ntype wrapErr interface {\n\tUnwrap() error\n}\n\nfunc getImplementer(err error) error {\n\tswitch e := err.(type) {\n\tcase\n\t\tErrNotFound,\n\t\tErrInvalidParameter,\n\t\tErrConflict,\n\t\tErrUnauthorized,\n\t\tErrUnavailable,\n\t\tErrForbidden,\n\t\tErrSystem,\n\t\tErrNotModified,\n\t\tErrNotImplemented,\n\t\tErrCancelled,\n\t\tErrDeadline,\n\t\tErrDataLoss,\n\t\tErrUnknown:\n\t\treturn err\n\tcase causer:\n\t\treturn getImplementer(e.Cause())\n\tcase wrapErr:\n\t\treturn getImplementer(e.Unwrap())\n\tdefault:\n\t\treturn err\n\t}\n}\n\n// IsNotFound returns if the passed in error is an ErrNotFound\nfunc IsNotFound(err error) bool {\n\t_, ok := getImplementer(err).(ErrNotFound)\n\treturn ok\n}\n\n// IsInvalidParameter returns if the passed in error is an ErrInvalidParameter\nfunc IsInvalidParameter(err error) bool {\n\t_, ok := getImplementer(err).(ErrInvalidParameter)\n\treturn ok\n}\n\n// IsConflict returns if the passed in error is an ErrConflict\nfunc IsConflict(err error) bool {\n\t_, ok := getImplementer(err).(ErrConflict)\n\treturn ok\n}\n\n// IsUnauthorized returns if the passed in error is an ErrUnauthorized\nfunc IsUnauthorized(err error) bool {\n\t_, ok := getImplementer(err).(ErrUnauthorized)\n\treturn ok\n}\n\n// IsUnavailable returns if the passed in error is an ErrUnavailable\nfunc IsUnavailable(err error) bool {\n\t_, ok := getImplementer(err).(ErrUnavailable)\n\treturn ok\n}\n\n// IsForbidden returns if the passed in error is an ErrForbidden\nfunc IsForbidden(err error) bool {\n\t_, ok := getImplementer(err).(ErrForbidden)\n\treturn ok\n}\n\n// IsSystem returns if the passed in error is an ErrSystem\nfunc IsSystem(err error) bool {\n\t_, ok := getImplementer(err).(ErrSystem)\n\treturn ok\n}\n\n// IsNotModified returns if the passed in error is a NotModified error\nfunc IsNotModified(err error) bool {\n\t_, ok := getImplementer(err).(ErrNotModified)\n\treturn ok\n}\n\n// IsNotImplemented returns if the passed in error is an ErrNotImplemented\nfunc IsNotImplemented(err error) bool {\n\t_, ok := getImplementer(err).(ErrNotImplemented)\n\treturn ok\n}\n\n// IsUnknown returns if the passed in error is an ErrUnknown\nfunc IsUnknown(err error) bool {\n\t_, ok := getImplementer(err).(ErrUnknown)\n\treturn ok\n}\n\n// IsCancelled returns if the passed in error is an ErrCancelled\nfunc IsCancelled(err error) bool {\n\t_, ok := getImplementer(err).(ErrCancelled)\n\treturn ok\n}\n\n// IsDeadline returns if the passed in error is an ErrDeadline\nfunc IsDeadline(err error) bool {\n\t_, ok := getImplementer(err).(ErrDeadline)\n\treturn ok\n}\n\n// IsDataLoss returns if the passed in error is an ErrDataLoss\nfunc IsDataLoss(err error) bool {\n\t_, ok := getImplementer(err).(ErrDataLoss)\n\treturn ok\n}\n\n// IsContext returns if the passed in error is due to context cancellation or deadline exceeded.\nfunc IsContext(err error) bool {\n\treturn errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/image/spec/specs-go/v1/image.go",
    "content": "package v1\n\nimport (\n\t\"time\"\n\n\tocispec \"github.com/opencontainers/image-spec/specs-go/v1\"\n)\n\nconst DockerOCIImageMediaType = \"application/vnd.docker.container.image.v1+json\"\n\n// DockerOCIImage is a ocispec.Image extended with Docker specific Config.\ntype DockerOCIImage struct {\n\tocispec.Image\n\n\t// Shadow ocispec.Image.Config\n\tConfig DockerOCIImageConfig `json:\"config,omitempty\"`\n}\n\n// DockerOCIImageConfig is a ocispec.ImageConfig extended with Docker specific fields.\ntype DockerOCIImageConfig struct {\n\tocispec.ImageConfig\n\n\tDockerOCIImageConfigExt\n}\n\n// DockerOCIImageConfigExt contains Docker-specific fields in DockerImageConfig.\ntype DockerOCIImageConfigExt struct {\n\tHealthcheck *HealthcheckConfig `json:\",omitempty\"` // Healthcheck describes how to check the container is healthy\n\n\tOnBuild []string `json:\",omitempty\"` // ONBUILD metadata that were defined on the image Dockerfile\n\tShell   []string `json:\",omitempty\"` // Shell for shell-form of RUN, CMD, ENTRYPOINT\n}\n\n// HealthcheckConfig holds configuration settings for the HEALTHCHECK feature.\ntype HealthcheckConfig struct {\n\t// Test is the test to perform to check that the container is healthy.\n\t// An empty slice means to inherit the default.\n\t// The options are:\n\t// {} : inherit healthcheck\n\t// {\"NONE\"} : disable healthcheck\n\t// {\"CMD\", args...} : exec arguments directly\n\t// {\"CMD-SHELL\", command} : run command with system's default shell\n\tTest []string `json:\",omitempty\"`\n\n\t// Zero means to inherit. Durations are expressed as integer nanoseconds.\n\tInterval      time.Duration `json:\",omitempty\"` // Interval is the time to wait between checks.\n\tTimeout       time.Duration `json:\",omitempty\"` // Timeout is the time to wait before considering the check to have hung.\n\tStartPeriod   time.Duration `json:\",omitempty\"` // The start period for the container to initialize before the retries starts to count down.\n\tStartInterval time.Duration `json:\",omitempty\"` // The interval to attempt healthchecks at during the start period\n\n\t// Retries is the number of consecutive failures needed to consider a container as unhealthy.\n\t// Zero means inherit.\n\tRetries int `json:\",omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/internal/multierror/multierror.go",
    "content": "package multierror\n\nimport (\n\t\"strings\"\n)\n\n// Join is a drop-in replacement for errors.Join with better formatting.\nfunc Join(errs ...error) error {\n\tn := 0\n\tfor _, err := range errs {\n\t\tif err != nil {\n\t\t\tn++\n\t\t}\n\t}\n\tif n == 0 {\n\t\treturn nil\n\t}\n\te := &joinError{\n\t\terrs: make([]error, 0, n),\n\t}\n\tfor _, err := range errs {\n\t\tif err != nil {\n\t\t\te.errs = append(e.errs, err)\n\t\t}\n\t}\n\treturn e\n}\n\ntype joinError struct {\n\terrs []error\n}\n\nfunc (e *joinError) Error() string {\n\tif len(e.errs) == 1 {\n\t\treturn strings.TrimSpace(e.errs[0].Error())\n\t}\n\tstringErrs := make([]string, 0, len(e.errs))\n\tfor _, subErr := range e.errs {\n\t\tstringErrs = append(stringErrs, strings.Replace(subErr.Error(), \"\\n\", \"\\n\\t\", -1))\n\t}\n\treturn \"* \" + strings.Join(stringErrs, \"\\n* \")\n}\n\nfunc (e *joinError) Unwrap() []error {\n\treturn e.errs\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/archive.go",
    "content": "// Package archive provides helper functions for dealing with archive files.\npackage archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/bzip2\"\n\t\"compress/gzip\"\n\t\"context\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/containerd/containerd/pkg/userns\"\n\t\"github.com/containerd/log\"\n\t\"github.com/docker/docker/pkg/idtools\"\n\t\"github.com/docker/docker/pkg/ioutils\"\n\t\"github.com/docker/docker/pkg/pools\"\n\t\"github.com/docker/docker/pkg/system\"\n\t\"github.com/klauspost/compress/zstd\"\n\t\"github.com/moby/patternmatcher\"\n\t\"github.com/moby/sys/sequential\"\n\t\"github.com/pkg/errors\"\n)\n\n// ImpliedDirectoryMode represents the mode (Unix permissions) applied to directories that are implied by files in a\n// tar, but that do not have their own header entry.\n//\n// The permissions mask is stored in a constant instead of locally to ensure that magic numbers do not\n// proliferate in the codebase. The default value 0755 has been selected based on the default umask of 0022, and\n// a convention of mkdir(1) calling mkdir(2) with permissions of 0777, resulting in a final value of 0755.\n//\n// This value is currently implementation-defined, and not captured in any cross-runtime specification. Thus, it is\n// subject to change in Moby at any time -- image authors who require consistent or known directory permissions\n// should explicitly control them by ensuring that header entries exist for any applicable path.\nconst ImpliedDirectoryMode = 0o755\n\ntype (\n\t// Compression is the state represents if compressed or not.\n\tCompression int\n\t// WhiteoutFormat is the format of whiteouts unpacked\n\tWhiteoutFormat int\n\n\t// TarOptions wraps the tar options.\n\tTarOptions struct {\n\t\tIncludeFiles     []string\n\t\tExcludePatterns  []string\n\t\tCompression      Compression\n\t\tNoLchown         bool\n\t\tIDMap            idtools.IdentityMapping\n\t\tChownOpts        *idtools.Identity\n\t\tIncludeSourceDir bool\n\t\t// WhiteoutFormat is the expected on disk format for whiteout files.\n\t\t// This format will be converted to the standard format on pack\n\t\t// and from the standard format on unpack.\n\t\tWhiteoutFormat WhiteoutFormat\n\t\t// When unpacking, specifies whether overwriting a directory with a\n\t\t// non-directory is allowed and vice versa.\n\t\tNoOverwriteDirNonDir bool\n\t\t// For each include when creating an archive, the included name will be\n\t\t// replaced with the matching name from this map.\n\t\tRebaseNames map[string]string\n\t\tInUserNS    bool\n\t\t// Allow unpacking to succeed in spite of failures to set extended\n\t\t// attributes on the unpacked files due to the destination filesystem\n\t\t// not supporting them or a lack of permissions. Extended attributes\n\t\t// were probably in the archive for a reason, so set this option at\n\t\t// your own peril.\n\t\tBestEffortXattrs bool\n\t}\n)\n\n// Archiver implements the Archiver interface and allows the reuse of most utility functions of\n// this package with a pluggable Untar function. Also, to facilitate the passing of specific id\n// mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations.\ntype Archiver struct {\n\tUntar     func(io.Reader, string, *TarOptions) error\n\tIDMapping idtools.IdentityMapping\n}\n\n// NewDefaultArchiver returns a new Archiver without any IdentityMapping\nfunc NewDefaultArchiver() *Archiver {\n\treturn &Archiver{Untar: Untar}\n}\n\n// breakoutError is used to differentiate errors related to breaking out\n// When testing archive breakout in the unit tests, this error is expected\n// in order for the test to pass.\ntype breakoutError error\n\nconst (\n\t// Uncompressed represents the uncompressed.\n\tUncompressed Compression = iota\n\t// Bzip2 is bzip2 compression algorithm.\n\tBzip2\n\t// Gzip is gzip compression algorithm.\n\tGzip\n\t// Xz is xz compression algorithm.\n\tXz\n\t// Zstd is zstd compression algorithm.\n\tZstd\n)\n\nconst (\n\t// AUFSWhiteoutFormat is the default format for whiteouts\n\tAUFSWhiteoutFormat WhiteoutFormat = iota\n\t// OverlayWhiteoutFormat formats whiteout according to the overlay\n\t// standard.\n\tOverlayWhiteoutFormat\n)\n\n// IsArchivePath checks if the (possibly compressed) file at the given path\n// starts with a tar file header.\nfunc IsArchivePath(path string) bool {\n\tfile, err := os.Open(path)\n\tif err != nil {\n\t\treturn false\n\t}\n\tdefer file.Close()\n\trdr, err := DecompressStream(file)\n\tif err != nil {\n\t\treturn false\n\t}\n\tdefer rdr.Close()\n\tr := tar.NewReader(rdr)\n\t_, err = r.Next()\n\treturn err == nil\n}\n\nconst (\n\tzstdMagicSkippableStart = 0x184D2A50\n\tzstdMagicSkippableMask  = 0xFFFFFFF0\n)\n\nvar (\n\tbzip2Magic = []byte{0x42, 0x5A, 0x68}\n\tgzipMagic  = []byte{0x1F, 0x8B, 0x08}\n\txzMagic    = []byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00}\n\tzstdMagic  = []byte{0x28, 0xb5, 0x2f, 0xfd}\n)\n\ntype matcher = func([]byte) bool\n\nfunc magicNumberMatcher(m []byte) matcher {\n\treturn func(source []byte) bool {\n\t\treturn bytes.HasPrefix(source, m)\n\t}\n}\n\n// zstdMatcher detects zstd compression algorithm.\n// Zstandard compressed data is made of one or more frames.\n// There are two frame formats defined by Zstandard: Zstandard frames and Skippable frames.\n// See https://tools.ietf.org/id/draft-kucherawy-dispatch-zstd-00.html#rfc.section.2 for more details.\nfunc zstdMatcher() matcher {\n\treturn func(source []byte) bool {\n\t\tif bytes.HasPrefix(source, zstdMagic) {\n\t\t\t// Zstandard frame\n\t\t\treturn true\n\t\t}\n\t\t// skippable frame\n\t\tif len(source) < 8 {\n\t\t\treturn false\n\t\t}\n\t\t// magic number from 0x184D2A50 to 0x184D2A5F.\n\t\tif binary.LittleEndian.Uint32(source[:4])&zstdMagicSkippableMask == zstdMagicSkippableStart {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n}\n\n// DetectCompression detects the compression algorithm of the source.\nfunc DetectCompression(source []byte) Compression {\n\tcompressionMap := map[Compression]matcher{\n\t\tBzip2: magicNumberMatcher(bzip2Magic),\n\t\tGzip:  magicNumberMatcher(gzipMagic),\n\t\tXz:    magicNumberMatcher(xzMagic),\n\t\tZstd:  zstdMatcher(),\n\t}\n\tfor _, compression := range []Compression{Bzip2, Gzip, Xz, Zstd} {\n\t\tfn := compressionMap[compression]\n\t\tif fn(source) {\n\t\t\treturn compression\n\t\t}\n\t}\n\treturn Uncompressed\n}\n\nfunc xzDecompress(ctx context.Context, archive io.Reader) (io.ReadCloser, error) {\n\targs := []string{\"xz\", \"-d\", \"-c\", \"-q\"}\n\n\treturn cmdStream(exec.CommandContext(ctx, args[0], args[1:]...), archive)\n}\n\nfunc gzDecompress(ctx context.Context, buf io.Reader) (io.ReadCloser, error) {\n\tif noPigzEnv := os.Getenv(\"MOBY_DISABLE_PIGZ\"); noPigzEnv != \"\" {\n\t\tnoPigz, err := strconv.ParseBool(noPigzEnv)\n\t\tif err != nil {\n\t\t\tlog.G(ctx).WithError(err).Warn(\"invalid value in MOBY_DISABLE_PIGZ env var\")\n\t\t}\n\t\tif noPigz {\n\t\t\tlog.G(ctx).Debugf(\"Use of pigz is disabled due to MOBY_DISABLE_PIGZ=%s\", noPigzEnv)\n\t\t\treturn gzip.NewReader(buf)\n\t\t}\n\t}\n\n\tunpigzPath, err := exec.LookPath(\"unpigz\")\n\tif err != nil {\n\t\tlog.G(ctx).Debugf(\"unpigz binary not found, falling back to go gzip library\")\n\t\treturn gzip.NewReader(buf)\n\t}\n\n\tlog.G(ctx).Debugf(\"Using %s to decompress\", unpigzPath)\n\n\treturn cmdStream(exec.CommandContext(ctx, unpigzPath, \"-d\", \"-c\"), buf)\n}\n\nfunc wrapReadCloser(readBuf io.ReadCloser, cancel context.CancelFunc) io.ReadCloser {\n\treturn ioutils.NewReadCloserWrapper(readBuf, func() error {\n\t\tcancel()\n\t\treturn readBuf.Close()\n\t})\n}\n\n// DecompressStream decompresses the archive and returns a ReaderCloser with the decompressed archive.\nfunc DecompressStream(archive io.Reader) (io.ReadCloser, error) {\n\tp := pools.BufioReader32KPool\n\tbuf := p.Get(archive)\n\tbs, err := buf.Peek(10)\n\tif err != nil && err != io.EOF {\n\t\t// Note: we'll ignore any io.EOF error because there are some odd\n\t\t// cases where the layer.tar file will be empty (zero bytes) and\n\t\t// that results in an io.EOF from the Peek() call. So, in those\n\t\t// cases we'll just treat it as a non-compressed stream and\n\t\t// that means just create an empty layer.\n\t\t// See Issue 18170\n\t\treturn nil, err\n\t}\n\n\tcompression := DetectCompression(bs)\n\tswitch compression {\n\tcase Uncompressed:\n\t\treadBufWrapper := p.NewReadCloserWrapper(buf, buf)\n\t\treturn readBufWrapper, nil\n\tcase Gzip:\n\t\tctx, cancel := context.WithCancel(context.Background())\n\n\t\tgzReader, err := gzDecompress(ctx, buf)\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\t\treadBufWrapper := p.NewReadCloserWrapper(buf, gzReader)\n\t\treturn wrapReadCloser(readBufWrapper, cancel), nil\n\tcase Bzip2:\n\t\tbz2Reader := bzip2.NewReader(buf)\n\t\treadBufWrapper := p.NewReadCloserWrapper(buf, bz2Reader)\n\t\treturn readBufWrapper, nil\n\tcase Xz:\n\t\tctx, cancel := context.WithCancel(context.Background())\n\n\t\txzReader, err := xzDecompress(ctx, buf)\n\t\tif err != nil {\n\t\t\tcancel()\n\t\t\treturn nil, err\n\t\t}\n\t\treadBufWrapper := p.NewReadCloserWrapper(buf, xzReader)\n\t\treturn wrapReadCloser(readBufWrapper, cancel), nil\n\tcase Zstd:\n\t\tzstdReader, err := zstd.NewReader(buf)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treadBufWrapper := p.NewReadCloserWrapper(buf, zstdReader)\n\t\treturn readBufWrapper, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Unsupported compression format %s\", (&compression).Extension())\n\t}\n}\n\n// CompressStream compresses the dest with specified compression algorithm.\nfunc CompressStream(dest io.Writer, compression Compression) (io.WriteCloser, error) {\n\tp := pools.BufioWriter32KPool\n\tbuf := p.Get(dest)\n\tswitch compression {\n\tcase Uncompressed:\n\t\twriteBufWrapper := p.NewWriteCloserWrapper(buf, buf)\n\t\treturn writeBufWrapper, nil\n\tcase Gzip:\n\t\tgzWriter := gzip.NewWriter(dest)\n\t\twriteBufWrapper := p.NewWriteCloserWrapper(buf, gzWriter)\n\t\treturn writeBufWrapper, nil\n\tcase Bzip2, Xz:\n\t\t// archive/bzip2 does not support writing, and there is no xz support at all\n\t\t// However, this is not a problem as docker only currently generates gzipped tars\n\t\treturn nil, fmt.Errorf(\"Unsupported compression format %s\", (&compression).Extension())\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"Unsupported compression format %s\", (&compression).Extension())\n\t}\n}\n\n// TarModifierFunc is a function that can be passed to ReplaceFileTarWrapper to\n// modify the contents or header of an entry in the archive. If the file already\n// exists in the archive the TarModifierFunc will be called with the Header and\n// a reader which will return the files content. If the file does not exist both\n// header and content will be nil.\ntype TarModifierFunc func(path string, header *tar.Header, content io.Reader) (*tar.Header, []byte, error)\n\n// ReplaceFileTarWrapper converts inputTarStream to a new tar stream. Files in the\n// tar stream are modified if they match any of the keys in mods.\nfunc ReplaceFileTarWrapper(inputTarStream io.ReadCloser, mods map[string]TarModifierFunc) io.ReadCloser {\n\tpipeReader, pipeWriter := io.Pipe()\n\n\tgo func() {\n\t\ttarReader := tar.NewReader(inputTarStream)\n\t\ttarWriter := tar.NewWriter(pipeWriter)\n\t\tdefer inputTarStream.Close()\n\t\tdefer tarWriter.Close()\n\n\t\tmodify := func(name string, original *tar.Header, modifier TarModifierFunc, tarReader io.Reader) error {\n\t\t\theader, data, err := modifier(name, original, tarReader)\n\t\t\tswitch {\n\t\t\tcase err != nil:\n\t\t\t\treturn err\n\t\t\tcase header == nil:\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif header.Name == \"\" {\n\t\t\t\theader.Name = name\n\t\t\t}\n\t\t\theader.Size = int64(len(data))\n\t\t\tif err := tarWriter.WriteHeader(header); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif len(data) != 0 {\n\t\t\t\tif _, err := tarWriter.Write(data); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tvar err error\n\t\tvar originalHeader *tar.Header\n\t\tfor {\n\t\t\toriginalHeader, err = tarReader.Next()\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\tpipeWriter.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tmodifier, ok := mods[originalHeader.Name]\n\t\t\tif !ok {\n\t\t\t\t// No modifiers for this file, copy the header and data\n\t\t\t\tif err := tarWriter.WriteHeader(originalHeader); err != nil {\n\t\t\t\t\tpipeWriter.CloseWithError(err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif _, err := pools.Copy(tarWriter, tarReader); err != nil {\n\t\t\t\t\tpipeWriter.CloseWithError(err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdelete(mods, originalHeader.Name)\n\n\t\t\tif err := modify(originalHeader.Name, originalHeader, modifier, tarReader); err != nil {\n\t\t\t\tpipeWriter.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\t// Apply the modifiers that haven't matched any files in the archive\n\t\tfor name, modifier := range mods {\n\t\t\tif err := modify(name, nil, modifier, nil); err != nil {\n\t\t\t\tpipeWriter.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tpipeWriter.Close()\n\t}()\n\treturn pipeReader\n}\n\n// Extension returns the extension of a file that uses the specified compression algorithm.\nfunc (compression *Compression) Extension() string {\n\tswitch *compression {\n\tcase Uncompressed:\n\t\treturn \"tar\"\n\tcase Bzip2:\n\t\treturn \"tar.bz2\"\n\tcase Gzip:\n\t\treturn \"tar.gz\"\n\tcase Xz:\n\t\treturn \"tar.xz\"\n\tcase Zstd:\n\t\treturn \"tar.zst\"\n\t}\n\treturn \"\"\n}\n\n// nosysFileInfo hides the system-dependent info of the wrapped FileInfo to\n// prevent tar.FileInfoHeader from introspecting it and potentially calling into\n// glibc.\ntype nosysFileInfo struct {\n\tos.FileInfo\n}\n\nfunc (fi nosysFileInfo) Sys() interface{} {\n\t// A Sys value of type *tar.Header is safe as it is system-independent.\n\t// The tar.FileInfoHeader function copies the fields into the returned\n\t// header without performing any OS lookups.\n\tif sys, ok := fi.FileInfo.Sys().(*tar.Header); ok {\n\t\treturn sys\n\t}\n\treturn nil\n}\n\n// sysStat, if non-nil, populates hdr from system-dependent fields of fi.\nvar sysStat func(fi os.FileInfo, hdr *tar.Header) error\n\n// FileInfoHeaderNoLookups creates a partially-populated tar.Header from fi.\n//\n// Compared to the archive/tar.FileInfoHeader function, this function is safe to\n// call from a chrooted process as it does not populate fields which would\n// require operating system lookups. It behaves identically to\n// tar.FileInfoHeader when fi is a FileInfo value returned from\n// tar.Header.FileInfo().\n//\n// When fi is a FileInfo for a native file, such as returned from os.Stat() and\n// os.Lstat(), the returned Header value differs from one returned from\n// tar.FileInfoHeader in the following ways. The Uname and Gname fields are not\n// set as OS lookups would be required to populate them. The AccessTime and\n// ChangeTime fields are not currently set (not yet implemented) although that\n// is subject to change. Callers which require the AccessTime or ChangeTime\n// fields to be zeroed should explicitly zero them out in the returned Header\n// value to avoid any compatibility issues in the future.\nfunc FileInfoHeaderNoLookups(fi os.FileInfo, link string) (*tar.Header, error) {\n\thdr, err := tar.FileInfoHeader(nosysFileInfo{fi}, link)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif sysStat != nil {\n\t\treturn hdr, sysStat(fi, hdr)\n\t}\n\treturn hdr, nil\n}\n\n// FileInfoHeader creates a populated Header from fi.\n//\n// Compared to the archive/tar package, this function fills in less information\n// but is safe to call from a chrooted process. The AccessTime and ChangeTime\n// fields are not set in the returned header, ModTime is truncated to one-second\n// precision, and the Uname and Gname fields are only set when fi is a FileInfo\n// value returned from tar.Header.FileInfo().\nfunc FileInfoHeader(name string, fi os.FileInfo, link string) (*tar.Header, error) {\n\thdr, err := FileInfoHeaderNoLookups(fi, link)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\thdr.Format = tar.FormatPAX\n\thdr.ModTime = hdr.ModTime.Truncate(time.Second)\n\thdr.AccessTime = time.Time{}\n\thdr.ChangeTime = time.Time{}\n\thdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))\n\thdr.Name = canonicalTarName(name, fi.IsDir())\n\treturn hdr, nil\n}\n\nconst paxSchilyXattr = \"SCHILY.xattr.\"\n\n// ReadSecurityXattrToTarHeader reads security.capability xattr from filesystem\n// to a tar header\nfunc ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {\n\tconst (\n\t\t// Values based on linux/include/uapi/linux/capability.h\n\t\txattrCapsSz2    = 20\n\t\tversionOffset   = 3\n\t\tvfsCapRevision2 = 2\n\t\tvfsCapRevision3 = 3\n\t)\n\tcapability, _ := system.Lgetxattr(path, \"security.capability\")\n\tif capability != nil {\n\t\tif capability[versionOffset] == vfsCapRevision3 {\n\t\t\t// Convert VFS_CAP_REVISION_3 to VFS_CAP_REVISION_2 as root UID makes no\n\t\t\t// sense outside the user namespace the archive is built in.\n\t\t\tcapability[versionOffset] = vfsCapRevision2\n\t\t\tcapability = capability[:xattrCapsSz2]\n\t\t}\n\t\tif hdr.PAXRecords == nil {\n\t\t\thdr.PAXRecords = make(map[string]string)\n\t\t}\n\t\thdr.PAXRecords[paxSchilyXattr+\"security.capability\"] = string(capability)\n\t}\n\treturn nil\n}\n\ntype tarWhiteoutConverter interface {\n\tConvertWrite(*tar.Header, string, os.FileInfo) (*tar.Header, error)\n\tConvertRead(*tar.Header, string) (bool, error)\n}\n\ntype tarAppender struct {\n\tTarWriter *tar.Writer\n\tBuffer    *bufio.Writer\n\n\t// for hardlink mapping\n\tSeenFiles       map[uint64]string\n\tIdentityMapping idtools.IdentityMapping\n\tChownOpts       *idtools.Identity\n\n\t// For packing and unpacking whiteout files in the\n\t// non standard format. The whiteout files defined\n\t// by the AUFS standard are used as the tar whiteout\n\t// standard.\n\tWhiteoutConverter tarWhiteoutConverter\n}\n\nfunc newTarAppender(idMapping idtools.IdentityMapping, writer io.Writer, chownOpts *idtools.Identity) *tarAppender {\n\treturn &tarAppender{\n\t\tSeenFiles:       make(map[uint64]string),\n\t\tTarWriter:       tar.NewWriter(writer),\n\t\tBuffer:          pools.BufioWriter32KPool.Get(nil),\n\t\tIdentityMapping: idMapping,\n\t\tChownOpts:       chownOpts,\n\t}\n}\n\n// CanonicalTarNameForPath canonicalizes relativePath to a POSIX-style path using\n// forward slashes. It is an alias for filepath.ToSlash, which is a no-op on\n// Linux and Unix.\nfunc CanonicalTarNameForPath(relativePath string) string {\n\treturn filepath.ToSlash(relativePath)\n}\n\n// canonicalTarName provides a platform-independent and consistent POSIX-style\n// path for files and directories to be archived regardless of the platform.\nfunc canonicalTarName(name string, isDir bool) string {\n\tname = filepath.ToSlash(name)\n\n\t// suffix with '/' for directories\n\tif isDir && !strings.HasSuffix(name, \"/\") {\n\t\tname += \"/\"\n\t}\n\treturn name\n}\n\n// addTarFile adds to the tar archive a file from `path` as `name`\nfunc (ta *tarAppender) addTarFile(path, name string) error {\n\tfi, err := os.Lstat(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar link string\n\tif fi.Mode()&os.ModeSymlink != 0 {\n\t\tvar err error\n\t\tlink, err = os.Readlink(path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\thdr, err := FileInfoHeader(name, fi, link)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := ReadSecurityXattrToTarHeader(path, hdr); err != nil {\n\t\treturn err\n\t}\n\n\t// if it's not a directory and has more than 1 link,\n\t// it's hard linked, so set the type flag accordingly\n\tif !fi.IsDir() && hasHardlinks(fi) {\n\t\tinode, err := getInodeFromStat(fi.Sys())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t// a link should have a name that it links too\n\t\t// and that linked name should be first in the tar archive\n\t\tif oldpath, ok := ta.SeenFiles[inode]; ok {\n\t\t\thdr.Typeflag = tar.TypeLink\n\t\t\thdr.Linkname = oldpath\n\t\t\thdr.Size = 0 // This Must be here for the writer math to add up!\n\t\t} else {\n\t\t\tta.SeenFiles[inode] = name\n\t\t}\n\t}\n\n\t// check whether the file is overlayfs whiteout\n\t// if yes, skip re-mapping container ID mappings.\n\tisOverlayWhiteout := fi.Mode()&os.ModeCharDevice != 0 && hdr.Devmajor == 0 && hdr.Devminor == 0\n\n\t// handle re-mapping container ID mappings back to host ID mappings before\n\t// writing tar headers/files. We skip whiteout files because they were written\n\t// by the kernel and already have proper ownership relative to the host\n\tif !isOverlayWhiteout && !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IdentityMapping.Empty() {\n\t\tfileIDPair, err := getFileUIDGID(fi.Sys())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\thdr.Uid, hdr.Gid, err = ta.IdentityMapping.ToContainer(fileIDPair)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// explicitly override with ChownOpts\n\tif ta.ChownOpts != nil {\n\t\thdr.Uid = ta.ChownOpts.UID\n\t\thdr.Gid = ta.ChownOpts.GID\n\t}\n\n\tif ta.WhiteoutConverter != nil {\n\t\two, err := ta.WhiteoutConverter.ConvertWrite(hdr, path, fi)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// If a new whiteout file exists, write original hdr, then\n\t\t// replace hdr with wo to be written after. Whiteouts should\n\t\t// always be written after the original. Note the original\n\t\t// hdr may have been updated to be a whiteout with returning\n\t\t// a whiteout header\n\t\tif wo != nil {\n\t\t\tif err := ta.TarWriter.WriteHeader(hdr); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {\n\t\t\t\treturn fmt.Errorf(\"tar: cannot use whiteout for non-empty file\")\n\t\t\t}\n\t\t\thdr = wo\n\t\t}\n\t}\n\n\tif err := ta.TarWriter.WriteHeader(hdr); err != nil {\n\t\treturn err\n\t}\n\n\tif hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {\n\t\t// We use sequential file access to avoid depleting the standby list on\n\t\t// Windows. On Linux, this equates to a regular os.Open.\n\t\tfile, err := sequential.Open(path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tta.Buffer.Reset(ta.TarWriter)\n\t\tdefer ta.Buffer.Reset(nil)\n\t\t_, err = io.Copy(ta.Buffer, file)\n\t\tfile.Close()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = ta.Buffer.Flush()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, opts *TarOptions) error {\n\tvar (\n\t\tLchown                     = true\n\t\tinUserns, bestEffortXattrs bool\n\t\tchownOpts                  *idtools.Identity\n\t)\n\tif opts != nil {\n\t\tLchown = !opts.NoLchown\n\t\tinUserns = opts.InUserNS\n\t\tchownOpts = opts.ChownOpts\n\t\tbestEffortXattrs = opts.BestEffortXattrs\n\t}\n\n\t// hdr.Mode is in linux format, which we can use for sycalls,\n\t// but for os.Foo() calls we need the mode converted to os.FileMode,\n\t// so use hdrInfo.Mode() (they differ for e.g. setuid bits)\n\thdrInfo := hdr.FileInfo()\n\n\tswitch hdr.Typeflag {\n\tcase tar.TypeDir:\n\t\t// Create directory unless it exists as a directory already.\n\t\t// In that case we just want to merge the two\n\t\tif fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) {\n\t\t\tif err := os.Mkdir(path, hdrInfo.Mode()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\tcase tar.TypeReg:\n\t\t// Source is regular file. We use sequential file access to avoid depleting\n\t\t// the standby list on Windows. On Linux, this equates to a regular os.OpenFile.\n\t\tfile, err := sequential.OpenFile(path, os.O_CREATE|os.O_WRONLY, hdrInfo.Mode())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := io.Copy(file, reader); err != nil {\n\t\t\tfile.Close()\n\t\t\treturn err\n\t\t}\n\t\tfile.Close()\n\n\tcase tar.TypeBlock, tar.TypeChar:\n\t\tif inUserns { // cannot create devices in a userns\n\t\t\treturn nil\n\t\t}\n\t\t// Handle this is an OS-specific way\n\t\tif err := handleTarTypeBlockCharFifo(hdr, path); err != nil {\n\t\t\treturn err\n\t\t}\n\n\tcase tar.TypeFifo:\n\t\t// Handle this is an OS-specific way\n\t\tif err := handleTarTypeBlockCharFifo(hdr, path); err != nil {\n\t\t\treturn err\n\t\t}\n\n\tcase tar.TypeLink:\n\t\t// #nosec G305 -- The target path is checked for path traversal.\n\t\ttargetPath := filepath.Join(extractDir, hdr.Linkname)\n\t\t// check for hardlink breakout\n\t\tif !strings.HasPrefix(targetPath, extractDir) {\n\t\t\treturn breakoutError(fmt.Errorf(\"invalid hardlink %q -> %q\", targetPath, hdr.Linkname))\n\t\t}\n\t\tif err := os.Link(targetPath, path); err != nil {\n\t\t\treturn err\n\t\t}\n\n\tcase tar.TypeSymlink:\n\t\t// \tpath \t\t\t\t-> hdr.Linkname = targetPath\n\t\t// e.g. /extractDir/path/to/symlink \t-> ../2/file\t= /extractDir/path/2/file\n\t\ttargetPath := filepath.Join(filepath.Dir(path), hdr.Linkname) // #nosec G305 -- The target path is checked for path traversal.\n\n\t\t// the reason we don't need to check symlinks in the path (with FollowSymlinkInScope) is because\n\t\t// that symlink would first have to be created, which would be caught earlier, at this very check:\n\t\tif !strings.HasPrefix(targetPath, extractDir) {\n\t\t\treturn breakoutError(fmt.Errorf(\"invalid symlink %q -> %q\", path, hdr.Linkname))\n\t\t}\n\t\tif err := os.Symlink(hdr.Linkname, path); err != nil {\n\t\t\treturn err\n\t\t}\n\n\tcase tar.TypeXGlobalHeader:\n\t\tlog.G(context.TODO()).Debug(\"PAX Global Extended Headers found and ignored\")\n\t\treturn nil\n\n\tdefault:\n\t\treturn fmt.Errorf(\"unhandled tar header type %d\", hdr.Typeflag)\n\t}\n\n\t// Lchown is not supported on Windows.\n\tif Lchown && runtime.GOOS != \"windows\" {\n\t\tif chownOpts == nil {\n\t\t\tchownOpts = &idtools.Identity{UID: hdr.Uid, GID: hdr.Gid}\n\t\t}\n\t\tif err := os.Lchown(path, chownOpts.UID, chownOpts.GID); err != nil {\n\t\t\tmsg := \"failed to Lchown %q for UID %d, GID %d\"\n\t\t\tif errors.Is(err, syscall.EINVAL) && userns.RunningInUserNS() {\n\t\t\t\tmsg += \" (try increasing the number of subordinate IDs in /etc/subuid and /etc/subgid)\"\n\t\t\t}\n\t\t\treturn errors.Wrapf(err, msg, path, hdr.Uid, hdr.Gid)\n\t\t}\n\t}\n\n\tvar xattrErrs []string\n\tfor key, value := range hdr.PAXRecords {\n\t\txattr, ok := strings.CutPrefix(key, paxSchilyXattr)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tif err := system.Lsetxattr(path, xattr, []byte(value), 0); err != nil {\n\t\t\tif bestEffortXattrs && errors.Is(err, syscall.ENOTSUP) || errors.Is(err, syscall.EPERM) {\n\t\t\t\t// EPERM occurs if modifying xattrs is not allowed. This can\n\t\t\t\t// happen when running in userns with restrictions (ChromeOS).\n\t\t\t\txattrErrs = append(xattrErrs, err.Error())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif len(xattrErrs) > 0 {\n\t\tlog.G(context.TODO()).WithFields(log.Fields{\n\t\t\t\"errors\": xattrErrs,\n\t\t}).Warn(\"ignored xattrs in archive: underlying filesystem doesn't support them\")\n\t}\n\n\t// There is no LChmod, so ignore mode for symlink. Also, this\n\t// must happen after chown, as that can modify the file mode\n\tif err := handleLChmod(hdr, path, hdrInfo); err != nil {\n\t\treturn err\n\t}\n\n\taTime := hdr.AccessTime\n\tif aTime.Before(hdr.ModTime) {\n\t\t// Last access time should never be before last modified time.\n\t\taTime = hdr.ModTime\n\t}\n\n\t// system.Chtimes doesn't support a NOFOLLOW flag atm\n\tif hdr.Typeflag == tar.TypeLink {\n\t\tif fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {\n\t\t\tif err := system.Chtimes(path, aTime, hdr.ModTime); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t} else if hdr.Typeflag != tar.TypeSymlink {\n\t\tif err := system.Chtimes(path, aTime, hdr.ModTime); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tts := []syscall.Timespec{timeToTimespec(aTime), timeToTimespec(hdr.ModTime)}\n\t\tif err := system.LUtimesNano(path, ts); err != nil && err != system.ErrNotSupportedPlatform {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Tar creates an archive from the directory at `path`, and returns it as a\n// stream of bytes.\nfunc Tar(path string, compression Compression) (io.ReadCloser, error) {\n\treturn TarWithOptions(path, &TarOptions{Compression: compression})\n}\n\n// TarWithOptions creates an archive from the directory at `path`, only including files whose relative\n// paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`.\nfunc TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {\n\ttb, err := NewTarballer(srcPath, options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgo tb.Do()\n\treturn tb.Reader(), nil\n}\n\n// Tarballer is a lower-level interface to TarWithOptions which gives the caller\n// control over which goroutine the archiving operation executes on.\ntype Tarballer struct {\n\tsrcPath           string\n\toptions           *TarOptions\n\tpm                *patternmatcher.PatternMatcher\n\tpipeReader        *io.PipeReader\n\tpipeWriter        *io.PipeWriter\n\tcompressWriter    io.WriteCloser\n\twhiteoutConverter tarWhiteoutConverter\n}\n\n// NewTarballer constructs a new tarballer. The arguments are the same as for\n// TarWithOptions.\nfunc NewTarballer(srcPath string, options *TarOptions) (*Tarballer, error) {\n\tpm, err := patternmatcher.New(options.ExcludePatterns)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpipeReader, pipeWriter := io.Pipe()\n\n\tcompressWriter, err := CompressStream(pipeWriter, options.Compression)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\twhiteoutConverter, err := getWhiteoutConverter(options.WhiteoutFormat, options.InUserNS)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &Tarballer{\n\t\t// Fix the source path to work with long path names. This is a no-op\n\t\t// on platforms other than Windows.\n\t\tsrcPath:           fixVolumePathPrefix(srcPath),\n\t\toptions:           options,\n\t\tpm:                pm,\n\t\tpipeReader:        pipeReader,\n\t\tpipeWriter:        pipeWriter,\n\t\tcompressWriter:    compressWriter,\n\t\twhiteoutConverter: whiteoutConverter,\n\t}, nil\n}\n\n// Reader returns the reader for the created archive.\nfunc (t *Tarballer) Reader() io.ReadCloser {\n\treturn t.pipeReader\n}\n\n// Do performs the archiving operation in the background. The resulting archive\n// can be read from t.Reader(). Do should only be called once on each Tarballer\n// instance.\nfunc (t *Tarballer) Do() {\n\tta := newTarAppender(\n\t\tt.options.IDMap,\n\t\tt.compressWriter,\n\t\tt.options.ChownOpts,\n\t)\n\tta.WhiteoutConverter = t.whiteoutConverter\n\n\tdefer func() {\n\t\t// Make sure to check the error on Close.\n\t\tif err := ta.TarWriter.Close(); err != nil {\n\t\t\tlog.G(context.TODO()).Errorf(\"Can't close tar writer: %s\", err)\n\t\t}\n\t\tif err := t.compressWriter.Close(); err != nil {\n\t\t\tlog.G(context.TODO()).Errorf(\"Can't close compress writer: %s\", err)\n\t\t}\n\t\tif err := t.pipeWriter.Close(); err != nil {\n\t\t\tlog.G(context.TODO()).Errorf(\"Can't close pipe writer: %s\", err)\n\t\t}\n\t}()\n\n\t// this buffer is needed for the duration of this piped stream\n\tdefer pools.BufioWriter32KPool.Put(ta.Buffer)\n\n\t// In general we log errors here but ignore them because\n\t// during e.g. a diff operation the container can continue\n\t// mutating the filesystem and we can see transient errors\n\t// from this\n\n\tstat, err := os.Lstat(t.srcPath)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif !stat.IsDir() {\n\t\t// We can't later join a non-dir with any includes because the\n\t\t// 'walk' will error if \"file/.\" is stat-ed and \"file\" is not a\n\t\t// directory. So, we must split the source path and use the\n\t\t// basename as the include.\n\t\tif len(t.options.IncludeFiles) > 0 {\n\t\t\tlog.G(context.TODO()).Warn(\"Tar: Can't archive a file with includes\")\n\t\t}\n\n\t\tdir, base := SplitPathDirEntry(t.srcPath)\n\t\tt.srcPath = dir\n\t\tt.options.IncludeFiles = []string{base}\n\t}\n\n\tif len(t.options.IncludeFiles) == 0 {\n\t\tt.options.IncludeFiles = []string{\".\"}\n\t}\n\n\tseen := make(map[string]bool)\n\n\tfor _, include := range t.options.IncludeFiles {\n\t\trebaseName := t.options.RebaseNames[include]\n\n\t\tvar (\n\t\t\tparentMatchInfo []patternmatcher.MatchInfo\n\t\t\tparentDirs      []string\n\t\t)\n\n\t\twalkRoot := getWalkRoot(t.srcPath, include)\n\t\tfilepath.WalkDir(walkRoot, func(filePath string, f os.DirEntry, err error) error {\n\t\t\tif err != nil {\n\t\t\t\tlog.G(context.TODO()).Errorf(\"Tar: Can't stat file %s to tar: %s\", t.srcPath, err)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\trelFilePath, err := filepath.Rel(t.srcPath, filePath)\n\t\t\tif err != nil || (!t.options.IncludeSourceDir && relFilePath == \".\" && f.IsDir()) {\n\t\t\t\t// Error getting relative path OR we are looking\n\t\t\t\t// at the source directory path. Skip in both situations.\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tif t.options.IncludeSourceDir && include == \".\" && relFilePath != \".\" {\n\t\t\t\trelFilePath = strings.Join([]string{\".\", relFilePath}, string(filepath.Separator))\n\t\t\t}\n\n\t\t\tskip := false\n\n\t\t\t// If \"include\" is an exact match for the current file\n\t\t\t// then even if there's an \"excludePatterns\" pattern that\n\t\t\t// matches it, don't skip it. IOW, assume an explicit 'include'\n\t\t\t// is asking for that file no matter what - which is true\n\t\t\t// for some files, like .dockerignore and Dockerfile (sometimes)\n\t\t\tif include != relFilePath {\n\t\t\t\tfor len(parentDirs) != 0 {\n\t\t\t\t\tlastParentDir := parentDirs[len(parentDirs)-1]\n\t\t\t\t\tif strings.HasPrefix(relFilePath, lastParentDir+string(os.PathSeparator)) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tparentDirs = parentDirs[:len(parentDirs)-1]\n\t\t\t\t\tparentMatchInfo = parentMatchInfo[:len(parentMatchInfo)-1]\n\t\t\t\t}\n\n\t\t\t\tvar matchInfo patternmatcher.MatchInfo\n\t\t\t\tif len(parentMatchInfo) != 0 {\n\t\t\t\t\tskip, matchInfo, err = t.pm.MatchesUsingParentResults(relFilePath, parentMatchInfo[len(parentMatchInfo)-1])\n\t\t\t\t} else {\n\t\t\t\t\tskip, matchInfo, err = t.pm.MatchesUsingParentResults(relFilePath, patternmatcher.MatchInfo{})\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.G(context.TODO()).Errorf(\"Error matching %s: %v\", relFilePath, err)\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tif f.IsDir() {\n\t\t\t\t\tparentDirs = append(parentDirs, relFilePath)\n\t\t\t\t\tparentMatchInfo = append(parentMatchInfo, matchInfo)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif skip {\n\t\t\t\t// If we want to skip this file and its a directory\n\t\t\t\t// then we should first check to see if there's an\n\t\t\t\t// excludes pattern (e.g. !dir/file) that starts with this\n\t\t\t\t// dir. If so then we can't skip this dir.\n\n\t\t\t\t// Its not a dir then so we can just return/skip.\n\t\t\t\tif !f.IsDir() {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\t// No exceptions (!...) in patterns so just skip dir\n\t\t\t\tif !t.pm.Exclusions() {\n\t\t\t\t\treturn filepath.SkipDir\n\t\t\t\t}\n\n\t\t\t\tdirSlash := relFilePath + string(filepath.Separator)\n\n\t\t\t\tfor _, pat := range t.pm.Patterns() {\n\t\t\t\t\tif !pat.Exclusion() {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif strings.HasPrefix(pat.String()+string(filepath.Separator), dirSlash) {\n\t\t\t\t\t\t// found a match - so can't skip this dir\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// No matching exclusion dir so just skip dir\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\n\t\t\tif seen[relFilePath] {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tseen[relFilePath] = true\n\n\t\t\t// Rename the base resource.\n\t\t\tif rebaseName != \"\" {\n\t\t\t\tvar replacement string\n\t\t\t\tif rebaseName != string(filepath.Separator) {\n\t\t\t\t\t// Special case the root directory to replace with an\n\t\t\t\t\t// empty string instead so that we don't end up with\n\t\t\t\t\t// double slashes in the paths.\n\t\t\t\t\treplacement = rebaseName\n\t\t\t\t}\n\n\t\t\t\trelFilePath = strings.Replace(relFilePath, include, replacement, 1)\n\t\t\t}\n\n\t\t\tif err := ta.addTarFile(filePath, relFilePath); err != nil {\n\t\t\t\tlog.G(context.TODO()).Errorf(\"Can't add file %s to tar: %s\", filePath, err)\n\t\t\t\t// if pipe is broken, stop writing tar stream to it\n\t\t\t\tif err == io.ErrClosedPipe {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t})\n\t}\n}\n\n// Unpack unpacks the decompressedArchive to dest with options.\nfunc Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) error {\n\ttr := tar.NewReader(decompressedArchive)\n\ttrBuf := pools.BufioReader32KPool.Get(nil)\n\tdefer pools.BufioReader32KPool.Put(trBuf)\n\n\tvar dirs []*tar.Header\n\twhiteoutConverter, err := getWhiteoutConverter(options.WhiteoutFormat, options.InUserNS)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Iterate through the files in the archive.\nloop:\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\t// end of tar archive\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// ignore XGlobalHeader early to avoid creating parent directories for them\n\t\tif hdr.Typeflag == tar.TypeXGlobalHeader {\n\t\t\tlog.G(context.TODO()).Debugf(\"PAX Global Extended Headers found for %s and ignored\", hdr.Name)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Normalize name, for safety and for a simple is-root check\n\t\t// This keeps \"../\" as-is, but normalizes \"/../\" to \"/\". Or Windows:\n\t\t// This keeps \"..\\\" as-is, but normalizes \"\\..\\\" to \"\\\".\n\t\thdr.Name = filepath.Clean(hdr.Name)\n\n\t\tfor _, exclude := range options.ExcludePatterns {\n\t\t\tif strings.HasPrefix(hdr.Name, exclude) {\n\t\t\t\tcontinue loop\n\t\t\t}\n\t\t}\n\n\t\t// Ensure that the parent directory exists.\n\t\terr = createImpliedDirectories(dest, hdr, options)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// #nosec G305 -- The joined path is checked for path traversal.\n\t\tpath := filepath.Join(dest, hdr.Name)\n\t\trel, err := filepath.Rel(dest, path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif strings.HasPrefix(rel, \"..\"+string(os.PathSeparator)) {\n\t\t\treturn breakoutError(fmt.Errorf(\"%q is outside of %q\", hdr.Name, dest))\n\t\t}\n\n\t\t// If path exits we almost always just want to remove and replace it\n\t\t// The only exception is when it is a directory *and* the file from\n\t\t// the layer is also a directory. Then we want to merge them (i.e.\n\t\t// just apply the metadata from the layer).\n\t\tif fi, err := os.Lstat(path); err == nil {\n\t\t\tif options.NoOverwriteDirNonDir && fi.IsDir() && hdr.Typeflag != tar.TypeDir {\n\t\t\t\t// If NoOverwriteDirNonDir is true then we cannot replace\n\t\t\t\t// an existing directory with a non-directory from the archive.\n\t\t\t\treturn fmt.Errorf(\"cannot overwrite directory %q with non-directory %q\", path, dest)\n\t\t\t}\n\n\t\t\tif options.NoOverwriteDirNonDir && !fi.IsDir() && hdr.Typeflag == tar.TypeDir {\n\t\t\t\t// If NoOverwriteDirNonDir is true then we cannot replace\n\t\t\t\t// an existing non-directory with a directory from the archive.\n\t\t\t\treturn fmt.Errorf(\"cannot overwrite non-directory %q with directory %q\", path, dest)\n\t\t\t}\n\n\t\t\tif fi.IsDir() && hdr.Name == \".\" {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !(fi.IsDir() && hdr.Typeflag == tar.TypeDir) {\n\t\t\t\tif err := os.RemoveAll(path); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttrBuf.Reset(tr)\n\n\t\tif err := remapIDs(options.IDMap, hdr); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif whiteoutConverter != nil {\n\t\t\twriteFile, err := whiteoutConverter.ConvertRead(hdr, path)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif !writeFile {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif err := createTarFile(path, dest, hdr, trBuf, options); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Directory mtimes must be handled at the end to avoid further\n\t\t// file creation in them to modify the directory mtime\n\t\tif hdr.Typeflag == tar.TypeDir {\n\t\t\tdirs = append(dirs, hdr)\n\t\t}\n\t}\n\n\tfor _, hdr := range dirs {\n\t\t// #nosec G305 -- The header was checked for path traversal before it was appended to the dirs slice.\n\t\tpath := filepath.Join(dest, hdr.Name)\n\n\t\tif err := system.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// createImpliedDirectories will create all parent directories of the current path with default permissions, if they do\n// not already exist. This is possible as the tar format supports 'implicit' directories, where their existence is\n// defined by the paths of files in the tar, but there are no header entries for the directories themselves, and thus\n// we most both create them and choose metadata like permissions.\n//\n// The caller should have performed filepath.Clean(hdr.Name), so hdr.Name will now be in the filepath format for the OS\n// on which the daemon is running. This precondition is required because this function assumes a OS-specific path\n// separator when checking that a path is not the root.\nfunc createImpliedDirectories(dest string, hdr *tar.Header, options *TarOptions) error {\n\t// Not the root directory, ensure that the parent directory exists\n\tif !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) {\n\t\tparent := filepath.Dir(hdr.Name)\n\t\tparentPath := filepath.Join(dest, parent)\n\t\tif _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {\n\t\t\t// RootPair() is confined inside this loop as most cases will not require a call, so we can spend some\n\t\t\t// unneeded function calls in the uncommon case to encapsulate logic -- implied directories are a niche\n\t\t\t// usage that reduces the portability of an image.\n\t\t\trootIDs := options.IDMap.RootPair()\n\n\t\t\terr = idtools.MkdirAllAndChownNew(parentPath, ImpliedDirectoryMode, rootIDs)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Untar reads a stream of bytes from `archive`, parses it as a tar archive,\n// and unpacks it into the directory at `dest`.\n// The archive may be compressed with one of the following algorithms:\n// identity (uncompressed), gzip, bzip2, xz.\n//\n// FIXME: specify behavior when target path exists vs. doesn't exist.\nfunc Untar(tarArchive io.Reader, dest string, options *TarOptions) error {\n\treturn untarHandler(tarArchive, dest, options, true)\n}\n\n// UntarUncompressed reads a stream of bytes from `archive`, parses it as a tar archive,\n// and unpacks it into the directory at `dest`.\n// The archive must be an uncompressed stream.\nfunc UntarUncompressed(tarArchive io.Reader, dest string, options *TarOptions) error {\n\treturn untarHandler(tarArchive, dest, options, false)\n}\n\n// Handler for teasing out the automatic decompression\nfunc untarHandler(tarArchive io.Reader, dest string, options *TarOptions, decompress bool) error {\n\tif tarArchive == nil {\n\t\treturn fmt.Errorf(\"Empty archive\")\n\t}\n\tdest = filepath.Clean(dest)\n\tif options == nil {\n\t\toptions = &TarOptions{}\n\t}\n\tif options.ExcludePatterns == nil {\n\t\toptions.ExcludePatterns = []string{}\n\t}\n\n\tr := tarArchive\n\tif decompress {\n\t\tdecompressedArchive, err := DecompressStream(tarArchive)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer decompressedArchive.Close()\n\t\tr = decompressedArchive\n\t}\n\n\treturn Unpack(r, dest, options)\n}\n\n// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other.\n// If either Tar or Untar fails, TarUntar aborts and returns the error.\nfunc (archiver *Archiver) TarUntar(src, dst string) error {\n\tarchive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed})\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer archive.Close()\n\toptions := &TarOptions{\n\t\tIDMap: archiver.IDMapping,\n\t}\n\treturn archiver.Untar(archive, dst, options)\n}\n\n// UntarPath untar a file from path to a destination, src is the source tar file path.\nfunc (archiver *Archiver) UntarPath(src, dst string) error {\n\tarchive, err := os.Open(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer archive.Close()\n\toptions := &TarOptions{\n\t\tIDMap: archiver.IDMapping,\n\t}\n\treturn archiver.Untar(archive, dst, options)\n}\n\n// CopyWithTar creates a tar archive of filesystem path `src`, and\n// unpacks it at filesystem path `dst`.\n// The archive is streamed directly with fixed buffering and no\n// intermediary disk IO.\nfunc (archiver *Archiver) CopyWithTar(src, dst string) error {\n\tsrcSt, err := os.Stat(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !srcSt.IsDir() {\n\t\treturn archiver.CopyFileWithTar(src, dst)\n\t}\n\n\t// if this Archiver is set up with ID mapping we need to create\n\t// the new destination directory with the remapped root UID/GID pair\n\t// as owner\n\trootIDs := archiver.IDMapping.RootPair()\n\t// Create dst, copy src's content into it\n\tif err := idtools.MkdirAllAndChownNew(dst, 0o755, rootIDs); err != nil {\n\t\treturn err\n\t}\n\treturn archiver.TarUntar(src, dst)\n}\n\n// CopyFileWithTar emulates the behavior of the 'cp' command-line\n// for a single file. It copies a regular file from path `src` to\n// path `dst`, and preserves all its metadata.\nfunc (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {\n\tsrcSt, err := os.Stat(src)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif srcSt.IsDir() {\n\t\treturn fmt.Errorf(\"Can't copy a directory\")\n\t}\n\n\t// Clean up the trailing slash. This must be done in an operating\n\t// system specific manner.\n\tif dst[len(dst)-1] == os.PathSeparator {\n\t\tdst = filepath.Join(dst, filepath.Base(src))\n\t}\n\t// Create the holding directory if necessary\n\tif err := system.MkdirAll(filepath.Dir(dst), 0o700); err != nil {\n\t\treturn err\n\t}\n\n\tr, w := io.Pipe()\n\terrC := make(chan error, 1)\n\n\tgo func() {\n\t\tdefer close(errC)\n\n\t\terrC <- func() error {\n\t\t\tdefer w.Close()\n\n\t\t\tsrcF, err := os.Open(src)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer srcF.Close()\n\n\t\t\thdr, err := FileInfoHeaderNoLookups(srcSt, \"\")\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\thdr.Format = tar.FormatPAX\n\t\t\thdr.ModTime = hdr.ModTime.Truncate(time.Second)\n\t\t\thdr.AccessTime = time.Time{}\n\t\t\thdr.ChangeTime = time.Time{}\n\t\t\thdr.Name = filepath.Base(dst)\n\t\t\thdr.Mode = int64(chmodTarEntry(os.FileMode(hdr.Mode)))\n\n\t\t\tif err := remapIDs(archiver.IDMapping, hdr); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\ttw := tar.NewWriter(w)\n\t\t\tdefer tw.Close()\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 := io.Copy(tw, srcF); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn nil\n\t\t}()\n\t}()\n\tdefer func() {\n\t\tif er := <-errC; err == nil && er != nil {\n\t\t\terr = er\n\t\t}\n\t}()\n\n\terr = archiver.Untar(r, filepath.Dir(dst), nil)\n\tif err != nil {\n\t\tr.CloseWithError(err)\n\t}\n\treturn err\n}\n\n// IdentityMapping returns the IdentityMapping of the archiver.\nfunc (archiver *Archiver) IdentityMapping() idtools.IdentityMapping {\n\treturn archiver.IDMapping\n}\n\nfunc remapIDs(idMapping idtools.IdentityMapping, hdr *tar.Header) error {\n\tids, err := idMapping.ToHost(idtools.Identity{UID: hdr.Uid, GID: hdr.Gid})\n\thdr.Uid, hdr.Gid = ids.UID, ids.GID\n\treturn err\n}\n\n// cmdStream executes a command, and returns its stdout as a stream.\n// If the command fails to run or doesn't complete successfully, an error\n// will be returned, including anything written on stderr.\nfunc cmdStream(cmd *exec.Cmd, input io.Reader) (io.ReadCloser, error) {\n\tcmd.Stdin = input\n\tpipeR, pipeW := io.Pipe()\n\tcmd.Stdout = pipeW\n\tvar errBuf bytes.Buffer\n\tcmd.Stderr = &errBuf\n\n\t// Run the command and return the pipe\n\tif err := cmd.Start(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Ensure the command has exited before we clean anything up\n\tdone := make(chan struct{})\n\n\t// Copy stdout to the returned pipe\n\tgo func() {\n\t\tif err := cmd.Wait(); err != nil {\n\t\t\tpipeW.CloseWithError(fmt.Errorf(\"%s: %s\", err, errBuf.String()))\n\t\t} else {\n\t\t\tpipeW.Close()\n\t\t}\n\t\tclose(done)\n\t}()\n\n\treturn ioutils.NewReadCloserWrapper(pipeR, func() error {\n\t\t// Close pipeR, and then wait for the command to complete before returning. We have to close pipeR first, as\n\t\t// cmd.Wait waits for any non-file stdout/stderr/stdin to close.\n\t\terr := pipeR.Close()\n\t\t<-done\n\t\treturn err\n\t}), nil\n}\n\n// NewTempArchive reads the content of src into a temporary file, and returns the contents\n// of that file as an archive. The archive can only be read once - as soon as reading completes,\n// the file will be deleted.\nfunc NewTempArchive(src io.Reader, dir string) (*TempArchive, error) {\n\tf, err := os.CreateTemp(dir, \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err := io.Copy(f, src); err != nil {\n\t\treturn nil, err\n\t}\n\tif _, err := f.Seek(0, 0); err != nil {\n\t\treturn nil, err\n\t}\n\tst, err := f.Stat()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsize := st.Size()\n\treturn &TempArchive{File: f, Size: size}, nil\n}\n\n// TempArchive is a temporary archive. The archive can only be read once - as soon as reading completes,\n// the file will be deleted.\ntype TempArchive struct {\n\t*os.File\n\tSize   int64 // Pre-computed from Stat().Size() as a convenience\n\tread   int64\n\tclosed bool\n}\n\n// Close closes the underlying file if it's still open, or does a no-op\n// to allow callers to try to close the TempArchive multiple times safely.\nfunc (archive *TempArchive) Close() error {\n\tif archive.closed {\n\t\treturn nil\n\t}\n\n\tarchive.closed = true\n\n\treturn archive.File.Close()\n}\n\nfunc (archive *TempArchive) Read(data []byte) (int, error) {\n\tn, err := archive.File.Read(data)\n\tarchive.read += int64(n)\n\tif err != nil || archive.read == archive.Size {\n\t\tarchive.Close()\n\t\tos.Remove(archive.File.Name())\n\t}\n\treturn n, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/archive_linux.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/pkg/system\"\n\t\"github.com/pkg/errors\"\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc getWhiteoutConverter(format WhiteoutFormat, inUserNS bool) (tarWhiteoutConverter, error) {\n\tif format == OverlayWhiteoutFormat {\n\t\tif inUserNS {\n\t\t\treturn nil, errors.New(\"specifying OverlayWhiteoutFormat is not allowed in userns\")\n\t\t}\n\t\treturn overlayWhiteoutConverter{}, nil\n\t}\n\treturn nil, nil\n}\n\ntype overlayWhiteoutConverter struct{}\n\nfunc (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os.FileInfo) (wo *tar.Header, err error) {\n\t// convert whiteouts to AUFS format\n\tif fi.Mode()&os.ModeCharDevice != 0 && hdr.Devmajor == 0 && hdr.Devminor == 0 {\n\t\t// we just rename the file and make it normal\n\t\tdir, filename := filepath.Split(hdr.Name)\n\t\thdr.Name = filepath.Join(dir, WhiteoutPrefix+filename)\n\t\thdr.Mode = 0o600\n\t\thdr.Typeflag = tar.TypeReg\n\t\thdr.Size = 0\n\t}\n\n\tif fi.Mode()&os.ModeDir != 0 {\n\t\t// convert opaque dirs to AUFS format by writing an empty file with the prefix\n\t\topaque, err := system.Lgetxattr(path, \"trusted.overlay.opaque\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(opaque) == 1 && opaque[0] == 'y' {\n\t\t\tdelete(hdr.PAXRecords, paxSchilyXattr+\"trusted.overlay.opaque\")\n\n\t\t\t// create a header for the whiteout file\n\t\t\t// it should inherit some properties from the parent, but be a regular file\n\t\t\two = &tar.Header{\n\t\t\t\tTypeflag:   tar.TypeReg,\n\t\t\t\tMode:       hdr.Mode & int64(os.ModePerm),\n\t\t\t\tName:       filepath.Join(hdr.Name, WhiteoutOpaqueDir),\n\t\t\t\tSize:       0,\n\t\t\t\tUid:        hdr.Uid,\n\t\t\t\tUname:      hdr.Uname,\n\t\t\t\tGid:        hdr.Gid,\n\t\t\t\tGname:      hdr.Gname,\n\t\t\t\tAccessTime: hdr.AccessTime,\n\t\t\t\tChangeTime: hdr.ChangeTime,\n\t\t\t} //#nosec G305 -- An archive is being created, not extracted.\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc (c overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) {\n\tbase := filepath.Base(path)\n\tdir := filepath.Dir(path)\n\n\t// if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay\n\tif base == WhiteoutOpaqueDir {\n\t\terr := unix.Setxattr(dir, \"trusted.overlay.opaque\", []byte{'y'}, 0)\n\t\tif err != nil {\n\t\t\treturn false, errors.Wrapf(err, \"setxattr(%q, trusted.overlay.opaque=y)\", dir)\n\t\t}\n\t\t// don't write the file itself\n\t\treturn false, err\n\t}\n\n\t// if a file was deleted and we are using overlay, we need to create a character device\n\tif strings.HasPrefix(base, WhiteoutPrefix) {\n\t\toriginalBase := base[len(WhiteoutPrefix):]\n\t\toriginalPath := filepath.Join(dir, originalBase)\n\n\t\tif err := unix.Mknod(originalPath, unix.S_IFCHR, 0); err != nil {\n\t\t\treturn false, errors.Wrapf(err, \"failed to mknod(%q, S_IFCHR, 0)\", originalPath)\n\t\t}\n\t\tif err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\t// don't write the file itself\n\t\treturn false, nil\n\t}\n\n\treturn true, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/archive_other.go",
    "content": "//go:build !linux\n\npackage archive // import \"github.com/docker/docker/pkg/archive\"\n\nfunc getWhiteoutConverter(format WhiteoutFormat, inUserNS bool) (tarWhiteoutConverter, error) {\n\treturn nil, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/archive_unix.go",
    "content": "//go:build !windows\n\npackage archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\t\"syscall\"\n\n\t\"github.com/containerd/containerd/pkg/userns\"\n\t\"github.com/docker/docker/pkg/idtools\"\n\t\"github.com/docker/docker/pkg/system\"\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc init() {\n\tsysStat = statUnix\n}\n\n// fixVolumePathPrefix does platform specific processing to ensure that if\n// the path being passed in is not in a volume path format, convert it to one.\nfunc fixVolumePathPrefix(srcPath string) string {\n\treturn srcPath\n}\n\n// getWalkRoot calculates the root path when performing a TarWithOptions.\n// We use a separate function as this is platform specific. On Linux, we\n// can't use filepath.Join(srcPath,include) because this will clean away\n// a trailing \".\" or \"/\" which may be important.\nfunc getWalkRoot(srcPath string, include string) string {\n\treturn strings.TrimSuffix(srcPath, string(filepath.Separator)) + string(filepath.Separator) + include\n}\n\n// chmodTarEntry is used to adjust the file permissions used in tar header based\n// on the platform the archival is done.\nfunc chmodTarEntry(perm os.FileMode) os.FileMode {\n\treturn perm // noop for unix as golang APIs provide perm bits correctly\n}\n\n// statUnix populates hdr from system-dependent fields of fi without performing\n// any OS lookups.\nfunc statUnix(fi os.FileInfo, hdr *tar.Header) error {\n\t// Devmajor and Devminor are only needed for special devices.\n\n\t// In FreeBSD, RDev for regular files is -1 (unless overridden by FS):\n\t// https://cgit.freebsd.org/src/tree/sys/kern/vfs_default.c?h=stable/13#n1531\n\t// (NODEV is -1: https://cgit.freebsd.org/src/tree/sys/sys/param.h?h=stable/13#n241).\n\n\t// ZFS in particular does not override the default:\n\t// https://cgit.freebsd.org/src/tree/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c?h=stable/13#n2027\n\n\t// Since `Stat_t.Rdev` is uint64, the cast turns -1 into (2^64 - 1).\n\t// Such large values cannot be encoded in a tar header.\n\tif runtime.GOOS == \"freebsd\" && hdr.Typeflag != tar.TypeBlock && hdr.Typeflag != tar.TypeChar {\n\t\treturn nil\n\t}\n\ts, ok := fi.Sys().(*syscall.Stat_t)\n\tif !ok {\n\t\treturn nil\n\t}\n\n\thdr.Uid = int(s.Uid)\n\thdr.Gid = int(s.Gid)\n\n\tif s.Mode&unix.S_IFBLK != 0 ||\n\t\ts.Mode&unix.S_IFCHR != 0 {\n\t\thdr.Devmajor = int64(unix.Major(uint64(s.Rdev))) //nolint: unconvert\n\t\thdr.Devminor = int64(unix.Minor(uint64(s.Rdev))) //nolint: unconvert\n\t}\n\n\treturn nil\n}\n\nfunc getInodeFromStat(stat interface{}) (inode uint64, err error) {\n\ts, ok := stat.(*syscall.Stat_t)\n\n\tif ok {\n\t\tinode = s.Ino\n\t}\n\n\treturn\n}\n\nfunc getFileUIDGID(stat interface{}) (idtools.Identity, error) {\n\ts, ok := stat.(*syscall.Stat_t)\n\n\tif !ok {\n\t\treturn idtools.Identity{}, errors.New(\"cannot convert stat value to syscall.Stat_t\")\n\t}\n\treturn idtools.Identity{UID: int(s.Uid), GID: int(s.Gid)}, nil\n}\n\n// handleTarTypeBlockCharFifo is an OS-specific helper function used by\n// createTarFile to handle the following types of header: Block; Char; Fifo\nfunc handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {\n\tmode := uint32(hdr.Mode & 0o7777)\n\tswitch hdr.Typeflag {\n\tcase tar.TypeBlock:\n\t\tmode |= unix.S_IFBLK\n\tcase tar.TypeChar:\n\t\tmode |= unix.S_IFCHR\n\tcase tar.TypeFifo:\n\t\tmode |= unix.S_IFIFO\n\t}\n\n\terr := system.Mknod(path, mode, int(system.Mkdev(hdr.Devmajor, hdr.Devminor)))\n\tif errors.Is(err, syscall.EPERM) && userns.RunningInUserNS() {\n\t\t// In most cases, cannot create a device if running in user namespace\n\t\terr = nil\n\t}\n\treturn err\n}\n\nfunc handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {\n\tif hdr.Typeflag == tar.TypeLink {\n\t\tif fi, err := os.Lstat(hdr.Linkname); err == nil && (fi.Mode()&os.ModeSymlink == 0) {\n\t\t\tif err := os.Chmod(path, hdrInfo.Mode()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t} else if hdr.Typeflag != tar.TypeSymlink {\n\t\tif err := os.Chmod(path, hdrInfo.Mode()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/archive_windows.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/docker/docker/pkg/idtools\"\n\t\"github.com/docker/docker/pkg/longpath\"\n)\n\n// fixVolumePathPrefix does platform specific processing to ensure that if\n// the path being passed in is not in a volume path format, convert it to one.\nfunc fixVolumePathPrefix(srcPath string) string {\n\treturn longpath.AddPrefix(srcPath)\n}\n\n// getWalkRoot calculates the root path when performing a TarWithOptions.\n// We use a separate function as this is platform specific.\nfunc getWalkRoot(srcPath string, include string) string {\n\treturn filepath.Join(srcPath, include)\n}\n\n// chmodTarEntry is used to adjust the file permissions used in tar header based\n// on the platform the archival is done.\nfunc chmodTarEntry(perm os.FileMode) os.FileMode {\n\t// Remove group- and world-writable bits.\n\tperm &= 0o755\n\n\t// Add the x bit: make everything +x on Windows\n\treturn perm | 0o111\n}\n\nfunc setHeaderForSpecialDevice(hdr *tar.Header, name string, stat interface{}) (err error) {\n\t// do nothing. no notion of Rdev, Nlink in stat on Windows\n\treturn\n}\n\nfunc getInodeFromStat(stat interface{}) (inode uint64, err error) {\n\t// do nothing. no notion of Inode in stat on Windows\n\treturn\n}\n\n// handleTarTypeBlockCharFifo is an OS-specific helper function used by\n// createTarFile to handle the following types of header: Block; Char; Fifo\nfunc handleTarTypeBlockCharFifo(hdr *tar.Header, path string) error {\n\treturn nil\n}\n\nfunc handleLChmod(hdr *tar.Header, path string, hdrInfo os.FileInfo) error {\n\treturn nil\n}\n\nfunc getFileUIDGID(stat interface{}) (idtools.Identity, error) {\n\t// no notion of file ownership mapping yet on Windows\n\treturn idtools.Identity{UID: 0, GID: 0}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/changes.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/containerd/log\"\n\t\"github.com/docker/docker/pkg/idtools\"\n\t\"github.com/docker/docker/pkg/pools\"\n\t\"github.com/docker/docker/pkg/system\"\n)\n\n// ChangeType represents the change type.\ntype ChangeType int\n\nconst (\n\t// ChangeModify represents the modify operation.\n\tChangeModify = iota\n\t// ChangeAdd represents the add operation.\n\tChangeAdd\n\t// ChangeDelete represents the delete operation.\n\tChangeDelete\n)\n\nfunc (c ChangeType) String() string {\n\tswitch c {\n\tcase ChangeModify:\n\t\treturn \"C\"\n\tcase ChangeAdd:\n\t\treturn \"A\"\n\tcase ChangeDelete:\n\t\treturn \"D\"\n\t}\n\treturn \"\"\n}\n\n// Change represents a change, it wraps the change type and path.\n// It describes changes of the files in the path respect to the\n// parent layers. The change could be modify, add, delete.\n// This is used for layer diff.\ntype Change struct {\n\tPath string\n\tKind ChangeType\n}\n\nfunc (change *Change) String() string {\n\treturn fmt.Sprintf(\"%s %s\", change.Kind, change.Path)\n}\n\n// for sort.Sort\ntype changesByPath []Change\n\nfunc (c changesByPath) Less(i, j int) bool { return c[i].Path < c[j].Path }\nfunc (c changesByPath) Len() int           { return len(c) }\nfunc (c changesByPath) Swap(i, j int)      { c[j], c[i] = c[i], c[j] }\n\n// Gnu tar doesn't have sub-second mtime precision. The go tar\n// writer (1.10+) does when using PAX format, but we round times to seconds\n// to ensure archives have the same hashes for backwards compatibility.\n// See https://github.com/moby/moby/pull/35739/commits/fb170206ba12752214630b269a40ac7be6115ed4.\n//\n// Non-sub-second is problematic when we apply changes via tar\n// files. We handle this by comparing for exact times, *or* same\n// second count and either a or b having exactly 0 nanoseconds\nfunc sameFsTime(a, b time.Time) bool {\n\treturn a.Equal(b) ||\n\t\t(a.Unix() == b.Unix() &&\n\t\t\t(a.Nanosecond() == 0 || b.Nanosecond() == 0))\n}\n\nfunc sameFsTimeSpec(a, b syscall.Timespec) bool {\n\treturn a.Sec == b.Sec &&\n\t\t(a.Nsec == b.Nsec || a.Nsec == 0 || b.Nsec == 0)\n}\n\n// Changes walks the path rw and determines changes for the files in the path,\n// with respect to the parent layers\nfunc Changes(layers []string, rw string) ([]Change, error) {\n\treturn changes(layers, rw, aufsDeletedFile, aufsMetadataSkip)\n}\n\nfunc aufsMetadataSkip(path string) (skip bool, err error) {\n\tskip, err = filepath.Match(string(os.PathSeparator)+WhiteoutMetaPrefix+\"*\", path)\n\tif err != nil {\n\t\tskip = true\n\t}\n\treturn\n}\n\nfunc aufsDeletedFile(root, path string, fi os.FileInfo) (string, error) {\n\tf := filepath.Base(path)\n\n\t// If there is a whiteout, then the file was removed\n\tif strings.HasPrefix(f, WhiteoutPrefix) {\n\t\toriginalFile := f[len(WhiteoutPrefix):]\n\t\treturn filepath.Join(filepath.Dir(path), originalFile), nil\n\t}\n\n\treturn \"\", nil\n}\n\ntype (\n\tskipChange   func(string) (bool, error)\n\tdeleteChange func(string, string, os.FileInfo) (string, error)\n)\n\nfunc changes(layers []string, rw string, dc deleteChange, sc skipChange) ([]Change, error) {\n\tvar (\n\t\tchanges     []Change\n\t\tchangedDirs = make(map[string]struct{})\n\t)\n\n\terr := filepath.Walk(rw, func(path string, f os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Rebase path\n\t\tpath, err = filepath.Rel(rw, path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// As this runs on the daemon side, file paths are OS specific.\n\t\tpath = filepath.Join(string(os.PathSeparator), path)\n\n\t\t// Skip root\n\t\tif path == string(os.PathSeparator) {\n\t\t\treturn nil\n\t\t}\n\n\t\tif sc != nil {\n\t\t\tif skip, err := sc(path); skip {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tchange := Change{\n\t\t\tPath: path,\n\t\t}\n\n\t\tdeletedFile, err := dc(rw, path, f)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Find out what kind of modification happened\n\t\tif deletedFile != \"\" {\n\t\t\tchange.Path = deletedFile\n\t\t\tchange.Kind = ChangeDelete\n\t\t} else {\n\t\t\t// Otherwise, the file was added\n\t\t\tchange.Kind = ChangeAdd\n\n\t\t\t// ...Unless it already existed in a top layer, in which case, it's a modification\n\t\t\tfor _, layer := range layers {\n\t\t\t\tstat, err := os.Stat(filepath.Join(layer, path))\n\t\t\t\tif err != nil && !os.IsNotExist(err) {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err == nil {\n\t\t\t\t\t// The file existed in the top layer, so that's a modification\n\n\t\t\t\t\t// However, if it's a directory, maybe it wasn't actually modified.\n\t\t\t\t\t// If you modify /foo/bar/baz, then /foo will be part of the changed files only because it's the parent of bar\n\t\t\t\t\tif stat.IsDir() && f.IsDir() {\n\t\t\t\t\t\tif f.Size() == stat.Size() && f.Mode() == stat.Mode() && sameFsTime(f.ModTime(), stat.ModTime()) {\n\t\t\t\t\t\t\t// Both directories are the same, don't record the change\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tchange.Kind = ChangeModify\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If /foo/bar/file.txt is modified, then /foo/bar must be part of the changed files.\n\t\t// This block is here to ensure the change is recorded even if the\n\t\t// modify time, mode and size of the parent directory in the rw and ro layers are all equal.\n\t\t// Check https://github.com/docker/docker/pull/13590 for details.\n\t\tif f.IsDir() {\n\t\t\tchangedDirs[path] = struct{}{}\n\t\t}\n\t\tif change.Kind == ChangeAdd || change.Kind == ChangeDelete {\n\t\t\tparent := filepath.Dir(path)\n\t\t\tif _, ok := changedDirs[parent]; !ok && parent != \"/\" {\n\t\t\t\tchanges = append(changes, Change{Path: parent, Kind: ChangeModify})\n\t\t\t\tchangedDirs[parent] = struct{}{}\n\t\t\t}\n\t\t}\n\n\t\t// Record change\n\t\tchanges = append(changes, change)\n\t\treturn nil\n\t})\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn nil, err\n\t}\n\treturn changes, nil\n}\n\n// FileInfo describes the information of a file.\ntype FileInfo struct {\n\tparent     *FileInfo\n\tname       string\n\tstat       *system.StatT\n\tchildren   map[string]*FileInfo\n\tcapability []byte\n\tadded      bool\n}\n\n// LookUp looks up the file information of a file.\nfunc (info *FileInfo) LookUp(path string) *FileInfo {\n\t// As this runs on the daemon side, file paths are OS specific.\n\tparent := info\n\tif path == string(os.PathSeparator) {\n\t\treturn info\n\t}\n\n\tpathElements := strings.Split(path, string(os.PathSeparator))\n\tfor _, elem := range pathElements {\n\t\tif elem != \"\" {\n\t\t\tchild := parent.children[elem]\n\t\t\tif child == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tparent = child\n\t\t}\n\t}\n\treturn parent\n}\n\nfunc (info *FileInfo) path() string {\n\tif info.parent == nil {\n\t\t// As this runs on the daemon side, file paths are OS specific.\n\t\treturn string(os.PathSeparator)\n\t}\n\treturn filepath.Join(info.parent.path(), info.name)\n}\n\nfunc (info *FileInfo) addChanges(oldInfo *FileInfo, changes *[]Change) {\n\tsizeAtEntry := len(*changes)\n\n\tif oldInfo == nil {\n\t\t// add\n\t\tchange := Change{\n\t\t\tPath: info.path(),\n\t\t\tKind: ChangeAdd,\n\t\t}\n\t\t*changes = append(*changes, change)\n\t\tinfo.added = true\n\t}\n\n\t// We make a copy so we can modify it to detect additions\n\t// also, we only recurse on the old dir if the new info is a directory\n\t// otherwise any previous delete/change is considered recursive\n\toldChildren := make(map[string]*FileInfo)\n\tif oldInfo != nil && info.isDir() {\n\t\tfor k, v := range oldInfo.children {\n\t\t\toldChildren[k] = v\n\t\t}\n\t}\n\n\tfor name, newChild := range info.children {\n\t\toldChild := oldChildren[name]\n\t\tif oldChild != nil {\n\t\t\t// change?\n\t\t\toldStat := oldChild.stat\n\t\t\tnewStat := newChild.stat\n\t\t\t// Note: We can't compare inode or ctime or blocksize here, because these change\n\t\t\t// when copying a file into a container. However, that is not generally a problem\n\t\t\t// because any content change will change mtime, and any status change should\n\t\t\t// be visible when actually comparing the stat fields. The only time this\n\t\t\t// breaks down is if some code intentionally hides a change by setting\n\t\t\t// back mtime\n\t\t\tif statDifferent(oldStat, newStat) ||\n\t\t\t\t!bytes.Equal(oldChild.capability, newChild.capability) {\n\t\t\t\tchange := Change{\n\t\t\t\t\tPath: newChild.path(),\n\t\t\t\t\tKind: ChangeModify,\n\t\t\t\t}\n\t\t\t\t*changes = append(*changes, change)\n\t\t\t\tnewChild.added = true\n\t\t\t}\n\n\t\t\t// Remove from copy so we can detect deletions\n\t\t\tdelete(oldChildren, name)\n\t\t}\n\n\t\tnewChild.addChanges(oldChild, changes)\n\t}\n\tfor _, oldChild := range oldChildren {\n\t\t// delete\n\t\tchange := Change{\n\t\t\tPath: oldChild.path(),\n\t\t\tKind: ChangeDelete,\n\t\t}\n\t\t*changes = append(*changes, change)\n\t}\n\n\t// If there were changes inside this directory, we need to add it, even if the directory\n\t// itself wasn't changed. This is needed to properly save and restore filesystem permissions.\n\t// As this runs on the daemon side, file paths are OS specific.\n\tif len(*changes) > sizeAtEntry && info.isDir() && !info.added && info.path() != string(os.PathSeparator) {\n\t\tchange := Change{\n\t\t\tPath: info.path(),\n\t\t\tKind: ChangeModify,\n\t\t}\n\t\t// Let's insert the directory entry before the recently added entries located inside this dir\n\t\t*changes = append(*changes, change) // just to resize the slice, will be overwritten\n\t\tcopy((*changes)[sizeAtEntry+1:], (*changes)[sizeAtEntry:])\n\t\t(*changes)[sizeAtEntry] = change\n\t}\n}\n\n// Changes add changes to file information.\nfunc (info *FileInfo) Changes(oldInfo *FileInfo) []Change {\n\tvar changes []Change\n\n\tinfo.addChanges(oldInfo, &changes)\n\n\treturn changes\n}\n\nfunc newRootFileInfo() *FileInfo {\n\t// As this runs on the daemon side, file paths are OS specific.\n\troot := &FileInfo{\n\t\tname:     string(os.PathSeparator),\n\t\tchildren: make(map[string]*FileInfo),\n\t}\n\treturn root\n}\n\n// ChangesDirs compares two directories and generates an array of Change objects describing the changes.\n// If oldDir is \"\", then all files in newDir will be Add-Changes.\nfunc ChangesDirs(newDir, oldDir string) ([]Change, error) {\n\tvar oldRoot, newRoot *FileInfo\n\tif oldDir == \"\" {\n\t\temptyDir, err := os.MkdirTemp(\"\", \"empty\")\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer os.Remove(emptyDir)\n\t\toldDir = emptyDir\n\t}\n\toldRoot, newRoot, err := collectFileInfoForChanges(oldDir, newDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn newRoot.Changes(oldRoot), nil\n}\n\n// ChangesSize calculates the size in bytes of the provided changes, based on newDir.\nfunc ChangesSize(newDir string, changes []Change) int64 {\n\tvar (\n\t\tsize int64\n\t\tsf   = make(map[uint64]struct{})\n\t)\n\tfor _, change := range changes {\n\t\tif change.Kind == ChangeModify || change.Kind == ChangeAdd {\n\t\t\tfile := filepath.Join(newDir, change.Path)\n\t\t\tfileInfo, err := os.Lstat(file)\n\t\t\tif err != nil {\n\t\t\t\tlog.G(context.TODO()).Errorf(\"Can not stat %q: %s\", file, err)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif fileInfo != nil && !fileInfo.IsDir() {\n\t\t\t\tif hasHardlinks(fileInfo) {\n\t\t\t\t\tinode := getIno(fileInfo)\n\t\t\t\t\tif _, ok := sf[inode]; !ok {\n\t\t\t\t\t\tsize += fileInfo.Size()\n\t\t\t\t\t\tsf[inode] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tsize += fileInfo.Size()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn size\n}\n\n// ExportChanges produces an Archive from the provided changes, relative to dir.\nfunc ExportChanges(dir string, changes []Change, idMap idtools.IdentityMapping) (io.ReadCloser, error) {\n\treader, writer := io.Pipe()\n\tgo func() {\n\t\tta := newTarAppender(idMap, writer, nil)\n\n\t\t// this buffer is needed for the duration of this piped stream\n\t\tdefer pools.BufioWriter32KPool.Put(ta.Buffer)\n\n\t\tsort.Sort(changesByPath(changes))\n\n\t\t// In general we log errors here but ignore them because\n\t\t// during e.g. a diff operation the container can continue\n\t\t// mutating the filesystem and we can see transient errors\n\t\t// from this\n\t\tfor _, change := range changes {\n\t\t\tif change.Kind == ChangeDelete {\n\t\t\t\twhiteOutDir := filepath.Dir(change.Path)\n\t\t\t\twhiteOutBase := filepath.Base(change.Path)\n\t\t\t\twhiteOut := filepath.Join(whiteOutDir, WhiteoutPrefix+whiteOutBase)\n\t\t\t\ttimestamp := time.Now()\n\t\t\t\thdr := &tar.Header{\n\t\t\t\t\tName:       whiteOut[1:],\n\t\t\t\t\tSize:       0,\n\t\t\t\t\tModTime:    timestamp,\n\t\t\t\t\tAccessTime: timestamp,\n\t\t\t\t\tChangeTime: timestamp,\n\t\t\t\t}\n\t\t\t\tif err := ta.TarWriter.WriteHeader(hdr); err != nil {\n\t\t\t\t\tlog.G(context.TODO()).Debugf(\"Can't write whiteout header: %s\", err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tpath := filepath.Join(dir, change.Path)\n\t\t\t\tif err := ta.addTarFile(path, change.Path[1:]); err != nil {\n\t\t\t\t\tlog.G(context.TODO()).Debugf(\"Can't add file %s to tar: %s\", path, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Make sure to check the error on Close.\n\t\tif err := ta.TarWriter.Close(); err != nil {\n\t\t\tlog.G(context.TODO()).Debugf(\"Can't close layer: %s\", err)\n\t\t}\n\t\tif err := writer.Close(); err != nil {\n\t\t\tlog.G(context.TODO()).Debugf(\"failed close Changes writer: %s\", err)\n\t\t}\n\t}()\n\treturn reader, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/changes_linux.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/docker/docker/pkg/system\"\n\t\"golang.org/x/sys/unix\"\n)\n\n// walker is used to implement collectFileInfoForChanges on linux. Where this\n// method in general returns the entire contents of two directory trees, we\n// optimize some FS calls out on linux. In particular, we take advantage of the\n// fact that getdents(2) returns the inode of each file in the directory being\n// walked, which, when walking two trees in parallel to generate a list of\n// changes, can be used to prune subtrees without ever having to lstat(2) them\n// directly. Eliminating stat calls in this way can save up to seconds on large\n// images.\ntype walker struct {\n\tdir1  string\n\tdir2  string\n\troot1 *FileInfo\n\troot2 *FileInfo\n}\n\n// collectFileInfoForChanges returns a complete representation of the trees\n// rooted at dir1 and dir2, with one important exception: any subtree or\n// leaf where the inode and device numbers are an exact match between dir1\n// and dir2 will be pruned from the results. This method is *only* to be used\n// to generating a list of changes between the two directories, as it does not\n// reflect the full contents.\nfunc collectFileInfoForChanges(dir1, dir2 string) (*FileInfo, *FileInfo, error) {\n\tw := &walker{\n\t\tdir1:  dir1,\n\t\tdir2:  dir2,\n\t\troot1: newRootFileInfo(),\n\t\troot2: newRootFileInfo(),\n\t}\n\n\ti1, err := os.Lstat(w.dir1)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\ti2, err := os.Lstat(w.dir2)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif err := w.walk(\"/\", i1, i2); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn w.root1, w.root2, nil\n}\n\n// Given a FileInfo, its path info, and a reference to the root of the tree\n// being constructed, register this file with the tree.\nfunc walkchunk(path string, fi os.FileInfo, dir string, root *FileInfo) error {\n\tif fi == nil {\n\t\treturn nil\n\t}\n\tparent := root.LookUp(filepath.Dir(path))\n\tif parent == nil {\n\t\treturn fmt.Errorf(\"walkchunk: Unexpectedly no parent for %s\", path)\n\t}\n\tinfo := &FileInfo{\n\t\tname:     filepath.Base(path),\n\t\tchildren: make(map[string]*FileInfo),\n\t\tparent:   parent,\n\t}\n\tcpath := filepath.Join(dir, path)\n\tstat, err := system.FromStatT(fi.Sys().(*syscall.Stat_t))\n\tif err != nil {\n\t\treturn err\n\t}\n\tinfo.stat = stat\n\tinfo.capability, _ = system.Lgetxattr(cpath, \"security.capability\") // lgetxattr(2): fs access\n\tparent.children[info.name] = info\n\treturn nil\n}\n\n// Walk a subtree rooted at the same path in both trees being iterated. For\n// example, /docker/overlay/1234/a/b/c/d and /docker/overlay/8888/a/b/c/d\nfunc (w *walker) walk(path string, i1, i2 os.FileInfo) (err error) {\n\t// Register these nodes with the return trees, unless we're still at the\n\t// (already-created) roots:\n\tif path != \"/\" {\n\t\tif err := walkchunk(path, i1, w.dir1, w.root1); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := walkchunk(path, i2, w.dir2, w.root2); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tis1Dir := i1 != nil && i1.IsDir()\n\tis2Dir := i2 != nil && i2.IsDir()\n\n\tsameDevice := false\n\tif i1 != nil && i2 != nil {\n\t\tsi1 := i1.Sys().(*syscall.Stat_t)\n\t\tsi2 := i2.Sys().(*syscall.Stat_t)\n\t\tif si1.Dev == si2.Dev {\n\t\t\tsameDevice = true\n\t\t}\n\t}\n\n\t// If these files are both non-existent, or leaves (non-dirs), we are done.\n\tif !is1Dir && !is2Dir {\n\t\treturn nil\n\t}\n\n\t// Fetch the names of all the files contained in both directories being walked:\n\tvar names1, names2 []nameIno\n\tif is1Dir {\n\t\tnames1, err = readdirnames(filepath.Join(w.dir1, path)) // getdents(2): fs access\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif is2Dir {\n\t\tnames2, err = readdirnames(filepath.Join(w.dir2, path)) // getdents(2): fs access\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// We have lists of the files contained in both parallel directories, sorted\n\t// in the same order. Walk them in parallel, generating a unique merged list\n\t// of all items present in either or both directories.\n\tvar names []string\n\tix1 := 0\n\tix2 := 0\n\n\tfor {\n\t\tif ix1 >= len(names1) {\n\t\t\tbreak\n\t\t}\n\t\tif ix2 >= len(names2) {\n\t\t\tbreak\n\t\t}\n\n\t\tni1 := names1[ix1]\n\t\tni2 := names2[ix2]\n\n\t\tswitch bytes.Compare([]byte(ni1.name), []byte(ni2.name)) {\n\t\tcase -1: // ni1 < ni2 -- advance ni1\n\t\t\t// we will not encounter ni1 in names2\n\t\t\tnames = append(names, ni1.name)\n\t\t\tix1++\n\t\tcase 0: // ni1 == ni2\n\t\t\tif ni1.ino != ni2.ino || !sameDevice {\n\t\t\t\tnames = append(names, ni1.name)\n\t\t\t}\n\t\t\tix1++\n\t\t\tix2++\n\t\tcase 1: // ni1 > ni2 -- advance ni2\n\t\t\t// we will not encounter ni2 in names1\n\t\t\tnames = append(names, ni2.name)\n\t\t\tix2++\n\t\t}\n\t}\n\tfor ix1 < len(names1) {\n\t\tnames = append(names, names1[ix1].name)\n\t\tix1++\n\t}\n\tfor ix2 < len(names2) {\n\t\tnames = append(names, names2[ix2].name)\n\t\tix2++\n\t}\n\n\t// For each of the names present in either or both of the directories being\n\t// iterated, stat the name under each root, and recurse the pair of them:\n\tfor _, name := range names {\n\t\tfname := filepath.Join(path, name)\n\t\tvar cInfo1, cInfo2 os.FileInfo\n\t\tif is1Dir {\n\t\t\tcInfo1, err = os.Lstat(filepath.Join(w.dir1, fname)) // lstat(2): fs access\n\t\t\tif err != nil && !os.IsNotExist(err) {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif is2Dir {\n\t\t\tcInfo2, err = os.Lstat(filepath.Join(w.dir2, fname)) // lstat(2): fs access\n\t\t\tif err != nil && !os.IsNotExist(err) {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err = w.walk(fname, cInfo1, cInfo2); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// {name,inode} pairs used to support the early-pruning logic of the walker type\ntype nameIno struct {\n\tname string\n\tino  uint64\n}\n\ntype nameInoSlice []nameIno\n\nfunc (s nameInoSlice) Len() int           { return len(s) }\nfunc (s nameInoSlice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\nfunc (s nameInoSlice) Less(i, j int) bool { return s[i].name < s[j].name }\n\n// readdirnames is a hacked-apart version of the Go stdlib code, exposing inode\n// numbers further up the stack when reading directory contents. Unlike\n// os.Readdirnames, which returns a list of filenames, this function returns a\n// list of {filename,inode} pairs.\nfunc readdirnames(dirname string) (names []nameIno, err error) {\n\tvar (\n\t\tsize = 100\n\t\tbuf  = make([]byte, 4096)\n\t\tnbuf int\n\t\tbufp int\n\t\tnb   int\n\t)\n\n\tf, err := os.Open(dirname)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer f.Close()\n\n\tnames = make([]nameIno, 0, size) // Empty with room to grow.\n\tfor {\n\t\t// Refill the buffer if necessary\n\t\tif bufp >= nbuf {\n\t\t\tbufp = 0\n\t\t\tnbuf, err = unix.ReadDirent(int(f.Fd()), buf) // getdents on linux\n\t\t\tif nbuf < 0 {\n\t\t\t\tnbuf = 0\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn nil, os.NewSyscallError(\"readdirent\", err)\n\t\t\t}\n\t\t\tif nbuf <= 0 {\n\t\t\t\tbreak // EOF\n\t\t\t}\n\t\t}\n\n\t\t// Drain the buffer\n\t\tnb, names = parseDirent(buf[bufp:nbuf], names)\n\t\tbufp += nb\n\t}\n\n\tsl := nameInoSlice(names)\n\tsort.Sort(sl)\n\treturn sl, nil\n}\n\n// parseDirent is a minor modification of unix.ParseDirent (linux version)\n// which returns {name,inode} pairs instead of just names.\nfunc parseDirent(buf []byte, names []nameIno) (consumed int, newnames []nameIno) {\n\toriglen := len(buf)\n\tfor len(buf) > 0 {\n\t\tdirent := (*unix.Dirent)(unsafe.Pointer(&buf[0]))\n\t\tbuf = buf[dirent.Reclen:]\n\t\tif dirent.Ino == 0 { // File absent in directory.\n\t\t\tcontinue\n\t\t}\n\t\tbytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))\n\t\tname := string(bytes[0:clen(bytes[:])])\n\t\tif name == \".\" || name == \"..\" { // Useless names\n\t\t\tcontinue\n\t\t}\n\t\tnames = append(names, nameIno{name, dirent.Ino})\n\t}\n\treturn origlen - len(buf), names\n}\n\nfunc clen(n []byte) int {\n\tfor i := 0; i < len(n); i++ {\n\t\tif n[i] == 0 {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn len(n)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/changes_other.go",
    "content": "//go:build !linux\n\npackage archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/pkg/system\"\n)\n\nfunc collectFileInfoForChanges(oldDir, newDir string) (*FileInfo, *FileInfo, error) {\n\tvar (\n\t\toldRoot, newRoot *FileInfo\n\t\terr1, err2       error\n\t\terrs             = make(chan error, 2)\n\t)\n\tgo func() {\n\t\toldRoot, err1 = collectFileInfo(oldDir)\n\t\terrs <- err1\n\t}()\n\tgo func() {\n\t\tnewRoot, err2 = collectFileInfo(newDir)\n\t\terrs <- err2\n\t}()\n\n\t// block until both routines have returned\n\tfor i := 0; i < 2; i++ {\n\t\tif err := <-errs; err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\n\treturn oldRoot, newRoot, nil\n}\n\nfunc collectFileInfo(sourceDir string) (*FileInfo, error) {\n\troot := newRootFileInfo()\n\n\terr := filepath.WalkDir(sourceDir, func(path string, _ os.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Rebase path\n\t\trelPath, err := filepath.Rel(sourceDir, path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// As this runs on the daemon side, file paths are OS specific.\n\t\trelPath = filepath.Join(string(os.PathSeparator), relPath)\n\n\t\t// See https://github.com/golang/go/issues/9168 - bug in filepath.Join.\n\t\t// Temporary workaround. If the returned path starts with two backslashes,\n\t\t// trim it down to a single backslash. Only relevant on Windows.\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tif strings.HasPrefix(relPath, `\\\\`) {\n\t\t\t\trelPath = relPath[1:]\n\t\t\t}\n\t\t}\n\n\t\tif relPath == string(os.PathSeparator) {\n\t\t\treturn nil\n\t\t}\n\n\t\tparent := root.LookUp(filepath.Dir(relPath))\n\t\tif parent == nil {\n\t\t\treturn fmt.Errorf(\"collectFileInfo: Unexpectedly no parent for %s\", relPath)\n\t\t}\n\n\t\tinfo := &FileInfo{\n\t\t\tname:     filepath.Base(relPath),\n\t\t\tchildren: make(map[string]*FileInfo),\n\t\t\tparent:   parent,\n\t\t}\n\n\t\ts, err := system.Lstat(path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tinfo.stat = s\n\n\t\tinfo.capability, _ = system.Lgetxattr(path, \"security.capability\")\n\n\t\tparent.children[info.name] = info\n\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn root, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/changes_unix.go",
    "content": "//go:build !windows\n\npackage archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"os\"\n\t\"syscall\"\n\n\t\"github.com/docker/docker/pkg/system\"\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc statDifferent(oldStat *system.StatT, newStat *system.StatT) bool {\n\t// Don't look at size for dirs, its not a good measure of change\n\tif oldStat.Mode() != newStat.Mode() ||\n\t\toldStat.UID() != newStat.UID() ||\n\t\toldStat.GID() != newStat.GID() ||\n\t\toldStat.Rdev() != newStat.Rdev() ||\n\t\t// Don't look at size or modification time for dirs, its not a good\n\t\t// measure of change. See https://github.com/moby/moby/issues/9874\n\t\t// for a description of the issue with modification time, and\n\t\t// https://github.com/moby/moby/pull/11422 for the change.\n\t\t// (Note that in the Windows implementation of this function,\n\t\t// modification time IS taken as a change). See\n\t\t// https://github.com/moby/moby/pull/37982 for more information.\n\t\t(oldStat.Mode()&unix.S_IFDIR != unix.S_IFDIR &&\n\t\t\t(!sameFsTimeSpec(oldStat.Mtim(), newStat.Mtim()) || (oldStat.Size() != newStat.Size()))) {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (info *FileInfo) isDir() bool {\n\treturn info.parent == nil || info.stat.Mode()&unix.S_IFDIR != 0\n}\n\nfunc getIno(fi os.FileInfo) uint64 {\n\treturn fi.Sys().(*syscall.Stat_t).Ino\n}\n\nfunc hasHardlinks(fi os.FileInfo) bool {\n\treturn fi.Sys().(*syscall.Stat_t).Nlink > 1\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/changes_windows.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"os\"\n\n\t\"github.com/docker/docker/pkg/system\"\n)\n\nfunc statDifferent(oldStat *system.StatT, newStat *system.StatT) bool {\n\t// Note there is slight difference between the Linux and Windows\n\t// implementations here. Due to https://github.com/moby/moby/issues/9874,\n\t// and the fix at https://github.com/moby/moby/pull/11422, Linux does not\n\t// consider a change to the directory time as a change. Windows on NTFS\n\t// does. See https://github.com/moby/moby/pull/37982 for more information.\n\n\tif !sameFsTime(oldStat.Mtim(), newStat.Mtim()) ||\n\t\toldStat.Mode() != newStat.Mode() ||\n\t\toldStat.Size() != newStat.Size() && !oldStat.Mode().IsDir() {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (info *FileInfo) isDir() bool {\n\treturn info.parent == nil || info.stat.Mode().IsDir()\n}\n\nfunc getIno(fi os.FileInfo) (inode uint64) {\n\treturn\n}\n\nfunc hasHardlinks(fi os.FileInfo) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/copy.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/containerd/log\"\n\t\"github.com/docker/docker/pkg/system\"\n)\n\n// Errors used or returned by this file.\nvar (\n\tErrNotDirectory      = errors.New(\"not a directory\")\n\tErrDirNotExists      = errors.New(\"no such directory\")\n\tErrCannotCopyDir     = errors.New(\"cannot copy directory\")\n\tErrInvalidCopySource = errors.New(\"invalid copy source content\")\n)\n\n// PreserveTrailingDotOrSeparator returns the given cleaned path (after\n// processing using any utility functions from the path or filepath stdlib\n// packages) and appends a trailing `/.` or `/` if its corresponding  original\n// path (from before being processed by utility functions from the path or\n// filepath stdlib packages) ends with a trailing `/.` or `/`. If the cleaned\n// path already ends in a `.` path segment, then another is not added. If the\n// clean path already ends in a path separator, then another is not added.\nfunc PreserveTrailingDotOrSeparator(cleanedPath string, originalPath string) string {\n\t// Ensure paths are in platform semantics\n\tcleanedPath = normalizePath(cleanedPath)\n\toriginalPath = normalizePath(originalPath)\n\n\tif !specifiesCurrentDir(cleanedPath) && specifiesCurrentDir(originalPath) {\n\t\tif !hasTrailingPathSeparator(cleanedPath) {\n\t\t\t// Add a separator if it doesn't already end with one (a cleaned\n\t\t\t// path would only end in a separator if it is the root).\n\t\t\tcleanedPath += string(filepath.Separator)\n\t\t}\n\t\tcleanedPath += \".\"\n\t}\n\n\tif !hasTrailingPathSeparator(cleanedPath) && hasTrailingPathSeparator(originalPath) {\n\t\tcleanedPath += string(filepath.Separator)\n\t}\n\n\treturn cleanedPath\n}\n\n// assertsDirectory returns whether the given path is\n// asserted to be a directory, i.e., the path ends with\n// a trailing '/' or `/.`, assuming a path separator of `/`.\nfunc assertsDirectory(path string) bool {\n\treturn hasTrailingPathSeparator(path) || specifiesCurrentDir(path)\n}\n\n// hasTrailingPathSeparator returns whether the given\n// path ends with the system's path separator character.\nfunc hasTrailingPathSeparator(path string) bool {\n\treturn len(path) > 0 && path[len(path)-1] == filepath.Separator\n}\n\n// specifiesCurrentDir returns whether the given path specifies\n// a \"current directory\", i.e., the last path segment is `.`.\nfunc specifiesCurrentDir(path string) bool {\n\treturn filepath.Base(path) == \".\"\n}\n\n// SplitPathDirEntry splits the given path between its directory name and its\n// basename by first cleaning the path but preserves a trailing \".\" if the\n// original path specified the current directory.\nfunc SplitPathDirEntry(path string) (dir, base string) {\n\tcleanedPath := filepath.Clean(filepath.FromSlash(path))\n\n\tif specifiesCurrentDir(path) {\n\t\tcleanedPath += string(os.PathSeparator) + \".\"\n\t}\n\n\treturn filepath.Dir(cleanedPath), filepath.Base(cleanedPath)\n}\n\n// TarResource archives the resource described by the given CopyInfo to a Tar\n// archive. A non-nil error is returned if sourcePath does not exist or is\n// asserted to be a directory but exists as another type of file.\n//\n// This function acts as a convenient wrapper around TarWithOptions, which\n// requires a directory as the source path. TarResource accepts either a\n// directory or a file path and correctly sets the Tar options.\nfunc TarResource(sourceInfo CopyInfo) (content io.ReadCloser, err error) {\n\treturn TarResourceRebase(sourceInfo.Path, sourceInfo.RebaseName)\n}\n\n// TarResourceRebase is like TarResource but renames the first path element of\n// items in the resulting tar archive to match the given rebaseName if not \"\".\nfunc TarResourceRebase(sourcePath, rebaseName string) (content io.ReadCloser, err error) {\n\tsourcePath = normalizePath(sourcePath)\n\tif _, err = os.Lstat(sourcePath); err != nil {\n\t\t// Catches the case where the source does not exist or is not a\n\t\t// directory if asserted to be a directory, as this also causes an\n\t\t// error.\n\t\treturn\n\t}\n\n\t// Separate the source path between its directory and\n\t// the entry in that directory which we are archiving.\n\tsourceDir, sourceBase := SplitPathDirEntry(sourcePath)\n\topts := TarResourceRebaseOpts(sourceBase, rebaseName)\n\n\tlog.G(context.TODO()).Debugf(\"copying %q from %q\", sourceBase, sourceDir)\n\treturn TarWithOptions(sourceDir, opts)\n}\n\n// TarResourceRebaseOpts does not preform the Tar, but instead just creates the rebase\n// parameters to be sent to TarWithOptions (the TarOptions struct)\nfunc TarResourceRebaseOpts(sourceBase string, rebaseName string) *TarOptions {\n\tfilter := []string{sourceBase}\n\treturn &TarOptions{\n\t\tCompression:      Uncompressed,\n\t\tIncludeFiles:     filter,\n\t\tIncludeSourceDir: true,\n\t\tRebaseNames: map[string]string{\n\t\t\tsourceBase: rebaseName,\n\t\t},\n\t}\n}\n\n// CopyInfo holds basic info about the source\n// or destination path of a copy operation.\ntype CopyInfo struct {\n\tPath       string\n\tExists     bool\n\tIsDir      bool\n\tRebaseName string\n}\n\n// CopyInfoSourcePath stats the given path to create a CopyInfo\n// struct representing that resource for the source of an archive copy\n// operation. The given path should be an absolute local path. A source path\n// has all symlinks evaluated that appear before the last path separator (\"/\"\n// on Unix). As it is to be a copy source, the path must exist.\nfunc CopyInfoSourcePath(path string, followLink bool) (CopyInfo, error) {\n\t// normalize the file path and then evaluate the symbol link\n\t// we will use the target file instead of the symbol link if\n\t// followLink is set\n\tpath = normalizePath(path)\n\n\tresolvedPath, rebaseName, err := ResolveHostSourcePath(path, followLink)\n\tif err != nil {\n\t\treturn CopyInfo{}, err\n\t}\n\n\tstat, err := os.Lstat(resolvedPath)\n\tif err != nil {\n\t\treturn CopyInfo{}, err\n\t}\n\n\treturn CopyInfo{\n\t\tPath:       resolvedPath,\n\t\tExists:     true,\n\t\tIsDir:      stat.IsDir(),\n\t\tRebaseName: rebaseName,\n\t}, nil\n}\n\n// CopyInfoDestinationPath stats the given path to create a CopyInfo\n// struct representing that resource for the destination of an archive copy\n// operation. The given path should be an absolute local path.\nfunc CopyInfoDestinationPath(path string) (info CopyInfo, err error) {\n\tmaxSymlinkIter := 10 // filepath.EvalSymlinks uses 255, but 10 already seems like a lot.\n\tpath = normalizePath(path)\n\toriginalPath := path\n\n\tstat, err := os.Lstat(path)\n\n\tif err == nil && stat.Mode()&os.ModeSymlink == 0 {\n\t\t// The path exists and is not a symlink.\n\t\treturn CopyInfo{\n\t\t\tPath:   path,\n\t\t\tExists: true,\n\t\t\tIsDir:  stat.IsDir(),\n\t\t}, nil\n\t}\n\n\t// While the path is a symlink.\n\tfor n := 0; err == nil && stat.Mode()&os.ModeSymlink != 0; n++ {\n\t\tif n > maxSymlinkIter {\n\t\t\t// Don't follow symlinks more than this arbitrary number of times.\n\t\t\treturn CopyInfo{}, errors.New(\"too many symlinks in \" + originalPath)\n\t\t}\n\n\t\t// The path is a symbolic link. We need to evaluate it so that the\n\t\t// destination of the copy operation is the link target and not the\n\t\t// link itself. This is notably different than CopyInfoSourcePath which\n\t\t// only evaluates symlinks before the last appearing path separator.\n\t\t// Also note that it is okay if the last path element is a broken\n\t\t// symlink as the copy operation should create the target.\n\t\tvar linkTarget string\n\n\t\tlinkTarget, err = os.Readlink(path)\n\t\tif err != nil {\n\t\t\treturn CopyInfo{}, err\n\t\t}\n\n\t\tif !system.IsAbs(linkTarget) {\n\t\t\t// Join with the parent directory.\n\t\t\tdstParent, _ := SplitPathDirEntry(path)\n\t\t\tlinkTarget = filepath.Join(dstParent, linkTarget)\n\t\t}\n\n\t\tpath = linkTarget\n\t\tstat, err = os.Lstat(path)\n\t}\n\n\tif err != nil {\n\t\t// It's okay if the destination path doesn't exist. We can still\n\t\t// continue the copy operation if the parent directory exists.\n\t\tif !os.IsNotExist(err) {\n\t\t\treturn CopyInfo{}, err\n\t\t}\n\n\t\t// Ensure destination parent dir exists.\n\t\tdstParent, _ := SplitPathDirEntry(path)\n\n\t\tparentDirStat, err := os.Stat(dstParent)\n\t\tif err != nil {\n\t\t\treturn CopyInfo{}, err\n\t\t}\n\t\tif !parentDirStat.IsDir() {\n\t\t\treturn CopyInfo{}, ErrNotDirectory\n\t\t}\n\n\t\treturn CopyInfo{Path: path}, nil\n\t}\n\n\t// The path exists after resolving symlinks.\n\treturn CopyInfo{\n\t\tPath:   path,\n\t\tExists: true,\n\t\tIsDir:  stat.IsDir(),\n\t}, nil\n}\n\n// PrepareArchiveCopy prepares the given srcContent archive, which should\n// contain the archived resource described by srcInfo, to the destination\n// described by dstInfo. Returns the possibly modified content archive along\n// with the path to the destination directory which it should be extracted to.\nfunc PrepareArchiveCopy(srcContent io.Reader, srcInfo, dstInfo CopyInfo) (dstDir string, content io.ReadCloser, err error) {\n\t// Ensure in platform semantics\n\tsrcInfo.Path = normalizePath(srcInfo.Path)\n\tdstInfo.Path = normalizePath(dstInfo.Path)\n\n\t// Separate the destination path between its directory and base\n\t// components in case the source archive contents need to be rebased.\n\tdstDir, dstBase := SplitPathDirEntry(dstInfo.Path)\n\t_, srcBase := SplitPathDirEntry(srcInfo.Path)\n\n\tswitch {\n\tcase dstInfo.Exists && dstInfo.IsDir:\n\t\t// The destination exists as a directory. No alteration\n\t\t// to srcContent is needed as its contents can be\n\t\t// simply extracted to the destination directory.\n\t\treturn dstInfo.Path, io.NopCloser(srcContent), nil\n\tcase dstInfo.Exists && srcInfo.IsDir:\n\t\t// The destination exists as some type of file and the source\n\t\t// content is a directory. This is an error condition since\n\t\t// you cannot copy a directory to an existing file location.\n\t\treturn \"\", nil, ErrCannotCopyDir\n\tcase dstInfo.Exists:\n\t\t// The destination exists as some type of file and the source content\n\t\t// is also a file. The source content entry will have to be renamed to\n\t\t// have a basename which matches the destination path's basename.\n\t\tif len(srcInfo.RebaseName) != 0 {\n\t\t\tsrcBase = srcInfo.RebaseName\n\t\t}\n\t\treturn dstDir, RebaseArchiveEntries(srcContent, srcBase, dstBase), nil\n\tcase srcInfo.IsDir:\n\t\t// The destination does not exist and the source content is an archive\n\t\t// of a directory. The archive should be extracted to the parent of\n\t\t// the destination path instead, and when it is, the directory that is\n\t\t// created as a result should take the name of the destination path.\n\t\t// The source content entries will have to be renamed to have a\n\t\t// basename which matches the destination path's basename.\n\t\tif len(srcInfo.RebaseName) != 0 {\n\t\t\tsrcBase = srcInfo.RebaseName\n\t\t}\n\t\treturn dstDir, RebaseArchiveEntries(srcContent, srcBase, dstBase), nil\n\tcase assertsDirectory(dstInfo.Path):\n\t\t// The destination does not exist and is asserted to be created as a\n\t\t// directory, but the source content is not a directory. This is an\n\t\t// error condition since you cannot create a directory from a file\n\t\t// source.\n\t\treturn \"\", nil, ErrDirNotExists\n\tdefault:\n\t\t// The last remaining case is when the destination does not exist, is\n\t\t// not asserted to be a directory, and the source content is not an\n\t\t// archive of a directory. It this case, the destination file will need\n\t\t// to be created when the archive is extracted and the source content\n\t\t// entry will have to be renamed to have a basename which matches the\n\t\t// destination path's basename.\n\t\tif len(srcInfo.RebaseName) != 0 {\n\t\t\tsrcBase = srcInfo.RebaseName\n\t\t}\n\t\treturn dstDir, RebaseArchiveEntries(srcContent, srcBase, dstBase), nil\n\t}\n}\n\n// RebaseArchiveEntries rewrites the given srcContent archive replacing\n// an occurrence of oldBase with newBase at the beginning of entry names.\nfunc RebaseArchiveEntries(srcContent io.Reader, oldBase, newBase string) io.ReadCloser {\n\tif oldBase == string(os.PathSeparator) {\n\t\t// If oldBase specifies the root directory, use an empty string as\n\t\t// oldBase instead so that newBase doesn't replace the path separator\n\t\t// that all paths will start with.\n\t\toldBase = \"\"\n\t}\n\n\trebased, w := io.Pipe()\n\n\tgo func() {\n\t\tsrcTar := tar.NewReader(srcContent)\n\t\trebasedTar := tar.NewWriter(w)\n\n\t\tfor {\n\t\t\thdr, err := srcTar.Next()\n\t\t\tif err == io.EOF {\n\t\t\t\t// Signals end of archive.\n\t\t\t\trebasedTar.Close()\n\t\t\t\tw.Close()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\tw.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// srcContent tar stream, as served by TarWithOptions(), is\n\t\t\t// definitely in PAX format, but tar.Next() mistakenly guesses it\n\t\t\t// as USTAR, which creates a problem: if the newBase is >100\n\t\t\t// characters long, WriteHeader() returns an error like\n\t\t\t// \"archive/tar: cannot encode header: Format specifies USTAR; and USTAR cannot encode Name=...\".\n\t\t\t//\n\t\t\t// To fix, set the format to PAX here. See docker/for-linux issue #484.\n\t\t\thdr.Format = tar.FormatPAX\n\t\t\thdr.Name = strings.Replace(hdr.Name, oldBase, newBase, 1)\n\t\t\tif hdr.Typeflag == tar.TypeLink {\n\t\t\t\thdr.Linkname = strings.Replace(hdr.Linkname, oldBase, newBase, 1)\n\t\t\t}\n\n\t\t\tif err = rebasedTar.WriteHeader(hdr); err != nil {\n\t\t\t\tw.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Ignoring GoSec G110. See https://github.com/securego/gosec/pull/433\n\t\t\t// and https://cure53.de/pentest-report_opa.pdf, which recommends to\n\t\t\t// replace io.Copy with io.CopyN7. The latter allows to specify the\n\t\t\t// maximum number of bytes that should be read. By properly defining\n\t\t\t// the limit, it can be assured that a GZip compression bomb cannot\n\t\t\t// easily cause a Denial-of-Service.\n\t\t\t// After reviewing with @tonistiigi and @cpuguy83, this should not\n\t\t\t// affect us, because here we do not read into memory, hence should\n\t\t\t// not be vulnerable to this code consuming memory.\n\t\t\t//nolint:gosec // G110: Potential DoS vulnerability via decompression bomb (gosec)\n\t\t\tif _, err = io.Copy(rebasedTar, srcTar); err != nil {\n\t\t\t\tw.CloseWithError(err)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn rebased\n}\n\n// CopyResource performs an archive copy from the given source path to the\n// given destination path. The source path MUST exist and the destination\n// path's parent directory must exist.\nfunc CopyResource(srcPath, dstPath string, followLink bool) error {\n\tvar (\n\t\tsrcInfo CopyInfo\n\t\terr     error\n\t)\n\n\t// Ensure in platform semantics\n\tsrcPath = normalizePath(srcPath)\n\tdstPath = normalizePath(dstPath)\n\n\t// Clean the source and destination paths.\n\tsrcPath = PreserveTrailingDotOrSeparator(filepath.Clean(srcPath), srcPath)\n\tdstPath = PreserveTrailingDotOrSeparator(filepath.Clean(dstPath), dstPath)\n\n\tif srcInfo, err = CopyInfoSourcePath(srcPath, followLink); err != nil {\n\t\treturn err\n\t}\n\n\tcontent, err := TarResource(srcInfo)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer content.Close()\n\n\treturn CopyTo(content, srcInfo, dstPath)\n}\n\n// CopyTo handles extracting the given content whose\n// entries should be sourced from srcInfo to dstPath.\nfunc CopyTo(content io.Reader, srcInfo CopyInfo, dstPath string) error {\n\t// The destination path need not exist, but CopyInfoDestinationPath will\n\t// ensure that at least the parent directory exists.\n\tdstInfo, err := CopyInfoDestinationPath(normalizePath(dstPath))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdstDir, copyArchive, err := PrepareArchiveCopy(content, srcInfo, dstInfo)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer copyArchive.Close()\n\n\toptions := &TarOptions{\n\t\tNoLchown:             true,\n\t\tNoOverwriteDirNonDir: true,\n\t}\n\n\treturn Untar(copyArchive, dstDir, options)\n}\n\n// ResolveHostSourcePath decides real path need to be copied with parameters such as\n// whether to follow symbol link or not, if followLink is true, resolvedPath will return\n// link target of any symbol link file, else it will only resolve symlink of directory\n// but return symbol link file itself without resolving.\nfunc ResolveHostSourcePath(path string, followLink bool) (resolvedPath, rebaseName string, err error) {\n\tif followLink {\n\t\tresolvedPath, err = filepath.EvalSymlinks(path)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tresolvedPath, rebaseName = GetRebaseName(path, resolvedPath)\n\t} else {\n\t\tdirPath, basePath := filepath.Split(path)\n\n\t\t// if not follow symbol link, then resolve symbol link of parent dir\n\t\tvar resolvedDirPath string\n\t\tresolvedDirPath, err = filepath.EvalSymlinks(dirPath)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\t// resolvedDirPath will have been cleaned (no trailing path separators) so\n\t\t// we can manually join it with the base path element.\n\t\tresolvedPath = resolvedDirPath + string(filepath.Separator) + basePath\n\t\tif hasTrailingPathSeparator(path) &&\n\t\t\tfilepath.Base(path) != filepath.Base(resolvedPath) {\n\t\t\trebaseName = filepath.Base(path)\n\t\t}\n\t}\n\treturn resolvedPath, rebaseName, nil\n}\n\n// GetRebaseName normalizes and compares path and resolvedPath,\n// return completed resolved path and rebased file name\nfunc GetRebaseName(path, resolvedPath string) (string, string) {\n\t// linkTarget will have been cleaned (no trailing path separators and dot) so\n\t// we can manually join it with them\n\tvar rebaseName string\n\tif specifiesCurrentDir(path) &&\n\t\t!specifiesCurrentDir(resolvedPath) {\n\t\tresolvedPath += string(filepath.Separator) + \".\"\n\t}\n\n\tif hasTrailingPathSeparator(path) &&\n\t\t!hasTrailingPathSeparator(resolvedPath) {\n\t\tresolvedPath += string(filepath.Separator)\n\t}\n\n\tif filepath.Base(path) != filepath.Base(resolvedPath) {\n\t\t// In the case where the path had a trailing separator and a symlink\n\t\t// evaluation has changed the last path component, we will need to\n\t\t// rebase the name in the archive that is being copied to match the\n\t\t// originally requested name.\n\t\trebaseName = filepath.Base(path)\n\t}\n\treturn resolvedPath, rebaseName\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/copy_unix.go",
    "content": "//go:build !windows\n\npackage archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"path/filepath\"\n)\n\nfunc normalizePath(path string) string {\n\treturn filepath.ToSlash(path)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/copy_windows.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"path/filepath\"\n)\n\nfunc normalizePath(path string) string {\n\treturn filepath.FromSlash(path)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/diff.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strings\"\n\n\t\"github.com/containerd/log\"\n\t\"github.com/docker/docker/pkg/pools\"\n\t\"github.com/docker/docker/pkg/system\"\n)\n\n// UnpackLayer unpack `layer` to a `dest`. The stream `layer` can be\n// compressed or uncompressed.\n// Returns the size in bytes of the contents of the layer.\nfunc UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, err error) {\n\ttr := tar.NewReader(layer)\n\ttrBuf := pools.BufioReader32KPool.Get(tr)\n\tdefer pools.BufioReader32KPool.Put(trBuf)\n\n\tvar dirs []*tar.Header\n\tunpackedPaths := make(map[string]struct{})\n\n\tif options == nil {\n\t\toptions = &TarOptions{}\n\t}\n\tif options.ExcludePatterns == nil {\n\t\toptions.ExcludePatterns = []string{}\n\t}\n\n\taufsTempdir := \"\"\n\taufsHardlinks := make(map[string]*tar.Header)\n\n\t// Iterate through the files in the archive.\n\tfor {\n\t\thdr, err := tr.Next()\n\t\tif err == io.EOF {\n\t\t\t// end of tar archive\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\tsize += hdr.Size\n\n\t\t// Normalize name, for safety and for a simple is-root check\n\t\thdr.Name = filepath.Clean(hdr.Name)\n\n\t\t// Windows does not support filenames with colons in them. Ignore\n\t\t// these files. This is not a problem though (although it might\n\t\t// appear that it is). Let's suppose a client is running docker pull.\n\t\t// The daemon it points to is Windows. Would it make sense for the\n\t\t// client to be doing a docker pull Ubuntu for example (which has files\n\t\t// with colons in the name under /usr/share/man/man3)? No, absolutely\n\t\t// not as it would really only make sense that they were pulling a\n\t\t// Windows image. However, for development, it is necessary to be able\n\t\t// to pull Linux images which are in the repository.\n\t\t//\n\t\t// TODO Windows. Once the registry is aware of what images are Windows-\n\t\t// specific or Linux-specific, this warning should be changed to an error\n\t\t// to cater for the situation where someone does manage to upload a Linux\n\t\t// image but have it tagged as Windows inadvertently.\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tif strings.Contains(hdr.Name, \":\") {\n\t\t\t\tlog.G(context.TODO()).Warnf(\"Windows: Ignoring %s (is this a Linux image?)\", hdr.Name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Ensure that the parent directory exists.\n\t\terr = createImpliedDirectories(dest, hdr, options)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// Skip AUFS metadata dirs\n\t\tif strings.HasPrefix(hdr.Name, WhiteoutMetaPrefix) {\n\t\t\t// Regular files inside /.wh..wh.plnk can be used as hardlink targets\n\t\t\t// We don't want this directory, but we need the files in them so that\n\t\t\t// such hardlinks can be resolved.\n\t\t\tif strings.HasPrefix(hdr.Name, WhiteoutLinkDir) && hdr.Typeflag == tar.TypeReg {\n\t\t\t\tbasename := filepath.Base(hdr.Name)\n\t\t\t\taufsHardlinks[basename] = hdr\n\t\t\t\tif aufsTempdir == \"\" {\n\t\t\t\t\tif aufsTempdir, err = os.MkdirTemp(dest, \"dockerplnk\"); err != nil {\n\t\t\t\t\t\treturn 0, err\n\t\t\t\t\t}\n\t\t\t\t\tdefer os.RemoveAll(aufsTempdir)\n\t\t\t\t}\n\t\t\t\tif err := createTarFile(filepath.Join(aufsTempdir, basename), dest, hdr, tr, options); err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif hdr.Name != WhiteoutOpaqueDir {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\t//#nosec G305 -- The joined path is guarded against path traversal.\n\t\tpath := filepath.Join(dest, hdr.Name)\n\t\trel, err := filepath.Rel(dest, path)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// Note as these operations are platform specific, so must the slash be.\n\t\tif strings.HasPrefix(rel, \"..\"+string(os.PathSeparator)) {\n\t\t\treturn 0, breakoutError(fmt.Errorf(\"%q is outside of %q\", hdr.Name, dest))\n\t\t}\n\t\tbase := filepath.Base(path)\n\n\t\tif strings.HasPrefix(base, WhiteoutPrefix) {\n\t\t\tdir := filepath.Dir(path)\n\t\t\tif base == WhiteoutOpaqueDir {\n\t\t\t\t_, err := os.Lstat(dir)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t\terr = filepath.WalkDir(dir, func(path string, info os.DirEntry, err error) error {\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tif os.IsNotExist(err) {\n\t\t\t\t\t\t\terr = nil // parent was deleted\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif path == dir {\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t\tif _, exists := unpackedPaths[path]; !exists {\n\t\t\t\t\t\treturn os.RemoveAll(path)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toriginalBase := base[len(WhiteoutPrefix):]\n\t\t\t\toriginalPath := filepath.Join(dir, originalBase)\n\t\t\t\tif err := os.RemoveAll(originalPath); err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// If path exits we almost always just want to remove and replace it.\n\t\t\t// The only exception is when it is a directory *and* the file from\n\t\t\t// the layer is also a directory. Then we want to merge them (i.e.\n\t\t\t// just apply the metadata from the layer).\n\t\t\tif fi, err := os.Lstat(path); err == nil {\n\t\t\t\tif !(fi.IsDir() && hdr.Typeflag == tar.TypeDir) {\n\t\t\t\t\tif err := os.RemoveAll(path); err != nil {\n\t\t\t\t\t\treturn 0, err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttrBuf.Reset(tr)\n\t\t\tsrcData := io.Reader(trBuf)\n\t\t\tsrcHdr := hdr\n\n\t\t\t// Hard links into /.wh..wh.plnk don't work, as we don't extract that directory, so\n\t\t\t// we manually retarget these into the temporary files we extracted them into\n\t\t\tif hdr.Typeflag == tar.TypeLink && strings.HasPrefix(filepath.Clean(hdr.Linkname), WhiteoutLinkDir) {\n\t\t\t\tlinkBasename := filepath.Base(hdr.Linkname)\n\t\t\t\tsrcHdr = aufsHardlinks[linkBasename]\n\t\t\t\tif srcHdr == nil {\n\t\t\t\t\treturn 0, fmt.Errorf(\"Invalid aufs hardlink\")\n\t\t\t\t}\n\t\t\t\ttmpFile, err := os.Open(filepath.Join(aufsTempdir, linkBasename))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t\tdefer tmpFile.Close()\n\t\t\t\tsrcData = tmpFile\n\t\t\t}\n\n\t\t\tif err := remapIDs(options.IDMap, srcHdr); err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\n\t\t\tif err := createTarFile(path, dest, srcHdr, srcData, options); err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\n\t\t\t// Directory mtimes must be handled at the end to avoid further\n\t\t\t// file creation in them to modify the directory mtime\n\t\t\tif hdr.Typeflag == tar.TypeDir {\n\t\t\t\tdirs = append(dirs, hdr)\n\t\t\t}\n\t\t\tunpackedPaths[path] = struct{}{}\n\t\t}\n\t}\n\n\tfor _, hdr := range dirs {\n\t\t//#nosec G305 -- The header was checked for path traversal before it was appended to the dirs slice.\n\t\tpath := filepath.Join(dest, hdr.Name)\n\t\tif err := system.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\n\treturn size, nil\n}\n\n// ApplyLayer parses a diff in the standard layer format from `layer`,\n// and applies it to the directory `dest`. The stream `layer` can be\n// compressed or uncompressed.\n// Returns the size in bytes of the contents of the layer.\nfunc ApplyLayer(dest string, layer io.Reader) (int64, error) {\n\treturn applyLayerHandler(dest, layer, &TarOptions{}, true)\n}\n\n// ApplyUncompressedLayer parses a diff in the standard layer format from\n// `layer`, and applies it to the directory `dest`. The stream `layer`\n// can only be uncompressed.\n// Returns the size in bytes of the contents of the layer.\nfunc ApplyUncompressedLayer(dest string, layer io.Reader, options *TarOptions) (int64, error) {\n\treturn applyLayerHandler(dest, layer, options, false)\n}\n\n// IsEmpty checks if the tar archive is empty (doesn't contain any entries).\nfunc IsEmpty(rd io.Reader) (bool, error) {\n\tdecompRd, err := DecompressStream(rd)\n\tif err != nil {\n\t\treturn true, fmt.Errorf(\"failed to decompress archive: %v\", err)\n\t}\n\tdefer decompRd.Close()\n\n\ttarReader := tar.NewReader(decompRd)\n\tif _, err := tarReader.Next(); err != nil {\n\t\tif err == io.EOF {\n\t\t\treturn true, nil\n\t\t}\n\t\treturn false, fmt.Errorf(\"failed to read next archive header: %v\", err)\n\t}\n\n\treturn false, nil\n}\n\n// do the bulk load of ApplyLayer, but allow for not calling DecompressStream\nfunc applyLayerHandler(dest string, layer io.Reader, options *TarOptions, decompress bool) (int64, error) {\n\tdest = filepath.Clean(dest)\n\n\t// We need to be able to set any perms\n\trestore := overrideUmask(0)\n\tdefer restore()\n\n\tif decompress {\n\t\tdecompLayer, err := DecompressStream(layer)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tdefer decompLayer.Close()\n\t\tlayer = decompLayer\n\t}\n\treturn UnpackLayer(dest, layer, options)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/diff_unix.go",
    "content": "//go:build !windows\n\npackage archive\n\nimport \"golang.org/x/sys/unix\"\n\n// overrideUmask sets current process's file mode creation mask to newmask\n// and returns a function to restore it.\n//\n// WARNING for readers stumbling upon this code. Changing umask in a multi-\n// threaded environment isn't safe. Don't use this without understanding the\n// risks, and don't export this function for others to use (we shouldn't even\n// be using this ourself).\n//\n// FIXME(thaJeztah): we should get rid of these hacks if possible.\nfunc overrideUmask(newMask int) func() {\n\toldMask := unix.Umask(newMask)\n\treturn func() {\n\t\tunix.Umask(oldMask)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/diff_windows.go",
    "content": "package archive\n\n// overrideUmask is a no-op on windows.\nfunc overrideUmask(newmask int) func() {\n\treturn func() {}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/path.go",
    "content": "package archive\n\n// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,\n// is the system drive.\n// On Linux: this is a no-op.\n// On Windows: this does the following>\n// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.\n// This is used, for example, when validating a user provided path in docker cp.\n// If a drive letter is supplied, it must be the system drive. The drive letter\n// is always removed. Also, it translates it to OS semantics (IOW / to \\). We\n// need the path in this syntax so that it can ultimately be concatenated with\n// a Windows long-path which doesn't support drive-letters. Examples:\n// C:\t\t\t--> Fail\n// C:\\\t\t\t--> \\\n// a\t\t\t--> a\n// /a\t\t\t--> \\a\n// d:\\\t\t\t--> Fail\nfunc CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {\n\treturn checkSystemDriveAndRemoveDriveLetter(path)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/path_unix.go",
    "content": "//go:build !windows\n\npackage archive\n\n// checkSystemDriveAndRemoveDriveLetter is the non-Windows implementation\n// of CheckSystemDriveAndRemoveDriveLetter\nfunc checkSystemDriveAndRemoveDriveLetter(path string) (string, error) {\n\treturn path, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/path_windows.go",
    "content": "package archive\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// checkSystemDriveAndRemoveDriveLetter is the Windows implementation\n// of CheckSystemDriveAndRemoveDriveLetter\nfunc checkSystemDriveAndRemoveDriveLetter(path string) (string, error) {\n\tif len(path) == 2 && string(path[1]) == \":\" {\n\t\treturn \"\", fmt.Errorf(\"no relative path specified in %q\", path)\n\t}\n\tif !filepath.IsAbs(path) || len(path) < 2 {\n\t\treturn filepath.FromSlash(path), nil\n\t}\n\tif string(path[1]) == \":\" && !strings.EqualFold(string(path[0]), \"c\") {\n\t\treturn \"\", fmt.Errorf(\"the specified path is not on the system drive (C:)\")\n\t}\n\treturn filepath.FromSlash(path[2:]), nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/time_linux.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"syscall\"\n\t\"time\"\n)\n\nfunc timeToTimespec(time time.Time) (ts syscall.Timespec) {\n\tif time.IsZero() {\n\t\t// Return UTIME_OMIT special value\n\t\tts.Sec = 0\n\t\tts.Nsec = (1 << 30) - 2\n\t\treturn\n\t}\n\treturn syscall.NsecToTimespec(time.UnixNano())\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/time_unsupported.go",
    "content": "//go:build !linux\n\npackage archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"syscall\"\n\t\"time\"\n)\n\nfunc timeToTimespec(time time.Time) (ts syscall.Timespec) {\n\tnsec := int64(0)\n\tif !time.IsZero() {\n\t\tnsec = time.UnixNano()\n\t}\n\treturn syscall.NsecToTimespec(nsec)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/whiteouts.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\n// Whiteouts are files with a special meaning for the layered filesystem.\n// Docker uses AUFS whiteout files inside exported archives. In other\n// filesystems these files are generated/handled on tar creation/extraction.\n\n// WhiteoutPrefix prefix means file is a whiteout. If this is followed by a\n// filename this means that file has been removed from the base layer.\nconst WhiteoutPrefix = \".wh.\"\n\n// WhiteoutMetaPrefix prefix means whiteout has a special meaning and is not\n// for removing an actual file. Normally these files are excluded from exported\n// archives.\nconst WhiteoutMetaPrefix = WhiteoutPrefix + WhiteoutPrefix\n\n// WhiteoutLinkDir is a directory AUFS uses for storing hardlink links to other\n// layers. Normally these should not go into exported archives and all changed\n// hardlinks should be copied to the top layer.\nconst WhiteoutLinkDir = WhiteoutMetaPrefix + \"plnk\"\n\n// WhiteoutOpaqueDir file means directory has been made opaque - meaning\n// readdir calls to this directory do not follow to lower layers.\nconst WhiteoutOpaqueDir = WhiteoutMetaPrefix + \".opq\"\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/archive/wrap.go",
    "content": "package archive // import \"github.com/docker/docker/pkg/archive\"\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"io\"\n)\n\n// Generate generates a new archive from the content provided\n// as input.\n//\n// `files` is a sequence of path/content pairs. A new file is\n// added to the archive for each pair.\n// If the last pair is incomplete, the file is created with an\n// empty content. For example:\n//\n// Generate(\"foo.txt\", \"hello world\", \"emptyfile\")\n//\n// The above call will return an archive with 2 files:\n//   - ./foo.txt with content \"hello world\"\n//   - ./empty with empty content\n//\n// FIXME: stream content instead of buffering\n// FIXME: specify permissions and other archive metadata\nfunc Generate(input ...string) (io.Reader, error) {\n\tfiles := parseStringPairs(input...)\n\tbuf := new(bytes.Buffer)\n\ttw := tar.NewWriter(buf)\n\tfor _, file := range files {\n\t\tname, content := file[0], file[1]\n\t\thdr := &tar.Header{\n\t\t\tName: name,\n\t\t\tSize: int64(len(content)),\n\t\t}\n\t\tif err := tw.WriteHeader(hdr); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif _, err := tw.Write([]byte(content)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif err := tw.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn buf, nil\n}\n\nfunc parseStringPairs(input ...string) (output [][2]string) {\n\toutput = make([][2]string, 0, len(input)/2+1)\n\tfor i := 0; i < len(input); i += 2 {\n\t\tvar pair [2]string\n\t\tpair[0] = input[i]\n\t\tif i+1 < len(input) {\n\t\t\tpair[1] = input[i+1]\n\t\t}\n\t\toutput = append(output, pair)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/homedir/homedir.go",
    "content": "package homedir\n\nimport (\n\t\"os\"\n\t\"os/user\"\n\t\"runtime\"\n)\n\n// Key returns the env var name for the user's home dir based on\n// the platform being run on.\n//\n// Deprecated: this function is no longer used, and will be removed in the next release.\nfunc Key() string {\n\treturn envKeyName\n}\n\n// Get returns the home directory of the current user with the help of\n// environment variables depending on the target operating system.\n// Returned path should be used with \"path/filepath\" to form new paths.\n//\n// On non-Windows platforms, it falls back to nss lookups, if the home\n// directory cannot be obtained from environment-variables.\n//\n// If linking statically with cgo enabled against glibc, ensure the\n// osusergo build tag is used.\n//\n// If needing to do nss lookups, do not disable cgo or set osusergo.\nfunc Get() string {\n\thome, _ := os.UserHomeDir()\n\tif home == \"\" && runtime.GOOS != \"windows\" {\n\t\tif u, err := user.Current(); err == nil {\n\t\t\treturn u.HomeDir\n\t\t}\n\t}\n\treturn home\n}\n\n// GetShortcutString returns the string that is shortcut to user's home directory\n// in the native shell of the platform running on.\n//\n// Deprecated: this function is no longer used, and will be removed in the next release.\nfunc GetShortcutString() string {\n\treturn homeShortCut\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/homedir/homedir_linux.go",
    "content": "package homedir // import \"github.com/docker/docker/pkg/homedir\"\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// GetRuntimeDir returns XDG_RUNTIME_DIR.\n// XDG_RUNTIME_DIR is typically configured via pam_systemd.\n// GetRuntimeDir returns non-nil error if XDG_RUNTIME_DIR is not set.\n//\n// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html\nfunc GetRuntimeDir() (string, error) {\n\tif xdgRuntimeDir := os.Getenv(\"XDG_RUNTIME_DIR\"); xdgRuntimeDir != \"\" {\n\t\treturn xdgRuntimeDir, nil\n\t}\n\treturn \"\", errors.New(\"could not get XDG_RUNTIME_DIR\")\n}\n\n// StickRuntimeDirContents sets the sticky bit on files that are under\n// XDG_RUNTIME_DIR, so that the files won't be periodically removed by the system.\n//\n// StickyRuntimeDir returns slice of sticked files.\n// StickyRuntimeDir returns nil error if XDG_RUNTIME_DIR is not set.\n//\n// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html\nfunc StickRuntimeDirContents(files []string) ([]string, error) {\n\truntimeDir, err := GetRuntimeDir()\n\tif err != nil {\n\t\t// ignore error if runtimeDir is empty\n\t\treturn nil, nil\n\t}\n\truntimeDir, err = filepath.Abs(runtimeDir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar sticked []string\n\tfor _, f := range files {\n\t\tf, err = filepath.Abs(f)\n\t\tif err != nil {\n\t\t\treturn sticked, err\n\t\t}\n\t\tif strings.HasPrefix(f, runtimeDir+\"/\") {\n\t\t\tif err = stick(f); err != nil {\n\t\t\t\treturn sticked, err\n\t\t\t}\n\t\t\tsticked = append(sticked, f)\n\t\t}\n\t}\n\treturn sticked, nil\n}\n\nfunc stick(f string) error {\n\tst, err := os.Stat(f)\n\tif err != nil {\n\t\treturn err\n\t}\n\tm := st.Mode()\n\tm |= os.ModeSticky\n\treturn os.Chmod(f, m)\n}\n\n// GetDataHome returns XDG_DATA_HOME.\n// GetDataHome returns $HOME/.local/share and nil error if XDG_DATA_HOME is not set.\n// If HOME and XDG_DATA_HOME are not set, getpwent(3) is consulted to determine the users home directory.\n//\n// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html\nfunc GetDataHome() (string, error) {\n\tif xdgDataHome := os.Getenv(\"XDG_DATA_HOME\"); xdgDataHome != \"\" {\n\t\treturn xdgDataHome, nil\n\t}\n\thome := Get()\n\tif home == \"\" {\n\t\treturn \"\", errors.New(\"could not get either XDG_DATA_HOME or HOME\")\n\t}\n\treturn filepath.Join(home, \".local\", \"share\"), nil\n}\n\n// GetConfigHome returns XDG_CONFIG_HOME.\n// GetConfigHome returns $HOME/.config and nil error if XDG_CONFIG_HOME is not set.\n// If HOME and XDG_CONFIG_HOME are not set, getpwent(3) is consulted to determine the users home directory.\n//\n// See also https://standards.freedesktop.org/basedir-spec/latest/ar01s03.html\nfunc GetConfigHome() (string, error) {\n\tif xdgConfigHome := os.Getenv(\"XDG_CONFIG_HOME\"); xdgConfigHome != \"\" {\n\t\treturn xdgConfigHome, nil\n\t}\n\thome := Get()\n\tif home == \"\" {\n\t\treturn \"\", errors.New(\"could not get either XDG_CONFIG_HOME or HOME\")\n\t}\n\treturn filepath.Join(home, \".config\"), nil\n}\n\n// GetLibHome returns $HOME/.local/lib\n// If HOME is not set, getpwent(3) is consulted to determine the users home directory.\nfunc GetLibHome() (string, error) {\n\thome := Get()\n\tif home == \"\" {\n\t\treturn \"\", errors.New(\"could not get HOME\")\n\t}\n\treturn filepath.Join(home, \".local/lib\"), nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/homedir/homedir_others.go",
    "content": "//go:build !linux\n\npackage homedir // import \"github.com/docker/docker/pkg/homedir\"\n\nimport (\n\t\"errors\"\n)\n\n// GetRuntimeDir is unsupported on non-linux system.\nfunc GetRuntimeDir() (string, error) {\n\treturn \"\", errors.New(\"homedir.GetRuntimeDir() is not supported on this system\")\n}\n\n// StickRuntimeDirContents is unsupported on non-linux system.\nfunc StickRuntimeDirContents(files []string) ([]string, error) {\n\treturn nil, errors.New(\"homedir.StickRuntimeDirContents() is not supported on this system\")\n}\n\n// GetDataHome is unsupported on non-linux system.\nfunc GetDataHome() (string, error) {\n\treturn \"\", errors.New(\"homedir.GetDataHome() is not supported on this system\")\n}\n\n// GetConfigHome is unsupported on non-linux system.\nfunc GetConfigHome() (string, error) {\n\treturn \"\", errors.New(\"homedir.GetConfigHome() is not supported on this system\")\n}\n\n// GetLibHome is unsupported on non-linux system.\nfunc GetLibHome() (string, error) {\n\treturn \"\", errors.New(\"homedir.GetLibHome() is not supported on this system\")\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/homedir/homedir_unix.go",
    "content": "//go:build !windows\n\npackage homedir // import \"github.com/docker/docker/pkg/homedir\"\n\nconst (\n\tenvKeyName   = \"HOME\"\n\thomeShortCut = \"~\"\n)\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/homedir/homedir_windows.go",
    "content": "package homedir // import \"github.com/docker/docker/pkg/homedir\"\n\nconst (\n\tenvKeyName   = \"USERPROFILE\"\n\thomeShortCut = \"%USERPROFILE%\" // be careful while using in format functions\n)\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/idtools/idtools.go",
    "content": "package idtools // import \"github.com/docker/docker/pkg/idtools\"\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// IDMap contains a single entry for user namespace range remapping. An array\n// of IDMap entries represents the structure that will be provided to the Linux\n// kernel for creating a user namespace.\ntype IDMap struct {\n\tContainerID int `json:\"container_id\"`\n\tHostID      int `json:\"host_id\"`\n\tSize        int `json:\"size\"`\n}\n\ntype subIDRange struct {\n\tStart  int\n\tLength int\n}\n\ntype ranges []subIDRange\n\nfunc (e ranges) Len() int           { return len(e) }\nfunc (e ranges) Swap(i, j int)      { e[i], e[j] = e[j], e[i] }\nfunc (e ranges) Less(i, j int) bool { return e[i].Start < e[j].Start }\n\nconst (\n\tsubuidFileName = \"/etc/subuid\"\n\tsubgidFileName = \"/etc/subgid\"\n)\n\n// MkdirAllAndChown creates a directory (include any along the path) and then modifies\n// ownership to the requested uid/gid.  If the directory already exists, this\n// function will still change ownership and permissions.\nfunc MkdirAllAndChown(path string, mode os.FileMode, owner Identity) error {\n\treturn mkdirAs(path, mode, owner, true, true)\n}\n\n// MkdirAndChown creates a directory and then modifies ownership to the requested uid/gid.\n// If the directory already exists, this function still changes ownership and permissions.\n// Note that unlike os.Mkdir(), this function does not return IsExist error\n// in case path already exists.\nfunc MkdirAndChown(path string, mode os.FileMode, owner Identity) error {\n\treturn mkdirAs(path, mode, owner, false, true)\n}\n\n// MkdirAllAndChownNew creates a directory (include any along the path) and then modifies\n// ownership ONLY of newly created directories to the requested uid/gid. If the\n// directories along the path exist, no change of ownership or permissions will be performed\nfunc MkdirAllAndChownNew(path string, mode os.FileMode, owner Identity) error {\n\treturn mkdirAs(path, mode, owner, true, false)\n}\n\n// GetRootUIDGID retrieves the remapped root uid/gid pair from the set of maps.\n// If the maps are empty, then the root uid/gid will default to \"real\" 0/0\nfunc GetRootUIDGID(uidMap, gidMap []IDMap) (int, int, error) {\n\tuid, err := toHost(0, uidMap)\n\tif err != nil {\n\t\treturn -1, -1, err\n\t}\n\tgid, err := toHost(0, gidMap)\n\tif err != nil {\n\t\treturn -1, -1, err\n\t}\n\treturn uid, gid, nil\n}\n\n// toContainer takes an id mapping, and uses it to translate a\n// host ID to the remapped ID. If no map is provided, then the translation\n// assumes a 1-to-1 mapping and returns the passed in id\nfunc toContainer(hostID int, idMap []IDMap) (int, error) {\n\tif idMap == nil {\n\t\treturn hostID, nil\n\t}\n\tfor _, m := range idMap {\n\t\tif (hostID >= m.HostID) && (hostID <= (m.HostID + m.Size - 1)) {\n\t\t\tcontID := m.ContainerID + (hostID - m.HostID)\n\t\t\treturn contID, nil\n\t\t}\n\t}\n\treturn -1, fmt.Errorf(\"Host ID %d cannot be mapped to a container ID\", hostID)\n}\n\n// toHost takes an id mapping and a remapped ID, and translates the\n// ID to the mapped host ID. If no map is provided, then the translation\n// assumes a 1-to-1 mapping and returns the passed in id #\nfunc toHost(contID int, idMap []IDMap) (int, error) {\n\tif idMap == nil {\n\t\treturn contID, nil\n\t}\n\tfor _, m := range idMap {\n\t\tif (contID >= m.ContainerID) && (contID <= (m.ContainerID + m.Size - 1)) {\n\t\t\thostID := m.HostID + (contID - m.ContainerID)\n\t\t\treturn hostID, nil\n\t\t}\n\t}\n\treturn -1, fmt.Errorf(\"Container ID %d cannot be mapped to a host ID\", contID)\n}\n\n// Identity is either a UID and GID pair or a SID (but not both)\ntype Identity struct {\n\tUID int\n\tGID int\n\tSID string\n}\n\n// Chown changes the numeric uid and gid of the named file to id.UID and id.GID.\nfunc (id Identity) Chown(name string) error {\n\treturn os.Chown(name, id.UID, id.GID)\n}\n\n// IdentityMapping contains a mappings of UIDs and GIDs.\n// The zero value represents an empty mapping.\ntype IdentityMapping struct {\n\tUIDMaps []IDMap `json:\"UIDMaps\"`\n\tGIDMaps []IDMap `json:\"GIDMaps\"`\n}\n\n// RootPair returns a uid and gid pair for the root user. The error is ignored\n// because a root user always exists, and the defaults are correct when the uid\n// and gid maps are empty.\nfunc (i IdentityMapping) RootPair() Identity {\n\tuid, gid, _ := GetRootUIDGID(i.UIDMaps, i.GIDMaps)\n\treturn Identity{UID: uid, GID: gid}\n}\n\n// ToHost returns the host UID and GID for the container uid, gid.\n// Remapping is only performed if the ids aren't already the remapped root ids\nfunc (i IdentityMapping) ToHost(pair Identity) (Identity, error) {\n\tvar err error\n\ttarget := i.RootPair()\n\n\tif pair.UID != target.UID {\n\t\ttarget.UID, err = toHost(pair.UID, i.UIDMaps)\n\t\tif err != nil {\n\t\t\treturn target, err\n\t\t}\n\t}\n\n\tif pair.GID != target.GID {\n\t\ttarget.GID, err = toHost(pair.GID, i.GIDMaps)\n\t}\n\treturn target, err\n}\n\n// ToContainer returns the container UID and GID for the host uid and gid\nfunc (i IdentityMapping) ToContainer(pair Identity) (int, int, error) {\n\tuid, err := toContainer(pair.UID, i.UIDMaps)\n\tif err != nil {\n\t\treturn -1, -1, err\n\t}\n\tgid, err := toContainer(pair.GID, i.GIDMaps)\n\treturn uid, gid, err\n}\n\n// Empty returns true if there are no id mappings\nfunc (i IdentityMapping) Empty() bool {\n\treturn len(i.UIDMaps) == 0 && len(i.GIDMaps) == 0\n}\n\nfunc createIDMap(subidRanges ranges) []IDMap {\n\tidMap := []IDMap{}\n\n\tcontainerID := 0\n\tfor _, idrange := range subidRanges {\n\t\tidMap = append(idMap, IDMap{\n\t\t\tContainerID: containerID,\n\t\t\tHostID:      idrange.Start,\n\t\t\tSize:        idrange.Length,\n\t\t})\n\t\tcontainerID = containerID + idrange.Length\n\t}\n\treturn idMap\n}\n\nfunc parseSubuid(username string) (ranges, error) {\n\treturn parseSubidFile(subuidFileName, username)\n}\n\nfunc parseSubgid(username string) (ranges, error) {\n\treturn parseSubidFile(subgidFileName, username)\n}\n\n// parseSubidFile will read the appropriate file (/etc/subuid or /etc/subgid)\n// and return all found ranges for a specified username. If the special value\n// \"ALL\" is supplied for username, then all ranges in the file will be returned\nfunc parseSubidFile(path, username string) (ranges, error) {\n\tvar rangeList ranges\n\n\tsubidFile, err := os.Open(path)\n\tif err != nil {\n\t\treturn rangeList, err\n\t}\n\tdefer subidFile.Close()\n\n\ts := bufio.NewScanner(subidFile)\n\tfor s.Scan() {\n\t\ttext := strings.TrimSpace(s.Text())\n\t\tif text == \"\" || strings.HasPrefix(text, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tparts := strings.Split(text, \":\")\n\t\tif len(parts) != 3 {\n\t\t\treturn rangeList, fmt.Errorf(\"Cannot parse subuid/gid information: Format not correct for %s file\", path)\n\t\t}\n\t\tif parts[0] == username || username == \"ALL\" {\n\t\t\tstartid, err := strconv.Atoi(parts[1])\n\t\t\tif err != nil {\n\t\t\t\treturn rangeList, fmt.Errorf(\"String to int conversion failed during subuid/gid parsing of %s: %v\", path, err)\n\t\t\t}\n\t\t\tlength, err := strconv.Atoi(parts[2])\n\t\t\tif err != nil {\n\t\t\t\treturn rangeList, fmt.Errorf(\"String to int conversion failed during subuid/gid parsing of %s: %v\", path, err)\n\t\t\t}\n\t\t\trangeList = append(rangeList, subIDRange{startid, length})\n\t\t}\n\t}\n\n\treturn rangeList, s.Err()\n}\n\n// CurrentIdentity returns the identity of the current process\nfunc CurrentIdentity() Identity {\n\treturn Identity{UID: os.Getuid(), GID: os.Getegid()}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/idtools/idtools_unix.go",
    "content": "//go:build !windows\n\npackage idtools // import \"github.com/docker/docker/pkg/idtools\"\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"syscall\"\n\n\t\"github.com/moby/sys/user\"\n)\n\nfunc mkdirAs(path string, mode os.FileMode, owner Identity, mkAll, chownExisting bool) error {\n\tpath, err := filepath.Abs(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tstat, err := os.Stat(path)\n\tif err == nil {\n\t\tif !stat.IsDir() {\n\t\t\treturn &os.PathError{Op: \"mkdir\", Path: path, Err: syscall.ENOTDIR}\n\t\t}\n\t\tif !chownExisting {\n\t\t\treturn nil\n\t\t}\n\n\t\t// short-circuit -- we were called with an existing directory and chown was requested\n\t\treturn setPermissions(path, mode, owner, stat)\n\t}\n\n\t// make an array containing the original path asked for, plus (for mkAll == true)\n\t// all path components leading up to the complete path that don't exist before we MkdirAll\n\t// so that we can chown all of them properly at the end.  If chownExisting is false, we won't\n\t// chown the full directory path if it exists\n\tvar paths []string\n\tif os.IsNotExist(err) {\n\t\tpaths = []string{path}\n\t}\n\n\tif mkAll {\n\t\t// walk back to \"/\" looking for directories which do not exist\n\t\t// and add them to the paths array for chown after creation\n\t\tdirPath := path\n\t\tfor {\n\t\t\tdirPath = filepath.Dir(dirPath)\n\t\t\tif dirPath == \"/\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif _, err = os.Stat(dirPath); err != nil && os.IsNotExist(err) {\n\t\t\t\tpaths = append(paths, dirPath)\n\t\t\t}\n\t\t}\n\t\tif err = os.MkdirAll(path, mode); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if err = os.Mkdir(path, mode); err != nil {\n\t\treturn err\n\t}\n\t// even if it existed, we will chown the requested path + any subpaths that\n\t// didn't exist when we called MkdirAll\n\tfor _, pathComponent := range paths {\n\t\tif err = setPermissions(pathComponent, mode, owner, nil); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// LookupUser uses traditional local system files lookup (from libcontainer/user) on a username,\n// followed by a call to `getent` for supporting host configured non-files passwd and group dbs\nfunc LookupUser(name string) (user.User, error) {\n\t// first try a local system files lookup using existing capabilities\n\tusr, err := user.LookupUser(name)\n\tif err == nil {\n\t\treturn usr, nil\n\t}\n\t// local files lookup failed; attempt to call `getent` to query configured passwd dbs\n\tusr, err = getentUser(name)\n\tif err != nil {\n\t\treturn user.User{}, err\n\t}\n\treturn usr, nil\n}\n\n// LookupUID uses traditional local system files lookup (from libcontainer/user) on a uid,\n// followed by a call to `getent` for supporting host configured non-files passwd and group dbs\nfunc LookupUID(uid int) (user.User, error) {\n\t// first try a local system files lookup using existing capabilities\n\tusr, err := user.LookupUid(uid)\n\tif err == nil {\n\t\treturn usr, nil\n\t}\n\t// local files lookup failed; attempt to call `getent` to query configured passwd dbs\n\treturn getentUser(strconv.Itoa(uid))\n}\n\nfunc getentUser(name string) (user.User, error) {\n\treader, err := callGetent(\"passwd\", name)\n\tif err != nil {\n\t\treturn user.User{}, err\n\t}\n\tusers, err := user.ParsePasswd(reader)\n\tif err != nil {\n\t\treturn user.User{}, err\n\t}\n\tif len(users) == 0 {\n\t\treturn user.User{}, fmt.Errorf(\"getent failed to find passwd entry for %q\", name)\n\t}\n\treturn users[0], nil\n}\n\n// LookupGroup uses traditional local system files lookup (from libcontainer/user) on a group name,\n// followed by a call to `getent` for supporting host configured non-files passwd and group dbs\nfunc LookupGroup(name string) (user.Group, error) {\n\t// first try a local system files lookup using existing capabilities\n\tgroup, err := user.LookupGroup(name)\n\tif err == nil {\n\t\treturn group, nil\n\t}\n\t// local files lookup failed; attempt to call `getent` to query configured group dbs\n\treturn getentGroup(name)\n}\n\n// LookupGID uses traditional local system files lookup (from libcontainer/user) on a group ID,\n// followed by a call to `getent` for supporting host configured non-files passwd and group dbs\nfunc LookupGID(gid int) (user.Group, error) {\n\t// first try a local system files lookup using existing capabilities\n\tgroup, err := user.LookupGid(gid)\n\tif err == nil {\n\t\treturn group, nil\n\t}\n\t// local files lookup failed; attempt to call `getent` to query configured group dbs\n\treturn getentGroup(strconv.Itoa(gid))\n}\n\nfunc getentGroup(name string) (user.Group, error) {\n\treader, err := callGetent(\"group\", name)\n\tif err != nil {\n\t\treturn user.Group{}, err\n\t}\n\tgroups, err := user.ParseGroup(reader)\n\tif err != nil {\n\t\treturn user.Group{}, err\n\t}\n\tif len(groups) == 0 {\n\t\treturn user.Group{}, fmt.Errorf(\"getent failed to find groups entry for %q\", name)\n\t}\n\treturn groups[0], nil\n}\n\nfunc callGetent(database, key string) (io.Reader, error) {\n\tgetentCmd, err := resolveBinary(\"getent\")\n\t// if no `getent` command within the execution environment, can't do anything else\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to find getent command: %w\", err)\n\t}\n\tcommand := exec.Command(getentCmd, database, key)\n\t// we run getent within container filesystem, but without /dev so /dev/null is not available for exec to mock stdin\n\tcommand.Stdin = io.NopCloser(bytes.NewReader(nil))\n\tout, err := command.CombinedOutput()\n\tif err != nil {\n\t\texitCode, errC := getExitCode(err)\n\t\tif errC != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tswitch exitCode {\n\t\tcase 1:\n\t\t\treturn nil, fmt.Errorf(\"getent reported invalid parameters/database unknown\")\n\t\tcase 2:\n\t\t\treturn nil, fmt.Errorf(\"getent unable to find entry %q in %s database\", key, database)\n\t\tcase 3:\n\t\t\treturn nil, fmt.Errorf(\"getent database doesn't support enumeration\")\n\t\tdefault:\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn bytes.NewReader(out), nil\n}\n\n// getExitCode returns the ExitStatus of the specified error if its type is\n// exec.ExitError, returns 0 and an error otherwise.\nfunc getExitCode(err error) (int, error) {\n\texitCode := 0\n\tif exiterr, ok := err.(*exec.ExitError); ok {\n\t\tif procExit, ok := exiterr.Sys().(syscall.WaitStatus); ok {\n\t\t\treturn procExit.ExitStatus(), nil\n\t\t}\n\t}\n\treturn exitCode, fmt.Errorf(\"failed to get exit code\")\n}\n\n// setPermissions performs a chown/chmod only if the uid/gid don't match what's requested\n// Normally a Chown is a no-op if uid/gid match, but in some cases this can still cause an error, e.g. if the\n// dir is on an NFS share, so don't call chown unless we absolutely must.\n// Likewise for setting permissions.\nfunc setPermissions(p string, mode os.FileMode, owner Identity, stat os.FileInfo) error {\n\tif stat == nil {\n\t\tvar err error\n\t\tstat, err = os.Stat(p)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif stat.Mode().Perm() != mode.Perm() {\n\t\tif err := os.Chmod(p, mode.Perm()); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tssi := stat.Sys().(*syscall.Stat_t)\n\tif ssi.Uid == uint32(owner.UID) && ssi.Gid == uint32(owner.GID) {\n\t\treturn nil\n\t}\n\treturn os.Chown(p, owner.UID, owner.GID)\n}\n\n// LoadIdentityMapping takes a requested username and\n// using the data from /etc/sub{uid,gid} ranges, creates the\n// proper uid and gid remapping ranges for that user/group pair\nfunc LoadIdentityMapping(name string) (IdentityMapping, error) {\n\tusr, err := LookupUser(name)\n\tif err != nil {\n\t\treturn IdentityMapping{}, fmt.Errorf(\"could not get user for username %s: %v\", name, err)\n\t}\n\n\tsubuidRanges, err := lookupSubUIDRanges(usr)\n\tif err != nil {\n\t\treturn IdentityMapping{}, err\n\t}\n\tsubgidRanges, err := lookupSubGIDRanges(usr)\n\tif err != nil {\n\t\treturn IdentityMapping{}, err\n\t}\n\n\treturn IdentityMapping{\n\t\tUIDMaps: subuidRanges,\n\t\tGIDMaps: subgidRanges,\n\t}, nil\n}\n\nfunc lookupSubUIDRanges(usr user.User) ([]IDMap, error) {\n\trangeList, err := parseSubuid(strconv.Itoa(usr.Uid))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(rangeList) == 0 {\n\t\trangeList, err = parseSubuid(usr.Name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif len(rangeList) == 0 {\n\t\treturn nil, fmt.Errorf(\"no subuid ranges found for user %q\", usr.Name)\n\t}\n\treturn createIDMap(rangeList), nil\n}\n\nfunc lookupSubGIDRanges(usr user.User) ([]IDMap, error) {\n\trangeList, err := parseSubgid(strconv.Itoa(usr.Uid))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(rangeList) == 0 {\n\t\trangeList, err = parseSubgid(usr.Name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif len(rangeList) == 0 {\n\t\treturn nil, fmt.Errorf(\"no subgid ranges found for user %q\", usr.Name)\n\t}\n\treturn createIDMap(rangeList), nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/idtools/idtools_windows.go",
    "content": "package idtools // import \"github.com/docker/docker/pkg/idtools\"\n\nimport (\n\t\"os\"\n\n\t\"github.com/docker/docker/pkg/system\"\n)\n\nconst (\n\tSeTakeOwnershipPrivilege = \"SeTakeOwnershipPrivilege\"\n)\n\nconst (\n\tContainerAdministratorSidString = \"S-1-5-93-2-1\"\n\tContainerUserSidString          = \"S-1-5-93-2-2\"\n)\n\n// This is currently a wrapper around MkdirAll, however, since currently\n// permissions aren't set through this path, the identity isn't utilized.\n// Ownership is handled elsewhere, but in the future could be support here\n// too.\nfunc mkdirAs(path string, _ os.FileMode, _ Identity, _, _ bool) error {\n\treturn system.MkdirAll(path, 0)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/idtools/usergroupadd_linux.go",
    "content": "package idtools // import \"github.com/docker/docker/pkg/idtools\"\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// add a user and/or group to Linux /etc/passwd, /etc/group using standard\n// Linux distribution commands:\n// adduser --system --shell /bin/false --disabled-login --disabled-password --no-create-home --group <username>\n// useradd -r -s /bin/false <username>\n\nvar (\n\tonce        sync.Once\n\tuserCommand string\n\tidOutRegexp = regexp.MustCompile(`uid=([0-9]+).*gid=([0-9]+)`)\n)\n\nconst (\n\t// default length for a UID/GID subordinate range\n\tdefaultRangeLen   = 65536\n\tdefaultRangeStart = 100000\n)\n\n// AddNamespaceRangesUser takes a username and uses the standard system\n// utility to create a system user/group pair used to hold the\n// /etc/sub{uid,gid} ranges which will be used for user namespace\n// mapping ranges in containers.\nfunc AddNamespaceRangesUser(name string) (int, int, error) {\n\tif err := addUser(name); err != nil {\n\t\treturn -1, -1, fmt.Errorf(\"error adding user %q: %v\", name, err)\n\t}\n\n\t// Query the system for the created uid and gid pair\n\tout, err := exec.Command(\"id\", name).CombinedOutput()\n\tif err != nil {\n\t\treturn -1, -1, fmt.Errorf(\"error trying to find uid/gid for new user %q: %v\", name, err)\n\t}\n\tmatches := idOutRegexp.FindStringSubmatch(strings.TrimSpace(string(out)))\n\tif len(matches) != 3 {\n\t\treturn -1, -1, fmt.Errorf(\"can't find uid, gid from `id` output: %q\", string(out))\n\t}\n\tuid, err := strconv.Atoi(matches[1])\n\tif err != nil {\n\t\treturn -1, -1, fmt.Errorf(\"can't convert found uid (%s) to int: %v\", matches[1], err)\n\t}\n\tgid, err := strconv.Atoi(matches[2])\n\tif err != nil {\n\t\treturn -1, -1, fmt.Errorf(\"Can't convert found gid (%s) to int: %v\", matches[2], err)\n\t}\n\n\t// Now we need to create the subuid/subgid ranges for our new user/group (system users\n\t// do not get auto-created ranges in subuid/subgid)\n\n\tif err := createSubordinateRanges(name); err != nil {\n\t\treturn -1, -1, fmt.Errorf(\"couldn't create subordinate ID ranges: %v\", err)\n\t}\n\treturn uid, gid, nil\n}\n\nfunc addUser(name string) error {\n\tonce.Do(func() {\n\t\t// set up which commands are used for adding users/groups dependent on distro\n\t\tif _, err := resolveBinary(\"adduser\"); err == nil {\n\t\t\tuserCommand = \"adduser\"\n\t\t} else if _, err := resolveBinary(\"useradd\"); err == nil {\n\t\t\tuserCommand = \"useradd\"\n\t\t}\n\t})\n\tvar args []string\n\tswitch userCommand {\n\tcase \"adduser\":\n\t\targs = []string{\"--system\", \"--shell\", \"/bin/false\", \"--no-create-home\", \"--disabled-login\", \"--disabled-password\", \"--group\", name}\n\tcase \"useradd\":\n\t\targs = []string{\"-r\", \"-s\", \"/bin/false\", name}\n\tdefault:\n\t\treturn fmt.Errorf(\"cannot add user; no useradd/adduser binary found\")\n\t}\n\n\tif out, err := exec.Command(userCommand, args...).CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"failed to add user with error: %v; output: %q\", err, string(out))\n\t}\n\treturn nil\n}\n\nfunc createSubordinateRanges(name string) error {\n\t// first, we should verify that ranges weren't automatically created\n\t// by the distro tooling\n\tranges, err := parseSubuid(name)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error while looking for subuid ranges for user %q: %v\", name, err)\n\t}\n\tif len(ranges) == 0 {\n\t\t// no UID ranges; let's create one\n\t\tstartID, err := findNextUIDRange()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"can't find available subuid range: %v\", err)\n\t\t}\n\t\tidRange := fmt.Sprintf(\"%d-%d\", startID, startID+defaultRangeLen-1)\n\t\tout, err := exec.Command(\"usermod\", \"-v\", idRange, name).CombinedOutput()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to add subuid range to user: %q; output: %s, err: %v\", name, out, err)\n\t\t}\n\t}\n\n\tranges, err = parseSubgid(name)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error while looking for subgid ranges for user %q: %v\", name, err)\n\t}\n\tif len(ranges) == 0 {\n\t\t// no GID ranges; let's create one\n\t\tstartID, err := findNextGIDRange()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"can't find available subgid range: %v\", err)\n\t\t}\n\t\tidRange := fmt.Sprintf(\"%d-%d\", startID, startID+defaultRangeLen-1)\n\t\tout, err := exec.Command(\"usermod\", \"-w\", idRange, name).CombinedOutput()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to add subgid range to user: %q; output: %s, err: %v\", name, out, err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc findNextUIDRange() (int, error) {\n\tranges, err := parseSubuid(\"ALL\")\n\tif err != nil {\n\t\treturn -1, fmt.Errorf(\"couldn't parse all ranges in /etc/subuid file: %v\", err)\n\t}\n\tsort.Sort(ranges)\n\treturn findNextRangeStart(ranges)\n}\n\nfunc findNextGIDRange() (int, error) {\n\tranges, err := parseSubgid(\"ALL\")\n\tif err != nil {\n\t\treturn -1, fmt.Errorf(\"couldn't parse all ranges in /etc/subgid file: %v\", err)\n\t}\n\tsort.Sort(ranges)\n\treturn findNextRangeStart(ranges)\n}\n\nfunc findNextRangeStart(rangeList ranges) (int, error) {\n\tstartID := defaultRangeStart\n\tfor _, arange := range rangeList {\n\t\tif wouldOverlap(arange, startID) {\n\t\t\tstartID = arange.Start + arange.Length\n\t\t}\n\t}\n\treturn startID, nil\n}\n\nfunc wouldOverlap(arange subIDRange, ID int) bool {\n\tlow := ID\n\thigh := ID + defaultRangeLen\n\tif (low >= arange.Start && low <= arange.Start+arange.Length) ||\n\t\t(high <= arange.Start+arange.Length && high >= arange.Start) {\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/idtools/usergroupadd_unsupported.go",
    "content": "//go:build !linux\n\npackage idtools // import \"github.com/docker/docker/pkg/idtools\"\n\nimport \"fmt\"\n\n// AddNamespaceRangesUser takes a name and finds an unused uid, gid pair\n// and calls the appropriate helper function to add the group and then\n// the user to the group in /etc/group and /etc/passwd respectively.\nfunc AddNamespaceRangesUser(name string) (int, int, error) {\n\treturn -1, -1, fmt.Errorf(\"No support for adding users or groups on this OS\")\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/idtools/utils_unix.go",
    "content": "//go:build !windows\n\npackage idtools // import \"github.com/docker/docker/pkg/idtools\"\n\nimport (\n\t\"fmt\"\n\t\"os/exec\"\n\t\"path/filepath\"\n)\n\nfunc resolveBinary(binname string) (string, error) {\n\tbinaryPath, err := exec.LookPath(binname)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tresolvedPath, err := filepath.EvalSymlinks(binaryPath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\t// only return no error if the final resolved binary basename\n\t// matches what was searched for\n\tif filepath.Base(resolvedPath) == binname {\n\t\treturn resolvedPath, nil\n\t}\n\treturn \"\", fmt.Errorf(\"Binary %q does not resolve to a binary of that name in $PATH (%q)\", binname, resolvedPath)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/ioutils/buffer.go",
    "content": "package ioutils // import \"github.com/docker/docker/pkg/ioutils\"\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\nvar errBufferFull = errors.New(\"buffer is full\")\n\ntype fixedBuffer struct {\n\tbuf      []byte\n\tpos      int\n\tlastRead int\n}\n\nfunc (b *fixedBuffer) Write(p []byte) (int, error) {\n\tn := copy(b.buf[b.pos:cap(b.buf)], p)\n\tb.pos += n\n\n\tif n < len(p) {\n\t\tif b.pos == cap(b.buf) {\n\t\t\treturn n, errBufferFull\n\t\t}\n\t\treturn n, io.ErrShortWrite\n\t}\n\treturn n, nil\n}\n\nfunc (b *fixedBuffer) Read(p []byte) (int, error) {\n\tn := copy(p, b.buf[b.lastRead:b.pos])\n\tb.lastRead += n\n\treturn n, nil\n}\n\nfunc (b *fixedBuffer) Len() int {\n\treturn b.pos - b.lastRead\n}\n\nfunc (b *fixedBuffer) Cap() int {\n\treturn cap(b.buf)\n}\n\nfunc (b *fixedBuffer) Reset() {\n\tb.pos = 0\n\tb.lastRead = 0\n\tb.buf = b.buf[:0]\n}\n\nfunc (b *fixedBuffer) String() string {\n\treturn string(b.buf[b.lastRead:b.pos])\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/ioutils/bytespipe.go",
    "content": "package ioutils // import \"github.com/docker/docker/pkg/ioutils\"\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n)\n\n// maxCap is the highest capacity to use in byte slices that buffer data.\nconst maxCap = 1e6\n\n// minCap is the lowest capacity to use in byte slices that buffer data\nconst minCap = 64\n\n// blockThreshold is the minimum number of bytes in the buffer which will cause\n// a write to BytesPipe to block when allocating a new slice.\nconst blockThreshold = 1e6\n\nvar (\n\t// ErrClosed is returned when Write is called on a closed BytesPipe.\n\tErrClosed = errors.New(\"write to closed BytesPipe\")\n\n\tbufPools     = make(map[int]*sync.Pool)\n\tbufPoolsLock sync.Mutex\n)\n\n// BytesPipe is io.ReadWriteCloser which works similarly to pipe(queue).\n// All written data may be read at most once. Also, BytesPipe allocates\n// and releases new byte slices to adjust to current needs, so the buffer\n// won't be overgrown after peak loads.\ntype BytesPipe struct {\n\tmu        sync.Mutex\n\twait      *sync.Cond\n\tbuf       []*fixedBuffer\n\tbufLen    int\n\tcloseErr  error // error to return from next Read. set to nil if not closed.\n\treadBlock bool  // check read BytesPipe is Wait() or not\n}\n\n// NewBytesPipe creates new BytesPipe, initialized by specified slice.\n// If buf is nil, then it will be initialized with slice which cap is 64.\n// buf will be adjusted in a way that len(buf) == 0, cap(buf) == cap(buf).\nfunc NewBytesPipe() *BytesPipe {\n\tbp := &BytesPipe{}\n\tbp.buf = append(bp.buf, getBuffer(minCap))\n\tbp.wait = sync.NewCond(&bp.mu)\n\treturn bp\n}\n\n// Write writes p to BytesPipe.\n// It can allocate new []byte slices in a process of writing.\nfunc (bp *BytesPipe) Write(p []byte) (int, error) {\n\tbp.mu.Lock()\n\tdefer bp.mu.Unlock()\n\n\twritten := 0\nloop0:\n\tfor {\n\t\tif bp.closeErr != nil {\n\t\t\treturn written, ErrClosed\n\t\t}\n\n\t\tif len(bp.buf) == 0 {\n\t\t\tbp.buf = append(bp.buf, getBuffer(64))\n\t\t}\n\t\t// get the last buffer\n\t\tb := bp.buf[len(bp.buf)-1]\n\n\t\tn, err := b.Write(p)\n\t\twritten += n\n\t\tbp.bufLen += n\n\n\t\t// errBufferFull is an error we expect to get if the buffer is full\n\t\tif err != nil && err != errBufferFull {\n\t\t\tbp.wait.Broadcast()\n\t\t\treturn written, err\n\t\t}\n\n\t\t// if there was enough room to write all then break\n\t\tif len(p) == n {\n\t\t\tbreak\n\t\t}\n\n\t\t// more data: write to the next slice\n\t\tp = p[n:]\n\n\t\t// make sure the buffer doesn't grow too big from this write\n\t\tfor bp.bufLen >= blockThreshold {\n\t\t\tif bp.readBlock {\n\t\t\t\tbp.wait.Broadcast()\n\t\t\t}\n\t\t\tbp.wait.Wait()\n\t\t\tif bp.closeErr != nil {\n\t\t\t\tcontinue loop0\n\t\t\t}\n\t\t}\n\n\t\t// add new byte slice to the buffers slice and continue writing\n\t\tnextCap := b.Cap() * 2\n\t\tif nextCap > maxCap {\n\t\t\tnextCap = maxCap\n\t\t}\n\t\tbp.buf = append(bp.buf, getBuffer(nextCap))\n\t}\n\tbp.wait.Broadcast()\n\treturn written, nil\n}\n\n// CloseWithError causes further reads from a BytesPipe to return immediately.\nfunc (bp *BytesPipe) CloseWithError(err error) error {\n\tbp.mu.Lock()\n\tif err != nil {\n\t\tbp.closeErr = err\n\t} else {\n\t\tbp.closeErr = io.EOF\n\t}\n\tbp.wait.Broadcast()\n\tbp.mu.Unlock()\n\treturn nil\n}\n\n// Close causes further reads from a BytesPipe to return immediately.\nfunc (bp *BytesPipe) Close() error {\n\treturn bp.CloseWithError(nil)\n}\n\n// Read reads bytes from BytesPipe.\n// Data could be read only once.\nfunc (bp *BytesPipe) Read(p []byte) (n int, err error) {\n\tbp.mu.Lock()\n\tdefer bp.mu.Unlock()\n\tif bp.bufLen == 0 {\n\t\tif bp.closeErr != nil {\n\t\t\treturn 0, bp.closeErr\n\t\t}\n\t\tbp.readBlock = true\n\t\tbp.wait.Wait()\n\t\tbp.readBlock = false\n\t\tif bp.bufLen == 0 && bp.closeErr != nil {\n\t\t\treturn 0, bp.closeErr\n\t\t}\n\t}\n\n\tfor bp.bufLen > 0 {\n\t\tb := bp.buf[0]\n\t\tread, _ := b.Read(p) // ignore error since fixedBuffer doesn't really return an error\n\t\tn += read\n\t\tbp.bufLen -= read\n\n\t\tif b.Len() == 0 {\n\t\t\t// it's empty so return it to the pool and move to the next one\n\t\t\treturnBuffer(b)\n\t\t\tbp.buf[0] = nil\n\t\t\tbp.buf = bp.buf[1:]\n\t\t}\n\n\t\tif len(p) == read {\n\t\t\tbreak\n\t\t}\n\n\t\tp = p[read:]\n\t}\n\n\tbp.wait.Broadcast()\n\treturn\n}\n\nfunc returnBuffer(b *fixedBuffer) {\n\tb.Reset()\n\tbufPoolsLock.Lock()\n\tpool := bufPools[b.Cap()]\n\tbufPoolsLock.Unlock()\n\tif pool != nil {\n\t\tpool.Put(b)\n\t}\n}\n\nfunc getBuffer(size int) *fixedBuffer {\n\tbufPoolsLock.Lock()\n\tpool, ok := bufPools[size]\n\tif !ok {\n\t\tpool = &sync.Pool{New: func() interface{} { return &fixedBuffer{buf: make([]byte, 0, size)} }}\n\t\tbufPools[size] = pool\n\t}\n\tbufPoolsLock.Unlock()\n\treturn pool.Get().(*fixedBuffer)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/ioutils/fswriters.go",
    "content": "package ioutils // import \"github.com/docker/docker/pkg/ioutils\"\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\n// NewAtomicFileWriter returns WriteCloser so that writing to it writes to a\n// temporary file and closing it atomically changes the temporary file to\n// destination path. Writing and closing concurrently is not allowed.\nfunc NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, error) {\n\tf, err := os.CreateTemp(filepath.Dir(filename), \".tmp-\"+filepath.Base(filename))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tabspath, err := filepath.Abs(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &atomicFileWriter{\n\t\tf:    f,\n\t\tfn:   abspath,\n\t\tperm: perm,\n\t}, nil\n}\n\n// AtomicWriteFile atomically writes data to a file named by filename.\nfunc AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {\n\tf, err := NewAtomicFileWriter(filename, perm)\n\tif err != nil {\n\t\treturn err\n\t}\n\tn, err := f.Write(data)\n\tif err == nil && n < len(data) {\n\t\terr = io.ErrShortWrite\n\t\tf.(*atomicFileWriter).writeErr = err\n\t}\n\tif err1 := f.Close(); err == nil {\n\t\terr = err1\n\t}\n\treturn err\n}\n\ntype atomicFileWriter struct {\n\tf        *os.File\n\tfn       string\n\twriteErr error\n\tperm     os.FileMode\n}\n\nfunc (w *atomicFileWriter) Write(dt []byte) (int, error) {\n\tn, err := w.f.Write(dt)\n\tif err != nil {\n\t\tw.writeErr = err\n\t}\n\treturn n, err\n}\n\nfunc (w *atomicFileWriter) Close() (retErr error) {\n\tdefer func() {\n\t\tif retErr != nil || w.writeErr != nil {\n\t\t\tos.Remove(w.f.Name())\n\t\t}\n\t}()\n\tif err := w.f.Sync(); err != nil {\n\t\tw.f.Close()\n\t\treturn err\n\t}\n\tif err := w.f.Close(); err != nil {\n\t\treturn err\n\t}\n\tif err := os.Chmod(w.f.Name(), w.perm); err != nil {\n\t\treturn err\n\t}\n\tif w.writeErr == nil {\n\t\treturn os.Rename(w.f.Name(), w.fn)\n\t}\n\treturn nil\n}\n\n// AtomicWriteSet is used to atomically write a set\n// of files and ensure they are visible at the same time.\n// Must be committed to a new directory.\ntype AtomicWriteSet struct {\n\troot string\n}\n\n// NewAtomicWriteSet creates a new atomic write set to\n// atomically create a set of files. The given directory\n// is used as the base directory for storing files before\n// commit. If no temporary directory is given the system\n// default is used.\nfunc NewAtomicWriteSet(tmpDir string) (*AtomicWriteSet, error) {\n\ttd, err := os.MkdirTemp(tmpDir, \"write-set-\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &AtomicWriteSet{\n\t\troot: td,\n\t}, nil\n}\n\n// WriteFile writes a file to the set, guaranteeing the file\n// has been synced.\nfunc (ws *AtomicWriteSet) WriteFile(filename string, data []byte, perm os.FileMode) error {\n\tf, err := ws.FileWriter(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)\n\tif err != nil {\n\t\treturn err\n\t}\n\tn, err := f.Write(data)\n\tif err == nil && n < len(data) {\n\t\terr = io.ErrShortWrite\n\t}\n\tif err1 := f.Close(); err == nil {\n\t\terr = err1\n\t}\n\treturn err\n}\n\ntype syncFileCloser struct {\n\t*os.File\n}\n\nfunc (w syncFileCloser) Close() error {\n\terr := w.File.Sync()\n\tif err1 := w.File.Close(); err == nil {\n\t\terr = err1\n\t}\n\treturn err\n}\n\n// FileWriter opens a file writer inside the set. The file\n// should be synced and closed before calling commit.\nfunc (ws *AtomicWriteSet) FileWriter(name string, flag int, perm os.FileMode) (io.WriteCloser, error) {\n\tf, err := os.OpenFile(filepath.Join(ws.root, name), flag, perm)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn syncFileCloser{f}, nil\n}\n\n// Cancel cancels the set and removes all temporary data\n// created in the set.\nfunc (ws *AtomicWriteSet) Cancel() error {\n\treturn os.RemoveAll(ws.root)\n}\n\n// Commit moves all created files to the target directory. The\n// target directory must not exist and the parent of the target\n// directory must exist.\nfunc (ws *AtomicWriteSet) Commit(target string) error {\n\treturn os.Rename(ws.root, target)\n}\n\n// String returns the location the set is writing to.\nfunc (ws *AtomicWriteSet) String() string {\n\treturn ws.root\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/ioutils/readers.go",
    "content": "package ioutils // import \"github.com/docker/docker/pkg/ioutils\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"runtime/debug\"\n\t\"sync/atomic\"\n\n\t// make sure crypto.SHA256, crypto.sha512 and crypto.SHA384 are registered\n\t// TODO remove once https://github.com/opencontainers/go-digest/pull/64 is merged.\n\t_ \"crypto/sha256\"\n\t_ \"crypto/sha512\"\n\n\t\"github.com/containerd/log\"\n)\n\n// ReadCloserWrapper wraps an io.Reader, and implements an io.ReadCloser\n// It calls the given callback function when closed. It should be constructed\n// with NewReadCloserWrapper\ntype ReadCloserWrapper struct {\n\tio.Reader\n\tcloser func() error\n\tclosed atomic.Bool\n}\n\n// Close calls back the passed closer function\nfunc (r *ReadCloserWrapper) Close() error {\n\tif !r.closed.CompareAndSwap(false, true) {\n\t\tsubsequentCloseWarn(\"ReadCloserWrapper\")\n\t\treturn nil\n\t}\n\treturn r.closer()\n}\n\n// NewReadCloserWrapper returns a new io.ReadCloser.\nfunc NewReadCloserWrapper(r io.Reader, closer func() error) io.ReadCloser {\n\treturn &ReadCloserWrapper{\n\t\tReader: r,\n\t\tcloser: closer,\n\t}\n}\n\ntype readerErrWrapper struct {\n\treader io.Reader\n\tcloser func()\n}\n\nfunc (r *readerErrWrapper) Read(p []byte) (int, error) {\n\tn, err := r.reader.Read(p)\n\tif err != nil {\n\t\tr.closer()\n\t}\n\treturn n, err\n}\n\n// NewReaderErrWrapper returns a new io.Reader.\nfunc NewReaderErrWrapper(r io.Reader, closer func()) io.Reader {\n\treturn &readerErrWrapper{\n\t\treader: r,\n\t\tcloser: closer,\n\t}\n}\n\n// OnEOFReader wraps an io.ReadCloser and a function\n// the function will run at the end of file or close the file.\ntype OnEOFReader struct {\n\tRc io.ReadCloser\n\tFn func()\n}\n\nfunc (r *OnEOFReader) Read(p []byte) (n int, err error) {\n\tn, err = r.Rc.Read(p)\n\tif err == io.EOF {\n\t\tr.runFunc()\n\t}\n\treturn\n}\n\n// Close closes the file and run the function.\nfunc (r *OnEOFReader) Close() error {\n\terr := r.Rc.Close()\n\tr.runFunc()\n\treturn err\n}\n\nfunc (r *OnEOFReader) runFunc() {\n\tif fn := r.Fn; fn != nil {\n\t\tfn()\n\t\tr.Fn = nil\n\t}\n}\n\n// cancelReadCloser wraps an io.ReadCloser with a context for cancelling read\n// operations.\ntype cancelReadCloser struct {\n\tcancel func()\n\tpR     *io.PipeReader // Stream to read from\n\tpW     *io.PipeWriter\n\tclosed atomic.Bool\n}\n\n// NewCancelReadCloser creates a wrapper that closes the ReadCloser when the\n// context is cancelled. The returned io.ReadCloser must be closed when it is\n// no longer needed.\nfunc NewCancelReadCloser(ctx context.Context, in io.ReadCloser) io.ReadCloser {\n\tpR, pW := io.Pipe()\n\n\t// Create a context used to signal when the pipe is closed\n\tdoneCtx, cancel := context.WithCancel(context.Background())\n\n\tp := &cancelReadCloser{\n\t\tcancel: cancel,\n\t\tpR:     pR,\n\t\tpW:     pW,\n\t}\n\n\tgo func() {\n\t\t_, err := io.Copy(pW, in)\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\t// If the context was closed, p.closeWithError\n\t\t\t// was already called. Calling it again would\n\t\t\t// change the error that Read returns.\n\t\tdefault:\n\t\t\tp.closeWithError(err)\n\t\t}\n\t\tin.Close()\n\t}()\n\tgo func() {\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\tp.closeWithError(ctx.Err())\n\t\t\tcase <-doneCtx.Done():\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\treturn p\n}\n\n// Read wraps the Read method of the pipe that provides data from the wrapped\n// ReadCloser.\nfunc (p *cancelReadCloser) Read(buf []byte) (n int, err error) {\n\treturn p.pR.Read(buf)\n}\n\n// closeWithError closes the wrapper and its underlying reader. It will\n// cause future calls to Read to return err.\nfunc (p *cancelReadCloser) closeWithError(err error) {\n\tp.pW.CloseWithError(err)\n\tp.cancel()\n}\n\n// Close closes the wrapper its underlying reader. It will cause\n// future calls to Read to return io.EOF.\nfunc (p *cancelReadCloser) Close() error {\n\tif !p.closed.CompareAndSwap(false, true) {\n\t\tsubsequentCloseWarn(\"cancelReadCloser\")\n\t\treturn nil\n\t}\n\tp.closeWithError(io.EOF)\n\treturn nil\n}\n\nfunc subsequentCloseWarn(name string) {\n\tlog.G(context.TODO()).Error(\"subsequent attempt to close \" + name)\n\tif log.GetLevel() >= log.DebugLevel {\n\t\tlog.G(context.TODO()).Errorf(\"stack trace: %s\", string(debug.Stack()))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/ioutils/writeflusher.go",
    "content": "package ioutils // import \"github.com/docker/docker/pkg/ioutils\"\n\nimport (\n\t\"io\"\n\t\"sync\"\n)\n\n// WriteFlusher wraps the Write and Flush operation ensuring that every write\n// is a flush. In addition, the Close method can be called to intercept\n// Read/Write calls if the targets lifecycle has already ended.\ntype WriteFlusher struct {\n\tw           io.Writer\n\tflusher     flusher\n\tflushed     chan struct{}\n\tflushedOnce sync.Once\n\tclosed      chan struct{}\n\tcloseLock   sync.Mutex\n}\n\ntype flusher interface {\n\tFlush()\n}\n\nvar errWriteFlusherClosed = io.EOF\n\nfunc (wf *WriteFlusher) Write(b []byte) (n int, err error) {\n\tselect {\n\tcase <-wf.closed:\n\t\treturn 0, errWriteFlusherClosed\n\tdefault:\n\t}\n\n\tn, err = wf.w.Write(b)\n\twf.Flush() // every write is a flush.\n\treturn n, err\n}\n\n// Flush the stream immediately.\nfunc (wf *WriteFlusher) Flush() {\n\tselect {\n\tcase <-wf.closed:\n\t\treturn\n\tdefault:\n\t}\n\n\twf.flushedOnce.Do(func() {\n\t\tclose(wf.flushed)\n\t})\n\twf.flusher.Flush()\n}\n\n// Flushed returns the state of flushed.\n// If it's flushed, return true, or else it return false.\nfunc (wf *WriteFlusher) Flushed() bool {\n\t// BUG(stevvooe): Remove this method. Its use is inherently racy. Seems to\n\t// be used to detect whether or a response code has been issued or not.\n\t// Another hook should be used instead.\n\tvar flushed bool\n\tselect {\n\tcase <-wf.flushed:\n\t\tflushed = true\n\tdefault:\n\t}\n\treturn flushed\n}\n\n// Close closes the write flusher, disallowing any further writes to the\n// target. After the flusher is closed, all calls to write or flush will\n// result in an error.\nfunc (wf *WriteFlusher) Close() error {\n\twf.closeLock.Lock()\n\tdefer wf.closeLock.Unlock()\n\n\tselect {\n\tcase <-wf.closed:\n\t\treturn errWriteFlusherClosed\n\tdefault:\n\t\tclose(wf.closed)\n\t}\n\treturn nil\n}\n\n// NewWriteFlusher returns a new WriteFlusher.\nfunc NewWriteFlusher(w io.Writer) *WriteFlusher {\n\tvar fl flusher\n\tif f, ok := w.(flusher); ok {\n\t\tfl = f\n\t} else {\n\t\tfl = &NopFlusher{}\n\t}\n\treturn &WriteFlusher{w: w, flusher: fl, closed: make(chan struct{}), flushed: make(chan struct{})}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/ioutils/writers.go",
    "content": "package ioutils // import \"github.com/docker/docker/pkg/ioutils\"\n\nimport (\n\t\"io\"\n\t\"sync/atomic\"\n)\n\n// NopWriter represents a type which write operation is nop.\ntype NopWriter struct{}\n\nfunc (*NopWriter) Write(buf []byte) (int, error) {\n\treturn len(buf), nil\n}\n\ntype nopWriteCloser struct {\n\tio.Writer\n}\n\nfunc (w *nopWriteCloser) Close() error { return nil }\n\n// NopWriteCloser returns a nopWriteCloser.\nfunc NopWriteCloser(w io.Writer) io.WriteCloser {\n\treturn &nopWriteCloser{w}\n}\n\n// NopFlusher represents a type which flush operation is nop.\ntype NopFlusher struct{}\n\n// Flush is a nop operation.\nfunc (f *NopFlusher) Flush() {}\n\ntype writeCloserWrapper struct {\n\tio.Writer\n\tcloser func() error\n\tclosed atomic.Bool\n}\n\nfunc (r *writeCloserWrapper) Close() error {\n\tif !r.closed.CompareAndSwap(false, true) {\n\t\tsubsequentCloseWarn(\"WriteCloserWrapper\")\n\t\treturn nil\n\t}\n\treturn r.closer()\n}\n\n// NewWriteCloserWrapper returns a new io.WriteCloser.\nfunc NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser {\n\treturn &writeCloserWrapper{\n\t\tWriter: r,\n\t\tcloser: closer,\n\t}\n}\n\n// WriteCounter wraps a concrete io.Writer and hold a count of the number\n// of bytes written to the writer during a \"session\".\n// This can be convenient when write return is masked\n// (e.g., json.Encoder.Encode())\ntype WriteCounter struct {\n\tCount  int64\n\tWriter io.Writer\n}\n\n// NewWriteCounter returns a new WriteCounter.\nfunc NewWriteCounter(w io.Writer) *WriteCounter {\n\treturn &WriteCounter{\n\t\tWriter: w,\n\t}\n}\n\nfunc (wc *WriteCounter) Write(p []byte) (count int, err error) {\n\tcount, err = wc.Writer.Write(p)\n\twc.Count += int64(count)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/jsonmessage/jsonmessage.go",
    "content": "package jsonmessage // import \"github.com/docker/docker/pkg/jsonmessage\"\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\tunits \"github.com/docker/go-units\"\n\t\"github.com/moby/term\"\n\t\"github.com/morikuni/aec\"\n)\n\n// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to\n// ensure the formatted time isalways the same number of characters.\nconst RFC3339NanoFixed = \"2006-01-02T15:04:05.000000000Z07:00\"\n\n// JSONError wraps a concrete Code and Message, Code is\n// an integer error code, Message is the error message.\ntype JSONError struct {\n\tCode    int    `json:\"code,omitempty\"`\n\tMessage string `json:\"message,omitempty\"`\n}\n\nfunc (e *JSONError) Error() string {\n\treturn e.Message\n}\n\n// JSONProgress describes a progress message in a JSON stream.\ntype JSONProgress struct {\n\t// Current is the current status and value of the progress made towards Total.\n\tCurrent int64 `json:\"current,omitempty\"`\n\t// Total is the end value describing when we made 100% progress for an operation.\n\tTotal int64 `json:\"total,omitempty\"`\n\t// Start is the initial value for the operation.\n\tStart int64 `json:\"start,omitempty\"`\n\t// HideCounts. if true, hides the progress count indicator (xB/yB).\n\tHideCounts bool `json:\"hidecounts,omitempty\"`\n\t// Units is the unit to print for progress. It defaults to \"bytes\" if empty.\n\tUnits string `json:\"units,omitempty\"`\n\n\t// terminalFd is the fd of the current terminal, if any. It is used\n\t// to get the terminal width.\n\tterminalFd uintptr\n\n\t// nowFunc is used to override the current time in tests.\n\tnowFunc func() time.Time\n\n\t// winSize is used to override the terminal width in tests.\n\twinSize int\n}\n\nfunc (p *JSONProgress) String() string {\n\tvar (\n\t\twidth       = p.width()\n\t\tpbBox       string\n\t\tnumbersBox  string\n\t\ttimeLeftBox string\n\t)\n\tif p.Current <= 0 && p.Total <= 0 {\n\t\treturn \"\"\n\t}\n\tif p.Total <= 0 {\n\t\tswitch p.Units {\n\t\tcase \"\":\n\t\t\treturn fmt.Sprintf(\"%8v\", units.HumanSize(float64(p.Current)))\n\t\tdefault:\n\t\t\treturn fmt.Sprintf(\"%d %s\", p.Current, p.Units)\n\t\t}\n\t}\n\n\tpercentage := int(float64(p.Current)/float64(p.Total)*100) / 2\n\tif percentage > 50 {\n\t\tpercentage = 50\n\t}\n\tif width > 110 {\n\t\t// this number can't be negative gh#7136\n\t\tnumSpaces := 0\n\t\tif 50-percentage > 0 {\n\t\t\tnumSpaces = 50 - percentage\n\t\t}\n\t\tpbBox = fmt.Sprintf(\"[%s>%s] \", strings.Repeat(\"=\", percentage), strings.Repeat(\" \", numSpaces))\n\t}\n\n\tswitch {\n\tcase p.HideCounts:\n\tcase p.Units == \"\": // no units, use bytes\n\t\tcurrent := units.HumanSize(float64(p.Current))\n\t\ttotal := units.HumanSize(float64(p.Total))\n\n\t\tnumbersBox = fmt.Sprintf(\"%8v/%v\", current, total)\n\n\t\tif p.Current > p.Total {\n\t\t\t// remove total display if the reported current is wonky.\n\t\t\tnumbersBox = fmt.Sprintf(\"%8v\", current)\n\t\t}\n\tdefault:\n\t\tnumbersBox = fmt.Sprintf(\"%d/%d %s\", p.Current, p.Total, p.Units)\n\n\t\tif p.Current > p.Total {\n\t\t\t// remove total display if the reported current is wonky.\n\t\t\tnumbersBox = fmt.Sprintf(\"%d %s\", p.Current, p.Units)\n\t\t}\n\t}\n\n\tif p.Current > 0 && p.Start > 0 && percentage < 50 {\n\t\tfromStart := p.now().Sub(time.Unix(p.Start, 0))\n\t\tperEntry := fromStart / time.Duration(p.Current)\n\t\tleft := time.Duration(p.Total-p.Current) * perEntry\n\t\tleft = (left / time.Second) * time.Second\n\n\t\tif width > 50 {\n\t\t\ttimeLeftBox = \" \" + left.String()\n\t\t}\n\t}\n\treturn pbBox + numbersBox + timeLeftBox\n}\n\n// now returns the current time in UTC, but can be overridden in tests\n// by setting JSONProgress.nowFunc to a custom function.\nfunc (p *JSONProgress) now() time.Time {\n\tif p.nowFunc != nil {\n\t\treturn p.nowFunc()\n\t}\n\treturn time.Now().UTC()\n}\n\n// width returns the current terminal's width, but can be overridden\n// in tests by setting JSONProgress.winSize to a non-zero value.\nfunc (p *JSONProgress) width() int {\n\tif p.winSize != 0 {\n\t\treturn p.winSize\n\t}\n\tws, err := term.GetWinsize(p.terminalFd)\n\tif err == nil {\n\t\treturn int(ws.Width)\n\t}\n\treturn 200\n}\n\n// JSONMessage defines a message struct. It describes\n// the created time, where it from, status, ID of the\n// message. It's used for docker events.\ntype JSONMessage struct {\n\tStream          string        `json:\"stream,omitempty\"`\n\tStatus          string        `json:\"status,omitempty\"`\n\tProgress        *JSONProgress `json:\"progressDetail,omitempty\"`\n\tProgressMessage string        `json:\"progress,omitempty\"` // deprecated\n\tID              string        `json:\"id,omitempty\"`\n\tFrom            string        `json:\"from,omitempty\"`\n\tTime            int64         `json:\"time,omitempty\"`\n\tTimeNano        int64         `json:\"timeNano,omitempty\"`\n\tError           *JSONError    `json:\"errorDetail,omitempty\"`\n\tErrorMessage    string        `json:\"error,omitempty\"` // deprecated\n\t// Aux contains out-of-band data, such as digests for push signing and image id after building.\n\tAux *json.RawMessage `json:\"aux,omitempty\"`\n}\n\nfunc clearLine(out io.Writer) {\n\teraseMode := aec.EraseModes.All\n\tcl := aec.EraseLine(eraseMode)\n\tfmt.Fprint(out, cl)\n}\n\nfunc cursorUp(out io.Writer, l uint) {\n\tfmt.Fprint(out, aec.Up(l))\n}\n\nfunc cursorDown(out io.Writer, l uint) {\n\tfmt.Fprint(out, aec.Down(l))\n}\n\n// Display prints the JSONMessage to out. If isTerminal is true, it erases\n// the entire current line when displaying the progressbar. It returns an\n// error if the [JSONMessage.Error] field is non-nil.\nfunc (jm *JSONMessage) Display(out io.Writer, isTerminal bool) error {\n\tif jm.Error != nil {\n\t\treturn jm.Error\n\t}\n\tvar endl string\n\tif isTerminal && jm.Stream == \"\" && jm.Progress != nil {\n\t\tclearLine(out)\n\t\tendl = \"\\r\"\n\t\tfmt.Fprint(out, endl)\n\t} else if jm.Progress != nil && jm.Progress.String() != \"\" { // disable progressbar in non-terminal\n\t\treturn nil\n\t}\n\tif jm.TimeNano != 0 {\n\t\tfmt.Fprintf(out, \"%s \", time.Unix(0, jm.TimeNano).Format(RFC3339NanoFixed))\n\t} else if jm.Time != 0 {\n\t\tfmt.Fprintf(out, \"%s \", time.Unix(jm.Time, 0).Format(RFC3339NanoFixed))\n\t}\n\tif jm.ID != \"\" {\n\t\tfmt.Fprintf(out, \"%s: \", jm.ID)\n\t}\n\tif jm.From != \"\" {\n\t\tfmt.Fprintf(out, \"(from %s) \", jm.From)\n\t}\n\tif jm.Progress != nil && isTerminal {\n\t\tfmt.Fprintf(out, \"%s %s%s\", jm.Status, jm.Progress.String(), endl)\n\t} else if jm.ProgressMessage != \"\" { // deprecated\n\t\tfmt.Fprintf(out, \"%s %s%s\", jm.Status, jm.ProgressMessage, endl)\n\t} else if jm.Stream != \"\" {\n\t\tfmt.Fprintf(out, \"%s%s\", jm.Stream, endl)\n\t} else {\n\t\tfmt.Fprintf(out, \"%s%s\\n\", jm.Status, endl)\n\t}\n\treturn nil\n}\n\n// DisplayJSONMessagesStream reads a JSON message stream from in, and writes\n// each [JSONMessage] to out. It returns an error if an invalid JSONMessage\n// is received, or if a JSONMessage containers a non-zero [JSONMessage.Error].\n//\n// Presentation of the JSONMessage depends on whether a terminal is attached,\n// and on the terminal width. Progress bars ([JSONProgress]) are suppressed\n// on narrower terminals (< 110 characters).\n//\n//   - isTerminal describes if out is a terminal, in which case it prints\n//     a newline (\"\\n\") at the end of each line and moves the cursor while\n//     displaying.\n//   - terminalFd is the fd of the current terminal (if any), and used\n//     to get the terminal width.\n//   - auxCallback allows handling the [JSONMessage.Aux] field. It is\n//     called if a JSONMessage contains an Aux field, in which case\n//     DisplayJSONMessagesStream does not present the JSONMessage.\nfunc DisplayJSONMessagesStream(in io.Reader, out io.Writer, terminalFd uintptr, isTerminal bool, auxCallback func(JSONMessage)) error {\n\tvar (\n\t\tdec = json.NewDecoder(in)\n\t\tids = make(map[string]uint)\n\t)\n\n\tfor {\n\t\tvar diff uint\n\t\tvar jm JSONMessage\n\t\tif err := dec.Decode(&jm); err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tif jm.Aux != nil {\n\t\t\tif auxCallback != nil {\n\t\t\t\tauxCallback(jm)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif jm.Progress != nil {\n\t\t\tjm.Progress.terminalFd = terminalFd\n\t\t}\n\t\tif jm.ID != \"\" && (jm.Progress != nil || jm.ProgressMessage != \"\") {\n\t\t\tline, ok := ids[jm.ID]\n\t\t\tif !ok {\n\t\t\t\t// NOTE: This approach of using len(id) to\n\t\t\t\t// figure out the number of lines of history\n\t\t\t\t// only works as long as we clear the history\n\t\t\t\t// when we output something that's not\n\t\t\t\t// accounted for in the map, such as a line\n\t\t\t\t// with no ID.\n\t\t\t\tline = uint(len(ids))\n\t\t\t\tids[jm.ID] = line\n\t\t\t\tif isTerminal {\n\t\t\t\t\tfmt.Fprintf(out, \"\\n\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tdiff = uint(len(ids)) - line\n\t\t\tif isTerminal {\n\t\t\t\tcursorUp(out, diff)\n\t\t\t}\n\t\t} else {\n\t\t\t// When outputting something that isn't progress\n\t\t\t// output, clear the history of previous lines. We\n\t\t\t// don't want progress entries from some previous\n\t\t\t// operation to be updated (for example, pull -a\n\t\t\t// with multiple tags).\n\t\t\tids = make(map[string]uint)\n\t\t}\n\t\terr := jm.Display(out, isTerminal)\n\t\tif jm.ID != \"\" && isTerminal {\n\t\t\tcursorDown(out, diff)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Stream is an io.Writer for output with utilities to get the output's file\n// descriptor and to detect wether it's a terminal.\n//\n// it is subset of the streams.Out type in\n// https://pkg.go.dev/github.com/docker/cli@v20.10.17+incompatible/cli/streams#Out\ntype Stream interface {\n\tio.Writer\n\tFD() uintptr\n\tIsTerminal() bool\n}\n\n// DisplayJSONMessagesToStream prints json messages to the output Stream. It is\n// used by the Docker CLI to print JSONMessage streams.\nfunc DisplayJSONMessagesToStream(in io.Reader, stream Stream, auxCallback func(JSONMessage)) error {\n\treturn DisplayJSONMessagesStream(in, stream, stream.FD(), stream.IsTerminal(), auxCallback)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/longpath/longpath.go",
    "content": "// Package longpath introduces some constants and helper functions for handling\n// long paths in Windows.\n//\n// Long paths are expected to be prepended with \"\\\\?\\\" and followed by either a\n// drive letter, a UNC server\\share, or a volume identifier.\npackage longpath // import \"github.com/docker/docker/pkg/longpath\"\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n)\n\n// Prefix is the longpath prefix for Windows file paths.\nconst Prefix = `\\\\?\\`\n\n// AddPrefix adds the Windows long path prefix to the path provided if\n// it does not already have it.\nfunc AddPrefix(path string) string {\n\tif !strings.HasPrefix(path, Prefix) {\n\t\tif strings.HasPrefix(path, `\\\\`) {\n\t\t\t// This is a UNC path, so we need to add 'UNC' to the path as well.\n\t\t\tpath = Prefix + `UNC` + path[1:]\n\t\t} else {\n\t\t\tpath = Prefix + path\n\t\t}\n\t}\n\treturn path\n}\n\n// MkdirTemp is the equivalent of [os.MkdirTemp], except that on Windows\n// the result is in Windows longpath format. On Unix systems it is\n// equivalent to [os.MkdirTemp].\nfunc MkdirTemp(dir, prefix string) (string, error) {\n\ttempDir, err := os.MkdirTemp(dir, prefix)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif runtime.GOOS != \"windows\" {\n\t\treturn tempDir, nil\n\t}\n\treturn AddPrefix(tempDir), nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/pools/pools.go",
    "content": "// Package pools provides a collection of pools which provide various\n// data types with buffers. These can be used to lower the number of\n// memory allocations and reuse buffers.\n//\n// New pools should be added to this package to allow them to be\n// shared across packages.\n//\n// Utility functions which operate on pools should be added to this\n// package to allow them to be reused.\npackage pools // import \"github.com/docker/docker/pkg/pools\"\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"sync\"\n\n\t\"github.com/docker/docker/pkg/ioutils\"\n)\n\nconst buffer32K = 32 * 1024\n\nvar (\n\t// BufioReader32KPool is a pool which returns bufio.Reader with a 32K buffer.\n\tBufioReader32KPool = newBufioReaderPoolWithSize(buffer32K)\n\t// BufioWriter32KPool is a pool which returns bufio.Writer with a 32K buffer.\n\tBufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K)\n\tbuffer32KPool      = newBufferPoolWithSize(buffer32K)\n)\n\n// BufioReaderPool is a bufio reader that uses sync.Pool.\ntype BufioReaderPool struct {\n\tpool sync.Pool\n}\n\n// newBufioReaderPoolWithSize is unexported because new pools should be\n// added here to be shared where required.\nfunc newBufioReaderPoolWithSize(size int) *BufioReaderPool {\n\treturn &BufioReaderPool{\n\t\tpool: sync.Pool{\n\t\t\tNew: func() interface{} { return bufio.NewReaderSize(nil, size) },\n\t\t},\n\t}\n}\n\n// Get returns a bufio.Reader which reads from r. The buffer size is that of the pool.\nfunc (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader {\n\tbuf := bufPool.pool.Get().(*bufio.Reader)\n\tbuf.Reset(r)\n\treturn buf\n}\n\n// Put puts the bufio.Reader back into the pool.\nfunc (bufPool *BufioReaderPool) Put(b *bufio.Reader) {\n\tb.Reset(nil)\n\tbufPool.pool.Put(b)\n}\n\ntype bufferPool struct {\n\tpool sync.Pool\n}\n\nfunc newBufferPoolWithSize(size int) *bufferPool {\n\treturn &bufferPool{\n\t\tpool: sync.Pool{\n\t\t\tNew: func() interface{} { s := make([]byte, size); return &s },\n\t\t},\n\t}\n}\n\nfunc (bp *bufferPool) Get() *[]byte {\n\treturn bp.pool.Get().(*[]byte)\n}\n\nfunc (bp *bufferPool) Put(b *[]byte) {\n\tbp.pool.Put(b)\n}\n\n// Copy is a convenience wrapper which uses a buffer to avoid allocation in io.Copy.\nfunc Copy(dst io.Writer, src io.Reader) (written int64, err error) {\n\tbuf := buffer32KPool.Get()\n\twritten, err = io.CopyBuffer(dst, src, *buf)\n\tbuffer32KPool.Put(buf)\n\treturn\n}\n\n// NewReadCloserWrapper returns a wrapper which puts the bufio.Reader back\n// into the pool and closes the reader if it's an io.ReadCloser.\nfunc (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser {\n\treturn ioutils.NewReadCloserWrapper(r, func() error {\n\t\tif readCloser, ok := r.(io.ReadCloser); ok {\n\t\t\treadCloser.Close()\n\t\t}\n\t\tbufPool.Put(buf)\n\t\treturn nil\n\t})\n}\n\n// BufioWriterPool is a bufio writer that uses sync.Pool.\ntype BufioWriterPool struct {\n\tpool sync.Pool\n}\n\n// newBufioWriterPoolWithSize is unexported because new pools should be\n// added here to be shared where required.\nfunc newBufioWriterPoolWithSize(size int) *BufioWriterPool {\n\treturn &BufioWriterPool{\n\t\tpool: sync.Pool{\n\t\t\tNew: func() interface{} { return bufio.NewWriterSize(nil, size) },\n\t\t},\n\t}\n}\n\n// Get returns a bufio.Writer which writes to w. The buffer size is that of the pool.\nfunc (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer {\n\tbuf := bufPool.pool.Get().(*bufio.Writer)\n\tbuf.Reset(w)\n\treturn buf\n}\n\n// Put puts the bufio.Writer back into the pool.\nfunc (bufPool *BufioWriterPool) Put(b *bufio.Writer) {\n\tb.Reset(nil)\n\tbufPool.pool.Put(b)\n}\n\n// NewWriteCloserWrapper returns a wrapper which puts the bufio.Writer back\n// into the pool and closes the writer if it's an io.Writecloser.\nfunc (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser {\n\treturn ioutils.NewWriteCloserWrapper(w, func() error {\n\t\tbuf.Flush()\n\t\tif writeCloser, ok := w.(io.WriteCloser); ok {\n\t\t\twriteCloser.Close()\n\t\t}\n\t\tbufPool.Put(buf)\n\t\treturn nil\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/stdcopy/stdcopy.go",
    "content": "package stdcopy // import \"github.com/docker/docker/pkg/stdcopy\"\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n)\n\n// StdType is the type of standard stream\n// a writer can multiplex to.\ntype StdType byte\n\nconst (\n\t// Stdin represents standard input stream type.\n\tStdin StdType = iota\n\t// Stdout represents standard output stream type.\n\tStdout\n\t// Stderr represents standard error steam type.\n\tStderr\n\t// Systemerr represents errors originating from the system that make it\n\t// into the multiplexed stream.\n\tSystemerr\n\n\tstdWriterPrefixLen = 8\n\tstdWriterFdIndex   = 0\n\tstdWriterSizeIndex = 4\n\n\tstartingBufLen = 32*1024 + stdWriterPrefixLen + 1\n)\n\nvar bufPool = &sync.Pool{New: func() interface{} { return bytes.NewBuffer(nil) }}\n\n// stdWriter is wrapper of io.Writer with extra customized info.\ntype stdWriter struct {\n\tio.Writer\n\tprefix byte\n}\n\n// Write sends the buffer to the underneath writer.\n// It inserts the prefix header before the buffer,\n// so stdcopy.StdCopy knows where to multiplex the output.\n// It makes stdWriter to implement io.Writer.\nfunc (w *stdWriter) Write(p []byte) (n int, err error) {\n\tif w == nil || w.Writer == nil {\n\t\treturn 0, errors.New(\"Writer not instantiated\")\n\t}\n\tif p == nil {\n\t\treturn 0, nil\n\t}\n\n\theader := [stdWriterPrefixLen]byte{stdWriterFdIndex: w.prefix}\n\tbinary.BigEndian.PutUint32(header[stdWriterSizeIndex:], uint32(len(p)))\n\tbuf := bufPool.Get().(*bytes.Buffer)\n\tbuf.Write(header[:])\n\tbuf.Write(p)\n\n\tn, err = w.Writer.Write(buf.Bytes())\n\tn -= stdWriterPrefixLen\n\tif n < 0 {\n\t\tn = 0\n\t}\n\n\tbuf.Reset()\n\tbufPool.Put(buf)\n\treturn\n}\n\n// NewStdWriter instantiates a new Writer.\n// Everything written to it will be encapsulated using a custom format,\n// and written to the underlying `w` stream.\n// This allows multiple write streams (e.g. stdout and stderr) to be muxed into a single connection.\n// `t` indicates the id of the stream to encapsulate.\n// It can be stdcopy.Stdin, stdcopy.Stdout, stdcopy.Stderr.\nfunc NewStdWriter(w io.Writer, t StdType) io.Writer {\n\treturn &stdWriter{\n\t\tWriter: w,\n\t\tprefix: byte(t),\n\t}\n}\n\n// StdCopy is a modified version of io.Copy.\n//\n// StdCopy will demultiplex `src`, assuming that it contains two streams,\n// previously multiplexed together using a StdWriter instance.\n// As it reads from `src`, StdCopy will write to `dstout` and `dsterr`.\n//\n// StdCopy will read until it hits EOF on `src`. It will then return a nil error.\n// In other words: if `err` is non nil, it indicates a real underlying error.\n//\n// `written` will hold the total number of bytes written to `dstout` and `dsterr`.\nfunc StdCopy(dstout, dsterr io.Writer, src io.Reader) (written int64, err error) {\n\tvar (\n\t\tbuf       = make([]byte, startingBufLen)\n\t\tbufLen    = len(buf)\n\t\tnr, nw    int\n\t\ter, ew    error\n\t\tout       io.Writer\n\t\tframeSize int\n\t)\n\n\tfor {\n\t\t// Make sure we have at least a full header\n\t\tfor nr < stdWriterPrefixLen {\n\t\t\tvar nr2 int\n\t\t\tnr2, er = src.Read(buf[nr:])\n\t\t\tnr += nr2\n\t\t\tif er == io.EOF {\n\t\t\t\tif nr < stdWriterPrefixLen {\n\t\t\t\t\treturn written, nil\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif er != nil {\n\t\t\t\treturn 0, er\n\t\t\t}\n\t\t}\n\n\t\tstream := StdType(buf[stdWriterFdIndex])\n\t\t// Check the first byte to know where to write\n\t\tswitch stream {\n\t\tcase Stdin:\n\t\t\tfallthrough\n\t\tcase Stdout:\n\t\t\t// Write on stdout\n\t\t\tout = dstout\n\t\tcase Stderr:\n\t\t\t// Write on stderr\n\t\t\tout = dsterr\n\t\tcase Systemerr:\n\t\t\t// If we're on Systemerr, we won't write anywhere.\n\t\t\t// NB: if this code changes later, make sure you don't try to write\n\t\t\t// to outstream if Systemerr is the stream\n\t\t\tout = nil\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"Unrecognized input header: %d\", buf[stdWriterFdIndex])\n\t\t}\n\n\t\t// Retrieve the size of the frame\n\t\tframeSize = int(binary.BigEndian.Uint32(buf[stdWriterSizeIndex : stdWriterSizeIndex+4]))\n\n\t\t// Check if the buffer is big enough to read the frame.\n\t\t// Extend it if necessary.\n\t\tif frameSize+stdWriterPrefixLen > bufLen {\n\t\t\tbuf = append(buf, make([]byte, frameSize+stdWriterPrefixLen-bufLen+1)...)\n\t\t\tbufLen = len(buf)\n\t\t}\n\n\t\t// While the amount of bytes read is less than the size of the frame + header, we keep reading\n\t\tfor nr < frameSize+stdWriterPrefixLen {\n\t\t\tvar nr2 int\n\t\t\tnr2, er = src.Read(buf[nr:])\n\t\t\tnr += nr2\n\t\t\tif er == io.EOF {\n\t\t\t\tif nr < frameSize+stdWriterPrefixLen {\n\t\t\t\t\treturn written, nil\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif er != nil {\n\t\t\t\treturn 0, er\n\t\t\t}\n\t\t}\n\n\t\t// we might have an error from the source mixed up in our multiplexed\n\t\t// stream. if we do, return it.\n\t\tif stream == Systemerr {\n\t\t\treturn written, fmt.Errorf(\"error from daemon in stream: %s\", string(buf[stdWriterPrefixLen:frameSize+stdWriterPrefixLen]))\n\t\t}\n\n\t\t// Write the retrieved frame (without header)\n\t\tnw, ew = out.Write(buf[stdWriterPrefixLen : frameSize+stdWriterPrefixLen])\n\t\tif ew != nil {\n\t\t\treturn 0, ew\n\t\t}\n\n\t\t// If the frame has not been fully written: error\n\t\tif nw != frameSize {\n\t\t\treturn 0, io.ErrShortWrite\n\t\t}\n\t\twritten += int64(nw)\n\n\t\t// Move the rest of the buffer to the beginning\n\t\tcopy(buf, buf[frameSize+stdWriterPrefixLen:])\n\t\t// Move the index\n\t\tnr -= frameSize + stdWriterPrefixLen\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/args_windows.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"strings\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n// EscapeArgs makes a Windows-style escaped command line from a set of arguments\nfunc EscapeArgs(args []string) string {\n\tescapedArgs := make([]string, len(args))\n\tfor i, a := range args {\n\t\tescapedArgs[i] = windows.EscapeArg(a)\n\t}\n\treturn strings.Join(escapedArgs, \" \")\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/chtimes.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"os\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n)\n\n// Used by Chtimes\nvar unixEpochTime, unixMaxTime time.Time\n\nfunc init() {\n\tunixEpochTime = time.Unix(0, 0)\n\tif unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {\n\t\t// This is a 64 bit timespec\n\t\t// os.Chtimes limits time to the following\n\t\t//\n\t\t// Note that this intentionally sets nsec (not sec), which sets both sec\n\t\t// and nsec internally in time.Unix();\n\t\t// https://github.com/golang/go/blob/go1.19.2/src/time/time.go#L1364-L1380\n\t\tunixMaxTime = time.Unix(0, 1<<63-1)\n\t} else {\n\t\t// This is a 32 bit timespec\n\t\tunixMaxTime = time.Unix(1<<31-1, 0)\n\t}\n}\n\n// Chtimes changes the access time and modified time of a file at the given path.\n// If the modified time is prior to the Unix Epoch (unixMinTime), or after the\n// end of Unix Time (unixEpochTime), os.Chtimes has undefined behavior. In this\n// case, Chtimes defaults to Unix Epoch, just in case.\nfunc Chtimes(name string, atime time.Time, mtime time.Time) error {\n\tif atime.Before(unixEpochTime) || atime.After(unixMaxTime) {\n\t\tatime = unixEpochTime\n\t}\n\n\tif mtime.Before(unixEpochTime) || mtime.After(unixMaxTime) {\n\t\tmtime = unixEpochTime\n\t}\n\n\tif err := os.Chtimes(name, atime, mtime); err != nil {\n\t\treturn err\n\t}\n\n\t// Take platform specific action for setting create time.\n\treturn setCTime(name, mtime)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/chtimes_nowindows.go",
    "content": "//go:build !windows\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"time\"\n)\n\n// setCTime will set the create time on a file. On Unix, the create\n// time is updated as a side effect of setting the modified time, so\n// no action is required.\nfunc setCTime(path string, ctime time.Time) error {\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/chtimes_windows.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"time\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n// setCTime will set the create time on a file. On Windows, this requires\n// calling SetFileTime and explicitly including the create time.\nfunc setCTime(path string, ctime time.Time) error {\n\tpathp, err := windows.UTF16PtrFromString(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\th, err := windows.CreateFile(pathp,\n\t\twindows.FILE_WRITE_ATTRIBUTES, windows.FILE_SHARE_WRITE, nil,\n\t\twindows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer windows.Close(h)\n\tc := windows.NsecToFiletime(ctime.UnixNano())\n\treturn windows.SetFileTime(h, &c, nil, nil)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/errors.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"errors\"\n\n// ErrNotSupportedPlatform means the platform is not supported.\nvar ErrNotSupportedPlatform = errors.New(\"platform and architecture is not supported\")\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/filesys.go",
    "content": "package system\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\n// IsAbs is a platform-agnostic wrapper for filepath.IsAbs.\n//\n// On Windows, golang filepath.IsAbs does not consider a path \\windows\\system32\n// as absolute as it doesn't start with a drive-letter/colon combination. However,\n// in docker we need to verify things such as WORKDIR /windows/system32 in\n// a Dockerfile (which gets translated to \\windows\\system32 when being processed\n// by the daemon). This SHOULD be treated as absolute from a docker processing\n// perspective.\nfunc IsAbs(path string) bool {\n\treturn filepath.IsAbs(path) || strings.HasPrefix(path, string(os.PathSeparator))\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/filesys_unix.go",
    "content": "//go:build !windows\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"os\"\n\n// MkdirAllWithACL is a wrapper for os.MkdirAll on unix systems.\nfunc MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {\n\treturn os.MkdirAll(path, perm)\n}\n\n// MkdirAll creates a directory named path along with any necessary parents,\n// with permission specified by attribute perm for all dir created.\nfunc MkdirAll(path string, perm os.FileMode) error {\n\treturn os.MkdirAll(path, perm)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/filesys_windows.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"os\"\n\t\"regexp\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n// SddlAdministratorsLocalSystem is local administrators plus NT AUTHORITY\\System.\nconst SddlAdministratorsLocalSystem = \"D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)\"\n\n// volumePath is a regular expression to check if a path is a Windows\n// volume path (e.g., \"\\\\?\\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\"\n// or \"\\\\?\\Volume{4c1b02c1-d990-11dc-99ae-806e6f6e6963}\\\").\nvar volumePath = regexp.MustCompile(`^\\\\\\\\\\?\\\\Volume{[a-z0-9-]+}\\\\?$`)\n\n// MkdirAllWithACL is a custom version of os.MkdirAll modified for use on Windows\n// so that it is both volume path aware, and can create a directory with\n// an appropriate SDDL defined ACL.\nfunc MkdirAllWithACL(path string, _ os.FileMode, sddl string) error {\n\tsa, err := makeSecurityAttributes(sddl)\n\tif err != nil {\n\t\treturn &os.PathError{Op: \"mkdirall\", Path: path, Err: err}\n\t}\n\treturn mkdirall(path, sa)\n}\n\n// MkdirAll is a custom version of os.MkdirAll that is volume path aware for\n// Windows. It can be used as a drop-in replacement for os.MkdirAll.\nfunc MkdirAll(path string, _ os.FileMode) error {\n\treturn mkdirall(path, nil)\n}\n\n// mkdirall is a custom version of os.MkdirAll modified for use on Windows\n// so that it is both volume path aware, and can create a directory with\n// a DACL.\nfunc mkdirall(path string, perm *windows.SecurityAttributes) error {\n\tif volumePath.MatchString(path) {\n\t\treturn nil\n\t}\n\n\t// The rest of this method is largely copied from os.MkdirAll and should be kept\n\t// as-is to ensure compatibility.\n\n\t// Fast path: if we can tell whether path is a directory or file, stop with success or error.\n\tdir, err := os.Stat(path)\n\tif err == nil {\n\t\tif dir.IsDir() {\n\t\t\treturn nil\n\t\t}\n\t\treturn &os.PathError{Op: \"mkdir\", Path: path, Err: syscall.ENOTDIR}\n\t}\n\n\t// Slow path: make sure parent exists and then call Mkdir for path.\n\ti := len(path)\n\tfor i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator.\n\t\ti--\n\t}\n\n\tj := i\n\tfor j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element.\n\t\tj--\n\t}\n\n\tif j > 1 {\n\t\t// Create parent.\n\t\terr = mkdirall(fixRootDirectory(path[:j-1]), perm)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Parent now exists; invoke Mkdir and use its result.\n\terr = mkdirWithACL(path, perm)\n\tif err != nil {\n\t\t// Handle arguments like \"foo/.\" by\n\t\t// double-checking that directory doesn't exist.\n\t\tdir, err1 := os.Lstat(path)\n\t\tif err1 == nil && dir.IsDir() {\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// mkdirWithACL creates a new directory. If there is an error, it will be of\n// type *PathError. .\n//\n// This is a modified and combined version of os.Mkdir and windows.Mkdir\n// in golang to cater for creating a directory am ACL permitting full\n// access, with inheritance, to any subfolder/file for Built-in Administrators\n// and Local System.\nfunc mkdirWithACL(name string, sa *windows.SecurityAttributes) error {\n\tif sa == nil {\n\t\treturn os.Mkdir(name, 0)\n\t}\n\n\tnamep, err := windows.UTF16PtrFromString(name)\n\tif err != nil {\n\t\treturn &os.PathError{Op: \"mkdir\", Path: name, Err: err}\n\t}\n\n\terr = windows.CreateDirectory(namep, sa)\n\tif err != nil {\n\t\treturn &os.PathError{Op: \"mkdir\", Path: name, Err: err}\n\t}\n\treturn nil\n}\n\n// fixRootDirectory fixes a reference to a drive's root directory to\n// have the required trailing slash.\nfunc fixRootDirectory(p string) string {\n\tif len(p) == len(`\\\\?\\c:`) {\n\t\tif os.IsPathSeparator(p[0]) && os.IsPathSeparator(p[1]) && p[2] == '?' && os.IsPathSeparator(p[3]) && p[5] == ':' {\n\t\t\treturn p + `\\`\n\t\t}\n\t}\n\treturn p\n}\n\nfunc makeSecurityAttributes(sddl string) (*windows.SecurityAttributes, error) {\n\tvar sa windows.SecurityAttributes\n\tsa.Length = uint32(unsafe.Sizeof(sa))\n\tsa.InheritHandle = 1\n\tvar err error\n\tsa.SecurityDescriptor, err = windows.SecurityDescriptorFromString(sddl)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &sa, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/image_os_deprecated.go",
    "content": "package system\n\nimport (\n\t\"errors\"\n\t\"runtime\"\n\t\"strings\"\n)\n\n// ErrNotSupportedOperatingSystem means the operating system is not supported.\n//\n// Deprecated: use [github.com/docker/docker/image.CheckOS] and check the error returned.\nvar ErrNotSupportedOperatingSystem = errors.New(\"operating system is not supported\")\n\n// IsOSSupported determines if an operating system is supported by the host.\n//\n// Deprecated: use [github.com/docker/docker/image.CheckOS] and check the error returned.\nfunc IsOSSupported(os string) bool {\n\treturn strings.EqualFold(runtime.GOOS, os)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/init_windows.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\n// containerdRuntimeSupported determines if containerd should be the runtime.\nvar containerdRuntimeSupported = false\n\n// InitContainerdRuntime sets whether to use containerd for runtime on Windows.\nfunc InitContainerdRuntime(cdPath string) {\n\tif len(cdPath) > 0 {\n\t\tcontainerdRuntimeSupported = true\n\t}\n}\n\n// ContainerdRuntimeSupported returns true if the use of containerd runtime is supported.\nfunc ContainerdRuntimeSupported() bool {\n\treturn containerdRuntimeSupported\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/lstat_unix.go",
    "content": "//go:build !windows\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"os\"\n\t\"syscall\"\n)\n\n// Lstat takes a path to a file and returns\n// a system.StatT type pertaining to that file.\n//\n// Throws an error if the file does not exist\nfunc Lstat(path string) (*StatT, error) {\n\ts := &syscall.Stat_t{}\n\tif err := syscall.Lstat(path, s); err != nil {\n\t\treturn nil, &os.PathError{Op: \"Lstat\", Path: path, Err: err}\n\t}\n\treturn fromStatT(s)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/lstat_windows.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"os\"\n\n// Lstat calls os.Lstat to get a fileinfo interface back.\n// This is then copied into our own locally defined structure.\nfunc Lstat(path string) (*StatT, error) {\n\tfi, err := os.Lstat(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn fromStatT(&fi)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/mknod.go",
    "content": "//go:build !windows\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\n// Mkdev is used to build the value of linux devices (in /dev/) which specifies major\n// and minor number of the newly created device special file.\n// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes.\n// They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major,\n// then the top 12 bits of the minor.\nfunc Mkdev(major int64, minor int64) uint32 {\n\treturn uint32(unix.Mkdev(uint32(major), uint32(minor)))\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/mknod_freebsd.go",
    "content": "//go:build freebsd\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\n// Mknod creates a filesystem node (file, device special file or named pipe) named path\n// with attributes specified by mode and dev.\nfunc Mknod(path string, mode uint32, dev int) error {\n\treturn unix.Mknod(path, mode, uint64(dev))\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/mknod_unix.go",
    "content": "//go:build !freebsd && !windows\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\n// Mknod creates a filesystem node (file, device special file or named pipe) named path\n// with attributes specified by mode and dev.\nfunc Mknod(path string, mode uint32, dev int) error {\n\treturn unix.Mknod(path, mode, dev)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/stat_bsd.go",
    "content": "//go:build freebsd || netbsd\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"syscall\"\n\n// fromStatT converts a syscall.Stat_t type to a system.Stat_t type\nfunc fromStatT(s *syscall.Stat_t) (*StatT, error) {\n\treturn &StatT{\n\t\tsize: s.Size,\n\t\tmode: uint32(s.Mode),\n\t\tuid:  s.Uid,\n\t\tgid:  s.Gid,\n\t\trdev: uint64(s.Rdev),\n\t\tmtim: s.Mtimespec,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/stat_darwin.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"syscall\"\n\n// fromStatT converts a syscall.Stat_t type to a system.Stat_t type\nfunc fromStatT(s *syscall.Stat_t) (*StatT, error) {\n\treturn &StatT{\n\t\tsize: s.Size,\n\t\tmode: uint32(s.Mode),\n\t\tuid:  s.Uid,\n\t\tgid:  s.Gid,\n\t\trdev: uint64(s.Rdev),\n\t\tmtim: s.Mtimespec,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/stat_linux.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"syscall\"\n\n// fromStatT converts a syscall.Stat_t type to a system.Stat_t type\nfunc fromStatT(s *syscall.Stat_t) (*StatT, error) {\n\treturn &StatT{\n\t\tsize: s.Size,\n\t\tmode: s.Mode,\n\t\tuid:  s.Uid,\n\t\tgid:  s.Gid,\n\t\t// the type is 32bit on mips\n\t\trdev: uint64(s.Rdev), //nolint: unconvert\n\t\tmtim: s.Mtim,\n\t}, nil\n}\n\n// FromStatT converts a syscall.Stat_t type to a system.Stat_t type\n// This is exposed on Linux as pkg/archive/changes uses it.\nfunc FromStatT(s *syscall.Stat_t) (*StatT, error) {\n\treturn fromStatT(s)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/stat_openbsd.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"syscall\"\n\n// fromStatT converts a syscall.Stat_t type to a system.Stat_t type\nfunc fromStatT(s *syscall.Stat_t) (*StatT, error) {\n\treturn &StatT{\n\t\tsize: s.Size,\n\t\tmode: uint32(s.Mode),\n\t\tuid:  s.Uid,\n\t\tgid:  s.Gid,\n\t\trdev: uint64(s.Rdev),\n\t\tmtim: s.Mtim,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/stat_unix.go",
    "content": "//go:build !windows\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"os\"\n\t\"syscall\"\n)\n\n// StatT type contains status of a file. It contains metadata\n// like permission, owner, group, size, etc about a file.\ntype StatT struct {\n\tmode uint32\n\tuid  uint32\n\tgid  uint32\n\trdev uint64\n\tsize int64\n\tmtim syscall.Timespec\n}\n\n// Mode returns file's permission mode.\nfunc (s StatT) Mode() uint32 {\n\treturn s.mode\n}\n\n// UID returns file's user id of owner.\nfunc (s StatT) UID() uint32 {\n\treturn s.uid\n}\n\n// GID returns file's group id of owner.\nfunc (s StatT) GID() uint32 {\n\treturn s.gid\n}\n\n// Rdev returns file's device ID (if it's special file).\nfunc (s StatT) Rdev() uint64 {\n\treturn s.rdev\n}\n\n// Size returns file's size.\nfunc (s StatT) Size() int64 {\n\treturn s.size\n}\n\n// Mtim returns file's last modification time.\nfunc (s StatT) Mtim() syscall.Timespec {\n\treturn s.mtim\n}\n\n// IsDir reports whether s describes a directory.\nfunc (s StatT) IsDir() bool {\n\treturn s.mode&syscall.S_IFDIR != 0\n}\n\n// Stat takes a path to a file and returns\n// a system.StatT type pertaining to that file.\n//\n// Throws an error if the file does not exist\nfunc Stat(path string) (*StatT, error) {\n\ts := &syscall.Stat_t{}\n\tif err := syscall.Stat(path, s); err != nil {\n\t\treturn nil, &os.PathError{Op: \"Stat\", Path: path, Err: err}\n\t}\n\treturn fromStatT(s)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/stat_windows.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"os\"\n\t\"time\"\n)\n\n// StatT type contains status of a file. It contains metadata\n// like permission, size, etc about a file.\ntype StatT struct {\n\tmode os.FileMode\n\tsize int64\n\tmtim time.Time\n}\n\n// Size returns file's size.\nfunc (s StatT) Size() int64 {\n\treturn s.size\n}\n\n// Mode returns file's permission mode.\nfunc (s StatT) Mode() os.FileMode {\n\treturn s.mode\n}\n\n// Mtim returns file's last modification time.\nfunc (s StatT) Mtim() time.Time {\n\treturn s.mtim\n}\n\n// Stat takes a path to a file and returns\n// a system.StatT type pertaining to that file.\n//\n// Throws an error if the file does not exist\nfunc Stat(path string) (*StatT, error) {\n\tfi, err := os.Stat(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn fromStatT(&fi)\n}\n\n// fromStatT converts a os.FileInfo type to a system.StatT type\nfunc fromStatT(fi *os.FileInfo) (*StatT, error) {\n\treturn &StatT{\n\t\tsize: (*fi).Size(),\n\t\tmode: (*fi).Mode(),\n\t\tmtim: (*fi).ModTime(),\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/utimes_unix.go",
    "content": "//go:build linux || freebsd\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// LUtimesNano is used to change access and modification time of the specified path.\n// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.\nfunc LUtimesNano(path string, ts []syscall.Timespec) error {\n\tuts := []unix.Timespec{\n\t\tunix.NsecToTimespec(syscall.TimespecToNsec(ts[0])),\n\t\tunix.NsecToTimespec(syscall.TimespecToNsec(ts[1])),\n\t}\n\terr := unix.UtimesNanoAt(unix.AT_FDCWD, path, uts, unix.AT_SYMLINK_NOFOLLOW)\n\tif err != nil && err != unix.ENOSYS {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/utimes_unsupported.go",
    "content": "//go:build !linux && !freebsd\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\nimport \"syscall\"\n\n// LUtimesNano is only supported on linux and freebsd.\nfunc LUtimesNano(path string, ts []syscall.Timespec) error {\n\treturn ErrNotSupportedPlatform\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/xattrs.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\ntype XattrError struct {\n\tOp   string\n\tAttr string\n\tPath string\n\tErr  error\n}\n\nfunc (e *XattrError) Error() string { return e.Op + \" \" + e.Attr + \" \" + e.Path + \": \" + e.Err.Error() }\n\nfunc (e *XattrError) Unwrap() error { return e.Err }\n\n// Timeout reports whether this error represents a timeout.\nfunc (e *XattrError) Timeout() bool {\n\tt, ok := e.Err.(interface{ Timeout() bool })\n\treturn ok && t.Timeout()\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/xattrs_linux.go",
    "content": "package system // import \"github.com/docker/docker/pkg/system\"\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\n// Lgetxattr retrieves the value of the extended attribute identified by attr\n// and associated with the given path in the file system.\n// It will returns a nil slice and nil error if the xattr is not set.\nfunc Lgetxattr(path string, attr string) ([]byte, error) {\n\tsysErr := func(err error) ([]byte, error) {\n\t\treturn nil, &XattrError{Op: \"lgetxattr\", Attr: attr, Path: path, Err: err}\n\t}\n\n\t// Start with a 128 length byte array\n\tdest := make([]byte, 128)\n\tsz, errno := unix.Lgetxattr(path, attr, dest)\n\n\tfor errno == unix.ERANGE {\n\t\t// Buffer too small, use zero-sized buffer to get the actual size\n\t\tsz, errno = unix.Lgetxattr(path, attr, []byte{})\n\t\tif errno != nil {\n\t\t\treturn sysErr(errno)\n\t\t}\n\t\tdest = make([]byte, sz)\n\t\tsz, errno = unix.Lgetxattr(path, attr, dest)\n\t}\n\n\tswitch {\n\tcase errno == unix.ENODATA:\n\t\treturn nil, nil\n\tcase errno != nil:\n\t\treturn sysErr(errno)\n\t}\n\n\treturn dest[:sz], nil\n}\n\n// Lsetxattr sets the value of the extended attribute identified by attr\n// and associated with the given path in the file system.\nfunc Lsetxattr(path string, attr string, data []byte, flags int) error {\n\terr := unix.Lsetxattr(path, attr, data, flags)\n\tif err != nil {\n\t\treturn &XattrError{Op: \"lsetxattr\", Attr: attr, Path: path, Err: err}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker/pkg/system/xattrs_unsupported.go",
    "content": "//go:build !linux\n\npackage system // import \"github.com/docker/docker/pkg/system\"\n\n// Lgetxattr is not supported on platforms other than linux.\nfunc Lgetxattr(path string, attr string) ([]byte, error) {\n\treturn nil, ErrNotSupportedPlatform\n}\n\n// Lsetxattr is not supported on platforms other than linux.\nfunc Lsetxattr(path string, attr string, data []byte, flags int) error {\n\treturn ErrNotSupportedPlatform\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker-credential-helpers/LICENSE",
    "content": "Copyright (c) 2016 David Calavera\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/docker/docker-credential-helpers/client/client.go",
    "content": "package client\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/docker/docker-credential-helpers/credentials\"\n)\n\n// isValidCredsMessage checks if 'msg' contains invalid credentials error message.\n// It returns whether the logs are free of invalid credentials errors and the error if it isn't.\n// error values can be errCredentialsMissingServerURL or errCredentialsMissingUsername.\nfunc isValidCredsMessage(msg string) error {\n\tif credentials.IsCredentialsMissingServerURLMessage(msg) {\n\t\treturn credentials.NewErrCredentialsMissingServerURL()\n\t}\n\n\tif credentials.IsCredentialsMissingUsernameMessage(msg) {\n\t\treturn credentials.NewErrCredentialsMissingUsername()\n\t}\n\n\treturn nil\n}\n\n// Store uses an external program to save credentials.\nfunc Store(program ProgramFunc, creds *credentials.Credentials) error {\n\tcmd := program(\"store\")\n\n\tbuffer := new(bytes.Buffer)\n\tif err := json.NewEncoder(buffer).Encode(creds); err != nil {\n\t\treturn err\n\t}\n\tcmd.Input(buffer)\n\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\tt := strings.TrimSpace(string(out))\n\n\t\tif isValidErr := isValidCredsMessage(t); isValidErr != nil {\n\t\t\terr = isValidErr\n\t\t}\n\n\t\treturn fmt.Errorf(\"error storing credentials - err: %v, out: `%s`\", err, t)\n\t}\n\n\treturn nil\n}\n\n// Get executes an external program to get the credentials from a native store.\nfunc Get(program ProgramFunc, serverURL string) (*credentials.Credentials, error) {\n\tcmd := program(\"get\")\n\tcmd.Input(strings.NewReader(serverURL))\n\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\tt := strings.TrimSpace(string(out))\n\n\t\tif credentials.IsErrCredentialsNotFoundMessage(t) {\n\t\t\treturn nil, credentials.NewErrCredentialsNotFound()\n\t\t}\n\n\t\tif isValidErr := isValidCredsMessage(t); isValidErr != nil {\n\t\t\terr = isValidErr\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"error getting credentials - err: %v, out: `%s`\", err, t)\n\t}\n\n\tresp := &credentials.Credentials{\n\t\tServerURL: serverURL,\n\t}\n\n\tif err := json.NewDecoder(bytes.NewReader(out)).Decode(resp); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn resp, nil\n}\n\n// Erase executes a program to remove the server credentials from the native store.\nfunc Erase(program ProgramFunc, serverURL string) error {\n\tcmd := program(\"erase\")\n\tcmd.Input(strings.NewReader(serverURL))\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\tt := strings.TrimSpace(string(out))\n\n\t\tif isValidErr := isValidCredsMessage(t); isValidErr != nil {\n\t\t\terr = isValidErr\n\t\t}\n\n\t\treturn fmt.Errorf(\"error erasing credentials - err: %v, out: `%s`\", err, t)\n\t}\n\n\treturn nil\n}\n\n// List executes a program to list server credentials in the native store.\nfunc List(program ProgramFunc) (map[string]string, error) {\n\tcmd := program(\"list\")\n\tcmd.Input(strings.NewReader(\"unused\"))\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\tt := strings.TrimSpace(string(out))\n\n\t\tif isValidErr := isValidCredsMessage(t); isValidErr != nil {\n\t\t\terr = isValidErr\n\t\t}\n\n\t\treturn nil, fmt.Errorf(\"error listing credentials - err: %v, out: `%s`\", err, t)\n\t}\n\n\tvar resp map[string]string\n\tif err = json.NewDecoder(bytes.NewReader(out)).Decode(&resp); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn resp, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker-credential-helpers/client/command.go",
    "content": "package client\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\texec \"golang.org/x/sys/execabs\"\n)\n\n// Program is an interface to execute external programs.\ntype Program interface {\n\tOutput() ([]byte, error)\n\tInput(in io.Reader)\n}\n\n// ProgramFunc is a type of function that initializes programs based on arguments.\ntype ProgramFunc func(args ...string) Program\n\n// NewShellProgramFunc creates programs that are executed in a Shell.\nfunc NewShellProgramFunc(name string) ProgramFunc {\n\treturn NewShellProgramFuncWithEnv(name, nil)\n}\n\n// NewShellProgramFuncWithEnv creates programs that are executed in a Shell with environment variables\nfunc NewShellProgramFuncWithEnv(name string, env *map[string]string) ProgramFunc {\n\treturn func(args ...string) Program {\n\t\treturn &Shell{cmd: createProgramCmdRedirectErr(name, args, env)}\n\t}\n}\n\nfunc createProgramCmdRedirectErr(commandName string, args []string, env *map[string]string) *exec.Cmd {\n\tprogramCmd := exec.Command(commandName, args...)\n\tprogramCmd.Env = os.Environ()\n\tif env != nil {\n\t\tfor k, v := range *env {\n\t\t\tprogramCmd.Env = append(programCmd.Env, fmt.Sprintf(\"%s=%s\", k, v))\n\t\t}\n\t}\n\tprogramCmd.Stderr = os.Stderr\n\treturn programCmd\n}\n\n// Shell invokes shell commands to talk with a remote credentials helper.\ntype Shell struct {\n\tcmd *exec.Cmd\n}\n\n// Output returns responses from the remote credentials helper.\nfunc (s *Shell) Output() ([]byte, error) {\n\treturn s.cmd.Output()\n}\n\n// Input sets the input to send to a remote credentials helper.\nfunc (s *Shell) Input(in io.Reader) {\n\ts.cmd.Stdin = in\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker-credential-helpers/credentials/credentials.go",
    "content": "package credentials\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\n// Credentials holds the information shared between docker and the credentials store.\ntype Credentials struct {\n\tServerURL string\n\tUsername  string\n\tSecret    string\n}\n\n// isValid checks the integrity of Credentials object such that no credentials lack\n// a server URL or a username.\n// It returns whether the credentials are valid and the error if it isn't.\n// error values can be errCredentialsMissingServerURL or errCredentialsMissingUsername\nfunc (c *Credentials) isValid() (bool, error) {\n\tif len(c.ServerURL) == 0 {\n\t\treturn false, NewErrCredentialsMissingServerURL()\n\t}\n\n\tif len(c.Username) == 0 {\n\t\treturn false, NewErrCredentialsMissingUsername()\n\t}\n\n\treturn true, nil\n}\n\n// CredsLabel holds the way Docker credentials should be labeled as such in credentials stores that allow labelling.\n// That label allows to filter out non-Docker credentials too at lookup/search in macOS keychain,\n// Windows credentials manager and Linux libsecret. Default value is \"Docker Credentials\"\nvar CredsLabel = \"Docker Credentials\"\n\n// SetCredsLabel is a simple setter for CredsLabel\nfunc SetCredsLabel(label string) {\n\tCredsLabel = label\n}\n\n// Serve initializes the credentials helper and parses the action argument.\n// This function is designed to be called from a command line interface.\n// It uses os.Args[1] as the key for the action.\n// It uses os.Stdin as input and os.Stdout as output.\n// This function terminates the program with os.Exit(1) if there is an error.\nfunc Serve(helper Helper) {\n\tvar err error\n\tif len(os.Args) != 2 {\n\t\terr = fmt.Errorf(\"Usage: %s <store|get|erase|list|version>\", os.Args[0])\n\t}\n\n\tif err == nil {\n\t\terr = HandleCommand(helper, os.Args[1], os.Stdin, os.Stdout)\n\t}\n\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stdout, \"%v\\n\", err)\n\t\tos.Exit(1)\n\t}\n}\n\n// HandleCommand uses a helper and a key to run a credential action.\nfunc HandleCommand(helper Helper, key string, in io.Reader, out io.Writer) error {\n\tswitch key {\n\tcase \"store\":\n\t\treturn Store(helper, in)\n\tcase \"get\":\n\t\treturn Get(helper, in, out)\n\tcase \"erase\":\n\t\treturn Erase(helper, in)\n\tcase \"list\":\n\t\treturn List(helper, out)\n\tcase \"version\":\n\t\treturn PrintVersion(out)\n\t}\n\treturn fmt.Errorf(\"Unknown credential action `%s`\", key)\n}\n\n// Store uses a helper and an input reader to save credentials.\n// The reader must contain the JSON serialization of a Credentials struct.\nfunc Store(helper Helper, reader io.Reader) error {\n\tscanner := bufio.NewScanner(reader)\n\n\tbuffer := new(bytes.Buffer)\n\tfor scanner.Scan() {\n\t\tbuffer.Write(scanner.Bytes())\n\t}\n\n\tif err := scanner.Err(); err != nil && err != io.EOF {\n\t\treturn err\n\t}\n\n\tvar creds Credentials\n\tif err := json.NewDecoder(buffer).Decode(&creds); err != nil {\n\t\treturn err\n\t}\n\n\tif ok, err := creds.isValid(); !ok {\n\t\treturn err\n\t}\n\n\treturn helper.Add(&creds)\n}\n\n// Get retrieves the credentials for a given server url.\n// The reader must contain the server URL to search.\n// The writer is used to write the JSON serialization of the credentials.\nfunc Get(helper Helper, reader io.Reader, writer io.Writer) error {\n\tscanner := bufio.NewScanner(reader)\n\n\tbuffer := new(bytes.Buffer)\n\tfor scanner.Scan() {\n\t\tbuffer.Write(scanner.Bytes())\n\t}\n\n\tif err := scanner.Err(); err != nil && err != io.EOF {\n\t\treturn err\n\t}\n\n\tserverURL := strings.TrimSpace(buffer.String())\n\tif len(serverURL) == 0 {\n\t\treturn NewErrCredentialsMissingServerURL()\n\t}\n\n\tusername, secret, err := helper.Get(serverURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresp := Credentials{\n\t\tServerURL: serverURL,\n\t\tUsername:  username,\n\t\tSecret:    secret,\n\t}\n\n\tbuffer.Reset()\n\tif err := json.NewEncoder(buffer).Encode(resp); err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Fprint(writer, buffer.String())\n\treturn nil\n}\n\n// Erase removes credentials from the store.\n// The reader must contain the server URL to remove.\nfunc Erase(helper Helper, reader io.Reader) error {\n\tscanner := bufio.NewScanner(reader)\n\n\tbuffer := new(bytes.Buffer)\n\tfor scanner.Scan() {\n\t\tbuffer.Write(scanner.Bytes())\n\t}\n\n\tif err := scanner.Err(); err != nil && err != io.EOF {\n\t\treturn err\n\t}\n\n\tserverURL := strings.TrimSpace(buffer.String())\n\tif len(serverURL) == 0 {\n\t\treturn NewErrCredentialsMissingServerURL()\n\t}\n\n\treturn helper.Delete(serverURL)\n}\n\n// List returns all the serverURLs of keys in\n// the OS store as a list of strings\nfunc List(helper Helper, writer io.Writer) error {\n\taccts, err := helper.List()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn json.NewEncoder(writer).Encode(accts)\n}\n\n// PrintVersion outputs the current version.\nfunc PrintVersion(writer io.Writer) error {\n\tfmt.Fprintf(writer, \"%s (%s) %s\\n\", Name, Package, Version)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker-credential-helpers/credentials/error.go",
    "content": "package credentials\n\nconst (\n\t// ErrCredentialsNotFound standardizes the not found error, so every helper returns\n\t// the same message and docker can handle it properly.\n\terrCredentialsNotFoundMessage = \"credentials not found in native keychain\"\n\n\t// ErrCredentialsMissingServerURL and ErrCredentialsMissingUsername standardize\n\t// invalid credentials or credentials management operations\n\terrCredentialsMissingServerURLMessage = \"no credentials server URL\"\n\terrCredentialsMissingUsernameMessage  = \"no credentials username\"\n)\n\n// errCredentialsNotFound represents an error\n// raised when credentials are not in the store.\ntype errCredentialsNotFound struct{}\n\n// Error returns the standard error message\n// for when the credentials are not in the store.\nfunc (errCredentialsNotFound) Error() string {\n\treturn errCredentialsNotFoundMessage\n}\n\n// NewErrCredentialsNotFound creates a new error\n// for when the credentials are not in the store.\nfunc NewErrCredentialsNotFound() error {\n\treturn errCredentialsNotFound{}\n}\n\n// IsErrCredentialsNotFound returns true if the error\n// was caused by not having a set of credentials in a store.\nfunc IsErrCredentialsNotFound(err error) bool {\n\t_, ok := err.(errCredentialsNotFound)\n\treturn ok\n}\n\n// IsErrCredentialsNotFoundMessage returns true if the error\n// was caused by not having a set of credentials in a store.\n//\n// This function helps to check messages returned by an\n// external program via its standard output.\nfunc IsErrCredentialsNotFoundMessage(err string) bool {\n\treturn err == errCredentialsNotFoundMessage\n}\n\n// errCredentialsMissingServerURL represents an error raised\n// when the credentials object has no server URL or when no\n// server URL is provided to a credentials operation requiring\n// one.\ntype errCredentialsMissingServerURL struct{}\n\nfunc (errCredentialsMissingServerURL) Error() string {\n\treturn errCredentialsMissingServerURLMessage\n}\n\n// errCredentialsMissingUsername represents an error raised\n// when the credentials object has no username or when no\n// username is provided to a credentials operation requiring\n// one.\ntype errCredentialsMissingUsername struct{}\n\nfunc (errCredentialsMissingUsername) Error() string {\n\treturn errCredentialsMissingUsernameMessage\n}\n\n// NewErrCredentialsMissingServerURL creates a new error for\n// errCredentialsMissingServerURL.\nfunc NewErrCredentialsMissingServerURL() error {\n\treturn errCredentialsMissingServerURL{}\n}\n\n// NewErrCredentialsMissingUsername creates a new error for\n// errCredentialsMissingUsername.\nfunc NewErrCredentialsMissingUsername() error {\n\treturn errCredentialsMissingUsername{}\n}\n\n// IsCredentialsMissingServerURL returns true if the error\n// was an errCredentialsMissingServerURL.\nfunc IsCredentialsMissingServerURL(err error) bool {\n\t_, ok := err.(errCredentialsMissingServerURL)\n\treturn ok\n}\n\n// IsCredentialsMissingServerURLMessage checks for an\n// errCredentialsMissingServerURL in the error message.\nfunc IsCredentialsMissingServerURLMessage(err string) bool {\n\treturn err == errCredentialsMissingServerURLMessage\n}\n\n// IsCredentialsMissingUsername returns true if the error\n// was an errCredentialsMissingUsername.\nfunc IsCredentialsMissingUsername(err error) bool {\n\t_, ok := err.(errCredentialsMissingUsername)\n\treturn ok\n}\n\n// IsCredentialsMissingUsernameMessage checks for an\n// errCredentialsMissingUsername in the error message.\nfunc IsCredentialsMissingUsernameMessage(err string) bool {\n\treturn err == errCredentialsMissingUsernameMessage\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker-credential-helpers/credentials/helper.go",
    "content": "package credentials\n\n// Helper is the interface a credentials store helper must implement.\ntype Helper interface {\n\t// Add appends credentials to the store.\n\tAdd(*Credentials) error\n\t// Delete removes credentials from the store.\n\tDelete(serverURL string) error\n\t// Get retrieves credentials from the store.\n\t// It returns username and secret as strings.\n\tGet(serverURL string) (string, string, error)\n\t// List returns the stored serverURLs and their associated usernames.\n\tList() (map[string]string, error)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/docker-credential-helpers/credentials/version.go",
    "content": "package credentials\n\nvar (\n\t// Name is filled at linking time\n\tName = \"\"\n\n\t// Package is filled at linking time\n\tPackage = \"github.com/docker/docker-credential-helpers\"\n\n\t// Version holds the complete version number. Filled in at linking time.\n\tVersion = \"v0.0.0+unknown\"\n\n\t// Revision is filled with the VCS (e.g. git) revision being used to build\n\t// the program at linking time.\n\tRevision = \"\"\n)\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/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 2015 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": "vendor/github.com/docker/go-connections/nat/nat.go",
    "content": "// Package nat is a convenience package for manipulation of strings describing network ports.\npackage nat\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst (\n\t// portSpecTemplate is the expected format for port specifications\n\tportSpecTemplate = \"ip:hostPort:containerPort\"\n)\n\n// PortBinding represents a binding between a Host IP address and a Host Port\ntype PortBinding struct {\n\t// HostIP is the host IP Address\n\tHostIP string `json:\"HostIp\"`\n\t// HostPort is the host port number\n\tHostPort string\n}\n\n// PortMap is a collection of PortBinding indexed by Port\ntype PortMap map[Port][]PortBinding\n\n// PortSet is a collection of structs indexed by Port\ntype PortSet map[Port]struct{}\n\n// Port is a string containing port number and protocol in the format \"80/tcp\"\ntype Port string\n\n// NewPort creates a new instance of a Port given a protocol and port number or port range\nfunc NewPort(proto, port string) (Port, error) {\n\t// Check for parsing issues on \"port\" now so we can avoid having\n\t// to check it later on.\n\n\tportStartInt, portEndInt, err := ParsePortRangeToInt(port)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif portStartInt == portEndInt {\n\t\treturn Port(fmt.Sprintf(\"%d/%s\", portStartInt, proto)), nil\n\t}\n\treturn Port(fmt.Sprintf(\"%d-%d/%s\", portStartInt, portEndInt, proto)), nil\n}\n\n// ParsePort parses the port number string and returns an int\nfunc ParsePort(rawPort string) (int, error) {\n\tif len(rawPort) == 0 {\n\t\treturn 0, nil\n\t}\n\tport, err := strconv.ParseUint(rawPort, 10, 16)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn int(port), nil\n}\n\n// ParsePortRangeToInt parses the port range string and returns start/end ints\nfunc ParsePortRangeToInt(rawPort string) (int, int, error) {\n\tif len(rawPort) == 0 {\n\t\treturn 0, 0, nil\n\t}\n\tstart, end, err := ParsePortRange(rawPort)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\treturn int(start), int(end), nil\n}\n\n// Proto returns the protocol of a Port\nfunc (p Port) Proto() string {\n\tproto, _ := SplitProtoPort(string(p))\n\treturn proto\n}\n\n// Port returns the port number of a Port\nfunc (p Port) Port() string {\n\t_, port := SplitProtoPort(string(p))\n\treturn port\n}\n\n// Int returns the port number of a Port as an int\nfunc (p Port) Int() int {\n\tportStr := p.Port()\n\t// We don't need to check for an error because we're going to\n\t// assume that any error would have been found, and reported, in NewPort()\n\tport, _ := ParsePort(portStr)\n\treturn port\n}\n\n// Range returns the start/end port numbers of a Port range as ints\nfunc (p Port) Range() (int, int, error) {\n\treturn ParsePortRangeToInt(p.Port())\n}\n\n// SplitProtoPort splits a port in the format of proto/port\nfunc SplitProtoPort(rawPort string) (string, string) {\n\tparts := strings.Split(rawPort, \"/\")\n\tl := len(parts)\n\tif len(rawPort) == 0 || l == 0 || len(parts[0]) == 0 {\n\t\treturn \"\", \"\"\n\t}\n\tif l == 1 {\n\t\treturn \"tcp\", rawPort\n\t}\n\tif len(parts[1]) == 0 {\n\t\treturn \"tcp\", parts[0]\n\t}\n\treturn parts[1], parts[0]\n}\n\nfunc validateProto(proto string) bool {\n\tfor _, availableProto := range []string{\"tcp\", \"udp\", \"sctp\"} {\n\t\tif availableProto == proto {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// ParsePortSpecs receives port specs in the format of ip:public:private/proto and parses\n// these in to the internal types\nfunc ParsePortSpecs(ports []string) (map[Port]struct{}, map[Port][]PortBinding, error) {\n\tvar (\n\t\texposedPorts = make(map[Port]struct{}, len(ports))\n\t\tbindings     = make(map[Port][]PortBinding)\n\t)\n\tfor _, rawPort := range ports {\n\t\tportMappings, err := ParsePortSpec(rawPort)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\n\t\tfor _, portMapping := range portMappings {\n\t\t\tport := portMapping.Port\n\t\t\tif _, exists := exposedPorts[port]; !exists {\n\t\t\t\texposedPorts[port] = struct{}{}\n\t\t\t}\n\t\t\tbslice, exists := bindings[port]\n\t\t\tif !exists {\n\t\t\t\tbslice = []PortBinding{}\n\t\t\t}\n\t\t\tbindings[port] = append(bslice, portMapping.Binding)\n\t\t}\n\t}\n\treturn exposedPorts, bindings, nil\n}\n\n// PortMapping is a data object mapping a Port to a PortBinding\ntype PortMapping struct {\n\tPort    Port\n\tBinding PortBinding\n}\n\nfunc splitParts(rawport string) (string, string, string) {\n\tparts := strings.Split(rawport, \":\")\n\tn := len(parts)\n\tcontainerport := parts[n-1]\n\n\tswitch n {\n\tcase 1:\n\t\treturn \"\", \"\", containerport\n\tcase 2:\n\t\treturn \"\", parts[0], containerport\n\tcase 3:\n\t\treturn parts[0], parts[1], containerport\n\tdefault:\n\t\treturn strings.Join(parts[:n-2], \":\"), parts[n-2], containerport\n\t}\n}\n\n// ParsePortSpec parses a port specification string into a slice of PortMappings\nfunc ParsePortSpec(rawPort string) ([]PortMapping, error) {\n\tvar proto string\n\trawIP, hostPort, containerPort := splitParts(rawPort)\n\tproto, containerPort = SplitProtoPort(containerPort)\n\n\t// Strip [] from IPV6 addresses\n\tip, _, err := net.SplitHostPort(rawIP + \":\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Invalid ip address %v: %s\", rawIP, err)\n\t}\n\tif ip != \"\" && net.ParseIP(ip) == nil {\n\t\treturn nil, fmt.Errorf(\"Invalid ip address: %s\", ip)\n\t}\n\tif containerPort == \"\" {\n\t\treturn nil, fmt.Errorf(\"No port specified: %s<empty>\", rawPort)\n\t}\n\n\tstartPort, endPort, err := ParsePortRange(containerPort)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"Invalid containerPort: %s\", containerPort)\n\t}\n\n\tvar startHostPort, endHostPort uint64 = 0, 0\n\tif len(hostPort) > 0 {\n\t\tstartHostPort, endHostPort, err = ParsePortRange(hostPort)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Invalid hostPort: %s\", hostPort)\n\t\t}\n\t}\n\n\tif hostPort != \"\" && (endPort-startPort) != (endHostPort-startHostPort) {\n\t\t// Allow host port range iff containerPort is not a range.\n\t\t// In this case, use the host port range as the dynamic\n\t\t// host port range to allocate into.\n\t\tif endPort != startPort {\n\t\t\treturn nil, fmt.Errorf(\"Invalid ranges specified for container and host Ports: %s and %s\", containerPort, hostPort)\n\t\t}\n\t}\n\n\tif !validateProto(strings.ToLower(proto)) {\n\t\treturn nil, fmt.Errorf(\"Invalid proto: %s\", proto)\n\t}\n\n\tports := []PortMapping{}\n\tfor i := uint64(0); i <= (endPort - startPort); i++ {\n\t\tcontainerPort = strconv.FormatUint(startPort+i, 10)\n\t\tif len(hostPort) > 0 {\n\t\t\thostPort = strconv.FormatUint(startHostPort+i, 10)\n\t\t}\n\t\t// Set hostPort to a range only if there is a single container port\n\t\t// and a dynamic host port.\n\t\tif startPort == endPort && startHostPort != endHostPort {\n\t\t\thostPort = fmt.Sprintf(\"%s-%s\", hostPort, strconv.FormatUint(endHostPort, 10))\n\t\t}\n\t\tport, err := NewPort(strings.ToLower(proto), containerPort)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tbinding := PortBinding{\n\t\t\tHostIP:   ip,\n\t\t\tHostPort: hostPort,\n\t\t}\n\t\tports = append(ports, PortMapping{Port: port, Binding: binding})\n\t}\n\treturn ports, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/nat/parse.go",
    "content": "package nat\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// PartParser parses and validates the specified string (data) using the specified template\n// e.g. ip:public:private -> 192.168.0.1:80:8000\n// DEPRECATED: do not use, this function may be removed in a future version\nfunc PartParser(template, data string) (map[string]string, error) {\n\t// ip:public:private\n\tvar (\n\t\ttemplateParts = strings.Split(template, \":\")\n\t\tparts         = strings.Split(data, \":\")\n\t\tout           = make(map[string]string, len(templateParts))\n\t)\n\tif len(parts) != len(templateParts) {\n\t\treturn nil, fmt.Errorf(\"Invalid format to parse. %s should match template %s\", data, template)\n\t}\n\n\tfor i, t := range templateParts {\n\t\tvalue := \"\"\n\t\tif len(parts) > i {\n\t\t\tvalue = parts[i]\n\t\t}\n\t\tout[t] = value\n\t}\n\treturn out, nil\n}\n\n// ParsePortRange parses and validates the specified string as a port-range (8000-9000)\nfunc ParsePortRange(ports string) (uint64, uint64, error) {\n\tif ports == \"\" {\n\t\treturn 0, 0, fmt.Errorf(\"Empty string specified for ports.\")\n\t}\n\tif !strings.Contains(ports, \"-\") {\n\t\tstart, err := strconv.ParseUint(ports, 10, 16)\n\t\tend := start\n\t\treturn start, end, err\n\t}\n\n\tparts := strings.Split(ports, \"-\")\n\tstart, err := strconv.ParseUint(parts[0], 10, 16)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\tend, err := strconv.ParseUint(parts[1], 10, 16)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\tif end < start {\n\t\treturn 0, 0, fmt.Errorf(\"Invalid range specified for the Port: %s\", ports)\n\t}\n\treturn start, end, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/nat/sort.go",
    "content": "package nat\n\nimport (\n\t\"sort\"\n\t\"strings\"\n)\n\ntype portSorter struct {\n\tports []Port\n\tby    func(i, j Port) bool\n}\n\nfunc (s *portSorter) Len() int {\n\treturn len(s.ports)\n}\n\nfunc (s *portSorter) Swap(i, j int) {\n\ts.ports[i], s.ports[j] = s.ports[j], s.ports[i]\n}\n\nfunc (s *portSorter) Less(i, j int) bool {\n\tip := s.ports[i]\n\tjp := s.ports[j]\n\n\treturn s.by(ip, jp)\n}\n\n// Sort sorts a list of ports using the provided predicate\n// This function should compare `i` and `j`, returning true if `i` is\n// considered to be less than `j`\nfunc Sort(ports []Port, predicate func(i, j Port) bool) {\n\ts := &portSorter{ports, predicate}\n\tsort.Sort(s)\n}\n\ntype portMapEntry struct {\n\tport    Port\n\tbinding PortBinding\n}\n\ntype portMapSorter []portMapEntry\n\nfunc (s portMapSorter) Len() int      { return len(s) }\nfunc (s portMapSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] }\n\n// sort the port so that the order is:\n// 1. port with larger specified bindings\n// 2. larger port\n// 3. port with tcp protocol\nfunc (s portMapSorter) Less(i, j int) bool {\n\tpi, pj := s[i].port, s[j].port\n\thpi, hpj := toInt(s[i].binding.HostPort), toInt(s[j].binding.HostPort)\n\treturn hpi > hpj || pi.Int() > pj.Int() || (pi.Int() == pj.Int() && strings.ToLower(pi.Proto()) == \"tcp\")\n}\n\n// SortPortMap sorts the list of ports and their respected mapping. The ports\n// will explicit HostPort will be placed first.\nfunc SortPortMap(ports []Port, bindings PortMap) {\n\ts := portMapSorter{}\n\tfor _, p := range ports {\n\t\tif binding, ok := bindings[p]; ok {\n\t\t\tfor _, b := range binding {\n\t\t\t\ts = append(s, portMapEntry{port: p, binding: b})\n\t\t\t}\n\t\t\tbindings[p] = []PortBinding{}\n\t\t} else {\n\t\t\ts = append(s, portMapEntry{port: p})\n\t\t}\n\t}\n\n\tsort.Sort(s)\n\tvar (\n\t\ti  int\n\t\tpm = make(map[Port]struct{})\n\t)\n\t// reorder ports\n\tfor _, entry := range s {\n\t\tif _, ok := pm[entry.port]; !ok {\n\t\t\tports[i] = entry.port\n\t\t\tpm[entry.port] = struct{}{}\n\t\t\ti++\n\t\t}\n\t\t// reorder bindings for this port\n\t\tif _, ok := bindings[entry.port]; ok {\n\t\t\tbindings[entry.port] = append(bindings[entry.port], entry.binding)\n\t\t}\n\t}\n}\n\nfunc toInt(s string) uint64 {\n\ti, _, err := ParsePortRange(s)\n\tif err != nil {\n\t\ti = 0\n\t}\n\treturn i\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/README.md",
    "content": ""
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/inmem_socket.go",
    "content": "package sockets\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"sync\"\n)\n\nvar errClosed = errors.New(\"use of closed network connection\")\n\n// InmemSocket implements net.Listener using in-memory only connections.\ntype InmemSocket struct {\n\tchConn  chan net.Conn\n\tchClose chan struct{}\n\taddr    string\n\tmu      sync.Mutex\n}\n\n// dummyAddr is used to satisfy net.Addr for the in-mem socket\n// it is just stored as a string and returns the string for all calls\ntype dummyAddr string\n\n// NewInmemSocket creates an in-memory only net.Listener\n// The addr argument can be any string, but is used to satisfy the `Addr()` part\n// of the net.Listener interface\nfunc NewInmemSocket(addr string, bufSize int) *InmemSocket {\n\treturn &InmemSocket{\n\t\tchConn:  make(chan net.Conn, bufSize),\n\t\tchClose: make(chan struct{}),\n\t\taddr:    addr,\n\t}\n}\n\n// Addr returns the socket's addr string to satisfy net.Listener\nfunc (s *InmemSocket) Addr() net.Addr {\n\treturn dummyAddr(s.addr)\n}\n\n// Accept implements the Accept method in the Listener interface; it waits for the next call and returns a generic Conn.\nfunc (s *InmemSocket) Accept() (net.Conn, error) {\n\tselect {\n\tcase conn := <-s.chConn:\n\t\treturn conn, nil\n\tcase <-s.chClose:\n\t\treturn nil, errClosed\n\t}\n}\n\n// Close closes the listener. It will be unavailable for use once closed.\nfunc (s *InmemSocket) Close() error {\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\tselect {\n\tcase <-s.chClose:\n\tdefault:\n\t\tclose(s.chClose)\n\t}\n\treturn nil\n}\n\n// Dial is used to establish a connection with the in-mem server\nfunc (s *InmemSocket) Dial(network, addr string) (net.Conn, error) {\n\tsrvConn, clientConn := net.Pipe()\n\tselect {\n\tcase s.chConn <- srvConn:\n\tcase <-s.chClose:\n\t\treturn nil, errClosed\n\t}\n\n\treturn clientConn, nil\n}\n\n// Network returns the addr string, satisfies net.Addr\nfunc (a dummyAddr) Network() string {\n\treturn string(a)\n}\n\n// String returns the string form\nfunc (a dummyAddr) String() string {\n\treturn string(a)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/proxy.go",
    "content": "package sockets\n\nimport (\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\t\"strings\"\n\n\t\"golang.org/x/net/proxy\"\n)\n\n// GetProxyEnv allows access to the uppercase and the lowercase forms of\n// proxy-related variables.  See the Go specification for details on these\n// variables. https://golang.org/pkg/net/http/\nfunc GetProxyEnv(key string) string {\n\tproxyValue := os.Getenv(strings.ToUpper(key))\n\tif proxyValue == \"\" {\n\t\treturn os.Getenv(strings.ToLower(key))\n\t}\n\treturn proxyValue\n}\n\n// DialerFromEnvironment takes in a \"direct\" *net.Dialer and returns a\n// proxy.Dialer which will route the connections through the proxy using the\n// given dialer.\nfunc DialerFromEnvironment(direct *net.Dialer) (proxy.Dialer, error) {\n\tallProxy := GetProxyEnv(\"all_proxy\")\n\tif len(allProxy) == 0 {\n\t\treturn direct, nil\n\t}\n\n\tproxyURL, err := url.Parse(allProxy)\n\tif err != nil {\n\t\treturn direct, err\n\t}\n\n\tproxyFromURL, err := proxy.FromURL(proxyURL, direct)\n\tif err != nil {\n\t\treturn direct, err\n\t}\n\n\tnoProxy := GetProxyEnv(\"no_proxy\")\n\tif len(noProxy) == 0 {\n\t\treturn proxyFromURL, nil\n\t}\n\n\tperHost := proxy.NewPerHost(proxyFromURL, direct)\n\tperHost.AddFromString(noProxy)\n\n\treturn perHost, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/sockets.go",
    "content": "// Package sockets provides helper functions to create and configure Unix or TCP sockets.\npackage sockets\n\nimport (\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// Why 32? See https://github.com/docker/docker/pull/8035.\nconst defaultTimeout = 32 * time.Second\n\n// ErrProtocolNotAvailable is returned when a given transport protocol is not provided by the operating system.\nvar ErrProtocolNotAvailable = errors.New(\"protocol not available\")\n\n// ConfigureTransport configures the specified Transport according to the\n// specified proto and addr.\n// If the proto is unix (using a unix socket to communicate) or npipe the\n// compression is disabled.\nfunc ConfigureTransport(tr *http.Transport, proto, addr string) error {\n\tswitch proto {\n\tcase \"unix\":\n\t\treturn configureUnixTransport(tr, proto, addr)\n\tcase \"npipe\":\n\t\treturn configureNpipeTransport(tr, proto, addr)\n\tdefault:\n\t\ttr.Proxy = http.ProxyFromEnvironment\n\t\tdialer, err := DialerFromEnvironment(&net.Dialer{\n\t\t\tTimeout: defaultTimeout,\n\t\t})\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttr.Dial = dialer.Dial\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/sockets_unix.go",
    "content": "// +build !windows\n\npackage sockets\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"syscall\"\n\t\"time\"\n)\n\nconst maxUnixSocketPathSize = len(syscall.RawSockaddrUnix{}.Path)\n\nfunc configureUnixTransport(tr *http.Transport, proto, addr string) error {\n\tif len(addr) > maxUnixSocketPathSize {\n\t\treturn fmt.Errorf(\"Unix socket path %q is too long\", addr)\n\t}\n\t// No need for compression in local communications.\n\ttr.DisableCompression = true\n\ttr.Dial = func(_, _ string) (net.Conn, error) {\n\t\treturn net.DialTimeout(proto, addr, defaultTimeout)\n\t}\n\treturn nil\n}\n\nfunc configureNpipeTransport(tr *http.Transport, proto, addr string) error {\n\treturn ErrProtocolNotAvailable\n}\n\n// DialPipe connects to a Windows named pipe.\n// This is not supported on other OSes.\nfunc DialPipe(_ string, _ time.Duration) (net.Conn, error) {\n\treturn nil, syscall.EAFNOSUPPORT\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/sockets_windows.go",
    "content": "package sockets\n\nimport (\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/Microsoft/go-winio\"\n)\n\nfunc configureUnixTransport(tr *http.Transport, proto, addr string) error {\n\treturn ErrProtocolNotAvailable\n}\n\nfunc configureNpipeTransport(tr *http.Transport, proto, addr string) error {\n\t// No need for compression in local communications.\n\ttr.DisableCompression = true\n\ttr.Dial = func(_, _ string) (net.Conn, error) {\n\t\treturn DialPipe(addr, defaultTimeout)\n\t}\n\treturn nil\n}\n\n// DialPipe connects to a Windows named pipe.\nfunc DialPipe(addr string, timeout time.Duration) (net.Conn, error) {\n\treturn winio.DialPipe(addr, &timeout)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/tcp_socket.go",
    "content": "// Package sockets provides helper functions to create and configure Unix or TCP sockets.\npackage sockets\n\nimport (\n\t\"crypto/tls\"\n\t\"net\"\n)\n\n// NewTCPSocket creates a TCP socket listener with the specified address and\n// the specified tls configuration. If TLSConfig is set, will encapsulate the\n// TCP listener inside a TLS one.\nfunc NewTCPSocket(addr string, tlsConfig *tls.Config) (net.Listener, error) {\n\tl, err := net.Listen(\"tcp\", addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif tlsConfig != nil {\n\t\ttlsConfig.NextProtos = []string{\"http/1.1\"}\n\t\tl = tls.NewListener(l, tlsConfig)\n\t}\n\treturn l, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/sockets/unix_socket.go",
    "content": "// +build !windows\n\npackage sockets\n\nimport (\n\t\"net\"\n\t\"os\"\n\t\"syscall\"\n)\n\n// NewUnixSocket creates a unix socket with the specified path and group.\nfunc NewUnixSocket(path string, gid int) (net.Listener, error) {\n\tif err := syscall.Unlink(path); err != nil && !os.IsNotExist(err) {\n\t\treturn nil, err\n\t}\n\tmask := syscall.Umask(0777)\n\tdefer syscall.Umask(mask)\n\n\tl, err := net.Listen(\"unix\", path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := os.Chown(path, 0, gid); err != nil {\n\t\tl.Close()\n\t\treturn nil, err\n\t}\n\tif err := os.Chmod(path, 0660); err != nil {\n\t\tl.Close()\n\t\treturn nil, err\n\t}\n\treturn l, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/tlsconfig/certpool_go17.go",
    "content": "// +build go1.7\n\npackage tlsconfig\n\nimport (\n\t\"crypto/x509\"\n\t\"runtime\"\n)\n\n// SystemCertPool returns a copy of the system cert pool,\n// returns an error if failed to load or empty pool on windows.\nfunc SystemCertPool() (*x509.CertPool, error) {\n\tcertpool, err := x509.SystemCertPool()\n\tif err != nil && runtime.GOOS == \"windows\" {\n\t\treturn x509.NewCertPool(), nil\n\t}\n\treturn certpool, err\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/tlsconfig/certpool_other.go",
    "content": "// +build !go1.7\n\npackage tlsconfig\n\nimport (\n\t\"crypto/x509\"\n)\n\n// SystemCertPool returns an new empty cert pool,\n// accessing system cert pool is supported in go 1.7\nfunc SystemCertPool() (*x509.CertPool, error) {\n\treturn x509.NewCertPool(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/tlsconfig/config.go",
    "content": "// Package tlsconfig provides primitives to retrieve secure-enough TLS configurations for both clients and servers.\n//\n// As a reminder from https://golang.org/pkg/crypto/tls/#Config:\n//\tA Config structure is used to configure a TLS client or server. After one has been passed to a TLS function it must not be modified.\n//\tA Config may be reused; the tls package will also not modify it.\npackage tlsconfig\n\nimport (\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// Options represents the information needed to create client and server TLS configurations.\ntype Options struct {\n\tCAFile string\n\n\t// If either CertFile or KeyFile is empty, Client() will not load them\n\t// preventing the client from authenticating to the server.\n\t// However, Server() requires them and will error out if they are empty.\n\tCertFile string\n\tKeyFile  string\n\n\t// client-only option\n\tInsecureSkipVerify bool\n\t// server-only option\n\tClientAuth tls.ClientAuthType\n\t// If ExclusiveRootPools is set, then if a CA file is provided, the root pool used for TLS\n\t// creds will include exclusively the roots in that CA file.  If no CA file is provided,\n\t// the system pool will be used.\n\tExclusiveRootPools bool\n\tMinVersion         uint16\n\t// If Passphrase is set, it will be used to decrypt a TLS private key\n\t// if the key is encrypted\n\tPassphrase string\n}\n\n// Extra (server-side) accepted CBC cipher suites - will phase out in the future\nvar acceptedCBCCiphers = []uint16{\n\ttls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,\n\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,\n\ttls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,\n\ttls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,\n}\n\n// DefaultServerAcceptedCiphers should be uses by code which already has a crypto/tls\n// options struct but wants to use a commonly accepted set of TLS cipher suites, with\n// known weak algorithms removed.\nvar DefaultServerAcceptedCiphers = append(clientCipherSuites, acceptedCBCCiphers...)\n\n// allTLSVersions lists all the TLS versions and is used by the code that validates\n// a uint16 value as a TLS version.\nvar allTLSVersions = map[uint16]struct{}{\n\ttls.VersionSSL30: {},\n\ttls.VersionTLS10: {},\n\ttls.VersionTLS11: {},\n\ttls.VersionTLS12: {},\n}\n\n// ServerDefault returns a secure-enough TLS configuration for the server TLS configuration.\nfunc ServerDefault(ops ...func(*tls.Config)) *tls.Config {\n\ttlsconfig := &tls.Config{\n\t\t// Avoid fallback by default to SSL protocols < TLS1.2\n\t\tMinVersion:               tls.VersionTLS12,\n\t\tPreferServerCipherSuites: true,\n\t\tCipherSuites:             DefaultServerAcceptedCiphers,\n\t}\n\n\tfor _, op := range ops {\n\t\top(tlsconfig)\n\t}\n\n\treturn tlsconfig\n}\n\n// ClientDefault returns a secure-enough TLS configuration for the client TLS configuration.\nfunc ClientDefault(ops ...func(*tls.Config)) *tls.Config {\n\ttlsconfig := &tls.Config{\n\t\t// Prefer TLS1.2 as the client minimum\n\t\tMinVersion:   tls.VersionTLS12,\n\t\tCipherSuites: clientCipherSuites,\n\t}\n\n\tfor _, op := range ops {\n\t\top(tlsconfig)\n\t}\n\n\treturn tlsconfig\n}\n\n// certPool returns an X.509 certificate pool from `caFile`, the certificate file.\nfunc certPool(caFile string, exclusivePool bool) (*x509.CertPool, error) {\n\t// If we should verify the server, we need to load a trusted ca\n\tvar (\n\t\tcertPool *x509.CertPool\n\t\terr      error\n\t)\n\tif exclusivePool {\n\t\tcertPool = x509.NewCertPool()\n\t} else {\n\t\tcertPool, err = SystemCertPool()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read system certificates: %v\", err)\n\t\t}\n\t}\n\tpem, err := ioutil.ReadFile(caFile)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not read CA certificate %q: %v\", caFile, err)\n\t}\n\tif !certPool.AppendCertsFromPEM(pem) {\n\t\treturn nil, fmt.Errorf(\"failed to append certificates from PEM file: %q\", caFile)\n\t}\n\treturn certPool, nil\n}\n\n// isValidMinVersion checks that the input value is a valid tls minimum version\nfunc isValidMinVersion(version uint16) bool {\n\t_, ok := allTLSVersions[version]\n\treturn ok\n}\n\n// adjustMinVersion sets the MinVersion on `config`, the input configuration.\n// It assumes the current MinVersion on the `config` is the lowest allowed.\nfunc adjustMinVersion(options Options, config *tls.Config) error {\n\tif options.MinVersion > 0 {\n\t\tif !isValidMinVersion(options.MinVersion) {\n\t\t\treturn fmt.Errorf(\"Invalid minimum TLS version: %x\", options.MinVersion)\n\t\t}\n\t\tif options.MinVersion < config.MinVersion {\n\t\t\treturn fmt.Errorf(\"Requested minimum TLS version is too low. Should be at-least: %x\", config.MinVersion)\n\t\t}\n\t\tconfig.MinVersion = options.MinVersion\n\t}\n\n\treturn nil\n}\n\n// IsErrEncryptedKey returns true if the 'err' is an error of incorrect\n// password when tryin to decrypt a TLS private key\nfunc IsErrEncryptedKey(err error) bool {\n\treturn errors.Cause(err) == x509.IncorrectPasswordError\n}\n\n// getPrivateKey returns the private key in 'keyBytes', in PEM-encoded format.\n// If the private key is encrypted, 'passphrase' is used to decrypted the\n// private key.\nfunc getPrivateKey(keyBytes []byte, passphrase string) ([]byte, error) {\n\t// this section makes some small changes to code from notary/tuf/utils/x509.go\n\tpemBlock, _ := pem.Decode(keyBytes)\n\tif pemBlock == nil {\n\t\treturn nil, fmt.Errorf(\"no valid private key found\")\n\t}\n\n\tvar err error\n\tif x509.IsEncryptedPEMBlock(pemBlock) {\n\t\tkeyBytes, err = x509.DecryptPEMBlock(pemBlock, []byte(passphrase))\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrap(err, \"private key is encrypted, but could not decrypt it\")\n\t\t}\n\t\tkeyBytes = pem.EncodeToMemory(&pem.Block{Type: pemBlock.Type, Bytes: keyBytes})\n\t}\n\n\treturn keyBytes, nil\n}\n\n// getCert returns a Certificate from the CertFile and KeyFile in 'options',\n// if the key is encrypted, the Passphrase in 'options' will be used to\n// decrypt it.\nfunc getCert(options Options) ([]tls.Certificate, error) {\n\tif options.CertFile == \"\" && options.KeyFile == \"\" {\n\t\treturn nil, nil\n\t}\n\n\terrMessage := \"Could not load X509 key pair\"\n\n\tcert, err := ioutil.ReadFile(options.CertFile)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, errMessage)\n\t}\n\n\tprKeyBytes, err := ioutil.ReadFile(options.KeyFile)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, errMessage)\n\t}\n\n\tprKeyBytes, err = getPrivateKey(prKeyBytes, options.Passphrase)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, errMessage)\n\t}\n\n\ttlsCert, err := tls.X509KeyPair(cert, prKeyBytes)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, errMessage)\n\t}\n\n\treturn []tls.Certificate{tlsCert}, nil\n}\n\n// Client returns a TLS configuration meant to be used by a client.\nfunc Client(options Options) (*tls.Config, error) {\n\ttlsConfig := ClientDefault()\n\ttlsConfig.InsecureSkipVerify = options.InsecureSkipVerify\n\tif !options.InsecureSkipVerify && options.CAFile != \"\" {\n\t\tCAs, err := certPool(options.CAFile, options.ExclusiveRootPools)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttlsConfig.RootCAs = CAs\n\t}\n\n\ttlsCerts, err := getCert(options)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttlsConfig.Certificates = tlsCerts\n\n\tif err := adjustMinVersion(options, tlsConfig); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn tlsConfig, nil\n}\n\n// Server returns a TLS configuration meant to be used by a server.\nfunc Server(options Options) (*tls.Config, error) {\n\ttlsConfig := ServerDefault()\n\ttlsConfig.ClientAuth = options.ClientAuth\n\ttlsCert, err := tls.LoadX509KeyPair(options.CertFile, options.KeyFile)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, fmt.Errorf(\"Could not load X509 key pair (cert: %q, key: %q): %v\", options.CertFile, options.KeyFile, err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"Error reading X509 key pair (cert: %q, key: %q): %v. Make sure the key is not encrypted.\", options.CertFile, options.KeyFile, err)\n\t}\n\ttlsConfig.Certificates = []tls.Certificate{tlsCert}\n\tif options.ClientAuth >= tls.VerifyClientCertIfGiven && options.CAFile != \"\" {\n\t\tCAs, err := certPool(options.CAFile, options.ExclusiveRootPools)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttlsConfig.ClientCAs = CAs\n\t}\n\n\tif err := adjustMinVersion(options, tlsConfig); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn tlsConfig, nil\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/tlsconfig/config_client_ciphers.go",
    "content": "// +build go1.5\n\n// Package tlsconfig provides primitives to retrieve secure-enough TLS configurations for both clients and servers.\n//\npackage tlsconfig\n\nimport (\n\t\"crypto/tls\"\n)\n\n// Client TLS cipher suites (dropping CBC ciphers for client preferred suite set)\nvar clientCipherSuites = []uint16{\n\ttls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n\ttls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,\n\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n\ttls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-connections/tlsconfig/config_legacy_client_ciphers.go",
    "content": "// +build !go1.5\n\n// Package tlsconfig provides primitives to retrieve secure-enough TLS configurations for both clients and servers.\n//\npackage tlsconfig\n\nimport (\n\t\"crypto/tls\"\n)\n\n// Client TLS cipher suites (dropping CBC ciphers for client preferred suite set)\nvar clientCipherSuites = []uint16{\n\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n\ttls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-units/CONTRIBUTING.md",
    "content": "# Contributing to go-units\n\nWant to hack on go-units? Awesome! Here are instructions to get you started.\n\ngo-units is a part of the [Docker](https://www.docker.com) project, and follows\nthe same rules and principles. If you're already familiar with the way\nDocker does things, you'll feel right at home.\n\nOtherwise, go read Docker's\n[contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md),\n[issue triaging](https://github.com/docker/docker/blob/master/project/ISSUE-TRIAGE.md),\n[review process](https://github.com/docker/docker/blob/master/project/REVIEWING.md) and\n[branches and tags](https://github.com/docker/docker/blob/master/project/BRANCHES-AND-TAGS.md).\n\n### Sign your work\n\nThe sign-off is a simple line at the end of the explanation for the patch. Your\nsignature certifies that you wrote the patch or otherwise have the right to pass\nit on as an open-source patch. The rules are pretty simple: if you can certify\nthe below (from [developercertificate.org](http://developercertificate.org/)):\n\n```\nDeveloper Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n660 York Street, Suite 102,\nSan Francisco, CA 94110 USA\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n    have the right to submit it under the open source license\n    indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n    of my knowledge, is covered under an appropriate open source\n    license and I have the right under that license to submit that\n    work with modifications, whether created in whole or in part\n    by me, under the same open source license (unless I am\n    permitted to submit under a different license), as indicated\n    in the file; or\n\n(c) The contribution was provided directly to me by some other\n    person who certified (a), (b) or (c) and I have not modified\n    it.\n\n(d) I understand and agree that this project and the contribution\n    are public and that a record of the contribution (including all\n    personal information I submit with it, including my sign-off) is\n    maintained indefinitely and may be redistributed consistent with\n    this project or the open source license(s) involved.\n```\n\nThen you just add a line to every git commit message:\n\n    Signed-off-by: Joe Smith <joe.smith@email.com>\n\nUse your real name (sorry, no pseudonyms or anonymous contributions.)\n\nIf you set your `user.name` and `user.email` git configs, you can sign your\ncommit automatically with `git commit -s`.\n"
  },
  {
    "path": "vendor/github.com/docker/go-units/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 2015 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": "vendor/github.com/docker/go-units/MAINTAINERS",
    "content": "# go-units maintainers file\n#\n# This file describes who runs the docker/go-units project and how.\n# This is a living document - if you see something out of date or missing, speak up!\n#\n# It is structured to be consumable by both humans and programs.\n# To extract its contents programmatically, use any TOML-compliant parser.\n#\n# This file is compiled into the MAINTAINERS file in docker/opensource.\n#\n[Org]\n\t[Org.\"Core maintainers\"]\n\t\tpeople = [\n\t\t\t\"akihirosuda\",\n\t\t\t\"dnephin\",\n\t\t\t\"thajeztah\",\n\t\t\t\"vdemeester\",\n\t\t]\n\n[people]\n\n# A reference list of all people associated with the project.\n# All other sections should refer to people by their canonical key\n# in the people section.\n\n\t# ADD YOURSELF HERE IN ALPHABETICAL ORDER\n\n\t[people.akihirosuda]\n\tName = \"Akihiro Suda\"\n\tEmail = \"akihiro.suda.cz@hco.ntt.co.jp\"\n\tGitHub = \"AkihiroSuda\"\n\n\t[people.dnephin]\n\tName = \"Daniel Nephin\"\n\tEmail = \"dnephin@gmail.com\"\n\tGitHub = \"dnephin\"\n\t\n\t[people.thajeztah]\n\tName = \"Sebastiaan van Stijn\"\n\tEmail = \"github@gone.nl\"\n\tGitHub = \"thaJeztah\"\n\n\t[people.vdemeester]\n\tName = \"Vincent Demeester\"\n\tEmail = \"vincent@sbr.pm\"\n\tGitHub = \"vdemeester\""
  },
  {
    "path": "vendor/github.com/docker/go-units/README.md",
    "content": "[![GoDoc](https://godoc.org/github.com/docker/go-units?status.svg)](https://godoc.org/github.com/docker/go-units)\n\n# Introduction\n\ngo-units is a library to transform human friendly measurements into machine friendly values.\n\n## Usage\n\nSee the [docs in godoc](https://godoc.org/github.com/docker/go-units) for examples and documentation.\n\n## Copyright and license\n\nCopyright © 2015 Docker, Inc.\n\ngo-units is licensed under the Apache License, Version 2.0.\nSee [LICENSE](LICENSE) for the full text of the license.\n"
  },
  {
    "path": "vendor/github.com/docker/go-units/circle.yml",
    "content": "dependencies:\n  post:\n    # install golint\n    - go get golang.org/x/lint/golint\n\ntest:\n  pre:\n    # run analysis before tests\n    - go vet ./...\n    - test -z \"$(golint ./... | tee /dev/stderr)\"\n    - test -z \"$(gofmt -s -l . | tee /dev/stderr)\"\n"
  },
  {
    "path": "vendor/github.com/docker/go-units/duration.go",
    "content": "// Package units provides helper function to parse and print size and time units\n// in human-readable format.\npackage units\n\nimport (\n\t\"fmt\"\n\t\"time\"\n)\n\n// HumanDuration returns a human-readable approximation of a duration\n// (eg. \"About a minute\", \"4 hours ago\", etc.).\nfunc HumanDuration(d time.Duration) string {\n\tif seconds := int(d.Seconds()); seconds < 1 {\n\t\treturn \"Less than a second\"\n\t} else if seconds == 1 {\n\t\treturn \"1 second\"\n\t} else if seconds < 60 {\n\t\treturn fmt.Sprintf(\"%d seconds\", seconds)\n\t} else if minutes := int(d.Minutes()); minutes == 1 {\n\t\treturn \"About a minute\"\n\t} else if minutes < 60 {\n\t\treturn fmt.Sprintf(\"%d minutes\", minutes)\n\t} else if hours := int(d.Hours() + 0.5); hours == 1 {\n\t\treturn \"About an hour\"\n\t} else if hours < 48 {\n\t\treturn fmt.Sprintf(\"%d hours\", hours)\n\t} else if hours < 24*7*2 {\n\t\treturn fmt.Sprintf(\"%d days\", hours/24)\n\t} else if hours < 24*30*2 {\n\t\treturn fmt.Sprintf(\"%d weeks\", hours/24/7)\n\t} else if hours < 24*365*2 {\n\t\treturn fmt.Sprintf(\"%d months\", hours/24/30)\n\t}\n\treturn fmt.Sprintf(\"%d years\", int(d.Hours())/24/365)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-units/size.go",
    "content": "package units\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// See: http://en.wikipedia.org/wiki/Binary_prefix\nconst (\n\t// Decimal\n\n\tKB = 1000\n\tMB = 1000 * KB\n\tGB = 1000 * MB\n\tTB = 1000 * GB\n\tPB = 1000 * TB\n\n\t// Binary\n\n\tKiB = 1024\n\tMiB = 1024 * KiB\n\tGiB = 1024 * MiB\n\tTiB = 1024 * GiB\n\tPiB = 1024 * TiB\n)\n\ntype unitMap map[byte]int64\n\nvar (\n\tdecimalMap = unitMap{'k': KB, 'm': MB, 'g': GB, 't': TB, 'p': PB}\n\tbinaryMap  = unitMap{'k': KiB, 'm': MiB, 'g': GiB, 't': TiB, 'p': PiB}\n)\n\nvar (\n\tdecimapAbbrs = []string{\"B\", \"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"}\n\tbinaryAbbrs  = []string{\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"}\n)\n\nfunc getSizeAndUnit(size float64, base float64, _map []string) (float64, string) {\n\ti := 0\n\tunitsLimit := len(_map) - 1\n\tfor size >= base && i < unitsLimit {\n\t\tsize = size / base\n\t\ti++\n\t}\n\treturn size, _map[i]\n}\n\n// CustomSize returns a human-readable approximation of a size\n// using custom format.\nfunc CustomSize(format string, size float64, base float64, _map []string) string {\n\tsize, unit := getSizeAndUnit(size, base, _map)\n\treturn fmt.Sprintf(format, size, unit)\n}\n\n// HumanSizeWithPrecision allows the size to be in any precision,\n// instead of 4 digit precision used in units.HumanSize.\nfunc HumanSizeWithPrecision(size float64, precision int) string {\n\tsize, unit := getSizeAndUnit(size, 1000.0, decimapAbbrs)\n\treturn fmt.Sprintf(\"%.*g%s\", precision, size, unit)\n}\n\n// HumanSize returns a human-readable approximation of a size\n// capped at 4 valid numbers (eg. \"2.746 MB\", \"796 KB\").\nfunc HumanSize(size float64) string {\n\treturn HumanSizeWithPrecision(size, 4)\n}\n\n// BytesSize returns a human-readable size in bytes, kibibytes,\n// mebibytes, gibibytes, or tebibytes (eg. \"44kiB\", \"17MiB\").\nfunc BytesSize(size float64) string {\n\treturn CustomSize(\"%.4g%s\", size, 1024.0, binaryAbbrs)\n}\n\n// FromHumanSize returns an integer from a human-readable specification of a\n// size using SI standard (eg. \"44kB\", \"17MB\").\nfunc FromHumanSize(size string) (int64, error) {\n\treturn parseSize(size, decimalMap)\n}\n\n// RAMInBytes parses a human-readable string representing an amount of RAM\n// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and\n// returns the number of bytes, or -1 if the string is unparseable.\n// Units are case-insensitive, and the 'b' suffix is optional.\nfunc RAMInBytes(size string) (int64, error) {\n\treturn parseSize(size, binaryMap)\n}\n\n// Parses the human-readable size string into the amount it represents.\nfunc parseSize(sizeStr string, uMap unitMap) (int64, error) {\n\t// TODO: rewrite to use strings.Cut if there's a space\n\t// once Go < 1.18 is deprecated.\n\tsep := strings.LastIndexAny(sizeStr, \"01234567890. \")\n\tif sep == -1 {\n\t\t// There should be at least a digit.\n\t\treturn -1, fmt.Errorf(\"invalid size: '%s'\", sizeStr)\n\t}\n\tvar num, sfx string\n\tif sizeStr[sep] != ' ' {\n\t\tnum = sizeStr[:sep+1]\n\t\tsfx = sizeStr[sep+1:]\n\t} else {\n\t\t// Omit the space separator.\n\t\tnum = sizeStr[:sep]\n\t\tsfx = sizeStr[sep+1:]\n\t}\n\n\tsize, err := strconv.ParseFloat(num, 64)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\t// Backward compatibility: reject negative sizes.\n\tif size < 0 {\n\t\treturn -1, fmt.Errorf(\"invalid size: '%s'\", sizeStr)\n\t}\n\n\tif len(sfx) == 0 {\n\t\treturn int64(size), nil\n\t}\n\n\t// Process the suffix.\n\n\tif len(sfx) > 3 { // Too long.\n\t\tgoto badSuffix\n\t}\n\tsfx = strings.ToLower(sfx)\n\t// Trivial case: b suffix.\n\tif sfx[0] == 'b' {\n\t\tif len(sfx) > 1 { // no extra characters allowed after b.\n\t\t\tgoto badSuffix\n\t\t}\n\t\treturn int64(size), nil\n\t}\n\t// A suffix from the map.\n\tif mul, ok := uMap[sfx[0]]; ok {\n\t\tsize *= float64(mul)\n\t} else {\n\t\tgoto badSuffix\n\t}\n\n\t// The suffix may have extra \"b\" or \"ib\" (e.g. KiB or MB).\n\tswitch {\n\tcase len(sfx) == 2 && sfx[1] != 'b':\n\t\tgoto badSuffix\n\tcase len(sfx) == 3 && sfx[1:] != \"ib\":\n\t\tgoto badSuffix\n\t}\n\n\treturn int64(size), nil\n\nbadSuffix:\n\treturn -1, fmt.Errorf(\"invalid suffix: '%s'\", sfx)\n}\n"
  },
  {
    "path": "vendor/github.com/docker/go-units/ulimit.go",
    "content": "package units\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Ulimit is a human friendly version of Rlimit.\ntype Ulimit struct {\n\tName string\n\tHard int64\n\tSoft int64\n}\n\n// Rlimit specifies the resource limits, such as max open files.\ntype Rlimit struct {\n\tType int    `json:\"type,omitempty\"`\n\tHard uint64 `json:\"hard,omitempty\"`\n\tSoft uint64 `json:\"soft,omitempty\"`\n}\n\nconst (\n\t// magic numbers for making the syscall\n\t// some of these are defined in the syscall package, but not all.\n\t// Also since Windows client doesn't get access to the syscall package, need to\n\t//\tdefine these here\n\trlimitAs         = 9\n\trlimitCore       = 4\n\trlimitCPU        = 0\n\trlimitData       = 2\n\trlimitFsize      = 1\n\trlimitLocks      = 10\n\trlimitMemlock    = 8\n\trlimitMsgqueue   = 12\n\trlimitNice       = 13\n\trlimitNofile     = 7\n\trlimitNproc      = 6\n\trlimitRss        = 5\n\trlimitRtprio     = 14\n\trlimitRttime     = 15\n\trlimitSigpending = 11\n\trlimitStack      = 3\n)\n\nvar ulimitNameMapping = map[string]int{\n\t//\"as\":         rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container.\n\t\"core\":       rlimitCore,\n\t\"cpu\":        rlimitCPU,\n\t\"data\":       rlimitData,\n\t\"fsize\":      rlimitFsize,\n\t\"locks\":      rlimitLocks,\n\t\"memlock\":    rlimitMemlock,\n\t\"msgqueue\":   rlimitMsgqueue,\n\t\"nice\":       rlimitNice,\n\t\"nofile\":     rlimitNofile,\n\t\"nproc\":      rlimitNproc,\n\t\"rss\":        rlimitRss,\n\t\"rtprio\":     rlimitRtprio,\n\t\"rttime\":     rlimitRttime,\n\t\"sigpending\": rlimitSigpending,\n\t\"stack\":      rlimitStack,\n}\n\n// ParseUlimit parses and returns a Ulimit from the specified string.\nfunc ParseUlimit(val string) (*Ulimit, error) {\n\tparts := strings.SplitN(val, \"=\", 2)\n\tif len(parts) != 2 {\n\t\treturn nil, fmt.Errorf(\"invalid ulimit argument: %s\", val)\n\t}\n\n\tif _, exists := ulimitNameMapping[parts[0]]; !exists {\n\t\treturn nil, fmt.Errorf(\"invalid ulimit type: %s\", parts[0])\n\t}\n\n\tvar (\n\t\tsoft int64\n\t\thard = &soft // default to soft in case no hard was set\n\t\ttemp int64\n\t\terr  error\n\t)\n\tswitch limitVals := strings.Split(parts[1], \":\"); len(limitVals) {\n\tcase 2:\n\t\ttemp, err = strconv.ParseInt(limitVals[1], 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\thard = &temp\n\t\tfallthrough\n\tcase 1:\n\t\tsoft, err = strconv.ParseInt(limitVals[0], 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"too many limit value arguments - %s, can only have up to two, `soft[:hard]`\", parts[1])\n\t}\n\n\tif *hard != -1 {\n\t\tif soft == -1 {\n\t\t\treturn nil, fmt.Errorf(\"ulimit soft limit must be less than or equal to hard limit: soft: -1 (unlimited), hard: %d\", *hard)\n\t\t}\n\t\tif soft > *hard {\n\t\t\treturn nil, fmt.Errorf(\"ulimit soft limit must be less than or equal to hard limit: %d > %d\", soft, *hard)\n\t\t}\n\t}\n\n\treturn &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil\n}\n\n// GetRlimit returns the RLimit corresponding to Ulimit.\nfunc (u *Ulimit) GetRlimit() (*Rlimit, error) {\n\tt, exists := ulimitNameMapping[u.Name]\n\tif !exists {\n\t\treturn nil, fmt.Errorf(\"invalid ulimit name %s\", u.Name)\n\t}\n\n\treturn &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil\n}\n\nfunc (u *Ulimit) String() string {\n\treturn fmt.Sprintf(\"%s=%d:%d\", u.Name, u.Soft, u.Hard)\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/.travis.yml",
    "content": "sudo: false\nlanguage: go\nbefore_install:\n  - curl -L https://github.com/google/brotli/archive/v1.0.2.tar.gz | tar -zxv\n  - (cd brotli-1.0.2 && mkdir out && cd out && ../configure-cmake && make && sudo make install)\n  - rm -rf brotli-1.0.2\n  - curl -L https://github.com/facebook/zstd/archive/v1.3.2.tar.gz | tar -zxv\n  - (cd zstd-1.3.2 && sudo make install)\n  - rm -rf zstd-1.3.2\n  - sudo ldconfig\n  - mkdir /tmp/go1.12\n  - curl -L -s https://dl.google.com/go/go1.12.linux-amd64.tar.gz | tar -zxf - -C /tmp/go1.12 --strip-components 1\n  - unset GOROOT\n  - (GO111MODULE=on /tmp/go1.12/bin/go mod vendor)\n  - (cd /tmp && GO111MODULE=on /tmp/go1.12/bin/go get golang.org/x/lint/golint@8f45f776aaf18cebc8d65861cc70c33c60471952)\n  - (cd /tmp && GO111MODULE=on /tmp/go1.12/bin/go get honnef.co/go/tools/cmd/staticcheck@2019.1)\nmatrix:\n  include:\n    - go: 1.9.x\n      script:\n        - go test -v -race ./...\n    - go: 1.10.x\n      script:\n        - go test -v -race ./...\n    - go: 1.11.x\n      script:\n        - go test -v -race ./...\n    - go: 1.12.x\n      script:\n        - ./ztest.sh\n    - go: master\n      script:\n        - go test -v -race ./...\n  allow_failures:\n    - go: master\n  fast_finish: true\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/LICENSE.md",
    "content": "Copyright © 2015, Joe Tsai and 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 met:\n\n* Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation and/or\nother materials provided with the distribution.\n* Neither the copyright holder nor the names of its contributors may be used to\nendorse or promote products derived from this software without specific prior\nwritten permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY\nDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\nON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/README.md",
    "content": "# Collection of compression libraries for Go #\n\n[![GoDoc](https://godoc.org/github.com/dsnet/compress/cmp?status.svg)](https://godoc.org/github.com/dsnet/compress)\n[![Build Status](https://travis-ci.org/dsnet/compress.svg?branch=master)](https://travis-ci.org/dsnet/compress)\n[![Report Card](https://goreportcard.com/badge/github.com/dsnet/compress)](https://goreportcard.com/report/github.com/dsnet/compress)\n\n## Introduction ##\n\n**NOTE: This library is in active development. As such, there are no guarantees about the stability of the API. The author reserves the right to arbitrarily break the API for any reason.**\n\nThis repository hosts a collection of compression related libraries. The goal of this project is to provide pure Go implementations for popular compression algorithms beyond what the Go standard library provides. The goals for these packages are as follows:\n* Maintainable: That the code remains well documented, well tested, readable, easy to maintain, and easy to verify that it conforms to the specification for the format being implemented.\n* Performant: To be able to compress and decompress within at least 80% of the rates that the C implementations are able to achieve.\n* Flexible: That the code provides low-level and fine granularity control over the compression streams similar to what the C APIs would provide.\n\nOf these three, the first objective is often at odds with the other two objectives and provides interesting challenges. Higher performance can often be achieved by muddling abstraction layers or using non-intuitive low-level primitives. Also, more features and functionality, while useful in some situations, often complicates the API. Thus, this package will attempt to satisfy all the goals, but will defer to favoring maintainability when the performance or flexibility benefits are not significant enough.\n\n\n## Library Status ##\n\nFor the packages available, only some features are currently implemented:\n\n| Package | Reader | Writer |\n| ------- | :----: | :----: |\n| brotli | :white_check_mark: | |\n| bzip2 | :white_check_mark: | :white_check_mark: |\n| flate | :white_check_mark: | |\n| xflate | :white_check_mark: | :white_check_mark: |\n\nThis library is in active development. As such, there are no guarantees about the stability of the API. The author reserves the right to arbitrarily break the API for any reason. When the library becomes more mature, it is planned to eventually conform to some strict versioning scheme like [Semantic Versioning](http://semver.org/).\n\nHowever, in the meanwhile, this library does provide some basic API guarantees. For the types defined below, the method signatures are guaranteed to not change. Note that the author still reserves the right to change the fields within each ```Reader``` and ```Writer``` structs.\n```go\ntype ReaderConfig struct { ... }\ntype Reader struct { ... }\n  func NewReader(io.Reader, *ReaderConfig) (*Reader, error) { ... }\n  func (*Reader) Read([]byte) (int, error)                  { ... }\n  func (*Reader) Close() error                              { ... }\n\ntype WriterConfig struct { ... }\ntype Writer struct { ... }\n  func NewWriter(io.Writer, *WriterConfig) (*Writer, error) { ... }\n  func (*Writer) Write([]byte) (int, error)                 { ... }\n  func (*Writer) Close() error                              { ... }\n```\n\nTo see what work still remains, see the [Task List](https://github.com/dsnet/compress/wiki/Task-List).\n\n## Performance  ##\n\nSee [Performance Metrics](https://github.com/dsnet/compress/wiki/Performance-Metrics).\n\n\n## Frequently Asked Questions ##\n\nSee [Frequently Asked Questions](https://github.com/dsnet/compress/wiki/Frequently-Asked-Questions).\n\n\n## Installation ##\n\nRun the command:\n\n```go get -u github.com/dsnet/compress```\n\nThis library requires `Go1.9` or higher in order to build.\n\n\n## Packages ##\n\n| Package | Description |\n| :------ | :---------- |\n| [brotli](http://godoc.org/github.com/dsnet/compress/brotli) | Package brotli implements the Brotli format, described in RFC 7932. |\n| [bzip2](http://godoc.org/github.com/dsnet/compress/bzip2) | Package bzip2 implements the BZip2 compressed data format. |\n| [flate](http://godoc.org/github.com/dsnet/compress/flate) | Package flate implements the DEFLATE format, described in RFC 1951. |\n| [xflate](http://godoc.org/github.com/dsnet/compress/xflate) | Package xflate implements the XFLATE format, an random-access extension to DEFLATE. |\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/api.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Package compress is a collection of compression libraries.\npackage compress\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\n\t\"github.com/dsnet/compress/internal/errors\"\n)\n\n// The Error interface identifies all compression related errors.\ntype Error interface {\n\terror\n\tCompressError()\n\n\t// IsDeprecated reports the use of a deprecated and unsupported feature.\n\tIsDeprecated() bool\n\n\t// IsCorrupted reports whether the input stream was corrupted.\n\tIsCorrupted() bool\n}\n\nvar _ Error = errors.Error{}\n\n// ByteReader is an interface accepted by all decompression Readers.\n// It guarantees that the decompressor never reads more data than is necessary\n// from the underlying io.Reader.\ntype ByteReader interface {\n\tio.Reader\n\tio.ByteReader\n}\n\nvar _ ByteReader = (*bufio.Reader)(nil)\n\n// BufferedReader is an interface accepted by all decompression Readers.\n// It guarantees that the decompressor never reads more data than is necessary\n// from the underlying io.Reader. Since BufferedReader allows a decompressor\n// to peek at bytes further along in the stream without advancing the read\n// pointer, decompression can experience a significant performance gain when\n// provided a reader that satisfies this interface. Thus, a decompressor will\n// prefer this interface over ByteReader for performance reasons.\n//\n// The bufio.Reader satisfies this interface.\ntype BufferedReader interface {\n\tio.Reader\n\n\t// Buffered returns the number of bytes currently buffered.\n\t//\n\t// This value becomes invalid following the next Read/Discard operation.\n\tBuffered() int\n\n\t// Peek returns the next n bytes without advancing the reader.\n\t//\n\t// If Peek returns fewer than n bytes, it also returns an error explaining\n\t// why the peek is short. Peek must support peeking of at least 8 bytes.\n\t// If 0 <= n <= Buffered(), Peek is guaranteed to succeed without reading\n\t// from the underlying io.Reader.\n\t//\n\t// This result becomes invalid following the next Read/Discard operation.\n\tPeek(n int) ([]byte, error)\n\n\t// Discard skips the next n bytes, returning the number of bytes discarded.\n\t//\n\t// If Discard skips fewer than n bytes, it also returns an error.\n\t// If 0 <= n <= Buffered(), Discard is guaranteed to succeed without reading\n\t// from the underlying io.Reader.\n\tDiscard(n int) (int, error)\n}\n\nvar _ BufferedReader = (*bufio.Reader)(nil)\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/bwt.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage bzip2\n\nimport \"github.com/dsnet/compress/bzip2/internal/sais\"\n\n// The Burrows-Wheeler Transform implementation used here is based on the\n// Suffix Array by Induced Sorting (SA-IS) methodology by Nong, Zhang, and Chan.\n// This implementation uses the sais algorithm originally written by Yuta Mori.\n//\n// The SA-IS algorithm runs in O(n) and outputs a Suffix Array. There is a\n// mathematical relationship between Suffix Arrays and the Burrows-Wheeler\n// Transform, such that a SA can be converted to a BWT in O(n) time.\n//\n// References:\n//\thttp://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf\n//\thttps://github.com/cscott/compressjs/blob/master/lib/BWT.js\n//\thttps://www.quora.com/How-can-I-optimize-burrows-wheeler-transform-and-inverse-transform-to-work-in-O-n-time-O-n-space\ntype burrowsWheelerTransform struct {\n\tbuf  []byte\n\tsa   []int\n\tperm []uint32\n}\n\nfunc (bwt *burrowsWheelerTransform) Encode(buf []byte) (ptr int) {\n\tif len(buf) == 0 {\n\t\treturn -1\n\t}\n\n\t// TODO(dsnet): Find a way to avoid the duplicate input string method.\n\t// We only need to do this because suffix arrays (by definition) only\n\t// operate non-wrapped suffixes of a string. On the other hand,\n\t// the BWT specifically used in bzip2 operate on a strings that wrap-around\n\t// when being sorted.\n\n\t// Step 1: Concatenate the input string to itself so that we can use the\n\t// suffix array algorithm for bzip2's variant of BWT.\n\tn := len(buf)\n\tbwt.buf = append(append(bwt.buf[:0], buf...), buf...)\n\tif cap(bwt.sa) < 2*n {\n\t\tbwt.sa = make([]int, 2*n)\n\t}\n\tt := bwt.buf[:2*n]\n\tsa := bwt.sa[:2*n]\n\n\t// Step 2: Compute the suffix array (SA). The input string, t, will not be\n\t// modified, while the results will be written to the output, sa.\n\tsais.ComputeSA(t, sa)\n\n\t// Step 3: Convert the SA to a BWT. Since ComputeSA does not mutate the\n\t// input, we have two copies of the input; in buf and buf2. Thus, we write\n\t// the transformation to buf, while using buf2.\n\tvar j int\n\tbuf2 := t[n:]\n\tfor _, i := range sa {\n\t\tif i < n {\n\t\t\tif i == 0 {\n\t\t\t\tptr = j\n\t\t\t\ti = n\n\t\t\t}\n\t\t\tbuf[j] = buf2[i-1]\n\t\t\tj++\n\t\t}\n\t}\n\treturn ptr\n}\n\nfunc (bwt *burrowsWheelerTransform) Decode(buf []byte, ptr int) {\n\tif len(buf) == 0 {\n\t\treturn\n\t}\n\n\t// Step 1: Compute cumm, where cumm[ch] reports the total number of\n\t// characters that precede the character ch in the alphabet.\n\tvar cumm [256]int\n\tfor _, v := range buf {\n\t\tcumm[v]++\n\t}\n\tvar sum int\n\tfor i, v := range cumm {\n\t\tcumm[i] = sum\n\t\tsum += v\n\t}\n\n\t// Step 2: Compute perm, where perm[ptr] contains a pointer to the next\n\t// byte in buf and the next pointer in perm itself.\n\tif cap(bwt.perm) < len(buf) {\n\t\tbwt.perm = make([]uint32, len(buf))\n\t}\n\tperm := bwt.perm[:len(buf)]\n\tfor i, b := range buf {\n\t\tperm[cumm[b]] = uint32(i)\n\t\tcumm[b]++\n\t}\n\n\t// Step 3: Follow each pointer in perm to the next byte, starting with the\n\t// origin pointer.\n\tif cap(bwt.buf) < len(buf) {\n\t\tbwt.buf = make([]byte, len(buf))\n\t}\n\tbuf2 := bwt.buf[:len(buf)]\n\ti := perm[ptr]\n\tfor j := range buf2 {\n\t\tbuf2[j] = buf[i]\n\t\ti = perm[i]\n\t}\n\tcopy(buf, buf2)\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/common.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Package bzip2 implements the BZip2 compressed data format.\n//\n// Canonical C implementation:\n//\thttp://bzip.org\n//\n// Unofficial format specification:\n//\thttps://github.com/dsnet/compress/blob/master/doc/bzip2-format.pdf\npackage bzip2\n\nimport (\n\t\"fmt\"\n\t\"hash/crc32\"\n\n\t\"github.com/dsnet/compress/internal\"\n\t\"github.com/dsnet/compress/internal/errors\"\n)\n\n// There does not exist a formal specification of the BZip2 format. As such,\n// much of this work is derived by either reverse engineering the original C\n// source code or using secondary sources.\n//\n// Significant amounts of fuzz testing is done to ensure that outputs from\n// this package is properly decoded by the C library. Furthermore, we test that\n// both this package and the C library agree about what inputs are invalid.\n//\n// Compression stack:\n//\tRun-length encoding 1     (RLE1)\n//\tBurrows-Wheeler transform (BWT)\n//\tMove-to-front transform   (MTF)\n//\tRun-length encoding 2     (RLE2)\n//\tPrefix encoding           (PE)\n//\n// References:\n//\thttp://bzip.org/\n//\thttps://en.wikipedia.org/wiki/Bzip2\n//\thttps://code.google.com/p/jbzip2/\n\nconst (\n\tBestSpeed          = 1\n\tBestCompression    = 9\n\tDefaultCompression = 6\n)\n\nconst (\n\thdrMagic = 0x425a         // Hex of \"BZ\"\n\tblkMagic = 0x314159265359 // BCD of PI\n\tendMagic = 0x177245385090 // BCD of sqrt(PI)\n\n\tblockSize = 100000\n)\n\nfunc errorf(c int, f string, a ...interface{}) error {\n\treturn errors.Error{Code: c, Pkg: \"bzip2\", Msg: fmt.Sprintf(f, a...)}\n}\n\nfunc panicf(c int, f string, a ...interface{}) {\n\terrors.Panic(errorf(c, f, a...))\n}\n\n// errWrap converts a lower-level errors.Error to be one from this package.\n// The replaceCode passed in will be used to replace the code for any errors\n// with the errors.Invalid code.\n//\n// For the Reader, set this to errors.Corrupted.\n// For the Writer, set this to errors.Internal.\nfunc errWrap(err error, replaceCode int) error {\n\tif cerr, ok := err.(errors.Error); ok {\n\t\tif errors.IsInvalid(cerr) {\n\t\t\tcerr.Code = replaceCode\n\t\t}\n\t\terr = errorf(cerr.Code, \"%s\", cerr.Msg)\n\t}\n\treturn err\n}\n\nvar errClosed = errorf(errors.Closed, \"\")\n\n// crc computes the CRC-32 used by BZip2.\n//\n// The CRC-32 computation in bzip2 treats bytes as having bits in big-endian\n// order. That is, the MSB is read before the LSB. Thus, we can use the\n// standard library version of CRC-32 IEEE with some minor adjustments.\n//\n// The byte array is used as an intermediate buffer to swap the bits of every\n// byte of the input.\ntype crc struct {\n\tval uint32\n\tbuf [256]byte\n}\n\n// update computes the CRC-32 of appending buf to c.\nfunc (c *crc) update(buf []byte) {\n\tcval := internal.ReverseUint32(c.val)\n\tfor len(buf) > 0 {\n\t\tn := len(buf)\n\t\tif n > len(c.buf) {\n\t\t\tn = len(c.buf)\n\t\t}\n\t\tfor i, b := range buf[:n] {\n\t\t\tc.buf[i] = internal.ReverseLUT[b]\n\t\t}\n\t\tcval = crc32.Update(cval, crc32.IEEETable, c.buf[:n])\n\t\tbuf = buf[n:]\n\t}\n\tc.val = internal.ReverseUint32(cval)\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/fuzz_off.go",
    "content": "// Copyright 2016, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// +build !gofuzz\n\n// This file exists to suppress fuzzing details from release builds.\n\npackage bzip2\n\ntype fuzzReader struct{}\n\nfunc (*fuzzReader) updateChecksum(int64, uint32) {}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/fuzz_on.go",
    "content": "// Copyright 2016, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// +build gofuzz\n\n// This file exists to export internal implementation details for fuzz testing.\n\npackage bzip2\n\nfunc ForwardBWT(buf []byte) (ptr int) {\n\tvar bwt burrowsWheelerTransform\n\treturn bwt.Encode(buf)\n}\n\nfunc ReverseBWT(buf []byte, ptr int) {\n\tvar bwt burrowsWheelerTransform\n\tbwt.Decode(buf, ptr)\n}\n\ntype fuzzReader struct {\n\tChecksums Checksums\n}\n\n// updateChecksum updates Checksums.\n//\n// If a valid pos is provided, it appends the (pos, val) pair to the slice.\n// Otherwise, it will update the last record with the new value.\nfunc (fr *fuzzReader) updateChecksum(pos int64, val uint32) {\n\tif pos >= 0 {\n\t\tfr.Checksums = append(fr.Checksums, Checksum{pos, val})\n\t} else {\n\t\tfr.Checksums[len(fr.Checksums)-1].Value = val\n\t}\n}\n\ntype Checksum struct {\n\tOffset int64  // Bit offset of the checksum\n\tValue  uint32 // Checksum value\n}\n\ntype Checksums []Checksum\n\n// Apply overwrites all checksum fields in d with the ones in cs.\nfunc (cs Checksums) Apply(d []byte) []byte {\n\td = append([]byte(nil), d...)\n\tfor _, c := range cs {\n\t\tsetU32(d, c.Offset, c.Value)\n\t}\n\treturn d\n}\n\nfunc setU32(d []byte, pos int64, val uint32) {\n\tfor i := uint(0); i < 32; i++ {\n\t\tbpos := uint64(pos) + uint64(i)\n\t\td[bpos/8] &= ^byte(1 << (7 - bpos%8))\n\t\td[bpos/8] |= byte(val>>(31-i)) << (7 - bpos%8)\n\t}\n}\n\n// Verify checks that all checksum fields in d matches those in cs.\nfunc (cs Checksums) Verify(d []byte) bool {\n\tfor _, c := range cs {\n\t\tif getU32(d, c.Offset) != c.Value {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc getU32(d []byte, pos int64) (val uint32) {\n\tfor i := uint(0); i < 32; i++ {\n\t\tbpos := uint64(pos) + uint64(i)\n\t\tval |= (uint32(d[bpos/8] >> (7 - bpos%8))) << (31 - i)\n\t}\n\treturn val\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/internal/sais/common.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Package sais implements a linear time suffix array algorithm.\npackage sais\n\n//go:generate go run sais_gen.go byte sais_byte.go\n//go:generate go run sais_gen.go int sais_int.go\n\n// This package ports the C sais implementation by Yuta Mori. The ports are\n// located in sais_byte.go and sais_int.go, which are identical to each other\n// except for the types. Since Go does not support generics, we use generators to\n// create the two files.\n//\n// References:\n//\thttps://sites.google.com/site/yuta256/sais\n//\thttps://www.researchgate.net/publication/221313676_Linear_Time_Suffix_Array_Construction_Using_D-Critical_Substrings\n//\thttps://www.researchgate.net/publication/224176324_Two_Efficient_Algorithms_for_Linear_Time_Suffix_Array_Construction\n\n// ComputeSA computes the suffix array of t and places the result in sa.\n// Both t and sa must be the same length.\nfunc ComputeSA(t []byte, sa []int) {\n\tif len(sa) != len(t) {\n\t\tpanic(\"mismatching sizes\")\n\t}\n\tcomputeSA_byte(t, sa, 0, len(t), 256)\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/internal/sais/sais_byte.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Code generated by sais_gen.go. DO NOT EDIT.\n\n// ====================================================\n// Copyright (c) 2008-2010 Yuta Mori All Rights Reserved.\n//\n// Permission is hereby granted, free of charge, to any person\n// obtaining a copy of this software and associated documentation\n// files (the \"Software\"), to deal in the Software without\n// restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following\n// conditions:\n//\n// The above copyright notice and this permission notice shall be\n// included in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n// OTHER DEALINGS IN THE SOFTWARE.\n// ====================================================\n\npackage sais\n\nfunc getCounts_byte(T []byte, C []int, n, k int) {\n\tvar i int\n\tfor i = 0; i < k; i++ {\n\t\tC[i] = 0\n\t}\n\tfor i = 0; i < n; i++ {\n\t\tC[T[i]]++\n\t}\n}\n\nfunc getBuckets_byte(C, B []int, k int, end bool) {\n\tvar i, sum int\n\tif end {\n\t\tfor i = 0; i < k; i++ {\n\t\t\tsum += C[i]\n\t\t\tB[i] = sum\n\t\t}\n\t} else {\n\t\tfor i = 0; i < k; i++ {\n\t\t\tsum += C[i]\n\t\t\tB[i] = sum - C[i]\n\t\t}\n\t}\n}\n\nfunc sortLMS1_byte(T []byte, SA, C, B []int, n, k int) {\n\tvar b, i, j int\n\tvar c0, c1 int\n\n\t// Compute SAl.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_byte(T, C, n, k)\n\t}\n\tgetBuckets_byte(C, B, k, false) // Find starts of buckets\n\tj = n - 1\n\tc1 = int(T[j])\n\tb = B[c1]\n\tj--\n\tif int(T[j]) < c1 {\n\t\tSA[b] = ^j\n\t} else {\n\t\tSA[b] = j\n\t}\n\tb++\n\tfor i = 0; i < n; i++ {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tif int(T[j]) < c1 {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tb++\n\t\t\tSA[i] = 0\n\t\t} else if j < 0 {\n\t\t\tSA[i] = ^j\n\t\t}\n\t}\n\n\t// Compute SAs.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_byte(T, C, n, k)\n\t}\n\tgetBuckets_byte(C, B, k, true) // Find ends of buckets\n\tc1 = 0\n\tb = B[c1]\n\tfor i = n - 1; i >= 0; i-- {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tb--\n\t\t\tif int(T[j]) > c1 {\n\t\t\t\tSA[b] = ^(j + 1)\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tSA[i] = 0\n\t\t}\n\t}\n}\n\nfunc postProcLMS1_byte(T []byte, SA []int, n, m int) int {\n\tvar i, j, p, q, plen, qlen, name int\n\tvar c0, c1 int\n\tvar diff bool\n\n\t// Compact all the sorted substrings into the first m items of SA.\n\t// 2*m must be not larger than n (provable).\n\tfor i = 0; SA[i] < 0; i++ {\n\t\tSA[i] = ^SA[i]\n\t}\n\tif i < m {\n\t\tfor j, i = i, i+1; ; i++ {\n\t\t\tif p = SA[i]; p < 0 {\n\t\t\t\tSA[j] = ^p\n\t\t\t\tj++\n\t\t\t\tSA[i] = 0\n\t\t\t\tif j == m {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Store the length of all substrings.\n\ti = n - 1\n\tj = n - 1\n\tc0 = int(T[n-1])\n\tfor {\n\t\tc1 = c0\n\t\tif i--; i < 0 {\n\t\t\tbreak\n\t\t}\n\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\tbreak\n\t\t}\n\t}\n\tfor i >= 0 {\n\t\tfor {\n\t\t\tc1 = c0\n\t\t\tif i--; i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c0 = int(T[i]); c0 > c1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif i >= 0 {\n\t\t\tSA[m+((i+1)>>1)] = j - i\n\t\t\tj = i + 1\n\t\t\tfor {\n\t\t\t\tc1 = c0\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Find the lexicographic names of all substrings.\n\tname = 0\n\tqlen = 0\n\tfor i, q = 0, n; i < m; i++ {\n\t\tp = SA[i]\n\t\tplen = SA[m+(p>>1)]\n\t\tdiff = true\n\t\tif (plen == qlen) && ((q + plen) < n) {\n\t\t\tfor j = 0; (j < plen) && (T[p+j] == T[q+j]); j++ {\n\t\t\t}\n\t\t\tif j == plen {\n\t\t\t\tdiff = false\n\t\t\t}\n\t\t}\n\t\tif diff {\n\t\t\tname++\n\t\t\tq = p\n\t\t\tqlen = plen\n\t\t}\n\t\tSA[m+(p>>1)] = name\n\t}\n\treturn name\n}\n\nfunc sortLMS2_byte(T []byte, SA, C, B, D []int, n, k int) {\n\tvar b, i, j, t, d int\n\tvar c0, c1 int\n\n\t// Compute SAl.\n\tgetBuckets_byte(C, B, k, false) // Find starts of buckets\n\tj = n - 1\n\tc1 = int(T[j])\n\tb = B[c1]\n\tj--\n\tif int(T[j]) < c1 {\n\t\tt = 1\n\t} else {\n\t\tt = 0\n\t}\n\tj += n\n\tif t&1 > 0 {\n\t\tSA[b] = ^j\n\t} else {\n\t\tSA[b] = j\n\t}\n\tb++\n\tfor i, d = 0, 0; i < n; i++ {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif n <= j {\n\t\t\t\td += 1\n\t\t\t\tj -= n\n\t\t\t}\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tt = int(c0) << 1\n\t\t\tif int(T[j]) < c1 {\n\t\t\t\tt |= 1\n\t\t\t}\n\t\t\tif D[t] != d {\n\t\t\t\tj += n\n\t\t\t\tD[t] = d\n\t\t\t}\n\t\t\tif t&1 > 0 {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tb++\n\t\t\tSA[i] = 0\n\t\t} else if j < 0 {\n\t\t\tSA[i] = ^j\n\t\t}\n\t}\n\tfor i = n - 1; 0 <= i; i-- {\n\t\tif SA[i] > 0 {\n\t\t\tif SA[i] < n {\n\t\t\t\tSA[i] += n\n\t\t\t\tfor j = i - 1; SA[j] < n; j-- {\n\t\t\t\t}\n\t\t\t\tSA[j] -= n\n\t\t\t\ti = j\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compute SAs.\n\tgetBuckets_byte(C, B, k, true) // Find ends of buckets\n\tc1 = 0\n\tb = B[c1]\n\tfor i, d = n-1, d+1; i >= 0; i-- {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif n <= j {\n\t\t\t\td += 1\n\t\t\t\tj -= n\n\t\t\t}\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tt = int(c0) << 1\n\t\t\tif int(T[j]) > c1 {\n\t\t\t\tt |= 1\n\t\t\t}\n\t\t\tif D[t] != d {\n\t\t\t\tj += n\n\t\t\t\tD[t] = d\n\t\t\t}\n\t\t\tb--\n\t\t\tif t&1 > 0 {\n\t\t\t\tSA[b] = ^(j + 1)\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tSA[i] = 0\n\t\t}\n\t}\n}\n\nfunc postProcLMS2_byte(SA []int, n, m int) int {\n\tvar i, j, d, name int\n\n\t// Compact all the sorted LMS substrings into the first m items of SA.\n\tname = 0\n\tfor i = 0; SA[i] < 0; i++ {\n\t\tj = ^SA[i]\n\t\tif n <= j {\n\t\t\tname += 1\n\t\t}\n\t\tSA[i] = j\n\t}\n\tif i < m {\n\t\tfor d, i = i, i+1; ; i++ {\n\t\t\tif j = SA[i]; j < 0 {\n\t\t\t\tj = ^j\n\t\t\t\tif n <= j {\n\t\t\t\t\tname += 1\n\t\t\t\t}\n\t\t\t\tSA[d] = j\n\t\t\t\td++\n\t\t\t\tSA[i] = 0\n\t\t\t\tif d == m {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif name < m {\n\t\t// Store the lexicographic names.\n\t\tfor i, d = m-1, name+1; 0 <= i; i-- {\n\t\t\tif j = SA[i]; n <= j {\n\t\t\t\tj -= n\n\t\t\t\td--\n\t\t\t}\n\t\t\tSA[m+(j>>1)] = d\n\t\t}\n\t} else {\n\t\t// Unset flags.\n\t\tfor i = 0; i < m; i++ {\n\t\t\tif j = SA[i]; n <= j {\n\t\t\t\tj -= n\n\t\t\t\tSA[i] = j\n\t\t\t}\n\t\t}\n\t}\n\treturn name\n}\n\nfunc induceSA_byte(T []byte, SA, C, B []int, n, k int) {\n\tvar b, i, j int\n\tvar c0, c1 int\n\n\t// Compute SAl.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_byte(T, C, n, k)\n\t}\n\tgetBuckets_byte(C, B, k, false) // Find starts of buckets\n\tj = n - 1\n\tc1 = int(T[j])\n\tb = B[c1]\n\tif j > 0 && int(T[j-1]) < c1 {\n\t\tSA[b] = ^j\n\t} else {\n\t\tSA[b] = j\n\t}\n\tb++\n\tfor i = 0; i < n; i++ {\n\t\tj = SA[i]\n\t\tSA[i] = ^j\n\t\tif j > 0 {\n\t\t\tj--\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tif j > 0 && int(T[j-1]) < c1 {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tb++\n\t\t}\n\t}\n\n\t// Compute SAs.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_byte(T, C, n, k)\n\t}\n\tgetBuckets_byte(C, B, k, true) // Find ends of buckets\n\tc1 = 0\n\tb = B[c1]\n\tfor i = n - 1; i >= 0; i-- {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tj--\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tb--\n\t\t\tif (j == 0) || (int(T[j-1]) > c1) {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t} else {\n\t\t\tSA[i] = ^j\n\t\t}\n\t}\n}\n\nfunc computeSA_byte(T []byte, SA []int, fs, n, k int) {\n\tconst (\n\t\tminBucketSize = 512\n\t\tsortLMS2Limit = 0x3fffffff\n\t)\n\n\tvar C, B, D, RA []int\n\tvar bo int // Offset of B relative to SA\n\tvar b, i, j, m, p, q, name, newfs int\n\tvar c0, c1 int\n\tvar flags uint\n\n\tif k <= minBucketSize {\n\t\tC = make([]int, k)\n\t\tif k <= fs {\n\t\t\tbo = n + fs - k\n\t\t\tB = SA[bo:]\n\t\t\tflags = 1\n\t\t} else {\n\t\t\tB = make([]int, k)\n\t\t\tflags = 3\n\t\t}\n\t} else if k <= fs {\n\t\tC = SA[n+fs-k:]\n\t\tif k <= fs-k {\n\t\t\tbo = n + fs - 2*k\n\t\t\tB = SA[bo:]\n\t\t\tflags = 0\n\t\t} else if k <= 4*minBucketSize {\n\t\t\tB = make([]int, k)\n\t\t\tflags = 2\n\t\t} else {\n\t\t\tB = C\n\t\t\tflags = 8\n\t\t}\n\t} else {\n\t\tC = make([]int, k)\n\t\tB = C\n\t\tflags = 4 | 8\n\t}\n\tif n <= sortLMS2Limit && 2 <= (n/k) {\n\t\tif flags&1 > 0 {\n\t\t\tif 2*k <= fs-k {\n\t\t\t\tflags |= 32\n\t\t\t} else {\n\t\t\t\tflags |= 16\n\t\t\t}\n\t\t} else if flags == 0 && 2*k <= (fs-2*k) {\n\t\t\tflags |= 32\n\t\t}\n\t}\n\n\t// Stage 1: Reduce the problem by at least 1/2.\n\t// Sort all the LMS-substrings.\n\tgetCounts_byte(T, C, n, k)\n\tgetBuckets_byte(C, B, k, true) // Find ends of buckets\n\tfor i = 0; i < n; i++ {\n\t\tSA[i] = 0\n\t}\n\tb = -1\n\ti = n - 1\n\tj = n\n\tm = 0\n\tc0 = int(T[n-1])\n\tfor {\n\t\tc1 = c0\n\t\tif i--; i < 0 {\n\t\t\tbreak\n\t\t}\n\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\tbreak\n\t\t}\n\t}\n\tfor i >= 0 {\n\t\tfor {\n\t\t\tc1 = c0\n\t\t\tif i--; i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c0 = int(T[i]); c0 > c1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif i >= 0 {\n\t\t\tif b >= 0 {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tB[c1]--\n\t\t\tb = B[c1]\n\t\t\tj = i\n\t\t\tm++\n\t\t\tfor {\n\t\t\t\tc1 = c0\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif m > 1 {\n\t\tif flags&(16|32) > 0 {\n\t\t\tif flags&16 > 0 {\n\t\t\t\tD = make([]int, 2*k)\n\t\t\t} else {\n\t\t\t\tD = SA[bo-2*k:]\n\t\t\t}\n\t\t\tB[T[j+1]]++\n\t\t\tfor i, j = 0, 0; i < k; i++ {\n\t\t\t\tj += C[i]\n\t\t\t\tif B[i] != j {\n\t\t\t\t\tSA[B[i]] += n\n\t\t\t\t}\n\t\t\t\tD[i] = 0\n\t\t\t\tD[i+k] = 0\n\t\t\t}\n\t\t\tsortLMS2_byte(T, SA, C, B, D, n, k)\n\t\t\tname = postProcLMS2_byte(SA, n, m)\n\t\t} else {\n\t\t\tsortLMS1_byte(T, SA, C, B, n, k)\n\t\t\tname = postProcLMS1_byte(T, SA, n, m)\n\t\t}\n\t} else if m == 1 {\n\t\tSA[b] = j + 1\n\t\tname = 1\n\t} else {\n\t\tname = 0\n\t}\n\n\t// Stage 2: Solve the reduced problem.\n\t// Recurse if names are not yet unique.\n\tif name < m {\n\t\tnewfs = n + fs - 2*m\n\t\tif flags&(1|4|8) == 0 {\n\t\t\tif k+name <= newfs {\n\t\t\t\tnewfs -= k\n\t\t\t} else {\n\t\t\t\tflags |= 8\n\t\t\t}\n\t\t}\n\t\tRA = SA[m+newfs:]\n\t\tfor i, j = m+(n>>1)-1, m-1; m <= i; i-- {\n\t\t\tif SA[i] != 0 {\n\t\t\t\tRA[j] = SA[i] - 1\n\t\t\t\tj--\n\t\t\t}\n\t\t}\n\t\tcomputeSA_int(RA, SA, newfs, m, name)\n\n\t\ti = n - 1\n\t\tj = m - 1\n\t\tc0 = int(T[n-1])\n\t\tfor {\n\t\t\tc1 = c0\n\t\t\tif i--; i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfor i >= 0 {\n\t\t\tfor {\n\t\t\t\tc1 = c0\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif c0 = int(T[i]); c0 > c1 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif i >= 0 {\n\t\t\t\tRA[j] = i + 1\n\t\t\t\tj--\n\t\t\t\tfor {\n\t\t\t\t\tc1 = c0\n\t\t\t\t\tif i--; i < 0 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor i = 0; i < m; i++ {\n\t\t\tSA[i] = RA[SA[i]]\n\t\t}\n\t\tif flags&4 > 0 {\n\t\t\tB = make([]int, k)\n\t\t\tC = B\n\t\t}\n\t\tif flags&2 > 0 {\n\t\t\tB = make([]int, k)\n\t\t}\n\t}\n\n\t// Stage 3: Induce the result for the original problem.\n\tif flags&8 > 0 {\n\t\tgetCounts_byte(T, C, n, k)\n\t}\n\t// Put all left-most S characters into their buckets.\n\tif m > 1 {\n\t\tgetBuckets_byte(C, B, k, true) // Find ends of buckets\n\t\ti = m - 1\n\t\tj = n\n\t\tp = SA[m-1]\n\t\tc1 = int(T[p])\n\t\tfor {\n\t\t\tc0 = c1\n\t\t\tq = B[c0]\n\t\t\tfor q < j {\n\t\t\t\tj--\n\t\t\t\tSA[j] = 0\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tj--\n\t\t\t\tSA[j] = p\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tp = SA[i]\n\t\t\t\tif c1 = int(T[p]); c1 != c0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfor j > 0 {\n\t\t\tj--\n\t\t\tSA[j] = 0\n\t\t}\n\t}\n\tinduceSA_byte(T, SA, C, B, n, k)\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/internal/sais/sais_int.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Code generated by sais_gen.go. DO NOT EDIT.\n\n// ====================================================\n// Copyright (c) 2008-2010 Yuta Mori All Rights Reserved.\n//\n// Permission is hereby granted, free of charge, to any person\n// obtaining a copy of this software and associated documentation\n// files (the \"Software\"), to deal in the Software without\n// restriction, including without limitation the rights to use,\n// copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the\n// Software is furnished to do so, subject to the following\n// conditions:\n//\n// The above copyright notice and this permission notice shall be\n// included in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n// OTHER DEALINGS IN THE SOFTWARE.\n// ====================================================\n\npackage sais\n\nfunc getCounts_int(T []int, C []int, n, k int) {\n\tvar i int\n\tfor i = 0; i < k; i++ {\n\t\tC[i] = 0\n\t}\n\tfor i = 0; i < n; i++ {\n\t\tC[T[i]]++\n\t}\n}\n\nfunc getBuckets_int(C, B []int, k int, end bool) {\n\tvar i, sum int\n\tif end {\n\t\tfor i = 0; i < k; i++ {\n\t\t\tsum += C[i]\n\t\t\tB[i] = sum\n\t\t}\n\t} else {\n\t\tfor i = 0; i < k; i++ {\n\t\t\tsum += C[i]\n\t\t\tB[i] = sum - C[i]\n\t\t}\n\t}\n}\n\nfunc sortLMS1_int(T []int, SA, C, B []int, n, k int) {\n\tvar b, i, j int\n\tvar c0, c1 int\n\n\t// Compute SAl.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_int(T, C, n, k)\n\t}\n\tgetBuckets_int(C, B, k, false) // Find starts of buckets\n\tj = n - 1\n\tc1 = int(T[j])\n\tb = B[c1]\n\tj--\n\tif int(T[j]) < c1 {\n\t\tSA[b] = ^j\n\t} else {\n\t\tSA[b] = j\n\t}\n\tb++\n\tfor i = 0; i < n; i++ {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tif int(T[j]) < c1 {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tb++\n\t\t\tSA[i] = 0\n\t\t} else if j < 0 {\n\t\t\tSA[i] = ^j\n\t\t}\n\t}\n\n\t// Compute SAs.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_int(T, C, n, k)\n\t}\n\tgetBuckets_int(C, B, k, true) // Find ends of buckets\n\tc1 = 0\n\tb = B[c1]\n\tfor i = n - 1; i >= 0; i-- {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tb--\n\t\t\tif int(T[j]) > c1 {\n\t\t\t\tSA[b] = ^(j + 1)\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tSA[i] = 0\n\t\t}\n\t}\n}\n\nfunc postProcLMS1_int(T []int, SA []int, n, m int) int {\n\tvar i, j, p, q, plen, qlen, name int\n\tvar c0, c1 int\n\tvar diff bool\n\n\t// Compact all the sorted substrings into the first m items of SA.\n\t// 2*m must be not larger than n (provable).\n\tfor i = 0; SA[i] < 0; i++ {\n\t\tSA[i] = ^SA[i]\n\t}\n\tif i < m {\n\t\tfor j, i = i, i+1; ; i++ {\n\t\t\tif p = SA[i]; p < 0 {\n\t\t\t\tSA[j] = ^p\n\t\t\t\tj++\n\t\t\t\tSA[i] = 0\n\t\t\t\tif j == m {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Store the length of all substrings.\n\ti = n - 1\n\tj = n - 1\n\tc0 = int(T[n-1])\n\tfor {\n\t\tc1 = c0\n\t\tif i--; i < 0 {\n\t\t\tbreak\n\t\t}\n\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\tbreak\n\t\t}\n\t}\n\tfor i >= 0 {\n\t\tfor {\n\t\t\tc1 = c0\n\t\t\tif i--; i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c0 = int(T[i]); c0 > c1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif i >= 0 {\n\t\t\tSA[m+((i+1)>>1)] = j - i\n\t\t\tj = i + 1\n\t\t\tfor {\n\t\t\t\tc1 = c0\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Find the lexicographic names of all substrings.\n\tname = 0\n\tqlen = 0\n\tfor i, q = 0, n; i < m; i++ {\n\t\tp = SA[i]\n\t\tplen = SA[m+(p>>1)]\n\t\tdiff = true\n\t\tif (plen == qlen) && ((q + plen) < n) {\n\t\t\tfor j = 0; (j < plen) && (T[p+j] == T[q+j]); j++ {\n\t\t\t}\n\t\t\tif j == plen {\n\t\t\t\tdiff = false\n\t\t\t}\n\t\t}\n\t\tif diff {\n\t\t\tname++\n\t\t\tq = p\n\t\t\tqlen = plen\n\t\t}\n\t\tSA[m+(p>>1)] = name\n\t}\n\treturn name\n}\n\nfunc sortLMS2_int(T []int, SA, C, B, D []int, n, k int) {\n\tvar b, i, j, t, d int\n\tvar c0, c1 int\n\n\t// Compute SAl.\n\tgetBuckets_int(C, B, k, false) // Find starts of buckets\n\tj = n - 1\n\tc1 = int(T[j])\n\tb = B[c1]\n\tj--\n\tif int(T[j]) < c1 {\n\t\tt = 1\n\t} else {\n\t\tt = 0\n\t}\n\tj += n\n\tif t&1 > 0 {\n\t\tSA[b] = ^j\n\t} else {\n\t\tSA[b] = j\n\t}\n\tb++\n\tfor i, d = 0, 0; i < n; i++ {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif n <= j {\n\t\t\t\td += 1\n\t\t\t\tj -= n\n\t\t\t}\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tt = int(c0) << 1\n\t\t\tif int(T[j]) < c1 {\n\t\t\t\tt |= 1\n\t\t\t}\n\t\t\tif D[t] != d {\n\t\t\t\tj += n\n\t\t\t\tD[t] = d\n\t\t\t}\n\t\t\tif t&1 > 0 {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tb++\n\t\t\tSA[i] = 0\n\t\t} else if j < 0 {\n\t\t\tSA[i] = ^j\n\t\t}\n\t}\n\tfor i = n - 1; 0 <= i; i-- {\n\t\tif SA[i] > 0 {\n\t\t\tif SA[i] < n {\n\t\t\t\tSA[i] += n\n\t\t\t\tfor j = i - 1; SA[j] < n; j-- {\n\t\t\t\t}\n\t\t\t\tSA[j] -= n\n\t\t\t\ti = j\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compute SAs.\n\tgetBuckets_int(C, B, k, true) // Find ends of buckets\n\tc1 = 0\n\tb = B[c1]\n\tfor i, d = n-1, d+1; i >= 0; i-- {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tif n <= j {\n\t\t\t\td += 1\n\t\t\t\tj -= n\n\t\t\t}\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tj--\n\t\t\tt = int(c0) << 1\n\t\t\tif int(T[j]) > c1 {\n\t\t\t\tt |= 1\n\t\t\t}\n\t\t\tif D[t] != d {\n\t\t\t\tj += n\n\t\t\t\tD[t] = d\n\t\t\t}\n\t\t\tb--\n\t\t\tif t&1 > 0 {\n\t\t\t\tSA[b] = ^(j + 1)\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tSA[i] = 0\n\t\t}\n\t}\n}\n\nfunc postProcLMS2_int(SA []int, n, m int) int {\n\tvar i, j, d, name int\n\n\t// Compact all the sorted LMS substrings into the first m items of SA.\n\tname = 0\n\tfor i = 0; SA[i] < 0; i++ {\n\t\tj = ^SA[i]\n\t\tif n <= j {\n\t\t\tname += 1\n\t\t}\n\t\tSA[i] = j\n\t}\n\tif i < m {\n\t\tfor d, i = i, i+1; ; i++ {\n\t\t\tif j = SA[i]; j < 0 {\n\t\t\t\tj = ^j\n\t\t\t\tif n <= j {\n\t\t\t\t\tname += 1\n\t\t\t\t}\n\t\t\t\tSA[d] = j\n\t\t\t\td++\n\t\t\t\tSA[i] = 0\n\t\t\t\tif d == m {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif name < m {\n\t\t// Store the lexicographic names.\n\t\tfor i, d = m-1, name+1; 0 <= i; i-- {\n\t\t\tif j = SA[i]; n <= j {\n\t\t\t\tj -= n\n\t\t\t\td--\n\t\t\t}\n\t\t\tSA[m+(j>>1)] = d\n\t\t}\n\t} else {\n\t\t// Unset flags.\n\t\tfor i = 0; i < m; i++ {\n\t\t\tif j = SA[i]; n <= j {\n\t\t\t\tj -= n\n\t\t\t\tSA[i] = j\n\t\t\t}\n\t\t}\n\t}\n\treturn name\n}\n\nfunc induceSA_int(T []int, SA, C, B []int, n, k int) {\n\tvar b, i, j int\n\tvar c0, c1 int\n\n\t// Compute SAl.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_int(T, C, n, k)\n\t}\n\tgetBuckets_int(C, B, k, false) // Find starts of buckets\n\tj = n - 1\n\tc1 = int(T[j])\n\tb = B[c1]\n\tif j > 0 && int(T[j-1]) < c1 {\n\t\tSA[b] = ^j\n\t} else {\n\t\tSA[b] = j\n\t}\n\tb++\n\tfor i = 0; i < n; i++ {\n\t\tj = SA[i]\n\t\tSA[i] = ^j\n\t\tif j > 0 {\n\t\t\tj--\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tif j > 0 && int(T[j-1]) < c1 {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tb++\n\t\t}\n\t}\n\n\t// Compute SAs.\n\tif &C[0] == &B[0] {\n\t\tgetCounts_int(T, C, n, k)\n\t}\n\tgetBuckets_int(C, B, k, true) // Find ends of buckets\n\tc1 = 0\n\tb = B[c1]\n\tfor i = n - 1; i >= 0; i-- {\n\t\tif j = SA[i]; j > 0 {\n\t\t\tj--\n\t\t\tif c0 = int(T[j]); c0 != c1 {\n\t\t\t\tB[c1] = b\n\t\t\t\tc1 = c0\n\t\t\t\tb = B[c1]\n\t\t\t}\n\t\t\tb--\n\t\t\tif (j == 0) || (int(T[j-1]) > c1) {\n\t\t\t\tSA[b] = ^j\n\t\t\t} else {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t} else {\n\t\t\tSA[i] = ^j\n\t\t}\n\t}\n}\n\nfunc computeSA_int(T []int, SA []int, fs, n, k int) {\n\tconst (\n\t\tminBucketSize = 512\n\t\tsortLMS2Limit = 0x3fffffff\n\t)\n\n\tvar C, B, D, RA []int\n\tvar bo int // Offset of B relative to SA\n\tvar b, i, j, m, p, q, name, newfs int\n\tvar c0, c1 int\n\tvar flags uint\n\n\tif k <= minBucketSize {\n\t\tC = make([]int, k)\n\t\tif k <= fs {\n\t\t\tbo = n + fs - k\n\t\t\tB = SA[bo:]\n\t\t\tflags = 1\n\t\t} else {\n\t\t\tB = make([]int, k)\n\t\t\tflags = 3\n\t\t}\n\t} else if k <= fs {\n\t\tC = SA[n+fs-k:]\n\t\tif k <= fs-k {\n\t\t\tbo = n + fs - 2*k\n\t\t\tB = SA[bo:]\n\t\t\tflags = 0\n\t\t} else if k <= 4*minBucketSize {\n\t\t\tB = make([]int, k)\n\t\t\tflags = 2\n\t\t} else {\n\t\t\tB = C\n\t\t\tflags = 8\n\t\t}\n\t} else {\n\t\tC = make([]int, k)\n\t\tB = C\n\t\tflags = 4 | 8\n\t}\n\tif n <= sortLMS2Limit && 2 <= (n/k) {\n\t\tif flags&1 > 0 {\n\t\t\tif 2*k <= fs-k {\n\t\t\t\tflags |= 32\n\t\t\t} else {\n\t\t\t\tflags |= 16\n\t\t\t}\n\t\t} else if flags == 0 && 2*k <= (fs-2*k) {\n\t\t\tflags |= 32\n\t\t}\n\t}\n\n\t// Stage 1: Reduce the problem by at least 1/2.\n\t// Sort all the LMS-substrings.\n\tgetCounts_int(T, C, n, k)\n\tgetBuckets_int(C, B, k, true) // Find ends of buckets\n\tfor i = 0; i < n; i++ {\n\t\tSA[i] = 0\n\t}\n\tb = -1\n\ti = n - 1\n\tj = n\n\tm = 0\n\tc0 = int(T[n-1])\n\tfor {\n\t\tc1 = c0\n\t\tif i--; i < 0 {\n\t\t\tbreak\n\t\t}\n\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\tbreak\n\t\t}\n\t}\n\tfor i >= 0 {\n\t\tfor {\n\t\t\tc1 = c0\n\t\t\tif i--; i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c0 = int(T[i]); c0 > c1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif i >= 0 {\n\t\t\tif b >= 0 {\n\t\t\t\tSA[b] = j\n\t\t\t}\n\t\t\tB[c1]--\n\t\t\tb = B[c1]\n\t\t\tj = i\n\t\t\tm++\n\t\t\tfor {\n\t\t\t\tc1 = c0\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif m > 1 {\n\t\tif flags&(16|32) > 0 {\n\t\t\tif flags&16 > 0 {\n\t\t\t\tD = make([]int, 2*k)\n\t\t\t} else {\n\t\t\t\tD = SA[bo-2*k:]\n\t\t\t}\n\t\t\tB[T[j+1]]++\n\t\t\tfor i, j = 0, 0; i < k; i++ {\n\t\t\t\tj += C[i]\n\t\t\t\tif B[i] != j {\n\t\t\t\t\tSA[B[i]] += n\n\t\t\t\t}\n\t\t\t\tD[i] = 0\n\t\t\t\tD[i+k] = 0\n\t\t\t}\n\t\t\tsortLMS2_int(T, SA, C, B, D, n, k)\n\t\t\tname = postProcLMS2_int(SA, n, m)\n\t\t} else {\n\t\t\tsortLMS1_int(T, SA, C, B, n, k)\n\t\t\tname = postProcLMS1_int(T, SA, n, m)\n\t\t}\n\t} else if m == 1 {\n\t\tSA[b] = j + 1\n\t\tname = 1\n\t} else {\n\t\tname = 0\n\t}\n\n\t// Stage 2: Solve the reduced problem.\n\t// Recurse if names are not yet unique.\n\tif name < m {\n\t\tnewfs = n + fs - 2*m\n\t\tif flags&(1|4|8) == 0 {\n\t\t\tif k+name <= newfs {\n\t\t\t\tnewfs -= k\n\t\t\t} else {\n\t\t\t\tflags |= 8\n\t\t\t}\n\t\t}\n\t\tRA = SA[m+newfs:]\n\t\tfor i, j = m+(n>>1)-1, m-1; m <= i; i-- {\n\t\t\tif SA[i] != 0 {\n\t\t\t\tRA[j] = SA[i] - 1\n\t\t\t\tj--\n\t\t\t}\n\t\t}\n\t\tcomputeSA_int(RA, SA, newfs, m, name)\n\n\t\ti = n - 1\n\t\tj = m - 1\n\t\tc0 = int(T[n-1])\n\t\tfor {\n\t\t\tc1 = c0\n\t\t\tif i--; i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfor i >= 0 {\n\t\t\tfor {\n\t\t\t\tc1 = c0\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif c0 = int(T[i]); c0 > c1 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif i >= 0 {\n\t\t\t\tRA[j] = i + 1\n\t\t\t\tj--\n\t\t\t\tfor {\n\t\t\t\t\tc1 = c0\n\t\t\t\t\tif i--; i < 0 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif c0 = int(T[i]); c0 < c1 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor i = 0; i < m; i++ {\n\t\t\tSA[i] = RA[SA[i]]\n\t\t}\n\t\tif flags&4 > 0 {\n\t\t\tB = make([]int, k)\n\t\t\tC = B\n\t\t}\n\t\tif flags&2 > 0 {\n\t\t\tB = make([]int, k)\n\t\t}\n\t}\n\n\t// Stage 3: Induce the result for the original problem.\n\tif flags&8 > 0 {\n\t\tgetCounts_int(T, C, n, k)\n\t}\n\t// Put all left-most S characters into their buckets.\n\tif m > 1 {\n\t\tgetBuckets_int(C, B, k, true) // Find ends of buckets\n\t\ti = m - 1\n\t\tj = n\n\t\tp = SA[m-1]\n\t\tc1 = int(T[p])\n\t\tfor {\n\t\t\tc0 = c1\n\t\t\tq = B[c0]\n\t\t\tfor q < j {\n\t\t\t\tj--\n\t\t\t\tSA[j] = 0\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tj--\n\t\t\t\tSA[j] = p\n\t\t\t\tif i--; i < 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tp = SA[i]\n\t\t\t\tif c1 = int(T[p]); c1 != c0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif i < 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tfor j > 0 {\n\t\t\tj--\n\t\t\tSA[j] = 0\n\t\t}\n\t}\n\tinduceSA_int(T, SA, C, B, n, k)\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/mtf_rle2.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage bzip2\n\nimport \"github.com/dsnet/compress/internal/errors\"\n\n// moveToFront implements both the MTF and RLE stages of bzip2 at the same time.\n// Any runs of zeros in the encoded output will be replaced by a sequence of\n// RUNA and RUNB symbols are encode the length of the run.\n//\n// The RLE encoding used can actually be encoded to and decoded from using\n// normal two's complement arithmetic. The methodology for doing so is below.\n//\n// Assuming the following:\n//\tnum: The value being encoded by RLE encoding.\n//\trun: A sequence of RUNA and RUNB symbols represented as a binary integer,\n//\twhere RUNA is the 0 bit, RUNB is the 1 bit, and least-significant RUN\n//\tsymbols are at the least-significant bit positions.\n//\tcnt: The number of RUNA and RUNB symbols.\n//\n// Then the RLE encoding used by bzip2 has this mathematical property:\n//\tnum+1 == (1<<cnt) | run\ntype moveToFront struct {\n\tdictBuf [256]uint8\n\tdictLen int\n\n\tvals    []byte\n\tsyms    []uint16\n\tblkSize int\n}\n\nfunc (mtf *moveToFront) Init(dict []uint8, blkSize int) {\n\tif len(dict) > len(mtf.dictBuf) {\n\t\tpanicf(errors.Internal, \"alphabet too large\")\n\t}\n\tcopy(mtf.dictBuf[:], dict)\n\tmtf.dictLen = len(dict)\n\tmtf.blkSize = blkSize\n}\n\nfunc (mtf *moveToFront) Encode(vals []byte) (syms []uint16) {\n\tdict := mtf.dictBuf[:mtf.dictLen]\n\tsyms = mtf.syms[:0]\n\n\tif len(vals) > mtf.blkSize {\n\t\tpanicf(errors.Internal, \"exceeded block size\")\n\t}\n\n\tvar lastNum uint32\n\tfor _, val := range vals {\n\t\t// Normal move-to-front transform.\n\t\tvar idx uint8 // Reverse lookup idx in dict\n\t\tfor di, dv := range dict {\n\t\t\tif dv == val {\n\t\t\t\tidx = uint8(di)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tcopy(dict[1:], dict[:idx])\n\t\tdict[0] = val\n\n\t\t// Run-length encoding augmentation.\n\t\tif idx == 0 {\n\t\t\tlastNum++\n\t\t\tcontinue\n\t\t}\n\t\tif lastNum > 0 {\n\t\t\tfor rc := lastNum + 1; rc != 1; rc >>= 1 {\n\t\t\t\tsyms = append(syms, uint16(rc&1))\n\t\t\t}\n\t\t\tlastNum = 0\n\t\t}\n\t\tsyms = append(syms, uint16(idx)+1)\n\t}\n\tif lastNum > 0 {\n\t\tfor rc := lastNum + 1; rc != 1; rc >>= 1 {\n\t\t\tsyms = append(syms, uint16(rc&1))\n\t\t}\n\t}\n\tmtf.syms = syms\n\treturn syms\n}\n\nfunc (mtf *moveToFront) Decode(syms []uint16) (vals []byte) {\n\tdict := mtf.dictBuf[:mtf.dictLen]\n\tvals = mtf.vals[:0]\n\n\tvar lastCnt uint\n\tvar lastRun uint32\n\tfor _, sym := range syms {\n\t\t// Run-length encoding augmentation.\n\t\tif sym < 2 {\n\t\t\tlastRun |= uint32(sym) << lastCnt\n\t\t\tlastCnt++\n\t\t\tcontinue\n\t\t}\n\t\tif lastCnt > 0 {\n\t\t\tcnt := int((1<<lastCnt)|lastRun) - 1\n\t\t\tif len(vals)+cnt > mtf.blkSize || lastCnt > 24 {\n\t\t\t\tpanicf(errors.Corrupted, \"run-length decoding exceeded block size\")\n\t\t\t}\n\t\t\tfor i := cnt; i > 0; i-- {\n\t\t\t\tvals = append(vals, dict[0])\n\t\t\t}\n\t\t\tlastCnt, lastRun = 0, 0\n\t\t}\n\n\t\t// Normal move-to-front transform.\n\t\tval := dict[sym-1] // Forward lookup val in dict\n\t\tcopy(dict[1:], dict[:sym-1])\n\t\tdict[0] = val\n\n\t\tif len(vals) >= mtf.blkSize {\n\t\t\tpanicf(errors.Corrupted, \"run-length decoding exceeded block size\")\n\t\t}\n\t\tvals = append(vals, val)\n\t}\n\tif lastCnt > 0 {\n\t\tcnt := int((1<<lastCnt)|lastRun) - 1\n\t\tif len(vals)+cnt > mtf.blkSize || lastCnt > 24 {\n\t\t\tpanicf(errors.Corrupted, \"run-length decoding exceeded block size\")\n\t\t}\n\t\tfor i := cnt; i > 0; i-- {\n\t\t\tvals = append(vals, dict[0])\n\t\t}\n\t}\n\tmtf.vals = vals\n\treturn vals\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/prefix.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage bzip2\n\nimport (\n\t\"io\"\n\n\t\"github.com/dsnet/compress/internal\"\n\t\"github.com/dsnet/compress/internal/errors\"\n\t\"github.com/dsnet/compress/internal/prefix\"\n)\n\nconst (\n\tminNumTrees = 2\n\tmaxNumTrees = 6\n\n\tmaxPrefixBits = 20      // Maximum bit-width of a prefix code\n\tmaxNumSyms    = 256 + 2 // Maximum number of symbols in the alphabet\n\tnumBlockSyms  = 50      // Number of bytes in a block\n)\n\n// encSel and decSel are used to handle the prefix encoding for tree selectors.\n// The prefix encoding is as follows:\n//\n//\tCode         TreeIdx\n//\t0        <=> 0\n//\t10       <=> 1\n//\t110      <=> 2\n//\t1110     <=> 3\n//\t11110    <=> 4\n//\t111110   <=> 5\n//\t111111   <=> 6\tInvalid tree index, so should fail\n//\nvar encSel, decSel = func() (e prefix.Encoder, d prefix.Decoder) {\n\tvar selCodes [maxNumTrees + 1]prefix.PrefixCode\n\tfor i := range selCodes {\n\t\tselCodes[i] = prefix.PrefixCode{Sym: uint32(i), Len: uint32(i + 1)}\n\t}\n\tselCodes[maxNumTrees] = prefix.PrefixCode{Sym: maxNumTrees, Len: maxNumTrees}\n\tprefix.GeneratePrefixes(selCodes[:])\n\te.Init(selCodes[:])\n\td.Init(selCodes[:])\n\treturn\n}()\n\ntype prefixReader struct{ prefix.Reader }\n\nfunc (pr *prefixReader) Init(r io.Reader) {\n\tpr.Reader.Init(r, true)\n}\n\nfunc (pr *prefixReader) ReadBitsBE64(nb uint) uint64 {\n\tif nb <= 32 {\n\t\tv := uint32(pr.ReadBits(nb))\n\t\treturn uint64(internal.ReverseUint32N(v, nb))\n\t}\n\tv0 := internal.ReverseUint32(uint32(pr.ReadBits(32)))\n\tv1 := internal.ReverseUint32(uint32(pr.ReadBits(nb - 32)))\n\tv := uint64(v0)<<32 | uint64(v1)\n\treturn v >> (64 - nb)\n}\n\nfunc (pr *prefixReader) ReadPrefixCodes(codes []prefix.PrefixCodes, trees []prefix.Decoder) {\n\tfor i, pc := range codes {\n\t\tclen := int(pr.ReadBitsBE64(5))\n\t\tsum := 1 << maxPrefixBits\n\t\tfor sym := range pc {\n\t\t\tfor {\n\t\t\t\tif clen < 1 || clen > maxPrefixBits {\n\t\t\t\t\tpanicf(errors.Corrupted, \"invalid prefix bit-length: %d\", clen)\n\t\t\t\t}\n\n\t\t\t\tb, ok := pr.TryReadBits(1)\n\t\t\t\tif !ok {\n\t\t\t\t\tb = pr.ReadBits(1)\n\t\t\t\t}\n\t\t\t\tif b == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tb, ok = pr.TryReadBits(1)\n\t\t\t\tif !ok {\n\t\t\t\t\tb = pr.ReadBits(1)\n\t\t\t\t}\n\t\t\t\tclen -= int(b*2) - 1 // +1 or -1\n\t\t\t}\n\t\t\tpc[sym] = prefix.PrefixCode{Sym: uint32(sym), Len: uint32(clen)}\n\t\t\tsum -= (1 << maxPrefixBits) >> uint(clen)\n\t\t}\n\n\t\tif sum == 0 {\n\t\t\t// Fast path, but only handles complete trees.\n\t\t\tif err := prefix.GeneratePrefixes(pc); err != nil {\n\t\t\t\terrors.Panic(err) // Using complete trees; should never fail\n\t\t\t}\n\t\t} else {\n\t\t\t// Slow path, but handles anything.\n\t\t\tpc = handleDegenerateCodes(pc) // Never fails, but may fail later\n\t\t\tcodes[i] = pc\n\t\t}\n\t\ttrees[i].Init(pc)\n\t}\n}\n\ntype prefixWriter struct{ prefix.Writer }\n\nfunc (pw *prefixWriter) Init(w io.Writer) {\n\tpw.Writer.Init(w, true)\n}\n\nfunc (pw *prefixWriter) WriteBitsBE64(v uint64, nb uint) {\n\tif nb <= 32 {\n\t\tv := internal.ReverseUint32N(uint32(v), nb)\n\t\tpw.WriteBits(uint(v), nb)\n\t\treturn\n\t}\n\tv <<= (64 - nb)\n\tv0 := internal.ReverseUint32(uint32(v >> 32))\n\tv1 := internal.ReverseUint32(uint32(v))\n\tpw.WriteBits(uint(v0), 32)\n\tpw.WriteBits(uint(v1), nb-32)\n\treturn\n}\n\nfunc (pw *prefixWriter) WritePrefixCodes(codes []prefix.PrefixCodes, trees []prefix.Encoder) {\n\tfor i, pc := range codes {\n\t\tif err := prefix.GeneratePrefixes(pc); err != nil {\n\t\t\terrors.Panic(err) // Using complete trees; should never fail\n\t\t}\n\t\ttrees[i].Init(pc)\n\n\t\tclen := int(pc[0].Len)\n\t\tpw.WriteBitsBE64(uint64(clen), 5)\n\t\tfor _, c := range pc {\n\t\t\tfor int(c.Len) < clen {\n\t\t\t\tpw.WriteBits(3, 2) // 11\n\t\t\t\tclen--\n\t\t\t}\n\t\t\tfor int(c.Len) > clen {\n\t\t\t\tpw.WriteBits(1, 2) // 10\n\t\t\t\tclen++\n\t\t\t}\n\t\t\tpw.WriteBits(0, 1)\n\t\t}\n\t}\n}\n\n// handleDegenerateCodes converts a degenerate tree into a canonical tree.\n//\n// For example, when the input is an under-subscribed tree:\n//\tinput:  []PrefixCode{\n//\t\t{Sym: 0, Len: 3},\n//\t\t{Sym: 1, Len: 4},\n//\t\t{Sym: 2, Len: 3},\n//\t}\n//\toutput: []PrefixCode{\n//\t\t{Sym:   0, Len: 3, Val:  0}, //  000\n//\t\t{Sym:   1, Len: 4, Val:  2}, // 0010\n//\t\t{Sym:   2, Len: 3, Val:  4}, //  100\n//\t\t{Sym: 258, Len: 4, Val: 10}, // 1010\n//\t\t{Sym: 259, Len: 3, Val:  6}, //  110\n//\t\t{Sym: 260, Len: 1, Val:  1}, //    1\n//\t}\n//\n// For example, when the input is an over-subscribed tree:\n//\tinput:  []PrefixCode{\n//\t\t{Sym: 0, Len: 1},\n//\t\t{Sym: 1, Len: 3},\n//\t\t{Sym: 2, Len: 4},\n//\t\t{Sym: 3, Len: 3},\n//\t\t{Sym: 4, Len: 2},\n//\t}\n//\toutput: []PrefixCode{\n//\t\t{Sym: 0, Len: 1, Val: 0}, //   0\n//\t\t{Sym: 1, Len: 3, Val: 3}, // 011\n//\t\t{Sym: 3, Len: 3, Val: 7}, // 111\n//\t\t{Sym: 4, Len: 2, Val: 1}, //  01\n//\t}\nfunc handleDegenerateCodes(codes prefix.PrefixCodes) prefix.PrefixCodes {\n\t// Since there is no formal definition for the BZip2 format, there is no\n\t// specification that says that the code lengths must form a complete\n\t// prefix tree (IE: it is neither over-subscribed nor under-subscribed).\n\t// Thus, the original C implementation becomes the reference for how prefix\n\t// decoding is done in these edge cases. Unfortunately, the C version does\n\t// not error when an invalid tree is used, but rather allows decoding to\n\t// continue and only errors if some bit pattern happens to cause an error.\n\t// Thus, it is possible for an invalid tree to end up decoding an input\n\t// \"properly\" so long as invalid bit patterns are not present. In order to\n\t// replicate this non-specified behavior, we use a ported version of the\n\t// C code to generate the codes as a valid canonical tree by substituting\n\t// invalid nodes with invalid symbols.\n\t//\n\t// ====================================================\n\t// This program, \"bzip2\", the associated library \"libbzip2\", and all\n\t// documentation, are copyright (C) 1996-2010 Julian R Seward.  All\n\t// rights reserved.\n\t//\n\t// Redistribution and use in source and binary forms, with or without\n\t// modification, are permitted provided that the following conditions\n\t// are met:\n\t//\n\t// 1. Redistributions of source code must retain the above copyright\n\t//    notice, this list of conditions and the following disclaimer.\n\t//\n\t// 2. The origin of this software must not be misrepresented; you must\n\t//    not claim that you wrote the original software.  If you use this\n\t//    software in a product, an acknowledgment in the product\n\t//    documentation would be appreciated but is not required.\n\t//\n\t// 3. Altered source versions must be plainly marked as such, and must\n\t//    not be misrepresented as being the original software.\n\t//\n\t// 4. The name of the author may not be used to endorse or promote\n\t//    products derived from this software without specific prior written\n\t//    permission.\n\t//\n\t// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS\n\t// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n\t// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\t// ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY\n\t// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\t// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n\t// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n\t// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n\t// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n\t// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n\t// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\t//\n\t// Julian Seward, jseward@bzip.org\n\t// bzip2/libbzip2 version 1.0.6 of 6 September 2010\n\t// ====================================================\n\tvar (\n\t\tlimits [maxPrefixBits + 2]int32\n\t\tbases  [maxPrefixBits + 2]int32\n\t\tperms  [maxNumSyms]int32\n\n\t\tminLen = uint32(maxPrefixBits)\n\t\tmaxLen = uint32(0)\n\t)\n\n\tconst (\n\t\tstatusOkay = iota\n\t\tstatusInvalid\n\t\tstatusNeedBits\n\t\tstatusMaxBits\n\t)\n\n\t// createTables is the BZ2_hbCreateDecodeTables function from the C code.\n\tcreateTables := func(codes []prefix.PrefixCode) {\n\t\tfor _, c := range codes {\n\t\t\tif c.Len > maxLen {\n\t\t\t\tmaxLen = c.Len\n\t\t\t}\n\t\t\tif c.Len < minLen {\n\t\t\t\tminLen = c.Len\n\t\t\t}\n\t\t}\n\n\t\tvar pp int\n\t\tfor i := minLen; i <= maxLen; i++ {\n\t\t\tfor j, c := range codes {\n\t\t\t\tif c.Len == i {\n\t\t\t\t\tperms[pp] = int32(j)\n\t\t\t\t\tpp++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar vec int32\n\t\tfor _, c := range codes {\n\t\t\tbases[c.Len+1]++\n\t\t}\n\t\tfor i := 1; i < len(bases); i++ {\n\t\t\tbases[i] += bases[i-1]\n\t\t}\n\t\tfor i := minLen; i <= maxLen; i++ {\n\t\t\tvec += bases[i+1] - bases[i]\n\t\t\tlimits[i] = vec - 1\n\t\t\tvec <<= 1\n\t\t}\n\t\tfor i := minLen + 1; i <= maxLen; i++ {\n\t\t\tbases[i] = ((limits[i-1] + 1) << 1) - bases[i]\n\t\t}\n\t}\n\n\t// getSymbol is the GET_MTF_VAL macro from the C code.\n\tgetSymbol := func(c prefix.PrefixCode) (uint32, int) {\n\t\tv := internal.ReverseUint32(c.Val)\n\t\tn := c.Len\n\n\t\tzn := minLen\n\t\tif zn > n {\n\t\t\treturn 0, statusNeedBits\n\t\t}\n\t\tzvec := int32(v >> (32 - zn))\n\t\tv <<= zn\n\t\tfor {\n\t\t\tif zn > maxLen {\n\t\t\t\treturn 0, statusMaxBits\n\t\t\t}\n\t\t\tif zvec <= limits[zn] {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tzn++\n\t\t\tif zn > n {\n\t\t\t\treturn 0, statusNeedBits\n\t\t\t}\n\t\t\tzvec = (zvec << 1) | int32(v>>31)\n\t\t\tv <<= 1\n\t\t}\n\t\tif zvec-bases[zn] < 0 || zvec-bases[zn] >= maxNumSyms {\n\t\t\treturn 0, statusInvalid\n\t\t}\n\t\treturn uint32(perms[zvec-bases[zn]]), statusOkay\n\t}\n\n\t// Step 1: Create the prefix trees using the C algorithm.\n\tcreateTables(codes)\n\n\t// Step 2: Starting with the shortest bit pattern, explore the whole tree.\n\t// If tree is under-subscribed, the worst-case runtime is O(1<<maxLen).\n\t// If tree is over-subscribed, the worst-case runtime is O(maxNumSyms).\n\tvar pcodesArr [2 * maxNumSyms]prefix.PrefixCode\n\tpcodes := pcodesArr[:maxNumSyms]\n\tvar exploreCode func(prefix.PrefixCode) bool\n\texploreCode = func(c prefix.PrefixCode) (term bool) {\n\t\tsym, status := getSymbol(c)\n\t\tswitch status {\n\t\tcase statusOkay:\n\t\t\t// This code is valid, so insert it.\n\t\t\tc.Sym = sym\n\t\t\tpcodes[sym] = c\n\t\t\tterm = true\n\t\tcase statusInvalid:\n\t\t\t// This code is invalid, so insert an invalid symbol.\n\t\t\tc.Sym = uint32(len(pcodes))\n\t\t\tpcodes = append(pcodes, c)\n\t\t\tterm = true\n\t\tcase statusNeedBits:\n\t\t\t// This code is too short, so explore both children.\n\t\t\tc.Len++\n\t\t\tc0, c1 := c, c\n\t\t\tc1.Val |= 1 << (c.Len - 1)\n\n\t\t\tb0 := exploreCode(c0)\n\t\t\tb1 := exploreCode(c1)\n\t\t\tswitch {\n\t\t\tcase !b0 && b1:\n\t\t\t\tc0.Sym = uint32(len(pcodes))\n\t\t\t\tpcodes = append(pcodes, c0)\n\t\t\tcase !b1 && b0:\n\t\t\t\tc1.Sym = uint32(len(pcodes))\n\t\t\t\tpcodes = append(pcodes, c1)\n\t\t\t}\n\t\t\tterm = b0 || b1\n\t\tcase statusMaxBits:\n\t\t\t// This code is too long, so report it upstream.\n\t\t\tterm = false\n\t\t}\n\t\treturn term // Did this code terminate?\n\t}\n\texploreCode(prefix.PrefixCode{})\n\n\t// Step 3: Copy new sparse codes to old output codes.\n\tcodes = codes[:0]\n\tfor _, c := range pcodes {\n\t\tif c.Len > 0 {\n\t\t\tcodes = append(codes, c)\n\t\t}\n\t}\n\treturn codes\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/reader.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage bzip2\n\nimport (\n\t\"io\"\n\n\t\"github.com/dsnet/compress/internal\"\n\t\"github.com/dsnet/compress/internal/errors\"\n\t\"github.com/dsnet/compress/internal/prefix\"\n)\n\ntype Reader struct {\n\tInputOffset  int64 // Total number of bytes read from underlying io.Reader\n\tOutputOffset int64 // Total number of bytes emitted from Read\n\n\trd       prefixReader\n\terr      error\n\tlevel    int    // The current compression level\n\trdHdrFtr int    // Number of times we read the stream header and footer\n\tblkCRC   uint32 // CRC-32 IEEE of each block (as stored)\n\tendCRC   uint32 // Checksum of all blocks using bzip2's custom method\n\n\tcrc crc\n\tmtf moveToFront\n\tbwt burrowsWheelerTransform\n\trle runLengthEncoding\n\n\t// These fields are allocated with Reader and re-used later.\n\ttreeSels []uint8\n\tcodes2D  [maxNumTrees][maxNumSyms]prefix.PrefixCode\n\tcodes1D  [maxNumTrees]prefix.PrefixCodes\n\ttrees1D  [maxNumTrees]prefix.Decoder\n\tsyms     []uint16\n\n\tfuzzReader // Exported functionality when fuzz testing\n}\n\ntype ReaderConfig struct {\n\t_ struct{} // Blank field to prevent unkeyed struct literals\n}\n\nfunc NewReader(r io.Reader, conf *ReaderConfig) (*Reader, error) {\n\tzr := new(Reader)\n\tzr.Reset(r)\n\treturn zr, nil\n}\n\nfunc (zr *Reader) Reset(r io.Reader) error {\n\t*zr = Reader{\n\t\trd: zr.rd,\n\n\t\tmtf: zr.mtf,\n\t\tbwt: zr.bwt,\n\t\trle: zr.rle,\n\n\t\ttreeSels: zr.treeSels,\n\t\ttrees1D:  zr.trees1D,\n\t\tsyms:     zr.syms,\n\t}\n\tzr.rd.Init(r)\n\treturn nil\n}\n\nfunc (zr *Reader) Read(buf []byte) (int, error) {\n\tfor {\n\t\tcnt, err := zr.rle.Read(buf)\n\t\tif err != rleDone && zr.err == nil {\n\t\t\tzr.err = err\n\t\t}\n\t\tif cnt > 0 {\n\t\t\tzr.crc.update(buf[:cnt])\n\t\t\tzr.OutputOffset += int64(cnt)\n\t\t\treturn cnt, nil\n\t\t}\n\t\tif zr.err != nil || len(buf) == 0 {\n\t\t\treturn 0, zr.err\n\t\t}\n\n\t\t// Read the next chunk.\n\t\tzr.rd.Offset = zr.InputOffset\n\t\tfunc() {\n\t\t\tdefer errors.Recover(&zr.err)\n\t\t\tif zr.rdHdrFtr%2 == 0 {\n\t\t\t\t// Check if we are already at EOF.\n\t\t\t\tif err := zr.rd.PullBits(1); err != nil {\n\t\t\t\t\tif err == io.ErrUnexpectedEOF && zr.rdHdrFtr > 0 {\n\t\t\t\t\t\terr = io.EOF // EOF is okay if we read at least one stream\n\t\t\t\t\t}\n\t\t\t\t\terrors.Panic(err)\n\t\t\t\t}\n\n\t\t\t\t// Read stream header.\n\t\t\t\tif zr.rd.ReadBitsBE64(16) != hdrMagic {\n\t\t\t\t\tpanicf(errors.Corrupted, \"invalid stream magic\")\n\t\t\t\t}\n\t\t\t\tif ver := zr.rd.ReadBitsBE64(8); ver != 'h' {\n\t\t\t\t\tif ver == '0' {\n\t\t\t\t\t\tpanicf(errors.Deprecated, \"bzip1 format is not supported\")\n\t\t\t\t\t}\n\t\t\t\t\tpanicf(errors.Corrupted, \"invalid version: %q\", ver)\n\t\t\t\t}\n\t\t\t\tlvl := int(zr.rd.ReadBitsBE64(8)) - '0'\n\t\t\t\tif lvl < BestSpeed || lvl > BestCompression {\n\t\t\t\t\tpanicf(errors.Corrupted, \"invalid block size: %d\", lvl*blockSize)\n\t\t\t\t}\n\t\t\t\tzr.level = lvl\n\t\t\t\tzr.rdHdrFtr++\n\t\t\t} else {\n\t\t\t\t// Check and update the CRC.\n\t\t\t\tif internal.GoFuzz {\n\t\t\t\t\tzr.updateChecksum(-1, zr.crc.val) // Update with value\n\t\t\t\t\tzr.blkCRC = zr.crc.val            // Suppress CRC failures\n\t\t\t\t}\n\t\t\t\tif zr.blkCRC != zr.crc.val {\n\t\t\t\t\tpanicf(errors.Corrupted, \"mismatching block checksum\")\n\t\t\t\t}\n\t\t\t\tzr.endCRC = (zr.endCRC<<1 | zr.endCRC>>31) ^ zr.blkCRC\n\t\t\t}\n\t\t\tbuf := zr.decodeBlock()\n\t\t\tzr.rle.Init(buf)\n\t\t}()\n\t\tif zr.InputOffset, err = zr.rd.Flush(); zr.err == nil {\n\t\t\tzr.err = err\n\t\t}\n\t\tif zr.err != nil {\n\t\t\tzr.err = errWrap(zr.err, errors.Corrupted)\n\t\t\treturn 0, zr.err\n\t\t}\n\t}\n}\n\nfunc (zr *Reader) Close() error {\n\tif zr.err == io.EOF || zr.err == errClosed {\n\t\tzr.rle.Init(nil) // Make sure future reads fail\n\t\tzr.err = errClosed\n\t\treturn nil\n\t}\n\treturn zr.err // Return the persistent error\n}\n\nfunc (zr *Reader) decodeBlock() []byte {\n\tif magic := zr.rd.ReadBitsBE64(48); magic != blkMagic {\n\t\tif magic == endMagic {\n\t\t\tendCRC := uint32(zr.rd.ReadBitsBE64(32))\n\t\t\tif internal.GoFuzz {\n\t\t\t\tzr.updateChecksum(zr.rd.BitsRead()-32, zr.endCRC)\n\t\t\t\tendCRC = zr.endCRC // Suppress CRC failures\n\t\t\t}\n\t\t\tif zr.endCRC != endCRC {\n\t\t\t\tpanicf(errors.Corrupted, \"mismatching stream checksum\")\n\t\t\t}\n\t\t\tzr.endCRC = 0\n\t\t\tzr.rd.ReadPads()\n\t\t\tzr.rdHdrFtr++\n\t\t\treturn nil\n\t\t}\n\t\tpanicf(errors.Corrupted, \"invalid block or footer magic\")\n\t}\n\n\tzr.crc.val = 0\n\tzr.blkCRC = uint32(zr.rd.ReadBitsBE64(32))\n\tif internal.GoFuzz {\n\t\tzr.updateChecksum(zr.rd.BitsRead()-32, 0) // Record offset only\n\t}\n\tif zr.rd.ReadBitsBE64(1) != 0 {\n\t\tpanicf(errors.Deprecated, \"block randomization is not supported\")\n\t}\n\n\t// Read BWT related fields.\n\tptr := int(zr.rd.ReadBitsBE64(24)) // BWT origin pointer\n\n\t// Read MTF related fields.\n\tvar dictArr [256]uint8\n\tdict := dictArr[:0]\n\tbmapHi := uint16(zr.rd.ReadBits(16))\n\tfor i := 0; i < 256; i, bmapHi = i+16, bmapHi>>1 {\n\t\tif bmapHi&1 > 0 {\n\t\t\tbmapLo := uint16(zr.rd.ReadBits(16))\n\t\t\tfor j := 0; j < 16; j, bmapLo = j+1, bmapLo>>1 {\n\t\t\t\tif bmapLo&1 > 0 {\n\t\t\t\t\tdict = append(dict, uint8(i+j))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Step 1: Prefix encoding.\n\tsyms := zr.decodePrefix(len(dict))\n\n\t// Step 2: Move-to-front transform and run-length encoding.\n\tzr.mtf.Init(dict, zr.level*blockSize)\n\tbuf := zr.mtf.Decode(syms)\n\n\t// Step 3: Burrows-Wheeler transformation.\n\tif ptr >= len(buf) {\n\t\tpanicf(errors.Corrupted, \"origin pointer (0x%06x) exceeds block size: %d\", ptr, len(buf))\n\t}\n\tzr.bwt.Decode(buf, ptr)\n\n\treturn buf\n}\n\nfunc (zr *Reader) decodePrefix(numSyms int) (syms []uint16) {\n\tnumSyms += 2 // Remove 0 symbol, add RUNA, RUNB, and EOF symbols\n\tif numSyms < 3 {\n\t\tpanicf(errors.Corrupted, \"not enough prefix symbols: %d\", numSyms)\n\t}\n\n\t// Read information about the trees and tree selectors.\n\tvar mtf internal.MoveToFront\n\tnumTrees := int(zr.rd.ReadBitsBE64(3))\n\tif numTrees < minNumTrees || numTrees > maxNumTrees {\n\t\tpanicf(errors.Corrupted, \"invalid number of prefix trees: %d\", numTrees)\n\t}\n\tnumSels := int(zr.rd.ReadBitsBE64(15))\n\tif cap(zr.treeSels) < numSels {\n\t\tzr.treeSels = make([]uint8, numSels)\n\t}\n\ttreeSels := zr.treeSels[:numSels]\n\tfor i := range treeSels {\n\t\tsym, ok := zr.rd.TryReadSymbol(&decSel)\n\t\tif !ok {\n\t\t\tsym = zr.rd.ReadSymbol(&decSel)\n\t\t}\n\t\tif int(sym) >= numTrees {\n\t\t\tpanicf(errors.Corrupted, \"invalid prefix tree selector: %d\", sym)\n\t\t}\n\t\ttreeSels[i] = uint8(sym)\n\t}\n\tmtf.Decode(treeSels)\n\tzr.treeSels = treeSels\n\n\t// Initialize prefix codes.\n\tfor i := range zr.codes2D[:numTrees] {\n\t\tzr.codes1D[i] = zr.codes2D[i][:numSyms]\n\t}\n\tzr.rd.ReadPrefixCodes(zr.codes1D[:numTrees], zr.trees1D[:numTrees])\n\n\t// Read prefix encoded symbols of compressed data.\n\tvar tree *prefix.Decoder\n\tvar blkLen, selIdx int\n\tsyms = zr.syms[:0]\n\tfor {\n\t\tif blkLen == 0 {\n\t\t\tblkLen = numBlockSyms\n\t\t\tif selIdx >= len(treeSels) {\n\t\t\t\tpanicf(errors.Corrupted, \"not enough prefix tree selectors\")\n\t\t\t}\n\t\t\ttree = &zr.trees1D[treeSels[selIdx]]\n\t\t\tselIdx++\n\t\t}\n\t\tblkLen--\n\t\tsym, ok := zr.rd.TryReadSymbol(tree)\n\t\tif !ok {\n\t\t\tsym = zr.rd.ReadSymbol(tree)\n\t\t}\n\n\t\tif int(sym) == numSyms-1 {\n\t\t\tbreak // EOF marker\n\t\t}\n\t\tif int(sym) >= numSyms {\n\t\t\tpanicf(errors.Corrupted, \"invalid prefix symbol: %d\", sym)\n\t\t}\n\t\tif len(syms) >= zr.level*blockSize {\n\t\t\tpanicf(errors.Corrupted, \"number of prefix symbols exceeds block size\")\n\t\t}\n\t\tsyms = append(syms, uint16(sym))\n\t}\n\tzr.syms = syms\n\treturn syms\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/rle1.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage bzip2\n\nimport \"github.com/dsnet/compress/internal/errors\"\n\n// rleDone is a special \"error\" to indicate that the RLE stage is done.\nvar rleDone = errorf(errors.Unknown, \"RLE1 stage is completed\")\n\n// runLengthEncoding implements the first RLE stage of bzip2. Every sequence\n// of 4..255 duplicated bytes is replaced by only the first 4 bytes, and a\n// single byte representing the repeat length. Similar to the C bzip2\n// implementation, the encoder will always terminate repeat sequences with a\n// count (even if it is the end of the buffer), and it will also never produce\n// run lengths of 256..259. The decoder can handle the latter case.\n//\n// For example, if the input was:\n//\tinput:  \"AAAAAAABBBBCCCD\"\n//\n// Then the output will be:\n//\toutput: \"AAAA\\x03BBBB\\x00CCCD\"\ntype runLengthEncoding struct {\n\tbuf     []byte\n\tidx     int\n\tlastVal byte\n\tlastCnt int\n}\n\nfunc (rle *runLengthEncoding) Init(buf []byte) {\n\t*rle = runLengthEncoding{buf: buf}\n}\n\nfunc (rle *runLengthEncoding) Write(buf []byte) (int, error) {\n\tfor i, b := range buf {\n\t\tif rle.lastVal != b {\n\t\t\trle.lastCnt = 0\n\t\t}\n\t\trle.lastCnt++\n\t\tswitch {\n\t\tcase rle.lastCnt < 4:\n\t\t\tif rle.idx >= len(rle.buf) {\n\t\t\t\treturn i, rleDone\n\t\t\t}\n\t\t\trle.buf[rle.idx] = b\n\t\t\trle.idx++\n\t\tcase rle.lastCnt == 4:\n\t\t\tif rle.idx+1 >= len(rle.buf) {\n\t\t\t\treturn i, rleDone\n\t\t\t}\n\t\t\trle.buf[rle.idx] = b\n\t\t\trle.idx++\n\t\t\trle.buf[rle.idx] = 0\n\t\t\trle.idx++\n\t\tcase rle.lastCnt < 256:\n\t\t\trle.buf[rle.idx-1]++\n\t\tdefault:\n\t\t\tif rle.idx >= len(rle.buf) {\n\t\t\t\treturn i, rleDone\n\t\t\t}\n\t\t\trle.lastCnt = 1\n\t\t\trle.buf[rle.idx] = b\n\t\t\trle.idx++\n\t\t}\n\t\trle.lastVal = b\n\t}\n\treturn len(buf), nil\n}\n\nfunc (rle *runLengthEncoding) Read(buf []byte) (int, error) {\n\tfor i := range buf {\n\t\tswitch {\n\t\tcase rle.lastCnt == -4:\n\t\t\tif rle.idx >= len(rle.buf) {\n\t\t\t\treturn i, errorf(errors.Corrupted, \"missing terminating run-length repeater\")\n\t\t\t}\n\t\t\trle.lastCnt = int(rle.buf[rle.idx])\n\t\t\trle.idx++\n\t\t\tif rle.lastCnt > 0 {\n\t\t\t\tbreak // Break the switch\n\t\t\t}\n\t\t\tfallthrough // Count was zero, continue the work\n\t\tcase rle.lastCnt <= 0:\n\t\t\tif rle.idx >= len(rle.buf) {\n\t\t\t\treturn i, rleDone\n\t\t\t}\n\t\t\tb := rle.buf[rle.idx]\n\t\t\trle.idx++\n\t\t\tif b != rle.lastVal {\n\t\t\t\trle.lastCnt = 0\n\t\t\t\trle.lastVal = b\n\t\t\t}\n\t\t}\n\t\tbuf[i] = rle.lastVal\n\t\trle.lastCnt--\n\t}\n\treturn len(buf), nil\n}\n\nfunc (rle *runLengthEncoding) Bytes() []byte { return rle.buf[:rle.idx] }\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/bzip2/writer.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage bzip2\n\nimport (\n\t\"io\"\n\n\t\"github.com/dsnet/compress/internal\"\n\t\"github.com/dsnet/compress/internal/errors\"\n\t\"github.com/dsnet/compress/internal/prefix\"\n)\n\ntype Writer struct {\n\tInputOffset  int64 // Total number of bytes issued to Write\n\tOutputOffset int64 // Total number of bytes written to underlying io.Writer\n\n\twr     prefixWriter\n\terr    error\n\tlevel  int    // The current compression level\n\twrHdr  bool   // Have we written the stream header?\n\tblkCRC uint32 // CRC-32 IEEE of each block\n\tendCRC uint32 // Checksum of all blocks using bzip2's custom method\n\n\tcrc crc\n\trle runLengthEncoding\n\tbwt burrowsWheelerTransform\n\tmtf moveToFront\n\n\t// These fields are allocated with Writer and re-used later.\n\tbuf         []byte\n\ttreeSels    []uint8\n\ttreeSelsMTF []uint8\n\tcodes2D     [maxNumTrees][maxNumSyms]prefix.PrefixCode\n\tcodes1D     [maxNumTrees]prefix.PrefixCodes\n\ttrees1D     [maxNumTrees]prefix.Encoder\n}\n\ntype WriterConfig struct {\n\tLevel int\n\n\t_ struct{} // Blank field to prevent unkeyed struct literals\n}\n\nfunc NewWriter(w io.Writer, conf *WriterConfig) (*Writer, error) {\n\tvar lvl int\n\tif conf != nil {\n\t\tlvl = conf.Level\n\t}\n\tif lvl == 0 {\n\t\tlvl = DefaultCompression\n\t}\n\tif lvl < BestSpeed || lvl > BestCompression {\n\t\treturn nil, errorf(errors.Invalid, \"compression level: %d\", lvl)\n\t}\n\tzw := new(Writer)\n\tzw.level = lvl\n\tzw.Reset(w)\n\treturn zw, nil\n}\n\nfunc (zw *Writer) Reset(w io.Writer) error {\n\t*zw = Writer{\n\t\twr:    zw.wr,\n\t\tlevel: zw.level,\n\n\t\trle: zw.rle,\n\t\tbwt: zw.bwt,\n\t\tmtf: zw.mtf,\n\n\t\tbuf:         zw.buf,\n\t\ttreeSels:    zw.treeSels,\n\t\ttreeSelsMTF: zw.treeSelsMTF,\n\t\ttrees1D:     zw.trees1D,\n\t}\n\tzw.wr.Init(w)\n\tif len(zw.buf) != zw.level*blockSize {\n\t\tzw.buf = make([]byte, zw.level*blockSize)\n\t}\n\tzw.rle.Init(zw.buf)\n\treturn nil\n}\n\nfunc (zw *Writer) Write(buf []byte) (int, error) {\n\tif zw.err != nil {\n\t\treturn 0, zw.err\n\t}\n\n\tcnt := len(buf)\n\tfor {\n\t\twrCnt, err := zw.rle.Write(buf)\n\t\tif err != rleDone && zw.err == nil {\n\t\t\tzw.err = err\n\t\t}\n\t\tzw.crc.update(buf[:wrCnt])\n\t\tbuf = buf[wrCnt:]\n\t\tif len(buf) == 0 {\n\t\t\tzw.InputOffset += int64(cnt)\n\t\t\treturn cnt, nil\n\t\t}\n\t\tif zw.err = zw.flush(); zw.err != nil {\n\t\t\treturn 0, zw.err\n\t\t}\n\t}\n}\n\nfunc (zw *Writer) flush() error {\n\tvals := zw.rle.Bytes()\n\tif len(vals) == 0 {\n\t\treturn nil\n\t}\n\tzw.wr.Offset = zw.OutputOffset\n\tfunc() {\n\t\tdefer errors.Recover(&zw.err)\n\t\tif !zw.wrHdr {\n\t\t\t// Write stream header.\n\t\t\tzw.wr.WriteBitsBE64(hdrMagic, 16)\n\t\t\tzw.wr.WriteBitsBE64('h', 8)\n\t\t\tzw.wr.WriteBitsBE64(uint64('0'+zw.level), 8)\n\t\t\tzw.wrHdr = true\n\t\t}\n\t\tzw.encodeBlock(vals)\n\t}()\n\tvar err error\n\tif zw.OutputOffset, err = zw.wr.Flush(); zw.err == nil {\n\t\tzw.err = err\n\t}\n\tif zw.err != nil {\n\t\tzw.err = errWrap(zw.err, errors.Internal)\n\t\treturn zw.err\n\t}\n\tzw.endCRC = (zw.endCRC<<1 | zw.endCRC>>31) ^ zw.blkCRC\n\tzw.blkCRC = 0\n\tzw.rle.Init(zw.buf)\n\treturn nil\n}\n\nfunc (zw *Writer) Close() error {\n\tif zw.err == errClosed {\n\t\treturn nil\n\t}\n\n\t// Flush RLE buffer if there is left-over data.\n\tif zw.err = zw.flush(); zw.err != nil {\n\t\treturn zw.err\n\t}\n\n\t// Write stream footer.\n\tzw.wr.Offset = zw.OutputOffset\n\tfunc() {\n\t\tdefer errors.Recover(&zw.err)\n\t\tif !zw.wrHdr {\n\t\t\t// Write stream header.\n\t\t\tzw.wr.WriteBitsBE64(hdrMagic, 16)\n\t\t\tzw.wr.WriteBitsBE64('h', 8)\n\t\t\tzw.wr.WriteBitsBE64(uint64('0'+zw.level), 8)\n\t\t\tzw.wrHdr = true\n\t\t}\n\t\tzw.wr.WriteBitsBE64(endMagic, 48)\n\t\tzw.wr.WriteBitsBE64(uint64(zw.endCRC), 32)\n\t\tzw.wr.WritePads(0)\n\t}()\n\tvar err error\n\tif zw.OutputOffset, err = zw.wr.Flush(); zw.err == nil {\n\t\tzw.err = err\n\t}\n\tif zw.err != nil {\n\t\tzw.err = errWrap(zw.err, errors.Internal)\n\t\treturn zw.err\n\t}\n\n\tzw.err = errClosed\n\treturn nil\n}\n\nfunc (zw *Writer) encodeBlock(buf []byte) {\n\tzw.blkCRC = zw.crc.val\n\tzw.wr.WriteBitsBE64(blkMagic, 48)\n\tzw.wr.WriteBitsBE64(uint64(zw.blkCRC), 32)\n\tzw.wr.WriteBitsBE64(0, 1)\n\tzw.crc.val = 0\n\n\t// Step 1: Burrows-Wheeler transformation.\n\tptr := zw.bwt.Encode(buf)\n\tzw.wr.WriteBitsBE64(uint64(ptr), 24)\n\n\t// Step 2: Move-to-front transform and run-length encoding.\n\tvar dictMap [256]bool\n\tfor _, c := range buf {\n\t\tdictMap[c] = true\n\t}\n\n\tvar dictArr [256]uint8\n\tvar bmapLo [16]uint16\n\tdict := dictArr[:0]\n\tbmapHi := uint16(0)\n\tfor i, b := range dictMap {\n\t\tif b {\n\t\t\tc := uint8(i)\n\t\t\tdict = append(dict, c)\n\t\t\tbmapHi |= 1 << (c >> 4)\n\t\t\tbmapLo[c>>4] |= 1 << (c & 0xf)\n\t\t}\n\t}\n\n\tzw.wr.WriteBits(uint(bmapHi), 16)\n\tfor _, m := range bmapLo {\n\t\tif m > 0 {\n\t\t\tzw.wr.WriteBits(uint(m), 16)\n\t\t}\n\t}\n\n\tzw.mtf.Init(dict, len(buf))\n\tsyms := zw.mtf.Encode(buf)\n\n\t// Step 3: Prefix encoding.\n\tzw.encodePrefix(syms, len(dict))\n}\n\nfunc (zw *Writer) encodePrefix(syms []uint16, numSyms int) {\n\tnumSyms += 2 // Remove 0 symbol, add RUNA, RUNB, and EOB symbols\n\tif numSyms < 3 {\n\t\tpanicf(errors.Internal, \"unable to encode EOB marker\")\n\t}\n\tsyms = append(syms, uint16(numSyms-1)) // EOB marker\n\n\t// Compute number of prefix trees needed.\n\tnumTrees := maxNumTrees\n\tfor i, lim := range []int{200, 600, 1200, 2400} {\n\t\tif len(syms) < lim {\n\t\t\tnumTrees = minNumTrees + i\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Compute number of block selectors.\n\tnumSels := (len(syms) + numBlockSyms - 1) / numBlockSyms\n\tif cap(zw.treeSels) < numSels {\n\t\tzw.treeSels = make([]uint8, numSels)\n\t}\n\ttreeSels := zw.treeSels[:numSels]\n\tfor i := range treeSels {\n\t\ttreeSels[i] = uint8(i % numTrees)\n\t}\n\n\t// Initialize prefix codes.\n\tfor i := range zw.codes2D[:numTrees] {\n\t\tpc := zw.codes2D[i][:numSyms]\n\t\tfor j := range pc {\n\t\t\tpc[j] = prefix.PrefixCode{Sym: uint32(j)}\n\t\t}\n\t\tzw.codes1D[i] = pc\n\t}\n\n\t// First cut at assigning prefix trees to each group.\n\tvar codes prefix.PrefixCodes\n\tvar blkLen, selIdx int\n\tfor _, sym := range syms {\n\t\tif blkLen == 0 {\n\t\t\tblkLen = numBlockSyms\n\t\t\tcodes = zw.codes2D[treeSels[selIdx]][:numSyms]\n\t\t\tselIdx++\n\t\t}\n\t\tblkLen--\n\t\tcodes[sym].Cnt++\n\t}\n\n\t// TODO(dsnet): Use K-means to cluster groups to each prefix tree.\n\n\t// Generate lengths and prefixes based on symbol frequencies.\n\tfor i := range zw.trees1D[:numTrees] {\n\t\tpc := prefix.PrefixCodes(zw.codes2D[i][:numSyms])\n\t\tpc.SortByCount()\n\t\tif err := prefix.GenerateLengths(pc, maxPrefixBits); err != nil {\n\t\t\terrors.Panic(err)\n\t\t}\n\t\tpc.SortBySymbol()\n\t}\n\n\t// Write out information about the trees and tree selectors.\n\tvar mtf internal.MoveToFront\n\tzw.wr.WriteBitsBE64(uint64(numTrees), 3)\n\tzw.wr.WriteBitsBE64(uint64(numSels), 15)\n\tzw.treeSelsMTF = append(zw.treeSelsMTF[:0], treeSels...)\n\tmtf.Encode(zw.treeSelsMTF)\n\tfor _, sym := range zw.treeSelsMTF {\n\t\tzw.wr.WriteSymbol(uint(sym), &encSel)\n\t}\n\tzw.wr.WritePrefixCodes(zw.codes1D[:numTrees], zw.trees1D[:numTrees])\n\n\t// Write out prefix encoded symbols of compressed data.\n\tvar tree *prefix.Encoder\n\tblkLen, selIdx = 0, 0\n\tfor _, sym := range syms {\n\t\tif blkLen == 0 {\n\t\t\tblkLen = numBlockSyms\n\t\t\ttree = &zw.trees1D[treeSels[selIdx]]\n\t\t\tselIdx++\n\t\t}\n\t\tblkLen--\n\t\tok := zw.wr.TryWriteSymbol(uint(sym), tree)\n\t\tif !ok {\n\t\t\tzw.wr.WriteSymbol(uint(sym), tree)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/common.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Package internal is a collection of common compression algorithms.\n//\n// For performance reasons, these packages lack strong error checking and\n// require that the caller to ensure that strict invariants are kept.\npackage internal\n\nvar (\n\t// IdentityLUT returns the input key itself.\n\tIdentityLUT = func() (lut [256]byte) {\n\t\tfor i := range lut {\n\t\t\tlut[i] = uint8(i)\n\t\t}\n\t\treturn lut\n\t}()\n\n\t// ReverseLUT returns the input key with its bits reversed.\n\tReverseLUT = func() (lut [256]byte) {\n\t\tfor i := range lut {\n\t\t\tb := uint8(i)\n\t\t\tb = (b&0xaa)>>1 | (b&0x55)<<1\n\t\t\tb = (b&0xcc)>>2 | (b&0x33)<<2\n\t\t\tb = (b&0xf0)>>4 | (b&0x0f)<<4\n\t\t\tlut[i] = b\n\t\t}\n\t\treturn lut\n\t}()\n)\n\n// ReverseUint32 reverses all bits of v.\nfunc ReverseUint32(v uint32) (x uint32) {\n\tx |= uint32(ReverseLUT[byte(v>>0)]) << 24\n\tx |= uint32(ReverseLUT[byte(v>>8)]) << 16\n\tx |= uint32(ReverseLUT[byte(v>>16)]) << 8\n\tx |= uint32(ReverseLUT[byte(v>>24)]) << 0\n\treturn x\n}\n\n// ReverseUint32N reverses the lower n bits of v.\nfunc ReverseUint32N(v uint32, n uint) (x uint32) {\n\treturn ReverseUint32(v << (32 - n))\n}\n\n// ReverseUint64 reverses all bits of v.\nfunc ReverseUint64(v uint64) (x uint64) {\n\tx |= uint64(ReverseLUT[byte(v>>0)]) << 56\n\tx |= uint64(ReverseLUT[byte(v>>8)]) << 48\n\tx |= uint64(ReverseLUT[byte(v>>16)]) << 40\n\tx |= uint64(ReverseLUT[byte(v>>24)]) << 32\n\tx |= uint64(ReverseLUT[byte(v>>32)]) << 24\n\tx |= uint64(ReverseLUT[byte(v>>40)]) << 16\n\tx |= uint64(ReverseLUT[byte(v>>48)]) << 8\n\tx |= uint64(ReverseLUT[byte(v>>56)]) << 0\n\treturn x\n}\n\n// ReverseUint64N reverses the lower n bits of v.\nfunc ReverseUint64N(v uint64, n uint) (x uint64) {\n\treturn ReverseUint64(v << (64 - n))\n}\n\n// MoveToFront is a data structure that allows for more efficient move-to-front\n// transformations. This specific implementation assumes that the alphabet is\n// densely packed within 0..255.\ntype MoveToFront struct {\n\tdict [256]uint8 // Mapping from indexes to values\n\ttail int        // Number of tail bytes that are already ordered\n}\n\nfunc (m *MoveToFront) Encode(vals []uint8) {\n\tcopy(m.dict[:], IdentityLUT[:256-m.tail]) // Reset dict to be identity\n\n\tvar max int\n\tfor i, val := range vals {\n\t\tvar idx uint8 // Reverse lookup idx in dict\n\t\tfor di, dv := range m.dict {\n\t\t\tif dv == val {\n\t\t\t\tidx = uint8(di)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tvals[i] = idx\n\n\t\tmax |= int(idx)\n\t\tcopy(m.dict[1:], m.dict[:idx])\n\t\tm.dict[0] = val\n\t}\n\tm.tail = 256 - max - 1\n}\n\nfunc (m *MoveToFront) Decode(idxs []uint8) {\n\tcopy(m.dict[:], IdentityLUT[:256-m.tail]) // Reset dict to be identity\n\n\tvar max int\n\tfor i, idx := range idxs {\n\t\tval := m.dict[idx] // Forward lookup val in dict\n\t\tidxs[i] = val\n\n\t\tmax |= int(idx)\n\t\tcopy(m.dict[1:], m.dict[:idx])\n\t\tm.dict[0] = val\n\t}\n\tm.tail = 256 - max - 1\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/debug.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// +build debug,!gofuzz\n\npackage internal\n\nconst (\n\tDebug  = true\n\tGoFuzz = false\n)\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/errors/errors.go",
    "content": "// Copyright 2016, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Package errors implements functions to manipulate compression errors.\n//\n// In idiomatic Go, it is an anti-pattern to use panics as a form of error\n// reporting in the API. Instead, the expected way to transmit errors is by\n// returning an error value. Unfortunately, the checking of \"err != nil\" in\n// tight loops commonly found in compression causes non-negligible performance\n// degradation. While this may not be idiomatic, the internal packages of this\n// repository rely on panics as a normal means to convey errors. In order to\n// ensure that these panics do not leak across the public API, the public\n// packages must recover from these panics and present an error value.\n//\n// The Panic and Recover functions in this package provide a safe way to\n// recover from errors only generated from within this repository.\n//\n// Example usage:\n//\tfunc Foo() (err error) {\n//\t\tdefer errors.Recover(&err)\n//\n//\t\tif rand.Intn(2) == 0 {\n//\t\t\t// Unexpected panics will not be caught by Recover.\n//\t\t\tio.Closer(nil).Close()\n//\t\t} else {\n//\t\t\t// Errors thrown by Panic will be caught by Recover.\n//\t\t\terrors.Panic(errors.New(\"whoopsie\"))\n//\t\t}\n//\t}\n//\npackage errors\n\nimport \"strings\"\n\nconst (\n\t// Unknown indicates that there is no classification for this error.\n\tUnknown = iota\n\n\t// Internal indicates that this error is due to an internal bug.\n\t// Users should file a issue report if this type of error is encountered.\n\tInternal\n\n\t// Invalid indicates that this error is due to the user misusing the API\n\t// and is indicative of a bug on the user's part.\n\tInvalid\n\n\t// Deprecated indicates the use of a deprecated and unsupported feature.\n\tDeprecated\n\n\t// Corrupted indicates that the input stream is corrupted.\n\tCorrupted\n\n\t// Closed indicates that the handlers are closed.\n\tClosed\n)\n\nvar codeMap = map[int]string{\n\tUnknown:    \"unknown error\",\n\tInternal:   \"internal error\",\n\tInvalid:    \"invalid argument\",\n\tDeprecated: \"deprecated format\",\n\tCorrupted:  \"corrupted input\",\n\tClosed:     \"closed handler\",\n}\n\ntype Error struct {\n\tCode int    // The error type\n\tPkg  string // Name of the package where the error originated\n\tMsg  string // Descriptive message about the error (optional)\n}\n\nfunc (e Error) Error() string {\n\tvar ss []string\n\tfor _, s := range []string{e.Pkg, codeMap[e.Code], e.Msg} {\n\t\tif s != \"\" {\n\t\t\tss = append(ss, s)\n\t\t}\n\t}\n\treturn strings.Join(ss, \": \")\n}\n\nfunc (e Error) CompressError()     {}\nfunc (e Error) IsInternal() bool   { return e.Code == Internal }\nfunc (e Error) IsInvalid() bool    { return e.Code == Invalid }\nfunc (e Error) IsDeprecated() bool { return e.Code == Deprecated }\nfunc (e Error) IsCorrupted() bool  { return e.Code == Corrupted }\nfunc (e Error) IsClosed() bool     { return e.Code == Closed }\n\nfunc IsInternal(err error) bool   { return isCode(err, Internal) }\nfunc IsInvalid(err error) bool    { return isCode(err, Invalid) }\nfunc IsDeprecated(err error) bool { return isCode(err, Deprecated) }\nfunc IsCorrupted(err error) bool  { return isCode(err, Corrupted) }\nfunc IsClosed(err error) bool     { return isCode(err, Closed) }\n\nfunc isCode(err error, code int) bool {\n\tif cerr, ok := err.(Error); ok && cerr.Code == code {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// errWrap is used by Panic and Recover to ensure that only errors raised by\n// Panic are recovered by Recover.\ntype errWrap struct{ e *error }\n\nfunc Recover(err *error) {\n\tswitch ex := recover().(type) {\n\tcase nil:\n\t\t// Do nothing.\n\tcase errWrap:\n\t\t*err = *ex.e\n\tdefault:\n\t\tpanic(ex)\n\t}\n}\n\nfunc Panic(err error) {\n\tpanic(errWrap{&err})\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/gofuzz.go",
    "content": "// Copyright 2016, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// +build gofuzz\n\npackage internal\n\nconst (\n\tDebug  = true\n\tGoFuzz = true\n)\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/debug.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// +build debug\n\npackage prefix\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strings\"\n)\n\nfunc max(a, b int) int {\n\tif a > b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc lenBase2(n uint) int {\n\treturn int(math.Ceil(math.Log2(float64(n + 1))))\n}\nfunc padBase2(v, n uint, m int) string {\n\ts := fmt.Sprintf(\"%b\", 1<<n|v)[1:]\n\tif pad := m - len(s); pad > 0 {\n\t\treturn strings.Repeat(\" \", pad) + s\n\t}\n\treturn s\n}\n\nfunc lenBase10(n int) int {\n\treturn int(math.Ceil(math.Log10(float64(n + 1))))\n}\nfunc padBase10(n, m int) string {\n\ts := fmt.Sprintf(\"%d\", n)\n\tif pad := m - len(s); pad > 0 {\n\t\treturn strings.Repeat(\" \", pad) + s\n\t}\n\treturn s\n}\n\nfunc (rc RangeCodes) String() string {\n\tvar maxLen, maxBase int\n\tfor _, c := range rc {\n\t\tmaxLen = max(maxLen, int(c.Len))\n\t\tmaxBase = max(maxBase, int(c.Base))\n\t}\n\n\tvar ss []string\n\tss = append(ss, \"{\")\n\tfor i, c := range rc {\n\t\tbase := padBase10(int(c.Base), lenBase10(maxBase))\n\t\tif c.Len > 0 {\n\t\t\tbase += fmt.Sprintf(\"-%d\", c.End()-1)\n\t\t}\n\t\tss = append(ss, fmt.Sprintf(\"\\t%s:  {len: %s, range: %s},\",\n\t\t\tpadBase10(int(i), lenBase10(len(rc)-1)),\n\t\t\tpadBase10(int(c.Len), lenBase10(maxLen)),\n\t\t\tbase,\n\t\t))\n\t}\n\tss = append(ss, \"}\")\n\treturn strings.Join(ss, \"\\n\")\n}\n\nfunc (pc PrefixCodes) String() string {\n\tvar maxSym, maxLen, maxCnt int\n\tfor _, c := range pc {\n\t\tmaxSym = max(maxSym, int(c.Sym))\n\t\tmaxLen = max(maxLen, int(c.Len))\n\t\tmaxCnt = max(maxCnt, int(c.Cnt))\n\t}\n\n\tvar ss []string\n\tss = append(ss, \"{\")\n\tfor _, c := range pc {\n\t\tvar cntStr string\n\t\tif maxCnt > 0 {\n\t\t\tcnt := int(32*float32(c.Cnt)/float32(maxCnt) + 0.5)\n\t\t\tcntStr = fmt.Sprintf(\"%s |%s\",\n\t\t\t\tpadBase10(int(c.Cnt), lenBase10(maxCnt)),\n\t\t\t\tstrings.Repeat(\"#\", cnt),\n\t\t\t)\n\t\t}\n\t\tss = append(ss, fmt.Sprintf(\"\\t%s:  %s,  %s\",\n\t\t\tpadBase10(int(c.Sym), lenBase10(maxSym)),\n\t\t\tpadBase2(uint(c.Val), uint(c.Len), maxLen),\n\t\t\tcntStr,\n\t\t))\n\t}\n\tss = append(ss, \"}\")\n\treturn strings.Join(ss, \"\\n\")\n}\n\nfunc (pd Decoder) String() string {\n\tvar ss []string\n\tss = append(ss, \"{\")\n\tif len(pd.chunks) > 0 {\n\t\tss = append(ss, \"\\tchunks: {\")\n\t\tfor i, c := range pd.chunks {\n\t\t\tlabel := \"sym\"\n\t\t\tif uint(c&countMask) > uint(pd.chunkBits) {\n\t\t\t\tlabel = \"idx\"\n\t\t\t}\n\t\t\tss = append(ss, fmt.Sprintf(\"\\t\\t%s:  {%s: %s, len: %s}\",\n\t\t\t\tpadBase2(uint(i), uint(pd.chunkBits), int(pd.chunkBits)),\n\t\t\t\tlabel, padBase10(int(c>>countBits), 3),\n\t\t\t\tpadBase10(int(c&countMask), 2),\n\t\t\t))\n\t\t}\n\t\tss = append(ss, \"\\t},\")\n\n\t\tfor j, links := range pd.links {\n\t\t\tss = append(ss, fmt.Sprintf(\"\\tlinks[%d]: {\", j))\n\t\t\tlinkBits := lenBase2(uint(pd.linkMask))\n\t\t\tfor i, c := range links {\n\t\t\t\tss = append(ss, fmt.Sprintf(\"\\t\\t%s:  {sym: %s, len: %s},\",\n\t\t\t\t\tpadBase2(uint(i), uint(linkBits), int(linkBits)),\n\t\t\t\t\tpadBase10(int(c>>countBits), 3),\n\t\t\t\t\tpadBase10(int(c&countMask), 2),\n\t\t\t\t))\n\t\t\t}\n\t\t\tss = append(ss, \"\\t},\")\n\t\t}\n\t}\n\tss = append(ss, fmt.Sprintf(\"\\tchunkMask: %b,\", pd.chunkMask))\n\tss = append(ss, fmt.Sprintf(\"\\tlinkMask:  %b,\", pd.linkMask))\n\tss = append(ss, fmt.Sprintf(\"\\tchunkBits: %d,\", pd.chunkBits))\n\tss = append(ss, fmt.Sprintf(\"\\tMinBits:   %d,\", pd.MinBits))\n\tss = append(ss, fmt.Sprintf(\"\\tNumSyms:   %d,\", pd.NumSyms))\n\tss = append(ss, \"}\")\n\treturn strings.Join(ss, \"\\n\")\n}\n\nfunc (pe Encoder) String() string {\n\tvar maxLen int\n\tfor _, c := range pe.chunks {\n\t\tmaxLen = max(maxLen, int(c&countMask))\n\t}\n\n\tvar ss []string\n\tss = append(ss, \"{\")\n\tif len(pe.chunks) > 0 {\n\t\tss = append(ss, \"\\tchunks: {\")\n\t\tfor i, c := range pe.chunks {\n\t\t\tss = append(ss, fmt.Sprintf(\"\\t\\t%s:  %s,\",\n\t\t\t\tpadBase10(i, 3),\n\t\t\t\tpadBase2(uint(c>>countBits), uint(c&countMask), maxLen),\n\t\t\t))\n\t\t}\n\t\tss = append(ss, \"\\t},\")\n\t}\n\tss = append(ss, fmt.Sprintf(\"\\tchunkMask: %b,\", pe.chunkMask))\n\tss = append(ss, fmt.Sprintf(\"\\tNumSyms:   %d,\", pe.NumSyms))\n\tss = append(ss, \"}\")\n\treturn strings.Join(ss, \"\\n\")\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/decoder.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage prefix\n\nimport (\n\t\"sort\"\n\n\t\"github.com/dsnet/compress/internal\"\n)\n\n// The algorithm used to decode variable length codes is based on the lookup\n// method in zlib. If the code is less-than-or-equal to maxChunkBits,\n// then the symbol can be decoded using a single lookup into the chunks table.\n// Otherwise, the links table will be used for a second level lookup.\n//\n// The chunks slice is keyed by the contents of the bit buffer ANDed with\n// the chunkMask to avoid a out-of-bounds lookup. The value of chunks is a tuple\n// that is decoded as follow:\n//\n//\tvar length = chunks[bitBuffer&chunkMask] & countMask\n//\tvar symbol = chunks[bitBuffer&chunkMask] >> countBits\n//\n// If the decoded length is larger than chunkBits, then an overflow link table\n// must be used for further decoding. In this case, the symbol is actually the\n// index into the links tables. The second-level links table returned is\n// processed in the same way as the chunks table.\n//\n//\tif length > chunkBits {\n//\t\tvar index = symbol // Previous symbol is index into links tables\n//\t\tlength = links[index][bitBuffer>>chunkBits & linkMask] & countMask\n//\t\tsymbol = links[index][bitBuffer>>chunkBits & linkMask] >> countBits\n//\t}\n//\n// See the following:\n//\thttp://www.gzip.org/algorithm.txt\n\ntype Decoder struct {\n\tchunks    []uint32   // First-level lookup map\n\tlinks     [][]uint32 // Second-level lookup map\n\tchunkMask uint32     // Mask the length of the chunks table\n\tlinkMask  uint32     // Mask the length of the link table\n\tchunkBits uint32     // Bit-length of the chunks table\n\n\tMinBits uint32 // The minimum number of bits to safely make progress\n\tNumSyms uint32 // Number of symbols\n}\n\n// Init initializes Decoder according to the codes provided.\nfunc (pd *Decoder) Init(codes PrefixCodes) {\n\t// Handle special case trees.\n\tif len(codes) <= 1 {\n\t\tswitch {\n\t\tcase len(codes) == 0: // Empty tree (should error if used later)\n\t\t\t*pd = Decoder{chunks: pd.chunks[:0], links: pd.links[:0], NumSyms: 0}\n\t\tcase len(codes) == 1 && codes[0].Len == 0: // Single code tree (bit-length of zero)\n\t\t\tpd.chunks = append(pd.chunks[:0], codes[0].Sym<<countBits|0)\n\t\t\t*pd = Decoder{chunks: pd.chunks[:1], links: pd.links[:0], NumSyms: 1}\n\t\tdefault:\n\t\t\tpanic(\"invalid codes\")\n\t\t}\n\t\treturn\n\t}\n\tif internal.Debug && !sort.IsSorted(prefixCodesBySymbol(codes)) {\n\t\tpanic(\"input codes is not sorted\")\n\t}\n\tif internal.Debug && !(codes.checkLengths() && codes.checkPrefixes()) {\n\t\tpanic(\"detected incomplete or overlapping codes\")\n\t}\n\n\tvar minBits, maxBits uint32 = valueBits, 0\n\tfor _, c := range codes {\n\t\tif minBits > c.Len {\n\t\t\tminBits = c.Len\n\t\t}\n\t\tif maxBits < c.Len {\n\t\t\tmaxBits = c.Len\n\t\t}\n\t}\n\n\t// Allocate chunks table as needed.\n\tconst maxChunkBits = 9 // This can be tuned for better performance\n\tpd.NumSyms = uint32(len(codes))\n\tpd.MinBits = minBits\n\tpd.chunkBits = maxBits\n\tif pd.chunkBits > maxChunkBits {\n\t\tpd.chunkBits = maxChunkBits\n\t}\n\tnumChunks := 1 << pd.chunkBits\n\tpd.chunks = allocUint32s(pd.chunks, numChunks)\n\tpd.chunkMask = uint32(numChunks - 1)\n\n\t// Allocate links tables as needed.\n\tpd.links = pd.links[:0]\n\tpd.linkMask = 0\n\tif pd.chunkBits < maxBits {\n\t\tnumLinks := 1 << (maxBits - pd.chunkBits)\n\t\tpd.linkMask = uint32(numLinks - 1)\n\n\t\tvar linkIdx uint32\n\t\tfor i := range pd.chunks {\n\t\t\tpd.chunks[i] = 0 // Logic below relies on zero value as uninitialized\n\t\t}\n\t\tfor _, c := range codes {\n\t\t\tif c.Len > pd.chunkBits && pd.chunks[c.Val&pd.chunkMask] == 0 {\n\t\t\t\tpd.chunks[c.Val&pd.chunkMask] = (linkIdx << countBits) | (pd.chunkBits + 1)\n\t\t\t\tlinkIdx++\n\t\t\t}\n\t\t}\n\n\t\tpd.links = extendSliceUint32s(pd.links, int(linkIdx))\n\t\tlinksFlat := allocUint32s(pd.links[0], numLinks*int(linkIdx))\n\t\tfor i, j := 0, 0; i < len(pd.links); i, j = i+1, j+numLinks {\n\t\t\tpd.links[i] = linksFlat[j : j+numLinks]\n\t\t}\n\t}\n\n\t// Fill out chunks and links tables with values.\n\tfor _, c := range codes {\n\t\tchunk := c.Sym<<countBits | c.Len\n\t\tif c.Len <= pd.chunkBits {\n\t\t\tskip := 1 << uint(c.Len)\n\t\t\tfor j := int(c.Val); j < len(pd.chunks); j += skip {\n\t\t\t\tpd.chunks[j] = chunk\n\t\t\t}\n\t\t} else {\n\t\t\tlinkIdx := pd.chunks[c.Val&pd.chunkMask] >> countBits\n\t\t\tlinks := pd.links[linkIdx]\n\t\t\tskip := 1 << uint(c.Len-pd.chunkBits)\n\t\t\tfor j := int(c.Val >> pd.chunkBits); j < len(links); j += skip {\n\t\t\t\tlinks[j] = chunk\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/encoder.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage prefix\n\nimport (\n\t\"sort\"\n\n\t\"github.com/dsnet/compress/internal\"\n)\n\ntype Encoder struct {\n\tchunks    []uint32 // First-level lookup map\n\tchunkMask uint32   // Mask the length of the chunks table\n\n\tNumSyms uint32 // Number of symbols\n}\n\n// Init initializes Encoder according to the codes provided.\nfunc (pe *Encoder) Init(codes PrefixCodes) {\n\t// Handle special case trees.\n\tif len(codes) <= 1 {\n\t\tswitch {\n\t\tcase len(codes) == 0: // Empty tree (should error if used later)\n\t\t\t*pe = Encoder{chunks: pe.chunks[:0], NumSyms: 0}\n\t\tcase len(codes) == 1 && codes[0].Len == 0: // Single code tree (bit-length of zero)\n\t\t\tpe.chunks = append(pe.chunks[:0], codes[0].Val<<countBits|0)\n\t\t\t*pe = Encoder{chunks: pe.chunks[:1], NumSyms: 1}\n\t\tdefault:\n\t\t\tpanic(\"invalid codes\")\n\t\t}\n\t\treturn\n\t}\n\tif internal.Debug && !sort.IsSorted(prefixCodesBySymbol(codes)) {\n\t\tpanic(\"input codes is not sorted\")\n\t}\n\tif internal.Debug && !(codes.checkLengths() && codes.checkPrefixes()) {\n\t\tpanic(\"detected incomplete or overlapping codes\")\n\t}\n\n\t// Enough chunks to contain all the symbols.\n\tnumChunks := 1\n\tfor n := len(codes) - 1; n > 0; n >>= 1 {\n\t\tnumChunks <<= 1\n\t}\n\tpe.NumSyms = uint32(len(codes))\n\nretry:\n\t// Allocate and reset chunks.\n\tpe.chunks = allocUint32s(pe.chunks, numChunks)\n\tpe.chunkMask = uint32(numChunks - 1)\n\tfor i := range pe.chunks {\n\t\tpe.chunks[i] = 0 // Logic below relies on zero value as uninitialized\n\t}\n\n\t// Insert each symbol, checking that there are no conflicts.\n\tfor _, c := range codes {\n\t\tif pe.chunks[c.Sym&pe.chunkMask] > 0 {\n\t\t\t// Collision found our \"hash\" table, so grow and try again.\n\t\t\tnumChunks <<= 1\n\t\t\tgoto retry\n\t\t}\n\t\tpe.chunks[c.Sym&pe.chunkMask] = c.Val<<countBits | c.Len\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/prefix.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// Package prefix implements bit readers and writers that use prefix encoding.\npackage prefix\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/dsnet/compress/internal\"\n\t\"github.com/dsnet/compress/internal/errors\"\n)\n\nfunc errorf(c int, f string, a ...interface{}) error {\n\treturn errors.Error{Code: c, Pkg: \"prefix\", Msg: fmt.Sprintf(f, a...)}\n}\n\nfunc panicf(c int, f string, a ...interface{}) {\n\terrors.Panic(errorf(c, f, a...))\n}\n\nconst (\n\tcountBits = 5  // Number of bits to store the bit-length of the code\n\tvalueBits = 27 // Number of bits to store the code value\n\n\tcountMask = (1 << countBits) - 1\n)\n\n// PrefixCode is a representation of a prefix code, which is conceptually a\n// mapping from some arbitrary symbol to some bit-string.\n//\n// The Sym and Cnt fields are typically provided by the user,\n// while the Len and Val fields are generated by this package.\ntype PrefixCode struct {\n\tSym uint32 // The symbol being mapped\n\tCnt uint32 // The number times this symbol is used\n\tLen uint32 // Bit-length of the prefix code\n\tVal uint32 // Value of the prefix code (must be in 0..(1<<Len)-1)\n}\ntype PrefixCodes []PrefixCode\n\ntype prefixCodesBySymbol []PrefixCode\n\nfunc (c prefixCodesBySymbol) Len() int           { return len(c) }\nfunc (c prefixCodesBySymbol) Less(i, j int) bool { return c[i].Sym < c[j].Sym }\nfunc (c prefixCodesBySymbol) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }\n\ntype prefixCodesByCount []PrefixCode\n\nfunc (c prefixCodesByCount) Len() int { return len(c) }\nfunc (c prefixCodesByCount) Less(i, j int) bool {\n\treturn c[i].Cnt < c[j].Cnt || (c[i].Cnt == c[j].Cnt && c[i].Sym < c[j].Sym)\n}\nfunc (c prefixCodesByCount) Swap(i, j int) { c[i], c[j] = c[j], c[i] }\n\nfunc (pc PrefixCodes) SortBySymbol() { sort.Sort(prefixCodesBySymbol(pc)) }\nfunc (pc PrefixCodes) SortByCount()  { sort.Sort(prefixCodesByCount(pc)) }\n\n// Length computes the total bit-length using the Len and Cnt fields.\nfunc (pc PrefixCodes) Length() (nb uint) {\n\tfor _, c := range pc {\n\t\tnb += uint(c.Len * c.Cnt)\n\t}\n\treturn nb\n}\n\n// checkLengths reports whether the codes form a complete prefix tree.\nfunc (pc PrefixCodes) checkLengths() bool {\n\tsum := 1 << valueBits\n\tfor _, c := range pc {\n\t\tsum -= (1 << valueBits) >> uint(c.Len)\n\t}\n\treturn sum == 0 || len(pc) == 0\n}\n\n// checkPrefixes reports whether all codes have non-overlapping prefixes.\nfunc (pc PrefixCodes) checkPrefixes() bool {\n\tfor i, c1 := range pc {\n\t\tfor j, c2 := range pc {\n\t\t\tmask := uint32(1)<<c1.Len - 1\n\t\t\tif i != j && c1.Len <= c2.Len && c1.Val&mask == c2.Val&mask {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\n// checkCanonical reports whether all codes are canonical.\n// That is, they have the following properties:\n//\n//\t1. All codes of a given bit-length are consecutive values.\n//\t2. Shorter codes lexicographically precede longer codes.\n//\n// The codes must have unique symbols and be sorted by the symbol\n// The Len and Val fields in each code must be populated.\nfunc (pc PrefixCodes) checkCanonical() bool {\n\t// Rule 1.\n\tvar vals [valueBits + 1]PrefixCode\n\tfor _, c := range pc {\n\t\tif c.Len > 0 {\n\t\t\tc.Val = internal.ReverseUint32N(c.Val, uint(c.Len))\n\t\t\tif vals[c.Len].Cnt > 0 && vals[c.Len].Val+1 != c.Val {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tvals[c.Len].Val = c.Val\n\t\t\tvals[c.Len].Cnt++\n\t\t}\n\t}\n\n\t// Rule 2.\n\tvar last PrefixCode\n\tfor _, v := range vals {\n\t\tif v.Cnt > 0 {\n\t\t\tcurVal := v.Val - v.Cnt + 1\n\t\t\tif last.Cnt != 0 && last.Val >= curVal {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tlast = v\n\t\t}\n\t}\n\treturn true\n}\n\n// GenerateLengths assigns non-zero bit-lengths to all codes. Codes with high\n// frequency counts will be assigned shorter codes to reduce bit entropy.\n// This function is used primarily by compressors.\n//\n// The input codes must have the Cnt field populated, be sorted by count.\n// Even if a code has a count of 0, a non-zero bit-length will be assigned.\n//\n// The result will have the Len field populated. The algorithm used guarantees\n// that Len <= maxBits and that it is a complete prefix tree. The resulting\n// codes will remain sorted by count.\nfunc GenerateLengths(codes PrefixCodes, maxBits uint) error {\n\tif len(codes) <= 1 {\n\t\tif len(codes) == 1 {\n\t\t\tcodes[0].Len = 0\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Verify that the codes are in ascending order by count.\n\tcntLast := codes[0].Cnt\n\tfor _, c := range codes[1:] {\n\t\tif c.Cnt < cntLast {\n\t\t\treturn errorf(errors.Invalid, \"non-monotonically increasing symbol counts\")\n\t\t}\n\t\tcntLast = c.Cnt\n\t}\n\n\t// Construct a Huffman tree used to generate the bit-lengths.\n\t//\n\t// The Huffman tree is a binary tree where each symbol lies as a leaf node\n\t// on this tree. The length of the prefix code to assign is the depth of\n\t// that leaf from the root. The Huffman algorithm, which runs in O(n),\n\t// is used to generate the tree. It assumes that codes are sorted in\n\t// increasing order of frequency.\n\t//\n\t// The algorithm is as follows:\n\t//\t1. Start with two queues, F and Q, where F contains all of the starting\n\t//\tsymbols sorted such that symbols with lowest counts come first.\n\t//\t2. While len(F)+len(Q) > 1:\n\t//\t\t2a. Dequeue the node from F or Q that has the lowest weight as N0.\n\t//\t\t2b. Dequeue the node from F or Q that has the lowest weight as N1.\n\t//\t\t2c. Create a new node N that has N0 and N1 as its children.\n\t//\t\t2d. Enqueue N into the back of Q.\n\t//\t3. The tree's root node is Q[0].\n\ttype node struct {\n\t\tcnt uint32\n\n\t\t// n0 or c0 represent the left child of this node.\n\t\t// Since Go does not have unions, only one of these will be set.\n\t\t// Similarly, n1 or c1 represent the right child of this node.\n\t\t//\n\t\t// If n0 or n1 is set, then it represents a \"pointer\" to another\n\t\t// node in the Huffman tree. Since Go's pointer analysis cannot reason\n\t\t// that these node pointers do not escape (golang.org/issue/13493),\n\t\t// we use an index to a node in the nodes slice as a pseudo-pointer.\n\t\t//\n\t\t// If c0 or c1 is set, then it represents a leaf \"node\" in the\n\t\t// Huffman tree. The leaves are the PrefixCode values themselves.\n\t\tn0, n1 int // Index to child nodes\n\t\tc0, c1 *PrefixCode\n\t}\n\tvar nodeIdx int\n\tvar nodeArr [1024]node // Large enough to handle most cases on the stack\n\tnodes := nodeArr[:]\n\tif len(nodes) < len(codes) {\n\t\tnodes = make([]node, len(codes)) // Number of internal nodes < number of leaves\n\t}\n\tfreqs, queue := codes, nodes[:0]\n\tfor len(freqs)+len(queue) > 1 {\n\t\t// These are the two smallest nodes at the front of freqs and queue.\n\t\tvar n node\n\t\tif len(queue) == 0 || (len(freqs) > 0 && freqs[0].Cnt <= queue[0].cnt) {\n\t\t\tn.c0, freqs = &freqs[0], freqs[1:]\n\t\t\tn.cnt += n.c0.Cnt\n\t\t} else {\n\t\t\tn.cnt += queue[0].cnt\n\t\t\tn.n0 = nodeIdx // nodeIdx is same as &queue[0] - &nodes[0]\n\t\t\tnodeIdx++\n\t\t\tqueue = queue[1:]\n\t\t}\n\t\tif len(queue) == 0 || (len(freqs) > 0 && freqs[0].Cnt <= queue[0].cnt) {\n\t\t\tn.c1, freqs = &freqs[0], freqs[1:]\n\t\t\tn.cnt += n.c1.Cnt\n\t\t} else {\n\t\t\tn.cnt += queue[0].cnt\n\t\t\tn.n1 = nodeIdx // nodeIdx is same as &queue[0] - &nodes[0]\n\t\t\tnodeIdx++\n\t\t\tqueue = queue[1:]\n\t\t}\n\t\tqueue = append(queue, n)\n\t}\n\trootIdx := nodeIdx\n\n\t// Search the whole binary tree, noting when we hit each leaf node.\n\t// We do not care about the exact Huffman tree structure, but rather we only\n\t// care about depth of each of the leaf nodes. That is, the depth determines\n\t// how long each symbol is in bits.\n\t//\n\t// Since the number of leaves is n, there is at most n internal nodes.\n\t// Thus, this algorithm runs in O(n).\n\tvar fixBits bool\n\tvar explore func(int, uint)\n\texplore = func(rootIdx int, level uint) {\n\t\troot := &nodes[rootIdx]\n\n\t\t// Explore left branch.\n\t\tif root.c0 == nil {\n\t\t\texplore(root.n0, level+1)\n\t\t} else {\n\t\t\tfixBits = fixBits || (level > maxBits)\n\t\t\troot.c0.Len = uint32(level)\n\t\t}\n\n\t\t// Explore right branch.\n\t\tif root.c1 == nil {\n\t\t\texplore(root.n1, level+1)\n\t\t} else {\n\t\t\tfixBits = fixBits || (level > maxBits)\n\t\t\troot.c1.Len = uint32(level)\n\t\t}\n\t}\n\texplore(rootIdx, 1)\n\n\t// Fix the bit-lengths if we violate the maxBits requirement.\n\tif fixBits {\n\t\t// Create histogram for number of symbols with each bit-length.\n\t\tvar symBitsArr [valueBits + 1]uint32\n\t\tsymBits := symBitsArr[:] // symBits[nb] indicates number of symbols using nb bits\n\t\tfor _, c := range codes {\n\t\t\tfor int(c.Len) >= len(symBits) {\n\t\t\t\tsymBits = append(symBits, 0)\n\t\t\t}\n\t\t\tsymBits[c.Len]++\n\t\t}\n\n\t\t// Fudge the tree such that the largest bit-length is <= maxBits.\n\t\t// This is accomplish by effectively doing a tree rotation. That is, we\n\t\t// increase the bit-length of some higher frequency code, so that the\n\t\t// bit-lengths of lower frequency codes can be decreased.\n\t\t//\n\t\t// Visually, this looks like the following transform:\n\t\t//\n\t\t//\tLevel   Before       After\n\t\t//\t          __          ___\n\t\t//\t         /  \\        /   \\\n\t\t//\t n-1    X  / \\      /\\   /\\\n\t\t//\t n        X  /\\    X  X X  X\n\t\t//\t n+1        X  X\n\t\t//\n\t\tvar treeRotate func(uint)\n\t\ttreeRotate = func(nb uint) {\n\t\t\tif symBits[nb-1] == 0 {\n\t\t\t\ttreeRotate(nb - 1)\n\t\t\t}\n\t\t\tsymBits[nb-1] -= 1 // Push this node to the level below\n\t\t\tsymBits[nb] += 3   // This level gets one node from above, two from below\n\t\t\tsymBits[nb+1] -= 2 // Push two nodes to the level above\n\t\t}\n\t\tfor i := uint(len(symBits)) - 1; i > maxBits; i-- {\n\t\t\tfor symBits[i] > 0 {\n\t\t\t\ttreeRotate(i - 1)\n\t\t\t}\n\t\t}\n\n\t\t// Assign bit-lengths to each code. Since codes is sorted in increasing\n\t\t// order of frequency, that means that the most frequently used symbols\n\t\t// should have the shortest bit-lengths. Thus, we copy symbols to codes\n\t\t// from the back of codes first.\n\t\tcs := codes\n\t\tfor nb, cnt := range symBits {\n\t\t\tif cnt > 0 {\n\t\t\t\tpos := len(cs) - int(cnt)\n\t\t\t\tcs2 := cs[pos:]\n\t\t\t\tfor i := range cs2 {\n\t\t\t\t\tcs2[i].Len = uint32(nb)\n\t\t\t\t}\n\t\t\t\tcs = cs[:pos]\n\t\t\t}\n\t\t}\n\t\tif len(cs) != 0 {\n\t\t\tpanic(\"not all codes were used up\")\n\t\t}\n\t}\n\n\tif internal.Debug && !codes.checkLengths() {\n\t\tpanic(\"incomplete prefix tree detected\")\n\t}\n\treturn nil\n}\n\n// GeneratePrefixes assigns a prefix value to all codes according to the\n// bit-lengths. This function is used by both compressors and decompressors.\n//\n// The input codes must have the Sym and Len fields populated and be\n// sorted by symbol. The bit-lengths of each code must be properly allocated,\n// such that it forms a complete tree.\n//\n// The result will have the Val field populated and will produce a canonical\n// prefix tree. The resulting codes will remain sorted by symbol.\nfunc GeneratePrefixes(codes PrefixCodes) error {\n\tif len(codes) <= 1 {\n\t\tif len(codes) == 1 {\n\t\t\tif codes[0].Len != 0 {\n\t\t\t\treturn errorf(errors.Invalid, \"degenerate prefix tree with one node\")\n\t\t\t}\n\t\t\tcodes[0].Val = 0\n\t\t}\n\t\treturn nil\n\t}\n\n\t// Compute basic statistics on the symbols.\n\tvar bitCnts [valueBits + 1]uint\n\tc0 := codes[0]\n\tbitCnts[c0.Len]++\n\tminBits, maxBits, symLast := c0.Len, c0.Len, c0.Sym\n\tfor _, c := range codes[1:] {\n\t\tif c.Sym <= symLast {\n\t\t\treturn errorf(errors.Invalid, \"non-unique or non-monotonically increasing symbols\")\n\t\t}\n\t\tif minBits > c.Len {\n\t\t\tminBits = c.Len\n\t\t}\n\t\tif maxBits < c.Len {\n\t\t\tmaxBits = c.Len\n\t\t}\n\t\tbitCnts[c.Len]++ // Histogram of bit counts\n\t\tsymLast = c.Sym  // Keep track of last symbol\n\t}\n\tif minBits == 0 {\n\t\treturn errorf(errors.Invalid, \"invalid prefix bit-length\")\n\t}\n\n\t// Compute the next code for a symbol of a given bit length.\n\tvar nextCodes [valueBits + 1]uint\n\tvar code uint\n\tfor i := minBits; i <= maxBits; i++ {\n\t\tcode <<= 1\n\t\tnextCodes[i] = code\n\t\tcode += bitCnts[i]\n\t}\n\tif code != 1<<maxBits {\n\t\treturn errorf(errors.Invalid, \"degenerate prefix tree\")\n\t}\n\n\t// Assign the code to each symbol.\n\tfor i, c := range codes {\n\t\tcodes[i].Val = internal.ReverseUint32N(uint32(nextCodes[c.Len]), uint(c.Len))\n\t\tnextCodes[c.Len]++\n\t}\n\n\tif internal.Debug && !codes.checkPrefixes() {\n\t\tpanic(\"overlapping prefixes detected\")\n\t}\n\tif internal.Debug && !codes.checkCanonical() {\n\t\tpanic(\"non-canonical prefixes detected\")\n\t}\n\treturn nil\n}\n\nfunc allocUint32s(s []uint32, n int) []uint32 {\n\tif cap(s) >= n {\n\t\treturn s[:n]\n\t}\n\treturn make([]uint32, n, n*3/2)\n}\n\nfunc extendSliceUint32s(s [][]uint32, n int) [][]uint32 {\n\tif cap(s) >= n {\n\t\treturn s[:n]\n\t}\n\tss := make([][]uint32, n, n*3/2)\n\tcopy(ss, s[:cap(s)])\n\treturn ss\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/range.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage prefix\n\ntype RangeCode struct {\n\tBase uint32 // Starting base offset of the range\n\tLen  uint32 // Bit-length of a subsequent integer to add to base offset\n}\ntype RangeCodes []RangeCode\n\ntype RangeEncoder struct {\n\trcs     RangeCodes\n\tlut     [1024]uint32\n\tminBase uint\n}\n\n// End reports the non-inclusive ending range.\nfunc (rc RangeCode) End() uint32 { return rc.Base + (1 << rc.Len) }\n\n// MakeRangeCodes creates a RangeCodes, where each region is assumed to be\n// contiguously stacked, without any gaps, with bit-lengths taken from bits.\nfunc MakeRangeCodes(minBase uint, bits []uint) (rc RangeCodes) {\n\tfor _, nb := range bits {\n\t\trc = append(rc, RangeCode{Base: uint32(minBase), Len: uint32(nb)})\n\t\tminBase += 1 << nb\n\t}\n\treturn rc\n}\n\n// Base reports the inclusive starting range for all ranges.\nfunc (rcs RangeCodes) Base() uint32 { return rcs[0].Base }\n\n// End reports the non-inclusive ending range for all ranges.\nfunc (rcs RangeCodes) End() uint32 { return rcs[len(rcs)-1].End() }\n\n// checkValid reports whether the RangeCodes is valid. In order to be valid,\n// the following must hold true:\n//\trcs[i-1].Base <= rcs[i].Base\n//\trcs[i-1].End  <= rcs[i].End\n//\trcs[i-1].End  >= rcs[i].Base\n//\n// Practically speaking, each range must be increasing and must not have any\n// gaps in between. It is okay for ranges to overlap.\nfunc (rcs RangeCodes) checkValid() bool {\n\tif len(rcs) == 0 {\n\t\treturn false\n\t}\n\tpre := rcs[0]\n\tfor _, cur := range rcs[1:] {\n\t\tpreBase, preEnd := pre.Base, pre.End()\n\t\tcurBase, curEnd := cur.Base, cur.End()\n\t\tif preBase > curBase || preEnd > curEnd || preEnd < curBase {\n\t\t\treturn false\n\t\t}\n\t\tpre = cur\n\t}\n\treturn true\n}\n\nfunc (re *RangeEncoder) Init(rcs RangeCodes) {\n\tif !rcs.checkValid() {\n\t\tpanic(\"invalid range codes\")\n\t}\n\t*re = RangeEncoder{rcs: rcs, minBase: uint(rcs.Base())}\n\tfor sym, rc := range rcs {\n\t\tbase := int(rc.Base) - int(re.minBase)\n\t\tend := int(rc.End()) - int(re.minBase)\n\t\tif base >= len(re.lut) {\n\t\t\tbreak\n\t\t}\n\t\tif end > len(re.lut) {\n\t\t\tend = len(re.lut)\n\t\t}\n\t\tfor i := base; i < end; i++ {\n\t\t\tre.lut[i] = uint32(sym)\n\t\t}\n\t}\n}\n\nfunc (re *RangeEncoder) Encode(offset uint) (sym uint) {\n\tif idx := int(offset - re.minBase); idx < len(re.lut) {\n\t\treturn uint(re.lut[idx])\n\t}\n\tsym = uint(re.lut[len(re.lut)-1])\nretry:\n\tif int(sym) >= len(re.rcs) || re.rcs[sym].Base > uint32(offset) {\n\t\treturn sym - 1\n\t}\n\tsym++\n\tgoto retry // Avoid for-loop so that this function can be inlined\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/reader.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage prefix\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/dsnet/compress\"\n\t\"github.com/dsnet/compress/internal\"\n\t\"github.com/dsnet/compress/internal/errors\"\n)\n\n// Reader implements a prefix decoder. If the input io.Reader satisfies the\n// compress.ByteReader or compress.BufferedReader interface, then it also\n// guarantees that it will never read more bytes than is necessary.\n//\n// For high performance, provide an io.Reader that satisfies the\n// compress.BufferedReader interface. If the input does not satisfy either\n// compress.ByteReader or compress.BufferedReader, then it will be internally\n// wrapped with a bufio.Reader.\ntype Reader struct {\n\tOffset int64 // Number of bytes read from the underlying io.Reader\n\n\trd     io.Reader\n\tbyteRd compress.ByteReader     // Set if rd is a ByteReader\n\tbufRd  compress.BufferedReader // Set if rd is a BufferedReader\n\n\tbufBits   uint64 // Buffer to hold some bits\n\tnumBits   uint   // Number of valid bits in bufBits\n\tbigEndian bool   // Do we treat input bytes as big endian?\n\n\t// These fields are only used if rd is a compress.BufferedReader.\n\tbufPeek     []byte // Buffer for the Peek data\n\tdiscardBits int    // Number of bits to discard from reader\n\tfedBits     uint   // Number of bits fed in last call to PullBits\n\n\t// These fields are used to reduce allocations.\n\tbb *buffer\n\tbr *bytesReader\n\tsr *stringReader\n\tbu *bufio.Reader\n}\n\n// Init initializes the bit Reader to read from r. If bigEndian is true, then\n// bits will be read starting from the most-significant bits of a byte\n// (as done in bzip2), otherwise it will read starting from the\n// least-significant bits of a byte (such as for deflate and brotli).\nfunc (pr *Reader) Init(r io.Reader, bigEndian bool) {\n\t*pr = Reader{\n\t\trd:        r,\n\t\tbigEndian: bigEndian,\n\n\t\tbb: pr.bb,\n\t\tbr: pr.br,\n\t\tsr: pr.sr,\n\t\tbu: pr.bu,\n\t}\n\tswitch rr := r.(type) {\n\tcase *bytes.Buffer:\n\t\tif pr.bb == nil {\n\t\t\tpr.bb = new(buffer)\n\t\t}\n\t\t*pr.bb = buffer{Buffer: rr}\n\t\tpr.bufRd = pr.bb\n\tcase *bytes.Reader:\n\t\tif pr.br == nil {\n\t\t\tpr.br = new(bytesReader)\n\t\t}\n\t\t*pr.br = bytesReader{Reader: rr}\n\t\tpr.bufRd = pr.br\n\tcase *strings.Reader:\n\t\tif pr.sr == nil {\n\t\t\tpr.sr = new(stringReader)\n\t\t}\n\t\t*pr.sr = stringReader{Reader: rr}\n\t\tpr.bufRd = pr.sr\n\tcase compress.BufferedReader:\n\t\tpr.bufRd = rr\n\tcase compress.ByteReader:\n\t\tpr.byteRd = rr\n\tdefault:\n\t\tif pr.bu == nil {\n\t\t\tpr.bu = bufio.NewReader(nil)\n\t\t}\n\t\tpr.bu.Reset(r)\n\t\tpr.rd, pr.bufRd = pr.bu, pr.bu\n\t}\n}\n\n// BitsRead reports the total number of bits emitted from any Read method.\nfunc (pr *Reader) BitsRead() int64 {\n\toffset := 8*pr.Offset - int64(pr.numBits)\n\tif pr.bufRd != nil {\n\t\tdiscardBits := pr.discardBits + int(pr.fedBits-pr.numBits)\n\t\toffset = 8*pr.Offset + int64(discardBits)\n\t}\n\treturn offset\n}\n\n// IsBufferedReader reports whether the underlying io.Reader is also a\n// compress.BufferedReader.\nfunc (pr *Reader) IsBufferedReader() bool {\n\treturn pr.bufRd != nil\n}\n\n// ReadPads reads 0-7 bits from the bit buffer to achieve byte-alignment.\nfunc (pr *Reader) ReadPads() uint {\n\tnb := pr.numBits % 8\n\tval := uint(pr.bufBits & uint64(1<<nb-1))\n\tpr.bufBits >>= nb\n\tpr.numBits -= nb\n\treturn val\n}\n\n// Read reads bytes into buf.\n// The bit-ordering mode does not affect this method.\nfunc (pr *Reader) Read(buf []byte) (cnt int, err error) {\n\tif pr.numBits > 0 {\n\t\tif pr.numBits%8 != 0 {\n\t\t\treturn 0, errorf(errors.Invalid, \"non-aligned bit buffer\")\n\t\t}\n\t\tfor cnt = 0; len(buf) > cnt && pr.numBits > 0; cnt++ {\n\t\t\tif pr.bigEndian {\n\t\t\t\tbuf[cnt] = internal.ReverseLUT[byte(pr.bufBits)]\n\t\t\t} else {\n\t\t\t\tbuf[cnt] = byte(pr.bufBits)\n\t\t\t}\n\t\t\tpr.bufBits >>= 8\n\t\t\tpr.numBits -= 8\n\t\t}\n\t\treturn cnt, nil\n\t}\n\tif _, err := pr.Flush(); err != nil {\n\t\treturn 0, err\n\t}\n\tcnt, err = pr.rd.Read(buf)\n\tpr.Offset += int64(cnt)\n\treturn cnt, err\n}\n\n// ReadOffset reads an offset value using the provided RangeCodes indexed by\n// the symbol read.\nfunc (pr *Reader) ReadOffset(pd *Decoder, rcs RangeCodes) uint {\n\trc := rcs[pr.ReadSymbol(pd)]\n\treturn uint(rc.Base) + pr.ReadBits(uint(rc.Len))\n}\n\n// TryReadBits attempts to read nb bits using the contents of the bit buffer\n// alone. It returns the value and whether it succeeded.\n//\n// This method is designed to be inlined for performance reasons.\nfunc (pr *Reader) TryReadBits(nb uint) (uint, bool) {\n\tif pr.numBits < nb {\n\t\treturn 0, false\n\t}\n\tval := uint(pr.bufBits & uint64(1<<nb-1))\n\tpr.bufBits >>= nb\n\tpr.numBits -= nb\n\treturn val, true\n}\n\n// ReadBits reads nb bits in from the underlying reader.\nfunc (pr *Reader) ReadBits(nb uint) uint {\n\tif err := pr.PullBits(nb); err != nil {\n\t\terrors.Panic(err)\n\t}\n\tval := uint(pr.bufBits & uint64(1<<nb-1))\n\tpr.bufBits >>= nb\n\tpr.numBits -= nb\n\treturn val\n}\n\n// TryReadSymbol attempts to decode the next symbol using the contents of the\n// bit buffer alone. It returns the decoded symbol and whether it succeeded.\n//\n// This method is designed to be inlined for performance reasons.\nfunc (pr *Reader) TryReadSymbol(pd *Decoder) (uint, bool) {\n\tif pr.numBits < uint(pd.MinBits) || len(pd.chunks) == 0 {\n\t\treturn 0, false\n\t}\n\tchunk := pd.chunks[uint32(pr.bufBits)&pd.chunkMask]\n\tnb := uint(chunk & countMask)\n\tif nb > pr.numBits || nb > uint(pd.chunkBits) {\n\t\treturn 0, false\n\t}\n\tpr.bufBits >>= nb\n\tpr.numBits -= nb\n\treturn uint(chunk >> countBits), true\n}\n\n// ReadSymbol reads the next symbol using the provided prefix Decoder.\nfunc (pr *Reader) ReadSymbol(pd *Decoder) uint {\n\tif len(pd.chunks) == 0 {\n\t\tpanicf(errors.Invalid, \"decode with empty prefix tree\")\n\t}\n\n\tnb := uint(pd.MinBits)\n\tfor {\n\t\tif err := pr.PullBits(nb); err != nil {\n\t\t\terrors.Panic(err)\n\t\t}\n\t\tchunk := pd.chunks[uint32(pr.bufBits)&pd.chunkMask]\n\t\tnb = uint(chunk & countMask)\n\t\tif nb > uint(pd.chunkBits) {\n\t\t\tlinkIdx := chunk >> countBits\n\t\t\tchunk = pd.links[linkIdx][uint32(pr.bufBits>>pd.chunkBits)&pd.linkMask]\n\t\t\tnb = uint(chunk & countMask)\n\t\t}\n\t\tif nb <= pr.numBits {\n\t\t\tpr.bufBits >>= nb\n\t\t\tpr.numBits -= nb\n\t\t\treturn uint(chunk >> countBits)\n\t\t}\n\t}\n}\n\n// Flush updates the read offset of the underlying ByteReader.\n// If reader is a compress.BufferedReader, then this calls Discard to update\n// the read offset.\nfunc (pr *Reader) Flush() (int64, error) {\n\tif pr.bufRd == nil {\n\t\treturn pr.Offset, nil\n\t}\n\n\t// Update the number of total bits to discard.\n\tpr.discardBits += int(pr.fedBits - pr.numBits)\n\tpr.fedBits = pr.numBits\n\n\t// Discard some bytes to update read offset.\n\tvar err error\n\tnd := (pr.discardBits + 7) / 8 // Round up to nearest byte\n\tnd, err = pr.bufRd.Discard(nd)\n\tpr.discardBits -= nd * 8 // -7..0\n\tpr.Offset += int64(nd)\n\n\t// These are invalid after Discard.\n\tpr.bufPeek = nil\n\treturn pr.Offset, err\n}\n\n// PullBits ensures that at least nb bits exist in the bit buffer.\n// If the underlying reader is a compress.BufferedReader, then this will fill\n// the bit buffer with as many bits as possible, relying on Peek and Discard to\n// properly advance the read offset. Otherwise, it will use ReadByte to fill the\n// buffer with just the right number of bits.\nfunc (pr *Reader) PullBits(nb uint) error {\n\tif pr.bufRd != nil {\n\t\tpr.discardBits += int(pr.fedBits - pr.numBits)\n\t\tfor {\n\t\t\tif len(pr.bufPeek) == 0 {\n\t\t\t\tpr.fedBits = pr.numBits // Don't discard bits just added\n\t\t\t\tif _, err := pr.Flush(); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\t// Peek no more bytes than necessary.\n\t\t\t\t// The computation for cntPeek computes the minimum number of\n\t\t\t\t// bytes to Peek to fill nb bits.\n\t\t\t\tvar err error\n\t\t\t\tcntPeek := int(nb+(-nb&7)) / 8\n\t\t\t\tif cntPeek < pr.bufRd.Buffered() {\n\t\t\t\t\tcntPeek = pr.bufRd.Buffered()\n\t\t\t\t}\n\t\t\t\tpr.bufPeek, err = pr.bufRd.Peek(cntPeek)\n\t\t\t\tpr.bufPeek = pr.bufPeek[int(pr.numBits/8):] // Skip buffered bits\n\t\t\t\tif len(pr.bufPeek) == 0 {\n\t\t\t\t\tif pr.numBits >= nb {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif err == io.EOF {\n\t\t\t\t\t\terr = io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tn := int(64-pr.numBits) / 8 // Number of bytes to copy to bit buffer\n\t\t\tif len(pr.bufPeek) >= 8 {\n\t\t\t\t// Starting with Go 1.7, the compiler should use a wide integer\n\t\t\t\t// load here if the architecture supports it.\n\t\t\t\tu := binary.LittleEndian.Uint64(pr.bufPeek)\n\t\t\t\tif pr.bigEndian {\n\t\t\t\t\t// Swap all the bits within each byte.\n\t\t\t\t\tu = (u&0xaaaaaaaaaaaaaaaa)>>1 | (u&0x5555555555555555)<<1\n\t\t\t\t\tu = (u&0xcccccccccccccccc)>>2 | (u&0x3333333333333333)<<2\n\t\t\t\t\tu = (u&0xf0f0f0f0f0f0f0f0)>>4 | (u&0x0f0f0f0f0f0f0f0f)<<4\n\t\t\t\t}\n\n\t\t\t\tpr.bufBits |= u << pr.numBits\n\t\t\t\tpr.numBits += uint(n * 8)\n\t\t\t\tpr.bufPeek = pr.bufPeek[n:]\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\tif n > len(pr.bufPeek) {\n\t\t\t\t\tn = len(pr.bufPeek)\n\t\t\t\t}\n\t\t\t\tfor _, c := range pr.bufPeek[:n] {\n\t\t\t\t\tif pr.bigEndian {\n\t\t\t\t\t\tc = internal.ReverseLUT[c]\n\t\t\t\t\t}\n\t\t\t\t\tpr.bufBits |= uint64(c) << pr.numBits\n\t\t\t\t\tpr.numBits += 8\n\t\t\t\t}\n\t\t\t\tpr.bufPeek = pr.bufPeek[n:]\n\t\t\t\tif pr.numBits > 56 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tpr.fedBits = pr.numBits\n\t} else {\n\t\tfor pr.numBits < nb {\n\t\t\tc, err := pr.byteRd.ReadByte()\n\t\t\tif err != nil {\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\terr = io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif pr.bigEndian {\n\t\t\t\tc = internal.ReverseLUT[c]\n\t\t\t}\n\t\t\tpr.bufBits |= uint64(c) << pr.numBits\n\t\t\tpr.numBits += 8\n\t\t\tpr.Offset++\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/wrap.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage prefix\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"strings\"\n)\n\n// For some of the common Readers, we wrap and extend them to satisfy the\n// compress.BufferedReader interface to improve performance.\n\ntype buffer struct {\n\t*bytes.Buffer\n}\n\ntype bytesReader struct {\n\t*bytes.Reader\n\tpos int64\n\tbuf []byte\n\tarr [512]byte\n}\n\ntype stringReader struct {\n\t*strings.Reader\n\tpos int64\n\tbuf []byte\n\tarr [512]byte\n}\n\nfunc (r *buffer) Buffered() int {\n\treturn r.Len()\n}\n\nfunc (r *buffer) Peek(n int) ([]byte, error) {\n\tb := r.Bytes()\n\tif len(b) < n {\n\t\treturn b, io.EOF\n\t}\n\treturn b[:n], nil\n}\n\nfunc (r *buffer) Discard(n int) (int, error) {\n\tb := r.Next(n)\n\tif len(b) < n {\n\t\treturn len(b), io.EOF\n\t}\n\treturn n, nil\n}\n\nfunc (r *bytesReader) Buffered() int {\n\tr.update()\n\tif r.Len() > len(r.buf) {\n\t\treturn len(r.buf)\n\t}\n\treturn r.Len()\n}\n\nfunc (r *bytesReader) Peek(n int) ([]byte, error) {\n\tif n > len(r.arr) {\n\t\treturn nil, io.ErrShortBuffer\n\t}\n\n\t// Return sub-slice of local buffer if possible.\n\tr.update()\n\tif len(r.buf) >= n {\n\t\treturn r.buf[:n], nil\n\t}\n\n\t// Fill entire local buffer, and return appropriate sub-slice.\n\tcnt, err := r.ReadAt(r.arr[:], r.pos)\n\tr.buf = r.arr[:cnt]\n\tif cnt < n {\n\t\treturn r.arr[:cnt], err\n\t}\n\treturn r.arr[:n], nil\n}\n\nfunc (r *bytesReader) Discard(n int) (int, error) {\n\tvar err error\n\tif n > r.Len() {\n\t\tn, err = r.Len(), io.EOF\n\t}\n\tr.Seek(int64(n), io.SeekCurrent)\n\treturn n, err\n}\n\n// update reslices the internal buffer to be consistent with the read offset.\nfunc (r *bytesReader) update() {\n\tpos, _ := r.Seek(0, io.SeekCurrent)\n\tif off := pos - r.pos; off >= 0 && off < int64(len(r.buf)) {\n\t\tr.buf, r.pos = r.buf[off:], pos\n\t} else {\n\t\tr.buf, r.pos = nil, pos\n\t}\n}\n\nfunc (r *stringReader) Buffered() int {\n\tr.update()\n\tif r.Len() > len(r.buf) {\n\t\treturn len(r.buf)\n\t}\n\treturn r.Len()\n}\n\nfunc (r *stringReader) Peek(n int) ([]byte, error) {\n\tif n > len(r.arr) {\n\t\treturn nil, io.ErrShortBuffer\n\t}\n\n\t// Return sub-slice of local buffer if possible.\n\tr.update()\n\tif len(r.buf) >= n {\n\t\treturn r.buf[:n], nil\n\t}\n\n\t// Fill entire local buffer, and return appropriate sub-slice.\n\tcnt, err := r.ReadAt(r.arr[:], r.pos)\n\tr.buf = r.arr[:cnt]\n\tif cnt < n {\n\t\treturn r.arr[:cnt], err\n\t}\n\treturn r.arr[:n], nil\n}\n\nfunc (r *stringReader) Discard(n int) (int, error) {\n\tvar err error\n\tif n > r.Len() {\n\t\tn, err = r.Len(), io.EOF\n\t}\n\tr.Seek(int64(n), io.SeekCurrent)\n\treturn n, err\n}\n\n// update reslices the internal buffer to be consistent with the read offset.\nfunc (r *stringReader) update() {\n\tpos, _ := r.Seek(0, io.SeekCurrent)\n\tif off := pos - r.pos; off >= 0 && off < int64(len(r.buf)) {\n\t\tr.buf, r.pos = r.buf[off:], pos\n\t} else {\n\t\tr.buf, r.pos = nil, pos\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/prefix/writer.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\npackage prefix\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\n\t\"github.com/dsnet/compress/internal/errors\"\n)\n\n// Writer implements a prefix encoder. For performance reasons, Writer will not\n// write bytes immediately to the underlying stream.\ntype Writer struct {\n\tOffset int64 // Number of bytes written to the underlying io.Writer\n\n\twr        io.Writer\n\tbufBits   uint64 // Buffer to hold some bits\n\tnumBits   uint   // Number of valid bits in bufBits\n\tbigEndian bool   // Are bits written in big-endian order?\n\n\tbuf    [512]byte\n\tcntBuf int\n}\n\n// Init initializes the bit Writer to write to w. If bigEndian is true, then\n// bits will be written starting from the most-significant bits of a byte\n// (as done in bzip2), otherwise it will write starting from the\n// least-significant bits of a byte (such as for deflate and brotli).\nfunc (pw *Writer) Init(w io.Writer, bigEndian bool) {\n\t*pw = Writer{wr: w, bigEndian: bigEndian}\n\treturn\n}\n\n// BitsWritten reports the total number of bits issued to any Write method.\nfunc (pw *Writer) BitsWritten() int64 {\n\treturn 8*pw.Offset + 8*int64(pw.cntBuf) + int64(pw.numBits)\n}\n\n// WritePads writes 0-7 bits to the bit buffer to achieve byte-alignment.\nfunc (pw *Writer) WritePads(v uint) {\n\tnb := -pw.numBits & 7\n\tpw.bufBits |= uint64(v) << pw.numBits\n\tpw.numBits += nb\n}\n\n// Write writes bytes from buf.\n// The bit-ordering mode does not affect this method.\nfunc (pw *Writer) Write(buf []byte) (cnt int, err error) {\n\tif pw.numBits > 0 || pw.cntBuf > 0 {\n\t\tif pw.numBits%8 != 0 {\n\t\t\treturn 0, errorf(errors.Invalid, \"non-aligned bit buffer\")\n\t\t}\n\t\tif _, err := pw.Flush(); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\tcnt, err = pw.wr.Write(buf)\n\tpw.Offset += int64(cnt)\n\treturn cnt, err\n}\n\n// WriteOffset writes ofs in a (sym, extra) fashion using the provided prefix\n// Encoder and RangeEncoder.\nfunc (pw *Writer) WriteOffset(ofs uint, pe *Encoder, re *RangeEncoder) {\n\tsym := re.Encode(ofs)\n\tpw.WriteSymbol(sym, pe)\n\trc := re.rcs[sym]\n\tpw.WriteBits(ofs-uint(rc.Base), uint(rc.Len))\n}\n\n// TryWriteBits attempts to write nb bits using the contents of the bit buffer\n// alone. It reports whether it succeeded.\n//\n// This method is designed to be inlined for performance reasons.\nfunc (pw *Writer) TryWriteBits(v, nb uint) bool {\n\tif 64-pw.numBits < nb {\n\t\treturn false\n\t}\n\tpw.bufBits |= uint64(v) << pw.numBits\n\tpw.numBits += nb\n\treturn true\n}\n\n// WriteBits writes nb bits of v to the underlying writer.\nfunc (pw *Writer) WriteBits(v, nb uint) {\n\tif _, err := pw.PushBits(); err != nil {\n\t\terrors.Panic(err)\n\t}\n\tpw.bufBits |= uint64(v) << pw.numBits\n\tpw.numBits += nb\n}\n\n// TryWriteSymbol attempts to encode the next symbol using the contents of the\n// bit buffer alone. It reports whether it succeeded.\n//\n// This method is designed to be inlined for performance reasons.\nfunc (pw *Writer) TryWriteSymbol(sym uint, pe *Encoder) bool {\n\tchunk := pe.chunks[uint32(sym)&pe.chunkMask]\n\tnb := uint(chunk & countMask)\n\tif 64-pw.numBits < nb {\n\t\treturn false\n\t}\n\tpw.bufBits |= uint64(chunk>>countBits) << pw.numBits\n\tpw.numBits += nb\n\treturn true\n}\n\n// WriteSymbol writes the symbol using the provided prefix Encoder.\nfunc (pw *Writer) WriteSymbol(sym uint, pe *Encoder) {\n\tif _, err := pw.PushBits(); err != nil {\n\t\terrors.Panic(err)\n\t}\n\tchunk := pe.chunks[uint32(sym)&pe.chunkMask]\n\tnb := uint(chunk & countMask)\n\tpw.bufBits |= uint64(chunk>>countBits) << pw.numBits\n\tpw.numBits += nb\n}\n\n// Flush flushes all complete bytes from the bit buffer to the byte buffer, and\n// then flushes all bytes in the byte buffer to the underlying writer.\n// After this call, the bit Writer is will only withhold 7 bits at most.\nfunc (pw *Writer) Flush() (int64, error) {\n\tif pw.numBits < 8 && pw.cntBuf == 0 {\n\t\treturn pw.Offset, nil\n\t}\n\tif _, err := pw.PushBits(); err != nil {\n\t\treturn pw.Offset, err\n\t}\n\tcnt, err := pw.wr.Write(pw.buf[:pw.cntBuf])\n\tpw.cntBuf -= cnt\n\tpw.Offset += int64(cnt)\n\treturn pw.Offset, err\n}\n\n// PushBits pushes as many bytes as possible from the bit buffer to the byte\n// buffer, reporting the number of bits pushed.\nfunc (pw *Writer) PushBits() (uint, error) {\n\tif pw.cntBuf >= len(pw.buf)-8 {\n\t\tcnt, err := pw.wr.Write(pw.buf[:pw.cntBuf])\n\t\tpw.cntBuf -= cnt\n\t\tpw.Offset += int64(cnt)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\n\tu := pw.bufBits\n\tif pw.bigEndian {\n\t\t// Swap all the bits within each byte.\n\t\tu = (u&0xaaaaaaaaaaaaaaaa)>>1 | (u&0x5555555555555555)<<1\n\t\tu = (u&0xcccccccccccccccc)>>2 | (u&0x3333333333333333)<<2\n\t\tu = (u&0xf0f0f0f0f0f0f0f0)>>4 | (u&0x0f0f0f0f0f0f0f0f)<<4\n\t}\n\t// Starting with Go 1.7, the compiler should use a wide integer\n\t// store here if the architecture supports it.\n\tbinary.LittleEndian.PutUint64(pw.buf[pw.cntBuf:], u)\n\n\tnb := pw.numBits / 8 // Number of bytes to copy from bit buffer\n\tpw.cntBuf += int(nb)\n\tpw.bufBits >>= 8 * nb\n\tpw.numBits -= 8 * nb\n\treturn 8 * nb, nil\n}\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/internal/release.go",
    "content": "// Copyright 2015, Joe Tsai. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE.md file.\n\n// +build !debug,!gofuzz\n\npackage internal\n\n// Debug indicates whether the debug build tag was set.\n//\n// If set, programs may choose to print with more human-readable\n// debug information and also perform sanity checks that would otherwise be too\n// expensive to run in a release build.\nconst Debug = false\n\n// GoFuzz indicates whether the gofuzz build tag was set.\n//\n// If set, programs may choose to disable certain checks (like checksums) that\n// would be nearly impossible for gofuzz to properly get right.\n// If GoFuzz is set, it implies that Debug is set as well.\nconst GoFuzz = false\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/zbench.sh",
    "content": "#!/bin/bash\n#\n# Copyright 2017, Joe Tsai. All rights reserved.\n# Use of this source code is governed by a BSD-style\n# license that can be found in the LICENSE.md file.\n\n# zbench wraps internal/tool/bench and is useful for comparing benchmarks from\n# the implementations in this repository relative to other implementations.\n#\n# See internal/tool/bench/main.go for more details.\ncd $(dirname \"${BASH_SOURCE[0]}\")/internal/tool/bench\ngo run $(go list -f '{{ join .GoFiles \"\\n\" }}') \"$@\"\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/zfuzz.sh",
    "content": "#!/bin/bash\n#\n# Copyright 2017, Joe Tsai. All rights reserved.\n# Use of this source code is governed by a BSD-style\n# license that can be found in the LICENSE.md file.\n\n# zfuzz wraps internal/tool/fuzz and is useful for fuzz testing each of\n# the implementations in this repository.\ncd $(dirname \"${BASH_SOURCE[0]}\")/internal/tool/fuzz\n./fuzz.sh \"$@\"\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/zprof.sh",
    "content": "#!/bin/bash\n#\n# Copyright 2017, Joe Tsai. All rights reserved.\n# Use of this source code is governed by a BSD-style\n# license that can be found in the LICENSE.md file.\n\nif [ $# == 0 ]; then\n\techo \"Usage: $0 PKG_PATH TEST_ARGS...\"\n\techo \"\"\n\techo \"Runs coverage and performance benchmarks for a given package.\"\n\techo \"The results are stored in the _zprof_ directory.\"\n\techo \"\"\n\techo \"Example:\"\n\techo \"\t$0 flate -test.bench=Decode/Twain/Default\"\n\texit 1\nfi\n\nDIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd)\"\nPKG_PATH=$1\nPKG_NAME=$(basename $PKG_PATH)\nshift\n\nTMPDIR=$(mktemp -d)\ntrap \"rm -rf $TMPDIR $PKG_PATH/$PKG_NAME.test\" SIGINT SIGTERM EXIT\n\n(\n\tcd $DIR/$PKG_PATH\n\n\t# Print the go version.\n\tgo version\n\n\t# Perform coverage profiling.\n\tgo test github.com/dsnet/compress/$PKG_PATH -coverprofile $TMPDIR/cover.profile\n\tif [ $? != 0 ]; then exit 1; fi\n\tgo tool cover -html $TMPDIR/cover.profile -o cover.html\n\n\t# Perform performance profiling.\n\tif [ $# != 0 ]; then\n\t\tgo test -c github.com/dsnet/compress/$PKG_PATH\n\t\tif [ $? != 0 ]; then exit 1; fi\n\t\t./$PKG_NAME.test -test.cpuprofile $TMPDIR/cpu.profile -test.memprofile $TMPDIR/mem.profile -test.run - \"$@\"\n\t\tPPROF=\"go tool pprof\"\n\t\t$PPROF -output=cpu.svg          -web                      $PKG_NAME.test $TMPDIR/cpu.profile 2> /dev/null\n\t\t$PPROF -output=cpu.html         -weblist=.                $PKG_NAME.test $TMPDIR/cpu.profile 2> /dev/null\n\t\t$PPROF -output=mem_objects.svg  -alloc_objects -web       $PKG_NAME.test $TMPDIR/mem.profile 2> /dev/null\n\t\t$PPROF -output=mem_objects.html -alloc_objects -weblist=. $PKG_NAME.test $TMPDIR/mem.profile 2> /dev/null\n\t\t$PPROF -output=mem_space.svg    -alloc_space   -web       $PKG_NAME.test $TMPDIR/mem.profile 2> /dev/null\n\t\t$PPROF -output=mem_space.html   -alloc_space   -weblist=. $PKG_NAME.test $TMPDIR/mem.profile 2> /dev/null\n\tfi\n\n\trm -rf $DIR/_zprof_/$PKG_NAME\n\tmkdir -p $DIR/_zprof_/$PKG_NAME\n\tmv *.html *.svg $DIR/_zprof_/$PKG_NAME 2> /dev/null\n)\n"
  },
  {
    "path": "vendor/github.com/dsnet/compress/ztest.sh",
    "content": "#!/bin/bash\n#\n# Copyright 2017, Joe Tsai. All rights reserved.\n# Use of this source code is governed by a BSD-style\n# license that can be found in the LICENSE.md file.\n\ncd $(go list -f '{{ .Dir }}' github.com/dsnet/compress)\n\nBOLD=\"\\x1b[1mRunning: \"\nPASS=\"\\x1b[32mPASS\"\nFAIL=\"\\x1b[31mFAIL\"\nRESET=\"\\x1b[0m\"\n\necho -e \"${BOLD}fmt${RESET}\"\nRET_FMT=$(find . -name \"*.go\" | egrep -v \"/(_.*_|\\..*|testdata)/\" | xargs gofmt -d)\nif [[ ! -z \"$RET_FMT\" ]]; then echo \"$RET_FMT\"; echo; fi\n\necho -e \"${BOLD}test${RESET}\"\nRET_TEST=$(go test -race ./... | egrep -v \"^(ok|[?])\\s+\")\nif [[ ! -z \"$RET_TEST\" ]]; then echo \"$RET_TEST\"; echo; fi\n\necho -e \"${BOLD}staticcheck${RESET}\"\nRET_SCHK=$(staticcheck \\\n\t-ignore \"\n\t\tgithub.com/dsnet/compress/brotli/*.go:SA4016\n\t\tgithub.com/dsnet/compress/brotli/*.go:S1023\n\t\tgithub.com/dsnet/compress/brotli/*.go:U1000\n\t\tgithub.com/dsnet/compress/bzip2/*.go:S1023\n\t\tgithub.com/dsnet/compress/flate/*.go:U1000\n\t\tgithub.com/dsnet/compress/internal/cgo/lzma/*.go:SA4000\n\t\tgithub.com/dsnet/compress/internal/prefix/*.go:S1004\n\t\tgithub.com/dsnet/compress/internal/prefix/*.go:S1023\n\t\tgithub.com/dsnet/compress/internal/prefix/*.go:SA4016\n\t\tgithub.com/dsnet/compress/internal/tool/bench/*.go:S1007\n\t\tgithub.com/dsnet/compress/xflate/internal/meta/*.go:S1023\n\t\" ./... 2>&1)\nif [[ ! -z \"$RET_SCHK\" ]]; then echo \"$RET_SCHK\"; echo; fi\n\necho -e \"${BOLD}lint${RESET}\"\nRET_LINT=$(golint ./... 2>&1 |\n\tegrep -v \"^vendor/\" |\n\tegrep -v \"should have comment(.*)or be unexported\" |\n\tegrep -v \"^(.*)type name will be used as(.*)by other packages\" |\n\tegrep -v \"^brotli/transform.go:(.*)replace i [+]= 1 with i[+]{2}\" |\n\tegrep -v \"^internal/prefix/prefix.go:(.*)replace symBits(.*) [-]= 1 with symBits(.*)[-]{2}\" |\n\tegrep -v \"^xflate/common.go:(.*)NoCompression should be of the form\" |\n\tegrep -v \"^exit status\")\nif [[ ! -z \"$RET_LINT\" ]]; then echo \"$RET_LINT\"; echo; fi\n\nif [[ ! -z \"$RET_FMT\" ]] || [ ! -z \"$RET_TEST\" ] || [[ ! -z \"$RET_SCHK\" ]] || [[ ! -z \"$RET_LINT\" ]]; then\n\techo -e \"${FAIL}${RESET}\"; exit 1\nelse\n\techo -e \"${PASS}${RESET}\"; exit 0\nfi\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/.travis.yml",
    "content": "sudo: false\nlanguage: go\ngo:\n  - 1.3.x\n  - 1.5.x\n  - 1.6.x\n  - 1.7.x\n  - 1.8.x\n  - 1.9.x\n  - master\nmatrix:\n  allow_failures:\n    - go: master\n  fast_finish: true\ninstall:\n  - # Do nothing. This is needed to prevent default install action \"go get -t -v ./...\" from happening here (we want it to happen inside script step).\nscript:\n  - go get -t -v ./...\n  - diff -u <(echo -n) <(gofmt -d -s .)\n  - go tool vet .\n  - go test -v -race ./...\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/LICENSE",
    "content": "Copyright (c) 2005-2008  Dustin Sallings <dustin@spy.net>\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\nall copies 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\n<http://www.opensource.org/licenses/mit-license.php>\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/README.markdown",
    "content": "# Humane Units [![Build Status](https://travis-ci.org/dustin/go-humanize.svg?branch=master)](https://travis-ci.org/dustin/go-humanize) [![GoDoc](https://godoc.org/github.com/dustin/go-humanize?status.svg)](https://godoc.org/github.com/dustin/go-humanize)\n\nJust a few functions for helping humanize times and sizes.\n\n`go get` it as `github.com/dustin/go-humanize`, import it as\n`\"github.com/dustin/go-humanize\"`, use it as `humanize`.\n\nSee [godoc](https://godoc.org/github.com/dustin/go-humanize) for\ncomplete documentation.\n\n## Sizes\n\nThis lets you take numbers like `82854982` and convert them to useful\nstrings like, `83 MB` or `79 MiB` (whichever you prefer).\n\nExample:\n\n```go\nfmt.Printf(\"That file is %s.\", humanize.Bytes(82854982)) // That file is 83 MB.\n```\n\n## Times\n\nThis lets you take a `time.Time` and spit it out in relative terms.\nFor example, `12 seconds ago` or `3 days from now`.\n\nExample:\n\n```go\nfmt.Printf(\"This was touched %s.\", humanize.Time(someTimeInstance)) // This was touched 7 hours ago.\n```\n\nThanks to Kyle Lemons for the time implementation from an IRC\nconversation one day. It's pretty neat.\n\n## Ordinals\n\nFrom a [mailing list discussion][odisc] where a user wanted to be able\nto label ordinals.\n\n    0 -> 0th\n    1 -> 1st\n    2 -> 2nd\n    3 -> 3rd\n    4 -> 4th\n    [...]\n\nExample:\n\n```go\nfmt.Printf(\"You're my %s best friend.\", humanize.Ordinal(193)) // You are my 193rd best friend.\n```\n\n## Commas\n\nWant to shove commas into numbers? Be my guest.\n\n    0 -> 0\n    100 -> 100\n    1000 -> 1,000\n    1000000000 -> 1,000,000,000\n    -100000 -> -100,000\n\nExample:\n\n```go\nfmt.Printf(\"You owe $%s.\\n\", humanize.Comma(6582491)) // You owe $6,582,491.\n```\n\n## Ftoa\n\nNicer float64 formatter that removes trailing zeros.\n\n```go\nfmt.Printf(\"%f\", 2.24)                // 2.240000\nfmt.Printf(\"%s\", humanize.Ftoa(2.24)) // 2.24\nfmt.Printf(\"%f\", 2.0)                 // 2.000000\nfmt.Printf(\"%s\", humanize.Ftoa(2.0))  // 2\n```\n\n## SI notation\n\nFormat numbers with [SI notation][sinotation].\n\nExample:\n\n```go\nhumanize.SI(0.00000000223, \"M\") // 2.23 nM\n```\n\n## English-specific functions\n\nThe following functions are in the `humanize/english` subpackage.\n\n### Plurals\n\nSimple English pluralization\n\n```go\nenglish.PluralWord(1, \"object\", \"\") // object\nenglish.PluralWord(42, \"object\", \"\") // objects\nenglish.PluralWord(2, \"bus\", \"\") // buses\nenglish.PluralWord(99, \"locus\", \"loci\") // loci\n\nenglish.Plural(1, \"object\", \"\") // 1 object\nenglish.Plural(42, \"object\", \"\") // 42 objects\nenglish.Plural(2, \"bus\", \"\") // 2 buses\nenglish.Plural(99, \"locus\", \"loci\") // 99 loci\n```\n\n### Word series\n\nFormat comma-separated words lists with conjuctions:\n\n```go\nenglish.WordSeries([]string{\"foo\"}, \"and\") // foo\nenglish.WordSeries([]string{\"foo\", \"bar\"}, \"and\") // foo and bar\nenglish.WordSeries([]string{\"foo\", \"bar\", \"baz\"}, \"and\") // foo, bar and baz\n\nenglish.OxfordWordSeries([]string{\"foo\", \"bar\", \"baz\"}, \"and\") // foo, bar, and baz\n```\n\n[odisc]: https://groups.google.com/d/topic/golang-nuts/l8NhI74jl-4/discussion\n[sinotation]: http://en.wikipedia.org/wiki/Metric_prefix\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/big.go",
    "content": "package humanize\n\nimport (\n\t\"math/big\"\n)\n\n// order of magnitude (to a max order)\nfunc oomm(n, b *big.Int, maxmag int) (float64, int) {\n\tmag := 0\n\tm := &big.Int{}\n\tfor n.Cmp(b) >= 0 {\n\t\tn.DivMod(n, b, m)\n\t\tmag++\n\t\tif mag == maxmag && maxmag >= 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag\n}\n\n// total order of magnitude\n// (same as above, but with no upper limit)\nfunc oom(n, b *big.Int) (float64, int) {\n\tmag := 0\n\tm := &big.Int{}\n\tfor n.Cmp(b) >= 0 {\n\t\tn.DivMod(n, b, m)\n\t\tmag++\n\t}\n\treturn float64(n.Int64()) + (float64(m.Int64()) / float64(b.Int64())), mag\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/bigbytes.go",
    "content": "package humanize\n\nimport (\n\t\"fmt\"\n\t\"math/big\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nvar (\n\tbigIECExp = big.NewInt(1024)\n\n\t// BigByte is one byte in bit.Ints\n\tBigByte = big.NewInt(1)\n\t// BigKiByte is 1,024 bytes in bit.Ints\n\tBigKiByte = (&big.Int{}).Mul(BigByte, bigIECExp)\n\t// BigMiByte is 1,024 k bytes in bit.Ints\n\tBigMiByte = (&big.Int{}).Mul(BigKiByte, bigIECExp)\n\t// BigGiByte is 1,024 m bytes in bit.Ints\n\tBigGiByte = (&big.Int{}).Mul(BigMiByte, bigIECExp)\n\t// BigTiByte is 1,024 g bytes in bit.Ints\n\tBigTiByte = (&big.Int{}).Mul(BigGiByte, bigIECExp)\n\t// BigPiByte is 1,024 t bytes in bit.Ints\n\tBigPiByte = (&big.Int{}).Mul(BigTiByte, bigIECExp)\n\t// BigEiByte is 1,024 p bytes in bit.Ints\n\tBigEiByte = (&big.Int{}).Mul(BigPiByte, bigIECExp)\n\t// BigZiByte is 1,024 e bytes in bit.Ints\n\tBigZiByte = (&big.Int{}).Mul(BigEiByte, bigIECExp)\n\t// BigYiByte is 1,024 z bytes in bit.Ints\n\tBigYiByte = (&big.Int{}).Mul(BigZiByte, bigIECExp)\n)\n\nvar (\n\tbigSIExp = big.NewInt(1000)\n\n\t// BigSIByte is one SI byte in big.Ints\n\tBigSIByte = big.NewInt(1)\n\t// BigKByte is 1,000 SI bytes in big.Ints\n\tBigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp)\n\t// BigMByte is 1,000 SI k bytes in big.Ints\n\tBigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp)\n\t// BigGByte is 1,000 SI m bytes in big.Ints\n\tBigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp)\n\t// BigTByte is 1,000 SI g bytes in big.Ints\n\tBigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp)\n\t// BigPByte is 1,000 SI t bytes in big.Ints\n\tBigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp)\n\t// BigEByte is 1,000 SI p bytes in big.Ints\n\tBigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp)\n\t// BigZByte is 1,000 SI e bytes in big.Ints\n\tBigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp)\n\t// BigYByte is 1,000 SI z bytes in big.Ints\n\tBigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp)\n)\n\nvar bigBytesSizeTable = map[string]*big.Int{\n\t\"b\":   BigByte,\n\t\"kib\": BigKiByte,\n\t\"kb\":  BigKByte,\n\t\"mib\": BigMiByte,\n\t\"mb\":  BigMByte,\n\t\"gib\": BigGiByte,\n\t\"gb\":  BigGByte,\n\t\"tib\": BigTiByte,\n\t\"tb\":  BigTByte,\n\t\"pib\": BigPiByte,\n\t\"pb\":  BigPByte,\n\t\"eib\": BigEiByte,\n\t\"eb\":  BigEByte,\n\t\"zib\": BigZiByte,\n\t\"zb\":  BigZByte,\n\t\"yib\": BigYiByte,\n\t\"yb\":  BigYByte,\n\t// Without suffix\n\t\"\":   BigByte,\n\t\"ki\": BigKiByte,\n\t\"k\":  BigKByte,\n\t\"mi\": BigMiByte,\n\t\"m\":  BigMByte,\n\t\"gi\": BigGiByte,\n\t\"g\":  BigGByte,\n\t\"ti\": BigTiByte,\n\t\"t\":  BigTByte,\n\t\"pi\": BigPiByte,\n\t\"p\":  BigPByte,\n\t\"ei\": BigEiByte,\n\t\"e\":  BigEByte,\n\t\"z\":  BigZByte,\n\t\"zi\": BigZiByte,\n\t\"y\":  BigYByte,\n\t\"yi\": BigYiByte,\n}\n\nvar ten = big.NewInt(10)\n\nfunc humanateBigBytes(s, base *big.Int, sizes []string) string {\n\tif s.Cmp(ten) < 0 {\n\t\treturn fmt.Sprintf(\"%d B\", s)\n\t}\n\tc := (&big.Int{}).Set(s)\n\tval, mag := oomm(c, base, len(sizes)-1)\n\tsuffix := sizes[mag]\n\tf := \"%.0f %s\"\n\tif val < 10 {\n\t\tf = \"%.1f %s\"\n\t}\n\n\treturn fmt.Sprintf(f, val, suffix)\n\n}\n\n// BigBytes produces a human readable representation of an SI size.\n//\n// See also: ParseBigBytes.\n//\n// BigBytes(82854982) -> 83 MB\nfunc BigBytes(s *big.Int) string {\n\tsizes := []string{\"B\", \"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"}\n\treturn humanateBigBytes(s, bigSIExp, sizes)\n}\n\n// BigIBytes produces a human readable representation of an IEC size.\n//\n// See also: ParseBigBytes.\n//\n// BigIBytes(82854982) -> 79 MiB\nfunc BigIBytes(s *big.Int) string {\n\tsizes := []string{\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\", \"ZiB\", \"YiB\"}\n\treturn humanateBigBytes(s, bigIECExp, sizes)\n}\n\n// ParseBigBytes parses a string representation of bytes into the number\n// of bytes it represents.\n//\n// See also: BigBytes, BigIBytes.\n//\n// ParseBigBytes(\"42 MB\") -> 42000000, nil\n// ParseBigBytes(\"42 mib\") -> 44040192, nil\nfunc ParseBigBytes(s string) (*big.Int, error) {\n\tlastDigit := 0\n\thasComma := false\n\tfor _, r := range s {\n\t\tif !(unicode.IsDigit(r) || r == '.' || r == ',') {\n\t\t\tbreak\n\t\t}\n\t\tif r == ',' {\n\t\t\thasComma = true\n\t\t}\n\t\tlastDigit++\n\t}\n\n\tnum := s[:lastDigit]\n\tif hasComma {\n\t\tnum = strings.Replace(num, \",\", \"\", -1)\n\t}\n\n\tval := &big.Rat{}\n\t_, err := fmt.Sscanf(num, \"%f\", val)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\textra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))\n\tif m, ok := bigBytesSizeTable[extra]; ok {\n\t\tmv := (&big.Rat{}).SetInt(m)\n\t\tval.Mul(val, mv)\n\t\trv := &big.Int{}\n\t\trv.Div(val.Num(), val.Denom())\n\t\treturn rv, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"unhandled size name: %v\", extra)\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/bytes.go",
    "content": "package humanize\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n)\n\n// IEC Sizes.\n// kibis of bits\nconst (\n\tByte = 1 << (iota * 10)\n\tKiByte\n\tMiByte\n\tGiByte\n\tTiByte\n\tPiByte\n\tEiByte\n)\n\n// SI Sizes.\nconst (\n\tIByte = 1\n\tKByte = IByte * 1000\n\tMByte = KByte * 1000\n\tGByte = MByte * 1000\n\tTByte = GByte * 1000\n\tPByte = TByte * 1000\n\tEByte = PByte * 1000\n)\n\nvar bytesSizeTable = map[string]uint64{\n\t\"b\":   Byte,\n\t\"kib\": KiByte,\n\t\"kb\":  KByte,\n\t\"mib\": MiByte,\n\t\"mb\":  MByte,\n\t\"gib\": GiByte,\n\t\"gb\":  GByte,\n\t\"tib\": TiByte,\n\t\"tb\":  TByte,\n\t\"pib\": PiByte,\n\t\"pb\":  PByte,\n\t\"eib\": EiByte,\n\t\"eb\":  EByte,\n\t// Without suffix\n\t\"\":   Byte,\n\t\"ki\": KiByte,\n\t\"k\":  KByte,\n\t\"mi\": MiByte,\n\t\"m\":  MByte,\n\t\"gi\": GiByte,\n\t\"g\":  GByte,\n\t\"ti\": TiByte,\n\t\"t\":  TByte,\n\t\"pi\": PiByte,\n\t\"p\":  PByte,\n\t\"ei\": EiByte,\n\t\"e\":  EByte,\n}\n\nfunc logn(n, b float64) float64 {\n\treturn math.Log(n) / math.Log(b)\n}\n\nfunc humanateBytes(s uint64, base float64, sizes []string) string {\n\tif s < 10 {\n\t\treturn fmt.Sprintf(\"%d B\", s)\n\t}\n\te := math.Floor(logn(float64(s), base))\n\tsuffix := sizes[int(e)]\n\tval := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10\n\tf := \"%.0f %s\"\n\tif val < 10 {\n\t\tf = \"%.1f %s\"\n\t}\n\n\treturn fmt.Sprintf(f, val, suffix)\n}\n\n// Bytes produces a human readable representation of an SI size.\n//\n// See also: ParseBytes.\n//\n// Bytes(82854982) -> 83 MB\nfunc Bytes(s uint64) string {\n\tsizes := []string{\"B\", \"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\"}\n\treturn humanateBytes(s, 1000, sizes)\n}\n\n// IBytes produces a human readable representation of an IEC size.\n//\n// See also: ParseBytes.\n//\n// IBytes(82854982) -> 79 MiB\nfunc IBytes(s uint64) string {\n\tsizes := []string{\"B\", \"KiB\", \"MiB\", \"GiB\", \"TiB\", \"PiB\", \"EiB\"}\n\treturn humanateBytes(s, 1024, sizes)\n}\n\n// ParseBytes parses a string representation of bytes into the number\n// of bytes it represents.\n//\n// See Also: Bytes, IBytes.\n//\n// ParseBytes(\"42 MB\") -> 42000000, nil\n// ParseBytes(\"42 mib\") -> 44040192, nil\nfunc ParseBytes(s string) (uint64, error) {\n\tlastDigit := 0\n\thasComma := false\n\tfor _, r := range s {\n\t\tif !(unicode.IsDigit(r) || r == '.' || r == ',') {\n\t\t\tbreak\n\t\t}\n\t\tif r == ',' {\n\t\t\thasComma = true\n\t\t}\n\t\tlastDigit++\n\t}\n\n\tnum := s[:lastDigit]\n\tif hasComma {\n\t\tnum = strings.Replace(num, \",\", \"\", -1)\n\t}\n\n\tf, err := strconv.ParseFloat(num, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\textra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))\n\tif m, ok := bytesSizeTable[extra]; ok {\n\t\tf *= float64(m)\n\t\tif f >= math.MaxUint64 {\n\t\t\treturn 0, fmt.Errorf(\"too large: %v\", s)\n\t\t}\n\t\treturn uint64(f), nil\n\t}\n\n\treturn 0, fmt.Errorf(\"unhandled size name: %v\", extra)\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/comma.go",
    "content": "package humanize\n\nimport (\n\t\"bytes\"\n\t\"math\"\n\t\"math/big\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Comma produces a string form of the given number in base 10 with\n// commas after every three orders of magnitude.\n//\n// e.g. Comma(834142) -> 834,142\nfunc Comma(v int64) string {\n\tsign := \"\"\n\n\t// Min int64 can't be negated to a usable value, so it has to be special cased.\n\tif v == math.MinInt64 {\n\t\treturn \"-9,223,372,036,854,775,808\"\n\t}\n\n\tif v < 0 {\n\t\tsign = \"-\"\n\t\tv = 0 - v\n\t}\n\n\tparts := []string{\"\", \"\", \"\", \"\", \"\", \"\", \"\"}\n\tj := len(parts) - 1\n\n\tfor v > 999 {\n\t\tparts[j] = strconv.FormatInt(v%1000, 10)\n\t\tswitch len(parts[j]) {\n\t\tcase 2:\n\t\t\tparts[j] = \"0\" + parts[j]\n\t\tcase 1:\n\t\t\tparts[j] = \"00\" + parts[j]\n\t\t}\n\t\tv = v / 1000\n\t\tj--\n\t}\n\tparts[j] = strconv.Itoa(int(v))\n\treturn sign + strings.Join(parts[j:], \",\")\n}\n\n// Commaf produces a string form of the given number in base 10 with\n// commas after every three orders of magnitude.\n//\n// e.g. Commaf(834142.32) -> 834,142.32\nfunc Commaf(v float64) string {\n\tbuf := &bytes.Buffer{}\n\tif v < 0 {\n\t\tbuf.Write([]byte{'-'})\n\t\tv = 0 - v\n\t}\n\n\tcomma := []byte{','}\n\n\tparts := strings.Split(strconv.FormatFloat(v, 'f', -1, 64), \".\")\n\tpos := 0\n\tif len(parts[0])%3 != 0 {\n\t\tpos += len(parts[0]) % 3\n\t\tbuf.WriteString(parts[0][:pos])\n\t\tbuf.Write(comma)\n\t}\n\tfor ; pos < len(parts[0]); pos += 3 {\n\t\tbuf.WriteString(parts[0][pos : pos+3])\n\t\tbuf.Write(comma)\n\t}\n\tbuf.Truncate(buf.Len() - 1)\n\n\tif len(parts) > 1 {\n\t\tbuf.Write([]byte{'.'})\n\t\tbuf.WriteString(parts[1])\n\t}\n\treturn buf.String()\n}\n\n// CommafWithDigits works like the Commaf but limits the resulting\n// string to the given number of decimal places.\n//\n// e.g. CommafWithDigits(834142.32, 1) -> 834,142.3\nfunc CommafWithDigits(f float64, decimals int) string {\n\treturn stripTrailingDigits(Commaf(f), decimals)\n}\n\n// BigComma produces a string form of the given big.Int in base 10\n// with commas after every three orders of magnitude.\nfunc BigComma(b *big.Int) string {\n\tsign := \"\"\n\tif b.Sign() < 0 {\n\t\tsign = \"-\"\n\t\tb.Abs(b)\n\t}\n\n\tathousand := big.NewInt(1000)\n\tc := (&big.Int{}).Set(b)\n\t_, m := oom(c, athousand)\n\tparts := make([]string, m+1)\n\tj := len(parts) - 1\n\n\tmod := &big.Int{}\n\tfor b.Cmp(athousand) >= 0 {\n\t\tb.DivMod(b, athousand, mod)\n\t\tparts[j] = strconv.FormatInt(mod.Int64(), 10)\n\t\tswitch len(parts[j]) {\n\t\tcase 2:\n\t\t\tparts[j] = \"0\" + parts[j]\n\t\tcase 1:\n\t\t\tparts[j] = \"00\" + parts[j]\n\t\t}\n\t\tj--\n\t}\n\tparts[j] = strconv.Itoa(int(b.Int64()))\n\treturn sign + strings.Join(parts[j:], \",\")\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/commaf.go",
    "content": "// +build go1.6\n\npackage humanize\n\nimport (\n\t\"bytes\"\n\t\"math/big\"\n\t\"strings\"\n)\n\n// BigCommaf produces a string form of the given big.Float in base 10\n// with commas after every three orders of magnitude.\nfunc BigCommaf(v *big.Float) string {\n\tbuf := &bytes.Buffer{}\n\tif v.Sign() < 0 {\n\t\tbuf.Write([]byte{'-'})\n\t\tv.Abs(v)\n\t}\n\n\tcomma := []byte{','}\n\n\tparts := strings.Split(v.Text('f', -1), \".\")\n\tpos := 0\n\tif len(parts[0])%3 != 0 {\n\t\tpos += len(parts[0]) % 3\n\t\tbuf.WriteString(parts[0][:pos])\n\t\tbuf.Write(comma)\n\t}\n\tfor ; pos < len(parts[0]); pos += 3 {\n\t\tbuf.WriteString(parts[0][pos : pos+3])\n\t\tbuf.Write(comma)\n\t}\n\tbuf.Truncate(buf.Len() - 1)\n\n\tif len(parts) > 1 {\n\t\tbuf.Write([]byte{'.'})\n\t\tbuf.WriteString(parts[1])\n\t}\n\treturn buf.String()\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/ftoa.go",
    "content": "package humanize\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n)\n\nfunc stripTrailingZeros(s string) string {\n\toffset := len(s) - 1\n\tfor offset > 0 {\n\t\tif s[offset] == '.' {\n\t\t\toffset--\n\t\t\tbreak\n\t\t}\n\t\tif s[offset] != '0' {\n\t\t\tbreak\n\t\t}\n\t\toffset--\n\t}\n\treturn s[:offset+1]\n}\n\nfunc stripTrailingDigits(s string, digits int) string {\n\tif i := strings.Index(s, \".\"); i >= 0 {\n\t\tif digits <= 0 {\n\t\t\treturn s[:i]\n\t\t}\n\t\ti++\n\t\tif i+digits >= len(s) {\n\t\t\treturn s\n\t\t}\n\t\treturn s[:i+digits]\n\t}\n\treturn s\n}\n\n// Ftoa converts a float to a string with no trailing zeros.\nfunc Ftoa(num float64) string {\n\treturn stripTrailingZeros(strconv.FormatFloat(num, 'f', 6, 64))\n}\n\n// FtoaWithDigits converts a float to a string but limits the resulting string\n// to the given number of decimal places, and no trailing zeros.\nfunc FtoaWithDigits(num float64, digits int) string {\n\treturn stripTrailingZeros(stripTrailingDigits(strconv.FormatFloat(num, 'f', 6, 64), digits))\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/humanize.go",
    "content": "/*\nPackage humanize converts boring ugly numbers to human-friendly strings and back.\n\nDurations can be turned into strings such as \"3 days ago\", numbers\nrepresenting sizes like 82854982 into useful strings like, \"83 MB\" or\n\"79 MiB\" (whichever you prefer).\n*/\npackage humanize\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/number.go",
    "content": "package humanize\n\n/*\nSlightly adapted from the source to fit go-humanize.\n\nAuthor: https://github.com/gorhill\nSource: https://gist.github.com/gorhill/5285193\n\n*/\n\nimport (\n\t\"math\"\n\t\"strconv\"\n)\n\nvar (\n\trenderFloatPrecisionMultipliers = [...]float64{\n\t\t1,\n\t\t10,\n\t\t100,\n\t\t1000,\n\t\t10000,\n\t\t100000,\n\t\t1000000,\n\t\t10000000,\n\t\t100000000,\n\t\t1000000000,\n\t}\n\n\trenderFloatPrecisionRounders = [...]float64{\n\t\t0.5,\n\t\t0.05,\n\t\t0.005,\n\t\t0.0005,\n\t\t0.00005,\n\t\t0.000005,\n\t\t0.0000005,\n\t\t0.00000005,\n\t\t0.000000005,\n\t\t0.0000000005,\n\t}\n)\n\n// FormatFloat produces a formatted number as string based on the following user-specified criteria:\n// * thousands separator\n// * decimal separator\n// * decimal precision\n//\n// Usage: s := RenderFloat(format, n)\n// The format parameter tells how to render the number n.\n//\n// See examples: http://play.golang.org/p/LXc1Ddm1lJ\n//\n// Examples of format strings, given n = 12345.6789:\n// \"#,###.##\" => \"12,345.67\"\n// \"#,###.\" => \"12,345\"\n// \"#,###\" => \"12345,678\"\n// \"#\\u202F###,##\" => \"12 345,68\"\n// \"#.###,###### => 12.345,678900\n// \"\" (aka default format) => 12,345.67\n//\n// The highest precision allowed is 9 digits after the decimal symbol.\n// There is also a version for integer number, FormatInteger(),\n// which is convenient for calls within template.\nfunc FormatFloat(format string, n float64) string {\n\t// Special cases:\n\t//   NaN = \"NaN\"\n\t//   +Inf = \"+Infinity\"\n\t//   -Inf = \"-Infinity\"\n\tif math.IsNaN(n) {\n\t\treturn \"NaN\"\n\t}\n\tif n > math.MaxFloat64 {\n\t\treturn \"Infinity\"\n\t}\n\tif n < -math.MaxFloat64 {\n\t\treturn \"-Infinity\"\n\t}\n\n\t// default format\n\tprecision := 2\n\tdecimalStr := \".\"\n\tthousandStr := \",\"\n\tpositiveStr := \"\"\n\tnegativeStr := \"-\"\n\n\tif len(format) > 0 {\n\t\tformat := []rune(format)\n\n\t\t// If there is an explicit format directive,\n\t\t// then default values are these:\n\t\tprecision = 9\n\t\tthousandStr = \"\"\n\n\t\t// collect indices of meaningful formatting directives\n\t\tformatIndx := []int{}\n\t\tfor i, char := range format {\n\t\t\tif char != '#' && char != '0' {\n\t\t\t\tformatIndx = append(formatIndx, i)\n\t\t\t}\n\t\t}\n\n\t\tif len(formatIndx) > 0 {\n\t\t\t// Directive at index 0:\n\t\t\t//   Must be a '+'\n\t\t\t//   Raise an error if not the case\n\t\t\t// index: 0123456789\n\t\t\t//        +0.000,000\n\t\t\t//        +000,000.0\n\t\t\t//        +0000.00\n\t\t\t//        +0000\n\t\t\tif formatIndx[0] == 0 {\n\t\t\t\tif format[formatIndx[0]] != '+' {\n\t\t\t\t\tpanic(\"RenderFloat(): invalid positive sign directive\")\n\t\t\t\t}\n\t\t\t\tpositiveStr = \"+\"\n\t\t\t\tformatIndx = formatIndx[1:]\n\t\t\t}\n\n\t\t\t// Two directives:\n\t\t\t//   First is thousands separator\n\t\t\t//   Raise an error if not followed by 3-digit\n\t\t\t// 0123456789\n\t\t\t// 0.000,000\n\t\t\t// 000,000.00\n\t\t\tif len(formatIndx) == 2 {\n\t\t\t\tif (formatIndx[1] - formatIndx[0]) != 4 {\n\t\t\t\t\tpanic(\"RenderFloat(): thousands separator directive must be followed by 3 digit-specifiers\")\n\t\t\t\t}\n\t\t\t\tthousandStr = string(format[formatIndx[0]])\n\t\t\t\tformatIndx = formatIndx[1:]\n\t\t\t}\n\n\t\t\t// One directive:\n\t\t\t//   Directive is decimal separator\n\t\t\t//   The number of digit-specifier following the separator indicates wanted precision\n\t\t\t// 0123456789\n\t\t\t// 0.00\n\t\t\t// 000,0000\n\t\t\tif len(formatIndx) == 1 {\n\t\t\t\tdecimalStr = string(format[formatIndx[0]])\n\t\t\t\tprecision = len(format) - formatIndx[0] - 1\n\t\t\t}\n\t\t}\n\t}\n\n\t// generate sign part\n\tvar signStr string\n\tif n >= 0.000000001 {\n\t\tsignStr = positiveStr\n\t} else if n <= -0.000000001 {\n\t\tsignStr = negativeStr\n\t\tn = -n\n\t} else {\n\t\tsignStr = \"\"\n\t\tn = 0.0\n\t}\n\n\t// split number into integer and fractional parts\n\tintf, fracf := math.Modf(n + renderFloatPrecisionRounders[precision])\n\n\t// generate integer part string\n\tintStr := strconv.FormatInt(int64(intf), 10)\n\n\t// add thousand separator if required\n\tif len(thousandStr) > 0 {\n\t\tfor i := len(intStr); i > 3; {\n\t\t\ti -= 3\n\t\t\tintStr = intStr[:i] + thousandStr + intStr[i:]\n\t\t}\n\t}\n\n\t// no fractional part, we can leave now\n\tif precision == 0 {\n\t\treturn signStr + intStr\n\t}\n\n\t// generate fractional part\n\tfracStr := strconv.Itoa(int(fracf * renderFloatPrecisionMultipliers[precision]))\n\t// may need padding\n\tif len(fracStr) < precision {\n\t\tfracStr = \"000000000000000\"[:precision-len(fracStr)] + fracStr\n\t}\n\n\treturn signStr + intStr + decimalStr + fracStr\n}\n\n// FormatInteger produces a formatted number as string.\n// See FormatFloat.\nfunc FormatInteger(format string, n int) string {\n\treturn FormatFloat(format, float64(n))\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/ordinals.go",
    "content": "package humanize\n\nimport \"strconv\"\n\n// Ordinal gives you the input number in a rank/ordinal format.\n//\n// Ordinal(3) -> 3rd\nfunc Ordinal(x int) string {\n\tsuffix := \"th\"\n\tswitch x % 10 {\n\tcase 1:\n\t\tif x%100 != 11 {\n\t\t\tsuffix = \"st\"\n\t\t}\n\tcase 2:\n\t\tif x%100 != 12 {\n\t\t\tsuffix = \"nd\"\n\t\t}\n\tcase 3:\n\t\tif x%100 != 13 {\n\t\t\tsuffix = \"rd\"\n\t\t}\n\t}\n\treturn strconv.Itoa(x) + suffix\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/si.go",
    "content": "package humanize\n\nimport (\n\t\"errors\"\n\t\"math\"\n\t\"regexp\"\n\t\"strconv\"\n)\n\nvar siPrefixTable = map[float64]string{\n\t-24: \"y\", // yocto\n\t-21: \"z\", // zepto\n\t-18: \"a\", // atto\n\t-15: \"f\", // femto\n\t-12: \"p\", // pico\n\t-9:  \"n\", // nano\n\t-6:  \"µ\", // micro\n\t-3:  \"m\", // milli\n\t0:   \"\",\n\t3:   \"k\", // kilo\n\t6:   \"M\", // mega\n\t9:   \"G\", // giga\n\t12:  \"T\", // tera\n\t15:  \"P\", // peta\n\t18:  \"E\", // exa\n\t21:  \"Z\", // zetta\n\t24:  \"Y\", // yotta\n}\n\nvar revSIPrefixTable = revfmap(siPrefixTable)\n\n// revfmap reverses the map and precomputes the power multiplier\nfunc revfmap(in map[float64]string) map[string]float64 {\n\trv := map[string]float64{}\n\tfor k, v := range in {\n\t\trv[v] = math.Pow(10, k)\n\t}\n\treturn rv\n}\n\nvar riParseRegex *regexp.Regexp\n\nfunc init() {\n\tri := `^([\\-0-9.]+)\\s?([`\n\tfor _, v := range siPrefixTable {\n\t\tri += v\n\t}\n\tri += `]?)(.*)`\n\n\triParseRegex = regexp.MustCompile(ri)\n}\n\n// ComputeSI finds the most appropriate SI prefix for the given number\n// and returns the prefix along with the value adjusted to be within\n// that prefix.\n//\n// See also: SI, ParseSI.\n//\n// e.g. ComputeSI(2.2345e-12) -> (2.2345, \"p\")\nfunc ComputeSI(input float64) (float64, string) {\n\tif input == 0 {\n\t\treturn 0, \"\"\n\t}\n\tmag := math.Abs(input)\n\texponent := math.Floor(logn(mag, 10))\n\texponent = math.Floor(exponent/3) * 3\n\n\tvalue := mag / math.Pow(10, exponent)\n\n\t// Handle special case where value is exactly 1000.0\n\t// Should return 1 M instead of 1000 k\n\tif value == 1000.0 {\n\t\texponent += 3\n\t\tvalue = mag / math.Pow(10, exponent)\n\t}\n\n\tvalue = math.Copysign(value, input)\n\n\tprefix := siPrefixTable[exponent]\n\treturn value, prefix\n}\n\n// SI returns a string with default formatting.\n//\n// SI uses Ftoa to format float value, removing trailing zeros.\n//\n// See also: ComputeSI, ParseSI.\n//\n// e.g. SI(1000000, \"B\") -> 1 MB\n// e.g. SI(2.2345e-12, \"F\") -> 2.2345 pF\nfunc SI(input float64, unit string) string {\n\tvalue, prefix := ComputeSI(input)\n\treturn Ftoa(value) + \" \" + prefix + unit\n}\n\n// SIWithDigits works like SI but limits the resulting string to the\n// given number of decimal places.\n//\n// e.g. SIWithDigits(1000000, 0, \"B\") -> 1 MB\n// e.g. SIWithDigits(2.2345e-12, 2, \"F\") -> 2.23 pF\nfunc SIWithDigits(input float64, decimals int, unit string) string {\n\tvalue, prefix := ComputeSI(input)\n\treturn FtoaWithDigits(value, decimals) + \" \" + prefix + unit\n}\n\nvar errInvalid = errors.New(\"invalid input\")\n\n// ParseSI parses an SI string back into the number and unit.\n//\n// See also: SI, ComputeSI.\n//\n// e.g. ParseSI(\"2.2345 pF\") -> (2.2345e-12, \"F\", nil)\nfunc ParseSI(input string) (float64, string, error) {\n\tfound := riParseRegex.FindStringSubmatch(input)\n\tif len(found) != 4 {\n\t\treturn 0, \"\", errInvalid\n\t}\n\tmag := revSIPrefixTable[found[2]]\n\tunit := found[3]\n\n\tbase, err := strconv.ParseFloat(found[1], 64)\n\treturn base * mag, unit, err\n}\n"
  },
  {
    "path": "vendor/github.com/dustin/go-humanize/times.go",
    "content": "package humanize\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"sort\"\n\t\"time\"\n)\n\n// Seconds-based time units\nconst (\n\tDay      = 24 * time.Hour\n\tWeek     = 7 * Day\n\tMonth    = 30 * Day\n\tYear     = 12 * Month\n\tLongTime = 37 * Year\n)\n\n// Time formats a time into a relative string.\n//\n// Time(someT) -> \"3 weeks ago\"\nfunc Time(then time.Time) string {\n\treturn RelTime(then, time.Now(), \"ago\", \"from now\")\n}\n\n// A RelTimeMagnitude struct contains a relative time point at which\n// the relative format of time will switch to a new format string.  A\n// slice of these in ascending order by their \"D\" field is passed to\n// CustomRelTime to format durations.\n//\n// The Format field is a string that may contain a \"%s\" which will be\n// replaced with the appropriate signed label (e.g. \"ago\" or \"from\n// now\") and a \"%d\" that will be replaced by the quantity.\n//\n// The DivBy field is the amount of time the time difference must be\n// divided by in order to display correctly.\n//\n// e.g. if D is 2*time.Minute and you want to display \"%d minutes %s\"\n// DivBy should be time.Minute so whatever the duration is will be\n// expressed in minutes.\ntype RelTimeMagnitude struct {\n\tD      time.Duration\n\tFormat string\n\tDivBy  time.Duration\n}\n\nvar defaultMagnitudes = []RelTimeMagnitude{\n\t{time.Second, \"now\", time.Second},\n\t{2 * time.Second, \"1 second %s\", 1},\n\t{time.Minute, \"%d seconds %s\", time.Second},\n\t{2 * time.Minute, \"1 minute %s\", 1},\n\t{time.Hour, \"%d minutes %s\", time.Minute},\n\t{2 * time.Hour, \"1 hour %s\", 1},\n\t{Day, \"%d hours %s\", time.Hour},\n\t{2 * Day, \"1 day %s\", 1},\n\t{Week, \"%d days %s\", Day},\n\t{2 * Week, \"1 week %s\", 1},\n\t{Month, \"%d weeks %s\", Week},\n\t{2 * Month, \"1 month %s\", 1},\n\t{Year, \"%d months %s\", Month},\n\t{18 * Month, \"1 year %s\", 1},\n\t{2 * Year, \"2 years %s\", 1},\n\t{LongTime, \"%d years %s\", Year},\n\t{math.MaxInt64, \"a long while %s\", 1},\n}\n\n// RelTime formats a time into a relative string.\n//\n// It takes two times and two labels.  In addition to the generic time\n// delta string (e.g. 5 minutes), the labels are used applied so that\n// the label corresponding to the smaller time is applied.\n//\n// RelTime(timeInPast, timeInFuture, \"earlier\", \"later\") -> \"3 weeks earlier\"\nfunc RelTime(a, b time.Time, albl, blbl string) string {\n\treturn CustomRelTime(a, b, albl, blbl, defaultMagnitudes)\n}\n\n// CustomRelTime formats a time into a relative string.\n//\n// It takes two times two labels and a table of relative time formats.\n// In addition to the generic time delta string (e.g. 5 minutes), the\n// labels are used applied so that the label corresponding to the\n// smaller time is applied.\nfunc CustomRelTime(a, b time.Time, albl, blbl string, magnitudes []RelTimeMagnitude) string {\n\tlbl := albl\n\tdiff := b.Sub(a)\n\n\tif a.After(b) {\n\t\tlbl = blbl\n\t\tdiff = a.Sub(b)\n\t}\n\n\tn := sort.Search(len(magnitudes), func(i int) bool {\n\t\treturn magnitudes[i].D > diff\n\t})\n\n\tif n >= len(magnitudes) {\n\t\tn = len(magnitudes) - 1\n\t}\n\tmag := magnitudes[n]\n\targs := []interface{}{}\n\tescaped := false\n\tfor _, ch := range mag.Format {\n\t\tif escaped {\n\t\t\tswitch ch {\n\t\t\tcase 's':\n\t\t\t\targs = append(args, lbl)\n\t\t\tcase 'd':\n\t\t\t\targs = append(args, diff/mag.DivBy)\n\t\t\t}\n\t\t\tescaped = false\n\t\t} else {\n\t\t\tescaped = ch == '%'\n\t\t}\n\t}\n\treturn fmt.Sprintf(mag.Format, args...)\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n\nrestful.html\n\n*.out\n\ntmp.prof\n\ngo-restful.test\n\nexamples/restful-basic-authentication\n\nexamples/restful-encoding-filter\n\nexamples/restful-filters\n\nexamples/restful-hello-world\n\nexamples/restful-resource-functions\n\nexamples/restful-serve-static\n\nexamples/restful-user-service\n\n*.DS_Store\nexamples/restful-user-resource\n\nexamples/restful-multi-containers\n\nexamples/restful-form-handling\n\nexamples/restful-CORS-filter\n\nexamples/restful-options-filter\n\nexamples/restful-curly-router\n\nexamples/restful-cpuprofiler-service\n\nexamples/restful-pre-post-filters\n\ncurly.prof\n\nexamples/restful-NCSA-logging\n\nexamples/restful-html-template\n\ns.html\nrestful-path-tail\n.idea\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/.goconvey",
    "content": "ignore"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.x\n\nbefore_install:\n  - go test -v\n\nscript:\n  - go test -race -coverprofile=coverage.txt -covermode=atomic\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/CHANGES.md",
    "content": "# Change history of go-restful\n\n## [v3.10.1] - 2022-11-19\n\n- fix broken 3.10.0 by using path package for joining paths\n\n## [v3.10.0] - 2022-10-11 - BROKEN\n\n- changed tokenizer to match std route match behavior; do not trimright the path (#511)\n- Add MIME_ZIP (#512)\n- Add MIME_ZIP and HEADER_ContentDisposition (#513)\n- Changed how to get query parameter issue #510\n\n## [v3.9.0] - 2022-07-21\n\n- add support for http.Handler implementations to work as FilterFunction, issue #504 (thanks to https://github.com/ggicci)\n\n## [v3.8.0] - 2022-06-06\n\n- use exact matching of allowed domain entries, issue #489 (#493)\n\t- this changes fixes [security] Authorization Bypass Through User-Controlled Key\n\t  by changing the behaviour of the AllowedDomains setting in the CORS filter.\n\t  To support the previous behaviour, the CORS filter type now has a AllowedDomainFunc\n\t  callback mechanism which is called when a simple domain match fails. \n- add test and fix for POST without body and Content-type, issue #492 (#496)\n- [Minor] Bad practice to have a mix of Receiver types. (#491)\n\n## [v3.7.2] - 2021-11-24\n\n- restored FilterChain (#482 by SVilgelm)\n\n\n## [v3.7.1] - 2021-10-04\n\n- fix problem with contentEncodingEnabled setting (#479)\n\n## [v3.7.0] - 2021-09-24\n\n- feat(parameter): adds additional openapi mappings (#478)\n\n## [v3.6.0] - 2021-09-18\n\n- add support for vendor extensions (#477 thx erraggy)\n\n## [v3.5.2] - 2021-07-14\n\n- fix removing absent route from webservice (#472)\n\n## [v3.5.1] - 2021-04-12\n\n- fix handling no match access selected path\n- remove obsolete field\n\n## [v3.5.0] - 2021-04-10\n\n- add check for wildcard (#463) in CORS\n- add access to Route from Request, issue #459 (#462)\n\n## [v3.4.0] - 2020-11-10\n\n- Added OPTIONS to WebService\n\n## [v3.3.2] - 2020-01-23\n\n- Fixed duplicate compression in dispatch. #449\n\n\n## [v3.3.1] - 2020-08-31\n\n- Added check on writer to prevent compression of response twice. #447\n\n## [v3.3.0] - 2020-08-19\n\n- Enable content encoding on Handle and ServeHTTP (#446)\n- List available representations in 406 body (#437)\n- Convert to string using rune() (#443)\n\n## [v3.2.0] - 2020-06-21\n\n- 405 Method Not Allowed must have Allow header (#436) (thx Bracken <abdawson@gmail.com>)\n- add field allowedMethodsWithoutContentType (#424)\n\n## [v3.1.0]\n\n- support describing response headers (#426)\n- fix openapi examples (#425)\n\nv3.0.0\n\n- fix: use request/response resulting from filter chain\n- add Go module\n  Module consumer should use github.com/emicklei/go-restful/v3 as import path\n\nv2.10.0\n\n- support for Custom Verbs (thanks Vinci Xu <277040271@qq.com>)\n- fixed static example (thanks Arthur <yang_yapo@126.com>)\n- simplify code (thanks Christian Muehlhaeuser <muesli@gmail.com>)\n- added JWT HMAC with SHA-512 authentication code example (thanks Amim Knabben <amim.knabben@gmail.com>)\n\nv2.9.6\n\n- small optimization in filter code\n\nv2.11.1\n\n- fix WriteError return value (#415)\n\nv2.11.0 \n\n- allow prefix and suffix in path variable expression (#414)\n\nv2.9.6\n\n- support google custome verb (#413)\n\nv2.9.5\n\n- fix panic in Response.WriteError if err == nil\n\nv2.9.4\n\n- fix issue #400 , parsing mime type quality\n- Route Builder added option for contentEncodingEnabled (#398)\n\nv2.9.3\n\n- Avoid return of 415 Unsupported Media Type when request body is empty (#396)\n\nv2.9.2\n\n- Reduce allocations in per-request methods to improve performance (#395)\n\nv2.9.1\n\n- Fix issue with default responses and invalid status code 0. (#393)\n\nv2.9.0\n\n- add per Route content encoding setting (overrides container setting)\n\nv2.8.0\n\n- add Request.QueryParameters()\n- add json-iterator (via build tag)\n- disable vgo module (until log is moved)\n\nv2.7.1\n\n- add vgo module\n\nv2.6.1\n\n- add JSONNewDecoderFunc to allow custom JSON Decoder usage (go 1.10+)\n\nv2.6.0\n\n- Make JSR 311 routing and path param processing consistent\n- Adding description to RouteBuilder.Reads()\n- Update example for Swagger12 and OpenAPI\n\n2017-09-13\n\n- added route condition functions using `.If(func)` in route building.\n\n2017-02-16\n\n- solved issue #304, make operation names unique\n\n2017-01-30\n \n\t[IMPORTANT] For swagger users, change your import statement to:\t\n\tswagger \"github.com/emicklei/go-restful-swagger12\"\n\n- moved swagger 1.2 code to go-restful-swagger12\n- created TAG 2.0.0\n\n2017-01-27\n\n- remove defer request body close\n- expose Dispatch for testing filters and Routefunctions\n- swagger response model cannot be array \n- created TAG 1.0.0\n\n2016-12-22\n\n- (API change) Remove code related to caching request content. Removes SetCacheReadEntity(doCache bool)\n\n2016-11-26\n\n- Default change! now use CurlyRouter (was RouterJSR311)\n- Default change! no more caching of request content\n- Default change! do not recover from panics\n\n2016-09-22\n\n- fix the DefaultRequestContentType feature\n\n2016-02-14\n\n- take the qualify factor of the Accept header mediatype into account when deciding the contentype of the response\n- add constructors for custom entity accessors for xml and json \n\n2015-09-27\n\n- rename new WriteStatusAnd... to WriteHeaderAnd... for consistency\n\n2015-09-25\n\n- fixed problem with changing Header after WriteHeader (issue 235)\n\n2015-09-14\n\n- changed behavior of WriteHeader (immediate write) and WriteEntity (no status write)\n- added support for custom EntityReaderWriters.\n\n2015-08-06\n\n- add support for reading entities from compressed request content\n- use sync.Pool for compressors of http response and request body\n- add Description to Parameter for documentation in Swagger UI\n\n2015-03-20\n\n- add configurable logging\n\n2015-03-18\n\n- if not specified, the Operation is derived from the Route function\n\n2015-03-17\n\n- expose Parameter creation functions\n- make trace logger an interface\n- fix OPTIONSFilter\n- customize rendering of ServiceError\n- JSR311 router now handles wildcards\n- add Notes to Route\n\n2014-11-27\n\n- (api add) PrettyPrint per response. (as proposed in #167)\n\n2014-11-12\n\n- (api add) ApiVersion(.) for documentation in Swagger UI\n\n2014-11-10\n\n- (api change) struct fields tagged with \"description\" show up in Swagger UI\n\n2014-10-31\n\n- (api change) ReturnsError -> Returns\n- (api add)    RouteBuilder.Do(aBuilder) for DRY use of RouteBuilder\n- fix swagger nested structs\n- sort Swagger response messages by code\n\n2014-10-23\n\n- (api add) ReturnsError allows you to document Http codes in swagger\n- fixed problem with greedy CurlyRouter\n- (api add) Access-Control-Max-Age in CORS\n- add tracing functionality (injectable) for debugging purposes\n- support JSON parse 64bit int \n- fix empty parameters for swagger\n- WebServicesUrl is now optional for swagger\n- fixed duplicate AccessControlAllowOrigin in CORS\n- (api change) expose ServeMux in container\n- (api add) added AllowedDomains in CORS\n- (api add) ParameterNamed for detailed documentation\n\n2014-04-16\n\n- (api add) expose constructor of Request for testing.\n\n2014-06-27\n\n- (api add) ParameterNamed gives access to a Parameter definition and its data (for further specification).\n- (api add) SetCacheReadEntity allow scontrol over whether or not the request body is being cached (default true for compatibility reasons).\n\n2014-07-03\n\n- (api add) CORS can be configured with a list of allowed domains\n\n2014-03-12\n\n- (api add) Route path parameters can use wildcard or regular expressions. (requires CurlyRouter)\n\n2014-02-26\n\n- (api add) Request now provides information about the matched Route, see method SelectedRoutePath \n\n2014-02-17\n\n- (api change) renamed parameter constants (go-lint checks)\n\n2014-01-10\n\n- (api add) support for CloseNotify, see http://golang.org/pkg/net/http/#CloseNotifier\n\n2014-01-07\n\n- (api change) Write* methods in Response now return the error or nil.\n- added example of serving HTML from a Go template.\n- fixed comparing Allowed headers in CORS (is now case-insensitive)\n\n2013-11-13\n\n- (api add) Response knows how many bytes are written to the response body.\n\n2013-10-29\n\n- (api add) RecoverHandler(handler RecoverHandleFunction) to change how panic recovery is handled. Default behavior is to log and return a stacktrace. This may be a security issue as it exposes sourcecode information.\n\n2013-10-04\n\n- (api add) Response knows what HTTP status has been written\n- (api add) Request can have attributes (map of string->interface, also called request-scoped variables\n\n2013-09-12\n\n- (api change) Router interface simplified\n- Implemented CurlyRouter, a Router that does not use|allow regular expressions in paths\n\n2013-08-05\n - add OPTIONS support\n - add CORS support\n\n2013-08-27\n\n- fixed some reported issues (see github)\n- (api change) deprecated use of WriteError; use WriteErrorString instead\n\n2014-04-15\n\n- (fix) v1.0.1 tag: fix Issue 111: WriteErrorString\n\n2013-08-08\n\n- (api add) Added implementation Container: a WebServices collection with its own http.ServeMux allowing multiple endpoints per program. Existing uses of go-restful will register their services to the DefaultContainer.\n- (api add) the swagger package has be extended to have a UI per container.\n- if panic is detected then a small stack trace is printed (thanks to runner-mei)\n- (api add) WriteErrorString to Response\n\nImportant API changes:\n\n- (api remove) package variable DoNotRecover no longer works ; use restful.DefaultContainer.DoNotRecover(true) instead.\n- (api remove) package variable EnableContentEncoding no longer works ; use restful.DefaultContainer.EnableContentEncoding(true) instead.\n \n \n2013-07-06\n\n- (api add) Added support for response encoding (gzip and deflate(zlib)). This feature is disabled on default (for backwards compatibility). Use restful.EnableContentEncoding = true in your initialization to enable this feature.\n\n2013-06-19\n\n- (improve) DoNotRecover option, moved request body closer, improved ReadEntity\n\n2013-06-03\n\n- (api change) removed Dispatcher interface, hide PathExpression\n- changed receiver names of type functions to be more idiomatic Go\n\n2013-06-02\n\n- (optimize) Cache the RegExp compilation of Paths.\n\n2013-05-22\n\t\n- (api add) Added support for request/response filter functions\n\n2013-05-18\n\n\n- (api add) Added feature to change the default Http Request Dispatch function (travis cline)\n- (api change) Moved Swagger Webservice to swagger package (see example restful-user)\n\n[2012-11-14 .. 2013-05-18>\n \n- See https://github.com/emicklei/go-restful/commits\n\n2012-11-14\n\n- Initial commit\n\n\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/LICENSE",
    "content": "Copyright (c) 2012,2013 Ernest Micklei\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/Makefile",
    "content": "all: test\n\ntest:\n\tgo vet .\n\tgo test -cover -v .\n\nex:\n\tfind ./examples -type f -name \"*.go\" | xargs -I {} go build -o /tmp/ignore {}"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/README.md",
    "content": "go-restful\n==========\npackage for building REST-style Web Services using Google Go\n\n[![Build Status](https://travis-ci.org/emicklei/go-restful.png)](https://travis-ci.org/emicklei/go-restful)\n[![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful)\n[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful)\n[![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful)\n\n- [Code examples use v3](https://github.com/emicklei/go-restful/tree/v3/examples)\n\nREST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:\n\n- GET = Retrieve a representation of a resource\n- POST = Create if you are sending content to the server to create a subordinate of the specified resource collection, using some server-side algorithm.\n- PUT = Create if you are sending the full content of the specified resource (URI).\n- PUT = Update if you are updating the full content of the specified resource.\n- DELETE = Delete if you are requesting the server to delete the resource\n- PATCH = Update partial content of a resource\n- OPTIONS = Get information about the communication options for the request URI\n    \n### Usage\n\n#### Without Go Modules\n\nAll versions up to `v2.*.*` (on the master) are not supporting Go modules.\n\n```\nimport (\n\trestful \"github.com/emicklei/go-restful\"\n)\n```\n\n#### Using Go Modules\n\nAs of version `v3.0.0` (on the v3 branch), this package supports Go modules.\n\n```\nimport (\n\trestful \"github.com/emicklei/go-restful/v3\"\n)\n```\n\n### Example\n\n```Go\nws := new(restful.WebService)\nws.\n\tPath(\"/users\").\n\tConsumes(restful.MIME_XML, restful.MIME_JSON).\n\tProduces(restful.MIME_JSON, restful.MIME_XML)\n\nws.Route(ws.GET(\"/{user-id}\").To(u.findUser).\n\tDoc(\"get a user\").\n\tParam(ws.PathParameter(\"user-id\", \"identifier of the user\").DataType(\"string\")).\n\tWrites(User{}))\t\t\n...\n\t\nfunc (u UserResource) findUser(request *restful.Request, response *restful.Response) {\n\tid := request.PathParameter(\"user-id\")\n\t...\n}\n```\n\t\n[Full API of a UserResource](https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go) \n\t\t\n### Features\n\n- Routes for request &#8594; function mapping with path parameter (e.g. {id} but also prefix_{var} and {var}_suffix) support\n- Configurable router:\n\t- (default) Fast routing algorithm that allows static elements, [google custom method](https://cloud.google.com/apis/design/custom_methods), regular expressions and dynamic parameters in the URL path (e.g. /resource/name:customVerb, /meetings/{id} or /static/{subpath:*})\n\t- Routing algorithm after [JSR311](http://jsr311.java.net/nonav/releases/1.1/spec/spec.html) that is implemented using (but does **not** accept) regular expressions\n- Request API for reading structs from JSON/XML and accessing parameters (path,query,header)\n- Response API for writing structs to JSON/XML and setting headers\n- Customizable encoding using EntityReaderWriter registration\n- Filters for intercepting the request &#8594; response flow on Service or Route level\n- Request-scoped variables using attributes\n- Containers for WebServices on different HTTP endpoints\n- Content encoding (gzip,deflate) of request and response payloads\n- Automatic responses on OPTIONS (using a filter)\n- Automatic CORS request handling (using a filter)\n- API declaration for Swagger UI ([go-restful-openapi](https://github.com/emicklei/go-restful-openapi), see [go-restful-swagger12](https://github.com/emicklei/go-restful-swagger12))\n- Panic recovery to produce HTTP 500, customizable using RecoverHandler(...)\n- Route errors produce HTTP 404/405/406/415 errors, customizable using ServiceErrorHandler(...)\n- Configurable (trace) logging\n- Customizable gzip/deflate readers and writers using CompressorProvider registration\n- Inject your own http.Handler using the `HttpMiddlewareHandlerToFilter` function\n\n## How to customize\nThere are several hooks to customize the behavior of the go-restful package.\n\n- Router algorithm\n- Panic recovery\n- JSON decoder\n- Trace logging\n- Compression\n- Encoders for other serializers\n- Use [jsoniter](https://github.com/json-iterator/go) by building this package using a build tag, e.g. `go build -tags=jsoniter .` \n\n## Resources\n\n- [Example programs](./examples)\n- [Example posted on blog](http://ernestmicklei.com/2012/11/go-restful-first-working-example/)\n- [Design explained on blog](http://ernestmicklei.com/2012/11/go-restful-api-design/)\n- [sourcegraph](https://sourcegraph.com/github.com/emicklei/go-restful)\n- [showcase: Zazkia - tcp proxy for testing resiliency](https://github.com/emicklei/zazkia)\n- [showcase: Mora - MongoDB REST Api server](https://github.com/emicklei/mora)\n\nType ```git shortlog -s``` for a full list of contributors.\n\n© 2012 - 2022, http://ernestmicklei.com. MIT License. Contributions are welcome.\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\n| Version | Supported          |\n| ------- | ------------------ |\n| v3.7.x     | :white_check_mark: |\n| < v3.0.1   | :x:                |\n\n## Reporting a Vulnerability\n\nCreate an Issue and put the label `[security]` in the title of the issue.\nValid reported security issues are expected to be solved within a week.\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/Srcfile",
    "content": "{\"SkipDirs\": [\"examples\"]}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/bench_test.sh",
    "content": "#go test -run=none -file bench_test.go -test.bench . -cpuprofile=bench_test.out\n\ngo test -c\n./go-restful.test -test.run=none -test.cpuprofile=tmp.prof -test.bench=BenchmarkMany\n./go-restful.test -test.run=none -test.cpuprofile=curly.prof -test.bench=BenchmarkManyCurly\n\n#go tool pprof go-restful.test tmp.prof\ngo tool pprof go-restful.test curly.prof\n\n\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/compress.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"bufio\"\n\t\"compress/gzip\"\n\t\"compress/zlib\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// OBSOLETE : use restful.DefaultContainer.EnableContentEncoding(true) to change this setting.\nvar EnableContentEncoding = false\n\n// CompressingResponseWriter is a http.ResponseWriter that can perform content encoding (gzip and zlib)\ntype CompressingResponseWriter struct {\n\twriter     http.ResponseWriter\n\tcompressor io.WriteCloser\n\tencoding   string\n}\n\n// Header is part of http.ResponseWriter interface\nfunc (c *CompressingResponseWriter) Header() http.Header {\n\treturn c.writer.Header()\n}\n\n// WriteHeader is part of http.ResponseWriter interface\nfunc (c *CompressingResponseWriter) WriteHeader(status int) {\n\tc.writer.WriteHeader(status)\n}\n\n// Write is part of http.ResponseWriter interface\n// It is passed through the compressor\nfunc (c *CompressingResponseWriter) Write(bytes []byte) (int, error) {\n\tif c.isCompressorClosed() {\n\t\treturn -1, errors.New(\"Compressing error: tried to write data using closed compressor\")\n\t}\n\treturn c.compressor.Write(bytes)\n}\n\n// CloseNotify is part of http.CloseNotifier interface\nfunc (c *CompressingResponseWriter) CloseNotify() <-chan bool {\n\treturn c.writer.(http.CloseNotifier).CloseNotify()\n}\n\n// Close the underlying compressor\nfunc (c *CompressingResponseWriter) Close() error {\n\tif c.isCompressorClosed() {\n\t\treturn errors.New(\"Compressing error: tried to close already closed compressor\")\n\t}\n\n\tc.compressor.Close()\n\tif ENCODING_GZIP == c.encoding {\n\t\tcurrentCompressorProvider.ReleaseGzipWriter(c.compressor.(*gzip.Writer))\n\t}\n\tif ENCODING_DEFLATE == c.encoding {\n\t\tcurrentCompressorProvider.ReleaseZlibWriter(c.compressor.(*zlib.Writer))\n\t}\n\t// gc hint needed?\n\tc.compressor = nil\n\treturn nil\n}\n\nfunc (c *CompressingResponseWriter) isCompressorClosed() bool {\n\treturn nil == c.compressor\n}\n\n// Hijack implements the Hijacker interface\n// This is especially useful when combining Container.EnabledContentEncoding\n// in combination with websockets (for instance gorilla/websocket)\nfunc (c *CompressingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\thijacker, ok := c.writer.(http.Hijacker)\n\tif !ok {\n\t\treturn nil, nil, errors.New(\"ResponseWriter doesn't support Hijacker interface\")\n\t}\n\treturn hijacker.Hijack()\n}\n\n// WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested.\n// It also inspects the httpWriter whether its content-encoding is already set (non-empty).\nfunc wantsCompressedResponse(httpRequest *http.Request, httpWriter http.ResponseWriter) (bool, string) {\n\tif contentEncoding := httpWriter.Header().Get(HEADER_ContentEncoding); contentEncoding != \"\" {\n\t\treturn false, \"\"\n\t}\n\theader := httpRequest.Header.Get(HEADER_AcceptEncoding)\n\tgi := strings.Index(header, ENCODING_GZIP)\n\tzi := strings.Index(header, ENCODING_DEFLATE)\n\t// use in order of appearance\n\tif gi == -1 {\n\t\treturn zi != -1, ENCODING_DEFLATE\n\t} else if zi == -1 {\n\t\treturn gi != -1, ENCODING_GZIP\n\t} else {\n\t\tif gi < zi {\n\t\t\treturn true, ENCODING_GZIP\n\t\t}\n\t\treturn true, ENCODING_DEFLATE\n\t}\n}\n\n// NewCompressingResponseWriter create a CompressingResponseWriter for a known encoding = {gzip,deflate}\nfunc NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding string) (*CompressingResponseWriter, error) {\n\thttpWriter.Header().Set(HEADER_ContentEncoding, encoding)\n\tc := new(CompressingResponseWriter)\n\tc.writer = httpWriter\n\tvar err error\n\tif ENCODING_GZIP == encoding {\n\t\tw := currentCompressorProvider.AcquireGzipWriter()\n\t\tw.Reset(httpWriter)\n\t\tc.compressor = w\n\t\tc.encoding = ENCODING_GZIP\n\t} else if ENCODING_DEFLATE == encoding {\n\t\tw := currentCompressorProvider.AcquireZlibWriter()\n\t\tw.Reset(httpWriter)\n\t\tc.compressor = w\n\t\tc.encoding = ENCODING_DEFLATE\n\t} else {\n\t\treturn nil, errors.New(\"Unknown encoding:\" + encoding)\n\t}\n\treturn c, err\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/compressor_cache.go",
    "content": "package restful\n\n// Copyright 2015 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"compress/gzip\"\n\t\"compress/zlib\"\n)\n\n// BoundedCachedCompressors is a CompressorProvider that uses a cache with a fixed amount\n// of writers and readers (resources).\n// If a new resource is acquired and all are in use, it will return a new unmanaged resource.\ntype BoundedCachedCompressors struct {\n\tgzipWriters     chan *gzip.Writer\n\tgzipReaders     chan *gzip.Reader\n\tzlibWriters     chan *zlib.Writer\n\twritersCapacity int\n\treadersCapacity int\n}\n\n// NewBoundedCachedCompressors returns a new, with filled cache,  BoundedCachedCompressors.\nfunc NewBoundedCachedCompressors(writersCapacity, readersCapacity int) *BoundedCachedCompressors {\n\tb := &BoundedCachedCompressors{\n\t\tgzipWriters:     make(chan *gzip.Writer, writersCapacity),\n\t\tgzipReaders:     make(chan *gzip.Reader, readersCapacity),\n\t\tzlibWriters:     make(chan *zlib.Writer, writersCapacity),\n\t\twritersCapacity: writersCapacity,\n\t\treadersCapacity: readersCapacity,\n\t}\n\tfor ix := 0; ix < writersCapacity; ix++ {\n\t\tb.gzipWriters <- newGzipWriter()\n\t\tb.zlibWriters <- newZlibWriter()\n\t}\n\tfor ix := 0; ix < readersCapacity; ix++ {\n\t\tb.gzipReaders <- newGzipReader()\n\t}\n\treturn b\n}\n\n// AcquireGzipWriter returns an resettable *gzip.Writer. Needs to be released.\nfunc (b *BoundedCachedCompressors) AcquireGzipWriter() *gzip.Writer {\n\tvar writer *gzip.Writer\n\tselect {\n\tcase writer, _ = <-b.gzipWriters:\n\tdefault:\n\t\t// return a new unmanaged one\n\t\twriter = newGzipWriter()\n\t}\n\treturn writer\n}\n\n// ReleaseGzipWriter accepts a writer (does not have to be one that was cached)\n// only when the cache has room for it. It will ignore it otherwise.\nfunc (b *BoundedCachedCompressors) ReleaseGzipWriter(w *gzip.Writer) {\n\t// forget the unmanaged ones\n\tif len(b.gzipWriters) < b.writersCapacity {\n\t\tb.gzipWriters <- w\n\t}\n}\n\n// AcquireGzipReader returns a *gzip.Reader. Needs to be released.\nfunc (b *BoundedCachedCompressors) AcquireGzipReader() *gzip.Reader {\n\tvar reader *gzip.Reader\n\tselect {\n\tcase reader, _ = <-b.gzipReaders:\n\tdefault:\n\t\t// return a new unmanaged one\n\t\treader = newGzipReader()\n\t}\n\treturn reader\n}\n\n// ReleaseGzipReader accepts a reader (does not have to be one that was cached)\n// only when the cache has room for it. It will ignore it otherwise.\nfunc (b *BoundedCachedCompressors) ReleaseGzipReader(r *gzip.Reader) {\n\t// forget the unmanaged ones\n\tif len(b.gzipReaders) < b.readersCapacity {\n\t\tb.gzipReaders <- r\n\t}\n}\n\n// AcquireZlibWriter returns an resettable *zlib.Writer. Needs to be released.\nfunc (b *BoundedCachedCompressors) AcquireZlibWriter() *zlib.Writer {\n\tvar writer *zlib.Writer\n\tselect {\n\tcase writer, _ = <-b.zlibWriters:\n\tdefault:\n\t\t// return a new unmanaged one\n\t\twriter = newZlibWriter()\n\t}\n\treturn writer\n}\n\n// ReleaseZlibWriter accepts a writer (does not have to be one that was cached)\n// only when the cache has room for it. It will ignore it otherwise.\nfunc (b *BoundedCachedCompressors) ReleaseZlibWriter(w *zlib.Writer) {\n\t// forget the unmanaged ones\n\tif len(b.zlibWriters) < b.writersCapacity {\n\t\tb.zlibWriters <- w\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/compressor_pools.go",
    "content": "package restful\n\n// Copyright 2015 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"compress/zlib\"\n\t\"sync\"\n)\n\n// SyncPoolCompessors is a CompressorProvider that use the standard sync.Pool.\ntype SyncPoolCompessors struct {\n\tGzipWriterPool *sync.Pool\n\tGzipReaderPool *sync.Pool\n\tZlibWriterPool *sync.Pool\n}\n\n// NewSyncPoolCompessors returns a new (\"empty\") SyncPoolCompessors.\nfunc NewSyncPoolCompessors() *SyncPoolCompessors {\n\treturn &SyncPoolCompessors{\n\t\tGzipWriterPool: &sync.Pool{\n\t\t\tNew: func() interface{} { return newGzipWriter() },\n\t\t},\n\t\tGzipReaderPool: &sync.Pool{\n\t\t\tNew: func() interface{} { return newGzipReader() },\n\t\t},\n\t\tZlibWriterPool: &sync.Pool{\n\t\t\tNew: func() interface{} { return newZlibWriter() },\n\t\t},\n\t}\n}\n\nfunc (s *SyncPoolCompessors) AcquireGzipWriter() *gzip.Writer {\n\treturn s.GzipWriterPool.Get().(*gzip.Writer)\n}\n\nfunc (s *SyncPoolCompessors) ReleaseGzipWriter(w *gzip.Writer) {\n\ts.GzipWriterPool.Put(w)\n}\n\nfunc (s *SyncPoolCompessors) AcquireGzipReader() *gzip.Reader {\n\treturn s.GzipReaderPool.Get().(*gzip.Reader)\n}\n\nfunc (s *SyncPoolCompessors) ReleaseGzipReader(r *gzip.Reader) {\n\ts.GzipReaderPool.Put(r)\n}\n\nfunc (s *SyncPoolCompessors) AcquireZlibWriter() *zlib.Writer {\n\treturn s.ZlibWriterPool.Get().(*zlib.Writer)\n}\n\nfunc (s *SyncPoolCompessors) ReleaseZlibWriter(w *zlib.Writer) {\n\ts.ZlibWriterPool.Put(w)\n}\n\nfunc newGzipWriter() *gzip.Writer {\n\t// create with an empty bytes writer; it will be replaced before using the gzipWriter\n\twriter, err := gzip.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\treturn writer\n}\n\nfunc newGzipReader() *gzip.Reader {\n\t// create with an empty reader (but with GZIP header); it will be replaced before using the gzipReader\n\t// we can safely use currentCompressProvider because it is set on package initialization.\n\tw := currentCompressorProvider.AcquireGzipWriter()\n\tdefer currentCompressorProvider.ReleaseGzipWriter(w)\n\tb := new(bytes.Buffer)\n\tw.Reset(b)\n\tw.Flush()\n\tw.Close()\n\treader, err := gzip.NewReader(bytes.NewReader(b.Bytes()))\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\treturn reader\n}\n\nfunc newZlibWriter() *zlib.Writer {\n\twriter, err := zlib.NewWriterLevel(new(bytes.Buffer), gzip.BestSpeed)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\treturn writer\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/compressors.go",
    "content": "package restful\n\n// Copyright 2015 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"compress/gzip\"\n\t\"compress/zlib\"\n)\n\n// CompressorProvider describes a component that can provider compressors for the std methods.\ntype CompressorProvider interface {\n\t// Returns a *gzip.Writer which needs to be released later.\n\t// Before using it, call Reset().\n\tAcquireGzipWriter() *gzip.Writer\n\n\t// Releases an acquired *gzip.Writer.\n\tReleaseGzipWriter(w *gzip.Writer)\n\n\t// Returns a *gzip.Reader which needs to be released later.\n\tAcquireGzipReader() *gzip.Reader\n\n\t// Releases an acquired *gzip.Reader.\n\tReleaseGzipReader(w *gzip.Reader)\n\n\t// Returns a *zlib.Writer which needs to be released later.\n\t// Before using it, call Reset().\n\tAcquireZlibWriter() *zlib.Writer\n\n\t// Releases an acquired *zlib.Writer.\n\tReleaseZlibWriter(w *zlib.Writer)\n}\n\n// DefaultCompressorProvider is the actual provider of compressors (zlib or gzip).\nvar currentCompressorProvider CompressorProvider\n\nfunc init() {\n\tcurrentCompressorProvider = NewSyncPoolCompessors()\n}\n\n// CurrentCompressorProvider returns the current CompressorProvider.\n// It is initialized using a SyncPoolCompessors.\nfunc CurrentCompressorProvider() CompressorProvider {\n\treturn currentCompressorProvider\n}\n\n// SetCompressorProvider sets the actual provider of compressors (zlib or gzip).\nfunc SetCompressorProvider(p CompressorProvider) {\n\tif p == nil {\n\t\tpanic(\"cannot set compressor provider to nil\")\n\t}\n\tcurrentCompressorProvider = p\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/constants.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nconst (\n\tMIME_XML   = \"application/xml\"          // Accept or Content-Type used in Consumes() and/or Produces()\n\tMIME_JSON  = \"application/json\"         // Accept or Content-Type used in Consumes() and/or Produces()\n\tMIME_ZIP   = \"application/zip\"          // Accept or Content-Type used in Consumes() and/or Produces()\n\tMIME_OCTET = \"application/octet-stream\" // If Content-Type is not present in request, use the default\n\n\tHEADER_Allow                         = \"Allow\"\n\tHEADER_Accept                        = \"Accept\"\n\tHEADER_Origin                        = \"Origin\"\n\tHEADER_ContentType                   = \"Content-Type\"\n\tHEADER_ContentDisposition            = \"Content-Disposition\"\n\tHEADER_LastModified                  = \"Last-Modified\"\n\tHEADER_AcceptEncoding                = \"Accept-Encoding\"\n\tHEADER_ContentEncoding               = \"Content-Encoding\"\n\tHEADER_AccessControlExposeHeaders    = \"Access-Control-Expose-Headers\"\n\tHEADER_AccessControlRequestMethod    = \"Access-Control-Request-Method\"\n\tHEADER_AccessControlRequestHeaders   = \"Access-Control-Request-Headers\"\n\tHEADER_AccessControlAllowMethods     = \"Access-Control-Allow-Methods\"\n\tHEADER_AccessControlAllowOrigin      = \"Access-Control-Allow-Origin\"\n\tHEADER_AccessControlAllowCredentials = \"Access-Control-Allow-Credentials\"\n\tHEADER_AccessControlAllowHeaders     = \"Access-Control-Allow-Headers\"\n\tHEADER_AccessControlMaxAge           = \"Access-Control-Max-Age\"\n\n\tENCODING_GZIP    = \"gzip\"\n\tENCODING_DEFLATE = \"deflate\"\n)\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/container.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/emicklei/go-restful/v3/log\"\n)\n\n// Container holds a collection of WebServices and a http.ServeMux to dispatch http requests.\n// The requests are further dispatched to routes of WebServices using a RouteSelector\ntype Container struct {\n\twebServicesLock        sync.RWMutex\n\twebServices            []*WebService\n\tServeMux               *http.ServeMux\n\tisRegisteredOnRoot     bool\n\tcontainerFilters       []FilterFunction\n\tdoNotRecover           bool // default is true\n\trecoverHandleFunc      RecoverHandleFunction\n\tserviceErrorHandleFunc ServiceErrorHandleFunction\n\trouter                 RouteSelector // default is a CurlyRouter (RouterJSR311 is a slower alternative)\n\tcontentEncodingEnabled bool          // default is false\n}\n\n// NewContainer creates a new Container using a new ServeMux and default router (CurlyRouter)\nfunc NewContainer() *Container {\n\treturn &Container{\n\t\twebServices:            []*WebService{},\n\t\tServeMux:               http.NewServeMux(),\n\t\tisRegisteredOnRoot:     false,\n\t\tcontainerFilters:       []FilterFunction{},\n\t\tdoNotRecover:           true,\n\t\trecoverHandleFunc:      logStackOnRecover,\n\t\tserviceErrorHandleFunc: writeServiceError,\n\t\trouter:                 CurlyRouter{},\n\t\tcontentEncodingEnabled: false}\n}\n\n// RecoverHandleFunction declares functions that can be used to handle a panic situation.\n// The first argument is what recover() returns. The second must be used to communicate an error response.\ntype RecoverHandleFunction func(interface{}, http.ResponseWriter)\n\n// RecoverHandler changes the default function (logStackOnRecover) to be called\n// when a panic is detected. DoNotRecover must be have its default value (=false).\nfunc (c *Container) RecoverHandler(handler RecoverHandleFunction) {\n\tc.recoverHandleFunc = handler\n}\n\n// ServiceErrorHandleFunction declares functions that can be used to handle a service error situation.\n// The first argument is the service error, the second is the request that resulted in the error and\n// the third must be used to communicate an error response.\ntype ServiceErrorHandleFunction func(ServiceError, *Request, *Response)\n\n// ServiceErrorHandler changes the default function (writeServiceError) to be called\n// when a ServiceError is detected.\nfunc (c *Container) ServiceErrorHandler(handler ServiceErrorHandleFunction) {\n\tc.serviceErrorHandleFunc = handler\n}\n\n// DoNotRecover controls whether panics will be caught to return HTTP 500.\n// If set to true, Route functions are responsible for handling any error situation.\n// Default value is true.\nfunc (c *Container) DoNotRecover(doNot bool) {\n\tc.doNotRecover = doNot\n}\n\n// Router changes the default Router (currently CurlyRouter)\nfunc (c *Container) Router(aRouter RouteSelector) {\n\tc.router = aRouter\n}\n\n// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses.\nfunc (c *Container) EnableContentEncoding(enabled bool) {\n\tc.contentEncodingEnabled = enabled\n}\n\n// Add a WebService to the Container. It will detect duplicate root paths and exit in that case.\nfunc (c *Container) Add(service *WebService) *Container {\n\tc.webServicesLock.Lock()\n\tdefer c.webServicesLock.Unlock()\n\n\t// if rootPath was not set then lazy initialize it\n\tif len(service.rootPath) == 0 {\n\t\tservice.Path(\"/\")\n\t}\n\n\t// cannot have duplicate root paths\n\tfor _, each := range c.webServices {\n\t\tif each.RootPath() == service.RootPath() {\n\t\t\tlog.Printf(\"WebService with duplicate root path detected:['%v']\", each)\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n\n\t// If not registered on root then add specific mapping\n\tif !c.isRegisteredOnRoot {\n\t\tc.isRegisteredOnRoot = c.addHandler(service, c.ServeMux)\n\t}\n\tc.webServices = append(c.webServices, service)\n\treturn c\n}\n\n// addHandler may set a new HandleFunc for the serveMux\n// this function must run inside the critical region protected by the webServicesLock.\n// returns true if the function was registered on root (\"/\")\nfunc (c *Container) addHandler(service *WebService, serveMux *http.ServeMux) bool {\n\tpattern := fixedPrefixPath(service.RootPath())\n\t// check if root path registration is needed\n\tif \"/\" == pattern || \"\" == pattern {\n\t\tserveMux.HandleFunc(\"/\", c.dispatch)\n\t\treturn true\n\t}\n\t// detect if registration already exists\n\talreadyMapped := false\n\tfor _, each := range c.webServices {\n\t\tif each.RootPath() == service.RootPath() {\n\t\t\talreadyMapped = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !alreadyMapped {\n\t\tserveMux.HandleFunc(pattern, c.dispatch)\n\t\tif !strings.HasSuffix(pattern, \"/\") {\n\t\t\tserveMux.HandleFunc(pattern+\"/\", c.dispatch)\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Container) Remove(ws *WebService) error {\n\tif c.ServeMux == http.DefaultServeMux {\n\t\terrMsg := fmt.Sprintf(\"cannot remove a WebService from a Container using the DefaultServeMux: ['%v']\", ws)\n\t\tlog.Print(errMsg)\n\t\treturn errors.New(errMsg)\n\t}\n\tc.webServicesLock.Lock()\n\tdefer c.webServicesLock.Unlock()\n\t// build a new ServeMux and re-register all WebServices\n\tnewServeMux := http.NewServeMux()\n\tnewServices := []*WebService{}\n\tnewIsRegisteredOnRoot := false\n\tfor _, each := range c.webServices {\n\t\tif each.rootPath != ws.rootPath {\n\t\t\t// If not registered on root then add specific mapping\n\t\t\tif !newIsRegisteredOnRoot {\n\t\t\t\tnewIsRegisteredOnRoot = c.addHandler(each, newServeMux)\n\t\t\t}\n\t\t\tnewServices = append(newServices, each)\n\t\t}\n\t}\n\tc.webServices, c.ServeMux, c.isRegisteredOnRoot = newServices, newServeMux, newIsRegisteredOnRoot\n\treturn nil\n}\n\n// logStackOnRecover is the default RecoverHandleFunction and is called\n// when DoNotRecover is false and the recoverHandleFunc is not set for the container.\n// Default implementation logs the stacktrace and writes the stacktrace on the response.\n// This may be a security issue as it exposes sourcecode information.\nfunc logStackOnRecover(panicReason interface{}, httpWriter http.ResponseWriter) {\n\tvar buffer bytes.Buffer\n\tbuffer.WriteString(fmt.Sprintf(\"recover from panic situation: - %v\\r\\n\", panicReason))\n\tfor i := 2; ; i += 1 {\n\t\t_, file, line, ok := runtime.Caller(i)\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\tbuffer.WriteString(fmt.Sprintf(\"    %s:%d\\r\\n\", file, line))\n\t}\n\tlog.Print(buffer.String())\n\thttpWriter.WriteHeader(http.StatusInternalServerError)\n\thttpWriter.Write(buffer.Bytes())\n}\n\n// writeServiceError is the default ServiceErrorHandleFunction and is called\n// when a ServiceError is returned during route selection. Default implementation\n// calls resp.WriteErrorString(err.Code, err.Message)\nfunc writeServiceError(err ServiceError, req *Request, resp *Response) {\n\tfor header, values := range err.Header {\n\t\tfor _, value := range values {\n\t\t\tresp.Header().Add(header, value)\n\t\t}\n\t}\n\tresp.WriteErrorString(err.Code, err.Message)\n}\n\n// Dispatch the incoming Http Request to a matching WebService.\nfunc (c *Container) Dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) {\n\tif httpWriter == nil {\n\t\tpanic(\"httpWriter cannot be nil\")\n\t}\n\tif httpRequest == nil {\n\t\tpanic(\"httpRequest cannot be nil\")\n\t}\n\tc.dispatch(httpWriter, httpRequest)\n}\n\n// Dispatch the incoming Http Request to a matching WebService.\nfunc (c *Container) dispatch(httpWriter http.ResponseWriter, httpRequest *http.Request) {\n\t// so we can assign a compressing one later\n\twriter := httpWriter\n\n\t// CompressingResponseWriter should be closed after all operations are done\n\tdefer func() {\n\t\tif compressWriter, ok := writer.(*CompressingResponseWriter); ok {\n\t\t\tcompressWriter.Close()\n\t\t}\n\t}()\n\n\t// Instal panic recovery unless told otherwise\n\tif !c.doNotRecover { // catch all for 500 response\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\tc.recoverHandleFunc(r, writer)\n\t\t\t\treturn\n\t\t\t}\n\t\t}()\n\t}\n\n\t// Find best match Route ; err is non nil if no match was found\n\tvar webService *WebService\n\tvar route *Route\n\tvar err error\n\tfunc() {\n\t\tc.webServicesLock.RLock()\n\t\tdefer c.webServicesLock.RUnlock()\n\t\twebService, route, err = c.router.SelectRoute(\n\t\t\tc.webServices,\n\t\t\thttpRequest)\n\t}()\n\tif err != nil {\n\t\t// a non-200 response (may be compressed) has already been written\n\t\t// run container filters anyway ; they should not touch the response...\n\t\tchain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {\n\t\t\tswitch err.(type) {\n\t\t\tcase ServiceError:\n\t\t\t\tser := err.(ServiceError)\n\t\t\t\tc.serviceErrorHandleFunc(ser, req, resp)\n\t\t\t}\n\t\t\t// TODO\n\t\t}}\n\t\tchain.ProcessFilter(NewRequest(httpRequest), NewResponse(writer))\n\t\treturn\n\t}\n\n\t// Unless httpWriter is already an CompressingResponseWriter see if we need to install one\n\tif _, isCompressing := httpWriter.(*CompressingResponseWriter); !isCompressing {\n\t\t// Detect if compression is needed\n\t\t// assume without compression, test for override\n\t\tcontentEncodingEnabled := c.contentEncodingEnabled\n\t\tif route != nil && route.contentEncodingEnabled != nil {\n\t\t\tcontentEncodingEnabled = *route.contentEncodingEnabled\n\t\t}\n\t\tif contentEncodingEnabled {\n\t\t\tdoCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter)\n\t\t\tif doCompress {\n\t\t\t\tvar err error\n\t\t\t\twriter, err = NewCompressingResponseWriter(httpWriter, encoding)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Print(\"unable to install compressor: \", err)\n\t\t\t\t\thttpWriter.WriteHeader(http.StatusInternalServerError)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tpathProcessor, routerProcessesPath := c.router.(PathProcessor)\n\tif !routerProcessesPath {\n\t\tpathProcessor = defaultPathProcessor{}\n\t}\n\tpathParams := pathProcessor.ExtractParameters(route, webService, httpRequest.URL.Path)\n\twrappedRequest, wrappedResponse := route.wrapRequestResponse(writer, httpRequest, pathParams)\n\t// pass through filters (if any)\n\tif size := len(c.containerFilters) + len(webService.filters) + len(route.Filters); size > 0 {\n\t\t// compose filter chain\n\t\tallFilters := make([]FilterFunction, 0, size)\n\t\tallFilters = append(allFilters, c.containerFilters...)\n\t\tallFilters = append(allFilters, webService.filters...)\n\t\tallFilters = append(allFilters, route.Filters...)\n\t\tchain := FilterChain{\n\t\t\tFilters:       allFilters,\n\t\t\tTarget:        route.Function,\n\t\t\tParameterDocs: route.ParameterDocs,\n\t\t\tOperation:     route.Operation,\n\t\t}\n\t\tchain.ProcessFilter(wrappedRequest, wrappedResponse)\n\t} else {\n\t\t// no filters, handle request by route\n\t\troute.Function(wrappedRequest, wrappedResponse)\n\t}\n}\n\n// fixedPrefixPath returns the fixed part of the partspec ; it may include template vars {}\nfunc fixedPrefixPath(pathspec string) string {\n\tvarBegin := strings.Index(pathspec, \"{\")\n\tif -1 == varBegin {\n\t\treturn pathspec\n\t}\n\treturn pathspec[:varBegin]\n}\n\n// ServeHTTP implements net/http.Handler therefore a Container can be a Handler in a http.Server\nfunc (c *Container) ServeHTTP(httpWriter http.ResponseWriter, httpRequest *http.Request) {\n\t// Skip, if content encoding is disabled\n\tif !c.contentEncodingEnabled {\n\t\tc.ServeMux.ServeHTTP(httpWriter, httpRequest)\n\t\treturn\n\t}\n\t// content encoding is enabled\n\n\t// Skip, if httpWriter is already an CompressingResponseWriter\n\tif _, ok := httpWriter.(*CompressingResponseWriter); ok {\n\t\tc.ServeMux.ServeHTTP(httpWriter, httpRequest)\n\t\treturn\n\t}\n\n\twriter := httpWriter\n\t// CompressingResponseWriter should be closed after all operations are done\n\tdefer func() {\n\t\tif compressWriter, ok := writer.(*CompressingResponseWriter); ok {\n\t\t\tcompressWriter.Close()\n\t\t}\n\t}()\n\n\tdoCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter)\n\tif doCompress {\n\t\tvar err error\n\t\twriter, err = NewCompressingResponseWriter(httpWriter, encoding)\n\t\tif err != nil {\n\t\t\tlog.Print(\"unable to install compressor: \", err)\n\t\t\thttpWriter.WriteHeader(http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t}\n\n\tc.ServeMux.ServeHTTP(writer, httpRequest)\n}\n\n// Handle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics.\nfunc (c *Container) Handle(pattern string, handler http.Handler) {\n\tc.ServeMux.Handle(pattern, http.HandlerFunc(func(httpWriter http.ResponseWriter, httpRequest *http.Request) {\n\t\t// Skip, if httpWriter is already an CompressingResponseWriter\n\t\tif _, ok := httpWriter.(*CompressingResponseWriter); ok {\n\t\t\thandler.ServeHTTP(httpWriter, httpRequest)\n\t\t\treturn\n\t\t}\n\n\t\twriter := httpWriter\n\n\t\t// CompressingResponseWriter should be closed after all operations are done\n\t\tdefer func() {\n\t\t\tif compressWriter, ok := writer.(*CompressingResponseWriter); ok {\n\t\t\t\tcompressWriter.Close()\n\t\t\t}\n\t\t}()\n\n\t\tif c.contentEncodingEnabled {\n\t\t\tdoCompress, encoding := wantsCompressedResponse(httpRequest, httpWriter)\n\t\t\tif doCompress {\n\t\t\t\tvar err error\n\t\t\t\twriter, err = NewCompressingResponseWriter(httpWriter, encoding)\n\t\t\t\tif err != nil {\n\t\t\t\t\tlog.Print(\"unable to install compressor: \", err)\n\t\t\t\t\thttpWriter.WriteHeader(http.StatusInternalServerError)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\thandler.ServeHTTP(writer, httpRequest)\n\t}))\n}\n\n// HandleWithFilter registers the handler for the given pattern.\n// Container's filter chain is applied for handler.\n// If a handler already exists for pattern, HandleWithFilter panics.\nfunc (c *Container) HandleWithFilter(pattern string, handler http.Handler) {\n\tf := func(httpResponse http.ResponseWriter, httpRequest *http.Request) {\n\t\tif len(c.containerFilters) == 0 {\n\t\t\thandler.ServeHTTP(httpResponse, httpRequest)\n\t\t\treturn\n\t\t}\n\n\t\tchain := FilterChain{Filters: c.containerFilters, Target: func(req *Request, resp *Response) {\n\t\t\thandler.ServeHTTP(resp, req.Request)\n\t\t}}\n\t\tchain.ProcessFilter(NewRequest(httpRequest), NewResponse(httpResponse))\n\t}\n\n\tc.Handle(pattern, http.HandlerFunc(f))\n}\n\n// Filter appends a container FilterFunction. These are called before dispatching\n// a http.Request to a WebService from the container\nfunc (c *Container) Filter(filter FilterFunction) {\n\tc.containerFilters = append(c.containerFilters, filter)\n}\n\n// RegisteredWebServices returns the collections of added WebServices\nfunc (c *Container) RegisteredWebServices() []*WebService {\n\tc.webServicesLock.RLock()\n\tdefer c.webServicesLock.RUnlock()\n\tresult := make([]*WebService, len(c.webServices))\n\tfor ix := range c.webServices {\n\t\tresult[ix] = c.webServices[ix]\n\t}\n\treturn result\n}\n\n// computeAllowedMethods returns a list of HTTP methods that are valid for a Request\nfunc (c *Container) computeAllowedMethods(req *Request) []string {\n\t// Go through all RegisteredWebServices() and all its Routes to collect the options\n\tmethods := []string{}\n\trequestPath := req.Request.URL.Path\n\tfor _, ws := range c.RegisteredWebServices() {\n\t\tmatches := ws.pathExpr.Matcher.FindStringSubmatch(requestPath)\n\t\tif matches != nil {\n\t\t\tfinalMatch := matches[len(matches)-1]\n\t\t\tfor _, rt := range ws.Routes() {\n\t\t\t\tmatches := rt.pathExpr.Matcher.FindStringSubmatch(finalMatch)\n\t\t\t\tif matches != nil {\n\t\t\t\t\tlastMatch := matches[len(matches)-1]\n\t\t\t\t\tif lastMatch == \"\" || lastMatch == \"/\" { // do not include if value is neither empty nor ‘/’.\n\t\t\t\t\t\tmethods = append(methods, rt.Method)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// methods = append(methods, \"OPTIONS\")  not sure about this\n\treturn methods\n}\n\n// newBasicRequestResponse creates a pair of Request,Response from its http versions.\n// It is basic because no parameter or (produces) content-type information is given.\nfunc newBasicRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request) (*Request, *Response) {\n\tresp := NewResponse(httpWriter)\n\tresp.requestAccept = httpRequest.Header.Get(HEADER_Accept)\n\treturn NewRequest(httpRequest), resp\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/cors_filter.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// CrossOriginResourceSharing is used to create a Container Filter that implements CORS.\n// Cross-origin resource sharing (CORS) is a mechanism that allows JavaScript on a web page\n// to make XMLHttpRequests to another domain, not the domain the JavaScript originated from.\n//\n// http://en.wikipedia.org/wiki/Cross-origin_resource_sharing\n// http://enable-cors.org/server.html\n// http://www.html5rocks.com/en/tutorials/cors/#toc-handling-a-not-so-simple-request\ntype CrossOriginResourceSharing struct {\n\tExposeHeaders []string // list of Header names\n\n\t// AllowedHeaders is alist of Header names. Checking is case-insensitive.\n\t// The list may contain the special wildcard string \".*\" ; all is allowed\n\tAllowedHeaders []string\n\n\t// AllowedDomains is a list of allowed values for Http Origin.\n\t// The list may contain the special wildcard string \".*\" ; all is allowed\n\t// If empty all are allowed.\n\tAllowedDomains []string\n\n\t// AllowedDomainFunc is optional and is a function that will do the check\n\t// when the origin is not part of the AllowedDomains and it does not contain the wildcard \".*\".\n\tAllowedDomainFunc func(origin string) bool\n\n\t// AllowedMethods is either empty or has a list of http methods names. Checking is case-insensitive.\n\tAllowedMethods []string\n\tMaxAge         int // number of seconds before requiring new Options request\n\tCookiesAllowed bool\n\tContainer      *Container\n\n\tallowedOriginPatterns []*regexp.Regexp // internal field for origin regexp check.\n}\n\n// Filter is a filter function that implements the CORS flow as documented on http://enable-cors.org/server.html\n// and http://www.html5rocks.com/static/images/cors_server_flowchart.png\nfunc (c CrossOriginResourceSharing) Filter(req *Request, resp *Response, chain *FilterChain) {\n\torigin := req.Request.Header.Get(HEADER_Origin)\n\tif len(origin) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Print(\"no Http header Origin set\")\n\t\t}\n\t\tchain.ProcessFilter(req, resp)\n\t\treturn\n\t}\n\tif !c.isOriginAllowed(origin) { // check whether this origin is allowed\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"HTTP Origin:%s is not part of %v, neither matches any part of %v\", origin, c.AllowedDomains, c.allowedOriginPatterns)\n\t\t}\n\t\tchain.ProcessFilter(req, resp)\n\t\treturn\n\t}\n\tif req.Request.Method != \"OPTIONS\" {\n\t\tc.doActualRequest(req, resp)\n\t\tchain.ProcessFilter(req, resp)\n\t\treturn\n\t}\n\tif acrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod); acrm != \"\" {\n\t\tc.doPreflightRequest(req, resp)\n\t} else {\n\t\tc.doActualRequest(req, resp)\n\t\tchain.ProcessFilter(req, resp)\n\t\treturn\n\t}\n}\n\nfunc (c CrossOriginResourceSharing) doActualRequest(req *Request, resp *Response) {\n\tc.setOptionsHeaders(req, resp)\n\t// continue processing the response\n}\n\nfunc (c *CrossOriginResourceSharing) doPreflightRequest(req *Request, resp *Response) {\n\tif len(c.AllowedMethods) == 0 {\n\t\tif c.Container == nil {\n\t\t\tc.AllowedMethods = DefaultContainer.computeAllowedMethods(req)\n\t\t} else {\n\t\t\tc.AllowedMethods = c.Container.computeAllowedMethods(req)\n\t\t}\n\t}\n\n\tacrm := req.Request.Header.Get(HEADER_AccessControlRequestMethod)\n\tif !c.isValidAccessControlRequestMethod(acrm, c.AllowedMethods) {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"Http header %s:%s is not in %v\",\n\t\t\t\tHEADER_AccessControlRequestMethod,\n\t\t\t\tacrm,\n\t\t\t\tc.AllowedMethods)\n\t\t}\n\t\treturn\n\t}\n\tacrhs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders)\n\tif len(acrhs) > 0 {\n\t\tfor _, each := range strings.Split(acrhs, \",\") {\n\t\t\tif !c.isValidAccessControlRequestHeader(strings.Trim(each, \" \")) {\n\t\t\t\tif trace {\n\t\t\t\t\ttraceLogger.Printf(\"Http header %s:%s is not in %v\",\n\t\t\t\t\t\tHEADER_AccessControlRequestHeaders,\n\t\t\t\t\t\tacrhs,\n\t\t\t\t\t\tc.AllowedHeaders)\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\tresp.AddHeader(HEADER_AccessControlAllowMethods, strings.Join(c.AllowedMethods, \",\"))\n\tresp.AddHeader(HEADER_AccessControlAllowHeaders, acrhs)\n\tc.setOptionsHeaders(req, resp)\n\n\t// return http 200 response, no body\n}\n\nfunc (c CrossOriginResourceSharing) setOptionsHeaders(req *Request, resp *Response) {\n\tc.checkAndSetExposeHeaders(resp)\n\tc.setAllowOriginHeader(req, resp)\n\tc.checkAndSetAllowCredentials(resp)\n\tif c.MaxAge > 0 {\n\t\tresp.AddHeader(HEADER_AccessControlMaxAge, strconv.Itoa(c.MaxAge))\n\t}\n}\n\nfunc (c CrossOriginResourceSharing) isOriginAllowed(origin string) bool {\n\tif len(origin) == 0 {\n\t\treturn false\n\t}\n\tlowerOrigin := strings.ToLower(origin)\n\tif len(c.AllowedDomains) == 0 {\n\t\tif c.AllowedDomainFunc != nil {\n\t\t\treturn c.AllowedDomainFunc(lowerOrigin)\n\t\t}\n\t\treturn true\n\t}\n\n\t// exact match on each allowed domain\n\tfor _, domain := range c.AllowedDomains {\n\t\tif domain == \".*\" || strings.ToLower(domain) == lowerOrigin {\n\t\t\treturn true\n\t\t}\n\t}\n\tif c.AllowedDomainFunc != nil {\n\t\treturn c.AllowedDomainFunc(origin)\n\t}\n\treturn false\n}\n\nfunc (c CrossOriginResourceSharing) setAllowOriginHeader(req *Request, resp *Response) {\n\torigin := req.Request.Header.Get(HEADER_Origin)\n\tif c.isOriginAllowed(origin) {\n\t\tresp.AddHeader(HEADER_AccessControlAllowOrigin, origin)\n\t}\n}\n\nfunc (c CrossOriginResourceSharing) checkAndSetExposeHeaders(resp *Response) {\n\tif len(c.ExposeHeaders) > 0 {\n\t\tresp.AddHeader(HEADER_AccessControlExposeHeaders, strings.Join(c.ExposeHeaders, \",\"))\n\t}\n}\n\nfunc (c CrossOriginResourceSharing) checkAndSetAllowCredentials(resp *Response) {\n\tif c.CookiesAllowed {\n\t\tresp.AddHeader(HEADER_AccessControlAllowCredentials, \"true\")\n\t}\n}\n\nfunc (c CrossOriginResourceSharing) isValidAccessControlRequestMethod(method string, allowedMethods []string) bool {\n\tfor _, each := range allowedMethods {\n\t\tif each == method {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c CrossOriginResourceSharing) isValidAccessControlRequestHeader(header string) bool {\n\tfor _, each := range c.AllowedHeaders {\n\t\tif strings.ToLower(each) == strings.ToLower(header) {\n\t\t\treturn true\n\t\t}\n\t\tif each == \"*\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/coverage.sh",
    "content": "go test -coverprofile=coverage.out\ngo tool cover -html=coverage.out"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/curly.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"net/http\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// CurlyRouter expects Routes with paths that contain zero or more parameters in curly brackets.\ntype CurlyRouter struct{}\n\n// SelectRoute is part of the Router interface and returns the best match\n// for the WebService and its Route for the given Request.\nfunc (c CurlyRouter) SelectRoute(\n\twebServices []*WebService,\n\thttpRequest *http.Request) (selectedService *WebService, selected *Route, err error) {\n\n\trequestTokens := tokenizePath(httpRequest.URL.Path)\n\n\tdetectedService := c.detectWebService(requestTokens, webServices)\n\tif detectedService == nil {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no WebService was found to match URL path:%s\\n\", httpRequest.URL.Path)\n\t\t}\n\t\treturn nil, nil, NewError(http.StatusNotFound, \"404: Page Not Found\")\n\t}\n\tcandidateRoutes := c.selectRoutes(detectedService, requestTokens)\n\tif len(candidateRoutes) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no Route in WebService with path %s was found to match URL path:%s\\n\", detectedService.rootPath, httpRequest.URL.Path)\n\t\t}\n\t\treturn detectedService, nil, NewError(http.StatusNotFound, \"404: Page Not Found\")\n\t}\n\tselectedRoute, err := c.detectRoute(candidateRoutes, httpRequest)\n\tif selectedRoute == nil {\n\t\treturn detectedService, nil, err\n\t}\n\treturn detectedService, selectedRoute, nil\n}\n\n// selectRoutes return a collection of Route from a WebService that matches the path tokens from the request.\nfunc (c CurlyRouter) selectRoutes(ws *WebService, requestTokens []string) sortableCurlyRoutes {\n\tcandidates := make(sortableCurlyRoutes, 0, 8)\n\tfor _, each := range ws.routes {\n\t\tmatches, paramCount, staticCount := c.matchesRouteByPathTokens(each.pathParts, requestTokens, each.hasCustomVerb)\n\t\tif matches {\n\t\t\tcandidates.add(curlyRoute{each, paramCount, staticCount}) // TODO make sure Routes() return pointers?\n\t\t}\n\t}\n\tsort.Sort(candidates)\n\treturn candidates\n}\n\n// matchesRouteByPathTokens computes whether it matches, howmany parameters do match and what the number of static path elements are.\nfunc (c CurlyRouter) matchesRouteByPathTokens(routeTokens, requestTokens []string, routeHasCustomVerb bool) (matches bool, paramCount int, staticCount int) {\n\tif len(routeTokens) < len(requestTokens) {\n\t\t// proceed in matching only if last routeToken is wildcard\n\t\tcount := len(routeTokens)\n\t\tif count == 0 || !strings.HasSuffix(routeTokens[count-1], \"*}\") {\n\t\t\treturn false, 0, 0\n\t\t}\n\t\t// proceed\n\t}\n\tfor i, routeToken := range routeTokens {\n\t\tif i == len(requestTokens) {\n\t\t\t// reached end of request path\n\t\t\treturn false, 0, 0\n\t\t}\n\t\trequestToken := requestTokens[i]\n\t\tif routeHasCustomVerb && hasCustomVerb(routeToken){\n\t\t\tif !isMatchCustomVerb(routeToken, requestToken) {\n\t\t\t\treturn false, 0, 0\n\t\t\t}\n\t\t\tstaticCount++\n\t\t\trequestToken = removeCustomVerb(requestToken)\n\t\t\trouteToken = removeCustomVerb(routeToken)\n\t\t}\n\n\t\tif strings.HasPrefix(routeToken, \"{\") {\n\t\t\tparamCount++\n\t\t\tif colon := strings.Index(routeToken, \":\"); colon != -1 {\n\t\t\t\t// match by regex\n\t\t\t\tmatchesToken, matchesRemainder := c.regularMatchesPathToken(routeToken, colon, requestToken)\n\t\t\t\tif !matchesToken {\n\t\t\t\t\treturn false, 0, 0\n\t\t\t\t}\n\t\t\t\tif matchesRemainder {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t} else { // no { prefix\n\t\t\tif requestToken != routeToken {\n\t\t\t\treturn false, 0, 0\n\t\t\t}\n\t\t\tstaticCount++\n\t\t}\n\t}\n\treturn true, paramCount, staticCount\n}\n\n// regularMatchesPathToken tests whether the regular expression part of routeToken matches the requestToken or all remaining tokens\n// format routeToken is {someVar:someExpression}, e.g. {zipcode:[\\d][\\d][\\d][\\d][A-Z][A-Z]}\nfunc (c CurlyRouter) regularMatchesPathToken(routeToken string, colon int, requestToken string) (matchesToken bool, matchesRemainder bool) {\n\tregPart := routeToken[colon+1 : len(routeToken)-1]\n\tif regPart == \"*\" {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"wildcard parameter detected in route token %s that matches %s\\n\", routeToken, requestToken)\n\t\t}\n\t\treturn true, true\n\t}\n\tmatched, err := regexp.MatchString(regPart, requestToken)\n\treturn (matched && err == nil), false\n}\n\nvar jsr311Router = RouterJSR311{}\n\n// detectRoute selectes from a list of Route the first match by inspecting both the Accept and Content-Type\n// headers of the Request. See also RouterJSR311 in jsr311.go\nfunc (c CurlyRouter) detectRoute(candidateRoutes sortableCurlyRoutes, httpRequest *http.Request) (*Route, error) {\n\t// tracing is done inside detectRoute\n\treturn jsr311Router.detectRoute(candidateRoutes.routes(), httpRequest)\n}\n\n// detectWebService returns the best matching webService given the list of path tokens.\n// see also computeWebserviceScore\nfunc (c CurlyRouter) detectWebService(requestTokens []string, webServices []*WebService) *WebService {\n\tvar best *WebService\n\tscore := -1\n\tfor _, each := range webServices {\n\t\tmatches, eachScore := c.computeWebserviceScore(requestTokens, each.pathExpr.tokens)\n\t\tif matches && (eachScore > score) {\n\t\t\tbest = each\n\t\t\tscore = eachScore\n\t\t}\n\t}\n\treturn best\n}\n\n// computeWebserviceScore returns whether tokens match and\n// the weighted score of the longest matching consecutive tokens from the beginning.\nfunc (c CurlyRouter) computeWebserviceScore(requestTokens []string, tokens []string) (bool, int) {\n\tif len(tokens) > len(requestTokens) {\n\t\treturn false, 0\n\t}\n\tscore := 0\n\tfor i := 0; i < len(tokens); i++ {\n\t\teach := requestTokens[i]\n\t\tother := tokens[i]\n\t\tif len(each) == 0 && len(other) == 0 {\n\t\t\tscore++\n\t\t\tcontinue\n\t\t}\n\t\tif len(other) > 0 && strings.HasPrefix(other, \"{\") {\n\t\t\t// no empty match\n\t\t\tif len(each) == 0 {\n\t\t\t\treturn false, score\n\t\t\t}\n\t\t\tscore += 1\n\t\t} else {\n\t\t\t// not a parameter\n\t\t\tif each != other {\n\t\t\t\treturn false, score\n\t\t\t}\n\t\t\tscore += (len(tokens) - i) * 10 //fuzzy\n\t\t}\n\t}\n\treturn true, score\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/curly_route.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\n// curlyRoute exits for sorting Routes by the CurlyRouter based on number of parameters and number of static path elements.\ntype curlyRoute struct {\n\troute       Route\n\tparamCount  int\n\tstaticCount int\n}\n\n// sortableCurlyRoutes orders by most parameters and path elements first.\ntype sortableCurlyRoutes []curlyRoute\n\nfunc (s *sortableCurlyRoutes) add(route curlyRoute) {\n\t*s = append(*s, route)\n}\n\nfunc (s sortableCurlyRoutes) routes() (routes []Route) {\n\troutes = make([]Route, 0, len(s))\n\tfor _, each := range s {\n\t\troutes = append(routes, each.route) // TODO change return type\n\t}\n\treturn routes\n}\n\nfunc (s sortableCurlyRoutes) Len() int {\n\treturn len(s)\n}\nfunc (s sortableCurlyRoutes) Swap(i, j int) {\n\ts[i], s[j] = s[j], s[i]\n}\nfunc (s sortableCurlyRoutes) Less(i, j int) bool {\n\ta := s[j]\n\tb := s[i]\n\n\t// primary key\n\tif a.staticCount < b.staticCount {\n\t\treturn true\n\t}\n\tif a.staticCount > b.staticCount {\n\t\treturn false\n\t}\n\t// secundary key\n\tif a.paramCount < b.paramCount {\n\t\treturn true\n\t}\n\tif a.paramCount > b.paramCount {\n\t\treturn false\n\t}\n\treturn a.route.Path < b.route.Path\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/custom_verb.go",
    "content": "package restful\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nvar (\n\tcustomVerbReg = regexp.MustCompile(\":([A-Za-z]+)$\")\n)\n\nfunc hasCustomVerb(routeToken string) bool {\n\treturn customVerbReg.MatchString(routeToken)\n}\n\nfunc isMatchCustomVerb(routeToken string, pathToken string) bool {\n\trs := customVerbReg.FindStringSubmatch(routeToken)\n\tif len(rs) < 2 {\n\t\treturn false\n\t}\n\n\tcustomVerb := rs[1]\n\tspecificVerbReg := regexp.MustCompile(fmt.Sprintf(\":%s$\", customVerb))\n\treturn specificVerbReg.MatchString(pathToken)\n}\n\nfunc removeCustomVerb(str string) string {\n\treturn customVerbReg.ReplaceAllString(str, \"\")\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/doc.go",
    "content": "/*\nPackage restful , a lean package for creating REST-style WebServices without magic.\n\nWebServices and Routes\n\nA WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls.\nTypically, a WebService has a root path (e.g. /users) and defines common MIME types for its routes.\nWebServices must be added to a container (see below) in order to handler Http requests from a server.\n\nA Route is defined by a HTTP method, an URL path and (optionally) the MIME types it consumes (Content-Type) and produces (Accept).\nThis package has the logic to find the best matching Route and if found, call its Function.\n\n\tws := new(restful.WebService)\n\tws.\n\t\tPath(\"/users\").\n\t\tConsumes(restful.MIME_JSON, restful.MIME_XML).\n\t\tProduces(restful.MIME_JSON, restful.MIME_XML)\n\n\tws.Route(ws.GET(\"/{user-id}\").To(u.findUser))  // u is a UserResource\n\n\t...\n\n\t// GET http://localhost:8080/users/1\n\tfunc (u UserResource) findUser(request *restful.Request, response *restful.Response) {\n\t\tid := request.PathParameter(\"user-id\")\n\t\t...\n\t}\n\nThe (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response.\n\nSee the example https://github.com/emicklei/go-restful/blob/v3/examples/user-resource/restful-user-resource.go with a full implementation.\n\nRegular expression matching Routes\n\nA Route parameter can be specified using the format \"uri/{var[:regexp]}\" or the special version \"uri/{var:*}\" for matching the tail of the path.\nFor example, /persons/{name:[A-Z][A-Z]} can be used to restrict values for the parameter \"name\" to only contain capital alphabetic characters.\nRegular expressions must use the standard Go syntax as described in the regexp package. (https://code.google.com/p/re2/wiki/Syntax)\nThis feature requires the use of a CurlyRouter.\n\nContainers\n\nA Container holds a collection of WebServices, Filters and a http.ServeMux for multiplexing http requests.\nUsing the statements \"restful.Add(...) and restful.Filter(...)\" will register WebServices and Filters to the Default Container.\nThe Default container of go-restful uses the http.DefaultServeMux.\nYou can create your own Container and create a new http.Server for that particular container.\n\n\tcontainer := restful.NewContainer()\n\tserver := &http.Server{Addr: \":8081\", Handler: container}\n\nFilters\n\nA filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses.\nYou can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc.\nIn the restful package there are three hooks into the request,response flow where filters can be added.\nEach filter must define a FilterFunction:\n\n\tfunc (req *restful.Request, resp *restful.Response, chain *restful.FilterChain)\n\nUse the following statement to pass the request,response pair to the next filter or RouteFunction\n\n\tchain.ProcessFilter(req, resp)\n\nContainer Filters\n\nThese are processed before any registered WebService.\n\n\t// install a (global) filter for the default container (processed before any webservice)\n\trestful.Filter(globalLogging)\n\nWebService Filters\n\nThese are processed before any Route of a WebService.\n\n\t// install a webservice filter (processed before any route)\n\tws.Filter(webserviceLogging).Filter(measureTime)\n\n\nRoute Filters\n\nThese are processed before calling the function associated with the Route.\n\n\t// install 2 chained route filters (processed before calling findUser)\n\tws.Route(ws.GET(\"/{user-id}\").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser))\n\nSee the example https://github.com/emicklei/go-restful/blob/v3/examples/filters/restful-filters.go with full implementations.\n\nResponse Encoding\n\nTwo encodings are supported: gzip and deflate. To enable this for all responses:\n\n\trestful.DefaultContainer.EnableContentEncoding(true)\n\nIf a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding.\nAlternatively, you can create a Filter that performs the encoding and install it per WebService or Route.\n\nSee the example https://github.com/emicklei/go-restful/blob/v3/examples/encoding/restful-encoding-filter.go\n\nOPTIONS support\n\nBy installing a pre-defined container filter, your Webservice(s) can respond to the OPTIONS Http request.\n\n\tFilter(OPTIONSFilter())\n\nCORS\n\nBy installing the filter of a CrossOriginResourceSharing (CORS), your WebService(s) can handle CORS requests.\n\n\tcors := CrossOriginResourceSharing{ExposeHeaders: []string{\"X-My-Header\"}, CookiesAllowed: false, Container: DefaultContainer}\n\tFilter(cors.Filter)\n\nError Handling\n\nUnexpected things happen. If a request cannot be processed because of a failure, your service needs to tell via the response what happened and why.\nFor this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation.\n\n\t400: Bad Request\n\nIf path or query parameters are not valid (content or type) then use http.StatusBadRequest.\n\n\t404: Not Found\n\nDespite a valid URI, the resource requested may not be available\n\n\t500: Internal Server Error\n\nIf the application logic could not process the request (or write the response) then use http.StatusInternalServerError.\n\n\t405: Method Not Allowed\n\nThe request has a valid URL but the method (GET,PUT,POST,...) is not allowed.\n\n\t406: Not Acceptable\n\nThe request does not have or has an unknown Accept Header set for this operation.\n\n\t415: Unsupported Media Type\n\nThe request does not have or has an unknown Content-Type Header set for this operation.\n\nServiceError\n\nIn addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response.\n\nPerformance options\n\nThis package has several options that affect the performance of your service. It is important to understand them and how you can change it.\n\n\trestful.DefaultContainer.DoNotRecover(false)\n\nDoNotRecover controls whether panics will be caught to return HTTP 500.\nIf set to false, the container will recover from panics.\nDefault value is true\n\n\trestful.SetCompressorProvider(NewBoundedCachedCompressors(20, 20))\n\nIf content encoding is enabled then the default strategy for getting new gzip/zlib writers and readers is to use a sync.Pool.\nBecause writers are expensive structures, performance is even more improved when using a preloaded cache. You can also inject your own implementation.\n\nTrouble shooting\n\nThis package has the means to produce detail logging of the complete Http request matching process and filter invocation.\nEnabling this feature requires you to set an implementation of restful.StdLogger (e.g. log.Logger) instance such as:\n\n\trestful.TraceLogger(log.New(os.Stdout, \"[restful] \", log.LstdFlags|log.Lshortfile))\n\nLogging\n\nThe restful.SetLogger() method allows you to override the logger used by the package. By default restful\nuses the standard library `log` package and logs to stdout. Different logging packages are supported as\nlong as they conform to `StdLogger` interface defined in the `log` sub-package, writing an adapter for your\npreferred package is simple.\n\nResources\n\n[project]: https://github.com/emicklei/go-restful\n\n[examples]: https://github.com/emicklei/go-restful/blob/master/examples\n\n[design]:  http://ernestmicklei.com/2012/11/11/go-restful-api-design/\n\n[showcases]: https://github.com/emicklei/mora, https://github.com/emicklei/landskape\n\n(c) 2012-2015, http://ernestmicklei.com. MIT License\n*/\npackage restful\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/entity_accessors.go",
    "content": "package restful\n\n// Copyright 2015 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"encoding/xml\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// EntityReaderWriter can read and write values using an encoding such as JSON,XML.\ntype EntityReaderWriter interface {\n\t// Read a serialized version of the value from the request.\n\t// The Request may have a decompressing reader. Depends on Content-Encoding.\n\tRead(req *Request, v interface{}) error\n\n\t// Write a serialized version of the value on the response.\n\t// The Response may have a compressing writer. Depends on Accept-Encoding.\n\t// status should be a valid Http Status code\n\tWrite(resp *Response, status int, v interface{}) error\n}\n\n// entityAccessRegistry is a singleton\nvar entityAccessRegistry = &entityReaderWriters{\n\tprotection: new(sync.RWMutex),\n\taccessors:  map[string]EntityReaderWriter{},\n}\n\n// entityReaderWriters associates MIME to an EntityReaderWriter\ntype entityReaderWriters struct {\n\tprotection *sync.RWMutex\n\taccessors  map[string]EntityReaderWriter\n}\n\nfunc init() {\n\tRegisterEntityAccessor(MIME_JSON, NewEntityAccessorJSON(MIME_JSON))\n\tRegisterEntityAccessor(MIME_XML, NewEntityAccessorXML(MIME_XML))\n}\n\n// RegisterEntityAccessor add/overrides the ReaderWriter for encoding content with this MIME type.\nfunc RegisterEntityAccessor(mime string, erw EntityReaderWriter) {\n\tentityAccessRegistry.protection.Lock()\n\tdefer entityAccessRegistry.protection.Unlock()\n\tentityAccessRegistry.accessors[mime] = erw\n}\n\n// NewEntityAccessorJSON returns a new EntityReaderWriter for accessing JSON content.\n// This package is already initialized with such an accessor using the MIME_JSON contentType.\nfunc NewEntityAccessorJSON(contentType string) EntityReaderWriter {\n\treturn entityJSONAccess{ContentType: contentType}\n}\n\n// NewEntityAccessorXML returns a new EntityReaderWriter for accessing XML content.\n// This package is already initialized with such an accessor using the MIME_XML contentType.\nfunc NewEntityAccessorXML(contentType string) EntityReaderWriter {\n\treturn entityXMLAccess{ContentType: contentType}\n}\n\n// accessorAt returns the registered ReaderWriter for this MIME type.\nfunc (r *entityReaderWriters) accessorAt(mime string) (EntityReaderWriter, bool) {\n\tr.protection.RLock()\n\tdefer r.protection.RUnlock()\n\ter, ok := r.accessors[mime]\n\tif !ok {\n\t\t// retry with reverse lookup\n\t\t// more expensive but we are in an exceptional situation anyway\n\t\tfor k, v := range r.accessors {\n\t\t\tif strings.Contains(mime, k) {\n\t\t\t\treturn v, true\n\t\t\t}\n\t\t}\n\t}\n\treturn er, ok\n}\n\n// entityXMLAccess is a EntityReaderWriter for XML encoding\ntype entityXMLAccess struct {\n\t// This is used for setting the Content-Type header when writing\n\tContentType string\n}\n\n// Read unmarshalls the value from XML\nfunc (e entityXMLAccess) Read(req *Request, v interface{}) error {\n\treturn xml.NewDecoder(req.Request.Body).Decode(v)\n}\n\n// Write marshalls the value to JSON and set the Content-Type Header.\nfunc (e entityXMLAccess) Write(resp *Response, status int, v interface{}) error {\n\treturn writeXML(resp, status, e.ContentType, v)\n}\n\n// writeXML marshalls the value to JSON and set the Content-Type Header.\nfunc writeXML(resp *Response, status int, contentType string, v interface{}) error {\n\tif v == nil {\n\t\tresp.WriteHeader(status)\n\t\t// do not write a nil representation\n\t\treturn nil\n\t}\n\tif resp.prettyPrint {\n\t\t// pretty output must be created and written explicitly\n\t\toutput, err := xml.MarshalIndent(v, \" \", \" \")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tresp.Header().Set(HEADER_ContentType, contentType)\n\t\tresp.WriteHeader(status)\n\t\t_, err = resp.Write([]byte(xml.Header))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = resp.Write(output)\n\t\treturn err\n\t}\n\t// not-so-pretty\n\tresp.Header().Set(HEADER_ContentType, contentType)\n\tresp.WriteHeader(status)\n\treturn xml.NewEncoder(resp).Encode(v)\n}\n\n// entityJSONAccess is a EntityReaderWriter for JSON encoding\ntype entityJSONAccess struct {\n\t// This is used for setting the Content-Type header when writing\n\tContentType string\n}\n\n// Read unmarshalls the value from JSON\nfunc (e entityJSONAccess) Read(req *Request, v interface{}) error {\n\tdecoder := NewDecoder(req.Request.Body)\n\tdecoder.UseNumber()\n\treturn decoder.Decode(v)\n}\n\n// Write marshalls the value to JSON and set the Content-Type Header.\nfunc (e entityJSONAccess) Write(resp *Response, status int, v interface{}) error {\n\treturn writeJSON(resp, status, e.ContentType, v)\n}\n\n// write marshalls the value to JSON and set the Content-Type Header.\nfunc writeJSON(resp *Response, status int, contentType string, v interface{}) error {\n\tif v == nil {\n\t\tresp.WriteHeader(status)\n\t\t// do not write a nil representation\n\t\treturn nil\n\t}\n\tif resp.prettyPrint {\n\t\t// pretty output must be created and written explicitly\n\t\toutput, err := MarshalIndent(v, \"\", \" \")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tresp.Header().Set(HEADER_ContentType, contentType)\n\t\tresp.WriteHeader(status)\n\t\t_, err = resp.Write(output)\n\t\treturn err\n\t}\n\t// not-so-pretty\n\tresp.Header().Set(HEADER_ContentType, contentType)\n\tresp.WriteHeader(status)\n\treturn NewEncoder(resp).Encode(v)\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/extensions.go",
    "content": "package restful\n\n// Copyright 2021 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\n// ExtensionProperties provides storage of vendor extensions for entities\ntype ExtensionProperties struct {\n\t// Extensions vendor extensions used to describe extra functionality\n\t// (https://swagger.io/docs/specification/2-0/swagger-extensions/)\n\tExtensions map[string]interface{}\n}\n\n// AddExtension adds or updates a key=value pair to the extension map.\nfunc (ep *ExtensionProperties) AddExtension(key string, value interface{}) {\n\tif ep.Extensions == nil {\n\t\tep.Extensions = map[string]interface{}{key: value}\n\t} else {\n\t\tep.Extensions[key] = value\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/filter.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\n// FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction.\ntype FilterChain struct {\n\tFilters       []FilterFunction // ordered list of FilterFunction\n\tIndex         int              // index into filters that is currently in progress\n\tTarget        RouteFunction    // function to call after passing all filters\n\tParameterDocs []*Parameter     // the parameter docs for the route\n\tOperation     string           // the name of the operation\n}\n\n// ProcessFilter passes the request,response pair through the next of Filters.\n// Each filter can decide to proceed to the next Filter or handle the Response itself.\nfunc (f *FilterChain) ProcessFilter(request *Request, response *Response) {\n\tif f.Index < len(f.Filters) {\n\t\tf.Index++\n\t\tf.Filters[f.Index-1](request, response, f)\n\t} else {\n\t\tf.Target(request, response)\n\t}\n}\n\n// FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction\ntype FilterFunction func(*Request, *Response, *FilterChain)\n\n// NoBrowserCacheFilter is a filter function to set HTTP headers that disable browser caching\n// See examples/restful-no-cache-filter.go for usage\nfunc NoBrowserCacheFilter(req *Request, resp *Response, chain *FilterChain) {\n\tresp.Header().Set(\"Cache-Control\", \"no-cache, no-store, must-revalidate\") // HTTP 1.1.\n\tresp.Header().Set(\"Pragma\", \"no-cache\")                                   // HTTP 1.0.\n\tresp.Header().Set(\"Expires\", \"0\")                                         // Proxies.\n\tchain.ProcessFilter(req, resp)\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/filter_adapter.go",
    "content": "package restful\n\nimport (\n\t\"net/http\"\n)\n\n// HttpMiddlewareHandler is a function that takes a http.Handler and returns a http.Handler\ntype HttpMiddlewareHandler func(http.Handler) http.Handler\n\n// HttpMiddlewareHandlerToFilter converts a HttpMiddlewareHandler to a FilterFunction.\nfunc HttpMiddlewareHandlerToFilter(middleware HttpMiddlewareHandler) FilterFunction {\n\treturn func(req *Request, resp *Response, chain *FilterChain) {\n\t\tnext := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {\n\t\t\treq.Request = r\n\t\t\tresp.ResponseWriter = rw\n\t\t\tchain.ProcessFilter(req, resp)\n\t\t})\n\n\t\tmiddleware(next).ServeHTTP(resp.ResponseWriter, req.Request)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/json.go",
    "content": "// +build !jsoniter\n\npackage restful\n\nimport \"encoding/json\"\n\nvar (\n\tMarshalIndent = json.MarshalIndent\n\tNewDecoder    = json.NewDecoder\n\tNewEncoder    = json.NewEncoder\n)\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/jsoniter.go",
    "content": "// +build jsoniter\n\npackage restful\n\nimport \"github.com/json-iterator/go\"\n\nvar (\n\tjson          = jsoniter.ConfigCompatibleWithStandardLibrary\n\tMarshalIndent = json.MarshalIndent\n\tNewDecoder    = json.NewDecoder\n\tNewEncoder    = json.NewEncoder\n)\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/jsr311.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// RouterJSR311 implements the flow for matching Requests to Routes (and consequently Resource Functions)\n// as specified by the JSR311 http://jsr311.java.net/nonav/releases/1.1/spec/spec.html.\n// RouterJSR311 implements the Router interface.\n// Concept of locators is not implemented.\ntype RouterJSR311 struct{}\n\n// SelectRoute is part of the Router interface and returns the best match\n// for the WebService and its Route for the given Request.\nfunc (r RouterJSR311) SelectRoute(\n\twebServices []*WebService,\n\thttpRequest *http.Request) (selectedService *WebService, selectedRoute *Route, err error) {\n\n\t// Identify the root resource class (WebService)\n\tdispatcher, finalMatch, err := r.detectDispatcher(httpRequest.URL.Path, webServices)\n\tif err != nil {\n\t\treturn nil, nil, NewError(http.StatusNotFound, \"\")\n\t}\n\t// Obtain the set of candidate methods (Routes)\n\troutes := r.selectRoutes(dispatcher, finalMatch)\n\tif len(routes) == 0 {\n\t\treturn dispatcher, nil, NewError(http.StatusNotFound, \"404: Page Not Found\")\n\t}\n\n\t// Identify the method (Route) that will handle the request\n\troute, ok := r.detectRoute(routes, httpRequest)\n\treturn dispatcher, route, ok\n}\n\n// ExtractParameters is used to obtain the path parameters from the route using the same matching\n// engine as the JSR 311 router.\nfunc (r RouterJSR311) ExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string {\n\twebServiceExpr := webService.pathExpr\n\twebServiceMatches := webServiceExpr.Matcher.FindStringSubmatch(urlPath)\n\tpathParameters := r.extractParams(webServiceExpr, webServiceMatches)\n\trouteExpr := route.pathExpr\n\trouteMatches := routeExpr.Matcher.FindStringSubmatch(webServiceMatches[len(webServiceMatches)-1])\n\trouteParams := r.extractParams(routeExpr, routeMatches)\n\tfor key, value := range routeParams {\n\t\tpathParameters[key] = value\n\t}\n\treturn pathParameters\n}\n\nfunc (RouterJSR311) extractParams(pathExpr *pathExpression, matches []string) map[string]string {\n\tparams := map[string]string{}\n\tfor i := 1; i < len(matches); i++ {\n\t\tif len(pathExpr.VarNames) >= i {\n\t\t\tparams[pathExpr.VarNames[i-1]] = matches[i]\n\t\t}\n\t}\n\treturn params\n}\n\n// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2\nfunc (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*Route, error) {\n\tcandidates := make([]*Route, 0, 8)\n\tfor i, each := range routes {\n\t\tok := true\n\t\tfor _, fn := range each.If {\n\t\t\tif !fn(httpRequest) {\n\t\t\t\tok = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif ok {\n\t\t\tcandidates = append(candidates, &routes[i])\n\t\t}\n\t}\n\tif len(candidates) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no Route found (from %d) that passes conditional checks\", len(routes))\n\t\t}\n\t\treturn nil, NewError(http.StatusNotFound, \"404: Not Found\")\n\t}\n\n\t// http method\n\tprevious := candidates\n\tcandidates = candidates[:0]\n\tfor _, each := range previous {\n\t\tif httpRequest.Method == each.Method {\n\t\t\tcandidates = append(candidates, each)\n\t\t}\n\t}\n\tif len(candidates) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no Route found (in %d routes) that matches HTTP method %s\\n\", len(previous), httpRequest.Method)\n\t\t}\n\t\tallowed := []string{}\n\tallowedLoop:\n\t\tfor _, candidate := range previous {\n\t\t\tfor _, method := range allowed {\n\t\t\t\tif method == candidate.Method {\n\t\t\t\t\tcontinue allowedLoop\n\t\t\t\t}\n\t\t\t}\n\t\t\tallowed = append(allowed, candidate.Method)\n\t\t}\n\t\theader := http.Header{\"Allow\": []string{strings.Join(allowed, \", \")}}\n\t\treturn nil, NewErrorWithHeader(http.StatusMethodNotAllowed, \"405: Method Not Allowed\", header)\n\t}\n\n\t// content-type\n\tcontentType := httpRequest.Header.Get(HEADER_ContentType)\n\tprevious = candidates\n\tcandidates = candidates[:0]\n\tfor _, each := range previous {\n\t\tif each.matchesContentType(contentType) {\n\t\t\tcandidates = append(candidates, each)\n\t\t}\n\t}\n\tif len(candidates) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no Route found (from %d) that matches HTTP Content-Type: %s\\n\", len(previous), contentType)\n\t\t}\n\t\tif httpRequest.ContentLength > 0 {\n\t\t\treturn nil, NewError(http.StatusUnsupportedMediaType, \"415: Unsupported Media Type\")\n\t\t}\n\t}\n\n\t// accept\n\tprevious = candidates\n\tcandidates = candidates[:0]\n\taccept := httpRequest.Header.Get(HEADER_Accept)\n\tif len(accept) == 0 {\n\t\taccept = \"*/*\"\n\t}\n\tfor _, each := range previous {\n\t\tif each.matchesAccept(accept) {\n\t\t\tcandidates = append(candidates, each)\n\t\t}\n\t}\n\tif len(candidates) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no Route found (from %d) that matches HTTP Accept: %s\\n\", len(previous), accept)\n\t\t}\n\t\tavailable := []string{}\n\t\tfor _, candidate := range previous {\n\t\t\tavailable = append(available, candidate.Produces...)\n\t\t}\n\t\t// if POST,PUT,PATCH without body\n\t\tmethod, length := httpRequest.Method, httpRequest.Header.Get(\"Content-Length\")\n\t\tif (method == http.MethodPost ||\n\t\t\tmethod == http.MethodPut ||\n\t\t\tmethod == http.MethodPatch) && length == \"\" {\n\t\t\treturn nil, NewError(\n\t\t\t\thttp.StatusUnsupportedMediaType,\n\t\t\t\tfmt.Sprintf(\"415: Unsupported Media Type\\n\\nAvailable representations: %s\", strings.Join(available, \", \")),\n\t\t\t)\n\t\t}\n\t\treturn nil, NewError(\n\t\t\thttp.StatusNotAcceptable,\n\t\t\tfmt.Sprintf(\"406: Not Acceptable\\n\\nAvailable representations: %s\", strings.Join(available, \", \")),\n\t\t)\n\t}\n\t// return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil\n\treturn candidates[0], nil\n}\n\n// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2\n// n/m > n/* > */*\nfunc (r RouterJSR311) bestMatchByMedia(routes []Route, contentType string, accept string) *Route {\n\t// TODO\n\treturn &routes[0]\n}\n\n// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2  (step 2)\nfunc (r RouterJSR311) selectRoutes(dispatcher *WebService, pathRemainder string) []Route {\n\tfiltered := &sortableRouteCandidates{}\n\tfor _, each := range dispatcher.Routes() {\n\t\tpathExpr := each.pathExpr\n\t\tmatches := pathExpr.Matcher.FindStringSubmatch(pathRemainder)\n\t\tif matches != nil {\n\t\t\tlastMatch := matches[len(matches)-1]\n\t\t\tif len(lastMatch) == 0 || lastMatch == \"/\" { // do not include if value is neither empty nor ‘/’.\n\t\t\t\tfiltered.candidates = append(filtered.candidates,\n\t\t\t\t\trouteCandidate{each, len(matches) - 1, pathExpr.LiteralCount, pathExpr.VarCount})\n\t\t\t}\n\t\t}\n\t}\n\tif len(filtered.candidates) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"WebService on path %s has no routes that match URL path remainder:%s\\n\", dispatcher.rootPath, pathRemainder)\n\t\t}\n\t\treturn []Route{}\n\t}\n\tsort.Sort(sort.Reverse(filtered))\n\n\t// select other routes from candidates whoes expression matches rmatch\n\tmatchingRoutes := []Route{filtered.candidates[0].route}\n\tfor c := 1; c < len(filtered.candidates); c++ {\n\t\teach := filtered.candidates[c]\n\t\tif each.route.pathExpr.Matcher.MatchString(pathRemainder) {\n\t\t\tmatchingRoutes = append(matchingRoutes, each.route)\n\t\t}\n\t}\n\treturn matchingRoutes\n}\n\n// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 (step 1)\nfunc (r RouterJSR311) detectDispatcher(requestPath string, dispatchers []*WebService) (*WebService, string, error) {\n\tfiltered := &sortableDispatcherCandidates{}\n\tfor _, each := range dispatchers {\n\t\tmatches := each.pathExpr.Matcher.FindStringSubmatch(requestPath)\n\t\tif matches != nil {\n\t\t\tfiltered.candidates = append(filtered.candidates,\n\t\t\t\tdispatcherCandidate{each, matches[len(matches)-1], len(matches), each.pathExpr.LiteralCount, each.pathExpr.VarCount})\n\t\t}\n\t}\n\tif len(filtered.candidates) == 0 {\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no WebService was found to match URL path:%s\\n\", requestPath)\n\t\t}\n\t\treturn nil, \"\", errors.New(\"not found\")\n\t}\n\tsort.Sort(sort.Reverse(filtered))\n\treturn filtered.candidates[0].dispatcher, filtered.candidates[0].finalMatch, nil\n}\n\n// Types and functions to support the sorting of Routes\n\ntype routeCandidate struct {\n\troute           Route\n\tmatchesCount    int // the number of capturing groups\n\tliteralCount    int // the number of literal characters (means those not resulting from template variable substitution)\n\tnonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^  /]+?)’)\n}\n\nfunc (r routeCandidate) expressionToMatch() string {\n\treturn r.route.pathExpr.Source\n}\n\nfunc (r routeCandidate) String() string {\n\treturn fmt.Sprintf(\"(m=%d,l=%d,n=%d)\", r.matchesCount, r.literalCount, r.nonDefaultCount)\n}\n\ntype sortableRouteCandidates struct {\n\tcandidates []routeCandidate\n}\n\nfunc (rcs *sortableRouteCandidates) Len() int {\n\treturn len(rcs.candidates)\n}\nfunc (rcs *sortableRouteCandidates) Swap(i, j int) {\n\trcs.candidates[i], rcs.candidates[j] = rcs.candidates[j], rcs.candidates[i]\n}\nfunc (rcs *sortableRouteCandidates) Less(i, j int) bool {\n\tci := rcs.candidates[i]\n\tcj := rcs.candidates[j]\n\t// primary key\n\tif ci.literalCount < cj.literalCount {\n\t\treturn true\n\t}\n\tif ci.literalCount > cj.literalCount {\n\t\treturn false\n\t}\n\t// secundary key\n\tif ci.matchesCount < cj.matchesCount {\n\t\treturn true\n\t}\n\tif ci.matchesCount > cj.matchesCount {\n\t\treturn false\n\t}\n\t// tertiary key\n\tif ci.nonDefaultCount < cj.nonDefaultCount {\n\t\treturn true\n\t}\n\tif ci.nonDefaultCount > cj.nonDefaultCount {\n\t\treturn false\n\t}\n\t// quaternary key (\"source\" is interpreted as Path)\n\treturn ci.route.Path < cj.route.Path\n}\n\n// Types and functions to support the sorting of Dispatchers\n\ntype dispatcherCandidate struct {\n\tdispatcher      *WebService\n\tfinalMatch      string\n\tmatchesCount    int // the number of capturing groups\n\tliteralCount    int // the number of literal characters (means those not resulting from template variable substitution)\n\tnonDefaultCount int // the number of capturing groups with non-default regular expressions (i.e. not ‘([^  /]+?)’)\n}\ntype sortableDispatcherCandidates struct {\n\tcandidates []dispatcherCandidate\n}\n\nfunc (dc *sortableDispatcherCandidates) Len() int {\n\treturn len(dc.candidates)\n}\nfunc (dc *sortableDispatcherCandidates) Swap(i, j int) {\n\tdc.candidates[i], dc.candidates[j] = dc.candidates[j], dc.candidates[i]\n}\nfunc (dc *sortableDispatcherCandidates) Less(i, j int) bool {\n\tci := dc.candidates[i]\n\tcj := dc.candidates[j]\n\t// primary key\n\tif ci.matchesCount < cj.matchesCount {\n\t\treturn true\n\t}\n\tif ci.matchesCount > cj.matchesCount {\n\t\treturn false\n\t}\n\t// secundary key\n\tif ci.literalCount < cj.literalCount {\n\t\treturn true\n\t}\n\tif ci.literalCount > cj.literalCount {\n\t\treturn false\n\t}\n\t// tertiary key\n\treturn ci.nonDefaultCount < cj.nonDefaultCount\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/log/log.go",
    "content": "package log\n\nimport (\n\tstdlog \"log\"\n\t\"os\"\n)\n\n// StdLogger corresponds to a minimal subset of the interface satisfied by stdlib log.Logger\ntype StdLogger interface {\n\tPrint(v ...interface{})\n\tPrintf(format string, v ...interface{})\n}\n\nvar Logger StdLogger\n\nfunc init() {\n\t// default Logger\n\tSetLogger(stdlog.New(os.Stderr, \"[restful] \", stdlog.LstdFlags|stdlog.Lshortfile))\n}\n\n// SetLogger sets the logger for this package\nfunc SetLogger(customLogger StdLogger) {\n\tLogger = customLogger\n}\n\n// Print delegates to the Logger\nfunc Print(v ...interface{}) {\n\tLogger.Print(v...)\n}\n\n// Printf delegates to the Logger\nfunc Printf(format string, v ...interface{}) {\n\tLogger.Printf(format, v...)\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/logger.go",
    "content": "package restful\n\n// Copyright 2014 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\nimport (\n\t\"github.com/emicklei/go-restful/v3/log\"\n)\n\nvar trace bool = false\nvar traceLogger log.StdLogger\n\nfunc init() {\n\ttraceLogger = log.Logger // use the package logger by default\n}\n\n// TraceLogger enables detailed logging of Http request matching and filter invocation. Default no logger is set.\n// You may call EnableTracing() directly to enable trace logging to the package-wide logger.\nfunc TraceLogger(logger log.StdLogger) {\n\ttraceLogger = logger\n\tEnableTracing(logger != nil)\n}\n\n// SetLogger exposes the setter for the global logger on the top-level package\nfunc SetLogger(customLogger log.StdLogger) {\n\tlog.SetLogger(customLogger)\n}\n\n// EnableTracing can be used to Trace logging on and off.\nfunc EnableTracing(enabled bool) {\n\ttrace = enabled\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/mime.go",
    "content": "package restful\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype mime struct {\n\tmedia   string\n\tquality float64\n}\n\n// insertMime adds a mime to a list and keeps it sorted by quality.\nfunc insertMime(l []mime, e mime) []mime {\n\tfor i, each := range l {\n\t\t// if current mime has lower quality then insert before\n\t\tif e.quality > each.quality {\n\t\t\tleft := append([]mime{}, l[0:i]...)\n\t\t\treturn append(append(left, e), l[i:]...)\n\t\t}\n\t}\n\treturn append(l, e)\n}\n\nconst qFactorWeightingKey = \"q\"\n\n// sortedMimes returns a list of mime sorted (desc) by its specified quality.\n// e.g. text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\nfunc sortedMimes(accept string) (sorted []mime) {\n\tfor _, each := range strings.Split(accept, \",\") {\n\t\ttypeAndQuality := strings.Split(strings.Trim(each, \" \"), \";\")\n\t\tif len(typeAndQuality) == 1 {\n\t\t\tsorted = insertMime(sorted, mime{typeAndQuality[0], 1.0})\n\t\t} else {\n\t\t\t// take factor\n\t\t\tqAndWeight := strings.Split(typeAndQuality[1], \"=\")\n\t\t\tif len(qAndWeight) == 2 && strings.Trim(qAndWeight[0], \" \") == qFactorWeightingKey {\n\t\t\t\tf, err := strconv.ParseFloat(qAndWeight[1], 64)\n\t\t\t\tif err != nil {\n\t\t\t\t\ttraceLogger.Printf(\"unable to parse quality in %s, %v\", each, err)\n\t\t\t\t} else {\n\t\t\t\t\tsorted = insertMime(sorted, mime{typeAndQuality[0], f})\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tsorted = insertMime(sorted, mime{typeAndQuality[0], 1.0})\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/options_filter.go",
    "content": "package restful\n\nimport \"strings\"\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\n// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method\n// and provides the response with a set of allowed methods for the request URL Path.\n// As for any filter, you can also install it for a particular WebService within a Container.\n// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS).\nfunc (c *Container) OPTIONSFilter(req *Request, resp *Response, chain *FilterChain) {\n\tif \"OPTIONS\" != req.Request.Method {\n\t\tchain.ProcessFilter(req, resp)\n\t\treturn\n\t}\n\n\tarchs := req.Request.Header.Get(HEADER_AccessControlRequestHeaders)\n\tmethods := strings.Join(c.computeAllowedMethods(req), \",\")\n\torigin := req.Request.Header.Get(HEADER_Origin)\n\n\tresp.AddHeader(HEADER_Allow, methods)\n\tresp.AddHeader(HEADER_AccessControlAllowOrigin, origin)\n\tresp.AddHeader(HEADER_AccessControlAllowHeaders, archs)\n\tresp.AddHeader(HEADER_AccessControlAllowMethods, methods)\n}\n\n// OPTIONSFilter is a filter function that inspects the Http Request for the OPTIONS method\n// and provides the response with a set of allowed methods for the request URL Path.\n// Note: this filter is not needed when using CrossOriginResourceSharing (for CORS).\nfunc OPTIONSFilter() FilterFunction {\n\treturn DefaultContainer.OPTIONSFilter\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/parameter.go",
    "content": "package restful\n\nimport \"sort\"\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nconst (\n\t// PathParameterKind = indicator of Request parameter type \"path\"\n\tPathParameterKind = iota\n\n\t// QueryParameterKind = indicator of Request parameter type \"query\"\n\tQueryParameterKind\n\n\t// BodyParameterKind = indicator of Request parameter type \"body\"\n\tBodyParameterKind\n\n\t// HeaderParameterKind = indicator of Request parameter type \"header\"\n\tHeaderParameterKind\n\n\t// FormParameterKind = indicator of Request parameter type \"form\"\n\tFormParameterKind\n\n\t// MultiPartFormParameterKind = indicator of Request parameter type \"multipart/form-data\"\n\tMultiPartFormParameterKind\n\n\t// CollectionFormatCSV comma separated values `foo,bar`\n\tCollectionFormatCSV = CollectionFormat(\"csv\")\n\n\t// CollectionFormatSSV space separated values `foo bar`\n\tCollectionFormatSSV = CollectionFormat(\"ssv\")\n\n\t// CollectionFormatTSV tab separated values `foo\\tbar`\n\tCollectionFormatTSV = CollectionFormat(\"tsv\")\n\n\t// CollectionFormatPipes pipe separated values `foo|bar`\n\tCollectionFormatPipes = CollectionFormat(\"pipes\")\n\n\t// CollectionFormatMulti corresponds to multiple parameter instances instead of multiple values for a single\n\t// instance `foo=bar&foo=baz`. This is valid only for QueryParameters and FormParameters\n\tCollectionFormatMulti = CollectionFormat(\"multi\")\n)\n\ntype CollectionFormat string\n\nfunc (cf CollectionFormat) String() string {\n\treturn string(cf)\n}\n\n// Parameter is for documententing the parameter used in a Http Request\n// ParameterData kinds are Path,Query and Body\ntype Parameter struct {\n\tdata *ParameterData\n}\n\n// ParameterData represents the state of a Parameter.\n// It is made public to make it accessible to e.g. the Swagger package.\ntype ParameterData struct {\n\tExtensionProperties\n\tName, Description, DataType, DataFormat string\n\tKind                                    int\n\tRequired                                bool\n\t// AllowableValues is deprecated. Use PossibleValues instead\n\tAllowableValues  map[string]string\n\tPossibleValues   []string\n\tAllowMultiple    bool\n\tAllowEmptyValue  bool\n\tDefaultValue     string\n\tCollectionFormat string\n\tPattern          string\n\tMinimum          *float64\n\tMaximum          *float64\n\tMinLength        *int64\n\tMaxLength        *int64\n\tMinItems         *int64\n\tMaxItems         *int64\n\tUniqueItems      bool\n}\n\n// Data returns the state of the Parameter\nfunc (p *Parameter) Data() ParameterData {\n\treturn *p.data\n}\n\n// Kind returns the parameter type indicator (see const for valid values)\nfunc (p *Parameter) Kind() int {\n\treturn p.data.Kind\n}\n\nfunc (p *Parameter) bePath() *Parameter {\n\tp.data.Kind = PathParameterKind\n\treturn p\n}\nfunc (p *Parameter) beQuery() *Parameter {\n\tp.data.Kind = QueryParameterKind\n\treturn p\n}\nfunc (p *Parameter) beBody() *Parameter {\n\tp.data.Kind = BodyParameterKind\n\treturn p\n}\n\nfunc (p *Parameter) beHeader() *Parameter {\n\tp.data.Kind = HeaderParameterKind\n\treturn p\n}\n\nfunc (p *Parameter) beForm() *Parameter {\n\tp.data.Kind = FormParameterKind\n\treturn p\n}\n\nfunc (p *Parameter) beMultiPartForm() *Parameter {\n\tp.data.Kind = MultiPartFormParameterKind\n\treturn p\n}\n\n// Required sets the required field and returns the receiver\nfunc (p *Parameter) Required(required bool) *Parameter {\n\tp.data.Required = required\n\treturn p\n}\n\n// AllowMultiple sets the allowMultiple field and returns the receiver\nfunc (p *Parameter) AllowMultiple(multiple bool) *Parameter {\n\tp.data.AllowMultiple = multiple\n\treturn p\n}\n\n// AddExtension adds or updates a key=value pair to the extension map\nfunc (p *Parameter) AddExtension(key string, value interface{}) *Parameter {\n\tp.data.AddExtension(key, value)\n\treturn p\n}\n\n// AllowEmptyValue sets the AllowEmptyValue field and returns the receiver\nfunc (p *Parameter) AllowEmptyValue(multiple bool) *Parameter {\n\tp.data.AllowEmptyValue = multiple\n\treturn p\n}\n\n// AllowableValues is deprecated. Use PossibleValues instead. Both will be set.\nfunc (p *Parameter) AllowableValues(values map[string]string) *Parameter {\n\tp.data.AllowableValues = values\n\n\tallowableSortedKeys := make([]string, 0, len(values))\n\tfor k := range values {\n\t\tallowableSortedKeys = append(allowableSortedKeys, k)\n\t}\n\tsort.Strings(allowableSortedKeys)\n\n\tp.data.PossibleValues = make([]string, 0, len(values))\n\tfor _, k := range allowableSortedKeys {\n\t\tp.data.PossibleValues = append(p.data.PossibleValues, values[k])\n\t}\n\treturn p\n}\n\n// PossibleValues sets the possible values field and returns the receiver\nfunc (p *Parameter) PossibleValues(values []string) *Parameter {\n\tp.data.PossibleValues = values\n\treturn p\n}\n\n// DataType sets the dataType field and returns the receiver\nfunc (p *Parameter) DataType(typeName string) *Parameter {\n\tp.data.DataType = typeName\n\treturn p\n}\n\n// DataFormat sets the dataFormat field for Swagger UI\nfunc (p *Parameter) DataFormat(formatName string) *Parameter {\n\tp.data.DataFormat = formatName\n\treturn p\n}\n\n// DefaultValue sets the default value field and returns the receiver\nfunc (p *Parameter) DefaultValue(stringRepresentation string) *Parameter {\n\tp.data.DefaultValue = stringRepresentation\n\treturn p\n}\n\n// Description sets the description value field and returns the receiver\nfunc (p *Parameter) Description(doc string) *Parameter {\n\tp.data.Description = doc\n\treturn p\n}\n\n// CollectionFormat sets the collection format for an array type\nfunc (p *Parameter) CollectionFormat(format CollectionFormat) *Parameter {\n\tp.data.CollectionFormat = format.String()\n\treturn p\n}\n\n// Pattern sets the pattern field and returns the receiver\nfunc (p *Parameter) Pattern(pattern string) *Parameter {\n\tp.data.Pattern = pattern\n\treturn p\n}\n\n// Minimum sets the minimum field and returns the receiver\nfunc (p *Parameter) Minimum(minimum float64) *Parameter {\n\tp.data.Minimum = &minimum\n\treturn p\n}\n\n// Maximum sets the maximum field and returns the receiver\nfunc (p *Parameter) Maximum(maximum float64) *Parameter {\n\tp.data.Maximum = &maximum\n\treturn p\n}\n\n// MinLength sets the minLength field and returns the receiver\nfunc (p *Parameter) MinLength(minLength int64) *Parameter {\n\tp.data.MinLength = &minLength\n\treturn p\n}\n\n// MaxLength sets the maxLength field and returns the receiver\nfunc (p *Parameter) MaxLength(maxLength int64) *Parameter {\n\tp.data.MaxLength = &maxLength\n\treturn p\n}\n\n// MinItems sets the minItems field and returns the receiver\nfunc (p *Parameter) MinItems(minItems int64) *Parameter {\n\tp.data.MinItems = &minItems\n\treturn p\n}\n\n// MaxItems sets the maxItems field and returns the receiver\nfunc (p *Parameter) MaxItems(maxItems int64) *Parameter {\n\tp.data.MaxItems = &maxItems\n\treturn p\n}\n\n// UniqueItems sets the uniqueItems field and returns the receiver\nfunc (p *Parameter) UniqueItems(uniqueItems bool) *Parameter {\n\tp.data.UniqueItems = uniqueItems\n\treturn p\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/path_expression.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// PathExpression holds a compiled path expression (RegExp) needed to match against\n// Http request paths and to extract path parameter values.\ntype pathExpression struct {\n\tLiteralCount int      // the number of literal characters (means those not resulting from template variable substitution)\n\tVarNames     []string // the names of parameters (enclosed by {}) in the path\n\tVarCount     int      // the number of named parameters (enclosed by {}) in the path\n\tMatcher      *regexp.Regexp\n\tSource       string // Path as defined by the RouteBuilder\n\ttokens       []string\n}\n\n// NewPathExpression creates a PathExpression from the input URL path.\n// Returns an error if the path is invalid.\nfunc newPathExpression(path string) (*pathExpression, error) {\n\texpression, literalCount, varNames, varCount, tokens := templateToRegularExpression(path)\n\tcompiled, err := regexp.Compile(expression)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &pathExpression{literalCount, varNames, varCount, compiled, expression, tokens}, nil\n}\n\n// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-370003.7.3\nfunc templateToRegularExpression(template string) (expression string, literalCount int, varNames []string, varCount int, tokens []string) {\n\tvar buffer bytes.Buffer\n\tbuffer.WriteString(\"^\")\n\t//tokens = strings.Split(template, \"/\")\n\ttokens = tokenizePath(template)\n\tfor _, each := range tokens {\n\t\tif each == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tbuffer.WriteString(\"/\")\n\t\tif strings.HasPrefix(each, \"{\") {\n\t\t\t// check for regular expression in variable\n\t\t\tcolon := strings.Index(each, \":\")\n\t\t\tvar varName string\n\t\t\tif colon != -1 {\n\t\t\t\t// extract expression\n\t\t\t\tvarName = strings.TrimSpace(each[1:colon])\n\t\t\t\tparamExpr := strings.TrimSpace(each[colon+1 : len(each)-1])\n\t\t\t\tif paramExpr == \"*\" { // special case\n\t\t\t\t\tbuffer.WriteString(\"(.*)\")\n\t\t\t\t} else {\n\t\t\t\t\tbuffer.WriteString(fmt.Sprintf(\"(%s)\", paramExpr)) // between colon and closing moustache\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// plain var\n\t\t\t\tvarName = strings.TrimSpace(each[1 : len(each)-1])\n\t\t\t\tbuffer.WriteString(\"([^/]+?)\")\n\t\t\t}\n\t\t\tvarNames = append(varNames, varName)\n\t\t\tvarCount += 1\n\t\t} else {\n\t\t\tliteralCount += len(each)\n\t\t\tencoded := each // TODO URI encode\n\t\t\tbuffer.WriteString(regexp.QuoteMeta(encoded))\n\t\t}\n\t}\n\treturn strings.TrimRight(buffer.String(), \"/\") + \"(/.*)?$\", literalCount, varNames, varCount, tokens\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/path_processor.go",
    "content": "package restful\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n)\n\n// Copyright 2018 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\n// PathProcessor is extra behaviour that a Router can provide to extract path parameters from the path.\n// If a Router does not implement this interface then the default behaviour will be used.\ntype PathProcessor interface {\n\t// ExtractParameters gets the path parameters defined in the route and webService from the urlPath\n\tExtractParameters(route *Route, webService *WebService, urlPath string) map[string]string\n}\n\ntype defaultPathProcessor struct{}\n\n// Extract the parameters from the request url path\nfunc (d defaultPathProcessor) ExtractParameters(r *Route, _ *WebService, urlPath string) map[string]string {\n\turlParts := tokenizePath(urlPath)\n\tpathParameters := map[string]string{}\n\tfor i, key := range r.pathParts {\n\t\tvar value string\n\t\tif i >= len(urlParts) {\n\t\t\tvalue = \"\"\n\t\t} else {\n\t\t\tvalue = urlParts[i]\n\t\t}\n\t\tif r.hasCustomVerb && hasCustomVerb(key) {\n\t\t\tkey = removeCustomVerb(key)\n\t\t\tvalue = removeCustomVerb(value)\n\t\t}\n\n\t\tif strings.Index(key, \"{\") > -1 { // path-parameter\n\t\t\tif colon := strings.Index(key, \":\"); colon != -1 {\n\t\t\t\t// extract by regex\n\t\t\t\tregPart := key[colon+1 : len(key)-1]\n\t\t\t\tkeyPart := key[1:colon]\n\t\t\t\tif regPart == \"*\" {\n\t\t\t\t\tpathParameters[keyPart] = untokenizePath(i, urlParts)\n\t\t\t\t\tbreak\n\t\t\t\t} else {\n\t\t\t\t\tpathParameters[keyPart] = value\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// without enclosing {}\n\t\t\t\tstartIndex := strings.Index(key, \"{\")\n\t\t\t\tendKeyIndex := strings.Index(key, \"}\")\n\n\t\t\t\tsuffixLength := len(key) - endKeyIndex - 1\n\t\t\t\tendValueIndex := len(value) - suffixLength\n\n\t\t\t\tpathParameters[key[startIndex+1:endKeyIndex]] = value[startIndex:endValueIndex]\n\t\t\t}\n\t\t}\n\t}\n\treturn pathParameters\n}\n\n// Untokenize back into an URL path using the slash separator\nfunc untokenizePath(offset int, parts []string) string {\n\tvar buffer bytes.Buffer\n\tfor p := offset; p < len(parts); p++ {\n\t\tbuffer.WriteString(parts[p])\n\t\t// do not end\n\t\tif p < len(parts)-1 {\n\t\t\tbuffer.WriteString(\"/\")\n\t\t}\n\t}\n\treturn buffer.String()\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/request.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"compress/zlib\"\n\t\"net/http\"\n)\n\nvar defaultRequestContentType string\n\n// Request is a wrapper for a http Request that provides convenience methods\ntype Request struct {\n\tRequest        *http.Request\n\tpathParameters map[string]string\n\tattributes     map[string]interface{} // for storing request-scoped values\n\tselectedRoute  *Route                 // is nil when no route was matched\n}\n\nfunc NewRequest(httpRequest *http.Request) *Request {\n\treturn &Request{\n\t\tRequest:        httpRequest,\n\t\tpathParameters: map[string]string{},\n\t\tattributes:     map[string]interface{}{},\n\t} // empty parameters, attributes\n}\n\n// If ContentType is missing or */* is given then fall back to this type, otherwise\n// a \"Unable to unmarshal content of type:\" response is returned.\n// Valid values are restful.MIME_JSON and restful.MIME_XML\n// Example:\n//\n//\trestful.DefaultRequestContentType(restful.MIME_JSON)\nfunc DefaultRequestContentType(mime string) {\n\tdefaultRequestContentType = mime\n}\n\n// PathParameter accesses the Path parameter value by its name\nfunc (r *Request) PathParameter(name string) string {\n\treturn r.pathParameters[name]\n}\n\n// PathParameters accesses the Path parameter values\nfunc (r *Request) PathParameters() map[string]string {\n\treturn r.pathParameters\n}\n\n// QueryParameter returns the (first) Query parameter value by its name\nfunc (r *Request) QueryParameter(name string) string {\n\treturn r.Request.URL.Query().Get(name)\n}\n\n// QueryParameters returns the all the query parameters values by name\nfunc (r *Request) QueryParameters(name string) []string {\n\treturn r.Request.URL.Query()[name]\n}\n\n// BodyParameter parses the body of the request (once for typically a POST or a PUT) and returns the value of the given name or an error.\nfunc (r *Request) BodyParameter(name string) (string, error) {\n\terr := r.Request.ParseForm()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn r.Request.PostFormValue(name), nil\n}\n\n// HeaderParameter returns the HTTP Header value of a Header name or empty if missing\nfunc (r *Request) HeaderParameter(name string) string {\n\treturn r.Request.Header.Get(name)\n}\n\n// ReadEntity checks the Accept header and reads the content into the entityPointer.\nfunc (r *Request) ReadEntity(entityPointer interface{}) (err error) {\n\tcontentType := r.Request.Header.Get(HEADER_ContentType)\n\tcontentEncoding := r.Request.Header.Get(HEADER_ContentEncoding)\n\n\t// check if the request body needs decompression\n\tif ENCODING_GZIP == contentEncoding {\n\t\tgzipReader := currentCompressorProvider.AcquireGzipReader()\n\t\tdefer currentCompressorProvider.ReleaseGzipReader(gzipReader)\n\t\tgzipReader.Reset(r.Request.Body)\n\t\tr.Request.Body = gzipReader\n\t} else if ENCODING_DEFLATE == contentEncoding {\n\t\tzlibReader, err := zlib.NewReader(r.Request.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.Request.Body = zlibReader\n\t}\n\n\t// lookup the EntityReader, use defaultRequestContentType if needed and provided\n\tentityReader, ok := entityAccessRegistry.accessorAt(contentType)\n\tif !ok {\n\t\tif len(defaultRequestContentType) != 0 {\n\t\t\tentityReader, ok = entityAccessRegistry.accessorAt(defaultRequestContentType)\n\t\t}\n\t\tif !ok {\n\t\t\treturn NewError(http.StatusBadRequest, \"Unable to unmarshal content of type:\"+contentType)\n\t\t}\n\t}\n\treturn entityReader.Read(r, entityPointer)\n}\n\n// SetAttribute adds or replaces the attribute with the given value.\nfunc (r *Request) SetAttribute(name string, value interface{}) {\n\tr.attributes[name] = value\n}\n\n// Attribute returns the value associated to the given name. Returns nil if absent.\nfunc (r Request) Attribute(name string) interface{} {\n\treturn r.attributes[name]\n}\n\n// SelectedRoutePath root path + route path that matched the request, e.g. /meetings/{id}/attendees\n// If no route was matched then return an empty string.\nfunc (r Request) SelectedRoutePath() string {\n\tif r.selectedRoute == nil {\n\t\treturn \"\"\n\t}\n\t// skip creating an accessor\n\treturn r.selectedRoute.Path\n}\n\n// SelectedRoute returns a reader to access the selected Route by the container\n// Returns nil if no route was matched.\nfunc (r Request) SelectedRoute() RouteReader {\n\tif r.selectedRoute == nil {\n\t\treturn nil\n\t}\n\treturn routeAccessor{route: r.selectedRoute}\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/response.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n)\n\n// DefaultResponseMimeType is DEPRECATED, use DefaultResponseContentType(mime)\nvar DefaultResponseMimeType string\n\n//PrettyPrintResponses controls the indentation feature of XML and JSON serialization\nvar PrettyPrintResponses = true\n\n// Response is a wrapper on the actual http ResponseWriter\n// It provides several convenience methods to prepare and write response content.\ntype Response struct {\n\thttp.ResponseWriter\n\trequestAccept string        // mime-type what the Http Request says it wants to receive\n\trouteProduces []string      // mime-types what the Route says it can produce\n\tstatusCode    int           // HTTP status code that has been written explicitly (if zero then net/http has written 200)\n\tcontentLength int           // number of bytes written for the response body\n\tprettyPrint   bool          // controls the indentation feature of XML and JSON serialization. It is initialized using var PrettyPrintResponses.\n\terr           error         // err property is kept when WriteError is called\n\thijacker      http.Hijacker // if underlying ResponseWriter supports it\n}\n\n// NewResponse creates a new response based on a http ResponseWriter.\nfunc NewResponse(httpWriter http.ResponseWriter) *Response {\n\thijacker, _ := httpWriter.(http.Hijacker)\n\treturn &Response{ResponseWriter: httpWriter, routeProduces: []string{}, statusCode: http.StatusOK, prettyPrint: PrettyPrintResponses, hijacker: hijacker}\n}\n\n// DefaultResponseContentType set a default.\n// If Accept header matching fails, fall back to this type.\n// Valid values are restful.MIME_JSON and restful.MIME_XML\n// Example:\n// \trestful.DefaultResponseContentType(restful.MIME_JSON)\nfunc DefaultResponseContentType(mime string) {\n\tDefaultResponseMimeType = mime\n}\n\n// InternalServerError writes the StatusInternalServerError header.\n// DEPRECATED, use WriteErrorString(http.StatusInternalServerError,reason)\nfunc (r Response) InternalServerError() Response {\n\tr.WriteHeader(http.StatusInternalServerError)\n\treturn r\n}\n\n// Hijack implements the http.Hijacker interface.  This expands\n// the Response to fulfill http.Hijacker if the underlying\n// http.ResponseWriter supports it.\nfunc (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tif r.hijacker == nil {\n\t\treturn nil, nil, errors.New(\"http.Hijacker not implemented by underlying http.ResponseWriter\")\n\t}\n\treturn r.hijacker.Hijack()\n}\n\n// PrettyPrint changes whether this response must produce pretty (line-by-line, indented) JSON or XML output.\nfunc (r *Response) PrettyPrint(bePretty bool) {\n\tr.prettyPrint = bePretty\n}\n\n// AddHeader is a shortcut for .Header().Add(header,value)\nfunc (r Response) AddHeader(header string, value string) Response {\n\tr.Header().Add(header, value)\n\treturn r\n}\n\n// SetRequestAccepts tells the response what Mime-type(s) the HTTP request said it wants to accept. Exposed for testing.\nfunc (r *Response) SetRequestAccepts(mime string) {\n\tr.requestAccept = mime\n}\n\n// EntityWriter returns the registered EntityWriter that the entity (requested resource)\n// can write according to what the request wants (Accept) and what the Route can produce or what the restful defaults say.\n// If called before WriteEntity and WriteHeader then a false return value can be used to write a 406: Not Acceptable.\nfunc (r *Response) EntityWriter() (EntityReaderWriter, bool) {\n\tsorted := sortedMimes(r.requestAccept)\n\tfor _, eachAccept := range sorted {\n\t\tfor _, eachProduce := range r.routeProduces {\n\t\t\tif eachProduce == eachAccept.media {\n\t\t\t\tif w, ok := entityAccessRegistry.accessorAt(eachAccept.media); ok {\n\t\t\t\t\treturn w, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif eachAccept.media == \"*/*\" {\n\t\t\tfor _, each := range r.routeProduces {\n\t\t\t\tif w, ok := entityAccessRegistry.accessorAt(each); ok {\n\t\t\t\t\treturn w, true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// if requestAccept is empty\n\twriter, ok := entityAccessRegistry.accessorAt(r.requestAccept)\n\tif !ok {\n\t\t// if not registered then fallback to the defaults (if set)\n\t\tif DefaultResponseMimeType == MIME_JSON {\n\t\t\treturn entityAccessRegistry.accessorAt(MIME_JSON)\n\t\t}\n\t\tif DefaultResponseMimeType == MIME_XML {\n\t\t\treturn entityAccessRegistry.accessorAt(MIME_XML)\n\t\t}\n\t\tif DefaultResponseMimeType == MIME_ZIP {\n\t\t\treturn entityAccessRegistry.accessorAt(MIME_ZIP)\n\t\t}\n\t\t// Fallback to whatever the route says it can produce.\n\t\t// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html\n\t\tfor _, each := range r.routeProduces {\n\t\t\tif w, ok := entityAccessRegistry.accessorAt(each); ok {\n\t\t\t\treturn w, true\n\t\t\t}\n\t\t}\n\t\tif trace {\n\t\t\ttraceLogger.Printf(\"no registered EntityReaderWriter found for %s\", r.requestAccept)\n\t\t}\n\t}\n\treturn writer, ok\n}\n\n// WriteEntity calls WriteHeaderAndEntity with Http Status OK (200)\nfunc (r *Response) WriteEntity(value interface{}) error {\n\treturn r.WriteHeaderAndEntity(http.StatusOK, value)\n}\n\n// WriteHeaderAndEntity marshals the value using the representation denoted by the Accept Header and the registered EntityWriters.\n// If no Accept header is specified (or */*) then respond with the Content-Type as specified by the first in the Route.Produces.\n// If an Accept header is specified then respond with the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header.\n// If the value is nil then no response is send except for the Http status. You may want to call WriteHeader(http.StatusNotFound) instead.\n// If there is no writer available that can represent the value in the requested MIME type then Http Status NotAcceptable is written.\n// Current implementation ignores any q-parameters in the Accept Header.\n// Returns an error if the value could not be written on the response.\nfunc (r *Response) WriteHeaderAndEntity(status int, value interface{}) error {\n\twriter, ok := r.EntityWriter()\n\tif !ok {\n\t\tr.WriteHeader(http.StatusNotAcceptable)\n\t\treturn nil\n\t}\n\treturn writer.Write(r, status, value)\n}\n\n// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value)\n// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter.\nfunc (r *Response) WriteAsXml(value interface{}) error {\n\treturn writeXML(r, http.StatusOK, MIME_XML, value)\n}\n\n// WriteHeaderAndXml is a convenience method for writing a status and value in xml (requires Xml tags on the value)\n// It uses the standard encoding/xml package for marshalling the value ; not using a registered EntityReaderWriter.\nfunc (r *Response) WriteHeaderAndXml(status int, value interface{}) error {\n\treturn writeXML(r, status, MIME_XML, value)\n}\n\n// WriteAsJson is a convenience method for writing a value in json.\n// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.\nfunc (r *Response) WriteAsJson(value interface{}) error {\n\treturn writeJSON(r, http.StatusOK, MIME_JSON, value)\n}\n\n// WriteJson is a convenience method for writing a value in Json with a given Content-Type.\n// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.\nfunc (r *Response) WriteJson(value interface{}, contentType string) error {\n\treturn writeJSON(r, http.StatusOK, contentType, value)\n}\n\n// WriteHeaderAndJson is a convenience method for writing the status and a value in Json with a given Content-Type.\n// It uses the standard encoding/json package for marshalling the value ; not using a registered EntityReaderWriter.\nfunc (r *Response) WriteHeaderAndJson(status int, value interface{}, contentType string) error {\n\treturn writeJSON(r, status, contentType, value)\n}\n\n// WriteError writes the http status and the error string on the response. err can be nil.\n// Return an error if writing was not successful.\nfunc (r *Response) WriteError(httpStatus int, err error) (writeErr error) {\n\tr.err = err\n\tif err == nil {\n\t\twriteErr = r.WriteErrorString(httpStatus, \"\")\n\t} else {\n\t\twriteErr = r.WriteErrorString(httpStatus, err.Error())\n\t}\n\treturn writeErr\n}\n\n// WriteServiceError is a convenience method for a responding with a status and a ServiceError\nfunc (r *Response) WriteServiceError(httpStatus int, err ServiceError) error {\n\tr.err = err\n\treturn r.WriteHeaderAndEntity(httpStatus, err)\n}\n\n// WriteErrorString is a convenience method for an error status with the actual error\nfunc (r *Response) WriteErrorString(httpStatus int, errorReason string) error {\n\tif r.err == nil {\n\t\t// if not called from WriteError\n\t\tr.err = errors.New(errorReason)\n\t}\n\tr.WriteHeader(httpStatus)\n\tif _, err := r.Write([]byte(errorReason)); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Flush implements http.Flusher interface, which sends any buffered data to the client.\nfunc (r *Response) Flush() {\n\tif f, ok := r.ResponseWriter.(http.Flusher); ok {\n\t\tf.Flush()\n\t} else if trace {\n\t\ttraceLogger.Printf(\"ResponseWriter %v doesn't support Flush\", r)\n\t}\n}\n\n// WriteHeader is overridden to remember the Status Code that has been written.\n// Changes to the Header of the response have no effect after this.\nfunc (r *Response) WriteHeader(httpStatus int) {\n\tr.statusCode = httpStatus\n\tr.ResponseWriter.WriteHeader(httpStatus)\n}\n\n// StatusCode returns the code that has been written using WriteHeader.\nfunc (r Response) StatusCode() int {\n\tif 0 == r.statusCode {\n\t\t// no status code has been written yet; assume OK\n\t\treturn http.StatusOK\n\t}\n\treturn r.statusCode\n}\n\n// Write writes the data to the connection as part of an HTTP reply.\n// Write is part of http.ResponseWriter interface.\nfunc (r *Response) Write(bytes []byte) (int, error) {\n\twritten, err := r.ResponseWriter.Write(bytes)\n\tr.contentLength += written\n\treturn written, err\n}\n\n// ContentLength returns the number of bytes written for the response content.\n// Note that this value is only correct if all data is written through the Response using its Write* methods.\n// Data written directly using the underlying http.ResponseWriter is not accounted for.\nfunc (r Response) ContentLength() int {\n\treturn r.contentLength\n}\n\n// CloseNotify is part of http.CloseNotifier interface\nfunc (r Response) CloseNotify() <-chan bool {\n\treturn r.ResponseWriter.(http.CloseNotifier).CloseNotify()\n}\n\n// Error returns the err created by WriteError\nfunc (r Response) Error() error {\n\treturn r.err\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/route.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"net/http\"\n\t\"strings\"\n)\n\n// RouteFunction declares the signature of a function that can be bound to a Route.\ntype RouteFunction func(*Request, *Response)\n\n// RouteSelectionConditionFunction declares the signature of a function that\n// can be used to add extra conditional logic when selecting whether the route\n// matches the HTTP request.\ntype RouteSelectionConditionFunction func(httpRequest *http.Request) bool\n\n// Route binds a HTTP Method,Path,Consumes combination to a RouteFunction.\ntype Route struct {\n\tExtensionProperties\n\tMethod   string\n\tProduces []string\n\tConsumes []string\n\tPath     string // webservice root path + described path\n\tFunction RouteFunction\n\tFilters  []FilterFunction\n\tIf       []RouteSelectionConditionFunction\n\n\t// cached values for dispatching\n\trelativePath string\n\tpathParts    []string\n\tpathExpr     *pathExpression // cached compilation of relativePath as RegExp\n\n\t// documentation\n\tDoc                     string\n\tNotes                   string\n\tOperation               string\n\tParameterDocs           []*Parameter\n\tResponseErrors          map[int]ResponseError\n\tDefaultResponse         *ResponseError\n\tReadSample, WriteSample interface{} // structs that model an example request or response payload\n\n\t// Extra information used to store custom information about the route.\n\tMetadata map[string]interface{}\n\n\t// marks a route as deprecated\n\tDeprecated bool\n\n\t//Overrides the container.contentEncodingEnabled\n\tcontentEncodingEnabled *bool\n\n\t// indicate route path has custom verb\n\thasCustomVerb bool\n\n\t// if a request does not include a content-type header then\n\t// depending on the method, it may return a 415 Unsupported Media\n\t// Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,...\n\tallowedMethodsWithoutContentType []string\n}\n\n// Initialize for Route\nfunc (r *Route) postBuild() {\n\tr.pathParts = tokenizePath(r.Path)\n\tr.hasCustomVerb = hasCustomVerb(r.Path)\n}\n\n// Create Request and Response from their http versions\nfunc (r *Route) wrapRequestResponse(httpWriter http.ResponseWriter, httpRequest *http.Request, pathParams map[string]string) (*Request, *Response) {\n\twrappedRequest := NewRequest(httpRequest)\n\twrappedRequest.pathParameters = pathParams\n\twrappedRequest.selectedRoute = r\n\twrappedResponse := NewResponse(httpWriter)\n\twrappedResponse.requestAccept = httpRequest.Header.Get(HEADER_Accept)\n\twrappedResponse.routeProduces = r.Produces\n\treturn wrappedRequest, wrappedResponse\n}\n\nfunc stringTrimSpaceCutset(r rune) bool {\n\treturn r == ' '\n}\n\n// Return whether the mimeType matches to what this Route can produce.\nfunc (r Route) matchesAccept(mimeTypesWithQuality string) bool {\n\tremaining := mimeTypesWithQuality\n\tfor {\n\t\tvar mimeType string\n\t\tif end := strings.Index(remaining, \",\"); end == -1 {\n\t\t\tmimeType, remaining = remaining, \"\"\n\t\t} else {\n\t\t\tmimeType, remaining = remaining[:end], remaining[end+1:]\n\t\t}\n\t\tif quality := strings.Index(mimeType, \";\"); quality != -1 {\n\t\t\tmimeType = mimeType[:quality]\n\t\t}\n\t\tmimeType = strings.TrimFunc(mimeType, stringTrimSpaceCutset)\n\t\tif mimeType == \"*/*\" {\n\t\t\treturn true\n\t\t}\n\t\tfor _, producibleType := range r.Produces {\n\t\t\tif producibleType == \"*/*\" || producibleType == mimeType {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\tif len(remaining) == 0 {\n\t\t\treturn false\n\t\t}\n\t}\n}\n\n// Return whether this Route can consume content with a type specified by mimeTypes (can be empty).\nfunc (r Route) matchesContentType(mimeTypes string) bool {\n\n\tif len(r.Consumes) == 0 {\n\t\t// did not specify what it can consume ;  any media type (“*/*”) is assumed\n\t\treturn true\n\t}\n\n\tif len(mimeTypes) == 0 {\n\t\t// idempotent methods with (most-likely or guaranteed) empty content match missing Content-Type\n\t\tm := r.Method\n\t\t// if route specifies less or non-idempotent methods then use that\n\t\tif len(r.allowedMethodsWithoutContentType) > 0 {\n\t\t\tfor _, each := range r.allowedMethodsWithoutContentType {\n\t\t\t\tif m == each {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif m == \"GET\" || m == \"HEAD\" || m == \"OPTIONS\" || m == \"DELETE\" || m == \"TRACE\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\t// proceed with default\n\t\tmimeTypes = MIME_OCTET\n\t}\n\n\tremaining := mimeTypes\n\tfor {\n\t\tvar mimeType string\n\t\tif end := strings.Index(remaining, \",\"); end == -1 {\n\t\t\tmimeType, remaining = remaining, \"\"\n\t\t} else {\n\t\t\tmimeType, remaining = remaining[:end], remaining[end+1:]\n\t\t}\n\t\tif quality := strings.Index(mimeType, \";\"); quality != -1 {\n\t\t\tmimeType = mimeType[:quality]\n\t\t}\n\t\tmimeType = strings.TrimFunc(mimeType, stringTrimSpaceCutset)\n\t\tfor _, consumeableType := range r.Consumes {\n\t\t\tif consumeableType == \"*/*\" || consumeableType == mimeType {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\tif len(remaining) == 0 {\n\t\t\treturn false\n\t\t}\n\t}\n}\n\n// Tokenize an URL path using the slash separator ; the result does not have empty tokens\nfunc tokenizePath(path string) []string {\n\tif \"/\" == path {\n\t\treturn nil\n\t}\n\treturn strings.Split(strings.TrimLeft(path, \"/\"), \"/\")\n}\n\n// for debugging\nfunc (r *Route) String() string {\n\treturn r.Method + \" \" + r.Path\n}\n\n// EnableContentEncoding (default=false) allows for GZIP or DEFLATE encoding of responses. Overrides the container.contentEncodingEnabled value.\nfunc (r *Route) EnableContentEncoding(enabled bool) {\n\tr.contentEncodingEnabled = &enabled\n}\n\nvar TrimRightSlashEnabled = false\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/route_builder.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync/atomic\"\n\n\t\"github.com/emicklei/go-restful/v3/log\"\n)\n\n// RouteBuilder is a helper to construct Routes.\ntype RouteBuilder struct {\n\trootPath                         string\n\tcurrentPath                      string\n\tproduces                         []string\n\tconsumes                         []string\n\thttpMethod                       string        // required\n\tfunction                         RouteFunction // required\n\tfilters                          []FilterFunction\n\tconditions                       []RouteSelectionConditionFunction\n\tallowedMethodsWithoutContentType []string // see Route\n\n\ttypeNameHandleFunc TypeNameHandleFunction // required\n\n\t// documentation\n\tdoc                     string\n\tnotes                   string\n\toperation               string\n\treadSample, writeSample interface{}\n\tparameters              []*Parameter\n\terrorMap                map[int]ResponseError\n\tdefaultResponse         *ResponseError\n\tmetadata                map[string]interface{}\n\textensions              map[string]interface{}\n\tdeprecated              bool\n\tcontentEncodingEnabled  *bool\n}\n\n// Do evaluates each argument with the RouteBuilder itself.\n// This allows you to follow DRY principles without breaking the fluent programming style.\n// Example:\n//\n//\tws.Route(ws.DELETE(\"/{name}\").To(t.deletePerson).Do(Returns200, Returns500))\n//\n//\tfunc Returns500(b *RouteBuilder) {\n//\t\tb.Returns(500, \"Internal Server Error\", restful.ServiceError{})\n//\t}\nfunc (b *RouteBuilder) Do(oneArgBlocks ...func(*RouteBuilder)) *RouteBuilder {\n\tfor _, each := range oneArgBlocks {\n\t\teach(b)\n\t}\n\treturn b\n}\n\n// To bind the route to a function.\n// If this route is matched with the incoming Http Request then call this function with the *Request,*Response pair. Required.\nfunc (b *RouteBuilder) To(function RouteFunction) *RouteBuilder {\n\tb.function = function\n\treturn b\n}\n\n// Method specifies what HTTP method to match. Required.\nfunc (b *RouteBuilder) Method(method string) *RouteBuilder {\n\tb.httpMethod = method\n\treturn b\n}\n\n// Produces specifies what MIME types can be produced ; the matched one will appear in the Content-Type Http header.\nfunc (b *RouteBuilder) Produces(mimeTypes ...string) *RouteBuilder {\n\tb.produces = mimeTypes\n\treturn b\n}\n\n// Consumes specifies what MIME types can be consumes ; the Accept Http header must matched any of these\nfunc (b *RouteBuilder) Consumes(mimeTypes ...string) *RouteBuilder {\n\tb.consumes = mimeTypes\n\treturn b\n}\n\n// Path specifies the relative (w.r.t WebService root path) URL path to match. Default is \"/\".\nfunc (b *RouteBuilder) Path(subPath string) *RouteBuilder {\n\tb.currentPath = subPath\n\treturn b\n}\n\n// Doc tells what this route is all about. Optional.\nfunc (b *RouteBuilder) Doc(documentation string) *RouteBuilder {\n\tb.doc = documentation\n\treturn b\n}\n\n// Notes is a verbose explanation of the operation behavior. Optional.\nfunc (b *RouteBuilder) Notes(notes string) *RouteBuilder {\n\tb.notes = notes\n\treturn b\n}\n\n// Reads tells what resource type will be read from the request payload. Optional.\n// A parameter of type \"body\" is added ,required is set to true and the dataType is set to the qualified name of the sample's type.\nfunc (b *RouteBuilder) Reads(sample interface{}, optionalDescription ...string) *RouteBuilder {\n\tfn := b.typeNameHandleFunc\n\tif fn == nil {\n\t\tfn = reflectTypeName\n\t}\n\ttypeAsName := fn(sample)\n\tdescription := \"\"\n\tif len(optionalDescription) > 0 {\n\t\tdescription = optionalDescription[0]\n\t}\n\tb.readSample = sample\n\tbodyParameter := &Parameter{&ParameterData{Name: \"body\", Description: description}}\n\tbodyParameter.beBody()\n\tbodyParameter.Required(true)\n\tbodyParameter.DataType(typeAsName)\n\tb.Param(bodyParameter)\n\treturn b\n}\n\n// ParameterNamed returns a Parameter already known to the RouteBuilder. Returns nil if not.\n// Use this to modify or extend information for the Parameter (through its Data()).\nfunc (b RouteBuilder) ParameterNamed(name string) (p *Parameter) {\n\tfor _, each := range b.parameters {\n\t\tif each.Data().Name == name {\n\t\t\treturn each\n\t\t}\n\t}\n\treturn p\n}\n\n// Writes tells what resource type will be written as the response payload. Optional.\nfunc (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder {\n\tb.writeSample = sample\n\treturn b\n}\n\n// Param allows you to document the parameters of the Route. It adds a new Parameter (does not check for duplicates).\nfunc (b *RouteBuilder) Param(parameter *Parameter) *RouteBuilder {\n\tif b.parameters == nil {\n\t\tb.parameters = []*Parameter{}\n\t}\n\tb.parameters = append(b.parameters, parameter)\n\treturn b\n}\n\n// Operation allows you to document what the actual method/function call is of the Route.\n// Unless called, the operation name is derived from the RouteFunction set using To(..).\nfunc (b *RouteBuilder) Operation(name string) *RouteBuilder {\n\tb.operation = name\n\treturn b\n}\n\n// ReturnsError is deprecated, use Returns instead.\nfunc (b *RouteBuilder) ReturnsError(code int, message string, model interface{}) *RouteBuilder {\n\tlog.Print(\"ReturnsError is deprecated, use Returns instead.\")\n\treturn b.Returns(code, message, model)\n}\n\n// Returns allows you to document what responses (errors or regular) can be expected.\n// The model parameter is optional ; either pass a struct instance or use nil if not applicable.\nfunc (b *RouteBuilder) Returns(code int, message string, model interface{}) *RouteBuilder {\n\terr := ResponseError{\n\t\tCode:      code,\n\t\tMessage:   message,\n\t\tModel:     model,\n\t\tIsDefault: false, // this field is deprecated, use default response instead.\n\t}\n\t// lazy init because there is no NewRouteBuilder (yet)\n\tif b.errorMap == nil {\n\t\tb.errorMap = map[int]ResponseError{}\n\t}\n\tb.errorMap[code] = err\n\treturn b\n}\n\n// ReturnsWithHeaders is similar to Returns, but can specify response headers\nfunc (b *RouteBuilder) ReturnsWithHeaders(code int, message string, model interface{}, headers map[string]Header) *RouteBuilder {\n\tb.Returns(code, message, model)\n\terr := b.errorMap[code]\n\terr.Headers = headers\n\tb.errorMap[code] = err\n\treturn b\n}\n\n// DefaultReturns is a special Returns call that sets the default of the response.\nfunc (b *RouteBuilder) DefaultReturns(message string, model interface{}) *RouteBuilder {\n\tb.defaultResponse = &ResponseError{\n\t\tMessage: message,\n\t\tModel:   model,\n\t}\n\treturn b\n}\n\n// Metadata adds or updates a key=value pair to the metadata map.\nfunc (b *RouteBuilder) Metadata(key string, value interface{}) *RouteBuilder {\n\tif b.metadata == nil {\n\t\tb.metadata = map[string]interface{}{}\n\t}\n\tb.metadata[key] = value\n\treturn b\n}\n\n// AddExtension adds or updates a key=value pair to the extensions map.\nfunc (b *RouteBuilder) AddExtension(key string, value interface{}) *RouteBuilder {\n\tif b.extensions == nil {\n\t\tb.extensions = map[string]interface{}{}\n\t}\n\tb.extensions[key] = value\n\treturn b\n}\n\n// Deprecate sets the value of deprecated to true.  Deprecated routes have a special UI treatment to warn against use\nfunc (b *RouteBuilder) Deprecate() *RouteBuilder {\n\tb.deprecated = true\n\treturn b\n}\n\n// AllowedMethodsWithoutContentType overrides the default list GET,HEAD,OPTIONS,DELETE,TRACE\n// If a request does not include a content-type header then\n// depending on the method, it may return a 415 Unsupported Media.\n// Must have uppercase HTTP Method names such as GET,HEAD,OPTIONS,...\nfunc (b *RouteBuilder) AllowedMethodsWithoutContentType(methods []string) *RouteBuilder {\n\tb.allowedMethodsWithoutContentType = methods\n\treturn b\n}\n\n// ResponseError represents a response; not necessarily an error.\ntype ResponseError struct {\n\tExtensionProperties\n\tCode      int\n\tMessage   string\n\tModel     interface{}\n\tHeaders   map[string]Header\n\tIsDefault bool\n}\n\n// Header describes a header for a response of the API\n//\n// For more information: http://goo.gl/8us55a#headerObject\ntype Header struct {\n\t*Items\n\tDescription string\n}\n\n// Items describe swagger simple schemas for headers\ntype Items struct {\n\tType             string\n\tFormat           string\n\tItems            *Items\n\tCollectionFormat string\n\tDefault          interface{}\n}\n\nfunc (b *RouteBuilder) servicePath(path string) *RouteBuilder {\n\tb.rootPath = path\n\treturn b\n}\n\n// Filter appends a FilterFunction to the end of filters for this Route to build.\nfunc (b *RouteBuilder) Filter(filter FilterFunction) *RouteBuilder {\n\tb.filters = append(b.filters, filter)\n\treturn b\n}\n\n// If sets a condition function that controls matching the Route based on custom logic.\n// The condition function is provided the HTTP request and should return true if the route\n// should be considered.\n//\n// Efficiency note: the condition function is called before checking the method, produces, and\n// consumes criteria, so that the correct HTTP status code can be returned.\n//\n// Lifecycle note: no filter functions have been called prior to calling the condition function,\n// so the condition function should not depend on any context that might be set up by container\n// or route filters.\nfunc (b *RouteBuilder) If(condition RouteSelectionConditionFunction) *RouteBuilder {\n\tb.conditions = append(b.conditions, condition)\n\treturn b\n}\n\n// ContentEncodingEnabled allows you to override the Containers value for auto-compressing this route response.\nfunc (b *RouteBuilder) ContentEncodingEnabled(enabled bool) *RouteBuilder {\n\tb.contentEncodingEnabled = &enabled\n\treturn b\n}\n\n// If no specific Route path then set to rootPath\n// If no specific Produces then set to rootProduces\n// If no specific Consumes then set to rootConsumes\nfunc (b *RouteBuilder) copyDefaults(rootProduces, rootConsumes []string) {\n\tif len(b.produces) == 0 {\n\t\tb.produces = rootProduces\n\t}\n\tif len(b.consumes) == 0 {\n\t\tb.consumes = rootConsumes\n\t}\n}\n\n// typeNameHandler sets the function that will convert types to strings in the parameter\n// and model definitions.\nfunc (b *RouteBuilder) typeNameHandler(handler TypeNameHandleFunction) *RouteBuilder {\n\tb.typeNameHandleFunc = handler\n\treturn b\n}\n\n// Build creates a new Route using the specification details collected by the RouteBuilder\nfunc (b *RouteBuilder) Build() Route {\n\tpathExpr, err := newPathExpression(b.currentPath)\n\tif err != nil {\n\t\tlog.Printf(\"Invalid path:%s because:%v\", b.currentPath, err)\n\t\tos.Exit(1)\n\t}\n\tif b.function == nil {\n\t\tlog.Printf(\"No function specified for route:\" + b.currentPath)\n\t\tos.Exit(1)\n\t}\n\toperationName := b.operation\n\tif len(operationName) == 0 && b.function != nil {\n\t\t// extract from definition\n\t\toperationName = nameOfFunction(b.function)\n\t}\n\troute := Route{\n\t\tMethod:                           b.httpMethod,\n\t\tPath:                             concatPath(b.rootPath, b.currentPath),\n\t\tProduces:                         b.produces,\n\t\tConsumes:                         b.consumes,\n\t\tFunction:                         b.function,\n\t\tFilters:                          b.filters,\n\t\tIf:                               b.conditions,\n\t\trelativePath:                     b.currentPath,\n\t\tpathExpr:                         pathExpr,\n\t\tDoc:                              b.doc,\n\t\tNotes:                            b.notes,\n\t\tOperation:                        operationName,\n\t\tParameterDocs:                    b.parameters,\n\t\tResponseErrors:                   b.errorMap,\n\t\tDefaultResponse:                  b.defaultResponse,\n\t\tReadSample:                       b.readSample,\n\t\tWriteSample:                      b.writeSample,\n\t\tMetadata:                         b.metadata,\n\t\tDeprecated:                       b.deprecated,\n\t\tcontentEncodingEnabled:           b.contentEncodingEnabled,\n\t\tallowedMethodsWithoutContentType: b.allowedMethodsWithoutContentType,\n\t}\n\troute.Extensions = b.extensions\n\troute.postBuild()\n\treturn route\n}\n\nfunc concatPath(path1, path2 string) string {\n\treturn path.Join(path1, path2)\n}\n\nvar anonymousFuncCount int32\n\n// nameOfFunction returns the short name of the function f for documentation.\n// It uses a runtime feature for debugging ; its value may change for later Go versions.\nfunc nameOfFunction(f interface{}) string {\n\tfun := runtime.FuncForPC(reflect.ValueOf(f).Pointer())\n\ttokenized := strings.Split(fun.Name(), \".\")\n\tlast := tokenized[len(tokenized)-1]\n\tlast = strings.TrimSuffix(last, \")·fm\") // < Go 1.5\n\tlast = strings.TrimSuffix(last, \")-fm\") // Go 1.5\n\tlast = strings.TrimSuffix(last, \"·fm\")  // < Go 1.5\n\tlast = strings.TrimSuffix(last, \"-fm\")  // Go 1.5\n\tif last == \"func1\" {                    // this could mean conflicts in API docs\n\t\tval := atomic.AddInt32(&anonymousFuncCount, 1)\n\t\tlast = \"func\" + fmt.Sprintf(\"%d\", val)\n\t\tatomic.StoreInt32(&anonymousFuncCount, val)\n\t}\n\treturn last\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/route_reader.go",
    "content": "package restful\n\n// Copyright 2021 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\ntype RouteReader interface {\n\tMethod() string\n\tConsumes() []string\n\tPath() string\n\tDoc() string\n\tNotes() string\n\tOperation() string\n\tParameterDocs() []*Parameter\n\t// Returns a copy\n\tMetadata() map[string]interface{}\n\tDeprecated() bool\n}\n\ntype routeAccessor struct {\n\troute *Route\n}\n\nfunc (r routeAccessor) Method() string {\n\treturn r.route.Method\n}\nfunc (r routeAccessor) Consumes() []string {\n\treturn r.route.Consumes[:]\n}\nfunc (r routeAccessor) Path() string {\n\treturn r.route.Path\n}\nfunc (r routeAccessor) Doc() string {\n\treturn r.route.Doc\n}\nfunc (r routeAccessor) Notes() string {\n\treturn r.route.Notes\n}\nfunc (r routeAccessor) Operation() string {\n\treturn r.route.Operation\n}\nfunc (r routeAccessor) ParameterDocs() []*Parameter {\n\treturn r.route.ParameterDocs[:]\n}\n\n// Returns a copy\nfunc (r routeAccessor) Metadata() map[string]interface{} {\n\treturn copyMap(r.route.Metadata)\n}\nfunc (r routeAccessor) Deprecated() bool {\n\treturn r.route.Deprecated\n}\n\n// https://stackoverflow.com/questions/23057785/how-to-copy-a-map\nfunc copyMap(m map[string]interface{}) map[string]interface{} {\n\tcp := make(map[string]interface{})\n\tfor k, v := range m {\n\t\tvm, ok := v.(map[string]interface{})\n\t\tif ok {\n\t\t\tcp[k] = copyMap(vm)\n\t\t} else {\n\t\t\tcp[k] = v\n\t\t}\n\t}\n\treturn cp\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/router.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport \"net/http\"\n\n// A RouteSelector finds the best matching Route given the input HTTP Request\n// RouteSelectors can optionally also implement the PathProcessor interface to also calculate the\n// path parameters after the route has been selected.\ntype RouteSelector interface {\n\n\t// SelectRoute finds a Route given the input HTTP Request and a list of WebServices.\n\t// It returns a selected Route and its containing WebService or an error indicating\n\t// a problem.\n\tSelectRoute(\n\t\twebServices []*WebService,\n\t\thttpRequest *http.Request) (selectedService *WebService, selected *Route, err error)\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/service_error.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request.\ntype ServiceError struct {\n\tCode    int\n\tMessage string\n\tHeader  http.Header\n}\n\n// NewError returns a ServiceError using the code and reason\nfunc NewError(code int, message string) ServiceError {\n\treturn ServiceError{Code: code, Message: message}\n}\n\n// NewErrorWithHeader returns a ServiceError using the code, reason and header\nfunc NewErrorWithHeader(code int, message string, header http.Header) ServiceError {\n\treturn ServiceError{Code: code, Message: message, Header: header}\n}\n\n// Error returns a text representation of the service error\nfunc (s ServiceError) Error() string {\n\treturn fmt.Sprintf(\"[ServiceError:%v] %v\", s.Code, s.Message)\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/web_service.go",
    "content": "package restful\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"github.com/emicklei/go-restful/v3/log\"\n)\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\n// WebService holds a collection of Route values that bind a Http Method + URL Path to a function.\ntype WebService struct {\n\trootPath       string\n\tpathExpr       *pathExpression // cached compilation of rootPath as RegExp\n\troutes         []Route\n\tproduces       []string\n\tconsumes       []string\n\tpathParameters []*Parameter\n\tfilters        []FilterFunction\n\tdocumentation  string\n\tapiVersion     string\n\n\ttypeNameHandleFunc TypeNameHandleFunction\n\n\tdynamicRoutes bool\n\n\t// protects 'routes' if dynamic routes are enabled\n\troutesLock sync.RWMutex\n}\n\nfunc (w *WebService) SetDynamicRoutes(enable bool) {\n\tw.dynamicRoutes = enable\n}\n\n// TypeNameHandleFunction declares functions that can handle translating the name of a sample object\n// into the restful documentation for the service.\ntype TypeNameHandleFunction func(sample interface{}) string\n\n// TypeNameHandler sets the function that will convert types to strings in the parameter\n// and model definitions. If not set, the web service will invoke\n// reflect.TypeOf(object).String().\nfunc (w *WebService) TypeNameHandler(handler TypeNameHandleFunction) *WebService {\n\tw.typeNameHandleFunc = handler\n\treturn w\n}\n\n// reflectTypeName is the default TypeNameHandleFunction and for a given object\n// returns the name that Go identifies it with (e.g. \"string\" or \"v1.Object\") via\n// the reflection API.\nfunc reflectTypeName(sample interface{}) string {\n\treturn reflect.TypeOf(sample).String()\n}\n\n// compilePathExpression ensures that the path is compiled into a RegEx for those routers that need it.\nfunc (w *WebService) compilePathExpression() {\n\tcompiled, err := newPathExpression(w.rootPath)\n\tif err != nil {\n\t\tlog.Printf(\"invalid path:%s because:%v\", w.rootPath, err)\n\t\tos.Exit(1)\n\t}\n\tw.pathExpr = compiled\n}\n\n// ApiVersion sets the API version for documentation purposes.\nfunc (w *WebService) ApiVersion(apiVersion string) *WebService {\n\tw.apiVersion = apiVersion\n\treturn w\n}\n\n// Version returns the API version for documentation purposes.\nfunc (w *WebService) Version() string { return w.apiVersion }\n\n// Path specifies the root URL template path of the WebService.\n// All Routes will be relative to this path.\nfunc (w *WebService) Path(root string) *WebService {\n\tw.rootPath = root\n\tif len(w.rootPath) == 0 {\n\t\tw.rootPath = \"/\"\n\t}\n\tw.compilePathExpression()\n\treturn w\n}\n\n// Param adds a PathParameter to document parameters used in the root path.\nfunc (w *WebService) Param(parameter *Parameter) *WebService {\n\tif w.pathParameters == nil {\n\t\tw.pathParameters = []*Parameter{}\n\t}\n\tw.pathParameters = append(w.pathParameters, parameter)\n\treturn w\n}\n\n// PathParameter creates a new Parameter of kind Path for documentation purposes.\n// It is initialized as required with string as its DataType.\nfunc (w *WebService) PathParameter(name, description string) *Parameter {\n\treturn PathParameter(name, description)\n}\n\n// PathParameter creates a new Parameter of kind Path for documentation purposes.\n// It is initialized as required with string as its DataType.\nfunc PathParameter(name, description string) *Parameter {\n\tp := &Parameter{&ParameterData{Name: name, Description: description, Required: true, DataType: \"string\"}}\n\tp.bePath()\n\treturn p\n}\n\n// QueryParameter creates a new Parameter of kind Query for documentation purposes.\n// It is initialized as not required with string as its DataType.\nfunc (w *WebService) QueryParameter(name, description string) *Parameter {\n\treturn QueryParameter(name, description)\n}\n\n// QueryParameter creates a new Parameter of kind Query for documentation purposes.\n// It is initialized as not required with string as its DataType.\nfunc QueryParameter(name, description string) *Parameter {\n\tp := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: \"string\", CollectionFormat: CollectionFormatCSV.String()}}\n\tp.beQuery()\n\treturn p\n}\n\n// BodyParameter creates a new Parameter of kind Body for documentation purposes.\n// It is initialized as required without a DataType.\nfunc (w *WebService) BodyParameter(name, description string) *Parameter {\n\treturn BodyParameter(name, description)\n}\n\n// BodyParameter creates a new Parameter of kind Body for documentation purposes.\n// It is initialized as required without a DataType.\nfunc BodyParameter(name, description string) *Parameter {\n\tp := &Parameter{&ParameterData{Name: name, Description: description, Required: true}}\n\tp.beBody()\n\treturn p\n}\n\n// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes.\n// It is initialized as not required with string as its DataType.\nfunc (w *WebService) HeaderParameter(name, description string) *Parameter {\n\treturn HeaderParameter(name, description)\n}\n\n// HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes.\n// It is initialized as not required with string as its DataType.\nfunc HeaderParameter(name, description string) *Parameter {\n\tp := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: \"string\"}}\n\tp.beHeader()\n\treturn p\n}\n\n// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes.\n// It is initialized as required with string as its DataType.\nfunc (w *WebService) FormParameter(name, description string) *Parameter {\n\treturn FormParameter(name, description)\n}\n\n// FormParameter creates a new Parameter of kind Form (using application/x-www-form-urlencoded) for documentation purposes.\n// It is initialized as required with string as its DataType.\nfunc FormParameter(name, description string) *Parameter {\n\tp := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: \"string\"}}\n\tp.beForm()\n\treturn p\n}\n\n// MultiPartFormParameter creates a new Parameter of kind Form (using multipart/form-data) for documentation purposes.\n// It is initialized as required with string as its DataType.\nfunc (w *WebService) MultiPartFormParameter(name, description string) *Parameter {\n\treturn MultiPartFormParameter(name, description)\n}\n\nfunc MultiPartFormParameter(name, description string) *Parameter {\n\tp := &Parameter{&ParameterData{Name: name, Description: description, Required: false, DataType: \"string\"}}\n\tp.beMultiPartForm()\n\treturn p\n}\n\n// Route creates a new Route using the RouteBuilder and add to the ordered list of Routes.\nfunc (w *WebService) Route(builder *RouteBuilder) *WebService {\n\tw.routesLock.Lock()\n\tdefer w.routesLock.Unlock()\n\tbuilder.copyDefaults(w.produces, w.consumes)\n\tw.routes = append(w.routes, builder.Build())\n\treturn w\n}\n\n// RemoveRoute removes the specified route, looks for something that matches 'path' and 'method'\nfunc (w *WebService) RemoveRoute(path, method string) error {\n    if !w.dynamicRoutes {\n        return errors.New(\"dynamic routes are not enabled.\")\n    }\n    w.routesLock.Lock()\n    defer w.routesLock.Unlock()\n    newRoutes := []Route{}\n    for _, route := range w.routes {\n        if route.Method == method && route.Path == path {\n            continue\n        }\n        newRoutes = append(newRoutes, route)\n    }\n    w.routes = newRoutes\n    return nil\n}\n\n// Method creates a new RouteBuilder and initialize its http method\nfunc (w *WebService) Method(httpMethod string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(httpMethod)\n}\n\n// Produces specifies that this WebService can produce one or more MIME types.\n// Http requests must have one of these values set for the Accept header.\nfunc (w *WebService) Produces(contentTypes ...string) *WebService {\n\tw.produces = contentTypes\n\treturn w\n}\n\n// Consumes specifies that this WebService can consume one or more MIME types.\n// Http requests must have one of these values set for the Content-Type header.\nfunc (w *WebService) Consumes(accepts ...string) *WebService {\n\tw.consumes = accepts\n\treturn w\n}\n\n// Routes returns the Routes associated with this WebService\nfunc (w *WebService) Routes() []Route {\n\tif !w.dynamicRoutes {\n\t\treturn w.routes\n\t}\n\t// Make a copy of the array to prevent concurrency problems\n\tw.routesLock.RLock()\n\tdefer w.routesLock.RUnlock()\n\tresult := make([]Route, len(w.routes))\n\tfor ix := range w.routes {\n\t\tresult[ix] = w.routes[ix]\n\t}\n\treturn result\n}\n\n// RootPath returns the RootPath associated with this WebService. Default \"/\"\nfunc (w *WebService) RootPath() string {\n\treturn w.rootPath\n}\n\n// PathParameters return the path parameter names for (shared among its Routes)\nfunc (w *WebService) PathParameters() []*Parameter {\n\treturn w.pathParameters\n}\n\n// Filter adds a filter function to the chain of filters applicable to all its Routes\nfunc (w *WebService) Filter(filter FilterFunction) *WebService {\n\tw.filters = append(w.filters, filter)\n\treturn w\n}\n\n// Doc is used to set the documentation of this service.\nfunc (w *WebService) Doc(plainText string) *WebService {\n\tw.documentation = plainText\n\treturn w\n}\n\n// Documentation returns it.\nfunc (w *WebService) Documentation() string {\n\treturn w.documentation\n}\n\n/*\n\tConvenience methods\n*/\n\n// HEAD is a shortcut for .Method(\"HEAD\").Path(subPath)\nfunc (w *WebService) HEAD(subPath string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(\"HEAD\").Path(subPath)\n}\n\n// GET is a shortcut for .Method(\"GET\").Path(subPath)\nfunc (w *WebService) GET(subPath string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(\"GET\").Path(subPath)\n}\n\n// POST is a shortcut for .Method(\"POST\").Path(subPath)\nfunc (w *WebService) POST(subPath string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(\"POST\").Path(subPath)\n}\n\n// PUT is a shortcut for .Method(\"PUT\").Path(subPath)\nfunc (w *WebService) PUT(subPath string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(\"PUT\").Path(subPath)\n}\n\n// PATCH is a shortcut for .Method(\"PATCH\").Path(subPath)\nfunc (w *WebService) PATCH(subPath string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(\"PATCH\").Path(subPath)\n}\n\n// DELETE is a shortcut for .Method(\"DELETE\").Path(subPath)\nfunc (w *WebService) DELETE(subPath string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(\"DELETE\").Path(subPath)\n}\n\n// OPTIONS is a shortcut for .Method(\"OPTIONS\").Path(subPath)\nfunc (w *WebService) OPTIONS(subPath string) *RouteBuilder {\n\treturn new(RouteBuilder).typeNameHandler(w.typeNameHandleFunc).servicePath(w.rootPath).Method(\"OPTIONS\").Path(subPath)\n}\n"
  },
  {
    "path": "vendor/github.com/emicklei/go-restful/v3/web_service_container.go",
    "content": "package restful\n\n// Copyright 2013 Ernest Micklei. All rights reserved.\n// Use of this source code is governed by a license\n// that can be found in the LICENSE file.\n\nimport (\n\t\"net/http\"\n)\n\n// DefaultContainer is a restful.Container that uses http.DefaultServeMux\nvar DefaultContainer *Container\n\nfunc init() {\n\tDefaultContainer = NewContainer()\n\tDefaultContainer.ServeMux = http.DefaultServeMux\n}\n\n// If set the true then panics will not be caught to return HTTP 500.\n// In that case, Route functions are responsible for handling any error situation.\n// Default value is false = recover from panics. This has performance implications.\n// OBSOLETE ; use restful.DefaultContainer.DoNotRecover(true)\nvar DoNotRecover = false\n\n// Add registers a new WebService add it to the DefaultContainer.\nfunc Add(service *WebService) {\n\tDefaultContainer.Add(service)\n}\n\n// Filter appends a container FilterFunction from the DefaultContainer.\n// These are called before dispatching a http.Request to a WebService.\nfunc Filter(filter FilterFunction) {\n\tDefaultContainer.Filter(filter)\n}\n\n// RegisteredWebServices returns the collections of WebServices from the DefaultContainer\nfunc RegisteredWebServices() []*WebService {\n\treturn DefaultContainer.RegisteredWebServices()\n}\n"
  },
  {
    "path": "vendor/github.com/evanphx/json-patch/.gitignore",
    "content": "# editor and IDE paraphernalia\n.idea\n.vscode\n\n# macOS paraphernalia\n.DS_Store\n"
  },
  {
    "path": "vendor/github.com/evanphx/json-patch/LICENSE",
    "content": "Copyright (c) 2014, Evan Phoenix\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without \nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n* Neither the name of the Evan Phoenix nor the names of its contributors \n  may be used to endorse or promote products derived from this software \n  without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" \nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE \nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL \nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR \nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER \nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \nOR TORT (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": "vendor/github.com/evanphx/json-patch/README.md",
    "content": "# JSON-Patch\n`jsonpatch` is a library which provides functionality for both applying\n[RFC6902 JSON patches](http://tools.ietf.org/html/rfc6902) against documents, as\nwell as for calculating & applying [RFC7396 JSON merge patches](https://tools.ietf.org/html/rfc7396).\n\n[![GoDoc](https://godoc.org/github.com/evanphx/json-patch?status.svg)](http://godoc.org/github.com/evanphx/json-patch)\n[![Build Status](https://travis-ci.org/evanphx/json-patch.svg?branch=master)](https://travis-ci.org/evanphx/json-patch)\n[![Report Card](https://goreportcard.com/badge/github.com/evanphx/json-patch)](https://goreportcard.com/report/github.com/evanphx/json-patch)\n\n# Get It!\n\n**Latest and greatest**: \n```bash\ngo get -u github.com/evanphx/json-patch/v5\n```\n\n**Stable Versions**:\n* Version 5: `go get -u gopkg.in/evanphx/json-patch.v5`\n* Version 4: `go get -u gopkg.in/evanphx/json-patch.v4`\n\n(previous versions below `v3` are unavailable)\n\n# Use It!\n* [Create and apply a merge patch](#create-and-apply-a-merge-patch)\n* [Create and apply a JSON Patch](#create-and-apply-a-json-patch)\n* [Comparing JSON documents](#comparing-json-documents)\n* [Combine merge patches](#combine-merge-patches)\n\n\n# Configuration\n\n* There is a global configuration variable `jsonpatch.SupportNegativeIndices`.\n  This defaults to `true` and enables the non-standard practice of allowing\n  negative indices to mean indices starting at the end of an array. This\n  functionality can be disabled by setting `jsonpatch.SupportNegativeIndices =\n  false`.\n\n* There is a global configuration variable `jsonpatch.AccumulatedCopySizeLimit`,\n  which limits the total size increase in bytes caused by \"copy\" operations in a\n  patch. It defaults to 0, which means there is no limit.\n\nThese global variables control the behavior of `jsonpatch.Apply`.\n\nAn alternative to `jsonpatch.Apply` is `jsonpatch.ApplyWithOptions` whose behavior\nis controlled by an `options` parameter of type `*jsonpatch.ApplyOptions`.\n\nStructure `jsonpatch.ApplyOptions` includes the configuration options above \nand adds two new options: `AllowMissingPathOnRemove` and `EnsurePathExistsOnAdd`.\n\nWhen `AllowMissingPathOnRemove` is set to `true`, `jsonpatch.ApplyWithOptions` will ignore\n`remove` operations whose `path` points to a non-existent location in the JSON document.\n`AllowMissingPathOnRemove` defaults to `false` which will lead to `jsonpatch.ApplyWithOptions`\nreturning an error when hitting a missing `path` on `remove`.\n\nWhen `EnsurePathExistsOnAdd` is set to `true`, `jsonpatch.ApplyWithOptions` will make sure\nthat `add` operations produce all the `path` elements that are missing from the target object.\n\nUse `jsonpatch.NewApplyOptions` to create an instance of `jsonpatch.ApplyOptions`\nwhose values are populated from the global configuration variables.\n\n## Create and apply a merge patch\nGiven both an original JSON document and a modified JSON document, you can create\na [Merge Patch](https://tools.ietf.org/html/rfc7396) document. \n\nIt can describe the changes needed to convert from the original to the \nmodified JSON document.\n\nOnce you have a merge patch, you can apply it to other JSON documents using the\n`jsonpatch.MergePatch(document, patch)` function.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tjsonpatch \"github.com/evanphx/json-patch\"\n)\n\nfunc main() {\n\t// Let's create a merge patch from these two documents...\n\toriginal := []byte(`{\"name\": \"John\", \"age\": 24, \"height\": 3.21}`)\n\ttarget := []byte(`{\"name\": \"Jane\", \"age\": 24}`)\n\n\tpatch, err := jsonpatch.CreateMergePatch(original, target)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Now lets apply the patch against a different JSON document...\n\n\talternative := []byte(`{\"name\": \"Tina\", \"age\": 28, \"height\": 3.75}`)\n\tmodifiedAlternative, err := jsonpatch.MergePatch(alternative, patch)\n\n\tfmt.Printf(\"patch document:   %s\\n\", patch)\n\tfmt.Printf(\"updated alternative doc: %s\\n\", modifiedAlternative)\n}\n```\n\nWhen ran, you get the following output:\n\n```bash\n$ go run main.go\npatch document:   {\"height\":null,\"name\":\"Jane\"}\nupdated alternative doc: {\"age\":28,\"name\":\"Jane\"}\n```\n\n## Create and apply a JSON Patch\nYou can create patch objects using `DecodePatch([]byte)`, which can then \nbe applied against JSON documents.\n\nThe following is an example of creating a patch from two operations, and\napplying it against a JSON document.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tjsonpatch \"github.com/evanphx/json-patch\"\n)\n\nfunc main() {\n\toriginal := []byte(`{\"name\": \"John\", \"age\": 24, \"height\": 3.21}`)\n\tpatchJSON := []byte(`[\n\t\t{\"op\": \"replace\", \"path\": \"/name\", \"value\": \"Jane\"},\n\t\t{\"op\": \"remove\", \"path\": \"/height\"}\n\t]`)\n\n\tpatch, err := jsonpatch.DecodePatch(patchJSON)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tmodified, err := patch.Apply(original)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Printf(\"Original document: %s\\n\", original)\n\tfmt.Printf(\"Modified document: %s\\n\", modified)\n}\n```\n\nWhen ran, you get the following output:\n\n```bash\n$ go run main.go\nOriginal document: {\"name\": \"John\", \"age\": 24, \"height\": 3.21}\nModified document: {\"age\":24,\"name\":\"Jane\"}\n```\n\n## Comparing JSON documents\nDue to potential whitespace and ordering differences, one cannot simply compare\nJSON strings or byte-arrays directly. \n\nAs such, you can instead use `jsonpatch.Equal(document1, document2)` to \ndetermine if two JSON documents are _structurally_ equal. This ignores\nwhitespace differences, and key-value ordering.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tjsonpatch \"github.com/evanphx/json-patch\"\n)\n\nfunc main() {\n\toriginal := []byte(`{\"name\": \"John\", \"age\": 24, \"height\": 3.21}`)\n\tsimilar := []byte(`\n\t\t{\n\t\t\t\"age\": 24,\n\t\t\t\"height\": 3.21,\n\t\t\t\"name\": \"John\"\n\t\t}\n\t`)\n\tdifferent := []byte(`{\"name\": \"Jane\", \"age\": 20, \"height\": 3.37}`)\n\n\tif jsonpatch.Equal(original, similar) {\n\t\tfmt.Println(`\"original\" is structurally equal to \"similar\"`)\n\t}\n\n\tif !jsonpatch.Equal(original, different) {\n\t\tfmt.Println(`\"original\" is _not_ structurally equal to \"different\"`)\n\t}\n}\n```\n\nWhen ran, you get the following output:\n```bash\n$ go run main.go\n\"original\" is structurally equal to \"similar\"\n\"original\" is _not_ structurally equal to \"different\"\n```\n\n## Combine merge patches\nGiven two JSON merge patch documents, it is possible to combine them into a \nsingle merge patch which can describe both set of changes.\n\nThe resulting merge patch can be used such that applying it results in a\ndocument structurally similar as merging each merge patch to the document\nin succession. \n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tjsonpatch \"github.com/evanphx/json-patch\"\n)\n\nfunc main() {\n\toriginal := []byte(`{\"name\": \"John\", \"age\": 24, \"height\": 3.21}`)\n\n\tnameAndHeight := []byte(`{\"height\":null,\"name\":\"Jane\"}`)\n\tageAndEyes := []byte(`{\"age\":4.23,\"eyes\":\"blue\"}`)\n\n\t// Let's combine these merge patch documents...\n\tcombinedPatch, err := jsonpatch.MergeMergePatches(nameAndHeight, ageAndEyes)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Apply each patch individual against the original document\n\twithoutCombinedPatch, err := jsonpatch.MergePatch(original, nameAndHeight)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\twithoutCombinedPatch, err = jsonpatch.MergePatch(withoutCombinedPatch, ageAndEyes)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Apply the combined patch against the original document\n\n\twithCombinedPatch, err := jsonpatch.MergePatch(original, combinedPatch)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Do both result in the same thing? They should!\n\tif jsonpatch.Equal(withCombinedPatch, withoutCombinedPatch) {\n\t\tfmt.Println(\"Both JSON documents are structurally the same!\")\n\t}\n\n\tfmt.Printf(\"combined merge patch: %s\", combinedPatch)\n}\n```\n\nWhen ran, you get the following output:\n```bash\n$ go run main.go\nBoth JSON documents are structurally the same!\ncombined merge patch: {\"age\":4.23,\"eyes\":\"blue\",\"height\":null,\"name\":\"Jane\"}\n```\n\n# CLI for comparing JSON documents\nYou can install the commandline program `json-patch`.\n\nThis program can take multiple JSON patch documents as arguments, \nand fed a JSON document from `stdin`. It will apply the patch(es) against \nthe document and output the modified doc.\n\n**patch.1.json**\n```json\n[\n    {\"op\": \"replace\", \"path\": \"/name\", \"value\": \"Jane\"},\n    {\"op\": \"remove\", \"path\": \"/height\"}\n]\n```\n\n**patch.2.json**\n```json\n[\n    {\"op\": \"add\", \"path\": \"/address\", \"value\": \"123 Main St\"},\n    {\"op\": \"replace\", \"path\": \"/age\", \"value\": \"21\"}\n]\n```\n\n**document.json**\n```json\n{\n    \"name\": \"John\",\n    \"age\": 24,\n    \"height\": 3.21\n}\n```\n\nYou can then run:\n\n```bash\n$ go install github.com/evanphx/json-patch/cmd/json-patch\n$ cat document.json | json-patch -p patch.1.json -p patch.2.json\n{\"address\":\"123 Main St\",\"age\":\"21\",\"name\":\"Jane\"}\n```\n\n# Help It!\nContributions are welcomed! Leave [an issue](https://github.com/evanphx/json-patch/issues)\nor [create a PR](https://github.com/evanphx/json-patch/compare).\n\n\nBefore creating a pull request, we'd ask that you make sure tests are passing\nand that you have added new tests when applicable.\n\nContributors can run tests using:\n\n```bash\ngo test -cover ./...\n```\n\nBuilds for pull requests are tested automatically \nusing [TravisCI](https://travis-ci.org/evanphx/json-patch).\n"
  },
  {
    "path": "vendor/github.com/evanphx/json-patch/errors.go",
    "content": "package jsonpatch\n\nimport \"fmt\"\n\n// AccumulatedCopySizeError is an error type returned when the accumulated size\n// increase caused by copy operations in a patch operation has exceeded the\n// limit.\ntype AccumulatedCopySizeError struct {\n\tlimit       int64\n\taccumulated int64\n}\n\n// NewAccumulatedCopySizeError returns an AccumulatedCopySizeError.\nfunc NewAccumulatedCopySizeError(l, a int64) *AccumulatedCopySizeError {\n\treturn &AccumulatedCopySizeError{limit: l, accumulated: a}\n}\n\n// Error implements the error interface.\nfunc (a *AccumulatedCopySizeError) Error() string {\n\treturn fmt.Sprintf(\"Unable to complete the copy, the accumulated size increase of copy is %d, exceeding the limit %d\", a.accumulated, a.limit)\n}\n\n// ArraySizeError is an error type returned when the array size has exceeded\n// the limit.\ntype ArraySizeError struct {\n\tlimit int\n\tsize  int\n}\n\n// NewArraySizeError returns an ArraySizeError.\nfunc NewArraySizeError(l, s int) *ArraySizeError {\n\treturn &ArraySizeError{limit: l, size: s}\n}\n\n// Error implements the error interface.\nfunc (a *ArraySizeError) Error() string {\n\treturn fmt.Sprintf(\"Unable to create array of size %d, limit is %d\", a.size, a.limit)\n}\n"
  },
  {
    "path": "vendor/github.com/evanphx/json-patch/merge.go",
    "content": "package jsonpatch\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n)\n\nfunc merge(cur, patch *lazyNode, mergeMerge bool) *lazyNode {\n\tcurDoc, err := cur.intoDoc()\n\n\tif err != nil {\n\t\tpruneNulls(patch)\n\t\treturn patch\n\t}\n\n\tpatchDoc, err := patch.intoDoc()\n\n\tif err != nil {\n\t\treturn patch\n\t}\n\n\tmergeDocs(curDoc, patchDoc, mergeMerge)\n\n\treturn cur\n}\n\nfunc mergeDocs(doc, patch *partialDoc, mergeMerge bool) {\n\tfor k, v := range *patch {\n\t\tif v == nil {\n\t\t\tif mergeMerge {\n\t\t\t\t(*doc)[k] = nil\n\t\t\t} else {\n\t\t\t\tdelete(*doc, k)\n\t\t\t}\n\t\t} else {\n\t\t\tcur, ok := (*doc)[k]\n\n\t\t\tif !ok || cur == nil {\n\t\t\t\tif !mergeMerge {\n\t\t\t\t\tpruneNulls(v)\n\t\t\t\t}\n\n\t\t\t\t(*doc)[k] = v\n\t\t\t} else {\n\t\t\t\t(*doc)[k] = merge(cur, v, mergeMerge)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc pruneNulls(n *lazyNode) {\n\tsub, err := n.intoDoc()\n\n\tif err == nil {\n\t\tpruneDocNulls(sub)\n\t} else {\n\t\tary, err := n.intoAry()\n\n\t\tif err == nil {\n\t\t\tpruneAryNulls(ary)\n\t\t}\n\t}\n}\n\nfunc pruneDocNulls(doc *partialDoc) *partialDoc {\n\tfor k, v := range *doc {\n\t\tif v == nil {\n\t\t\tdelete(*doc, k)\n\t\t} else {\n\t\t\tpruneNulls(v)\n\t\t}\n\t}\n\n\treturn doc\n}\n\nfunc pruneAryNulls(ary *partialArray) *partialArray {\n\tnewAry := []*lazyNode{}\n\n\tfor _, v := range *ary {\n\t\tif v != nil {\n\t\t\tpruneNulls(v)\n\t\t}\n\t\tnewAry = append(newAry, v)\n\t}\n\n\t*ary = newAry\n\n\treturn ary\n}\n\nvar ErrBadJSONDoc = fmt.Errorf(\"Invalid JSON Document\")\nvar ErrBadJSONPatch = fmt.Errorf(\"Invalid JSON Patch\")\nvar errBadMergeTypes = fmt.Errorf(\"Mismatched JSON Documents\")\n\n// MergeMergePatches merges two merge patches together, such that\n// applying this resulting merged merge patch to a document yields the same\n// as merging each merge patch to the document in succession.\nfunc MergeMergePatches(patch1Data, patch2Data []byte) ([]byte, error) {\n\treturn doMergePatch(patch1Data, patch2Data, true)\n}\n\n// MergePatch merges the patchData into the docData.\nfunc MergePatch(docData, patchData []byte) ([]byte, error) {\n\treturn doMergePatch(docData, patchData, false)\n}\n\nfunc doMergePatch(docData, patchData []byte, mergeMerge bool) ([]byte, error) {\n\tdoc := &partialDoc{}\n\n\tdocErr := json.Unmarshal(docData, doc)\n\n\tpatch := &partialDoc{}\n\n\tpatchErr := json.Unmarshal(patchData, patch)\n\n\tif _, ok := docErr.(*json.SyntaxError); ok {\n\t\treturn nil, ErrBadJSONDoc\n\t}\n\n\tif _, ok := patchErr.(*json.SyntaxError); ok {\n\t\treturn nil, ErrBadJSONPatch\n\t}\n\n\tif docErr == nil && *doc == nil {\n\t\treturn nil, ErrBadJSONDoc\n\t}\n\n\tif patchErr == nil && *patch == nil {\n\t\treturn nil, ErrBadJSONPatch\n\t}\n\n\tif docErr != nil || patchErr != nil {\n\t\t// Not an error, just not a doc, so we turn straight into the patch\n\t\tif patchErr == nil {\n\t\t\tif mergeMerge {\n\t\t\t\tdoc = patch\n\t\t\t} else {\n\t\t\t\tdoc = pruneDocNulls(patch)\n\t\t\t}\n\t\t} else {\n\t\t\tpatchAry := &partialArray{}\n\t\t\tpatchErr = json.Unmarshal(patchData, patchAry)\n\n\t\t\tif patchErr != nil {\n\t\t\t\treturn nil, ErrBadJSONPatch\n\t\t\t}\n\n\t\t\tpruneAryNulls(patchAry)\n\n\t\t\tout, patchErr := json.Marshal(patchAry)\n\n\t\t\tif patchErr != nil {\n\t\t\t\treturn nil, ErrBadJSONPatch\n\t\t\t}\n\n\t\t\treturn out, nil\n\t\t}\n\t} else {\n\t\tmergeDocs(doc, patch, mergeMerge)\n\t}\n\n\treturn json.Marshal(doc)\n}\n\n// resemblesJSONArray indicates whether the byte-slice \"appears\" to be\n// a JSON array or not.\n// False-positives are possible, as this function does not check the internal\n// structure of the array. It only checks that the outer syntax is present and\n// correct.\nfunc resemblesJSONArray(input []byte) bool {\n\tinput = bytes.TrimSpace(input)\n\n\thasPrefix := bytes.HasPrefix(input, []byte(\"[\"))\n\thasSuffix := bytes.HasSuffix(input, []byte(\"]\"))\n\n\treturn hasPrefix && hasSuffix\n}\n\n// CreateMergePatch will return a merge patch document capable of converting\n// the original document(s) to the modified document(s).\n// The parameters can be bytes of either two JSON Documents, or two arrays of\n// JSON documents.\n// The merge patch returned follows the specification defined at http://tools.ietf.org/html/draft-ietf-appsawg-json-merge-patch-07\nfunc CreateMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {\n\toriginalResemblesArray := resemblesJSONArray(originalJSON)\n\tmodifiedResemblesArray := resemblesJSONArray(modifiedJSON)\n\n\t// Do both byte-slices seem like JSON arrays?\n\tif originalResemblesArray && modifiedResemblesArray {\n\t\treturn createArrayMergePatch(originalJSON, modifiedJSON)\n\t}\n\n\t// Are both byte-slices are not arrays? Then they are likely JSON objects...\n\tif !originalResemblesArray && !modifiedResemblesArray {\n\t\treturn createObjectMergePatch(originalJSON, modifiedJSON)\n\t}\n\n\t// None of the above? Then return an error because of mismatched types.\n\treturn nil, errBadMergeTypes\n}\n\n// createObjectMergePatch will return a merge-patch document capable of\n// converting the original document to the modified document.\nfunc createObjectMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {\n\toriginalDoc := map[string]interface{}{}\n\tmodifiedDoc := map[string]interface{}{}\n\n\terr := json.Unmarshal(originalJSON, &originalDoc)\n\tif err != nil {\n\t\treturn nil, ErrBadJSONDoc\n\t}\n\n\terr = json.Unmarshal(modifiedJSON, &modifiedDoc)\n\tif err != nil {\n\t\treturn nil, ErrBadJSONDoc\n\t}\n\n\tdest, err := getDiff(originalDoc, modifiedDoc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn json.Marshal(dest)\n}\n\n// createArrayMergePatch will return an array of merge-patch documents capable\n// of converting the original document to the modified document for each\n// pair of JSON documents provided in the arrays.\n// Arrays of mismatched sizes will result in an error.\nfunc createArrayMergePatch(originalJSON, modifiedJSON []byte) ([]byte, error) {\n\toriginalDocs := []json.RawMessage{}\n\tmodifiedDocs := []json.RawMessage{}\n\n\terr := json.Unmarshal(originalJSON, &originalDocs)\n\tif err != nil {\n\t\treturn nil, ErrBadJSONDoc\n\t}\n\n\terr = json.Unmarshal(modifiedJSON, &modifiedDocs)\n\tif err != nil {\n\t\treturn nil, ErrBadJSONDoc\n\t}\n\n\ttotal := len(originalDocs)\n\tif len(modifiedDocs) != total {\n\t\treturn nil, ErrBadJSONDoc\n\t}\n\n\tresult := []json.RawMessage{}\n\tfor i := 0; i < len(originalDocs); i++ {\n\t\toriginal := originalDocs[i]\n\t\tmodified := modifiedDocs[i]\n\n\t\tpatch, err := createObjectMergePatch(original, modified)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tresult = append(result, json.RawMessage(patch))\n\t}\n\n\treturn json.Marshal(result)\n}\n\n// Returns true if the array matches (must be json types).\n// As is idiomatic for go, an empty array is not the same as a nil array.\nfunc matchesArray(a, b []interface{}) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tif (a == nil && b != nil) || (a != nil && b == nil) {\n\t\treturn false\n\t}\n\tfor i := range a {\n\t\tif !matchesValue(a[i], b[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Returns true if the values matches (must be json types)\n// The types of the values must match, otherwise it will always return false\n// If two map[string]interface{} are given, all elements must match.\nfunc matchesValue(av, bv interface{}) bool {\n\tif reflect.TypeOf(av) != reflect.TypeOf(bv) {\n\t\treturn false\n\t}\n\tswitch at := av.(type) {\n\tcase string:\n\t\tbt := bv.(string)\n\t\tif bt == at {\n\t\t\treturn true\n\t\t}\n\tcase float64:\n\t\tbt := bv.(float64)\n\t\tif bt == at {\n\t\t\treturn true\n\t\t}\n\tcase bool:\n\t\tbt := bv.(bool)\n\t\tif bt == at {\n\t\t\treturn true\n\t\t}\n\tcase nil:\n\t\t// Both nil, fine.\n\t\treturn true\n\tcase map[string]interface{}:\n\t\tbt := bv.(map[string]interface{})\n\t\tif len(bt) != len(at) {\n\t\t\treturn false\n\t\t}\n\t\tfor key := range bt {\n\t\t\tav, aOK := at[key]\n\t\t\tbv, bOK := bt[key]\n\t\t\tif aOK != bOK {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !matchesValue(av, bv) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\tcase []interface{}:\n\t\tbt := bv.([]interface{})\n\t\treturn matchesArray(at, bt)\n\t}\n\treturn false\n}\n\n// getDiff returns the (recursive) difference between a and b as a map[string]interface{}.\nfunc getDiff(a, b map[string]interface{}) (map[string]interface{}, error) {\n\tinto := map[string]interface{}{}\n\tfor key, bv := range b {\n\t\tav, ok := a[key]\n\t\t// value was added\n\t\tif !ok {\n\t\t\tinto[key] = bv\n\t\t\tcontinue\n\t\t}\n\t\t// If types have changed, replace completely\n\t\tif reflect.TypeOf(av) != reflect.TypeOf(bv) {\n\t\t\tinto[key] = bv\n\t\t\tcontinue\n\t\t}\n\t\t// Types are the same, compare values\n\t\tswitch at := av.(type) {\n\t\tcase map[string]interface{}:\n\t\t\tbt := bv.(map[string]interface{})\n\t\t\tdst := make(map[string]interface{}, len(bt))\n\t\t\tdst, err := getDiff(at, bt)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif len(dst) > 0 {\n\t\t\t\tinto[key] = dst\n\t\t\t}\n\t\tcase string, float64, bool:\n\t\t\tif !matchesValue(av, bv) {\n\t\t\t\tinto[key] = bv\n\t\t\t}\n\t\tcase []interface{}:\n\t\t\tbt := bv.([]interface{})\n\t\t\tif !matchesArray(at, bt) {\n\t\t\t\tinto[key] = bv\n\t\t\t}\n\t\tcase nil:\n\t\t\tswitch bv.(type) {\n\t\t\tcase nil:\n\t\t\t\t// Both nil, fine.\n\t\t\tdefault:\n\t\t\t\tinto[key] = bv\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"Unknown type:%T in key %s\", av, key))\n\t\t}\n\t}\n\t// Now add all deleted values as nil\n\tfor key := range a {\n\t\t_, found := b[key]\n\t\tif !found {\n\t\t\tinto[key] = nil\n\t\t}\n\t}\n\treturn into, nil\n}\n"
  },
  {
    "path": "vendor/github.com/evanphx/json-patch/patch.go",
    "content": "package jsonpatch\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/pkg/errors\"\n)\n\nconst (\n\teRaw = iota\n\teDoc\n\teAry\n)\n\nvar (\n\t// SupportNegativeIndices decides whether to support non-standard practice of\n\t// allowing negative indices to mean indices starting at the end of an array.\n\t// Default to true.\n\tSupportNegativeIndices bool = true\n\t// AccumulatedCopySizeLimit limits the total size increase in bytes caused by\n\t// \"copy\" operations in a patch.\n\tAccumulatedCopySizeLimit int64 = 0\n)\n\nvar (\n\tErrTestFailed   = errors.New(\"test failed\")\n\tErrMissing      = errors.New(\"missing value\")\n\tErrUnknownType  = errors.New(\"unknown object type\")\n\tErrInvalid      = errors.New(\"invalid state detected\")\n\tErrInvalidIndex = errors.New(\"invalid index referenced\")\n)\n\ntype lazyNode struct {\n\traw   *json.RawMessage\n\tdoc   partialDoc\n\tary   partialArray\n\twhich int\n}\n\n// Operation is a single JSON-Patch step, such as a single 'add' operation.\ntype Operation map[string]*json.RawMessage\n\n// Patch is an ordered collection of Operations.\ntype Patch []Operation\n\ntype partialDoc map[string]*lazyNode\ntype partialArray []*lazyNode\n\ntype container interface {\n\tget(key string) (*lazyNode, error)\n\tset(key string, val *lazyNode) error\n\tadd(key string, val *lazyNode) error\n\tremove(key string) error\n}\n\nfunc newLazyNode(raw *json.RawMessage) *lazyNode {\n\treturn &lazyNode{raw: raw, doc: nil, ary: nil, which: eRaw}\n}\n\nfunc (n *lazyNode) MarshalJSON() ([]byte, error) {\n\tswitch n.which {\n\tcase eRaw:\n\t\treturn json.Marshal(n.raw)\n\tcase eDoc:\n\t\treturn json.Marshal(n.doc)\n\tcase eAry:\n\t\treturn json.Marshal(n.ary)\n\tdefault:\n\t\treturn nil, ErrUnknownType\n\t}\n}\n\nfunc (n *lazyNode) UnmarshalJSON(data []byte) error {\n\tdest := make(json.RawMessage, len(data))\n\tcopy(dest, data)\n\tn.raw = &dest\n\tn.which = eRaw\n\treturn nil\n}\n\nfunc deepCopy(src *lazyNode) (*lazyNode, int, error) {\n\tif src == nil {\n\t\treturn nil, 0, nil\n\t}\n\ta, err := src.MarshalJSON()\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\tsz := len(a)\n\tra := make(json.RawMessage, sz)\n\tcopy(ra, a)\n\treturn newLazyNode(&ra), sz, nil\n}\n\nfunc (n *lazyNode) intoDoc() (*partialDoc, error) {\n\tif n.which == eDoc {\n\t\treturn &n.doc, nil\n\t}\n\n\tif n.raw == nil {\n\t\treturn nil, ErrInvalid\n\t}\n\n\terr := json.Unmarshal(*n.raw, &n.doc)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tn.which = eDoc\n\treturn &n.doc, nil\n}\n\nfunc (n *lazyNode) intoAry() (*partialArray, error) {\n\tif n.which == eAry {\n\t\treturn &n.ary, nil\n\t}\n\n\tif n.raw == nil {\n\t\treturn nil, ErrInvalid\n\t}\n\n\terr := json.Unmarshal(*n.raw, &n.ary)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tn.which = eAry\n\treturn &n.ary, nil\n}\n\nfunc (n *lazyNode) compact() []byte {\n\tbuf := &bytes.Buffer{}\n\n\tif n.raw == nil {\n\t\treturn nil\n\t}\n\n\terr := json.Compact(buf, *n.raw)\n\n\tif err != nil {\n\t\treturn *n.raw\n\t}\n\n\treturn buf.Bytes()\n}\n\nfunc (n *lazyNode) tryDoc() bool {\n\tif n.raw == nil {\n\t\treturn false\n\t}\n\n\terr := json.Unmarshal(*n.raw, &n.doc)\n\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tn.which = eDoc\n\treturn true\n}\n\nfunc (n *lazyNode) tryAry() bool {\n\tif n.raw == nil {\n\t\treturn false\n\t}\n\n\terr := json.Unmarshal(*n.raw, &n.ary)\n\n\tif err != nil {\n\t\treturn false\n\t}\n\n\tn.which = eAry\n\treturn true\n}\n\nfunc (n *lazyNode) equal(o *lazyNode) bool {\n\tif n.which == eRaw {\n\t\tif !n.tryDoc() && !n.tryAry() {\n\t\t\tif o.which != eRaw {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\treturn bytes.Equal(n.compact(), o.compact())\n\t\t}\n\t}\n\n\tif n.which == eDoc {\n\t\tif o.which == eRaw {\n\t\t\tif !o.tryDoc() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\tif o.which != eDoc {\n\t\t\treturn false\n\t\t}\n\n\t\tif len(n.doc) != len(o.doc) {\n\t\t\treturn false\n\t\t}\n\n\t\tfor k, v := range n.doc {\n\t\t\tov, ok := o.doc[k]\n\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif (v == nil) != (ov == nil) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif v == nil && ov == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif !v.equal(ov) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\tif o.which != eAry && !o.tryAry() {\n\t\treturn false\n\t}\n\n\tif len(n.ary) != len(o.ary) {\n\t\treturn false\n\t}\n\n\tfor idx, val := range n.ary {\n\t\tif !val.equal(o.ary[idx]) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n// Kind reads the \"op\" field of the Operation.\nfunc (o Operation) Kind() string {\n\tif obj, ok := o[\"op\"]; ok && obj != nil {\n\t\tvar op string\n\n\t\terr := json.Unmarshal(*obj, &op)\n\n\t\tif err != nil {\n\t\t\treturn \"unknown\"\n\t\t}\n\n\t\treturn op\n\t}\n\n\treturn \"unknown\"\n}\n\n// Path reads the \"path\" field of the Operation.\nfunc (o Operation) Path() (string, error) {\n\tif obj, ok := o[\"path\"]; ok && obj != nil {\n\t\tvar op string\n\n\t\terr := json.Unmarshal(*obj, &op)\n\n\t\tif err != nil {\n\t\t\treturn \"unknown\", err\n\t\t}\n\n\t\treturn op, nil\n\t}\n\n\treturn \"unknown\", errors.Wrapf(ErrMissing, \"operation missing path field\")\n}\n\n// From reads the \"from\" field of the Operation.\nfunc (o Operation) From() (string, error) {\n\tif obj, ok := o[\"from\"]; ok && obj != nil {\n\t\tvar op string\n\n\t\terr := json.Unmarshal(*obj, &op)\n\n\t\tif err != nil {\n\t\t\treturn \"unknown\", err\n\t\t}\n\n\t\treturn op, nil\n\t}\n\n\treturn \"unknown\", errors.Wrapf(ErrMissing, \"operation, missing from field\")\n}\n\nfunc (o Operation) value() *lazyNode {\n\tif obj, ok := o[\"value\"]; ok {\n\t\treturn newLazyNode(obj)\n\t}\n\n\treturn nil\n}\n\n// ValueInterface decodes the operation value into an interface.\nfunc (o Operation) ValueInterface() (interface{}, error) {\n\tif obj, ok := o[\"value\"]; ok && obj != nil {\n\t\tvar v interface{}\n\n\t\terr := json.Unmarshal(*obj, &v)\n\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn v, nil\n\t}\n\n\treturn nil, errors.Wrapf(ErrMissing, \"operation, missing value field\")\n}\n\nfunc isArray(buf []byte) bool {\nLoop:\n\tfor _, c := range buf {\n\t\tswitch c {\n\t\tcase ' ':\n\t\tcase '\\n':\n\t\tcase '\\t':\n\t\t\tcontinue\n\t\tcase '[':\n\t\t\treturn true\n\t\tdefault:\n\t\t\tbreak Loop\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc findObject(pd *container, path string) (container, string) {\n\tdoc := *pd\n\n\tsplit := strings.Split(path, \"/\")\n\n\tif len(split) < 2 {\n\t\treturn nil, \"\"\n\t}\n\n\tparts := split[1 : len(split)-1]\n\n\tkey := split[len(split)-1]\n\n\tvar err error\n\n\tfor _, part := range parts {\n\n\t\tnext, ok := doc.get(decodePatchKey(part))\n\n\t\tif next == nil || ok != nil {\n\t\t\treturn nil, \"\"\n\t\t}\n\n\t\tif isArray(*next.raw) {\n\t\t\tdoc, err = next.intoAry()\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, \"\"\n\t\t\t}\n\t\t} else {\n\t\t\tdoc, err = next.intoDoc()\n\n\t\t\tif err != nil {\n\t\t\t\treturn nil, \"\"\n\t\t\t}\n\t\t}\n\t}\n\n\treturn doc, decodePatchKey(key)\n}\n\nfunc (d *partialDoc) set(key string, val *lazyNode) error {\n\t(*d)[key] = val\n\treturn nil\n}\n\nfunc (d *partialDoc) add(key string, val *lazyNode) error {\n\t(*d)[key] = val\n\treturn nil\n}\n\nfunc (d *partialDoc) get(key string) (*lazyNode, error) {\n\treturn (*d)[key], nil\n}\n\nfunc (d *partialDoc) remove(key string) error {\n\t_, ok := (*d)[key]\n\tif !ok {\n\t\treturn errors.Wrapf(ErrMissing, \"Unable to remove nonexistent key: %s\", key)\n\t}\n\n\tdelete(*d, key)\n\treturn nil\n}\n\n// set should only be used to implement the \"replace\" operation, so \"key\" must\n// be an already existing index in \"d\".\nfunc (d *partialArray) set(key string, val *lazyNode) error {\n\tidx, err := strconv.Atoi(key)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif idx < 0 {\n\t\tif !SupportNegativeIndices {\n\t\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tif idx < -len(*d) {\n\t\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tidx += len(*d)\n\t}\n\n\t(*d)[idx] = val\n\treturn nil\n}\n\nfunc (d *partialArray) add(key string, val *lazyNode) error {\n\tif key == \"-\" {\n\t\t*d = append(*d, val)\n\t\treturn nil\n\t}\n\n\tidx, err := strconv.Atoi(key)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"value was not a proper array index: '%s'\", key)\n\t}\n\n\tsz := len(*d) + 1\n\n\tary := make([]*lazyNode, sz)\n\n\tcur := *d\n\n\tif idx >= len(ary) {\n\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t}\n\n\tif idx < 0 {\n\t\tif !SupportNegativeIndices {\n\t\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tif idx < -len(ary) {\n\t\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tidx += len(ary)\n\t}\n\n\tcopy(ary[0:idx], cur[0:idx])\n\tary[idx] = val\n\tcopy(ary[idx+1:], cur[idx:])\n\n\t*d = ary\n\treturn nil\n}\n\nfunc (d *partialArray) get(key string) (*lazyNode, error) {\n\tidx, err := strconv.Atoi(key)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif idx < 0 {\n\t\tif !SupportNegativeIndices {\n\t\t\treturn nil, errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tif idx < -len(*d) {\n\t\t\treturn nil, errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tidx += len(*d)\n\t}\n\n\tif idx >= len(*d) {\n\t\treturn nil, errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t}\n\n\treturn (*d)[idx], nil\n}\n\nfunc (d *partialArray) remove(key string) error {\n\tidx, err := strconv.Atoi(key)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcur := *d\n\n\tif idx >= len(cur) {\n\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t}\n\n\tif idx < 0 {\n\t\tif !SupportNegativeIndices {\n\t\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tif idx < -len(cur) {\n\t\t\treturn errors.Wrapf(ErrInvalidIndex, \"Unable to access invalid index: %d\", idx)\n\t\t}\n\t\tidx += len(cur)\n\t}\n\n\tary := make([]*lazyNode, len(cur)-1)\n\n\tcopy(ary[0:idx], cur[0:idx])\n\tcopy(ary[idx:], cur[idx+1:])\n\n\t*d = ary\n\treturn nil\n\n}\n\nfunc (p Patch) add(doc *container, op Operation) error {\n\tpath, err := op.Path()\n\tif err != nil {\n\t\treturn errors.Wrapf(ErrMissing, \"add operation failed to decode path\")\n\t}\n\n\tcon, key := findObject(doc, path)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"add operation does not apply: doc is missing path: \\\"%s\\\"\", path)\n\t}\n\n\terr = con.add(key, op.value())\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in add for path: '%s'\", path)\n\t}\n\n\treturn nil\n}\n\nfunc (p Patch) remove(doc *container, op Operation) error {\n\tpath, err := op.Path()\n\tif err != nil {\n\t\treturn errors.Wrapf(ErrMissing, \"remove operation failed to decode path\")\n\t}\n\n\tcon, key := findObject(doc, path)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"remove operation does not apply: doc is missing path: \\\"%s\\\"\", path)\n\t}\n\n\terr = con.remove(key)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in remove for path: '%s'\", path)\n\t}\n\n\treturn nil\n}\n\nfunc (p Patch) replace(doc *container, op Operation) error {\n\tpath, err := op.Path()\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"replace operation failed to decode path\")\n\t}\n\n\tif path == \"\" {\n\t\tval := op.value()\n\n\t\tif val.which == eRaw {\n\t\t\tif !val.tryDoc() {\n\t\t\t\tif !val.tryAry() {\n\t\t\t\t\treturn errors.Wrapf(err, \"replace operation value must be object or array\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch val.which {\n\t\tcase eAry:\n\t\t\t*doc = &val.ary\n\t\tcase eDoc:\n\t\t\t*doc = &val.doc\n\t\tcase eRaw:\n\t\t\treturn errors.Wrapf(err, \"replace operation hit impossible case\")\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tcon, key := findObject(doc, path)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"replace operation does not apply: doc is missing path: %s\", path)\n\t}\n\n\t_, ok := con.get(key)\n\tif ok != nil {\n\t\treturn errors.Wrapf(ErrMissing, \"replace operation does not apply: doc is missing key: %s\", path)\n\t}\n\n\terr = con.set(key, op.value())\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in remove for path: '%s'\", path)\n\t}\n\n\treturn nil\n}\n\nfunc (p Patch) move(doc *container, op Operation) error {\n\tfrom, err := op.From()\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"move operation failed to decode from\")\n\t}\n\n\tcon, key := findObject(doc, from)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"move operation does not apply: doc is missing from path: %s\", from)\n\t}\n\n\tval, err := con.get(key)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in move for path: '%s'\", key)\n\t}\n\n\terr = con.remove(key)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in move for path: '%s'\", key)\n\t}\n\n\tpath, err := op.Path()\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"move operation failed to decode path\")\n\t}\n\n\tcon, key = findObject(doc, path)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"move operation does not apply: doc is missing destination path: %s\", path)\n\t}\n\n\terr = con.add(key, val)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in move for path: '%s'\", path)\n\t}\n\n\treturn nil\n}\n\nfunc (p Patch) test(doc *container, op Operation) error {\n\tpath, err := op.Path()\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"test operation failed to decode path\")\n\t}\n\n\tif path == \"\" {\n\t\tvar self lazyNode\n\n\t\tswitch sv := (*doc).(type) {\n\t\tcase *partialDoc:\n\t\t\tself.doc = *sv\n\t\t\tself.which = eDoc\n\t\tcase *partialArray:\n\t\t\tself.ary = *sv\n\t\t\tself.which = eAry\n\t\t}\n\n\t\tif self.equal(op.value()) {\n\t\t\treturn nil\n\t\t}\n\n\t\treturn errors.Wrapf(ErrTestFailed, \"testing value %s failed\", path)\n\t}\n\n\tcon, key := findObject(doc, path)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"test operation does not apply: is missing path: %s\", path)\n\t}\n\n\tval, err := con.get(key)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in test for path: '%s'\", path)\n\t}\n\n\tif val == nil {\n\t\tif op.value().raw == nil {\n\t\t\treturn nil\n\t\t}\n\t\treturn errors.Wrapf(ErrTestFailed, \"testing value %s failed\", path)\n\t} else if op.value() == nil {\n\t\treturn errors.Wrapf(ErrTestFailed, \"testing value %s failed\", path)\n\t}\n\n\tif val.equal(op.value()) {\n\t\treturn nil\n\t}\n\n\treturn errors.Wrapf(ErrTestFailed, \"testing value %s failed\", path)\n}\n\nfunc (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64) error {\n\tfrom, err := op.From()\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"copy operation failed to decode from\")\n\t}\n\n\tcon, key := findObject(doc, from)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"copy operation does not apply: doc is missing from path: %s\", from)\n\t}\n\n\tval, err := con.get(key)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error in copy for from: '%s'\", from)\n\t}\n\n\tpath, err := op.Path()\n\tif err != nil {\n\t\treturn errors.Wrapf(ErrMissing, \"copy operation failed to decode path\")\n\t}\n\n\tcon, key = findObject(doc, path)\n\n\tif con == nil {\n\t\treturn errors.Wrapf(ErrMissing, \"copy operation does not apply: doc is missing destination path: %s\", path)\n\t}\n\n\tvalCopy, sz, err := deepCopy(val)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error while performing deep copy\")\n\t}\n\n\t(*accumulatedCopySize) += int64(sz)\n\tif AccumulatedCopySizeLimit > 0 && *accumulatedCopySize > AccumulatedCopySizeLimit {\n\t\treturn NewAccumulatedCopySizeError(AccumulatedCopySizeLimit, *accumulatedCopySize)\n\t}\n\n\terr = con.add(key, valCopy)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error while adding value during copy\")\n\t}\n\n\treturn nil\n}\n\n// Equal indicates if 2 JSON documents have the same structural equality.\nfunc Equal(a, b []byte) bool {\n\tra := make(json.RawMessage, len(a))\n\tcopy(ra, a)\n\tla := newLazyNode(&ra)\n\n\trb := make(json.RawMessage, len(b))\n\tcopy(rb, b)\n\tlb := newLazyNode(&rb)\n\n\treturn la.equal(lb)\n}\n\n// DecodePatch decodes the passed JSON document as an RFC 6902 patch.\nfunc DecodePatch(buf []byte) (Patch, error) {\n\tvar p Patch\n\n\terr := json.Unmarshal(buf, &p)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p, nil\n}\n\n// Apply mutates a JSON document according to the patch, and returns the new\n// document.\nfunc (p Patch) Apply(doc []byte) ([]byte, error) {\n\treturn p.ApplyIndent(doc, \"\")\n}\n\n// ApplyIndent mutates a JSON document according to the patch, and returns the new\n// document indented.\nfunc (p Patch) ApplyIndent(doc []byte, indent string) ([]byte, error) {\n\tif len(doc) == 0 {\n\t\treturn doc, nil\n\t}\n\n\tvar pd container\n\tif doc[0] == '[' {\n\t\tpd = &partialArray{}\n\t} else {\n\t\tpd = &partialDoc{}\n\t}\n\n\terr := json.Unmarshal(doc, pd)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\terr = nil\n\n\tvar accumulatedCopySize int64\n\n\tfor _, op := range p {\n\t\tswitch op.Kind() {\n\t\tcase \"add\":\n\t\t\terr = p.add(&pd, op)\n\t\tcase \"remove\":\n\t\t\terr = p.remove(&pd, op)\n\t\tcase \"replace\":\n\t\t\terr = p.replace(&pd, op)\n\t\tcase \"move\":\n\t\t\terr = p.move(&pd, op)\n\t\tcase \"test\":\n\t\t\terr = p.test(&pd, op)\n\t\tcase \"copy\":\n\t\t\terr = p.copy(&pd, op, &accumulatedCopySize)\n\t\tdefault:\n\t\t\terr = fmt.Errorf(\"Unexpected kind: %s\", op.Kind())\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif indent != \"\" {\n\t\treturn json.MarshalIndent(pd, \"\", indent)\n\t}\n\n\treturn json.Marshal(pd)\n}\n\n// From http://tools.ietf.org/html/rfc6901#section-4 :\n//\n// Evaluation of each reference token begins by decoding any escaped\n// character sequence.  This is performed by first transforming any\n// occurrence of the sequence '~1' to '/', and then transforming any\n// occurrence of the sequence '~0' to '~'.\n\nvar (\n\trfc6901Decoder = strings.NewReplacer(\"~1\", \"/\", \"~0\", \"~\")\n)\n\nfunc decodePatchKey(k string) string {\n\treturn rfc6901Decoder.Replace(k)\n}\n"
  },
  {
    "path": "vendor/github.com/fatih/color/LICENSE.md",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Fatih Arslan\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject 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, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/fatih/color/README.md",
    "content": "# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/fatih/color)](https://pkg.go.dev/github.com/fatih/color)\n\nColor lets you use colorized outputs in terms of [ANSI Escape\nCodes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It\nhas support for Windows too! The API can be used in several ways, pick one that\nsuits you.\n\n![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg)\n\n\n## Install\n\n```bash\ngo get github.com/fatih/color\n```\n\n## Examples\n\n### Standard colors\n\n```go\n// Print with default helper functions\ncolor.Cyan(\"Prints text in cyan.\")\n\n// A newline will be appended automatically\ncolor.Blue(\"Prints %s in blue.\", \"text\")\n\n// These are using the default foreground colors\ncolor.Red(\"We have red\")\ncolor.Magenta(\"And many others ..\")\n\n```\n\n### Mix and reuse colors\n\n```go\n// Create a new color object\nc := color.New(color.FgCyan).Add(color.Underline)\nc.Println(\"Prints cyan text with an underline.\")\n\n// Or just add them to New()\nd := color.New(color.FgCyan, color.Bold)\nd.Printf(\"This prints bold cyan %s\\n\", \"too!.\")\n\n// Mix up foreground and background colors, create new mixes!\nred := color.New(color.FgRed)\n\nboldRed := red.Add(color.Bold)\nboldRed.Println(\"This will print text in bold red.\")\n\nwhiteBackground := red.Add(color.BgWhite)\nwhiteBackground.Println(\"Red text with white background.\")\n```\n\n### Use your own output (io.Writer)\n\n```go\n// Use your own io.Writer output\ncolor.New(color.FgBlue).Fprintln(myWriter, \"blue color!\")\n\nblue := color.New(color.FgBlue)\nblue.Fprint(writer, \"This will print text in blue.\")\n```\n\n### Custom print functions (PrintFunc)\n\n```go\n// Create a custom print function for convenience\nred := color.New(color.FgRed).PrintfFunc()\nred(\"Warning\")\nred(\"Error: %s\", err)\n\n// Mix up multiple attributes\nnotice := color.New(color.Bold, color.FgGreen).PrintlnFunc()\nnotice(\"Don't forget this...\")\n```\n\n### Custom fprint functions (FprintFunc)\n\n```go\nblue := color.New(color.FgBlue).FprintfFunc()\nblue(myWriter, \"important notice: %s\", stars)\n\n// Mix up with multiple attributes\nsuccess := color.New(color.Bold, color.FgGreen).FprintlnFunc()\nsuccess(myWriter, \"Don't forget this...\")\n```\n\n### Insert into noncolor strings (SprintFunc)\n\n```go\n// Create SprintXxx functions to mix strings with other non-colorized strings:\nyellow := color.New(color.FgYellow).SprintFunc()\nred := color.New(color.FgRed).SprintFunc()\nfmt.Printf(\"This is a %s and this is %s.\\n\", yellow(\"warning\"), red(\"error\"))\n\ninfo := color.New(color.FgWhite, color.BgGreen).SprintFunc()\nfmt.Printf(\"This %s rocks!\\n\", info(\"package\"))\n\n// Use helper functions\nfmt.Println(\"This\", color.RedString(\"warning\"), \"should be not neglected.\")\nfmt.Printf(\"%v %v\\n\", color.GreenString(\"Info:\"), \"an important message.\")\n\n// Windows supported too! Just don't forget to change the output to color.Output\nfmt.Fprintf(color.Output, \"Windows support: %s\", color.GreenString(\"PASS\"))\n```\n\n### Plug into existing code\n\n```go\n// Use handy standard colors\ncolor.Set(color.FgYellow)\n\nfmt.Println(\"Existing text will now be in yellow\")\nfmt.Printf(\"This one %s\\n\", \"too\")\n\ncolor.Unset() // Don't forget to unset\n\n// You can mix up parameters\ncolor.Set(color.FgMagenta, color.Bold)\ndefer color.Unset() // Use it in your function\n\nfmt.Println(\"All text will now be bold magenta.\")\n```\n\n### Disable/Enable color\n \nThere might be a case where you want to explicitly disable/enable color output. the \n`go-isatty` package will automatically disable color output for non-tty output streams \n(for example if the output were piped directly to `less`).\n\nThe `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment\nvariable is set (regardless of its value).\n\n`Color` has support to disable/enable colors programatically both globally and\nfor single color definitions. For example suppose you have a CLI app and a\n`--no-color` bool flag. You can easily disable the color output with:\n\n```go\nvar flagNoColor = flag.Bool(\"no-color\", false, \"Disable color output\")\n\nif *flagNoColor {\n\tcolor.NoColor = true // disables colorized output\n}\n```\n\nIt also has support for single color definitions (local). You can\ndisable/enable color output on the fly:\n\n```go\nc := color.New(color.FgCyan)\nc.Println(\"Prints cyan text\")\n\nc.DisableColor()\nc.Println(\"This is printed without any color\")\n\nc.EnableColor()\nc.Println(\"This prints again cyan...\")\n```\n\n## GitHub Actions\n\nTo output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams. \n\n## Todo\n\n* Save/Return previous values\n* Evaluate fmt.Formatter interface\n\n\n## Credits\n\n * [Fatih Arslan](https://github.com/fatih)\n * Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable)\n\n## License\n\nThe MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details\n"
  },
  {
    "path": "vendor/github.com/fatih/color/color.go",
    "content": "package color\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/mattn/go-colorable\"\n\t\"github.com/mattn/go-isatty\"\n)\n\nvar (\n\t// NoColor defines if the output is colorized or not. It's dynamically set to\n\t// false or true based on the stdout's file descriptor referring to a terminal\n\t// or not. It's also set to true if the NO_COLOR environment variable is\n\t// set (regardless of its value). This is a global option and affects all\n\t// colors. For more control over each color block use the methods\n\t// DisableColor() individually.\n\tNoColor = noColorExists() || os.Getenv(\"TERM\") == \"dumb\" ||\n\t\t(!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))\n\n\t// Output defines the standard output of the print functions. By default\n\t// os.Stdout is used.\n\tOutput = colorable.NewColorableStdout()\n\n\t// Error defines a color supporting writer for os.Stderr.\n\tError = colorable.NewColorableStderr()\n\n\t// colorsCache is used to reduce the count of created Color objects and\n\t// allows to reuse already created objects with required Attribute.\n\tcolorsCache   = make(map[Attribute]*Color)\n\tcolorsCacheMu sync.Mutex // protects colorsCache\n)\n\n// noColorExists returns true if the environment variable NO_COLOR exists.\nfunc noColorExists() bool {\n\t_, exists := os.LookupEnv(\"NO_COLOR\")\n\treturn exists\n}\n\n// Color defines a custom color object which is defined by SGR parameters.\ntype Color struct {\n\tparams  []Attribute\n\tnoColor *bool\n}\n\n// Attribute defines a single SGR Code\ntype Attribute int\n\nconst escape = \"\\x1b\"\n\n// Base attributes\nconst (\n\tReset Attribute = iota\n\tBold\n\tFaint\n\tItalic\n\tUnderline\n\tBlinkSlow\n\tBlinkRapid\n\tReverseVideo\n\tConcealed\n\tCrossedOut\n)\n\n// Foreground text colors\nconst (\n\tFgBlack Attribute = iota + 30\n\tFgRed\n\tFgGreen\n\tFgYellow\n\tFgBlue\n\tFgMagenta\n\tFgCyan\n\tFgWhite\n)\n\n// Foreground Hi-Intensity text colors\nconst (\n\tFgHiBlack Attribute = iota + 90\n\tFgHiRed\n\tFgHiGreen\n\tFgHiYellow\n\tFgHiBlue\n\tFgHiMagenta\n\tFgHiCyan\n\tFgHiWhite\n)\n\n// Background text colors\nconst (\n\tBgBlack Attribute = iota + 40\n\tBgRed\n\tBgGreen\n\tBgYellow\n\tBgBlue\n\tBgMagenta\n\tBgCyan\n\tBgWhite\n)\n\n// Background Hi-Intensity text colors\nconst (\n\tBgHiBlack Attribute = iota + 100\n\tBgHiRed\n\tBgHiGreen\n\tBgHiYellow\n\tBgHiBlue\n\tBgHiMagenta\n\tBgHiCyan\n\tBgHiWhite\n)\n\n// New returns a newly created color object.\nfunc New(value ...Attribute) *Color {\n\tc := &Color{\n\t\tparams: make([]Attribute, 0),\n\t}\n\n\tif noColorExists() {\n\t\tc.noColor = boolPtr(true)\n\t}\n\n\tc.Add(value...)\n\treturn c\n}\n\n// Set sets the given parameters immediately. It will change the color of\n// output with the given SGR parameters until color.Unset() is called.\nfunc Set(p ...Attribute) *Color {\n\tc := New(p...)\n\tc.Set()\n\treturn c\n}\n\n// Unset resets all escape attributes and clears the output. Usually should\n// be called after Set().\nfunc Unset() {\n\tif NoColor {\n\t\treturn\n\t}\n\n\tfmt.Fprintf(Output, \"%s[%dm\", escape, Reset)\n}\n\n// Set sets the SGR sequence.\nfunc (c *Color) Set() *Color {\n\tif c.isNoColorSet() {\n\t\treturn c\n\t}\n\n\tfmt.Fprintf(Output, c.format())\n\treturn c\n}\n\nfunc (c *Color) unset() {\n\tif c.isNoColorSet() {\n\t\treturn\n\t}\n\n\tUnset()\n}\n\nfunc (c *Color) setWriter(w io.Writer) *Color {\n\tif c.isNoColorSet() {\n\t\treturn c\n\t}\n\n\tfmt.Fprintf(w, c.format())\n\treturn c\n}\n\nfunc (c *Color) unsetWriter(w io.Writer) {\n\tif c.isNoColorSet() {\n\t\treturn\n\t}\n\n\tif NoColor {\n\t\treturn\n\t}\n\n\tfmt.Fprintf(w, \"%s[%dm\", escape, Reset)\n}\n\n// Add is used to chain SGR parameters. Use as many as parameters to combine\n// and create custom color objects. Example: Add(color.FgRed, color.Underline).\nfunc (c *Color) Add(value ...Attribute) *Color {\n\tc.params = append(c.params, value...)\n\treturn c\n}\n\nfunc (c *Color) prepend(value Attribute) {\n\tc.params = append(c.params, 0)\n\tcopy(c.params[1:], c.params[0:])\n\tc.params[0] = value\n}\n\n// Fprint formats using the default formats for its operands and writes to w.\n// Spaces are added between operands when neither is a string.\n// It returns the number of bytes written and any write error encountered.\n// On Windows, users should wrap w with colorable.NewColorable() if w is of\n// type *os.File.\nfunc (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) {\n\tc.setWriter(w)\n\tdefer c.unsetWriter(w)\n\n\treturn fmt.Fprint(w, a...)\n}\n\n// Print formats using the default formats for its operands and writes to\n// standard output. Spaces are added between operands when neither is a\n// string. It returns the number of bytes written and any write error\n// encountered. This is the standard fmt.Print() method wrapped with the given\n// color.\nfunc (c *Color) Print(a ...interface{}) (n int, err error) {\n\tc.Set()\n\tdefer c.unset()\n\n\treturn fmt.Fprint(Output, a...)\n}\n\n// Fprintf formats according to a format specifier and writes to w.\n// It returns the number of bytes written and any write error encountered.\n// On Windows, users should wrap w with colorable.NewColorable() if w is of\n// type *os.File.\nfunc (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {\n\tc.setWriter(w)\n\tdefer c.unsetWriter(w)\n\n\treturn fmt.Fprintf(w, format, a...)\n}\n\n// Printf formats according to a format specifier and writes to standard output.\n// It returns the number of bytes written and any write error encountered.\n// This is the standard fmt.Printf() method wrapped with the given color.\nfunc (c *Color) Printf(format string, a ...interface{}) (n int, err error) {\n\tc.Set()\n\tdefer c.unset()\n\n\treturn fmt.Fprintf(Output, format, a...)\n}\n\n// Fprintln formats using the default formats for its operands and writes to w.\n// Spaces are always added between operands and a newline is appended.\n// On Windows, users should wrap w with colorable.NewColorable() if w is of\n// type *os.File.\nfunc (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {\n\tc.setWriter(w)\n\tdefer c.unsetWriter(w)\n\n\treturn fmt.Fprintln(w, a...)\n}\n\n// Println formats using the default formats for its operands and writes to\n// standard output. Spaces are always added between operands and a newline is\n// appended. It returns the number of bytes written and any write error\n// encountered. This is the standard fmt.Print() method wrapped with the given\n// color.\nfunc (c *Color) Println(a ...interface{}) (n int, err error) {\n\tc.Set()\n\tdefer c.unset()\n\n\treturn fmt.Fprintln(Output, a...)\n}\n\n// Sprint is just like Print, but returns a string instead of printing it.\nfunc (c *Color) Sprint(a ...interface{}) string {\n\treturn c.wrap(fmt.Sprint(a...))\n}\n\n// Sprintln is just like Println, but returns a string instead of printing it.\nfunc (c *Color) Sprintln(a ...interface{}) string {\n\treturn c.wrap(fmt.Sprintln(a...))\n}\n\n// Sprintf is just like Printf, but returns a string instead of printing it.\nfunc (c *Color) Sprintf(format string, a ...interface{}) string {\n\treturn c.wrap(fmt.Sprintf(format, a...))\n}\n\n// FprintFunc returns a new function that prints the passed arguments as\n// colorized with color.Fprint().\nfunc (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) {\n\treturn func(w io.Writer, a ...interface{}) {\n\t\tc.Fprint(w, a...)\n\t}\n}\n\n// PrintFunc returns a new function that prints the passed arguments as\n// colorized with color.Print().\nfunc (c *Color) PrintFunc() func(a ...interface{}) {\n\treturn func(a ...interface{}) {\n\t\tc.Print(a...)\n\t}\n}\n\n// FprintfFunc returns a new function that prints the passed arguments as\n// colorized with color.Fprintf().\nfunc (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) {\n\treturn func(w io.Writer, format string, a ...interface{}) {\n\t\tc.Fprintf(w, format, a...)\n\t}\n}\n\n// PrintfFunc returns a new function that prints the passed arguments as\n// colorized with color.Printf().\nfunc (c *Color) PrintfFunc() func(format string, a ...interface{}) {\n\treturn func(format string, a ...interface{}) {\n\t\tc.Printf(format, a...)\n\t}\n}\n\n// FprintlnFunc returns a new function that prints the passed arguments as\n// colorized with color.Fprintln().\nfunc (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) {\n\treturn func(w io.Writer, a ...interface{}) {\n\t\tc.Fprintln(w, a...)\n\t}\n}\n\n// PrintlnFunc returns a new function that prints the passed arguments as\n// colorized with color.Println().\nfunc (c *Color) PrintlnFunc() func(a ...interface{}) {\n\treturn func(a ...interface{}) {\n\t\tc.Println(a...)\n\t}\n}\n\n// SprintFunc returns a new function that returns colorized strings for the\n// given arguments with fmt.Sprint(). Useful to put into or mix into other\n// string. Windows users should use this in conjunction with color.Output, example:\n//\n//\tput := New(FgYellow).SprintFunc()\n//\tfmt.Fprintf(color.Output, \"This is a %s\", put(\"warning\"))\nfunc (c *Color) SprintFunc() func(a ...interface{}) string {\n\treturn func(a ...interface{}) string {\n\t\treturn c.wrap(fmt.Sprint(a...))\n\t}\n}\n\n// SprintfFunc returns a new function that returns colorized strings for the\n// given arguments with fmt.Sprintf(). Useful to put into or mix into other\n// string. Windows users should use this in conjunction with color.Output.\nfunc (c *Color) SprintfFunc() func(format string, a ...interface{}) string {\n\treturn func(format string, a ...interface{}) string {\n\t\treturn c.wrap(fmt.Sprintf(format, a...))\n\t}\n}\n\n// SprintlnFunc returns a new function that returns colorized strings for the\n// given arguments with fmt.Sprintln(). Useful to put into or mix into other\n// string. Windows users should use this in conjunction with color.Output.\nfunc (c *Color) SprintlnFunc() func(a ...interface{}) string {\n\treturn func(a ...interface{}) string {\n\t\treturn c.wrap(fmt.Sprintln(a...))\n\t}\n}\n\n// sequence returns a formatted SGR sequence to be plugged into a \"\\x1b[...m\"\n// an example output might be: \"1;36\" -> bold cyan\nfunc (c *Color) sequence() string {\n\tformat := make([]string, len(c.params))\n\tfor i, v := range c.params {\n\t\tformat[i] = strconv.Itoa(int(v))\n\t}\n\n\treturn strings.Join(format, \";\")\n}\n\n// wrap wraps the s string with the colors attributes. The string is ready to\n// be printed.\nfunc (c *Color) wrap(s string) string {\n\tif c.isNoColorSet() {\n\t\treturn s\n\t}\n\n\treturn c.format() + s + c.unformat()\n}\n\nfunc (c *Color) format() string {\n\treturn fmt.Sprintf(\"%s[%sm\", escape, c.sequence())\n}\n\nfunc (c *Color) unformat() string {\n\treturn fmt.Sprintf(\"%s[%dm\", escape, Reset)\n}\n\n// DisableColor disables the color output. Useful to not change any existing\n// code and still being able to output. Can be used for flags like\n// \"--no-color\". To enable back use EnableColor() method.\nfunc (c *Color) DisableColor() {\n\tc.noColor = boolPtr(true)\n}\n\n// EnableColor enables the color output. Use it in conjunction with\n// DisableColor(). Otherwise this method has no side effects.\nfunc (c *Color) EnableColor() {\n\tc.noColor = boolPtr(false)\n}\n\nfunc (c *Color) isNoColorSet() bool {\n\t// check first if we have user set action\n\tif c.noColor != nil {\n\t\treturn *c.noColor\n\t}\n\n\t// if not return the global option, which is disabled by default\n\treturn NoColor\n}\n\n// Equals returns a boolean value indicating whether two colors are equal.\nfunc (c *Color) Equals(c2 *Color) bool {\n\tif len(c.params) != len(c2.params) {\n\t\treturn false\n\t}\n\n\tfor _, attr := range c.params {\n\t\tif !c2.attrExists(attr) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (c *Color) attrExists(a Attribute) bool {\n\tfor _, attr := range c.params {\n\t\tif attr == a {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc boolPtr(v bool) *bool {\n\treturn &v\n}\n\nfunc getCachedColor(p Attribute) *Color {\n\tcolorsCacheMu.Lock()\n\tdefer colorsCacheMu.Unlock()\n\n\tc, ok := colorsCache[p]\n\tif !ok {\n\t\tc = New(p)\n\t\tcolorsCache[p] = c\n\t}\n\n\treturn c\n}\n\nfunc colorPrint(format string, p Attribute, a ...interface{}) {\n\tc := getCachedColor(p)\n\n\tif !strings.HasSuffix(format, \"\\n\") {\n\t\tformat += \"\\n\"\n\t}\n\n\tif len(a) == 0 {\n\t\tc.Print(format)\n\t} else {\n\t\tc.Printf(format, a...)\n\t}\n}\n\nfunc colorString(format string, p Attribute, a ...interface{}) string {\n\tc := getCachedColor(p)\n\n\tif len(a) == 0 {\n\t\treturn c.SprintFunc()(format)\n\t}\n\n\treturn c.SprintfFunc()(format, a...)\n}\n\n// Black is a convenient helper function to print with black foreground. A\n// newline is appended to format by default.\nfunc Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) }\n\n// Red is a convenient helper function to print with red foreground. A\n// newline is appended to format by default.\nfunc Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) }\n\n// Green is a convenient helper function to print with green foreground. A\n// newline is appended to format by default.\nfunc Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) }\n\n// Yellow is a convenient helper function to print with yellow foreground.\n// A newline is appended to format by default.\nfunc Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) }\n\n// Blue is a convenient helper function to print with blue foreground. A\n// newline is appended to format by default.\nfunc Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) }\n\n// Magenta is a convenient helper function to print with magenta foreground.\n// A newline is appended to format by default.\nfunc Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) }\n\n// Cyan is a convenient helper function to print with cyan foreground. A\n// newline is appended to format by default.\nfunc Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) }\n\n// White is a convenient helper function to print with white foreground. A\n// newline is appended to format by default.\nfunc White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) }\n\n// BlackString is a convenient helper function to return a string with black\n// foreground.\nfunc BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) }\n\n// RedString is a convenient helper function to return a string with red\n// foreground.\nfunc RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) }\n\n// GreenString is a convenient helper function to return a string with green\n// foreground.\nfunc GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) }\n\n// YellowString is a convenient helper function to return a string with yellow\n// foreground.\nfunc YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) }\n\n// BlueString is a convenient helper function to return a string with blue\n// foreground.\nfunc BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) }\n\n// MagentaString is a convenient helper function to return a string with magenta\n// foreground.\nfunc MagentaString(format string, a ...interface{}) string {\n\treturn colorString(format, FgMagenta, a...)\n}\n\n// CyanString is a convenient helper function to return a string with cyan\n// foreground.\nfunc CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) }\n\n// WhiteString is a convenient helper function to return a string with white\n// foreground.\nfunc WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) }\n\n// HiBlack is a convenient helper function to print with hi-intensity black foreground. A\n// newline is appended to format by default.\nfunc HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) }\n\n// HiRed is a convenient helper function to print with hi-intensity red foreground. A\n// newline is appended to format by default.\nfunc HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) }\n\n// HiGreen is a convenient helper function to print with hi-intensity green foreground. A\n// newline is appended to format by default.\nfunc HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) }\n\n// HiYellow is a convenient helper function to print with hi-intensity yellow foreground.\n// A newline is appended to format by default.\nfunc HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) }\n\n// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A\n// newline is appended to format by default.\nfunc HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) }\n\n// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground.\n// A newline is appended to format by default.\nfunc HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) }\n\n// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A\n// newline is appended to format by default.\nfunc HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) }\n\n// HiWhite is a convenient helper function to print with hi-intensity white foreground. A\n// newline is appended to format by default.\nfunc HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) }\n\n// HiBlackString is a convenient helper function to return a string with hi-intensity black\n// foreground.\nfunc HiBlackString(format string, a ...interface{}) string {\n\treturn colorString(format, FgHiBlack, a...)\n}\n\n// HiRedString is a convenient helper function to return a string with hi-intensity red\n// foreground.\nfunc HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) }\n\n// HiGreenString is a convenient helper function to return a string with hi-intensity green\n// foreground.\nfunc HiGreenString(format string, a ...interface{}) string {\n\treturn colorString(format, FgHiGreen, a...)\n}\n\n// HiYellowString is a convenient helper function to return a string with hi-intensity yellow\n// foreground.\nfunc HiYellowString(format string, a ...interface{}) string {\n\treturn colorString(format, FgHiYellow, a...)\n}\n\n// HiBlueString is a convenient helper function to return a string with hi-intensity blue\n// foreground.\nfunc HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) }\n\n// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta\n// foreground.\nfunc HiMagentaString(format string, a ...interface{}) string {\n\treturn colorString(format, FgHiMagenta, a...)\n}\n\n// HiCyanString is a convenient helper function to return a string with hi-intensity cyan\n// foreground.\nfunc HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) }\n\n// HiWhiteString is a convenient helper function to return a string with hi-intensity white\n// foreground.\nfunc HiWhiteString(format string, a ...interface{}) string {\n\treturn colorString(format, FgHiWhite, a...)\n}\n"
  },
  {
    "path": "vendor/github.com/fatih/color/doc.go",
    "content": "/*\nPackage color is an ANSI color package to output colorized or SGR defined\noutput to the standard output. The API can be used in several way, pick one\nthat suits you.\n\nUse simple and default helper functions with predefined foreground colors:\n\n    color.Cyan(\"Prints text in cyan.\")\n\n    // a newline will be appended automatically\n    color.Blue(\"Prints %s in blue.\", \"text\")\n\n    // More default foreground colors..\n    color.Red(\"We have red\")\n    color.Yellow(\"Yellow color too!\")\n    color.Magenta(\"And many others ..\")\n\n    // Hi-intensity colors\n    color.HiGreen(\"Bright green color.\")\n    color.HiBlack(\"Bright black means gray..\")\n    color.HiWhite(\"Shiny white color!\")\n\nHowever there are times where custom color mixes are required. Below are some\nexamples to create custom color objects and use the print functions of each\nseparate color object.\n\n    // Create a new color object\n    c := color.New(color.FgCyan).Add(color.Underline)\n    c.Println(\"Prints cyan text with an underline.\")\n\n    // Or just add them to New()\n    d := color.New(color.FgCyan, color.Bold)\n    d.Printf(\"This prints bold cyan %s\\n\", \"too!.\")\n\n\n    // Mix up foreground and background colors, create new mixes!\n    red := color.New(color.FgRed)\n\n    boldRed := red.Add(color.Bold)\n    boldRed.Println(\"This will print text in bold red.\")\n\n    whiteBackground := red.Add(color.BgWhite)\n    whiteBackground.Println(\"Red text with White background.\")\n\n    // Use your own io.Writer output\n    color.New(color.FgBlue).Fprintln(myWriter, \"blue color!\")\n\n    blue := color.New(color.FgBlue)\n    blue.Fprint(myWriter, \"This will print text in blue.\")\n\nYou can create PrintXxx functions to simplify even more:\n\n    // Create a custom print function for convenient\n    red := color.New(color.FgRed).PrintfFunc()\n    red(\"warning\")\n    red(\"error: %s\", err)\n\n    // Mix up multiple attributes\n    notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()\n    notice(\"don't forget this...\")\n\nYou can also FprintXxx functions to pass your own io.Writer:\n\n    blue := color.New(FgBlue).FprintfFunc()\n    blue(myWriter, \"important notice: %s\", stars)\n\n    // Mix up with multiple attributes\n    success := color.New(color.Bold, color.FgGreen).FprintlnFunc()\n    success(myWriter, don't forget this...\")\n\n\nOr create SprintXxx functions to mix strings with other non-colorized strings:\n\n    yellow := New(FgYellow).SprintFunc()\n    red := New(FgRed).SprintFunc()\n\n    fmt.Printf(\"this is a %s and this is %s.\\n\", yellow(\"warning\"), red(\"error\"))\n\n    info := New(FgWhite, BgGreen).SprintFunc()\n    fmt.Printf(\"this %s rocks!\\n\", info(\"package\"))\n\nWindows support is enabled by default. All Print functions work as intended.\nHowever only for color.SprintXXX functions, user should use fmt.FprintXXX and\nset the output to color.Output:\n\n    fmt.Fprintf(color.Output, \"Windows support: %s\", color.GreenString(\"PASS\"))\n\n    info := New(FgWhite, BgGreen).SprintFunc()\n    fmt.Fprintf(color.Output, \"this %s rocks!\\n\", info(\"package\"))\n\nUsing with existing code is possible. Just use the Set() method to set the\nstandard output to the given parameters. That way a rewrite of an existing\ncode is not required.\n\n    // Use handy standard colors.\n    color.Set(color.FgYellow)\n\n    fmt.Println(\"Existing text will be now in Yellow\")\n    fmt.Printf(\"This one %s\\n\", \"too\")\n\n    color.Unset() // don't forget to unset\n\n    // You can mix up parameters\n    color.Set(color.FgMagenta, color.Bold)\n    defer color.Unset() // use it in your function\n\n    fmt.Println(\"All text will be now bold magenta.\")\n\nThere might be a case where you want to disable color output (for example to\npipe the standard output of your app to somewhere else). `Color` has support to\ndisable colors both globally and for single color definition. For example\nsuppose you have a CLI app and a `--no-color` bool flag. You can easily disable\nthe color output with:\n\n    var flagNoColor = flag.Bool(\"no-color\", false, \"Disable color output\")\n\n    if *flagNoColor {\n    \tcolor.NoColor = true // disables colorized output\n    }\n\nYou can also disable the color by setting the NO_COLOR environment variable to any value.\n\nIt also has support for single color definitions (local). You can\ndisable/enable color output on the fly:\n\n     c := color.New(color.FgCyan)\n     c.Println(\"Prints cyan text\")\n\n     c.DisableColor()\n     c.Println(\"This is printed without any color\")\n\n     c.EnableColor()\n     c.Println(\"This prints again cyan...\")\n*/\npackage color\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/.gitignore",
    "content": ""
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.6\n  - 1.7\n  - 1.8\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/LICENSE.txt",
    "content": "Copyright (c) 2016 Felix Geisendörfer (felix@debuggable.com)\n\n Permission is hereby granted, free of charge, to any person obtaining a copy\n of this software and associated documentation files (the \"Software\"), to deal\n in the Software without restriction, including without limitation the rights\n to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the Software is\n furnished to do so, subject to the following conditions:\n\n The above copyright notice and this permission notice shall be included in\n all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/Makefile",
    "content": ".PHONY: ci generate clean\n\nci: clean generate\n\tgo test -v ./...\n\ngenerate:\n\tgo generate .\n\nclean:\n\trm -rf *_generated*.go\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/README.md",
    "content": "# httpsnoop\n\nPackage httpsnoop provides an easy way to capture http related metrics (i.e.\nresponse time, bytes written, and http status code) from your application's\nhttp.Handlers.\n\nDoing this requires non-trivial wrapping of the http.ResponseWriter interface,\nwhich is also exposed for users interested in a more low-level API.\n\n[![GoDoc](https://godoc.org/github.com/felixge/httpsnoop?status.svg)](https://godoc.org/github.com/felixge/httpsnoop)\n[![Build Status](https://travis-ci.org/felixge/httpsnoop.svg?branch=master)](https://travis-ci.org/felixge/httpsnoop)\n\n## Usage Example\n\n```go\n// myH is your app's http handler, perhaps a http.ServeMux or similar.\nvar myH http.Handler\n// wrappedH wraps myH in order to log every request.\nwrappedH := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\tm := httpsnoop.CaptureMetrics(myH, w, r)\n\tlog.Printf(\n\t\t\"%s %s (code=%d dt=%s written=%d)\",\n\t\tr.Method,\n\t\tr.URL,\n\t\tm.Code,\n\t\tm.Duration,\n\t\tm.Written,\n\t)\n})\nhttp.ListenAndServe(\":8080\", wrappedH)\n```\n\n## Why this package exists\n\nInstrumenting an application's http.Handler is surprisingly difficult.\n\nHowever if you google for e.g. \"capture ResponseWriter status code\" you'll find\nlots of advise and code examples that suggest it to be a fairly trivial\nundertaking. Unfortunately everything I've seen so far has a high chance of\nbreaking your application.\n\nThe main problem is that a `http.ResponseWriter` often implements additional\ninterfaces such as `http.Flusher`, `http.CloseNotifier`, `http.Hijacker`, `http.Pusher`, and\n`io.ReaderFrom`. So the naive approach of just wrapping `http.ResponseWriter`\nin your own struct that also implements the `http.ResponseWriter` interface\nwill hide the additional interfaces mentioned above. This has a high change of\nintroducing subtle bugs into any non-trivial application.\n\nAnother approach I've seen people take is to return a struct that implements\nall of the interfaces above. However, that's also problematic, because it's\ndifficult to fake some of these interfaces behaviors when the underlying\n`http.ResponseWriter` doesn't have an implementation. It's also dangerous,\nbecause an application may choose to operate differently, merely because it\ndetects the presence of these additional interfaces.\n\nThis package solves this problem by checking which additional interfaces a\n`http.ResponseWriter` implements, returning a wrapped version implementing the\nexact same set of interfaces.\n\nAdditionally this package properly handles edge cases such as `WriteHeader` not\nbeing called, or called more than once, as well as concurrent calls to\n`http.ResponseWriter` methods, and even calls happening after the wrapped\n`ServeHTTP` has already returned.\n\nUnfortunately this package is not perfect either. It's possible that it is\nstill missing some interfaces provided by the go core (let me know if you find\none), and it won't work for applications adding their own interfaces into the\nmix. You can however use `httpsnoop.Unwrap(w)` to access the underlying\n`http.ResponseWriter` and type-assert the result to its other interfaces.\n\nHowever, hopefully the explanation above has sufficiently scared you of rolling\nyour own solution to this problem. httpsnoop may still break your application,\nbut at least it tries to avoid it as much as possible.\n\nAnyway, the real problem here is that smuggling additional interfaces inside\n`http.ResponseWriter` is a problematic design choice, but it probably goes as\ndeep as the Go language specification itself. But that's okay, I still prefer\nGo over the alternatives ;).\n\n## Performance\n\n```\nBenchmarkBaseline-8      \t   20000\t     94912 ns/op\nBenchmarkCaptureMetrics-8\t   20000\t     95461 ns/op\n```\n\nAs you can see, using `CaptureMetrics` on a vanilla http.Handler introduces an\noverhead of ~500 ns per http request on my machine. However, the margin of\nerror appears to be larger than that, therefor it should be reasonable to\nassume that the overhead introduced by `CaptureMetrics` is absolutely\nnegligible.\n\n## License\n\nMIT\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/capture_metrics.go",
    "content": "package httpsnoop\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// Metrics holds metrics captured from CaptureMetrics.\ntype Metrics struct {\n\t// Code is the first http response code passed to the WriteHeader func of\n\t// the ResponseWriter. If no such call is made, a default code of 200 is\n\t// assumed instead.\n\tCode int\n\t// Duration is the time it took to execute the handler.\n\tDuration time.Duration\n\t// Written is the number of bytes successfully written by the Write or\n\t// ReadFrom function of the ResponseWriter. ResponseWriters may also write\n\t// data to their underlaying connection directly (e.g. headers), but those\n\t// are not tracked. Therefor the number of Written bytes will usually match\n\t// the size of the response body.\n\tWritten int64\n}\n\n// CaptureMetrics wraps the given hnd, executes it with the given w and r, and\n// returns the metrics it captured from it.\nfunc CaptureMetrics(hnd http.Handler, w http.ResponseWriter, r *http.Request) Metrics {\n\treturn CaptureMetricsFn(w, func(ww http.ResponseWriter) {\n\t\thnd.ServeHTTP(ww, r)\n\t})\n}\n\n// CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the\n// resulting metrics. This is very similar to CaptureMetrics (which is just\n// sugar on top of this func), but is a more usable interface if your\n// application doesn't use the Go http.Handler interface.\nfunc CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics {\n\tm := Metrics{Code: http.StatusOK}\n\tm.CaptureMetrics(w, fn)\n\treturn m\n}\n\n// CaptureMetrics wraps w and calls fn with the wrapped w and updates\n// Metrics m with the resulting metrics. This is similar to CaptureMetricsFn,\n// but allows one to customize starting Metrics object.\nfunc (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWriter)) {\n\tvar (\n\t\tstart         = time.Now()\n\t\theaderWritten bool\n\t\thooks         = Hooks{\n\t\t\tWriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc {\n\t\t\t\treturn func(code int) {\n\t\t\t\t\tnext(code)\n\n\t\t\t\t\tif !headerWritten {\n\t\t\t\t\t\tm.Code = code\n\t\t\t\t\t\theaderWritten = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tWrite: func(next WriteFunc) WriteFunc {\n\t\t\t\treturn func(p []byte) (int, error) {\n\t\t\t\t\tn, err := next(p)\n\n\t\t\t\t\tm.Written += int64(n)\n\t\t\t\t\theaderWritten = true\n\t\t\t\t\treturn n, err\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tReadFrom: func(next ReadFromFunc) ReadFromFunc {\n\t\t\t\treturn func(src io.Reader) (int64, error) {\n\t\t\t\t\tn, err := next(src)\n\n\t\t\t\t\theaderWritten = true\n\t\t\t\t\tm.Written += n\n\t\t\t\t\treturn n, err\n\t\t\t\t}\n\t\t\t},\n\t\t}\n\t)\n\n\tfn(Wrap(w, hooks))\n\tm.Duration += time.Since(start)\n}\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/docs.go",
    "content": "// Package httpsnoop provides an easy way to capture http related metrics (i.e.\n// response time, bytes written, and http status code) from your application's\n// http.Handlers.\n//\n// Doing this requires non-trivial wrapping of the http.ResponseWriter\n// interface, which is also exposed for users interested in a more low-level\n// API.\npackage httpsnoop\n\n//go:generate go run codegen/main.go\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/wrap_generated_gteq_1.8.go",
    "content": "// +build go1.8\n// Code generated by \"httpsnoop/codegen\"; DO NOT EDIT\n\npackage httpsnoop\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n)\n\n// HeaderFunc is part of the http.ResponseWriter interface.\ntype HeaderFunc func() http.Header\n\n// WriteHeaderFunc is part of the http.ResponseWriter interface.\ntype WriteHeaderFunc func(code int)\n\n// WriteFunc is part of the http.ResponseWriter interface.\ntype WriteFunc func(b []byte) (int, error)\n\n// FlushFunc is part of the http.Flusher interface.\ntype FlushFunc func()\n\n// CloseNotifyFunc is part of the http.CloseNotifier interface.\ntype CloseNotifyFunc func() <-chan bool\n\n// HijackFunc is part of the http.Hijacker interface.\ntype HijackFunc func() (net.Conn, *bufio.ReadWriter, error)\n\n// ReadFromFunc is part of the io.ReaderFrom interface.\ntype ReadFromFunc func(src io.Reader) (int64, error)\n\n// PushFunc is part of the http.Pusher interface.\ntype PushFunc func(target string, opts *http.PushOptions) error\n\n// Hooks defines a set of method interceptors for methods included in\n// http.ResponseWriter as well as some others. You can think of them as\n// middleware for the function calls they target. See Wrap for more details.\ntype Hooks struct {\n\tHeader      func(HeaderFunc) HeaderFunc\n\tWriteHeader func(WriteHeaderFunc) WriteHeaderFunc\n\tWrite       func(WriteFunc) WriteFunc\n\tFlush       func(FlushFunc) FlushFunc\n\tCloseNotify func(CloseNotifyFunc) CloseNotifyFunc\n\tHijack      func(HijackFunc) HijackFunc\n\tReadFrom    func(ReadFromFunc) ReadFromFunc\n\tPush        func(PushFunc) PushFunc\n}\n\n// Wrap returns a wrapped version of w that provides the exact same interface\n// as w. Specifically if w implements any combination of:\n//\n// - http.Flusher\n// - http.CloseNotifier\n// - http.Hijacker\n// - io.ReaderFrom\n// - http.Pusher\n//\n// The wrapped version will implement the exact same combination. If no hooks\n// are set, the wrapped version also behaves exactly as w. Hooks targeting\n// methods not supported by w are ignored. Any other hooks will intercept the\n// method they target and may modify the call's arguments and/or return values.\n// The CaptureMetrics implementation serves as a working example for how the\n// hooks can be used.\nfunc Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter {\n\trw := &rw{w: w, h: hooks}\n\t_, i0 := w.(http.Flusher)\n\t_, i1 := w.(http.CloseNotifier)\n\t_, i2 := w.(http.Hijacker)\n\t_, i3 := w.(io.ReaderFrom)\n\t_, i4 := w.(http.Pusher)\n\tswitch {\n\t// combination 1/32\n\tcase !i0 && !i1 && !i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t}{rw, rw}\n\t// combination 2/32\n\tcase !i0 && !i1 && !i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw}\n\t// combination 3/32\n\tcase !i0 && !i1 && !i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw}\n\t// combination 4/32\n\tcase !i0 && !i1 && !i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw}\n\t// combination 5/32\n\tcase !i0 && !i1 && i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw}\n\t// combination 6/32\n\tcase !i0 && !i1 && i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Hijacker\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw}\n\t// combination 7/32\n\tcase !i0 && !i1 && i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw}\n\t// combination 8/32\n\tcase !i0 && !i1 && i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 9/32\n\tcase !i0 && i1 && !i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t}{rw, rw, rw}\n\t// combination 10/32\n\tcase !i0 && i1 && !i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw}\n\t// combination 11/32\n\tcase !i0 && i1 && !i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw}\n\t// combination 12/32\n\tcase !i0 && i1 && !i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 13/32\n\tcase !i0 && i1 && i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw, rw}\n\t// combination 14/32\n\tcase !i0 && i1 && i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 15/32\n\tcase !i0 && i1 && i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 16/32\n\tcase !i0 && i1 && i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw, rw}\n\t// combination 17/32\n\tcase i0 && !i1 && !i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t}{rw, rw, rw}\n\t// combination 18/32\n\tcase i0 && !i1 && !i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw}\n\t// combination 19/32\n\tcase i0 && !i1 && !i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw}\n\t// combination 20/32\n\tcase i0 && !i1 && !i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 21/32\n\tcase i0 && !i1 && i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw, rw}\n\t// combination 22/32\n\tcase i0 && !i1 && i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.Hijacker\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 23/32\n\tcase i0 && !i1 && i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 24/32\n\tcase i0 && !i1 && i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw, rw}\n\t// combination 25/32\n\tcase i0 && i1 && !i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{rw, rw, rw, rw}\n\t// combination 26/32\n\tcase i0 && i1 && !i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 27/32\n\tcase i0 && i1 && !i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 28/32\n\tcase i0 && i1 && !i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw, rw}\n\t// combination 29/32\n\tcase i0 && i1 && i2 && !i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 30/32\n\tcase i0 && i1 && i2 && !i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw, rw}\n\t// combination 31/32\n\tcase i0 && i1 && i2 && i3 && !i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw, rw}\n\t// combination 32/32\n\tcase i0 && i1 && i2 && i3 && i4:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t\thttp.Pusher\n\t\t}{rw, rw, rw, rw, rw, rw, rw}\n\t}\n\tpanic(\"unreachable\")\n}\n\ntype rw struct {\n\tw http.ResponseWriter\n\th Hooks\n}\n\nfunc (w *rw) Unwrap() http.ResponseWriter {\n\treturn w.w\n}\n\nfunc (w *rw) Header() http.Header {\n\tf := w.w.(http.ResponseWriter).Header\n\tif w.h.Header != nil {\n\t\tf = w.h.Header(f)\n\t}\n\treturn f()\n}\n\nfunc (w *rw) WriteHeader(code int) {\n\tf := w.w.(http.ResponseWriter).WriteHeader\n\tif w.h.WriteHeader != nil {\n\t\tf = w.h.WriteHeader(f)\n\t}\n\tf(code)\n}\n\nfunc (w *rw) Write(b []byte) (int, error) {\n\tf := w.w.(http.ResponseWriter).Write\n\tif w.h.Write != nil {\n\t\tf = w.h.Write(f)\n\t}\n\treturn f(b)\n}\n\nfunc (w *rw) Flush() {\n\tf := w.w.(http.Flusher).Flush\n\tif w.h.Flush != nil {\n\t\tf = w.h.Flush(f)\n\t}\n\tf()\n}\n\nfunc (w *rw) CloseNotify() <-chan bool {\n\tf := w.w.(http.CloseNotifier).CloseNotify\n\tif w.h.CloseNotify != nil {\n\t\tf = w.h.CloseNotify(f)\n\t}\n\treturn f()\n}\n\nfunc (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tf := w.w.(http.Hijacker).Hijack\n\tif w.h.Hijack != nil {\n\t\tf = w.h.Hijack(f)\n\t}\n\treturn f()\n}\n\nfunc (w *rw) ReadFrom(src io.Reader) (int64, error) {\n\tf := w.w.(io.ReaderFrom).ReadFrom\n\tif w.h.ReadFrom != nil {\n\t\tf = w.h.ReadFrom(f)\n\t}\n\treturn f(src)\n}\n\nfunc (w *rw) Push(target string, opts *http.PushOptions) error {\n\tf := w.w.(http.Pusher).Push\n\tif w.h.Push != nil {\n\t\tf = w.h.Push(f)\n\t}\n\treturn f(target, opts)\n}\n\ntype Unwrapper interface {\n\tUnwrap() http.ResponseWriter\n}\n\n// Unwrap returns the underlying http.ResponseWriter from within zero or more\n// layers of httpsnoop wrappers.\nfunc Unwrap(w http.ResponseWriter) http.ResponseWriter {\n\tif rw, ok := w.(Unwrapper); ok {\n\t\t// recurse until rw.Unwrap() returns a non-Unwrapper\n\t\treturn Unwrap(rw.Unwrap())\n\t} else {\n\t\treturn w\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/felixge/httpsnoop/wrap_generated_lt_1.8.go",
    "content": "// +build !go1.8\n// Code generated by \"httpsnoop/codegen\"; DO NOT EDIT\n\npackage httpsnoop\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n)\n\n// HeaderFunc is part of the http.ResponseWriter interface.\ntype HeaderFunc func() http.Header\n\n// WriteHeaderFunc is part of the http.ResponseWriter interface.\ntype WriteHeaderFunc func(code int)\n\n// WriteFunc is part of the http.ResponseWriter interface.\ntype WriteFunc func(b []byte) (int, error)\n\n// FlushFunc is part of the http.Flusher interface.\ntype FlushFunc func()\n\n// CloseNotifyFunc is part of the http.CloseNotifier interface.\ntype CloseNotifyFunc func() <-chan bool\n\n// HijackFunc is part of the http.Hijacker interface.\ntype HijackFunc func() (net.Conn, *bufio.ReadWriter, error)\n\n// ReadFromFunc is part of the io.ReaderFrom interface.\ntype ReadFromFunc func(src io.Reader) (int64, error)\n\n// Hooks defines a set of method interceptors for methods included in\n// http.ResponseWriter as well as some others. You can think of them as\n// middleware for the function calls they target. See Wrap for more details.\ntype Hooks struct {\n\tHeader      func(HeaderFunc) HeaderFunc\n\tWriteHeader func(WriteHeaderFunc) WriteHeaderFunc\n\tWrite       func(WriteFunc) WriteFunc\n\tFlush       func(FlushFunc) FlushFunc\n\tCloseNotify func(CloseNotifyFunc) CloseNotifyFunc\n\tHijack      func(HijackFunc) HijackFunc\n\tReadFrom    func(ReadFromFunc) ReadFromFunc\n}\n\n// Wrap returns a wrapped version of w that provides the exact same interface\n// as w. Specifically if w implements any combination of:\n//\n// - http.Flusher\n// - http.CloseNotifier\n// - http.Hijacker\n// - io.ReaderFrom\n//\n// The wrapped version will implement the exact same combination. If no hooks\n// are set, the wrapped version also behaves exactly as w. Hooks targeting\n// methods not supported by w are ignored. Any other hooks will intercept the\n// method they target and may modify the call's arguments and/or return values.\n// The CaptureMetrics implementation serves as a working example for how the\n// hooks can be used.\nfunc Wrap(w http.ResponseWriter, hooks Hooks) http.ResponseWriter {\n\trw := &rw{w: w, h: hooks}\n\t_, i0 := w.(http.Flusher)\n\t_, i1 := w.(http.CloseNotifier)\n\t_, i2 := w.(http.Hijacker)\n\t_, i3 := w.(io.ReaderFrom)\n\tswitch {\n\t// combination 1/16\n\tcase !i0 && !i1 && !i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t}{rw, rw}\n\t// combination 2/16\n\tcase !i0 && !i1 && !i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw}\n\t// combination 3/16\n\tcase !i0 && !i1 && i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw}\n\t// combination 4/16\n\tcase !i0 && !i1 && i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw}\n\t// combination 5/16\n\tcase !i0 && i1 && !i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t}{rw, rw, rw}\n\t// combination 6/16\n\tcase !i0 && i1 && !i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw}\n\t// combination 7/16\n\tcase !i0 && i1 && i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw, rw}\n\t// combination 8/16\n\tcase !i0 && i1 && i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 9/16\n\tcase i0 && !i1 && !i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t}{rw, rw, rw}\n\t// combination 10/16\n\tcase i0 && !i1 && !i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw}\n\t// combination 11/16\n\tcase i0 && !i1 && i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw, rw}\n\t// combination 12/16\n\tcase i0 && !i1 && i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 13/16\n\tcase i0 && i1 && !i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t}{rw, rw, rw, rw}\n\t// combination 14/16\n\tcase i0 && i1 && !i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 15/16\n\tcase i0 && i1 && i2 && !i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t}{rw, rw, rw, rw, rw}\n\t// combination 16/16\n\tcase i0 && i1 && i2 && i3:\n\t\treturn struct {\n\t\t\tUnwrapper\n\t\t\thttp.ResponseWriter\n\t\t\thttp.Flusher\n\t\t\thttp.CloseNotifier\n\t\t\thttp.Hijacker\n\t\t\tio.ReaderFrom\n\t\t}{rw, rw, rw, rw, rw, rw}\n\t}\n\tpanic(\"unreachable\")\n}\n\ntype rw struct {\n\tw http.ResponseWriter\n\th Hooks\n}\n\nfunc (w *rw) Unwrap() http.ResponseWriter {\n\treturn w.w\n}\n\nfunc (w *rw) Header() http.Header {\n\tf := w.w.(http.ResponseWriter).Header\n\tif w.h.Header != nil {\n\t\tf = w.h.Header(f)\n\t}\n\treturn f()\n}\n\nfunc (w *rw) WriteHeader(code int) {\n\tf := w.w.(http.ResponseWriter).WriteHeader\n\tif w.h.WriteHeader != nil {\n\t\tf = w.h.WriteHeader(f)\n\t}\n\tf(code)\n}\n\nfunc (w *rw) Write(b []byte) (int, error) {\n\tf := w.w.(http.ResponseWriter).Write\n\tif w.h.Write != nil {\n\t\tf = w.h.Write(f)\n\t}\n\treturn f(b)\n}\n\nfunc (w *rw) Flush() {\n\tf := w.w.(http.Flusher).Flush\n\tif w.h.Flush != nil {\n\t\tf = w.h.Flush(f)\n\t}\n\tf()\n}\n\nfunc (w *rw) CloseNotify() <-chan bool {\n\tf := w.w.(http.CloseNotifier).CloseNotify\n\tif w.h.CloseNotify != nil {\n\t\tf = w.h.CloseNotify(f)\n\t}\n\treturn f()\n}\n\nfunc (w *rw) Hijack() (net.Conn, *bufio.ReadWriter, error) {\n\tf := w.w.(http.Hijacker).Hijack\n\tif w.h.Hijack != nil {\n\t\tf = w.h.Hijack(f)\n\t}\n\treturn f()\n}\n\nfunc (w *rw) ReadFrom(src io.Reader) (int64, error) {\n\tf := w.w.(io.ReaderFrom).ReadFrom\n\tif w.h.ReadFrom != nil {\n\t\tf = w.h.ReadFrom(f)\n\t}\n\treturn f(src)\n}\n\ntype Unwrapper interface {\n\tUnwrap() http.ResponseWriter\n}\n\n// Unwrap returns the underlying http.ResponseWriter from within zero or more\n// layers of httpsnoop wrappers.\nfunc Unwrap(w http.ResponseWriter) http.ResponseWriter {\n\tif rw, ok := w.(Unwrapper); ok {\n\t\t// recurse until rw.Unwrap() returns a non-Unwrapper\n\t\treturn Unwrap(rw.Unwrap())\n\t} else {\n\t\treturn w\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/.gitattributes",
    "content": "* text=auto eol=lf\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/.gitignore",
    "content": "# temporary symlink for testing\ntesting/data/symlink\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/.golangci.yaml",
    "content": "run:\n  deadline: 5m\n\nlinters:\n  disable-all: true\n  enable:\n    - gofumpt\n    - goimports\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/DOCKER-LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\nYou can find the Docker license at the following link:\nhttps://raw.githubusercontent.com/docker/docker/HEAD/LICENSE\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/LICENSE",
    "content": "Copyright (c) go-dockerclient authors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (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": "vendor/github.com/fsouza/go-dockerclient/Makefile",
    "content": "ifeq \"$(strip $(shell go env GOARCH))\" \"amd64\"\nRACE_FLAG := -race\nendif\n\n.PHONY: test\ntest: pretest gotest\n\n.PHONY: golangci-lint\ngolangci-lint:\n\tgo install github.com/golangci/golangci-lint/cmd/golangci-lint@latest\n\tgolangci-lint run\n\n.PHONY: staticcheck\nstaticcheck:\n\tgo install honnef.co/go/tools/cmd/staticcheck@master\n\tstaticcheck ./...\n\n.PHONY: lint\nlint: golangci-lint staticcheck\n\n.PHONY: pretest\npretest: lint\n\n.PHONY: gotest\ngotest:\n\tgo test $(RACE_FLAG) -vet all ./...\n\n.PHONY: integration\nintegration:\n\tgo test -tags docker_integration -run TestIntegration -v\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/README.md",
    "content": "# go-dockerclient\n\n[![Build Status](https://github.com/fsouza/go-dockerclient/workflows/Build/badge.svg)](https://github.com/fsouza/go-dockerclient/actions?query=branch:main+workflow:Build)\n[![GoDoc](https://img.shields.io/badge/api-Godoc-blue.svg?style=flat-square)](https://pkg.go.dev/github.com/fsouza/go-dockerclient)\n\nThis package presents a client for the Docker remote API. It also provides\nsupport for the extensions in the [Swarm API](https://docs.docker.com/swarm/swarm-api/).\n\nThis package also provides support for docker's network API, which is a simple\npassthrough to the libnetwork remote API.\n\nFor more details, check the [remote API\ndocumentation](https://docs.docker.com/engine/api/latest/).\n\n## Difference between go-dockerclient and the official SDK\n\nLink for the official SDK: https://docs.docker.com/develop/sdk/\n\ngo-dockerclient was created before Docker had an official Go SDK and is\nstill maintained and active because it's still used out there. New features in\nthe Docker API do not get automatically implemented here: it's based on demand,\nif someone wants it, they can file an issue or a PR and the feature may get\nimplemented/merged.\n\nFor new projects, using the official SDK is probably more appropriate as\ngo-dockerclient lags behind the official SDK.\n\n## Example\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n)\n\nfunc main() {\n\tclient, err := docker.NewClientFromEnv()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\timgs, err := client.ListImages(docker.ListImagesOptions{All: false})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfor _, img := range imgs {\n\t\tfmt.Println(\"ID: \", img.ID)\n\t\tfmt.Println(\"RepoTags: \", img.RepoTags)\n\t\tfmt.Println(\"Created: \", img.Created)\n\t\tfmt.Println(\"Size: \", img.Size)\n\t\tfmt.Println(\"VirtualSize: \", img.VirtualSize)\n\t\tfmt.Println(\"ParentId: \", img.ParentID)\n\t}\n}\n```\n\n## Using with TLS\n\nIn order to instantiate the client for a TLS-enabled daemon, you should use\nNewTLSClient, passing the endpoint and path for key and certificates as\nparameters.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n)\n\nfunc main() {\n\tconst endpoint = \"tcp://[ip]:[port]\"\n\tpath := os.Getenv(\"DOCKER_CERT_PATH\")\n\tca := fmt.Sprintf(\"%s/ca.pem\", path)\n\tcert := fmt.Sprintf(\"%s/cert.pem\", path)\n\tkey := fmt.Sprintf(\"%s/key.pem\", path)\n\tclient, _ := docker.NewTLSClient(endpoint, cert, key, ca)\n\t// use client\n}\n```\n\nIf using [docker-machine](https://docs.docker.com/machine/), or another\napplication that exports environment variables `DOCKER_HOST`,\n`DOCKER_TLS_VERIFY`, `DOCKER_CERT_PATH`, `DOCKER_API_VERSION`, you can use\nNewClientFromEnv.\n\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\tdocker \"github.com/fsouza/go-dockerclient\"\n)\n\nfunc main() {\n\tclient, err := docker.NewClientFromEnv()\n\tif err != nil {\n\t\t// handle err\n\t}\n\t// use client\n}\n```\n\nSee the documentation for more details.\n\n## Developing\n\nAll development commands can be seen in the [Makefile](Makefile).\n\nCommitted code must pass:\n\n* [golangci-lint](https://github.com/golangci/golangci-lint)\n* [go test](https://golang.org/cmd/go/#hdr-Test_packages)\n* [staticcheck](https://staticcheck.io/)\n\nRunning ``make test`` will run all checks, as well as install any required\ndependencies.\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/auth.go",
    "content": "// Copyright 2015 go-dockerclient 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 docker\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path\"\n\t\"strings\"\n)\n\n// ErrCannotParseDockercfg is the error returned by NewAuthConfigurations when the dockercfg cannot be parsed.\nvar ErrCannotParseDockercfg = errors.New(\"failed to read authentication from dockercfg\")\n\n// AuthConfiguration represents authentication options to use in the PushImage\n// method. It represents the authentication in the Docker index server.\ntype AuthConfiguration struct {\n\tUsername      string `json:\"username,omitempty\"`\n\tPassword      string `json:\"password,omitempty\"`\n\tEmail         string `json:\"email,omitempty\"`\n\tServerAddress string `json:\"serveraddress,omitempty\"`\n\n\t// IdentityToken can be supplied with the identitytoken response of the AuthCheck call\n\t// see https://pkg.go.dev/github.com/docker/docker/api/types?tab=doc#AuthConfig\n\t// It can be used in place of password not in conjunction with it\n\tIdentityToken string `json:\"identitytoken,omitempty\"`\n\n\t// RegistryToken can be supplied with the registrytoken\n\tRegistryToken string `json:\"registrytoken,omitempty\"`\n}\n\nfunc (c AuthConfiguration) isEmpty() bool {\n\treturn c == AuthConfiguration{}\n}\n\nfunc (c AuthConfiguration) headerKey() string {\n\treturn \"X-Registry-Auth\"\n}\n\n// AuthConfigurations represents authentication options to use for the\n// PushImage method accommodating the new X-Registry-Config header\ntype AuthConfigurations struct {\n\tConfigs map[string]AuthConfiguration `json:\"configs\"`\n}\n\nfunc (c AuthConfigurations) isEmpty() bool {\n\treturn len(c.Configs) == 0\n}\n\nfunc (AuthConfigurations) headerKey() string {\n\treturn \"X-Registry-Config\"\n}\n\n// merge updates the configuration. If a key is defined in both maps, the one\n// in c.Configs takes precedence.\nfunc (c *AuthConfigurations) merge(other AuthConfigurations) {\n\tfor k, v := range other.Configs {\n\t\tif c.Configs == nil {\n\t\t\tc.Configs = make(map[string]AuthConfiguration)\n\t\t}\n\t\tif _, ok := c.Configs[k]; !ok {\n\t\t\tc.Configs[k] = v\n\t\t}\n\t}\n}\n\n// AuthConfigurations119 is used to serialize a set of AuthConfigurations\n// for Docker API >= 1.19.\ntype AuthConfigurations119 map[string]AuthConfiguration\n\nfunc (c AuthConfigurations119) isEmpty() bool {\n\treturn len(c) == 0\n}\n\nfunc (c AuthConfigurations119) headerKey() string {\n\treturn \"X-Registry-Config\"\n}\n\n// dockerConfig represents a registry authentation configuration from the\n// .dockercfg file.\ntype dockerConfig struct {\n\tAuth          string `json:\"auth\"`\n\tEmail         string `json:\"email\"`\n\tIdentityToken string `json:\"identitytoken\"`\n\tRegistryToken string `json:\"registrytoken\"`\n}\n\n// NewAuthConfigurationsFromFile returns AuthConfigurations from a path containing JSON\n// in the same format as the .dockercfg file.\nfunc NewAuthConfigurationsFromFile(path string) (*AuthConfigurations, error) {\n\tr, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewAuthConfigurations(r)\n}\n\nfunc cfgPaths(dockerConfigEnv string, homeEnv string) []string {\n\tif dockerConfigEnv != \"\" {\n\t\treturn []string{\n\t\t\tpath.Join(dockerConfigEnv, \"plaintext-passwords.json\"),\n\t\t\tpath.Join(dockerConfigEnv, \"config.json\"),\n\t\t}\n\t}\n\tif homeEnv != \"\" {\n\t\treturn []string{\n\t\t\tpath.Join(homeEnv, \".docker\", \"plaintext-passwords.json\"),\n\t\t\tpath.Join(homeEnv, \".docker\", \"config.json\"),\n\t\t\tpath.Join(homeEnv, \".dockercfg\"),\n\t\t}\n\t}\n\treturn nil\n}\n\n// NewAuthConfigurationsFromDockerCfg returns AuthConfigurations from system\n// config files. The following files are checked in the order listed:\n//\n// If the environment variable DOCKER_CONFIG is set to a non-empty string:\n//\n// - $DOCKER_CONFIG/plaintext-passwords.json\n// - $DOCKER_CONFIG/config.json\n//\n// Otherwise, it looks for files in the $HOME directory and the legacy\n// location:\n//\n// - $HOME/.docker/plaintext-passwords.json\n// - $HOME/.docker/config.json\n// - $HOME/.dockercfg\nfunc NewAuthConfigurationsFromDockerCfg() (*AuthConfigurations, error) {\n\tpathsToTry := cfgPaths(os.Getenv(\"DOCKER_CONFIG\"), os.Getenv(\"HOME\"))\n\tif len(pathsToTry) < 1 {\n\t\treturn nil, errors.New(\"no docker configuration found\")\n\t}\n\treturn newAuthConfigurationsFromDockerCfg(pathsToTry)\n}\n\nfunc newAuthConfigurationsFromDockerCfg(pathsToTry []string) (*AuthConfigurations, error) {\n\tvar result *AuthConfigurations\n\tvar auths *AuthConfigurations\n\tvar err error\n\tfor _, path := range pathsToTry {\n\t\tauths, err = NewAuthConfigurationsFromFile(path)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif result == nil {\n\t\t\tresult = auths\n\t\t} else {\n\t\t\tresult.merge(*auths)\n\t\t}\n\t}\n\n\tif result != nil {\n\t\treturn result, nil\n\t}\n\treturn result, err\n}\n\n// NewAuthConfigurations returns AuthConfigurations from a JSON encoded string in the\n// same format as the .dockercfg file.\nfunc NewAuthConfigurations(r io.Reader) (*AuthConfigurations, error) {\n\tvar auth *AuthConfigurations\n\tconfs, err := parseDockerConfig(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tauth, err = authConfigs(confs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn auth, nil\n}\n\nfunc parseDockerConfig(r io.Reader) (map[string]dockerConfig, error) {\n\tbuf := new(bytes.Buffer)\n\tbuf.ReadFrom(r)\n\tbyteData := buf.Bytes()\n\n\tconfsWrapper := struct {\n\t\tAuths map[string]dockerConfig `json:\"auths\"`\n\t}{}\n\tif err := json.Unmarshal(byteData, &confsWrapper); err == nil {\n\t\tif len(confsWrapper.Auths) > 0 {\n\t\t\treturn confsWrapper.Auths, nil\n\t\t}\n\t}\n\n\tvar confs map[string]dockerConfig\n\tif err := json.Unmarshal(byteData, &confs); err != nil {\n\t\treturn nil, err\n\t}\n\treturn confs, nil\n}\n\n// authConfigs converts a dockerConfigs map to a AuthConfigurations object.\nfunc authConfigs(confs map[string]dockerConfig) (*AuthConfigurations, error) {\n\tc := &AuthConfigurations{\n\t\tConfigs: make(map[string]AuthConfiguration),\n\t}\n\n\tfor reg, conf := range confs {\n\t\tif conf.Auth == \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// support both padded and unpadded encoding\n\t\tdata, err := base64.StdEncoding.DecodeString(conf.Auth)\n\t\tif err != nil {\n\t\t\tdata, err = base64.StdEncoding.WithPadding(base64.NoPadding).DecodeString(conf.Auth)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"error decoding plaintext credentials\")\n\t\t}\n\n\t\tuserpass := strings.SplitN(string(data), \":\", 2)\n\t\tif len(userpass) != 2 {\n\t\t\treturn nil, ErrCannotParseDockercfg\n\t\t}\n\n\t\tauthConfig := AuthConfiguration{\n\t\t\tEmail:         conf.Email,\n\t\t\tUsername:      userpass[0],\n\t\t\tPassword:      userpass[1],\n\t\t\tServerAddress: reg,\n\t\t}\n\n\t\t// if identitytoken provided then zero the password and set it\n\t\tif conf.IdentityToken != \"\" {\n\t\t\tauthConfig.Password = \"\"\n\t\t\tauthConfig.IdentityToken = conf.IdentityToken\n\t\t}\n\n\t\t// if registrytoken provided then zero the password and set it\n\t\tif conf.RegistryToken != \"\" {\n\t\t\tauthConfig.Password = \"\"\n\t\t\tauthConfig.RegistryToken = conf.RegistryToken\n\t\t}\n\t\tc.Configs[reg] = authConfig\n\t}\n\n\treturn c, nil\n}\n\n// AuthStatus returns the authentication status for Docker API versions >= 1.23.\ntype AuthStatus struct {\n\tStatus        string `json:\"Status,omitempty\" yaml:\"Status,omitempty\" toml:\"Status,omitempty\"`\n\tIdentityToken string `json:\"IdentityToken,omitempty\" yaml:\"IdentityToken,omitempty\" toml:\"IdentityToken,omitempty\"`\n}\n\n// AuthCheck validates the given credentials. It returns nil if successful.\n//\n// For Docker API versions >= 1.23, the AuthStatus struct will be populated, otherwise it will be empty.`\n//\n// See https://goo.gl/6nsZkH for more details.\nfunc (c *Client) AuthCheck(conf *AuthConfiguration) (AuthStatus, error) {\n\treturn c.AuthCheckWithContext(conf, context.TODO())\n}\n\n// AuthCheckWithContext validates the given credentials. It returns nil if successful. The context object\n// can be used to cancel the request.\n//\n// For Docker API versions >= 1.23, the AuthStatus struct will be populated, otherwise it will be empty.\n//\n// See https://goo.gl/6nsZkH for more details.\nfunc (c *Client) AuthCheckWithContext(conf *AuthConfiguration, ctx context.Context) (AuthStatus, error) {\n\tvar authStatus AuthStatus\n\tif conf == nil {\n\t\treturn authStatus, errors.New(\"conf is nil\")\n\t}\n\tresp, err := c.do(http.MethodPost, \"/auth\", doOptions{data: conf, context: ctx})\n\tif err != nil {\n\t\treturn authStatus, err\n\t}\n\tdefer resp.Body.Close()\n\tdata, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn authStatus, err\n\t}\n\tif len(data) == 0 {\n\t\treturn authStatus, nil\n\t}\n\tif err := json.Unmarshal(data, &authStatus); err != nil {\n\t\treturn authStatus, err\n\t}\n\treturn authStatus, nil\n}\n\n// helperCredentials represents credentials commit from an helper\ntype helperCredentials struct {\n\tUsername string `json:\"Username,omitempty\"`\n\tSecret   string `json:\"Secret,omitempty\"`\n}\n\n// NewAuthConfigurationsFromCredsHelpers returns AuthConfigurations from\n// installed credentials helpers\nfunc NewAuthConfigurationsFromCredsHelpers(registry string) (*AuthConfiguration, error) {\n\t// Load docker configuration file in order to find a possible helper provider\n\tpathsToTry := cfgPaths(os.Getenv(\"DOCKER_CONFIG\"), os.Getenv(\"HOME\"))\n\tif len(pathsToTry) < 1 {\n\t\treturn nil, errors.New(\"no docker configuration found\")\n\t}\n\n\tprovider, err := getHelperProviderFromDockerCfg(pathsToTry, registry)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tc, err := getCredentialsFromHelper(provider, registry)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcreds := new(AuthConfiguration)\n\tcreds.Username = c.Username\n\tcreds.Password = c.Secret\n\treturn creds, nil\n}\n\nfunc getHelperProviderFromDockerCfg(pathsToTry []string, registry string) (string, error) {\n\tfor _, path := range pathsToTry {\n\t\tcontent, err := os.ReadFile(path)\n\t\tif err != nil {\n\t\t\t// if we can't read the file keep going\n\t\t\tcontinue\n\t\t}\n\n\t\tprovider, err := parseCredsDockerConfig(content, registry)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif provider != \"\" {\n\t\t\treturn provider, nil\n\t\t}\n\t}\n\treturn \"\", errors.New(\"no docker credentials provider found\")\n}\n\nfunc parseCredsDockerConfig(config []byte, registry string) (string, error) {\n\tcreds := struct {\n\t\tCredsStore  string            `json:\"credsStore,omitempty\"`\n\t\tCredHelpers map[string]string `json:\"credHelpers,omitempty\"`\n\t}{}\n\terr := json.Unmarshal(config, &creds)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tprovider, ok := creds.CredHelpers[registry]\n\tif ok {\n\t\treturn provider, nil\n\t}\n\treturn creds.CredsStore, nil\n}\n\n// Run and parse the found credential helper\nfunc getCredentialsFromHelper(provider string, registry string) (*helperCredentials, error) {\n\thelpercreds, err := runDockerCredentialsHelper(provider, registry)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tc := new(helperCredentials)\n\terr = json.Unmarshal(helpercreds, c)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn c, nil\n}\n\nfunc runDockerCredentialsHelper(provider string, registry string) ([]byte, error) {\n\tcmd := exec.Command(\"docker-credential-\"+provider, \"get\")\n\n\tvar stdout bytes.Buffer\n\n\tcmd.Stdin = bytes.NewBuffer([]byte(registry))\n\tcmd.Stdout = &stdout\n\n\terr := cmd.Run()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn stdout.Bytes(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/change.go",
    "content": "// Copyright 2014 go-dockerclient 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 docker\n\nimport \"fmt\"\n\n// ChangeType is a type for constants indicating the type of change\n// in a container\ntype ChangeType int\n\nconst (\n\t// ChangeModify is the ChangeType for container modifications\n\tChangeModify ChangeType = iota\n\n\t// ChangeAdd is the ChangeType for additions to a container\n\tChangeAdd\n\n\t// ChangeDelete is the ChangeType for deletions from a container\n\tChangeDelete\n)\n\n// Change represents a change in a container.\n//\n// See https://goo.gl/Wo0JJp for more details.\ntype Change struct {\n\tPath string\n\tKind ChangeType\n}\n\nfunc (change *Change) String() string {\n\tvar kind string\n\tswitch change.Kind {\n\tcase ChangeModify:\n\t\tkind = \"C\"\n\tcase ChangeAdd:\n\t\tkind = \"A\"\n\tcase ChangeDelete:\n\t\tkind = \"D\"\n\t}\n\treturn fmt.Sprintf(\"%s %s\", kind, change.Path)\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/client.go",
    "content": "// Copyright 2013 go-dockerclient 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// Package docker provides a client for the Docker remote API.\n//\n// See https://goo.gl/o2v3rk for more details on the remote API.\npackage docker\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/docker/docker/pkg/homedir\"\n\t\"github.com/docker/docker/pkg/jsonmessage\"\n\t\"github.com/docker/docker/pkg/stdcopy\"\n)\n\nconst (\n\tuserAgent = \"go-dockerclient\"\n\n\tunixProtocol      = \"unix\"\n\tnamedPipeProtocol = \"npipe\"\n)\n\nvar (\n\t// ErrInvalidEndpoint is returned when the endpoint is not a valid HTTP URL.\n\tErrInvalidEndpoint = errors.New(\"invalid endpoint\")\n\n\t// ErrConnectionRefused is returned when the client cannot connect to the given endpoint.\n\tErrConnectionRefused = errors.New(\"cannot connect to Docker endpoint\")\n\n\t// ErrInactivityTimeout is returned when a streamable call has been inactive for some time.\n\tErrInactivityTimeout = errors.New(\"inactivity time exceeded timeout\")\n\n\tapiVersion112, _ = NewAPIVersion(\"1.12\")\n\tapiVersion118, _ = NewAPIVersion(\"1.18\")\n\tapiVersion119, _ = NewAPIVersion(\"1.19\")\n\tapiVersion121, _ = NewAPIVersion(\"1.21\")\n\tapiVersion124, _ = NewAPIVersion(\"1.24\")\n\tapiVersion125, _ = NewAPIVersion(\"1.25\")\n\tapiVersion135, _ = NewAPIVersion(\"1.35\")\n)\n\n// APIVersion is an internal representation of a version of the Remote API.\ntype APIVersion []int\n\n// NewAPIVersion returns an instance of APIVersion for the given string.\n//\n// The given string must be in the form <major>.<minor>.<patch>, where <major>,\n// <minor> and <patch> are integer numbers.\nfunc NewAPIVersion(input string) (APIVersion, error) {\n\tif !strings.Contains(input, \".\") {\n\t\treturn nil, fmt.Errorf(\"unable to parse version %q\", input)\n\t}\n\traw := strings.Split(input, \"-\")\n\tarr := strings.Split(raw[0], \".\")\n\tret := make(APIVersion, len(arr))\n\tvar err error\n\tfor i, val := range arr {\n\t\tret[i], err = strconv.Atoi(val)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to parse version %q: %q is not an integer\", input, val)\n\t\t}\n\t}\n\treturn ret, nil\n}\n\nfunc (version APIVersion) String() string {\n\tparts := make([]string, len(version))\n\tfor i, val := range version {\n\t\tparts[i] = strconv.Itoa(val)\n\t}\n\treturn strings.Join(parts, \".\")\n}\n\n// LessThan is a function for comparing APIVersion structs.\nfunc (version APIVersion) LessThan(other APIVersion) bool {\n\treturn version.compare(other) < 0\n}\n\n// LessThanOrEqualTo is a function for comparing APIVersion structs.\nfunc (version APIVersion) LessThanOrEqualTo(other APIVersion) bool {\n\treturn version.compare(other) <= 0\n}\n\n// GreaterThan is a function for comparing APIVersion structs.\nfunc (version APIVersion) GreaterThan(other APIVersion) bool {\n\treturn version.compare(other) > 0\n}\n\n// GreaterThanOrEqualTo is a function for comparing APIVersion structs.\nfunc (version APIVersion) GreaterThanOrEqualTo(other APIVersion) bool {\n\treturn version.compare(other) >= 0\n}\n\nfunc (version APIVersion) compare(other APIVersion) int {\n\tfor i, v := range version {\n\t\tif i <= len(other)-1 {\n\t\t\totherVersion := other[i]\n\n\t\t\tif v < otherVersion {\n\t\t\t\treturn -1\n\t\t\t} else if v > otherVersion {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t}\n\t}\n\tif len(version) > len(other) {\n\t\treturn 1\n\t}\n\tif len(version) < len(other) {\n\t\treturn -1\n\t}\n\treturn 0\n}\n\n// Client is the basic type of this package. It provides methods for\n// interaction with the API.\ntype Client struct {\n\tSkipServerVersionCheck bool\n\tHTTPClient             *http.Client\n\tTLSConfig              *tls.Config\n\tDialer                 Dialer\n\n\tendpoint            string\n\tendpointURL         *url.URL\n\teventMonitor        *eventMonitoringState\n\trequestedAPIVersion APIVersion\n\tserverAPIVersion    APIVersion\n\texpectedAPIVersion  APIVersion\n}\n\n// Dialer is an interface that allows network connections to be dialed\n// (net.Dialer fulfills this interface) and named pipes (a shim using\n// winio.DialPipe)\ntype Dialer interface {\n\tDial(network, address string) (net.Conn, error)\n}\n\n// NewClient returns a Client instance ready for communication with the given\n// server endpoint. It will use the latest remote API version available in the\n// server.\nfunc NewClient(endpoint string) (*Client, error) {\n\tclient, err := NewVersionedClient(endpoint, \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tclient.SkipServerVersionCheck = true\n\treturn client, nil\n}\n\n// NewTLSClient returns a Client instance ready for TLS communications with the givens\n// server endpoint, key and certificates . It will use the latest remote API version\n// available in the server.\nfunc NewTLSClient(endpoint string, cert, key, ca string) (*Client, error) {\n\tclient, err := NewVersionedTLSClient(endpoint, cert, key, ca, \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tclient.SkipServerVersionCheck = true\n\treturn client, nil\n}\n\n// NewTLSClientFromBytes returns a Client instance ready for TLS communications with the givens\n// server endpoint, key and certificates (passed inline to the function as opposed to being\n// read from a local file). It will use the latest remote API version available in the server.\nfunc NewTLSClientFromBytes(endpoint string, certPEMBlock, keyPEMBlock, caPEMCert []byte) (*Client, error) {\n\tclient, err := NewVersionedTLSClientFromBytes(endpoint, certPEMBlock, keyPEMBlock, caPEMCert, \"\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tclient.SkipServerVersionCheck = true\n\treturn client, nil\n}\n\n// NewVersionedClient returns a Client instance ready for communication with\n// the given server endpoint, using a specific remote API version.\nfunc NewVersionedClient(endpoint string, apiVersionString string) (*Client, error) {\n\tu, err := parseEndpoint(endpoint, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar requestedAPIVersion APIVersion\n\tif strings.Contains(apiVersionString, \".\") {\n\t\trequestedAPIVersion, err = NewAPIVersion(apiVersionString)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tc := &Client{\n\t\tHTTPClient:          defaultClient(),\n\t\tDialer:              &net.Dialer{},\n\t\tendpoint:            endpoint,\n\t\tendpointURL:         u,\n\t\teventMonitor:        new(eventMonitoringState),\n\t\trequestedAPIVersion: requestedAPIVersion,\n\t}\n\tc.initializeNativeClient(defaultTransport)\n\treturn c, nil\n}\n\n// WithTransport replaces underlying HTTP client of Docker Client by accepting\n// a function that returns pointer to a transport object.\nfunc (c *Client) WithTransport(trFunc func() *http.Transport) {\n\tc.initializeNativeClient(trFunc)\n}\n\n// NewVersionnedTLSClient is like NewVersionedClient, but with ann extra n.\n//\n// Deprecated: Use NewVersionedTLSClient instead.\nfunc NewVersionnedTLSClient(endpoint string, cert, key, ca, apiVersionString string) (*Client, error) {\n\treturn NewVersionedTLSClient(endpoint, cert, key, ca, apiVersionString)\n}\n\n// NewVersionedTLSClient returns a Client instance ready for TLS communications with the givens\n// server endpoint, key and certificates, using a specific remote API version.\nfunc NewVersionedTLSClient(endpoint string, cert, key, ca, apiVersionString string) (*Client, error) {\n\tvar certPEMBlock []byte\n\tvar keyPEMBlock []byte\n\tvar caPEMCert []byte\n\tif _, err := os.Stat(cert); !os.IsNotExist(err) {\n\t\tcertPEMBlock, err = os.ReadFile(cert)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif _, err := os.Stat(key); !os.IsNotExist(err) {\n\t\tkeyPEMBlock, err = os.ReadFile(key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif _, err := os.Stat(ca); !os.IsNotExist(err) {\n\t\tcaPEMCert, err = os.ReadFile(ca)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn NewVersionedTLSClientFromBytes(endpoint, certPEMBlock, keyPEMBlock, caPEMCert, apiVersionString)\n}\n\n// NewClientFromEnv returns a Client instance ready for communication created from\n// Docker's default logic for the environment variables DOCKER_HOST, DOCKER_TLS_VERIFY, DOCKER_CERT_PATH,\n// and DOCKER_API_VERSION.\n//\n// See https://github.com/docker/docker/blob/1f963af697e8df3a78217f6fdbf67b8123a7db94/docker/docker.go#L68.\n// See https://github.com/docker/compose/blob/81707ef1ad94403789166d2fe042c8a718a4c748/compose/cli/docker_client.py#L7.\n// See https://github.com/moby/moby/blob/28d7dba41d0c0d9c7f0dafcc79d3c59f2b3f5dc3/client/options.go#L51\nfunc NewClientFromEnv() (*Client, error) {\n\tapiVersionString := os.Getenv(\"DOCKER_API_VERSION\")\n\tclient, err := NewVersionedClientFromEnv(apiVersionString)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tclient.SkipServerVersionCheck = apiVersionString == \"\"\n\treturn client, nil\n}\n\n// NewVersionedClientFromEnv returns a Client instance ready for TLS communications created from\n// Docker's default logic for the environment variables DOCKER_HOST, DOCKER_TLS_VERIFY, and DOCKER_CERT_PATH,\n// and using a specific remote API version.\n//\n// See https://github.com/docker/docker/blob/1f963af697e8df3a78217f6fdbf67b8123a7db94/docker/docker.go#L68.\n// See https://github.com/docker/compose/blob/81707ef1ad94403789166d2fe042c8a718a4c748/compose/cli/docker_client.py#L7.\nfunc NewVersionedClientFromEnv(apiVersionString string) (*Client, error) {\n\tdockerEnv, err := getDockerEnv()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdockerHost := dockerEnv.dockerHost\n\tif dockerEnv.dockerTLSVerify {\n\t\tparts := strings.SplitN(dockerEnv.dockerHost, \"://\", 2)\n\t\tif len(parts) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"could not split %s into two parts by ://\", dockerHost)\n\t\t}\n\t\tcert := filepath.Join(dockerEnv.dockerCertPath, \"cert.pem\")\n\t\tkey := filepath.Join(dockerEnv.dockerCertPath, \"key.pem\")\n\t\tca := filepath.Join(dockerEnv.dockerCertPath, \"ca.pem\")\n\t\treturn NewVersionedTLSClient(dockerEnv.dockerHost, cert, key, ca, apiVersionString)\n\t}\n\treturn NewVersionedClient(dockerEnv.dockerHost, apiVersionString)\n}\n\n// NewVersionedTLSClientFromBytes returns a Client instance ready for TLS communications with the givens\n// server endpoint, key and certificates (passed inline to the function as opposed to being\n// read from a local file), using a specific remote API version.\nfunc NewVersionedTLSClientFromBytes(endpoint string, certPEMBlock, keyPEMBlock, caPEMCert []byte, apiVersionString string) (*Client, error) {\n\tu, err := parseEndpoint(endpoint, true)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar requestedAPIVersion APIVersion\n\tif strings.Contains(apiVersionString, \".\") {\n\t\trequestedAPIVersion, err = NewAPIVersion(apiVersionString)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\ttlsConfig := &tls.Config{MinVersion: tls.VersionTLS12}\n\tif certPEMBlock != nil && keyPEMBlock != nil {\n\t\ttlsCert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttlsConfig.Certificates = []tls.Certificate{tlsCert}\n\t}\n\tif caPEMCert == nil {\n\t\ttlsConfig.InsecureSkipVerify = true\n\t} else {\n\t\tcaPool := x509.NewCertPool()\n\t\tif !caPool.AppendCertsFromPEM(caPEMCert) {\n\t\t\treturn nil, errors.New(\"could not add RootCA pem\")\n\t\t}\n\t\ttlsConfig.RootCAs = caPool\n\t}\n\ttr := defaultTransport()\n\ttr.TLSClientConfig = tlsConfig\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tc := &Client{\n\t\tHTTPClient:          &http.Client{Transport: tr},\n\t\tTLSConfig:           tlsConfig,\n\t\tDialer:              &net.Dialer{},\n\t\tendpoint:            endpoint,\n\t\tendpointURL:         u,\n\t\teventMonitor:        new(eventMonitoringState),\n\t\trequestedAPIVersion: requestedAPIVersion,\n\t}\n\tc.initializeNativeClient(defaultTransport)\n\treturn c, nil\n}\n\n// SetTimeout takes a timeout and applies it to the HTTPClient. It should not\n// be called concurrently with any other Client methods.\nfunc (c *Client) SetTimeout(t time.Duration) {\n\tif c.HTTPClient != nil {\n\t\tc.HTTPClient.Timeout = t\n\t}\n}\n\nfunc (c *Client) checkAPIVersion() error {\n\tserverAPIVersionString, err := c.getServerAPIVersionString()\n\tif err != nil {\n\t\treturn err\n\t}\n\tc.serverAPIVersion, err = NewAPIVersion(serverAPIVersionString)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.requestedAPIVersion == nil {\n\t\tc.expectedAPIVersion = c.serverAPIVersion\n\t} else {\n\t\tc.expectedAPIVersion = c.requestedAPIVersion\n\t}\n\treturn nil\n}\n\n// Endpoint returns the current endpoint. It's useful for getting the endpoint\n// when using functions that get this data from the environment (like\n// NewClientFromEnv.\nfunc (c *Client) Endpoint() string {\n\treturn c.endpoint\n}\n\n// Ping pings the docker server\n//\n// See https://goo.gl/wYfgY1 for more details.\nfunc (c *Client) Ping() error {\n\treturn c.PingWithContext(context.TODO())\n}\n\n// PingWithContext pings the docker server\n// The context object can be used to cancel the ping request.\n//\n// See https://goo.gl/wYfgY1 for more details.\nfunc (c *Client) PingWithContext(ctx context.Context) error {\n\tpath := \"/_ping\"\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: ctx})\n\tif err != nil {\n\t\treturn err\n\t}\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn newError(resp)\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\nfunc (c *Client) getServerAPIVersionString() (version string, err error) {\n\tresp, err := c.do(http.MethodGet, \"/version\", doOptions{})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn \"\", fmt.Errorf(\"received unexpected status %d while trying to retrieve the server version\", resp.StatusCode)\n\t}\n\tvar versionResponse map[string]any\n\tif err := json.NewDecoder(resp.Body).Decode(&versionResponse); err != nil {\n\t\treturn \"\", err\n\t}\n\tif version, ok := (versionResponse[\"ApiVersion\"]).(string); ok {\n\t\treturn version, nil\n\t}\n\treturn \"\", nil\n}\n\ntype doOptions struct {\n\tdata      any\n\tforceJSON bool\n\theaders   map[string]string\n\tcontext   context.Context\n}\n\nfunc (c *Client) do(method, path string, doOptions doOptions) (*http.Response, error) {\n\tvar params io.Reader\n\tif doOptions.data != nil || doOptions.forceJSON {\n\t\tbuf, err := json.Marshal(doOptions.data)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tparams = bytes.NewBuffer(buf)\n\t}\n\tif path != \"/version\" && !c.SkipServerVersionCheck && c.expectedAPIVersion == nil {\n\t\terr := c.checkAPIVersion()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tprotocol := c.endpointURL.Scheme\n\tvar u string\n\tswitch protocol {\n\tcase unixProtocol, namedPipeProtocol:\n\t\tu = c.getFakeNativeURL(path)\n\tdefault:\n\t\tu = c.getURL(path)\n\t}\n\n\treq, err := http.NewRequest(method, u, params)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"User-Agent\", userAgent)\n\tif doOptions.data != nil {\n\t\treq.Header.Set(\"Content-Type\", \"application/json\")\n\t} else if method == http.MethodPost {\n\t\treq.Header.Set(\"Content-Type\", \"plain/text\")\n\t}\n\n\tfor k, v := range doOptions.headers {\n\t\treq.Header.Set(k, v)\n\t}\n\n\tctx := doOptions.context\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}\n\n\tresp, err := c.HTTPClient.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"connection refused\") {\n\t\t\treturn nil, ErrConnectionRefused\n\t\t}\n\n\t\treturn nil, chooseError(ctx, err)\n\t}\n\tif resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusBadRequest {\n\t\treturn nil, newError(resp)\n\t}\n\treturn resp, nil\n}\n\ntype streamOptions struct {\n\tsetRawTerminal bool\n\trawJSONStream  bool\n\tuseJSONDecoder bool\n\theaders        map[string]string\n\tin             io.Reader\n\tstdout         io.Writer\n\tstderr         io.Writer\n\treqSent        chan struct{}\n\t// timeout is the initial connection timeout\n\ttimeout time.Duration\n\t// Timeout with no data is received, it's reset every time new data\n\t// arrives\n\tinactivityTimeout time.Duration\n\tcontext           context.Context\n}\n\nfunc chooseError(ctx context.Context, err error) error {\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn context.Cause(ctx)\n\tdefault:\n\t\treturn err\n\t}\n}\n\nfunc (c *Client) stream(method, path string, streamOptions streamOptions) error {\n\tif (method == http.MethodPost || method == http.MethodPut) && streamOptions.in == nil {\n\t\tstreamOptions.in = bytes.NewReader(nil)\n\t}\n\tif path != \"/version\" && !c.SkipServerVersionCheck && c.expectedAPIVersion == nil {\n\t\terr := c.checkAPIVersion()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn c.streamURL(method, c.getURL(path), streamOptions)\n}\n\nfunc (c *Client) streamURL(method, url string, streamOptions streamOptions) error {\n\tif (method == http.MethodPost || method == http.MethodPut) && streamOptions.in == nil {\n\t\tstreamOptions.in = bytes.NewReader(nil)\n\t}\n\tif !c.SkipServerVersionCheck && c.expectedAPIVersion == nil {\n\t\terr := c.checkAPIVersion()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// make a sub-context so that our active cancellation does not affect parent\n\tctx := streamOptions.context\n\tif ctx == nil {\n\t\tctx = context.Background()\n\t}\n\tsubCtx, cancelRequest := context.WithCancel(ctx)\n\tdefer cancelRequest()\n\n\treq, err := http.NewRequestWithContext(ctx, method, url, streamOptions.in)\n\tif err != nil {\n\t\treturn err\n\t}\n\treq.Header.Set(\"User-Agent\", userAgent)\n\tif method == http.MethodPost {\n\t\treq.Header.Set(\"Content-Type\", \"plain/text\")\n\t}\n\tfor key, val := range streamOptions.headers {\n\t\treq.Header.Set(key, val)\n\t}\n\tvar resp *http.Response\n\tprotocol := c.endpointURL.Scheme\n\taddress := c.endpointURL.Path\n\tif streamOptions.stdout == nil {\n\t\tstreamOptions.stdout = io.Discard\n\t}\n\tif streamOptions.stderr == nil {\n\t\tstreamOptions.stderr = io.Discard\n\t}\n\n\tif protocol == unixProtocol || protocol == namedPipeProtocol {\n\t\tvar dial net.Conn\n\t\tdial, err = c.Dialer.Dial(protocol, address)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tgo func() {\n\t\t\t<-subCtx.Done()\n\t\t\tdial.Close()\n\t\t}()\n\t\tbreader := bufio.NewReader(dial)\n\t\terr = req.Write(dial)\n\t\tif err != nil {\n\t\t\treturn chooseError(subCtx, err)\n\t\t}\n\n\t\t// ReadResponse may hang if server does not replay\n\t\tif streamOptions.timeout > 0 {\n\t\t\tdial.SetDeadline(time.Now().Add(streamOptions.timeout))\n\t\t}\n\n\t\tif streamOptions.reqSent != nil {\n\t\t\tclose(streamOptions.reqSent)\n\t\t}\n\t\tif resp, err = http.ReadResponse(breader, req); err != nil {\n\t\t\t// Cancel timeout for future I/O operations\n\t\t\tif streamOptions.timeout > 0 {\n\t\t\t\tdial.SetDeadline(time.Time{})\n\t\t\t}\n\t\t\tif strings.Contains(err.Error(), \"connection refused\") {\n\t\t\t\treturn ErrConnectionRefused\n\t\t\t}\n\n\t\t\treturn chooseError(subCtx, err)\n\t\t}\n\t\tdefer resp.Body.Close()\n\t} else {\n\t\tif resp, err = c.HTTPClient.Do(req.WithContext(subCtx)); err != nil {\n\t\t\tif strings.Contains(err.Error(), \"connection refused\") {\n\t\t\t\treturn ErrConnectionRefused\n\t\t\t}\n\t\t\treturn chooseError(subCtx, err)\n\t\t}\n\t\tdefer resp.Body.Close()\n\t\tif streamOptions.reqSent != nil {\n\t\t\tclose(streamOptions.reqSent)\n\t\t}\n\t}\n\tif resp.StatusCode < 200 || resp.StatusCode >= 400 {\n\t\treturn newError(resp)\n\t}\n\tvar canceled uint32\n\tif streamOptions.inactivityTimeout > 0 {\n\t\tvar ch chan<- struct{}\n\t\tresp.Body, ch = handleInactivityTimeout(resp.Body, streamOptions.inactivityTimeout, cancelRequest, &canceled)\n\t\tdefer close(ch)\n\t}\n\terr = handleStreamResponse(resp, &streamOptions)\n\tif err != nil {\n\t\tif atomic.LoadUint32(&canceled) != 0 {\n\t\t\treturn ErrInactivityTimeout\n\t\t}\n\t\treturn chooseError(subCtx, err)\n\t}\n\treturn nil\n}\n\nfunc handleStreamResponse(resp *http.Response, streamOptions *streamOptions) error {\n\tvar err error\n\tif !streamOptions.useJSONDecoder && resp.Header.Get(\"Content-Type\") != \"application/json\" {\n\t\tif streamOptions.setRawTerminal {\n\t\t\t_, err = io.Copy(streamOptions.stdout, resp.Body)\n\t\t} else {\n\t\t\t_, err = stdcopy.StdCopy(streamOptions.stdout, streamOptions.stderr, resp.Body)\n\t\t}\n\t\treturn err\n\t}\n\t// if we want to get raw json stream, just copy it back to output\n\t// without decoding it\n\tif streamOptions.rawJSONStream {\n\t\t_, err = io.Copy(streamOptions.stdout, resp.Body)\n\t\treturn err\n\t}\n\tif st, ok := streamOptions.stdout.(stream); ok {\n\t\terr = jsonmessage.DisplayJSONMessagesToStream(resp.Body, st, nil)\n\t} else {\n\t\terr = jsonmessage.DisplayJSONMessagesStream(resp.Body, streamOptions.stdout, 0, false, nil)\n\t}\n\treturn err\n}\n\ntype stream interface {\n\tio.Writer\n\tFD() uintptr\n\tIsTerminal() bool\n}\n\ntype proxyReader struct {\n\tio.ReadCloser\n\tcalls uint64\n}\n\nfunc (p *proxyReader) callCount() uint64 {\n\treturn atomic.LoadUint64(&p.calls)\n}\n\nfunc (p *proxyReader) Read(data []byte) (int, error) {\n\tatomic.AddUint64(&p.calls, 1)\n\treturn p.ReadCloser.Read(data)\n}\n\nfunc handleInactivityTimeout(reader io.ReadCloser, timeout time.Duration, cancelRequest func(), canceled *uint32) (io.ReadCloser, chan<- struct{}) {\n\tdone := make(chan struct{})\n\tproxyReader := &proxyReader{ReadCloser: reader}\n\tgo func() {\n\t\tvar lastCallCount uint64\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-time.After(timeout):\n\t\t\tcase <-done:\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcurCallCount := proxyReader.callCount()\n\t\t\tif curCallCount == lastCallCount {\n\t\t\t\tatomic.AddUint32(canceled, 1)\n\t\t\t\tcancelRequest()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlastCallCount = curCallCount\n\t\t}\n\t}()\n\treturn proxyReader, done\n}\n\ntype hijackOptions struct {\n\tsuccess        chan struct{}\n\tsetRawTerminal bool\n\tin             io.Reader\n\tstdout         io.Writer\n\tstderr         io.Writer\n\tdata           any\n}\n\n// CloseWaiter is an interface with methods for closing the underlying resource\n// and then waiting for it to finish processing.\ntype CloseWaiter interface {\n\tio.Closer\n\tWait() error\n}\n\ntype waiterFunc func() error\n\nfunc (w waiterFunc) Wait() error { return w() }\n\ntype closerFunc func() error\n\nfunc (c closerFunc) Close() error { return c() }\n\nfunc (c *Client) hijack(method, path string, hijackOptions hijackOptions) (CloseWaiter, error) {\n\tif path != \"/version\" && !c.SkipServerVersionCheck && c.expectedAPIVersion == nil {\n\t\terr := c.checkAPIVersion()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tvar params io.Reader\n\tif hijackOptions.data != nil {\n\t\tbuf, err := json.Marshal(hijackOptions.data)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tparams = bytes.NewBuffer(buf)\n\t}\n\treq, err := http.NewRequest(method, c.getURL(path), params)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Connection\", \"Upgrade\")\n\treq.Header.Set(\"Upgrade\", \"tcp\")\n\tprotocol := c.endpointURL.Scheme\n\taddress := c.endpointURL.Path\n\tif protocol != unixProtocol && protocol != namedPipeProtocol {\n\t\tprotocol = \"tcp\"\n\t\taddress = c.endpointURL.Host\n\t}\n\tvar dial net.Conn\n\tif c.TLSConfig != nil && protocol != unixProtocol && protocol != namedPipeProtocol {\n\t\tnetDialer, ok := c.Dialer.(*net.Dialer)\n\t\tif !ok {\n\t\t\treturn nil, ErrTLSNotSupported\n\t\t}\n\t\tdial, err = tlsDialWithDialer(netDialer, protocol, address, c.TLSConfig)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tdial, err = c.Dialer.Dial(protocol, address)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\terrs := make(chan error, 1)\n\tquit := make(chan struct{})\n\tgo func() {\n\t\t//lint:ignore SA1019 the alternative doesn't quite work, so keep using the deprecated thing.\n\t\tclientconn := httputil.NewClientConn(dial, nil)\n\t\tdefer clientconn.Close()\n\t\tclientconn.Do(req)\n\t\tif hijackOptions.success != nil {\n\t\t\thijackOptions.success <- struct{}{}\n\t\t\t<-hijackOptions.success\n\t\t}\n\t\trwc, br := clientconn.Hijack()\n\t\tdefer rwc.Close()\n\n\t\terrChanOut := make(chan error, 1)\n\t\terrChanIn := make(chan error, 2)\n\t\tif hijackOptions.stdout == nil && hijackOptions.stderr == nil {\n\t\t\tclose(errChanOut)\n\t\t} else {\n\t\t\t// Only copy if hijackOptions.stdout and/or hijackOptions.stderr is actually set.\n\t\t\t// Otherwise, if the only stream you care about is stdin, your attach session\n\t\t\t// will \"hang\" until the container terminates, even though you're not reading\n\t\t\t// stdout/stderr\n\t\t\tif hijackOptions.stdout == nil {\n\t\t\t\thijackOptions.stdout = io.Discard\n\t\t\t}\n\t\t\tif hijackOptions.stderr == nil {\n\t\t\t\thijackOptions.stderr = io.Discard\n\t\t\t}\n\n\t\t\tgo func() {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif hijackOptions.in != nil {\n\t\t\t\t\t\tif closer, ok := hijackOptions.in.(io.Closer); ok {\n\t\t\t\t\t\t\tcloser.Close()\n\t\t\t\t\t\t}\n\t\t\t\t\t\terrChanIn <- nil\n\t\t\t\t\t}\n\t\t\t\t}()\n\n\t\t\t\tvar err error\n\t\t\t\tif hijackOptions.setRawTerminal {\n\t\t\t\t\t_, err = io.Copy(hijackOptions.stdout, br)\n\t\t\t\t} else {\n\t\t\t\t\t_, err = stdcopy.StdCopy(hijackOptions.stdout, hijackOptions.stderr, br)\n\t\t\t\t}\n\t\t\t\terrChanOut <- err\n\t\t\t}()\n\t\t}\n\n\t\tgo func() {\n\t\t\tvar err error\n\t\t\tif hijackOptions.in != nil {\n\t\t\t\t_, err = io.Copy(rwc, hijackOptions.in)\n\t\t\t}\n\t\t\terrChanIn <- err\n\t\t\trwc.(interface {\n\t\t\t\tCloseWrite() error\n\t\t\t}).CloseWrite()\n\t\t}()\n\n\t\tvar errIn error\n\t\tselect {\n\t\tcase errIn = <-errChanIn:\n\t\tcase <-quit:\n\t\t}\n\n\t\tvar errOut error\n\t\tselect {\n\t\tcase errOut = <-errChanOut:\n\t\tcase <-quit:\n\t\t}\n\n\t\tif errIn != nil {\n\t\t\terrs <- errIn\n\t\t} else {\n\t\t\terrs <- errOut\n\t\t}\n\t}()\n\n\treturn struct {\n\t\tcloserFunc\n\t\twaiterFunc\n\t}{\n\t\tcloserFunc(func() error { close(quit); return nil }),\n\t\twaiterFunc(func() error { return <-errs }),\n\t}, nil\n}\n\nfunc (c *Client) getURL(path string) string {\n\turlStr := strings.TrimRight(c.endpointURL.String(), \"/\")\n\tif c.endpointURL.Scheme == unixProtocol || c.endpointURL.Scheme == namedPipeProtocol {\n\t\turlStr = \"\"\n\t}\n\tif c.requestedAPIVersion != nil {\n\t\treturn fmt.Sprintf(\"%s/v%s%s\", urlStr, c.requestedAPIVersion, path)\n\t}\n\treturn fmt.Sprintf(\"%s%s\", urlStr, path)\n}\n\nfunc (c *Client) getPath(basepath string, opts any) (string, error) {\n\tqueryStr, requiredAPIVersion := queryStringVersion(opts)\n\treturn c.pathVersionCheck(basepath, queryStr, requiredAPIVersion)\n}\n\nfunc (c *Client) pathVersionCheck(basepath, queryStr string, requiredAPIVersion APIVersion) (string, error) {\n\turlStr := strings.TrimRight(c.endpointURL.String(), \"/\")\n\tif c.endpointURL.Scheme == unixProtocol || c.endpointURL.Scheme == namedPipeProtocol {\n\t\turlStr = \"\"\n\t}\n\tif c.requestedAPIVersion != nil {\n\t\tif c.requestedAPIVersion.GreaterThanOrEqualTo(requiredAPIVersion) {\n\t\t\treturn fmt.Sprintf(\"%s/v%s%s?%s\", urlStr, c.requestedAPIVersion, basepath, queryStr), nil\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"API %s requires version %s, requested version %s is insufficient\",\n\t\t\tbasepath, requiredAPIVersion, c.requestedAPIVersion)\n\t}\n\tif requiredAPIVersion != nil {\n\t\treturn fmt.Sprintf(\"%s/v%s%s?%s\", urlStr, requiredAPIVersion, basepath, queryStr), nil\n\t}\n\treturn fmt.Sprintf(\"%s%s?%s\", urlStr, basepath, queryStr), nil\n}\n\n// getFakeNativeURL returns the URL needed to make an HTTP request over a UNIX\n// domain socket to the given path.\nfunc (c *Client) getFakeNativeURL(path string) string {\n\tu := *c.endpointURL // Copy.\n\n\t// Override URL so that net/http will not complain.\n\tu.Scheme = \"http\"\n\tu.Host = \"unix.sock\" // Doesn't matter what this is - it's not used.\n\tu.Path = \"\"\n\turlStr := strings.TrimRight(u.String(), \"/\")\n\tif c.requestedAPIVersion != nil {\n\t\treturn fmt.Sprintf(\"%s/v%s%s\", urlStr, c.requestedAPIVersion, path)\n\t}\n\treturn fmt.Sprintf(\"%s%s\", urlStr, path)\n}\n\nfunc queryStringVersion(opts any) (string, APIVersion) {\n\tif opts == nil {\n\t\treturn \"\", nil\n\t}\n\tvalue := reflect.ValueOf(opts)\n\tif value.Kind() == reflect.Ptr {\n\t\tvalue = value.Elem()\n\t}\n\tif value.Kind() != reflect.Struct {\n\t\treturn \"\", nil\n\t}\n\tvar apiVersion APIVersion\n\titems := url.Values(map[string][]string{})\n\tfor i := 0; i < value.NumField(); i++ {\n\t\tfield := value.Type().Field(i)\n\t\tif field.PkgPath != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tkey := field.Tag.Get(\"qs\")\n\t\tif key == \"\" {\n\t\t\tkey = strings.ToLower(field.Name)\n\t\t} else if key == \"-\" {\n\t\t\tcontinue\n\t\t}\n\t\tif addQueryStringValue(items, key, value.Field(i)) {\n\t\t\tverstr := field.Tag.Get(\"ver\")\n\t\t\tif verstr != \"\" {\n\t\t\t\tver, _ := NewAPIVersion(verstr)\n\t\t\t\tif apiVersion == nil {\n\t\t\t\t\tapiVersion = ver\n\t\t\t\t} else if ver.GreaterThan(apiVersion) {\n\t\t\t\t\tapiVersion = ver\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn items.Encode(), apiVersion\n}\n\nfunc queryString(opts any) string {\n\ts, _ := queryStringVersion(opts)\n\treturn s\n}\n\nfunc addQueryStringValue(items url.Values, key string, v reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Bool:\n\t\tif v.Bool() {\n\t\t\titems.Add(key, \"1\")\n\t\t\treturn true\n\t\t}\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tif v.Int() > 0 {\n\t\t\titems.Add(key, strconv.FormatInt(v.Int(), 10))\n\t\t\treturn true\n\t\t}\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\tif v.Uint() > 0 {\n\t\t\titems.Add(key, strconv.FormatUint(v.Uint(), 10))\n\t\t\treturn true\n\t\t}\n\tcase reflect.Float32, reflect.Float64:\n\t\tif v.Float() > 0 {\n\t\t\titems.Add(key, strconv.FormatFloat(v.Float(), 'f', -1, 64))\n\t\t\treturn true\n\t\t}\n\tcase reflect.String:\n\t\tif v.String() != \"\" {\n\t\t\titems.Add(key, v.String())\n\t\t\treturn true\n\t\t}\n\tcase reflect.Ptr:\n\t\tif !v.IsNil() {\n\t\t\tif b, err := json.Marshal(v.Interface()); err == nil {\n\t\t\t\titems.Add(key, string(b))\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase reflect.Map:\n\t\tif len(v.MapKeys()) > 0 {\n\t\t\tif b, err := json.Marshal(v.Interface()); err == nil {\n\t\t\t\titems.Add(key, string(b))\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase reflect.Array, reflect.Slice:\n\t\tvLen := v.Len()\n\t\tvar valuesAdded int\n\t\tif vLen > 0 {\n\t\t\tfor i := 0; i < vLen; i++ {\n\t\t\t\tif addQueryStringValue(items, key, v.Index(i)) {\n\t\t\t\t\tvaluesAdded++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn valuesAdded > 0\n\t}\n\treturn false\n}\n\n// Error represents failures in the API. It represents a failure from the API.\ntype Error struct {\n\tStatus  int\n\tMessage string\n}\n\nfunc newError(resp *http.Response) *Error {\n\ttype ErrMsg struct {\n\t\tMessage string `json:\"message\"`\n\t}\n\tdefer resp.Body.Close()\n\tdata, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn &Error{Status: resp.StatusCode, Message: fmt.Sprintf(\"cannot read body, err: %v\", err)}\n\t}\n\tvar emsg ErrMsg\n\terr = json.Unmarshal(data, &emsg)\n\tif err != nil {\n\t\treturn &Error{Status: resp.StatusCode, Message: string(data)}\n\t}\n\treturn &Error{Status: resp.StatusCode, Message: emsg.Message}\n}\n\nfunc (e *Error) Error() string {\n\treturn fmt.Sprintf(\"API error (%d): %s\", e.Status, e.Message)\n}\n\nfunc parseEndpoint(endpoint string, tls bool) (*url.URL, error) {\n\tif endpoint != \"\" && !strings.Contains(endpoint, \"://\") {\n\t\tendpoint = \"tcp://\" + endpoint\n\t}\n\tu, err := url.Parse(endpoint)\n\tif err != nil {\n\t\treturn nil, ErrInvalidEndpoint\n\t}\n\tif tls && u.Scheme != \"unix\" {\n\t\tu.Scheme = \"https\"\n\t}\n\tswitch u.Scheme {\n\tcase unixProtocol, namedPipeProtocol:\n\t\treturn u, nil\n\tcase \"http\", \"https\", \"tcp\":\n\t\t_, port, err := net.SplitHostPort(u.Host)\n\t\tif err != nil {\n\t\t\tvar e *net.AddrError\n\t\t\tif errors.As(err, &e) {\n\t\t\t\tif e.Err == \"missing port in address\" {\n\t\t\t\t\treturn u, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil, ErrInvalidEndpoint\n\t\t}\n\t\tnumber, err := strconv.ParseInt(port, 10, 64)\n\t\tif err == nil && number > 0 && number < 65536 {\n\t\t\tif u.Scheme == \"tcp\" {\n\t\t\t\tif tls {\n\t\t\t\t\tu.Scheme = \"https\"\n\t\t\t\t} else {\n\t\t\t\t\tu.Scheme = \"http\"\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn u, nil\n\t\t}\n\t\treturn nil, ErrInvalidEndpoint\n\tdefault:\n\t\treturn nil, ErrInvalidEndpoint\n\t}\n}\n\ntype dockerEnv struct {\n\tdockerHost      string\n\tdockerTLSVerify bool\n\tdockerCertPath  string\n}\n\nfunc getDockerEnv() (*dockerEnv, error) {\n\tdockerHost := os.Getenv(\"DOCKER_HOST\")\n\tvar err error\n\tif dockerHost == \"\" {\n\t\tdockerHost = defaultHost\n\t}\n\tdockerTLSVerify := os.Getenv(\"DOCKER_TLS_VERIFY\") != \"\"\n\tvar dockerCertPath string\n\tif dockerTLSVerify {\n\t\tdockerCertPath = os.Getenv(\"DOCKER_CERT_PATH\")\n\t\tif dockerCertPath == \"\" {\n\t\t\thome := homedir.Get()\n\t\t\tif home == \"\" {\n\t\t\t\treturn nil, errors.New(\"environment variable HOME must be set if DOCKER_CERT_PATH is not set\")\n\t\t\t}\n\t\t\tdockerCertPath = filepath.Join(home, \".docker\")\n\t\t\tdockerCertPath, err = filepath.Abs(dockerCertPath)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn &dockerEnv{\n\t\tdockerHost:      dockerHost,\n\t\tdockerTLSVerify: dockerTLSVerify,\n\t\tdockerCertPath:  dockerCertPath,\n\t}, nil\n}\n\n// defaultTransport returns a new http.Transport with similar default values to\n// http.DefaultTransport, but with idle connections and keepalives disabled.\nfunc defaultTransport() *http.Transport {\n\ttransport := defaultPooledTransport()\n\ttransport.DisableKeepAlives = true\n\ttransport.MaxIdleConnsPerHost = -1\n\treturn transport\n}\n\n// defaultPooledTransport returns a new http.Transport with similar default\n// values to http.DefaultTransport. Do not use this for transient transports as\n// it can leak file descriptors over time. Only use this for transports that\n// will be re-used for the same host(s).\nfunc defaultPooledTransport() *http.Transport {\n\ttransport := &http.Transport{\n\t\tProxy: http.ProxyFromEnvironment,\n\t\tDialContext: (&net.Dialer{\n\t\t\tTimeout:   30 * time.Second,\n\t\t\tKeepAlive: 30 * time.Second,\n\t\t}).DialContext,\n\t\tMaxIdleConns:          100,\n\t\tIdleConnTimeout:       90 * time.Second,\n\t\tTLSHandshakeTimeout:   10 * time.Second,\n\t\tExpectContinueTimeout: 1 * time.Second,\n\t\tMaxIdleConnsPerHost:   runtime.GOMAXPROCS(0) + 1,\n\t}\n\treturn transport\n}\n\n// defaultClient returns a new http.Client with similar default values to\n// http.Client, but with a non-shared Transport, idle connections disabled, and\n// keepalives disabled.\nfunc defaultClient() *http.Client {\n\treturn &http.Client{\n\t\tTransport: defaultTransport(),\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/client_unix.go",
    "content": "// Copyright 2016 go-dockerclient 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 !windows\n\npackage docker\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n)\n\nconst defaultHost = \"unix:///var/run/docker.sock\"\n\n// initializeNativeClient initializes the native Unix domain socket client on\n// Unix-style operating systems\nfunc (c *Client) initializeNativeClient(trFunc func() *http.Transport) {\n\tif c.endpointURL.Scheme != unixProtocol {\n\t\treturn\n\t}\n\tsockPath := c.endpointURL.Path\n\n\ttr := trFunc()\n\ttr.Proxy = nil\n\ttr.DialContext = func(_ context.Context, network, addr string) (net.Conn, error) {\n\t\treturn c.Dialer.Dial(unixProtocol, sockPath)\n\t}\n\tc.HTTPClient.Transport = tr\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/client_windows.go",
    "content": "// Copyright 2016 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"net\"\n\t\"net/http\"\n\t\"time\"\n\n\twinio \"github.com/Microsoft/go-winio\"\n)\n\nconst (\n\tdefaultHost             = \"npipe:////./pipe/docker_engine\"\n\tnamedPipeConnectTimeout = 2 * time.Second\n)\n\ntype pipeDialer struct {\n\tdialFunc func(network, addr string) (net.Conn, error)\n}\n\nfunc (p pipeDialer) Dial(network, address string) (net.Conn, error) {\n\treturn p.dialFunc(network, address)\n}\n\n// initializeNativeClient initializes the native Named Pipe client for Windows\nfunc (c *Client) initializeNativeClient(trFunc func() *http.Transport) {\n\tif c.endpointURL.Scheme != namedPipeProtocol {\n\t\treturn\n\t}\n\tnamedPipePath := c.endpointURL.Path\n\tdialFunc := func(_, addr string) (net.Conn, error) {\n\t\ttimeout := namedPipeConnectTimeout\n\t\treturn winio.DialPipe(namedPipePath, &timeout)\n\t}\n\ttr := trFunc()\n\ttr.Proxy = nil\n\ttr.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\treturn dialFunc(network, addr)\n\t}\n\tc.Dialer = &pipeDialer{dialFunc}\n\tc.HTTPClient.Transport = tr\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container.go",
    "content": "// Copyright 2013 go-dockerclient 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 docker\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tunits \"github.com/docker/go-units\"\n)\n\n// APIPort is a type that represents a port mapping returned by the Docker API\ntype APIPort struct {\n\tPrivatePort int64  `json:\"PrivatePort,omitempty\" yaml:\"PrivatePort,omitempty\" toml:\"PrivatePort,omitempty\"`\n\tPublicPort  int64  `json:\"PublicPort,omitempty\" yaml:\"PublicPort,omitempty\" toml:\"PublicPort,omitempty\"`\n\tType        string `json:\"Type,omitempty\" yaml:\"Type,omitempty\" toml:\"Type,omitempty\"`\n\tIP          string `json:\"IP,omitempty\" yaml:\"IP,omitempty\" toml:\"IP,omitempty\"`\n}\n\n// APIMount represents a mount point for a container.\ntype APIMount struct {\n\tName        string `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tSource      string `json:\"Source,omitempty\" yaml:\"Source,omitempty\" toml:\"Source,omitempty\"`\n\tDestination string `json:\"Destination,omitempty\" yaml:\"Destination,omitempty\" toml:\"Destination,omitempty\"`\n\tDriver      string `json:\"Driver,omitempty\" yaml:\"Driver,omitempty\" toml:\"Driver,omitempty\"`\n\tMode        string `json:\"Mode,omitempty\" yaml:\"Mode,omitempty\" toml:\"Mode,omitempty\"`\n\tRW          bool   `json:\"RW,omitempty\" yaml:\"RW,omitempty\" toml:\"RW,omitempty\"`\n\tPropagation string `json:\"Propagation,omitempty\" yaml:\"Propagation,omitempty\" toml:\"Propagation,omitempty\"`\n\tType        string `json:\"Type,omitempty\" yaml:\"Type,omitempty\" toml:\"Type,omitempty\"`\n}\n\n// APIContainers represents each container in the list returned by\n// ListContainers.\ntype APIContainers struct {\n\tID         string            `json:\"Id\" yaml:\"Id\" toml:\"Id\"`\n\tImage      string            `json:\"Image,omitempty\" yaml:\"Image,omitempty\" toml:\"Image,omitempty\"`\n\tCommand    string            `json:\"Command,omitempty\" yaml:\"Command,omitempty\" toml:\"Command,omitempty\"`\n\tCreated    int64             `json:\"Created,omitempty\" yaml:\"Created,omitempty\" toml:\"Created,omitempty\"`\n\tState      string            `json:\"State,omitempty\" yaml:\"State,omitempty\" toml:\"State,omitempty\"`\n\tStatus     string            `json:\"Status,omitempty\" yaml:\"Status,omitempty\" toml:\"Status,omitempty\"`\n\tPorts      []APIPort         `json:\"Ports,omitempty\" yaml:\"Ports,omitempty\" toml:\"Ports,omitempty\"`\n\tSizeRw     int64             `json:\"SizeRw,omitempty\" yaml:\"SizeRw,omitempty\" toml:\"SizeRw,omitempty\"`\n\tSizeRootFs int64             `json:\"SizeRootFs,omitempty\" yaml:\"SizeRootFs,omitempty\" toml:\"SizeRootFs,omitempty\"`\n\tNames      []string          `json:\"Names,omitempty\" yaml:\"Names,omitempty\" toml:\"Names,omitempty\"`\n\tLabels     map[string]string `json:\"Labels,omitempty\" yaml:\"Labels,omitempty\" toml:\"Labels,omitempty\"`\n\tNetworks   NetworkList       `json:\"NetworkSettings,omitempty\" yaml:\"NetworkSettings,omitempty\" toml:\"NetworkSettings,omitempty\"`\n\tMounts     []APIMount        `json:\"Mounts,omitempty\" yaml:\"Mounts,omitempty\" toml:\"Mounts,omitempty\"`\n}\n\n// NetworkList encapsulates a map of networks, as returned by the Docker API in\n// ListContainers.\ntype NetworkList struct {\n\tNetworks map[string]ContainerNetwork `json:\"Networks\" yaml:\"Networks,omitempty\" toml:\"Networks,omitempty\"`\n}\n\n// Port represents the port number and the protocol, in the form\n// <number>/<protocol>. For example: 80/tcp.\ntype Port string\n\n// Port returns the number of the port.\nfunc (p Port) Port() string {\n\treturn strings.Split(string(p), \"/\")[0]\n}\n\n// Proto returns the name of the protocol.\nfunc (p Port) Proto() string {\n\tparts := strings.Split(string(p), \"/\")\n\tif len(parts) == 1 {\n\t\treturn \"tcp\"\n\t}\n\treturn parts[1]\n}\n\n// HealthCheck represents one check of health.\ntype HealthCheck struct {\n\tStart    time.Time `json:\"Start,omitempty\" yaml:\"Start,omitempty\" toml:\"Start,omitempty\"`\n\tEnd      time.Time `json:\"End,omitempty\" yaml:\"End,omitempty\" toml:\"End,omitempty\"`\n\tExitCode int       `json:\"ExitCode,omitempty\" yaml:\"ExitCode,omitempty\" toml:\"ExitCode,omitempty\"`\n\tOutput   string    `json:\"Output,omitempty\" yaml:\"Output,omitempty\" toml:\"Output,omitempty\"`\n}\n\n// Health represents the health of a container.\ntype Health struct {\n\tStatus        string        `json:\"Status,omitempty\" yaml:\"Status,omitempty\" toml:\"Status,omitempty\"`\n\tFailingStreak int           `json:\"FailingStreak,omitempty\" yaml:\"FailingStreak,omitempty\" toml:\"FailingStreak,omitempty\"`\n\tLog           []HealthCheck `json:\"Log,omitempty\" yaml:\"Log,omitempty\" toml:\"Log,omitempty\"`\n}\n\n// State represents the state of a container.\ntype State struct {\n\tStatus            string    `json:\"Status,omitempty\" yaml:\"Status,omitempty\" toml:\"Status,omitempty\"`\n\tRunning           bool      `json:\"Running,omitempty\" yaml:\"Running,omitempty\" toml:\"Running,omitempty\"`\n\tPaused            bool      `json:\"Paused,omitempty\" yaml:\"Paused,omitempty\" toml:\"Paused,omitempty\"`\n\tRestarting        bool      `json:\"Restarting,omitempty\" yaml:\"Restarting,omitempty\" toml:\"Restarting,omitempty\"`\n\tOOMKilled         bool      `json:\"OOMKilled,omitempty\" yaml:\"OOMKilled,omitempty\" toml:\"OOMKilled,omitempty\"`\n\tRemovalInProgress bool      `json:\"RemovalInProgress,omitempty\" yaml:\"RemovalInProgress,omitempty\" toml:\"RemovalInProgress,omitempty\"`\n\tDead              bool      `json:\"Dead,omitempty\" yaml:\"Dead,omitempty\" toml:\"Dead,omitempty\"`\n\tPid               int       `json:\"Pid,omitempty\" yaml:\"Pid,omitempty\" toml:\"Pid,omitempty\"`\n\tExitCode          int       `json:\"ExitCode,omitempty\" yaml:\"ExitCode,omitempty\" toml:\"ExitCode,omitempty\"`\n\tError             string    `json:\"Error,omitempty\" yaml:\"Error,omitempty\" toml:\"Error,omitempty\"`\n\tStartedAt         time.Time `json:\"StartedAt,omitempty\" yaml:\"StartedAt,omitempty\" toml:\"StartedAt,omitempty\"`\n\tFinishedAt        time.Time `json:\"FinishedAt,omitempty\" yaml:\"FinishedAt,omitempty\" toml:\"FinishedAt,omitempty\"`\n\tHealth            Health    `json:\"Health,omitempty\" yaml:\"Health,omitempty\" toml:\"Health,omitempty\"`\n}\n\n// String returns a human-readable description of the state\nfunc (s *State) String() string {\n\tif s.Running {\n\t\tif s.Paused {\n\t\t\treturn fmt.Sprintf(\"Up %s (Paused)\", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))\n\t\t}\n\t\tif s.Restarting {\n\t\t\treturn fmt.Sprintf(\"Restarting (%d) %s ago\", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))\n\t\t}\n\n\t\treturn fmt.Sprintf(\"Up %s\", units.HumanDuration(time.Now().UTC().Sub(s.StartedAt)))\n\t}\n\n\tif s.RemovalInProgress {\n\t\treturn \"Removal In Progress\"\n\t}\n\n\tif s.Dead {\n\t\treturn \"Dead\"\n\t}\n\n\tif s.StartedAt.IsZero() {\n\t\treturn \"Created\"\n\t}\n\n\tif s.FinishedAt.IsZero() {\n\t\treturn \"\"\n\t}\n\n\treturn fmt.Sprintf(\"Exited (%d) %s ago\", s.ExitCode, units.HumanDuration(time.Now().UTC().Sub(s.FinishedAt)))\n}\n\n// StateString returns a single string to describe state\nfunc (s *State) StateString() string {\n\tif s.Running {\n\t\tif s.Paused {\n\t\t\treturn \"paused\"\n\t\t}\n\t\tif s.Restarting {\n\t\t\treturn \"restarting\"\n\t\t}\n\t\treturn \"running\"\n\t}\n\n\tif s.Dead {\n\t\treturn \"dead\"\n\t}\n\n\tif s.StartedAt.IsZero() {\n\t\treturn \"created\"\n\t}\n\n\treturn \"exited\"\n}\n\n// PortBinding represents the host/container port mapping as returned in the\n// `docker inspect` json\ntype PortBinding struct {\n\tHostIP   string `json:\"HostIp,omitempty\" yaml:\"HostIp,omitempty\" toml:\"HostIp,omitempty\"`\n\tHostPort string `json:\"HostPort,omitempty\" yaml:\"HostPort,omitempty\" toml:\"HostPort,omitempty\"`\n}\n\n// PortMapping represents a deprecated field in the `docker inspect` output,\n// and its value as found in NetworkSettings should always be nil\ntype PortMapping map[string]string\n\n// ContainerNetwork represents the networking settings of a container per network.\ntype ContainerNetwork struct {\n\tAliases             []string `json:\"Aliases,omitempty\" yaml:\"Aliases,omitempty\" toml:\"Aliases,omitempty\"`\n\tMacAddress          string   `json:\"MacAddress,omitempty\" yaml:\"MacAddress,omitempty\" toml:\"MacAddress,omitempty\"`\n\tGlobalIPv6PrefixLen int      `json:\"GlobalIPv6PrefixLen,omitempty\" yaml:\"GlobalIPv6PrefixLen,omitempty\" toml:\"GlobalIPv6PrefixLen,omitempty\"`\n\tGlobalIPv6Address   string   `json:\"GlobalIPv6Address,omitempty\" yaml:\"GlobalIPv6Address,omitempty\" toml:\"GlobalIPv6Address,omitempty\"`\n\tIPv6Gateway         string   `json:\"IPv6Gateway,omitempty\" yaml:\"IPv6Gateway,omitempty\" toml:\"IPv6Gateway,omitempty\"`\n\tIPPrefixLen         int      `json:\"IPPrefixLen,omitempty\" yaml:\"IPPrefixLen,omitempty\" toml:\"IPPrefixLen,omitempty\"`\n\tIPAddress           string   `json:\"IPAddress,omitempty\" yaml:\"IPAddress,omitempty\" toml:\"IPAddress,omitempty\"`\n\tGateway             string   `json:\"Gateway,omitempty\" yaml:\"Gateway,omitempty\" toml:\"Gateway,omitempty\"`\n\tEndpointID          string   `json:\"EndpointID,omitempty\" yaml:\"EndpointID,omitempty\" toml:\"EndpointID,omitempty\"`\n\tNetworkID           string   `json:\"NetworkID,omitempty\" yaml:\"NetworkID,omitempty\" toml:\"NetworkID,omitempty\"`\n}\n\n// NetworkSettings contains network-related information about a container\ntype NetworkSettings struct {\n\tNetworks               map[string]ContainerNetwork `json:\"Networks,omitempty\" yaml:\"Networks,omitempty\" toml:\"Networks,omitempty\"`\n\tIPAddress              string                      `json:\"IPAddress,omitempty\" yaml:\"IPAddress,omitempty\" toml:\"IPAddress,omitempty\"`\n\tIPPrefixLen            int                         `json:\"IPPrefixLen,omitempty\" yaml:\"IPPrefixLen,omitempty\" toml:\"IPPrefixLen,omitempty\"`\n\tMacAddress             string                      `json:\"MacAddress,omitempty\" yaml:\"MacAddress,omitempty\" toml:\"MacAddress,omitempty\"`\n\tGateway                string                      `json:\"Gateway,omitempty\" yaml:\"Gateway,omitempty\" toml:\"Gateway,omitempty\"`\n\tBridge                 string                      `json:\"Bridge,omitempty\" yaml:\"Bridge,omitempty\" toml:\"Bridge,omitempty\"`\n\tPortMapping            map[string]PortMapping      `json:\"PortMapping,omitempty\" yaml:\"PortMapping,omitempty\" toml:\"PortMapping,omitempty\"`\n\tPorts                  map[Port][]PortBinding      `json:\"Ports,omitempty\" yaml:\"Ports,omitempty\" toml:\"Ports,omitempty\"`\n\tNetworkID              string                      `json:\"NetworkID,omitempty\" yaml:\"NetworkID,omitempty\" toml:\"NetworkID,omitempty\"`\n\tEndpointID             string                      `json:\"EndpointID,omitempty\" yaml:\"EndpointID,omitempty\" toml:\"EndpointID,omitempty\"`\n\tSandboxKey             string                      `json:\"SandboxKey,omitempty\" yaml:\"SandboxKey,omitempty\" toml:\"SandboxKey,omitempty\"`\n\tGlobalIPv6Address      string                      `json:\"GlobalIPv6Address,omitempty\" yaml:\"GlobalIPv6Address,omitempty\" toml:\"GlobalIPv6Address,omitempty\"`\n\tGlobalIPv6PrefixLen    int                         `json:\"GlobalIPv6PrefixLen,omitempty\" yaml:\"GlobalIPv6PrefixLen,omitempty\" toml:\"GlobalIPv6PrefixLen,omitempty\"`\n\tIPv6Gateway            string                      `json:\"IPv6Gateway,omitempty\" yaml:\"IPv6Gateway,omitempty\" toml:\"IPv6Gateway,omitempty\"`\n\tLinkLocalIPv6Address   string                      `json:\"LinkLocalIPv6Address,omitempty\" yaml:\"LinkLocalIPv6Address,omitempty\" toml:\"LinkLocalIPv6Address,omitempty\"`\n\tLinkLocalIPv6PrefixLen int                         `json:\"LinkLocalIPv6PrefixLen,omitempty\" yaml:\"LinkLocalIPv6PrefixLen,omitempty\" toml:\"LinkLocalIPv6PrefixLen,omitempty\"`\n\tSecondaryIPAddresses   []string                    `json:\"SecondaryIPAddresses,omitempty\" yaml:\"SecondaryIPAddresses,omitempty\" toml:\"SecondaryIPAddresses,omitempty\"`\n\tSecondaryIPv6Addresses []string                    `json:\"SecondaryIPv6Addresses,omitempty\" yaml:\"SecondaryIPv6Addresses,omitempty\" toml:\"SecondaryIPv6Addresses,omitempty\"`\n}\n\n// PortMappingAPI translates the port mappings as contained in NetworkSettings\n// into the format in which they would appear when returned by the API\nfunc (settings *NetworkSettings) PortMappingAPI() []APIPort {\n\tvar mapping []APIPort\n\tfor port, bindings := range settings.Ports {\n\t\tp, _ := parsePort(port.Port())\n\t\tif len(bindings) == 0 {\n\t\t\tmapping = append(mapping, APIPort{\n\t\t\t\tPrivatePort: int64(p),\n\t\t\t\tType:        port.Proto(),\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tfor _, binding := range bindings {\n\t\t\tp, _ := parsePort(port.Port())\n\t\t\th, _ := parsePort(binding.HostPort)\n\t\t\tmapping = append(mapping, APIPort{\n\t\t\t\tPrivatePort: int64(p),\n\t\t\t\tPublicPort:  int64(h),\n\t\t\t\tType:        port.Proto(),\n\t\t\t\tIP:          binding.HostIP,\n\t\t\t})\n\t\t}\n\t}\n\treturn mapping\n}\n\nfunc parsePort(rawPort string) (int, error) {\n\tport, err := strconv.ParseUint(rawPort, 10, 16)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn int(port), nil\n}\n\n// Config is the list of configuration options used when creating a container.\n// Config does not contain the options that are specific to starting a container on a\n// given host.  Those are contained in HostConfig\ntype Config struct {\n\tHostname          string              `json:\"Hostname,omitempty\" yaml:\"Hostname,omitempty\" toml:\"Hostname,omitempty\"`\n\tDomainname        string              `json:\"Domainname,omitempty\" yaml:\"Domainname,omitempty\" toml:\"Domainname,omitempty\"`\n\tUser              string              `json:\"User,omitempty\" yaml:\"User,omitempty\" toml:\"User,omitempty\"`\n\tMemory            int64               `json:\"Memory,omitempty\" yaml:\"Memory,omitempty\" toml:\"Memory,omitempty\"`\n\tMemorySwap        int64               `json:\"MemorySwap,omitempty\" yaml:\"MemorySwap,omitempty\" toml:\"MemorySwap,omitempty\"`\n\tMemoryReservation int64               `json:\"MemoryReservation,omitempty\" yaml:\"MemoryReservation,omitempty\" toml:\"MemoryReservation,omitempty\"`\n\tKernelMemory      int64               `json:\"KernelMemory,omitempty\" yaml:\"KernelMemory,omitempty\" toml:\"KernelMemory,omitempty\"`\n\tCPUShares         int64               `json:\"CpuShares,omitempty\" yaml:\"CpuShares,omitempty\" toml:\"CpuShares,omitempty\"`\n\tCPUSet            string              `json:\"Cpuset,omitempty\" yaml:\"Cpuset,omitempty\" toml:\"Cpuset,omitempty\"`\n\tPortSpecs         []string            `json:\"PortSpecs,omitempty\" yaml:\"PortSpecs,omitempty\" toml:\"PortSpecs,omitempty\"`\n\tExposedPorts      map[Port]struct{}   `json:\"ExposedPorts,omitempty\" yaml:\"ExposedPorts,omitempty\" toml:\"ExposedPorts,omitempty\"`\n\tPublishService    string              `json:\"PublishService,omitempty\" yaml:\"PublishService,omitempty\" toml:\"PublishService,omitempty\"`\n\tStopSignal        string              `json:\"StopSignal,omitempty\" yaml:\"StopSignal,omitempty\" toml:\"StopSignal,omitempty\"`\n\tStopTimeout       int                 `json:\"StopTimeout,omitempty\" yaml:\"StopTimeout,omitempty\" toml:\"StopTimeout,omitempty\"`\n\tEnv               []string            `json:\"Env,omitempty\" yaml:\"Env,omitempty\" toml:\"Env,omitempty\"`\n\tCmd               []string            `json:\"Cmd\" yaml:\"Cmd\" toml:\"Cmd\"`\n\tShell             []string            `json:\"Shell,omitempty\" yaml:\"Shell,omitempty\" toml:\"Shell,omitempty\"`\n\tHealthcheck       *HealthConfig       `json:\"Healthcheck,omitempty\" yaml:\"Healthcheck,omitempty\" toml:\"Healthcheck,omitempty\"`\n\tDNS               []string            `json:\"Dns,omitempty\" yaml:\"Dns,omitempty\" toml:\"Dns,omitempty\"` // For Docker API v1.9 and below only\n\tImage             string              `json:\"Image,omitempty\" yaml:\"Image,omitempty\" toml:\"Image,omitempty\"`\n\tVolumes           map[string]struct{} `json:\"Volumes,omitempty\" yaml:\"Volumes,omitempty\" toml:\"Volumes,omitempty\"`\n\tVolumeDriver      string              `json:\"VolumeDriver,omitempty\" yaml:\"VolumeDriver,omitempty\" toml:\"VolumeDriver,omitempty\"`\n\tWorkingDir        string              `json:\"WorkingDir,omitempty\" yaml:\"WorkingDir,omitempty\" toml:\"WorkingDir,omitempty\"`\n\tMacAddress        string              `json:\"MacAddress,omitempty\" yaml:\"MacAddress,omitempty\" toml:\"MacAddress,omitempty\"`\n\tEntrypoint        []string            `json:\"Entrypoint\" yaml:\"Entrypoint\" toml:\"Entrypoint\"`\n\tSecurityOpts      []string            `json:\"SecurityOpts,omitempty\" yaml:\"SecurityOpts,omitempty\" toml:\"SecurityOpts,omitempty\"`\n\tOnBuild           []string            `json:\"OnBuild,omitempty\" yaml:\"OnBuild,omitempty\" toml:\"OnBuild,omitempty\"`\n\tMounts            []Mount             `json:\"Mounts,omitempty\" yaml:\"Mounts,omitempty\" toml:\"Mounts,omitempty\"`\n\tLabels            map[string]string   `json:\"Labels,omitempty\" yaml:\"Labels,omitempty\" toml:\"Labels,omitempty\"`\n\tAttachStdin       bool                `json:\"AttachStdin,omitempty\" yaml:\"AttachStdin,omitempty\" toml:\"AttachStdin,omitempty\"`\n\tAttachStdout      bool                `json:\"AttachStdout,omitempty\" yaml:\"AttachStdout,omitempty\" toml:\"AttachStdout,omitempty\"`\n\tAttachStderr      bool                `json:\"AttachStderr,omitempty\" yaml:\"AttachStderr,omitempty\" toml:\"AttachStderr,omitempty\"`\n\tArgsEscaped       bool                `json:\"ArgsEscaped,omitempty\" yaml:\"ArgsEscaped,omitempty\" toml:\"ArgsEscaped,omitempty\"`\n\tTty               bool                `json:\"Tty,omitempty\" yaml:\"Tty,omitempty\" toml:\"Tty,omitempty\"`\n\tOpenStdin         bool                `json:\"OpenStdin,omitempty\" yaml:\"OpenStdin,omitempty\" toml:\"OpenStdin,omitempty\"`\n\tStdinOnce         bool                `json:\"StdinOnce,omitempty\" yaml:\"StdinOnce,omitempty\" toml:\"StdinOnce,omitempty\"`\n\tNetworkDisabled   bool                `json:\"NetworkDisabled,omitempty\" yaml:\"NetworkDisabled,omitempty\" toml:\"NetworkDisabled,omitempty\"`\n\n\t// This is no longer used and has been kept here for backward\n\t// compatibility, please use HostConfig.VolumesFrom.\n\tVolumesFrom string `json:\"VolumesFrom,omitempty\" yaml:\"VolumesFrom,omitempty\" toml:\"VolumesFrom,omitempty\"`\n}\n\n// HostMount represents a mount point in the container in HostConfig.\n//\n// It has been added in the version 1.25 of the Docker API\ntype HostMount struct {\n\tTarget        string         `json:\"Target,omitempty\" yaml:\"Target,omitempty\" toml:\"Target,omitempty\"`\n\tSource        string         `json:\"Source,omitempty\" yaml:\"Source,omitempty\" toml:\"Source,omitempty\"`\n\tType          string         `json:\"Type,omitempty\" yaml:\"Type,omitempty\" toml:\"Type,omitempty\"`\n\tReadOnly      bool           `json:\"ReadOnly,omitempty\" yaml:\"ReadOnly,omitempty\" toml:\"ReadOnly,omitempty\"`\n\tBindOptions   *BindOptions   `json:\"BindOptions,omitempty\" yaml:\"BindOptions,omitempty\" toml:\"BindOptions,omitempty\"`\n\tVolumeOptions *VolumeOptions `json:\"VolumeOptions,omitempty\" yaml:\"VolumeOptions,omitempty\" toml:\"VolumeOptions,omitempty\"`\n\tTempfsOptions *TempfsOptions `json:\"TmpfsOptions,omitempty\" yaml:\"TmpfsOptions,omitempty\" toml:\"TmpfsOptions,omitempty\"`\n}\n\n// BindOptions contains optional configuration for the bind type\ntype BindOptions struct {\n\tPropagation string `json:\"Propagation,omitempty\" yaml:\"Propagation,omitempty\" toml:\"Propagation,omitempty\"`\n}\n\n// VolumeOptions contains optional configuration for the volume type\ntype VolumeOptions struct {\n\tNoCopy       bool               `json:\"NoCopy,omitempty\" yaml:\"NoCopy,omitempty\" toml:\"NoCopy,omitempty\"`\n\tLabels       map[string]string  `json:\"Labels,omitempty\" yaml:\"Labels,omitempty\" toml:\"Labels,omitempty\"`\n\tDriverConfig VolumeDriverConfig `json:\"DriverConfig,omitempty\" yaml:\"DriverConfig,omitempty\" toml:\"DriverConfig,omitempty\"`\n}\n\n// TempfsOptions contains optional configuration for the tempfs type\ntype TempfsOptions struct {\n\tSizeBytes int64 `json:\"SizeBytes,omitempty\" yaml:\"SizeBytes,omitempty\" toml:\"SizeBytes,omitempty\"`\n\tMode      int   `json:\"Mode,omitempty\" yaml:\"Mode,omitempty\" toml:\"Mode,omitempty\"`\n}\n\n// VolumeDriverConfig holds a map of volume driver specific options\ntype VolumeDriverConfig struct {\n\tName    string            `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tOptions map[string]string `json:\"Options,omitempty\" yaml:\"Options,omitempty\" toml:\"Options,omitempty\"`\n}\n\n// Mount represents a mount point in the container.\n//\n// It has been added in the version 1.20 of the Docker API, available since\n// Docker 1.8.\ntype Mount struct {\n\tName        string\n\tSource      string\n\tDestination string\n\tDriver      string\n\tMode        string\n\tRW          bool\n}\n\n// LogConfig defines the log driver type and the configuration for it.\ntype LogConfig struct {\n\tType   string            `json:\"Type,omitempty\" yaml:\"Type,omitempty\" toml:\"Type,omitempty\"`\n\tConfig map[string]string `json:\"Config,omitempty\" yaml:\"Config,omitempty\" toml:\"Config,omitempty\"`\n}\n\n// ULimit defines system-wide resource limitations This can help a lot in\n// system administration, e.g. when a user starts too many processes and\n// therefore makes the system unresponsive for other users.\ntype ULimit struct {\n\tName string `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tSoft int64  `json:\"Soft,omitempty\" yaml:\"Soft,omitempty\" toml:\"Soft,omitempty\"`\n\tHard int64  `json:\"Hard,omitempty\" yaml:\"Hard,omitempty\" toml:\"Hard,omitempty\"`\n}\n\n// SwarmNode containers information about which Swarm node the container is on.\ntype SwarmNode struct {\n\tID     string            `json:\"ID,omitempty\" yaml:\"ID,omitempty\" toml:\"ID,omitempty\"`\n\tIP     string            `json:\"IP,omitempty\" yaml:\"IP,omitempty\" toml:\"IP,omitempty\"`\n\tAddr   string            `json:\"Addr,omitempty\" yaml:\"Addr,omitempty\" toml:\"Addr,omitempty\"`\n\tName   string            `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tCPUs   int64             `json:\"CPUs,omitempty\" yaml:\"CPUs,omitempty\" toml:\"CPUs,omitempty\"`\n\tMemory int64             `json:\"Memory,omitempty\" yaml:\"Memory,omitempty\" toml:\"Memory,omitempty\"`\n\tLabels map[string]string `json:\"Labels,omitempty\" yaml:\"Labels,omitempty\" toml:\"Labels,omitempty\"`\n}\n\n// GraphDriver contains information about the GraphDriver used by the\n// container.\ntype GraphDriver struct {\n\tName string            `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tData map[string]string `json:\"Data,omitempty\" yaml:\"Data,omitempty\" toml:\"Data,omitempty\"`\n}\n\n// HealthConfig holds configuration settings for the HEALTHCHECK feature\n//\n// It has been added in the version 1.24 of the Docker API, available since\n// Docker 1.12.\ntype HealthConfig struct {\n\t// Test is the test to perform to check that the container is healthy.\n\t// An empty slice means to inherit the default.\n\t// The options are:\n\t// {} : inherit healthcheck\n\t// {\"NONE\"} : disable healthcheck\n\t// {\"CMD\", args...} : exec arguments directly\n\t// {\"CMD-SHELL\", command} : run command with system's default shell\n\tTest []string `json:\"Test,omitempty\" yaml:\"Test,omitempty\" toml:\"Test,omitempty\"`\n\n\t// Zero means to inherit. Durations are expressed as integer nanoseconds.\n\tInterval    time.Duration `json:\"Interval,omitempty\" yaml:\"Interval,omitempty\" toml:\"Interval,omitempty\"`          // Interval is the time to wait between checks.\n\tTimeout     time.Duration `json:\"Timeout,omitempty\" yaml:\"Timeout,omitempty\" toml:\"Timeout,omitempty\"`             // Timeout is the time to wait before considering the check to have hung.\n\tStartPeriod time.Duration `json:\"StartPeriod,omitempty\" yaml:\"StartPeriod,omitempty\" toml:\"StartPeriod,omitempty\"` // The start period for the container to initialize before the retries starts to count down.\n\n\t// Retries is the number of consecutive failures needed to consider a container as unhealthy.\n\t// Zero means inherit.\n\tRetries int `json:\"Retries,omitempty\" yaml:\"Retries,omitempty\" toml:\"Retries,omitempty\"`\n}\n\n// Container is the type encompasing everything about a container - its config,\n// hostconfig, etc.\ntype Container struct {\n\tID string `json:\"Id\" yaml:\"Id\" toml:\"Id\"`\n\n\tCreated time.Time `json:\"Created,omitempty\" yaml:\"Created,omitempty\" toml:\"Created,omitempty\"`\n\n\tPath string   `json:\"Path,omitempty\" yaml:\"Path,omitempty\" toml:\"Path,omitempty\"`\n\tArgs []string `json:\"Args,omitempty\" yaml:\"Args,omitempty\" toml:\"Args,omitempty\"`\n\n\tConfig *Config `json:\"Config,omitempty\" yaml:\"Config,omitempty\" toml:\"Config,omitempty\"`\n\tState  State   `json:\"State,omitempty\" yaml:\"State,omitempty\" toml:\"State,omitempty\"`\n\tImage  string  `json:\"Image,omitempty\" yaml:\"Image,omitempty\" toml:\"Image,omitempty\"`\n\n\tNode *SwarmNode `json:\"Node,omitempty\" yaml:\"Node,omitempty\" toml:\"Node,omitempty\"`\n\n\tNetworkSettings *NetworkSettings `json:\"NetworkSettings,omitempty\" yaml:\"NetworkSettings,omitempty\" toml:\"NetworkSettings,omitempty\"`\n\n\tSysInitPath    string  `json:\"SysInitPath,omitempty\" yaml:\"SysInitPath,omitempty\" toml:\"SysInitPath,omitempty\"`\n\tResolvConfPath string  `json:\"ResolvConfPath,omitempty\" yaml:\"ResolvConfPath,omitempty\" toml:\"ResolvConfPath,omitempty\"`\n\tHostnamePath   string  `json:\"HostnamePath,omitempty\" yaml:\"HostnamePath,omitempty\" toml:\"HostnamePath,omitempty\"`\n\tHostsPath      string  `json:\"HostsPath,omitempty\" yaml:\"HostsPath,omitempty\" toml:\"HostsPath,omitempty\"`\n\tLogPath        string  `json:\"LogPath,omitempty\" yaml:\"LogPath,omitempty\" toml:\"LogPath,omitempty\"`\n\tName           string  `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tDriver         string  `json:\"Driver,omitempty\" yaml:\"Driver,omitempty\" toml:\"Driver,omitempty\"`\n\tMounts         []Mount `json:\"Mounts,omitempty\" yaml:\"Mounts,omitempty\" toml:\"Mounts,omitempty\"`\n\n\tVolumes     map[string]string `json:\"Volumes,omitempty\" yaml:\"Volumes,omitempty\" toml:\"Volumes,omitempty\"`\n\tVolumesRW   map[string]bool   `json:\"VolumesRW,omitempty\" yaml:\"VolumesRW,omitempty\" toml:\"VolumesRW,omitempty\"`\n\tHostConfig  *HostConfig       `json:\"HostConfig,omitempty\" yaml:\"HostConfig,omitempty\" toml:\"HostConfig,omitempty\"`\n\tExecIDs     []string          `json:\"ExecIDs,omitempty\" yaml:\"ExecIDs,omitempty\" toml:\"ExecIDs,omitempty\"`\n\tGraphDriver *GraphDriver      `json:\"GraphDriver,omitempty\" yaml:\"GraphDriver,omitempty\" toml:\"GraphDriver,omitempty\"`\n\n\tRestartCount int `json:\"RestartCount,omitempty\" yaml:\"RestartCount,omitempty\" toml:\"RestartCount,omitempty\"`\n\n\tAppArmorProfile string `json:\"AppArmorProfile,omitempty\" yaml:\"AppArmorProfile,omitempty\" toml:\"AppArmorProfile,omitempty\"`\n\n\tMountLabel   string `json:\"MountLabel,omitempty\" yaml:\"MountLabel,omitempty\" toml:\"MountLabel,omitempty\"`\n\tProcessLabel string `json:\"ProcessLabel,omitempty\" yaml:\"ProcessLabel,omitempty\" toml:\"ProcessLabel,omitempty\"`\n\tPlatform     string `json:\"Platform,omitempty\" yaml:\"Platform,omitempty\" toml:\"Platform,omitempty\"`\n\tSizeRw       int64  `json:\"SizeRw,omitempty\" yaml:\"SizeRw,omitempty\" toml:\"SizeRw,omitempty\"`\n\tSizeRootFs   int64  `json:\"SizeRootFs,omitempty\" yaml:\"SizeRootFs,omitempty\" toml:\"SizeRootFs,omitempty\"`\n}\n\n// KeyValuePair is a type for generic key/value pairs as used in the Lxc\n// configuration\ntype KeyValuePair struct {\n\tKey   string `json:\"Key,omitempty\" yaml:\"Key,omitempty\" toml:\"Key,omitempty\"`\n\tValue string `json:\"Value,omitempty\" yaml:\"Value,omitempty\" toml:\"Value,omitempty\"`\n}\n\n// Device represents a device mapping between the Docker host and the\n// container.\ntype Device struct {\n\tPathOnHost        string `json:\"PathOnHost,omitempty\" yaml:\"PathOnHost,omitempty\" toml:\"PathOnHost,omitempty\"`\n\tPathInContainer   string `json:\"PathInContainer,omitempty\" yaml:\"PathInContainer,omitempty\" toml:\"PathInContainer,omitempty\"`\n\tCgroupPermissions string `json:\"CgroupPermissions,omitempty\" yaml:\"CgroupPermissions,omitempty\" toml:\"CgroupPermissions,omitempty\"`\n}\n\n// DeviceRequest represents a request for device that's sent to device drivers.\ntype DeviceRequest struct {\n\tDriver       string            `json:\"Driver,omitempty\" yaml:\"Driver,omitempty\" toml:\"Driver,omitempty\"`\n\tCount        int               `json:\"Count,omitempty\" yaml:\"Count,omitempty\" toml:\"Count,omitempty\"`\n\tDeviceIDs    []string          `json:\"DeviceIDs,omitempty\" yaml:\"DeviceIDs,omitempty\" toml:\"DeviceIDs,omitempty\"`\n\tCapabilities [][]string        `json:\"Capabilities,omitempty\" yaml:\"Capabilities,omitempty\" toml:\"Capabilities,omitempty\"`\n\tOptions      map[string]string `json:\"Options,omitempty\" yaml:\"Options,omitempty\" toml:\"Options,omitempty\"`\n}\n\n// BlockWeight represents a relative device weight for an individual device inside\n// of a container\ntype BlockWeight struct {\n\tPath   string `json:\"Path,omitempty\"`\n\tWeight string `json:\"Weight,omitempty\"`\n}\n\n// BlockLimit represents a read/write limit in IOPS or Bandwidth for a device\n// inside of a container\ntype BlockLimit struct {\n\tPath string `json:\"Path,omitempty\"`\n\tRate int64  `json:\"Rate,omitempty\"`\n}\n\n// HostConfig contains the container options related to starting a container on\n// a given host\ntype HostConfig struct {\n\tBinds                []string               `json:\"Binds,omitempty\" yaml:\"Binds,omitempty\" toml:\"Binds,omitempty\"`\n\tCapAdd               []string               `json:\"CapAdd,omitempty\" yaml:\"CapAdd,omitempty\" toml:\"CapAdd,omitempty\"`\n\tCapDrop              []string               `json:\"CapDrop,omitempty\" yaml:\"CapDrop,omitempty\" toml:\"CapDrop,omitempty\"`\n\tCapabilities         []string               `json:\"Capabilities,omitempty\" yaml:\"Capabilities,omitempty\" toml:\"Capabilities,omitempty\"` // Mutually exclusive w.r.t. CapAdd and CapDrop API v1.40\n\tGroupAdd             []string               `json:\"GroupAdd,omitempty\" yaml:\"GroupAdd,omitempty\" toml:\"GroupAdd,omitempty\"`\n\tContainerIDFile      string                 `json:\"ContainerIDFile,omitempty\" yaml:\"ContainerIDFile,omitempty\" toml:\"ContainerIDFile,omitempty\"`\n\tLxcConf              []KeyValuePair         `json:\"LxcConf,omitempty\" yaml:\"LxcConf,omitempty\" toml:\"LxcConf,omitempty\"`\n\tPortBindings         map[Port][]PortBinding `json:\"PortBindings,omitempty\" yaml:\"PortBindings,omitempty\" toml:\"PortBindings,omitempty\"`\n\tLinks                []string               `json:\"Links,omitempty\" yaml:\"Links,omitempty\" toml:\"Links,omitempty\"`\n\tDNS                  []string               `json:\"Dns,omitempty\" yaml:\"Dns,omitempty\" toml:\"Dns,omitempty\"` // For Docker API v1.10 and above only\n\tDNSOptions           []string               `json:\"DnsOptions,omitempty\" yaml:\"DnsOptions,omitempty\" toml:\"DnsOptions,omitempty\"`\n\tDNSSearch            []string               `json:\"DnsSearch,omitempty\" yaml:\"DnsSearch,omitempty\" toml:\"DnsSearch,omitempty\"`\n\tExtraHosts           []string               `json:\"ExtraHosts,omitempty\" yaml:\"ExtraHosts,omitempty\" toml:\"ExtraHosts,omitempty\"`\n\tVolumesFrom          []string               `json:\"VolumesFrom,omitempty\" yaml:\"VolumesFrom,omitempty\" toml:\"VolumesFrom,omitempty\"`\n\tUsernsMode           string                 `json:\"UsernsMode,omitempty\" yaml:\"UsernsMode,omitempty\" toml:\"UsernsMode,omitempty\"`\n\tNetworkMode          string                 `json:\"NetworkMode,omitempty\" yaml:\"NetworkMode,omitempty\" toml:\"NetworkMode,omitempty\"`\n\tIpcMode              string                 `json:\"IpcMode,omitempty\" yaml:\"IpcMode,omitempty\" toml:\"IpcMode,omitempty\"`\n\tIsolation            string                 `json:\"Isolation,omitempty\" yaml:\"Isolation,omitempty\" toml:\"Isolation,omitempty\"`       // Windows only\n\tConsoleSize          [2]int                 `json:\"ConsoleSize,omitempty\" yaml:\"ConsoleSize,omitempty\" toml:\"ConsoleSize,omitempty\"` // Windows only height x width\n\tPidMode              string                 `json:\"PidMode,omitempty\" yaml:\"PidMode,omitempty\" toml:\"PidMode,omitempty\"`\n\tUTSMode              string                 `json:\"UTSMode,omitempty\" yaml:\"UTSMode,omitempty\" toml:\"UTSMode,omitempty\"`\n\tRestartPolicy        RestartPolicy          `json:\"RestartPolicy,omitempty\" yaml:\"RestartPolicy,omitempty\" toml:\"RestartPolicy,omitempty\"`\n\tDevices              []Device               `json:\"Devices,omitempty\" yaml:\"Devices,omitempty\" toml:\"Devices,omitempty\"`\n\tDeviceCgroupRules    []string               `json:\"DeviceCgroupRules,omitempty\" yaml:\"DeviceCgroupRules,omitempty\" toml:\"DeviceCgroupRules,omitempty\"`\n\tDeviceRequests       []DeviceRequest        `json:\"DeviceRequests,omitempty\" yaml:\"DeviceRequests,omitempty\" toml:\"DeviceRequests,omitempty\"`\n\tLogConfig            LogConfig              `json:\"LogConfig,omitempty\" yaml:\"LogConfig,omitempty\" toml:\"LogConfig,omitempty\"`\n\tSecurityOpt          []string               `json:\"SecurityOpt,omitempty\" yaml:\"SecurityOpt,omitempty\" toml:\"SecurityOpt,omitempty\"`\n\tCgroupnsMode         string                 `json:\"CgroupnsMode,omitempty\" yaml:\"CgroupnsMode,omitempty\" toml:\"CgroupnsMode,omitempty\"` // v1.40+\n\tCgroup               string                 `json:\"Cgroup,omitempty\" yaml:\"Cgroup,omitempty\" toml:\"Cgroup,omitempty\"`\n\tCgroupParent         string                 `json:\"CgroupParent,omitempty\" yaml:\"CgroupParent,omitempty\" toml:\"CgroupParent,omitempty\"`\n\tMemory               int64                  `json:\"Memory,omitempty\" yaml:\"Memory,omitempty\" toml:\"Memory,omitempty\"`\n\tMemoryReservation    int64                  `json:\"MemoryReservation,omitempty\" yaml:\"MemoryReservation,omitempty\" toml:\"MemoryReservation,omitempty\"`\n\tKernelMemory         int64                  `json:\"KernelMemory,omitempty\" yaml:\"KernelMemory,omitempty\" toml:\"KernelMemory,omitempty\"`\n\tMemorySwap           int64                  `json:\"MemorySwap,omitempty\" yaml:\"MemorySwap,omitempty\" toml:\"MemorySwap,omitempty\"`\n\tCPUShares            int64                  `json:\"CpuShares,omitempty\" yaml:\"CpuShares,omitempty\" toml:\"CpuShares,omitempty\"`\n\tCPUSet               string                 `json:\"Cpuset,omitempty\" yaml:\"Cpuset,omitempty\" toml:\"Cpuset,omitempty\"`\n\tCPUSetCPUs           string                 `json:\"CpusetCpus,omitempty\" yaml:\"CpusetCpus,omitempty\" toml:\"CpusetCpus,omitempty\"`\n\tCPUSetMEMs           string                 `json:\"CpusetMems,omitempty\" yaml:\"CpusetMems,omitempty\" toml:\"CpusetMems,omitempty\"`\n\tCPUQuota             int64                  `json:\"CpuQuota,omitempty\" yaml:\"CpuQuota,omitempty\" toml:\"CpuQuota,omitempty\"`\n\tCPUPeriod            int64                  `json:\"CpuPeriod,omitempty\" yaml:\"CpuPeriod,omitempty\" toml:\"CpuPeriod,omitempty\"`\n\tCPURealtimePeriod    int64                  `json:\"CpuRealtimePeriod,omitempty\" yaml:\"CpuRealtimePeriod,omitempty\" toml:\"CpuRealtimePeriod,omitempty\"`\n\tCPURealtimeRuntime   int64                  `json:\"CpuRealtimeRuntime,omitempty\" yaml:\"CpuRealtimeRuntime,omitempty\" toml:\"CpuRealtimeRuntime,omitempty\"`\n\tNanoCPUs             int64                  `json:\"NanoCpus,omitempty\" yaml:\"NanoCpus,omitempty\" toml:\"NanoCpus,omitempty\"`\n\tBlkioWeight          int64                  `json:\"BlkioWeight,omitempty\" yaml:\"BlkioWeight,omitempty\" toml:\"BlkioWeight,omitempty\"`\n\tBlkioWeightDevice    []BlockWeight          `json:\"BlkioWeightDevice,omitempty\" yaml:\"BlkioWeightDevice,omitempty\" toml:\"BlkioWeightDevice,omitempty\"`\n\tBlkioDeviceReadBps   []BlockLimit           `json:\"BlkioDeviceReadBps,omitempty\" yaml:\"BlkioDeviceReadBps,omitempty\" toml:\"BlkioDeviceReadBps,omitempty\"`\n\tBlkioDeviceReadIOps  []BlockLimit           `json:\"BlkioDeviceReadIOps,omitempty\" yaml:\"BlkioDeviceReadIOps,omitempty\" toml:\"BlkioDeviceReadIOps,omitempty\"`\n\tBlkioDeviceWriteBps  []BlockLimit           `json:\"BlkioDeviceWriteBps,omitempty\" yaml:\"BlkioDeviceWriteBps,omitempty\" toml:\"BlkioDeviceWriteBps,omitempty\"`\n\tBlkioDeviceWriteIOps []BlockLimit           `json:\"BlkioDeviceWriteIOps,omitempty\" yaml:\"BlkioDeviceWriteIOps,omitempty\" toml:\"BlkioDeviceWriteIOps,omitempty\"`\n\tUlimits              []ULimit               `json:\"Ulimits,omitempty\" yaml:\"Ulimits,omitempty\" toml:\"Ulimits,omitempty\"`\n\tVolumeDriver         string                 `json:\"VolumeDriver,omitempty\" yaml:\"VolumeDriver,omitempty\" toml:\"VolumeDriver,omitempty\"`\n\tOomScoreAdj          int                    `json:\"OomScoreAdj,omitempty\" yaml:\"OomScoreAdj,omitempty\" toml:\"OomScoreAdj,omitempty\"`\n\tMemorySwappiness     *int64                 `json:\"MemorySwappiness,omitempty\" yaml:\"MemorySwappiness,omitempty\" toml:\"MemorySwappiness,omitempty\"`\n\tPidsLimit            *int64                 `json:\"PidsLimit,omitempty\" yaml:\"PidsLimit,omitempty\" toml:\"PidsLimit,omitempty\"`\n\tOOMKillDisable       *bool                  `json:\"OomKillDisable,omitempty\" yaml:\"OomKillDisable,omitempty\" toml:\"OomKillDisable,omitempty\"`\n\tShmSize              int64                  `json:\"ShmSize,omitempty\" yaml:\"ShmSize,omitempty\" toml:\"ShmSize,omitempty\"`\n\tTmpfs                map[string]string      `json:\"Tmpfs,omitempty\" yaml:\"Tmpfs,omitempty\" toml:\"Tmpfs,omitempty\"`\n\tStorageOpt           map[string]string      `json:\"StorageOpt,omitempty\" yaml:\"StorageOpt,omitempty\" toml:\"StorageOpt,omitempty\"`\n\tSysctls              map[string]string      `json:\"Sysctls,omitempty\" yaml:\"Sysctls,omitempty\" toml:\"Sysctls,omitempty\"`\n\tCPUCount             int64                  `json:\"CpuCount,omitempty\" yaml:\"CpuCount,omitempty\"`\n\tCPUPercent           int64                  `json:\"CpuPercent,omitempty\" yaml:\"CpuPercent,omitempty\"`\n\tIOMaximumBandwidth   int64                  `json:\"IOMaximumBandwidth,omitempty\" yaml:\"IOMaximumBandwidth,omitempty\"`\n\tIOMaximumIOps        int64                  `json:\"IOMaximumIOps,omitempty\" yaml:\"IOMaximumIOps,omitempty\"`\n\tMounts               []HostMount            `json:\"Mounts,omitempty\" yaml:\"Mounts,omitempty\" toml:\"Mounts,omitempty\"`\n\tMaskedPaths          []string               `json:\"MaskedPaths,omitempty\" yaml:\"MaskedPaths,omitempty\" toml:\"MaskedPaths,omitempty\"`\n\tReadonlyPaths        []string               `json:\"ReadonlyPaths,omitempty\" yaml:\"ReadonlyPaths,omitempty\" toml:\"ReadonlyPaths,omitempty\"`\n\tRuntime              string                 `json:\"Runtime,omitempty\" yaml:\"Runtime,omitempty\" toml:\"Runtime,omitempty\"`\n\tInit                 bool                   `json:\",omitempty\" yaml:\",omitempty\"`\n\tPrivileged           bool                   `json:\"Privileged,omitempty\" yaml:\"Privileged,omitempty\" toml:\"Privileged,omitempty\"`\n\tPublishAllPorts      bool                   `json:\"PublishAllPorts,omitempty\" yaml:\"PublishAllPorts,omitempty\" toml:\"PublishAllPorts,omitempty\"`\n\tReadonlyRootfs       bool                   `json:\"ReadonlyRootfs,omitempty\" yaml:\"ReadonlyRootfs,omitempty\" toml:\"ReadonlyRootfs,omitempty\"`\n\tAutoRemove           bool                   `json:\"AutoRemove,omitempty\" yaml:\"AutoRemove,omitempty\" toml:\"AutoRemove,omitempty\"`\n}\n\n// NetworkingConfig represents the container's networking configuration for each of its interfaces\n// Carries the networking configs specified in the `docker run` and `docker network connect` commands\ntype NetworkingConfig struct {\n\tEndpointsConfig map[string]*EndpointConfig `json:\"EndpointsConfig\" yaml:\"EndpointsConfig\" toml:\"EndpointsConfig\"` // Endpoint configs for each connecting network\n}\n\n// NoSuchContainer is the error returned when a given container does not exist.\ntype NoSuchContainer struct {\n\tID  string\n\tErr error\n}\n\nfunc (err *NoSuchContainer) Error() string {\n\tif err.Err != nil {\n\t\treturn err.Err.Error()\n\t}\n\treturn \"No such container: \" + err.ID\n}\n\n// ContainerAlreadyRunning is the error returned when a given container is\n// already running.\ntype ContainerAlreadyRunning struct {\n\tID string\n}\n\nfunc (err *ContainerAlreadyRunning) Error() string {\n\treturn \"Container already running: \" + err.ID\n}\n\n// ContainerNotRunning is the error returned when a given container is not\n// running.\ntype ContainerNotRunning struct {\n\tID string\n}\n\nfunc (err *ContainerNotRunning) Error() string {\n\treturn \"Container not running: \" + err.ID\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_archive.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// UploadToContainerOptions is the set of options that can be used when\n// uploading an archive into a container.\n//\n// See https://goo.gl/g25o7u for more details.\ntype UploadToContainerOptions struct {\n\tInputStream          io.Reader `json:\"-\" qs:\"-\"`\n\tPath                 string    `qs:\"path\"`\n\tNoOverwriteDirNonDir bool      `qs:\"noOverwriteDirNonDir\"`\n\tContext              context.Context\n}\n\n// UploadToContainer uploads a tar archive to be extracted to a path in the\n// filesystem of the container.\n//\n// See https://goo.gl/g25o7u for more details.\nfunc (c *Client) UploadToContainer(id string, opts UploadToContainerOptions) error {\n\turl := fmt.Sprintf(\"/containers/%s/archive?\", id) + queryString(opts)\n\n\treturn c.stream(http.MethodPut, url, streamOptions{\n\t\tin:      opts.InputStream,\n\t\tcontext: opts.Context,\n\t})\n}\n\n// DownloadFromContainerOptions is the set of options that can be used when\n// downloading resources from a container.\n//\n// See https://goo.gl/W49jxK for more details.\ntype DownloadFromContainerOptions struct {\n\tOutputStream      io.Writer     `json:\"-\" qs:\"-\"`\n\tPath              string        `qs:\"path\"`\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tContext           context.Context\n}\n\n// DownloadFromContainer downloads a tar archive of files or folders in a container.\n//\n// See https://goo.gl/W49jxK for more details.\nfunc (c *Client) DownloadFromContainer(id string, opts DownloadFromContainerOptions) error {\n\turl := fmt.Sprintf(\"/containers/%s/archive?\", id) + queryString(opts)\n\n\treturn c.stream(http.MethodGet, url, streamOptions{\n\t\tsetRawTerminal:    true,\n\t\tstdout:            opts.OutputStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\tcontext:           opts.Context,\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_attach.go",
    "content": "package docker\n\nimport (\n\t\"io\"\n\t\"net/http\"\n)\n\n// AttachToContainerOptions is the set of options that can be used when\n// attaching to a container.\n//\n// See https://goo.gl/JF10Zk for more details.\ntype AttachToContainerOptions struct {\n\tContainer    string    `qs:\"-\"`\n\tInputStream  io.Reader `qs:\"-\"`\n\tOutputStream io.Writer `qs:\"-\"`\n\tErrorStream  io.Writer `qs:\"-\"`\n\n\t// If set, after a successful connect, a sentinel will be sent and then the\n\t// client will block on receive before continuing.\n\t//\n\t// It must be an unbuffered channel. Using a buffered channel can lead\n\t// to unexpected behavior.\n\tSuccess chan struct{}\n\n\t// Override the key sequence for detaching a container.\n\tDetachKeys string\n\n\t// Use raw terminal? Usually true when the container contains a TTY.\n\tRawTerminal bool `qs:\"-\"`\n\n\t// Get container logs, sending it to OutputStream.\n\tLogs bool\n\n\t// Stream the response?\n\tStream bool\n\n\t// Attach to stdin, and use InputStream.\n\tStdin bool\n\n\t// Attach to stdout, and use OutputStream.\n\tStdout bool\n\n\t// Attach to stderr, and use ErrorStream.\n\tStderr bool\n}\n\n// AttachToContainer attaches to a container, using the given options.\n//\n// See https://goo.gl/JF10Zk for more details.\nfunc (c *Client) AttachToContainer(opts AttachToContainerOptions) error {\n\tcw, err := c.AttachToContainerNonBlocking(opts)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn cw.Wait()\n}\n\n// AttachToContainerNonBlocking attaches to a container, using the given options.\n// This function does not block.\n//\n// See https://goo.gl/NKpkFk for more details.\nfunc (c *Client) AttachToContainerNonBlocking(opts AttachToContainerOptions) (CloseWaiter, error) {\n\tif opts.Container == \"\" {\n\t\treturn nil, &NoSuchContainer{ID: opts.Container}\n\t}\n\tpath := \"/containers/\" + opts.Container + \"/attach?\" + queryString(opts)\n\treturn c.hijack(http.MethodPost, path, hijackOptions{\n\t\tsuccess:        opts.Success,\n\t\tsetRawTerminal: opts.RawTerminal,\n\t\tin:             opts.InputStream,\n\t\tstdout:         opts.OutputStream,\n\t\tstderr:         opts.ErrorStream,\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_changes.go",
    "content": "package docker\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n)\n\n// ContainerChanges returns changes in the filesystem of the given container.\n//\n// See https://goo.gl/15KKzh for more details.\nfunc (c *Client) ContainerChanges(id string) ([]Change, error) {\n\tpath := \"/containers/\" + id + \"/changes\"\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchContainer{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar changes []Change\n\tif err := json.NewDecoder(resp.Body).Decode(&changes); err != nil {\n\t\treturn nil, err\n\t}\n\treturn changes, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_commit.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n)\n\n// CommitContainerOptions aggregates parameters to the CommitContainer method.\n//\n// See https://goo.gl/CzIguf for more details.\ntype CommitContainerOptions struct {\n\tContainer  string\n\tRepository string `qs:\"repo\"`\n\tTag        string\n\tMessage    string `qs:\"comment\"`\n\tAuthor     string\n\tChanges    []string `qs:\"changes\"`\n\tRun        *Config  `qs:\"-\"`\n\tContext    context.Context\n}\n\n// CommitContainer creates a new image from a container's changes.\n//\n// See https://goo.gl/CzIguf for more details.\nfunc (c *Client) CommitContainer(opts CommitContainerOptions) (*Image, error) {\n\tpath := \"/commit?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tdata:    opts.Run,\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchContainer{ID: opts.Container}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar image Image\n\tif err := json.NewDecoder(resp.Body).Decode(&image); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &image, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_copy.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n)\n\n// CopyFromContainerOptions contains the set of options used for copying\n// files from a container.\n//\n// Deprecated: Use DownloadFromContainerOptions and DownloadFromContainer instead.\ntype CopyFromContainerOptions struct {\n\tOutputStream io.Writer `json:\"-\"`\n\tContainer    string    `json:\"-\"`\n\tResource     string\n\tContext      context.Context `json:\"-\"`\n}\n\n// CopyFromContainer copies files from a container.\n//\n// Deprecated: Use DownloadFromContainer and DownloadFromContainer instead.\nfunc (c *Client) CopyFromContainer(opts CopyFromContainerOptions) error {\n\tif opts.Container == \"\" {\n\t\treturn &NoSuchContainer{ID: opts.Container}\n\t}\n\tif c.serverAPIVersion == nil {\n\t\tc.checkAPIVersion()\n\t}\n\tif c.serverAPIVersion != nil && c.serverAPIVersion.GreaterThanOrEqualTo(apiVersion124) {\n\t\treturn errors.New(\"go-dockerclient: CopyFromContainer is no longer available in Docker >= 1.12, use DownloadFromContainer instead\")\n\t}\n\turl := fmt.Sprintf(\"/containers/%s/copy\", opts.Container)\n\tresp, err := c.do(http.MethodPost, url, doOptions{\n\t\tdata:    opts,\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchContainer{ID: opts.Container}\n\t\t}\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\t_, err = io.Copy(opts.OutputStream, resp.Body)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_create.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\t\"strings\"\n)\n\n// ErrContainerAlreadyExists is the error returned by CreateContainer when the\n// container already exists.\nvar ErrContainerAlreadyExists = errors.New(\"container already exists\")\n\n// CreateContainerOptions specify parameters to the CreateContainer function.\n//\n// See https://goo.gl/tyzwVM for more details.\ntype CreateContainerOptions struct {\n\tName             string\n\tPlatform         string\n\tConfig           *Config           `qs:\"-\"`\n\tHostConfig       *HostConfig       `qs:\"-\"`\n\tNetworkingConfig *NetworkingConfig `qs:\"-\"`\n\tContext          context.Context\n}\n\n// CreateContainer creates a new container, returning the container instance,\n// or an error in case of failure.\n//\n// The returned container instance contains only the container ID. To get more\n// details about the container after creating it, use InspectContainer.\n//\n// See https://goo.gl/tyzwVM for more details.\nfunc (c *Client) CreateContainer(opts CreateContainerOptions) (*Container, error) {\n\tpath := \"/containers/create?\" + queryString(opts)\n\tresp, err := c.do(\n\t\thttp.MethodPost,\n\t\tpath,\n\t\tdoOptions{\n\t\t\tdata: struct {\n\t\t\t\t*Config\n\t\t\t\tHostConfig       *HostConfig       `json:\"HostConfig,omitempty\" yaml:\"HostConfig,omitempty\" toml:\"HostConfig,omitempty\"`\n\t\t\t\tNetworkingConfig *NetworkingConfig `json:\"NetworkingConfig,omitempty\" yaml:\"NetworkingConfig,omitempty\" toml:\"NetworkingConfig,omitempty\"`\n\t\t\t}{\n\t\t\t\topts.Config,\n\t\t\t\topts.HostConfig,\n\t\t\t\topts.NetworkingConfig,\n\t\t\t},\n\t\t\tcontext: opts.Context,\n\t\t},\n\t)\n\n\tvar e *Error\n\tif errors.As(err, &e) {\n\t\tif e.Status == http.StatusNotFound && strings.Contains(e.Message, \"No such image\") {\n\t\t\treturn nil, ErrNoSuchImage\n\t\t}\n\t\tif e.Status == http.StatusConflict {\n\t\t\treturn nil, ErrContainerAlreadyExists\n\t\t}\n\t\t// Workaround for 17.09 bug returning 400 instead of 409.\n\t\t// See https://github.com/moby/moby/issues/35021\n\t\tif e.Status == http.StatusBadRequest && strings.Contains(e.Message, \"Conflict.\") {\n\t\t\treturn nil, ErrContainerAlreadyExists\n\t\t}\n\t}\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar container Container\n\tif err := json.NewDecoder(resp.Body).Decode(&container); err != nil {\n\t\treturn nil, err\n\t}\n\n\tcontainer.Name = opts.Name\n\n\treturn &container, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_export.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// ExportContainerOptions is the set of parameters to the ExportContainer\n// method.\n//\n// See https://goo.gl/yGJCIh for more details.\ntype ExportContainerOptions struct {\n\tID                string\n\tOutputStream      io.Writer\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tContext           context.Context\n}\n\n// ExportContainer export the contents of container id as tar archive\n// and prints the exported contents to stdout.\n//\n// See https://goo.gl/yGJCIh for more details.\nfunc (c *Client) ExportContainer(opts ExportContainerOptions) error {\n\tif opts.ID == \"\" {\n\t\treturn &NoSuchContainer{ID: opts.ID}\n\t}\n\turl := fmt.Sprintf(\"/containers/%s/export\", opts.ID)\n\treturn c.stream(http.MethodGet, url, streamOptions{\n\t\tsetRawTerminal:    true,\n\t\tstdout:            opts.OutputStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\tcontext:           opts.Context,\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_inspect.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n)\n\n// InspectContainer returns information about a container by its ID.\n//\n// Deprecated: Use InspectContainerWithOptions instead.\nfunc (c *Client) InspectContainer(id string) (*Container, error) {\n\treturn c.InspectContainerWithOptions(InspectContainerOptions{ID: id})\n}\n\n// InspectContainerWithContext returns information about a container by its ID.\n// The context object can be used to cancel the inspect request.\n//\n// Deprecated: Use InspectContainerWithOptions instead.\nfunc (c *Client) InspectContainerWithContext(id string, ctx context.Context) (*Container, error) {\n\treturn c.InspectContainerWithOptions(InspectContainerOptions{ID: id, Context: ctx})\n}\n\n// InspectContainerWithOptions returns information about a container by its ID.\n//\n// See https://goo.gl/FaI5JT for more details.\nfunc (c *Client) InspectContainerWithOptions(opts InspectContainerOptions) (*Container, error) {\n\tpath := \"/containers/\" + opts.ID + \"/json?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchContainer{ID: opts.ID}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar container Container\n\tif err := json.NewDecoder(resp.Body).Decode(&container); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &container, nil\n}\n\n// InspectContainerOptions specifies parameters for InspectContainerWithOptions.\n//\n// See https://goo.gl/FaI5JT for more details.\ntype InspectContainerOptions struct {\n\tContext context.Context\n\tID      string `qs:\"-\"`\n\tSize    bool\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_kill.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n)\n\n// KillContainerOptions represents the set of options that can be used in a\n// call to KillContainer.\n//\n// See https://goo.gl/JnTxXZ for more details.\ntype KillContainerOptions struct {\n\t// The ID of the container.\n\tID string `qs:\"-\"`\n\n\t// The signal to send to the container. When omitted, Docker server\n\t// will assume SIGKILL.\n\tSignal  Signal\n\tContext context.Context\n}\n\n// KillContainer sends a signal to a container, returning an error in case of\n// failure.\n//\n// See https://goo.gl/JnTxXZ for more details.\nfunc (c *Client) KillContainer(opts KillContainerOptions) error {\n\tpath := \"/containers/\" + opts.ID + \"/kill\" + \"?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif !errors.As(err, &e) {\n\t\t\treturn err\n\t\t}\n\t\tswitch e.Status {\n\t\tcase http.StatusNotFound:\n\t\t\treturn &NoSuchContainer{ID: opts.ID}\n\t\tcase http.StatusConflict:\n\t\t\treturn &ContainerNotRunning{ID: opts.ID}\n\t\tdefault:\n\t\t\treturn err\n\t\t}\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_list.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\n// ListContainersOptions specify parameters to the ListContainers function.\n//\n// See https://goo.gl/kaOHGw for more details.\ntype ListContainersOptions struct {\n\tAll     bool\n\tSize    bool\n\tLimit   int\n\tSince   string\n\tBefore  string\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// ListContainers returns a slice of containers matching the given criteria.\n//\n// See https://goo.gl/kaOHGw for more details.\nfunc (c *Client) ListContainers(opts ListContainersOptions) ([]APIContainers, error) {\n\tpath := \"/containers/json?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar containers []APIContainers\n\tif err := json.NewDecoder(resp.Body).Decode(&containers); err != nil {\n\t\treturn nil, err\n\t}\n\treturn containers, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_logs.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// LogsOptions represents the set of options used when getting logs from a\n// container.\n//\n// See https://goo.gl/krK0ZH for more details.\ntype LogsOptions struct {\n\tContext           context.Context\n\tContainer         string        `qs:\"-\"`\n\tOutputStream      io.Writer     `qs:\"-\"`\n\tErrorStream       io.Writer     `qs:\"-\"`\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tTail              string\n\n\tSince      int64\n\tFollow     bool\n\tStdout     bool\n\tStderr     bool\n\tTimestamps bool\n\n\t// Use raw terminal? Usually true when the container contains a TTY.\n\tRawTerminal bool `qs:\"-\"`\n}\n\n// Logs gets stdout and stderr logs from the specified container.\n//\n// When LogsOptions.RawTerminal is set to false, go-dockerclient will multiplex\n// the streams and send the containers stdout to LogsOptions.OutputStream, and\n// stderr to LogsOptions.ErrorStream.\n//\n// When LogsOptions.RawTerminal is true, callers will get the raw stream on\n// LogsOptions.OutputStream. The caller can use libraries such as dlog\n// (github.com/ahmetalpbalkan/dlog).\n//\n// See https://goo.gl/krK0ZH for more details.\nfunc (c *Client) Logs(opts LogsOptions) error {\n\tif opts.Container == \"\" {\n\t\treturn &NoSuchContainer{ID: opts.Container}\n\t}\n\tif opts.Tail == \"\" {\n\t\topts.Tail = \"all\"\n\t}\n\tpath := \"/containers/\" + opts.Container + \"/logs?\" + queryString(opts)\n\treturn c.stream(http.MethodGet, path, streamOptions{\n\t\tsetRawTerminal:    opts.RawTerminal,\n\t\tstdout:            opts.OutputStream,\n\t\tstderr:            opts.ErrorStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\tcontext:           opts.Context,\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_pause.go",
    "content": "package docker\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// PauseContainer pauses the given container.\n//\n// See https://goo.gl/D1Yaii for more details.\nfunc (c *Client) PauseContainer(id string) error {\n\tpath := fmt.Sprintf(\"/containers/%s/pause\", id)\n\tresp, err := c.do(http.MethodPost, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchContainer{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_prune.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\n// PruneContainersOptions specify parameters to the PruneContainers function.\n//\n// See https://goo.gl/wnkgDT for more details.\ntype PruneContainersOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// PruneContainersResults specify results from the PruneContainers function.\n//\n// See https://goo.gl/wnkgDT for more details.\ntype PruneContainersResults struct {\n\tContainersDeleted []string\n\tSpaceReclaimed    int64\n}\n\n// PruneContainers deletes containers which are stopped.\n//\n// See https://goo.gl/wnkgDT for more details.\nfunc (c *Client) PruneContainers(opts PruneContainersOptions) (*PruneContainersResults, error) {\n\tpath := \"/containers/prune?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar results PruneContainersResults\n\tif err := json.NewDecoder(resp.Body).Decode(&results); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &results, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_remove.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n)\n\n// RemoveContainerOptions encapsulates options to remove a container.\n//\n// See https://goo.gl/hL5IPC for more details.\ntype RemoveContainerOptions struct {\n\t// The ID of the container.\n\tID string `qs:\"-\"`\n\n\t// A flag that indicates whether Docker should remove the volumes\n\t// associated to the container.\n\tRemoveVolumes bool `qs:\"v\"`\n\n\t// A flag that indicates whether Docker should remove the container\n\t// even if it is currently running.\n\tForce   bool\n\tContext context.Context\n}\n\n// RemoveContainer removes a container, returning an error in case of failure.\n//\n// See https://goo.gl/hL5IPC for more details.\nfunc (c *Client) RemoveContainer(opts RemoveContainerOptions) error {\n\tpath := \"/containers/\" + opts.ID + \"?\" + queryString(opts)\n\tresp, err := c.do(http.MethodDelete, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchContainer{ID: opts.ID}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_rename.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// RenameContainerOptions specify parameters to the RenameContainer function.\n//\n// See https://goo.gl/46inai for more details.\ntype RenameContainerOptions struct {\n\t// ID of container to rename\n\tID string `qs:\"-\"`\n\n\t// New name\n\tName    string `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tContext context.Context\n}\n\n// RenameContainer updates and existing containers name\n//\n// See https://goo.gl/46inai for more details.\nfunc (c *Client) RenameContainer(opts RenameContainerOptions) error {\n\tresp, err := c.do(http.MethodPost, fmt.Sprintf(\"/containers/\"+opts.ID+\"/rename?%s\", queryString(opts)), doOptions{\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_resize.go",
    "content": "package docker\n\nimport (\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n)\n\n// ResizeContainerTTY resizes the terminal to the given height and width.\n//\n// See https://goo.gl/FImjeq for more details.\nfunc (c *Client) ResizeContainerTTY(id string, height, width int) error {\n\tparams := make(url.Values)\n\tparams.Set(\"h\", strconv.Itoa(height))\n\tparams.Set(\"w\", strconv.Itoa(width))\n\tresp, err := c.do(http.MethodPost, \"/containers/\"+id+\"/resize?\"+params.Encode(), doOptions{})\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_restart.go",
    "content": "package docker\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// RestartPolicy represents the policy for automatically restarting a container.\n//\n// Possible values are:\n//\n//   - always: the docker daemon will always restart the container\n//   - on-failure: the docker daemon will restart the container on failures, at\n//     most MaximumRetryCount times\n//   - unless-stopped: the docker daemon will always restart the container except\n//     when user has manually stopped the container\n//   - no: the docker daemon will not restart the container automatically\ntype RestartPolicy struct {\n\tName              string `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tMaximumRetryCount int    `json:\"MaximumRetryCount,omitempty\" yaml:\"MaximumRetryCount,omitempty\" toml:\"MaximumRetryCount,omitempty\"`\n}\n\n// AlwaysRestart returns a restart policy that tells the Docker daemon to\n// always restart the container.\nfunc AlwaysRestart() RestartPolicy {\n\treturn RestartPolicy{Name: \"always\"}\n}\n\n// RestartOnFailure returns a restart policy that tells the Docker daemon to\n// restart the container on failures, trying at most maxRetry times.\nfunc RestartOnFailure(maxRetry int) RestartPolicy {\n\treturn RestartPolicy{Name: \"on-failure\", MaximumRetryCount: maxRetry}\n}\n\n// RestartUnlessStopped returns a restart policy that tells the Docker daemon to\n// always restart the container except when user has manually stopped the container.\nfunc RestartUnlessStopped() RestartPolicy {\n\treturn RestartPolicy{Name: \"unless-stopped\"}\n}\n\n// NeverRestart returns a restart policy that tells the Docker daemon to never\n// restart the container on failures.\nfunc NeverRestart() RestartPolicy {\n\treturn RestartPolicy{Name: \"no\"}\n}\n\n// RestartContainer stops a container, killing it after the given timeout (in\n// seconds), during the stop process.\n//\n// See https://goo.gl/MrAKQ5 for more details.\nfunc (c *Client) RestartContainer(id string, timeout uint) error {\n\tpath := fmt.Sprintf(\"/containers/%s/restart?t=%d\", id, timeout)\n\tresp, err := c.do(http.MethodPost, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchContainer{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_start.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n)\n\n// StartContainer starts a container, returning an error in case of failure.\n//\n// Passing the HostConfig to this method has been deprecated in Docker API 1.22\n// (Docker Engine 1.10.x) and totally removed in Docker API 1.24 (Docker Engine\n// 1.12.x). The client will ignore the parameter when communicating with Docker\n// API 1.24 or greater.\n//\n// See https://goo.gl/fbOSZy for more details.\nfunc (c *Client) StartContainer(id string, hostConfig *HostConfig) error {\n\treturn c.startContainer(id, hostConfig, doOptions{})\n}\n\n// StartContainerWithContext starts a container, returning an error in case of\n// failure. The context can be used to cancel the outstanding start container\n// request.\n//\n// Passing the HostConfig to this method has been deprecated in Docker API 1.22\n// (Docker Engine 1.10.x) and totally removed in Docker API 1.24 (Docker Engine\n// 1.12.x). The client will ignore the parameter when communicating with Docker\n// API 1.24 or greater.\n//\n// See https://goo.gl/fbOSZy for more details.\nfunc (c *Client) StartContainerWithContext(id string, hostConfig *HostConfig, ctx context.Context) error {\n\treturn c.startContainer(id, hostConfig, doOptions{context: ctx})\n}\n\nfunc (c *Client) startContainer(id string, hostConfig *HostConfig, opts doOptions) error {\n\tpath := \"/containers/\" + id + \"/start\"\n\tif c.serverAPIVersion == nil {\n\t\tc.checkAPIVersion()\n\t}\n\tif c.serverAPIVersion != nil && c.serverAPIVersion.LessThan(apiVersion124) {\n\t\topts.data = hostConfig\n\t\topts.forceJSON = true\n\t}\n\tresp, err := c.do(http.MethodPost, path, opts)\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchContainer{ID: id, Err: err}\n\t\t}\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode == http.StatusNotModified {\n\t\treturn &ContainerAlreadyRunning{ID: id}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_stats.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// Stats represents container statistics, returned by /containers/<id>/stats.\n//\n// See https://goo.gl/Dk3Xio for more details.\ntype Stats struct {\n\tRead      time.Time `json:\"read,omitempty\" yaml:\"read,omitempty\" toml:\"read,omitempty\"`\n\tPreRead   time.Time `json:\"preread,omitempty\" yaml:\"preread,omitempty\" toml:\"preread,omitempty\"`\n\tNumProcs  uint32    `json:\"num_procs\" yaml:\"num_procs\" toml:\"num_procs\"`\n\tPidsStats struct {\n\t\tCurrent uint64 `json:\"current,omitempty\" yaml:\"current,omitempty\"`\n\t} `json:\"pids_stats,omitempty\" yaml:\"pids_stats,omitempty\" toml:\"pids_stats,omitempty\"`\n\tNetwork     NetworkStats            `json:\"network,omitempty\" yaml:\"network,omitempty\" toml:\"network,omitempty\"`\n\tNetworks    map[string]NetworkStats `json:\"networks,omitempty\" yaml:\"networks,omitempty\" toml:\"networks,omitempty\"`\n\tMemoryStats struct {\n\t\tStats struct {\n\t\t\tTotalPgmafault          uint64 `json:\"total_pgmafault,omitempty\" yaml:\"total_pgmafault,omitempty\" toml:\"total_pgmafault,omitempty\"`\n\t\t\tCache                   uint64 `json:\"cache,omitempty\" yaml:\"cache,omitempty\" toml:\"cache,omitempty\"`\n\t\t\tMappedFile              uint64 `json:\"mapped_file,omitempty\" yaml:\"mapped_file,omitempty\" toml:\"mapped_file,omitempty\"`\n\t\t\tTotalInactiveFile       uint64 `json:\"total_inactive_file,omitempty\" yaml:\"total_inactive_file,omitempty\" toml:\"total_inactive_file,omitempty\"`\n\t\t\tPgpgout                 uint64 `json:\"pgpgout,omitempty\" yaml:\"pgpgout,omitempty\" toml:\"pgpgout,omitempty\"`\n\t\t\tRss                     uint64 `json:\"rss,omitempty\" yaml:\"rss,omitempty\" toml:\"rss,omitempty\"`\n\t\t\tTotalMappedFile         uint64 `json:\"total_mapped_file,omitempty\" yaml:\"total_mapped_file,omitempty\" toml:\"total_mapped_file,omitempty\"`\n\t\t\tWriteback               uint64 `json:\"writeback,omitempty\" yaml:\"writeback,omitempty\" toml:\"writeback,omitempty\"`\n\t\t\tUnevictable             uint64 `json:\"unevictable,omitempty\" yaml:\"unevictable,omitempty\" toml:\"unevictable,omitempty\"`\n\t\t\tPgpgin                  uint64 `json:\"pgpgin,omitempty\" yaml:\"pgpgin,omitempty\" toml:\"pgpgin,omitempty\"`\n\t\t\tTotalUnevictable        uint64 `json:\"total_unevictable,omitempty\" yaml:\"total_unevictable,omitempty\" toml:\"total_unevictable,omitempty\"`\n\t\t\tPgmajfault              uint64 `json:\"pgmajfault,omitempty\" yaml:\"pgmajfault,omitempty\" toml:\"pgmajfault,omitempty\"`\n\t\t\tTotalRss                uint64 `json:\"total_rss,omitempty\" yaml:\"total_rss,omitempty\" toml:\"total_rss,omitempty\"`\n\t\t\tTotalRssHuge            uint64 `json:\"total_rss_huge,omitempty\" yaml:\"total_rss_huge,omitempty\" toml:\"total_rss_huge,omitempty\"`\n\t\t\tTotalWriteback          uint64 `json:\"total_writeback,omitempty\" yaml:\"total_writeback,omitempty\" toml:\"total_writeback,omitempty\"`\n\t\t\tTotalInactiveAnon       uint64 `json:\"total_inactive_anon,omitempty\" yaml:\"total_inactive_anon,omitempty\" toml:\"total_inactive_anon,omitempty\"`\n\t\t\tRssHuge                 uint64 `json:\"rss_huge,omitempty\" yaml:\"rss_huge,omitempty\" toml:\"rss_huge,omitempty\"`\n\t\t\tHierarchicalMemoryLimit uint64 `json:\"hierarchical_memory_limit,omitempty\" yaml:\"hierarchical_memory_limit,omitempty\" toml:\"hierarchical_memory_limit,omitempty\"`\n\t\t\tTotalPgfault            uint64 `json:\"total_pgfault,omitempty\" yaml:\"total_pgfault,omitempty\" toml:\"total_pgfault,omitempty\"`\n\t\t\tTotalActiveFile         uint64 `json:\"total_active_file,omitempty\" yaml:\"total_active_file,omitempty\" toml:\"total_active_file,omitempty\"`\n\t\t\tActiveAnon              uint64 `json:\"active_anon,omitempty\" yaml:\"active_anon,omitempty\" toml:\"active_anon,omitempty\"`\n\t\t\tTotalActiveAnon         uint64 `json:\"total_active_anon,omitempty\" yaml:\"total_active_anon,omitempty\" toml:\"total_active_anon,omitempty\"`\n\t\t\tTotalPgpgout            uint64 `json:\"total_pgpgout,omitempty\" yaml:\"total_pgpgout,omitempty\" toml:\"total_pgpgout,omitempty\"`\n\t\t\tTotalCache              uint64 `json:\"total_cache,omitempty\" yaml:\"total_cache,omitempty\" toml:\"total_cache,omitempty\"`\n\t\t\tInactiveAnon            uint64 `json:\"inactive_anon,omitempty\" yaml:\"inactive_anon,omitempty\" toml:\"inactive_anon,omitempty\"`\n\t\t\tActiveFile              uint64 `json:\"active_file,omitempty\" yaml:\"active_file,omitempty\" toml:\"active_file,omitempty\"`\n\t\t\tPgfault                 uint64 `json:\"pgfault,omitempty\" yaml:\"pgfault,omitempty\" toml:\"pgfault,omitempty\"`\n\t\t\tInactiveFile            uint64 `json:\"inactive_file,omitempty\" yaml:\"inactive_file,omitempty\" toml:\"inactive_file,omitempty\"`\n\t\t\tTotalPgpgin             uint64 `json:\"total_pgpgin,omitempty\" yaml:\"total_pgpgin,omitempty\" toml:\"total_pgpgin,omitempty\"`\n\t\t\tHierarchicalMemswLimit  uint64 `json:\"hierarchical_memsw_limit,omitempty\" yaml:\"hierarchical_memsw_limit,omitempty\" toml:\"hierarchical_memsw_limit,omitempty\"`\n\t\t\tSwap                    uint64 `json:\"swap,omitempty\" yaml:\"swap,omitempty\" toml:\"swap,omitempty\"`\n\t\t\tAnon                    uint64 `json:\"anon,omitempty\" yaml:\"anon,omitempty\" toml:\"anon,omitempty\"`\n\t\t\tAnonThp                 uint64 `json:\"anon_thp,omitempty\" yaml:\"anon_thp,omitempty\" toml:\"anon_thp,omitempty\"`\n\t\t\tFile                    uint64 `json:\"file,omitempty\" yaml:\"file,omitempty\" toml:\"file,omitempty\"`\n\t\t\tFileDirty               uint64 `json:\"file_dirty,omitempty\" yaml:\"file_dirty,omitempty\" toml:\"file_dirty,omitempty\"`\n\t\t\tFileMapped              uint64 `json:\"file_mapped,omitempty\" yaml:\"file_mapped,omitempty\" toml:\"file_mapped,omitempty\"`\n\t\t\tFileWriteback           uint64 `json:\"file_writeback,omitempty\" yaml:\"file_writeback,omitempty\" toml:\"file_writeback,omitempty\"`\n\t\t\tKernelStack             uint64 `json:\"kernel_stack,omitempty\" yaml:\"kernel_stack,omitempty\" toml:\"kernel_stack,omitempty\"`\n\t\t\tPgactivate              uint64 `json:\"pgactivate,omitempty\" yaml:\"pgactivate,omitempty\" toml:\"pgactivate,omitempty\"`\n\t\t\tPgdeactivate            uint64 `json:\"pgdeactivate,omitempty\" yaml:\"pgdeactivate,omitempty\" toml:\"pgdeactivate,omitempty\"`\n\t\t\tPglazyfree              uint64 `json:\"pglazyfree,omitempty\" yaml:\"pglazyfree,omitempty\" toml:\"pglazyfree,omitempty\"`\n\t\t\tPglazyfreed             uint64 `json:\"pglazyfreed,omitempty\" yaml:\"pglazyfreed,omitempty\" toml:\"pglazyfreed,omitempty\"`\n\t\t\tPgrefill                uint64 `json:\"pgrefill,omitempty\" yaml:\"pgrefill,omitempty\" toml:\"pgrefill,omitempty\"`\n\t\t\tPgscan                  uint64 `json:\"pgscan,omitempty\" yaml:\"pgscan,omitempty\" toml:\"pgscan,omitempty\"`\n\t\t\tPgsteal                 uint64 `json:\"pgsteal,omitempty\" yaml:\"pgsteal,omitempty\" toml:\"pgsteal,omitempty\"`\n\t\t\tShmem                   uint64 `json:\"shmem,omitempty\" yaml:\"shmem,omitempty\" toml:\"shmem,omitempty\"`\n\t\t\tSlab                    uint64 `json:\"slab,omitempty\" yaml:\"slab,omitempty\" toml:\"slab,omitempty\"`\n\t\t\tSlabReclaimable         uint64 `json:\"slab_reclaimable,omitempty\" yaml:\"slab_reclaimable,omitempty\" toml:\"slab_reclaimable,omitempty\"`\n\t\t\tSlabUnreclaimable       uint64 `json:\"slab_unreclaimable,omitempty\" yaml:\"slab_unreclaimable,omitempty\" toml:\"slab_unreclaimable,omitempty\"`\n\t\t\tSock                    uint64 `json:\"sock,omitempty\" yaml:\"sock,omitempty\" toml:\"sock,omitempty\"`\n\t\t\tThpCollapseAlloc        uint64 `json:\"thp_collapse_alloc,omitempty\" yaml:\"thp_collapse_alloc,omitempty\" toml:\"thp_collapse_alloc,omitempty\"`\n\t\t\tThpFaultAlloc           uint64 `json:\"thp_fault_alloc,omitempty\" yaml:\"thp_fault_alloc,omitempty\" toml:\"thp_fault_alloc,omitempty\"`\n\t\t\tWorkingsetActivate      uint64 `json:\"workingset_activate,omitempty\" yaml:\"workingset_activate,omitempty\" toml:\"workingset_activate,omitempty\"`\n\t\t\tWorkingsetNodereclaim   uint64 `json:\"workingset_nodereclaim,omitempty\" yaml:\"workingset_nodereclaim,omitempty\" toml:\"workingset_nodereclaim,omitempty\"`\n\t\t\tWorkingsetRefault       uint64 `json:\"workingset_refault,omitempty\" yaml:\"workingset_refault,omitempty\" toml:\"workingset_refault,omitempty\"`\n\t\t} `json:\"stats,omitempty\" yaml:\"stats,omitempty\" toml:\"stats,omitempty\"`\n\t\tMaxUsage          uint64 `json:\"max_usage,omitempty\" yaml:\"max_usage,omitempty\" toml:\"max_usage,omitempty\"`\n\t\tUsage             uint64 `json:\"usage,omitempty\" yaml:\"usage,omitempty\" toml:\"usage,omitempty\"`\n\t\tFailcnt           uint64 `json:\"failcnt,omitempty\" yaml:\"failcnt,omitempty\" toml:\"failcnt,omitempty\"`\n\t\tLimit             uint64 `json:\"limit,omitempty\" yaml:\"limit,omitempty\" toml:\"limit,omitempty\"`\n\t\tCommit            uint64 `json:\"commitbytes,omitempty\" yaml:\"commitbytes,omitempty\" toml:\"privateworkingset,omitempty\"`\n\t\tCommitPeak        uint64 `json:\"commitpeakbytes,omitempty\" yaml:\"commitpeakbytes,omitempty\" toml:\"commitpeakbytes,omitempty\"`\n\t\tPrivateWorkingSet uint64 `json:\"privateworkingset,omitempty\" yaml:\"privateworkingset,omitempty\" toml:\"privateworkingset,omitempty\"`\n\t} `json:\"memory_stats,omitempty\" yaml:\"memory_stats,omitempty\" toml:\"memory_stats,omitempty\"`\n\tBlkioStats struct {\n\t\tIOServiceBytesRecursive []BlkioStatsEntry `json:\"io_service_bytes_recursive,omitempty\" yaml:\"io_service_bytes_recursive,omitempty\" toml:\"io_service_bytes_recursive,omitempty\"`\n\t\tIOServicedRecursive     []BlkioStatsEntry `json:\"io_serviced_recursive,omitempty\" yaml:\"io_serviced_recursive,omitempty\" toml:\"io_serviced_recursive,omitempty\"`\n\t\tIOQueueRecursive        []BlkioStatsEntry `json:\"io_queue_recursive,omitempty\" yaml:\"io_queue_recursive,omitempty\" toml:\"io_queue_recursive,omitempty\"`\n\t\tIOServiceTimeRecursive  []BlkioStatsEntry `json:\"io_service_time_recursive,omitempty\" yaml:\"io_service_time_recursive,omitempty\" toml:\"io_service_time_recursive,omitempty\"`\n\t\tIOWaitTimeRecursive     []BlkioStatsEntry `json:\"io_wait_time_recursive,omitempty\" yaml:\"io_wait_time_recursive,omitempty\" toml:\"io_wait_time_recursive,omitempty\"`\n\t\tIOMergedRecursive       []BlkioStatsEntry `json:\"io_merged_recursive,omitempty\" yaml:\"io_merged_recursive,omitempty\" toml:\"io_merged_recursive,omitempty\"`\n\t\tIOTimeRecursive         []BlkioStatsEntry `json:\"io_time_recursive,omitempty\" yaml:\"io_time_recursive,omitempty\" toml:\"io_time_recursive,omitempty\"`\n\t\tSectorsRecursive        []BlkioStatsEntry `json:\"sectors_recursive,omitempty\" yaml:\"sectors_recursive,omitempty\" toml:\"sectors_recursive,omitempty\"`\n\t} `json:\"blkio_stats,omitempty\" yaml:\"blkio_stats,omitempty\" toml:\"blkio_stats,omitempty\"`\n\tCPUStats     CPUStats `json:\"cpu_stats,omitempty\" yaml:\"cpu_stats,omitempty\" toml:\"cpu_stats,omitempty\"`\n\tPreCPUStats  CPUStats `json:\"precpu_stats,omitempty\"`\n\tStorageStats struct {\n\t\tReadCountNormalized  uint64 `json:\"read_count_normalized,omitempty\" yaml:\"read_count_normalized,omitempty\" toml:\"read_count_normalized,omitempty\"`\n\t\tReadSizeBytes        uint64 `json:\"read_size_bytes,omitempty\" yaml:\"read_size_bytes,omitempty\" toml:\"read_size_bytes,omitempty\"`\n\t\tWriteCountNormalized uint64 `json:\"write_count_normalized,omitempty\" yaml:\"write_count_normalized,omitempty\" toml:\"write_count_normalized,omitempty\"`\n\t\tWriteSizeBytes       uint64 `json:\"write_size_bytes,omitempty\" yaml:\"write_size_bytes,omitempty\" toml:\"write_size_bytes,omitempty\"`\n\t} `json:\"storage_stats,omitempty\" yaml:\"storage_stats,omitempty\" toml:\"storage_stats,omitempty\"`\n}\n\n// NetworkStats is a stats entry for network stats\ntype NetworkStats struct {\n\tRxDropped uint64 `json:\"rx_dropped,omitempty\" yaml:\"rx_dropped,omitempty\" toml:\"rx_dropped,omitempty\"`\n\tRxBytes   uint64 `json:\"rx_bytes,omitempty\" yaml:\"rx_bytes,omitempty\" toml:\"rx_bytes,omitempty\"`\n\tRxErrors  uint64 `json:\"rx_errors,omitempty\" yaml:\"rx_errors,omitempty\" toml:\"rx_errors,omitempty\"`\n\tTxPackets uint64 `json:\"tx_packets,omitempty\" yaml:\"tx_packets,omitempty\" toml:\"tx_packets,omitempty\"`\n\tTxDropped uint64 `json:\"tx_dropped,omitempty\" yaml:\"tx_dropped,omitempty\" toml:\"tx_dropped,omitempty\"`\n\tRxPackets uint64 `json:\"rx_packets,omitempty\" yaml:\"rx_packets,omitempty\" toml:\"rx_packets,omitempty\"`\n\tTxErrors  uint64 `json:\"tx_errors,omitempty\" yaml:\"tx_errors,omitempty\" toml:\"tx_errors,omitempty\"`\n\tTxBytes   uint64 `json:\"tx_bytes,omitempty\" yaml:\"tx_bytes,omitempty\" toml:\"tx_bytes,omitempty\"`\n}\n\n// CPUStats is a stats entry for cpu stats\ntype CPUStats struct {\n\tCPUUsage struct {\n\t\tPercpuUsage       []uint64 `json:\"percpu_usage,omitempty\" yaml:\"percpu_usage,omitempty\" toml:\"percpu_usage,omitempty\"`\n\t\tUsageInUsermode   uint64   `json:\"usage_in_usermode,omitempty\" yaml:\"usage_in_usermode,omitempty\" toml:\"usage_in_usermode,omitempty\"`\n\t\tTotalUsage        uint64   `json:\"total_usage,omitempty\" yaml:\"total_usage,omitempty\" toml:\"total_usage,omitempty\"`\n\t\tUsageInKernelmode uint64   `json:\"usage_in_kernelmode,omitempty\" yaml:\"usage_in_kernelmode,omitempty\" toml:\"usage_in_kernelmode,omitempty\"`\n\t} `json:\"cpu_usage,omitempty\" yaml:\"cpu_usage,omitempty\" toml:\"cpu_usage,omitempty\"`\n\tSystemCPUUsage uint64 `json:\"system_cpu_usage,omitempty\" yaml:\"system_cpu_usage,omitempty\" toml:\"system_cpu_usage,omitempty\"`\n\tOnlineCPUs     uint64 `json:\"online_cpus,omitempty\" yaml:\"online_cpus,omitempty\" toml:\"online_cpus,omitempty\"`\n\tThrottlingData struct {\n\t\tPeriods          uint64 `json:\"periods,omitempty\"`\n\t\tThrottledPeriods uint64 `json:\"throttled_periods,omitempty\"`\n\t\tThrottledTime    uint64 `json:\"throttled_time,omitempty\"`\n\t} `json:\"throttling_data,omitempty\" yaml:\"throttling_data,omitempty\" toml:\"throttling_data,omitempty\"`\n}\n\n// BlkioStatsEntry is a stats entry for blkio_stats\ntype BlkioStatsEntry struct {\n\tMajor uint64 `json:\"major,omitempty\" yaml:\"major,omitempty\" toml:\"major,omitempty\"`\n\tMinor uint64 `json:\"minor,omitempty\" yaml:\"minor,omitempty\" toml:\"minor,omitempty\"`\n\tOp    string `json:\"op,omitempty\" yaml:\"op,omitempty\" toml:\"op,omitempty\"`\n\tValue uint64 `json:\"value,omitempty\" yaml:\"value,omitempty\" toml:\"value,omitempty\"`\n}\n\n// StatsOptions specify parameters to the Stats function.\n//\n// See https://goo.gl/Dk3Xio for more details.\ntype StatsOptions struct {\n\tID     string\n\tStats  chan<- *Stats\n\tStream bool\n\t// A flag that enables stopping the stats operation\n\tDone <-chan bool\n\t// Initial connection timeout\n\tTimeout time.Duration\n\t// Timeout with no data is received, it's reset every time new data\n\t// arrives\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tContext           context.Context\n}\n\n// Stats sends container statistics for the given container to the given channel.\n//\n// This function is blocking, similar to a streaming call for logs, and should be run\n// on a separate goroutine from the caller. Note that this function will block until\n// the given container is removed, not just exited. When finished, this function\n// will close the given channel. Alternatively, function can be stopped by\n// signaling on the Done channel.\n//\n// See https://goo.gl/Dk3Xio for more details.\nfunc (c *Client) Stats(opts StatsOptions) (retErr error) {\n\terrC := make(chan error, 1)\n\treadCloser, writeCloser := io.Pipe()\n\n\tdefer func() {\n\t\tclose(opts.Stats)\n\n\t\tif err := <-errC; err != nil && retErr == nil {\n\t\t\tretErr = err\n\t\t}\n\n\t\tif err := readCloser.Close(); err != nil && retErr == nil {\n\t\t\tretErr = err\n\t\t}\n\t}()\n\n\treqSent := make(chan struct{})\n\tgo func() {\n\t\tdefer close(errC)\n\t\terr := c.stream(http.MethodGet, fmt.Sprintf(\"/containers/%s/stats?stream=%v\", opts.ID, opts.Stream), streamOptions{\n\t\t\trawJSONStream:     true,\n\t\t\tuseJSONDecoder:    true,\n\t\t\tstdout:            writeCloser,\n\t\t\ttimeout:           opts.Timeout,\n\t\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\t\tcontext:           opts.Context,\n\t\t\treqSent:           reqSent,\n\t\t})\n\t\tif err != nil {\n\t\t\tvar dockerError *Error\n\t\t\tif errors.As(err, &dockerError) {\n\t\t\t\tif dockerError.Status == http.StatusNotFound {\n\t\t\t\t\terr = &NoSuchContainer{ID: opts.ID}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif closeErr := writeCloser.Close(); closeErr != nil && err == nil {\n\t\t\terr = closeErr\n\t\t}\n\t\terrC <- err\n\t}()\n\n\tquit := make(chan struct{})\n\tdefer close(quit)\n\tgo func() {\n\t\t// block here waiting for the signal to stop function\n\t\tselect {\n\t\tcase <-opts.Done:\n\t\t\treadCloser.Close()\n\t\tcase <-quit:\n\t\t\treturn\n\t\t}\n\t}()\n\n\tdecoder := json.NewDecoder(readCloser)\n\tstats := new(Stats)\n\t<-reqSent\n\tfor err := decoder.Decode(stats); !errors.Is(err, io.EOF); err = decoder.Decode(stats) {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\topts.Stats <- stats\n\t\tstats = new(Stats)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_stop.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// StopContainer stops a container, killing it after the given timeout (in\n// seconds).\n//\n// See https://goo.gl/R9dZcV for more details.\nfunc (c *Client) StopContainer(id string, timeout uint) error {\n\treturn c.stopContainer(id, timeout, doOptions{})\n}\n\n// StopContainerWithContext stops a container, killing it after the given\n// timeout (in seconds). The context can be used to cancel the stop\n// container request.\n//\n// See https://goo.gl/R9dZcV for more details.\nfunc (c *Client) StopContainerWithContext(id string, timeout uint, ctx context.Context) error {\n\treturn c.stopContainer(id, timeout, doOptions{context: ctx})\n}\n\nfunc (c *Client) stopContainer(id string, timeout uint, opts doOptions) error {\n\tpath := fmt.Sprintf(\"/containers/%s/stop?t=%d\", id, timeout)\n\tresp, err := c.do(http.MethodPost, path, opts)\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchContainer{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode == http.StatusNotModified {\n\t\treturn &ContainerNotRunning{ID: id}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_top.go",
    "content": "package docker\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// TopResult represents the list of processes running in a container, as\n// returned by /containers/<id>/top.\n//\n// See https://goo.gl/FLwpPl for more details.\ntype TopResult struct {\n\tTitles    []string\n\tProcesses [][]string\n}\n\n// TopContainer returns processes running inside a container\n//\n// See https://goo.gl/FLwpPl for more details.\nfunc (c *Client) TopContainer(id string, psArgs string) (TopResult, error) {\n\tvar args string\n\tvar result TopResult\n\tif psArgs != \"\" {\n\t\targs = fmt.Sprintf(\"?ps_args=%s\", psArgs)\n\t}\n\tpath := fmt.Sprintf(\"/containers/%s/top%s\", id, args)\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn result, &NoSuchContainer{ID: id}\n\t\t}\n\t\treturn result, err\n\t}\n\tdefer resp.Body.Close()\n\terr = json.NewDecoder(resp.Body).Decode(&result)\n\treturn result, err\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_unpause.go",
    "content": "package docker\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// UnpauseContainer unpauses the given container.\n//\n// See https://goo.gl/sZ2faO for more details.\nfunc (c *Client) UnpauseContainer(id string) error {\n\tpath := fmt.Sprintf(\"/containers/%s/unpause\", id)\n\tresp, err := c.do(http.MethodPost, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchContainer{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_update.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n)\n\n// UpdateContainerOptions specify parameters to the UpdateContainer function.\n//\n// See https://goo.gl/Y6fXUy for more details.\ntype UpdateContainerOptions struct {\n\tBlkioWeight        int           `json:\"BlkioWeight\"`\n\tCPUShares          int           `json:\"CpuShares\"`\n\tCPUPeriod          int           `json:\"CpuPeriod\"`\n\tCPURealtimePeriod  int64         `json:\"CpuRealtimePeriod\"`\n\tCPURealtimeRuntime int64         `json:\"CpuRealtimeRuntime\"`\n\tCPUQuota           int           `json:\"CpuQuota\"`\n\tCpusetCpus         string        `json:\"CpusetCpus\"`\n\tCpusetMems         string        `json:\"CpusetMems\"`\n\tMemory             int           `json:\"Memory\"`\n\tMemorySwap         int           `json:\"MemorySwap\"`\n\tMemoryReservation  int           `json:\"MemoryReservation\"`\n\tKernelMemory       int           `json:\"KernelMemory\"`\n\tRestartPolicy      RestartPolicy `json:\"RestartPolicy,omitempty\"`\n\tContext            context.Context\n}\n\n// UpdateContainer updates the container at ID with the options\n//\n// See https://goo.gl/Y6fXUy for more details.\nfunc (c *Client) UpdateContainer(id string, opts UpdateContainerOptions) error {\n\tresp, err := c.do(http.MethodPost, fmt.Sprintf(\"/containers/\"+id+\"/update\"), doOptions{\n\t\tdata:      opts,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/container_wait.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n)\n\n// WaitContainer blocks until the given container stops, return the exit code\n// of the container status.\n//\n// See https://goo.gl/4AGweZ for more details.\nfunc (c *Client) WaitContainer(id string) (int, error) {\n\treturn c.waitContainer(id, doOptions{})\n}\n\n// WaitContainerWithContext blocks until the given container stops, return the exit code\n// of the container status. The context object can be used to cancel the\n// inspect request.\n//\n// See https://goo.gl/4AGweZ for more details.\nfunc (c *Client) WaitContainerWithContext(id string, ctx context.Context) (int, error) {\n\treturn c.waitContainer(id, doOptions{context: ctx})\n}\n\nfunc (c *Client) waitContainer(id string, opts doOptions) (int, error) {\n\tresp, err := c.do(http.MethodPost, \"/containers/\"+id+\"/wait\", opts)\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn 0, &NoSuchContainer{ID: id}\n\t\t}\n\t\treturn 0, err\n\t}\n\tdefer resp.Body.Close()\n\tvar r struct{ StatusCode int }\n\tif err := json.NewDecoder(resp.Body).Decode(&r); err != nil {\n\t\treturn 0, err\n\t}\n\treturn r.StatusCode, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/distribution.go",
    "content": "// Copyright 2017 go-dockerclient 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 docker\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n\n\t\"github.com/docker/docker/api/types/registry\"\n)\n\n// InspectDistribution returns image digest and platform information by contacting the registry\nfunc (c *Client) InspectDistribution(name string) (*registry.DistributionInspect, error) {\n\tpath := \"/distribution/\" + name + \"/json\"\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar distributionInspect registry.DistributionInspect\n\tif err := json.NewDecoder(resp.Body).Decode(&distributionInspect); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &distributionInspect, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/env.go",
    "content": "// Copyright 2014 Docker authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the DOCKER-LICENSE file.\n\npackage docker\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Env represents a list of key-pair represented in the form KEY=VALUE.\ntype Env []string\n\n// Get returns the string value of the given key.\nfunc (env *Env) Get(key string) (value string) {\n\treturn env.Map()[key]\n}\n\n// Exists checks whether the given key is defined in the internal Env\n// representation.\nfunc (env *Env) Exists(key string) bool {\n\t_, exists := env.Map()[key]\n\treturn exists\n}\n\n// GetBool returns a boolean representation of the given key. The key is false\n// whenever its value if 0, no, false, none or an empty string. Any other value\n// will be interpreted as true.\nfunc (env *Env) GetBool(key string) (value bool) {\n\ts := strings.ToLower(strings.Trim(env.Get(key), \" \\t\"))\n\tif s == \"\" || s == \"0\" || s == \"no\" || s == \"false\" || s == \"none\" {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// SetBool defines a boolean value to the given key.\nfunc (env *Env) SetBool(key string, value bool) {\n\tif value {\n\t\tenv.Set(key, \"1\")\n\t} else {\n\t\tenv.Set(key, \"0\")\n\t}\n}\n\n// GetInt returns the value of the provided key, converted to int.\n//\n// It the value cannot be represented as an integer, it returns -1.\nfunc (env *Env) GetInt(key string) int {\n\treturn int(env.GetInt64(key))\n}\n\n// SetInt defines an integer value to the given key.\nfunc (env *Env) SetInt(key string, value int) {\n\tenv.Set(key, strconv.Itoa(value))\n}\n\n// GetInt64 returns the value of the provided key, converted to int64.\n//\n// It the value cannot be represented as an integer, it returns -1.\nfunc (env *Env) GetInt64(key string) int64 {\n\ts := strings.Trim(env.Get(key), \" \\t\")\n\tval, err := strconv.ParseInt(s, 10, 64)\n\tif err != nil {\n\t\treturn -1\n\t}\n\treturn val\n}\n\n// SetInt64 defines an integer (64-bit wide) value to the given key.\nfunc (env *Env) SetInt64(key string, value int64) {\n\tenv.Set(key, strconv.FormatInt(value, 10))\n}\n\n// GetJSON unmarshals the value of the provided key in the provided iface.\n//\n// iface is a value that can be provided to the json.Unmarshal function.\nfunc (env *Env) GetJSON(key string, iface any) error {\n\tsval := env.Get(key)\n\tif sval == \"\" {\n\t\treturn nil\n\t}\n\treturn json.Unmarshal([]byte(sval), iface)\n}\n\n// SetJSON marshals the given value to JSON format and stores it using the\n// provided key.\nfunc (env *Env) SetJSON(key string, value any) error {\n\tsval, err := json.Marshal(value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tenv.Set(key, string(sval))\n\treturn nil\n}\n\n// GetList returns a list of strings matching the provided key. It handles the\n// list as a JSON representation of a list of strings.\n//\n// If the given key matches to a single string, it will return a list\n// containing only the value that matches the key.\nfunc (env *Env) GetList(key string) []string {\n\tsval := env.Get(key)\n\tif sval == \"\" {\n\t\treturn nil\n\t}\n\tvar l []string\n\tif err := json.Unmarshal([]byte(sval), &l); err != nil {\n\t\tl = append(l, sval)\n\t}\n\treturn l\n}\n\n// SetList stores the given list in the provided key, after serializing it to\n// JSON format.\nfunc (env *Env) SetList(key string, value []string) error {\n\treturn env.SetJSON(key, value)\n}\n\n// Set defines the value of a key to the given string.\nfunc (env *Env) Set(key, value string) {\n\t*env = append(*env, key+\"=\"+value)\n}\n\n// Decode decodes `src` as a json dictionary, and adds each decoded key-value\n// pair to the environment.\n//\n// If `src` cannot be decoded as a json dictionary, an error is returned.\nfunc (env *Env) Decode(src io.Reader) error {\n\tm := make(map[string]any)\n\tif err := json.NewDecoder(src).Decode(&m); err != nil {\n\t\treturn err\n\t}\n\tfor k, v := range m {\n\t\tenv.SetAuto(k, v)\n\t}\n\treturn nil\n}\n\n// SetAuto will try to define the Set* method to call based on the given value.\nfunc (env *Env) SetAuto(key string, value any) {\n\tif fval, ok := value.(float64); ok {\n\t\tenv.SetInt64(key, int64(fval))\n\t} else if sval, ok := value.(string); ok {\n\t\tenv.Set(key, sval)\n\t} else if val, err := json.Marshal(value); err == nil {\n\t\tenv.Set(key, string(val))\n\t} else {\n\t\tenv.Set(key, fmt.Sprintf(\"%v\", value))\n\t}\n}\n\n// Map returns the map representation of the env.\nfunc (env *Env) Map() map[string]string {\n\tif env == nil || len(*env) == 0 {\n\t\treturn nil\n\t}\n\tm := make(map[string]string)\n\tfor _, kv := range *env {\n\t\tparts := strings.SplitN(kv, \"=\", 2)\n\t\tif len(parts) == 1 {\n\t\t\tm[parts[0]] = \"\"\n\t\t} else {\n\t\t\tm[parts[0]] = parts[1]\n\t\t}\n\t}\n\treturn m\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/event.go",
    "content": "// Copyright 2014 go-dockerclient 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 docker\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"math\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\n// EventsOptions to filter events\n// See https://docs.docker.com/engine/api/v1.41/#operation/SystemEvents for more details.\ntype EventsOptions struct {\n\t// Show events created since this timestamp then stream new events.\n\tSince string\n\n\t// Show events created until this timestamp then stop streaming.\n\tUntil string\n\n\t// Filter for events. For example:\n\t//  map[string][]string{\"type\": {\"container\"}, \"event\": {\"start\", \"die\"}}\n\t// will return events when container was started and stopped or killed\n\t//\n\t// Available filters:\n\t//  config=<string> config name or ID\n\t//  container=<string> container name or ID\n\t//  daemon=<string> daemon name or ID\n\t//  event=<string> event type\n\t//  image=<string> image name or ID\n\t//  label=<string> image or container label\n\t//  network=<string> network name or ID\n\t//  node=<string> node ID\n\t//  plugin= plugin name or ID\n\t//  scope= local or swarm\n\t//  secret=<string> secret name or ID\n\t//  service=<string> service name or ID\n\t//  type=<string> container, image, volume, network, daemon, plugin, node, service, secret or config\n\t//  volume=<string> volume name\n\tFilters map[string][]string\n}\n\n// APIEvents represents events coming from the Docker API\n// The fields in the Docker API changed in API version 1.22, and\n// events for more than images and containers are now fired off.\n// To maintain forward and backward compatibility, go-dockerclient\n// replicates the event in both the new and old format as faithfully as possible.\n//\n// For events that only exist in 1.22 in later, `Status` is filled in as\n// `\"Type:Action\"` instead of just `Action` to allow for older clients to\n// differentiate and not break if they rely on the pre-1.22 Status types.\n//\n// The transformEvent method can be consulted for more information about how\n// events are translated from new/old API formats\ntype APIEvents struct {\n\t// New API Fields in 1.22\n\tAction string   `json:\"action,omitempty\"`\n\tType   string   `json:\"type,omitempty\"`\n\tActor  APIActor `json:\"actor,omitempty\"`\n\n\t// Old API fields for < 1.22\n\tStatus string `json:\"status,omitempty\"`\n\tID     string `json:\"id,omitempty\"`\n\tFrom   string `json:\"from,omitempty\"`\n\n\t// Fields in both\n\tTime     int64 `json:\"time,omitempty\"`\n\tTimeNano int64 `json:\"timeNano,omitempty\"`\n}\n\n// APIActor represents an actor that accomplishes something for an event\ntype APIActor struct {\n\tID         string            `json:\"id,omitempty\"`\n\tAttributes map[string]string `json:\"attributes,omitempty\"`\n}\n\ntype eventMonitoringState struct {\n\t// `sync/atomic` expects the first word in an allocated struct to be 64-bit\n\t// aligned on both ARM and x86-32. See https://goo.gl/zW7dgq for more details.\n\tlastSeen int64\n\tsync.RWMutex\n\tsync.WaitGroup\n\tenabled   bool\n\tC         chan *APIEvents\n\terrC      chan error\n\tlisteners []chan<- *APIEvents\n\tcloseConn func()\n}\n\nconst (\n\tmaxMonitorConnRetries = 5\n\tretryInitialWaitTime  = 10.\n)\n\nvar (\n\t// ErrNoListeners is the error returned when no listeners are available\n\t// to receive an event.\n\tErrNoListeners = errors.New(\"no listeners present to receive event\")\n\n\t// ErrListenerAlreadyExists is the error returned when the listerner already\n\t// exists.\n\tErrListenerAlreadyExists = errors.New(\"listener already exists for docker events\")\n\n\t// ErrTLSNotSupported is the error returned when the client does not support\n\t// TLS (this applies to the Windows named pipe client).\n\tErrTLSNotSupported = errors.New(\"tls not supported by this client\")\n\n\t// EOFEvent is sent when the event listener receives an EOF error.\n\tEOFEvent = &APIEvents{\n\t\tType:   \"EOF\",\n\t\tStatus: \"EOF\",\n\t}\n)\n\n// AddEventListener adds a new listener to container events in the Docker API.\n//\n// The parameter is a channel through which events will be sent.\nfunc (c *Client) AddEventListener(listener chan<- *APIEvents) error {\n\treturn c.AddEventListenerWithOptions(EventsOptions{}, listener)\n}\n\n// AddEventListener adds a new listener to container events in the Docker API.\n// See https://docs.docker.com/engine/api/v1.41/#operation/SystemEvents for more details.\n//\n// The listener parameter is a channel through which events will be sent.\nfunc (c *Client) AddEventListenerWithOptions(options EventsOptions, listener chan<- *APIEvents) error {\n\tvar err error\n\tif !c.eventMonitor.isEnabled() {\n\t\terr = c.eventMonitor.enableEventMonitoring(c, options)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn c.eventMonitor.addListener(listener)\n}\n\n// RemoveEventListener removes a listener from the monitor.\nfunc (c *Client) RemoveEventListener(listener chan *APIEvents) error {\n\terr := c.eventMonitor.removeListener(listener)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.eventMonitor.listernersCount() == 0 {\n\t\tc.eventMonitor.disableEventMonitoring()\n\t}\n\treturn nil\n}\n\nfunc (eventState *eventMonitoringState) addListener(listener chan<- *APIEvents) error {\n\teventState.Lock()\n\tdefer eventState.Unlock()\n\tif listenerExists(listener, &eventState.listeners) {\n\t\treturn ErrListenerAlreadyExists\n\t}\n\teventState.Add(1)\n\teventState.listeners = append(eventState.listeners, listener)\n\treturn nil\n}\n\nfunc (eventState *eventMonitoringState) removeListener(listener chan<- *APIEvents) error {\n\teventState.Lock()\n\tdefer eventState.Unlock()\n\tif listenerExists(listener, &eventState.listeners) {\n\t\tvar newListeners []chan<- *APIEvents\n\t\tfor _, l := range eventState.listeners {\n\t\t\tif l != listener {\n\t\t\t\tnewListeners = append(newListeners, l)\n\t\t\t}\n\t\t}\n\t\teventState.listeners = newListeners\n\t\teventState.Add(-1)\n\t}\n\treturn nil\n}\n\nfunc (eventState *eventMonitoringState) closeListeners() {\n\tfor _, l := range eventState.listeners {\n\t\tclose(l)\n\t\teventState.Add(-1)\n\t}\n\teventState.listeners = nil\n}\n\nfunc (eventState *eventMonitoringState) listernersCount() int {\n\teventState.RLock()\n\tdefer eventState.RUnlock()\n\treturn len(eventState.listeners)\n}\n\nfunc listenerExists(a chan<- *APIEvents, list *[]chan<- *APIEvents) bool {\n\tfor _, b := range *list {\n\t\tif b == a {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (eventState *eventMonitoringState) enableEventMonitoring(c *Client, opts EventsOptions) error {\n\teventState.Lock()\n\tdefer eventState.Unlock()\n\tif !eventState.enabled {\n\t\teventState.enabled = true\n\t\tatomic.StoreInt64(&eventState.lastSeen, 0)\n\t\teventState.C = make(chan *APIEvents, 100)\n\t\teventState.errC = make(chan error, 1)\n\t\tgo eventState.monitorEvents(c, opts)\n\t}\n\treturn nil\n}\n\nfunc (eventState *eventMonitoringState) disableEventMonitoring() {\n\teventState.Lock()\n\tdefer eventState.Unlock()\n\n\teventState.closeListeners()\n\n\teventState.Wait()\n\n\tif eventState.enabled {\n\t\teventState.enabled = false\n\t\tclose(eventState.C)\n\t\tclose(eventState.errC)\n\n\t\tif eventState.closeConn != nil {\n\t\t\teventState.closeConn()\n\t\t\teventState.closeConn = nil\n\t\t}\n\t}\n}\n\nfunc (eventState *eventMonitoringState) monitorEvents(c *Client, opts EventsOptions) {\n\tconst (\n\t\tnoListenersTimeout  = 5 * time.Second\n\t\tnoListenersInterval = 10 * time.Millisecond\n\t\tnoListenersMaxTries = noListenersTimeout / noListenersInterval\n\t)\n\n\tvar err error\n\tfor i := time.Duration(0); i < noListenersMaxTries && eventState.noListeners(); i++ {\n\t\ttime.Sleep(10 * time.Millisecond)\n\t}\n\n\tif eventState.noListeners() {\n\t\t// terminate if no listener is available after 5 seconds.\n\t\t// Prevents goroutine leak when RemoveEventListener is called\n\t\t// right after AddEventListener.\n\t\teventState.disableEventMonitoring()\n\t\treturn\n\t}\n\n\tif err = eventState.connectWithRetry(c, opts); err != nil {\n\t\t// terminate if connect failed\n\t\teventState.disableEventMonitoring()\n\t\treturn\n\t}\n\tfor eventState.isEnabled() {\n\t\ttimeout := time.After(100 * time.Millisecond)\n\t\tselect {\n\t\tcase ev, ok := <-eventState.C:\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif ev == EOFEvent {\n\t\t\t\teventState.disableEventMonitoring()\n\t\t\t\treturn\n\t\t\t}\n\t\t\teventState.updateLastSeen(ev)\n\t\t\teventState.sendEvent(ev)\n\t\tcase err = <-eventState.errC:\n\t\t\tif errors.Is(err, ErrNoListeners) {\n\t\t\t\teventState.disableEventMonitoring()\n\t\t\t\treturn\n\t\t\t} else if err != nil {\n\t\t\t\tdefer func() { go eventState.monitorEvents(c, opts) }()\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-timeout:\n\t\t\tcontinue\n\t\t}\n\t}\n}\n\nfunc (eventState *eventMonitoringState) connectWithRetry(c *Client, opts EventsOptions) error {\n\tvar retries int\n\teventState.RLock()\n\teventChan := eventState.C\n\terrChan := eventState.errC\n\teventState.RUnlock()\n\tcloseConn, err := c.eventHijack(opts, atomic.LoadInt64(&eventState.lastSeen), eventChan, errChan)\n\tfor ; err != nil && retries < maxMonitorConnRetries; retries++ {\n\t\twaitTime := int64(retryInitialWaitTime * math.Pow(2, float64(retries)))\n\t\ttime.Sleep(time.Duration(waitTime) * time.Millisecond)\n\t\teventState.RLock()\n\t\teventChan = eventState.C\n\t\terrChan = eventState.errC\n\t\teventState.RUnlock()\n\t\tcloseConn, err = c.eventHijack(opts, atomic.LoadInt64(&eventState.lastSeen), eventChan, errChan)\n\t}\n\teventState.Lock()\n\tdefer eventState.Unlock()\n\teventState.closeConn = closeConn\n\treturn err\n}\n\nfunc (eventState *eventMonitoringState) noListeners() bool {\n\teventState.RLock()\n\tdefer eventState.RUnlock()\n\treturn len(eventState.listeners) == 0\n}\n\nfunc (eventState *eventMonitoringState) isEnabled() bool {\n\teventState.RLock()\n\tdefer eventState.RUnlock()\n\treturn eventState.enabled\n}\n\nfunc (eventState *eventMonitoringState) sendEvent(event *APIEvents) {\n\teventState.RLock()\n\tdefer eventState.RUnlock()\n\teventState.Add(1)\n\tdefer eventState.Done()\n\tif eventState.enabled {\n\t\tif len(eventState.listeners) == 0 {\n\t\t\teventState.errC <- ErrNoListeners\n\t\t\treturn\n\t\t}\n\n\t\tfor _, listener := range eventState.listeners {\n\t\t\tselect {\n\t\t\tcase listener <- event:\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (eventState *eventMonitoringState) updateLastSeen(e *APIEvents) {\n\teventState.Lock()\n\tdefer eventState.Unlock()\n\tif atomic.LoadInt64(&eventState.lastSeen) < e.Time {\n\t\tatomic.StoreInt64(&eventState.lastSeen, e.Time)\n\t}\n}\n\nfunc (c *Client) eventHijack(opts EventsOptions, startTime int64, eventChan chan *APIEvents, errChan chan error) (closeConn func(), err error) {\n\t// on reconnect override initial Since with last event seen time\n\tif startTime != 0 {\n\t\topts.Since = strconv.FormatInt(startTime, 10)\n\t}\n\turi := \"/events?\" + queryString(opts)\n\tprotocol := c.endpointURL.Scheme\n\taddress := c.endpointURL.Path\n\tif protocol != \"unix\" && protocol != \"npipe\" {\n\t\tprotocol = \"tcp\"\n\t\taddress = c.endpointURL.Host\n\t}\n\tvar dial net.Conn\n\tif c.TLSConfig == nil {\n\t\tdial, err = c.Dialer.Dial(protocol, address)\n\t} else {\n\t\tnetDialer, ok := c.Dialer.(*net.Dialer)\n\t\tif !ok {\n\t\t\treturn nil, ErrTLSNotSupported\n\t\t}\n\t\tdial, err = tlsDialWithDialer(netDialer, protocol, address, c.TLSConfig)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t//lint:ignore SA1019 the alternative doesn't quite work, so keep using the deprecated thing.\n\tconn := httputil.NewClientConn(dial, nil)\n\treq, err := http.NewRequest(http.MethodGet, uri, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tres, err := conn.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkeepRunning := int32(1)\n\t//lint:ignore SA1019 the alternative doesn't quite work, so keep using the deprecated thing.\n\tgo func(res *http.Response, conn *httputil.ClientConn) {\n\t\tdefer conn.Close()\n\t\tdefer res.Body.Close()\n\t\tdecoder := json.NewDecoder(res.Body)\n\t\tfor atomic.LoadInt32(&keepRunning) == 1 {\n\t\t\tvar event APIEvents\n\t\t\tif err := decoder.Decode(&event); err != nil {\n\t\t\t\tif errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {\n\t\t\t\t\tc.eventMonitor.RLock()\n\t\t\t\t\tif c.eventMonitor.enabled && c.eventMonitor.C == eventChan {\n\t\t\t\t\t\t// Signal that we're exiting.\n\t\t\t\t\t\teventChan <- EOFEvent\n\t\t\t\t\t}\n\t\t\t\t\tc.eventMonitor.RUnlock()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\terrChan <- err\n\t\t\t}\n\t\t\tif event.Time == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttransformEvent(&event)\n\t\t\tc.eventMonitor.RLock()\n\t\t\tif c.eventMonitor.enabled && c.eventMonitor.C == eventChan {\n\t\t\t\teventChan <- &event\n\t\t\t}\n\t\t\tc.eventMonitor.RUnlock()\n\t\t}\n\t}(res, conn)\n\treturn func() {\n\t\tatomic.StoreInt32(&keepRunning, 0)\n\t}, nil\n}\n\n// transformEvent takes an event and determines what version it is from\n// then populates both versions of the event\nfunc transformEvent(event *APIEvents) {\n\t// if event version is <= 1.21 there will be no Action and no Type\n\tif event.Action == \"\" && event.Type == \"\" {\n\t\tevent.Action = event.Status\n\t\tevent.Actor.ID = event.ID\n\t\tevent.Actor.Attributes = map[string]string{}\n\t\tswitch event.Status {\n\t\tcase \"delete\", \"import\", \"pull\", \"push\", \"tag\", \"untag\":\n\t\t\tevent.Type = \"image\"\n\t\tdefault:\n\t\t\tevent.Type = \"container\"\n\t\t\tif event.From != \"\" {\n\t\t\t\tevent.Actor.Attributes[\"image\"] = event.From\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif event.Status == \"\" {\n\t\t\tif event.Type == \"image\" || event.Type == \"container\" {\n\t\t\t\tevent.Status = event.Action\n\t\t\t} else {\n\t\t\t\t// Because just the Status has been overloaded with different Types\n\t\t\t\t// if an event is not for an image or a container, we prepend the type\n\t\t\t\t// to avoid problems for people relying on actions being only for\n\t\t\t\t// images and containers\n\t\t\t\tevent.Status = event.Type + \":\" + event.Action\n\t\t\t}\n\t\t}\n\t\tif event.ID == \"\" {\n\t\t\tevent.ID = event.Actor.ID\n\t\t}\n\t\tif event.From == \"\" {\n\t\t\tevent.From = event.Actor.Attributes[\"image\"]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/exec.go",
    "content": "// Copyright 2014 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n)\n\n// Exec is the type representing a `docker exec` instance and containing the\n// instance ID\ntype Exec struct {\n\tID string `json:\"Id,omitempty\" yaml:\"Id,omitempty\"`\n}\n\n// CreateExecOptions specify parameters to the CreateExecContainer function.\n//\n// See https://goo.gl/60TeBP for more details\ntype CreateExecOptions struct {\n\tEnv          []string        `json:\"Env,omitempty\" yaml:\"Env,omitempty\" toml:\"Env,omitempty\"`\n\tCmd          []string        `json:\"Cmd,omitempty\" yaml:\"Cmd,omitempty\" toml:\"Cmd,omitempty\"`\n\tContainer    string          `json:\"Container,omitempty\" yaml:\"Container,omitempty\" toml:\"Container,omitempty\"`\n\tUser         string          `json:\"User,omitempty\" yaml:\"User,omitempty\" toml:\"User,omitempty\"`\n\tWorkingDir   string          `json:\"WorkingDir,omitempty\" yaml:\"WorkingDir,omitempty\" toml:\"WorkingDir,omitempty\"`\n\tDetachKeys   string          `json:\"DetachKeys,omitempty\" yaml:\"DetachKeys,omitempty\" toml:\"DetachKeys,omitempty\"`\n\tContext      context.Context `json:\"-\"`\n\tAttachStdin  bool            `json:\"AttachStdin,omitempty\" yaml:\"AttachStdin,omitempty\" toml:\"AttachStdin,omitempty\"`\n\tAttachStdout bool            `json:\"AttachStdout,omitempty\" yaml:\"AttachStdout,omitempty\" toml:\"AttachStdout,omitempty\"`\n\tAttachStderr bool            `json:\"AttachStderr,omitempty\" yaml:\"AttachStderr,omitempty\" toml:\"AttachStderr,omitempty\"`\n\tTty          bool            `json:\"Tty,omitempty\" yaml:\"Tty,omitempty\" toml:\"Tty,omitempty\"`\n\tPrivileged   bool            `json:\"Privileged,omitempty\" yaml:\"Privileged,omitempty\" toml:\"Privileged,omitempty\"`\n}\n\n// CreateExec sets up an exec instance in a running container `id`, returning the exec\n// instance, or an error in case of failure.\n//\n// See https://goo.gl/60TeBP for more details\nfunc (c *Client) CreateExec(opts CreateExecOptions) (*Exec, error) {\n\tif c.serverAPIVersion == nil {\n\t\tc.checkAPIVersion()\n\t}\n\tif len(opts.Env) > 0 && c.serverAPIVersion.LessThan(apiVersion125) {\n\t\treturn nil, errors.New(\"exec configuration Env is only supported in API#1.25 and above\")\n\t}\n\tif len(opts.WorkingDir) > 0 && c.serverAPIVersion.LessThan(apiVersion135) {\n\t\treturn nil, errors.New(\"exec configuration WorkingDir is only supported in API#1.35 and above\")\n\t}\n\tpath := fmt.Sprintf(\"/containers/%s/exec\", opts.Container)\n\tresp, err := c.do(http.MethodPost, path, doOptions{data: opts, context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchContainer{ID: opts.Container}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar exec Exec\n\tif err := json.NewDecoder(resp.Body).Decode(&exec); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &exec, nil\n}\n\n// StartExecOptions specify parameters to the StartExecContainer function.\n//\n// See https://goo.gl/1EeDWi for more details\ntype StartExecOptions struct {\n\tInputStream  io.Reader `qs:\"-\"`\n\tOutputStream io.Writer `qs:\"-\"`\n\tErrorStream  io.Writer `qs:\"-\"`\n\n\tDetach bool `json:\"Detach,omitempty\" yaml:\"Detach,omitempty\" toml:\"Detach,omitempty\"`\n\tTty    bool `json:\"Tty,omitempty\" yaml:\"Tty,omitempty\" toml:\"Tty,omitempty\"`\n\n\t// Use raw terminal? Usually true when the container contains a TTY.\n\tRawTerminal bool `qs:\"-\"`\n\n\t// If set, after a successful connect, a sentinel will be sent and then the\n\t// client will block on receive before continuing.\n\t//\n\t// It must be an unbuffered channel. Using a buffered channel can lead\n\t// to unexpected behavior.\n\tSuccess chan struct{} `json:\"-\"`\n\n\tContext context.Context `json:\"-\"`\n}\n\n// StartExec starts a previously set up exec instance id. If opts.Detach is\n// true, it returns after starting the exec command. Otherwise, it sets up an\n// interactive session with the exec command.\n//\n// See https://goo.gl/1EeDWi for more details\nfunc (c *Client) StartExec(id string, opts StartExecOptions) error {\n\tcw, err := c.StartExecNonBlocking(id, opts)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif cw != nil {\n\t\treturn cw.Wait()\n\t}\n\treturn nil\n}\n\n// StartExecNonBlocking starts a previously set up exec instance id. If opts.Detach is\n// true, it returns after starting the exec command. Otherwise, it sets up an\n// interactive session with the exec command.\n//\n// See https://goo.gl/1EeDWi for more details\nfunc (c *Client) StartExecNonBlocking(id string, opts StartExecOptions) (CloseWaiter, error) {\n\tif id == \"\" {\n\t\treturn nil, &NoSuchExec{ID: id}\n\t}\n\n\tpath := fmt.Sprintf(\"/exec/%s/start\", id)\n\n\tif opts.Detach {\n\t\tresp, err := c.do(http.MethodPost, path, doOptions{data: opts, context: opts.Context})\n\t\tif err != nil {\n\t\t\tvar e *Error\n\t\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\t\treturn nil, &NoSuchExec{ID: id}\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer resp.Body.Close()\n\t\treturn nil, nil\n\t}\n\n\treturn c.hijack(http.MethodPost, path, hijackOptions{\n\t\tsuccess:        opts.Success,\n\t\tsetRawTerminal: opts.RawTerminal,\n\t\tin:             opts.InputStream,\n\t\tstdout:         opts.OutputStream,\n\t\tstderr:         opts.ErrorStream,\n\t\tdata:           opts,\n\t})\n}\n\n// ResizeExecTTY resizes the tty session used by the exec command id. This API\n// is valid only if Tty was specified as part of creating and starting the exec\n// command.\n//\n// See https://goo.gl/Mo5bxx for more details\nfunc (c *Client) ResizeExecTTY(id string, height, width int) error {\n\tparams := make(url.Values)\n\tparams.Set(\"h\", strconv.Itoa(height))\n\tparams.Set(\"w\", strconv.Itoa(width))\n\n\tpath := fmt.Sprintf(\"/exec/%s/resize?%s\", id, params.Encode())\n\tresp, err := c.do(http.MethodPost, path, doOptions{})\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// ExecProcessConfig is a type describing the command associated to a Exec\n// instance. It's used in the ExecInspect type.\ntype ExecProcessConfig struct {\n\tUser       string   `json:\"user,omitempty\" yaml:\"user,omitempty\" toml:\"user,omitempty\"`\n\tPrivileged bool     `json:\"privileged,omitempty\" yaml:\"privileged,omitempty\" toml:\"privileged,omitempty\"`\n\tTty        bool     `json:\"tty,omitempty\" yaml:\"tty,omitempty\" toml:\"tty,omitempty\"`\n\tEntryPoint string   `json:\"entrypoint,omitempty\" yaml:\"entrypoint,omitempty\" toml:\"entrypoint,omitempty\"`\n\tArguments  []string `json:\"arguments,omitempty\" yaml:\"arguments,omitempty\" toml:\"arguments,omitempty\"`\n}\n\n// ExecInspect is a type with details about a exec instance, including the\n// exit code if the command has finished running. It's returned by a api\n// call to /exec/(id)/json\n//\n// See https://goo.gl/ctMUiW for more details\ntype ExecInspect struct {\n\tID            string            `json:\"ID,omitempty\" yaml:\"ID,omitempty\" toml:\"ID,omitempty\"`\n\tExitCode      int               `json:\"ExitCode,omitempty\" yaml:\"ExitCode,omitempty\" toml:\"ExitCode,omitempty\"`\n\tProcessConfig ExecProcessConfig `json:\"ProcessConfig,omitempty\" yaml:\"ProcessConfig,omitempty\" toml:\"ProcessConfig,omitempty\"`\n\tContainerID   string            `json:\"ContainerID,omitempty\" yaml:\"ContainerID,omitempty\" toml:\"ContainerID,omitempty\"`\n\tDetachKeys    string            `json:\"DetachKeys,omitempty\" yaml:\"DetachKeys,omitempty\" toml:\"DetachKeys,omitempty\"`\n\tRunning       bool              `json:\"Running,omitempty\" yaml:\"Running,omitempty\" toml:\"Running,omitempty\"`\n\tOpenStdin     bool              `json:\"OpenStdin,omitempty\" yaml:\"OpenStdin,omitempty\" toml:\"OpenStdin,omitempty\"`\n\tOpenStderr    bool              `json:\"OpenStderr,omitempty\" yaml:\"OpenStderr,omitempty\" toml:\"OpenStderr,omitempty\"`\n\tOpenStdout    bool              `json:\"OpenStdout,omitempty\" yaml:\"OpenStdout,omitempty\" toml:\"OpenStdout,omitempty\"`\n\tCanRemove     bool              `json:\"CanRemove,omitempty\" yaml:\"CanRemove,omitempty\" toml:\"CanRemove,omitempty\"`\n}\n\n// InspectExec returns low-level information about the exec command id.\n//\n// See https://goo.gl/ctMUiW for more details\nfunc (c *Client) InspectExec(id string) (*ExecInspect, error) {\n\tpath := fmt.Sprintf(\"/exec/%s/json\", id)\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchExec{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar exec ExecInspect\n\tif err := json.NewDecoder(resp.Body).Decode(&exec); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &exec, nil\n}\n\n// NoSuchExec is the error returned when a given exec instance does not exist.\ntype NoSuchExec struct {\n\tID string\n}\n\nfunc (err *NoSuchExec) Error() string {\n\treturn \"No such exec instance: \" + err.ID\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/image.go",
    "content": "// Copyright 2013 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\n// APIImages represent an image returned in the ListImages call.\ntype APIImages struct {\n\tID          string            `json:\"Id\" yaml:\"Id\" toml:\"Id\"`\n\tRepoTags    []string          `json:\"RepoTags,omitempty\" yaml:\"RepoTags,omitempty\" toml:\"RepoTags,omitempty\"`\n\tCreated     int64             `json:\"Created,omitempty\" yaml:\"Created,omitempty\" toml:\"Created,omitempty\"`\n\tSize        int64             `json:\"Size,omitempty\" yaml:\"Size,omitempty\" toml:\"Size,omitempty\"`\n\tVirtualSize int64             `json:\"VirtualSize,omitempty\" yaml:\"VirtualSize,omitempty\" toml:\"VirtualSize,omitempty\"`\n\tParentID    string            `json:\"ParentId,omitempty\" yaml:\"ParentId,omitempty\" toml:\"ParentId,omitempty\"`\n\tRepoDigests []string          `json:\"RepoDigests,omitempty\" yaml:\"RepoDigests,omitempty\" toml:\"RepoDigests,omitempty\"`\n\tLabels      map[string]string `json:\"Labels,omitempty\" yaml:\"Labels,omitempty\" toml:\"Labels,omitempty\"`\n}\n\n// RootFS represents the underlying layers used by an image\ntype RootFS struct {\n\tType   string   `json:\"Type,omitempty\" yaml:\"Type,omitempty\" toml:\"Type,omitempty\"`\n\tLayers []string `json:\"Layers,omitempty\" yaml:\"Layers,omitempty\" toml:\"Layers,omitempty\"`\n}\n\n// Image is the type representing a docker image and its various properties\ntype Image struct {\n\tID              string    `json:\"Id\" yaml:\"Id\" toml:\"Id\"`\n\tRepoTags        []string  `json:\"RepoTags,omitempty\" yaml:\"RepoTags,omitempty\" toml:\"RepoTags,omitempty\"`\n\tParent          string    `json:\"Parent,omitempty\" yaml:\"Parent,omitempty\" toml:\"Parent,omitempty\"`\n\tComment         string    `json:\"Comment,omitempty\" yaml:\"Comment,omitempty\" toml:\"Comment,omitempty\"`\n\tCreated         time.Time `json:\"Created,omitempty\" yaml:\"Created,omitempty\" toml:\"Created,omitempty\"`\n\tContainer       string    `json:\"Container,omitempty\" yaml:\"Container,omitempty\" toml:\"Container,omitempty\"`\n\tContainerConfig Config    `json:\"ContainerConfig,omitempty\" yaml:\"ContainerConfig,omitempty\" toml:\"ContainerConfig,omitempty\"`\n\tDockerVersion   string    `json:\"DockerVersion,omitempty\" yaml:\"DockerVersion,omitempty\" toml:\"DockerVersion,omitempty\"`\n\tAuthor          string    `json:\"Author,omitempty\" yaml:\"Author,omitempty\" toml:\"Author,omitempty\"`\n\tConfig          *Config   `json:\"Config,omitempty\" yaml:\"Config,omitempty\" toml:\"Config,omitempty\"`\n\tArchitecture    string    `json:\"Architecture,omitempty\" yaml:\"Architecture,omitempty\"`\n\tSize            int64     `json:\"Size,omitempty\" yaml:\"Size,omitempty\" toml:\"Size,omitempty\"`\n\tVirtualSize     int64     `json:\"VirtualSize,omitempty\" yaml:\"VirtualSize,omitempty\" toml:\"VirtualSize,omitempty\"`\n\tRepoDigests     []string  `json:\"RepoDigests,omitempty\" yaml:\"RepoDigests,omitempty\" toml:\"RepoDigests,omitempty\"`\n\tRootFS          *RootFS   `json:\"RootFS,omitempty\" yaml:\"RootFS,omitempty\" toml:\"RootFS,omitempty\"`\n\tOS              string    `json:\"Os,omitempty\" yaml:\"Os,omitempty\" toml:\"Os,omitempty\"`\n}\n\n// ImagePre012 serves the same purpose as the Image type except that it is for\n// earlier versions of the Docker API (pre-012 to be specific)\ntype ImagePre012 struct {\n\tID              string    `json:\"id\"`\n\tParent          string    `json:\"parent,omitempty\"`\n\tComment         string    `json:\"comment,omitempty\"`\n\tCreated         time.Time `json:\"created\"`\n\tContainer       string    `json:\"container,omitempty\"`\n\tContainerConfig Config    `json:\"container_config,omitempty\"`\n\tDockerVersion   string    `json:\"docker_version,omitempty\"`\n\tAuthor          string    `json:\"author,omitempty\"`\n\tConfig          *Config   `json:\"config,omitempty\"`\n\tArchitecture    string    `json:\"architecture,omitempty\"`\n\tSize            int64     `json:\"size,omitempty\"`\n}\n\nvar (\n\t// ErrNoSuchImage is the error returned when the image does not exist.\n\tErrNoSuchImage = errors.New(\"no such image\")\n\n\t// ErrMissingRepo is the error returned when the remote repository is\n\t// missing.\n\tErrMissingRepo = errors.New(\"missing remote repository e.g. 'github.com/user/repo'\")\n\n\t// ErrMissingOutputStream is the error returned when no output stream\n\t// is provided to some calls, like BuildImage.\n\tErrMissingOutputStream = errors.New(\"missing output stream\")\n\n\t// ErrMultipleContexts is the error returned when both a ContextDir and\n\t// InputStream are provided in BuildImageOptions\n\tErrMultipleContexts = errors.New(\"image build may not be provided BOTH context dir and input stream\")\n\n\t// ErrMustSpecifyNames is the error returned when the Names field on\n\t// ExportImagesOptions is nil or empty\n\tErrMustSpecifyNames = errors.New(\"must specify at least one name to export\")\n)\n\n// ListImagesOptions specify parameters to the ListImages function.\n//\n// See https://goo.gl/BVzauZ for more details.\ntype ListImagesOptions struct {\n\tFilters map[string][]string\n\tAll     bool\n\tDigests bool\n\tFilter  string\n\tContext context.Context\n}\n\n// ListImages returns the list of available images in the server.\n//\n// See https://goo.gl/BVzauZ for more details.\nfunc (c *Client) ListImages(opts ListImagesOptions) ([]APIImages, error) {\n\tpath := \"/images/json?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar images []APIImages\n\tif err := json.NewDecoder(resp.Body).Decode(&images); err != nil {\n\t\treturn nil, err\n\t}\n\treturn images, nil\n}\n\n// ImageHistory represent a layer in an image's history returned by the\n// ImageHistory call.\ntype ImageHistory struct {\n\tID        string   `json:\"Id\" yaml:\"Id\" toml:\"Id\"`\n\tTags      []string `json:\"Tags,omitempty\" yaml:\"Tags,omitempty\" toml:\"Tags,omitempty\"`\n\tCreated   int64    `json:\"Created,omitempty\" yaml:\"Created,omitempty\" toml:\"Tags,omitempty\"`\n\tCreatedBy string   `json:\"CreatedBy,omitempty\" yaml:\"CreatedBy,omitempty\" toml:\"CreatedBy,omitempty\"`\n\tSize      int64    `json:\"Size,omitempty\" yaml:\"Size,omitempty\" toml:\"Size,omitempty\"`\n\tComment   string   `json:\"Comment,omitempty\" yaml:\"Comment,omitempty\" toml:\"Comment,omitempty\"`\n}\n\n// ImageHistory returns the history of the image by its name or ID.\n//\n// See https://goo.gl/fYtxQa for more details.\nfunc (c *Client) ImageHistory(name string) ([]ImageHistory, error) {\n\tresp, err := c.do(http.MethodGet, \"/images/\"+name+\"/history\", doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, ErrNoSuchImage\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar history []ImageHistory\n\tif err := json.NewDecoder(resp.Body).Decode(&history); err != nil {\n\t\treturn nil, err\n\t}\n\treturn history, nil\n}\n\n// RemoveImage removes an image by its name or ID.\n//\n// See https://goo.gl/Vd2Pck for more details.\nfunc (c *Client) RemoveImage(name string) error {\n\tresp, err := c.do(http.MethodDelete, \"/images/\"+name, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn ErrNoSuchImage\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// RemoveImageOptions present the set of options available for removing an image\n// from a registry.\n//\n// See https://goo.gl/Vd2Pck for more details.\ntype RemoveImageOptions struct {\n\tForce   bool `qs:\"force\"`\n\tNoPrune bool `qs:\"noprune\"`\n\tContext context.Context\n}\n\n// RemoveImageExtended removes an image by its name or ID.\n// Extra params can be passed, see RemoveImageOptions\n//\n// See https://goo.gl/Vd2Pck for more details.\nfunc (c *Client) RemoveImageExtended(name string, opts RemoveImageOptions) error {\n\turi := fmt.Sprintf(\"/images/%s?%s\", name, queryString(&opts))\n\tresp, err := c.do(http.MethodDelete, uri, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn ErrNoSuchImage\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// InspectImage returns an image by its name or ID.\n//\n// See https://goo.gl/ncLTG8 for more details.\nfunc (c *Client) InspectImage(name string) (*Image, error) {\n\tresp, err := c.do(http.MethodGet, \"/images/\"+name+\"/json\", doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, ErrNoSuchImage\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tvar image Image\n\n\t// if the caller elected to skip checking the server's version, assume it's the latest\n\tif c.SkipServerVersionCheck || c.expectedAPIVersion.GreaterThanOrEqualTo(apiVersion112) {\n\t\tif err := json.NewDecoder(resp.Body).Decode(&image); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tvar imagePre012 ImagePre012\n\t\tif err := json.NewDecoder(resp.Body).Decode(&imagePre012); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\timage.ID = imagePre012.ID\n\t\timage.Parent = imagePre012.Parent\n\t\timage.Comment = imagePre012.Comment\n\t\timage.Created = imagePre012.Created\n\t\timage.Container = imagePre012.Container\n\t\timage.ContainerConfig = imagePre012.ContainerConfig\n\t\timage.DockerVersion = imagePre012.DockerVersion\n\t\timage.Author = imagePre012.Author\n\t\timage.Config = imagePre012.Config\n\t\timage.Architecture = imagePre012.Architecture\n\t\timage.Size = imagePre012.Size\n\t}\n\n\treturn &image, nil\n}\n\n// PushImageOptions represents options to use in the PushImage method.\n//\n// See https://goo.gl/BZemGg for more details.\ntype PushImageOptions struct {\n\t// Name of the image\n\tName string\n\n\t// Tag of the image\n\tTag string\n\n\t// Registry server to push the image\n\tRegistry string\n\n\tOutputStream      io.Writer     `qs:\"-\"`\n\tRawJSONStream     bool          `qs:\"-\"`\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\n\tContext context.Context\n}\n\n// PushImage pushes an image to a remote registry, logging progress to w.\n//\n// An empty instance of AuthConfiguration may be used for unauthenticated\n// pushes.\n//\n// See https://goo.gl/BZemGg for more details.\nfunc (c *Client) PushImage(opts PushImageOptions, auth AuthConfiguration) error {\n\tif opts.Name == \"\" {\n\t\treturn ErrNoSuchImage\n\t}\n\theaders, err := headersWithAuth(auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\tname := opts.Name\n\topts.Name = \"\"\n\tpath := \"/images/\" + name + \"/push?\" + queryString(&opts)\n\treturn c.stream(http.MethodPost, path, streamOptions{\n\t\tsetRawTerminal:    true,\n\t\trawJSONStream:     opts.RawJSONStream,\n\t\theaders:           headers,\n\t\tstdout:            opts.OutputStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\tcontext:           opts.Context,\n\t})\n}\n\n// PullImageOptions present the set of options available for pulling an image\n// from a registry.\n//\n// See https://goo.gl/qkoSsn for more details.\ntype PullImageOptions struct {\n\tAll        bool\n\tRepository string `qs:\"fromImage\"`\n\tTag        string\n\tPlatform   string `ver:\"1.32\"`\n\n\t// Only required for Docker Engine 1.9 or 1.10 w/ Remote API < 1.21\n\t// and Docker Engine < 1.9\n\t// This parameter was removed in Docker Engine 1.11\n\tRegistry string\n\n\tOutputStream      io.Writer     `qs:\"-\"`\n\tRawJSONStream     bool          `qs:\"-\"`\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tContext           context.Context\n}\n\n// PullImage pulls an image from a remote registry, logging progress to\n// opts.OutputStream.\n//\n// See https://goo.gl/qkoSsn for more details.\nfunc (c *Client) PullImage(opts PullImageOptions, auth AuthConfiguration) error {\n\tif opts.Repository == \"\" {\n\t\treturn ErrNoSuchImage\n\t}\n\n\theaders, err := headersWithAuth(auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif opts.Tag == \"\" && strings.Contains(opts.Repository, \"@\") {\n\t\tparts := strings.SplitN(opts.Repository, \"@\", 2)\n\t\topts.Repository = parts[0]\n\t\topts.Tag = parts[1]\n\t}\n\treturn c.createImage(&opts, headers, nil, opts.OutputStream, opts.RawJSONStream, opts.InactivityTimeout, opts.Context)\n}\n\nfunc (c *Client) createImage(opts any, headers map[string]string, in io.Reader, w io.Writer, rawJSONStream bool, timeout time.Duration, context context.Context) error {\n\turl, err := c.getPath(\"/images/create\", opts)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn c.streamURL(http.MethodPost, url, streamOptions{\n\t\tsetRawTerminal:    true,\n\t\theaders:           headers,\n\t\tin:                in,\n\t\tstdout:            w,\n\t\trawJSONStream:     rawJSONStream,\n\t\tinactivityTimeout: timeout,\n\t\tcontext:           context,\n\t})\n}\n\n// LoadImageOptions represents the options for LoadImage Docker API Call\n//\n// See https://goo.gl/rEsBV3 for more details.\ntype LoadImageOptions struct {\n\tInputStream  io.Reader\n\tOutputStream io.Writer\n\tContext      context.Context\n}\n\n// LoadImage imports a tarball docker image\n//\n// See https://goo.gl/rEsBV3 for more details.\nfunc (c *Client) LoadImage(opts LoadImageOptions) error {\n\treturn c.stream(http.MethodPost, \"/images/load\", streamOptions{\n\t\tsetRawTerminal: true,\n\t\tin:             opts.InputStream,\n\t\tstdout:         opts.OutputStream,\n\t\tcontext:        opts.Context,\n\t})\n}\n\n// ExportImageOptions represent the options for ExportImage Docker API call.\n//\n// See https://goo.gl/AuySaA for more details.\ntype ExportImageOptions struct {\n\tName              string\n\tOutputStream      io.Writer\n\tInactivityTimeout time.Duration\n\tContext           context.Context\n}\n\n// ExportImage exports an image (as a tar file) into the stream.\n//\n// See https://goo.gl/AuySaA for more details.\nfunc (c *Client) ExportImage(opts ExportImageOptions) error {\n\treturn c.stream(http.MethodGet, fmt.Sprintf(\"/images/%s/get\", opts.Name), streamOptions{\n\t\tsetRawTerminal:    true,\n\t\tstdout:            opts.OutputStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\tcontext:           opts.Context,\n\t})\n}\n\n// ExportImagesOptions represent the options for ExportImages Docker API call\n//\n// See https://goo.gl/N9XlDn for more details.\ntype ExportImagesOptions struct {\n\tNames             []string\n\tOutputStream      io.Writer     `qs:\"-\"`\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tContext           context.Context\n}\n\n// ExportImages exports one or more images (as a tar file) into the stream\n//\n// See https://goo.gl/N9XlDn for more details.\nfunc (c *Client) ExportImages(opts ExportImagesOptions) error {\n\tif opts.Names == nil || len(opts.Names) == 0 {\n\t\treturn ErrMustSpecifyNames\n\t}\n\t// API < 1.25 allows multiple name values\n\t// 1.25 says name must be a comma separated list\n\tvar err error\n\tvar exporturl string\n\tif c.requestedAPIVersion.GreaterThanOrEqualTo(apiVersion125) {\n\t\tstr := opts.Names[0]\n\t\tfor _, val := range opts.Names[1:] {\n\t\t\tstr += \",\" + val\n\t\t}\n\t\texporturl, err = c.getPath(\"/images/get\", ExportImagesOptions{\n\t\t\tNames:             []string{str},\n\t\t\tOutputStream:      opts.OutputStream,\n\t\t\tInactivityTimeout: opts.InactivityTimeout,\n\t\t\tContext:           opts.Context,\n\t\t})\n\t} else {\n\t\texporturl, err = c.getPath(\"/images/get\", &opts)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn c.streamURL(http.MethodGet, exporturl, streamOptions{\n\t\tsetRawTerminal:    true,\n\t\tstdout:            opts.OutputStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t})\n}\n\n// ImportImageOptions present the set of informations available for importing\n// an image from a source file or the stdin.\n//\n// See https://goo.gl/qkoSsn for more details.\ntype ImportImageOptions struct {\n\tRepository string `qs:\"repo\"`\n\tSource     string `qs:\"fromSrc\"`\n\tTag        string `qs:\"tag\"`\n\n\tInputStream       io.Reader     `qs:\"-\"`\n\tOutputStream      io.Writer     `qs:\"-\"`\n\tRawJSONStream     bool          `qs:\"-\"`\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tContext           context.Context\n}\n\n// ImportImage imports an image from a url, a file or stdin\n//\n// See https://goo.gl/qkoSsn for more details.\nfunc (c *Client) ImportImage(opts ImportImageOptions) error {\n\tif opts.Repository == \"\" {\n\t\treturn ErrNoSuchImage\n\t}\n\tif opts.Source != \"-\" {\n\t\topts.InputStream = nil\n\t}\n\tif opts.Source != \"-\" && !isURL(opts.Source) {\n\t\tf, err := os.Open(opts.Source)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\topts.InputStream = f\n\t\topts.Source = \"-\"\n\t}\n\treturn c.createImage(&opts, nil, opts.InputStream, opts.OutputStream, opts.RawJSONStream, opts.InactivityTimeout, opts.Context)\n}\n\n// BuilderVersion represents either the BuildKit or V1 (\"classic\") builder.\ntype BuilderVersion string\n\nconst (\n\tBuilderV1       BuilderVersion = \"1\"\n\tBuilderBuildKit BuilderVersion = \"2\"\n)\n\n// BuildImageOptions present the set of informations available for building an\n// image from a tarfile with a Dockerfile in it.\n//\n// For more details about the Docker building process, see\n// https://goo.gl/4nYHwV.\ntype BuildImageOptions struct {\n\tContext             context.Context\n\tName                string   `qs:\"t\"`\n\tDockerfile          string   `ver:\"1.25\"`\n\tExtraHosts          string   `ver:\"1.28\"`\n\tCacheFrom           []string `qs:\"-\" ver:\"1.25\"`\n\tMemory              int64\n\tMemswap             int64\n\tShmSize             int64\n\tCPUShares           int64\n\tCPUQuota            int64 `ver:\"1.21\"`\n\tCPUPeriod           int64 `ver:\"1.21\"`\n\tCPUSetCPUs          string\n\tLabels              map[string]string\n\tInputStream         io.Reader `qs:\"-\"`\n\tOutputStream        io.Writer `qs:\"-\"`\n\tRemote              string\n\tAuth                AuthConfiguration  `qs:\"-\"` // for older docker X-Registry-Auth header\n\tAuthConfigs         AuthConfigurations `qs:\"-\"` // for newer docker X-Registry-Config header\n\tContextDir          string             `qs:\"-\"`\n\tUlimits             []ULimit           `qs:\"-\" ver:\"1.18\"`\n\tBuildArgs           []BuildArg         `qs:\"-\" ver:\"1.21\"`\n\tNetworkMode         string             `ver:\"1.25\"`\n\tPlatform            string             `ver:\"1.32\"`\n\tInactivityTimeout   time.Duration      `qs:\"-\"`\n\tCgroupParent        string\n\tSecurityOpt         []string\n\tTarget              string\n\tOutputs             string `ver:\"1.40\"`\n\tNoCache             bool\n\tSuppressOutput      bool           `qs:\"q\"`\n\tPull                bool           `ver:\"1.16\"`\n\tRmTmpContainer      bool           `qs:\"rm\"`\n\tForceRmTmpContainer bool           `qs:\"forcerm\" ver:\"1.12\"`\n\tRawJSONStream       bool           `qs:\"-\"`\n\tVersion             BuilderVersion `qs:\"version\" ver:\"1.39\"`\n}\n\n// BuildArg represents arguments that can be passed to the image when building\n// it from a Dockerfile.\n//\n// For more details about the Docker building process, see\n// https://goo.gl/4nYHwV.\ntype BuildArg struct {\n\tName  string `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tValue string `json:\"Value,omitempty\" yaml:\"Value,omitempty\" toml:\"Value,omitempty\"`\n}\n\n// BuildImage builds an image from a tarball's url or a Dockerfile in the input\n// stream.\n//\n// See https://goo.gl/4nYHwV for more details.\nfunc (c *Client) BuildImage(opts BuildImageOptions) error {\n\tif opts.OutputStream == nil {\n\t\treturn ErrMissingOutputStream\n\t}\n\theaders, err := headersWithAuth(opts.Auth, c.versionedAuthConfigs(opts.AuthConfigs))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif opts.Remote != \"\" && opts.Name == \"\" {\n\t\topts.Name = opts.Remote\n\t}\n\tif opts.InputStream != nil || opts.ContextDir != \"\" {\n\t\theaders[\"Content-Type\"] = \"application/tar\"\n\t} else if opts.Remote == \"\" {\n\t\treturn ErrMissingRepo\n\t}\n\tif opts.ContextDir != \"\" {\n\t\tif opts.InputStream != nil {\n\t\t\treturn ErrMultipleContexts\n\t\t}\n\t\tvar err error\n\t\tif opts.InputStream, err = createTarStream(opts.ContextDir, opts.Dockerfile); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tqs, ver := queryStringVersion(&opts)\n\n\tif len(opts.CacheFrom) > 0 {\n\t\tif b, err := json.Marshal(opts.CacheFrom); err == nil {\n\t\t\titem := url.Values(map[string][]string{})\n\t\t\titem.Add(\"cachefrom\", string(b))\n\t\t\tqs = fmt.Sprintf(\"%s&%s\", qs, item.Encode())\n\t\t\tif ver == nil || apiVersion125.GreaterThan(ver) {\n\t\t\t\tver = apiVersion125\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(opts.Ulimits) > 0 {\n\t\tif b, err := json.Marshal(opts.Ulimits); err == nil {\n\t\t\titem := url.Values(map[string][]string{})\n\t\t\titem.Add(\"ulimits\", string(b))\n\t\t\tqs = fmt.Sprintf(\"%s&%s\", qs, item.Encode())\n\t\t\tif ver == nil || apiVersion118.GreaterThan(ver) {\n\t\t\t\tver = apiVersion118\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(opts.BuildArgs) > 0 {\n\t\tv := make(map[string]string)\n\t\tfor _, arg := range opts.BuildArgs {\n\t\t\tv[arg.Name] = arg.Value\n\t\t}\n\t\tif b, err := json.Marshal(v); err == nil {\n\t\t\titem := url.Values(map[string][]string{})\n\t\t\titem.Add(\"buildargs\", string(b))\n\t\t\tqs = fmt.Sprintf(\"%s&%s\", qs, item.Encode())\n\t\t\tif ver == nil || apiVersion121.GreaterThan(ver) {\n\t\t\t\tver = apiVersion121\n\t\t\t}\n\t\t}\n\t}\n\n\tbuildURL, err := c.pathVersionCheck(\"/build\", qs, ver)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn c.streamURL(http.MethodPost, buildURL, streamOptions{\n\t\tsetRawTerminal:    true,\n\t\trawJSONStream:     opts.RawJSONStream,\n\t\theaders:           headers,\n\t\tin:                opts.InputStream,\n\t\tstdout:            opts.OutputStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\tcontext:           opts.Context,\n\t})\n}\n\nfunc (c *Client) versionedAuthConfigs(authConfigs AuthConfigurations) registryAuth {\n\tif c.serverAPIVersion == nil {\n\t\tc.checkAPIVersion()\n\t}\n\tif c.serverAPIVersion != nil && c.serverAPIVersion.GreaterThanOrEqualTo(apiVersion119) {\n\t\treturn AuthConfigurations119(authConfigs.Configs)\n\t}\n\treturn authConfigs\n}\n\n// TagImageOptions present the set of options to tag an image.\n//\n// See https://goo.gl/prHrvo for more details.\ntype TagImageOptions struct {\n\tRepo    string\n\tTag     string\n\tForce   bool\n\tContext context.Context\n}\n\n// TagImage adds a tag to the image identified by the given name.\n//\n// See https://goo.gl/prHrvo for more details.\nfunc (c *Client) TagImage(name string, opts TagImageOptions) error {\n\tif name == \"\" {\n\t\treturn ErrNoSuchImage\n\t}\n\tresp, err := c.do(http.MethodPost, \"/images/\"+name+\"/tag?\"+queryString(&opts), doOptions{\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode == http.StatusNotFound {\n\t\treturn ErrNoSuchImage\n\t}\n\n\treturn err\n}\n\nfunc isURL(u string) bool {\n\tp, err := url.Parse(u)\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn p.Scheme == \"http\" || p.Scheme == \"https\"\n}\n\nfunc headersWithAuth(auths ...registryAuth) (map[string]string, error) {\n\theaders := make(map[string]string)\n\n\tfor _, auth := range auths {\n\t\tif auth.isEmpty() {\n\t\t\tcontinue\n\t\t}\n\t\tdata, err := json.Marshal(auth)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\theaders[auth.headerKey()] = base64.URLEncoding.EncodeToString(data)\n\t}\n\n\treturn headers, nil\n}\n\n// APIImageSearch reflect the result of a search on the Docker Hub.\n//\n// See https://goo.gl/KLO9IZ for more details.\ntype APIImageSearch struct {\n\tDescription string `json:\"description,omitempty\" yaml:\"description,omitempty\" toml:\"description,omitempty\"`\n\tIsOfficial  bool   `json:\"is_official,omitempty\" yaml:\"is_official,omitempty\" toml:\"is_official,omitempty\"`\n\tIsAutomated bool   `json:\"is_automated,omitempty\" yaml:\"is_automated,omitempty\" toml:\"is_automated,omitempty\"`\n\tName        string `json:\"name,omitempty\" yaml:\"name,omitempty\" toml:\"name,omitempty\"`\n\tStarCount   int    `json:\"star_count,omitempty\" yaml:\"star_count,omitempty\" toml:\"star_count,omitempty\"`\n}\n\n// SearchImages search the docker hub with a specific given term.\n//\n// See https://goo.gl/KLO9IZ for more details.\nfunc (c *Client) SearchImages(term string) ([]APIImageSearch, error) {\n\tresp, err := c.do(http.MethodGet, \"/images/search?term=\"+term, doOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar searchResult []APIImageSearch\n\tif err := json.NewDecoder(resp.Body).Decode(&searchResult); err != nil {\n\t\treturn nil, err\n\t}\n\treturn searchResult, nil\n}\n\n// SearchImagesEx search the docker hub with a specific given term and authentication.\n//\n// See https://goo.gl/KLO9IZ for more details.\nfunc (c *Client) SearchImagesEx(term string, auth AuthConfiguration) ([]APIImageSearch, error) {\n\theaders, err := headersWithAuth(auth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := c.do(http.MethodGet, \"/images/search?term=\"+term, doOptions{\n\t\theaders: headers,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer resp.Body.Close()\n\n\tvar searchResult []APIImageSearch\n\tif err := json.NewDecoder(resp.Body).Decode(&searchResult); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn searchResult, nil\n}\n\n// PruneImagesOptions specify parameters to the PruneImages function.\n//\n// See https://goo.gl/qfZlbZ for more details.\ntype PruneImagesOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// PruneImagesResults specify results from the PruneImages function.\n//\n// See https://goo.gl/qfZlbZ for more details.\ntype PruneImagesResults struct {\n\tImagesDeleted  []struct{ Untagged, Deleted string }\n\tSpaceReclaimed int64\n}\n\n// PruneImages deletes images which are unused.\n//\n// See https://goo.gl/qfZlbZ for more details.\nfunc (c *Client) PruneImages(opts PruneImagesOptions) (*PruneImagesResults, error) {\n\tpath := \"/images/prune?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar results PruneImagesResults\n\tif err := json.NewDecoder(resp.Body).Decode(&results); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &results, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/misc.go",
    "content": "// Copyright 2013 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// Version returns version information about the docker server.\n//\n// See https://goo.gl/mU7yje for more details.\nfunc (c *Client) Version() (*Env, error) {\n\treturn c.VersionWithContext(context.TODO())\n}\n\n// VersionWithContext returns version information about the docker server.\nfunc (c *Client) VersionWithContext(ctx context.Context) (*Env, error) {\n\tresp, err := c.do(http.MethodGet, \"/version\", doOptions{context: ctx})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar env Env\n\tif err := env.Decode(resp.Body); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &env, nil\n}\n\n// DockerInfo contains information about the Docker server\n//\n// See https://goo.gl/bHUoz9 for more details.\ntype DockerInfo struct {\n\tID                 string\n\tContainers         int\n\tContainersRunning  int\n\tContainersPaused   int\n\tContainersStopped  int\n\tImages             int\n\tDriver             string\n\tDriverStatus       [][2]string\n\tSystemStatus       [][2]string\n\tPlugins            PluginsInfo\n\tNFd                int\n\tNGoroutines        int\n\tSystemTime         string\n\tExecutionDriver    string\n\tLoggingDriver      string\n\tCgroupDriver       string\n\tNEventsListener    int\n\tKernelVersion      string\n\tOperatingSystem    string\n\tOSType             string\n\tArchitecture       string\n\tIndexServerAddress string\n\tRegistryConfig     *ServiceConfig\n\tSecurityOptions    []string\n\tNCPU               int\n\tMemTotal           int64\n\tDockerRootDir      string\n\tHTTPProxy          string `json:\"HttpProxy\"`\n\tHTTPSProxy         string `json:\"HttpsProxy\"`\n\tNoProxy            string\n\tName               string\n\tLabels             []string\n\tServerVersion      string\n\tClusterStore       string\n\tRuntimes           map[string]Runtime\n\tClusterAdvertise   string\n\tIsolation          string\n\tInitBinary         string\n\tDefaultRuntime     string\n\tSwarm              swarm.Info\n\tLiveRestoreEnabled bool\n\tMemoryLimit        bool\n\tSwapLimit          bool\n\tKernelMemory       bool\n\tCPUCfsPeriod       bool `json:\"CpuCfsPeriod\"`\n\tCPUCfsQuota        bool `json:\"CpuCfsQuota\"`\n\tCPUShares          bool\n\tCPUSet             bool\n\tIPv4Forwarding     bool\n\tBridgeNfIptables   bool\n\tBridgeNfIP6tables  bool `json:\"BridgeNfIp6tables\"`\n\tDebug              bool\n\tOomKillDisable     bool\n\tExperimentalBuild  bool\n}\n\n// Runtime describes an OCI runtime\n//\n// for more information, see: https://dockr.ly/2NKM8qq\ntype Runtime struct {\n\tPath string\n\tArgs []string `json:\"runtimeArgs\"`\n}\n\n// PluginsInfo is a struct with the plugins registered with the docker daemon\n//\n// for more information, see: https://goo.gl/bHUoz9\ntype PluginsInfo struct {\n\t// List of Volume plugins registered\n\tVolume []string\n\t// List of Network plugins registered\n\tNetwork []string\n\t// List of Authorization plugins registered\n\tAuthorization []string\n}\n\n// ServiceConfig stores daemon registry services configuration.\n//\n// for more information, see: https://goo.gl/7iFFDz\ntype ServiceConfig struct {\n\tInsecureRegistryCIDRs []*NetIPNet\n\tIndexConfigs          map[string]*IndexInfo\n\tMirrors               []string\n}\n\n// NetIPNet is the net.IPNet type, which can be marshalled and\n// unmarshalled to JSON.\n//\n// for more information, see: https://goo.gl/7iFFDz\ntype NetIPNet net.IPNet\n\n// MarshalJSON returns the JSON representation of the IPNet.\nfunc (ipnet *NetIPNet) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal((*net.IPNet)(ipnet).String())\n}\n\n// UnmarshalJSON sets the IPNet from a byte array of JSON.\nfunc (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) {\n\tvar ipnetStr string\n\tif err = json.Unmarshal(b, &ipnetStr); err == nil {\n\t\tvar cidr *net.IPNet\n\t\tif _, cidr, err = net.ParseCIDR(ipnetStr); err == nil {\n\t\t\t*ipnet = NetIPNet(*cidr)\n\t\t}\n\t}\n\treturn\n}\n\n// IndexInfo contains information about a registry.\n//\n// for more information, see: https://goo.gl/7iFFDz\ntype IndexInfo struct {\n\tName     string\n\tMirrors  []string\n\tSecure   bool\n\tOfficial bool\n}\n\n// Info returns system-wide information about the Docker server.\n//\n// See https://goo.gl/ElTHi2 for more details.\nfunc (c *Client) Info() (*DockerInfo, error) {\n\tresp, err := c.do(http.MethodGet, \"/info\", doOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar info DockerInfo\n\tif err := json.NewDecoder(resp.Body).Decode(&info); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &info, nil\n}\n\n// ParseRepositoryTag gets the name of the repository and returns it splitted\n// in two parts: the repository and the tag. It ignores the digest when it is\n// present.\n//\n// Some examples:\n//\n//\tlocalhost.localdomain:5000/samalba/hipache:latest -> localhost.localdomain:5000/samalba/hipache, latest\n//\tlocalhost.localdomain:5000/samalba/hipache -> localhost.localdomain:5000/samalba/hipache, \"\"\n//\tbusybox:latest@sha256:4a731fb46adc5cefe3ae374a8b6020fc1b6ad667a279647766e9a3cd89f6fa92 -> busybox, latest\nfunc ParseRepositoryTag(repoTag string) (repository string, tag string) {\n\tparts := strings.SplitN(repoTag, \"@\", 2)\n\trepoTag = parts[0]\n\tn := strings.LastIndex(repoTag, \":\")\n\tif n < 0 {\n\t\treturn repoTag, \"\"\n\t}\n\tif tag := repoTag[n+1:]; !strings.Contains(tag, \"/\") {\n\t\treturn repoTag[:n], tag\n\t}\n\treturn repoTag, \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/network.go",
    "content": "// Copyright 2015 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n)\n\n// ErrNetworkAlreadyExists is the error returned by CreateNetwork when the\n// network already exists.\nvar ErrNetworkAlreadyExists = errors.New(\"network already exists\")\n\n// Network represents a network.\n//\n// See https://goo.gl/6GugX3 for more details.\ntype Network struct {\n\tName       string\n\tID         string `json:\"Id\"`\n\tScope      string\n\tDriver     string\n\tIPAM       IPAMOptions\n\tContainers map[string]Endpoint\n\tOptions    map[string]string\n\tInternal   bool\n\tEnableIPv6 bool `json:\"EnableIPv6\"`\n\tLabels     map[string]string\n}\n\n// Endpoint contains network resources allocated and used for a container in a network\n//\n// See https://goo.gl/6GugX3 for more details.\ntype Endpoint struct {\n\tName        string\n\tID          string `json:\"EndpointID\"`\n\tMacAddress  string\n\tIPv4Address string\n\tIPv6Address string\n}\n\n// ListNetworks returns all networks.\n//\n// See https://goo.gl/6GugX3 for more details.\nfunc (c *Client) ListNetworks() ([]Network, error) {\n\tresp, err := c.do(http.MethodGet, \"/networks\", doOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar networks []Network\n\tif err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {\n\t\treturn nil, err\n\t}\n\treturn networks, nil\n}\n\n// NetworkFilterOpts is an aggregation of key=value that Docker\n// uses to filter networks\ntype NetworkFilterOpts map[string]map[string]bool\n\n// FilteredListNetworks returns all networks with the filters applied\n//\n// See goo.gl/zd2mx4 for more details.\nfunc (c *Client) FilteredListNetworks(opts NetworkFilterOpts) ([]Network, error) {\n\tparams, err := json.Marshal(opts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tqs := make(url.Values)\n\tqs.Add(\"filters\", string(params))\n\tpath := \"/networks?\" + qs.Encode()\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar networks []Network\n\tif err := json.NewDecoder(resp.Body).Decode(&networks); err != nil {\n\t\treturn nil, err\n\t}\n\treturn networks, nil\n}\n\n// NetworkInfo returns information about a network by its ID.\n//\n// See https://goo.gl/6GugX3 for more details.\nfunc (c *Client) NetworkInfo(id string) (*Network, error) {\n\tpath := \"/networks/\" + id\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchNetwork{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar network Network\n\tif err := json.NewDecoder(resp.Body).Decode(&network); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &network, nil\n}\n\n// CreateNetworkOptions specify parameters to the CreateNetwork function and\n// (for now) is the expected body of the \"create network\" http request message\n//\n// See https://goo.gl/6GugX3 for more details.\ntype CreateNetworkOptions struct {\n\tName           string             `json:\"Name\" yaml:\"Name\" toml:\"Name\"`\n\tDriver         string             `json:\"Driver\" yaml:\"Driver\" toml:\"Driver\"`\n\tScope          string             `json:\"Scope\" yaml:\"Scope\" toml:\"Scope\"`\n\tIPAM           *IPAMOptions       `json:\"IPAM,omitempty\" yaml:\"IPAM\" toml:\"IPAM\"`\n\tConfigFrom     *NetworkConfigFrom `json:\"ConfigFrom,omitempty\" yaml:\"ConfigFrom\" toml:\"ConfigFrom\"`\n\tOptions        map[string]any     `json:\"Options\" yaml:\"Options\" toml:\"Options\"`\n\tLabels         map[string]string  `json:\"Labels\" yaml:\"Labels\" toml:\"Labels\"`\n\tCheckDuplicate bool               `json:\"CheckDuplicate\" yaml:\"CheckDuplicate\" toml:\"CheckDuplicate\"`\n\tInternal       bool               `json:\"Internal\" yaml:\"Internal\" toml:\"Internal\"`\n\tEnableIPv6     bool               `json:\"EnableIPv6\" yaml:\"EnableIPv6\" toml:\"EnableIPv6\"`\n\tAttachable     bool               `json:\"Attachable\" yaml:\"Attachable\" toml:\"Attachable\"`\n\tConfigOnly     bool               `json:\"ConfigOnly\" yaml:\"ConfigOnly\" toml:\"ConfigOnly\"`\n\tIngress        bool               `json:\"Ingress\" yaml:\"Ingress\" toml:\"Ingress\"`\n\tContext        context.Context    `json:\"-\"`\n}\n\n// NetworkConfigFrom is used in network creation for specifying the source of a\n// network configuration.\ntype NetworkConfigFrom struct {\n\tNetwork string `json:\"Network\" yaml:\"Network\" toml:\"Network\"`\n}\n\n// IPAMOptions controls IP Address Management when creating a network\n//\n// See https://goo.gl/T8kRVH for more details.\ntype IPAMOptions struct {\n\tDriver  string            `json:\"Driver\" yaml:\"Driver\" toml:\"Driver\"`\n\tConfig  []IPAMConfig      `json:\"Config\" yaml:\"Config\" toml:\"Config\"`\n\tOptions map[string]string `json:\"Options\" yaml:\"Options\" toml:\"Options\"`\n}\n\n// IPAMConfig represents IPAM configurations\n//\n// See https://goo.gl/T8kRVH for more details.\ntype IPAMConfig struct {\n\tSubnet     string            `json:\",omitempty\"`\n\tIPRange    string            `json:\",omitempty\"`\n\tGateway    string            `json:\",omitempty\"`\n\tAuxAddress map[string]string `json:\"AuxiliaryAddresses,omitempty\"`\n}\n\n// CreateNetwork creates a new network, returning the network instance,\n// or an error in case of failure.\n//\n// See https://goo.gl/6GugX3 for more details.\nfunc (c *Client) CreateNetwork(opts CreateNetworkOptions) (*Network, error) {\n\tresp, err := c.do(\n\t\thttp.MethodPost,\n\t\t\"/networks/create\",\n\t\tdoOptions{\n\t\t\tdata:    opts,\n\t\t\tcontext: opts.Context,\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\ttype createNetworkResponse struct {\n\t\tID string\n\t}\n\tvar (\n\t\tnetwork Network\n\t\tcnr     createNetworkResponse\n\t)\n\tif err := json.NewDecoder(resp.Body).Decode(&cnr); err != nil {\n\t\treturn nil, err\n\t}\n\n\tnetwork.Name = opts.Name\n\tnetwork.ID = cnr.ID\n\tnetwork.Driver = opts.Driver\n\n\treturn &network, nil\n}\n\n// RemoveNetwork removes a network or returns an error in case of failure.\n//\n// See https://goo.gl/6GugX3 for more details.\nfunc (c *Client) RemoveNetwork(id string) error {\n\tresp, err := c.do(http.MethodDelete, \"/networks/\"+id, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchNetwork{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// NetworkConnectionOptions specify parameters to the ConnectNetwork and\n// DisconnectNetwork function.\n//\n// See https://goo.gl/RV7BJU for more details.\ntype NetworkConnectionOptions struct {\n\tContainer string\n\n\t// EndpointConfig is only applicable to the ConnectNetwork call\n\tEndpointConfig *EndpointConfig `json:\"EndpointConfig,omitempty\"`\n\n\t// Force is only applicable to the DisconnectNetwork call\n\tForce bool\n\n\tContext context.Context `json:\"-\"`\n}\n\n// EndpointConfig stores network endpoint details\n//\n// See https://goo.gl/RV7BJU for more details.\ntype EndpointConfig struct {\n\tIPAMConfig          *EndpointIPAMConfig `json:\"IPAMConfig,omitempty\" yaml:\"IPAMConfig,omitempty\" toml:\"IPAMConfig,omitempty\"`\n\tLinks               []string            `json:\"Links,omitempty\" yaml:\"Links,omitempty\" toml:\"Links,omitempty\"`\n\tAliases             []string            `json:\"Aliases,omitempty\" yaml:\"Aliases,omitempty\" toml:\"Aliases,omitempty\"`\n\tNetworkID           string              `json:\"NetworkID,omitempty\" yaml:\"NetworkID,omitempty\" toml:\"NetworkID,omitempty\"`\n\tEndpointID          string              `json:\"EndpointID,omitempty\" yaml:\"EndpointID,omitempty\" toml:\"EndpointID,omitempty\"`\n\tGateway             string              `json:\"Gateway,omitempty\" yaml:\"Gateway,omitempty\" toml:\"Gateway,omitempty\"`\n\tIPAddress           string              `json:\"IPAddress,omitempty\" yaml:\"IPAddress,omitempty\" toml:\"IPAddress,omitempty\"`\n\tIPPrefixLen         int                 `json:\"IPPrefixLen,omitempty\" yaml:\"IPPrefixLen,omitempty\" toml:\"IPPrefixLen,omitempty\"`\n\tIPv6Gateway         string              `json:\"IPv6Gateway,omitempty\" yaml:\"IPv6Gateway,omitempty\" toml:\"IPv6Gateway,omitempty\"`\n\tGlobalIPv6Address   string              `json:\"GlobalIPv6Address,omitempty\" yaml:\"GlobalIPv6Address,omitempty\" toml:\"GlobalIPv6Address,omitempty\"`\n\tGlobalIPv6PrefixLen int                 `json:\"GlobalIPv6PrefixLen,omitempty\" yaml:\"GlobalIPv6PrefixLen,omitempty\" toml:\"GlobalIPv6PrefixLen,omitempty\"`\n\tMacAddress          string              `json:\"MacAddress,omitempty\" yaml:\"MacAddress,omitempty\" toml:\"MacAddress,omitempty\"`\n\tDriverOpts          map[string]string   `json:\"DriverOpts,omitempty\" yaml:\"DriverOpts,omitempty\" toml:\"DriverOpts,omitempty\"`\n}\n\n// EndpointIPAMConfig represents IPAM configurations for an\n// endpoint\n//\n// See https://goo.gl/RV7BJU for more details.\ntype EndpointIPAMConfig struct {\n\tIPv4Address string `json:\",omitempty\" yaml:\"IPv4Address,omitempty\"`\n\tIPv6Address string `json:\",omitempty\" yaml:\"IPv6Address,omitempty\"`\n}\n\n// ConnectNetwork adds a container to a network or returns an error in case of\n// failure.\n//\n// See https://goo.gl/6GugX3 for more details.\nfunc (c *Client) ConnectNetwork(id string, opts NetworkConnectionOptions) error {\n\tresp, err := c.do(http.MethodPost, \"/networks/\"+id+\"/connect\", doOptions{\n\t\tdata:    opts,\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// DisconnectNetwork removes a container from a network or returns an error in\n// case of failure.\n//\n// See https://goo.gl/6GugX3 for more details.\nfunc (c *Client) DisconnectNetwork(id string, opts NetworkConnectionOptions) error {\n\tresp, err := c.do(http.MethodPost, \"/networks/\"+id+\"/disconnect\", doOptions{data: opts})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchNetworkOrContainer{NetworkID: id, ContainerID: opts.Container}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// PruneNetworksOptions specify parameters to the PruneNetworks function.\n//\n// See https://goo.gl/kX0S9h for more details.\ntype PruneNetworksOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// PruneNetworksResults specify results from the PruneNetworks function.\n//\n// See https://goo.gl/kX0S9h for more details.\ntype PruneNetworksResults struct {\n\tNetworksDeleted []string\n}\n\n// PruneNetworks deletes networks which are unused.\n//\n// See https://goo.gl/kX0S9h for more details.\nfunc (c *Client) PruneNetworks(opts PruneNetworksOptions) (*PruneNetworksResults, error) {\n\tpath := \"/networks/prune?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar results PruneNetworksResults\n\tif err := json.NewDecoder(resp.Body).Decode(&results); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &results, nil\n}\n\n// NoSuchNetwork is the error returned when a given network does not exist.\ntype NoSuchNetwork struct {\n\tID string\n}\n\nfunc (err *NoSuchNetwork) Error() string {\n\treturn fmt.Sprintf(\"No such network: %s\", err.ID)\n}\n\n// NoSuchNetworkOrContainer is the error returned when a given network or\n// container does not exist.\ntype NoSuchNetworkOrContainer struct {\n\tNetworkID   string\n\tContainerID string\n}\n\nfunc (err *NoSuchNetworkOrContainer) Error() string {\n\treturn fmt.Sprintf(\"No such network (%s) or container (%s)\", err.NetworkID, err.ContainerID)\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/plugin.go",
    "content": "// Copyright 2018 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n)\n\n// PluginPrivilege represents a privilege for a plugin.\ntype PluginPrivilege struct {\n\tName        string   `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tDescription string   `json:\"Description,omitempty\" yaml:\"Description,omitempty\" toml:\"Description,omitempty\"`\n\tValue       []string `json:\"Value,omitempty\" yaml:\"Value,omitempty\" toml:\"Value,omitempty\"`\n}\n\n// InstallPluginOptions specify parameters to the InstallPlugins function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype InstallPluginOptions struct {\n\tRemote  string\n\tName    string\n\tPlugins []PluginPrivilege `qs:\"-\"`\n\n\tAuth AuthConfiguration\n\n\tContext context.Context\n}\n\n// InstallPlugins installs a plugin or returns an error in case of failure.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) InstallPlugins(opts InstallPluginOptions) error {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpath := \"/plugins/pull?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tdata:    opts.Plugins,\n\t\tcontext: opts.Context,\n\t\theaders: headers,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\t// PullPlugin streams back the progress of the pull, we must consume the whole body\n\t// otherwise the pull will be canceled on the engine.\n\tif _, err := io.ReadAll(resp.Body); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// PluginSettings stores plugin settings.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginSettings struct {\n\tEnv     []string `json:\"Env,omitempty\" yaml:\"Env,omitempty\" toml:\"Env,omitempty\"`\n\tArgs    []string `json:\"Args,omitempty\" yaml:\"Args,omitempty\" toml:\"Args,omitempty\"`\n\tDevices []string `json:\"Devices,omitempty\" yaml:\"Devices,omitempty\" toml:\"Devices,omitempty\"`\n}\n\n// PluginInterface stores plugin interface.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginInterface struct {\n\tTypes  []string `json:\"Types,omitempty\" yaml:\"Types,omitempty\" toml:\"Types,omitempty\"`\n\tSocket string   `json:\"Socket,omitempty\" yaml:\"Socket,omitempty\" toml:\"Socket,omitempty\"`\n}\n\n// PluginNetwork stores plugin network type.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginNetwork struct {\n\tType string `json:\"Type,omitempty\" yaml:\"Type,omitempty\" toml:\"Type,omitempty\"`\n}\n\n// PluginLinux stores plugin linux setting.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginLinux struct {\n\tCapabilities    []string             `json:\"Capabilities,omitempty\" yaml:\"Capabilities,omitempty\" toml:\"Capabilities,omitempty\"`\n\tAllowAllDevices bool                 `json:\"AllowAllDevices,omitempty\" yaml:\"AllowAllDevices,omitempty\" toml:\"AllowAllDevices,omitempty\"`\n\tDevices         []PluginLinuxDevices `json:\"Devices,omitempty\" yaml:\"Devices,omitempty\" toml:\"Devices,omitempty\"`\n}\n\n// PluginLinuxDevices stores plugin linux device setting.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginLinuxDevices struct {\n\tName        string   `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tDescription string   `json:\"Documentation,omitempty\" yaml:\"Documentation,omitempty\" toml:\"Documentation,omitempty\"`\n\tSettable    []string `json:\"Settable,omitempty\" yaml:\"Settable,omitempty\" toml:\"Settable,omitempty\"`\n\tPath        string   `json:\"Path,omitempty\" yaml:\"Path,omitempty\" toml:\"Path,omitempty\"`\n}\n\n// PluginEnv stores plugin environment.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginEnv struct {\n\tName        string   `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tDescription string   `json:\"Description,omitempty\" yaml:\"Description,omitempty\" toml:\"Description,omitempty\"`\n\tSettable    []string `json:\"Settable,omitempty\" yaml:\"Settable,omitempty\" toml:\"Settable,omitempty\"`\n\tValue       string   `json:\"Value,omitempty\" yaml:\"Value,omitempty\" toml:\"Value,omitempty\"`\n}\n\n// PluginArgs stores plugin arguments.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginArgs struct {\n\tName        string   `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tDescription string   `json:\"Description,omitempty\" yaml:\"Description,omitempty\" toml:\"Description,omitempty\"`\n\tSettable    []string `json:\"Settable,omitempty\" yaml:\"Settable,omitempty\" toml:\"Settable,omitempty\"`\n\tValue       []string `json:\"Value,omitempty\" yaml:\"Value,omitempty\" toml:\"Value,omitempty\"`\n}\n\n// PluginUser stores plugin user.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginUser struct {\n\tUID int32 `json:\"UID,omitempty\" yaml:\"UID,omitempty\" toml:\"UID,omitempty\"`\n\tGID int32 `json:\"GID,omitempty\" yaml:\"GID,omitempty\" toml:\"GID,omitempty\"`\n}\n\n// PluginConfig stores plugin config.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginConfig struct {\n\tDescription     string `json:\"Description,omitempty\" yaml:\"Description,omitempty\" toml:\"Description,omitempty\"`\n\tDocumentation   string\n\tInterface       PluginInterface `json:\"Interface,omitempty\" yaml:\"Interface,omitempty\" toml:\"Interface,omitempty\"`\n\tEntrypoint      []string        `json:\"Entrypoint,omitempty\" yaml:\"Entrypoint,omitempty\" toml:\"Entrypoint,omitempty\"`\n\tWorkDir         string          `json:\"WorkDir,omitempty\" yaml:\"WorkDir,omitempty\" toml:\"WorkDir,omitempty\"`\n\tUser            PluginUser      `json:\"User,omitempty\" yaml:\"User,omitempty\" toml:\"User,omitempty\"`\n\tNetwork         PluginNetwork   `json:\"Network,omitempty\" yaml:\"Network,omitempty\" toml:\"Network,omitempty\"`\n\tLinux           PluginLinux     `json:\"Linux,omitempty\" yaml:\"Linux,omitempty\" toml:\"Linux,omitempty\"`\n\tPropagatedMount string          `json:\"PropagatedMount,omitempty\" yaml:\"PropagatedMount,omitempty\" toml:\"PropagatedMount,omitempty\"`\n\tMounts          []Mount         `json:\"Mounts,omitempty\" yaml:\"Mounts,omitempty\" toml:\"Mounts,omitempty\"`\n\tEnv             []PluginEnv     `json:\"Env,omitempty\" yaml:\"Env,omitempty\" toml:\"Env,omitempty\"`\n\tArgs            PluginArgs      `json:\"Args,omitempty\" yaml:\"Args,omitempty\" toml:\"Args,omitempty\"`\n}\n\n// PluginDetail specify results from the ListPlugins function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PluginDetail struct {\n\tID       string         `json:\"Id,omitempty\" yaml:\"Id,omitempty\" toml:\"Id,omitempty\"`\n\tName     string         `json:\"Name,omitempty\" yaml:\"Name,omitempty\" toml:\"Name,omitempty\"`\n\tTag      string         `json:\"Tag,omitempty\" yaml:\"Tag,omitempty\" toml:\"Tag,omitempty\"`\n\tActive   bool           `json:\"Enabled,omitempty\" yaml:\"Active,omitempty\" toml:\"Active,omitempty\"`\n\tSettings PluginSettings `json:\"Settings,omitempty\" yaml:\"Settings,omitempty\" toml:\"Settings,omitempty\"`\n\tConfig   PluginConfig   `json:\"Config,omitempty\" yaml:\"Config,omitempty\" toml:\"Config,omitempty\"`\n}\n\n// ListPlugins returns pluginDetails or an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) ListPlugins(ctx context.Context) ([]PluginDetail, error) {\n\tresp, err := c.do(http.MethodGet, \"/plugins\", doOptions{\n\t\tcontext: ctx,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tpluginDetails := make([]PluginDetail, 0)\n\tif err := json.NewDecoder(resp.Body).Decode(&pluginDetails); err != nil {\n\t\treturn nil, err\n\t}\n\treturn pluginDetails, nil\n}\n\n// ListFilteredPluginsOptions specify parameters to the ListFilteredPlugins function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype ListFilteredPluginsOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// ListFilteredPlugins returns pluginDetails or an error.\n//\n// See https://goo.gl/rmdmWg for more details.\nfunc (c *Client) ListFilteredPlugins(opts ListFilteredPluginsOptions) ([]PluginDetail, error) {\n\tpath := \"/plugins/json?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tpluginDetails := make([]PluginDetail, 0)\n\tif err := json.NewDecoder(resp.Body).Decode(&pluginDetails); err != nil {\n\t\treturn nil, err\n\t}\n\treturn pluginDetails, nil\n}\n\n// GetPluginPrivileges returns pluginPrivileges or an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) GetPluginPrivileges(remote string, ctx context.Context) ([]PluginPrivilege, error) {\n\treturn c.GetPluginPrivilegesWithOptions(\n\t\tGetPluginPrivilegesOptions{\n\t\t\tRemote:  remote,\n\t\t\tContext: ctx,\n\t\t})\n}\n\n// GetPluginPrivilegesOptions specify parameters to the GetPluginPrivilegesWithOptions function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype GetPluginPrivilegesOptions struct {\n\tRemote  string\n\tAuth    AuthConfiguration\n\tContext context.Context\n}\n\n// GetPluginPrivilegesWithOptions returns pluginPrivileges or an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) GetPluginPrivilegesWithOptions(opts GetPluginPrivilegesOptions) ([]PluginPrivilege, error) {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpath := \"/plugins/privileges?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{\n\t\tcontext: opts.Context,\n\t\theaders: headers,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar pluginPrivileges []PluginPrivilege\n\tif err := json.NewDecoder(resp.Body).Decode(&pluginPrivileges); err != nil {\n\t\treturn nil, err\n\t}\n\treturn pluginPrivileges, nil\n}\n\n// InspectPlugins returns a pluginDetail or an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) InspectPlugins(name string, ctx context.Context) (*PluginDetail, error) {\n\tresp, err := c.do(http.MethodGet, \"/plugins/\"+name+\"/json\", doOptions{\n\t\tcontext: ctx,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchPlugin{ID: name}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar pluginDetail PluginDetail\n\tif err := json.NewDecoder(resp.Body).Decode(&pluginDetail); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &pluginDetail, nil\n}\n\n// RemovePluginOptions specify parameters to the RemovePlugin function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype RemovePluginOptions struct {\n\t// The Name of the plugin.\n\tName string `qs:\"-\"`\n\n\tForce   bool `qs:\"force\"`\n\tContext context.Context\n}\n\n// RemovePlugin returns a PluginDetail or an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) RemovePlugin(opts RemovePluginOptions) (*PluginDetail, error) {\n\tpath := \"/plugins/\" + opts.Name + \"?\" + queryString(opts)\n\tresp, err := c.do(http.MethodDelete, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchPlugin{ID: opts.Name}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif len(body) == 0 {\n\t\t// Seems like newer docker versions won't return the plugindetail after removal\n\t\treturn nil, nil\n\t}\n\n\tvar pluginDetail PluginDetail\n\tif err := json.Unmarshal(body, &pluginDetail); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &pluginDetail, nil\n}\n\n// EnablePluginOptions specify parameters to the EnablePlugin function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype EnablePluginOptions struct {\n\t// The Name of the plugin.\n\tName    string `qs:\"-\"`\n\tTimeout int64  `qs:\"timeout\"`\n\n\tContext context.Context\n}\n\n// EnablePlugin enables plugin that opts point or returns an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) EnablePlugin(opts EnablePluginOptions) error {\n\tpath := \"/plugins/\" + opts.Name + \"/enable?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// DisablePluginOptions specify parameters to the DisablePlugin function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype DisablePluginOptions struct {\n\t// The Name of the plugin.\n\tName string `qs:\"-\"`\n\n\tContext context.Context\n}\n\n// DisablePlugin disables plugin that opts point or returns an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) DisablePlugin(opts DisablePluginOptions) error {\n\tpath := \"/plugins/\" + opts.Name + \"/disable\"\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// CreatePluginOptions specify parameters to the CreatePlugin function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype CreatePluginOptions struct {\n\t// The Name of the plugin.\n\tName string `qs:\"name\"`\n\t// Path to tar containing plugin\n\tPath string `qs:\"-\"`\n\n\tContext context.Context\n}\n\n// CreatePlugin creates plugin that opts point or returns an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) CreatePlugin(opts CreatePluginOptions) (string, error) {\n\tpath := \"/plugins/create?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tdata:    opts.Path,\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\tcontainerNameBytes, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(containerNameBytes), nil\n}\n\n// PushPluginOptions specify parameters to PushPlugin function.\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype PushPluginOptions struct {\n\t// The Name of the plugin.\n\tName string\n\n\tContext context.Context\n}\n\n// PushPlugin pushes plugin that opts point or returns an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) PushPlugin(opts PushPluginOptions) error {\n\tpath := \"/plugins/\" + opts.Name + \"/push\"\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// ConfigurePluginOptions specify parameters to the ConfigurePlugin\n//\n// See https://goo.gl/C4t7Tz for more details.\ntype ConfigurePluginOptions struct {\n\t// The Name of the plugin.\n\tName string `qs:\"name\"`\n\tEnvs []string\n\n\tContext context.Context\n}\n\n// ConfigurePlugin configures plugin that opts point or returns an error.\n//\n// See https://goo.gl/C4t7Tz for more details.\nfunc (c *Client) ConfigurePlugin(opts ConfigurePluginOptions) error {\n\tpath := \"/plugins/\" + opts.Name + \"/set\"\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tdata:    opts.Envs,\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchPlugin{ID: opts.Name}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// NoSuchPlugin is the error returned when a given plugin does not exist.\ntype NoSuchPlugin struct {\n\tID  string\n\tErr error\n}\n\nfunc (err *NoSuchPlugin) Error() string {\n\tif err.Err != nil {\n\t\treturn err.Err.Error()\n\t}\n\treturn \"No such plugin: \" + err.ID\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/registry_auth.go",
    "content": "// Copyright 2013 go-dockerclient 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 docker\n\ntype registryAuth interface {\n\tisEmpty() bool\n\theaderKey() string\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/signal.go",
    "content": "// Copyright 2014 go-dockerclient 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 docker\n\n// Signal represents a signal that can be send to the container on\n// KillContainer call.\ntype Signal int\n\n// These values represent all signals available on Linux, where containers will\n// be running.\nconst (\n\tSIGABRT   = Signal(0x6)\n\tSIGALRM   = Signal(0xe)\n\tSIGBUS    = Signal(0x7)\n\tSIGCHLD   = Signal(0x11)\n\tSIGCLD    = Signal(0x11)\n\tSIGCONT   = Signal(0x12)\n\tSIGFPE    = Signal(0x8)\n\tSIGHUP    = Signal(0x1)\n\tSIGILL    = Signal(0x4)\n\tSIGINT    = Signal(0x2)\n\tSIGIO     = Signal(0x1d)\n\tSIGIOT    = Signal(0x6)\n\tSIGKILL   = Signal(0x9)\n\tSIGPIPE   = Signal(0xd)\n\tSIGPOLL   = Signal(0x1d)\n\tSIGPROF   = Signal(0x1b)\n\tSIGPWR    = Signal(0x1e)\n\tSIGQUIT   = Signal(0x3)\n\tSIGSEGV   = Signal(0xb)\n\tSIGSTKFLT = Signal(0x10)\n\tSIGSTOP   = Signal(0x13)\n\tSIGSYS    = Signal(0x1f)\n\tSIGTERM   = Signal(0xf)\n\tSIGTRAP   = Signal(0x5)\n\tSIGTSTP   = Signal(0x14)\n\tSIGTTIN   = Signal(0x15)\n\tSIGTTOU   = Signal(0x16)\n\tSIGUNUSED = Signal(0x1f)\n\tSIGURG    = Signal(0x17)\n\tSIGUSR1   = Signal(0xa)\n\tSIGUSR2   = Signal(0xc)\n\tSIGVTALRM = Signal(0x1a)\n\tSIGWINCH  = Signal(0x1c)\n\tSIGXCPU   = Signal(0x18)\n\tSIGXFSZ   = Signal(0x19)\n)\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/swarm.go",
    "content": "// Copyright 2016 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\nvar (\n\t// ErrNodeAlreadyInSwarm is the error returned by InitSwarm and JoinSwarm\n\t// when the node is already part of a Swarm.\n\tErrNodeAlreadyInSwarm = errors.New(\"node already in a Swarm\")\n\n\t// ErrNodeNotInSwarm is the error returned by LeaveSwarm and UpdateSwarm\n\t// when the node is not part of a Swarm.\n\tErrNodeNotInSwarm = errors.New(\"node is not in a Swarm\")\n)\n\n// InitSwarmOptions specify parameters to the InitSwarm function.\n// See https://goo.gl/hzkgWu for more details.\ntype InitSwarmOptions struct {\n\tswarm.InitRequest\n\tContext context.Context\n}\n\n// InitSwarm initializes a new Swarm and returns the node ID.\n// See https://goo.gl/ZWyG1M for more details.\nfunc (c *Client) InitSwarm(opts InitSwarmOptions) (string, error) {\n\tpath := \"/swarm/init\"\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tdata:      opts.InitRequest,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && (e.Status == http.StatusNotAcceptable || e.Status == http.StatusServiceUnavailable) {\n\t\t\treturn \"\", ErrNodeAlreadyInSwarm\n\t\t}\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\tvar response string\n\tif err := json.NewDecoder(resp.Body).Decode(&response); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn response, nil\n}\n\n// JoinSwarmOptions specify parameters to the JoinSwarm function.\n// See https://goo.gl/TdhJWU for more details.\ntype JoinSwarmOptions struct {\n\tswarm.JoinRequest\n\tContext context.Context\n}\n\n// JoinSwarm joins an existing Swarm.\n// See https://goo.gl/N59IP1 for more details.\nfunc (c *Client) JoinSwarm(opts JoinSwarmOptions) error {\n\tpath := \"/swarm/join\"\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tdata:      opts.JoinRequest,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && (e.Status == http.StatusNotAcceptable || e.Status == http.StatusServiceUnavailable) {\n\t\t\treturn ErrNodeAlreadyInSwarm\n\t\t}\n\t}\n\tresp.Body.Close()\n\treturn err\n}\n\n// LeaveSwarmOptions specify parameters to the LeaveSwarm function.\n// See https://goo.gl/UWDlLg for more details.\ntype LeaveSwarmOptions struct {\n\tForce   bool\n\tContext context.Context\n}\n\n// LeaveSwarm leaves a Swarm.\n// See https://goo.gl/FTX1aD for more details.\nfunc (c *Client) LeaveSwarm(opts LeaveSwarmOptions) error {\n\tparams := make(url.Values)\n\tparams.Set(\"force\", strconv.FormatBool(opts.Force))\n\tpath := \"/swarm/leave?\" + params.Encode()\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && (e.Status == http.StatusNotAcceptable || e.Status == http.StatusServiceUnavailable) {\n\t\t\treturn ErrNodeNotInSwarm\n\t\t}\n\t}\n\tresp.Body.Close()\n\treturn err\n}\n\n// UpdateSwarmOptions specify parameters to the UpdateSwarm function.\n// See https://goo.gl/vFbq36 for more details.\ntype UpdateSwarmOptions struct {\n\tVersion            int\n\tRotateWorkerToken  bool\n\tRotateManagerToken bool\n\tSwarm              swarm.Spec\n\tContext            context.Context\n}\n\n// UpdateSwarm updates a Swarm.\n// See https://goo.gl/iJFnsw for more details.\nfunc (c *Client) UpdateSwarm(opts UpdateSwarmOptions) error {\n\tparams := make(url.Values)\n\tparams.Set(\"version\", strconv.Itoa(opts.Version))\n\tparams.Set(\"rotateWorkerToken\", strconv.FormatBool(opts.RotateWorkerToken))\n\tparams.Set(\"rotateManagerToken\", strconv.FormatBool(opts.RotateManagerToken))\n\tpath := \"/swarm/update?\" + params.Encode()\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tdata:      opts.Swarm,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && (e.Status == http.StatusNotAcceptable || e.Status == http.StatusServiceUnavailable) {\n\t\t\treturn ErrNodeNotInSwarm\n\t\t}\n\t}\n\tresp.Body.Close()\n\treturn err\n}\n\n// InspectSwarm inspects a Swarm.\n// See https://goo.gl/MFwgX9 for more details.\nfunc (c *Client) InspectSwarm(ctx context.Context) (swarm.Swarm, error) {\n\tresponse := swarm.Swarm{}\n\tresp, err := c.do(http.MethodGet, \"/swarm\", doOptions{\n\t\tcontext: ctx,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && (e.Status == http.StatusNotAcceptable || e.Status == http.StatusServiceUnavailable) {\n\t\t\treturn response, ErrNodeNotInSwarm\n\t\t}\n\t\treturn response, err\n\t}\n\tdefer resp.Body.Close()\n\terr = json.NewDecoder(resp.Body).Decode(&response)\n\treturn response, err\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/swarm_configs.go",
    "content": "// Copyright 2017 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NoSuchConfig is the error returned when a given config does not exist.\ntype NoSuchConfig struct {\n\tID  string\n\tErr error\n}\n\nfunc (err *NoSuchConfig) Error() string {\n\tif err.Err != nil {\n\t\treturn err.Err.Error()\n\t}\n\treturn \"No such config: \" + err.ID\n}\n\n// CreateConfigOptions specify parameters to the CreateConfig function.\n//\n// See https://goo.gl/KrVjHz for more details.\ntype CreateConfigOptions struct {\n\tAuth AuthConfiguration `qs:\"-\"`\n\tswarm.ConfigSpec\n\tContext context.Context\n}\n\n// CreateConfig creates a new config, returning the config instance\n// or an error in case of failure.\n//\n// See https://goo.gl/KrVjHz for more details.\nfunc (c *Client) CreateConfig(opts CreateConfigOptions) (*swarm.Config, error) {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpath := \"/configs/create?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\theaders:   headers,\n\t\tdata:      opts.ConfigSpec,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar config swarm.Config\n\tif err := json.NewDecoder(resp.Body).Decode(&config); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &config, nil\n}\n\n// RemoveConfigOptions encapsulates options to remove a config.\n//\n// See https://goo.gl/Tqrtya for more details.\ntype RemoveConfigOptions struct {\n\tID      string `qs:\"-\"`\n\tContext context.Context\n}\n\n// RemoveConfig removes a config, returning an error in case of failure.\n//\n// See https://goo.gl/Tqrtya for more details.\nfunc (c *Client) RemoveConfig(opts RemoveConfigOptions) error {\n\tpath := \"/configs/\" + opts.ID\n\tresp, err := c.do(http.MethodDelete, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchConfig{ID: opts.ID}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// UpdateConfigOptions specify parameters to the UpdateConfig function.\n//\n// See https://goo.gl/wu3MmS for more details.\ntype UpdateConfigOptions struct {\n\tAuth AuthConfiguration `qs:\"-\"`\n\tswarm.ConfigSpec\n\tContext context.Context\n\tVersion uint64\n}\n\n// UpdateConfig updates the config at ID with the options\n//\n// Only label can be updated\n// https://docs.docker.com/engine/api/v1.33/#operation/ConfigUpdate\n// See https://goo.gl/wu3MmS for more details.\nfunc (c *Client) UpdateConfig(id string, opts UpdateConfigOptions) error {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\tparams := make(url.Values)\n\tparams.Set(\"version\", strconv.FormatUint(opts.Version, 10))\n\tresp, err := c.do(http.MethodPost, \"/configs/\"+id+\"/update?\"+params.Encode(), doOptions{\n\t\theaders:   headers,\n\t\tdata:      opts.ConfigSpec,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchConfig{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\treturn nil\n}\n\n// InspectConfig returns information about a config by its ID.\n//\n// See https://goo.gl/dHmr75 for more details.\nfunc (c *Client) InspectConfig(id string) (*swarm.Config, error) {\n\tpath := \"/configs/\" + id\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchConfig{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar config swarm.Config\n\tif err := json.NewDecoder(resp.Body).Decode(&config); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &config, nil\n}\n\n// ListConfigsOptions specify parameters to the ListConfigs function.\n//\n// See https://goo.gl/DwvNMd for more details.\ntype ListConfigsOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// ListConfigs returns a slice of configs matching the given criteria.\n//\n// See https://goo.gl/DwvNMd for more details.\nfunc (c *Client) ListConfigs(opts ListConfigsOptions) ([]swarm.Config, error) {\n\tpath := \"/configs?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar configs []swarm.Config\n\tif err := json.NewDecoder(resp.Body).Decode(&configs); err != nil {\n\t\treturn nil, err\n\t}\n\treturn configs, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/swarm_node.go",
    "content": "// Copyright 2016 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NoSuchNode is the error returned when a given node does not exist.\ntype NoSuchNode struct {\n\tID  string\n\tErr error\n}\n\nfunc (err *NoSuchNode) Error() string {\n\tif err.Err != nil {\n\t\treturn err.Err.Error()\n\t}\n\treturn \"No such node: \" + err.ID\n}\n\n// ListNodesOptions specify parameters to the ListNodes function.\n//\n// See http://goo.gl/3K4GwU for more details.\ntype ListNodesOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// ListNodes returns a slice of nodes matching the given criteria.\n//\n// See http://goo.gl/3K4GwU for more details.\nfunc (c *Client) ListNodes(opts ListNodesOptions) ([]swarm.Node, error) {\n\tpath := \"/nodes?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar nodes []swarm.Node\n\tif err := json.NewDecoder(resp.Body).Decode(&nodes); err != nil {\n\t\treturn nil, err\n\t}\n\treturn nodes, nil\n}\n\n// InspectNode returns information about a node by its ID.\n//\n// See http://goo.gl/WjkTOk for more details.\nfunc (c *Client) InspectNode(id string) (*swarm.Node, error) {\n\tresp, err := c.do(http.MethodGet, \"/nodes/\"+id, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchNode{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar node swarm.Node\n\tif err := json.NewDecoder(resp.Body).Decode(&node); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &node, nil\n}\n\n// UpdateNodeOptions specify parameters to the NodeUpdate function.\n//\n// See http://goo.gl/VPBFgA for more details.\ntype UpdateNodeOptions struct {\n\tswarm.NodeSpec\n\tVersion uint64\n\tContext context.Context\n}\n\n// UpdateNode updates a node.\n//\n// See http://goo.gl/VPBFgA for more details.\nfunc (c *Client) UpdateNode(id string, opts UpdateNodeOptions) error {\n\tparams := make(url.Values)\n\tparams.Set(\"version\", strconv.FormatUint(opts.Version, 10))\n\tpath := \"/nodes/\" + id + \"/update?\" + params.Encode()\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\tcontext:   opts.Context,\n\t\tforceJSON: true,\n\t\tdata:      opts.NodeSpec,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchNode{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// RemoveNodeOptions specify parameters to the RemoveNode function.\n//\n// See http://goo.gl/0SNvYg for more details.\ntype RemoveNodeOptions struct {\n\tID      string\n\tForce   bool\n\tContext context.Context\n}\n\n// RemoveNode removes a node.\n//\n// See http://goo.gl/0SNvYg for more details.\nfunc (c *Client) RemoveNode(opts RemoveNodeOptions) error {\n\tparams := make(url.Values)\n\tparams.Set(\"force\", strconv.FormatBool(opts.Force))\n\tpath := \"/nodes/\" + opts.ID + \"?\" + params.Encode()\n\tresp, err := c.do(http.MethodDelete, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchNode{ID: opts.ID}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/swarm_secrets.go",
    "content": "// Copyright 2016 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strconv\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NoSuchSecret is the error returned when a given secret does not exist.\ntype NoSuchSecret struct {\n\tID  string\n\tErr error\n}\n\nfunc (err *NoSuchSecret) Error() string {\n\tif err.Err != nil {\n\t\treturn err.Err.Error()\n\t}\n\treturn \"No such secret: \" + err.ID\n}\n\n// CreateSecretOptions specify parameters to the CreateSecret function.\n//\n// See https://goo.gl/KrVjHz for more details.\ntype CreateSecretOptions struct {\n\tAuth AuthConfiguration `qs:\"-\"`\n\tswarm.SecretSpec\n\tContext context.Context\n}\n\n// CreateSecret creates a new secret, returning the secret instance\n// or an error in case of failure.\n//\n// See https://goo.gl/KrVjHz for more details.\nfunc (c *Client) CreateSecret(opts CreateSecretOptions) (*swarm.Secret, error) {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpath := \"/secrets/create?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\theaders:   headers,\n\t\tdata:      opts.SecretSpec,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar secret swarm.Secret\n\tif err := json.NewDecoder(resp.Body).Decode(&secret); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &secret, nil\n}\n\n// RemoveSecretOptions encapsulates options to remove a secret.\n//\n// See https://goo.gl/Tqrtya for more details.\ntype RemoveSecretOptions struct {\n\tID      string `qs:\"-\"`\n\tContext context.Context\n}\n\n// RemoveSecret removes a secret, returning an error in case of failure.\n//\n// See https://goo.gl/Tqrtya for more details.\nfunc (c *Client) RemoveSecret(opts RemoveSecretOptions) error {\n\tpath := \"/secrets/\" + opts.ID\n\tresp, err := c.do(http.MethodDelete, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchSecret{ID: opts.ID}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// UpdateSecretOptions specify parameters to the UpdateSecret function.\n//\n// Only label can be updated\n// See https://docs.docker.com/engine/api/v1.33/#operation/SecretUpdate\n// See https://goo.gl/wu3MmS for more details.\ntype UpdateSecretOptions struct {\n\tAuth AuthConfiguration `qs:\"-\"`\n\tswarm.SecretSpec\n\tContext context.Context\n\tVersion uint64\n}\n\n// UpdateSecret updates the secret at ID with the options\n//\n// See https://goo.gl/wu3MmS for more details.\nfunc (c *Client) UpdateSecret(id string, opts UpdateSecretOptions) error {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\tparams := make(url.Values)\n\tparams.Set(\"version\", strconv.FormatUint(opts.Version, 10))\n\tresp, err := c.do(http.MethodPost, \"/secrets/\"+id+\"/update?\"+params.Encode(), doOptions{\n\t\theaders:   headers,\n\t\tdata:      opts.SecretSpec,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchSecret{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\treturn nil\n}\n\n// InspectSecret returns information about a secret by its ID.\n//\n// See https://goo.gl/dHmr75 for more details.\nfunc (c *Client) InspectSecret(id string) (*swarm.Secret, error) {\n\tpath := \"/secrets/\" + id\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchSecret{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar secret swarm.Secret\n\tif err := json.NewDecoder(resp.Body).Decode(&secret); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &secret, nil\n}\n\n// ListSecretsOptions specify parameters to the ListSecrets function.\n//\n// See https://goo.gl/DwvNMd for more details.\ntype ListSecretsOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// ListSecrets returns a slice of secrets matching the given criteria.\n//\n// See https://goo.gl/DwvNMd for more details.\nfunc (c *Client) ListSecrets(opts ListSecretsOptions) ([]swarm.Secret, error) {\n\tpath := \"/secrets?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar secrets []swarm.Secret\n\tif err := json.NewDecoder(resp.Body).Decode(&secrets); err != nil {\n\t\treturn nil, err\n\t}\n\treturn secrets, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/swarm_service.go",
    "content": "// Copyright 2016 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NoSuchService is the error returned when a given service does not exist.\ntype NoSuchService struct {\n\tID  string\n\tErr error\n}\n\nfunc (err *NoSuchService) Error() string {\n\tif err.Err != nil {\n\t\treturn err.Err.Error()\n\t}\n\treturn \"No such service: \" + err.ID\n}\n\n// CreateServiceOptions specify parameters to the CreateService function.\n//\n// See https://goo.gl/KrVjHz for more details.\ntype CreateServiceOptions struct {\n\tAuth AuthConfiguration `qs:\"-\"`\n\tswarm.ServiceSpec\n\tContext context.Context\n}\n\n// CreateService creates a new service, returning the service instance\n// or an error in case of failure.\n//\n// See https://goo.gl/KrVjHz for more details.\nfunc (c *Client) CreateService(opts CreateServiceOptions) (*swarm.Service, error) {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpath := \"/services/create?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{\n\t\theaders:   headers,\n\t\tdata:      opts.ServiceSpec,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar service swarm.Service\n\tif err := json.NewDecoder(resp.Body).Decode(&service); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &service, nil\n}\n\n// RemoveServiceOptions encapsulates options to remove a service.\n//\n// See https://goo.gl/Tqrtya for more details.\ntype RemoveServiceOptions struct {\n\tID      string `qs:\"-\"`\n\tContext context.Context\n}\n\n// RemoveService removes a service, returning an error in case of failure.\n//\n// See https://goo.gl/Tqrtya for more details.\nfunc (c *Client) RemoveService(opts RemoveServiceOptions) error {\n\tpath := \"/services/\" + opts.ID\n\tresp, err := c.do(http.MethodDelete, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchService{ID: opts.ID}\n\t\t}\n\t\treturn err\n\t}\n\tresp.Body.Close()\n\treturn nil\n}\n\n// UpdateServiceOptions specify parameters to the UpdateService function.\n//\n// See https://goo.gl/wu3MmS for more details.\ntype UpdateServiceOptions struct {\n\tAuth              AuthConfiguration `qs:\"-\"`\n\tswarm.ServiceSpec `qs:\"-\"`\n\tContext           context.Context\n\tVersion           uint64\n\tRollback          string\n}\n\n// UpdateService updates the service at ID with the options\n//\n// See https://goo.gl/wu3MmS for more details.\nfunc (c *Client) UpdateService(id string, opts UpdateServiceOptions) error {\n\theaders, err := headersWithAuth(opts.Auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\tresp, err := c.do(http.MethodPost, \"/services/\"+id+\"/update?\"+queryString(opts), doOptions{\n\t\theaders:   headers,\n\t\tdata:      opts.ServiceSpec,\n\t\tforceJSON: true,\n\t\tcontext:   opts.Context,\n\t})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn &NoSuchService{ID: id}\n\t\t}\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\treturn nil\n}\n\n// InspectService returns information about a service by its ID.\n//\n// See https://goo.gl/dHmr75 for more details.\nfunc (c *Client) InspectService(id string) (*swarm.Service, error) {\n\tpath := \"/services/\" + id\n\tresp, err := c.do(http.MethodGet, path, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchService{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar service swarm.Service\n\tif err := json.NewDecoder(resp.Body).Decode(&service); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &service, nil\n}\n\n// ListServicesOptions specify parameters to the ListServices function.\n//\n// See https://goo.gl/DwvNMd for more details.\ntype ListServicesOptions struct {\n\tFilters map[string][]string\n\tStatus  bool\n\tContext context.Context\n}\n\n// ListServices returns a slice of services matching the given criteria.\n//\n// See https://goo.gl/DwvNMd for more details.\nfunc (c *Client) ListServices(opts ListServicesOptions) ([]swarm.Service, error) {\n\tpath := \"/services?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar services []swarm.Service\n\tif err := json.NewDecoder(resp.Body).Decode(&services); err != nil {\n\t\treturn nil, err\n\t}\n\treturn services, nil\n}\n\n// LogsServiceOptions represents the set of options used when getting logs from a\n// service.\ntype LogsServiceOptions struct {\n\tContext           context.Context\n\tService           string        `qs:\"-\"`\n\tOutputStream      io.Writer     `qs:\"-\"`\n\tErrorStream       io.Writer     `qs:\"-\"`\n\tInactivityTimeout time.Duration `qs:\"-\"`\n\tTail              string\n\tSince             int64\n\n\t// Use raw terminal? Usually true when the container contains a TTY.\n\tRawTerminal bool `qs:\"-\"`\n\tFollow      bool\n\tStdout      bool\n\tStderr      bool\n\tTimestamps  bool\n\tDetails     bool\n}\n\n// GetServiceLogs gets stdout and stderr logs from the specified service.\n//\n// When LogsServiceOptions.RawTerminal is set to false, go-dockerclient will multiplex\n// the streams and send the containers stdout to LogsServiceOptions.OutputStream, and\n// stderr to LogsServiceOptions.ErrorStream.\n//\n// When LogsServiceOptions.RawTerminal is true, callers will get the raw stream on\n// LogsServiceOptions.OutputStream.\nfunc (c *Client) GetServiceLogs(opts LogsServiceOptions) error {\n\tif opts.Service == \"\" {\n\t\treturn &NoSuchService{ID: opts.Service}\n\t}\n\tif opts.Tail == \"\" {\n\t\topts.Tail = \"all\"\n\t}\n\tpath := \"/services/\" + opts.Service + \"/logs?\" + queryString(opts)\n\treturn c.stream(http.MethodGet, path, streamOptions{\n\t\tsetRawTerminal:    opts.RawTerminal,\n\t\tstdout:            opts.OutputStream,\n\t\tstderr:            opts.ErrorStream,\n\t\tinactivityTimeout: opts.InactivityTimeout,\n\t\tcontext:           opts.Context,\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/swarm_task.go",
    "content": "// Copyright 2016 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\n\t\"github.com/docker/docker/api/types/swarm\"\n)\n\n// NoSuchTask is the error returned when a given task does not exist.\ntype NoSuchTask struct {\n\tID  string\n\tErr error\n}\n\nfunc (err *NoSuchTask) Error() string {\n\tif err.Err != nil {\n\t\treturn err.Err.Error()\n\t}\n\treturn \"No such task: \" + err.ID\n}\n\n// ListTasksOptions specify parameters to the ListTasks function.\n//\n// See http://goo.gl/rByLzw for more details.\ntype ListTasksOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// ListTasks returns a slice of tasks matching the given criteria.\n//\n// See http://goo.gl/rByLzw for more details.\nfunc (c *Client) ListTasks(opts ListTasksOptions) ([]swarm.Task, error) {\n\tpath := \"/tasks?\" + queryString(opts)\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar tasks []swarm.Task\n\tif err := json.NewDecoder(resp.Body).Decode(&tasks); err != nil {\n\t\treturn nil, err\n\t}\n\treturn tasks, nil\n}\n\n// InspectTask returns information about a task by its ID.\n//\n// See http://goo.gl/kyziuq for more details.\nfunc (c *Client) InspectTask(id string) (*swarm.Task, error) {\n\tresp, err := c.do(http.MethodGet, \"/tasks/\"+id, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, &NoSuchTask{ID: id}\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar task swarm.Task\n\tif err := json.NewDecoder(resp.Body).Decode(&task); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &task, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/system.go",
    "content": "package docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\n// VolumeUsageData represents usage data from the docker system api\n// More Info Here https://dockr.ly/2PNzQyO\ntype VolumeUsageData struct {\n\t// The number of containers referencing this volume. This field\n\t// is set to `-1` if the reference-count is not available.\n\t//\n\t// Required: true\n\tRefCount int64 `json:\"RefCount\"`\n\n\t// Amount of disk space used by the volume (in bytes). This information\n\t// is only available for volumes created with the `\"local\"` volume\n\t// driver. For volumes created with other volume drivers, this field\n\t// is set to `-1` (\"not available\")\n\t//\n\t// Required: true\n\tSize int64 `json:\"Size\"`\n}\n\n// ImageSummary represents data about what images are\n// currently known to docker\n// More Info Here https://dockr.ly/2PNzQyO\ntype ImageSummary struct {\n\tContainers  int64             `json:\"Containers\"`\n\tCreated     int64             `json:\"Created\"`\n\tID          string            `json:\"Id\"`\n\tLabels      map[string]string `json:\"Labels\"`\n\tParentID    string            `json:\"ParentId\"`\n\tRepoDigests []string          `json:\"RepoDigests\"`\n\tRepoTags    []string          `json:\"RepoTags\"`\n\tSharedSize  int64             `json:\"SharedSize\"`\n\tSize        int64             `json:\"Size\"`\n\tVirtualSize int64             `json:\"VirtualSize\"`\n}\n\n// DiskUsage holds information about what docker is using disk space on.\n// More Info Here https://dockr.ly/2PNzQyO\ntype DiskUsage struct {\n\tLayersSize int64\n\tImages     []*ImageSummary\n\tContainers []*APIContainers\n\tVolumes    []*Volume\n}\n\n// DiskUsageOptions only contains a context for canceling.\ntype DiskUsageOptions struct {\n\tContext context.Context\n}\n\n// DiskUsage returns a *DiskUsage describing what docker is using disk on.\n//\n// More Info Here https://dockr.ly/2PNzQyO\nfunc (c *Client) DiskUsage(opts DiskUsageOptions) (*DiskUsage, error) {\n\tpath := \"/system/df\"\n\tresp, err := c.do(http.MethodGet, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar du *DiskUsage\n\tif err := json.NewDecoder(resp.Body).Decode(&du); err != nil {\n\t\treturn nil, err\n\t}\n\treturn du, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/tar.go",
    "content": "// Copyright 2014 go-dockerclient 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 docker\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/pkg/archive\"\n\t\"github.com/moby/patternmatcher\"\n)\n\nfunc createTarStream(srcPath, dockerfilePath string) (io.ReadCloser, error) {\n\tsrcPath, err := filepath.Abs(srcPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\texcludes, err := parseDockerignore(srcPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tincludes := []string{\".\"}\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 deamon will remove them for us, if needed, after it\n\t// parses the Dockerfile.\n\t//\n\t// https://github.com/docker/docker/issues/8330\n\t//\n\tforceIncludeFiles := []string{\".dockerignore\", dockerfilePath}\n\n\tfor _, includeFile := range forceIncludeFiles {\n\t\tif includeFile == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tkeepThem, err := patternmatcher.Matches(includeFile, excludes)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot match .dockerfileignore: '%s', error: %w\", includeFile, err)\n\t\t}\n\t\tif keepThem {\n\t\t\tincludes = append(includes, includeFile)\n\t\t}\n\t}\n\n\tif err := validateContextDirectory(srcPath, excludes); err != nil {\n\t\treturn nil, err\n\t}\n\ttarOpts := &archive.TarOptions{\n\t\tExcludePatterns: excludes,\n\t\tIncludeFiles:    includes,\n\t\tCompression:     archive.Uncompressed,\n\t\tNoLchown:        true,\n\t}\n\treturn archive.TarWithOptions(srcPath, tarOpts)\n}\n\n// validateContextDirectory checks if all the contents of the directory\n// can be read and returns an error if some files can't be read.\n// Symlinks which point to non-existing files don't trigger an error\nfunc validateContextDirectory(srcPath string, excludes []string) error {\n\treturn filepath.Walk(filepath.Join(srcPath, \".\"), func(filePath string, f os.FileInfo, err error) error {\n\t\t// skip this directory/file if it's not in the path, it won't get added to the context\n\t\tif relFilePath, relErr := filepath.Rel(srcPath, filePath); relErr != nil {\n\t\t\treturn relErr\n\t\t} else if skip, matchErr := patternmatcher.Matches(relFilePath, excludes); matchErr != nil {\n\t\t\treturn matchErr\n\t\t} else if skip {\n\t\t\tif f.IsDir() {\n\t\t\t\treturn filepath.SkipDir\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif err != nil {\n\t\t\tif os.IsPermission(err) {\n\t\t\t\treturn fmt.Errorf(\"cannot stat %q: %w\", filePath, err)\n\t\t\t}\n\t\t\tif os.IsNotExist(err) {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\t// skip checking if symlinks point to non-existing files, such symlinks can be useful\n\t\t// also skip named pipes, because they hanging on open\n\t\tif f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\tif !f.IsDir() {\n\t\t\tcurrentFile, err := os.Open(filePath)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"cannot open %q for reading: %w\", filePath, err)\n\t\t\t}\n\t\t\tcurrentFile.Close()\n\t\t}\n\t\treturn nil\n\t})\n}\n\nfunc parseDockerignore(root string) ([]string, error) {\n\tvar excludes []string\n\tignore, err := os.ReadFile(path.Join(root, \".dockerignore\"))\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn excludes, fmt.Errorf(\"error reading .dockerignore: %w\", err)\n\t}\n\texcludes = strings.Split(string(ignore), \"\\n\")\n\n\treturn excludes, nil\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/tls.go",
    "content": "// Copyright 2014 go-dockerclient 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// The content is borrowed from Docker's own source code to provide a simple\n// tls based dialer\n\npackage docker\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"net\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype tlsClientCon struct {\n\t*tls.Conn\n\trawConn net.Conn\n}\n\nfunc (c *tlsClientCon) CloseWrite() error {\n\t// Go standard tls.Conn doesn't provide the CloseWrite() method so we do it\n\t// on its underlying connection.\n\tif cwc, ok := c.rawConn.(interface {\n\t\tCloseWrite() error\n\t}); ok {\n\t\treturn cwc.CloseWrite()\n\t}\n\treturn nil\n}\n\nfunc tlsDialWithDialer(dialer *net.Dialer, network, addr string, config *tls.Config) (net.Conn, error) {\n\t// We want the Timeout and Deadline values from dialer to cover the\n\t// whole process: TCP connection and TLS handshake. This means that we\n\t// also need to start our own timers now.\n\ttimeout := dialer.Timeout\n\n\tif !dialer.Deadline.IsZero() {\n\t\tdeadlineTimeout := time.Until(dialer.Deadline)\n\t\tif timeout == 0 || deadlineTimeout < timeout {\n\t\t\ttimeout = deadlineTimeout\n\t\t}\n\t}\n\n\tvar errChannel chan error\n\n\tif timeout != 0 {\n\t\terrChannel = make(chan error, 2)\n\t\ttime.AfterFunc(timeout, func() {\n\t\t\terrChannel <- errors.New(\"\")\n\t\t})\n\t}\n\n\trawConn, err := dialer.Dial(network, addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcolonPos := strings.LastIndex(addr, \":\")\n\tif colonPos == -1 {\n\t\tcolonPos = len(addr)\n\t}\n\thostname := addr[:colonPos]\n\n\t// If no ServerName is set, infer the ServerName\n\t// from the hostname we're connecting to.\n\tif config.ServerName == \"\" {\n\t\t// Make a copy to avoid polluting argument or default.\n\t\tconfig = copyTLSConfig(config)\n\t\tconfig.ServerName = hostname\n\t}\n\n\tconn := tls.Client(rawConn, config)\n\n\tif timeout == 0 {\n\t\terr = conn.Handshake()\n\t} else {\n\t\tgo func() {\n\t\t\terrChannel <- conn.Handshake()\n\t\t}()\n\n\t\terr = <-errChannel\n\t}\n\n\tif err != nil {\n\t\trawConn.Close()\n\t\treturn nil, err\n\t}\n\n\t// This is Docker difference with standard's crypto/tls package: returned a\n\t// wrapper which holds both the TLS and raw connections.\n\treturn &tlsClientCon{conn, rawConn}, nil\n}\n\n// this exists to silent an error message in go vet\nfunc copyTLSConfig(cfg *tls.Config) *tls.Config {\n\treturn &tls.Config{\n\t\tCertificates:           cfg.Certificates,\n\t\tCipherSuites:           cfg.CipherSuites,\n\t\tClientAuth:             cfg.ClientAuth,\n\t\tClientCAs:              cfg.ClientCAs,\n\t\tClientSessionCache:     cfg.ClientSessionCache,\n\t\tCurvePreferences:       cfg.CurvePreferences,\n\t\tInsecureSkipVerify:     cfg.InsecureSkipVerify,\n\t\tMaxVersion:             cfg.MaxVersion,\n\t\tMinVersion:             cfg.MinVersion,\n\t\tNextProtos:             cfg.NextProtos,\n\t\tRand:                   cfg.Rand,\n\t\tRootCAs:                cfg.RootCAs,\n\t\tServerName:             cfg.ServerName,\n\t\tSessionTicketsDisabled: cfg.SessionTicketsDisabled,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/fsouza/go-dockerclient/volume.go",
    "content": "// Copyright 2015 go-dockerclient 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 docker\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"net/http\"\n\t\"time\"\n)\n\nvar (\n\t// ErrNoSuchVolume is the error returned when the volume does not exist.\n\tErrNoSuchVolume = errors.New(\"no such volume\")\n\n\t// ErrVolumeInUse is the error returned when the volume requested to be removed is still in use.\n\tErrVolumeInUse = errors.New(\"volume in use and cannot be removed\")\n)\n\n// Volume represents a volume.\n//\n// See https://goo.gl/3wgTsd for more details.\ntype Volume struct {\n\tName       string            `json:\"Name\" yaml:\"Name\" toml:\"Name\"`\n\tDriver     string            `json:\"Driver,omitempty\" yaml:\"Driver,omitempty\" toml:\"Driver,omitempty\"`\n\tMountpoint string            `json:\"Mountpoint,omitempty\" yaml:\"Mountpoint,omitempty\" toml:\"Mountpoint,omitempty\"`\n\tLabels     map[string]string `json:\"Labels,omitempty\" yaml:\"Labels,omitempty\" toml:\"Labels,omitempty\"`\n\tOptions    map[string]string `json:\"Options,omitempty\" yaml:\"Options,omitempty\" toml:\"Options,omitempty\"`\n\tCreatedAt  time.Time         `json:\"CreatedAt,omitempty\" yaml:\"CreatedAt,omitempty\" toml:\"CreatedAt,omitempty\"`\n}\n\n// ListVolumesOptions specify parameters to the ListVolumes function.\n//\n// See https://goo.gl/3wgTsd for more details.\ntype ListVolumesOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// ListVolumes returns a list of available volumes in the server.\n//\n// See https://goo.gl/3wgTsd for more details.\nfunc (c *Client) ListVolumes(opts ListVolumesOptions) ([]Volume, error) {\n\tresp, err := c.do(http.MethodGet, \"/volumes?\"+queryString(opts), doOptions{\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tm := make(map[string]any)\n\tif err = json.NewDecoder(resp.Body).Decode(&m); err != nil {\n\t\treturn nil, err\n\t}\n\tvar volumes []Volume\n\tvolumesJSON, ok := m[\"Volumes\"]\n\tif !ok {\n\t\treturn volumes, nil\n\t}\n\tdata, err := json.Marshal(volumesJSON)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := json.Unmarshal(data, &volumes); err != nil {\n\t\treturn nil, err\n\t}\n\treturn volumes, nil\n}\n\n// CreateVolumeOptions specify parameters to the CreateVolume function.\n//\n// See https://goo.gl/qEhmEC for more details.\ntype CreateVolumeOptions struct {\n\tName       string\n\tDriver     string\n\tDriverOpts map[string]string\n\tContext    context.Context `json:\"-\"`\n\tLabels     map[string]string\n}\n\n// CreateVolume creates a volume on the server.\n//\n// See https://goo.gl/qEhmEC for more details.\nfunc (c *Client) CreateVolume(opts CreateVolumeOptions) (*Volume, error) {\n\tresp, err := c.do(http.MethodPost, \"/volumes/create\", doOptions{\n\t\tdata:    opts,\n\t\tcontext: opts.Context,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar volume Volume\n\tif err := json.NewDecoder(resp.Body).Decode(&volume); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &volume, nil\n}\n\n// InspectVolume returns a volume by its name.\n//\n// See https://goo.gl/GMjsMc for more details.\nfunc (c *Client) InspectVolume(name string) (*Volume, error) {\n\tresp, err := c.do(http.MethodGet, \"/volumes/\"+name, doOptions{})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) && e.Status == http.StatusNotFound {\n\t\t\treturn nil, ErrNoSuchVolume\n\t\t}\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar volume Volume\n\tif err := json.NewDecoder(resp.Body).Decode(&volume); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &volume, nil\n}\n\n// RemoveVolume removes a volume by its name.\n//\n// Deprecated: Use RemoveVolumeWithOptions instead.\nfunc (c *Client) RemoveVolume(name string) error {\n\treturn c.RemoveVolumeWithOptions(RemoveVolumeOptions{Name: name})\n}\n\n// RemoveVolumeOptions specify parameters to the RemoveVolumeWithOptions\n// function.\n//\n// See https://goo.gl/nvd6qj for more details.\ntype RemoveVolumeOptions struct {\n\tContext context.Context\n\tName    string `qs:\"-\"`\n\tForce   bool\n}\n\n// RemoveVolumeWithOptions removes a volume by its name and takes extra\n// parameters.\n//\n// See https://goo.gl/nvd6qj for more details.\nfunc (c *Client) RemoveVolumeWithOptions(opts RemoveVolumeOptions) error {\n\tpath := \"/volumes/\" + opts.Name\n\tresp, err := c.do(http.MethodDelete, path+\"?\"+queryString(opts), doOptions{context: opts.Context})\n\tif err != nil {\n\t\tvar e *Error\n\t\tif errors.As(err, &e) {\n\t\t\tif e.Status == http.StatusNotFound {\n\t\t\t\treturn ErrNoSuchVolume\n\t\t\t}\n\t\t\tif e.Status == http.StatusConflict {\n\t\t\t\treturn ErrVolumeInUse\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\treturn nil\n}\n\n// PruneVolumesOptions specify parameters to the PruneVolumes function.\n//\n// See https://goo.gl/f9XDem for more details.\ntype PruneVolumesOptions struct {\n\tFilters map[string][]string\n\tContext context.Context\n}\n\n// PruneVolumesResults specify results from the PruneVolumes function.\n//\n// See https://goo.gl/f9XDem for more details.\ntype PruneVolumesResults struct {\n\tVolumesDeleted []string\n\tSpaceReclaimed int64\n}\n\n// PruneVolumes deletes volumes which are unused.\n//\n// See https://goo.gl/f9XDem for more details.\nfunc (c *Client) PruneVolumes(opts PruneVolumesOptions) (*PruneVolumesResults, error) {\n\tpath := \"/volumes/prune?\" + queryString(opts)\n\tresp, err := c.do(http.MethodPost, path, doOptions{context: opts.Context})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\tvar results PruneVolumesResults\n\tif err := json.NewDecoder(resp.Body).Decode(&results); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &results, nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017-2018 the project authors.\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": "vendor/github.com/getkin/kin-openapi/openapi2/doc.go",
    "content": "// Package openapi2 parses and writes OpenAPIv2 specification documents.\n//\n// Does not cover all elements of OpenAPIv2.\n// When OpenAPI version 3 is backwards-compatible with version 2, version 3 elements have been used.\n//\n// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md\npackage openapi2\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/header.go",
    "content": "package openapi2\n\ntype Header struct {\n\tParameter\n}\n\n// MarshalJSON returns the JSON encoding of Header.\nfunc (header Header) MarshalJSON() ([]byte, error) {\n\treturn header.Parameter.MarshalJSON()\n}\n\n// UnmarshalJSON sets Header to a copy of data.\nfunc (header *Header) UnmarshalJSON(data []byte) error {\n\treturn header.Parameter.UnmarshalJSON(data)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/helpers.go",
    "content": "package openapi2\n\nimport (\n\t\"net/url\"\n)\n\n// copyURI makes a copy of the pointer.\nfunc copyURI(u *url.URL) *url.URL {\n\tif u == nil {\n\t\treturn nil\n\t}\n\n\tc := *u // shallow-copy\n\treturn &c\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/marsh.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/oasdiff/yaml\"\n)\n\nfunc unmarshalError(jsonUnmarshalErr error) error {\n\tif before, after, found := strings.Cut(jsonUnmarshalErr.Error(), \"Bis\"); found && before != \"\" && after != \"\" {\n\t\tbefore = strings.ReplaceAll(before, \" Go struct \", \" \")\n\t\treturn fmt.Errorf(\"%s%s\", before, strings.ReplaceAll(after, \"Bis\", \"\"))\n\t}\n\treturn jsonUnmarshalErr\n}\n\nfunc unmarshal(data []byte, v any) error {\n\tvar jsonErr, yamlErr error\n\n\t// See https://github.com/getkin/kin-openapi/issues/680\n\tif jsonErr = json.Unmarshal(data, v); jsonErr == nil {\n\t\treturn nil\n\t}\n\n\t// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys\n\tif yamlErr = yaml.Unmarshal(data, v); yamlErr == nil {\n\t\treturn nil\n\t}\n\n\t// If both unmarshaling attempts fail, return a new error that includes both errors\n\treturn fmt.Errorf(\"failed to unmarshal data: json error: %v, yaml error: %v\", jsonErr, yamlErr)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/openapi2.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\n// T is the root of an OpenAPI v2 document\ntype T struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tSwagger             string                     `json:\"swagger\" yaml:\"swagger\"` // required\n\tInfo                openapi3.Info              `json:\"info\" yaml:\"info\"`       // required\n\tExternalDocs        *openapi3.ExternalDocs     `json:\"externalDocs,omitempty\" yaml:\"externalDocs,omitempty\"`\n\tSchemes             []string                   `json:\"schemes,omitempty\" yaml:\"schemes,omitempty\"`\n\tConsumes            []string                   `json:\"consumes,omitempty\" yaml:\"consumes,omitempty\"`\n\tProduces            []string                   `json:\"produces,omitempty\" yaml:\"produces,omitempty\"`\n\tHost                string                     `json:\"host,omitempty\" yaml:\"host,omitempty\"`\n\tBasePath            string                     `json:\"basePath,omitempty\" yaml:\"basePath,omitempty\"`\n\tPaths               map[string]*PathItem       `json:\"paths,omitempty\" yaml:\"paths,omitempty\"`\n\tDefinitions         map[string]*SchemaRef      `json:\"definitions,omitempty\" yaml:\"definitions,omitempty\"`\n\tParameters          map[string]*Parameter      `json:\"parameters,omitempty\" yaml:\"parameters,omitempty\"`\n\tResponses           map[string]*Response       `json:\"responses,omitempty\" yaml:\"responses,omitempty\"`\n\tSecurityDefinitions map[string]*SecurityScheme `json:\"securityDefinitions,omitempty\" yaml:\"securityDefinitions,omitempty\"`\n\tSecurity            SecurityRequirements       `json:\"security,omitempty\" yaml:\"security,omitempty\"`\n\tTags                openapi3.Tags              `json:\"tags,omitempty\" yaml:\"tags,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of T.\nfunc (doc T) MarshalJSON() ([]byte, error) {\n\tm := make(map[string]any, 15+len(doc.Extensions))\n\tfor k, v := range doc.Extensions {\n\t\tm[k] = v\n\t}\n\tm[\"swagger\"] = doc.Swagger\n\tm[\"info\"] = doc.Info\n\tif x := doc.ExternalDocs; x != nil {\n\t\tm[\"externalDocs\"] = x\n\t}\n\tif x := doc.Schemes; len(x) != 0 {\n\t\tm[\"schemes\"] = x\n\t}\n\tif x := doc.Consumes; len(x) != 0 {\n\t\tm[\"consumes\"] = x\n\t}\n\tif x := doc.Produces; len(x) != 0 {\n\t\tm[\"produces\"] = x\n\t}\n\tif x := doc.Host; x != \"\" {\n\t\tm[\"host\"] = x\n\t}\n\tif x := doc.BasePath; x != \"\" {\n\t\tm[\"basePath\"] = x\n\t}\n\tif x := doc.Paths; len(x) != 0 {\n\t\tm[\"paths\"] = x\n\t}\n\tif x := doc.Definitions; len(x) != 0 {\n\t\tm[\"definitions\"] = x\n\t}\n\tif x := doc.Parameters; len(x) != 0 {\n\t\tm[\"parameters\"] = x\n\t}\n\tif x := doc.Responses; len(x) != 0 {\n\t\tm[\"responses\"] = x\n\t}\n\tif x := doc.SecurityDefinitions; len(x) != 0 {\n\t\tm[\"securityDefinitions\"] = x\n\t}\n\tif x := doc.Security; len(x) != 0 {\n\t\tm[\"security\"] = x\n\t}\n\tif x := doc.Tags; len(x) != 0 {\n\t\tm[\"tags\"] = x\n\t}\n\treturn json.Marshal(m)\n}\n\n// UnmarshalJSON sets T to a copy of data.\nfunc (doc *T) UnmarshalJSON(data []byte) error {\n\ttype TBis T\n\tvar x TBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, \"swagger\")\n\tdelete(x.Extensions, \"info\")\n\tdelete(x.Extensions, \"externalDocs\")\n\tdelete(x.Extensions, \"schemes\")\n\tdelete(x.Extensions, \"consumes\")\n\tdelete(x.Extensions, \"produces\")\n\tdelete(x.Extensions, \"host\")\n\tdelete(x.Extensions, \"basePath\")\n\tdelete(x.Extensions, \"paths\")\n\tdelete(x.Extensions, \"definitions\")\n\tdelete(x.Extensions, \"parameters\")\n\tdelete(x.Extensions, \"responses\")\n\tdelete(x.Extensions, \"securityDefinitions\")\n\tdelete(x.Extensions, \"security\")\n\tdelete(x.Extensions, \"tags\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*doc = T(x)\n\treturn nil\n}\n\nfunc (doc *T) AddOperation(path string, method string, operation *Operation) {\n\tif doc.Paths == nil {\n\t\tdoc.Paths = make(map[string]*PathItem)\n\t}\n\tpathItem := doc.Paths[path]\n\tif pathItem == nil {\n\t\tpathItem = &PathItem{}\n\t\tdoc.Paths[path] = pathItem\n\t}\n\tpathItem.SetOperation(method, operation)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/operation.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\ntype Operation struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tSummary      string                 `json:\"summary,omitempty\" yaml:\"summary,omitempty\"`\n\tDescription  string                 `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tDeprecated   bool                   `json:\"deprecated,omitempty\" yaml:\"deprecated,omitempty\"`\n\tExternalDocs *openapi3.ExternalDocs `json:\"externalDocs,omitempty\" yaml:\"externalDocs,omitempty\"`\n\tTags         []string               `json:\"tags,omitempty\" yaml:\"tags,omitempty\"`\n\tOperationID  string                 `json:\"operationId,omitempty\" yaml:\"operationId,omitempty\"`\n\tParameters   Parameters             `json:\"parameters,omitempty\" yaml:\"parameters,omitempty\"`\n\tResponses    map[string]*Response   `json:\"responses\" yaml:\"responses\"`\n\tConsumes     []string               `json:\"consumes,omitempty\" yaml:\"consumes,omitempty\"`\n\tProduces     []string               `json:\"produces,omitempty\" yaml:\"produces,omitempty\"`\n\tSchemes      []string               `json:\"schemes,omitempty\" yaml:\"schemes,omitempty\"`\n\tSecurity     *SecurityRequirements  `json:\"security,omitempty\" yaml:\"security,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Operation.\nfunc (operation Operation) MarshalJSON() ([]byte, error) {\n\tm := make(map[string]any, 12+len(operation.Extensions))\n\tfor k, v := range operation.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := operation.Summary; x != \"\" {\n\t\tm[\"summary\"] = x\n\t}\n\tif x := operation.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := operation.Deprecated; x {\n\t\tm[\"deprecated\"] = x\n\t}\n\tif x := operation.ExternalDocs; x != nil {\n\t\tm[\"externalDocs\"] = x\n\t}\n\tif x := operation.Tags; len(x) != 0 {\n\t\tm[\"tags\"] = x\n\t}\n\tif x := operation.OperationID; x != \"\" {\n\t\tm[\"operationId\"] = x\n\t}\n\tif x := operation.Parameters; len(x) != 0 {\n\t\tm[\"parameters\"] = x\n\t}\n\tm[\"responses\"] = operation.Responses\n\tif x := operation.Consumes; len(x) != 0 {\n\t\tm[\"consumes\"] = x\n\t}\n\tif x := operation.Produces; len(x) != 0 {\n\t\tm[\"produces\"] = x\n\t}\n\tif x := operation.Schemes; len(x) != 0 {\n\t\tm[\"schemes\"] = x\n\t}\n\tif x := operation.Security; x != nil {\n\t\tm[\"security\"] = x\n\t}\n\treturn json.Marshal(m)\n}\n\n// UnmarshalJSON sets Operation to a copy of data.\nfunc (operation *Operation) UnmarshalJSON(data []byte) error {\n\ttype OperationBis Operation\n\tvar x OperationBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, \"summary\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"deprecated\")\n\tdelete(x.Extensions, \"externalDocs\")\n\tdelete(x.Extensions, \"tags\")\n\tdelete(x.Extensions, \"operationId\")\n\tdelete(x.Extensions, \"parameters\")\n\tdelete(x.Extensions, \"responses\")\n\tdelete(x.Extensions, \"consumes\")\n\tdelete(x.Extensions, \"produces\")\n\tdelete(x.Extensions, \"schemes\")\n\tdelete(x.Extensions, \"security\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*operation = Operation(x)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/parameter.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\t\"sort\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\ntype Parameters []*Parameter\n\nvar _ sort.Interface = Parameters{}\n\nfunc (ps Parameters) Len() int      { return len(ps) }\nfunc (ps Parameters) Swap(i, j int) { ps[i], ps[j] = ps[j], ps[i] }\nfunc (ps Parameters) Less(i, j int) bool {\n\tif ps[i].Name != ps[j].Name {\n\t\treturn ps[i].Name < ps[j].Name\n\t}\n\tif ps[i].In != ps[j].In {\n\t\treturn ps[i].In < ps[j].In\n\t}\n\treturn ps[i].Ref < ps[j].Ref\n}\n\ntype Parameter struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tRef string `json:\"$ref,omitempty\" yaml:\"$ref,omitempty\"`\n\n\tIn               string          `json:\"in,omitempty\" yaml:\"in,omitempty\"`\n\tName             string          `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tDescription      string          `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tCollectionFormat string          `json:\"collectionFormat,omitempty\" yaml:\"collectionFormat,omitempty\"`\n\tType             *openapi3.Types `json:\"type,omitempty\" yaml:\"type,omitempty\"`\n\tFormat           string          `json:\"format,omitempty\" yaml:\"format,omitempty\"`\n\tPattern          string          `json:\"pattern,omitempty\" yaml:\"pattern,omitempty\"`\n\tAllowEmptyValue  bool            `json:\"allowEmptyValue,omitempty\" yaml:\"allowEmptyValue,omitempty\"`\n\tRequired         bool            `json:\"required,omitempty\" yaml:\"required,omitempty\"`\n\tUniqueItems      bool            `json:\"uniqueItems,omitempty\" yaml:\"uniqueItems,omitempty\"`\n\tExclusiveMin     bool            `json:\"exclusiveMinimum,omitempty\" yaml:\"exclusiveMinimum,omitempty\"`\n\tExclusiveMax     bool            `json:\"exclusiveMaximum,omitempty\" yaml:\"exclusiveMaximum,omitempty\"`\n\tSchema           *SchemaRef      `json:\"schema,omitempty\" yaml:\"schema,omitempty\"`\n\tItems            *SchemaRef      `json:\"items,omitempty\" yaml:\"items,omitempty\"`\n\tEnum             []any           `json:\"enum,omitempty\" yaml:\"enum,omitempty\"`\n\tMultipleOf       *float64        `json:\"multipleOf,omitempty\" yaml:\"multipleOf,omitempty\"`\n\tMinimum          *float64        `json:\"minimum,omitempty\" yaml:\"minimum,omitempty\"`\n\tMaximum          *float64        `json:\"maximum,omitempty\" yaml:\"maximum,omitempty\"`\n\tMaxLength        *uint64         `json:\"maxLength,omitempty\" yaml:\"maxLength,omitempty\"`\n\tMaxItems         *uint64         `json:\"maxItems,omitempty\" yaml:\"maxItems,omitempty\"`\n\tMinLength        uint64          `json:\"minLength,omitempty\" yaml:\"minLength,omitempty\"`\n\tMinItems         uint64          `json:\"minItems,omitempty\" yaml:\"minItems,omitempty\"`\n\tDefault          any             `json:\"default,omitempty\" yaml:\"default,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Parameter.\nfunc (parameter Parameter) MarshalJSON() ([]byte, error) {\n\tif ref := parameter.Ref; ref != \"\" {\n\t\treturn json.Marshal(openapi3.Ref{Ref: ref})\n\t}\n\n\tm := make(map[string]any, 24+len(parameter.Extensions))\n\tfor k, v := range parameter.Extensions {\n\t\tm[k] = v\n\t}\n\n\tif x := parameter.In; x != \"\" {\n\t\tm[\"in\"] = x\n\t}\n\tif x := parameter.Name; x != \"\" {\n\t\tm[\"name\"] = x\n\t}\n\tif x := parameter.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := parameter.CollectionFormat; x != \"\" {\n\t\tm[\"collectionFormat\"] = x\n\t}\n\tif x := parameter.Type; x != nil {\n\t\tm[\"type\"] = x\n\t}\n\tif x := parameter.Format; x != \"\" {\n\t\tm[\"format\"] = x\n\t}\n\tif x := parameter.Pattern; x != \"\" {\n\t\tm[\"pattern\"] = x\n\t}\n\tif x := parameter.AllowEmptyValue; x {\n\t\tm[\"allowEmptyValue\"] = x\n\t}\n\tif x := parameter.Required; x {\n\t\tm[\"required\"] = x\n\t}\n\tif x := parameter.UniqueItems; x {\n\t\tm[\"uniqueItems\"] = x\n\t}\n\tif x := parameter.ExclusiveMin; x {\n\t\tm[\"exclusiveMinimum\"] = x\n\t}\n\tif x := parameter.ExclusiveMax; x {\n\t\tm[\"exclusiveMaximum\"] = x\n\t}\n\tif x := parameter.Schema; x != nil {\n\t\tm[\"schema\"] = x\n\t}\n\tif x := parameter.Items; x != nil {\n\t\tm[\"items\"] = x\n\t}\n\tif x := parameter.Enum; x != nil {\n\t\tm[\"enum\"] = x\n\t}\n\tif x := parameter.MultipleOf; x != nil {\n\t\tm[\"multipleOf\"] = x\n\t}\n\tif x := parameter.Minimum; x != nil {\n\t\tm[\"minimum\"] = x\n\t}\n\tif x := parameter.Maximum; x != nil {\n\t\tm[\"maximum\"] = x\n\t}\n\tif x := parameter.MaxLength; x != nil {\n\t\tm[\"maxLength\"] = x\n\t}\n\tif x := parameter.MaxItems; x != nil {\n\t\tm[\"maxItems\"] = x\n\t}\n\tif x := parameter.MinLength; x != 0 {\n\t\tm[\"minLength\"] = x\n\t}\n\tif x := parameter.MinItems; x != 0 {\n\t\tm[\"minItems\"] = x\n\t}\n\tif x := parameter.Default; x != nil {\n\t\tm[\"default\"] = x\n\t}\n\n\treturn json.Marshal(m)\n}\n\n// UnmarshalJSON sets Parameter to a copy of data.\nfunc (parameter *Parameter) UnmarshalJSON(data []byte) error {\n\ttype ParameterBis Parameter\n\tvar x ParameterBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, \"$ref\")\n\n\tdelete(x.Extensions, \"in\")\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"collectionFormat\")\n\tdelete(x.Extensions, \"type\")\n\tdelete(x.Extensions, \"format\")\n\tdelete(x.Extensions, \"pattern\")\n\tdelete(x.Extensions, \"allowEmptyValue\")\n\tdelete(x.Extensions, \"required\")\n\tdelete(x.Extensions, \"uniqueItems\")\n\tdelete(x.Extensions, \"exclusiveMinimum\")\n\tdelete(x.Extensions, \"exclusiveMaximum\")\n\tdelete(x.Extensions, \"schema\")\n\tdelete(x.Extensions, \"items\")\n\tdelete(x.Extensions, \"enum\")\n\tdelete(x.Extensions, \"multipleOf\")\n\tdelete(x.Extensions, \"minimum\")\n\tdelete(x.Extensions, \"maximum\")\n\tdelete(x.Extensions, \"maxLength\")\n\tdelete(x.Extensions, \"maxItems\")\n\tdelete(x.Extensions, \"minLength\")\n\tdelete(x.Extensions, \"minItems\")\n\tdelete(x.Extensions, \"default\")\n\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\n\t*parameter = Parameter(x)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/path_item.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\ntype PathItem struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tRef string `json:\"$ref,omitempty\" yaml:\"$ref,omitempty\"`\n\n\tDelete     *Operation `json:\"delete,omitempty\" yaml:\"delete,omitempty\"`\n\tGet        *Operation `json:\"get,omitempty\" yaml:\"get,omitempty\"`\n\tHead       *Operation `json:\"head,omitempty\" yaml:\"head,omitempty\"`\n\tOptions    *Operation `json:\"options,omitempty\" yaml:\"options,omitempty\"`\n\tPatch      *Operation `json:\"patch,omitempty\" yaml:\"patch,omitempty\"`\n\tPost       *Operation `json:\"post,omitempty\" yaml:\"post,omitempty\"`\n\tPut        *Operation `json:\"put,omitempty\" yaml:\"put,omitempty\"`\n\tParameters Parameters `json:\"parameters,omitempty\" yaml:\"parameters,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of PathItem.\nfunc (pathItem PathItem) MarshalJSON() ([]byte, error) {\n\tif ref := pathItem.Ref; ref != \"\" {\n\t\treturn json.Marshal(openapi3.Ref{Ref: ref})\n\t}\n\n\tm := make(map[string]any, 8+len(pathItem.Extensions))\n\tfor k, v := range pathItem.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := pathItem.Delete; x != nil {\n\t\tm[\"delete\"] = x\n\t}\n\tif x := pathItem.Get; x != nil {\n\t\tm[\"get\"] = x\n\t}\n\tif x := pathItem.Head; x != nil {\n\t\tm[\"head\"] = x\n\t}\n\tif x := pathItem.Options; x != nil {\n\t\tm[\"options\"] = x\n\t}\n\tif x := pathItem.Patch; x != nil {\n\t\tm[\"patch\"] = x\n\t}\n\tif x := pathItem.Post; x != nil {\n\t\tm[\"post\"] = x\n\t}\n\tif x := pathItem.Put; x != nil {\n\t\tm[\"put\"] = x\n\t}\n\tif x := pathItem.Parameters; len(x) != 0 {\n\t\tm[\"parameters\"] = x\n\t}\n\treturn json.Marshal(m)\n}\n\n// UnmarshalJSON sets PathItem to a copy of data.\nfunc (pathItem *PathItem) UnmarshalJSON(data []byte) error {\n\ttype PathItemBis PathItem\n\tvar x PathItemBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, \"$ref\")\n\tdelete(x.Extensions, \"delete\")\n\tdelete(x.Extensions, \"get\")\n\tdelete(x.Extensions, \"head\")\n\tdelete(x.Extensions, \"options\")\n\tdelete(x.Extensions, \"patch\")\n\tdelete(x.Extensions, \"post\")\n\tdelete(x.Extensions, \"put\")\n\tdelete(x.Extensions, \"parameters\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*pathItem = PathItem(x)\n\treturn nil\n}\n\nfunc (pathItem *PathItem) Operations() map[string]*Operation {\n\toperations := make(map[string]*Operation)\n\tif v := pathItem.Delete; v != nil {\n\t\toperations[http.MethodDelete] = v\n\t}\n\tif v := pathItem.Get; v != nil {\n\t\toperations[http.MethodGet] = v\n\t}\n\tif v := pathItem.Head; v != nil {\n\t\toperations[http.MethodHead] = v\n\t}\n\tif v := pathItem.Options; v != nil {\n\t\toperations[http.MethodOptions] = v\n\t}\n\tif v := pathItem.Patch; v != nil {\n\t\toperations[http.MethodPatch] = v\n\t}\n\tif v := pathItem.Post; v != nil {\n\t\toperations[http.MethodPost] = v\n\t}\n\tif v := pathItem.Put; v != nil {\n\t\toperations[http.MethodPut] = v\n\t}\n\treturn operations\n}\n\nfunc (pathItem *PathItem) GetOperation(method string) *Operation {\n\tswitch method {\n\tcase http.MethodDelete:\n\t\treturn pathItem.Delete\n\tcase http.MethodGet:\n\t\treturn pathItem.Get\n\tcase http.MethodHead:\n\t\treturn pathItem.Head\n\tcase http.MethodOptions:\n\t\treturn pathItem.Options\n\tcase http.MethodPatch:\n\t\treturn pathItem.Patch\n\tcase http.MethodPost:\n\t\treturn pathItem.Post\n\tcase http.MethodPut:\n\t\treturn pathItem.Put\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unsupported HTTP method %q\", method))\n\t}\n}\n\nfunc (pathItem *PathItem) SetOperation(method string, operation *Operation) {\n\tswitch method {\n\tcase http.MethodDelete:\n\t\tpathItem.Delete = operation\n\tcase http.MethodGet:\n\t\tpathItem.Get = operation\n\tcase http.MethodHead:\n\t\tpathItem.Head = operation\n\tcase http.MethodOptions:\n\t\tpathItem.Options = operation\n\tcase http.MethodPatch:\n\t\tpathItem.Patch = operation\n\tcase http.MethodPost:\n\t\tpathItem.Post = operation\n\tcase http.MethodPut:\n\t\tpathItem.Put = operation\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unsupported HTTP method %q\", method))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/ref.go",
    "content": "package openapi2\n\n//go:generate go run refsgenerator.go\n\n// Ref is specified by OpenAPI/Swagger 2.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#reference-object\ntype Ref struct {\n\tRef string `json:\"$ref\" yaml:\"$ref\"`\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/refs.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n\t\"github.com/perimeterx/marshmallow\"\n)\n\n// SchemaRef represents either a Schema or a $ref to a Schema.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype SchemaRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\n\tRef   string\n\tValue *Schema\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*SchemaRef)(nil)\n\nfunc (x *SchemaRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *SchemaRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *SchemaRef) CollectionName() string { return \"schemas\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *SchemaRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *SchemaRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of SchemaRef.\nfunc (x SchemaRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of SchemaRef.\nfunc (x SchemaRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets SchemaRef to a copy of data.\nfunc (x *SchemaRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *SchemaRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/response.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\ntype Response struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tRef string `json:\"$ref,omitempty\" yaml:\"$ref,omitempty\"`\n\n\tDescription string             `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tSchema      *SchemaRef         `json:\"schema,omitempty\" yaml:\"schema,omitempty\"`\n\tHeaders     map[string]*Header `json:\"headers,omitempty\" yaml:\"headers,omitempty\"`\n\tExamples    map[string]any     `json:\"examples,omitempty\" yaml:\"examples,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Response.\nfunc (response Response) MarshalJSON() ([]byte, error) {\n\tif ref := response.Ref; ref != \"\" {\n\t\treturn json.Marshal(openapi3.Ref{Ref: ref})\n\t}\n\n\tm := make(map[string]any, 4+len(response.Extensions))\n\tfor k, v := range response.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := response.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := response.Schema; x != nil {\n\t\tm[\"schema\"] = x\n\t}\n\tif x := response.Headers; len(x) != 0 {\n\t\tm[\"headers\"] = x\n\t}\n\tif x := response.Examples; len(x) != 0 {\n\t\tm[\"examples\"] = x\n\t}\n\treturn json.Marshal(m)\n}\n\n// UnmarshalJSON sets Response to a copy of data.\nfunc (response *Response) UnmarshalJSON(data []byte) error {\n\ttype ResponseBis Response\n\tvar x ResponseBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, \"$ref\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"schema\")\n\tdelete(x.Extensions, \"headers\")\n\tdelete(x.Extensions, \"examples\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*response = Response(x)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/schema.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\t\"strings\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\ntype (\n\tSchemas    map[string]*SchemaRef\n\tSchemaRefs []*SchemaRef\n)\n\n// Schema is specified by OpenAPI/Swagger 2.0 standard.\n// See https://swagger.io/specification/v2/#schema-object\ntype Schema struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tAllOf        SchemaRefs             `json:\"allOf,omitempty\" yaml:\"allOf,omitempty\"`\n\tNot          *SchemaRef             `json:\"not,omitempty\" yaml:\"not,omitempty\"`\n\tType         *openapi3.Types        `json:\"type,omitempty\" yaml:\"type,omitempty\"`\n\tTitle        string                 `json:\"title,omitempty\" yaml:\"title,omitempty\"`\n\tFormat       string                 `json:\"format,omitempty\" yaml:\"format,omitempty\"`\n\tDescription  string                 `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tEnum         []any                  `json:\"enum,omitempty\" yaml:\"enum,omitempty\"`\n\tDefault      any                    `json:\"default,omitempty\" yaml:\"default,omitempty\"`\n\tExample      any                    `json:\"example,omitempty\" yaml:\"example,omitempty\"`\n\tExternalDocs *openapi3.ExternalDocs `json:\"externalDocs,omitempty\" yaml:\"externalDocs,omitempty\"`\n\n\t// Array-related, here for struct compactness\n\tUniqueItems bool `json:\"uniqueItems,omitempty\" yaml:\"uniqueItems,omitempty\"`\n\t// Number-related, here for struct compactness\n\tExclusiveMin bool `json:\"exclusiveMinimum,omitempty\" yaml:\"exclusiveMinimum,omitempty\"`\n\tExclusiveMax bool `json:\"exclusiveMaximum,omitempty\" yaml:\"exclusiveMaximum,omitempty\"`\n\t// Properties\n\tReadOnly        bool          `json:\"readOnly,omitempty\" yaml:\"readOnly,omitempty\"`\n\tWriteOnly       bool          `json:\"writeOnly,omitempty\" yaml:\"writeOnly,omitempty\"`\n\tAllowEmptyValue bool          `json:\"allowEmptyValue,omitempty\" yaml:\"allowEmptyValue,omitempty\"`\n\tDeprecated      bool          `json:\"deprecated,omitempty\" yaml:\"deprecated,omitempty\"`\n\tXML             *openapi3.XML `json:\"xml,omitempty\" yaml:\"xml,omitempty\"`\n\n\t// Number\n\tMin        *float64 `json:\"minimum,omitempty\" yaml:\"minimum,omitempty\"`\n\tMax        *float64 `json:\"maximum,omitempty\" yaml:\"maximum,omitempty\"`\n\tMultipleOf *float64 `json:\"multipleOf,omitempty\" yaml:\"multipleOf,omitempty\"`\n\n\t// String\n\tMinLength uint64  `json:\"minLength,omitempty\" yaml:\"minLength,omitempty\"`\n\tMaxLength *uint64 `json:\"maxLength,omitempty\" yaml:\"maxLength,omitempty\"`\n\tPattern   string  `json:\"pattern,omitempty\" yaml:\"pattern,omitempty\"`\n\n\t// Array\n\tMinItems uint64     `json:\"minItems,omitempty\" yaml:\"minItems,omitempty\"`\n\tMaxItems *uint64    `json:\"maxItems,omitempty\" yaml:\"maxItems,omitempty\"`\n\tItems    *SchemaRef `json:\"items,omitempty\" yaml:\"items,omitempty\"`\n\n\t// Object\n\tRequired             []string                      `json:\"required,omitempty\" yaml:\"required,omitempty\"`\n\tProperties           Schemas                       `json:\"properties,omitempty\" yaml:\"properties,omitempty\"`\n\tMinProps             uint64                        `json:\"minProperties,omitempty\" yaml:\"minProperties,omitempty\"`\n\tMaxProps             *uint64                       `json:\"maxProperties,omitempty\" yaml:\"maxProperties,omitempty\"`\n\tAdditionalProperties openapi3.AdditionalProperties `json:\"additionalProperties,omitempty\" yaml:\"additionalProperties,omitempty\"`\n\tDiscriminator        string                        `json:\"discriminator,omitempty\" yaml:\"discriminator,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Schema.\nfunc (schema Schema) MarshalJSON() ([]byte, error) {\n\tm, err := schema.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn json.Marshal(m)\n}\n\n// MarshalYAML returns the YAML encoding of Schema.\nfunc (schema Schema) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 36+len(schema.Extensions))\n\tfor k, v := range schema.Extensions {\n\t\tm[k] = v\n\t}\n\n\tif x := schema.AllOf; len(x) != 0 {\n\t\tm[\"allOf\"] = x\n\t}\n\tif x := schema.Not; x != nil {\n\t\tm[\"not\"] = x\n\t}\n\tif x := schema.Type; x != nil {\n\t\tm[\"type\"] = x\n\t}\n\tif x := schema.Title; len(x) != 0 {\n\t\tm[\"title\"] = x\n\t}\n\tif x := schema.Format; len(x) != 0 {\n\t\tm[\"format\"] = x\n\t}\n\tif x := schema.Description; len(x) != 0 {\n\t\tm[\"description\"] = x\n\t}\n\tif x := schema.Enum; len(x) != 0 {\n\t\tm[\"enum\"] = x\n\t}\n\tif x := schema.Default; x != nil {\n\t\tm[\"default\"] = x\n\t}\n\tif x := schema.Example; x != nil {\n\t\tm[\"example\"] = x\n\t}\n\tif x := schema.ExternalDocs; x != nil {\n\t\tm[\"externalDocs\"] = x\n\t}\n\n\t// Array-related\n\tif x := schema.UniqueItems; x {\n\t\tm[\"uniqueItems\"] = x\n\t}\n\t// Number-related\n\tif x := schema.ExclusiveMin; x {\n\t\tm[\"exclusiveMinimum\"] = x\n\t}\n\tif x := schema.ExclusiveMax; x {\n\t\tm[\"exclusiveMaximum\"] = x\n\t}\n\tif x := schema.ReadOnly; x {\n\t\tm[\"readOnly\"] = x\n\t}\n\tif x := schema.WriteOnly; x {\n\t\tm[\"writeOnly\"] = x\n\t}\n\tif x := schema.AllowEmptyValue; x {\n\t\tm[\"allowEmptyValue\"] = x\n\t}\n\tif x := schema.Deprecated; x {\n\t\tm[\"deprecated\"] = x\n\t}\n\tif x := schema.XML; x != nil {\n\t\tm[\"xml\"] = x\n\t}\n\n\t// Number\n\tif x := schema.Min; x != nil {\n\t\tm[\"minimum\"] = x\n\t}\n\tif x := schema.Max; x != nil {\n\t\tm[\"maximum\"] = x\n\t}\n\tif x := schema.MultipleOf; x != nil {\n\t\tm[\"multipleOf\"] = x\n\t}\n\n\t// String\n\tif x := schema.MinLength; x != 0 {\n\t\tm[\"minLength\"] = x\n\t}\n\tif x := schema.MaxLength; x != nil {\n\t\tm[\"maxLength\"] = x\n\t}\n\tif x := schema.Pattern; x != \"\" {\n\t\tm[\"pattern\"] = x\n\t}\n\n\t// Array\n\tif x := schema.MinItems; x != 0 {\n\t\tm[\"minItems\"] = x\n\t}\n\tif x := schema.MaxItems; x != nil {\n\t\tm[\"maxItems\"] = x\n\t}\n\tif x := schema.Items; x != nil {\n\t\tm[\"items\"] = x\n\t}\n\n\t// Object\n\tif x := schema.Required; len(x) != 0 {\n\t\tm[\"required\"] = x\n\t}\n\tif x := schema.Properties; len(x) != 0 {\n\t\tm[\"properties\"] = x\n\t}\n\tif x := schema.MinProps; x != 0 {\n\t\tm[\"minProperties\"] = x\n\t}\n\tif x := schema.MaxProps; x != nil {\n\t\tm[\"maxProperties\"] = x\n\t}\n\tif x := schema.AdditionalProperties; x.Has != nil || x.Schema != nil {\n\t\tm[\"additionalProperties\"] = &x\n\t}\n\tif x := schema.Discriminator; x != \"\" {\n\t\tm[\"discriminator\"] = x\n\t}\n\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Schema to a copy of data.\nfunc (schema *Schema) UnmarshalJSON(data []byte) error {\n\ttype SchemaBis Schema\n\tvar x SchemaBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, \"oneOf\")\n\tdelete(x.Extensions, \"anyOf\")\n\tdelete(x.Extensions, \"allOf\")\n\tdelete(x.Extensions, \"not\")\n\tdelete(x.Extensions, \"type\")\n\tdelete(x.Extensions, \"title\")\n\tdelete(x.Extensions, \"format\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"enum\")\n\tdelete(x.Extensions, \"default\")\n\tdelete(x.Extensions, \"example\")\n\tdelete(x.Extensions, \"externalDocs\")\n\n\t// Array-related\n\tdelete(x.Extensions, \"uniqueItems\")\n\t// Number-related\n\tdelete(x.Extensions, \"exclusiveMinimum\")\n\tdelete(x.Extensions, \"exclusiveMaximum\")\n\t// Properties\n\tdelete(x.Extensions, \"nullable\")\n\tdelete(x.Extensions, \"readOnly\")\n\tdelete(x.Extensions, \"writeOnly\")\n\tdelete(x.Extensions, \"allowEmptyValue\")\n\tdelete(x.Extensions, \"deprecated\")\n\tdelete(x.Extensions, \"xml\")\n\n\t// Number\n\tdelete(x.Extensions, \"minimum\")\n\tdelete(x.Extensions, \"maximum\")\n\tdelete(x.Extensions, \"multipleOf\")\n\n\t// String\n\tdelete(x.Extensions, \"minLength\")\n\tdelete(x.Extensions, \"maxLength\")\n\tdelete(x.Extensions, \"pattern\")\n\n\t// Array\n\tdelete(x.Extensions, \"minItems\")\n\tdelete(x.Extensions, \"maxItems\")\n\tdelete(x.Extensions, \"items\")\n\n\t// Object\n\tdelete(x.Extensions, \"required\")\n\tdelete(x.Extensions, \"properties\")\n\tdelete(x.Extensions, \"minProperties\")\n\tdelete(x.Extensions, \"maxProperties\")\n\tdelete(x.Extensions, \"additionalProperties\")\n\tdelete(x.Extensions, \"discriminator\")\n\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\n\t*schema = Schema(x)\n\n\tif schema.Format == \"date\" {\n\t\t// This is a fix for: https://github.com/getkin/kin-openapi/issues/697\n\t\tif eg, ok := schema.Example.(string); ok {\n\t\t\tschema.Example = strings.TrimSuffix(eg, \"T00:00:00Z\")\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2/security_scheme.go",
    "content": "package openapi2\n\nimport (\n\t\"encoding/json\"\n\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\ntype SecurityRequirements []map[string][]string\n\ntype SecurityScheme struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tRef string `json:\"$ref,omitempty\" yaml:\"$ref,omitempty\"`\n\n\tDescription      string            `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tType             string            `json:\"type,omitempty\" yaml:\"type,omitempty\"`\n\tIn               string            `json:\"in,omitempty\" yaml:\"in,omitempty\"`\n\tName             string            `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tFlow             string            `json:\"flow,omitempty\" yaml:\"flow,omitempty\"`\n\tAuthorizationURL string            `json:\"authorizationUrl,omitempty\" yaml:\"authorizationUrl,omitempty\"`\n\tTokenURL         string            `json:\"tokenUrl,omitempty\" yaml:\"tokenUrl,omitempty\"`\n\tScopes           map[string]string `json:\"scopes,omitempty\" yaml:\"scopes,omitempty\"`\n\tTags             openapi3.Tags     `json:\"tags,omitempty\" yaml:\"tags,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of SecurityScheme.\nfunc (securityScheme SecurityScheme) MarshalJSON() ([]byte, error) {\n\tif ref := securityScheme.Ref; ref != \"\" {\n\t\treturn json.Marshal(openapi3.Ref{Ref: ref})\n\t}\n\n\tm := make(map[string]any, 10+len(securityScheme.Extensions))\n\tfor k, v := range securityScheme.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := securityScheme.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := securityScheme.Type; x != \"\" {\n\t\tm[\"type\"] = x\n\t}\n\tif x := securityScheme.In; x != \"\" {\n\t\tm[\"in\"] = x\n\t}\n\tif x := securityScheme.Name; x != \"\" {\n\t\tm[\"name\"] = x\n\t}\n\tif x := securityScheme.Flow; x != \"\" {\n\t\tm[\"flow\"] = x\n\t}\n\tif x := securityScheme.AuthorizationURL; x != \"\" {\n\t\tm[\"authorizationUrl\"] = x\n\t}\n\tif x := securityScheme.TokenURL; x != \"\" {\n\t\tm[\"tokenUrl\"] = x\n\t}\n\tif x := securityScheme.Scopes; len(x) != 0 {\n\t\tm[\"scopes\"] = x\n\t}\n\tif x := securityScheme.Tags; len(x) != 0 {\n\t\tm[\"tags\"] = x\n\t}\n\treturn json.Marshal(m)\n}\n\n// UnmarshalJSON sets SecurityScheme to a copy of data.\nfunc (securityScheme *SecurityScheme) UnmarshalJSON(data []byte) error {\n\ttype SecuritySchemeBis SecurityScheme\n\tvar x SecuritySchemeBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, \"$ref\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"type\")\n\tdelete(x.Extensions, \"in\")\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"flow\")\n\tdelete(x.Extensions, \"authorizationUrl\")\n\tdelete(x.Extensions, \"tokenUrl\")\n\tdelete(x.Extensions, \"scopes\")\n\tdelete(x.Extensions, \"tags\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*securityScheme = SecurityScheme(x)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2conv/doc.go",
    "content": "// Package openapi2conv converts an OpenAPI v2 specification document to v3.\npackage openapi2conv\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi2conv/openapi2_conv.go",
    "content": "package openapi2conv\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/getkin/kin-openapi/openapi2\"\n\t\"github.com/getkin/kin-openapi/openapi3\"\n)\n\n// ToV3 converts an OpenAPIv2 spec to an OpenAPIv3 spec\nfunc ToV3(doc2 *openapi2.T) (*openapi3.T, error) {\n\treturn ToV3WithLoader(doc2, openapi3.NewLoader(), nil)\n}\n\nfunc ToV3WithLoader(doc2 *openapi2.T, loader *openapi3.Loader, location *url.URL) (*openapi3.T, error) {\n\tdoc3 := &openapi3.T{\n\t\tOpenAPI:      \"3.0.3\",\n\t\tInfo:         &doc2.Info,\n\t\tComponents:   &openapi3.Components{},\n\t\tTags:         doc2.Tags,\n\t\tExtensions:   stripNonExtensions(doc2.Extensions),\n\t\tExternalDocs: doc2.ExternalDocs,\n\t}\n\n\tif host := doc2.Host; host != \"\" {\n\t\tif strings.Contains(host, \"/\") {\n\t\t\terr := fmt.Errorf(\"invalid host %q. This MUST be the host only and does not include the scheme nor sub-paths.\", host)\n\t\t\treturn nil, err\n\t\t}\n\t\tschemes := doc2.Schemes\n\t\tif len(schemes) == 0 {\n\t\t\tschemes = []string{\"https\"}\n\t\t}\n\t\tbasePath := doc2.BasePath\n\t\tif basePath == \"\" {\n\t\t\tbasePath = \"/\"\n\t\t}\n\t\tfor _, scheme := range schemes {\n\t\t\tu := url.URL{\n\t\t\t\tScheme: scheme,\n\t\t\t\tHost:   host,\n\t\t\t\tPath:   basePath,\n\t\t\t}\n\t\t\tdoc3.AddServer(&openapi3.Server{URL: u.String()})\n\t\t}\n\t}\n\n\tdoc3.Components.Schemas = make(map[string]*openapi3.SchemaRef)\n\tif parameters := doc2.Parameters; len(parameters) != 0 {\n\t\tdoc3.Components.Parameters = make(map[string]*openapi3.ParameterRef)\n\t\tdoc3.Components.RequestBodies = make(map[string]*openapi3.RequestBodyRef)\n\t\tfor k, parameter := range parameters {\n\t\t\tv3Parameter, v3RequestBody, v3SchemaMap, err := ToV3Parameter(doc3.Components, parameter, doc2.Consumes)\n\t\t\tswitch {\n\t\t\tcase err != nil:\n\t\t\t\treturn nil, err\n\t\t\tcase v3RequestBody != nil:\n\t\t\t\tdoc3.Components.RequestBodies[k] = v3RequestBody\n\t\t\tcase v3SchemaMap != nil:\n\t\t\t\tfor _, v3Schema := range v3SchemaMap {\n\t\t\t\t\tdoc3.Components.Schemas[k] = v3Schema\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tdoc3.Components.Parameters[k] = v3Parameter\n\t\t\t}\n\t\t}\n\t}\n\n\tif paths := doc2.Paths; len(paths) != 0 {\n\t\tdoc3.Paths = openapi3.NewPathsWithCapacity(len(paths))\n\t\tfor path, pathItem := range paths {\n\t\t\tr, err := ToV3PathItem(doc2, doc3.Components, pathItem, doc2.Consumes)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdoc3.Paths.Set(path, r)\n\t\t}\n\t}\n\n\tif responses := doc2.Responses; len(responses) != 0 {\n\t\tdoc3.Components.Responses = make(openapi3.ResponseBodies, len(responses))\n\t\tfor k, response := range responses {\n\t\t\tr, err := ToV3Response(response, doc2.Produces)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdoc3.Components.Responses[k] = r\n\t\t}\n\t}\n\n\tfor key, schema := range ToV3Schemas(doc2.Definitions) {\n\t\tdoc3.Components.Schemas[key] = schema\n\t}\n\n\tif m := doc2.SecurityDefinitions; len(m) != 0 {\n\t\tdoc3SecuritySchemes := make(map[string]*openapi3.SecuritySchemeRef)\n\t\tfor k, v := range m {\n\t\t\tr, err := ToV3SecurityScheme(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdoc3SecuritySchemes[k] = r\n\t\t}\n\t\tdoc3.Components.SecuritySchemes = doc3SecuritySchemes\n\t}\n\n\tdoc3.Security = ToV3SecurityRequirements(doc2.Security)\n\n\tif err := loader.ResolveRefsIn(doc3, location); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn doc3, nil\n}\n\nfunc ToV3PathItem(doc2 *openapi2.T, components *openapi3.Components, pathItem *openapi2.PathItem, consumes []string) (*openapi3.PathItem, error) {\n\tdoc3 := &openapi3.PathItem{\n\t\tExtensions: stripNonExtensions(pathItem.Extensions),\n\t}\n\tfor method, operation := range pathItem.Operations() {\n\t\tdoc3Operation, err := ToV3Operation(doc2, components, pathItem, operation, consumes)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdoc3.SetOperation(method, doc3Operation)\n\t}\n\tfor _, parameter := range pathItem.Parameters {\n\t\tv3Parameter, v3RequestBody, v3Schema, err := ToV3Parameter(components, parameter, consumes)\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\treturn nil, err\n\t\tcase v3RequestBody != nil:\n\t\t\treturn nil, errors.New(\"pathItem must not have a body parameter\")\n\t\tcase v3Schema != nil:\n\t\t\treturn nil, errors.New(\"pathItem must not have a schema parameter\")\n\t\tdefault:\n\t\t\tdoc3.Parameters = append(doc3.Parameters, v3Parameter)\n\t\t}\n\t}\n\treturn doc3, nil\n}\n\nfunc ToV3Operation(doc2 *openapi2.T, components *openapi3.Components, pathItem *openapi2.PathItem, operation *openapi2.Operation, consumes []string) (*openapi3.Operation, error) {\n\tif operation == nil {\n\t\treturn nil, nil\n\t}\n\tdoc3 := &openapi3.Operation{\n\t\tOperationID: operation.OperationID,\n\t\tSummary:     operation.Summary,\n\t\tDescription: operation.Description,\n\t\tDeprecated:  operation.Deprecated,\n\t\tTags:        operation.Tags,\n\t\tExtensions:  stripNonExtensions(operation.Extensions),\n\t}\n\tif v := operation.Security; v != nil {\n\t\tdoc3Security := ToV3SecurityRequirements(*v)\n\t\tdoc3.Security = &doc3Security\n\t}\n\n\tif len(operation.Consumes) > 0 {\n\t\tconsumes = operation.Consumes\n\t}\n\n\tvar reqBodies []*openapi3.RequestBodyRef\n\tformDataSchemas := make(map[string]*openapi3.SchemaRef)\n\tfor _, parameter := range operation.Parameters {\n\t\tv3Parameter, v3RequestBody, v3SchemaMap, err := ToV3Parameter(components, parameter, consumes)\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\treturn nil, err\n\t\tcase v3RequestBody != nil:\n\t\t\treqBodies = append(reqBodies, v3RequestBody)\n\t\tcase v3SchemaMap != nil:\n\t\t\tfor key, v3Schema := range v3SchemaMap {\n\t\t\t\tformDataSchemas[key] = v3Schema\n\t\t\t}\n\t\tdefault:\n\t\t\tdoc3.Parameters = append(doc3.Parameters, v3Parameter)\n\t\t}\n\t}\n\tvar err error\n\tif doc3.RequestBody, err = onlyOneReqBodyParam(reqBodies, formDataSchemas, components, consumes); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif responses := operation.Responses; responses != nil {\n\t\tdoc3.Responses = openapi3.NewResponsesWithCapacity(len(responses))\n\t\tfor k, response := range responses {\n\t\t\tresponseRef3, err := ToV3Response(response, operation.Produces)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdoc3.Responses.Set(k, responseRef3)\n\t\t}\n\t}\n\treturn doc3, nil\n}\n\nfunc getParameterNameFromOldRef(ref string) string {\n\tcleanPath := strings.TrimPrefix(ref, \"#/parameters/\")\n\tpathSections := strings.SplitN(cleanPath, \"/\", 1)\n\n\treturn pathSections[0]\n}\n\nfunc ToV3Parameter(components *openapi3.Components, parameter *openapi2.Parameter, consumes []string) (*openapi3.ParameterRef, *openapi3.RequestBodyRef, map[string]*openapi3.SchemaRef, error) {\n\tif ref := parameter.Ref; ref != \"\" {\n\t\tif strings.HasPrefix(ref, \"#/parameters/\") {\n\t\t\tname := getParameterNameFromOldRef(ref)\n\t\t\tif _, ok := components.RequestBodies[name]; ok {\n\t\t\t\tv3Ref := strings.Replace(ref, \"#/parameters/\", \"#/components/requestBodies/\", 1)\n\t\t\t\treturn nil, &openapi3.RequestBodyRef{Ref: v3Ref}, nil, nil\n\t\t\t} else if schema, ok := components.Schemas[name]; ok {\n\t\t\t\tschemaRefMap := make(map[string]*openapi3.SchemaRef)\n\t\t\t\tif val, ok := schema.Value.Extensions[\"x-formData-name\"]; ok {\n\t\t\t\t\tname = val.(string)\n\t\t\t\t}\n\t\t\t\tv3Ref := strings.Replace(ref, \"#/parameters/\", \"#/components/schemas/\", 1)\n\t\t\t\tschemaRefMap[name] = &openapi3.SchemaRef{Ref: v3Ref}\n\t\t\t\treturn nil, nil, schemaRefMap, nil\n\t\t\t}\n\t\t}\n\t\treturn &openapi3.ParameterRef{Ref: ToV3Ref(ref)}, nil, nil, nil\n\t}\n\n\tswitch parameter.In {\n\tcase \"body\":\n\t\tresult := &openapi3.RequestBody{\n\t\t\tDescription: parameter.Description,\n\t\t\tRequired:    parameter.Required,\n\t\t\tExtensions:  stripNonExtensions(parameter.Extensions),\n\t\t}\n\t\tif parameter.Name != \"\" {\n\t\t\tif result.Extensions == nil {\n\t\t\t\tresult.Extensions = make(map[string]any, 1)\n\t\t\t}\n\t\t\tresult.Extensions[\"x-originalParamName\"] = parameter.Name\n\t\t}\n\n\t\tif schemaRef := parameter.Schema; schemaRef != nil {\n\t\t\tresult.WithSchemaRef(ToV3SchemaRef(schemaRef), consumes)\n\t\t}\n\t\treturn nil, &openapi3.RequestBodyRef{Value: result}, nil, nil\n\n\tcase \"formData\":\n\t\tformat, typ := parameter.Format, parameter.Type\n\t\tif typ.Is(\"file\") {\n\t\t\tformat, typ = \"binary\", &openapi3.Types{\"string\"}\n\t\t}\n\t\tif parameter.Extensions == nil {\n\t\t\tparameter.Extensions = make(map[string]any, 1)\n\t\t}\n\t\tparameter.Extensions[\"x-formData-name\"] = parameter.Name\n\t\tvar required []string\n\t\tif parameter.Required {\n\t\t\trequired = []string{parameter.Name}\n\t\t}\n\t\tschemaRef := &openapi3.SchemaRef{Value: &openapi3.Schema{\n\t\t\tDescription:     parameter.Description,\n\t\t\tType:            typ,\n\t\t\tExtensions:      stripNonExtensions(parameter.Extensions),\n\t\t\tFormat:          format,\n\t\t\tEnum:            parameter.Enum,\n\t\t\tMin:             parameter.Minimum,\n\t\t\tMax:             parameter.Maximum,\n\t\t\tExclusiveMin:    parameter.ExclusiveMin,\n\t\t\tExclusiveMax:    parameter.ExclusiveMax,\n\t\t\tMinLength:       parameter.MinLength,\n\t\t\tMaxLength:       parameter.MaxLength,\n\t\t\tDefault:         parameter.Default,\n\t\t\tMinItems:        parameter.MinItems,\n\t\t\tMaxItems:        parameter.MaxItems,\n\t\t\tPattern:         parameter.Pattern,\n\t\t\tAllowEmptyValue: parameter.AllowEmptyValue,\n\t\t\tUniqueItems:     parameter.UniqueItems,\n\t\t\tMultipleOf:      parameter.MultipleOf,\n\t\t\tRequired:        required,\n\t\t}}\n\t\tif parameter.Items != nil {\n\t\t\tschemaRef.Value.Items = ToV3SchemaRef(parameter.Items)\n\t\t}\n\n\t\tschemaRefMap := make(map[string]*openapi3.SchemaRef, 1)\n\t\tschemaRefMap[parameter.Name] = schemaRef\n\t\treturn nil, nil, schemaRefMap, nil\n\n\tdefault:\n\t\trequired := parameter.Required\n\t\tif parameter.In == openapi3.ParameterInPath {\n\t\t\trequired = true\n\t\t}\n\n\t\tvar schemaRefRef string\n\t\tif schemaRef := parameter.Schema; schemaRef != nil && schemaRef.Ref != \"\" {\n\t\t\tschemaRefRef = schemaRef.Ref\n\t\t}\n\t\tresult := &openapi3.Parameter{\n\t\t\tIn:          parameter.In,\n\t\t\tName:        parameter.Name,\n\t\t\tDescription: parameter.Description,\n\t\t\tRequired:    required,\n\t\t\tExtensions:  stripNonExtensions(parameter.Extensions),\n\t\t\tSchema: ToV3SchemaRef(&openapi2.SchemaRef{Value: &openapi2.Schema{\n\t\t\t\tType:            parameter.Type,\n\t\t\t\tFormat:          parameter.Format,\n\t\t\t\tEnum:            parameter.Enum,\n\t\t\t\tMin:             parameter.Minimum,\n\t\t\t\tMax:             parameter.Maximum,\n\t\t\t\tExclusiveMin:    parameter.ExclusiveMin,\n\t\t\t\tExclusiveMax:    parameter.ExclusiveMax,\n\t\t\t\tMinLength:       parameter.MinLength,\n\t\t\t\tMaxLength:       parameter.MaxLength,\n\t\t\t\tDefault:         parameter.Default,\n\t\t\t\tItems:           parameter.Items,\n\t\t\t\tMinItems:        parameter.MinItems,\n\t\t\t\tMaxItems:        parameter.MaxItems,\n\t\t\t\tPattern:         parameter.Pattern,\n\t\t\t\tAllowEmptyValue: parameter.AllowEmptyValue,\n\t\t\t\tUniqueItems:     parameter.UniqueItems,\n\t\t\t\tMultipleOf:      parameter.MultipleOf,\n\t\t\t},\n\t\t\t\tRef: schemaRefRef,\n\t\t\t}),\n\t\t}\n\t\treturn &openapi3.ParameterRef{Value: result}, nil, nil, nil\n\t}\n}\n\nfunc formDataBody(bodies map[string]*openapi3.SchemaRef, reqs map[string]bool, consumes []string) *openapi3.RequestBodyRef {\n\tif len(bodies) != len(reqs) {\n\t\tpanic(`request bodies and them being required must match`)\n\t}\n\trequireds := make([]string, 0, len(reqs))\n\tfor propName, req := range reqs {\n\t\tif _, ok := bodies[propName]; !ok {\n\t\t\tpanic(`request bodies and them being required must match`)\n\t\t}\n\t\tif req {\n\t\t\trequireds = append(requireds, propName)\n\t\t}\n\t}\n\tfor s, ref := range bodies {\n\t\tif ref.Value != nil && len(ref.Value.Required) > 0 {\n\t\t\tref.Value.Required = nil\n\t\t\tbodies[s] = ref\n\t\t}\n\t}\n\tsort.Strings(requireds)\n\tschema := &openapi3.Schema{\n\t\tType:       &openapi3.Types{\"object\"},\n\t\tProperties: bodies,\n\t\tRequired:   requireds,\n\t}\n\treturn &openapi3.RequestBodyRef{\n\t\tValue: openapi3.NewRequestBody().WithSchema(schema, consumes),\n\t}\n}\n\nfunc getParameterNameFromNewRef(ref string) string {\n\tcleanPath := strings.TrimPrefix(ref, \"#/components/schemas/\")\n\tpathSections := strings.SplitN(cleanPath, \"/\", 1)\n\n\treturn pathSections[0]\n}\n\nfunc onlyOneReqBodyParam(bodies []*openapi3.RequestBodyRef, formDataSchemas map[string]*openapi3.SchemaRef, components *openapi3.Components, consumes []string) (*openapi3.RequestBodyRef, error) {\n\tif len(bodies) > 1 {\n\t\treturn nil, errors.New(\"multiple body parameters cannot exist for the same operation\")\n\t}\n\n\tif len(bodies) != 0 && len(formDataSchemas) != 0 {\n\t\treturn nil, errors.New(\"body and form parameters cannot exist together for the same operation\")\n\t}\n\n\tfor _, requestBodyRef := range bodies {\n\t\treturn requestBodyRef, nil\n\t}\n\n\tif len(formDataSchemas) > 0 {\n\t\tformDataParams := make(map[string]*openapi3.SchemaRef, len(formDataSchemas))\n\t\tformDataReqs := make(map[string]bool, len(formDataSchemas))\n\t\tfor formDataName, formDataSchema := range formDataSchemas {\n\t\t\tif formDataSchema.Ref != \"\" {\n\t\t\t\tname := getParameterNameFromNewRef(formDataSchema.Ref)\n\t\t\t\tif schema := components.Schemas[name]; schema != nil && schema.Value != nil {\n\t\t\t\t\tif tempName, ok := schema.Value.Extensions[\"x-formData-name\"]; ok {\n\t\t\t\t\t\tname = tempName.(string)\n\t\t\t\t\t}\n\t\t\t\t\tformDataParams[name] = formDataSchema\n\t\t\t\t\tformDataReqs[name] = false\n\t\t\t\t\tfor _, req := range schema.Value.Required {\n\t\t\t\t\t\tif name == req {\n\t\t\t\t\t\t\tformDataReqs[name] = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if formDataSchema.Value != nil {\n\t\t\t\tformDataParams[formDataName] = formDataSchema\n\t\t\t\tformDataReqs[formDataName] = false\n\t\t\t\tfor _, req := range formDataSchema.Value.Required {\n\t\t\t\t\tif formDataName == req {\n\t\t\t\t\t\tformDataReqs[formDataName] = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn formDataBody(formDataParams, formDataReqs, consumes), nil\n\t}\n\n\treturn nil, nil\n}\n\nfunc ToV3Response(response *openapi2.Response, produces []string) (*openapi3.ResponseRef, error) {\n\tif ref := response.Ref; ref != \"\" {\n\t\treturn &openapi3.ResponseRef{Ref: ToV3Ref(ref)}, nil\n\t}\n\tresult := &openapi3.Response{\n\t\tDescription: &response.Description,\n\t\tExtensions:  stripNonExtensions(response.Extensions),\n\t}\n\n\t// Default to \"application/json\" if \"produces\" is not specified.\n\tif len(produces) == 0 {\n\t\tproduces = []string{\"application/json\"}\n\t}\n\n\tif schemaRef := response.Schema; schemaRef != nil {\n\t\tschema := ToV3SchemaRef(schemaRef)\n\t\tresult.Content = make(openapi3.Content, len(produces))\n\t\tfor _, mime := range produces {\n\t\t\tresult.Content[mime] = openapi3.NewMediaType().WithSchemaRef(schema)\n\t\t}\n\t}\n\tif headers := response.Headers; len(headers) > 0 {\n\t\tresult.Headers = ToV3Headers(headers)\n\t}\n\treturn &openapi3.ResponseRef{Value: result}, nil\n}\n\nfunc ToV3Headers(defs map[string]*openapi2.Header) openapi3.Headers {\n\theaders := make(openapi3.Headers, len(defs))\n\tfor name, header := range defs {\n\t\theader.In = \"\"\n\t\theader.Name = \"\"\n\t\tif ref := header.Ref; ref != \"\" {\n\t\t\theaders[name] = &openapi3.HeaderRef{Ref: ToV3Ref(ref)}\n\t\t} else {\n\t\t\tparameter, _, _, _ := ToV3Parameter(nil, &header.Parameter, nil)\n\t\t\theaders[name] = &openapi3.HeaderRef{Value: &openapi3.Header{\n\t\t\t\tParameter: *parameter.Value,\n\t\t\t}}\n\t\t}\n\t}\n\treturn headers\n}\n\nfunc ToV3Schemas(defs map[string]*openapi2.SchemaRef) map[string]*openapi3.SchemaRef {\n\tschemas := make(map[string]*openapi3.SchemaRef, len(defs))\n\tfor name, schema := range defs {\n\t\tschemas[name] = ToV3SchemaRef(schema)\n\t}\n\treturn schemas\n}\n\nfunc ToV3SchemaRef(schema *openapi2.SchemaRef) *openapi3.SchemaRef {\n\tif schema == nil {\n\t\treturn &openapi3.SchemaRef{}\n\t}\n\n\tif ref := schema.Ref; ref != \"\" {\n\t\treturn &openapi3.SchemaRef{Ref: ToV3Ref(ref)}\n\t}\n\n\tif schema.Value == nil {\n\t\treturn &openapi3.SchemaRef{\n\t\t\tExtensions: schema.Extensions,\n\t\t}\n\t}\n\n\tv3Schema := &openapi3.Schema{\n\t\tExtensions:           schema.Extensions,\n\t\tType:                 schema.Value.Type,\n\t\tTitle:                schema.Value.Title,\n\t\tFormat:               schema.Value.Format,\n\t\tDescription:          schema.Value.Description,\n\t\tEnum:                 schema.Value.Enum,\n\t\tDefault:              schema.Value.Default,\n\t\tExample:              schema.Value.Example,\n\t\tExternalDocs:         schema.Value.ExternalDocs,\n\t\tUniqueItems:          schema.Value.UniqueItems,\n\t\tExclusiveMin:         schema.Value.ExclusiveMin,\n\t\tExclusiveMax:         schema.Value.ExclusiveMax,\n\t\tReadOnly:             schema.Value.ReadOnly,\n\t\tWriteOnly:            schema.Value.WriteOnly,\n\t\tAllowEmptyValue:      schema.Value.AllowEmptyValue,\n\t\tDeprecated:           schema.Value.Deprecated,\n\t\tXML:                  schema.Value.XML,\n\t\tMin:                  schema.Value.Min,\n\t\tMax:                  schema.Value.Max,\n\t\tMultipleOf:           schema.Value.MultipleOf,\n\t\tMinLength:            schema.Value.MinLength,\n\t\tMaxLength:            schema.Value.MaxLength,\n\t\tPattern:              schema.Value.Pattern,\n\t\tMinItems:             schema.Value.MinItems,\n\t\tMaxItems:             schema.Value.MaxItems,\n\t\tRequired:             schema.Value.Required,\n\t\tMinProps:             schema.Value.MinProps,\n\t\tMaxProps:             schema.Value.MaxProps,\n\t\tAllOf:                make(openapi3.SchemaRefs, len(schema.Value.AllOf)),\n\t\tProperties:           make(openapi3.Schemas),\n\t\tAdditionalProperties: toV3AdditionalProperties(schema.Value.AdditionalProperties),\n\t}\n\n\tif schema.Value.Discriminator != \"\" {\n\t\tv3Schema.Discriminator = &openapi3.Discriminator{\n\t\t\tPropertyName: schema.Value.Discriminator,\n\t\t}\n\t}\n\n\tif schema.Value.Items != nil {\n\t\tv3Schema.Items = ToV3SchemaRef(schema.Value.Items)\n\t}\n\tif schema.Value.Type.Is(\"file\") {\n\t\tv3Schema.Format, v3Schema.Type = \"binary\", &openapi3.Types{\"string\"}\n\t}\n\tfor k, v := range schema.Value.Properties {\n\t\tv3Schema.Properties[k] = ToV3SchemaRef(v)\n\t}\n\tfor i, v := range schema.Value.AllOf {\n\t\tv3Schema.AllOf[i] = ToV3SchemaRef(v)\n\t}\n\tif val, ok := schema.Value.Extensions[\"x-nullable\"]; ok {\n\t\tif nullable, valid := val.(bool); valid {\n\t\t\tv3Schema.Nullable = nullable\n\t\t\tdelete(v3Schema.Extensions, \"x-nullable\")\n\t\t}\n\t}\n\n\treturn &openapi3.SchemaRef{\n\t\tExtensions: schema.Extensions,\n\t\tValue:      v3Schema,\n\t}\n}\n\nfunc toV3AdditionalProperties(from openapi3.AdditionalProperties) openapi3.AdditionalProperties {\n\treturn openapi3.AdditionalProperties{\n\t\tHas:    from.Has,\n\t\tSchema: convertRefsInV3SchemaRef(from.Schema),\n\t}\n}\n\nfunc convertRefsInV3SchemaRef(from *openapi3.SchemaRef) *openapi3.SchemaRef {\n\tif from == nil {\n\t\treturn nil\n\t}\n\tto := *from\n\tto.Ref = ToV3Ref(to.Ref)\n\tif to.Value != nil {\n\t\tv := *from.Value\n\t\tto.Value = &v\n\t\tto.Value.AdditionalProperties = toV3AdditionalProperties(to.Value.AdditionalProperties)\n\t}\n\treturn &to\n}\n\nvar ref2To3 = map[string]string{\n\t\"#/definitions/\": \"#/components/schemas/\",\n\t\"#/responses/\":   \"#/components/responses/\",\n\t\"#/parameters/\":  \"#/components/parameters/\",\n}\n\nfunc ToV3Ref(ref string) string {\n\tfor old, new := range ref2To3 {\n\t\tif strings.HasPrefix(ref, old) {\n\t\t\tref = strings.Replace(ref, old, new, 1)\n\t\t}\n\t}\n\treturn ref\n}\n\nfunc FromV3Ref(ref string) string {\n\tfor new, old := range ref2To3 {\n\t\tif strings.HasPrefix(ref, old) {\n\t\t\tref = strings.Replace(ref, old, new, 1)\n\t\t} else if strings.HasPrefix(ref, \"#/components/requestBodies/\") {\n\t\t\tref = strings.Replace(ref, \"#/components/requestBodies/\", \"#/parameters/\", 1)\n\t\t}\n\t}\n\treturn ref\n}\n\nfunc ToV3SecurityRequirements(requirements openapi2.SecurityRequirements) openapi3.SecurityRequirements {\n\tif requirements == nil {\n\t\treturn nil\n\t}\n\tresult := make(openapi3.SecurityRequirements, len(requirements))\n\tfor i, item := range requirements {\n\t\tresult[i] = item\n\t}\n\treturn result\n}\n\nfunc ToV3SecurityScheme(securityScheme *openapi2.SecurityScheme) (*openapi3.SecuritySchemeRef, error) {\n\tif securityScheme == nil {\n\t\treturn nil, nil\n\t}\n\tresult := &openapi3.SecurityScheme{\n\t\tDescription: securityScheme.Description,\n\t\tExtensions:  stripNonExtensions(securityScheme.Extensions),\n\t}\n\tswitch securityScheme.Type {\n\tcase \"basic\":\n\t\tresult.Type = \"http\"\n\t\tresult.Scheme = \"basic\"\n\tcase \"apiKey\":\n\t\tresult.Type = \"apiKey\"\n\t\tresult.In = securityScheme.In\n\t\tresult.Name = securityScheme.Name\n\tcase \"oauth2\":\n\t\tresult.Type = \"oauth2\"\n\t\tflows := &openapi3.OAuthFlows{}\n\t\tresult.Flows = flows\n\t\tscopesMap := make(map[string]string)\n\t\tfor scope, desc := range securityScheme.Scopes {\n\t\t\tscopesMap[scope] = desc\n\t\t}\n\t\tflow := &openapi3.OAuthFlow{\n\t\t\tAuthorizationURL: securityScheme.AuthorizationURL,\n\t\t\tTokenURL:         securityScheme.TokenURL,\n\t\t\tScopes:           scopesMap,\n\t\t}\n\t\tswitch securityScheme.Flow {\n\t\tcase \"implicit\":\n\t\t\tflows.Implicit = flow\n\t\tcase \"accessCode\":\n\t\t\tflows.AuthorizationCode = flow\n\t\tcase \"password\":\n\t\t\tflows.Password = flow\n\t\tcase \"application\":\n\t\t\tflows.ClientCredentials = flow\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unsupported flow %q\", securityScheme.Flow)\n\t\t}\n\t}\n\treturn &openapi3.SecuritySchemeRef{\n\t\tRef:   ToV3Ref(securityScheme.Ref),\n\t\tValue: result,\n\t}, nil\n}\n\n// FromV3 converts an OpenAPIv3 spec to an OpenAPIv2 spec\nfunc FromV3(doc3 *openapi3.T) (*openapi2.T, error) {\n\tdoc2Responses, err := FromV3Responses(doc3.Components.Responses, doc3.Components)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tschemas, parameters := FromV3Schemas(doc3.Components.Schemas, doc3.Components)\n\tdoc2 := &openapi2.T{\n\t\tSwagger:      \"2.0\",\n\t\tInfo:         *doc3.Info,\n\t\tDefinitions:  schemas,\n\t\tParameters:   parameters,\n\t\tResponses:    doc2Responses,\n\t\tTags:         doc3.Tags,\n\t\tExtensions:   stripNonExtensions(doc3.Extensions),\n\t\tExternalDocs: doc3.ExternalDocs,\n\t}\n\n\tisHTTPS := false\n\tisHTTP := false\n\tservers := doc3.Servers\n\tfor i, server := range servers {\n\t\tparsedURL, err := url.Parse(server.URL)\n\t\tif err == nil {\n\t\t\t// See which schemes seem to be supported\n\t\t\tif parsedURL.Scheme == \"https\" {\n\t\t\t\tisHTTPS = true\n\t\t\t} else if parsedURL.Scheme == \"http\" {\n\t\t\t\tisHTTP = true\n\t\t\t}\n\t\t\t// The first server is assumed to provide the base path\n\t\t\tif i == 0 {\n\t\t\t\tdoc2.Host = parsedURL.Host\n\t\t\t\tdoc2.BasePath = parsedURL.Path\n\t\t\t}\n\t\t}\n\t}\n\n\tif isHTTPS {\n\t\tdoc2.Schemes = append(doc2.Schemes, \"https\")\n\t}\n\tif isHTTP {\n\t\tdoc2.Schemes = append(doc2.Schemes, \"http\")\n\t}\n\n\tfor path, pathItem := range doc3.Paths.Map() {\n\t\tif pathItem == nil {\n\t\t\tcontinue\n\t\t}\n\t\tdoc2.AddOperation(path, \"GET\", nil)\n\t\taddPathExtensions(doc2, path, stripNonExtensions(pathItem.Extensions))\n\t\tfor method, operation := range pathItem.Operations() {\n\t\t\tif operation == nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdoc2Operation, err := FromV3Operation(doc3, operation)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdoc2.AddOperation(path, method, doc2Operation)\n\t\t}\n\t\tparams := openapi2.Parameters{}\n\t\tfor _, param := range pathItem.Parameters {\n\t\t\tp, err := FromV3Parameter(param, doc3.Components)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tparams = append(params, p)\n\t\t}\n\t\tsort.Sort(params)\n\t\tdoc2.Paths[path].Parameters = params\n\t}\n\n\tfor name, param := range doc3.Components.Parameters {\n\t\tif doc2.Parameters[name], err = FromV3Parameter(param, doc3.Components); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tfor name, requestBodyRef := range doc3.Components.RequestBodies {\n\t\tbodyOrRefParameters, formDataParameters, consumes, err := fromV3RequestBodies(name, requestBodyRef, doc3.Components)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(formDataParameters) != 0 {\n\t\t\tfor _, param := range formDataParameters {\n\t\t\t\tdoc2.Parameters[param.Name] = param\n\t\t\t}\n\t\t} else if len(bodyOrRefParameters) != 0 {\n\t\t\tfor _, param := range bodyOrRefParameters {\n\t\t\t\tdoc2.Parameters[name] = param\n\t\t\t}\n\t\t}\n\n\t\tif len(consumes) != 0 {\n\t\t\tdoc2.Consumes = consumesToArray(consumes)\n\t\t}\n\t}\n\n\tif m := doc3.Components.SecuritySchemes; m != nil {\n\t\tdoc2SecuritySchemes := make(map[string]*openapi2.SecurityScheme)\n\t\tfor id, securityScheme := range m {\n\t\t\tv, err := FromV3SecurityScheme(doc3, securityScheme)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdoc2SecuritySchemes[id] = v\n\t\t}\n\t\tdoc2.SecurityDefinitions = doc2SecuritySchemes\n\t}\n\tdoc2.Security = FromV3SecurityRequirements(doc3.Security)\n\n\treturn doc2, nil\n}\n\nfunc consumesToArray(consumes map[string]struct{}) []string {\n\tconsumesArr := make([]string, 0, len(consumes))\n\tfor key := range consumes {\n\t\tconsumesArr = append(consumesArr, key)\n\t}\n\tsort.Strings(consumesArr)\n\treturn consumesArr\n}\n\nfunc fromV3RequestBodies(name string, requestBodyRef *openapi3.RequestBodyRef, components *openapi3.Components) (\n\tbodyOrRefParameters openapi2.Parameters,\n\tformParameters openapi2.Parameters,\n\tconsumes map[string]struct{},\n\terr error,\n) {\n\tif ref := requestBodyRef.Ref; ref != \"\" {\n\t\tbodyOrRefParameters = append(bodyOrRefParameters, &openapi2.Parameter{Ref: FromV3Ref(ref)})\n\t\treturn\n\t}\n\n\t// Only select one formData or request body for an individual requestBody as OpenAPI 2 does not support multiples\n\tif requestBodyRef.Value != nil {\n\t\tfor contentType, mediaType := range requestBodyRef.Value.Content {\n\t\t\tif consumes == nil {\n\t\t\t\tconsumes = make(map[string]struct{})\n\t\t\t}\n\t\t\tconsumes[contentType] = struct{}{}\n\t\t\tif contentType == \"application/x-www-form-urlencoded\" || contentType == \"multipart/form-data\" {\n\t\t\t\tformParameters = FromV3RequestBodyFormData(mediaType)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tparamName := name\n\t\t\tif originalName, ok := requestBodyRef.Value.Extensions[\"x-originalParamName\"]; ok {\n\t\t\t\tparamName = originalName.(string)\n\t\t\t}\n\n\t\t\tvar r *openapi2.Parameter\n\t\t\tif r, err = FromV3RequestBody(paramName, requestBodyRef, mediaType, components); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tbodyOrRefParameters = append(bodyOrRefParameters, r)\n\t\t}\n\t}\n\treturn\n}\n\nfunc FromV3Schemas(schemas map[string]*openapi3.SchemaRef, components *openapi3.Components) (map[string]*openapi2.SchemaRef, map[string]*openapi2.Parameter) {\n\tv2Defs := make(map[string]*openapi2.SchemaRef)\n\tv2Params := make(map[string]*openapi2.Parameter)\n\tfor name, schema := range schemas {\n\t\tschemaConv, parameterConv := FromV3SchemaRef(schema, components)\n\t\tif schemaConv != nil {\n\t\t\tv2Defs[name] = schemaConv\n\t\t} else if parameterConv != nil {\n\t\t\tif parameterConv.Name == \"\" {\n\t\t\t\tparameterConv.Name = name\n\t\t\t}\n\t\t\tv2Params[name] = parameterConv\n\t\t}\n\t}\n\treturn v2Defs, v2Params\n}\n\nfunc FromV3SchemaRef(schema *openapi3.SchemaRef, components *openapi3.Components) (*openapi2.SchemaRef, *openapi2.Parameter) {\n\tif ref := schema.Ref; ref != \"\" {\n\t\tname := getParameterNameFromNewRef(ref)\n\t\tif val, ok := components.Schemas[name]; ok {\n\t\t\tif val.Value.Format == \"binary\" {\n\t\t\t\tv2Ref := strings.Replace(ref, \"#/components/schemas/\", \"#/parameters/\", 1)\n\t\t\t\treturn nil, &openapi2.Parameter{Ref: v2Ref}\n\t\t\t}\n\t\t}\n\n\t\treturn &openapi2.SchemaRef{Ref: FromV3Ref(ref)}, nil\n\t}\n\tif schema.Value == nil {\n\t\treturn &openapi2.SchemaRef{\n\t\t\tExtensions: schema.Extensions,\n\t\t}, nil\n\t}\n\n\tif schema.Value != nil {\n\t\tif schema.Value.Type.Is(\"string\") && schema.Value.Format == \"binary\" {\n\t\t\tparamType := &openapi3.Types{\"file\"}\n\t\t\trequired := false\n\n\t\t\tvalue, _ := schema.Value.Extensions[\"x-formData-name\"]\n\t\t\toriginalName, _ := value.(string)\n\t\t\tfor _, prop := range schema.Value.Required {\n\t\t\t\tif originalName == prop {\n\t\t\t\t\trequired = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil, &openapi2.Parameter{\n\t\t\t\tIn:           \"formData\",\n\t\t\t\tName:         originalName,\n\t\t\t\tDescription:  schema.Value.Description,\n\t\t\t\tType:         paramType,\n\t\t\t\tEnum:         schema.Value.Enum,\n\t\t\t\tMinimum:      schema.Value.Min,\n\t\t\t\tMaximum:      schema.Value.Max,\n\t\t\t\tExclusiveMin: schema.Value.ExclusiveMin,\n\t\t\t\tExclusiveMax: schema.Value.ExclusiveMax,\n\t\t\t\tMinLength:    schema.Value.MinLength,\n\t\t\t\tMaxLength:    schema.Value.MaxLength,\n\t\t\t\tDefault:      schema.Value.Default,\n\t\t\t\t// Items:           schema.Value.Items,\n\t\t\t\tMinItems:        schema.Value.MinItems,\n\t\t\t\tMaxItems:        schema.Value.MaxItems,\n\t\t\t\tAllowEmptyValue: schema.Value.AllowEmptyValue,\n\t\t\t\tUniqueItems:     schema.Value.UniqueItems,\n\t\t\t\tMultipleOf:      schema.Value.MultipleOf,\n\t\t\t\tExtensions:      stripNonExtensions(schema.Value.Extensions),\n\t\t\t\tRequired:        required,\n\t\t\t}\n\t\t}\n\t}\n\n\tv2Schema := &openapi2.Schema{\n\t\tExtensions:           schema.Value.Extensions,\n\t\tType:                 schema.Value.Type,\n\t\tTitle:                schema.Value.Title,\n\t\tFormat:               schema.Value.Format,\n\t\tDescription:          schema.Value.Description,\n\t\tEnum:                 schema.Value.Enum,\n\t\tDefault:              schema.Value.Default,\n\t\tExample:              schema.Value.Example,\n\t\tExternalDocs:         schema.Value.ExternalDocs,\n\t\tUniqueItems:          schema.Value.UniqueItems,\n\t\tExclusiveMin:         schema.Value.ExclusiveMin,\n\t\tExclusiveMax:         schema.Value.ExclusiveMax,\n\t\tReadOnly:             schema.Value.ReadOnly,\n\t\tWriteOnly:            schema.Value.WriteOnly,\n\t\tAllowEmptyValue:      schema.Value.AllowEmptyValue,\n\t\tDeprecated:           schema.Value.Deprecated,\n\t\tXML:                  schema.Value.XML,\n\t\tMin:                  schema.Value.Min,\n\t\tMax:                  schema.Value.Max,\n\t\tMultipleOf:           schema.Value.MultipleOf,\n\t\tMinLength:            schema.Value.MinLength,\n\t\tMaxLength:            schema.Value.MaxLength,\n\t\tPattern:              schema.Value.Pattern,\n\t\tMinItems:             schema.Value.MinItems,\n\t\tMaxItems:             schema.Value.MaxItems,\n\t\tRequired:             schema.Value.Required,\n\t\tMinProps:             schema.Value.MinProps,\n\t\tMaxProps:             schema.Value.MaxProps,\n\t\tProperties:           make(openapi2.Schemas),\n\t\tAllOf:                make(openapi2.SchemaRefs, len(schema.Value.AllOf)),\n\t\tAdditionalProperties: schema.Value.AdditionalProperties,\n\t}\n\n\tif v := schema.Value.Items; v != nil {\n\t\tv2Schema.Items, _ = FromV3SchemaRef(v, components)\n\t}\n\n\tkeys := make([]string, 0, len(schema.Value.Properties))\n\tfor k := range schema.Value.Properties {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\tfor _, key := range keys {\n\t\tproperty, _ := FromV3SchemaRef(schema.Value.Properties[key], components)\n\t\tif property != nil {\n\t\t\tv2Schema.Properties[key] = property\n\t\t}\n\t}\n\n\tfor i, v := range schema.Value.AllOf {\n\t\tv2Schema.AllOf[i], _ = FromV3SchemaRef(v, components)\n\t}\n\tif schema.Value.PermitsNull() {\n\t\tschema.Value.Nullable = false\n\t\tif schema.Value.Extensions == nil {\n\t\t\tv2Schema.Extensions = make(map[string]any)\n\t\t}\n\t\tv2Schema.Extensions[\"x-nullable\"] = true\n\t}\n\n\treturn &openapi2.SchemaRef{\n\t\tExtensions: schema.Extensions,\n\t\tValue:      v2Schema,\n\t}, nil\n}\n\nfunc FromV3SecurityRequirements(requirements openapi3.SecurityRequirements) openapi2.SecurityRequirements {\n\tif requirements == nil {\n\t\treturn nil\n\t}\n\tresult := make([]map[string][]string, 0, len(requirements))\n\tfor _, item := range requirements {\n\t\tresult = append(result, item)\n\t}\n\treturn result\n}\n\nfunc FromV3PathItem(doc3 *openapi3.T, pathItem *openapi3.PathItem) (*openapi2.PathItem, error) {\n\tresult := &openapi2.PathItem{\n\t\tExtensions: stripNonExtensions(pathItem.Extensions),\n\t}\n\tfor method, operation := range pathItem.Operations() {\n\t\tr, err := FromV3Operation(doc3, operation)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresult.SetOperation(method, r)\n\t}\n\tfor _, parameter := range pathItem.Parameters {\n\t\tp, err := FromV3Parameter(parameter, doc3.Components)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresult.Parameters = append(result.Parameters, p)\n\t}\n\treturn result, nil\n}\n\nfunc findNameForRequestBody(operation *openapi3.Operation) string {\nnameSearch:\n\tfor _, name := range attemptedBodyParameterNames {\n\t\tfor _, parameterRef := range operation.Parameters {\n\t\t\tparameter := parameterRef.Value\n\t\t\tif parameter != nil && parameter.Name == name {\n\t\t\t\tcontinue nameSearch\n\t\t\t}\n\t\t}\n\t\treturn name\n\t}\n\treturn \"\"\n}\n\nfunc FromV3RequestBodyFormData(mediaType *openapi3.MediaType) openapi2.Parameters {\n\tparameters := openapi2.Parameters{}\n\tfor propName, schemaRef := range mediaType.Schema.Value.Properties {\n\t\tif ref := schemaRef.Ref; ref != \"\" {\n\t\t\tv2Ref := strings.Replace(ref, \"#/components/schemas/\", \"#/parameters/\", 1)\n\t\t\tparameters = append(parameters, &openapi2.Parameter{Ref: v2Ref})\n\t\t\tcontinue\n\t\t}\n\t\tval := schemaRef.Value\n\t\ttyp := val.Type\n\t\tif val.Format == \"binary\" {\n\t\t\ttyp = &openapi3.Types{\"file\"}\n\t\t}\n\t\trequired := false\n\t\tfor _, name := range val.Required {\n\t\t\tif name == propName {\n\t\t\t\trequired = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tvar v2Items *openapi2.SchemaRef\n\t\tif val.Items != nil {\n\t\t\tv2Items, _ = FromV3SchemaRef(val.Items, nil)\n\t\t}\n\t\tparameter := &openapi2.Parameter{\n\t\t\tName:         propName,\n\t\t\tDescription:  val.Description,\n\t\t\tType:         typ,\n\t\t\tIn:           \"formData\",\n\t\t\tExtensions:   stripNonExtensions(val.Extensions),\n\t\t\tEnum:         val.Enum,\n\t\t\tExclusiveMin: val.ExclusiveMin,\n\t\t\tExclusiveMax: val.ExclusiveMax,\n\t\t\tMinLength:    val.MinLength,\n\t\t\tMaxLength:    val.MaxLength,\n\t\t\tDefault:      val.Default,\n\t\t\tItems:        v2Items,\n\t\t\tMinItems:     val.MinItems,\n\t\t\tMaxItems:     val.MaxItems,\n\t\t\tMaximum:      val.Max,\n\t\t\tMinimum:      val.Min,\n\t\t\tPattern:      val.Pattern,\n\t\t\t// CollectionFormat: val.CollectionFormat,\n\t\t\t// Format:          val.Format,\n\t\t\tAllowEmptyValue: val.AllowEmptyValue,\n\t\t\tRequired:        required,\n\t\t\tUniqueItems:     val.UniqueItems,\n\t\t\tMultipleOf:      val.MultipleOf,\n\t\t}\n\t\tparameters = append(parameters, parameter)\n\t}\n\treturn parameters\n}\n\nfunc FromV3Operation(doc3 *openapi3.T, operation *openapi3.Operation) (*openapi2.Operation, error) {\n\tif operation == nil {\n\t\treturn nil, nil\n\t}\n\tresult := &openapi2.Operation{\n\t\tOperationID: operation.OperationID,\n\t\tSummary:     operation.Summary,\n\t\tDescription: operation.Description,\n\t\tDeprecated:  operation.Deprecated,\n\t\tTags:        operation.Tags,\n\t\tExtensions:  stripNonExtensions(operation.Extensions),\n\t}\n\tif v := operation.Security; v != nil {\n\t\tresultSecurity := FromV3SecurityRequirements(*v)\n\t\tresult.Security = &resultSecurity\n\t}\n\tfor _, parameter := range operation.Parameters {\n\t\tr, err := FromV3Parameter(parameter, doc3.Components)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresult.Parameters = append(result.Parameters, r)\n\t}\n\tif v := operation.RequestBody; v != nil {\n\t\t// Find parameter name that we can use for the body\n\t\tname := findNameForRequestBody(operation)\n\t\tif name == \"\" {\n\t\t\treturn nil, errors.New(\"could not find a name for request body\")\n\t\t}\n\n\t\tbodyOrRefParameters, formDataParameters, consumes, err := fromV3RequestBodies(name, v, doc3.Components)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(formDataParameters) != 0 {\n\t\t\tresult.Parameters = append(result.Parameters, formDataParameters...)\n\t\t} else if len(bodyOrRefParameters) != 0 {\n\t\t\tfor _, param := range bodyOrRefParameters {\n\t\t\t\tresult.Parameters = append(result.Parameters, param)\n\t\t\t\tbreak // add a single request body\n\t\t\t}\n\n\t\t}\n\n\t\tif len(consumes) != 0 {\n\t\t\tresult.Consumes = consumesToArray(consumes)\n\t\t}\n\t}\n\tsort.Sort(result.Parameters)\n\n\tif responses := operation.Responses; responses != nil {\n\t\tresultResponses, err := FromV3Responses(responses.Map(), doc3.Components)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresult.Responses = resultResponses\n\t}\n\treturn result, nil\n}\n\nfunc FromV3RequestBody(name string, requestBodyRef *openapi3.RequestBodyRef, mediaType *openapi3.MediaType, components *openapi3.Components) (*openapi2.Parameter, error) {\n\trequestBody := requestBodyRef.Value\n\n\tresult := &openapi2.Parameter{\n\t\tIn:          \"body\",\n\t\tName:        name,\n\t\tDescription: requestBody.Description,\n\t\tRequired:    requestBody.Required,\n\t\tExtensions:  stripNonExtensions(requestBody.Extensions),\n\t}\n\n\tif mediaType != nil {\n\t\tresult.Schema, _ = FromV3SchemaRef(mediaType.Schema, components)\n\t}\n\treturn result, nil\n}\n\nfunc FromV3Parameter(ref *openapi3.ParameterRef, components *openapi3.Components) (*openapi2.Parameter, error) {\n\tif ref := ref.Ref; ref != \"\" {\n\t\treturn &openapi2.Parameter{Ref: FromV3Ref(ref)}, nil\n\t}\n\tparameter := ref.Value\n\tif parameter == nil {\n\t\treturn nil, nil\n\t}\n\tresult := &openapi2.Parameter{\n\t\tDescription: parameter.Description,\n\t\tIn:          parameter.In,\n\t\tName:        parameter.Name,\n\t\tRequired:    parameter.Required,\n\t\tExtensions:  stripNonExtensions(parameter.Extensions),\n\t}\n\tif schemaRef := parameter.Schema; schemaRef != nil {\n\t\tschemaRefV2, _ := FromV3SchemaRef(schemaRef, components)\n\t\tif ref := schemaRefV2.Ref; ref != \"\" {\n\t\t\tresult.Schema = &openapi2.SchemaRef{Ref: FromV3Ref(ref)}\n\t\t\treturn result, nil\n\t\t}\n\t\tschema := schemaRefV2.Value\n\t\tresult.Type = schema.Type\n\t\tresult.Format = schema.Format\n\t\tresult.Enum = schema.Enum\n\t\tresult.Minimum = schema.Min\n\t\tresult.Maximum = schema.Max\n\t\tresult.ExclusiveMin = schema.ExclusiveMin\n\t\tresult.ExclusiveMax = schema.ExclusiveMax\n\t\tresult.MinLength = schema.MinLength\n\t\tresult.MaxLength = schema.MaxLength\n\t\tresult.Pattern = schema.Pattern\n\t\tresult.Default = schema.Default\n\t\tresult.Items = schema.Items\n\t\tresult.MinItems = schema.MinItems\n\t\tresult.MaxItems = schema.MaxItems\n\t\tresult.AllowEmptyValue = schema.AllowEmptyValue\n\t\t// result.CollectionFormat = schema.CollectionFormat\n\t\tresult.UniqueItems = schema.UniqueItems\n\t\tresult.MultipleOf = schema.MultipleOf\n\t}\n\treturn result, nil\n}\n\nfunc FromV3Responses(responses map[string]*openapi3.ResponseRef, components *openapi3.Components) (map[string]*openapi2.Response, error) {\n\tv2Responses := make(map[string]*openapi2.Response, len(responses))\n\tfor k, response := range responses {\n\t\tr, err := FromV3Response(response, components)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tv2Responses[k] = r\n\t}\n\treturn v2Responses, nil\n}\n\nfunc FromV3Response(ref *openapi3.ResponseRef, components *openapi3.Components) (*openapi2.Response, error) {\n\tif ref := ref.Ref; ref != \"\" {\n\t\treturn &openapi2.Response{Ref: FromV3Ref(ref)}, nil\n\t}\n\n\tresponse := ref.Value\n\tif response == nil {\n\t\treturn nil, nil\n\t}\n\tdescription := \"\"\n\tif desc := response.Description; desc != nil {\n\t\tdescription = *desc\n\t}\n\tresult := &openapi2.Response{\n\t\tDescription: description,\n\t\tExtensions:  stripNonExtensions(response.Extensions),\n\t}\n\tif content := response.Content; content != nil {\n\t\tif ct := content[\"application/json\"]; ct != nil {\n\t\t\tresult.Schema, _ = FromV3SchemaRef(ct.Schema, components)\n\t\t}\n\t}\n\tif headers := response.Headers; len(headers) > 0 {\n\t\tvar err error\n\t\tif result.Headers, err = FromV3Headers(headers, components); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn result, nil\n}\n\nfunc FromV3Headers(defs openapi3.Headers, components *openapi3.Components) (map[string]*openapi2.Header, error) {\n\theaders := make(map[string]*openapi2.Header, len(defs))\n\tfor name, header := range defs {\n\t\tref := openapi3.ParameterRef{Ref: header.Ref, Value: &header.Value.Parameter}\n\t\tparameter, err := FromV3Parameter(&ref, components)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tparameter.In = \"\"\n\t\tparameter.Name = \"\"\n\t\theaders[name] = &openapi2.Header{Parameter: *parameter}\n\t}\n\treturn headers, nil\n}\n\nfunc FromV3SecurityScheme(doc3 *openapi3.T, ref *openapi3.SecuritySchemeRef) (*openapi2.SecurityScheme, error) {\n\tsecurityScheme := ref.Value\n\tif securityScheme == nil {\n\t\treturn nil, nil\n\t}\n\tresult := &openapi2.SecurityScheme{\n\t\tRef:         FromV3Ref(ref.Ref),\n\t\tDescription: securityScheme.Description,\n\t\tExtensions:  stripNonExtensions(securityScheme.Extensions),\n\t}\n\tswitch securityScheme.Type {\n\tcase \"http\":\n\t\tswitch securityScheme.Scheme {\n\t\tcase \"basic\":\n\t\t\tresult.Type = \"basic\"\n\t\tdefault:\n\t\t\tresult.Type = \"apiKey\"\n\t\t\tresult.In = \"header\"\n\t\t\tresult.Name = \"Authorization\"\n\t\t}\n\tcase \"apiKey\":\n\t\tresult.Type = \"apiKey\"\n\t\tresult.In = securityScheme.In\n\t\tresult.Name = securityScheme.Name\n\tcase \"oauth2\":\n\t\tresult.Type = \"oauth2\"\n\t\tflows := securityScheme.Flows\n\t\tif flows != nil {\n\t\t\tvar flow *openapi3.OAuthFlow\n\t\t\t// TODO: Is this the right priority? What if multiple defined?\n\t\t\tswitch {\n\t\t\tcase flows.Implicit != nil:\n\t\t\t\tresult.Flow = \"implicit\"\n\t\t\t\tflow = flows.Implicit\n\t\t\t\tresult.AuthorizationURL = flow.AuthorizationURL\n\n\t\t\tcase flows.AuthorizationCode != nil:\n\t\t\t\tresult.Flow = \"accessCode\"\n\t\t\t\tflow = flows.AuthorizationCode\n\t\t\t\tresult.AuthorizationURL = flow.AuthorizationURL\n\t\t\t\tresult.TokenURL = flow.TokenURL\n\n\t\t\tcase flows.Password != nil:\n\t\t\t\tresult.Flow = \"password\"\n\t\t\t\tflow = flows.Password\n\t\t\t\tresult.TokenURL = flow.TokenURL\n\n\t\t\tcase flows.ClientCredentials != nil:\n\t\t\t\tresult.Flow = \"application\"\n\t\t\t\tflow = flows.ClientCredentials\n\t\t\t\tresult.TokenURL = flow.TokenURL\n\n\t\t\tdefault:\n\t\t\t\treturn nil, nil\n\t\t\t}\n\n\t\t\tresult.Scopes = make(map[string]string, len(flow.Scopes))\n\t\t\tfor scope, desc := range flow.Scopes {\n\t\t\t\tresult.Scopes[scope] = desc\n\t\t\t}\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported security scheme type %q\", securityScheme.Type)\n\t}\n\treturn result, nil\n}\n\nvar attemptedBodyParameterNames = []string{\n\t\"body\",\n\t\"requestBody\",\n}\n\n// stripNonExtensions removes invalid extensions: those not prefixed by \"x-\" and returns them\nfunc stripNonExtensions(extensions map[string]any) map[string]any {\n\tfor extName := range extensions {\n\t\tif !strings.HasPrefix(extName, \"x-\") {\n\t\t\tdelete(extensions, extName)\n\t\t}\n\t}\n\treturn extensions\n}\n\nfunc addPathExtensions(doc2 *openapi2.T, path string, extensions map[string]any) {\n\tif doc2.Paths == nil {\n\t\tdoc2.Paths = make(map[string]*openapi2.PathItem)\n\t}\n\tpathItem := doc2.Paths[path]\n\tif pathItem == nil {\n\t\tpathItem = &openapi2.PathItem{}\n\t\tdoc2.Paths[path] = pathItem\n\t}\n\tpathItem.Extensions = extensions\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/callback.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"sort\"\n)\n\n// Callback is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callback-object\ntype Callback struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tm map[string]*PathItem\n}\n\n// NewCallback builds a Callback object with path items in insertion order.\nfunc NewCallback(opts ...NewCallbackOption) *Callback {\n\tCallback := NewCallbackWithCapacity(len(opts))\n\tfor _, opt := range opts {\n\t\topt(Callback)\n\t}\n\treturn Callback\n}\n\n// NewCallbackOption describes options to NewCallback func\ntype NewCallbackOption func(*Callback)\n\n// WithCallback adds Callback as an option to NewCallback\nfunc WithCallback(cb string, pathItem *PathItem) NewCallbackOption {\n\treturn func(callback *Callback) {\n\t\tif p := pathItem; p != nil && cb != \"\" {\n\t\t\tcallback.Set(cb, p)\n\t\t}\n\t}\n}\n\n// Validate returns an error if Callback does not comply with the OpenAPI spec.\nfunc (callback *Callback) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tkeys := make([]string, 0, callback.Len())\n\tfor key := range callback.Map() {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\tfor _, key := range keys {\n\t\tv := callback.Value(key)\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, callback.Extensions)\n}\n\n// UnmarshalJSON sets Callbacks to a copy of data.\nfunc (callbacks *Callbacks) UnmarshalJSON(data []byte) (err error) {\n\t*callbacks, _, err = unmarshalStringMapP[CallbackRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/components.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\ntype (\n\tCallbacks       map[string]*CallbackRef\n\tExamples        map[string]*ExampleRef\n\tHeaders         map[string]*HeaderRef\n\tLinks           map[string]*LinkRef\n\tParametersMap   map[string]*ParameterRef\n\tRequestBodies   map[string]*RequestBodyRef\n\tResponseBodies  map[string]*ResponseRef\n\tSchemas         map[string]*SchemaRef\n\tSecuritySchemes map[string]*SecuritySchemeRef\n)\n\n// Components is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#components-object\ntype Components struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tSchemas         Schemas         `json:\"schemas,omitempty\" yaml:\"schemas,omitempty\"`\n\tParameters      ParametersMap   `json:\"parameters,omitempty\" yaml:\"parameters,omitempty\"`\n\tHeaders         Headers         `json:\"headers,omitempty\" yaml:\"headers,omitempty\"`\n\tRequestBodies   RequestBodies   `json:\"requestBodies,omitempty\" yaml:\"requestBodies,omitempty\"`\n\tResponses       ResponseBodies  `json:\"responses,omitempty\" yaml:\"responses,omitempty\"`\n\tSecuritySchemes SecuritySchemes `json:\"securitySchemes,omitempty\" yaml:\"securitySchemes,omitempty\"`\n\tExamples        Examples        `json:\"examples,omitempty\" yaml:\"examples,omitempty\"`\n\tLinks           Links           `json:\"links,omitempty\" yaml:\"links,omitempty\"`\n\tCallbacks       Callbacks       `json:\"callbacks,omitempty\" yaml:\"callbacks,omitempty\"`\n}\n\nfunc NewComponents() Components {\n\treturn Components{}\n}\n\n// MarshalJSON returns the JSON encoding of Components.\nfunc (components Components) MarshalJSON() ([]byte, error) {\n\tx, err := components.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Components.\nfunc (components Components) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 9+len(components.Extensions))\n\tfor k, v := range components.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := components.Schemas; len(x) != 0 {\n\t\tm[\"schemas\"] = x\n\t}\n\tif x := components.Parameters; len(x) != 0 {\n\t\tm[\"parameters\"] = x\n\t}\n\tif x := components.Headers; len(x) != 0 {\n\t\tm[\"headers\"] = x\n\t}\n\tif x := components.RequestBodies; len(x) != 0 {\n\t\tm[\"requestBodies\"] = x\n\t}\n\tif x := components.Responses; len(x) != 0 {\n\t\tm[\"responses\"] = x\n\t}\n\tif x := components.SecuritySchemes; len(x) != 0 {\n\t\tm[\"securitySchemes\"] = x\n\t}\n\tif x := components.Examples; len(x) != 0 {\n\t\tm[\"examples\"] = x\n\t}\n\tif x := components.Links; len(x) != 0 {\n\t\tm[\"links\"] = x\n\t}\n\tif x := components.Callbacks; len(x) != 0 {\n\t\tm[\"callbacks\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Components to a copy of data.\nfunc (components *Components) UnmarshalJSON(data []byte) error {\n\ttype ComponentsBis Components\n\tvar x ComponentsBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"schemas\")\n\tdelete(x.Extensions, \"parameters\")\n\tdelete(x.Extensions, \"headers\")\n\tdelete(x.Extensions, \"requestBodies\")\n\tdelete(x.Extensions, \"responses\")\n\tdelete(x.Extensions, \"securitySchemes\")\n\tdelete(x.Extensions, \"examples\")\n\tdelete(x.Extensions, \"links\")\n\tdelete(x.Extensions, \"callbacks\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*components = Components(x)\n\treturn nil\n}\n\n// Validate returns an error if Components does not comply with the OpenAPI spec.\nfunc (components *Components) Validate(ctx context.Context, opts ...ValidationOption) (err error) {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tschemas := make([]string, 0, len(components.Schemas))\n\tfor name := range components.Schemas {\n\t\tschemas = append(schemas, name)\n\t}\n\tsort.Strings(schemas)\n\tfor _, k := range schemas {\n\t\tv := components.Schemas[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"schema %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"schema %q: %w\", k, err)\n\t\t}\n\t}\n\n\tparameters := make([]string, 0, len(components.Parameters))\n\tfor name := range components.Parameters {\n\t\tparameters = append(parameters, name)\n\t}\n\tsort.Strings(parameters)\n\tfor _, k := range parameters {\n\t\tv := components.Parameters[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"parameter %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"parameter %q: %w\", k, err)\n\t\t}\n\t}\n\n\trequestBodies := make([]string, 0, len(components.RequestBodies))\n\tfor name := range components.RequestBodies {\n\t\trequestBodies = append(requestBodies, name)\n\t}\n\tsort.Strings(requestBodies)\n\tfor _, k := range requestBodies {\n\t\tv := components.RequestBodies[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"request body %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"request body %q: %w\", k, err)\n\t\t}\n\t}\n\n\tresponses := make([]string, 0, len(components.Responses))\n\tfor name := range components.Responses {\n\t\tresponses = append(responses, name)\n\t}\n\tsort.Strings(responses)\n\tfor _, k := range responses {\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"response %q: %w\", k, err)\n\t\t}\n\t\tv := components.Responses[k]\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"response %q: %w\", k, err)\n\t\t}\n\t}\n\n\theaders := make([]string, 0, len(components.Headers))\n\tfor name := range components.Headers {\n\t\theaders = append(headers, name)\n\t}\n\tsort.Strings(headers)\n\tfor _, k := range headers {\n\t\tv := components.Headers[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"header %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"header %q: %w\", k, err)\n\t\t}\n\t}\n\n\tsecuritySchemes := make([]string, 0, len(components.SecuritySchemes))\n\tfor name := range components.SecuritySchemes {\n\t\tsecuritySchemes = append(securitySchemes, name)\n\t}\n\tsort.Strings(securitySchemes)\n\tfor _, k := range securitySchemes {\n\t\tv := components.SecuritySchemes[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"security scheme %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"security scheme %q: %w\", k, err)\n\t\t}\n\t}\n\n\texamples := make([]string, 0, len(components.Examples))\n\tfor name := range components.Examples {\n\t\texamples = append(examples, name)\n\t}\n\tsort.Strings(examples)\n\tfor _, k := range examples {\n\t\tv := components.Examples[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"example %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"example %q: %w\", k, err)\n\t\t}\n\t}\n\n\tlinks := make([]string, 0, len(components.Links))\n\tfor name := range components.Links {\n\t\tlinks = append(links, name)\n\t}\n\tsort.Strings(links)\n\tfor _, k := range links {\n\t\tv := components.Links[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"link %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"link %q: %w\", k, err)\n\t\t}\n\t}\n\n\tcallbacks := make([]string, 0, len(components.Callbacks))\n\tfor name := range components.Callbacks {\n\t\tcallbacks = append(callbacks, name)\n\t}\n\tsort.Strings(callbacks)\n\tfor _, k := range callbacks {\n\t\tv := components.Callbacks[k]\n\t\tif err = ValidateIdentifier(k); err != nil {\n\t\t\treturn fmt.Errorf(\"callback %q: %w\", k, err)\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"callback %q: %w\", k, err)\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, components.Extensions)\n}\n\nvar _ jsonpointer.JSONPointable = (*Schemas)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m Schemas) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no schema %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*ParametersMap)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m ParametersMap) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no parameter %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*Headers)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m Headers) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no header %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m RequestBodies) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no request body %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*ResponseRef)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m ResponseBodies) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no response body %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*SecuritySchemes)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m SecuritySchemes) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no security scheme body %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*Examples)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m Examples) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no example body %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*Links)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m Links) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no link body %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n\nvar _ jsonpointer.JSONPointable = (*Callbacks)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (m Callbacks) JSONLookup(token string) (any, error) {\n\tif v, ok := m[token]; !ok || v == nil {\n\t\treturn nil, fmt.Errorf(\"no callback body %q\", token)\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\treturn v.Value, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/contact.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n)\n\n// Contact is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#contact-object\ntype Contact struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tName  string `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tURL   string `json:\"url,omitempty\" yaml:\"url,omitempty\"`\n\tEmail string `json:\"email,omitempty\" yaml:\"email,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Contact.\nfunc (contact Contact) MarshalJSON() ([]byte, error) {\n\tx, err := contact.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Contact.\nfunc (contact Contact) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 3+len(contact.Extensions))\n\tfor k, v := range contact.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := contact.Name; x != \"\" {\n\t\tm[\"name\"] = x\n\t}\n\tif x := contact.URL; x != \"\" {\n\t\tm[\"url\"] = x\n\t}\n\tif x := contact.Email; x != \"\" {\n\t\tm[\"email\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Contact to a copy of data.\nfunc (contact *Contact) UnmarshalJSON(data []byte) error {\n\ttype ContactBis Contact\n\tvar x ContactBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"url\")\n\tdelete(x.Extensions, \"email\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*contact = Contact(x)\n\treturn nil\n}\n\n// Validate returns an error if Contact does not comply with the OpenAPI spec.\nfunc (contact *Contact) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\treturn validateExtensions(ctx, contact.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/content.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// Content is specified by OpenAPI/Swagger 3.0 standard.\ntype Content map[string]*MediaType\n\nfunc NewContent() Content {\n\treturn make(map[string]*MediaType)\n}\n\nfunc NewContentWithSchema(schema *Schema, consumes []string) Content {\n\tif len(consumes) == 0 {\n\t\treturn Content{\n\t\t\t\"*/*\": NewMediaType().WithSchema(schema),\n\t\t}\n\t}\n\tcontent := make(map[string]*MediaType, len(consumes))\n\tfor _, mediaType := range consumes {\n\t\tcontent[mediaType] = NewMediaType().WithSchema(schema)\n\t}\n\treturn content\n}\n\nfunc NewContentWithSchemaRef(schema *SchemaRef, consumes []string) Content {\n\tif len(consumes) == 0 {\n\t\treturn Content{\n\t\t\t\"*/*\": NewMediaType().WithSchemaRef(schema),\n\t\t}\n\t}\n\tcontent := make(map[string]*MediaType, len(consumes))\n\tfor _, mediaType := range consumes {\n\t\tcontent[mediaType] = NewMediaType().WithSchemaRef(schema)\n\t}\n\treturn content\n}\n\nfunc NewContentWithJSONSchema(schema *Schema) Content {\n\treturn Content{\n\t\t\"application/json\": NewMediaType().WithSchema(schema),\n\t}\n}\nfunc NewContentWithJSONSchemaRef(schema *SchemaRef) Content {\n\treturn Content{\n\t\t\"application/json\": NewMediaType().WithSchemaRef(schema),\n\t}\n}\n\nfunc NewContentWithFormDataSchema(schema *Schema) Content {\n\treturn Content{\n\t\t\"multipart/form-data\": NewMediaType().WithSchema(schema),\n\t}\n}\n\nfunc NewContentWithFormDataSchemaRef(schema *SchemaRef) Content {\n\treturn Content{\n\t\t\"multipart/form-data\": NewMediaType().WithSchemaRef(schema),\n\t}\n}\n\nfunc (content Content) Get(mime string) *MediaType {\n\t// If the mime is empty then short-circuit to the wildcard.\n\t// We do this here so that we catch only the specific case of\n\t// and empty mime rather than a present, but invalid, mime type.\n\tif mime == \"\" {\n\t\treturn content[\"*/*\"]\n\t}\n\t// Start by making the most specific match possible\n\t// by using the mime type in full.\n\tif v := content[mime]; v != nil {\n\t\treturn v\n\t}\n\t// If an exact match is not found then we strip all\n\t// metadata from the mime type and only use the x/y\n\t// portion.\n\ti := strings.IndexByte(mime, ';')\n\tif i < 0 {\n\t\t// If there is no metadata then preserve the full mime type\n\t\t// string for later wildcard searches.\n\t\ti = len(mime)\n\t}\n\tmime = mime[:i]\n\tif v := content[mime]; v != nil {\n\t\treturn v\n\t}\n\t// If the x/y pattern has no specific match then we\n\t// try the x/* pattern.\n\ti = strings.IndexByte(mime, '/')\n\tif i < 0 {\n\t\t// In the case that the given mime type is not valid because it is\n\t\t// missing the subtype we return nil so that this does not accidentally\n\t\t// resolve with the wildcard.\n\t\treturn nil\n\t}\n\tmime = mime[:i] + \"/*\"\n\tif v := content[mime]; v != nil {\n\t\treturn v\n\t}\n\t// Finally, the most generic match of */* is returned\n\t// as a catch-all.\n\treturn content[\"*/*\"]\n}\n\n// Validate returns an error if Content does not comply with the OpenAPI spec.\nfunc (content Content) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tkeys := make([]string, 0, len(content))\n\tfor key := range content {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\tfor _, k := range keys {\n\t\tv := content[k]\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// UnmarshalJSON sets Content to a copy of data.\nfunc (content *Content) UnmarshalJSON(data []byte) (err error) {\n\t*content, _, err = unmarshalStringMapP[MediaType](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/discriminator.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n)\n\n// Discriminator is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#discriminator-object\ntype Discriminator struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tPropertyName string    `json:\"propertyName\" yaml:\"propertyName\"` // required\n\tMapping      StringMap `json:\"mapping,omitempty\" yaml:\"mapping,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Discriminator.\nfunc (discriminator Discriminator) MarshalJSON() ([]byte, error) {\n\tx, err := discriminator.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Discriminator.\nfunc (discriminator Discriminator) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 2+len(discriminator.Extensions))\n\tfor k, v := range discriminator.Extensions {\n\t\tm[k] = v\n\t}\n\tm[\"propertyName\"] = discriminator.PropertyName\n\tif x := discriminator.Mapping; len(x) != 0 {\n\t\tm[\"mapping\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Discriminator to a copy of data.\nfunc (discriminator *Discriminator) UnmarshalJSON(data []byte) error {\n\ttype DiscriminatorBis Discriminator\n\tvar x DiscriminatorBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"propertyName\")\n\tdelete(x.Extensions, \"mapping\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*discriminator = Discriminator(x)\n\treturn nil\n}\n\n// Validate returns an error if Discriminator does not comply with the OpenAPI spec.\nfunc (discriminator *Discriminator) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\treturn validateExtensions(ctx, discriminator.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/doc.go",
    "content": "// Package openapi3 parses and writes OpenAPI 3 specification documents.\n//\n// See https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md\npackage openapi3\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/encoding.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n)\n\n// Encoding is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#encoding-object\ntype Encoding struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tContentType   string  `json:\"contentType,omitempty\" yaml:\"contentType,omitempty\"`\n\tHeaders       Headers `json:\"headers,omitempty\" yaml:\"headers,omitempty\"`\n\tStyle         string  `json:\"style,omitempty\" yaml:\"style,omitempty\"`\n\tExplode       *bool   `json:\"explode,omitempty\" yaml:\"explode,omitempty\"`\n\tAllowReserved bool    `json:\"allowReserved,omitempty\" yaml:\"allowReserved,omitempty\"`\n}\n\nfunc NewEncoding() *Encoding {\n\treturn &Encoding{}\n}\n\nfunc (encoding *Encoding) WithHeader(name string, header *Header) *Encoding {\n\treturn encoding.WithHeaderRef(name, &HeaderRef{\n\t\tValue: header,\n\t})\n}\n\nfunc (encoding *Encoding) WithHeaderRef(name string, ref *HeaderRef) *Encoding {\n\theaders := encoding.Headers\n\tif headers == nil {\n\t\theaders = make(map[string]*HeaderRef)\n\t\tencoding.Headers = headers\n\t}\n\theaders[name] = ref\n\treturn encoding\n}\n\n// MarshalJSON returns the JSON encoding of Encoding.\nfunc (encoding Encoding) MarshalJSON() ([]byte, error) {\n\tx, err := encoding.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Encoding.\nfunc (encoding Encoding) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 5+len(encoding.Extensions))\n\tfor k, v := range encoding.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := encoding.ContentType; x != \"\" {\n\t\tm[\"contentType\"] = x\n\t}\n\tif x := encoding.Headers; len(x) != 0 {\n\t\tm[\"headers\"] = x\n\t}\n\tif x := encoding.Style; x != \"\" {\n\t\tm[\"style\"] = x\n\t}\n\tif x := encoding.Explode; x != nil {\n\t\tm[\"explode\"] = x\n\t}\n\tif x := encoding.AllowReserved; x {\n\t\tm[\"allowReserved\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Encoding to a copy of data.\nfunc (encoding *Encoding) UnmarshalJSON(data []byte) error {\n\ttype EncodingBis Encoding\n\tvar x EncodingBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"contentType\")\n\tdelete(x.Extensions, \"headers\")\n\tdelete(x.Extensions, \"style\")\n\tdelete(x.Extensions, \"explode\")\n\tdelete(x.Extensions, \"allowReserved\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*encoding = Encoding(x)\n\treturn nil\n}\n\n// SerializationMethod returns a serialization method of request body.\n// When serialization method is not defined the method returns the default serialization method.\nfunc (encoding *Encoding) SerializationMethod() *SerializationMethod {\n\tsm := &SerializationMethod{Style: SerializationForm, Explode: true}\n\tif encoding != nil {\n\t\tif encoding.Style != \"\" {\n\t\t\tsm.Style = encoding.Style\n\t\t}\n\t\tif encoding.Explode != nil {\n\t\t\tsm.Explode = *encoding.Explode\n\t\t}\n\t}\n\treturn sm\n}\n\n// Validate returns an error if Encoding does not comply with the OpenAPI spec.\nfunc (encoding *Encoding) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif encoding == nil {\n\t\treturn nil\n\t}\n\n\theaders := make([]string, 0, len(encoding.Headers))\n\tfor k := range encoding.Headers {\n\t\theaders = append(headers, k)\n\t}\n\tsort.Strings(headers)\n\tfor _, k := range headers {\n\t\tv := encoding.Headers[k]\n\t\tif err := ValidateIdentifier(k); err != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// Validate a media types's serialization method.\n\tsm := encoding.SerializationMethod()\n\tswitch {\n\tcase sm.Style == SerializationForm && sm.Explode,\n\t\tsm.Style == SerializationForm && !sm.Explode,\n\t\tsm.Style == SerializationSpaceDelimited && sm.Explode,\n\t\tsm.Style == SerializationSpaceDelimited && !sm.Explode,\n\t\tsm.Style == SerializationPipeDelimited && sm.Explode,\n\t\tsm.Style == SerializationPipeDelimited && !sm.Explode,\n\t\tsm.Style == SerializationDeepObject && sm.Explode:\n\tdefault:\n\t\treturn fmt.Errorf(\"serialization method with style=%q and explode=%v is not supported by media type\", sm.Style, sm.Explode)\n\t}\n\n\treturn validateExtensions(ctx, encoding.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/errors.go",
    "content": "package openapi3\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n)\n\n// MultiError is a collection of errors, intended for when\n// multiple issues need to be reported upstream\ntype MultiError []error\n\nfunc (me MultiError) Error() string {\n\treturn spliceErr(\" | \", me)\n}\n\nfunc spliceErr(sep string, errs []error) string {\n\tbuff := &bytes.Buffer{}\n\tfor i, e := range errs {\n\t\tbuff.WriteString(e.Error())\n\t\tif i != len(errs)-1 {\n\t\t\tbuff.WriteString(sep)\n\t\t}\n\t}\n\treturn buff.String()\n}\n\n// Is allows you to determine if a generic error is in fact a MultiError using `errors.Is()`\n// It will also return true if any of the contained errors match target\nfunc (me MultiError) Is(target error) bool {\n\tif _, ok := target.(MultiError); ok {\n\t\treturn true\n\t}\n\tfor _, e := range me {\n\t\tif errors.Is(e, target) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// As allows you to use `errors.As()` to set target to the first error within the multi error that matches the target type\nfunc (me MultiError) As(target any) bool {\n\tfor _, e := range me {\n\t\tif errors.As(e, target) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype multiErrorForOneOf MultiError\n\nfunc (meo multiErrorForOneOf) Error() string {\n\treturn spliceErr(\" Or \", meo)\n}\n\nfunc (meo multiErrorForOneOf) Unwrap() error {\n\treturn MultiError(meo)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/example.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n)\n\n// Example is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#example-object\ntype Example struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tSummary       string `json:\"summary,omitempty\" yaml:\"summary,omitempty\"`\n\tDescription   string `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tValue         any    `json:\"value,omitempty\" yaml:\"value,omitempty\"`\n\tExternalValue string `json:\"externalValue,omitempty\" yaml:\"externalValue,omitempty\"`\n}\n\nfunc NewExample(value any) *Example {\n\treturn &Example{Value: value}\n}\n\n// MarshalJSON returns the JSON encoding of Example.\nfunc (example Example) MarshalJSON() ([]byte, error) {\n\tx, err := example.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Example.\nfunc (example Example) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 4+len(example.Extensions))\n\tfor k, v := range example.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := example.Summary; x != \"\" {\n\t\tm[\"summary\"] = x\n\t}\n\tif x := example.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := example.Value; x != nil {\n\t\tm[\"value\"] = x\n\t}\n\tif x := example.ExternalValue; x != \"\" {\n\t\tm[\"externalValue\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Example to a copy of data.\nfunc (example *Example) UnmarshalJSON(data []byte) error {\n\ttype ExampleBis Example\n\tvar x ExampleBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"summary\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"value\")\n\tdelete(x.Extensions, \"externalValue\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*example = Example(x)\n\treturn nil\n}\n\n// Validate returns an error if Example does not comply with the OpenAPI spec.\nfunc (example *Example) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif example.Value != nil && example.ExternalValue != \"\" {\n\t\treturn errors.New(\"value and externalValue are mutually exclusive\")\n\t}\n\tif example.Value == nil && example.ExternalValue == \"\" {\n\t\treturn errors.New(\"no value or externalValue field\")\n\t}\n\n\treturn validateExtensions(ctx, example.Extensions)\n}\n\n// UnmarshalJSON sets Examples to a copy of data.\nfunc (examples *Examples) UnmarshalJSON(data []byte) (err error) {\n\t*examples, _, err = unmarshalStringMapP[ExampleRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/example_validation.go",
    "content": "package openapi3\n\nimport \"context\"\n\nfunc validateExampleValue(ctx context.Context, input any, schema *Schema) error {\n\topts := make([]SchemaValidationOption, 0, 2)\n\n\tif vo := getValidationOptions(ctx); vo.examplesValidationAsReq {\n\t\topts = append(opts, VisitAsRequest())\n\t} else if vo.examplesValidationAsRes {\n\t\topts = append(opts, VisitAsResponse())\n\t}\n\topts = append(opts, MultiErrors())\n\n\treturn schema.VisitJSON(input, opts...)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/extension.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\nfunc validateExtensions(ctx context.Context, extensions map[string]any) error { // FIXME: newtype + Validate(...)\n\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\n\tvar unknowns []string\n\tfor k := range extensions {\n\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\tcontinue\n\t\t}\n\t\tif allowed != nil {\n\t\t\tif _, ok := allowed[k]; ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tunknowns = append(unknowns, k)\n\t}\n\n\tif len(unknowns) != 0 {\n\t\tsort.Strings(unknowns)\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", unknowns)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/external_docs.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n)\n\n// ExternalDocs is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#external-documentation-object\ntype ExternalDocs struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tDescription string `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tURL         string `json:\"url,omitempty\" yaml:\"url,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of ExternalDocs.\nfunc (e ExternalDocs) MarshalJSON() ([]byte, error) {\n\tx, err := e.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of ExternalDocs.\nfunc (e ExternalDocs) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 2+len(e.Extensions))\n\tfor k, v := range e.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := e.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := e.URL; x != \"\" {\n\t\tm[\"url\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets ExternalDocs to a copy of data.\nfunc (e *ExternalDocs) UnmarshalJSON(data []byte) error {\n\ttype ExternalDocsBis ExternalDocs\n\tvar x ExternalDocsBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"url\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*e = ExternalDocs(x)\n\treturn nil\n}\n\n// Validate returns an error if ExternalDocs does not comply with the OpenAPI spec.\nfunc (e *ExternalDocs) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif e.URL == \"\" {\n\t\treturn errors.New(\"url is required\")\n\t}\n\tif _, err := url.Parse(e.URL); err != nil {\n\t\treturn fmt.Errorf(\"url is incorrect: %w\", err)\n\t}\n\n\treturn validateExtensions(ctx, e.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/header.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\n// Header is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#header-object\ntype Header struct {\n\tParameter\n}\n\nvar _ jsonpointer.JSONPointable = (*Header)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (header Header) JSONLookup(token string) (any, error) {\n\treturn header.Parameter.JSONLookup(token)\n}\n\n// MarshalJSON returns the JSON encoding of Header.\nfunc (header Header) MarshalJSON() ([]byte, error) {\n\treturn header.Parameter.MarshalJSON()\n}\n\n// UnmarshalJSON sets Header to a copy of data.\nfunc (header *Header) UnmarshalJSON(data []byte) error {\n\treturn header.Parameter.UnmarshalJSON(data)\n}\n\n// MarshalYAML returns the JSON encoding of Header.\nfunc (header Header) MarshalYAML() (any, error) {\n\treturn header.Parameter, nil\n}\n\n// SerializationMethod returns a header's serialization method.\nfunc (header *Header) SerializationMethod() (*SerializationMethod, error) {\n\tstyle := header.Style\n\tif style == \"\" {\n\t\tstyle = SerializationSimple\n\t}\n\texplode := false\n\tif header.Explode != nil {\n\t\texplode = *header.Explode\n\t}\n\treturn &SerializationMethod{Style: style, Explode: explode}, nil\n}\n\n// Validate returns an error if Header does not comply with the OpenAPI spec.\nfunc (header *Header) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif header.Name != \"\" {\n\t\treturn errors.New(\"header 'name' MUST NOT be specified, it is given in the corresponding headers map\")\n\t}\n\tif header.In != \"\" {\n\t\treturn errors.New(\"header 'in' MUST NOT be specified, it is implicitly in header\")\n\t}\n\n\t// Validate a parameter's serialization method.\n\tsm, err := header.SerializationMethod()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif smSupported := false ||\n\t\tsm.Style == SerializationSimple && !sm.Explode ||\n\t\tsm.Style == SerializationSimple && sm.Explode; !smSupported {\n\t\te := fmt.Errorf(\"serialization method with style=%q and explode=%v is not supported by a header parameter\", sm.Style, sm.Explode)\n\t\treturn fmt.Errorf(\"header schema is invalid: %w\", e)\n\t}\n\n\tif (header.Schema == nil) == (len(header.Content) == 0) {\n\t\te := fmt.Errorf(\"parameter must contain exactly one of content and schema: %v\", header)\n\t\treturn fmt.Errorf(\"header schema is invalid: %w\", e)\n\t}\n\tif schema := header.Schema; schema != nil {\n\t\tif err := schema.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"header schema is invalid: %w\", err)\n\t\t}\n\t}\n\n\tif content := header.Content; content != nil {\n\t\te := errors.New(\"parameter content must only contain one entry\")\n\t\tif len(content) > 1 {\n\t\t\treturn fmt.Errorf(\"header content is invalid: %w\", e)\n\t\t}\n\n\t\tif err := content.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"header content is invalid: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// UnmarshalJSON sets Headers to a copy of data.\nfunc (headers *Headers) UnmarshalJSON(data []byte) (err error) {\n\t*headers, _, err = unmarshalStringMapP[HeaderRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/helpers.go",
    "content": "package openapi3\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"path\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\nconst identifierChars = `a-zA-Z0-9._-`\n\n// IdentifierRegExp verifies whether Component object key matches contains just 'identifierChars', according to OpenAPI v3.x.\n// InvalidIdentifierCharRegExp matches all characters not contained in 'identifierChars'.\n// However, to be able supporting legacy OpenAPI v2.x, there is a need to customize above pattern in order not to fail\n// converted v2-v3 validation\nvar (\n\tIdentifierRegExp            = regexp.MustCompile(`^[` + identifierChars + `]+$`)\n\tInvalidIdentifierCharRegExp = regexp.MustCompile(`[^` + identifierChars + `]`)\n)\n\n// ValidateIdentifier returns an error if the given component name does not match [IdentifierRegExp].\nfunc ValidateIdentifier(value string) error {\n\tif IdentifierRegExp.MatchString(value) {\n\t\treturn nil\n\t}\n\treturn fmt.Errorf(\"identifier %q is not supported by OpenAPIv3 standard (charset: [%q])\", value, identifierChars)\n}\n\n// Float64Ptr is a helper for defining OpenAPI schemas.\nfunc Float64Ptr(value float64) *float64 {\n\treturn &value\n}\n\n// BoolPtr is a helper for defining OpenAPI schemas.\nfunc BoolPtr(value bool) *bool {\n\treturn &value\n}\n\n// Int64Ptr is a helper for defining OpenAPI schemas.\nfunc Int64Ptr(value int64) *int64 {\n\treturn &value\n}\n\n// Uint64Ptr is a helper for defining OpenAPI schemas.\nfunc Uint64Ptr(value uint64) *uint64 {\n\treturn &value\n}\n\n// componentNames returns the map keys in a sorted slice.\nfunc componentNames[E any](s map[string]E) []string {\n\tout := make([]string, 0, len(s))\n\tfor i := range s {\n\t\tout = append(out, i)\n\t}\n\tsort.Strings(out)\n\treturn out\n}\n\n// copyURI makes a copy of the pointer.\nfunc copyURI(u *url.URL) *url.URL {\n\tif u == nil {\n\t\treturn nil\n\t}\n\n\tc := *u // shallow-copy\n\treturn &c\n}\n\ntype ComponentRef interface {\n\tRefString() string\n\tRefPath() *url.URL\n\tCollectionName() string\n}\n\n// refersToSameDocument returns if the $ref refers to the same document.\n//\n// Documents in different directories will have distinct $ref values that resolve to\n// the same document.\n// For example, consider the 3 files:\n//\n//\t/records.yaml\n//\t/root.yaml         $ref: records.yaml\n//\t/schema/other.yaml $ref: ../records.yaml\n//\n// The records.yaml reference in the 2 latter refers to the same document.\nfunc refersToSameDocument(o1 ComponentRef, o2 ComponentRef) bool {\n\tif o1 == nil || o2 == nil {\n\t\treturn false\n\t}\n\n\tr1 := o1.RefPath()\n\tr2 := o2.RefPath()\n\n\tif r1 == nil || r2 == nil {\n\t\treturn false\n\t}\n\n\t// refURL is relative to the working directory & base spec file.\n\treturn referenceURIMatch(r1, r2)\n}\n\n// referencesRootDocument returns if the $ref points to the root document of the OpenAPI spec.\n//\n// If the document has no location, perhaps loaded from data in memory, it always returns false.\nfunc referencesRootDocument(doc *T, ref ComponentRef) bool {\n\tif doc.url == nil || ref == nil || ref.RefPath() == nil {\n\t\treturn false\n\t}\n\n\trefURL := *ref.RefPath()\n\trefURL.Fragment = \"\"\n\n\t// Check referenced element was in the root document.\n\treturn referenceURIMatch(doc.url, &refURL)\n}\n\nfunc referenceURIMatch(u1 *url.URL, u2 *url.URL) bool {\n\ts1, s2 := *u1, *u2\n\tif s1.Scheme == \"\" {\n\t\ts1.Scheme = \"file\"\n\t}\n\tif s2.Scheme == \"\" {\n\t\ts2.Scheme = \"file\"\n\t}\n\n\treturn s1.String() == s2.String()\n}\n\n// ReferencesComponentInRootDocument returns if the given component reference references\n// the same document or element as another component reference in the root document's\n// '#/components/<type>'. If it does, it returns the name of it in the form\n// '#/components/<type>/NameXXX'\n//\n// Of course given a component from the root document will always match itself.\n//\n// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#reference-object\n// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#relative-references-in-urls\n//\n// Example. Take the spec with directory structure:\n//\n//\topenapi.yaml\n//\tschemas/\n//\t├─ record.yaml\n//\t├─ records.yaml\n//\n// In openapi.yaml we have:\n//\n//\tcomponents:\n//\t  schemas:\n//\t    Record:\n//\t      $ref: schemas/record.yaml\n//\n// Case 1: records.yml references a component in the root document\n//\n//\t$ref: ../openapi.yaml#/components/schemas/Record\n//\n// This would return...\n//\n//\t#/components/schemas/Record\n//\n// Case 2: records.yml indirectly refers to the same schema\n// as a schema the root document's '#/components/schemas'.\n//\n//\t$ref: ./record.yaml\n//\n// This would also return...\n//\n//\t#/components/schemas/Record\nfunc ReferencesComponentInRootDocument(doc *T, ref ComponentRef) (string, bool) {\n\tif ref == nil || ref.RefString() == \"\" {\n\t\treturn \"\", false\n\t}\n\n\t// Case 1:\n\t// Something like: ../another-folder/document.json#/myElement\n\tif isRemoteReference(ref.RefString()) && isRootComponentReference(ref.RefString(), ref.CollectionName()) {\n\t\t// Determine if it is *this* root doc.\n\t\tif referencesRootDocument(doc, ref) {\n\t\t\t_, name, _ := strings.Cut(ref.RefString(), path.Join(\"#/components/\", ref.CollectionName()))\n\n\t\t\treturn path.Join(\"#/components/\", ref.CollectionName(), name), true\n\t\t}\n\t}\n\n\t// If there are no schemas defined in the root document return early.\n\tif doc.Components == nil {\n\t\treturn \"\", false\n\t}\n\n\tcollection, _, err := jsonpointer.GetForToken(doc.Components, ref.CollectionName())\n\tif err != nil {\n\t\tpanic(err) // unreachable\n\t}\n\n\tvar components map[string]ComponentRef\n\n\tcomponentRefType := reflect.TypeOf(new(ComponentRef)).Elem()\n\tif t := reflect.TypeOf(collection); t.Kind() == reflect.Map &&\n\t\tt.Key().Kind() == reflect.String &&\n\t\tt.Elem().AssignableTo(componentRefType) {\n\t\tv := reflect.ValueOf(collection)\n\n\t\tcomponents = make(map[string]ComponentRef, v.Len())\n\t\tfor _, key := range v.MapKeys() {\n\t\t\tstrct := v.MapIndex(key)\n\t\t\t// Type assertion safe, already checked via reflection above.\n\t\t\tcomponents[key.Interface().(string)] = strct.Interface().(ComponentRef)\n\t\t}\n\t} else {\n\t\treturn \"\", false\n\t}\n\n\t// Case 2:\n\t// Something like: ../openapi.yaml#/components/schemas/myElement\n\tfor name, s := range components {\n\t\t// Must be a reference to a YAML file.\n\t\tif !isWholeDocumentReference(s.RefString()) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Is the schema a ref to the same resource.\n\t\tif !refersToSameDocument(s, ref) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Transform the remote ref to the equivalent schema in the root document.\n\t\treturn path.Join(\"#/components/\", ref.CollectionName(), name), true\n\t}\n\n\treturn \"\", false\n}\n\n// isElementReference takes a $ref value and checks if it references a specific element.\nfunc isElementReference(ref string) bool {\n\treturn ref != \"\" && !isWholeDocumentReference(ref)\n}\n\n// isSchemaReference takes a $ref value and checks if it references a schema element.\nfunc isRootComponentReference(ref string, compType string) bool {\n\treturn isElementReference(ref) && strings.Contains(ref, path.Join(\"#/components/\", compType))\n}\n\n// isWholeDocumentReference takes a $ref value and checks if it is whole document reference.\nfunc isWholeDocumentReference(ref string) bool {\n\treturn ref != \"\" && !strings.ContainsAny(ref, \"#\")\n}\n\n// isRemoteReference takes a $ref value and checks if it is remote reference.\nfunc isRemoteReference(ref string) bool {\n\treturn ref != \"\" && !strings.HasPrefix(ref, \"#\") && !isURLReference(ref)\n}\n\n// isURLReference takes a $ref value and checks if it is URL reference.\nfunc isURLReference(ref string) bool {\n\treturn strings.HasPrefix(ref, \"http://\") || strings.HasPrefix(ref, \"https://\") || strings.HasPrefix(ref, \"//\")\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/info.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n)\n\n// Info is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#info-object\ntype Info struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tTitle          string   `json:\"title\" yaml:\"title\"` // Required\n\tDescription    string   `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tTermsOfService string   `json:\"termsOfService,omitempty\" yaml:\"termsOfService,omitempty\"`\n\tContact        *Contact `json:\"contact,omitempty\" yaml:\"contact,omitempty\"`\n\tLicense        *License `json:\"license,omitempty\" yaml:\"license,omitempty\"`\n\tVersion        string   `json:\"version\" yaml:\"version\"` // Required\n}\n\n// MarshalJSON returns the JSON encoding of Info.\nfunc (info Info) MarshalJSON() ([]byte, error) {\n\tx, err := info.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Info.\nfunc (info *Info) MarshalYAML() (any, error) {\n\tif info == nil {\n\t\treturn nil, nil\n\t}\n\tm := make(map[string]any, 6+len(info.Extensions))\n\tfor k, v := range info.Extensions {\n\t\tm[k] = v\n\t}\n\tm[\"title\"] = info.Title\n\tif x := info.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := info.TermsOfService; x != \"\" {\n\t\tm[\"termsOfService\"] = x\n\t}\n\tif x := info.Contact; x != nil {\n\t\tm[\"contact\"] = x\n\t}\n\tif x := info.License; x != nil {\n\t\tm[\"license\"] = x\n\t}\n\tm[\"version\"] = info.Version\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Info to a copy of data.\nfunc (info *Info) UnmarshalJSON(data []byte) error {\n\ttype InfoBis Info\n\tvar x InfoBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"title\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"termsOfService\")\n\tdelete(x.Extensions, \"contact\")\n\tdelete(x.Extensions, \"license\")\n\tdelete(x.Extensions, \"version\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*info = Info(x)\n\treturn nil\n}\n\n// Validate returns an error if Info does not comply with the OpenAPI spec.\nfunc (info *Info) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif contact := info.Contact; contact != nil {\n\t\tif err := contact.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif license := info.License; license != nil {\n\t\tif err := license.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif info.Version == \"\" {\n\t\treturn errors.New(\"value of version must be a non-empty string\")\n\t}\n\n\tif info.Title == \"\" {\n\t\treturn errors.New(\"value of title must be a non-empty string\")\n\t}\n\n\treturn validateExtensions(ctx, info.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/internalize_refs.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"path\"\n\t\"strings\"\n)\n\n// RefNameResolver maps a component to an name that is used as it's internalized name.\n//\n// The function should avoid name collisions (i.e. be a injective mapping).\n// It must only contain characters valid for fixed field names: [IdentifierRegExp].\ntype RefNameResolver func(*T, ComponentRef) string\n\n// DefaultRefResolver is a default implementation of refNameResolver for the\n// InternalizeRefs function.\n//\n// The external reference is internalized to (hopefully) a unique name. If\n// the external reference matches (by path) to another reference in the root\n// document then the name of that component is used.\n//\n// The transformation involves:\n//   - Cutting the \"#/components/<type>\" part.\n//   - Cutting the file extensions (.yaml/.json) from documents.\n//   - Trimming the common directory with the root spec.\n//   - Replace invalid characters with with underscores.\n//\n// This is an injective mapping over a \"reasonable\" amount of the possible openapi\n// spec domain space but is not perfect. There might be edge cases.\nfunc DefaultRefNameResolver(doc *T, ref ComponentRef) string {\n\tif ref.RefString() == \"\" || ref.RefPath() == nil {\n\t\tpanic(\"unable to resolve reference to name\")\n\t}\n\n\tname := ref.RefPath()\n\n\t// If refering to a component in the root spec, no need to internalize just use\n\t// the existing component.\n\t// XXX(percivalalb): since this function call is iterating over components behind the\n\t// scenes during an internalization call it actually starts interating over\n\t// new & replaced internalized components. This might caused some edge cases,\n\t// haven't found one yet but this might need to actually be used on a frozen copy\n\t// of doc.\n\tif nameInRoot, found := ReferencesComponentInRootDocument(doc, ref); found {\n\t\tnameInRoot = strings.TrimPrefix(nameInRoot, \"#\")\n\n\t\trootCompURI := copyURI(doc.url)\n\t\trootCompURI.Fragment = nameInRoot\n\t\tname = rootCompURI\n\t}\n\n\tfilePath, componentPath := name.Path, name.Fragment\n\n\t// Cut out the \"#/components/<type>\" to make the names shorter.\n\t// XXX(percivalalb): This might cause collisions but is worth the brevity.\n\tif b, a, ok := strings.Cut(componentPath, path.Join(\"components\", ref.CollectionName(), \"\")); ok {\n\t\tcomponentPath = path.Join(b, a)\n\t}\n\n\tif filePath != \"\" {\n\t\t// If the path is the same as the root doc, just remove.\n\t\tif doc.url != nil && filePath == doc.url.Path {\n\t\t\tfilePath = \"\"\n\t\t}\n\n\t\t// Remove the path extentions to make this JSON/YAML agnostic.\n\t\tfor ext := path.Ext(filePath); len(ext) > 0; ext = path.Ext(filePath) {\n\t\t\tfilePath = strings.TrimSuffix(filePath, ext)\n\t\t}\n\n\t\t// Trim the common prefix with the root doc path.\n\t\tif doc.url != nil {\n\t\t\tcommonDir := path.Dir(doc.url.Path)\n\t\t\tfor {\n\t\t\t\tif commonDir == \".\" { // no common prefix\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif p, found := cutDirectories(filePath, commonDir); found {\n\t\t\t\t\tfilePath = p\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tcommonDir = path.Dir(commonDir)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar internalizedName string\n\n\t// Trim .'s & slashes from start e.g. otherwise ./doc.yaml would end up as __doc\n\tif filePath != \"\" {\n\t\tinternalizedName = strings.TrimLeft(filePath, \"./\")\n\t}\n\n\tif componentPath != \"\" {\n\t\tif internalizedName != \"\" {\n\t\t\tinternalizedName += \"_\"\n\t\t}\n\n\t\tinternalizedName += strings.TrimLeft(componentPath, \"./\")\n\t}\n\n\t// Replace invalid characters in component fixed field names.\n\tinternalizedName = InvalidIdentifierCharRegExp.ReplaceAllString(internalizedName, \"_\")\n\n\treturn internalizedName\n}\n\n// cutDirectories removes the given directories from the start of the path if\n// the path is a child.\nfunc cutDirectories(p, dirs string) (string, bool) {\n\tif dirs == \"\" || p == \"\" {\n\t\treturn p, false\n\t}\n\n\tp = strings.TrimRight(p, \"/\")\n\tdirs = strings.TrimRight(dirs, \"/\")\n\n\tvar sb strings.Builder\n\tsb.Grow(len(ParameterInHeader))\n\tfor _, segments := range strings.Split(p, \"/\") {\n\t\tsb.WriteString(segments)\n\n\t\tif sb.String() == p {\n\t\t\treturn strings.TrimPrefix(p, dirs), true\n\t\t}\n\n\t\tsb.WriteRune('/')\n\t}\n\n\treturn p, false\n}\n\nfunc isExternalRef(ref string, parentIsExternal bool) bool {\n\treturn ref != \"\" && (!strings.HasPrefix(ref, \"#/components/\") || parentIsExternal)\n}\n\nfunc (doc *T) addSchemaToSpec(s *SchemaRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {\n\tif s == nil || !isExternalRef(s.Ref, parentIsExternal) {\n\t\treturn false\n\t}\n\n\tname := refNameResolver(doc, s)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.Schemas[name]; ok {\n\t\t\ts.Ref = \"#/components/schemas/\" + name\n\t\t\treturn true\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.Schemas == nil {\n\t\tdoc.Components.Schemas = make(Schemas)\n\t}\n\tdoc.Components.Schemas[name] = s.Value.NewRef()\n\ts.Ref = \"#/components/schemas/\" + name\n\treturn true\n}\n\nfunc (doc *T) addParameterToSpec(p *ParameterRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {\n\tif p == nil || !isExternalRef(p.Ref, parentIsExternal) {\n\t\treturn false\n\t}\n\tname := refNameResolver(doc, p)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.Parameters[name]; ok {\n\t\t\tp.Ref = \"#/components/parameters/\" + name\n\t\t\treturn true\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.Parameters == nil {\n\t\tdoc.Components.Parameters = make(ParametersMap)\n\t}\n\tdoc.Components.Parameters[name] = &ParameterRef{Value: p.Value}\n\tp.Ref = \"#/components/parameters/\" + name\n\treturn true\n}\n\nfunc (doc *T) addHeaderToSpec(h *HeaderRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {\n\tif h == nil || !isExternalRef(h.Ref, parentIsExternal) {\n\t\treturn false\n\t}\n\tname := refNameResolver(doc, h)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.Headers[name]; ok {\n\t\t\th.Ref = \"#/components/headers/\" + name\n\t\t\treturn true\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.Headers == nil {\n\t\tdoc.Components.Headers = make(Headers)\n\t}\n\tdoc.Components.Headers[name] = &HeaderRef{Value: h.Value}\n\th.Ref = \"#/components/headers/\" + name\n\treturn true\n}\n\nfunc (doc *T) addRequestBodyToSpec(r *RequestBodyRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {\n\tif r == nil || !isExternalRef(r.Ref, parentIsExternal) {\n\t\treturn false\n\t}\n\tname := refNameResolver(doc, r)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.RequestBodies[name]; ok {\n\t\t\tr.Ref = \"#/components/requestBodies/\" + name\n\t\t\treturn true\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.RequestBodies == nil {\n\t\tdoc.Components.RequestBodies = make(RequestBodies)\n\t}\n\tdoc.Components.RequestBodies[name] = &RequestBodyRef{Value: r.Value}\n\tr.Ref = \"#/components/requestBodies/\" + name\n\treturn true\n}\n\nfunc (doc *T) addResponseToSpec(r *ResponseRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {\n\tif r == nil || !isExternalRef(r.Ref, parentIsExternal) {\n\t\treturn false\n\t}\n\tname := refNameResolver(doc, r)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.Responses[name]; ok {\n\t\t\tr.Ref = \"#/components/responses/\" + name\n\t\t\treturn true\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.Responses == nil {\n\t\tdoc.Components.Responses = make(ResponseBodies)\n\t}\n\tdoc.Components.Responses[name] = &ResponseRef{Value: r.Value}\n\tr.Ref = \"#/components/responses/\" + name\n\treturn true\n}\n\nfunc (doc *T) addSecuritySchemeToSpec(ss *SecuritySchemeRef, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tif ss == nil || !isExternalRef(ss.Ref, parentIsExternal) {\n\t\treturn\n\t}\n\tname := refNameResolver(doc, ss)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.SecuritySchemes[name]; ok {\n\t\t\tss.Ref = \"#/components/securitySchemes/\" + name\n\t\t\treturn\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.SecuritySchemes == nil {\n\t\tdoc.Components.SecuritySchemes = make(SecuritySchemes)\n\t}\n\tdoc.Components.SecuritySchemes[name] = &SecuritySchemeRef{Value: ss.Value}\n\tss.Ref = \"#/components/securitySchemes/\" + name\n\n}\n\nfunc (doc *T) addExampleToSpec(e *ExampleRef, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tif e == nil || !isExternalRef(e.Ref, parentIsExternal) {\n\t\treturn\n\t}\n\tname := refNameResolver(doc, e)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.Examples[name]; ok {\n\t\t\te.Ref = \"#/components/examples/\" + name\n\t\t\treturn\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.Examples == nil {\n\t\tdoc.Components.Examples = make(Examples)\n\t}\n\tdoc.Components.Examples[name] = &ExampleRef{Value: e.Value}\n\te.Ref = \"#/components/examples/\" + name\n\n}\n\nfunc (doc *T) addLinkToSpec(l *LinkRef, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tif l == nil || !isExternalRef(l.Ref, parentIsExternal) {\n\t\treturn\n\t}\n\tname := refNameResolver(doc, l)\n\tif doc.Components != nil {\n\t\tif _, ok := doc.Components.Links[name]; ok {\n\t\t\tl.Ref = \"#/components/links/\" + name\n\t\t\treturn\n\t\t}\n\t}\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.Links == nil {\n\t\tdoc.Components.Links = make(Links)\n\t}\n\tdoc.Components.Links[name] = &LinkRef{Value: l.Value}\n\tl.Ref = \"#/components/links/\" + name\n\n}\n\nfunc (doc *T) addCallbackToSpec(c *CallbackRef, refNameResolver RefNameResolver, parentIsExternal bool) bool {\n\tif c == nil || !isExternalRef(c.Ref, parentIsExternal) {\n\t\treturn false\n\t}\n\tname := refNameResolver(doc, c)\n\n\tif doc.Components == nil {\n\t\tdoc.Components = &Components{}\n\t}\n\tif doc.Components.Callbacks == nil {\n\t\tdoc.Components.Callbacks = make(Callbacks)\n\t}\n\tc.Ref = \"#/components/callbacks/\" + name\n\tdoc.Components.Callbacks[name] = &CallbackRef{Value: c.Value}\n\treturn true\n}\n\nfunc (doc *T) derefSchema(s *Schema, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tif s == nil || doc.isVisitedSchema(s) {\n\t\treturn\n\t}\n\n\tfor _, list := range []SchemaRefs{s.AllOf, s.AnyOf, s.OneOf} {\n\t\tfor _, s2 := range list {\n\t\t\tisExternal := doc.addSchemaToSpec(s2, refNameResolver, parentIsExternal)\n\t\t\tif s2 != nil {\n\t\t\t\tdoc.derefSchema(s2.Value, refNameResolver, isExternal || parentIsExternal)\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, name := range componentNames(s.Properties) {\n\t\ts2 := s.Properties[name]\n\t\tisExternal := doc.addSchemaToSpec(s2, refNameResolver, parentIsExternal)\n\t\tif s2 != nil {\n\t\t\tdoc.derefSchema(s2.Value, refNameResolver, isExternal || parentIsExternal)\n\t\t}\n\t}\n\tfor _, ref := range []*SchemaRef{s.Not, s.AdditionalProperties.Schema, s.Items} {\n\t\tisExternal := doc.addSchemaToSpec(ref, refNameResolver, parentIsExternal)\n\t\tif ref != nil {\n\t\t\tdoc.derefSchema(ref.Value, refNameResolver, isExternal || parentIsExternal)\n\t\t}\n\t}\n}\n\nfunc (doc *T) derefHeaders(hs Headers, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tfor _, name := range componentNames(hs) {\n\t\th := hs[name]\n\t\tisExternal := doc.addHeaderToSpec(h, refNameResolver, parentIsExternal)\n\t\tif doc.isVisitedHeader(h.Value) {\n\t\t\tcontinue\n\t\t}\n\t\tdoc.derefParameter(h.Value.Parameter, refNameResolver, parentIsExternal || isExternal)\n\t}\n}\n\nfunc (doc *T) derefExamples(es Examples, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tfor _, name := range componentNames(es) {\n\t\te := es[name]\n\t\tdoc.addExampleToSpec(e, refNameResolver, parentIsExternal)\n\t}\n}\n\nfunc (doc *T) derefContent(c Content, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tfor _, name := range componentNames(c) {\n\t\tmediatype := c[name]\n\t\tisExternal := doc.addSchemaToSpec(mediatype.Schema, refNameResolver, parentIsExternal)\n\t\tif mediatype.Schema != nil {\n\t\t\tdoc.derefSchema(mediatype.Schema.Value, refNameResolver, isExternal || parentIsExternal)\n\t\t}\n\t\tdoc.derefExamples(mediatype.Examples, refNameResolver, parentIsExternal)\n\t\tfor _, name := range componentNames(mediatype.Encoding) {\n\t\t\te := mediatype.Encoding[name]\n\t\t\tdoc.derefHeaders(e.Headers, refNameResolver, parentIsExternal)\n\t\t}\n\t}\n}\n\nfunc (doc *T) derefLinks(ls Links, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tfor _, name := range componentNames(ls) {\n\t\tl := ls[name]\n\t\tdoc.addLinkToSpec(l, refNameResolver, parentIsExternal)\n\t}\n}\n\nfunc (doc *T) derefResponse(r *ResponseRef, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tisExternal := doc.addResponseToSpec(r, refNameResolver, parentIsExternal)\n\tif v := r.Value; v != nil {\n\t\tdoc.derefHeaders(v.Headers, refNameResolver, isExternal || parentIsExternal)\n\t\tdoc.derefContent(v.Content, refNameResolver, isExternal || parentIsExternal)\n\t\tdoc.derefLinks(v.Links, refNameResolver, isExternal || parentIsExternal)\n\t}\n}\n\nfunc (doc *T) derefResponses(rs *Responses, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tdoc.derefResponseBodies(rs.Map(), refNameResolver, parentIsExternal)\n}\n\nfunc (doc *T) derefResponseBodies(es ResponseBodies, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tfor _, name := range componentNames(es) {\n\t\te := es[name]\n\t\tdoc.derefResponse(e, refNameResolver, parentIsExternal)\n\t}\n}\n\nfunc (doc *T) derefParameter(p Parameter, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tisExternal := doc.addSchemaToSpec(p.Schema, refNameResolver, parentIsExternal)\n\tdoc.derefContent(p.Content, refNameResolver, parentIsExternal)\n\tif p.Schema != nil {\n\t\tdoc.derefSchema(p.Schema.Value, refNameResolver, isExternal || parentIsExternal)\n\t}\n}\n\nfunc (doc *T) derefRequestBody(r RequestBody, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tdoc.derefContent(r.Content, refNameResolver, parentIsExternal)\n}\n\nfunc (doc *T) derefPaths(paths map[string]*PathItem, refNameResolver RefNameResolver, parentIsExternal bool) {\n\tfor _, name := range componentNames(paths) {\n\t\tops := paths[name]\n\t\tpathIsExternal := isExternalRef(ops.Ref, parentIsExternal)\n\t\t// inline full operations\n\t\tops.Ref = \"\"\n\n\t\tfor _, param := range ops.Parameters {\n\t\t\tisExternal := doc.addParameterToSpec(param, refNameResolver, pathIsExternal)\n\t\t\tif param.Value != nil {\n\t\t\t\tdoc.derefParameter(*param.Value, refNameResolver, pathIsExternal || isExternal)\n\t\t\t}\n\t\t}\n\n\t\topsWithMethod := ops.Operations()\n\t\tfor _, name := range componentNames(opsWithMethod) {\n\t\t\top := opsWithMethod[name]\n\t\t\tisExternal := doc.addRequestBodyToSpec(op.RequestBody, refNameResolver, pathIsExternal)\n\t\t\tif op.RequestBody != nil && op.RequestBody.Value != nil {\n\t\t\t\tdoc.derefRequestBody(*op.RequestBody.Value, refNameResolver, pathIsExternal || isExternal)\n\t\t\t}\n\t\t\tfor _, name := range componentNames(op.Callbacks) {\n\t\t\t\tcb := op.Callbacks[name]\n\t\t\t\tisExternal := doc.addCallbackToSpec(cb, refNameResolver, pathIsExternal)\n\t\t\t\tif cb.Value != nil {\n\t\t\t\t\tcbValue := (*cb.Value).Map()\n\t\t\t\t\tdoc.derefPaths(cbValue, refNameResolver, pathIsExternal || isExternal)\n\t\t\t\t}\n\t\t\t}\n\t\t\tdoc.derefResponses(op.Responses, refNameResolver, pathIsExternal)\n\t\t\tfor _, param := range op.Parameters {\n\t\t\t\tisExternal := doc.addParameterToSpec(param, refNameResolver, pathIsExternal)\n\t\t\t\tif param.Value != nil {\n\t\t\t\t\tdoc.derefParameter(*param.Value, refNameResolver, pathIsExternal || isExternal)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// InternalizeRefs removes all references to external files from the spec and moves them\n// to the components section.\n//\n// refNameResolver takes in references to returns a name to store the reference under locally.\n// It MUST return a unique name for each reference type.\n// A default implementation is provided that will suffice for most use cases. See the function\n// documentation for more details.\n//\n// Example:\n//\n//\tdoc.InternalizeRefs(context.Background(), nil)\nfunc (doc *T) InternalizeRefs(ctx context.Context, refNameResolver func(*T, ComponentRef) string) {\n\tdoc.resetVisited()\n\n\tif refNameResolver == nil {\n\t\trefNameResolver = DefaultRefNameResolver\n\t}\n\n\tif components := doc.Components; components != nil {\n\t\tfor _, name := range componentNames(components.Schemas) {\n\t\t\tschema := components.Schemas[name]\n\t\t\tisExternal := doc.addSchemaToSpec(schema, refNameResolver, false)\n\t\t\tif schema != nil {\n\t\t\t\tschema.Ref = \"\" // always dereference the top level\n\t\t\t\tdoc.derefSchema(schema.Value, refNameResolver, isExternal)\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.Parameters) {\n\t\t\tp := components.Parameters[name]\n\t\t\tisExternal := doc.addParameterToSpec(p, refNameResolver, false)\n\t\t\tif p != nil && p.Value != nil {\n\t\t\t\tp.Ref = \"\" // always dereference the top level\n\t\t\t\tdoc.derefParameter(*p.Value, refNameResolver, isExternal)\n\t\t\t}\n\t\t}\n\t\tdoc.derefHeaders(components.Headers, refNameResolver, false)\n\t\tfor _, name := range componentNames(components.RequestBodies) {\n\t\t\treq := components.RequestBodies[name]\n\t\t\tisExternal := doc.addRequestBodyToSpec(req, refNameResolver, false)\n\t\t\tif req != nil && req.Value != nil {\n\t\t\t\treq.Ref = \"\" // always dereference the top level\n\t\t\t\tdoc.derefRequestBody(*req.Value, refNameResolver, isExternal)\n\t\t\t}\n\t\t}\n\t\tdoc.derefResponseBodies(components.Responses, refNameResolver, false)\n\t\tfor _, name := range componentNames(components.SecuritySchemes) {\n\t\t\tss := components.SecuritySchemes[name]\n\t\t\tdoc.addSecuritySchemeToSpec(ss, refNameResolver, false)\n\t\t}\n\t\tdoc.derefExamples(components.Examples, refNameResolver, false)\n\t\tdoc.derefLinks(components.Links, refNameResolver, false)\n\n\t\tfor _, name := range componentNames(components.Callbacks) {\n\t\t\tcb := components.Callbacks[name]\n\t\t\tisExternal := doc.addCallbackToSpec(cb, refNameResolver, false)\n\t\t\tif cb != nil && cb.Value != nil {\n\t\t\t\tcb.Ref = \"\" // always dereference the top level\n\t\t\t\tcbValue := (*cb.Value).Map()\n\t\t\t\tdoc.derefPaths(cbValue, refNameResolver, isExternal)\n\t\t\t}\n\t\t}\n\t}\n\n\tdoc.derefPaths(doc.Paths.Map(), refNameResolver, false)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/license.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n)\n\n// License is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#license-object\ntype License struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tName string `json:\"name\" yaml:\"name\"` // Required\n\tURL  string `json:\"url,omitempty\" yaml:\"url,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of License.\nfunc (license License) MarshalJSON() ([]byte, error) {\n\tx, err := license.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of License.\nfunc (license License) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 2+len(license.Extensions))\n\tfor k, v := range license.Extensions {\n\t\tm[k] = v\n\t}\n\tm[\"name\"] = license.Name\n\tif x := license.URL; x != \"\" {\n\t\tm[\"url\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets License to a copy of data.\nfunc (license *License) UnmarshalJSON(data []byte) error {\n\ttype LicenseBis License\n\tvar x LicenseBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"url\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*license = License(x)\n\treturn nil\n}\n\n// Validate returns an error if License does not comply with the OpenAPI spec.\nfunc (license *License) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif license.Name == \"\" {\n\t\treturn errors.New(\"value of license name must be a non-empty string\")\n\t}\n\n\treturn validateExtensions(ctx, license.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/link.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// Link is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#link-object\ntype Link struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tOperationRef string         `json:\"operationRef,omitempty\" yaml:\"operationRef,omitempty\"`\n\tOperationID  string         `json:\"operationId,omitempty\" yaml:\"operationId,omitempty\"`\n\tDescription  string         `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tParameters   map[string]any `json:\"parameters,omitempty\" yaml:\"parameters,omitempty\"`\n\tServer       *Server        `json:\"server,omitempty\" yaml:\"server,omitempty\"`\n\tRequestBody  any            `json:\"requestBody,omitempty\" yaml:\"requestBody,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Link.\nfunc (link Link) MarshalJSON() ([]byte, error) {\n\tx, err := link.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Link.\nfunc (link Link) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 6+len(link.Extensions))\n\tfor k, v := range link.Extensions {\n\t\tm[k] = v\n\t}\n\n\tif x := link.OperationRef; x != \"\" {\n\t\tm[\"operationRef\"] = x\n\t}\n\tif x := link.OperationID; x != \"\" {\n\t\tm[\"operationId\"] = x\n\t}\n\tif x := link.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := link.Parameters; len(x) != 0 {\n\t\tm[\"parameters\"] = x\n\t}\n\tif x := link.Server; x != nil {\n\t\tm[\"server\"] = x\n\t}\n\tif x := link.RequestBody; x != nil {\n\t\tm[\"requestBody\"] = x\n\t}\n\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Link to a copy of data.\nfunc (link *Link) UnmarshalJSON(data []byte) error {\n\ttype LinkBis Link\n\tvar x LinkBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"operationRef\")\n\tdelete(x.Extensions, \"operationId\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"parameters\")\n\tdelete(x.Extensions, \"server\")\n\tdelete(x.Extensions, \"requestBody\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*link = Link(x)\n\treturn nil\n}\n\n// Validate returns an error if Link does not comply with the OpenAPI spec.\nfunc (link *Link) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif link.OperationID == \"\" && link.OperationRef == \"\" {\n\t\treturn errors.New(\"missing operationId or operationRef on link\")\n\t}\n\tif link.OperationID != \"\" && link.OperationRef != \"\" {\n\t\treturn fmt.Errorf(\"operationId %q and operationRef %q are mutually exclusive\", link.OperationID, link.OperationRef)\n\t}\n\n\treturn validateExtensions(ctx, link.Extensions)\n}\n\n// UnmarshalJSON sets Links to a copy of data.\nfunc (links *Links) UnmarshalJSON(data []byte) (err error) {\n\t*links, _, err = unmarshalStringMapP[LinkRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/loader.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// IncludeOrigin specifies whether to include the origin of the OpenAPI elements\n// Set this to true before loading a spec to include the origin of the OpenAPI elements\n// Note it is global and affects all loaders\nvar IncludeOrigin = false\n\nfunc foundUnresolvedRef(ref string) error {\n\treturn fmt.Errorf(\"found unresolved ref: %q\", ref)\n}\n\nfunc failedToResolveRefFragmentPart(value, what string) error {\n\treturn fmt.Errorf(\"failed to resolve %q in fragment in URI: %q\", what, value)\n}\n\n// Loader helps deserialize an OpenAPIv3 document\ntype Loader struct {\n\t// IsExternalRefsAllowed enables visiting other files\n\tIsExternalRefsAllowed bool\n\n\t// ReadFromURIFunc allows overriding the any file/URL reading func\n\tReadFromURIFunc ReadFromURIFunc\n\n\tContext context.Context\n\n\trootDir      string\n\trootLocation string\n\n\tvisitedPathItemRefs map[string]struct{}\n\n\tvisitedDocuments map[string]*T\n\n\tvisitedRefs map[string]struct{}\n\tvisitedPath []string\n\tbacktrack   map[string][]func(value any)\n}\n\n// NewLoader returns an empty Loader\nfunc NewLoader() *Loader {\n\treturn &Loader{\n\t\tContext: context.Background(),\n\t}\n}\n\nfunc (loader *Loader) resetVisitedPathItemRefs() {\n\tloader.visitedPathItemRefs = make(map[string]struct{})\n\tloader.visitedRefs = make(map[string]struct{})\n\tloader.visitedPath = nil\n\tloader.backtrack = make(map[string][]func(value any))\n}\n\n// LoadFromURI loads a spec from a remote URL\nfunc (loader *Loader) LoadFromURI(location *url.URL) (*T, error) {\n\tloader.resetVisitedPathItemRefs()\n\treturn loader.loadFromURIInternal(location)\n}\n\n// LoadFromFile loads a spec from a local file path\nfunc (loader *Loader) LoadFromFile(location string) (*T, error) {\n\tloader.rootDir = path.Dir(location)\n\treturn loader.LoadFromURI(&url.URL{Path: filepath.ToSlash(location)})\n}\n\nfunc (loader *Loader) loadFromURIInternal(location *url.URL) (*T, error) {\n\tdata, err := loader.readURL(location)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn loader.loadFromDataWithPathInternal(data, location)\n}\n\nfunc (loader *Loader) allowsExternalRefs(ref string) (err error) {\n\tif !loader.IsExternalRefsAllowed {\n\t\terr = fmt.Errorf(\"encountered disallowed external reference: %q\", ref)\n\t}\n\treturn\n}\n\nfunc (loader *Loader) loadSingleElementFromURI(ref string, rootPath *url.URL, element any) (*url.URL, error) {\n\tif err := loader.allowsExternalRefs(ref); err != nil {\n\t\treturn nil, err\n\t}\n\n\tresolvedPath, err := resolvePathWithRef(ref, rootPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif frag := resolvedPath.Fragment; frag != \"\" {\n\t\treturn nil, fmt.Errorf(\"unexpected ref fragment %q\", frag)\n\t}\n\n\tdata, err := loader.readURL(resolvedPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := unmarshal(data, element, IncludeOrigin); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn resolvedPath, nil\n}\n\nfunc (loader *Loader) readURL(location *url.URL) ([]byte, error) {\n\tif f := loader.ReadFromURIFunc; f != nil {\n\t\treturn f(loader, location)\n\t}\n\treturn DefaultReadFromURI(loader, location)\n}\n\n// LoadFromStdin loads a spec from stdin\nfunc (loader *Loader) LoadFromStdin() (*T, error) {\n\treturn loader.LoadFromIoReader(os.Stdin)\n}\n\n// LoadFromStdin loads a spec from io.Reader\nfunc (loader *Loader) LoadFromIoReader(reader io.Reader) (*T, error) {\n\tif reader == nil {\n\t\treturn nil, fmt.Errorf(\"invalid reader: %v\", reader)\n\t}\n\n\tdata, err := io.ReadAll(reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn loader.LoadFromData(data)\n}\n\n// LoadFromData loads a spec from a byte array\nfunc (loader *Loader) LoadFromData(data []byte) (*T, error) {\n\tloader.resetVisitedPathItemRefs()\n\tdoc := &T{}\n\tif err := unmarshal(data, doc, IncludeOrigin); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := loader.ResolveRefsIn(doc, nil); err != nil {\n\t\treturn nil, err\n\t}\n\treturn doc, nil\n}\n\n// LoadFromDataWithPath takes the OpenAPI document data in bytes and a path where the resolver can find referred\n// elements and returns a *T with all resolved data or an error if unable to load data or resolve refs.\nfunc (loader *Loader) LoadFromDataWithPath(data []byte, location *url.URL) (*T, error) {\n\tloader.resetVisitedPathItemRefs()\n\treturn loader.loadFromDataWithPathInternal(data, location)\n}\n\nfunc (loader *Loader) loadFromDataWithPathInternal(data []byte, location *url.URL) (*T, error) {\n\tif loader.visitedDocuments == nil {\n\t\tloader.visitedDocuments = make(map[string]*T)\n\t\tloader.rootLocation = location.Path\n\t}\n\turi := location.String()\n\tif doc, ok := loader.visitedDocuments[uri]; ok {\n\t\treturn doc, nil\n\t}\n\n\tdoc := &T{}\n\tloader.visitedDocuments[uri] = doc\n\n\tif err := unmarshal(data, doc, IncludeOrigin); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdoc.url = copyURI(location)\n\n\tif err := loader.ResolveRefsIn(doc, location); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn doc, nil\n}\n\n// ResolveRefsIn expands references if for instance spec was just unmarshaled\nfunc (loader *Loader) ResolveRefsIn(doc *T, location *url.URL) (err error) {\n\tif loader.Context == nil {\n\t\tloader.Context = context.Background()\n\t}\n\n\tif loader.visitedPathItemRefs == nil {\n\t\tloader.resetVisitedPathItemRefs()\n\t}\n\n\tif components := doc.Components; components != nil {\n\t\tfor _, name := range componentNames(components.Headers) {\n\t\t\tcomponent := components.Headers[name]\n\t\t\tif err = loader.resolveHeaderRef(doc, component, location); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.Parameters) {\n\t\t\tcomponent := components.Parameters[name]\n\t\t\tif err = loader.resolveParameterRef(doc, component, location); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.RequestBodies) {\n\t\t\tcomponent := components.RequestBodies[name]\n\t\t\tif err = loader.resolveRequestBodyRef(doc, component, location); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.Responses) {\n\t\t\tcomponent := components.Responses[name]\n\t\t\tif err = loader.resolveResponseRef(doc, component, location); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.Schemas) {\n\t\t\tcomponent := components.Schemas[name]\n\t\t\tif err = loader.resolveSchemaRef(doc, component, location, []string{}); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.SecuritySchemes) {\n\t\t\tcomponent := components.SecuritySchemes[name]\n\t\t\tif err = loader.resolveSecuritySchemeRef(doc, component, location); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.Examples) {\n\t\t\tcomponent := components.Examples[name]\n\t\t\tif err = loader.resolveExampleRef(doc, component, location); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(components.Callbacks) {\n\t\t\tcomponent := components.Callbacks[name]\n\t\t\tif err = loader.resolveCallbackRef(doc, component, location); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Visit all operations\n\tpathItems := doc.Paths.Map()\n\tfor _, name := range componentNames(pathItems) {\n\t\tpathItem := pathItems[name]\n\t\tif pathItem == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err = loader.resolvePathItemRef(doc, pathItem, location); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc join(basePath *url.URL, relativePath *url.URL) *url.URL {\n\tif basePath == nil {\n\t\treturn relativePath\n\t}\n\tnewPath := *basePath\n\tnewPath.Path = path.Join(path.Dir(newPath.Path), relativePath.Path)\n\treturn &newPath\n}\n\nfunc resolvePath(basePath *url.URL, componentPath *url.URL) *url.URL {\n\tif is_file(componentPath) {\n\t\t// support absolute paths\n\t\tif filepath.IsAbs(componentPath.Path) {\n\t\t\treturn componentPath\n\t\t}\n\t\treturn join(basePath, componentPath)\n\t}\n\treturn componentPath\n}\n\nfunc resolvePathWithRef(ref string, rootPath *url.URL) (*url.URL, error) {\n\tparsedURL, err := url.Parse(ref)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot parse reference: %q: %w\", ref, err)\n\t}\n\n\tresolvedPath := resolvePath(rootPath, parsedURL)\n\tresolvedPath.Fragment = parsedURL.Fragment\n\treturn resolvedPath, nil\n}\n\nfunc (loader *Loader) resolveRefPath(ref string, path *url.URL) (*url.URL, error) {\n\tif ref != \"\" && ref[0] == '#' {\n\t\tpath = copyURI(path)\n\t\t// Resolving internal refs of a doc loaded from memory\n\t\t// has no path, so just set the Fragment.\n\t\tif path == nil {\n\t\t\tpath = new(url.URL)\n\t\t}\n\n\t\tpath.Fragment = ref\n\t\treturn path, nil\n\t}\n\n\tif err := loader.allowsExternalRefs(ref); err != nil {\n\t\treturn nil, err\n\t}\n\n\tresolvedPath, err := resolvePathWithRef(ref, path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn resolvedPath, nil\n}\n\nfunc isSingleRefElement(ref string) bool {\n\treturn !strings.Contains(ref, \"#\")\n}\n\nfunc (loader *Loader) visitRef(ref string) {\n\tif loader.visitedRefs == nil {\n\t\tloader.visitedRefs = make(map[string]struct{})\n\t\tloader.backtrack = make(map[string][]func(value any))\n\t}\n\tloader.visitedPath = append(loader.visitedPath, ref)\n\tloader.visitedRefs[ref] = struct{}{}\n}\n\nfunc (loader *Loader) unvisitRef(ref string, value any) {\n\tif value != nil {\n\t\tfor _, fn := range loader.backtrack[ref] {\n\t\t\tfn(value)\n\t\t}\n\t}\n\tdelete(loader.visitedRefs, ref)\n\tdelete(loader.backtrack, ref)\n\tloader.visitedPath = loader.visitedPath[:len(loader.visitedPath)-1]\n}\n\nfunc (loader *Loader) shouldVisitRef(ref string, fn func(value any)) bool {\n\tif _, ok := loader.visitedRefs[ref]; ok {\n\t\tloader.backtrack[ref] = append(loader.backtrack[ref], fn)\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (loader *Loader) resolveComponent(doc *T, ref string, path *url.URL, resolved any) (\n\tcomponentDoc *T,\n\tcomponentPath *url.URL,\n\terr error,\n) {\n\tif componentDoc, ref, componentPath, err = loader.resolveRefAndDocument(doc, ref, path); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tparsedURL, err := url.Parse(ref)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"cannot parse reference: %q: %v\", ref, parsedURL)\n\t}\n\tfragment := parsedURL.Fragment\n\tif fragment == \"\" {\n\t\tfragment = \"/\"\n\t}\n\tif fragment[0] != '/' {\n\t\treturn nil, nil, fmt.Errorf(\"expected fragment prefix '#/' in URI %q\", ref)\n\t}\n\n\tdrill := func(cursor any) (any, error) {\n\t\tfor _, pathPart := range strings.Split(fragment[1:], \"/\") {\n\t\t\tpathPart = unescapeRefString(pathPart)\n\t\t\tattempted := false\n\n\t\t\tswitch c := cursor.(type) {\n\t\t\t// Special case of T\n\t\t\t// See issue856: a ref to doc => we assume that doc is a T => things live in T.Extensions\n\t\t\tcase *T:\n\t\t\t\tif pathPart == \"\" {\n\t\t\t\t\tcursor = c.Extensions\n\t\t\t\t\tattempted = true\n\t\t\t\t}\n\n\t\t\t// Special case due to multijson\n\t\t\tcase *SchemaRef:\n\t\t\t\tif pathPart == \"additionalProperties\" {\n\t\t\t\t\tif ap := c.Value.AdditionalProperties.Has; ap != nil {\n\t\t\t\t\t\tcursor = *ap\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcursor = c.Value.AdditionalProperties.Schema\n\t\t\t\t\t}\n\t\t\t\t\tattempted = true\n\t\t\t\t}\n\n\t\t\tcase *Responses:\n\t\t\t\tcursor = c.m // m map[string]*ResponseRef\n\t\t\tcase *Callback:\n\t\t\t\tcursor = c.m // m map[string]*PathItem\n\t\t\tcase *Paths:\n\t\t\t\tcursor = c.m // m map[string]*PathItem\n\t\t\t}\n\n\t\t\tif !attempted {\n\t\t\t\tif cursor, err = drillIntoField(cursor, pathPart); err != nil {\n\t\t\t\t\te := failedToResolveRefFragmentPart(ref, pathPart)\n\t\t\t\t\treturn nil, fmt.Errorf(\"%s: %w\", e, err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif cursor == nil {\n\t\t\t\treturn nil, failedToResolveRefFragmentPart(ref, pathPart)\n\t\t\t}\n\t\t}\n\t\treturn cursor, nil\n\t}\n\tvar cursor any\n\tif cursor, err = drill(componentDoc); err != nil {\n\t\tif path == nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tvar err2 error\n\t\tdata, err2 := loader.readURL(path)\n\t\tif err2 != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tif err2 = unmarshal(data, &cursor, IncludeOrigin); err2 != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tif cursor, err2 = drill(cursor); err2 != nil || cursor == nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\terr = nil\n\t}\n\n\tsetPathRef := func(target any) {\n\t\tif i, ok := target.(interface {\n\t\t\tsetRefPath(*url.URL)\n\t\t}); ok {\n\t\t\tpathRef := copyURI(componentPath)\n\t\t\t// Resolving internal refs of a doc loaded from memory\n\t\t\t// has no path, so just set the Fragment.\n\t\t\tif pathRef == nil {\n\t\t\t\tpathRef = new(url.URL)\n\t\t\t}\n\t\t\tpathRef.Fragment = fragment\n\n\t\t\ti.setRefPath(pathRef)\n\t\t}\n\t}\n\n\tswitch {\n\tcase reflect.TypeOf(cursor) == reflect.TypeOf(resolved):\n\t\tsetPathRef(cursor)\n\n\t\treflect.ValueOf(resolved).Elem().Set(reflect.ValueOf(cursor).Elem())\n\t\treturn componentDoc, componentPath, nil\n\n\tcase reflect.TypeOf(cursor) == reflect.TypeOf(map[string]any{}):\n\t\tcodec := func(got, expect any) error {\n\t\t\tenc, err := json.Marshal(got)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err = json.Unmarshal(enc, expect); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tsetPathRef(expect)\n\t\t\treturn nil\n\t\t}\n\t\tif err := codec(cursor, resolved); err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"bad data in %q (expecting %s)\", ref, readableType(resolved))\n\t\t}\n\t\treturn componentDoc, componentPath, nil\n\n\tdefault:\n\t\treturn nil, nil, fmt.Errorf(\"bad data in %q (expecting %s)\", ref, readableType(resolved))\n\t}\n}\n\nfunc readableType(x any) string {\n\tswitch x.(type) {\n\tcase *Callback:\n\t\treturn \"callback object\"\n\tcase *CallbackRef:\n\t\treturn \"ref to callback object\"\n\tcase *ExampleRef:\n\t\treturn \"ref to example object\"\n\tcase *HeaderRef:\n\t\treturn \"ref to header object\"\n\tcase *LinkRef:\n\t\treturn \"ref to link object\"\n\tcase *ParameterRef:\n\t\treturn \"ref to parameter object\"\n\tcase *PathItem:\n\t\treturn \"pathItem object\"\n\tcase *RequestBodyRef:\n\t\treturn \"ref to requestBody object\"\n\tcase *ResponseRef:\n\t\treturn \"ref to response object\"\n\tcase *SchemaRef:\n\t\treturn \"ref to schema object\"\n\tcase *SecuritySchemeRef:\n\t\treturn \"ref to securityScheme object\"\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unreachable %T\", x))\n\t}\n}\n\nfunc drillIntoField(cursor any, fieldName string) (any, error) {\n\tswitch val := reflect.Indirect(reflect.ValueOf(cursor)); val.Kind() {\n\n\tcase reflect.Map:\n\t\telementValue := val.MapIndex(reflect.ValueOf(fieldName))\n\t\tif !elementValue.IsValid() {\n\t\t\treturn nil, fmt.Errorf(\"map key %q not found\", fieldName)\n\t\t}\n\t\treturn elementValue.Interface(), nil\n\n\tcase reflect.Slice:\n\t\ti, err := strconv.ParseUint(fieldName, 10, 32)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tindex := int(i)\n\t\tif 0 > index || index >= val.Len() {\n\t\t\treturn nil, errors.New(\"slice index out of bounds\")\n\t\t}\n\t\treturn val.Index(index).Interface(), nil\n\n\tcase reflect.Struct:\n\t\thasFields := false\n\t\tfor i := 0; i < val.NumField(); i++ {\n\t\t\thasFields = true\n\t\t\tif yamlTag := val.Type().Field(i).Tag.Get(\"yaml\"); yamlTag != \"-\" {\n\t\t\t\tif tagName := strings.Split(yamlTag, \",\")[0]; tagName != \"\" {\n\t\t\t\t\tif fieldName == tagName {\n\t\t\t\t\t\treturn val.Field(i).Interface(), nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if cursor is a \"ref wrapper\" struct (e.g. RequestBodyRef),\n\t\tif _, ok := val.Type().FieldByName(\"Value\"); ok {\n\t\t\t// try digging into its Value field\n\t\t\treturn drillIntoField(val.FieldByName(\"Value\").Interface(), fieldName)\n\t\t}\n\t\tif hasFields {\n\t\t\tif ff := val.Type().Field(0); ff.PkgPath == \"\" && ff.Name == \"Extensions\" {\n\t\t\t\textensions := val.Field(0).Interface().(map[string]any)\n\t\t\t\tif enc, ok := extensions[fieldName]; ok {\n\t\t\t\t\treturn enc, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil, fmt.Errorf(\"struct field %q not found\", fieldName)\n\n\tdefault:\n\t\treturn nil, errors.New(\"not a map, slice nor struct\")\n\t}\n}\n\nfunc (loader *Loader) resolveRefAndDocument(doc *T, ref string, path *url.URL) (*T, string, *url.URL, error) {\n\tif ref != \"\" && ref[0] == '#' {\n\t\treturn doc, ref, path, nil\n\t}\n\n\tfragment, resolvedPath, err := loader.resolveRef(ref, path)\n\tif err != nil {\n\t\treturn nil, \"\", nil, err\n\t}\n\n\tif doc, err = loader.loadFromURIInternal(resolvedPath); err != nil {\n\t\treturn nil, \"\", nil, fmt.Errorf(\"error resolving reference %q: %w\", ref, err)\n\t}\n\n\treturn doc, fragment, resolvedPath, nil\n}\n\nfunc (loader *Loader) resolveRef(ref string, path *url.URL) (string, *url.URL, error) {\n\tresolvedPathRef, err := loader.resolveRefPath(ref, path)\n\tif err != nil {\n\t\treturn \"\", nil, err\n\t}\n\n\tfragment := \"#\" + resolvedPathRef.Fragment\n\tresolvedPathRef.Fragment = \"\"\n\treturn fragment, resolvedPathRef, nil\n}\n\nvar (\n\terrMUSTCallback       = errors.New(\"invalid callback: value MUST be an object\")\n\terrMUSTExample        = errors.New(\"invalid example: value MUST be an object\")\n\terrMUSTHeader         = errors.New(\"invalid header: value MUST be an object\")\n\terrMUSTLink           = errors.New(\"invalid link: value MUST be an object\")\n\terrMUSTParameter      = errors.New(\"invalid parameter: value MUST be an object\")\n\terrMUSTPathItem       = errors.New(\"invalid path item: value MUST be an object\")\n\terrMUSTRequestBody    = errors.New(\"invalid requestBody: value MUST be an object\")\n\terrMUSTResponse       = errors.New(\"invalid response: value MUST be an object\")\n\terrMUSTSchema         = errors.New(\"invalid schema: value MUST be an object\")\n\terrMUSTSecurityScheme = errors.New(\"invalid securityScheme: value MUST be an object\")\n)\n\nfunc (loader *Loader) resolveHeaderRef(doc *T, component *HeaderRef, documentPath *url.URL) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTHeader\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*Header)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar header Header\n\t\t\tif documentPath, err = loader.loadSingleElementFromURI(ref, documentPath, &header); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &header\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved HeaderRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := loader.resolveHeaderRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTHeader {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\tvalue := component.Value\n\tif value == nil {\n\t\treturn nil\n\t}\n\n\tif schema := value.Schema; schema != nil {\n\t\tif err := loader.resolveSchemaRef(doc, schema, documentPath, []string{}); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveParameterRef(doc *T, component *ParameterRef, documentPath *url.URL) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTParameter\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*Parameter)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar param Parameter\n\t\t\tif documentPath, err = loader.loadSingleElementFromURI(ref, documentPath, &param); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &param\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved ParameterRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := loader.resolveParameterRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTParameter {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\tvalue := component.Value\n\tif value == nil {\n\t\treturn nil\n\t}\n\n\tif value.Content != nil && value.Schema != nil {\n\t\treturn errors.New(\"cannot contain both schema and content in a parameter\")\n\t}\n\tfor _, name := range componentNames(value.Content) {\n\t\tcontentType := value.Content[name]\n\t\tif schema := contentType.Schema; schema != nil {\n\t\t\tif err := loader.resolveSchemaRef(doc, schema, documentPath, []string{}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\tif schema := value.Schema; schema != nil {\n\t\tif err := loader.resolveSchemaRef(doc, schema, documentPath, []string{}); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveRequestBodyRef(doc *T, component *RequestBodyRef, documentPath *url.URL) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTRequestBody\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*RequestBody)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar requestBody RequestBody\n\t\t\tif documentPath, err = loader.loadSingleElementFromURI(ref, documentPath, &requestBody); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &requestBody\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved RequestBodyRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err = loader.resolveRequestBodyRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTRequestBody {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\tvalue := component.Value\n\tif value == nil {\n\t\treturn nil\n\t}\n\n\tfor _, name := range componentNames(value.Content) {\n\t\tcontentType := value.Content[name]\n\t\tif contentType == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, name := range componentNames(contentType.Examples) {\n\t\t\texample := contentType.Examples[name]\n\t\t\tif err := loader.resolveExampleRef(doc, example, documentPath); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontentType.Examples[name] = example\n\t\t}\n\t\tif schema := contentType.Schema; schema != nil {\n\t\t\tif err := loader.resolveSchemaRef(doc, schema, documentPath, []string{}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveResponseRef(doc *T, component *ResponseRef, documentPath *url.URL) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTResponse\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*Response)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar resp Response\n\t\t\tif documentPath, err = loader.loadSingleElementFromURI(ref, documentPath, &resp); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &resp\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved ResponseRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := loader.resolveResponseRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTResponse {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\tvalue := component.Value\n\tif value == nil {\n\t\treturn nil\n\t}\n\n\tfor _, name := range componentNames(value.Headers) {\n\t\theader := value.Headers[name]\n\t\tif err := loader.resolveHeaderRef(doc, header, documentPath); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, name := range componentNames(value.Content) {\n\t\tcontentType := value.Content[name]\n\t\tif contentType == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, name := range componentNames(contentType.Examples) {\n\t\t\texample := contentType.Examples[name]\n\t\t\tif err := loader.resolveExampleRef(doc, example, documentPath); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontentType.Examples[name] = example\n\t\t}\n\t\tif schema := contentType.Schema; schema != nil {\n\t\t\tif err := loader.resolveSchemaRef(doc, schema, documentPath, []string{}); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontentType.Schema = schema\n\t\t}\n\t}\n\tfor _, name := range componentNames(value.Links) {\n\t\tlink := value.Links[name]\n\t\tif err := loader.resolveLinkRef(doc, link, documentPath); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveSchemaRef(doc *T, component *SchemaRef, documentPath *url.URL, visited []string) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTSchema\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*Schema)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar schema Schema\n\t\t\tif documentPath, err = loader.loadSingleElementFromURI(ref, documentPath, &schema); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &schema\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved SchemaRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := loader.resolveSchemaRef(doc, &resolved, componentPath, visited); err != nil {\n\t\t\t\tif err == errMUSTSchema {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\tvalue := component.Value\n\tif value == nil {\n\t\treturn nil\n\t}\n\n\t// ResolveRefs referred schemas\n\tif v := value.Items; v != nil {\n\t\tif err := loader.resolveSchemaRef(doc, v, documentPath, visited); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, name := range componentNames(value.Properties) {\n\t\tv := value.Properties[name]\n\t\tif err := loader.resolveSchemaRef(doc, v, documentPath, visited); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif v := value.AdditionalProperties.Schema; v != nil {\n\t\tif err := loader.resolveSchemaRef(doc, v, documentPath, visited); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif v := value.Not; v != nil {\n\t\tif err := loader.resolveSchemaRef(doc, v, documentPath, visited); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, v := range value.AllOf {\n\t\tif err := loader.resolveSchemaRef(doc, v, documentPath, visited); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, v := range value.AnyOf {\n\t\tif err := loader.resolveSchemaRef(doc, v, documentPath, visited); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, v := range value.OneOf {\n\t\tif err := loader.resolveSchemaRef(doc, v, documentPath, visited); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveSecuritySchemeRef(doc *T, component *SecuritySchemeRef, documentPath *url.URL) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTSecurityScheme\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*SecurityScheme)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar scheme SecurityScheme\n\t\t\tif _, err = loader.loadSingleElementFromURI(ref, documentPath, &scheme); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &scheme\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved SecuritySchemeRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := loader.resolveSecuritySchemeRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTSecurityScheme {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveExampleRef(doc *T, component *ExampleRef, documentPath *url.URL) (err error) {\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*Example)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar example Example\n\t\t\tif _, err = loader.loadSingleElementFromURI(ref, documentPath, &example); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &example\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved ExampleRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := loader.resolveExampleRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTExample {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveCallbackRef(doc *T, component *CallbackRef, documentPath *url.URL) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTCallback\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*Callback)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar resolved Callback\n\t\t\tif documentPath, err = loader.loadSingleElementFromURI(ref, documentPath, &resolved); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &resolved\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved CallbackRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err = loader.resolveCallbackRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTCallback {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\tvalue := component.Value\n\tif value == nil {\n\t\treturn nil\n\t}\n\n\tpathItems := value.Map()\n\tfor _, name := range componentNames(pathItems) {\n\t\tpathItem := pathItems[name]\n\t\tif err = loader.resolvePathItemRef(doc, pathItem, documentPath); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolveLinkRef(doc *T, component *LinkRef, documentPath *url.URL) (err error) {\n\tif component.isEmpty() {\n\t\treturn errMUSTLink\n\t}\n\n\tif ref := component.Ref; ref != \"\" {\n\t\tif component.Value != nil {\n\t\t\treturn nil\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\tcomponent.Value = value.(*Link)\n\t\t\trefPath, _ := loader.resolveRefPath(ref, documentPath)\n\t\t\tcomponent.setRefPath(refPath)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar link Link\n\t\t\tif _, err = loader.loadSingleElementFromURI(ref, documentPath, &link); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = &link\n\t\t\tcomponent.setRefPath(documentPath)\n\t\t} else {\n\t\t\tvar resolved LinkRef\n\t\t\tdoc, componentPath, err := loader.resolveComponent(doc, ref, documentPath, &resolved)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := loader.resolveLinkRef(doc, &resolved, componentPath); err != nil {\n\t\t\t\tif err == errMUSTLink {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcomponent.Value = resolved.Value\n\t\t\tcomponent.setRefPath(resolved.RefPath())\n\t\t}\n\t\tdefer loader.unvisitRef(ref, component.Value)\n\t}\n\treturn nil\n}\n\nfunc (loader *Loader) resolvePathItemRef(doc *T, pathItem *PathItem, documentPath *url.URL) (err error) {\n\tif pathItem == nil {\n\t\terr = errMUSTPathItem\n\t\treturn\n\t}\n\n\tif ref := pathItem.Ref; ref != \"\" {\n\t\tif !pathItem.isEmpty() {\n\t\t\treturn\n\t\t}\n\t\tif !loader.shouldVisitRef(ref, func(value any) {\n\t\t\t*pathItem = *value.(*PathItem)\n\t\t}) {\n\t\t\treturn nil\n\t\t}\n\t\tloader.visitRef(ref)\n\t\tif isSingleRefElement(ref) {\n\t\t\tvar p PathItem\n\t\t\tif documentPath, err = loader.loadSingleElementFromURI(ref, documentPath, &p); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t*pathItem = p\n\t\t} else {\n\t\t\tvar resolved PathItem\n\t\t\tif doc, documentPath, err = loader.resolveComponent(doc, ref, documentPath, &resolved); err != nil {\n\t\t\t\tif err == errMUSTPathItem {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\t*pathItem = resolved\n\t\t}\n\t\tpathItem.Ref = ref\n\t\tdefer loader.unvisitRef(ref, pathItem)\n\t}\n\n\tfor _, parameter := range pathItem.Parameters {\n\t\tif err = loader.resolveParameterRef(doc, parameter, documentPath); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\toperations := pathItem.Operations()\n\tfor _, name := range componentNames(operations) {\n\t\toperation := operations[name]\n\t\tfor _, parameter := range operation.Parameters {\n\t\t\tif err = loader.resolveParameterRef(doc, parameter, documentPath); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif requestBody := operation.RequestBody; requestBody != nil {\n\t\t\tif err = loader.resolveRequestBodyRef(doc, requestBody, documentPath); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tresponses := operation.Responses.Map()\n\t\tfor _, name := range componentNames(responses) {\n\t\t\tresponse := responses[name]\n\t\t\tif err = loader.resolveResponseRef(doc, response, documentPath); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tfor _, name := range componentNames(operation.Callbacks) {\n\t\t\tcallback := operation.Callbacks[name]\n\t\t\tif err = loader.resolveCallbackRef(doc, callback, documentPath); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc unescapeRefString(ref string) string {\n\treturn strings.Replace(strings.Replace(ref, \"~1\", \"/\", -1), \"~0\", \"~\", -1)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/loader_uri_reader.go",
    "content": "package openapi3\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n)\n\n// ReadFromURIFunc defines a function which reads the contents of a resource\n// located at a URI.\ntype ReadFromURIFunc func(loader *Loader, url *url.URL) ([]byte, error)\n\nvar uriMu = &sync.RWMutex{}\n\n// ErrURINotSupported indicates the ReadFromURIFunc does not know how to handle a\n// given URI.\nvar ErrURINotSupported = errors.New(\"unsupported URI\")\n\n// ReadFromURIs returns a ReadFromURIFunc which tries to read a URI using the\n// given reader functions, in the same order. If a reader function does not\n// support the URI and returns ErrURINotSupported, the next function is checked\n// until a match is found, or the URI is not supported by any.\nfunc ReadFromURIs(readers ...ReadFromURIFunc) ReadFromURIFunc {\n\treturn func(loader *Loader, url *url.URL) ([]byte, error) {\n\t\tfor i := range readers {\n\t\t\tbuf, err := readers[i](loader, url)\n\t\t\tif err == ErrURINotSupported {\n\t\t\t\tcontinue\n\t\t\t} else if err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn buf, nil\n\t\t}\n\t\treturn nil, ErrURINotSupported\n\t}\n}\n\n// DefaultReadFromURI returns a caching ReadFromURIFunc which can read remote\n// HTTP URIs and local file URIs.\nvar DefaultReadFromURI = URIMapCache(ReadFromURIs(ReadFromHTTP(http.DefaultClient), ReadFromFile))\n\n// ReadFromHTTP returns a ReadFromURIFunc which uses the given http.Client to\n// read the contents from a remote HTTP URI. This client may be customized to\n// implement timeouts, RFC 7234 caching, etc.\nfunc ReadFromHTTP(cl *http.Client) ReadFromURIFunc {\n\treturn func(loader *Loader, location *url.URL) ([]byte, error) {\n\t\tif location.Scheme == \"\" || location.Host == \"\" {\n\t\t\treturn nil, ErrURINotSupported\n\t\t}\n\t\treq, err := http.NewRequest(\"GET\", location.String(), nil)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresp, err := cl.Do(req)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer resp.Body.Close()\n\t\tif resp.StatusCode > 399 {\n\t\t\treturn nil, fmt.Errorf(\"error loading %q: request returned status code %d\", location.String(), resp.StatusCode)\n\t\t}\n\t\treturn io.ReadAll(resp.Body)\n\t}\n}\n\nfunc is_file(location *url.URL) bool {\n\treturn location.Path != \"\" &&\n\t\tlocation.Host == \"\" &&\n\t\t(location.Scheme == \"\" || location.Scheme == \"file\")\n}\n\n// ReadFromFile is a ReadFromURIFunc which reads local file URIs.\nfunc ReadFromFile(loader *Loader, location *url.URL) ([]byte, error) {\n\tif !is_file(location) {\n\t\treturn nil, ErrURINotSupported\n\t}\n\treturn os.ReadFile(filepath.FromSlash(location.Path))\n}\n\n// URIMapCache returns a ReadFromURIFunc that caches the contents read from URI\n// locations in a simple map. This cache implementation is suitable for\n// short-lived processes such as command-line tools which process OpenAPI\n// documents.\nfunc URIMapCache(reader ReadFromURIFunc) ReadFromURIFunc {\n\tcache := map[string][]byte{}\n\treturn func(loader *Loader, location *url.URL) (buf []byte, err error) {\n\t\tif location.Scheme == \"\" || location.Scheme == \"file\" {\n\t\t\tif !filepath.IsAbs(location.Path) {\n\t\t\t\t// Do not cache relative file paths; this can cause trouble if\n\t\t\t\t// the current working directory changes when processing\n\t\t\t\t// multiple top-level documents.\n\t\t\t\treturn reader(loader, location)\n\t\t\t}\n\t\t}\n\t\turi := location.String()\n\t\tvar ok bool\n\t\turiMu.RLock()\n\t\tif buf, ok = cache[uri]; ok {\n\t\t\turiMu.RUnlock()\n\t\t\treturn\n\t\t}\n\t\turiMu.RUnlock()\n\t\tif buf, err = reader(loader, location); err != nil {\n\t\t\treturn\n\t\t}\n\t\turiMu.Lock()\n\t\tdefer uriMu.Unlock()\n\t\tcache[uri] = buf\n\t\treturn\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/maplike.go",
    "content": "package openapi3\n\nimport (\n\t\"encoding/json\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\n// NewResponsesWithCapacity builds a responses object of the given capacity.\nfunc NewResponsesWithCapacity(cap int) *Responses {\n\tif cap == 0 {\n\t\treturn &Responses{m: make(map[string]*ResponseRef)}\n\t}\n\treturn &Responses{m: make(map[string]*ResponseRef, cap)}\n}\n\n// Value returns the responses for key or nil\nfunc (responses *Responses) Value(key string) *ResponseRef {\n\tif responses.Len() == 0 {\n\t\treturn nil\n\t}\n\treturn responses.m[key]\n}\n\n// Set adds or replaces key 'key' of 'responses' with 'value'.\n// Note: 'responses' MUST be non-nil\nfunc (responses *Responses) Set(key string, value *ResponseRef) {\n\tif responses.m == nil {\n\t\tresponses.m = make(map[string]*ResponseRef)\n\t}\n\tresponses.m[key] = value\n}\n\n// Len returns the amount of keys in responses excluding responses.Extensions.\nfunc (responses *Responses) Len() int {\n\tif responses == nil || responses.m == nil {\n\t\treturn 0\n\t}\n\treturn len(responses.m)\n}\n\n// Delete removes the entry associated with key 'key' from 'responses'.\nfunc (responses *Responses) Delete(key string) {\n\tif responses != nil && responses.m != nil {\n\t\tdelete(responses.m, key)\n\t}\n}\n\n// Map returns responses as a 'map'.\n// Note: iteration on Go maps is not ordered.\nfunc (responses *Responses) Map() (m map[string]*ResponseRef) {\n\tif responses == nil || len(responses.m) == 0 {\n\t\treturn make(map[string]*ResponseRef)\n\t}\n\tm = make(map[string]*ResponseRef, len(responses.m))\n\tfor k, v := range responses.m {\n\t\tm[k] = v\n\t}\n\treturn\n}\n\nvar _ jsonpointer.JSONPointable = (*Responses)(nil)\n\n// JSONLookup implements https://github.com/go-openapi/jsonpointer#JSONPointable\nfunc (responses Responses) JSONLookup(token string) (any, error) {\n\tif v := responses.Value(token); v == nil {\n\t\tvv, _, err := jsonpointer.GetForToken(responses.Extensions, token)\n\t\treturn vv, err\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\tvar vv *Response = v.Value\n\t\treturn vv, nil\n\t}\n}\n\n// MarshalYAML returns the YAML encoding of Responses.\nfunc (responses *Responses) MarshalYAML() (any, error) {\n\tif responses == nil {\n\t\treturn nil, nil\n\t}\n\tm := make(map[string]any, responses.Len()+len(responses.Extensions))\n\tfor k, v := range responses.Extensions {\n\t\tm[k] = v\n\t}\n\tfor k, v := range responses.Map() {\n\t\tm[k] = v\n\t}\n\treturn m, nil\n}\n\n// MarshalJSON returns the JSON encoding of Responses.\nfunc (responses *Responses) MarshalJSON() ([]byte, error) {\n\tresponsesYaml, err := responses.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(responsesYaml)\n}\n\n// UnmarshalJSON sets Responses to a copy of data.\nfunc (responses *Responses) UnmarshalJSON(data []byte) (err error) {\n\tvar m map[string]any\n\tif err = json.Unmarshal(data, &m); err != nil {\n\t\treturn\n\t}\n\n\tks := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tks = append(ks, k)\n\t}\n\tsort.Strings(ks)\n\n\tx := Responses{\n\t\tExtensions: make(map[string]any),\n\t\tm:          make(map[string]*ResponseRef, len(m)),\n\t}\n\n\tfor _, k := range ks {\n\t\tv := m[k]\n\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\tx.Extensions[k] = v\n\t\t\tcontinue\n\t\t}\n\n\t\tif k == originKey {\n\t\t\tvar data []byte\n\t\t\tif data, err = json.Marshal(v); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err = json.Unmarshal(data, &x.Origin); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tvar data []byte\n\t\tif data, err = json.Marshal(v); err != nil {\n\t\t\treturn\n\t\t}\n\t\tvar vv ResponseRef\n\t\tif err = vv.UnmarshalJSON(data); err != nil {\n\t\t\treturn\n\t\t}\n\t\tx.m[k] = &vv\n\t}\n\t*responses = x\n\treturn\n}\n\n// NewCallbackWithCapacity builds a callback object of the given capacity.\nfunc NewCallbackWithCapacity(cap int) *Callback {\n\tif cap == 0 {\n\t\treturn &Callback{m: make(map[string]*PathItem)}\n\t}\n\treturn &Callback{m: make(map[string]*PathItem, cap)}\n}\n\n// Value returns the callback for key or nil\nfunc (callback *Callback) Value(key string) *PathItem {\n\tif callback.Len() == 0 {\n\t\treturn nil\n\t}\n\treturn callback.m[key]\n}\n\n// Set adds or replaces key 'key' of 'callback' with 'value'.\n// Note: 'callback' MUST be non-nil\nfunc (callback *Callback) Set(key string, value *PathItem) {\n\tif callback.m == nil {\n\t\tcallback.m = make(map[string]*PathItem)\n\t}\n\tcallback.m[key] = value\n}\n\n// Len returns the amount of keys in callback excluding callback.Extensions.\nfunc (callback *Callback) Len() int {\n\tif callback == nil || callback.m == nil {\n\t\treturn 0\n\t}\n\treturn len(callback.m)\n}\n\n// Delete removes the entry associated with key 'key' from 'callback'.\nfunc (callback *Callback) Delete(key string) {\n\tif callback != nil && callback.m != nil {\n\t\tdelete(callback.m, key)\n\t}\n}\n\n// Map returns callback as a 'map'.\n// Note: iteration on Go maps is not ordered.\nfunc (callback *Callback) Map() (m map[string]*PathItem) {\n\tif callback == nil || len(callback.m) == 0 {\n\t\treturn make(map[string]*PathItem)\n\t}\n\tm = make(map[string]*PathItem, len(callback.m))\n\tfor k, v := range callback.m {\n\t\tm[k] = v\n\t}\n\treturn\n}\n\nvar _ jsonpointer.JSONPointable = (*Callback)(nil)\n\n// JSONLookup implements https://github.com/go-openapi/jsonpointer#JSONPointable\nfunc (callback Callback) JSONLookup(token string) (any, error) {\n\tif v := callback.Value(token); v == nil {\n\t\tvv, _, err := jsonpointer.GetForToken(callback.Extensions, token)\n\t\treturn vv, err\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\tvar vv *PathItem = v\n\t\treturn vv, nil\n\t}\n}\n\n// MarshalYAML returns the YAML encoding of Callback.\nfunc (callback *Callback) MarshalYAML() (any, error) {\n\tif callback == nil {\n\t\treturn nil, nil\n\t}\n\tm := make(map[string]any, callback.Len()+len(callback.Extensions))\n\tfor k, v := range callback.Extensions {\n\t\tm[k] = v\n\t}\n\tfor k, v := range callback.Map() {\n\t\tm[k] = v\n\t}\n\treturn m, nil\n}\n\n// MarshalJSON returns the JSON encoding of Callback.\nfunc (callback *Callback) MarshalJSON() ([]byte, error) {\n\tcallbackYaml, err := callback.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(callbackYaml)\n}\n\n// UnmarshalJSON sets Callback to a copy of data.\nfunc (callback *Callback) UnmarshalJSON(data []byte) (err error) {\n\tvar m map[string]any\n\tif err = json.Unmarshal(data, &m); err != nil {\n\t\treturn\n\t}\n\n\tks := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tks = append(ks, k)\n\t}\n\tsort.Strings(ks)\n\n\tx := Callback{\n\t\tExtensions: make(map[string]any),\n\t\tm:          make(map[string]*PathItem, len(m)),\n\t}\n\n\tfor _, k := range ks {\n\t\tv := m[k]\n\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\tx.Extensions[k] = v\n\t\t\tcontinue\n\t\t}\n\n\t\tif k == originKey {\n\t\t\tvar data []byte\n\t\t\tif data, err = json.Marshal(v); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err = json.Unmarshal(data, &x.Origin); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tvar data []byte\n\t\tif data, err = json.Marshal(v); err != nil {\n\t\t\treturn\n\t\t}\n\t\tvar vv PathItem\n\t\tif err = vv.UnmarshalJSON(data); err != nil {\n\t\t\treturn\n\t\t}\n\t\tx.m[k] = &vv\n\t}\n\t*callback = x\n\treturn\n}\n\n// NewPathsWithCapacity builds a paths object of the given capacity.\nfunc NewPathsWithCapacity(cap int) *Paths {\n\tif cap == 0 {\n\t\treturn &Paths{m: make(map[string]*PathItem)}\n\t}\n\treturn &Paths{m: make(map[string]*PathItem, cap)}\n}\n\n// Value returns the paths for key or nil\nfunc (paths *Paths) Value(key string) *PathItem {\n\tif paths.Len() == 0 {\n\t\treturn nil\n\t}\n\treturn paths.m[key]\n}\n\n// Set adds or replaces key 'key' of 'paths' with 'value'.\n// Note: 'paths' MUST be non-nil\nfunc (paths *Paths) Set(key string, value *PathItem) {\n\tif paths.m == nil {\n\t\tpaths.m = make(map[string]*PathItem)\n\t}\n\tpaths.m[key] = value\n}\n\n// Len returns the amount of keys in paths excluding paths.Extensions.\nfunc (paths *Paths) Len() int {\n\tif paths == nil || paths.m == nil {\n\t\treturn 0\n\t}\n\treturn len(paths.m)\n}\n\n// Delete removes the entry associated with key 'key' from 'paths'.\nfunc (paths *Paths) Delete(key string) {\n\tif paths != nil && paths.m != nil {\n\t\tdelete(paths.m, key)\n\t}\n}\n\n// Map returns paths as a 'map'.\n// Note: iteration on Go maps is not ordered.\nfunc (paths *Paths) Map() (m map[string]*PathItem) {\n\tif paths == nil || len(paths.m) == 0 {\n\t\treturn make(map[string]*PathItem)\n\t}\n\tm = make(map[string]*PathItem, len(paths.m))\n\tfor k, v := range paths.m {\n\t\tm[k] = v\n\t}\n\treturn\n}\n\nvar _ jsonpointer.JSONPointable = (*Paths)(nil)\n\n// JSONLookup implements https://github.com/go-openapi/jsonpointer#JSONPointable\nfunc (paths Paths) JSONLookup(token string) (any, error) {\n\tif v := paths.Value(token); v == nil {\n\t\tvv, _, err := jsonpointer.GetForToken(paths.Extensions, token)\n\t\treturn vv, err\n\t} else if ref := v.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t} else {\n\t\tvar vv *PathItem = v\n\t\treturn vv, nil\n\t}\n}\n\n// MarshalYAML returns the YAML encoding of Paths.\nfunc (paths *Paths) MarshalYAML() (any, error) {\n\tif paths == nil {\n\t\treturn nil, nil\n\t}\n\tm := make(map[string]any, paths.Len()+len(paths.Extensions))\n\tfor k, v := range paths.Extensions {\n\t\tm[k] = v\n\t}\n\tfor k, v := range paths.Map() {\n\t\tm[k] = v\n\t}\n\treturn m, nil\n}\n\n// MarshalJSON returns the JSON encoding of Paths.\nfunc (paths *Paths) MarshalJSON() ([]byte, error) {\n\tpathsYaml, err := paths.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(pathsYaml)\n}\n\n// UnmarshalJSON sets Paths to a copy of data.\nfunc (paths *Paths) UnmarshalJSON(data []byte) (err error) {\n\tvar m map[string]any\n\tif err = json.Unmarshal(data, &m); err != nil {\n\t\treturn\n\t}\n\n\tks := make([]string, 0, len(m))\n\tfor k := range m {\n\t\tks = append(ks, k)\n\t}\n\tsort.Strings(ks)\n\n\tx := Paths{\n\t\tExtensions: make(map[string]any),\n\t\tm:          make(map[string]*PathItem, len(m)),\n\t}\n\n\tfor _, k := range ks {\n\t\tv := m[k]\n\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\tx.Extensions[k] = v\n\t\t\tcontinue\n\t\t}\n\n\t\tif k == originKey {\n\t\t\tvar data []byte\n\t\t\tif data, err = json.Marshal(v); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err = json.Unmarshal(data, &x.Origin); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tvar data []byte\n\t\tif data, err = json.Marshal(v); err != nil {\n\t\t\treturn\n\t\t}\n\t\tvar vv PathItem\n\t\tif err = vv.UnmarshalJSON(data); err != nil {\n\t\t\treturn\n\t\t}\n\t\tx.m[k] = &vv\n\t}\n\t*paths = x\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/marsh.go",
    "content": "package openapi3\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/oasdiff/yaml\"\n)\n\nfunc unmarshalError(jsonUnmarshalErr error) error {\n\tif before, after, found := strings.Cut(jsonUnmarshalErr.Error(), \"Bis\"); found && before != \"\" && after != \"\" {\n\t\tbefore = strings.ReplaceAll(before, \" Go struct \", \" \")\n\t\treturn fmt.Errorf(\"%s%s\", before, strings.ReplaceAll(after, \"Bis\", \"\"))\n\t}\n\treturn jsonUnmarshalErr\n}\n\nfunc unmarshal(data []byte, v any, includeOrigin bool) error {\n\tvar jsonErr, yamlErr error\n\n\t// See https://github.com/getkin/kin-openapi/issues/680\n\tif jsonErr = json.Unmarshal(data, v); jsonErr == nil {\n\t\treturn nil\n\t}\n\n\t// UnmarshalStrict(data, v) TODO: investigate how ymlv3 handles duplicate map keys\n\tif yamlErr = yaml.UnmarshalWithOrigin(data, v, includeOrigin); yamlErr == nil {\n\t\treturn nil\n\t}\n\n\t// If both unmarshaling attempts fail, return a new error that includes both errors\n\treturn fmt.Errorf(\"failed to unmarshal data: json error: %v, yaml error: %v\", jsonErr, yamlErr)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/media_type.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\n// MediaType is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#media-type-object\ntype MediaType struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tSchema   *SchemaRef           `json:\"schema,omitempty\" yaml:\"schema,omitempty\"`\n\tExample  any                  `json:\"example,omitempty\" yaml:\"example,omitempty\"`\n\tExamples Examples             `json:\"examples,omitempty\" yaml:\"examples,omitempty\"`\n\tEncoding map[string]*Encoding `json:\"encoding,omitempty\" yaml:\"encoding,omitempty\"`\n}\n\nvar _ jsonpointer.JSONPointable = (*MediaType)(nil)\n\nfunc NewMediaType() *MediaType {\n\treturn &MediaType{}\n}\n\nfunc (mediaType *MediaType) WithSchema(schema *Schema) *MediaType {\n\tif schema == nil {\n\t\tmediaType.Schema = nil\n\t} else {\n\t\tmediaType.Schema = &SchemaRef{Value: schema}\n\t}\n\treturn mediaType\n}\n\nfunc (mediaType *MediaType) WithSchemaRef(schema *SchemaRef) *MediaType {\n\tmediaType.Schema = schema\n\treturn mediaType\n}\n\nfunc (mediaType *MediaType) WithExample(name string, value any) *MediaType {\n\texample := mediaType.Examples\n\tif example == nil {\n\t\texample = make(map[string]*ExampleRef)\n\t\tmediaType.Examples = example\n\t}\n\texample[name] = &ExampleRef{\n\t\tValue: NewExample(value),\n\t}\n\treturn mediaType\n}\n\nfunc (mediaType *MediaType) WithEncoding(name string, enc *Encoding) *MediaType {\n\tencoding := mediaType.Encoding\n\tif encoding == nil {\n\t\tencoding = make(map[string]*Encoding)\n\t\tmediaType.Encoding = encoding\n\t}\n\tencoding[name] = enc\n\treturn mediaType\n}\n\n// MarshalJSON returns the JSON encoding of MediaType.\nfunc (mediaType MediaType) MarshalJSON() ([]byte, error) {\n\tx, err := mediaType.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of MediaType.\nfunc (mediaType MediaType) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 4+len(mediaType.Extensions))\n\tfor k, v := range mediaType.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := mediaType.Schema; x != nil {\n\t\tm[\"schema\"] = x\n\t}\n\tif x := mediaType.Example; x != nil {\n\t\tm[\"example\"] = x\n\t}\n\tif x := mediaType.Examples; len(x) != 0 {\n\t\tm[\"examples\"] = x\n\t}\n\tif x := mediaType.Encoding; len(x) != 0 {\n\t\tm[\"encoding\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets MediaType to a copy of data.\nfunc (mediaType *MediaType) UnmarshalJSON(data []byte) error {\n\ttype MediaTypeBis MediaType\n\tvar x MediaTypeBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"schema\")\n\tdelete(x.Extensions, \"example\")\n\tdelete(x.Extensions, \"examples\")\n\tdelete(x.Extensions, \"encoding\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*mediaType = MediaType(x)\n\treturn nil\n}\n\n// Validate returns an error if MediaType does not comply with the OpenAPI spec.\nfunc (mediaType *MediaType) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif mediaType == nil {\n\t\treturn nil\n\t}\n\tif schema := mediaType.Schema; schema != nil {\n\t\tif err := schema.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif mediaType.Example != nil && mediaType.Examples != nil {\n\t\t\treturn errors.New(\"example and examples are mutually exclusive\")\n\t\t}\n\n\t\tif vo := getValidationOptions(ctx); !vo.examplesValidationDisabled {\n\t\t\tif example := mediaType.Example; example != nil {\n\t\t\t\tif err := validateExampleValue(ctx, example, schema.Value); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"invalid example: %w\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif examples := mediaType.Examples; examples != nil {\n\t\t\t\tnames := make([]string, 0, len(examples))\n\t\t\t\tfor name := range examples {\n\t\t\t\t\tnames = append(names, name)\n\t\t\t\t}\n\t\t\t\tsort.Strings(names)\n\t\t\t\tfor _, k := range names {\n\t\t\t\t\tv := examples[k]\n\t\t\t\t\tif err := v.Validate(ctx); err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"example %s: %w\", k, err)\n\t\t\t\t\t}\n\t\t\t\t\tif err := validateExampleValue(ctx, v.Value.Value, schema.Value); err != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"example %s: %w\", k, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, mediaType.Extensions)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (mediaType MediaType) JSONLookup(token string) (any, error) {\n\tswitch token {\n\tcase \"schema\":\n\t\tif mediaType.Schema != nil {\n\t\t\tif mediaType.Schema.Ref != \"\" {\n\t\t\t\treturn &Ref{Ref: mediaType.Schema.Ref}, nil\n\t\t\t}\n\t\t\treturn mediaType.Schema.Value, nil\n\t\t}\n\tcase \"example\":\n\t\treturn mediaType.Example, nil\n\tcase \"examples\":\n\t\treturn mediaType.Examples, nil\n\tcase \"encoding\":\n\t\treturn mediaType.Encoding, nil\n\t}\n\tv, _, err := jsonpointer.GetForToken(mediaType.Extensions, token)\n\treturn v, err\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/openapi3.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\n// T is the root of an OpenAPI v3 document\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#openapi-object\ntype T struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\n\tOpenAPI      string               `json:\"openapi\" yaml:\"openapi\"` // Required\n\tComponents   *Components          `json:\"components,omitempty\" yaml:\"components,omitempty\"`\n\tInfo         *Info                `json:\"info\" yaml:\"info\"`   // Required\n\tPaths        *Paths               `json:\"paths\" yaml:\"paths\"` // Required\n\tSecurity     SecurityRequirements `json:\"security,omitempty\" yaml:\"security,omitempty\"`\n\tServers      Servers              `json:\"servers,omitempty\" yaml:\"servers,omitempty\"`\n\tTags         Tags                 `json:\"tags,omitempty\" yaml:\"tags,omitempty\"`\n\tExternalDocs *ExternalDocs        `json:\"externalDocs,omitempty\" yaml:\"externalDocs,omitempty\"`\n\n\tvisited visitedComponent\n\turl     *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*T)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (doc *T) JSONLookup(token string) (any, error) {\n\tswitch token {\n\tcase \"openapi\":\n\t\treturn doc.OpenAPI, nil\n\tcase \"components\":\n\t\treturn doc.Components, nil\n\tcase \"info\":\n\t\treturn doc.Info, nil\n\tcase \"paths\":\n\t\treturn doc.Paths, nil\n\tcase \"security\":\n\t\treturn doc.Security, nil\n\tcase \"servers\":\n\t\treturn doc.Servers, nil\n\tcase \"tags\":\n\t\treturn doc.Tags, nil\n\tcase \"externalDocs\":\n\t\treturn doc.ExternalDocs, nil\n\t}\n\n\tv, _, err := jsonpointer.GetForToken(doc.Extensions, token)\n\treturn v, err\n}\n\n// MarshalJSON returns the JSON encoding of T.\nfunc (doc *T) MarshalJSON() ([]byte, error) {\n\tx, err := doc.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of T.\nfunc (doc *T) MarshalYAML() (any, error) {\n\tif doc == nil {\n\t\treturn nil, nil\n\t}\n\tm := make(map[string]any, 4+len(doc.Extensions))\n\tfor k, v := range doc.Extensions {\n\t\tm[k] = v\n\t}\n\tm[\"openapi\"] = doc.OpenAPI\n\tif x := doc.Components; x != nil {\n\t\tm[\"components\"] = x\n\t}\n\tm[\"info\"] = doc.Info\n\tm[\"paths\"] = doc.Paths\n\tif x := doc.Security; len(x) != 0 {\n\t\tm[\"security\"] = x\n\t}\n\tif x := doc.Servers; len(x) != 0 {\n\t\tm[\"servers\"] = x\n\t}\n\tif x := doc.Tags; len(x) != 0 {\n\t\tm[\"tags\"] = x\n\t}\n\tif x := doc.ExternalDocs; x != nil {\n\t\tm[\"externalDocs\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets T to a copy of data.\nfunc (doc *T) UnmarshalJSON(data []byte) error {\n\ttype TBis T\n\tvar x TBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, \"openapi\")\n\tdelete(x.Extensions, \"components\")\n\tdelete(x.Extensions, \"info\")\n\tdelete(x.Extensions, \"paths\")\n\tdelete(x.Extensions, \"security\")\n\tdelete(x.Extensions, \"servers\")\n\tdelete(x.Extensions, \"tags\")\n\tdelete(x.Extensions, \"externalDocs\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*doc = T(x)\n\treturn nil\n}\n\nfunc (doc *T) AddOperation(path string, method string, operation *Operation) {\n\tif doc.Paths == nil {\n\t\tdoc.Paths = NewPaths()\n\t}\n\tpathItem := doc.Paths.Value(path)\n\tif pathItem == nil {\n\t\tpathItem = &PathItem{}\n\t\tdoc.Paths.Set(path, pathItem)\n\t}\n\tpathItem.SetOperation(method, operation)\n}\n\nfunc (doc *T) AddServer(server *Server) {\n\tdoc.Servers = append(doc.Servers, server)\n}\n\nfunc (doc *T) AddServers(servers ...*Server) {\n\tdoc.Servers = append(doc.Servers, servers...)\n}\n\n// Validate returns an error if T does not comply with the OpenAPI spec.\n// Validations Options can be provided to modify the validation behavior.\nfunc (doc *T) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif doc.OpenAPI == \"\" {\n\t\treturn errors.New(\"value of openapi must be a non-empty string\")\n\t}\n\n\tvar wrap func(error) error\n\n\twrap = func(e error) error { return fmt.Errorf(\"invalid components: %w\", e) }\n\tif v := doc.Components; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn wrap(err)\n\t\t}\n\t}\n\n\twrap = func(e error) error { return fmt.Errorf(\"invalid info: %w\", e) }\n\tif v := doc.Info; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn wrap(err)\n\t\t}\n\t} else {\n\t\treturn wrap(errors.New(\"must be an object\"))\n\t}\n\n\twrap = func(e error) error { return fmt.Errorf(\"invalid paths: %w\", e) }\n\tif v := doc.Paths; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn wrap(err)\n\t\t}\n\t} else {\n\t\treturn wrap(errors.New(\"must be an object\"))\n\t}\n\n\twrap = func(e error) error { return fmt.Errorf(\"invalid security: %w\", e) }\n\tif v := doc.Security; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn wrap(err)\n\t\t}\n\t}\n\n\twrap = func(e error) error { return fmt.Errorf(\"invalid servers: %w\", e) }\n\tif v := doc.Servers; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn wrap(err)\n\t\t}\n\t}\n\n\twrap = func(e error) error { return fmt.Errorf(\"invalid tags: %w\", e) }\n\tif v := doc.Tags; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn wrap(err)\n\t\t}\n\t}\n\n\twrap = func(e error) error { return fmt.Errorf(\"invalid external docs: %w\", e) }\n\tif v := doc.ExternalDocs; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn wrap(err)\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, doc.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/operation.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\n// Operation represents \"operation\" specified by\" OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object\ntype Operation struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\t// Optional tags for documentation.\n\tTags []string `json:\"tags,omitempty\" yaml:\"tags,omitempty\"`\n\n\t// Optional short summary.\n\tSummary string `json:\"summary,omitempty\" yaml:\"summary,omitempty\"`\n\n\t// Optional description. Should use CommonMark syntax.\n\tDescription string `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\n\t// Optional operation ID.\n\tOperationID string `json:\"operationId,omitempty\" yaml:\"operationId,omitempty\"`\n\n\t// Optional parameters.\n\tParameters Parameters `json:\"parameters,omitempty\" yaml:\"parameters,omitempty\"`\n\n\t// Optional body parameter.\n\tRequestBody *RequestBodyRef `json:\"requestBody,omitempty\" yaml:\"requestBody,omitempty\"`\n\n\t// Responses.\n\tResponses *Responses `json:\"responses\" yaml:\"responses\"` // Required\n\n\t// Optional callbacks\n\tCallbacks Callbacks `json:\"callbacks,omitempty\" yaml:\"callbacks,omitempty\"`\n\n\tDeprecated bool `json:\"deprecated,omitempty\" yaml:\"deprecated,omitempty\"`\n\n\t// Optional security requirements that overrides top-level security.\n\tSecurity *SecurityRequirements `json:\"security,omitempty\" yaml:\"security,omitempty\"`\n\n\t// Optional servers that overrides top-level servers.\n\tServers *Servers `json:\"servers,omitempty\" yaml:\"servers,omitempty\"`\n\n\tExternalDocs *ExternalDocs `json:\"externalDocs,omitempty\" yaml:\"externalDocs,omitempty\"`\n}\n\nvar _ jsonpointer.JSONPointable = (*Operation)(nil)\n\nfunc NewOperation() *Operation {\n\treturn &Operation{}\n}\n\n// MarshalJSON returns the JSON encoding of Operation.\nfunc (operation Operation) MarshalJSON() ([]byte, error) {\n\tx, err := operation.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Operation.\nfunc (operation Operation) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 12+len(operation.Extensions))\n\tfor k, v := range operation.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := operation.Tags; len(x) != 0 {\n\t\tm[\"tags\"] = x\n\t}\n\tif x := operation.Summary; x != \"\" {\n\t\tm[\"summary\"] = x\n\t}\n\tif x := operation.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := operation.OperationID; x != \"\" {\n\t\tm[\"operationId\"] = x\n\t}\n\tif x := operation.Parameters; len(x) != 0 {\n\t\tm[\"parameters\"] = x\n\t}\n\tif x := operation.RequestBody; x != nil {\n\t\tm[\"requestBody\"] = x\n\t}\n\tm[\"responses\"] = operation.Responses\n\tif x := operation.Callbacks; len(x) != 0 {\n\t\tm[\"callbacks\"] = x\n\t}\n\tif x := operation.Deprecated; x {\n\t\tm[\"deprecated\"] = x\n\t}\n\tif x := operation.Security; x != nil {\n\t\tm[\"security\"] = x\n\t}\n\tif x := operation.Servers; x != nil {\n\t\tm[\"servers\"] = x\n\t}\n\tif x := operation.ExternalDocs; x != nil {\n\t\tm[\"externalDocs\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Operation to a copy of data.\nfunc (operation *Operation) UnmarshalJSON(data []byte) error {\n\ttype OperationBis Operation\n\tvar x OperationBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"tags\")\n\tdelete(x.Extensions, \"summary\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"operationId\")\n\tdelete(x.Extensions, \"parameters\")\n\tdelete(x.Extensions, \"requestBody\")\n\tdelete(x.Extensions, \"responses\")\n\tdelete(x.Extensions, \"callbacks\")\n\tdelete(x.Extensions, \"deprecated\")\n\tdelete(x.Extensions, \"security\")\n\tdelete(x.Extensions, \"servers\")\n\tdelete(x.Extensions, \"externalDocs\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*operation = Operation(x)\n\treturn nil\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (operation Operation) JSONLookup(token string) (any, error) {\n\tswitch token {\n\tcase \"requestBody\":\n\t\tif operation.RequestBody != nil {\n\t\t\tif operation.RequestBody.Ref != \"\" {\n\t\t\t\treturn &Ref{Ref: operation.RequestBody.Ref}, nil\n\t\t\t}\n\t\t\treturn operation.RequestBody.Value, nil\n\t\t}\n\tcase \"tags\":\n\t\treturn operation.Tags, nil\n\tcase \"summary\":\n\t\treturn operation.Summary, nil\n\tcase \"description\":\n\t\treturn operation.Description, nil\n\tcase \"operationID\":\n\t\treturn operation.OperationID, nil\n\tcase \"parameters\":\n\t\treturn operation.Parameters, nil\n\tcase \"responses\":\n\t\treturn operation.Responses, nil\n\tcase \"callbacks\":\n\t\treturn operation.Callbacks, nil\n\tcase \"deprecated\":\n\t\treturn operation.Deprecated, nil\n\tcase \"security\":\n\t\treturn operation.Security, nil\n\tcase \"servers\":\n\t\treturn operation.Servers, nil\n\tcase \"externalDocs\":\n\t\treturn operation.ExternalDocs, nil\n\t}\n\n\tv, _, err := jsonpointer.GetForToken(operation.Extensions, token)\n\treturn v, err\n}\n\nfunc (operation *Operation) AddParameter(p *Parameter) {\n\toperation.Parameters = append(operation.Parameters, &ParameterRef{Value: p})\n}\n\nfunc (operation *Operation) AddResponse(status int, response *Response) {\n\tcode := \"default\"\n\tif 0 < status && status < 1000 {\n\t\tcode = strconv.FormatInt(int64(status), 10)\n\t}\n\tif operation.Responses == nil {\n\t\toperation.Responses = NewResponses()\n\t}\n\toperation.Responses.Set(code, &ResponseRef{Value: response})\n}\n\n// Validate returns an error if Operation does not comply with the OpenAPI spec.\nfunc (operation *Operation) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif v := operation.Parameters; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif v := operation.RequestBody; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif v := operation.Responses; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\treturn errors.New(\"value of responses must be an object\")\n\t}\n\n\tif v := operation.ExternalDocs; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid external docs: %w\", err)\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, operation.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/origin.go",
    "content": "package openapi3\n\nconst originKey = \"__origin__\"\n\n// Origin contains the origin of a collection.\n// Key is the location of the collection itself.\n// Fields is a map of the location of each field in the collection.\ntype Origin struct {\n\tKey    *Location           `json:\"key,omitempty\" yaml:\"key,omitempty\"`\n\tFields map[string]Location `json:\"fields,omitempty\" yaml:\"fields,omitempty\"`\n}\n\n// Location is a struct that contains the location of a field.\ntype Location struct {\n\tLine   int `json:\"line,omitempty\" yaml:\"line,omitempty\"`\n\tColumn int `json:\"column,omitempty\" yaml:\"column,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/parameter.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n)\n\n// Parameters is specified by OpenAPI/Swagger 3.0 standard.\ntype Parameters []*ParameterRef\n\nvar _ jsonpointer.JSONPointable = (*Parameters)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (p Parameters) JSONLookup(token string) (any, error) {\n\tindex, err := strconv.Atoi(token)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif index < 0 || index >= len(p) {\n\t\treturn nil, fmt.Errorf(\"index %d out of bounds of array of length %d\", index, len(p))\n\t}\n\n\tref := p[index]\n\tif ref != nil && ref.Ref != \"\" {\n\t\treturn &Ref{Ref: ref.Ref}, nil\n\t}\n\treturn ref.Value, nil\n}\n\nfunc NewParameters() Parameters {\n\treturn make(Parameters, 0, 4)\n}\n\nfunc (parameters Parameters) GetByInAndName(in string, name string) *Parameter {\n\tfor _, item := range parameters {\n\t\tif v := item.Value; v != nil {\n\t\t\tif v.Name == name && v.In == in {\n\t\t\t\treturn v\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Validate returns an error if Parameters does not comply with the OpenAPI spec.\nfunc (parameters Parameters) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tdupes := make(map[string]struct{})\n\tfor _, parameterRef := range parameters {\n\t\tif v := parameterRef.Value; v != nil {\n\t\t\tkey := v.In + \":\" + v.Name\n\t\t\tif _, ok := dupes[key]; ok {\n\t\t\t\treturn fmt.Errorf(\"more than one %q parameter has name %q\", v.In, v.Name)\n\t\t\t}\n\t\t\tdupes[key] = struct{}{}\n\t\t}\n\n\t\tif err := parameterRef.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Parameter is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#parameter-object\ntype Parameter struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tName            string     `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tIn              string     `json:\"in,omitempty\" yaml:\"in,omitempty\"`\n\tDescription     string     `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tStyle           string     `json:\"style,omitempty\" yaml:\"style,omitempty\"`\n\tExplode         *bool      `json:\"explode,omitempty\" yaml:\"explode,omitempty\"`\n\tAllowEmptyValue bool       `json:\"allowEmptyValue,omitempty\" yaml:\"allowEmptyValue,omitempty\"`\n\tAllowReserved   bool       `json:\"allowReserved,omitempty\" yaml:\"allowReserved,omitempty\"`\n\tDeprecated      bool       `json:\"deprecated,omitempty\" yaml:\"deprecated,omitempty\"`\n\tRequired        bool       `json:\"required,omitempty\" yaml:\"required,omitempty\"`\n\tSchema          *SchemaRef `json:\"schema,omitempty\" yaml:\"schema,omitempty\"`\n\tExample         any        `json:\"example,omitempty\" yaml:\"example,omitempty\"`\n\tExamples        Examples   `json:\"examples,omitempty\" yaml:\"examples,omitempty\"`\n\tContent         Content    `json:\"content,omitempty\" yaml:\"content,omitempty\"`\n}\n\nvar _ jsonpointer.JSONPointable = (*Parameter)(nil)\n\nconst (\n\tParameterInPath   = \"path\"\n\tParameterInQuery  = \"query\"\n\tParameterInHeader = \"header\"\n\tParameterInCookie = \"cookie\"\n)\n\nfunc NewPathParameter(name string) *Parameter {\n\treturn &Parameter{\n\t\tName:     name,\n\t\tIn:       ParameterInPath,\n\t\tRequired: true,\n\t}\n}\n\nfunc NewQueryParameter(name string) *Parameter {\n\treturn &Parameter{\n\t\tName: name,\n\t\tIn:   ParameterInQuery,\n\t}\n}\n\nfunc NewHeaderParameter(name string) *Parameter {\n\treturn &Parameter{\n\t\tName: name,\n\t\tIn:   ParameterInHeader,\n\t}\n}\n\nfunc NewCookieParameter(name string) *Parameter {\n\treturn &Parameter{\n\t\tName: name,\n\t\tIn:   ParameterInCookie,\n\t}\n}\n\nfunc (parameter *Parameter) WithDescription(value string) *Parameter {\n\tparameter.Description = value\n\treturn parameter\n}\n\nfunc (parameter *Parameter) WithRequired(value bool) *Parameter {\n\tparameter.Required = value\n\treturn parameter\n}\n\nfunc (parameter *Parameter) WithSchema(value *Schema) *Parameter {\n\tif value == nil {\n\t\tparameter.Schema = nil\n\t} else {\n\t\tparameter.Schema = &SchemaRef{\n\t\t\tValue: value,\n\t\t}\n\t}\n\treturn parameter\n}\n\n// MarshalJSON returns the JSON encoding of Parameter.\nfunc (parameter Parameter) MarshalJSON() ([]byte, error) {\n\tx, err := parameter.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Parameter.\nfunc (parameter Parameter) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 13+len(parameter.Extensions))\n\tfor k, v := range parameter.Extensions {\n\t\tm[k] = v\n\t}\n\n\tif x := parameter.Name; x != \"\" {\n\t\tm[\"name\"] = x\n\t}\n\tif x := parameter.In; x != \"\" {\n\t\tm[\"in\"] = x\n\t}\n\tif x := parameter.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := parameter.Style; x != \"\" {\n\t\tm[\"style\"] = x\n\t}\n\tif x := parameter.Explode; x != nil {\n\t\tm[\"explode\"] = x\n\t}\n\tif x := parameter.AllowEmptyValue; x {\n\t\tm[\"allowEmptyValue\"] = x\n\t}\n\tif x := parameter.AllowReserved; x {\n\t\tm[\"allowReserved\"] = x\n\t}\n\tif x := parameter.Deprecated; x {\n\t\tm[\"deprecated\"] = x\n\t}\n\tif x := parameter.Required; x {\n\t\tm[\"required\"] = x\n\t}\n\tif x := parameter.Schema; x != nil {\n\t\tm[\"schema\"] = x\n\t}\n\tif x := parameter.Example; x != nil {\n\t\tm[\"example\"] = x\n\t}\n\tif x := parameter.Examples; len(x) != 0 {\n\t\tm[\"examples\"] = x\n\t}\n\tif x := parameter.Content; len(x) != 0 {\n\t\tm[\"content\"] = x\n\t}\n\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Parameter to a copy of data.\nfunc (parameter *Parameter) UnmarshalJSON(data []byte) error {\n\ttype ParameterBis Parameter\n\tvar x ParameterBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"in\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"style\")\n\tdelete(x.Extensions, \"explode\")\n\tdelete(x.Extensions, \"allowEmptyValue\")\n\tdelete(x.Extensions, \"allowReserved\")\n\tdelete(x.Extensions, \"deprecated\")\n\tdelete(x.Extensions, \"required\")\n\tdelete(x.Extensions, \"schema\")\n\tdelete(x.Extensions, \"example\")\n\tdelete(x.Extensions, \"examples\")\n\tdelete(x.Extensions, \"content\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\n\t*parameter = Parameter(x)\n\treturn nil\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (parameter Parameter) JSONLookup(token string) (any, error) {\n\tswitch token {\n\tcase \"schema\":\n\t\tif parameter.Schema != nil {\n\t\t\tif parameter.Schema.Ref != \"\" {\n\t\t\t\treturn &Ref{Ref: parameter.Schema.Ref}, nil\n\t\t\t}\n\t\t\treturn parameter.Schema.Value, nil\n\t\t}\n\tcase \"name\":\n\t\treturn parameter.Name, nil\n\tcase \"in\":\n\t\treturn parameter.In, nil\n\tcase \"description\":\n\t\treturn parameter.Description, nil\n\tcase \"style\":\n\t\treturn parameter.Style, nil\n\tcase \"explode\":\n\t\treturn parameter.Explode, nil\n\tcase \"allowEmptyValue\":\n\t\treturn parameter.AllowEmptyValue, nil\n\tcase \"allowReserved\":\n\t\treturn parameter.AllowReserved, nil\n\tcase \"deprecated\":\n\t\treturn parameter.Deprecated, nil\n\tcase \"required\":\n\t\treturn parameter.Required, nil\n\tcase \"example\":\n\t\treturn parameter.Example, nil\n\tcase \"examples\":\n\t\treturn parameter.Examples, nil\n\tcase \"content\":\n\t\treturn parameter.Content, nil\n\t}\n\n\tv, _, err := jsonpointer.GetForToken(parameter.Extensions, token)\n\treturn v, err\n}\n\n// SerializationMethod returns a parameter's serialization method.\n// When a parameter's serialization method is not defined the method returns\n// the default serialization method corresponding to a parameter's location.\nfunc (parameter *Parameter) SerializationMethod() (*SerializationMethod, error) {\n\tswitch parameter.In {\n\tcase ParameterInPath, ParameterInHeader:\n\t\tstyle := parameter.Style\n\t\tif style == \"\" {\n\t\t\tstyle = SerializationSimple\n\t\t}\n\t\texplode := false\n\t\tif parameter.Explode != nil {\n\t\t\texplode = *parameter.Explode\n\t\t}\n\t\treturn &SerializationMethod{Style: style, Explode: explode}, nil\n\tcase ParameterInQuery, ParameterInCookie:\n\t\tstyle := parameter.Style\n\t\tif style == \"\" {\n\t\t\tstyle = SerializationForm\n\t\t}\n\t\texplode := true\n\t\tif parameter.Explode != nil {\n\t\t\texplode = *parameter.Explode\n\t\t}\n\t\treturn &SerializationMethod{Style: style, Explode: explode}, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unexpected parameter's 'in': %q\", parameter.In)\n\t}\n}\n\n// Validate returns an error if Parameter does not comply with the OpenAPI spec.\nfunc (parameter *Parameter) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif parameter.Name == \"\" {\n\t\treturn errors.New(\"parameter name can't be blank\")\n\t}\n\tin := parameter.In\n\tswitch in {\n\tcase\n\t\tParameterInPath,\n\t\tParameterInQuery,\n\t\tParameterInHeader,\n\t\tParameterInCookie:\n\tdefault:\n\t\treturn fmt.Errorf(\"parameter can't have 'in' value %q\", parameter.In)\n\t}\n\n\tif in == ParameterInPath && !parameter.Required {\n\t\treturn fmt.Errorf(\"path parameter %q must be required\", parameter.Name)\n\t}\n\n\t// Validate a parameter's serialization method.\n\tsm, err := parameter.SerializationMethod()\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar smSupported bool\n\tswitch {\n\tcase parameter.In == ParameterInPath && sm.Style == SerializationSimple && !sm.Explode,\n\t\tparameter.In == ParameterInPath && sm.Style == SerializationSimple && sm.Explode,\n\t\tparameter.In == ParameterInPath && sm.Style == SerializationLabel && !sm.Explode,\n\t\tparameter.In == ParameterInPath && sm.Style == SerializationLabel && sm.Explode,\n\t\tparameter.In == ParameterInPath && sm.Style == SerializationMatrix && !sm.Explode,\n\t\tparameter.In == ParameterInPath && sm.Style == SerializationMatrix && sm.Explode,\n\n\t\tparameter.In == ParameterInQuery && sm.Style == SerializationForm && sm.Explode,\n\t\tparameter.In == ParameterInQuery && sm.Style == SerializationForm && !sm.Explode,\n\t\tparameter.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && sm.Explode,\n\t\tparameter.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && !sm.Explode,\n\t\tparameter.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && sm.Explode,\n\t\tparameter.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && !sm.Explode,\n\t\tparameter.In == ParameterInQuery && sm.Style == SerializationDeepObject && sm.Explode,\n\n\t\tparameter.In == ParameterInHeader && sm.Style == SerializationSimple && !sm.Explode,\n\t\tparameter.In == ParameterInHeader && sm.Style == SerializationSimple && sm.Explode,\n\n\t\tparameter.In == ParameterInCookie && sm.Style == SerializationForm && !sm.Explode,\n\t\tparameter.In == ParameterInCookie && sm.Style == SerializationForm && sm.Explode:\n\t\tsmSupported = true\n\t}\n\tif !smSupported {\n\t\te := fmt.Errorf(\"serialization method with style=%q and explode=%v is not supported by a %s parameter\", sm.Style, sm.Explode, in)\n\t\treturn fmt.Errorf(\"parameter %q schema is invalid: %w\", parameter.Name, e)\n\t}\n\n\tif (parameter.Schema == nil) == (len(parameter.Content) == 0) {\n\t\te := errors.New(\"parameter must contain exactly one of content and schema\")\n\t\treturn fmt.Errorf(\"parameter %q schema is invalid: %w\", parameter.Name, e)\n\t}\n\n\tif content := parameter.Content; content != nil {\n\t\te := errors.New(\"parameter content must only contain one entry\")\n\t\tif len(content) > 1 {\n\t\t\treturn fmt.Errorf(\"parameter %q content is invalid: %w\", parameter.Name, e)\n\t\t}\n\n\t\tif err := content.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"parameter %q content is invalid: %w\", parameter.Name, err)\n\t\t}\n\t}\n\n\tif schema := parameter.Schema; schema != nil {\n\t\tif err := schema.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"parameter %q schema is invalid: %w\", parameter.Name, err)\n\t\t}\n\t\tif parameter.Example != nil && parameter.Examples != nil {\n\t\t\treturn fmt.Errorf(\"parameter %q example and examples are mutually exclusive\", parameter.Name)\n\t\t}\n\n\t\tif vo := getValidationOptions(ctx); vo.examplesValidationDisabled {\n\t\t\treturn nil\n\t\t}\n\t\tif example := parameter.Example; example != nil {\n\t\t\tif err := validateExampleValue(ctx, example, schema.Value); err != nil {\n\t\t\t\treturn fmt.Errorf(\"invalid example: %w\", err)\n\t\t\t}\n\t\t} else if examples := parameter.Examples; examples != nil {\n\t\t\tnames := make([]string, 0, len(examples))\n\t\t\tfor name := range examples {\n\t\t\t\tnames = append(names, name)\n\t\t\t}\n\t\t\tsort.Strings(names)\n\t\t\tfor _, k := range names {\n\t\t\t\tv := examples[k]\n\t\t\t\tif err := v.Validate(ctx); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"%s: %w\", k, err)\n\t\t\t\t}\n\t\t\t\tif err := validateExampleValue(ctx, v.Value.Value, schema.Value); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"%s: %w\", k, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, parameter.Extensions)\n}\n\n// UnmarshalJSON sets ParametersMap to a copy of data.\nfunc (parametersMap *ParametersMap) UnmarshalJSON(data []byte) (err error) {\n\t*parametersMap, _, err = unmarshalStringMapP[ParameterRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/path_item.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"sort\"\n)\n\n// PathItem is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#path-item-object\ntype PathItem struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tRef         string     `json:\"$ref,omitempty\" yaml:\"$ref,omitempty\"`\n\tSummary     string     `json:\"summary,omitempty\" yaml:\"summary,omitempty\"`\n\tDescription string     `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tConnect     *Operation `json:\"connect,omitempty\" yaml:\"connect,omitempty\"`\n\tDelete      *Operation `json:\"delete,omitempty\" yaml:\"delete,omitempty\"`\n\tGet         *Operation `json:\"get,omitempty\" yaml:\"get,omitempty\"`\n\tHead        *Operation `json:\"head,omitempty\" yaml:\"head,omitempty\"`\n\tOptions     *Operation `json:\"options,omitempty\" yaml:\"options,omitempty\"`\n\tPatch       *Operation `json:\"patch,omitempty\" yaml:\"patch,omitempty\"`\n\tPost        *Operation `json:\"post,omitempty\" yaml:\"post,omitempty\"`\n\tPut         *Operation `json:\"put,omitempty\" yaml:\"put,omitempty\"`\n\tTrace       *Operation `json:\"trace,omitempty\" yaml:\"trace,omitempty\"`\n\tServers     Servers    `json:\"servers,omitempty\" yaml:\"servers,omitempty\"`\n\tParameters  Parameters `json:\"parameters,omitempty\" yaml:\"parameters,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of PathItem.\nfunc (pathItem PathItem) MarshalJSON() ([]byte, error) {\n\tx, err := pathItem.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of PathItem.\nfunc (pathItem PathItem) MarshalYAML() (any, error) {\n\tif ref := pathItem.Ref; ref != \"\" {\n\t\treturn Ref{Ref: ref}, nil\n\t}\n\n\tm := make(map[string]any, 13+len(pathItem.Extensions))\n\tfor k, v := range pathItem.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := pathItem.Summary; x != \"\" {\n\t\tm[\"summary\"] = x\n\t}\n\tif x := pathItem.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := pathItem.Connect; x != nil {\n\t\tm[\"connect\"] = x\n\t}\n\tif x := pathItem.Delete; x != nil {\n\t\tm[\"delete\"] = x\n\t}\n\tif x := pathItem.Get; x != nil {\n\t\tm[\"get\"] = x\n\t}\n\tif x := pathItem.Head; x != nil {\n\t\tm[\"head\"] = x\n\t}\n\tif x := pathItem.Options; x != nil {\n\t\tm[\"options\"] = x\n\t}\n\tif x := pathItem.Patch; x != nil {\n\t\tm[\"patch\"] = x\n\t}\n\tif x := pathItem.Post; x != nil {\n\t\tm[\"post\"] = x\n\t}\n\tif x := pathItem.Put; x != nil {\n\t\tm[\"put\"] = x\n\t}\n\tif x := pathItem.Trace; x != nil {\n\t\tm[\"trace\"] = x\n\t}\n\tif x := pathItem.Servers; len(x) != 0 {\n\t\tm[\"servers\"] = x\n\t}\n\tif x := pathItem.Parameters; len(x) != 0 {\n\t\tm[\"parameters\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets PathItem to a copy of data.\nfunc (pathItem *PathItem) UnmarshalJSON(data []byte) error {\n\ttype PathItemBis PathItem\n\tvar x PathItemBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"$ref\")\n\tdelete(x.Extensions, \"summary\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"connect\")\n\tdelete(x.Extensions, \"delete\")\n\tdelete(x.Extensions, \"get\")\n\tdelete(x.Extensions, \"head\")\n\tdelete(x.Extensions, \"options\")\n\tdelete(x.Extensions, \"patch\")\n\tdelete(x.Extensions, \"post\")\n\tdelete(x.Extensions, \"put\")\n\tdelete(x.Extensions, \"trace\")\n\tdelete(x.Extensions, \"servers\")\n\tdelete(x.Extensions, \"parameters\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*pathItem = PathItem(x)\n\treturn nil\n}\n\nfunc (pathItem *PathItem) Operations() map[string]*Operation {\n\toperations := make(map[string]*Operation)\n\tif v := pathItem.Connect; v != nil {\n\t\toperations[http.MethodConnect] = v\n\t}\n\tif v := pathItem.Delete; v != nil {\n\t\toperations[http.MethodDelete] = v\n\t}\n\tif v := pathItem.Get; v != nil {\n\t\toperations[http.MethodGet] = v\n\t}\n\tif v := pathItem.Head; v != nil {\n\t\toperations[http.MethodHead] = v\n\t}\n\tif v := pathItem.Options; v != nil {\n\t\toperations[http.MethodOptions] = v\n\t}\n\tif v := pathItem.Patch; v != nil {\n\t\toperations[http.MethodPatch] = v\n\t}\n\tif v := pathItem.Post; v != nil {\n\t\toperations[http.MethodPost] = v\n\t}\n\tif v := pathItem.Put; v != nil {\n\t\toperations[http.MethodPut] = v\n\t}\n\tif v := pathItem.Trace; v != nil {\n\t\toperations[http.MethodTrace] = v\n\t}\n\treturn operations\n}\n\nfunc (pathItem *PathItem) GetOperation(method string) *Operation {\n\tswitch method {\n\tcase http.MethodConnect:\n\t\treturn pathItem.Connect\n\tcase http.MethodDelete:\n\t\treturn pathItem.Delete\n\tcase http.MethodGet:\n\t\treturn pathItem.Get\n\tcase http.MethodHead:\n\t\treturn pathItem.Head\n\tcase http.MethodOptions:\n\t\treturn pathItem.Options\n\tcase http.MethodPatch:\n\t\treturn pathItem.Patch\n\tcase http.MethodPost:\n\t\treturn pathItem.Post\n\tcase http.MethodPut:\n\t\treturn pathItem.Put\n\tcase http.MethodTrace:\n\t\treturn pathItem.Trace\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unsupported HTTP method %q\", method))\n\t}\n}\n\nfunc (pathItem *PathItem) SetOperation(method string, operation *Operation) {\n\tswitch method {\n\tcase http.MethodConnect:\n\t\tpathItem.Connect = operation\n\tcase http.MethodDelete:\n\t\tpathItem.Delete = operation\n\tcase http.MethodGet:\n\t\tpathItem.Get = operation\n\tcase http.MethodHead:\n\t\tpathItem.Head = operation\n\tcase http.MethodOptions:\n\t\tpathItem.Options = operation\n\tcase http.MethodPatch:\n\t\tpathItem.Patch = operation\n\tcase http.MethodPost:\n\t\tpathItem.Post = operation\n\tcase http.MethodPut:\n\t\tpathItem.Put = operation\n\tcase http.MethodTrace:\n\t\tpathItem.Trace = operation\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unsupported HTTP method %q\", method))\n\t}\n}\n\n// Validate returns an error if PathItem does not comply with the OpenAPI spec.\nfunc (pathItem *PathItem) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\toperations := pathItem.Operations()\n\n\tmethods := make([]string, 0, len(operations))\n\tfor method := range operations {\n\t\tmethods = append(methods, method)\n\t}\n\tsort.Strings(methods)\n\tfor _, method := range methods {\n\t\toperation := operations[method]\n\t\tif err := operation.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid operation %s: %v\", method, err)\n\t\t}\n\t}\n\n\tif v := pathItem.Parameters; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, pathItem.Extensions)\n}\n\n// isEmpty's introduced in 546590b1\nfunc (pathItem *PathItem) isEmpty() bool {\n\t// NOTE: ignores pathItem.Extensions\n\t// NOTE: ignores pathItem.Ref\n\treturn pathItem.Summary == \"\" &&\n\t\tpathItem.Description == \"\" &&\n\t\tpathItem.Connect == nil &&\n\t\tpathItem.Delete == nil &&\n\t\tpathItem.Get == nil &&\n\t\tpathItem.Head == nil &&\n\t\tpathItem.Options == nil &&\n\t\tpathItem.Patch == nil &&\n\t\tpathItem.Post == nil &&\n\t\tpathItem.Put == nil &&\n\t\tpathItem.Trace == nil &&\n\t\tlen(pathItem.Servers) == 0 &&\n\t\tlen(pathItem.Parameters) == 0\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/paths.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// Paths is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object\ntype Paths struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tm map[string]*PathItem\n}\n\n// NewPaths builds a paths object with path items in insertion order.\nfunc NewPaths(opts ...NewPathsOption) *Paths {\n\tpaths := NewPathsWithCapacity(len(opts))\n\tfor _, opt := range opts {\n\t\topt(paths)\n\t}\n\treturn paths\n}\n\n// NewPathsOption describes options to NewPaths func\ntype NewPathsOption func(*Paths)\n\n// WithPath adds a named path item\nfunc WithPath(path string, pathItem *PathItem) NewPathsOption {\n\treturn func(paths *Paths) {\n\t\tif p := pathItem; p != nil && path != \"\" {\n\t\t\tpaths.Set(path, p)\n\t\t}\n\t}\n}\n\n// Validate returns an error if Paths does not comply with the OpenAPI spec.\nfunc (paths *Paths) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tnormalizedPaths := make(map[string]string, paths.Len())\n\n\tkeys := make([]string, 0, paths.Len())\n\tfor key := range paths.Map() {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\tfor _, path := range keys {\n\t\tpathItem := paths.Value(path)\n\t\tif path == \"\" || path[0] != '/' {\n\t\t\treturn fmt.Errorf(\"path %q does not start with a forward slash (/)\", path)\n\t\t}\n\n\t\tif pathItem == nil {\n\t\t\tpathItem = &PathItem{}\n\t\t\tpaths.Set(path, pathItem)\n\t\t}\n\n\t\tnormalizedPath, _, varsInPath := normalizeTemplatedPath(path)\n\t\tif oldPath, ok := normalizedPaths[normalizedPath]; ok {\n\t\t\treturn fmt.Errorf(\"conflicting paths %q and %q\", path, oldPath)\n\t\t}\n\t\tnormalizedPaths[path] = path\n\n\t\tvar commonParams []string\n\t\tfor _, parameterRef := range pathItem.Parameters {\n\t\t\tif parameterRef != nil {\n\t\t\t\tif parameter := parameterRef.Value; parameter != nil && parameter.In == ParameterInPath {\n\t\t\t\t\tcommonParams = append(commonParams, parameter.Name)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\toperations := pathItem.Operations()\n\t\tmethods := make([]string, 0, len(operations))\n\t\tfor method := range operations {\n\t\t\tmethods = append(methods, method)\n\t\t}\n\t\tsort.Strings(methods)\n\t\tfor _, method := range methods {\n\t\t\toperation := operations[method]\n\t\t\tvar setParams []string\n\t\t\tfor _, parameterRef := range operation.Parameters {\n\t\t\t\tif parameterRef != nil {\n\t\t\t\t\tif parameter := parameterRef.Value; parameter != nil && parameter.In == ParameterInPath {\n\t\t\t\t\t\tsetParams = append(setParams, parameter.Name)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif expected := len(setParams) + len(commonParams); expected != len(varsInPath) {\n\t\t\t\texpected -= len(varsInPath)\n\t\t\t\tif expected < 0 {\n\t\t\t\t\texpected *= -1\n\t\t\t\t}\n\t\t\t\tmissing := make(map[string]struct{}, expected)\n\t\t\t\tdefinedParams := append(setParams, commonParams...)\n\t\t\t\tfor _, name := range definedParams {\n\t\t\t\t\tif _, ok := varsInPath[name]; !ok {\n\t\t\t\t\t\tmissing[name] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor name := range varsInPath {\n\t\t\t\t\tgot := false\n\t\t\t\t\tfor _, othername := range definedParams {\n\t\t\t\t\t\tif othername == name {\n\t\t\t\t\t\t\tgot = true\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif !got {\n\t\t\t\t\t\tmissing[name] = struct{}{}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif len(missing) != 0 {\n\t\t\t\t\tmissings := make([]string, 0, len(missing))\n\t\t\t\t\tfor name := range missing {\n\t\t\t\t\t\tmissings = append(missings, name)\n\t\t\t\t\t}\n\t\t\t\t\treturn fmt.Errorf(\"operation %s %s must define exactly all path parameters (missing: %v)\", method, path, missings)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif err := pathItem.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid path %s: %v\", path, err)\n\t\t}\n\t}\n\n\tif err := paths.validateUniqueOperationIDs(); err != nil {\n\t\treturn err\n\t}\n\n\treturn validateExtensions(ctx, paths.Extensions)\n}\n\n// InMatchingOrder returns paths in the order they are matched against URLs.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object\n// When matching URLs, concrete (non-templated) paths would be matched\n// before their templated counterparts.\nfunc (paths *Paths) InMatchingOrder() []string {\n\t// NOTE: sorting by number of variables ASC then by descending lexicographical\n\t// order seems to be a good heuristic.\n\tif paths.Len() == 0 {\n\t\treturn nil\n\t}\n\n\tvars := make(map[int][]string)\n\tmax := 0\n\tfor path := range paths.Map() {\n\t\tcount := strings.Count(path, \"}\")\n\t\tvars[count] = append(vars[count], path)\n\t\tif count > max {\n\t\t\tmax = count\n\t\t}\n\t}\n\n\tordered := make([]string, 0, paths.Len())\n\tfor c := 0; c <= max; c++ {\n\t\tif ps, ok := vars[c]; ok {\n\t\t\tsort.Sort(sort.Reverse(sort.StringSlice(ps)))\n\t\t\tordered = append(ordered, ps...)\n\t\t}\n\t}\n\treturn ordered\n}\n\n// Find returns a path that matches the key.\n//\n// The method ignores differences in template variable names (except possible \"*\" suffix).\n//\n// For example:\n//\n//\tpaths := openapi3.Paths {\n//\t  \"/person/{personName}\": &openapi3.PathItem{},\n//\t}\n//\tpathItem := path.Find(\"/person/{name}\")\n//\n// would return the correct path item.\nfunc (paths *Paths) Find(key string) *PathItem {\n\t// Try directly access the map\n\tpathItem := paths.Value(key)\n\tif pathItem != nil {\n\t\treturn pathItem\n\t}\n\n\tnormalizedPath, expected, _ := normalizeTemplatedPath(key)\n\tfor path, pathItem := range paths.Map() {\n\t\tpathNormalized, got, _ := normalizeTemplatedPath(path)\n\t\tif got == expected && pathNormalized == normalizedPath {\n\t\t\treturn pathItem\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (paths *Paths) validateUniqueOperationIDs() error {\n\toperationIDs := make(map[string]string)\n\tfor urlPath, pathItem := range paths.Map() {\n\t\tif pathItem == nil {\n\t\t\tcontinue\n\t\t}\n\t\tfor httpMethod, operation := range pathItem.Operations() {\n\t\t\tif operation == nil || operation.OperationID == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tendpoint := httpMethod + \" \" + urlPath\n\t\t\tif endpointDup, ok := operationIDs[operation.OperationID]; ok {\n\t\t\t\tif endpoint > endpointDup { // For make error message a bit more deterministic. May be useful for tests.\n\t\t\t\t\tendpoint, endpointDup = endpointDup, endpoint\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"operations %q and %q have the same operation id %q\",\n\t\t\t\t\tendpoint, endpointDup, operation.OperationID)\n\t\t\t}\n\t\t\toperationIDs[operation.OperationID] = endpoint\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc normalizeTemplatedPath(path string) (string, uint, map[string]struct{}) {\n\tif strings.IndexByte(path, '{') < 0 {\n\t\treturn path, 0, nil\n\t}\n\n\tvar buffTpl strings.Builder\n\tbuffTpl.Grow(len(path))\n\n\tvar (\n\t\tcc         rune\n\t\tcount      uint\n\t\tisVariable bool\n\t\tvars       = make(map[string]struct{})\n\t\tbuffVar    strings.Builder\n\t)\n\tfor i, c := range path {\n\t\tif isVariable {\n\t\t\tif c == '}' {\n\t\t\t\t// End path variable\n\t\t\t\tisVariable = false\n\n\t\t\t\tvars[buffVar.String()] = struct{}{}\n\t\t\t\tbuffVar = strings.Builder{}\n\n\t\t\t\t// First append possible '*' before this character\n\t\t\t\t// The character '}' will be appended\n\t\t\t\tif i > 0 && cc == '*' {\n\t\t\t\t\tbuffTpl.WriteRune(cc)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbuffVar.WriteRune(c)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t} else if c == '{' {\n\t\t\t// Begin path variable\n\t\t\tisVariable = true\n\n\t\t\t// The character '{' will be appended\n\t\t\tcount++\n\t\t}\n\n\t\t// Append the character\n\t\tbuffTpl.WriteRune(c)\n\t\tcc = c\n\t}\n\treturn buffTpl.String(), count, vars\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/ref.go",
    "content": "package openapi3\n\n//go:generate go run refsgenerator.go\n\n// Ref is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#reference-object\ntype Ref struct {\n\tRef    string  `json:\"$ref\" yaml:\"$ref\"`\n\tOrigin *Origin `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/refs.go",
    "content": "// Code generated by go generate; DO NOT EDIT.\npackage openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n\t\"github.com/perimeterx/marshmallow\"\n)\n\n// CallbackRef represents either a Callback or a $ref to a Callback.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype CallbackRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *Callback\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*CallbackRef)(nil)\n\nfunc (x *CallbackRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *CallbackRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *CallbackRef) CollectionName() string { return \"callbacks\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *CallbackRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *CallbackRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of CallbackRef.\nfunc (x CallbackRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of CallbackRef.\nfunc (x CallbackRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets CallbackRef to a copy of data.\nfunc (x *CallbackRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if CallbackRef does not comply with the OpenAPI spec.\nfunc (x *CallbackRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *CallbackRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// ExampleRef represents either a Example or a $ref to a Example.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype ExampleRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *Example\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*ExampleRef)(nil)\n\nfunc (x *ExampleRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *ExampleRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *ExampleRef) CollectionName() string { return \"examples\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *ExampleRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *ExampleRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of ExampleRef.\nfunc (x ExampleRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of ExampleRef.\nfunc (x ExampleRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets ExampleRef to a copy of data.\nfunc (x *ExampleRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if ExampleRef does not comply with the OpenAPI spec.\nfunc (x *ExampleRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *ExampleRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// HeaderRef represents either a Header or a $ref to a Header.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype HeaderRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *Header\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*HeaderRef)(nil)\n\nfunc (x *HeaderRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *HeaderRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *HeaderRef) CollectionName() string { return \"headers\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *HeaderRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *HeaderRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of HeaderRef.\nfunc (x HeaderRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of HeaderRef.\nfunc (x HeaderRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets HeaderRef to a copy of data.\nfunc (x *HeaderRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if HeaderRef does not comply with the OpenAPI spec.\nfunc (x *HeaderRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *HeaderRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// LinkRef represents either a Link or a $ref to a Link.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype LinkRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *Link\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*LinkRef)(nil)\n\nfunc (x *LinkRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *LinkRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *LinkRef) CollectionName() string { return \"links\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *LinkRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *LinkRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of LinkRef.\nfunc (x LinkRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of LinkRef.\nfunc (x LinkRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets LinkRef to a copy of data.\nfunc (x *LinkRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if LinkRef does not comply with the OpenAPI spec.\nfunc (x *LinkRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *LinkRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// ParameterRef represents either a Parameter or a $ref to a Parameter.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype ParameterRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *Parameter\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*ParameterRef)(nil)\n\nfunc (x *ParameterRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *ParameterRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *ParameterRef) CollectionName() string { return \"parameters\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *ParameterRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *ParameterRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of ParameterRef.\nfunc (x ParameterRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of ParameterRef.\nfunc (x ParameterRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets ParameterRef to a copy of data.\nfunc (x *ParameterRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if ParameterRef does not comply with the OpenAPI spec.\nfunc (x *ParameterRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *ParameterRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// RequestBodyRef represents either a RequestBody or a $ref to a RequestBody.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype RequestBodyRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *RequestBody\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil)\n\nfunc (x *RequestBodyRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *RequestBodyRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *RequestBodyRef) CollectionName() string { return \"requestBodies\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *RequestBodyRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *RequestBodyRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of RequestBodyRef.\nfunc (x RequestBodyRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of RequestBodyRef.\nfunc (x RequestBodyRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets RequestBodyRef to a copy of data.\nfunc (x *RequestBodyRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if RequestBodyRef does not comply with the OpenAPI spec.\nfunc (x *RequestBodyRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *RequestBodyRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// ResponseRef represents either a Response or a $ref to a Response.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype ResponseRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *Response\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*ResponseRef)(nil)\n\nfunc (x *ResponseRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *ResponseRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *ResponseRef) CollectionName() string { return \"responses\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *ResponseRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *ResponseRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of ResponseRef.\nfunc (x ResponseRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of ResponseRef.\nfunc (x ResponseRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets ResponseRef to a copy of data.\nfunc (x *ResponseRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if ResponseRef does not comply with the OpenAPI spec.\nfunc (x *ResponseRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *ResponseRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// SchemaRef represents either a Schema or a $ref to a Schema.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype SchemaRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *Schema\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*SchemaRef)(nil)\n\nfunc (x *SchemaRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *SchemaRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *SchemaRef) CollectionName() string { return \"schemas\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *SchemaRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *SchemaRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of SchemaRef.\nfunc (x SchemaRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of SchemaRef.\nfunc (x SchemaRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets SchemaRef to a copy of data.\nfunc (x *SchemaRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if SchemaRef does not comply with the OpenAPI spec.\nfunc (x *SchemaRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *SchemaRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n\n// SecuritySchemeRef represents either a SecurityScheme or a $ref to a SecurityScheme.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype SecuritySchemeRef struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *SecurityScheme\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*SecuritySchemeRef)(nil)\n\nfunc (x *SecuritySchemeRef) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *SecuritySchemeRef) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *SecuritySchemeRef) CollectionName() string { return \"securitySchemes\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *SecuritySchemeRef) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *SecuritySchemeRef) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of SecuritySchemeRef.\nfunc (x SecuritySchemeRef) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of SecuritySchemeRef.\nfunc (x SecuritySchemeRef) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets SecuritySchemeRef to a copy of data.\nfunc (x *SecuritySchemeRef) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if SecuritySchemeRef does not comply with the OpenAPI spec.\nfunc (x *SecuritySchemeRef) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *SecuritySchemeRef) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/refs.tmpl",
    "content": "// Code generated by go generate; DO NOT EDIT.\npackage {{ .Package }}\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n\t\"github.com/perimeterx/marshmallow\"\n)\n{{ range $type := .Types }}\n// {{ $type.Name }}Ref represents either a {{ $type.Name }} or a $ref to a {{ $type.Name }}.\n// When serializing and both fields are set, Ref is preferred over Value.\ntype {{ $type.Name }}Ref struct {\n\t// Extensions only captures fields starting with 'x-' as no other fields\n\t// are allowed by the openapi spec.\n\tExtensions map[string]any\n\tOrigin     *Origin\n\n\tRef   string\n\tValue *{{ $type.Name }}\n\textra []string\n\n\trefPath *url.URL\n}\n\nvar _ jsonpointer.JSONPointable = (*{{ $type.Name }}Ref)(nil)\n\nfunc (x *{{ $type.Name }}Ref) isEmpty() bool { return x == nil || x.Ref == \"\" && x.Value == nil }\n\n// RefString returns the $ref value.\nfunc (x *{{ $type.Name }}Ref) RefString() string { return x.Ref }\n\n// CollectionName returns the JSON string used for a collection of these components.\nfunc (x *{{ $type.Name }}Ref) CollectionName() string { return \"{{ $type.CollectionName }}\" }\n\n// RefPath returns the path of the $ref relative to the root document.\nfunc (x *{{ $type.Name }}Ref) RefPath() *url.URL { return copyURI(x.refPath) }\n\nfunc (x *{{ $type.Name }}Ref) setRefPath(u *url.URL) {\n\t// Once the refPath is set don't override. References can be loaded\n\t// multiple times not all with access to the correct path info.\n\tif x.refPath != nil {\n\t\treturn\n\t}\n\n\tx.refPath = copyURI(u)\n}\n\n// MarshalYAML returns the YAML encoding of {{ $type.Name }}Ref.\nfunc (x {{ $type.Name }}Ref) MarshalYAML() (any, error) {\n\tif ref := x.Ref; ref != \"\" {\n\t\treturn &Ref{Ref: ref}, nil\n\t}\n\treturn x.Value.MarshalYAML()\n}\n\n// MarshalJSON returns the JSON encoding of {{ $type.Name }}Ref.\nfunc (x {{ $type.Name }}Ref) MarshalJSON() ([]byte, error) {\n\ty, err := x.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(y)\n}\n\n// UnmarshalJSON sets {{ $type.Name }}Ref to a copy of data.\nfunc (x *{{ $type.Name }}Ref) UnmarshalJSON(data []byte) error {\n\tvar refOnly Ref\n\tif extra, err := marshmallow.Unmarshal(data, &refOnly, marshmallow.WithExcludeKnownFieldsFromMap(true)); err == nil && refOnly.Ref != \"\" {\n\t\tx.Ref = refOnly.Ref\n\t\tx.Origin = refOnly.Origin\n\t\tif len(extra) != 0 {\n\t\t\tx.extra = make([]string, 0, len(extra))\n\t\t\tfor key := range extra {\n\t\t\t\tx.extra = append(x.extra, key)\n\t\t\t}\n\t\t\tsort.Strings(x.extra)\n\t\t\tfor k := range extra {\n\t\t\t\tif !strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tdelete(extra, k)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(extra) != 0 {\n\t\t\t\tx.Extensions = extra\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn json.Unmarshal(data, &x.Value)\n}\n\n// Validate returns an error if {{ $type.Name }}Ref does not comply with the OpenAPI spec.\nfunc (x *{{ $type.Name }}Ref) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\texProhibited := getValidationOptions(ctx).schemaExtensionsInRefProhibited\n\tvar extras []string\n\tif extra := x.extra; len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor _, ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// extras in the Extensions checked below\n\t\t\tif _, ok := x.Extensions[ex]; !ok {\n\t\t\t\textras = append(extras, ex)\n\t\t\t}\n\t\t}\n\t}\n\n\tif extra := x.Extensions; exProhibited && len(extra) != 0 {\n\t\tallowed := getValidationOptions(ctx).extraSiblingFieldsAllowed\n\t\tfor ex := range extra {\n\t\t\tif allowed != nil {\n\t\t\t\tif _, ok := allowed[ex]; ok {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\textras = append(extras, ex)\n\t\t}\n\t}\n\n\tif len(extras) != 0 {\n\t\treturn fmt.Errorf(\"extra sibling fields: %+v\", extras)\n\t}\n\n\tif v := x.Value; v != nil {\n\t\treturn v.Validate(ctx)\n\t}\n\n\treturn foundUnresolvedRef(x.Ref)\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (x *{{ $type.Name }}Ref) JSONLookup(token string) (any, error) {\n\tif token == \"$ref\" {\n\t\treturn x.Ref, nil\n\t}\n\n\tif v, ok := x.Extensions[token]; ok {\n\t\treturn v, nil\n\t}\n\n\tptr, _, err := jsonpointer.GetForToken(x.Value, token)\n\treturn ptr, err\n}\n{{ end -}}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/refs_test.tmpl",
    "content": "// Code generated by go generate; DO NOT EDIT.\npackage {{ .Package }}\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n)\n{{ range $type := .Types }}\nfunc Test{{ $type.Name }}Ref_Extensions(t *testing.T) {\n\tdata := []byte(`{\"$ref\":\"#/components/schemas/Pet\",\"something\":\"integer\",\"x-order\":1}`)\n\n\tref := {{ $type.Name }}Ref{}\n\terr := json.Unmarshal(data, &ref)\n\tassert.NoError(t, err)\n\n\t// captures extension\n\tassert.Equal(t, \"#/components/schemas/Pet\", ref.Ref)\n\tassert.Equal(t, float64(1), ref.Extensions[\"x-order\"])\n\n\t// does not capture non-extensions\n\tassert.Nil(t, ref.Extensions[\"something\"])\n\n\t// validation\n\terr = ref.Validate(context.Background())\n\trequire.EqualError(t, err, \"extra sibling fields: [something]\")\n\n\terr = ref.Validate(context.Background(), ProhibitExtensionsWithRef())\n\trequire.EqualError(t, err, \"extra sibling fields: [something x-order]\")\n\n\terr = ref.Validate(context.Background(), AllowExtraSiblingFields(\"something\"))\n\tassert.ErrorContains(t, err, \"found unresolved ref\") // expected since value not defined\n\n\t// non-extension not json lookable\n\t_, err = ref.JSONLookup(\"something\")\n\tassert.Error(t, err)\n{{ if ne $type.Name \"Header\" }}\n\tt.Run(\"extentions in value\", func(t *testing.T) {\n\t\tref.Value = &{{ $type.Name }}{Extensions: map[string]any{}}\n\t\tref.Value.Extensions[\"x-order\"] = 2.0\n\n\t\t// prefers the value next to the \\$ref over the one in the \\$ref.\n\t\tv, err := ref.JSONLookup(\"x-order\")\n\t\tassert.NoError(t, err)\n\t\tassert.Equal(t, float64(1), v)\n\t})\n{{ else }}\n\t// Header does not have its own extensions.\n{{ end -}}\n}\n{{ end -}}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/request_body.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n)\n\n// RequestBody is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#request-body-object\ntype RequestBody struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tDescription string  `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tRequired    bool    `json:\"required,omitempty\" yaml:\"required,omitempty\"`\n\tContent     Content `json:\"content\" yaml:\"content\"`\n}\n\nfunc NewRequestBody() *RequestBody {\n\treturn &RequestBody{}\n}\n\nfunc (requestBody *RequestBody) WithDescription(value string) *RequestBody {\n\trequestBody.Description = value\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithRequired(value bool) *RequestBody {\n\trequestBody.Required = value\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithContent(content Content) *RequestBody {\n\trequestBody.Content = content\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithSchemaRef(value *SchemaRef, consumes []string) *RequestBody {\n\trequestBody.Content = NewContentWithSchemaRef(value, consumes)\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithSchema(value *Schema, consumes []string) *RequestBody {\n\trequestBody.Content = NewContentWithSchema(value, consumes)\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithJSONSchemaRef(value *SchemaRef) *RequestBody {\n\trequestBody.Content = NewContentWithJSONSchemaRef(value)\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithJSONSchema(value *Schema) *RequestBody {\n\trequestBody.Content = NewContentWithJSONSchema(value)\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithFormDataSchemaRef(value *SchemaRef) *RequestBody {\n\trequestBody.Content = NewContentWithFormDataSchemaRef(value)\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) WithFormDataSchema(value *Schema) *RequestBody {\n\trequestBody.Content = NewContentWithFormDataSchema(value)\n\treturn requestBody\n}\n\nfunc (requestBody *RequestBody) GetMediaType(mediaType string) *MediaType {\n\tm := requestBody.Content\n\tif m == nil {\n\t\treturn nil\n\t}\n\treturn m[mediaType]\n}\n\n// MarshalJSON returns the JSON encoding of RequestBody.\nfunc (requestBody RequestBody) MarshalJSON() ([]byte, error) {\n\tx, err := requestBody.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of RequestBody.\nfunc (requestBody RequestBody) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 3+len(requestBody.Extensions))\n\tfor k, v := range requestBody.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := requestBody.Description; x != \"\" {\n\t\tm[\"description\"] = requestBody.Description\n\t}\n\tif x := requestBody.Required; x {\n\t\tm[\"required\"] = x\n\t}\n\tif x := requestBody.Content; true {\n\t\tm[\"content\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets RequestBody to a copy of data.\nfunc (requestBody *RequestBody) UnmarshalJSON(data []byte) error {\n\ttype RequestBodyBis RequestBody\n\tvar x RequestBodyBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"required\")\n\tdelete(x.Extensions, \"content\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*requestBody = RequestBody(x)\n\treturn nil\n}\n\n// Validate returns an error if RequestBody does not comply with the OpenAPI spec.\nfunc (requestBody *RequestBody) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif requestBody.Content == nil {\n\t\treturn errors.New(\"content of the request body is required\")\n\t}\n\n\tif vo := getValidationOptions(ctx); !vo.examplesValidationDisabled {\n\t\tvo.examplesValidationAsReq, vo.examplesValidationAsRes = true, false\n\t}\n\n\tif err := requestBody.Content.Validate(ctx); err != nil {\n\t\treturn err\n\t}\n\n\treturn validateExtensions(ctx, requestBody.Extensions)\n}\n\n// UnmarshalJSON sets RequestBodies to a copy of data.\nfunc (requestBodies *RequestBodies) UnmarshalJSON(data []byte) (err error) {\n\t*requestBodies, _, err = unmarshalStringMapP[RequestBodyRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/response.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"sort\"\n\t\"strconv\"\n)\n\n// Responses is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#responses-object\ntype Responses struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"-\" yaml:\"-\"`\n\n\tm map[string]*ResponseRef\n}\n\n// NewResponses builds a responses object with response objects in insertion order.\n// Given no arguments, NewResponses returns a valid responses object containing a default match-all reponse.\nfunc NewResponses(opts ...NewResponsesOption) *Responses {\n\tif len(opts) == 0 {\n\t\treturn NewResponses(WithName(\"default\", NewResponse().WithDescription(\"\")))\n\t}\n\tresponses := NewResponsesWithCapacity(len(opts))\n\tfor _, opt := range opts {\n\t\topt(responses)\n\t}\n\treturn responses\n}\n\n// NewResponsesOption describes options to NewResponses func\ntype NewResponsesOption func(*Responses)\n\n// WithStatus adds a status code keyed ResponseRef\nfunc WithStatus(status int, responseRef *ResponseRef) NewResponsesOption {\n\treturn func(responses *Responses) {\n\t\tif r := responseRef; r != nil {\n\t\t\tcode := strconv.FormatInt(int64(status), 10)\n\t\t\tresponses.Set(code, r)\n\t\t}\n\t}\n}\n\n// WithName adds a name-keyed Response\nfunc WithName(name string, response *Response) NewResponsesOption {\n\treturn func(responses *Responses) {\n\t\tif r := response; r != nil && name != \"\" {\n\t\t\tresponses.Set(name, &ResponseRef{Value: r})\n\t\t}\n\t}\n}\n\n// Default returns the default response\nfunc (responses *Responses) Default() *ResponseRef {\n\treturn responses.Value(\"default\")\n}\n\n// Status returns a ResponseRef for the given status\n// If an exact match isn't initially found a patterned field is checked using\n// the first digit to determine the range (eg: 201 to 2XX)\n// See https://spec.openapis.org/oas/v3.0.3#patterned-fields-0\nfunc (responses *Responses) Status(status int) *ResponseRef {\n\tst := strconv.FormatInt(int64(status), 10)\n\tif rref := responses.Value(st); rref != nil {\n\t\treturn rref\n\t}\n\tif 99 < status && status < 600 {\n\t\tst = string(st[0]) + \"XX\"\n\t\tswitch st {\n\t\tcase \"1XX\", \"2XX\", \"3XX\", \"4XX\", \"5XX\":\n\t\t\treturn responses.Value(st)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Validate returns an error if Responses does not comply with the OpenAPI spec.\nfunc (responses *Responses) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif responses.Len() == 0 {\n\t\treturn errors.New(\"the responses object MUST contain at least one response code\")\n\t}\n\n\tkeys := make([]string, 0, responses.Len())\n\tfor key := range responses.Map() {\n\t\tkeys = append(keys, key)\n\t}\n\tsort.Strings(keys)\n\tfor _, key := range keys {\n\t\tv := responses.Value(key)\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, responses.Extensions)\n}\n\n// Response is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#response-object\ntype Response struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tDescription *string `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tHeaders     Headers `json:\"headers,omitempty\" yaml:\"headers,omitempty\"`\n\tContent     Content `json:\"content,omitempty\" yaml:\"content,omitempty\"`\n\tLinks       Links   `json:\"links,omitempty\" yaml:\"links,omitempty\"`\n}\n\nfunc NewResponse() *Response {\n\treturn &Response{}\n}\n\nfunc (response *Response) WithDescription(value string) *Response {\n\tresponse.Description = &value\n\treturn response\n}\n\nfunc (response *Response) WithContent(content Content) *Response {\n\tresponse.Content = content\n\treturn response\n}\n\nfunc (response *Response) WithJSONSchema(schema *Schema) *Response {\n\tresponse.Content = NewContentWithJSONSchema(schema)\n\treturn response\n}\n\nfunc (response *Response) WithJSONSchemaRef(schema *SchemaRef) *Response {\n\tresponse.Content = NewContentWithJSONSchemaRef(schema)\n\treturn response\n}\n\n// MarshalJSON returns the JSON encoding of Response.\nfunc (response Response) MarshalJSON() ([]byte, error) {\n\tx, err := response.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Response.\nfunc (response Response) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 4+len(response.Extensions))\n\tfor k, v := range response.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := response.Description; x != nil {\n\t\tm[\"description\"] = x\n\t}\n\tif x := response.Headers; len(x) != 0 {\n\t\tm[\"headers\"] = x\n\t}\n\tif x := response.Content; len(x) != 0 {\n\t\tm[\"content\"] = x\n\t}\n\tif x := response.Links; len(x) != 0 {\n\t\tm[\"links\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Response to a copy of data.\nfunc (response *Response) UnmarshalJSON(data []byte) error {\n\ttype ResponseBis Response\n\tvar x ResponseBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"headers\")\n\tdelete(x.Extensions, \"content\")\n\tdelete(x.Extensions, \"links\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*response = Response(x)\n\treturn nil\n}\n\n// Validate returns an error if Response does not comply with the OpenAPI spec.\nfunc (response *Response) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif response.Description == nil {\n\t\treturn errors.New(\"a short description of the response is required\")\n\t}\n\tif vo := getValidationOptions(ctx); !vo.examplesValidationDisabled {\n\t\tvo.examplesValidationAsReq, vo.examplesValidationAsRes = false, true\n\t}\n\n\tif content := response.Content; content != nil {\n\t\tif err := content.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\theaders := make([]string, 0, len(response.Headers))\n\tfor name := range response.Headers {\n\t\theaders = append(headers, name)\n\t}\n\tsort.Strings(headers)\n\tfor _, name := range headers {\n\t\theader := response.Headers[name]\n\t\tif err := header.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tlinks := make([]string, 0, len(response.Links))\n\tfor name := range response.Links {\n\t\tlinks = append(links, name)\n\t}\n\tsort.Strings(links)\n\tfor _, name := range links {\n\t\tlink := response.Links[name]\n\t\tif err := link.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, response.Extensions)\n}\n\n// UnmarshalJSON sets ResponseBodies to a copy of data.\nfunc (responseBodies *ResponseBodies) UnmarshalJSON(data []byte) (err error) {\n\t*responseBodies, _, err = unmarshalStringMapP[ResponseRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/schema.go",
    "content": "package openapi3\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode/utf16\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n\t\"github.com/mohae/deepcopy\"\n)\n\nconst (\n\tTypeArray   = \"array\"\n\tTypeBoolean = \"boolean\"\n\tTypeInteger = \"integer\"\n\tTypeNumber  = \"number\"\n\tTypeObject  = \"object\"\n\tTypeString  = \"string\"\n\tTypeNull    = \"null\"\n)\n\nvar (\n\t// SchemaErrorDetailsDisabled disables printing of details about schema errors.\n\tSchemaErrorDetailsDisabled = false\n\n\terrSchema = errors.New(\"input does not match the schema\")\n\n\t// ErrOneOfConflict is the SchemaError Origin when data matches more than one oneOf schema\n\tErrOneOfConflict = errors.New(\"input matches more than one oneOf schemas\")\n\n\t// ErrSchemaInputNaN may be returned when validating a number\n\tErrSchemaInputNaN = errors.New(\"floating point NaN is not allowed\")\n\t// ErrSchemaInputInf may be returned when validating a number\n\tErrSchemaInputInf = errors.New(\"floating point Inf is not allowed\")\n\n\tcompiledPatterns sync.Map\n)\n\n// NewSchemaRef simply builds a SchemaRef\nfunc NewSchemaRef(ref string, value *Schema) *SchemaRef {\n\treturn &SchemaRef{\n\t\tRef:   ref,\n\t\tValue: value,\n\t}\n}\n\ntype SchemaRefs []*SchemaRef\n\nvar _ jsonpointer.JSONPointable = (*SchemaRefs)(nil)\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (s SchemaRefs) JSONLookup(token string) (any, error) {\n\ti, err := strconv.ParseUint(token, 10, 64)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif i >= uint64(len(s)) {\n\t\treturn nil, fmt.Errorf(\"index out of range: %d\", i)\n\t}\n\n\tref := s[i]\n\n\tif ref == nil || ref.Ref != \"\" {\n\t\treturn &Ref{Ref: ref.Ref}, nil\n\t}\n\treturn ref.Value, nil\n}\n\n// Schema is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schema-object\ntype Schema struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tOneOf        SchemaRefs    `json:\"oneOf,omitempty\" yaml:\"oneOf,omitempty\"`\n\tAnyOf        SchemaRefs    `json:\"anyOf,omitempty\" yaml:\"anyOf,omitempty\"`\n\tAllOf        SchemaRefs    `json:\"allOf,omitempty\" yaml:\"allOf,omitempty\"`\n\tNot          *SchemaRef    `json:\"not,omitempty\" yaml:\"not,omitempty\"`\n\tType         *Types        `json:\"type,omitempty\" yaml:\"type,omitempty\"`\n\tTitle        string        `json:\"title,omitempty\" yaml:\"title,omitempty\"`\n\tFormat       string        `json:\"format,omitempty\" yaml:\"format,omitempty\"`\n\tDescription  string        `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tEnum         []any         `json:\"enum,omitempty\" yaml:\"enum,omitempty\"`\n\tDefault      any           `json:\"default,omitempty\" yaml:\"default,omitempty\"`\n\tExample      any           `json:\"example,omitempty\" yaml:\"example,omitempty\"`\n\tExternalDocs *ExternalDocs `json:\"externalDocs,omitempty\" yaml:\"externalDocs,omitempty\"`\n\n\t// Array-related, here for struct compactness\n\tUniqueItems bool `json:\"uniqueItems,omitempty\" yaml:\"uniqueItems,omitempty\"`\n\t// Number-related, here for struct compactness\n\tExclusiveMin bool `json:\"exclusiveMinimum,omitempty\" yaml:\"exclusiveMinimum,omitempty\"`\n\tExclusiveMax bool `json:\"exclusiveMaximum,omitempty\" yaml:\"exclusiveMaximum,omitempty\"`\n\t// Properties\n\tNullable        bool `json:\"nullable,omitempty\" yaml:\"nullable,omitempty\"`\n\tReadOnly        bool `json:\"readOnly,omitempty\" yaml:\"readOnly,omitempty\"`\n\tWriteOnly       bool `json:\"writeOnly,omitempty\" yaml:\"writeOnly,omitempty\"`\n\tAllowEmptyValue bool `json:\"allowEmptyValue,omitempty\" yaml:\"allowEmptyValue,omitempty\"`\n\tDeprecated      bool `json:\"deprecated,omitempty\" yaml:\"deprecated,omitempty\"`\n\tXML             *XML `json:\"xml,omitempty\" yaml:\"xml,omitempty\"`\n\n\t// Number\n\tMin        *float64 `json:\"minimum,omitempty\" yaml:\"minimum,omitempty\"`\n\tMax        *float64 `json:\"maximum,omitempty\" yaml:\"maximum,omitempty\"`\n\tMultipleOf *float64 `json:\"multipleOf,omitempty\" yaml:\"multipleOf,omitempty\"`\n\n\t// String\n\tMinLength uint64  `json:\"minLength,omitempty\" yaml:\"minLength,omitempty\"`\n\tMaxLength *uint64 `json:\"maxLength,omitempty\" yaml:\"maxLength,omitempty\"`\n\tPattern   string  `json:\"pattern,omitempty\" yaml:\"pattern,omitempty\"`\n\n\t// Array\n\tMinItems uint64     `json:\"minItems,omitempty\" yaml:\"minItems,omitempty\"`\n\tMaxItems *uint64    `json:\"maxItems,omitempty\" yaml:\"maxItems,omitempty\"`\n\tItems    *SchemaRef `json:\"items,omitempty\" yaml:\"items,omitempty\"`\n\n\t// Object\n\tRequired             []string             `json:\"required,omitempty\" yaml:\"required,omitempty\"`\n\tProperties           Schemas              `json:\"properties,omitempty\" yaml:\"properties,omitempty\"`\n\tMinProps             uint64               `json:\"minProperties,omitempty\" yaml:\"minProperties,omitempty\"`\n\tMaxProps             *uint64              `json:\"maxProperties,omitempty\" yaml:\"maxProperties,omitempty\"`\n\tAdditionalProperties AdditionalProperties `json:\"additionalProperties,omitempty\" yaml:\"additionalProperties,omitempty\"`\n\tDiscriminator        *Discriminator       `json:\"discriminator,omitempty\" yaml:\"discriminator,omitempty\"`\n}\n\ntype Types []string\n\nfunc (types *Types) Is(typ string) bool {\n\treturn types != nil && len(*types) == 1 && (*types)[0] == typ\n}\n\nfunc (types *Types) Slice() []string {\n\tif types == nil {\n\t\treturn nil\n\t}\n\treturn *types\n}\n\nfunc (pTypes *Types) Includes(typ string) bool {\n\tif pTypes == nil {\n\t\treturn false\n\t}\n\ttypes := *pTypes\n\tfor _, candidate := range types {\n\t\tif candidate == typ {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (types *Types) Permits(typ string) bool {\n\tif types == nil {\n\t\treturn true\n\t}\n\treturn types.Includes(typ)\n}\n\nfunc (pTypes *Types) MarshalJSON() ([]byte, error) {\n\tx, err := pTypes.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\nfunc (pTypes *Types) MarshalYAML() (any, error) {\n\tif pTypes == nil {\n\t\treturn nil, nil\n\t}\n\ttypes := *pTypes\n\tswitch len(types) {\n\tcase 0:\n\t\treturn nil, nil\n\tcase 1:\n\t\treturn types[0], nil\n\tdefault:\n\t\treturn []string(types), nil\n\t}\n}\n\nfunc (types *Types) UnmarshalJSON(data []byte) error {\n\tvar strings []string\n\tif err := json.Unmarshal(data, &strings); err != nil {\n\t\tvar s string\n\t\tif err := json.Unmarshal(data, &s); err != nil {\n\t\t\treturn unmarshalError(err)\n\t\t}\n\t\tstrings = []string{s}\n\t}\n\t*types = strings\n\treturn nil\n}\n\ntype AdditionalProperties struct {\n\tHas    *bool\n\tSchema *SchemaRef\n}\n\n// MarshalYAML returns the YAML encoding of AdditionalProperties.\nfunc (addProps AdditionalProperties) MarshalYAML() (any, error) {\n\tif x := addProps.Has; x != nil {\n\t\tif *x {\n\t\t\treturn true, nil\n\t\t}\n\t\treturn false, nil\n\t}\n\tif x := addProps.Schema; x != nil {\n\t\treturn x.MarshalYAML()\n\t}\n\treturn nil, nil\n}\n\n// MarshalJSON returns the JSON encoding of AdditionalProperties.\nfunc (addProps AdditionalProperties) MarshalJSON() ([]byte, error) {\n\tx, err := addProps.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// UnmarshalJSON sets AdditionalProperties to a copy of data.\nfunc (addProps *AdditionalProperties) UnmarshalJSON(data []byte) error {\n\tvar x any\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\tswitch y := x.(type) {\n\tcase nil:\n\tcase bool:\n\t\taddProps.Has = &y\n\tcase map[string]any:\n\t\tif len(y) == 0 {\n\t\t\taddProps.Schema = &SchemaRef{Value: &Schema{}}\n\t\t} else {\n\t\t\tbuf := new(bytes.Buffer)\n\t\t\tjson.NewEncoder(buf).Encode(y)\n\t\t\tif err := json.NewDecoder(buf).Decode(&addProps.Schema); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tdefault:\n\t\treturn errors.New(\"cannot unmarshal additionalProperties: value must be either a schema object or a boolean\")\n\t}\n\treturn nil\n}\n\nvar _ jsonpointer.JSONPointable = (*Schema)(nil)\n\nfunc NewSchema() *Schema {\n\treturn &Schema{}\n}\n\n// MarshalJSON returns the JSON encoding of Schema.\nfunc (schema Schema) MarshalJSON() ([]byte, error) {\n\tm, err := schema.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn json.Marshal(m)\n}\n\n// MarshalYAML returns the YAML encoding of Schema.\nfunc (schema Schema) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 36+len(schema.Extensions))\n\tfor k, v := range schema.Extensions {\n\t\tm[k] = v\n\t}\n\n\tif x := schema.OneOf; len(x) != 0 {\n\t\tm[\"oneOf\"] = x\n\t}\n\tif x := schema.AnyOf; len(x) != 0 {\n\t\tm[\"anyOf\"] = x\n\t}\n\tif x := schema.AllOf; len(x) != 0 {\n\t\tm[\"allOf\"] = x\n\t}\n\tif x := schema.Not; x != nil {\n\t\tm[\"not\"] = x\n\t}\n\tif x := schema.Type; x != nil {\n\t\tm[\"type\"] = x\n\t}\n\tif x := schema.Title; len(x) != 0 {\n\t\tm[\"title\"] = x\n\t}\n\tif x := schema.Format; len(x) != 0 {\n\t\tm[\"format\"] = x\n\t}\n\tif x := schema.Description; len(x) != 0 {\n\t\tm[\"description\"] = x\n\t}\n\tif x := schema.Enum; len(x) != 0 {\n\t\tm[\"enum\"] = x\n\t}\n\tif x := schema.Default; x != nil {\n\t\tm[\"default\"] = x\n\t}\n\tif x := schema.Example; x != nil {\n\t\tm[\"example\"] = x\n\t}\n\tif x := schema.ExternalDocs; x != nil {\n\t\tm[\"externalDocs\"] = x\n\t}\n\n\t// Array-related\n\tif x := schema.UniqueItems; x {\n\t\tm[\"uniqueItems\"] = x\n\t}\n\t// Number-related\n\tif x := schema.ExclusiveMin; x {\n\t\tm[\"exclusiveMinimum\"] = x\n\t}\n\tif x := schema.ExclusiveMax; x {\n\t\tm[\"exclusiveMaximum\"] = x\n\t}\n\t// Properties\n\tif x := schema.Nullable; x {\n\t\tm[\"nullable\"] = x\n\t}\n\tif x := schema.ReadOnly; x {\n\t\tm[\"readOnly\"] = x\n\t}\n\tif x := schema.WriteOnly; x {\n\t\tm[\"writeOnly\"] = x\n\t}\n\tif x := schema.AllowEmptyValue; x {\n\t\tm[\"allowEmptyValue\"] = x\n\t}\n\tif x := schema.Deprecated; x {\n\t\tm[\"deprecated\"] = x\n\t}\n\tif x := schema.XML; x != nil {\n\t\tm[\"xml\"] = x\n\t}\n\n\t// Number\n\tif x := schema.Min; x != nil {\n\t\tm[\"minimum\"] = x\n\t}\n\tif x := schema.Max; x != nil {\n\t\tm[\"maximum\"] = x\n\t}\n\tif x := schema.MultipleOf; x != nil {\n\t\tm[\"multipleOf\"] = x\n\t}\n\n\t// String\n\tif x := schema.MinLength; x != 0 {\n\t\tm[\"minLength\"] = x\n\t}\n\tif x := schema.MaxLength; x != nil {\n\t\tm[\"maxLength\"] = x\n\t}\n\tif x := schema.Pattern; x != \"\" {\n\t\tm[\"pattern\"] = x\n\t}\n\n\t// Array\n\tif x := schema.MinItems; x != 0 {\n\t\tm[\"minItems\"] = x\n\t}\n\tif x := schema.MaxItems; x != nil {\n\t\tm[\"maxItems\"] = x\n\t}\n\tif x := schema.Items; x != nil {\n\t\tm[\"items\"] = x\n\t}\n\n\t// Object\n\tif x := schema.Required; len(x) != 0 {\n\t\tm[\"required\"] = x\n\t}\n\tif x := schema.Properties; len(x) != 0 {\n\t\tm[\"properties\"] = x\n\t}\n\tif x := schema.MinProps; x != 0 {\n\t\tm[\"minProperties\"] = x\n\t}\n\tif x := schema.MaxProps; x != nil {\n\t\tm[\"maxProperties\"] = x\n\t}\n\tif x := schema.AdditionalProperties; x.Has != nil || x.Schema != nil {\n\t\tm[\"additionalProperties\"] = &x\n\t}\n\tif x := schema.Discriminator; x != nil {\n\t\tm[\"discriminator\"] = x\n\t}\n\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Schema to a copy of data.\nfunc (schema *Schema) UnmarshalJSON(data []byte) error {\n\ttype SchemaBis Schema\n\tvar x SchemaBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"oneOf\")\n\tdelete(x.Extensions, \"anyOf\")\n\tdelete(x.Extensions, \"allOf\")\n\tdelete(x.Extensions, \"not\")\n\tdelete(x.Extensions, \"type\")\n\tdelete(x.Extensions, \"title\")\n\tdelete(x.Extensions, \"format\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"enum\")\n\tdelete(x.Extensions, \"default\")\n\tdelete(x.Extensions, \"example\")\n\tdelete(x.Extensions, \"externalDocs\")\n\n\t// Array-related\n\tdelete(x.Extensions, \"uniqueItems\")\n\t// Number-related\n\tdelete(x.Extensions, \"exclusiveMinimum\")\n\tdelete(x.Extensions, \"exclusiveMaximum\")\n\t// Properties\n\tdelete(x.Extensions, \"nullable\")\n\tdelete(x.Extensions, \"readOnly\")\n\tdelete(x.Extensions, \"writeOnly\")\n\tdelete(x.Extensions, \"allowEmptyValue\")\n\tdelete(x.Extensions, \"deprecated\")\n\tdelete(x.Extensions, \"xml\")\n\n\t// Number\n\tdelete(x.Extensions, \"minimum\")\n\tdelete(x.Extensions, \"maximum\")\n\tdelete(x.Extensions, \"multipleOf\")\n\n\t// String\n\tdelete(x.Extensions, \"minLength\")\n\tdelete(x.Extensions, \"maxLength\")\n\tdelete(x.Extensions, \"pattern\")\n\n\t// Array\n\tdelete(x.Extensions, \"minItems\")\n\tdelete(x.Extensions, \"maxItems\")\n\tdelete(x.Extensions, \"items\")\n\n\t// Object\n\tdelete(x.Extensions, \"required\")\n\tdelete(x.Extensions, \"properties\")\n\tdelete(x.Extensions, \"minProperties\")\n\tdelete(x.Extensions, \"maxProperties\")\n\tdelete(x.Extensions, \"additionalProperties\")\n\tdelete(x.Extensions, \"discriminator\")\n\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\n\t*schema = Schema(x)\n\n\tif schema.Format == \"date\" {\n\t\t// This is a fix for: https://github.com/getkin/kin-openapi/issues/697\n\t\tif eg, ok := schema.Example.(string); ok {\n\t\t\tschema.Example = strings.TrimSuffix(eg, \"T00:00:00Z\")\n\t\t}\n\t}\n\treturn nil\n}\n\n// JSONLookup implements https://pkg.go.dev/github.com/go-openapi/jsonpointer#JSONPointable\nfunc (schema Schema) JSONLookup(token string) (any, error) {\n\tswitch token {\n\tcase \"additionalProperties\":\n\t\tif addProps := schema.AdditionalProperties.Has; addProps != nil {\n\t\t\treturn *addProps, nil\n\t\t}\n\t\tif addProps := schema.AdditionalProperties.Schema; addProps != nil {\n\t\t\tif addProps.Ref != \"\" {\n\t\t\t\treturn &Ref{Ref: addProps.Ref}, nil\n\t\t\t}\n\t\t\treturn addProps.Value, nil\n\t\t}\n\tcase \"not\":\n\t\tif schema.Not != nil {\n\t\t\tif schema.Not.Ref != \"\" {\n\t\t\t\treturn &Ref{Ref: schema.Not.Ref}, nil\n\t\t\t}\n\t\t\treturn schema.Not.Value, nil\n\t\t}\n\tcase \"items\":\n\t\tif schema.Items != nil {\n\t\t\tif schema.Items.Ref != \"\" {\n\t\t\t\treturn &Ref{Ref: schema.Items.Ref}, nil\n\t\t\t}\n\t\t\treturn schema.Items.Value, nil\n\t\t}\n\tcase \"oneOf\":\n\t\treturn schema.OneOf, nil\n\tcase \"anyOf\":\n\t\treturn schema.AnyOf, nil\n\tcase \"allOf\":\n\t\treturn schema.AllOf, nil\n\tcase \"type\":\n\t\treturn schema.Type, nil\n\tcase \"title\":\n\t\treturn schema.Title, nil\n\tcase \"format\":\n\t\treturn schema.Format, nil\n\tcase \"description\":\n\t\treturn schema.Description, nil\n\tcase \"enum\":\n\t\treturn schema.Enum, nil\n\tcase \"default\":\n\t\treturn schema.Default, nil\n\tcase \"example\":\n\t\treturn schema.Example, nil\n\tcase \"externalDocs\":\n\t\treturn schema.ExternalDocs, nil\n\tcase \"uniqueItems\":\n\t\treturn schema.UniqueItems, nil\n\tcase \"exclusiveMin\":\n\t\treturn schema.ExclusiveMin, nil\n\tcase \"exclusiveMax\":\n\t\treturn schema.ExclusiveMax, nil\n\tcase \"nullable\":\n\t\treturn schema.Nullable, nil\n\tcase \"readOnly\":\n\t\treturn schema.ReadOnly, nil\n\tcase \"writeOnly\":\n\t\treturn schema.WriteOnly, nil\n\tcase \"allowEmptyValue\":\n\t\treturn schema.AllowEmptyValue, nil\n\tcase \"xml\":\n\t\treturn schema.XML, nil\n\tcase \"deprecated\":\n\t\treturn schema.Deprecated, nil\n\tcase \"min\":\n\t\treturn schema.Min, nil\n\tcase \"max\":\n\t\treturn schema.Max, nil\n\tcase \"multipleOf\":\n\t\treturn schema.MultipleOf, nil\n\tcase \"minLength\":\n\t\treturn schema.MinLength, nil\n\tcase \"maxLength\":\n\t\treturn schema.MaxLength, nil\n\tcase \"pattern\":\n\t\treturn schema.Pattern, nil\n\tcase \"minItems\":\n\t\treturn schema.MinItems, nil\n\tcase \"maxItems\":\n\t\treturn schema.MaxItems, nil\n\tcase \"required\":\n\t\treturn schema.Required, nil\n\tcase \"properties\":\n\t\treturn schema.Properties, nil\n\tcase \"minProps\":\n\t\treturn schema.MinProps, nil\n\tcase \"maxProps\":\n\t\treturn schema.MaxProps, nil\n\tcase \"discriminator\":\n\t\treturn schema.Discriminator, nil\n\t}\n\n\tv, _, err := jsonpointer.GetForToken(schema.Extensions, token)\n\treturn v, err\n}\n\nfunc (schema *Schema) NewRef() *SchemaRef {\n\treturn &SchemaRef{\n\t\tValue: schema,\n\t}\n}\n\nfunc NewOneOfSchema(schemas ...*Schema) *Schema {\n\trefs := make([]*SchemaRef, 0, len(schemas))\n\tfor _, schema := range schemas {\n\t\trefs = append(refs, &SchemaRef{Value: schema})\n\t}\n\treturn &Schema{\n\t\tOneOf: refs,\n\t}\n}\n\nfunc NewAnyOfSchema(schemas ...*Schema) *Schema {\n\trefs := make([]*SchemaRef, 0, len(schemas))\n\tfor _, schema := range schemas {\n\t\trefs = append(refs, &SchemaRef{Value: schema})\n\t}\n\treturn &Schema{\n\t\tAnyOf: refs,\n\t}\n}\n\nfunc NewAllOfSchema(schemas ...*Schema) *Schema {\n\trefs := make([]*SchemaRef, 0, len(schemas))\n\tfor _, schema := range schemas {\n\t\trefs = append(refs, &SchemaRef{Value: schema})\n\t}\n\treturn &Schema{\n\t\tAllOf: refs,\n\t}\n}\n\nfunc NewBoolSchema() *Schema {\n\treturn &Schema{\n\t\tType: &Types{TypeBoolean},\n\t}\n}\n\nfunc NewFloat64Schema() *Schema {\n\treturn &Schema{\n\t\tType: &Types{TypeNumber},\n\t}\n}\n\nfunc NewIntegerSchema() *Schema {\n\treturn &Schema{\n\t\tType: &Types{TypeInteger},\n\t}\n}\n\nfunc NewInt32Schema() *Schema {\n\treturn &Schema{\n\t\tType:   &Types{TypeInteger},\n\t\tFormat: \"int32\",\n\t}\n}\n\nfunc NewInt64Schema() *Schema {\n\treturn &Schema{\n\t\tType:   &Types{TypeInteger},\n\t\tFormat: \"int64\",\n\t}\n}\n\nfunc NewStringSchema() *Schema {\n\treturn &Schema{\n\t\tType: &Types{TypeString},\n\t}\n}\n\nfunc NewDateTimeSchema() *Schema {\n\treturn &Schema{\n\t\tType:   &Types{TypeString},\n\t\tFormat: \"date-time\",\n\t}\n}\n\nfunc NewUUIDSchema() *Schema {\n\treturn &Schema{\n\t\tType:   &Types{TypeString},\n\t\tFormat: \"uuid\",\n\t}\n}\n\nfunc NewBytesSchema() *Schema {\n\treturn &Schema{\n\t\tType:   &Types{TypeString},\n\t\tFormat: \"byte\",\n\t}\n}\n\nfunc NewArraySchema() *Schema {\n\treturn &Schema{\n\t\tType: &Types{TypeArray},\n\t}\n}\n\nfunc NewObjectSchema() *Schema {\n\treturn &Schema{\n\t\tType:       &Types{TypeObject},\n\t\tProperties: make(Schemas),\n\t}\n}\n\nfunc (schema *Schema) WithNullable() *Schema {\n\tschema.Nullable = true\n\treturn schema\n}\n\nfunc (schema *Schema) WithMin(value float64) *Schema {\n\tschema.Min = &value\n\treturn schema\n}\n\nfunc (schema *Schema) WithMax(value float64) *Schema {\n\tschema.Max = &value\n\treturn schema\n}\n\nfunc (schema *Schema) WithExclusiveMin(value bool) *Schema {\n\tschema.ExclusiveMin = value\n\treturn schema\n}\n\nfunc (schema *Schema) WithExclusiveMax(value bool) *Schema {\n\tschema.ExclusiveMax = value\n\treturn schema\n}\n\nfunc (schema *Schema) WithEnum(values ...any) *Schema {\n\tschema.Enum = values\n\treturn schema\n}\n\nfunc (schema *Schema) WithDefault(defaultValue any) *Schema {\n\tschema.Default = defaultValue\n\treturn schema\n}\n\nfunc (schema *Schema) WithFormat(value string) *Schema {\n\tschema.Format = value\n\treturn schema\n}\n\nfunc (schema *Schema) WithLength(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MinLength = n\n\tschema.MaxLength = &n\n\treturn schema\n}\n\nfunc (schema *Schema) WithMinLength(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MinLength = n\n\treturn schema\n}\n\nfunc (schema *Schema) WithMaxLength(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MaxLength = &n\n\treturn schema\n}\n\nfunc (schema *Schema) WithLengthDecodedBase64(i int64) *Schema {\n\tn := uint64(i)\n\tv := (n*8 + 5) / 6\n\tschema.MinLength = v\n\tschema.MaxLength = &v\n\treturn schema\n}\n\nfunc (schema *Schema) WithMinLengthDecodedBase64(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MinLength = (n*8 + 5) / 6\n\treturn schema\n}\n\nfunc (schema *Schema) WithMaxLengthDecodedBase64(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MinLength = (n*8 + 5) / 6\n\treturn schema\n}\n\nfunc (schema *Schema) WithPattern(pattern string) *Schema {\n\tschema.Pattern = pattern\n\treturn schema\n}\n\nfunc (schema *Schema) WithItems(value *Schema) *Schema {\n\tschema.Items = &SchemaRef{\n\t\tValue: value,\n\t}\n\treturn schema\n}\n\nfunc (schema *Schema) WithMinItems(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MinItems = n\n\treturn schema\n}\n\nfunc (schema *Schema) WithMaxItems(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MaxItems = &n\n\treturn schema\n}\n\nfunc (schema *Schema) WithUniqueItems(unique bool) *Schema {\n\tschema.UniqueItems = unique\n\treturn schema\n}\n\nfunc (schema *Schema) WithProperty(name string, propertySchema *Schema) *Schema {\n\treturn schema.WithPropertyRef(name, &SchemaRef{\n\t\tValue: propertySchema,\n\t})\n}\n\nfunc (schema *Schema) WithPropertyRef(name string, ref *SchemaRef) *Schema {\n\tproperties := schema.Properties\n\tif properties == nil {\n\t\tproperties = make(Schemas)\n\t\tschema.Properties = properties\n\t}\n\tproperties[name] = ref\n\treturn schema\n}\n\nfunc (schema *Schema) WithProperties(properties map[string]*Schema) *Schema {\n\tresult := make(Schemas, len(properties))\n\tfor k, v := range properties {\n\t\tresult[k] = &SchemaRef{\n\t\t\tValue: v,\n\t\t}\n\t}\n\tschema.Properties = result\n\treturn schema\n}\n\nfunc (schema *Schema) WithRequired(required []string) *Schema {\n\tschema.Required = required\n\treturn schema\n}\n\nfunc (schema *Schema) WithMinProperties(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MinProps = n\n\treturn schema\n}\n\nfunc (schema *Schema) WithMaxProperties(i int64) *Schema {\n\tn := uint64(i)\n\tschema.MaxProps = &n\n\treturn schema\n}\n\nfunc (schema *Schema) WithAnyAdditionalProperties() *Schema {\n\tschema.AdditionalProperties = AdditionalProperties{Has: BoolPtr(true)}\n\treturn schema\n}\n\nfunc (schema *Schema) WithoutAdditionalProperties() *Schema {\n\tschema.AdditionalProperties = AdditionalProperties{Has: BoolPtr(false)}\n\treturn schema\n}\n\nfunc (schema *Schema) WithAdditionalProperties(v *Schema) *Schema {\n\tschema.AdditionalProperties = AdditionalProperties{}\n\tif v != nil {\n\t\tschema.AdditionalProperties.Schema = &SchemaRef{Value: v}\n\t}\n\treturn schema\n}\n\nfunc (schema *Schema) PermitsNull() bool {\n\treturn schema.Nullable || schema.Type.Includes(\"null\")\n}\n\n// IsEmpty tells whether schema is equivalent to the empty schema `{}`.\nfunc (schema *Schema) IsEmpty() bool {\n\tif schema.Type != nil || schema.Format != \"\" || len(schema.Enum) != 0 ||\n\t\tschema.UniqueItems || schema.ExclusiveMin || schema.ExclusiveMax ||\n\t\tschema.Nullable || schema.ReadOnly || schema.WriteOnly || schema.AllowEmptyValue ||\n\t\tschema.Min != nil || schema.Max != nil || schema.MultipleOf != nil ||\n\t\tschema.MinLength != 0 || schema.MaxLength != nil || schema.Pattern != \"\" ||\n\t\tschema.MinItems != 0 || schema.MaxItems != nil ||\n\t\tlen(schema.Required) != 0 ||\n\t\tschema.MinProps != 0 || schema.MaxProps != nil {\n\t\treturn false\n\t}\n\tif n := schema.Not; n != nil && n.Value != nil && !n.Value.IsEmpty() {\n\t\treturn false\n\t}\n\tif ap := schema.AdditionalProperties.Schema; ap != nil && ap.Value != nil && !ap.Value.IsEmpty() {\n\t\treturn false\n\t}\n\tif apa := schema.AdditionalProperties.Has; apa != nil && !*apa {\n\t\treturn false\n\t}\n\tif items := schema.Items; items != nil && items.Value != nil && !items.Value.IsEmpty() {\n\t\treturn false\n\t}\n\tfor _, s := range schema.Properties {\n\t\tif ss := s.Value; ss != nil && !ss.IsEmpty() {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor _, s := range schema.OneOf {\n\t\tif ss := s.Value; ss != nil && !ss.IsEmpty() {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor _, s := range schema.AnyOf {\n\t\tif ss := s.Value; ss != nil && !ss.IsEmpty() {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor _, s := range schema.AllOf {\n\t\tif ss := s.Value; ss != nil && !ss.IsEmpty() {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Validate returns an error if Schema does not comply with the OpenAPI spec.\nfunc (schema *Schema) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\t_, err := schema.validate(ctx, []*Schema{})\n\treturn err\n}\n\n// returns the updated stack and an error if Schema does not comply with the OpenAPI spec.\nfunc (schema *Schema) validate(ctx context.Context, stack []*Schema) ([]*Schema, error) {\n\tvalidationOpts := getValidationOptions(ctx)\n\n\tfor _, existing := range stack {\n\t\tif existing == schema {\n\t\t\treturn stack, nil\n\t\t}\n\t}\n\tstack = append(stack, schema)\n\n\tif schema.ReadOnly && schema.WriteOnly {\n\t\treturn stack, errors.New(\"a property MUST NOT be marked as both readOnly and writeOnly being true\")\n\t}\n\n\tfor _, item := range schema.OneOf {\n\t\tv := item.Value\n\t\tif v == nil {\n\t\t\treturn stack, foundUnresolvedRef(item.Ref)\n\t\t}\n\n\t\tvar err error\n\t\tif stack, err = v.validate(ctx, stack); err != nil {\n\t\t\treturn stack, err\n\t\t}\n\t}\n\n\tfor _, item := range schema.AnyOf {\n\t\tv := item.Value\n\t\tif v == nil {\n\t\t\treturn stack, foundUnresolvedRef(item.Ref)\n\t\t}\n\n\t\tvar err error\n\t\tif stack, err = v.validate(ctx, stack); err != nil {\n\t\t\treturn stack, err\n\t\t}\n\t}\n\n\tfor _, item := range schema.AllOf {\n\t\tv := item.Value\n\t\tif v == nil {\n\t\t\treturn stack, foundUnresolvedRef(item.Ref)\n\t\t}\n\n\t\tvar err error\n\t\tif stack, err = v.validate(ctx, stack); err != nil {\n\t\t\treturn stack, err\n\t\t}\n\t}\n\n\tif ref := schema.Not; ref != nil {\n\t\tv := ref.Value\n\t\tif v == nil {\n\t\t\treturn stack, foundUnresolvedRef(ref.Ref)\n\t\t}\n\n\t\tvar err error\n\t\tif stack, err = v.validate(ctx, stack); err != nil {\n\t\t\treturn stack, err\n\t\t}\n\t}\n\n\tfor _, schemaType := range schema.Type.Slice() {\n\t\tswitch schemaType {\n\t\tcase TypeBoolean:\n\t\tcase TypeNumber:\n\t\t\tif format := schema.Format; len(format) > 0 {\n\t\t\t\tswitch format {\n\t\t\t\tcase \"float\", \"double\":\n\t\t\t\tdefault:\n\t\t\t\t\tif _, ok := SchemaNumberFormats[format]; !ok && validationOpts.schemaFormatValidationEnabled {\n\t\t\t\t\t\treturn stack, unsupportedFormat(format)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase TypeInteger:\n\t\t\tif format := schema.Format; len(format) > 0 {\n\t\t\t\tswitch format {\n\t\t\t\tcase \"int32\", \"int64\":\n\t\t\t\tdefault:\n\t\t\t\t\tif _, ok := SchemaIntegerFormats[format]; !ok && validationOpts.schemaFormatValidationEnabled {\n\t\t\t\t\t\treturn stack, unsupportedFormat(format)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase TypeString:\n\t\t\tif format := schema.Format; len(format) > 0 {\n\t\t\t\tswitch format {\n\t\t\t\t// Supported by OpenAPIv3.0.3:\n\t\t\t\t// https://spec.openapis.org/oas/v3.0.3\n\t\t\t\tcase \"byte\", \"binary\", \"date\", \"date-time\", \"password\":\n\t\t\t\t// In JSON Draft-07 (not validated yet though):\n\t\t\t\t// https://json-schema.org/draft-07/json-schema-release-notes.html#formats\n\t\t\t\tcase \"iri\", \"iri-reference\", \"uri-template\", \"idn-email\", \"idn-hostname\":\n\t\t\t\tcase \"json-pointer\", \"relative-json-pointer\", \"regex\", \"time\":\n\t\t\t\t// In JSON Draft 2019-09 (not validated yet though):\n\t\t\t\t// https://json-schema.org/draft/2019-09/release-notes.html#format-vocabulary\n\t\t\t\tcase \"duration\", \"uuid\":\n\t\t\t\t// Defined in some other specification\n\t\t\t\tcase \"email\", \"hostname\", \"ipv4\", \"ipv6\", \"uri\", \"uri-reference\":\n\t\t\t\tdefault:\n\t\t\t\t\tif _, ok := SchemaStringFormats[format]; !ok && validationOpts.schemaFormatValidationEnabled {\n\t\t\t\t\t\treturn stack, unsupportedFormat(format)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !validationOpts.schemaPatternValidationDisabled && schema.Pattern != \"\" {\n\t\t\t\tif _, err := schema.compilePattern(validationOpts.regexCompilerFunc); err != nil {\n\t\t\t\t\treturn stack, err\n\t\t\t\t}\n\t\t\t}\n\t\tcase TypeArray:\n\t\t\tif schema.Items == nil {\n\t\t\t\treturn stack, errors.New(\"when schema type is 'array', schema 'items' must be non-null\")\n\t\t\t}\n\t\tcase TypeObject:\n\t\tdefault:\n\t\t\treturn stack, fmt.Errorf(\"unsupported 'type' value %q\", schemaType)\n\t\t}\n\t}\n\n\tif ref := schema.Items; ref != nil {\n\t\tv := ref.Value\n\t\tif v == nil {\n\t\t\treturn stack, foundUnresolvedRef(ref.Ref)\n\t\t}\n\n\t\tvar err error\n\t\tif stack, err = v.validate(ctx, stack); err != nil {\n\t\t\treturn stack, err\n\t\t}\n\t}\n\n\tproperties := make([]string, 0, len(schema.Properties))\n\tfor name := range schema.Properties {\n\t\tproperties = append(properties, name)\n\t}\n\tsort.Strings(properties)\n\tfor _, name := range properties {\n\t\tref := schema.Properties[name]\n\t\tv := ref.Value\n\t\tif v == nil {\n\t\t\treturn stack, foundUnresolvedRef(ref.Ref)\n\t\t}\n\n\t\tvar err error\n\t\tif stack, err = v.validate(ctx, stack); err != nil {\n\t\t\treturn stack, err\n\t\t}\n\t}\n\n\tif schema.AdditionalProperties.Has != nil && schema.AdditionalProperties.Schema != nil {\n\t\treturn stack, errors.New(\"additionalProperties are set to both boolean and schema\")\n\t}\n\tif ref := schema.AdditionalProperties.Schema; ref != nil {\n\t\tv := ref.Value\n\t\tif v == nil {\n\t\t\treturn stack, foundUnresolvedRef(ref.Ref)\n\t\t}\n\n\t\tvar err error\n\t\tif stack, err = v.validate(ctx, stack); err != nil {\n\t\t\treturn stack, err\n\t\t}\n\t}\n\n\tif v := schema.ExternalDocs; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn stack, fmt.Errorf(\"invalid external docs: %w\", err)\n\t\t}\n\t}\n\n\tif v := schema.Default; v != nil && !validationOpts.schemaDefaultsValidationDisabled {\n\t\tif err := schema.VisitJSON(v); err != nil {\n\t\t\treturn stack, fmt.Errorf(\"invalid default: %w\", err)\n\t\t}\n\t}\n\n\tif x := schema.Example; x != nil && !validationOpts.examplesValidationDisabled {\n\t\tif err := validateExampleValue(ctx, x, schema); err != nil {\n\t\t\treturn stack, fmt.Errorf(\"invalid example: %w\", err)\n\t\t}\n\t}\n\n\treturn stack, validateExtensions(ctx, schema.Extensions)\n}\n\nfunc (schema *Schema) IsMatching(value any) bool {\n\tsettings := newSchemaValidationSettings(FailFast())\n\treturn schema.visitJSON(settings, value) == nil\n}\n\nfunc (schema *Schema) IsMatchingJSONBoolean(value bool) bool {\n\tsettings := newSchemaValidationSettings(FailFast())\n\treturn schema.visitJSON(settings, value) == nil\n}\n\nfunc (schema *Schema) IsMatchingJSONNumber(value float64) bool {\n\tsettings := newSchemaValidationSettings(FailFast())\n\treturn schema.visitJSON(settings, value) == nil\n}\n\nfunc (schema *Schema) IsMatchingJSONString(value string) bool {\n\tsettings := newSchemaValidationSettings(FailFast())\n\treturn schema.visitJSON(settings, value) == nil\n}\n\nfunc (schema *Schema) IsMatchingJSONArray(value []any) bool {\n\tsettings := newSchemaValidationSettings(FailFast())\n\treturn schema.visitJSON(settings, value) == nil\n}\n\nfunc (schema *Schema) IsMatchingJSONObject(value map[string]any) bool {\n\tsettings := newSchemaValidationSettings(FailFast())\n\treturn schema.visitJSON(settings, value) == nil\n}\n\nfunc (schema *Schema) VisitJSON(value any, opts ...SchemaValidationOption) error {\n\tsettings := newSchemaValidationSettings(opts...)\n\treturn schema.visitJSON(settings, value)\n}\n\nfunc (schema *Schema) visitJSON(settings *schemaValidationSettings, value any) (err error) {\n\tswitch value := value.(type) {\n\tcase nil:\n\t\t// Don't use VisitJSONNull, as we still want to reach 'visitXOFOperations', since\n\t\t// those could allow for a nullable value even though this one doesn't\n\t\tif schema.PermitsNull() {\n\t\t\treturn\n\t\t}\n\tcase float64:\n\t\tif math.IsNaN(value) {\n\t\t\treturn ErrSchemaInputNaN\n\t\t}\n\t\tif math.IsInf(value, 0) {\n\t\t\treturn ErrSchemaInputInf\n\t\t}\n\t}\n\n\tif schema.IsEmpty() {\n\t\tswitch value.(type) {\n\t\tcase nil:\n\t\t\treturn schema.visitJSONNull(settings)\n\t\tdefault:\n\t\t\treturn\n\t\t}\n\t}\n\n\tif err = schema.visitNotOperation(settings, value); err != nil {\n\t\treturn\n\t}\n\tvar run bool\n\tif err, run = schema.visitXOFOperations(settings, value); err != nil || !run {\n\t\treturn\n\t}\n\tif err = schema.visitEnumOperation(settings, value); err != nil {\n\t\treturn\n\t}\n\n\tswitch value := value.(type) {\n\tcase nil:\n\t\treturn schema.visitJSONNull(settings)\n\tcase bool:\n\t\treturn schema.visitJSONBoolean(settings, value)\n\tcase json.Number:\n\t\tvalueFloat64, err := value.Float64()\n\t\tif err != nil {\n\t\t\treturn &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"type\",\n\t\t\t\tReason:                \"cannot convert json.Number to float64\",\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t\tOrigin:                err,\n\t\t\t}\n\t\t}\n\t\treturn schema.visitJSONNumber(settings, valueFloat64)\n\tcase int:\n\t\treturn schema.visitJSONNumber(settings, float64(value))\n\tcase int32:\n\t\treturn schema.visitJSONNumber(settings, float64(value))\n\tcase int64:\n\t\treturn schema.visitJSONNumber(settings, float64(value))\n\tcase float64:\n\t\treturn schema.visitJSONNumber(settings, value)\n\tcase string:\n\t\treturn schema.visitJSONString(settings, value)\n\tcase []any:\n\t\treturn schema.visitJSONArray(settings, value)\n\tcase map[string]any:\n\t\treturn schema.visitJSONObject(settings, value)\n\tcase map[any]any: // for YAML cf. issue https://github.com/getkin/kin-openapi/issues/444\n\t\tvalues := make(map[string]any, len(value))\n\t\tfor key, v := range value {\n\t\t\tif k, ok := key.(string); ok {\n\t\t\t\tvalues[k] = v\n\t\t\t}\n\t\t}\n\t\tif len(value) == len(values) {\n\t\t\treturn schema.visitJSONObject(settings, values)\n\t\t}\n\t}\n\n\t// Catch slice of non-empty interface type\n\tif reflect.TypeOf(value).Kind() == reflect.Slice {\n\t\tvalueR := reflect.ValueOf(value)\n\t\tnewValue := make([]any, 0, valueR.Len())\n\t\tfor i := 0; i < valueR.Len(); i++ {\n\t\t\tnewValue = append(newValue, valueR.Index(i).Interface())\n\t\t}\n\t\treturn schema.visitJSONArray(settings, newValue)\n\t}\n\n\treturn &SchemaError{\n\t\tValue:                 value,\n\t\tSchema:                schema,\n\t\tSchemaField:           \"type\",\n\t\tReason:                fmt.Sprintf(\"unhandled value of type %T\", value),\n\t\tcustomizeMessageError: settings.customizeMessageError,\n\t}\n}\n\nfunc (schema *Schema) visitEnumOperation(settings *schemaValidationSettings, value any) (err error) {\n\tif enum := schema.Enum; len(enum) != 0 {\n\t\tfor _, v := range enum {\n\t\t\tswitch c := value.(type) {\n\t\t\tcase json.Number:\n\t\t\t\tvar f float64\n\t\t\t\tif f, err = strconv.ParseFloat(c.String(), 64); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif v == f {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\tcase int64:\n\t\t\t\tif v == float64(c) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif reflect.DeepEqual(v, value) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\tallowedValues, _ := json.Marshal(enum)\n\t\treturn &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"enum\",\n\t\t\tReason:                fmt.Sprintf(\"value is not one of the allowed values %s\", string(allowedValues)),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t}\n\treturn\n}\n\nfunc (schema *Schema) visitNotOperation(settings *schemaValidationSettings, value any) (err error) {\n\tif ref := schema.Not; ref != nil {\n\t\tv := ref.Value\n\t\tif v == nil {\n\t\t\treturn foundUnresolvedRef(ref.Ref)\n\t\t}\n\t\tif err := v.visitJSON(settings, value); err == nil {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema\n\t\t\t}\n\t\t\treturn &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"not\",\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\n// If the XOF operations pass successfully, abort further run of validation, as they will already be satisfied (unless the schema\n// itself is badly specified\nfunc (schema *Schema) visitXOFOperations(settings *schemaValidationSettings, value any) (err error, run bool) {\n\tvar visitedOneOf, visitedAnyOf, visitedAllOf bool\n\tif v := schema.OneOf; len(v) > 0 {\n\t\tvar discriminatorRef string\n\t\tif schema.Discriminator != nil {\n\t\t\tpn := schema.Discriminator.PropertyName\n\t\t\tif valuemap, okcheck := value.(map[string]any); okcheck {\n\t\t\t\tdiscriminatorVal, okcheck := valuemap[pn]\n\t\t\t\tif !okcheck {\n\t\t\t\t\treturn &SchemaError{\n\t\t\t\t\t\tSchema:      schema,\n\t\t\t\t\t\tSchemaField: \"discriminator\",\n\t\t\t\t\t\tReason:      fmt.Sprintf(\"input does not contain the discriminator property %q\", pn),\n\t\t\t\t\t}, false\n\t\t\t\t}\n\n\t\t\t\tdiscriminatorValString, okcheck := discriminatorVal.(string)\n\t\t\t\tif !okcheck {\n\t\t\t\t\treturn &SchemaError{\n\t\t\t\t\t\tValue:       discriminatorVal,\n\t\t\t\t\t\tSchema:      schema,\n\t\t\t\t\t\tSchemaField: \"discriminator\",\n\t\t\t\t\t\tReason:      fmt.Sprintf(\"value of discriminator property %q is not a string\", pn),\n\t\t\t\t\t}, false\n\t\t\t\t}\n\n\t\t\t\tif discriminatorRef, okcheck = schema.Discriminator.Mapping[discriminatorValString]; len(schema.Discriminator.Mapping) > 0 && !okcheck {\n\t\t\t\t\treturn &SchemaError{\n\t\t\t\t\t\tValue:       discriminatorVal,\n\t\t\t\t\t\tSchema:      schema,\n\t\t\t\t\t\tSchemaField: \"discriminator\",\n\t\t\t\t\t\tReason:      fmt.Sprintf(\"discriminator property %q has invalid value\", pn),\n\t\t\t\t\t}, false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar (\n\t\t\tok                  = 0\n\t\t\tvalidationErrors    = multiErrorForOneOf{}\n\t\t\tmatchedOneOfIndices = make([]int, 0)\n\t\t\ttempValue           = value\n\t\t)\n\t\tfor idx, item := range v {\n\t\t\tv := item.Value\n\t\t\tif v == nil {\n\t\t\t\treturn foundUnresolvedRef(item.Ref), false\n\t\t\t}\n\n\t\t\tif discriminatorRef != \"\" && discriminatorRef != item.Ref {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// make a deep copy to protect origin value from being injected default value that defined in mismatched oneOf schema\n\t\t\tif settings.asreq || settings.asrep {\n\t\t\t\ttempValue = deepcopy.Copy(value)\n\t\t\t}\n\n\t\t\tif err := v.visitJSON(settings, tempValue); err != nil {\n\t\t\t\tvalidationErrors = append(validationErrors, err)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tmatchedOneOfIndices = append(matchedOneOfIndices, idx)\n\t\t\tok++\n\t\t}\n\n\t\tif ok != 1 {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema, false\n\t\t\t}\n\t\t\te := &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"oneOf\",\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}\n\t\t\tif ok > 1 {\n\t\t\t\te.Origin = ErrOneOfConflict\n\t\t\t\te.Reason = fmt.Sprintf(`value matches more than one schema from \"oneOf\" (matches schemas at indices %v)`, matchedOneOfIndices)\n\t\t\t} else {\n\t\t\t\te.Origin = fmt.Errorf(\"doesn't match schema due to: %w\", validationErrors)\n\t\t\t\te.Reason = `value doesn't match any schema from \"oneOf\"`\n\t\t\t}\n\n\t\t\treturn e, false\n\t\t}\n\n\t\t// run again to inject default value that defined in matched oneOf schema\n\t\tif settings.asreq || settings.asrep {\n\t\t\t_ = v[matchedOneOfIndices[0]].Value.visitJSON(settings, value)\n\t\t}\n\t\tvisitedOneOf = true\n\t}\n\n\tif v := schema.AnyOf; len(v) > 0 {\n\t\tvar (\n\t\t\tok              = false\n\t\t\tmatchedAnyOfIdx = 0\n\t\t\ttempValue       = value\n\t\t)\n\t\tfor idx, item := range v {\n\t\t\tv := item.Value\n\t\t\tif v == nil {\n\t\t\t\treturn foundUnresolvedRef(item.Ref), false\n\t\t\t}\n\t\t\t// make a deep copy to protect origin value from being injected default value that defined in mismatched anyOf schema\n\t\t\tif settings.asreq || settings.asrep {\n\t\t\t\ttempValue = deepcopy.Copy(value)\n\t\t\t}\n\t\t\tif err := v.visitJSON(settings, tempValue); err == nil {\n\t\t\t\tok = true\n\t\t\t\tmatchedAnyOfIdx = idx\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !ok {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema, false\n\t\t\t}\n\t\t\treturn &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"anyOf\",\n\t\t\t\tReason:                `doesn't match any schema from \"anyOf\"`,\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}, false\n\t\t}\n\n\t\t_ = v[matchedAnyOfIdx].Value.visitJSON(settings, value)\n\t\tvisitedAnyOf = true\n\t}\n\n\tfor _, item := range schema.AllOf {\n\t\tv := item.Value\n\t\tif v == nil {\n\t\t\treturn foundUnresolvedRef(item.Ref), false\n\t\t}\n\t\tif err := v.visitJSON(settings, value); err != nil {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema, false\n\t\t\t}\n\t\t\treturn &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"allOf\",\n\t\t\t\tReason:                `doesn't match all schemas from \"allOf\"`,\n\t\t\t\tOrigin:                err,\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}, false\n\t\t}\n\t\tvisitedAllOf = true\n\t}\n\n\trun = !((visitedOneOf || visitedAnyOf || visitedAllOf) && value == nil)\n\treturn\n}\n\n// The value is not considered in visitJSONNull because according to the spec\n// \"null is not supported as a type\" unless `nullable` is also set to true\n// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#data-types\n// https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#schema-object\nfunc (schema *Schema) visitJSONNull(settings *schemaValidationSettings) (err error) {\n\tif schema.PermitsNull() {\n\t\treturn\n\t}\n\tif settings.failfast {\n\t\treturn errSchema\n\t}\n\treturn &SchemaError{\n\t\tValue:                 nil,\n\t\tSchema:                schema,\n\t\tSchemaField:           \"nullable\",\n\t\tReason:                \"Value is not nullable\",\n\t\tcustomizeMessageError: settings.customizeMessageError,\n\t}\n}\n\nfunc (schema *Schema) VisitJSONBoolean(value bool) error {\n\tsettings := newSchemaValidationSettings()\n\treturn schema.visitJSONBoolean(settings, value)\n}\n\nfunc (schema *Schema) visitJSONBoolean(settings *schemaValidationSettings, value bool) (err error) {\n\tif !schema.Type.Permits(TypeBoolean) {\n\t\treturn schema.expectedType(settings, value)\n\t}\n\treturn\n}\n\nfunc (schema *Schema) VisitJSONNumber(value float64) error {\n\tsettings := newSchemaValidationSettings()\n\treturn schema.visitJSONNumber(settings, value)\n}\n\nfunc (schema *Schema) visitJSONNumber(settings *schemaValidationSettings, value float64) error {\n\tvar me MultiError\n\tschemaType := schema.Type\n\trequireInteger := false\n\tif schemaType.Permits(TypeInteger) && !schemaType.Permits(TypeNumber) {\n\t\trequireInteger = true\n\t\tif bigFloat := big.NewFloat(value); !bigFloat.IsInt() {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema\n\t\t\t}\n\t\t\terr := &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"type\",\n\t\t\t\tReason:                \"value must be an integer\",\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}\n\t\t\tif !settings.multiError {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tme = append(me, err)\n\t\t}\n\t} else if !(schemaType.Permits(TypeInteger) || schemaType.Permits(TypeNumber)) {\n\t\treturn schema.expectedType(settings, value)\n\t}\n\n\t// formats\n\tvar formatStrErr string\n\tvar formatErr error\n\tformat := schema.Format\n\tif format != \"\" {\n\t\tif requireInteger {\n\t\t\tif f, ok := SchemaIntegerFormats[format]; ok {\n\t\t\t\tif err := f.Validate(int64(value)); err != nil {\n\t\t\t\t\tvar reason string\n\t\t\t\t\tschemaErr := &SchemaError{}\n\t\t\t\t\tif errors.As(err, &schemaErr) {\n\t\t\t\t\t\treason = schemaErr.Reason\n\t\t\t\t\t} else {\n\t\t\t\t\t\treason = err.Error()\n\t\t\t\t\t}\n\t\t\t\t\tformatStrErr = fmt.Sprintf(`integer doesn't match the format %q (%v)`, format, reason)\n\t\t\t\t\tformatErr = fmt.Errorf(\"integer doesn't match the format %q: %w\", format, err)\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif f, ok := SchemaNumberFormats[format]; ok {\n\t\t\t\tif err := f.Validate(value); err != nil {\n\t\t\t\t\tvar reason string\n\t\t\t\t\tschemaErr := &SchemaError{}\n\t\t\t\t\tif errors.As(err, &schemaErr) {\n\t\t\t\t\t\treason = schemaErr.Reason\n\t\t\t\t\t} else {\n\t\t\t\t\t\treason = err.Error()\n\t\t\t\t\t}\n\t\t\t\t\tformatStrErr = fmt.Sprintf(`number doesn't match the format %q (%v)`, format, reason)\n\t\t\t\t\tformatErr = fmt.Errorf(\"number doesn't match the format %q: %w\", format, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif formatStrErr != \"\" || formatErr != nil {\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"format\",\n\t\t\tReason:                formatStrErr,\n\t\t\tOrigin:                formatErr,\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"exclusiveMinimum\"\n\tif v := schema.ExclusiveMin; v && !(*schema.Min < value) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"exclusiveMinimum\",\n\t\t\tReason:                fmt.Sprintf(\"number must be more than %g\", *schema.Min),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"exclusiveMaximum\"\n\tif v := schema.ExclusiveMax; v && !(*schema.Max > value) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"exclusiveMaximum\",\n\t\t\tReason:                fmt.Sprintf(\"number must be less than %g\", *schema.Max),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"minimum\"\n\tif v := schema.Min; v != nil && !(*v <= value) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"minimum\",\n\t\t\tReason:                fmt.Sprintf(\"number must be at least %g\", *v),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"maximum\"\n\tif v := schema.Max; v != nil && !(*v >= value) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"maximum\",\n\t\t\tReason:                fmt.Sprintf(\"number must be at most %g\", *v),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"multipleOf\"\n\tif v := schema.MultipleOf; v != nil {\n\t\t// \"A numeric instance is valid only if division by this keyword's\n\t\t//    value results in an integer.\"\n\t\tif bigFloat := big.NewFloat(value / *v); !bigFloat.IsInt() {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema\n\t\t\t}\n\t\t\terr := &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"multipleOf\",\n\t\t\t\tReason:                fmt.Sprintf(\"number must be a multiple of %g\", *v),\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}\n\t\t\tif !settings.multiError {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tme = append(me, err)\n\t\t}\n\t}\n\n\tif len(me) > 0 {\n\t\treturn me\n\t}\n\n\treturn nil\n}\n\nfunc (schema *Schema) VisitJSONString(value string) error {\n\tsettings := newSchemaValidationSettings()\n\treturn schema.visitJSONString(settings, value)\n}\n\nfunc (schema *Schema) visitJSONString(settings *schemaValidationSettings, value string) error {\n\tif !schema.Type.Permits(TypeString) {\n\t\treturn schema.expectedType(settings, value)\n\t}\n\n\tvar me MultiError\n\n\t// \"minLength\" and \"maxLength\"\n\tminLength := schema.MinLength\n\tmaxLength := schema.MaxLength\n\tif minLength != 0 || maxLength != nil {\n\t\t// JSON schema string lengths are UTF-16, not UTF-8!\n\t\tlength := int64(0)\n\t\tfor _, r := range value {\n\t\t\tif utf16.IsSurrogate(r) {\n\t\t\t\tlength += 2\n\t\t\t} else {\n\t\t\t\tlength++\n\t\t\t}\n\t\t}\n\t\tif minLength != 0 && length < int64(minLength) {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema\n\t\t\t}\n\t\t\terr := &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"minLength\",\n\t\t\t\tReason:                fmt.Sprintf(\"minimum string length is %d\", minLength),\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}\n\t\t\tif !settings.multiError {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tme = append(me, err)\n\t\t}\n\t\tif maxLength != nil && length > int64(*maxLength) {\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema\n\t\t\t}\n\t\t\terr := &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"maxLength\",\n\t\t\t\tReason:                fmt.Sprintf(\"maximum string length is %d\", *maxLength),\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}\n\t\t\tif !settings.multiError {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tme = append(me, err)\n\t\t}\n\t}\n\n\t// \"pattern\"\n\tif !settings.patternValidationDisabled && schema.Pattern != \"\" {\n\t\tcpiface, _ := compiledPatterns.Load(schema.Pattern)\n\t\tcp, _ := cpiface.(RegexMatcher)\n\t\tif cp == nil {\n\t\t\tvar err error\n\t\t\tif cp, err = schema.compilePattern(settings.regexCompiler); err != nil {\n\t\t\t\tif !settings.multiError {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tme = append(me, err)\n\t\t\t}\n\t\t}\n\t\tif !cp.MatchString(value) {\n\t\t\terr := &SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"pattern\",\n\t\t\t\tReason:                fmt.Sprintf(`string doesn't match the regular expression \"%s\"`, schema.Pattern),\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}\n\t\t\tif !settings.multiError {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tme = append(me, err)\n\t\t}\n\t}\n\n\t// \"format\"\n\tvar formatStrErr string\n\tvar formatErr error\n\tif format := schema.Format; format != \"\" {\n\t\tif f, ok := SchemaStringFormats[format]; ok {\n\t\t\tif err := f.Validate(value); err != nil {\n\t\t\t\tvar reason string\n\t\t\t\tschemaErr := &SchemaError{}\n\t\t\t\tif errors.As(err, &schemaErr) {\n\t\t\t\t\treason = schemaErr.Reason\n\t\t\t\t} else {\n\t\t\t\t\treason = err.Error()\n\t\t\t\t}\n\t\t\t\tformatStrErr = fmt.Sprintf(`string doesn't match the format %q (%v)`, format, reason)\n\t\t\t\tformatErr = fmt.Errorf(\"string doesn't match the format %q: %w\", format, err)\n\t\t\t}\n\t\t}\n\t}\n\tif formatStrErr != \"\" || formatErr != nil {\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"format\",\n\t\t\tReason:                formatStrErr,\n\t\t\tOrigin:                formatErr,\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\n\t}\n\n\tif len(me) > 0 {\n\t\treturn me\n\t}\n\n\treturn nil\n}\n\nfunc (schema *Schema) VisitJSONArray(value []any) error {\n\tsettings := newSchemaValidationSettings()\n\treturn schema.visitJSONArray(settings, value)\n}\n\nfunc (schema *Schema) visitJSONArray(settings *schemaValidationSettings, value []any) error {\n\tif !schema.Type.Permits(TypeArray) {\n\t\treturn schema.expectedType(settings, value)\n\t}\n\n\tvar me MultiError\n\n\tlenValue := int64(len(value))\n\n\t// \"minItems\"\n\tif v := schema.MinItems; v != 0 && lenValue < int64(v) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"minItems\",\n\t\t\tReason:                fmt.Sprintf(\"minimum number of items is %d\", v),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"maxItems\"\n\tif v := schema.MaxItems; v != nil && lenValue > int64(*v) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"maxItems\",\n\t\t\tReason:                fmt.Sprintf(\"maximum number of items is %d\", *v),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"uniqueItems\"\n\tif sliceUniqueItemsChecker == nil {\n\t\tsliceUniqueItemsChecker = isSliceOfUniqueItems\n\t}\n\tif v := schema.UniqueItems; v && !sliceUniqueItemsChecker(value) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"uniqueItems\",\n\t\t\tReason:                \"duplicate items found\",\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"items\"\n\tif itemSchemaRef := schema.Items; itemSchemaRef != nil {\n\t\titemSchema := itemSchemaRef.Value\n\t\tif itemSchema == nil {\n\t\t\treturn foundUnresolvedRef(itemSchemaRef.Ref)\n\t\t}\n\t\tfor i, item := range value {\n\t\t\tif err := itemSchema.visitJSON(settings, item); err != nil {\n\t\t\t\terr = markSchemaErrorIndex(err, i)\n\t\t\t\tif !settings.multiError {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif itemMe, ok := err.(MultiError); ok {\n\t\t\t\t\tme = append(me, itemMe...)\n\t\t\t\t} else {\n\t\t\t\t\tme = append(me, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(me) > 0 {\n\t\treturn me\n\t}\n\n\treturn nil\n}\n\nfunc (schema *Schema) VisitJSONObject(value map[string]any) error {\n\tsettings := newSchemaValidationSettings()\n\treturn schema.visitJSONObject(settings, value)\n}\n\nfunc (schema *Schema) visitJSONObject(settings *schemaValidationSettings, value map[string]any) error {\n\tif !schema.Type.Permits(TypeObject) {\n\t\treturn schema.expectedType(settings, value)\n\t}\n\n\tvar me MultiError\n\n\tif settings.asreq || settings.asrep {\n\t\tproperties := make([]string, 0, len(schema.Properties))\n\t\tfor propName := range schema.Properties {\n\t\t\tproperties = append(properties, propName)\n\t\t}\n\t\tsort.Strings(properties)\n\t\tfor _, propName := range properties {\n\t\t\tpropSchema := schema.Properties[propName]\n\t\t\treqRO := settings.asreq && propSchema.Value.ReadOnly && !settings.readOnlyValidationDisabled\n\t\t\trepWO := settings.asrep && propSchema.Value.WriteOnly && !settings.writeOnlyValidationDisabled\n\n\t\t\tif f := settings.defaultsSet; f != nil && value[propName] == nil {\n\t\t\t\tif dflt := propSchema.Value.Default; dflt != nil && !reqRO && !repWO {\n\t\t\t\t\tvalue[propName] = dflt\n\t\t\t\t\tsettings.onceSettingDefaults.Do(f)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif value[propName] != nil {\n\t\t\t\tif reqRO {\n\t\t\t\t\tme = append(me, fmt.Errorf(\"readOnly property %q in request\", propName))\n\t\t\t\t} else if repWO {\n\t\t\t\t\tme = append(me, fmt.Errorf(\"writeOnly property %q in response\", propName))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// \"properties\"\n\tproperties := schema.Properties\n\tlenValue := int64(len(value))\n\n\t// \"minProperties\"\n\tif v := schema.MinProps; v != 0 && lenValue < int64(v) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"minProperties\",\n\t\t\tReason:                fmt.Sprintf(\"there must be at least %d properties\", v),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"maxProperties\"\n\tif v := schema.MaxProps; v != nil && lenValue > int64(*v) {\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"maxProperties\",\n\t\t\tReason:                fmt.Sprintf(\"there must be at most %d properties\", *v),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"additionalProperties\"\n\tvar additionalProperties *Schema\n\tif ref := schema.AdditionalProperties.Schema; ref != nil {\n\t\tadditionalProperties = ref.Value\n\t}\n\tkeys := make([]string, 0, len(value))\n\tfor k := range value {\n\t\tkeys = append(keys, k)\n\t}\n\tsort.Strings(keys)\n\tfor _, k := range keys {\n\t\tv := value[k]\n\t\tif properties != nil {\n\t\t\tpropertyRef := properties[k]\n\t\t\tif propertyRef != nil {\n\t\t\t\tp := propertyRef.Value\n\t\t\t\tif p == nil {\n\t\t\t\t\treturn foundUnresolvedRef(propertyRef.Ref)\n\t\t\t\t}\n\t\t\t\tif err := p.visitJSON(settings, v); err != nil {\n\t\t\t\t\tif settings.failfast {\n\t\t\t\t\t\treturn errSchema\n\t\t\t\t\t}\n\t\t\t\t\terr = markSchemaErrorKey(err, k)\n\t\t\t\t\tif !settings.multiError {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif v, ok := err.(MultiError); ok {\n\t\t\t\t\t\tme = append(me, v...)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tme = append(me, err)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif allowed := schema.AdditionalProperties.Has; allowed == nil || *allowed {\n\t\t\tif additionalProperties != nil {\n\t\t\t\tif err := additionalProperties.visitJSON(settings, v); err != nil {\n\t\t\t\t\tif settings.failfast {\n\t\t\t\t\t\treturn errSchema\n\t\t\t\t\t}\n\t\t\t\t\terr = markSchemaErrorKey(err, k)\n\t\t\t\t\tif !settings.multiError {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif v, ok := err.(MultiError); ok {\n\t\t\t\t\t\tme = append(me, v...)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tme = append(me, err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif settings.failfast {\n\t\t\treturn errSchema\n\t\t}\n\t\terr := &SchemaError{\n\t\t\tValue:                 value,\n\t\t\tSchema:                schema,\n\t\t\tSchemaField:           \"properties\",\n\t\t\tReason:                fmt.Sprintf(\"property %q is unsupported\", k),\n\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t}\n\t\tif !settings.multiError {\n\t\t\treturn err\n\t\t}\n\t\tme = append(me, err)\n\t}\n\n\t// \"required\"\n\tfor _, k := range schema.Required {\n\t\tif _, ok := value[k]; !ok {\n\t\t\tif s := schema.Properties[k]; s != nil && s.Value.ReadOnly && settings.asreq {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif s := schema.Properties[k]; s != nil && s.Value.WriteOnly && settings.asrep {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif settings.failfast {\n\t\t\t\treturn errSchema\n\t\t\t}\n\t\t\terr := markSchemaErrorKey(&SchemaError{\n\t\t\t\tValue:                 value,\n\t\t\t\tSchema:                schema,\n\t\t\t\tSchemaField:           \"required\",\n\t\t\t\tReason:                fmt.Sprintf(\"property %q is missing\", k),\n\t\t\t\tcustomizeMessageError: settings.customizeMessageError,\n\t\t\t}, k)\n\t\t\tif !settings.multiError {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tme = append(me, err)\n\t\t}\n\t}\n\n\tif len(me) > 0 {\n\t\treturn me\n\t}\n\n\treturn nil\n}\n\nfunc (schema *Schema) expectedType(settings *schemaValidationSettings, value any) error {\n\tif settings.failfast {\n\t\treturn errSchema\n\t}\n\n\ta := \"a\"\n\tvar x string\n\tschemaTypes := (*schema.Type)\n\tif len(schemaTypes) == 1 {\n\t\tx = schemaTypes[0]\n\t\tswitch x {\n\t\tcase TypeArray, TypeObject, TypeInteger:\n\t\t\ta = \"an\"\n\t\t}\n\t} else {\n\t\ta = \"one of\"\n\t\tx = strings.Join(schemaTypes, \", \")\n\t}\n\treturn &SchemaError{\n\t\tValue:                 value,\n\t\tSchema:                schema,\n\t\tSchemaField:           \"type\",\n\t\tReason:                fmt.Sprintf(\"value must be %s %s\", a, x),\n\t\tcustomizeMessageError: settings.customizeMessageError,\n\t}\n}\n\n// SchemaError is an error that occurs during schema validation.\ntype SchemaError struct {\n\t// Value is the value that failed validation.\n\tValue any\n\t// reversePath is the path to the value that failed validation.\n\treversePath []string\n\t// Schema is the schema that failed validation.\n\tSchema *Schema\n\t// SchemaField is the field of the schema that failed validation.\n\tSchemaField string\n\t// Reason is a human-readable message describing the error.\n\t// The message should never include the original value to prevent leakage of potentially sensitive inputs in error messages.\n\tReason string\n\t// Origin is the original error that caused this error.\n\tOrigin error\n\t// customizeMessageError is a function that can be used to customize the error message.\n\tcustomizeMessageError func(err *SchemaError) string\n}\n\nvar _ interface{ Unwrap() error } = SchemaError{}\n\nfunc markSchemaErrorKey(err error, key string) error {\n\n\tif v, ok := err.(*SchemaError); ok {\n\t\tv.reversePath = append(v.reversePath, key)\n\t\tif v.Origin != nil {\n\t\t\tif unwrapped := errors.Unwrap(v.Origin); unwrapped != nil {\n\t\t\t\tif me, ok := unwrapped.(multiErrorForOneOf); ok {\n\t\t\t\t\t_ = markSchemaErrorKey(MultiError(me), key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn v\n\t}\n\tif v, ok := err.(MultiError); ok {\n\t\tfor _, e := range v {\n\t\t\t_ = markSchemaErrorKey(e, key)\n\t\t}\n\t\treturn v\n\t}\n\treturn err\n}\n\nfunc markSchemaErrorIndex(err error, index int) error {\n\treturn markSchemaErrorKey(err, strconv.FormatInt(int64(index), 10))\n}\n\nfunc (err *SchemaError) JSONPointer() []string {\n\treversePath := err.reversePath\n\tpath := append([]string(nil), reversePath...)\n\tfor left, right := 0, len(path)-1; left < right; left, right = left+1, right-1 {\n\t\tpath[left], path[right] = path[right], path[left]\n\t}\n\treturn path\n}\n\nfunc (err *SchemaError) Error() string {\n\tif err.customizeMessageError != nil {\n\t\tif msg := err.customizeMessageError(err); msg != \"\" {\n\t\t\treturn msg\n\t\t}\n\t}\n\n\tbuf := bytes.NewBuffer(make([]byte, 0, 256))\n\n\tif len(err.reversePath) > 0 {\n\t\tbuf.WriteString(`Error at \"`)\n\t\treversePath := err.reversePath\n\t\tfor i := len(reversePath) - 1; i >= 0; i-- {\n\t\t\tbuf.WriteByte('/')\n\t\t\tbuf.WriteString(reversePath[i])\n\t\t}\n\t\tbuf.WriteString(`\": `)\n\t}\n\n\tif err.Origin != nil {\n\t\tbuf.WriteString(err.Origin.Error())\n\n\t\treturn buf.String()\n\t}\n\n\treason := err.Reason\n\tif reason == \"\" {\n\t\tbuf.WriteString(`Doesn't match schema \"`)\n\t\tbuf.WriteString(err.SchemaField)\n\t\tbuf.WriteString(`\"`)\n\t} else {\n\t\tbuf.WriteString(reason)\n\t}\n\n\tif !SchemaErrorDetailsDisabled {\n\t\tbuf.WriteString(\"\\nSchema:\\n  \")\n\t\tencoder := json.NewEncoder(buf)\n\t\tencoder.SetIndent(\"  \", \"  \")\n\t\tif err := encoder.Encode(err.Schema); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tbuf.WriteString(\"\\nValue:\\n  \")\n\t\tif err := encoder.Encode(err.Value); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\treturn buf.String()\n}\n\nfunc (err SchemaError) Unwrap() error {\n\treturn err.Origin\n}\n\nfunc isSliceOfUniqueItems(xs []any) bool {\n\ts := len(xs)\n\tm := make(map[string]struct{}, s)\n\tfor _, x := range xs {\n\t\t// The input slice is converted from a JSON string, there shall\n\t\t// have no error when convert it back.\n\t\tkey, _ := json.Marshal(&x)\n\t\tm[string(key)] = struct{}{}\n\t}\n\treturn s == len(m)\n}\n\n// SliceUniqueItemsChecker is an function used to check if an given slice\n// have unique items.\ntype SliceUniqueItemsChecker func(items []any) bool\n\n// By default using predefined func isSliceOfUniqueItems which make use of\n// json.Marshal to generate a key for map used to check if a given slice\n// have unique items.\nvar sliceUniqueItemsChecker SliceUniqueItemsChecker = isSliceOfUniqueItems\n\n// RegisterArrayUniqueItemsChecker is used to register a customized function\n// used to check if JSON array have unique items.\nfunc RegisterArrayUniqueItemsChecker(fn SliceUniqueItemsChecker) {\n\tsliceUniqueItemsChecker = fn\n}\n\nfunc unsupportedFormat(format string) error {\n\treturn fmt.Errorf(\"unsupported 'format' value %q\", format)\n}\n\n// UnmarshalJSON sets Schemas to a copy of data.\nfunc (schemas *Schemas) UnmarshalJSON(data []byte) (err error) {\n\t*schemas, _, err = unmarshalStringMapP[SchemaRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/schema_formats.go",
    "content": "package openapi3\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"net/netip\"\n\t\"regexp\"\n)\n\ntype (\n\t// FormatValidator is an interface for custom format validators.\n\tFormatValidator[T any] interface {\n\t\tValidate(value T) error\n\t}\n\t// StringFormatValidator is a type alias for FormatValidator[string]\n\tStringFormatValidator = FormatValidator[string]\n\t// NumberFormatValidator is a type alias for FormatValidator[float64]\n\tNumberFormatValidator = FormatValidator[float64]\n\t// IntegerFormatValidator is a type alias for FormatValidator[int64]\n\tIntegerFormatValidator = FormatValidator[int64]\n)\n\nvar (\n\t// SchemaStringFormats is a map of custom string format validators.\n\tSchemaStringFormats = make(map[string]StringFormatValidator)\n\t// SchemaNumberFormats is a map of custom number format validators.\n\tSchemaNumberFormats = make(map[string]NumberFormatValidator)\n\t// SchemaIntegerFormats is a map of custom integer format validators.\n\tSchemaIntegerFormats = make(map[string]IntegerFormatValidator)\n)\n\nconst (\n\t// FormatOfStringForUUIDOfRFC4122 is an optional predefined format for UUID v1-v5 as specified by RFC4122\n\tFormatOfStringForUUIDOfRFC4122 = `^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$`\n\n\t// FormatOfStringForEmail pattern catches only some suspiciously wrong-looking email addresses.\n\t// Use DefineStringFormat(...) if you need something stricter.\n\tFormatOfStringForEmail = `^[^@]+@[^@<>\",\\s]+$`\n\n\t// FormatOfStringByte is a regexp for base64-encoded characters, for example, \"U3dhZ2dlciByb2Nrcw==\"\n\tFormatOfStringByte = `(^$|^[a-zA-Z0-9+/\\-_]*=*$)`\n\n\t// FormatOfStringDate is a RFC3339 date format regexp, for example \"2017-07-21\".\n\tFormatOfStringDate = `^[0-9]{4}-(0[1-9]|10|11|12)-(0[1-9]|[12][0-9]|3[01])$`\n\n\t// FormatOfStringDateTime is a RFC3339 date-time format regexp, for example \"2017-07-21T17:32:28Z\".\n\tFormatOfStringDateTime = `^[0-9]{4}-(0[1-9]|10|11|12)-(0[1-9]|[12][0-9]|3[01])T([0-1][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)(\\.[0-9]+)?(Z|(\\+|-)[0-9]{2}:[0-9]{2})?$`\n)\n\nfunc init() {\n\tDefineStringFormatValidator(\"byte\", NewRegexpFormatValidator(FormatOfStringByte))\n\tDefineStringFormatValidator(\"date\", NewRegexpFormatValidator(FormatOfStringDate))\n\tDefineStringFormatValidator(\"date-time\", NewRegexpFormatValidator(FormatOfStringDateTime))\n\tDefineIntegerFormatValidator(\"int32\", NewRangeFormatValidator(int64(math.MinInt32), int64(math.MaxInt32)))\n\tDefineIntegerFormatValidator(\"int64\", NewRangeFormatValidator(int64(math.MinInt64), int64(math.MaxInt64)))\n}\n\n// DefineIPv4Format opts in ipv4 format validation on top of OAS 3 spec\nfunc DefineIPv4Format() {\n\tDefineStringFormatValidator(\"ipv4\", NewIPValidator(true))\n}\n\n// DefineIPv6Format opts in ipv6 format validation on top of OAS 3 spec\nfunc DefineIPv6Format() {\n\tDefineStringFormatValidator(\"ipv6\", NewIPValidator(false))\n}\n\ntype stringRegexpFormatValidator struct {\n\tre *regexp.Regexp\n}\n\nfunc (s stringRegexpFormatValidator) Validate(value string) error {\n\tif !s.re.MatchString(value) {\n\t\treturn fmt.Errorf(`string doesn't match pattern \"%s\"`, s.re.String())\n\t}\n\treturn nil\n}\n\ntype callbackValidator[T any] struct {\n\tfn func(T) error\n}\n\nfunc (c callbackValidator[T]) Validate(value T) error {\n\treturn c.fn(value)\n}\n\ntype rangeFormat[T int64 | float64] struct {\n\tmin, max T\n}\n\nfunc (r rangeFormat[T]) Validate(value T) error {\n\tif value < r.min || value > r.max {\n\t\treturn fmt.Errorf(\"value should be between %v and %v\", r.min, r.max)\n\t}\n\treturn nil\n}\n\n// NewRangeFormatValidator creates a new FormatValidator that validates the value is within a given range.\nfunc NewRangeFormatValidator[T int64 | float64](min, max T) FormatValidator[T] {\n\treturn rangeFormat[T]{min: min, max: max}\n}\n\n// NewRegexpFormatValidator creates a new FormatValidator that uses a regular expression to validate the value.\nfunc NewRegexpFormatValidator(pattern string) StringFormatValidator {\n\tre, err := regexp.Compile(pattern)\n\tif err != nil {\n\t\terr := fmt.Errorf(\"string regexp format has invalid pattern %q: %w\", pattern, err)\n\t\tpanic(err)\n\t}\n\treturn stringRegexpFormatValidator{re: re}\n}\n\n// NewCallbackValidator creates a new FormatValidator that uses a callback function to validate the value.\nfunc NewCallbackValidator[T any](fn func(T) error) FormatValidator[T] {\n\treturn callbackValidator[T]{fn: fn}\n}\n\n// DefineStringFormatValidator defines a custom format validator for a given string format.\nfunc DefineStringFormatValidator(name string, validator StringFormatValidator) {\n\tSchemaStringFormats[name] = validator\n}\n\n// DefineNumberFormatValidator defines a custom format validator for a given number format.\nfunc DefineNumberFormatValidator(name string, validator NumberFormatValidator) {\n\tSchemaNumberFormats[name] = validator\n}\n\n// DefineIntegerFormatValidator defines a custom format validator for a given integer format.\nfunc DefineIntegerFormatValidator(name string, validator IntegerFormatValidator) {\n\tSchemaIntegerFormats[name] = validator\n}\n\n// DefineStringFormat defines a regexp pattern for a given string format\n//\n// Deprecated: Use openapi3.DefineStringFormatValidator(name, NewRegexpFormatValidator(pattern)) instead.\nfunc DefineStringFormat(name string, pattern string) {\n\tDefineStringFormatValidator(name, NewRegexpFormatValidator(pattern))\n}\n\n// DefineStringFormatCallback defines a callback function for a given string format\n//\n// Deprecated: Use openapi3.DefineStringFormatValidator(name, NewCallbackValidator(fn)) instead.\nfunc DefineStringFormatCallback(name string, callback func(string) error) {\n\tDefineStringFormatValidator(name, NewCallbackValidator(callback))\n}\n\n// NewIPValidator creates a new FormatValidator that validates the value is an IP address.\nfunc NewIPValidator(isIPv4 bool) FormatValidator[string] {\n\treturn callbackValidator[string]{fn: func(ip string) error {\n\t\taddr, err := netip.ParseAddr(ip)\n\t\tif err != nil {\n\t\t\treturn &SchemaError{\n\t\t\t\tValue:  ip,\n\t\t\t\tReason: \"Not an IP address\",\n\t\t\t}\n\t\t}\n\t\tif isIPv4 && !addr.Is4() {\n\t\t\treturn &SchemaError{\n\t\t\t\tValue:  ip,\n\t\t\t\tReason: \"Not an IPv4 address (it's IPv6)\",\n\t\t\t}\n\t\t}\n\t\tif !isIPv4 && !addr.Is6() {\n\t\t\treturn &SchemaError{\n\t\t\t\tValue:  ip,\n\t\t\t\tReason: \"Not an IPv6 address (it's IPv4)\",\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}}\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/schema_pattern.go",
    "content": "package openapi3\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n)\n\nvar patRewriteCodepoints = regexp.MustCompile(`(?P<replaced_with_slash_x>\\\\u)(?P<code>[0-9A-F]{4})`)\n\n// See https://pkg.go.dev/regexp/syntax\nfunc intoGoRegexp(re string) string {\n\treturn patRewriteCodepoints.ReplaceAllString(re, `\\x{${code}}`)\n}\n\n// NOTE: racey WRT [writes to schema.Pattern] vs [reads schema.Pattern then writes to compiledPatterns]\nfunc (schema *Schema) compilePattern(c RegexCompilerFunc) (cp RegexMatcher, err error) {\n\tpattern := schema.Pattern\n\tif c != nil {\n\t\tcp, err = c(pattern)\n\t} else {\n\t\tcp, err = regexp.Compile(intoGoRegexp(pattern))\n\t}\n\tif err != nil {\n\t\terr = &SchemaError{\n\t\t\tSchema:      schema,\n\t\t\tSchemaField: \"pattern\",\n\t\t\tOrigin:      err,\n\t\t\tReason:      fmt.Sprintf(\"cannot compile pattern %q: %v\", pattern, err),\n\t\t}\n\t\treturn\n\t}\n\n\tvar _ bool = compiledPatterns.CompareAndSwap(pattern, nil, cp)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/schema_validation_settings.go",
    "content": "package openapi3\n\nimport (\n\t\"sync\"\n)\n\n// SchemaValidationOption describes options a user has when validating request / response bodies.\ntype SchemaValidationOption func(*schemaValidationSettings)\n\ntype RegexCompilerFunc func(expr string) (RegexMatcher, error)\n\ntype RegexMatcher interface {\n\tMatchString(s string) bool\n}\n\ntype schemaValidationSettings struct {\n\tfailfast                    bool\n\tmultiError                  bool\n\tasreq, asrep                bool // exclusive (XOR) fields\n\tformatValidationEnabled     bool\n\tpatternValidationDisabled   bool\n\treadOnlyValidationDisabled  bool\n\twriteOnlyValidationDisabled bool\n\n\tregexCompiler RegexCompilerFunc\n\n\tonceSettingDefaults sync.Once\n\tdefaultsSet         func()\n\n\tcustomizeMessageError func(err *SchemaError) string\n}\n\n// FailFast returns schema validation errors quicker.\nfunc FailFast() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.failfast = true }\n}\n\nfunc MultiErrors() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.multiError = true }\n}\n\nfunc VisitAsRequest() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.asreq, s.asrep = true, false }\n}\n\nfunc VisitAsResponse() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.asreq, s.asrep = false, true }\n}\n\n// EnableFormatValidation setting makes Validate not return an error when validating documents that mention schema formats that are not defined by the OpenAPIv3 specification.\nfunc EnableFormatValidation() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.formatValidationEnabled = true }\n}\n\n// DisablePatternValidation setting makes Validate not return an error when validating patterns that are not supported by the Go regexp engine.\nfunc DisablePatternValidation() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.patternValidationDisabled = true }\n}\n\n// DisableReadOnlyValidation setting makes Validate not return an error when validating properties marked as read-only\nfunc DisableReadOnlyValidation() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.readOnlyValidationDisabled = true }\n}\n\n// DisableWriteOnlyValidation setting makes Validate not return an error when validating properties marked as write-only\nfunc DisableWriteOnlyValidation() SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.writeOnlyValidationDisabled = true }\n}\n\n// DefaultsSet executes the given callback (once) IFF schema validation set default values.\nfunc DefaultsSet(f func()) SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.defaultsSet = f }\n}\n\n// SetSchemaErrorMessageCustomizer allows to override the schema error message.\n// If the passed function returns an empty string, it returns to the previous Error() implementation.\nfunc SetSchemaErrorMessageCustomizer(f func(err *SchemaError) string) SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.customizeMessageError = f }\n}\n\n// SetSchemaRegexCompiler allows to override the regex implementation used to validate field \"pattern\".\nfunc SetSchemaRegexCompiler(c RegexCompilerFunc) SchemaValidationOption {\n\treturn func(s *schemaValidationSettings) { s.regexCompiler = c }\n}\n\nfunc newSchemaValidationSettings(opts ...SchemaValidationOption) *schemaValidationSettings {\n\tsettings := &schemaValidationSettings{}\n\tfor _, opt := range opts {\n\t\topt(settings)\n\t}\n\treturn settings\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/security_requirements.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n)\n\ntype SecurityRequirements []SecurityRequirement\n\nfunc NewSecurityRequirements() *SecurityRequirements {\n\treturn &SecurityRequirements{}\n}\n\nfunc (srs *SecurityRequirements) With(securityRequirement SecurityRequirement) *SecurityRequirements {\n\t*srs = append(*srs, securityRequirement)\n\treturn srs\n}\n\n// Validate returns an error if SecurityRequirements does not comply with the OpenAPI spec.\nfunc (srs SecurityRequirements) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tfor _, security := range srs {\n\t\tif err := security.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// SecurityRequirement is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-requirement-object\ntype SecurityRequirement map[string][]string\n\nfunc NewSecurityRequirement() SecurityRequirement {\n\treturn make(SecurityRequirement)\n}\n\nfunc (security SecurityRequirement) Authenticate(provider string, scopes ...string) SecurityRequirement {\n\tif len(scopes) == 0 {\n\t\tscopes = []string{} // Forces the variable to be encoded as an array instead of null\n\t}\n\tsecurity[provider] = scopes\n\treturn security\n}\n\n// Validate returns an error if SecurityRequirement does not comply with the OpenAPI spec.\nfunc (security *SecurityRequirement) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\treturn nil\n}\n\n// UnmarshalJSON sets SecurityRequirement to a copy of data.\nfunc (security *SecurityRequirement) UnmarshalJSON(data []byte) (err error) {\n\t*security, _, err = unmarshalStringMap[[]string](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/security_scheme.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n)\n\n// SecurityScheme is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-scheme-object\ntype SecurityScheme struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tType             string      `json:\"type,omitempty\" yaml:\"type,omitempty\"`\n\tDescription      string      `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tName             string      `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tIn               string      `json:\"in,omitempty\" yaml:\"in,omitempty\"`\n\tScheme           string      `json:\"scheme,omitempty\" yaml:\"scheme,omitempty\"`\n\tBearerFormat     string      `json:\"bearerFormat,omitempty\" yaml:\"bearerFormat,omitempty\"`\n\tFlows            *OAuthFlows `json:\"flows,omitempty\" yaml:\"flows,omitempty\"`\n\tOpenIdConnectUrl string      `json:\"openIdConnectUrl,omitempty\" yaml:\"openIdConnectUrl,omitempty\"`\n}\n\nfunc NewSecurityScheme() *SecurityScheme {\n\treturn &SecurityScheme{}\n}\n\nfunc NewCSRFSecurityScheme() *SecurityScheme {\n\treturn &SecurityScheme{\n\t\tType: \"apiKey\",\n\t\tIn:   \"header\",\n\t\tName: \"X-XSRF-TOKEN\",\n\t}\n}\n\nfunc NewOIDCSecurityScheme(oidcUrl string) *SecurityScheme {\n\treturn &SecurityScheme{\n\t\tType:             \"openIdConnect\",\n\t\tOpenIdConnectUrl: oidcUrl,\n\t}\n}\n\nfunc NewJWTSecurityScheme() *SecurityScheme {\n\treturn &SecurityScheme{\n\t\tType:         \"http\",\n\t\tScheme:       \"bearer\",\n\t\tBearerFormat: \"JWT\",\n\t}\n}\n\n// MarshalJSON returns the JSON encoding of SecurityScheme.\nfunc (ss SecurityScheme) MarshalJSON() ([]byte, error) {\n\tx, err := ss.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of SecurityScheme.\nfunc (ss SecurityScheme) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 8+len(ss.Extensions))\n\tfor k, v := range ss.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := ss.Type; x != \"\" {\n\t\tm[\"type\"] = x\n\t}\n\tif x := ss.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := ss.Name; x != \"\" {\n\t\tm[\"name\"] = x\n\t}\n\tif x := ss.In; x != \"\" {\n\t\tm[\"in\"] = x\n\t}\n\tif x := ss.Scheme; x != \"\" {\n\t\tm[\"scheme\"] = x\n\t}\n\tif x := ss.BearerFormat; x != \"\" {\n\t\tm[\"bearerFormat\"] = x\n\t}\n\tif x := ss.Flows; x != nil {\n\t\tm[\"flows\"] = x\n\t}\n\tif x := ss.OpenIdConnectUrl; x != \"\" {\n\t\tm[\"openIdConnectUrl\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets SecurityScheme to a copy of data.\nfunc (ss *SecurityScheme) UnmarshalJSON(data []byte) error {\n\ttype SecuritySchemeBis SecurityScheme\n\tvar x SecuritySchemeBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"type\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"in\")\n\tdelete(x.Extensions, \"scheme\")\n\tdelete(x.Extensions, \"bearerFormat\")\n\tdelete(x.Extensions, \"flows\")\n\tdelete(x.Extensions, \"openIdConnectUrl\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*ss = SecurityScheme(x)\n\treturn nil\n}\n\nfunc (ss *SecurityScheme) WithType(value string) *SecurityScheme {\n\tss.Type = value\n\treturn ss\n}\n\nfunc (ss *SecurityScheme) WithDescription(value string) *SecurityScheme {\n\tss.Description = value\n\treturn ss\n}\n\nfunc (ss *SecurityScheme) WithName(value string) *SecurityScheme {\n\tss.Name = value\n\treturn ss\n}\n\nfunc (ss *SecurityScheme) WithIn(value string) *SecurityScheme {\n\tss.In = value\n\treturn ss\n}\n\nfunc (ss *SecurityScheme) WithScheme(value string) *SecurityScheme {\n\tss.Scheme = value\n\treturn ss\n}\n\nfunc (ss *SecurityScheme) WithBearerFormat(value string) *SecurityScheme {\n\tss.BearerFormat = value\n\treturn ss\n}\n\n// Validate returns an error if SecurityScheme does not comply with the OpenAPI spec.\nfunc (ss *SecurityScheme) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\thasIn := false\n\thasBearerFormat := false\n\thasFlow := false\n\tswitch ss.Type {\n\tcase \"apiKey\":\n\t\thasIn = true\n\tcase \"http\":\n\t\tscheme := ss.Scheme\n\t\tswitch scheme {\n\t\tcase \"bearer\":\n\t\t\thasBearerFormat = true\n\t\tcase \"basic\", \"negotiate\", \"digest\":\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"security scheme of type 'http' has invalid 'scheme' value %q\", scheme)\n\t\t}\n\tcase \"oauth2\":\n\t\thasFlow = true\n\tcase \"openIdConnect\":\n\t\tif ss.OpenIdConnectUrl == \"\" {\n\t\t\treturn fmt.Errorf(\"no OIDC URL found for openIdConnect security scheme %q\", ss.Name)\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\"security scheme 'type' can't be %q\", ss.Type)\n\t}\n\n\t// Validate \"in\" and \"name\"\n\tif hasIn {\n\t\tswitch ss.In {\n\t\tcase \"query\", \"header\", \"cookie\":\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"security scheme of type 'apiKey' should have 'in'. It can be 'query', 'header' or 'cookie', not %q\", ss.In)\n\t\t}\n\t\tif ss.Name == \"\" {\n\t\t\treturn errors.New(\"security scheme of type 'apiKey' should have 'name'\")\n\t\t}\n\t} else if len(ss.In) > 0 {\n\t\treturn fmt.Errorf(\"security scheme of type %q can't have 'in'\", ss.Type)\n\t} else if len(ss.Name) > 0 {\n\t\treturn fmt.Errorf(\"security scheme of type %q can't have 'name'\", ss.Type)\n\t}\n\n\t// Validate \"format\"\n\t// \"bearerFormat\" is an arbitrary string so we only check if the scheme supports it\n\tif !hasBearerFormat && len(ss.BearerFormat) > 0 {\n\t\treturn fmt.Errorf(\"security scheme of type %q can't have 'bearerFormat'\", ss.Type)\n\t}\n\n\t// Validate \"flow\"\n\tif hasFlow {\n\t\tflow := ss.Flows\n\t\tif flow == nil {\n\t\t\treturn fmt.Errorf(\"security scheme of type %q should have 'flows'\", ss.Type)\n\t\t}\n\t\tif err := flow.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"security scheme 'flow' is invalid: %w\", err)\n\t\t}\n\t} else if ss.Flows != nil {\n\t\treturn fmt.Errorf(\"security scheme of type %q can't have 'flows'\", ss.Type)\n\t}\n\n\treturn validateExtensions(ctx, ss.Extensions)\n}\n\n// OAuthFlows is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flows-object\ntype OAuthFlows struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tImplicit          *OAuthFlow `json:\"implicit,omitempty\" yaml:\"implicit,omitempty\"`\n\tPassword          *OAuthFlow `json:\"password,omitempty\" yaml:\"password,omitempty\"`\n\tClientCredentials *OAuthFlow `json:\"clientCredentials,omitempty\" yaml:\"clientCredentials,omitempty\"`\n\tAuthorizationCode *OAuthFlow `json:\"authorizationCode,omitempty\" yaml:\"authorizationCode,omitempty\"`\n}\n\ntype oAuthFlowType int\n\nconst (\n\toAuthFlowTypeImplicit oAuthFlowType = iota\n\toAuthFlowTypePassword\n\toAuthFlowTypeClientCredentials\n\toAuthFlowAuthorizationCode\n)\n\n// MarshalJSON returns the JSON encoding of OAuthFlows.\nfunc (flows OAuthFlows) MarshalJSON() ([]byte, error) {\n\tx, err := flows.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of OAuthFlows.\nfunc (flows OAuthFlows) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 4+len(flows.Extensions))\n\tfor k, v := range flows.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := flows.Implicit; x != nil {\n\t\tm[\"implicit\"] = x\n\t}\n\tif x := flows.Password; x != nil {\n\t\tm[\"password\"] = x\n\t}\n\tif x := flows.ClientCredentials; x != nil {\n\t\tm[\"clientCredentials\"] = x\n\t}\n\tif x := flows.AuthorizationCode; x != nil {\n\t\tm[\"authorizationCode\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets OAuthFlows to a copy of data.\nfunc (flows *OAuthFlows) UnmarshalJSON(data []byte) error {\n\ttype OAuthFlowsBis OAuthFlows\n\tvar x OAuthFlowsBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"implicit\")\n\tdelete(x.Extensions, \"password\")\n\tdelete(x.Extensions, \"clientCredentials\")\n\tdelete(x.Extensions, \"authorizationCode\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*flows = OAuthFlows(x)\n\treturn nil\n}\n\n// Validate returns an error if OAuthFlows does not comply with the OpenAPI spec.\nfunc (flows *OAuthFlows) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif v := flows.Implicit; v != nil {\n\t\tif err := v.validate(ctx, oAuthFlowTypeImplicit, opts...); err != nil {\n\t\t\treturn fmt.Errorf(\"the OAuth flow 'implicit' is invalid: %w\", err)\n\t\t}\n\t}\n\n\tif v := flows.Password; v != nil {\n\t\tif err := v.validate(ctx, oAuthFlowTypePassword, opts...); err != nil {\n\t\t\treturn fmt.Errorf(\"the OAuth flow 'password' is invalid: %w\", err)\n\t\t}\n\t}\n\n\tif v := flows.ClientCredentials; v != nil {\n\t\tif err := v.validate(ctx, oAuthFlowTypeClientCredentials, opts...); err != nil {\n\t\t\treturn fmt.Errorf(\"the OAuth flow 'clientCredentials' is invalid: %w\", err)\n\t\t}\n\t}\n\n\tif v := flows.AuthorizationCode; v != nil {\n\t\tif err := v.validate(ctx, oAuthFlowAuthorizationCode, opts...); err != nil {\n\t\t\treturn fmt.Errorf(\"the OAuth flow 'authorizationCode' is invalid: %w\", err)\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, flows.Extensions)\n}\n\n// OAuthFlow is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#oauth-flow-object\ntype OAuthFlow struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tAuthorizationURL string    `json:\"authorizationUrl,omitempty\" yaml:\"authorizationUrl,omitempty\"`\n\tTokenURL         string    `json:\"tokenUrl,omitempty\" yaml:\"tokenUrl,omitempty\"`\n\tRefreshURL       string    `json:\"refreshUrl,omitempty\" yaml:\"refreshUrl,omitempty\"`\n\tScopes           StringMap `json:\"scopes\" yaml:\"scopes\"` // required\n}\n\n// MarshalJSON returns the JSON encoding of OAuthFlow.\nfunc (flow OAuthFlow) MarshalJSON() ([]byte, error) {\n\tx, err := flow.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of OAuthFlow.\nfunc (flow OAuthFlow) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 4+len(flow.Extensions))\n\tfor k, v := range flow.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := flow.AuthorizationURL; x != \"\" {\n\t\tm[\"authorizationUrl\"] = x\n\t}\n\tif x := flow.TokenURL; x != \"\" {\n\t\tm[\"tokenUrl\"] = x\n\t}\n\tif x := flow.RefreshURL; x != \"\" {\n\t\tm[\"refreshUrl\"] = x\n\t}\n\tm[\"scopes\"] = flow.Scopes\n\treturn m, nil\n}\n\n// UnmarshalJSON sets OAuthFlow to a copy of data.\nfunc (flow *OAuthFlow) UnmarshalJSON(data []byte) error {\n\ttype OAuthFlowBis OAuthFlow\n\tvar x OAuthFlowBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"authorizationUrl\")\n\tdelete(x.Extensions, \"tokenUrl\")\n\tdelete(x.Extensions, \"refreshUrl\")\n\tdelete(x.Extensions, \"scopes\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*flow = OAuthFlow(x)\n\treturn nil\n}\n\n// Validate returns an error if OAuthFlows does not comply with the OpenAPI spec.\nfunc (flow *OAuthFlow) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif v := flow.RefreshURL; v != \"\" {\n\t\tif _, err := url.Parse(v); err != nil {\n\t\t\treturn fmt.Errorf(\"field 'refreshUrl' is invalid: %w\", err)\n\t\t}\n\t}\n\n\tif flow.Scopes == nil {\n\t\treturn errors.New(\"field 'scopes' is missing\")\n\t}\n\n\treturn validateExtensions(ctx, flow.Extensions)\n}\n\nfunc (flow *OAuthFlow) validate(ctx context.Context, typ oAuthFlowType, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\ttypeIn := func(types ...oAuthFlowType) bool {\n\t\tfor _, ty := range types {\n\t\t\tif ty == typ {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\n\tif in := typeIn(oAuthFlowTypeImplicit, oAuthFlowAuthorizationCode); true {\n\t\tswitch {\n\t\tcase flow.AuthorizationURL == \"\" && in:\n\t\t\treturn errors.New(\"field 'authorizationUrl' is empty or missing\")\n\t\tcase flow.AuthorizationURL != \"\" && !in:\n\t\t\treturn errors.New(\"field 'authorizationUrl' should not be set\")\n\t\tcase flow.AuthorizationURL != \"\":\n\t\t\tif _, err := url.Parse(flow.AuthorizationURL); err != nil {\n\t\t\t\treturn fmt.Errorf(\"field 'authorizationUrl' is invalid: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif in := typeIn(oAuthFlowTypePassword, oAuthFlowTypeClientCredentials, oAuthFlowAuthorizationCode); true {\n\t\tswitch {\n\t\tcase flow.TokenURL == \"\" && in:\n\t\t\treturn errors.New(\"field 'tokenUrl' is empty or missing\")\n\t\tcase flow.TokenURL != \"\" && !in:\n\t\t\treturn errors.New(\"field 'tokenUrl' should not be set\")\n\t\tcase flow.TokenURL != \"\":\n\t\t\tif _, err := url.Parse(flow.TokenURL); err != nil {\n\t\t\t\treturn fmt.Errorf(\"field 'tokenUrl' is invalid: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn flow.Validate(ctx, opts...)\n}\n\n// UnmarshalJSON sets SecuritySchemes to a copy of data.\nfunc (securitySchemes *SecuritySchemes) UnmarshalJSON(data []byte) (err error) {\n\t*securitySchemes, _, err = unmarshalStringMapP[SecuritySchemeRef](data)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/serialization_method.go",
    "content": "package openapi3\n\nconst (\n\tSerializationSimple         = \"simple\"\n\tSerializationLabel          = \"label\"\n\tSerializationMatrix         = \"matrix\"\n\tSerializationForm           = \"form\"\n\tSerializationSpaceDelimited = \"spaceDelimited\"\n\tSerializationPipeDelimited  = \"pipeDelimited\"\n\tSerializationDeepObject     = \"deepObject\"\n)\n\n// SerializationMethod describes a serialization method of HTTP request's parameters and body.\ntype SerializationMethod struct {\n\tStyle   string\n\tExplode bool\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/server.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// Servers is specified by OpenAPI/Swagger standard version 3.\ntype Servers []*Server\n\n// Validate returns an error if Servers does not comply with the OpenAPI spec.\nfunc (servers Servers) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tfor _, v := range servers {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// BasePath returns the base path of the first server in the list, or /.\nfunc (servers Servers) BasePath() (string, error) {\n\tfor _, server := range servers {\n\t\treturn server.BasePath()\n\t}\n\treturn \"/\", nil\n}\n\nfunc (servers Servers) MatchURL(parsedURL *url.URL) (*Server, []string, string) {\n\trawURL := parsedURL.String()\n\tif i := strings.IndexByte(rawURL, '?'); i >= 0 {\n\t\trawURL = rawURL[:i]\n\t}\n\tfor _, server := range servers {\n\t\tpathParams, remaining, ok := server.MatchRawURL(rawURL)\n\t\tif ok {\n\t\t\treturn server, pathParams, remaining\n\t\t}\n\t}\n\treturn nil, nil, \"\"\n}\n\n// Server is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-object\ntype Server struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tURL         string                     `json:\"url\" yaml:\"url\"` // Required\n\tDescription string                     `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tVariables   map[string]*ServerVariable `json:\"variables,omitempty\" yaml:\"variables,omitempty\"`\n}\n\n// BasePath returns the base path extracted from the default values of variables, if any.\n// Assumes a valid struct (per Validate()).\nfunc (server *Server) BasePath() (string, error) {\n\tif server == nil {\n\t\treturn \"/\", nil\n\t}\n\n\turi := server.URL\n\tfor name, svar := range server.Variables {\n\t\turi = strings.ReplaceAll(uri, \"{\"+name+\"}\", svar.Default)\n\t}\n\n\tu, err := url.ParseRequestURI(uri)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif bp := u.Path; bp != \"\" {\n\t\treturn bp, nil\n\t}\n\n\treturn \"/\", nil\n}\n\n// MarshalJSON returns the JSON encoding of Server.\nfunc (server Server) MarshalJSON() ([]byte, error) {\n\tx, err := server.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Server.\nfunc (server Server) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 3+len(server.Extensions))\n\tfor k, v := range server.Extensions {\n\t\tm[k] = v\n\t}\n\tm[\"url\"] = server.URL\n\tif x := server.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := server.Variables; len(x) != 0 {\n\t\tm[\"variables\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Server to a copy of data.\nfunc (server *Server) UnmarshalJSON(data []byte) error {\n\ttype ServerBis Server\n\tvar x ServerBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"url\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"variables\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*server = Server(x)\n\treturn nil\n}\n\nfunc (server Server) ParameterNames() ([]string, error) {\n\tpattern := server.URL\n\tvar params []string\n\tfor len(pattern) > 0 {\n\t\ti := strings.IndexByte(pattern, '{')\n\t\tif i < 0 {\n\t\t\tbreak\n\t\t}\n\t\tpattern = pattern[i+1:]\n\t\ti = strings.IndexByte(pattern, '}')\n\t\tif i < 0 {\n\t\t\treturn nil, errors.New(\"missing '}'\")\n\t\t}\n\t\tparams = append(params, strings.TrimSpace(pattern[:i]))\n\t\tpattern = pattern[i+1:]\n\t}\n\treturn params, nil\n}\n\nfunc (server Server) MatchRawURL(input string) ([]string, string, bool) {\n\tpattern := server.URL\n\tvar params []string\n\tfor len(pattern) > 0 {\n\t\tc := pattern[0]\n\t\tif len(pattern) == 1 && c == '/' {\n\t\t\tbreak\n\t\t}\n\t\tif c == '{' {\n\t\t\t// Find end of pattern\n\t\t\ti := strings.IndexByte(pattern, '}')\n\t\t\tif i < 0 {\n\t\t\t\treturn nil, \"\", false\n\t\t\t}\n\t\t\tpattern = pattern[i+1:]\n\n\t\t\t// Find next matching pattern character or next '/' whichever comes first\n\t\t\tnp := -1\n\t\t\tif len(pattern) > 0 {\n\t\t\t\tnp = strings.IndexByte(input, pattern[0])\n\t\t\t}\n\t\t\tns := strings.IndexByte(input, '/')\n\n\t\t\tif np < 0 {\n\t\t\t\ti = ns\n\t\t\t} else if ns < 0 {\n\t\t\t\ti = np\n\t\t\t} else {\n\t\t\t\ti = min(np, ns)\n\t\t\t}\n\t\t\tif i < 0 {\n\t\t\t\ti = len(input)\n\t\t\t}\n\t\t\tparams = append(params, input[:i])\n\t\t\tinput = input[i:]\n\t\t\tcontinue\n\t\t}\n\t\tif len(input) == 0 || input[0] != c {\n\t\t\treturn nil, \"\", false\n\t\t}\n\t\tpattern = pattern[1:]\n\t\tinput = input[1:]\n\t}\n\tif input == \"\" {\n\t\tinput = \"/\"\n\t}\n\tif input[0] != '/' {\n\t\treturn nil, \"\", false\n\t}\n\treturn params, input, true\n}\n\n// Validate returns an error if Server does not comply with the OpenAPI spec.\nfunc (server *Server) Validate(ctx context.Context, opts ...ValidationOption) (err error) {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif server.URL == \"\" {\n\t\treturn errors.New(\"value of url must be a non-empty string\")\n\t}\n\n\topening, closing := strings.Count(server.URL, \"{\"), strings.Count(server.URL, \"}\")\n\tif opening != closing {\n\t\treturn errors.New(\"server URL has mismatched { and }\")\n\t}\n\n\tif opening != len(server.Variables) {\n\t\treturn errors.New(\"server has undeclared variables\")\n\t}\n\n\tvariables := make([]string, 0, len(server.Variables))\n\tfor name := range server.Variables {\n\t\tvariables = append(variables, name)\n\t}\n\tsort.Strings(variables)\n\tfor _, name := range variables {\n\t\tv := server.Variables[name]\n\t\tif !strings.Contains(server.URL, \"{\"+name+\"}\") {\n\t\t\treturn errors.New(\"server has undeclared variables\")\n\t\t}\n\t\tif err = v.Validate(ctx); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, server.Extensions)\n}\n\n// ServerVariable is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#server-variable-object\ntype ServerVariable struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tEnum        []string `json:\"enum,omitempty\" yaml:\"enum,omitempty\"`\n\tDefault     string   `json:\"default,omitempty\" yaml:\"default,omitempty\"`\n\tDescription string   `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of ServerVariable.\nfunc (serverVariable ServerVariable) MarshalJSON() ([]byte, error) {\n\tx, err := serverVariable.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of ServerVariable.\nfunc (serverVariable ServerVariable) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 4+len(serverVariable.Extensions))\n\tfor k, v := range serverVariable.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := serverVariable.Enum; len(x) != 0 {\n\t\tm[\"enum\"] = x\n\t}\n\tif x := serverVariable.Default; x != \"\" {\n\t\tm[\"default\"] = x\n\t}\n\tif x := serverVariable.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets ServerVariable to a copy of data.\nfunc (serverVariable *ServerVariable) UnmarshalJSON(data []byte) error {\n\ttype ServerVariableBis ServerVariable\n\tvar x ServerVariableBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"enum\")\n\tdelete(x.Extensions, \"default\")\n\tdelete(x.Extensions, \"description\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*serverVariable = ServerVariable(x)\n\treturn nil\n}\n\n// Validate returns an error if ServerVariable does not comply with the OpenAPI spec.\nfunc (serverVariable *ServerVariable) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif serverVariable.Default == \"\" {\n\t\tdata, err := serverVariable.MarshalJSON()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn fmt.Errorf(\"field default is required in %s\", data)\n\t}\n\n\treturn validateExtensions(ctx, serverVariable.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/stringmap.go",
    "content": "package openapi3\n\nimport \"encoding/json\"\n\n// StringMap is a map[string]string that ignores the origin in the underlying json representation.\ntype StringMap map[string]string\n\n// UnmarshalJSON sets StringMap to a copy of data.\nfunc (stringMap *StringMap) UnmarshalJSON(data []byte) (err error) {\n\t*stringMap, _, err = unmarshalStringMap[string](data)\n\treturn\n}\n\n// unmarshalStringMapP unmarshals given json into a map[string]*V\nfunc unmarshalStringMapP[V any](data []byte) (map[string]*V, *Origin, error) {\n\tvar m map[string]any\n\tif err := json.Unmarshal(data, &m); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\torigin, err := popOrigin(m, originKey)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tresult := make(map[string]*V, len(m))\n\tfor k, v := range m {\n\t\tvalue, err := deepCast[V](v)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tresult[k] = value\n\t}\n\n\treturn result, origin, nil\n}\n\n// unmarshalStringMap unmarshals given json into a map[string]V\nfunc unmarshalStringMap[V any](data []byte) (map[string]V, *Origin, error) {\n\tvar m map[string]any\n\tif err := json.Unmarshal(data, &m); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\torigin, err := popOrigin(m, originKey)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tresult := make(map[string]V, len(m))\n\tfor k, v := range m {\n\t\tvalue, err := deepCast[V](v)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tresult[k] = *value\n\t}\n\n\treturn result, origin, nil\n}\n\n// deepCast casts any value to a value of type V.\nfunc deepCast[V any](value any) (*V, error) {\n\tdata, err := json.Marshal(value)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar result V\n\tif err = json.Unmarshal(data, &result); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &result, nil\n}\n\n// popOrigin removes the origin from the map and returns it.\nfunc popOrigin(m map[string]any, key string) (*Origin, error) {\n\tif !IncludeOrigin {\n\t\treturn nil, nil\n\t}\n\n\torigin, err := deepCast[Origin](m[key])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdelete(m, key)\n\treturn origin, nil\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/tag.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// Tags is specified by OpenAPI/Swagger 3.0 standard.\ntype Tags []*Tag\n\nfunc (tags Tags) Get(name string) *Tag {\n\tfor _, tag := range tags {\n\t\tif tag.Name == name {\n\t\t\treturn tag\n\t\t}\n\t}\n\treturn nil\n}\n\n// Validate returns an error if Tags does not comply with the OpenAPI spec.\nfunc (tags Tags) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tfor _, v := range tags {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Tag is specified by OpenAPI/Swagger 3.0 standard.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#tag-object\ntype Tag struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tName         string        `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tDescription  string        `json:\"description,omitempty\" yaml:\"description,omitempty\"`\n\tExternalDocs *ExternalDocs `json:\"externalDocs,omitempty\" yaml:\"externalDocs,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of Tag.\nfunc (t Tag) MarshalJSON() ([]byte, error) {\n\tx, err := t.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of Tag.\nfunc (t Tag) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 3+len(t.Extensions))\n\tfor k, v := range t.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := t.Name; x != \"\" {\n\t\tm[\"name\"] = x\n\t}\n\tif x := t.Description; x != \"\" {\n\t\tm[\"description\"] = x\n\t}\n\tif x := t.ExternalDocs; x != nil {\n\t\tm[\"externalDocs\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets Tag to a copy of data.\nfunc (t *Tag) UnmarshalJSON(data []byte) error {\n\ttype TagBis Tag\n\tvar x TagBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"description\")\n\tdelete(x.Extensions, \"externalDocs\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*t = Tag(x)\n\treturn nil\n}\n\n// Validate returns an error if Tag does not comply with the OpenAPI spec.\nfunc (t *Tag) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\tif v := t.ExternalDocs; v != nil {\n\t\tif err := v.Validate(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid external docs: %w\", err)\n\t\t}\n\t}\n\n\treturn validateExtensions(ctx, t.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/validation_options.go",
    "content": "package openapi3\n\nimport \"context\"\n\n// ValidationOption allows the modification of how the OpenAPI document is validated.\ntype ValidationOption func(options *ValidationOptions)\n\n// ValidationOptions provides configuration for validating OpenAPI documents.\ntype ValidationOptions struct {\n\texamplesValidationAsReq, examplesValidationAsRes bool\n\texamplesValidationDisabled                       bool\n\tschemaDefaultsValidationDisabled                 bool\n\tschemaFormatValidationEnabled                    bool\n\tschemaPatternValidationDisabled                  bool\n\tschemaExtensionsInRefProhibited                  bool\n\tregexCompilerFunc                                RegexCompilerFunc\n\textraSiblingFieldsAllowed                        map[string]struct{}\n}\n\ntype validationOptionsKey struct{}\n\n// AllowExtraSiblingFields called as AllowExtraSiblingFields(\"description\") makes Validate not return an error when said field appears next to a $ref.\nfunc AllowExtraSiblingFields(fields ...string) ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\tif options.extraSiblingFieldsAllowed == nil && len(fields) != 0 {\n\t\t\toptions.extraSiblingFieldsAllowed = make(map[string]struct{}, len(fields))\n\t\t}\n\t\tfor _, field := range fields {\n\t\t\toptions.extraSiblingFieldsAllowed[field] = struct{}{}\n\t\t}\n\t}\n}\n\n// EnableSchemaFormatValidation makes Validate not return an error when validating documents that mention schema formats that are not defined by the OpenAPIv3 specification.\n// By default, schema format validation is disabled.\nfunc EnableSchemaFormatValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaFormatValidationEnabled = true\n\t}\n}\n\n// DisableSchemaFormatValidation does the opposite of EnableSchemaFormatValidation.\n// By default, schema format validation is disabled.\nfunc DisableSchemaFormatValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaFormatValidationEnabled = false\n\t}\n}\n\n// EnableSchemaPatternValidation does the opposite of DisableSchemaPatternValidation.\n// By default, schema pattern validation is enabled.\nfunc EnableSchemaPatternValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaPatternValidationDisabled = false\n\t}\n}\n\n// DisableSchemaPatternValidation makes Validate not return an error when validating patterns that are not supported by the Go regexp engine.\nfunc DisableSchemaPatternValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaPatternValidationDisabled = true\n\t}\n}\n\n// EnableSchemaDefaultsValidation does the opposite of DisableSchemaDefaultsValidation.\n// By default, schema default values are validated against their schema.\nfunc EnableSchemaDefaultsValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaDefaultsValidationDisabled = false\n\t}\n}\n\n// DisableSchemaDefaultsValidation disables schemas' default field validation.\n// By default, schema default values are validated against their schema.\nfunc DisableSchemaDefaultsValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaDefaultsValidationDisabled = true\n\t}\n}\n\n// EnableExamplesValidation does the opposite of DisableExamplesValidation.\n// By default, all schema examples are validated.\nfunc EnableExamplesValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.examplesValidationDisabled = false\n\t}\n}\n\n// DisableExamplesValidation disables all example schema validation.\n// By default, all schema examples are validated.\nfunc DisableExamplesValidation() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.examplesValidationDisabled = true\n\t}\n}\n\n// AllowExtensionsWithRef allows extensions (fields starting with 'x-')\n// as siblings for $ref fields. This is the default.\n// Non-extension fields are prohibited unless allowed explicitly with the\n// AllowExtraSiblingFields option.\nfunc AllowExtensionsWithRef() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaExtensionsInRefProhibited = false\n\t}\n}\n\n// ProhibitExtensionsWithRef causes the validation to return an\n// error if extensions (fields starting with 'x-') are found as\n// siblings for $ref fields. Non-extension fields are prohibited\n// unless allowed explicitly with the AllowExtraSiblingFields option.\nfunc ProhibitExtensionsWithRef() ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.schemaExtensionsInRefProhibited = true\n\t}\n}\n\n// SetRegexCompiler allows to override the regex implementation used to validate\n// field \"pattern\".\nfunc SetRegexCompiler(c RegexCompilerFunc) ValidationOption {\n\treturn func(options *ValidationOptions) {\n\t\toptions.regexCompilerFunc = c\n\t}\n}\n\n// WithValidationOptions allows adding validation options to a context object that can be used when validating any OpenAPI type.\nfunc WithValidationOptions(ctx context.Context, opts ...ValidationOption) context.Context {\n\tif len(opts) == 0 {\n\t\treturn ctx\n\t}\n\toptions := &ValidationOptions{}\n\tfor _, opt := range opts {\n\t\topt(options)\n\t}\n\treturn context.WithValue(ctx, validationOptionsKey{}, options)\n}\n\nfunc getValidationOptions(ctx context.Context) *ValidationOptions {\n\tif options, ok := ctx.Value(validationOptionsKey{}).(*ValidationOptions); ok {\n\t\treturn options\n\t}\n\treturn &ValidationOptions{}\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/visited.go",
    "content": "package openapi3\n\nfunc newVisited() visitedComponent {\n\treturn visitedComponent{\n\t\theader: make(map[*Header]struct{}),\n\t\tschema: make(map[*Schema]struct{}),\n\t}\n}\n\ntype visitedComponent struct {\n\theader map[*Header]struct{}\n\tschema map[*Schema]struct{}\n}\n\n// resetVisited clears visitedComponent map\n// should be called before recursion over doc *T\nfunc (doc *T) resetVisited() {\n\tdoc.visited = newVisited()\n}\n\n// isVisitedHeader returns `true` if the *Header pointer was already visited\n// otherwise it returns `false`\nfunc (doc *T) isVisitedHeader(h *Header) bool {\n\tif _, ok := doc.visited.header[h]; ok {\n\t\treturn true\n\t}\n\n\tdoc.visited.header[h] = struct{}{}\n\treturn false\n}\n\n// isVisitedHeader returns `true` if the *Schema pointer was already visited\n// otherwise it returns `false`\nfunc (doc *T) isVisitedSchema(s *Schema) bool {\n\tif _, ok := doc.visited.schema[s]; ok {\n\t\treturn true\n\t}\n\n\tdoc.visited.schema[s] = struct{}{}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/getkin/kin-openapi/openapi3/xml.go",
    "content": "package openapi3\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n)\n\n// XML is specified by OpenAPI/Swagger standard version 3.\n// See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#xml-object\ntype XML struct {\n\tExtensions map[string]any `json:\"-\" yaml:\"-\"`\n\tOrigin     *Origin        `json:\"__origin__,omitempty\" yaml:\"__origin__,omitempty\"`\n\n\tName      string `json:\"name,omitempty\" yaml:\"name,omitempty\"`\n\tNamespace string `json:\"namespace,omitempty\" yaml:\"namespace,omitempty\"`\n\tPrefix    string `json:\"prefix,omitempty\" yaml:\"prefix,omitempty\"`\n\tAttribute bool   `json:\"attribute,omitempty\" yaml:\"attribute,omitempty\"`\n\tWrapped   bool   `json:\"wrapped,omitempty\" yaml:\"wrapped,omitempty\"`\n}\n\n// MarshalJSON returns the JSON encoding of XML.\nfunc (xml XML) MarshalJSON() ([]byte, error) {\n\tx, err := xml.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(x)\n}\n\n// MarshalYAML returns the YAML encoding of XML.\nfunc (xml XML) MarshalYAML() (any, error) {\n\tm := make(map[string]any, 5+len(xml.Extensions))\n\tfor k, v := range xml.Extensions {\n\t\tm[k] = v\n\t}\n\tif x := xml.Name; x != \"\" {\n\t\tm[\"name\"] = x\n\t}\n\tif x := xml.Namespace; x != \"\" {\n\t\tm[\"namespace\"] = x\n\t}\n\tif x := xml.Prefix; x != \"\" {\n\t\tm[\"prefix\"] = x\n\t}\n\tif x := xml.Attribute; x {\n\t\tm[\"attribute\"] = x\n\t}\n\tif x := xml.Wrapped; x {\n\t\tm[\"wrapped\"] = x\n\t}\n\treturn m, nil\n}\n\n// UnmarshalJSON sets XML to a copy of data.\nfunc (xml *XML) UnmarshalJSON(data []byte) error {\n\ttype XMLBis XML\n\tvar x XMLBis\n\tif err := json.Unmarshal(data, &x); err != nil {\n\t\treturn unmarshalError(err)\n\t}\n\t_ = json.Unmarshal(data, &x.Extensions)\n\tdelete(x.Extensions, originKey)\n\tdelete(x.Extensions, \"name\")\n\tdelete(x.Extensions, \"namespace\")\n\tdelete(x.Extensions, \"prefix\")\n\tdelete(x.Extensions, \"attribute\")\n\tdelete(x.Extensions, \"wrapped\")\n\tif len(x.Extensions) == 0 {\n\t\tx.Extensions = nil\n\t}\n\t*xml = XML(x)\n\treturn nil\n}\n\n// Validate returns an error if XML does not comply with the OpenAPI spec.\nfunc (xml *XML) Validate(ctx context.Context, opts ...ValidationOption) error {\n\tctx = WithValidationOptions(ctx, opts...)\n\n\treturn validateExtensions(ctx, xml.Extensions)\n}\n"
  },
  {
    "path": "vendor/github.com/ghodss/yaml/.gitignore",
    "content": "# OSX leaves these everywhere on SMB shares\n._*\n\n# Eclipse files\n.classpath\n.project\n.settings/**\n\n# Emacs save files\n*~\n\n# Vim-related files\n[._]*.s[a-w][a-z]\n[._]s[a-w][a-z]\n*.un~\nSession.vim\n.netrwhist\n\n# Go test binaries\n*.test\n"
  },
  {
    "path": "vendor/github.com/ghodss/yaml/.travis.yml",
    "content": "language: go\ngo:\n  - 1.3\n  - 1.4\nscript:\n  - go test\n  - go build\n"
  },
  {
    "path": "vendor/github.com/ghodss/yaml/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Sam Ghods\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\n\nCopyright (c) 2012 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/ghodss/yaml/README.md",
    "content": "# YAML marshaling and unmarshaling support for Go\n\n[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml)\n\n## Introduction\n\nA wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs.\n\nIn short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/).\n\n## Compatibility\n\nThis package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility).\n\n## Caveats\n\n**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example:\n\n```\nBAD:\n\texampleKey: !!binary gIGC\n\nGOOD:\n\texampleKey: gIGC\n... and decode the base64 data in your code.\n```\n\n**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys.\n\n## Installation and usage\n\nTo install, run:\n\n```\n$ go get github.com/ghodss/yaml\n```\n\nAnd import using:\n\n```\nimport \"github.com/ghodss/yaml\"\n```\n\nUsage is very similar to the JSON library:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/ghodss/yaml\"\n)\n\ntype Person struct {\n\tName string `json:\"name\"` // Affects YAML field names too.\n\tAge  int    `json:\"age\"`\n}\n\nfunc main() {\n\t// Marshal a Person struct to YAML.\n\tp := Person{\"John\", 30}\n\ty, err := yaml.Marshal(p)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(string(y))\n\t/* Output:\n\tage: 30\n\tname: John\n\t*/\n\n\t// Unmarshal the YAML back into a Person struct.\n\tvar p2 Person\n\terr = yaml.Unmarshal(y, &p2)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(p2)\n\t/* Output:\n\t{John 30}\n\t*/\n}\n```\n\n`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/ghodss/yaml\"\n)\n\nfunc main() {\n\tj := []byte(`{\"name\": \"John\", \"age\": 30}`)\n\ty, err := yaml.JSONToYAML(j)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(string(y))\n\t/* Output:\n\tname: John\n\tage: 30\n\t*/\n\tj2, err := yaml.YAMLToJSON(y)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(string(j2))\n\t/* Output:\n\t{\"age\":30,\"name\":\"John\"}\n\t*/\n}\n```\n"
  },
  {
    "path": "vendor/github.com/ghodss/yaml/fields.go",
    "content": "// Copyright 2013 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.\npackage yaml\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\n// indirect walks down v allocating pointers as needed,\n// until it gets to a non-pointer.\n// if it encounters an Unmarshaler, indirect stops and returns that.\n// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.\nfunc indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {\n\t// If v is a named type and is addressable,\n\t// start with its address, so that if the type has pointer methods,\n\t// we find them.\n\tif v.Kind() != reflect.Ptr && v.Type().Name() != \"\" && v.CanAddr() {\n\t\tv = v.Addr()\n\t}\n\tfor {\n\t\t// Load value from interface, but only if the result will be\n\t\t// usefully addressable.\n\t\tif v.Kind() == reflect.Interface && !v.IsNil() {\n\t\t\te := v.Elem()\n\t\t\tif e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {\n\t\t\t\tv = e\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif v.Kind() != reflect.Ptr {\n\t\t\tbreak\n\t\t}\n\n\t\tif v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {\n\t\t\tbreak\n\t\t}\n\t\tif v.IsNil() {\n\t\t\tif v.CanSet() {\n\t\t\t\tv.Set(reflect.New(v.Type().Elem()))\n\t\t\t} else {\n\t\t\t\tv = reflect.New(v.Type().Elem())\n\t\t\t}\n\t\t}\n\t\tif v.Type().NumMethod() > 0 {\n\t\t\tif u, ok := v.Interface().(json.Unmarshaler); ok {\n\t\t\t\treturn u, nil, reflect.Value{}\n\t\t\t}\n\t\t\tif u, ok := v.Interface().(encoding.TextUnmarshaler); ok {\n\t\t\t\treturn nil, u, reflect.Value{}\n\t\t\t}\n\t\t}\n\t\tv = v.Elem()\n\t}\n\treturn nil, nil, v\n}\n\n// A field represents a single field found in a struct.\ntype field struct {\n\tname      string\n\tnameBytes []byte                 // []byte(name)\n\tequalFold func(s, t []byte) bool // bytes.EqualFold or equivalent\n\n\ttag       bool\n\tindex     []int\n\ttyp       reflect.Type\n\tomitEmpty bool\n\tquoted    bool\n}\n\nfunc fillField(f field) field {\n\tf.nameBytes = []byte(f.name)\n\tf.equalFold = foldFunc(f.nameBytes)\n\treturn f\n}\n\n// byName sorts field by name, breaking ties with depth,\n// then breaking ties with \"name came from json tag\", then\n// breaking ties with index sequence.\ntype byName []field\n\nfunc (x byName) Len() int { return len(x) }\n\nfunc (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byName) Less(i, j int) bool {\n\tif x[i].name != x[j].name {\n\t\treturn x[i].name < x[j].name\n\t}\n\tif len(x[i].index) != len(x[j].index) {\n\t\treturn len(x[i].index) < len(x[j].index)\n\t}\n\tif x[i].tag != x[j].tag {\n\t\treturn x[i].tag\n\t}\n\treturn byIndex(x).Less(i, j)\n}\n\n// byIndex sorts field by index sequence.\ntype byIndex []field\n\nfunc (x byIndex) Len() int { return len(x) }\n\nfunc (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byIndex) Less(i, j int) bool {\n\tfor k, xik := range x[i].index {\n\t\tif k >= len(x[j].index) {\n\t\t\treturn false\n\t\t}\n\t\tif xik != x[j].index[k] {\n\t\t\treturn xik < x[j].index[k]\n\t\t}\n\t}\n\treturn len(x[i].index) < len(x[j].index)\n}\n\n// typeFields returns a list of fields that JSON should recognize for the given type.\n// The algorithm is breadth-first search over the set of structs to include - the top struct\n// and then any reachable anonymous structs.\nfunc typeFields(t reflect.Type) []field {\n\t// Anonymous fields to explore at the current level and the next.\n\tcurrent := []field{}\n\tnext := []field{{typ: t}}\n\n\t// Count of queued names for current level and the next.\n\tcount := map[reflect.Type]int{}\n\tnextCount := map[reflect.Type]int{}\n\n\t// Types already visited at an earlier level.\n\tvisited := map[reflect.Type]bool{}\n\n\t// Fields found.\n\tvar fields []field\n\n\tfor len(next) > 0 {\n\t\tcurrent, next = next, current[:0]\n\t\tcount, nextCount = nextCount, map[reflect.Type]int{}\n\n\t\tfor _, f := range current {\n\t\t\tif visited[f.typ] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvisited[f.typ] = true\n\n\t\t\t// Scan f.typ for fields to include.\n\t\t\tfor i := 0; i < f.typ.NumField(); i++ {\n\t\t\t\tsf := f.typ.Field(i)\n\t\t\t\tif sf.PkgPath != \"\" { // unexported\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttag := sf.Tag.Get(\"json\")\n\t\t\t\tif tag == \"-\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tname, opts := parseTag(tag)\n\t\t\t\tif !isValidTag(name) {\n\t\t\t\t\tname = \"\"\n\t\t\t\t}\n\t\t\t\tindex := make([]int, len(f.index)+1)\n\t\t\t\tcopy(index, f.index)\n\t\t\t\tindex[len(f.index)] = i\n\n\t\t\t\tft := sf.Type\n\t\t\t\tif ft.Name() == \"\" && ft.Kind() == reflect.Ptr {\n\t\t\t\t\t// Follow pointer.\n\t\t\t\t\tft = ft.Elem()\n\t\t\t\t}\n\n\t\t\t\t// Record found field and index sequence.\n\t\t\t\tif name != \"\" || !sf.Anonymous || ft.Kind() != reflect.Struct {\n\t\t\t\t\ttagged := name != \"\"\n\t\t\t\t\tif name == \"\" {\n\t\t\t\t\t\tname = sf.Name\n\t\t\t\t\t}\n\t\t\t\t\tfields = append(fields, fillField(field{\n\t\t\t\t\t\tname:      name,\n\t\t\t\t\t\ttag:       tagged,\n\t\t\t\t\t\tindex:     index,\n\t\t\t\t\t\ttyp:       ft,\n\t\t\t\t\t\tomitEmpty: opts.Contains(\"omitempty\"),\n\t\t\t\t\t\tquoted:    opts.Contains(\"string\"),\n\t\t\t\t\t}))\n\t\t\t\t\tif count[f.typ] > 1 {\n\t\t\t\t\t\t// If there were multiple instances, add a second,\n\t\t\t\t\t\t// so that the annihilation code will see a duplicate.\n\t\t\t\t\t\t// It only cares about the distinction between 1 or 2,\n\t\t\t\t\t\t// so don't bother generating any more copies.\n\t\t\t\t\t\tfields = append(fields, fields[len(fields)-1])\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Record new anonymous struct to explore in next round.\n\t\t\t\tnextCount[ft]++\n\t\t\t\tif nextCount[ft] == 1 {\n\t\t\t\t\tnext = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsort.Sort(byName(fields))\n\n\t// Delete all fields that are hidden by the Go rules for embedded fields,\n\t// except that fields with JSON tags are promoted.\n\n\t// The fields are sorted in primary order of name, secondary order\n\t// of field index length. Loop over names; for each name, delete\n\t// hidden fields by choosing the one dominant field that survives.\n\tout := fields[:0]\n\tfor advance, i := 0, 0; i < len(fields); i += advance {\n\t\t// One iteration per name.\n\t\t// Find the sequence of fields with the name of this first field.\n\t\tfi := fields[i]\n\t\tname := fi.name\n\t\tfor advance = 1; i+advance < len(fields); advance++ {\n\t\t\tfj := fields[i+advance]\n\t\t\tif fj.name != name {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif advance == 1 { // Only one field with this name\n\t\t\tout = append(out, fi)\n\t\t\tcontinue\n\t\t}\n\t\tdominant, ok := dominantField(fields[i : i+advance])\n\t\tif ok {\n\t\t\tout = append(out, dominant)\n\t\t}\n\t}\n\n\tfields = out\n\tsort.Sort(byIndex(fields))\n\n\treturn fields\n}\n\n// dominantField looks through the fields, all of which are known to\n// have the same name, to find the single field that dominates the\n// others using Go's embedding rules, modified by the presence of\n// JSON tags. If there are multiple top-level fields, the boolean\n// will be false: This condition is an error in Go and we skip all\n// the fields.\nfunc dominantField(fields []field) (field, bool) {\n\t// The fields are sorted in increasing index-length order. The winner\n\t// must therefore be one with the shortest index length. Drop all\n\t// longer entries, which is easy: just truncate the slice.\n\tlength := len(fields[0].index)\n\ttagged := -1 // Index of first tagged field.\n\tfor i, f := range fields {\n\t\tif len(f.index) > length {\n\t\t\tfields = fields[:i]\n\t\t\tbreak\n\t\t}\n\t\tif f.tag {\n\t\t\tif tagged >= 0 {\n\t\t\t\t// Multiple tagged fields at the same level: conflict.\n\t\t\t\t// Return no field.\n\t\t\t\treturn field{}, false\n\t\t\t}\n\t\t\ttagged = i\n\t\t}\n\t}\n\tif tagged >= 0 {\n\t\treturn fields[tagged], true\n\t}\n\t// All remaining fields have the same length. If there's more than one,\n\t// we have a conflict (two fields named \"X\" at the same level) and we\n\t// return no field.\n\tif len(fields) > 1 {\n\t\treturn field{}, false\n\t}\n\treturn fields[0], true\n}\n\nvar fieldCache struct {\n\tsync.RWMutex\n\tm map[reflect.Type][]field\n}\n\n// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.\nfunc cachedTypeFields(t reflect.Type) []field {\n\tfieldCache.RLock()\n\tf := fieldCache.m[t]\n\tfieldCache.RUnlock()\n\tif f != nil {\n\t\treturn f\n\t}\n\n\t// Compute fields without lock.\n\t// Might duplicate effort but won't hold other computations back.\n\tf = typeFields(t)\n\tif f == nil {\n\t\tf = []field{}\n\t}\n\n\tfieldCache.Lock()\n\tif fieldCache.m == nil {\n\t\tfieldCache.m = map[reflect.Type][]field{}\n\t}\n\tfieldCache.m[t] = f\n\tfieldCache.Unlock()\n\treturn f\n}\n\nfunc isValidTag(s string) bool {\n\tif s == \"\" {\n\t\treturn false\n\t}\n\tfor _, c := range s {\n\t\tswitch {\n\t\tcase strings.ContainsRune(\"!#$%&()*+-./:<=>?@[]^_{|}~ \", c):\n\t\t\t// Backslash and quote chars are reserved, but\n\t\t\t// otherwise any punctuation chars are allowed\n\t\t\t// in a tag name.\n\t\tdefault:\n\t\t\tif !unicode.IsLetter(c) && !unicode.IsDigit(c) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nconst (\n\tcaseMask     = ^byte(0x20) // Mask to ignore case in ASCII.\n\tkelvin       = '\\u212a'\n\tsmallLongEss = '\\u017f'\n)\n\n// foldFunc returns one of four different case folding equivalence\n// functions, from most general (and slow) to fastest:\n//\n// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8\n// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')\n// 3) asciiEqualFold, no special, but includes non-letters (including _)\n// 4) simpleLetterEqualFold, no specials, no non-letters.\n//\n// The letters S and K are special because they map to 3 runes, not just 2:\n//  * S maps to s and to U+017F 'ſ' Latin small letter long s\n//  * k maps to K and to U+212A 'K' Kelvin sign\n// See http://play.golang.org/p/tTxjOc0OGo\n//\n// The returned function is specialized for matching against s and\n// should only be given s. It's not curried for performance reasons.\nfunc foldFunc(s []byte) func(s, t []byte) bool {\n\tnonLetter := false\n\tspecial := false // special letter\n\tfor _, b := range s {\n\t\tif b >= utf8.RuneSelf {\n\t\t\treturn bytes.EqualFold\n\t\t}\n\t\tupper := b & caseMask\n\t\tif upper < 'A' || upper > 'Z' {\n\t\t\tnonLetter = true\n\t\t} else if upper == 'K' || upper == 'S' {\n\t\t\t// See above for why these letters are special.\n\t\t\tspecial = true\n\t\t}\n\t}\n\tif special {\n\t\treturn equalFoldRight\n\t}\n\tif nonLetter {\n\t\treturn asciiEqualFold\n\t}\n\treturn simpleLetterEqualFold\n}\n\n// equalFoldRight is a specialization of bytes.EqualFold when s is\n// known to be all ASCII (including punctuation), but contains an 's',\n// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.\n// See comments on foldFunc.\nfunc equalFoldRight(s, t []byte) bool {\n\tfor _, sb := range s {\n\t\tif len(t) == 0 {\n\t\t\treturn false\n\t\t}\n\t\ttb := t[0]\n\t\tif tb < utf8.RuneSelf {\n\t\t\tif sb != tb {\n\t\t\t\tsbUpper := sb & caseMask\n\t\t\t\tif 'A' <= sbUpper && sbUpper <= 'Z' {\n\t\t\t\t\tif sbUpper != tb&caseMask {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tt = t[1:]\n\t\t\tcontinue\n\t\t}\n\t\t// sb is ASCII and t is not. t must be either kelvin\n\t\t// sign or long s; sb must be s, S, k, or K.\n\t\ttr, size := utf8.DecodeRune(t)\n\t\tswitch sb {\n\t\tcase 's', 'S':\n\t\t\tif tr != smallLongEss {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase 'k', 'K':\n\t\t\tif tr != kelvin {\n\t\t\t\treturn false\n\t\t\t}\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t\tt = t[size:]\n\n\t}\n\tif len(t) > 0 {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// asciiEqualFold is a specialization of bytes.EqualFold for use when\n// s is all ASCII (but may contain non-letters) and contains no\n// special-folding letters.\n// See comments on foldFunc.\nfunc asciiEqualFold(s, t []byte) bool {\n\tif len(s) != len(t) {\n\t\treturn false\n\t}\n\tfor i, sb := range s {\n\t\ttb := t[i]\n\t\tif sb == tb {\n\t\t\tcontinue\n\t\t}\n\t\tif ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {\n\t\t\tif sb&caseMask != tb&caseMask {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// simpleLetterEqualFold is a specialization of bytes.EqualFold for\n// use when s is all ASCII letters (no underscores, etc) and also\n// doesn't contain 'k', 'K', 's', or 'S'.\n// See comments on foldFunc.\nfunc simpleLetterEqualFold(s, t []byte) bool {\n\tif len(s) != len(t) {\n\t\treturn false\n\t}\n\tfor i, b := range s {\n\t\tif b&caseMask != t[i]&caseMask {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// tagOptions is the string following a comma in a struct field's \"json\"\n// tag, or the empty string. It does not include the leading comma.\ntype tagOptions string\n\n// parseTag splits a struct field's json tag into its name and\n// comma-separated options.\nfunc parseTag(tag string) (string, tagOptions) {\n\tif idx := strings.Index(tag, \",\"); idx != -1 {\n\t\treturn tag[:idx], tagOptions(tag[idx+1:])\n\t}\n\treturn tag, tagOptions(\"\")\n}\n\n// Contains reports whether a comma-separated list of options\n// contains a particular substr flag. substr must be surrounded by a\n// string boundary or commas.\nfunc (o tagOptions) Contains(optionName string) bool {\n\tif len(o) == 0 {\n\t\treturn false\n\t}\n\ts := string(o)\n\tfor s != \"\" {\n\t\tvar next string\n\t\ti := strings.Index(s, \",\")\n\t\tif i >= 0 {\n\t\t\ts, next = s[:i], s[i+1:]\n\t\t}\n\t\tif s == optionName {\n\t\t\treturn true\n\t\t}\n\t\ts = next\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/ghodss/yaml/yaml.go",
    "content": "package yaml\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\n\t\"gopkg.in/yaml.v2\"\n)\n\n// Marshals the object into JSON then converts JSON to YAML and returns the\n// YAML.\nfunc Marshal(o interface{}) ([]byte, error) {\n\tj, err := json.Marshal(o)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error marshaling into JSON: %v\", err)\n\t}\n\n\ty, err := JSONToYAML(j)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error converting JSON to YAML: %v\", err)\n\t}\n\n\treturn y, nil\n}\n\n// Converts YAML to JSON then uses JSON to unmarshal into an object.\nfunc Unmarshal(y []byte, o interface{}) error {\n\tvo := reflect.ValueOf(o)\n\tj, err := yamlToJSON(y, &vo)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error converting YAML to JSON: %v\", err)\n\t}\n\n\terr = json.Unmarshal(j, o)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error unmarshaling JSON: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// Convert JSON to YAML.\nfunc JSONToYAML(j []byte) ([]byte, error) {\n\t// Convert the JSON to an object.\n\tvar jsonObj interface{}\n\t// We are using yaml.Unmarshal here (instead of json.Unmarshal) because the\n\t// Go JSON library doesn't try to pick the right number type (int, float,\n\t// etc.) when unmarshalling to interface{}, it just picks float64\n\t// universally. go-yaml does go through the effort of picking the right\n\t// number type, so we can preserve number type throughout this process.\n\terr := yaml.Unmarshal(j, &jsonObj)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Marshal this object into YAML.\n\treturn yaml.Marshal(jsonObj)\n}\n\n// Convert YAML to JSON. Since JSON is a subset of YAML, passing JSON through\n// this method should be a no-op.\n//\n// Things YAML can do that are not supported by JSON:\n// * In YAML you can have binary and null keys in your maps. These are invalid\n//   in JSON. (int and float keys are converted to strings.)\n// * Binary data in YAML with the !!binary tag is not supported. If you want to\n//   use binary data with this library, encode the data as base64 as usual but do\n//   not use the !!binary tag in your YAML. This will ensure the original base64\n//   encoded data makes it all the way through to the JSON.\nfunc YAMLToJSON(y []byte) ([]byte, error) {\n\treturn yamlToJSON(y, nil)\n}\n\nfunc yamlToJSON(y []byte, jsonTarget *reflect.Value) ([]byte, error) {\n\t// Convert the YAML to an object.\n\tvar yamlObj interface{}\n\terr := yaml.Unmarshal(y, &yamlObj)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// YAML objects are not completely compatible with JSON objects (e.g. you\n\t// can have non-string keys in YAML). So, convert the YAML-compatible object\n\t// to a JSON-compatible object, failing with an error if irrecoverable\n\t// incompatibilties happen along the way.\n\tjsonObj, err := convertToJSONableObject(yamlObj, jsonTarget)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Convert this object to JSON and return the data.\n\treturn json.Marshal(jsonObj)\n}\n\nfunc convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) {\n\tvar err error\n\n\t// Resolve jsonTarget to a concrete value (i.e. not a pointer or an\n\t// interface). We pass decodingNull as false because we're not actually\n\t// decoding into the value, we're just checking if the ultimate target is a\n\t// string.\n\tif jsonTarget != nil {\n\t\tju, tu, pv := indirect(*jsonTarget, false)\n\t\t// We have a JSON or Text Umarshaler at this level, so we can't be trying\n\t\t// to decode into a string.\n\t\tif ju != nil || tu != nil {\n\t\t\tjsonTarget = nil\n\t\t} else {\n\t\t\tjsonTarget = &pv\n\t\t}\n\t}\n\n\t// If yamlObj is a number or a boolean, check if jsonTarget is a string -\n\t// if so, coerce.  Else return normal.\n\t// If yamlObj is a map or array, find the field that each key is\n\t// unmarshaling to, and when you recurse pass the reflect.Value for that\n\t// field back into this function.\n\tswitch typedYAMLObj := yamlObj.(type) {\n\tcase map[interface{}]interface{}:\n\t\t// JSON does not support arbitrary keys in a map, so we must convert\n\t\t// these keys to strings.\n\t\t//\n\t\t// From my reading of go-yaml v2 (specifically the resolve function),\n\t\t// keys can only have the types string, int, int64, float64, binary\n\t\t// (unsupported), or null (unsupported).\n\t\tstrMap := make(map[string]interface{})\n\t\tfor k, v := range typedYAMLObj {\n\t\t\t// Resolve the key to a string first.\n\t\t\tvar keyString string\n\t\t\tswitch typedKey := k.(type) {\n\t\t\tcase string:\n\t\t\t\tkeyString = typedKey\n\t\t\tcase int:\n\t\t\t\tkeyString = strconv.Itoa(typedKey)\n\t\t\tcase int64:\n\t\t\t\t// go-yaml will only return an int64 as a key if the system\n\t\t\t\t// architecture is 32-bit and the key's value is between 32-bit\n\t\t\t\t// and 64-bit. Otherwise the key type will simply be int.\n\t\t\t\tkeyString = strconv.FormatInt(typedKey, 10)\n\t\t\tcase float64:\n\t\t\t\t// Stolen from go-yaml to use the same conversion to string as\n\t\t\t\t// the go-yaml library uses to convert float to string when\n\t\t\t\t// Marshaling.\n\t\t\t\ts := strconv.FormatFloat(typedKey, 'g', -1, 32)\n\t\t\t\tswitch s {\n\t\t\t\tcase \"+Inf\":\n\t\t\t\t\ts = \".inf\"\n\t\t\t\tcase \"-Inf\":\n\t\t\t\t\ts = \"-.inf\"\n\t\t\t\tcase \"NaN\":\n\t\t\t\t\ts = \".nan\"\n\t\t\t\t}\n\t\t\t\tkeyString = s\n\t\t\tcase bool:\n\t\t\t\tif typedKey {\n\t\t\t\t\tkeyString = \"true\"\n\t\t\t\t} else {\n\t\t\t\t\tkeyString = \"false\"\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"Unsupported map key of type: %s, key: %+#v, value: %+#v\",\n\t\t\t\t\treflect.TypeOf(k), k, v)\n\t\t\t}\n\n\t\t\t// jsonTarget should be a struct or a map. If it's a struct, find\n\t\t\t// the field it's going to map to and pass its reflect.Value. If\n\t\t\t// it's a map, find the element type of the map and pass the\n\t\t\t// reflect.Value created from that type. If it's neither, just pass\n\t\t\t// nil - JSON conversion will error for us if it's a real issue.\n\t\t\tif jsonTarget != nil {\n\t\t\t\tt := *jsonTarget\n\t\t\t\tif t.Kind() == reflect.Struct {\n\t\t\t\t\tkeyBytes := []byte(keyString)\n\t\t\t\t\t// Find the field that the JSON library would use.\n\t\t\t\t\tvar f *field\n\t\t\t\t\tfields := cachedTypeFields(t.Type())\n\t\t\t\t\tfor i := range fields {\n\t\t\t\t\t\tff := &fields[i]\n\t\t\t\t\t\tif bytes.Equal(ff.nameBytes, keyBytes) {\n\t\t\t\t\t\t\tf = ff\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Do case-insensitive comparison.\n\t\t\t\t\t\tif f == nil && ff.equalFold(ff.nameBytes, keyBytes) {\n\t\t\t\t\t\t\tf = ff\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif f != nil {\n\t\t\t\t\t\t// Find the reflect.Value of the most preferential\n\t\t\t\t\t\t// struct field.\n\t\t\t\t\t\tjtf := t.Field(f.index[0])\n\t\t\t\t\t\tstrMap[keyString], err = convertToJSONableObject(v, &jtf)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if t.Kind() == reflect.Map {\n\t\t\t\t\t// Create a zero value of the map's element type to use as\n\t\t\t\t\t// the JSON target.\n\t\t\t\t\tjtv := reflect.Zero(t.Type().Elem())\n\t\t\t\t\tstrMap[keyString], err = convertToJSONableObject(v, &jtv)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tstrMap[keyString], err = convertToJSONableObject(v, nil)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn strMap, nil\n\tcase []interface{}:\n\t\t// We need to recurse into arrays in case there are any\n\t\t// map[interface{}]interface{}'s inside and to convert any\n\t\t// numbers to strings.\n\n\t\t// If jsonTarget is a slice (which it really should be), find the\n\t\t// thing it's going to map to. If it's not a slice, just pass nil\n\t\t// - JSON conversion will error for us if it's a real issue.\n\t\tvar jsonSliceElemValue *reflect.Value\n\t\tif jsonTarget != nil {\n\t\t\tt := *jsonTarget\n\t\t\tif t.Kind() == reflect.Slice {\n\t\t\t\t// By default slices point to nil, but we need a reflect.Value\n\t\t\t\t// pointing to a value of the slice type, so we create one here.\n\t\t\t\tev := reflect.Indirect(reflect.New(t.Type().Elem()))\n\t\t\t\tjsonSliceElemValue = &ev\n\t\t\t}\n\t\t}\n\n\t\t// Make and use a new array.\n\t\tarr := make([]interface{}, len(typedYAMLObj))\n\t\tfor i, v := range typedYAMLObj {\n\t\t\tarr[i], err = convertToJSONableObject(v, jsonSliceElemValue)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn arr, nil\n\tdefault:\n\t\t// If the target type is a string and the YAML type is a number,\n\t\t// convert the YAML type to a string.\n\t\tif jsonTarget != nil && (*jsonTarget).Kind() == reflect.String {\n\t\t\t// Based on my reading of go-yaml, it may return int, int64,\n\t\t\t// float64, or uint64.\n\t\t\tvar s string\n\t\t\tswitch typedVal := typedYAMLObj.(type) {\n\t\t\tcase int:\n\t\t\t\ts = strconv.FormatInt(int64(typedVal), 10)\n\t\t\tcase int64:\n\t\t\t\ts = strconv.FormatInt(typedVal, 10)\n\t\t\tcase float64:\n\t\t\t\ts = strconv.FormatFloat(typedVal, 'g', -1, 32)\n\t\t\tcase uint64:\n\t\t\t\ts = strconv.FormatUint(typedVal, 10)\n\t\t\tcase bool:\n\t\t\t\tif typedVal {\n\t\t\t\t\ts = \"true\"\n\t\t\t\t} else {\n\t\t\t\t\ts = \"false\"\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(s) > 0 {\n\t\t\t\tyamlObj = interface{}(s)\n\t\t\t}\n\t\t}\n\t\treturn yamlObj, nil\n\t}\n\n\treturn nil, nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/.travis.yml",
    "content": "language: go\n\ngo:\n  - \"1.8.x\"\n  - \"1.10.x\"\n  - \"1.13.x\"\n  - \"1.14.x\"\n  - \"1.16.x\"\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/LICENSE.MIT",
    "content": "Copyright (c) 2015 Conrad Irwin <conrad@bugsnag.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/README.md",
    "content": "go-errors/errors\n================\n\n[![Build Status](https://travis-ci.org/go-errors/errors.svg?branch=master)](https://travis-ci.org/go-errors/errors)\n\nPackage errors adds stacktrace support to errors in go.\n\nThis is particularly useful when you want to understand the state of execution\nwhen an error was returned unexpectedly.\n\nIt provides the type \\*Error which implements the standard golang error\ninterface, so you can use this library interchangably with code that is\nexpecting a normal error return.\n\nUsage\n-----\n\nFull documentation is available on\n[godoc](https://godoc.org/github.com/go-errors/errors), but here's a simple\nexample:\n\n```go\npackage crashy\n\nimport \"github.com/go-errors/errors\"\n\nvar Crashed = errors.Errorf(\"oh dear\")\n\nfunc Crash() error {\n    return errors.New(Crashed)\n}\n```\n\nThis can be called as follows:\n\n```go\npackage main\n\nimport (\n    \"crashy\"\n    \"fmt\"\n    \"github.com/go-errors/errors\"\n)\n\nfunc main() {\n    err := crashy.Crash()\n    if err != nil {\n        if errors.Is(err, crashy.Crashed) {\n            fmt.Println(err.(*errors.Error).ErrorStack())\n        } else {\n            panic(err)\n        }\n    }\n}\n```\n\nMeta-fu\n-------\n\nThis package was original written to allow reporting to\n[Bugsnag](https://bugsnag.com/) from\n[bugsnag-go](https://github.com/bugsnag/bugsnag-go), but after I found similar\npackages by Facebook and Dropbox, it was moved to one canonical location so\neveryone can benefit.\n\nThis package is licensed under the MIT license, see LICENSE.MIT for details.\n\n\n## Changelog\n* v1.1.0 updated to use go1.13's standard-library errors.Is method instead of == in errors.Is\n* v1.2.0 added `errors.As` from the standard library.\n* v1.3.0 *BREAKING* updated error methods to return `error` instead of `*Error`.\n>  Code that needs access to the underlying `*Error` can use the new errors.AsError(e)\n> ```\n>   // before\n>   errors.New(err).ErrorStack()\n>   // after\n>.  errors.AsError(errors.Wrap(err)).ErrorStack()\n> ```\n* v1.4.0 *BREAKING* v1.4.0 reverted all changes from v1.3.0 and is identical to v1.2.0\n* v1.4.1 no code change, but now without an unnecessary cover.out file.\n* v1.4.2 performance improvement to ErrorStack() to avoid unnecessary work https://github.com/go-errors/errors/pull/40\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/error.go",
    "content": "// Package errors provides errors that have stack-traces.\n//\n// This is particularly useful when you want to understand the\n// state of execution when an error was returned unexpectedly.\n//\n// It provides the type *Error which implements the standard\n// golang error interface, so you can use this library interchangably\n// with code that is expecting a normal error return.\n//\n// For example:\n//\n//  package crashy\n//\n//  import \"github.com/go-errors/errors\"\n//\n//  var Crashed = errors.Errorf(\"oh dear\")\n//\n//  func Crash() error {\n//      return errors.New(Crashed)\n//  }\n//\n// This can be called as follows:\n//\n//  package main\n//\n//  import (\n//      \"crashy\"\n//      \"fmt\"\n//      \"github.com/go-errors/errors\"\n//  )\n//\n//  func main() {\n//      err := crashy.Crash()\n//      if err != nil {\n//          if errors.Is(err, crashy.Crashed) {\n//              fmt.Println(err.(*errors.Error).ErrorStack())\n//          } else {\n//              panic(err)\n//          }\n//      }\n//  }\n//\n// This package was original written to allow reporting to Bugsnag,\n// but after I found similar packages by Facebook and Dropbox, it\n// was moved to one canonical location so everyone can benefit.\npackage errors\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"runtime\"\n)\n\n// The maximum number of stackframes on any error.\nvar MaxStackDepth = 50\n\n// Error is an error with an attached stacktrace. It can be used\n// wherever the builtin error interface is expected.\ntype Error struct {\n\tErr    error\n\tstack  []uintptr\n\tframes []StackFrame\n\tprefix string\n}\n\n// New makes an Error from the given value. If that value is already an\n// error then it will be used directly, if not, it will be passed to\n// fmt.Errorf(\"%v\"). The stacktrace will point to the line of code that\n// called New.\nfunc New(e interface{}) *Error {\n\tvar err error\n\n\tswitch e := e.(type) {\n\tcase error:\n\t\terr = e\n\tdefault:\n\t\terr = fmt.Errorf(\"%v\", e)\n\t}\n\n\tstack := make([]uintptr, MaxStackDepth)\n\tlength := runtime.Callers(2, stack[:])\n\treturn &Error{\n\t\tErr:   err,\n\t\tstack: stack[:length],\n\t}\n}\n\n// Wrap makes an Error from the given value. If that value is already an\n// error then it will be used directly, if not, it will be passed to\n// fmt.Errorf(\"%v\"). The skip parameter indicates how far up the stack\n// to start the stacktrace. 0 is from the current call, 1 from its caller, etc.\nfunc Wrap(e interface{}, skip int) *Error {\n\tif e == nil {\n\t\treturn nil\n\t}\n\n\tvar err error\n\n\tswitch e := e.(type) {\n\tcase *Error:\n\t\treturn e\n\tcase error:\n\t\terr = e\n\tdefault:\n\t\terr = fmt.Errorf(\"%v\", e)\n\t}\n\n\tstack := make([]uintptr, MaxStackDepth)\n\tlength := runtime.Callers(2+skip, stack[:])\n\treturn &Error{\n\t\tErr:   err,\n\t\tstack: stack[:length],\n\t}\n}\n\n// WrapPrefix makes an Error from the given value. If that value is already an\n// error then it will be used directly, if not, it will be passed to\n// fmt.Errorf(\"%v\"). The prefix parameter is used to add a prefix to the\n// error message when calling Error(). The skip parameter indicates how far\n// up the stack to start the stacktrace. 0 is from the current call,\n// 1 from its caller, etc.\nfunc WrapPrefix(e interface{}, prefix string, skip int) *Error {\n\tif e == nil {\n\t\treturn nil\n\t}\n\n\terr := Wrap(e, 1+skip)\n\n\tif err.prefix != \"\" {\n\t\tprefix = fmt.Sprintf(\"%s: %s\", prefix, err.prefix)\n\t}\n\n\treturn &Error{\n\t\tErr:    err.Err,\n\t\tstack:  err.stack,\n\t\tprefix: prefix,\n\t}\n\n}\n\n// Errorf creates a new error with the given message. You can use it\n// as a drop-in replacement for fmt.Errorf() to provide descriptive\n// errors in return values.\nfunc Errorf(format string, a ...interface{}) *Error {\n\treturn Wrap(fmt.Errorf(format, a...), 1)\n}\n\n// Error returns the underlying error's message.\nfunc (err *Error) Error() string {\n\n\tmsg := err.Err.Error()\n\tif err.prefix != \"\" {\n\t\tmsg = fmt.Sprintf(\"%s: %s\", err.prefix, msg)\n\t}\n\n\treturn msg\n}\n\n// Stack returns the callstack formatted the same way that go does\n// in runtime/debug.Stack()\nfunc (err *Error) Stack() []byte {\n\tbuf := bytes.Buffer{}\n\n\tfor _, frame := range err.StackFrames() {\n\t\tbuf.WriteString(frame.String())\n\t}\n\n\treturn buf.Bytes()\n}\n\n// Callers satisfies the bugsnag ErrorWithCallerS() interface\n// so that the stack can be read out.\nfunc (err *Error) Callers() []uintptr {\n\treturn err.stack\n}\n\n// ErrorStack returns a string that contains both the\n// error message and the callstack.\nfunc (err *Error) ErrorStack() string {\n\treturn err.TypeName() + \" \" + err.Error() + \"\\n\" + string(err.Stack())\n}\n\n// StackFrames returns an array of frames containing information about the\n// stack.\nfunc (err *Error) StackFrames() []StackFrame {\n\tif err.frames == nil {\n\t\terr.frames = make([]StackFrame, len(err.stack))\n\n\t\tfor i, pc := range err.stack {\n\t\t\terr.frames[i] = NewStackFrame(pc)\n\t\t}\n\t}\n\n\treturn err.frames\n}\n\n// TypeName returns the type this error. e.g. *errors.stringError.\nfunc (err *Error) TypeName() string {\n\tif _, ok := err.Err.(uncaughtPanic); ok {\n\t\treturn \"panic\"\n\t}\n\treturn reflect.TypeOf(err.Err).String()\n}\n\n// Return the wrapped error (implements api for As function).\nfunc (err *Error) Unwrap() error {\n\treturn err.Err\n}\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/error_1_13.go",
    "content": "// +build go1.13\n\npackage errors\n\nimport (\n\tbaseErrors \"errors\"\n)\n\n// find error in any wrapped error\nfunc As(err error, target interface{}) bool {\n\treturn baseErrors.As(err, target)\n}\n\n// Is detects whether the error is equal to a given error. Errors\n// are considered equal by this function if they are matched by errors.Is\n// or if their contained errors are matched through errors.Is\nfunc Is(e error, original error) bool {\n\tif baseErrors.Is(e, original) {\n\t\treturn true\n\t}\n\n\tif e, ok := e.(*Error); ok {\n\t\treturn Is(e.Err, original)\n\t}\n\n\tif original, ok := original.(*Error); ok {\n\t\treturn Is(e, original.Err)\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/error_backward.go",
    "content": "// +build !go1.13\n\npackage errors\n\nimport (\n\t\"reflect\"\n)\n\ntype unwrapper interface {\n\tUnwrap() error\n}\n\n// As assigns error or any wrapped error to the value target points\n// to. If there is no value of the target type of target As returns\n// false.\nfunc As(err error, target interface{}) bool {\n\ttargetType := reflect.TypeOf(target)\n\n\tfor {\n\t\terrType := reflect.TypeOf(err)\n\n\t\tif errType == nil {\n\t\t\treturn false\n\t\t}\n\n\t\tif reflect.PtrTo(errType) == targetType {\n\t\t\treflect.ValueOf(target).Elem().Set(reflect.ValueOf(err))\n\t\t\treturn true\n\t\t}\n\n\t\twrapped, ok := err.(unwrapper)\n\t\tif ok {\n\t\t\terr = wrapped.Unwrap()\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n}\n\n// Is detects whether the error is equal to a given error. Errors\n// are considered equal by this function if they are the same object,\n// or if they both contain the same error inside an errors.Error.\nfunc Is(e error, original error) bool {\n\tif e == original {\n\t\treturn true\n\t}\n\n\tif e, ok := e.(*Error); ok {\n\t\treturn Is(e.Err, original)\n\t}\n\n\tif original, ok := original.(*Error); ok {\n\t\treturn Is(e, original.Err)\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/parse_panic.go",
    "content": "package errors\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n)\n\ntype uncaughtPanic struct{ message string }\n\nfunc (p uncaughtPanic) Error() string {\n\treturn p.message\n}\n\n// ParsePanic allows you to get an error object from the output of a go program\n// that panicked. This is particularly useful with https://github.com/mitchellh/panicwrap.\nfunc ParsePanic(text string) (*Error, error) {\n\tlines := strings.Split(text, \"\\n\")\n\n\tstate := \"start\"\n\n\tvar message string\n\tvar stack []StackFrame\n\n\tfor i := 0; i < len(lines); i++ {\n\t\tline := lines[i]\n\n\t\tif state == \"start\" {\n\t\t\tif strings.HasPrefix(line, \"panic: \") {\n\t\t\t\tmessage = strings.TrimPrefix(line, \"panic: \")\n\t\t\t\tstate = \"seek\"\n\t\t\t} else {\n\t\t\t\treturn nil, Errorf(\"bugsnag.panicParser: Invalid line (no prefix): %s\", line)\n\t\t\t}\n\n\t\t} else if state == \"seek\" {\n\t\t\tif strings.HasPrefix(line, \"goroutine \") && strings.HasSuffix(line, \"[running]:\") {\n\t\t\t\tstate = \"parsing\"\n\t\t\t}\n\n\t\t} else if state == \"parsing\" {\n\t\t\tif line == \"\" {\n\t\t\t\tstate = \"done\"\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcreatedBy := false\n\t\t\tif strings.HasPrefix(line, \"created by \") {\n\t\t\t\tline = strings.TrimPrefix(line, \"created by \")\n\t\t\t\tcreatedBy = true\n\t\t\t}\n\n\t\t\ti++\n\n\t\t\tif i >= len(lines) {\n\t\t\t\treturn nil, Errorf(\"bugsnag.panicParser: Invalid line (unpaired): %s\", line)\n\t\t\t}\n\n\t\t\tframe, err := parsePanicFrame(line, lines[i], createdBy)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tstack = append(stack, *frame)\n\t\t\tif createdBy {\n\t\t\t\tstate = \"done\"\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif state == \"done\" || state == \"parsing\" {\n\t\treturn &Error{Err: uncaughtPanic{message}, frames: stack}, nil\n\t}\n\treturn nil, Errorf(\"could not parse panic: %v\", text)\n}\n\n// The lines we're passing look like this:\n//\n//     main.(*foo).destruct(0xc208067e98)\n//             /0/go/src/github.com/bugsnag/bugsnag-go/pan/main.go:22 +0x151\nfunc parsePanicFrame(name string, line string, createdBy bool) (*StackFrame, error) {\n\tidx := strings.LastIndex(name, \"(\")\n\tif idx == -1 && !createdBy {\n\t\treturn nil, Errorf(\"bugsnag.panicParser: Invalid line (no call): %s\", name)\n\t}\n\tif idx != -1 {\n\t\tname = name[:idx]\n\t}\n\tpkg := \"\"\n\n\tif lastslash := strings.LastIndex(name, \"/\"); lastslash >= 0 {\n\t\tpkg += name[:lastslash] + \"/\"\n\t\tname = name[lastslash+1:]\n\t}\n\tif period := strings.Index(name, \".\"); period >= 0 {\n\t\tpkg += name[:period]\n\t\tname = name[period+1:]\n\t}\n\n\tname = strings.Replace(name, \"·\", \".\", -1)\n\n\tif !strings.HasPrefix(line, \"\\t\") {\n\t\treturn nil, Errorf(\"bugsnag.panicParser: Invalid line (no tab): %s\", line)\n\t}\n\n\tidx = strings.LastIndex(line, \":\")\n\tif idx == -1 {\n\t\treturn nil, Errorf(\"bugsnag.panicParser: Invalid line (no line number): %s\", line)\n\t}\n\tfile := line[1:idx]\n\n\tnumber := line[idx+1:]\n\tif idx = strings.Index(number, \" +\"); idx > -1 {\n\t\tnumber = number[:idx]\n\t}\n\n\tlno, err := strconv.ParseInt(number, 10, 32)\n\tif err != nil {\n\t\treturn nil, Errorf(\"bugsnag.panicParser: Invalid line (bad line number): %s\", line)\n\t}\n\n\treturn &StackFrame{\n\t\tFile:       file,\n\t\tLineNumber: int(lno),\n\t\tPackage:    pkg,\n\t\tName:       name,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/go-errors/errors/stackframe.go",
    "content": "package errors\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n)\n\n// A StackFrame contains all necessary information about to generate a line\n// in a callstack.\ntype StackFrame struct {\n\t// The path to the file containing this ProgramCounter\n\tFile string\n\t// The LineNumber in that file\n\tLineNumber int\n\t// The Name of the function that contains this ProgramCounter\n\tName string\n\t// The Package that contains this function\n\tPackage string\n\t// The underlying ProgramCounter\n\tProgramCounter uintptr\n}\n\n// NewStackFrame popoulates a stack frame object from the program counter.\nfunc NewStackFrame(pc uintptr) (frame StackFrame) {\n\n\tframe = StackFrame{ProgramCounter: pc}\n\tif frame.Func() == nil {\n\t\treturn\n\t}\n\tframe.Package, frame.Name = packageAndName(frame.Func())\n\n\t// pc -1 because the program counters we use are usually return addresses,\n\t// and we want to show the line that corresponds to the function call\n\tframe.File, frame.LineNumber = frame.Func().FileLine(pc - 1)\n\treturn\n\n}\n\n// Func returns the function that contained this frame.\nfunc (frame *StackFrame) Func() *runtime.Func {\n\tif frame.ProgramCounter == 0 {\n\t\treturn nil\n\t}\n\treturn runtime.FuncForPC(frame.ProgramCounter)\n}\n\n// String returns the stackframe formatted in the same way as go does\n// in runtime/debug.Stack()\nfunc (frame *StackFrame) String() string {\n\tstr := fmt.Sprintf(\"%s:%d (0x%x)\\n\", frame.File, frame.LineNumber, frame.ProgramCounter)\n\n\tsource, err := frame.sourceLine()\n\tif err != nil {\n\t\treturn str\n\t}\n\n\treturn str + fmt.Sprintf(\"\\t%s: %s\\n\", frame.Name, source)\n}\n\n// SourceLine gets the line of code (from File and Line) of the original source if possible.\nfunc (frame *StackFrame) SourceLine() (string, error) {\n\tsource, err := frame.sourceLine()\n\tif err != nil {\n\t\treturn source, New(err)\n\t}\n\treturn source, err\n}\n\nfunc (frame *StackFrame) sourceLine() (string, error) {\n\tif frame.LineNumber <= 0 {\n\t\treturn \"???\", nil\n\t}\n\n\tfile, err := os.Open(frame.File)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer file.Close()\n\n\tscanner := bufio.NewScanner(file)\n\tcurrentLine := 1\n\tfor scanner.Scan() {\n\t\tif currentLine == frame.LineNumber {\n\t\t\treturn string(bytes.Trim(scanner.Bytes(), \" \\t\")), nil\n\t\t}\n\t\tcurrentLine++\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn \"???\", nil\n}\n\nfunc packageAndName(fn *runtime.Func) (string, string) {\n\tname := fn.Name()\n\tpkg := \"\"\n\n\t// The name includes the path name to the package, which is unnecessary\n\t// since the file name is already included.  Plus, it has center dots.\n\t// That is, we see\n\t//  runtime/debug.*T·ptrmethod\n\t// and want\n\t//  *T.ptrmethod\n\t// Since the package path might contains dots (e.g. code.google.com/...),\n\t// we first remove the path prefix if there is one.\n\tif lastslash := strings.LastIndex(name, \"/\"); lastslash >= 0 {\n\t\tpkg += name[:lastslash] + \"/\"\n\t\tname = name[lastslash+1:]\n\t}\n\tif period := strings.Index(name, \".\"); period >= 0 {\n\t\tpkg += name[:period]\n\t\tname = name[period+1:]\n\t}\n\n\tname = strings.Replace(name, \"·\", \".\", -1)\n\treturn pkg, name\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/.golangci.yaml",
    "content": "run:\n  timeout: 1m\n  tests: true\n\nlinters:\n  disable-all: true\n  enable:\n    - asciicheck\n    - errcheck\n    - forcetypeassert\n    - gocritic\n    - gofmt\n    - goimports\n    - gosimple\n    - govet\n    - ineffassign\n    - misspell\n    - revive\n    - staticcheck\n    - typecheck\n    - unused\n\nissues:\n  exclude-use-default: false\n  max-issues-per-linter: 0\n  max-same-issues: 10\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/CHANGELOG.md",
    "content": "# CHANGELOG\n\n## v1.0.0-rc1\n\nThis is the first logged release.  Major changes (including breaking changes)\nhave occurred since earlier tags.\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/CONTRIBUTING.md",
    "content": "# Contributing\n\nLogr is open to pull-requests, provided they fit within the intended scope of\nthe project.  Specifically, this library aims to be VERY small and minimalist,\nwith no external dependencies.\n\n## Compatibility\n\nThis project intends to follow [semantic versioning](http://semver.org) and\nis very strict about compatibility.  Any proposed changes MUST follow those\nrules.\n\n## Performance\n\nAs a logging library, logr must be as light-weight as possible.  Any proposed\ncode change must include results of running the [benchmark](./benchmark)\nbefore and after the change.\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\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       http://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": "vendor/github.com/go-logr/logr/README.md",
    "content": "# A minimal logging API for Go\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr)\n\nlogr offers an(other) opinion on how Go programs and libraries can do logging\nwithout becoming coupled to a particular logging implementation.  This is not\nan implementation of logging - it is an API.  In fact it is two APIs with two\ndifferent sets of users.\n\nThe `Logger` type is intended for application and library authors.  It provides\na relatively small API which can be used everywhere you want to emit logs.  It\ndefers the actual act of writing logs (to files, to stdout, or whatever) to the\n`LogSink` interface.\n\nThe `LogSink` interface is intended for logging library implementers.  It is a\npure interface which can be implemented by logging frameworks to provide the actual logging\nfunctionality.\n\nThis decoupling allows application and library developers to write code in\nterms of `logr.Logger` (which has very low dependency fan-out) while the\nimplementation of logging is managed \"up stack\" (e.g. in or near `main()`.)\nApplication developers can then switch out implementations as necessary.\n\nMany people assert that libraries should not be logging, and as such efforts\nlike this are pointless.  Those people are welcome to convince the authors of\nthe tens-of-thousands of libraries that *DO* write logs that they are all\nwrong.  In the meantime, logr takes a more practical approach.\n\n## Typical usage\n\nSomewhere, early in an application's life, it will make a decision about which\nlogging library (implementation) it actually wants to use.  Something like:\n\n```\n    func main() {\n        // ... other setup code ...\n\n        // Create the \"root\" logger.  We have chosen the \"logimpl\" implementation,\n        // which takes some initial parameters and returns a logr.Logger.\n        logger := logimpl.New(param1, param2)\n\n        // ... other setup code ...\n```\n\nMost apps will call into other libraries, create structures to govern the flow,\netc.  The `logr.Logger` object can be passed to these other libraries, stored\nin structs, or even used as a package-global variable, if needed.  For example:\n\n```\n    app := createTheAppObject(logger)\n    app.Run()\n```\n\nOutside of this early setup, no other packages need to know about the choice of\nimplementation.  They write logs in terms of the `logr.Logger` that they\nreceived:\n\n```\n    type appObject struct {\n        // ... other fields ...\n        logger logr.Logger\n        // ... other fields ...\n    }\n\n    func (app *appObject) Run() {\n        app.logger.Info(\"starting up\", \"timestamp\", time.Now())\n\n        // ... app code ...\n```\n\n## Background\n\nIf the Go standard library had defined an interface for logging, this project\nprobably would not be needed.  Alas, here we are.\n\n### Inspiration\n\nBefore you consider this package, please read [this blog post by the\ninimitable Dave Cheney][warning-makes-no-sense].  We really appreciate what\nhe has to say, and it largely aligns with our own experiences.\n\n### Differences from Dave's ideas\n\nThe main differences are:\n\n1. Dave basically proposes doing away with the notion of a logging API in favor\nof `fmt.Printf()`.  We disagree, especially when you consider things like output\nlocations, timestamps, file and line decorations, and structured logging.  This\npackage restricts the logging API to just 2 types of logs: info and error.\n\nInfo logs are things you want to tell the user which are not errors.  Error\nlogs are, well, errors.  If your code receives an `error` from a subordinate\nfunction call and is logging that `error` *and not returning it*, use error\nlogs.\n\n2. Verbosity-levels on info logs.  This gives developers a chance to indicate\narbitrary grades of importance for info logs, without assigning names with\nsemantic meaning such as \"warning\", \"trace\", and \"debug.\"  Superficially this\nmay feel very similar, but the primary difference is the lack of semantics.\nBecause verbosity is a numerical value, it's safe to assume that an app running\nwith higher verbosity means more (and less important) logs will be generated.\n\n## Implementations (non-exhaustive)\n\nThere are implementations for the following logging libraries:\n\n- **a function** (can bridge to non-structured libraries): [funcr](https://github.com/go-logr/logr/tree/master/funcr)\n- **a testing.T** (for use in Go tests, with JSON-like output): [testr](https://github.com/go-logr/logr/tree/master/testr)\n- **github.com/google/glog**: [glogr](https://github.com/go-logr/glogr)\n- **k8s.io/klog** (for Kubernetes): [klogr](https://git.k8s.io/klog/klogr)\n- **a testing.T** (with klog-like text output): [ktesting](https://git.k8s.io/klog/ktesting)\n- **go.uber.org/zap**: [zapr](https://github.com/go-logr/zapr)\n- **log** (the Go standard library logger): [stdr](https://github.com/go-logr/stdr)\n- **github.com/sirupsen/logrus**: [logrusr](https://github.com/bombsimon/logrusr)\n- **github.com/wojas/genericr**: [genericr](https://github.com/wojas/genericr) (makes it easy to implement your own backend)\n- **logfmt** (Heroku style [logging](https://www.brandur.org/logfmt)): [logfmtr](https://github.com/iand/logfmtr)\n- **github.com/rs/zerolog**: [zerologr](https://github.com/go-logr/zerologr)\n- **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0)\n- **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing)\n\n## FAQ\n\n### Conceptual\n\n#### Why structured logging?\n\n- **Structured logs are more easily queryable**: Since you've got\n  key-value pairs, it's much easier to query your structured logs for\n  particular values by filtering on the contents of a particular key --\n  think searching request logs for error codes, Kubernetes reconcilers for\n  the name and namespace of the reconciled object, etc.\n\n- **Structured logging makes it easier to have cross-referenceable logs**:\n  Similarly to searchability, if you maintain conventions around your\n  keys, it becomes easy to gather all log lines related to a particular\n  concept.\n\n- **Structured logs allow better dimensions of filtering**: if you have\n  structure to your logs, you've got more precise control over how much\n  information is logged -- you might choose in a particular configuration\n  to log certain keys but not others, only log lines where a certain key\n  matches a certain value, etc., instead of just having v-levels and names\n  to key off of.\n\n- **Structured logs better represent structured data**: sometimes, the\n  data that you want to log is inherently structured (think tuple-link\n  objects.)  Structured logs allow you to preserve that structure when\n  outputting.\n\n#### Why V-levels?\n\n**V-levels give operators an easy way to control the chattiness of log\noperations**.  V-levels provide a way for a given package to distinguish\nthe relative importance or verbosity of a given log message.  Then, if\na particular logger or package is logging too many messages, the user\nof the package can simply change the v-levels for that library.\n\n#### Why not named levels, like Info/Warning/Error?\n\nRead [Dave Cheney's post][warning-makes-no-sense].  Then read [Differences\nfrom Dave's ideas](#differences-from-daves-ideas).\n\n#### Why not allow format strings, too?\n\n**Format strings negate many of the benefits of structured logs**:\n\n- They're not easily searchable without resorting to fuzzy searching,\n  regular expressions, etc.\n\n- They don't store structured data well, since contents are flattened into\n  a string.\n\n- They're not cross-referenceable.\n\n- They don't compress easily, since the message is not constant.\n\n(Unless you turn positional parameters into key-value pairs with numerical\nkeys, at which point you've gotten key-value logging with meaningless\nkeys.)\n\n### Practical\n\n#### Why key-value pairs, and not a map?\n\nKey-value pairs are *much* easier to optimize, especially around\nallocations.  Zap (a structured logger that inspired logr's interface) has\n[performance measurements](https://github.com/uber-go/zap#performance)\nthat show this quite nicely.\n\nWhile the interface ends up being a little less obvious, you get\npotentially better performance, plus avoid making users type\n`map[string]string{}` every time they want to log.\n\n#### What if my V-levels differ between libraries?\n\nThat's fine.  Control your V-levels on a per-logger basis, and use the\n`WithName` method to pass different loggers to different libraries.\n\nGenerally, you should take care to ensure that you have relatively\nconsistent V-levels within a given logger, however, as this makes deciding\non what verbosity of logs to request easier.\n\n#### But I really want to use a format string!\n\nThat's not actually a question.  Assuming your question is \"how do\nI convert my mental model of logging with format strings to logging with\nconstant messages\":\n\n1. Figure out what the error actually is, as you'd write in a TL;DR style,\n   and use that as a message.\n\n2. For every place you'd write a format specifier, look to the word before\n   it, and add that as a key value pair.\n\nFor instance, consider the following examples (all taken from spots in the\nKubernetes codebase):\n\n- `klog.V(4).Infof(\"Client is returning errors: code %v, error %v\",\n  responseCode, err)` becomes `logger.Error(err, \"client returned an\n  error\", \"code\", responseCode)`\n\n- `klog.V(4).Infof(\"Got a Retry-After %ds response for attempt %d to %v\",\n  seconds, retries, url)` becomes `logger.V(4).Info(\"got a retry-after\n  response when requesting url\", \"attempt\", retries, \"after\n  seconds\", seconds, \"url\", url)`\n\nIf you *really* must use a format string, use it in a key's value, and\ncall `fmt.Sprintf` yourself.  For instance: `log.Printf(\"unable to\nreflect over type %T\")` becomes `logger.Info(\"unable to reflect over\ntype\", \"type\", fmt.Sprintf(\"%T\"))`.  In general though, the cases where\nthis is necessary should be few and far between.\n\n#### How do I choose my V-levels?\n\nThis is basically the only hard constraint: increase V-levels to denote\nmore verbose or more debug-y logs.\n\nOtherwise, you can start out with `0` as \"you always want to see this\",\n`1` as \"common logging that you might *possibly* want to turn off\", and\n`10` as \"I would like to performance-test your log collection stack.\"\n\nThen gradually choose levels in between as you need them, working your way\ndown from 10 (for debug and trace style logs) and up from 1 (for chattier\ninfo-type logs.)\n\n#### How do I choose my keys?\n\nKeys are fairly flexible, and can hold more or less any string\nvalue. For best compatibility with implementations and consistency\nwith existing code in other projects, there are a few conventions you\nshould consider.\n\n- Make your keys human-readable.\n- Constant keys are generally a good idea.\n- Be consistent across your codebase.\n- Keys should naturally match parts of the message string.\n- Use lower case for simple keys and\n  [lowerCamelCase](https://en.wiktionary.org/wiki/lowerCamelCase) for\n  more complex ones. Kubernetes is one example of a project that has\n  [adopted that\n  convention](https://github.com/kubernetes/community/blob/HEAD/contributors/devel/sig-instrumentation/migration-to-structured-logging.md#name-arguments).\n\nWhile key names are mostly unrestricted (and spaces are acceptable),\nit's generally a good idea to stick to printable ascii characters, or at\nleast match the general character set of your log lines.\n\n#### Why should keys be constant values?\n\nThe point of structured logging is to make later log processing easier.  Your\nkeys are, effectively, the schema of each log message.  If you use different\nkeys across instances of the same log line, you will make your structured logs\nmuch harder to use.  `Sprintf()` is for values, not for keys!\n\n#### Why is this not a pure interface?\n\nThe Logger type is implemented as a struct in order to allow the Go compiler to\noptimize things like high-V `Info` logs that are not triggered.  Not all of\nthese implementations are implemented yet, but this structure was suggested as\na way to ensure they *can* be implemented.  All of the real work is behind the\n`LogSink` interface.\n\n[warning-makes-no-sense]: http://dave.cheney.net/2015/11/05/lets-talk-about-logging\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/discard.go",
    "content": "/*\nCopyright 2020 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage logr\n\n// Discard returns a Logger that discards all messages logged to it.  It can be\n// used whenever the caller is not interested in the logs.  Logger instances\n// produced by this function always compare as equal.\nfunc Discard() Logger {\n\treturn New(nil)\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/funcr/funcr.go",
    "content": "/*\nCopyright 2021 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package funcr implements formatting of structured log messages and\n// optionally captures the call site and timestamp.\n//\n// The simplest way to use it is via its implementation of a\n// github.com/go-logr/logr.LogSink with output through an arbitrary\n// \"write\" function.  See New and NewJSON for details.\n//\n// # Custom LogSinks\n//\n// For users who need more control, a funcr.Formatter can be embedded inside\n// your own custom LogSink implementation. This is useful when the LogSink\n// needs to implement additional methods, for example.\n//\n// # Formatting\n//\n// This will respect logr.Marshaler, fmt.Stringer, and error interfaces for\n// values which are being logged.  When rendering a struct, funcr will use Go's\n// standard JSON tags (all except \"string\").\npackage funcr\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/go-logr/logr\"\n)\n\n// New returns a logr.Logger which is implemented by an arbitrary function.\nfunc New(fn func(prefix, args string), opts Options) logr.Logger {\n\treturn logr.New(newSink(fn, NewFormatter(opts)))\n}\n\n// NewJSON returns a logr.Logger which is implemented by an arbitrary function\n// and produces JSON output.\nfunc NewJSON(fn func(obj string), opts Options) logr.Logger {\n\tfnWrapper := func(_, obj string) {\n\t\tfn(obj)\n\t}\n\treturn logr.New(newSink(fnWrapper, NewFormatterJSON(opts)))\n}\n\n// Underlier exposes access to the underlying logging function. Since\n// callers only have a logr.Logger, they have to know which\n// implementation is in use, so this interface is less of an\n// abstraction and more of a way to test type conversion.\ntype Underlier interface {\n\tGetUnderlying() func(prefix, args string)\n}\n\nfunc newSink(fn func(prefix, args string), formatter Formatter) logr.LogSink {\n\tl := &fnlogger{\n\t\tFormatter: formatter,\n\t\twrite:     fn,\n\t}\n\t// For skipping fnlogger.Info and fnlogger.Error.\n\tl.Formatter.AddCallDepth(1)\n\treturn l\n}\n\n// Options carries parameters which influence the way logs are generated.\ntype Options struct {\n\t// LogCaller tells funcr to add a \"caller\" key to some or all log lines.\n\t// This has some overhead, so some users might not want it.\n\tLogCaller MessageClass\n\n\t// LogCallerFunc tells funcr to also log the calling function name.  This\n\t// has no effect if caller logging is not enabled (see Options.LogCaller).\n\tLogCallerFunc bool\n\n\t// LogTimestamp tells funcr to add a \"ts\" key to log lines.  This has some\n\t// overhead, so some users might not want it.\n\tLogTimestamp bool\n\n\t// TimestampFormat tells funcr how to render timestamps when LogTimestamp\n\t// is enabled.  If not specified, a default format will be used.  For more\n\t// details, see docs for Go's time.Layout.\n\tTimestampFormat string\n\n\t// Verbosity tells funcr which V logs to produce.  Higher values enable\n\t// more logs.  Info logs at or below this level will be written, while logs\n\t// above this level will be discarded.\n\tVerbosity int\n\n\t// RenderBuiltinsHook allows users to mutate the list of key-value pairs\n\t// while a log line is being rendered.  The kvList argument follows logr\n\t// conventions - each pair of slice elements is comprised of a string key\n\t// and an arbitrary value (verified and sanitized before calling this\n\t// hook).  The value returned must follow the same conventions.  This hook\n\t// can be used to audit or modify logged data.  For example, you might want\n\t// to prefix all of funcr's built-in keys with some string.  This hook is\n\t// only called for built-in (provided by funcr itself) key-value pairs.\n\t// Equivalent hooks are offered for key-value pairs saved via\n\t// logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and\n\t// for user-provided pairs (see RenderArgsHook).\n\tRenderBuiltinsHook func(kvList []interface{}) []interface{}\n\n\t// RenderValuesHook is the same as RenderBuiltinsHook, except that it is\n\t// only called for key-value pairs saved via logr.Logger.WithValues.  See\n\t// RenderBuiltinsHook for more details.\n\tRenderValuesHook func(kvList []interface{}) []interface{}\n\n\t// RenderArgsHook is the same as RenderBuiltinsHook, except that it is only\n\t// called for key-value pairs passed directly to Info and Error.  See\n\t// RenderBuiltinsHook for more details.\n\tRenderArgsHook func(kvList []interface{}) []interface{}\n\n\t// MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct\n\t// that contains a struct, etc.) it may log.  Every time it finds a struct,\n\t// slice, array, or map the depth is increased by one.  When the maximum is\n\t// reached, the value will be converted to a string indicating that the max\n\t// depth has been exceeded.  If this field is not specified, a default\n\t// value will be used.\n\tMaxLogDepth int\n}\n\n// MessageClass indicates which category or categories of messages to consider.\ntype MessageClass int\n\nconst (\n\t// None ignores all message classes.\n\tNone MessageClass = iota\n\t// All considers all message classes.\n\tAll\n\t// Info only considers info messages.\n\tInfo\n\t// Error only considers error messages.\n\tError\n)\n\n// fnlogger inherits some of its LogSink implementation from Formatter\n// and just needs to add some glue code.\ntype fnlogger struct {\n\tFormatter\n\twrite func(prefix, args string)\n}\n\nfunc (l fnlogger) WithName(name string) logr.LogSink {\n\tl.Formatter.AddName(name)\n\treturn &l\n}\n\nfunc (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink {\n\tl.Formatter.AddValues(kvList)\n\treturn &l\n}\n\nfunc (l fnlogger) WithCallDepth(depth int) logr.LogSink {\n\tl.Formatter.AddCallDepth(depth)\n\treturn &l\n}\n\nfunc (l fnlogger) Info(level int, msg string, kvList ...interface{}) {\n\tprefix, args := l.FormatInfo(level, msg, kvList)\n\tl.write(prefix, args)\n}\n\nfunc (l fnlogger) Error(err error, msg string, kvList ...interface{}) {\n\tprefix, args := l.FormatError(err, msg, kvList)\n\tl.write(prefix, args)\n}\n\nfunc (l fnlogger) GetUnderlying() func(prefix, args string) {\n\treturn l.write\n}\n\n// Assert conformance to the interfaces.\nvar _ logr.LogSink = &fnlogger{}\nvar _ logr.CallDepthLogSink = &fnlogger{}\nvar _ Underlier = &fnlogger{}\n\n// NewFormatter constructs a Formatter which emits a JSON-like key=value format.\nfunc NewFormatter(opts Options) Formatter {\n\treturn newFormatter(opts, outputKeyValue)\n}\n\n// NewFormatterJSON constructs a Formatter which emits strict JSON.\nfunc NewFormatterJSON(opts Options) Formatter {\n\treturn newFormatter(opts, outputJSON)\n}\n\n// Defaults for Options.\nconst defaultTimestampFormat = \"2006-01-02 15:04:05.000000\"\nconst defaultMaxLogDepth = 16\n\nfunc newFormatter(opts Options, outfmt outputFormat) Formatter {\n\tif opts.TimestampFormat == \"\" {\n\t\topts.TimestampFormat = defaultTimestampFormat\n\t}\n\tif opts.MaxLogDepth == 0 {\n\t\topts.MaxLogDepth = defaultMaxLogDepth\n\t}\n\tf := Formatter{\n\t\toutputFormat: outfmt,\n\t\tprefix:       \"\",\n\t\tvalues:       nil,\n\t\tdepth:        0,\n\t\topts:         &opts,\n\t}\n\treturn f\n}\n\n// Formatter is an opaque struct which can be embedded in a LogSink\n// implementation. It should be constructed with NewFormatter. Some of\n// its methods directly implement logr.LogSink.\ntype Formatter struct {\n\toutputFormat outputFormat\n\tprefix       string\n\tvalues       []interface{}\n\tvaluesStr    string\n\tdepth        int\n\topts         *Options\n}\n\n// outputFormat indicates which outputFormat to use.\ntype outputFormat int\n\nconst (\n\t// outputKeyValue emits a JSON-like key=value format, but not strict JSON.\n\toutputKeyValue outputFormat = iota\n\t// outputJSON emits strict JSON.\n\toutputJSON\n)\n\n// PseudoStruct is a list of key-value pairs that gets logged as a struct.\ntype PseudoStruct []interface{}\n\n// render produces a log line, ready to use.\nfunc (f Formatter) render(builtins, args []interface{}) string {\n\t// Empirically bytes.Buffer is faster than strings.Builder for this.\n\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\tif f.outputFormat == outputJSON {\n\t\tbuf.WriteByte('{')\n\t}\n\tvals := builtins\n\tif hook := f.opts.RenderBuiltinsHook; hook != nil {\n\t\tvals = hook(f.sanitize(vals))\n\t}\n\tf.flatten(buf, vals, false, false) // keys are ours, no need to escape\n\tcontinuing := len(builtins) > 0\n\tif len(f.valuesStr) > 0 {\n\t\tif continuing {\n\t\t\tif f.outputFormat == outputJSON {\n\t\t\t\tbuf.WriteByte(',')\n\t\t\t} else {\n\t\t\t\tbuf.WriteByte(' ')\n\t\t\t}\n\t\t}\n\t\tcontinuing = true\n\t\tbuf.WriteString(f.valuesStr)\n\t}\n\tvals = args\n\tif hook := f.opts.RenderArgsHook; hook != nil {\n\t\tvals = hook(f.sanitize(vals))\n\t}\n\tf.flatten(buf, vals, continuing, true) // escape user-provided keys\n\tif f.outputFormat == outputJSON {\n\t\tbuf.WriteByte('}')\n\t}\n\treturn buf.String()\n}\n\n// flatten renders a list of key-value pairs into a buffer.  If continuing is\n// true, it assumes that the buffer has previous values and will emit a\n// separator (which depends on the output format) before the first pair it\n// writes.  If escapeKeys is true, the keys are assumed to have\n// non-JSON-compatible characters in them and must be evaluated for escapes.\n//\n// This function returns a potentially modified version of kvList, which\n// ensures that there is a value for every key (adding a value if needed) and\n// that each key is a string (substituting a key if needed).\nfunc (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} {\n\t// This logic overlaps with sanitize() but saves one type-cast per key,\n\t// which can be measurable.\n\tif len(kvList)%2 != 0 {\n\t\tkvList = append(kvList, noValue)\n\t}\n\tfor i := 0; i < len(kvList); i += 2 {\n\t\tk, ok := kvList[i].(string)\n\t\tif !ok {\n\t\t\tk = f.nonStringKey(kvList[i])\n\t\t\tkvList[i] = k\n\t\t}\n\t\tv := kvList[i+1]\n\n\t\tif i > 0 || continuing {\n\t\t\tif f.outputFormat == outputJSON {\n\t\t\t\tbuf.WriteByte(',')\n\t\t\t} else {\n\t\t\t\t// In theory the format could be something we don't understand.  In\n\t\t\t\t// practice, we control it, so it won't be.\n\t\t\t\tbuf.WriteByte(' ')\n\t\t\t}\n\t\t}\n\n\t\tif escapeKeys {\n\t\t\tbuf.WriteString(prettyString(k))\n\t\t} else {\n\t\t\t// this is faster\n\t\t\tbuf.WriteByte('\"')\n\t\t\tbuf.WriteString(k)\n\t\t\tbuf.WriteByte('\"')\n\t\t}\n\t\tif f.outputFormat == outputJSON {\n\t\t\tbuf.WriteByte(':')\n\t\t} else {\n\t\t\tbuf.WriteByte('=')\n\t\t}\n\t\tbuf.WriteString(f.pretty(v))\n\t}\n\treturn kvList\n}\n\nfunc (f Formatter) pretty(value interface{}) string {\n\treturn f.prettyWithFlags(value, 0, 0)\n}\n\nconst (\n\tflagRawStruct = 0x1 // do not print braces on structs\n)\n\n// TODO: This is not fast. Most of the overhead goes here.\nfunc (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string {\n\tif depth > f.opts.MaxLogDepth {\n\t\treturn `\"<max-log-depth-exceeded>\"`\n\t}\n\n\t// Handle types that take full control of logging.\n\tif v, ok := value.(logr.Marshaler); ok {\n\t\t// Replace the value with what the type wants to get logged.\n\t\t// That then gets handled below via reflection.\n\t\tvalue = invokeMarshaler(v)\n\t}\n\n\t// Handle types that want to format themselves.\n\tswitch v := value.(type) {\n\tcase fmt.Stringer:\n\t\tvalue = invokeStringer(v)\n\tcase error:\n\t\tvalue = invokeError(v)\n\t}\n\n\t// Handling the most common types without reflect is a small perf win.\n\tswitch v := value.(type) {\n\tcase bool:\n\t\treturn strconv.FormatBool(v)\n\tcase string:\n\t\treturn prettyString(v)\n\tcase int:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int8:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int16:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int32:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase int64:\n\t\treturn strconv.FormatInt(int64(v), 10)\n\tcase uint:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint8:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint16:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint32:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase uint64:\n\t\treturn strconv.FormatUint(v, 10)\n\tcase uintptr:\n\t\treturn strconv.FormatUint(uint64(v), 10)\n\tcase float32:\n\t\treturn strconv.FormatFloat(float64(v), 'f', -1, 32)\n\tcase float64:\n\t\treturn strconv.FormatFloat(v, 'f', -1, 64)\n\tcase complex64:\n\t\treturn `\"` + strconv.FormatComplex(complex128(v), 'f', -1, 64) + `\"`\n\tcase complex128:\n\t\treturn `\"` + strconv.FormatComplex(v, 'f', -1, 128) + `\"`\n\tcase PseudoStruct:\n\t\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\t\tv = f.sanitize(v)\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('{')\n\t\t}\n\t\tfor i := 0; i < len(v); i += 2 {\n\t\t\tif i > 0 {\n\t\t\t\tbuf.WriteByte(',')\n\t\t\t}\n\t\t\tk, _ := v[i].(string) // sanitize() above means no need to check success\n\t\t\t// arbitrary keys might need escaping\n\t\t\tbuf.WriteString(prettyString(k))\n\t\t\tbuf.WriteByte(':')\n\t\t\tbuf.WriteString(f.prettyWithFlags(v[i+1], 0, depth+1))\n\t\t}\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('}')\n\t\t}\n\t\treturn buf.String()\n\t}\n\n\tbuf := bytes.NewBuffer(make([]byte, 0, 256))\n\tt := reflect.TypeOf(value)\n\tif t == nil {\n\t\treturn \"null\"\n\t}\n\tv := reflect.ValueOf(value)\n\tswitch t.Kind() {\n\tcase reflect.Bool:\n\t\treturn strconv.FormatBool(v.Bool())\n\tcase reflect.String:\n\t\treturn prettyString(v.String())\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn strconv.FormatInt(int64(v.Int()), 10)\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn strconv.FormatUint(uint64(v.Uint()), 10)\n\tcase reflect.Float32:\n\t\treturn strconv.FormatFloat(float64(v.Float()), 'f', -1, 32)\n\tcase reflect.Float64:\n\t\treturn strconv.FormatFloat(v.Float(), 'f', -1, 64)\n\tcase reflect.Complex64:\n\t\treturn `\"` + strconv.FormatComplex(complex128(v.Complex()), 'f', -1, 64) + `\"`\n\tcase reflect.Complex128:\n\t\treturn `\"` + strconv.FormatComplex(v.Complex(), 'f', -1, 128) + `\"`\n\tcase reflect.Struct:\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('{')\n\t\t}\n\t\tprintComma := false // testing i>0 is not enough because of JSON omitted fields\n\t\tfor i := 0; i < t.NumField(); i++ {\n\t\t\tfld := t.Field(i)\n\t\t\tif fld.PkgPath != \"\" {\n\t\t\t\t// reflect says this field is only defined for non-exported fields.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif !v.Field(i).CanInterface() {\n\t\t\t\t// reflect isn't clear exactly what this means, but we can't use it.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tname := \"\"\n\t\t\tomitempty := false\n\t\t\tif tag, found := fld.Tag.Lookup(\"json\"); found {\n\t\t\t\tif tag == \"-\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif comma := strings.Index(tag, \",\"); comma != -1 {\n\t\t\t\t\tif n := tag[:comma]; n != \"\" {\n\t\t\t\t\t\tname = n\n\t\t\t\t\t}\n\t\t\t\t\trest := tag[comma:]\n\t\t\t\t\tif strings.Contains(rest, \",omitempty,\") || strings.HasSuffix(rest, \",omitempty\") {\n\t\t\t\t\t\tomitempty = true\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tname = tag\n\t\t\t\t}\n\t\t\t}\n\t\t\tif omitempty && isEmpty(v.Field(i)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif printComma {\n\t\t\t\tbuf.WriteByte(',')\n\t\t\t}\n\t\t\tprintComma = true // if we got here, we are rendering a field\n\t\t\tif fld.Anonymous && fld.Type.Kind() == reflect.Struct && name == \"\" {\n\t\t\t\tbuf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), flags|flagRawStruct, depth+1))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif name == \"\" {\n\t\t\t\tname = fld.Name\n\t\t\t}\n\t\t\t// field names can't contain characters which need escaping\n\t\t\tbuf.WriteByte('\"')\n\t\t\tbuf.WriteString(name)\n\t\t\tbuf.WriteByte('\"')\n\t\t\tbuf.WriteByte(':')\n\t\t\tbuf.WriteString(f.prettyWithFlags(v.Field(i).Interface(), 0, depth+1))\n\t\t}\n\t\tif flags&flagRawStruct == 0 {\n\t\t\tbuf.WriteByte('}')\n\t\t}\n\t\treturn buf.String()\n\tcase reflect.Slice, reflect.Array:\n\t\t// If this is outputing as JSON make sure this isn't really a json.RawMessage.\n\t\t// If so just emit \"as-is\" and don't pretty it as that will just print\n\t\t// it as [X,Y,Z,...] which isn't terribly useful vs the string form you really want.\n\t\tif f.outputFormat == outputJSON {\n\t\t\tif rm, ok := value.(json.RawMessage); ok {\n\t\t\t\t// If it's empty make sure we emit an empty value as the array style would below.\n\t\t\t\tif len(rm) > 0 {\n\t\t\t\t\tbuf.Write(rm)\n\t\t\t\t} else {\n\t\t\t\t\tbuf.WriteString(\"null\")\n\t\t\t\t}\n\t\t\t\treturn buf.String()\n\t\t\t}\n\t\t}\n\t\tbuf.WriteByte('[')\n\t\tfor i := 0; i < v.Len(); i++ {\n\t\t\tif i > 0 {\n\t\t\t\tbuf.WriteByte(',')\n\t\t\t}\n\t\t\te := v.Index(i)\n\t\t\tbuf.WriteString(f.prettyWithFlags(e.Interface(), 0, depth+1))\n\t\t}\n\t\tbuf.WriteByte(']')\n\t\treturn buf.String()\n\tcase reflect.Map:\n\t\tbuf.WriteByte('{')\n\t\t// This does not sort the map keys, for best perf.\n\t\tit := v.MapRange()\n\t\ti := 0\n\t\tfor it.Next() {\n\t\t\tif i > 0 {\n\t\t\t\tbuf.WriteByte(',')\n\t\t\t}\n\t\t\t// If a map key supports TextMarshaler, use it.\n\t\t\tkeystr := \"\"\n\t\t\tif m, ok := it.Key().Interface().(encoding.TextMarshaler); ok {\n\t\t\t\ttxt, err := m.MarshalText()\n\t\t\t\tif err != nil {\n\t\t\t\t\tkeystr = fmt.Sprintf(\"<error-MarshalText: %s>\", err.Error())\n\t\t\t\t} else {\n\t\t\t\t\tkeystr = string(txt)\n\t\t\t\t}\n\t\t\t\tkeystr = prettyString(keystr)\n\t\t\t} else {\n\t\t\t\t// prettyWithFlags will produce already-escaped values\n\t\t\t\tkeystr = f.prettyWithFlags(it.Key().Interface(), 0, depth+1)\n\t\t\t\tif t.Key().Kind() != reflect.String {\n\t\t\t\t\t// JSON only does string keys.  Unlike Go's standard JSON, we'll\n\t\t\t\t\t// convert just about anything to a string.\n\t\t\t\t\tkeystr = prettyString(keystr)\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuf.WriteString(keystr)\n\t\t\tbuf.WriteByte(':')\n\t\t\tbuf.WriteString(f.prettyWithFlags(it.Value().Interface(), 0, depth+1))\n\t\t\ti++\n\t\t}\n\t\tbuf.WriteByte('}')\n\t\treturn buf.String()\n\tcase reflect.Ptr, reflect.Interface:\n\t\tif v.IsNil() {\n\t\t\treturn \"null\"\n\t\t}\n\t\treturn f.prettyWithFlags(v.Elem().Interface(), 0, depth)\n\t}\n\treturn fmt.Sprintf(`\"<unhandled-%s>\"`, t.Kind().String())\n}\n\nfunc prettyString(s string) string {\n\t// Avoid escaping (which does allocations) if we can.\n\tif needsEscape(s) {\n\t\treturn strconv.Quote(s)\n\t}\n\tb := bytes.NewBuffer(make([]byte, 0, 1024))\n\tb.WriteByte('\"')\n\tb.WriteString(s)\n\tb.WriteByte('\"')\n\treturn b.String()\n}\n\n// needsEscape determines whether the input string needs to be escaped or not,\n// without doing any allocations.\nfunc needsEscape(s string) bool {\n\tfor _, r := range s {\n\t\tif !strconv.IsPrint(r) || r == '\\\\' || r == '\"' {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isEmpty(v reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn v.Len() == 0\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn v.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.Complex64, reflect.Complex128:\n\t\treturn v.Complex() == 0\n\tcase reflect.Interface, reflect.Ptr:\n\t\treturn v.IsNil()\n\t}\n\treturn false\n}\n\nfunc invokeMarshaler(m logr.Marshaler) (ret interface{}) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tret = fmt.Sprintf(\"<panic: %s>\", r)\n\t\t}\n\t}()\n\treturn m.MarshalLog()\n}\n\nfunc invokeStringer(s fmt.Stringer) (ret string) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tret = fmt.Sprintf(\"<panic: %s>\", r)\n\t\t}\n\t}()\n\treturn s.String()\n}\n\nfunc invokeError(e error) (ret string) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tret = fmt.Sprintf(\"<panic: %s>\", r)\n\t\t}\n\t}()\n\treturn e.Error()\n}\n\n// Caller represents the original call site for a log line, after considering\n// logr.Logger.WithCallDepth and logr.Logger.WithCallStackHelper.  The File and\n// Line fields will always be provided, while the Func field is optional.\n// Users can set the render hook fields in Options to examine logged key-value\n// pairs, one of which will be {\"caller\", Caller} if the Options.LogCaller\n// field is enabled for the given MessageClass.\ntype Caller struct {\n\t// File is the basename of the file for this call site.\n\tFile string `json:\"file\"`\n\t// Line is the line number in the file for this call site.\n\tLine int `json:\"line\"`\n\t// Func is the function name for this call site, or empty if\n\t// Options.LogCallerFunc is not enabled.\n\tFunc string `json:\"function,omitempty\"`\n}\n\nfunc (f Formatter) caller() Caller {\n\t// +1 for this frame, +1 for Info/Error.\n\tpc, file, line, ok := runtime.Caller(f.depth + 2)\n\tif !ok {\n\t\treturn Caller{\"<unknown>\", 0, \"\"}\n\t}\n\tfn := \"\"\n\tif f.opts.LogCallerFunc {\n\t\tif fp := runtime.FuncForPC(pc); fp != nil {\n\t\t\tfn = fp.Name()\n\t\t}\n\t}\n\n\treturn Caller{filepath.Base(file), line, fn}\n}\n\nconst noValue = \"<no-value>\"\n\nfunc (f Formatter) nonStringKey(v interface{}) string {\n\treturn fmt.Sprintf(\"<non-string-key: %s>\", f.snippet(v))\n}\n\n// snippet produces a short snippet string of an arbitrary value.\nfunc (f Formatter) snippet(v interface{}) string {\n\tconst snipLen = 16\n\n\tsnip := f.pretty(v)\n\tif len(snip) > snipLen {\n\t\tsnip = snip[:snipLen]\n\t}\n\treturn snip\n}\n\n// sanitize ensures that a list of key-value pairs has a value for every key\n// (adding a value if needed) and that each key is a string (substituting a key\n// if needed).\nfunc (f Formatter) sanitize(kvList []interface{}) []interface{} {\n\tif len(kvList)%2 != 0 {\n\t\tkvList = append(kvList, noValue)\n\t}\n\tfor i := 0; i < len(kvList); i += 2 {\n\t\t_, ok := kvList[i].(string)\n\t\tif !ok {\n\t\t\tkvList[i] = f.nonStringKey(kvList[i])\n\t\t}\n\t}\n\treturn kvList\n}\n\n// Init configures this Formatter from runtime info, such as the call depth\n// imposed by logr itself.\n// Note that this receiver is a pointer, so depth can be saved.\nfunc (f *Formatter) Init(info logr.RuntimeInfo) {\n\tf.depth += info.CallDepth\n}\n\n// Enabled checks whether an info message at the given level should be logged.\nfunc (f Formatter) Enabled(level int) bool {\n\treturn level <= f.opts.Verbosity\n}\n\n// GetDepth returns the current depth of this Formatter.  This is useful for\n// implementations which do their own caller attribution.\nfunc (f Formatter) GetDepth() int {\n\treturn f.depth\n}\n\n// FormatInfo renders an Info log message into strings.  The prefix will be\n// empty when no names were set (via AddNames), or when the output is\n// configured for JSON.\nfunc (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) {\n\targs := make([]interface{}, 0, 64) // using a constant here impacts perf\n\tprefix = f.prefix\n\tif f.outputFormat == outputJSON {\n\t\targs = append(args, \"logger\", prefix)\n\t\tprefix = \"\"\n\t}\n\tif f.opts.LogTimestamp {\n\t\targs = append(args, \"ts\", time.Now().Format(f.opts.TimestampFormat))\n\t}\n\tif policy := f.opts.LogCaller; policy == All || policy == Info {\n\t\targs = append(args, \"caller\", f.caller())\n\t}\n\targs = append(args, \"level\", level, \"msg\", msg)\n\treturn prefix, f.render(args, kvList)\n}\n\n// FormatError renders an Error log message into strings.  The prefix will be\n// empty when no names were set (via AddNames),  or when the output is\n// configured for JSON.\nfunc (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) {\n\targs := make([]interface{}, 0, 64) // using a constant here impacts perf\n\tprefix = f.prefix\n\tif f.outputFormat == outputJSON {\n\t\targs = append(args, \"logger\", prefix)\n\t\tprefix = \"\"\n\t}\n\tif f.opts.LogTimestamp {\n\t\targs = append(args, \"ts\", time.Now().Format(f.opts.TimestampFormat))\n\t}\n\tif policy := f.opts.LogCaller; policy == All || policy == Error {\n\t\targs = append(args, \"caller\", f.caller())\n\t}\n\targs = append(args, \"msg\", msg)\n\tvar loggableErr interface{}\n\tif err != nil {\n\t\tloggableErr = err.Error()\n\t}\n\targs = append(args, \"error\", loggableErr)\n\treturn f.prefix, f.render(args, kvList)\n}\n\n// AddName appends the specified name.  funcr uses '/' characters to separate\n// name elements.  Callers should not pass '/' in the provided name string, but\n// this library does not actually enforce that.\nfunc (f *Formatter) AddName(name string) {\n\tif len(f.prefix) > 0 {\n\t\tf.prefix += \"/\"\n\t}\n\tf.prefix += name\n}\n\n// AddValues adds key-value pairs to the set of saved values to be logged with\n// each log line.\nfunc (f *Formatter) AddValues(kvList []interface{}) {\n\t// Three slice args forces a copy.\n\tn := len(f.values)\n\tf.values = append(f.values[:n:n], kvList...)\n\n\tvals := f.values\n\tif hook := f.opts.RenderValuesHook; hook != nil {\n\t\tvals = hook(f.sanitize(vals))\n\t}\n\n\t// Pre-render values, so we don't have to do it on each Info/Error call.\n\tbuf := bytes.NewBuffer(make([]byte, 0, 1024))\n\tf.flatten(buf, vals, false, true) // escape user-provided keys\n\tf.valuesStr = buf.String()\n}\n\n// AddCallDepth increases the number of stack-frames to skip when attributing\n// the log line to a file and line.\nfunc (f *Formatter) AddCallDepth(depth int) {\n\tf.depth += depth\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/logr/logr.go",
    "content": "/*\nCopyright 2019 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// This design derives from Dave Cheney's blog:\n//     http://dave.cheney.net/2015/11/05/lets-talk-about-logging\n\n// Package logr defines a general-purpose logging API and abstract interfaces\n// to back that API.  Packages in the Go ecosystem can depend on this package,\n// while callers can implement logging with whatever backend is appropriate.\n//\n// # Usage\n//\n// Logging is done using a Logger instance.  Logger is a concrete type with\n// methods, which defers the actual logging to a LogSink interface.  The main\n// methods of Logger are Info() and Error().  Arguments to Info() and Error()\n// are key/value pairs rather than printf-style formatted strings, emphasizing\n// \"structured logging\".\n//\n// With Go's standard log package, we might write:\n//\n//\tlog.Printf(\"setting target value %s\", targetValue)\n//\n// With logr's structured logging, we'd write:\n//\n//\tlogger.Info(\"setting target\", \"value\", targetValue)\n//\n// Errors are much the same.  Instead of:\n//\n//\tlog.Printf(\"failed to open the pod bay door for user %s: %v\", user, err)\n//\n// We'd write:\n//\n//\tlogger.Error(err, \"failed to open the pod bay door\", \"user\", user)\n//\n// Info() and Error() are very similar, but they are separate methods so that\n// LogSink implementations can choose to do things like attach additional\n// information (such as stack traces) on calls to Error(). Error() messages are\n// always logged, regardless of the current verbosity.  If there is no error\n// instance available, passing nil is valid.\n//\n// # Verbosity\n//\n// Often we want to log information only when the application in \"verbose\n// mode\".  To write log lines that are more verbose, Logger has a V() method.\n// The higher the V-level of a log line, the less critical it is considered.\n// Log-lines with V-levels that are not enabled (as per the LogSink) will not\n// be written.  Level V(0) is the default, and logger.V(0).Info() has the same\n// meaning as logger.Info().  Negative V-levels have the same meaning as V(0).\n// Error messages do not have a verbosity level and are always logged.\n//\n// Where we might have written:\n//\n//\tif flVerbose >= 2 {\n//\t    log.Printf(\"an unusual thing happened\")\n//\t}\n//\n// We can write:\n//\n//\tlogger.V(2).Info(\"an unusual thing happened\")\n//\n// # Logger Names\n//\n// Logger instances can have name strings so that all messages logged through\n// that instance have additional context.  For example, you might want to add\n// a subsystem name:\n//\n//\tlogger.WithName(\"compactor\").Info(\"started\", \"time\", time.Now())\n//\n// The WithName() method returns a new Logger, which can be passed to\n// constructors or other functions for further use.  Repeated use of WithName()\n// will accumulate name \"segments\".  These name segments will be joined in some\n// way by the LogSink implementation.  It is strongly recommended that name\n// segments contain simple identifiers (letters, digits, and hyphen), and do\n// not contain characters that could muddle the log output or confuse the\n// joining operation (e.g. whitespace, commas, periods, slashes, brackets,\n// quotes, etc).\n//\n// # Saved Values\n//\n// Logger instances can store any number of key/value pairs, which will be\n// logged alongside all messages logged through that instance.  For example,\n// you might want to create a Logger instance per managed object:\n//\n// With the standard log package, we might write:\n//\n//\tlog.Printf(\"decided to set field foo to value %q for object %s/%s\",\n//\t    targetValue, object.Namespace, object.Name)\n//\n// With logr we'd write:\n//\n//\t// Elsewhere: set up the logger to log the object name.\n//\tobj.logger = mainLogger.WithValues(\n//\t    \"name\", obj.name, \"namespace\", obj.namespace)\n//\n//\t// later on...\n//\tobj.logger.Info(\"setting foo\", \"value\", targetValue)\n//\n// # Best Practices\n//\n// Logger has very few hard rules, with the goal that LogSink implementations\n// might have a lot of freedom to differentiate.  There are, however, some\n// things to consider.\n//\n// The log message consists of a constant message attached to the log line.\n// This should generally be a simple description of what's occurring, and should\n// never be a format string.  Variable information can then be attached using\n// named values.\n//\n// Keys are arbitrary strings, but should generally be constant values.  Values\n// may be any Go value, but how the value is formatted is determined by the\n// LogSink implementation.\n//\n// Logger instances are meant to be passed around by value. Code that receives\n// such a value can call its methods without having to check whether the\n// instance is ready for use.\n//\n// Calling methods with the null logger (Logger{}) as instance will crash\n// because it has no LogSink. Therefore this null logger should never be passed\n// around. For cases where passing a logger is optional, a pointer to Logger\n// should be used.\n//\n// # Key Naming Conventions\n//\n// Keys are not strictly required to conform to any specification or regex, but\n// it is recommended that they:\n//   - be human-readable and meaningful (not auto-generated or simple ordinals)\n//   - be constant (not dependent on input data)\n//   - contain only printable characters\n//   - not contain whitespace or punctuation\n//   - use lower case for simple keys and lowerCamelCase for more complex ones\n//\n// These guidelines help ensure that log data is processed properly regardless\n// of the log implementation.  For example, log implementations will try to\n// output JSON data or will store data for later database (e.g. SQL) queries.\n//\n// While users are generally free to use key names of their choice, it's\n// generally best to avoid using the following keys, as they're frequently used\n// by implementations:\n//   - \"caller\": the calling information (file/line) of a particular log line\n//   - \"error\": the underlying error value in the `Error` method\n//   - \"level\": the log level\n//   - \"logger\": the name of the associated logger\n//   - \"msg\": the log message\n//   - \"stacktrace\": the stack trace associated with a particular log line or\n//     error (often from the `Error` message)\n//   - \"ts\": the timestamp for a log line\n//\n// Implementations are encouraged to make use of these keys to represent the\n// above concepts, when necessary (for example, in a pure-JSON output form, it\n// would be necessary to represent at least message and timestamp as ordinary\n// named values).\n//\n// # Break Glass\n//\n// Implementations may choose to give callers access to the underlying\n// logging implementation.  The recommended pattern for this is:\n//\n//\t// Underlier exposes access to the underlying logging implementation.\n//\t// Since callers only have a logr.Logger, they have to know which\n//\t// implementation is in use, so this interface is less of an abstraction\n//\t// and more of way to test type conversion.\n//\ttype Underlier interface {\n//\t    GetUnderlying() <underlying-type>\n//\t}\n//\n// Logger grants access to the sink to enable type assertions like this:\n//\n//\tfunc DoSomethingWithImpl(log logr.Logger) {\n//\t    if underlier, ok := log.GetSink().(impl.Underlier); ok {\n//\t       implLogger := underlier.GetUnderlying()\n//\t       ...\n//\t    }\n//\t}\n//\n// Custom `With*` functions can be implemented by copying the complete\n// Logger struct and replacing the sink in the copy:\n//\n//\t// WithFooBar changes the foobar parameter in the log sink and returns a\n//\t// new logger with that modified sink.  It does nothing for loggers where\n//\t// the sink doesn't support that parameter.\n//\tfunc WithFoobar(log logr.Logger, foobar int) logr.Logger {\n//\t   if foobarLogSink, ok := log.GetSink().(FoobarSink); ok {\n//\t      log = log.WithSink(foobarLogSink.WithFooBar(foobar))\n//\t   }\n//\t   return log\n//\t}\n//\n// Don't use New to construct a new Logger with a LogSink retrieved from an\n// existing Logger. Source code attribution might not work correctly and\n// unexported fields in Logger get lost.\n//\n// Beware that the same LogSink instance may be shared by different logger\n// instances. Calling functions that modify the LogSink will affect all of\n// those.\npackage logr\n\nimport (\n\t\"context\"\n)\n\n// New returns a new Logger instance.  This is primarily used by libraries\n// implementing LogSink, rather than end users.  Passing a nil sink will create\n// a Logger which discards all log lines.\nfunc New(sink LogSink) Logger {\n\tlogger := Logger{}\n\tlogger.setSink(sink)\n\tif sink != nil {\n\t\tsink.Init(runtimeInfo)\n\t}\n\treturn logger\n}\n\n// setSink stores the sink and updates any related fields. It mutates the\n// logger and thus is only safe to use for loggers that are not currently being\n// used concurrently.\nfunc (l *Logger) setSink(sink LogSink) {\n\tl.sink = sink\n}\n\n// GetSink returns the stored sink.\nfunc (l Logger) GetSink() LogSink {\n\treturn l.sink\n}\n\n// WithSink returns a copy of the logger with the new sink.\nfunc (l Logger) WithSink(sink LogSink) Logger {\n\tl.setSink(sink)\n\treturn l\n}\n\n// Logger is an interface to an abstract logging implementation.  This is a\n// concrete type for performance reasons, but all the real work is passed on to\n// a LogSink.  Implementations of LogSink should provide their own constructors\n// that return Logger, not LogSink.\n//\n// The underlying sink can be accessed through GetSink and be modified through\n// WithSink. This enables the implementation of custom extensions (see \"Break\n// Glass\" in the package documentation). Normally the sink should be used only\n// indirectly.\ntype Logger struct {\n\tsink  LogSink\n\tlevel int\n}\n\n// Enabled tests whether this Logger is enabled.  For example, commandline\n// flags might be used to set the logging verbosity and disable some info logs.\nfunc (l Logger) Enabled() bool {\n\treturn l.sink != nil && l.sink.Enabled(l.level)\n}\n\n// Info logs a non-error message with the given key/value pairs as context.\n//\n// The msg argument should be used to add some constant description to the log\n// line.  The key/value pairs can then be used to add additional variable\n// information.  The key/value pairs must alternate string keys and arbitrary\n// values.\nfunc (l Logger) Info(msg string, keysAndValues ...interface{}) {\n\tif l.sink == nil {\n\t\treturn\n\t}\n\tif l.Enabled() {\n\t\tif withHelper, ok := l.sink.(CallStackHelperLogSink); ok {\n\t\t\twithHelper.GetCallStackHelper()()\n\t\t}\n\t\tl.sink.Info(l.level, msg, keysAndValues...)\n\t}\n}\n\n// Error logs an error, with the given message and key/value pairs as context.\n// It functions similarly to Info, but may have unique behavior, and should be\n// preferred for logging errors (see the package documentations for more\n// information). The log message will always be emitted, regardless of\n// verbosity level.\n//\n// The msg argument should be used to add context to any underlying error,\n// while the err argument should be used to attach the actual error that\n// triggered this log line, if present. The err parameter is optional\n// and nil may be passed instead of an error instance.\nfunc (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {\n\tif l.sink == nil {\n\t\treturn\n\t}\n\tif withHelper, ok := l.sink.(CallStackHelperLogSink); ok {\n\t\twithHelper.GetCallStackHelper()()\n\t}\n\tl.sink.Error(err, msg, keysAndValues...)\n}\n\n// V returns a new Logger instance for a specific verbosity level, relative to\n// this Logger.  In other words, V-levels are additive.  A higher verbosity\n// level means a log message is less important.  Negative V-levels are treated\n// as 0.\nfunc (l Logger) V(level int) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tif level < 0 {\n\t\tlevel = 0\n\t}\n\tl.level += level\n\treturn l\n}\n\n// WithValues returns a new Logger instance with additional key/value pairs.\n// See Info for documentation on how key/value pairs work.\nfunc (l Logger) WithValues(keysAndValues ...interface{}) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tl.setSink(l.sink.WithValues(keysAndValues...))\n\treturn l\n}\n\n// WithName returns a new Logger instance with the specified name element added\n// to the Logger's name.  Successive calls with WithName append additional\n// suffixes to the Logger's name.  It's strongly recommended that name segments\n// contain only letters, digits, and hyphens (see the package documentation for\n// more information).\nfunc (l Logger) WithName(name string) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tl.setSink(l.sink.WithName(name))\n\treturn l\n}\n\n// WithCallDepth returns a Logger instance that offsets the call stack by the\n// specified number of frames when logging call site information, if possible.\n// This is useful for users who have helper functions between the \"real\" call\n// site and the actual calls to Logger methods.  If depth is 0 the attribution\n// should be to the direct caller of this function.  If depth is 1 the\n// attribution should skip 1 call frame, and so on.  Successive calls to this\n// are additive.\n//\n// If the underlying log implementation supports a WithCallDepth(int) method,\n// it will be called and the result returned.  If the implementation does not\n// support CallDepthLogSink, the original Logger will be returned.\n//\n// To skip one level, WithCallStackHelper() should be used instead of\n// WithCallDepth(1) because it works with implementions that support the\n// CallDepthLogSink and/or CallStackHelperLogSink interfaces.\nfunc (l Logger) WithCallDepth(depth int) Logger {\n\tif l.sink == nil {\n\t\treturn l\n\t}\n\tif withCallDepth, ok := l.sink.(CallDepthLogSink); ok {\n\t\tl.setSink(withCallDepth.WithCallDepth(depth))\n\t}\n\treturn l\n}\n\n// WithCallStackHelper returns a new Logger instance that skips the direct\n// caller when logging call site information, if possible.  This is useful for\n// users who have helper functions between the \"real\" call site and the actual\n// calls to Logger methods and want to support loggers which depend on marking\n// each individual helper function, like loggers based on testing.T.\n//\n// In addition to using that new logger instance, callers also must call the\n// returned function.\n//\n// If the underlying log implementation supports a WithCallDepth(int) method,\n// WithCallDepth(1) will be called to produce a new logger. If it supports a\n// WithCallStackHelper() method, that will be also called. If the\n// implementation does not support either of these, the original Logger will be\n// returned.\nfunc (l Logger) WithCallStackHelper() (func(), Logger) {\n\tif l.sink == nil {\n\t\treturn func() {}, l\n\t}\n\tvar helper func()\n\tif withCallDepth, ok := l.sink.(CallDepthLogSink); ok {\n\t\tl.setSink(withCallDepth.WithCallDepth(1))\n\t}\n\tif withHelper, ok := l.sink.(CallStackHelperLogSink); ok {\n\t\thelper = withHelper.GetCallStackHelper()\n\t} else {\n\t\thelper = func() {}\n\t}\n\treturn helper, l\n}\n\n// IsZero returns true if this logger is an uninitialized zero value\nfunc (l Logger) IsZero() bool {\n\treturn l.sink == nil\n}\n\n// contextKey is how we find Loggers in a context.Context.\ntype contextKey struct{}\n\n// FromContext returns a Logger from ctx or an error if no Logger is found.\nfunc FromContext(ctx context.Context) (Logger, error) {\n\tif v, ok := ctx.Value(contextKey{}).(Logger); ok {\n\t\treturn v, nil\n\t}\n\n\treturn Logger{}, notFoundError{}\n}\n\n// notFoundError exists to carry an IsNotFound method.\ntype notFoundError struct{}\n\nfunc (notFoundError) Error() string {\n\treturn \"no logr.Logger was present\"\n}\n\nfunc (notFoundError) IsNotFound() bool {\n\treturn true\n}\n\n// FromContextOrDiscard returns a Logger from ctx.  If no Logger is found, this\n// returns a Logger that discards all log messages.\nfunc FromContextOrDiscard(ctx context.Context) Logger {\n\tif v, ok := ctx.Value(contextKey{}).(Logger); ok {\n\t\treturn v\n\t}\n\n\treturn Discard()\n}\n\n// NewContext returns a new Context, derived from ctx, which carries the\n// provided Logger.\nfunc NewContext(ctx context.Context, logger Logger) context.Context {\n\treturn context.WithValue(ctx, contextKey{}, logger)\n}\n\n// RuntimeInfo holds information that the logr \"core\" library knows which\n// LogSinks might want to know.\ntype RuntimeInfo struct {\n\t// CallDepth is the number of call frames the logr library adds between the\n\t// end-user and the LogSink.  LogSink implementations which choose to print\n\t// the original logging site (e.g. file & line) should climb this many\n\t// additional frames to find it.\n\tCallDepth int\n}\n\n// runtimeInfo is a static global.  It must not be changed at run time.\nvar runtimeInfo = RuntimeInfo{\n\tCallDepth: 1,\n}\n\n// LogSink represents a logging implementation.  End-users will generally not\n// interact with this type.\ntype LogSink interface {\n\t// Init receives optional information about the logr library for LogSink\n\t// implementations that need it.\n\tInit(info RuntimeInfo)\n\n\t// Enabled tests whether this LogSink is enabled at the specified V-level.\n\t// For example, commandline flags might be used to set the logging\n\t// verbosity and disable some info logs.\n\tEnabled(level int) bool\n\n\t// Info logs a non-error message with the given key/value pairs as context.\n\t// The level argument is provided for optional logging.  This method will\n\t// only be called when Enabled(level) is true. See Logger.Info for more\n\t// details.\n\tInfo(level int, msg string, keysAndValues ...interface{})\n\n\t// Error logs an error, with the given message and key/value pairs as\n\t// context.  See Logger.Error for more details.\n\tError(err error, msg string, keysAndValues ...interface{})\n\n\t// WithValues returns a new LogSink with additional key/value pairs.  See\n\t// Logger.WithValues for more details.\n\tWithValues(keysAndValues ...interface{}) LogSink\n\n\t// WithName returns a new LogSink with the specified name appended.  See\n\t// Logger.WithName for more details.\n\tWithName(name string) LogSink\n}\n\n// CallDepthLogSink represents a LogSink that knows how to climb the call stack\n// to identify the original call site and can offset the depth by a specified\n// number of frames.  This is useful for users who have helper functions\n// between the \"real\" call site and the actual calls to Logger methods.\n// Implementations that log information about the call site (such as file,\n// function, or line) would otherwise log information about the intermediate\n// helper functions.\n//\n// This is an optional interface and implementations are not required to\n// support it.\ntype CallDepthLogSink interface {\n\t// WithCallDepth returns a LogSink that will offset the call\n\t// stack by the specified number of frames when logging call\n\t// site information.\n\t//\n\t// If depth is 0, the LogSink should skip exactly the number\n\t// of call frames defined in RuntimeInfo.CallDepth when Info\n\t// or Error are called, i.e. the attribution should be to the\n\t// direct caller of Logger.Info or Logger.Error.\n\t//\n\t// If depth is 1 the attribution should skip 1 call frame, and so on.\n\t// Successive calls to this are additive.\n\tWithCallDepth(depth int) LogSink\n}\n\n// CallStackHelperLogSink represents a LogSink that knows how to climb\n// the call stack to identify the original call site and can skip\n// intermediate helper functions if they mark themselves as\n// helper. Go's testing package uses that approach.\n//\n// This is useful for users who have helper functions between the\n// \"real\" call site and the actual calls to Logger methods.\n// Implementations that log information about the call site (such as\n// file, function, or line) would otherwise log information about the\n// intermediate helper functions.\n//\n// This is an optional interface and implementations are not required\n// to support it. Implementations that choose to support this must not\n// simply implement it as WithCallDepth(1), because\n// Logger.WithCallStackHelper will call both methods if they are\n// present. This should only be implemented for LogSinks that actually\n// need it, as with testing.T.\ntype CallStackHelperLogSink interface {\n\t// GetCallStackHelper returns a function that must be called\n\t// to mark the direct caller as helper function when logging\n\t// call site information.\n\tGetCallStackHelper() func()\n}\n\n// Marshaler is an optional interface that logged values may choose to\n// implement. Loggers with structured output, such as JSON, should\n// log the object return by the MarshalLog method instead of the\n// original value.\ntype Marshaler interface {\n\t// MarshalLog can be used to:\n\t//   - ensure that structs are not logged as strings when the original\n\t//     value has a String method: return a different type without a\n\t//     String method\n\t//   - select which fields of a complex type should get logged:\n\t//     return a simpler struct with fewer fields\n\t//   - log unexported fields: return a different struct\n\t//     with exported fields\n\t//\n\t// It may return any value of any type.\n\tMarshalLog() interface{}\n}\n"
  },
  {
    "path": "vendor/github.com/go-logr/stdr/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/go-logr/stdr/README.md",
    "content": "# Minimal Go logging using logr and Go's standard library\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/stdr.svg)](https://pkg.go.dev/github.com/go-logr/stdr)\n\nThis package implements the [logr interface](https://github.com/go-logr/logr)\nin terms of Go's standard log package(https://pkg.go.dev/log).\n"
  },
  {
    "path": "vendor/github.com/go-logr/stdr/stdr.go",
    "content": "/*\nCopyright 2019 The logr Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package stdr implements github.com/go-logr/logr.Logger in terms of\n// Go's standard log package.\npackage stdr\n\nimport (\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/go-logr/logr/funcr\"\n)\n\n// The global verbosity level.  See SetVerbosity().\nvar globalVerbosity int\n\n// SetVerbosity sets the global level against which all info logs will be\n// compared.  If this is greater than or equal to the \"V\" of the logger, the\n// message will be logged.  A higher value here means more logs will be written.\n// The previous verbosity value is returned.  This is not concurrent-safe -\n// callers must be sure to call it from only one goroutine.\nfunc SetVerbosity(v int) int {\n\told := globalVerbosity\n\tglobalVerbosity = v\n\treturn old\n}\n\n// New returns a logr.Logger which is implemented by Go's standard log package,\n// or something like it.  If std is nil, this will use a default logger\n// instead.\n//\n// Example: stdr.New(log.New(os.Stderr, \"\", log.LstdFlags|log.Lshortfile)))\nfunc New(std StdLogger) logr.Logger {\n\treturn NewWithOptions(std, Options{})\n}\n\n// NewWithOptions returns a logr.Logger which is implemented by Go's standard\n// log package, or something like it.  See New for details.\nfunc NewWithOptions(std StdLogger, opts Options) logr.Logger {\n\tif std == nil {\n\t\t// Go's log.Default() is only available in 1.16 and higher.\n\t\tstd = log.New(os.Stderr, \"\", log.LstdFlags)\n\t}\n\n\tif opts.Depth < 0 {\n\t\topts.Depth = 0\n\t}\n\n\tfopts := funcr.Options{\n\t\tLogCaller: funcr.MessageClass(opts.LogCaller),\n\t}\n\n\tsl := &logger{\n\t\tFormatter: funcr.NewFormatter(fopts),\n\t\tstd:       std,\n\t}\n\n\t// For skipping our own logger.Info/Error.\n\tsl.Formatter.AddCallDepth(1 + opts.Depth)\n\n\treturn logr.New(sl)\n}\n\n// Options carries parameters which influence the way logs are generated.\ntype Options struct {\n\t// Depth biases the assumed number of call frames to the \"true\" caller.\n\t// This is useful when the calling code calls a function which then calls\n\t// stdr (e.g. a logging shim to another API).  Values less than zero will\n\t// be treated as zero.\n\tDepth int\n\n\t// LogCaller tells stdr to add a \"caller\" key to some or all log lines.\n\t// Go's log package has options to log this natively, too.\n\tLogCaller MessageClass\n\n\t// TODO: add an option to log the date/time\n}\n\n// MessageClass indicates which category or categories of messages to consider.\ntype MessageClass int\n\nconst (\n\t// None ignores all message classes.\n\tNone MessageClass = iota\n\t// All considers all message classes.\n\tAll\n\t// Info only considers info messages.\n\tInfo\n\t// Error only considers error messages.\n\tError\n)\n\n// StdLogger is the subset of the Go stdlib log.Logger API that is needed for\n// this adapter.\ntype StdLogger interface {\n\t// Output is the same as log.Output and log.Logger.Output.\n\tOutput(calldepth int, logline string) error\n}\n\ntype logger struct {\n\tfuncr.Formatter\n\tstd StdLogger\n}\n\nvar _ logr.LogSink = &logger{}\nvar _ logr.CallDepthLogSink = &logger{}\n\nfunc (l logger) Enabled(level int) bool {\n\treturn globalVerbosity >= level\n}\n\nfunc (l logger) Info(level int, msg string, kvList ...interface{}) {\n\tprefix, args := l.FormatInfo(level, msg, kvList)\n\tif prefix != \"\" {\n\t\targs = prefix + \": \" + args\n\t}\n\t_ = l.std.Output(l.Formatter.GetDepth()+1, args)\n}\n\nfunc (l logger) Error(err error, msg string, kvList ...interface{}) {\n\tprefix, args := l.FormatError(err, msg, kvList)\n\tif prefix != \"\" {\n\t\targs = prefix + \": \" + args\n\t}\n\t_ = l.std.Output(l.Formatter.GetDepth()+1, args)\n}\n\nfunc (l logger) WithName(name string) logr.LogSink {\n\tl.Formatter.AddName(name)\n\treturn &l\n}\n\nfunc (l logger) WithValues(kvList ...interface{}) logr.LogSink {\n\tl.Formatter.AddValues(kvList)\n\treturn &l\n}\n\nfunc (l logger) WithCallDepth(depth int) logr.LogSink {\n\tl.Formatter.AddCallDepth(depth)\n\treturn &l\n}\n\n// Underlier exposes access to the underlying logging implementation.  Since\n// callers only have a logr.Logger, they have to know which implementation is\n// in use, so this interface is less of an abstraction and more of way to test\n// type conversion.\ntype Underlier interface {\n\tGetUnderlying() StdLogger\n}\n\n// GetUnderlying returns the StdLogger underneath this logger.  Since StdLogger\n// is itself an interface, the result may or may not be a Go log.Logger.\nfunc (l logger) GetUnderlying() StdLogger {\n\treturn l.std\n}\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonpointer/.editorconfig",
    "content": "# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*]\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\ntrim_trailing_whitespace = true\n\n# Set default charset\n[*.{js,py,go,scala,rb,java,html,css,less,sass,md}]\ncharset = utf-8\n\n# Tab indentation (no size specified)\n[*.go]\nindent_style = tab\n\n[*.md]\ntrim_trailing_whitespace = false\n\n# Matches the exact files either package.json or .travis.yml\n[{package.json,.travis.yml}]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonpointer/.gitignore",
    "content": "secrets.yml\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonpointer/.golangci.yml",
    "content": "linters-settings:\n  govet:\n    check-shadowing: true\n  golint:\n    min-confidence: 0\n  gocyclo:\n    min-complexity: 45\n  maligned:\n    suggest-new: true\n  dupl:\n    threshold: 200\n  goconst:\n    min-len: 2\n    min-occurrences: 3\n\nlinters:\n  enable-all: true\n  disable:\n    - maligned\n    - unparam\n    - lll\n    - gochecknoinits\n    - gochecknoglobals\n    - funlen\n    - godox\n    - gocognit\n    - whitespace\n    - wsl\n    - wrapcheck\n    - testpackage\n    - nlreturn\n    - gomnd\n    - exhaustivestruct\n    - goerr113\n    - errorlint\n    - nestif\n    - godot\n    - gofumpt\n    - paralleltest\n    - tparallel\n    - thelper\n    - ifshort\n    - exhaustruct\n    - varnamelen\n    - gci\n    - depguard\n    - errchkjson\n    - inamedparam\n    - nonamedreturns\n    - musttag\n    - ireturn\n    - forcetypeassert\n    - cyclop\n    # deprecated linters\n    - deadcode\n    - interfacer\n    - scopelint\n    - varcheck\n    - structcheck\n    - golint\n    - nosnakecase\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonpointer/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at ivan+abuse@flanders.co.nz. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonpointer/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/go-openapi/jsonpointer/README.md",
    "content": "# gojsonpointer [![Build Status](https://github.com/go-openapi/jsonpointer/actions/workflows/go-test.yml/badge.svg)](https://github.com/go-openapi/jsonpointer/actions?query=workflow%3A\"go+test\") [![codecov](https://codecov.io/gh/go-openapi/jsonpointer/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonpointer)\n\n[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)\n[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonpointer/master/LICENSE)\n[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/jsonpointer.svg)](https://pkg.go.dev/github.com/go-openapi/jsonpointer)\n[![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/jsonpointer)](https://goreportcard.com/report/github.com/go-openapi/jsonpointer)\n\nAn implementation of JSON Pointer - Go language\n\n## Status\nCompleted YES\n\nTested YES\n\n## References\nhttp://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07\n\n### Note\nThe 4.Evaluation part of the previous reference, starting with 'If the currently referenced value is a JSON array, the reference token MUST contain either...' is not implemented.\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonpointer/pointer.go",
    "content": "// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )\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//   http://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\n// author       sigu-399\n// author-github  https://github.com/sigu-399\n// author-mail    sigu.399@gmail.com\n//\n// repository-name  jsonpointer\n// repository-desc  An implementation of JSON Pointer - Go language\n//\n// description    Main and unique file.\n//\n// created        25-02-2013\n\npackage jsonpointer\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/go-openapi/swag\"\n)\n\nconst (\n\temptyPointer     = ``\n\tpointerSeparator = `/`\n\n\tinvalidStart = `JSON pointer must be empty or start with a \"` + pointerSeparator\n\tnotFound     = `Can't find the pointer in the document`\n)\n\nvar jsonPointableType = reflect.TypeOf(new(JSONPointable)).Elem()\nvar jsonSetableType = reflect.TypeOf(new(JSONSetable)).Elem()\n\n// JSONPointable is an interface for structs to implement when they need to customize the\n// json pointer process\ntype JSONPointable interface {\n\tJSONLookup(string) (any, error)\n}\n\n// JSONSetable is an interface for structs to implement when they need to customize the\n// json pointer process\ntype JSONSetable interface {\n\tJSONSet(string, any) error\n}\n\n// New creates a new json pointer for the given string\nfunc New(jsonPointerString string) (Pointer, error) {\n\n\tvar p Pointer\n\terr := p.parse(jsonPointerString)\n\treturn p, err\n\n}\n\n// Pointer the json pointer reprsentation\ntype Pointer struct {\n\treferenceTokens []string\n}\n\n// \"Constructor\", parses the given string JSON pointer\nfunc (p *Pointer) parse(jsonPointerString string) error {\n\n\tvar err error\n\n\tif jsonPointerString != emptyPointer {\n\t\tif !strings.HasPrefix(jsonPointerString, pointerSeparator) {\n\t\t\terr = errors.New(invalidStart)\n\t\t} else {\n\t\t\treferenceTokens := strings.Split(jsonPointerString, pointerSeparator)\n\t\t\tp.referenceTokens = append(p.referenceTokens, referenceTokens[1:]...)\n\t\t}\n\t}\n\n\treturn err\n}\n\n// Get uses the pointer to retrieve a value from a JSON document\nfunc (p *Pointer) Get(document any) (any, reflect.Kind, error) {\n\treturn p.get(document, swag.DefaultJSONNameProvider)\n}\n\n// Set uses the pointer to set a value from a JSON document\nfunc (p *Pointer) Set(document any, value any) (any, error) {\n\treturn document, p.set(document, value, swag.DefaultJSONNameProvider)\n}\n\n// GetForToken gets a value for a json pointer token 1 level deep\nfunc GetForToken(document any, decodedToken string) (any, reflect.Kind, error) {\n\treturn getSingleImpl(document, decodedToken, swag.DefaultJSONNameProvider)\n}\n\n// SetForToken gets a value for a json pointer token 1 level deep\nfunc SetForToken(document any, decodedToken string, value any) (any, error) {\n\treturn document, setSingleImpl(document, value, decodedToken, swag.DefaultJSONNameProvider)\n}\n\nfunc isNil(input any) bool {\n\tif input == nil {\n\t\treturn true\n\t}\n\n\tkind := reflect.TypeOf(input).Kind()\n\tswitch kind { //nolint:exhaustive\n\tcase reflect.Ptr, reflect.Map, reflect.Slice, reflect.Chan:\n\t\treturn reflect.ValueOf(input).IsNil()\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc getSingleImpl(node any, decodedToken string, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {\n\trValue := reflect.Indirect(reflect.ValueOf(node))\n\tkind := rValue.Kind()\n\tif isNil(node) {\n\t\treturn nil, kind, fmt.Errorf(\"nil value has not field %q\", decodedToken)\n\t}\n\n\tswitch typed := node.(type) {\n\tcase JSONPointable:\n\t\tr, err := typed.JSONLookup(decodedToken)\n\t\tif err != nil {\n\t\t\treturn nil, kind, err\n\t\t}\n\t\treturn r, kind, nil\n\tcase *any: // case of a pointer to interface, that is not resolved by reflect.Indirect\n\t\treturn getSingleImpl(*typed, decodedToken, nameProvider)\n\t}\n\n\tswitch kind { //nolint:exhaustive\n\tcase reflect.Struct:\n\t\tnm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)\n\t\tif !ok {\n\t\t\treturn nil, kind, fmt.Errorf(\"object has no field %q\", decodedToken)\n\t\t}\n\t\tfld := rValue.FieldByName(nm)\n\t\treturn fld.Interface(), kind, nil\n\n\tcase reflect.Map:\n\t\tkv := reflect.ValueOf(decodedToken)\n\t\tmv := rValue.MapIndex(kv)\n\n\t\tif mv.IsValid() {\n\t\t\treturn mv.Interface(), kind, nil\n\t\t}\n\t\treturn nil, kind, fmt.Errorf(\"object has no key %q\", decodedToken)\n\n\tcase reflect.Slice:\n\t\ttokenIndex, err := strconv.Atoi(decodedToken)\n\t\tif err != nil {\n\t\t\treturn nil, kind, err\n\t\t}\n\t\tsLength := rValue.Len()\n\t\tif tokenIndex < 0 || tokenIndex >= sLength {\n\t\t\treturn nil, kind, fmt.Errorf(\"index out of bounds array[0,%d] index '%d'\", sLength-1, tokenIndex)\n\t\t}\n\n\t\telem := rValue.Index(tokenIndex)\n\t\treturn elem.Interface(), kind, nil\n\n\tdefault:\n\t\treturn nil, kind, fmt.Errorf(\"invalid token reference %q\", decodedToken)\n\t}\n\n}\n\nfunc setSingleImpl(node, data any, decodedToken string, nameProvider *swag.NameProvider) error {\n\trValue := reflect.Indirect(reflect.ValueOf(node))\n\n\tif ns, ok := node.(JSONSetable); ok { // pointer impl\n\t\treturn ns.JSONSet(decodedToken, data)\n\t}\n\n\tif rValue.Type().Implements(jsonSetableType) {\n\t\treturn node.(JSONSetable).JSONSet(decodedToken, data)\n\t}\n\n\tswitch rValue.Kind() { //nolint:exhaustive\n\tcase reflect.Struct:\n\t\tnm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"object has no field %q\", decodedToken)\n\t\t}\n\t\tfld := rValue.FieldByName(nm)\n\t\tif fld.IsValid() {\n\t\t\tfld.Set(reflect.ValueOf(data))\n\t\t}\n\t\treturn nil\n\n\tcase reflect.Map:\n\t\tkv := reflect.ValueOf(decodedToken)\n\t\trValue.SetMapIndex(kv, reflect.ValueOf(data))\n\t\treturn nil\n\n\tcase reflect.Slice:\n\t\ttokenIndex, err := strconv.Atoi(decodedToken)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsLength := rValue.Len()\n\t\tif tokenIndex < 0 || tokenIndex >= sLength {\n\t\t\treturn fmt.Errorf(\"index out of bounds array[0,%d] index '%d'\", sLength, tokenIndex)\n\t\t}\n\n\t\telem := rValue.Index(tokenIndex)\n\t\tif !elem.CanSet() {\n\t\t\treturn fmt.Errorf(\"can't set slice index %s to %v\", decodedToken, data)\n\t\t}\n\t\telem.Set(reflect.ValueOf(data))\n\t\treturn nil\n\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid token reference %q\", decodedToken)\n\t}\n\n}\n\nfunc (p *Pointer) get(node any, nameProvider *swag.NameProvider) (any, reflect.Kind, error) {\n\n\tif nameProvider == nil {\n\t\tnameProvider = swag.DefaultJSONNameProvider\n\t}\n\n\tkind := reflect.Invalid\n\n\t// Full document when empty\n\tif len(p.referenceTokens) == 0 {\n\t\treturn node, kind, nil\n\t}\n\n\tfor _, token := range p.referenceTokens {\n\n\t\tdecodedToken := Unescape(token)\n\n\t\tr, knd, err := getSingleImpl(node, decodedToken, nameProvider)\n\t\tif err != nil {\n\t\t\treturn nil, knd, err\n\t\t}\n\t\tnode = r\n\t}\n\n\trValue := reflect.ValueOf(node)\n\tkind = rValue.Kind()\n\n\treturn node, kind, nil\n}\n\nfunc (p *Pointer) set(node, data any, nameProvider *swag.NameProvider) error {\n\tknd := reflect.ValueOf(node).Kind()\n\n\tif knd != reflect.Ptr && knd != reflect.Struct && knd != reflect.Map && knd != reflect.Slice && knd != reflect.Array {\n\t\treturn errors.New(\"only structs, pointers, maps and slices are supported for setting values\")\n\t}\n\n\tif nameProvider == nil {\n\t\tnameProvider = swag.DefaultJSONNameProvider\n\t}\n\n\t// Full document when empty\n\tif len(p.referenceTokens) == 0 {\n\t\treturn nil\n\t}\n\n\tlastI := len(p.referenceTokens) - 1\n\tfor i, token := range p.referenceTokens {\n\t\tisLastToken := i == lastI\n\t\tdecodedToken := Unescape(token)\n\n\t\tif isLastToken {\n\n\t\t\treturn setSingleImpl(node, data, decodedToken, nameProvider)\n\t\t}\n\n\t\trValue := reflect.Indirect(reflect.ValueOf(node))\n\t\tkind := rValue.Kind()\n\n\t\tif rValue.Type().Implements(jsonPointableType) {\n\t\t\tr, err := node.(JSONPointable).JSONLookup(decodedToken)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfld := reflect.ValueOf(r)\n\t\t\tif fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {\n\t\t\t\tnode = fld.Addr().Interface()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tnode = r\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch kind { //nolint:exhaustive\n\t\tcase reflect.Struct:\n\t\t\tnm, ok := nameProvider.GetGoNameForType(rValue.Type(), decodedToken)\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"object has no field %q\", decodedToken)\n\t\t\t}\n\t\t\tfld := rValue.FieldByName(nm)\n\t\t\tif fld.CanAddr() && fld.Kind() != reflect.Interface && fld.Kind() != reflect.Map && fld.Kind() != reflect.Slice && fld.Kind() != reflect.Ptr {\n\t\t\t\tnode = fld.Addr().Interface()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tnode = fld.Interface()\n\n\t\tcase reflect.Map:\n\t\t\tkv := reflect.ValueOf(decodedToken)\n\t\t\tmv := rValue.MapIndex(kv)\n\n\t\t\tif !mv.IsValid() {\n\t\t\t\treturn fmt.Errorf(\"object has no key %q\", decodedToken)\n\t\t\t}\n\t\t\tif mv.CanAddr() && mv.Kind() != reflect.Interface && mv.Kind() != reflect.Map && mv.Kind() != reflect.Slice && mv.Kind() != reflect.Ptr {\n\t\t\t\tnode = mv.Addr().Interface()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tnode = mv.Interface()\n\n\t\tcase reflect.Slice:\n\t\t\ttokenIndex, err := strconv.Atoi(decodedToken)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tsLength := rValue.Len()\n\t\t\tif tokenIndex < 0 || tokenIndex >= sLength {\n\t\t\t\treturn fmt.Errorf(\"index out of bounds array[0,%d] index '%d'\", sLength, tokenIndex)\n\t\t\t}\n\n\t\t\telem := rValue.Index(tokenIndex)\n\t\t\tif elem.CanAddr() && elem.Kind() != reflect.Interface && elem.Kind() != reflect.Map && elem.Kind() != reflect.Slice && elem.Kind() != reflect.Ptr {\n\t\t\t\tnode = elem.Addr().Interface()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tnode = elem.Interface()\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"invalid token reference %q\", decodedToken)\n\t\t}\n\n\t}\n\n\treturn nil\n}\n\n// DecodedTokens returns the decoded tokens\nfunc (p *Pointer) DecodedTokens() []string {\n\tresult := make([]string, 0, len(p.referenceTokens))\n\tfor _, t := range p.referenceTokens {\n\t\tresult = append(result, Unescape(t))\n\t}\n\treturn result\n}\n\n// IsEmpty returns true if this is an empty json pointer\n// this indicates that it points to the root document\nfunc (p *Pointer) IsEmpty() bool {\n\treturn len(p.referenceTokens) == 0\n}\n\n// Pointer to string representation function\nfunc (p *Pointer) String() string {\n\n\tif len(p.referenceTokens) == 0 {\n\t\treturn emptyPointer\n\t}\n\n\tpointerString := pointerSeparator + strings.Join(p.referenceTokens, pointerSeparator)\n\n\treturn pointerString\n}\n\nfunc (p *Pointer) Offset(document string) (int64, error) {\n\tdec := json.NewDecoder(strings.NewReader(document))\n\tvar offset int64\n\tfor _, ttk := range p.DecodedTokens() {\n\t\ttk, err := dec.Token()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tswitch tk := tk.(type) {\n\t\tcase json.Delim:\n\t\t\tswitch tk {\n\t\t\tcase '{':\n\t\t\t\toffset, err = offsetSingleObject(dec, ttk)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\tcase '[':\n\t\t\t\toffset, err = offsetSingleArray(dec, ttk)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn 0, fmt.Errorf(\"invalid token %#v\", tk)\n\t\t\t}\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"invalid token %#v\", tk)\n\t\t}\n\t}\n\treturn offset, nil\n}\n\nfunc offsetSingleObject(dec *json.Decoder, decodedToken string) (int64, error) {\n\tfor dec.More() {\n\t\toffset := dec.InputOffset()\n\t\ttk, err := dec.Token()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tswitch tk := tk.(type) {\n\t\tcase json.Delim:\n\t\t\tswitch tk {\n\t\t\tcase '{':\n\t\t\t\tif err = drainSingle(dec); err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\tcase '[':\n\t\t\t\tif err = drainSingle(dec); err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\t\tcase string:\n\t\t\tif tk == decodedToken {\n\t\t\t\treturn offset, nil\n\t\t\t}\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"invalid token %#v\", tk)\n\t\t}\n\t}\n\treturn 0, fmt.Errorf(\"token reference %q not found\", decodedToken)\n}\n\nfunc offsetSingleArray(dec *json.Decoder, decodedToken string) (int64, error) {\n\tidx, err := strconv.Atoi(decodedToken)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"token reference %q is not a number: %v\", decodedToken, err)\n\t}\n\tvar i int\n\tfor i = 0; i < idx && dec.More(); i++ {\n\t\ttk, err := dec.Token()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\tif delim, isDelim := tk.(json.Delim); isDelim {\n\t\t\tswitch delim {\n\t\t\tcase '{':\n\t\t\t\tif err = drainSingle(dec); err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\tcase '[':\n\t\t\t\tif err = drainSingle(dec); err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif !dec.More() {\n\t\treturn 0, fmt.Errorf(\"token reference %q not found\", decodedToken)\n\t}\n\treturn dec.InputOffset(), nil\n}\n\n// drainSingle drains a single level of object or array.\n// The decoder has to guarantee the beginning delim (i.e. '{' or '[') has been consumed.\nfunc drainSingle(dec *json.Decoder) error {\n\tfor dec.More() {\n\t\ttk, err := dec.Token()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif delim, isDelim := tk.(json.Delim); isDelim {\n\t\t\tswitch delim {\n\t\t\tcase '{':\n\t\t\t\tif err = drainSingle(dec); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\tcase '[':\n\t\t\t\tif err = drainSingle(dec); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Consumes the ending delim\n\tif _, err := dec.Token(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Specific JSON pointer encoding here\n// ~0 => ~\n// ~1 => /\n// ... and vice versa\n\nconst (\n\tencRefTok0 = `~0`\n\tencRefTok1 = `~1`\n\tdecRefTok0 = `~`\n\tdecRefTok1 = `/`\n)\n\n// Unescape unescapes a json pointer reference token string to the original representation\nfunc Unescape(token string) string {\n\tstep1 := strings.ReplaceAll(token, encRefTok1, decRefTok1)\n\tstep2 := strings.ReplaceAll(step1, encRefTok0, decRefTok0)\n\treturn step2\n}\n\n// Escape escapes a pointer reference token string\nfunc Escape(token string) string {\n\tstep1 := strings.ReplaceAll(token, decRefTok0, encRefTok0)\n\tstep2 := strings.ReplaceAll(step1, decRefTok1, encRefTok1)\n\treturn step2\n}\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonreference/.gitignore",
    "content": "secrets.yml\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonreference/.golangci.yml",
    "content": "linters-settings:\n  govet:\n    check-shadowing: true\n  gocyclo:\n    min-complexity: 30\n  maligned:\n    suggest-new: true\n  dupl:\n    threshold: 100\n  goconst:\n    min-len: 2\n    min-occurrences: 4\n  paralleltest:\n    ignore-missing: true\nlinters:\n  enable-all: true\n  disable:\n    - maligned\n    - lll\n    - gochecknoglobals\n    - godox\n    - gocognit\n    - whitespace\n    - wsl\n    - funlen\n    - gochecknoglobals\n    - gochecknoinits\n    - scopelint\n    - wrapcheck\n    - exhaustivestruct\n    - exhaustive\n    - nlreturn\n    - testpackage\n    - gci\n    - gofumpt\n    - goerr113\n    - gomnd\n    - tparallel\n    - nestif\n    - godot\n    - errorlint\n    - varcheck\n    - interfacer\n    - deadcode\n    - golint\n    - ifshort\n    - structcheck\n    - nosnakecase\n    - varnamelen\n    - exhaustruct\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonreference/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of experience,\nnationality, personal appearance, race, religion, or sexual identity and\norientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\nadvances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at ivan+abuse@flanders.co.nz. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonreference/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/go-openapi/jsonreference/README.md",
    "content": "# gojsonreference [![Build Status](https://travis-ci.org/go-openapi/jsonreference.svg?branch=master)](https://travis-ci.org/go-openapi/jsonreference) [![codecov](https://codecov.io/gh/go-openapi/jsonreference/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/jsonreference) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io)\n\n[![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/jsonreference/master/LICENSE) [![GoDoc](https://godoc.org/github.com/go-openapi/jsonreference?status.svg)](http://godoc.org/github.com/go-openapi/jsonreference)\nAn implementation of JSON Reference - Go language\n\n## Status\nFeature complete. Stable API\n\n## Dependencies\nhttps://github.com/go-openapi/jsonpointer\n\n## References\nhttp://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-07\n\nhttp://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonreference/internal/normalize_url.go",
    "content": "package internal\n\nimport (\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nconst (\n\tdefaultHTTPPort  = \":80\"\n\tdefaultHTTPSPort = \":443\"\n)\n\n// Regular expressions used by the normalizations\nvar rxPort = regexp.MustCompile(`(:\\d+)/?$`)\nvar rxDupSlashes = regexp.MustCompile(`/{2,}`)\n\n// NormalizeURL will normalize the specified URL\n// This was added to replace a previous call to the no longer maintained purell library:\n// The call that was used looked like the following:\n//\n//\turl.Parse(purell.NormalizeURL(parsed, purell.FlagsSafe|purell.FlagRemoveDuplicateSlashes))\n//\n// To explain all that was included in the call above, purell.FlagsSafe was really just the following:\n//   - FlagLowercaseScheme\n//   - FlagLowercaseHost\n//   - FlagRemoveDefaultPort\n//   - FlagRemoveDuplicateSlashes (and this was mixed in with the |)\nfunc NormalizeURL(u *url.URL) {\n\tlowercaseScheme(u)\n\tlowercaseHost(u)\n\tremoveDefaultPort(u)\n\tremoveDuplicateSlashes(u)\n}\n\nfunc lowercaseScheme(u *url.URL) {\n\tif len(u.Scheme) > 0 {\n\t\tu.Scheme = strings.ToLower(u.Scheme)\n\t}\n}\n\nfunc lowercaseHost(u *url.URL) {\n\tif len(u.Host) > 0 {\n\t\tu.Host = strings.ToLower(u.Host)\n\t}\n}\n\nfunc removeDefaultPort(u *url.URL) {\n\tif len(u.Host) > 0 {\n\t\tscheme := strings.ToLower(u.Scheme)\n\t\tu.Host = rxPort.ReplaceAllStringFunc(u.Host, func(val string) string {\n\t\t\tif (scheme == \"http\" && val == defaultHTTPPort) || (scheme == \"https\" && val == defaultHTTPSPort) {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\treturn val\n\t\t})\n\t}\n}\n\nfunc removeDuplicateSlashes(u *url.URL) {\n\tif len(u.Path) > 0 {\n\t\tu.Path = rxDupSlashes.ReplaceAllString(u.Path, \"/\")\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/go-openapi/jsonreference/reference.go",
    "content": "// Copyright 2013 sigu-399 ( https://github.com/sigu-399 )\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//   http://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\n// author       sigu-399\n// author-github  https://github.com/sigu-399\n// author-mail    sigu.399@gmail.com\n//\n// repository-name  jsonreference\n// repository-desc  An implementation of JSON Reference - Go language\n//\n// description    Main and unique file.\n//\n// created        26-02-2013\n\npackage jsonreference\n\nimport (\n\t\"errors\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/go-openapi/jsonpointer\"\n\t\"github.com/go-openapi/jsonreference/internal\"\n)\n\nconst (\n\tfragmentRune = `#`\n)\n\n// New creates a new reference for the given string\nfunc New(jsonReferenceString string) (Ref, error) {\n\n\tvar r Ref\n\terr := r.parse(jsonReferenceString)\n\treturn r, err\n\n}\n\n// MustCreateRef parses the ref string and panics when it's invalid.\n// Use the New method for a version that returns an error\nfunc MustCreateRef(ref string) Ref {\n\tr, err := New(ref)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn r\n}\n\n// Ref represents a json reference object\ntype Ref struct {\n\treferenceURL     *url.URL\n\treferencePointer jsonpointer.Pointer\n\n\tHasFullURL      bool\n\tHasURLPathOnly  bool\n\tHasFragmentOnly bool\n\tHasFileScheme   bool\n\tHasFullFilePath bool\n}\n\n// GetURL gets the URL for this reference\nfunc (r *Ref) GetURL() *url.URL {\n\treturn r.referenceURL\n}\n\n// GetPointer gets the json pointer for this reference\nfunc (r *Ref) GetPointer() *jsonpointer.Pointer {\n\treturn &r.referencePointer\n}\n\n// String returns the best version of the url for this reference\nfunc (r *Ref) String() string {\n\n\tif r.referenceURL != nil {\n\t\treturn r.referenceURL.String()\n\t}\n\n\tif r.HasFragmentOnly {\n\t\treturn fragmentRune + r.referencePointer.String()\n\t}\n\n\treturn r.referencePointer.String()\n}\n\n// IsRoot returns true if this reference is a root document\nfunc (r *Ref) IsRoot() bool {\n\treturn r.referenceURL != nil &&\n\t\t!r.IsCanonical() &&\n\t\t!r.HasURLPathOnly &&\n\t\tr.referenceURL.Fragment == \"\"\n}\n\n// IsCanonical returns true when this pointer starts with http(s):// or file://\nfunc (r *Ref) IsCanonical() bool {\n\treturn (r.HasFileScheme && r.HasFullFilePath) || (!r.HasFileScheme && r.HasFullURL)\n}\n\n// \"Constructor\", parses the given string JSON reference\nfunc (r *Ref) parse(jsonReferenceString string) error {\n\n\tparsed, err := url.Parse(jsonReferenceString)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tinternal.NormalizeURL(parsed)\n\n\tr.referenceURL = parsed\n\trefURL := r.referenceURL\n\n\tif refURL.Scheme != \"\" && refURL.Host != \"\" {\n\t\tr.HasFullURL = true\n\t} else {\n\t\tif refURL.Path != \"\" {\n\t\t\tr.HasURLPathOnly = true\n\t\t} else if refURL.RawQuery == \"\" && refURL.Fragment != \"\" {\n\t\t\tr.HasFragmentOnly = true\n\t\t}\n\t}\n\n\tr.HasFileScheme = refURL.Scheme == \"file\"\n\tr.HasFullFilePath = strings.HasPrefix(refURL.Path, \"/\")\n\n\t// invalid json-pointer error means url has no json-pointer fragment. simply ignore error\n\tr.referencePointer, _ = jsonpointer.New(refURL.Fragment)\n\n\treturn nil\n}\n\n// Inherits creates a new reference from a parent and a child\n// If the child cannot inherit from the parent, an error is returned\nfunc (r *Ref) Inherits(child Ref) (*Ref, error) {\n\tchildURL := child.GetURL()\n\tparentURL := r.GetURL()\n\tif childURL == nil {\n\t\treturn nil, errors.New(\"child url is nil\")\n\t}\n\tif parentURL == nil {\n\t\treturn &child, nil\n\t}\n\n\tref, err := New(parentURL.ResolveReference(childURL).String())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &ref, nil\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/.gitignore",
    "content": "glob.iml\n.idea\n*.cpu\n*.mem\n*.test\n*.dot\n*.png\n*.svg\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/.travis.yml",
    "content": "sudo: false\n\nlanguage: go\n\ngo:\n  - 1.5.3\n\nscript:\n  - go test -v ./...\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Sergey Kamardin\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."
  },
  {
    "path": "vendor/github.com/gobwas/glob/bench.sh",
    "content": "#! /bin/bash\n\nbench() {\n    filename=\"/tmp/$1-$2.bench\"\n    if test -e \"${filename}\";\n    then\n        echo \"Already exists ${filename}\"\n    else\n        backup=`git rev-parse --abbrev-ref HEAD`\n        git checkout $1\n        echo -n \"Creating ${filename}... \"\n        go test ./... -run=NONE -bench=$2 > \"${filename}\" -benchmem\n        echo \"OK\"\n        git checkout ${backup}\n        sleep 5\n    fi\n}\n\n\nto=$1\ncurrent=`git rev-parse --abbrev-ref HEAD`\n\nbench ${to} $2\nbench ${current} $2\n\nbenchcmp $3 \"/tmp/${to}-$2.bench\" \"/tmp/${current}-$2.bench\"\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/compiler/compiler.go",
    "content": "package compiler\n\n// TODO use constructor with all matchers, and to their structs private\n// TODO glue multiple Text nodes (like after QuoteMeta)\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/gobwas/glob/match\"\n\t\"github.com/gobwas/glob/syntax/ast\"\n\t\"github.com/gobwas/glob/util/runes\"\n)\n\nfunc optimizeMatcher(matcher match.Matcher) match.Matcher {\n\tswitch m := matcher.(type) {\n\n\tcase match.Any:\n\t\tif len(m.Separators) == 0 {\n\t\t\treturn match.NewSuper()\n\t\t}\n\n\tcase match.AnyOf:\n\t\tif len(m.Matchers) == 1 {\n\t\t\treturn m.Matchers[0]\n\t\t}\n\n\t\treturn m\n\n\tcase match.List:\n\t\tif m.Not == false && len(m.List) == 1 {\n\t\t\treturn match.NewText(string(m.List))\n\t\t}\n\n\t\treturn m\n\n\tcase match.BTree:\n\t\tm.Left = optimizeMatcher(m.Left)\n\t\tm.Right = optimizeMatcher(m.Right)\n\n\t\tr, ok := m.Value.(match.Text)\n\t\tif !ok {\n\t\t\treturn m\n\t\t}\n\n\t\tvar (\n\t\t\tleftNil  = m.Left == nil\n\t\t\trightNil = m.Right == nil\n\t\t)\n\t\tif leftNil && rightNil {\n\t\t\treturn match.NewText(r.Str)\n\t\t}\n\n\t\t_, leftSuper := m.Left.(match.Super)\n\t\tlp, leftPrefix := m.Left.(match.Prefix)\n\t\tla, leftAny := m.Left.(match.Any)\n\n\t\t_, rightSuper := m.Right.(match.Super)\n\t\trs, rightSuffix := m.Right.(match.Suffix)\n\t\tra, rightAny := m.Right.(match.Any)\n\n\t\tswitch {\n\t\tcase leftSuper && rightSuper:\n\t\t\treturn match.NewContains(r.Str, false)\n\n\t\tcase leftSuper && rightNil:\n\t\t\treturn match.NewSuffix(r.Str)\n\n\t\tcase rightSuper && leftNil:\n\t\t\treturn match.NewPrefix(r.Str)\n\n\t\tcase leftNil && rightSuffix:\n\t\t\treturn match.NewPrefixSuffix(r.Str, rs.Suffix)\n\n\t\tcase rightNil && leftPrefix:\n\t\t\treturn match.NewPrefixSuffix(lp.Prefix, r.Str)\n\n\t\tcase rightNil && leftAny:\n\t\t\treturn match.NewSuffixAny(r.Str, la.Separators)\n\n\t\tcase leftNil && rightAny:\n\t\t\treturn match.NewPrefixAny(r.Str, ra.Separators)\n\t\t}\n\n\t\treturn m\n\t}\n\n\treturn matcher\n}\n\nfunc compileMatchers(matchers []match.Matcher) (match.Matcher, error) {\n\tif len(matchers) == 0 {\n\t\treturn nil, fmt.Errorf(\"compile error: need at least one matcher\")\n\t}\n\tif len(matchers) == 1 {\n\t\treturn matchers[0], nil\n\t}\n\tif m := glueMatchers(matchers); m != nil {\n\t\treturn m, nil\n\t}\n\n\tidx := -1\n\tmaxLen := -1\n\tvar val match.Matcher\n\tfor i, matcher := range matchers {\n\t\tif l := matcher.Len(); l != -1 && l >= maxLen {\n\t\t\tmaxLen = l\n\t\t\tidx = i\n\t\t\tval = matcher\n\t\t}\n\t}\n\n\tif val == nil { // not found matcher with static length\n\t\tr, err := compileMatchers(matchers[1:])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn match.NewBTree(matchers[0], nil, r), nil\n\t}\n\n\tleft := matchers[:idx]\n\tvar right []match.Matcher\n\tif len(matchers) > idx+1 {\n\t\tright = matchers[idx+1:]\n\t}\n\n\tvar l, r match.Matcher\n\tvar err error\n\tif len(left) > 0 {\n\t\tl, err = compileMatchers(left)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif len(right) > 0 {\n\t\tr, err = compileMatchers(right)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn match.NewBTree(val, l, r), nil\n}\n\nfunc glueMatchers(matchers []match.Matcher) match.Matcher {\n\tif m := glueMatchersAsEvery(matchers); m != nil {\n\t\treturn m\n\t}\n\tif m := glueMatchersAsRow(matchers); m != nil {\n\t\treturn m\n\t}\n\treturn nil\n}\n\nfunc glueMatchersAsRow(matchers []match.Matcher) match.Matcher {\n\tif len(matchers) <= 1 {\n\t\treturn nil\n\t}\n\n\tvar (\n\t\tc []match.Matcher\n\t\tl int\n\t)\n\tfor _, matcher := range matchers {\n\t\tif ml := matcher.Len(); ml == -1 {\n\t\t\treturn nil\n\t\t} else {\n\t\t\tc = append(c, matcher)\n\t\t\tl += ml\n\t\t}\n\t}\n\treturn match.NewRow(l, c...)\n}\n\nfunc glueMatchersAsEvery(matchers []match.Matcher) match.Matcher {\n\tif len(matchers) <= 1 {\n\t\treturn nil\n\t}\n\n\tvar (\n\t\thasAny    bool\n\t\thasSuper  bool\n\t\thasSingle bool\n\t\tmin       int\n\t\tseparator []rune\n\t)\n\n\tfor i, matcher := range matchers {\n\t\tvar sep []rune\n\n\t\tswitch m := matcher.(type) {\n\t\tcase match.Super:\n\t\t\tsep = []rune{}\n\t\t\thasSuper = true\n\n\t\tcase match.Any:\n\t\t\tsep = m.Separators\n\t\t\thasAny = true\n\n\t\tcase match.Single:\n\t\t\tsep = m.Separators\n\t\t\thasSingle = true\n\t\t\tmin++\n\n\t\tcase match.List:\n\t\t\tif !m.Not {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tsep = m.List\n\t\t\thasSingle = true\n\t\t\tmin++\n\n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\n\t\t// initialize\n\t\tif i == 0 {\n\t\t\tseparator = sep\n\t\t}\n\n\t\tif runes.Equal(sep, separator) {\n\t\t\tcontinue\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tif hasSuper && !hasAny && !hasSingle {\n\t\treturn match.NewSuper()\n\t}\n\n\tif hasAny && !hasSuper && !hasSingle {\n\t\treturn match.NewAny(separator)\n\t}\n\n\tif (hasAny || hasSuper) && min > 0 && len(separator) == 0 {\n\t\treturn match.NewMin(min)\n\t}\n\n\tevery := match.NewEveryOf()\n\n\tif min > 0 {\n\t\tevery.Add(match.NewMin(min))\n\n\t\tif !hasAny && !hasSuper {\n\t\t\tevery.Add(match.NewMax(min))\n\t\t}\n\t}\n\n\tif len(separator) > 0 {\n\t\tevery.Add(match.NewContains(string(separator), true))\n\t}\n\n\treturn every\n}\n\nfunc minimizeMatchers(matchers []match.Matcher) []match.Matcher {\n\tvar done match.Matcher\n\tvar left, right, count int\n\n\tfor l := 0; l < len(matchers); l++ {\n\t\tfor r := len(matchers); r > l; r-- {\n\t\t\tif glued := glueMatchers(matchers[l:r]); glued != nil {\n\t\t\t\tvar swap bool\n\n\t\t\t\tif done == nil {\n\t\t\t\t\tswap = true\n\t\t\t\t} else {\n\t\t\t\t\tcl, gl := done.Len(), glued.Len()\n\t\t\t\t\tswap = cl > -1 && gl > -1 && gl > cl\n\t\t\t\t\tswap = swap || count < r-l\n\t\t\t\t}\n\n\t\t\t\tif swap {\n\t\t\t\t\tdone = glued\n\t\t\t\t\tleft = l\n\t\t\t\t\tright = r\n\t\t\t\t\tcount = r - l\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif done == nil {\n\t\treturn matchers\n\t}\n\n\tnext := append(append([]match.Matcher{}, matchers[:left]...), done)\n\tif right < len(matchers) {\n\t\tnext = append(next, matchers[right:]...)\n\t}\n\n\tif len(next) == len(matchers) {\n\t\treturn next\n\t}\n\n\treturn minimizeMatchers(next)\n}\n\n// minimizeAnyOf tries to apply some heuristics to minimize number of nodes in given tree\nfunc minimizeTree(tree *ast.Node) *ast.Node {\n\tswitch tree.Kind {\n\tcase ast.KindAnyOf:\n\t\treturn minimizeTreeAnyOf(tree)\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// minimizeAnyOf tries to find common children of given node of AnyOf pattern\n// it searches for common children from left and from right\n// if any common children are found – then it returns new optimized ast tree\n// else it returns nil\nfunc minimizeTreeAnyOf(tree *ast.Node) *ast.Node {\n\tif !areOfSameKind(tree.Children, ast.KindPattern) {\n\t\treturn nil\n\t}\n\n\tcommonLeft, commonRight := commonChildren(tree.Children)\n\tcommonLeftCount, commonRightCount := len(commonLeft), len(commonRight)\n\tif commonLeftCount == 0 && commonRightCount == 0 { // there are no common parts\n\t\treturn nil\n\t}\n\n\tvar result []*ast.Node\n\tif commonLeftCount > 0 {\n\t\tresult = append(result, ast.NewNode(ast.KindPattern, nil, commonLeft...))\n\t}\n\n\tvar anyOf []*ast.Node\n\tfor _, child := range tree.Children {\n\t\treuse := child.Children[commonLeftCount : len(child.Children)-commonRightCount]\n\t\tvar node *ast.Node\n\t\tif len(reuse) == 0 {\n\t\t\t// this pattern is completely reduced by commonLeft and commonRight patterns\n\t\t\t// so it become nothing\n\t\t\tnode = ast.NewNode(ast.KindNothing, nil)\n\t\t} else {\n\t\t\tnode = ast.NewNode(ast.KindPattern, nil, reuse...)\n\t\t}\n\t\tanyOf = appendIfUnique(anyOf, node)\n\t}\n\tswitch {\n\tcase len(anyOf) == 1 && anyOf[0].Kind != ast.KindNothing:\n\t\tresult = append(result, anyOf[0])\n\tcase len(anyOf) > 1:\n\t\tresult = append(result, ast.NewNode(ast.KindAnyOf, nil, anyOf...))\n\t}\n\n\tif commonRightCount > 0 {\n\t\tresult = append(result, ast.NewNode(ast.KindPattern, nil, commonRight...))\n\t}\n\n\treturn ast.NewNode(ast.KindPattern, nil, result...)\n}\n\nfunc commonChildren(nodes []*ast.Node) (commonLeft, commonRight []*ast.Node) {\n\tif len(nodes) <= 1 {\n\t\treturn\n\t}\n\n\t// find node that has least number of children\n\tidx := leastChildren(nodes)\n\tif idx == -1 {\n\t\treturn\n\t}\n\ttree := nodes[idx]\n\ttreeLength := len(tree.Children)\n\n\t// allocate max able size for rightCommon slice\n\t// to get ability insert elements in reverse order (from end to start)\n\t// without sorting\n\tcommonRight = make([]*ast.Node, treeLength)\n\tlastRight := treeLength // will use this to get results as commonRight[lastRight:]\n\n\tvar (\n\t\tbreakLeft   bool\n\t\tbreakRight  bool\n\t\tcommonTotal int\n\t)\n\tfor i, j := 0, treeLength-1; commonTotal < treeLength && j >= 0 && !(breakLeft && breakRight); i, j = i+1, j-1 {\n\t\ttreeLeft := tree.Children[i]\n\t\ttreeRight := tree.Children[j]\n\n\t\tfor k := 0; k < len(nodes) && !(breakLeft && breakRight); k++ {\n\t\t\t// skip least children node\n\t\t\tif k == idx {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\trestLeft := nodes[k].Children[i]\n\t\t\trestRight := nodes[k].Children[j+len(nodes[k].Children)-treeLength]\n\n\t\t\tbreakLeft = breakLeft || !treeLeft.Equal(restLeft)\n\n\t\t\t// disable searching for right common parts, if left part is already overlapping\n\t\t\tbreakRight = breakRight || (!breakLeft && j <= i)\n\t\t\tbreakRight = breakRight || !treeRight.Equal(restRight)\n\t\t}\n\n\t\tif !breakLeft {\n\t\t\tcommonTotal++\n\t\t\tcommonLeft = append(commonLeft, treeLeft)\n\t\t}\n\t\tif !breakRight {\n\t\t\tcommonTotal++\n\t\t\tlastRight = j\n\t\t\tcommonRight[j] = treeRight\n\t\t}\n\t}\n\n\tcommonRight = commonRight[lastRight:]\n\n\treturn\n}\n\nfunc appendIfUnique(target []*ast.Node, val *ast.Node) []*ast.Node {\n\tfor _, n := range target {\n\t\tif reflect.DeepEqual(n, val) {\n\t\t\treturn target\n\t\t}\n\t}\n\treturn append(target, val)\n}\n\nfunc areOfSameKind(nodes []*ast.Node, kind ast.Kind) bool {\n\tfor _, n := range nodes {\n\t\tif n.Kind != kind {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc leastChildren(nodes []*ast.Node) int {\n\tmin := -1\n\tidx := -1\n\tfor i, n := range nodes {\n\t\tif idx == -1 || (len(n.Children) < min) {\n\t\t\tmin = len(n.Children)\n\t\t\tidx = i\n\t\t}\n\t}\n\treturn idx\n}\n\nfunc compileTreeChildren(tree *ast.Node, sep []rune) ([]match.Matcher, error) {\n\tvar matchers []match.Matcher\n\tfor _, desc := range tree.Children {\n\t\tm, err := compile(desc, sep)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmatchers = append(matchers, optimizeMatcher(m))\n\t}\n\treturn matchers, nil\n}\n\nfunc compile(tree *ast.Node, sep []rune) (m match.Matcher, err error) {\n\tswitch tree.Kind {\n\tcase ast.KindAnyOf:\n\t\t// todo this could be faster on pattern_alternatives_combine_lite (see glob_test.go)\n\t\tif n := minimizeTree(tree); n != nil {\n\t\t\treturn compile(n, sep)\n\t\t}\n\t\tmatchers, err := compileTreeChildren(tree, sep)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn match.NewAnyOf(matchers...), nil\n\n\tcase ast.KindPattern:\n\t\tif len(tree.Children) == 0 {\n\t\t\treturn match.NewNothing(), nil\n\t\t}\n\t\tmatchers, err := compileTreeChildren(tree, sep)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tm, err = compileMatchers(minimizeMatchers(matchers))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\tcase ast.KindAny:\n\t\tm = match.NewAny(sep)\n\n\tcase ast.KindSuper:\n\t\tm = match.NewSuper()\n\n\tcase ast.KindSingle:\n\t\tm = match.NewSingle(sep)\n\n\tcase ast.KindNothing:\n\t\tm = match.NewNothing()\n\n\tcase ast.KindList:\n\t\tl := tree.Value.(ast.List)\n\t\tm = match.NewList([]rune(l.Chars), l.Not)\n\n\tcase ast.KindRange:\n\t\tr := tree.Value.(ast.Range)\n\t\tm = match.NewRange(r.Lo, r.Hi, r.Not)\n\n\tcase ast.KindText:\n\t\tt := tree.Value.(ast.Text)\n\t\tm = match.NewText(t.Text)\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"could not compile tree: unknown node type\")\n\t}\n\n\treturn optimizeMatcher(m), nil\n}\n\nfunc Compile(tree *ast.Node, sep []rune) (match.Matcher, error) {\n\tm, err := compile(tree, sep)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn m, nil\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/glob.go",
    "content": "package glob\n\nimport (\n\t\"github.com/gobwas/glob/compiler\"\n\t\"github.com/gobwas/glob/syntax\"\n)\n\n// Glob represents compiled glob pattern.\ntype Glob interface {\n\tMatch(string) bool\n}\n\n// Compile creates Glob for given pattern and strings (if any present after pattern) as separators.\n// The pattern syntax is:\n//\n//    pattern:\n//        { term }\n//\n//    term:\n//        `*`         matches any sequence of non-separator characters\n//        `**`        matches any sequence of characters\n//        `?`         matches any single non-separator character\n//        `[` [ `!` ] { character-range } `]`\n//                    character class (must be non-empty)\n//        `{` pattern-list `}`\n//                    pattern alternatives\n//        c           matches character c (c != `*`, `**`, `?`, `\\`, `[`, `{`, `}`)\n//        `\\` c       matches character c\n//\n//    character-range:\n//        c           matches character c (c != `\\\\`, `-`, `]`)\n//        `\\` c       matches character c\n//        lo `-` hi   matches character c for lo <= c <= hi\n//\n//    pattern-list:\n//        pattern { `,` pattern }\n//                    comma-separated (without spaces) patterns\n//\nfunc Compile(pattern string, separators ...rune) (Glob, error) {\n\tast, err := syntax.Parse(pattern)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tmatcher, err := compiler.Compile(ast, separators)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn matcher, nil\n}\n\n// MustCompile is the same as Compile, except that if Compile returns error, this will panic\nfunc MustCompile(pattern string, separators ...rune) Glob {\n\tg, err := Compile(pattern, separators...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn g\n}\n\n// QuoteMeta returns a string that quotes all glob pattern meta characters\n// inside the argument text; For example, QuoteMeta(`{foo*}`) returns `\\[foo\\*\\]`.\nfunc QuoteMeta(s string) string {\n\tb := make([]byte, 2*len(s))\n\n\t// a byte loop is correct because all meta characters are ASCII\n\tj := 0\n\tfor i := 0; i < len(s); i++ {\n\t\tif syntax.Special(s[i]) {\n\t\t\tb[j] = '\\\\'\n\t\t\tj++\n\t\t}\n\t\tb[j] = s[i]\n\t\tj++\n\t}\n\n\treturn string(b[0:j])\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/any.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"github.com/gobwas/glob/util/strings\"\n)\n\ntype Any struct {\n\tSeparators []rune\n}\n\nfunc NewAny(s []rune) Any {\n\treturn Any{s}\n}\n\nfunc (self Any) Match(s string) bool {\n\treturn strings.IndexAnyRunes(s, self.Separators) == -1\n}\n\nfunc (self Any) Index(s string) (int, []int) {\n\tfound := strings.IndexAnyRunes(s, self.Separators)\n\tswitch found {\n\tcase -1:\n\tcase 0:\n\t\treturn 0, segments0\n\tdefault:\n\t\ts = s[:found]\n\t}\n\n\tsegments := acquireSegments(len(s))\n\tfor i := range s {\n\t\tsegments = append(segments, i)\n\t}\n\tsegments = append(segments, len(s))\n\n\treturn 0, segments\n}\n\nfunc (self Any) Len() int {\n\treturn lenNo\n}\n\nfunc (self Any) String() string {\n\treturn fmt.Sprintf(\"<any:![%s]>\", string(self.Separators))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/any_of.go",
    "content": "package match\n\nimport \"fmt\"\n\ntype AnyOf struct {\n\tMatchers Matchers\n}\n\nfunc NewAnyOf(m ...Matcher) AnyOf {\n\treturn AnyOf{Matchers(m)}\n}\n\nfunc (self *AnyOf) Add(m Matcher) error {\n\tself.Matchers = append(self.Matchers, m)\n\treturn nil\n}\n\nfunc (self AnyOf) Match(s string) bool {\n\tfor _, m := range self.Matchers {\n\t\tif m.Match(s) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (self AnyOf) Index(s string) (int, []int) {\n\tindex := -1\n\n\tsegments := acquireSegments(len(s))\n\tfor _, m := range self.Matchers {\n\t\tidx, seg := m.Index(s)\n\t\tif idx == -1 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif index == -1 || idx < index {\n\t\t\tindex = idx\n\t\t\tsegments = append(segments[:0], seg...)\n\t\t\tcontinue\n\t\t}\n\n\t\tif idx > index {\n\t\t\tcontinue\n\t\t}\n\n\t\t// here idx == index\n\t\tsegments = appendMerge(segments, seg)\n\t}\n\n\tif index == -1 {\n\t\treleaseSegments(segments)\n\t\treturn -1, nil\n\t}\n\n\treturn index, segments\n}\n\nfunc (self AnyOf) Len() (l int) {\n\tl = -1\n\tfor _, m := range self.Matchers {\n\t\tml := m.Len()\n\t\tswitch {\n\t\tcase l == -1:\n\t\t\tl = ml\n\t\t\tcontinue\n\n\t\tcase ml == -1:\n\t\t\treturn -1\n\n\t\tcase l != ml:\n\t\t\treturn -1\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc (self AnyOf) String() string {\n\treturn fmt.Sprintf(\"<any_of:[%s]>\", self.Matchers)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/btree.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"unicode/utf8\"\n)\n\ntype BTree struct {\n\tValue            Matcher\n\tLeft             Matcher\n\tRight            Matcher\n\tValueLengthRunes int\n\tLeftLengthRunes  int\n\tRightLengthRunes int\n\tLengthRunes      int\n}\n\nfunc NewBTree(Value, Left, Right Matcher) (tree BTree) {\n\ttree.Value = Value\n\ttree.Left = Left\n\ttree.Right = Right\n\n\tlenOk := true\n\tif tree.ValueLengthRunes = Value.Len(); tree.ValueLengthRunes == -1 {\n\t\tlenOk = false\n\t}\n\n\tif Left != nil {\n\t\tif tree.LeftLengthRunes = Left.Len(); tree.LeftLengthRunes == -1 {\n\t\t\tlenOk = false\n\t\t}\n\t}\n\n\tif Right != nil {\n\t\tif tree.RightLengthRunes = Right.Len(); tree.RightLengthRunes == -1 {\n\t\t\tlenOk = false\n\t\t}\n\t}\n\n\tif lenOk {\n\t\ttree.LengthRunes = tree.LeftLengthRunes + tree.ValueLengthRunes + tree.RightLengthRunes\n\t} else {\n\t\ttree.LengthRunes = -1\n\t}\n\n\treturn tree\n}\n\nfunc (self BTree) Len() int {\n\treturn self.LengthRunes\n}\n\n// todo?\nfunc (self BTree) Index(s string) (int, []int) {\n\treturn -1, nil\n}\n\nfunc (self BTree) Match(s string) bool {\n\tinputLen := len(s)\n\n\t// self.Length, self.RLen and self.LLen are values meaning the length of runes for each part\n\t// here we manipulating byte length for better optimizations\n\t// but these checks still works, cause minLen of 1-rune string is 1 byte.\n\tif self.LengthRunes != -1 && self.LengthRunes > inputLen {\n\t\treturn false\n\t}\n\n\t// try to cut unnecessary parts\n\t// by knowledge of length of right and left part\n\tvar offset, limit int\n\tif self.LeftLengthRunes >= 0 {\n\t\toffset = self.LeftLengthRunes\n\t}\n\tif self.RightLengthRunes >= 0 {\n\t\tlimit = inputLen - self.RightLengthRunes\n\t} else {\n\t\tlimit = inputLen\n\t}\n\n\tfor offset < limit {\n\t\t// search for matching part in substring\n\t\tindex, segments := self.Value.Index(s[offset:limit])\n\t\tif index == -1 {\n\t\t\treleaseSegments(segments)\n\t\t\treturn false\n\t\t}\n\n\t\tl := s[:offset+index]\n\t\tvar left bool\n\t\tif self.Left != nil {\n\t\t\tleft = self.Left.Match(l)\n\t\t} else {\n\t\t\tleft = l == \"\"\n\t\t}\n\n\t\tif left {\n\t\t\tfor i := len(segments) - 1; i >= 0; i-- {\n\t\t\t\tlength := segments[i]\n\n\t\t\t\tvar right bool\n\t\t\t\tvar r string\n\t\t\t\t// if there is no string for the right branch\n\t\t\t\tif inputLen <= offset+index+length {\n\t\t\t\t\tr = \"\"\n\t\t\t\t} else {\n\t\t\t\t\tr = s[offset+index+length:]\n\t\t\t\t}\n\n\t\t\t\tif self.Right != nil {\n\t\t\t\t\tright = self.Right.Match(r)\n\t\t\t\t} else {\n\t\t\t\t\tright = r == \"\"\n\t\t\t\t}\n\n\t\t\t\tif right {\n\t\t\t\t\treleaseSegments(segments)\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t_, step := utf8.DecodeRuneInString(s[offset+index:])\n\t\toffset += index + step\n\n\t\treleaseSegments(segments)\n\t}\n\n\treturn false\n}\n\nfunc (self BTree) String() string {\n\tconst n string = \"<nil>\"\n\tvar l, r string\n\tif self.Left == nil {\n\t\tl = n\n\t} else {\n\t\tl = self.Left.String()\n\t}\n\tif self.Right == nil {\n\t\tr = n\n\t} else {\n\t\tr = self.Right.String()\n\t}\n\n\treturn fmt.Sprintf(\"<btree:[%s<-%s->%s]>\", l, self.Value, r)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/contains.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype Contains struct {\n\tNeedle string\n\tNot    bool\n}\n\nfunc NewContains(needle string, not bool) Contains {\n\treturn Contains{needle, not}\n}\n\nfunc (self Contains) Match(s string) bool {\n\treturn strings.Contains(s, self.Needle) != self.Not\n}\n\nfunc (self Contains) Index(s string) (int, []int) {\n\tvar offset int\n\n\tidx := strings.Index(s, self.Needle)\n\n\tif !self.Not {\n\t\tif idx == -1 {\n\t\t\treturn -1, nil\n\t\t}\n\n\t\toffset = idx + len(self.Needle)\n\t\tif len(s) <= offset {\n\t\t\treturn 0, []int{offset}\n\t\t}\n\t\ts = s[offset:]\n\t} else if idx != -1 {\n\t\ts = s[:idx]\n\t}\n\n\tsegments := acquireSegments(len(s) + 1)\n\tfor i := range s {\n\t\tsegments = append(segments, offset+i)\n\t}\n\n\treturn 0, append(segments, offset+len(s))\n}\n\nfunc (self Contains) Len() int {\n\treturn lenNo\n}\n\nfunc (self Contains) String() string {\n\tvar not string\n\tif self.Not {\n\t\tnot = \"!\"\n\t}\n\treturn fmt.Sprintf(\"<contains:%s[%s]>\", not, self.Needle)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/every_of.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n)\n\ntype EveryOf struct {\n\tMatchers Matchers\n}\n\nfunc NewEveryOf(m ...Matcher) EveryOf {\n\treturn EveryOf{Matchers(m)}\n}\n\nfunc (self *EveryOf) Add(m Matcher) error {\n\tself.Matchers = append(self.Matchers, m)\n\treturn nil\n}\n\nfunc (self EveryOf) Len() (l int) {\n\tfor _, m := range self.Matchers {\n\t\tif ml := m.Len(); l > 0 {\n\t\t\tl += ml\n\t\t} else {\n\t\t\treturn -1\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc (self EveryOf) Index(s string) (int, []int) {\n\tvar index int\n\tvar offset int\n\n\t// make `in` with cap as len(s),\n\t// cause it is the maximum size of output segments values\n\tnext := acquireSegments(len(s))\n\tcurrent := acquireSegments(len(s))\n\n\tsub := s\n\tfor i, m := range self.Matchers {\n\t\tidx, seg := m.Index(sub)\n\t\tif idx == -1 {\n\t\t\treleaseSegments(next)\n\t\t\treleaseSegments(current)\n\t\t\treturn -1, nil\n\t\t}\n\n\t\tif i == 0 {\n\t\t\t// we use copy here instead of `current = seg`\n\t\t\t// cause seg is a slice from reusable buffer `in`\n\t\t\t// and it could be overwritten in next iteration\n\t\t\tcurrent = append(current, seg...)\n\t\t} else {\n\t\t\t// clear the next\n\t\t\tnext = next[:0]\n\n\t\t\tdelta := index - (idx + offset)\n\t\t\tfor _, ex := range current {\n\t\t\t\tfor _, n := range seg {\n\t\t\t\t\tif ex+delta == n {\n\t\t\t\t\t\tnext = append(next, n)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(next) == 0 {\n\t\t\t\treleaseSegments(next)\n\t\t\t\treleaseSegments(current)\n\t\t\t\treturn -1, nil\n\t\t\t}\n\n\t\t\tcurrent = append(current[:0], next...)\n\t\t}\n\n\t\tindex = idx + offset\n\t\tsub = s[index:]\n\t\toffset += idx\n\t}\n\n\treleaseSegments(next)\n\n\treturn index, current\n}\n\nfunc (self EveryOf) Match(s string) bool {\n\tfor _, m := range self.Matchers {\n\t\tif !m.Match(s) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (self EveryOf) String() string {\n\treturn fmt.Sprintf(\"<every_of:[%s]>\", self.Matchers)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/list.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"github.com/gobwas/glob/util/runes\"\n\t\"unicode/utf8\"\n)\n\ntype List struct {\n\tList []rune\n\tNot  bool\n}\n\nfunc NewList(list []rune, not bool) List {\n\treturn List{list, not}\n}\n\nfunc (self List) Match(s string) bool {\n\tr, w := utf8.DecodeRuneInString(s)\n\tif len(s) > w {\n\t\treturn false\n\t}\n\n\tinList := runes.IndexRune(self.List, r) != -1\n\treturn inList == !self.Not\n}\n\nfunc (self List) Len() int {\n\treturn lenOne\n}\n\nfunc (self List) Index(s string) (int, []int) {\n\tfor i, r := range s {\n\t\tif self.Not == (runes.IndexRune(self.List, r) == -1) {\n\t\t\treturn i, segmentsByRuneLength[utf8.RuneLen(r)]\n\t\t}\n\t}\n\n\treturn -1, nil\n}\n\nfunc (self List) String() string {\n\tvar not string\n\tif self.Not {\n\t\tnot = \"!\"\n\t}\n\n\treturn fmt.Sprintf(\"<list:%s[%s]>\", not, string(self.List))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/match.go",
    "content": "package match\n\n// todo common table of rune's length\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nconst lenOne = 1\nconst lenZero = 0\nconst lenNo = -1\n\ntype Matcher interface {\n\tMatch(string) bool\n\tIndex(string) (int, []int)\n\tLen() int\n\tString() string\n}\n\ntype Matchers []Matcher\n\nfunc (m Matchers) String() string {\n\tvar s []string\n\tfor _, matcher := range m {\n\t\ts = append(s, fmt.Sprint(matcher))\n\t}\n\n\treturn fmt.Sprintf(\"%s\", strings.Join(s, \",\"))\n}\n\n// appendMerge merges and sorts given already SORTED and UNIQUE segments.\nfunc appendMerge(target, sub []int) []int {\n\tlt, ls := len(target), len(sub)\n\tout := make([]int, 0, lt+ls)\n\n\tfor x, y := 0, 0; x < lt || y < ls; {\n\t\tif x >= lt {\n\t\t\tout = append(out, sub[y:]...)\n\t\t\tbreak\n\t\t}\n\n\t\tif y >= ls {\n\t\t\tout = append(out, target[x:]...)\n\t\t\tbreak\n\t\t}\n\n\t\txValue := target[x]\n\t\tyValue := sub[y]\n\n\t\tswitch {\n\n\t\tcase xValue == yValue:\n\t\t\tout = append(out, xValue)\n\t\t\tx++\n\t\t\ty++\n\n\t\tcase xValue < yValue:\n\t\t\tout = append(out, xValue)\n\t\t\tx++\n\n\t\tcase yValue < xValue:\n\t\t\tout = append(out, yValue)\n\t\t\ty++\n\n\t\t}\n\t}\n\n\ttarget = append(target[:0], out...)\n\n\treturn target\n}\n\nfunc reverseSegments(input []int) {\n\tl := len(input)\n\tm := l / 2\n\n\tfor i := 0; i < m; i++ {\n\t\tinput[i], input[l-i-1] = input[l-i-1], input[i]\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/max.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"unicode/utf8\"\n)\n\ntype Max struct {\n\tLimit int\n}\n\nfunc NewMax(l int) Max {\n\treturn Max{l}\n}\n\nfunc (self Max) Match(s string) bool {\n\tvar l int\n\tfor range s {\n\t\tl += 1\n\t\tif l > self.Limit {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (self Max) Index(s string) (int, []int) {\n\tsegments := acquireSegments(self.Limit + 1)\n\tsegments = append(segments, 0)\n\tvar count int\n\tfor i, r := range s {\n\t\tcount++\n\t\tif count > self.Limit {\n\t\t\tbreak\n\t\t}\n\t\tsegments = append(segments, i+utf8.RuneLen(r))\n\t}\n\n\treturn 0, segments\n}\n\nfunc (self Max) Len() int {\n\treturn lenNo\n}\n\nfunc (self Max) String() string {\n\treturn fmt.Sprintf(\"<max:%d>\", self.Limit)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/min.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"unicode/utf8\"\n)\n\ntype Min struct {\n\tLimit int\n}\n\nfunc NewMin(l int) Min {\n\treturn Min{l}\n}\n\nfunc (self Min) Match(s string) bool {\n\tvar l int\n\tfor range s {\n\t\tl += 1\n\t\tif l >= self.Limit {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc (self Min) Index(s string) (int, []int) {\n\tvar count int\n\n\tc := len(s) - self.Limit + 1\n\tif c <= 0 {\n\t\treturn -1, nil\n\t}\n\n\tsegments := acquireSegments(c)\n\tfor i, r := range s {\n\t\tcount++\n\t\tif count >= self.Limit {\n\t\t\tsegments = append(segments, i+utf8.RuneLen(r))\n\t\t}\n\t}\n\n\tif len(segments) == 0 {\n\t\treturn -1, nil\n\t}\n\n\treturn 0, segments\n}\n\nfunc (self Min) Len() int {\n\treturn lenNo\n}\n\nfunc (self Min) String() string {\n\treturn fmt.Sprintf(\"<min:%d>\", self.Limit)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/nothing.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n)\n\ntype Nothing struct{}\n\nfunc NewNothing() Nothing {\n\treturn Nothing{}\n}\n\nfunc (self Nothing) Match(s string) bool {\n\treturn len(s) == 0\n}\n\nfunc (self Nothing) Index(s string) (int, []int) {\n\treturn 0, segments0\n}\n\nfunc (self Nothing) Len() int {\n\treturn lenZero\n}\n\nfunc (self Nothing) String() string {\n\treturn fmt.Sprintf(\"<nothing>\")\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/prefix.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\ntype Prefix struct {\n\tPrefix string\n}\n\nfunc NewPrefix(p string) Prefix {\n\treturn Prefix{p}\n}\n\nfunc (self Prefix) Index(s string) (int, []int) {\n\tidx := strings.Index(s, self.Prefix)\n\tif idx == -1 {\n\t\treturn -1, nil\n\t}\n\n\tlength := len(self.Prefix)\n\tvar sub string\n\tif len(s) > idx+length {\n\t\tsub = s[idx+length:]\n\t} else {\n\t\tsub = \"\"\n\t}\n\n\tsegments := acquireSegments(len(sub) + 1)\n\tsegments = append(segments, length)\n\tfor i, r := range sub {\n\t\tsegments = append(segments, length+i+utf8.RuneLen(r))\n\t}\n\n\treturn idx, segments\n}\n\nfunc (self Prefix) Len() int {\n\treturn lenNo\n}\n\nfunc (self Prefix) Match(s string) bool {\n\treturn strings.HasPrefix(s, self.Prefix)\n}\n\nfunc (self Prefix) String() string {\n\treturn fmt.Sprintf(\"<prefix:%s>\", self.Prefix)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/prefix_any.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\tsutil \"github.com/gobwas/glob/util/strings\"\n)\n\ntype PrefixAny struct {\n\tPrefix     string\n\tSeparators []rune\n}\n\nfunc NewPrefixAny(s string, sep []rune) PrefixAny {\n\treturn PrefixAny{s, sep}\n}\n\nfunc (self PrefixAny) Index(s string) (int, []int) {\n\tidx := strings.Index(s, self.Prefix)\n\tif idx == -1 {\n\t\treturn -1, nil\n\t}\n\n\tn := len(self.Prefix)\n\tsub := s[idx+n:]\n\ti := sutil.IndexAnyRunes(sub, self.Separators)\n\tif i > -1 {\n\t\tsub = sub[:i]\n\t}\n\n\tseg := acquireSegments(len(sub) + 1)\n\tseg = append(seg, n)\n\tfor i, r := range sub {\n\t\tseg = append(seg, n+i+utf8.RuneLen(r))\n\t}\n\n\treturn idx, seg\n}\n\nfunc (self PrefixAny) Len() int {\n\treturn lenNo\n}\n\nfunc (self PrefixAny) Match(s string) bool {\n\tif !strings.HasPrefix(s, self.Prefix) {\n\t\treturn false\n\t}\n\treturn sutil.IndexAnyRunes(s[len(self.Prefix):], self.Separators) == -1\n}\n\nfunc (self PrefixAny) String() string {\n\treturn fmt.Sprintf(\"<prefix_any:%s![%s]>\", self.Prefix, string(self.Separators))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/prefix_suffix.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype PrefixSuffix struct {\n\tPrefix, Suffix string\n}\n\nfunc NewPrefixSuffix(p, s string) PrefixSuffix {\n\treturn PrefixSuffix{p, s}\n}\n\nfunc (self PrefixSuffix) Index(s string) (int, []int) {\n\tprefixIdx := strings.Index(s, self.Prefix)\n\tif prefixIdx == -1 {\n\t\treturn -1, nil\n\t}\n\n\tsuffixLen := len(self.Suffix)\n\tif suffixLen <= 0 {\n\t\treturn prefixIdx, []int{len(s) - prefixIdx}\n\t}\n\n\tif (len(s) - prefixIdx) <= 0 {\n\t\treturn -1, nil\n\t}\n\n\tsegments := acquireSegments(len(s) - prefixIdx)\n\tfor sub := s[prefixIdx:]; ; {\n\t\tsuffixIdx := strings.LastIndex(sub, self.Suffix)\n\t\tif suffixIdx == -1 {\n\t\t\tbreak\n\t\t}\n\n\t\tsegments = append(segments, suffixIdx+suffixLen)\n\t\tsub = sub[:suffixIdx]\n\t}\n\n\tif len(segments) == 0 {\n\t\treleaseSegments(segments)\n\t\treturn -1, nil\n\t}\n\n\treverseSegments(segments)\n\n\treturn prefixIdx, segments\n}\n\nfunc (self PrefixSuffix) Len() int {\n\treturn lenNo\n}\n\nfunc (self PrefixSuffix) Match(s string) bool {\n\treturn strings.HasPrefix(s, self.Prefix) && strings.HasSuffix(s, self.Suffix)\n}\n\nfunc (self PrefixSuffix) String() string {\n\treturn fmt.Sprintf(\"<prefix_suffix:[%s,%s]>\", self.Prefix, self.Suffix)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/range.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"unicode/utf8\"\n)\n\ntype Range struct {\n\tLo, Hi rune\n\tNot    bool\n}\n\nfunc NewRange(lo, hi rune, not bool) Range {\n\treturn Range{lo, hi, not}\n}\n\nfunc (self Range) Len() int {\n\treturn lenOne\n}\n\nfunc (self Range) Match(s string) bool {\n\tr, w := utf8.DecodeRuneInString(s)\n\tif len(s) > w {\n\t\treturn false\n\t}\n\n\tinRange := r >= self.Lo && r <= self.Hi\n\n\treturn inRange == !self.Not\n}\n\nfunc (self Range) Index(s string) (int, []int) {\n\tfor i, r := range s {\n\t\tif self.Not != (r >= self.Lo && r <= self.Hi) {\n\t\t\treturn i, segmentsByRuneLength[utf8.RuneLen(r)]\n\t\t}\n\t}\n\n\treturn -1, nil\n}\n\nfunc (self Range) String() string {\n\tvar not string\n\tif self.Not {\n\t\tnot = \"!\"\n\t}\n\treturn fmt.Sprintf(\"<range:%s[%s,%s]>\", not, string(self.Lo), string(self.Hi))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/row.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n)\n\ntype Row struct {\n\tMatchers    Matchers\n\tRunesLength int\n\tSegments    []int\n}\n\nfunc NewRow(len int, m ...Matcher) Row {\n\treturn Row{\n\t\tMatchers:    Matchers(m),\n\t\tRunesLength: len,\n\t\tSegments:    []int{len},\n\t}\n}\n\nfunc (self Row) matchAll(s string) bool {\n\tvar idx int\n\tfor _, m := range self.Matchers {\n\t\tlength := m.Len()\n\n\t\tvar next, i int\n\t\tfor next = range s[idx:] {\n\t\t\ti++\n\t\t\tif i == length {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif i < length || !m.Match(s[idx:idx+next+1]) {\n\t\t\treturn false\n\t\t}\n\n\t\tidx += next + 1\n\t}\n\n\treturn true\n}\n\nfunc (self Row) lenOk(s string) bool {\n\tvar i int\n\tfor range s {\n\t\ti++\n\t\tif i > self.RunesLength {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn self.RunesLength == i\n}\n\nfunc (self Row) Match(s string) bool {\n\treturn self.lenOk(s) && self.matchAll(s)\n}\n\nfunc (self Row) Len() (l int) {\n\treturn self.RunesLength\n}\n\nfunc (self Row) Index(s string) (int, []int) {\n\tfor i := range s {\n\t\tif len(s[i:]) < self.RunesLength {\n\t\t\tbreak\n\t\t}\n\t\tif self.matchAll(s[i:]) {\n\t\t\treturn i, self.Segments\n\t\t}\n\t}\n\treturn -1, nil\n}\n\nfunc (self Row) String() string {\n\treturn fmt.Sprintf(\"<row_%d:[%s]>\", self.RunesLength, self.Matchers)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/segments.go",
    "content": "package match\n\nimport (\n\t\"sync\"\n)\n\ntype SomePool interface {\n\tGet() []int\n\tPut([]int)\n}\n\nvar segmentsPools [1024]sync.Pool\n\nfunc toPowerOfTwo(v int) int {\n\tv--\n\tv |= v >> 1\n\tv |= v >> 2\n\tv |= v >> 4\n\tv |= v >> 8\n\tv |= v >> 16\n\tv++\n\n\treturn v\n}\n\nconst (\n\tcacheFrom             = 16\n\tcacheToAndHigher      = 1024\n\tcacheFromIndex        = 15\n\tcacheToAndHigherIndex = 1023\n)\n\nvar (\n\tsegments0 = []int{0}\n\tsegments1 = []int{1}\n\tsegments2 = []int{2}\n\tsegments3 = []int{3}\n\tsegments4 = []int{4}\n)\n\nvar segmentsByRuneLength [5][]int = [5][]int{\n\t0: segments0,\n\t1: segments1,\n\t2: segments2,\n\t3: segments3,\n\t4: segments4,\n}\n\nfunc init() {\n\tfor i := cacheToAndHigher; i >= cacheFrom; i >>= 1 {\n\t\tfunc(i int) {\n\t\t\tsegmentsPools[i-1] = sync.Pool{New: func() interface{} {\n\t\t\t\treturn make([]int, 0, i)\n\t\t\t}}\n\t\t}(i)\n\t}\n}\n\nfunc getTableIndex(c int) int {\n\tp := toPowerOfTwo(c)\n\tswitch {\n\tcase p >= cacheToAndHigher:\n\t\treturn cacheToAndHigherIndex\n\tcase p <= cacheFrom:\n\t\treturn cacheFromIndex\n\tdefault:\n\t\treturn p - 1\n\t}\n}\n\nfunc acquireSegments(c int) []int {\n\t// make []int with less capacity than cacheFrom\n\t// is faster than acquiring it from pool\n\tif c < cacheFrom {\n\t\treturn make([]int, 0, c)\n\t}\n\n\treturn segmentsPools[getTableIndex(c)].Get().([]int)[:0]\n}\n\nfunc releaseSegments(s []int) {\n\tc := cap(s)\n\n\t// make []int with less capacity than cacheFrom\n\t// is faster than acquiring it from pool\n\tif c < cacheFrom {\n\t\treturn\n\t}\n\n\tsegmentsPools[getTableIndex(c)].Put(s)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/single.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"github.com/gobwas/glob/util/runes\"\n\t\"unicode/utf8\"\n)\n\n// single represents ?\ntype Single struct {\n\tSeparators []rune\n}\n\nfunc NewSingle(s []rune) Single {\n\treturn Single{s}\n}\n\nfunc (self Single) Match(s string) bool {\n\tr, w := utf8.DecodeRuneInString(s)\n\tif len(s) > w {\n\t\treturn false\n\t}\n\n\treturn runes.IndexRune(self.Separators, r) == -1\n}\n\nfunc (self Single) Len() int {\n\treturn lenOne\n}\n\nfunc (self Single) Index(s string) (int, []int) {\n\tfor i, r := range s {\n\t\tif runes.IndexRune(self.Separators, r) == -1 {\n\t\t\treturn i, segmentsByRuneLength[utf8.RuneLen(r)]\n\t\t}\n\t}\n\n\treturn -1, nil\n}\n\nfunc (self Single) String() string {\n\treturn fmt.Sprintf(\"<single:![%s]>\", string(self.Separators))\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/suffix.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype Suffix struct {\n\tSuffix string\n}\n\nfunc NewSuffix(s string) Suffix {\n\treturn Suffix{s}\n}\n\nfunc (self Suffix) Len() int {\n\treturn lenNo\n}\n\nfunc (self Suffix) Match(s string) bool {\n\treturn strings.HasSuffix(s, self.Suffix)\n}\n\nfunc (self Suffix) Index(s string) (int, []int) {\n\tidx := strings.Index(s, self.Suffix)\n\tif idx == -1 {\n\t\treturn -1, nil\n\t}\n\n\treturn 0, []int{idx + len(self.Suffix)}\n}\n\nfunc (self Suffix) String() string {\n\treturn fmt.Sprintf(\"<suffix:%s>\", self.Suffix)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/suffix_any.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tsutil \"github.com/gobwas/glob/util/strings\"\n)\n\ntype SuffixAny struct {\n\tSuffix     string\n\tSeparators []rune\n}\n\nfunc NewSuffixAny(s string, sep []rune) SuffixAny {\n\treturn SuffixAny{s, sep}\n}\n\nfunc (self SuffixAny) Index(s string) (int, []int) {\n\tidx := strings.Index(s, self.Suffix)\n\tif idx == -1 {\n\t\treturn -1, nil\n\t}\n\n\ti := sutil.LastIndexAnyRunes(s[:idx], self.Separators) + 1\n\n\treturn i, []int{idx + len(self.Suffix) - i}\n}\n\nfunc (self SuffixAny) Len() int {\n\treturn lenNo\n}\n\nfunc (self SuffixAny) Match(s string) bool {\n\tif !strings.HasSuffix(s, self.Suffix) {\n\t\treturn false\n\t}\n\treturn sutil.IndexAnyRunes(s[:len(s)-len(self.Suffix)], self.Separators) == -1\n}\n\nfunc (self SuffixAny) String() string {\n\treturn fmt.Sprintf(\"<suffix_any:![%s]%s>\", string(self.Separators), self.Suffix)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/super.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n)\n\ntype Super struct{}\n\nfunc NewSuper() Super {\n\treturn Super{}\n}\n\nfunc (self Super) Match(s string) bool {\n\treturn true\n}\n\nfunc (self Super) Len() int {\n\treturn lenNo\n}\n\nfunc (self Super) Index(s string) (int, []int) {\n\tsegments := acquireSegments(len(s) + 1)\n\tfor i := range s {\n\t\tsegments = append(segments, i)\n\t}\n\tsegments = append(segments, len(s))\n\n\treturn 0, segments\n}\n\nfunc (self Super) String() string {\n\treturn fmt.Sprintf(\"<super>\")\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/match/text.go",
    "content": "package match\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// raw represents raw string to match\ntype Text struct {\n\tStr         string\n\tRunesLength int\n\tBytesLength int\n\tSegments    []int\n}\n\nfunc NewText(s string) Text {\n\treturn Text{\n\t\tStr:         s,\n\t\tRunesLength: utf8.RuneCountInString(s),\n\t\tBytesLength: len(s),\n\t\tSegments:    []int{len(s)},\n\t}\n}\n\nfunc (self Text) Match(s string) bool {\n\treturn self.Str == s\n}\n\nfunc (self Text) Len() int {\n\treturn self.RunesLength\n}\n\nfunc (self Text) Index(s string) (int, []int) {\n\tindex := strings.Index(s, self.Str)\n\tif index == -1 {\n\t\treturn -1, nil\n\t}\n\n\treturn index, self.Segments\n}\n\nfunc (self Text) String() string {\n\treturn fmt.Sprintf(\"<text:`%v`>\", self.Str)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/readme.md",
    "content": "# glob.[go](https://golang.org)\n\n[![GoDoc][godoc-image]][godoc-url] [![Build Status][travis-image]][travis-url]\n\n> Go Globbing Library.\n\n## Install\n\n```shell\n    go get github.com/gobwas/glob\n```\n\n## Example\n\n```go\n\npackage main\n\nimport \"github.com/gobwas/glob\"\n\nfunc main() {\n    var g glob.Glob\n    \n    // create simple glob\n    g = glob.MustCompile(\"*.github.com\")\n    g.Match(\"api.github.com\") // true\n    \n    // quote meta characters and then create simple glob \n    g = glob.MustCompile(glob.QuoteMeta(\"*.github.com\"))\n    g.Match(\"*.github.com\") // true\n    \n    // create new glob with set of delimiters as [\".\"]\n    g = glob.MustCompile(\"api.*.com\", '.')\n    g.Match(\"api.github.com\") // true\n    g.Match(\"api.gi.hub.com\") // false\n    \n    // create new glob with set of delimiters as [\".\"]\n    // but now with super wildcard\n    g = glob.MustCompile(\"api.**.com\", '.')\n    g.Match(\"api.github.com\") // true\n    g.Match(\"api.gi.hub.com\") // true\n        \n    // create glob with single symbol wildcard\n    g = glob.MustCompile(\"?at\")\n    g.Match(\"cat\") // true\n    g.Match(\"fat\") // true\n    g.Match(\"at\") // false\n    \n    // create glob with single symbol wildcard and delimiters ['f']\n    g = glob.MustCompile(\"?at\", 'f')\n    g.Match(\"cat\") // true\n    g.Match(\"fat\") // false\n    g.Match(\"at\") // false \n    \n    // create glob with character-list matchers \n    g = glob.MustCompile(\"[abc]at\")\n    g.Match(\"cat\") // true\n    g.Match(\"bat\") // true\n    g.Match(\"fat\") // false\n    g.Match(\"at\") // false\n    \n    // create glob with character-list matchers \n    g = glob.MustCompile(\"[!abc]at\")\n    g.Match(\"cat\") // false\n    g.Match(\"bat\") // false\n    g.Match(\"fat\") // true\n    g.Match(\"at\") // false \n    \n    // create glob with character-range matchers \n    g = glob.MustCompile(\"[a-c]at\")\n    g.Match(\"cat\") // true\n    g.Match(\"bat\") // true\n    g.Match(\"fat\") // false\n    g.Match(\"at\") // false\n    \n    // create glob with character-range matchers \n    g = glob.MustCompile(\"[!a-c]at\")\n    g.Match(\"cat\") // false\n    g.Match(\"bat\") // false\n    g.Match(\"fat\") // true\n    g.Match(\"at\") // false \n    \n    // create glob with pattern-alternatives list \n    g = glob.MustCompile(\"{cat,bat,[fr]at}\")\n    g.Match(\"cat\") // true\n    g.Match(\"bat\") // true\n    g.Match(\"fat\") // true\n    g.Match(\"rat\") // true\n    g.Match(\"at\") // false \n    g.Match(\"zat\") // false \n}\n\n```\n\n## Performance\n\nThis library is created for compile-once patterns. This means, that compilation could take time, but \nstrings matching is done faster, than in case when always parsing template.\n\nIf you will not use compiled `glob.Glob` object, and do `g := glob.MustCompile(pattern); g.Match(...)` every time, then your code will be much more slower.\n\nRun `go test -bench=.` from source root to see the benchmarks:\n\nPattern | Fixture | Match | Speed (ns/op)\n--------|---------|-------|--------------\n`[a-z][!a-x]*cat*[h][!b]*eyes*` | `my cat has very bright eyes` | `true` | 432\n`[a-z][!a-x]*cat*[h][!b]*eyes*` | `my dog has very bright eyes` | `false` | 199\n`https://*.google.*` | `https://account.google.com` | `true` | 96\n`https://*.google.*` | `https://google.com` | `false` | 66\n`{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}` | `http://yahoo.com` | `true` | 163\n`{https://*.google.*,*yandex.*,*yahoo.*,*mail.ru}` | `http://google.com` | `false` | 197\n`{https://*gobwas.com,http://exclude.gobwas.com}` | `https://safe.gobwas.com` | `true` | 22\n`{https://*gobwas.com,http://exclude.gobwas.com}` | `http://safe.gobwas.com` | `false` | 24\n`abc*` | `abcdef` | `true` | 8.15\n`abc*` | `af` | `false` | 5.68\n`*def` | `abcdef` | `true` | 8.84\n`*def` | `af` | `false` | 5.74\n`ab*ef` | `abcdef` | `true` | 15.2\n`ab*ef` | `af` | `false` | 10.4\n\nThe same things with `regexp` package:\n\nPattern | Fixture | Match | Speed (ns/op)\n--------|---------|-------|--------------\n`^[a-z][^a-x].*cat.*[h][^b].*eyes.*$` | `my cat has very bright eyes` | `true` | 2553\n`^[a-z][^a-x].*cat.*[h][^b].*eyes.*$` | `my dog has very bright eyes` | `false` | 1383\n`^https:\\/\\/.*\\.google\\..*$` | `https://account.google.com` | `true` | 1205\n`^https:\\/\\/.*\\.google\\..*$` | `https://google.com` | `false` | 767\n`^(https:\\/\\/.*\\.google\\..*|.*yandex\\..*|.*yahoo\\..*|.*mail\\.ru)$` | `http://yahoo.com` | `true` | 1435\n`^(https:\\/\\/.*\\.google\\..*|.*yandex\\..*|.*yahoo\\..*|.*mail\\.ru)$` | `http://google.com` | `false` | 1674\n`^(https:\\/\\/.*gobwas\\.com|http://exclude.gobwas.com)$` | `https://safe.gobwas.com` | `true` | 1039\n`^(https:\\/\\/.*gobwas\\.com|http://exclude.gobwas.com)$` | `http://safe.gobwas.com` | `false` | 272\n`^abc.*$` | `abcdef` | `true` | 237\n`^abc.*$` | `af` | `false` | 100\n`^.*def$` | `abcdef` | `true` | 464\n`^.*def$` | `af` | `false` | 265\n`^ab.*ef$` | `abcdef` | `true` | 375\n`^ab.*ef$` | `af` | `false` | 145\n\n[godoc-image]: https://godoc.org/github.com/gobwas/glob?status.svg\n[godoc-url]: https://godoc.org/github.com/gobwas/glob\n[travis-image]: https://travis-ci.org/gobwas/glob.svg?branch=master\n[travis-url]: https://travis-ci.org/gobwas/glob\n\n## Syntax\n\nSyntax is inspired by [standard wildcards](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm),\nexcept that `**` is aka super-asterisk, that do not sensitive for separators."
  },
  {
    "path": "vendor/github.com/gobwas/glob/syntax/ast/ast.go",
    "content": "package ast\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n)\n\ntype Node struct {\n\tParent   *Node\n\tChildren []*Node\n\tValue    interface{}\n\tKind     Kind\n}\n\nfunc NewNode(k Kind, v interface{}, ch ...*Node) *Node {\n\tn := &Node{\n\t\tKind:  k,\n\t\tValue: v,\n\t}\n\tfor _, c := range ch {\n\t\tInsert(n, c)\n\t}\n\treturn n\n}\n\nfunc (a *Node) Equal(b *Node) bool {\n\tif a.Kind != b.Kind {\n\t\treturn false\n\t}\n\tif a.Value != b.Value {\n\t\treturn false\n\t}\n\tif len(a.Children) != len(b.Children) {\n\t\treturn false\n\t}\n\tfor i, c := range a.Children {\n\t\tif !c.Equal(b.Children[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (a *Node) String() string {\n\tvar buf bytes.Buffer\n\tbuf.WriteString(a.Kind.String())\n\tif a.Value != nil {\n\t\tbuf.WriteString(\" =\")\n\t\tbuf.WriteString(fmt.Sprintf(\"%v\", a.Value))\n\t}\n\tif len(a.Children) > 0 {\n\t\tbuf.WriteString(\" [\")\n\t\tfor i, c := range a.Children {\n\t\t\tif i > 0 {\n\t\t\t\tbuf.WriteString(\", \")\n\t\t\t}\n\t\t\tbuf.WriteString(c.String())\n\t\t}\n\t\tbuf.WriteString(\"]\")\n\t}\n\treturn buf.String()\n}\n\nfunc Insert(parent *Node, children ...*Node) {\n\tparent.Children = append(parent.Children, children...)\n\tfor _, ch := range children {\n\t\tch.Parent = parent\n\t}\n}\n\ntype List struct {\n\tNot   bool\n\tChars string\n}\n\ntype Range struct {\n\tNot    bool\n\tLo, Hi rune\n}\n\ntype Text struct {\n\tText string\n}\n\ntype Kind int\n\nconst (\n\tKindNothing Kind = iota\n\tKindPattern\n\tKindList\n\tKindRange\n\tKindText\n\tKindAny\n\tKindSuper\n\tKindSingle\n\tKindAnyOf\n)\n\nfunc (k Kind) String() string {\n\tswitch k {\n\tcase KindNothing:\n\t\treturn \"Nothing\"\n\tcase KindPattern:\n\t\treturn \"Pattern\"\n\tcase KindList:\n\t\treturn \"List\"\n\tcase KindRange:\n\t\treturn \"Range\"\n\tcase KindText:\n\t\treturn \"Text\"\n\tcase KindAny:\n\t\treturn \"Any\"\n\tcase KindSuper:\n\t\treturn \"Super\"\n\tcase KindSingle:\n\t\treturn \"Single\"\n\tcase KindAnyOf:\n\t\treturn \"AnyOf\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/syntax/ast/parser.go",
    "content": "package ast\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/gobwas/glob/syntax/lexer\"\n\t\"unicode/utf8\"\n)\n\ntype Lexer interface {\n\tNext() lexer.Token\n}\n\ntype parseFn func(*Node, Lexer) (parseFn, *Node, error)\n\nfunc Parse(lexer Lexer) (*Node, error) {\n\tvar parser parseFn\n\n\troot := NewNode(KindPattern, nil)\n\n\tvar (\n\t\ttree *Node\n\t\terr  error\n\t)\n\tfor parser, tree = parserMain, root; parser != nil; {\n\t\tparser, tree, err = parser(tree, lexer)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn root, nil\n}\n\nfunc parserMain(tree *Node, lex Lexer) (parseFn, *Node, error) {\n\tfor {\n\t\ttoken := lex.Next()\n\t\tswitch token.Type {\n\t\tcase lexer.EOF:\n\t\t\treturn nil, tree, nil\n\n\t\tcase lexer.Error:\n\t\t\treturn nil, tree, errors.New(token.Raw)\n\n\t\tcase lexer.Text:\n\t\t\tInsert(tree, NewNode(KindText, Text{token.Raw}))\n\t\t\treturn parserMain, tree, nil\n\n\t\tcase lexer.Any:\n\t\t\tInsert(tree, NewNode(KindAny, nil))\n\t\t\treturn parserMain, tree, nil\n\n\t\tcase lexer.Super:\n\t\t\tInsert(tree, NewNode(KindSuper, nil))\n\t\t\treturn parserMain, tree, nil\n\n\t\tcase lexer.Single:\n\t\t\tInsert(tree, NewNode(KindSingle, nil))\n\t\t\treturn parserMain, tree, nil\n\n\t\tcase lexer.RangeOpen:\n\t\t\treturn parserRange, tree, nil\n\n\t\tcase lexer.TermsOpen:\n\t\t\ta := NewNode(KindAnyOf, nil)\n\t\t\tInsert(tree, a)\n\n\t\t\tp := NewNode(KindPattern, nil)\n\t\t\tInsert(a, p)\n\n\t\t\treturn parserMain, p, nil\n\n\t\tcase lexer.Separator:\n\t\t\tp := NewNode(KindPattern, nil)\n\t\t\tInsert(tree.Parent, p)\n\n\t\t\treturn parserMain, p, nil\n\n\t\tcase lexer.TermsClose:\n\t\t\treturn parserMain, tree.Parent.Parent, nil\n\n\t\tdefault:\n\t\t\treturn nil, tree, fmt.Errorf(\"unexpected token: %s\", token)\n\t\t}\n\t}\n\treturn nil, tree, fmt.Errorf(\"unknown error\")\n}\n\nfunc parserRange(tree *Node, lex Lexer) (parseFn, *Node, error) {\n\tvar (\n\t\tnot   bool\n\t\tlo    rune\n\t\thi    rune\n\t\tchars string\n\t)\n\tfor {\n\t\ttoken := lex.Next()\n\t\tswitch token.Type {\n\t\tcase lexer.EOF:\n\t\t\treturn nil, tree, errors.New(\"unexpected end\")\n\n\t\tcase lexer.Error:\n\t\t\treturn nil, tree, errors.New(token.Raw)\n\n\t\tcase lexer.Not:\n\t\t\tnot = true\n\n\t\tcase lexer.RangeLo:\n\t\t\tr, w := utf8.DecodeRuneInString(token.Raw)\n\t\t\tif len(token.Raw) > w {\n\t\t\t\treturn nil, tree, fmt.Errorf(\"unexpected length of lo character\")\n\t\t\t}\n\t\t\tlo = r\n\n\t\tcase lexer.RangeBetween:\n\t\t\t//\n\n\t\tcase lexer.RangeHi:\n\t\t\tr, w := utf8.DecodeRuneInString(token.Raw)\n\t\t\tif len(token.Raw) > w {\n\t\t\t\treturn nil, tree, fmt.Errorf(\"unexpected length of lo character\")\n\t\t\t}\n\n\t\t\thi = r\n\n\t\t\tif hi < lo {\n\t\t\t\treturn nil, tree, fmt.Errorf(\"hi character '%s' should be greater than lo '%s'\", string(hi), string(lo))\n\t\t\t}\n\n\t\tcase lexer.Text:\n\t\t\tchars = token.Raw\n\n\t\tcase lexer.RangeClose:\n\t\t\tisRange := lo != 0 && hi != 0\n\t\t\tisChars := chars != \"\"\n\n\t\t\tif isChars == isRange {\n\t\t\t\treturn nil, tree, fmt.Errorf(\"could not parse range\")\n\t\t\t}\n\n\t\t\tif isRange {\n\t\t\t\tInsert(tree, NewNode(KindRange, Range{\n\t\t\t\t\tLo:  lo,\n\t\t\t\t\tHi:  hi,\n\t\t\t\t\tNot: not,\n\t\t\t\t}))\n\t\t\t} else {\n\t\t\t\tInsert(tree, NewNode(KindList, List{\n\t\t\t\t\tChars: chars,\n\t\t\t\t\tNot:   not,\n\t\t\t\t}))\n\t\t\t}\n\n\t\t\treturn parserMain, tree, nil\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/syntax/lexer/lexer.go",
    "content": "package lexer\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"github.com/gobwas/glob/util/runes\"\n\t\"unicode/utf8\"\n)\n\nconst (\n\tchar_any           = '*'\n\tchar_comma         = ','\n\tchar_single        = '?'\n\tchar_escape        = '\\\\'\n\tchar_range_open    = '['\n\tchar_range_close   = ']'\n\tchar_terms_open    = '{'\n\tchar_terms_close   = '}'\n\tchar_range_not     = '!'\n\tchar_range_between = '-'\n)\n\nvar specials = []byte{\n\tchar_any,\n\tchar_single,\n\tchar_escape,\n\tchar_range_open,\n\tchar_range_close,\n\tchar_terms_open,\n\tchar_terms_close,\n}\n\nfunc Special(c byte) bool {\n\treturn bytes.IndexByte(specials, c) != -1\n}\n\ntype tokens []Token\n\nfunc (i *tokens) shift() (ret Token) {\n\tret = (*i)[0]\n\tcopy(*i, (*i)[1:])\n\t*i = (*i)[:len(*i)-1]\n\treturn\n}\n\nfunc (i *tokens) push(v Token) {\n\t*i = append(*i, v)\n}\n\nfunc (i *tokens) empty() bool {\n\treturn len(*i) == 0\n}\n\nvar eof rune = 0\n\ntype lexer struct {\n\tdata string\n\tpos  int\n\terr  error\n\n\ttokens     tokens\n\ttermsLevel int\n\n\tlastRune     rune\n\tlastRuneSize int\n\thasRune      bool\n}\n\nfunc NewLexer(source string) *lexer {\n\tl := &lexer{\n\t\tdata:   source,\n\t\ttokens: tokens(make([]Token, 0, 4)),\n\t}\n\treturn l\n}\n\nfunc (l *lexer) Next() Token {\n\tif l.err != nil {\n\t\treturn Token{Error, l.err.Error()}\n\t}\n\tif !l.tokens.empty() {\n\t\treturn l.tokens.shift()\n\t}\n\n\tl.fetchItem()\n\treturn l.Next()\n}\n\nfunc (l *lexer) peek() (r rune, w int) {\n\tif l.pos == len(l.data) {\n\t\treturn eof, 0\n\t}\n\n\tr, w = utf8.DecodeRuneInString(l.data[l.pos:])\n\tif r == utf8.RuneError {\n\t\tl.errorf(\"could not read rune\")\n\t\tr = eof\n\t\tw = 0\n\t}\n\n\treturn\n}\n\nfunc (l *lexer) read() rune {\n\tif l.hasRune {\n\t\tl.hasRune = false\n\t\tl.seek(l.lastRuneSize)\n\t\treturn l.lastRune\n\t}\n\n\tr, s := l.peek()\n\tl.seek(s)\n\n\tl.lastRune = r\n\tl.lastRuneSize = s\n\n\treturn r\n}\n\nfunc (l *lexer) seek(w int) {\n\tl.pos += w\n}\n\nfunc (l *lexer) unread() {\n\tif l.hasRune {\n\t\tl.errorf(\"could not unread rune\")\n\t\treturn\n\t}\n\tl.seek(-l.lastRuneSize)\n\tl.hasRune = true\n}\n\nfunc (l *lexer) errorf(f string, v ...interface{}) {\n\tl.err = fmt.Errorf(f, v...)\n}\n\nfunc (l *lexer) inTerms() bool {\n\treturn l.termsLevel > 0\n}\n\nfunc (l *lexer) termsEnter() {\n\tl.termsLevel++\n}\n\nfunc (l *lexer) termsLeave() {\n\tl.termsLevel--\n}\n\nvar inTextBreakers = []rune{char_single, char_any, char_range_open, char_terms_open}\nvar inTermsBreakers = append(inTextBreakers, char_terms_close, char_comma)\n\nfunc (l *lexer) fetchItem() {\n\tr := l.read()\n\tswitch {\n\tcase r == eof:\n\t\tl.tokens.push(Token{EOF, \"\"})\n\n\tcase r == char_terms_open:\n\t\tl.termsEnter()\n\t\tl.tokens.push(Token{TermsOpen, string(r)})\n\n\tcase r == char_comma && l.inTerms():\n\t\tl.tokens.push(Token{Separator, string(r)})\n\n\tcase r == char_terms_close && l.inTerms():\n\t\tl.tokens.push(Token{TermsClose, string(r)})\n\t\tl.termsLeave()\n\n\tcase r == char_range_open:\n\t\tl.tokens.push(Token{RangeOpen, string(r)})\n\t\tl.fetchRange()\n\n\tcase r == char_single:\n\t\tl.tokens.push(Token{Single, string(r)})\n\n\tcase r == char_any:\n\t\tif l.read() == char_any {\n\t\t\tl.tokens.push(Token{Super, string(r) + string(r)})\n\t\t} else {\n\t\t\tl.unread()\n\t\t\tl.tokens.push(Token{Any, string(r)})\n\t\t}\n\n\tdefault:\n\t\tl.unread()\n\n\t\tvar breakers []rune\n\t\tif l.inTerms() {\n\t\t\tbreakers = inTermsBreakers\n\t\t} else {\n\t\t\tbreakers = inTextBreakers\n\t\t}\n\t\tl.fetchText(breakers)\n\t}\n}\n\nfunc (l *lexer) fetchRange() {\n\tvar wantHi bool\n\tvar wantClose bool\n\tvar seenNot bool\n\tfor {\n\t\tr := l.read()\n\t\tif r == eof {\n\t\t\tl.errorf(\"unexpected end of input\")\n\t\t\treturn\n\t\t}\n\n\t\tif wantClose {\n\t\t\tif r != char_range_close {\n\t\t\t\tl.errorf(\"expected close range character\")\n\t\t\t} else {\n\t\t\t\tl.tokens.push(Token{RangeClose, string(r)})\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif wantHi {\n\t\t\tl.tokens.push(Token{RangeHi, string(r)})\n\t\t\twantClose = true\n\t\t\tcontinue\n\t\t}\n\n\t\tif !seenNot && r == char_range_not {\n\t\t\tl.tokens.push(Token{Not, string(r)})\n\t\t\tseenNot = true\n\t\t\tcontinue\n\t\t}\n\n\t\tif n, w := l.peek(); n == char_range_between {\n\t\t\tl.seek(w)\n\t\t\tl.tokens.push(Token{RangeLo, string(r)})\n\t\t\tl.tokens.push(Token{RangeBetween, string(n)})\n\t\t\twantHi = true\n\t\t\tcontinue\n\t\t}\n\n\t\tl.unread() // unread first peek and fetch as text\n\t\tl.fetchText([]rune{char_range_close})\n\t\twantClose = true\n\t}\n}\n\nfunc (l *lexer) fetchText(breakers []rune) {\n\tvar data []rune\n\tvar escaped bool\n\nreading:\n\tfor {\n\t\tr := l.read()\n\t\tif r == eof {\n\t\t\tbreak\n\t\t}\n\n\t\tif !escaped {\n\t\t\tif r == char_escape {\n\t\t\t\tescaped = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif runes.IndexRune(breakers, r) != -1 {\n\t\t\t\tl.unread()\n\t\t\t\tbreak reading\n\t\t\t}\n\t\t}\n\n\t\tescaped = false\n\t\tdata = append(data, r)\n\t}\n\n\tif len(data) > 0 {\n\t\tl.tokens.push(Token{Text, string(data)})\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/syntax/lexer/token.go",
    "content": "package lexer\n\nimport \"fmt\"\n\ntype TokenType int\n\nconst (\n\tEOF TokenType = iota\n\tError\n\tText\n\tChar\n\tAny\n\tSuper\n\tSingle\n\tNot\n\tSeparator\n\tRangeOpen\n\tRangeClose\n\tRangeLo\n\tRangeHi\n\tRangeBetween\n\tTermsOpen\n\tTermsClose\n)\n\nfunc (tt TokenType) String() string {\n\tswitch tt {\n\tcase EOF:\n\t\treturn \"eof\"\n\n\tcase Error:\n\t\treturn \"error\"\n\n\tcase Text:\n\t\treturn \"text\"\n\n\tcase Char:\n\t\treturn \"char\"\n\n\tcase Any:\n\t\treturn \"any\"\n\n\tcase Super:\n\t\treturn \"super\"\n\n\tcase Single:\n\t\treturn \"single\"\n\n\tcase Not:\n\t\treturn \"not\"\n\n\tcase Separator:\n\t\treturn \"separator\"\n\n\tcase RangeOpen:\n\t\treturn \"range_open\"\n\n\tcase RangeClose:\n\t\treturn \"range_close\"\n\n\tcase RangeLo:\n\t\treturn \"range_lo\"\n\n\tcase RangeHi:\n\t\treturn \"range_hi\"\n\n\tcase RangeBetween:\n\t\treturn \"range_between\"\n\n\tcase TermsOpen:\n\t\treturn \"terms_open\"\n\n\tcase TermsClose:\n\t\treturn \"terms_close\"\n\n\tdefault:\n\t\treturn \"undef\"\n\t}\n}\n\ntype Token struct {\n\tType TokenType\n\tRaw  string\n}\n\nfunc (t Token) String() string {\n\treturn fmt.Sprintf(\"%v<%q>\", t.Type, t.Raw)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/syntax/syntax.go",
    "content": "package syntax\n\nimport (\n\t\"github.com/gobwas/glob/syntax/ast\"\n\t\"github.com/gobwas/glob/syntax/lexer\"\n)\n\nfunc Parse(s string) (*ast.Node, error) {\n\treturn ast.Parse(lexer.NewLexer(s))\n}\n\nfunc Special(b byte) bool {\n\treturn lexer.Special(b)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/util/runes/runes.go",
    "content": "package runes\n\nfunc Index(s, needle []rune) int {\n\tls, ln := len(s), len(needle)\n\n\tswitch {\n\tcase ln == 0:\n\t\treturn 0\n\tcase ln == 1:\n\t\treturn IndexRune(s, needle[0])\n\tcase ln == ls:\n\t\tif Equal(s, needle) {\n\t\t\treturn 0\n\t\t}\n\t\treturn -1\n\tcase ln > ls:\n\t\treturn -1\n\t}\n\nhead:\n\tfor i := 0; i < ls && ls-i >= ln; i++ {\n\t\tfor y := 0; y < ln; y++ {\n\t\t\tif s[i+y] != needle[y] {\n\t\t\t\tcontinue head\n\t\t\t}\n\t\t}\n\n\t\treturn i\n\t}\n\n\treturn -1\n}\n\nfunc LastIndex(s, needle []rune) int {\n\tls, ln := len(s), len(needle)\n\n\tswitch {\n\tcase ln == 0:\n\t\tif ls == 0 {\n\t\t\treturn 0\n\t\t}\n\t\treturn ls\n\tcase ln == 1:\n\t\treturn IndexLastRune(s, needle[0])\n\tcase ln == ls:\n\t\tif Equal(s, needle) {\n\t\t\treturn 0\n\t\t}\n\t\treturn -1\n\tcase ln > ls:\n\t\treturn -1\n\t}\n\nhead:\n\tfor i := ls - 1; i >= 0 && i >= ln; i-- {\n\t\tfor y := ln - 1; y >= 0; y-- {\n\t\t\tif s[i-(ln-y-1)] != needle[y] {\n\t\t\t\tcontinue head\n\t\t\t}\n\t\t}\n\n\t\treturn i - ln + 1\n\t}\n\n\treturn -1\n}\n\n// IndexAny returns the index of the first instance of any Unicode code point\n// from chars in s, or -1 if no Unicode code point from chars is present in s.\nfunc IndexAny(s, chars []rune) int {\n\tif len(chars) > 0 {\n\t\tfor i, c := range s {\n\t\t\tfor _, m := range chars {\n\t\t\t\tif c == m {\n\t\t\t\t\treturn i\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn -1\n}\n\nfunc Contains(s, needle []rune) bool {\n\treturn Index(s, needle) >= 0\n}\n\nfunc Max(s []rune) (max rune) {\n\tfor _, r := range s {\n\t\tif r > max {\n\t\t\tmax = r\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc Min(s []rune) rune {\n\tmin := rune(-1)\n\tfor _, r := range s {\n\t\tif min == -1 {\n\t\t\tmin = r\n\t\t\tcontinue\n\t\t}\n\n\t\tif r < min {\n\t\t\tmin = r\n\t\t}\n\t}\n\n\treturn min\n}\n\nfunc IndexRune(s []rune, r rune) int {\n\tfor i, c := range s {\n\t\tif c == r {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\nfunc IndexLastRune(s []rune, r rune) int {\n\tfor i := len(s) - 1; i >= 0; i-- {\n\t\tif s[i] == r {\n\t\t\treturn i\n\t\t}\n\t}\n\n\treturn -1\n}\n\nfunc Equal(a, b []rune) bool {\n\tif len(a) == len(b) {\n\t\tfor i := 0; i < len(a); i++ {\n\t\t\tif a[i] != b[i] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// HasPrefix tests whether the string s begins with prefix.\nfunc HasPrefix(s, prefix []rune) bool {\n\treturn len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix)\n}\n\n// HasSuffix tests whether the string s ends with suffix.\nfunc HasSuffix(s, suffix []rune) bool {\n\treturn len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)\n}\n"
  },
  {
    "path": "vendor/github.com/gobwas/glob/util/strings/strings.go",
    "content": "package strings\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nfunc IndexAnyRunes(s string, rs []rune) int {\n\tfor _, r := range rs {\n\t\tif i := strings.IndexRune(s, r); i != -1 {\n\t\t\treturn i\n\t\t}\n\t}\n\n\treturn -1\n}\n\nfunc LastIndexAnyRunes(s string, rs []rune) int {\n\tfor _, r := range rs {\n\t\ti := -1\n\t\tif 0 <= r && r < utf8.RuneSelf {\n\t\t\ti = strings.LastIndexByte(s, byte(r))\n\t\t} else {\n\t\t\tsub := s\n\t\t\tfor len(sub) > 0 {\n\t\t\t\tj := strings.IndexRune(s, r)\n\t\t\t\tif j == -1 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ti = j\n\t\t\t\tsub = sub[i+1:]\n\t\t\t}\n\t\t}\n\t\tif i != -1 {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/.codecov.yml",
    "content": "comment: false\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/.travis.yml",
    "content": "language: go\nsudo: false\ngo:\n  - 1.11.x\n  - 1.12.x\n  - 1.13.x\n  - tip\nscript:\n  - go get -u golang.org/x/lint/golint\n  - OUT=\"$(go get -a)\"; test -z \"$OUT\" || (echo \"$OUT\" && return 1)\n  - OUT=\"$(gofmt -l -d ./)\"; test -z \"$OUT\" || (echo \"$OUT\" && return 1)\n  - OUT=\"$(golint ./...)\"; test -z \"$OUT\" || (echo \"$OUT\" && return 1)\n  - go vet -v ./...\n  - go test -race -v -coverprofile=coverage.txt -covermode=atomic ./\n  - go build\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/CHANGELOG.md",
    "content": "# 2.0.0 - 2019.11.28\n\n - Breaking change: Change Collector.RedirectHandler member to Collector.SetRedirectHandler function\n - Go module support\n - Collector.HasVisited method added to be able to check if an url has been visited\n - Collector.SetClient method introduced\n - HTMLElement.ChildTexts method added\n - New user agents\n - Multiple bugfixes\n\n# 1.2.0 - 2019.02.13\n\n - Compatibility with the latest htmlquery package\n - New request shortcut for HEAD requests\n - Check URL availibility before visiting\n - Fix proxy URL value\n - Request counter fix\n - Minor fixes in examples\n\n# 1.1.0 - 2018.08.13\n\n - Appengine integration takes context.Context instead of http.Request (API change)\n - Added \"Accept\" http header by default to every request\n - Support slices of pointers in unmarshal\n - Fixed a race condition in queues\n - ForEachWithBreak method added to HTMLElement\n - Added a local file example\n - Support gzip decompression of response bodies\n - Don't share waitgroup when cloning a collector\n - Fixed instagram example\n\n\n# 1.0.0 - 2018.05.13\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/CONTRIBUTING.md",
    "content": "# Contribute\n\n## Introduction\n\nFirst, thank you for considering contributing to colly! It's people like you that make the open source community such a great community! 😊\n\nWe welcome any type of contribution, not only code. You can help with \n- **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open)\n- **Marketing**: writing blog posts, howto's, printing stickers, ...\n- **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ...\n- **Code**: take a look at the [open issues](https://github.com/gocolly/colly/issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. It helps us triage them.\n- **Money**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/colly).\n\n## Your First Contribution\n\nWorking on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).\n\n## Submitting code\n\nAny code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. The pull request should also contain tests.\n\n## Code review process\n\nThe bigger the pull request, the longer it will take to review and merge. Try to break down large pull requests in smaller chunks that are easier to review and merge.\nIt is also always helpful to have some context for your pull request. What was the purpose? Why does it matter to you?\n\n## Financial contributions\n\nWe also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/colly).\nAnyone can file an expense. If the expense makes sense for the development of the community, it will be \"merged\" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed.\n\n## Questions\n\nIf you have any questions, create an [issue](https://github.com/gocolly/colly/issues/new) (protip: do a quick search first to see if someone else didn't ask the same question before!).\nYou can also reach us at hello@colly.opencollective.com.\n\n## Credits\n\n### Contributors\n\nThank you to all the people who have already contributed to colly!\n<a href=\"graphs/contributors\"><img src=\"https://opencollective.com/colly/contributors.svg?width=890\" /></a>\n\n\n### Backers\n\nThank you to all our backers! [[Become a backer](https://opencollective.com/colly#backer)]\n\n<a href=\"https://opencollective.com/colly#backers\" target=\"_blank\"><img src=\"https://opencollective.com/colly/backers.svg?width=890\"></a>\n\n\n### Sponsors\n\nThank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/colly#sponsor))\n\n<a href=\"https://opencollective.com/colly/sponsor/0/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/1/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/2/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/3/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/4/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/5/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/6/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/7/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/8/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/9/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/9/avatar.svg\"></a>\n\n<!-- This `CONTRIBUTING.md` is based on @nayafia's template https://github.com/nayafia/contributing-template -->\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/LICENSE.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/gocolly/colly/v2/README.md",
    "content": "# Colly\n\nLightning Fast and Elegant Scraping Framework for Gophers\n\nColly provides a clean interface to write any kind of crawler/scraper/spider.\n\nWith Colly you can easily extract structured data from websites, which can be used for a wide range of applications, like data mining, data processing or archiving.\n\n[![GoDoc](https://godoc.org/github.com/gocolly/colly?status.svg)](https://pkg.go.dev/github.com/gocolly/colly/v2)\n[![Backers on Open Collective](https://opencollective.com/colly/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/colly/sponsors/badge.svg)](#sponsors) [![build status](https://img.shields.io/travis/gocolly/colly/master.svg?style=flat-square)](https://travis-ci.org/gocolly/colly)\n[![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=flat-square)](http://goreportcard.com/report/gocolly/colly)\n[![view examples](https://img.shields.io/badge/learn%20by-examples-0077b3.svg?style=flat-square)](https://github.com/gocolly/colly/tree/master/_examples)\n[![Code Coverage](https://img.shields.io/codecov/c/github/gocolly/colly/master.svg)](https://codecov.io/github/gocolly/colly?branch=master)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fgocolly%2Fcolly.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fgocolly%2Fcolly?ref=badge_shield)\n[![Twitter URL](https://img.shields.io/badge/twitter-follow-green.svg)](https://twitter.com/gocolly)\n\n## Features\n\n-   Clean API\n-   Fast (>1k request/sec on a single core)\n-   Manages request delays and maximum concurrency per domain\n-   Automatic cookie and session handling\n-   Sync/async/parallel scraping\n-   Caching\n-   Automatic encoding of non-unicode responses\n-   Robots.txt support\n-   Distributed scraping\n-   Configuration via environment variables\n-   Extensions\n\n## Example\n\n```go\nfunc main() {\n\tc := colly.NewCollector()\n\n\t// Find and visit all links\n\tc.OnHTML(\"a[href]\", func(e *colly.HTMLElement) {\n\t\te.Request.Visit(e.Attr(\"href\"))\n\t})\n\n\tc.OnRequest(func(r *colly.Request) {\n\t\tfmt.Println(\"Visiting\", r.URL)\n\t})\n\n\tc.Visit(\"http://go-colly.org/\")\n}\n```\n\nSee [examples folder](https://github.com/gocolly/colly/tree/master/_examples) for more detailed examples.\n\n## Installation\n\nAdd colly to your `go.mod` file:\n\n```\nmodule github.com/x/y\n\ngo 1.14\n\nrequire (\n        github.com/gocolly/colly/v2 latest\n)\n```\n\n## Bugs\n\nBugs or suggestions? Visit the [issue tracker](https://github.com/gocolly/colly/issues) or join `#colly` on freenode\n\n## Other Projects Using Colly\n\nBelow is a list of public, open source projects that use Colly:\n\n-   [greenpeace/check-my-pages](https://github.com/greenpeace/check-my-pages) Scraping script to test the Spanish Greenpeace web archive.\n-   [altsab/gowap](https://github.com/altsab/gowap) Wappalyzer implementation in Go.\n-   [jesuiscamille/goquotes](https://github.com/jesuiscamille/goquotes) A quotes scrapper, making your day a little better!\n-   [jivesearch/jivesearch](https://github.com/jivesearch/jivesearch) A search engine that doesn't track you.\n-   [Leagify/colly-draft-prospects](https://github.com/Leagify/colly-draft-prospects) A scraper for future NFL Draft prospects.\n-   [lucasepe/go-ps4](https://github.com/lucasepe/go-ps4) Search playstation store for your favorite PS4 games using the command line.\n-   [yringler/inside-chassidus-scraper](https://github.com/yringler/inside-chassidus-scraper) Scrapes Rabbi Paltiel's web site for lesson metadata.\n-   [gamedb/gamedb](https://github.com/gamedb/gamedb) A database of Steam games.\n-   [lawzava/scrape](https://github.com/lawzava/scrape) CLI for email scraping from any website.\n-   [eureka101v/WeiboSpiderGo](https://github.com/eureka101v/WeiboSpiderGo) A sina weibo(chinese twitter) scrapper\n-   [Go-phie/gophie](https://github.com/Go-phie/gophie) Search, Download and Stream movies from your terminal\n-   [imthaghost/goclone](https://github.com/imthaghost/goclone) Clone websites to your computer within seconds.\n\nIf you are using Colly in a project please send a pull request to add it to the list.\n\n## Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute]](CONTRIBUTING.md).\n<a href=\"https://github.com/gocolly/colly/graphs/contributors\"><img src=\"https://opencollective.com/colly/contributors.svg?width=890\" /></a>\n\n## Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/colly#backer)]\n\n<a href=\"https://opencollective.com/colly#backers\" target=\"_blank\"><img src=\"https://opencollective.com/colly/backers.svg?width=890\"></a>\n\n## Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/colly#sponsor)]\n\n<a href=\"https://opencollective.com/colly/sponsor/0/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/0/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/1/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/1/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/2/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/2/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/3/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/3/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/4/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/4/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/5/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/5/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/6/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/6/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/7/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/7/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/8/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/8/avatar.svg\"></a>\n<a href=\"https://opencollective.com/colly/sponsor/9/website\" target=\"_blank\"><img src=\"https://opencollective.com/colly/sponsor/9/avatar.svg\"></a>\n\n## License\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fgocolly%2Fcolly.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fgocolly%2Fcolly?ref=badge_large)\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/VERSION",
    "content": "2.1.0\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/colly.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\n// Package colly implements a HTTP scraping framework\npackage colly\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash/fnv\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/http/cookiejar\"\n\t\"net/url\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"github.com/PuerkitoBio/goquery\"\n\t\"github.com/antchfx/htmlquery\"\n\t\"github.com/antchfx/xmlquery\"\n\t\"github.com/gocolly/colly/v2/debug\"\n\t\"github.com/gocolly/colly/v2/storage\"\n\t\"github.com/kennygrant/sanitize\"\n\t\"github.com/temoto/robotstxt\"\n\t\"google.golang.org/appengine/urlfetch\"\n)\n\n// A CollectorOption sets an option on a Collector.\ntype CollectorOption func(*Collector)\n\n// Collector provides the scraper instance for a scraping job\ntype Collector struct {\n\t// UserAgent is the User-Agent string used by HTTP requests\n\tUserAgent string\n\t// MaxDepth limits the recursion depth of visited URLs.\n\t// Set it to 0 for infinite recursion (default).\n\tMaxDepth int\n\t// AllowedDomains is a domain whitelist.\n\t// Leave it blank to allow any domains to be visited\n\tAllowedDomains []string\n\t// DisallowedDomains is a domain blacklist.\n\tDisallowedDomains []string\n\t// DisallowedURLFilters is a list of regular expressions which restricts\n\t// visiting URLs. If any of the rules matches to a URL the\n\t// request will be stopped. DisallowedURLFilters will\n\t// be evaluated before URLFilters\n\t// Leave it blank to allow any URLs to be visited\n\tDisallowedURLFilters []*regexp.Regexp\n\t// URLFilters is a list of regular expressions which restricts\n\t// visiting URLs. If any of the rules matches to a URL the\n\t// request won't be stopped. DisallowedURLFilters will\n\t// be evaluated before URLFilters\n\n\t// Leave it blank to allow any URLs to be visited\n\tURLFilters []*regexp.Regexp\n\n\t// AllowURLRevisit allows multiple downloads of the same URL\n\tAllowURLRevisit bool\n\t// MaxBodySize is the limit of the retrieved response body in bytes.\n\t// 0 means unlimited.\n\t// The default value for MaxBodySize is 10MB (10 * 1024 * 1024 bytes).\n\tMaxBodySize int\n\t// CacheDir specifies a location where GET requests are cached as files.\n\t// When it's not defined, caching is disabled.\n\tCacheDir string\n\t// IgnoreRobotsTxt allows the Collector to ignore any restrictions set by\n\t// the target host's robots.txt file.  See http://www.robotstxt.org/ for more\n\t// information.\n\tIgnoreRobotsTxt bool\n\t// Async turns on asynchronous network communication. Use Collector.Wait() to\n\t// be sure all requests have been finished.\n\tAsync bool\n\t// ParseHTTPErrorResponse allows parsing HTTP responses with non 2xx status codes.\n\t// By default, Colly parses only successful HTTP responses. Set ParseHTTPErrorResponse\n\t// to true to enable it.\n\tParseHTTPErrorResponse bool\n\t// ID is the unique identifier of a collector\n\tID uint32\n\t// DetectCharset can enable character encoding detection for non-utf8 response bodies\n\t// without explicit charset declaration. This feature uses https://github.com/saintfish/chardet\n\tDetectCharset bool\n\t// RedirectHandler allows control on how a redirect will be managed\n\t// use c.SetRedirectHandler to set this value\n\tredirectHandler func(req *http.Request, via []*http.Request) error\n\t// CheckHead performs a HEAD request before every GET to pre-validate the response\n\tCheckHead bool\n\t// TraceHTTP enables capturing and reporting request performance for crawler tuning.\n\t// When set to true, the Response.Trace will be filled in with an HTTPTrace object.\n\tTraceHTTP                bool\n\tstore                    storage.Storage\n\tdebugger                 debug.Debugger\n\trobotsMap                map[string]*robotstxt.RobotsData\n\thtmlCallbacks            []*htmlCallbackContainer\n\txmlCallbacks             []*xmlCallbackContainer\n\trequestCallbacks         []RequestCallback\n\tresponseCallbacks        []ResponseCallback\n\tresponseHeadersCallbacks []ResponseHeadersCallback\n\terrorCallbacks           []ErrorCallback\n\tscrapedCallbacks         []ScrapedCallback\n\trequestCount             uint32\n\tresponseCount            uint32\n\tbackend                  *httpBackend\n\twg                       *sync.WaitGroup\n\tlock                     *sync.RWMutex\n}\n\n// RequestCallback is a type alias for OnRequest callback functions\ntype RequestCallback func(*Request)\n\n// ResponseHeadersCallback is a type alias for OnResponseHeaders callback functions\ntype ResponseHeadersCallback func(*Response)\n\n// ResponseCallback is a type alias for OnResponse callback functions\ntype ResponseCallback func(*Response)\n\n// HTMLCallback is a type alias for OnHTML callback functions\ntype HTMLCallback func(*HTMLElement)\n\n// XMLCallback is a type alias for OnXML callback functions\ntype XMLCallback func(*XMLElement)\n\n// ErrorCallback is a type alias for OnError callback functions\ntype ErrorCallback func(*Response, error)\n\n// ScrapedCallback is a type alias for OnScraped callback functions\ntype ScrapedCallback func(*Response)\n\n// ProxyFunc is a type alias for proxy setter functions.\ntype ProxyFunc func(*http.Request) (*url.URL, error)\n\ntype htmlCallbackContainer struct {\n\tSelector string\n\tFunction HTMLCallback\n}\n\ntype xmlCallbackContainer struct {\n\tQuery    string\n\tFunction XMLCallback\n}\n\ntype cookieJarSerializer struct {\n\tstore storage.Storage\n\tlock  *sync.RWMutex\n}\n\nvar collectorCounter uint32\n\n// The key type is unexported to prevent collisions with context keys defined in\n// other packages.\ntype key int\n\n// ProxyURLKey is the context key for the request proxy address.\nconst ProxyURLKey key = iota\n\nvar (\n\t// ErrForbiddenDomain is the error thrown if visiting\n\t// a domain which is not allowed in AllowedDomains\n\tErrForbiddenDomain = errors.New(\"Forbidden domain\")\n\t// ErrMissingURL is the error type for missing URL errors\n\tErrMissingURL = errors.New(\"Missing URL\")\n\t// ErrMaxDepth is the error type for exceeding max depth\n\tErrMaxDepth = errors.New(\"Max depth limit reached\")\n\t// ErrForbiddenURL is the error thrown if visiting\n\t// a URL which is not allowed by URLFilters\n\tErrForbiddenURL = errors.New(\"ForbiddenURL\")\n\n\t// ErrNoURLFiltersMatch is the error thrown if visiting\n\t// a URL which is not allowed by URLFilters\n\tErrNoURLFiltersMatch = errors.New(\"No URLFilters match\")\n\t// ErrAlreadyVisited is the error type for already visited URLs\n\tErrAlreadyVisited = errors.New(\"URL already visited\")\n\t// ErrRobotsTxtBlocked is the error type for robots.txt errors\n\tErrRobotsTxtBlocked = errors.New(\"URL blocked by robots.txt\")\n\t// ErrNoCookieJar is the error type for missing cookie jar\n\tErrNoCookieJar = errors.New(\"Cookie jar is not available\")\n\t// ErrNoPattern is the error type for LimitRules without patterns\n\tErrNoPattern = errors.New(\"No pattern defined in LimitRule\")\n\t// ErrEmptyProxyURL is the error type for empty Proxy URL list\n\tErrEmptyProxyURL = errors.New(\"Proxy URL list is empty\")\n\t// ErrAbortedAfterHeaders is the error returned when OnResponseHeaders aborts the transfer.\n\tErrAbortedAfterHeaders = errors.New(\"Aborted after receiving response headers\")\n\t// ErrQueueFull is the error returned when the queue is full\n\tErrQueueFull = errors.New(\"Queue MaxSize reached\")\n)\n\nvar envMap = map[string]func(*Collector, string){\n\t\"ALLOWED_DOMAINS\": func(c *Collector, val string) {\n\t\tc.AllowedDomains = strings.Split(val, \",\")\n\t},\n\t\"CACHE_DIR\": func(c *Collector, val string) {\n\t\tc.CacheDir = val\n\t},\n\t\"DETECT_CHARSET\": func(c *Collector, val string) {\n\t\tc.DetectCharset = isYesString(val)\n\t},\n\t\"DISABLE_COOKIES\": func(c *Collector, _ string) {\n\t\tc.backend.Client.Jar = nil\n\t},\n\t\"DISALLOWED_DOMAINS\": func(c *Collector, val string) {\n\t\tc.DisallowedDomains = strings.Split(val, \",\")\n\t},\n\t\"IGNORE_ROBOTSTXT\": func(c *Collector, val string) {\n\t\tc.IgnoreRobotsTxt = isYesString(val)\n\t},\n\t\"FOLLOW_REDIRECTS\": func(c *Collector, val string) {\n\t\tif !isYesString(val) {\n\t\t\tc.redirectHandler = func(req *http.Request, via []*http.Request) error {\n\t\t\t\treturn http.ErrUseLastResponse\n\t\t\t}\n\t\t}\n\t},\n\t\"MAX_BODY_SIZE\": func(c *Collector, val string) {\n\t\tsize, err := strconv.Atoi(val)\n\t\tif err == nil {\n\t\t\tc.MaxBodySize = size\n\t\t}\n\t},\n\t\"MAX_DEPTH\": func(c *Collector, val string) {\n\t\tmaxDepth, err := strconv.Atoi(val)\n\t\tif err == nil {\n\t\t\tc.MaxDepth = maxDepth\n\t\t}\n\t},\n\t\"PARSE_HTTP_ERROR_RESPONSE\": func(c *Collector, val string) {\n\t\tc.ParseHTTPErrorResponse = isYesString(val)\n\t},\n\t\"TRACE_HTTP\": func(c *Collector, val string) {\n\t\tc.TraceHTTP = isYesString(val)\n\t},\n\t\"USER_AGENT\": func(c *Collector, val string) {\n\t\tc.UserAgent = val\n\t},\n}\n\n// NewCollector creates a new Collector instance with default configuration\nfunc NewCollector(options ...CollectorOption) *Collector {\n\tc := &Collector{}\n\tc.Init()\n\n\tfor _, f := range options {\n\t\tf(c)\n\t}\n\n\tc.parseSettingsFromEnv()\n\n\treturn c\n}\n\n// UserAgent sets the user agent used by the Collector.\nfunc UserAgent(ua string) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.UserAgent = ua\n\t}\n}\n\n// MaxDepth limits the recursion depth of visited URLs.\nfunc MaxDepth(depth int) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.MaxDepth = depth\n\t}\n}\n\n// AllowedDomains sets the domain whitelist used by the Collector.\nfunc AllowedDomains(domains ...string) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.AllowedDomains = domains\n\t}\n}\n\n// ParseHTTPErrorResponse allows parsing responses with HTTP errors\nfunc ParseHTTPErrorResponse() CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.ParseHTTPErrorResponse = true\n\t}\n}\n\n// DisallowedDomains sets the domain blacklist used by the Collector.\nfunc DisallowedDomains(domains ...string) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.DisallowedDomains = domains\n\t}\n}\n\n// DisallowedURLFilters sets the list of regular expressions which restricts\n// visiting URLs. If any of the rules matches to a URL the request will be stopped.\nfunc DisallowedURLFilters(filters ...*regexp.Regexp) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.DisallowedURLFilters = filters\n\t}\n}\n\n// URLFilters sets the list of regular expressions which restricts\n// visiting URLs. If any of the rules matches to a URL the request won't be stopped.\nfunc URLFilters(filters ...*regexp.Regexp) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.URLFilters = filters\n\t}\n}\n\n// AllowURLRevisit instructs the Collector to allow multiple downloads of the same URL\nfunc AllowURLRevisit() CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.AllowURLRevisit = true\n\t}\n}\n\n// MaxBodySize sets the limit of the retrieved response body in bytes.\nfunc MaxBodySize(sizeInBytes int) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.MaxBodySize = sizeInBytes\n\t}\n}\n\n// CacheDir specifies the location where GET requests are cached as files.\nfunc CacheDir(path string) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.CacheDir = path\n\t}\n}\n\n// IgnoreRobotsTxt instructs the Collector to ignore any restrictions\n// set by the target host's robots.txt file.\nfunc IgnoreRobotsTxt() CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.IgnoreRobotsTxt = true\n\t}\n}\n\n// TraceHTTP instructs the Collector to collect and report request trace data\n// on the Response.Trace.\nfunc TraceHTTP() CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.TraceHTTP = true\n\t}\n}\n\n// ID sets the unique identifier of the Collector.\nfunc ID(id uint32) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.ID = id\n\t}\n}\n\n// Async turns on asynchronous network requests.\nfunc Async(a ...bool) CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.Async = true\n\t}\n}\n\n// DetectCharset enables character encoding detection for non-utf8 response bodies\n// without explicit charset declaration. This feature uses https://github.com/saintfish/chardet\nfunc DetectCharset() CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.DetectCharset = true\n\t}\n}\n\n// Debugger sets the debugger used by the Collector.\nfunc Debugger(d debug.Debugger) CollectorOption {\n\treturn func(c *Collector) {\n\t\td.Init()\n\t\tc.debugger = d\n\t}\n}\n\n// CheckHead performs a HEAD request before every GET to pre-validate the response\nfunc CheckHead() CollectorOption {\n\treturn func(c *Collector) {\n\t\tc.CheckHead = true\n\t}\n}\n\n// Init initializes the Collector's private variables and sets default\n// configuration for the Collector\nfunc (c *Collector) Init() {\n\tc.UserAgent = \"colly - https://github.com/gocolly/colly/v2\"\n\tc.MaxDepth = 0\n\tc.store = &storage.InMemoryStorage{}\n\tc.store.Init()\n\tc.MaxBodySize = 10 * 1024 * 1024\n\tc.backend = &httpBackend{}\n\tjar, _ := cookiejar.New(nil)\n\tc.backend.Init(jar)\n\tc.backend.Client.CheckRedirect = c.checkRedirectFunc()\n\tc.wg = &sync.WaitGroup{}\n\tc.lock = &sync.RWMutex{}\n\tc.robotsMap = make(map[string]*robotstxt.RobotsData)\n\tc.IgnoreRobotsTxt = true\n\tc.ID = atomic.AddUint32(&collectorCounter, 1)\n\tc.TraceHTTP = false\n}\n\n// Appengine will replace the Collector's backend http.Client\n// With an Http.Client that is provided by appengine/urlfetch\n// This function should be used when the scraper is run on\n// Google App Engine. Example:\n//   func startScraper(w http.ResponseWriter, r *http.Request) {\n//     ctx := appengine.NewContext(r)\n//     c := colly.NewCollector()\n//     c.Appengine(ctx)\n//      ...\n//     c.Visit(\"https://google.ca\")\n//   }\nfunc (c *Collector) Appengine(ctx context.Context) {\n\tclient := urlfetch.Client(ctx)\n\tclient.Jar = c.backend.Client.Jar\n\tclient.CheckRedirect = c.backend.Client.CheckRedirect\n\tclient.Timeout = c.backend.Client.Timeout\n\n\tc.backend.Client = client\n}\n\n// Visit starts Collector's collecting job by creating a\n// request to the URL specified in parameter.\n// Visit also calls the previously provided callbacks\nfunc (c *Collector) Visit(URL string) error {\n\tif c.CheckHead {\n\t\tif check := c.scrape(URL, \"HEAD\", 1, nil, nil, nil, true); check != nil {\n\t\t\treturn check\n\t\t}\n\t}\n\treturn c.scrape(URL, \"GET\", 1, nil, nil, nil, true)\n}\n\n// HasVisited checks if the provided URL has been visited\nfunc (c *Collector) HasVisited(URL string) (bool, error) {\n\treturn c.checkHasVisited(URL, nil)\n}\n\n// HasPosted checks if the provided URL and requestData has been visited\n// This method is useful more likely to prevent re-visit same URL and POST body\nfunc (c *Collector) HasPosted(URL string, requestData map[string]string) (bool, error) {\n\treturn c.checkHasVisited(URL, requestData)\n}\n\n// Head starts a collector job by creating a HEAD request.\nfunc (c *Collector) Head(URL string) error {\n\treturn c.scrape(URL, \"HEAD\", 1, nil, nil, nil, false)\n}\n\n// Post starts a collector job by creating a POST request.\n// Post also calls the previously provided callbacks\nfunc (c *Collector) Post(URL string, requestData map[string]string) error {\n\treturn c.scrape(URL, \"POST\", 1, createFormReader(requestData), nil, nil, true)\n}\n\n// PostRaw starts a collector job by creating a POST request with raw binary data.\n// Post also calls the previously provided callbacks\nfunc (c *Collector) PostRaw(URL string, requestData []byte) error {\n\treturn c.scrape(URL, \"POST\", 1, bytes.NewReader(requestData), nil, nil, true)\n}\n\n// PostMultipart starts a collector job by creating a Multipart POST request\n// with raw binary data.  PostMultipart also calls the previously provided callbacks\nfunc (c *Collector) PostMultipart(URL string, requestData map[string][]byte) error {\n\tboundary := randomBoundary()\n\thdr := http.Header{}\n\thdr.Set(\"Content-Type\", \"multipart/form-data; boundary=\"+boundary)\n\thdr.Set(\"User-Agent\", c.UserAgent)\n\treturn c.scrape(URL, \"POST\", 1, createMultipartReader(boundary, requestData), nil, hdr, true)\n}\n\n// Request starts a collector job by creating a custom HTTP request\n// where method, context, headers and request data can be specified.\n// Set requestData, ctx, hdr parameters to nil if you don't want to use them.\n// Valid methods:\n//   - \"GET\"\n//   - \"HEAD\"\n//   - \"POST\"\n//   - \"PUT\"\n//   - \"DELETE\"\n//   - \"PATCH\"\n//   - \"OPTIONS\"\nfunc (c *Collector) Request(method, URL string, requestData io.Reader, ctx *Context, hdr http.Header) error {\n\treturn c.scrape(URL, method, 1, requestData, ctx, hdr, true)\n}\n\n// SetDebugger attaches a debugger to the collector\nfunc (c *Collector) SetDebugger(d debug.Debugger) {\n\td.Init()\n\tc.debugger = d\n}\n\n// UnmarshalRequest creates a Request from serialized data\nfunc (c *Collector) UnmarshalRequest(r []byte) (*Request, error) {\n\treq := &serializableRequest{}\n\terr := json.Unmarshal(r, req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tu, err := url.Parse(req.URL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tctx := NewContext()\n\tfor k, v := range req.Ctx {\n\t\tctx.Put(k, v)\n\t}\n\n\treturn &Request{\n\t\tMethod:    req.Method,\n\t\tURL:       u,\n\t\tDepth:     req.Depth,\n\t\tBody:      bytes.NewReader(req.Body),\n\t\tCtx:       ctx,\n\t\tID:        atomic.AddUint32(&c.requestCount, 1),\n\t\tHeaders:   &req.Headers,\n\t\tcollector: c,\n\t}, nil\n}\n\nfunc (c *Collector) scrape(u, method string, depth int, requestData io.Reader, ctx *Context, hdr http.Header, checkRevisit bool) error {\n\tparsedURL, err := url.Parse(u)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := c.requestCheck(u, parsedURL, method, requestData, depth, checkRevisit); err != nil {\n\t\treturn err\n\t}\n\n\tif hdr == nil {\n\t\thdr = http.Header{\"User-Agent\": []string{c.UserAgent}}\n\t}\n\trc, ok := requestData.(io.ReadCloser)\n\tif !ok && requestData != nil {\n\t\trc = ioutil.NopCloser(requestData)\n\t}\n\t// The Go HTTP API ignores \"Host\" in the headers, preferring the client\n\t// to use the Host field on Request.\n\thost := parsedURL.Host\n\tif hostHeader := hdr.Get(\"Host\"); hostHeader != \"\" {\n\t\thost = hostHeader\n\t}\n\treq := &http.Request{\n\t\tMethod:     method,\n\t\tURL:        parsedURL,\n\t\tProto:      \"HTTP/1.1\",\n\t\tProtoMajor: 1,\n\t\tProtoMinor: 1,\n\t\tHeader:     hdr,\n\t\tBody:       rc,\n\t\tHost:       host,\n\t}\n\tsetRequestBody(req, requestData)\n\tu = parsedURL.String()\n\tc.wg.Add(1)\n\tif c.Async {\n\t\tgo c.fetch(u, method, depth, requestData, ctx, hdr, req)\n\t\treturn nil\n\t}\n\treturn c.fetch(u, method, depth, requestData, ctx, hdr, req)\n}\n\nfunc setRequestBody(req *http.Request, body io.Reader) {\n\tif body != nil {\n\t\tswitch v := body.(type) {\n\t\tcase *bytes.Buffer:\n\t\t\treq.ContentLength = int64(v.Len())\n\t\t\tbuf := v.Bytes()\n\t\t\treq.GetBody = func() (io.ReadCloser, error) {\n\t\t\t\tr := bytes.NewReader(buf)\n\t\t\t\treturn ioutil.NopCloser(r), nil\n\t\t\t}\n\t\tcase *bytes.Reader:\n\t\t\treq.ContentLength = int64(v.Len())\n\t\t\tsnapshot := *v\n\t\t\treq.GetBody = func() (io.ReadCloser, error) {\n\t\t\t\tr := snapshot\n\t\t\t\treturn ioutil.NopCloser(&r), nil\n\t\t\t}\n\t\tcase *strings.Reader:\n\t\t\treq.ContentLength = int64(v.Len())\n\t\t\tsnapshot := *v\n\t\t\treq.GetBody = func() (io.ReadCloser, error) {\n\t\t\t\tr := snapshot\n\t\t\t\treturn ioutil.NopCloser(&r), nil\n\t\t\t}\n\t\t}\n\t\tif req.GetBody != nil && req.ContentLength == 0 {\n\t\t\treq.Body = http.NoBody\n\t\t\treq.GetBody = func() (io.ReadCloser, error) { return http.NoBody, nil }\n\t\t}\n\t}\n}\n\nfunc (c *Collector) fetch(u, method string, depth int, requestData io.Reader, ctx *Context, hdr http.Header, req *http.Request) error {\n\tdefer c.wg.Done()\n\tif ctx == nil {\n\t\tctx = NewContext()\n\t}\n\trequest := &Request{\n\t\tURL:       req.URL,\n\t\tHeaders:   &req.Header,\n\t\tCtx:       ctx,\n\t\tDepth:     depth,\n\t\tMethod:    method,\n\t\tBody:      requestData,\n\t\tcollector: c,\n\t\tID:        atomic.AddUint32(&c.requestCount, 1),\n\t}\n\n\tc.handleOnRequest(request)\n\n\tif request.abort {\n\t\treturn nil\n\t}\n\n\tif method == \"POST\" && req.Header.Get(\"Content-Type\") == \"\" {\n\t\treq.Header.Add(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\t}\n\n\tif req.Header.Get(\"Accept\") == \"\" {\n\t\treq.Header.Set(\"Accept\", \"*/*\")\n\t}\n\n\tvar hTrace *HTTPTrace\n\tif c.TraceHTTP {\n\t\thTrace = &HTTPTrace{}\n\t\treq = hTrace.WithTrace(req)\n\t}\n\tcheckHeadersFunc := func(statusCode int, headers http.Header) bool {\n\t\tc.handleOnResponseHeaders(&Response{Ctx: ctx, Request: request, StatusCode: statusCode, Headers: &headers})\n\t\treturn !request.abort\n\t}\n\n\torigURL := req.URL\n\tresponse, err := c.backend.Cache(req, c.MaxBodySize, checkHeadersFunc, c.CacheDir)\n\tif proxyURL, ok := req.Context().Value(ProxyURLKey).(string); ok {\n\t\trequest.ProxyURL = proxyURL\n\t}\n\tif err := c.handleOnError(response, err, request, ctx); err != nil {\n\t\treturn err\n\t}\n\tif req.URL != origURL {\n\t\trequest.URL = req.URL\n\t\trequest.Headers = &req.Header\n\t}\n\tatomic.AddUint32(&c.responseCount, 1)\n\tresponse.Ctx = ctx\n\tresponse.Request = request\n\tresponse.Trace = hTrace\n\n\terr = response.fixCharset(c.DetectCharset, request.ResponseCharacterEncoding)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.handleOnResponse(response)\n\n\terr = c.handleOnHTML(response)\n\tif err != nil {\n\t\tc.handleOnError(response, err, request, ctx)\n\t}\n\n\terr = c.handleOnXML(response)\n\tif err != nil {\n\t\tc.handleOnError(response, err, request, ctx)\n\t}\n\n\tc.handleOnScraped(response)\n\n\treturn err\n}\n\nfunc (c *Collector) requestCheck(u string, parsedURL *url.URL, method string, requestData io.Reader, depth int, checkRevisit bool) error {\n\tif u == \"\" {\n\t\treturn ErrMissingURL\n\t}\n\tif c.MaxDepth > 0 && c.MaxDepth < depth {\n\t\treturn ErrMaxDepth\n\t}\n\tif len(c.DisallowedURLFilters) > 0 {\n\t\tif isMatchingFilter(c.DisallowedURLFilters, []byte(u)) {\n\t\t\treturn ErrForbiddenURL\n\t\t}\n\t}\n\tif len(c.URLFilters) > 0 {\n\t\tif !isMatchingFilter(c.URLFilters, []byte(u)) {\n\t\t\treturn ErrNoURLFiltersMatch\n\t\t}\n\t}\n\tif !c.isDomainAllowed(parsedURL.Hostname()) {\n\t\treturn ErrForbiddenDomain\n\t}\n\tif method != \"HEAD\" && !c.IgnoreRobotsTxt {\n\t\tif err := c.checkRobots(parsedURL); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif checkRevisit && !c.AllowURLRevisit {\n\t\th := fnv.New64a()\n\t\th.Write([]byte(u))\n\n\t\tvar uHash uint64\n\t\tif method == \"GET\" {\n\t\t\tuHash = h.Sum64()\n\t\t} else if requestData != nil {\n\t\t\th.Write(streamToByte(requestData))\n\t\t\tuHash = h.Sum64()\n\t\t} else {\n\t\t\treturn nil\n\t\t}\n\n\t\tvisited, err := c.store.IsVisited(uHash)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif visited {\n\t\t\treturn ErrAlreadyVisited\n\t\t}\n\t\treturn c.store.Visited(uHash)\n\t}\n\treturn nil\n}\n\nfunc (c *Collector) isDomainAllowed(domain string) bool {\n\tfor _, d2 := range c.DisallowedDomains {\n\t\tif d2 == domain {\n\t\t\treturn false\n\t\t}\n\t}\n\tif c.AllowedDomains == nil || len(c.AllowedDomains) == 0 {\n\t\treturn true\n\t}\n\tfor _, d2 := range c.AllowedDomains {\n\t\tif d2 == domain {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (c *Collector) checkRobots(u *url.URL) error {\n\tc.lock.RLock()\n\trobot, ok := c.robotsMap[u.Host]\n\tc.lock.RUnlock()\n\n\tif !ok {\n\t\t// no robots file cached\n\t\tresp, err := c.backend.Client.Get(u.Scheme + \"://\" + u.Host + \"/robots.txt\")\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\trobot, err = robotstxt.FromResponse(resp)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tc.lock.Lock()\n\t\tc.robotsMap[u.Host] = robot\n\t\tc.lock.Unlock()\n\t}\n\n\tuaGroup := robot.FindGroup(c.UserAgent)\n\tif uaGroup == nil {\n\t\treturn nil\n\t}\n\n\teu := u.EscapedPath()\n\tif u.RawQuery != \"\" {\n\t\teu += \"?\" + u.Query().Encode()\n\t}\n\tif !uaGroup.Test(eu) {\n\t\treturn ErrRobotsTxtBlocked\n\t}\n\treturn nil\n}\n\n// String is the text representation of the collector.\n// It contains useful debug information about the collector's internals\nfunc (c *Collector) String() string {\n\treturn fmt.Sprintf(\n\t\t\"Requests made: %d (%d responses) | Callbacks: OnRequest: %d, OnHTML: %d, OnResponse: %d, OnError: %d\",\n\t\tc.requestCount,\n\t\tc.responseCount,\n\t\tlen(c.requestCallbacks),\n\t\tlen(c.htmlCallbacks),\n\t\tlen(c.responseCallbacks),\n\t\tlen(c.errorCallbacks),\n\t)\n}\n\n// Wait returns when the collector jobs are finished\nfunc (c *Collector) Wait() {\n\tc.wg.Wait()\n}\n\n// OnRequest registers a function. Function will be executed on every\n// request made by the Collector\nfunc (c *Collector) OnRequest(f RequestCallback) {\n\tc.lock.Lock()\n\tif c.requestCallbacks == nil {\n\t\tc.requestCallbacks = make([]RequestCallback, 0, 4)\n\t}\n\tc.requestCallbacks = append(c.requestCallbacks, f)\n\tc.lock.Unlock()\n}\n\n// OnResponseHeaders registers a function. Function will be executed on every response\n// when headers and status are already received, but body is not yet read.\n//\n// Like in OnRequest, you can call Request.Abort to abort the transfer. This might be\n// useful if, for example, you're following all hyperlinks, but want to avoid\n// downloading files.\n//\n// Be aware that using this will prevent HTTP/1.1 connection reuse, as\n// the only way to abort a download is to immediately close the connection.\n// HTTP/2 doesn't suffer from this problem, as it's possible to close\n// specific stream inside the connection.\nfunc (c *Collector) OnResponseHeaders(f ResponseHeadersCallback) {\n\tc.lock.Lock()\n\tc.responseHeadersCallbacks = append(c.responseHeadersCallbacks, f)\n\tc.lock.Unlock()\n}\n\n// OnResponse registers a function. Function will be executed on every response\nfunc (c *Collector) OnResponse(f ResponseCallback) {\n\tc.lock.Lock()\n\tif c.responseCallbacks == nil {\n\t\tc.responseCallbacks = make([]ResponseCallback, 0, 4)\n\t}\n\tc.responseCallbacks = append(c.responseCallbacks, f)\n\tc.lock.Unlock()\n}\n\n// OnHTML registers a function. Function will be executed on every HTML\n// element matched by the GoQuery Selector parameter.\n// GoQuery Selector is a selector used by https://github.com/PuerkitoBio/goquery\nfunc (c *Collector) OnHTML(goquerySelector string, f HTMLCallback) {\n\tc.lock.Lock()\n\tif c.htmlCallbacks == nil {\n\t\tc.htmlCallbacks = make([]*htmlCallbackContainer, 0, 4)\n\t}\n\tc.htmlCallbacks = append(c.htmlCallbacks, &htmlCallbackContainer{\n\t\tSelector: goquerySelector,\n\t\tFunction: f,\n\t})\n\tc.lock.Unlock()\n}\n\n// OnXML registers a function. Function will be executed on every XML\n// element matched by the xpath Query parameter.\n// xpath Query is used by https://github.com/antchfx/xmlquery\nfunc (c *Collector) OnXML(xpathQuery string, f XMLCallback) {\n\tc.lock.Lock()\n\tif c.xmlCallbacks == nil {\n\t\tc.xmlCallbacks = make([]*xmlCallbackContainer, 0, 4)\n\t}\n\tc.xmlCallbacks = append(c.xmlCallbacks, &xmlCallbackContainer{\n\t\tQuery:    xpathQuery,\n\t\tFunction: f,\n\t})\n\tc.lock.Unlock()\n}\n\n// OnHTMLDetach deregister a function. Function will not be execute after detached\nfunc (c *Collector) OnHTMLDetach(goquerySelector string) {\n\tc.lock.Lock()\n\tdeleteIdx := -1\n\tfor i, cc := range c.htmlCallbacks {\n\t\tif cc.Selector == goquerySelector {\n\t\t\tdeleteIdx = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif deleteIdx != -1 {\n\t\tc.htmlCallbacks = append(c.htmlCallbacks[:deleteIdx], c.htmlCallbacks[deleteIdx+1:]...)\n\t}\n\tc.lock.Unlock()\n}\n\n// OnXMLDetach deregister a function. Function will not be execute after detached\nfunc (c *Collector) OnXMLDetach(xpathQuery string) {\n\tc.lock.Lock()\n\tdeleteIdx := -1\n\tfor i, cc := range c.xmlCallbacks {\n\t\tif cc.Query == xpathQuery {\n\t\t\tdeleteIdx = i\n\t\t\tbreak\n\t\t}\n\t}\n\tif deleteIdx != -1 {\n\t\tc.xmlCallbacks = append(c.xmlCallbacks[:deleteIdx], c.xmlCallbacks[deleteIdx+1:]...)\n\t}\n\tc.lock.Unlock()\n}\n\n// OnError registers a function. Function will be executed if an error\n// occurs during the HTTP request.\nfunc (c *Collector) OnError(f ErrorCallback) {\n\tc.lock.Lock()\n\tif c.errorCallbacks == nil {\n\t\tc.errorCallbacks = make([]ErrorCallback, 0, 4)\n\t}\n\tc.errorCallbacks = append(c.errorCallbacks, f)\n\tc.lock.Unlock()\n}\n\n// OnScraped registers a function. Function will be executed after\n// OnHTML, as a final part of the scraping.\nfunc (c *Collector) OnScraped(f ScrapedCallback) {\n\tc.lock.Lock()\n\tif c.scrapedCallbacks == nil {\n\t\tc.scrapedCallbacks = make([]ScrapedCallback, 0, 4)\n\t}\n\tc.scrapedCallbacks = append(c.scrapedCallbacks, f)\n\tc.lock.Unlock()\n}\n\n// SetClient will override the previously set http.Client\nfunc (c *Collector) SetClient(client *http.Client) {\n\tc.backend.Client = client\n}\n\n// WithTransport allows you to set a custom http.RoundTripper (transport)\nfunc (c *Collector) WithTransport(transport http.RoundTripper) {\n\tc.backend.Client.Transport = transport\n}\n\n// DisableCookies turns off cookie handling\nfunc (c *Collector) DisableCookies() {\n\tc.backend.Client.Jar = nil\n}\n\n// SetCookieJar overrides the previously set cookie jar\nfunc (c *Collector) SetCookieJar(j http.CookieJar) {\n\tc.backend.Client.Jar = j\n}\n\n// SetRequestTimeout overrides the default timeout (10 seconds) for this collector\nfunc (c *Collector) SetRequestTimeout(timeout time.Duration) {\n\tc.backend.Client.Timeout = timeout\n}\n\n// SetStorage overrides the default in-memory storage.\n// Storage stores scraping related data like cookies and visited urls\nfunc (c *Collector) SetStorage(s storage.Storage) error {\n\tif err := s.Init(); err != nil {\n\t\treturn err\n\t}\n\tc.store = s\n\tc.backend.Client.Jar = createJar(s)\n\treturn nil\n}\n\n// SetProxy sets a proxy for the collector. This method overrides the previously\n// used http.Transport if the type of the transport is not http.RoundTripper.\n// The proxy type is determined by the URL scheme. \"http\"\n// and \"socks5\" are supported. If the scheme is empty,\n// \"http\" is assumed.\nfunc (c *Collector) SetProxy(proxyURL string) error {\n\tproxyParsed, err := url.Parse(proxyURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.SetProxyFunc(http.ProxyURL(proxyParsed))\n\n\treturn nil\n}\n\n// SetProxyFunc sets a custom proxy setter/switcher function.\n// See built-in ProxyFuncs for more details.\n// This method overrides the previously used http.Transport\n// if the type of the transport is not http.RoundTripper.\n// The proxy type is determined by the URL scheme. \"http\"\n// and \"socks5\" are supported. If the scheme is empty,\n// \"http\" is assumed.\nfunc (c *Collector) SetProxyFunc(p ProxyFunc) {\n\tt, ok := c.backend.Client.Transport.(*http.Transport)\n\tif c.backend.Client.Transport != nil && ok {\n\t\tt.Proxy = p\n\t} else {\n\t\tc.backend.Client.Transport = &http.Transport{\n\t\t\tProxy: p,\n\t\t}\n\t}\n}\n\nfunc createEvent(eventType string, requestID, collectorID uint32, kvargs map[string]string) *debug.Event {\n\treturn &debug.Event{\n\t\tCollectorID: collectorID,\n\t\tRequestID:   requestID,\n\t\tType:        eventType,\n\t\tValues:      kvargs,\n\t}\n}\n\nfunc (c *Collector) handleOnRequest(r *Request) {\n\tif c.debugger != nil {\n\t\tc.debugger.Event(createEvent(\"request\", r.ID, c.ID, map[string]string{\n\t\t\t\"url\": r.URL.String(),\n\t\t}))\n\t}\n\tfor _, f := range c.requestCallbacks {\n\t\tf(r)\n\t}\n}\n\nfunc (c *Collector) handleOnResponse(r *Response) {\n\tif c.debugger != nil {\n\t\tc.debugger.Event(createEvent(\"response\", r.Request.ID, c.ID, map[string]string{\n\t\t\t\"url\":    r.Request.URL.String(),\n\t\t\t\"status\": http.StatusText(r.StatusCode),\n\t\t}))\n\t}\n\tfor _, f := range c.responseCallbacks {\n\t\tf(r)\n\t}\n}\n\nfunc (c *Collector) handleOnResponseHeaders(r *Response) {\n\tif c.debugger != nil {\n\t\tc.debugger.Event(createEvent(\"responseHeaders\", r.Request.ID, c.ID, map[string]string{\n\t\t\t\"url\":    r.Request.URL.String(),\n\t\t\t\"status\": http.StatusText(r.StatusCode),\n\t\t}))\n\t}\n\tfor _, f := range c.responseHeadersCallbacks {\n\t\tf(r)\n\t}\n}\n\nfunc (c *Collector) handleOnHTML(resp *Response) error {\n\tif len(c.htmlCallbacks) == 0 || !strings.Contains(strings.ToLower(resp.Headers.Get(\"Content-Type\")), \"html\") {\n\t\treturn nil\n\t}\n\tdoc, err := goquery.NewDocumentFromReader(bytes.NewBuffer(resp.Body))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif href, found := doc.Find(\"base[href]\").Attr(\"href\"); found {\n\t\tresp.Request.baseURL, _ = resp.Request.URL.Parse(href)\n\t}\n\tfor _, cc := range c.htmlCallbacks {\n\t\ti := 0\n\t\tdoc.Find(cc.Selector).Each(func(_ int, s *goquery.Selection) {\n\t\t\tfor _, n := range s.Nodes {\n\t\t\t\te := NewHTMLElementFromSelectionNode(resp, s, n, i)\n\t\t\t\ti++\n\t\t\t\tif c.debugger != nil {\n\t\t\t\t\tc.debugger.Event(createEvent(\"html\", resp.Request.ID, c.ID, map[string]string{\n\t\t\t\t\t\t\"selector\": cc.Selector,\n\t\t\t\t\t\t\"url\":      resp.Request.URL.String(),\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t\tcc.Function(e)\n\t\t\t}\n\t\t})\n\t}\n\treturn nil\n}\n\nfunc (c *Collector) handleOnXML(resp *Response) error {\n\tif len(c.xmlCallbacks) == 0 {\n\t\treturn nil\n\t}\n\tcontentType := strings.ToLower(resp.Headers.Get(\"Content-Type\"))\n\tisXMLFile := strings.HasSuffix(strings.ToLower(resp.Request.URL.Path), \".xml\") || strings.HasSuffix(strings.ToLower(resp.Request.URL.Path), \".xml.gz\")\n\tif !strings.Contains(contentType, \"html\") && (!strings.Contains(contentType, \"xml\") && !isXMLFile) {\n\t\treturn nil\n\t}\n\n\tif strings.Contains(contentType, \"html\") {\n\t\tdoc, err := htmlquery.Parse(bytes.NewBuffer(resp.Body))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif e := htmlquery.FindOne(doc, \"//base\"); e != nil {\n\t\t\tfor _, a := range e.Attr {\n\t\t\t\tif a.Key == \"href\" {\n\t\t\t\t\tresp.Request.baseURL, _ = resp.Request.URL.Parse(a.Val)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor _, cc := range c.xmlCallbacks {\n\t\t\tfor _, n := range htmlquery.Find(doc, cc.Query) {\n\t\t\t\te := NewXMLElementFromHTMLNode(resp, n)\n\t\t\t\tif c.debugger != nil {\n\t\t\t\t\tc.debugger.Event(createEvent(\"xml\", resp.Request.ID, c.ID, map[string]string{\n\t\t\t\t\t\t\"selector\": cc.Query,\n\t\t\t\t\t\t\"url\":      resp.Request.URL.String(),\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t\tcc.Function(e)\n\t\t\t}\n\t\t}\n\t} else if strings.Contains(contentType, \"xml\") || isXMLFile {\n\t\tdoc, err := xmlquery.Parse(bytes.NewBuffer(resp.Body))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfor _, cc := range c.xmlCallbacks {\n\t\t\txmlquery.FindEach(doc, cc.Query, func(i int, n *xmlquery.Node) {\n\t\t\t\te := NewXMLElementFromXMLNode(resp, n)\n\t\t\t\tif c.debugger != nil {\n\t\t\t\t\tc.debugger.Event(createEvent(\"xml\", resp.Request.ID, c.ID, map[string]string{\n\t\t\t\t\t\t\"selector\": cc.Query,\n\t\t\t\t\t\t\"url\":      resp.Request.URL.String(),\n\t\t\t\t\t}))\n\t\t\t\t}\n\t\t\t\tcc.Function(e)\n\t\t\t})\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (c *Collector) handleOnError(response *Response, err error, request *Request, ctx *Context) error {\n\tif err == nil && (c.ParseHTTPErrorResponse || response.StatusCode < 203) {\n\t\treturn nil\n\t}\n\tif err == nil && response.StatusCode >= 203 {\n\t\terr = errors.New(http.StatusText(response.StatusCode))\n\t}\n\tif response == nil {\n\t\tresponse = &Response{\n\t\t\tRequest: request,\n\t\t\tCtx:     ctx,\n\t\t}\n\t}\n\tif c.debugger != nil {\n\t\tc.debugger.Event(createEvent(\"error\", request.ID, c.ID, map[string]string{\n\t\t\t\"url\":    request.URL.String(),\n\t\t\t\"status\": http.StatusText(response.StatusCode),\n\t\t}))\n\t}\n\tif response.Request == nil {\n\t\tresponse.Request = request\n\t}\n\tif response.Ctx == nil {\n\t\tresponse.Ctx = request.Ctx\n\t}\n\tfor _, f := range c.errorCallbacks {\n\t\tf(response, err)\n\t}\n\treturn err\n}\n\nfunc (c *Collector) handleOnScraped(r *Response) {\n\tif c.debugger != nil {\n\t\tc.debugger.Event(createEvent(\"scraped\", r.Request.ID, c.ID, map[string]string{\n\t\t\t\"url\": r.Request.URL.String(),\n\t\t}))\n\t}\n\tfor _, f := range c.scrapedCallbacks {\n\t\tf(r)\n\t}\n}\n\n// Limit adds a new LimitRule to the collector\nfunc (c *Collector) Limit(rule *LimitRule) error {\n\treturn c.backend.Limit(rule)\n}\n\n// Limits adds new LimitRules to the collector\nfunc (c *Collector) Limits(rules []*LimitRule) error {\n\treturn c.backend.Limits(rules)\n}\n\n// SetRedirectHandler instructs the Collector to allow multiple downloads of the same URL\nfunc (c *Collector) SetRedirectHandler(f func(req *http.Request, via []*http.Request) error) {\n\tc.redirectHandler = f\n\tc.backend.Client.CheckRedirect = c.checkRedirectFunc()\n}\n\n// SetCookies handles the receipt of the cookies in a reply for the given URL\nfunc (c *Collector) SetCookies(URL string, cookies []*http.Cookie) error {\n\tif c.backend.Client.Jar == nil {\n\t\treturn ErrNoCookieJar\n\t}\n\tu, err := url.Parse(URL)\n\tif err != nil {\n\t\treturn err\n\t}\n\tc.backend.Client.Jar.SetCookies(u, cookies)\n\treturn nil\n}\n\n// Cookies returns the cookies to send in a request for the given URL.\nfunc (c *Collector) Cookies(URL string) []*http.Cookie {\n\tif c.backend.Client.Jar == nil {\n\t\treturn nil\n\t}\n\tu, err := url.Parse(URL)\n\tif err != nil {\n\t\treturn nil\n\t}\n\treturn c.backend.Client.Jar.Cookies(u)\n}\n\n// Clone creates an exact copy of a Collector without callbacks.\n// HTTP backend, robots.txt cache and cookie jar are shared\n// between collectors.\nfunc (c *Collector) Clone() *Collector {\n\treturn &Collector{\n\t\tAllowedDomains:         c.AllowedDomains,\n\t\tAllowURLRevisit:        c.AllowURLRevisit,\n\t\tCacheDir:               c.CacheDir,\n\t\tDetectCharset:          c.DetectCharset,\n\t\tDisallowedDomains:      c.DisallowedDomains,\n\t\tID:                     atomic.AddUint32(&collectorCounter, 1),\n\t\tIgnoreRobotsTxt:        c.IgnoreRobotsTxt,\n\t\tMaxBodySize:            c.MaxBodySize,\n\t\tMaxDepth:               c.MaxDepth,\n\t\tDisallowedURLFilters:   c.DisallowedURLFilters,\n\t\tURLFilters:             c.URLFilters,\n\t\tCheckHead:              c.CheckHead,\n\t\tParseHTTPErrorResponse: c.ParseHTTPErrorResponse,\n\t\tUserAgent:              c.UserAgent,\n\t\tTraceHTTP:              c.TraceHTTP,\n\t\tstore:                  c.store,\n\t\tbackend:                c.backend,\n\t\tdebugger:               c.debugger,\n\t\tAsync:                  c.Async,\n\t\tredirectHandler:        c.redirectHandler,\n\t\terrorCallbacks:         make([]ErrorCallback, 0, 8),\n\t\thtmlCallbacks:          make([]*htmlCallbackContainer, 0, 8),\n\t\txmlCallbacks:           make([]*xmlCallbackContainer, 0, 8),\n\t\tscrapedCallbacks:       make([]ScrapedCallback, 0, 8),\n\t\tlock:                   c.lock,\n\t\trequestCallbacks:       make([]RequestCallback, 0, 8),\n\t\tresponseCallbacks:      make([]ResponseCallback, 0, 8),\n\t\trobotsMap:              c.robotsMap,\n\t\twg:                     &sync.WaitGroup{},\n\t}\n}\n\nfunc (c *Collector) checkRedirectFunc() func(req *http.Request, via []*http.Request) error {\n\treturn func(req *http.Request, via []*http.Request) error {\n\t\tif !c.isDomainAllowed(req.URL.Hostname()) {\n\t\t\treturn fmt.Errorf(\"Not following redirect to %s because its not in AllowedDomains\", req.URL.Host)\n\t\t}\n\n\t\tif c.redirectHandler != nil {\n\t\t\treturn c.redirectHandler(req, via)\n\t\t}\n\n\t\t// Honor golangs default of maximum of 10 redirects\n\t\tif len(via) >= 10 {\n\t\t\treturn http.ErrUseLastResponse\n\t\t}\n\n\t\tlastRequest := via[len(via)-1]\n\n\t\t// If domain has changed, remove the Authorization-header if it exists\n\t\tif req.URL.Host != lastRequest.URL.Host {\n\t\t\treq.Header.Del(\"Authorization\")\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\nfunc (c *Collector) parseSettingsFromEnv() {\n\tfor _, e := range os.Environ() {\n\t\tif !strings.HasPrefix(e, \"COLLY_\") {\n\t\t\tcontinue\n\t\t}\n\t\tpair := strings.SplitN(e[6:], \"=\", 2)\n\t\tif f, ok := envMap[pair[0]]; ok {\n\t\t\tf(c, pair[1])\n\t\t} else {\n\t\t\tlog.Println(\"Unknown environment variable:\", pair[0])\n\t\t}\n\t}\n}\n\nfunc (c *Collector) checkHasVisited(URL string, requestData map[string]string) (bool, error) {\n\th := fnv.New64a()\n\th.Write([]byte(URL))\n\n\tif requestData != nil {\n\t\th.Write(streamToByte(createFormReader(requestData)))\n\t}\n\n\treturn c.store.IsVisited(h.Sum64())\n}\n\n// SanitizeFileName replaces dangerous characters in a string\n// so the return value can be used as a safe file name.\nfunc SanitizeFileName(fileName string) string {\n\text := filepath.Ext(fileName)\n\tcleanExt := sanitize.BaseName(ext)\n\tif cleanExt == \"\" {\n\t\tcleanExt = \".unknown\"\n\t}\n\treturn strings.Replace(fmt.Sprintf(\n\t\t\"%s.%s\",\n\t\tsanitize.BaseName(fileName[:len(fileName)-len(ext)]),\n\t\tcleanExt[1:],\n\t), \"-\", \"_\", -1)\n}\n\nfunc createFormReader(data map[string]string) io.Reader {\n\tform := url.Values{}\n\tfor k, v := range data {\n\t\tform.Add(k, v)\n\t}\n\treturn strings.NewReader(form.Encode())\n}\n\nfunc createMultipartReader(boundary string, data map[string][]byte) io.Reader {\n\tdashBoundary := \"--\" + boundary\n\n\tbody := []byte{}\n\tbuffer := bytes.NewBuffer(body)\n\n\tbuffer.WriteString(\"Content-type: multipart/form-data; boundary=\" + boundary + \"\\n\\n\")\n\tfor contentType, content := range data {\n\t\tbuffer.WriteString(dashBoundary + \"\\n\")\n\t\tbuffer.WriteString(\"Content-Disposition: form-data; name=\" + contentType + \"\\n\")\n\t\tbuffer.WriteString(fmt.Sprintf(\"Content-Length: %d \\n\\n\", len(content)))\n\t\tbuffer.Write(content)\n\t\tbuffer.WriteString(\"\\n\")\n\t}\n\tbuffer.WriteString(dashBoundary + \"--\\n\\n\")\n\treturn buffer\n}\n\n// randomBoundary was borrowed from\n// github.com/golang/go/mime/multipart/writer.go#randomBoundary\nfunc randomBoundary() string {\n\tvar buf [30]byte\n\t_, err := io.ReadFull(rand.Reader, buf[:])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn fmt.Sprintf(\"%x\", buf[:])\n}\n\nfunc isYesString(s string) bool {\n\tswitch strings.ToLower(s) {\n\tcase \"1\", \"yes\", \"true\", \"y\":\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc createJar(s storage.Storage) http.CookieJar {\n\treturn &cookieJarSerializer{store: s, lock: &sync.RWMutex{}}\n}\n\nfunc (j *cookieJarSerializer) SetCookies(u *url.URL, cookies []*http.Cookie) {\n\tj.lock.Lock()\n\tdefer j.lock.Unlock()\n\tcookieStr := j.store.Cookies(u)\n\n\t// Merge existing cookies, new cookies have precedence.\n\tcnew := make([]*http.Cookie, len(cookies))\n\tcopy(cnew, cookies)\n\texisting := storage.UnstringifyCookies(cookieStr)\n\tfor _, c := range existing {\n\t\tif !storage.ContainsCookie(cnew, c.Name) {\n\t\t\tcnew = append(cnew, c)\n\t\t}\n\t}\n\tj.store.SetCookies(u, storage.StringifyCookies(cnew))\n}\n\nfunc (j *cookieJarSerializer) Cookies(u *url.URL) []*http.Cookie {\n\tcookies := storage.UnstringifyCookies(j.store.Cookies(u))\n\t// Filter.\n\tnow := time.Now()\n\tcnew := make([]*http.Cookie, 0, len(cookies))\n\tfor _, c := range cookies {\n\t\t// Drop expired cookies.\n\t\tif c.RawExpires != \"\" && c.Expires.Before(now) {\n\t\t\tcontinue\n\t\t}\n\t\t// Drop secure cookies if not over https.\n\t\tif c.Secure && u.Scheme != \"https\" {\n\t\t\tcontinue\n\t\t}\n\t\tcnew = append(cnew, c)\n\t}\n\treturn cnew\n}\n\nfunc isMatchingFilter(fs []*regexp.Regexp, d []byte) bool {\n\tfor _, r := range fs {\n\t\tif r.Match(d) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc streamToByte(r io.Reader) []byte {\n\tbuf := new(bytes.Buffer)\n\tbuf.ReadFrom(r)\n\n\tif strReader, k := r.(*strings.Reader); k {\n\t\tstrReader.Seek(0, 0)\n\t} else if bReader, kb := r.(*bytes.Reader); kb {\n\t\tbReader.Seek(0, 0)\n\t}\n\n\treturn buf.Bytes()\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/context.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage colly\n\nimport (\n\t\"sync\"\n)\n\n// Context provides a tiny layer for passing data between callbacks\ntype Context struct {\n\tcontextMap map[string]interface{}\n\tlock       *sync.RWMutex\n}\n\n// NewContext initializes a new Context instance\nfunc NewContext() *Context {\n\treturn &Context{\n\t\tcontextMap: make(map[string]interface{}),\n\t\tlock:       &sync.RWMutex{},\n\t}\n}\n\n// UnmarshalBinary decodes Context value to nil\n// This function is used by request caching\nfunc (c *Context) UnmarshalBinary(_ []byte) error {\n\treturn nil\n}\n\n// MarshalBinary encodes Context value\n// This function is used by request caching\nfunc (c *Context) MarshalBinary() (_ []byte, _ error) {\n\treturn nil, nil\n}\n\n// Put stores a value of any type in Context\nfunc (c *Context) Put(key string, value interface{}) {\n\tc.lock.Lock()\n\tc.contextMap[key] = value\n\tc.lock.Unlock()\n}\n\n// Get retrieves a string value from Context.\n// Get returns an empty string if key not found\nfunc (c *Context) Get(key string) string {\n\tc.lock.RLock()\n\tdefer c.lock.RUnlock()\n\tif v, ok := c.contextMap[key]; ok {\n\t\treturn v.(string)\n\t}\n\treturn \"\"\n}\n\n// GetAny retrieves a value from Context.\n// GetAny returns nil if key not found\nfunc (c *Context) GetAny(key string) interface{} {\n\tc.lock.RLock()\n\tdefer c.lock.RUnlock()\n\tif v, ok := c.contextMap[key]; ok {\n\t\treturn v\n\t}\n\treturn nil\n}\n\n// ForEach iterate context\nfunc (c *Context) ForEach(fn func(k string, v interface{}) interface{}) []interface{} {\n\tc.lock.RLock()\n\tdefer c.lock.RUnlock()\n\n\tret := make([]interface{}, 0, len(c.contextMap))\n\tfor k, v := range c.contextMap {\n\t\tret = append(ret, fn(k, v))\n\t}\n\n\treturn ret\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/debug/debug.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage debug\n\n// Event represents an action inside a collector\ntype Event struct {\n\t// Type is the type of the event\n\tType string\n\t// RequestID identifies the HTTP request of the Event\n\tRequestID uint32\n\t// CollectorID identifies the collector of the Event\n\tCollectorID uint32\n\t// Values contains the event's key-value pairs. Different type of events\n\t// can return different key-value pairs\n\tValues map[string]string\n}\n\n// Debugger is an interface for different type of debugging backends\ntype Debugger interface {\n\t// Init initializes the backend\n\tInit() error\n\t// Event receives a new collector event.\n\tEvent(e *Event)\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/debug/logdebugger.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage debug\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"os\"\n\t\"sync/atomic\"\n\t\"time\"\n)\n\n// LogDebugger is the simplest debugger which prints log messages to the STDERR\ntype LogDebugger struct {\n\t// Output is the log destination, anything can be used which implements them\n\t// io.Writer interface. Leave it blank to use STDERR\n\tOutput io.Writer\n\t// Prefix appears at the beginning of each generated log line\n\tPrefix string\n\t// Flag defines the logging properties.\n\tFlag    int\n\tlogger  *log.Logger\n\tcounter int32\n\tstart   time.Time\n}\n\n// Init initializes the LogDebugger\nfunc (l *LogDebugger) Init() error {\n\tl.counter = 0\n\tl.start = time.Now()\n\tif l.Output == nil {\n\t\tl.Output = os.Stderr\n\t}\n\tl.logger = log.New(l.Output, l.Prefix, l.Flag)\n\treturn nil\n}\n\n// Event receives Collector events and prints them to STDERR\nfunc (l *LogDebugger) Event(e *Event) {\n\ti := atomic.AddInt32(&l.counter, 1)\n\tl.logger.Printf(\"[%06d] %d [%6d - %s] %q (%s)\\n\", i, e.CollectorID, e.RequestID, e.Type, e.Values, time.Since(l.start))\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/debug/webdebugger.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage debug\n\nimport (\n\t\"encoding/json\"\n\t\"log\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n)\n\n// WebDebugger is a web based debuging frontend for colly\ntype WebDebugger struct {\n\t// Address is the address of the web server. It is 127.0.0.1:7676 by default.\n\tAddress         string\n\tinitialized     bool\n\tCurrentRequests map[uint32]requestInfo\n\tRequestLog      []requestInfo\n\tsync.Mutex\n}\n\ntype requestInfo struct {\n\tURL            string\n\tStarted        time.Time\n\tDuration       time.Duration\n\tResponseStatus string\n\tID             uint32\n\tCollectorID    uint32\n}\n\n// Init initializes the WebDebugger\nfunc (w *WebDebugger) Init() error {\n\tif w.initialized {\n\t\treturn nil\n\t}\n\tdefer func() {\n\t\tw.initialized = true\n\t}()\n\tif w.Address == \"\" {\n\t\tw.Address = \"127.0.0.1:7676\"\n\t}\n\tw.RequestLog = make([]requestInfo, 0)\n\tw.CurrentRequests = make(map[uint32]requestInfo)\n\thttp.HandleFunc(\"/\", w.indexHandler)\n\thttp.HandleFunc(\"/status\", w.statusHandler)\n\tlog.Println(\"Starting debug webserver on\", w.Address)\n\tgo http.ListenAndServe(w.Address, nil)\n\treturn nil\n}\n\n// Event updates the debugger's status\nfunc (w *WebDebugger) Event(e *Event) {\n\tw.Lock()\n\tdefer w.Unlock()\n\n\tswitch e.Type {\n\tcase \"request\":\n\t\tw.CurrentRequests[e.RequestID] = requestInfo{\n\t\t\tURL:         e.Values[\"url\"],\n\t\t\tStarted:     time.Now(),\n\t\t\tID:          e.RequestID,\n\t\t\tCollectorID: e.CollectorID,\n\t\t}\n\tcase \"response\", \"error\":\n\t\tr := w.CurrentRequests[e.RequestID]\n\t\tr.Duration = time.Since(r.Started)\n\t\tr.ResponseStatus = e.Values[\"status\"]\n\t\tw.RequestLog = append(w.RequestLog, r)\n\t\tdelete(w.CurrentRequests, e.RequestID)\n\t}\n}\n\nfunc (w *WebDebugger) indexHandler(wr http.ResponseWriter, r *http.Request) {\n\twr.Write([]byte(`<!DOCTYPE html>\n<html>\n<head>\n <title>Colly Debugger WebUI</title>\n <script src=\"https://code.jquery.com/jquery-latest.min.js\" type=\"text/javascript\"></script>\n <link rel=\"stylesheet\" type=\"text/css\" href=\"https://semantic-ui.com/dist/semantic.min.css\">\n</head>\n<body>\n<div class=\"ui inverted vertical masthead center aligned segment\" id=\"menu\">\n <div class=\"ui tiny secondary inverted menu\">\n   <a class=\"item\" href=\"/\"><b>Colly WebDebugger</b></a>\n </div>\n</div>\n<div class=\"ui grid container\">\n <div class=\"row\">\n  <div class=\"eight wide column\">\n   <h1>Current Requests <span id=\"current_request_count\"></span></h1>\n   <div id=\"current_requests\" class=\"ui small feed\"></div>\n  </div>\n  <div class=\"eight wide column\">\n   <h1>Finished Requests <span id=\"request_log_count\"></span></h1>\n   <div id=\"request_log\" class=\"ui small feed\"></div>\n  </div>\n </div>\n</div>\n<script>\nfunction curRequestTpl(url, started, collectorId) {\n  return '<div class=\"event\"><div class=\"content\"><div class=\"summary\">' + url + '</div><div class=\"meta\">Collector #' + collectorId + ' - ' + started + \"</div></div></div>\";\n}\nfunction requestLogTpl(url, duration, collectorId) {\n  return '<div class=\"event\"><div class=\"content\"><div class=\"summary\">' + url + '</div><div class=\"meta\">Collector #' + collectorId + ' - ' + (duration/1000000000) + \"s</div></div></div>\";\n}\nfunction fetchStatus() {\n  $.getJSON(\"/status\", function(data) {\n    $(\"#current_requests\").html(\"\");\n    $(\"#request_log\").html(\"\");\n    $(\"#current_request_count\").text('(' + Object.keys(data.CurrentRequests).length + ')');\n    $(\"#request_log_count\").text('(' + data.RequestLog.length + ')');\n    for(var i in data.CurrentRequests) {\n      var r = data.CurrentRequests[i];\n      $(\"#current_requests\").append(curRequestTpl(r.URL, r.Started, r.CollectorID));\n    }\n    for(var i in data.RequestLog.reverse()) {\n      var r = data.RequestLog[i];\n      $(\"#request_log\").append(requestLogTpl(r.URL, r.Duration, r.CollectorID));\n    }\n    setTimeout(fetchStatus, 1000);\n  });\n}\n$(document).ready(function() {\n    fetchStatus();\n});\n</script>\n</body>\n</html>\n`))\n}\n\nfunc (w *WebDebugger) statusHandler(wr http.ResponseWriter, r *http.Request) {\n\tw.Lock()\n\tjsonData, err := json.MarshalIndent(w, \"\", \"  \")\n\tw.Unlock()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\twr.Write(jsonData)\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/htmlelement.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage colly\n\nimport (\n\t\"strings\"\n\n\t\"github.com/PuerkitoBio/goquery\"\n\t\"golang.org/x/net/html\"\n)\n\n// HTMLElement is the representation of a HTML tag.\ntype HTMLElement struct {\n\t// Name is the name of the tag\n\tName       string\n\tText       string\n\tattributes []html.Attribute\n\t// Request is the request object of the element's HTML document\n\tRequest *Request\n\t// Response is the Response object of the element's HTML document\n\tResponse *Response\n\t// DOM is the goquery parsed DOM object of the page. DOM is relative\n\t// to the current HTMLElement\n\tDOM *goquery.Selection\n\t// Index stores the position of the current element within all the elements matched by an OnHTML callback\n\tIndex int\n}\n\n// NewHTMLElementFromSelectionNode creates a HTMLElement from a goquery.Selection Node.\nfunc NewHTMLElementFromSelectionNode(resp *Response, s *goquery.Selection, n *html.Node, idx int) *HTMLElement {\n\treturn &HTMLElement{\n\t\tName:       n.Data,\n\t\tRequest:    resp.Request,\n\t\tResponse:   resp,\n\t\tText:       goquery.NewDocumentFromNode(n).Text(),\n\t\tDOM:        s,\n\t\tIndex:      idx,\n\t\tattributes: n.Attr,\n\t}\n}\n\n// Attr returns the selected attribute of a HTMLElement or empty string\n// if no attribute found\nfunc (h *HTMLElement) Attr(k string) string {\n\tfor _, a := range h.attributes {\n\t\tif a.Key == k {\n\t\t\treturn a.Val\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// ChildText returns the concatenated and stripped text content of the matching\n// elements.\nfunc (h *HTMLElement) ChildText(goquerySelector string) string {\n\treturn strings.TrimSpace(h.DOM.Find(goquerySelector).Text())\n}\n\n// ChildTexts returns the stripped text content of all the matching\n// elements.\nfunc (h *HTMLElement) ChildTexts(goquerySelector string) []string {\n\tvar res []string\n\th.DOM.Find(goquerySelector).Each(func(_ int, s *goquery.Selection) {\n\n\t\tres = append(res, strings.TrimSpace(s.Text()))\n\t})\n\treturn res\n}\n\n// ChildAttr returns the stripped text content of the first matching\n// element's attribute.\nfunc (h *HTMLElement) ChildAttr(goquerySelector, attrName string) string {\n\tif attr, ok := h.DOM.Find(goquerySelector).Attr(attrName); ok {\n\t\treturn strings.TrimSpace(attr)\n\t}\n\treturn \"\"\n}\n\n// ChildAttrs returns the stripped text content of all the matching\n// element's attributes.\nfunc (h *HTMLElement) ChildAttrs(goquerySelector, attrName string) []string {\n\tvar res []string\n\th.DOM.Find(goquerySelector).Each(func(_ int, s *goquery.Selection) {\n\t\tif attr, ok := s.Attr(attrName); ok {\n\t\t\tres = append(res, strings.TrimSpace(attr))\n\t\t}\n\t})\n\treturn res\n}\n\n// ForEach iterates over the elements matched by the first argument\n// and calls the callback function on every HTMLElement match.\nfunc (h *HTMLElement) ForEach(goquerySelector string, callback func(int, *HTMLElement)) {\n\ti := 0\n\th.DOM.Find(goquerySelector).Each(func(_ int, s *goquery.Selection) {\n\t\tfor _, n := range s.Nodes {\n\t\t\tcallback(i, NewHTMLElementFromSelectionNode(h.Response, s, n, i))\n\t\t\ti++\n\t\t}\n\t})\n}\n\n// ForEachWithBreak iterates over the elements matched by the first argument\n// and calls the callback function on every HTMLElement match.\n// It is identical to ForEach except that it is possible to break\n// out of the loop by returning false in the callback function. It returns the\n// current Selection object.\nfunc (h *HTMLElement) ForEachWithBreak(goquerySelector string, callback func(int, *HTMLElement) bool) {\n\ti := 0\n\th.DOM.Find(goquerySelector).EachWithBreak(func(_ int, s *goquery.Selection) bool {\n\t\tfor _, n := range s.Nodes {\n\t\t\tif callback(i, NewHTMLElementFromSelectionNode(h.Response, s, n, i)) {\n\t\t\t\ti++\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/http_backend.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage colly\n\nimport (\n\t\"crypto/sha1\"\n\t\"encoding/gob\"\n\t\"encoding/hex\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"compress/gzip\"\n\n\t\"github.com/gobwas/glob\"\n)\n\ntype httpBackend struct {\n\tLimitRules []*LimitRule\n\tClient     *http.Client\n\tlock       *sync.RWMutex\n}\n\ntype checkHeadersFunc func(statusCode int, header http.Header) bool\n\n// LimitRule provides connection restrictions for domains.\n// Both DomainRegexp and DomainGlob can be used to specify\n// the included domains patterns, but at least one is required.\n// There can be two kind of limitations:\n//  - Parallelism: Set limit for the number of concurrent requests to matching domains\n//  - Delay: Wait specified amount of time between requests (parallelism is 1 in this case)\ntype LimitRule struct {\n\t// DomainRegexp is a regular expression to match against domains\n\tDomainRegexp string\n\t// DomainGlob is a glob pattern to match against domains\n\tDomainGlob string\n\t// Delay is the duration to wait before creating a new request to the matching domains\n\tDelay time.Duration\n\t// RandomDelay is the extra randomized duration to wait added to Delay before creating a new request\n\tRandomDelay time.Duration\n\t// Parallelism is the number of the maximum allowed concurrent requests of the matching domains\n\tParallelism    int\n\twaitChan       chan bool\n\tcompiledRegexp *regexp.Regexp\n\tcompiledGlob   glob.Glob\n}\n\n// Init initializes the private members of LimitRule\nfunc (r *LimitRule) Init() error {\n\twaitChanSize := 1\n\tif r.Parallelism > 1 {\n\t\twaitChanSize = r.Parallelism\n\t}\n\tr.waitChan = make(chan bool, waitChanSize)\n\thasPattern := false\n\tif r.DomainRegexp != \"\" {\n\t\tc, err := regexp.Compile(r.DomainRegexp)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.compiledRegexp = c\n\t\thasPattern = true\n\t}\n\tif r.DomainGlob != \"\" {\n\t\tc, err := glob.Compile(r.DomainGlob)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.compiledGlob = c\n\t\thasPattern = true\n\t}\n\tif !hasPattern {\n\t\treturn ErrNoPattern\n\t}\n\treturn nil\n}\n\nfunc (h *httpBackend) Init(jar http.CookieJar) {\n\trand.Seed(time.Now().UnixNano())\n\th.Client = &http.Client{\n\t\tJar:     jar,\n\t\tTimeout: 10 * time.Second,\n\t}\n\th.lock = &sync.RWMutex{}\n}\n\n// Match checks that the domain parameter triggers the rule\nfunc (r *LimitRule) Match(domain string) bool {\n\tmatch := false\n\tif r.compiledRegexp != nil && r.compiledRegexp.MatchString(domain) {\n\t\tmatch = true\n\t}\n\tif r.compiledGlob != nil && r.compiledGlob.Match(domain) {\n\t\tmatch = true\n\t}\n\treturn match\n}\n\nfunc (h *httpBackend) GetMatchingRule(domain string) *LimitRule {\n\tif h.LimitRules == nil {\n\t\treturn nil\n\t}\n\th.lock.RLock()\n\tdefer h.lock.RUnlock()\n\tfor _, r := range h.LimitRules {\n\t\tif r.Match(domain) {\n\t\t\treturn r\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (h *httpBackend) Cache(request *http.Request, bodySize int, checkHeadersFunc checkHeadersFunc, cacheDir string) (*Response, error) {\n\tif cacheDir == \"\" || request.Method != \"GET\" {\n\t\treturn h.Do(request, bodySize, checkHeadersFunc)\n\t}\n\tsum := sha1.Sum([]byte(request.URL.String()))\n\thash := hex.EncodeToString(sum[:])\n\tdir := path.Join(cacheDir, hash[:2])\n\tfilename := path.Join(dir, hash)\n\tif file, err := os.Open(filename); err == nil {\n\t\tresp := new(Response)\n\t\terr := gob.NewDecoder(file).Decode(resp)\n\t\tfile.Close()\n\t\tif resp.StatusCode < 500 {\n\t\t\treturn resp, err\n\t\t}\n\t}\n\tresp, err := h.Do(request, bodySize, checkHeadersFunc)\n\tif err != nil || resp.StatusCode >= 500 {\n\t\treturn resp, err\n\t}\n\tif _, err := os.Stat(dir); err != nil {\n\t\tif err := os.MkdirAll(dir, 0750); err != nil {\n\t\t\treturn resp, err\n\t\t}\n\t}\n\tfile, err := os.Create(filename + \"~\")\n\tif err != nil {\n\t\treturn resp, err\n\t}\n\tif err := gob.NewEncoder(file).Encode(resp); err != nil {\n\t\tfile.Close()\n\t\treturn resp, err\n\t}\n\tfile.Close()\n\treturn resp, os.Rename(filename+\"~\", filename)\n}\n\nfunc (h *httpBackend) Do(request *http.Request, bodySize int, checkHeadersFunc checkHeadersFunc) (*Response, error) {\n\tr := h.GetMatchingRule(request.URL.Host)\n\tif r != nil {\n\t\tr.waitChan <- true\n\t\tdefer func(r *LimitRule) {\n\t\t\trandomDelay := time.Duration(0)\n\t\t\tif r.RandomDelay != 0 {\n\t\t\t\trandomDelay = time.Duration(rand.Int63n(int64(r.RandomDelay)))\n\t\t\t}\n\t\t\ttime.Sleep(r.Delay + randomDelay)\n\t\t\t<-r.waitChan\n\t\t}(r)\n\t}\n\n\tres, err := h.Client.Do(request)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\tif res.Request != nil {\n\t\t*request = *res.Request\n\t}\n\tif !checkHeadersFunc(res.StatusCode, res.Header) {\n\t\t// closing res.Body (see defer above) without reading it aborts\n\t\t// the download\n\t\treturn nil, ErrAbortedAfterHeaders\n\t}\n\n\tvar bodyReader io.Reader = res.Body\n\tif bodySize > 0 {\n\t\tbodyReader = io.LimitReader(bodyReader, int64(bodySize))\n\t}\n\tcontentEncoding := strings.ToLower(res.Header.Get(\"Content-Encoding\"))\n\tif !res.Uncompressed && (strings.Contains(contentEncoding, \"gzip\") || (contentEncoding == \"\" && strings.Contains(strings.ToLower(res.Header.Get(\"Content-Type\")), \"gzip\")) || strings.HasSuffix(strings.ToLower(request.URL.Path), \".xml.gz\")) {\n\t\tbodyReader, err = gzip.NewReader(bodyReader)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdefer bodyReader.(*gzip.Reader).Close()\n\t}\n\tbody, err := ioutil.ReadAll(bodyReader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Response{\n\t\tStatusCode: res.StatusCode,\n\t\tBody:       body,\n\t\tHeaders:    &res.Header,\n\t}, nil\n}\n\nfunc (h *httpBackend) Limit(rule *LimitRule) error {\n\th.lock.Lock()\n\tif h.LimitRules == nil {\n\t\th.LimitRules = make([]*LimitRule, 0, 8)\n\t}\n\th.LimitRules = append(h.LimitRules, rule)\n\th.lock.Unlock()\n\treturn rule.Init()\n}\n\nfunc (h *httpBackend) Limits(rules []*LimitRule) error {\n\tfor _, r := range rules {\n\t\tif err := h.Limit(r); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/http_trace.go",
    "content": "package colly\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"time\"\n)\n\n// HTTPTrace provides a datastructure for storing an http trace.\ntype HTTPTrace struct {\n\tstart, connect    time.Time\n\tConnectDuration   time.Duration\n\tFirstByteDuration time.Duration\n}\n\n// trace returns a httptrace.ClientTrace object to be used with an http\n// request via httptrace.WithClientTrace() that fills in the HttpTrace.\nfunc (ht *HTTPTrace) trace() *httptrace.ClientTrace {\n\ttrace := &httptrace.ClientTrace{\n\t\tConnectStart: func(network, addr string) { ht.connect = time.Now() },\n\t\tConnectDone: func(network, addr string, err error) {\n\t\t\tht.ConnectDuration = time.Since(ht.connect)\n\t\t},\n\n\t\tGetConn: func(hostPort string) { ht.start = time.Now() },\n\t\tGotFirstResponseByte: func() {\n\t\t\tht.FirstByteDuration = time.Since(ht.start)\n\t\t},\n\t}\n\treturn trace\n}\n\n// WithTrace returns the given HTTP Request with this HTTPTrace added to its\n// context.\nfunc (ht *HTTPTrace) WithTrace(req *http.Request) *http.Request {\n\treturn req.WithContext(httptrace.WithClientTrace(req.Context(), ht.trace()))\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/request.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage colly\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"sync/atomic\"\n)\n\n// Request is the representation of a HTTP request made by a Collector\ntype Request struct {\n\t// URL is the parsed URL of the HTTP request\n\tURL *url.URL\n\t// Headers contains the Request's HTTP headers\n\tHeaders *http.Header\n\t// Ctx is a context between a Request and a Response\n\tCtx *Context\n\t// Depth is the number of the parents of the request\n\tDepth int\n\t// Method is the HTTP method of the request\n\tMethod string\n\t// Body is the request body which is used on POST/PUT requests\n\tBody io.Reader\n\t// ResponseCharacterencoding is the character encoding of the response body.\n\t// Leave it blank to allow automatic character encoding of the response body.\n\t// It is empty by default and it can be set in OnRequest callback.\n\tResponseCharacterEncoding string\n\t// ID is the Unique identifier of the request\n\tID        uint32\n\tcollector *Collector\n\tabort     bool\n\tbaseURL   *url.URL\n\t// ProxyURL is the proxy address that handles the request\n\tProxyURL string\n}\n\ntype serializableRequest struct {\n\tURL     string\n\tMethod  string\n\tDepth   int\n\tBody    []byte\n\tID      uint32\n\tCtx     map[string]interface{}\n\tHeaders http.Header\n}\n\n// New creates a new request with the context of the original request\nfunc (r *Request) New(method, URL string, body io.Reader) (*Request, error) {\n\tu, err := url.Parse(URL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Request{\n\t\tMethod:    method,\n\t\tURL:       u,\n\t\tBody:      body,\n\t\tCtx:       r.Ctx,\n\t\tHeaders:   &http.Header{},\n\t\tID:        atomic.AddUint32(&r.collector.requestCount, 1),\n\t\tcollector: r.collector,\n\t}, nil\n}\n\n// Abort cancels the HTTP request when called in an OnRequest callback\nfunc (r *Request) Abort() {\n\tr.abort = true\n}\n\n// AbsoluteURL returns with the resolved absolute URL of an URL chunk.\n// AbsoluteURL returns empty string if the URL chunk is a fragment or\n// could not be parsed\nfunc (r *Request) AbsoluteURL(u string) string {\n\tif strings.HasPrefix(u, \"#\") {\n\t\treturn \"\"\n\t}\n\tvar base *url.URL\n\tif r.baseURL != nil {\n\t\tbase = r.baseURL\n\t} else {\n\t\tbase = r.URL\n\t}\n\tabsURL, err := base.Parse(u)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\tabsURL.Fragment = \"\"\n\tif absURL.Scheme == \"//\" {\n\t\tabsURL.Scheme = r.URL.Scheme\n\t}\n\treturn absURL.String()\n}\n\n// Visit continues Collector's collecting job by creating a\n// request and preserves the Context of the previous request.\n// Visit also calls the previously provided callbacks\nfunc (r *Request) Visit(URL string) error {\n\treturn r.collector.scrape(r.AbsoluteURL(URL), \"GET\", r.Depth+1, nil, r.Ctx, nil, true)\n}\n\n// HasVisited checks if the provided URL has been visited\nfunc (r *Request) HasVisited(URL string) (bool, error) {\n\treturn r.collector.HasVisited(URL)\n}\n\n// Post continues a collector job by creating a POST request and preserves the Context\n// of the previous request.\n// Post also calls the previously provided callbacks\nfunc (r *Request) Post(URL string, requestData map[string]string) error {\n\treturn r.collector.scrape(r.AbsoluteURL(URL), \"POST\", r.Depth+1, createFormReader(requestData), r.Ctx, nil, true)\n}\n\n// PostRaw starts a collector job by creating a POST request with raw binary data.\n// PostRaw preserves the Context of the previous request\n// and calls the previously provided callbacks\nfunc (r *Request) PostRaw(URL string, requestData []byte) error {\n\treturn r.collector.scrape(r.AbsoluteURL(URL), \"POST\", r.Depth+1, bytes.NewReader(requestData), r.Ctx, nil, true)\n}\n\n// PostMultipart starts a collector job by creating a Multipart POST request\n// with raw binary data.  PostMultipart also calls the previously provided.\n// callbacks\nfunc (r *Request) PostMultipart(URL string, requestData map[string][]byte) error {\n\tboundary := randomBoundary()\n\thdr := http.Header{}\n\thdr.Set(\"Content-Type\", \"multipart/form-data; boundary=\"+boundary)\n\thdr.Set(\"User-Agent\", r.collector.UserAgent)\n\treturn r.collector.scrape(r.AbsoluteURL(URL), \"POST\", r.Depth+1, createMultipartReader(boundary, requestData), r.Ctx, hdr, true)\n}\n\n// Retry submits HTTP request again with the same parameters\nfunc (r *Request) Retry() error {\n\tr.Headers.Del(\"Cookie\")\n\treturn r.collector.scrape(r.URL.String(), r.Method, r.Depth, r.Body, r.Ctx, *r.Headers, false)\n}\n\n// Do submits the request\nfunc (r *Request) Do() error {\n\treturn r.collector.scrape(r.URL.String(), r.Method, r.Depth, r.Body, r.Ctx, *r.Headers, !r.collector.AllowURLRevisit)\n}\n\n// Marshal serializes the Request\nfunc (r *Request) Marshal() ([]byte, error) {\n\tctx := make(map[string]interface{})\n\tif r.Ctx != nil {\n\t\tr.Ctx.ForEach(func(k string, v interface{}) interface{} {\n\t\t\tctx[k] = v\n\t\t\treturn nil\n\t\t})\n\t}\n\tvar err error\n\tvar body []byte\n\tif r.Body != nil {\n\t\tbody, err = ioutil.ReadAll(r.Body)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tsr := &serializableRequest{\n\t\tURL:    r.URL.String(),\n\t\tMethod: r.Method,\n\t\tDepth:  r.Depth,\n\t\tBody:   body,\n\t\tID:     r.ID,\n\t\tCtx:    ctx,\n\t}\n\tif r.Headers != nil {\n\t\tsr.Headers = *r.Headers\n\t}\n\treturn json.Marshal(sr)\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/response.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage colly\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"mime\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/saintfish/chardet\"\n\t\"golang.org/x/net/html/charset\"\n)\n\n// Response is the representation of a HTTP response made by a Collector\ntype Response struct {\n\t// StatusCode is the status code of the Response\n\tStatusCode int\n\t// Body is the content of the Response\n\tBody []byte\n\t// Ctx is a context between a Request and a Response\n\tCtx *Context\n\t// Request is the Request object of the response\n\tRequest *Request\n\t// Headers contains the Response's HTTP headers\n\tHeaders *http.Header\n\t// Trace contains the HTTPTrace for the request. Will only be set by the\n\t// collector if Collector.TraceHTTP is set to true.\n\tTrace *HTTPTrace\n}\n\n// Save writes response body to disk\nfunc (r *Response) Save(fileName string) error {\n\treturn ioutil.WriteFile(fileName, r.Body, 0644)\n}\n\n// FileName returns the sanitized file name parsed from \"Content-Disposition\"\n// header or from URL\nfunc (r *Response) FileName() string {\n\t_, params, err := mime.ParseMediaType(r.Headers.Get(\"Content-Disposition\"))\n\tif fName, ok := params[\"filename\"]; ok && err == nil {\n\t\treturn SanitizeFileName(fName)\n\t}\n\tif r.Request.URL.RawQuery != \"\" {\n\t\treturn SanitizeFileName(fmt.Sprintf(\"%s_%s\", r.Request.URL.Path, r.Request.URL.RawQuery))\n\t}\n\treturn SanitizeFileName(strings.TrimPrefix(r.Request.URL.Path, \"/\"))\n}\n\nfunc (r *Response) fixCharset(detectCharset bool, defaultEncoding string) error {\n\tif len(r.Body) == 0 {\n\t\treturn nil\n\t}\n\tif defaultEncoding != \"\" {\n\t\ttmpBody, err := encodeBytes(r.Body, \"text/plain; charset=\"+defaultEncoding)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.Body = tmpBody\n\t\treturn nil\n\t}\n\tcontentType := strings.ToLower(r.Headers.Get(\"Content-Type\"))\n\n\tif strings.Contains(contentType, \"image/\") ||\n\t\tstrings.Contains(contentType, \"video/\") ||\n\t\tstrings.Contains(contentType, \"audio/\") ||\n\t\tstrings.Contains(contentType, \"font/\") {\n\t\t// These MIME types should not have textual data.\n\n\t\treturn nil\n\t}\n\n\tif !strings.Contains(contentType, \"charset\") {\n\t\tif !detectCharset {\n\t\t\treturn nil\n\t\t}\n\t\td := chardet.NewTextDetector()\n\t\tr, err := d.DetectBest(r.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcontentType = \"text/plain; charset=\" + r.Charset\n\t}\n\tif strings.Contains(contentType, \"utf-8\") || strings.Contains(contentType, \"utf8\") {\n\t\treturn nil\n\t}\n\ttmpBody, err := encodeBytes(r.Body, contentType)\n\tif err != nil {\n\t\treturn err\n\t}\n\tr.Body = tmpBody\n\treturn nil\n}\n\nfunc encodeBytes(b []byte, contentType string) ([]byte, error) {\n\tr, err := charset.NewReader(bytes.NewReader(b), contentType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn ioutil.ReadAll(r)\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/storage/storage.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage storage\n\nimport (\n\t\"net/http\"\n\t\"net/http/cookiejar\"\n\t\"net/url\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// Storage is an interface which handles Collector's internal data,\n// like visited urls and cookies.\n// The default Storage of the Collector is the InMemoryStorage.\n// Collector's storage can be changed by calling Collector.SetStorage()\n// function.\ntype Storage interface {\n\t// Init initializes the storage\n\tInit() error\n\t// Visited receives and stores a request ID that is visited by the Collector\n\tVisited(requestID uint64) error\n\t// IsVisited returns true if the request was visited before IsVisited\n\t// is called\n\tIsVisited(requestID uint64) (bool, error)\n\t// Cookies retrieves stored cookies for a given host\n\tCookies(u *url.URL) string\n\t// SetCookies stores cookies for a given host\n\tSetCookies(u *url.URL, cookies string)\n}\n\n// InMemoryStorage is the default storage backend of colly.\n// InMemoryStorage keeps cookies and visited urls in memory\n// without persisting data on the disk.\ntype InMemoryStorage struct {\n\tvisitedURLs map[uint64]bool\n\tlock        *sync.RWMutex\n\tjar         *cookiejar.Jar\n}\n\n// Init initializes InMemoryStorage\nfunc (s *InMemoryStorage) Init() error {\n\tif s.visitedURLs == nil {\n\t\ts.visitedURLs = make(map[uint64]bool)\n\t}\n\tif s.lock == nil {\n\t\ts.lock = &sync.RWMutex{}\n\t}\n\tif s.jar == nil {\n\t\tvar err error\n\t\ts.jar, err = cookiejar.New(nil)\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Visited implements Storage.Visited()\nfunc (s *InMemoryStorage) Visited(requestID uint64) error {\n\ts.lock.Lock()\n\ts.visitedURLs[requestID] = true\n\ts.lock.Unlock()\n\treturn nil\n}\n\n// IsVisited implements Storage.IsVisited()\nfunc (s *InMemoryStorage) IsVisited(requestID uint64) (bool, error) {\n\ts.lock.RLock()\n\tvisited := s.visitedURLs[requestID]\n\ts.lock.RUnlock()\n\treturn visited, nil\n}\n\n// Cookies implements Storage.Cookies()\nfunc (s *InMemoryStorage) Cookies(u *url.URL) string {\n\treturn StringifyCookies(s.jar.Cookies(u))\n}\n\n// SetCookies implements Storage.SetCookies()\nfunc (s *InMemoryStorage) SetCookies(u *url.URL, cookies string) {\n\ts.jar.SetCookies(u, UnstringifyCookies(cookies))\n}\n\n// Close implements Storage.Close()\nfunc (s *InMemoryStorage) Close() error {\n\treturn nil\n}\n\n// StringifyCookies serializes list of http.Cookies to string\nfunc StringifyCookies(cookies []*http.Cookie) string {\n\t// Stringify cookies.\n\tcs := make([]string, len(cookies))\n\tfor i, c := range cookies {\n\t\tcs[i] = c.String()\n\t}\n\treturn strings.Join(cs, \"\\n\")\n}\n\n// UnstringifyCookies deserializes a cookie string to http.Cookies\nfunc UnstringifyCookies(s string) []*http.Cookie {\n\th := http.Header{}\n\tfor _, c := range strings.Split(s, \"\\n\") {\n\t\th.Add(\"Set-Cookie\", c)\n\t}\n\tr := http.Response{Header: h}\n\treturn r.Cookies()\n}\n\n// ContainsCookie checks if a cookie name is represented in cookies\nfunc ContainsCookie(cookies []*http.Cookie, name string) bool {\n\tfor _, c := range cookies {\n\t\tif c.Name == name {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/unmarshal.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage colly\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/PuerkitoBio/goquery\"\n)\n\n// Unmarshal is a shorthand for colly.UnmarshalHTML\nfunc (h *HTMLElement) Unmarshal(v interface{}) error {\n\treturn UnmarshalHTML(v, h.DOM, nil)\n}\n\n// UnmarshalWithMap is a shorthand for colly.UnmarshalHTML, extended to allow maps to be passed in.\nfunc (h *HTMLElement) UnmarshalWithMap(v interface{}, structMap map[string]string) error {\n\treturn UnmarshalHTML(v, h.DOM, structMap)\n}\n\n// UnmarshalHTML declaratively extracts text or attributes to a struct from\n// HTML response using struct tags composed of css selectors.\n// Allowed struct tags:\n//  - \"selector\" (required): CSS (goquery) selector of the desired data\n//  - \"attr\" (optional): Selects the matching element's attribute's value.\n//     Leave it blank or omit to get the text of the element.\n//\n// Example struct declaration:\n//\n//   type Nested struct {\n//   \tString  string   `selector:\"div > p\"`\n//      Classes []string `selector:\"li\" attr:\"class\"`\n//   \tStruct  *Nested  `selector:\"div > div\"`\n//   }\n//\n// Supported types: struct, *struct, string, []string\nfunc UnmarshalHTML(v interface{}, s *goquery.Selection, structMap map[string]string) error {\n\trv := reflect.ValueOf(v)\n\n\tif rv.Kind() != reflect.Ptr || rv.IsNil() {\n\t\treturn errors.New(\"Invalid type or nil-pointer\")\n\t}\n\n\tsv := rv.Elem()\n\tst := reflect.TypeOf(v).Elem()\n\tif structMap != nil {\n\t\tfor k, v := range structMap {\n\t\t\tattrV := sv.FieldByName(k)\n\t\t\tif !attrV.CanAddr() || !attrV.CanSet() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err := unmarshalSelector(s, attrV, v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i := 0; i < sv.NumField(); i++ {\n\t\t\tattrV := sv.Field(i)\n\t\t\tif !attrV.CanAddr() || !attrV.CanSet() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err := unmarshalAttr(s, attrV, st.Field(i)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc unmarshalSelector(s *goquery.Selection, attrV reflect.Value, selector string) error {\n\t//selector is \"-\" specify that field should ignore.\n\tif selector == \"-\" {\n\t\treturn nil\n\t}\n\thtmlAttr := \"\"\n\t// TODO support more types\n\tswitch attrV.Kind() {\n\tcase reflect.Slice:\n\t\tif err := unmarshalSlice(s, selector, htmlAttr, attrV); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase reflect.String:\n\t\tval := getDOMValue(s.Find(selector), htmlAttr)\n\t\tattrV.Set(reflect.Indirect(reflect.ValueOf(val)))\n\tcase reflect.Struct:\n\t\tif err := unmarshalStruct(s, selector, attrV); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase reflect.Ptr:\n\t\tif err := unmarshalPtr(s, selector, attrV); err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\treturn errors.New(\"Invalid type: \" + attrV.String())\n\t}\n\treturn nil\n}\n\nfunc unmarshalAttr(s *goquery.Selection, attrV reflect.Value, attrT reflect.StructField) error {\n\tselector := attrT.Tag.Get(\"selector\")\n\t//selector is \"-\" specify that field should ignore.\n\tif selector == \"-\" {\n\t\treturn nil\n\t}\n\thtmlAttr := attrT.Tag.Get(\"attr\")\n\t// TODO support more types\n\tswitch attrV.Kind() {\n\tcase reflect.Slice:\n\t\tif err := unmarshalSlice(s, selector, htmlAttr, attrV); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase reflect.String:\n\t\tval := getDOMValue(s.Find(selector), htmlAttr)\n\t\tattrV.Set(reflect.Indirect(reflect.ValueOf(val)))\n\tcase reflect.Struct:\n\t\tif err := unmarshalStruct(s, selector, attrV); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase reflect.Ptr:\n\t\tif err := unmarshalPtr(s, selector, attrV); err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\treturn errors.New(\"Invalid type: \" + attrV.String())\n\t}\n\treturn nil\n}\n\nfunc unmarshalStruct(s *goquery.Selection, selector string, attrV reflect.Value) error {\n\tnewS := s\n\tif selector != \"\" {\n\t\tnewS = newS.Find(selector)\n\t}\n\tif newS.Nodes == nil {\n\t\treturn nil\n\t}\n\tv := reflect.New(attrV.Type())\n\terr := UnmarshalHTML(v.Interface(), newS, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tattrV.Set(reflect.Indirect(v))\n\treturn nil\n}\n\nfunc unmarshalPtr(s *goquery.Selection, selector string, attrV reflect.Value) error {\n\tnewS := s\n\tif selector != \"\" {\n\t\tnewS = newS.Find(selector)\n\t}\n\tif newS.Nodes == nil {\n\t\treturn nil\n\t}\n\te := attrV.Type().Elem()\n\tif e.Kind() != reflect.Struct {\n\t\treturn errors.New(\"Invalid slice type\")\n\t}\n\tv := reflect.New(e)\n\terr := UnmarshalHTML(v.Interface(), newS, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\tattrV.Set(v)\n\treturn nil\n}\n\nfunc unmarshalSlice(s *goquery.Selection, selector, htmlAttr string, attrV reflect.Value) error {\n\tif attrV.Pointer() == 0 {\n\t\tv := reflect.MakeSlice(attrV.Type(), 0, 0)\n\t\tattrV.Set(v)\n\t}\n\tswitch attrV.Type().Elem().Kind() {\n\tcase reflect.String:\n\t\ts.Find(selector).Each(func(_ int, s *goquery.Selection) {\n\t\t\tval := getDOMValue(s, htmlAttr)\n\t\t\tattrV.Set(reflect.Append(attrV, reflect.Indirect(reflect.ValueOf(val))))\n\t\t})\n\tcase reflect.Ptr:\n\t\ts.Find(selector).Each(func(_ int, innerSel *goquery.Selection) {\n\t\t\tsomeVal := reflect.New(attrV.Type().Elem().Elem())\n\t\t\tUnmarshalHTML(someVal.Interface(), innerSel, nil)\n\t\t\tattrV.Set(reflect.Append(attrV, someVal))\n\t\t})\n\tcase reflect.Struct:\n\t\ts.Find(selector).Each(func(_ int, innerSel *goquery.Selection) {\n\t\t\tsomeVal := reflect.New(attrV.Type().Elem())\n\t\t\tUnmarshalHTML(someVal.Interface(), innerSel, nil)\n\t\t\tattrV.Set(reflect.Append(attrV, reflect.Indirect(someVal)))\n\t\t})\n\tdefault:\n\t\treturn errors.New(\"Invalid slice type\")\n\t}\n\treturn nil\n}\n\nfunc getDOMValue(s *goquery.Selection, attr string) string {\n\tif attr == \"\" {\n\t\treturn strings.TrimSpace(s.First().Text())\n\t}\n\tattrV, _ := s.Attr(attr)\n\treturn attrV\n}\n"
  },
  {
    "path": "vendor/github.com/gocolly/colly/v2/xmlelement.go",
    "content": "// Copyright 2018 Adam Tauber\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//      http://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\npackage colly\n\nimport (\n\t\"encoding/xml\"\n\t\"strings\"\n\n\t\"github.com/antchfx/htmlquery\"\n\t\"github.com/antchfx/xmlquery\"\n\t\"golang.org/x/net/html\"\n)\n\n// XMLElement is the representation of a XML tag.\ntype XMLElement struct {\n\t// Name is the name of the tag\n\tName       string\n\tText       string\n\tattributes interface{}\n\t// Request is the request object of the element's HTML document\n\tRequest *Request\n\t// Response is the Response object of the element's HTML document\n\tResponse *Response\n\t// DOM is the DOM object of the page. DOM is relative\n\t// to the current XMLElement and is either a html.Node or xmlquery.Node\n\t// based on how the XMLElement was created.\n\tDOM    interface{}\n\tisHTML bool\n}\n\n// NewXMLElementFromHTMLNode creates a XMLElement from a html.Node.\nfunc NewXMLElementFromHTMLNode(resp *Response, s *html.Node) *XMLElement {\n\treturn &XMLElement{\n\t\tName:       s.Data,\n\t\tRequest:    resp.Request,\n\t\tResponse:   resp,\n\t\tText:       htmlquery.InnerText(s),\n\t\tDOM:        s,\n\t\tattributes: s.Attr,\n\t\tisHTML:     true,\n\t}\n}\n\n// NewXMLElementFromXMLNode creates a XMLElement from a xmlquery.Node.\nfunc NewXMLElementFromXMLNode(resp *Response, s *xmlquery.Node) *XMLElement {\n\treturn &XMLElement{\n\t\tName:       s.Data,\n\t\tRequest:    resp.Request,\n\t\tResponse:   resp,\n\t\tText:       s.InnerText(),\n\t\tDOM:        s,\n\t\tattributes: s.Attr,\n\t\tisHTML:     false,\n\t}\n}\n\n// Attr returns the selected attribute of a HTMLElement or empty string\n// if no attribute found\nfunc (h *XMLElement) Attr(k string) string {\n\tif h.isHTML {\n\t\tfor _, a := range h.attributes.([]html.Attribute) {\n\t\t\tif a.Key == k {\n\t\t\t\treturn a.Val\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor _, a := range h.attributes.([]xml.Attr) {\n\t\t\tif a.Name.Local == k {\n\t\t\t\treturn a.Value\n\t\t\t}\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// ChildText returns the concatenated and stripped text content of the matching\n// elements.\nfunc (h *XMLElement) ChildText(xpathQuery string) string {\n\tif h.isHTML {\n\t\tchild := htmlquery.FindOne(h.DOM.(*html.Node), xpathQuery)\n\t\tif child == nil {\n\t\t\treturn \"\"\n\t\t}\n\t\treturn strings.TrimSpace(htmlquery.InnerText(child))\n\t}\n\tchild := xmlquery.FindOne(h.DOM.(*xmlquery.Node), xpathQuery)\n\tif child == nil {\n\t\treturn \"\"\n\t}\n\treturn strings.TrimSpace(child.InnerText())\n\n}\n\n// ChildAttr returns the stripped text content of the first matching\n// element's attribute.\nfunc (h *XMLElement) ChildAttr(xpathQuery, attrName string) string {\n\tif h.isHTML {\n\t\tchild := htmlquery.FindOne(h.DOM.(*html.Node), xpathQuery)\n\t\tif child != nil {\n\t\t\tfor _, attr := range child.Attr {\n\t\t\t\tif attr.Key == attrName {\n\t\t\t\t\treturn strings.TrimSpace(attr.Val)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tchild := xmlquery.FindOne(h.DOM.(*xmlquery.Node), xpathQuery)\n\t\tif child != nil {\n\t\t\tfor _, attr := range child.Attr {\n\t\t\t\tif attr.Name.Local == attrName {\n\t\t\t\t\treturn strings.TrimSpace(attr.Value)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// ChildAttrs returns the stripped text content of all the matching\n// element's attributes.\nfunc (h *XMLElement) ChildAttrs(xpathQuery, attrName string) []string {\n\tvar res []string\n\tif h.isHTML {\n\t\tfor _, child := range htmlquery.Find(h.DOM.(*html.Node), xpathQuery) {\n\t\t\tfor _, attr := range child.Attr {\n\t\t\t\tif attr.Key == attrName {\n\t\t\t\t\tres = append(res, strings.TrimSpace(attr.Val))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\txmlquery.FindEach(h.DOM.(*xmlquery.Node), xpathQuery, func(i int, child *xmlquery.Node) {\n\t\t\tfor _, attr := range child.Attr {\n\t\t\t\tif attr.Name.Local == attrName {\n\t\t\t\t\tres = append(res, strings.TrimSpace(attr.Value))\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n\treturn res\n}\n\n// ChildTexts returns an array of strings corresponding to child elements that match the xpath query.\n// Each item in the array is the stripped text content of the corresponding matching child element.\nfunc (h *XMLElement) ChildTexts(xpathQuery string) []string {\n\ttexts := make([]string, 0)\n\tif h.isHTML {\n\t\tfor _, child := range htmlquery.Find(h.DOM.(*html.Node), xpathQuery) {\n\t\t\ttexts = append(texts, strings.TrimSpace(htmlquery.InnerText(child)))\n\t\t}\n\t} else {\n\t\txmlquery.FindEach(h.DOM.(*xmlquery.Node), xpathQuery, func(i int, child *xmlquery.Node) {\n\t\t\ttexts = append(texts, strings.TrimSpace(child.InnerText()))\n\t\t})\n\t}\n\treturn texts\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/AUTHORS",
    "content": "# This is the official list of GoGo authors for copyright purposes.\n# This file is distinct from the CONTRIBUTORS file, which\n# lists people.  For example, employees are listed in CONTRIBUTORS,\n# but not in AUTHORS, because the employer holds the copyright.\n\n# Names should be added to this file as one of\n#     Organization's name\n#     Individual's name <submission email address>\n#     Individual's name <submission email address> <email2> <emailN>\n\n# Please keep the list sorted.\n\nSendgrid, Inc\nVastech SA (PTY) LTD\nWalter Schulze <awalterschulze@gmail.com>\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/CONTRIBUTORS",
    "content": "Anton Povarov <anton.povarov@gmail.com>\nBrian Goff <cpuguy83@gmail.com>\nClayton Coleman <ccoleman@redhat.com>\nDenis Smirnov <denis.smirnov.91@gmail.com>\nDongYun Kang <ceram1000@gmail.com>\nDwayne Schultz <dschultz@pivotal.io>\nGeorg Apitz <gapitz@pivotal.io>\nGustav Paul <gustav.paul@gmail.com>\nJohan Brandhorst <johan.brandhorst@gmail.com>\nJohn Shahid <jvshahid@gmail.com>\nJohn Tuley <john@tuley.org>\nLaurent <laurent@adyoulike.com>\nPatrick Lee <patrick@dropbox.com>\nPeter Edge <peter.edge@gmail.com>\nRoger Johansson <rogeralsing@gmail.com>\nSam Nguyen <sam.nguyen@sendgrid.com>\nSergio Arbeo <serabe@gmail.com>\nStephen J Day <stephen.day@docker.com>\nTamir Duberstein <tamird@gmail.com>\nTodd Eisenberger <teisenberger@dropbox.com>\nTormod Erevik Lea <tormodlea@gmail.com>\nVyacheslav Kim <kane@sendgrid.com>\nWalter Schulze <awalterschulze@gmail.com>\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/LICENSE",
    "content": "Copyright (c) 2013, The GoGo Authors. All rights reserved.\n\nProtocol Buffers for Go with Gadgets\n\nGo support for Protocol Buffers - Google's data interchange format\n\nCopyright 2010 The Go Authors.  All rights reserved.\nhttps://github.com/golang/protobuf\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * 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    * 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\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/Makefile",
    "content": "# Go support for Protocol Buffers - Google's data interchange format\n#\n# Copyright 2010 The Go Authors.  All rights reserved.\n# https://github.com/golang/protobuf\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions are\n# met:\n#\n#     * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#     * Redistributions in binary form must reproduce the above\n# copyright notice, this list of conditions and the following disclaimer\n# in the documentation and/or other materials provided with the\n# distribution.\n#     * Neither the name of Google Inc. nor the names of its\n# contributors may be used to endorse or promote products derived from\n# this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\ninstall:\n\tgo install\n\ntest: install generate-test-pbs\n\tgo test\n\n\ngenerate-test-pbs:\n\tmake install\n\tmake -C test_proto\n\tmake -C proto3_proto\n\tmake\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/clone.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2011 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Protocol buffer deep copy and merge.\n// TODO: RawMessage.\n\npackage proto\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// Clone returns a deep copy of a protocol buffer.\nfunc Clone(src Message) Message {\n\tin := reflect.ValueOf(src)\n\tif in.IsNil() {\n\t\treturn src\n\t}\n\tout := reflect.New(in.Type().Elem())\n\tdst := out.Interface().(Message)\n\tMerge(dst, src)\n\treturn dst\n}\n\n// Merger is the interface representing objects that can merge messages of the same type.\ntype Merger interface {\n\t// Merge merges src into this message.\n\t// Required and optional fields that are set in src will be set to that value in dst.\n\t// Elements of repeated fields will be appended.\n\t//\n\t// Merge may panic if called with a different argument type than the receiver.\n\tMerge(src Message)\n}\n\n// generatedMerger is the custom merge method that generated protos will have.\n// We must add this method since a generate Merge method will conflict with\n// many existing protos that have a Merge data field already defined.\ntype generatedMerger interface {\n\tXXX_Merge(src Message)\n}\n\n// Merge merges src into dst.\n// Required and optional fields that are set in src will be set to that value in dst.\n// Elements of repeated fields will be appended.\n// Merge panics if src and dst are not the same type, or if dst is nil.\nfunc Merge(dst, src Message) {\n\tif m, ok := dst.(Merger); ok {\n\t\tm.Merge(src)\n\t\treturn\n\t}\n\n\tin := reflect.ValueOf(src)\n\tout := reflect.ValueOf(dst)\n\tif out.IsNil() {\n\t\tpanic(\"proto: nil destination\")\n\t}\n\tif in.Type() != out.Type() {\n\t\tpanic(fmt.Sprintf(\"proto.Merge(%T, %T) type mismatch\", dst, src))\n\t}\n\tif in.IsNil() {\n\t\treturn // Merge from nil src is a noop\n\t}\n\tif m, ok := dst.(generatedMerger); ok {\n\t\tm.XXX_Merge(src)\n\t\treturn\n\t}\n\tmergeStruct(out.Elem(), in.Elem())\n}\n\nfunc mergeStruct(out, in reflect.Value) {\n\tsprop := GetProperties(in.Type())\n\tfor i := 0; i < in.NumField(); i++ {\n\t\tf := in.Type().Field(i)\n\t\tif strings.HasPrefix(f.Name, \"XXX_\") {\n\t\t\tcontinue\n\t\t}\n\t\tmergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])\n\t}\n\n\tif emIn, ok := in.Addr().Interface().(extensionsBytes); ok {\n\t\temOut := out.Addr().Interface().(extensionsBytes)\n\t\tbIn := emIn.GetExtensions()\n\t\tbOut := emOut.GetExtensions()\n\t\t*bOut = append(*bOut, *bIn...)\n\t} else if emIn, err := extendable(in.Addr().Interface()); err == nil {\n\t\temOut, _ := extendable(out.Addr().Interface())\n\t\tmIn, muIn := emIn.extensionsRead()\n\t\tif mIn != nil {\n\t\t\tmOut := emOut.extensionsWrite()\n\t\t\tmuIn.Lock()\n\t\t\tmergeExtension(mOut, mIn)\n\t\t\tmuIn.Unlock()\n\t\t}\n\t}\n\n\tuf := in.FieldByName(\"XXX_unrecognized\")\n\tif !uf.IsValid() {\n\t\treturn\n\t}\n\tuin := uf.Bytes()\n\tif len(uin) > 0 {\n\t\tout.FieldByName(\"XXX_unrecognized\").SetBytes(append([]byte(nil), uin...))\n\t}\n}\n\n// mergeAny performs a merge between two values of the same type.\n// viaPtr indicates whether the values were indirected through a pointer (implying proto2).\n// prop is set if this is a struct field (it may be nil).\nfunc mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {\n\tif in.Type() == protoMessageType {\n\t\tif !in.IsNil() {\n\t\t\tif out.IsNil() {\n\t\t\t\tout.Set(reflect.ValueOf(Clone(in.Interface().(Message))))\n\t\t\t} else {\n\t\t\t\tMerge(out.Interface().(Message), in.Interface().(Message))\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\tswitch in.Kind() {\n\tcase reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,\n\t\treflect.String, reflect.Uint32, reflect.Uint64:\n\t\tif !viaPtr && isProto3Zero(in) {\n\t\t\treturn\n\t\t}\n\t\tout.Set(in)\n\tcase reflect.Interface:\n\t\t// Probably a oneof field; copy non-nil values.\n\t\tif in.IsNil() {\n\t\t\treturn\n\t\t}\n\t\t// Allocate destination if it is not set, or set to a different type.\n\t\t// Otherwise we will merge as normal.\n\t\tif out.IsNil() || out.Elem().Type() != in.Elem().Type() {\n\t\t\tout.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)\n\t\t}\n\t\tmergeAny(out.Elem(), in.Elem(), false, nil)\n\tcase reflect.Map:\n\t\tif in.Len() == 0 {\n\t\t\treturn\n\t\t}\n\t\tif out.IsNil() {\n\t\t\tout.Set(reflect.MakeMap(in.Type()))\n\t\t}\n\t\t// For maps with value types of *T or []byte we need to deep copy each value.\n\t\telemKind := in.Type().Elem().Kind()\n\t\tfor _, key := range in.MapKeys() {\n\t\t\tvar val reflect.Value\n\t\t\tswitch elemKind {\n\t\t\tcase reflect.Ptr:\n\t\t\t\tval = reflect.New(in.Type().Elem().Elem())\n\t\t\t\tmergeAny(val, in.MapIndex(key), false, nil)\n\t\t\tcase reflect.Slice:\n\t\t\t\tval = in.MapIndex(key)\n\t\t\t\tval = reflect.ValueOf(append([]byte{}, val.Bytes()...))\n\t\t\tdefault:\n\t\t\t\tval = in.MapIndex(key)\n\t\t\t}\n\t\t\tout.SetMapIndex(key, val)\n\t\t}\n\tcase reflect.Ptr:\n\t\tif in.IsNil() {\n\t\t\treturn\n\t\t}\n\t\tif out.IsNil() {\n\t\t\tout.Set(reflect.New(in.Elem().Type()))\n\t\t}\n\t\tmergeAny(out.Elem(), in.Elem(), true, nil)\n\tcase reflect.Slice:\n\t\tif in.IsNil() {\n\t\t\treturn\n\t\t}\n\t\tif in.Type().Elem().Kind() == reflect.Uint8 {\n\t\t\t// []byte is a scalar bytes field, not a repeated field.\n\n\t\t\t// Edge case: if this is in a proto3 message, a zero length\n\t\t\t// bytes field is considered the zero value, and should not\n\t\t\t// be merged.\n\t\t\tif prop != nil && prop.proto3 && in.Len() == 0 {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Make a deep copy.\n\t\t\t// Append to []byte{} instead of []byte(nil) so that we never end up\n\t\t\t// with a nil result.\n\t\t\tout.SetBytes(append([]byte{}, in.Bytes()...))\n\t\t\treturn\n\t\t}\n\t\tn := in.Len()\n\t\tif out.IsNil() {\n\t\t\tout.Set(reflect.MakeSlice(in.Type(), 0, n))\n\t\t}\n\t\tswitch in.Type().Elem().Kind() {\n\t\tcase reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,\n\t\t\treflect.String, reflect.Uint32, reflect.Uint64:\n\t\t\tout.Set(reflect.AppendSlice(out, in))\n\t\tdefault:\n\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\tx := reflect.Indirect(reflect.New(in.Type().Elem()))\n\t\t\t\tmergeAny(x, in.Index(i), false, nil)\n\t\t\t\tout.Set(reflect.Append(out, x))\n\t\t\t}\n\t\t}\n\tcase reflect.Struct:\n\t\tmergeStruct(out, in)\n\tdefault:\n\t\t// unknown type, so not a protocol buffer\n\t\tlog.Printf(\"proto: don't know how to copy %v\", in)\n\t}\n}\n\nfunc mergeExtension(out, in map[int32]Extension) {\n\tfor extNum, eIn := range in {\n\t\teOut := Extension{desc: eIn.desc}\n\t\tif eIn.value != nil {\n\t\t\tv := reflect.New(reflect.TypeOf(eIn.value)).Elem()\n\t\t\tmergeAny(v, reflect.ValueOf(eIn.value), false, nil)\n\t\t\teOut.value = v.Interface()\n\t\t}\n\t\tif eIn.enc != nil {\n\t\t\teOut.enc = make([]byte, len(eIn.enc))\n\t\t\tcopy(eOut.enc, eIn.enc)\n\t\t}\n\n\t\tout[extNum] = eOut\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/custom_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport \"reflect\"\n\ntype custom interface {\n\tMarshal() ([]byte, error)\n\tUnmarshal(data []byte) error\n\tSize() int\n}\n\nvar customType = reflect.TypeOf((*custom)(nil)).Elem()\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/decode.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n/*\n * Routines for decoding protocol buffer data to construct in-memory representations.\n */\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// errOverflow is returned when an integer is too large to be represented.\nvar errOverflow = errors.New(\"proto: integer overflow\")\n\n// ErrInternalBadWireType is returned by generated code when an incorrect\n// wire type is encountered. It does not get returned to user code.\nvar ErrInternalBadWireType = errors.New(\"proto: internal error: bad wiretype for oneof\")\n\n// DecodeVarint reads a varint-encoded integer from the slice.\n// It returns the integer and the number of bytes consumed, or\n// zero if there is not enough.\n// This is the format for the\n// int32, int64, uint32, uint64, bool, and enum\n// protocol buffer types.\nfunc DecodeVarint(buf []byte) (x uint64, n int) {\n\tfor shift := uint(0); shift < 64; shift += 7 {\n\t\tif n >= len(buf) {\n\t\t\treturn 0, 0\n\t\t}\n\t\tb := uint64(buf[n])\n\t\tn++\n\t\tx |= (b & 0x7F) << shift\n\t\tif (b & 0x80) == 0 {\n\t\t\treturn x, n\n\t\t}\n\t}\n\n\t// The number is too large to represent in a 64-bit value.\n\treturn 0, 0\n}\n\nfunc (p *Buffer) decodeVarintSlow() (x uint64, err error) {\n\ti := p.index\n\tl := len(p.buf)\n\n\tfor shift := uint(0); shift < 64; shift += 7 {\n\t\tif i >= l {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t\treturn\n\t\t}\n\t\tb := p.buf[i]\n\t\ti++\n\t\tx |= (uint64(b) & 0x7F) << shift\n\t\tif b < 0x80 {\n\t\t\tp.index = i\n\t\t\treturn\n\t\t}\n\t}\n\n\t// The number is too large to represent in a 64-bit value.\n\terr = errOverflow\n\treturn\n}\n\n// DecodeVarint reads a varint-encoded integer from the Buffer.\n// This is the format for the\n// int32, int64, uint32, uint64, bool, and enum\n// protocol buffer types.\nfunc (p *Buffer) DecodeVarint() (x uint64, err error) {\n\ti := p.index\n\tbuf := p.buf\n\n\tif i >= len(buf) {\n\t\treturn 0, io.ErrUnexpectedEOF\n\t} else if buf[i] < 0x80 {\n\t\tp.index++\n\t\treturn uint64(buf[i]), nil\n\t} else if len(buf)-i < 10 {\n\t\treturn p.decodeVarintSlow()\n\t}\n\n\tvar b uint64\n\t// we already checked the first byte\n\tx = uint64(buf[i]) - 0x80\n\ti++\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 7\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 7\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 14\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 14\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 21\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 21\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 28\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 28\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 35\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 35\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 42\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 42\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 49\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 49\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 56\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\tx -= 0x80 << 56\n\n\tb = uint64(buf[i])\n\ti++\n\tx += b << 63\n\tif b&0x80 == 0 {\n\t\tgoto done\n\t}\n\n\treturn 0, errOverflow\n\ndone:\n\tp.index = i\n\treturn x, nil\n}\n\n// DecodeFixed64 reads a 64-bit integer from the Buffer.\n// This is the format for the\n// fixed64, sfixed64, and double protocol buffer types.\nfunc (p *Buffer) DecodeFixed64() (x uint64, err error) {\n\t// x, err already 0\n\ti := p.index + 8\n\tif i < 0 || i > len(p.buf) {\n\t\terr = io.ErrUnexpectedEOF\n\t\treturn\n\t}\n\tp.index = i\n\n\tx = uint64(p.buf[i-8])\n\tx |= uint64(p.buf[i-7]) << 8\n\tx |= uint64(p.buf[i-6]) << 16\n\tx |= uint64(p.buf[i-5]) << 24\n\tx |= uint64(p.buf[i-4]) << 32\n\tx |= uint64(p.buf[i-3]) << 40\n\tx |= uint64(p.buf[i-2]) << 48\n\tx |= uint64(p.buf[i-1]) << 56\n\treturn\n}\n\n// DecodeFixed32 reads a 32-bit integer from the Buffer.\n// This is the format for the\n// fixed32, sfixed32, and float protocol buffer types.\nfunc (p *Buffer) DecodeFixed32() (x uint64, err error) {\n\t// x, err already 0\n\ti := p.index + 4\n\tif i < 0 || i > len(p.buf) {\n\t\terr = io.ErrUnexpectedEOF\n\t\treturn\n\t}\n\tp.index = i\n\n\tx = uint64(p.buf[i-4])\n\tx |= uint64(p.buf[i-3]) << 8\n\tx |= uint64(p.buf[i-2]) << 16\n\tx |= uint64(p.buf[i-1]) << 24\n\treturn\n}\n\n// DecodeZigzag64 reads a zigzag-encoded 64-bit integer\n// from the Buffer.\n// This is the format used for the sint64 protocol buffer type.\nfunc (p *Buffer) DecodeZigzag64() (x uint64, err error) {\n\tx, err = p.DecodeVarint()\n\tif err != nil {\n\t\treturn\n\t}\n\tx = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)\n\treturn\n}\n\n// DecodeZigzag32 reads a zigzag-encoded 32-bit integer\n// from  the Buffer.\n// This is the format used for the sint32 protocol buffer type.\nfunc (p *Buffer) DecodeZigzag32() (x uint64, err error) {\n\tx, err = p.DecodeVarint()\n\tif err != nil {\n\t\treturn\n\t}\n\tx = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))\n\treturn\n}\n\n// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.\n// This is the format used for the bytes protocol buffer\n// type and for embedded messages.\nfunc (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {\n\tn, err := p.DecodeVarint()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tnb := int(n)\n\tif nb < 0 {\n\t\treturn nil, fmt.Errorf(\"proto: bad byte length %d\", nb)\n\t}\n\tend := p.index + nb\n\tif end < p.index || end > len(p.buf) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\n\tif !alloc {\n\t\t// todo: check if can get more uses of alloc=false\n\t\tbuf = p.buf[p.index:end]\n\t\tp.index += nb\n\t\treturn\n\t}\n\n\tbuf = make([]byte, nb)\n\tcopy(buf, p.buf[p.index:])\n\tp.index += nb\n\treturn\n}\n\n// DecodeStringBytes reads an encoded string from the Buffer.\n// This is the format used for the proto2 string type.\nfunc (p *Buffer) DecodeStringBytes() (s string, err error) {\n\tbuf, err := p.DecodeRawBytes(false)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn string(buf), nil\n}\n\n// Unmarshaler is the interface representing objects that can\n// unmarshal themselves.  The argument points to data that may be\n// overwritten, so implementations should not keep references to the\n// buffer.\n// Unmarshal implementations should not clear the receiver.\n// Any unmarshaled data should be merged into the receiver.\n// Callers of Unmarshal that do not want to retain existing data\n// should Reset the receiver before calling Unmarshal.\ntype Unmarshaler interface {\n\tUnmarshal([]byte) error\n}\n\n// newUnmarshaler is the interface representing objects that can\n// unmarshal themselves. The semantics are identical to Unmarshaler.\n//\n// This exists to support protoc-gen-go generated messages.\n// The proto package will stop type-asserting to this interface in the future.\n//\n// DO NOT DEPEND ON THIS.\ntype newUnmarshaler interface {\n\tXXX_Unmarshal([]byte) error\n}\n\n// Unmarshal parses the protocol buffer representation in buf and places the\n// decoded result in pb.  If the struct underlying pb does not match\n// the data in buf, the results can be unpredictable.\n//\n// Unmarshal resets pb before starting to unmarshal, so any\n// existing data in pb is always removed. Use UnmarshalMerge\n// to preserve and append to existing data.\nfunc Unmarshal(buf []byte, pb Message) error {\n\tpb.Reset()\n\tif u, ok := pb.(newUnmarshaler); ok {\n\t\treturn u.XXX_Unmarshal(buf)\n\t}\n\tif u, ok := pb.(Unmarshaler); ok {\n\t\treturn u.Unmarshal(buf)\n\t}\n\treturn NewBuffer(buf).Unmarshal(pb)\n}\n\n// UnmarshalMerge parses the protocol buffer representation in buf and\n// writes the decoded result to pb.  If the struct underlying pb does not match\n// the data in buf, the results can be unpredictable.\n//\n// UnmarshalMerge merges into existing data in pb.\n// Most code should use Unmarshal instead.\nfunc UnmarshalMerge(buf []byte, pb Message) error {\n\tif u, ok := pb.(newUnmarshaler); ok {\n\t\treturn u.XXX_Unmarshal(buf)\n\t}\n\tif u, ok := pb.(Unmarshaler); ok {\n\t\t// NOTE: The history of proto have unfortunately been inconsistent\n\t\t// whether Unmarshaler should or should not implicitly clear itself.\n\t\t// Some implementations do, most do not.\n\t\t// Thus, calling this here may or may not do what people want.\n\t\t//\n\t\t// See https://github.com/golang/protobuf/issues/424\n\t\treturn u.Unmarshal(buf)\n\t}\n\treturn NewBuffer(buf).Unmarshal(pb)\n}\n\n// DecodeMessage reads a count-delimited message from the Buffer.\nfunc (p *Buffer) DecodeMessage(pb Message) error {\n\tenc, err := p.DecodeRawBytes(false)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn NewBuffer(enc).Unmarshal(pb)\n}\n\n// DecodeGroup reads a tag-delimited group from the Buffer.\n// StartGroup tag is already consumed. This function consumes\n// EndGroup tag.\nfunc (p *Buffer) DecodeGroup(pb Message) error {\n\tb := p.buf[p.index:]\n\tx, y := findEndGroup(b)\n\tif x < 0 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\terr := Unmarshal(b[:x], pb)\n\tp.index += y\n\treturn err\n}\n\n// Unmarshal parses the protocol buffer representation in the\n// Buffer and places the decoded result in pb.  If the struct\n// underlying pb does not match the data in the buffer, the results can be\n// unpredictable.\n//\n// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.\nfunc (p *Buffer) Unmarshal(pb Message) error {\n\t// If the object can unmarshal itself, let it.\n\tif u, ok := pb.(newUnmarshaler); ok {\n\t\terr := u.XXX_Unmarshal(p.buf[p.index:])\n\t\tp.index = len(p.buf)\n\t\treturn err\n\t}\n\tif u, ok := pb.(Unmarshaler); ok {\n\t\t// NOTE: The history of proto have unfortunately been inconsistent\n\t\t// whether Unmarshaler should or should not implicitly clear itself.\n\t\t// Some implementations do, most do not.\n\t\t// Thus, calling this here may or may not do what people want.\n\t\t//\n\t\t// See https://github.com/golang/protobuf/issues/424\n\t\terr := u.Unmarshal(p.buf[p.index:])\n\t\tp.index = len(p.buf)\n\t\treturn err\n\t}\n\n\t// Slow workaround for messages that aren't Unmarshalers.\n\t// This includes some hand-coded .pb.go files and\n\t// bootstrap protos.\n\t// TODO: fix all of those and then add Unmarshal to\n\t// the Message interface. Then:\n\t// The cast above and code below can be deleted.\n\t// The old unmarshaler can be deleted.\n\t// Clients can call Unmarshal directly (can already do that, actually).\n\tvar info InternalMessageInfo\n\terr := info.Unmarshal(pb, p.buf[p.index:])\n\tp.index = len(p.buf)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/deprecated.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2018 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport \"errors\"\n\n// Deprecated: do not use.\ntype Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }\n\n// Deprecated: do not use.\nfunc GetStats() Stats { return Stats{} }\n\n// Deprecated: do not use.\nfunc MarshalMessageSet(interface{}) ([]byte, error) {\n\treturn nil, errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: do not use.\nfunc UnmarshalMessageSet([]byte, interface{}) error {\n\treturn errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: do not use.\nfunc MarshalMessageSetJSON(interface{}) ([]byte, error) {\n\treturn nil, errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: do not use.\nfunc UnmarshalMessageSetJSON([]byte, interface{}) error {\n\treturn errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: do not use.\nfunc RegisterMessageSetType(Message, int32, string) {}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/discard.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2017 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\ntype generatedDiscarder interface {\n\tXXX_DiscardUnknown()\n}\n\n// DiscardUnknown recursively discards all unknown fields from this message\n// and all embedded messages.\n//\n// When unmarshaling a message with unrecognized fields, the tags and values\n// of such fields are preserved in the Message. This allows a later call to\n// marshal to be able to produce a message that continues to have those\n// unrecognized fields. To avoid this, DiscardUnknown is used to\n// explicitly clear the unknown fields after unmarshaling.\n//\n// For proto2 messages, the unknown fields of message extensions are only\n// discarded from messages that have been accessed via GetExtension.\nfunc DiscardUnknown(m Message) {\n\tif m, ok := m.(generatedDiscarder); ok {\n\t\tm.XXX_DiscardUnknown()\n\t\treturn\n\t}\n\t// TODO: Dynamically populate a InternalMessageInfo for legacy messages,\n\t// but the master branch has no implementation for InternalMessageInfo,\n\t// so it would be more work to replicate that approach.\n\tdiscardLegacy(m)\n}\n\n// DiscardUnknown recursively discards all unknown fields.\nfunc (a *InternalMessageInfo) DiscardUnknown(m Message) {\n\tdi := atomicLoadDiscardInfo(&a.discard)\n\tif di == nil {\n\t\tdi = getDiscardInfo(reflect.TypeOf(m).Elem())\n\t\tatomicStoreDiscardInfo(&a.discard, di)\n\t}\n\tdi.discard(toPointer(&m))\n}\n\ntype discardInfo struct {\n\ttyp reflect.Type\n\n\tinitialized int32 // 0: only typ is valid, 1: everything is valid\n\tlock        sync.Mutex\n\n\tfields       []discardFieldInfo\n\tunrecognized field\n}\n\ntype discardFieldInfo struct {\n\tfield   field // Offset of field, guaranteed to be valid\n\tdiscard func(src pointer)\n}\n\nvar (\n\tdiscardInfoMap  = map[reflect.Type]*discardInfo{}\n\tdiscardInfoLock sync.Mutex\n)\n\nfunc getDiscardInfo(t reflect.Type) *discardInfo {\n\tdiscardInfoLock.Lock()\n\tdefer discardInfoLock.Unlock()\n\tdi := discardInfoMap[t]\n\tif di == nil {\n\t\tdi = &discardInfo{typ: t}\n\t\tdiscardInfoMap[t] = di\n\t}\n\treturn di\n}\n\nfunc (di *discardInfo) discard(src pointer) {\n\tif src.isNil() {\n\t\treturn // Nothing to do.\n\t}\n\n\tif atomic.LoadInt32(&di.initialized) == 0 {\n\t\tdi.computeDiscardInfo()\n\t}\n\n\tfor _, fi := range di.fields {\n\t\tsfp := src.offset(fi.field)\n\t\tfi.discard(sfp)\n\t}\n\n\t// For proto2 messages, only discard unknown fields in message extensions\n\t// that have been accessed via GetExtension.\n\tif em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {\n\t\t// Ignore lock since DiscardUnknown is not concurrency safe.\n\t\temm, _ := em.extensionsRead()\n\t\tfor _, mx := range emm {\n\t\t\tif m, ok := mx.value.(Message); ok {\n\t\t\t\tDiscardUnknown(m)\n\t\t\t}\n\t\t}\n\t}\n\n\tif di.unrecognized.IsValid() {\n\t\t*src.offset(di.unrecognized).toBytes() = nil\n\t}\n}\n\nfunc (di *discardInfo) computeDiscardInfo() {\n\tdi.lock.Lock()\n\tdefer di.lock.Unlock()\n\tif di.initialized != 0 {\n\t\treturn\n\t}\n\tt := di.typ\n\tn := t.NumField()\n\n\tfor i := 0; i < n; i++ {\n\t\tf := t.Field(i)\n\t\tif strings.HasPrefix(f.Name, \"XXX_\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tdfi := discardFieldInfo{field: toField(&f)}\n\t\ttf := f.Type\n\n\t\t// Unwrap tf to get its most basic type.\n\t\tvar isPointer, isSlice bool\n\t\tif tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {\n\t\t\tisSlice = true\n\t\t\ttf = tf.Elem()\n\t\t}\n\t\tif tf.Kind() == reflect.Ptr {\n\t\t\tisPointer = true\n\t\t\ttf = tf.Elem()\n\t\t}\n\t\tif isPointer && isSlice && tf.Kind() != reflect.Struct {\n\t\t\tpanic(fmt.Sprintf(\"%v.%s cannot be a slice of pointers to primitive types\", t, f.Name))\n\t\t}\n\n\t\tswitch tf.Kind() {\n\t\tcase reflect.Struct:\n\t\t\tswitch {\n\t\t\tcase !isPointer:\n\t\t\t\tpanic(fmt.Sprintf(\"%v.%s cannot be a direct struct value\", t, f.Name))\n\t\t\tcase isSlice: // E.g., []*pb.T\n\t\t\t\tdiscardInfo := getDiscardInfo(tf)\n\t\t\t\tdfi.discard = func(src pointer) {\n\t\t\t\t\tsps := src.getPointerSlice()\n\t\t\t\t\tfor _, sp := range sps {\n\t\t\t\t\t\tif !sp.isNil() {\n\t\t\t\t\t\t\tdiscardInfo.discard(sp)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., *pb.T\n\t\t\t\tdiscardInfo := getDiscardInfo(tf)\n\t\t\t\tdfi.discard = func(src pointer) {\n\t\t\t\t\tsp := src.getPointer()\n\t\t\t\t\tif !sp.isNil() {\n\t\t\t\t\t\tdiscardInfo.discard(sp)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Map:\n\t\t\tswitch {\n\t\t\tcase isPointer || isSlice:\n\t\t\t\tpanic(fmt.Sprintf(\"%v.%s cannot be a pointer to a map or a slice of map values\", t, f.Name))\n\t\t\tdefault: // E.g., map[K]V\n\t\t\t\tif tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)\n\t\t\t\t\tdfi.discard = func(src pointer) {\n\t\t\t\t\t\tsm := src.asPointerTo(tf).Elem()\n\t\t\t\t\t\tif sm.Len() == 0 {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor _, key := range sm.MapKeys() {\n\t\t\t\t\t\t\tval := sm.MapIndex(key)\n\t\t\t\t\t\t\tDiscardUnknown(val.Interface().(Message))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tdfi.discard = func(pointer) {} // Noop\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Interface:\n\t\t\t// Must be oneof field.\n\t\t\tswitch {\n\t\t\tcase isPointer || isSlice:\n\t\t\t\tpanic(fmt.Sprintf(\"%v.%s cannot be a pointer to a interface or a slice of interface values\", t, f.Name))\n\t\t\tdefault: // E.g., interface{}\n\t\t\t\t// TODO: Make this faster?\n\t\t\t\tdfi.discard = func(src pointer) {\n\t\t\t\t\tsu := src.asPointerTo(tf).Elem()\n\t\t\t\t\tif !su.IsNil() {\n\t\t\t\t\t\tsv := su.Elem().Elem().Field(0)\n\t\t\t\t\t\tif sv.Kind() == reflect.Ptr && sv.IsNil() {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch sv.Type().Kind() {\n\t\t\t\t\t\tcase reflect.Ptr: // Proto struct (e.g., *T)\n\t\t\t\t\t\t\tDiscardUnknown(sv.Interface().(Message))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\t\tdi.fields = append(di.fields, dfi)\n\t}\n\n\tdi.unrecognized = invalidField\n\tif f, ok := t.FieldByName(\"XXX_unrecognized\"); ok {\n\t\tif f.Type != reflect.TypeOf([]byte{}) {\n\t\t\tpanic(\"expected XXX_unrecognized to be of type []byte\")\n\t\t}\n\t\tdi.unrecognized = toField(&f)\n\t}\n\n\tatomic.StoreInt32(&di.initialized, 1)\n}\n\nfunc discardLegacy(m Message) {\n\tv := reflect.ValueOf(m)\n\tif v.Kind() != reflect.Ptr || v.IsNil() {\n\t\treturn\n\t}\n\tv = v.Elem()\n\tif v.Kind() != reflect.Struct {\n\t\treturn\n\t}\n\tt := v.Type()\n\n\tfor i := 0; i < v.NumField(); i++ {\n\t\tf := t.Field(i)\n\t\tif strings.HasPrefix(f.Name, \"XXX_\") {\n\t\t\tcontinue\n\t\t}\n\t\tvf := v.Field(i)\n\t\ttf := f.Type\n\n\t\t// Unwrap tf to get its most basic type.\n\t\tvar isPointer, isSlice bool\n\t\tif tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {\n\t\t\tisSlice = true\n\t\t\ttf = tf.Elem()\n\t\t}\n\t\tif tf.Kind() == reflect.Ptr {\n\t\t\tisPointer = true\n\t\t\ttf = tf.Elem()\n\t\t}\n\t\tif isPointer && isSlice && tf.Kind() != reflect.Struct {\n\t\t\tpanic(fmt.Sprintf(\"%T.%s cannot be a slice of pointers to primitive types\", m, f.Name))\n\t\t}\n\n\t\tswitch tf.Kind() {\n\t\tcase reflect.Struct:\n\t\t\tswitch {\n\t\t\tcase !isPointer:\n\t\t\t\tpanic(fmt.Sprintf(\"%T.%s cannot be a direct struct value\", m, f.Name))\n\t\t\tcase isSlice: // E.g., []*pb.T\n\t\t\t\tfor j := 0; j < vf.Len(); j++ {\n\t\t\t\t\tdiscardLegacy(vf.Index(j).Interface().(Message))\n\t\t\t\t}\n\t\t\tdefault: // E.g., *pb.T\n\t\t\t\tdiscardLegacy(vf.Interface().(Message))\n\t\t\t}\n\t\tcase reflect.Map:\n\t\t\tswitch {\n\t\t\tcase isPointer || isSlice:\n\t\t\t\tpanic(fmt.Sprintf(\"%T.%s cannot be a pointer to a map or a slice of map values\", m, f.Name))\n\t\t\tdefault: // E.g., map[K]V\n\t\t\t\ttv := vf.Type().Elem()\n\t\t\t\tif tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T)\n\t\t\t\t\tfor _, key := range vf.MapKeys() {\n\t\t\t\t\t\tval := vf.MapIndex(key)\n\t\t\t\t\t\tdiscardLegacy(val.Interface().(Message))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Interface:\n\t\t\t// Must be oneof field.\n\t\t\tswitch {\n\t\t\tcase isPointer || isSlice:\n\t\t\t\tpanic(fmt.Sprintf(\"%T.%s cannot be a pointer to a interface or a slice of interface values\", m, f.Name))\n\t\t\tdefault: // E.g., test_proto.isCommunique_Union interface\n\t\t\t\tif !vf.IsNil() && f.Tag.Get(\"protobuf_oneof\") != \"\" {\n\t\t\t\t\tvf = vf.Elem() // E.g., *test_proto.Communique_Msg\n\t\t\t\t\tif !vf.IsNil() {\n\t\t\t\t\t\tvf = vf.Elem()   // E.g., test_proto.Communique_Msg\n\t\t\t\t\t\tvf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value\n\t\t\t\t\t\tif vf.Kind() == reflect.Ptr {\n\t\t\t\t\t\t\tdiscardLegacy(vf.Interface().(Message))\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\tif vf := v.FieldByName(\"XXX_unrecognized\"); vf.IsValid() {\n\t\tif vf.Type() != reflect.TypeOf([]byte{}) {\n\t\t\tpanic(\"expected XXX_unrecognized to be of type []byte\")\n\t\t}\n\t\tvf.Set(reflect.ValueOf([]byte(nil)))\n\t}\n\n\t// For proto2 messages, only discard unknown fields in message extensions\n\t// that have been accessed via GetExtension.\n\tif em, err := extendable(m); err == nil {\n\t\t// Ignore lock since discardLegacy is not concurrency safe.\n\t\temm, _ := em.extensionsRead()\n\t\tfor _, mx := range emm {\n\t\t\tif m, ok := mx.value.(Message); ok {\n\t\t\t\tdiscardLegacy(m)\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/duration.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2016 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n// This file implements conversions between google.protobuf.Duration\n// and time.Duration.\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n)\n\nconst (\n\t// Range of a Duration in seconds, as specified in\n\t// google/protobuf/duration.proto. This is about 10,000 years in seconds.\n\tmaxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)\n\tminSeconds = -maxSeconds\n)\n\n// validateDuration determines whether the Duration is valid according to the\n// definition in google/protobuf/duration.proto. A valid Duration\n// may still be too large to fit into a time.Duration (the range of Duration\n// is about 10,000 years, and the range of time.Duration is about 290).\nfunc validateDuration(d *duration) error {\n\tif d == nil {\n\t\treturn errors.New(\"duration: nil Duration\")\n\t}\n\tif d.Seconds < minSeconds || d.Seconds > maxSeconds {\n\t\treturn fmt.Errorf(\"duration: %#v: seconds out of range\", d)\n\t}\n\tif d.Nanos <= -1e9 || d.Nanos >= 1e9 {\n\t\treturn fmt.Errorf(\"duration: %#v: nanos out of range\", d)\n\t}\n\t// Seconds and Nanos must have the same sign, unless d.Nanos is zero.\n\tif (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {\n\t\treturn fmt.Errorf(\"duration: %#v: seconds and nanos have different signs\", d)\n\t}\n\treturn nil\n}\n\n// DurationFromProto converts a Duration to a time.Duration. DurationFromProto\n// returns an error if the Duration is invalid or is too large to be\n// represented in a time.Duration.\nfunc durationFromProto(p *duration) (time.Duration, error) {\n\tif err := validateDuration(p); err != nil {\n\t\treturn 0, err\n\t}\n\td := time.Duration(p.Seconds) * time.Second\n\tif int64(d/time.Second) != p.Seconds {\n\t\treturn 0, fmt.Errorf(\"duration: %#v is out of range for time.Duration\", p)\n\t}\n\tif p.Nanos != 0 {\n\t\td += time.Duration(p.Nanos)\n\t\tif (d < 0) != (p.Nanos < 0) {\n\t\t\treturn 0, fmt.Errorf(\"duration: %#v is out of range for time.Duration\", p)\n\t\t}\n\t}\n\treturn d, nil\n}\n\n// DurationProto converts a time.Duration to a Duration.\nfunc durationProto(d time.Duration) *duration {\n\tnanos := d.Nanoseconds()\n\tsecs := nanos / 1e9\n\tnanos -= secs * 1e9\n\treturn &duration{\n\t\tSeconds: secs,\n\t\tNanos:   int32(nanos),\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/duration_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2016, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"reflect\"\n\t\"time\"\n)\n\nvar durationType = reflect.TypeOf((*time.Duration)(nil)).Elem()\n\ntype duration struct {\n\tSeconds int64 `protobuf:\"varint,1,opt,name=seconds,proto3\" json:\"seconds,omitempty\"`\n\tNanos   int32 `protobuf:\"varint,2,opt,name=nanos,proto3\" json:\"nanos,omitempty\"`\n}\n\nfunc (m *duration) Reset()       { *m = duration{} }\nfunc (*duration) ProtoMessage()  {}\nfunc (*duration) String() string { return \"duration<string>\" }\n\nfunc init() {\n\tRegisterType((*duration)(nil), \"gogo.protobuf.proto.duration\")\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/encode.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n/*\n * Routines for encoding data into the wire format for protocol buffers.\n */\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n)\n\nvar (\n\t// errRepeatedHasNil is the error returned if Marshal is called with\n\t// a struct with a repeated field containing a nil element.\n\terrRepeatedHasNil = errors.New(\"proto: repeated field has nil element\")\n\n\t// errOneofHasNil is the error returned if Marshal is called with\n\t// a struct with a oneof field containing a nil element.\n\terrOneofHasNil = errors.New(\"proto: oneof field has nil value\")\n\n\t// ErrNil is the error returned if Marshal is called with nil.\n\tErrNil = errors.New(\"proto: Marshal called with nil\")\n\n\t// ErrTooLarge is the error returned if Marshal is called with a\n\t// message that encodes to >2GB.\n\tErrTooLarge = errors.New(\"proto: message encodes to over 2 GB\")\n)\n\n// The fundamental encoders that put bytes on the wire.\n// Those that take integer types all accept uint64 and are\n// therefore of type valueEncoder.\n\nconst maxVarintBytes = 10 // maximum length of a varint\n\n// EncodeVarint returns the varint encoding of x.\n// This is the format for the\n// int32, int64, uint32, uint64, bool, and enum\n// protocol buffer types.\n// Not used by the package itself, but helpful to clients\n// wishing to use the same encoding.\nfunc EncodeVarint(x uint64) []byte {\n\tvar buf [maxVarintBytes]byte\n\tvar n int\n\tfor n = 0; x > 127; n++ {\n\t\tbuf[n] = 0x80 | uint8(x&0x7F)\n\t\tx >>= 7\n\t}\n\tbuf[n] = uint8(x)\n\tn++\n\treturn buf[0:n]\n}\n\n// EncodeVarint writes a varint-encoded integer to the Buffer.\n// This is the format for the\n// int32, int64, uint32, uint64, bool, and enum\n// protocol buffer types.\nfunc (p *Buffer) EncodeVarint(x uint64) error {\n\tfor x >= 1<<7 {\n\t\tp.buf = append(p.buf, uint8(x&0x7f|0x80))\n\t\tx >>= 7\n\t}\n\tp.buf = append(p.buf, uint8(x))\n\treturn nil\n}\n\n// SizeVarint returns the varint encoding size of an integer.\nfunc SizeVarint(x uint64) int {\n\tswitch {\n\tcase x < 1<<7:\n\t\treturn 1\n\tcase x < 1<<14:\n\t\treturn 2\n\tcase x < 1<<21:\n\t\treturn 3\n\tcase x < 1<<28:\n\t\treturn 4\n\tcase x < 1<<35:\n\t\treturn 5\n\tcase x < 1<<42:\n\t\treturn 6\n\tcase x < 1<<49:\n\t\treturn 7\n\tcase x < 1<<56:\n\t\treturn 8\n\tcase x < 1<<63:\n\t\treturn 9\n\t}\n\treturn 10\n}\n\n// EncodeFixed64 writes a 64-bit integer to the Buffer.\n// This is the format for the\n// fixed64, sfixed64, and double protocol buffer types.\nfunc (p *Buffer) EncodeFixed64(x uint64) error {\n\tp.buf = append(p.buf,\n\t\tuint8(x),\n\t\tuint8(x>>8),\n\t\tuint8(x>>16),\n\t\tuint8(x>>24),\n\t\tuint8(x>>32),\n\t\tuint8(x>>40),\n\t\tuint8(x>>48),\n\t\tuint8(x>>56))\n\treturn nil\n}\n\n// EncodeFixed32 writes a 32-bit integer to the Buffer.\n// This is the format for the\n// fixed32, sfixed32, and float protocol buffer types.\nfunc (p *Buffer) EncodeFixed32(x uint64) error {\n\tp.buf = append(p.buf,\n\t\tuint8(x),\n\t\tuint8(x>>8),\n\t\tuint8(x>>16),\n\t\tuint8(x>>24))\n\treturn nil\n}\n\n// EncodeZigzag64 writes a zigzag-encoded 64-bit integer\n// to the Buffer.\n// This is the format used for the sint64 protocol buffer type.\nfunc (p *Buffer) EncodeZigzag64(x uint64) error {\n\t// use signed number to get arithmetic right shift.\n\treturn p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))\n}\n\n// EncodeZigzag32 writes a zigzag-encoded 32-bit integer\n// to the Buffer.\n// This is the format used for the sint32 protocol buffer type.\nfunc (p *Buffer) EncodeZigzag32(x uint64) error {\n\t// use signed number to get arithmetic right shift.\n\treturn p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))\n}\n\n// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.\n// This is the format used for the bytes protocol buffer\n// type and for embedded messages.\nfunc (p *Buffer) EncodeRawBytes(b []byte) error {\n\tp.EncodeVarint(uint64(len(b)))\n\tp.buf = append(p.buf, b...)\n\treturn nil\n}\n\n// EncodeStringBytes writes an encoded string to the Buffer.\n// This is the format used for the proto2 string type.\nfunc (p *Buffer) EncodeStringBytes(s string) error {\n\tp.EncodeVarint(uint64(len(s)))\n\tp.buf = append(p.buf, s...)\n\treturn nil\n}\n\n// Marshaler is the interface representing objects that can marshal themselves.\ntype Marshaler interface {\n\tMarshal() ([]byte, error)\n}\n\n// EncodeMessage writes the protocol buffer to the Buffer,\n// prefixed by a varint-encoded length.\nfunc (p *Buffer) EncodeMessage(pb Message) error {\n\tsiz := Size(pb)\n\tsizVar := SizeVarint(uint64(siz))\n\tp.grow(siz + sizVar)\n\tp.EncodeVarint(uint64(siz))\n\treturn p.Marshal(pb)\n}\n\n// All protocol buffer fields are nillable, but be careful.\nfunc isNil(v reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:\n\t\treturn v.IsNil()\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/encode_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nfunc NewRequiredNotSetError(field string) *RequiredNotSetError {\n\treturn &RequiredNotSetError{field}\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/equal.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2011 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// Protocol buffer comparison.\n\npackage proto\n\nimport (\n\t\"bytes\"\n\t\"log\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n/*\nEqual returns true iff protocol buffers a and b are equal.\nThe arguments must both be pointers to protocol buffer structs.\n\nEquality is defined in this way:\n  - Two messages are equal iff they are the same type,\n    corresponding fields are equal, unknown field sets\n    are equal, and extensions sets are equal.\n  - Two set scalar fields are equal iff their values are equal.\n    If the fields are of a floating-point type, remember that\n    NaN != x for all x, including NaN. If the message is defined\n    in a proto3 .proto file, fields are not \"set\"; specifically,\n    zero length proto3 \"bytes\" fields are equal (nil == {}).\n  - Two repeated fields are equal iff their lengths are the same,\n    and their corresponding elements are equal. Note a \"bytes\" field,\n    although represented by []byte, is not a repeated field and the\n    rule for the scalar fields described above applies.\n  - Two unset fields are equal.\n  - Two unknown field sets are equal if their current\n    encoded state is equal.\n  - Two extension sets are equal iff they have corresponding\n    elements that are pairwise equal.\n  - Two map fields are equal iff their lengths are the same,\n    and they contain the same set of elements. Zero-length map\n    fields are equal.\n  - Every other combination of things are not equal.\n\nThe return value is undefined if a and b are not protocol buffers.\n*/\nfunc Equal(a, b Message) bool {\n\tif a == nil || b == nil {\n\t\treturn a == b\n\t}\n\tv1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)\n\tif v1.Type() != v2.Type() {\n\t\treturn false\n\t}\n\tif v1.Kind() == reflect.Ptr {\n\t\tif v1.IsNil() {\n\t\t\treturn v2.IsNil()\n\t\t}\n\t\tif v2.IsNil() {\n\t\t\treturn false\n\t\t}\n\t\tv1, v2 = v1.Elem(), v2.Elem()\n\t}\n\tif v1.Kind() != reflect.Struct {\n\t\treturn false\n\t}\n\treturn equalStruct(v1, v2)\n}\n\n// v1 and v2 are known to have the same type.\nfunc equalStruct(v1, v2 reflect.Value) bool {\n\tsprop := GetProperties(v1.Type())\n\tfor i := 0; i < v1.NumField(); i++ {\n\t\tf := v1.Type().Field(i)\n\t\tif strings.HasPrefix(f.Name, \"XXX_\") {\n\t\t\tcontinue\n\t\t}\n\t\tf1, f2 := v1.Field(i), v2.Field(i)\n\t\tif f.Type.Kind() == reflect.Ptr {\n\t\t\tif n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {\n\t\t\t\t// both unset\n\t\t\t\tcontinue\n\t\t\t} else if n1 != n2 {\n\t\t\t\t// set/unset mismatch\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tf1, f2 = f1.Elem(), f2.Elem()\n\t\t}\n\t\tif !equalAny(f1, f2, sprop.Prop[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif em1 := v1.FieldByName(\"XXX_InternalExtensions\"); em1.IsValid() {\n\t\tem2 := v2.FieldByName(\"XXX_InternalExtensions\")\n\t\tif !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif em1 := v1.FieldByName(\"XXX_extensions\"); em1.IsValid() {\n\t\tem2 := v2.FieldByName(\"XXX_extensions\")\n\t\tif !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tuf := v1.FieldByName(\"XXX_unrecognized\")\n\tif !uf.IsValid() {\n\t\treturn true\n\t}\n\n\tu1 := uf.Bytes()\n\tu2 := v2.FieldByName(\"XXX_unrecognized\").Bytes()\n\treturn bytes.Equal(u1, u2)\n}\n\n// v1 and v2 are known to have the same type.\n// prop may be nil.\nfunc equalAny(v1, v2 reflect.Value, prop *Properties) bool {\n\tif v1.Type() == protoMessageType {\n\t\tm1, _ := v1.Interface().(Message)\n\t\tm2, _ := v2.Interface().(Message)\n\t\treturn Equal(m1, m2)\n\t}\n\tswitch v1.Kind() {\n\tcase reflect.Bool:\n\t\treturn v1.Bool() == v2.Bool()\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v1.Float() == v2.Float()\n\tcase reflect.Int32, reflect.Int64:\n\t\treturn v1.Int() == v2.Int()\n\tcase reflect.Interface:\n\t\t// Probably a oneof field; compare the inner values.\n\t\tn1, n2 := v1.IsNil(), v2.IsNil()\n\t\tif n1 || n2 {\n\t\t\treturn n1 == n2\n\t\t}\n\t\te1, e2 := v1.Elem(), v2.Elem()\n\t\tif e1.Type() != e2.Type() {\n\t\t\treturn false\n\t\t}\n\t\treturn equalAny(e1, e2, nil)\n\tcase reflect.Map:\n\t\tif v1.Len() != v2.Len() {\n\t\t\treturn false\n\t\t}\n\t\tfor _, key := range v1.MapKeys() {\n\t\t\tval2 := v2.MapIndex(key)\n\t\t\tif !val2.IsValid() {\n\t\t\t\t// This key was not found in the second map.\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !equalAny(v1.MapIndex(key), val2, nil) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\tcase reflect.Ptr:\n\t\t// Maps may have nil values in them, so check for nil.\n\t\tif v1.IsNil() && v2.IsNil() {\n\t\t\treturn true\n\t\t}\n\t\tif v1.IsNil() != v2.IsNil() {\n\t\t\treturn false\n\t\t}\n\t\treturn equalAny(v1.Elem(), v2.Elem(), prop)\n\tcase reflect.Slice:\n\t\tif v1.Type().Elem().Kind() == reflect.Uint8 {\n\t\t\t// short circuit: []byte\n\n\t\t\t// Edge case: if this is in a proto3 message, a zero length\n\t\t\t// bytes field is considered the zero value.\n\t\t\tif prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif v1.IsNil() != v2.IsNil() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))\n\t\t}\n\n\t\tif v1.Len() != v2.Len() {\n\t\t\treturn false\n\t\t}\n\t\tfor i := 0; i < v1.Len(); i++ {\n\t\t\tif !equalAny(v1.Index(i), v2.Index(i), prop) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\tcase reflect.String:\n\t\treturn v1.Interface().(string) == v2.Interface().(string)\n\tcase reflect.Struct:\n\t\treturn equalStruct(v1, v2)\n\tcase reflect.Uint32, reflect.Uint64:\n\t\treturn v1.Uint() == v2.Uint()\n\t}\n\n\t// unknown type, so not a protocol buffer\n\tlog.Printf(\"proto: don't know how to compare %v\", v1)\n\treturn false\n}\n\n// base is the struct type that the extensions are based on.\n// x1 and x2 are InternalExtensions.\nfunc equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool {\n\tem1, _ := x1.extensionsRead()\n\tem2, _ := x2.extensionsRead()\n\treturn equalExtMap(base, em1, em2)\n}\n\nfunc equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {\n\tif len(em1) != len(em2) {\n\t\treturn false\n\t}\n\n\tfor extNum, e1 := range em1 {\n\t\te2, ok := em2[extNum]\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\n\t\tm1, m2 := e1.value, e2.value\n\n\t\tif m1 == nil && m2 == nil {\n\t\t\t// Both have only encoded form.\n\t\t\tif bytes.Equal(e1.enc, e2.enc) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// The bytes are different, but the extensions might still be\n\t\t\t// equal. We need to decode them to compare.\n\t\t}\n\n\t\tif m1 != nil && m2 != nil {\n\t\t\t// Both are unencoded.\n\t\t\tif !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// At least one is encoded. To do a semantically correct comparison\n\t\t// we need to unmarshal them first.\n\t\tvar desc *ExtensionDesc\n\t\tif m := extensionMaps[base]; m != nil {\n\t\t\tdesc = m[extNum]\n\t\t}\n\t\tif desc == nil {\n\t\t\t// If both have only encoded form and the bytes are the same,\n\t\t\t// it is handled above. We get here when the bytes are different.\n\t\t\t// We don't know how to decode it, so just compare them as byte\n\t\t\t// slices.\n\t\t\tlog.Printf(\"proto: don't know how to compare extension %d of %v\", extNum, base)\n\t\t\treturn false\n\t\t}\n\t\tvar err error\n\t\tif m1 == nil {\n\t\t\tm1, err = decodeExtension(e1.enc, desc)\n\t\t}\n\t\tif m2 == nil && err == nil {\n\t\t\tm2, err = decodeExtension(e2.enc, desc)\n\t\t}\n\t\tif err != nil {\n\t\t\t// The encoded form is invalid.\n\t\t\tlog.Printf(\"proto: badly encoded extension %d of %v: %v\", extNum, base, err)\n\t\t\treturn false\n\t\t}\n\t\tif !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/extensions.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n/*\n * Types and routines for supporting protocol buffer extensions.\n */\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"sync\"\n)\n\n// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.\nvar ErrMissingExtension = errors.New(\"proto: missing extension\")\n\n// ExtensionRange represents a range of message extensions for a protocol buffer.\n// Used in code generated by the protocol compiler.\ntype ExtensionRange struct {\n\tStart, End int32 // both inclusive\n}\n\n// extendableProto is an interface implemented by any protocol buffer generated by the current\n// proto compiler that may be extended.\ntype extendableProto interface {\n\tMessage\n\tExtensionRangeArray() []ExtensionRange\n\textensionsWrite() map[int32]Extension\n\textensionsRead() (map[int32]Extension, sync.Locker)\n}\n\n// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous\n// version of the proto compiler that may be extended.\ntype extendableProtoV1 interface {\n\tMessage\n\tExtensionRangeArray() []ExtensionRange\n\tExtensionMap() map[int32]Extension\n}\n\n// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.\ntype extensionAdapter struct {\n\textendableProtoV1\n}\n\nfunc (e extensionAdapter) extensionsWrite() map[int32]Extension {\n\treturn e.ExtensionMap()\n}\n\nfunc (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {\n\treturn e.ExtensionMap(), notLocker{}\n}\n\n// notLocker is a sync.Locker whose Lock and Unlock methods are nops.\ntype notLocker struct{}\n\nfunc (n notLocker) Lock()   {}\nfunc (n notLocker) Unlock() {}\n\n// extendable returns the extendableProto interface for the given generated proto message.\n// If the proto message has the old extension format, it returns a wrapper that implements\n// the extendableProto interface.\nfunc extendable(p interface{}) (extendableProto, error) {\n\tswitch p := p.(type) {\n\tcase extendableProto:\n\t\tif isNilPtr(p) {\n\t\t\treturn nil, fmt.Errorf(\"proto: nil %T is not extendable\", p)\n\t\t}\n\t\treturn p, nil\n\tcase extendableProtoV1:\n\t\tif isNilPtr(p) {\n\t\t\treturn nil, fmt.Errorf(\"proto: nil %T is not extendable\", p)\n\t\t}\n\t\treturn extensionAdapter{p}, nil\n\tcase extensionsBytes:\n\t\treturn slowExtensionAdapter{p}, nil\n\t}\n\t// Don't allocate a specific error containing %T:\n\t// this is the hot path for Clone and MarshalText.\n\treturn nil, errNotExtendable\n}\n\nvar errNotExtendable = errors.New(\"proto: not an extendable proto.Message\")\n\nfunc isNilPtr(x interface{}) bool {\n\tv := reflect.ValueOf(x)\n\treturn v.Kind() == reflect.Ptr && v.IsNil()\n}\n\n// XXX_InternalExtensions is an internal representation of proto extensions.\n//\n// Each generated message struct type embeds an anonymous XXX_InternalExtensions field,\n// thus gaining the unexported 'extensions' method, which can be called only from the proto package.\n//\n// The methods of XXX_InternalExtensions are not concurrency safe in general,\n// but calls to logically read-only methods such as has and get may be executed concurrently.\ntype XXX_InternalExtensions struct {\n\t// The struct must be indirect so that if a user inadvertently copies a\n\t// generated message and its embedded XXX_InternalExtensions, they\n\t// avoid the mayhem of a copied mutex.\n\t//\n\t// The mutex serializes all logically read-only operations to p.extensionMap.\n\t// It is up to the client to ensure that write operations to p.extensionMap are\n\t// mutually exclusive with other accesses.\n\tp *struct {\n\t\tmu           sync.Mutex\n\t\textensionMap map[int32]Extension\n\t}\n}\n\n// extensionsWrite returns the extension map, creating it on first use.\nfunc (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension {\n\tif e.p == nil {\n\t\te.p = new(struct {\n\t\t\tmu           sync.Mutex\n\t\t\textensionMap map[int32]Extension\n\t\t})\n\t\te.p.extensionMap = make(map[int32]Extension)\n\t}\n\treturn e.p.extensionMap\n}\n\n// extensionsRead returns the extensions map for read-only use.  It may be nil.\n// The caller must hold the returned mutex's lock when accessing Elements within the map.\nfunc (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) {\n\tif e.p == nil {\n\t\treturn nil, nil\n\t}\n\treturn e.p.extensionMap, &e.p.mu\n}\n\n// ExtensionDesc represents an extension specification.\n// Used in generated code from the protocol compiler.\ntype ExtensionDesc struct {\n\tExtendedType  Message     // nil pointer to the type that is being extended\n\tExtensionType interface{} // nil pointer to the extension type\n\tField         int32       // field number\n\tName          string      // fully-qualified name of extension, for text formatting\n\tTag           string      // protobuf tag style\n\tFilename      string      // name of the file in which the extension is defined\n}\n\nfunc (ed *ExtensionDesc) repeated() bool {\n\tt := reflect.TypeOf(ed.ExtensionType)\n\treturn t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8\n}\n\n// Extension represents an extension in a message.\ntype Extension struct {\n\t// When an extension is stored in a message using SetExtension\n\t// only desc and value are set. When the message is marshaled\n\t// enc will be set to the encoded form of the message.\n\t//\n\t// When a message is unmarshaled and contains extensions, each\n\t// extension will have only enc set. When such an extension is\n\t// accessed using GetExtension (or GetExtensions) desc and value\n\t// will be set.\n\tdesc  *ExtensionDesc\n\tvalue interface{}\n\tenc   []byte\n}\n\n// SetRawExtension is for testing only.\nfunc SetRawExtension(base Message, id int32, b []byte) {\n\tif ebase, ok := base.(extensionsBytes); ok {\n\t\tclearExtension(base, id)\n\t\text := ebase.GetExtensions()\n\t\t*ext = append(*ext, b...)\n\t\treturn\n\t}\n\tepb, err := extendable(base)\n\tif err != nil {\n\t\treturn\n\t}\n\textmap := epb.extensionsWrite()\n\textmap[id] = Extension{enc: b}\n}\n\n// isExtensionField returns true iff the given field number is in an extension range.\nfunc isExtensionField(pb extendableProto, field int32) bool {\n\tfor _, er := range pb.ExtensionRangeArray() {\n\t\tif er.Start <= field && field <= er.End {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// checkExtensionTypes checks that the given extension is valid for pb.\nfunc checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {\n\tvar pbi interface{} = pb\n\t// Check the extended type.\n\tif ea, ok := pbi.(extensionAdapter); ok {\n\t\tpbi = ea.extendableProtoV1\n\t}\n\tif ea, ok := pbi.(slowExtensionAdapter); ok {\n\t\tpbi = ea.extensionsBytes\n\t}\n\tif a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {\n\t\treturn fmt.Errorf(\"proto: bad extended type; %v does not extend %v\", b, a)\n\t}\n\t// Check the range.\n\tif !isExtensionField(pb, extension.Field) {\n\t\treturn errors.New(\"proto: bad extension number; not in declared ranges\")\n\t}\n\treturn nil\n}\n\n// extPropKey is sufficient to uniquely identify an extension.\ntype extPropKey struct {\n\tbase  reflect.Type\n\tfield int32\n}\n\nvar extProp = struct {\n\tsync.RWMutex\n\tm map[extPropKey]*Properties\n}{\n\tm: make(map[extPropKey]*Properties),\n}\n\nfunc extensionProperties(ed *ExtensionDesc) *Properties {\n\tkey := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}\n\n\textProp.RLock()\n\tif prop, ok := extProp.m[key]; ok {\n\t\textProp.RUnlock()\n\t\treturn prop\n\t}\n\textProp.RUnlock()\n\n\textProp.Lock()\n\tdefer extProp.Unlock()\n\t// Check again.\n\tif prop, ok := extProp.m[key]; ok {\n\t\treturn prop\n\t}\n\n\tprop := new(Properties)\n\tprop.Init(reflect.TypeOf(ed.ExtensionType), \"unknown_name\", ed.Tag, nil)\n\textProp.m[key] = prop\n\treturn prop\n}\n\n// HasExtension returns whether the given extension is present in pb.\nfunc HasExtension(pb Message, extension *ExtensionDesc) bool {\n\tif epb, doki := pb.(extensionsBytes); doki {\n\t\text := epb.GetExtensions()\n\t\tbuf := *ext\n\t\to := 0\n\t\tfor o < len(buf) {\n\t\t\ttag, n := DecodeVarint(buf[o:])\n\t\t\tfieldNum := int32(tag >> 3)\n\t\t\tif int32(fieldNum) == extension.Field {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\twireType := int(tag & 0x7)\n\t\t\to += n\n\t\t\tl, err := size(buf[o:], wireType)\n\t\t\tif err != nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\to += l\n\t\t}\n\t\treturn false\n\t}\n\t// TODO: Check types, field numbers, etc.?\n\tepb, err := extendable(pb)\n\tif err != nil {\n\t\treturn false\n\t}\n\textmap, mu := epb.extensionsRead()\n\tif extmap == nil {\n\t\treturn false\n\t}\n\tmu.Lock()\n\t_, ok := extmap[extension.Field]\n\tmu.Unlock()\n\treturn ok\n}\n\n// ClearExtension removes the given extension from pb.\nfunc ClearExtension(pb Message, extension *ExtensionDesc) {\n\tclearExtension(pb, extension.Field)\n}\n\nfunc clearExtension(pb Message, fieldNum int32) {\n\tif epb, ok := pb.(extensionsBytes); ok {\n\t\toffset := 0\n\t\tfor offset != -1 {\n\t\t\toffset = deleteExtension(epb, fieldNum, offset)\n\t\t}\n\t\treturn\n\t}\n\tepb, err := extendable(pb)\n\tif err != nil {\n\t\treturn\n\t}\n\t// TODO: Check types, field numbers, etc.?\n\textmap := epb.extensionsWrite()\n\tdelete(extmap, fieldNum)\n}\n\n// GetExtension retrieves a proto2 extended field from pb.\n//\n// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),\n// then GetExtension parses the encoded field and returns a Go value of the specified type.\n// If the field is not present, then the default value is returned (if one is specified),\n// otherwise ErrMissingExtension is reported.\n//\n// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),\n// then GetExtension returns the raw encoded bytes of the field extension.\nfunc GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {\n\tif epb, doki := pb.(extensionsBytes); doki {\n\t\text := epb.GetExtensions()\n\t\treturn decodeExtensionFromBytes(extension, *ext)\n\t}\n\n\tepb, err := extendable(pb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif extension.ExtendedType != nil {\n\t\t// can only check type if this is a complete descriptor\n\t\tif cerr := checkExtensionTypes(epb, extension); cerr != nil {\n\t\t\treturn nil, cerr\n\t\t}\n\t}\n\n\temap, mu := epb.extensionsRead()\n\tif emap == nil {\n\t\treturn defaultExtensionValue(extension)\n\t}\n\tmu.Lock()\n\tdefer mu.Unlock()\n\te, ok := emap[extension.Field]\n\tif !ok {\n\t\t// defaultExtensionValue returns the default value or\n\t\t// ErrMissingExtension if there is no default.\n\t\treturn defaultExtensionValue(extension)\n\t}\n\n\tif e.value != nil {\n\t\t// Already decoded. Check the descriptor, though.\n\t\tif e.desc != extension {\n\t\t\t// This shouldn't happen. If it does, it means that\n\t\t\t// GetExtension was called twice with two different\n\t\t\t// descriptors with the same field number.\n\t\t\treturn nil, errors.New(\"proto: descriptor conflict\")\n\t\t}\n\t\treturn e.value, nil\n\t}\n\n\tif extension.ExtensionType == nil {\n\t\t// incomplete descriptor\n\t\treturn e.enc, nil\n\t}\n\n\tv, err := decodeExtension(e.enc, extension)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Remember the decoded version and drop the encoded version.\n\t// That way it is safe to mutate what we return.\n\te.value = v\n\te.desc = extension\n\te.enc = nil\n\temap[extension.Field] = e\n\treturn e.value, nil\n}\n\n// defaultExtensionValue returns the default value for extension.\n// If no default for an extension is defined ErrMissingExtension is returned.\nfunc defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {\n\tif extension.ExtensionType == nil {\n\t\t// incomplete descriptor, so no default\n\t\treturn nil, ErrMissingExtension\n\t}\n\n\tt := reflect.TypeOf(extension.ExtensionType)\n\tprops := extensionProperties(extension)\n\n\tsf, _, err := fieldDefault(t, props)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif sf == nil || sf.value == nil {\n\t\t// There is no default value.\n\t\treturn nil, ErrMissingExtension\n\t}\n\n\tif t.Kind() != reflect.Ptr {\n\t\t// We do not need to return a Ptr, we can directly return sf.value.\n\t\treturn sf.value, nil\n\t}\n\n\t// We need to return an interface{} that is a pointer to sf.value.\n\tvalue := reflect.New(t).Elem()\n\tvalue.Set(reflect.New(value.Type().Elem()))\n\tif sf.kind == reflect.Int32 {\n\t\t// We may have an int32 or an enum, but the underlying data is int32.\n\t\t// Since we can't set an int32 into a non int32 reflect.value directly\n\t\t// set it as a int32.\n\t\tvalue.Elem().SetInt(int64(sf.value.(int32)))\n\t} else {\n\t\tvalue.Elem().Set(reflect.ValueOf(sf.value))\n\t}\n\treturn value.Interface(), nil\n}\n\n// decodeExtension decodes an extension encoded in b.\nfunc decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {\n\tt := reflect.TypeOf(extension.ExtensionType)\n\tunmarshal := typeUnmarshaler(t, extension.Tag)\n\n\t// t is a pointer to a struct, pointer to basic type or a slice.\n\t// Allocate space to store the pointer/slice.\n\tvalue := reflect.New(t).Elem()\n\n\tvar err error\n\tfor {\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\twire := int(x) & 7\n\n\t\tb, err = unmarshal(b, valToPointer(value.Addr()), wire)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif len(b) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn value.Interface(), nil\n}\n\n// GetExtensions returns a slice of the extensions present in pb that are also listed in es.\n// The returned slice has the same length as es; missing extensions will appear as nil elements.\nfunc GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {\n\tepb, err := extendable(pb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\textensions = make([]interface{}, len(es))\n\tfor i, e := range es {\n\t\textensions[i], err = GetExtension(epb, e)\n\t\tif err == ErrMissingExtension {\n\t\t\terr = nil\n\t\t}\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\n// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order.\n// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing\n// just the Field field, which defines the extension's field number.\nfunc ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {\n\tepb, err := extendable(pb)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tregisteredExtensions := RegisteredExtensions(pb)\n\n\temap, mu := epb.extensionsRead()\n\tif emap == nil {\n\t\treturn nil, nil\n\t}\n\tmu.Lock()\n\tdefer mu.Unlock()\n\textensions := make([]*ExtensionDesc, 0, len(emap))\n\tfor extid, e := range emap {\n\t\tdesc := e.desc\n\t\tif desc == nil {\n\t\t\tdesc = registeredExtensions[extid]\n\t\t\tif desc == nil {\n\t\t\t\tdesc = &ExtensionDesc{Field: extid}\n\t\t\t}\n\t\t}\n\n\t\textensions = append(extensions, desc)\n\t}\n\treturn extensions, nil\n}\n\n// SetExtension sets the specified extension of pb to the specified value.\nfunc SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {\n\tif epb, ok := pb.(extensionsBytes); ok {\n\t\tClearExtension(pb, extension)\n\t\tnewb, err := encodeExtension(extension, value)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbb := epb.GetExtensions()\n\t\t*bb = append(*bb, newb...)\n\t\treturn nil\n\t}\n\tepb, err := extendable(pb)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := checkExtensionTypes(epb, extension); err != nil {\n\t\treturn err\n\t}\n\ttyp := reflect.TypeOf(extension.ExtensionType)\n\tif typ != reflect.TypeOf(value) {\n\t\treturn fmt.Errorf(\"proto: bad extension value type. got: %T, want: %T\", value, extension.ExtensionType)\n\t}\n\t// nil extension values need to be caught early, because the\n\t// encoder can't distinguish an ErrNil due to a nil extension\n\t// from an ErrNil due to a missing field. Extensions are\n\t// always optional, so the encoder would just swallow the error\n\t// and drop all the extensions from the encoded message.\n\tif reflect.ValueOf(value).IsNil() {\n\t\treturn fmt.Errorf(\"proto: SetExtension called with nil value of type %T\", value)\n\t}\n\n\textmap := epb.extensionsWrite()\n\textmap[extension.Field] = Extension{desc: extension, value: value}\n\treturn nil\n}\n\n// ClearAllExtensions clears all extensions from pb.\nfunc ClearAllExtensions(pb Message) {\n\tif epb, doki := pb.(extensionsBytes); doki {\n\t\text := epb.GetExtensions()\n\t\t*ext = []byte{}\n\t\treturn\n\t}\n\tepb, err := extendable(pb)\n\tif err != nil {\n\t\treturn\n\t}\n\tm := epb.extensionsWrite()\n\tfor k := range m {\n\t\tdelete(m, k)\n\t}\n}\n\n// A global registry of extensions.\n// The generated code will register the generated descriptors by calling RegisterExtension.\n\nvar extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)\n\n// RegisterExtension is called from the generated code.\nfunc RegisterExtension(desc *ExtensionDesc) {\n\tst := reflect.TypeOf(desc.ExtendedType).Elem()\n\tm := extensionMaps[st]\n\tif m == nil {\n\t\tm = make(map[int32]*ExtensionDesc)\n\t\textensionMaps[st] = m\n\t}\n\tif _, ok := m[desc.Field]; ok {\n\t\tpanic(\"proto: duplicate extension registered: \" + st.String() + \" \" + strconv.Itoa(int(desc.Field)))\n\t}\n\tm[desc.Field] = desc\n}\n\n// RegisteredExtensions returns a map of the registered extensions of a\n// protocol buffer struct, indexed by the extension number.\n// The argument pb should be a nil pointer to the struct type.\nfunc RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {\n\treturn extensionMaps[reflect.TypeOf(pb).Elem()]\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/extensions_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype extensionsBytes interface {\n\tMessage\n\tExtensionRangeArray() []ExtensionRange\n\tGetExtensions() *[]byte\n}\n\ntype slowExtensionAdapter struct {\n\textensionsBytes\n}\n\nfunc (s slowExtensionAdapter) extensionsWrite() map[int32]Extension {\n\tpanic(\"Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.\")\n}\n\nfunc (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {\n\tb := s.GetExtensions()\n\tm, err := BytesToExtensionsMap(*b)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn m, notLocker{}\n}\n\nfunc GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool {\n\tif reflect.ValueOf(pb).IsNil() {\n\t\treturn ifnotset\n\t}\n\tvalue, err := GetExtension(pb, extension)\n\tif err != nil {\n\t\treturn ifnotset\n\t}\n\tif value == nil {\n\t\treturn ifnotset\n\t}\n\tif value.(*bool) == nil {\n\t\treturn ifnotset\n\t}\n\treturn *(value.(*bool))\n}\n\nfunc (this *Extension) Equal(that *Extension) bool {\n\tif err := this.Encode(); err != nil {\n\t\treturn false\n\t}\n\tif err := that.Encode(); err != nil {\n\t\treturn false\n\t}\n\treturn bytes.Equal(this.enc, that.enc)\n}\n\nfunc (this *Extension) Compare(that *Extension) int {\n\tif err := this.Encode(); err != nil {\n\t\treturn 1\n\t}\n\tif err := that.Encode(); err != nil {\n\t\treturn -1\n\t}\n\treturn bytes.Compare(this.enc, that.enc)\n}\n\nfunc SizeOfInternalExtension(m extendableProto) (n int) {\n\tinfo := getMarshalInfo(reflect.TypeOf(m))\n\treturn info.sizeV1Extensions(m.extensionsWrite())\n}\n\ntype sortableMapElem struct {\n\tfield int32\n\text   Extension\n}\n\nfunc newSortableExtensionsFromMap(m map[int32]Extension) sortableExtensions {\n\ts := make(sortableExtensions, 0, len(m))\n\tfor k, v := range m {\n\t\ts = append(s, &sortableMapElem{field: k, ext: v})\n\t}\n\treturn s\n}\n\ntype sortableExtensions []*sortableMapElem\n\nfunc (this sortableExtensions) Len() int { return len(this) }\n\nfunc (this sortableExtensions) Swap(i, j int) { this[i], this[j] = this[j], this[i] }\n\nfunc (this sortableExtensions) Less(i, j int) bool { return this[i].field < this[j].field }\n\nfunc (this sortableExtensions) String() string {\n\tsort.Sort(this)\n\tss := make([]string, len(this))\n\tfor i := range this {\n\t\tss[i] = fmt.Sprintf(\"%d: %v\", this[i].field, this[i].ext)\n\t}\n\treturn \"map[\" + strings.Join(ss, \",\") + \"]\"\n}\n\nfunc StringFromInternalExtension(m extendableProto) string {\n\treturn StringFromExtensionsMap(m.extensionsWrite())\n}\n\nfunc StringFromExtensionsMap(m map[int32]Extension) string {\n\treturn newSortableExtensionsFromMap(m).String()\n}\n\nfunc StringFromExtensionsBytes(ext []byte) string {\n\tm, err := BytesToExtensionsMap(ext)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn StringFromExtensionsMap(m)\n}\n\nfunc EncodeInternalExtension(m extendableProto, data []byte) (n int, err error) {\n\treturn EncodeExtensionMap(m.extensionsWrite(), data)\n}\n\nfunc EncodeInternalExtensionBackwards(m extendableProto, data []byte) (n int, err error) {\n\treturn EncodeExtensionMapBackwards(m.extensionsWrite(), data)\n}\n\nfunc EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {\n\to := 0\n\tfor _, e := range m {\n\t\tif err := e.Encode(); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn := copy(data[o:], e.enc)\n\t\tif n != len(e.enc) {\n\t\t\treturn 0, io.ErrShortBuffer\n\t\t}\n\t\to += n\n\t}\n\treturn o, nil\n}\n\nfunc EncodeExtensionMapBackwards(m map[int32]Extension, data []byte) (n int, err error) {\n\to := 0\n\tend := len(data)\n\tfor _, e := range m {\n\t\tif err := e.Encode(); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn := copy(data[end-len(e.enc):], e.enc)\n\t\tif n != len(e.enc) {\n\t\t\treturn 0, io.ErrShortBuffer\n\t\t}\n\t\tend -= n\n\t\to += n\n\t}\n\treturn o, nil\n}\n\nfunc GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {\n\te := m[id]\n\tif err := e.Encode(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn e.enc, nil\n}\n\nfunc size(buf []byte, wire int) (int, error) {\n\tswitch wire {\n\tcase WireVarint:\n\t\t_, n := DecodeVarint(buf)\n\t\treturn n, nil\n\tcase WireFixed64:\n\t\treturn 8, nil\n\tcase WireBytes:\n\t\tv, n := DecodeVarint(buf)\n\t\treturn int(v) + n, nil\n\tcase WireFixed32:\n\t\treturn 4, nil\n\tcase WireStartGroup:\n\t\toffset := 0\n\t\tfor {\n\t\t\tu, n := DecodeVarint(buf[offset:])\n\t\t\tfwire := int(u & 0x7)\n\t\t\toffset += n\n\t\t\tif fwire == WireEndGroup {\n\t\t\t\treturn offset, nil\n\t\t\t}\n\t\t\ts, err := size(buf[offset:], wire)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\toffset += s\n\t\t}\n\t}\n\treturn 0, fmt.Errorf(\"proto: can't get size for unknown wire type %d\", wire)\n}\n\nfunc BytesToExtensionsMap(buf []byte) (map[int32]Extension, error) {\n\tm := make(map[int32]Extension)\n\ti := 0\n\tfor i < len(buf) {\n\t\ttag, n := DecodeVarint(buf[i:])\n\t\tif n <= 0 {\n\t\t\treturn nil, fmt.Errorf(\"unable to decode varint\")\n\t\t}\n\t\tfieldNum := int32(tag >> 3)\n\t\twireType := int(tag & 0x7)\n\t\tl, err := size(buf[i+n:], wireType)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tend := i + int(l) + n\n\t\tm[int32(fieldNum)] = Extension{enc: buf[i:end]}\n\t\ti = end\n\t}\n\treturn m, nil\n}\n\nfunc NewExtension(e []byte) Extension {\n\tee := Extension{enc: make([]byte, len(e))}\n\tcopy(ee.enc, e)\n\treturn ee\n}\n\nfunc AppendExtension(e Message, tag int32, buf []byte) {\n\tif ee, eok := e.(extensionsBytes); eok {\n\t\text := ee.GetExtensions()\n\t\t*ext = append(*ext, buf...)\n\t\treturn\n\t}\n\tif ee, eok := e.(extendableProto); eok {\n\t\tm := ee.extensionsWrite()\n\t\text := m[int32(tag)] // may be missing\n\t\text.enc = append(ext.enc, buf...)\n\t\tm[int32(tag)] = ext\n\t}\n}\n\nfunc encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) {\n\tu := getMarshalInfo(reflect.TypeOf(extension.ExtendedType))\n\tei := u.getExtElemInfo(extension)\n\tv := value\n\tp := toAddrPointer(&v, ei.isptr)\n\tsiz := ei.sizer(p, SizeVarint(ei.wiretag))\n\tbuf := make([]byte, 0, siz)\n\treturn ei.marshaler(buf, p, ei.wiretag, false)\n}\n\nfunc decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) {\n\to := 0\n\tfor o < len(buf) {\n\t\ttag, n := DecodeVarint((buf)[o:])\n\t\tfieldNum := int32(tag >> 3)\n\t\twireType := int(tag & 0x7)\n\t\tif o+n > len(buf) {\n\t\t\treturn nil, fmt.Errorf(\"unable to decode extension\")\n\t\t}\n\t\tl, err := size((buf)[o+n:], wireType)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif int32(fieldNum) == extension.Field {\n\t\t\tif o+n+l > len(buf) {\n\t\t\t\treturn nil, fmt.Errorf(\"unable to decode extension\")\n\t\t\t}\n\t\t\tv, err := decodeExtension((buf)[o:o+n+l], extension)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn v, nil\n\t\t}\n\t\to += n + l\n\t}\n\treturn defaultExtensionValue(extension)\n}\n\nfunc (this *Extension) Encode() error {\n\tif this.enc == nil {\n\t\tvar err error\n\t\tthis.enc, err = encodeExtension(this.desc, this.value)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (this Extension) GoString() string {\n\tif err := this.Encode(); err != nil {\n\t\treturn fmt.Sprintf(\"error encoding extension: %v\", err)\n\t}\n\treturn fmt.Sprintf(\"proto.NewExtension(%#v)\", this.enc)\n}\n\nfunc SetUnsafeExtension(pb Message, fieldNum int32, value interface{}) error {\n\ttyp := reflect.TypeOf(pb).Elem()\n\text, ok := extensionMaps[typ]\n\tif !ok {\n\t\treturn fmt.Errorf(\"proto: bad extended type; %s is not extendable\", typ.String())\n\t}\n\tdesc, ok := ext[fieldNum]\n\tif !ok {\n\t\treturn errors.New(\"proto: bad extension number; not in declared ranges\")\n\t}\n\treturn SetExtension(pb, desc, value)\n}\n\nfunc GetUnsafeExtension(pb Message, fieldNum int32) (interface{}, error) {\n\ttyp := reflect.TypeOf(pb).Elem()\n\text, ok := extensionMaps[typ]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"proto: bad extended type; %s is not extendable\", typ.String())\n\t}\n\tdesc, ok := ext[fieldNum]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unregistered field number %d\", fieldNum)\n\t}\n\treturn GetExtension(pb, desc)\n}\n\nfunc NewUnsafeXXX_InternalExtensions(m map[int32]Extension) XXX_InternalExtensions {\n\tx := &XXX_InternalExtensions{\n\t\tp: new(struct {\n\t\t\tmu           sync.Mutex\n\t\t\textensionMap map[int32]Extension\n\t\t}),\n\t}\n\tx.p.extensionMap = m\n\treturn *x\n}\n\nfunc GetUnsafeExtensionsMap(extendable Message) map[int32]Extension {\n\tpb := extendable.(extendableProto)\n\treturn pb.extensionsWrite()\n}\n\nfunc deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {\n\text := pb.GetExtensions()\n\tfor offset < len(*ext) {\n\t\ttag, n1 := DecodeVarint((*ext)[offset:])\n\t\tfieldNum := int32(tag >> 3)\n\t\twireType := int(tag & 0x7)\n\t\tn2, err := size((*ext)[offset+n1:], wireType)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tnewOffset := offset + n1 + n2\n\t\tif fieldNum == theFieldNum {\n\t\t\t*ext = append((*ext)[:offset], (*ext)[newOffset:]...)\n\t\t\treturn offset\n\t\t}\n\t\toffset = newOffset\n\t}\n\treturn -1\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/lib.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n/*\nPackage proto converts data structures to and from the wire format of\nprotocol buffers.  It works in concert with the Go source code generated\nfor .proto files by the protocol compiler.\n\nA summary of the properties of the protocol buffer interface\nfor a protocol buffer variable v:\n\n  - Names are turned from camel_case to CamelCase for export.\n  - There are no methods on v to set fields; just treat\n\tthem as structure fields.\n  - There are getters that return a field's value if set,\n\tand return the field's default value if unset.\n\tThe getters work even if the receiver is a nil message.\n  - The zero value for a struct is its correct initialization state.\n\tAll desired fields must be set before marshaling.\n  - A Reset() method will restore a protobuf struct to its zero state.\n  - Non-repeated fields are pointers to the values; nil means unset.\n\tThat is, optional or required field int32 f becomes F *int32.\n  - Repeated fields are slices.\n  - Helper functions are available to aid the setting of fields.\n\tmsg.Foo = proto.String(\"hello\") // set field\n  - Constants are defined to hold the default values of all fields that\n\thave them.  They have the form Default_StructName_FieldName.\n\tBecause the getter methods handle defaulted values,\n\tdirect use of these constants should be rare.\n  - Enums are given type names and maps from names to values.\n\tEnum values are prefixed by the enclosing message's name, or by the\n\tenum's type name if it is a top-level enum. Enum types have a String\n\tmethod, and a Enum method to assist in message construction.\n  - Nested messages, groups and enums have type names prefixed with the name of\n\tthe surrounding message type.\n  - Extensions are given descriptor names that start with E_,\n\tfollowed by an underscore-delimited list of the nested messages\n\tthat contain it (if any) followed by the CamelCased name of the\n\textension field itself.  HasExtension, ClearExtension, GetExtension\n\tand SetExtension are functions for manipulating extensions.\n  - Oneof field sets are given a single field in their message,\n\twith distinguished wrapper types for each possible field value.\n  - Marshal and Unmarshal are functions to encode and decode the wire format.\n\nWhen the .proto file specifies `syntax=\"proto3\"`, there are some differences:\n\n  - Non-repeated fields of non-message type are values instead of pointers.\n  - Enum types do not get an Enum method.\n\nThe simplest way to describe this is to see an example.\nGiven file test.proto, containing\n\n\tpackage example;\n\n\tenum FOO { X = 17; }\n\n\tmessage Test {\n\t  required string label = 1;\n\t  optional int32 type = 2 [default=77];\n\t  repeated int64 reps = 3;\n\t  optional group OptionalGroup = 4 {\n\t    required string RequiredField = 5;\n\t  }\n\t  oneof union {\n\t    int32 number = 6;\n\t    string name = 7;\n\t  }\n\t}\n\nThe resulting file, test.pb.go, is:\n\n\tpackage example\n\n\timport proto \"github.com/gogo/protobuf/proto\"\n\timport math \"math\"\n\n\ttype FOO int32\n\tconst (\n\t\tFOO_X FOO = 17\n\t)\n\tvar FOO_name = map[int32]string{\n\t\t17: \"X\",\n\t}\n\tvar FOO_value = map[string]int32{\n\t\t\"X\": 17,\n\t}\n\n\tfunc (x FOO) Enum() *FOO {\n\t\tp := new(FOO)\n\t\t*p = x\n\t\treturn p\n\t}\n\tfunc (x FOO) String() string {\n\t\treturn proto.EnumName(FOO_name, int32(x))\n\t}\n\tfunc (x *FOO) UnmarshalJSON(data []byte) error {\n\t\tvalue, err := proto.UnmarshalJSONEnum(FOO_value, data)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*x = FOO(value)\n\t\treturn nil\n\t}\n\n\ttype Test struct {\n\t\tLabel         *string             `protobuf:\"bytes,1,req,name=label\" json:\"label,omitempty\"`\n\t\tType          *int32              `protobuf:\"varint,2,opt,name=type,def=77\" json:\"type,omitempty\"`\n\t\tReps          []int64             `protobuf:\"varint,3,rep,name=reps\" json:\"reps,omitempty\"`\n\t\tOptionalgroup *Test_OptionalGroup `protobuf:\"group,4,opt,name=OptionalGroup\" json:\"optionalgroup,omitempty\"`\n\t\t// Types that are valid to be assigned to Union:\n\t\t//\t*Test_Number\n\t\t//\t*Test_Name\n\t\tUnion            isTest_Union `protobuf_oneof:\"union\"`\n\t\tXXX_unrecognized []byte       `json:\"-\"`\n\t}\n\tfunc (m *Test) Reset()         { *m = Test{} }\n\tfunc (m *Test) String() string { return proto.CompactTextString(m) }\n\tfunc (*Test) ProtoMessage() {}\n\n\ttype isTest_Union interface {\n\t\tisTest_Union()\n\t}\n\n\ttype Test_Number struct {\n\t\tNumber int32 `protobuf:\"varint,6,opt,name=number\"`\n\t}\n\ttype Test_Name struct {\n\t\tName string `protobuf:\"bytes,7,opt,name=name\"`\n\t}\n\n\tfunc (*Test_Number) isTest_Union() {}\n\tfunc (*Test_Name) isTest_Union()   {}\n\n\tfunc (m *Test) GetUnion() isTest_Union {\n\t\tif m != nil {\n\t\t\treturn m.Union\n\t\t}\n\t\treturn nil\n\t}\n\tconst Default_Test_Type int32 = 77\n\n\tfunc (m *Test) GetLabel() string {\n\t\tif m != nil && m.Label != nil {\n\t\t\treturn *m.Label\n\t\t}\n\t\treturn \"\"\n\t}\n\n\tfunc (m *Test) GetType() int32 {\n\t\tif m != nil && m.Type != nil {\n\t\t\treturn *m.Type\n\t\t}\n\t\treturn Default_Test_Type\n\t}\n\n\tfunc (m *Test) GetOptionalgroup() *Test_OptionalGroup {\n\t\tif m != nil {\n\t\t\treturn m.Optionalgroup\n\t\t}\n\t\treturn nil\n\t}\n\n\ttype Test_OptionalGroup struct {\n\t\tRequiredField *string `protobuf:\"bytes,5,req\" json:\"RequiredField,omitempty\"`\n\t}\n\tfunc (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }\n\tfunc (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }\n\n\tfunc (m *Test_OptionalGroup) GetRequiredField() string {\n\t\tif m != nil && m.RequiredField != nil {\n\t\t\treturn *m.RequiredField\n\t\t}\n\t\treturn \"\"\n\t}\n\n\tfunc (m *Test) GetNumber() int32 {\n\t\tif x, ok := m.GetUnion().(*Test_Number); ok {\n\t\t\treturn x.Number\n\t\t}\n\t\treturn 0\n\t}\n\n\tfunc (m *Test) GetName() string {\n\t\tif x, ok := m.GetUnion().(*Test_Name); ok {\n\t\t\treturn x.Name\n\t\t}\n\t\treturn \"\"\n\t}\n\n\tfunc init() {\n\t\tproto.RegisterEnum(\"example.FOO\", FOO_name, FOO_value)\n\t}\n\nTo create and play with a Test object:\n\n\tpackage main\n\n\timport (\n\t\t\"log\"\n\n\t\t\"github.com/gogo/protobuf/proto\"\n\t\tpb \"./example.pb\"\n\t)\n\n\tfunc main() {\n\t\ttest := &pb.Test{\n\t\t\tLabel: proto.String(\"hello\"),\n\t\t\tType:  proto.Int32(17),\n\t\t\tReps:  []int64{1, 2, 3},\n\t\t\tOptionalgroup: &pb.Test_OptionalGroup{\n\t\t\t\tRequiredField: proto.String(\"good bye\"),\n\t\t\t},\n\t\t\tUnion: &pb.Test_Name{\"fred\"},\n\t\t}\n\t\tdata, err := proto.Marshal(test)\n\t\tif err != nil {\n\t\t\tlog.Fatal(\"marshaling error: \", err)\n\t\t}\n\t\tnewTest := &pb.Test{}\n\t\terr = proto.Unmarshal(data, newTest)\n\t\tif err != nil {\n\t\t\tlog.Fatal(\"unmarshaling error: \", err)\n\t\t}\n\t\t// Now test and newTest contain the same data.\n\t\tif test.GetLabel() != newTest.GetLabel() {\n\t\t\tlog.Fatalf(\"data mismatch %q != %q\", test.GetLabel(), newTest.GetLabel())\n\t\t}\n\t\t// Use a type switch to determine which oneof was set.\n\t\tswitch u := test.Union.(type) {\n\t\tcase *pb.Test_Number: // u.Number contains the number.\n\t\tcase *pb.Test_Name: // u.Name contains the string.\n\t\t}\n\t\t// etc.\n\t}\n*/\npackage proto\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"sync\"\n)\n\n// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.\n// Marshal reports this when a required field is not initialized.\n// Unmarshal reports this when a required field is missing from the wire data.\ntype RequiredNotSetError struct{ field string }\n\nfunc (e *RequiredNotSetError) Error() string {\n\tif e.field == \"\" {\n\t\treturn fmt.Sprintf(\"proto: required field not set\")\n\t}\n\treturn fmt.Sprintf(\"proto: required field %q not set\", e.field)\n}\nfunc (e *RequiredNotSetError) RequiredNotSet() bool {\n\treturn true\n}\n\ntype invalidUTF8Error struct{ field string }\n\nfunc (e *invalidUTF8Error) Error() string {\n\tif e.field == \"\" {\n\t\treturn \"proto: invalid UTF-8 detected\"\n\t}\n\treturn fmt.Sprintf(\"proto: field %q contains invalid UTF-8\", e.field)\n}\nfunc (e *invalidUTF8Error) InvalidUTF8() bool {\n\treturn true\n}\n\n// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.\n// This error should not be exposed to the external API as such errors should\n// be recreated with the field information.\nvar errInvalidUTF8 = &invalidUTF8Error{}\n\n// isNonFatal reports whether the error is either a RequiredNotSet error\n// or a InvalidUTF8 error.\nfunc isNonFatal(err error) bool {\n\tif re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {\n\t\treturn true\n\t}\n\tif re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype nonFatal struct{ E error }\n\n// Merge merges err into nf and reports whether it was successful.\n// Otherwise it returns false for any fatal non-nil errors.\nfunc (nf *nonFatal) Merge(err error) (ok bool) {\n\tif err == nil {\n\t\treturn true // not an error\n\t}\n\tif !isNonFatal(err) {\n\t\treturn false // fatal error\n\t}\n\tif nf.E == nil {\n\t\tnf.E = err // store first instance of non-fatal error\n\t}\n\treturn true\n}\n\n// Message is implemented by generated protocol buffer messages.\ntype Message interface {\n\tReset()\n\tString() string\n\tProtoMessage()\n}\n\n// A Buffer is a buffer manager for marshaling and unmarshaling\n// protocol buffers.  It may be reused between invocations to\n// reduce memory usage.  It is not necessary to use a Buffer;\n// the global functions Marshal and Unmarshal create a\n// temporary Buffer and are fine for most applications.\ntype Buffer struct {\n\tbuf   []byte // encode/decode byte stream\n\tindex int    // read point\n\n\tdeterministic bool\n}\n\n// NewBuffer allocates a new Buffer and initializes its internal data to\n// the contents of the argument slice.\nfunc NewBuffer(e []byte) *Buffer {\n\treturn &Buffer{buf: e}\n}\n\n// Reset resets the Buffer, ready for marshaling a new protocol buffer.\nfunc (p *Buffer) Reset() {\n\tp.buf = p.buf[0:0] // for reading/writing\n\tp.index = 0        // for reading\n}\n\n// SetBuf replaces the internal buffer with the slice,\n// ready for unmarshaling the contents of the slice.\nfunc (p *Buffer) SetBuf(s []byte) {\n\tp.buf = s\n\tp.index = 0\n}\n\n// Bytes returns the contents of the Buffer.\nfunc (p *Buffer) Bytes() []byte { return p.buf }\n\n// SetDeterministic sets whether to use deterministic serialization.\n//\n// Deterministic serialization guarantees that for a given binary, equal\n// messages will always be serialized to the same bytes. This implies:\n//\n//   - Repeated serialization of a message will return the same bytes.\n//   - Different processes of the same binary (which may be executing on\n//     different machines) will serialize equal messages to the same bytes.\n//\n// Note that the deterministic serialization is NOT canonical across\n// languages. It is not guaranteed to remain stable over time. It is unstable\n// across different builds with schema changes due to unknown fields.\n// Users who need canonical serialization (e.g., persistent storage in a\n// canonical form, fingerprinting, etc.) should define their own\n// canonicalization specification and implement their own serializer rather\n// than relying on this API.\n//\n// If deterministic serialization is requested, map entries will be sorted\n// by keys in lexographical order. This is an implementation detail and\n// subject to change.\nfunc (p *Buffer) SetDeterministic(deterministic bool) {\n\tp.deterministic = deterministic\n}\n\n/*\n * Helper routines for simplifying the creation of optional fields of basic type.\n */\n\n// Bool is a helper routine that allocates a new bool value\n// to store v and returns a pointer to it.\nfunc Bool(v bool) *bool {\n\treturn &v\n}\n\n// Int32 is a helper routine that allocates a new int32 value\n// to store v and returns a pointer to it.\nfunc Int32(v int32) *int32 {\n\treturn &v\n}\n\n// Int is a helper routine that allocates a new int32 value\n// to store v and returns a pointer to it, but unlike Int32\n// its argument value is an int.\nfunc Int(v int) *int32 {\n\tp := new(int32)\n\t*p = int32(v)\n\treturn p\n}\n\n// Int64 is a helper routine that allocates a new int64 value\n// to store v and returns a pointer to it.\nfunc Int64(v int64) *int64 {\n\treturn &v\n}\n\n// Float32 is a helper routine that allocates a new float32 value\n// to store v and returns a pointer to it.\nfunc Float32(v float32) *float32 {\n\treturn &v\n}\n\n// Float64 is a helper routine that allocates a new float64 value\n// to store v and returns a pointer to it.\nfunc Float64(v float64) *float64 {\n\treturn &v\n}\n\n// Uint32 is a helper routine that allocates a new uint32 value\n// to store v and returns a pointer to it.\nfunc Uint32(v uint32) *uint32 {\n\treturn &v\n}\n\n// Uint64 is a helper routine that allocates a new uint64 value\n// to store v and returns a pointer to it.\nfunc Uint64(v uint64) *uint64 {\n\treturn &v\n}\n\n// String is a helper routine that allocates a new string value\n// to store v and returns a pointer to it.\nfunc String(v string) *string {\n\treturn &v\n}\n\n// EnumName is a helper function to simplify printing protocol buffer enums\n// by name.  Given an enum map and a value, it returns a useful string.\nfunc EnumName(m map[int32]string, v int32) string {\n\ts, ok := m[v]\n\tif ok {\n\t\treturn s\n\t}\n\treturn strconv.Itoa(int(v))\n}\n\n// UnmarshalJSONEnum is a helper function to simplify recovering enum int values\n// from their JSON-encoded representation. Given a map from the enum's symbolic\n// names to its int values, and a byte buffer containing the JSON-encoded\n// value, it returns an int32 that can be cast to the enum type by the caller.\n//\n// The function can deal with both JSON representations, numeric and symbolic.\nfunc UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {\n\tif data[0] == '\"' {\n\t\t// New style: enums are strings.\n\t\tvar repr string\n\t\tif err := json.Unmarshal(data, &repr); err != nil {\n\t\t\treturn -1, err\n\t\t}\n\t\tval, ok := m[repr]\n\t\tif !ok {\n\t\t\treturn 0, fmt.Errorf(\"unrecognized enum %s value %q\", enumName, repr)\n\t\t}\n\t\treturn val, nil\n\t}\n\t// Old style: enums are ints.\n\tvar val int32\n\tif err := json.Unmarshal(data, &val); err != nil {\n\t\treturn 0, fmt.Errorf(\"cannot unmarshal %#q into enum %s\", data, enumName)\n\t}\n\treturn val, nil\n}\n\n// DebugPrint dumps the encoded data in b in a debugging format with a header\n// including the string s. Used in testing but made available for general debugging.\nfunc (p *Buffer) DebugPrint(s string, b []byte) {\n\tvar u uint64\n\n\tobuf := p.buf\n\tsindex := p.index\n\tp.buf = b\n\tp.index = 0\n\tdepth := 0\n\n\tfmt.Printf(\"\\n--- %s ---\\n\", s)\n\nout:\n\tfor {\n\t\tfor i := 0; i < depth; i++ {\n\t\t\tfmt.Print(\"  \")\n\t\t}\n\n\t\tindex := p.index\n\t\tif index == len(p.buf) {\n\t\t\tbreak\n\t\t}\n\n\t\top, err := p.DecodeVarint()\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"%3d: fetching op err %v\\n\", index, err)\n\t\t\tbreak out\n\t\t}\n\t\ttag := op >> 3\n\t\twire := op & 7\n\n\t\tswitch wire {\n\t\tdefault:\n\t\t\tfmt.Printf(\"%3d: t=%3d unknown wire=%d\\n\",\n\t\t\t\tindex, tag, wire)\n\t\t\tbreak out\n\n\t\tcase WireBytes:\n\t\t\tvar r []byte\n\n\t\t\tr, err = p.DecodeRawBytes(false)\n\t\t\tif err != nil {\n\t\t\t\tbreak out\n\t\t\t}\n\t\t\tfmt.Printf(\"%3d: t=%3d bytes [%d]\", index, tag, len(r))\n\t\t\tif len(r) <= 6 {\n\t\t\t\tfor i := 0; i < len(r); i++ {\n\t\t\t\t\tfmt.Printf(\" %.2x\", r[i])\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor i := 0; i < 3; i++ {\n\t\t\t\t\tfmt.Printf(\" %.2x\", r[i])\n\t\t\t\t}\n\t\t\t\tfmt.Printf(\" ..\")\n\t\t\t\tfor i := len(r) - 3; i < len(r); i++ {\n\t\t\t\t\tfmt.Printf(\" %.2x\", r[i])\n\t\t\t\t}\n\t\t\t}\n\t\t\tfmt.Printf(\"\\n\")\n\n\t\tcase WireFixed32:\n\t\t\tu, err = p.DecodeFixed32()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Printf(\"%3d: t=%3d fix32 err %v\\n\", index, tag, err)\n\t\t\t\tbreak out\n\t\t\t}\n\t\t\tfmt.Printf(\"%3d: t=%3d fix32 %d\\n\", index, tag, u)\n\n\t\tcase WireFixed64:\n\t\t\tu, err = p.DecodeFixed64()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Printf(\"%3d: t=%3d fix64 err %v\\n\", index, tag, err)\n\t\t\t\tbreak out\n\t\t\t}\n\t\t\tfmt.Printf(\"%3d: t=%3d fix64 %d\\n\", index, tag, u)\n\n\t\tcase WireVarint:\n\t\t\tu, err = p.DecodeVarint()\n\t\t\tif err != nil {\n\t\t\t\tfmt.Printf(\"%3d: t=%3d varint err %v\\n\", index, tag, err)\n\t\t\t\tbreak out\n\t\t\t}\n\t\t\tfmt.Printf(\"%3d: t=%3d varint %d\\n\", index, tag, u)\n\n\t\tcase WireStartGroup:\n\t\t\tfmt.Printf(\"%3d: t=%3d start\\n\", index, tag)\n\t\t\tdepth++\n\n\t\tcase WireEndGroup:\n\t\t\tdepth--\n\t\t\tfmt.Printf(\"%3d: t=%3d end\\n\", index, tag)\n\t\t}\n\t}\n\n\tif depth != 0 {\n\t\tfmt.Printf(\"%3d: start-end not balanced %d\\n\", p.index, depth)\n\t}\n\tfmt.Printf(\"\\n\")\n\n\tp.buf = obuf\n\tp.index = sindex\n}\n\n// SetDefaults sets unset protocol buffer fields to their default values.\n// It only modifies fields that are both unset and have defined defaults.\n// It recursively sets default values in any non-nil sub-messages.\nfunc SetDefaults(pb Message) {\n\tsetDefaults(reflect.ValueOf(pb), true, false)\n}\n\n// v is a struct.\nfunc setDefaults(v reflect.Value, recur, zeros bool) {\n\tif v.Kind() == reflect.Ptr {\n\t\tv = v.Elem()\n\t}\n\n\tdefaultMu.RLock()\n\tdm, ok := defaults[v.Type()]\n\tdefaultMu.RUnlock()\n\tif !ok {\n\t\tdm = buildDefaultMessage(v.Type())\n\t\tdefaultMu.Lock()\n\t\tdefaults[v.Type()] = dm\n\t\tdefaultMu.Unlock()\n\t}\n\n\tfor _, sf := range dm.scalars {\n\t\tf := v.Field(sf.index)\n\t\tif !f.IsNil() {\n\t\t\t// field already set\n\t\t\tcontinue\n\t\t}\n\t\tdv := sf.value\n\t\tif dv == nil && !zeros {\n\t\t\t// no explicit default, and don't want to set zeros\n\t\t\tcontinue\n\t\t}\n\t\tfptr := f.Addr().Interface() // **T\n\t\t// TODO: Consider batching the allocations we do here.\n\t\tswitch sf.kind {\n\t\tcase reflect.Bool:\n\t\t\tb := new(bool)\n\t\t\tif dv != nil {\n\t\t\t\t*b = dv.(bool)\n\t\t\t}\n\t\t\t*(fptr.(**bool)) = b\n\t\tcase reflect.Float32:\n\t\t\tf := new(float32)\n\t\t\tif dv != nil {\n\t\t\t\t*f = dv.(float32)\n\t\t\t}\n\t\t\t*(fptr.(**float32)) = f\n\t\tcase reflect.Float64:\n\t\t\tf := new(float64)\n\t\t\tif dv != nil {\n\t\t\t\t*f = dv.(float64)\n\t\t\t}\n\t\t\t*(fptr.(**float64)) = f\n\t\tcase reflect.Int32:\n\t\t\t// might be an enum\n\t\t\tif ft := f.Type(); ft != int32PtrType {\n\t\t\t\t// enum\n\t\t\t\tf.Set(reflect.New(ft.Elem()))\n\t\t\t\tif dv != nil {\n\t\t\t\t\tf.Elem().SetInt(int64(dv.(int32)))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// int32 field\n\t\t\t\ti := new(int32)\n\t\t\t\tif dv != nil {\n\t\t\t\t\t*i = dv.(int32)\n\t\t\t\t}\n\t\t\t\t*(fptr.(**int32)) = i\n\t\t\t}\n\t\tcase reflect.Int64:\n\t\t\ti := new(int64)\n\t\t\tif dv != nil {\n\t\t\t\t*i = dv.(int64)\n\t\t\t}\n\t\t\t*(fptr.(**int64)) = i\n\t\tcase reflect.String:\n\t\t\ts := new(string)\n\t\t\tif dv != nil {\n\t\t\t\t*s = dv.(string)\n\t\t\t}\n\t\t\t*(fptr.(**string)) = s\n\t\tcase reflect.Uint8:\n\t\t\t// exceptional case: []byte\n\t\t\tvar b []byte\n\t\t\tif dv != nil {\n\t\t\t\tdb := dv.([]byte)\n\t\t\t\tb = make([]byte, len(db))\n\t\t\t\tcopy(b, db)\n\t\t\t} else {\n\t\t\t\tb = []byte{}\n\t\t\t}\n\t\t\t*(fptr.(*[]byte)) = b\n\t\tcase reflect.Uint32:\n\t\t\tu := new(uint32)\n\t\t\tif dv != nil {\n\t\t\t\t*u = dv.(uint32)\n\t\t\t}\n\t\t\t*(fptr.(**uint32)) = u\n\t\tcase reflect.Uint64:\n\t\t\tu := new(uint64)\n\t\t\tif dv != nil {\n\t\t\t\t*u = dv.(uint64)\n\t\t\t}\n\t\t\t*(fptr.(**uint64)) = u\n\t\tdefault:\n\t\t\tlog.Printf(\"proto: can't set default for field %v (sf.kind=%v)\", f, sf.kind)\n\t\t}\n\t}\n\n\tfor _, ni := range dm.nested {\n\t\tf := v.Field(ni)\n\t\t// f is *T or T or []*T or []T\n\t\tswitch f.Kind() {\n\t\tcase reflect.Struct:\n\t\t\tsetDefaults(f, recur, zeros)\n\n\t\tcase reflect.Ptr:\n\t\t\tif f.IsNil() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsetDefaults(f, recur, zeros)\n\n\t\tcase reflect.Slice:\n\t\t\tfor i := 0; i < f.Len(); i++ {\n\t\t\t\te := f.Index(i)\n\t\t\t\tif e.Kind() == reflect.Ptr && e.IsNil() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsetDefaults(e, recur, zeros)\n\t\t\t}\n\n\t\tcase reflect.Map:\n\t\t\tfor _, k := range f.MapKeys() {\n\t\t\t\te := f.MapIndex(k)\n\t\t\t\tif e.IsNil() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsetDefaults(e, recur, zeros)\n\t\t\t}\n\t\t}\n\t}\n}\n\nvar (\n\t// defaults maps a protocol buffer struct type to a slice of the fields,\n\t// with its scalar fields set to their proto-declared non-zero default values.\n\tdefaultMu sync.RWMutex\n\tdefaults  = make(map[reflect.Type]defaultMessage)\n\n\tint32PtrType = reflect.TypeOf((*int32)(nil))\n)\n\n// defaultMessage represents information about the default values of a message.\ntype defaultMessage struct {\n\tscalars []scalarField\n\tnested  []int // struct field index of nested messages\n}\n\ntype scalarField struct {\n\tindex int          // struct field index\n\tkind  reflect.Kind // element type (the T in *T or []T)\n\tvalue interface{}  // the proto-declared default value, or nil\n}\n\n// t is a struct type.\nfunc buildDefaultMessage(t reflect.Type) (dm defaultMessage) {\n\tsprop := GetProperties(t)\n\tfor _, prop := range sprop.Prop {\n\t\tfi, ok := sprop.decoderTags.get(prop.Tag)\n\t\tif !ok {\n\t\t\t// XXX_unrecognized\n\t\t\tcontinue\n\t\t}\n\t\tft := t.Field(fi).Type\n\n\t\tsf, nested, err := fieldDefault(ft, prop)\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\tlog.Print(err)\n\t\tcase nested:\n\t\t\tdm.nested = append(dm.nested, fi)\n\t\tcase sf != nil:\n\t\t\tsf.index = fi\n\t\t\tdm.scalars = append(dm.scalars, *sf)\n\t\t}\n\t}\n\n\treturn dm\n}\n\n// fieldDefault returns the scalarField for field type ft.\n// sf will be nil if the field can not have a default.\n// nestedMessage will be true if this is a nested message.\n// Note that sf.index is not set on return.\nfunc fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {\n\tvar canHaveDefault bool\n\tswitch ft.Kind() {\n\tcase reflect.Struct:\n\t\tnestedMessage = true // non-nullable\n\n\tcase reflect.Ptr:\n\t\tif ft.Elem().Kind() == reflect.Struct {\n\t\t\tnestedMessage = true\n\t\t} else {\n\t\t\tcanHaveDefault = true // proto2 scalar field\n\t\t}\n\n\tcase reflect.Slice:\n\t\tswitch ft.Elem().Kind() {\n\t\tcase reflect.Ptr, reflect.Struct:\n\t\t\tnestedMessage = true // repeated message\n\t\tcase reflect.Uint8:\n\t\t\tcanHaveDefault = true // bytes field\n\t\t}\n\n\tcase reflect.Map:\n\t\tif ft.Elem().Kind() == reflect.Ptr {\n\t\t\tnestedMessage = true // map with message values\n\t\t}\n\t}\n\n\tif !canHaveDefault {\n\t\tif nestedMessage {\n\t\t\treturn nil, true, nil\n\t\t}\n\t\treturn nil, false, nil\n\t}\n\n\t// We now know that ft is a pointer or slice.\n\tsf = &scalarField{kind: ft.Elem().Kind()}\n\n\t// scalar fields without defaults\n\tif !prop.HasDefault {\n\t\treturn sf, false, nil\n\t}\n\n\t// a scalar field: either *T or []byte\n\tswitch ft.Elem().Kind() {\n\tcase reflect.Bool:\n\t\tx, err := strconv.ParseBool(prop.Default)\n\t\tif err != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"proto: bad default bool %q: %v\", prop.Default, err)\n\t\t}\n\t\tsf.value = x\n\tcase reflect.Float32:\n\t\tx, err := strconv.ParseFloat(prop.Default, 32)\n\t\tif err != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"proto: bad default float32 %q: %v\", prop.Default, err)\n\t\t}\n\t\tsf.value = float32(x)\n\tcase reflect.Float64:\n\t\tx, err := strconv.ParseFloat(prop.Default, 64)\n\t\tif err != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"proto: bad default float64 %q: %v\", prop.Default, err)\n\t\t}\n\t\tsf.value = x\n\tcase reflect.Int32:\n\t\tx, err := strconv.ParseInt(prop.Default, 10, 32)\n\t\tif err != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"proto: bad default int32 %q: %v\", prop.Default, err)\n\t\t}\n\t\tsf.value = int32(x)\n\tcase reflect.Int64:\n\t\tx, err := strconv.ParseInt(prop.Default, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"proto: bad default int64 %q: %v\", prop.Default, err)\n\t\t}\n\t\tsf.value = x\n\tcase reflect.String:\n\t\tsf.value = prop.Default\n\tcase reflect.Uint8:\n\t\t// []byte (not *uint8)\n\t\tsf.value = []byte(prop.Default)\n\tcase reflect.Uint32:\n\t\tx, err := strconv.ParseUint(prop.Default, 10, 32)\n\t\tif err != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"proto: bad default uint32 %q: %v\", prop.Default, err)\n\t\t}\n\t\tsf.value = uint32(x)\n\tcase reflect.Uint64:\n\t\tx, err := strconv.ParseUint(prop.Default, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, false, fmt.Errorf(\"proto: bad default uint64 %q: %v\", prop.Default, err)\n\t\t}\n\t\tsf.value = x\n\tdefault:\n\t\treturn nil, false, fmt.Errorf(\"proto: unhandled def kind %v\", ft.Elem().Kind())\n\t}\n\n\treturn sf, false, nil\n}\n\n// mapKeys returns a sort.Interface to be used for sorting the map keys.\n// Map fields may have key types of non-float scalars, strings and enums.\nfunc mapKeys(vs []reflect.Value) sort.Interface {\n\ts := mapKeySorter{vs: vs}\n\n\t// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.\n\tif len(vs) == 0 {\n\t\treturn s\n\t}\n\tswitch vs[0].Kind() {\n\tcase reflect.Int32, reflect.Int64:\n\t\ts.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }\n\tcase reflect.Uint32, reflect.Uint64:\n\t\ts.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }\n\tcase reflect.Bool:\n\t\ts.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true\n\tcase reflect.String:\n\t\ts.less = func(a, b reflect.Value) bool { return a.String() < b.String() }\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unsupported map key type: %v\", vs[0].Kind()))\n\t}\n\n\treturn s\n}\n\ntype mapKeySorter struct {\n\tvs   []reflect.Value\n\tless func(a, b reflect.Value) bool\n}\n\nfunc (s mapKeySorter) Len() int      { return len(s.vs) }\nfunc (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }\nfunc (s mapKeySorter) Less(i, j int) bool {\n\treturn s.less(s.vs[i], s.vs[j])\n}\n\n// isProto3Zero reports whether v is a zero proto3 value.\nfunc isProto3Zero(v reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Uint32, reflect.Uint64:\n\t\treturn v.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.String:\n\t\treturn v.String() == \"\"\n\t}\n\treturn false\n}\n\nconst (\n\t// ProtoPackageIsVersion3 is referenced from generated protocol buffer files\n\t// to assert that that code is compatible with this version of the proto package.\n\tGoGoProtoPackageIsVersion3 = true\n\n\t// ProtoPackageIsVersion2 is referenced from generated protocol buffer files\n\t// to assert that that code is compatible with this version of the proto package.\n\tGoGoProtoPackageIsVersion2 = true\n\n\t// ProtoPackageIsVersion1 is referenced from generated protocol buffer files\n\t// to assert that that code is compatible with this version of the proto package.\n\tGoGoProtoPackageIsVersion1 = true\n)\n\n// InternalMessageInfo is a type used internally by generated .pb.go files.\n// This type is not intended to be used by non-generated code.\n// This type is not subject to any compatibility guarantee.\ntype InternalMessageInfo struct {\n\tmarshal   *marshalInfo\n\tunmarshal *unmarshalInfo\n\tmerge     *mergeInfo\n\tdiscard   *discardInfo\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/lib_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"encoding/json\"\n\t\"strconv\"\n)\n\ntype Sizer interface {\n\tSize() int\n}\n\ntype ProtoSizer interface {\n\tProtoSize() int\n}\n\nfunc MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) {\n\ts, ok := m[value]\n\tif !ok {\n\t\ts = strconv.Itoa(int(value))\n\t}\n\treturn json.Marshal(s)\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/message_set.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n/*\n * Support for message sets.\n */\n\nimport (\n\t\"errors\"\n)\n\n// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.\n// A message type ID is required for storing a protocol buffer in a message set.\nvar errNoMessageTypeID = errors.New(\"proto does not have a message type ID\")\n\n// The first two types (_MessageSet_Item and messageSet)\n// model what the protocol compiler produces for the following protocol message:\n//   message MessageSet {\n//     repeated group Item = 1 {\n//       required int32 type_id = 2;\n//       required string message = 3;\n//     };\n//   }\n// That is the MessageSet wire format. We can't use a proto to generate these\n// because that would introduce a circular dependency between it and this package.\n\ntype _MessageSet_Item struct {\n\tTypeId  *int32 `protobuf:\"varint,2,req,name=type_id\"`\n\tMessage []byte `protobuf:\"bytes,3,req,name=message\"`\n}\n\ntype messageSet struct {\n\tItem             []*_MessageSet_Item `protobuf:\"group,1,rep\"`\n\tXXX_unrecognized []byte\n\t// TODO: caching?\n}\n\n// Make sure messageSet is a Message.\nvar _ Message = (*messageSet)(nil)\n\n// messageTypeIder is an interface satisfied by a protocol buffer type\n// that may be stored in a MessageSet.\ntype messageTypeIder interface {\n\tMessageTypeId() int32\n}\n\nfunc (ms *messageSet) find(pb Message) *_MessageSet_Item {\n\tmti, ok := pb.(messageTypeIder)\n\tif !ok {\n\t\treturn nil\n\t}\n\tid := mti.MessageTypeId()\n\tfor _, item := range ms.Item {\n\t\tif *item.TypeId == id {\n\t\t\treturn item\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (ms *messageSet) Has(pb Message) bool {\n\treturn ms.find(pb) != nil\n}\n\nfunc (ms *messageSet) Unmarshal(pb Message) error {\n\tif item := ms.find(pb); item != nil {\n\t\treturn Unmarshal(item.Message, pb)\n\t}\n\tif _, ok := pb.(messageTypeIder); !ok {\n\t\treturn errNoMessageTypeID\n\t}\n\treturn nil // TODO: return error instead?\n}\n\nfunc (ms *messageSet) Marshal(pb Message) error {\n\tmsg, err := Marshal(pb)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif item := ms.find(pb); item != nil {\n\t\t// reuse existing item\n\t\titem.Message = msg\n\t\treturn nil\n\t}\n\n\tmti, ok := pb.(messageTypeIder)\n\tif !ok {\n\t\treturn errNoMessageTypeID\n\t}\n\n\tmtid := mti.MessageTypeId()\n\tms.Item = append(ms.Item, &_MessageSet_Item{\n\t\tTypeId:  &mtid,\n\t\tMessage: msg,\n\t})\n\treturn nil\n}\n\nfunc (ms *messageSet) Reset()         { *ms = messageSet{} }\nfunc (ms *messageSet) String() string { return CompactTextString(ms) }\nfunc (*messageSet) ProtoMessage()     {}\n\n// Support for the message_set_wire_format message option.\n\nfunc skipVarint(buf []byte) []byte {\n\ti := 0\n\tfor ; buf[i]&0x80 != 0; i++ {\n\t}\n\treturn buf[i+1:]\n}\n\n// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.\n// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.\nfunc unmarshalMessageSet(buf []byte, exts interface{}) error {\n\tvar m map[int32]Extension\n\tswitch exts := exts.(type) {\n\tcase *XXX_InternalExtensions:\n\t\tm = exts.extensionsWrite()\n\tcase map[int32]Extension:\n\t\tm = exts\n\tdefault:\n\t\treturn errors.New(\"proto: not an extension map\")\n\t}\n\n\tms := new(messageSet)\n\tif err := Unmarshal(buf, ms); err != nil {\n\t\treturn err\n\t}\n\tfor _, item := range ms.Item {\n\t\tid := *item.TypeId\n\t\tmsg := item.Message\n\n\t\t// Restore wire type and field number varint, plus length varint.\n\t\t// Be careful to preserve duplicate items.\n\t\tb := EncodeVarint(uint64(id)<<3 | WireBytes)\n\t\tif ext, ok := m[id]; ok {\n\t\t\t// Existing data; rip off the tag and length varint\n\t\t\t// so we join the new data correctly.\n\t\t\t// We can assume that ext.enc is set because we are unmarshaling.\n\t\t\to := ext.enc[len(b):]   // skip wire type and field number\n\t\t\t_, n := DecodeVarint(o) // calculate length of length varint\n\t\t\to = o[n:]               // skip length varint\n\t\t\tmsg = append(o, msg...) // join old data and new data\n\t\t}\n\t\tb = append(b, EncodeVarint(uint64(len(msg)))...)\n\t\tb = append(b, msg...)\n\n\t\tm[id] = Extension{enc: b}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/pointer_reflect.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2012 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// +build purego appengine js\n\n// This file contains an implementation of proto field accesses using package reflect.\n// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can\n// be used on App Engine.\n\npackage proto\n\nimport (\n\t\"reflect\"\n\t\"sync\"\n)\n\nconst unsafeAllowed = false\n\n// A field identifies a field in a struct, accessible from a pointer.\n// In this implementation, a field is identified by the sequence of field indices\n// passed to reflect's FieldByIndex.\ntype field []int\n\n// toField returns a field equivalent to the given reflect field.\nfunc toField(f *reflect.StructField) field {\n\treturn f.Index\n}\n\n// invalidField is an invalid field identifier.\nvar invalidField = field(nil)\n\n// zeroField is a noop when calling pointer.offset.\nvar zeroField = field([]int{})\n\n// IsValid reports whether the field identifier is valid.\nfunc (f field) IsValid() bool { return f != nil }\n\n// The pointer type is for the table-driven decoder.\n// The implementation here uses a reflect.Value of pointer type to\n// create a generic pointer. In pointer_unsafe.go we use unsafe\n// instead of reflect to implement the same (but faster) interface.\ntype pointer struct {\n\tv reflect.Value\n}\n\n// toPointer converts an interface of pointer type to a pointer\n// that points to the same target.\nfunc toPointer(i *Message) pointer {\n\treturn pointer{v: reflect.ValueOf(*i)}\n}\n\n// toAddrPointer converts an interface to a pointer that points to\n// the interface data.\nfunc toAddrPointer(i *interface{}, isptr bool) pointer {\n\tv := reflect.ValueOf(*i)\n\tu := reflect.New(v.Type())\n\tu.Elem().Set(v)\n\treturn pointer{v: u}\n}\n\n// valToPointer converts v to a pointer.  v must be of pointer type.\nfunc valToPointer(v reflect.Value) pointer {\n\treturn pointer{v: v}\n}\n\n// offset converts from a pointer to a structure to a pointer to\n// one of its fields.\nfunc (p pointer) offset(f field) pointer {\n\treturn pointer{v: p.v.Elem().FieldByIndex(f).Addr()}\n}\n\nfunc (p pointer) isNil() bool {\n\treturn p.v.IsNil()\n}\n\n// grow updates the slice s in place to make it one element longer.\n// s must be addressable.\n// Returns the (addressable) new element.\nfunc grow(s reflect.Value) reflect.Value {\n\tn, m := s.Len(), s.Cap()\n\tif n < m {\n\t\ts.SetLen(n + 1)\n\t} else {\n\t\ts.Set(reflect.Append(s, reflect.Zero(s.Type().Elem())))\n\t}\n\treturn s.Index(n)\n}\n\nfunc (p pointer) toInt64() *int64 {\n\treturn p.v.Interface().(*int64)\n}\nfunc (p pointer) toInt64Ptr() **int64 {\n\treturn p.v.Interface().(**int64)\n}\nfunc (p pointer) toInt64Slice() *[]int64 {\n\treturn p.v.Interface().(*[]int64)\n}\n\nvar int32ptr = reflect.TypeOf((*int32)(nil))\n\nfunc (p pointer) toInt32() *int32 {\n\treturn p.v.Convert(int32ptr).Interface().(*int32)\n}\n\n// The toInt32Ptr/Slice methods don't work because of enums.\n// Instead, we must use set/get methods for the int32ptr/slice case.\n/*\n\tfunc (p pointer) toInt32Ptr() **int32 {\n\t\treturn p.v.Interface().(**int32)\n}\n\tfunc (p pointer) toInt32Slice() *[]int32 {\n\t\treturn p.v.Interface().(*[]int32)\n}\n*/\nfunc (p pointer) getInt32Ptr() *int32 {\n\tif p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {\n\t\t// raw int32 type\n\t\treturn p.v.Elem().Interface().(*int32)\n\t}\n\t// an enum\n\treturn p.v.Elem().Convert(int32PtrType).Interface().(*int32)\n}\nfunc (p pointer) setInt32Ptr(v int32) {\n\t// Allocate value in a *int32. Possibly convert that to a *enum.\n\t// Then assign it to a **int32 or **enum.\n\t// Note: we can convert *int32 to *enum, but we can't convert\n\t// **int32 to **enum!\n\tp.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem()))\n}\n\n// getInt32Slice copies []int32 from p as a new slice.\n// This behavior differs from the implementation in pointer_unsafe.go.\nfunc (p pointer) getInt32Slice() []int32 {\n\tif p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {\n\t\t// raw int32 type\n\t\treturn p.v.Elem().Interface().([]int32)\n\t}\n\t// an enum\n\t// Allocate a []int32, then assign []enum's values into it.\n\t// Note: we can't convert []enum to []int32.\n\tslice := p.v.Elem()\n\ts := make([]int32, slice.Len())\n\tfor i := 0; i < slice.Len(); i++ {\n\t\ts[i] = int32(slice.Index(i).Int())\n\t}\n\treturn s\n}\n\n// setInt32Slice copies []int32 into p as a new slice.\n// This behavior differs from the implementation in pointer_unsafe.go.\nfunc (p pointer) setInt32Slice(v []int32) {\n\tif p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {\n\t\t// raw int32 type\n\t\tp.v.Elem().Set(reflect.ValueOf(v))\n\t\treturn\n\t}\n\t// an enum\n\t// Allocate a []enum, then assign []int32's values into it.\n\t// Note: we can't convert []enum to []int32.\n\tslice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v))\n\tfor i, x := range v {\n\t\tslice.Index(i).SetInt(int64(x))\n\t}\n\tp.v.Elem().Set(slice)\n}\nfunc (p pointer) appendInt32Slice(v int32) {\n\tgrow(p.v.Elem()).SetInt(int64(v))\n}\n\nfunc (p pointer) toUint64() *uint64 {\n\treturn p.v.Interface().(*uint64)\n}\nfunc (p pointer) toUint64Ptr() **uint64 {\n\treturn p.v.Interface().(**uint64)\n}\nfunc (p pointer) toUint64Slice() *[]uint64 {\n\treturn p.v.Interface().(*[]uint64)\n}\nfunc (p pointer) toUint32() *uint32 {\n\treturn p.v.Interface().(*uint32)\n}\nfunc (p pointer) toUint32Ptr() **uint32 {\n\treturn p.v.Interface().(**uint32)\n}\nfunc (p pointer) toUint32Slice() *[]uint32 {\n\treturn p.v.Interface().(*[]uint32)\n}\nfunc (p pointer) toBool() *bool {\n\treturn p.v.Interface().(*bool)\n}\nfunc (p pointer) toBoolPtr() **bool {\n\treturn p.v.Interface().(**bool)\n}\nfunc (p pointer) toBoolSlice() *[]bool {\n\treturn p.v.Interface().(*[]bool)\n}\nfunc (p pointer) toFloat64() *float64 {\n\treturn p.v.Interface().(*float64)\n}\nfunc (p pointer) toFloat64Ptr() **float64 {\n\treturn p.v.Interface().(**float64)\n}\nfunc (p pointer) toFloat64Slice() *[]float64 {\n\treturn p.v.Interface().(*[]float64)\n}\nfunc (p pointer) toFloat32() *float32 {\n\treturn p.v.Interface().(*float32)\n}\nfunc (p pointer) toFloat32Ptr() **float32 {\n\treturn p.v.Interface().(**float32)\n}\nfunc (p pointer) toFloat32Slice() *[]float32 {\n\treturn p.v.Interface().(*[]float32)\n}\nfunc (p pointer) toString() *string {\n\treturn p.v.Interface().(*string)\n}\nfunc (p pointer) toStringPtr() **string {\n\treturn p.v.Interface().(**string)\n}\nfunc (p pointer) toStringSlice() *[]string {\n\treturn p.v.Interface().(*[]string)\n}\nfunc (p pointer) toBytes() *[]byte {\n\treturn p.v.Interface().(*[]byte)\n}\nfunc (p pointer) toBytesSlice() *[][]byte {\n\treturn p.v.Interface().(*[][]byte)\n}\nfunc (p pointer) toExtensions() *XXX_InternalExtensions {\n\treturn p.v.Interface().(*XXX_InternalExtensions)\n}\nfunc (p pointer) toOldExtensions() *map[int32]Extension {\n\treturn p.v.Interface().(*map[int32]Extension)\n}\nfunc (p pointer) getPointer() pointer {\n\treturn pointer{v: p.v.Elem()}\n}\nfunc (p pointer) setPointer(q pointer) {\n\tp.v.Elem().Set(q.v)\n}\nfunc (p pointer) appendPointer(q pointer) {\n\tgrow(p.v.Elem()).Set(q.v)\n}\n\n// getPointerSlice copies []*T from p as a new []pointer.\n// This behavior differs from the implementation in pointer_unsafe.go.\nfunc (p pointer) getPointerSlice() []pointer {\n\tif p.v.IsNil() {\n\t\treturn nil\n\t}\n\tn := p.v.Elem().Len()\n\ts := make([]pointer, n)\n\tfor i := 0; i < n; i++ {\n\t\ts[i] = pointer{v: p.v.Elem().Index(i)}\n\t}\n\treturn s\n}\n\n// setPointerSlice copies []pointer into p as a new []*T.\n// This behavior differs from the implementation in pointer_unsafe.go.\nfunc (p pointer) setPointerSlice(v []pointer) {\n\tif v == nil {\n\t\tp.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem())\n\t\treturn\n\t}\n\ts := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v))\n\tfor _, p := range v {\n\t\ts = reflect.Append(s, p.v)\n\t}\n\tp.v.Elem().Set(s)\n}\n\n// getInterfacePointer returns a pointer that points to the\n// interface data of the interface pointed by p.\nfunc (p pointer) getInterfacePointer() pointer {\n\tif p.v.Elem().IsNil() {\n\t\treturn pointer{v: p.v.Elem()}\n\t}\n\treturn pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct\n}\n\nfunc (p pointer) asPointerTo(t reflect.Type) reflect.Value {\n\t// TODO: check that p.v.Type().Elem() == t?\n\treturn p.v\n}\n\nfunc atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\treturn *p\n}\nfunc atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\t*p = v\n}\nfunc atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\treturn *p\n}\nfunc atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\t*p = v\n}\nfunc atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\treturn *p\n}\nfunc atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\t*p = v\n}\nfunc atomicLoadDiscardInfo(p **discardInfo) *discardInfo {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\treturn *p\n}\nfunc atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {\n\tatomicLock.Lock()\n\tdefer atomicLock.Unlock()\n\t*p = v\n}\n\nvar atomicLock sync.Mutex\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// +build purego appengine js\n\n// This file contains an implementation of proto field accesses using package reflect.\n// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can\n// be used on App Engine.\n\npackage proto\n\nimport (\n\t\"reflect\"\n)\n\n// TODO: untested, so probably incorrect.\n\nfunc (p pointer) getRef() pointer {\n\treturn pointer{v: p.v.Addr()}\n}\n\nfunc (p pointer) appendRef(v pointer, typ reflect.Type) {\n\tslice := p.getSlice(typ)\n\telem := v.asPointerTo(typ).Elem()\n\tnewSlice := reflect.Append(slice, elem)\n\tslice.Set(newSlice)\n}\n\nfunc (p pointer) getSlice(typ reflect.Type) reflect.Value {\n\tsliceTyp := reflect.SliceOf(typ)\n\tslice := p.asPointerTo(sliceTyp)\n\tslice = slice.Elem()\n\treturn slice\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2012 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// +build !purego,!appengine,!js\n\n// This file contains the implementation of the proto field accesses using package unsafe.\n\npackage proto\n\nimport (\n\t\"reflect\"\n\t\"sync/atomic\"\n\t\"unsafe\"\n)\n\nconst unsafeAllowed = true\n\n// A field identifies a field in a struct, accessible from a pointer.\n// In this implementation, a field is identified by its byte offset from the start of the struct.\ntype field uintptr\n\n// toField returns a field equivalent to the given reflect field.\nfunc toField(f *reflect.StructField) field {\n\treturn field(f.Offset)\n}\n\n// invalidField is an invalid field identifier.\nconst invalidField = ^field(0)\n\n// zeroField is a noop when calling pointer.offset.\nconst zeroField = field(0)\n\n// IsValid reports whether the field identifier is valid.\nfunc (f field) IsValid() bool {\n\treturn f != invalidField\n}\n\n// The pointer type below is for the new table-driven encoder/decoder.\n// The implementation here uses unsafe.Pointer to create a generic pointer.\n// In pointer_reflect.go we use reflect instead of unsafe to implement\n// the same (but slower) interface.\ntype pointer struct {\n\tp unsafe.Pointer\n}\n\n// size of pointer\nvar ptrSize = unsafe.Sizeof(uintptr(0))\n\n// toPointer converts an interface of pointer type to a pointer\n// that points to the same target.\nfunc toPointer(i *Message) pointer {\n\t// Super-tricky - read pointer out of data word of interface value.\n\t// Saves ~25ns over the equivalent:\n\t// return valToPointer(reflect.ValueOf(*i))\n\treturn pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}\n}\n\n// toAddrPointer converts an interface to a pointer that points to\n// the interface data.\nfunc toAddrPointer(i *interface{}, isptr bool) pointer {\n\t// Super-tricky - read or get the address of data word of interface value.\n\tif isptr {\n\t\t// The interface is of pointer type, thus it is a direct interface.\n\t\t// The data word is the pointer data itself. We take its address.\n\t\treturn pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}\n\t}\n\t// The interface is not of pointer type. The data word is the pointer\n\t// to the data.\n\treturn pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}\n}\n\n// valToPointer converts v to a pointer. v must be of pointer type.\nfunc valToPointer(v reflect.Value) pointer {\n\treturn pointer{p: unsafe.Pointer(v.Pointer())}\n}\n\n// offset converts from a pointer to a structure to a pointer to\n// one of its fields.\nfunc (p pointer) offset(f field) pointer {\n\t// For safety, we should panic if !f.IsValid, however calling panic causes\n\t// this to no longer be inlineable, which is a serious performance cost.\n\t/*\n\t\tif !f.IsValid() {\n\t\t\tpanic(\"invalid field\")\n\t\t}\n\t*/\n\treturn pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}\n}\n\nfunc (p pointer) isNil() bool {\n\treturn p.p == nil\n}\n\nfunc (p pointer) toInt64() *int64 {\n\treturn (*int64)(p.p)\n}\nfunc (p pointer) toInt64Ptr() **int64 {\n\treturn (**int64)(p.p)\n}\nfunc (p pointer) toInt64Slice() *[]int64 {\n\treturn (*[]int64)(p.p)\n}\nfunc (p pointer) toInt32() *int32 {\n\treturn (*int32)(p.p)\n}\n\n// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.\n/*\n\tfunc (p pointer) toInt32Ptr() **int32 {\n\t\treturn (**int32)(p.p)\n\t}\n\tfunc (p pointer) toInt32Slice() *[]int32 {\n\t\treturn (*[]int32)(p.p)\n\t}\n*/\nfunc (p pointer) getInt32Ptr() *int32 {\n\treturn *(**int32)(p.p)\n}\nfunc (p pointer) setInt32Ptr(v int32) {\n\t*(**int32)(p.p) = &v\n}\n\n// getInt32Slice loads a []int32 from p.\n// The value returned is aliased with the original slice.\n// This behavior differs from the implementation in pointer_reflect.go.\nfunc (p pointer) getInt32Slice() []int32 {\n\treturn *(*[]int32)(p.p)\n}\n\n// setInt32Slice stores a []int32 to p.\n// The value set is aliased with the input slice.\n// This behavior differs from the implementation in pointer_reflect.go.\nfunc (p pointer) setInt32Slice(v []int32) {\n\t*(*[]int32)(p.p) = v\n}\n\n// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?\nfunc (p pointer) appendInt32Slice(v int32) {\n\ts := (*[]int32)(p.p)\n\t*s = append(*s, v)\n}\n\nfunc (p pointer) toUint64() *uint64 {\n\treturn (*uint64)(p.p)\n}\nfunc (p pointer) toUint64Ptr() **uint64 {\n\treturn (**uint64)(p.p)\n}\nfunc (p pointer) toUint64Slice() *[]uint64 {\n\treturn (*[]uint64)(p.p)\n}\nfunc (p pointer) toUint32() *uint32 {\n\treturn (*uint32)(p.p)\n}\nfunc (p pointer) toUint32Ptr() **uint32 {\n\treturn (**uint32)(p.p)\n}\nfunc (p pointer) toUint32Slice() *[]uint32 {\n\treturn (*[]uint32)(p.p)\n}\nfunc (p pointer) toBool() *bool {\n\treturn (*bool)(p.p)\n}\nfunc (p pointer) toBoolPtr() **bool {\n\treturn (**bool)(p.p)\n}\nfunc (p pointer) toBoolSlice() *[]bool {\n\treturn (*[]bool)(p.p)\n}\nfunc (p pointer) toFloat64() *float64 {\n\treturn (*float64)(p.p)\n}\nfunc (p pointer) toFloat64Ptr() **float64 {\n\treturn (**float64)(p.p)\n}\nfunc (p pointer) toFloat64Slice() *[]float64 {\n\treturn (*[]float64)(p.p)\n}\nfunc (p pointer) toFloat32() *float32 {\n\treturn (*float32)(p.p)\n}\nfunc (p pointer) toFloat32Ptr() **float32 {\n\treturn (**float32)(p.p)\n}\nfunc (p pointer) toFloat32Slice() *[]float32 {\n\treturn (*[]float32)(p.p)\n}\nfunc (p pointer) toString() *string {\n\treturn (*string)(p.p)\n}\nfunc (p pointer) toStringPtr() **string {\n\treturn (**string)(p.p)\n}\nfunc (p pointer) toStringSlice() *[]string {\n\treturn (*[]string)(p.p)\n}\nfunc (p pointer) toBytes() *[]byte {\n\treturn (*[]byte)(p.p)\n}\nfunc (p pointer) toBytesSlice() *[][]byte {\n\treturn (*[][]byte)(p.p)\n}\nfunc (p pointer) toExtensions() *XXX_InternalExtensions {\n\treturn (*XXX_InternalExtensions)(p.p)\n}\nfunc (p pointer) toOldExtensions() *map[int32]Extension {\n\treturn (*map[int32]Extension)(p.p)\n}\n\n// getPointerSlice loads []*T from p as a []pointer.\n// The value returned is aliased with the original slice.\n// This behavior differs from the implementation in pointer_reflect.go.\nfunc (p pointer) getPointerSlice() []pointer {\n\t// Super-tricky - p should point to a []*T where T is a\n\t// message type. We load it as []pointer.\n\treturn *(*[]pointer)(p.p)\n}\n\n// setPointerSlice stores []pointer into p as a []*T.\n// The value set is aliased with the input slice.\n// This behavior differs from the implementation in pointer_reflect.go.\nfunc (p pointer) setPointerSlice(v []pointer) {\n\t// Super-tricky - p should point to a []*T where T is a\n\t// message type. We store it as []pointer.\n\t*(*[]pointer)(p.p) = v\n}\n\n// getPointer loads the pointer at p and returns it.\nfunc (p pointer) getPointer() pointer {\n\treturn pointer{p: *(*unsafe.Pointer)(p.p)}\n}\n\n// setPointer stores the pointer q at p.\nfunc (p pointer) setPointer(q pointer) {\n\t*(*unsafe.Pointer)(p.p) = q.p\n}\n\n// append q to the slice pointed to by p.\nfunc (p pointer) appendPointer(q pointer) {\n\ts := (*[]unsafe.Pointer)(p.p)\n\t*s = append(*s, q.p)\n}\n\n// getInterfacePointer returns a pointer that points to the\n// interface data of the interface pointed by p.\nfunc (p pointer) getInterfacePointer() pointer {\n\t// Super-tricky - read pointer out of data word of interface value.\n\treturn pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}\n}\n\n// asPointerTo returns a reflect.Value that is a pointer to an\n// object of type t stored at p.\nfunc (p pointer) asPointerTo(t reflect.Type) reflect.Value {\n\treturn reflect.NewAt(t, p.p)\n}\n\nfunc atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {\n\treturn (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))\n}\nfunc atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {\n\tatomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))\n}\nfunc atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {\n\treturn (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))\n}\nfunc atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {\n\tatomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))\n}\nfunc atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {\n\treturn (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))\n}\nfunc atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {\n\tatomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))\n}\nfunc atomicLoadDiscardInfo(p **discardInfo) *discardInfo {\n\treturn (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))\n}\nfunc atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {\n\tatomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n// +build !purego,!appengine,!js\n\n// This file contains the implementation of the proto field accesses using package unsafe.\n\npackage proto\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\nfunc (p pointer) getRef() pointer {\n\treturn pointer{p: (unsafe.Pointer)(&p.p)}\n}\n\nfunc (p pointer) appendRef(v pointer, typ reflect.Type) {\n\tslice := p.getSlice(typ)\n\telem := v.asPointerTo(typ).Elem()\n\tnewSlice := reflect.Append(slice, elem)\n\tslice.Set(newSlice)\n}\n\nfunc (p pointer) getSlice(typ reflect.Type) reflect.Value {\n\tsliceTyp := reflect.SliceOf(typ)\n\tslice := p.asPointerTo(sliceTyp)\n\tslice = slice.Elem()\n\treturn slice\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/properties.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n/*\n * Routines for encoding data into the wire format for protocol buffers.\n */\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\nconst debug bool = false\n\n// Constants that identify the encoding of a value on the wire.\nconst (\n\tWireVarint     = 0\n\tWireFixed64    = 1\n\tWireBytes      = 2\n\tWireStartGroup = 3\n\tWireEndGroup   = 4\n\tWireFixed32    = 5\n)\n\n// tagMap is an optimization over map[int]int for typical protocol buffer\n// use-cases. Encoded protocol buffers are often in tag order with small tag\n// numbers.\ntype tagMap struct {\n\tfastTags []int\n\tslowTags map[int]int\n}\n\n// tagMapFastLimit is the upper bound on the tag number that will be stored in\n// the tagMap slice rather than its map.\nconst tagMapFastLimit = 1024\n\nfunc (p *tagMap) get(t int) (int, bool) {\n\tif t > 0 && t < tagMapFastLimit {\n\t\tif t >= len(p.fastTags) {\n\t\t\treturn 0, false\n\t\t}\n\t\tfi := p.fastTags[t]\n\t\treturn fi, fi >= 0\n\t}\n\tfi, ok := p.slowTags[t]\n\treturn fi, ok\n}\n\nfunc (p *tagMap) put(t int, fi int) {\n\tif t > 0 && t < tagMapFastLimit {\n\t\tfor len(p.fastTags) < t+1 {\n\t\t\tp.fastTags = append(p.fastTags, -1)\n\t\t}\n\t\tp.fastTags[t] = fi\n\t\treturn\n\t}\n\tif p.slowTags == nil {\n\t\tp.slowTags = make(map[int]int)\n\t}\n\tp.slowTags[t] = fi\n}\n\n// StructProperties represents properties for all the fields of a struct.\n// decoderTags and decoderOrigNames should only be used by the decoder.\ntype StructProperties struct {\n\tProp             []*Properties  // properties for each field\n\treqCount         int            // required count\n\tdecoderTags      tagMap         // map from proto tag to struct field number\n\tdecoderOrigNames map[string]int // map from original name to struct field number\n\torder            []int          // list of struct field numbers in tag order\n\n\t// OneofTypes contains information about the oneof fields in this message.\n\t// It is keyed by the original name of a field.\n\tOneofTypes map[string]*OneofProperties\n}\n\n// OneofProperties represents information about a specific field in a oneof.\ntype OneofProperties struct {\n\tType  reflect.Type // pointer to generated struct type for this oneof field\n\tField int          // struct field number of the containing oneof in the message\n\tProp  *Properties\n}\n\n// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.\n// See encode.go, (*Buffer).enc_struct.\n\nfunc (sp *StructProperties) Len() int { return len(sp.order) }\nfunc (sp *StructProperties) Less(i, j int) bool {\n\treturn sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag\n}\nfunc (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] }\n\n// Properties represents the protocol-specific behavior of a single struct field.\ntype Properties struct {\n\tName     string // name of the field, for error messages\n\tOrigName string // original name before protocol compiler (always set)\n\tJSONName string // name to use for JSON; determined by protoc\n\tWire     string\n\tWireType int\n\tTag      int\n\tRequired bool\n\tOptional bool\n\tRepeated bool\n\tPacked   bool   // relevant for repeated primitives only\n\tEnum     string // set for enum types only\n\tproto3   bool   // whether this is known to be a proto3 field\n\toneof    bool   // whether this is a oneof field\n\n\tDefault     string // default value\n\tHasDefault  bool   // whether an explicit default was provided\n\tCustomType  string\n\tCastType    string\n\tStdTime     bool\n\tStdDuration bool\n\tWktPointer  bool\n\n\tstype reflect.Type      // set for struct types only\n\tctype reflect.Type      // set for custom types only\n\tsprop *StructProperties // set for struct types only\n\n\tmtype      reflect.Type // set for map types only\n\tMapKeyProp *Properties  // set for map types only\n\tMapValProp *Properties  // set for map types only\n}\n\n// String formats the properties in the protobuf struct field tag style.\nfunc (p *Properties) String() string {\n\ts := p.Wire\n\ts += \",\"\n\ts += strconv.Itoa(p.Tag)\n\tif p.Required {\n\t\ts += \",req\"\n\t}\n\tif p.Optional {\n\t\ts += \",opt\"\n\t}\n\tif p.Repeated {\n\t\ts += \",rep\"\n\t}\n\tif p.Packed {\n\t\ts += \",packed\"\n\t}\n\ts += \",name=\" + p.OrigName\n\tif p.JSONName != p.OrigName {\n\t\ts += \",json=\" + p.JSONName\n\t}\n\tif p.proto3 {\n\t\ts += \",proto3\"\n\t}\n\tif p.oneof {\n\t\ts += \",oneof\"\n\t}\n\tif len(p.Enum) > 0 {\n\t\ts += \",enum=\" + p.Enum\n\t}\n\tif p.HasDefault {\n\t\ts += \",def=\" + p.Default\n\t}\n\treturn s\n}\n\n// Parse populates p by parsing a string in the protobuf struct field tag style.\nfunc (p *Properties) Parse(s string) {\n\t// \"bytes,49,opt,name=foo,def=hello!\"\n\tfields := strings.Split(s, \",\") // breaks def=, but handled below.\n\tif len(fields) < 2 {\n\t\tlog.Printf(\"proto: tag has too few fields: %q\", s)\n\t\treturn\n\t}\n\n\tp.Wire = fields[0]\n\tswitch p.Wire {\n\tcase \"varint\":\n\t\tp.WireType = WireVarint\n\tcase \"fixed32\":\n\t\tp.WireType = WireFixed32\n\tcase \"fixed64\":\n\t\tp.WireType = WireFixed64\n\tcase \"zigzag32\":\n\t\tp.WireType = WireVarint\n\tcase \"zigzag64\":\n\t\tp.WireType = WireVarint\n\tcase \"bytes\", \"group\":\n\t\tp.WireType = WireBytes\n\t\t// no numeric converter for non-numeric types\n\tdefault:\n\t\tlog.Printf(\"proto: tag has unknown wire type: %q\", s)\n\t\treturn\n\t}\n\n\tvar err error\n\tp.Tag, err = strconv.Atoi(fields[1])\n\tif err != nil {\n\t\treturn\n\t}\n\nouter:\n\tfor i := 2; i < len(fields); i++ {\n\t\tf := fields[i]\n\t\tswitch {\n\t\tcase f == \"req\":\n\t\t\tp.Required = true\n\t\tcase f == \"opt\":\n\t\t\tp.Optional = true\n\t\tcase f == \"rep\":\n\t\t\tp.Repeated = true\n\t\tcase f == \"packed\":\n\t\t\tp.Packed = true\n\t\tcase strings.HasPrefix(f, \"name=\"):\n\t\t\tp.OrigName = f[5:]\n\t\tcase strings.HasPrefix(f, \"json=\"):\n\t\t\tp.JSONName = f[5:]\n\t\tcase strings.HasPrefix(f, \"enum=\"):\n\t\t\tp.Enum = f[5:]\n\t\tcase f == \"proto3\":\n\t\t\tp.proto3 = true\n\t\tcase f == \"oneof\":\n\t\t\tp.oneof = true\n\t\tcase strings.HasPrefix(f, \"def=\"):\n\t\t\tp.HasDefault = true\n\t\t\tp.Default = f[4:] // rest of string\n\t\t\tif i+1 < len(fields) {\n\t\t\t\t// Commas aren't escaped, and def is always last.\n\t\t\t\tp.Default += \",\" + strings.Join(fields[i+1:], \",\")\n\t\t\t\tbreak outer\n\t\t\t}\n\t\tcase strings.HasPrefix(f, \"embedded=\"):\n\t\t\tp.OrigName = strings.Split(f, \"=\")[1]\n\t\tcase strings.HasPrefix(f, \"customtype=\"):\n\t\t\tp.CustomType = strings.Split(f, \"=\")[1]\n\t\tcase strings.HasPrefix(f, \"casttype=\"):\n\t\t\tp.CastType = strings.Split(f, \"=\")[1]\n\t\tcase f == \"stdtime\":\n\t\t\tp.StdTime = true\n\t\tcase f == \"stdduration\":\n\t\t\tp.StdDuration = true\n\t\tcase f == \"wktptr\":\n\t\t\tp.WktPointer = true\n\t\t}\n\t}\n}\n\nvar protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()\n\n// setFieldProps initializes the field properties for submessages and maps.\nfunc (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {\n\tisMap := typ.Kind() == reflect.Map\n\tif len(p.CustomType) > 0 && !isMap {\n\t\tp.ctype = typ\n\t\tp.setTag(lockGetProp)\n\t\treturn\n\t}\n\tif p.StdTime && !isMap {\n\t\tp.setTag(lockGetProp)\n\t\treturn\n\t}\n\tif p.StdDuration && !isMap {\n\t\tp.setTag(lockGetProp)\n\t\treturn\n\t}\n\tif p.WktPointer && !isMap {\n\t\tp.setTag(lockGetProp)\n\t\treturn\n\t}\n\tswitch t1 := typ; t1.Kind() {\n\tcase reflect.Struct:\n\t\tp.stype = typ\n\tcase reflect.Ptr:\n\t\tif t1.Elem().Kind() == reflect.Struct {\n\t\t\tp.stype = t1.Elem()\n\t\t}\n\tcase reflect.Slice:\n\t\tswitch t2 := t1.Elem(); t2.Kind() {\n\t\tcase reflect.Ptr:\n\t\t\tswitch t3 := t2.Elem(); t3.Kind() {\n\t\t\tcase reflect.Struct:\n\t\t\t\tp.stype = t3\n\t\t\t}\n\t\tcase reflect.Struct:\n\t\t\tp.stype = t2\n\t\t}\n\n\tcase reflect.Map:\n\n\t\tp.mtype = t1\n\t\tp.MapKeyProp = &Properties{}\n\t\tp.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), \"Key\", f.Tag.Get(\"protobuf_key\"), nil, lockGetProp)\n\t\tp.MapValProp = &Properties{}\n\t\tvtype := p.mtype.Elem()\n\t\tif vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {\n\t\t\t// The value type is not a message (*T) or bytes ([]byte),\n\t\t\t// so we need encoders for the pointer to this type.\n\t\t\tvtype = reflect.PtrTo(vtype)\n\t\t}\n\n\t\tp.MapValProp.CustomType = p.CustomType\n\t\tp.MapValProp.StdDuration = p.StdDuration\n\t\tp.MapValProp.StdTime = p.StdTime\n\t\tp.MapValProp.WktPointer = p.WktPointer\n\t\tp.MapValProp.init(vtype, \"Value\", f.Tag.Get(\"protobuf_val\"), nil, lockGetProp)\n\t}\n\tp.setTag(lockGetProp)\n}\n\nfunc (p *Properties) setTag(lockGetProp bool) {\n\tif p.stype != nil {\n\t\tif lockGetProp {\n\t\t\tp.sprop = GetProperties(p.stype)\n\t\t} else {\n\t\t\tp.sprop = getPropertiesLocked(p.stype)\n\t\t}\n\t}\n}\n\nvar (\n\tmarshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()\n)\n\n// Init populates the properties from a protocol buffer struct tag.\nfunc (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {\n\tp.init(typ, name, tag, f, true)\n}\n\nfunc (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) {\n\t// \"bytes,49,opt,def=hello!\"\n\tp.Name = name\n\tp.OrigName = name\n\tif tag == \"\" {\n\t\treturn\n\t}\n\tp.Parse(tag)\n\tp.setFieldProps(typ, f, lockGetProp)\n}\n\nvar (\n\tpropertiesMu  sync.RWMutex\n\tpropertiesMap = make(map[reflect.Type]*StructProperties)\n)\n\n// GetProperties returns the list of properties for the type represented by t.\n// t must represent a generated struct type of a protocol message.\nfunc GetProperties(t reflect.Type) *StructProperties {\n\tif t.Kind() != reflect.Struct {\n\t\tpanic(\"proto: type must have kind struct\")\n\t}\n\n\t// Most calls to GetProperties in a long-running program will be\n\t// retrieving details for types we have seen before.\n\tpropertiesMu.RLock()\n\tsprop, ok := propertiesMap[t]\n\tpropertiesMu.RUnlock()\n\tif ok {\n\t\treturn sprop\n\t}\n\n\tpropertiesMu.Lock()\n\tsprop = getPropertiesLocked(t)\n\tpropertiesMu.Unlock()\n\treturn sprop\n}\n\ntype (\n\toneofFuncsIface interface {\n\t\tXXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})\n\t}\n\toneofWrappersIface interface {\n\t\tXXX_OneofWrappers() []interface{}\n\t}\n)\n\n// getPropertiesLocked requires that propertiesMu is held.\nfunc getPropertiesLocked(t reflect.Type) *StructProperties {\n\tif prop, ok := propertiesMap[t]; ok {\n\t\treturn prop\n\t}\n\n\tprop := new(StructProperties)\n\t// in case of recursive protos, fill this in now.\n\tpropertiesMap[t] = prop\n\n\t// build properties\n\tprop.Prop = make([]*Properties, t.NumField())\n\tprop.order = make([]int, t.NumField())\n\n\tisOneofMessage := false\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tf := t.Field(i)\n\t\tp := new(Properties)\n\t\tname := f.Name\n\t\tp.init(f.Type, name, f.Tag.Get(\"protobuf\"), &f, false)\n\n\t\toneof := f.Tag.Get(\"protobuf_oneof\") // special case\n\t\tif oneof != \"\" {\n\t\t\tisOneofMessage = true\n\t\t\t// Oneof fields don't use the traditional protobuf tag.\n\t\t\tp.OrigName = oneof\n\t\t}\n\t\tprop.Prop[i] = p\n\t\tprop.order[i] = i\n\t\tif debug {\n\t\t\tprint(i, \" \", f.Name, \" \", t.String(), \" \")\n\t\t\tif p.Tag > 0 {\n\t\t\t\tprint(p.String())\n\t\t\t}\n\t\t\tprint(\"\\n\")\n\t\t}\n\t}\n\n\t// Re-order prop.order.\n\tsort.Sort(prop)\n\n\tif isOneofMessage {\n\t\tvar oots []interface{}\n\t\tswitch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {\n\t\tcase oneofFuncsIface:\n\t\t\t_, _, _, oots = m.XXX_OneofFuncs()\n\t\tcase oneofWrappersIface:\n\t\t\toots = m.XXX_OneofWrappers()\n\t\t}\n\t\tif len(oots) > 0 {\n\t\t\t// Interpret oneof metadata.\n\t\t\tprop.OneofTypes = make(map[string]*OneofProperties)\n\t\t\tfor _, oot := range oots {\n\t\t\t\toop := &OneofProperties{\n\t\t\t\t\tType: reflect.ValueOf(oot).Type(), // *T\n\t\t\t\t\tProp: new(Properties),\n\t\t\t\t}\n\t\t\t\tsft := oop.Type.Elem().Field(0)\n\t\t\t\toop.Prop.Name = sft.Name\n\t\t\t\toop.Prop.Parse(sft.Tag.Get(\"protobuf\"))\n\t\t\t\t// There will be exactly one interface field that\n\t\t\t\t// this new value is assignable to.\n\t\t\t\tfor i := 0; i < t.NumField(); i++ {\n\t\t\t\t\tf := t.Field(i)\n\t\t\t\t\tif f.Type.Kind() != reflect.Interface {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif !oop.Type.AssignableTo(f.Type) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\toop.Field = i\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tprop.OneofTypes[oop.Prop.OrigName] = oop\n\t\t\t}\n\t\t}\n\t}\n\n\t// build required counts\n\t// build tags\n\treqCount := 0\n\tprop.decoderOrigNames = make(map[string]int)\n\tfor i, p := range prop.Prop {\n\t\tif strings.HasPrefix(p.Name, \"XXX_\") {\n\t\t\t// Internal fields should not appear in tags/origNames maps.\n\t\t\t// They are handled specially when encoding and decoding.\n\t\t\tcontinue\n\t\t}\n\t\tif p.Required {\n\t\t\treqCount++\n\t\t}\n\t\tprop.decoderTags.put(p.Tag, i)\n\t\tprop.decoderOrigNames[p.OrigName] = i\n\t}\n\tprop.reqCount = reqCount\n\n\treturn prop\n}\n\n// A global registry of enum types.\n// The generated code will register the generated maps by calling RegisterEnum.\n\nvar enumValueMaps = make(map[string]map[string]int32)\nvar enumStringMaps = make(map[string]map[int32]string)\n\n// RegisterEnum is called from the generated code to install the enum descriptor\n// maps into the global table to aid parsing text format protocol buffers.\nfunc RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) {\n\tif _, ok := enumValueMaps[typeName]; ok {\n\t\tpanic(\"proto: duplicate enum registered: \" + typeName)\n\t}\n\tenumValueMaps[typeName] = valueMap\n\tif _, ok := enumStringMaps[typeName]; ok {\n\t\tpanic(\"proto: duplicate enum registered: \" + typeName)\n\t}\n\tenumStringMaps[typeName] = unusedNameMap\n}\n\n// EnumValueMap returns the mapping from names to integers of the\n// enum type enumType, or a nil if not found.\nfunc EnumValueMap(enumType string) map[string]int32 {\n\treturn enumValueMaps[enumType]\n}\n\n// A registry of all linked message types.\n// The string is a fully-qualified proto name (\"pkg.Message\").\nvar (\n\tprotoTypedNils = make(map[string]Message)      // a map from proto names to typed nil pointers\n\tprotoMapTypes  = make(map[string]reflect.Type) // a map from proto names to map types\n\trevProtoTypes  = make(map[reflect.Type]string)\n)\n\n// RegisterType is called from generated code and maps from the fully qualified\n// proto name to the type (pointer to struct) of the protocol buffer.\nfunc RegisterType(x Message, name string) {\n\tif _, ok := protoTypedNils[name]; ok {\n\t\t// TODO: Some day, make this a panic.\n\t\tlog.Printf(\"proto: duplicate proto type registered: %s\", name)\n\t\treturn\n\t}\n\tt := reflect.TypeOf(x)\n\tif v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {\n\t\t// Generated code always calls RegisterType with nil x.\n\t\t// This check is just for extra safety.\n\t\tprotoTypedNils[name] = x\n\t} else {\n\t\tprotoTypedNils[name] = reflect.Zero(t).Interface().(Message)\n\t}\n\trevProtoTypes[t] = name\n}\n\n// RegisterMapType is called from generated code and maps from the fully qualified\n// proto name to the native map type of the proto map definition.\nfunc RegisterMapType(x interface{}, name string) {\n\tif reflect.TypeOf(x).Kind() != reflect.Map {\n\t\tpanic(fmt.Sprintf(\"RegisterMapType(%T, %q); want map\", x, name))\n\t}\n\tif _, ok := protoMapTypes[name]; ok {\n\t\tlog.Printf(\"proto: duplicate proto type registered: %s\", name)\n\t\treturn\n\t}\n\tt := reflect.TypeOf(x)\n\tprotoMapTypes[name] = t\n\trevProtoTypes[t] = name\n}\n\n// MessageName returns the fully-qualified proto name for the given message type.\nfunc MessageName(x Message) string {\n\ttype xname interface {\n\t\tXXX_MessageName() string\n\t}\n\tif m, ok := x.(xname); ok {\n\t\treturn m.XXX_MessageName()\n\t}\n\treturn revProtoTypes[reflect.TypeOf(x)]\n}\n\n// MessageType returns the message type (pointer to struct) for a named message.\n// The type is not guaranteed to implement proto.Message if the name refers to a\n// map entry.\nfunc MessageType(name string) reflect.Type {\n\tif t, ok := protoTypedNils[name]; ok {\n\t\treturn reflect.TypeOf(t)\n\t}\n\treturn protoMapTypes[name]\n}\n\n// A registry of all linked proto files.\nvar (\n\tprotoFiles = make(map[string][]byte) // file name => fileDescriptor\n)\n\n// RegisterFile is called from generated code and maps from the\n// full file name of a .proto file to its compressed FileDescriptorProto.\nfunc RegisterFile(filename string, fileDescriptor []byte) {\n\tprotoFiles[filename] = fileDescriptor\n}\n\n// FileDescriptor returns the compressed FileDescriptorProto for a .proto file.\nfunc FileDescriptor(filename string) []byte { return protoFiles[filename] }\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/properties_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"reflect\"\n)\n\nvar sizerType = reflect.TypeOf((*Sizer)(nil)).Elem()\nvar protosizerType = reflect.TypeOf((*ProtoSizer)(nil)).Elem()\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/skip_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\nfunc Skip(data []byte) (n int, err error) {\n\tl := len(data)\n\tindex := 0\n\tfor index < l {\n\t\tvar wire uint64\n\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\tif index >= l {\n\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb := data[index]\n\t\t\tindex++\n\t\t\twire |= (uint64(b) & 0x7F) << shift\n\t\t\tif b < 0x80 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\twireType := int(wire & 0x7)\n\t\tswitch wireType {\n\t\tcase 0:\n\t\t\tfor {\n\t\t\t\tif index >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tindex++\n\t\t\t\tif data[index-1] < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn index, nil\n\t\tcase 1:\n\t\t\tindex += 8\n\t\t\treturn index, nil\n\t\tcase 2:\n\t\t\tvar length int\n\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\tif index >= l {\n\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t}\n\t\t\t\tb := data[index]\n\t\t\t\tindex++\n\t\t\t\tlength |= (int(b) & 0x7F) << shift\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tindex += length\n\t\t\treturn index, nil\n\t\tcase 3:\n\t\t\tfor {\n\t\t\t\tvar innerWire uint64\n\t\t\t\tvar start int = index\n\t\t\t\tfor shift := uint(0); ; shift += 7 {\n\t\t\t\t\tif index >= l {\n\t\t\t\t\t\treturn 0, io.ErrUnexpectedEOF\n\t\t\t\t\t}\n\t\t\t\t\tb := data[index]\n\t\t\t\t\tindex++\n\t\t\t\t\tinnerWire |= (uint64(b) & 0x7F) << shift\n\t\t\t\t\tif b < 0x80 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tinnerWireType := int(innerWire & 0x7)\n\t\t\t\tif innerWireType == 4 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnext, err := Skip(data[start:])\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t\tindex = start + next\n\t\t\t}\n\t\t\treturn index, nil\n\t\tcase 4:\n\t\t\treturn index, nil\n\t\tcase 5:\n\t\t\tindex += 4\n\t\t\treturn index, nil\n\t\tdefault:\n\t\t\treturn 0, fmt.Errorf(\"proto: illegal wireType %d\", wireType)\n\t\t}\n\t}\n\tpanic(\"unreachable\")\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/table_marshal.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2016 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"unicode/utf8\"\n)\n\n// a sizer takes a pointer to a field and the size of its tag, computes the size of\n// the encoded data.\ntype sizer func(pointer, int) int\n\n// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),\n// marshals the field to the end of the slice, returns the slice and error (if any).\ntype marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)\n\n// marshalInfo is the information used for marshaling a message.\ntype marshalInfo struct {\n\ttyp          reflect.Type\n\tfields       []*marshalFieldInfo\n\tunrecognized field                      // offset of XXX_unrecognized\n\textensions   field                      // offset of XXX_InternalExtensions\n\tv1extensions field                      // offset of XXX_extensions\n\tsizecache    field                      // offset of XXX_sizecache\n\tinitialized  int32                      // 0 -- only typ is set, 1 -- fully initialized\n\tmessageset   bool                       // uses message set wire format\n\thasmarshaler bool                       // has custom marshaler\n\tsync.RWMutex                            // protect extElems map, also for initialization\n\textElems     map[int32]*marshalElemInfo // info of extension elements\n\n\thassizer      bool // has custom sizer\n\thasprotosizer bool // has custom protosizer\n\n\tbytesExtensions field // offset of XXX_extensions where the field type is []byte\n}\n\n// marshalFieldInfo is the information used for marshaling a field of a message.\ntype marshalFieldInfo struct {\n\tfield      field\n\twiretag    uint64 // tag in wire format\n\ttagsize    int    // size of tag in wire format\n\tsizer      sizer\n\tmarshaler  marshaler\n\tisPointer  bool\n\trequired   bool                              // field is required\n\tname       string                            // name of the field, for error reporting\n\toneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements\n}\n\n// marshalElemInfo is the information used for marshaling an extension or oneof element.\ntype marshalElemInfo struct {\n\twiretag   uint64 // tag in wire format\n\ttagsize   int    // size of tag in wire format\n\tsizer     sizer\n\tmarshaler marshaler\n\tisptr     bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)\n}\n\nvar (\n\tmarshalInfoMap  = map[reflect.Type]*marshalInfo{}\n\tmarshalInfoLock sync.Mutex\n\n\tuint8SliceType = reflect.TypeOf(([]uint8)(nil)).Kind()\n)\n\n// getMarshalInfo returns the information to marshal a given type of message.\n// The info it returns may not necessarily initialized.\n// t is the type of the message (NOT the pointer to it).\nfunc getMarshalInfo(t reflect.Type) *marshalInfo {\n\tmarshalInfoLock.Lock()\n\tu, ok := marshalInfoMap[t]\n\tif !ok {\n\t\tu = &marshalInfo{typ: t}\n\t\tmarshalInfoMap[t] = u\n\t}\n\tmarshalInfoLock.Unlock()\n\treturn u\n}\n\n// Size is the entry point from generated code,\n// and should be ONLY called by generated code.\n// It computes the size of encoded data of msg.\n// a is a pointer to a place to store cached marshal info.\nfunc (a *InternalMessageInfo) Size(msg Message) int {\n\tu := getMessageMarshalInfo(msg, a)\n\tptr := toPointer(&msg)\n\tif ptr.isNil() {\n\t\t// We get here if msg is a typed nil ((*SomeMessage)(nil)),\n\t\t// so it satisfies the interface, and msg == nil wouldn't\n\t\t// catch it. We don't want crash in this case.\n\t\treturn 0\n\t}\n\treturn u.size(ptr)\n}\n\n// Marshal is the entry point from generated code,\n// and should be ONLY called by generated code.\n// It marshals msg to the end of b.\n// a is a pointer to a place to store cached marshal info.\nfunc (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) {\n\tu := getMessageMarshalInfo(msg, a)\n\tptr := toPointer(&msg)\n\tif ptr.isNil() {\n\t\t// We get here if msg is a typed nil ((*SomeMessage)(nil)),\n\t\t// so it satisfies the interface, and msg == nil wouldn't\n\t\t// catch it. We don't want crash in this case.\n\t\treturn b, ErrNil\n\t}\n\treturn u.marshal(b, ptr, deterministic)\n}\n\nfunc getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo {\n\t// u := a.marshal, but atomically.\n\t// We use an atomic here to ensure memory consistency.\n\tu := atomicLoadMarshalInfo(&a.marshal)\n\tif u == nil {\n\t\t// Get marshal information from type of message.\n\t\tt := reflect.ValueOf(msg).Type()\n\t\tif t.Kind() != reflect.Ptr {\n\t\t\tpanic(fmt.Sprintf(\"cannot handle non-pointer message type %v\", t))\n\t\t}\n\t\tu = getMarshalInfo(t.Elem())\n\t\t// Store it in the cache for later users.\n\t\t// a.marshal = u, but atomically.\n\t\tatomicStoreMarshalInfo(&a.marshal, u)\n\t}\n\treturn u\n}\n\n// size is the main function to compute the size of the encoded data of a message.\n// ptr is the pointer to the message.\nfunc (u *marshalInfo) size(ptr pointer) int {\n\tif atomic.LoadInt32(&u.initialized) == 0 {\n\t\tu.computeMarshalInfo()\n\t}\n\n\t// If the message can marshal itself, let it do it, for compatibility.\n\t// NOTE: This is not efficient.\n\tif u.hasmarshaler {\n\t\t// Uses the message's Size method if available\n\t\tif u.hassizer {\n\t\t\ts := ptr.asPointerTo(u.typ).Interface().(Sizer)\n\t\t\treturn s.Size()\n\t\t}\n\t\t// Uses the message's ProtoSize method if available\n\t\tif u.hasprotosizer {\n\t\t\ts := ptr.asPointerTo(u.typ).Interface().(ProtoSizer)\n\t\t\treturn s.ProtoSize()\n\t\t}\n\n\t\tm := ptr.asPointerTo(u.typ).Interface().(Marshaler)\n\t\tb, _ := m.Marshal()\n\t\treturn len(b)\n\t}\n\n\tn := 0\n\tfor _, f := range u.fields {\n\t\tif f.isPointer && ptr.offset(f.field).getPointer().isNil() {\n\t\t\t// nil pointer always marshals to nothing\n\t\t\tcontinue\n\t\t}\n\t\tn += f.sizer(ptr.offset(f.field), f.tagsize)\n\t}\n\tif u.extensions.IsValid() {\n\t\te := ptr.offset(u.extensions).toExtensions()\n\t\tif u.messageset {\n\t\t\tn += u.sizeMessageSet(e)\n\t\t} else {\n\t\t\tn += u.sizeExtensions(e)\n\t\t}\n\t}\n\tif u.v1extensions.IsValid() {\n\t\tm := *ptr.offset(u.v1extensions).toOldExtensions()\n\t\tn += u.sizeV1Extensions(m)\n\t}\n\tif u.bytesExtensions.IsValid() {\n\t\ts := *ptr.offset(u.bytesExtensions).toBytes()\n\t\tn += len(s)\n\t}\n\tif u.unrecognized.IsValid() {\n\t\ts := *ptr.offset(u.unrecognized).toBytes()\n\t\tn += len(s)\n\t}\n\n\t// cache the result for use in marshal\n\tif u.sizecache.IsValid() {\n\t\tatomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n))\n\t}\n\treturn n\n}\n\n// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),\n// fall back to compute the size.\nfunc (u *marshalInfo) cachedsize(ptr pointer) int {\n\tif u.sizecache.IsValid() {\n\t\treturn int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32()))\n\t}\n\treturn u.size(ptr)\n}\n\n// marshal is the main function to marshal a message. It takes a byte slice and appends\n// the encoded data to the end of the slice, returns the slice and error (if any).\n// ptr is the pointer to the message.\n// If deterministic is true, map is marshaled in deterministic order.\nfunc (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) {\n\tif atomic.LoadInt32(&u.initialized) == 0 {\n\t\tu.computeMarshalInfo()\n\t}\n\n\t// If the message can marshal itself, let it do it, for compatibility.\n\t// NOTE: This is not efficient.\n\tif u.hasmarshaler {\n\t\tm := ptr.asPointerTo(u.typ).Interface().(Marshaler)\n\t\tb1, err := m.Marshal()\n\t\tb = append(b, b1...)\n\t\treturn b, err\n\t}\n\n\tvar err, errLater error\n\t// The old marshaler encodes extensions at beginning.\n\tif u.extensions.IsValid() {\n\t\te := ptr.offset(u.extensions).toExtensions()\n\t\tif u.messageset {\n\t\t\tb, err = u.appendMessageSet(b, e, deterministic)\n\t\t} else {\n\t\t\tb, err = u.appendExtensions(b, e, deterministic)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn b, err\n\t\t}\n\t}\n\tif u.v1extensions.IsValid() {\n\t\tm := *ptr.offset(u.v1extensions).toOldExtensions()\n\t\tb, err = u.appendV1Extensions(b, m, deterministic)\n\t\tif err != nil {\n\t\t\treturn b, err\n\t\t}\n\t}\n\tif u.bytesExtensions.IsValid() {\n\t\ts := *ptr.offset(u.bytesExtensions).toBytes()\n\t\tb = append(b, s...)\n\t}\n\tfor _, f := range u.fields {\n\t\tif f.required {\n\t\t\tif f.isPointer && ptr.offset(f.field).getPointer().isNil() {\n\t\t\t\t// Required field is not set.\n\t\t\t\t// We record the error but keep going, to give a complete marshaling.\n\t\t\t\tif errLater == nil {\n\t\t\t\t\terrLater = &RequiredNotSetError{f.name}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif f.isPointer && ptr.offset(f.field).getPointer().isNil() {\n\t\t\t// nil pointer always marshals to nothing\n\t\t\tcontinue\n\t\t}\n\t\tb, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic)\n\t\tif err != nil {\n\t\t\tif err1, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\t// Required field in submessage is not set.\n\t\t\t\t// We record the error but keep going, to give a complete marshaling.\n\t\t\t\tif errLater == nil {\n\t\t\t\t\terrLater = &RequiredNotSetError{f.name + \".\" + err1.field}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err == errRepeatedHasNil {\n\t\t\t\terr = errors.New(\"proto: repeated field \" + f.name + \" has nil element\")\n\t\t\t}\n\t\t\tif err == errInvalidUTF8 {\n\t\t\t\tif errLater == nil {\n\t\t\t\t\tfullName := revProtoTypes[reflect.PtrTo(u.typ)] + \".\" + f.name\n\t\t\t\t\terrLater = &invalidUTF8Error{fullName}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn b, err\n\t\t}\n\t}\n\tif u.unrecognized.IsValid() {\n\t\ts := *ptr.offset(u.unrecognized).toBytes()\n\t\tb = append(b, s...)\n\t}\n\treturn b, errLater\n}\n\n// computeMarshalInfo initializes the marshal info.\nfunc (u *marshalInfo) computeMarshalInfo() {\n\tu.Lock()\n\tdefer u.Unlock()\n\tif u.initialized != 0 { // non-atomic read is ok as it is protected by the lock\n\t\treturn\n\t}\n\n\tt := u.typ\n\tu.unrecognized = invalidField\n\tu.extensions = invalidField\n\tu.v1extensions = invalidField\n\tu.bytesExtensions = invalidField\n\tu.sizecache = invalidField\n\tisOneofMessage := false\n\n\tif reflect.PtrTo(t).Implements(sizerType) {\n\t\tu.hassizer = true\n\t}\n\tif reflect.PtrTo(t).Implements(protosizerType) {\n\t\tu.hasprotosizer = true\n\t}\n\t// If the message can marshal itself, let it do it, for compatibility.\n\t// NOTE: This is not efficient.\n\tif reflect.PtrTo(t).Implements(marshalerType) {\n\t\tu.hasmarshaler = true\n\t\tatomic.StoreInt32(&u.initialized, 1)\n\t\treturn\n\t}\n\n\tn := t.NumField()\n\n\t// deal with XXX fields first\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tf := t.Field(i)\n\t\tif f.Tag.Get(\"protobuf_oneof\") != \"\" {\n\t\t\tisOneofMessage = true\n\t\t}\n\t\tif !strings.HasPrefix(f.Name, \"XXX_\") {\n\t\t\tcontinue\n\t\t}\n\t\tswitch f.Name {\n\t\tcase \"XXX_sizecache\":\n\t\t\tu.sizecache = toField(&f)\n\t\tcase \"XXX_unrecognized\":\n\t\t\tu.unrecognized = toField(&f)\n\t\tcase \"XXX_InternalExtensions\":\n\t\t\tu.extensions = toField(&f)\n\t\t\tu.messageset = f.Tag.Get(\"protobuf_messageset\") == \"1\"\n\t\tcase \"XXX_extensions\":\n\t\t\tif f.Type.Kind() == reflect.Map {\n\t\t\t\tu.v1extensions = toField(&f)\n\t\t\t} else {\n\t\t\t\tu.bytesExtensions = toField(&f)\n\t\t\t}\n\t\tcase \"XXX_NoUnkeyedLiteral\":\n\t\t\t// nothing to do\n\t\tdefault:\n\t\t\tpanic(\"unknown XXX field: \" + f.Name)\n\t\t}\n\t\tn--\n\t}\n\n\t// get oneof implementers\n\tvar oneofImplementers []interface{}\n\t// gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler\n\tif isOneofMessage {\n\t\tswitch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {\n\t\tcase oneofFuncsIface:\n\t\t\t_, _, _, oneofImplementers = m.XXX_OneofFuncs()\n\t\tcase oneofWrappersIface:\n\t\t\toneofImplementers = m.XXX_OneofWrappers()\n\t\t}\n\t}\n\n\t// normal fields\n\tfields := make([]marshalFieldInfo, n) // batch allocation\n\tu.fields = make([]*marshalFieldInfo, 0, n)\n\tfor i, j := 0, 0; i < t.NumField(); i++ {\n\t\tf := t.Field(i)\n\n\t\tif strings.HasPrefix(f.Name, \"XXX_\") {\n\t\t\tcontinue\n\t\t}\n\t\tfield := &fields[j]\n\t\tj++\n\t\tfield.name = f.Name\n\t\tu.fields = append(u.fields, field)\n\t\tif f.Tag.Get(\"protobuf_oneof\") != \"\" {\n\t\t\tfield.computeOneofFieldInfo(&f, oneofImplementers)\n\t\t\tcontinue\n\t\t}\n\t\tif f.Tag.Get(\"protobuf\") == \"\" {\n\t\t\t// field has no tag (not in generated message), ignore it\n\t\t\tu.fields = u.fields[:len(u.fields)-1]\n\t\t\tj--\n\t\t\tcontinue\n\t\t}\n\t\tfield.computeMarshalFieldInfo(&f)\n\t}\n\n\t// fields are marshaled in tag order on the wire.\n\tsort.Sort(byTag(u.fields))\n\n\tatomic.StoreInt32(&u.initialized, 1)\n}\n\n// helper for sorting fields by tag\ntype byTag []*marshalFieldInfo\n\nfunc (a byTag) Len() int           { return len(a) }\nfunc (a byTag) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }\nfunc (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag }\n\n// getExtElemInfo returns the information to marshal an extension element.\n// The info it returns is initialized.\nfunc (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {\n\t// get from cache first\n\tu.RLock()\n\te, ok := u.extElems[desc.Field]\n\tu.RUnlock()\n\tif ok {\n\t\treturn e\n\t}\n\n\tt := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct\n\ttags := strings.Split(desc.Tag, \",\")\n\ttag, err := strconv.Atoi(tags[1])\n\tif err != nil {\n\t\tpanic(\"tag is not an integer\")\n\t}\n\twt := wiretype(tags[0])\n\tsizr, marshalr := typeMarshaler(t, tags, false, false)\n\te = &marshalElemInfo{\n\t\twiretag:   uint64(tag)<<3 | wt,\n\t\ttagsize:   SizeVarint(uint64(tag) << 3),\n\t\tsizer:     sizr,\n\t\tmarshaler: marshalr,\n\t\tisptr:     t.Kind() == reflect.Ptr,\n\t}\n\n\t// update cache\n\tu.Lock()\n\tif u.extElems == nil {\n\t\tu.extElems = make(map[int32]*marshalElemInfo)\n\t}\n\tu.extElems[desc.Field] = e\n\tu.Unlock()\n\treturn e\n}\n\n// computeMarshalFieldInfo fills up the information to marshal a field.\nfunc (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {\n\t// parse protobuf tag of the field.\n\t// tag has format of \"bytes,49,opt,name=foo,def=hello!\"\n\ttags := strings.Split(f.Tag.Get(\"protobuf\"), \",\")\n\tif tags[0] == \"\" {\n\t\treturn\n\t}\n\ttag, err := strconv.Atoi(tags[1])\n\tif err != nil {\n\t\tpanic(\"tag is not an integer\")\n\t}\n\twt := wiretype(tags[0])\n\tif tags[2] == \"req\" {\n\t\tfi.required = true\n\t}\n\tfi.setTag(f, tag, wt)\n\tfi.setMarshaler(f, tags)\n}\n\nfunc (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {\n\tfi.field = toField(f)\n\tfi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.\n\tfi.isPointer = true\n\tfi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)\n\tfi.oneofElems = make(map[reflect.Type]*marshalElemInfo)\n\n\tityp := f.Type // interface type\n\tfor _, o := range oneofImplementers {\n\t\tt := reflect.TypeOf(o)\n\t\tif !t.Implements(ityp) {\n\t\t\tcontinue\n\t\t}\n\t\tsf := t.Elem().Field(0) // oneof implementer is a struct with a single field\n\t\ttags := strings.Split(sf.Tag.Get(\"protobuf\"), \",\")\n\t\ttag, err := strconv.Atoi(tags[1])\n\t\tif err != nil {\n\t\t\tpanic(\"tag is not an integer\")\n\t\t}\n\t\twt := wiretype(tags[0])\n\t\tsizr, marshalr := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value\n\t\tfi.oneofElems[t.Elem()] = &marshalElemInfo{\n\t\t\twiretag:   uint64(tag)<<3 | wt,\n\t\t\ttagsize:   SizeVarint(uint64(tag) << 3),\n\t\t\tsizer:     sizr,\n\t\t\tmarshaler: marshalr,\n\t\t}\n\t}\n}\n\n// wiretype returns the wire encoding of the type.\nfunc wiretype(encoding string) uint64 {\n\tswitch encoding {\n\tcase \"fixed32\":\n\t\treturn WireFixed32\n\tcase \"fixed64\":\n\t\treturn WireFixed64\n\tcase \"varint\", \"zigzag32\", \"zigzag64\":\n\t\treturn WireVarint\n\tcase \"bytes\":\n\t\treturn WireBytes\n\tcase \"group\":\n\t\treturn WireStartGroup\n\t}\n\tpanic(\"unknown wire type \" + encoding)\n}\n\n// setTag fills up the tag (in wire format) and its size in the info of a field.\nfunc (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) {\n\tfi.field = toField(f)\n\tfi.wiretag = uint64(tag)<<3 | wt\n\tfi.tagsize = SizeVarint(uint64(tag) << 3)\n}\n\n// setMarshaler fills up the sizer and marshaler in the info of a field.\nfunc (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) {\n\tswitch f.Type.Kind() {\n\tcase reflect.Map:\n\t\t// map field\n\t\tfi.isPointer = true\n\t\tfi.sizer, fi.marshaler = makeMapMarshaler(f)\n\t\treturn\n\tcase reflect.Ptr, reflect.Slice:\n\t\tfi.isPointer = true\n\t}\n\tfi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false)\n}\n\n// typeMarshaler returns the sizer and marshaler of a given field.\n// t is the type of the field.\n// tags is the generated \"protobuf\" tag of the field.\n// If nozero is true, zero value is not marshaled to the wire.\n// If oneof is true, it is a oneof field.\nfunc typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) {\n\tencoding := tags[0]\n\n\tpointer := false\n\tslice := false\n\tif t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {\n\t\tslice = true\n\t\tt = t.Elem()\n\t}\n\tif t.Kind() == reflect.Ptr {\n\t\tpointer = true\n\t\tt = t.Elem()\n\t}\n\n\tpacked := false\n\tproto3 := false\n\tctype := false\n\tisTime := false\n\tisDuration := false\n\tisWktPointer := false\n\tvalidateUTF8 := true\n\tfor i := 2; i < len(tags); i++ {\n\t\tif tags[i] == \"packed\" {\n\t\t\tpacked = true\n\t\t}\n\t\tif tags[i] == \"proto3\" {\n\t\t\tproto3 = true\n\t\t}\n\t\tif strings.HasPrefix(tags[i], \"customtype=\") {\n\t\t\tctype = true\n\t\t}\n\t\tif tags[i] == \"stdtime\" {\n\t\t\tisTime = true\n\t\t}\n\t\tif tags[i] == \"stdduration\" {\n\t\t\tisDuration = true\n\t\t}\n\t\tif tags[i] == \"wktptr\" {\n\t\t\tisWktPointer = true\n\t\t}\n\t}\n\tvalidateUTF8 = validateUTF8 && proto3\n\tif !proto3 && !pointer && !slice {\n\t\tnozero = false\n\t}\n\n\tif ctype {\n\t\tif reflect.PtrTo(t).Implements(customType) {\n\t\t\tif slice {\n\t\t\t\treturn makeMessageRefSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif pointer {\n\t\t\t\treturn makeCustomPtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeCustomMarshaler(getMarshalInfo(t))\n\t\t} else {\n\t\t\tpanic(fmt.Sprintf(\"custom type: type: %v, does not implement the proto.custom interface\", t))\n\t\t}\n\t}\n\n\tif isTime {\n\t\tif pointer {\n\t\t\tif slice {\n\t\t\t\treturn makeTimePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeTimePtrMarshaler(getMarshalInfo(t))\n\t\t}\n\t\tif slice {\n\t\t\treturn makeTimeSliceMarshaler(getMarshalInfo(t))\n\t\t}\n\t\treturn makeTimeMarshaler(getMarshalInfo(t))\n\t}\n\n\tif isDuration {\n\t\tif pointer {\n\t\t\tif slice {\n\t\t\t\treturn makeDurationPtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeDurationPtrMarshaler(getMarshalInfo(t))\n\t\t}\n\t\tif slice {\n\t\t\treturn makeDurationSliceMarshaler(getMarshalInfo(t))\n\t\t}\n\t\treturn makeDurationMarshaler(getMarshalInfo(t))\n\t}\n\n\tif isWktPointer {\n\t\tswitch t.Kind() {\n\t\tcase reflect.Float64:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdDoubleValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdDoubleValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdDoubleValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdDoubleValueMarshaler(getMarshalInfo(t))\n\t\tcase reflect.Float32:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdFloatValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdFloatValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdFloatValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdFloatValueMarshaler(getMarshalInfo(t))\n\t\tcase reflect.Int64:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdInt64ValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdInt64ValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdInt64ValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdInt64ValueMarshaler(getMarshalInfo(t))\n\t\tcase reflect.Uint64:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdUInt64ValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdUInt64ValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdUInt64ValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdUInt64ValueMarshaler(getMarshalInfo(t))\n\t\tcase reflect.Int32:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdInt32ValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdInt32ValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdInt32ValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdInt32ValueMarshaler(getMarshalInfo(t))\n\t\tcase reflect.Uint32:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdUInt32ValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdUInt32ValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdUInt32ValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdUInt32ValueMarshaler(getMarshalInfo(t))\n\t\tcase reflect.Bool:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdBoolValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdBoolValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdBoolValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdBoolValueMarshaler(getMarshalInfo(t))\n\t\tcase reflect.String:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdStringValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdStringValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdStringValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdStringValueMarshaler(getMarshalInfo(t))\n\t\tcase uint8SliceType:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdBytesValuePtrSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeStdBytesValuePtrMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdBytesValueSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeStdBytesValueMarshaler(getMarshalInfo(t))\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown wktpointer type %#v\", t))\n\t\t}\n\t}\n\n\tswitch t.Kind() {\n\tcase reflect.Bool:\n\t\tif pointer {\n\t\t\treturn sizeBoolPtr, appendBoolPtr\n\t\t}\n\t\tif slice {\n\t\t\tif packed {\n\t\t\t\treturn sizeBoolPackedSlice, appendBoolPackedSlice\n\t\t\t}\n\t\t\treturn sizeBoolSlice, appendBoolSlice\n\t\t}\n\t\tif nozero {\n\t\t\treturn sizeBoolValueNoZero, appendBoolValueNoZero\n\t\t}\n\t\treturn sizeBoolValue, appendBoolValue\n\tcase reflect.Uint32:\n\t\tswitch encoding {\n\t\tcase \"fixed32\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeFixed32Ptr, appendFixed32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeFixed32PackedSlice, appendFixed32PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeFixed32Slice, appendFixed32Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeFixed32ValueNoZero, appendFixed32ValueNoZero\n\t\t\t}\n\t\t\treturn sizeFixed32Value, appendFixed32Value\n\t\tcase \"varint\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeVarint32Ptr, appendVarint32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeVarint32PackedSlice, appendVarint32PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeVarint32Slice, appendVarint32Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeVarint32ValueNoZero, appendVarint32ValueNoZero\n\t\t\t}\n\t\t\treturn sizeVarint32Value, appendVarint32Value\n\t\t}\n\tcase reflect.Int32:\n\t\tswitch encoding {\n\t\tcase \"fixed32\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeFixedS32Ptr, appendFixedS32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeFixedS32PackedSlice, appendFixedS32PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeFixedS32Slice, appendFixedS32Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero\n\t\t\t}\n\t\t\treturn sizeFixedS32Value, appendFixedS32Value\n\t\tcase \"varint\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeVarintS32Ptr, appendVarintS32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeVarintS32PackedSlice, appendVarintS32PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeVarintS32Slice, appendVarintS32Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero\n\t\t\t}\n\t\t\treturn sizeVarintS32Value, appendVarintS32Value\n\t\tcase \"zigzag32\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeZigzag32Ptr, appendZigzag32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeZigzag32PackedSlice, appendZigzag32PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeZigzag32Slice, appendZigzag32Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero\n\t\t\t}\n\t\t\treturn sizeZigzag32Value, appendZigzag32Value\n\t\t}\n\tcase reflect.Uint64:\n\t\tswitch encoding {\n\t\tcase \"fixed64\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeFixed64Ptr, appendFixed64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeFixed64PackedSlice, appendFixed64PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeFixed64Slice, appendFixed64Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeFixed64ValueNoZero, appendFixed64ValueNoZero\n\t\t\t}\n\t\t\treturn sizeFixed64Value, appendFixed64Value\n\t\tcase \"varint\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeVarint64Ptr, appendVarint64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeVarint64PackedSlice, appendVarint64PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeVarint64Slice, appendVarint64Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeVarint64ValueNoZero, appendVarint64ValueNoZero\n\t\t\t}\n\t\t\treturn sizeVarint64Value, appendVarint64Value\n\t\t}\n\tcase reflect.Int64:\n\t\tswitch encoding {\n\t\tcase \"fixed64\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeFixedS64Ptr, appendFixedS64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeFixedS64PackedSlice, appendFixedS64PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeFixedS64Slice, appendFixedS64Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero\n\t\t\t}\n\t\t\treturn sizeFixedS64Value, appendFixedS64Value\n\t\tcase \"varint\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeVarintS64Ptr, appendVarintS64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeVarintS64PackedSlice, appendVarintS64PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeVarintS64Slice, appendVarintS64Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero\n\t\t\t}\n\t\t\treturn sizeVarintS64Value, appendVarintS64Value\n\t\tcase \"zigzag64\":\n\t\t\tif pointer {\n\t\t\t\treturn sizeZigzag64Ptr, appendZigzag64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\tif packed {\n\t\t\t\t\treturn sizeZigzag64PackedSlice, appendZigzag64PackedSlice\n\t\t\t\t}\n\t\t\t\treturn sizeZigzag64Slice, appendZigzag64Slice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero\n\t\t\t}\n\t\t\treturn sizeZigzag64Value, appendZigzag64Value\n\t\t}\n\tcase reflect.Float32:\n\t\tif pointer {\n\t\t\treturn sizeFloat32Ptr, appendFloat32Ptr\n\t\t}\n\t\tif slice {\n\t\t\tif packed {\n\t\t\t\treturn sizeFloat32PackedSlice, appendFloat32PackedSlice\n\t\t\t}\n\t\t\treturn sizeFloat32Slice, appendFloat32Slice\n\t\t}\n\t\tif nozero {\n\t\t\treturn sizeFloat32ValueNoZero, appendFloat32ValueNoZero\n\t\t}\n\t\treturn sizeFloat32Value, appendFloat32Value\n\tcase reflect.Float64:\n\t\tif pointer {\n\t\t\treturn sizeFloat64Ptr, appendFloat64Ptr\n\t\t}\n\t\tif slice {\n\t\t\tif packed {\n\t\t\t\treturn sizeFloat64PackedSlice, appendFloat64PackedSlice\n\t\t\t}\n\t\t\treturn sizeFloat64Slice, appendFloat64Slice\n\t\t}\n\t\tif nozero {\n\t\t\treturn sizeFloat64ValueNoZero, appendFloat64ValueNoZero\n\t\t}\n\t\treturn sizeFloat64Value, appendFloat64Value\n\tcase reflect.String:\n\t\tif validateUTF8 {\n\t\t\tif pointer {\n\t\t\t\treturn sizeStringPtr, appendUTF8StringPtr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn sizeStringSlice, appendUTF8StringSlice\n\t\t\t}\n\t\t\tif nozero {\n\t\t\t\treturn sizeStringValueNoZero, appendUTF8StringValueNoZero\n\t\t\t}\n\t\t\treturn sizeStringValue, appendUTF8StringValue\n\t\t}\n\t\tif pointer {\n\t\t\treturn sizeStringPtr, appendStringPtr\n\t\t}\n\t\tif slice {\n\t\t\treturn sizeStringSlice, appendStringSlice\n\t\t}\n\t\tif nozero {\n\t\t\treturn sizeStringValueNoZero, appendStringValueNoZero\n\t\t}\n\t\treturn sizeStringValue, appendStringValue\n\tcase reflect.Slice:\n\t\tif slice {\n\t\t\treturn sizeBytesSlice, appendBytesSlice\n\t\t}\n\t\tif oneof {\n\t\t\t// Oneof bytes field may also have \"proto3\" tag.\n\t\t\t// We want to marshal it as a oneof field. Do this\n\t\t\t// check before the proto3 check.\n\t\t\treturn sizeBytesOneof, appendBytesOneof\n\t\t}\n\t\tif proto3 {\n\t\t\treturn sizeBytes3, appendBytes3\n\t\t}\n\t\treturn sizeBytes, appendBytes\n\tcase reflect.Struct:\n\t\tswitch encoding {\n\t\tcase \"group\":\n\t\t\tif slice {\n\t\t\t\treturn makeGroupSliceMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t\treturn makeGroupMarshaler(getMarshalInfo(t))\n\t\tcase \"bytes\":\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeMessageSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeMessageMarshaler(getMarshalInfo(t))\n\t\t\t} else {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeMessageRefSliceMarshaler(getMarshalInfo(t))\n\t\t\t\t}\n\t\t\t\treturn makeMessageRefMarshaler(getMarshalInfo(t))\n\t\t\t}\n\t\t}\n\t}\n\tpanic(fmt.Sprintf(\"unknown or mismatched type: type: %v, wire type: %v\", t, encoding))\n}\n\n// Below are functions to size/marshal a specific type of a field.\n// They are stored in the field's info, and called by function pointers.\n// They have type sizer or marshaler.\n\nfunc sizeFixed32Value(_ pointer, tagsize int) int {\n\treturn 4 + tagsize\n}\nfunc sizeFixed32ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toUint32()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn 4 + tagsize\n}\nfunc sizeFixed32Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toUint32Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 4 + tagsize\n}\nfunc sizeFixed32Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint32Slice()\n\treturn (4 + tagsize) * len(s)\n}\nfunc sizeFixed32PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint32Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\treturn 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize\n}\nfunc sizeFixedS32Value(_ pointer, tagsize int) int {\n\treturn 4 + tagsize\n}\nfunc sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt32()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn 4 + tagsize\n}\nfunc sizeFixedS32Ptr(ptr pointer, tagsize int) int {\n\tp := ptr.getInt32Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 4 + tagsize\n}\nfunc sizeFixedS32Slice(ptr pointer, tagsize int) int {\n\ts := ptr.getInt32Slice()\n\treturn (4 + tagsize) * len(s)\n}\nfunc sizeFixedS32PackedSlice(ptr pointer, tagsize int) int {\n\ts := ptr.getInt32Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\treturn 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize\n}\nfunc sizeFloat32Value(_ pointer, tagsize int) int {\n\treturn 4 + tagsize\n}\nfunc sizeFloat32ValueNoZero(ptr pointer, tagsize int) int {\n\tv := math.Float32bits(*ptr.toFloat32())\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn 4 + tagsize\n}\nfunc sizeFloat32Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toFloat32Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 4 + tagsize\n}\nfunc sizeFloat32Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toFloat32Slice()\n\treturn (4 + tagsize) * len(s)\n}\nfunc sizeFloat32PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toFloat32Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\treturn 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize\n}\nfunc sizeFixed64Value(_ pointer, tagsize int) int {\n\treturn 8 + tagsize\n}\nfunc sizeFixed64ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toUint64()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn 8 + tagsize\n}\nfunc sizeFixed64Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toUint64Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 8 + tagsize\n}\nfunc sizeFixed64Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint64Slice()\n\treturn (8 + tagsize) * len(s)\n}\nfunc sizeFixed64PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint64Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\treturn 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize\n}\nfunc sizeFixedS64Value(_ pointer, tagsize int) int {\n\treturn 8 + tagsize\n}\nfunc sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt64()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn 8 + tagsize\n}\nfunc sizeFixedS64Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toInt64Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 8 + tagsize\n}\nfunc sizeFixedS64Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toInt64Slice()\n\treturn (8 + tagsize) * len(s)\n}\nfunc sizeFixedS64PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toInt64Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\treturn 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize\n}\nfunc sizeFloat64Value(_ pointer, tagsize int) int {\n\treturn 8 + tagsize\n}\nfunc sizeFloat64ValueNoZero(ptr pointer, tagsize int) int {\n\tv := math.Float64bits(*ptr.toFloat64())\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn 8 + tagsize\n}\nfunc sizeFloat64Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toFloat64Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 8 + tagsize\n}\nfunc sizeFloat64Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toFloat64Slice()\n\treturn (8 + tagsize) * len(s)\n}\nfunc sizeFloat64PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toFloat64Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\treturn 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize\n}\nfunc sizeVarint32Value(ptr pointer, tagsize int) int {\n\tv := *ptr.toUint32()\n\treturn SizeVarint(uint64(v)) + tagsize\n}\nfunc sizeVarint32ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toUint32()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64(v)) + tagsize\n}\nfunc sizeVarint32Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toUint32Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64(*p)) + tagsize\n}\nfunc sizeVarint32Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint32Slice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v)) + tagsize\n\t}\n\treturn n\n}\nfunc sizeVarint32PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint32Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v))\n\t}\n\treturn n + SizeVarint(uint64(n)) + tagsize\n}\nfunc sizeVarintS32Value(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt32()\n\treturn SizeVarint(uint64(v)) + tagsize\n}\nfunc sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt32()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64(v)) + tagsize\n}\nfunc sizeVarintS32Ptr(ptr pointer, tagsize int) int {\n\tp := ptr.getInt32Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64(*p)) + tagsize\n}\nfunc sizeVarintS32Slice(ptr pointer, tagsize int) int {\n\ts := ptr.getInt32Slice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v)) + tagsize\n\t}\n\treturn n\n}\nfunc sizeVarintS32PackedSlice(ptr pointer, tagsize int) int {\n\ts := ptr.getInt32Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v))\n\t}\n\treturn n + SizeVarint(uint64(n)) + tagsize\n}\nfunc sizeVarint64Value(ptr pointer, tagsize int) int {\n\tv := *ptr.toUint64()\n\treturn SizeVarint(v) + tagsize\n}\nfunc sizeVarint64ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toUint64()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn SizeVarint(v) + tagsize\n}\nfunc sizeVarint64Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toUint64Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn SizeVarint(*p) + tagsize\n}\nfunc sizeVarint64Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint64Slice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(v) + tagsize\n\t}\n\treturn n\n}\nfunc sizeVarint64PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toUint64Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(v)\n\t}\n\treturn n + SizeVarint(uint64(n)) + tagsize\n}\nfunc sizeVarintS64Value(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt64()\n\treturn SizeVarint(uint64(v)) + tagsize\n}\nfunc sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt64()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64(v)) + tagsize\n}\nfunc sizeVarintS64Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toInt64Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64(*p)) + tagsize\n}\nfunc sizeVarintS64Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toInt64Slice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v)) + tagsize\n\t}\n\treturn n\n}\nfunc sizeVarintS64PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toInt64Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v))\n\t}\n\treturn n + SizeVarint(uint64(n)) + tagsize\n}\nfunc sizeZigzag32Value(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt32()\n\treturn SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize\n}\nfunc sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt32()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize\n}\nfunc sizeZigzag32Ptr(ptr pointer, tagsize int) int {\n\tp := ptr.getInt32Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\tv := *p\n\treturn SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize\n}\nfunc sizeZigzag32Slice(ptr pointer, tagsize int) int {\n\ts := ptr.getInt32Slice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize\n\t}\n\treturn n\n}\nfunc sizeZigzag32PackedSlice(ptr pointer, tagsize int) int {\n\ts := ptr.getInt32Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))\n\t}\n\treturn n + SizeVarint(uint64(n)) + tagsize\n}\nfunc sizeZigzag64Value(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt64()\n\treturn SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize\n}\nfunc sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toInt64()\n\tif v == 0 {\n\t\treturn 0\n\t}\n\treturn SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize\n}\nfunc sizeZigzag64Ptr(ptr pointer, tagsize int) int {\n\tp := *ptr.toInt64Ptr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\tv := *p\n\treturn SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize\n}\nfunc sizeZigzag64Slice(ptr pointer, tagsize int) int {\n\ts := *ptr.toInt64Slice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize\n\t}\n\treturn n\n}\nfunc sizeZigzag64PackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toInt64Slice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))\n\t}\n\treturn n + SizeVarint(uint64(n)) + tagsize\n}\nfunc sizeBoolValue(_ pointer, tagsize int) int {\n\treturn 1 + tagsize\n}\nfunc sizeBoolValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toBool()\n\tif !v {\n\t\treturn 0\n\t}\n\treturn 1 + tagsize\n}\nfunc sizeBoolPtr(ptr pointer, tagsize int) int {\n\tp := *ptr.toBoolPtr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\treturn 1 + tagsize\n}\nfunc sizeBoolSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toBoolSlice()\n\treturn (1 + tagsize) * len(s)\n}\nfunc sizeBoolPackedSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toBoolSlice()\n\tif len(s) == 0 {\n\t\treturn 0\n\t}\n\treturn len(s) + SizeVarint(uint64(len(s))) + tagsize\n}\nfunc sizeStringValue(ptr pointer, tagsize int) int {\n\tv := *ptr.toString()\n\treturn len(v) + SizeVarint(uint64(len(v))) + tagsize\n}\nfunc sizeStringValueNoZero(ptr pointer, tagsize int) int {\n\tv := *ptr.toString()\n\tif v == \"\" {\n\t\treturn 0\n\t}\n\treturn len(v) + SizeVarint(uint64(len(v))) + tagsize\n}\nfunc sizeStringPtr(ptr pointer, tagsize int) int {\n\tp := *ptr.toStringPtr()\n\tif p == nil {\n\t\treturn 0\n\t}\n\tv := *p\n\treturn len(v) + SizeVarint(uint64(len(v))) + tagsize\n}\nfunc sizeStringSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toStringSlice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += len(v) + SizeVarint(uint64(len(v))) + tagsize\n\t}\n\treturn n\n}\nfunc sizeBytes(ptr pointer, tagsize int) int {\n\tv := *ptr.toBytes()\n\tif v == nil {\n\t\treturn 0\n\t}\n\treturn len(v) + SizeVarint(uint64(len(v))) + tagsize\n}\nfunc sizeBytes3(ptr pointer, tagsize int) int {\n\tv := *ptr.toBytes()\n\tif len(v) == 0 {\n\t\treturn 0\n\t}\n\treturn len(v) + SizeVarint(uint64(len(v))) + tagsize\n}\nfunc sizeBytesOneof(ptr pointer, tagsize int) int {\n\tv := *ptr.toBytes()\n\treturn len(v) + SizeVarint(uint64(len(v))) + tagsize\n}\nfunc sizeBytesSlice(ptr pointer, tagsize int) int {\n\ts := *ptr.toBytesSlice()\n\tn := 0\n\tfor _, v := range s {\n\t\tn += len(v) + SizeVarint(uint64(len(v))) + tagsize\n\t}\n\treturn n\n}\n\n// appendFixed32 appends an encoded fixed32 to b.\nfunc appendFixed32(b []byte, v uint32) []byte {\n\tb = append(b,\n\t\tbyte(v),\n\t\tbyte(v>>8),\n\t\tbyte(v>>16),\n\t\tbyte(v>>24))\n\treturn b\n}\n\n// appendFixed64 appends an encoded fixed64 to b.\nfunc appendFixed64(b []byte, v uint64) []byte {\n\tb = append(b,\n\t\tbyte(v),\n\t\tbyte(v>>8),\n\t\tbyte(v>>16),\n\t\tbyte(v>>24),\n\t\tbyte(v>>32),\n\t\tbyte(v>>40),\n\t\tbyte(v>>48),\n\t\tbyte(v>>56))\n\treturn b\n}\n\n// appendVarint appends an encoded varint to b.\nfunc appendVarint(b []byte, v uint64) []byte {\n\t// TODO: make 1-byte (maybe 2-byte) case inline-able, once we\n\t// have non-leaf inliner.\n\tswitch {\n\tcase v < 1<<7:\n\t\tb = append(b, byte(v))\n\tcase v < 1<<14:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte(v>>7))\n\tcase v < 1<<21:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte(v>>14))\n\tcase v < 1<<28:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte((v>>14)&0x7f|0x80),\n\t\t\tbyte(v>>21))\n\tcase v < 1<<35:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte((v>>14)&0x7f|0x80),\n\t\t\tbyte((v>>21)&0x7f|0x80),\n\t\t\tbyte(v>>28))\n\tcase v < 1<<42:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte((v>>14)&0x7f|0x80),\n\t\t\tbyte((v>>21)&0x7f|0x80),\n\t\t\tbyte((v>>28)&0x7f|0x80),\n\t\t\tbyte(v>>35))\n\tcase v < 1<<49:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte((v>>14)&0x7f|0x80),\n\t\t\tbyte((v>>21)&0x7f|0x80),\n\t\t\tbyte((v>>28)&0x7f|0x80),\n\t\t\tbyte((v>>35)&0x7f|0x80),\n\t\t\tbyte(v>>42))\n\tcase v < 1<<56:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte((v>>14)&0x7f|0x80),\n\t\t\tbyte((v>>21)&0x7f|0x80),\n\t\t\tbyte((v>>28)&0x7f|0x80),\n\t\t\tbyte((v>>35)&0x7f|0x80),\n\t\t\tbyte((v>>42)&0x7f|0x80),\n\t\t\tbyte(v>>49))\n\tcase v < 1<<63:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte((v>>14)&0x7f|0x80),\n\t\t\tbyte((v>>21)&0x7f|0x80),\n\t\t\tbyte((v>>28)&0x7f|0x80),\n\t\t\tbyte((v>>35)&0x7f|0x80),\n\t\t\tbyte((v>>42)&0x7f|0x80),\n\t\t\tbyte((v>>49)&0x7f|0x80),\n\t\t\tbyte(v>>56))\n\tdefault:\n\t\tb = append(b,\n\t\t\tbyte(v&0x7f|0x80),\n\t\t\tbyte((v>>7)&0x7f|0x80),\n\t\t\tbyte((v>>14)&0x7f|0x80),\n\t\t\tbyte((v>>21)&0x7f|0x80),\n\t\t\tbyte((v>>28)&0x7f|0x80),\n\t\t\tbyte((v>>35)&0x7f|0x80),\n\t\t\tbyte((v>>42)&0x7f|0x80),\n\t\t\tbyte((v>>49)&0x7f|0x80),\n\t\t\tbyte((v>>56)&0x7f|0x80),\n\t\t\t1)\n\t}\n\treturn b\n}\n\nfunc appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint32()\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, v)\n\treturn b, nil\n}\nfunc appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint32()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, v)\n\treturn b, nil\n}\nfunc appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toUint32Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, *p)\n\treturn b, nil\n}\nfunc appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint32Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendFixed32(b, v)\n\t}\n\treturn b, nil\n}\nfunc appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint32Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\tb = appendVarint(b, uint64(4*len(s)))\n\tfor _, v := range s {\n\t\tb = appendFixed32(b, v)\n\t}\n\treturn b, nil\n}\nfunc appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt32()\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, uint32(v))\n\treturn b, nil\n}\nfunc appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt32()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, uint32(v))\n\treturn b, nil\n}\nfunc appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := ptr.getInt32Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, uint32(*p))\n\treturn b, nil\n}\nfunc appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := ptr.getInt32Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendFixed32(b, uint32(v))\n\t}\n\treturn b, nil\n}\nfunc appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := ptr.getInt32Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\tb = appendVarint(b, uint64(4*len(s)))\n\tfor _, v := range s {\n\t\tb = appendFixed32(b, uint32(v))\n\t}\n\treturn b, nil\n}\nfunc appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := math.Float32bits(*ptr.toFloat32())\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, v)\n\treturn b, nil\n}\nfunc appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := math.Float32bits(*ptr.toFloat32())\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, v)\n\treturn b, nil\n}\nfunc appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toFloat32Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed32(b, math.Float32bits(*p))\n\treturn b, nil\n}\nfunc appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toFloat32Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendFixed32(b, math.Float32bits(v))\n\t}\n\treturn b, nil\n}\nfunc appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toFloat32Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\tb = appendVarint(b, uint64(4*len(s)))\n\tfor _, v := range s {\n\t\tb = appendFixed32(b, math.Float32bits(v))\n\t}\n\treturn b, nil\n}\nfunc appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint64()\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, v)\n\treturn b, nil\n}\nfunc appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint64()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, v)\n\treturn b, nil\n}\nfunc appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toUint64Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, *p)\n\treturn b, nil\n}\nfunc appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint64Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendFixed64(b, v)\n\t}\n\treturn b, nil\n}\nfunc appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint64Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\tb = appendVarint(b, uint64(8*len(s)))\n\tfor _, v := range s {\n\t\tb = appendFixed64(b, v)\n\t}\n\treturn b, nil\n}\nfunc appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt64()\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, uint64(v))\n\treturn b, nil\n}\nfunc appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt64()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, uint64(v))\n\treturn b, nil\n}\nfunc appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toInt64Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, uint64(*p))\n\treturn b, nil\n}\nfunc appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toInt64Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendFixed64(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toInt64Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\tb = appendVarint(b, uint64(8*len(s)))\n\tfor _, v := range s {\n\t\tb = appendFixed64(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := math.Float64bits(*ptr.toFloat64())\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, v)\n\treturn b, nil\n}\nfunc appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := math.Float64bits(*ptr.toFloat64())\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, v)\n\treturn b, nil\n}\nfunc appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toFloat64Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendFixed64(b, math.Float64bits(*p))\n\treturn b, nil\n}\nfunc appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toFloat64Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendFixed64(b, math.Float64bits(v))\n\t}\n\treturn b, nil\n}\nfunc appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toFloat64Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\tb = appendVarint(b, uint64(8*len(s)))\n\tfor _, v := range s {\n\t\tb = appendFixed64(b, math.Float64bits(v))\n\t}\n\treturn b, nil\n}\nfunc appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint32()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v))\n\treturn b, nil\n}\nfunc appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint32()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v))\n\treturn b, nil\n}\nfunc appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toUint32Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(*p))\n\treturn b, nil\n}\nfunc appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint32Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint32Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\t// compute size\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v))\n\t}\n\tb = appendVarint(b, uint64(n))\n\tfor _, v := range s {\n\t\tb = appendVarint(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt32()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v))\n\treturn b, nil\n}\nfunc appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt32()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v))\n\treturn b, nil\n}\nfunc appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := ptr.getInt32Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(*p))\n\treturn b, nil\n}\nfunc appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := ptr.getInt32Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := ptr.getInt32Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\t// compute size\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v))\n\t}\n\tb = appendVarint(b, uint64(n))\n\tfor _, v := range s {\n\t\tb = appendVarint(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint64()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, v)\n\treturn b, nil\n}\nfunc appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toUint64()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, v)\n\treturn b, nil\n}\nfunc appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toUint64Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, *p)\n\treturn b, nil\n}\nfunc appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint64Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, v)\n\t}\n\treturn b, nil\n}\nfunc appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toUint64Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\t// compute size\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(v)\n\t}\n\tb = appendVarint(b, uint64(n))\n\tfor _, v := range s {\n\t\tb = appendVarint(b, v)\n\t}\n\treturn b, nil\n}\nfunc appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt64()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v))\n\treturn b, nil\n}\nfunc appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt64()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v))\n\treturn b, nil\n}\nfunc appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toInt64Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(*p))\n\treturn b, nil\n}\nfunc appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toInt64Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toInt64Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\t// compute size\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v))\n\t}\n\tb = appendVarint(b, uint64(n))\n\tfor _, v := range s {\n\t\tb = appendVarint(b, uint64(v))\n\t}\n\treturn b, nil\n}\nfunc appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt32()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))\n\treturn b, nil\n}\nfunc appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt32()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))\n\treturn b, nil\n}\nfunc appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := ptr.getInt32Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tv := *p\n\tb = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))\n\treturn b, nil\n}\nfunc appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := ptr.getInt32Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))\n\t}\n\treturn b, nil\n}\nfunc appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := ptr.getInt32Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\t// compute size\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))\n\t}\n\tb = appendVarint(b, uint64(n))\n\tfor _, v := range s {\n\t\tb = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))\n\t}\n\treturn b, nil\n}\nfunc appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt64()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))\n\treturn b, nil\n}\nfunc appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toInt64()\n\tif v == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))\n\treturn b, nil\n}\nfunc appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toInt64Ptr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tv := *p\n\tb = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))\n\treturn b, nil\n}\nfunc appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toInt64Slice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))\n\t}\n\treturn b, nil\n}\nfunc appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toInt64Slice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\t// compute size\n\tn := 0\n\tfor _, v := range s {\n\t\tn += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))\n\t}\n\tb = appendVarint(b, uint64(n))\n\tfor _, v := range s {\n\t\tb = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))\n\t}\n\treturn b, nil\n}\nfunc appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toBool()\n\tb = appendVarint(b, wiretag)\n\tif v {\n\t\tb = append(b, 1)\n\t} else {\n\t\tb = append(b, 0)\n\t}\n\treturn b, nil\n}\nfunc appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toBool()\n\tif !v {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = append(b, 1)\n\treturn b, nil\n}\n\nfunc appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toBoolPtr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tif *p {\n\t\tb = append(b, 1)\n\t} else {\n\t\tb = append(b, 0)\n\t}\n\treturn b, nil\n}\nfunc appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toBoolSlice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tif v {\n\t\t\tb = append(b, 1)\n\t\t} else {\n\t\t\tb = append(b, 0)\n\t\t}\n\t}\n\treturn b, nil\n}\nfunc appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toBoolSlice()\n\tif len(s) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag&^7|WireBytes)\n\tb = appendVarint(b, uint64(len(s)))\n\tfor _, v := range s {\n\t\tif v {\n\t\t\tb = append(b, 1)\n\t\t} else {\n\t\t\tb = append(b, 0)\n\t\t}\n\t}\n\treturn b, nil\n}\nfunc appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toString()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\treturn b, nil\n}\nfunc appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toString()\n\tif v == \"\" {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\treturn b, nil\n}\nfunc appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tp := *ptr.toStringPtr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tv := *p\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\treturn b, nil\n}\nfunc appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toStringSlice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64(len(v)))\n\t\tb = append(b, v...)\n\t}\n\treturn b, nil\n}\nfunc appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tvar invalidUTF8 bool\n\tv := *ptr.toString()\n\tif !utf8.ValidString(v) {\n\t\tinvalidUTF8 = true\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\tif invalidUTF8 {\n\t\treturn b, errInvalidUTF8\n\t}\n\treturn b, nil\n}\nfunc appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tvar invalidUTF8 bool\n\tv := *ptr.toString()\n\tif v == \"\" {\n\t\treturn b, nil\n\t}\n\tif !utf8.ValidString(v) {\n\t\tinvalidUTF8 = true\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\tif invalidUTF8 {\n\t\treturn b, errInvalidUTF8\n\t}\n\treturn b, nil\n}\nfunc appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tvar invalidUTF8 bool\n\tp := *ptr.toStringPtr()\n\tif p == nil {\n\t\treturn b, nil\n\t}\n\tv := *p\n\tif !utf8.ValidString(v) {\n\t\tinvalidUTF8 = true\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\tif invalidUTF8 {\n\t\treturn b, errInvalidUTF8\n\t}\n\treturn b, nil\n}\nfunc appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tvar invalidUTF8 bool\n\ts := *ptr.toStringSlice()\n\tfor _, v := range s {\n\t\tif !utf8.ValidString(v) {\n\t\t\tinvalidUTF8 = true\n\t\t}\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64(len(v)))\n\t\tb = append(b, v...)\n\t}\n\tif invalidUTF8 {\n\t\treturn b, errInvalidUTF8\n\t}\n\treturn b, nil\n}\nfunc appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toBytes()\n\tif v == nil {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\treturn b, nil\n}\nfunc appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toBytes()\n\tif len(v) == 0 {\n\t\treturn b, nil\n\t}\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\treturn b, nil\n}\nfunc appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\tv := *ptr.toBytes()\n\tb = appendVarint(b, wiretag)\n\tb = appendVarint(b, uint64(len(v)))\n\tb = append(b, v...)\n\treturn b, nil\n}\nfunc appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {\n\ts := *ptr.toBytesSlice()\n\tfor _, v := range s {\n\t\tb = appendVarint(b, wiretag)\n\t\tb = appendVarint(b, uint64(len(v)))\n\t\tb = append(b, v...)\n\t}\n\treturn b, nil\n}\n\n// makeGroupMarshaler returns the sizer and marshaler for a group.\n// u is the marshal info of the underlying message.\nfunc makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tp := ptr.getPointer()\n\t\t\tif p.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\treturn u.size(p) + 2*tagsize\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tp := ptr.getPointer()\n\t\t\tif p.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tvar err error\n\t\t\tb = appendVarint(b, wiretag) // start group\n\t\t\tb, err = u.marshal(b, p, deterministic)\n\t\t\tb = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group\n\t\t\treturn b, err\n\t\t}\n}\n\n// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice.\n// u is the marshal info of the underlying message.\nfunc makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getPointerSlice()\n\t\t\tn := 0\n\t\t\tfor _, v := range s {\n\t\t\t\tif v.isNil() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tn += u.size(v) + 2*tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getPointerSlice()\n\t\t\tvar err error\n\t\t\tvar nerr nonFatal\n\t\t\tfor _, v := range s {\n\t\t\t\tif v.isNil() {\n\t\t\t\t\treturn b, errRepeatedHasNil\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag) // start group\n\t\t\t\tb, err = u.marshal(b, v, deterministic)\n\t\t\t\tb = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group\n\t\t\t\tif !nerr.Merge(err) {\n\t\t\t\t\tif err == ErrNil {\n\t\t\t\t\t\terr = errRepeatedHasNil\n\t\t\t\t\t}\n\t\t\t\t\treturn b, err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn b, nerr.E\n\t\t}\n}\n\n// makeMessageMarshaler returns the sizer and marshaler for a message field.\n// u is the marshal info of the message.\nfunc makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tp := ptr.getPointer()\n\t\t\tif p.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tsiz := u.size(p)\n\t\t\treturn siz + SizeVarint(uint64(siz)) + tagsize\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tp := ptr.getPointer()\n\t\t\tif p.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tsiz := u.cachedsize(p)\n\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\treturn u.marshal(b, p, deterministic)\n\t\t}\n}\n\n// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice.\n// u is the marshal info of the message.\nfunc makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getPointerSlice()\n\t\t\tn := 0\n\t\t\tfor _, v := range s {\n\t\t\t\tif v.isNil() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tsiz := u.size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getPointerSlice()\n\t\t\tvar err error\n\t\t\tvar nerr nonFatal\n\t\t\tfor _, v := range s {\n\t\t\t\tif v.isNil() {\n\t\t\t\t\treturn b, errRepeatedHasNil\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tsiz := u.cachedsize(v)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb, err = u.marshal(b, v, deterministic)\n\n\t\t\t\tif !nerr.Merge(err) {\n\t\t\t\t\tif err == ErrNil {\n\t\t\t\t\t\terr = errRepeatedHasNil\n\t\t\t\t\t}\n\t\t\t\t\treturn b, err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn b, nerr.E\n\t\t}\n}\n\n// makeMapMarshaler returns the sizer and marshaler for a map field.\n// f is the pointer to the reflect data structure of the field.\nfunc makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {\n\t// figure out key and value type\n\tt := f.Type\n\tkeyType := t.Key()\n\tvalType := t.Elem()\n\ttags := strings.Split(f.Tag.Get(\"protobuf\"), \",\")\n\tkeyTags := strings.Split(f.Tag.Get(\"protobuf_key\"), \",\")\n\tvalTags := strings.Split(f.Tag.Get(\"protobuf_val\"), \",\")\n\tstdOptions := false\n\tfor _, t := range tags {\n\t\tif strings.HasPrefix(t, \"customtype=\") {\n\t\t\tvalTags = append(valTags, t)\n\t\t}\n\t\tif t == \"stdtime\" {\n\t\t\tvalTags = append(valTags, t)\n\t\t\tstdOptions = true\n\t\t}\n\t\tif t == \"stdduration\" {\n\t\t\tvalTags = append(valTags, t)\n\t\t\tstdOptions = true\n\t\t}\n\t\tif t == \"wktptr\" {\n\t\t\tvalTags = append(valTags, t)\n\t\t}\n\t}\n\tkeySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map\n\tvalSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map\n\tkeyWireTag := 1<<3 | wiretype(keyTags[0])\n\tvalWireTag := 2<<3 | wiretype(valTags[0])\n\n\t// We create an interface to get the addresses of the map key and value.\n\t// If value is pointer-typed, the interface is a direct interface, the\n\t// idata itself is the value. Otherwise, the idata is the pointer to the\n\t// value.\n\t// Key cannot be pointer-typed.\n\tvalIsPtr := valType.Kind() == reflect.Ptr\n\n\t// If value is a message with nested maps, calling\n\t// valSizer in marshal may be quadratic. We should use\n\t// cached version in marshal (but not in size).\n\t// If value is not message type, we don't have size cache,\n\t// but it cannot be nested either. Just use valSizer.\n\tvalCachedSizer := valSizer\n\tif valIsPtr && !stdOptions && valType.Elem().Kind() == reflect.Struct {\n\t\tu := getMarshalInfo(valType.Elem())\n\t\tvalCachedSizer = func(ptr pointer, tagsize int) int {\n\t\t\t// Same as message sizer, but use cache.\n\t\t\tp := ptr.getPointer()\n\t\t\tif p.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tsiz := u.cachedsize(p)\n\t\t\treturn siz + SizeVarint(uint64(siz)) + tagsize\n\t\t}\n\t}\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tm := ptr.asPointerTo(t).Elem() // the map\n\t\t\tn := 0\n\t\t\tfor _, k := range m.MapKeys() {\n\t\t\t\tki := k.Interface()\n\t\t\t\tvi := m.MapIndex(k).Interface()\n\t\t\t\tkaddr := toAddrPointer(&ki, false)             // pointer to key\n\t\t\t\tvaddr := toAddrPointer(&vi, valIsPtr)          // pointer to value\n\t\t\t\tsiz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) {\n\t\t\tm := ptr.asPointerTo(t).Elem() // the map\n\t\t\tvar err error\n\t\t\tkeys := m.MapKeys()\n\t\t\tif len(keys) > 1 && deterministic {\n\t\t\t\tsort.Sort(mapKeys(keys))\n\t\t\t}\n\n\t\t\tvar nerr nonFatal\n\t\t\tfor _, k := range keys {\n\t\t\t\tki := k.Interface()\n\t\t\t\tvi := m.MapIndex(k).Interface()\n\t\t\t\tkaddr := toAddrPointer(&ki, false)    // pointer to key\n\t\t\t\tvaddr := toAddrPointer(&vi, valIsPtr) // pointer to value\n\t\t\t\tb = appendVarint(b, tag)\n\t\t\t\tsiz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)\n\t\t\t\tif !nerr.Merge(err) {\n\t\t\t\t\treturn b, err\n\t\t\t\t}\n\t\t\t\tb, err = valMarshaler(b, vaddr, valWireTag, deterministic)\n\t\t\t\tif err != ErrNil && !nerr.Merge(err) { // allow nil value in map\n\t\t\t\t\treturn b, err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn b, nerr.E\n\t\t}\n}\n\n// makeOneOfMarshaler returns the sizer and marshaler for a oneof field.\n// fi is the marshal info of the field.\n// f is the pointer to the reflect data structure of the field.\nfunc makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) {\n\t// Oneof field is an interface. We need to get the actual data type on the fly.\n\tt := f.Type\n\treturn func(ptr pointer, _ int) int {\n\t\t\tp := ptr.getInterfacePointer()\n\t\t\tif p.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tv := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct\n\t\t\ttelem := v.Type()\n\t\t\te := fi.oneofElems[telem]\n\t\t\treturn e.sizer(p, e.tagsize)\n\t\t},\n\t\tfunc(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) {\n\t\t\tp := ptr.getInterfacePointer()\n\t\t\tif p.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tv := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct\n\t\t\ttelem := v.Type()\n\t\t\tif telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() {\n\t\t\t\treturn b, errOneofHasNil\n\t\t\t}\n\t\t\te := fi.oneofElems[telem]\n\t\t\treturn e.marshaler(b, p, e.wiretag, deterministic)\n\t\t}\n}\n\n// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field.\nfunc (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {\n\tm, mu := ext.extensionsRead()\n\tif m == nil {\n\t\treturn 0\n\t}\n\tmu.Lock()\n\n\tn := 0\n\tfor _, e := range m {\n\t\tif e.value == nil || e.desc == nil {\n\t\t\t// Extension is only in its encoded form.\n\t\t\tn += len(e.enc)\n\t\t\tcontinue\n\t\t}\n\n\t\t// We don't skip extensions that have an encoded form set,\n\t\t// because the extension value may have been mutated after\n\t\t// the last time this function was called.\n\t\tei := u.getExtElemInfo(e.desc)\n\t\tv := e.value\n\t\tp := toAddrPointer(&v, ei.isptr)\n\t\tn += ei.sizer(p, ei.tagsize)\n\t}\n\tmu.Unlock()\n\treturn n\n}\n\n// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b.\nfunc (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {\n\tm, mu := ext.extensionsRead()\n\tif m == nil {\n\t\treturn b, nil\n\t}\n\tmu.Lock()\n\tdefer mu.Unlock()\n\n\tvar err error\n\tvar nerr nonFatal\n\n\t// Fast-path for common cases: zero or one extensions.\n\t// Don't bother sorting the keys.\n\tif len(m) <= 1 {\n\t\tfor _, e := range m {\n\t\t\tif e.value == nil || e.desc == nil {\n\t\t\t\t// Extension is only in its encoded form.\n\t\t\t\tb = append(b, e.enc...)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// We don't skip extensions that have an encoded form set,\n\t\t\t// because the extension value may have been mutated after\n\t\t\t// the last time this function was called.\n\n\t\t\tei := u.getExtElemInfo(e.desc)\n\t\t\tv := e.value\n\t\t\tp := toAddrPointer(&v, ei.isptr)\n\t\t\tb, err = ei.marshaler(b, p, ei.wiretag, deterministic)\n\t\t\tif !nerr.Merge(err) {\n\t\t\t\treturn b, err\n\t\t\t}\n\t\t}\n\t\treturn b, nerr.E\n\t}\n\n\t// Sort the keys to provide a deterministic encoding.\n\t// Not sure this is required, but the old code does it.\n\tkeys := make([]int, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, int(k))\n\t}\n\tsort.Ints(keys)\n\n\tfor _, k := range keys {\n\t\te := m[int32(k)]\n\t\tif e.value == nil || e.desc == nil {\n\t\t\t// Extension is only in its encoded form.\n\t\t\tb = append(b, e.enc...)\n\t\t\tcontinue\n\t\t}\n\n\t\t// We don't skip extensions that have an encoded form set,\n\t\t// because the extension value may have been mutated after\n\t\t// the last time this function was called.\n\n\t\tei := u.getExtElemInfo(e.desc)\n\t\tv := e.value\n\t\tp := toAddrPointer(&v, ei.isptr)\n\t\tb, err = ei.marshaler(b, p, ei.wiretag, deterministic)\n\t\tif !nerr.Merge(err) {\n\t\t\treturn b, err\n\t\t}\n\t}\n\treturn b, nerr.E\n}\n\n// message set format is:\n//   message MessageSet {\n//     repeated group Item = 1 {\n//       required int32 type_id = 2;\n//       required string message = 3;\n//     };\n//   }\n\n// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field\n// in message set format (above).\nfunc (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {\n\tm, mu := ext.extensionsRead()\n\tif m == nil {\n\t\treturn 0\n\t}\n\tmu.Lock()\n\n\tn := 0\n\tfor id, e := range m {\n\t\tn += 2                          // start group, end group. tag = 1 (size=1)\n\t\tn += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1)\n\n\t\tif e.value == nil || e.desc == nil {\n\t\t\t// Extension is only in its encoded form.\n\t\t\tmsgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint\n\t\t\tsiz := len(msgWithLen)\n\t\t\tn += siz + 1 // message, tag = 3 (size=1)\n\t\t\tcontinue\n\t\t}\n\n\t\t// We don't skip extensions that have an encoded form set,\n\t\t// because the extension value may have been mutated after\n\t\t// the last time this function was called.\n\n\t\tei := u.getExtElemInfo(e.desc)\n\t\tv := e.value\n\t\tp := toAddrPointer(&v, ei.isptr)\n\t\tn += ei.sizer(p, 1) // message, tag = 3 (size=1)\n\t}\n\tmu.Unlock()\n\treturn n\n}\n\n// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above)\n// to the end of byte slice b.\nfunc (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {\n\tm, mu := ext.extensionsRead()\n\tif m == nil {\n\t\treturn b, nil\n\t}\n\tmu.Lock()\n\tdefer mu.Unlock()\n\n\tvar err error\n\tvar nerr nonFatal\n\n\t// Fast-path for common cases: zero or one extensions.\n\t// Don't bother sorting the keys.\n\tif len(m) <= 1 {\n\t\tfor id, e := range m {\n\t\t\tb = append(b, 1<<3|WireStartGroup)\n\t\t\tb = append(b, 2<<3|WireVarint)\n\t\t\tb = appendVarint(b, uint64(id))\n\n\t\t\tif e.value == nil || e.desc == nil {\n\t\t\t\t// Extension is only in its encoded form.\n\t\t\t\tmsgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint\n\t\t\t\tb = append(b, 3<<3|WireBytes)\n\t\t\t\tb = append(b, msgWithLen...)\n\t\t\t\tb = append(b, 1<<3|WireEndGroup)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// We don't skip extensions that have an encoded form set,\n\t\t\t// because the extension value may have been mutated after\n\t\t\t// the last time this function was called.\n\n\t\t\tei := u.getExtElemInfo(e.desc)\n\t\t\tv := e.value\n\t\t\tp := toAddrPointer(&v, ei.isptr)\n\t\t\tb, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)\n\t\t\tif !nerr.Merge(err) {\n\t\t\t\treturn b, err\n\t\t\t}\n\t\t\tb = append(b, 1<<3|WireEndGroup)\n\t\t}\n\t\treturn b, nerr.E\n\t}\n\n\t// Sort the keys to provide a deterministic encoding.\n\tkeys := make([]int, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, int(k))\n\t}\n\tsort.Ints(keys)\n\n\tfor _, id := range keys {\n\t\te := m[int32(id)]\n\t\tb = append(b, 1<<3|WireStartGroup)\n\t\tb = append(b, 2<<3|WireVarint)\n\t\tb = appendVarint(b, uint64(id))\n\n\t\tif e.value == nil || e.desc == nil {\n\t\t\t// Extension is only in its encoded form.\n\t\t\tmsgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint\n\t\t\tb = append(b, 3<<3|WireBytes)\n\t\t\tb = append(b, msgWithLen...)\n\t\t\tb = append(b, 1<<3|WireEndGroup)\n\t\t\tcontinue\n\t\t}\n\n\t\t// We don't skip extensions that have an encoded form set,\n\t\t// because the extension value may have been mutated after\n\t\t// the last time this function was called.\n\n\t\tei := u.getExtElemInfo(e.desc)\n\t\tv := e.value\n\t\tp := toAddrPointer(&v, ei.isptr)\n\t\tb, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)\n\t\tb = append(b, 1<<3|WireEndGroup)\n\t\tif !nerr.Merge(err) {\n\t\t\treturn b, err\n\t\t}\n\t}\n\treturn b, nerr.E\n}\n\n// sizeV1Extensions computes the size of encoded data for a V1-API extension field.\nfunc (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {\n\tif m == nil {\n\t\treturn 0\n\t}\n\n\tn := 0\n\tfor _, e := range m {\n\t\tif e.value == nil || e.desc == nil {\n\t\t\t// Extension is only in its encoded form.\n\t\t\tn += len(e.enc)\n\t\t\tcontinue\n\t\t}\n\n\t\t// We don't skip extensions that have an encoded form set,\n\t\t// because the extension value may have been mutated after\n\t\t// the last time this function was called.\n\n\t\tei := u.getExtElemInfo(e.desc)\n\t\tv := e.value\n\t\tp := toAddrPointer(&v, ei.isptr)\n\t\tn += ei.sizer(p, ei.tagsize)\n\t}\n\treturn n\n}\n\n// appendV1Extensions marshals a V1-API extension field to the end of byte slice b.\nfunc (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) {\n\tif m == nil {\n\t\treturn b, nil\n\t}\n\n\t// Sort the keys to provide a deterministic encoding.\n\tkeys := make([]int, 0, len(m))\n\tfor k := range m {\n\t\tkeys = append(keys, int(k))\n\t}\n\tsort.Ints(keys)\n\n\tvar err error\n\tvar nerr nonFatal\n\tfor _, k := range keys {\n\t\te := m[int32(k)]\n\t\tif e.value == nil || e.desc == nil {\n\t\t\t// Extension is only in its encoded form.\n\t\t\tb = append(b, e.enc...)\n\t\t\tcontinue\n\t\t}\n\n\t\t// We don't skip extensions that have an encoded form set,\n\t\t// because the extension value may have been mutated after\n\t\t// the last time this function was called.\n\n\t\tei := u.getExtElemInfo(e.desc)\n\t\tv := e.value\n\t\tp := toAddrPointer(&v, ei.isptr)\n\t\tb, err = ei.marshaler(b, p, ei.wiretag, deterministic)\n\t\tif !nerr.Merge(err) {\n\t\t\treturn b, err\n\t\t}\n\t}\n\treturn b, nerr.E\n}\n\n// newMarshaler is the interface representing objects that can marshal themselves.\n//\n// This exists to support protoc-gen-go generated messages.\n// The proto package will stop type-asserting to this interface in the future.\n//\n// DO NOT DEPEND ON THIS.\ntype newMarshaler interface {\n\tXXX_Size() int\n\tXXX_Marshal(b []byte, deterministic bool) ([]byte, error)\n}\n\n// Size returns the encoded size of a protocol buffer message.\n// This is the main entry point.\nfunc Size(pb Message) int {\n\tif m, ok := pb.(newMarshaler); ok {\n\t\treturn m.XXX_Size()\n\t}\n\tif m, ok := pb.(Marshaler); ok {\n\t\t// If the message can marshal itself, let it do it, for compatibility.\n\t\t// NOTE: This is not efficient.\n\t\tb, _ := m.Marshal()\n\t\treturn len(b)\n\t}\n\t// in case somehow we didn't generate the wrapper\n\tif pb == nil {\n\t\treturn 0\n\t}\n\tvar info InternalMessageInfo\n\treturn info.Size(pb)\n}\n\n// Marshal takes a protocol buffer message\n// and encodes it into the wire format, returning the data.\n// This is the main entry point.\nfunc Marshal(pb Message) ([]byte, error) {\n\tif m, ok := pb.(newMarshaler); ok {\n\t\tsiz := m.XXX_Size()\n\t\tb := make([]byte, 0, siz)\n\t\treturn m.XXX_Marshal(b, false)\n\t}\n\tif m, ok := pb.(Marshaler); ok {\n\t\t// If the message can marshal itself, let it do it, for compatibility.\n\t\t// NOTE: This is not efficient.\n\t\treturn m.Marshal()\n\t}\n\t// in case somehow we didn't generate the wrapper\n\tif pb == nil {\n\t\treturn nil, ErrNil\n\t}\n\tvar info InternalMessageInfo\n\tsiz := info.Size(pb)\n\tb := make([]byte, 0, siz)\n\treturn info.Marshal(b, pb, false)\n}\n\n// Marshal takes a protocol buffer message\n// and encodes it into the wire format, writing the result to the\n// Buffer.\n// This is an alternative entry point. It is not necessary to use\n// a Buffer for most applications.\nfunc (p *Buffer) Marshal(pb Message) error {\n\tvar err error\n\tif p.deterministic {\n\t\tif _, ok := pb.(Marshaler); ok {\n\t\t\treturn fmt.Errorf(\"proto: deterministic not supported by the Marshal method of %T\", pb)\n\t\t}\n\t}\n\tif m, ok := pb.(newMarshaler); ok {\n\t\tsiz := m.XXX_Size()\n\t\tp.grow(siz) // make sure buf has enough capacity\n\t\tpp := p.buf[len(p.buf) : len(p.buf) : len(p.buf)+siz]\n\t\tpp, err = m.XXX_Marshal(pp, p.deterministic)\n\t\tp.buf = append(p.buf, pp...)\n\t\treturn err\n\t}\n\tif m, ok := pb.(Marshaler); ok {\n\t\t// If the message can marshal itself, let it do it, for compatibility.\n\t\t// NOTE: This is not efficient.\n\t\tvar b []byte\n\t\tb, err = m.Marshal()\n\t\tp.buf = append(p.buf, b...)\n\t\treturn err\n\t}\n\t// in case somehow we didn't generate the wrapper\n\tif pb == nil {\n\t\treturn ErrNil\n\t}\n\tvar info InternalMessageInfo\n\tsiz := info.Size(pb)\n\tp.grow(siz) // make sure buf has enough capacity\n\tp.buf, err = info.Marshal(p.buf, pb, p.deterministic)\n\treturn err\n}\n\n// grow grows the buffer's capacity, if necessary, to guarantee space for\n// another n bytes. After grow(n), at least n bytes can be written to the\n// buffer without another allocation.\nfunc (p *Buffer) grow(n int) {\n\tneed := len(p.buf) + n\n\tif need <= cap(p.buf) {\n\t\treturn\n\t}\n\tnewCap := len(p.buf) * 2\n\tif newCap < need {\n\t\tnewCap = need\n\t}\n\tp.buf = append(make([]byte, 0, newCap), p.buf...)\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"reflect\"\n\t\"time\"\n)\n\n// makeMessageRefMarshaler differs a bit from makeMessageMarshaler\n// It marshal a message T instead of a *T\nfunc makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tsiz := u.size(ptr)\n\t\t\treturn siz + SizeVarint(uint64(siz)) + tagsize\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tsiz := u.cachedsize(ptr)\n\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\treturn u.marshal(b, ptr, deterministic)\n\t\t}\n}\n\n// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler\n// It marshals a slice of messages []T instead of []*T\nfunc makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\te := elem.Interface()\n\t\t\t\tv := toAddrPointer(&e, false)\n\t\t\t\tsiz := u.size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tvar err, errreq error\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\te := elem.Interface()\n\t\t\t\tv := toAddrPointer(&e, false)\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tsiz := u.size(v)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb, err = u.marshal(b, v, deterministic)\n\n\t\t\t\tif err != nil {\n\t\t\t\t\tif _, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\t\t\t// Required field in submessage is not set.\n\t\t\t\t\t\t// We record the error but keep going, to give a complete marshaling.\n\t\t\t\t\t\tif errreq == nil {\n\t\t\t\t\t\t\terrreq = err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif err == ErrNil {\n\t\t\t\t\t\terr = errRepeatedHasNil\n\t\t\t\t\t}\n\t\t\t\t\treturn b, err\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn b, errreq\n\t\t}\n}\n\nfunc makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tm := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)\n\t\t\tsiz := m.Size()\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tm := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)\n\t\t\tsiz := m.Size()\n\t\t\tbuf, err := m.Marshal()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tm := ptr.asPointerTo(u.typ).Interface().(custom)\n\t\t\tsiz := m.Size()\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tm := ptr.asPointerTo(u.typ).Interface().(custom)\n\t\t\tsiz := m.Size()\n\t\t\tbuf, err := m.Marshal()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*time.Time)\n\t\t\tts, err := timestampProto(*t)\n\t\t\tif err != nil {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tsiz := Size(ts)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*time.Time)\n\t\t\tts, err := timestampProto(*t)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tbuf, err := Marshal(ts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)\n\t\t\tts, err := timestampProto(*t)\n\t\t\tif err != nil {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tsiz := Size(ts)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)\n\t\t\tts, err := timestampProto(*t)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tbuf, err := Marshal(ts)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(time.Time)\n\t\t\t\tts, err := timestampProto(t)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t\tsiz := Size(ts)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(time.Time)\n\t\t\t\tts, err := timestampProto(t)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tsiz := Size(ts)\n\t\t\t\tbuf, err := Marshal(ts)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*time.Time)\n\t\t\t\tts, err := timestampProto(*t)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0\n\t\t\t\t}\n\t\t\t\tsiz := Size(ts)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*time.Time)\n\t\t\t\tts, err := timestampProto(*t)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tsiz := Size(ts)\n\t\t\t\tbuf, err := Marshal(ts)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\td := ptr.asPointerTo(u.typ).Interface().(*time.Duration)\n\t\t\tdur := durationProto(*d)\n\t\t\tsiz := Size(dur)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\td := ptr.asPointerTo(u.typ).Interface().(*time.Duration)\n\t\t\tdur := durationProto(*d)\n\t\t\tbuf, err := Marshal(dur)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\td := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)\n\t\t\tdur := durationProto(*d)\n\t\t\tsiz := Size(dur)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\td := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)\n\t\t\tdur := durationProto(*d)\n\t\t\tbuf, err := Marshal(dur)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\td := elem.Interface().(time.Duration)\n\t\t\t\tdur := durationProto(d)\n\t\t\t\tsiz := Size(dur)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\td := elem.Interface().(time.Duration)\n\t\t\t\tdur := durationProto(d)\n\t\t\t\tsiz := Size(dur)\n\t\t\t\tbuf, err := Marshal(dur)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\td := elem.Interface().(*time.Duration)\n\t\t\t\tdur := durationProto(*d)\n\t\t\t\tsiz := Size(dur)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\td := elem.Interface().(*time.Duration)\n\t\t\t\tdur := durationProto(*d)\n\t\t\t\tsiz := Size(dur)\n\t\t\t\tbuf, err := Marshal(dur)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/table_merge.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2016 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\n// Merge merges the src message into dst.\n// This assumes that dst and src of the same type and are non-nil.\nfunc (a *InternalMessageInfo) Merge(dst, src Message) {\n\tmi := atomicLoadMergeInfo(&a.merge)\n\tif mi == nil {\n\t\tmi = getMergeInfo(reflect.TypeOf(dst).Elem())\n\t\tatomicStoreMergeInfo(&a.merge, mi)\n\t}\n\tmi.merge(toPointer(&dst), toPointer(&src))\n}\n\ntype mergeInfo struct {\n\ttyp reflect.Type\n\n\tinitialized int32 // 0: only typ is valid, 1: everything is valid\n\tlock        sync.Mutex\n\n\tfields       []mergeFieldInfo\n\tunrecognized field // Offset of XXX_unrecognized\n}\n\ntype mergeFieldInfo struct {\n\tfield field // Offset of field, guaranteed to be valid\n\n\t// isPointer reports whether the value in the field is a pointer.\n\t// This is true for the following situations:\n\t//\t* Pointer to struct\n\t//\t* Pointer to basic type (proto2 only)\n\t//\t* Slice (first value in slice header is a pointer)\n\t//\t* String (first value in string header is a pointer)\n\tisPointer bool\n\n\t// basicWidth reports the width of the field assuming that it is directly\n\t// embedded in the struct (as is the case for basic types in proto3).\n\t// The possible values are:\n\t// \t0: invalid\n\t//\t1: bool\n\t//\t4: int32, uint32, float32\n\t//\t8: int64, uint64, float64\n\tbasicWidth int\n\n\t// Where dst and src are pointers to the types being merged.\n\tmerge func(dst, src pointer)\n}\n\nvar (\n\tmergeInfoMap  = map[reflect.Type]*mergeInfo{}\n\tmergeInfoLock sync.Mutex\n)\n\nfunc getMergeInfo(t reflect.Type) *mergeInfo {\n\tmergeInfoLock.Lock()\n\tdefer mergeInfoLock.Unlock()\n\tmi := mergeInfoMap[t]\n\tif mi == nil {\n\t\tmi = &mergeInfo{typ: t}\n\t\tmergeInfoMap[t] = mi\n\t}\n\treturn mi\n}\n\n// merge merges src into dst assuming they are both of type *mi.typ.\nfunc (mi *mergeInfo) merge(dst, src pointer) {\n\tif dst.isNil() {\n\t\tpanic(\"proto: nil destination\")\n\t}\n\tif src.isNil() {\n\t\treturn // Nothing to do.\n\t}\n\n\tif atomic.LoadInt32(&mi.initialized) == 0 {\n\t\tmi.computeMergeInfo()\n\t}\n\n\tfor _, fi := range mi.fields {\n\t\tsfp := src.offset(fi.field)\n\n\t\t// As an optimization, we can avoid the merge function call cost\n\t\t// if we know for sure that the source will have no effect\n\t\t// by checking if it is the zero value.\n\t\tif unsafeAllowed {\n\t\t\tif fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif fi.basicWidth > 0 {\n\t\t\t\tswitch {\n\t\t\t\tcase fi.basicWidth == 1 && !*sfp.toBool():\n\t\t\t\t\tcontinue\n\t\t\t\tcase fi.basicWidth == 4 && *sfp.toUint32() == 0:\n\t\t\t\t\tcontinue\n\t\t\t\tcase fi.basicWidth == 8 && *sfp.toUint64() == 0:\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdfp := dst.offset(fi.field)\n\t\tfi.merge(dfp, sfp)\n\t}\n\n\t// TODO: Make this faster?\n\tout := dst.asPointerTo(mi.typ).Elem()\n\tin := src.asPointerTo(mi.typ).Elem()\n\tif emIn, err := extendable(in.Addr().Interface()); err == nil {\n\t\temOut, _ := extendable(out.Addr().Interface())\n\t\tmIn, muIn := emIn.extensionsRead()\n\t\tif mIn != nil {\n\t\t\tmOut := emOut.extensionsWrite()\n\t\t\tmuIn.Lock()\n\t\t\tmergeExtension(mOut, mIn)\n\t\t\tmuIn.Unlock()\n\t\t}\n\t}\n\n\tif mi.unrecognized.IsValid() {\n\t\tif b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 {\n\t\t\t*dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...)\n\t\t}\n\t}\n}\n\nfunc (mi *mergeInfo) computeMergeInfo() {\n\tmi.lock.Lock()\n\tdefer mi.lock.Unlock()\n\tif mi.initialized != 0 {\n\t\treturn\n\t}\n\tt := mi.typ\n\tn := t.NumField()\n\n\tprops := GetProperties(t)\n\tfor i := 0; i < n; i++ {\n\t\tf := t.Field(i)\n\t\tif strings.HasPrefix(f.Name, \"XXX_\") {\n\t\t\tcontinue\n\t\t}\n\n\t\tmfi := mergeFieldInfo{field: toField(&f)}\n\t\ttf := f.Type\n\n\t\t// As an optimization, we can avoid the merge function call cost\n\t\t// if we know for sure that the source will have no effect\n\t\t// by checking if it is the zero value.\n\t\tif unsafeAllowed {\n\t\t\tswitch tf.Kind() {\n\t\t\tcase reflect.Ptr, reflect.Slice, reflect.String:\n\t\t\t\t// As a special case, we assume slices and strings are pointers\n\t\t\t\t// since we know that the first field in the SliceSlice or\n\t\t\t\t// StringHeader is a data pointer.\n\t\t\t\tmfi.isPointer = true\n\t\t\tcase reflect.Bool:\n\t\t\t\tmfi.basicWidth = 1\n\t\t\tcase reflect.Int32, reflect.Uint32, reflect.Float32:\n\t\t\t\tmfi.basicWidth = 4\n\t\t\tcase reflect.Int64, reflect.Uint64, reflect.Float64:\n\t\t\t\tmfi.basicWidth = 8\n\t\t\t}\n\t\t}\n\n\t\t// Unwrap tf to get at its most basic type.\n\t\tvar isPointer, isSlice bool\n\t\tif tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {\n\t\t\tisSlice = true\n\t\t\ttf = tf.Elem()\n\t\t}\n\t\tif tf.Kind() == reflect.Ptr {\n\t\t\tisPointer = true\n\t\t\ttf = tf.Elem()\n\t\t}\n\t\tif isPointer && isSlice && tf.Kind() != reflect.Struct {\n\t\t\tpanic(\"both pointer and slice for basic type in \" + tf.Name())\n\t\t}\n\n\t\tswitch tf.Kind() {\n\t\tcase reflect.Int32:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []int32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\t// NOTE: toInt32Slice is not defined (see pointer_reflect.go).\n\t\t\t\t\t/*\n\t\t\t\t\t\tsfsp := src.toInt32Slice()\n\t\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\t\tdfsp := dst.toInt32Slice()\n\t\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t\t*dfsp = []int64{}\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\tsfs := src.getInt32Slice()\n\t\t\t\t\tif sfs != nil {\n\t\t\t\t\t\tdfs := dst.getInt32Slice()\n\t\t\t\t\t\tdfs = append(dfs, sfs...)\n\t\t\t\t\t\tif dfs == nil {\n\t\t\t\t\t\t\tdfs = []int32{}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdst.setInt32Slice(dfs)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *int32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\t// NOTE: toInt32Ptr is not defined (see pointer_reflect.go).\n\t\t\t\t\t/*\n\t\t\t\t\t\tsfpp := src.toInt32Ptr()\n\t\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\t\tdfpp := dst.toInt32Ptr()\n\t\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t\t*dfpp = Int32(**sfpp)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t**dfpp = **sfpp\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\tsfp := src.getInt32Ptr()\n\t\t\t\t\tif sfp != nil {\n\t\t\t\t\t\tdfp := dst.getInt32Ptr()\n\t\t\t\t\t\tif dfp == nil {\n\t\t\t\t\t\t\tdst.setInt32Ptr(*sfp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t*dfp = *sfp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., int32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toInt32(); v != 0 {\n\t\t\t\t\t\t*dst.toInt32() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Int64:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []int64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfsp := src.toInt64Slice()\n\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\tdfsp := dst.toInt64Slice()\n\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t*dfsp = []int64{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *int64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfpp := src.toInt64Ptr()\n\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\tdfpp := dst.toInt64Ptr()\n\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t*dfpp = Int64(**sfpp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t**dfpp = **sfpp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., int64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toInt64(); v != 0 {\n\t\t\t\t\t\t*dst.toInt64() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Uint32:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []uint32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfsp := src.toUint32Slice()\n\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\tdfsp := dst.toUint32Slice()\n\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t*dfsp = []uint32{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *uint32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfpp := src.toUint32Ptr()\n\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\tdfpp := dst.toUint32Ptr()\n\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t*dfpp = Uint32(**sfpp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t**dfpp = **sfpp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., uint32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toUint32(); v != 0 {\n\t\t\t\t\t\t*dst.toUint32() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Uint64:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []uint64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfsp := src.toUint64Slice()\n\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\tdfsp := dst.toUint64Slice()\n\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t*dfsp = []uint64{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *uint64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfpp := src.toUint64Ptr()\n\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\tdfpp := dst.toUint64Ptr()\n\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t*dfpp = Uint64(**sfpp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t**dfpp = **sfpp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., uint64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toUint64(); v != 0 {\n\t\t\t\t\t\t*dst.toUint64() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Float32:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []float32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfsp := src.toFloat32Slice()\n\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\tdfsp := dst.toFloat32Slice()\n\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t*dfsp = []float32{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *float32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfpp := src.toFloat32Ptr()\n\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\tdfpp := dst.toFloat32Ptr()\n\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t*dfpp = Float32(**sfpp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t**dfpp = **sfpp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., float32\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toFloat32(); v != 0 {\n\t\t\t\t\t\t*dst.toFloat32() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Float64:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []float64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfsp := src.toFloat64Slice()\n\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\tdfsp := dst.toFloat64Slice()\n\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t*dfsp = []float64{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *float64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfpp := src.toFloat64Ptr()\n\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\tdfpp := dst.toFloat64Ptr()\n\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t*dfpp = Float64(**sfpp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t**dfpp = **sfpp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., float64\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toFloat64(); v != 0 {\n\t\t\t\t\t\t*dst.toFloat64() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Bool:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []bool\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfsp := src.toBoolSlice()\n\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\tdfsp := dst.toBoolSlice()\n\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t*dfsp = []bool{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *bool\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfpp := src.toBoolPtr()\n\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\tdfpp := dst.toBoolPtr()\n\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t*dfpp = Bool(**sfpp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t**dfpp = **sfpp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., bool\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toBool(); v {\n\t\t\t\t\t\t*dst.toBool() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.String:\n\t\t\tswitch {\n\t\t\tcase isSlice: // E.g., []string\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfsp := src.toStringSlice()\n\t\t\t\t\tif *sfsp != nil {\n\t\t\t\t\t\tdfsp := dst.toStringSlice()\n\t\t\t\t\t\t*dfsp = append(*dfsp, *sfsp...)\n\t\t\t\t\t\tif *dfsp == nil {\n\t\t\t\t\t\t\t*dfsp = []string{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase isPointer: // E.g., *string\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsfpp := src.toStringPtr()\n\t\t\t\t\tif *sfpp != nil {\n\t\t\t\t\t\tdfpp := dst.toStringPtr()\n\t\t\t\t\t\tif *dfpp == nil {\n\t\t\t\t\t\t\t*dfpp = String(**sfpp)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t**dfpp = **sfpp\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., string\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tif v := *src.toString(); v != \"\" {\n\t\t\t\t\t\t*dst.toString() = v\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Slice:\n\t\t\tisProto3 := props.Prop[i].proto3\n\t\t\tswitch {\n\t\t\tcase isPointer:\n\t\t\t\tpanic(\"bad pointer in byte slice case in \" + tf.Name())\n\t\t\tcase tf.Elem().Kind() != reflect.Uint8:\n\t\t\t\tpanic(\"bad element kind in byte slice case in \" + tf.Name())\n\t\t\tcase isSlice: // E.g., [][]byte\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsbsp := src.toBytesSlice()\n\t\t\t\t\tif *sbsp != nil {\n\t\t\t\t\t\tdbsp := dst.toBytesSlice()\n\t\t\t\t\t\tfor _, sb := range *sbsp {\n\t\t\t\t\t\t\tif sb == nil {\n\t\t\t\t\t\t\t\t*dbsp = append(*dbsp, nil)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t*dbsp = append(*dbsp, append([]byte{}, sb...))\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif *dbsp == nil {\n\t\t\t\t\t\t\t*dbsp = [][]byte{}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., []byte\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsbp := src.toBytes()\n\t\t\t\t\tif *sbp != nil {\n\t\t\t\t\t\tdbp := dst.toBytes()\n\t\t\t\t\t\tif !isProto3 || len(*sbp) > 0 {\n\t\t\t\t\t\t\t*dbp = append([]byte{}, *sbp...)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Struct:\n\t\t\tswitch {\n\t\t\tcase isSlice && !isPointer: // E.g. []pb.T\n\t\t\t\tmergeInfo := getMergeInfo(tf)\n\t\t\t\tzero := reflect.Zero(tf)\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\t// TODO: Make this faster?\n\t\t\t\t\tdstsp := dst.asPointerTo(f.Type)\n\t\t\t\t\tdsts := dstsp.Elem()\n\t\t\t\t\tsrcs := src.asPointerTo(f.Type).Elem()\n\t\t\t\t\tfor i := 0; i < srcs.Len(); i++ {\n\t\t\t\t\t\tdsts = reflect.Append(dsts, zero)\n\t\t\t\t\t\tsrcElement := srcs.Index(i).Addr()\n\t\t\t\t\t\tdstElement := dsts.Index(dsts.Len() - 1).Addr()\n\t\t\t\t\t\tmergeInfo.merge(valToPointer(dstElement), valToPointer(srcElement))\n\t\t\t\t\t}\n\t\t\t\t\tif dsts.IsNil() {\n\t\t\t\t\t\tdsts = reflect.MakeSlice(f.Type, 0, 0)\n\t\t\t\t\t}\n\t\t\t\t\tdstsp.Elem().Set(dsts)\n\t\t\t\t}\n\t\t\tcase !isPointer:\n\t\t\t\tmergeInfo := getMergeInfo(tf)\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tmergeInfo.merge(dst, src)\n\t\t\t\t}\n\t\t\tcase isSlice: // E.g., []*pb.T\n\t\t\t\tmergeInfo := getMergeInfo(tf)\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsps := src.getPointerSlice()\n\t\t\t\t\tif sps != nil {\n\t\t\t\t\t\tdps := dst.getPointerSlice()\n\t\t\t\t\t\tfor _, sp := range sps {\n\t\t\t\t\t\t\tvar dp pointer\n\t\t\t\t\t\t\tif !sp.isNil() {\n\t\t\t\t\t\t\t\tdp = valToPointer(reflect.New(tf))\n\t\t\t\t\t\t\t\tmergeInfo.merge(dp, sp)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tdps = append(dps, dp)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif dps == nil {\n\t\t\t\t\t\t\tdps = []pointer{}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdst.setPointerSlice(dps)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault: // E.g., *pb.T\n\t\t\t\tmergeInfo := getMergeInfo(tf)\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsp := src.getPointer()\n\t\t\t\t\tif !sp.isNil() {\n\t\t\t\t\t\tdp := dst.getPointer()\n\t\t\t\t\t\tif dp.isNil() {\n\t\t\t\t\t\t\tdp = valToPointer(reflect.New(tf))\n\t\t\t\t\t\t\tdst.setPointer(dp)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmergeInfo.merge(dp, sp)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Map:\n\t\t\tswitch {\n\t\t\tcase isPointer || isSlice:\n\t\t\t\tpanic(\"bad pointer or slice in map case in \" + tf.Name())\n\t\t\tdefault: // E.g., map[K]V\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsm := src.asPointerTo(tf).Elem()\n\t\t\t\t\tif sm.Len() == 0 {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tdm := dst.asPointerTo(tf).Elem()\n\t\t\t\t\tif dm.IsNil() {\n\t\t\t\t\t\tdm.Set(reflect.MakeMap(tf))\n\t\t\t\t\t}\n\n\t\t\t\t\tswitch tf.Elem().Kind() {\n\t\t\t\t\tcase reflect.Ptr: // Proto struct (e.g., *T)\n\t\t\t\t\t\tfor _, key := range sm.MapKeys() {\n\t\t\t\t\t\t\tval := sm.MapIndex(key)\n\t\t\t\t\t\t\tval = reflect.ValueOf(Clone(val.Interface().(Message)))\n\t\t\t\t\t\t\tdm.SetMapIndex(key, val)\n\t\t\t\t\t\t}\n\t\t\t\t\tcase reflect.Slice: // E.g. Bytes type (e.g., []byte)\n\t\t\t\t\t\tfor _, key := range sm.MapKeys() {\n\t\t\t\t\t\t\tval := sm.MapIndex(key)\n\t\t\t\t\t\t\tval = reflect.ValueOf(append([]byte{}, val.Bytes()...))\n\t\t\t\t\t\t\tdm.SetMapIndex(key, val)\n\t\t\t\t\t\t}\n\t\t\t\t\tdefault: // Basic type (e.g., string)\n\t\t\t\t\t\tfor _, key := range sm.MapKeys() {\n\t\t\t\t\t\t\tval := sm.MapIndex(key)\n\t\t\t\t\t\t\tdm.SetMapIndex(key, val)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase reflect.Interface:\n\t\t\t// Must be oneof field.\n\t\t\tswitch {\n\t\t\tcase isPointer || isSlice:\n\t\t\t\tpanic(\"bad pointer or slice in interface case in \" + tf.Name())\n\t\t\tdefault: // E.g., interface{}\n\t\t\t\t// TODO: Make this faster?\n\t\t\t\tmfi.merge = func(dst, src pointer) {\n\t\t\t\t\tsu := src.asPointerTo(tf).Elem()\n\t\t\t\t\tif !su.IsNil() {\n\t\t\t\t\t\tdu := dst.asPointerTo(tf).Elem()\n\t\t\t\t\t\ttyp := su.Elem().Type()\n\t\t\t\t\t\tif du.IsNil() || du.Elem().Type() != typ {\n\t\t\t\t\t\t\tdu.Set(reflect.New(typ.Elem())) // Initialize interface if empty\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsv := su.Elem().Elem().Field(0)\n\t\t\t\t\t\tif sv.Kind() == reflect.Ptr && sv.IsNil() {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdv := du.Elem().Elem().Field(0)\n\t\t\t\t\t\tif dv.Kind() == reflect.Ptr && dv.IsNil() {\n\t\t\t\t\t\t\tdv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch sv.Type().Kind() {\n\t\t\t\t\t\tcase reflect.Ptr: // Proto struct (e.g., *T)\n\t\t\t\t\t\t\tMerge(dv.Interface().(Message), sv.Interface().(Message))\n\t\t\t\t\t\tcase reflect.Slice: // E.g. Bytes type (e.g., []byte)\n\t\t\t\t\t\t\tdv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...)))\n\t\t\t\t\t\tdefault: // Basic type (e.g., string)\n\t\t\t\t\t\t\tdv.Set(sv)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"merger not found for type:%s\", tf))\n\t\t}\n\t\tmi.fields = append(mi.fields, mfi)\n\t}\n\n\tmi.unrecognized = invalidField\n\tif f, ok := t.FieldByName(\"XXX_unrecognized\"); ok {\n\t\tif f.Type != reflect.TypeOf([]byte{}) {\n\t\t\tpanic(\"expected XXX_unrecognized to be of type []byte\")\n\t\t}\n\t\tmi.unrecognized = toField(&f)\n\t}\n\n\tatomic.StoreInt32(&mi.initialized, 1)\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/table_unmarshal.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2016 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"unicode/utf8\"\n)\n\n// Unmarshal is the entry point from the generated .pb.go files.\n// This function is not intended to be used by non-generated code.\n// This function is not subject to any compatibility guarantee.\n// msg contains a pointer to a protocol buffer struct.\n// b is the data to be unmarshaled into the protocol buffer.\n// a is a pointer to a place to store cached unmarshal information.\nfunc (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error {\n\t// Load the unmarshal information for this message type.\n\t// The atomic load ensures memory consistency.\n\tu := atomicLoadUnmarshalInfo(&a.unmarshal)\n\tif u == nil {\n\t\t// Slow path: find unmarshal info for msg, update a with it.\n\t\tu = getUnmarshalInfo(reflect.TypeOf(msg).Elem())\n\t\tatomicStoreUnmarshalInfo(&a.unmarshal, u)\n\t}\n\t// Then do the unmarshaling.\n\terr := u.unmarshal(toPointer(&msg), b)\n\treturn err\n}\n\ntype unmarshalInfo struct {\n\ttyp reflect.Type // type of the protobuf struct\n\n\t// 0 = only typ field is initialized\n\t// 1 = completely initialized\n\tinitialized     int32\n\tlock            sync.Mutex                    // prevents double initialization\n\tdense           []unmarshalFieldInfo          // fields indexed by tag #\n\tsparse          map[uint64]unmarshalFieldInfo // fields indexed by tag #\n\treqFields       []string                      // names of required fields\n\treqMask         uint64                        // 1<<len(reqFields)-1\n\tunrecognized    field                         // offset of []byte to put unrecognized data (or invalidField if we should throw it away)\n\textensions      field                         // offset of extensions field (of type proto.XXX_InternalExtensions), or invalidField if it does not exist\n\toldExtensions   field                         // offset of old-form extensions field (of type map[int]Extension)\n\textensionRanges []ExtensionRange              // if non-nil, implies extensions field is valid\n\tisMessageSet    bool                          // if true, implies extensions field is valid\n\n\tbytesExtensions field // offset of XXX_extensions with type []byte\n}\n\n// An unmarshaler takes a stream of bytes and a pointer to a field of a message.\n// It decodes the field, stores it at f, and returns the unused bytes.\n// w is the wire encoding.\n// b is the data after the tag and wire encoding have been read.\ntype unmarshaler func(b []byte, f pointer, w int) ([]byte, error)\n\ntype unmarshalFieldInfo struct {\n\t// location of the field in the proto message structure.\n\tfield field\n\n\t// function to unmarshal the data for the field.\n\tunmarshal unmarshaler\n\n\t// if a required field, contains a single set bit at this field's index in the required field list.\n\treqMask uint64\n\n\tname string // name of the field, for error reporting\n}\n\nvar (\n\tunmarshalInfoMap  = map[reflect.Type]*unmarshalInfo{}\n\tunmarshalInfoLock sync.Mutex\n)\n\n// getUnmarshalInfo returns the data structure which can be\n// subsequently used to unmarshal a message of the given type.\n// t is the type of the message (note: not pointer to message).\nfunc getUnmarshalInfo(t reflect.Type) *unmarshalInfo {\n\t// It would be correct to return a new unmarshalInfo\n\t// unconditionally. We would end up allocating one\n\t// per occurrence of that type as a message or submessage.\n\t// We use a cache here just to reduce memory usage.\n\tunmarshalInfoLock.Lock()\n\tdefer unmarshalInfoLock.Unlock()\n\tu := unmarshalInfoMap[t]\n\tif u == nil {\n\t\tu = &unmarshalInfo{typ: t}\n\t\t// Note: we just set the type here. The rest of the fields\n\t\t// will be initialized on first use.\n\t\tunmarshalInfoMap[t] = u\n\t}\n\treturn u\n}\n\n// unmarshal does the main work of unmarshaling a message.\n// u provides type information used to unmarshal the message.\n// m is a pointer to a protocol buffer message.\n// b is a byte stream to unmarshal into m.\n// This is top routine used when recursively unmarshaling submessages.\nfunc (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {\n\tif atomic.LoadInt32(&u.initialized) == 0 {\n\t\tu.computeUnmarshalInfo()\n\t}\n\tif u.isMessageSet {\n\t\treturn unmarshalMessageSet(b, m.offset(u.extensions).toExtensions())\n\t}\n\tvar reqMask uint64 // bitmask of required fields we've seen.\n\tvar errLater error\n\tfor len(b) > 0 {\n\t\t// Read tag and wire type.\n\t\t// Special case 1 and 2 byte varints.\n\t\tvar x uint64\n\t\tif b[0] < 128 {\n\t\t\tx = uint64(b[0])\n\t\t\tb = b[1:]\n\t\t} else if len(b) >= 2 && b[1] < 128 {\n\t\t\tx = uint64(b[0]&0x7f) + uint64(b[1])<<7\n\t\t\tb = b[2:]\n\t\t} else {\n\t\t\tvar n int\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t}\n\t\ttag := x >> 3\n\t\twire := int(x) & 7\n\n\t\t// Dispatch on the tag to one of the unmarshal* functions below.\n\t\tvar f unmarshalFieldInfo\n\t\tif tag < uint64(len(u.dense)) {\n\t\t\tf = u.dense[tag]\n\t\t} else {\n\t\t\tf = u.sparse[tag]\n\t\t}\n\t\tif fn := f.unmarshal; fn != nil {\n\t\t\tvar err error\n\t\t\tb, err = fn(b, m.offset(f.field), wire)\n\t\t\tif err == nil {\n\t\t\t\treqMask |= f.reqMask\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif r, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\t// Remember this error, but keep parsing. We need to produce\n\t\t\t\t// a full parse even if a required field is missing.\n\t\t\t\tif errLater == nil {\n\t\t\t\t\terrLater = r\n\t\t\t\t}\n\t\t\t\treqMask |= f.reqMask\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err != errInternalBadWireType {\n\t\t\t\tif err == errInvalidUTF8 {\n\t\t\t\t\tif errLater == nil {\n\t\t\t\t\t\tfullName := revProtoTypes[reflect.PtrTo(u.typ)] + \".\" + f.name\n\t\t\t\t\t\terrLater = &invalidUTF8Error{fullName}\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// Fragments with bad wire type are treated as unknown fields.\n\t\t}\n\n\t\t// Unknown tag.\n\t\tif !u.unrecognized.IsValid() {\n\t\t\t// Don't keep unrecognized data; just skip it.\n\t\t\tvar err error\n\t\t\tb, err = skipField(b, wire)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\t// Keep unrecognized data around.\n\t\t// maybe in extensions, maybe in the unrecognized field.\n\t\tz := m.offset(u.unrecognized).toBytes()\n\t\tvar emap map[int32]Extension\n\t\tvar e Extension\n\t\tfor _, r := range u.extensionRanges {\n\t\t\tif uint64(r.Start) <= tag && tag <= uint64(r.End) {\n\t\t\t\tif u.extensions.IsValid() {\n\t\t\t\t\tmp := m.offset(u.extensions).toExtensions()\n\t\t\t\t\temap = mp.extensionsWrite()\n\t\t\t\t\te = emap[int32(tag)]\n\t\t\t\t\tz = &e.enc\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif u.oldExtensions.IsValid() {\n\t\t\t\t\tp := m.offset(u.oldExtensions).toOldExtensions()\n\t\t\t\t\temap = *p\n\t\t\t\t\tif emap == nil {\n\t\t\t\t\t\temap = map[int32]Extension{}\n\t\t\t\t\t\t*p = emap\n\t\t\t\t\t}\n\t\t\t\t\te = emap[int32(tag)]\n\t\t\t\t\tz = &e.enc\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif u.bytesExtensions.IsValid() {\n\t\t\t\t\tz = m.offset(u.bytesExtensions).toBytes()\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tpanic(\"no extensions field available\")\n\t\t\t}\n\t\t}\n\t\t// Use wire type to skip data.\n\t\tvar err error\n\t\tb0 := b\n\t\tb, err = skipField(b, wire)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*z = encodeVarint(*z, tag<<3|uint64(wire))\n\t\t*z = append(*z, b0[:len(b0)-len(b)]...)\n\n\t\tif emap != nil {\n\t\t\temap[int32(tag)] = e\n\t\t}\n\t}\n\tif reqMask != u.reqMask && errLater == nil {\n\t\t// A required field of this message is missing.\n\t\tfor _, n := range u.reqFields {\n\t\t\tif reqMask&1 == 0 {\n\t\t\t\terrLater = &RequiredNotSetError{n}\n\t\t\t}\n\t\t\treqMask >>= 1\n\t\t}\n\t}\n\treturn errLater\n}\n\n// computeUnmarshalInfo fills in u with information for use\n// in unmarshaling protocol buffers of type u.typ.\nfunc (u *unmarshalInfo) computeUnmarshalInfo() {\n\tu.lock.Lock()\n\tdefer u.lock.Unlock()\n\tif u.initialized != 0 {\n\t\treturn\n\t}\n\tt := u.typ\n\tn := t.NumField()\n\n\t// Set up the \"not found\" value for the unrecognized byte buffer.\n\t// This is the default for proto3.\n\tu.unrecognized = invalidField\n\tu.extensions = invalidField\n\tu.oldExtensions = invalidField\n\tu.bytesExtensions = invalidField\n\n\t// List of the generated type and offset for each oneof field.\n\ttype oneofField struct {\n\t\tityp  reflect.Type // interface type of oneof field\n\t\tfield field        // offset in containing message\n\t}\n\tvar oneofFields []oneofField\n\n\tfor i := 0; i < n; i++ {\n\t\tf := t.Field(i)\n\t\tif f.Name == \"XXX_unrecognized\" {\n\t\t\t// The byte slice used to hold unrecognized input is special.\n\t\t\tif f.Type != reflect.TypeOf(([]byte)(nil)) {\n\t\t\t\tpanic(\"bad type for XXX_unrecognized field: \" + f.Type.Name())\n\t\t\t}\n\t\t\tu.unrecognized = toField(&f)\n\t\t\tcontinue\n\t\t}\n\t\tif f.Name == \"XXX_InternalExtensions\" {\n\t\t\t// Ditto here.\n\t\t\tif f.Type != reflect.TypeOf(XXX_InternalExtensions{}) {\n\t\t\t\tpanic(\"bad type for XXX_InternalExtensions field: \" + f.Type.Name())\n\t\t\t}\n\t\t\tu.extensions = toField(&f)\n\t\t\tif f.Tag.Get(\"protobuf_messageset\") == \"1\" {\n\t\t\t\tu.isMessageSet = true\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif f.Name == \"XXX_extensions\" {\n\t\t\t// An older form of the extensions field.\n\t\t\tif f.Type == reflect.TypeOf((map[int32]Extension)(nil)) {\n\t\t\t\tu.oldExtensions = toField(&f)\n\t\t\t\tcontinue\n\t\t\t} else if f.Type == reflect.TypeOf(([]byte)(nil)) {\n\t\t\t\tu.bytesExtensions = toField(&f)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpanic(\"bad type for XXX_extensions field: \" + f.Type.Name())\n\t\t}\n\t\tif f.Name == \"XXX_NoUnkeyedLiteral\" || f.Name == \"XXX_sizecache\" {\n\t\t\tcontinue\n\t\t}\n\n\t\toneof := f.Tag.Get(\"protobuf_oneof\")\n\t\tif oneof != \"\" {\n\t\t\toneofFields = append(oneofFields, oneofField{f.Type, toField(&f)})\n\t\t\t// The rest of oneof processing happens below.\n\t\t\tcontinue\n\t\t}\n\n\t\ttags := f.Tag.Get(\"protobuf\")\n\t\ttagArray := strings.Split(tags, \",\")\n\t\tif len(tagArray) < 2 {\n\t\t\tpanic(\"protobuf tag not enough fields in \" + t.Name() + \".\" + f.Name + \": \" + tags)\n\t\t}\n\t\ttag, err := strconv.Atoi(tagArray[1])\n\t\tif err != nil {\n\t\t\tpanic(\"protobuf tag field not an integer: \" + tagArray[1])\n\t\t}\n\n\t\tname := \"\"\n\t\tfor _, tag := range tagArray[3:] {\n\t\t\tif strings.HasPrefix(tag, \"name=\") {\n\t\t\t\tname = tag[5:]\n\t\t\t}\n\t\t}\n\n\t\t// Extract unmarshaling function from the field (its type and tags).\n\t\tunmarshal := fieldUnmarshaler(&f)\n\n\t\t// Required field?\n\t\tvar reqMask uint64\n\t\tif tagArray[2] == \"req\" {\n\t\t\tbit := len(u.reqFields)\n\t\t\tu.reqFields = append(u.reqFields, name)\n\t\t\treqMask = uint64(1) << uint(bit)\n\t\t\t// TODO: if we have more than 64 required fields, we end up\n\t\t\t// not verifying that all required fields are present.\n\t\t\t// Fix this, perhaps using a count of required fields?\n\t\t}\n\n\t\t// Store the info in the correct slot in the message.\n\t\tu.setTag(tag, toField(&f), unmarshal, reqMask, name)\n\t}\n\n\t// Find any types associated with oneof fields.\n\t// gogo: len(oneofFields) > 0 is needed for embedded oneof messages, without a marshaler and unmarshaler\n\tif len(oneofFields) > 0 {\n\t\tvar oneofImplementers []interface{}\n\t\tswitch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) {\n\t\tcase oneofFuncsIface:\n\t\t\t_, _, _, oneofImplementers = m.XXX_OneofFuncs()\n\t\tcase oneofWrappersIface:\n\t\t\toneofImplementers = m.XXX_OneofWrappers()\n\t\t}\n\t\tfor _, v := range oneofImplementers {\n\t\t\ttptr := reflect.TypeOf(v) // *Msg_X\n\t\t\ttyp := tptr.Elem()        // Msg_X\n\n\t\t\tf := typ.Field(0) // oneof implementers have one field\n\t\t\tbaseUnmarshal := fieldUnmarshaler(&f)\n\t\t\ttags := strings.Split(f.Tag.Get(\"protobuf\"), \",\")\n\t\t\tfieldNum, err := strconv.Atoi(tags[1])\n\t\t\tif err != nil {\n\t\t\t\tpanic(\"protobuf tag field not an integer: \" + tags[1])\n\t\t\t}\n\t\t\tvar name string\n\t\t\tfor _, tag := range tags {\n\t\t\t\tif strings.HasPrefix(tag, \"name=\") {\n\t\t\t\t\tname = strings.TrimPrefix(tag, \"name=\")\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Find the oneof field that this struct implements.\n\t\t\t// Might take O(n^2) to process all of the oneofs, but who cares.\n\t\t\tfor _, of := range oneofFields {\n\t\t\t\tif tptr.Implements(of.ityp) {\n\t\t\t\t\t// We have found the corresponding interface for this struct.\n\t\t\t\t\t// That lets us know where this struct should be stored\n\t\t\t\t\t// when we encounter it during unmarshaling.\n\t\t\t\t\tunmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)\n\t\t\t\t\tu.setTag(fieldNum, of.field, unmarshal, 0, name)\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\t// Get extension ranges, if any.\n\tfn := reflect.Zero(reflect.PtrTo(t)).MethodByName(\"ExtensionRangeArray\")\n\tif fn.IsValid() {\n\t\tif !u.extensions.IsValid() && !u.oldExtensions.IsValid() && !u.bytesExtensions.IsValid() {\n\t\t\tpanic(\"a message with extensions, but no extensions field in \" + t.Name())\n\t\t}\n\t\tu.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange)\n\t}\n\n\t// Explicitly disallow tag 0. This will ensure we flag an error\n\t// when decoding a buffer of all zeros. Without this code, we\n\t// would decode and skip an all-zero buffer of even length.\n\t// [0 0] is [tag=0/wiretype=varint varint-encoded-0].\n\tu.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) {\n\t\treturn nil, fmt.Errorf(\"proto: %s: illegal tag 0 (wire type %d)\", t, w)\n\t}, 0, \"\")\n\n\t// Set mask for required field check.\n\tu.reqMask = uint64(1)<<uint(len(u.reqFields)) - 1\n\n\tatomic.StoreInt32(&u.initialized, 1)\n}\n\n// setTag stores the unmarshal information for the given tag.\n// tag = tag # for field\n// field/unmarshal = unmarshal info for that field.\n// reqMask = if required, bitmask for field position in required field list. 0 otherwise.\n// name = short name of the field.\nfunc (u *unmarshalInfo) setTag(tag int, field field, unmarshal unmarshaler, reqMask uint64, name string) {\n\ti := unmarshalFieldInfo{field: field, unmarshal: unmarshal, reqMask: reqMask, name: name}\n\tn := u.typ.NumField()\n\tif tag >= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here?\n\t\tfor len(u.dense) <= tag {\n\t\t\tu.dense = append(u.dense, unmarshalFieldInfo{})\n\t\t}\n\t\tu.dense[tag] = i\n\t\treturn\n\t}\n\tif u.sparse == nil {\n\t\tu.sparse = map[uint64]unmarshalFieldInfo{}\n\t}\n\tu.sparse[uint64(tag)] = i\n}\n\n// fieldUnmarshaler returns an unmarshaler for the given field.\nfunc fieldUnmarshaler(f *reflect.StructField) unmarshaler {\n\tif f.Type.Kind() == reflect.Map {\n\t\treturn makeUnmarshalMap(f)\n\t}\n\treturn typeUnmarshaler(f.Type, f.Tag.Get(\"protobuf\"))\n}\n\n// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair.\nfunc typeUnmarshaler(t reflect.Type, tags string) unmarshaler {\n\ttagArray := strings.Split(tags, \",\")\n\tencoding := tagArray[0]\n\tname := \"unknown\"\n\tctype := false\n\tisTime := false\n\tisDuration := false\n\tisWktPointer := false\n\tproto3 := false\n\tvalidateUTF8 := true\n\tfor _, tag := range tagArray[3:] {\n\t\tif strings.HasPrefix(tag, \"name=\") {\n\t\t\tname = tag[5:]\n\t\t}\n\t\tif tag == \"proto3\" {\n\t\t\tproto3 = true\n\t\t}\n\t\tif strings.HasPrefix(tag, \"customtype=\") {\n\t\t\tctype = true\n\t\t}\n\t\tif tag == \"stdtime\" {\n\t\t\tisTime = true\n\t\t}\n\t\tif tag == \"stdduration\" {\n\t\t\tisDuration = true\n\t\t}\n\t\tif tag == \"wktptr\" {\n\t\t\tisWktPointer = true\n\t\t}\n\t}\n\tvalidateUTF8 = validateUTF8 && proto3\n\n\t// Figure out packaging (pointer, slice, or both)\n\tslice := false\n\tpointer := false\n\tif t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {\n\t\tslice = true\n\t\tt = t.Elem()\n\t}\n\tif t.Kind() == reflect.Ptr {\n\t\tpointer = true\n\t\tt = t.Elem()\n\t}\n\n\tif ctype {\n\t\tif reflect.PtrTo(t).Implements(customType) {\n\t\t\tif slice {\n\t\t\t\treturn makeUnmarshalCustomSlice(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif pointer {\n\t\t\t\treturn makeUnmarshalCustomPtr(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeUnmarshalCustom(getUnmarshalInfo(t), name)\n\t\t} else {\n\t\t\tpanic(fmt.Sprintf(\"custom type: type: %v, does not implement the proto.custom interface\", t))\n\t\t}\n\t}\n\n\tif isTime {\n\t\tif pointer {\n\t\t\tif slice {\n\t\t\t\treturn makeUnmarshalTimePtrSlice(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeUnmarshalTimePtr(getUnmarshalInfo(t), name)\n\t\t}\n\t\tif slice {\n\t\t\treturn makeUnmarshalTimeSlice(getUnmarshalInfo(t), name)\n\t\t}\n\t\treturn makeUnmarshalTime(getUnmarshalInfo(t), name)\n\t}\n\n\tif isDuration {\n\t\tif pointer {\n\t\t\tif slice {\n\t\t\t\treturn makeUnmarshalDurationPtrSlice(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeUnmarshalDurationPtr(getUnmarshalInfo(t), name)\n\t\t}\n\t\tif slice {\n\t\t\treturn makeUnmarshalDurationSlice(getUnmarshalInfo(t), name)\n\t\t}\n\t\treturn makeUnmarshalDuration(getUnmarshalInfo(t), name)\n\t}\n\n\tif isWktPointer {\n\t\tswitch t.Kind() {\n\t\tcase reflect.Float64:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdDoubleValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdDoubleValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdDoubleValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdDoubleValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase reflect.Float32:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdFloatValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdFloatValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdFloatValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdFloatValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase reflect.Int64:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdInt64ValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase reflect.Uint64:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdUInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdUInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdUInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdUInt64ValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase reflect.Int32:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdInt32ValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase reflect.Uint32:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdUInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdUInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdUInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdUInt32ValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase reflect.Bool:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdBoolValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdBoolValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdBoolValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdBoolValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase reflect.String:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdStringValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdStringValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdStringValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdStringValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tcase uint8SliceType:\n\t\t\tif pointer {\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeStdBytesValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeStdBytesValuePtrUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn makeStdBytesValueSliceUnmarshaler(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeStdBytesValueUnmarshaler(getUnmarshalInfo(t), name)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown wktpointer type %#v\", t))\n\t\t}\n\t}\n\n\t// We'll never have both pointer and slice for basic types.\n\tif pointer && slice && t.Kind() != reflect.Struct {\n\t\tpanic(\"both pointer and slice for basic type in \" + t.Name())\n\t}\n\n\tswitch t.Kind() {\n\tcase reflect.Bool:\n\t\tif pointer {\n\t\t\treturn unmarshalBoolPtr\n\t\t}\n\t\tif slice {\n\t\t\treturn unmarshalBoolSlice\n\t\t}\n\t\treturn unmarshalBoolValue\n\tcase reflect.Int32:\n\t\tswitch encoding {\n\t\tcase \"fixed32\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalFixedS32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalFixedS32Slice\n\t\t\t}\n\t\t\treturn unmarshalFixedS32Value\n\t\tcase \"varint\":\n\t\t\t// this could be int32 or enum\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalInt32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalInt32Slice\n\t\t\t}\n\t\t\treturn unmarshalInt32Value\n\t\tcase \"zigzag32\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalSint32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalSint32Slice\n\t\t\t}\n\t\t\treturn unmarshalSint32Value\n\t\t}\n\tcase reflect.Int64:\n\t\tswitch encoding {\n\t\tcase \"fixed64\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalFixedS64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalFixedS64Slice\n\t\t\t}\n\t\t\treturn unmarshalFixedS64Value\n\t\tcase \"varint\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalInt64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalInt64Slice\n\t\t\t}\n\t\t\treturn unmarshalInt64Value\n\t\tcase \"zigzag64\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalSint64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalSint64Slice\n\t\t\t}\n\t\t\treturn unmarshalSint64Value\n\t\t}\n\tcase reflect.Uint32:\n\t\tswitch encoding {\n\t\tcase \"fixed32\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalFixed32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalFixed32Slice\n\t\t\t}\n\t\t\treturn unmarshalFixed32Value\n\t\tcase \"varint\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalUint32Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalUint32Slice\n\t\t\t}\n\t\t\treturn unmarshalUint32Value\n\t\t}\n\tcase reflect.Uint64:\n\t\tswitch encoding {\n\t\tcase \"fixed64\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalFixed64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalFixed64Slice\n\t\t\t}\n\t\t\treturn unmarshalFixed64Value\n\t\tcase \"varint\":\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalUint64Ptr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalUint64Slice\n\t\t\t}\n\t\t\treturn unmarshalUint64Value\n\t\t}\n\tcase reflect.Float32:\n\t\tif pointer {\n\t\t\treturn unmarshalFloat32Ptr\n\t\t}\n\t\tif slice {\n\t\t\treturn unmarshalFloat32Slice\n\t\t}\n\t\treturn unmarshalFloat32Value\n\tcase reflect.Float64:\n\t\tif pointer {\n\t\t\treturn unmarshalFloat64Ptr\n\t\t}\n\t\tif slice {\n\t\t\treturn unmarshalFloat64Slice\n\t\t}\n\t\treturn unmarshalFloat64Value\n\tcase reflect.Map:\n\t\tpanic(\"map type in typeUnmarshaler in \" + t.Name())\n\tcase reflect.Slice:\n\t\tif pointer {\n\t\t\tpanic(\"bad pointer in slice case in \" + t.Name())\n\t\t}\n\t\tif slice {\n\t\t\treturn unmarshalBytesSlice\n\t\t}\n\t\treturn unmarshalBytesValue\n\tcase reflect.String:\n\t\tif validateUTF8 {\n\t\t\tif pointer {\n\t\t\t\treturn unmarshalUTF8StringPtr\n\t\t\t}\n\t\t\tif slice {\n\t\t\t\treturn unmarshalUTF8StringSlice\n\t\t\t}\n\t\t\treturn unmarshalUTF8StringValue\n\t\t}\n\t\tif pointer {\n\t\t\treturn unmarshalStringPtr\n\t\t}\n\t\tif slice {\n\t\t\treturn unmarshalStringSlice\n\t\t}\n\t\treturn unmarshalStringValue\n\tcase reflect.Struct:\n\t\t// message or group field\n\t\tif !pointer {\n\t\t\tswitch encoding {\n\t\t\tcase \"bytes\":\n\t\t\t\tif slice {\n\t\t\t\t\treturn makeUnmarshalMessageSlice(getUnmarshalInfo(t), name)\n\t\t\t\t}\n\t\t\t\treturn makeUnmarshalMessage(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t}\n\t\tswitch encoding {\n\t\tcase \"bytes\":\n\t\t\tif slice {\n\t\t\t\treturn makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeUnmarshalMessagePtr(getUnmarshalInfo(t), name)\n\t\tcase \"group\":\n\t\t\tif slice {\n\t\t\t\treturn makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name)\n\t\t\t}\n\t\t\treturn makeUnmarshalGroupPtr(getUnmarshalInfo(t), name)\n\t\t}\n\t}\n\tpanic(fmt.Sprintf(\"unmarshaler not found type:%s encoding:%s\", t, encoding))\n}\n\n// Below are all the unmarshalers for individual fields of various types.\n\nfunc unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int64(x)\n\t*f.toInt64() = v\n\treturn b, nil\n}\n\nfunc unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int64(x)\n\t*f.toInt64Ptr() = &v\n\treturn b, nil\n}\n\nfunc unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tv := int64(x)\n\t\t\ts := f.toInt64Slice()\n\t\t\t*s = append(*s, v)\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int64(x)\n\ts := f.toInt64Slice()\n\t*s = append(*s, v)\n\treturn b, nil\n}\n\nfunc unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int64(x>>1) ^ int64(x)<<63>>63\n\t*f.toInt64() = v\n\treturn b, nil\n}\n\nfunc unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int64(x>>1) ^ int64(x)<<63>>63\n\t*f.toInt64Ptr() = &v\n\treturn b, nil\n}\n\nfunc unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tv := int64(x>>1) ^ int64(x)<<63>>63\n\t\t\ts := f.toInt64Slice()\n\t\t\t*s = append(*s, v)\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int64(x>>1) ^ int64(x)<<63>>63\n\ts := f.toInt64Slice()\n\t*s = append(*s, v)\n\treturn b, nil\n}\n\nfunc unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := uint64(x)\n\t*f.toUint64() = v\n\treturn b, nil\n}\n\nfunc unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := uint64(x)\n\t*f.toUint64Ptr() = &v\n\treturn b, nil\n}\n\nfunc unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tv := uint64(x)\n\t\t\ts := f.toUint64Slice()\n\t\t\t*s = append(*s, v)\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := uint64(x)\n\ts := f.toUint64Slice()\n\t*s = append(*s, v)\n\treturn b, nil\n}\n\nfunc unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int32(x)\n\t*f.toInt32() = v\n\treturn b, nil\n}\n\nfunc unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int32(x)\n\tf.setInt32Ptr(v)\n\treturn b, nil\n}\n\nfunc unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tv := int32(x)\n\t\t\tf.appendInt32Slice(v)\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int32(x)\n\tf.appendInt32Slice(v)\n\treturn b, nil\n}\n\nfunc unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int32(x>>1) ^ int32(x)<<31>>31\n\t*f.toInt32() = v\n\treturn b, nil\n}\n\nfunc unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int32(x>>1) ^ int32(x)<<31>>31\n\tf.setInt32Ptr(v)\n\treturn b, nil\n}\n\nfunc unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tv := int32(x>>1) ^ int32(x)<<31>>31\n\t\t\tf.appendInt32Slice(v)\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := int32(x>>1) ^ int32(x)<<31>>31\n\tf.appendInt32Slice(v)\n\treturn b, nil\n}\n\nfunc unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := uint32(x)\n\t*f.toUint32() = v\n\treturn b, nil\n}\n\nfunc unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := uint32(x)\n\t*f.toUint32Ptr() = &v\n\treturn b, nil\n}\n\nfunc unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tv := uint32(x)\n\t\t\ts := f.toUint32Slice()\n\t\t\t*s = append(*s, v)\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tv := uint32(x)\n\ts := f.toUint32Slice()\n\t*s = append(*s, v)\n\treturn b, nil\n}\n\nfunc unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n\t*f.toUint64() = v\n\treturn b[8:], nil\n}\n\nfunc unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n\t*f.toUint64Ptr() = &v\n\treturn b[8:], nil\n}\n\nfunc unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tif len(b) < 8 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tv := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n\t\t\ts := f.toUint64Slice()\n\t\t\t*s = append(*s, v)\n\t\t\tb = b[8:]\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n\ts := f.toUint64Slice()\n\t*s = append(*s, v)\n\treturn b[8:], nil\n}\n\nfunc unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56\n\t*f.toInt64() = v\n\treturn b[8:], nil\n}\n\nfunc unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56\n\t*f.toInt64Ptr() = &v\n\treturn b[8:], nil\n}\n\nfunc unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tif len(b) < 8 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tv := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56\n\t\t\ts := f.toInt64Slice()\n\t\t\t*s = append(*s, v)\n\t\t\tb = b[8:]\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56\n\ts := f.toInt64Slice()\n\t*s = append(*s, v)\n\treturn b[8:], nil\n}\n\nfunc unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n\t*f.toUint32() = v\n\treturn b[4:], nil\n}\n\nfunc unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n\t*f.toUint32Ptr() = &v\n\treturn b[4:], nil\n}\n\nfunc unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tif len(b) < 4 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tv := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n\t\t\ts := f.toUint32Slice()\n\t\t\t*s = append(*s, v)\n\t\t\tb = b[4:]\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n\ts := f.toUint32Slice()\n\t*s = append(*s, v)\n\treturn b[4:], nil\n}\n\nfunc unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24\n\t*f.toInt32() = v\n\treturn b[4:], nil\n}\n\nfunc unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24\n\tf.setInt32Ptr(v)\n\treturn b[4:], nil\n}\n\nfunc unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tif len(b) < 4 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tv := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24\n\t\t\tf.appendInt32Slice(v)\n\t\t\tb = b[4:]\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24\n\tf.appendInt32Slice(v)\n\treturn b[4:], nil\n}\n\nfunc unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\t// Note: any length varint is allowed, even though any sane\n\t// encoder will use one byte.\n\t// See https://github.com/golang/protobuf/issues/76\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\t// TODO: check if x>1? Tests seem to indicate no.\n\tv := x != 0\n\t*f.toBool() = v\n\treturn b[n:], nil\n}\n\nfunc unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := x != 0\n\t*f.toBoolPtr() = &v\n\treturn b[n:], nil\n}\n\nfunc unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tx, n = decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tv := x != 0\n\t\t\ts := f.toBoolSlice()\n\t\t\t*s = append(*s, v)\n\t\t\tb = b[n:]\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireVarint {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := x != 0\n\ts := f.toBoolSlice()\n\t*s = append(*s, v)\n\treturn b[n:], nil\n}\n\nfunc unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)\n\t*f.toFloat64() = v\n\treturn b[8:], nil\n}\n\nfunc unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)\n\t*f.toFloat64Ptr() = &v\n\treturn b[8:], nil\n}\n\nfunc unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tif len(b) < 8 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tv := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)\n\t\t\ts := f.toFloat64Slice()\n\t\t\t*s = append(*s, v)\n\t\t\tb = b[8:]\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireFixed64 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 8 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)\n\ts := f.toFloat64Slice()\n\t*s = append(*s, v)\n\treturn b[8:], nil\n}\n\nfunc unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)\n\t*f.toFloat32() = v\n\treturn b[4:], nil\n}\n\nfunc unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)\n\t*f.toFloat32Ptr() = &v\n\treturn b[4:], nil\n}\n\nfunc unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w == WireBytes { // packed\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tres := b[x:]\n\t\tb = b[:x]\n\t\tfor len(b) > 0 {\n\t\t\tif len(b) < 4 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tv := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)\n\t\t\ts := f.toFloat32Slice()\n\t\t\t*s = append(*s, v)\n\t\t\tb = b[4:]\n\t\t}\n\t\treturn res, nil\n\t}\n\tif w != WireFixed32 {\n\t\treturn b, errInternalBadWireType\n\t}\n\tif len(b) < 4 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)\n\ts := f.toFloat32Slice()\n\t*s = append(*s, v)\n\treturn b[4:], nil\n}\n\nfunc unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := string(b[:x])\n\t*f.toString() = v\n\treturn b[x:], nil\n}\n\nfunc unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := string(b[:x])\n\t*f.toStringPtr() = &v\n\treturn b[x:], nil\n}\n\nfunc unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := string(b[:x])\n\ts := f.toStringSlice()\n\t*s = append(*s, v)\n\treturn b[x:], nil\n}\n\nfunc unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := string(b[:x])\n\t*f.toString() = v\n\tif !utf8.ValidString(v) {\n\t\treturn b[x:], errInvalidUTF8\n\t}\n\treturn b[x:], nil\n}\n\nfunc unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := string(b[:x])\n\t*f.toStringPtr() = &v\n\tif !utf8.ValidString(v) {\n\t\treturn b[x:], errInvalidUTF8\n\t}\n\treturn b[x:], nil\n}\n\nfunc unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := string(b[:x])\n\ts := f.toStringSlice()\n\t*s = append(*s, v)\n\tif !utf8.ValidString(v) {\n\t\treturn b[x:], errInvalidUTF8\n\t}\n\treturn b[x:], nil\n}\n\nvar emptyBuf [0]byte\n\nfunc unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\t// The use of append here is a trick which avoids the zeroing\n\t// that would be required if we used a make/copy pair.\n\t// We append to emptyBuf instead of nil because we want\n\t// a non-nil result even when the length is 0.\n\tv := append(emptyBuf[:], b[:x]...)\n\t*f.toBytes() = v\n\treturn b[x:], nil\n}\n\nfunc unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) {\n\tif w != WireBytes {\n\t\treturn b, errInternalBadWireType\n\t}\n\tx, n := decodeVarint(b)\n\tif n == 0 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tb = b[n:]\n\tif x > uint64(len(b)) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tv := append(emptyBuf[:], b[:x]...)\n\ts := f.toBytesSlice()\n\t*s = append(*s, v)\n\treturn b[x:], nil\n}\n\nfunc makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn b, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\t// First read the message field to see if something is there.\n\t\t// The semantics of multiple submessages are weird.  Instead of\n\t\t// the last one winning (as it is for all other fields), multiple\n\t\t// submessages are merged.\n\t\tv := f.getPointer()\n\t\tif v.isNil() {\n\t\t\tv = valToPointer(reflect.New(sub.typ))\n\t\t\tf.setPointer(v)\n\t\t}\n\t\terr := sub.unmarshal(v, b[:x])\n\t\tif err != nil {\n\t\t\tif r, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\tr.field = name + \".\" + r.field\n\t\t\t} else {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn b[x:], err\n\t}\n}\n\nfunc makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn b, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tv := valToPointer(reflect.New(sub.typ))\n\t\terr := sub.unmarshal(v, b[:x])\n\t\tif err != nil {\n\t\t\tif r, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\tr.field = name + \".\" + r.field\n\t\t\t} else {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tf.appendPointer(v)\n\t\treturn b[x:], err\n\t}\n}\n\nfunc makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireStartGroup {\n\t\t\treturn b, errInternalBadWireType\n\t\t}\n\t\tx, y := findEndGroup(b)\n\t\tif x < 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tv := f.getPointer()\n\t\tif v.isNil() {\n\t\t\tv = valToPointer(reflect.New(sub.typ))\n\t\t\tf.setPointer(v)\n\t\t}\n\t\terr := sub.unmarshal(v, b[:x])\n\t\tif err != nil {\n\t\t\tif r, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\tr.field = name + \".\" + r.field\n\t\t\t} else {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn b[y:], err\n\t}\n}\n\nfunc makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireStartGroup {\n\t\t\treturn b, errInternalBadWireType\n\t\t}\n\t\tx, y := findEndGroup(b)\n\t\tif x < 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tv := valToPointer(reflect.New(sub.typ))\n\t\terr := sub.unmarshal(v, b[:x])\n\t\tif err != nil {\n\t\t\tif r, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\tr.field = name + \".\" + r.field\n\t\t\t} else {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tf.appendPointer(v)\n\t\treturn b[y:], err\n\t}\n}\n\nfunc makeUnmarshalMap(f *reflect.StructField) unmarshaler {\n\tt := f.Type\n\tkt := t.Key()\n\tvt := t.Elem()\n\ttagArray := strings.Split(f.Tag.Get(\"protobuf\"), \",\")\n\tvalTags := strings.Split(f.Tag.Get(\"protobuf_val\"), \",\")\n\tfor _, t := range tagArray {\n\t\tif strings.HasPrefix(t, \"customtype=\") {\n\t\t\tvalTags = append(valTags, t)\n\t\t}\n\t\tif t == \"stdtime\" {\n\t\t\tvalTags = append(valTags, t)\n\t\t}\n\t\tif t == \"stdduration\" {\n\t\t\tvalTags = append(valTags, t)\n\t\t}\n\t\tif t == \"wktptr\" {\n\t\t\tvalTags = append(valTags, t)\n\t\t}\n\t}\n\tunmarshalKey := typeUnmarshaler(kt, f.Tag.Get(\"protobuf_key\"))\n\tunmarshalVal := typeUnmarshaler(vt, strings.Join(valTags, \",\"))\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\t// The map entry is a submessage. Figure out how big it is.\n\t\tif w != WireBytes {\n\t\t\treturn nil, fmt.Errorf(\"proto: bad wiretype for map field: got %d want %d\", w, WireBytes)\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tr := b[x:] // unused data to return\n\t\tb = b[:x]  // data for map entry\n\n\t\t// Note: we could use #keys * #values ~= 200 functions\n\t\t// to do map decoding without reflection. Probably not worth it.\n\t\t// Maps will be somewhat slow. Oh well.\n\n\t\t// Read key and value from data.\n\t\tvar nerr nonFatal\n\t\tk := reflect.New(kt)\n\t\tv := reflect.New(vt)\n\t\tfor len(b) > 0 {\n\t\t\tx, n := decodeVarint(b)\n\t\t\tif n == 0 {\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\twire := int(x) & 7\n\t\t\tb = b[n:]\n\n\t\t\tvar err error\n\t\t\tswitch x >> 3 {\n\t\t\tcase 1:\n\t\t\t\tb, err = unmarshalKey(b, valToPointer(k), wire)\n\t\t\tcase 2:\n\t\t\t\tb, err = unmarshalVal(b, valToPointer(v), wire)\n\t\t\tdefault:\n\t\t\t\terr = errInternalBadWireType // skip unknown tag\n\t\t\t}\n\n\t\t\tif nerr.Merge(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif err != errInternalBadWireType {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Skip past unknown fields.\n\t\t\tb, err = skipField(b, wire)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\t// Get map, allocate if needed.\n\t\tm := f.asPointerTo(t).Elem() // an addressable map[K]T\n\t\tif m.IsNil() {\n\t\t\tm.Set(reflect.MakeMap(t))\n\t\t}\n\n\t\t// Insert into map.\n\t\tm.SetMapIndex(k.Elem(), v.Elem())\n\n\t\treturn r, nerr.E\n\t}\n}\n\n// makeUnmarshalOneof makes an unmarshaler for oneof fields.\n// for:\n// message Msg {\n//   oneof F {\n//     int64 X = 1;\n//     float64 Y = 2;\n//   }\n// }\n// typ is the type of the concrete entry for a oneof case (e.g. Msg_X).\n// ityp is the interface type of the oneof field (e.g. isMsg_F).\n// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64).\n// Note that this function will be called once for each case in the oneof.\nfunc makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler {\n\tsf := typ.Field(0)\n\tfield0 := toField(&sf)\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\t// Allocate holder for value.\n\t\tv := reflect.New(typ)\n\n\t\t// Unmarshal data into holder.\n\t\t// We unmarshal into the first field of the holder object.\n\t\tvar err error\n\t\tvar nerr nonFatal\n\t\tb, err = unmarshal(b, valToPointer(v).offset(field0), w)\n\t\tif !nerr.Merge(err) {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// Write pointer to holder into target field.\n\t\tf.asPointerTo(ityp).Elem().Set(v)\n\n\t\treturn b, nerr.E\n\t}\n}\n\n// Error used by decode internally.\nvar errInternalBadWireType = errors.New(\"proto: internal error: bad wiretype\")\n\n// skipField skips past a field of type wire and returns the remaining bytes.\nfunc skipField(b []byte, wire int) ([]byte, error) {\n\tswitch wire {\n\tcase WireVarint:\n\t\t_, k := decodeVarint(b)\n\t\tif k == 0 {\n\t\t\treturn b, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[k:]\n\tcase WireFixed32:\n\t\tif len(b) < 4 {\n\t\t\treturn b, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[4:]\n\tcase WireFixed64:\n\t\tif len(b) < 8 {\n\t\t\treturn b, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[8:]\n\tcase WireBytes:\n\t\tm, k := decodeVarint(b)\n\t\tif k == 0 || uint64(len(b)-k) < m {\n\t\t\treturn b, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[uint64(k)+m:]\n\tcase WireStartGroup:\n\t\t_, i := findEndGroup(b)\n\t\tif i == -1 {\n\t\t\treturn b, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[i:]\n\tdefault:\n\t\treturn b, fmt.Errorf(\"proto: can't skip unknown wire type %d\", wire)\n\t}\n\treturn b, nil\n}\n\n// findEndGroup finds the index of the next EndGroup tag.\n// Groups may be nested, so the \"next\" EndGroup tag is the first\n// unpaired EndGroup.\n// findEndGroup returns the indexes of the start and end of the EndGroup tag.\n// Returns (-1,-1) if it can't find one.\nfunc findEndGroup(b []byte) (int, int) {\n\tdepth := 1\n\ti := 0\n\tfor {\n\t\tx, n := decodeVarint(b[i:])\n\t\tif n == 0 {\n\t\t\treturn -1, -1\n\t\t}\n\t\tj := i\n\t\ti += n\n\t\tswitch x & 7 {\n\t\tcase WireVarint:\n\t\t\t_, k := decodeVarint(b[i:])\n\t\t\tif k == 0 {\n\t\t\t\treturn -1, -1\n\t\t\t}\n\t\t\ti += k\n\t\tcase WireFixed32:\n\t\t\tif len(b)-4 < i {\n\t\t\t\treturn -1, -1\n\t\t\t}\n\t\t\ti += 4\n\t\tcase WireFixed64:\n\t\t\tif len(b)-8 < i {\n\t\t\t\treturn -1, -1\n\t\t\t}\n\t\t\ti += 8\n\t\tcase WireBytes:\n\t\t\tm, k := decodeVarint(b[i:])\n\t\t\tif k == 0 {\n\t\t\t\treturn -1, -1\n\t\t\t}\n\t\t\ti += k\n\t\t\tif uint64(len(b)-i) < m {\n\t\t\t\treturn -1, -1\n\t\t\t}\n\t\t\ti += int(m)\n\t\tcase WireStartGroup:\n\t\t\tdepth++\n\t\tcase WireEndGroup:\n\t\t\tdepth--\n\t\t\tif depth == 0 {\n\t\t\t\treturn j, i\n\t\t\t}\n\t\tdefault:\n\t\t\treturn -1, -1\n\t\t}\n\t}\n}\n\n// encodeVarint appends a varint-encoded integer to b and returns the result.\nfunc encodeVarint(b []byte, x uint64) []byte {\n\tfor x >= 1<<7 {\n\t\tb = append(b, byte(x&0x7f|0x80))\n\t\tx >>= 7\n\t}\n\treturn append(b, byte(x))\n}\n\n// decodeVarint reads a varint-encoded integer from b.\n// Returns the decoded integer and the number of bytes read.\n// If there is an error, it returns 0,0.\nfunc decodeVarint(b []byte) (uint64, int) {\n\tvar x, y uint64\n\tif len(b) == 0 {\n\t\tgoto bad\n\t}\n\tx = uint64(b[0])\n\tif x < 0x80 {\n\t\treturn x, 1\n\t}\n\tx -= 0x80\n\n\tif len(b) <= 1 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[1])\n\tx += y << 7\n\tif y < 0x80 {\n\t\treturn x, 2\n\t}\n\tx -= 0x80 << 7\n\n\tif len(b) <= 2 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[2])\n\tx += y << 14\n\tif y < 0x80 {\n\t\treturn x, 3\n\t}\n\tx -= 0x80 << 14\n\n\tif len(b) <= 3 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[3])\n\tx += y << 21\n\tif y < 0x80 {\n\t\treturn x, 4\n\t}\n\tx -= 0x80 << 21\n\n\tif len(b) <= 4 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[4])\n\tx += y << 28\n\tif y < 0x80 {\n\t\treturn x, 5\n\t}\n\tx -= 0x80 << 28\n\n\tif len(b) <= 5 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[5])\n\tx += y << 35\n\tif y < 0x80 {\n\t\treturn x, 6\n\t}\n\tx -= 0x80 << 35\n\n\tif len(b) <= 6 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[6])\n\tx += y << 42\n\tif y < 0x80 {\n\t\treturn x, 7\n\t}\n\tx -= 0x80 << 42\n\n\tif len(b) <= 7 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[7])\n\tx += y << 49\n\tif y < 0x80 {\n\t\treturn x, 8\n\t}\n\tx -= 0x80 << 49\n\n\tif len(b) <= 8 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[8])\n\tx += y << 56\n\tif y < 0x80 {\n\t\treturn x, 9\n\t}\n\tx -= 0x80 << 56\n\n\tif len(b) <= 9 {\n\t\tgoto bad\n\t}\n\ty = uint64(b[9])\n\tx += y << 63\n\tif y < 2 {\n\t\treturn x, 10\n\t}\n\nbad:\n\treturn 0, 0\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"io\"\n\t\"reflect\"\n)\n\nfunc makeUnmarshalMessage(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\t// First read the message field to see if something is there.\n\t\t// The semantics of multiple submessages are weird.  Instead of\n\t\t// the last one winning (as it is for all other fields), multiple\n\t\t// submessages are merged.\n\t\tv := f // gogo: changed from v := f.getPointer()\n\t\tif v.isNil() {\n\t\t\tv = valToPointer(reflect.New(sub.typ))\n\t\t\tf.setPointer(v)\n\t\t}\n\t\terr := sub.unmarshal(v, b[:x])\n\t\tif err != nil {\n\t\t\tif r, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\tr.field = name + \".\" + r.field\n\t\t\t} else {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn b[x:], err\n\t}\n}\n\nfunc makeUnmarshalMessageSlice(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tv := valToPointer(reflect.New(sub.typ))\n\t\terr := sub.unmarshal(v, b[:x])\n\t\tif err != nil {\n\t\t\tif r, ok := err.(*RequiredNotSetError); ok {\n\t\t\t\tr.field = name + \".\" + r.field\n\t\t\t} else {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\tf.appendRef(v, sub.typ) // gogo: changed from f.appendPointer(v)\n\t\treturn b[x:], err\n\t}\n}\n\nfunc makeUnmarshalCustomPtr(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.New(sub.typ))\n\t\tm := s.Interface().(custom)\n\t\tif err := m.Unmarshal(b[:x]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalCustomSlice(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := reflect.New(sub.typ)\n\t\tc := m.Interface().(custom)\n\t\tif err := c.Unmarshal(b[:x]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tv := valToPointer(m)\n\t\tf.appendRef(v, sub.typ)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalCustom(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\n\t\tm := f.asPointerTo(sub.typ).Interface().(custom)\n\t\tif err := m.Unmarshal(b[:x]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalTime(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &timestamp{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tt, err := timestampFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(t))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalTimePtr(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &timestamp{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tt, err := timestampFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&t))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalTimePtrSlice(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &timestamp{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tt, err := timestampFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&t))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalTimeSlice(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &timestamp{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tt, err := timestampFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(t))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalDurationPtr(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &duration{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td, err := durationFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&d))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalDuration(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &duration{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td, err := durationFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(d))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalDurationPtrSlice(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &duration{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td, err := durationFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&d))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeUnmarshalDurationSlice(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &duration{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td, err := durationFromProto(m)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(d))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/text.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n// Functions for writing the text protocol buffer format.\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"math\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\nvar (\n\tnewline         = []byte(\"\\n\")\n\tspaces          = []byte(\"                                        \")\n\tendBraceNewline = []byte(\"}\\n\")\n\tbackslashN      = []byte{'\\\\', 'n'}\n\tbackslashR      = []byte{'\\\\', 'r'}\n\tbackslashT      = []byte{'\\\\', 't'}\n\tbackslashDQ     = []byte{'\\\\', '\"'}\n\tbackslashBS     = []byte{'\\\\', '\\\\'}\n\tposInf          = []byte(\"inf\")\n\tnegInf          = []byte(\"-inf\")\n\tnan             = []byte(\"nan\")\n)\n\ntype writer interface {\n\tio.Writer\n\tWriteByte(byte) error\n}\n\n// textWriter is an io.Writer that tracks its indentation level.\ntype textWriter struct {\n\tind      int\n\tcomplete bool // if the current position is a complete line\n\tcompact  bool // whether to write out as a one-liner\n\tw        writer\n}\n\nfunc (w *textWriter) WriteString(s string) (n int, err error) {\n\tif !strings.Contains(s, \"\\n\") {\n\t\tif !w.compact && w.complete {\n\t\t\tw.writeIndent()\n\t\t}\n\t\tw.complete = false\n\t\treturn io.WriteString(w.w, s)\n\t}\n\t// WriteString is typically called without newlines, so this\n\t// codepath and its copy are rare.  We copy to avoid\n\t// duplicating all of Write's logic here.\n\treturn w.Write([]byte(s))\n}\n\nfunc (w *textWriter) Write(p []byte) (n int, err error) {\n\tnewlines := bytes.Count(p, newline)\n\tif newlines == 0 {\n\t\tif !w.compact && w.complete {\n\t\t\tw.writeIndent()\n\t\t}\n\t\tn, err = w.w.Write(p)\n\t\tw.complete = false\n\t\treturn n, err\n\t}\n\n\tfrags := bytes.SplitN(p, newline, newlines+1)\n\tif w.compact {\n\t\tfor i, frag := range frags {\n\t\t\tif i > 0 {\n\t\t\t\tif err := w.w.WriteByte(' '); err != nil {\n\t\t\t\t\treturn n, err\n\t\t\t\t}\n\t\t\t\tn++\n\t\t\t}\n\t\t\tnn, err := w.w.Write(frag)\n\t\t\tn += nn\n\t\t\tif err != nil {\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t\treturn n, nil\n\t}\n\n\tfor i, frag := range frags {\n\t\tif w.complete {\n\t\t\tw.writeIndent()\n\t\t}\n\t\tnn, err := w.w.Write(frag)\n\t\tn += nn\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tif i+1 < len(frags) {\n\t\t\tif err := w.w.WriteByte('\\n'); err != nil {\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t\tn++\n\t\t}\n\t}\n\tw.complete = len(frags[len(frags)-1]) == 0\n\treturn n, nil\n}\n\nfunc (w *textWriter) WriteByte(c byte) error {\n\tif w.compact && c == '\\n' {\n\t\tc = ' '\n\t}\n\tif !w.compact && w.complete {\n\t\tw.writeIndent()\n\t}\n\terr := w.w.WriteByte(c)\n\tw.complete = c == '\\n'\n\treturn err\n}\n\nfunc (w *textWriter) indent() { w.ind++ }\n\nfunc (w *textWriter) unindent() {\n\tif w.ind == 0 {\n\t\tlog.Print(\"proto: textWriter unindented too far\")\n\t\treturn\n\t}\n\tw.ind--\n}\n\nfunc writeName(w *textWriter, props *Properties) error {\n\tif _, err := w.WriteString(props.OrigName); err != nil {\n\t\treturn err\n\t}\n\tif props.Wire != \"group\" {\n\t\treturn w.WriteByte(':')\n\t}\n\treturn nil\n}\n\nfunc requiresQuotes(u string) bool {\n\t// When type URL contains any characters except [0-9A-Za-z./\\-]*, it must be quoted.\n\tfor _, ch := range u {\n\t\tswitch {\n\t\tcase ch == '.' || ch == '/' || ch == '_':\n\t\t\tcontinue\n\t\tcase '0' <= ch && ch <= '9':\n\t\t\tcontinue\n\t\tcase 'A' <= ch && ch <= 'Z':\n\t\t\tcontinue\n\t\tcase 'a' <= ch && ch <= 'z':\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// isAny reports whether sv is a google.protobuf.Any message\nfunc isAny(sv reflect.Value) bool {\n\ttype wkt interface {\n\t\tXXX_WellKnownType() string\n\t}\n\tt, ok := sv.Addr().Interface().(wkt)\n\treturn ok && t.XXX_WellKnownType() == \"Any\"\n}\n\n// writeProto3Any writes an expanded google.protobuf.Any message.\n//\n// It returns (false, nil) if sv value can't be unmarshaled (e.g. because\n// required messages are not linked in).\n//\n// It returns (true, error) when sv was written in expanded format or an error\n// was encountered.\nfunc (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) {\n\tturl := sv.FieldByName(\"TypeUrl\")\n\tval := sv.FieldByName(\"Value\")\n\tif !turl.IsValid() || !val.IsValid() {\n\t\treturn true, errors.New(\"proto: invalid google.protobuf.Any message\")\n\t}\n\n\tb, ok := val.Interface().([]byte)\n\tif !ok {\n\t\treturn true, errors.New(\"proto: invalid google.protobuf.Any message\")\n\t}\n\n\tparts := strings.Split(turl.String(), \"/\")\n\tmt := MessageType(parts[len(parts)-1])\n\tif mt == nil {\n\t\treturn false, nil\n\t}\n\tm := reflect.New(mt.Elem())\n\tif err := Unmarshal(b, m.Interface().(Message)); err != nil {\n\t\treturn false, nil\n\t}\n\tw.Write([]byte(\"[\"))\n\tu := turl.String()\n\tif requiresQuotes(u) {\n\t\twriteString(w, u)\n\t} else {\n\t\tw.Write([]byte(u))\n\t}\n\tif w.compact {\n\t\tw.Write([]byte(\"]:<\"))\n\t} else {\n\t\tw.Write([]byte(\"]: <\\n\"))\n\t\tw.ind++\n\t}\n\tif err := tm.writeStruct(w, m.Elem()); err != nil {\n\t\treturn true, err\n\t}\n\tif w.compact {\n\t\tw.Write([]byte(\"> \"))\n\t} else {\n\t\tw.ind--\n\t\tw.Write([]byte(\">\\n\"))\n\t}\n\treturn true, nil\n}\n\nfunc (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {\n\tif tm.ExpandAny && isAny(sv) {\n\t\tif canExpand, err := tm.writeProto3Any(w, sv); canExpand {\n\t\t\treturn err\n\t\t}\n\t}\n\tst := sv.Type()\n\tsprops := GetProperties(st)\n\tfor i := 0; i < sv.NumField(); i++ {\n\t\tfv := sv.Field(i)\n\t\tprops := sprops.Prop[i]\n\t\tname := st.Field(i).Name\n\n\t\tif name == \"XXX_NoUnkeyedLiteral\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tif strings.HasPrefix(name, \"XXX_\") {\n\t\t\t// There are two XXX_ fields:\n\t\t\t//   XXX_unrecognized []byte\n\t\t\t//   XXX_extensions   map[int32]proto.Extension\n\t\t\t// The first is handled here;\n\t\t\t// the second is handled at the bottom of this function.\n\t\t\tif name == \"XXX_unrecognized\" && !fv.IsNil() {\n\t\t\t\tif err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif fv.Kind() == reflect.Ptr && fv.IsNil() {\n\t\t\t// Field not filled in. This could be an optional field or\n\t\t\t// a required field that wasn't filled in. Either way, there\n\t\t\t// isn't anything we can show for it.\n\t\t\tcontinue\n\t\t}\n\t\tif fv.Kind() == reflect.Slice && fv.IsNil() {\n\t\t\t// Repeated field that is empty, or a bytes field that is unused.\n\t\t\tcontinue\n\t\t}\n\n\t\tif props.Repeated && fv.Kind() == reflect.Slice {\n\t\t\t// Repeated field.\n\t\t\tfor j := 0; j < fv.Len(); j++ {\n\t\t\t\tif err := writeName(w, props); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif !w.compact {\n\t\t\t\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tv := fv.Index(j)\n\t\t\t\tif v.Kind() == reflect.Ptr && v.IsNil() {\n\t\t\t\t\t// A nil message in a repeated field is not valid,\n\t\t\t\t\t// but we can handle that more gracefully than panicking.\n\t\t\t\t\tif _, err := w.Write([]byte(\"<nil>\\n\")); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif len(props.Enum) > 0 {\n\t\t\t\t\tif err := tm.writeEnum(w, v, props); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t} else if err := tm.writeAny(w, v, props); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif fv.Kind() == reflect.Map {\n\t\t\t// Map fields are rendered as a repeated struct with key/value fields.\n\t\t\tkeys := fv.MapKeys()\n\t\t\tsort.Sort(mapKeys(keys))\n\t\t\tfor _, key := range keys {\n\t\t\t\tval := fv.MapIndex(key)\n\t\t\t\tif err := writeName(w, props); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif !w.compact {\n\t\t\t\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// open struct\n\t\t\t\tif err := w.WriteByte('<'); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif !w.compact {\n\t\t\t\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tw.indent()\n\t\t\t\t// key\n\t\t\t\tif _, err := w.WriteString(\"key:\"); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif !w.compact {\n\t\t\t\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif err := tm.writeAny(w, key, props.MapKeyProp); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\t// nil values aren't legal, but we can avoid panicking because of them.\n\t\t\t\tif val.Kind() != reflect.Ptr || !val.IsNil() {\n\t\t\t\t\t// value\n\t\t\t\t\tif _, err := w.WriteString(\"value:\"); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif !w.compact {\n\t\t\t\t\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\t\t\t\t\treturn err\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif err := tm.writeAny(w, val, props.MapValProp); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// close struct\n\t\t\t\tw.unindent()\n\t\t\t\tif err := w.WriteByte('>'); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {\n\t\t\t// empty bytes field\n\t\t\tcontinue\n\t\t}\n\t\tif props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {\n\t\t\t// proto3 non-repeated scalar field; skip if zero value\n\t\t\tif isProto3Zero(fv) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif fv.Kind() == reflect.Interface {\n\t\t\t// Check if it is a oneof.\n\t\t\tif st.Field(i).Tag.Get(\"protobuf_oneof\") != \"\" {\n\t\t\t\t// fv is nil, or holds a pointer to generated struct.\n\t\t\t\t// That generated struct has exactly one field,\n\t\t\t\t// which has a protobuf struct tag.\n\t\t\t\tif fv.IsNil() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tinner := fv.Elem().Elem() // interface -> *T -> T\n\t\t\t\ttag := inner.Type().Field(0).Tag.Get(\"protobuf\")\n\t\t\t\tprops = new(Properties) // Overwrite the outer props var, but not its pointee.\n\t\t\t\tprops.Parse(tag)\n\t\t\t\t// Write the value in the oneof, not the oneof itself.\n\t\t\t\tfv = inner.Field(0)\n\n\t\t\t\t// Special case to cope with malformed messages gracefully:\n\t\t\t\t// If the value in the oneof is a nil pointer, don't panic\n\t\t\t\t// in writeAny.\n\t\t\t\tif fv.Kind() == reflect.Ptr && fv.IsNil() {\n\t\t\t\t\t// Use errors.New so writeAny won't render quotes.\n\t\t\t\t\tmsg := errors.New(\"/* nil */\")\n\t\t\t\t\tfv = reflect.ValueOf(&msg).Elem()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif err := writeName(w, props); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !w.compact {\n\t\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif len(props.Enum) > 0 {\n\t\t\tif err := tm.writeEnum(w, fv, props); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else if err := tm.writeAny(w, fv, props); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Extensions (the XXX_extensions field).\n\tpv := sv\n\tif pv.CanAddr() {\n\t\tpv = sv.Addr()\n\t} else {\n\t\tpv = reflect.New(sv.Type())\n\t\tpv.Elem().Set(sv)\n\t}\n\tif _, err := extendable(pv.Interface()); err == nil {\n\t\tif err := tm.writeExtensions(w, pv); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nvar textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()\n\n// writeAny writes an arbitrary field.\nfunc (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {\n\tv = reflect.Indirect(v)\n\n\tif props != nil {\n\t\tif len(props.CustomType) > 0 {\n\t\t\tcustom, ok := v.Interface().(Marshaler)\n\t\t\tif ok {\n\t\t\t\tdata, err := custom.Marshal()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := writeString(w, string(data)); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t} else if len(props.CastType) > 0 {\n\t\t\tif _, ok := v.Interface().(interface {\n\t\t\t\tString() string\n\t\t\t}); ok {\n\t\t\t\tswitch v.Kind() {\n\t\t\t\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n\t\t\t\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\t\t\t\t_, err := fmt.Fprintf(w, \"%d\", v.Interface())\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t} else if props.StdTime {\n\t\t\tt, ok := v.Interface().(time.Time)\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"stdtime is not time.Time, but %T\", v.Interface())\n\t\t\t}\n\t\t\ttproto, err := timestampProto(t)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tpropsCopy := *props // Make a copy so that this is goroutine-safe\n\t\t\tpropsCopy.StdTime = false\n\t\t\terr = tm.writeAny(w, reflect.ValueOf(tproto), &propsCopy)\n\t\t\treturn err\n\t\t} else if props.StdDuration {\n\t\t\td, ok := v.Interface().(time.Duration)\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"stdtime is not time.Duration, but %T\", v.Interface())\n\t\t\t}\n\t\t\tdproto := durationProto(d)\n\t\t\tpropsCopy := *props // Make a copy so that this is goroutine-safe\n\t\t\tpropsCopy.StdDuration = false\n\t\t\terr := tm.writeAny(w, reflect.ValueOf(dproto), &propsCopy)\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Floats have special cases.\n\tif v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {\n\t\tx := v.Float()\n\t\tvar b []byte\n\t\tswitch {\n\t\tcase math.IsInf(x, 1):\n\t\t\tb = posInf\n\t\tcase math.IsInf(x, -1):\n\t\t\tb = negInf\n\t\tcase math.IsNaN(x):\n\t\t\tb = nan\n\t\t}\n\t\tif b != nil {\n\t\t\t_, err := w.Write(b)\n\t\t\treturn err\n\t\t}\n\t\t// Other values are handled below.\n\t}\n\n\t// We don't attempt to serialise every possible value type; only those\n\t// that can occur in protocol buffers.\n\tswitch v.Kind() {\n\tcase reflect.Slice:\n\t\t// Should only be a []byte; repeated fields are handled in writeStruct.\n\t\tif err := writeString(w, string(v.Bytes())); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase reflect.String:\n\t\tif err := writeString(w, v.String()); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase reflect.Struct:\n\t\t// Required/optional group/message.\n\t\tvar bra, ket byte = '<', '>'\n\t\tif props != nil && props.Wire == \"group\" {\n\t\t\tbra, ket = '{', '}'\n\t\t}\n\t\tif err := w.WriteByte(bra); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !w.compact {\n\t\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tw.indent()\n\t\tif v.CanAddr() {\n\t\t\t// Calling v.Interface on a struct causes the reflect package to\n\t\t\t// copy the entire struct. This is racy with the new Marshaler\n\t\t\t// since we atomically update the XXX_sizecache.\n\t\t\t//\n\t\t\t// Thus, we retrieve a pointer to the struct if possible to avoid\n\t\t\t// a race since v.Interface on the pointer doesn't copy the struct.\n\t\t\t//\n\t\t\t// If v is not addressable, then we are not worried about a race\n\t\t\t// since it implies that the binary Marshaler cannot possibly be\n\t\t\t// mutating this value.\n\t\t\tv = v.Addr()\n\t\t}\n\t\tif v.Type().Implements(textMarshalerType) {\n\t\t\ttext, err := v.Interface().(encoding.TextMarshaler).MarshalText()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif _, err = w.Write(text); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tif v.Kind() == reflect.Ptr {\n\t\t\t\tv = v.Elem()\n\t\t\t}\n\t\t\tif err := tm.writeStruct(w, v); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tw.unindent()\n\t\tif err := w.WriteByte(ket); err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\t_, err := fmt.Fprint(w, v.Interface())\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// equivalent to C's isprint.\nfunc isprint(c byte) bool {\n\treturn c >= 0x20 && c < 0x7f\n}\n\n// writeString writes a string in the protocol buffer text format.\n// It is similar to strconv.Quote except we don't use Go escape sequences,\n// we treat the string as a byte sequence, and we use octal escapes.\n// These differences are to maintain interoperability with the other\n// languages' implementations of the text format.\nfunc writeString(w *textWriter, s string) error {\n\t// use WriteByte here to get any needed indent\n\tif err := w.WriteByte('\"'); err != nil {\n\t\treturn err\n\t}\n\t// Loop over the bytes, not the runes.\n\tfor i := 0; i < len(s); i++ {\n\t\tvar err error\n\t\t// Divergence from C++: we don't escape apostrophes.\n\t\t// There's no need to escape them, and the C++ parser\n\t\t// copes with a naked apostrophe.\n\t\tswitch c := s[i]; c {\n\t\tcase '\\n':\n\t\t\t_, err = w.w.Write(backslashN)\n\t\tcase '\\r':\n\t\t\t_, err = w.w.Write(backslashR)\n\t\tcase '\\t':\n\t\t\t_, err = w.w.Write(backslashT)\n\t\tcase '\"':\n\t\t\t_, err = w.w.Write(backslashDQ)\n\t\tcase '\\\\':\n\t\t\t_, err = w.w.Write(backslashBS)\n\t\tdefault:\n\t\t\tif isprint(c) {\n\t\t\t\terr = w.w.WriteByte(c)\n\t\t\t} else {\n\t\t\t\t_, err = fmt.Fprintf(w.w, \"\\\\%03o\", c)\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn w.WriteByte('\"')\n}\n\nfunc writeUnknownStruct(w *textWriter, data []byte) (err error) {\n\tif !w.compact {\n\t\tif _, err := fmt.Fprintf(w, \"/* %d unknown bytes */\\n\", len(data)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tb := NewBuffer(data)\n\tfor b.index < len(b.buf) {\n\t\tx, err := b.DecodeVarint()\n\t\tif err != nil {\n\t\t\t_, ferr := fmt.Fprintf(w, \"/* %v */\\n\", err)\n\t\t\treturn ferr\n\t\t}\n\t\twire, tag := x&7, x>>3\n\t\tif wire == WireEndGroup {\n\t\t\tw.unindent()\n\t\t\tif _, werr := w.Write(endBraceNewline); werr != nil {\n\t\t\t\treturn werr\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif _, ferr := fmt.Fprint(w, tag); ferr != nil {\n\t\t\treturn ferr\n\t\t}\n\t\tif wire != WireStartGroup {\n\t\t\tif err = w.WriteByte(':'); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif !w.compact || wire == WireStartGroup {\n\t\t\tif err = w.WriteByte(' '); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tswitch wire {\n\t\tcase WireBytes:\n\t\t\tbuf, e := b.DecodeRawBytes(false)\n\t\t\tif e == nil {\n\t\t\t\t_, err = fmt.Fprintf(w, \"%q\", buf)\n\t\t\t} else {\n\t\t\t\t_, err = fmt.Fprintf(w, \"/* %v */\", e)\n\t\t\t}\n\t\tcase WireFixed32:\n\t\t\tx, err = b.DecodeFixed32()\n\t\t\terr = writeUnknownInt(w, x, err)\n\t\tcase WireFixed64:\n\t\t\tx, err = b.DecodeFixed64()\n\t\t\terr = writeUnknownInt(w, x, err)\n\t\tcase WireStartGroup:\n\t\t\terr = w.WriteByte('{')\n\t\t\tw.indent()\n\t\tcase WireVarint:\n\t\t\tx, err = b.DecodeVarint()\n\t\t\terr = writeUnknownInt(w, x, err)\n\t\tdefault:\n\t\t\t_, err = fmt.Fprintf(w, \"/* unknown wire type %d */\", wire)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc writeUnknownInt(w *textWriter, x uint64, err error) error {\n\tif err == nil {\n\t\t_, err = fmt.Fprint(w, x)\n\t} else {\n\t\t_, err = fmt.Fprintf(w, \"/* %v */\", err)\n\t}\n\treturn err\n}\n\ntype int32Slice []int32\n\nfunc (s int32Slice) Len() int           { return len(s) }\nfunc (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }\nfunc (s int32Slice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }\n\n// writeExtensions writes all the extensions in pv.\n// pv is assumed to be a pointer to a protocol message struct that is extendable.\nfunc (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error {\n\temap := extensionMaps[pv.Type().Elem()]\n\te := pv.Interface().(Message)\n\n\tvar m map[int32]Extension\n\tvar mu sync.Locker\n\tif em, ok := e.(extensionsBytes); ok {\n\t\teb := em.GetExtensions()\n\t\tvar err error\n\t\tm, err = BytesToExtensionsMap(*eb)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tmu = notLocker{}\n\t} else if _, ok := e.(extendableProto); ok {\n\t\tep, _ := extendable(e)\n\t\tm, mu = ep.extensionsRead()\n\t\tif m == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// Order the extensions by ID.\n\t// This isn't strictly necessary, but it will give us\n\t// canonical output, which will also make testing easier.\n\n\tmu.Lock()\n\tids := make([]int32, 0, len(m))\n\tfor id := range m {\n\t\tids = append(ids, id)\n\t}\n\tsort.Sort(int32Slice(ids))\n\tmu.Unlock()\n\n\tfor _, extNum := range ids {\n\t\text := m[extNum]\n\t\tvar desc *ExtensionDesc\n\t\tif emap != nil {\n\t\t\tdesc = emap[extNum]\n\t\t}\n\t\tif desc == nil {\n\t\t\t// Unknown extension.\n\t\t\tif err := writeUnknownStruct(w, ext.enc); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tpb, err := GetExtension(e, desc)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed getting extension: %v\", err)\n\t\t}\n\n\t\t// Repeated extensions will appear as a slice.\n\t\tif !desc.repeated() {\n\t\t\tif err := tm.writeExtension(w, desc.Name, pb); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tv := reflect.ValueOf(pb)\n\t\t\tfor i := 0; i < v.Len(); i++ {\n\t\t\t\tif err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error {\n\tif _, err := fmt.Fprintf(w, \"[%s]:\", name); err != nil {\n\t\treturn err\n\t}\n\tif !w.compact {\n\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte('\\n'); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (w *textWriter) writeIndent() {\n\tif !w.complete {\n\t\treturn\n\t}\n\tremain := w.ind * 2\n\tfor remain > 0 {\n\t\tn := remain\n\t\tif n > len(spaces) {\n\t\t\tn = len(spaces)\n\t\t}\n\t\tw.w.Write(spaces[:n])\n\t\tremain -= n\n\t}\n\tw.complete = false\n}\n\n// TextMarshaler is a configurable text format marshaler.\ntype TextMarshaler struct {\n\tCompact   bool // use compact text format (one line).\n\tExpandAny bool // expand google.protobuf.Any messages of known types\n}\n\n// Marshal writes a given protocol buffer in text format.\n// The only errors returned are from w.\nfunc (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error {\n\tval := reflect.ValueOf(pb)\n\tif pb == nil || val.IsNil() {\n\t\tw.Write([]byte(\"<nil>\"))\n\t\treturn nil\n\t}\n\tvar bw *bufio.Writer\n\tww, ok := w.(writer)\n\tif !ok {\n\t\tbw = bufio.NewWriter(w)\n\t\tww = bw\n\t}\n\taw := &textWriter{\n\t\tw:        ww,\n\t\tcomplete: true,\n\t\tcompact:  tm.Compact,\n\t}\n\n\tif etm, ok := pb.(encoding.TextMarshaler); ok {\n\t\ttext, err := etm.MarshalText()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err = aw.Write(text); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif bw != nil {\n\t\t\treturn bw.Flush()\n\t\t}\n\t\treturn nil\n\t}\n\t// Dereference the received pointer so we don't have outer < and >.\n\tv := reflect.Indirect(val)\n\tif err := tm.writeStruct(aw, v); err != nil {\n\t\treturn err\n\t}\n\tif bw != nil {\n\t\treturn bw.Flush()\n\t}\n\treturn nil\n}\n\n// Text is the same as Marshal, but returns the string directly.\nfunc (tm *TextMarshaler) Text(pb Message) string {\n\tvar buf bytes.Buffer\n\ttm.Marshal(&buf, pb)\n\treturn buf.String()\n}\n\nvar (\n\tdefaultTextMarshaler = TextMarshaler{}\n\tcompactTextMarshaler = TextMarshaler{Compact: true}\n)\n\n// TODO: consider removing some of the Marshal functions below.\n\n// MarshalText writes a given protocol buffer in text format.\n// The only errors returned are from w.\nfunc MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) }\n\n// MarshalTextString is the same as MarshalText, but returns the string directly.\nfunc MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) }\n\n// CompactText writes a given protocol buffer in compact text format (one line).\nfunc CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) }\n\n// CompactTextString is the same as CompactText, but returns the string directly.\nfunc CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) }\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/text_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\nfunc (tm *TextMarshaler) writeEnum(w *textWriter, v reflect.Value, props *Properties) error {\n\tm, ok := enumStringMaps[props.Enum]\n\tif !ok {\n\t\tif err := tm.writeAny(w, v, props); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tkey := int32(0)\n\tif v.Kind() == reflect.Ptr {\n\t\tkey = int32(v.Elem().Int())\n\t} else {\n\t\tkey = int32(v.Int())\n\t}\n\ts, ok := m[key]\n\tif !ok {\n\t\tif err := tm.writeAny(w, v, props); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t_, err := fmt.Fprint(w, s)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/text_parser.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2010 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n// Functions for parsing the Text protocol buffer format.\n// TODO: message sets.\n\nimport (\n\t\"encoding\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode/utf8\"\n)\n\n// Error string emitted when deserializing Any and fields are already set\nconst anyRepeatedlyUnpacked = \"Any message unpacked multiple times, or %q already set\"\n\ntype ParseError struct {\n\tMessage string\n\tLine    int // 1-based line number\n\tOffset  int // 0-based byte offset from start of input\n}\n\nfunc (p *ParseError) Error() string {\n\tif p.Line == 1 {\n\t\t// show offset only for first line\n\t\treturn fmt.Sprintf(\"line 1.%d: %v\", p.Offset, p.Message)\n\t}\n\treturn fmt.Sprintf(\"line %d: %v\", p.Line, p.Message)\n}\n\ntype token struct {\n\tvalue    string\n\terr      *ParseError\n\tline     int    // line number\n\toffset   int    // byte number from start of input, not start of line\n\tunquoted string // the unquoted version of value, if it was a quoted string\n}\n\nfunc (t *token) String() string {\n\tif t.err == nil {\n\t\treturn fmt.Sprintf(\"%q (line=%d, offset=%d)\", t.value, t.line, t.offset)\n\t}\n\treturn fmt.Sprintf(\"parse error: %v\", t.err)\n}\n\ntype textParser struct {\n\ts            string // remaining input\n\tdone         bool   // whether the parsing is finished (success or error)\n\tbacked       bool   // whether back() was called\n\toffset, line int\n\tcur          token\n}\n\nfunc newTextParser(s string) *textParser {\n\tp := new(textParser)\n\tp.s = s\n\tp.line = 1\n\tp.cur.line = 1\n\treturn p\n}\n\nfunc (p *textParser) errorf(format string, a ...interface{}) *ParseError {\n\tpe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}\n\tp.cur.err = pe\n\tp.done = true\n\treturn pe\n}\n\n// Numbers and identifiers are matched by [-+._A-Za-z0-9]\nfunc isIdentOrNumberChar(c byte) bool {\n\tswitch {\n\tcase 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':\n\t\treturn true\n\tcase '0' <= c && c <= '9':\n\t\treturn true\n\t}\n\tswitch c {\n\tcase '-', '+', '.', '_':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isWhitespace(c byte) bool {\n\tswitch c {\n\tcase ' ', '\\t', '\\n', '\\r':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isQuote(c byte) bool {\n\tswitch c {\n\tcase '\"', '\\'':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (p *textParser) skipWhitespace() {\n\ti := 0\n\tfor i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {\n\t\tif p.s[i] == '#' {\n\t\t\t// comment; skip to end of line or input\n\t\t\tfor i < len(p.s) && p.s[i] != '\\n' {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i == len(p.s) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif p.s[i] == '\\n' {\n\t\t\tp.line++\n\t\t}\n\t\ti++\n\t}\n\tp.offset += i\n\tp.s = p.s[i:len(p.s)]\n\tif len(p.s) == 0 {\n\t\tp.done = true\n\t}\n}\n\nfunc (p *textParser) advance() {\n\t// Skip whitespace\n\tp.skipWhitespace()\n\tif p.done {\n\t\treturn\n\t}\n\n\t// Start of non-whitespace\n\tp.cur.err = nil\n\tp.cur.offset, p.cur.line = p.offset, p.line\n\tp.cur.unquoted = \"\"\n\tswitch p.s[0] {\n\tcase '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':\n\t\t// Single symbol\n\t\tp.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]\n\tcase '\"', '\\'':\n\t\t// Quoted string\n\t\ti := 1\n\t\tfor i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\\n' {\n\t\t\tif p.s[i] == '\\\\' && i+1 < len(p.s) {\n\t\t\t\t// skip escaped char\n\t\t\t\ti++\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t\tif i >= len(p.s) || p.s[i] != p.s[0] {\n\t\t\tp.errorf(\"unmatched quote\")\n\t\t\treturn\n\t\t}\n\t\tunq, err := unquoteC(p.s[1:i], rune(p.s[0]))\n\t\tif err != nil {\n\t\t\tp.errorf(\"invalid quoted string %s: %v\", p.s[0:i+1], err)\n\t\t\treturn\n\t\t}\n\t\tp.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]\n\t\tp.cur.unquoted = unq\n\tdefault:\n\t\ti := 0\n\t\tfor i < len(p.s) && isIdentOrNumberChar(p.s[i]) {\n\t\t\ti++\n\t\t}\n\t\tif i == 0 {\n\t\t\tp.errorf(\"unexpected byte %#x\", p.s[0])\n\t\t\treturn\n\t\t}\n\t\tp.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]\n\t}\n\tp.offset += len(p.cur.value)\n}\n\nvar (\n\terrBadUTF8 = errors.New(\"proto: bad UTF-8\")\n)\n\nfunc unquoteC(s string, quote rune) (string, error) {\n\t// This is based on C++'s tokenizer.cc.\n\t// Despite its name, this is *not* parsing C syntax.\n\t// For instance, \"\\0\" is an invalid quoted string.\n\n\t// Avoid allocation in trivial cases.\n\tsimple := true\n\tfor _, r := range s {\n\t\tif r == '\\\\' || r == quote {\n\t\t\tsimple = false\n\t\t\tbreak\n\t\t}\n\t}\n\tif simple {\n\t\treturn s, nil\n\t}\n\n\tbuf := make([]byte, 0, 3*len(s)/2)\n\tfor len(s) > 0 {\n\t\tr, n := utf8.DecodeRuneInString(s)\n\t\tif r == utf8.RuneError && n == 1 {\n\t\t\treturn \"\", errBadUTF8\n\t\t}\n\t\ts = s[n:]\n\t\tif r != '\\\\' {\n\t\t\tif r < utf8.RuneSelf {\n\t\t\t\tbuf = append(buf, byte(r))\n\t\t\t} else {\n\t\t\t\tbuf = append(buf, string(r)...)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tch, tail, err := unescape(s)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tbuf = append(buf, ch...)\n\t\ts = tail\n\t}\n\treturn string(buf), nil\n}\n\nfunc unescape(s string) (ch string, tail string, err error) {\n\tr, n := utf8.DecodeRuneInString(s)\n\tif r == utf8.RuneError && n == 1 {\n\t\treturn \"\", \"\", errBadUTF8\n\t}\n\ts = s[n:]\n\tswitch r {\n\tcase 'a':\n\t\treturn \"\\a\", s, nil\n\tcase 'b':\n\t\treturn \"\\b\", s, nil\n\tcase 'f':\n\t\treturn \"\\f\", s, nil\n\tcase 'n':\n\t\treturn \"\\n\", s, nil\n\tcase 'r':\n\t\treturn \"\\r\", s, nil\n\tcase 't':\n\t\treturn \"\\t\", s, nil\n\tcase 'v':\n\t\treturn \"\\v\", s, nil\n\tcase '?':\n\t\treturn \"?\", s, nil // trigraph workaround\n\tcase '\\'', '\"', '\\\\':\n\t\treturn string(r), s, nil\n\tcase '0', '1', '2', '3', '4', '5', '6', '7':\n\t\tif len(s) < 2 {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c requires 2 following digits`, r)\n\t\t}\n\t\tss := string(r) + s[:2]\n\t\ts = s[2:]\n\t\ti, err := strconv.ParseUint(ss, 8, 8)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%s contains non-octal digits`, ss)\n\t\t}\n\t\treturn string([]byte{byte(i)}), s, nil\n\tcase 'x', 'X', 'u', 'U':\n\t\tvar n int\n\t\tswitch r {\n\t\tcase 'x', 'X':\n\t\t\tn = 2\n\t\tcase 'u':\n\t\t\tn = 4\n\t\tcase 'U':\n\t\t\tn = 8\n\t\t}\n\t\tif len(s) < n {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c requires %d following digits`, r, n)\n\t\t}\n\t\tss := s[:n]\n\t\ts = s[n:]\n\t\ti, err := strconv.ParseUint(ss, 16, 64)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c%s contains non-hexadecimal digits`, r, ss)\n\t\t}\n\t\tif r == 'x' || r == 'X' {\n\t\t\treturn string([]byte{byte(i)}), s, nil\n\t\t}\n\t\tif i > utf8.MaxRune {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c%s is not a valid Unicode code point`, r, ss)\n\t\t}\n\t\treturn string(rune(i)), s, nil\n\t}\n\treturn \"\", \"\", fmt.Errorf(`unknown escape \\%c`, r)\n}\n\n// Back off the parser by one token. Can only be done between calls to next().\n// It makes the next advance() a no-op.\nfunc (p *textParser) back() { p.backed = true }\n\n// Advances the parser and returns the new current token.\nfunc (p *textParser) next() *token {\n\tif p.backed || p.done {\n\t\tp.backed = false\n\t\treturn &p.cur\n\t}\n\tp.advance()\n\tif p.done {\n\t\tp.cur.value = \"\"\n\t} else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {\n\t\t// Look for multiple quoted strings separated by whitespace,\n\t\t// and concatenate them.\n\t\tcat := p.cur\n\t\tfor {\n\t\t\tp.skipWhitespace()\n\t\t\tif p.done || !isQuote(p.s[0]) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.advance()\n\t\t\tif p.cur.err != nil {\n\t\t\t\treturn &p.cur\n\t\t\t}\n\t\t\tcat.value += \" \" + p.cur.value\n\t\t\tcat.unquoted += p.cur.unquoted\n\t\t}\n\t\tp.done = false // parser may have seen EOF, but we want to return cat\n\t\tp.cur = cat\n\t}\n\treturn &p.cur\n}\n\nfunc (p *textParser) consumeToken(s string) error {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn tok.err\n\t}\n\tif tok.value != s {\n\t\tp.back()\n\t\treturn p.errorf(\"expected %q, found %q\", s, tok.value)\n\t}\n\treturn nil\n}\n\n// Return a RequiredNotSetError indicating which required field was not set.\nfunc (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {\n\tst := sv.Type()\n\tsprops := GetProperties(st)\n\tfor i := 0; i < st.NumField(); i++ {\n\t\tif !isNil(sv.Field(i)) {\n\t\t\tcontinue\n\t\t}\n\n\t\tprops := sprops.Prop[i]\n\t\tif props.Required {\n\t\t\treturn &RequiredNotSetError{fmt.Sprintf(\"%v.%v\", st, props.OrigName)}\n\t\t}\n\t}\n\treturn &RequiredNotSetError{fmt.Sprintf(\"%v.<unknown field name>\", st)} // should not happen\n}\n\n// Returns the index in the struct for the named field, as well as the parsed tag properties.\nfunc structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {\n\ti, ok := sprops.decoderOrigNames[name]\n\tif ok {\n\t\treturn i, sprops.Prop[i], true\n\t}\n\treturn -1, nil, false\n}\n\n// Consume a ':' from the input stream (if the next token is a colon),\n// returning an error if a colon is needed but not present.\nfunc (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn tok.err\n\t}\n\tif tok.value != \":\" {\n\t\t// Colon is optional when the field is a group or message.\n\t\tneedColon := true\n\t\tswitch props.Wire {\n\t\tcase \"group\":\n\t\t\tneedColon = false\n\t\tcase \"bytes\":\n\t\t\t// A \"bytes\" field is either a message, a string, or a repeated field;\n\t\t\t// those three become *T, *string and []T respectively, so we can check for\n\t\t\t// this field being a pointer to a non-string.\n\t\t\tif typ.Kind() == reflect.Ptr {\n\t\t\t\t// *T or *string\n\t\t\t\tif typ.Elem().Kind() == reflect.String {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t} else if typ.Kind() == reflect.Slice {\n\t\t\t\t// []T or []*T\n\t\t\t\tif typ.Elem().Kind() != reflect.Ptr {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t} else if typ.Kind() == reflect.String {\n\t\t\t\t// The proto3 exception is for a string field,\n\t\t\t\t// which requires a colon.\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tneedColon = false\n\t\t}\n\t\tif needColon {\n\t\t\treturn p.errorf(\"expected ':', found %q\", tok.value)\n\t\t}\n\t\tp.back()\n\t}\n\treturn nil\n}\n\nfunc (p *textParser) readStruct(sv reflect.Value, terminator string) error {\n\tst := sv.Type()\n\tsprops := GetProperties(st)\n\treqCount := sprops.reqCount\n\tvar reqFieldErr error\n\tfieldSet := make(map[string]bool)\n\t// A struct is a sequence of \"name: value\", terminated by one of\n\t// '>' or '}', or the end of the input.  A name may also be\n\t// \"[extension]\" or \"[type/url]\".\n\t//\n\t// The whole struct can also be an expanded Any message, like:\n\t// [type/url] < ... struct contents ... >\n\tfor {\n\t\ttok := p.next()\n\t\tif tok.err != nil {\n\t\t\treturn tok.err\n\t\t}\n\t\tif tok.value == terminator {\n\t\t\tbreak\n\t\t}\n\t\tif tok.value == \"[\" {\n\t\t\t// Looks like an extension or an Any.\n\t\t\t//\n\t\t\t// TODO: Check whether we need to handle\n\t\t\t// namespace rooted names (e.g. \".something.Foo\").\n\t\t\textName, err := p.consumeExtName()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif s := strings.LastIndex(extName, \"/\"); s >= 0 {\n\t\t\t\t// If it contains a slash, it's an Any type URL.\n\t\t\t\tmessageName := extName[s+1:]\n\t\t\t\tmt := MessageType(messageName)\n\t\t\t\tif mt == nil {\n\t\t\t\t\treturn p.errorf(\"unrecognized message %q in google.protobuf.Any\", messageName)\n\t\t\t\t}\n\t\t\t\ttok = p.next()\n\t\t\t\tif tok.err != nil {\n\t\t\t\t\treturn tok.err\n\t\t\t\t}\n\t\t\t\t// consume an optional colon\n\t\t\t\tif tok.value == \":\" {\n\t\t\t\t\ttok = p.next()\n\t\t\t\t\tif tok.err != nil {\n\t\t\t\t\t\treturn tok.err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar terminator string\n\t\t\t\tswitch tok.value {\n\t\t\t\tcase \"<\":\n\t\t\t\t\tterminator = \">\"\n\t\t\t\tcase \"{\":\n\t\t\t\t\tterminator = \"}\"\n\t\t\t\tdefault:\n\t\t\t\t\treturn p.errorf(\"expected '{' or '<', found %q\", tok.value)\n\t\t\t\t}\n\t\t\t\tv := reflect.New(mt.Elem())\n\t\t\t\tif pe := p.readStruct(v.Elem(), terminator); pe != nil {\n\t\t\t\t\treturn pe\n\t\t\t\t}\n\t\t\t\tb, err := Marshal(v.Interface().(Message))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn p.errorf(\"failed to marshal message of type %q: %v\", messageName, err)\n\t\t\t\t}\n\t\t\t\tif fieldSet[\"type_url\"] {\n\t\t\t\t\treturn p.errorf(anyRepeatedlyUnpacked, \"type_url\")\n\t\t\t\t}\n\t\t\t\tif fieldSet[\"value\"] {\n\t\t\t\t\treturn p.errorf(anyRepeatedlyUnpacked, \"value\")\n\t\t\t\t}\n\t\t\t\tsv.FieldByName(\"TypeUrl\").SetString(extName)\n\t\t\t\tsv.FieldByName(\"Value\").SetBytes(b)\n\t\t\t\tfieldSet[\"type_url\"] = true\n\t\t\t\tfieldSet[\"value\"] = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar desc *ExtensionDesc\n\t\t\t// This could be faster, but it's functional.\n\t\t\t// TODO: Do something smarter than a linear scan.\n\t\t\tfor _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) {\n\t\t\t\tif d.Name == extName {\n\t\t\t\t\tdesc = d\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif desc == nil {\n\t\t\t\treturn p.errorf(\"unrecognized extension %q\", extName)\n\t\t\t}\n\n\t\t\tprops := &Properties{}\n\t\t\tprops.Parse(desc.Tag)\n\n\t\t\ttyp := reflect.TypeOf(desc.ExtensionType)\n\t\t\tif err := p.checkForColon(props, typ); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\trep := desc.repeated()\n\n\t\t\t// Read the extension structure, and set it in\n\t\t\t// the value we're constructing.\n\t\t\tvar ext reflect.Value\n\t\t\tif !rep {\n\t\t\t\text = reflect.New(typ).Elem()\n\t\t\t} else {\n\t\t\t\text = reflect.New(typ.Elem()).Elem()\n\t\t\t}\n\t\t\tif err := p.readAny(ext, props); err != nil {\n\t\t\t\tif _, ok := err.(*RequiredNotSetError); !ok {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\treqFieldErr = err\n\t\t\t}\n\t\t\tep := sv.Addr().Interface().(Message)\n\t\t\tif !rep {\n\t\t\t\tSetExtension(ep, desc, ext.Interface())\n\t\t\t} else {\n\t\t\t\told, err := GetExtension(ep, desc)\n\t\t\t\tvar sl reflect.Value\n\t\t\t\tif err == nil {\n\t\t\t\t\tsl = reflect.ValueOf(old) // existing slice\n\t\t\t\t} else {\n\t\t\t\t\tsl = reflect.MakeSlice(typ, 0, 1)\n\t\t\t\t}\n\t\t\t\tsl = reflect.Append(sl, ext)\n\t\t\t\tSetExtension(ep, desc, sl.Interface())\n\t\t\t}\n\t\t\tif err := p.consumeOptionalSeparator(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// This is a normal, non-extension field.\n\t\tname := tok.value\n\t\tvar dst reflect.Value\n\t\tfi, props, ok := structFieldByName(sprops, name)\n\t\tif ok {\n\t\t\tdst = sv.Field(fi)\n\t\t} else if oop, ok := sprops.OneofTypes[name]; ok {\n\t\t\t// It is a oneof.\n\t\t\tprops = oop.Prop\n\t\t\tnv := reflect.New(oop.Type.Elem())\n\t\t\tdst = nv.Elem().Field(0)\n\t\t\tfield := sv.Field(oop.Field)\n\t\t\tif !field.IsNil() {\n\t\t\t\treturn p.errorf(\"field '%s' would overwrite already parsed oneof '%s'\", name, sv.Type().Field(oop.Field).Name)\n\t\t\t}\n\t\t\tfield.Set(nv)\n\t\t}\n\t\tif !dst.IsValid() {\n\t\t\treturn p.errorf(\"unknown field name %q in %v\", name, st)\n\t\t}\n\n\t\tif dst.Kind() == reflect.Map {\n\t\t\t// Consume any colon.\n\t\t\tif err := p.checkForColon(props, dst.Type()); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Construct the map if it doesn't already exist.\n\t\t\tif dst.IsNil() {\n\t\t\t\tdst.Set(reflect.MakeMap(dst.Type()))\n\t\t\t}\n\t\t\tkey := reflect.New(dst.Type().Key()).Elem()\n\t\t\tval := reflect.New(dst.Type().Elem()).Elem()\n\n\t\t\t// The map entry should be this sequence of tokens:\n\t\t\t//\t< key : KEY value : VALUE >\n\t\t\t// However, implementations may omit key or value, and technically\n\t\t\t// we should support them in any order.  See b/28924776 for a time\n\t\t\t// this went wrong.\n\n\t\t\ttok := p.next()\n\t\t\tvar terminator string\n\t\t\tswitch tok.value {\n\t\t\tcase \"<\":\n\t\t\t\tterminator = \">\"\n\t\t\tcase \"{\":\n\t\t\t\tterminator = \"}\"\n\t\t\tdefault:\n\t\t\t\treturn p.errorf(\"expected '{' or '<', found %q\", tok.value)\n\t\t\t}\n\t\t\tfor {\n\t\t\t\ttok := p.next()\n\t\t\t\tif tok.err != nil {\n\t\t\t\t\treturn tok.err\n\t\t\t\t}\n\t\t\t\tif tok.value == terminator {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tswitch tok.value {\n\t\t\t\tcase \"key\":\n\t\t\t\t\tif err := p.consumeToken(\":\"); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif err := p.readAny(key, props.MapKeyProp); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif err := p.consumeOptionalSeparator(); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\tcase \"value\":\n\t\t\t\t\tif err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif err := p.readAny(val, props.MapValProp); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif err := p.consumeOptionalSeparator(); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\tp.back()\n\t\t\t\t\treturn p.errorf(`expected \"key\", \"value\", or %q, found %q`, terminator, tok.value)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdst.SetMapIndex(key, val)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check that it's not already set if it's not a repeated field.\n\t\tif !props.Repeated && fieldSet[name] {\n\t\t\treturn p.errorf(\"non-repeated field %q was repeated\", name)\n\t\t}\n\n\t\tif err := p.checkForColon(props, dst.Type()); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Parse into the field.\n\t\tfieldSet[name] = true\n\t\tif err := p.readAny(dst, props); err != nil {\n\t\t\tif _, ok := err.(*RequiredNotSetError); !ok {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treqFieldErr = err\n\t\t}\n\t\tif props.Required {\n\t\t\treqCount--\n\t\t}\n\n\t\tif err := p.consumeOptionalSeparator(); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t}\n\n\tif reqCount > 0 {\n\t\treturn p.missingRequiredFieldError(sv)\n\t}\n\treturn reqFieldErr\n}\n\n// consumeExtName consumes extension name or expanded Any type URL and the\n// following ']'. It returns the name or URL consumed.\nfunc (p *textParser) consumeExtName() (string, error) {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn \"\", tok.err\n\t}\n\n\t// If extension name or type url is quoted, it's a single token.\n\tif len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {\n\t\tname, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn name, p.consumeToken(\"]\")\n\t}\n\n\t// Consume everything up to \"]\"\n\tvar parts []string\n\tfor tok.value != \"]\" {\n\t\tparts = append(parts, tok.value)\n\t\ttok = p.next()\n\t\tif tok.err != nil {\n\t\t\treturn \"\", p.errorf(\"unrecognized type_url or extension name: %s\", tok.err)\n\t\t}\n\t\tif p.done && tok.value != \"]\" {\n\t\t\treturn \"\", p.errorf(\"unclosed type_url or extension name\")\n\t\t}\n\t}\n\treturn strings.Join(parts, \"\"), nil\n}\n\n// consumeOptionalSeparator consumes an optional semicolon or comma.\n// It is used in readStruct to provide backward compatibility.\nfunc (p *textParser) consumeOptionalSeparator() error {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn tok.err\n\t}\n\tif tok.value != \";\" && tok.value != \",\" {\n\t\tp.back()\n\t}\n\treturn nil\n}\n\nfunc (p *textParser) readAny(v reflect.Value, props *Properties) error {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn tok.err\n\t}\n\tif tok.value == \"\" {\n\t\treturn p.errorf(\"unexpected EOF\")\n\t}\n\tif len(props.CustomType) > 0 {\n\t\tif props.Repeated {\n\t\t\tt := reflect.TypeOf(v.Interface())\n\t\t\tif t.Kind() == reflect.Slice {\n\t\t\t\ttc := reflect.TypeOf(new(Marshaler))\n\t\t\t\tok := t.Elem().Implements(tc.Elem())\n\t\t\t\tif ok {\n\t\t\t\t\tfv := v\n\t\t\t\t\tflen := fv.Len()\n\t\t\t\t\tif flen == fv.Cap() {\n\t\t\t\t\t\tnav := reflect.MakeSlice(v.Type(), flen, 2*flen+1)\n\t\t\t\t\t\treflect.Copy(nav, fv)\n\t\t\t\t\t\tfv.Set(nav)\n\t\t\t\t\t}\n\t\t\t\t\tfv.SetLen(flen + 1)\n\n\t\t\t\t\t// Read one.\n\t\t\t\t\tp.back()\n\t\t\t\t\treturn p.readAny(fv.Index(flen), props)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {\n\t\t\tcustom := reflect.New(props.ctype.Elem()).Interface().(Unmarshaler)\n\t\t\terr := custom.Unmarshal([]byte(tok.unquoted))\n\t\t\tif err != nil {\n\t\t\t\treturn p.errorf(\"%v %v: %v\", err, v.Type(), tok.value)\n\t\t\t}\n\t\t\tv.Set(reflect.ValueOf(custom))\n\t\t} else {\n\t\t\tcustom := reflect.New(reflect.TypeOf(v.Interface())).Interface().(Unmarshaler)\n\t\t\terr := custom.Unmarshal([]byte(tok.unquoted))\n\t\t\tif err != nil {\n\t\t\t\treturn p.errorf(\"%v %v: %v\", err, v.Type(), tok.value)\n\t\t\t}\n\t\t\tv.Set(reflect.Indirect(reflect.ValueOf(custom)))\n\t\t}\n\t\treturn nil\n\t}\n\tif props.StdTime {\n\t\tfv := v\n\t\tp.back()\n\t\tprops.StdTime = false\n\t\ttproto := &timestamp{}\n\t\terr := p.readAny(reflect.ValueOf(tproto).Elem(), props)\n\t\tprops.StdTime = true\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttim, err := timestampFromProto(tproto)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif props.Repeated {\n\t\t\tt := reflect.TypeOf(v.Interface())\n\t\t\tif t.Kind() == reflect.Slice {\n\t\t\t\tif t.Elem().Kind() == reflect.Ptr {\n\t\t\t\t\tts := fv.Interface().([]*time.Time)\n\t\t\t\t\tts = append(ts, &tim)\n\t\t\t\t\tfv.Set(reflect.ValueOf(ts))\n\t\t\t\t\treturn nil\n\t\t\t\t} else {\n\t\t\t\t\tts := fv.Interface().([]time.Time)\n\t\t\t\t\tts = append(ts, tim)\n\t\t\t\t\tfv.Set(reflect.ValueOf(ts))\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {\n\t\t\tv.Set(reflect.ValueOf(&tim))\n\t\t} else {\n\t\t\tv.Set(reflect.Indirect(reflect.ValueOf(&tim)))\n\t\t}\n\t\treturn nil\n\t}\n\tif props.StdDuration {\n\t\tfv := v\n\t\tp.back()\n\t\tprops.StdDuration = false\n\t\tdproto := &duration{}\n\t\terr := p.readAny(reflect.ValueOf(dproto).Elem(), props)\n\t\tprops.StdDuration = true\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdur, err := durationFromProto(dproto)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif props.Repeated {\n\t\t\tt := reflect.TypeOf(v.Interface())\n\t\t\tif t.Kind() == reflect.Slice {\n\t\t\t\tif t.Elem().Kind() == reflect.Ptr {\n\t\t\t\t\tds := fv.Interface().([]*time.Duration)\n\t\t\t\t\tds = append(ds, &dur)\n\t\t\t\t\tfv.Set(reflect.ValueOf(ds))\n\t\t\t\t\treturn nil\n\t\t\t\t} else {\n\t\t\t\t\tds := fv.Interface().([]time.Duration)\n\t\t\t\t\tds = append(ds, dur)\n\t\t\t\t\tfv.Set(reflect.ValueOf(ds))\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif reflect.TypeOf(v.Interface()).Kind() == reflect.Ptr {\n\t\t\tv.Set(reflect.ValueOf(&dur))\n\t\t} else {\n\t\t\tv.Set(reflect.Indirect(reflect.ValueOf(&dur)))\n\t\t}\n\t\treturn nil\n\t}\n\tswitch fv := v; fv.Kind() {\n\tcase reflect.Slice:\n\t\tat := v.Type()\n\t\tif at.Elem().Kind() == reflect.Uint8 {\n\t\t\t// Special case for []byte\n\t\t\tif tok.value[0] != '\"' && tok.value[0] != '\\'' {\n\t\t\t\t// Deliberately written out here, as the error after\n\t\t\t\t// this switch statement would write \"invalid []byte: ...\",\n\t\t\t\t// which is not as user-friendly.\n\t\t\t\treturn p.errorf(\"invalid string: %v\", tok.value)\n\t\t\t}\n\t\t\tbytes := []byte(tok.unquoted)\n\t\t\tfv.Set(reflect.ValueOf(bytes))\n\t\t\treturn nil\n\t\t}\n\t\t// Repeated field.\n\t\tif tok.value == \"[\" {\n\t\t\t// Repeated field with list notation, like [1,2,3].\n\t\t\tfor {\n\t\t\t\tfv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))\n\t\t\t\terr := p.readAny(fv.Index(fv.Len()-1), props)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tntok := p.next()\n\t\t\t\tif ntok.err != nil {\n\t\t\t\t\treturn ntok.err\n\t\t\t\t}\n\t\t\t\tif ntok.value == \"]\" {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif ntok.value != \",\" {\n\t\t\t\t\treturn p.errorf(\"Expected ']' or ',' found %q\", ntok.value)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\t// One value of the repeated field.\n\t\tp.back()\n\t\tfv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))\n\t\treturn p.readAny(fv.Index(fv.Len()-1), props)\n\tcase reflect.Bool:\n\t\t// true/1/t/True or false/f/0/False.\n\t\tswitch tok.value {\n\t\tcase \"true\", \"1\", \"t\", \"True\":\n\t\t\tfv.SetBool(true)\n\t\t\treturn nil\n\t\tcase \"false\", \"0\", \"f\", \"False\":\n\t\t\tfv.SetBool(false)\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Float32, reflect.Float64:\n\t\tv := tok.value\n\t\t// Ignore 'f' for compatibility with output generated by C++, but don't\n\t\t// remove 'f' when the value is \"-inf\" or \"inf\".\n\t\tif strings.HasSuffix(v, \"f\") && tok.value != \"-inf\" && tok.value != \"inf\" {\n\t\t\tv = v[:len(v)-1]\n\t\t}\n\t\tif f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil {\n\t\t\tfv.SetFloat(f)\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Int8:\n\t\tif x, err := strconv.ParseInt(tok.value, 0, 8); err == nil {\n\t\t\tfv.SetInt(x)\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Int16:\n\t\tif x, err := strconv.ParseInt(tok.value, 0, 16); err == nil {\n\t\t\tfv.SetInt(x)\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Int32:\n\t\tif x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {\n\t\t\tfv.SetInt(x)\n\t\t\treturn nil\n\t\t}\n\n\t\tif len(props.Enum) == 0 {\n\t\t\tbreak\n\t\t}\n\t\tm, ok := enumValueMaps[props.Enum]\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\tx, ok := m[tok.value]\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\tfv.SetInt(int64(x))\n\t\treturn nil\n\tcase reflect.Int64:\n\t\tif x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {\n\t\t\tfv.SetInt(x)\n\t\t\treturn nil\n\t\t}\n\n\tcase reflect.Ptr:\n\t\t// A basic field (indirected through pointer), or a repeated message/group\n\t\tp.back()\n\t\tfv.Set(reflect.New(fv.Type().Elem()))\n\t\treturn p.readAny(fv.Elem(), props)\n\tcase reflect.String:\n\t\tif tok.value[0] == '\"' || tok.value[0] == '\\'' {\n\t\t\tfv.SetString(tok.unquoted)\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Struct:\n\t\tvar terminator string\n\t\tswitch tok.value {\n\t\tcase \"{\":\n\t\t\tterminator = \"}\"\n\t\tcase \"<\":\n\t\t\tterminator = \">\"\n\t\tdefault:\n\t\t\treturn p.errorf(\"expected '{' or '<', found %q\", tok.value)\n\t\t}\n\t\t// TODO: Handle nested messages which implement encoding.TextUnmarshaler.\n\t\treturn p.readStruct(fv, terminator)\n\tcase reflect.Uint8:\n\t\tif x, err := strconv.ParseUint(tok.value, 0, 8); err == nil {\n\t\t\tfv.SetUint(x)\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Uint16:\n\t\tif x, err := strconv.ParseUint(tok.value, 0, 16); err == nil {\n\t\t\tfv.SetUint(x)\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Uint32:\n\t\tif x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {\n\t\t\tfv.SetUint(uint64(x))\n\t\t\treturn nil\n\t\t}\n\tcase reflect.Uint64:\n\t\tif x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {\n\t\t\tfv.SetUint(x)\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn p.errorf(\"invalid %v: %v\", v.Type(), tok.value)\n}\n\n// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb\n// before starting to unmarshal, so any existing data in pb is always removed.\n// If a required field is not set and no other error occurs,\n// UnmarshalText returns *RequiredNotSetError.\nfunc UnmarshalText(s string, pb Message) error {\n\tif um, ok := pb.(encoding.TextUnmarshaler); ok {\n\t\treturn um.UnmarshalText([]byte(s))\n\t}\n\tpb.Reset()\n\tv := reflect.ValueOf(pb)\n\treturn newTextParser(s).readStruct(v.Elem(), \"\")\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/timestamp.go",
    "content": "// Go support for Protocol Buffers - Google's data interchange format\n//\n// Copyright 2016 The Go Authors.  All rights reserved.\n// https://github.com/golang/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//     * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\n// This file implements operations on google.protobuf.Timestamp.\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n)\n\nconst (\n\t// Seconds field of the earliest valid Timestamp.\n\t// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().\n\tminValidSeconds = -62135596800\n\t// Seconds field just after the latest valid Timestamp.\n\t// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().\n\tmaxValidSeconds = 253402300800\n)\n\n// validateTimestamp determines whether a Timestamp is valid.\n// A valid timestamp represents a time in the range\n// [0001-01-01, 10000-01-01) and has a Nanos field\n// in the range [0, 1e9).\n//\n// If the Timestamp is valid, validateTimestamp returns nil.\n// Otherwise, it returns an error that describes\n// the problem.\n//\n// Every valid Timestamp can be represented by a time.Time, but the converse is not true.\nfunc validateTimestamp(ts *timestamp) error {\n\tif ts == nil {\n\t\treturn errors.New(\"timestamp: nil Timestamp\")\n\t}\n\tif ts.Seconds < minValidSeconds {\n\t\treturn fmt.Errorf(\"timestamp: %#v before 0001-01-01\", ts)\n\t}\n\tif ts.Seconds >= maxValidSeconds {\n\t\treturn fmt.Errorf(\"timestamp: %#v after 10000-01-01\", ts)\n\t}\n\tif ts.Nanos < 0 || ts.Nanos >= 1e9 {\n\t\treturn fmt.Errorf(\"timestamp: %#v: nanos not in range [0, 1e9)\", ts)\n\t}\n\treturn nil\n}\n\n// TimestampFromProto converts a google.protobuf.Timestamp proto to a time.Time.\n// It returns an error if the argument is invalid.\n//\n// Unlike most Go functions, if Timestamp returns an error, the first return value\n// is not the zero time.Time. Instead, it is the value obtained from the\n// time.Unix function when passed the contents of the Timestamp, in the UTC\n// locale. This may or may not be a meaningful time; many invalid Timestamps\n// do map to valid time.Times.\n//\n// A nil Timestamp returns an error. The first return value in that case is\n// undefined.\nfunc timestampFromProto(ts *timestamp) (time.Time, error) {\n\t// Don't return the zero value on error, because corresponds to a valid\n\t// timestamp. Instead return whatever time.Unix gives us.\n\tvar t time.Time\n\tif ts == nil {\n\t\tt = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp\n\t} else {\n\t\tt = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()\n\t}\n\treturn t, validateTimestamp(ts)\n}\n\n// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.\n// It returns an error if the resulting Timestamp is invalid.\nfunc timestampProto(t time.Time) (*timestamp, error) {\n\tseconds := t.Unix()\n\tnanos := int32(t.Sub(time.Unix(seconds, 0)))\n\tts := &timestamp{\n\t\tSeconds: seconds,\n\t\tNanos:   nanos,\n\t}\n\tif err := validateTimestamp(ts); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ts, nil\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2016, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"reflect\"\n\t\"time\"\n)\n\nvar timeType = reflect.TypeOf((*time.Time)(nil)).Elem()\n\ntype timestamp struct {\n\tSeconds int64 `protobuf:\"varint,1,opt,name=seconds,proto3\" json:\"seconds,omitempty\"`\n\tNanos   int32 `protobuf:\"varint,2,opt,name=nanos,proto3\" json:\"nanos,omitempty\"`\n}\n\nfunc (m *timestamp) Reset()       { *m = timestamp{} }\nfunc (*timestamp) ProtoMessage()  {}\nfunc (*timestamp) String() string { return \"timestamp<string>\" }\n\nfunc init() {\n\tRegisterType((*timestamp)(nil), \"gogo.protobuf.proto.timestamp\")\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/wrappers.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\nimport (\n\t\"io\"\n\t\"reflect\"\n)\n\nfunc makeStdDoubleValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*float64)\n\t\t\tv := &float64Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*float64)\n\t\t\tv := &float64Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdDoubleValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64)\n\t\t\tv := &float64Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64)\n\t\t\tv := &float64Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdDoubleValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(float64)\n\t\t\t\tv := &float64Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(float64)\n\t\t\t\tv := &float64Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdDoubleValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*float64)\n\t\t\t\tv := &float64Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*float64)\n\t\t\t\tv := &float64Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdDoubleValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdDoubleValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdDoubleValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdDoubleValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdFloatValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*float32)\n\t\t\tv := &float32Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*float32)\n\t\t\tv := &float32Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdFloatValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32)\n\t\t\tv := &float32Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32)\n\t\t\tv := &float32Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdFloatValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(float32)\n\t\t\t\tv := &float32Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(float32)\n\t\t\t\tv := &float32Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdFloatValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*float32)\n\t\t\t\tv := &float32Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*float32)\n\t\t\t\tv := &float32Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdFloatValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdFloatValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdFloatValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdFloatValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &float32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*int64)\n\t\t\tv := &int64Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*int64)\n\t\t\tv := &int64Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64)\n\t\t\tv := &int64Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64)\n\t\t\tv := &int64Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(int64)\n\t\t\t\tv := &int64Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(int64)\n\t\t\t\tv := &int64Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*int64)\n\t\t\t\tv := &int64Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*int64)\n\t\t\t\tv := &int64Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*uint64)\n\t\t\tv := &uint64Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*uint64)\n\t\t\tv := &uint64Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64)\n\t\t\tv := &uint64Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64)\n\t\t\tv := &uint64Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(uint64)\n\t\t\t\tv := &uint64Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(uint64)\n\t\t\t\tv := &uint64Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*uint64)\n\t\t\t\tv := &uint64Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*uint64)\n\t\t\t\tv := &uint64Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint64Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*int32)\n\t\t\tv := &int32Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*int32)\n\t\t\tv := &int32Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32)\n\t\t\tv := &int32Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32)\n\t\t\tv := &int32Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(int32)\n\t\t\t\tv := &int32Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(int32)\n\t\t\t\tv := &int32Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*int32)\n\t\t\t\tv := &int32Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*int32)\n\t\t\t\tv := &int32Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &int32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*uint32)\n\t\t\tv := &uint32Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*uint32)\n\t\t\tv := &uint32Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32)\n\t\t\tv := &uint32Value{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32)\n\t\t\tv := &uint32Value{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(uint32)\n\t\t\t\tv := &uint32Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(uint32)\n\t\t\t\tv := &uint32Value{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*uint32)\n\t\t\t\tv := &uint32Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*uint32)\n\t\t\t\tv := &uint32Value{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdUInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdUInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &uint32Value{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBoolValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*bool)\n\t\t\tv := &boolValue{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*bool)\n\t\t\tv := &boolValue{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBoolValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool)\n\t\t\tv := &boolValue{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool)\n\t\t\tv := &boolValue{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBoolValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(bool)\n\t\t\t\tv := &boolValue{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(bool)\n\t\t\t\tv := &boolValue{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBoolValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*bool)\n\t\t\t\tv := &boolValue{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*bool)\n\t\t\t\tv := &boolValue{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBoolValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &boolValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBoolValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &boolValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBoolValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &boolValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBoolValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &boolValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdStringValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*string)\n\t\t\tv := &stringValue{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*string)\n\t\t\tv := &stringValue{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdStringValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string)\n\t\t\tv := &stringValue{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string)\n\t\t\tv := &stringValue{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdStringValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(string)\n\t\t\t\tv := &stringValue{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(string)\n\t\t\t\tv := &stringValue{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdStringValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*string)\n\t\t\t\tv := &stringValue{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*string)\n\t\t\t\tv := &stringValue{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdStringValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &stringValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdStringValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &stringValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdStringValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &stringValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdStringValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &stringValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBytesValueMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*[]byte)\n\t\t\tv := &bytesValue{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tt := ptr.asPointerTo(u.typ).Interface().(*[]byte)\n\t\t\tv := &bytesValue{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBytesValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte)\n\t\t\tv := &bytesValue{*t}\n\t\t\tsiz := Size(v)\n\t\t\treturn tagsize + SizeVarint(uint64(siz)) + siz\n\t\t}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\tif ptr.isNil() {\n\t\t\t\treturn b, nil\n\t\t\t}\n\t\t\tt := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte)\n\t\t\tv := &bytesValue{*t}\n\t\t\tbuf, err := Marshal(v)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tb = appendVarint(b, wiretag)\n\t\t\tb = appendVarint(b, uint64(len(buf)))\n\t\t\tb = append(b, buf...)\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBytesValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().([]byte)\n\t\t\t\tv := &bytesValue{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(u.typ)\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().([]byte)\n\t\t\t\tv := &bytesValue{t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBytesValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {\n\treturn func(ptr pointer, tagsize int) int {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tn := 0\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*[]byte)\n\t\t\t\tv := &bytesValue{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tn += siz + SizeVarint(uint64(siz)) + tagsize\n\t\t\t}\n\t\t\treturn n\n\t\t},\n\t\tfunc(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {\n\t\t\ts := ptr.getSlice(reflect.PtrTo(u.typ))\n\t\t\tfor i := 0; i < s.Len(); i++ {\n\t\t\t\telem := s.Index(i)\n\t\t\t\tt := elem.Interface().(*[]byte)\n\t\t\t\tv := &bytesValue{*t}\n\t\t\t\tsiz := Size(v)\n\t\t\t\tbuf, err := Marshal(v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tb = appendVarint(b, wiretag)\n\t\t\t\tb = appendVarint(b, uint64(siz))\n\t\t\t\tb = append(b, buf...)\n\t\t\t}\n\n\t\t\treturn b, nil\n\t\t}\n}\n\nfunc makeStdBytesValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &bytesValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(sub.typ).Elem()\n\t\ts.Set(reflect.ValueOf(m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBytesValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &bytesValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ts := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()\n\t\ts.Set(reflect.ValueOf(&m.Value))\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBytesValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &bytesValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(reflect.PtrTo(sub.typ))\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n\nfunc makeStdBytesValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {\n\treturn func(b []byte, f pointer, w int) ([]byte, error) {\n\t\tif w != WireBytes {\n\t\t\treturn nil, errInternalBadWireType\n\t\t}\n\t\tx, n := decodeVarint(b)\n\t\tif n == 0 {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tb = b[n:]\n\t\tif x > uint64(len(b)) {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tm := &bytesValue{}\n\t\tif err := Unmarshal(b[:x], m); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tslice := f.getSlice(sub.typ)\n\t\tnewSlice := reflect.Append(slice, reflect.ValueOf(m.Value))\n\t\tslice.Set(newSlice)\n\t\treturn b[x:], nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2018, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage proto\n\ntype float64Value struct {\n\tValue float64 `protobuf:\"fixed64,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *float64Value) Reset()       { *m = float64Value{} }\nfunc (*float64Value) ProtoMessage()  {}\nfunc (*float64Value) String() string { return \"float64<string>\" }\n\ntype float32Value struct {\n\tValue float32 `protobuf:\"fixed32,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *float32Value) Reset()       { *m = float32Value{} }\nfunc (*float32Value) ProtoMessage()  {}\nfunc (*float32Value) String() string { return \"float32<string>\" }\n\ntype int64Value struct {\n\tValue int64 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *int64Value) Reset()       { *m = int64Value{} }\nfunc (*int64Value) ProtoMessage()  {}\nfunc (*int64Value) String() string { return \"int64<string>\" }\n\ntype uint64Value struct {\n\tValue uint64 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *uint64Value) Reset()       { *m = uint64Value{} }\nfunc (*uint64Value) ProtoMessage()  {}\nfunc (*uint64Value) String() string { return \"uint64<string>\" }\n\ntype int32Value struct {\n\tValue int32 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *int32Value) Reset()       { *m = int32Value{} }\nfunc (*int32Value) ProtoMessage()  {}\nfunc (*int32Value) String() string { return \"int32<string>\" }\n\ntype uint32Value struct {\n\tValue uint32 `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *uint32Value) Reset()       { *m = uint32Value{} }\nfunc (*uint32Value) ProtoMessage()  {}\nfunc (*uint32Value) String() string { return \"uint32<string>\" }\n\ntype boolValue struct {\n\tValue bool `protobuf:\"varint,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *boolValue) Reset()       { *m = boolValue{} }\nfunc (*boolValue) ProtoMessage()  {}\nfunc (*boolValue) String() string { return \"bool<string>\" }\n\ntype stringValue struct {\n\tValue string `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *stringValue) Reset()       { *m = stringValue{} }\nfunc (*stringValue) ProtoMessage()  {}\nfunc (*stringValue) String() string { return \"string<string>\" }\n\ntype bytesValue struct {\n\tValue []byte `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (m *bytesValue) Reset()       { *m = bytesValue{} }\nfunc (*bytesValue) ProtoMessage()  {}\nfunc (*bytesValue) String() string { return \"[]byte<string>\" }\n\nfunc init() {\n\tRegisterType((*float64Value)(nil), \"gogo.protobuf.proto.DoubleValue\")\n\tRegisterType((*float32Value)(nil), \"gogo.protobuf.proto.FloatValue\")\n\tRegisterType((*int64Value)(nil), \"gogo.protobuf.proto.Int64Value\")\n\tRegisterType((*uint64Value)(nil), \"gogo.protobuf.proto.UInt64Value\")\n\tRegisterType((*int32Value)(nil), \"gogo.protobuf.proto.Int32Value\")\n\tRegisterType((*uint32Value)(nil), \"gogo.protobuf.proto.UInt32Value\")\n\tRegisterType((*boolValue)(nil), \"gogo.protobuf.proto.BoolValue\")\n\tRegisterType((*stringValue)(nil), \"gogo.protobuf.proto.StringValue\")\n\tRegisterType((*bytesValue)(nil), \"gogo.protobuf.proto.BytesValue\")\n}\n"
  },
  {
    "path": "vendor/github.com/gogo/protobuf/sortkeys/sortkeys.go",
    "content": "// Protocol Buffers for Go with Gadgets\n//\n// Copyright (c) 2013, The GoGo Authors. All rights reserved.\n// http://github.com/gogo/protobuf\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n//     * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n//     * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\npackage sortkeys\n\nimport (\n\t\"sort\"\n)\n\nfunc Strings(l []string) {\n\tsort.Strings(l)\n}\n\nfunc Float64s(l []float64) {\n\tsort.Float64s(l)\n}\n\nfunc Float32s(l []float32) {\n\tsort.Sort(Float32Slice(l))\n}\n\nfunc Int64s(l []int64) {\n\tsort.Sort(Int64Slice(l))\n}\n\nfunc Int32s(l []int32) {\n\tsort.Sort(Int32Slice(l))\n}\n\nfunc Uint64s(l []uint64) {\n\tsort.Sort(Uint64Slice(l))\n}\n\nfunc Uint32s(l []uint32) {\n\tsort.Sort(Uint32Slice(l))\n}\n\nfunc Bools(l []bool) {\n\tsort.Sort(BoolSlice(l))\n}\n\ntype BoolSlice []bool\n\nfunc (p BoolSlice) Len() int           { return len(p) }\nfunc (p BoolSlice) Less(i, j int) bool { return p[j] }\nfunc (p BoolSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\n\ntype Int64Slice []int64\n\nfunc (p Int64Slice) Len() int           { return len(p) }\nfunc (p Int64Slice) Less(i, j int) bool { return p[i] < p[j] }\nfunc (p Int64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\n\ntype Int32Slice []int32\n\nfunc (p Int32Slice) Len() int           { return len(p) }\nfunc (p Int32Slice) Less(i, j int) bool { return p[i] < p[j] }\nfunc (p Int32Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\n\ntype Uint64Slice []uint64\n\nfunc (p Uint64Slice) Len() int           { return len(p) }\nfunc (p Uint64Slice) Less(i, j int) bool { return p[i] < p[j] }\nfunc (p Uint64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\n\ntype Uint32Slice []uint32\n\nfunc (p Uint32Slice) Len() int           { return len(p) }\nfunc (p Uint32Slice) Less(i, j int) bool { return p[i] < p[j] }\nfunc (p Uint32Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\n\ntype Float32Slice []float32\n\nfunc (p Float32Slice) Len() int           { return len(p) }\nfunc (p Float32Slice) Less(i, j int) bool { return p[i] < p[j] }\nfunc (p Float32Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }\n"
  },
  {
    "path": "vendor/github.com/golang/groupcache/LICENSE",
    "content": "Apache License\nVersion 2.0, January 2004\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n1. Definitions.\n\n\"License\" shall mean the terms and conditions for use, reproduction, and\ndistribution as defined by Sections 1 through 9 of this document.\n\n\"Licensor\" shall mean the copyright owner or entity authorized by the copyright\nowner that is granting the License.\n\n\"Legal Entity\" shall mean the union of the acting entity and all other entities\nthat control, are controlled by, or are under common control with that entity.\nFor the purposes of this definition, \"control\" means (i) the power, direct or\nindirect, to cause the direction or management of such entity, whether by\ncontract or otherwise, or (ii) ownership of fifty percent (50%) or more of the\noutstanding shares, or (iii) beneficial ownership of such entity.\n\n\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising\npermissions granted by this License.\n\n\"Source\" form shall mean the preferred form for making modifications, including\nbut not limited to software source code, documentation source, and configuration\nfiles.\n\n\"Object\" form shall mean any form resulting from mechanical transformation or\ntranslation of a Source form, including but not limited to compiled object code,\ngenerated documentation, and conversions to other media types.\n\n\"Work\" shall mean the work of authorship, whether in Source or Object form, made\navailable under the License, as indicated by a copyright notice that is included\nin or attached to the work (an example is provided in the Appendix below).\n\n\"Derivative Works\" shall mean any work, whether in Source or Object form, that\nis based on (or derived from) the Work and for which the editorial revisions,\nannotations, elaborations, or other modifications represent, as a whole, an\noriginal work of authorship. For the purposes of this License, Derivative Works\nshall not include works that remain separable from, or merely link (or bind by\nname) to the interfaces of, the Work and Derivative Works thereof.\n\n\"Contribution\" shall mean any work of authorship, including the original version\nof the Work and any modifications or additions to that Work or Derivative Works\nthereof, that is intentionally submitted to Licensor for inclusion in the Work\nby the copyright owner or by an individual or Legal Entity authorized to submit\non behalf of the copyright owner. For the purposes of this definition,\n\"submitted\" means any form of electronic, verbal, or written communication sent\nto the Licensor or its representatives, including but not limited to\ncommunication on electronic mailing lists, source code control systems, and\nissue tracking systems that are managed by, or on behalf of, the Licensor for\nthe purpose of discussing and improving the Work, but excluding communication\nthat is conspicuously marked or otherwise designated in writing by the copyright\nowner as \"Not a Contribution.\"\n\n\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf\nof whom a Contribution has been received by Licensor and subsequently\nincorporated within the Work.\n\n2. Grant of Copyright License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable copyright license to reproduce, prepare Derivative Works of,\npublicly display, publicly perform, sublicense, and distribute the Work and such\nDerivative Works in Source or Object form.\n\n3. Grant of Patent License.\n\nSubject to the terms and conditions of this License, each Contributor hereby\ngrants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,\nirrevocable (except as stated in this section) patent license to make, have\nmade, use, offer to sell, sell, import, and otherwise transfer the Work, where\nsuch license applies only to those patent claims licensable by such Contributor\nthat are necessarily infringed by their Contribution(s) alone or by combination\nof their Contribution(s) with the Work to which such Contribution(s) was\nsubmitted. If You institute patent litigation against any entity (including a\ncross-claim or counterclaim in a lawsuit) alleging that the Work or a\nContribution incorporated within the Work constitutes direct or contributory\npatent infringement, then any patent licenses granted to You under this License\nfor that Work shall terminate as of the date such litigation is filed.\n\n4. Redistribution.\n\nYou may reproduce and distribute copies of the Work or Derivative Works thereof\nin any medium, with or without modifications, and in Source or Object form,\nprovided that You meet the following conditions:\n\nYou must give any other recipients of the Work or Derivative Works a copy of\nthis License; and\nYou must cause any modified files to carry prominent notices stating that You\nchanged the files; and\nYou must retain, in the Source form of any Derivative Works that You distribute,\nall copyright, patent, trademark, and attribution notices from the Source form\nof the Work, excluding those notices that do not pertain to any part of the\nDerivative Works; and\nIf the Work includes a \"NOTICE\" text file as part of its distribution, then any\nDerivative Works that You distribute must include a readable copy of the\nattribution notices contained within such NOTICE file, excluding those notices\nthat do not pertain to any part of the Derivative Works, in at least one of the\nfollowing places: within a NOTICE text file distributed as part of the\nDerivative Works; within the Source form or documentation, if provided along\nwith the Derivative Works; or, within a display generated by the Derivative\nWorks, if and wherever such third-party notices normally appear. The contents of\nthe NOTICE file are for informational purposes only and do not modify the\nLicense. You may add Your own attribution notices within Derivative Works that\nYou distribute, alongside or as an addendum to the NOTICE text from the Work,\nprovided that such additional attribution notices cannot be construed as\nmodifying the License.\nYou may add Your own copyright statement to Your modifications and may provide\nadditional or different license terms and conditions for use, reproduction, or\ndistribution of Your modifications, or for any such Derivative Works as a whole,\nprovided Your use, reproduction, and distribution of the Work otherwise complies\nwith the conditions stated in this License.\n\n5. Submission of Contributions.\n\nUnless You explicitly state otherwise, any Contribution intentionally submitted\nfor inclusion in the Work by You to the Licensor shall be under the terms and\nconditions of this License, without any additional terms or conditions.\nNotwithstanding the above, nothing herein shall supersede or modify the terms of\nany separate license agreement you may have executed with Licensor regarding\nsuch Contributions.\n\n6. Trademarks.\n\nThis License does not grant permission to use the trade names, trademarks,\nservice marks, or product names of the Licensor, except as required for\nreasonable and customary use in describing the origin of the Work and\nreproducing the content of the NOTICE file.\n\n7. Disclaimer of Warranty.\n\nUnless required by applicable law or agreed to in writing, Licensor provides the\nWork (and each Contributor provides its Contributions) on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,\nincluding, without limitation, any warranties or conditions of TITLE,\nNON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are\nsolely responsible for determining the appropriateness of using or\nredistributing the Work and assume any risks associated with Your exercise of\npermissions under this License.\n\n8. Limitation of Liability.\n\nIn no event and under no legal theory, whether in tort (including negligence),\ncontract, or otherwise, unless required by applicable law (such as deliberate\nand grossly negligent acts) or agreed to in writing, shall any Contributor be\nliable to You for damages, including any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License or\nout of the use or inability to use the Work (including but not limited to\ndamages for loss of goodwill, work stoppage, computer failure or malfunction, or\nany and all other commercial damages or losses), even if such Contributor has\nbeen advised of the possibility of such damages.\n\n9. Accepting Warranty or Additional Liability.\n\nWhile redistributing the Work or Derivative Works thereof, You may choose to\noffer, and charge a fee for, acceptance of support, warranty, indemnity, or\nother liability obligations and/or rights consistent with this License. However,\nin accepting such obligations, You may act only on Your own behalf and on Your\nsole responsibility, not on behalf of any other Contributor, and only if You\nagree to indemnify, defend, and hold each Contributor harmless for any liability\nincurred by, or claims asserted against, such Contributor by reason of your\naccepting any such warranty or additional liability.\n\nEND OF TERMS AND CONDITIONS\n\nAPPENDIX: How to apply the Apache License to your work\n\nTo apply the Apache License to your work, attach the following boilerplate\nnotice, with the fields enclosed by brackets \"[]\" replaced with your own\nidentifying information. (Don't include the brackets!) The text should be\nenclosed in the appropriate comment syntax for the file format. We also\nrecommend that a file or class name and description of purpose be included on\nthe same \"printed page\" as the copyright notice for easier identification within\nthird-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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     http://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": "vendor/github.com/golang/groupcache/lru/lru.go",
    "content": "/*\nCopyright 2013 Google Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n     http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package lru implements an LRU cache.\npackage lru\n\nimport \"container/list\"\n\n// Cache is an LRU cache. It is not safe for concurrent access.\ntype Cache struct {\n\t// MaxEntries is the maximum number of cache entries before\n\t// an item is evicted. Zero means no limit.\n\tMaxEntries int\n\n\t// OnEvicted optionally specifies a callback function to be\n\t// executed when an entry is purged from the cache.\n\tOnEvicted func(key Key, value interface{})\n\n\tll    *list.List\n\tcache map[interface{}]*list.Element\n}\n\n// A Key may be any value that is comparable. See http://golang.org/ref/spec#Comparison_operators\ntype Key interface{}\n\ntype entry struct {\n\tkey   Key\n\tvalue interface{}\n}\n\n// New creates a new Cache.\n// If maxEntries is zero, the cache has no limit and it's assumed\n// that eviction is done by the caller.\nfunc New(maxEntries int) *Cache {\n\treturn &Cache{\n\t\tMaxEntries: maxEntries,\n\t\tll:         list.New(),\n\t\tcache:      make(map[interface{}]*list.Element),\n\t}\n}\n\n// Add adds a value to the cache.\nfunc (c *Cache) Add(key Key, value interface{}) {\n\tif c.cache == nil {\n\t\tc.cache = make(map[interface{}]*list.Element)\n\t\tc.ll = list.New()\n\t}\n\tif ee, ok := c.cache[key]; ok {\n\t\tc.ll.MoveToFront(ee)\n\t\tee.Value.(*entry).value = value\n\t\treturn\n\t}\n\tele := c.ll.PushFront(&entry{key, value})\n\tc.cache[key] = ele\n\tif c.MaxEntries != 0 && c.ll.Len() > c.MaxEntries {\n\t\tc.RemoveOldest()\n\t}\n}\n\n// Get looks up a key's value from the cache.\nfunc (c *Cache) Get(key Key) (value interface{}, ok bool) {\n\tif c.cache == nil {\n\t\treturn\n\t}\n\tif ele, hit := c.cache[key]; hit {\n\t\tc.ll.MoveToFront(ele)\n\t\treturn ele.Value.(*entry).value, true\n\t}\n\treturn\n}\n\n// Remove removes the provided key from the cache.\nfunc (c *Cache) Remove(key Key) {\n\tif c.cache == nil {\n\t\treturn\n\t}\n\tif ele, hit := c.cache[key]; hit {\n\t\tc.removeElement(ele)\n\t}\n}\n\n// RemoveOldest removes the oldest item from the cache.\nfunc (c *Cache) RemoveOldest() {\n\tif c.cache == nil {\n\t\treturn\n\t}\n\tele := c.ll.Back()\n\tif ele != nil {\n\t\tc.removeElement(ele)\n\t}\n}\n\nfunc (c *Cache) removeElement(e *list.Element) {\n\tc.ll.Remove(e)\n\tkv := e.Value.(*entry)\n\tdelete(c.cache, kv.key)\n\tif c.OnEvicted != nil {\n\t\tc.OnEvicted(kv.key, kv.value)\n\t}\n}\n\n// Len returns the number of items in the cache.\nfunc (c *Cache) Len() int {\n\tif c.cache == nil {\n\t\treturn 0\n\t}\n\treturn c.ll.Len()\n}\n\n// Clear purges all stored items from the cache.\nfunc (c *Cache) Clear() {\n\tif c.OnEvicted != nil {\n\t\tfor _, e := range c.cache {\n\t\t\tkv := e.Value.(*entry)\n\t\t\tc.OnEvicted(kv.key, kv.value)\n\t\t}\n\t}\n\tc.ll = nil\n\tc.cache = nil\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/AUTHORS",
    "content": "# This source code refers to The Go Authors for copyright purposes.\n# The master list of authors is in the main Go distribution,\n# visible at http://tip.golang.org/AUTHORS.\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/CONTRIBUTORS",
    "content": "# This source code was written by the Go contributors.\n# The master list of contributors is in the main Go distribution,\n# visible at http://tip.golang.org/CONTRIBUTORS.\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/LICENSE",
    "content": "Copyright 2010 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    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * 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    * 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\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/buffer.go",
    "content": "// Copyright 2019 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 proto\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"google.golang.org/protobuf/encoding/prototext\"\n\t\"google.golang.org/protobuf/encoding/protowire\"\n\t\"google.golang.org/protobuf/runtime/protoimpl\"\n)\n\nconst (\n\tWireVarint     = 0\n\tWireFixed32    = 5\n\tWireFixed64    = 1\n\tWireBytes      = 2\n\tWireStartGroup = 3\n\tWireEndGroup   = 4\n)\n\n// EncodeVarint returns the varint encoded bytes of v.\nfunc EncodeVarint(v uint64) []byte {\n\treturn protowire.AppendVarint(nil, v)\n}\n\n// SizeVarint returns the length of the varint encoded bytes of v.\n// This is equal to len(EncodeVarint(v)).\nfunc SizeVarint(v uint64) int {\n\treturn protowire.SizeVarint(v)\n}\n\n// DecodeVarint parses a varint encoded integer from b,\n// returning the integer value and the length of the varint.\n// It returns (0, 0) if there is a parse error.\nfunc DecodeVarint(b []byte) (uint64, int) {\n\tv, n := protowire.ConsumeVarint(b)\n\tif n < 0 {\n\t\treturn 0, 0\n\t}\n\treturn v, n\n}\n\n// Buffer is a buffer for encoding and decoding the protobuf wire format.\n// It may be reused between invocations to reduce memory usage.\ntype Buffer struct {\n\tbuf           []byte\n\tidx           int\n\tdeterministic bool\n}\n\n// NewBuffer allocates a new Buffer initialized with buf,\n// where the contents of buf are considered the unread portion of the buffer.\nfunc NewBuffer(buf []byte) *Buffer {\n\treturn &Buffer{buf: buf}\n}\n\n// SetDeterministic specifies whether to use deterministic serialization.\n//\n// Deterministic serialization guarantees that for a given binary, equal\n// messages will always be serialized to the same bytes. This implies:\n//\n//   - Repeated serialization of a message will return the same bytes.\n//   - Different processes of the same binary (which may be executing on\n//     different machines) will serialize equal messages to the same bytes.\n//\n// Note that the deterministic serialization is NOT canonical across\n// languages. It is not guaranteed to remain stable over time. It is unstable\n// across different builds with schema changes due to unknown fields.\n// Users who need canonical serialization (e.g., persistent storage in a\n// canonical form, fingerprinting, etc.) should define their own\n// canonicalization specification and implement their own serializer rather\n// than relying on this API.\n//\n// If deterministic serialization is requested, map entries will be sorted\n// by keys in lexographical order. This is an implementation detail and\n// subject to change.\nfunc (b *Buffer) SetDeterministic(deterministic bool) {\n\tb.deterministic = deterministic\n}\n\n// SetBuf sets buf as the internal buffer,\n// where the contents of buf are considered the unread portion of the buffer.\nfunc (b *Buffer) SetBuf(buf []byte) {\n\tb.buf = buf\n\tb.idx = 0\n}\n\n// Reset clears the internal buffer of all written and unread data.\nfunc (b *Buffer) Reset() {\n\tb.buf = b.buf[:0]\n\tb.idx = 0\n}\n\n// Bytes returns the internal buffer.\nfunc (b *Buffer) Bytes() []byte {\n\treturn b.buf\n}\n\n// Unread returns the unread portion of the buffer.\nfunc (b *Buffer) Unread() []byte {\n\treturn b.buf[b.idx:]\n}\n\n// Marshal appends the wire-format encoding of m to the buffer.\nfunc (b *Buffer) Marshal(m Message) error {\n\tvar err error\n\tb.buf, err = marshalAppend(b.buf, m, b.deterministic)\n\treturn err\n}\n\n// Unmarshal parses the wire-format message in the buffer and\n// places the decoded results in m.\n// It does not reset m before unmarshaling.\nfunc (b *Buffer) Unmarshal(m Message) error {\n\terr := UnmarshalMerge(b.Unread(), m)\n\tb.idx = len(b.buf)\n\treturn err\n}\n\ntype unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields }\n\nfunc (m *unknownFields) String() string { panic(\"not implemented\") }\nfunc (m *unknownFields) Reset()         { panic(\"not implemented\") }\nfunc (m *unknownFields) ProtoMessage()  { panic(\"not implemented\") }\n\n// DebugPrint dumps the encoded bytes of b with a header and footer including s\n// to stdout. This is only intended for debugging.\nfunc (*Buffer) DebugPrint(s string, b []byte) {\n\tm := MessageReflect(new(unknownFields))\n\tm.SetUnknown(b)\n\tb, _ = prototext.MarshalOptions{AllowPartial: true, Indent: \"\\t\"}.Marshal(m.Interface())\n\tfmt.Printf(\"==== %s ====\\n%s==== %s ====\\n\", s, b, s)\n}\n\n// EncodeVarint appends an unsigned varint encoding to the buffer.\nfunc (b *Buffer) EncodeVarint(v uint64) error {\n\tb.buf = protowire.AppendVarint(b.buf, v)\n\treturn nil\n}\n\n// EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer.\nfunc (b *Buffer) EncodeZigzag32(v uint64) error {\n\treturn b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))\n}\n\n// EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer.\nfunc (b *Buffer) EncodeZigzag64(v uint64) error {\n\treturn b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63))))\n}\n\n// EncodeFixed32 appends a 32-bit little-endian integer to the buffer.\nfunc (b *Buffer) EncodeFixed32(v uint64) error {\n\tb.buf = protowire.AppendFixed32(b.buf, uint32(v))\n\treturn nil\n}\n\n// EncodeFixed64 appends a 64-bit little-endian integer to the buffer.\nfunc (b *Buffer) EncodeFixed64(v uint64) error {\n\tb.buf = protowire.AppendFixed64(b.buf, uint64(v))\n\treturn nil\n}\n\n// EncodeRawBytes appends a length-prefixed raw bytes to the buffer.\nfunc (b *Buffer) EncodeRawBytes(v []byte) error {\n\tb.buf = protowire.AppendBytes(b.buf, v)\n\treturn nil\n}\n\n// EncodeStringBytes appends a length-prefixed raw bytes to the buffer.\n// It does not validate whether v contains valid UTF-8.\nfunc (b *Buffer) EncodeStringBytes(v string) error {\n\tb.buf = protowire.AppendString(b.buf, v)\n\treturn nil\n}\n\n// EncodeMessage appends a length-prefixed encoded message to the buffer.\nfunc (b *Buffer) EncodeMessage(m Message) error {\n\tvar err error\n\tb.buf = protowire.AppendVarint(b.buf, uint64(Size(m)))\n\tb.buf, err = marshalAppend(b.buf, m, b.deterministic)\n\treturn err\n}\n\n// DecodeVarint consumes an encoded unsigned varint from the buffer.\nfunc (b *Buffer) DecodeVarint() (uint64, error) {\n\tv, n := protowire.ConsumeVarint(b.buf[b.idx:])\n\tif n < 0 {\n\t\treturn 0, protowire.ParseError(n)\n\t}\n\tb.idx += n\n\treturn uint64(v), nil\n}\n\n// DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer.\nfunc (b *Buffer) DecodeZigzag32() (uint64, error) {\n\tv, err := b.DecodeVarint()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil\n}\n\n// DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer.\nfunc (b *Buffer) DecodeZigzag64() (uint64, error) {\n\tv, err := b.DecodeVarint()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil\n}\n\n// DecodeFixed32 consumes a 32-bit little-endian integer from the buffer.\nfunc (b *Buffer) DecodeFixed32() (uint64, error) {\n\tv, n := protowire.ConsumeFixed32(b.buf[b.idx:])\n\tif n < 0 {\n\t\treturn 0, protowire.ParseError(n)\n\t}\n\tb.idx += n\n\treturn uint64(v), nil\n}\n\n// DecodeFixed64 consumes a 64-bit little-endian integer from the buffer.\nfunc (b *Buffer) DecodeFixed64() (uint64, error) {\n\tv, n := protowire.ConsumeFixed64(b.buf[b.idx:])\n\tif n < 0 {\n\t\treturn 0, protowire.ParseError(n)\n\t}\n\tb.idx += n\n\treturn uint64(v), nil\n}\n\n// DecodeRawBytes consumes a length-prefixed raw bytes from the buffer.\n// If alloc is specified, it returns a copy the raw bytes\n// rather than a sub-slice of the buffer.\nfunc (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) {\n\tv, n := protowire.ConsumeBytes(b.buf[b.idx:])\n\tif n < 0 {\n\t\treturn nil, protowire.ParseError(n)\n\t}\n\tb.idx += n\n\tif alloc {\n\t\tv = append([]byte(nil), v...)\n\t}\n\treturn v, nil\n}\n\n// DecodeStringBytes consumes a length-prefixed raw bytes from the buffer.\n// It does not validate whether the raw bytes contain valid UTF-8.\nfunc (b *Buffer) DecodeStringBytes() (string, error) {\n\tv, n := protowire.ConsumeString(b.buf[b.idx:])\n\tif n < 0 {\n\t\treturn \"\", protowire.ParseError(n)\n\t}\n\tb.idx += n\n\treturn v, nil\n}\n\n// DecodeMessage consumes a length-prefixed message from the buffer.\n// It does not reset m before unmarshaling.\nfunc (b *Buffer) DecodeMessage(m Message) error {\n\tv, err := b.DecodeRawBytes(false)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn UnmarshalMerge(v, m)\n}\n\n// DecodeGroup consumes a message group from the buffer.\n// It assumes that the start group marker has already been consumed and\n// consumes all bytes until (and including the end group marker).\n// It does not reset m before unmarshaling.\nfunc (b *Buffer) DecodeGroup(m Message) error {\n\tv, n, err := consumeGroup(b.buf[b.idx:])\n\tif err != nil {\n\t\treturn err\n\t}\n\tb.idx += n\n\treturn UnmarshalMerge(v, m)\n}\n\n// consumeGroup parses b until it finds an end group marker, returning\n// the raw bytes of the message (excluding the end group marker) and the\n// the total length of the message (including the end group marker).\nfunc consumeGroup(b []byte) ([]byte, int, error) {\n\tb0 := b\n\tdepth := 1 // assume this follows a start group marker\n\tfor {\n\t\t_, wtyp, tagLen := protowire.ConsumeTag(b)\n\t\tif tagLen < 0 {\n\t\t\treturn nil, 0, protowire.ParseError(tagLen)\n\t\t}\n\t\tb = b[tagLen:]\n\n\t\tvar valLen int\n\t\tswitch wtyp {\n\t\tcase protowire.VarintType:\n\t\t\t_, valLen = protowire.ConsumeVarint(b)\n\t\tcase protowire.Fixed32Type:\n\t\t\t_, valLen = protowire.ConsumeFixed32(b)\n\t\tcase protowire.Fixed64Type:\n\t\t\t_, valLen = protowire.ConsumeFixed64(b)\n\t\tcase protowire.BytesType:\n\t\t\t_, valLen = protowire.ConsumeBytes(b)\n\t\tcase protowire.StartGroupType:\n\t\t\tdepth++\n\t\tcase protowire.EndGroupType:\n\t\t\tdepth--\n\t\tdefault:\n\t\t\treturn nil, 0, errors.New(\"proto: cannot parse reserved wire type\")\n\t\t}\n\t\tif valLen < 0 {\n\t\t\treturn nil, 0, protowire.ParseError(valLen)\n\t\t}\n\t\tb = b[valLen:]\n\n\t\tif depth == 0 {\n\t\t\treturn b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/defaults.go",
    "content": "// Copyright 2019 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 proto\n\nimport (\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n)\n\n// SetDefaults sets unpopulated scalar fields to their default values.\n// Fields within a oneof are not set even if they have a default value.\n// SetDefaults is recursively called upon any populated message fields.\nfunc SetDefaults(m Message) {\n\tif m != nil {\n\t\tsetDefaults(MessageReflect(m))\n\t}\n}\n\nfunc setDefaults(m protoreflect.Message) {\n\tfds := m.Descriptor().Fields()\n\tfor i := 0; i < fds.Len(); i++ {\n\t\tfd := fds.Get(i)\n\t\tif !m.Has(fd) {\n\t\t\tif fd.HasDefault() && fd.ContainingOneof() == nil {\n\t\t\t\tv := fd.Default()\n\t\t\t\tif fd.Kind() == protoreflect.BytesKind {\n\t\t\t\t\tv = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes\n\t\t\t\t}\n\t\t\t\tm.Set(fd, v)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t}\n\n\tm.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {\n\t\tswitch {\n\t\t// Handle singular message.\n\t\tcase fd.Cardinality() != protoreflect.Repeated:\n\t\t\tif fd.Message() != nil {\n\t\t\t\tsetDefaults(m.Get(fd).Message())\n\t\t\t}\n\t\t// Handle list of messages.\n\t\tcase fd.IsList():\n\t\t\tif fd.Message() != nil {\n\t\t\t\tls := m.Get(fd).List()\n\t\t\t\tfor i := 0; i < ls.Len(); i++ {\n\t\t\t\t\tsetDefaults(ls.Get(i).Message())\n\t\t\t\t}\n\t\t\t}\n\t\t// Handle map of messages.\n\t\tcase fd.IsMap():\n\t\t\tif fd.MapValue().Message() != nil {\n\t\t\t\tms := m.Get(fd).Map()\n\t\t\t\tms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {\n\t\t\t\t\tsetDefaults(v.Message())\n\t\t\t\t\treturn true\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn true\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/deprecated.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\npackage proto\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strconv\"\n\n\tprotoV2 \"google.golang.org/protobuf/proto\"\n)\n\nvar (\n\t// Deprecated: No longer returned.\n\tErrNil = errors.New(\"proto: Marshal called with nil\")\n\n\t// Deprecated: No longer returned.\n\tErrTooLarge = errors.New(\"proto: message encodes to over 2 GB\")\n\n\t// Deprecated: No longer returned.\n\tErrInternalBadWireType = errors.New(\"proto: internal error: bad wiretype for oneof\")\n)\n\n// Deprecated: Do not use.\ntype Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }\n\n// Deprecated: Do not use.\nfunc GetStats() Stats { return Stats{} }\n\n// Deprecated: Do not use.\nfunc MarshalMessageSet(interface{}) ([]byte, error) {\n\treturn nil, errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: Do not use.\nfunc UnmarshalMessageSet([]byte, interface{}) error {\n\treturn errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: Do not use.\nfunc MarshalMessageSetJSON(interface{}) ([]byte, error) {\n\treturn nil, errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: Do not use.\nfunc UnmarshalMessageSetJSON([]byte, interface{}) error {\n\treturn errors.New(\"proto: not implemented\")\n}\n\n// Deprecated: Do not use.\nfunc RegisterMessageSetType(Message, int32, string) {}\n\n// Deprecated: Do not use.\nfunc EnumName(m map[int32]string, v int32) string {\n\ts, ok := m[v]\n\tif ok {\n\t\treturn s\n\t}\n\treturn strconv.Itoa(int(v))\n}\n\n// Deprecated: Do not use.\nfunc UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {\n\tif data[0] == '\"' {\n\t\t// New style: enums are strings.\n\t\tvar repr string\n\t\tif err := json.Unmarshal(data, &repr); err != nil {\n\t\t\treturn -1, err\n\t\t}\n\t\tval, ok := m[repr]\n\t\tif !ok {\n\t\t\treturn 0, fmt.Errorf(\"unrecognized enum %s value %q\", enumName, repr)\n\t\t}\n\t\treturn val, nil\n\t}\n\t// Old style: enums are ints.\n\tvar val int32\n\tif err := json.Unmarshal(data, &val); err != nil {\n\t\treturn 0, fmt.Errorf(\"cannot unmarshal %#q into enum %s\", data, enumName)\n\t}\n\treturn val, nil\n}\n\n// Deprecated: Do not use; this type existed for intenal-use only.\ntype InternalMessageInfo struct{}\n\n// Deprecated: Do not use; this method existed for intenal-use only.\nfunc (*InternalMessageInfo) DiscardUnknown(m Message) {\n\tDiscardUnknown(m)\n}\n\n// Deprecated: Do not use; this method existed for intenal-use only.\nfunc (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) {\n\treturn protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m))\n}\n\n// Deprecated: Do not use; this method existed for intenal-use only.\nfunc (*InternalMessageInfo) Merge(dst, src Message) {\n\tprotoV2.Merge(MessageV2(dst), MessageV2(src))\n}\n\n// Deprecated: Do not use; this method existed for intenal-use only.\nfunc (*InternalMessageInfo) Size(m Message) int {\n\treturn protoV2.Size(MessageV2(m))\n}\n\n// Deprecated: Do not use; this method existed for intenal-use only.\nfunc (*InternalMessageInfo) Unmarshal(m Message, b []byte) error {\n\treturn protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m))\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/discard.go",
    "content": "// Copyright 2019 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 proto\n\nimport (\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n)\n\n// DiscardUnknown recursively discards all unknown fields from this message\n// and all embedded messages.\n//\n// When unmarshaling a message with unrecognized fields, the tags and values\n// of such fields are preserved in the Message. This allows a later call to\n// marshal to be able to produce a message that continues to have those\n// unrecognized fields. To avoid this, DiscardUnknown is used to\n// explicitly clear the unknown fields after unmarshaling.\nfunc DiscardUnknown(m Message) {\n\tif m != nil {\n\t\tdiscardUnknown(MessageReflect(m))\n\t}\n}\n\nfunc discardUnknown(m protoreflect.Message) {\n\tm.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool {\n\t\tswitch {\n\t\t// Handle singular message.\n\t\tcase fd.Cardinality() != protoreflect.Repeated:\n\t\t\tif fd.Message() != nil {\n\t\t\t\tdiscardUnknown(m.Get(fd).Message())\n\t\t\t}\n\t\t// Handle list of messages.\n\t\tcase fd.IsList():\n\t\t\tif fd.Message() != nil {\n\t\t\t\tls := m.Get(fd).List()\n\t\t\t\tfor i := 0; i < ls.Len(); i++ {\n\t\t\t\t\tdiscardUnknown(ls.Get(i).Message())\n\t\t\t\t}\n\t\t\t}\n\t\t// Handle map of messages.\n\t\tcase fd.IsMap():\n\t\t\tif fd.MapValue().Message() != nil {\n\t\t\t\tms := m.Get(fd).Map()\n\t\t\t\tms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {\n\t\t\t\t\tdiscardUnknown(v.Message())\n\t\t\t\t\treturn true\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\treturn true\n\t})\n\n\t// Discard unknown fields.\n\tif len(m.GetUnknown()) > 0 {\n\t\tm.SetUnknown(nil)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/extensions.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 proto\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"google.golang.org/protobuf/encoding/protowire\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/reflect/protoregistry\"\n\t\"google.golang.org/protobuf/runtime/protoiface\"\n\t\"google.golang.org/protobuf/runtime/protoimpl\"\n)\n\ntype (\n\t// ExtensionDesc represents an extension descriptor and\n\t// is used to interact with an extension field in a message.\n\t//\n\t// Variables of this type are generated in code by protoc-gen-go.\n\tExtensionDesc = protoimpl.ExtensionInfo\n\n\t// ExtensionRange represents a range of message extensions.\n\t// Used in code generated by protoc-gen-go.\n\tExtensionRange = protoiface.ExtensionRangeV1\n\n\t// Deprecated: Do not use; this is an internal type.\n\tExtension = protoimpl.ExtensionFieldV1\n\n\t// Deprecated: Do not use; this is an internal type.\n\tXXX_InternalExtensions = protoimpl.ExtensionFields\n)\n\n// ErrMissingExtension reports whether the extension was not present.\nvar ErrMissingExtension = errors.New(\"proto: missing extension\")\n\nvar errNotExtendable = errors.New(\"proto: not an extendable proto.Message\")\n\n// HasExtension reports whether the extension field is present in m\n// either as an explicitly populated field or as an unknown field.\nfunc HasExtension(m Message, xt *ExtensionDesc) (has bool) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() {\n\t\treturn false\n\t}\n\n\t// Check whether any populated known field matches the field number.\n\txtd := xt.TypeDescriptor()\n\tif isValidExtension(mr.Descriptor(), xtd) {\n\t\thas = mr.Has(xtd)\n\t} else {\n\t\tmr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {\n\t\t\thas = int32(fd.Number()) == xt.Field\n\t\t\treturn !has\n\t\t})\n\t}\n\n\t// Check whether any unknown field matches the field number.\n\tfor b := mr.GetUnknown(); !has && len(b) > 0; {\n\t\tnum, _, n := protowire.ConsumeField(b)\n\t\thas = int32(num) == xt.Field\n\t\tb = b[n:]\n\t}\n\treturn has\n}\n\n// ClearExtension removes the extension field from m\n// either as an explicitly populated field or as an unknown field.\nfunc ClearExtension(m Message, xt *ExtensionDesc) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() {\n\t\treturn\n\t}\n\n\txtd := xt.TypeDescriptor()\n\tif isValidExtension(mr.Descriptor(), xtd) {\n\t\tmr.Clear(xtd)\n\t} else {\n\t\tmr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {\n\t\t\tif int32(fd.Number()) == xt.Field {\n\t\t\t\tmr.Clear(fd)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\t})\n\t}\n\tclearUnknown(mr, fieldNum(xt.Field))\n}\n\n// ClearAllExtensions clears all extensions from m.\n// This includes populated fields and unknown fields in the extension range.\nfunc ClearAllExtensions(m Message) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() {\n\t\treturn\n\t}\n\n\tmr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool {\n\t\tif fd.IsExtension() {\n\t\t\tmr.Clear(fd)\n\t\t}\n\t\treturn true\n\t})\n\tclearUnknown(mr, mr.Descriptor().ExtensionRanges())\n}\n\n// GetExtension retrieves a proto2 extended field from m.\n//\n// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),\n// then GetExtension parses the encoded field and returns a Go value of the specified type.\n// If the field is not present, then the default value is returned (if one is specified),\n// otherwise ErrMissingExtension is reported.\n//\n// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil),\n// then GetExtension returns the raw encoded bytes for the extension field.\nfunc GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {\n\t\treturn nil, errNotExtendable\n\t}\n\n\t// Retrieve the unknown fields for this extension field.\n\tvar bo protoreflect.RawFields\n\tfor bi := mr.GetUnknown(); len(bi) > 0; {\n\t\tnum, _, n := protowire.ConsumeField(bi)\n\t\tif int32(num) == xt.Field {\n\t\t\tbo = append(bo, bi[:n]...)\n\t\t}\n\t\tbi = bi[n:]\n\t}\n\n\t// For type incomplete descriptors, only retrieve the unknown fields.\n\tif xt.ExtensionType == nil {\n\t\treturn []byte(bo), nil\n\t}\n\n\t// If the extension field only exists as unknown fields, unmarshal it.\n\t// This is rarely done since proto.Unmarshal eagerly unmarshals extensions.\n\txtd := xt.TypeDescriptor()\n\tif !isValidExtension(mr.Descriptor(), xtd) {\n\t\treturn nil, fmt.Errorf(\"proto: bad extended type; %T does not extend %T\", xt.ExtendedType, m)\n\t}\n\tif !mr.Has(xtd) && len(bo) > 0 {\n\t\tm2 := mr.New()\n\t\tif err := (proto.UnmarshalOptions{\n\t\t\tResolver: extensionResolver{xt},\n\t\t}.Unmarshal(bo, m2.Interface())); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif m2.Has(xtd) {\n\t\t\tmr.Set(xtd, m2.Get(xtd))\n\t\t\tclearUnknown(mr, fieldNum(xt.Field))\n\t\t}\n\t}\n\n\t// Check whether the message has the extension field set or a default.\n\tvar pv protoreflect.Value\n\tswitch {\n\tcase mr.Has(xtd):\n\t\tpv = mr.Get(xtd)\n\tcase xtd.HasDefault():\n\t\tpv = xtd.Default()\n\tdefault:\n\t\treturn nil, ErrMissingExtension\n\t}\n\n\tv := xt.InterfaceOf(pv)\n\trv := reflect.ValueOf(v)\n\tif isScalarKind(rv.Kind()) {\n\t\trv2 := reflect.New(rv.Type())\n\t\trv2.Elem().Set(rv)\n\t\tv = rv2.Interface()\n\t}\n\treturn v, nil\n}\n\n// extensionResolver is a custom extension resolver that stores a single\n// extension type that takes precedence over the global registry.\ntype extensionResolver struct{ xt protoreflect.ExtensionType }\n\nfunc (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) {\n\tif xtd := r.xt.TypeDescriptor(); xtd.FullName() == field {\n\t\treturn r.xt, nil\n\t}\n\treturn protoregistry.GlobalTypes.FindExtensionByName(field)\n}\n\nfunc (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) {\n\tif xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field {\n\t\treturn r.xt, nil\n\t}\n\treturn protoregistry.GlobalTypes.FindExtensionByNumber(message, field)\n}\n\n// GetExtensions returns a list of the extensions values present in m,\n// corresponding with the provided list of extension descriptors, xts.\n// If an extension is missing in m, the corresponding value is nil.\nfunc GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() {\n\t\treturn nil, errNotExtendable\n\t}\n\n\tvs := make([]interface{}, len(xts))\n\tfor i, xt := range xts {\n\t\tv, err := GetExtension(m, xt)\n\t\tif err != nil {\n\t\t\tif err == ErrMissingExtension {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn vs, err\n\t\t}\n\t\tvs[i] = v\n\t}\n\treturn vs, nil\n}\n\n// SetExtension sets an extension field in m to the provided value.\nfunc SetExtension(m Message, xt *ExtensionDesc, v interface{}) error {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {\n\t\treturn errNotExtendable\n\t}\n\n\trv := reflect.ValueOf(v)\n\tif reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) {\n\t\treturn fmt.Errorf(\"proto: bad extension value type. got: %T, want: %T\", v, xt.ExtensionType)\n\t}\n\tif rv.Kind() == reflect.Ptr {\n\t\tif rv.IsNil() {\n\t\t\treturn fmt.Errorf(\"proto: SetExtension called with nil value of type %T\", v)\n\t\t}\n\t\tif isScalarKind(rv.Elem().Kind()) {\n\t\t\tv = rv.Elem().Interface()\n\t\t}\n\t}\n\n\txtd := xt.TypeDescriptor()\n\tif !isValidExtension(mr.Descriptor(), xtd) {\n\t\treturn fmt.Errorf(\"proto: bad extended type; %T does not extend %T\", xt.ExtendedType, m)\n\t}\n\tmr.Set(xtd, xt.ValueOf(v))\n\tclearUnknown(mr, fieldNum(xt.Field))\n\treturn nil\n}\n\n// SetRawExtension inserts b into the unknown fields of m.\n//\n// Deprecated: Use Message.ProtoReflect.SetUnknown instead.\nfunc SetRawExtension(m Message, fnum int32, b []byte) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() {\n\t\treturn\n\t}\n\n\t// Verify that the raw field is valid.\n\tfor b0 := b; len(b0) > 0; {\n\t\tnum, _, n := protowire.ConsumeField(b0)\n\t\tif int32(num) != fnum {\n\t\t\tpanic(fmt.Sprintf(\"mismatching field number: got %d, want %d\", num, fnum))\n\t\t}\n\t\tb0 = b0[n:]\n\t}\n\n\tClearExtension(m, &ExtensionDesc{Field: fnum})\n\tmr.SetUnknown(append(mr.GetUnknown(), b...))\n}\n\n// ExtensionDescs returns a list of extension descriptors found in m,\n// containing descriptors for both populated extension fields in m and\n// also unknown fields of m that are in the extension range.\n// For the later case, an type incomplete descriptor is provided where only\n// the ExtensionDesc.Field field is populated.\n// The order of the extension descriptors is undefined.\nfunc ExtensionDescs(m Message) ([]*ExtensionDesc, error) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 {\n\t\treturn nil, errNotExtendable\n\t}\n\n\t// Collect a set of known extension descriptors.\n\textDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc)\n\tmr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {\n\t\tif fd.IsExtension() {\n\t\t\txt := fd.(protoreflect.ExtensionTypeDescriptor)\n\t\t\tif xd, ok := xt.Type().(*ExtensionDesc); ok {\n\t\t\t\textDescs[fd.Number()] = xd\n\t\t\t}\n\t\t}\n\t\treturn true\n\t})\n\n\t// Collect a set of unknown extension descriptors.\n\textRanges := mr.Descriptor().ExtensionRanges()\n\tfor b := mr.GetUnknown(); len(b) > 0; {\n\t\tnum, _, n := protowire.ConsumeField(b)\n\t\tif extRanges.Has(num) && extDescs[num] == nil {\n\t\t\textDescs[num] = nil\n\t\t}\n\t\tb = b[n:]\n\t}\n\n\t// Transpose the set of descriptors into a list.\n\tvar xts []*ExtensionDesc\n\tfor num, xt := range extDescs {\n\t\tif xt == nil {\n\t\t\txt = &ExtensionDesc{Field: int32(num)}\n\t\t}\n\t\txts = append(xts, xt)\n\t}\n\treturn xts, nil\n}\n\n// isValidExtension reports whether xtd is a valid extension descriptor for md.\nfunc isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool {\n\treturn xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number())\n}\n\n// isScalarKind reports whether k is a protobuf scalar kind (except bytes).\n// This function exists for historical reasons since the representation of\n// scalars differs between v1 and v2, where v1 uses *T and v2 uses T.\nfunc isScalarKind(k reflect.Kind) bool {\n\tswitch k {\n\tcase reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// clearUnknown removes unknown fields from m where remover.Has reports true.\nfunc clearUnknown(m protoreflect.Message, remover interface {\n\tHas(protoreflect.FieldNumber) bool\n}) {\n\tvar bo protoreflect.RawFields\n\tfor bi := m.GetUnknown(); len(bi) > 0; {\n\t\tnum, _, n := protowire.ConsumeField(bi)\n\t\tif !remover.Has(num) {\n\t\t\tbo = append(bo, bi[:n]...)\n\t\t}\n\t\tbi = bi[n:]\n\t}\n\tif bi := m.GetUnknown(); len(bi) != len(bo) {\n\t\tm.SetUnknown(bo)\n\t}\n}\n\ntype fieldNum protoreflect.FieldNumber\n\nfunc (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool {\n\treturn protoreflect.FieldNumber(n1) == n2\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/properties.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 proto\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/runtime/protoimpl\"\n)\n\n// StructProperties represents protocol buffer type information for a\n// generated protobuf message in the open-struct API.\n//\n// Deprecated: Do not use.\ntype StructProperties struct {\n\t// Prop are the properties for each field.\n\t//\n\t// Fields belonging to a oneof are stored in OneofTypes instead, with a\n\t// single Properties representing the parent oneof held here.\n\t//\n\t// The order of Prop matches the order of fields in the Go struct.\n\t// Struct fields that are not related to protobufs have a \"XXX_\" prefix\n\t// in the Properties.Name and must be ignored by the user.\n\tProp []*Properties\n\n\t// OneofTypes contains information about the oneof fields in this message.\n\t// It is keyed by the protobuf field name.\n\tOneofTypes map[string]*OneofProperties\n}\n\n// Properties represents the type information for a protobuf message field.\n//\n// Deprecated: Do not use.\ntype Properties struct {\n\t// Name is a placeholder name with little meaningful semantic value.\n\t// If the name has an \"XXX_\" prefix, the entire Properties must be ignored.\n\tName string\n\t// OrigName is the protobuf field name or oneof name.\n\tOrigName string\n\t// JSONName is the JSON name for the protobuf field.\n\tJSONName string\n\t// Enum is a placeholder name for enums.\n\t// For historical reasons, this is neither the Go name for the enum,\n\t// nor the protobuf name for the enum.\n\tEnum string // Deprecated: Do not use.\n\t// Weak contains the full name of the weakly referenced message.\n\tWeak string\n\t// Wire is a string representation of the wire type.\n\tWire string\n\t// WireType is the protobuf wire type for the field.\n\tWireType int\n\t// Tag is the protobuf field number.\n\tTag int\n\t// Required reports whether this is a required field.\n\tRequired bool\n\t// Optional reports whether this is a optional field.\n\tOptional bool\n\t// Repeated reports whether this is a repeated field.\n\tRepeated bool\n\t// Packed reports whether this is a packed repeated field of scalars.\n\tPacked bool\n\t// Proto3 reports whether this field operates under the proto3 syntax.\n\tProto3 bool\n\t// Oneof reports whether this field belongs within a oneof.\n\tOneof bool\n\n\t// Default is the default value in string form.\n\tDefault string\n\t// HasDefault reports whether the field has a default value.\n\tHasDefault bool\n\n\t// MapKeyProp is the properties for the key field for a map field.\n\tMapKeyProp *Properties\n\t// MapValProp is the properties for the value field for a map field.\n\tMapValProp *Properties\n}\n\n// OneofProperties represents the type information for a protobuf oneof.\n//\n// Deprecated: Do not use.\ntype OneofProperties struct {\n\t// Type is a pointer to the generated wrapper type for the field value.\n\t// This is nil for messages that are not in the open-struct API.\n\tType reflect.Type\n\t// Field is the index into StructProperties.Prop for the containing oneof.\n\tField int\n\t// Prop is the properties for the field.\n\tProp *Properties\n}\n\n// String formats the properties in the protobuf struct field tag style.\nfunc (p *Properties) String() string {\n\ts := p.Wire\n\ts += \",\" + strconv.Itoa(p.Tag)\n\tif p.Required {\n\t\ts += \",req\"\n\t}\n\tif p.Optional {\n\t\ts += \",opt\"\n\t}\n\tif p.Repeated {\n\t\ts += \",rep\"\n\t}\n\tif p.Packed {\n\t\ts += \",packed\"\n\t}\n\ts += \",name=\" + p.OrigName\n\tif p.JSONName != \"\" {\n\t\ts += \",json=\" + p.JSONName\n\t}\n\tif len(p.Enum) > 0 {\n\t\ts += \",enum=\" + p.Enum\n\t}\n\tif len(p.Weak) > 0 {\n\t\ts += \",weak=\" + p.Weak\n\t}\n\tif p.Proto3 {\n\t\ts += \",proto3\"\n\t}\n\tif p.Oneof {\n\t\ts += \",oneof\"\n\t}\n\tif p.HasDefault {\n\t\ts += \",def=\" + p.Default\n\t}\n\treturn s\n}\n\n// Parse populates p by parsing a string in the protobuf struct field tag style.\nfunc (p *Properties) Parse(tag string) {\n\t// For example: \"bytes,49,opt,name=foo,def=hello!\"\n\tfor len(tag) > 0 {\n\t\ti := strings.IndexByte(tag, ',')\n\t\tif i < 0 {\n\t\t\ti = len(tag)\n\t\t}\n\t\tswitch s := tag[:i]; {\n\t\tcase strings.HasPrefix(s, \"name=\"):\n\t\t\tp.OrigName = s[len(\"name=\"):]\n\t\tcase strings.HasPrefix(s, \"json=\"):\n\t\t\tp.JSONName = s[len(\"json=\"):]\n\t\tcase strings.HasPrefix(s, \"enum=\"):\n\t\t\tp.Enum = s[len(\"enum=\"):]\n\t\tcase strings.HasPrefix(s, \"weak=\"):\n\t\t\tp.Weak = s[len(\"weak=\"):]\n\t\tcase strings.Trim(s, \"0123456789\") == \"\":\n\t\t\tn, _ := strconv.ParseUint(s, 10, 32)\n\t\t\tp.Tag = int(n)\n\t\tcase s == \"opt\":\n\t\t\tp.Optional = true\n\t\tcase s == \"req\":\n\t\t\tp.Required = true\n\t\tcase s == \"rep\":\n\t\t\tp.Repeated = true\n\t\tcase s == \"varint\" || s == \"zigzag32\" || s == \"zigzag64\":\n\t\t\tp.Wire = s\n\t\t\tp.WireType = WireVarint\n\t\tcase s == \"fixed32\":\n\t\t\tp.Wire = s\n\t\t\tp.WireType = WireFixed32\n\t\tcase s == \"fixed64\":\n\t\t\tp.Wire = s\n\t\t\tp.WireType = WireFixed64\n\t\tcase s == \"bytes\":\n\t\t\tp.Wire = s\n\t\t\tp.WireType = WireBytes\n\t\tcase s == \"group\":\n\t\t\tp.Wire = s\n\t\t\tp.WireType = WireStartGroup\n\t\tcase s == \"packed\":\n\t\t\tp.Packed = true\n\t\tcase s == \"proto3\":\n\t\t\tp.Proto3 = true\n\t\tcase s == \"oneof\":\n\t\t\tp.Oneof = true\n\t\tcase strings.HasPrefix(s, \"def=\"):\n\t\t\t// The default tag is special in that everything afterwards is the\n\t\t\t// default regardless of the presence of commas.\n\t\t\tp.HasDefault = true\n\t\t\tp.Default, i = tag[len(\"def=\"):], len(tag)\n\t\t}\n\t\ttag = strings.TrimPrefix(tag[i:], \",\")\n\t}\n}\n\n// Init populates the properties from a protocol buffer struct tag.\n//\n// Deprecated: Do not use.\nfunc (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {\n\tp.Name = name\n\tp.OrigName = name\n\tif tag == \"\" {\n\t\treturn\n\t}\n\tp.Parse(tag)\n\n\tif typ != nil && typ.Kind() == reflect.Map {\n\t\tp.MapKeyProp = new(Properties)\n\t\tp.MapKeyProp.Init(nil, \"Key\", f.Tag.Get(\"protobuf_key\"), nil)\n\t\tp.MapValProp = new(Properties)\n\t\tp.MapValProp.Init(nil, \"Value\", f.Tag.Get(\"protobuf_val\"), nil)\n\t}\n}\n\nvar propertiesCache sync.Map // map[reflect.Type]*StructProperties\n\n// GetProperties returns the list of properties for the type represented by t,\n// which must be a generated protocol buffer message in the open-struct API,\n// where protobuf message fields are represented by exported Go struct fields.\n//\n// Deprecated: Use protobuf reflection instead.\nfunc GetProperties(t reflect.Type) *StructProperties {\n\tif p, ok := propertiesCache.Load(t); ok {\n\t\treturn p.(*StructProperties)\n\t}\n\tp, _ := propertiesCache.LoadOrStore(t, newProperties(t))\n\treturn p.(*StructProperties)\n}\n\nfunc newProperties(t reflect.Type) *StructProperties {\n\tif t.Kind() != reflect.Struct {\n\t\tpanic(fmt.Sprintf(\"%v is not a generated message in the open-struct API\", t))\n\t}\n\n\tvar hasOneof bool\n\tprop := new(StructProperties)\n\n\t// Construct a list of properties for each field in the struct.\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tp := new(Properties)\n\t\tf := t.Field(i)\n\t\ttagField := f.Tag.Get(\"protobuf\")\n\t\tp.Init(f.Type, f.Name, tagField, &f)\n\n\t\ttagOneof := f.Tag.Get(\"protobuf_oneof\")\n\t\tif tagOneof != \"\" {\n\t\t\thasOneof = true\n\t\t\tp.OrigName = tagOneof\n\t\t}\n\n\t\t// Rename unrelated struct fields with the \"XXX_\" prefix since so much\n\t\t// user code simply checks for this to exclude special fields.\n\t\tif tagField == \"\" && tagOneof == \"\" && !strings.HasPrefix(p.Name, \"XXX_\") {\n\t\t\tp.Name = \"XXX_\" + p.Name\n\t\t\tp.OrigName = \"XXX_\" + p.OrigName\n\t\t} else if p.Weak != \"\" {\n\t\t\tp.Name = p.OrigName // avoid possible \"XXX_\" prefix on weak field\n\t\t}\n\n\t\tprop.Prop = append(prop.Prop, p)\n\t}\n\n\t// Construct a mapping of oneof field names to properties.\n\tif hasOneof {\n\t\tvar oneofWrappers []interface{}\n\t\tif fn, ok := reflect.PtrTo(t).MethodByName(\"XXX_OneofFuncs\"); ok {\n\t\t\toneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3].Interface().([]interface{})\n\t\t}\n\t\tif fn, ok := reflect.PtrTo(t).MethodByName(\"XXX_OneofWrappers\"); ok {\n\t\t\toneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0].Interface().([]interface{})\n\t\t}\n\t\tif m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(protoreflect.ProtoMessage); ok {\n\t\t\tif m, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *protoimpl.MessageInfo }); ok {\n\t\t\t\toneofWrappers = m.ProtoMessageInfo().OneofWrappers\n\t\t\t}\n\t\t}\n\n\t\tprop.OneofTypes = make(map[string]*OneofProperties)\n\t\tfor _, wrapper := range oneofWrappers {\n\t\t\tp := &OneofProperties{\n\t\t\t\tType: reflect.ValueOf(wrapper).Type(), // *T\n\t\t\t\tProp: new(Properties),\n\t\t\t}\n\t\t\tf := p.Type.Elem().Field(0)\n\t\t\tp.Prop.Name = f.Name\n\t\t\tp.Prop.Parse(f.Tag.Get(\"protobuf\"))\n\n\t\t\t// Determine the struct field that contains this oneof.\n\t\t\t// Each wrapper is assignable to exactly one parent field.\n\t\t\tvar foundOneof bool\n\t\t\tfor i := 0; i < t.NumField() && !foundOneof; i++ {\n\t\t\t\tif p.Type.AssignableTo(t.Field(i).Type) {\n\t\t\t\t\tp.Field = i\n\t\t\t\t\tfoundOneof = true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !foundOneof {\n\t\t\t\tpanic(fmt.Sprintf(\"%v is not a generated message in the open-struct API\", t))\n\t\t\t}\n\t\t\tprop.OneofTypes[p.Prop.OrigName] = p\n\t\t}\n\t}\n\n\treturn prop\n}\n\nfunc (sp *StructProperties) Len() int           { return len(sp.Prop) }\nfunc (sp *StructProperties) Less(i, j int) bool { return false }\nfunc (sp *StructProperties) Swap(i, j int)      { return }\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/proto.go",
    "content": "// Copyright 2019 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// Package proto provides functionality for handling protocol buffer messages.\n// In particular, it provides marshaling and unmarshaling between a protobuf\n// message and the binary wire format.\n//\n// See https://developers.google.com/protocol-buffers/docs/gotutorial for\n// more information.\n//\n// Deprecated: Use the \"google.golang.org/protobuf/proto\" package instead.\npackage proto\n\nimport (\n\tprotoV2 \"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/runtime/protoiface\"\n\t\"google.golang.org/protobuf/runtime/protoimpl\"\n)\n\nconst (\n\tProtoPackageIsVersion1 = true\n\tProtoPackageIsVersion2 = true\n\tProtoPackageIsVersion3 = true\n\tProtoPackageIsVersion4 = true\n)\n\n// GeneratedEnum is any enum type generated by protoc-gen-go\n// which is a named int32 kind.\n// This type exists for documentation purposes.\ntype GeneratedEnum interface{}\n\n// GeneratedMessage is any message type generated by protoc-gen-go\n// which is a pointer to a named struct kind.\n// This type exists for documentation purposes.\ntype GeneratedMessage interface{}\n\n// Message is a protocol buffer message.\n//\n// This is the v1 version of the message interface and is marginally better\n// than an empty interface as it lacks any method to programatically interact\n// with the contents of the message.\n//\n// A v2 message is declared in \"google.golang.org/protobuf/proto\".Message and\n// exposes protobuf reflection as a first-class feature of the interface.\n//\n// To convert a v1 message to a v2 message, use the MessageV2 function.\n// To convert a v2 message to a v1 message, use the MessageV1 function.\ntype Message = protoiface.MessageV1\n\n// MessageV1 converts either a v1 or v2 message to a v1 message.\n// It returns nil if m is nil.\nfunc MessageV1(m GeneratedMessage) protoiface.MessageV1 {\n\treturn protoimpl.X.ProtoMessageV1Of(m)\n}\n\n// MessageV2 converts either a v1 or v2 message to a v2 message.\n// It returns nil if m is nil.\nfunc MessageV2(m GeneratedMessage) protoV2.Message {\n\treturn protoimpl.X.ProtoMessageV2Of(m)\n}\n\n// MessageReflect returns a reflective view for a message.\n// It returns nil if m is nil.\nfunc MessageReflect(m Message) protoreflect.Message {\n\treturn protoimpl.X.MessageOf(m)\n}\n\n// Marshaler is implemented by messages that can marshal themselves.\n// This interface is used by the following functions: Size, Marshal,\n// Buffer.Marshal, and Buffer.EncodeMessage.\n//\n// Deprecated: Do not implement.\ntype Marshaler interface {\n\t// Marshal formats the encoded bytes of the message.\n\t// It should be deterministic and emit valid protobuf wire data.\n\t// The caller takes ownership of the returned buffer.\n\tMarshal() ([]byte, error)\n}\n\n// Unmarshaler is implemented by messages that can unmarshal themselves.\n// This interface is used by the following functions: Unmarshal, UnmarshalMerge,\n// Buffer.Unmarshal, Buffer.DecodeMessage, and Buffer.DecodeGroup.\n//\n// Deprecated: Do not implement.\ntype Unmarshaler interface {\n\t// Unmarshal parses the encoded bytes of the protobuf wire input.\n\t// The provided buffer is only valid for during method call.\n\t// It should not reset the receiver message.\n\tUnmarshal([]byte) error\n}\n\n// Merger is implemented by messages that can merge themselves.\n// This interface is used by the following functions: Clone and Merge.\n//\n// Deprecated: Do not implement.\ntype Merger interface {\n\t// Merge merges the contents of src into the receiver message.\n\t// It clones all data structures in src such that it aliases no mutable\n\t// memory referenced by src.\n\tMerge(src Message)\n}\n\n// RequiredNotSetError is an error type returned when\n// marshaling or unmarshaling a message with missing required fields.\ntype RequiredNotSetError struct {\n\terr error\n}\n\nfunc (e *RequiredNotSetError) Error() string {\n\tif e.err != nil {\n\t\treturn e.err.Error()\n\t}\n\treturn \"proto: required field not set\"\n}\nfunc (e *RequiredNotSetError) RequiredNotSet() bool {\n\treturn true\n}\n\nfunc checkRequiredNotSet(m protoV2.Message) error {\n\tif err := protoV2.CheckInitialized(m); err != nil {\n\t\treturn &RequiredNotSetError{err: err}\n\t}\n\treturn nil\n}\n\n// Clone returns a deep copy of src.\nfunc Clone(src Message) Message {\n\treturn MessageV1(protoV2.Clone(MessageV2(src)))\n}\n\n// Merge merges src into dst, which must be messages of the same type.\n//\n// Populated scalar fields in src are copied to dst, while populated\n// singular messages in src are merged into dst by recursively calling Merge.\n// The elements of every list field in src is appended to the corresponded\n// list fields in dst. The entries of every map field in src is copied into\n// the corresponding map field in dst, possibly replacing existing entries.\n// The unknown fields of src are appended to the unknown fields of dst.\nfunc Merge(dst, src Message) {\n\tprotoV2.Merge(MessageV2(dst), MessageV2(src))\n}\n\n// Equal reports whether two messages are equal.\n// If two messages marshal to the same bytes under deterministic serialization,\n// then Equal is guaranteed to report true.\n//\n// Two messages are equal if they are the same protobuf message type,\n// have the same set of populated known and extension field values,\n// and the same set of unknown fields values.\n//\n// Scalar values are compared with the equivalent of the == operator in Go,\n// except bytes values which are compared using bytes.Equal and\n// floating point values which specially treat NaNs as equal.\n// Message values are compared by recursively calling Equal.\n// Lists are equal if each element value is also equal.\n// Maps are equal if they have the same set of keys, where the pair of values\n// for each key is also equal.\nfunc Equal(x, y Message) bool {\n\treturn protoV2.Equal(MessageV2(x), MessageV2(y))\n}\n\nfunc isMessageSet(md protoreflect.MessageDescriptor) bool {\n\tms, ok := md.(interface{ IsMessageSet() bool })\n\treturn ok && ms.IsMessageSet()\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/registry.go",
    "content": "// Copyright 2019 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 proto\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"google.golang.org/protobuf/reflect/protodesc\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/reflect/protoregistry\"\n\t\"google.golang.org/protobuf/runtime/protoimpl\"\n)\n\n// filePath is the path to the proto source file.\ntype filePath = string // e.g., \"google/protobuf/descriptor.proto\"\n\n// fileDescGZIP is the compressed contents of the encoded FileDescriptorProto.\ntype fileDescGZIP = []byte\n\nvar fileCache sync.Map // map[filePath]fileDescGZIP\n\n// RegisterFile is called from generated code to register the compressed\n// FileDescriptorProto with the file path for a proto source file.\n//\n// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead.\nfunc RegisterFile(s filePath, d fileDescGZIP) {\n\t// Decompress the descriptor.\n\tzr, err := gzip.NewReader(bytes.NewReader(d))\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"proto: invalid compressed file descriptor: %v\", err))\n\t}\n\tb, err := ioutil.ReadAll(zr)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"proto: invalid compressed file descriptor: %v\", err))\n\t}\n\n\t// Construct a protoreflect.FileDescriptor from the raw descriptor.\n\t// Note that DescBuilder.Build automatically registers the constructed\n\t// file descriptor with the v2 registry.\n\tprotoimpl.DescBuilder{RawDescriptor: b}.Build()\n\n\t// Locally cache the raw descriptor form for the file.\n\tfileCache.Store(s, d)\n}\n\n// FileDescriptor returns the compressed FileDescriptorProto given the file path\n// for a proto source file. It returns nil if not found.\n//\n// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead.\nfunc FileDescriptor(s filePath) fileDescGZIP {\n\tif v, ok := fileCache.Load(s); ok {\n\t\treturn v.(fileDescGZIP)\n\t}\n\n\t// Find the descriptor in the v2 registry.\n\tvar b []byte\n\tif fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil {\n\t\tb, _ = Marshal(protodesc.ToFileDescriptorProto(fd))\n\t}\n\n\t// Locally cache the raw descriptor form for the file.\n\tif len(b) > 0 {\n\t\tv, _ := fileCache.LoadOrStore(s, protoimpl.X.CompressGZIP(b))\n\t\treturn v.(fileDescGZIP)\n\t}\n\treturn nil\n}\n\n// enumName is the name of an enum. For historical reasons, the enum name is\n// neither the full Go name nor the full protobuf name of the enum.\n// The name is the dot-separated combination of just the proto package that the\n// enum is declared within followed by the Go type name of the generated enum.\ntype enumName = string // e.g., \"my.proto.package.GoMessage_GoEnum\"\n\n// enumsByName maps enum values by name to their numeric counterpart.\ntype enumsByName = map[string]int32\n\n// enumsByNumber maps enum values by number to their name counterpart.\ntype enumsByNumber = map[int32]string\n\nvar enumCache sync.Map     // map[enumName]enumsByName\nvar numFilesCache sync.Map // map[protoreflect.FullName]int\n\n// RegisterEnum is called from the generated code to register the mapping of\n// enum value names to enum numbers for the enum identified by s.\n//\n// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead.\nfunc RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) {\n\tif _, ok := enumCache.Load(s); ok {\n\t\tpanic(\"proto: duplicate enum registered: \" + s)\n\t}\n\tenumCache.Store(s, m)\n\n\t// This does not forward registration to the v2 registry since this API\n\t// lacks sufficient information to construct a complete v2 enum descriptor.\n}\n\n// EnumValueMap returns the mapping from enum value names to enum numbers for\n// the enum of the given name. It returns nil if not found.\n//\n// Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead.\nfunc EnumValueMap(s enumName) enumsByName {\n\tif v, ok := enumCache.Load(s); ok {\n\t\treturn v.(enumsByName)\n\t}\n\n\t// Check whether the cache is stale. If the number of files in the current\n\t// package differs, then it means that some enums may have been recently\n\t// registered upstream that we do not know about.\n\tvar protoPkg protoreflect.FullName\n\tif i := strings.LastIndexByte(s, '.'); i >= 0 {\n\t\tprotoPkg = protoreflect.FullName(s[:i])\n\t}\n\tv, _ := numFilesCache.Load(protoPkg)\n\tnumFiles, _ := v.(int)\n\tif protoregistry.GlobalFiles.NumFilesByPackage(protoPkg) == numFiles {\n\t\treturn nil // cache is up-to-date; was not found earlier\n\t}\n\n\t// Update the enum cache for all enums declared in the given proto package.\n\tnumFiles = 0\n\tprotoregistry.GlobalFiles.RangeFilesByPackage(protoPkg, func(fd protoreflect.FileDescriptor) bool {\n\t\twalkEnums(fd, func(ed protoreflect.EnumDescriptor) {\n\t\t\tname := protoimpl.X.LegacyEnumName(ed)\n\t\t\tif _, ok := enumCache.Load(name); !ok {\n\t\t\t\tm := make(enumsByName)\n\t\t\t\tevs := ed.Values()\n\t\t\t\tfor i := evs.Len() - 1; i >= 0; i-- {\n\t\t\t\t\tev := evs.Get(i)\n\t\t\t\t\tm[string(ev.Name())] = int32(ev.Number())\n\t\t\t\t}\n\t\t\t\tenumCache.LoadOrStore(name, m)\n\t\t\t}\n\t\t})\n\t\tnumFiles++\n\t\treturn true\n\t})\n\tnumFilesCache.Store(protoPkg, numFiles)\n\n\t// Check cache again for enum map.\n\tif v, ok := enumCache.Load(s); ok {\n\t\treturn v.(enumsByName)\n\t}\n\treturn nil\n}\n\n// walkEnums recursively walks all enums declared in d.\nfunc walkEnums(d interface {\n\tEnums() protoreflect.EnumDescriptors\n\tMessages() protoreflect.MessageDescriptors\n}, f func(protoreflect.EnumDescriptor)) {\n\teds := d.Enums()\n\tfor i := eds.Len() - 1; i >= 0; i-- {\n\t\tf(eds.Get(i))\n\t}\n\tmds := d.Messages()\n\tfor i := mds.Len() - 1; i >= 0; i-- {\n\t\twalkEnums(mds.Get(i), f)\n\t}\n}\n\n// messageName is the full name of protobuf message.\ntype messageName = string\n\nvar messageTypeCache sync.Map // map[messageName]reflect.Type\n\n// RegisterType is called from generated code to register the message Go type\n// for a message of the given name.\n//\n// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead.\nfunc RegisterType(m Message, s messageName) {\n\tmt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s))\n\tif err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil {\n\t\tpanic(err)\n\t}\n\tmessageTypeCache.Store(s, reflect.TypeOf(m))\n}\n\n// RegisterMapType is called from generated code to register the Go map type\n// for a protobuf message representing a map entry.\n//\n// Deprecated: Do not use.\nfunc RegisterMapType(m interface{}, s messageName) {\n\tt := reflect.TypeOf(m)\n\tif t.Kind() != reflect.Map {\n\t\tpanic(fmt.Sprintf(\"invalid map kind: %v\", t))\n\t}\n\tif _, ok := messageTypeCache.Load(s); ok {\n\t\tpanic(fmt.Errorf(\"proto: duplicate proto message registered: %s\", s))\n\t}\n\tmessageTypeCache.Store(s, t)\n}\n\n// MessageType returns the message type for a named message.\n// It returns nil if not found.\n//\n// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead.\nfunc MessageType(s messageName) reflect.Type {\n\tif v, ok := messageTypeCache.Load(s); ok {\n\t\treturn v.(reflect.Type)\n\t}\n\n\t// Derive the message type from the v2 registry.\n\tvar t reflect.Type\n\tif mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s)); mt != nil {\n\t\tt = messageGoType(mt)\n\t}\n\n\t// If we could not get a concrete type, it is possible that it is a\n\t// pseudo-message for a map entry.\n\tif t == nil {\n\t\td, _ := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(s))\n\t\tif md, _ := d.(protoreflect.MessageDescriptor); md != nil && md.IsMapEntry() {\n\t\t\tkt := goTypeForField(md.Fields().ByNumber(1))\n\t\t\tvt := goTypeForField(md.Fields().ByNumber(2))\n\t\t\tt = reflect.MapOf(kt, vt)\n\t\t}\n\t}\n\n\t// Locally cache the message type for the given name.\n\tif t != nil {\n\t\tv, _ := messageTypeCache.LoadOrStore(s, t)\n\t\treturn v.(reflect.Type)\n\t}\n\treturn nil\n}\n\nfunc goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type {\n\tswitch k := fd.Kind(); k {\n\tcase protoreflect.EnumKind:\n\t\tif et, _ := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName()); et != nil {\n\t\t\treturn enumGoType(et)\n\t\t}\n\t\treturn reflect.TypeOf(protoreflect.EnumNumber(0))\n\tcase protoreflect.MessageKind, protoreflect.GroupKind:\n\t\tif mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()); mt != nil {\n\t\t\treturn messageGoType(mt)\n\t\t}\n\t\treturn reflect.TypeOf((*protoreflect.Message)(nil)).Elem()\n\tdefault:\n\t\treturn reflect.TypeOf(fd.Default().Interface())\n\t}\n}\n\nfunc enumGoType(et protoreflect.EnumType) reflect.Type {\n\treturn reflect.TypeOf(et.New(0))\n}\n\nfunc messageGoType(mt protoreflect.MessageType) reflect.Type {\n\treturn reflect.TypeOf(MessageV1(mt.Zero().Interface()))\n}\n\n// MessageName returns the full protobuf name for the given message type.\n//\n// Deprecated: Use protoreflect.MessageDescriptor.FullName instead.\nfunc MessageName(m Message) messageName {\n\tif m == nil {\n\t\treturn \"\"\n\t}\n\tif m, ok := m.(interface{ XXX_MessageName() messageName }); ok {\n\t\treturn m.XXX_MessageName()\n\t}\n\treturn messageName(protoimpl.X.MessageDescriptorOf(m).FullName())\n}\n\n// RegisterExtension is called from the generated code to register\n// the extension descriptor.\n//\n// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead.\nfunc RegisterExtension(d *ExtensionDesc) {\n\tif err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil {\n\t\tpanic(err)\n\t}\n}\n\ntype extensionsByNumber = map[int32]*ExtensionDesc\n\nvar extensionCache sync.Map // map[messageName]extensionsByNumber\n\n// RegisteredExtensions returns a map of the registered extensions for the\n// provided protobuf message, indexed by the extension field number.\n//\n// Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead.\nfunc RegisteredExtensions(m Message) extensionsByNumber {\n\t// Check whether the cache is stale. If the number of extensions for\n\t// the given message differs, then it means that some extensions were\n\t// recently registered upstream that we do not know about.\n\ts := MessageName(m)\n\tv, _ := extensionCache.Load(s)\n\txs, _ := v.(extensionsByNumber)\n\tif protoregistry.GlobalTypes.NumExtensionsByMessage(protoreflect.FullName(s)) == len(xs) {\n\t\treturn xs // cache is up-to-date\n\t}\n\n\t// Cache is stale, re-compute the extensions map.\n\txs = make(extensionsByNumber)\n\tprotoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool {\n\t\tif xd, ok := xt.(*ExtensionDesc); ok {\n\t\t\txs[int32(xt.TypeDescriptor().Number())] = xd\n\t\t} else {\n\t\t\t// TODO: This implies that the protoreflect.ExtensionType is a\n\t\t\t// custom type not generated by protoc-gen-go. We could try and\n\t\t\t// convert the type to an ExtensionDesc.\n\t\t}\n\t\treturn true\n\t})\n\textensionCache.Store(s, xs)\n\treturn xs\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/text_decode.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 proto\n\nimport (\n\t\"encoding\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"google.golang.org/protobuf/encoding/prototext\"\n\tprotoV2 \"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/reflect/protoregistry\"\n)\n\nconst wrapTextUnmarshalV2 = false\n\n// ParseError is returned by UnmarshalText.\ntype ParseError struct {\n\tMessage string\n\n\t// Deprecated: Do not use.\n\tLine, Offset int\n}\n\nfunc (e *ParseError) Error() string {\n\tif wrapTextUnmarshalV2 {\n\t\treturn e.Message\n\t}\n\tif e.Line == 1 {\n\t\treturn fmt.Sprintf(\"line 1.%d: %v\", e.Offset, e.Message)\n\t}\n\treturn fmt.Sprintf(\"line %d: %v\", e.Line, e.Message)\n}\n\n// UnmarshalText parses a proto text formatted string into m.\nfunc UnmarshalText(s string, m Message) error {\n\tif u, ok := m.(encoding.TextUnmarshaler); ok {\n\t\treturn u.UnmarshalText([]byte(s))\n\t}\n\n\tm.Reset()\n\tmi := MessageV2(m)\n\n\tif wrapTextUnmarshalV2 {\n\t\terr := prototext.UnmarshalOptions{\n\t\t\tAllowPartial: true,\n\t\t}.Unmarshal([]byte(s), mi)\n\t\tif err != nil {\n\t\t\treturn &ParseError{Message: err.Error()}\n\t\t}\n\t\treturn checkRequiredNotSet(mi)\n\t} else {\n\t\tif err := newTextParser(s).unmarshalMessage(mi.ProtoReflect(), \"\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn checkRequiredNotSet(mi)\n\t}\n}\n\ntype textParser struct {\n\ts            string // remaining input\n\tdone         bool   // whether the parsing is finished (success or error)\n\tbacked       bool   // whether back() was called\n\toffset, line int\n\tcur          token\n}\n\ntype token struct {\n\tvalue    string\n\terr      *ParseError\n\tline     int    // line number\n\toffset   int    // byte number from start of input, not start of line\n\tunquoted string // the unquoted version of value, if it was a quoted string\n}\n\nfunc newTextParser(s string) *textParser {\n\tp := new(textParser)\n\tp.s = s\n\tp.line = 1\n\tp.cur.line = 1\n\treturn p\n}\n\nfunc (p *textParser) unmarshalMessage(m protoreflect.Message, terminator string) (err error) {\n\tmd := m.Descriptor()\n\tfds := md.Fields()\n\n\t// A struct is a sequence of \"name: value\", terminated by one of\n\t// '>' or '}', or the end of the input.  A name may also be\n\t// \"[extension]\" or \"[type/url]\".\n\t//\n\t// The whole struct can also be an expanded Any message, like:\n\t// [type/url] < ... struct contents ... >\n\tseen := make(map[protoreflect.FieldNumber]bool)\n\tfor {\n\t\ttok := p.next()\n\t\tif tok.err != nil {\n\t\t\treturn tok.err\n\t\t}\n\t\tif tok.value == terminator {\n\t\t\tbreak\n\t\t}\n\t\tif tok.value == \"[\" {\n\t\t\tif err := p.unmarshalExtensionOrAny(m, seen); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// This is a normal, non-extension field.\n\t\tname := protoreflect.Name(tok.value)\n\t\tfd := fds.ByName(name)\n\t\tswitch {\n\t\tcase fd == nil:\n\t\t\tgd := fds.ByName(protoreflect.Name(strings.ToLower(string(name))))\n\t\t\tif gd != nil && gd.Kind() == protoreflect.GroupKind && gd.Message().Name() == name {\n\t\t\t\tfd = gd\n\t\t\t}\n\t\tcase fd.Kind() == protoreflect.GroupKind && fd.Message().Name() != name:\n\t\t\tfd = nil\n\t\tcase fd.IsWeak() && fd.Message().IsPlaceholder():\n\t\t\tfd = nil\n\t\t}\n\t\tif fd == nil {\n\t\t\ttypeName := string(md.FullName())\n\t\t\tif m, ok := m.Interface().(Message); ok {\n\t\t\t\tt := reflect.TypeOf(m)\n\t\t\t\tif t.Kind() == reflect.Ptr {\n\t\t\t\t\ttypeName = t.Elem().String()\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn p.errorf(\"unknown field name %q in %v\", name, typeName)\n\t\t}\n\t\tif od := fd.ContainingOneof(); od != nil && m.WhichOneof(od) != nil {\n\t\t\treturn p.errorf(\"field '%s' would overwrite already parsed oneof '%s'\", name, od.Name())\n\t\t}\n\t\tif fd.Cardinality() != protoreflect.Repeated && seen[fd.Number()] {\n\t\t\treturn p.errorf(\"non-repeated field %q was repeated\", fd.Name())\n\t\t}\n\t\tseen[fd.Number()] = true\n\n\t\t// Consume any colon.\n\t\tif err := p.checkForColon(fd); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Parse into the field.\n\t\tv := m.Get(fd)\n\t\tif !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) {\n\t\t\tv = m.Mutable(fd)\n\t\t}\n\t\tif v, err = p.unmarshalValue(v, fd); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tm.Set(fd, v)\n\n\t\tif err := p.consumeOptionalSeparator(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, seen map[protoreflect.FieldNumber]bool) error {\n\tname, err := p.consumeExtensionOrAnyName()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// If it contains a slash, it's an Any type URL.\n\tif slashIdx := strings.LastIndex(name, \"/\"); slashIdx >= 0 {\n\t\ttok := p.next()\n\t\tif tok.err != nil {\n\t\t\treturn tok.err\n\t\t}\n\t\t// consume an optional colon\n\t\tif tok.value == \":\" {\n\t\t\ttok = p.next()\n\t\t\tif tok.err != nil {\n\t\t\t\treturn tok.err\n\t\t\t}\n\t\t}\n\n\t\tvar terminator string\n\t\tswitch tok.value {\n\t\tcase \"<\":\n\t\t\tterminator = \">\"\n\t\tcase \"{\":\n\t\t\tterminator = \"}\"\n\t\tdefault:\n\t\t\treturn p.errorf(\"expected '{' or '<', found %q\", tok.value)\n\t\t}\n\n\t\tmt, err := protoregistry.GlobalTypes.FindMessageByURL(name)\n\t\tif err != nil {\n\t\t\treturn p.errorf(\"unrecognized message %q in google.protobuf.Any\", name[slashIdx+len(\"/\"):])\n\t\t}\n\t\tm2 := mt.New()\n\t\tif err := p.unmarshalMessage(m2, terminator); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tb, err := protoV2.Marshal(m2.Interface())\n\t\tif err != nil {\n\t\t\treturn p.errorf(\"failed to marshal message of type %q: %v\", name[slashIdx+len(\"/\"):], err)\n\t\t}\n\n\t\turlFD := m.Descriptor().Fields().ByName(\"type_url\")\n\t\tvalFD := m.Descriptor().Fields().ByName(\"value\")\n\t\tif seen[urlFD.Number()] {\n\t\t\treturn p.errorf(\"Any message unpacked multiple times, or %q already set\", urlFD.Name())\n\t\t}\n\t\tif seen[valFD.Number()] {\n\t\t\treturn p.errorf(\"Any message unpacked multiple times, or %q already set\", valFD.Name())\n\t\t}\n\t\tm.Set(urlFD, protoreflect.ValueOfString(name))\n\t\tm.Set(valFD, protoreflect.ValueOfBytes(b))\n\t\tseen[urlFD.Number()] = true\n\t\tseen[valFD.Number()] = true\n\t\treturn nil\n\t}\n\n\txname := protoreflect.FullName(name)\n\txt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname)\n\tif xt == nil && isMessageSet(m.Descriptor()) {\n\t\txt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append(\"message_set_extension\"))\n\t}\n\tif xt == nil {\n\t\treturn p.errorf(\"unrecognized extension %q\", name)\n\t}\n\tfd := xt.TypeDescriptor()\n\tif fd.ContainingMessage().FullName() != m.Descriptor().FullName() {\n\t\treturn p.errorf(\"extension field %q does not extend message %q\", name, m.Descriptor().FullName())\n\t}\n\n\tif err := p.checkForColon(fd); err != nil {\n\t\treturn err\n\t}\n\n\tv := m.Get(fd)\n\tif !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) {\n\t\tv = m.Mutable(fd)\n\t}\n\tv, err = p.unmarshalValue(v, fd)\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.Set(fd, v)\n\treturn p.consumeOptionalSeparator()\n}\n\nfunc (p *textParser) unmarshalValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn v, tok.err\n\t}\n\tif tok.value == \"\" {\n\t\treturn v, p.errorf(\"unexpected EOF\")\n\t}\n\n\tswitch {\n\tcase fd.IsList():\n\t\tlv := v.List()\n\t\tvar err error\n\t\tif tok.value == \"[\" {\n\t\t\t// Repeated field with list notation, like [1,2,3].\n\t\t\tfor {\n\t\t\t\tvv := lv.NewElement()\n\t\t\t\tvv, err = p.unmarshalSingularValue(vv, fd)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn v, err\n\t\t\t\t}\n\t\t\t\tlv.Append(vv)\n\n\t\t\t\ttok := p.next()\n\t\t\t\tif tok.err != nil {\n\t\t\t\t\treturn v, tok.err\n\t\t\t\t}\n\t\t\t\tif tok.value == \"]\" {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif tok.value != \",\" {\n\t\t\t\t\treturn v, p.errorf(\"Expected ']' or ',' found %q\", tok.value)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn v, nil\n\t\t}\n\n\t\t// One value of the repeated field.\n\t\tp.back()\n\t\tvv := lv.NewElement()\n\t\tvv, err = p.unmarshalSingularValue(vv, fd)\n\t\tif err != nil {\n\t\t\treturn v, err\n\t\t}\n\t\tlv.Append(vv)\n\t\treturn v, nil\n\tcase fd.IsMap():\n\t\t// The map entry should be this sequence of tokens:\n\t\t//\t< key : KEY value : VALUE >\n\t\t// However, implementations may omit key or value, and technically\n\t\t// we should support them in any order.\n\t\tvar terminator string\n\t\tswitch tok.value {\n\t\tcase \"<\":\n\t\t\tterminator = \">\"\n\t\tcase \"{\":\n\t\t\tterminator = \"}\"\n\t\tdefault:\n\t\t\treturn v, p.errorf(\"expected '{' or '<', found %q\", tok.value)\n\t\t}\n\n\t\tkeyFD := fd.MapKey()\n\t\tvalFD := fd.MapValue()\n\n\t\tmv := v.Map()\n\t\tkv := keyFD.Default()\n\t\tvv := mv.NewValue()\n\t\tfor {\n\t\t\ttok := p.next()\n\t\t\tif tok.err != nil {\n\t\t\t\treturn v, tok.err\n\t\t\t}\n\t\t\tif tok.value == terminator {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tvar err error\n\t\t\tswitch tok.value {\n\t\t\tcase \"key\":\n\t\t\t\tif err := p.consumeToken(\":\"); err != nil {\n\t\t\t\t\treturn v, err\n\t\t\t\t}\n\t\t\t\tif kv, err = p.unmarshalSingularValue(kv, keyFD); err != nil {\n\t\t\t\t\treturn v, err\n\t\t\t\t}\n\t\t\t\tif err := p.consumeOptionalSeparator(); err != nil {\n\t\t\t\t\treturn v, err\n\t\t\t\t}\n\t\t\tcase \"value\":\n\t\t\t\tif err := p.checkForColon(valFD); err != nil {\n\t\t\t\t\treturn v, err\n\t\t\t\t}\n\t\t\t\tif vv, err = p.unmarshalSingularValue(vv, valFD); err != nil {\n\t\t\t\t\treturn v, err\n\t\t\t\t}\n\t\t\t\tif err := p.consumeOptionalSeparator(); err != nil {\n\t\t\t\t\treturn v, err\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tp.back()\n\t\t\t\treturn v, p.errorf(`expected \"key\", \"value\", or %q, found %q`, terminator, tok.value)\n\t\t\t}\n\t\t}\n\t\tmv.Set(kv.MapKey(), vv)\n\t\treturn v, nil\n\tdefault:\n\t\tp.back()\n\t\treturn p.unmarshalSingularValue(v, fd)\n\t}\n}\n\nfunc (p *textParser) unmarshalSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn v, tok.err\n\t}\n\tif tok.value == \"\" {\n\t\treturn v, p.errorf(\"unexpected EOF\")\n\t}\n\n\tswitch fd.Kind() {\n\tcase protoreflect.BoolKind:\n\t\tswitch tok.value {\n\t\tcase \"true\", \"1\", \"t\", \"True\":\n\t\t\treturn protoreflect.ValueOfBool(true), nil\n\t\tcase \"false\", \"0\", \"f\", \"False\":\n\t\t\treturn protoreflect.ValueOfBool(false), nil\n\t\t}\n\tcase protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:\n\t\tif x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {\n\t\t\treturn protoreflect.ValueOfInt32(int32(x)), nil\n\t\t}\n\n\t\t// The C++ parser accepts large positive hex numbers that uses\n\t\t// two's complement arithmetic to represent negative numbers.\n\t\t// This feature is here for backwards compatibility with C++.\n\t\tif strings.HasPrefix(tok.value, \"0x\") {\n\t\t\tif x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {\n\t\t\t\treturn protoreflect.ValueOfInt32(int32(-(int64(^x) + 1))), nil\n\t\t\t}\n\t\t}\n\tcase protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:\n\t\tif x, err := strconv.ParseInt(tok.value, 0, 64); err == nil {\n\t\t\treturn protoreflect.ValueOfInt64(int64(x)), nil\n\t\t}\n\n\t\t// The C++ parser accepts large positive hex numbers that uses\n\t\t// two's complement arithmetic to represent negative numbers.\n\t\t// This feature is here for backwards compatibility with C++.\n\t\tif strings.HasPrefix(tok.value, \"0x\") {\n\t\t\tif x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {\n\t\t\t\treturn protoreflect.ValueOfInt64(int64(-(int64(^x) + 1))), nil\n\t\t\t}\n\t\t}\n\tcase protoreflect.Uint32Kind, protoreflect.Fixed32Kind:\n\t\tif x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {\n\t\t\treturn protoreflect.ValueOfUint32(uint32(x)), nil\n\t\t}\n\tcase protoreflect.Uint64Kind, protoreflect.Fixed64Kind:\n\t\tif x, err := strconv.ParseUint(tok.value, 0, 64); err == nil {\n\t\t\treturn protoreflect.ValueOfUint64(uint64(x)), nil\n\t\t}\n\tcase protoreflect.FloatKind:\n\t\t// Ignore 'f' for compatibility with output generated by C++,\n\t\t// but don't remove 'f' when the value is \"-inf\" or \"inf\".\n\t\tv := tok.value\n\t\tif strings.HasSuffix(v, \"f\") && v != \"-inf\" && v != \"inf\" {\n\t\t\tv = v[:len(v)-len(\"f\")]\n\t\t}\n\t\tif x, err := strconv.ParseFloat(v, 32); err == nil {\n\t\t\treturn protoreflect.ValueOfFloat32(float32(x)), nil\n\t\t}\n\tcase protoreflect.DoubleKind:\n\t\t// Ignore 'f' for compatibility with output generated by C++,\n\t\t// but don't remove 'f' when the value is \"-inf\" or \"inf\".\n\t\tv := tok.value\n\t\tif strings.HasSuffix(v, \"f\") && v != \"-inf\" && v != \"inf\" {\n\t\t\tv = v[:len(v)-len(\"f\")]\n\t\t}\n\t\tif x, err := strconv.ParseFloat(v, 64); err == nil {\n\t\t\treturn protoreflect.ValueOfFloat64(float64(x)), nil\n\t\t}\n\tcase protoreflect.StringKind:\n\t\tif isQuote(tok.value[0]) {\n\t\t\treturn protoreflect.ValueOfString(tok.unquoted), nil\n\t\t}\n\tcase protoreflect.BytesKind:\n\t\tif isQuote(tok.value[0]) {\n\t\t\treturn protoreflect.ValueOfBytes([]byte(tok.unquoted)), nil\n\t\t}\n\tcase protoreflect.EnumKind:\n\t\tif x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {\n\t\t\treturn protoreflect.ValueOfEnum(protoreflect.EnumNumber(x)), nil\n\t\t}\n\t\tvd := fd.Enum().Values().ByName(protoreflect.Name(tok.value))\n\t\tif vd != nil {\n\t\t\treturn protoreflect.ValueOfEnum(vd.Number()), nil\n\t\t}\n\tcase protoreflect.MessageKind, protoreflect.GroupKind:\n\t\tvar terminator string\n\t\tswitch tok.value {\n\t\tcase \"{\":\n\t\t\tterminator = \"}\"\n\t\tcase \"<\":\n\t\t\tterminator = \">\"\n\t\tdefault:\n\t\t\treturn v, p.errorf(\"expected '{' or '<', found %q\", tok.value)\n\t\t}\n\t\terr := p.unmarshalMessage(v.Message(), terminator)\n\t\treturn v, err\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"invalid kind %v\", fd.Kind()))\n\t}\n\treturn v, p.errorf(\"invalid %v: %v\", fd.Kind(), tok.value)\n}\n\n// Consume a ':' from the input stream (if the next token is a colon),\n// returning an error if a colon is needed but not present.\nfunc (p *textParser) checkForColon(fd protoreflect.FieldDescriptor) *ParseError {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn tok.err\n\t}\n\tif tok.value != \":\" {\n\t\tif fd.Message() == nil {\n\t\t\treturn p.errorf(\"expected ':', found %q\", tok.value)\n\t\t}\n\t\tp.back()\n\t}\n\treturn nil\n}\n\n// consumeExtensionOrAnyName consumes an extension name or an Any type URL and\n// the following ']'. It returns the name or URL consumed.\nfunc (p *textParser) consumeExtensionOrAnyName() (string, error) {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn \"\", tok.err\n\t}\n\n\t// If extension name or type url is quoted, it's a single token.\n\tif len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] {\n\t\tname, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0]))\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn name, p.consumeToken(\"]\")\n\t}\n\n\t// Consume everything up to \"]\"\n\tvar parts []string\n\tfor tok.value != \"]\" {\n\t\tparts = append(parts, tok.value)\n\t\ttok = p.next()\n\t\tif tok.err != nil {\n\t\t\treturn \"\", p.errorf(\"unrecognized type_url or extension name: %s\", tok.err)\n\t\t}\n\t\tif p.done && tok.value != \"]\" {\n\t\t\treturn \"\", p.errorf(\"unclosed type_url or extension name\")\n\t\t}\n\t}\n\treturn strings.Join(parts, \"\"), nil\n}\n\n// consumeOptionalSeparator consumes an optional semicolon or comma.\n// It is used in unmarshalMessage to provide backward compatibility.\nfunc (p *textParser) consumeOptionalSeparator() error {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn tok.err\n\t}\n\tif tok.value != \";\" && tok.value != \",\" {\n\t\tp.back()\n\t}\n\treturn nil\n}\n\nfunc (p *textParser) errorf(format string, a ...interface{}) *ParseError {\n\tpe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset}\n\tp.cur.err = pe\n\tp.done = true\n\treturn pe\n}\n\nfunc (p *textParser) skipWhitespace() {\n\ti := 0\n\tfor i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {\n\t\tif p.s[i] == '#' {\n\t\t\t// comment; skip to end of line or input\n\t\t\tfor i < len(p.s) && p.s[i] != '\\n' {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i == len(p.s) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif p.s[i] == '\\n' {\n\t\t\tp.line++\n\t\t}\n\t\ti++\n\t}\n\tp.offset += i\n\tp.s = p.s[i:len(p.s)]\n\tif len(p.s) == 0 {\n\t\tp.done = true\n\t}\n}\n\nfunc (p *textParser) advance() {\n\t// Skip whitespace\n\tp.skipWhitespace()\n\tif p.done {\n\t\treturn\n\t}\n\n\t// Start of non-whitespace\n\tp.cur.err = nil\n\tp.cur.offset, p.cur.line = p.offset, p.line\n\tp.cur.unquoted = \"\"\n\tswitch p.s[0] {\n\tcase '<', '>', '{', '}', ':', '[', ']', ';', ',', '/':\n\t\t// Single symbol\n\t\tp.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)]\n\tcase '\"', '\\'':\n\t\t// Quoted string\n\t\ti := 1\n\t\tfor i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\\n' {\n\t\t\tif p.s[i] == '\\\\' && i+1 < len(p.s) {\n\t\t\t\t// skip escaped char\n\t\t\t\ti++\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t\tif i >= len(p.s) || p.s[i] != p.s[0] {\n\t\t\tp.errorf(\"unmatched quote\")\n\t\t\treturn\n\t\t}\n\t\tunq, err := unquoteC(p.s[1:i], rune(p.s[0]))\n\t\tif err != nil {\n\t\t\tp.errorf(\"invalid quoted string %s: %v\", p.s[0:i+1], err)\n\t\t\treturn\n\t\t}\n\t\tp.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]\n\t\tp.cur.unquoted = unq\n\tdefault:\n\t\ti := 0\n\t\tfor i < len(p.s) && isIdentOrNumberChar(p.s[i]) {\n\t\t\ti++\n\t\t}\n\t\tif i == 0 {\n\t\t\tp.errorf(\"unexpected byte %#x\", p.s[0])\n\t\t\treturn\n\t\t}\n\t\tp.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)]\n\t}\n\tp.offset += len(p.cur.value)\n}\n\n// Back off the parser by one token. Can only be done between calls to next().\n// It makes the next advance() a no-op.\nfunc (p *textParser) back() { p.backed = true }\n\n// Advances the parser and returns the new current token.\nfunc (p *textParser) next() *token {\n\tif p.backed || p.done {\n\t\tp.backed = false\n\t\treturn &p.cur\n\t}\n\tp.advance()\n\tif p.done {\n\t\tp.cur.value = \"\"\n\t} else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {\n\t\t// Look for multiple quoted strings separated by whitespace,\n\t\t// and concatenate them.\n\t\tcat := p.cur\n\t\tfor {\n\t\t\tp.skipWhitespace()\n\t\t\tif p.done || !isQuote(p.s[0]) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.advance()\n\t\t\tif p.cur.err != nil {\n\t\t\t\treturn &p.cur\n\t\t\t}\n\t\t\tcat.value += \" \" + p.cur.value\n\t\t\tcat.unquoted += p.cur.unquoted\n\t\t}\n\t\tp.done = false // parser may have seen EOF, but we want to return cat\n\t\tp.cur = cat\n\t}\n\treturn &p.cur\n}\n\nfunc (p *textParser) consumeToken(s string) error {\n\ttok := p.next()\n\tif tok.err != nil {\n\t\treturn tok.err\n\t}\n\tif tok.value != s {\n\t\tp.back()\n\t\treturn p.errorf(\"expected %q, found %q\", s, tok.value)\n\t}\n\treturn nil\n}\n\nvar errBadUTF8 = errors.New(\"proto: bad UTF-8\")\n\nfunc unquoteC(s string, quote rune) (string, error) {\n\t// This is based on C++'s tokenizer.cc.\n\t// Despite its name, this is *not* parsing C syntax.\n\t// For instance, \"\\0\" is an invalid quoted string.\n\n\t// Avoid allocation in trivial cases.\n\tsimple := true\n\tfor _, r := range s {\n\t\tif r == '\\\\' || r == quote {\n\t\t\tsimple = false\n\t\t\tbreak\n\t\t}\n\t}\n\tif simple {\n\t\treturn s, nil\n\t}\n\n\tbuf := make([]byte, 0, 3*len(s)/2)\n\tfor len(s) > 0 {\n\t\tr, n := utf8.DecodeRuneInString(s)\n\t\tif r == utf8.RuneError && n == 1 {\n\t\t\treturn \"\", errBadUTF8\n\t\t}\n\t\ts = s[n:]\n\t\tif r != '\\\\' {\n\t\t\tif r < utf8.RuneSelf {\n\t\t\t\tbuf = append(buf, byte(r))\n\t\t\t} else {\n\t\t\t\tbuf = append(buf, string(r)...)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tch, tail, err := unescape(s)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tbuf = append(buf, ch...)\n\t\ts = tail\n\t}\n\treturn string(buf), nil\n}\n\nfunc unescape(s string) (ch string, tail string, err error) {\n\tr, n := utf8.DecodeRuneInString(s)\n\tif r == utf8.RuneError && n == 1 {\n\t\treturn \"\", \"\", errBadUTF8\n\t}\n\ts = s[n:]\n\tswitch r {\n\tcase 'a':\n\t\treturn \"\\a\", s, nil\n\tcase 'b':\n\t\treturn \"\\b\", s, nil\n\tcase 'f':\n\t\treturn \"\\f\", s, nil\n\tcase 'n':\n\t\treturn \"\\n\", s, nil\n\tcase 'r':\n\t\treturn \"\\r\", s, nil\n\tcase 't':\n\t\treturn \"\\t\", s, nil\n\tcase 'v':\n\t\treturn \"\\v\", s, nil\n\tcase '?':\n\t\treturn \"?\", s, nil // trigraph workaround\n\tcase '\\'', '\"', '\\\\':\n\t\treturn string(r), s, nil\n\tcase '0', '1', '2', '3', '4', '5', '6', '7':\n\t\tif len(s) < 2 {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c requires 2 following digits`, r)\n\t\t}\n\t\tss := string(r) + s[:2]\n\t\ts = s[2:]\n\t\ti, err := strconv.ParseUint(ss, 8, 8)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%s contains non-octal digits`, ss)\n\t\t}\n\t\treturn string([]byte{byte(i)}), s, nil\n\tcase 'x', 'X', 'u', 'U':\n\t\tvar n int\n\t\tswitch r {\n\t\tcase 'x', 'X':\n\t\t\tn = 2\n\t\tcase 'u':\n\t\t\tn = 4\n\t\tcase 'U':\n\t\t\tn = 8\n\t\t}\n\t\tif len(s) < n {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c requires %d following digits`, r, n)\n\t\t}\n\t\tss := s[:n]\n\t\ts = s[n:]\n\t\ti, err := strconv.ParseUint(ss, 16, 64)\n\t\tif err != nil {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c%s contains non-hexadecimal digits`, r, ss)\n\t\t}\n\t\tif r == 'x' || r == 'X' {\n\t\t\treturn string([]byte{byte(i)}), s, nil\n\t\t}\n\t\tif i > utf8.MaxRune {\n\t\t\treturn \"\", \"\", fmt.Errorf(`\\%c%s is not a valid Unicode code point`, r, ss)\n\t\t}\n\t\treturn string(rune(i)), s, nil\n\t}\n\treturn \"\", \"\", fmt.Errorf(`unknown escape \\%c`, r)\n}\n\nfunc isIdentOrNumberChar(c byte) bool {\n\tswitch {\n\tcase 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z':\n\t\treturn true\n\tcase '0' <= c && c <= '9':\n\t\treturn true\n\t}\n\tswitch c {\n\tcase '-', '+', '.', '_':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isWhitespace(c byte) bool {\n\tswitch c {\n\tcase ' ', '\\t', '\\n', '\\r':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isQuote(c byte) bool {\n\tswitch c {\n\tcase '\"', '\\'':\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/text_encode.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 proto\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"google.golang.org/protobuf/encoding/prototext\"\n\t\"google.golang.org/protobuf/encoding/protowire\"\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/reflect/protoregistry\"\n)\n\nconst wrapTextMarshalV2 = false\n\n// TextMarshaler is a configurable text format marshaler.\ntype TextMarshaler struct {\n\tCompact   bool // use compact text format (one line)\n\tExpandAny bool // expand google.protobuf.Any messages of known types\n}\n\n// Marshal writes the proto text format of m to w.\nfunc (tm *TextMarshaler) Marshal(w io.Writer, m Message) error {\n\tb, err := tm.marshal(m)\n\tif len(b) > 0 {\n\t\tif _, err := w.Write(b); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn err\n}\n\n// Text returns a proto text formatted string of m.\nfunc (tm *TextMarshaler) Text(m Message) string {\n\tb, _ := tm.marshal(m)\n\treturn string(b)\n}\n\nfunc (tm *TextMarshaler) marshal(m Message) ([]byte, error) {\n\tmr := MessageReflect(m)\n\tif mr == nil || !mr.IsValid() {\n\t\treturn []byte(\"<nil>\"), nil\n\t}\n\n\tif wrapTextMarshalV2 {\n\t\tif m, ok := m.(encoding.TextMarshaler); ok {\n\t\t\treturn m.MarshalText()\n\t\t}\n\n\t\topts := prototext.MarshalOptions{\n\t\t\tAllowPartial: true,\n\t\t\tEmitUnknown:  true,\n\t\t}\n\t\tif !tm.Compact {\n\t\t\topts.Indent = \"  \"\n\t\t}\n\t\tif !tm.ExpandAny {\n\t\t\topts.Resolver = (*protoregistry.Types)(nil)\n\t\t}\n\t\treturn opts.Marshal(mr.Interface())\n\t} else {\n\t\tw := &textWriter{\n\t\t\tcompact:   tm.Compact,\n\t\t\texpandAny: tm.ExpandAny,\n\t\t\tcomplete:  true,\n\t\t}\n\n\t\tif m, ok := m.(encoding.TextMarshaler); ok {\n\t\t\tb, err := m.MarshalText()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tw.Write(b)\n\t\t\treturn w.buf, nil\n\t\t}\n\n\t\terr := w.writeMessage(mr)\n\t\treturn w.buf, err\n\t}\n}\n\nvar (\n\tdefaultTextMarshaler = TextMarshaler{}\n\tcompactTextMarshaler = TextMarshaler{Compact: true}\n)\n\n// MarshalText writes the proto text format of m to w.\nfunc MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) }\n\n// MarshalTextString returns a proto text formatted string of m.\nfunc MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) }\n\n// CompactText writes the compact proto text format of m to w.\nfunc CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) }\n\n// CompactTextString returns a compact proto text formatted string of m.\nfunc CompactTextString(m Message) string { return compactTextMarshaler.Text(m) }\n\nvar (\n\tnewline         = []byte(\"\\n\")\n\tendBraceNewline = []byte(\"}\\n\")\n\tposInf          = []byte(\"inf\")\n\tnegInf          = []byte(\"-inf\")\n\tnan             = []byte(\"nan\")\n)\n\n// textWriter is an io.Writer that tracks its indentation level.\ntype textWriter struct {\n\tcompact   bool // same as TextMarshaler.Compact\n\texpandAny bool // same as TextMarshaler.ExpandAny\n\tcomplete  bool // whether the current position is a complete line\n\tindent    int  // indentation level; never negative\n\tbuf       []byte\n}\n\nfunc (w *textWriter) Write(p []byte) (n int, _ error) {\n\tnewlines := bytes.Count(p, newline)\n\tif newlines == 0 {\n\t\tif !w.compact && w.complete {\n\t\t\tw.writeIndent()\n\t\t}\n\t\tw.buf = append(w.buf, p...)\n\t\tw.complete = false\n\t\treturn len(p), nil\n\t}\n\n\tfrags := bytes.SplitN(p, newline, newlines+1)\n\tif w.compact {\n\t\tfor i, frag := range frags {\n\t\t\tif i > 0 {\n\t\t\t\tw.buf = append(w.buf, ' ')\n\t\t\t\tn++\n\t\t\t}\n\t\t\tw.buf = append(w.buf, frag...)\n\t\t\tn += len(frag)\n\t\t}\n\t\treturn n, nil\n\t}\n\n\tfor i, frag := range frags {\n\t\tif w.complete {\n\t\t\tw.writeIndent()\n\t\t}\n\t\tw.buf = append(w.buf, frag...)\n\t\tn += len(frag)\n\t\tif i+1 < len(frags) {\n\t\t\tw.buf = append(w.buf, '\\n')\n\t\t\tn++\n\t\t}\n\t}\n\tw.complete = len(frags[len(frags)-1]) == 0\n\treturn n, nil\n}\n\nfunc (w *textWriter) WriteByte(c byte) error {\n\tif w.compact && c == '\\n' {\n\t\tc = ' '\n\t}\n\tif !w.compact && w.complete {\n\t\tw.writeIndent()\n\t}\n\tw.buf = append(w.buf, c)\n\tw.complete = c == '\\n'\n\treturn nil\n}\n\nfunc (w *textWriter) writeName(fd protoreflect.FieldDescriptor) {\n\tif !w.compact && w.complete {\n\t\tw.writeIndent()\n\t}\n\tw.complete = false\n\n\tif fd.Kind() != protoreflect.GroupKind {\n\t\tw.buf = append(w.buf, fd.Name()...)\n\t\tw.WriteByte(':')\n\t} else {\n\t\t// Use message type name for group field name.\n\t\tw.buf = append(w.buf, fd.Message().Name()...)\n\t}\n\n\tif !w.compact {\n\t\tw.WriteByte(' ')\n\t}\n}\n\nfunc requiresQuotes(u string) bool {\n\t// When type URL contains any characters except [0-9A-Za-z./\\-]*, it must be quoted.\n\tfor _, ch := range u {\n\t\tswitch {\n\t\tcase ch == '.' || ch == '/' || ch == '_':\n\t\t\tcontinue\n\t\tcase '0' <= ch && ch <= '9':\n\t\t\tcontinue\n\t\tcase 'A' <= ch && ch <= 'Z':\n\t\t\tcontinue\n\t\tcase 'a' <= ch && ch <= 'z':\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// writeProto3Any writes an expanded google.protobuf.Any message.\n//\n// It returns (false, nil) if sv value can't be unmarshaled (e.g. because\n// required messages are not linked in).\n//\n// It returns (true, error) when sv was written in expanded format or an error\n// was encountered.\nfunc (w *textWriter) writeProto3Any(m protoreflect.Message) (bool, error) {\n\tmd := m.Descriptor()\n\tfdURL := md.Fields().ByName(\"type_url\")\n\tfdVal := md.Fields().ByName(\"value\")\n\n\turl := m.Get(fdURL).String()\n\tmt, err := protoregistry.GlobalTypes.FindMessageByURL(url)\n\tif err != nil {\n\t\treturn false, nil\n\t}\n\n\tb := m.Get(fdVal).Bytes()\n\tm2 := mt.New()\n\tif err := proto.Unmarshal(b, m2.Interface()); err != nil {\n\t\treturn false, nil\n\t}\n\tw.Write([]byte(\"[\"))\n\tif requiresQuotes(url) {\n\t\tw.writeQuotedString(url)\n\t} else {\n\t\tw.Write([]byte(url))\n\t}\n\tif w.compact {\n\t\tw.Write([]byte(\"]:<\"))\n\t} else {\n\t\tw.Write([]byte(\"]: <\\n\"))\n\t\tw.indent++\n\t}\n\tif err := w.writeMessage(m2); err != nil {\n\t\treturn true, err\n\t}\n\tif w.compact {\n\t\tw.Write([]byte(\"> \"))\n\t} else {\n\t\tw.indent--\n\t\tw.Write([]byte(\">\\n\"))\n\t}\n\treturn true, nil\n}\n\nfunc (w *textWriter) writeMessage(m protoreflect.Message) error {\n\tmd := m.Descriptor()\n\tif w.expandAny && md.FullName() == \"google.protobuf.Any\" {\n\t\tif canExpand, err := w.writeProto3Any(m); canExpand {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tfds := md.Fields()\n\tfor i := 0; i < fds.Len(); {\n\t\tfd := fds.Get(i)\n\t\tif od := fd.ContainingOneof(); od != nil {\n\t\t\tfd = m.WhichOneof(od)\n\t\t\ti += od.Fields().Len()\n\t\t} else {\n\t\t\ti++\n\t\t}\n\t\tif fd == nil || !m.Has(fd) {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch {\n\t\tcase fd.IsList():\n\t\t\tlv := m.Get(fd).List()\n\t\t\tfor j := 0; j < lv.Len(); j++ {\n\t\t\t\tw.writeName(fd)\n\t\t\t\tv := lv.Get(j)\n\t\t\t\tif err := w.writeSingularValue(v, fd); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tw.WriteByte('\\n')\n\t\t\t}\n\t\tcase fd.IsMap():\n\t\t\tkfd := fd.MapKey()\n\t\t\tvfd := fd.MapValue()\n\t\t\tmv := m.Get(fd).Map()\n\n\t\t\ttype entry struct{ key, val protoreflect.Value }\n\t\t\tvar entries []entry\n\t\t\tmv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {\n\t\t\t\tentries = append(entries, entry{k.Value(), v})\n\t\t\t\treturn true\n\t\t\t})\n\t\t\tsort.Slice(entries, func(i, j int) bool {\n\t\t\t\tswitch kfd.Kind() {\n\t\t\t\tcase protoreflect.BoolKind:\n\t\t\t\t\treturn !entries[i].key.Bool() && entries[j].key.Bool()\n\t\t\t\tcase protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:\n\t\t\t\t\treturn entries[i].key.Int() < entries[j].key.Int()\n\t\t\t\tcase protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:\n\t\t\t\t\treturn entries[i].key.Uint() < entries[j].key.Uint()\n\t\t\t\tcase protoreflect.StringKind:\n\t\t\t\t\treturn entries[i].key.String() < entries[j].key.String()\n\t\t\t\tdefault:\n\t\t\t\t\tpanic(\"invalid kind\")\n\t\t\t\t}\n\t\t\t})\n\t\t\tfor _, entry := range entries {\n\t\t\t\tw.writeName(fd)\n\t\t\t\tw.WriteByte('<')\n\t\t\t\tif !w.compact {\n\t\t\t\t\tw.WriteByte('\\n')\n\t\t\t\t}\n\t\t\t\tw.indent++\n\t\t\t\tw.writeName(kfd)\n\t\t\t\tif err := w.writeSingularValue(entry.key, kfd); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tw.WriteByte('\\n')\n\t\t\t\tw.writeName(vfd)\n\t\t\t\tif err := w.writeSingularValue(entry.val, vfd); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tw.WriteByte('\\n')\n\t\t\t\tw.indent--\n\t\t\t\tw.WriteByte('>')\n\t\t\t\tw.WriteByte('\\n')\n\t\t\t}\n\t\tdefault:\n\t\t\tw.writeName(fd)\n\t\t\tif err := w.writeSingularValue(m.Get(fd), fd); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tw.WriteByte('\\n')\n\t\t}\n\t}\n\n\tif b := m.GetUnknown(); len(b) > 0 {\n\t\tw.writeUnknownFields(b)\n\t}\n\treturn w.writeExtensions(m)\n}\n\nfunc (w *textWriter) writeSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) error {\n\tswitch fd.Kind() {\n\tcase protoreflect.FloatKind, protoreflect.DoubleKind:\n\t\tswitch vf := v.Float(); {\n\t\tcase math.IsInf(vf, +1):\n\t\t\tw.Write(posInf)\n\t\tcase math.IsInf(vf, -1):\n\t\t\tw.Write(negInf)\n\t\tcase math.IsNaN(vf):\n\t\t\tw.Write(nan)\n\t\tdefault:\n\t\t\tfmt.Fprint(w, v.Interface())\n\t\t}\n\tcase protoreflect.StringKind:\n\t\t// NOTE: This does not validate UTF-8 for historical reasons.\n\t\tw.writeQuotedString(string(v.String()))\n\tcase protoreflect.BytesKind:\n\t\tw.writeQuotedString(string(v.Bytes()))\n\tcase protoreflect.MessageKind, protoreflect.GroupKind:\n\t\tvar bra, ket byte = '<', '>'\n\t\tif fd.Kind() == protoreflect.GroupKind {\n\t\t\tbra, ket = '{', '}'\n\t\t}\n\t\tw.WriteByte(bra)\n\t\tif !w.compact {\n\t\t\tw.WriteByte('\\n')\n\t\t}\n\t\tw.indent++\n\t\tm := v.Message()\n\t\tif m2, ok := m.Interface().(encoding.TextMarshaler); ok {\n\t\t\tb, err := m2.MarshalText()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tw.Write(b)\n\t\t} else {\n\t\t\tw.writeMessage(m)\n\t\t}\n\t\tw.indent--\n\t\tw.WriteByte(ket)\n\tcase protoreflect.EnumKind:\n\t\tif ev := fd.Enum().Values().ByNumber(v.Enum()); ev != nil {\n\t\t\tfmt.Fprint(w, ev.Name())\n\t\t} else {\n\t\t\tfmt.Fprint(w, v.Enum())\n\t\t}\n\tdefault:\n\t\tfmt.Fprint(w, v.Interface())\n\t}\n\treturn nil\n}\n\n// writeQuotedString writes a quoted string in the protocol buffer text format.\nfunc (w *textWriter) writeQuotedString(s string) {\n\tw.WriteByte('\"')\n\tfor i := 0; i < len(s); i++ {\n\t\tswitch c := s[i]; c {\n\t\tcase '\\n':\n\t\t\tw.buf = append(w.buf, `\\n`...)\n\t\tcase '\\r':\n\t\t\tw.buf = append(w.buf, `\\r`...)\n\t\tcase '\\t':\n\t\t\tw.buf = append(w.buf, `\\t`...)\n\t\tcase '\"':\n\t\t\tw.buf = append(w.buf, `\\\"`...)\n\t\tcase '\\\\':\n\t\t\tw.buf = append(w.buf, `\\\\`...)\n\t\tdefault:\n\t\t\tif isPrint := c >= 0x20 && c < 0x7f; isPrint {\n\t\t\t\tw.buf = append(w.buf, c)\n\t\t\t} else {\n\t\t\t\tw.buf = append(w.buf, fmt.Sprintf(`\\%03o`, c)...)\n\t\t\t}\n\t\t}\n\t}\n\tw.WriteByte('\"')\n}\n\nfunc (w *textWriter) writeUnknownFields(b []byte) {\n\tif !w.compact {\n\t\tfmt.Fprintf(w, \"/* %d unknown bytes */\\n\", len(b))\n\t}\n\n\tfor len(b) > 0 {\n\t\tnum, wtyp, n := protowire.ConsumeTag(b)\n\t\tif n < 0 {\n\t\t\treturn\n\t\t}\n\t\tb = b[n:]\n\n\t\tif wtyp == protowire.EndGroupType {\n\t\t\tw.indent--\n\t\t\tw.Write(endBraceNewline)\n\t\t\tcontinue\n\t\t}\n\t\tfmt.Fprint(w, num)\n\t\tif wtyp != protowire.StartGroupType {\n\t\t\tw.WriteByte(':')\n\t\t}\n\t\tif !w.compact || wtyp == protowire.StartGroupType {\n\t\t\tw.WriteByte(' ')\n\t\t}\n\t\tswitch wtyp {\n\t\tcase protowire.VarintType:\n\t\t\tv, n := protowire.ConsumeVarint(b)\n\t\t\tif n < 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tfmt.Fprint(w, v)\n\t\tcase protowire.Fixed32Type:\n\t\t\tv, n := protowire.ConsumeFixed32(b)\n\t\t\tif n < 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tfmt.Fprint(w, v)\n\t\tcase protowire.Fixed64Type:\n\t\t\tv, n := protowire.ConsumeFixed64(b)\n\t\t\tif n < 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tfmt.Fprint(w, v)\n\t\tcase protowire.BytesType:\n\t\t\tv, n := protowire.ConsumeBytes(b)\n\t\t\tif n < 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tb = b[n:]\n\t\t\tfmt.Fprintf(w, \"%q\", v)\n\t\tcase protowire.StartGroupType:\n\t\t\tw.WriteByte('{')\n\t\t\tw.indent++\n\t\tdefault:\n\t\t\tfmt.Fprintf(w, \"/* unknown wire type %d */\", wtyp)\n\t\t}\n\t\tw.WriteByte('\\n')\n\t}\n}\n\n// writeExtensions writes all the extensions in m.\nfunc (w *textWriter) writeExtensions(m protoreflect.Message) error {\n\tmd := m.Descriptor()\n\tif md.ExtensionRanges().Len() == 0 {\n\t\treturn nil\n\t}\n\n\ttype ext struct {\n\t\tdesc protoreflect.FieldDescriptor\n\t\tval  protoreflect.Value\n\t}\n\tvar exts []ext\n\tm.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {\n\t\tif fd.IsExtension() {\n\t\t\texts = append(exts, ext{fd, v})\n\t\t}\n\t\treturn true\n\t})\n\tsort.Slice(exts, func(i, j int) bool {\n\t\treturn exts[i].desc.Number() < exts[j].desc.Number()\n\t})\n\n\tfor _, ext := range exts {\n\t\t// For message set, use the name of the message as the extension name.\n\t\tname := string(ext.desc.FullName())\n\t\tif isMessageSet(ext.desc.ContainingMessage()) {\n\t\t\tname = strings.TrimSuffix(name, \".message_set_extension\")\n\t\t}\n\n\t\tif !ext.desc.IsList() {\n\t\t\tif err := w.writeSingularExtension(name, ext.val, ext.desc); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tlv := ext.val.List()\n\t\t\tfor i := 0; i < lv.Len(); i++ {\n\t\t\t\tif err := w.writeSingularExtension(name, lv.Get(i), ext.desc); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (w *textWriter) writeSingularExtension(name string, v protoreflect.Value, fd protoreflect.FieldDescriptor) error {\n\tfmt.Fprintf(w, \"[%s]:\", name)\n\tif !w.compact {\n\t\tw.WriteByte(' ')\n\t}\n\tif err := w.writeSingularValue(v, fd); err != nil {\n\t\treturn err\n\t}\n\tw.WriteByte('\\n')\n\treturn nil\n}\n\nfunc (w *textWriter) writeIndent() {\n\tif !w.complete {\n\t\treturn\n\t}\n\tfor i := 0; i < w.indent*2; i++ {\n\t\tw.buf = append(w.buf, ' ')\n\t}\n\tw.complete = false\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/wire.go",
    "content": "// Copyright 2019 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 proto\n\nimport (\n\tprotoV2 \"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/runtime/protoiface\"\n)\n\n// Size returns the size in bytes of the wire-format encoding of m.\nfunc Size(m Message) int {\n\tif m == nil {\n\t\treturn 0\n\t}\n\tmi := MessageV2(m)\n\treturn protoV2.Size(mi)\n}\n\n// Marshal returns the wire-format encoding of m.\nfunc Marshal(m Message) ([]byte, error) {\n\tb, err := marshalAppend(nil, m, false)\n\tif b == nil {\n\t\tb = zeroBytes\n\t}\n\treturn b, err\n}\n\nvar zeroBytes = make([]byte, 0, 0)\n\nfunc marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) {\n\tif m == nil {\n\t\treturn nil, ErrNil\n\t}\n\tmi := MessageV2(m)\n\tnbuf, err := protoV2.MarshalOptions{\n\t\tDeterministic: deterministic,\n\t\tAllowPartial:  true,\n\t}.MarshalAppend(buf, mi)\n\tif err != nil {\n\t\treturn buf, err\n\t}\n\tif len(buf) == len(nbuf) {\n\t\tif !mi.ProtoReflect().IsValid() {\n\t\t\treturn buf, ErrNil\n\t\t}\n\t}\n\treturn nbuf, checkRequiredNotSet(mi)\n}\n\n// Unmarshal parses a wire-format message in b and places the decoded results in m.\n//\n// Unmarshal resets m before starting to unmarshal, so any existing data in m is always\n// removed. Use UnmarshalMerge to preserve and append to existing data.\nfunc Unmarshal(b []byte, m Message) error {\n\tm.Reset()\n\treturn UnmarshalMerge(b, m)\n}\n\n// UnmarshalMerge parses a wire-format message in b and places the decoded results in m.\nfunc UnmarshalMerge(b []byte, m Message) error {\n\tmi := MessageV2(m)\n\tout, err := protoV2.UnmarshalOptions{\n\t\tAllowPartial: true,\n\t\tMerge:        true,\n\t}.UnmarshalState(protoiface.UnmarshalInput{\n\t\tBuf:     b,\n\t\tMessage: mi.ProtoReflect(),\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tif out.Flags&protoiface.UnmarshalInitialized > 0 {\n\t\treturn nil\n\t}\n\treturn checkRequiredNotSet(mi)\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/proto/wrappers.go",
    "content": "// Copyright 2019 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 proto\n\n// Bool stores v in a new bool value and returns a pointer to it.\nfunc Bool(v bool) *bool { return &v }\n\n// Int stores v in a new int32 value and returns a pointer to it.\n//\n// Deprecated: Use Int32 instead.\nfunc Int(v int) *int32 { return Int32(int32(v)) }\n\n// Int32 stores v in a new int32 value and returns a pointer to it.\nfunc Int32(v int32) *int32 { return &v }\n\n// Int64 stores v in a new int64 value and returns a pointer to it.\nfunc Int64(v int64) *int64 { return &v }\n\n// Uint32 stores v in a new uint32 value and returns a pointer to it.\nfunc Uint32(v uint32) *uint32 { return &v }\n\n// Uint64 stores v in a new uint64 value and returns a pointer to it.\nfunc Uint64(v uint64) *uint64 { return &v }\n\n// Float32 stores v in a new float32 value and returns a pointer to it.\nfunc Float32(v float32) *float32 { return &v }\n\n// Float64 stores v in a new float64 value and returns a pointer to it.\nfunc Float64(v float64) *float64 { return &v }\n\n// String stores v in a new string value and returns a pointer to it.\nfunc String(v string) *string { return &v }\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/any/any.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: github.com/golang/protobuf/ptypes/any/any.proto\n\npackage any\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\tanypb \"google.golang.org/protobuf/types/known/anypb\"\n\treflect \"reflect\"\n)\n\n// Symbols defined in public import of google/protobuf/any.proto.\n\ntype Any = anypb.Any\n\nvar File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor\n\nvar file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{\n\t0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,\n\t0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,\n\t0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,\n\t0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29,\n\t0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e,\n\t0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65,\n\t0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x33,\n}\n\nvar file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{}\nvar file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{\n\t0, // [0:0] is the sub-list for method output_type\n\t0, // [0:0] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() }\nfunc file_github_com_golang_protobuf_ptypes_any_any_proto_init() {\n\tif File_github_com_golang_protobuf_ptypes_any_any_proto != nil {\n\t\treturn\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_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   0,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes,\n\t\tDependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs,\n\t}.Build()\n\tFile_github_com_golang_protobuf_ptypes_any_any_proto = out.File\n\tfile_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil\n\tfile_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil\n\tfile_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/any.go",
    "content": "// Copyright 2016 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 ptypes\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"google.golang.org/protobuf/reflect/protoreflect\"\n\t\"google.golang.org/protobuf/reflect/protoregistry\"\n\n\tanypb \"github.com/golang/protobuf/ptypes/any\"\n)\n\nconst urlPrefix = \"type.googleapis.com/\"\n\n// AnyMessageName returns the message name contained in an anypb.Any message.\n// Most type assertions should use the Is function instead.\n//\n// Deprecated: Call the any.MessageName method instead.\nfunc AnyMessageName(any *anypb.Any) (string, error) {\n\tname, err := anyMessageName(any)\n\treturn string(name), err\n}\nfunc anyMessageName(any *anypb.Any) (protoreflect.FullName, error) {\n\tif any == nil {\n\t\treturn \"\", fmt.Errorf(\"message is nil\")\n\t}\n\tname := protoreflect.FullName(any.TypeUrl)\n\tif i := strings.LastIndex(any.TypeUrl, \"/\"); i >= 0 {\n\t\tname = name[i+len(\"/\"):]\n\t}\n\tif !name.IsValid() {\n\t\treturn \"\", fmt.Errorf(\"message type url %q is invalid\", any.TypeUrl)\n\t}\n\treturn name, nil\n}\n\n// MarshalAny marshals the given message m into an anypb.Any message.\n//\n// Deprecated: Call the anypb.New function instead.\nfunc MarshalAny(m proto.Message) (*anypb.Any, error) {\n\tswitch dm := m.(type) {\n\tcase DynamicAny:\n\t\tm = dm.Message\n\tcase *DynamicAny:\n\t\tif dm == nil {\n\t\t\treturn nil, proto.ErrNil\n\t\t}\n\t\tm = dm.Message\n\t}\n\tb, err := proto.Marshal(m)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil\n}\n\n// Empty returns a new message of the type specified in an anypb.Any message.\n// It returns protoregistry.NotFound if the corresponding message type could not\n// be resolved in the global registry.\n//\n// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead\n// to resolve the message name and create a new instance of it.\nfunc Empty(any *anypb.Any) (proto.Message, error) {\n\tname, err := anyMessageName(any)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmt, err := protoregistry.GlobalTypes.FindMessageByName(name)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn proto.MessageV1(mt.New().Interface()), nil\n}\n\n// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message\n// into the provided message m. It returns an error if the target message\n// does not match the type in the Any message or if an unmarshal error occurs.\n//\n// The target message m may be a *DynamicAny message. If the underlying message\n// type could not be resolved, then this returns protoregistry.NotFound.\n//\n// Deprecated: Call the any.UnmarshalTo method instead.\nfunc UnmarshalAny(any *anypb.Any, m proto.Message) error {\n\tif dm, ok := m.(*DynamicAny); ok {\n\t\tif dm.Message == nil {\n\t\t\tvar err error\n\t\t\tdm.Message, err = Empty(any)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tm = dm.Message\n\t}\n\n\tanyName, err := AnyMessageName(any)\n\tif err != nil {\n\t\treturn err\n\t}\n\tmsgName := proto.MessageName(m)\n\tif anyName != msgName {\n\t\treturn fmt.Errorf(\"mismatched message type: got %q want %q\", anyName, msgName)\n\t}\n\treturn proto.Unmarshal(any.Value, m)\n}\n\n// Is reports whether the Any message contains a message of the specified type.\n//\n// Deprecated: Call the any.MessageIs method instead.\nfunc Is(any *anypb.Any, m proto.Message) bool {\n\tif any == nil || m == nil {\n\t\treturn false\n\t}\n\tname := proto.MessageName(m)\n\tif !strings.HasSuffix(any.TypeUrl, name) {\n\t\treturn false\n\t}\n\treturn len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/'\n}\n\n// DynamicAny is a value that can be passed to UnmarshalAny to automatically\n// allocate a proto.Message for the type specified in an anypb.Any message.\n// The allocated message is stored in the embedded proto.Message.\n//\n// Example:\n//   var x ptypes.DynamicAny\n//   if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }\n//   fmt.Printf(\"unmarshaled message: %v\", x.Message)\n//\n// Deprecated: Use the any.UnmarshalNew method instead to unmarshal\n// the any message contents into a new instance of the underlying message.\ntype DynamicAny struct{ proto.Message }\n\nfunc (m DynamicAny) String() string {\n\tif m.Message == nil {\n\t\treturn \"<nil>\"\n\t}\n\treturn m.Message.String()\n}\nfunc (m DynamicAny) Reset() {\n\tif m.Message == nil {\n\t\treturn\n\t}\n\tm.Message.Reset()\n}\nfunc (m DynamicAny) ProtoMessage() {\n\treturn\n}\nfunc (m DynamicAny) ProtoReflect() protoreflect.Message {\n\tif m.Message == nil {\n\t\treturn nil\n\t}\n\treturn dynamicAny{proto.MessageReflect(m.Message)}\n}\n\ntype dynamicAny struct{ protoreflect.Message }\n\nfunc (m dynamicAny) Type() protoreflect.MessageType {\n\treturn dynamicAnyType{m.Message.Type()}\n}\nfunc (m dynamicAny) New() protoreflect.Message {\n\treturn dynamicAnyType{m.Message.Type()}.New()\n}\nfunc (m dynamicAny) Interface() protoreflect.ProtoMessage {\n\treturn DynamicAny{proto.MessageV1(m.Message.Interface())}\n}\n\ntype dynamicAnyType struct{ protoreflect.MessageType }\n\nfunc (t dynamicAnyType) New() protoreflect.Message {\n\treturn dynamicAny{t.MessageType.New()}\n}\nfunc (t dynamicAnyType) Zero() protoreflect.Message {\n\treturn dynamicAny{t.MessageType.Zero()}\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/doc.go",
    "content": "// Copyright 2016 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// Package ptypes provides functionality for interacting with well-known types.\n//\n// Deprecated: Well-known types have specialized functionality directly\n// injected into the generated packages for each message type.\n// See the deprecation notice for each function for the suggested alternative.\npackage ptypes\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: github.com/golang/protobuf/ptypes/duration/duration.proto\n\npackage duration\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\tdurationpb \"google.golang.org/protobuf/types/known/durationpb\"\n\treflect \"reflect\"\n)\n\n// Symbols defined in public import of google/protobuf/duration.proto.\n\ntype Duration = durationpb.Duration\n\nvar File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor\n\nvar file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{\n\t0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,\n\t0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,\n\t0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f,\n\t0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67,\n\t0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67,\n\t0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73,\n\t0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69,\n\t0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{}\nvar file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{\n\t0, // [0:0] is the sub-list for method output_type\n\t0, // [0:0] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() }\nfunc file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() {\n\tif File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil {\n\t\treturn\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_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   0,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes,\n\t\tDependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs,\n\t}.Build()\n\tFile_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File\n\tfile_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil\n\tfile_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil\n\tfile_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/duration.go",
    "content": "// Copyright 2016 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 ptypes\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\tdurationpb \"github.com/golang/protobuf/ptypes/duration\"\n)\n\n// Range of google.protobuf.Duration as specified in duration.proto.\n// This is about 10,000 years in seconds.\nconst (\n\tmaxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)\n\tminSeconds = -maxSeconds\n)\n\n// Duration converts a durationpb.Duration to a time.Duration.\n// Duration returns an error if dur is invalid or overflows a time.Duration.\n//\n// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead.\nfunc Duration(dur *durationpb.Duration) (time.Duration, error) {\n\tif err := validateDuration(dur); err != nil {\n\t\treturn 0, err\n\t}\n\td := time.Duration(dur.Seconds) * time.Second\n\tif int64(d/time.Second) != dur.Seconds {\n\t\treturn 0, fmt.Errorf(\"duration: %v is out of range for time.Duration\", dur)\n\t}\n\tif dur.Nanos != 0 {\n\t\td += time.Duration(dur.Nanos) * time.Nanosecond\n\t\tif (d < 0) != (dur.Nanos < 0) {\n\t\t\treturn 0, fmt.Errorf(\"duration: %v is out of range for time.Duration\", dur)\n\t\t}\n\t}\n\treturn d, nil\n}\n\n// DurationProto converts a time.Duration to a durationpb.Duration.\n//\n// Deprecated: Call the durationpb.New function instead.\nfunc DurationProto(d time.Duration) *durationpb.Duration {\n\tnanos := d.Nanoseconds()\n\tsecs := nanos / 1e9\n\tnanos -= secs * 1e9\n\treturn &durationpb.Duration{\n\t\tSeconds: int64(secs),\n\t\tNanos:   int32(nanos),\n\t}\n}\n\n// validateDuration determines whether the durationpb.Duration is valid\n// according to the definition in google/protobuf/duration.proto.\n// A valid durpb.Duration may still be too large to fit into a time.Duration\n// Note that the range of durationpb.Duration is about 10,000 years,\n// while the range of time.Duration is about 290 years.\nfunc validateDuration(dur *durationpb.Duration) error {\n\tif dur == nil {\n\t\treturn errors.New(\"duration: nil Duration\")\n\t}\n\tif dur.Seconds < minSeconds || dur.Seconds > maxSeconds {\n\t\treturn fmt.Errorf(\"duration: %v: seconds out of range\", dur)\n\t}\n\tif dur.Nanos <= -1e9 || dur.Nanos >= 1e9 {\n\t\treturn fmt.Errorf(\"duration: %v: nanos out of range\", dur)\n\t}\n\t// Seconds and Nanos must have the same sign, unless d.Nanos is zero.\n\tif (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) {\n\t\treturn fmt.Errorf(\"duration: %v: seconds and nanos have different signs\", dur)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto\n\npackage timestamp\n\nimport (\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\treflect \"reflect\"\n)\n\n// Symbols defined in public import of google/protobuf/timestamp.proto.\n\ntype Timestamp = timestamppb.Timestamp\n\nvar File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor\n\nvar file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{\n\t0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,\n\t0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,\n\t0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69,\n\t0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67,\n\t0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74,\n\t0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37,\n\t0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c,\n\t0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79,\n\t0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69,\n\t0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x33,\n}\n\nvar file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{}\nvar file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{\n\t0, // [0:0] is the sub-list for method output_type\n\t0, // [0:0] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() }\nfunc file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() {\n\tif File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil {\n\t\treturn\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_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   0,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes,\n\t\tDependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs,\n\t}.Build()\n\tFile_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File\n\tfile_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil\n\tfile_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil\n\tfile_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/github.com/golang/protobuf/ptypes/timestamp.go",
    "content": "// Copyright 2016 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 ptypes\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"time\"\n\n\ttimestamppb \"github.com/golang/protobuf/ptypes/timestamp\"\n)\n\n// Range of google.protobuf.Duration as specified in timestamp.proto.\nconst (\n\t// Seconds field of the earliest valid Timestamp.\n\t// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().\n\tminValidSeconds = -62135596800\n\t// Seconds field just after the latest valid Timestamp.\n\t// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().\n\tmaxValidSeconds = 253402300800\n)\n\n// Timestamp converts a timestamppb.Timestamp to a time.Time.\n// It returns an error if the argument is invalid.\n//\n// Unlike most Go functions, if Timestamp returns an error, the first return\n// value is not the zero time.Time. Instead, it is the value obtained from the\n// time.Unix function when passed the contents of the Timestamp, in the UTC\n// locale. This may or may not be a meaningful time; many invalid Timestamps\n// do map to valid time.Times.\n//\n// A nil Timestamp returns an error. The first return value in that case is\n// undefined.\n//\n// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead.\nfunc Timestamp(ts *timestamppb.Timestamp) (time.Time, error) {\n\t// Don't return the zero value on error, because corresponds to a valid\n\t// timestamp. Instead return whatever time.Unix gives us.\n\tvar t time.Time\n\tif ts == nil {\n\t\tt = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp\n\t} else {\n\t\tt = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()\n\t}\n\treturn t, validateTimestamp(ts)\n}\n\n// TimestampNow returns a google.protobuf.Timestamp for the current time.\n//\n// Deprecated: Call the timestamppb.Now function instead.\nfunc TimestampNow() *timestamppb.Timestamp {\n\tts, err := TimestampProto(time.Now())\n\tif err != nil {\n\t\tpanic(\"ptypes: time.Now() out of Timestamp range\")\n\t}\n\treturn ts\n}\n\n// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.\n// It returns an error if the resulting Timestamp is invalid.\n//\n// Deprecated: Call the timestamppb.New function instead.\nfunc TimestampProto(t time.Time) (*timestamppb.Timestamp, error) {\n\tts := &timestamppb.Timestamp{\n\t\tSeconds: t.Unix(),\n\t\tNanos:   int32(t.Nanosecond()),\n\t}\n\tif err := validateTimestamp(ts); err != nil {\n\t\treturn nil, err\n\t}\n\treturn ts, nil\n}\n\n// TimestampString returns the RFC 3339 string for valid Timestamps.\n// For invalid Timestamps, it returns an error message in parentheses.\n//\n// Deprecated: Call the ts.AsTime method instead,\n// followed by a call to the Format method on the time.Time value.\nfunc TimestampString(ts *timestamppb.Timestamp) string {\n\tt, err := Timestamp(ts)\n\tif err != nil {\n\t\treturn fmt.Sprintf(\"(%v)\", err)\n\t}\n\treturn t.Format(time.RFC3339Nano)\n}\n\n// validateTimestamp determines whether a Timestamp is valid.\n// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01)\n// and has a Nanos field in the range [0, 1e9).\n//\n// If the Timestamp is valid, validateTimestamp returns nil.\n// Otherwise, it returns an error that describes the problem.\n//\n// Every valid Timestamp can be represented by a time.Time,\n// but the converse is not true.\nfunc validateTimestamp(ts *timestamppb.Timestamp) error {\n\tif ts == nil {\n\t\treturn errors.New(\"timestamp: nil Timestamp\")\n\t}\n\tif ts.Seconds < minValidSeconds {\n\t\treturn fmt.Errorf(\"timestamp: %v before 0001-01-01\", ts)\n\t}\n\tif ts.Seconds >= maxValidSeconds {\n\t\treturn fmt.Errorf(\"timestamp: %v after 10000-01-01\", ts)\n\t}\n\tif ts.Nanos < 0 || ts.Nanos >= 1e9 {\n\t\treturn fmt.Errorf(\"timestamp: %v: nanos not in range [0, 1e9)\", ts)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/btree/.travis.yml",
    "content": "language: go\n"
  },
  {
    "path": "vendor/github.com/google/btree/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/google/btree/README.md",
    "content": "# BTree implementation for Go\n\n![Travis CI Build Status](https://api.travis-ci.org/google/btree.svg?branch=master)\n\nThis package provides an in-memory B-Tree implementation for Go, useful as\nan ordered, mutable data structure.\n\nThe API is based off of the wonderful\nhttp://godoc.org/github.com/petar/GoLLRB/llrb, and is meant to allow btree to\nact as a drop-in replacement for gollrb trees.\n\nSee http://godoc.org/github.com/google/btree for documentation.\n"
  },
  {
    "path": "vendor/github.com/google/btree/btree.go",
    "content": "// Copyright 2014 Google 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//     http://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\n// Package btree implements in-memory B-Trees of arbitrary degree.\n//\n// btree implements an in-memory B-Tree for use as an ordered data structure.\n// It is not meant for persistent storage solutions.\n//\n// It has a flatter structure than an equivalent red-black or other binary tree,\n// which in some cases yields better memory usage and/or performance.\n// See some discussion on the matter here:\n//   http://google-opensource.blogspot.com/2013/01/c-containers-that-save-memory-and-time.html\n// Note, though, that this project is in no way related to the C++ B-Tree\n// implementation written about there.\n//\n// Within this tree, each node contains a slice of items and a (possibly nil)\n// slice of children.  For basic numeric values or raw structs, this can cause\n// efficiency differences when compared to equivalent C++ template code that\n// stores values in arrays within the node:\n//   * Due to the overhead of storing values as interfaces (each\n//     value needs to be stored as the value itself, then 2 words for the\n//     interface pointing to that value and its type), resulting in higher\n//     memory use.\n//   * Since interfaces can point to values anywhere in memory, values are\n//     most likely not stored in contiguous blocks, resulting in a higher\n//     number of cache misses.\n// These issues don't tend to matter, though, when working with strings or other\n// heap-allocated structures, since C++-equivalent structures also must store\n// pointers and also distribute their values across the heap.\n//\n// This implementation is designed to be a drop-in replacement to gollrb.LLRB\n// trees, (http://github.com/petar/gollrb), an excellent and probably the most\n// widely used ordered tree implementation in the Go ecosystem currently.\n// Its functions, therefore, exactly mirror those of\n// llrb.LLRB where possible.  Unlike gollrb, though, we currently don't\n// support storing multiple equivalent values.\npackage btree\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// Item represents a single object in the tree.\ntype Item interface {\n\t// Less tests whether the current item is less than the given argument.\n\t//\n\t// This must provide a strict weak ordering.\n\t// If !a.Less(b) && !b.Less(a), we treat this to mean a == b (i.e. we can only\n\t// hold one of either a or b in the tree).\n\tLess(than Item) bool\n}\n\nconst (\n\tDefaultFreeListSize = 32\n)\n\nvar (\n\tnilItems    = make(items, 16)\n\tnilChildren = make(children, 16)\n)\n\n// FreeList represents a free list of btree nodes. By default each\n// BTree has its own FreeList, but multiple BTrees can share the same\n// FreeList.\n// Two Btrees using the same freelist are safe for concurrent write access.\ntype FreeList struct {\n\tmu       sync.Mutex\n\tfreelist []*node\n}\n\n// NewFreeList creates a new free list.\n// size is the maximum size of the returned free list.\nfunc NewFreeList(size int) *FreeList {\n\treturn &FreeList{freelist: make([]*node, 0, size)}\n}\n\nfunc (f *FreeList) newNode() (n *node) {\n\tf.mu.Lock()\n\tindex := len(f.freelist) - 1\n\tif index < 0 {\n\t\tf.mu.Unlock()\n\t\treturn new(node)\n\t}\n\tn = f.freelist[index]\n\tf.freelist[index] = nil\n\tf.freelist = f.freelist[:index]\n\tf.mu.Unlock()\n\treturn\n}\n\n// freeNode adds the given node to the list, returning true if it was added\n// and false if it was discarded.\nfunc (f *FreeList) freeNode(n *node) (out bool) {\n\tf.mu.Lock()\n\tif len(f.freelist) < cap(f.freelist) {\n\t\tf.freelist = append(f.freelist, n)\n\t\tout = true\n\t}\n\tf.mu.Unlock()\n\treturn\n}\n\n// ItemIterator allows callers of Ascend* to iterate in-order over portions of\n// the tree.  When this function returns false, iteration will stop and the\n// associated Ascend* function will immediately return.\ntype ItemIterator func(i Item) bool\n\n// New creates a new B-Tree with the given degree.\n//\n// New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items\n// and 2-4 children).\nfunc New(degree int) *BTree {\n\treturn NewWithFreeList(degree, NewFreeList(DefaultFreeListSize))\n}\n\n// NewWithFreeList creates a new B-Tree that uses the given node free list.\nfunc NewWithFreeList(degree int, f *FreeList) *BTree {\n\tif degree <= 1 {\n\t\tpanic(\"bad degree\")\n\t}\n\treturn &BTree{\n\t\tdegree: degree,\n\t\tcow:    &copyOnWriteContext{freelist: f},\n\t}\n}\n\n// items stores items in a node.\ntype items []Item\n\n// insertAt inserts a value into the given index, pushing all subsequent values\n// forward.\nfunc (s *items) insertAt(index int, item Item) {\n\t*s = append(*s, nil)\n\tif index < len(*s) {\n\t\tcopy((*s)[index+1:], (*s)[index:])\n\t}\n\t(*s)[index] = item\n}\n\n// removeAt removes a value at a given index, pulling all subsequent values\n// back.\nfunc (s *items) removeAt(index int) Item {\n\titem := (*s)[index]\n\tcopy((*s)[index:], (*s)[index+1:])\n\t(*s)[len(*s)-1] = nil\n\t*s = (*s)[:len(*s)-1]\n\treturn item\n}\n\n// pop removes and returns the last element in the list.\nfunc (s *items) pop() (out Item) {\n\tindex := len(*s) - 1\n\tout = (*s)[index]\n\t(*s)[index] = nil\n\t*s = (*s)[:index]\n\treturn\n}\n\n// truncate truncates this instance at index so that it contains only the\n// first index items. index must be less than or equal to length.\nfunc (s *items) truncate(index int) {\n\tvar toClear items\n\t*s, toClear = (*s)[:index], (*s)[index:]\n\tfor len(toClear) > 0 {\n\t\ttoClear = toClear[copy(toClear, nilItems):]\n\t}\n}\n\n// find returns the index where the given item should be inserted into this\n// list.  'found' is true if the item already exists in the list at the given\n// index.\nfunc (s items) find(item Item) (index int, found bool) {\n\ti := sort.Search(len(s), func(i int) bool {\n\t\treturn item.Less(s[i])\n\t})\n\tif i > 0 && !s[i-1].Less(item) {\n\t\treturn i - 1, true\n\t}\n\treturn i, false\n}\n\n// children stores child nodes in a node.\ntype children []*node\n\n// insertAt inserts a value into the given index, pushing all subsequent values\n// forward.\nfunc (s *children) insertAt(index int, n *node) {\n\t*s = append(*s, nil)\n\tif index < len(*s) {\n\t\tcopy((*s)[index+1:], (*s)[index:])\n\t}\n\t(*s)[index] = n\n}\n\n// removeAt removes a value at a given index, pulling all subsequent values\n// back.\nfunc (s *children) removeAt(index int) *node {\n\tn := (*s)[index]\n\tcopy((*s)[index:], (*s)[index+1:])\n\t(*s)[len(*s)-1] = nil\n\t*s = (*s)[:len(*s)-1]\n\treturn n\n}\n\n// pop removes and returns the last element in the list.\nfunc (s *children) pop() (out *node) {\n\tindex := len(*s) - 1\n\tout = (*s)[index]\n\t(*s)[index] = nil\n\t*s = (*s)[:index]\n\treturn\n}\n\n// truncate truncates this instance at index so that it contains only the\n// first index children. index must be less than or equal to length.\nfunc (s *children) truncate(index int) {\n\tvar toClear children\n\t*s, toClear = (*s)[:index], (*s)[index:]\n\tfor len(toClear) > 0 {\n\t\ttoClear = toClear[copy(toClear, nilChildren):]\n\t}\n}\n\n// node is an internal node in a tree.\n//\n// It must at all times maintain the invariant that either\n//   * len(children) == 0, len(items) unconstrained\n//   * len(children) == len(items) + 1\ntype node struct {\n\titems    items\n\tchildren children\n\tcow      *copyOnWriteContext\n}\n\nfunc (n *node) mutableFor(cow *copyOnWriteContext) *node {\n\tif n.cow == cow {\n\t\treturn n\n\t}\n\tout := cow.newNode()\n\tif cap(out.items) >= len(n.items) {\n\t\tout.items = out.items[:len(n.items)]\n\t} else {\n\t\tout.items = make(items, len(n.items), cap(n.items))\n\t}\n\tcopy(out.items, n.items)\n\t// Copy children\n\tif cap(out.children) >= len(n.children) {\n\t\tout.children = out.children[:len(n.children)]\n\t} else {\n\t\tout.children = make(children, len(n.children), cap(n.children))\n\t}\n\tcopy(out.children, n.children)\n\treturn out\n}\n\nfunc (n *node) mutableChild(i int) *node {\n\tc := n.children[i].mutableFor(n.cow)\n\tn.children[i] = c\n\treturn c\n}\n\n// split splits the given node at the given index.  The current node shrinks,\n// and this function returns the item that existed at that index and a new node\n// containing all items/children after it.\nfunc (n *node) split(i int) (Item, *node) {\n\titem := n.items[i]\n\tnext := n.cow.newNode()\n\tnext.items = append(next.items, n.items[i+1:]...)\n\tn.items.truncate(i)\n\tif len(n.children) > 0 {\n\t\tnext.children = append(next.children, n.children[i+1:]...)\n\t\tn.children.truncate(i + 1)\n\t}\n\treturn item, next\n}\n\n// maybeSplitChild checks if a child should be split, and if so splits it.\n// Returns whether or not a split occurred.\nfunc (n *node) maybeSplitChild(i, maxItems int) bool {\n\tif len(n.children[i].items) < maxItems {\n\t\treturn false\n\t}\n\tfirst := n.mutableChild(i)\n\titem, second := first.split(maxItems / 2)\n\tn.items.insertAt(i, item)\n\tn.children.insertAt(i+1, second)\n\treturn true\n}\n\n// insert inserts an item into the subtree rooted at this node, making sure\n// no nodes in the subtree exceed maxItems items.  Should an equivalent item be\n// be found/replaced by insert, it will be returned.\nfunc (n *node) insert(item Item, maxItems int) Item {\n\ti, found := n.items.find(item)\n\tif found {\n\t\tout := n.items[i]\n\t\tn.items[i] = item\n\t\treturn out\n\t}\n\tif len(n.children) == 0 {\n\t\tn.items.insertAt(i, item)\n\t\treturn nil\n\t}\n\tif n.maybeSplitChild(i, maxItems) {\n\t\tinTree := n.items[i]\n\t\tswitch {\n\t\tcase item.Less(inTree):\n\t\t\t// no change, we want first split node\n\t\tcase inTree.Less(item):\n\t\t\ti++ // we want second split node\n\t\tdefault:\n\t\t\tout := n.items[i]\n\t\t\tn.items[i] = item\n\t\t\treturn out\n\t\t}\n\t}\n\treturn n.mutableChild(i).insert(item, maxItems)\n}\n\n// get finds the given key in the subtree and returns it.\nfunc (n *node) get(key Item) Item {\n\ti, found := n.items.find(key)\n\tif found {\n\t\treturn n.items[i]\n\t} else if len(n.children) > 0 {\n\t\treturn n.children[i].get(key)\n\t}\n\treturn nil\n}\n\n// min returns the first item in the subtree.\nfunc min(n *node) Item {\n\tif n == nil {\n\t\treturn nil\n\t}\n\tfor len(n.children) > 0 {\n\t\tn = n.children[0]\n\t}\n\tif len(n.items) == 0 {\n\t\treturn nil\n\t}\n\treturn n.items[0]\n}\n\n// max returns the last item in the subtree.\nfunc max(n *node) Item {\n\tif n == nil {\n\t\treturn nil\n\t}\n\tfor len(n.children) > 0 {\n\t\tn = n.children[len(n.children)-1]\n\t}\n\tif len(n.items) == 0 {\n\t\treturn nil\n\t}\n\treturn n.items[len(n.items)-1]\n}\n\n// toRemove details what item to remove in a node.remove call.\ntype toRemove int\n\nconst (\n\tremoveItem toRemove = iota // removes the given item\n\tremoveMin                  // removes smallest item in the subtree\n\tremoveMax                  // removes largest item in the subtree\n)\n\n// remove removes an item from the subtree rooted at this node.\nfunc (n *node) remove(item Item, minItems int, typ toRemove) Item {\n\tvar i int\n\tvar found bool\n\tswitch typ {\n\tcase removeMax:\n\t\tif len(n.children) == 0 {\n\t\t\treturn n.items.pop()\n\t\t}\n\t\ti = len(n.items)\n\tcase removeMin:\n\t\tif len(n.children) == 0 {\n\t\t\treturn n.items.removeAt(0)\n\t\t}\n\t\ti = 0\n\tcase removeItem:\n\t\ti, found = n.items.find(item)\n\t\tif len(n.children) == 0 {\n\t\t\tif found {\n\t\t\t\treturn n.items.removeAt(i)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\tdefault:\n\t\tpanic(\"invalid type\")\n\t}\n\t// If we get to here, we have children.\n\tif len(n.children[i].items) <= minItems {\n\t\treturn n.growChildAndRemove(i, item, minItems, typ)\n\t}\n\tchild := n.mutableChild(i)\n\t// Either we had enough items to begin with, or we've done some\n\t// merging/stealing, because we've got enough now and we're ready to return\n\t// stuff.\n\tif found {\n\t\t// The item exists at index 'i', and the child we've selected can give us a\n\t\t// predecessor, since if we've gotten here it's got > minItems items in it.\n\t\tout := n.items[i]\n\t\t// We use our special-case 'remove' call with typ=maxItem to pull the\n\t\t// predecessor of item i (the rightmost leaf of our immediate left child)\n\t\t// and set it into where we pulled the item from.\n\t\tn.items[i] = child.remove(nil, minItems, removeMax)\n\t\treturn out\n\t}\n\t// Final recursive call.  Once we're here, we know that the item isn't in this\n\t// node and that the child is big enough to remove from.\n\treturn child.remove(item, minItems, typ)\n}\n\n// growChildAndRemove grows child 'i' to make sure it's possible to remove an\n// item from it while keeping it at minItems, then calls remove to actually\n// remove it.\n//\n// Most documentation says we have to do two sets of special casing:\n//   1) item is in this node\n//   2) item is in child\n// In both cases, we need to handle the two subcases:\n//   A) node has enough values that it can spare one\n//   B) node doesn't have enough values\n// For the latter, we have to check:\n//   a) left sibling has node to spare\n//   b) right sibling has node to spare\n//   c) we must merge\n// To simplify our code here, we handle cases #1 and #2 the same:\n// If a node doesn't have enough items, we make sure it does (using a,b,c).\n// We then simply redo our remove call, and the second time (regardless of\n// whether we're in case 1 or 2), we'll have enough items and can guarantee\n// that we hit case A.\nfunc (n *node) growChildAndRemove(i int, item Item, minItems int, typ toRemove) Item {\n\tif i > 0 && len(n.children[i-1].items) > minItems {\n\t\t// Steal from left child\n\t\tchild := n.mutableChild(i)\n\t\tstealFrom := n.mutableChild(i - 1)\n\t\tstolenItem := stealFrom.items.pop()\n\t\tchild.items.insertAt(0, n.items[i-1])\n\t\tn.items[i-1] = stolenItem\n\t\tif len(stealFrom.children) > 0 {\n\t\t\tchild.children.insertAt(0, stealFrom.children.pop())\n\t\t}\n\t} else if i < len(n.items) && len(n.children[i+1].items) > minItems {\n\t\t// steal from right child\n\t\tchild := n.mutableChild(i)\n\t\tstealFrom := n.mutableChild(i + 1)\n\t\tstolenItem := stealFrom.items.removeAt(0)\n\t\tchild.items = append(child.items, n.items[i])\n\t\tn.items[i] = stolenItem\n\t\tif len(stealFrom.children) > 0 {\n\t\t\tchild.children = append(child.children, stealFrom.children.removeAt(0))\n\t\t}\n\t} else {\n\t\tif i >= len(n.items) {\n\t\t\ti--\n\t\t}\n\t\tchild := n.mutableChild(i)\n\t\t// merge with right child\n\t\tmergeItem := n.items.removeAt(i)\n\t\tmergeChild := n.children.removeAt(i + 1)\n\t\tchild.items = append(child.items, mergeItem)\n\t\tchild.items = append(child.items, mergeChild.items...)\n\t\tchild.children = append(child.children, mergeChild.children...)\n\t\tn.cow.freeNode(mergeChild)\n\t}\n\treturn n.remove(item, minItems, typ)\n}\n\ntype direction int\n\nconst (\n\tdescend = direction(-1)\n\tascend  = direction(+1)\n)\n\n// iterate provides a simple method for iterating over elements in the tree.\n//\n// When ascending, the 'start' should be less than 'stop' and when descending,\n// the 'start' should be greater than 'stop'. Setting 'includeStart' to true\n// will force the iterator to include the first item when it equals 'start',\n// thus creating a \"greaterOrEqual\" or \"lessThanEqual\" rather than just a\n// \"greaterThan\" or \"lessThan\" queries.\nfunc (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit bool, iter ItemIterator) (bool, bool) {\n\tvar ok, found bool\n\tvar index int\n\tswitch dir {\n\tcase ascend:\n\t\tif start != nil {\n\t\t\tindex, _ = n.items.find(start)\n\t\t}\n\t\tfor i := index; i < len(n.items); i++ {\n\t\t\tif len(n.children) > 0 {\n\t\t\t\tif hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok {\n\t\t\t\t\treturn hit, false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !includeStart && !hit && start != nil && !start.Less(n.items[i]) {\n\t\t\t\thit = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\thit = true\n\t\t\tif stop != nil && !n.items[i].Less(stop) {\n\t\t\t\treturn hit, false\n\t\t\t}\n\t\t\tif !iter(n.items[i]) {\n\t\t\t\treturn hit, false\n\t\t\t}\n\t\t}\n\t\tif len(n.children) > 0 {\n\t\t\tif hit, ok = n.children[len(n.children)-1].iterate(dir, start, stop, includeStart, hit, iter); !ok {\n\t\t\t\treturn hit, false\n\t\t\t}\n\t\t}\n\tcase descend:\n\t\tif start != nil {\n\t\t\tindex, found = n.items.find(start)\n\t\t\tif !found {\n\t\t\t\tindex = index - 1\n\t\t\t}\n\t\t} else {\n\t\t\tindex = len(n.items) - 1\n\t\t}\n\t\tfor i := index; i >= 0; i-- {\n\t\t\tif start != nil && !n.items[i].Less(start) {\n\t\t\t\tif !includeStart || hit || start.Less(n.items[i]) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(n.children) > 0 {\n\t\t\t\tif hit, ok = n.children[i+1].iterate(dir, start, stop, includeStart, hit, iter); !ok {\n\t\t\t\t\treturn hit, false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif stop != nil && !stop.Less(n.items[i]) {\n\t\t\t\treturn hit, false //\tcontinue\n\t\t\t}\n\t\t\thit = true\n\t\t\tif !iter(n.items[i]) {\n\t\t\t\treturn hit, false\n\t\t\t}\n\t\t}\n\t\tif len(n.children) > 0 {\n\t\t\tif hit, ok = n.children[0].iterate(dir, start, stop, includeStart, hit, iter); !ok {\n\t\t\t\treturn hit, false\n\t\t\t}\n\t\t}\n\t}\n\treturn hit, true\n}\n\n// Used for testing/debugging purposes.\nfunc (n *node) print(w io.Writer, level int) {\n\tfmt.Fprintf(w, \"%sNODE:%v\\n\", strings.Repeat(\"  \", level), n.items)\n\tfor _, c := range n.children {\n\t\tc.print(w, level+1)\n\t}\n}\n\n// BTree is an implementation of a B-Tree.\n//\n// BTree stores Item instances in an ordered structure, allowing easy insertion,\n// removal, and iteration.\n//\n// Write operations are not safe for concurrent mutation by multiple\n// goroutines, but Read operations are.\ntype BTree struct {\n\tdegree int\n\tlength int\n\troot   *node\n\tcow    *copyOnWriteContext\n}\n\n// copyOnWriteContext pointers determine node ownership... a tree with a write\n// context equivalent to a node's write context is allowed to modify that node.\n// A tree whose write context does not match a node's is not allowed to modify\n// it, and must create a new, writable copy (IE: it's a Clone).\n//\n// When doing any write operation, we maintain the invariant that the current\n// node's context is equal to the context of the tree that requested the write.\n// We do this by, before we descend into any node, creating a copy with the\n// correct context if the contexts don't match.\n//\n// Since the node we're currently visiting on any write has the requesting\n// tree's context, that node is modifiable in place.  Children of that node may\n// not share context, but before we descend into them, we'll make a mutable\n// copy.\ntype copyOnWriteContext struct {\n\tfreelist *FreeList\n}\n\n// Clone clones the btree, lazily.  Clone should not be called concurrently,\n// but the original tree (t) and the new tree (t2) can be used concurrently\n// once the Clone call completes.\n//\n// The internal tree structure of b is marked read-only and shared between t and\n// t2.  Writes to both t and t2 use copy-on-write logic, creating new nodes\n// whenever one of b's original nodes would have been modified.  Read operations\n// should have no performance degredation.  Write operations for both t and t2\n// will initially experience minor slow-downs caused by additional allocs and\n// copies due to the aforementioned copy-on-write logic, but should converge to\n// the original performance characteristics of the original tree.\nfunc (t *BTree) Clone() (t2 *BTree) {\n\t// Create two entirely new copy-on-write contexts.\n\t// This operation effectively creates three trees:\n\t//   the original, shared nodes (old b.cow)\n\t//   the new b.cow nodes\n\t//   the new out.cow nodes\n\tcow1, cow2 := *t.cow, *t.cow\n\tout := *t\n\tt.cow = &cow1\n\tout.cow = &cow2\n\treturn &out\n}\n\n// maxItems returns the max number of items to allow per node.\nfunc (t *BTree) maxItems() int {\n\treturn t.degree*2 - 1\n}\n\n// minItems returns the min number of items to allow per node (ignored for the\n// root node).\nfunc (t *BTree) minItems() int {\n\treturn t.degree - 1\n}\n\nfunc (c *copyOnWriteContext) newNode() (n *node) {\n\tn = c.freelist.newNode()\n\tn.cow = c\n\treturn\n}\n\ntype freeType int\n\nconst (\n\tftFreelistFull freeType = iota // node was freed (available for GC, not stored in freelist)\n\tftStored                       // node was stored in the freelist for later use\n\tftNotOwned                     // node was ignored by COW, since it's owned by another one\n)\n\n// freeNode frees a node within a given COW context, if it's owned by that\n// context.  It returns what happened to the node (see freeType const\n// documentation).\nfunc (c *copyOnWriteContext) freeNode(n *node) freeType {\n\tif n.cow == c {\n\t\t// clear to allow GC\n\t\tn.items.truncate(0)\n\t\tn.children.truncate(0)\n\t\tn.cow = nil\n\t\tif c.freelist.freeNode(n) {\n\t\t\treturn ftStored\n\t\t} else {\n\t\t\treturn ftFreelistFull\n\t\t}\n\t} else {\n\t\treturn ftNotOwned\n\t}\n}\n\n// ReplaceOrInsert adds the given item to the tree.  If an item in the tree\n// already equals the given one, it is removed from the tree and returned.\n// Otherwise, nil is returned.\n//\n// nil cannot be added to the tree (will panic).\nfunc (t *BTree) ReplaceOrInsert(item Item) Item {\n\tif item == nil {\n\t\tpanic(\"nil item being added to BTree\")\n\t}\n\tif t.root == nil {\n\t\tt.root = t.cow.newNode()\n\t\tt.root.items = append(t.root.items, item)\n\t\tt.length++\n\t\treturn nil\n\t} else {\n\t\tt.root = t.root.mutableFor(t.cow)\n\t\tif len(t.root.items) >= t.maxItems() {\n\t\t\titem2, second := t.root.split(t.maxItems() / 2)\n\t\t\toldroot := t.root\n\t\t\tt.root = t.cow.newNode()\n\t\t\tt.root.items = append(t.root.items, item2)\n\t\t\tt.root.children = append(t.root.children, oldroot, second)\n\t\t}\n\t}\n\tout := t.root.insert(item, t.maxItems())\n\tif out == nil {\n\t\tt.length++\n\t}\n\treturn out\n}\n\n// Delete removes an item equal to the passed in item from the tree, returning\n// it.  If no such item exists, returns nil.\nfunc (t *BTree) Delete(item Item) Item {\n\treturn t.deleteItem(item, removeItem)\n}\n\n// DeleteMin removes the smallest item in the tree and returns it.\n// If no such item exists, returns nil.\nfunc (t *BTree) DeleteMin() Item {\n\treturn t.deleteItem(nil, removeMin)\n}\n\n// DeleteMax removes the largest item in the tree and returns it.\n// If no such item exists, returns nil.\nfunc (t *BTree) DeleteMax() Item {\n\treturn t.deleteItem(nil, removeMax)\n}\n\nfunc (t *BTree) deleteItem(item Item, typ toRemove) Item {\n\tif t.root == nil || len(t.root.items) == 0 {\n\t\treturn nil\n\t}\n\tt.root = t.root.mutableFor(t.cow)\n\tout := t.root.remove(item, t.minItems(), typ)\n\tif len(t.root.items) == 0 && len(t.root.children) > 0 {\n\t\toldroot := t.root\n\t\tt.root = t.root.children[0]\n\t\tt.cow.freeNode(oldroot)\n\t}\n\tif out != nil {\n\t\tt.length--\n\t}\n\treturn out\n}\n\n// AscendRange calls the iterator for every value in the tree within the range\n// [greaterOrEqual, lessThan), until iterator returns false.\nfunc (t *BTree) AscendRange(greaterOrEqual, lessThan Item, iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(ascend, greaterOrEqual, lessThan, true, false, iterator)\n}\n\n// AscendLessThan calls the iterator for every value in the tree within the range\n// [first, pivot), until iterator returns false.\nfunc (t *BTree) AscendLessThan(pivot Item, iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(ascend, nil, pivot, false, false, iterator)\n}\n\n// AscendGreaterOrEqual calls the iterator for every value in the tree within\n// the range [pivot, last], until iterator returns false.\nfunc (t *BTree) AscendGreaterOrEqual(pivot Item, iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(ascend, pivot, nil, true, false, iterator)\n}\n\n// Ascend calls the iterator for every value in the tree within the range\n// [first, last], until iterator returns false.\nfunc (t *BTree) Ascend(iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(ascend, nil, nil, false, false, iterator)\n}\n\n// DescendRange calls the iterator for every value in the tree within the range\n// [lessOrEqual, greaterThan), until iterator returns false.\nfunc (t *BTree) DescendRange(lessOrEqual, greaterThan Item, iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(descend, lessOrEqual, greaterThan, true, false, iterator)\n}\n\n// DescendLessOrEqual calls the iterator for every value in the tree within the range\n// [pivot, first], until iterator returns false.\nfunc (t *BTree) DescendLessOrEqual(pivot Item, iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(descend, pivot, nil, true, false, iterator)\n}\n\n// DescendGreaterThan calls the iterator for every value in the tree within\n// the range [last, pivot), until iterator returns false.\nfunc (t *BTree) DescendGreaterThan(pivot Item, iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(descend, nil, pivot, false, false, iterator)\n}\n\n// Descend calls the iterator for every value in the tree within the range\n// [last, first], until iterator returns false.\nfunc (t *BTree) Descend(iterator ItemIterator) {\n\tif t.root == nil {\n\t\treturn\n\t}\n\tt.root.iterate(descend, nil, nil, false, false, iterator)\n}\n\n// Get looks for the key item in the tree, returning it.  It returns nil if\n// unable to find that item.\nfunc (t *BTree) Get(key Item) Item {\n\tif t.root == nil {\n\t\treturn nil\n\t}\n\treturn t.root.get(key)\n}\n\n// Min returns the smallest item in the tree, or nil if the tree is empty.\nfunc (t *BTree) Min() Item {\n\treturn min(t.root)\n}\n\n// Max returns the largest item in the tree, or nil if the tree is empty.\nfunc (t *BTree) Max() Item {\n\treturn max(t.root)\n}\n\n// Has returns true if the given key is in the tree.\nfunc (t *BTree) Has(key Item) bool {\n\treturn t.Get(key) != nil\n}\n\n// Len returns the number of items currently in the tree.\nfunc (t *BTree) Len() int {\n\treturn t.length\n}\n\n// Clear removes all items from the btree.  If addNodesToFreelist is true,\n// t's nodes are added to its freelist as part of this call, until the freelist\n// is full.  Otherwise, the root node is simply dereferenced and the subtree\n// left to Go's normal GC processes.\n//\n// This can be much faster\n// than calling Delete on all elements, because that requires finding/removing\n// each element in the tree and updating the tree accordingly.  It also is\n// somewhat faster than creating a new tree to replace the old one, because\n// nodes from the old tree are reclaimed into the freelist for use by the new\n// one, instead of being lost to the garbage collector.\n//\n// This call takes:\n//   O(1): when addNodesToFreelist is false, this is a single operation.\n//   O(1): when the freelist is already full, it breaks out immediately\n//   O(freelist size):  when the freelist is empty and the nodes are all owned\n//       by this tree, nodes are added to the freelist until full.\n//   O(tree size):  when all nodes are owned by another tree, all nodes are\n//       iterated over looking for nodes to add to the freelist, and due to\n//       ownership, none are.\nfunc (t *BTree) Clear(addNodesToFreelist bool) {\n\tif t.root != nil && addNodesToFreelist {\n\t\tt.root.reset(t.cow)\n\t}\n\tt.root, t.length = nil, 0\n}\n\n// reset returns a subtree to the freelist.  It breaks out immediately if the\n// freelist is full, since the only benefit of iterating is to fill that\n// freelist up.  Returns true if parent reset call should continue.\nfunc (n *node) reset(c *copyOnWriteContext) bool {\n\tfor _, child := range n.children {\n\t\tif !child.reset(c) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn c.freeNode(n) != ftFreelistFull\n}\n\n// Int implements the Item interface for integers.\ntype Int int\n\n// Less returns true if int(a) < int(b).\nfunc (a Int) Less(b Item) bool {\n\treturn a < b.(Int)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/compiler/README.md",
    "content": "# Compiler support code\n\nThis directory contains compiler support code used by Gnostic and Gnostic\nextensions.\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/compiler/context.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage compiler\n\nimport (\n\tyaml \"gopkg.in/yaml.v3\"\n)\n\n// Context contains state of the compiler as it traverses a document.\ntype Context struct {\n\tParent            *Context\n\tName              string\n\tNode              *yaml.Node\n\tExtensionHandlers *[]ExtensionHandler\n}\n\n// NewContextWithExtensions returns a new object representing the compiler state\nfunc NewContextWithExtensions(name string, node *yaml.Node, parent *Context, extensionHandlers *[]ExtensionHandler) *Context {\n\treturn &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: extensionHandlers}\n}\n\n// NewContext returns a new object representing the compiler state\nfunc NewContext(name string, node *yaml.Node, parent *Context) *Context {\n\tif parent != nil {\n\t\treturn &Context{Name: name, Node: node, Parent: parent, ExtensionHandlers: parent.ExtensionHandlers}\n\t}\n\treturn &Context{Name: name, Parent: parent, ExtensionHandlers: nil}\n}\n\n// Description returns a text description of the compiler state\nfunc (context *Context) Description() string {\n\tname := context.Name\n\tif context.Parent != nil {\n\t\tname = context.Parent.Description() + \".\" + name\n\t}\n\treturn name\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/compiler/error.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage compiler\n\nimport \"fmt\"\n\n// Error represents compiler errors and their location in the document.\ntype Error struct {\n\tContext *Context\n\tMessage string\n}\n\n// NewError creates an Error.\nfunc NewError(context *Context, message string) *Error {\n\treturn &Error{Context: context, Message: message}\n}\n\nfunc (err *Error) locationDescription() string {\n\tif err.Context.Node != nil {\n\t\treturn fmt.Sprintf(\"[%d,%d] %s\", err.Context.Node.Line, err.Context.Node.Column, err.Context.Description())\n\t}\n\treturn err.Context.Description()\n}\n\n// Error returns the string value of an Error.\nfunc (err *Error) Error() string {\n\tif err.Context == nil {\n\t\treturn err.Message\n\t}\n\treturn err.locationDescription() + \" \" + err.Message\n}\n\n// ErrorGroup is a container for groups of Error values.\ntype ErrorGroup struct {\n\tErrors []error\n}\n\n// NewErrorGroupOrNil returns a new ErrorGroup for a slice of errors or nil if the slice is empty.\nfunc NewErrorGroupOrNil(errors []error) error {\n\tif len(errors) == 0 {\n\t\treturn nil\n\t} else if len(errors) == 1 {\n\t\treturn errors[0]\n\t} else {\n\t\treturn &ErrorGroup{Errors: errors}\n\t}\n}\n\nfunc (group *ErrorGroup) Error() string {\n\tresult := \"\"\n\tfor i, err := range group.Errors {\n\t\tif i > 0 {\n\t\t\tresult += \"\\n\"\n\t\t}\n\t\tresult += err.Error()\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/compiler/extensions.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage compiler\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"github.com/golang/protobuf/ptypes/any\"\n\tyaml \"gopkg.in/yaml.v3\"\n\n\textensions \"github.com/google/gnostic/extensions\"\n)\n\n// ExtensionHandler describes a binary that is called by the compiler to handle specification extensions.\ntype ExtensionHandler struct {\n\tName string\n}\n\n// CallExtension calls a binary extension handler.\nfunc CallExtension(context *Context, in *yaml.Node, extensionName string) (handled bool, response *any.Any, err error) {\n\tif context == nil || context.ExtensionHandlers == nil {\n\t\treturn false, nil, nil\n\t}\n\thandled = false\n\tfor _, handler := range *(context.ExtensionHandlers) {\n\t\tresponse, err = handler.handle(in, extensionName)\n\t\tif response == nil {\n\t\t\tcontinue\n\t\t} else {\n\t\t\thandled = true\n\t\t\tbreak\n\t\t}\n\t}\n\treturn handled, response, err\n}\n\nfunc (extensionHandlers *ExtensionHandler) handle(in *yaml.Node, extensionName string) (*any.Any, error) {\n\tif extensionHandlers.Name != \"\" {\n\t\tyamlData, _ := yaml.Marshal(in)\n\t\trequest := &extensions.ExtensionHandlerRequest{\n\t\t\tCompilerVersion: &extensions.Version{\n\t\t\t\tMajor: 0,\n\t\t\t\tMinor: 1,\n\t\t\t\tPatch: 0,\n\t\t\t},\n\t\t\tWrapper: &extensions.Wrapper{\n\t\t\t\tVersion:       \"unknown\", // TODO: set this to the type/version of spec being parsed.\n\t\t\t\tYaml:          string(yamlData),\n\t\t\t\tExtensionName: extensionName,\n\t\t\t},\n\t\t}\n\t\trequestBytes, _ := proto.Marshal(request)\n\t\tcmd := exec.Command(extensionHandlers.Name)\n\t\tcmd.Stdin = bytes.NewReader(requestBytes)\n\t\toutput, err := cmd.Output()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tresponse := &extensions.ExtensionHandlerResponse{}\n\t\terr = proto.Unmarshal(output, response)\n\t\tif err != nil || !response.Handled {\n\t\t\treturn nil, err\n\t\t}\n\t\tif len(response.Errors) != 0 {\n\t\t\treturn nil, fmt.Errorf(\"Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v\", in, extensionName, extensionHandlers.Name, strings.Join(response.Errors, \",\"))\n\t\t}\n\t\treturn response.Value, nil\n\t}\n\treturn nil, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/compiler/helpers.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage compiler\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/google/gnostic/jsonschema\"\n)\n\n// compiler helper functions, usually called from generated code\n\n// UnpackMap gets a *yaml.Node if possible.\nfunc UnpackMap(in *yaml.Node) (*yaml.Node, bool) {\n\tif in == nil {\n\t\treturn nil, false\n\t}\n\treturn in, true\n}\n\n// SortedKeysForMap returns the sorted keys of a yamlv2.MapSlice.\nfunc SortedKeysForMap(m *yaml.Node) []string {\n\tkeys := make([]string, 0)\n\tif m.Kind == yaml.MappingNode {\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tkeys = append(keys, m.Content[i].Value)\n\t\t}\n\t}\n\tsort.Strings(keys)\n\treturn keys\n}\n\n// MapHasKey returns true if a yamlv2.MapSlice contains a specified key.\nfunc MapHasKey(m *yaml.Node, key string) bool {\n\tif m == nil {\n\t\treturn false\n\t}\n\tif m.Kind == yaml.MappingNode {\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\titemKey := m.Content[i].Value\n\t\t\tif key == itemKey {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// MapValueForKey gets the value of a map value for a specified key.\nfunc MapValueForKey(m *yaml.Node, key string) *yaml.Node {\n\tif m == nil {\n\t\treturn nil\n\t}\n\tif m.Kind == yaml.MappingNode {\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\titemKey := m.Content[i].Value\n\t\t\tif key == itemKey {\n\t\t\t\treturn m.Content[i+1]\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// ConvertInterfaceArrayToStringArray converts an array of interfaces to an array of strings, if possible.\nfunc ConvertInterfaceArrayToStringArray(interfaceArray []interface{}) []string {\n\tstringArray := make([]string, 0)\n\tfor _, item := range interfaceArray {\n\t\tv, ok := item.(string)\n\t\tif ok {\n\t\t\tstringArray = append(stringArray, v)\n\t\t}\n\t}\n\treturn stringArray\n}\n\n// SequenceNodeForNode returns a node if it is a SequenceNode.\nfunc SequenceNodeForNode(node *yaml.Node) (*yaml.Node, bool) {\n\tif node.Kind != yaml.SequenceNode {\n\t\treturn nil, false\n\t}\n\treturn node, true\n}\n\n// BoolForScalarNode returns the bool value of a node.\nfunc BoolForScalarNode(node *yaml.Node) (bool, bool) {\n\tif node == nil {\n\t\treturn false, false\n\t}\n\tif node.Kind == yaml.DocumentNode {\n\t\treturn BoolForScalarNode(node.Content[0])\n\t}\n\tif node.Kind != yaml.ScalarNode {\n\t\treturn false, false\n\t}\n\tif node.Tag != \"!!bool\" {\n\t\treturn false, false\n\t}\n\tv, err := strconv.ParseBool(node.Value)\n\tif err != nil {\n\t\treturn false, false\n\t}\n\treturn v, true\n}\n\n// IntForScalarNode returns the integer value of a node.\nfunc IntForScalarNode(node *yaml.Node) (int64, bool) {\n\tif node == nil {\n\t\treturn 0, false\n\t}\n\tif node.Kind == yaml.DocumentNode {\n\t\treturn IntForScalarNode(node.Content[0])\n\t}\n\tif node.Kind != yaml.ScalarNode {\n\t\treturn 0, false\n\t}\n\tif node.Tag != \"!!int\" {\n\t\treturn 0, false\n\t}\n\tv, err := strconv.ParseInt(node.Value, 10, 64)\n\tif err != nil {\n\t\treturn 0, false\n\t}\n\treturn v, true\n}\n\n// FloatForScalarNode returns the float value of a node.\nfunc FloatForScalarNode(node *yaml.Node) (float64, bool) {\n\tif node == nil {\n\t\treturn 0.0, false\n\t}\n\tif node.Kind == yaml.DocumentNode {\n\t\treturn FloatForScalarNode(node.Content[0])\n\t}\n\tif node.Kind != yaml.ScalarNode {\n\t\treturn 0.0, false\n\t}\n\tif (node.Tag != \"!!int\") && (node.Tag != \"!!float\") {\n\t\treturn 0.0, false\n\t}\n\tv, err := strconv.ParseFloat(node.Value, 64)\n\tif err != nil {\n\t\treturn 0.0, false\n\t}\n\treturn v, true\n}\n\n// StringForScalarNode returns the string value of a node.\nfunc StringForScalarNode(node *yaml.Node) (string, bool) {\n\tif node == nil {\n\t\treturn \"\", false\n\t}\n\tif node.Kind == yaml.DocumentNode {\n\t\treturn StringForScalarNode(node.Content[0])\n\t}\n\tswitch node.Kind {\n\tcase yaml.ScalarNode:\n\t\tswitch node.Tag {\n\t\tcase \"!!int\":\n\t\t\treturn node.Value, true\n\t\tcase \"!!str\":\n\t\t\treturn node.Value, true\n\t\tcase \"!!timestamp\":\n\t\t\treturn node.Value, true\n\t\tcase \"!!null\":\n\t\t\treturn \"\", true\n\t\tdefault:\n\t\t\treturn \"\", false\n\t\t}\n\tdefault:\n\t\treturn \"\", false\n\t}\n}\n\n// StringArrayForSequenceNode converts a sequence node to an array of strings, if possible.\nfunc StringArrayForSequenceNode(node *yaml.Node) []string {\n\tstringArray := make([]string, 0)\n\tfor _, item := range node.Content {\n\t\tv, ok := StringForScalarNode(item)\n\t\tif ok {\n\t\t\tstringArray = append(stringArray, v)\n\t\t}\n\t}\n\treturn stringArray\n}\n\n// MissingKeysInMap identifies which keys from a list of required keys are not in a map.\nfunc MissingKeysInMap(m *yaml.Node, requiredKeys []string) []string {\n\tmissingKeys := make([]string, 0)\n\tfor _, k := range requiredKeys {\n\t\tif !MapHasKey(m, k) {\n\t\t\tmissingKeys = append(missingKeys, k)\n\t\t}\n\t}\n\treturn missingKeys\n}\n\n// InvalidKeysInMap returns keys in a map that don't match a list of allowed keys and patterns.\nfunc InvalidKeysInMap(m *yaml.Node, allowedKeys []string, allowedPatterns []*regexp.Regexp) []string {\n\tinvalidKeys := make([]string, 0)\n\tif m == nil || m.Kind != yaml.MappingNode {\n\t\treturn invalidKeys\n\t}\n\tfor i := 0; i < len(m.Content); i += 2 {\n\t\tkey := m.Content[i].Value\n\t\tfound := false\n\t\t// does the key match an allowed key?\n\t\tfor _, allowedKey := range allowedKeys {\n\t\t\tif key == allowedKey {\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\t// does the key match an allowed pattern?\n\t\t\tfor _, allowedPattern := range allowedPatterns {\n\t\t\t\tif allowedPattern.MatchString(key) {\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\tinvalidKeys = append(invalidKeys, key)\n\t\t\t}\n\t\t}\n\t}\n\treturn invalidKeys\n}\n\n// NewNullNode creates a new Null node.\nfunc NewNullNode() *yaml.Node {\n\tnode := &yaml.Node{\n\t\tKind: yaml.ScalarNode,\n\t\tTag:  \"!!null\",\n\t}\n\treturn node\n}\n\n// NewMappingNode creates a new Mapping node.\nfunc NewMappingNode() *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:    yaml.MappingNode,\n\t\tContent: make([]*yaml.Node, 0),\n\t}\n}\n\n// NewSequenceNode creates a new Sequence node.\nfunc NewSequenceNode() *yaml.Node {\n\tnode := &yaml.Node{\n\t\tKind:    yaml.SequenceNode,\n\t\tContent: make([]*yaml.Node, 0),\n\t}\n\treturn node\n}\n\n// NewScalarNodeForString creates a new node to hold a string.\nfunc NewScalarNodeForString(s string) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!str\",\n\t\tValue: s,\n\t}\n}\n\n// NewSequenceNodeForStringArray creates a new node to hold an array of strings.\nfunc NewSequenceNodeForStringArray(strings []string) *yaml.Node {\n\tnode := &yaml.Node{\n\t\tKind:    yaml.SequenceNode,\n\t\tContent: make([]*yaml.Node, 0),\n\t}\n\tfor _, s := range strings {\n\t\tnode.Content = append(node.Content, NewScalarNodeForString(s))\n\t}\n\treturn node\n}\n\n// NewScalarNodeForBool creates a new node to hold a bool.\nfunc NewScalarNodeForBool(b bool) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!bool\",\n\t\tValue: fmt.Sprintf(\"%t\", b),\n\t}\n}\n\n// NewScalarNodeForFloat creates a new node to hold a float.\nfunc NewScalarNodeForFloat(f float64) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!float\",\n\t\tValue: fmt.Sprintf(\"%g\", f),\n\t}\n}\n\n// NewScalarNodeForInt creates a new node to hold an integer.\nfunc NewScalarNodeForInt(i int64) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!int\",\n\t\tValue: fmt.Sprintf(\"%d\", i),\n\t}\n}\n\n// PluralProperties returns the string \"properties\" pluralized.\nfunc PluralProperties(count int) string {\n\tif count == 1 {\n\t\treturn \"property\"\n\t}\n\treturn \"properties\"\n}\n\n// StringArrayContainsValue returns true if a string array contains a specified value.\nfunc StringArrayContainsValue(array []string, value string) bool {\n\tfor _, item := range array {\n\t\tif item == value {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// StringArrayContainsValues returns true if a string array contains all of a list of specified values.\nfunc StringArrayContainsValues(array []string, values []string) bool {\n\tfor _, value := range values {\n\t\tif !StringArrayContainsValue(array, value) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// StringValue returns the string value of an item.\nfunc StringValue(item interface{}) (value string, ok bool) {\n\tvalue, ok = item.(string)\n\tif ok {\n\t\treturn value, ok\n\t}\n\tintValue, ok := item.(int)\n\tif ok {\n\t\treturn strconv.Itoa(intValue), true\n\t}\n\treturn \"\", false\n}\n\n// Description returns a human-readable represention of an item.\nfunc Description(item interface{}) string {\n\tvalue, ok := item.(*yaml.Node)\n\tif ok {\n\t\treturn jsonschema.Render(value)\n\t}\n\treturn fmt.Sprintf(\"%+v\", item)\n}\n\n// Display returns a description of a node for use in error messages.\nfunc Display(node *yaml.Node) string {\n\tswitch node.Kind {\n\tcase yaml.ScalarNode:\n\t\tswitch node.Tag {\n\t\tcase \"!!str\":\n\t\t\treturn fmt.Sprintf(\"%s (string)\", node.Value)\n\t\t}\n\t}\n\treturn fmt.Sprintf(\"%+v (%T)\", node, node)\n}\n\n// Marshal creates a yaml version of a structure in our preferred style\nfunc Marshal(in *yaml.Node) []byte {\n\tclearStyle(in)\n\t//bytes, _ := yaml.Marshal(&yaml.Node{Kind: yaml.DocumentNode, Content: []*yaml.Node{in}})\n\tbytes, _ := yaml.Marshal(in)\n\n\treturn bytes\n}\n\nfunc clearStyle(node *yaml.Node) {\n\tnode.Style = 0\n\tfor _, c := range node.Content {\n\t\tclearStyle(c)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/compiler/main.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\n// Package compiler provides support functions to generated compiler code.\npackage compiler\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/compiler/reader.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage compiler\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\n\tyaml \"gopkg.in/yaml.v3\"\n)\n\nvar verboseReader = false\n\nvar fileCache map[string][]byte\nvar infoCache map[string]*yaml.Node\n\nvar fileCacheEnable = true\nvar infoCacheEnable = true\n\n// These locks are used to synchronize accesses to the fileCache and infoCache\n// maps (above). They are global state and can throw thread-related errors\n// when modified from separate goroutines. The general strategy is to protect\n// all public functions in this file with mutex Lock() calls. As a result, to\n// avoid deadlock, these public functions should not call other public\n// functions, so some public functions have private equivalents.\n// In the future, we might consider replacing the maps with sync.Map and\n// eliminating these mutexes.\nvar fileCacheMutex sync.Mutex\nvar infoCacheMutex sync.Mutex\n\nfunc initializeFileCache() {\n\tif fileCache == nil {\n\t\tfileCache = make(map[string][]byte, 0)\n\t}\n}\n\nfunc initializeInfoCache() {\n\tif infoCache == nil {\n\t\tinfoCache = make(map[string]*yaml.Node, 0)\n\t}\n}\n\n// EnableFileCache turns on file caching.\nfunc EnableFileCache() {\n\tfileCacheMutex.Lock()\n\tdefer fileCacheMutex.Unlock()\n\tfileCacheEnable = true\n}\n\n// EnableInfoCache turns on parsed info caching.\nfunc EnableInfoCache() {\n\tinfoCacheMutex.Lock()\n\tdefer infoCacheMutex.Unlock()\n\tinfoCacheEnable = true\n}\n\n// DisableFileCache turns off file caching.\nfunc DisableFileCache() {\n\tfileCacheMutex.Lock()\n\tdefer fileCacheMutex.Unlock()\n\tfileCacheEnable = false\n}\n\n// DisableInfoCache turns off parsed info caching.\nfunc DisableInfoCache() {\n\tinfoCacheMutex.Lock()\n\tdefer infoCacheMutex.Unlock()\n\tinfoCacheEnable = false\n}\n\n// RemoveFromFileCache removes an entry from the file cache.\nfunc RemoveFromFileCache(fileurl string) {\n\tfileCacheMutex.Lock()\n\tdefer fileCacheMutex.Unlock()\n\tif !fileCacheEnable {\n\t\treturn\n\t}\n\tinitializeFileCache()\n\tdelete(fileCache, fileurl)\n}\n\n// RemoveFromInfoCache removes an entry from the info cache.\nfunc RemoveFromInfoCache(filename string) {\n\tinfoCacheMutex.Lock()\n\tdefer infoCacheMutex.Unlock()\n\tif !infoCacheEnable {\n\t\treturn\n\t}\n\tinitializeInfoCache()\n\tdelete(infoCache, filename)\n}\n\n// GetInfoCache returns the info cache map.\nfunc GetInfoCache() map[string]*yaml.Node {\n\tinfoCacheMutex.Lock()\n\tdefer infoCacheMutex.Unlock()\n\tif infoCache == nil {\n\t\tinitializeInfoCache()\n\t}\n\treturn infoCache\n}\n\n// ClearFileCache clears the file cache.\nfunc ClearFileCache() {\n\tfileCacheMutex.Lock()\n\tdefer fileCacheMutex.Unlock()\n\tfileCache = make(map[string][]byte, 0)\n}\n\n// ClearInfoCache clears the info cache.\nfunc ClearInfoCache() {\n\tinfoCacheMutex.Lock()\n\tdefer infoCacheMutex.Unlock()\n\tinfoCache = make(map[string]*yaml.Node)\n}\n\n// ClearCaches clears all caches.\nfunc ClearCaches() {\n\tClearFileCache()\n\tClearInfoCache()\n}\n\n// FetchFile gets a specified file from the local filesystem or a remote location.\nfunc FetchFile(fileurl string) ([]byte, error) {\n\tfileCacheMutex.Lock()\n\tdefer fileCacheMutex.Unlock()\n\treturn fetchFile(fileurl)\n}\n\nfunc fetchFile(fileurl string) ([]byte, error) {\n\tvar bytes []byte\n\tinitializeFileCache()\n\tif fileCacheEnable {\n\t\tbytes, ok := fileCache[fileurl]\n\t\tif ok {\n\t\t\tif verboseReader {\n\t\t\t\tlog.Printf(\"Cache hit %s\", fileurl)\n\t\t\t}\n\t\t\treturn bytes, nil\n\t\t}\n\t\tif verboseReader {\n\t\t\tlog.Printf(\"Fetching %s\", fileurl)\n\t\t}\n\t}\n\tresponse, err := http.Get(fileurl)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer response.Body.Close()\n\tif response.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"Error downloading %s: %s\", fileurl, response.Status)\n\t}\n\tbytes, err = ioutil.ReadAll(response.Body)\n\tif fileCacheEnable && err == nil {\n\t\tfileCache[fileurl] = bytes\n\t}\n\treturn bytes, err\n}\n\n// ReadBytesForFile reads the bytes of a file.\nfunc ReadBytesForFile(filename string) ([]byte, error) {\n\tfileCacheMutex.Lock()\n\tdefer fileCacheMutex.Unlock()\n\treturn readBytesForFile(filename)\n}\n\nfunc readBytesForFile(filename string) ([]byte, error) {\n\t// is the filename a url?\n\tfileurl, _ := url.Parse(filename)\n\tif fileurl.Scheme != \"\" {\n\t\t// yes, fetch it\n\t\tbytes, err := fetchFile(filename)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn bytes, nil\n\t}\n\t// no, it's a local filename\n\tbytes, err := ioutil.ReadFile(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn bytes, nil\n}\n\n// ReadInfoFromBytes unmarshals a file as a *yaml.Node.\nfunc ReadInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) {\n\tinfoCacheMutex.Lock()\n\tdefer infoCacheMutex.Unlock()\n\treturn readInfoFromBytes(filename, bytes)\n}\n\nfunc readInfoFromBytes(filename string, bytes []byte) (*yaml.Node, error) {\n\tinitializeInfoCache()\n\tif infoCacheEnable {\n\t\tcachedInfo, ok := infoCache[filename]\n\t\tif ok {\n\t\t\tif verboseReader {\n\t\t\t\tlog.Printf(\"Cache hit info for file %s\", filename)\n\t\t\t}\n\t\t\treturn cachedInfo, nil\n\t\t}\n\t\tif verboseReader {\n\t\t\tlog.Printf(\"Reading info for file %s\", filename)\n\t\t}\n\t}\n\tvar info yaml.Node\n\terr := yaml.Unmarshal(bytes, &info)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif infoCacheEnable && len(filename) > 0 {\n\t\tinfoCache[filename] = &info\n\t}\n\treturn &info, nil\n}\n\n// ReadInfoForRef reads a file and return the fragment needed to resolve a $ref.\nfunc ReadInfoForRef(basefile string, ref string) (*yaml.Node, error) {\n\tfileCacheMutex.Lock()\n\tdefer fileCacheMutex.Unlock()\n\tinfoCacheMutex.Lock()\n\tdefer infoCacheMutex.Unlock()\n\tinitializeInfoCache()\n\tif infoCacheEnable {\n\t\tinfo, ok := infoCache[ref]\n\t\tif ok {\n\t\t\tif verboseReader {\n\t\t\t\tlog.Printf(\"Cache hit for ref %s#%s\", basefile, ref)\n\t\t\t}\n\t\t\treturn info, nil\n\t\t}\n\t\tif verboseReader {\n\t\t\tlog.Printf(\"Reading info for ref %s#%s\", basefile, ref)\n\t\t}\n\t}\n\tbasedir, _ := filepath.Split(basefile)\n\tparts := strings.Split(ref, \"#\")\n\tvar filename string\n\tif parts[0] != \"\" {\n\t\tfilename = parts[0]\n\t\tif _, err := url.ParseRequestURI(parts[0]); err != nil {\n\t\t\t// It is not an URL, so the file is local\n\t\t\tfilename = basedir + parts[0]\n\t\t}\n\t} else {\n\t\tfilename = basefile\n\t}\n\tbytes, err := readBytesForFile(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tinfo, err := readInfoFromBytes(filename, bytes)\n\tif info != nil && info.Kind == yaml.DocumentNode {\n\t\tinfo = info.Content[0]\n\t}\n\tif err != nil {\n\t\tlog.Printf(\"File error: %v\\n\", err)\n\t} else {\n\t\tif info == nil {\n\t\t\treturn nil, NewError(nil, fmt.Sprintf(\"could not resolve %s\", ref))\n\t\t}\n\t\tif len(parts) > 1 {\n\t\t\tpath := strings.Split(parts[1], \"/\")\n\t\t\tfor i, key := range path {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tm := info\n\t\t\t\t\tif true {\n\t\t\t\t\t\tfound := false\n\t\t\t\t\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\t\t\t\t\tif m.Content[i].Value == key {\n\t\t\t\t\t\t\t\tinfo = m.Content[i+1]\n\t\t\t\t\t\t\t\tfound = true\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif !found {\n\t\t\t\t\t\t\tinfoCache[ref] = nil\n\t\t\t\t\t\t\treturn nil, NewError(nil, fmt.Sprintf(\"could not resolve %s\", ref))\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\tif infoCacheEnable {\n\t\tinfoCache[ref] = info\n\t}\n\treturn info, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/extensions/README.md",
    "content": "# Extensions\n\n**Extension Support is experimental.**\n\nThis directory contains support code for building Gnostic extensio handlers and\nassociated examples.\n\nExtension handlers can be used to compile vendor or specification extensions\ninto protocol buffer structures.\n\nLike plugins, extension handlers are built as separate executables. Extension\nbodies are written to extension handlers as serialized\nExtensionHandlerRequests.\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/extensions/extension.pb.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.18.1\n// source: extensions/extension.proto\n\npackage gnostic_extension_v1\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\tanypb \"google.golang.org/protobuf/types/known/anypb\"\n\treflect \"reflect\"\n\tsync \"sync\"\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\n// The version number of Gnostic.\ntype Version struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tMajor int32 `protobuf:\"varint,1,opt,name=major,proto3\" json:\"major,omitempty\"`\n\tMinor int32 `protobuf:\"varint,2,opt,name=minor,proto3\" json:\"minor,omitempty\"`\n\tPatch int32 `protobuf:\"varint,3,opt,name=patch,proto3\" json:\"patch,omitempty\"`\n\t// A suffix for alpha, beta or rc release, e.g., \"alpha-1\", \"rc2\". It should\n\t// be empty for mainline stable releases.\n\tSuffix string `protobuf:\"bytes,4,opt,name=suffix,proto3\" json:\"suffix,omitempty\"`\n}\n\nfunc (x *Version) Reset() {\n\t*x = Version{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_extensions_extension_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Version) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Version) ProtoMessage() {}\n\nfunc (x *Version) ProtoReflect() protoreflect.Message {\n\tmi := &file_extensions_extension_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 Version.ProtoReflect.Descriptor instead.\nfunc (*Version) Descriptor() ([]byte, []int) {\n\treturn file_extensions_extension_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Version) GetMajor() int32 {\n\tif x != nil {\n\t\treturn x.Major\n\t}\n\treturn 0\n}\n\nfunc (x *Version) GetMinor() int32 {\n\tif x != nil {\n\t\treturn x.Minor\n\t}\n\treturn 0\n}\n\nfunc (x *Version) GetPatch() int32 {\n\tif x != nil {\n\t\treturn x.Patch\n\t}\n\treturn 0\n}\n\nfunc (x *Version) GetSuffix() string {\n\tif x != nil {\n\t\treturn x.Suffix\n\t}\n\treturn \"\"\n}\n\n// An encoded Request is written to the ExtensionHandler's stdin.\ntype ExtensionHandlerRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The extension to process.\n\tWrapper *Wrapper `protobuf:\"bytes,1,opt,name=wrapper,proto3\" json:\"wrapper,omitempty\"`\n\t// The version number of Gnostic.\n\tCompilerVersion *Version `protobuf:\"bytes,2,opt,name=compiler_version,json=compilerVersion,proto3\" json:\"compiler_version,omitempty\"`\n}\n\nfunc (x *ExtensionHandlerRequest) Reset() {\n\t*x = ExtensionHandlerRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_extensions_extension_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExtensionHandlerRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExtensionHandlerRequest) ProtoMessage() {}\n\nfunc (x *ExtensionHandlerRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_extensions_extension_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 ExtensionHandlerRequest.ProtoReflect.Descriptor instead.\nfunc (*ExtensionHandlerRequest) Descriptor() ([]byte, []int) {\n\treturn file_extensions_extension_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *ExtensionHandlerRequest) GetWrapper() *Wrapper {\n\tif x != nil {\n\t\treturn x.Wrapper\n\t}\n\treturn nil\n}\n\nfunc (x *ExtensionHandlerRequest) GetCompilerVersion() *Version {\n\tif x != nil {\n\t\treturn x.CompilerVersion\n\t}\n\treturn nil\n}\n\n// The extensions writes an encoded ExtensionHandlerResponse to stdout.\ntype ExtensionHandlerResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// true if the extension is handled by the extension handler; false otherwise\n\tHandled bool `protobuf:\"varint,1,opt,name=handled,proto3\" json:\"handled,omitempty\"`\n\t// Error message(s).  If non-empty, the extension handling failed.\n\t// The extension handler process should exit with status code zero\n\t// even if it reports an error in this way.\n\t//\n\t// This should be used to indicate errors which prevent the extension from\n\t// operating as intended.  Errors which indicate a problem in gnostic\n\t// itself -- such as the input Document being unparseable -- should be\n\t// reported by writing a message to stderr and exiting with a non-zero\n\t// status code.\n\tErrors []string `protobuf:\"bytes,2,rep,name=errors,proto3\" json:\"errors,omitempty\"`\n\t// text output\n\tValue *anypb.Any `protobuf:\"bytes,3,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *ExtensionHandlerResponse) Reset() {\n\t*x = ExtensionHandlerResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_extensions_extension_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExtensionHandlerResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExtensionHandlerResponse) ProtoMessage() {}\n\nfunc (x *ExtensionHandlerResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_extensions_extension_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 ExtensionHandlerResponse.ProtoReflect.Descriptor instead.\nfunc (*ExtensionHandlerResponse) Descriptor() ([]byte, []int) {\n\treturn file_extensions_extension_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ExtensionHandlerResponse) GetHandled() bool {\n\tif x != nil {\n\t\treturn x.Handled\n\t}\n\treturn false\n}\n\nfunc (x *ExtensionHandlerResponse) GetErrors() []string {\n\tif x != nil {\n\t\treturn x.Errors\n\t}\n\treturn nil\n}\n\nfunc (x *ExtensionHandlerResponse) GetValue() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\ntype Wrapper struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// version of the OpenAPI specification in which this extension was written.\n\tVersion string `protobuf:\"bytes,1,opt,name=version,proto3\" json:\"version,omitempty\"`\n\t// Name of the extension.\n\tExtensionName string `protobuf:\"bytes,2,opt,name=extension_name,json=extensionName,proto3\" json:\"extension_name,omitempty\"`\n\t// YAML-formatted extension value.\n\tYaml string `protobuf:\"bytes,3,opt,name=yaml,proto3\" json:\"yaml,omitempty\"`\n}\n\nfunc (x *Wrapper) Reset() {\n\t*x = Wrapper{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_extensions_extension_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Wrapper) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Wrapper) ProtoMessage() {}\n\nfunc (x *Wrapper) ProtoReflect() protoreflect.Message {\n\tmi := &file_extensions_extension_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 Wrapper.ProtoReflect.Descriptor instead.\nfunc (*Wrapper) Descriptor() ([]byte, []int) {\n\treturn file_extensions_extension_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *Wrapper) GetVersion() string {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn \"\"\n}\n\nfunc (x *Wrapper) GetExtensionName() string {\n\tif x != nil {\n\t\treturn x.ExtensionName\n\t}\n\treturn \"\"\n}\n\nfunc (x *Wrapper) GetYaml() string {\n\tif x != nil {\n\t\treturn x.Yaml\n\t}\n\treturn \"\"\n}\n\nvar File_extensions_extension_proto protoreflect.FileDescriptor\n\nvar file_extensions_extension_proto_rawDesc = []byte{\n\t0x0a, 0x1a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x65, 0x78, 0x74,\n\t0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x14, 0x67, 0x6e,\n\t0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e,\n\t0x76, 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x63, 0x0a,\n\t0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f,\n\t0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14,\n\t0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d,\n\t0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20,\n\t0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75,\n\t0x66, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66,\n\t0x69, 0x78, 0x22, 0x9c, 0x01, 0x0a, 0x17, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x37,\n\t0x0a, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x1d, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,\n\t0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x52, 0x07,\n\t0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x48, 0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x69,\n\t0x6c, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,\n\t0x52, 0x0f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,\n\t0x6e, 0x22, 0x78, 0x0a, 0x18, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x48, 0x61,\n\t0x6e, 0x64, 0x6c, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a,\n\t0x07, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07,\n\t0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72,\n\t0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x12,\n\t0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14,\n\t0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,\n\t0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5e, 0x0a, 0x07, 0x57,\n\t0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,\n\t0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,\n\t0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61,\n\t0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,\n\t0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18,\n\t0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x42, 0x4d, 0x0a, 0x0e, 0x6f,\n\t0x72, 0x67, 0x2e, 0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x76, 0x31, 0x42, 0x10, 0x47,\n\t0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x50,\n\t0x01, 0x5a, 0x21, 0x2e, 0x2f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x3b,\n\t0x67, 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x5f, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x47, 0x4e, 0x58, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x33,\n}\n\nvar (\n\tfile_extensions_extension_proto_rawDescOnce sync.Once\n\tfile_extensions_extension_proto_rawDescData = file_extensions_extension_proto_rawDesc\n)\n\nfunc file_extensions_extension_proto_rawDescGZIP() []byte {\n\tfile_extensions_extension_proto_rawDescOnce.Do(func() {\n\t\tfile_extensions_extension_proto_rawDescData = protoimpl.X.CompressGZIP(file_extensions_extension_proto_rawDescData)\n\t})\n\treturn file_extensions_extension_proto_rawDescData\n}\n\nvar file_extensions_extension_proto_msgTypes = make([]protoimpl.MessageInfo, 4)\nvar file_extensions_extension_proto_goTypes = []interface{}{\n\t(*Version)(nil),                  // 0: gnostic.extension.v1.Version\n\t(*ExtensionHandlerRequest)(nil),  // 1: gnostic.extension.v1.ExtensionHandlerRequest\n\t(*ExtensionHandlerResponse)(nil), // 2: gnostic.extension.v1.ExtensionHandlerResponse\n\t(*Wrapper)(nil),                  // 3: gnostic.extension.v1.Wrapper\n\t(*anypb.Any)(nil),                // 4: google.protobuf.Any\n}\nvar file_extensions_extension_proto_depIdxs = []int32{\n\t3, // 0: gnostic.extension.v1.ExtensionHandlerRequest.wrapper:type_name -> gnostic.extension.v1.Wrapper\n\t0, // 1: gnostic.extension.v1.ExtensionHandlerRequest.compiler_version:type_name -> gnostic.extension.v1.Version\n\t4, // 2: gnostic.extension.v1.ExtensionHandlerResponse.value:type_name -> google.protobuf.Any\n\t3, // [3:3] is the sub-list for method output_type\n\t3, // [3:3] is the sub-list for method input_type\n\t3, // [3:3] is the sub-list for extension type_name\n\t3, // [3:3] is the sub-list for extension extendee\n\t0, // [0:3] is the sub-list for field type_name\n}\n\nfunc init() { file_extensions_extension_proto_init() }\nfunc file_extensions_extension_proto_init() {\n\tif File_extensions_extension_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_extensions_extension_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Version); 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_extensions_extension_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExtensionHandlerRequest); 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_extensions_extension_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExtensionHandlerResponse); 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_extensions_extension_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Wrapper); 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_extensions_extension_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   4,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_extensions_extension_proto_goTypes,\n\t\tDependencyIndexes: file_extensions_extension_proto_depIdxs,\n\t\tMessageInfos:      file_extensions_extension_proto_msgTypes,\n\t}.Build()\n\tFile_extensions_extension_proto = out.File\n\tfile_extensions_extension_proto_rawDesc = nil\n\tfile_extensions_extension_proto_goTypes = nil\n\tfile_extensions_extension_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/extensions/extension.proto",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\nsyntax = \"proto3\";\n\npackage gnostic.extension.v1;\n\nimport \"google/protobuf/any.proto\";\n\n// This option lets the proto compiler generate Java code inside the package\n// name (see below) instead of inside an outer class. It creates a simpler\n// developer experience by reducing one-level of name nesting and be\n// consistent with most programming languages that don't support outer classes.\noption java_multiple_files = true;\n\n// The Java outer classname should be the filename in UpperCamelCase. This\n// class is only used to hold proto descriptor, so developers don't need to\n// work with it directly.\noption java_outer_classname = \"GnosticExtension\";\n\n// The Java package name must be proto package name with proper prefix.\noption java_package = \"org.gnostic.v1\";\n\n// A reasonable prefix for the Objective-C symbols generated from the package.\n// It should at a minimum be 3 characters long, all uppercase, and convention\n// is to use an abbreviation of the package name. Something short, but\n// hopefully unique enough to not conflict with things that may come along in\n// the future. 'GPB' is reserved for the protocol buffer implementation itself.\n//\n// \"Gnostic Extension\"\noption objc_class_prefix = \"GNX\";\n\n// The Go package name.\noption go_package = \"./extensions;gnostic_extension_v1\";\n\n// The version number of Gnostic.\nmessage Version {\n  int32 major = 1;\n  int32 minor = 2;\n  int32 patch = 3;\n  // A suffix for alpha, beta or rc release, e.g., \"alpha-1\", \"rc2\". It should\n  // be empty for mainline stable releases.\n  string suffix = 4;\n}\n\n// An encoded Request is written to the ExtensionHandler's stdin.\nmessage ExtensionHandlerRequest {\n\n  // The extension to process.\n  Wrapper wrapper = 1;\n\n  // The version number of Gnostic.\n  Version compiler_version = 2;\n}\n\n// The extensions writes an encoded ExtensionHandlerResponse to stdout.\nmessage ExtensionHandlerResponse {\n\n  // true if the extension is handled by the extension handler; false otherwise\n  bool handled = 1;\n\n  // Error message(s).  If non-empty, the extension handling failed.\n  // The extension handler process should exit with status code zero\n  // even if it reports an error in this way.\n  //\n  // This should be used to indicate errors which prevent the extension from\n  // operating as intended.  Errors which indicate a problem in gnostic\n  // itself -- such as the input Document being unparseable -- should be\n  // reported by writing a message to stderr and exiting with a non-zero\n  // status code.\n  repeated string errors = 2;\n\n  // text output\n  google.protobuf.Any value = 3;\n}\n\nmessage Wrapper {\n  // version of the OpenAPI specification in which this extension was written.\n  string version = 1;\n\n  // Name of the extension.\n  string extension_name = 2;\n\n  // YAML-formatted extension value.\n  string yaml = 3;\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/extensions/extensions.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage gnostic_extension_v1\n\nimport (\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/golang/protobuf/proto\"\n\t\"github.com/golang/protobuf/ptypes\"\n)\n\ntype extensionHandler func(name string, yamlInput string) (bool, proto.Message, error)\n\n// Main implements the main program of an extension handler.\nfunc Main(handler extensionHandler) {\n\t// unpack the request\n\tdata, err := ioutil.ReadAll(os.Stdin)\n\tif err != nil {\n\t\tlog.Println(\"File error:\", err.Error())\n\t\tos.Exit(1)\n\t}\n\tif len(data) == 0 {\n\t\tlog.Println(\"No input data.\")\n\t\tos.Exit(1)\n\t}\n\trequest := &ExtensionHandlerRequest{}\n\terr = proto.Unmarshal(data, request)\n\tif err != nil {\n\t\tlog.Println(\"Input error:\", err.Error())\n\t\tos.Exit(1)\n\t}\n\t// call the handler\n\thandled, output, err := handler(request.Wrapper.ExtensionName, request.Wrapper.Yaml)\n\t// respond with the output of the handler\n\tresponse := &ExtensionHandlerResponse{\n\t\tHandled: false, // default assumption\n\t\tErrors:  make([]string, 0),\n\t}\n\tif err != nil {\n\t\tresponse.Errors = append(response.Errors, err.Error())\n\t} else if handled {\n\t\tresponse.Handled = true\n\t\tresponse.Value, err = ptypes.MarshalAny(output)\n\t\tif err != nil {\n\t\t\tresponse.Errors = append(response.Errors, err.Error())\n\t\t}\n\t}\n\tresponseBytes, _ := proto.Marshal(response)\n\tos.Stdout.Write(responseBytes)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/README.md",
    "content": "# jsonschema\n\nThis directory contains code for reading, writing, and manipulating JSON\nschemas.\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/base.go",
    "content": "\n// THIS FILE IS AUTOMATICALLY GENERATED.\n\npackage jsonschema\n\nimport (\n\t\"encoding/base64\"\n)\n\nfunc baseSchemaBytes() ([]byte, error){\n\treturn base64.StdEncoding.DecodeString(\n`ewogICAgImlkIjogImh0dHA6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQtMDQvc2NoZW1hIyIsCiAgICAi\nJHNjaGVtYSI6ICJodHRwOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LTA0L3NjaGVtYSMiLAogICAgImRl\nc2NyaXB0aW9uIjogIkNvcmUgc2NoZW1hIG1ldGEtc2NoZW1hIiwKICAgICJkZWZpbml0aW9ucyI6IHsK\nICAgICAgICAic2NoZW1hQXJyYXkiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImFycmF5IiwKICAgICAg\nICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjIiB9CiAg\nICAgICAgfSwKICAgICAgICAicG9zaXRpdmVJbnRlZ2VyIjogewogICAgICAgICAgICAidHlwZSI6ICJp\nbnRlZ2VyIiwKICAgICAgICAgICAgIm1pbmltdW0iOiAwCiAgICAgICAgfSwKICAgICAgICAicG9zaXRp\ndmVJbnRlZ2VyRGVmYXVsdDAiOiB7CiAgICAgICAgICAgICJhbGxPZiI6IFsgeyAiJHJlZiI6ICIjL2Rl\nZmluaXRpb25zL3Bvc2l0aXZlSW50ZWdlciIgfSwgeyAiZGVmYXVsdCI6IDAgfSBdCiAgICAgICAgfSwK\nICAgICAgICAic2ltcGxlVHlwZXMiOiB7CiAgICAgICAgICAgICJlbnVtIjogWyAiYXJyYXkiLCAiYm9v\nbGVhbiIsICJpbnRlZ2VyIiwgIm51bGwiLCAibnVtYmVyIiwgIm9iamVjdCIsICJzdHJpbmciIF0KICAg\nICAgICB9LAogICAgICAgICJzdHJpbmdBcnJheSI6IHsKICAgICAgICAgICAgInR5cGUiOiAiYXJyYXki\nLAogICAgICAgICAgICAiaXRlbXMiOiB7ICJ0eXBlIjogInN0cmluZyIgfSwKICAgICAgICAgICAgIm1p\nbkl0ZW1zIjogMSwKICAgICAgICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0KICAgIH0s\nCiAgICAidHlwZSI6ICJvYmplY3QiLAogICAgInByb3BlcnRpZXMiOiB7CiAgICAgICAgImlkIjogewog\nICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAogICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAg\nICAgICB9LAogICAgICAgICIkc2NoZW1hIjogewogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciLAog\nICAgICAgICAgICAiZm9ybWF0IjogInVyaSIKICAgICAgICB9LAogICAgICAgICJ0aXRsZSI6IHsKICAg\nICAgICAgICAgInR5cGUiOiAic3RyaW5nIgogICAgICAgIH0sCiAgICAgICAgImRlc2NyaXB0aW9uIjog\newogICAgICAgICAgICAidHlwZSI6ICJzdHJpbmciCiAgICAgICAgfSwKICAgICAgICAiZGVmYXVsdCI6\nIHt9LAogICAgICAgICJtdWx0aXBsZU9mIjogewogICAgICAgICAgICAidHlwZSI6ICJudW1iZXIiLAog\nICAgICAgICAgICAibWluaW11bSI6IDAsCiAgICAgICAgICAgICJleGNsdXNpdmVNaW5pbXVtIjogdHJ1\nZQogICAgICAgIH0sCiAgICAgICAgIm1heGltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJl\nciIKICAgICAgICB9LAogICAgICAgICJleGNsdXNpdmVNYXhpbXVtIjogewogICAgICAgICAgICAidHlw\nZSI6ICJib29sZWFuIiwKICAgICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAg\nICAgIm1pbmltdW0iOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm51bWJlciIKICAgICAgICB9LAogICAg\nICAgICJleGNsdXNpdmVNaW5pbXVtIjogewogICAgICAgICAgICAidHlwZSI6ICJib29sZWFuIiwKICAg\nICAgICAgICAgImRlZmF1bHQiOiBmYWxzZQogICAgICAgIH0sCiAgICAgICAgIm1heExlbmd0aCI6IHsg\nIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pbkxlbmd0\naCI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAg\nICAgICAicGF0dGVybiI6IHsKICAgICAgICAgICAgInR5cGUiOiAic3RyaW5nIiwKICAgICAgICAgICAg\nImZvcm1hdCI6ICJyZWdleCIKICAgICAgICB9LAogICAgICAgICJhZGRpdGlvbmFsSXRlbXMiOiB7CiAg\nICAgICAgICAgICJhbnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgInR5cGUiOiAiYm9vbGVhbiIgfSwK\nICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfQogICAgICAgICAgICBdLAogICAgICAgICAgICAi\nZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAiaXRlbXMiOiB7CiAgICAgICAgICAgICJhbnlP\nZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgICAgIHsgIiRy\nZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIgfQogICAgICAgICAgICBdLAogICAgICAgICAg\nICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAibWF4SXRlbXMiOiB7ICIkcmVmIjogIiMv\nZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyIiB9LAogICAgICAgICJtaW5JdGVtcyI6IHsgIiRyZWYi\nOiAiIy9kZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXJEZWZhdWx0MCIgfSwKICAgICAgICAidW5pcXVl\nSXRlbXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogImJvb2xlYW4iLAogICAgICAgICAgICAiZGVmYXVs\ndCI6IGZhbHNlCiAgICAgICAgfSwKICAgICAgICAibWF4UHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIy9k\nZWZpbml0aW9ucy9wb3NpdGl2ZUludGVnZXIiIH0sCiAgICAgICAgIm1pblByb3BlcnRpZXMiOiB7ICIk\ncmVmIjogIiMvZGVmaW5pdGlvbnMvcG9zaXRpdmVJbnRlZ2VyRGVmYXVsdDAiIH0sCiAgICAgICAgInJl\ncXVpcmVkIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3N0cmluZ0FycmF5IiB9LAogICAgICAgICJh\nZGRpdGlvbmFsUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgImFueU9mIjogWwogICAgICAgICAgICAg\nICAgeyAidHlwZSI6ICJib29sZWFuIiB9LAogICAgICAgICAgICAgICAgeyAiJHJlZiI6ICIjIiB9CiAg\nICAgICAgICAgIF0sCiAgICAgICAgICAgICJkZWZhdWx0Ijoge30KICAgICAgICB9LAogICAgICAgICJk\nZWZpbml0aW9ucyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2JqZWN0IiwKICAgICAgICAgICAgImFk\nZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9LAogICAgICAgICAgICAiZGVmYXVsdCI6\nIHt9CiAgICAgICAgfSwKICAgICAgICAicHJvcGVydGllcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAi\nb2JqZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogeyAiJHJlZiI6ICIjIiB9\nLAogICAgICAgICAgICAiZGVmYXVsdCI6IHt9CiAgICAgICAgfSwKICAgICAgICAicGF0dGVyblByb3Bl\ncnRpZXMiOiB7CiAgICAgICAgICAgICJ0eXBlIjogIm9iamVjdCIsCiAgICAgICAgICAgICJhZGRpdGlv\nbmFsUHJvcGVydGllcyI6IHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAgImRlZmF1bHQiOiB7fQog\nICAgICAgIH0sCiAgICAgICAgImRlcGVuZGVuY2llcyI6IHsKICAgICAgICAgICAgInR5cGUiOiAib2Jq\nZWN0IiwKICAgICAgICAgICAgImFkZGl0aW9uYWxQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAg\nImFueU9mIjogWwogICAgICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIyIgfSwKICAgICAgICAgICAg\nICAgICAgICB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc3RyaW5nQXJyYXkiIH0KICAgICAgICAgICAg\nICAgIF0KICAgICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgImVudW0iOiB7CiAgICAgICAgICAg\nICJ0eXBlIjogImFycmF5IiwKICAgICAgICAgICAgIm1pbkl0ZW1zIjogMSwKICAgICAgICAgICAgInVu\naXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgIH0sCiAgICAgICAgInR5cGUiOiB7CiAgICAgICAgICAgICJh\nbnlPZiI6IFsKICAgICAgICAgICAgICAgIHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zaW1wbGVUeXBl\ncyIgfSwKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAidHlwZSI6ICJhcnJheSIs\nCiAgICAgICAgICAgICAgICAgICAgIml0ZW1zIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NpbXBs\nZVR5cGVzIiB9LAogICAgICAgICAgICAgICAgICAgICJtaW5JdGVtcyI6IDEsCiAgICAgICAgICAgICAg\nICAgICAgInVuaXF1ZUl0ZW1zIjogdHJ1ZQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBdCiAg\nICAgICAgfSwKICAgICAgICAiYWxsT2YiOiB7ICIkcmVmIjogIiMvZGVmaW5pdGlvbnMvc2NoZW1hQXJy\nYXkiIH0sCiAgICAgICAgImFueU9mIjogeyAiJHJlZiI6ICIjL2RlZmluaXRpb25zL3NjaGVtYUFycmF5\nIiB9LAogICAgICAgICJvbmVPZiI6IHsgIiRyZWYiOiAiIy9kZWZpbml0aW9ucy9zY2hlbWFBcnJheSIg\nfSwKICAgICAgICAibm90IjogeyAiJHJlZiI6ICIjIiB9CiAgICB9LAogICAgImRlcGVuZGVuY2llcyI6\nIHsKICAgICAgICAiZXhjbHVzaXZlTWF4aW11bSI6IFsgIm1heGltdW0iIF0sCiAgICAgICAgImV4Y2x1\nc2l2ZU1pbmltdW0iOiBbICJtaW5pbXVtIiBdCiAgICB9LAogICAgImRlZmF1bHQiOiB7fQp9Cg==`)}"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/display.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage jsonschema\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n//\n// DISPLAY\n// The following methods display Schemas.\n//\n\n// Description returns a string representation of a string or string array.\nfunc (s *StringOrStringArray) Description() string {\n\tif s.String != nil {\n\t\treturn *s.String\n\t}\n\tif s.StringArray != nil {\n\t\treturn strings.Join(*s.StringArray, \", \")\n\t}\n\treturn \"\"\n}\n\n// Returns a string representation of a Schema.\nfunc (schema *Schema) String() string {\n\treturn schema.describeSchema(\"\")\n}\n\n// Helper: Returns a string representation of a Schema indented by a specified string.\nfunc (schema *Schema) describeSchema(indent string) string {\n\tresult := \"\"\n\tif schema.Schema != nil {\n\t\tresult += indent + \"$schema: \" + *(schema.Schema) + \"\\n\"\n\t}\n\tif schema.ID != nil {\n\t\tresult += indent + \"id: \" + *(schema.ID) + \"\\n\"\n\t}\n\tif schema.MultipleOf != nil {\n\t\tresult += indent + fmt.Sprintf(\"multipleOf: %+v\\n\", *(schema.MultipleOf))\n\t}\n\tif schema.Maximum != nil {\n\t\tresult += indent + fmt.Sprintf(\"maximum: %+v\\n\", *(schema.Maximum))\n\t}\n\tif schema.ExclusiveMaximum != nil {\n\t\tresult += indent + fmt.Sprintf(\"exclusiveMaximum: %+v\\n\", *(schema.ExclusiveMaximum))\n\t}\n\tif schema.Minimum != nil {\n\t\tresult += indent + fmt.Sprintf(\"minimum: %+v\\n\", *(schema.Minimum))\n\t}\n\tif schema.ExclusiveMinimum != nil {\n\t\tresult += indent + fmt.Sprintf(\"exclusiveMinimum: %+v\\n\", *(schema.ExclusiveMinimum))\n\t}\n\tif schema.MaxLength != nil {\n\t\tresult += indent + fmt.Sprintf(\"maxLength: %+v\\n\", *(schema.MaxLength))\n\t}\n\tif schema.MinLength != nil {\n\t\tresult += indent + fmt.Sprintf(\"minLength: %+v\\n\", *(schema.MinLength))\n\t}\n\tif schema.Pattern != nil {\n\t\tresult += indent + fmt.Sprintf(\"pattern: %+v\\n\", *(schema.Pattern))\n\t}\n\tif schema.AdditionalItems != nil {\n\t\ts := schema.AdditionalItems.Schema\n\t\tif s != nil {\n\t\t\tresult += indent + \"additionalItems:\\n\"\n\t\t\tresult += s.describeSchema(indent + \"  \")\n\t\t} else {\n\t\t\tb := *(schema.AdditionalItems.Boolean)\n\t\t\tresult += indent + fmt.Sprintf(\"additionalItems: %+v\\n\", b)\n\t\t}\n\t}\n\tif schema.Items != nil {\n\t\tresult += indent + \"items:\\n\"\n\t\titems := schema.Items\n\t\tif items.SchemaArray != nil {\n\t\t\tfor i, s := range *(items.SchemaArray) {\n\t\t\t\tresult += indent + \"  \" + fmt.Sprintf(\"%d\", i) + \":\\n\"\n\t\t\t\tresult += s.describeSchema(indent + \"  \" + \"  \")\n\t\t\t}\n\t\t} else if items.Schema != nil {\n\t\t\tresult += items.Schema.describeSchema(indent + \"  \" + \"  \")\n\t\t}\n\t}\n\tif schema.MaxItems != nil {\n\t\tresult += indent + fmt.Sprintf(\"maxItems: %+v\\n\", *(schema.MaxItems))\n\t}\n\tif schema.MinItems != nil {\n\t\tresult += indent + fmt.Sprintf(\"minItems: %+v\\n\", *(schema.MinItems))\n\t}\n\tif schema.UniqueItems != nil {\n\t\tresult += indent + fmt.Sprintf(\"uniqueItems: %+v\\n\", *(schema.UniqueItems))\n\t}\n\tif schema.MaxProperties != nil {\n\t\tresult += indent + fmt.Sprintf(\"maxProperties: %+v\\n\", *(schema.MaxProperties))\n\t}\n\tif schema.MinProperties != nil {\n\t\tresult += indent + fmt.Sprintf(\"minProperties: %+v\\n\", *(schema.MinProperties))\n\t}\n\tif schema.Required != nil {\n\t\tresult += indent + fmt.Sprintf(\"required: %+v\\n\", *(schema.Required))\n\t}\n\tif schema.AdditionalProperties != nil {\n\t\ts := schema.AdditionalProperties.Schema\n\t\tif s != nil {\n\t\t\tresult += indent + \"additionalProperties:\\n\"\n\t\t\tresult += s.describeSchema(indent + \"  \")\n\t\t} else {\n\t\t\tb := *(schema.AdditionalProperties.Boolean)\n\t\t\tresult += indent + fmt.Sprintf(\"additionalProperties: %+v\\n\", b)\n\t\t}\n\t}\n\tif schema.Properties != nil {\n\t\tresult += indent + \"properties:\\n\"\n\t\tfor _, pair := range *(schema.Properties) {\n\t\t\tname := pair.Name\n\t\t\ts := pair.Value\n\t\t\tresult += indent + \"  \" + name + \":\\n\"\n\t\t\tresult += s.describeSchema(indent + \"  \" + \"  \")\n\t\t}\n\t}\n\tif schema.PatternProperties != nil {\n\t\tresult += indent + \"patternProperties:\\n\"\n\t\tfor _, pair := range *(schema.PatternProperties) {\n\t\t\tname := pair.Name\n\t\t\ts := pair.Value\n\t\t\tresult += indent + \"  \" + name + \":\\n\"\n\t\t\tresult += s.describeSchema(indent + \"  \" + \"  \")\n\t\t}\n\t}\n\tif schema.Dependencies != nil {\n\t\tresult += indent + \"dependencies:\\n\"\n\t\tfor _, pair := range *(schema.Dependencies) {\n\t\t\tname := pair.Name\n\t\t\tschemaOrStringArray := pair.Value\n\t\t\ts := schemaOrStringArray.Schema\n\t\t\tif s != nil {\n\t\t\t\tresult += indent + \"  \" + name + \":\\n\"\n\t\t\t\tresult += s.describeSchema(indent + \"  \" + \"  \")\n\t\t\t} else {\n\t\t\t\ta := schemaOrStringArray.StringArray\n\t\t\t\tif a != nil {\n\t\t\t\t\tresult += indent + \"  \" + name + \":\\n\"\n\t\t\t\t\tfor _, s2 := range *a {\n\t\t\t\t\t\tresult += indent + \"  \" + \"  \" + s2 + \"\\n\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\tif schema.Enumeration != nil {\n\t\tresult += indent + \"enumeration:\\n\"\n\t\tfor _, value := range *(schema.Enumeration) {\n\t\t\tif value.String != nil {\n\t\t\t\tresult += indent + \"  \" + fmt.Sprintf(\"%+v\\n\", *value.String)\n\t\t\t} else {\n\t\t\t\tresult += indent + \"  \" + fmt.Sprintf(\"%+v\\n\", *value.Bool)\n\t\t\t}\n\t\t}\n\t}\n\tif schema.Type != nil {\n\t\tresult += indent + fmt.Sprintf(\"type: %+v\\n\", schema.Type.Description())\n\t}\n\tif schema.AllOf != nil {\n\t\tresult += indent + \"allOf:\\n\"\n\t\tfor _, s := range *(schema.AllOf) {\n\t\t\tresult += s.describeSchema(indent + \"  \")\n\t\t\tresult += indent + \"-\\n\"\n\t\t}\n\t}\n\tif schema.AnyOf != nil {\n\t\tresult += indent + \"anyOf:\\n\"\n\t\tfor _, s := range *(schema.AnyOf) {\n\t\t\tresult += s.describeSchema(indent + \"  \")\n\t\t\tresult += indent + \"-\\n\"\n\t\t}\n\t}\n\tif schema.OneOf != nil {\n\t\tresult += indent + \"oneOf:\\n\"\n\t\tfor _, s := range *(schema.OneOf) {\n\t\t\tresult += s.describeSchema(indent + \"  \")\n\t\t\tresult += indent + \"-\\n\"\n\t\t}\n\t}\n\tif schema.Not != nil {\n\t\tresult += indent + \"not:\\n\"\n\t\tresult += schema.Not.describeSchema(indent + \"  \")\n\t}\n\tif schema.Definitions != nil {\n\t\tresult += indent + \"definitions:\\n\"\n\t\tfor _, pair := range *(schema.Definitions) {\n\t\t\tname := pair.Name\n\t\t\ts := pair.Value\n\t\t\tresult += indent + \"  \" + name + \":\\n\"\n\t\t\tresult += s.describeSchema(indent + \"  \" + \"  \")\n\t\t}\n\t}\n\tif schema.Title != nil {\n\t\tresult += indent + \"title: \" + *(schema.Title) + \"\\n\"\n\t}\n\tif schema.Description != nil {\n\t\tresult += indent + \"description: \" + *(schema.Description) + \"\\n\"\n\t}\n\tif schema.Default != nil {\n\t\tresult += indent + \"default:\\n\"\n\t\tresult += indent + fmt.Sprintf(\"  %+v\\n\", *(schema.Default))\n\t}\n\tif schema.Format != nil {\n\t\tresult += indent + \"format: \" + *(schema.Format) + \"\\n\"\n\t}\n\tif schema.Ref != nil {\n\t\tresult += indent + \"$ref: \" + *(schema.Ref) + \"\\n\"\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/models.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\n// Package jsonschema supports the reading, writing, and manipulation\n// of JSON Schemas.\npackage jsonschema\n\nimport \"gopkg.in/yaml.v3\"\n\n// The Schema struct models a JSON Schema and, because schemas are\n// defined hierarchically, contains many references to itself.\n// All fields are pointers and are nil if the associated values\n// are not specified.\ntype Schema struct {\n\tSchema *string // $schema\n\tID     *string // id keyword used for $ref resolution scope\n\tRef    *string // $ref, i.e. JSON Pointers\n\n\t// http://json-schema.org/latest/json-schema-validation.html\n\t// 5.1.  Validation keywords for numeric instances (number and integer)\n\tMultipleOf       *SchemaNumber\n\tMaximum          *SchemaNumber\n\tExclusiveMaximum *bool\n\tMinimum          *SchemaNumber\n\tExclusiveMinimum *bool\n\n\t// 5.2.  Validation keywords for strings\n\tMaxLength *int64\n\tMinLength *int64\n\tPattern   *string\n\n\t// 5.3.  Validation keywords for arrays\n\tAdditionalItems *SchemaOrBoolean\n\tItems           *SchemaOrSchemaArray\n\tMaxItems        *int64\n\tMinItems        *int64\n\tUniqueItems     *bool\n\n\t// 5.4.  Validation keywords for objects\n\tMaxProperties        *int64\n\tMinProperties        *int64\n\tRequired             *[]string\n\tAdditionalProperties *SchemaOrBoolean\n\tProperties           *[]*NamedSchema\n\tPatternProperties    *[]*NamedSchema\n\tDependencies         *[]*NamedSchemaOrStringArray\n\n\t// 5.5.  Validation keywords for any instance type\n\tEnumeration *[]SchemaEnumValue\n\tType        *StringOrStringArray\n\tAllOf       *[]*Schema\n\tAnyOf       *[]*Schema\n\tOneOf       *[]*Schema\n\tNot         *Schema\n\tDefinitions *[]*NamedSchema\n\n\t// 6.  Metadata keywords\n\tTitle       *string\n\tDescription *string\n\tDefault     *yaml.Node\n\n\t// 7.  Semantic validation with \"format\"\n\tFormat *string\n}\n\n// These helper structs represent \"combination\" types that generally can\n// have values of one type or another. All are used to represent parts\n// of Schemas.\n\n// SchemaNumber represents a value that can be either an Integer or a Float.\ntype SchemaNumber struct {\n\tInteger *int64\n\tFloat   *float64\n}\n\n// NewSchemaNumberWithInteger creates and returns a new object\nfunc NewSchemaNumberWithInteger(i int64) *SchemaNumber {\n\tresult := &SchemaNumber{}\n\tresult.Integer = &i\n\treturn result\n}\n\n// NewSchemaNumberWithFloat creates and returns a new object\nfunc NewSchemaNumberWithFloat(f float64) *SchemaNumber {\n\tresult := &SchemaNumber{}\n\tresult.Float = &f\n\treturn result\n}\n\n// SchemaOrBoolean represents a value that can be either a Schema or a Boolean.\ntype SchemaOrBoolean struct {\n\tSchema  *Schema\n\tBoolean *bool\n}\n\n// NewSchemaOrBooleanWithSchema creates and returns a new object\nfunc NewSchemaOrBooleanWithSchema(s *Schema) *SchemaOrBoolean {\n\tresult := &SchemaOrBoolean{}\n\tresult.Schema = s\n\treturn result\n}\n\n// NewSchemaOrBooleanWithBoolean creates and returns a new object\nfunc NewSchemaOrBooleanWithBoolean(b bool) *SchemaOrBoolean {\n\tresult := &SchemaOrBoolean{}\n\tresult.Boolean = &b\n\treturn result\n}\n\n// StringOrStringArray represents a value that can be either\n// a String or an Array of Strings.\ntype StringOrStringArray struct {\n\tString      *string\n\tStringArray *[]string\n}\n\n// NewStringOrStringArrayWithString creates and returns a new object\nfunc NewStringOrStringArrayWithString(s string) *StringOrStringArray {\n\tresult := &StringOrStringArray{}\n\tresult.String = &s\n\treturn result\n}\n\n// NewStringOrStringArrayWithStringArray creates and returns a new object\nfunc NewStringOrStringArrayWithStringArray(a []string) *StringOrStringArray {\n\tresult := &StringOrStringArray{}\n\tresult.StringArray = &a\n\treturn result\n}\n\n// SchemaOrStringArray represents a value that can be either\n// a Schema or an Array of Strings.\ntype SchemaOrStringArray struct {\n\tSchema      *Schema\n\tStringArray *[]string\n}\n\n// SchemaOrSchemaArray represents a value that can be either\n// a Schema or an Array of Schemas.\ntype SchemaOrSchemaArray struct {\n\tSchema      *Schema\n\tSchemaArray *[]*Schema\n}\n\n// NewSchemaOrSchemaArrayWithSchema creates and returns a new object\nfunc NewSchemaOrSchemaArrayWithSchema(s *Schema) *SchemaOrSchemaArray {\n\tresult := &SchemaOrSchemaArray{}\n\tresult.Schema = s\n\treturn result\n}\n\n// NewSchemaOrSchemaArrayWithSchemaArray creates and returns a new object\nfunc NewSchemaOrSchemaArrayWithSchemaArray(a []*Schema) *SchemaOrSchemaArray {\n\tresult := &SchemaOrSchemaArray{}\n\tresult.SchemaArray = &a\n\treturn result\n}\n\n// SchemaEnumValue represents a value that can be part of an\n// enumeration in a Schema.\ntype SchemaEnumValue struct {\n\tString *string\n\tBool   *bool\n}\n\n// NamedSchema is a name-value pair that is used to emulate maps\n// with ordered keys.\ntype NamedSchema struct {\n\tName  string\n\tValue *Schema\n}\n\n// NewNamedSchema creates and returns a new object\nfunc NewNamedSchema(name string, value *Schema) *NamedSchema {\n\treturn &NamedSchema{Name: name, Value: value}\n}\n\n// NamedSchemaOrStringArray is a name-value pair that is used\n// to emulate maps with ordered keys.\ntype NamedSchemaOrStringArray struct {\n\tName  string\n\tValue *SchemaOrStringArray\n}\n\n// Access named subschemas by name\n\nfunc namedSchemaArrayElementWithName(array *[]*NamedSchema, name string) *Schema {\n\tif array == nil {\n\t\treturn nil\n\t}\n\tfor _, pair := range *array {\n\t\tif pair.Name == name {\n\t\t\treturn pair.Value\n\t\t}\n\t}\n\treturn nil\n}\n\n// PropertyWithName returns the selected element.\nfunc (s *Schema) PropertyWithName(name string) *Schema {\n\treturn namedSchemaArrayElementWithName(s.Properties, name)\n}\n\n// PatternPropertyWithName returns the selected element.\nfunc (s *Schema) PatternPropertyWithName(name string) *Schema {\n\treturn namedSchemaArrayElementWithName(s.PatternProperties, name)\n}\n\n// DefinitionWithName returns the selected element.\nfunc (s *Schema) DefinitionWithName(name string) *Schema {\n\treturn namedSchemaArrayElementWithName(s.Definitions, name)\n}\n\n// AddProperty adds a named property.\nfunc (s *Schema) AddProperty(name string, property *Schema) {\n\t*s.Properties = append(*s.Properties, NewNamedSchema(name, property))\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/operations.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage jsonschema\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n)\n\n//\n// OPERATIONS\n// The following methods perform operations on Schemas.\n//\n\n// IsEmpty returns true if no members of the Schema are specified.\nfunc (schema *Schema) IsEmpty() bool {\n\treturn (schema.Schema == nil) &&\n\t\t(schema.ID == nil) &&\n\t\t(schema.MultipleOf == nil) &&\n\t\t(schema.Maximum == nil) &&\n\t\t(schema.ExclusiveMaximum == nil) &&\n\t\t(schema.Minimum == nil) &&\n\t\t(schema.ExclusiveMinimum == nil) &&\n\t\t(schema.MaxLength == nil) &&\n\t\t(schema.MinLength == nil) &&\n\t\t(schema.Pattern == nil) &&\n\t\t(schema.AdditionalItems == nil) &&\n\t\t(schema.Items == nil) &&\n\t\t(schema.MaxItems == nil) &&\n\t\t(schema.MinItems == nil) &&\n\t\t(schema.UniqueItems == nil) &&\n\t\t(schema.MaxProperties == nil) &&\n\t\t(schema.MinProperties == nil) &&\n\t\t(schema.Required == nil) &&\n\t\t(schema.AdditionalProperties == nil) &&\n\t\t(schema.Properties == nil) &&\n\t\t(schema.PatternProperties == nil) &&\n\t\t(schema.Dependencies == nil) &&\n\t\t(schema.Enumeration == nil) &&\n\t\t(schema.Type == nil) &&\n\t\t(schema.AllOf == nil) &&\n\t\t(schema.AnyOf == nil) &&\n\t\t(schema.OneOf == nil) &&\n\t\t(schema.Not == nil) &&\n\t\t(schema.Definitions == nil) &&\n\t\t(schema.Title == nil) &&\n\t\t(schema.Description == nil) &&\n\t\t(schema.Default == nil) &&\n\t\t(schema.Format == nil) &&\n\t\t(schema.Ref == nil)\n}\n\n// IsEqual returns true if two schemas are equal.\nfunc (schema *Schema) IsEqual(schema2 *Schema) bool {\n\treturn schema.String() == schema2.String()\n}\n\n// SchemaOperation represents a function that can be applied to a Schema.\ntype SchemaOperation func(schema *Schema, context string)\n\n// Applies a specified function to a Schema and all of the Schemas that it contains.\nfunc (schema *Schema) applyToSchemas(operation SchemaOperation, context string) {\n\n\tif schema.AdditionalItems != nil {\n\t\ts := schema.AdditionalItems.Schema\n\t\tif s != nil {\n\t\t\ts.applyToSchemas(operation, \"AdditionalItems\")\n\t\t}\n\t}\n\n\tif schema.Items != nil {\n\t\tif schema.Items.SchemaArray != nil {\n\t\t\tfor _, s := range *(schema.Items.SchemaArray) {\n\t\t\t\ts.applyToSchemas(operation, \"Items.SchemaArray\")\n\t\t\t}\n\t\t} else if schema.Items.Schema != nil {\n\t\t\tschema.Items.Schema.applyToSchemas(operation, \"Items.Schema\")\n\t\t}\n\t}\n\n\tif schema.AdditionalProperties != nil {\n\t\ts := schema.AdditionalProperties.Schema\n\t\tif s != nil {\n\t\t\ts.applyToSchemas(operation, \"AdditionalProperties\")\n\t\t}\n\t}\n\n\tif schema.Properties != nil {\n\t\tfor _, pair := range *(schema.Properties) {\n\t\t\ts := pair.Value\n\t\t\ts.applyToSchemas(operation, \"Properties\")\n\t\t}\n\t}\n\tif schema.PatternProperties != nil {\n\t\tfor _, pair := range *(schema.PatternProperties) {\n\t\t\ts := pair.Value\n\t\t\ts.applyToSchemas(operation, \"PatternProperties\")\n\t\t}\n\t}\n\n\tif schema.Dependencies != nil {\n\t\tfor _, pair := range *(schema.Dependencies) {\n\t\t\tschemaOrStringArray := pair.Value\n\t\t\ts := schemaOrStringArray.Schema\n\t\t\tif s != nil {\n\t\t\t\ts.applyToSchemas(operation, \"Dependencies\")\n\t\t\t}\n\t\t}\n\t}\n\n\tif schema.AllOf != nil {\n\t\tfor _, s := range *(schema.AllOf) {\n\t\t\ts.applyToSchemas(operation, \"AllOf\")\n\t\t}\n\t}\n\tif schema.AnyOf != nil {\n\t\tfor _, s := range *(schema.AnyOf) {\n\t\t\ts.applyToSchemas(operation, \"AnyOf\")\n\t\t}\n\t}\n\tif schema.OneOf != nil {\n\t\tfor _, s := range *(schema.OneOf) {\n\t\t\ts.applyToSchemas(operation, \"OneOf\")\n\t\t}\n\t}\n\tif schema.Not != nil {\n\t\tschema.Not.applyToSchemas(operation, \"Not\")\n\t}\n\n\tif schema.Definitions != nil {\n\t\tfor _, pair := range *(schema.Definitions) {\n\t\t\ts := pair.Value\n\t\t\ts.applyToSchemas(operation, \"Definitions\")\n\t\t}\n\t}\n\n\toperation(schema, context)\n}\n\n// CopyProperties copies all non-nil properties from the source Schema to the schema Schema.\nfunc (schema *Schema) CopyProperties(source *Schema) {\n\tif source.Schema != nil {\n\t\tschema.Schema = source.Schema\n\t}\n\tif source.ID != nil {\n\t\tschema.ID = source.ID\n\t}\n\tif source.MultipleOf != nil {\n\t\tschema.MultipleOf = source.MultipleOf\n\t}\n\tif source.Maximum != nil {\n\t\tschema.Maximum = source.Maximum\n\t}\n\tif source.ExclusiveMaximum != nil {\n\t\tschema.ExclusiveMaximum = source.ExclusiveMaximum\n\t}\n\tif source.Minimum != nil {\n\t\tschema.Minimum = source.Minimum\n\t}\n\tif source.ExclusiveMinimum != nil {\n\t\tschema.ExclusiveMinimum = source.ExclusiveMinimum\n\t}\n\tif source.MaxLength != nil {\n\t\tschema.MaxLength = source.MaxLength\n\t}\n\tif source.MinLength != nil {\n\t\tschema.MinLength = source.MinLength\n\t}\n\tif source.Pattern != nil {\n\t\tschema.Pattern = source.Pattern\n\t}\n\tif source.AdditionalItems != nil {\n\t\tschema.AdditionalItems = source.AdditionalItems\n\t}\n\tif source.Items != nil {\n\t\tschema.Items = source.Items\n\t}\n\tif source.MaxItems != nil {\n\t\tschema.MaxItems = source.MaxItems\n\t}\n\tif source.MinItems != nil {\n\t\tschema.MinItems = source.MinItems\n\t}\n\tif source.UniqueItems != nil {\n\t\tschema.UniqueItems = source.UniqueItems\n\t}\n\tif source.MaxProperties != nil {\n\t\tschema.MaxProperties = source.MaxProperties\n\t}\n\tif source.MinProperties != nil {\n\t\tschema.MinProperties = source.MinProperties\n\t}\n\tif source.Required != nil {\n\t\tschema.Required = source.Required\n\t}\n\tif source.AdditionalProperties != nil {\n\t\tschema.AdditionalProperties = source.AdditionalProperties\n\t}\n\tif source.Properties != nil {\n\t\tschema.Properties = source.Properties\n\t}\n\tif source.PatternProperties != nil {\n\t\tschema.PatternProperties = source.PatternProperties\n\t}\n\tif source.Dependencies != nil {\n\t\tschema.Dependencies = source.Dependencies\n\t}\n\tif source.Enumeration != nil {\n\t\tschema.Enumeration = source.Enumeration\n\t}\n\tif source.Type != nil {\n\t\tschema.Type = source.Type\n\t}\n\tif source.AllOf != nil {\n\t\tschema.AllOf = source.AllOf\n\t}\n\tif source.AnyOf != nil {\n\t\tschema.AnyOf = source.AnyOf\n\t}\n\tif source.OneOf != nil {\n\t\tschema.OneOf = source.OneOf\n\t}\n\tif source.Not != nil {\n\t\tschema.Not = source.Not\n\t}\n\tif source.Definitions != nil {\n\t\tschema.Definitions = source.Definitions\n\t}\n\tif source.Title != nil {\n\t\tschema.Title = source.Title\n\t}\n\tif source.Description != nil {\n\t\tschema.Description = source.Description\n\t}\n\tif source.Default != nil {\n\t\tschema.Default = source.Default\n\t}\n\tif source.Format != nil {\n\t\tschema.Format = source.Format\n\t}\n\tif source.Ref != nil {\n\t\tschema.Ref = source.Ref\n\t}\n}\n\n// TypeIs returns true if the Type of a Schema includes the specified type\nfunc (schema *Schema) TypeIs(typeName string) bool {\n\tif schema.Type != nil {\n\t\t// the schema Type is either a string or an array of strings\n\t\tif schema.Type.String != nil {\n\t\t\treturn (*(schema.Type.String) == typeName)\n\t\t} else if schema.Type.StringArray != nil {\n\t\t\tfor _, n := range *(schema.Type.StringArray) {\n\t\t\t\tif n == typeName {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// ResolveRefs resolves \"$ref\" elements in a Schema and its children.\n// But if a reference refers to an object type, is inside a oneOf, or contains a oneOf,\n// the reference is kept and we expect downstream tools to separately model these\n// referenced schemas.\nfunc (schema *Schema) ResolveRefs() {\n\trootSchema := schema\n\tcount := 1\n\tfor count > 0 {\n\t\tcount = 0\n\t\tschema.applyToSchemas(\n\t\t\tfunc(schema *Schema, context string) {\n\t\t\t\tif schema.Ref != nil {\n\t\t\t\t\tresolvedRef, err := rootSchema.resolveJSONPointer(*(schema.Ref))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tlog.Printf(\"%+v\", err)\n\t\t\t\t\t} else if resolvedRef.TypeIs(\"object\") {\n\t\t\t\t\t\t// don't substitute for objects, we'll model the referenced schema with a class\n\t\t\t\t\t} else if context == \"OneOf\" {\n\t\t\t\t\t\t// don't substitute for references inside oneOf declarations\n\t\t\t\t\t} else if resolvedRef.OneOf != nil {\n\t\t\t\t\t\t// don't substitute for references that contain oneOf declarations\n\t\t\t\t\t} else if resolvedRef.AdditionalProperties != nil {\n\t\t\t\t\t\t// don't substitute for references that look like objects\n\t\t\t\t\t} else {\n\t\t\t\t\t\tschema.Ref = nil\n\t\t\t\t\t\tschema.CopyProperties(resolvedRef)\n\t\t\t\t\t\tcount++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}, \"\")\n\t}\n}\n\n// resolveJSONPointer resolves JSON pointers.\n// This current implementation is very crude and custom for OpenAPI 2.0 schemas.\n// It panics for any pointer that it is unable to resolve.\nfunc (schema *Schema) resolveJSONPointer(ref string) (result *Schema, err error) {\n\tparts := strings.Split(ref, \"#\")\n\tif len(parts) == 2 {\n\t\tdocumentName := parts[0] + \"#\"\n\t\tif documentName == \"#\" && schema.ID != nil {\n\t\t\tdocumentName = *(schema.ID)\n\t\t}\n\t\tpath := parts[1]\n\t\tdocument := schemas[documentName]\n\t\tpathParts := strings.Split(path, \"/\")\n\n\t\t// we currently do a very limited (hard-coded) resolution of certain paths and log errors for missed cases\n\t\tif len(pathParts) == 1 {\n\t\t\treturn document, nil\n\t\t} else if len(pathParts) == 3 {\n\t\t\tswitch pathParts[1] {\n\t\t\tcase \"definitions\":\n\t\t\t\tdictionary := document.Definitions\n\t\t\t\tfor _, pair := range *dictionary {\n\t\t\t\t\tif pair.Name == pathParts[2] {\n\t\t\t\t\t\tresult = pair.Value\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tcase \"properties\":\n\t\t\t\tdictionary := document.Properties\n\t\t\t\tfor _, pair := range *dictionary {\n\t\t\t\t\tif pair.Name == pathParts[2] {\n\t\t\t\t\t\tresult = pair.Value\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tif result == nil {\n\t\treturn nil, fmt.Errorf(\"unresolved pointer: %+v\", ref)\n\t}\n\treturn result, nil\n}\n\n// ResolveAllOfs replaces \"allOf\" elements by merging their properties into the parent Schema.\nfunc (schema *Schema) ResolveAllOfs() {\n\tschema.applyToSchemas(\n\t\tfunc(schema *Schema, context string) {\n\t\t\tif schema.AllOf != nil {\n\t\t\t\tfor _, allOf := range *(schema.AllOf) {\n\t\t\t\t\tschema.CopyProperties(allOf)\n\t\t\t\t}\n\t\t\t\tschema.AllOf = nil\n\t\t\t}\n\t\t}, \"resolveAllOfs\")\n}\n\n// ResolveAnyOfs replaces all \"anyOf\" elements with \"oneOf\".\nfunc (schema *Schema) ResolveAnyOfs() {\n\tschema.applyToSchemas(\n\t\tfunc(schema *Schema, context string) {\n\t\t\tif schema.AnyOf != nil {\n\t\t\t\tschema.OneOf = schema.AnyOf\n\t\t\t\tschema.AnyOf = nil\n\t\t\t}\n\t\t}, \"resolveAnyOfs\")\n}\n\n// return a pointer to a copy of a passed-in string\nfunc stringptr(input string) (output *string) {\n\treturn &input\n}\n\n// CopyOfficialSchemaProperty copies a named property from the official JSON Schema definition\nfunc (schema *Schema) CopyOfficialSchemaProperty(name string) {\n\t*schema.Properties = append(*schema.Properties,\n\t\tNewNamedSchema(name,\n\t\t\t&Schema{Ref: stringptr(\"http://json-schema.org/draft-04/schema#/properties/\" + name)}))\n}\n\n// CopyOfficialSchemaProperties copies named properties from the official JSON Schema definition\nfunc (schema *Schema) CopyOfficialSchemaProperties(names []string) {\n\tfor _, name := range names {\n\t\tschema.CopyOfficialSchemaProperty(name)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/reader.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\n//go:generate go run generate-base.go\n\npackage jsonschema\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"strconv\"\n\n\t\"gopkg.in/yaml.v3\"\n)\n\n// This is a global map of all known Schemas.\n// It is initialized when the first Schema is created and inserted.\nvar schemas map[string]*Schema\n\n// NewBaseSchema builds a schema object from an embedded json representation.\nfunc NewBaseSchema() (schema *Schema, err error) {\n\tb, err := baseSchemaBytes()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar node yaml.Node\n\terr = yaml.Unmarshal(b, &node)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewSchemaFromObject(&node), nil\n}\n\n// NewSchemaFromFile reads a schema from a file.\n// Currently this assumes that schemas are stored in the source distribution of this project.\nfunc NewSchemaFromFile(filename string) (schema *Schema, err error) {\n\tfile, err := ioutil.ReadFile(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar node yaml.Node\n\terr = yaml.Unmarshal(file, &node)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewSchemaFromObject(&node), nil\n}\n\n// NewSchemaFromObject constructs a schema from a parsed JSON object.\n// Due to the complexity of the schema representation, this is a\n// custom reader and not the standard Go JSON reader (encoding/json).\nfunc NewSchemaFromObject(jsonData *yaml.Node) *Schema {\n\tswitch jsonData.Kind {\n\tcase yaml.DocumentNode:\n\t\treturn NewSchemaFromObject(jsonData.Content[0])\n\tcase yaml.MappingNode:\n\t\tschema := &Schema{}\n\n\t\tfor i := 0; i < len(jsonData.Content); i += 2 {\n\t\t\tk := jsonData.Content[i].Value\n\t\t\tv := jsonData.Content[i+1]\n\n\t\t\tswitch k {\n\t\t\tcase \"$schema\":\n\t\t\t\tschema.Schema = schema.stringValue(v)\n\t\t\tcase \"id\":\n\t\t\t\tschema.ID = schema.stringValue(v)\n\n\t\t\tcase \"multipleOf\":\n\t\t\t\tschema.MultipleOf = schema.numberValue(v)\n\t\t\tcase \"maximum\":\n\t\t\t\tschema.Maximum = schema.numberValue(v)\n\t\t\tcase \"exclusiveMaximum\":\n\t\t\t\tschema.ExclusiveMaximum = schema.boolValue(v)\n\t\t\tcase \"minimum\":\n\t\t\t\tschema.Minimum = schema.numberValue(v)\n\t\t\tcase \"exclusiveMinimum\":\n\t\t\t\tschema.ExclusiveMinimum = schema.boolValue(v)\n\n\t\t\tcase \"maxLength\":\n\t\t\t\tschema.MaxLength = schema.intValue(v)\n\t\t\tcase \"minLength\":\n\t\t\t\tschema.MinLength = schema.intValue(v)\n\t\t\tcase \"pattern\":\n\t\t\t\tschema.Pattern = schema.stringValue(v)\n\n\t\t\tcase \"additionalItems\":\n\t\t\t\tschema.AdditionalItems = schema.schemaOrBooleanValue(v)\n\t\t\tcase \"items\":\n\t\t\t\tschema.Items = schema.schemaOrSchemaArrayValue(v)\n\t\t\tcase \"maxItems\":\n\t\t\t\tschema.MaxItems = schema.intValue(v)\n\t\t\tcase \"minItems\":\n\t\t\t\tschema.MinItems = schema.intValue(v)\n\t\t\tcase \"uniqueItems\":\n\t\t\t\tschema.UniqueItems = schema.boolValue(v)\n\n\t\t\tcase \"maxProperties\":\n\t\t\t\tschema.MaxProperties = schema.intValue(v)\n\t\t\tcase \"minProperties\":\n\t\t\t\tschema.MinProperties = schema.intValue(v)\n\t\t\tcase \"required\":\n\t\t\t\tschema.Required = schema.arrayOfStringsValue(v)\n\t\t\tcase \"additionalProperties\":\n\t\t\t\tschema.AdditionalProperties = schema.schemaOrBooleanValue(v)\n\t\t\tcase \"properties\":\n\t\t\t\tschema.Properties = schema.mapOfSchemasValue(v)\n\t\t\tcase \"patternProperties\":\n\t\t\t\tschema.PatternProperties = schema.mapOfSchemasValue(v)\n\t\t\tcase \"dependencies\":\n\t\t\t\tschema.Dependencies = schema.mapOfSchemasOrStringArraysValue(v)\n\n\t\t\tcase \"enum\":\n\t\t\t\tschema.Enumeration = schema.arrayOfEnumValuesValue(v)\n\n\t\t\tcase \"type\":\n\t\t\t\tschema.Type = schema.stringOrStringArrayValue(v)\n\t\t\tcase \"allOf\":\n\t\t\t\tschema.AllOf = schema.arrayOfSchemasValue(v)\n\t\t\tcase \"anyOf\":\n\t\t\t\tschema.AnyOf = schema.arrayOfSchemasValue(v)\n\t\t\tcase \"oneOf\":\n\t\t\t\tschema.OneOf = schema.arrayOfSchemasValue(v)\n\t\t\tcase \"not\":\n\t\t\t\tschema.Not = NewSchemaFromObject(v)\n\t\t\tcase \"definitions\":\n\t\t\t\tschema.Definitions = schema.mapOfSchemasValue(v)\n\n\t\t\tcase \"title\":\n\t\t\t\tschema.Title = schema.stringValue(v)\n\t\t\tcase \"description\":\n\t\t\t\tschema.Description = schema.stringValue(v)\n\n\t\t\tcase \"default\":\n\t\t\t\tschema.Default = v\n\n\t\t\tcase \"format\":\n\t\t\t\tschema.Format = schema.stringValue(v)\n\t\t\tcase \"$ref\":\n\t\t\t\tschema.Ref = schema.stringValue(v)\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"UNSUPPORTED (%s)\\n\", k)\n\t\t\t}\n\t\t}\n\n\t\t// insert schema in global map\n\t\tif schema.ID != nil {\n\t\t\tif schemas == nil {\n\t\t\t\tschemas = make(map[string]*Schema, 0)\n\t\t\t}\n\t\t\tschemas[*(schema.ID)] = schema\n\t\t}\n\t\treturn schema\n\n\tdefault:\n\t\tfmt.Printf(\"schemaValue: unexpected node %+v\\n\", jsonData)\n\t\treturn nil\n\t}\n\n\treturn nil\n}\n\n//\n// BUILDERS\n// The following methods build elements of Schemas from interface{} values.\n// Each returns nil if it is unable to build the desired element.\n//\n\n// Gets the string value of an interface{} value if possible.\nfunc (schema *Schema) stringValue(v *yaml.Node) *string {\n\tswitch v.Kind {\n\tcase yaml.ScalarNode:\n\t\treturn &v.Value\n\tdefault:\n\t\tfmt.Printf(\"stringValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets the numeric value of an interface{} value if possible.\nfunc (schema *Schema) numberValue(v *yaml.Node) *SchemaNumber {\n\tnumber := &SchemaNumber{}\n\tswitch v.Kind {\n\tcase yaml.ScalarNode:\n\t\tswitch v.Tag {\n\t\tcase \"!!float\":\n\t\t\tv2, _ := strconv.ParseFloat(v.Value, 64)\n\t\t\tnumber.Float = &v2\n\t\t\treturn number\n\t\tcase \"!!int\":\n\t\t\tv2, _ := strconv.ParseInt(v.Value, 10, 64)\n\t\t\tnumber.Integer = &v2\n\t\t\treturn number\n\t\tdefault:\n\t\t\tfmt.Printf(\"stringValue: unexpected node %+v\\n\", v)\n\t\t}\n\tdefault:\n\t\tfmt.Printf(\"stringValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets the integer value of an interface{} value if possible.\nfunc (schema *Schema) intValue(v *yaml.Node) *int64 {\n\tswitch v.Kind {\n\tcase yaml.ScalarNode:\n\t\tswitch v.Tag {\n\t\tcase \"!!float\":\n\t\t\tv2, _ := strconv.ParseFloat(v.Value, 64)\n\t\t\tv3 := int64(v2)\n\t\t\treturn &v3\n\t\tcase \"!!int\":\n\t\t\tv2, _ := strconv.ParseInt(v.Value, 10, 64)\n\t\t\treturn &v2\n\t\tdefault:\n\t\t\tfmt.Printf(\"intValue: unexpected node %+v\\n\", v)\n\t\t}\n\tdefault:\n\t\tfmt.Printf(\"intValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets the bool value of an interface{} value if possible.\nfunc (schema *Schema) boolValue(v *yaml.Node) *bool {\n\tswitch v.Kind {\n\tcase yaml.ScalarNode:\n\t\tswitch v.Tag {\n\t\tcase \"!!bool\":\n\t\t\tv2, _ := strconv.ParseBool(v.Value)\n\t\t\treturn &v2\n\t\tdefault:\n\t\t\tfmt.Printf(\"boolValue: unexpected node %+v\\n\", v)\n\t\t}\n\tdefault:\n\t\tfmt.Printf(\"boolValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets a map of Schemas from an interface{} value if possible.\nfunc (schema *Schema) mapOfSchemasValue(v *yaml.Node) *[]*NamedSchema {\n\tswitch v.Kind {\n\tcase yaml.MappingNode:\n\t\tm := make([]*NamedSchema, 0)\n\t\tfor i := 0; i < len(v.Content); i += 2 {\n\t\t\tk2 := v.Content[i].Value\n\t\t\tv2 := v.Content[i+1]\n\t\t\tpair := &NamedSchema{Name: k2, Value: NewSchemaFromObject(v2)}\n\t\t\tm = append(m, pair)\n\t\t}\n\t\treturn &m\n\tdefault:\n\t\tfmt.Printf(\"mapOfSchemasValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets an array of Schemas from an interface{} value if possible.\nfunc (schema *Schema) arrayOfSchemasValue(v *yaml.Node) *[]*Schema {\n\tswitch v.Kind {\n\tcase yaml.SequenceNode:\n\t\tm := make([]*Schema, 0)\n\t\tfor _, v2 := range v.Content {\n\t\t\tswitch v2.Kind {\n\t\t\tcase yaml.MappingNode:\n\t\t\t\ts := NewSchemaFromObject(v2)\n\t\t\t\tm = append(m, s)\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"arrayOfSchemasValue: unexpected node %+v\\n\", v2)\n\t\t\t}\n\t\t}\n\t\treturn &m\n\tcase yaml.MappingNode:\n\t\tm := make([]*Schema, 0)\n\t\ts := NewSchemaFromObject(v)\n\t\tm = append(m, s)\n\t\treturn &m\n\tdefault:\n\t\tfmt.Printf(\"arrayOfSchemasValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets a Schema or an array of Schemas from an interface{} value if possible.\nfunc (schema *Schema) schemaOrSchemaArrayValue(v *yaml.Node) *SchemaOrSchemaArray {\n\tswitch v.Kind {\n\tcase yaml.SequenceNode:\n\t\tm := make([]*Schema, 0)\n\t\tfor _, v2 := range v.Content {\n\t\t\tswitch v2.Kind {\n\t\t\tcase yaml.MappingNode:\n\t\t\t\ts := NewSchemaFromObject(v2)\n\t\t\t\tm = append(m, s)\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"schemaOrSchemaArrayValue: unexpected node %+v\\n\", v2)\n\t\t\t}\n\t\t}\n\t\treturn &SchemaOrSchemaArray{SchemaArray: &m}\n\tcase yaml.MappingNode:\n\t\ts := NewSchemaFromObject(v)\n\t\treturn &SchemaOrSchemaArray{Schema: s}\n\tdefault:\n\t\tfmt.Printf(\"schemaOrSchemaArrayValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets an array of strings from an interface{} value if possible.\nfunc (schema *Schema) arrayOfStringsValue(v *yaml.Node) *[]string {\n\tswitch v.Kind {\n\tcase yaml.ScalarNode:\n\t\ta := []string{v.Value}\n\t\treturn &a\n\tcase yaml.SequenceNode:\n\t\ta := make([]string, 0)\n\t\tfor _, v2 := range v.Content {\n\t\t\tswitch v2.Kind {\n\t\t\tcase yaml.ScalarNode:\n\t\t\t\ta = append(a, v2.Value)\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"arrayOfStringsValue: unexpected node %+v\\n\", v2)\n\t\t\t}\n\t\t}\n\t\treturn &a\n\tdefault:\n\t\tfmt.Printf(\"arrayOfStringsValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets a string or an array of strings from an interface{} value if possible.\nfunc (schema *Schema) stringOrStringArrayValue(v *yaml.Node) *StringOrStringArray {\n\tswitch v.Kind {\n\tcase yaml.ScalarNode:\n\t\ts := &StringOrStringArray{}\n\t\ts.String = &v.Value\n\t\treturn s\n\tcase yaml.SequenceNode:\n\t\ta := make([]string, 0)\n\t\tfor _, v2 := range v.Content {\n\t\t\tswitch v2.Kind {\n\t\t\tcase yaml.ScalarNode:\n\t\t\t\ta = append(a, v2.Value)\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"arrayOfStringsValue: unexpected node %+v\\n\", v2)\n\t\t\t}\n\t\t}\n\t\ts := &StringOrStringArray{}\n\t\ts.StringArray = &a\n\t\treturn s\n\tdefault:\n\t\tfmt.Printf(\"arrayOfStringsValue: unexpected node %+v\\n\", v)\n\t}\n\treturn nil\n}\n\n// Gets an array of enum values from an interface{} value if possible.\nfunc (schema *Schema) arrayOfEnumValuesValue(v *yaml.Node) *[]SchemaEnumValue {\n\ta := make([]SchemaEnumValue, 0)\n\tswitch v.Kind {\n\tcase yaml.SequenceNode:\n\t\tfor _, v2 := range v.Content {\n\t\t\tswitch v2.Kind {\n\t\t\tcase yaml.ScalarNode:\n\t\t\t\tswitch v2.Tag {\n\t\t\t\tcase \"!!str\":\n\t\t\t\t\ta = append(a, SchemaEnumValue{String: &v2.Value})\n\t\t\t\tcase \"!!bool\":\n\t\t\t\t\tv3, _ := strconv.ParseBool(v2.Value)\n\t\t\t\t\ta = append(a, SchemaEnumValue{Bool: &v3})\n\t\t\t\tdefault:\n\t\t\t\t\tfmt.Printf(\"arrayOfEnumValuesValue: unexpected type %s\\n\", v2.Tag)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"arrayOfEnumValuesValue: unexpected node %+v\\n\", v2)\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tfmt.Printf(\"arrayOfEnumValuesValue: unexpected node %+v\\n\", v)\n\t}\n\treturn &a\n}\n\n// Gets a map of schemas or string arrays from an interface{} value if possible.\nfunc (schema *Schema) mapOfSchemasOrStringArraysValue(v *yaml.Node) *[]*NamedSchemaOrStringArray {\n\tm := make([]*NamedSchemaOrStringArray, 0)\n\tswitch v.Kind {\n\tcase yaml.MappingNode:\n\t\tfor i := 0; i < len(v.Content); i += 2 {\n\t\t\tk2 := v.Content[i].Value\n\t\t\tv2 := v.Content[i+1]\n\t\t\tswitch v2.Kind {\n\t\t\tcase yaml.SequenceNode:\n\t\t\t\ta := make([]string, 0)\n\t\t\t\tfor _, v3 := range v2.Content {\n\t\t\t\t\tswitch v3.Kind {\n\t\t\t\t\tcase yaml.ScalarNode:\n\t\t\t\t\t\ta = append(a, v3.Value)\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tfmt.Printf(\"mapOfSchemasOrStringArraysValue: unexpected node %+v\\n\", v3)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ts := &SchemaOrStringArray{}\n\t\t\t\ts.StringArray = &a\n\t\t\t\tpair := &NamedSchemaOrStringArray{Name: k2, Value: s}\n\t\t\t\tm = append(m, pair)\n\t\t\tdefault:\n\t\t\t\tfmt.Printf(\"mapOfSchemasOrStringArraysValue: unexpected node %+v\\n\", v2)\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tfmt.Printf(\"mapOfSchemasOrStringArraysValue: unexpected node %+v\\n\", v)\n\t}\n\treturn &m\n}\n\n// Gets a schema or a boolean value from an interface{} value if possible.\nfunc (schema *Schema) schemaOrBooleanValue(v *yaml.Node) *SchemaOrBoolean {\n\tschemaOrBoolean := &SchemaOrBoolean{}\n\tswitch v.Kind {\n\tcase yaml.ScalarNode:\n\t\tv2, _ := strconv.ParseBool(v.Value)\n\t\tschemaOrBoolean.Boolean = &v2\n\tcase yaml.MappingNode:\n\t\tschemaOrBoolean.Schema = NewSchemaFromObject(v)\n\tdefault:\n\t\tfmt.Printf(\"schemaOrBooleanValue: unexpected node %+v\\n\", v)\n\t}\n\treturn schemaOrBoolean\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/schema.json",
    "content": "{\n    \"id\": \"http://json-schema.org/draft-04/schema#\",\n    \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n    \"description\": \"Core schema meta-schema\",\n    \"definitions\": {\n        \"schemaArray\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"items\": { \"$ref\": \"#\" }\n        },\n        \"positiveInteger\": {\n            \"type\": \"integer\",\n            \"minimum\": 0\n        },\n        \"positiveIntegerDefault0\": {\n            \"allOf\": [ { \"$ref\": \"#/definitions/positiveInteger\" }, { \"default\": 0 } ]\n        },\n        \"simpleTypes\": {\n            \"enum\": [ \"array\", \"boolean\", \"integer\", \"null\", \"number\", \"object\", \"string\" ]\n        },\n        \"stringArray\": {\n            \"type\": \"array\",\n            \"items\": { \"type\": \"string\" },\n            \"minItems\": 1,\n            \"uniqueItems\": true\n        }\n    },\n    \"type\": \"object\",\n    \"properties\": {\n        \"id\": {\n            \"type\": \"string\",\n            \"format\": \"uri\"\n        },\n        \"$schema\": {\n            \"type\": \"string\",\n            \"format\": \"uri\"\n        },\n        \"title\": {\n            \"type\": \"string\"\n        },\n        \"description\": {\n            \"type\": \"string\"\n        },\n        \"default\": {},\n        \"multipleOf\": {\n            \"type\": \"number\",\n            \"minimum\": 0,\n            \"exclusiveMinimum\": true\n        },\n        \"maximum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMaximum\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"minimum\": {\n            \"type\": \"number\"\n        },\n        \"exclusiveMinimum\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"maxLength\": { \"$ref\": \"#/definitions/positiveInteger\" },\n        \"minLength\": { \"$ref\": \"#/definitions/positiveIntegerDefault0\" },\n        \"pattern\": {\n            \"type\": \"string\",\n            \"format\": \"regex\"\n        },\n        \"additionalItems\": {\n            \"anyOf\": [\n                { \"type\": \"boolean\" },\n                { \"$ref\": \"#\" }\n            ],\n            \"default\": {}\n        },\n        \"items\": {\n            \"anyOf\": [\n                { \"$ref\": \"#\" },\n                { \"$ref\": \"#/definitions/schemaArray\" }\n            ],\n            \"default\": {}\n        },\n        \"maxItems\": { \"$ref\": \"#/definitions/positiveInteger\" },\n        \"minItems\": { \"$ref\": \"#/definitions/positiveIntegerDefault0\" },\n        \"uniqueItems\": {\n            \"type\": \"boolean\",\n            \"default\": false\n        },\n        \"maxProperties\": { \"$ref\": \"#/definitions/positiveInteger\" },\n        \"minProperties\": { \"$ref\": \"#/definitions/positiveIntegerDefault0\" },\n        \"required\": { \"$ref\": \"#/definitions/stringArray\" },\n        \"additionalProperties\": {\n            \"anyOf\": [\n                { \"type\": \"boolean\" },\n                { \"$ref\": \"#\" }\n            ],\n            \"default\": {}\n        },\n        \"definitions\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"properties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"patternProperties\": {\n            \"type\": \"object\",\n            \"additionalProperties\": { \"$ref\": \"#\" },\n            \"default\": {}\n        },\n        \"dependencies\": {\n            \"type\": \"object\",\n            \"additionalProperties\": {\n                \"anyOf\": [\n                    { \"$ref\": \"#\" },\n                    { \"$ref\": \"#/definitions/stringArray\" }\n                ]\n            }\n        },\n        \"enum\": {\n            \"type\": \"array\",\n            \"minItems\": 1,\n            \"uniqueItems\": true\n        },\n        \"type\": {\n            \"anyOf\": [\n                { \"$ref\": \"#/definitions/simpleTypes\" },\n                {\n                    \"type\": \"array\",\n                    \"items\": { \"$ref\": \"#/definitions/simpleTypes\" },\n                    \"minItems\": 1,\n                    \"uniqueItems\": true\n                }\n            ]\n        },\n        \"allOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"anyOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"oneOf\": { \"$ref\": \"#/definitions/schemaArray\" },\n        \"not\": { \"$ref\": \"#\" }\n    },\n    \"dependencies\": {\n        \"exclusiveMaximum\": [ \"maximum\" ],\n        \"exclusiveMinimum\": [ \"minimum\" ]\n    },\n    \"default\": {}\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/jsonschema/writer.go",
    "content": "// Copyright 2017 Google LLC. All Rights Reserved.\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//    http://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\npackage jsonschema\n\nimport (\n\t\"fmt\"\n\n\t\"gopkg.in/yaml.v3\"\n)\n\nconst indentation = \"  \"\n\nfunc renderMappingNode(node *yaml.Node, indent string) (result string) {\n\tresult = \"{\\n\"\n\tinnerIndent := indent + indentation\n\tfor i := 0; i < len(node.Content); i += 2 {\n\t\t// first print the key\n\t\tkey := node.Content[i].Value\n\t\tresult += fmt.Sprintf(\"%s\\\"%+v\\\": \", innerIndent, key)\n\t\t// then the value\n\t\tvalue := node.Content[i+1]\n\t\tswitch value.Kind {\n\t\tcase yaml.ScalarNode:\n\t\t\tresult += \"\\\"\" + value.Value + \"\\\"\"\n\t\tcase yaml.MappingNode:\n\t\t\tresult += renderMappingNode(value, innerIndent)\n\t\tcase yaml.SequenceNode:\n\t\t\tresult += renderSequenceNode(value, innerIndent)\n\t\tdefault:\n\t\t\tresult += fmt.Sprintf(\"???MapItem(Key:%+v, Value:%T)\", value, value)\n\t\t}\n\t\tif i < len(node.Content)-2 {\n\t\t\tresult += \",\"\n\t\t}\n\t\tresult += \"\\n\"\n\t}\n\n\tresult += indent + \"}\"\n\treturn result\n}\n\nfunc renderSequenceNode(node *yaml.Node, indent string) (result string) {\n\tresult = \"[\\n\"\n\tinnerIndent := indent + indentation\n\tfor i := 0; i < len(node.Content); i++ {\n\t\titem := node.Content[i]\n\t\tswitch item.Kind {\n\t\tcase yaml.ScalarNode:\n\t\t\tresult += innerIndent + \"\\\"\" + item.Value + \"\\\"\"\n\t\tcase yaml.MappingNode:\n\t\t\tresult += innerIndent + renderMappingNode(item, innerIndent) + \"\"\n\t\tdefault:\n\t\t\tresult += innerIndent + fmt.Sprintf(\"???ArrayItem(%+v)\", item)\n\t\t}\n\t\tif i < len(node.Content)-1 {\n\t\t\tresult += \",\"\n\t\t}\n\t\tresult += \"\\n\"\n\t}\n\tresult += indent + \"]\"\n\treturn result\n}\n\nfunc renderStringArray(array []string, indent string) (result string) {\n\tresult = \"[\\n\"\n\tinnerIndent := indent + indentation\n\tfor i, item := range array {\n\t\tresult += innerIndent + \"\\\"\" + item + \"\\\"\"\n\t\tif i < len(array)-1 {\n\t\t\tresult += \",\"\n\t\t}\n\t\tresult += \"\\n\"\n\t}\n\tresult += indent + \"]\"\n\treturn result\n}\n\n// Render renders a yaml.Node as JSON\nfunc Render(node *yaml.Node) string {\n\tif node.Kind == yaml.DocumentNode {\n\t\tif len(node.Content) == 1 {\n\t\t\treturn Render(node.Content[0])\n\t\t}\n\t} else if node.Kind == yaml.MappingNode {\n\t\treturn renderMappingNode(node, \"\") + \"\\n\"\n\t} else if node.Kind == yaml.SequenceNode {\n\t\treturn renderSequenceNode(node, \"\") + \"\\n\"\n\t}\n\treturn \"\"\n}\n\nfunc (object *SchemaNumber) nodeValue() *yaml.Node {\n\tif object.Integer != nil {\n\t\treturn nodeForInt64(*object.Integer)\n\t} else if object.Float != nil {\n\t\treturn nodeForFloat64(*object.Float)\n\t} else {\n\t\treturn nil\n\t}\n}\n\nfunc (object *SchemaOrBoolean) nodeValue() *yaml.Node {\n\tif object.Schema != nil {\n\t\treturn object.Schema.nodeValue()\n\t} else if object.Boolean != nil {\n\t\treturn nodeForBoolean(*object.Boolean)\n\t} else {\n\t\treturn nil\n\t}\n}\n\nfunc nodeForStringArray(array []string) *yaml.Node {\n\tcontent := make([]*yaml.Node, 0)\n\tfor _, item := range array {\n\t\tcontent = append(content, nodeForString(item))\n\t}\n\treturn nodeForSequence(content)\n}\n\nfunc nodeForSchemaArray(array []*Schema) *yaml.Node {\n\tcontent := make([]*yaml.Node, 0)\n\tfor _, item := range array {\n\t\tcontent = append(content, item.nodeValue())\n\t}\n\treturn nodeForSequence(content)\n}\n\nfunc (object *StringOrStringArray) nodeValue() *yaml.Node {\n\tif object.String != nil {\n\t\treturn nodeForString(*object.String)\n\t} else if object.StringArray != nil {\n\t\treturn nodeForStringArray(*(object.StringArray))\n\t} else {\n\t\treturn nil\n\t}\n}\n\nfunc (object *SchemaOrStringArray) nodeValue() *yaml.Node {\n\tif object.Schema != nil {\n\t\treturn object.Schema.nodeValue()\n\t} else if object.StringArray != nil {\n\t\treturn nodeForStringArray(*(object.StringArray))\n\t} else {\n\t\treturn nil\n\t}\n}\n\nfunc (object *SchemaOrSchemaArray) nodeValue() *yaml.Node {\n\tif object.Schema != nil {\n\t\treturn object.Schema.nodeValue()\n\t} else if object.SchemaArray != nil {\n\t\treturn nodeForSchemaArray(*(object.SchemaArray))\n\t} else {\n\t\treturn nil\n\t}\n}\n\nfunc (object *SchemaEnumValue) nodeValue() *yaml.Node {\n\tif object.String != nil {\n\t\treturn nodeForString(*object.String)\n\t} else if object.Bool != nil {\n\t\treturn nodeForBoolean(*object.Bool)\n\t} else {\n\t\treturn nil\n\t}\n}\n\nfunc nodeForNamedSchemaArray(array *[]*NamedSchema) *yaml.Node {\n\tcontent := make([]*yaml.Node, 0)\n\tfor _, pair := range *(array) {\n\t\tcontent = appendPair(content, pair.Name, pair.Value.nodeValue())\n\t}\n\treturn nodeForMapping(content)\n}\n\nfunc nodeForNamedSchemaOrStringArray(array *[]*NamedSchemaOrStringArray) *yaml.Node {\n\tcontent := make([]*yaml.Node, 0)\n\tfor _, pair := range *(array) {\n\t\tcontent = appendPair(content, pair.Name, pair.Value.nodeValue())\n\t}\n\treturn nodeForMapping(content)\n}\n\nfunc nodeForSchemaEnumArray(array *[]SchemaEnumValue) *yaml.Node {\n\tcontent := make([]*yaml.Node, 0)\n\tfor _, item := range *array {\n\t\tcontent = append(content, item.nodeValue())\n\t}\n\treturn nodeForSequence(content)\n}\n\nfunc nodeForMapping(content []*yaml.Node) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:    yaml.MappingNode,\n\t\tContent: content,\n\t}\n}\n\nfunc nodeForSequence(content []*yaml.Node) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:    yaml.SequenceNode,\n\t\tContent: content,\n\t}\n}\n\nfunc nodeForString(value string) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!str\",\n\t\tValue: value,\n\t}\n}\n\nfunc nodeForBoolean(value bool) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!bool\",\n\t\tValue: fmt.Sprintf(\"%t\", value),\n\t}\n}\n\nfunc nodeForInt64(value int64) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!int\",\n\t\tValue: fmt.Sprintf(\"%d\", value),\n\t}\n}\n\nfunc nodeForFloat64(value float64) *yaml.Node {\n\treturn &yaml.Node{\n\t\tKind:  yaml.ScalarNode,\n\t\tTag:   \"!!float\",\n\t\tValue: fmt.Sprintf(\"%f\", value),\n\t}\n}\n\nfunc appendPair(nodes []*yaml.Node, name string, value *yaml.Node) []*yaml.Node {\n\tnodes = append(nodes, nodeForString(name))\n\tnodes = append(nodes, value)\n\treturn nodes\n}\n\nfunc (schema *Schema) nodeValue() *yaml.Node {\n\tn := &yaml.Node{Kind: yaml.MappingNode}\n\tcontent := make([]*yaml.Node, 0)\n\tif schema.Title != nil {\n\t\tcontent = appendPair(content, \"title\", nodeForString(*schema.Title))\n\t}\n\tif schema.ID != nil {\n\t\tcontent = appendPair(content, \"id\", nodeForString(*schema.ID))\n\t}\n\tif schema.Schema != nil {\n\t\tcontent = appendPair(content, \"$schema\", nodeForString(*schema.Schema))\n\t}\n\tif schema.Type != nil {\n\t\tcontent = appendPair(content, \"type\", schema.Type.nodeValue())\n\t}\n\tif schema.Items != nil {\n\t\tcontent = appendPair(content, \"items\", schema.Items.nodeValue())\n\t}\n\tif schema.Description != nil {\n\t\tcontent = appendPair(content, \"description\", nodeForString(*schema.Description))\n\t}\n\tif schema.Required != nil {\n\t\tcontent = appendPair(content, \"required\", nodeForStringArray(*schema.Required))\n\t}\n\tif schema.AdditionalProperties != nil {\n\t\tcontent = appendPair(content, \"additionalProperties\", schema.AdditionalProperties.nodeValue())\n\t}\n\tif schema.PatternProperties != nil {\n\t\tcontent = appendPair(content, \"patternProperties\", nodeForNamedSchemaArray(schema.PatternProperties))\n\t}\n\tif schema.Properties != nil {\n\t\tcontent = appendPair(content, \"properties\", nodeForNamedSchemaArray(schema.Properties))\n\t}\n\tif schema.Dependencies != nil {\n\t\tcontent = appendPair(content, \"dependencies\", nodeForNamedSchemaOrStringArray(schema.Dependencies))\n\t}\n\tif schema.Ref != nil {\n\t\tcontent = appendPair(content, \"$ref\", nodeForString(*schema.Ref))\n\t}\n\tif schema.MultipleOf != nil {\n\t\tcontent = appendPair(content, \"multipleOf\", schema.MultipleOf.nodeValue())\n\t}\n\tif schema.Maximum != nil {\n\t\tcontent = appendPair(content, \"maximum\", schema.Maximum.nodeValue())\n\t}\n\tif schema.ExclusiveMaximum != nil {\n\t\tcontent = appendPair(content, \"exclusiveMaximum\", nodeForBoolean(*schema.ExclusiveMaximum))\n\t}\n\tif schema.Minimum != nil {\n\t\tcontent = appendPair(content, \"minimum\", schema.Minimum.nodeValue())\n\t}\n\tif schema.ExclusiveMinimum != nil {\n\t\tcontent = appendPair(content, \"exclusiveMinimum\", nodeForBoolean(*schema.ExclusiveMinimum))\n\t}\n\tif schema.MaxLength != nil {\n\t\tcontent = appendPair(content, \"maxLength\", nodeForInt64(*schema.MaxLength))\n\t}\n\tif schema.MinLength != nil {\n\t\tcontent = appendPair(content, \"minLength\", nodeForInt64(*schema.MinLength))\n\t}\n\tif schema.Pattern != nil {\n\t\tcontent = appendPair(content, \"pattern\", nodeForString(*schema.Pattern))\n\t}\n\tif schema.AdditionalItems != nil {\n\t\tcontent = appendPair(content, \"additionalItems\", schema.AdditionalItems.nodeValue())\n\t}\n\tif schema.MaxItems != nil {\n\t\tcontent = appendPair(content, \"maxItems\", nodeForInt64(*schema.MaxItems))\n\t}\n\tif schema.MinItems != nil {\n\t\tcontent = appendPair(content, \"minItems\", nodeForInt64(*schema.MinItems))\n\t}\n\tif schema.UniqueItems != nil {\n\t\tcontent = appendPair(content, \"uniqueItems\", nodeForBoolean(*schema.UniqueItems))\n\t}\n\tif schema.MaxProperties != nil {\n\t\tcontent = appendPair(content, \"maxProperties\", nodeForInt64(*schema.MaxProperties))\n\t}\n\tif schema.MinProperties != nil {\n\t\tcontent = appendPair(content, \"minProperties\", nodeForInt64(*schema.MinProperties))\n\t}\n\tif schema.Enumeration != nil {\n\t\tcontent = appendPair(content, \"enum\", nodeForSchemaEnumArray(schema.Enumeration))\n\t}\n\tif schema.AllOf != nil {\n\t\tcontent = appendPair(content, \"allOf\", nodeForSchemaArray(*schema.AllOf))\n\t}\n\tif schema.AnyOf != nil {\n\t\tcontent = appendPair(content, \"anyOf\", nodeForSchemaArray(*schema.AnyOf))\n\t}\n\tif schema.OneOf != nil {\n\t\tcontent = appendPair(content, \"oneOf\", nodeForSchemaArray(*schema.OneOf))\n\t}\n\tif schema.Not != nil {\n\t\tcontent = appendPair(content, \"not\", schema.Not.nodeValue())\n\t}\n\tif schema.Definitions != nil {\n\t\tcontent = appendPair(content, \"definitions\", nodeForNamedSchemaArray(schema.Definitions))\n\t}\n\tif schema.Default != nil {\n\t\t// m = append(m, yaml.MapItem{Key: \"default\", Value: *schema.Default})\n\t}\n\tif schema.Format != nil {\n\t\tcontent = appendPair(content, \"format\", nodeForString(*schema.Format))\n\t}\n\tn.Content = content\n\treturn n\n}\n\n// JSONString returns a json representation of a schema.\nfunc (schema *Schema) JSONString() string {\n\tnode := schema.nodeValue()\n\treturn Render(node)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.go",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\n// THIS FILE IS AUTOMATICALLY GENERATED.\n\npackage openapi_v2\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/google/gnostic/compiler\"\n)\n\n// Version returns the package name (and OpenAPI version).\nfunc Version() string {\n\treturn \"openapi_v2\"\n}\n\n// NewAdditionalPropertiesItem creates an object of type AdditionalPropertiesItem if possible, returning an error if not.\nfunc NewAdditionalPropertiesItem(in *yaml.Node, context *compiler.Context) (*AdditionalPropertiesItem, error) {\n\terrors := make([]error, 0)\n\tx := &AdditionalPropertiesItem{}\n\tmatched := false\n\t// Schema schema = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewSchema(m, compiler.NewContext(\"schema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &AdditionalPropertiesItem_Schema{Schema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// bool boolean = 2;\n\tboolValue, ok := compiler.BoolForScalarNode(in)\n\tif ok {\n\t\tx.Oneof = &AdditionalPropertiesItem_Boolean{Boolean: boolValue}\n\t\tmatched = true\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid AdditionalPropertiesItem\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewAny creates an object of type Any if possible, returning an error if not.\nfunc NewAny(in *yaml.Node, context *compiler.Context) (*Any, error) {\n\terrors := make([]error, 0)\n\tx := &Any{}\n\tbytes := compiler.Marshal(in)\n\tx.Yaml = string(bytes)\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewApiKeySecurity creates an object of type ApiKeySecurity if possible, returning an error if not.\nfunc NewApiKeySecurity(in *yaml.Node, context *compiler.Context) (*ApiKeySecurity, error) {\n\terrors := make([]error, 0)\n\tx := &ApiKeySecurity{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"in\", \"name\", \"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"in\", \"name\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [apiKey]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"apiKey\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string name = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"name\")\n\t\tif v2 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"in\")\n\t\tif v3 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [header query]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"header\", \"query\"}, x.In) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"description\")\n\t\tif v4 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 5;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewBasicAuthenticationSecurity creates an object of type BasicAuthenticationSecurity if possible, returning an error if not.\nfunc NewBasicAuthenticationSecurity(in *yaml.Node, context *compiler.Context) (*BasicAuthenticationSecurity, error) {\n\terrors := make([]error, 0)\n\tx := &BasicAuthenticationSecurity{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [basic]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"basic\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 3;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewBodyParameter creates an object of type BodyParameter if possible, returning an error if not.\nfunc NewBodyParameter(in *yaml.Node, context *compiler.Context) (*BodyParameter, error) {\n\terrors := make([]error, 0)\n\tx := &BodyParameter{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"in\", \"name\", \"schema\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"in\", \"name\", \"required\", \"schema\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string description = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"description\")\n\t\tif v1 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string name = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"name\")\n\t\tif v2 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"in\")\n\t\tif v3 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [body]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"body\"}, x.In) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool required = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"required\")\n\t\tif v4 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Schema schema = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"schema\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Schema, err = NewSchema(v5, compiler.NewContext(\"schema\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 6;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewContact creates an object of type Contact if possible, returning an error if not.\nfunc NewContact(in *yaml.Node, context *compiler.Context) (*Contact, error) {\n\terrors := make([]error, 0)\n\tx := &Contact{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"email\", \"name\", \"url\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string url = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"url\")\n\t\tif v2 != nil {\n\t\t\tx.Url, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for url: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string email = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"email\")\n\t\tif v3 != nil {\n\t\t\tx.Email, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for email: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 4;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewDefault creates an object of type Default if possible, returning an error if not.\nfunc NewDefault(in *yaml.Node, context *compiler.Context) (*Default, error) {\n\terrors := make([]error, 0)\n\tx := &Default{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedAny additional_properties = 1;\n\t\t// MAP: Any\n\t\tx.AdditionalProperties = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedAny{}\n\t\t\t\tpair.Name = k\n\t\t\t\tresult := &Any{}\n\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\tif handled {\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewDefinitions creates an object of type Definitions if possible, returning an error if not.\nfunc NewDefinitions(in *yaml.Node, context *compiler.Context) (*Definitions, error) {\n\terrors := make([]error, 0)\n\tx := &Definitions{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedSchema additional_properties = 1;\n\t\t// MAP: Schema\n\t\tx.AdditionalProperties = make([]*NamedSchema, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedSchema{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewSchema(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewDocument creates an object of type Document if possible, returning an error if not.\nfunc NewDocument(in *yaml.Node, context *compiler.Context) (*Document, error) {\n\terrors := make([]error, 0)\n\tx := &Document{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"info\", \"paths\", \"swagger\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"basePath\", \"consumes\", \"definitions\", \"externalDocs\", \"host\", \"info\", \"parameters\", \"paths\", \"produces\", \"responses\", \"schemes\", \"security\", \"securityDefinitions\", \"swagger\", \"tags\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string swagger = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"swagger\")\n\t\tif v1 != nil {\n\t\t\tx.Swagger, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for swagger: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [2.0]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"2.0\"}, x.Swagger) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for swagger: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Info info = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"info\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Info, err = NewInfo(v2, compiler.NewContext(\"info\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string host = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"host\")\n\t\tif v3 != nil {\n\t\t\tx.Host, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for host: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string base_path = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"basePath\")\n\t\tif v4 != nil {\n\t\t\tx.BasePath, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for basePath: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated string schemes = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"schemes\")\n\t\tif v5 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v5)\n\t\t\tif ok {\n\t\t\t\tx.Schemes = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for schemes: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [http https ws wss]\n\t\t\tif ok && !compiler.StringArrayContainsValues([]string{\"http\", \"https\", \"ws\", \"wss\"}, x.Schemes) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for schemes: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated string consumes = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"consumes\")\n\t\tif v6 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v6)\n\t\t\tif ok {\n\t\t\t\tx.Consumes = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for consumes: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated string produces = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"produces\")\n\t\tif v7 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v7)\n\t\t\tif ok {\n\t\t\t\tx.Produces = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for produces: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Paths paths = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"paths\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Paths, err = NewPaths(v8, compiler.NewContext(\"paths\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Definitions definitions = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"definitions\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Definitions, err = NewDefinitions(v9, compiler.NewContext(\"definitions\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ParameterDefinitions parameters = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"parameters\")\n\t\tif v10 != nil {\n\t\t\tvar err error\n\t\t\tx.Parameters, err = NewParameterDefinitions(v10, compiler.NewContext(\"parameters\", v10, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ResponseDefinitions responses = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"responses\")\n\t\tif v11 != nil {\n\t\t\tvar err error\n\t\t\tx.Responses, err = NewResponseDefinitions(v11, compiler.NewContext(\"responses\", v11, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated SecurityRequirement security = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"security\")\n\t\tif v12 != nil {\n\t\t\t// repeated SecurityRequirement\n\t\t\tx.Security = make([]*SecurityRequirement, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v12)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSecurityRequirement(item, compiler.NewContext(\"security\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Security = append(x.Security, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// SecurityDefinitions security_definitions = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"securityDefinitions\")\n\t\tif v13 != nil {\n\t\t\tvar err error\n\t\t\tx.SecurityDefinitions, err = NewSecurityDefinitions(v13, compiler.NewContext(\"securityDefinitions\", v13, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated Tag tags = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"tags\")\n\t\tif v14 != nil {\n\t\t\t// repeated Tag\n\t\t\tx.Tags = make([]*Tag, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v14)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewTag(item, compiler.NewContext(\"tags\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Tags = append(x.Tags, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v15 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v15, compiler.NewContext(\"externalDocs\", v15, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 16;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewExamples creates an object of type Examples if possible, returning an error if not.\nfunc NewExamples(in *yaml.Node, context *compiler.Context) (*Examples, error) {\n\terrors := make([]error, 0)\n\tx := &Examples{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedAny additional_properties = 1;\n\t\t// MAP: Any\n\t\tx.AdditionalProperties = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedAny{}\n\t\t\t\tpair.Name = k\n\t\t\t\tresult := &Any{}\n\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\tif handled {\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewExternalDocs creates an object of type ExternalDocs if possible, returning an error if not.\nfunc NewExternalDocs(in *yaml.Node, context *compiler.Context) (*ExternalDocs, error) {\n\terrors := make([]error, 0)\n\tx := &ExternalDocs{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"url\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"url\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string description = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"description\")\n\t\tif v1 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string url = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"url\")\n\t\tif v2 != nil {\n\t\t\tx.Url, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for url: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 3;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewFileSchema creates an object of type FileSchema if possible, returning an error if not.\nfunc NewFileSchema(in *yaml.Node, context *compiler.Context) (*FileSchema, error) {\n\terrors := make([]error, 0)\n\tx := &FileSchema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"default\", \"description\", \"example\", \"externalDocs\", \"format\", \"readOnly\", \"required\", \"title\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string format = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"format\")\n\t\tif v1 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string title = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"title\")\n\t\tif v2 != nil {\n\t\t\tx.Title, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for title: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"default\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v4, compiler.NewContext(\"default\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated string required = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"required\")\n\t\tif v5 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v5)\n\t\t\tif ok {\n\t\t\t\tx.Required = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string type = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"type\")\n\t\tif v6 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [file]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"file\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool read_only = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"readOnly\")\n\t\tif v7 != nil {\n\t\t\tx.ReadOnly, ok = compiler.BoolForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for readOnly: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v8, compiler.NewContext(\"externalDocs\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Any example = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"example\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Example, err = NewAny(v9, compiler.NewContext(\"example\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 10;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewFormDataParameterSubSchema creates an object of type FormDataParameterSubSchema if possible, returning an error if not.\nfunc NewFormDataParameterSubSchema(in *yaml.Node, context *compiler.Context) (*FormDataParameterSubSchema, error) {\n\terrors := make([]error, 0)\n\tx := &FormDataParameterSubSchema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"allowEmptyValue\", \"collectionFormat\", \"default\", \"description\", \"enum\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"format\", \"in\", \"items\", \"maxItems\", \"maxLength\", \"maximum\", \"minItems\", \"minLength\", \"minimum\", \"multipleOf\", \"name\", \"pattern\", \"required\", \"type\", \"uniqueItems\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// bool required = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"required\")\n\t\tif v1 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"in\")\n\t\tif v2 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [formData]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"formData\"}, x.In) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string name = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"name\")\n\t\tif v4 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool allow_empty_value = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"allowEmptyValue\")\n\t\tif v5 != nil {\n\t\t\tx.AllowEmptyValue, ok = compiler.BoolForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for allowEmptyValue: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string type = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"type\")\n\t\tif v6 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [string number boolean integer array file]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"string\", \"number\", \"boolean\", \"integer\", \"array\", \"file\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"format\")\n\t\tif v7 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PrimitivesItems items = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"items\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewPrimitivesItems(v8, compiler.NewContext(\"items\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string collection_format = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"collectionFormat\")\n\t\tif v9 != nil {\n\t\t\tx.CollectionFormat, ok = compiler.StringForScalarNode(v9)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [csv ssv tsv pipes multi]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"csv\", \"ssv\", \"tsv\", \"pipes\", \"multi\"}, x.CollectionFormat) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"default\")\n\t\tif v10 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v10, compiler.NewContext(\"default\", v10, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// float maximum = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v11 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v11)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v12 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v12)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v13 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v13)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v14 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v14)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v15 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v15)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v16 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v16)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v16))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v17 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v17)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 18;\n\t\tv18 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v18 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v18)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v18))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 19;\n\t\tv19 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v19 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v19)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v19))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 20;\n\t\tv20 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v20 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v20)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v20))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 21;\n\t\tv21 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v21 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v21)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 22;\n\t\tv22 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v22 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v22)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v22))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 23;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewHeader creates an object of type Header if possible, returning an error if not.\nfunc NewHeader(in *yaml.Node, context *compiler.Context) (*Header, error) {\n\terrors := make([]error, 0)\n\tx := &Header{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"collectionFormat\", \"default\", \"description\", \"enum\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"format\", \"items\", \"maxItems\", \"maxLength\", \"maximum\", \"minItems\", \"minLength\", \"minimum\", \"multipleOf\", \"pattern\", \"type\", \"uniqueItems\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [string number integer boolean array]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"string\", \"number\", \"integer\", \"boolean\", \"array\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"format\")\n\t\tif v2 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PrimitivesItems items = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"items\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewPrimitivesItems(v3, compiler.NewContext(\"items\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string collection_format = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"collectionFormat\")\n\t\tif v4 != nil {\n\t\t\tx.CollectionFormat, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [csv ssv tsv pipes]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"csv\", \"ssv\", \"tsv\", \"pipes\"}, x.CollectionFormat) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"default\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v5, compiler.NewContext(\"default\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// float maximum = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v6 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v6)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v7 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v8 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v8)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v9 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v9)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v10 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v10)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v11 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v11)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v12 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v12)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v13 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v13)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v14 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v14)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v15 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v15)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v16 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v16)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v17 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v17)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 18;\n\t\tv18 := compiler.MapValueForKey(m, \"description\")\n\t\tif v18 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v18)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v18))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 19;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewHeaderParameterSubSchema creates an object of type HeaderParameterSubSchema if possible, returning an error if not.\nfunc NewHeaderParameterSubSchema(in *yaml.Node, context *compiler.Context) (*HeaderParameterSubSchema, error) {\n\terrors := make([]error, 0)\n\tx := &HeaderParameterSubSchema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"collectionFormat\", \"default\", \"description\", \"enum\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"format\", \"in\", \"items\", \"maxItems\", \"maxLength\", \"maximum\", \"minItems\", \"minLength\", \"minimum\", \"multipleOf\", \"name\", \"pattern\", \"required\", \"type\", \"uniqueItems\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// bool required = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"required\")\n\t\tif v1 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"in\")\n\t\tif v2 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [header]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"header\"}, x.In) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string name = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"name\")\n\t\tif v4 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string type = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"type\")\n\t\tif v5 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [string number boolean integer array]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"string\", \"number\", \"boolean\", \"integer\", \"array\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"format\")\n\t\tif v6 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PrimitivesItems items = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"items\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewPrimitivesItems(v7, compiler.NewContext(\"items\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string collection_format = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"collectionFormat\")\n\t\tif v8 != nil {\n\t\t\tx.CollectionFormat, ok = compiler.StringForScalarNode(v8)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [csv ssv tsv pipes]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"csv\", \"ssv\", \"tsv\", \"pipes\"}, x.CollectionFormat) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"default\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v9, compiler.NewContext(\"default\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// float maximum = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v10 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v10)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v11 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v11)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v12 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v12)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v13 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v13)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v14 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v14)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v15 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v15)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v16 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v16)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v16))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v17 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v17)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 18;\n\t\tv18 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v18 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v18)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v18))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 19;\n\t\tv19 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v19 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v19)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v19))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 20;\n\t\tv20 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v20 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v20)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 21;\n\t\tv21 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v21 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v21)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v21))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 22;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewHeaders creates an object of type Headers if possible, returning an error if not.\nfunc NewHeaders(in *yaml.Node, context *compiler.Context) (*Headers, error) {\n\terrors := make([]error, 0)\n\tx := &Headers{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedHeader additional_properties = 1;\n\t\t// MAP: Header\n\t\tx.AdditionalProperties = make([]*NamedHeader, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedHeader{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewHeader(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewInfo creates an object of type Info if possible, returning an error if not.\nfunc NewInfo(in *yaml.Node, context *compiler.Context) (*Info, error) {\n\terrors := make([]error, 0)\n\tx := &Info{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"title\", \"version\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"contact\", \"description\", \"license\", \"termsOfService\", \"title\", \"version\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string title = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"title\")\n\t\tif v1 != nil {\n\t\t\tx.Title, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for title: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string version = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"version\")\n\t\tif v2 != nil {\n\t\t\tx.Version, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for version: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string terms_of_service = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"termsOfService\")\n\t\tif v4 != nil {\n\t\t\tx.TermsOfService, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for termsOfService: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Contact contact = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"contact\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Contact, err = NewContact(v5, compiler.NewContext(\"contact\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// License license = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"license\")\n\t\tif v6 != nil {\n\t\t\tvar err error\n\t\t\tx.License, err = NewLicense(v6, compiler.NewContext(\"license\", v6, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 7;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewItemsItem creates an object of type ItemsItem if possible, returning an error if not.\nfunc NewItemsItem(in *yaml.Node, context *compiler.Context) (*ItemsItem, error) {\n\terrors := make([]error, 0)\n\tx := &ItemsItem{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value for item array: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tx.Schema = make([]*Schema, 0)\n\t\ty, err := NewSchema(m, compiler.NewContext(\"<array>\", m, context))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tx.Schema = append(x.Schema, y)\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewJsonReference creates an object of type JsonReference if possible, returning an error if not.\nfunc NewJsonReference(in *yaml.Node, context *compiler.Context) (*JsonReference, error) {\n\terrors := make([]error, 0)\n\tx := &JsonReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"$ref\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string _ref = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"$ref\")\n\t\tif v1 != nil {\n\t\t\tx.XRef, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for $ref: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewLicense creates an object of type License if possible, returning an error if not.\nfunc NewLicense(in *yaml.Node, context *compiler.Context) (*License, error) {\n\terrors := make([]error, 0)\n\tx := &License{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"name\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"name\", \"url\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string url = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"url\")\n\t\tif v2 != nil {\n\t\t\tx.Url, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for url: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 3;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedAny creates an object of type NamedAny if possible, returning an error if not.\nfunc NewNamedAny(in *yaml.Node, context *compiler.Context) (*NamedAny, error) {\n\terrors := make([]error, 0)\n\tx := &NamedAny{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewAny(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedHeader creates an object of type NamedHeader if possible, returning an error if not.\nfunc NewNamedHeader(in *yaml.Node, context *compiler.Context) (*NamedHeader, error) {\n\terrors := make([]error, 0)\n\tx := &NamedHeader{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Header value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewHeader(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedParameter creates an object of type NamedParameter if possible, returning an error if not.\nfunc NewNamedParameter(in *yaml.Node, context *compiler.Context) (*NamedParameter, error) {\n\terrors := make([]error, 0)\n\tx := &NamedParameter{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Parameter value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewParameter(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedPathItem creates an object of type NamedPathItem if possible, returning an error if not.\nfunc NewNamedPathItem(in *yaml.Node, context *compiler.Context) (*NamedPathItem, error) {\n\terrors := make([]error, 0)\n\tx := &NamedPathItem{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PathItem value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewPathItem(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedResponse creates an object of type NamedResponse if possible, returning an error if not.\nfunc NewNamedResponse(in *yaml.Node, context *compiler.Context) (*NamedResponse, error) {\n\terrors := make([]error, 0)\n\tx := &NamedResponse{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Response value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewResponse(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedResponseValue creates an object of type NamedResponseValue if possible, returning an error if not.\nfunc NewNamedResponseValue(in *yaml.Node, context *compiler.Context) (*NamedResponseValue, error) {\n\terrors := make([]error, 0)\n\tx := &NamedResponseValue{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ResponseValue value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewResponseValue(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedSchema creates an object of type NamedSchema if possible, returning an error if not.\nfunc NewNamedSchema(in *yaml.Node, context *compiler.Context) (*NamedSchema, error) {\n\terrors := make([]error, 0)\n\tx := &NamedSchema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Schema value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewSchema(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedSecurityDefinitionsItem creates an object of type NamedSecurityDefinitionsItem if possible, returning an error if not.\nfunc NewNamedSecurityDefinitionsItem(in *yaml.Node, context *compiler.Context) (*NamedSecurityDefinitionsItem, error) {\n\terrors := make([]error, 0)\n\tx := &NamedSecurityDefinitionsItem{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// SecurityDefinitionsItem value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewSecurityDefinitionsItem(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedString creates an object of type NamedString if possible, returning an error if not.\nfunc NewNamedString(in *yaml.Node, context *compiler.Context) (*NamedString, error) {\n\terrors := make([]error, 0)\n\tx := &NamedString{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tx.Value, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for value: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedStringArray creates an object of type NamedStringArray if possible, returning an error if not.\nfunc NewNamedStringArray(in *yaml.Node, context *compiler.Context) (*NamedStringArray, error) {\n\terrors := make([]error, 0)\n\tx := &NamedStringArray{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// StringArray value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewStringArray(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNonBodyParameter creates an object of type NonBodyParameter if possible, returning an error if not.\nfunc NewNonBodyParameter(in *yaml.Node, context *compiler.Context) (*NonBodyParameter, error) {\n\terrors := make([]error, 0)\n\tx := &NonBodyParameter{}\n\tmatched := false\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"in\", \"name\", \"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// HeaderParameterSubSchema header_parameter_sub_schema = 1;\n\t\t{\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewHeaderParameterSubSchema(m, compiler.NewContext(\"headerParameterSubSchema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &NonBodyParameter_HeaderParameterSubSchema{HeaderParameterSubSchema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t\t// FormDataParameterSubSchema form_data_parameter_sub_schema = 2;\n\t\t{\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewFormDataParameterSubSchema(m, compiler.NewContext(\"formDataParameterSubSchema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &NonBodyParameter_FormDataParameterSubSchema{FormDataParameterSubSchema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t\t// QueryParameterSubSchema query_parameter_sub_schema = 3;\n\t\t{\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewQueryParameterSubSchema(m, compiler.NewContext(\"queryParameterSubSchema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &NonBodyParameter_QueryParameterSubSchema{QueryParameterSubSchema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t\t// PathParameterSubSchema path_parameter_sub_schema = 4;\n\t\t{\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewPathParameterSubSchema(m, compiler.NewContext(\"pathParameterSubSchema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &NonBodyParameter_PathParameterSubSchema{PathParameterSubSchema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid NonBodyParameter\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOauth2AccessCodeSecurity creates an object of type Oauth2AccessCodeSecurity if possible, returning an error if not.\nfunc NewOauth2AccessCodeSecurity(in *yaml.Node, context *compiler.Context) (*Oauth2AccessCodeSecurity, error) {\n\terrors := make([]error, 0)\n\tx := &Oauth2AccessCodeSecurity{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"authorizationUrl\", \"flow\", \"tokenUrl\", \"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"authorizationUrl\", \"description\", \"flow\", \"scopes\", \"tokenUrl\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [oauth2]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"oauth2\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string flow = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"flow\")\n\t\tif v2 != nil {\n\t\t\tx.Flow, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [accessCode]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"accessCode\"}, x.Flow) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Oauth2Scopes scopes = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"scopes\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext(\"scopes\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string authorization_url = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"authorizationUrl\")\n\t\tif v4 != nil {\n\t\t\tx.AuthorizationUrl, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for authorizationUrl: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string token_url = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"tokenUrl\")\n\t\tif v5 != nil {\n\t\t\tx.TokenUrl, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for tokenUrl: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"description\")\n\t\tif v6 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 7;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOauth2ApplicationSecurity creates an object of type Oauth2ApplicationSecurity if possible, returning an error if not.\nfunc NewOauth2ApplicationSecurity(in *yaml.Node, context *compiler.Context) (*Oauth2ApplicationSecurity, error) {\n\terrors := make([]error, 0)\n\tx := &Oauth2ApplicationSecurity{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"flow\", \"tokenUrl\", \"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"flow\", \"scopes\", \"tokenUrl\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [oauth2]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"oauth2\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string flow = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"flow\")\n\t\tif v2 != nil {\n\t\t\tx.Flow, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [application]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"application\"}, x.Flow) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Oauth2Scopes scopes = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"scopes\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext(\"scopes\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string token_url = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"tokenUrl\")\n\t\tif v4 != nil {\n\t\t\tx.TokenUrl, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for tokenUrl: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"description\")\n\t\tif v5 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 6;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOauth2ImplicitSecurity creates an object of type Oauth2ImplicitSecurity if possible, returning an error if not.\nfunc NewOauth2ImplicitSecurity(in *yaml.Node, context *compiler.Context) (*Oauth2ImplicitSecurity, error) {\n\terrors := make([]error, 0)\n\tx := &Oauth2ImplicitSecurity{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"authorizationUrl\", \"flow\", \"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"authorizationUrl\", \"description\", \"flow\", \"scopes\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [oauth2]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"oauth2\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string flow = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"flow\")\n\t\tif v2 != nil {\n\t\t\tx.Flow, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [implicit]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"implicit\"}, x.Flow) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Oauth2Scopes scopes = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"scopes\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext(\"scopes\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string authorization_url = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"authorizationUrl\")\n\t\tif v4 != nil {\n\t\t\tx.AuthorizationUrl, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for authorizationUrl: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"description\")\n\t\tif v5 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 6;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOauth2PasswordSecurity creates an object of type Oauth2PasswordSecurity if possible, returning an error if not.\nfunc NewOauth2PasswordSecurity(in *yaml.Node, context *compiler.Context) (*Oauth2PasswordSecurity, error) {\n\terrors := make([]error, 0)\n\tx := &Oauth2PasswordSecurity{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"flow\", \"tokenUrl\", \"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"flow\", \"scopes\", \"tokenUrl\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [oauth2]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"oauth2\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string flow = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"flow\")\n\t\tif v2 != nil {\n\t\t\tx.Flow, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [password]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"password\"}, x.Flow) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for flow: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Oauth2Scopes scopes = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"scopes\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Scopes, err = NewOauth2Scopes(v3, compiler.NewContext(\"scopes\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string token_url = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"tokenUrl\")\n\t\tif v4 != nil {\n\t\t\tx.TokenUrl, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for tokenUrl: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"description\")\n\t\tif v5 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 6;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOauth2Scopes creates an object of type Oauth2Scopes if possible, returning an error if not.\nfunc NewOauth2Scopes(in *yaml.Node, context *compiler.Context) (*Oauth2Scopes, error) {\n\terrors := make([]error, 0)\n\tx := &Oauth2Scopes{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedString additional_properties = 1;\n\t\t// MAP: string\n\t\tx.AdditionalProperties = make([]*NamedString, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedString{}\n\t\t\t\tpair.Name = k\n\t\t\t\tpair.Value, _ = compiler.StringForScalarNode(v)\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOperation creates an object of type Operation if possible, returning an error if not.\nfunc NewOperation(in *yaml.Node, context *compiler.Context) (*Operation, error) {\n\terrors := make([]error, 0)\n\tx := &Operation{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"responses\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"consumes\", \"deprecated\", \"description\", \"externalDocs\", \"operationId\", \"parameters\", \"produces\", \"responses\", \"schemes\", \"security\", \"summary\", \"tags\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// repeated string tags = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"tags\")\n\t\tif v1 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v1)\n\t\t\tif ok {\n\t\t\t\tx.Tags = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for tags: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string summary = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"summary\")\n\t\tif v2 != nil {\n\t\t\tx.Summary, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for summary: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v4, compiler.NewContext(\"externalDocs\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string operation_id = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"operationId\")\n\t\tif v5 != nil {\n\t\t\tx.OperationId, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for operationId: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated string produces = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"produces\")\n\t\tif v6 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v6)\n\t\t\tif ok {\n\t\t\t\tx.Produces = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for produces: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated string consumes = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"consumes\")\n\t\tif v7 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v7)\n\t\t\tif ok {\n\t\t\t\tx.Consumes = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for consumes: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated ParametersItem parameters = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"parameters\")\n\t\tif v8 != nil {\n\t\t\t// repeated ParametersItem\n\t\t\tx.Parameters = make([]*ParametersItem, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v8)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewParametersItem(item, compiler.NewContext(\"parameters\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Parameters = append(x.Parameters, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Responses responses = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"responses\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Responses, err = NewResponses(v9, compiler.NewContext(\"responses\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated string schemes = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"schemes\")\n\t\tif v10 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v10)\n\t\t\tif ok {\n\t\t\t\tx.Schemes = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for schemes: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [http https ws wss]\n\t\t\tif ok && !compiler.StringArrayContainsValues([]string{\"http\", \"https\", \"ws\", \"wss\"}, x.Schemes) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for schemes: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool deprecated = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"deprecated\")\n\t\tif v11 != nil {\n\t\t\tx.Deprecated, ok = compiler.BoolForScalarNode(v11)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for deprecated: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated SecurityRequirement security = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"security\")\n\t\tif v12 != nil {\n\t\t\t// repeated SecurityRequirement\n\t\t\tx.Security = make([]*SecurityRequirement, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v12)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSecurityRequirement(item, compiler.NewContext(\"security\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Security = append(x.Security, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 13;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewParameter creates an object of type Parameter if possible, returning an error if not.\nfunc NewParameter(in *yaml.Node, context *compiler.Context) (*Parameter, error) {\n\terrors := make([]error, 0)\n\tx := &Parameter{}\n\tmatched := false\n\t// BodyParameter body_parameter = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewBodyParameter(m, compiler.NewContext(\"bodyParameter\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &Parameter_BodyParameter{BodyParameter: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// NonBodyParameter non_body_parameter = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewNonBodyParameter(m, compiler.NewContext(\"nonBodyParameter\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &Parameter_NonBodyParameter{NonBodyParameter: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid Parameter\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewParameterDefinitions creates an object of type ParameterDefinitions if possible, returning an error if not.\nfunc NewParameterDefinitions(in *yaml.Node, context *compiler.Context) (*ParameterDefinitions, error) {\n\terrors := make([]error, 0)\n\tx := &ParameterDefinitions{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedParameter additional_properties = 1;\n\t\t// MAP: Parameter\n\t\tx.AdditionalProperties = make([]*NamedParameter, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedParameter{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewParameter(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewParametersItem creates an object of type ParametersItem if possible, returning an error if not.\nfunc NewParametersItem(in *yaml.Node, context *compiler.Context) (*ParametersItem, error) {\n\terrors := make([]error, 0)\n\tx := &ParametersItem{}\n\tmatched := false\n\t// Parameter parameter = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewParameter(m, compiler.NewContext(\"parameter\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ParametersItem_Parameter{Parameter: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// JsonReference json_reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewJsonReference(m, compiler.NewContext(\"jsonReference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ParametersItem_JsonReference{JsonReference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid ParametersItem\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewPathItem creates an object of type PathItem if possible, returning an error if not.\nfunc NewPathItem(in *yaml.Node, context *compiler.Context) (*PathItem, error) {\n\terrors := make([]error, 0)\n\tx := &PathItem{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"$ref\", \"delete\", \"get\", \"head\", \"options\", \"parameters\", \"patch\", \"post\", \"put\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string _ref = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"$ref\")\n\t\tif v1 != nil {\n\t\t\tx.XRef, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for $ref: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Operation get = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"get\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Get, err = NewOperation(v2, compiler.NewContext(\"get\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation put = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"put\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Put, err = NewOperation(v3, compiler.NewContext(\"put\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation post = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"post\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Post, err = NewOperation(v4, compiler.NewContext(\"post\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation delete = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"delete\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Delete, err = NewOperation(v5, compiler.NewContext(\"delete\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation options = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"options\")\n\t\tif v6 != nil {\n\t\t\tvar err error\n\t\t\tx.Options, err = NewOperation(v6, compiler.NewContext(\"options\", v6, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation head = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"head\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.Head, err = NewOperation(v7, compiler.NewContext(\"head\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation patch = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"patch\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Patch, err = NewOperation(v8, compiler.NewContext(\"patch\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated ParametersItem parameters = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"parameters\")\n\t\tif v9 != nil {\n\t\t\t// repeated ParametersItem\n\t\t\tx.Parameters = make([]*ParametersItem, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v9)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewParametersItem(item, compiler.NewContext(\"parameters\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Parameters = append(x.Parameters, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 10;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewPathParameterSubSchema creates an object of type PathParameterSubSchema if possible, returning an error if not.\nfunc NewPathParameterSubSchema(in *yaml.Node, context *compiler.Context) (*PathParameterSubSchema, error) {\n\terrors := make([]error, 0)\n\tx := &PathParameterSubSchema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"required\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"collectionFormat\", \"default\", \"description\", \"enum\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"format\", \"in\", \"items\", \"maxItems\", \"maxLength\", \"maximum\", \"minItems\", \"minLength\", \"minimum\", \"multipleOf\", \"name\", \"pattern\", \"required\", \"type\", \"uniqueItems\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// bool required = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"required\")\n\t\tif v1 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"in\")\n\t\tif v2 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [path]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"path\"}, x.In) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string name = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"name\")\n\t\tif v4 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string type = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"type\")\n\t\tif v5 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [string number boolean integer array]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"string\", \"number\", \"boolean\", \"integer\", \"array\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"format\")\n\t\tif v6 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PrimitivesItems items = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"items\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewPrimitivesItems(v7, compiler.NewContext(\"items\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string collection_format = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"collectionFormat\")\n\t\tif v8 != nil {\n\t\t\tx.CollectionFormat, ok = compiler.StringForScalarNode(v8)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [csv ssv tsv pipes]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"csv\", \"ssv\", \"tsv\", \"pipes\"}, x.CollectionFormat) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"default\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v9, compiler.NewContext(\"default\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// float maximum = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v10 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v10)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v11 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v11)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v12 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v12)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v13 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v13)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v14 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v14)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v15 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v15)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v16 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v16)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v16))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v17 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v17)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 18;\n\t\tv18 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v18 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v18)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v18))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 19;\n\t\tv19 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v19 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v19)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v19))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 20;\n\t\tv20 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v20 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v20)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 21;\n\t\tv21 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v21 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v21)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v21))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 22;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewPaths creates an object of type Paths if possible, returning an error if not.\nfunc NewPaths(in *yaml.Node, context *compiler.Context) (*Paths, error) {\n\terrors := make([]error, 0)\n\tx := &Paths{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0, pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 1;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedPathItem path = 2;\n\t\t// MAP: PathItem ^/\n\t\tx.Path = make([]*NamedPathItem, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"/\") {\n\t\t\t\t\tpair := &NamedPathItem{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tvar err error\n\t\t\t\t\tpair.Value, err = NewPathItem(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Path = append(x.Path, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewPrimitivesItems creates an object of type PrimitivesItems if possible, returning an error if not.\nfunc NewPrimitivesItems(in *yaml.Node, context *compiler.Context) (*PrimitivesItems, error) {\n\terrors := make([]error, 0)\n\tx := &PrimitivesItems{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"collectionFormat\", \"default\", \"enum\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"format\", \"items\", \"maxItems\", \"maxLength\", \"maximum\", \"minItems\", \"minLength\", \"minimum\", \"multipleOf\", \"pattern\", \"type\", \"uniqueItems\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [string number integer boolean array]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"string\", \"number\", \"integer\", \"boolean\", \"array\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"format\")\n\t\tif v2 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PrimitivesItems items = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"items\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewPrimitivesItems(v3, compiler.NewContext(\"items\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string collection_format = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"collectionFormat\")\n\t\tif v4 != nil {\n\t\t\tx.CollectionFormat, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [csv ssv tsv pipes]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"csv\", \"ssv\", \"tsv\", \"pipes\"}, x.CollectionFormat) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"default\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v5, compiler.NewContext(\"default\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// float maximum = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v6 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v6)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v7 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v8 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v8)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v9 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v9)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v10 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v10)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v11 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v11)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v12 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v12)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v13 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v13)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v14 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v14)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v15 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v15)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v16 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v16)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v17 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v17)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 18;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewProperties creates an object of type Properties if possible, returning an error if not.\nfunc NewProperties(in *yaml.Node, context *compiler.Context) (*Properties, error) {\n\terrors := make([]error, 0)\n\tx := &Properties{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedSchema additional_properties = 1;\n\t\t// MAP: Schema\n\t\tx.AdditionalProperties = make([]*NamedSchema, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedSchema{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewSchema(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewQueryParameterSubSchema creates an object of type QueryParameterSubSchema if possible, returning an error if not.\nfunc NewQueryParameterSubSchema(in *yaml.Node, context *compiler.Context) (*QueryParameterSubSchema, error) {\n\terrors := make([]error, 0)\n\tx := &QueryParameterSubSchema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"allowEmptyValue\", \"collectionFormat\", \"default\", \"description\", \"enum\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"format\", \"in\", \"items\", \"maxItems\", \"maxLength\", \"maximum\", \"minItems\", \"minLength\", \"minimum\", \"multipleOf\", \"name\", \"pattern\", \"required\", \"type\", \"uniqueItems\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// bool required = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"required\")\n\t\tif v1 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"in\")\n\t\tif v2 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [query]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"query\"}, x.In) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string name = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"name\")\n\t\tif v4 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool allow_empty_value = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"allowEmptyValue\")\n\t\tif v5 != nil {\n\t\t\tx.AllowEmptyValue, ok = compiler.BoolForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for allowEmptyValue: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string type = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"type\")\n\t\tif v6 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [string number boolean integer array]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"string\", \"number\", \"boolean\", \"integer\", \"array\"}, x.Type) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"format\")\n\t\tif v7 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PrimitivesItems items = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"items\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewPrimitivesItems(v8, compiler.NewContext(\"items\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string collection_format = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"collectionFormat\")\n\t\tif v9 != nil {\n\t\t\tx.CollectionFormat, ok = compiler.StringForScalarNode(v9)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t\t// check for valid enum values\n\t\t\t// [csv ssv tsv pipes multi]\n\t\t\tif ok && !compiler.StringArrayContainsValue([]string{\"csv\", \"ssv\", \"tsv\", \"pipes\", \"multi\"}, x.CollectionFormat) {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for collectionFormat: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"default\")\n\t\tif v10 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v10, compiler.NewContext(\"default\", v10, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// float maximum = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v11 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v11)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v12 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v12)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v13 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v13)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v14 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v14)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v15 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v15)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v16 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v16)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v16))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v17 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v17)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 18;\n\t\tv18 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v18 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v18)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v18))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 19;\n\t\tv19 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v19 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v19)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v19))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 20;\n\t\tv20 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v20 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v20)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v20))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 21;\n\t\tv21 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v21 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v21)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 22;\n\t\tv22 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v22 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v22)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v22))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 23;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponse creates an object of type Response if possible, returning an error if not.\nfunc NewResponse(in *yaml.Node, context *compiler.Context) (*Response, error) {\n\terrors := make([]error, 0)\n\tx := &Response{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"description\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"examples\", \"headers\", \"schema\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string description = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"description\")\n\t\tif v1 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// SchemaItem schema = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"schema\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Schema, err = NewSchemaItem(v2, compiler.NewContext(\"schema\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Headers headers = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"headers\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Headers, err = NewHeaders(v3, compiler.NewContext(\"headers\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Examples examples = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"examples\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Examples, err = NewExamples(v4, compiler.NewContext(\"examples\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 5;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponseDefinitions creates an object of type ResponseDefinitions if possible, returning an error if not.\nfunc NewResponseDefinitions(in *yaml.Node, context *compiler.Context) (*ResponseDefinitions, error) {\n\terrors := make([]error, 0)\n\tx := &ResponseDefinitions{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedResponse additional_properties = 1;\n\t\t// MAP: Response\n\t\tx.AdditionalProperties = make([]*NamedResponse, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedResponse{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewResponse(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponseValue creates an object of type ResponseValue if possible, returning an error if not.\nfunc NewResponseValue(in *yaml.Node, context *compiler.Context) (*ResponseValue, error) {\n\terrors := make([]error, 0)\n\tx := &ResponseValue{}\n\tmatched := false\n\t// Response response = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewResponse(m, compiler.NewContext(\"response\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ResponseValue_Response{Response: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// JsonReference json_reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewJsonReference(m, compiler.NewContext(\"jsonReference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ResponseValue_JsonReference{JsonReference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid ResponseValue\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponses creates an object of type Responses if possible, returning an error if not.\nfunc NewResponses(in *yaml.Node, context *compiler.Context) (*Responses, error) {\n\terrors := make([]error, 0)\n\tx := &Responses{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{}\n\t\tallowedPatterns := []*regexp.Regexp{pattern2, pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// repeated NamedResponseValue response_code = 1;\n\t\t// MAP: ResponseValue ^([0-9]{3})$|^(default)$\n\t\tx.ResponseCode = make([]*NamedResponseValue, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif pattern2.MatchString(k) {\n\t\t\t\t\tpair := &NamedResponseValue{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tvar err error\n\t\t\t\t\tpair.Value, err = NewResponseValue(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.ResponseCode = append(x.ResponseCode, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 2;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSchema creates an object of type Schema if possible, returning an error if not.\nfunc NewSchema(in *yaml.Node, context *compiler.Context) (*Schema, error) {\n\terrors := make([]error, 0)\n\tx := &Schema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"$ref\", \"additionalProperties\", \"allOf\", \"default\", \"description\", \"discriminator\", \"enum\", \"example\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"externalDocs\", \"format\", \"items\", \"maxItems\", \"maxLength\", \"maxProperties\", \"maximum\", \"minItems\", \"minLength\", \"minProperties\", \"minimum\", \"multipleOf\", \"pattern\", \"properties\", \"readOnly\", \"required\", \"title\", \"type\", \"uniqueItems\", \"xml\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string _ref = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"$ref\")\n\t\tif v1 != nil {\n\t\t\tx.XRef, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for $ref: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"format\")\n\t\tif v2 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string title = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"title\")\n\t\tif v3 != nil {\n\t\t\tx.Title, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for title: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"description\")\n\t\tif v4 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any default = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"default\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewAny(v5, compiler.NewContext(\"default\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v6 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v6)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float maximum = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v7 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v7)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v8 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v8)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v9 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v9)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v10 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v10)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v11 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v11)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v12 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v12)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v13 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v13)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v14 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v14)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v15 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v15)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v16 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v16)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v16))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_properties = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"maxProperties\")\n\t\tif v17 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v17)\n\t\t\tif ok {\n\t\t\t\tx.MaxProperties = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxProperties: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_properties = 18;\n\t\tv18 := compiler.MapValueForKey(m, \"minProperties\")\n\t\tif v18 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v18)\n\t\t\tif ok {\n\t\t\t\tx.MinProperties = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minProperties: %s\", compiler.Display(v18))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated string required = 19;\n\t\tv19 := compiler.MapValueForKey(m, \"required\")\n\t\tif v19 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v19)\n\t\t\tif ok {\n\t\t\t\tx.Required = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v19))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 20;\n\t\tv20 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v20 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v20)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// AdditionalPropertiesItem additional_properties = 21;\n\t\tv21 := compiler.MapValueForKey(m, \"additionalProperties\")\n\t\tif v21 != nil {\n\t\t\tvar err error\n\t\t\tx.AdditionalProperties, err = NewAdditionalPropertiesItem(v21, compiler.NewContext(\"additionalProperties\", v21, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// TypeItem type = 22;\n\t\tv22 := compiler.MapValueForKey(m, \"type\")\n\t\tif v22 != nil {\n\t\t\tvar err error\n\t\t\tx.Type, err = NewTypeItem(v22, compiler.NewContext(\"type\", v22, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ItemsItem items = 23;\n\t\tv23 := compiler.MapValueForKey(m, \"items\")\n\t\tif v23 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewItemsItem(v23, compiler.NewContext(\"items\", v23, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated Schema all_of = 24;\n\t\tv24 := compiler.MapValueForKey(m, \"allOf\")\n\t\tif v24 != nil {\n\t\t\t// repeated Schema\n\t\t\tx.AllOf = make([]*Schema, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v24)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSchema(item, compiler.NewContext(\"allOf\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.AllOf = append(x.AllOf, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Properties properties = 25;\n\t\tv25 := compiler.MapValueForKey(m, \"properties\")\n\t\tif v25 != nil {\n\t\t\tvar err error\n\t\t\tx.Properties, err = NewProperties(v25, compiler.NewContext(\"properties\", v25, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string discriminator = 26;\n\t\tv26 := compiler.MapValueForKey(m, \"discriminator\")\n\t\tif v26 != nil {\n\t\t\tx.Discriminator, ok = compiler.StringForScalarNode(v26)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for discriminator: %s\", compiler.Display(v26))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool read_only = 27;\n\t\tv27 := compiler.MapValueForKey(m, \"readOnly\")\n\t\tif v27 != nil {\n\t\t\tx.ReadOnly, ok = compiler.BoolForScalarNode(v27)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for readOnly: %s\", compiler.Display(v27))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Xml xml = 28;\n\t\tv28 := compiler.MapValueForKey(m, \"xml\")\n\t\tif v28 != nil {\n\t\t\tvar err error\n\t\t\tx.Xml, err = NewXml(v28, compiler.NewContext(\"xml\", v28, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 29;\n\t\tv29 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v29 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v29, compiler.NewContext(\"externalDocs\", v29, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Any example = 30;\n\t\tv30 := compiler.MapValueForKey(m, \"example\")\n\t\tif v30 != nil {\n\t\t\tvar err error\n\t\t\tx.Example, err = NewAny(v30, compiler.NewContext(\"example\", v30, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 31;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSchemaItem creates an object of type SchemaItem if possible, returning an error if not.\nfunc NewSchemaItem(in *yaml.Node, context *compiler.Context) (*SchemaItem, error) {\n\terrors := make([]error, 0)\n\tx := &SchemaItem{}\n\tmatched := false\n\t// Schema schema = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewSchema(m, compiler.NewContext(\"schema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SchemaItem_Schema{Schema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// FileSchema file_schema = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewFileSchema(m, compiler.NewContext(\"fileSchema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SchemaItem_FileSchema{FileSchema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid SchemaItem\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSecurityDefinitions creates an object of type SecurityDefinitions if possible, returning an error if not.\nfunc NewSecurityDefinitions(in *yaml.Node, context *compiler.Context) (*SecurityDefinitions, error) {\n\terrors := make([]error, 0)\n\tx := &SecurityDefinitions{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedSecurityDefinitionsItem additional_properties = 1;\n\t\t// MAP: SecurityDefinitionsItem\n\t\tx.AdditionalProperties = make([]*NamedSecurityDefinitionsItem, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedSecurityDefinitionsItem{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewSecurityDefinitionsItem(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSecurityDefinitionsItem creates an object of type SecurityDefinitionsItem if possible, returning an error if not.\nfunc NewSecurityDefinitionsItem(in *yaml.Node, context *compiler.Context) (*SecurityDefinitionsItem, error) {\n\terrors := make([]error, 0)\n\tx := &SecurityDefinitionsItem{}\n\tmatched := false\n\t// BasicAuthenticationSecurity basic_authentication_security = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewBasicAuthenticationSecurity(m, compiler.NewContext(\"basicAuthenticationSecurity\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecurityDefinitionsItem_BasicAuthenticationSecurity{BasicAuthenticationSecurity: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// ApiKeySecurity api_key_security = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewApiKeySecurity(m, compiler.NewContext(\"apiKeySecurity\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecurityDefinitionsItem_ApiKeySecurity{ApiKeySecurity: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Oauth2ImplicitSecurity oauth2_implicit_security = 3;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewOauth2ImplicitSecurity(m, compiler.NewContext(\"oauth2ImplicitSecurity\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecurityDefinitionsItem_Oauth2ImplicitSecurity{Oauth2ImplicitSecurity: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Oauth2PasswordSecurity oauth2_password_security = 4;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewOauth2PasswordSecurity(m, compiler.NewContext(\"oauth2PasswordSecurity\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecurityDefinitionsItem_Oauth2PasswordSecurity{Oauth2PasswordSecurity: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Oauth2ApplicationSecurity oauth2_application_security = 5;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewOauth2ApplicationSecurity(m, compiler.NewContext(\"oauth2ApplicationSecurity\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecurityDefinitionsItem_Oauth2ApplicationSecurity{Oauth2ApplicationSecurity: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Oauth2AccessCodeSecurity oauth2_access_code_security = 6;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewOauth2AccessCodeSecurity(m, compiler.NewContext(\"oauth2AccessCodeSecurity\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecurityDefinitionsItem_Oauth2AccessCodeSecurity{Oauth2AccessCodeSecurity: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid SecurityDefinitionsItem\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSecurityRequirement creates an object of type SecurityRequirement if possible, returning an error if not.\nfunc NewSecurityRequirement(in *yaml.Node, context *compiler.Context) (*SecurityRequirement, error) {\n\terrors := make([]error, 0)\n\tx := &SecurityRequirement{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedStringArray additional_properties = 1;\n\t\t// MAP: StringArray\n\t\tx.AdditionalProperties = make([]*NamedStringArray, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedStringArray{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewStringArray(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewStringArray creates an object of type StringArray if possible, returning an error if not.\nfunc NewStringArray(in *yaml.Node, context *compiler.Context) (*StringArray, error) {\n\terrors := make([]error, 0)\n\tx := &StringArray{}\n\tx.Value = make([]string, 0)\n\tfor _, node := range in.Content {\n\t\ts, _ := compiler.StringForScalarNode(node)\n\t\tx.Value = append(x.Value, s)\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewTag creates an object of type Tag if possible, returning an error if not.\nfunc NewTag(in *yaml.Node, context *compiler.Context) (*Tag, error) {\n\terrors := make([]error, 0)\n\tx := &Tag{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"name\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"externalDocs\", \"name\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v3, compiler.NewContext(\"externalDocs\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 4;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewTypeItem creates an object of type TypeItem if possible, returning an error if not.\nfunc NewTypeItem(in *yaml.Node, context *compiler.Context) (*TypeItem, error) {\n\terrors := make([]error, 0)\n\tx := &TypeItem{}\n\tv1 := in\n\tswitch v1.Kind {\n\tcase yaml.ScalarNode:\n\t\tx.Value = make([]string, 0)\n\t\tx.Value = append(x.Value, v1.Value)\n\tcase yaml.SequenceNode:\n\t\tx.Value = make([]string, 0)\n\t\tfor _, v := range v1.Content {\n\t\t\tvalue := v.Value\n\t\t\tok := v.Kind == yaml.ScalarNode\n\t\t\tif ok {\n\t\t\t\tx.Value = append(x.Value, value)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for string array element: %+v (%T)\", value, value)\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tmessage := fmt.Sprintf(\"has unexpected value for string array: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewVendorExtension creates an object of type VendorExtension if possible, returning an error if not.\nfunc NewVendorExtension(in *yaml.Node, context *compiler.Context) (*VendorExtension, error) {\n\terrors := make([]error, 0)\n\tx := &VendorExtension{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedAny additional_properties = 1;\n\t\t// MAP: Any\n\t\tx.AdditionalProperties = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedAny{}\n\t\t\t\tpair.Name = k\n\t\t\t\tresult := &Any{}\n\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\tif handled {\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewXml creates an object of type Xml if possible, returning an error if not.\nfunc NewXml(in *yaml.Node, context *compiler.Context) (*Xml, error) {\n\terrors := make([]error, 0)\n\tx := &Xml{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"attribute\", \"name\", \"namespace\", \"prefix\", \"wrapped\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string namespace = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"namespace\")\n\t\tif v2 != nil {\n\t\t\tx.Namespace, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for namespace: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string prefix = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"prefix\")\n\t\tif v3 != nil {\n\t\t\tx.Prefix, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for prefix: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool attribute = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"attribute\")\n\t\tif v4 != nil {\n\t\t\tx.Attribute, ok = compiler.BoolForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for attribute: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool wrapped = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"wrapped\")\n\t\tif v5 != nil {\n\t\t\tx.Wrapped, ok = compiler.BoolForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for wrapped: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny vendor_extension = 6;\n\t\t// MAP: Any ^x-\n\t\tx.VendorExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.VendorExtension = append(x.VendorExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside AdditionalPropertiesItem objects.\nfunc (m *AdditionalPropertiesItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*AdditionalPropertiesItem_Schema)\n\t\tif ok {\n\t\t\t_, err := p.Schema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Any objects.\nfunc (m *Any) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ApiKeySecurity objects.\nfunc (m *ApiKeySecurity) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside BasicAuthenticationSecurity objects.\nfunc (m *BasicAuthenticationSecurity) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside BodyParameter objects.\nfunc (m *BodyParameter) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Schema != nil {\n\t\t_, err := m.Schema.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Contact objects.\nfunc (m *Contact) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Default objects.\nfunc (m *Default) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Definitions objects.\nfunc (m *Definitions) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Document objects.\nfunc (m *Document) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Info != nil {\n\t\t_, err := m.Info.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Paths != nil {\n\t\t_, err := m.Paths.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Definitions != nil {\n\t\t_, err := m.Definitions.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Parameters != nil {\n\t\t_, err := m.Parameters.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Responses != nil {\n\t\t_, err := m.Responses.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Security {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.SecurityDefinitions != nil {\n\t\t_, err := m.SecurityDefinitions.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Tags {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Examples objects.\nfunc (m *Examples) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ExternalDocs objects.\nfunc (m *ExternalDocs) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside FileSchema objects.\nfunc (m *FileSchema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Example != nil {\n\t\t_, err := m.Example.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside FormDataParameterSubSchema objects.\nfunc (m *FormDataParameterSubSchema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Header objects.\nfunc (m *Header) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside HeaderParameterSubSchema objects.\nfunc (m *HeaderParameterSubSchema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Headers objects.\nfunc (m *Headers) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Info objects.\nfunc (m *Info) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Contact != nil {\n\t\t_, err := m.Contact.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.License != nil {\n\t\t_, err := m.License.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ItemsItem objects.\nfunc (m *ItemsItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.Schema {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside JsonReference objects.\nfunc (m *JsonReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.XRef != \"\" {\n\t\tinfo, err := compiler.ReadInfoForRef(root, m.XRef)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif info != nil {\n\t\t\treplacement, err := NewJsonReference(info, nil)\n\t\t\tif err == nil {\n\t\t\t\t*m = *replacement\n\t\t\t\treturn m.ResolveReferences(root)\n\t\t\t}\n\t\t}\n\t\treturn info, nil\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside License objects.\nfunc (m *License) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedAny objects.\nfunc (m *NamedAny) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedHeader objects.\nfunc (m *NamedHeader) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedParameter objects.\nfunc (m *NamedParameter) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedPathItem objects.\nfunc (m *NamedPathItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedResponse objects.\nfunc (m *NamedResponse) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedResponseValue objects.\nfunc (m *NamedResponseValue) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedSchema objects.\nfunc (m *NamedSchema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedSecurityDefinitionsItem objects.\nfunc (m *NamedSecurityDefinitionsItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedString objects.\nfunc (m *NamedString) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedStringArray objects.\nfunc (m *NamedStringArray) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NonBodyParameter objects.\nfunc (m *NonBodyParameter) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*NonBodyParameter_HeaderParameterSubSchema)\n\t\tif ok {\n\t\t\t_, err := p.HeaderParameterSubSchema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*NonBodyParameter_FormDataParameterSubSchema)\n\t\tif ok {\n\t\t\t_, err := p.FormDataParameterSubSchema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*NonBodyParameter_QueryParameterSubSchema)\n\t\tif ok {\n\t\t\t_, err := p.QueryParameterSubSchema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*NonBodyParameter_PathParameterSubSchema)\n\t\tif ok {\n\t\t\t_, err := p.PathParameterSubSchema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Oauth2AccessCodeSecurity objects.\nfunc (m *Oauth2AccessCodeSecurity) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Scopes != nil {\n\t\t_, err := m.Scopes.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Oauth2ApplicationSecurity objects.\nfunc (m *Oauth2ApplicationSecurity) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Scopes != nil {\n\t\t_, err := m.Scopes.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Oauth2ImplicitSecurity objects.\nfunc (m *Oauth2ImplicitSecurity) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Scopes != nil {\n\t\t_, err := m.Scopes.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Oauth2PasswordSecurity objects.\nfunc (m *Oauth2PasswordSecurity) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Scopes != nil {\n\t\t_, err := m.Scopes.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Oauth2Scopes objects.\nfunc (m *Oauth2Scopes) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Operation objects.\nfunc (m *Operation) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Parameters {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.Responses != nil {\n\t\t_, err := m.Responses.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Security {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Parameter objects.\nfunc (m *Parameter) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*Parameter_BodyParameter)\n\t\tif ok {\n\t\t\t_, err := p.BodyParameter.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*Parameter_NonBodyParameter)\n\t\tif ok {\n\t\t\t_, err := p.NonBodyParameter.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ParameterDefinitions objects.\nfunc (m *ParameterDefinitions) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ParametersItem objects.\nfunc (m *ParametersItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*ParametersItem_Parameter)\n\t\tif ok {\n\t\t\t_, err := p.Parameter.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*ParametersItem_JsonReference)\n\t\tif ok {\n\t\t\tinfo, err := p.JsonReference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t} else if info != nil {\n\t\t\t\tn, err := NewParametersItem(info, nil)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t} else if n != nil {\n\t\t\t\t\t*m = *n\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside PathItem objects.\nfunc (m *PathItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.XRef != \"\" {\n\t\tinfo, err := compiler.ReadInfoForRef(root, m.XRef)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif info != nil {\n\t\t\treplacement, err := NewPathItem(info, nil)\n\t\t\tif err == nil {\n\t\t\t\t*m = *replacement\n\t\t\t\treturn m.ResolveReferences(root)\n\t\t\t}\n\t\t}\n\t\treturn info, nil\n\t}\n\tif m.Get != nil {\n\t\t_, err := m.Get.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Put != nil {\n\t\t_, err := m.Put.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Post != nil {\n\t\t_, err := m.Post.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Delete != nil {\n\t\t_, err := m.Delete.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Options != nil {\n\t\t_, err := m.Options.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Head != nil {\n\t\t_, err := m.Head.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Patch != nil {\n\t\t_, err := m.Patch.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Parameters {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside PathParameterSubSchema objects.\nfunc (m *PathParameterSubSchema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Paths objects.\nfunc (m *Paths) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.Path {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside PrimitivesItems objects.\nfunc (m *PrimitivesItems) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Properties objects.\nfunc (m *Properties) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside QueryParameterSubSchema objects.\nfunc (m *QueryParameterSubSchema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Response objects.\nfunc (m *Response) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Schema != nil {\n\t\t_, err := m.Schema.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Headers != nil {\n\t\t_, err := m.Headers.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Examples != nil {\n\t\t_, err := m.Examples.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ResponseDefinitions objects.\nfunc (m *ResponseDefinitions) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ResponseValue objects.\nfunc (m *ResponseValue) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*ResponseValue_Response)\n\t\tif ok {\n\t\t\t_, err := p.Response.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*ResponseValue_JsonReference)\n\t\tif ok {\n\t\t\tinfo, err := p.JsonReference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t} else if info != nil {\n\t\t\t\tn, err := NewResponseValue(info, nil)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t} else if n != nil {\n\t\t\t\t\t*m = *n\n\t\t\t\t\treturn nil, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Responses objects.\nfunc (m *Responses) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.ResponseCode {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Schema objects.\nfunc (m *Schema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.XRef != \"\" {\n\t\tinfo, err := compiler.ReadInfoForRef(root, m.XRef)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif info != nil {\n\t\t\treplacement, err := NewSchema(info, nil)\n\t\t\tif err == nil {\n\t\t\t\t*m = *replacement\n\t\t\t\treturn m.ResolveReferences(root)\n\t\t\t}\n\t\t}\n\t\treturn info, nil\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.AdditionalProperties != nil {\n\t\t_, err := m.AdditionalProperties.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Type != nil {\n\t\t_, err := m.Type.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.AllOf {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.Properties != nil {\n\t\t_, err := m.Properties.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Xml != nil {\n\t\t_, err := m.Xml.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Example != nil {\n\t\t_, err := m.Example.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SchemaItem objects.\nfunc (m *SchemaItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*SchemaItem_Schema)\n\t\tif ok {\n\t\t\t_, err := p.Schema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SchemaItem_FileSchema)\n\t\tif ok {\n\t\t\t_, err := p.FileSchema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SecurityDefinitions objects.\nfunc (m *SecurityDefinitions) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SecurityDefinitionsItem objects.\nfunc (m *SecurityDefinitionsItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*SecurityDefinitionsItem_BasicAuthenticationSecurity)\n\t\tif ok {\n\t\t\t_, err := p.BasicAuthenticationSecurity.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SecurityDefinitionsItem_ApiKeySecurity)\n\t\tif ok {\n\t\t\t_, err := p.ApiKeySecurity.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2ImplicitSecurity)\n\t\tif ok {\n\t\t\t_, err := p.Oauth2ImplicitSecurity.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2PasswordSecurity)\n\t\tif ok {\n\t\t\t_, err := p.Oauth2PasswordSecurity.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2ApplicationSecurity)\n\t\tif ok {\n\t\t\t_, err := p.Oauth2ApplicationSecurity.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SecurityDefinitionsItem_Oauth2AccessCodeSecurity)\n\t\tif ok {\n\t\t\t_, err := p.Oauth2AccessCodeSecurity.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SecurityRequirement objects.\nfunc (m *SecurityRequirement) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside StringArray objects.\nfunc (m *StringArray) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Tag objects.\nfunc (m *Tag) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside TypeItem objects.\nfunc (m *TypeItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside VendorExtension objects.\nfunc (m *VendorExtension) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Xml objects.\nfunc (m *Xml) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.VendorExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ToRawInfo returns a description of AdditionalPropertiesItem suitable for JSON or YAML export.\nfunc (m *AdditionalPropertiesItem) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// AdditionalPropertiesItem\n\t// {Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetSchema()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:boolean Type:bool StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v1, ok := m.GetOneof().(*AdditionalPropertiesItem_Boolean); ok {\n\t\treturn compiler.NewScalarNodeForBool(v1.Boolean)\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Any suitable for JSON or YAML export.\nfunc (m *Any) ToRawInfo() *yaml.Node {\n\tvar err error\n\tvar node yaml.Node\n\terr = yaml.Unmarshal([]byte(m.Yaml), &node)\n\tif err == nil {\n\t\tif node.Kind == yaml.DocumentNode {\n\t\t\treturn node.Content[0]\n\t\t}\n\t\treturn &node\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of ApiKeySecurity suitable for JSON or YAML export.\nfunc (m *ApiKeySecurity) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of BasicAuthenticationSecurity suitable for JSON or YAML export.\nfunc (m *BasicAuthenticationSecurity) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of BodyParameter suitable for JSON or YAML export.\nfunc (m *BodyParameter) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\tif m.Required != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schema\"))\n\tinfo.Content = append(info.Content, m.Schema.ToRawInfo())\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Contact suitable for JSON or YAML export.\nfunc (m *Contact) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Url != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"url\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Url))\n\t}\n\tif m.Email != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"email\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Email))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Default suitable for JSON or YAML export.\nfunc (m *Default) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Definitions suitable for JSON or YAML export.\nfunc (m *Definitions) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Document suitable for JSON or YAML export.\nfunc (m *Document) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"swagger\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Swagger))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"info\"))\n\tinfo.Content = append(info.Content, m.Info.ToRawInfo())\n\tif m.Host != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"host\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Host))\n\t}\n\tif m.BasePath != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"basePath\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.BasePath))\n\t}\n\tif len(m.Schemes) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schemes\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Schemes))\n\t}\n\tif len(m.Consumes) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"consumes\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Consumes))\n\t}\n\tif len(m.Produces) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"produces\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Produces))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"paths\"))\n\tinfo.Content = append(info.Content, m.Paths.ToRawInfo())\n\tif m.Definitions != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"definitions\"))\n\t\tinfo.Content = append(info.Content, m.Definitions.ToRawInfo())\n\t}\n\tif m.Parameters != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"parameters\"))\n\t\tinfo.Content = append(info.Content, m.Parameters.ToRawInfo())\n\t}\n\tif m.Responses != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"responses\"))\n\t\tinfo.Content = append(info.Content, m.Responses.ToRawInfo())\n\t}\n\tif len(m.Security) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Security {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"security\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.SecurityDefinitions != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"securityDefinitions\"))\n\t\tinfo.Content = append(info.Content, m.SecurityDefinitions.ToRawInfo())\n\t}\n\tif len(m.Tags) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Tags {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tags\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Examples suitable for JSON or YAML export.\nfunc (m *Examples) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ExternalDocs suitable for JSON or YAML export.\nfunc (m *ExternalDocs) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"url\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Url))\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of FileSchema suitable for JSON or YAML export.\nfunc (m *FileSchema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Title != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"title\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Title))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif len(m.Required) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Required))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\tif m.ReadOnly != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"readOnly\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ReadOnly))\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.Example != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"example\"))\n\t\tinfo.Content = append(info.Content, m.Example.ToRawInfo())\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of FormDataParameterSubSchema suitable for JSON or YAML export.\nfunc (m *FormDataParameterSubSchema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Required != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\t}\n\tif m.In != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.AllowEmptyValue != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allowEmptyValue\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.AllowEmptyValue))\n\t}\n\tif m.Type != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Items != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, m.Items.ToRawInfo())\n\t}\n\tif m.CollectionFormat != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"collectionFormat\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.CollectionFormat))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Header suitable for JSON or YAML export.\nfunc (m *Header) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Items != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, m.Items.ToRawInfo())\n\t}\n\tif m.CollectionFormat != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"collectionFormat\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.CollectionFormat))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of HeaderParameterSubSchema suitable for JSON or YAML export.\nfunc (m *HeaderParameterSubSchema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Required != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\t}\n\tif m.In != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Type != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Items != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, m.Items.ToRawInfo())\n\t}\n\tif m.CollectionFormat != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"collectionFormat\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.CollectionFormat))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Headers suitable for JSON or YAML export.\nfunc (m *Headers) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Info suitable for JSON or YAML export.\nfunc (m *Info) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"title\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Title))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"version\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Version))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.TermsOfService != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"termsOfService\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.TermsOfService))\n\t}\n\tif m.Contact != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"contact\"))\n\t\tinfo.Content = append(info.Content, m.Contact.ToRawInfo())\n\t}\n\tif m.License != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"license\"))\n\t\tinfo.Content = append(info.Content, m.License.ToRawInfo())\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ItemsItem suitable for JSON or YAML export.\nfunc (m *ItemsItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif len(m.Schema) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Schema {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schema\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of JsonReference suitable for JSON or YAML export.\nfunc (m *JsonReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"$ref\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.XRef))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of License suitable for JSON or YAML export.\nfunc (m *License) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\tif m.Url != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"url\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Url))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedAny suitable for JSON or YAML export.\nfunc (m *NamedAny) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Value != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"value\"))\n\t\tinfo.Content = append(info.Content, m.Value.ToRawInfo())\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedHeader suitable for JSON or YAML export.\nfunc (m *NamedHeader) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:Header StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedParameter suitable for JSON or YAML export.\nfunc (m *NamedParameter) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:Parameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedPathItem suitable for JSON or YAML export.\nfunc (m *NamedPathItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:PathItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedResponse suitable for JSON or YAML export.\nfunc (m *NamedResponse) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:Response StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedResponseValue suitable for JSON or YAML export.\nfunc (m *NamedResponseValue) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:ResponseValue StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedSchema suitable for JSON or YAML export.\nfunc (m *NamedSchema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedSecurityDefinitionsItem suitable for JSON or YAML export.\nfunc (m *NamedSecurityDefinitionsItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:SecurityDefinitionsItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedString suitable for JSON or YAML export.\nfunc (m *NamedString) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Value != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"value\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Value))\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedStringArray suitable for JSON or YAML export.\nfunc (m *NamedStringArray) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:StringArray StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NonBodyParameter suitable for JSON or YAML export.\nfunc (m *NonBodyParameter) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// NonBodyParameter\n\t// {Name:headerParameterSubSchema Type:HeaderParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetHeaderParameterSubSchema()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:formDataParameterSubSchema Type:FormDataParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetFormDataParameterSubSchema()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\t// {Name:queryParameterSubSchema Type:QueryParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv2 := m.GetQueryParameterSubSchema()\n\tif v2 != nil {\n\t\treturn v2.ToRawInfo()\n\t}\n\t// {Name:pathParameterSubSchema Type:PathParameterSubSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv3 := m.GetPathParameterSubSchema()\n\tif v3 != nil {\n\t\treturn v3.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Oauth2AccessCodeSecurity suitable for JSON or YAML export.\nfunc (m *Oauth2AccessCodeSecurity) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"flow\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Flow))\n\tif m.Scopes != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"scopes\"))\n\t\tinfo.Content = append(info.Content, m.Scopes.ToRawInfo())\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"authorizationUrl\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.AuthorizationUrl))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tokenUrl\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.TokenUrl))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Oauth2ApplicationSecurity suitable for JSON or YAML export.\nfunc (m *Oauth2ApplicationSecurity) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"flow\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Flow))\n\tif m.Scopes != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"scopes\"))\n\t\tinfo.Content = append(info.Content, m.Scopes.ToRawInfo())\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tokenUrl\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.TokenUrl))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Oauth2ImplicitSecurity suitable for JSON or YAML export.\nfunc (m *Oauth2ImplicitSecurity) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"flow\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Flow))\n\tif m.Scopes != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"scopes\"))\n\t\tinfo.Content = append(info.Content, m.Scopes.ToRawInfo())\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"authorizationUrl\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.AuthorizationUrl))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Oauth2PasswordSecurity suitable for JSON or YAML export.\nfunc (m *Oauth2PasswordSecurity) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"flow\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Flow))\n\tif m.Scopes != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"scopes\"))\n\t\tinfo.Content = append(info.Content, m.Scopes.ToRawInfo())\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tokenUrl\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.TokenUrl))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Oauth2Scopes suitable for JSON or YAML export.\nfunc (m *Oauth2Scopes) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:}\n\treturn info\n}\n\n// ToRawInfo returns a description of Operation suitable for JSON or YAML export.\nfunc (m *Operation) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif len(m.Tags) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tags\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Tags))\n\t}\n\tif m.Summary != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"summary\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Summary))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.OperationId != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"operationId\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.OperationId))\n\t}\n\tif len(m.Produces) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"produces\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Produces))\n\t}\n\tif len(m.Consumes) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"consumes\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Consumes))\n\t}\n\tif len(m.Parameters) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Parameters {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"parameters\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"responses\"))\n\tinfo.Content = append(info.Content, m.Responses.ToRawInfo())\n\tif len(m.Schemes) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schemes\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Schemes))\n\t}\n\tif m.Deprecated != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"deprecated\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Deprecated))\n\t}\n\tif len(m.Security) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Security {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"security\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Parameter suitable for JSON or YAML export.\nfunc (m *Parameter) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// Parameter\n\t// {Name:bodyParameter Type:BodyParameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetBodyParameter()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:nonBodyParameter Type:NonBodyParameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetNonBodyParameter()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of ParameterDefinitions suitable for JSON or YAML export.\nfunc (m *ParameterDefinitions) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ParametersItem suitable for JSON or YAML export.\nfunc (m *ParametersItem) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// ParametersItem\n\t// {Name:parameter Type:Parameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetParameter()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:jsonReference Type:JsonReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetJsonReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of PathItem suitable for JSON or YAML export.\nfunc (m *PathItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.XRef != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"$ref\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.XRef))\n\t}\n\tif m.Get != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"get\"))\n\t\tinfo.Content = append(info.Content, m.Get.ToRawInfo())\n\t}\n\tif m.Put != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"put\"))\n\t\tinfo.Content = append(info.Content, m.Put.ToRawInfo())\n\t}\n\tif m.Post != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"post\"))\n\t\tinfo.Content = append(info.Content, m.Post.ToRawInfo())\n\t}\n\tif m.Delete != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"delete\"))\n\t\tinfo.Content = append(info.Content, m.Delete.ToRawInfo())\n\t}\n\tif m.Options != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"options\"))\n\t\tinfo.Content = append(info.Content, m.Options.ToRawInfo())\n\t}\n\tif m.Head != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"head\"))\n\t\tinfo.Content = append(info.Content, m.Head.ToRawInfo())\n\t}\n\tif m.Patch != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"patch\"))\n\t\tinfo.Content = append(info.Content, m.Patch.ToRawInfo())\n\t}\n\tif len(m.Parameters) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Parameters {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"parameters\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of PathParameterSubSchema suitable for JSON or YAML export.\nfunc (m *PathParameterSubSchema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\tif m.In != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Type != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Items != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, m.Items.ToRawInfo())\n\t}\n\tif m.CollectionFormat != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"collectionFormat\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.CollectionFormat))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Paths suitable for JSON or YAML export.\nfunc (m *Paths) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\tif m.Path != nil {\n\t\tfor _, item := range m.Path {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of PrimitivesItems suitable for JSON or YAML export.\nfunc (m *PrimitivesItems) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Type != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Items != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, m.Items.ToRawInfo())\n\t}\n\tif m.CollectionFormat != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"collectionFormat\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.CollectionFormat))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Properties suitable for JSON or YAML export.\nfunc (m *Properties) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of QueryParameterSubSchema suitable for JSON or YAML export.\nfunc (m *QueryParameterSubSchema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Required != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\t}\n\tif m.In != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.AllowEmptyValue != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allowEmptyValue\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.AllowEmptyValue))\n\t}\n\tif m.Type != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Items != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, m.Items.ToRawInfo())\n\t}\n\tif m.CollectionFormat != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"collectionFormat\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.CollectionFormat))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Response suitable for JSON or YAML export.\nfunc (m *Response) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\tif m.Schema != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schema\"))\n\t\tinfo.Content = append(info.Content, m.Schema.ToRawInfo())\n\t}\n\tif m.Headers != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"headers\"))\n\t\tinfo.Content = append(info.Content, m.Headers.ToRawInfo())\n\t}\n\tif m.Examples != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"examples\"))\n\t\tinfo.Content = append(info.Content, m.Examples.ToRawInfo())\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ResponseDefinitions suitable for JSON or YAML export.\nfunc (m *ResponseDefinitions) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ResponseValue suitable for JSON or YAML export.\nfunc (m *ResponseValue) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// ResponseValue\n\t// {Name:response Type:Response StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetResponse()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:jsonReference Type:JsonReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetJsonReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Responses suitable for JSON or YAML export.\nfunc (m *Responses) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.ResponseCode != nil {\n\t\tfor _, item := range m.ResponseCode {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Schema suitable for JSON or YAML export.\nfunc (m *Schema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.XRef != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"$ref\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.XRef))\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.Title != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"title\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Title))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif m.MaxProperties != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxProperties\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxProperties))\n\t}\n\tif m.MinProperties != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minProperties\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinProperties))\n\t}\n\tif len(m.Required) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Required))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"additionalProperties\"))\n\t\tinfo.Content = append(info.Content, m.AdditionalProperties.ToRawInfo())\n\t}\n\tif m.Type != nil {\n\t\tif len(m.Type.Value) == 1 {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type.Value[0]))\n\t\t} else {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Type.Value))\n\t\t}\n\t}\n\tif m.Items != nil {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Items.Schema {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tif len(items.Content) == 1 {\n\t\t\titems = items.Content[0]\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif len(m.AllOf) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.AllOf {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allOf\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.Properties != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"properties\"))\n\t\tinfo.Content = append(info.Content, m.Properties.ToRawInfo())\n\t}\n\tif m.Discriminator != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"discriminator\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Discriminator))\n\t}\n\tif m.ReadOnly != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"readOnly\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ReadOnly))\n\t}\n\tif m.Xml != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"xml\"))\n\t\tinfo.Content = append(info.Content, m.Xml.ToRawInfo())\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.Example != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"example\"))\n\t\tinfo.Content = append(info.Content, m.Example.ToRawInfo())\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of SchemaItem suitable for JSON or YAML export.\nfunc (m *SchemaItem) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// SchemaItem\n\t// {Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetSchema()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:fileSchema Type:FileSchema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetFileSchema()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of SecurityDefinitions suitable for JSON or YAML export.\nfunc (m *SecurityDefinitions) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of SecurityDefinitionsItem suitable for JSON or YAML export.\nfunc (m *SecurityDefinitionsItem) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// SecurityDefinitionsItem\n\t// {Name:basicAuthenticationSecurity Type:BasicAuthenticationSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetBasicAuthenticationSecurity()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:apiKeySecurity Type:ApiKeySecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetApiKeySecurity()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\t// {Name:oauth2ImplicitSecurity Type:Oauth2ImplicitSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv2 := m.GetOauth2ImplicitSecurity()\n\tif v2 != nil {\n\t\treturn v2.ToRawInfo()\n\t}\n\t// {Name:oauth2PasswordSecurity Type:Oauth2PasswordSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv3 := m.GetOauth2PasswordSecurity()\n\tif v3 != nil {\n\t\treturn v3.ToRawInfo()\n\t}\n\t// {Name:oauth2ApplicationSecurity Type:Oauth2ApplicationSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv4 := m.GetOauth2ApplicationSecurity()\n\tif v4 != nil {\n\t\treturn v4.ToRawInfo()\n\t}\n\t// {Name:oauth2AccessCodeSecurity Type:Oauth2AccessCodeSecurity StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv5 := m.GetOauth2AccessCodeSecurity()\n\tif v5 != nil {\n\t\treturn v5.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of SecurityRequirement suitable for JSON or YAML export.\nfunc (m *SecurityRequirement) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of StringArray suitable for JSON or YAML export.\nfunc (m *StringArray) ToRawInfo() *yaml.Node {\n\treturn compiler.NewSequenceNodeForStringArray(m.Value)\n}\n\n// ToRawInfo returns a description of Tag suitable for JSON or YAML export.\nfunc (m *Tag) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of TypeItem suitable for JSON or YAML export.\nfunc (m *TypeItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif len(m.Value) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"value\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Value))\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of VendorExtension suitable for JSON or YAML export.\nfunc (m *VendorExtension) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Xml suitable for JSON or YAML export.\nfunc (m *Xml) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Namespace != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"namespace\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Namespace))\n\t}\n\tif m.Prefix != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"prefix\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Prefix))\n\t}\n\tif m.Attribute != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"attribute\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Attribute))\n\t}\n\tif m.Wrapped != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"wrapped\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Wrapped))\n\t}\n\tif m.VendorExtension != nil {\n\t\tfor _, item := range m.VendorExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\nvar (\n\tpattern0 = regexp.MustCompile(\"^x-\")\n\tpattern1 = regexp.MustCompile(\"^/\")\n\tpattern2 = regexp.MustCompile(\"^([0-9]{3})$|^(default)$\")\n)\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.pb.go",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\n// THIS FILE IS AUTOMATICALLY GENERATED.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.18.1\n// source: openapiv2/OpenAPIv2.proto\n\npackage openapi_v2\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\tanypb \"google.golang.org/protobuf/types/known/anypb\"\n\treflect \"reflect\"\n\tsync \"sync\"\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 AdditionalPropertiesItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*AdditionalPropertiesItem_Schema\n\t//\t*AdditionalPropertiesItem_Boolean\n\tOneof isAdditionalPropertiesItem_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *AdditionalPropertiesItem) Reset() {\n\t*x = AdditionalPropertiesItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *AdditionalPropertiesItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AdditionalPropertiesItem) ProtoMessage() {}\n\nfunc (x *AdditionalPropertiesItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 AdditionalPropertiesItem.ProtoReflect.Descriptor instead.\nfunc (*AdditionalPropertiesItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (m *AdditionalPropertiesItem) GetOneof() isAdditionalPropertiesItem_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *AdditionalPropertiesItem) GetSchema() *Schema {\n\tif x, ok := x.GetOneof().(*AdditionalPropertiesItem_Schema); ok {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *AdditionalPropertiesItem) GetBoolean() bool {\n\tif x, ok := x.GetOneof().(*AdditionalPropertiesItem_Boolean); ok {\n\t\treturn x.Boolean\n\t}\n\treturn false\n}\n\ntype isAdditionalPropertiesItem_Oneof interface {\n\tisAdditionalPropertiesItem_Oneof()\n}\n\ntype AdditionalPropertiesItem_Schema struct {\n\tSchema *Schema `protobuf:\"bytes,1,opt,name=schema,proto3,oneof\"`\n}\n\ntype AdditionalPropertiesItem_Boolean struct {\n\tBoolean bool `protobuf:\"varint,2,opt,name=boolean,proto3,oneof\"`\n}\n\nfunc (*AdditionalPropertiesItem_Schema) isAdditionalPropertiesItem_Oneof() {}\n\nfunc (*AdditionalPropertiesItem_Boolean) isAdditionalPropertiesItem_Oneof() {}\n\ntype Any struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue *anypb.Any `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tYaml  string     `protobuf:\"bytes,2,opt,name=yaml,proto3\" json:\"yaml,omitempty\"`\n}\n\nfunc (x *Any) Reset() {\n\t*x = Any{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Any) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Any) ProtoMessage() {}\n\nfunc (x *Any) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 Any.ProtoReflect.Descriptor instead.\nfunc (*Any) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Any) GetValue() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\nfunc (x *Any) GetYaml() string {\n\tif x != nil {\n\t\treturn x.Yaml\n\t}\n\treturn \"\"\n}\n\ntype ApiKeySecurity struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType            string      `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tName            string      `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tIn              string      `protobuf:\"bytes,3,opt,name=in,proto3\" json:\"in,omitempty\"`\n\tDescription     string      `protobuf:\"bytes,4,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,5,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *ApiKeySecurity) Reset() {\n\t*x = ApiKeySecurity{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ApiKeySecurity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ApiKeySecurity) ProtoMessage() {}\n\nfunc (x *ApiKeySecurity) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 ApiKeySecurity.ProtoReflect.Descriptor instead.\nfunc (*ApiKeySecurity) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (x *ApiKeySecurity) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *ApiKeySecurity) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *ApiKeySecurity) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *ApiKeySecurity) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *ApiKeySecurity) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype BasicAuthenticationSecurity struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType            string      `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tDescription     string      `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,3,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *BasicAuthenticationSecurity) Reset() {\n\t*x = BasicAuthenticationSecurity{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *BasicAuthenticationSecurity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*BasicAuthenticationSecurity) ProtoMessage() {}\n\nfunc (x *BasicAuthenticationSecurity) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 BasicAuthenticationSecurity.ProtoReflect.Descriptor instead.\nfunc (*BasicAuthenticationSecurity) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *BasicAuthenticationSecurity) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *BasicAuthenticationSecurity) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *BasicAuthenticationSecurity) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype BodyParameter struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n\tDescription string `protobuf:\"bytes,1,opt,name=description,proto3\" json:\"description,omitempty\"`\n\t// The name of the parameter.\n\tName string `protobuf:\"bytes,2,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Determines the location of the parameter.\n\tIn string `protobuf:\"bytes,3,opt,name=in,proto3\" json:\"in,omitempty\"`\n\t// Determines whether or not this parameter is required or optional.\n\tRequired        bool        `protobuf:\"varint,4,opt,name=required,proto3\" json:\"required,omitempty\"`\n\tSchema          *Schema     `protobuf:\"bytes,5,opt,name=schema,proto3\" json:\"schema,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,6,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *BodyParameter) Reset() {\n\t*x = BodyParameter{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *BodyParameter) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*BodyParameter) ProtoMessage() {}\n\nfunc (x *BodyParameter) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 BodyParameter.ProtoReflect.Descriptor instead.\nfunc (*BodyParameter) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *BodyParameter) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *BodyParameter) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *BodyParameter) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *BodyParameter) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *BodyParameter) GetSchema() *Schema {\n\tif x != nil {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *BodyParameter) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\n// Contact information for the owners of the API.\ntype Contact struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The identifying name of the contact person/organization.\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// The URL pointing to the contact information.\n\tUrl string `protobuf:\"bytes,2,opt,name=url,proto3\" json:\"url,omitempty\"`\n\t// The email address of the contact person/organization.\n\tEmail           string      `protobuf:\"bytes,3,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,4,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Contact) Reset() {\n\t*x = Contact{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[5]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Contact) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Contact) ProtoMessage() {}\n\nfunc (x *Contact) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 Contact.ProtoReflect.Descriptor instead.\nfunc (*Contact) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *Contact) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Contact) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *Contact) GetEmail() string {\n\tif x != nil {\n\t\treturn x.Email\n\t}\n\treturn \"\"\n}\n\nfunc (x *Contact) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Default struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedAny `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Default) Reset() {\n\t*x = Default{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[6]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Default) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Default) ProtoMessage() {}\n\nfunc (x *Default) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 Default.ProtoReflect.Descriptor instead.\nfunc (*Default) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *Default) GetAdditionalProperties() []*NamedAny {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// One or more JSON objects describing the schemas being consumed and produced by the API.\ntype Definitions struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedSchema `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Definitions) Reset() {\n\t*x = Definitions{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[7]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Definitions) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Definitions) ProtoMessage() {}\n\nfunc (x *Definitions) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 Definitions.ProtoReflect.Descriptor instead.\nfunc (*Definitions) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *Definitions) GetAdditionalProperties() []*NamedSchema {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype Document struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The Swagger version of this document.\n\tSwagger string `protobuf:\"bytes,1,opt,name=swagger,proto3\" json:\"swagger,omitempty\"`\n\tInfo    *Info  `protobuf:\"bytes,2,opt,name=info,proto3\" json:\"info,omitempty\"`\n\t// The host (name or ip) of the API. Example: 'swagger.io'\n\tHost string `protobuf:\"bytes,3,opt,name=host,proto3\" json:\"host,omitempty\"`\n\t// The base path to the API. Example: '/api'.\n\tBasePath string `protobuf:\"bytes,4,opt,name=base_path,json=basePath,proto3\" json:\"base_path,omitempty\"`\n\t// The transfer protocol of the API.\n\tSchemes []string `protobuf:\"bytes,5,rep,name=schemes,proto3\" json:\"schemes,omitempty\"`\n\t// A list of MIME types accepted by the API.\n\tConsumes []string `protobuf:\"bytes,6,rep,name=consumes,proto3\" json:\"consumes,omitempty\"`\n\t// A list of MIME types the API can produce.\n\tProduces            []string               `protobuf:\"bytes,7,rep,name=produces,proto3\" json:\"produces,omitempty\"`\n\tPaths               *Paths                 `protobuf:\"bytes,8,opt,name=paths,proto3\" json:\"paths,omitempty\"`\n\tDefinitions         *Definitions           `protobuf:\"bytes,9,opt,name=definitions,proto3\" json:\"definitions,omitempty\"`\n\tParameters          *ParameterDefinitions  `protobuf:\"bytes,10,opt,name=parameters,proto3\" json:\"parameters,omitempty\"`\n\tResponses           *ResponseDefinitions   `protobuf:\"bytes,11,opt,name=responses,proto3\" json:\"responses,omitempty\"`\n\tSecurity            []*SecurityRequirement `protobuf:\"bytes,12,rep,name=security,proto3\" json:\"security,omitempty\"`\n\tSecurityDefinitions *SecurityDefinitions   `protobuf:\"bytes,13,opt,name=security_definitions,json=securityDefinitions,proto3\" json:\"security_definitions,omitempty\"`\n\tTags                []*Tag                 `protobuf:\"bytes,14,rep,name=tags,proto3\" json:\"tags,omitempty\"`\n\tExternalDocs        *ExternalDocs          `protobuf:\"bytes,15,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tVendorExtension     []*NamedAny            `protobuf:\"bytes,16,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Document) Reset() {\n\t*x = Document{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[8]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Document) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Document) ProtoMessage() {}\n\nfunc (x *Document) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 Document.ProtoReflect.Descriptor instead.\nfunc (*Document) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (x *Document) GetSwagger() string {\n\tif x != nil {\n\t\treturn x.Swagger\n\t}\n\treturn \"\"\n}\n\nfunc (x *Document) GetInfo() *Info {\n\tif x != nil {\n\t\treturn x.Info\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetHost() string {\n\tif x != nil {\n\t\treturn x.Host\n\t}\n\treturn \"\"\n}\n\nfunc (x *Document) GetBasePath() string {\n\tif x != nil {\n\t\treturn x.BasePath\n\t}\n\treturn \"\"\n}\n\nfunc (x *Document) GetSchemes() []string {\n\tif x != nil {\n\t\treturn x.Schemes\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetConsumes() []string {\n\tif x != nil {\n\t\treturn x.Consumes\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetProduces() []string {\n\tif x != nil {\n\t\treturn x.Produces\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetPaths() *Paths {\n\tif x != nil {\n\t\treturn x.Paths\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetDefinitions() *Definitions {\n\tif x != nil {\n\t\treturn x.Definitions\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetParameters() *ParameterDefinitions {\n\tif x != nil {\n\t\treturn x.Parameters\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetResponses() *ResponseDefinitions {\n\tif x != nil {\n\t\treturn x.Responses\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetSecurity() []*SecurityRequirement {\n\tif x != nil {\n\t\treturn x.Security\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetSecurityDefinitions() *SecurityDefinitions {\n\tif x != nil {\n\t\treturn x.SecurityDefinitions\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetTags() []*Tag {\n\tif x != nil {\n\t\treturn x.Tags\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Examples struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedAny `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Examples) Reset() {\n\t*x = Examples{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[9]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Examples) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Examples) ProtoMessage() {}\n\nfunc (x *Examples) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 Examples.ProtoReflect.Descriptor instead.\nfunc (*Examples) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{9}\n}\n\nfunc (x *Examples) GetAdditionalProperties() []*NamedAny {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// information about external documentation\ntype ExternalDocs struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tDescription     string      `protobuf:\"bytes,1,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tUrl             string      `protobuf:\"bytes,2,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,3,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *ExternalDocs) Reset() {\n\t*x = ExternalDocs{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[10]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExternalDocs) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExternalDocs) ProtoMessage() {}\n\nfunc (x *ExternalDocs) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_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 ExternalDocs.ProtoReflect.Descriptor instead.\nfunc (*ExternalDocs) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{10}\n}\n\nfunc (x *ExternalDocs) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *ExternalDocs) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *ExternalDocs) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\n// A deterministic version of a JSON Schema object.\ntype FileSchema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tFormat          string        `protobuf:\"bytes,1,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tTitle           string        `protobuf:\"bytes,2,opt,name=title,proto3\" json:\"title,omitempty\"`\n\tDescription     string        `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tDefault         *Any          `protobuf:\"bytes,4,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tRequired        []string      `protobuf:\"bytes,5,rep,name=required,proto3\" json:\"required,omitempty\"`\n\tType            string        `protobuf:\"bytes,6,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tReadOnly        bool          `protobuf:\"varint,7,opt,name=read_only,json=readOnly,proto3\" json:\"read_only,omitempty\"`\n\tExternalDocs    *ExternalDocs `protobuf:\"bytes,8,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tExample         *Any          `protobuf:\"bytes,9,opt,name=example,proto3\" json:\"example,omitempty\"`\n\tVendorExtension []*NamedAny   `protobuf:\"bytes,10,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *FileSchema) Reset() {\n\t*x = FileSchema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[11]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *FileSchema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FileSchema) ProtoMessage() {}\n\nfunc (x *FileSchema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[11]\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 FileSchema.ProtoReflect.Descriptor instead.\nfunc (*FileSchema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{11}\n}\n\nfunc (x *FileSchema) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *FileSchema) GetTitle() string {\n\tif x != nil {\n\t\treturn x.Title\n\t}\n\treturn \"\"\n}\n\nfunc (x *FileSchema) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *FileSchema) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *FileSchema) GetRequired() []string {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn nil\n}\n\nfunc (x *FileSchema) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *FileSchema) GetReadOnly() bool {\n\tif x != nil {\n\t\treturn x.ReadOnly\n\t}\n\treturn false\n}\n\nfunc (x *FileSchema) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *FileSchema) GetExample() *Any {\n\tif x != nil {\n\t\treturn x.Example\n\t}\n\treturn nil\n}\n\nfunc (x *FileSchema) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype FormDataParameterSubSchema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Determines whether or not this parameter is required or optional.\n\tRequired bool `protobuf:\"varint,1,opt,name=required,proto3\" json:\"required,omitempty\"`\n\t// Determines the location of the parameter.\n\tIn string `protobuf:\"bytes,2,opt,name=in,proto3\" json:\"in,omitempty\"`\n\t// A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\t// The name of the parameter.\n\tName string `protobuf:\"bytes,4,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// allows sending a parameter by name only or with an empty value.\n\tAllowEmptyValue  bool             `protobuf:\"varint,5,opt,name=allow_empty_value,json=allowEmptyValue,proto3\" json:\"allow_empty_value,omitempty\"`\n\tType             string           `protobuf:\"bytes,6,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFormat           string           `protobuf:\"bytes,7,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tItems            *PrimitivesItems `protobuf:\"bytes,8,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tCollectionFormat string           `protobuf:\"bytes,9,opt,name=collection_format,json=collectionFormat,proto3\" json:\"collection_format,omitempty\"`\n\tDefault          *Any             `protobuf:\"bytes,10,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tMaximum          float64          `protobuf:\"fixed64,11,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum bool             `protobuf:\"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum          float64          `protobuf:\"fixed64,13,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum bool             `protobuf:\"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength        int64            `protobuf:\"varint,15,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength        int64            `protobuf:\"varint,16,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern          string           `protobuf:\"bytes,17,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems         int64            `protobuf:\"varint,18,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems         int64            `protobuf:\"varint,19,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems      bool             `protobuf:\"varint,20,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tEnum             []*Any           `protobuf:\"bytes,21,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tMultipleOf       float64          `protobuf:\"fixed64,22,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tVendorExtension  []*NamedAny      `protobuf:\"bytes,23,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *FormDataParameterSubSchema) Reset() {\n\t*x = FormDataParameterSubSchema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[12]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *FormDataParameterSubSchema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*FormDataParameterSubSchema) ProtoMessage() {}\n\nfunc (x *FormDataParameterSubSchema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[12]\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 FormDataParameterSubSchema.ProtoReflect.Descriptor instead.\nfunc (*FormDataParameterSubSchema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{12}\n}\n\nfunc (x *FormDataParameterSubSchema) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *FormDataParameterSubSchema) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *FormDataParameterSubSchema) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *FormDataParameterSubSchema) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *FormDataParameterSubSchema) GetAllowEmptyValue() bool {\n\tif x != nil {\n\t\treturn x.AllowEmptyValue\n\t}\n\treturn false\n}\n\nfunc (x *FormDataParameterSubSchema) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *FormDataParameterSubSchema) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *FormDataParameterSubSchema) GetItems() *PrimitivesItems {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *FormDataParameterSubSchema) GetCollectionFormat() string {\n\tif x != nil {\n\t\treturn x.CollectionFormat\n\t}\n\treturn \"\"\n}\n\nfunc (x *FormDataParameterSubSchema) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *FormDataParameterSubSchema) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *FormDataParameterSubSchema) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *FormDataParameterSubSchema) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *FormDataParameterSubSchema) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *FormDataParameterSubSchema) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *FormDataParameterSubSchema) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *FormDataParameterSubSchema) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *FormDataParameterSubSchema) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *FormDataParameterSubSchema) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *FormDataParameterSubSchema) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *FormDataParameterSubSchema) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *FormDataParameterSubSchema) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *FormDataParameterSubSchema) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Header struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType             string           `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFormat           string           `protobuf:\"bytes,2,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tItems            *PrimitivesItems `protobuf:\"bytes,3,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tCollectionFormat string           `protobuf:\"bytes,4,opt,name=collection_format,json=collectionFormat,proto3\" json:\"collection_format,omitempty\"`\n\tDefault          *Any             `protobuf:\"bytes,5,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tMaximum          float64          `protobuf:\"fixed64,6,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum bool             `protobuf:\"varint,7,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum          float64          `protobuf:\"fixed64,8,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum bool             `protobuf:\"varint,9,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength        int64            `protobuf:\"varint,10,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength        int64            `protobuf:\"varint,11,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern          string           `protobuf:\"bytes,12,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems         int64            `protobuf:\"varint,13,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems         int64            `protobuf:\"varint,14,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems      bool             `protobuf:\"varint,15,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tEnum             []*Any           `protobuf:\"bytes,16,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tMultipleOf       float64          `protobuf:\"fixed64,17,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tDescription      string           `protobuf:\"bytes,18,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVendorExtension  []*NamedAny      `protobuf:\"bytes,19,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Header) Reset() {\n\t*x = Header{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[13]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Header) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Header) ProtoMessage() {}\n\nfunc (x *Header) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[13]\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 Header.ProtoReflect.Descriptor instead.\nfunc (*Header) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{13}\n}\n\nfunc (x *Header) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetItems() *PrimitivesItems {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *Header) GetCollectionFormat() string {\n\tif x != nil {\n\t\treturn x.CollectionFormat\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *Header) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *Header) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *Header) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *Header) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *Header) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *Header) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *Header) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *Header) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *Header) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype HeaderParameterSubSchema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Determines whether or not this parameter is required or optional.\n\tRequired bool `protobuf:\"varint,1,opt,name=required,proto3\" json:\"required,omitempty\"`\n\t// Determines the location of the parameter.\n\tIn string `protobuf:\"bytes,2,opt,name=in,proto3\" json:\"in,omitempty\"`\n\t// A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\t// The name of the parameter.\n\tName             string           `protobuf:\"bytes,4,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tType             string           `protobuf:\"bytes,5,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFormat           string           `protobuf:\"bytes,6,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tItems            *PrimitivesItems `protobuf:\"bytes,7,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tCollectionFormat string           `protobuf:\"bytes,8,opt,name=collection_format,json=collectionFormat,proto3\" json:\"collection_format,omitempty\"`\n\tDefault          *Any             `protobuf:\"bytes,9,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tMaximum          float64          `protobuf:\"fixed64,10,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum bool             `protobuf:\"varint,11,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum          float64          `protobuf:\"fixed64,12,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum bool             `protobuf:\"varint,13,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength        int64            `protobuf:\"varint,14,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength        int64            `protobuf:\"varint,15,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern          string           `protobuf:\"bytes,16,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems         int64            `protobuf:\"varint,17,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems         int64            `protobuf:\"varint,18,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems      bool             `protobuf:\"varint,19,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tEnum             []*Any           `protobuf:\"bytes,20,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tMultipleOf       float64          `protobuf:\"fixed64,21,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tVendorExtension  []*NamedAny      `protobuf:\"bytes,22,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *HeaderParameterSubSchema) Reset() {\n\t*x = HeaderParameterSubSchema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[14]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HeaderParameterSubSchema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HeaderParameterSubSchema) ProtoMessage() {}\n\nfunc (x *HeaderParameterSubSchema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[14]\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 HeaderParameterSubSchema.ProtoReflect.Descriptor instead.\nfunc (*HeaderParameterSubSchema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{14}\n}\n\nfunc (x *HeaderParameterSubSchema) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *HeaderParameterSubSchema) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderParameterSubSchema) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderParameterSubSchema) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderParameterSubSchema) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderParameterSubSchema) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderParameterSubSchema) GetItems() *PrimitivesItems {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderParameterSubSchema) GetCollectionFormat() string {\n\tif x != nil {\n\t\treturn x.CollectionFormat\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderParameterSubSchema) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderParameterSubSchema) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderParameterSubSchema) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *HeaderParameterSubSchema) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderParameterSubSchema) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *HeaderParameterSubSchema) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderParameterSubSchema) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderParameterSubSchema) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *HeaderParameterSubSchema) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderParameterSubSchema) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderParameterSubSchema) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *HeaderParameterSubSchema) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderParameterSubSchema) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *HeaderParameterSubSchema) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Headers struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedHeader `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Headers) Reset() {\n\t*x = Headers{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[15]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Headers) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Headers) ProtoMessage() {}\n\nfunc (x *Headers) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[15]\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 Headers.ProtoReflect.Descriptor instead.\nfunc (*Headers) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{15}\n}\n\nfunc (x *Headers) GetAdditionalProperties() []*NamedHeader {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// General information about the API.\ntype Info struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// A unique and precise title of the API.\n\tTitle string `protobuf:\"bytes,1,opt,name=title,proto3\" json:\"title,omitempty\"`\n\t// A semantic version number of the API.\n\tVersion string `protobuf:\"bytes,2,opt,name=version,proto3\" json:\"version,omitempty\"`\n\t// A longer description of the API. Should be different from the title.  GitHub Flavored Markdown is allowed.\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\t// The terms of service for the API.\n\tTermsOfService  string      `protobuf:\"bytes,4,opt,name=terms_of_service,json=termsOfService,proto3\" json:\"terms_of_service,omitempty\"`\n\tContact         *Contact    `protobuf:\"bytes,5,opt,name=contact,proto3\" json:\"contact,omitempty\"`\n\tLicense         *License    `protobuf:\"bytes,6,opt,name=license,proto3\" json:\"license,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,7,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Info) Reset() {\n\t*x = Info{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[16]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Info) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Info) ProtoMessage() {}\n\nfunc (x *Info) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[16]\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 Info.ProtoReflect.Descriptor instead.\nfunc (*Info) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{16}\n}\n\nfunc (x *Info) GetTitle() string {\n\tif x != nil {\n\t\treturn x.Title\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetVersion() string {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetTermsOfService() string {\n\tif x != nil {\n\t\treturn x.TermsOfService\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetContact() *Contact {\n\tif x != nil {\n\t\treturn x.Contact\n\t}\n\treturn nil\n}\n\nfunc (x *Info) GetLicense() *License {\n\tif x != nil {\n\t\treturn x.License\n\t}\n\treturn nil\n}\n\nfunc (x *Info) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype ItemsItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSchema []*Schema `protobuf:\"bytes,1,rep,name=schema,proto3\" json:\"schema,omitempty\"`\n}\n\nfunc (x *ItemsItem) Reset() {\n\t*x = ItemsItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[17]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ItemsItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ItemsItem) ProtoMessage() {}\n\nfunc (x *ItemsItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[17]\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 ItemsItem.ProtoReflect.Descriptor instead.\nfunc (*ItemsItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{17}\n}\n\nfunc (x *ItemsItem) GetSchema() []*Schema {\n\tif x != nil {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\ntype JsonReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tXRef        string `protobuf:\"bytes,1,opt,name=_ref,json=Ref,proto3\" json:\"_ref,omitempty\"`\n\tDescription string `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n}\n\nfunc (x *JsonReference) Reset() {\n\t*x = JsonReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[18]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *JsonReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*JsonReference) ProtoMessage() {}\n\nfunc (x *JsonReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[18]\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 JsonReference.ProtoReflect.Descriptor instead.\nfunc (*JsonReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{18}\n}\n\nfunc (x *JsonReference) GetXRef() string {\n\tif x != nil {\n\t\treturn x.XRef\n\t}\n\treturn \"\"\n}\n\nfunc (x *JsonReference) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\ntype License struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// The name of the license type. It's encouraged to use an OSI compatible license.\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// The URL pointing to the license.\n\tUrl             string      `protobuf:\"bytes,2,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,3,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *License) Reset() {\n\t*x = License{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[19]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *License) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*License) ProtoMessage() {}\n\nfunc (x *License) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[19]\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 License.ProtoReflect.Descriptor instead.\nfunc (*License) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{19}\n}\n\nfunc (x *License) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *License) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *License) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs.\ntype NamedAny struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *Any `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedAny) Reset() {\n\t*x = NamedAny{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[20]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedAny) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedAny) ProtoMessage() {}\n\nfunc (x *NamedAny) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[20]\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 NamedAny.ProtoReflect.Descriptor instead.\nfunc (*NamedAny) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{20}\n}\n\nfunc (x *NamedAny) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedAny) GetValue() *Any {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of Header as ordered (name,value) pairs.\ntype NamedHeader struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *Header `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedHeader) Reset() {\n\t*x = NamedHeader{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[21]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedHeader) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedHeader) ProtoMessage() {}\n\nfunc (x *NamedHeader) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[21]\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 NamedHeader.ProtoReflect.Descriptor instead.\nfunc (*NamedHeader) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{21}\n}\n\nfunc (x *NamedHeader) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedHeader) GetValue() *Header {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of Parameter as ordered (name,value) pairs.\ntype NamedParameter struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *Parameter `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedParameter) Reset() {\n\t*x = NamedParameter{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[22]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedParameter) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedParameter) ProtoMessage() {}\n\nfunc (x *NamedParameter) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[22]\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 NamedParameter.ProtoReflect.Descriptor instead.\nfunc (*NamedParameter) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{22}\n}\n\nfunc (x *NamedParameter) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedParameter) GetValue() *Parameter {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs.\ntype NamedPathItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *PathItem `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedPathItem) Reset() {\n\t*x = NamedPathItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[23]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedPathItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedPathItem) ProtoMessage() {}\n\nfunc (x *NamedPathItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[23]\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 NamedPathItem.ProtoReflect.Descriptor instead.\nfunc (*NamedPathItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{23}\n}\n\nfunc (x *NamedPathItem) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedPathItem) GetValue() *PathItem {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of Response as ordered (name,value) pairs.\ntype NamedResponse struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *Response `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedResponse) Reset() {\n\t*x = NamedResponse{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[24]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedResponse) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedResponse) ProtoMessage() {}\n\nfunc (x *NamedResponse) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[24]\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 NamedResponse.ProtoReflect.Descriptor instead.\nfunc (*NamedResponse) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{24}\n}\n\nfunc (x *NamedResponse) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedResponse) GetValue() *Response {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of ResponseValue as ordered (name,value) pairs.\ntype NamedResponseValue struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *ResponseValue `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedResponseValue) Reset() {\n\t*x = NamedResponseValue{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[25]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedResponseValue) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedResponseValue) ProtoMessage() {}\n\nfunc (x *NamedResponseValue) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[25]\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 NamedResponseValue.ProtoReflect.Descriptor instead.\nfunc (*NamedResponseValue) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{25}\n}\n\nfunc (x *NamedResponseValue) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedResponseValue) GetValue() *ResponseValue {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of Schema as ordered (name,value) pairs.\ntype NamedSchema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *Schema `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedSchema) Reset() {\n\t*x = NamedSchema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[26]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedSchema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedSchema) ProtoMessage() {}\n\nfunc (x *NamedSchema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[26]\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 NamedSchema.ProtoReflect.Descriptor instead.\nfunc (*NamedSchema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{26}\n}\n\nfunc (x *NamedSchema) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedSchema) GetValue() *Schema {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of SecurityDefinitionsItem as ordered (name,value) pairs.\ntype NamedSecurityDefinitionsItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *SecurityDefinitionsItem `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedSecurityDefinitionsItem) Reset() {\n\t*x = NamedSecurityDefinitionsItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[27]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedSecurityDefinitionsItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedSecurityDefinitionsItem) ProtoMessage() {}\n\nfunc (x *NamedSecurityDefinitionsItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[27]\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 NamedSecurityDefinitionsItem.ProtoReflect.Descriptor instead.\nfunc (*NamedSecurityDefinitionsItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{27}\n}\n\nfunc (x *NamedSecurityDefinitionsItem) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedSecurityDefinitionsItem) GetValue() *SecurityDefinitionsItem {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of string as ordered (name,value) pairs.\ntype NamedString struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue string `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedString) Reset() {\n\t*x = NamedString{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[28]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedString) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedString) ProtoMessage() {}\n\nfunc (x *NamedString) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[28]\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 NamedString.ProtoReflect.Descriptor instead.\nfunc (*NamedString) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{28}\n}\n\nfunc (x *NamedString) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedString) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\n// Automatically-generated message used to represent maps of StringArray as ordered (name,value) pairs.\ntype NamedStringArray struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *StringArray `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedStringArray) Reset() {\n\t*x = NamedStringArray{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[29]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedStringArray) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedStringArray) ProtoMessage() {}\n\nfunc (x *NamedStringArray) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[29]\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 NamedStringArray.ProtoReflect.Descriptor instead.\nfunc (*NamedStringArray) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{29}\n}\n\nfunc (x *NamedStringArray) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedStringArray) GetValue() *StringArray {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\ntype NonBodyParameter struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*NonBodyParameter_HeaderParameterSubSchema\n\t//\t*NonBodyParameter_FormDataParameterSubSchema\n\t//\t*NonBodyParameter_QueryParameterSubSchema\n\t//\t*NonBodyParameter_PathParameterSubSchema\n\tOneof isNonBodyParameter_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *NonBodyParameter) Reset() {\n\t*x = NonBodyParameter{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[30]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NonBodyParameter) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NonBodyParameter) ProtoMessage() {}\n\nfunc (x *NonBodyParameter) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[30]\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 NonBodyParameter.ProtoReflect.Descriptor instead.\nfunc (*NonBodyParameter) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{30}\n}\n\nfunc (m *NonBodyParameter) GetOneof() isNonBodyParameter_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *NonBodyParameter) GetHeaderParameterSubSchema() *HeaderParameterSubSchema {\n\tif x, ok := x.GetOneof().(*NonBodyParameter_HeaderParameterSubSchema); ok {\n\t\treturn x.HeaderParameterSubSchema\n\t}\n\treturn nil\n}\n\nfunc (x *NonBodyParameter) GetFormDataParameterSubSchema() *FormDataParameterSubSchema {\n\tif x, ok := x.GetOneof().(*NonBodyParameter_FormDataParameterSubSchema); ok {\n\t\treturn x.FormDataParameterSubSchema\n\t}\n\treturn nil\n}\n\nfunc (x *NonBodyParameter) GetQueryParameterSubSchema() *QueryParameterSubSchema {\n\tif x, ok := x.GetOneof().(*NonBodyParameter_QueryParameterSubSchema); ok {\n\t\treturn x.QueryParameterSubSchema\n\t}\n\treturn nil\n}\n\nfunc (x *NonBodyParameter) GetPathParameterSubSchema() *PathParameterSubSchema {\n\tif x, ok := x.GetOneof().(*NonBodyParameter_PathParameterSubSchema); ok {\n\t\treturn x.PathParameterSubSchema\n\t}\n\treturn nil\n}\n\ntype isNonBodyParameter_Oneof interface {\n\tisNonBodyParameter_Oneof()\n}\n\ntype NonBodyParameter_HeaderParameterSubSchema struct {\n\tHeaderParameterSubSchema *HeaderParameterSubSchema `protobuf:\"bytes,1,opt,name=header_parameter_sub_schema,json=headerParameterSubSchema,proto3,oneof\"`\n}\n\ntype NonBodyParameter_FormDataParameterSubSchema struct {\n\tFormDataParameterSubSchema *FormDataParameterSubSchema `protobuf:\"bytes,2,opt,name=form_data_parameter_sub_schema,json=formDataParameterSubSchema,proto3,oneof\"`\n}\n\ntype NonBodyParameter_QueryParameterSubSchema struct {\n\tQueryParameterSubSchema *QueryParameterSubSchema `protobuf:\"bytes,3,opt,name=query_parameter_sub_schema,json=queryParameterSubSchema,proto3,oneof\"`\n}\n\ntype NonBodyParameter_PathParameterSubSchema struct {\n\tPathParameterSubSchema *PathParameterSubSchema `protobuf:\"bytes,4,opt,name=path_parameter_sub_schema,json=pathParameterSubSchema,proto3,oneof\"`\n}\n\nfunc (*NonBodyParameter_HeaderParameterSubSchema) isNonBodyParameter_Oneof() {}\n\nfunc (*NonBodyParameter_FormDataParameterSubSchema) isNonBodyParameter_Oneof() {}\n\nfunc (*NonBodyParameter_QueryParameterSubSchema) isNonBodyParameter_Oneof() {}\n\nfunc (*NonBodyParameter_PathParameterSubSchema) isNonBodyParameter_Oneof() {}\n\ntype Oauth2AccessCodeSecurity struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType             string        `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFlow             string        `protobuf:\"bytes,2,opt,name=flow,proto3\" json:\"flow,omitempty\"`\n\tScopes           *Oauth2Scopes `protobuf:\"bytes,3,opt,name=scopes,proto3\" json:\"scopes,omitempty\"`\n\tAuthorizationUrl string        `protobuf:\"bytes,4,opt,name=authorization_url,json=authorizationUrl,proto3\" json:\"authorization_url,omitempty\"`\n\tTokenUrl         string        `protobuf:\"bytes,5,opt,name=token_url,json=tokenUrl,proto3\" json:\"token_url,omitempty\"`\n\tDescription      string        `protobuf:\"bytes,6,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVendorExtension  []*NamedAny   `protobuf:\"bytes,7,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Oauth2AccessCodeSecurity) Reset() {\n\t*x = Oauth2AccessCodeSecurity{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[31]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Oauth2AccessCodeSecurity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Oauth2AccessCodeSecurity) ProtoMessage() {}\n\nfunc (x *Oauth2AccessCodeSecurity) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[31]\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 Oauth2AccessCodeSecurity.ProtoReflect.Descriptor instead.\nfunc (*Oauth2AccessCodeSecurity) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{31}\n}\n\nfunc (x *Oauth2AccessCodeSecurity) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2AccessCodeSecurity) GetFlow() string {\n\tif x != nil {\n\t\treturn x.Flow\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2AccessCodeSecurity) GetScopes() *Oauth2Scopes {\n\tif x != nil {\n\t\treturn x.Scopes\n\t}\n\treturn nil\n}\n\nfunc (x *Oauth2AccessCodeSecurity) GetAuthorizationUrl() string {\n\tif x != nil {\n\t\treturn x.AuthorizationUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2AccessCodeSecurity) GetTokenUrl() string {\n\tif x != nil {\n\t\treturn x.TokenUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2AccessCodeSecurity) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2AccessCodeSecurity) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Oauth2ApplicationSecurity struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType            string        `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFlow            string        `protobuf:\"bytes,2,opt,name=flow,proto3\" json:\"flow,omitempty\"`\n\tScopes          *Oauth2Scopes `protobuf:\"bytes,3,opt,name=scopes,proto3\" json:\"scopes,omitempty\"`\n\tTokenUrl        string        `protobuf:\"bytes,4,opt,name=token_url,json=tokenUrl,proto3\" json:\"token_url,omitempty\"`\n\tDescription     string        `protobuf:\"bytes,5,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVendorExtension []*NamedAny   `protobuf:\"bytes,6,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Oauth2ApplicationSecurity) Reset() {\n\t*x = Oauth2ApplicationSecurity{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[32]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Oauth2ApplicationSecurity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Oauth2ApplicationSecurity) ProtoMessage() {}\n\nfunc (x *Oauth2ApplicationSecurity) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[32]\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 Oauth2ApplicationSecurity.ProtoReflect.Descriptor instead.\nfunc (*Oauth2ApplicationSecurity) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{32}\n}\n\nfunc (x *Oauth2ApplicationSecurity) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ApplicationSecurity) GetFlow() string {\n\tif x != nil {\n\t\treturn x.Flow\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ApplicationSecurity) GetScopes() *Oauth2Scopes {\n\tif x != nil {\n\t\treturn x.Scopes\n\t}\n\treturn nil\n}\n\nfunc (x *Oauth2ApplicationSecurity) GetTokenUrl() string {\n\tif x != nil {\n\t\treturn x.TokenUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ApplicationSecurity) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ApplicationSecurity) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Oauth2ImplicitSecurity struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType             string        `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFlow             string        `protobuf:\"bytes,2,opt,name=flow,proto3\" json:\"flow,omitempty\"`\n\tScopes           *Oauth2Scopes `protobuf:\"bytes,3,opt,name=scopes,proto3\" json:\"scopes,omitempty\"`\n\tAuthorizationUrl string        `protobuf:\"bytes,4,opt,name=authorization_url,json=authorizationUrl,proto3\" json:\"authorization_url,omitempty\"`\n\tDescription      string        `protobuf:\"bytes,5,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVendorExtension  []*NamedAny   `protobuf:\"bytes,6,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Oauth2ImplicitSecurity) Reset() {\n\t*x = Oauth2ImplicitSecurity{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[33]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Oauth2ImplicitSecurity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Oauth2ImplicitSecurity) ProtoMessage() {}\n\nfunc (x *Oauth2ImplicitSecurity) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[33]\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 Oauth2ImplicitSecurity.ProtoReflect.Descriptor instead.\nfunc (*Oauth2ImplicitSecurity) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{33}\n}\n\nfunc (x *Oauth2ImplicitSecurity) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ImplicitSecurity) GetFlow() string {\n\tif x != nil {\n\t\treturn x.Flow\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ImplicitSecurity) GetScopes() *Oauth2Scopes {\n\tif x != nil {\n\t\treturn x.Scopes\n\t}\n\treturn nil\n}\n\nfunc (x *Oauth2ImplicitSecurity) GetAuthorizationUrl() string {\n\tif x != nil {\n\t\treturn x.AuthorizationUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ImplicitSecurity) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2ImplicitSecurity) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Oauth2PasswordSecurity struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType            string        `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFlow            string        `protobuf:\"bytes,2,opt,name=flow,proto3\" json:\"flow,omitempty\"`\n\tScopes          *Oauth2Scopes `protobuf:\"bytes,3,opt,name=scopes,proto3\" json:\"scopes,omitempty\"`\n\tTokenUrl        string        `protobuf:\"bytes,4,opt,name=token_url,json=tokenUrl,proto3\" json:\"token_url,omitempty\"`\n\tDescription     string        `protobuf:\"bytes,5,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVendorExtension []*NamedAny   `protobuf:\"bytes,6,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Oauth2PasswordSecurity) Reset() {\n\t*x = Oauth2PasswordSecurity{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[34]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Oauth2PasswordSecurity) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Oauth2PasswordSecurity) ProtoMessage() {}\n\nfunc (x *Oauth2PasswordSecurity) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[34]\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 Oauth2PasswordSecurity.ProtoReflect.Descriptor instead.\nfunc (*Oauth2PasswordSecurity) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{34}\n}\n\nfunc (x *Oauth2PasswordSecurity) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2PasswordSecurity) GetFlow() string {\n\tif x != nil {\n\t\treturn x.Flow\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2PasswordSecurity) GetScopes() *Oauth2Scopes {\n\tif x != nil {\n\t\treturn x.Scopes\n\t}\n\treturn nil\n}\n\nfunc (x *Oauth2PasswordSecurity) GetTokenUrl() string {\n\tif x != nil {\n\t\treturn x.TokenUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2PasswordSecurity) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Oauth2PasswordSecurity) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Oauth2Scopes struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedString `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Oauth2Scopes) Reset() {\n\t*x = Oauth2Scopes{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[35]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Oauth2Scopes) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Oauth2Scopes) ProtoMessage() {}\n\nfunc (x *Oauth2Scopes) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[35]\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 Oauth2Scopes.ProtoReflect.Descriptor instead.\nfunc (*Oauth2Scopes) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{35}\n}\n\nfunc (x *Oauth2Scopes) GetAdditionalProperties() []*NamedString {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype Operation struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tTags []string `protobuf:\"bytes,1,rep,name=tags,proto3\" json:\"tags,omitempty\"`\n\t// A brief summary of the operation.\n\tSummary string `protobuf:\"bytes,2,opt,name=summary,proto3\" json:\"summary,omitempty\"`\n\t// A longer description of the operation, GitHub Flavored Markdown is allowed.\n\tDescription  string        `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tExternalDocs *ExternalDocs `protobuf:\"bytes,4,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\t// A unique identifier of the operation.\n\tOperationId string `protobuf:\"bytes,5,opt,name=operation_id,json=operationId,proto3\" json:\"operation_id,omitempty\"`\n\t// A list of MIME types the API can produce.\n\tProduces []string `protobuf:\"bytes,6,rep,name=produces,proto3\" json:\"produces,omitempty\"`\n\t// A list of MIME types the API can consume.\n\tConsumes []string `protobuf:\"bytes,7,rep,name=consumes,proto3\" json:\"consumes,omitempty\"`\n\t// The parameters needed to send a valid API call.\n\tParameters []*ParametersItem `protobuf:\"bytes,8,rep,name=parameters,proto3\" json:\"parameters,omitempty\"`\n\tResponses  *Responses        `protobuf:\"bytes,9,opt,name=responses,proto3\" json:\"responses,omitempty\"`\n\t// The transfer protocol of the API.\n\tSchemes         []string               `protobuf:\"bytes,10,rep,name=schemes,proto3\" json:\"schemes,omitempty\"`\n\tDeprecated      bool                   `protobuf:\"varint,11,opt,name=deprecated,proto3\" json:\"deprecated,omitempty\"`\n\tSecurity        []*SecurityRequirement `protobuf:\"bytes,12,rep,name=security,proto3\" json:\"security,omitempty\"`\n\tVendorExtension []*NamedAny            `protobuf:\"bytes,13,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Operation) Reset() {\n\t*x = Operation{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[36]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Operation) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Operation) ProtoMessage() {}\n\nfunc (x *Operation) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[36]\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 Operation.ProtoReflect.Descriptor instead.\nfunc (*Operation) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{36}\n}\n\nfunc (x *Operation) GetTags() []string {\n\tif x != nil {\n\t\treturn x.Tags\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetSummary() string {\n\tif x != nil {\n\t\treturn x.Summary\n\t}\n\treturn \"\"\n}\n\nfunc (x *Operation) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Operation) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetOperationId() string {\n\tif x != nil {\n\t\treturn x.OperationId\n\t}\n\treturn \"\"\n}\n\nfunc (x *Operation) GetProduces() []string {\n\tif x != nil {\n\t\treturn x.Produces\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetConsumes() []string {\n\tif x != nil {\n\t\treturn x.Consumes\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetParameters() []*ParametersItem {\n\tif x != nil {\n\t\treturn x.Parameters\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetResponses() *Responses {\n\tif x != nil {\n\t\treturn x.Responses\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetSchemes() []string {\n\tif x != nil {\n\t\treturn x.Schemes\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetDeprecated() bool {\n\tif x != nil {\n\t\treturn x.Deprecated\n\t}\n\treturn false\n}\n\nfunc (x *Operation) GetSecurity() []*SecurityRequirement {\n\tif x != nil {\n\t\treturn x.Security\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Parameter struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*Parameter_BodyParameter\n\t//\t*Parameter_NonBodyParameter\n\tOneof isParameter_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *Parameter) Reset() {\n\t*x = Parameter{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[37]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Parameter) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Parameter) ProtoMessage() {}\n\nfunc (x *Parameter) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[37]\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 Parameter.ProtoReflect.Descriptor instead.\nfunc (*Parameter) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{37}\n}\n\nfunc (m *Parameter) GetOneof() isParameter_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *Parameter) GetBodyParameter() *BodyParameter {\n\tif x, ok := x.GetOneof().(*Parameter_BodyParameter); ok {\n\t\treturn x.BodyParameter\n\t}\n\treturn nil\n}\n\nfunc (x *Parameter) GetNonBodyParameter() *NonBodyParameter {\n\tif x, ok := x.GetOneof().(*Parameter_NonBodyParameter); ok {\n\t\treturn x.NonBodyParameter\n\t}\n\treturn nil\n}\n\ntype isParameter_Oneof interface {\n\tisParameter_Oneof()\n}\n\ntype Parameter_BodyParameter struct {\n\tBodyParameter *BodyParameter `protobuf:\"bytes,1,opt,name=body_parameter,json=bodyParameter,proto3,oneof\"`\n}\n\ntype Parameter_NonBodyParameter struct {\n\tNonBodyParameter *NonBodyParameter `protobuf:\"bytes,2,opt,name=non_body_parameter,json=nonBodyParameter,proto3,oneof\"`\n}\n\nfunc (*Parameter_BodyParameter) isParameter_Oneof() {}\n\nfunc (*Parameter_NonBodyParameter) isParameter_Oneof() {}\n\n// One or more JSON representations for parameters\ntype ParameterDefinitions struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedParameter `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *ParameterDefinitions) Reset() {\n\t*x = ParameterDefinitions{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[38]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ParameterDefinitions) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ParameterDefinitions) ProtoMessage() {}\n\nfunc (x *ParameterDefinitions) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[38]\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 ParameterDefinitions.ProtoReflect.Descriptor instead.\nfunc (*ParameterDefinitions) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{38}\n}\n\nfunc (x *ParameterDefinitions) GetAdditionalProperties() []*NamedParameter {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype ParametersItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*ParametersItem_Parameter\n\t//\t*ParametersItem_JsonReference\n\tOneof isParametersItem_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *ParametersItem) Reset() {\n\t*x = ParametersItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[39]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ParametersItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ParametersItem) ProtoMessage() {}\n\nfunc (x *ParametersItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[39]\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 ParametersItem.ProtoReflect.Descriptor instead.\nfunc (*ParametersItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{39}\n}\n\nfunc (m *ParametersItem) GetOneof() isParametersItem_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *ParametersItem) GetParameter() *Parameter {\n\tif x, ok := x.GetOneof().(*ParametersItem_Parameter); ok {\n\t\treturn x.Parameter\n\t}\n\treturn nil\n}\n\nfunc (x *ParametersItem) GetJsonReference() *JsonReference {\n\tif x, ok := x.GetOneof().(*ParametersItem_JsonReference); ok {\n\t\treturn x.JsonReference\n\t}\n\treturn nil\n}\n\ntype isParametersItem_Oneof interface {\n\tisParametersItem_Oneof()\n}\n\ntype ParametersItem_Parameter struct {\n\tParameter *Parameter `protobuf:\"bytes,1,opt,name=parameter,proto3,oneof\"`\n}\n\ntype ParametersItem_JsonReference struct {\n\tJsonReference *JsonReference `protobuf:\"bytes,2,opt,name=json_reference,json=jsonReference,proto3,oneof\"`\n}\n\nfunc (*ParametersItem_Parameter) isParametersItem_Oneof() {}\n\nfunc (*ParametersItem_JsonReference) isParametersItem_Oneof() {}\n\ntype PathItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tXRef    string     `protobuf:\"bytes,1,opt,name=_ref,json=Ref,proto3\" json:\"_ref,omitempty\"`\n\tGet     *Operation `protobuf:\"bytes,2,opt,name=get,proto3\" json:\"get,omitempty\"`\n\tPut     *Operation `protobuf:\"bytes,3,opt,name=put,proto3\" json:\"put,omitempty\"`\n\tPost    *Operation `protobuf:\"bytes,4,opt,name=post,proto3\" json:\"post,omitempty\"`\n\tDelete  *Operation `protobuf:\"bytes,5,opt,name=delete,proto3\" json:\"delete,omitempty\"`\n\tOptions *Operation `protobuf:\"bytes,6,opt,name=options,proto3\" json:\"options,omitempty\"`\n\tHead    *Operation `protobuf:\"bytes,7,opt,name=head,proto3\" json:\"head,omitempty\"`\n\tPatch   *Operation `protobuf:\"bytes,8,opt,name=patch,proto3\" json:\"patch,omitempty\"`\n\t// The parameters needed to send a valid API call.\n\tParameters      []*ParametersItem `protobuf:\"bytes,9,rep,name=parameters,proto3\" json:\"parameters,omitempty\"`\n\tVendorExtension []*NamedAny       `protobuf:\"bytes,10,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *PathItem) Reset() {\n\t*x = PathItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[40]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *PathItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PathItem) ProtoMessage() {}\n\nfunc (x *PathItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[40]\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 PathItem.ProtoReflect.Descriptor instead.\nfunc (*PathItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{40}\n}\n\nfunc (x *PathItem) GetXRef() string {\n\tif x != nil {\n\t\treturn x.XRef\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathItem) GetGet() *Operation {\n\tif x != nil {\n\t\treturn x.Get\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetPut() *Operation {\n\tif x != nil {\n\t\treturn x.Put\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetPost() *Operation {\n\tif x != nil {\n\t\treturn x.Post\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetDelete() *Operation {\n\tif x != nil {\n\t\treturn x.Delete\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetOptions() *Operation {\n\tif x != nil {\n\t\treturn x.Options\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetHead() *Operation {\n\tif x != nil {\n\t\treturn x.Head\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetPatch() *Operation {\n\tif x != nil {\n\t\treturn x.Patch\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetParameters() []*ParametersItem {\n\tif x != nil {\n\t\treturn x.Parameters\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype PathParameterSubSchema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Determines whether or not this parameter is required or optional.\n\tRequired bool `protobuf:\"varint,1,opt,name=required,proto3\" json:\"required,omitempty\"`\n\t// Determines the location of the parameter.\n\tIn string `protobuf:\"bytes,2,opt,name=in,proto3\" json:\"in,omitempty\"`\n\t// A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\t// The name of the parameter.\n\tName             string           `protobuf:\"bytes,4,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tType             string           `protobuf:\"bytes,5,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFormat           string           `protobuf:\"bytes,6,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tItems            *PrimitivesItems `protobuf:\"bytes,7,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tCollectionFormat string           `protobuf:\"bytes,8,opt,name=collection_format,json=collectionFormat,proto3\" json:\"collection_format,omitempty\"`\n\tDefault          *Any             `protobuf:\"bytes,9,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tMaximum          float64          `protobuf:\"fixed64,10,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum bool             `protobuf:\"varint,11,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum          float64          `protobuf:\"fixed64,12,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum bool             `protobuf:\"varint,13,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength        int64            `protobuf:\"varint,14,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength        int64            `protobuf:\"varint,15,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern          string           `protobuf:\"bytes,16,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems         int64            `protobuf:\"varint,17,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems         int64            `protobuf:\"varint,18,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems      bool             `protobuf:\"varint,19,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tEnum             []*Any           `protobuf:\"bytes,20,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tMultipleOf       float64          `protobuf:\"fixed64,21,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tVendorExtension  []*NamedAny      `protobuf:\"bytes,22,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *PathParameterSubSchema) Reset() {\n\t*x = PathParameterSubSchema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[41]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *PathParameterSubSchema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PathParameterSubSchema) ProtoMessage() {}\n\nfunc (x *PathParameterSubSchema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[41]\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 PathParameterSubSchema.ProtoReflect.Descriptor instead.\nfunc (*PathParameterSubSchema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{41}\n}\n\nfunc (x *PathParameterSubSchema) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *PathParameterSubSchema) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathParameterSubSchema) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathParameterSubSchema) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathParameterSubSchema) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathParameterSubSchema) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathParameterSubSchema) GetItems() *PrimitivesItems {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *PathParameterSubSchema) GetCollectionFormat() string {\n\tif x != nil {\n\t\treturn x.CollectionFormat\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathParameterSubSchema) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *PathParameterSubSchema) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *PathParameterSubSchema) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *PathParameterSubSchema) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *PathParameterSubSchema) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *PathParameterSubSchema) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *PathParameterSubSchema) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *PathParameterSubSchema) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathParameterSubSchema) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *PathParameterSubSchema) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *PathParameterSubSchema) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *PathParameterSubSchema) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *PathParameterSubSchema) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *PathParameterSubSchema) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\n// Relative paths to the individual endpoints. They must be relative to the 'basePath'.\ntype Paths struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tVendorExtension []*NamedAny      `protobuf:\"bytes,1,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n\tPath            []*NamedPathItem `protobuf:\"bytes,2,rep,name=path,proto3\" json:\"path,omitempty\"`\n}\n\nfunc (x *Paths) Reset() {\n\t*x = Paths{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[42]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Paths) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Paths) ProtoMessage() {}\n\nfunc (x *Paths) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[42]\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 Paths.ProtoReflect.Descriptor instead.\nfunc (*Paths) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{42}\n}\n\nfunc (x *Paths) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\nfunc (x *Paths) GetPath() []*NamedPathItem {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn nil\n}\n\ntype PrimitivesItems struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType             string           `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFormat           string           `protobuf:\"bytes,2,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tItems            *PrimitivesItems `protobuf:\"bytes,3,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tCollectionFormat string           `protobuf:\"bytes,4,opt,name=collection_format,json=collectionFormat,proto3\" json:\"collection_format,omitempty\"`\n\tDefault          *Any             `protobuf:\"bytes,5,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tMaximum          float64          `protobuf:\"fixed64,6,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum bool             `protobuf:\"varint,7,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum          float64          `protobuf:\"fixed64,8,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum bool             `protobuf:\"varint,9,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength        int64            `protobuf:\"varint,10,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength        int64            `protobuf:\"varint,11,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern          string           `protobuf:\"bytes,12,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems         int64            `protobuf:\"varint,13,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems         int64            `protobuf:\"varint,14,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems      bool             `protobuf:\"varint,15,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tEnum             []*Any           `protobuf:\"bytes,16,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tMultipleOf       float64          `protobuf:\"fixed64,17,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tVendorExtension  []*NamedAny      `protobuf:\"bytes,18,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *PrimitivesItems) Reset() {\n\t*x = PrimitivesItems{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[43]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *PrimitivesItems) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PrimitivesItems) ProtoMessage() {}\n\nfunc (x *PrimitivesItems) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[43]\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 PrimitivesItems.ProtoReflect.Descriptor instead.\nfunc (*PrimitivesItems) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{43}\n}\n\nfunc (x *PrimitivesItems) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *PrimitivesItems) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *PrimitivesItems) GetItems() *PrimitivesItems {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitivesItems) GetCollectionFormat() string {\n\tif x != nil {\n\t\treturn x.CollectionFormat\n\t}\n\treturn \"\"\n}\n\nfunc (x *PrimitivesItems) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitivesItems) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *PrimitivesItems) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *PrimitivesItems) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *PrimitivesItems) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *PrimitivesItems) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *PrimitivesItems) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *PrimitivesItems) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *PrimitivesItems) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *PrimitivesItems) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *PrimitivesItems) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *PrimitivesItems) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *PrimitivesItems) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *PrimitivesItems) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Properties struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedSchema `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Properties) Reset() {\n\t*x = Properties{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[44]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Properties) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Properties) ProtoMessage() {}\n\nfunc (x *Properties) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[44]\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 Properties.ProtoReflect.Descriptor instead.\nfunc (*Properties) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{44}\n}\n\nfunc (x *Properties) GetAdditionalProperties() []*NamedSchema {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype QueryParameterSubSchema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Determines whether or not this parameter is required or optional.\n\tRequired bool `protobuf:\"varint,1,opt,name=required,proto3\" json:\"required,omitempty\"`\n\t// Determines the location of the parameter.\n\tIn string `protobuf:\"bytes,2,opt,name=in,proto3\" json:\"in,omitempty\"`\n\t// A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\t// The name of the parameter.\n\tName string `protobuf:\"bytes,4,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// allows sending a parameter by name only or with an empty value.\n\tAllowEmptyValue  bool             `protobuf:\"varint,5,opt,name=allow_empty_value,json=allowEmptyValue,proto3\" json:\"allow_empty_value,omitempty\"`\n\tType             string           `protobuf:\"bytes,6,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tFormat           string           `protobuf:\"bytes,7,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tItems            *PrimitivesItems `protobuf:\"bytes,8,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tCollectionFormat string           `protobuf:\"bytes,9,opt,name=collection_format,json=collectionFormat,proto3\" json:\"collection_format,omitempty\"`\n\tDefault          *Any             `protobuf:\"bytes,10,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tMaximum          float64          `protobuf:\"fixed64,11,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum bool             `protobuf:\"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum          float64          `protobuf:\"fixed64,13,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum bool             `protobuf:\"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength        int64            `protobuf:\"varint,15,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength        int64            `protobuf:\"varint,16,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern          string           `protobuf:\"bytes,17,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems         int64            `protobuf:\"varint,18,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems         int64            `protobuf:\"varint,19,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems      bool             `protobuf:\"varint,20,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tEnum             []*Any           `protobuf:\"bytes,21,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tMultipleOf       float64          `protobuf:\"fixed64,22,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tVendorExtension  []*NamedAny      `protobuf:\"bytes,23,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *QueryParameterSubSchema) Reset() {\n\t*x = QueryParameterSubSchema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[45]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *QueryParameterSubSchema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*QueryParameterSubSchema) ProtoMessage() {}\n\nfunc (x *QueryParameterSubSchema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[45]\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 QueryParameterSubSchema.ProtoReflect.Descriptor instead.\nfunc (*QueryParameterSubSchema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{45}\n}\n\nfunc (x *QueryParameterSubSchema) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *QueryParameterSubSchema) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryParameterSubSchema) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryParameterSubSchema) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryParameterSubSchema) GetAllowEmptyValue() bool {\n\tif x != nil {\n\t\treturn x.AllowEmptyValue\n\t}\n\treturn false\n}\n\nfunc (x *QueryParameterSubSchema) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryParameterSubSchema) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryParameterSubSchema) GetItems() *PrimitivesItems {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *QueryParameterSubSchema) GetCollectionFormat() string {\n\tif x != nil {\n\t\treturn x.CollectionFormat\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryParameterSubSchema) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *QueryParameterSubSchema) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *QueryParameterSubSchema) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *QueryParameterSubSchema) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *QueryParameterSubSchema) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *QueryParameterSubSchema) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *QueryParameterSubSchema) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *QueryParameterSubSchema) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *QueryParameterSubSchema) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *QueryParameterSubSchema) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *QueryParameterSubSchema) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *QueryParameterSubSchema) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *QueryParameterSubSchema) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *QueryParameterSubSchema) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype Response struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tDescription     string      `protobuf:\"bytes,1,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tSchema          *SchemaItem `protobuf:\"bytes,2,opt,name=schema,proto3\" json:\"schema,omitempty\"`\n\tHeaders         *Headers    `protobuf:\"bytes,3,opt,name=headers,proto3\" json:\"headers,omitempty\"`\n\tExamples        *Examples   `protobuf:\"bytes,4,opt,name=examples,proto3\" json:\"examples,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,5,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Response) Reset() {\n\t*x = Response{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[46]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Response) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Response) ProtoMessage() {}\n\nfunc (x *Response) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[46]\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 Response.ProtoReflect.Descriptor instead.\nfunc (*Response) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{46}\n}\n\nfunc (x *Response) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Response) GetSchema() *SchemaItem {\n\tif x != nil {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *Response) GetHeaders() *Headers {\n\tif x != nil {\n\t\treturn x.Headers\n\t}\n\treturn nil\n}\n\nfunc (x *Response) GetExamples() *Examples {\n\tif x != nil {\n\t\treturn x.Examples\n\t}\n\treturn nil\n}\n\nfunc (x *Response) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\n// One or more JSON representations for responses\ntype ResponseDefinitions struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedResponse `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *ResponseDefinitions) Reset() {\n\t*x = ResponseDefinitions{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[47]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ResponseDefinitions) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ResponseDefinitions) ProtoMessage() {}\n\nfunc (x *ResponseDefinitions) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[47]\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 ResponseDefinitions.ProtoReflect.Descriptor instead.\nfunc (*ResponseDefinitions) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{47}\n}\n\nfunc (x *ResponseDefinitions) GetAdditionalProperties() []*NamedResponse {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype ResponseValue struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*ResponseValue_Response\n\t//\t*ResponseValue_JsonReference\n\tOneof isResponseValue_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *ResponseValue) Reset() {\n\t*x = ResponseValue{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[48]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ResponseValue) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ResponseValue) ProtoMessage() {}\n\nfunc (x *ResponseValue) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[48]\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 ResponseValue.ProtoReflect.Descriptor instead.\nfunc (*ResponseValue) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{48}\n}\n\nfunc (m *ResponseValue) GetOneof() isResponseValue_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *ResponseValue) GetResponse() *Response {\n\tif x, ok := x.GetOneof().(*ResponseValue_Response); ok {\n\t\treturn x.Response\n\t}\n\treturn nil\n}\n\nfunc (x *ResponseValue) GetJsonReference() *JsonReference {\n\tif x, ok := x.GetOneof().(*ResponseValue_JsonReference); ok {\n\t\treturn x.JsonReference\n\t}\n\treturn nil\n}\n\ntype isResponseValue_Oneof interface {\n\tisResponseValue_Oneof()\n}\n\ntype ResponseValue_Response struct {\n\tResponse *Response `protobuf:\"bytes,1,opt,name=response,proto3,oneof\"`\n}\n\ntype ResponseValue_JsonReference struct {\n\tJsonReference *JsonReference `protobuf:\"bytes,2,opt,name=json_reference,json=jsonReference,proto3,oneof\"`\n}\n\nfunc (*ResponseValue_Response) isResponseValue_Oneof() {}\n\nfunc (*ResponseValue_JsonReference) isResponseValue_Oneof() {}\n\n// Response objects names can either be any valid HTTP status code or 'default'.\ntype Responses struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tResponseCode    []*NamedResponseValue `protobuf:\"bytes,1,rep,name=response_code,json=responseCode,proto3\" json:\"response_code,omitempty\"`\n\tVendorExtension []*NamedAny           `protobuf:\"bytes,2,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Responses) Reset() {\n\t*x = Responses{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[49]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Responses) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Responses) ProtoMessage() {}\n\nfunc (x *Responses) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[49]\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 Responses.ProtoReflect.Descriptor instead.\nfunc (*Responses) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{49}\n}\n\nfunc (x *Responses) GetResponseCode() []*NamedResponseValue {\n\tif x != nil {\n\t\treturn x.ResponseCode\n\t}\n\treturn nil\n}\n\nfunc (x *Responses) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\n// A deterministic version of a JSON Schema object.\ntype Schema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tXRef                 string                    `protobuf:\"bytes,1,opt,name=_ref,json=Ref,proto3\" json:\"_ref,omitempty\"`\n\tFormat               string                    `protobuf:\"bytes,2,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tTitle                string                    `protobuf:\"bytes,3,opt,name=title,proto3\" json:\"title,omitempty\"`\n\tDescription          string                    `protobuf:\"bytes,4,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tDefault              *Any                      `protobuf:\"bytes,5,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tMultipleOf           float64                   `protobuf:\"fixed64,6,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tMaximum              float64                   `protobuf:\"fixed64,7,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum     bool                      `protobuf:\"varint,8,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum              float64                   `protobuf:\"fixed64,9,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum     bool                      `protobuf:\"varint,10,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength            int64                     `protobuf:\"varint,11,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength            int64                     `protobuf:\"varint,12,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern              string                    `protobuf:\"bytes,13,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems             int64                     `protobuf:\"varint,14,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems             int64                     `protobuf:\"varint,15,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems          bool                      `protobuf:\"varint,16,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tMaxProperties        int64                     `protobuf:\"varint,17,opt,name=max_properties,json=maxProperties,proto3\" json:\"max_properties,omitempty\"`\n\tMinProperties        int64                     `protobuf:\"varint,18,opt,name=min_properties,json=minProperties,proto3\" json:\"min_properties,omitempty\"`\n\tRequired             []string                  `protobuf:\"bytes,19,rep,name=required,proto3\" json:\"required,omitempty\"`\n\tEnum                 []*Any                    `protobuf:\"bytes,20,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tAdditionalProperties *AdditionalPropertiesItem `protobuf:\"bytes,21,opt,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n\tType                 *TypeItem                 `protobuf:\"bytes,22,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tItems                *ItemsItem                `protobuf:\"bytes,23,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tAllOf                []*Schema                 `protobuf:\"bytes,24,rep,name=all_of,json=allOf,proto3\" json:\"all_of,omitempty\"`\n\tProperties           *Properties               `protobuf:\"bytes,25,opt,name=properties,proto3\" json:\"properties,omitempty\"`\n\tDiscriminator        string                    `protobuf:\"bytes,26,opt,name=discriminator,proto3\" json:\"discriminator,omitempty\"`\n\tReadOnly             bool                      `protobuf:\"varint,27,opt,name=read_only,json=readOnly,proto3\" json:\"read_only,omitempty\"`\n\tXml                  *Xml                      `protobuf:\"bytes,28,opt,name=xml,proto3\" json:\"xml,omitempty\"`\n\tExternalDocs         *ExternalDocs             `protobuf:\"bytes,29,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tExample              *Any                      `protobuf:\"bytes,30,opt,name=example,proto3\" json:\"example,omitempty\"`\n\tVendorExtension      []*NamedAny               `protobuf:\"bytes,31,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Schema) Reset() {\n\t*x = Schema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[50]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Schema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Schema) ProtoMessage() {}\n\nfunc (x *Schema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[50]\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 Schema.ProtoReflect.Descriptor instead.\nfunc (*Schema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{50}\n}\n\nfunc (x *Schema) GetXRef() string {\n\tif x != nil {\n\t\treturn x.XRef\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetTitle() string {\n\tif x != nil {\n\t\treturn x.Title\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetDefault() *Any {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetMaxProperties() int64 {\n\tif x != nil {\n\t\treturn x.MaxProperties\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMinProperties() int64 {\n\tif x != nil {\n\t\treturn x.MinProperties\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetRequired() []string {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetAdditionalProperties() *AdditionalPropertiesItem {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetType() *TypeItem {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetItems() *ItemsItem {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetAllOf() []*Schema {\n\tif x != nil {\n\t\treturn x.AllOf\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetProperties() *Properties {\n\tif x != nil {\n\t\treturn x.Properties\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetDiscriminator() string {\n\tif x != nil {\n\t\treturn x.Discriminator\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetReadOnly() bool {\n\tif x != nil {\n\t\treturn x.ReadOnly\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetXml() *Xml {\n\tif x != nil {\n\t\treturn x.Xml\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetExample() *Any {\n\tif x != nil {\n\t\treturn x.Example\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype SchemaItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*SchemaItem_Schema\n\t//\t*SchemaItem_FileSchema\n\tOneof isSchemaItem_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *SchemaItem) Reset() {\n\t*x = SchemaItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[51]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SchemaItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SchemaItem) ProtoMessage() {}\n\nfunc (x *SchemaItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[51]\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 SchemaItem.ProtoReflect.Descriptor instead.\nfunc (*SchemaItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{51}\n}\n\nfunc (m *SchemaItem) GetOneof() isSchemaItem_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *SchemaItem) GetSchema() *Schema {\n\tif x, ok := x.GetOneof().(*SchemaItem_Schema); ok {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *SchemaItem) GetFileSchema() *FileSchema {\n\tif x, ok := x.GetOneof().(*SchemaItem_FileSchema); ok {\n\t\treturn x.FileSchema\n\t}\n\treturn nil\n}\n\ntype isSchemaItem_Oneof interface {\n\tisSchemaItem_Oneof()\n}\n\ntype SchemaItem_Schema struct {\n\tSchema *Schema `protobuf:\"bytes,1,opt,name=schema,proto3,oneof\"`\n}\n\ntype SchemaItem_FileSchema struct {\n\tFileSchema *FileSchema `protobuf:\"bytes,2,opt,name=file_schema,json=fileSchema,proto3,oneof\"`\n}\n\nfunc (*SchemaItem_Schema) isSchemaItem_Oneof() {}\n\nfunc (*SchemaItem_FileSchema) isSchemaItem_Oneof() {}\n\ntype SecurityDefinitions struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedSecurityDefinitionsItem `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *SecurityDefinitions) Reset() {\n\t*x = SecurityDefinitions{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[52]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SecurityDefinitions) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecurityDefinitions) ProtoMessage() {}\n\nfunc (x *SecurityDefinitions) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[52]\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 SecurityDefinitions.ProtoReflect.Descriptor instead.\nfunc (*SecurityDefinitions) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{52}\n}\n\nfunc (x *SecurityDefinitions) GetAdditionalProperties() []*NamedSecurityDefinitionsItem {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype SecurityDefinitionsItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*SecurityDefinitionsItem_BasicAuthenticationSecurity\n\t//\t*SecurityDefinitionsItem_ApiKeySecurity\n\t//\t*SecurityDefinitionsItem_Oauth2ImplicitSecurity\n\t//\t*SecurityDefinitionsItem_Oauth2PasswordSecurity\n\t//\t*SecurityDefinitionsItem_Oauth2ApplicationSecurity\n\t//\t*SecurityDefinitionsItem_Oauth2AccessCodeSecurity\n\tOneof isSecurityDefinitionsItem_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *SecurityDefinitionsItem) Reset() {\n\t*x = SecurityDefinitionsItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[53]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SecurityDefinitionsItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecurityDefinitionsItem) ProtoMessage() {}\n\nfunc (x *SecurityDefinitionsItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[53]\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 SecurityDefinitionsItem.ProtoReflect.Descriptor instead.\nfunc (*SecurityDefinitionsItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{53}\n}\n\nfunc (m *SecurityDefinitionsItem) GetOneof() isSecurityDefinitionsItem_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *SecurityDefinitionsItem) GetBasicAuthenticationSecurity() *BasicAuthenticationSecurity {\n\tif x, ok := x.GetOneof().(*SecurityDefinitionsItem_BasicAuthenticationSecurity); ok {\n\t\treturn x.BasicAuthenticationSecurity\n\t}\n\treturn nil\n}\n\nfunc (x *SecurityDefinitionsItem) GetApiKeySecurity() *ApiKeySecurity {\n\tif x, ok := x.GetOneof().(*SecurityDefinitionsItem_ApiKeySecurity); ok {\n\t\treturn x.ApiKeySecurity\n\t}\n\treturn nil\n}\n\nfunc (x *SecurityDefinitionsItem) GetOauth2ImplicitSecurity() *Oauth2ImplicitSecurity {\n\tif x, ok := x.GetOneof().(*SecurityDefinitionsItem_Oauth2ImplicitSecurity); ok {\n\t\treturn x.Oauth2ImplicitSecurity\n\t}\n\treturn nil\n}\n\nfunc (x *SecurityDefinitionsItem) GetOauth2PasswordSecurity() *Oauth2PasswordSecurity {\n\tif x, ok := x.GetOneof().(*SecurityDefinitionsItem_Oauth2PasswordSecurity); ok {\n\t\treturn x.Oauth2PasswordSecurity\n\t}\n\treturn nil\n}\n\nfunc (x *SecurityDefinitionsItem) GetOauth2ApplicationSecurity() *Oauth2ApplicationSecurity {\n\tif x, ok := x.GetOneof().(*SecurityDefinitionsItem_Oauth2ApplicationSecurity); ok {\n\t\treturn x.Oauth2ApplicationSecurity\n\t}\n\treturn nil\n}\n\nfunc (x *SecurityDefinitionsItem) GetOauth2AccessCodeSecurity() *Oauth2AccessCodeSecurity {\n\tif x, ok := x.GetOneof().(*SecurityDefinitionsItem_Oauth2AccessCodeSecurity); ok {\n\t\treturn x.Oauth2AccessCodeSecurity\n\t}\n\treturn nil\n}\n\ntype isSecurityDefinitionsItem_Oneof interface {\n\tisSecurityDefinitionsItem_Oneof()\n}\n\ntype SecurityDefinitionsItem_BasicAuthenticationSecurity struct {\n\tBasicAuthenticationSecurity *BasicAuthenticationSecurity `protobuf:\"bytes,1,opt,name=basic_authentication_security,json=basicAuthenticationSecurity,proto3,oneof\"`\n}\n\ntype SecurityDefinitionsItem_ApiKeySecurity struct {\n\tApiKeySecurity *ApiKeySecurity `protobuf:\"bytes,2,opt,name=api_key_security,json=apiKeySecurity,proto3,oneof\"`\n}\n\ntype SecurityDefinitionsItem_Oauth2ImplicitSecurity struct {\n\tOauth2ImplicitSecurity *Oauth2ImplicitSecurity `protobuf:\"bytes,3,opt,name=oauth2_implicit_security,json=oauth2ImplicitSecurity,proto3,oneof\"`\n}\n\ntype SecurityDefinitionsItem_Oauth2PasswordSecurity struct {\n\tOauth2PasswordSecurity *Oauth2PasswordSecurity `protobuf:\"bytes,4,opt,name=oauth2_password_security,json=oauth2PasswordSecurity,proto3,oneof\"`\n}\n\ntype SecurityDefinitionsItem_Oauth2ApplicationSecurity struct {\n\tOauth2ApplicationSecurity *Oauth2ApplicationSecurity `protobuf:\"bytes,5,opt,name=oauth2_application_security,json=oauth2ApplicationSecurity,proto3,oneof\"`\n}\n\ntype SecurityDefinitionsItem_Oauth2AccessCodeSecurity struct {\n\tOauth2AccessCodeSecurity *Oauth2AccessCodeSecurity `protobuf:\"bytes,6,opt,name=oauth2_access_code_security,json=oauth2AccessCodeSecurity,proto3,oneof\"`\n}\n\nfunc (*SecurityDefinitionsItem_BasicAuthenticationSecurity) isSecurityDefinitionsItem_Oneof() {}\n\nfunc (*SecurityDefinitionsItem_ApiKeySecurity) isSecurityDefinitionsItem_Oneof() {}\n\nfunc (*SecurityDefinitionsItem_Oauth2ImplicitSecurity) isSecurityDefinitionsItem_Oneof() {}\n\nfunc (*SecurityDefinitionsItem_Oauth2PasswordSecurity) isSecurityDefinitionsItem_Oneof() {}\n\nfunc (*SecurityDefinitionsItem_Oauth2ApplicationSecurity) isSecurityDefinitionsItem_Oneof() {}\n\nfunc (*SecurityDefinitionsItem_Oauth2AccessCodeSecurity) isSecurityDefinitionsItem_Oneof() {}\n\ntype SecurityRequirement struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedStringArray `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *SecurityRequirement) Reset() {\n\t*x = SecurityRequirement{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[54]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SecurityRequirement) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecurityRequirement) ProtoMessage() {}\n\nfunc (x *SecurityRequirement) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[54]\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 SecurityRequirement.ProtoReflect.Descriptor instead.\nfunc (*SecurityRequirement) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{54}\n}\n\nfunc (x *SecurityRequirement) GetAdditionalProperties() []*NamedStringArray {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype StringArray struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue []string `protobuf:\"bytes,1,rep,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *StringArray) Reset() {\n\t*x = StringArray{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[55]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *StringArray) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StringArray) ProtoMessage() {}\n\nfunc (x *StringArray) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[55]\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 StringArray.ProtoReflect.Descriptor instead.\nfunc (*StringArray) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{55}\n}\n\nfunc (x *StringArray) GetValue() []string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\ntype Tag struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName            string        `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tDescription     string        `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tExternalDocs    *ExternalDocs `protobuf:\"bytes,3,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tVendorExtension []*NamedAny   `protobuf:\"bytes,4,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Tag) Reset() {\n\t*x = Tag{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[56]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Tag) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Tag) ProtoMessage() {}\n\nfunc (x *Tag) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[56]\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 Tag.ProtoReflect.Descriptor instead.\nfunc (*Tag) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{56}\n}\n\nfunc (x *Tag) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Tag) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Tag) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Tag) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\ntype TypeItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue []string `protobuf:\"bytes,1,rep,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *TypeItem) Reset() {\n\t*x = TypeItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[57]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *TypeItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*TypeItem) ProtoMessage() {}\n\nfunc (x *TypeItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[57]\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 TypeItem.ProtoReflect.Descriptor instead.\nfunc (*TypeItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{57}\n}\n\nfunc (x *TypeItem) GetValue() []string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Any property starting with x- is valid.\ntype VendorExtension struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedAny `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *VendorExtension) Reset() {\n\t*x = VendorExtension{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[58]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *VendorExtension) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*VendorExtension) ProtoMessage() {}\n\nfunc (x *VendorExtension) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[58]\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 VendorExtension.ProtoReflect.Descriptor instead.\nfunc (*VendorExtension) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{58}\n}\n\nfunc (x *VendorExtension) GetAdditionalProperties() []*NamedAny {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype Xml struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName            string      `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tNamespace       string      `protobuf:\"bytes,2,opt,name=namespace,proto3\" json:\"namespace,omitempty\"`\n\tPrefix          string      `protobuf:\"bytes,3,opt,name=prefix,proto3\" json:\"prefix,omitempty\"`\n\tAttribute       bool        `protobuf:\"varint,4,opt,name=attribute,proto3\" json:\"attribute,omitempty\"`\n\tWrapped         bool        `protobuf:\"varint,5,opt,name=wrapped,proto3\" json:\"wrapped,omitempty\"`\n\tVendorExtension []*NamedAny `protobuf:\"bytes,6,rep,name=vendor_extension,json=vendorExtension,proto3\" json:\"vendor_extension,omitempty\"`\n}\n\nfunc (x *Xml) Reset() {\n\t*x = Xml{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[59]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Xml) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Xml) ProtoMessage() {}\n\nfunc (x *Xml) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv2_OpenAPIv2_proto_msgTypes[59]\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 Xml.ProtoReflect.Descriptor instead.\nfunc (*Xml) Descriptor() ([]byte, []int) {\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescGZIP(), []int{59}\n}\n\nfunc (x *Xml) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Xml) GetNamespace() string {\n\tif x != nil {\n\t\treturn x.Namespace\n\t}\n\treturn \"\"\n}\n\nfunc (x *Xml) GetPrefix() string {\n\tif x != nil {\n\t\treturn x.Prefix\n\t}\n\treturn \"\"\n}\n\nfunc (x *Xml) GetAttribute() bool {\n\tif x != nil {\n\t\treturn x.Attribute\n\t}\n\treturn false\n}\n\nfunc (x *Xml) GetWrapped() bool {\n\tif x != nil {\n\t\treturn x.Wrapped\n\t}\n\treturn false\n}\n\nfunc (x *Xml) GetVendorExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.VendorExtension\n\t}\n\treturn nil\n}\n\nvar File_openapiv2_OpenAPIv2_proto protoreflect.FileDescriptor\n\nvar file_openapiv2_OpenAPIv2_proto_rawDesc = []byte{\n\t0x0a, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x4f, 0x70, 0x65, 0x6e,\n\t0x41, 0x50, 0x49, 0x76, 0x32, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x22, 0x6d, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,\n\t0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x2c,\n\t0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x68, 0x65,\n\t0x6d, 0x61, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1a, 0x0a, 0x07,\n\t0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52,\n\t0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f,\n\t0x66, 0x22, 0x45, 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,\n\t0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76,\n\t0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x22, 0xab, 0x01, 0x0a, 0x0e, 0x41, 0x70, 0x69,\n\t0x4b, 0x65, 0x79, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74,\n\t0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,\n\t0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x02, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,\n\t0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,\n\t0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f,\n\t0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,\n\t0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d,\n\t0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74,\n\t0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x01, 0x0a, 0x1b, 0x42, 0x61, 0x73, 0x69, 0x63,\n\t0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65,\n\t0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,\n\t0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x10,\n\t0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65,\n\t0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xde, 0x01,\n\t0x0a, 0x0d, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12,\n\t0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,\n\t0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,\n\t0x64, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53,\n\t0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x3f, 0x0a,\n\t0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76,\n\t0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x86,\n\t0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10,\n\t0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c,\n\t0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72,\n\t0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x54, 0x0a, 0x07, 0x44, 0x65, 0x66, 0x61, 0x75,\n\t0x6c, 0x74, 0x12, 0x49, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,\n\t0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f,\n\t0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x5b, 0x0a,\n\t0x0b, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4c, 0x0a, 0x15,\n\t0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x63,\n\t0x68, 0x65, 0x6d, 0x61, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,\n\t0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xe8, 0x05, 0x0a, 0x08, 0x44,\n\t0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x77, 0x61, 0x67, 0x67,\n\t0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x77, 0x61, 0x67, 0x67, 0x65,\n\t0x72, 0x12, 0x24, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x10, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6e, 0x66,\n\t0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18,\n\t0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x62,\n\t0x61, 0x73, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08,\n\t0x62, 0x61, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x63, 0x68, 0x65,\n\t0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d,\n\t0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x18, 0x06,\n\t0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x73, 0x12, 0x1a,\n\t0x0a, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09,\n\t0x52, 0x08, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x73, 0x12, 0x27, 0x0a, 0x05, 0x70, 0x61,\n\t0x74, 0x68, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x73, 0x52, 0x05, 0x70, 0x61,\n\t0x74, 0x68, 0x73, 0x12, 0x39, 0x0a, 0x0b, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f,\n\t0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x73, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x40,\n\t0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0a, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,\n\t0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73,\n\t0x12, 0x3d, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0b, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12,\n\t0x3b, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0c, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53,\n\t0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65,\n\t0x6e, 0x74, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x52, 0x0a, 0x14,\n\t0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,\n\t0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x13, 0x73, 0x65, 0x63,\n\t0x75, 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,\n\t0x12, 0x23, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x61, 0x67, 0x52,\n\t0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61,\n\t0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e,\n\t0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,\n\t0x44, 0x6f, 0x63, 0x73, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65,\n\t0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65,\n\t0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x55, 0x0a, 0x08, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,\n\t0x73, 0x12, 0x49, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f,\n\t0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x83, 0x01, 0x0a,\n\t0x0c, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x20, 0x0a,\n\t0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,\n\t0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72,\n\t0x6c, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e,\n\t0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x22, 0xff, 0x02, 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74,\n\t0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12,\n\t0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x12, 0x29, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x04, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,\n\t0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x1a, 0x0a, 0x08,\n\t0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08,\n\t0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,\n\t0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09,\n\t0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52,\n\t0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74,\n\t0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78,\n\t0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65,\n\t0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x29, 0x0a, 0x07, 0x65, 0x78, 0x61, 0x6d,\n\t0x70, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x65, 0x78, 0x61, 0x6d,\n\t0x70, 0x6c, 0x65, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x22, 0xab, 0x06, 0x0a, 0x1a, 0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74,\n\t0x61, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68,\n\t0x65, 0x6d, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12,\n\t0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, 0x12,\n\t0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x65,\n\t0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08,\n\t0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x75,\n\t0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18,\n\t0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x31, 0x0a,\n\t0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74,\n\t0x69, 0x76, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,\n\t0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66,\n\t0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6c,\n\t0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x29, 0x0a,\n\t0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52,\n\t0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69,\n\t0x6d, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d,\n\t0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f,\n\t0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65,\n\t0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12,\n\t0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01,\n\t0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63,\n\t0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0e,\n\t0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d,\n\t0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65,\n\t0x6e, 0x67, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c,\n\t0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e,\n\t0x67, 0x74, 0x68, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65,\n\t0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18,\n\t0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b,\n\t0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28,\n\t0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d,\n\t0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,\n\t0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71,\n\t0x75, 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b,\n\t0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x65,\n\t0x6e, 0x75, 0x6d, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d,\n\t0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x18,\n\t0x16, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f,\n\t0x66, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x17, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e,\n\t0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x22, 0xab, 0x05, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a,\n\t0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,\n\t0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x74, 0x65,\n\t0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73,\n\t0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x11,\n\t0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61,\n\t0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,\n\t0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x64, 0x65, 0x66,\n\t0x61, 0x75, 0x6c, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x66,\n\t0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18,\n\t0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b,\n\t0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x69,\n\t0x6d, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75,\n\t0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x6d,\n\t0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x69,\n\t0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69,\n\t0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08,\n\t0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6d,\n\t0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,\n\t0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74,\n\t0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18,\n\t0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68,\n\t0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61,\n\t0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d,\n\t0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69,\n\t0x74, 0x65, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49,\n\t0x74, 0x65, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x69,\n\t0x74, 0x65, 0x6d, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71,\n\t0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18,\n\t0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x1f, 0x0a, 0x0b,\n\t0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x18, 0x11, 0x20, 0x01, 0x28,\n\t0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f, 0x66, 0x12, 0x20, 0x0a,\n\t0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,\n\t0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,\n\t0x69, 0x6f, 0x6e, 0x18, 0x13, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52,\n\t0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x22, 0xfd, 0x05, 0x0a, 0x18, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x65, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1a, 0x0a,\n\t0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52,\n\t0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73,\n\t0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,\n\t0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,\n\t0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,\n\t0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x06, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x31, 0x0a, 0x05, 0x69,\n\t0x74, 0x65, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76,\n\t0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x2b,\n\t0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72,\n\t0x6d, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x65,\n\t0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x64,\n\t0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64,\n\t0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75,\n\t0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d,\n\t0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x61,\n\t0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63,\n\t0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x18, 0x0a,\n\t0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07,\n\t0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75,\n\t0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0d, 0x20, 0x01,\n\t0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6e,\n\t0x69, 0x6d, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67,\n\t0x74, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e,\n\t0x67, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74,\n\t0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67,\n\t0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x10, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b, 0x0a, 0x09,\n\t0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52,\n\t0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e,\n\t0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69,\n\t0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65,\n\t0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e,\n\t0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x65, 0x6e, 0x75,\n\t0x6d, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x1f,\n\t0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x18, 0x15, 0x20,\n\t0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f, 0x66, 0x12,\n\t0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,\n\t0x69, 0x6f, 0x6e, 0x18, 0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52,\n\t0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x22, 0x57, 0x0a, 0x07, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x4c, 0x0a, 0x15, 0x61,\n\t0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72,\n\t0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x48, 0x65, 0x61,\n\t0x64, 0x65, 0x72, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xa1, 0x02, 0x0a, 0x04, 0x49, 0x6e,\n\t0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73,\n\t0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69,\n\t0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x5f, 0x6f, 0x66,\n\t0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,\n\t0x74, 0x65, 0x72, 0x6d, 0x73, 0x4f, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d,\n\t0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x13, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6e,\n\t0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x2d, 0x0a,\n\t0x07, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x63, 0x65,\n\t0x6e, 0x73, 0x65, 0x52, 0x07, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x10,\n\t0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65,\n\t0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x37, 0x0a,\n\t0x09, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x63,\n\t0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06,\n\t0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x44, 0x0a, 0x0d, 0x4a, 0x73, 0x6f, 0x6e, 0x52, 0x65,\n\t0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x11, 0x0a, 0x04, 0x5f, 0x72, 0x65, 0x66, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,\n\t0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x70, 0x0a, 0x07,\n\t0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75,\n\t0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x3f, 0x0a,\n\t0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76,\n\t0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x45,\n\t0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25,\n\t0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4b, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x48, 0x65,\n\t0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x32, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c,\n\t0x75, 0x65, 0x22, 0x51, 0x0a, 0x0e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x65, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4f, 0x0a, 0x0d, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x61,\n\t0x74, 0x68, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61,\n\t0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x49, 0x74, 0x65, 0x6d, 0x52,\n\t0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4f, 0x0a, 0x0d, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x52,\n\t0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x76,\n\t0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,\n\t0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x59, 0x0a, 0x12, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,\n\t0x65, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c,\n\t0x75, 0x65, 0x22, 0x4b, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x32, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,\n\t0x6d, 0x0a, 0x1c, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,\n\t0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12,\n\t0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,\n\t0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69,\n\t0x6f, 0x6e, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x37,\n\t0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,\n\t0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x55, 0x0a, 0x10, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,\n\t0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x69,\n\t0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb5,\n\t0x03, 0x0a, 0x10, 0x4e, 0x6f, 0x6e, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,\n\t0x74, 0x65, 0x72, 0x12, 0x65, 0x0a, 0x1b, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x61,\n\t0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x73, 0x63, 0x68, 0x65,\n\t0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61,\n\t0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x48, 0x00,\n\t0x52, 0x18, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,\n\t0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x6c, 0x0a, 0x1e, 0x66, 0x6f,\n\t0x72, 0x6d, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,\n\t0x72, 0x5f, 0x73, 0x75, 0x62, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,\n\t0x46, 0x6f, 0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,\n\t0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x48, 0x00, 0x52, 0x1a, 0x66, 0x6f,\n\t0x72, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53,\n\t0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x62, 0x0a, 0x1a, 0x71, 0x75, 0x65, 0x72,\n\t0x79, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x62, 0x5f,\n\t0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50,\n\t0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x48, 0x00, 0x52, 0x17, 0x71, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,\n\t0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x5f, 0x0a, 0x19,\n\t0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73,\n\t0x75, 0x62, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x74,\n\t0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68,\n\t0x65, 0x6d, 0x61, 0x48, 0x00, 0x52, 0x16, 0x70, 0x61, 0x74, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x65, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x42, 0x07, 0x0a,\n\t0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0xa1, 0x02, 0x0a, 0x18, 0x4f, 0x61, 0x75, 0x74, 0x68,\n\t0x32, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72,\n\t0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x30, 0x0a, 0x06, 0x73,\n\t0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x53,\n\t0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x2b, 0x0a,\n\t0x11, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75,\n\t0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,\n\t0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f,\n\t0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74,\n\t0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,\n\t0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,\n\t0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e,\n\t0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f,\n\t0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xf5, 0x01, 0x0a, 0x19, 0x4f,\n\t0x61, 0x75, 0x74, 0x68, 0x32, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,\n\t0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04,\n\t0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x6c, 0x6f, 0x77,\n\t0x12, 0x30, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x61,\n\t0x75, 0x74, 0x68, 0x32, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70,\n\t0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18,\n\t0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12,\n\t0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e,\n\t0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x22, 0x82, 0x02, 0x0a, 0x16, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x49, 0x6d, 0x70,\n\t0x6c, 0x69, 0x63, 0x69, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x12, 0x0a,\n\t0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,\n\t0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x18,\n\t0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x52,\n\t0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x75, 0x74, 0x68, 0x6f,\n\t0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x10, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,\n\t0x6e, 0x55, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,\n\t0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,\n\t0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72,\n\t0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xf2, 0x01, 0x0a, 0x16, 0x4f, 0x61, 0x75, 0x74,\n\t0x68, 0x32, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,\n\t0x74, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x63,\n\t0x6f, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x53, 0x63,\n\t0x6f, 0x70, 0x65, 0x73, 0x52, 0x06, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09,\n\t0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x08, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73,\n\t0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,\n\t0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x10, 0x76,\n\t0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18,\n\t0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e,\n\t0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5c, 0x0a, 0x0c,\n\t0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x53, 0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x15,\n\t0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x74,\n\t0x72, 0x69, 0x6e, 0x67, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,\n\t0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x9e, 0x04, 0x0a, 0x09, 0x4f,\n\t0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73,\n\t0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07,\n\t0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,\n\t0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,\n\t0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,\n\t0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65,\n\t0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x18, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x74,\n\t0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72,\n\t0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f,\n\t0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72,\n\t0x6f, 0x64, 0x75, 0x63, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72,\n\t0x6f, 0x64, 0x75, 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d,\n\t0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d,\n\t0x65, 0x73, 0x12, 0x3a, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73,\n\t0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x49, 0x74,\n\t0x65, 0x6d, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x33,\n\t0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x52,\n\t0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,\n\t0x73, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x18, 0x0a,\n\t0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x12, 0x1e, 0x0a,\n\t0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28,\n\t0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x3b, 0x0a,\n\t0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32,\n\t0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x63,\n\t0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74,\n\t0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65,\n\t0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0d,\n\t0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64,\n\t0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xa6, 0x01, 0x0a, 0x09,\n\t0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0e, 0x62, 0x6f, 0x64,\n\t0x79, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x42,\n\t0x6f, 0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x0d,\n\t0x62, 0x6f, 0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x4c, 0x0a,\n\t0x12, 0x6e, 0x6f, 0x6e, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65,\n\t0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x6e, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x61,\n\t0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x6e, 0x6f, 0x6e, 0x42, 0x6f,\n\t0x64, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x6f,\n\t0x6e, 0x65, 0x6f, 0x66, 0x22, 0x67, 0x0a, 0x14, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,\n\t0x72, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x15,\n\t0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x61,\n\t0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f,\n\t0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x94, 0x01,\n\t0x0a, 0x0e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x49, 0x74, 0x65, 0x6d,\n\t0x12, 0x35, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x09, 0x70, 0x61,\n\t0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0e, 0x6a, 0x73, 0x6f, 0x6e, 0x5f,\n\t0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4a, 0x73, 0x6f,\n\t0x6e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x6a, 0x73,\n\t0x6f, 0x6e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f,\n\t0x6e, 0x65, 0x6f, 0x66, 0x22, 0xcf, 0x03, 0x0a, 0x08, 0x50, 0x61, 0x74, 0x68, 0x49, 0x74, 0x65,\n\t0x6d, 0x12, 0x11, 0x0a, 0x04, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x03, 0x52, 0x65, 0x66, 0x12, 0x27, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f,\n\t0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x67, 0x65, 0x74, 0x12, 0x27, 0x0a,\n\t0x03, 0x70, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f,\n\t0x6e, 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x04,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x32, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x70, 0x6f, 0x73,\n\t0x74, 0x12, 0x2d, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f,\n\t0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65,\n\t0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f,\n\t0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,\n\t0x73, 0x12, 0x29, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x70, 0x65,\n\t0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64, 0x12, 0x2b, 0x0a, 0x05,\n\t0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69,\n\t0x6f, 0x6e, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3a, 0x0a, 0x0a, 0x70, 0x61, 0x72,\n\t0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x65, 0x74, 0x65, 0x72, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d,\n\t0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f,\n\t0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32,\n\t0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d,\n\t0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74,\n\t0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xfb, 0x05, 0x0a, 0x16, 0x50, 0x61, 0x74, 0x68, 0x50,\n\t0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x0e, 0x0a,\n\t0x02, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x20, 0x0a,\n\t0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12,\n\t0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61,\n\t0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12,\n\t0x31, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x69, 0x6d,\n\t0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65,\n\t0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,\n\t0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63,\n\t0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12,\n\t0x29, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e,\n\t0x79, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61,\n\t0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78,\n\t0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76,\n\t0x65, 0x5f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52,\n\t0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75,\n\t0x6d, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0c, 0x20, 0x01,\n\t0x28, 0x01, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65,\n\t0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d,\n\t0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76,\n\t0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f,\n\t0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x61,\n\t0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c,\n\t0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x69, 0x6e,\n\t0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72,\n\t0x6e, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e,\n\t0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x11, 0x20,\n\t0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a,\n\t0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03,\n\t0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e,\n\t0x69, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08,\n\t0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x23, 0x0a,\n\t0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x65, 0x6e,\n\t0x75, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x6f,\n\t0x66, 0x18, 0x15, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c,\n\t0x65, 0x4f, 0x66, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x16, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x22, 0x77, 0x0a, 0x05, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x3f, 0x0a,\n\t0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76,\n\t0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d,\n\t0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50,\n\t0x61, 0x74, 0x68, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x92, 0x05,\n\t0x0a, 0x0f, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d,\n\t0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x31, 0x0a,\n\t0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74,\n\t0x69, 0x76, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73,\n\t0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66,\n\t0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6c,\n\t0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x29, 0x0a,\n\t0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52,\n\t0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69,\n\t0x6d, 0x75, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d,\n\t0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f,\n\t0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65,\n\t0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12,\n\t0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x01,\n\t0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63,\n\t0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x09,\n\t0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d,\n\t0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65,\n\t0x6e, 0x67, 0x74, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c,\n\t0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e,\n\t0x67, 0x74, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65,\n\t0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18,\n\t0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b,\n\t0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28,\n\t0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d,\n\t0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08,\n\t0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71,\n\t0x75, 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b,\n\t0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x65,\n\t0x6e, 0x75, 0x6d, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d,\n\t0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x18,\n\t0x11, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f,\n\t0x66, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x12, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e,\n\t0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x22, 0x5a, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,\n\t0x12, 0x4c, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,\n\t0x17, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d,\n\t0x65, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69,\n\t0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xa8,\n\t0x06, 0x0a, 0x17, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,\n\t0x72, 0x53, 0x75, 0x62, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65,\n\t0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65,\n\t0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,\n\t0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,\n\t0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,\n\t0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x11,\n\t0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6d,\n\t0x70, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,\n\t0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06,\n\t0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f,\n\t0x72, 0x6d, 0x61, 0x74, 0x12, 0x31, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x08, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x73,\n\t0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x63, 0x6f, 0x6c, 0x6c, 0x65,\n\t0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x10, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x6f,\n\t0x72, 0x6d, 0x61, 0x74, 0x12, 0x29, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18,\n\t0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12,\n\t0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01,\n\t0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63,\n\t0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0c,\n\t0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d,\n\t0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75,\n\t0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d,\n\t0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69,\n\t0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63,\n\t0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x1d, 0x0a,\n\t0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28,\n\t0x03, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1d, 0x0a, 0x0a,\n\t0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x10, 0x20, 0x01, 0x28, 0x03,\n\t0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x70,\n\t0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61,\n\t0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x74, 0x65,\n\t0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49, 0x74, 0x65,\n\t0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18,\n\t0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12,\n\t0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18,\n\t0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49, 0x74, 0x65,\n\t0x6d, 0x73, 0x12, 0x23, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e,\n\t0x79, 0x52, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69,\n\t0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x18, 0x16, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75,\n\t0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f, 0x66, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64,\n\t0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x17, 0x20, 0x03,\n\t0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72,\n\t0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xfe, 0x01, 0x0a, 0x08, 0x52, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,\n\t0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,\n\t0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65,\n\t0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x49, 0x74, 0x65, 0x6d,\n\t0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x2d, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64,\n\t0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x52, 0x07,\n\t0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70,\n\t0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x52,\n\t0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e,\n\t0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f,\n\t0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x65, 0x0a, 0x13, 0x52, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x73, 0x12, 0x4e, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f,\n\t0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64,\n\t0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,\n\t0x73, 0x22, 0x90, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x61,\n\t0x6c, 0x75, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x08, 0x72,\n\t0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0e, 0x6a, 0x73, 0x6f, 0x6e, 0x5f,\n\t0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4a, 0x73, 0x6f,\n\t0x6e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x0d, 0x6a, 0x73,\n\t0x6f, 0x6e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f,\n\t0x6e, 0x65, 0x6f, 0x66, 0x22, 0x91, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,\n\t0x65, 0x73, 0x12, 0x43, 0x0a, 0x0d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x63,\n\t0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70,\n\t0x6f, 0x6e, 0x73, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x70, 0x6f,\n\t0x6e, 0x73, 0x65, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f,\n\t0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45,\n\t0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xaf, 0x09, 0x0a, 0x06, 0x53, 0x63, 0x68,\n\t0x65, 0x6d, 0x61, 0x12, 0x11, 0x0a, 0x04, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x14,\n\t0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74,\n\t0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,\n\t0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,\n\t0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,\n\t0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,\n\t0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x66,\n\t0x18, 0x06, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65,\n\t0x4f, 0x66, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x07, 0x20,\n\t0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11,\n\t0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75,\n\t0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69,\n\t0x76, 0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e,\n\t0x69, 0x6d, 0x75, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69,\n\t0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65,\n\t0x5f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10,\n\t0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d,\n\t0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0b,\n\t0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12,\n\t0x1d, 0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0c, 0x20,\n\t0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18,\n\t0x0a, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f,\n\t0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78,\n\t0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65,\n\t0x6d, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65,\n\t0x6d, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x74, 0x65,\n\t0x6d, 0x73, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65,\n\t0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x6f,\n\t0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d,\n\t0x61, 0x78, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e,\n\t0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x12,\n\t0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,\n\t0x69, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18,\n\t0x13, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12,\n\t0x23, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04,\n\t0x65, 0x6e, 0x75, 0x6d, 0x12, 0x59, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x15, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x69, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12,\n\t0x28, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x49,\n\t0x74, 0x65, 0x6d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65,\n\t0x6d, 0x73, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52,\n\t0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x29, 0x0a, 0x06, 0x61, 0x6c, 0x6c, 0x5f, 0x6f, 0x66,\n\t0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x4f,\n\t0x66, 0x12, 0x36, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18,\n\t0x19, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0a, 0x70,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x64, 0x69, 0x73,\n\t0x63, 0x72, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f, 0x72, 0x12,\n\t0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x1b, 0x20, 0x01,\n\t0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x03,\n\t0x78, 0x6d, 0x6c, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x58, 0x6d, 0x6c, 0x52, 0x03, 0x78, 0x6d, 0x6c, 0x12,\n\t0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73,\n\t0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73,\n\t0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x29,\n\t0x0a, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x6e, 0x79,\n\t0x52, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e,\n\t0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x1f, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f,\n\t0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x7e, 0x0a, 0x0a, 0x53, 0x63,\n\t0x68, 0x65, 0x6d, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65,\n\t0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x48, 0x00, 0x52, 0x06,\n\t0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x39, 0x0a, 0x0b, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x73,\n\t0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x63, 0x68,\n\t0x65, 0x6d, 0x61, 0x48, 0x00, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x74, 0x0a, 0x13, 0x53, 0x65,\n\t0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x73, 0x12, 0x5d, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f,\n\t0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x28, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66, 0x69, 0x6e,\n\t0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69,\n\t0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,\n\t0x22, 0xe9, 0x04, 0x0a, 0x17, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x44, 0x65, 0x66,\n\t0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x6d, 0x0a, 0x1d,\n\t0x62, 0x61, 0x73, 0x69, 0x63, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32,\n\t0x2e, 0x42, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x1b,\n\t0x62, 0x61, 0x73, 0x69, 0x63, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,\n\t0x69, 0x6f, 0x6e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x61,\n\t0x70, 0x69, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,\n\t0x79, 0x48, 0x00, 0x52, 0x0e, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x63, 0x75, 0x72,\n\t0x69, 0x74, 0x79, 0x12, 0x5e, 0x0a, 0x18, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x5f, 0x69, 0x6d,\n\t0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18,\n\t0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x49, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69,\n\t0x74, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x16, 0x6f, 0x61, 0x75,\n\t0x74, 0x68, 0x32, 0x49, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x53, 0x65, 0x63, 0x75, 0x72,\n\t0x69, 0x74, 0x79, 0x12, 0x5e, 0x0a, 0x18, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x5f, 0x70, 0x61,\n\t0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18,\n\t0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x32, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,\n\t0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x16, 0x6f, 0x61, 0x75,\n\t0x74, 0x68, 0x32, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72,\n\t0x69, 0x74, 0x79, 0x12, 0x67, 0x0a, 0x1b, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x5f, 0x61, 0x70,\n\t0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69,\n\t0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x41, 0x70, 0x70, 0x6c,\n\t0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x48,\n\t0x00, 0x52, 0x19, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x65, 0x0a, 0x1b,\n\t0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f,\n\t0x64, 0x65, 0x5f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4f,\n\t0x61, 0x75, 0x74, 0x68, 0x32, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x53,\n\t0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x48, 0x00, 0x52, 0x18, 0x6f, 0x61, 0x75, 0x74, 0x68,\n\t0x32, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72,\n\t0x69, 0x74, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x68, 0x0a, 0x13,\n\t0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d,\n\t0x65, 0x6e, 0x74, 0x12, 0x51, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61,\n\t0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,\n\t0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79,\n\t0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70,\n\t0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x23, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,\n\t0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,\n\t0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xbb, 0x01, 0x0a, 0x03,\n\t0x54, 0x61, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,\n\t0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,\n\t0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74,\n\t0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x78,\n\t0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65,\n\t0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64,\n\t0x6f, 0x72, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03,\n\t0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72,\n\t0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x20, 0x0a, 0x08, 0x54, 0x79, 0x70,\n\t0x65, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01,\n\t0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5c, 0x0a, 0x0f, 0x56,\n\t0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49,\n\t0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f,\n\t0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x41, 0x6e, 0x79, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x03, 0x58, 0x6d,\n\t0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61,\n\t0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70,\n\t0x61, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x61,\n\t0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09,\n\t0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x72, 0x61,\n\t0x70, 0x70, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x72, 0x61, 0x70,\n\t0x70, 0x65, 0x64, 0x12, 0x3f, 0x0a, 0x10, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x65, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x41, 0x6e, 0x79, 0x52, 0x0f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x42, 0x3e, 0x0a, 0x0e, 0x6f, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x5f, 0x76, 0x32, 0x42, 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x50,\n\t0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x16, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x76, 0x32, 0x3b, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x32, 0xa2, 0x02,\n\t0x03, 0x4f, 0x41, 0x53, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_openapiv2_OpenAPIv2_proto_rawDescOnce sync.Once\n\tfile_openapiv2_OpenAPIv2_proto_rawDescData = file_openapiv2_OpenAPIv2_proto_rawDesc\n)\n\nfunc file_openapiv2_OpenAPIv2_proto_rawDescGZIP() []byte {\n\tfile_openapiv2_OpenAPIv2_proto_rawDescOnce.Do(func() {\n\t\tfile_openapiv2_OpenAPIv2_proto_rawDescData = protoimpl.X.CompressGZIP(file_openapiv2_OpenAPIv2_proto_rawDescData)\n\t})\n\treturn file_openapiv2_OpenAPIv2_proto_rawDescData\n}\n\nvar file_openapiv2_OpenAPIv2_proto_msgTypes = make([]protoimpl.MessageInfo, 60)\nvar file_openapiv2_OpenAPIv2_proto_goTypes = []interface{}{\n\t(*AdditionalPropertiesItem)(nil),     // 0: openapi.v2.AdditionalPropertiesItem\n\t(*Any)(nil),                          // 1: openapi.v2.Any\n\t(*ApiKeySecurity)(nil),               // 2: openapi.v2.ApiKeySecurity\n\t(*BasicAuthenticationSecurity)(nil),  // 3: openapi.v2.BasicAuthenticationSecurity\n\t(*BodyParameter)(nil),                // 4: openapi.v2.BodyParameter\n\t(*Contact)(nil),                      // 5: openapi.v2.Contact\n\t(*Default)(nil),                      // 6: openapi.v2.Default\n\t(*Definitions)(nil),                  // 7: openapi.v2.Definitions\n\t(*Document)(nil),                     // 8: openapi.v2.Document\n\t(*Examples)(nil),                     // 9: openapi.v2.Examples\n\t(*ExternalDocs)(nil),                 // 10: openapi.v2.ExternalDocs\n\t(*FileSchema)(nil),                   // 11: openapi.v2.FileSchema\n\t(*FormDataParameterSubSchema)(nil),   // 12: openapi.v2.FormDataParameterSubSchema\n\t(*Header)(nil),                       // 13: openapi.v2.Header\n\t(*HeaderParameterSubSchema)(nil),     // 14: openapi.v2.HeaderParameterSubSchema\n\t(*Headers)(nil),                      // 15: openapi.v2.Headers\n\t(*Info)(nil),                         // 16: openapi.v2.Info\n\t(*ItemsItem)(nil),                    // 17: openapi.v2.ItemsItem\n\t(*JsonReference)(nil),                // 18: openapi.v2.JsonReference\n\t(*License)(nil),                      // 19: openapi.v2.License\n\t(*NamedAny)(nil),                     // 20: openapi.v2.NamedAny\n\t(*NamedHeader)(nil),                  // 21: openapi.v2.NamedHeader\n\t(*NamedParameter)(nil),               // 22: openapi.v2.NamedParameter\n\t(*NamedPathItem)(nil),                // 23: openapi.v2.NamedPathItem\n\t(*NamedResponse)(nil),                // 24: openapi.v2.NamedResponse\n\t(*NamedResponseValue)(nil),           // 25: openapi.v2.NamedResponseValue\n\t(*NamedSchema)(nil),                  // 26: openapi.v2.NamedSchema\n\t(*NamedSecurityDefinitionsItem)(nil), // 27: openapi.v2.NamedSecurityDefinitionsItem\n\t(*NamedString)(nil),                  // 28: openapi.v2.NamedString\n\t(*NamedStringArray)(nil),             // 29: openapi.v2.NamedStringArray\n\t(*NonBodyParameter)(nil),             // 30: openapi.v2.NonBodyParameter\n\t(*Oauth2AccessCodeSecurity)(nil),     // 31: openapi.v2.Oauth2AccessCodeSecurity\n\t(*Oauth2ApplicationSecurity)(nil),    // 32: openapi.v2.Oauth2ApplicationSecurity\n\t(*Oauth2ImplicitSecurity)(nil),       // 33: openapi.v2.Oauth2ImplicitSecurity\n\t(*Oauth2PasswordSecurity)(nil),       // 34: openapi.v2.Oauth2PasswordSecurity\n\t(*Oauth2Scopes)(nil),                 // 35: openapi.v2.Oauth2Scopes\n\t(*Operation)(nil),                    // 36: openapi.v2.Operation\n\t(*Parameter)(nil),                    // 37: openapi.v2.Parameter\n\t(*ParameterDefinitions)(nil),         // 38: openapi.v2.ParameterDefinitions\n\t(*ParametersItem)(nil),               // 39: openapi.v2.ParametersItem\n\t(*PathItem)(nil),                     // 40: openapi.v2.PathItem\n\t(*PathParameterSubSchema)(nil),       // 41: openapi.v2.PathParameterSubSchema\n\t(*Paths)(nil),                        // 42: openapi.v2.Paths\n\t(*PrimitivesItems)(nil),              // 43: openapi.v2.PrimitivesItems\n\t(*Properties)(nil),                   // 44: openapi.v2.Properties\n\t(*QueryParameterSubSchema)(nil),      // 45: openapi.v2.QueryParameterSubSchema\n\t(*Response)(nil),                     // 46: openapi.v2.Response\n\t(*ResponseDefinitions)(nil),          // 47: openapi.v2.ResponseDefinitions\n\t(*ResponseValue)(nil),                // 48: openapi.v2.ResponseValue\n\t(*Responses)(nil),                    // 49: openapi.v2.Responses\n\t(*Schema)(nil),                       // 50: openapi.v2.Schema\n\t(*SchemaItem)(nil),                   // 51: openapi.v2.SchemaItem\n\t(*SecurityDefinitions)(nil),          // 52: openapi.v2.SecurityDefinitions\n\t(*SecurityDefinitionsItem)(nil),      // 53: openapi.v2.SecurityDefinitionsItem\n\t(*SecurityRequirement)(nil),          // 54: openapi.v2.SecurityRequirement\n\t(*StringArray)(nil),                  // 55: openapi.v2.StringArray\n\t(*Tag)(nil),                          // 56: openapi.v2.Tag\n\t(*TypeItem)(nil),                     // 57: openapi.v2.TypeItem\n\t(*VendorExtension)(nil),              // 58: openapi.v2.VendorExtension\n\t(*Xml)(nil),                          // 59: openapi.v2.Xml\n\t(*anypb.Any)(nil),                    // 60: google.protobuf.Any\n}\nvar file_openapiv2_OpenAPIv2_proto_depIdxs = []int32{\n\t50,  // 0: openapi.v2.AdditionalPropertiesItem.schema:type_name -> openapi.v2.Schema\n\t60,  // 1: openapi.v2.Any.value:type_name -> google.protobuf.Any\n\t20,  // 2: openapi.v2.ApiKeySecurity.vendor_extension:type_name -> openapi.v2.NamedAny\n\t20,  // 3: openapi.v2.BasicAuthenticationSecurity.vendor_extension:type_name -> openapi.v2.NamedAny\n\t50,  // 4: openapi.v2.BodyParameter.schema:type_name -> openapi.v2.Schema\n\t20,  // 5: openapi.v2.BodyParameter.vendor_extension:type_name -> openapi.v2.NamedAny\n\t20,  // 6: openapi.v2.Contact.vendor_extension:type_name -> openapi.v2.NamedAny\n\t20,  // 7: openapi.v2.Default.additional_properties:type_name -> openapi.v2.NamedAny\n\t26,  // 8: openapi.v2.Definitions.additional_properties:type_name -> openapi.v2.NamedSchema\n\t16,  // 9: openapi.v2.Document.info:type_name -> openapi.v2.Info\n\t42,  // 10: openapi.v2.Document.paths:type_name -> openapi.v2.Paths\n\t7,   // 11: openapi.v2.Document.definitions:type_name -> openapi.v2.Definitions\n\t38,  // 12: openapi.v2.Document.parameters:type_name -> openapi.v2.ParameterDefinitions\n\t47,  // 13: openapi.v2.Document.responses:type_name -> openapi.v2.ResponseDefinitions\n\t54,  // 14: openapi.v2.Document.security:type_name -> openapi.v2.SecurityRequirement\n\t52,  // 15: openapi.v2.Document.security_definitions:type_name -> openapi.v2.SecurityDefinitions\n\t56,  // 16: openapi.v2.Document.tags:type_name -> openapi.v2.Tag\n\t10,  // 17: openapi.v2.Document.external_docs:type_name -> openapi.v2.ExternalDocs\n\t20,  // 18: openapi.v2.Document.vendor_extension:type_name -> openapi.v2.NamedAny\n\t20,  // 19: openapi.v2.Examples.additional_properties:type_name -> openapi.v2.NamedAny\n\t20,  // 20: openapi.v2.ExternalDocs.vendor_extension:type_name -> openapi.v2.NamedAny\n\t1,   // 21: openapi.v2.FileSchema.default:type_name -> openapi.v2.Any\n\t10,  // 22: openapi.v2.FileSchema.external_docs:type_name -> openapi.v2.ExternalDocs\n\t1,   // 23: openapi.v2.FileSchema.example:type_name -> openapi.v2.Any\n\t20,  // 24: openapi.v2.FileSchema.vendor_extension:type_name -> openapi.v2.NamedAny\n\t43,  // 25: openapi.v2.FormDataParameterSubSchema.items:type_name -> openapi.v2.PrimitivesItems\n\t1,   // 26: openapi.v2.FormDataParameterSubSchema.default:type_name -> openapi.v2.Any\n\t1,   // 27: openapi.v2.FormDataParameterSubSchema.enum:type_name -> openapi.v2.Any\n\t20,  // 28: openapi.v2.FormDataParameterSubSchema.vendor_extension:type_name -> openapi.v2.NamedAny\n\t43,  // 29: openapi.v2.Header.items:type_name -> openapi.v2.PrimitivesItems\n\t1,   // 30: openapi.v2.Header.default:type_name -> openapi.v2.Any\n\t1,   // 31: openapi.v2.Header.enum:type_name -> openapi.v2.Any\n\t20,  // 32: openapi.v2.Header.vendor_extension:type_name -> openapi.v2.NamedAny\n\t43,  // 33: openapi.v2.HeaderParameterSubSchema.items:type_name -> openapi.v2.PrimitivesItems\n\t1,   // 34: openapi.v2.HeaderParameterSubSchema.default:type_name -> openapi.v2.Any\n\t1,   // 35: openapi.v2.HeaderParameterSubSchema.enum:type_name -> openapi.v2.Any\n\t20,  // 36: openapi.v2.HeaderParameterSubSchema.vendor_extension:type_name -> openapi.v2.NamedAny\n\t21,  // 37: openapi.v2.Headers.additional_properties:type_name -> openapi.v2.NamedHeader\n\t5,   // 38: openapi.v2.Info.contact:type_name -> openapi.v2.Contact\n\t19,  // 39: openapi.v2.Info.license:type_name -> openapi.v2.License\n\t20,  // 40: openapi.v2.Info.vendor_extension:type_name -> openapi.v2.NamedAny\n\t50,  // 41: openapi.v2.ItemsItem.schema:type_name -> openapi.v2.Schema\n\t20,  // 42: openapi.v2.License.vendor_extension:type_name -> openapi.v2.NamedAny\n\t1,   // 43: openapi.v2.NamedAny.value:type_name -> openapi.v2.Any\n\t13,  // 44: openapi.v2.NamedHeader.value:type_name -> openapi.v2.Header\n\t37,  // 45: openapi.v2.NamedParameter.value:type_name -> openapi.v2.Parameter\n\t40,  // 46: openapi.v2.NamedPathItem.value:type_name -> openapi.v2.PathItem\n\t46,  // 47: openapi.v2.NamedResponse.value:type_name -> openapi.v2.Response\n\t48,  // 48: openapi.v2.NamedResponseValue.value:type_name -> openapi.v2.ResponseValue\n\t50,  // 49: openapi.v2.NamedSchema.value:type_name -> openapi.v2.Schema\n\t53,  // 50: openapi.v2.NamedSecurityDefinitionsItem.value:type_name -> openapi.v2.SecurityDefinitionsItem\n\t55,  // 51: openapi.v2.NamedStringArray.value:type_name -> openapi.v2.StringArray\n\t14,  // 52: openapi.v2.NonBodyParameter.header_parameter_sub_schema:type_name -> openapi.v2.HeaderParameterSubSchema\n\t12,  // 53: openapi.v2.NonBodyParameter.form_data_parameter_sub_schema:type_name -> openapi.v2.FormDataParameterSubSchema\n\t45,  // 54: openapi.v2.NonBodyParameter.query_parameter_sub_schema:type_name -> openapi.v2.QueryParameterSubSchema\n\t41,  // 55: openapi.v2.NonBodyParameter.path_parameter_sub_schema:type_name -> openapi.v2.PathParameterSubSchema\n\t35,  // 56: openapi.v2.Oauth2AccessCodeSecurity.scopes:type_name -> openapi.v2.Oauth2Scopes\n\t20,  // 57: openapi.v2.Oauth2AccessCodeSecurity.vendor_extension:type_name -> openapi.v2.NamedAny\n\t35,  // 58: openapi.v2.Oauth2ApplicationSecurity.scopes:type_name -> openapi.v2.Oauth2Scopes\n\t20,  // 59: openapi.v2.Oauth2ApplicationSecurity.vendor_extension:type_name -> openapi.v2.NamedAny\n\t35,  // 60: openapi.v2.Oauth2ImplicitSecurity.scopes:type_name -> openapi.v2.Oauth2Scopes\n\t20,  // 61: openapi.v2.Oauth2ImplicitSecurity.vendor_extension:type_name -> openapi.v2.NamedAny\n\t35,  // 62: openapi.v2.Oauth2PasswordSecurity.scopes:type_name -> openapi.v2.Oauth2Scopes\n\t20,  // 63: openapi.v2.Oauth2PasswordSecurity.vendor_extension:type_name -> openapi.v2.NamedAny\n\t28,  // 64: openapi.v2.Oauth2Scopes.additional_properties:type_name -> openapi.v2.NamedString\n\t10,  // 65: openapi.v2.Operation.external_docs:type_name -> openapi.v2.ExternalDocs\n\t39,  // 66: openapi.v2.Operation.parameters:type_name -> openapi.v2.ParametersItem\n\t49,  // 67: openapi.v2.Operation.responses:type_name -> openapi.v2.Responses\n\t54,  // 68: openapi.v2.Operation.security:type_name -> openapi.v2.SecurityRequirement\n\t20,  // 69: openapi.v2.Operation.vendor_extension:type_name -> openapi.v2.NamedAny\n\t4,   // 70: openapi.v2.Parameter.body_parameter:type_name -> openapi.v2.BodyParameter\n\t30,  // 71: openapi.v2.Parameter.non_body_parameter:type_name -> openapi.v2.NonBodyParameter\n\t22,  // 72: openapi.v2.ParameterDefinitions.additional_properties:type_name -> openapi.v2.NamedParameter\n\t37,  // 73: openapi.v2.ParametersItem.parameter:type_name -> openapi.v2.Parameter\n\t18,  // 74: openapi.v2.ParametersItem.json_reference:type_name -> openapi.v2.JsonReference\n\t36,  // 75: openapi.v2.PathItem.get:type_name -> openapi.v2.Operation\n\t36,  // 76: openapi.v2.PathItem.put:type_name -> openapi.v2.Operation\n\t36,  // 77: openapi.v2.PathItem.post:type_name -> openapi.v2.Operation\n\t36,  // 78: openapi.v2.PathItem.delete:type_name -> openapi.v2.Operation\n\t36,  // 79: openapi.v2.PathItem.options:type_name -> openapi.v2.Operation\n\t36,  // 80: openapi.v2.PathItem.head:type_name -> openapi.v2.Operation\n\t36,  // 81: openapi.v2.PathItem.patch:type_name -> openapi.v2.Operation\n\t39,  // 82: openapi.v2.PathItem.parameters:type_name -> openapi.v2.ParametersItem\n\t20,  // 83: openapi.v2.PathItem.vendor_extension:type_name -> openapi.v2.NamedAny\n\t43,  // 84: openapi.v2.PathParameterSubSchema.items:type_name -> openapi.v2.PrimitivesItems\n\t1,   // 85: openapi.v2.PathParameterSubSchema.default:type_name -> openapi.v2.Any\n\t1,   // 86: openapi.v2.PathParameterSubSchema.enum:type_name -> openapi.v2.Any\n\t20,  // 87: openapi.v2.PathParameterSubSchema.vendor_extension:type_name -> openapi.v2.NamedAny\n\t20,  // 88: openapi.v2.Paths.vendor_extension:type_name -> openapi.v2.NamedAny\n\t23,  // 89: openapi.v2.Paths.path:type_name -> openapi.v2.NamedPathItem\n\t43,  // 90: openapi.v2.PrimitivesItems.items:type_name -> openapi.v2.PrimitivesItems\n\t1,   // 91: openapi.v2.PrimitivesItems.default:type_name -> openapi.v2.Any\n\t1,   // 92: openapi.v2.PrimitivesItems.enum:type_name -> openapi.v2.Any\n\t20,  // 93: openapi.v2.PrimitivesItems.vendor_extension:type_name -> openapi.v2.NamedAny\n\t26,  // 94: openapi.v2.Properties.additional_properties:type_name -> openapi.v2.NamedSchema\n\t43,  // 95: openapi.v2.QueryParameterSubSchema.items:type_name -> openapi.v2.PrimitivesItems\n\t1,   // 96: openapi.v2.QueryParameterSubSchema.default:type_name -> openapi.v2.Any\n\t1,   // 97: openapi.v2.QueryParameterSubSchema.enum:type_name -> openapi.v2.Any\n\t20,  // 98: openapi.v2.QueryParameterSubSchema.vendor_extension:type_name -> openapi.v2.NamedAny\n\t51,  // 99: openapi.v2.Response.schema:type_name -> openapi.v2.SchemaItem\n\t15,  // 100: openapi.v2.Response.headers:type_name -> openapi.v2.Headers\n\t9,   // 101: openapi.v2.Response.examples:type_name -> openapi.v2.Examples\n\t20,  // 102: openapi.v2.Response.vendor_extension:type_name -> openapi.v2.NamedAny\n\t24,  // 103: openapi.v2.ResponseDefinitions.additional_properties:type_name -> openapi.v2.NamedResponse\n\t46,  // 104: openapi.v2.ResponseValue.response:type_name -> openapi.v2.Response\n\t18,  // 105: openapi.v2.ResponseValue.json_reference:type_name -> openapi.v2.JsonReference\n\t25,  // 106: openapi.v2.Responses.response_code:type_name -> openapi.v2.NamedResponseValue\n\t20,  // 107: openapi.v2.Responses.vendor_extension:type_name -> openapi.v2.NamedAny\n\t1,   // 108: openapi.v2.Schema.default:type_name -> openapi.v2.Any\n\t1,   // 109: openapi.v2.Schema.enum:type_name -> openapi.v2.Any\n\t0,   // 110: openapi.v2.Schema.additional_properties:type_name -> openapi.v2.AdditionalPropertiesItem\n\t57,  // 111: openapi.v2.Schema.type:type_name -> openapi.v2.TypeItem\n\t17,  // 112: openapi.v2.Schema.items:type_name -> openapi.v2.ItemsItem\n\t50,  // 113: openapi.v2.Schema.all_of:type_name -> openapi.v2.Schema\n\t44,  // 114: openapi.v2.Schema.properties:type_name -> openapi.v2.Properties\n\t59,  // 115: openapi.v2.Schema.xml:type_name -> openapi.v2.Xml\n\t10,  // 116: openapi.v2.Schema.external_docs:type_name -> openapi.v2.ExternalDocs\n\t1,   // 117: openapi.v2.Schema.example:type_name -> openapi.v2.Any\n\t20,  // 118: openapi.v2.Schema.vendor_extension:type_name -> openapi.v2.NamedAny\n\t50,  // 119: openapi.v2.SchemaItem.schema:type_name -> openapi.v2.Schema\n\t11,  // 120: openapi.v2.SchemaItem.file_schema:type_name -> openapi.v2.FileSchema\n\t27,  // 121: openapi.v2.SecurityDefinitions.additional_properties:type_name -> openapi.v2.NamedSecurityDefinitionsItem\n\t3,   // 122: openapi.v2.SecurityDefinitionsItem.basic_authentication_security:type_name -> openapi.v2.BasicAuthenticationSecurity\n\t2,   // 123: openapi.v2.SecurityDefinitionsItem.api_key_security:type_name -> openapi.v2.ApiKeySecurity\n\t33,  // 124: openapi.v2.SecurityDefinitionsItem.oauth2_implicit_security:type_name -> openapi.v2.Oauth2ImplicitSecurity\n\t34,  // 125: openapi.v2.SecurityDefinitionsItem.oauth2_password_security:type_name -> openapi.v2.Oauth2PasswordSecurity\n\t32,  // 126: openapi.v2.SecurityDefinitionsItem.oauth2_application_security:type_name -> openapi.v2.Oauth2ApplicationSecurity\n\t31,  // 127: openapi.v2.SecurityDefinitionsItem.oauth2_access_code_security:type_name -> openapi.v2.Oauth2AccessCodeSecurity\n\t29,  // 128: openapi.v2.SecurityRequirement.additional_properties:type_name -> openapi.v2.NamedStringArray\n\t10,  // 129: openapi.v2.Tag.external_docs:type_name -> openapi.v2.ExternalDocs\n\t20,  // 130: openapi.v2.Tag.vendor_extension:type_name -> openapi.v2.NamedAny\n\t20,  // 131: openapi.v2.VendorExtension.additional_properties:type_name -> openapi.v2.NamedAny\n\t20,  // 132: openapi.v2.Xml.vendor_extension:type_name -> openapi.v2.NamedAny\n\t133, // [133:133] is the sub-list for method output_type\n\t133, // [133:133] is the sub-list for method input_type\n\t133, // [133:133] is the sub-list for extension type_name\n\t133, // [133:133] is the sub-list for extension extendee\n\t0,   // [0:133] is the sub-list for field type_name\n}\n\nfunc init() { file_openapiv2_OpenAPIv2_proto_init() }\nfunc file_openapiv2_OpenAPIv2_proto_init() {\n\tif File_openapiv2_OpenAPIv2_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_openapiv2_OpenAPIv2_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*AdditionalPropertiesItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Any); 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_openapiv2_OpenAPIv2_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ApiKeySecurity); 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_openapiv2_OpenAPIv2_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*BasicAuthenticationSecurity); 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_openapiv2_OpenAPIv2_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*BodyParameter); 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_openapiv2_OpenAPIv2_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Contact); 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_openapiv2_OpenAPIv2_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Default); 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_openapiv2_OpenAPIv2_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Definitions); 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_openapiv2_OpenAPIv2_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Document); 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_openapiv2_OpenAPIv2_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Examples); 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_openapiv2_OpenAPIv2_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExternalDocs); 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_openapiv2_OpenAPIv2_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*FileSchema); 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_openapiv2_OpenAPIv2_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*FormDataParameterSubSchema); 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_openapiv2_OpenAPIv2_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Header); 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_openapiv2_OpenAPIv2_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HeaderParameterSubSchema); 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_openapiv2_OpenAPIv2_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Headers); 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_openapiv2_OpenAPIv2_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Info); 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_openapiv2_OpenAPIv2_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ItemsItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*JsonReference); 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_openapiv2_OpenAPIv2_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*License); 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_openapiv2_OpenAPIv2_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedAny); 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_openapiv2_OpenAPIv2_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedHeader); 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_openapiv2_OpenAPIv2_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedParameter); 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_openapiv2_OpenAPIv2_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedPathItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedResponse); 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_openapiv2_OpenAPIv2_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedResponseValue); 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_openapiv2_OpenAPIv2_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedSchema); 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_openapiv2_OpenAPIv2_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedSecurityDefinitionsItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedString); 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_openapiv2_OpenAPIv2_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedStringArray); 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_openapiv2_OpenAPIv2_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NonBodyParameter); 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_openapiv2_OpenAPIv2_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Oauth2AccessCodeSecurity); 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_openapiv2_OpenAPIv2_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Oauth2ApplicationSecurity); 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_openapiv2_OpenAPIv2_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Oauth2ImplicitSecurity); 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_openapiv2_OpenAPIv2_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Oauth2PasswordSecurity); 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_openapiv2_OpenAPIv2_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Oauth2Scopes); 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_openapiv2_OpenAPIv2_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Operation); 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_openapiv2_OpenAPIv2_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Parameter); 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_openapiv2_OpenAPIv2_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ParameterDefinitions); 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_openapiv2_OpenAPIv2_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ParametersItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*PathItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*PathParameterSubSchema); 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_openapiv2_OpenAPIv2_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Paths); 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_openapiv2_OpenAPIv2_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*PrimitivesItems); 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_openapiv2_OpenAPIv2_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Properties); 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_openapiv2_OpenAPIv2_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*QueryParameterSubSchema); 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_openapiv2_OpenAPIv2_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Response); 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_openapiv2_OpenAPIv2_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ResponseDefinitions); 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_openapiv2_OpenAPIv2_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ResponseValue); 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_openapiv2_OpenAPIv2_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Responses); 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_openapiv2_OpenAPIv2_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Schema); 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_openapiv2_OpenAPIv2_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SchemaItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SecurityDefinitions); 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_openapiv2_OpenAPIv2_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SecurityDefinitionsItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SecurityRequirement); 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_openapiv2_OpenAPIv2_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*StringArray); 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_openapiv2_OpenAPIv2_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Tag); 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_openapiv2_OpenAPIv2_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*TypeItem); 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_openapiv2_OpenAPIv2_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*VendorExtension); 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_openapiv2_OpenAPIv2_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Xml); 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\tfile_openapiv2_OpenAPIv2_proto_msgTypes[0].OneofWrappers = []interface{}{\n\t\t(*AdditionalPropertiesItem_Schema)(nil),\n\t\t(*AdditionalPropertiesItem_Boolean)(nil),\n\t}\n\tfile_openapiv2_OpenAPIv2_proto_msgTypes[30].OneofWrappers = []interface{}{\n\t\t(*NonBodyParameter_HeaderParameterSubSchema)(nil),\n\t\t(*NonBodyParameter_FormDataParameterSubSchema)(nil),\n\t\t(*NonBodyParameter_QueryParameterSubSchema)(nil),\n\t\t(*NonBodyParameter_PathParameterSubSchema)(nil),\n\t}\n\tfile_openapiv2_OpenAPIv2_proto_msgTypes[37].OneofWrappers = []interface{}{\n\t\t(*Parameter_BodyParameter)(nil),\n\t\t(*Parameter_NonBodyParameter)(nil),\n\t}\n\tfile_openapiv2_OpenAPIv2_proto_msgTypes[39].OneofWrappers = []interface{}{\n\t\t(*ParametersItem_Parameter)(nil),\n\t\t(*ParametersItem_JsonReference)(nil),\n\t}\n\tfile_openapiv2_OpenAPIv2_proto_msgTypes[48].OneofWrappers = []interface{}{\n\t\t(*ResponseValue_Response)(nil),\n\t\t(*ResponseValue_JsonReference)(nil),\n\t}\n\tfile_openapiv2_OpenAPIv2_proto_msgTypes[51].OneofWrappers = []interface{}{\n\t\t(*SchemaItem_Schema)(nil),\n\t\t(*SchemaItem_FileSchema)(nil),\n\t}\n\tfile_openapiv2_OpenAPIv2_proto_msgTypes[53].OneofWrappers = []interface{}{\n\t\t(*SecurityDefinitionsItem_BasicAuthenticationSecurity)(nil),\n\t\t(*SecurityDefinitionsItem_ApiKeySecurity)(nil),\n\t\t(*SecurityDefinitionsItem_Oauth2ImplicitSecurity)(nil),\n\t\t(*SecurityDefinitionsItem_Oauth2PasswordSecurity)(nil),\n\t\t(*SecurityDefinitionsItem_Oauth2ApplicationSecurity)(nil),\n\t\t(*SecurityDefinitionsItem_Oauth2AccessCodeSecurity)(nil),\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_openapiv2_OpenAPIv2_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   60,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_openapiv2_OpenAPIv2_proto_goTypes,\n\t\tDependencyIndexes: file_openapiv2_OpenAPIv2_proto_depIdxs,\n\t\tMessageInfos:      file_openapiv2_OpenAPIv2_proto_msgTypes,\n\t}.Build()\n\tFile_openapiv2_OpenAPIv2_proto = out.File\n\tfile_openapiv2_OpenAPIv2_proto_rawDesc = nil\n\tfile_openapiv2_OpenAPIv2_proto_goTypes = nil\n\tfile_openapiv2_OpenAPIv2_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv2/OpenAPIv2.proto",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\n// THIS FILE IS AUTOMATICALLY GENERATED.\n\nsyntax = \"proto3\";\n\npackage openapi.v2;\n\nimport \"google/protobuf/any.proto\";\n\n// This option lets the proto compiler generate Java code inside the package\n// name (see below) instead of inside an outer class. It creates a simpler\n// developer experience by reducing one-level of name nesting and be\n// consistent with most programming languages that don't support outer classes.\noption java_multiple_files = true;\n\n// The Java outer classname should be the filename in UpperCamelCase. This\n// class is only used to hold proto descriptor, so developers don't need to\n// work with it directly.\noption java_outer_classname = \"OpenAPIProto\";\n\n// The Java package name must be proto package name with proper prefix.\noption java_package = \"org.openapi_v2\";\n\n// A reasonable prefix for the Objective-C symbols generated from the package.\n// It should at a minimum be 3 characters long, all uppercase, and convention\n// is to use an abbreviation of the package name. Something short, but\n// hopefully unique enough to not conflict with things that may come along in\n// the future. 'GPB' is reserved for the protocol buffer implementation itself.\noption objc_class_prefix = \"OAS\";\n\n// The Go package name.\noption go_package = \"./openapiv2;openapi_v2\";\n\nmessage AdditionalPropertiesItem {\n  oneof oneof {\n    Schema schema = 1;\n    bool boolean = 2;\n  }\n}\n\nmessage Any {\n  google.protobuf.Any value = 1;\n  string yaml = 2;\n}\n\nmessage ApiKeySecurity {\n  string type = 1;\n  string name = 2;\n  string in = 3;\n  string description = 4;\n  repeated NamedAny vendor_extension = 5;\n}\n\nmessage BasicAuthenticationSecurity {\n  string type = 1;\n  string description = 2;\n  repeated NamedAny vendor_extension = 3;\n}\n\nmessage BodyParameter {\n  // A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n  string description = 1;\n  // The name of the parameter.\n  string name = 2;\n  // Determines the location of the parameter.\n  string in = 3;\n  // Determines whether or not this parameter is required or optional.\n  bool required = 4;\n  Schema schema = 5;\n  repeated NamedAny vendor_extension = 6;\n}\n\n// Contact information for the owners of the API.\nmessage Contact {\n  // The identifying name of the contact person/organization.\n  string name = 1;\n  // The URL pointing to the contact information.\n  string url = 2;\n  // The email address of the contact person/organization.\n  string email = 3;\n  repeated NamedAny vendor_extension = 4;\n}\n\nmessage Default {\n  repeated NamedAny additional_properties = 1;\n}\n\n// One or more JSON objects describing the schemas being consumed and produced by the API.\nmessage Definitions {\n  repeated NamedSchema additional_properties = 1;\n}\n\nmessage Document {\n  // The Swagger version of this document.\n  string swagger = 1;\n  Info info = 2;\n  // The host (name or ip) of the API. Example: 'swagger.io'\n  string host = 3;\n  // The base path to the API. Example: '/api'.\n  string base_path = 4;\n  // The transfer protocol of the API.\n  repeated string schemes = 5;\n  // A list of MIME types accepted by the API.\n  repeated string consumes = 6;\n  // A list of MIME types the API can produce.\n  repeated string produces = 7;\n  Paths paths = 8;\n  Definitions definitions = 9;\n  ParameterDefinitions parameters = 10;\n  ResponseDefinitions responses = 11;\n  repeated SecurityRequirement security = 12;\n  SecurityDefinitions security_definitions = 13;\n  repeated Tag tags = 14;\n  ExternalDocs external_docs = 15;\n  repeated NamedAny vendor_extension = 16;\n}\n\nmessage Examples {\n  repeated NamedAny additional_properties = 1;\n}\n\n// information about external documentation\nmessage ExternalDocs {\n  string description = 1;\n  string url = 2;\n  repeated NamedAny vendor_extension = 3;\n}\n\n// A deterministic version of a JSON Schema object.\nmessage FileSchema {\n  string format = 1;\n  string title = 2;\n  string description = 3;\n  Any default = 4;\n  repeated string required = 5;\n  string type = 6;\n  bool read_only = 7;\n  ExternalDocs external_docs = 8;\n  Any example = 9;\n  repeated NamedAny vendor_extension = 10;\n}\n\nmessage FormDataParameterSubSchema {\n  // Determines whether or not this parameter is required or optional.\n  bool required = 1;\n  // Determines the location of the parameter.\n  string in = 2;\n  // A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n  string description = 3;\n  // The name of the parameter.\n  string name = 4;\n  // allows sending a parameter by name only or with an empty value.\n  bool allow_empty_value = 5;\n  string type = 6;\n  string format = 7;\n  PrimitivesItems items = 8;\n  string collection_format = 9;\n  Any default = 10;\n  double maximum = 11;\n  bool exclusive_maximum = 12;\n  double minimum = 13;\n  bool exclusive_minimum = 14;\n  int64 max_length = 15;\n  int64 min_length = 16;\n  string pattern = 17;\n  int64 max_items = 18;\n  int64 min_items = 19;\n  bool unique_items = 20;\n  repeated Any enum = 21;\n  double multiple_of = 22;\n  repeated NamedAny vendor_extension = 23;\n}\n\nmessage Header {\n  string type = 1;\n  string format = 2;\n  PrimitivesItems items = 3;\n  string collection_format = 4;\n  Any default = 5;\n  double maximum = 6;\n  bool exclusive_maximum = 7;\n  double minimum = 8;\n  bool exclusive_minimum = 9;\n  int64 max_length = 10;\n  int64 min_length = 11;\n  string pattern = 12;\n  int64 max_items = 13;\n  int64 min_items = 14;\n  bool unique_items = 15;\n  repeated Any enum = 16;\n  double multiple_of = 17;\n  string description = 18;\n  repeated NamedAny vendor_extension = 19;\n}\n\nmessage HeaderParameterSubSchema {\n  // Determines whether or not this parameter is required or optional.\n  bool required = 1;\n  // Determines the location of the parameter.\n  string in = 2;\n  // A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n  string description = 3;\n  // The name of the parameter.\n  string name = 4;\n  string type = 5;\n  string format = 6;\n  PrimitivesItems items = 7;\n  string collection_format = 8;\n  Any default = 9;\n  double maximum = 10;\n  bool exclusive_maximum = 11;\n  double minimum = 12;\n  bool exclusive_minimum = 13;\n  int64 max_length = 14;\n  int64 min_length = 15;\n  string pattern = 16;\n  int64 max_items = 17;\n  int64 min_items = 18;\n  bool unique_items = 19;\n  repeated Any enum = 20;\n  double multiple_of = 21;\n  repeated NamedAny vendor_extension = 22;\n}\n\nmessage Headers {\n  repeated NamedHeader additional_properties = 1;\n}\n\n// General information about the API.\nmessage Info {\n  // A unique and precise title of the API.\n  string title = 1;\n  // A semantic version number of the API.\n  string version = 2;\n  // A longer description of the API. Should be different from the title.  GitHub Flavored Markdown is allowed.\n  string description = 3;\n  // The terms of service for the API.\n  string terms_of_service = 4;\n  Contact contact = 5;\n  License license = 6;\n  repeated NamedAny vendor_extension = 7;\n}\n\nmessage ItemsItem {\n  repeated Schema schema = 1;\n}\n\nmessage JsonReference {\n  string _ref = 1;\n  string description = 2;\n}\n\nmessage License {\n  // The name of the license type. It's encouraged to use an OSI compatible license.\n  string name = 1;\n  // The URL pointing to the license.\n  string url = 2;\n  repeated NamedAny vendor_extension = 3;\n}\n\n// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs.\nmessage NamedAny {\n  // Map key\n  string name = 1;\n  // Mapped value\n  Any value = 2;\n}\n\n// Automatically-generated message used to represent maps of Header as ordered (name,value) pairs.\nmessage NamedHeader {\n  // Map key\n  string name = 1;\n  // Mapped value\n  Header value = 2;\n}\n\n// Automatically-generated message used to represent maps of Parameter as ordered (name,value) pairs.\nmessage NamedParameter {\n  // Map key\n  string name = 1;\n  // Mapped value\n  Parameter value = 2;\n}\n\n// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs.\nmessage NamedPathItem {\n  // Map key\n  string name = 1;\n  // Mapped value\n  PathItem value = 2;\n}\n\n// Automatically-generated message used to represent maps of Response as ordered (name,value) pairs.\nmessage NamedResponse {\n  // Map key\n  string name = 1;\n  // Mapped value\n  Response value = 2;\n}\n\n// Automatically-generated message used to represent maps of ResponseValue as ordered (name,value) pairs.\nmessage NamedResponseValue {\n  // Map key\n  string name = 1;\n  // Mapped value\n  ResponseValue value = 2;\n}\n\n// Automatically-generated message used to represent maps of Schema as ordered (name,value) pairs.\nmessage NamedSchema {\n  // Map key\n  string name = 1;\n  // Mapped value\n  Schema value = 2;\n}\n\n// Automatically-generated message used to represent maps of SecurityDefinitionsItem as ordered (name,value) pairs.\nmessage NamedSecurityDefinitionsItem {\n  // Map key\n  string name = 1;\n  // Mapped value\n  SecurityDefinitionsItem value = 2;\n}\n\n// Automatically-generated message used to represent maps of string as ordered (name,value) pairs.\nmessage NamedString {\n  // Map key\n  string name = 1;\n  // Mapped value\n  string value = 2;\n}\n\n// Automatically-generated message used to represent maps of StringArray as ordered (name,value) pairs.\nmessage NamedStringArray {\n  // Map key\n  string name = 1;\n  // Mapped value\n  StringArray value = 2;\n}\n\nmessage NonBodyParameter {\n  oneof oneof {\n    HeaderParameterSubSchema header_parameter_sub_schema = 1;\n    FormDataParameterSubSchema form_data_parameter_sub_schema = 2;\n    QueryParameterSubSchema query_parameter_sub_schema = 3;\n    PathParameterSubSchema path_parameter_sub_schema = 4;\n  }\n}\n\nmessage Oauth2AccessCodeSecurity {\n  string type = 1;\n  string flow = 2;\n  Oauth2Scopes scopes = 3;\n  string authorization_url = 4;\n  string token_url = 5;\n  string description = 6;\n  repeated NamedAny vendor_extension = 7;\n}\n\nmessage Oauth2ApplicationSecurity {\n  string type = 1;\n  string flow = 2;\n  Oauth2Scopes scopes = 3;\n  string token_url = 4;\n  string description = 5;\n  repeated NamedAny vendor_extension = 6;\n}\n\nmessage Oauth2ImplicitSecurity {\n  string type = 1;\n  string flow = 2;\n  Oauth2Scopes scopes = 3;\n  string authorization_url = 4;\n  string description = 5;\n  repeated NamedAny vendor_extension = 6;\n}\n\nmessage Oauth2PasswordSecurity {\n  string type = 1;\n  string flow = 2;\n  Oauth2Scopes scopes = 3;\n  string token_url = 4;\n  string description = 5;\n  repeated NamedAny vendor_extension = 6;\n}\n\nmessage Oauth2Scopes {\n  repeated NamedString additional_properties = 1;\n}\n\nmessage Operation {\n  repeated string tags = 1;\n  // A brief summary of the operation.\n  string summary = 2;\n  // A longer description of the operation, GitHub Flavored Markdown is allowed.\n  string description = 3;\n  ExternalDocs external_docs = 4;\n  // A unique identifier of the operation.\n  string operation_id = 5;\n  // A list of MIME types the API can produce.\n  repeated string produces = 6;\n  // A list of MIME types the API can consume.\n  repeated string consumes = 7;\n  // The parameters needed to send a valid API call.\n  repeated ParametersItem parameters = 8;\n  Responses responses = 9;\n  // The transfer protocol of the API.\n  repeated string schemes = 10;\n  bool deprecated = 11;\n  repeated SecurityRequirement security = 12;\n  repeated NamedAny vendor_extension = 13;\n}\n\nmessage Parameter {\n  oneof oneof {\n    BodyParameter body_parameter = 1;\n    NonBodyParameter non_body_parameter = 2;\n  }\n}\n\n// One or more JSON representations for parameters\nmessage ParameterDefinitions {\n  repeated NamedParameter additional_properties = 1;\n}\n\nmessage ParametersItem {\n  oneof oneof {\n    Parameter parameter = 1;\n    JsonReference json_reference = 2;\n  }\n}\n\nmessage PathItem {\n  string _ref = 1;\n  Operation get = 2;\n  Operation put = 3;\n  Operation post = 4;\n  Operation delete = 5;\n  Operation options = 6;\n  Operation head = 7;\n  Operation patch = 8;\n  // The parameters needed to send a valid API call.\n  repeated ParametersItem parameters = 9;\n  repeated NamedAny vendor_extension = 10;\n}\n\nmessage PathParameterSubSchema {\n  // Determines whether or not this parameter is required or optional.\n  bool required = 1;\n  // Determines the location of the parameter.\n  string in = 2;\n  // A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n  string description = 3;\n  // The name of the parameter.\n  string name = 4;\n  string type = 5;\n  string format = 6;\n  PrimitivesItems items = 7;\n  string collection_format = 8;\n  Any default = 9;\n  double maximum = 10;\n  bool exclusive_maximum = 11;\n  double minimum = 12;\n  bool exclusive_minimum = 13;\n  int64 max_length = 14;\n  int64 min_length = 15;\n  string pattern = 16;\n  int64 max_items = 17;\n  int64 min_items = 18;\n  bool unique_items = 19;\n  repeated Any enum = 20;\n  double multiple_of = 21;\n  repeated NamedAny vendor_extension = 22;\n}\n\n// Relative paths to the individual endpoints. They must be relative to the 'basePath'.\nmessage Paths {\n  repeated NamedAny vendor_extension = 1;\n  repeated NamedPathItem path = 2;\n}\n\nmessage PrimitivesItems {\n  string type = 1;\n  string format = 2;\n  PrimitivesItems items = 3;\n  string collection_format = 4;\n  Any default = 5;\n  double maximum = 6;\n  bool exclusive_maximum = 7;\n  double minimum = 8;\n  bool exclusive_minimum = 9;\n  int64 max_length = 10;\n  int64 min_length = 11;\n  string pattern = 12;\n  int64 max_items = 13;\n  int64 min_items = 14;\n  bool unique_items = 15;\n  repeated Any enum = 16;\n  double multiple_of = 17;\n  repeated NamedAny vendor_extension = 18;\n}\n\nmessage Properties {\n  repeated NamedSchema additional_properties = 1;\n}\n\nmessage QueryParameterSubSchema {\n  // Determines whether or not this parameter is required or optional.\n  bool required = 1;\n  // Determines the location of the parameter.\n  string in = 2;\n  // A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\n  string description = 3;\n  // The name of the parameter.\n  string name = 4;\n  // allows sending a parameter by name only or with an empty value.\n  bool allow_empty_value = 5;\n  string type = 6;\n  string format = 7;\n  PrimitivesItems items = 8;\n  string collection_format = 9;\n  Any default = 10;\n  double maximum = 11;\n  bool exclusive_maximum = 12;\n  double minimum = 13;\n  bool exclusive_minimum = 14;\n  int64 max_length = 15;\n  int64 min_length = 16;\n  string pattern = 17;\n  int64 max_items = 18;\n  int64 min_items = 19;\n  bool unique_items = 20;\n  repeated Any enum = 21;\n  double multiple_of = 22;\n  repeated NamedAny vendor_extension = 23;\n}\n\nmessage Response {\n  string description = 1;\n  SchemaItem schema = 2;\n  Headers headers = 3;\n  Examples examples = 4;\n  repeated NamedAny vendor_extension = 5;\n}\n\n// One or more JSON representations for responses\nmessage ResponseDefinitions {\n  repeated NamedResponse additional_properties = 1;\n}\n\nmessage ResponseValue {\n  oneof oneof {\n    Response response = 1;\n    JsonReference json_reference = 2;\n  }\n}\n\n// Response objects names can either be any valid HTTP status code or 'default'.\nmessage Responses {\n  repeated NamedResponseValue response_code = 1;\n  repeated NamedAny vendor_extension = 2;\n}\n\n// A deterministic version of a JSON Schema object.\nmessage Schema {\n  string _ref = 1;\n  string format = 2;\n  string title = 3;\n  string description = 4;\n  Any default = 5;\n  double multiple_of = 6;\n  double maximum = 7;\n  bool exclusive_maximum = 8;\n  double minimum = 9;\n  bool exclusive_minimum = 10;\n  int64 max_length = 11;\n  int64 min_length = 12;\n  string pattern = 13;\n  int64 max_items = 14;\n  int64 min_items = 15;\n  bool unique_items = 16;\n  int64 max_properties = 17;\n  int64 min_properties = 18;\n  repeated string required = 19;\n  repeated Any enum = 20;\n  AdditionalPropertiesItem additional_properties = 21;\n  TypeItem type = 22;\n  ItemsItem items = 23;\n  repeated Schema all_of = 24;\n  Properties properties = 25;\n  string discriminator = 26;\n  bool read_only = 27;\n  Xml xml = 28;\n  ExternalDocs external_docs = 29;\n  Any example = 30;\n  repeated NamedAny vendor_extension = 31;\n}\n\nmessage SchemaItem {\n  oneof oneof {\n    Schema schema = 1;\n    FileSchema file_schema = 2;\n  }\n}\n\nmessage SecurityDefinitions {\n  repeated NamedSecurityDefinitionsItem additional_properties = 1;\n}\n\nmessage SecurityDefinitionsItem {\n  oneof oneof {\n    BasicAuthenticationSecurity basic_authentication_security = 1;\n    ApiKeySecurity api_key_security = 2;\n    Oauth2ImplicitSecurity oauth2_implicit_security = 3;\n    Oauth2PasswordSecurity oauth2_password_security = 4;\n    Oauth2ApplicationSecurity oauth2_application_security = 5;\n    Oauth2AccessCodeSecurity oauth2_access_code_security = 6;\n  }\n}\n\nmessage SecurityRequirement {\n  repeated NamedStringArray additional_properties = 1;\n}\n\nmessage StringArray {\n  repeated string value = 1;\n}\n\nmessage Tag {\n  string name = 1;\n  string description = 2;\n  ExternalDocs external_docs = 3;\n  repeated NamedAny vendor_extension = 4;\n}\n\nmessage TypeItem {\n  repeated string value = 1;\n}\n\n// Any property starting with x- is valid.\nmessage VendorExtension {\n  repeated NamedAny additional_properties = 1;\n}\n\nmessage Xml {\n  string name = 1;\n  string namespace = 2;\n  string prefix = 3;\n  bool attribute = 4;\n  bool wrapped = 5;\n  repeated NamedAny vendor_extension = 6;\n}\n\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv2/README.md",
    "content": "# OpenAPI v2 Protocol Buffer Models\n\nThis directory contains a Protocol Buffer-language model and related code for\nsupporting OpenAPI v2.\n\nGnostic applications and plugins can use OpenAPIv2.proto to generate Protocol\nBuffer support code for their preferred languages.\n\nOpenAPIv2.go is used by Gnostic to read JSON and YAML OpenAPI descriptions into\nthe Protocol Buffer-based datastructures generated from OpenAPIv2.proto.\n\nOpenAPIv2.proto and OpenAPIv2.go are generated by the Gnostic compiler\ngenerator, and OpenAPIv2.pb.go is generated by protoc, the Protocol Buffer\ncompiler, and protoc-gen-go, the Protocol Buffer Go code generation plugin.\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv2/document.go",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\npackage openapi_v2\n\nimport (\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/google/gnostic/compiler\"\n)\n\n// ParseDocument reads an OpenAPI v2 description from a YAML/JSON representation.\nfunc ParseDocument(b []byte) (*Document, error) {\n\tinfo, err := compiler.ReadInfoFromBytes(\"\", b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\troot := info.Content[0]\n\treturn NewDocument(root, compiler.NewContextWithExtensions(\"$root\", root, nil, nil))\n}\n\n// YAMLValue produces a serialized YAML representation of the document.\nfunc (d *Document) YAMLValue(comment string) ([]byte, error) {\n\trawInfo := d.ToRawInfo()\n\trawInfo = &yaml.Node{\n\t\tKind:        yaml.DocumentNode,\n\t\tContent:     []*yaml.Node{rawInfo},\n\t\tHeadComment: comment,\n\t}\n\treturn yaml.Marshal(rawInfo)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv2/openapi-2.0.json",
    "content": "{\n  \"title\": \"A JSON Schema for Swagger 2.0 API.\",\n  \"id\": \"http://swagger.io/v2/schema.json#\",\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"type\": \"object\",\n  \"required\": [\n    \"swagger\",\n    \"info\",\n    \"paths\"\n  ],\n  \"additionalProperties\": false,\n  \"patternProperties\": {\n    \"^x-\": {\n      \"$ref\": \"#/definitions/vendorExtension\"\n    }\n  },\n  \"properties\": {\n    \"swagger\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"2.0\"\n      ],\n      \"description\": \"The Swagger version of this document.\"\n    },\n    \"info\": {\n      \"$ref\": \"#/definitions/info\"\n    },\n    \"host\": {\n      \"type\": \"string\",\n      \"pattern\": \"^[^{}/ :\\\\\\\\]+(?::\\\\d+)?$\",\n      \"description\": \"The host (name or ip) of the API. Example: 'swagger.io'\"\n    },\n    \"basePath\": {\n      \"type\": \"string\",\n      \"pattern\": \"^/\",\n      \"description\": \"The base path to the API. Example: '/api'.\"\n    },\n    \"schemes\": {\n      \"$ref\": \"#/definitions/schemesList\"\n    },\n    \"consumes\": {\n      \"description\": \"A list of MIME types accepted by the API.\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/mediaTypeList\"\n        }\n      ]\n    },\n    \"produces\": {\n      \"description\": \"A list of MIME types the API can produce.\",\n      \"allOf\": [\n        {\n          \"$ref\": \"#/definitions/mediaTypeList\"\n        }\n      ]\n    },\n    \"paths\": {\n      \"$ref\": \"#/definitions/paths\"\n    },\n    \"definitions\": {\n      \"$ref\": \"#/definitions/definitions\"\n    },\n    \"parameters\": {\n      \"$ref\": \"#/definitions/parameterDefinitions\"\n    },\n    \"responses\": {\n      \"$ref\": \"#/definitions/responseDefinitions\"\n    },\n    \"security\": {\n      \"$ref\": \"#/definitions/security\"\n    },\n    \"securityDefinitions\": {\n      \"$ref\": \"#/definitions/securityDefinitions\"\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/tag\"\n      },\n      \"uniqueItems\": true\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/definitions/externalDocs\"\n    }\n  },\n  \"definitions\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"description\": \"General information about the API.\",\n      \"required\": [\n        \"version\",\n        \"title\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\",\n          \"description\": \"A unique and precise title of the API.\"\n        },\n        \"version\": {\n          \"type\": \"string\",\n          \"description\": \"A semantic version number of the API.\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A longer description of the API. Should be different from the title.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\",\n          \"description\": \"The terms of service for the API.\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/definitions/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/definitions/license\"\n        }\n      }\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"description\": \"Contact information for the owners of the API.\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The identifying name of the contact person/organization.\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"description\": \"The URL pointing to the contact information.\",\n          \"format\": \"uri\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"description\": \"The email address of the contact person/organization.\",\n          \"format\": \"email\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the license type. It's encouraged to use an OSI compatible license.\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"description\": \"The URL pointing to the license.\",\n          \"format\": \"uri\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"description\": \"Relative paths to the individual endpoints. They must be relative to the 'basePath'.\",\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        },\n        \"^/\": {\n          \"$ref\": \"#/definitions/pathItem\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"definitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/schema\"\n      },\n      \"description\": \"One or more JSON objects describing the schemas being consumed and produced by the API.\"\n    },\n    \"parameterDefinitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/parameter\"\n      },\n      \"description\": \"One or more JSON representations for parameters\"\n    },\n    \"responseDefinitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/response\"\n      },\n      \"description\": \"One or more JSON representations for responses\"\n    },\n    \"externalDocs\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"description\": \"information about external documentation\",\n      \"required\": [\n        \"url\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"examples\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true\n    },\n    \"mimeType\": {\n      \"type\": \"string\",\n      \"description\": \"The MIME type of the HTTP message.\"\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"responses\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"uniqueItems\": true\n        },\n        \"summary\": {\n          \"type\": \"string\",\n          \"description\": \"A brief summary of the operation.\"\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A longer description of the operation, GitHub Flavored Markdown is allowed.\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"operationId\": {\n          \"type\": \"string\",\n          \"description\": \"A unique identifier of the operation.\"\n        },\n        \"produces\": {\n          \"description\": \"A list of MIME types the API can produce.\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/mediaTypeList\"\n            }\n          ]\n        },\n        \"consumes\": {\n          \"description\": \"A list of MIME types the API can consume.\",\n          \"allOf\": [\n            {\n              \"$ref\": \"#/definitions/mediaTypeList\"\n            }\n          ]\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/parametersList\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/responses\"\n        },\n        \"schemes\": {\n          \"$ref\": \"#/definitions/schemesList\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"security\": {\n          \"$ref\": \"#/definitions/security\"\n        }\n      }\n    },\n    \"pathItem\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"get\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/parametersList\"\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"description\": \"Response objects names can either be any valid HTTP status code or 'default'.\",\n      \"minProperties\": 1,\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^([0-9]{3})$|^(default)$\": {\n          \"$ref\": \"#/definitions/responseValue\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"not\": {\n        \"type\": \"object\",\n        \"additionalProperties\": false,\n        \"patternProperties\": {\n          \"^x-\": {\n            \"$ref\": \"#/definitions/vendorExtension\"\n          }\n        }\n      }\n    },\n    \"responseValue\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/response\"\n        },\n        {\n          \"$ref\": \"#/definitions/jsonReference\"\n        }\n      ]\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"description\"\n      ],\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"schema\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/schema\"\n            },\n            {\n              \"$ref\": \"#/definitions/fileSchema\"\n            }\n          ]\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headers\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examples\"\n        }\n      },\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"headers\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/header\"\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"integer\",\n            \"boolean\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"vendorExtension\": {\n      \"description\": \"Any property starting with x- is valid.\",\n      \"additionalProperties\": true,\n      \"additionalItems\": true\n    },\n    \"bodyParameter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"in\",\n        \"schema\"\n      ],\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"body\"\n          ]\n        },\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"schema\": {\n          \"$ref\": \"#/definitions/schema\"\n        }\n      },\n      \"additionalProperties\": false\n    },\n    \"headerParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"header\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"queryParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"query\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"allows sending a parameter by name only or with an empty value.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormatWithMulti\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"formDataParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"description\": \"Determines whether or not this parameter is required or optional.\",\n          \"default\": false\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"formData\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\",\n          \"default\": false,\n          \"description\": \"allows sending a parameter by name only or with an empty value.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\",\n            \"file\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormatWithMulti\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"pathParameterSubSchema\": {\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"required\": [\n        \"required\"\n      ],\n      \"properties\": {\n        \"required\": {\n          \"type\": \"boolean\",\n          \"enum\": [\n            true\n          ],\n          \"description\": \"Determines whether or not this parameter is required or optional.\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"description\": \"Determines the location of the parameter.\",\n          \"enum\": [\n            \"path\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\",\n          \"description\": \"A brief description of the parameter. This could contain examples of use.  GitHub Flavored Markdown is allowed.\"\n        },\n        \"name\": {\n          \"type\": \"string\",\n          \"description\": \"The name of the parameter.\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"boolean\",\n            \"integer\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      }\n    },\n    \"nonBodyParameter\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"name\",\n        \"in\",\n        \"type\"\n      ],\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/headerParameterSubSchema\"\n        },\n        {\n          \"$ref\": \"#/definitions/formDataParameterSubSchema\"\n        },\n        {\n          \"$ref\": \"#/definitions/queryParameterSubSchema\"\n        },\n        {\n          \"$ref\": \"#/definitions/pathParameterSubSchema\"\n        }\n      ]\n    },\n    \"parameter\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/bodyParameter\"\n        },\n        {\n          \"$ref\": \"#/definitions/nonBodyParameter\"\n        }\n      ]\n    },\n    \"schema\": {\n      \"type\": \"object\",\n      \"description\": \"A deterministic version of a JSON Schema object.\",\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"title\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n        },\n        \"description\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/description\"\n        },\n        \"default\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/default\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/multipleOf\"\n        },\n        \"maximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n        },\n        \"minLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n        },\n        \"pattern\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n        },\n        \"minItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/uniqueItems\"\n        },\n        \"maxProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n        },\n        \"minProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n        },\n        \"required\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/stringArray\"\n        },\n        \"enum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/enum\"\n        },\n        \"additionalProperties\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/schema\"\n            },\n            {\n              \"type\": \"boolean\"\n            }\n          ],\n          \"default\": {}\n        },\n        \"type\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/type\"\n        },\n        \"items\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/schema\"\n            },\n            {\n              \"type\": \"array\",\n              \"minItems\": 1,\n              \"items\": {\n                \"$ref\": \"#/definitions/schema\"\n              }\n            }\n          ],\n          \"default\": {}\n        },\n        \"allOf\": {\n          \"type\": \"array\",\n          \"minItems\": 1,\n          \"items\": {\n            \"$ref\": \"#/definitions/schema\"\n          }\n        },\n        \"properties\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/schema\"\n          },\n          \"default\": {}\n        },\n        \"discriminator\": {\n          \"type\": \"string\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"xml\": {\n          \"$ref\": \"#/definitions/xml\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"example\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"fileSchema\": {\n      \"type\": \"object\",\n      \"description\": \"A deterministic version of a JSON Schema object.\",\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      },\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"title\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n        },\n        \"description\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/description\"\n        },\n        \"default\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/default\"\n        },\n        \"required\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/stringArray\"\n        },\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"file\"\n          ]\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"example\": {}\n      },\n      \"additionalProperties\": false\n    },\n    \"primitivesItems\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"string\",\n            \"number\",\n            \"integer\",\n            \"boolean\",\n            \"array\"\n          ]\n        },\n        \"format\": {\n          \"type\": \"string\"\n        },\n        \"items\": {\n          \"$ref\": \"#/definitions/primitivesItems\"\n        },\n        \"collectionFormat\": {\n          \"$ref\": \"#/definitions/collectionFormat\"\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/default\"\n        },\n        \"maximum\": {\n          \"$ref\": \"#/definitions/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"#/definitions/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"#/definitions/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"#/definitions/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"#/definitions/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"#/definitions/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"#/definitions/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"#/definitions/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"#/definitions/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"#/definitions/uniqueItems\"\n        },\n        \"enum\": {\n          \"$ref\": \"#/definitions/enum\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"#/definitions/multipleOf\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/securityRequirement\"\n      },\n      \"uniqueItems\": true\n    },\n    \"securityRequirement\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        },\n        \"uniqueItems\": true\n      }\n    },\n    \"xml\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"type\": \"string\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"attribute\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\",\n          \"default\": false\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"name\"\n      ],\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"securityDefinitions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/basicAuthenticationSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/apiKeySecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2ImplicitSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2PasswordSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2ApplicationSecurity\"\n          },\n          {\n            \"$ref\": \"#/definitions/oauth2AccessCodeSecurity\"\n          }\n        ]\n      }\n    },\n    \"basicAuthenticationSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"basic\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"apiKeySecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"name\",\n        \"in\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"apiKey\"\n          ]\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"header\",\n            \"query\"\n          ]\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2ImplicitSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"authorizationUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"implicit\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2PasswordSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"tokenUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"password\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2ApplicationSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"tokenUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"application\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2AccessCodeSecurity\": {\n      \"type\": \"object\",\n      \"additionalProperties\": false,\n      \"required\": [\n        \"type\",\n        \"flow\",\n        \"authorizationUrl\",\n        \"tokenUrl\"\n      ],\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"oauth2\"\n          ]\n        },\n        \"flow\": {\n          \"type\": \"string\",\n          \"enum\": [\n            \"accessCode\"\n          ]\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/oauth2Scopes\"\n        },\n        \"authorizationUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      },\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/vendorExtension\"\n        }\n      }\n    },\n    \"oauth2Scopes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"mediaTypeList\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/mimeType\"\n      },\n      \"uniqueItems\": true\n    },\n    \"parametersList\": {\n      \"type\": \"array\",\n      \"description\": \"The parameters needed to send a valid API call.\",\n      \"additionalItems\": false,\n      \"items\": {\n        \"oneOf\": [\n          {\n            \"$ref\": \"#/definitions/parameter\"\n          },\n          {\n            \"$ref\": \"#/definitions/jsonReference\"\n          }\n        ]\n      },\n      \"uniqueItems\": true\n    },\n    \"schemesList\": {\n      \"type\": \"array\",\n      \"description\": \"The transfer protocol of the API.\",\n      \"items\": {\n        \"type\": \"string\",\n        \"enum\": [\n          \"http\",\n          \"https\",\n          \"ws\",\n          \"wss\"\n        ]\n      },\n      \"uniqueItems\": true\n    },\n    \"collectionFormat\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"csv\",\n        \"ssv\",\n        \"tsv\",\n        \"pipes\"\n      ],\n      \"default\": \"csv\"\n    },\n    \"collectionFormatWithMulti\": {\n      \"type\": \"string\",\n      \"enum\": [\n        \"csv\",\n        \"ssv\",\n        \"tsv\",\n        \"pipes\",\n        \"multi\"\n      ],\n      \"default\": \"csv\"\n    },\n    \"title\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n    },\n    \"description\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/description\"\n    },\n    \"default\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/default\"\n    },\n    \"multipleOf\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/multipleOf\"\n    },\n    \"maximum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maximum\"\n    },\n    \"exclusiveMaximum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum\"\n    },\n    \"minimum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minimum\"\n    },\n    \"exclusiveMinimum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum\"\n    },\n    \"maxLength\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n    },\n    \"minLength\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n    },\n    \"pattern\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/pattern\"\n    },\n    \"maxItems\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveInteger\"\n    },\n    \"minItems\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0\"\n    },\n    \"uniqueItems\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/uniqueItems\"\n    },\n    \"enum\": {\n      \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/enum\"\n    },\n    \"jsonReference\": {\n      \"type\": \"object\",\n      \"required\": [\n        \"$ref\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    }\n  }\n}"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.go",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\n// THIS FILE IS AUTOMATICALLY GENERATED.\n\npackage openapi_v3\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/google/gnostic/compiler\"\n)\n\n// Version returns the package name (and OpenAPI version).\nfunc Version() string {\n\treturn \"openapi_v3\"\n}\n\n// NewAdditionalPropertiesItem creates an object of type AdditionalPropertiesItem if possible, returning an error if not.\nfunc NewAdditionalPropertiesItem(in *yaml.Node, context *compiler.Context) (*AdditionalPropertiesItem, error) {\n\terrors := make([]error, 0)\n\tx := &AdditionalPropertiesItem{}\n\tmatched := false\n\t// SchemaOrReference schema_or_reference = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewSchemaOrReference(m, compiler.NewContext(\"schemaOrReference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &AdditionalPropertiesItem_SchemaOrReference{SchemaOrReference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// bool boolean = 2;\n\tboolValue, ok := compiler.BoolForScalarNode(in)\n\tif ok {\n\t\tx.Oneof = &AdditionalPropertiesItem_Boolean{Boolean: boolValue}\n\t\tmatched = true\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid AdditionalPropertiesItem\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewAny creates an object of type Any if possible, returning an error if not.\nfunc NewAny(in *yaml.Node, context *compiler.Context) (*Any, error) {\n\terrors := make([]error, 0)\n\tx := &Any{}\n\tbytes := compiler.Marshal(in)\n\tx.Yaml = string(bytes)\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewAnyOrExpression creates an object of type AnyOrExpression if possible, returning an error if not.\nfunc NewAnyOrExpression(in *yaml.Node, context *compiler.Context) (*AnyOrExpression, error) {\n\terrors := make([]error, 0)\n\tx := &AnyOrExpression{}\n\tmatched := false\n\t// Any any = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewAny(m, compiler.NewContext(\"any\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &AnyOrExpression_Any{Any: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Expression expression = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewExpression(m, compiler.NewContext(\"expression\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &AnyOrExpression_Expression{Expression: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid AnyOrExpression\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewCallback creates an object of type Callback if possible, returning an error if not.\nfunc NewCallback(in *yaml.Node, context *compiler.Context) (*Callback, error) {\n\terrors := make([]error, 0)\n\tx := &Callback{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{}\n\t\tallowedPatterns := []*regexp.Regexp{pattern0, pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// repeated NamedPathItem path = 1;\n\t\t// MAP: PathItem ^\n\t\tx.Path = make([]*NamedPathItem, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif true {\n\t\t\t\t\tpair := &NamedPathItem{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tvar err error\n\t\t\t\t\tpair.Value, err = NewPathItem(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Path = append(x.Path, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 2;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewCallbackOrReference creates an object of type CallbackOrReference if possible, returning an error if not.\nfunc NewCallbackOrReference(in *yaml.Node, context *compiler.Context) (*CallbackOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &CallbackOrReference{}\n\tmatched := false\n\t// Callback callback = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewCallback(m, compiler.NewContext(\"callback\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &CallbackOrReference_Callback{Callback: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &CallbackOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid CallbackOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewCallbacksOrReferences creates an object of type CallbacksOrReferences if possible, returning an error if not.\nfunc NewCallbacksOrReferences(in *yaml.Node, context *compiler.Context) (*CallbacksOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &CallbacksOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedCallbackOrReference additional_properties = 1;\n\t\t// MAP: CallbackOrReference\n\t\tx.AdditionalProperties = make([]*NamedCallbackOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedCallbackOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewCallbackOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewComponents creates an object of type Components if possible, returning an error if not.\nfunc NewComponents(in *yaml.Node, context *compiler.Context) (*Components, error) {\n\terrors := make([]error, 0)\n\tx := &Components{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"callbacks\", \"examples\", \"headers\", \"links\", \"parameters\", \"requestBodies\", \"responses\", \"schemas\", \"securitySchemes\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// SchemasOrReferences schemas = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"schemas\")\n\t\tif v1 != nil {\n\t\t\tvar err error\n\t\t\tx.Schemas, err = NewSchemasOrReferences(v1, compiler.NewContext(\"schemas\", v1, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ResponsesOrReferences responses = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"responses\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Responses, err = NewResponsesOrReferences(v2, compiler.NewContext(\"responses\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ParametersOrReferences parameters = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"parameters\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Parameters, err = NewParametersOrReferences(v3, compiler.NewContext(\"parameters\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ExamplesOrReferences examples = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"examples\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Examples, err = NewExamplesOrReferences(v4, compiler.NewContext(\"examples\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// RequestBodiesOrReferences request_bodies = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"requestBodies\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.RequestBodies, err = NewRequestBodiesOrReferences(v5, compiler.NewContext(\"requestBodies\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// HeadersOrReferences headers = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"headers\")\n\t\tif v6 != nil {\n\t\t\tvar err error\n\t\t\tx.Headers, err = NewHeadersOrReferences(v6, compiler.NewContext(\"headers\", v6, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// SecuritySchemesOrReferences security_schemes = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"securitySchemes\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.SecuritySchemes, err = NewSecuritySchemesOrReferences(v7, compiler.NewContext(\"securitySchemes\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// LinksOrReferences links = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"links\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Links, err = NewLinksOrReferences(v8, compiler.NewContext(\"links\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// CallbacksOrReferences callbacks = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"callbacks\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Callbacks, err = NewCallbacksOrReferences(v9, compiler.NewContext(\"callbacks\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 10;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewContact creates an object of type Contact if possible, returning an error if not.\nfunc NewContact(in *yaml.Node, context *compiler.Context) (*Contact, error) {\n\terrors := make([]error, 0)\n\tx := &Contact{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"email\", \"name\", \"url\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string url = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"url\")\n\t\tif v2 != nil {\n\t\t\tx.Url, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for url: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string email = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"email\")\n\t\tif v3 != nil {\n\t\t\tx.Email, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for email: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 4;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewDefaultType creates an object of type DefaultType if possible, returning an error if not.\nfunc NewDefaultType(in *yaml.Node, context *compiler.Context) (*DefaultType, error) {\n\terrors := make([]error, 0)\n\tx := &DefaultType{}\n\tmatched := false\n\tswitch in.Tag {\n\tcase \"!!bool\":\n\t\tvar v bool\n\t\tv, matched = compiler.BoolForScalarNode(in)\n\t\tx.Oneof = &DefaultType_Boolean{Boolean: v}\n\tcase \"!!str\":\n\t\tvar v string\n\t\tv, matched = compiler.StringForScalarNode(in)\n\t\tx.Oneof = &DefaultType_String_{String_: v}\n\tcase \"!!float\":\n\t\tvar v float64\n\t\tv, matched = compiler.FloatForScalarNode(in)\n\t\tx.Oneof = &DefaultType_Number{Number: v}\n\tcase \"!!int\":\n\t\tvar v int64\n\t\tv, matched = compiler.IntForScalarNode(in)\n\t\tx.Oneof = &DefaultType_Number{Number: float64(v)}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewDiscriminator creates an object of type Discriminator if possible, returning an error if not.\nfunc NewDiscriminator(in *yaml.Node, context *compiler.Context) (*Discriminator, error) {\n\terrors := make([]error, 0)\n\tx := &Discriminator{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"propertyName\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"mapping\", \"propertyName\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string property_name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"propertyName\")\n\t\tif v1 != nil {\n\t\t\tx.PropertyName, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for propertyName: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Strings mapping = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"mapping\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Mapping, err = NewStrings(v2, compiler.NewContext(\"mapping\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 3;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewDocument creates an object of type Document if possible, returning an error if not.\nfunc NewDocument(in *yaml.Node, context *compiler.Context) (*Document, error) {\n\terrors := make([]error, 0)\n\tx := &Document{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"info\", \"openapi\", \"paths\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"components\", \"externalDocs\", \"info\", \"openapi\", \"paths\", \"security\", \"servers\", \"tags\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string openapi = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"openapi\")\n\t\tif v1 != nil {\n\t\t\tx.Openapi, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for openapi: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Info info = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"info\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Info, err = NewInfo(v2, compiler.NewContext(\"info\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated Server servers = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"servers\")\n\t\tif v3 != nil {\n\t\t\t// repeated Server\n\t\t\tx.Servers = make([]*Server, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v3)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewServer(item, compiler.NewContext(\"servers\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Servers = append(x.Servers, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Paths paths = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"paths\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Paths, err = NewPaths(v4, compiler.NewContext(\"paths\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Components components = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"components\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Components, err = NewComponents(v5, compiler.NewContext(\"components\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated SecurityRequirement security = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"security\")\n\t\tif v6 != nil {\n\t\t\t// repeated SecurityRequirement\n\t\t\tx.Security = make([]*SecurityRequirement, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v6)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSecurityRequirement(item, compiler.NewContext(\"security\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Security = append(x.Security, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated Tag tags = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"tags\")\n\t\tif v7 != nil {\n\t\t\t// repeated Tag\n\t\t\tx.Tags = make([]*Tag, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v7)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewTag(item, compiler.NewContext(\"tags\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Tags = append(x.Tags, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v8, compiler.NewContext(\"externalDocs\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 9;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewEncoding creates an object of type Encoding if possible, returning an error if not.\nfunc NewEncoding(in *yaml.Node, context *compiler.Context) (*Encoding, error) {\n\terrors := make([]error, 0)\n\tx := &Encoding{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"allowReserved\", \"contentType\", \"explode\", \"headers\", \"style\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string content_type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"contentType\")\n\t\tif v1 != nil {\n\t\t\tx.ContentType, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for contentType: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// HeadersOrReferences headers = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"headers\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Headers, err = NewHeadersOrReferences(v2, compiler.NewContext(\"headers\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string style = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"style\")\n\t\tif v3 != nil {\n\t\t\tx.Style, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for style: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool explode = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"explode\")\n\t\tif v4 != nil {\n\t\t\tx.Explode, ok = compiler.BoolForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for explode: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool allow_reserved = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"allowReserved\")\n\t\tif v5 != nil {\n\t\t\tx.AllowReserved, ok = compiler.BoolForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for allowReserved: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 6;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewEncodings creates an object of type Encodings if possible, returning an error if not.\nfunc NewEncodings(in *yaml.Node, context *compiler.Context) (*Encodings, error) {\n\terrors := make([]error, 0)\n\tx := &Encodings{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedEncoding additional_properties = 1;\n\t\t// MAP: Encoding\n\t\tx.AdditionalProperties = make([]*NamedEncoding, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedEncoding{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewEncoding(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewExample creates an object of type Example if possible, returning an error if not.\nfunc NewExample(in *yaml.Node, context *compiler.Context) (*Example, error) {\n\terrors := make([]error, 0)\n\tx := &Example{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"description\", \"externalValue\", \"summary\", \"value\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string summary = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"summary\")\n\t\tif v1 != nil {\n\t\t\tx.Summary, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for summary: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any value = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"value\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewAny(v3, compiler.NewContext(\"value\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string external_value = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"externalValue\")\n\t\tif v4 != nil {\n\t\t\tx.ExternalValue, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for externalValue: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 5;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewExampleOrReference creates an object of type ExampleOrReference if possible, returning an error if not.\nfunc NewExampleOrReference(in *yaml.Node, context *compiler.Context) (*ExampleOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &ExampleOrReference{}\n\tmatched := false\n\t// Example example = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewExample(m, compiler.NewContext(\"example\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ExampleOrReference_Example{Example: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ExampleOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid ExampleOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewExamplesOrReferences creates an object of type ExamplesOrReferences if possible, returning an error if not.\nfunc NewExamplesOrReferences(in *yaml.Node, context *compiler.Context) (*ExamplesOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &ExamplesOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedExampleOrReference additional_properties = 1;\n\t\t// MAP: ExampleOrReference\n\t\tx.AdditionalProperties = make([]*NamedExampleOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedExampleOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewExampleOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewExpression creates an object of type Expression if possible, returning an error if not.\nfunc NewExpression(in *yaml.Node, context *compiler.Context) (*Expression, error) {\n\terrors := make([]error, 0)\n\tx := &Expression{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedAny additional_properties = 1;\n\t\t// MAP: Any\n\t\tx.AdditionalProperties = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedAny{}\n\t\t\t\tpair.Name = k\n\t\t\t\tresult := &Any{}\n\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\tif handled {\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewExternalDocs creates an object of type ExternalDocs if possible, returning an error if not.\nfunc NewExternalDocs(in *yaml.Node, context *compiler.Context) (*ExternalDocs, error) {\n\terrors := make([]error, 0)\n\tx := &ExternalDocs{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"url\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"url\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string description = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"description\")\n\t\tif v1 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string url = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"url\")\n\t\tif v2 != nil {\n\t\t\tx.Url, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for url: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 3;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewHeader creates an object of type Header if possible, returning an error if not.\nfunc NewHeader(in *yaml.Node, context *compiler.Context) (*Header, error) {\n\terrors := make([]error, 0)\n\tx := &Header{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"allowEmptyValue\", \"allowReserved\", \"content\", \"deprecated\", \"description\", \"example\", \"examples\", \"explode\", \"required\", \"schema\", \"style\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string description = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"description\")\n\t\tif v1 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool required = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"required\")\n\t\tif v2 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool deprecated = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"deprecated\")\n\t\tif v3 != nil {\n\t\t\tx.Deprecated, ok = compiler.BoolForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for deprecated: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool allow_empty_value = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"allowEmptyValue\")\n\t\tif v4 != nil {\n\t\t\tx.AllowEmptyValue, ok = compiler.BoolForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for allowEmptyValue: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string style = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"style\")\n\t\tif v5 != nil {\n\t\t\tx.Style, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for style: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool explode = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"explode\")\n\t\tif v6 != nil {\n\t\t\tx.Explode, ok = compiler.BoolForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for explode: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool allow_reserved = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"allowReserved\")\n\t\tif v7 != nil {\n\t\t\tx.AllowReserved, ok = compiler.BoolForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for allowReserved: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// SchemaOrReference schema = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"schema\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Schema, err = NewSchemaOrReference(v8, compiler.NewContext(\"schema\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Any example = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"example\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Example, err = NewAny(v9, compiler.NewContext(\"example\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ExamplesOrReferences examples = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"examples\")\n\t\tif v10 != nil {\n\t\t\tvar err error\n\t\t\tx.Examples, err = NewExamplesOrReferences(v10, compiler.NewContext(\"examples\", v10, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// MediaTypes content = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"content\")\n\t\tif v11 != nil {\n\t\t\tvar err error\n\t\t\tx.Content, err = NewMediaTypes(v11, compiler.NewContext(\"content\", v11, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 12;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewHeaderOrReference creates an object of type HeaderOrReference if possible, returning an error if not.\nfunc NewHeaderOrReference(in *yaml.Node, context *compiler.Context) (*HeaderOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &HeaderOrReference{}\n\tmatched := false\n\t// Header header = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewHeader(m, compiler.NewContext(\"header\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &HeaderOrReference_Header{Header: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &HeaderOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid HeaderOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewHeadersOrReferences creates an object of type HeadersOrReferences if possible, returning an error if not.\nfunc NewHeadersOrReferences(in *yaml.Node, context *compiler.Context) (*HeadersOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &HeadersOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedHeaderOrReference additional_properties = 1;\n\t\t// MAP: HeaderOrReference\n\t\tx.AdditionalProperties = make([]*NamedHeaderOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedHeaderOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewHeaderOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewInfo creates an object of type Info if possible, returning an error if not.\nfunc NewInfo(in *yaml.Node, context *compiler.Context) (*Info, error) {\n\terrors := make([]error, 0)\n\tx := &Info{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"title\", \"version\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"contact\", \"description\", \"license\", \"summary\", \"termsOfService\", \"title\", \"version\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string title = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"title\")\n\t\tif v1 != nil {\n\t\t\tx.Title, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for title: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string terms_of_service = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"termsOfService\")\n\t\tif v3 != nil {\n\t\t\tx.TermsOfService, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for termsOfService: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Contact contact = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"contact\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Contact, err = NewContact(v4, compiler.NewContext(\"contact\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// License license = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"license\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.License, err = NewLicense(v5, compiler.NewContext(\"license\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string version = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"version\")\n\t\tif v6 != nil {\n\t\t\tx.Version, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for version: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string summary = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"summary\")\n\t\tif v7 != nil {\n\t\t\tx.Summary, ok = compiler.StringForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for summary: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 8;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewItemsItem creates an object of type ItemsItem if possible, returning an error if not.\nfunc NewItemsItem(in *yaml.Node, context *compiler.Context) (*ItemsItem, error) {\n\terrors := make([]error, 0)\n\tx := &ItemsItem{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value for item array: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tx.SchemaOrReference = make([]*SchemaOrReference, 0)\n\t\ty, err := NewSchemaOrReference(m, compiler.NewContext(\"<array>\", m, context))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tx.SchemaOrReference = append(x.SchemaOrReference, y)\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewLicense creates an object of type License if possible, returning an error if not.\nfunc NewLicense(in *yaml.Node, context *compiler.Context) (*License, error) {\n\terrors := make([]error, 0)\n\tx := &License{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"name\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"name\", \"url\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string url = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"url\")\n\t\tif v2 != nil {\n\t\t\tx.Url, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for url: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 3;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewLink creates an object of type Link if possible, returning an error if not.\nfunc NewLink(in *yaml.Node, context *compiler.Context) (*Link, error) {\n\terrors := make([]error, 0)\n\tx := &Link{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"description\", \"operationId\", \"operationRef\", \"parameters\", \"requestBody\", \"server\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string operation_ref = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"operationRef\")\n\t\tif v1 != nil {\n\t\t\tx.OperationRef, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for operationRef: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string operation_id = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"operationId\")\n\t\tif v2 != nil {\n\t\t\tx.OperationId, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for operationId: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// AnyOrExpression parameters = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"parameters\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Parameters, err = NewAnyOrExpression(v3, compiler.NewContext(\"parameters\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// AnyOrExpression request_body = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"requestBody\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.RequestBody, err = NewAnyOrExpression(v4, compiler.NewContext(\"requestBody\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string description = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"description\")\n\t\tif v5 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Server server = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"server\")\n\t\tif v6 != nil {\n\t\t\tvar err error\n\t\t\tx.Server, err = NewServer(v6, compiler.NewContext(\"server\", v6, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 7;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewLinkOrReference creates an object of type LinkOrReference if possible, returning an error if not.\nfunc NewLinkOrReference(in *yaml.Node, context *compiler.Context) (*LinkOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &LinkOrReference{}\n\tmatched := false\n\t// Link link = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewLink(m, compiler.NewContext(\"link\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &LinkOrReference_Link{Link: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &LinkOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid LinkOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewLinksOrReferences creates an object of type LinksOrReferences if possible, returning an error if not.\nfunc NewLinksOrReferences(in *yaml.Node, context *compiler.Context) (*LinksOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &LinksOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedLinkOrReference additional_properties = 1;\n\t\t// MAP: LinkOrReference\n\t\tx.AdditionalProperties = make([]*NamedLinkOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedLinkOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewLinkOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewMediaType creates an object of type MediaType if possible, returning an error if not.\nfunc NewMediaType(in *yaml.Node, context *compiler.Context) (*MediaType, error) {\n\terrors := make([]error, 0)\n\tx := &MediaType{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"encoding\", \"example\", \"examples\", \"schema\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// SchemaOrReference schema = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"schema\")\n\t\tif v1 != nil {\n\t\t\tvar err error\n\t\t\tx.Schema, err = NewSchemaOrReference(v1, compiler.NewContext(\"schema\", v1, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Any example = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"example\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Example, err = NewAny(v2, compiler.NewContext(\"example\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ExamplesOrReferences examples = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"examples\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Examples, err = NewExamplesOrReferences(v3, compiler.NewContext(\"examples\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Encodings encoding = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"encoding\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Encoding, err = NewEncodings(v4, compiler.NewContext(\"encoding\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 5;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewMediaTypes creates an object of type MediaTypes if possible, returning an error if not.\nfunc NewMediaTypes(in *yaml.Node, context *compiler.Context) (*MediaTypes, error) {\n\terrors := make([]error, 0)\n\tx := &MediaTypes{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedMediaType additional_properties = 1;\n\t\t// MAP: MediaType\n\t\tx.AdditionalProperties = make([]*NamedMediaType, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedMediaType{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewMediaType(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedAny creates an object of type NamedAny if possible, returning an error if not.\nfunc NewNamedAny(in *yaml.Node, context *compiler.Context) (*NamedAny, error) {\n\terrors := make([]error, 0)\n\tx := &NamedAny{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Any value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewAny(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedCallbackOrReference creates an object of type NamedCallbackOrReference if possible, returning an error if not.\nfunc NewNamedCallbackOrReference(in *yaml.Node, context *compiler.Context) (*NamedCallbackOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedCallbackOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// CallbackOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewCallbackOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedEncoding creates an object of type NamedEncoding if possible, returning an error if not.\nfunc NewNamedEncoding(in *yaml.Node, context *compiler.Context) (*NamedEncoding, error) {\n\terrors := make([]error, 0)\n\tx := &NamedEncoding{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Encoding value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewEncoding(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedExampleOrReference creates an object of type NamedExampleOrReference if possible, returning an error if not.\nfunc NewNamedExampleOrReference(in *yaml.Node, context *compiler.Context) (*NamedExampleOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedExampleOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ExampleOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewExampleOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedHeaderOrReference creates an object of type NamedHeaderOrReference if possible, returning an error if not.\nfunc NewNamedHeaderOrReference(in *yaml.Node, context *compiler.Context) (*NamedHeaderOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedHeaderOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// HeaderOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewHeaderOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedLinkOrReference creates an object of type NamedLinkOrReference if possible, returning an error if not.\nfunc NewNamedLinkOrReference(in *yaml.Node, context *compiler.Context) (*NamedLinkOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedLinkOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// LinkOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewLinkOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedMediaType creates an object of type NamedMediaType if possible, returning an error if not.\nfunc NewNamedMediaType(in *yaml.Node, context *compiler.Context) (*NamedMediaType, error) {\n\terrors := make([]error, 0)\n\tx := &NamedMediaType{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// MediaType value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewMediaType(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedParameterOrReference creates an object of type NamedParameterOrReference if possible, returning an error if not.\nfunc NewNamedParameterOrReference(in *yaml.Node, context *compiler.Context) (*NamedParameterOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedParameterOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ParameterOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewParameterOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedPathItem creates an object of type NamedPathItem if possible, returning an error if not.\nfunc NewNamedPathItem(in *yaml.Node, context *compiler.Context) (*NamedPathItem, error) {\n\terrors := make([]error, 0)\n\tx := &NamedPathItem{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// PathItem value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewPathItem(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedRequestBodyOrReference creates an object of type NamedRequestBodyOrReference if possible, returning an error if not.\nfunc NewNamedRequestBodyOrReference(in *yaml.Node, context *compiler.Context) (*NamedRequestBodyOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedRequestBodyOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// RequestBodyOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewRequestBodyOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedResponseOrReference creates an object of type NamedResponseOrReference if possible, returning an error if not.\nfunc NewNamedResponseOrReference(in *yaml.Node, context *compiler.Context) (*NamedResponseOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedResponseOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ResponseOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewResponseOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedSchemaOrReference creates an object of type NamedSchemaOrReference if possible, returning an error if not.\nfunc NewNamedSchemaOrReference(in *yaml.Node, context *compiler.Context) (*NamedSchemaOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedSchemaOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// SchemaOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewSchemaOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedSecuritySchemeOrReference creates an object of type NamedSecuritySchemeOrReference if possible, returning an error if not.\nfunc NewNamedSecuritySchemeOrReference(in *yaml.Node, context *compiler.Context) (*NamedSecuritySchemeOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &NamedSecuritySchemeOrReference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// SecuritySchemeOrReference value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewSecuritySchemeOrReference(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedServerVariable creates an object of type NamedServerVariable if possible, returning an error if not.\nfunc NewNamedServerVariable(in *yaml.Node, context *compiler.Context) (*NamedServerVariable, error) {\n\terrors := make([]error, 0)\n\tx := &NamedServerVariable{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ServerVariable value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewServerVariable(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedString creates an object of type NamedString if possible, returning an error if not.\nfunc NewNamedString(in *yaml.Node, context *compiler.Context) (*NamedString, error) {\n\terrors := make([]error, 0)\n\tx := &NamedString{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tx.Value, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for value: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewNamedStringArray creates an object of type NamedStringArray if possible, returning an error if not.\nfunc NewNamedStringArray(in *yaml.Node, context *compiler.Context) (*NamedStringArray, error) {\n\terrors := make([]error, 0)\n\tx := &NamedStringArray{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"name\", \"value\"}\n\t\tvar allowedPatterns []*regexp.Regexp\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// StringArray value = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"value\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Value, err = NewStringArray(v2, compiler.NewContext(\"value\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOauthFlow creates an object of type OauthFlow if possible, returning an error if not.\nfunc NewOauthFlow(in *yaml.Node, context *compiler.Context) (*OauthFlow, error) {\n\terrors := make([]error, 0)\n\tx := &OauthFlow{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"authorizationUrl\", \"refreshUrl\", \"scopes\", \"tokenUrl\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string authorization_url = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"authorizationUrl\")\n\t\tif v1 != nil {\n\t\t\tx.AuthorizationUrl, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for authorizationUrl: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string token_url = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"tokenUrl\")\n\t\tif v2 != nil {\n\t\t\tx.TokenUrl, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for tokenUrl: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string refresh_url = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"refreshUrl\")\n\t\tif v3 != nil {\n\t\t\tx.RefreshUrl, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for refreshUrl: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Strings scopes = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"scopes\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Scopes, err = NewStrings(v4, compiler.NewContext(\"scopes\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 5;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOauthFlows creates an object of type OauthFlows if possible, returning an error if not.\nfunc NewOauthFlows(in *yaml.Node, context *compiler.Context) (*OauthFlows, error) {\n\terrors := make([]error, 0)\n\tx := &OauthFlows{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"authorizationCode\", \"clientCredentials\", \"implicit\", \"password\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// OauthFlow implicit = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"implicit\")\n\t\tif v1 != nil {\n\t\t\tvar err error\n\t\t\tx.Implicit, err = NewOauthFlow(v1, compiler.NewContext(\"implicit\", v1, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// OauthFlow password = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"password\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Password, err = NewOauthFlow(v2, compiler.NewContext(\"password\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// OauthFlow client_credentials = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"clientCredentials\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.ClientCredentials, err = NewOauthFlow(v3, compiler.NewContext(\"clientCredentials\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// OauthFlow authorization_code = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"authorizationCode\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.AuthorizationCode, err = NewOauthFlow(v4, compiler.NewContext(\"authorizationCode\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 5;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewObject creates an object of type Object if possible, returning an error if not.\nfunc NewObject(in *yaml.Node, context *compiler.Context) (*Object, error) {\n\terrors := make([]error, 0)\n\tx := &Object{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedAny additional_properties = 1;\n\t\t// MAP: Any\n\t\tx.AdditionalProperties = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedAny{}\n\t\t\t\tpair.Name = k\n\t\t\t\tresult := &Any{}\n\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\tif handled {\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewOperation creates an object of type Operation if possible, returning an error if not.\nfunc NewOperation(in *yaml.Node, context *compiler.Context) (*Operation, error) {\n\terrors := make([]error, 0)\n\tx := &Operation{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"responses\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"callbacks\", \"deprecated\", \"description\", \"externalDocs\", \"operationId\", \"parameters\", \"requestBody\", \"responses\", \"security\", \"servers\", \"summary\", \"tags\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// repeated string tags = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"tags\")\n\t\tif v1 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v1)\n\t\t\tif ok {\n\t\t\t\tx.Tags = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for tags: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string summary = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"summary\")\n\t\tif v2 != nil {\n\t\t\tx.Summary, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for summary: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v4, compiler.NewContext(\"externalDocs\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string operation_id = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"operationId\")\n\t\tif v5 != nil {\n\t\t\tx.OperationId, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for operationId: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated ParameterOrReference parameters = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"parameters\")\n\t\tif v6 != nil {\n\t\t\t// repeated ParameterOrReference\n\t\t\tx.Parameters = make([]*ParameterOrReference, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v6)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewParameterOrReference(item, compiler.NewContext(\"parameters\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Parameters = append(x.Parameters, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// RequestBodyOrReference request_body = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"requestBody\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.RequestBody, err = NewRequestBodyOrReference(v7, compiler.NewContext(\"requestBody\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Responses responses = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"responses\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Responses, err = NewResponses(v8, compiler.NewContext(\"responses\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// CallbacksOrReferences callbacks = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"callbacks\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Callbacks, err = NewCallbacksOrReferences(v9, compiler.NewContext(\"callbacks\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// bool deprecated = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"deprecated\")\n\t\tif v10 != nil {\n\t\t\tx.Deprecated, ok = compiler.BoolForScalarNode(v10)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for deprecated: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated SecurityRequirement security = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"security\")\n\t\tif v11 != nil {\n\t\t\t// repeated SecurityRequirement\n\t\t\tx.Security = make([]*SecurityRequirement, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v11)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSecurityRequirement(item, compiler.NewContext(\"security\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Security = append(x.Security, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated Server servers = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"servers\")\n\t\tif v12 != nil {\n\t\t\t// repeated Server\n\t\t\tx.Servers = make([]*Server, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v12)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewServer(item, compiler.NewContext(\"servers\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Servers = append(x.Servers, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 13;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewParameter creates an object of type Parameter if possible, returning an error if not.\nfunc NewParameter(in *yaml.Node, context *compiler.Context) (*Parameter, error) {\n\terrors := make([]error, 0)\n\tx := &Parameter{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"in\", \"name\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"allowEmptyValue\", \"allowReserved\", \"content\", \"deprecated\", \"description\", \"example\", \"examples\", \"explode\", \"in\", \"name\", \"required\", \"schema\", \"style\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"in\")\n\t\tif v2 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool required = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"required\")\n\t\tif v4 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool deprecated = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"deprecated\")\n\t\tif v5 != nil {\n\t\t\tx.Deprecated, ok = compiler.BoolForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for deprecated: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool allow_empty_value = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"allowEmptyValue\")\n\t\tif v6 != nil {\n\t\t\tx.AllowEmptyValue, ok = compiler.BoolForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for allowEmptyValue: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string style = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"style\")\n\t\tif v7 != nil {\n\t\t\tx.Style, ok = compiler.StringForScalarNode(v7)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for style: %s\", compiler.Display(v7))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool explode = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"explode\")\n\t\tif v8 != nil {\n\t\t\tx.Explode, ok = compiler.BoolForScalarNode(v8)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for explode: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool allow_reserved = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"allowReserved\")\n\t\tif v9 != nil {\n\t\t\tx.AllowReserved, ok = compiler.BoolForScalarNode(v9)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for allowReserved: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// SchemaOrReference schema = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"schema\")\n\t\tif v10 != nil {\n\t\t\tvar err error\n\t\t\tx.Schema, err = NewSchemaOrReference(v10, compiler.NewContext(\"schema\", v10, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Any example = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"example\")\n\t\tif v11 != nil {\n\t\t\tvar err error\n\t\t\tx.Example, err = NewAny(v11, compiler.NewContext(\"example\", v11, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ExamplesOrReferences examples = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"examples\")\n\t\tif v12 != nil {\n\t\t\tvar err error\n\t\t\tx.Examples, err = NewExamplesOrReferences(v12, compiler.NewContext(\"examples\", v12, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// MediaTypes content = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"content\")\n\t\tif v13 != nil {\n\t\t\tvar err error\n\t\t\tx.Content, err = NewMediaTypes(v13, compiler.NewContext(\"content\", v13, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 14;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewParameterOrReference creates an object of type ParameterOrReference if possible, returning an error if not.\nfunc NewParameterOrReference(in *yaml.Node, context *compiler.Context) (*ParameterOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &ParameterOrReference{}\n\tmatched := false\n\t// Parameter parameter = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewParameter(m, compiler.NewContext(\"parameter\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ParameterOrReference_Parameter{Parameter: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ParameterOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid ParameterOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewParametersOrReferences creates an object of type ParametersOrReferences if possible, returning an error if not.\nfunc NewParametersOrReferences(in *yaml.Node, context *compiler.Context) (*ParametersOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &ParametersOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedParameterOrReference additional_properties = 1;\n\t\t// MAP: ParameterOrReference\n\t\tx.AdditionalProperties = make([]*NamedParameterOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedParameterOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewParameterOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewPathItem creates an object of type PathItem if possible, returning an error if not.\nfunc NewPathItem(in *yaml.Node, context *compiler.Context) (*PathItem, error) {\n\terrors := make([]error, 0)\n\tx := &PathItem{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"$ref\", \"delete\", \"description\", \"get\", \"head\", \"options\", \"parameters\", \"patch\", \"post\", \"put\", \"servers\", \"summary\", \"trace\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string _ref = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"$ref\")\n\t\tif v1 != nil {\n\t\t\tx.XRef, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for $ref: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string summary = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"summary\")\n\t\tif v2 != nil {\n\t\t\tx.Summary, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for summary: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Operation get = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"get\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Get, err = NewOperation(v4, compiler.NewContext(\"get\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation put = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"put\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Put, err = NewOperation(v5, compiler.NewContext(\"put\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation post = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"post\")\n\t\tif v6 != nil {\n\t\t\tvar err error\n\t\t\tx.Post, err = NewOperation(v6, compiler.NewContext(\"post\", v6, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation delete = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"delete\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.Delete, err = NewOperation(v7, compiler.NewContext(\"delete\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation options = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"options\")\n\t\tif v8 != nil {\n\t\t\tvar err error\n\t\t\tx.Options, err = NewOperation(v8, compiler.NewContext(\"options\", v8, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation head = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"head\")\n\t\tif v9 != nil {\n\t\t\tvar err error\n\t\t\tx.Head, err = NewOperation(v9, compiler.NewContext(\"head\", v9, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation patch = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"patch\")\n\t\tif v10 != nil {\n\t\t\tvar err error\n\t\t\tx.Patch, err = NewOperation(v10, compiler.NewContext(\"patch\", v10, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Operation trace = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"trace\")\n\t\tif v11 != nil {\n\t\t\tvar err error\n\t\t\tx.Trace, err = NewOperation(v11, compiler.NewContext(\"trace\", v11, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated Server servers = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"servers\")\n\t\tif v12 != nil {\n\t\t\t// repeated Server\n\t\t\tx.Servers = make([]*Server, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v12)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewServer(item, compiler.NewContext(\"servers\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Servers = append(x.Servers, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated ParameterOrReference parameters = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"parameters\")\n\t\tif v13 != nil {\n\t\t\t// repeated ParameterOrReference\n\t\t\tx.Parameters = make([]*ParameterOrReference, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v13)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewParameterOrReference(item, compiler.NewContext(\"parameters\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Parameters = append(x.Parameters, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 14;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewPaths creates an object of type Paths if possible, returning an error if not.\nfunc NewPaths(in *yaml.Node, context *compiler.Context) (*Paths, error) {\n\terrors := make([]error, 0)\n\tx := &Paths{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{}\n\t\tallowedPatterns := []*regexp.Regexp{pattern2, pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// repeated NamedPathItem path = 1;\n\t\t// MAP: PathItem ^/\n\t\tx.Path = make([]*NamedPathItem, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"/\") {\n\t\t\t\t\tpair := &NamedPathItem{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tvar err error\n\t\t\t\t\tpair.Value, err = NewPathItem(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Path = append(x.Path, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 2;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewProperties creates an object of type Properties if possible, returning an error if not.\nfunc NewProperties(in *yaml.Node, context *compiler.Context) (*Properties, error) {\n\terrors := make([]error, 0)\n\tx := &Properties{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedSchemaOrReference additional_properties = 1;\n\t\t// MAP: SchemaOrReference\n\t\tx.AdditionalProperties = make([]*NamedSchemaOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedSchemaOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewSchemaOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewReference creates an object of type Reference if possible, returning an error if not.\nfunc NewReference(in *yaml.Node, context *compiler.Context) (*Reference, error) {\n\terrors := make([]error, 0)\n\tx := &Reference{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"$ref\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string _ref = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"$ref\")\n\t\tif v1 != nil {\n\t\t\tx.XRef, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for $ref: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string summary = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"summary\")\n\t\tif v2 != nil {\n\t\t\tx.Summary, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for summary: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewRequestBodiesOrReferences creates an object of type RequestBodiesOrReferences if possible, returning an error if not.\nfunc NewRequestBodiesOrReferences(in *yaml.Node, context *compiler.Context) (*RequestBodiesOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &RequestBodiesOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedRequestBodyOrReference additional_properties = 1;\n\t\t// MAP: RequestBodyOrReference\n\t\tx.AdditionalProperties = make([]*NamedRequestBodyOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedRequestBodyOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewRequestBodyOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewRequestBody creates an object of type RequestBody if possible, returning an error if not.\nfunc NewRequestBody(in *yaml.Node, context *compiler.Context) (*RequestBody, error) {\n\terrors := make([]error, 0)\n\tx := &RequestBody{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"content\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"content\", \"description\", \"required\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string description = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"description\")\n\t\tif v1 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// MediaTypes content = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"content\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Content, err = NewMediaTypes(v2, compiler.NewContext(\"content\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// bool required = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"required\")\n\t\tif v3 != nil {\n\t\t\tx.Required, ok = compiler.BoolForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 4;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewRequestBodyOrReference creates an object of type RequestBodyOrReference if possible, returning an error if not.\nfunc NewRequestBodyOrReference(in *yaml.Node, context *compiler.Context) (*RequestBodyOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &RequestBodyOrReference{}\n\tmatched := false\n\t// RequestBody request_body = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewRequestBody(m, compiler.NewContext(\"requestBody\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &RequestBodyOrReference_RequestBody{RequestBody: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &RequestBodyOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid RequestBodyOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponse creates an object of type Response if possible, returning an error if not.\nfunc NewResponse(in *yaml.Node, context *compiler.Context) (*Response, error) {\n\terrors := make([]error, 0)\n\tx := &Response{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"description\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"content\", \"description\", \"headers\", \"links\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string description = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"description\")\n\t\tif v1 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// HeadersOrReferences headers = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"headers\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Headers, err = NewHeadersOrReferences(v2, compiler.NewContext(\"headers\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// MediaTypes content = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"content\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Content, err = NewMediaTypes(v3, compiler.NewContext(\"content\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// LinksOrReferences links = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"links\")\n\t\tif v4 != nil {\n\t\t\tvar err error\n\t\t\tx.Links, err = NewLinksOrReferences(v4, compiler.NewContext(\"links\", v4, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 5;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponseOrReference creates an object of type ResponseOrReference if possible, returning an error if not.\nfunc NewResponseOrReference(in *yaml.Node, context *compiler.Context) (*ResponseOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &ResponseOrReference{}\n\tmatched := false\n\t// Response response = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewResponse(m, compiler.NewContext(\"response\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ResponseOrReference_Response{Response: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &ResponseOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid ResponseOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponses creates an object of type Responses if possible, returning an error if not.\nfunc NewResponses(in *yaml.Node, context *compiler.Context) (*Responses, error) {\n\terrors := make([]error, 0)\n\tx := &Responses{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"default\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern3, pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// ResponseOrReference default = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"default\")\n\t\tif v1 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewResponseOrReference(v1, compiler.NewContext(\"default\", v1, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedResponseOrReference response_or_reference = 2;\n\t\t// MAP: ResponseOrReference ^([0-9X]{3})$\n\t\tx.ResponseOrReference = make([]*NamedResponseOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif pattern3.MatchString(k) {\n\t\t\t\t\tpair := &NamedResponseOrReference{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tvar err error\n\t\t\t\t\tpair.Value, err = NewResponseOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.ResponseOrReference = append(x.ResponseOrReference, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 3;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewResponsesOrReferences creates an object of type ResponsesOrReferences if possible, returning an error if not.\nfunc NewResponsesOrReferences(in *yaml.Node, context *compiler.Context) (*ResponsesOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &ResponsesOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedResponseOrReference additional_properties = 1;\n\t\t// MAP: ResponseOrReference\n\t\tx.AdditionalProperties = make([]*NamedResponseOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedResponseOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewResponseOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSchema creates an object of type Schema if possible, returning an error if not.\nfunc NewSchema(in *yaml.Node, context *compiler.Context) (*Schema, error) {\n\terrors := make([]error, 0)\n\tx := &Schema{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"additionalProperties\", \"allOf\", \"anyOf\", \"default\", \"deprecated\", \"description\", \"discriminator\", \"enum\", \"example\", \"exclusiveMaximum\", \"exclusiveMinimum\", \"externalDocs\", \"format\", \"items\", \"maxItems\", \"maxLength\", \"maxProperties\", \"maximum\", \"minItems\", \"minLength\", \"minProperties\", \"minimum\", \"multipleOf\", \"not\", \"nullable\", \"oneOf\", \"pattern\", \"properties\", \"readOnly\", \"required\", \"title\", \"type\", \"uniqueItems\", \"writeOnly\", \"xml\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// bool nullable = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"nullable\")\n\t\tif v1 != nil {\n\t\t\tx.Nullable, ok = compiler.BoolForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for nullable: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Discriminator discriminator = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"discriminator\")\n\t\tif v2 != nil {\n\t\t\tvar err error\n\t\t\tx.Discriminator, err = NewDiscriminator(v2, compiler.NewContext(\"discriminator\", v2, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// bool read_only = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"readOnly\")\n\t\tif v3 != nil {\n\t\t\tx.ReadOnly, ok = compiler.BoolForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for readOnly: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool write_only = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"writeOnly\")\n\t\tif v4 != nil {\n\t\t\tx.WriteOnly, ok = compiler.BoolForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for writeOnly: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// Xml xml = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"xml\")\n\t\tif v5 != nil {\n\t\t\tvar err error\n\t\t\tx.Xml, err = NewXml(v5, compiler.NewContext(\"xml\", v5, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v6 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v6, compiler.NewContext(\"externalDocs\", v6, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Any example = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"example\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.Example, err = NewAny(v7, compiler.NewContext(\"example\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// bool deprecated = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"deprecated\")\n\t\tif v8 != nil {\n\t\t\tx.Deprecated, ok = compiler.BoolForScalarNode(v8)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for deprecated: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string title = 9;\n\t\tv9 := compiler.MapValueForKey(m, \"title\")\n\t\tif v9 != nil {\n\t\t\tx.Title, ok = compiler.StringForScalarNode(v9)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for title: %s\", compiler.Display(v9))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float multiple_of = 10;\n\t\tv10 := compiler.MapValueForKey(m, \"multipleOf\")\n\t\tif v10 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v10)\n\t\t\tif ok {\n\t\t\t\tx.MultipleOf = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for multipleOf: %s\", compiler.Display(v10))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float maximum = 11;\n\t\tv11 := compiler.MapValueForKey(m, \"maximum\")\n\t\tif v11 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v11)\n\t\t\tif ok {\n\t\t\t\tx.Maximum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maximum: %s\", compiler.Display(v11))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_maximum = 12;\n\t\tv12 := compiler.MapValueForKey(m, \"exclusiveMaximum\")\n\t\tif v12 != nil {\n\t\t\tx.ExclusiveMaximum, ok = compiler.BoolForScalarNode(v12)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMaximum: %s\", compiler.Display(v12))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// float minimum = 13;\n\t\tv13 := compiler.MapValueForKey(m, \"minimum\")\n\t\tif v13 != nil {\n\t\t\tv, ok := compiler.FloatForScalarNode(v13)\n\t\t\tif ok {\n\t\t\t\tx.Minimum = v\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minimum: %s\", compiler.Display(v13))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool exclusive_minimum = 14;\n\t\tv14 := compiler.MapValueForKey(m, \"exclusiveMinimum\")\n\t\tif v14 != nil {\n\t\t\tx.ExclusiveMinimum, ok = compiler.BoolForScalarNode(v14)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for exclusiveMinimum: %s\", compiler.Display(v14))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_length = 15;\n\t\tv15 := compiler.MapValueForKey(m, \"maxLength\")\n\t\tif v15 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v15)\n\t\t\tif ok {\n\t\t\t\tx.MaxLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxLength: %s\", compiler.Display(v15))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_length = 16;\n\t\tv16 := compiler.MapValueForKey(m, \"minLength\")\n\t\tif v16 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v16)\n\t\t\tif ok {\n\t\t\t\tx.MinLength = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minLength: %s\", compiler.Display(v16))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string pattern = 17;\n\t\tv17 := compiler.MapValueForKey(m, \"pattern\")\n\t\tif v17 != nil {\n\t\t\tx.Pattern, ok = compiler.StringForScalarNode(v17)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for pattern: %s\", compiler.Display(v17))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_items = 18;\n\t\tv18 := compiler.MapValueForKey(m, \"maxItems\")\n\t\tif v18 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v18)\n\t\t\tif ok {\n\t\t\t\tx.MaxItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxItems: %s\", compiler.Display(v18))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_items = 19;\n\t\tv19 := compiler.MapValueForKey(m, \"minItems\")\n\t\tif v19 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v19)\n\t\t\tif ok {\n\t\t\t\tx.MinItems = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minItems: %s\", compiler.Display(v19))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool unique_items = 20;\n\t\tv20 := compiler.MapValueForKey(m, \"uniqueItems\")\n\t\tif v20 != nil {\n\t\t\tx.UniqueItems, ok = compiler.BoolForScalarNode(v20)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for uniqueItems: %s\", compiler.Display(v20))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 max_properties = 21;\n\t\tv21 := compiler.MapValueForKey(m, \"maxProperties\")\n\t\tif v21 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v21)\n\t\t\tif ok {\n\t\t\t\tx.MaxProperties = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for maxProperties: %s\", compiler.Display(v21))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// int64 min_properties = 22;\n\t\tv22 := compiler.MapValueForKey(m, \"minProperties\")\n\t\tif v22 != nil {\n\t\t\tt, ok := compiler.IntForScalarNode(v22)\n\t\t\tif ok {\n\t\t\t\tx.MinProperties = int64(t)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for minProperties: %s\", compiler.Display(v22))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated string required = 23;\n\t\tv23 := compiler.MapValueForKey(m, \"required\")\n\t\tif v23 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v23)\n\t\t\tif ok {\n\t\t\t\tx.Required = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for required: %s\", compiler.Display(v23))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated Any enum = 24;\n\t\tv24 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v24 != nil {\n\t\t\t// repeated Any\n\t\t\tx.Enum = make([]*Any, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v24)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewAny(item, compiler.NewContext(\"enum\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.Enum = append(x.Enum, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// string type = 25;\n\t\tv25 := compiler.MapValueForKey(m, \"type\")\n\t\tif v25 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v25)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v25))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated SchemaOrReference all_of = 26;\n\t\tv26 := compiler.MapValueForKey(m, \"allOf\")\n\t\tif v26 != nil {\n\t\t\t// repeated SchemaOrReference\n\t\t\tx.AllOf = make([]*SchemaOrReference, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v26)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSchemaOrReference(item, compiler.NewContext(\"allOf\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.AllOf = append(x.AllOf, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated SchemaOrReference one_of = 27;\n\t\tv27 := compiler.MapValueForKey(m, \"oneOf\")\n\t\tif v27 != nil {\n\t\t\t// repeated SchemaOrReference\n\t\t\tx.OneOf = make([]*SchemaOrReference, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v27)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSchemaOrReference(item, compiler.NewContext(\"oneOf\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.OneOf = append(x.OneOf, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// repeated SchemaOrReference any_of = 28;\n\t\tv28 := compiler.MapValueForKey(m, \"anyOf\")\n\t\tif v28 != nil {\n\t\t\t// repeated SchemaOrReference\n\t\t\tx.AnyOf = make([]*SchemaOrReference, 0)\n\t\t\ta, ok := compiler.SequenceNodeForNode(v28)\n\t\t\tif ok {\n\t\t\t\tfor _, item := range a.Content {\n\t\t\t\t\ty, err := NewSchemaOrReference(item, compiler.NewContext(\"anyOf\", item, context))\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t}\n\t\t\t\t\tx.AnyOf = append(x.AnyOf, y)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Schema not = 29;\n\t\tv29 := compiler.MapValueForKey(m, \"not\")\n\t\tif v29 != nil {\n\t\t\tvar err error\n\t\t\tx.Not, err = NewSchema(v29, compiler.NewContext(\"not\", v29, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// ItemsItem items = 30;\n\t\tv30 := compiler.MapValueForKey(m, \"items\")\n\t\tif v30 != nil {\n\t\t\tvar err error\n\t\t\tx.Items, err = NewItemsItem(v30, compiler.NewContext(\"items\", v30, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// Properties properties = 31;\n\t\tv31 := compiler.MapValueForKey(m, \"properties\")\n\t\tif v31 != nil {\n\t\t\tvar err error\n\t\t\tx.Properties, err = NewProperties(v31, compiler.NewContext(\"properties\", v31, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// AdditionalPropertiesItem additional_properties = 32;\n\t\tv32 := compiler.MapValueForKey(m, \"additionalProperties\")\n\t\tif v32 != nil {\n\t\t\tvar err error\n\t\t\tx.AdditionalProperties, err = NewAdditionalPropertiesItem(v32, compiler.NewContext(\"additionalProperties\", v32, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// DefaultType default = 33;\n\t\tv33 := compiler.MapValueForKey(m, \"default\")\n\t\tif v33 != nil {\n\t\t\tvar err error\n\t\t\tx.Default, err = NewDefaultType(v33, compiler.NewContext(\"default\", v33, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string description = 34;\n\t\tv34 := compiler.MapValueForKey(m, \"description\")\n\t\tif v34 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v34)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v34))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string format = 35;\n\t\tv35 := compiler.MapValueForKey(m, \"format\")\n\t\tif v35 != nil {\n\t\t\tx.Format, ok = compiler.StringForScalarNode(v35)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for format: %s\", compiler.Display(v35))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 36;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSchemaOrReference creates an object of type SchemaOrReference if possible, returning an error if not.\nfunc NewSchemaOrReference(in *yaml.Node, context *compiler.Context) (*SchemaOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &SchemaOrReference{}\n\tmatched := false\n\t// Schema schema = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewSchema(m, compiler.NewContext(\"schema\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SchemaOrReference_Schema{Schema: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SchemaOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid SchemaOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSchemasOrReferences creates an object of type SchemasOrReferences if possible, returning an error if not.\nfunc NewSchemasOrReferences(in *yaml.Node, context *compiler.Context) (*SchemasOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &SchemasOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedSchemaOrReference additional_properties = 1;\n\t\t// MAP: SchemaOrReference\n\t\tx.AdditionalProperties = make([]*NamedSchemaOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedSchemaOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewSchemaOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSecurityRequirement creates an object of type SecurityRequirement if possible, returning an error if not.\nfunc NewSecurityRequirement(in *yaml.Node, context *compiler.Context) (*SecurityRequirement, error) {\n\terrors := make([]error, 0)\n\tx := &SecurityRequirement{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedStringArray additional_properties = 1;\n\t\t// MAP: StringArray\n\t\tx.AdditionalProperties = make([]*NamedStringArray, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedStringArray{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewStringArray(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSecurityScheme creates an object of type SecurityScheme if possible, returning an error if not.\nfunc NewSecurityScheme(in *yaml.Node, context *compiler.Context) (*SecurityScheme, error) {\n\terrors := make([]error, 0)\n\tx := &SecurityScheme{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"type\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"bearerFormat\", \"description\", \"flows\", \"in\", \"name\", \"openIdConnectUrl\", \"scheme\", \"type\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string type = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"type\")\n\t\tif v1 != nil {\n\t\t\tx.Type, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for type: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string name = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"name\")\n\t\tif v3 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string in = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"in\")\n\t\tif v4 != nil {\n\t\t\tx.In, ok = compiler.StringForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for in: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string scheme = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"scheme\")\n\t\tif v5 != nil {\n\t\t\tx.Scheme, ok = compiler.StringForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for scheme: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string bearer_format = 6;\n\t\tv6 := compiler.MapValueForKey(m, \"bearerFormat\")\n\t\tif v6 != nil {\n\t\t\tx.BearerFormat, ok = compiler.StringForScalarNode(v6)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for bearerFormat: %s\", compiler.Display(v6))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// OauthFlows flows = 7;\n\t\tv7 := compiler.MapValueForKey(m, \"flows\")\n\t\tif v7 != nil {\n\t\t\tvar err error\n\t\t\tx.Flows, err = NewOauthFlows(v7, compiler.NewContext(\"flows\", v7, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// string open_id_connect_url = 8;\n\t\tv8 := compiler.MapValueForKey(m, \"openIdConnectUrl\")\n\t\tif v8 != nil {\n\t\t\tx.OpenIdConnectUrl, ok = compiler.StringForScalarNode(v8)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for openIdConnectUrl: %s\", compiler.Display(v8))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 9;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSecuritySchemeOrReference creates an object of type SecuritySchemeOrReference if possible, returning an error if not.\nfunc NewSecuritySchemeOrReference(in *yaml.Node, context *compiler.Context) (*SecuritySchemeOrReference, error) {\n\terrors := make([]error, 0)\n\tx := &SecuritySchemeOrReference{}\n\tmatched := false\n\t// SecurityScheme security_scheme = 1;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewSecurityScheme(m, compiler.NewContext(\"securityScheme\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecuritySchemeOrReference_SecurityScheme{SecurityScheme: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\t// Reference reference = 2;\n\t{\n\t\tm, ok := compiler.UnpackMap(in)\n\t\tif ok {\n\t\t\t// errors might be ok here, they mean we just don't have the right subtype\n\t\t\tt, matchingError := NewReference(m, compiler.NewContext(\"reference\", m, context))\n\t\t\tif matchingError == nil {\n\t\t\t\tx.Oneof = &SecuritySchemeOrReference_Reference{Reference: t}\n\t\t\t\tmatched = true\n\t\t\t} else {\n\t\t\t\terrors = append(errors, matchingError)\n\t\t\t}\n\t\t}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t} else {\n\t\tmessage := fmt.Sprintf(\"contains an invalid SecuritySchemeOrReference\")\n\t\terr := compiler.NewError(context, message)\n\t\terrors = []error{err}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSecuritySchemesOrReferences creates an object of type SecuritySchemesOrReferences if possible, returning an error if not.\nfunc NewSecuritySchemesOrReferences(in *yaml.Node, context *compiler.Context) (*SecuritySchemesOrReferences, error) {\n\terrors := make([]error, 0)\n\tx := &SecuritySchemesOrReferences{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedSecuritySchemeOrReference additional_properties = 1;\n\t\t// MAP: SecuritySchemeOrReference\n\t\tx.AdditionalProperties = make([]*NamedSecuritySchemeOrReference, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedSecuritySchemeOrReference{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewSecuritySchemeOrReference(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewServer creates an object of type Server if possible, returning an error if not.\nfunc NewServer(in *yaml.Node, context *compiler.Context) (*Server, error) {\n\terrors := make([]error, 0)\n\tx := &Server{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"url\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"url\", \"variables\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string url = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"url\")\n\t\tif v1 != nil {\n\t\t\tx.Url, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for url: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ServerVariables variables = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"variables\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.Variables, err = NewServerVariables(v3, compiler.NewContext(\"variables\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 4;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewServerVariable creates an object of type ServerVariable if possible, returning an error if not.\nfunc NewServerVariable(in *yaml.Node, context *compiler.Context) (*ServerVariable, error) {\n\terrors := make([]error, 0)\n\tx := &ServerVariable{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"default\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"default\", \"description\", \"enum\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// repeated string enum = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"enum\")\n\t\tif v1 != nil {\n\t\t\tv, ok := compiler.SequenceNodeForNode(v1)\n\t\t\tif ok {\n\t\t\t\tx.Enum = compiler.StringArrayForSequenceNode(v)\n\t\t\t} else {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for enum: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string default = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"default\")\n\t\tif v2 != nil {\n\t\t\tx.Default, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for default: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"description\")\n\t\tif v3 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 4;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewServerVariables creates an object of type ServerVariables if possible, returning an error if not.\nfunc NewServerVariables(in *yaml.Node, context *compiler.Context) (*ServerVariables, error) {\n\terrors := make([]error, 0)\n\tx := &ServerVariables{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedServerVariable additional_properties = 1;\n\t\t// MAP: ServerVariable\n\t\tx.AdditionalProperties = make([]*NamedServerVariable, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedServerVariable{}\n\t\t\t\tpair.Name = k\n\t\t\t\tvar err error\n\t\t\t\tpair.Value, err = NewServerVariable(v, compiler.NewContext(k, v, context))\n\t\t\t\tif err != nil {\n\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t}\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewSpecificationExtension creates an object of type SpecificationExtension if possible, returning an error if not.\nfunc NewSpecificationExtension(in *yaml.Node, context *compiler.Context) (*SpecificationExtension, error) {\n\terrors := make([]error, 0)\n\tx := &SpecificationExtension{}\n\tmatched := false\n\tswitch in.Tag {\n\tcase \"!!bool\":\n\t\tvar v bool\n\t\tv, matched = compiler.BoolForScalarNode(in)\n\t\tx.Oneof = &SpecificationExtension_Boolean{Boolean: v}\n\tcase \"!!str\":\n\t\tvar v string\n\t\tv, matched = compiler.StringForScalarNode(in)\n\t\tx.Oneof = &SpecificationExtension_String_{String_: v}\n\tcase \"!!float\":\n\t\tvar v float64\n\t\tv, matched = compiler.FloatForScalarNode(in)\n\t\tx.Oneof = &SpecificationExtension_Number{Number: v}\n\tcase \"!!int\":\n\t\tvar v int64\n\t\tv, matched = compiler.IntForScalarNode(in)\n\t\tx.Oneof = &SpecificationExtension_Number{Number: float64(v)}\n\t}\n\tif matched {\n\t\t// since the oneof matched one of its possibilities, discard any matching errors\n\t\terrors = make([]error, 0)\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewStringArray creates an object of type StringArray if possible, returning an error if not.\nfunc NewStringArray(in *yaml.Node, context *compiler.Context) (*StringArray, error) {\n\terrors := make([]error, 0)\n\tx := &StringArray{}\n\tx.Value = make([]string, 0)\n\tfor _, node := range in.Content {\n\t\ts, _ := compiler.StringForScalarNode(node)\n\t\tx.Value = append(x.Value, s)\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewStrings creates an object of type Strings if possible, returning an error if not.\nfunc NewStrings(in *yaml.Node, context *compiler.Context) (*Strings, error) {\n\terrors := make([]error, 0)\n\tx := &Strings{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\t// repeated NamedString additional_properties = 1;\n\t\t// MAP: string\n\t\tx.AdditionalProperties = make([]*NamedString, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tpair := &NamedString{}\n\t\t\t\tpair.Name = k\n\t\t\t\tpair.Value, _ = compiler.StringForScalarNode(v)\n\t\t\t\tx.AdditionalProperties = append(x.AdditionalProperties, pair)\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewTag creates an object of type Tag if possible, returning an error if not.\nfunc NewTag(in *yaml.Node, context *compiler.Context) (*Tag, error) {\n\terrors := make([]error, 0)\n\tx := &Tag{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\trequiredKeys := []string{\"name\"}\n\t\tmissingKeys := compiler.MissingKeysInMap(m, requiredKeys)\n\t\tif len(missingKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"is missing required %s: %+v\", compiler.PluralProperties(len(missingKeys)), strings.Join(missingKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\tallowedKeys := []string{\"description\", \"externalDocs\", \"name\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string description = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"description\")\n\t\tif v2 != nil {\n\t\t\tx.Description, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for description: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// ExternalDocs external_docs = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"externalDocs\")\n\t\tif v3 != nil {\n\t\t\tvar err error\n\t\t\tx.ExternalDocs, err = NewExternalDocs(v3, compiler.NewContext(\"externalDocs\", v3, context))\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 4;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// NewXml creates an object of type Xml if possible, returning an error if not.\nfunc NewXml(in *yaml.Node, context *compiler.Context) (*Xml, error) {\n\terrors := make([]error, 0)\n\tx := &Xml{}\n\tm, ok := compiler.UnpackMap(in)\n\tif !ok {\n\t\tmessage := fmt.Sprintf(\"has unexpected value: %+v (%T)\", in, in)\n\t\terrors = append(errors, compiler.NewError(context, message))\n\t} else {\n\t\tallowedKeys := []string{\"attribute\", \"name\", \"namespace\", \"prefix\", \"wrapped\"}\n\t\tallowedPatterns := []*regexp.Regexp{pattern1}\n\t\tinvalidKeys := compiler.InvalidKeysInMap(m, allowedKeys, allowedPatterns)\n\t\tif len(invalidKeys) > 0 {\n\t\t\tmessage := fmt.Sprintf(\"has invalid %s: %+v\", compiler.PluralProperties(len(invalidKeys)), strings.Join(invalidKeys, \", \"))\n\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t}\n\t\t// string name = 1;\n\t\tv1 := compiler.MapValueForKey(m, \"name\")\n\t\tif v1 != nil {\n\t\t\tx.Name, ok = compiler.StringForScalarNode(v1)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for name: %s\", compiler.Display(v1))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string namespace = 2;\n\t\tv2 := compiler.MapValueForKey(m, \"namespace\")\n\t\tif v2 != nil {\n\t\t\tx.Namespace, ok = compiler.StringForScalarNode(v2)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for namespace: %s\", compiler.Display(v2))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// string prefix = 3;\n\t\tv3 := compiler.MapValueForKey(m, \"prefix\")\n\t\tif v3 != nil {\n\t\t\tx.Prefix, ok = compiler.StringForScalarNode(v3)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for prefix: %s\", compiler.Display(v3))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool attribute = 4;\n\t\tv4 := compiler.MapValueForKey(m, \"attribute\")\n\t\tif v4 != nil {\n\t\t\tx.Attribute, ok = compiler.BoolForScalarNode(v4)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for attribute: %s\", compiler.Display(v4))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// bool wrapped = 5;\n\t\tv5 := compiler.MapValueForKey(m, \"wrapped\")\n\t\tif v5 != nil {\n\t\t\tx.Wrapped, ok = compiler.BoolForScalarNode(v5)\n\t\t\tif !ok {\n\t\t\t\tmessage := fmt.Sprintf(\"has unexpected value for wrapped: %s\", compiler.Display(v5))\n\t\t\t\terrors = append(errors, compiler.NewError(context, message))\n\t\t\t}\n\t\t}\n\t\t// repeated NamedAny specification_extension = 6;\n\t\t// MAP: Any ^x-\n\t\tx.SpecificationExtension = make([]*NamedAny, 0)\n\t\tfor i := 0; i < len(m.Content); i += 2 {\n\t\t\tk, ok := compiler.StringForScalarNode(m.Content[i])\n\t\t\tif ok {\n\t\t\t\tv := m.Content[i+1]\n\t\t\t\tif strings.HasPrefix(k, \"x-\") {\n\t\t\t\t\tpair := &NamedAny{}\n\t\t\t\t\tpair.Name = k\n\t\t\t\t\tresult := &Any{}\n\t\t\t\t\thandled, resultFromExt, err := compiler.CallExtension(context, v, k)\n\t\t\t\t\tif handled {\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbytes := compiler.Marshal(v)\n\t\t\t\t\t\t\tresult.Yaml = string(bytes)\n\t\t\t\t\t\t\tresult.Value = resultFromExt\n\t\t\t\t\t\t\tpair.Value = result\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpair.Value, err = NewAny(v, compiler.NewContext(k, v, context))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\terrors = append(errors, err)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tx.SpecificationExtension = append(x.SpecificationExtension, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn x, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside AdditionalPropertiesItem objects.\nfunc (m *AdditionalPropertiesItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*AdditionalPropertiesItem_SchemaOrReference)\n\t\tif ok {\n\t\t\t_, err := p.SchemaOrReference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Any objects.\nfunc (m *Any) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside AnyOrExpression objects.\nfunc (m *AnyOrExpression) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*AnyOrExpression_Any)\n\t\tif ok {\n\t\t\t_, err := p.Any.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*AnyOrExpression_Expression)\n\t\tif ok {\n\t\t\t_, err := p.Expression.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Callback objects.\nfunc (m *Callback) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.Path {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside CallbackOrReference objects.\nfunc (m *CallbackOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*CallbackOrReference_Callback)\n\t\tif ok {\n\t\t\t_, err := p.Callback.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*CallbackOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside CallbacksOrReferences objects.\nfunc (m *CallbacksOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Components objects.\nfunc (m *Components) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Schemas != nil {\n\t\t_, err := m.Schemas.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Responses != nil {\n\t\t_, err := m.Responses.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Parameters != nil {\n\t\t_, err := m.Parameters.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Examples != nil {\n\t\t_, err := m.Examples.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.RequestBodies != nil {\n\t\t_, err := m.RequestBodies.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Headers != nil {\n\t\t_, err := m.Headers.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.SecuritySchemes != nil {\n\t\t_, err := m.SecuritySchemes.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Links != nil {\n\t\t_, err := m.Links.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Callbacks != nil {\n\t\t_, err := m.Callbacks.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Contact objects.\nfunc (m *Contact) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside DefaultType objects.\nfunc (m *DefaultType) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Discriminator objects.\nfunc (m *Discriminator) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Mapping != nil {\n\t\t_, err := m.Mapping.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Document objects.\nfunc (m *Document) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Info != nil {\n\t\t_, err := m.Info.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Servers {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.Paths != nil {\n\t\t_, err := m.Paths.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Components != nil {\n\t\t_, err := m.Components.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Security {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.Tags {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Encoding objects.\nfunc (m *Encoding) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Headers != nil {\n\t\t_, err := m.Headers.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Encodings objects.\nfunc (m *Encodings) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Example objects.\nfunc (m *Example) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ExampleOrReference objects.\nfunc (m *ExampleOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*ExampleOrReference_Example)\n\t\tif ok {\n\t\t\t_, err := p.Example.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*ExampleOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ExamplesOrReferences objects.\nfunc (m *ExamplesOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Expression objects.\nfunc (m *Expression) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ExternalDocs objects.\nfunc (m *ExternalDocs) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Header objects.\nfunc (m *Header) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Schema != nil {\n\t\t_, err := m.Schema.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Example != nil {\n\t\t_, err := m.Example.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Examples != nil {\n\t\t_, err := m.Examples.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Content != nil {\n\t\t_, err := m.Content.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside HeaderOrReference objects.\nfunc (m *HeaderOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*HeaderOrReference_Header)\n\t\tif ok {\n\t\t\t_, err := p.Header.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*HeaderOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside HeadersOrReferences objects.\nfunc (m *HeadersOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Info objects.\nfunc (m *Info) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Contact != nil {\n\t\t_, err := m.Contact.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.License != nil {\n\t\t_, err := m.License.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ItemsItem objects.\nfunc (m *ItemsItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.SchemaOrReference {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside License objects.\nfunc (m *License) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Link objects.\nfunc (m *Link) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Parameters != nil {\n\t\t_, err := m.Parameters.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.RequestBody != nil {\n\t\t_, err := m.RequestBody.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Server != nil {\n\t\t_, err := m.Server.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside LinkOrReference objects.\nfunc (m *LinkOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*LinkOrReference_Link)\n\t\tif ok {\n\t\t\t_, err := p.Link.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*LinkOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside LinksOrReferences objects.\nfunc (m *LinksOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside MediaType objects.\nfunc (m *MediaType) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Schema != nil {\n\t\t_, err := m.Schema.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Example != nil {\n\t\t_, err := m.Example.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Examples != nil {\n\t\t_, err := m.Examples.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Encoding != nil {\n\t\t_, err := m.Encoding.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside MediaTypes objects.\nfunc (m *MediaTypes) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedAny objects.\nfunc (m *NamedAny) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedCallbackOrReference objects.\nfunc (m *NamedCallbackOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedEncoding objects.\nfunc (m *NamedEncoding) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedExampleOrReference objects.\nfunc (m *NamedExampleOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedHeaderOrReference objects.\nfunc (m *NamedHeaderOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedLinkOrReference objects.\nfunc (m *NamedLinkOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedMediaType objects.\nfunc (m *NamedMediaType) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedParameterOrReference objects.\nfunc (m *NamedParameterOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedPathItem objects.\nfunc (m *NamedPathItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedRequestBodyOrReference objects.\nfunc (m *NamedRequestBodyOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedResponseOrReference objects.\nfunc (m *NamedResponseOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedSchemaOrReference objects.\nfunc (m *NamedSchemaOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedSecuritySchemeOrReference objects.\nfunc (m *NamedSecuritySchemeOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedServerVariable objects.\nfunc (m *NamedServerVariable) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedString objects.\nfunc (m *NamedString) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside NamedStringArray objects.\nfunc (m *NamedStringArray) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Value != nil {\n\t\t_, err := m.Value.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside OauthFlow objects.\nfunc (m *OauthFlow) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Scopes != nil {\n\t\t_, err := m.Scopes.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside OauthFlows objects.\nfunc (m *OauthFlows) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Implicit != nil {\n\t\t_, err := m.Implicit.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Password != nil {\n\t\t_, err := m.Password.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.ClientCredentials != nil {\n\t\t_, err := m.ClientCredentials.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.AuthorizationCode != nil {\n\t\t_, err := m.AuthorizationCode.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Object objects.\nfunc (m *Object) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Operation objects.\nfunc (m *Operation) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Parameters {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.RequestBody != nil {\n\t\t_, err := m.RequestBody.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Responses != nil {\n\t\t_, err := m.Responses.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Callbacks != nil {\n\t\t_, err := m.Callbacks.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Security {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.Servers {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Parameter objects.\nfunc (m *Parameter) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Schema != nil {\n\t\t_, err := m.Schema.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Example != nil {\n\t\t_, err := m.Example.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Examples != nil {\n\t\t_, err := m.Examples.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Content != nil {\n\t\t_, err := m.Content.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ParameterOrReference objects.\nfunc (m *ParameterOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*ParameterOrReference_Parameter)\n\t\tif ok {\n\t\t\t_, err := p.Parameter.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*ParameterOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ParametersOrReferences objects.\nfunc (m *ParametersOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside PathItem objects.\nfunc (m *PathItem) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.XRef != \"\" {\n\t\tinfo, err := compiler.ReadInfoForRef(root, m.XRef)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif info != nil {\n\t\t\treplacement, err := NewPathItem(info, nil)\n\t\t\tif err == nil {\n\t\t\t\t*m = *replacement\n\t\t\t\treturn m.ResolveReferences(root)\n\t\t\t}\n\t\t}\n\t\treturn info, nil\n\t}\n\tif m.Get != nil {\n\t\t_, err := m.Get.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Put != nil {\n\t\t_, err := m.Put.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Post != nil {\n\t\t_, err := m.Post.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Delete != nil {\n\t\t_, err := m.Delete.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Options != nil {\n\t\t_, err := m.Options.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Head != nil {\n\t\t_, err := m.Head.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Patch != nil {\n\t\t_, err := m.Patch.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Trace != nil {\n\t\t_, err := m.Trace.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Servers {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.Parameters {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Paths objects.\nfunc (m *Paths) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.Path {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Properties objects.\nfunc (m *Properties) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Reference objects.\nfunc (m *Reference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.XRef != \"\" {\n\t\tinfo, err := compiler.ReadInfoForRef(root, m.XRef)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif info != nil {\n\t\t\treplacement, err := NewReference(info, nil)\n\t\t\tif err == nil {\n\t\t\t\t*m = *replacement\n\t\t\t\treturn m.ResolveReferences(root)\n\t\t\t}\n\t\t}\n\t\treturn info, nil\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside RequestBodiesOrReferences objects.\nfunc (m *RequestBodiesOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside RequestBody objects.\nfunc (m *RequestBody) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Content != nil {\n\t\t_, err := m.Content.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside RequestBodyOrReference objects.\nfunc (m *RequestBodyOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*RequestBodyOrReference_RequestBody)\n\t\tif ok {\n\t\t\t_, err := p.RequestBody.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*RequestBodyOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Response objects.\nfunc (m *Response) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Headers != nil {\n\t\t_, err := m.Headers.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Content != nil {\n\t\t_, err := m.Content.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Links != nil {\n\t\t_, err := m.Links.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ResponseOrReference objects.\nfunc (m *ResponseOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*ResponseOrReference_Response)\n\t\tif ok {\n\t\t\t_, err := p.Response.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*ResponseOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Responses objects.\nfunc (m *Responses) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.ResponseOrReference {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ResponsesOrReferences objects.\nfunc (m *ResponsesOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Schema objects.\nfunc (m *Schema) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Discriminator != nil {\n\t\t_, err := m.Discriminator.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Xml != nil {\n\t\t_, err := m.Xml.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Example != nil {\n\t\t_, err := m.Example.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.Enum {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.AllOf {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.OneOf {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tfor _, item := range m.AnyOf {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\tif m.Not != nil {\n\t\t_, err := m.Not.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Items != nil {\n\t\t_, err := m.Items.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Properties != nil {\n\t\t_, err := m.Properties.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.AdditionalProperties != nil {\n\t\t_, err := m.AdditionalProperties.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tif m.Default != nil {\n\t\t_, err := m.Default.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SchemaOrReference objects.\nfunc (m *SchemaOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*SchemaOrReference_Schema)\n\t\tif ok {\n\t\t\t_, err := p.Schema.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SchemaOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SchemasOrReferences objects.\nfunc (m *SchemasOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SecurityRequirement objects.\nfunc (m *SecurityRequirement) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SecurityScheme objects.\nfunc (m *SecurityScheme) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Flows != nil {\n\t\t_, err := m.Flows.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SecuritySchemeOrReference objects.\nfunc (m *SecuritySchemeOrReference) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\t{\n\t\tp, ok := m.Oneof.(*SecuritySchemeOrReference_SecurityScheme)\n\t\tif ok {\n\t\t\t_, err := p.SecurityScheme.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tp, ok := m.Oneof.(*SecuritySchemeOrReference_Reference)\n\t\tif ok {\n\t\t\t_, err := p.Reference.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SecuritySchemesOrReferences objects.\nfunc (m *SecuritySchemesOrReferences) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Server objects.\nfunc (m *Server) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.Variables != nil {\n\t\t_, err := m.Variables.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ServerVariable objects.\nfunc (m *ServerVariable) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside ServerVariables objects.\nfunc (m *ServerVariables) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside SpecificationExtension objects.\nfunc (m *SpecificationExtension) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside StringArray objects.\nfunc (m *StringArray) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Strings objects.\nfunc (m *Strings) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.AdditionalProperties {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Tag objects.\nfunc (m *Tag) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tif m.ExternalDocs != nil {\n\t\t_, err := m.ExternalDocs.ResolveReferences(root)\n\t\tif err != nil {\n\t\t\terrors = append(errors, err)\n\t\t}\n\t}\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ResolveReferences resolves references found inside Xml objects.\nfunc (m *Xml) ResolveReferences(root string) (*yaml.Node, error) {\n\terrors := make([]error, 0)\n\tfor _, item := range m.SpecificationExtension {\n\t\tif item != nil {\n\t\t\t_, err := item.ResolveReferences(root)\n\t\t\tif err != nil {\n\t\t\t\terrors = append(errors, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, compiler.NewErrorGroupOrNil(errors)\n}\n\n// ToRawInfo returns a description of AdditionalPropertiesItem suitable for JSON or YAML export.\nfunc (m *AdditionalPropertiesItem) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// AdditionalPropertiesItem\n\t// {Name:schemaOrReference Type:SchemaOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetSchemaOrReference()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:boolean Type:bool StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v1, ok := m.GetOneof().(*AdditionalPropertiesItem_Boolean); ok {\n\t\treturn compiler.NewScalarNodeForBool(v1.Boolean)\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Any suitable for JSON or YAML export.\nfunc (m *Any) ToRawInfo() *yaml.Node {\n\tvar err error\n\tvar node yaml.Node\n\terr = yaml.Unmarshal([]byte(m.Yaml), &node)\n\tif err == nil {\n\t\tif node.Kind == yaml.DocumentNode {\n\t\t\treturn node.Content[0]\n\t\t}\n\t\treturn &node\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of AnyOrExpression suitable for JSON or YAML export.\nfunc (m *AnyOrExpression) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// AnyOrExpression\n\t// {Name:any Type:Any StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetAny()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:expression Type:Expression StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetExpression()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Callback suitable for JSON or YAML export.\nfunc (m *Callback) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Path != nil {\n\t\tfor _, item := range m.Path {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of CallbackOrReference suitable for JSON or YAML export.\nfunc (m *CallbackOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// CallbackOrReference\n\t// {Name:callback Type:Callback StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetCallback()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of CallbacksOrReferences suitable for JSON or YAML export.\nfunc (m *CallbacksOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Components suitable for JSON or YAML export.\nfunc (m *Components) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Schemas != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schemas\"))\n\t\tinfo.Content = append(info.Content, m.Schemas.ToRawInfo())\n\t}\n\tif m.Responses != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"responses\"))\n\t\tinfo.Content = append(info.Content, m.Responses.ToRawInfo())\n\t}\n\tif m.Parameters != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"parameters\"))\n\t\tinfo.Content = append(info.Content, m.Parameters.ToRawInfo())\n\t}\n\tif m.Examples != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"examples\"))\n\t\tinfo.Content = append(info.Content, m.Examples.ToRawInfo())\n\t}\n\tif m.RequestBodies != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"requestBodies\"))\n\t\tinfo.Content = append(info.Content, m.RequestBodies.ToRawInfo())\n\t}\n\tif m.Headers != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"headers\"))\n\t\tinfo.Content = append(info.Content, m.Headers.ToRawInfo())\n\t}\n\tif m.SecuritySchemes != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"securitySchemes\"))\n\t\tinfo.Content = append(info.Content, m.SecuritySchemes.ToRawInfo())\n\t}\n\tif m.Links != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"links\"))\n\t\tinfo.Content = append(info.Content, m.Links.ToRawInfo())\n\t}\n\tif m.Callbacks != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"callbacks\"))\n\t\tinfo.Content = append(info.Content, m.Callbacks.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Contact suitable for JSON or YAML export.\nfunc (m *Contact) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Url != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"url\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Url))\n\t}\n\tif m.Email != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"email\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Email))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of DefaultType suitable for JSON or YAML export.\nfunc (m *DefaultType) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// DefaultType\n\t// {Name:number Type:float StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v0, ok := m.GetOneof().(*DefaultType_Number); ok {\n\t\treturn compiler.NewScalarNodeForFloat(v0.Number)\n\t}\n\t// {Name:boolean Type:bool StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v1, ok := m.GetOneof().(*DefaultType_Boolean); ok {\n\t\treturn compiler.NewScalarNodeForBool(v1.Boolean)\n\t}\n\t// {Name:string Type:string StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v2, ok := m.GetOneof().(*DefaultType_String_); ok {\n\t\treturn compiler.NewScalarNodeForString(v2.String_)\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Discriminator suitable for JSON or YAML export.\nfunc (m *Discriminator) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"propertyName\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.PropertyName))\n\tif m.Mapping != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"mapping\"))\n\t\tinfo.Content = append(info.Content, m.Mapping.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Document suitable for JSON or YAML export.\nfunc (m *Document) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"openapi\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Openapi))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"info\"))\n\tinfo.Content = append(info.Content, m.Info.ToRawInfo())\n\tif len(m.Servers) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Servers {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"servers\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"paths\"))\n\tinfo.Content = append(info.Content, m.Paths.ToRawInfo())\n\tif m.Components != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"components\"))\n\t\tinfo.Content = append(info.Content, m.Components.ToRawInfo())\n\t}\n\tif len(m.Security) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Security {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"security\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif len(m.Tags) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Tags {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tags\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Encoding suitable for JSON or YAML export.\nfunc (m *Encoding) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.ContentType != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"contentType\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.ContentType))\n\t}\n\tif m.Headers != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"headers\"))\n\t\tinfo.Content = append(info.Content, m.Headers.ToRawInfo())\n\t}\n\tif m.Style != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"style\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Style))\n\t}\n\tif m.Explode != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"explode\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Explode))\n\t}\n\tif m.AllowReserved != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allowReserved\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.AllowReserved))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Encodings suitable for JSON or YAML export.\nfunc (m *Encodings) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Example suitable for JSON or YAML export.\nfunc (m *Example) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Summary != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"summary\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Summary))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Value != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"value\"))\n\t\tinfo.Content = append(info.Content, m.Value.ToRawInfo())\n\t}\n\tif m.ExternalValue != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalValue\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.ExternalValue))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ExampleOrReference suitable for JSON or YAML export.\nfunc (m *ExampleOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// ExampleOrReference\n\t// {Name:example Type:Example StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetExample()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of ExamplesOrReferences suitable for JSON or YAML export.\nfunc (m *ExamplesOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Expression suitable for JSON or YAML export.\nfunc (m *Expression) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ExternalDocs suitable for JSON or YAML export.\nfunc (m *ExternalDocs) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"url\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Url))\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Header suitable for JSON or YAML export.\nfunc (m *Header) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Required != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\t}\n\tif m.Deprecated != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"deprecated\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Deprecated))\n\t}\n\tif m.AllowEmptyValue != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allowEmptyValue\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.AllowEmptyValue))\n\t}\n\tif m.Style != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"style\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Style))\n\t}\n\tif m.Explode != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"explode\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Explode))\n\t}\n\tif m.AllowReserved != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allowReserved\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.AllowReserved))\n\t}\n\tif m.Schema != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schema\"))\n\t\tinfo.Content = append(info.Content, m.Schema.ToRawInfo())\n\t}\n\tif m.Example != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"example\"))\n\t\tinfo.Content = append(info.Content, m.Example.ToRawInfo())\n\t}\n\tif m.Examples != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"examples\"))\n\t\tinfo.Content = append(info.Content, m.Examples.ToRawInfo())\n\t}\n\tif m.Content != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"content\"))\n\t\tinfo.Content = append(info.Content, m.Content.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of HeaderOrReference suitable for JSON or YAML export.\nfunc (m *HeaderOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// HeaderOrReference\n\t// {Name:header Type:Header StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetHeader()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of HeadersOrReferences suitable for JSON or YAML export.\nfunc (m *HeadersOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Info suitable for JSON or YAML export.\nfunc (m *Info) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"title\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Title))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.TermsOfService != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"termsOfService\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.TermsOfService))\n\t}\n\tif m.Contact != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"contact\"))\n\t\tinfo.Content = append(info.Content, m.Contact.ToRawInfo())\n\t}\n\tif m.License != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"license\"))\n\t\tinfo.Content = append(info.Content, m.License.ToRawInfo())\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"version\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Version))\n\tif m.Summary != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"summary\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Summary))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ItemsItem suitable for JSON or YAML export.\nfunc (m *ItemsItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif len(m.SchemaOrReference) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.SchemaOrReference {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schemaOrReference\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of License suitable for JSON or YAML export.\nfunc (m *License) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\tif m.Url != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"url\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Url))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Link suitable for JSON or YAML export.\nfunc (m *Link) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.OperationRef != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"operationRef\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.OperationRef))\n\t}\n\tif m.OperationId != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"operationId\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.OperationId))\n\t}\n\tif m.Parameters != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"parameters\"))\n\t\tinfo.Content = append(info.Content, m.Parameters.ToRawInfo())\n\t}\n\tif m.RequestBody != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"requestBody\"))\n\t\tinfo.Content = append(info.Content, m.RequestBody.ToRawInfo())\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Server != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"server\"))\n\t\tinfo.Content = append(info.Content, m.Server.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of LinkOrReference suitable for JSON or YAML export.\nfunc (m *LinkOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// LinkOrReference\n\t// {Name:link Type:Link StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetLink()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of LinksOrReferences suitable for JSON or YAML export.\nfunc (m *LinksOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of MediaType suitable for JSON or YAML export.\nfunc (m *MediaType) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Schema != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schema\"))\n\t\tinfo.Content = append(info.Content, m.Schema.ToRawInfo())\n\t}\n\tif m.Example != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"example\"))\n\t\tinfo.Content = append(info.Content, m.Example.ToRawInfo())\n\t}\n\tif m.Examples != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"examples\"))\n\t\tinfo.Content = append(info.Content, m.Examples.ToRawInfo())\n\t}\n\tif m.Encoding != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"encoding\"))\n\t\tinfo.Content = append(info.Content, m.Encoding.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of MediaTypes suitable for JSON or YAML export.\nfunc (m *MediaTypes) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedAny suitable for JSON or YAML export.\nfunc (m *NamedAny) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Value != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"value\"))\n\t\tinfo.Content = append(info.Content, m.Value.ToRawInfo())\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedCallbackOrReference suitable for JSON or YAML export.\nfunc (m *NamedCallbackOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:CallbackOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedEncoding suitable for JSON or YAML export.\nfunc (m *NamedEncoding) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:Encoding StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedExampleOrReference suitable for JSON or YAML export.\nfunc (m *NamedExampleOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:ExampleOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedHeaderOrReference suitable for JSON or YAML export.\nfunc (m *NamedHeaderOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:HeaderOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedLinkOrReference suitable for JSON or YAML export.\nfunc (m *NamedLinkOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:LinkOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedMediaType suitable for JSON or YAML export.\nfunc (m *NamedMediaType) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:MediaType StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedParameterOrReference suitable for JSON or YAML export.\nfunc (m *NamedParameterOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:ParameterOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedPathItem suitable for JSON or YAML export.\nfunc (m *NamedPathItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:PathItem StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedRequestBodyOrReference suitable for JSON or YAML export.\nfunc (m *NamedRequestBodyOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:RequestBodyOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedResponseOrReference suitable for JSON or YAML export.\nfunc (m *NamedResponseOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:ResponseOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedSchemaOrReference suitable for JSON or YAML export.\nfunc (m *NamedSchemaOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:SchemaOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedSecuritySchemeOrReference suitable for JSON or YAML export.\nfunc (m *NamedSecuritySchemeOrReference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:SecuritySchemeOrReference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedServerVariable suitable for JSON or YAML export.\nfunc (m *NamedServerVariable) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:ServerVariable StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedString suitable for JSON or YAML export.\nfunc (m *NamedString) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Value != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"value\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Value))\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of NamedStringArray suitable for JSON or YAML export.\nfunc (m *NamedStringArray) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\t// &{Name:value Type:StringArray StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:Mapped value}\n\treturn info\n}\n\n// ToRawInfo returns a description of OauthFlow suitable for JSON or YAML export.\nfunc (m *OauthFlow) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AuthorizationUrl != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"authorizationUrl\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.AuthorizationUrl))\n\t}\n\tif m.TokenUrl != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tokenUrl\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.TokenUrl))\n\t}\n\tif m.RefreshUrl != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"refreshUrl\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.RefreshUrl))\n\t}\n\tif m.Scopes != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"scopes\"))\n\t\tinfo.Content = append(info.Content, m.Scopes.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of OauthFlows suitable for JSON or YAML export.\nfunc (m *OauthFlows) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Implicit != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"implicit\"))\n\t\tinfo.Content = append(info.Content, m.Implicit.ToRawInfo())\n\t}\n\tif m.Password != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"password\"))\n\t\tinfo.Content = append(info.Content, m.Password.ToRawInfo())\n\t}\n\tif m.ClientCredentials != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"clientCredentials\"))\n\t\tinfo.Content = append(info.Content, m.ClientCredentials.ToRawInfo())\n\t}\n\tif m.AuthorizationCode != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"authorizationCode\"))\n\t\tinfo.Content = append(info.Content, m.AuthorizationCode.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Object suitable for JSON or YAML export.\nfunc (m *Object) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Operation suitable for JSON or YAML export.\nfunc (m *Operation) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif len(m.Tags) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"tags\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Tags))\n\t}\n\tif m.Summary != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"summary\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Summary))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.OperationId != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"operationId\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.OperationId))\n\t}\n\tif len(m.Parameters) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Parameters {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"parameters\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.RequestBody != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"requestBody\"))\n\t\tinfo.Content = append(info.Content, m.RequestBody.ToRawInfo())\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"responses\"))\n\tinfo.Content = append(info.Content, m.Responses.ToRawInfo())\n\tif m.Callbacks != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"callbacks\"))\n\t\tinfo.Content = append(info.Content, m.Callbacks.ToRawInfo())\n\t}\n\tif m.Deprecated != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"deprecated\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Deprecated))\n\t}\n\tif len(m.Security) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Security {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"security\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif len(m.Servers) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Servers {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"servers\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Parameter suitable for JSON or YAML export.\nfunc (m *Parameter) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Required != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\t}\n\tif m.Deprecated != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"deprecated\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Deprecated))\n\t}\n\tif m.AllowEmptyValue != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allowEmptyValue\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.AllowEmptyValue))\n\t}\n\tif m.Style != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"style\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Style))\n\t}\n\tif m.Explode != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"explode\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Explode))\n\t}\n\tif m.AllowReserved != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allowReserved\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.AllowReserved))\n\t}\n\tif m.Schema != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"schema\"))\n\t\tinfo.Content = append(info.Content, m.Schema.ToRawInfo())\n\t}\n\tif m.Example != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"example\"))\n\t\tinfo.Content = append(info.Content, m.Example.ToRawInfo())\n\t}\n\tif m.Examples != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"examples\"))\n\t\tinfo.Content = append(info.Content, m.Examples.ToRawInfo())\n\t}\n\tif m.Content != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"content\"))\n\t\tinfo.Content = append(info.Content, m.Content.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ParameterOrReference suitable for JSON or YAML export.\nfunc (m *ParameterOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// ParameterOrReference\n\t// {Name:parameter Type:Parameter StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetParameter()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of ParametersOrReferences suitable for JSON or YAML export.\nfunc (m *ParametersOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of PathItem suitable for JSON or YAML export.\nfunc (m *PathItem) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.XRef != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"$ref\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.XRef))\n\t}\n\tif m.Summary != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"summary\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Summary))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Get != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"get\"))\n\t\tinfo.Content = append(info.Content, m.Get.ToRawInfo())\n\t}\n\tif m.Put != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"put\"))\n\t\tinfo.Content = append(info.Content, m.Put.ToRawInfo())\n\t}\n\tif m.Post != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"post\"))\n\t\tinfo.Content = append(info.Content, m.Post.ToRawInfo())\n\t}\n\tif m.Delete != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"delete\"))\n\t\tinfo.Content = append(info.Content, m.Delete.ToRawInfo())\n\t}\n\tif m.Options != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"options\"))\n\t\tinfo.Content = append(info.Content, m.Options.ToRawInfo())\n\t}\n\tif m.Head != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"head\"))\n\t\tinfo.Content = append(info.Content, m.Head.ToRawInfo())\n\t}\n\tif m.Patch != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"patch\"))\n\t\tinfo.Content = append(info.Content, m.Patch.ToRawInfo())\n\t}\n\tif m.Trace != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"trace\"))\n\t\tinfo.Content = append(info.Content, m.Trace.ToRawInfo())\n\t}\n\tif len(m.Servers) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Servers {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"servers\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif len(m.Parameters) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Parameters {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"parameters\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Paths suitable for JSON or YAML export.\nfunc (m *Paths) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Path != nil {\n\t\tfor _, item := range m.Path {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Properties suitable for JSON or YAML export.\nfunc (m *Properties) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Reference suitable for JSON or YAML export.\nfunc (m *Reference) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"$ref\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.XRef))\n\tif m.Summary != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"summary\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Summary))\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of RequestBodiesOrReferences suitable for JSON or YAML export.\nfunc (m *RequestBodiesOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of RequestBody suitable for JSON or YAML export.\nfunc (m *RequestBody) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"content\"))\n\tinfo.Content = append(info.Content, m.Content.ToRawInfo())\n\tif m.Required != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Required))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of RequestBodyOrReference suitable for JSON or YAML export.\nfunc (m *RequestBodyOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// RequestBodyOrReference\n\t// {Name:requestBody Type:RequestBody StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetRequestBody()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Response suitable for JSON or YAML export.\nfunc (m *Response) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\tif m.Headers != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"headers\"))\n\t\tinfo.Content = append(info.Content, m.Headers.ToRawInfo())\n\t}\n\tif m.Content != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"content\"))\n\t\tinfo.Content = append(info.Content, m.Content.ToRawInfo())\n\t}\n\tif m.Links != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"links\"))\n\t\tinfo.Content = append(info.Content, m.Links.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ResponseOrReference suitable for JSON or YAML export.\nfunc (m *ResponseOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// ResponseOrReference\n\t// {Name:response Type:Response StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetResponse()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of Responses suitable for JSON or YAML export.\nfunc (m *Responses) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.ResponseOrReference != nil {\n\t\tfor _, item := range m.ResponseOrReference {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ResponsesOrReferences suitable for JSON or YAML export.\nfunc (m *ResponsesOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Schema suitable for JSON or YAML export.\nfunc (m *Schema) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Nullable != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"nullable\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Nullable))\n\t}\n\tif m.Discriminator != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"discriminator\"))\n\t\tinfo.Content = append(info.Content, m.Discriminator.ToRawInfo())\n\t}\n\tif m.ReadOnly != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"readOnly\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ReadOnly))\n\t}\n\tif m.WriteOnly != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"writeOnly\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.WriteOnly))\n\t}\n\tif m.Xml != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"xml\"))\n\t\tinfo.Content = append(info.Content, m.Xml.ToRawInfo())\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.Example != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"example\"))\n\t\tinfo.Content = append(info.Content, m.Example.ToRawInfo())\n\t}\n\tif m.Deprecated != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"deprecated\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Deprecated))\n\t}\n\tif m.Title != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"title\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Title))\n\t}\n\tif m.MultipleOf != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"multipleOf\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.MultipleOf))\n\t}\n\tif m.Maximum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Maximum))\n\t}\n\tif m.ExclusiveMaximum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMaximum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMaximum))\n\t}\n\tif m.Minimum != 0.0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForFloat(m.Minimum))\n\t}\n\tif m.ExclusiveMinimum != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"exclusiveMinimum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.ExclusiveMinimum))\n\t}\n\tif m.MaxLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxLength))\n\t}\n\tif m.MinLength != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minLength\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinLength))\n\t}\n\tif m.Pattern != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"pattern\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Pattern))\n\t}\n\tif m.MaxItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxItems))\n\t}\n\tif m.MinItems != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinItems))\n\t}\n\tif m.UniqueItems != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"uniqueItems\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.UniqueItems))\n\t}\n\tif m.MaxProperties != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"maxProperties\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MaxProperties))\n\t}\n\tif m.MinProperties != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"minProperties\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForInt(m.MinProperties))\n\t}\n\tif len(m.Required) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"required\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Required))\n\t}\n\tif len(m.Enum) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Enum {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.Type != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\t}\n\tif len(m.AllOf) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.AllOf {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"allOf\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif len(m.OneOf) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.OneOf {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"oneOf\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif len(m.AnyOf) != 0 {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.AnyOf {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"anyOf\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.Not != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"not\"))\n\t\tinfo.Content = append(info.Content, m.Not.ToRawInfo())\n\t}\n\tif m.Items != nil {\n\t\titems := compiler.NewSequenceNode()\n\t\tfor _, item := range m.Items.SchemaOrReference {\n\t\t\titems.Content = append(items.Content, item.ToRawInfo())\n\t\t}\n\t\tif len(items.Content) == 1 {\n\t\t\titems = items.Content[0]\n\t\t}\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"items\"))\n\t\tinfo.Content = append(info.Content, items)\n\t}\n\tif m.Properties != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"properties\"))\n\t\tinfo.Content = append(info.Content, m.Properties.ToRawInfo())\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"additionalProperties\"))\n\t\tinfo.Content = append(info.Content, m.AdditionalProperties.ToRawInfo())\n\t}\n\tif m.Default != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\t\tinfo.Content = append(info.Content, m.Default.ToRawInfo())\n\t}\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Format != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"format\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Format))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of SchemaOrReference suitable for JSON or YAML export.\nfunc (m *SchemaOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// SchemaOrReference\n\t// {Name:schema Type:Schema StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetSchema()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of SchemasOrReferences suitable for JSON or YAML export.\nfunc (m *SchemasOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of SecurityRequirement suitable for JSON or YAML export.\nfunc (m *SecurityRequirement) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of SecurityScheme suitable for JSON or YAML export.\nfunc (m *SecurityScheme) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"type\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Type))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.In != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"in\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.In))\n\t}\n\tif m.Scheme != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"scheme\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Scheme))\n\t}\n\tif m.BearerFormat != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"bearerFormat\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.BearerFormat))\n\t}\n\tif m.Flows != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"flows\"))\n\t\tinfo.Content = append(info.Content, m.Flows.ToRawInfo())\n\t}\n\tif m.OpenIdConnectUrl != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"openIdConnectUrl\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.OpenIdConnectUrl))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of SecuritySchemeOrReference suitable for JSON or YAML export.\nfunc (m *SecuritySchemeOrReference) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// SecuritySchemeOrReference\n\t// {Name:securityScheme Type:SecurityScheme StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv0 := m.GetSecurityScheme()\n\tif v0 != nil {\n\t\treturn v0.ToRawInfo()\n\t}\n\t// {Name:reference Type:Reference StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tv1 := m.GetReference()\n\tif v1 != nil {\n\t\treturn v1.ToRawInfo()\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of SecuritySchemesOrReferences suitable for JSON or YAML export.\nfunc (m *SecuritySchemesOrReferences) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Server suitable for JSON or YAML export.\nfunc (m *Server) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"url\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Url))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.Variables != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"variables\"))\n\t\tinfo.Content = append(info.Content, m.Variables.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ServerVariable suitable for JSON or YAML export.\nfunc (m *ServerVariable) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif len(m.Enum) != 0 {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"enum\"))\n\t\tinfo.Content = append(info.Content, compiler.NewSequenceNodeForStringArray(m.Enum))\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"default\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Default))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of ServerVariables suitable for JSON or YAML export.\nfunc (m *ServerVariables) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.AdditionalProperties != nil {\n\t\tfor _, item := range m.AdditionalProperties {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of SpecificationExtension suitable for JSON or YAML export.\nfunc (m *SpecificationExtension) ToRawInfo() *yaml.Node {\n\t// ONE OF WRAPPER\n\t// SpecificationExtension\n\t// {Name:number Type:float StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v0, ok := m.GetOneof().(*SpecificationExtension_Number); ok {\n\t\treturn compiler.NewScalarNodeForFloat(v0.Number)\n\t}\n\t// {Name:boolean Type:bool StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v1, ok := m.GetOneof().(*SpecificationExtension_Boolean); ok {\n\t\treturn compiler.NewScalarNodeForBool(v1.Boolean)\n\t}\n\t// {Name:string Type:string StringEnumValues:[] MapType: Repeated:false Pattern: Implicit:false Description:}\n\tif v2, ok := m.GetOneof().(*SpecificationExtension_String_); ok {\n\t\treturn compiler.NewScalarNodeForString(v2.String_)\n\t}\n\treturn compiler.NewNullNode()\n}\n\n// ToRawInfo returns a description of StringArray suitable for JSON or YAML export.\nfunc (m *StringArray) ToRawInfo() *yaml.Node {\n\treturn compiler.NewSequenceNodeForStringArray(m.Value)\n}\n\n// ToRawInfo returns a description of Strings suitable for JSON or YAML export.\nfunc (m *Strings) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// &{Name:additionalProperties Type:NamedString StringEnumValues:[] MapType:string Repeated:true Pattern: Implicit:true Description:}\n\treturn info\n}\n\n// ToRawInfo returns a description of Tag suitable for JSON or YAML export.\nfunc (m *Tag) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\t// always include this required field.\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\tif m.Description != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"description\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Description))\n\t}\n\tif m.ExternalDocs != nil {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"externalDocs\"))\n\t\tinfo.Content = append(info.Content, m.ExternalDocs.ToRawInfo())\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\n// ToRawInfo returns a description of Xml suitable for JSON or YAML export.\nfunc (m *Xml) ToRawInfo() *yaml.Node {\n\tinfo := compiler.NewMappingNode()\n\tif m == nil {\n\t\treturn info\n\t}\n\tif m.Name != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"name\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Name))\n\t}\n\tif m.Namespace != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"namespace\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Namespace))\n\t}\n\tif m.Prefix != \"\" {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"prefix\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(m.Prefix))\n\t}\n\tif m.Attribute != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"attribute\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Attribute))\n\t}\n\tif m.Wrapped != false {\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(\"wrapped\"))\n\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForBool(m.Wrapped))\n\t}\n\tif m.SpecificationExtension != nil {\n\t\tfor _, item := range m.SpecificationExtension {\n\t\t\tinfo.Content = append(info.Content, compiler.NewScalarNodeForString(item.Name))\n\t\t\tinfo.Content = append(info.Content, item.Value.ToRawInfo())\n\t\t}\n\t}\n\treturn info\n}\n\nvar (\n\tpattern0 = regexp.MustCompile(\"^\")\n\tpattern1 = regexp.MustCompile(\"^x-\")\n\tpattern2 = regexp.MustCompile(\"^/\")\n\tpattern3 = regexp.MustCompile(\"^([0-9X]{3})$\")\n)\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.pb.go",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\n// THIS FILE IS AUTOMATICALLY GENERATED.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.26.0\n// \tprotoc        v3.18.1\n// source: openapiv3/OpenAPIv3.proto\n\npackage openapi_v3\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\tanypb \"google.golang.org/protobuf/types/known/anypb\"\n\treflect \"reflect\"\n\tsync \"sync\"\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 AdditionalPropertiesItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*AdditionalPropertiesItem_SchemaOrReference\n\t//\t*AdditionalPropertiesItem_Boolean\n\tOneof isAdditionalPropertiesItem_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *AdditionalPropertiesItem) Reset() {\n\t*x = AdditionalPropertiesItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *AdditionalPropertiesItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AdditionalPropertiesItem) ProtoMessage() {}\n\nfunc (x *AdditionalPropertiesItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 AdditionalPropertiesItem.ProtoReflect.Descriptor instead.\nfunc (*AdditionalPropertiesItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (m *AdditionalPropertiesItem) GetOneof() isAdditionalPropertiesItem_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *AdditionalPropertiesItem) GetSchemaOrReference() *SchemaOrReference {\n\tif x, ok := x.GetOneof().(*AdditionalPropertiesItem_SchemaOrReference); ok {\n\t\treturn x.SchemaOrReference\n\t}\n\treturn nil\n}\n\nfunc (x *AdditionalPropertiesItem) GetBoolean() bool {\n\tif x, ok := x.GetOneof().(*AdditionalPropertiesItem_Boolean); ok {\n\t\treturn x.Boolean\n\t}\n\treturn false\n}\n\ntype isAdditionalPropertiesItem_Oneof interface {\n\tisAdditionalPropertiesItem_Oneof()\n}\n\ntype AdditionalPropertiesItem_SchemaOrReference struct {\n\tSchemaOrReference *SchemaOrReference `protobuf:\"bytes,1,opt,name=schema_or_reference,json=schemaOrReference,proto3,oneof\"`\n}\n\ntype AdditionalPropertiesItem_Boolean struct {\n\tBoolean bool `protobuf:\"varint,2,opt,name=boolean,proto3,oneof\"`\n}\n\nfunc (*AdditionalPropertiesItem_SchemaOrReference) isAdditionalPropertiesItem_Oneof() {}\n\nfunc (*AdditionalPropertiesItem_Boolean) isAdditionalPropertiesItem_Oneof() {}\n\ntype Any struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue *anypb.Any `protobuf:\"bytes,1,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tYaml  string     `protobuf:\"bytes,2,opt,name=yaml,proto3\" json:\"yaml,omitempty\"`\n}\n\nfunc (x *Any) Reset() {\n\t*x = Any{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Any) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Any) ProtoMessage() {}\n\nfunc (x *Any) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 Any.ProtoReflect.Descriptor instead.\nfunc (*Any) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *Any) GetValue() *anypb.Any {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\nfunc (x *Any) GetYaml() string {\n\tif x != nil {\n\t\treturn x.Yaml\n\t}\n\treturn \"\"\n}\n\ntype AnyOrExpression struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*AnyOrExpression_Any\n\t//\t*AnyOrExpression_Expression\n\tOneof isAnyOrExpression_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *AnyOrExpression) Reset() {\n\t*x = AnyOrExpression{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *AnyOrExpression) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*AnyOrExpression) ProtoMessage() {}\n\nfunc (x *AnyOrExpression) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 AnyOrExpression.ProtoReflect.Descriptor instead.\nfunc (*AnyOrExpression) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{2}\n}\n\nfunc (m *AnyOrExpression) GetOneof() isAnyOrExpression_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *AnyOrExpression) GetAny() *Any {\n\tif x, ok := x.GetOneof().(*AnyOrExpression_Any); ok {\n\t\treturn x.Any\n\t}\n\treturn nil\n}\n\nfunc (x *AnyOrExpression) GetExpression() *Expression {\n\tif x, ok := x.GetOneof().(*AnyOrExpression_Expression); ok {\n\t\treturn x.Expression\n\t}\n\treturn nil\n}\n\ntype isAnyOrExpression_Oneof interface {\n\tisAnyOrExpression_Oneof()\n}\n\ntype AnyOrExpression_Any struct {\n\tAny *Any `protobuf:\"bytes,1,opt,name=any,proto3,oneof\"`\n}\n\ntype AnyOrExpression_Expression struct {\n\tExpression *Expression `protobuf:\"bytes,2,opt,name=expression,proto3,oneof\"`\n}\n\nfunc (*AnyOrExpression_Any) isAnyOrExpression_Oneof() {}\n\nfunc (*AnyOrExpression_Expression) isAnyOrExpression_Oneof() {}\n\n// A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.\ntype Callback struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tPath                   []*NamedPathItem `protobuf:\"bytes,1,rep,name=path,proto3\" json:\"path,omitempty\"`\n\tSpecificationExtension []*NamedAny      `protobuf:\"bytes,2,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Callback) Reset() {\n\t*x = Callback{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Callback) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Callback) ProtoMessage() {}\n\nfunc (x *Callback) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 Callback.ProtoReflect.Descriptor instead.\nfunc (*Callback) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{3}\n}\n\nfunc (x *Callback) GetPath() []*NamedPathItem {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn nil\n}\n\nfunc (x *Callback) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype CallbackOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*CallbackOrReference_Callback\n\t//\t*CallbackOrReference_Reference\n\tOneof isCallbackOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *CallbackOrReference) Reset() {\n\t*x = CallbackOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *CallbackOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*CallbackOrReference) ProtoMessage() {}\n\nfunc (x *CallbackOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 CallbackOrReference.ProtoReflect.Descriptor instead.\nfunc (*CallbackOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (m *CallbackOrReference) GetOneof() isCallbackOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *CallbackOrReference) GetCallback() *Callback {\n\tif x, ok := x.GetOneof().(*CallbackOrReference_Callback); ok {\n\t\treturn x.Callback\n\t}\n\treturn nil\n}\n\nfunc (x *CallbackOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*CallbackOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isCallbackOrReference_Oneof interface {\n\tisCallbackOrReference_Oneof()\n}\n\ntype CallbackOrReference_Callback struct {\n\tCallback *Callback `protobuf:\"bytes,1,opt,name=callback,proto3,oneof\"`\n}\n\ntype CallbackOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*CallbackOrReference_Callback) isCallbackOrReference_Oneof() {}\n\nfunc (*CallbackOrReference_Reference) isCallbackOrReference_Oneof() {}\n\ntype CallbacksOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedCallbackOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *CallbacksOrReferences) Reset() {\n\t*x = CallbacksOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[5]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *CallbacksOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*CallbacksOrReferences) ProtoMessage() {}\n\nfunc (x *CallbacksOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 CallbacksOrReferences.ProtoReflect.Descriptor instead.\nfunc (*CallbacksOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{5}\n}\n\nfunc (x *CallbacksOrReferences) GetAdditionalProperties() []*NamedCallbackOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.\ntype Components struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSchemas                *SchemasOrReferences         `protobuf:\"bytes,1,opt,name=schemas,proto3\" json:\"schemas,omitempty\"`\n\tResponses              *ResponsesOrReferences       `protobuf:\"bytes,2,opt,name=responses,proto3\" json:\"responses,omitempty\"`\n\tParameters             *ParametersOrReferences      `protobuf:\"bytes,3,opt,name=parameters,proto3\" json:\"parameters,omitempty\"`\n\tExamples               *ExamplesOrReferences        `protobuf:\"bytes,4,opt,name=examples,proto3\" json:\"examples,omitempty\"`\n\tRequestBodies          *RequestBodiesOrReferences   `protobuf:\"bytes,5,opt,name=request_bodies,json=requestBodies,proto3\" json:\"request_bodies,omitempty\"`\n\tHeaders                *HeadersOrReferences         `protobuf:\"bytes,6,opt,name=headers,proto3\" json:\"headers,omitempty\"`\n\tSecuritySchemes        *SecuritySchemesOrReferences `protobuf:\"bytes,7,opt,name=security_schemes,json=securitySchemes,proto3\" json:\"security_schemes,omitempty\"`\n\tLinks                  *LinksOrReferences           `protobuf:\"bytes,8,opt,name=links,proto3\" json:\"links,omitempty\"`\n\tCallbacks              *CallbacksOrReferences       `protobuf:\"bytes,9,opt,name=callbacks,proto3\" json:\"callbacks,omitempty\"`\n\tSpecificationExtension []*NamedAny                  `protobuf:\"bytes,10,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Components) Reset() {\n\t*x = Components{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[6]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Components) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Components) ProtoMessage() {}\n\nfunc (x *Components) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 Components.ProtoReflect.Descriptor instead.\nfunc (*Components) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{6}\n}\n\nfunc (x *Components) GetSchemas() *SchemasOrReferences {\n\tif x != nil {\n\t\treturn x.Schemas\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetResponses() *ResponsesOrReferences {\n\tif x != nil {\n\t\treturn x.Responses\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetParameters() *ParametersOrReferences {\n\tif x != nil {\n\t\treturn x.Parameters\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetExamples() *ExamplesOrReferences {\n\tif x != nil {\n\t\treturn x.Examples\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetRequestBodies() *RequestBodiesOrReferences {\n\tif x != nil {\n\t\treturn x.RequestBodies\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetHeaders() *HeadersOrReferences {\n\tif x != nil {\n\t\treturn x.Headers\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetSecuritySchemes() *SecuritySchemesOrReferences {\n\tif x != nil {\n\t\treturn x.SecuritySchemes\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetLinks() *LinksOrReferences {\n\tif x != nil {\n\t\treturn x.Links\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetCallbacks() *CallbacksOrReferences {\n\tif x != nil {\n\t\treturn x.Callbacks\n\t}\n\treturn nil\n}\n\nfunc (x *Components) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// Contact information for the exposed API.\ntype Contact struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName                   string      `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tUrl                    string      `protobuf:\"bytes,2,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tEmail                  string      `protobuf:\"bytes,3,opt,name=email,proto3\" json:\"email,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,4,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Contact) Reset() {\n\t*x = Contact{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[7]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Contact) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Contact) ProtoMessage() {}\n\nfunc (x *Contact) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 Contact.ProtoReflect.Descriptor instead.\nfunc (*Contact) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{7}\n}\n\nfunc (x *Contact) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Contact) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *Contact) GetEmail() string {\n\tif x != nil {\n\t\treturn x.Email\n\t}\n\treturn \"\"\n}\n\nfunc (x *Contact) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype DefaultType struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*DefaultType_Number\n\t//\t*DefaultType_Boolean\n\t//\t*DefaultType_String_\n\tOneof isDefaultType_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *DefaultType) Reset() {\n\t*x = DefaultType{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[8]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *DefaultType) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DefaultType) ProtoMessage() {}\n\nfunc (x *DefaultType) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 DefaultType.ProtoReflect.Descriptor instead.\nfunc (*DefaultType) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{8}\n}\n\nfunc (m *DefaultType) GetOneof() isDefaultType_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *DefaultType) GetNumber() float64 {\n\tif x, ok := x.GetOneof().(*DefaultType_Number); ok {\n\t\treturn x.Number\n\t}\n\treturn 0\n}\n\nfunc (x *DefaultType) GetBoolean() bool {\n\tif x, ok := x.GetOneof().(*DefaultType_Boolean); ok {\n\t\treturn x.Boolean\n\t}\n\treturn false\n}\n\nfunc (x *DefaultType) GetString_() string {\n\tif x, ok := x.GetOneof().(*DefaultType_String_); ok {\n\t\treturn x.String_\n\t}\n\treturn \"\"\n}\n\ntype isDefaultType_Oneof interface {\n\tisDefaultType_Oneof()\n}\n\ntype DefaultType_Number struct {\n\tNumber float64 `protobuf:\"fixed64,1,opt,name=number,proto3,oneof\"`\n}\n\ntype DefaultType_Boolean struct {\n\tBoolean bool `protobuf:\"varint,2,opt,name=boolean,proto3,oneof\"`\n}\n\ntype DefaultType_String_ struct {\n\tString_ string `protobuf:\"bytes,3,opt,name=string,proto3,oneof\"`\n}\n\nfunc (*DefaultType_Number) isDefaultType_Oneof() {}\n\nfunc (*DefaultType_Boolean) isDefaultType_Oneof() {}\n\nfunc (*DefaultType_String_) isDefaultType_Oneof() {}\n\n// When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation.  The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it.  When using the discriminator, _inline_ schemas will not be considered.\ntype Discriminator struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tPropertyName           string      `protobuf:\"bytes,1,opt,name=property_name,json=propertyName,proto3\" json:\"property_name,omitempty\"`\n\tMapping                *Strings    `protobuf:\"bytes,2,opt,name=mapping,proto3\" json:\"mapping,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,3,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Discriminator) Reset() {\n\t*x = Discriminator{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[9]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Discriminator) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Discriminator) ProtoMessage() {}\n\nfunc (x *Discriminator) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 Discriminator.ProtoReflect.Descriptor instead.\nfunc (*Discriminator) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{9}\n}\n\nfunc (x *Discriminator) GetPropertyName() string {\n\tif x != nil {\n\t\treturn x.PropertyName\n\t}\n\treturn \"\"\n}\n\nfunc (x *Discriminator) GetMapping() *Strings {\n\tif x != nil {\n\t\treturn x.Mapping\n\t}\n\treturn nil\n}\n\nfunc (x *Discriminator) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype Document struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tOpenapi                string                 `protobuf:\"bytes,1,opt,name=openapi,proto3\" json:\"openapi,omitempty\"`\n\tInfo                   *Info                  `protobuf:\"bytes,2,opt,name=info,proto3\" json:\"info,omitempty\"`\n\tServers                []*Server              `protobuf:\"bytes,3,rep,name=servers,proto3\" json:\"servers,omitempty\"`\n\tPaths                  *Paths                 `protobuf:\"bytes,4,opt,name=paths,proto3\" json:\"paths,omitempty\"`\n\tComponents             *Components            `protobuf:\"bytes,5,opt,name=components,proto3\" json:\"components,omitempty\"`\n\tSecurity               []*SecurityRequirement `protobuf:\"bytes,6,rep,name=security,proto3\" json:\"security,omitempty\"`\n\tTags                   []*Tag                 `protobuf:\"bytes,7,rep,name=tags,proto3\" json:\"tags,omitempty\"`\n\tExternalDocs           *ExternalDocs          `protobuf:\"bytes,8,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tSpecificationExtension []*NamedAny            `protobuf:\"bytes,9,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Document) Reset() {\n\t*x = Document{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[10]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Document) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Document) ProtoMessage() {}\n\nfunc (x *Document) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_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 Document.ProtoReflect.Descriptor instead.\nfunc (*Document) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{10}\n}\n\nfunc (x *Document) GetOpenapi() string {\n\tif x != nil {\n\t\treturn x.Openapi\n\t}\n\treturn \"\"\n}\n\nfunc (x *Document) GetInfo() *Info {\n\tif x != nil {\n\t\treturn x.Info\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetServers() []*Server {\n\tif x != nil {\n\t\treturn x.Servers\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetPaths() *Paths {\n\tif x != nil {\n\t\treturn x.Paths\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetComponents() *Components {\n\tif x != nil {\n\t\treturn x.Components\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetSecurity() []*SecurityRequirement {\n\tif x != nil {\n\t\treturn x.Security\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetTags() []*Tag {\n\tif x != nil {\n\t\treturn x.Tags\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Document) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// A single encoding definition applied to a single schema property.\ntype Encoding struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tContentType            string               `protobuf:\"bytes,1,opt,name=content_type,json=contentType,proto3\" json:\"content_type,omitempty\"`\n\tHeaders                *HeadersOrReferences `protobuf:\"bytes,2,opt,name=headers,proto3\" json:\"headers,omitempty\"`\n\tStyle                  string               `protobuf:\"bytes,3,opt,name=style,proto3\" json:\"style,omitempty\"`\n\tExplode                bool                 `protobuf:\"varint,4,opt,name=explode,proto3\" json:\"explode,omitempty\"`\n\tAllowReserved          bool                 `protobuf:\"varint,5,opt,name=allow_reserved,json=allowReserved,proto3\" json:\"allow_reserved,omitempty\"`\n\tSpecificationExtension []*NamedAny          `protobuf:\"bytes,6,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Encoding) Reset() {\n\t*x = Encoding{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[11]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Encoding) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Encoding) ProtoMessage() {}\n\nfunc (x *Encoding) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[11]\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 Encoding.ProtoReflect.Descriptor instead.\nfunc (*Encoding) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{11}\n}\n\nfunc (x *Encoding) GetContentType() string {\n\tif x != nil {\n\t\treturn x.ContentType\n\t}\n\treturn \"\"\n}\n\nfunc (x *Encoding) GetHeaders() *HeadersOrReferences {\n\tif x != nil {\n\t\treturn x.Headers\n\t}\n\treturn nil\n}\n\nfunc (x *Encoding) GetStyle() string {\n\tif x != nil {\n\t\treturn x.Style\n\t}\n\treturn \"\"\n}\n\nfunc (x *Encoding) GetExplode() bool {\n\tif x != nil {\n\t\treturn x.Explode\n\t}\n\treturn false\n}\n\nfunc (x *Encoding) GetAllowReserved() bool {\n\tif x != nil {\n\t\treturn x.AllowReserved\n\t}\n\treturn false\n}\n\nfunc (x *Encoding) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype Encodings struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedEncoding `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Encodings) Reset() {\n\t*x = Encodings{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[12]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Encodings) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Encodings) ProtoMessage() {}\n\nfunc (x *Encodings) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[12]\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 Encodings.ProtoReflect.Descriptor instead.\nfunc (*Encodings) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{12}\n}\n\nfunc (x *Encodings) GetAdditionalProperties() []*NamedEncoding {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype Example struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSummary                string      `protobuf:\"bytes,1,opt,name=summary,proto3\" json:\"summary,omitempty\"`\n\tDescription            string      `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tValue                  *Any        `protobuf:\"bytes,3,opt,name=value,proto3\" json:\"value,omitempty\"`\n\tExternalValue          string      `protobuf:\"bytes,4,opt,name=external_value,json=externalValue,proto3\" json:\"external_value,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,5,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Example) Reset() {\n\t*x = Example{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[13]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Example) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Example) ProtoMessage() {}\n\nfunc (x *Example) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[13]\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 Example.ProtoReflect.Descriptor instead.\nfunc (*Example) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{13}\n}\n\nfunc (x *Example) GetSummary() string {\n\tif x != nil {\n\t\treturn x.Summary\n\t}\n\treturn \"\"\n}\n\nfunc (x *Example) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Example) GetValue() *Any {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\nfunc (x *Example) GetExternalValue() string {\n\tif x != nil {\n\t\treturn x.ExternalValue\n\t}\n\treturn \"\"\n}\n\nfunc (x *Example) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype ExampleOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*ExampleOrReference_Example\n\t//\t*ExampleOrReference_Reference\n\tOneof isExampleOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *ExampleOrReference) Reset() {\n\t*x = ExampleOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[14]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExampleOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExampleOrReference) ProtoMessage() {}\n\nfunc (x *ExampleOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[14]\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 ExampleOrReference.ProtoReflect.Descriptor instead.\nfunc (*ExampleOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{14}\n}\n\nfunc (m *ExampleOrReference) GetOneof() isExampleOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *ExampleOrReference) GetExample() *Example {\n\tif x, ok := x.GetOneof().(*ExampleOrReference_Example); ok {\n\t\treturn x.Example\n\t}\n\treturn nil\n}\n\nfunc (x *ExampleOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*ExampleOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isExampleOrReference_Oneof interface {\n\tisExampleOrReference_Oneof()\n}\n\ntype ExampleOrReference_Example struct {\n\tExample *Example `protobuf:\"bytes,1,opt,name=example,proto3,oneof\"`\n}\n\ntype ExampleOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*ExampleOrReference_Example) isExampleOrReference_Oneof() {}\n\nfunc (*ExampleOrReference_Reference) isExampleOrReference_Oneof() {}\n\ntype ExamplesOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedExampleOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *ExamplesOrReferences) Reset() {\n\t*x = ExamplesOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[15]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExamplesOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExamplesOrReferences) ProtoMessage() {}\n\nfunc (x *ExamplesOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[15]\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 ExamplesOrReferences.ProtoReflect.Descriptor instead.\nfunc (*ExamplesOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{15}\n}\n\nfunc (x *ExamplesOrReferences) GetAdditionalProperties() []*NamedExampleOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\ntype Expression struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedAny `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Expression) Reset() {\n\t*x = Expression{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[16]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Expression) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Expression) ProtoMessage() {}\n\nfunc (x *Expression) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[16]\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 Expression.ProtoReflect.Descriptor instead.\nfunc (*Expression) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{16}\n}\n\nfunc (x *Expression) GetAdditionalProperties() []*NamedAny {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Allows referencing an external resource for extended documentation.\ntype ExternalDocs struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tDescription            string      `protobuf:\"bytes,1,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tUrl                    string      `protobuf:\"bytes,2,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,3,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *ExternalDocs) Reset() {\n\t*x = ExternalDocs{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[17]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ExternalDocs) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ExternalDocs) ProtoMessage() {}\n\nfunc (x *ExternalDocs) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[17]\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 ExternalDocs.ProtoReflect.Descriptor instead.\nfunc (*ExternalDocs) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{17}\n}\n\nfunc (x *ExternalDocs) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *ExternalDocs) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *ExternalDocs) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// The Header Object follows the structure of the Parameter Object with the following changes:  1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).\ntype Header struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tDescription            string                `protobuf:\"bytes,1,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tRequired               bool                  `protobuf:\"varint,2,opt,name=required,proto3\" json:\"required,omitempty\"`\n\tDeprecated             bool                  `protobuf:\"varint,3,opt,name=deprecated,proto3\" json:\"deprecated,omitempty\"`\n\tAllowEmptyValue        bool                  `protobuf:\"varint,4,opt,name=allow_empty_value,json=allowEmptyValue,proto3\" json:\"allow_empty_value,omitempty\"`\n\tStyle                  string                `protobuf:\"bytes,5,opt,name=style,proto3\" json:\"style,omitempty\"`\n\tExplode                bool                  `protobuf:\"varint,6,opt,name=explode,proto3\" json:\"explode,omitempty\"`\n\tAllowReserved          bool                  `protobuf:\"varint,7,opt,name=allow_reserved,json=allowReserved,proto3\" json:\"allow_reserved,omitempty\"`\n\tSchema                 *SchemaOrReference    `protobuf:\"bytes,8,opt,name=schema,proto3\" json:\"schema,omitempty\"`\n\tExample                *Any                  `protobuf:\"bytes,9,opt,name=example,proto3\" json:\"example,omitempty\"`\n\tExamples               *ExamplesOrReferences `protobuf:\"bytes,10,opt,name=examples,proto3\" json:\"examples,omitempty\"`\n\tContent                *MediaTypes           `protobuf:\"bytes,11,opt,name=content,proto3\" json:\"content,omitempty\"`\n\tSpecificationExtension []*NamedAny           `protobuf:\"bytes,12,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Header) Reset() {\n\t*x = Header{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[18]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Header) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Header) ProtoMessage() {}\n\nfunc (x *Header) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[18]\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 Header.ProtoReflect.Descriptor instead.\nfunc (*Header) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{18}\n}\n\nfunc (x *Header) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetDeprecated() bool {\n\tif x != nil {\n\t\treturn x.Deprecated\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetAllowEmptyValue() bool {\n\tif x != nil {\n\t\treturn x.AllowEmptyValue\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetStyle() string {\n\tif x != nil {\n\t\treturn x.Style\n\t}\n\treturn \"\"\n}\n\nfunc (x *Header) GetExplode() bool {\n\tif x != nil {\n\t\treturn x.Explode\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetAllowReserved() bool {\n\tif x != nil {\n\t\treturn x.AllowReserved\n\t}\n\treturn false\n}\n\nfunc (x *Header) GetSchema() *SchemaOrReference {\n\tif x != nil {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *Header) GetExample() *Any {\n\tif x != nil {\n\t\treturn x.Example\n\t}\n\treturn nil\n}\n\nfunc (x *Header) GetExamples() *ExamplesOrReferences {\n\tif x != nil {\n\t\treturn x.Examples\n\t}\n\treturn nil\n}\n\nfunc (x *Header) GetContent() *MediaTypes {\n\tif x != nil {\n\t\treturn x.Content\n\t}\n\treturn nil\n}\n\nfunc (x *Header) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype HeaderOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*HeaderOrReference_Header\n\t//\t*HeaderOrReference_Reference\n\tOneof isHeaderOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *HeaderOrReference) Reset() {\n\t*x = HeaderOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[19]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HeaderOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HeaderOrReference) ProtoMessage() {}\n\nfunc (x *HeaderOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[19]\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 HeaderOrReference.ProtoReflect.Descriptor instead.\nfunc (*HeaderOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{19}\n}\n\nfunc (m *HeaderOrReference) GetOneof() isHeaderOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderOrReference) GetHeader() *Header {\n\tif x, ok := x.GetOneof().(*HeaderOrReference_Header); ok {\n\t\treturn x.Header\n\t}\n\treturn nil\n}\n\nfunc (x *HeaderOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*HeaderOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isHeaderOrReference_Oneof interface {\n\tisHeaderOrReference_Oneof()\n}\n\ntype HeaderOrReference_Header struct {\n\tHeader *Header `protobuf:\"bytes,1,opt,name=header,proto3,oneof\"`\n}\n\ntype HeaderOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*HeaderOrReference_Header) isHeaderOrReference_Oneof() {}\n\nfunc (*HeaderOrReference_Reference) isHeaderOrReference_Oneof() {}\n\ntype HeadersOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedHeaderOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *HeadersOrReferences) Reset() {\n\t*x = HeadersOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[20]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HeadersOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HeadersOrReferences) ProtoMessage() {}\n\nfunc (x *HeadersOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[20]\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 HeadersOrReferences.ProtoReflect.Descriptor instead.\nfunc (*HeadersOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{20}\n}\n\nfunc (x *HeadersOrReferences) GetAdditionalProperties() []*NamedHeaderOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.\ntype Info struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tTitle                  string      `protobuf:\"bytes,1,opt,name=title,proto3\" json:\"title,omitempty\"`\n\tDescription            string      `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tTermsOfService         string      `protobuf:\"bytes,3,opt,name=terms_of_service,json=termsOfService,proto3\" json:\"terms_of_service,omitempty\"`\n\tContact                *Contact    `protobuf:\"bytes,4,opt,name=contact,proto3\" json:\"contact,omitempty\"`\n\tLicense                *License    `protobuf:\"bytes,5,opt,name=license,proto3\" json:\"license,omitempty\"`\n\tVersion                string      `protobuf:\"bytes,6,opt,name=version,proto3\" json:\"version,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,7,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n\tSummary                string      `protobuf:\"bytes,8,opt,name=summary,proto3\" json:\"summary,omitempty\"`\n}\n\nfunc (x *Info) Reset() {\n\t*x = Info{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[21]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Info) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Info) ProtoMessage() {}\n\nfunc (x *Info) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[21]\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 Info.ProtoReflect.Descriptor instead.\nfunc (*Info) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{21}\n}\n\nfunc (x *Info) GetTitle() string {\n\tif x != nil {\n\t\treturn x.Title\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetTermsOfService() string {\n\tif x != nil {\n\t\treturn x.TermsOfService\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetContact() *Contact {\n\tif x != nil {\n\t\treturn x.Contact\n\t}\n\treturn nil\n}\n\nfunc (x *Info) GetLicense() *License {\n\tif x != nil {\n\t\treturn x.License\n\t}\n\treturn nil\n}\n\nfunc (x *Info) GetVersion() string {\n\tif x != nil {\n\t\treturn x.Version\n\t}\n\treturn \"\"\n}\n\nfunc (x *Info) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\nfunc (x *Info) GetSummary() string {\n\tif x != nil {\n\t\treturn x.Summary\n\t}\n\treturn \"\"\n}\n\ntype ItemsItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSchemaOrReference []*SchemaOrReference `protobuf:\"bytes,1,rep,name=schema_or_reference,json=schemaOrReference,proto3\" json:\"schema_or_reference,omitempty\"`\n}\n\nfunc (x *ItemsItem) Reset() {\n\t*x = ItemsItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[22]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ItemsItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ItemsItem) ProtoMessage() {}\n\nfunc (x *ItemsItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[22]\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 ItemsItem.ProtoReflect.Descriptor instead.\nfunc (*ItemsItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{22}\n}\n\nfunc (x *ItemsItem) GetSchemaOrReference() []*SchemaOrReference {\n\tif x != nil {\n\t\treturn x.SchemaOrReference\n\t}\n\treturn nil\n}\n\n// License information for the exposed API.\ntype License struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName                   string      `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tUrl                    string      `protobuf:\"bytes,2,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,3,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *License) Reset() {\n\t*x = License{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[23]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *License) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*License) ProtoMessage() {}\n\nfunc (x *License) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[23]\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 License.ProtoReflect.Descriptor instead.\nfunc (*License) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{23}\n}\n\nfunc (x *License) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *License) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *License) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.  Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response.  For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.\ntype Link struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tOperationRef           string           `protobuf:\"bytes,1,opt,name=operation_ref,json=operationRef,proto3\" json:\"operation_ref,omitempty\"`\n\tOperationId            string           `protobuf:\"bytes,2,opt,name=operation_id,json=operationId,proto3\" json:\"operation_id,omitempty\"`\n\tParameters             *AnyOrExpression `protobuf:\"bytes,3,opt,name=parameters,proto3\" json:\"parameters,omitempty\"`\n\tRequestBody            *AnyOrExpression `protobuf:\"bytes,4,opt,name=request_body,json=requestBody,proto3\" json:\"request_body,omitempty\"`\n\tDescription            string           `protobuf:\"bytes,5,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tServer                 *Server          `protobuf:\"bytes,6,opt,name=server,proto3\" json:\"server,omitempty\"`\n\tSpecificationExtension []*NamedAny      `protobuf:\"bytes,7,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Link) Reset() {\n\t*x = Link{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[24]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Link) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Link) ProtoMessage() {}\n\nfunc (x *Link) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[24]\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 Link.ProtoReflect.Descriptor instead.\nfunc (*Link) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{24}\n}\n\nfunc (x *Link) GetOperationRef() string {\n\tif x != nil {\n\t\treturn x.OperationRef\n\t}\n\treturn \"\"\n}\n\nfunc (x *Link) GetOperationId() string {\n\tif x != nil {\n\t\treturn x.OperationId\n\t}\n\treturn \"\"\n}\n\nfunc (x *Link) GetParameters() *AnyOrExpression {\n\tif x != nil {\n\t\treturn x.Parameters\n\t}\n\treturn nil\n}\n\nfunc (x *Link) GetRequestBody() *AnyOrExpression {\n\tif x != nil {\n\t\treturn x.RequestBody\n\t}\n\treturn nil\n}\n\nfunc (x *Link) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Link) GetServer() *Server {\n\tif x != nil {\n\t\treturn x.Server\n\t}\n\treturn nil\n}\n\nfunc (x *Link) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype LinkOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*LinkOrReference_Link\n\t//\t*LinkOrReference_Reference\n\tOneof isLinkOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *LinkOrReference) Reset() {\n\t*x = LinkOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[25]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *LinkOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*LinkOrReference) ProtoMessage() {}\n\nfunc (x *LinkOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[25]\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 LinkOrReference.ProtoReflect.Descriptor instead.\nfunc (*LinkOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{25}\n}\n\nfunc (m *LinkOrReference) GetOneof() isLinkOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *LinkOrReference) GetLink() *Link {\n\tif x, ok := x.GetOneof().(*LinkOrReference_Link); ok {\n\t\treturn x.Link\n\t}\n\treturn nil\n}\n\nfunc (x *LinkOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*LinkOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isLinkOrReference_Oneof interface {\n\tisLinkOrReference_Oneof()\n}\n\ntype LinkOrReference_Link struct {\n\tLink *Link `protobuf:\"bytes,1,opt,name=link,proto3,oneof\"`\n}\n\ntype LinkOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*LinkOrReference_Link) isLinkOrReference_Oneof() {}\n\nfunc (*LinkOrReference_Reference) isLinkOrReference_Oneof() {}\n\ntype LinksOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedLinkOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *LinksOrReferences) Reset() {\n\t*x = LinksOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[26]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *LinksOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*LinksOrReferences) ProtoMessage() {}\n\nfunc (x *LinksOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[26]\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 LinksOrReferences.ProtoReflect.Descriptor instead.\nfunc (*LinksOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{26}\n}\n\nfunc (x *LinksOrReferences) GetAdditionalProperties() []*NamedLinkOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Each Media Type Object provides schema and examples for the media type identified by its key.\ntype MediaType struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tSchema                 *SchemaOrReference    `protobuf:\"bytes,1,opt,name=schema,proto3\" json:\"schema,omitempty\"`\n\tExample                *Any                  `protobuf:\"bytes,2,opt,name=example,proto3\" json:\"example,omitempty\"`\n\tExamples               *ExamplesOrReferences `protobuf:\"bytes,3,opt,name=examples,proto3\" json:\"examples,omitempty\"`\n\tEncoding               *Encodings            `protobuf:\"bytes,4,opt,name=encoding,proto3\" json:\"encoding,omitempty\"`\n\tSpecificationExtension []*NamedAny           `protobuf:\"bytes,5,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *MediaType) Reset() {\n\t*x = MediaType{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[27]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *MediaType) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*MediaType) ProtoMessage() {}\n\nfunc (x *MediaType) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[27]\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 MediaType.ProtoReflect.Descriptor instead.\nfunc (*MediaType) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{27}\n}\n\nfunc (x *MediaType) GetSchema() *SchemaOrReference {\n\tif x != nil {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *MediaType) GetExample() *Any {\n\tif x != nil {\n\t\treturn x.Example\n\t}\n\treturn nil\n}\n\nfunc (x *MediaType) GetExamples() *ExamplesOrReferences {\n\tif x != nil {\n\t\treturn x.Examples\n\t}\n\treturn nil\n}\n\nfunc (x *MediaType) GetEncoding() *Encodings {\n\tif x != nil {\n\t\treturn x.Encoding\n\t}\n\treturn nil\n}\n\nfunc (x *MediaType) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype MediaTypes struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedMediaType `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *MediaTypes) Reset() {\n\t*x = MediaTypes{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[28]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *MediaTypes) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*MediaTypes) ProtoMessage() {}\n\nfunc (x *MediaTypes) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[28]\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 MediaTypes.ProtoReflect.Descriptor instead.\nfunc (*MediaTypes) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{28}\n}\n\nfunc (x *MediaTypes) GetAdditionalProperties() []*NamedMediaType {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs.\ntype NamedAny struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *Any `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedAny) Reset() {\n\t*x = NamedAny{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[29]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedAny) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedAny) ProtoMessage() {}\n\nfunc (x *NamedAny) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[29]\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 NamedAny.ProtoReflect.Descriptor instead.\nfunc (*NamedAny) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{29}\n}\n\nfunc (x *NamedAny) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedAny) GetValue() *Any {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of CallbackOrReference as ordered (name,value) pairs.\ntype NamedCallbackOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *CallbackOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedCallbackOrReference) Reset() {\n\t*x = NamedCallbackOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[30]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedCallbackOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedCallbackOrReference) ProtoMessage() {}\n\nfunc (x *NamedCallbackOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[30]\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 NamedCallbackOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedCallbackOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{30}\n}\n\nfunc (x *NamedCallbackOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedCallbackOrReference) GetValue() *CallbackOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of Encoding as ordered (name,value) pairs.\ntype NamedEncoding struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *Encoding `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedEncoding) Reset() {\n\t*x = NamedEncoding{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[31]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedEncoding) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedEncoding) ProtoMessage() {}\n\nfunc (x *NamedEncoding) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[31]\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 NamedEncoding.ProtoReflect.Descriptor instead.\nfunc (*NamedEncoding) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{31}\n}\n\nfunc (x *NamedEncoding) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedEncoding) GetValue() *Encoding {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of ExampleOrReference as ordered (name,value) pairs.\ntype NamedExampleOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *ExampleOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedExampleOrReference) Reset() {\n\t*x = NamedExampleOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[32]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedExampleOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedExampleOrReference) ProtoMessage() {}\n\nfunc (x *NamedExampleOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[32]\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 NamedExampleOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedExampleOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{32}\n}\n\nfunc (x *NamedExampleOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedExampleOrReference) GetValue() *ExampleOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of HeaderOrReference as ordered (name,value) pairs.\ntype NamedHeaderOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *HeaderOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedHeaderOrReference) Reset() {\n\t*x = NamedHeaderOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[33]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedHeaderOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedHeaderOrReference) ProtoMessage() {}\n\nfunc (x *NamedHeaderOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[33]\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 NamedHeaderOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedHeaderOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{33}\n}\n\nfunc (x *NamedHeaderOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedHeaderOrReference) GetValue() *HeaderOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of LinkOrReference as ordered (name,value) pairs.\ntype NamedLinkOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *LinkOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedLinkOrReference) Reset() {\n\t*x = NamedLinkOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[34]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedLinkOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedLinkOrReference) ProtoMessage() {}\n\nfunc (x *NamedLinkOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[34]\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 NamedLinkOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedLinkOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{34}\n}\n\nfunc (x *NamedLinkOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedLinkOrReference) GetValue() *LinkOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of MediaType as ordered (name,value) pairs.\ntype NamedMediaType struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *MediaType `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedMediaType) Reset() {\n\t*x = NamedMediaType{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[35]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedMediaType) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedMediaType) ProtoMessage() {}\n\nfunc (x *NamedMediaType) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[35]\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 NamedMediaType.ProtoReflect.Descriptor instead.\nfunc (*NamedMediaType) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{35}\n}\n\nfunc (x *NamedMediaType) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedMediaType) GetValue() *MediaType {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of ParameterOrReference as ordered (name,value) pairs.\ntype NamedParameterOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *ParameterOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedParameterOrReference) Reset() {\n\t*x = NamedParameterOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[36]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedParameterOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedParameterOrReference) ProtoMessage() {}\n\nfunc (x *NamedParameterOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[36]\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 NamedParameterOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedParameterOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{36}\n}\n\nfunc (x *NamedParameterOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedParameterOrReference) GetValue() *ParameterOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs.\ntype NamedPathItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *PathItem `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedPathItem) Reset() {\n\t*x = NamedPathItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[37]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedPathItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedPathItem) ProtoMessage() {}\n\nfunc (x *NamedPathItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[37]\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 NamedPathItem.ProtoReflect.Descriptor instead.\nfunc (*NamedPathItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{37}\n}\n\nfunc (x *NamedPathItem) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedPathItem) GetValue() *PathItem {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of RequestBodyOrReference as ordered (name,value) pairs.\ntype NamedRequestBodyOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *RequestBodyOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedRequestBodyOrReference) Reset() {\n\t*x = NamedRequestBodyOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[38]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedRequestBodyOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedRequestBodyOrReference) ProtoMessage() {}\n\nfunc (x *NamedRequestBodyOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[38]\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 NamedRequestBodyOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedRequestBodyOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{38}\n}\n\nfunc (x *NamedRequestBodyOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedRequestBodyOrReference) GetValue() *RequestBodyOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of ResponseOrReference as ordered (name,value) pairs.\ntype NamedResponseOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *ResponseOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedResponseOrReference) Reset() {\n\t*x = NamedResponseOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[39]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedResponseOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedResponseOrReference) ProtoMessage() {}\n\nfunc (x *NamedResponseOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[39]\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 NamedResponseOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedResponseOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{39}\n}\n\nfunc (x *NamedResponseOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedResponseOrReference) GetValue() *ResponseOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of SchemaOrReference as ordered (name,value) pairs.\ntype NamedSchemaOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *SchemaOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedSchemaOrReference) Reset() {\n\t*x = NamedSchemaOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[40]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedSchemaOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedSchemaOrReference) ProtoMessage() {}\n\nfunc (x *NamedSchemaOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[40]\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 NamedSchemaOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedSchemaOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{40}\n}\n\nfunc (x *NamedSchemaOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedSchemaOrReference) GetValue() *SchemaOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of SecuritySchemeOrReference as ordered (name,value) pairs.\ntype NamedSecuritySchemeOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *SecuritySchemeOrReference `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedSecuritySchemeOrReference) Reset() {\n\t*x = NamedSecuritySchemeOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[41]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedSecuritySchemeOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedSecuritySchemeOrReference) ProtoMessage() {}\n\nfunc (x *NamedSecuritySchemeOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[41]\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 NamedSecuritySchemeOrReference.ProtoReflect.Descriptor instead.\nfunc (*NamedSecuritySchemeOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{41}\n}\n\nfunc (x *NamedSecuritySchemeOrReference) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedSecuritySchemeOrReference) GetValue() *SecuritySchemeOrReference {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of ServerVariable as ordered (name,value) pairs.\ntype NamedServerVariable struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *ServerVariable `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedServerVariable) Reset() {\n\t*x = NamedServerVariable{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[42]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedServerVariable) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedServerVariable) ProtoMessage() {}\n\nfunc (x *NamedServerVariable) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[42]\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 NamedServerVariable.ProtoReflect.Descriptor instead.\nfunc (*NamedServerVariable) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{42}\n}\n\nfunc (x *NamedServerVariable) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedServerVariable) GetValue() *ServerVariable {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Automatically-generated message used to represent maps of string as ordered (name,value) pairs.\ntype NamedString struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue string `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedString) Reset() {\n\t*x = NamedString{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[43]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedString) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedString) ProtoMessage() {}\n\nfunc (x *NamedString) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[43]\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 NamedString.ProtoReflect.Descriptor instead.\nfunc (*NamedString) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{43}\n}\n\nfunc (x *NamedString) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedString) GetValue() string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn \"\"\n}\n\n// Automatically-generated message used to represent maps of StringArray as ordered (name,value) pairs.\ntype NamedStringArray struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Map key\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\t// Mapped value\n\tValue *StringArray `protobuf:\"bytes,2,opt,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *NamedStringArray) Reset() {\n\t*x = NamedStringArray{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[44]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NamedStringArray) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NamedStringArray) ProtoMessage() {}\n\nfunc (x *NamedStringArray) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[44]\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 NamedStringArray.ProtoReflect.Descriptor instead.\nfunc (*NamedStringArray) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{44}\n}\n\nfunc (x *NamedStringArray) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *NamedStringArray) GetValue() *StringArray {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\n// Configuration details for a supported OAuth Flow\ntype OauthFlow struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAuthorizationUrl       string      `protobuf:\"bytes,1,opt,name=authorization_url,json=authorizationUrl,proto3\" json:\"authorization_url,omitempty\"`\n\tTokenUrl               string      `protobuf:\"bytes,2,opt,name=token_url,json=tokenUrl,proto3\" json:\"token_url,omitempty\"`\n\tRefreshUrl             string      `protobuf:\"bytes,3,opt,name=refresh_url,json=refreshUrl,proto3\" json:\"refresh_url,omitempty\"`\n\tScopes                 *Strings    `protobuf:\"bytes,4,opt,name=scopes,proto3\" json:\"scopes,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,5,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *OauthFlow) Reset() {\n\t*x = OauthFlow{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[45]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *OauthFlow) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OauthFlow) ProtoMessage() {}\n\nfunc (x *OauthFlow) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[45]\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 OauthFlow.ProtoReflect.Descriptor instead.\nfunc (*OauthFlow) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{45}\n}\n\nfunc (x *OauthFlow) GetAuthorizationUrl() string {\n\tif x != nil {\n\t\treturn x.AuthorizationUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *OauthFlow) GetTokenUrl() string {\n\tif x != nil {\n\t\treturn x.TokenUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *OauthFlow) GetRefreshUrl() string {\n\tif x != nil {\n\t\treturn x.RefreshUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *OauthFlow) GetScopes() *Strings {\n\tif x != nil {\n\t\treturn x.Scopes\n\t}\n\treturn nil\n}\n\nfunc (x *OauthFlow) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// Allows configuration of the supported OAuth Flows.\ntype OauthFlows struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tImplicit               *OauthFlow  `protobuf:\"bytes,1,opt,name=implicit,proto3\" json:\"implicit,omitempty\"`\n\tPassword               *OauthFlow  `protobuf:\"bytes,2,opt,name=password,proto3\" json:\"password,omitempty\"`\n\tClientCredentials      *OauthFlow  `protobuf:\"bytes,3,opt,name=client_credentials,json=clientCredentials,proto3\" json:\"client_credentials,omitempty\"`\n\tAuthorizationCode      *OauthFlow  `protobuf:\"bytes,4,opt,name=authorization_code,json=authorizationCode,proto3\" json:\"authorization_code,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,5,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *OauthFlows) Reset() {\n\t*x = OauthFlows{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[46]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *OauthFlows) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*OauthFlows) ProtoMessage() {}\n\nfunc (x *OauthFlows) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[46]\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 OauthFlows.ProtoReflect.Descriptor instead.\nfunc (*OauthFlows) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{46}\n}\n\nfunc (x *OauthFlows) GetImplicit() *OauthFlow {\n\tif x != nil {\n\t\treturn x.Implicit\n\t}\n\treturn nil\n}\n\nfunc (x *OauthFlows) GetPassword() *OauthFlow {\n\tif x != nil {\n\t\treturn x.Password\n\t}\n\treturn nil\n}\n\nfunc (x *OauthFlows) GetClientCredentials() *OauthFlow {\n\tif x != nil {\n\t\treturn x.ClientCredentials\n\t}\n\treturn nil\n}\n\nfunc (x *OauthFlows) GetAuthorizationCode() *OauthFlow {\n\tif x != nil {\n\t\treturn x.AuthorizationCode\n\t}\n\treturn nil\n}\n\nfunc (x *OauthFlows) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype Object struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedAny `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Object) Reset() {\n\t*x = Object{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[47]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Object) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Object) ProtoMessage() {}\n\nfunc (x *Object) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[47]\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 Object.ProtoReflect.Descriptor instead.\nfunc (*Object) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{47}\n}\n\nfunc (x *Object) GetAdditionalProperties() []*NamedAny {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Describes a single API operation on a path.\ntype Operation struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tTags                   []string                `protobuf:\"bytes,1,rep,name=tags,proto3\" json:\"tags,omitempty\"`\n\tSummary                string                  `protobuf:\"bytes,2,opt,name=summary,proto3\" json:\"summary,omitempty\"`\n\tDescription            string                  `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tExternalDocs           *ExternalDocs           `protobuf:\"bytes,4,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tOperationId            string                  `protobuf:\"bytes,5,opt,name=operation_id,json=operationId,proto3\" json:\"operation_id,omitempty\"`\n\tParameters             []*ParameterOrReference `protobuf:\"bytes,6,rep,name=parameters,proto3\" json:\"parameters,omitempty\"`\n\tRequestBody            *RequestBodyOrReference `protobuf:\"bytes,7,opt,name=request_body,json=requestBody,proto3\" json:\"request_body,omitempty\"`\n\tResponses              *Responses              `protobuf:\"bytes,8,opt,name=responses,proto3\" json:\"responses,omitempty\"`\n\tCallbacks              *CallbacksOrReferences  `protobuf:\"bytes,9,opt,name=callbacks,proto3\" json:\"callbacks,omitempty\"`\n\tDeprecated             bool                    `protobuf:\"varint,10,opt,name=deprecated,proto3\" json:\"deprecated,omitempty\"`\n\tSecurity               []*SecurityRequirement  `protobuf:\"bytes,11,rep,name=security,proto3\" json:\"security,omitempty\"`\n\tServers                []*Server               `protobuf:\"bytes,12,rep,name=servers,proto3\" json:\"servers,omitempty\"`\n\tSpecificationExtension []*NamedAny             `protobuf:\"bytes,13,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Operation) Reset() {\n\t*x = Operation{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[48]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Operation) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Operation) ProtoMessage() {}\n\nfunc (x *Operation) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[48]\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 Operation.ProtoReflect.Descriptor instead.\nfunc (*Operation) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{48}\n}\n\nfunc (x *Operation) GetTags() []string {\n\tif x != nil {\n\t\treturn x.Tags\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetSummary() string {\n\tif x != nil {\n\t\treturn x.Summary\n\t}\n\treturn \"\"\n}\n\nfunc (x *Operation) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Operation) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetOperationId() string {\n\tif x != nil {\n\t\treturn x.OperationId\n\t}\n\treturn \"\"\n}\n\nfunc (x *Operation) GetParameters() []*ParameterOrReference {\n\tif x != nil {\n\t\treturn x.Parameters\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetRequestBody() *RequestBodyOrReference {\n\tif x != nil {\n\t\treturn x.RequestBody\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetResponses() *Responses {\n\tif x != nil {\n\t\treturn x.Responses\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetCallbacks() *CallbacksOrReferences {\n\tif x != nil {\n\t\treturn x.Callbacks\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetDeprecated() bool {\n\tif x != nil {\n\t\treturn x.Deprecated\n\t}\n\treturn false\n}\n\nfunc (x *Operation) GetSecurity() []*SecurityRequirement {\n\tif x != nil {\n\t\treturn x.Security\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetServers() []*Server {\n\tif x != nil {\n\t\treturn x.Servers\n\t}\n\treturn nil\n}\n\nfunc (x *Operation) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// Describes a single operation parameter.  A unique parameter is defined by a combination of a name and location.\ntype Parameter struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName                   string                `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tIn                     string                `protobuf:\"bytes,2,opt,name=in,proto3\" json:\"in,omitempty\"`\n\tDescription            string                `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tRequired               bool                  `protobuf:\"varint,4,opt,name=required,proto3\" json:\"required,omitempty\"`\n\tDeprecated             bool                  `protobuf:\"varint,5,opt,name=deprecated,proto3\" json:\"deprecated,omitempty\"`\n\tAllowEmptyValue        bool                  `protobuf:\"varint,6,opt,name=allow_empty_value,json=allowEmptyValue,proto3\" json:\"allow_empty_value,omitempty\"`\n\tStyle                  string                `protobuf:\"bytes,7,opt,name=style,proto3\" json:\"style,omitempty\"`\n\tExplode                bool                  `protobuf:\"varint,8,opt,name=explode,proto3\" json:\"explode,omitempty\"`\n\tAllowReserved          bool                  `protobuf:\"varint,9,opt,name=allow_reserved,json=allowReserved,proto3\" json:\"allow_reserved,omitempty\"`\n\tSchema                 *SchemaOrReference    `protobuf:\"bytes,10,opt,name=schema,proto3\" json:\"schema,omitempty\"`\n\tExample                *Any                  `protobuf:\"bytes,11,opt,name=example,proto3\" json:\"example,omitempty\"`\n\tExamples               *ExamplesOrReferences `protobuf:\"bytes,12,opt,name=examples,proto3\" json:\"examples,omitempty\"`\n\tContent                *MediaTypes           `protobuf:\"bytes,13,opt,name=content,proto3\" json:\"content,omitempty\"`\n\tSpecificationExtension []*NamedAny           `protobuf:\"bytes,14,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Parameter) Reset() {\n\t*x = Parameter{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[49]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Parameter) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Parameter) ProtoMessage() {}\n\nfunc (x *Parameter) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[49]\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 Parameter.ProtoReflect.Descriptor instead.\nfunc (*Parameter) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{49}\n}\n\nfunc (x *Parameter) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Parameter) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *Parameter) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Parameter) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *Parameter) GetDeprecated() bool {\n\tif x != nil {\n\t\treturn x.Deprecated\n\t}\n\treturn false\n}\n\nfunc (x *Parameter) GetAllowEmptyValue() bool {\n\tif x != nil {\n\t\treturn x.AllowEmptyValue\n\t}\n\treturn false\n}\n\nfunc (x *Parameter) GetStyle() string {\n\tif x != nil {\n\t\treturn x.Style\n\t}\n\treturn \"\"\n}\n\nfunc (x *Parameter) GetExplode() bool {\n\tif x != nil {\n\t\treturn x.Explode\n\t}\n\treturn false\n}\n\nfunc (x *Parameter) GetAllowReserved() bool {\n\tif x != nil {\n\t\treturn x.AllowReserved\n\t}\n\treturn false\n}\n\nfunc (x *Parameter) GetSchema() *SchemaOrReference {\n\tif x != nil {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *Parameter) GetExample() *Any {\n\tif x != nil {\n\t\treturn x.Example\n\t}\n\treturn nil\n}\n\nfunc (x *Parameter) GetExamples() *ExamplesOrReferences {\n\tif x != nil {\n\t\treturn x.Examples\n\t}\n\treturn nil\n}\n\nfunc (x *Parameter) GetContent() *MediaTypes {\n\tif x != nil {\n\t\treturn x.Content\n\t}\n\treturn nil\n}\n\nfunc (x *Parameter) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype ParameterOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*ParameterOrReference_Parameter\n\t//\t*ParameterOrReference_Reference\n\tOneof isParameterOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *ParameterOrReference) Reset() {\n\t*x = ParameterOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[50]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ParameterOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ParameterOrReference) ProtoMessage() {}\n\nfunc (x *ParameterOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[50]\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 ParameterOrReference.ProtoReflect.Descriptor instead.\nfunc (*ParameterOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{50}\n}\n\nfunc (m *ParameterOrReference) GetOneof() isParameterOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *ParameterOrReference) GetParameter() *Parameter {\n\tif x, ok := x.GetOneof().(*ParameterOrReference_Parameter); ok {\n\t\treturn x.Parameter\n\t}\n\treturn nil\n}\n\nfunc (x *ParameterOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*ParameterOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isParameterOrReference_Oneof interface {\n\tisParameterOrReference_Oneof()\n}\n\ntype ParameterOrReference_Parameter struct {\n\tParameter *Parameter `protobuf:\"bytes,1,opt,name=parameter,proto3,oneof\"`\n}\n\ntype ParameterOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*ParameterOrReference_Parameter) isParameterOrReference_Oneof() {}\n\nfunc (*ParameterOrReference_Reference) isParameterOrReference_Oneof() {}\n\ntype ParametersOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedParameterOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *ParametersOrReferences) Reset() {\n\t*x = ParametersOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[51]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ParametersOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ParametersOrReferences) ProtoMessage() {}\n\nfunc (x *ParametersOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[51]\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 ParametersOrReferences.ProtoReflect.Descriptor instead.\nfunc (*ParametersOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{51}\n}\n\nfunc (x *ParametersOrReferences) GetAdditionalProperties() []*NamedParameterOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.\ntype PathItem struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tXRef                   string                  `protobuf:\"bytes,1,opt,name=_ref,json=Ref,proto3\" json:\"_ref,omitempty\"`\n\tSummary                string                  `protobuf:\"bytes,2,opt,name=summary,proto3\" json:\"summary,omitempty\"`\n\tDescription            string                  `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tGet                    *Operation              `protobuf:\"bytes,4,opt,name=get,proto3\" json:\"get,omitempty\"`\n\tPut                    *Operation              `protobuf:\"bytes,5,opt,name=put,proto3\" json:\"put,omitempty\"`\n\tPost                   *Operation              `protobuf:\"bytes,6,opt,name=post,proto3\" json:\"post,omitempty\"`\n\tDelete                 *Operation              `protobuf:\"bytes,7,opt,name=delete,proto3\" json:\"delete,omitempty\"`\n\tOptions                *Operation              `protobuf:\"bytes,8,opt,name=options,proto3\" json:\"options,omitempty\"`\n\tHead                   *Operation              `protobuf:\"bytes,9,opt,name=head,proto3\" json:\"head,omitempty\"`\n\tPatch                  *Operation              `protobuf:\"bytes,10,opt,name=patch,proto3\" json:\"patch,omitempty\"`\n\tTrace                  *Operation              `protobuf:\"bytes,11,opt,name=trace,proto3\" json:\"trace,omitempty\"`\n\tServers                []*Server               `protobuf:\"bytes,12,rep,name=servers,proto3\" json:\"servers,omitempty\"`\n\tParameters             []*ParameterOrReference `protobuf:\"bytes,13,rep,name=parameters,proto3\" json:\"parameters,omitempty\"`\n\tSpecificationExtension []*NamedAny             `protobuf:\"bytes,14,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *PathItem) Reset() {\n\t*x = PathItem{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[52]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *PathItem) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*PathItem) ProtoMessage() {}\n\nfunc (x *PathItem) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[52]\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 PathItem.ProtoReflect.Descriptor instead.\nfunc (*PathItem) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{52}\n}\n\nfunc (x *PathItem) GetXRef() string {\n\tif x != nil {\n\t\treturn x.XRef\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathItem) GetSummary() string {\n\tif x != nil {\n\t\treturn x.Summary\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathItem) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *PathItem) GetGet() *Operation {\n\tif x != nil {\n\t\treturn x.Get\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetPut() *Operation {\n\tif x != nil {\n\t\treturn x.Put\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetPost() *Operation {\n\tif x != nil {\n\t\treturn x.Post\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetDelete() *Operation {\n\tif x != nil {\n\t\treturn x.Delete\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetOptions() *Operation {\n\tif x != nil {\n\t\treturn x.Options\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetHead() *Operation {\n\tif x != nil {\n\t\treturn x.Head\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetPatch() *Operation {\n\tif x != nil {\n\t\treturn x.Patch\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetTrace() *Operation {\n\tif x != nil {\n\t\treturn x.Trace\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetServers() []*Server {\n\tif x != nil {\n\t\treturn x.Servers\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetParameters() []*ParameterOrReference {\n\tif x != nil {\n\t\treturn x.Parameters\n\t}\n\treturn nil\n}\n\nfunc (x *PathItem) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL.  The Paths MAY be empty, due to ACL constraints.\ntype Paths struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tPath                   []*NamedPathItem `protobuf:\"bytes,1,rep,name=path,proto3\" json:\"path,omitempty\"`\n\tSpecificationExtension []*NamedAny      `protobuf:\"bytes,2,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Paths) Reset() {\n\t*x = Paths{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[53]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Paths) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Paths) ProtoMessage() {}\n\nfunc (x *Paths) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[53]\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 Paths.ProtoReflect.Descriptor instead.\nfunc (*Paths) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{53}\n}\n\nfunc (x *Paths) GetPath() []*NamedPathItem {\n\tif x != nil {\n\t\treturn x.Path\n\t}\n\treturn nil\n}\n\nfunc (x *Paths) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype Properties struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedSchemaOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Properties) Reset() {\n\t*x = Properties{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[54]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Properties) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Properties) ProtoMessage() {}\n\nfunc (x *Properties) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[54]\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 Properties.ProtoReflect.Descriptor instead.\nfunc (*Properties) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{54}\n}\n\nfunc (x *Properties) GetAdditionalProperties() []*NamedSchemaOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// A simple object to allow referencing other components in the specification, internally and externally.  The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules.   For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.\ntype Reference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tXRef        string `protobuf:\"bytes,1,opt,name=_ref,json=Ref,proto3\" json:\"_ref,omitempty\"`\n\tSummary     string `protobuf:\"bytes,2,opt,name=summary,proto3\" json:\"summary,omitempty\"`\n\tDescription string `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n}\n\nfunc (x *Reference) Reset() {\n\t*x = Reference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[55]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Reference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Reference) ProtoMessage() {}\n\nfunc (x *Reference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[55]\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 Reference.ProtoReflect.Descriptor instead.\nfunc (*Reference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{55}\n}\n\nfunc (x *Reference) GetXRef() string {\n\tif x != nil {\n\t\treturn x.XRef\n\t}\n\treturn \"\"\n}\n\nfunc (x *Reference) GetSummary() string {\n\tif x != nil {\n\t\treturn x.Summary\n\t}\n\treturn \"\"\n}\n\nfunc (x *Reference) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\ntype RequestBodiesOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedRequestBodyOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *RequestBodiesOrReferences) Reset() {\n\t*x = RequestBodiesOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[56]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *RequestBodiesOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RequestBodiesOrReferences) ProtoMessage() {}\n\nfunc (x *RequestBodiesOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[56]\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 RequestBodiesOrReferences.ProtoReflect.Descriptor instead.\nfunc (*RequestBodiesOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{56}\n}\n\nfunc (x *RequestBodiesOrReferences) GetAdditionalProperties() []*NamedRequestBodyOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Describes a single request body.\ntype RequestBody struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tDescription            string      `protobuf:\"bytes,1,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tContent                *MediaTypes `protobuf:\"bytes,2,opt,name=content,proto3\" json:\"content,omitempty\"`\n\tRequired               bool        `protobuf:\"varint,3,opt,name=required,proto3\" json:\"required,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,4,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *RequestBody) Reset() {\n\t*x = RequestBody{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[57]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *RequestBody) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RequestBody) ProtoMessage() {}\n\nfunc (x *RequestBody) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[57]\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 RequestBody.ProtoReflect.Descriptor instead.\nfunc (*RequestBody) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{57}\n}\n\nfunc (x *RequestBody) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *RequestBody) GetContent() *MediaTypes {\n\tif x != nil {\n\t\treturn x.Content\n\t}\n\treturn nil\n}\n\nfunc (x *RequestBody) GetRequired() bool {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn false\n}\n\nfunc (x *RequestBody) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype RequestBodyOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*RequestBodyOrReference_RequestBody\n\t//\t*RequestBodyOrReference_Reference\n\tOneof isRequestBodyOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *RequestBodyOrReference) Reset() {\n\t*x = RequestBodyOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[58]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *RequestBodyOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*RequestBodyOrReference) ProtoMessage() {}\n\nfunc (x *RequestBodyOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[58]\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 RequestBodyOrReference.ProtoReflect.Descriptor instead.\nfunc (*RequestBodyOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{58}\n}\n\nfunc (m *RequestBodyOrReference) GetOneof() isRequestBodyOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *RequestBodyOrReference) GetRequestBody() *RequestBody {\n\tif x, ok := x.GetOneof().(*RequestBodyOrReference_RequestBody); ok {\n\t\treturn x.RequestBody\n\t}\n\treturn nil\n}\n\nfunc (x *RequestBodyOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*RequestBodyOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isRequestBodyOrReference_Oneof interface {\n\tisRequestBodyOrReference_Oneof()\n}\n\ntype RequestBodyOrReference_RequestBody struct {\n\tRequestBody *RequestBody `protobuf:\"bytes,1,opt,name=request_body,json=requestBody,proto3,oneof\"`\n}\n\ntype RequestBodyOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*RequestBodyOrReference_RequestBody) isRequestBodyOrReference_Oneof() {}\n\nfunc (*RequestBodyOrReference_Reference) isRequestBodyOrReference_Oneof() {}\n\n// Describes a single response from an API Operation, including design-time, static  `links` to operations based on the response.\ntype Response struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tDescription            string               `protobuf:\"bytes,1,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tHeaders                *HeadersOrReferences `protobuf:\"bytes,2,opt,name=headers,proto3\" json:\"headers,omitempty\"`\n\tContent                *MediaTypes          `protobuf:\"bytes,3,opt,name=content,proto3\" json:\"content,omitempty\"`\n\tLinks                  *LinksOrReferences   `protobuf:\"bytes,4,opt,name=links,proto3\" json:\"links,omitempty\"`\n\tSpecificationExtension []*NamedAny          `protobuf:\"bytes,5,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Response) Reset() {\n\t*x = Response{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[59]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Response) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Response) ProtoMessage() {}\n\nfunc (x *Response) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[59]\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 Response.ProtoReflect.Descriptor instead.\nfunc (*Response) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{59}\n}\n\nfunc (x *Response) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Response) GetHeaders() *HeadersOrReferences {\n\tif x != nil {\n\t\treturn x.Headers\n\t}\n\treturn nil\n}\n\nfunc (x *Response) GetContent() *MediaTypes {\n\tif x != nil {\n\t\treturn x.Content\n\t}\n\treturn nil\n}\n\nfunc (x *Response) GetLinks() *LinksOrReferences {\n\tif x != nil {\n\t\treturn x.Links\n\t}\n\treturn nil\n}\n\nfunc (x *Response) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype ResponseOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*ResponseOrReference_Response\n\t//\t*ResponseOrReference_Reference\n\tOneof isResponseOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *ResponseOrReference) Reset() {\n\t*x = ResponseOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[60]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ResponseOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ResponseOrReference) ProtoMessage() {}\n\nfunc (x *ResponseOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[60]\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 ResponseOrReference.ProtoReflect.Descriptor instead.\nfunc (*ResponseOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{60}\n}\n\nfunc (m *ResponseOrReference) GetOneof() isResponseOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *ResponseOrReference) GetResponse() *Response {\n\tif x, ok := x.GetOneof().(*ResponseOrReference_Response); ok {\n\t\treturn x.Response\n\t}\n\treturn nil\n}\n\nfunc (x *ResponseOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*ResponseOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isResponseOrReference_Oneof interface {\n\tisResponseOrReference_Oneof()\n}\n\ntype ResponseOrReference_Response struct {\n\tResponse *Response `protobuf:\"bytes,1,opt,name=response,proto3,oneof\"`\n}\n\ntype ResponseOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*ResponseOrReference_Response) isResponseOrReference_Oneof() {}\n\nfunc (*ResponseOrReference_Reference) isResponseOrReference_Oneof() {}\n\n// A container for the expected responses of an operation. The container maps a HTTP response code to the expected response.  The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors.  The `default` MAY be used as a default response object for all HTTP codes  that are not covered individually by the specification.  The `Responses Object` MUST contain at least one response code, and it  SHOULD be the response for a successful operation call.\ntype Responses struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tDefault                *ResponseOrReference        `protobuf:\"bytes,1,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tResponseOrReference    []*NamedResponseOrReference `protobuf:\"bytes,2,rep,name=response_or_reference,json=responseOrReference,proto3\" json:\"response_or_reference,omitempty\"`\n\tSpecificationExtension []*NamedAny                 `protobuf:\"bytes,3,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Responses) Reset() {\n\t*x = Responses{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[61]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Responses) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Responses) ProtoMessage() {}\n\nfunc (x *Responses) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[61]\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 Responses.ProtoReflect.Descriptor instead.\nfunc (*Responses) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{61}\n}\n\nfunc (x *Responses) GetDefault() *ResponseOrReference {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *Responses) GetResponseOrReference() []*NamedResponseOrReference {\n\tif x != nil {\n\t\treturn x.ResponseOrReference\n\t}\n\treturn nil\n}\n\nfunc (x *Responses) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype ResponsesOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedResponseOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *ResponsesOrReferences) Reset() {\n\t*x = ResponsesOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[62]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ResponsesOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ResponsesOrReferences) ProtoMessage() {}\n\nfunc (x *ResponsesOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[62]\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 ResponsesOrReferences.ProtoReflect.Descriptor instead.\nfunc (*ResponsesOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{62}\n}\n\nfunc (x *ResponsesOrReferences) GetAdditionalProperties() []*NamedResponseOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00.  For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.\ntype Schema struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tNullable               bool                      `protobuf:\"varint,1,opt,name=nullable,proto3\" json:\"nullable,omitempty\"`\n\tDiscriminator          *Discriminator            `protobuf:\"bytes,2,opt,name=discriminator,proto3\" json:\"discriminator,omitempty\"`\n\tReadOnly               bool                      `protobuf:\"varint,3,opt,name=read_only,json=readOnly,proto3\" json:\"read_only,omitempty\"`\n\tWriteOnly              bool                      `protobuf:\"varint,4,opt,name=write_only,json=writeOnly,proto3\" json:\"write_only,omitempty\"`\n\tXml                    *Xml                      `protobuf:\"bytes,5,opt,name=xml,proto3\" json:\"xml,omitempty\"`\n\tExternalDocs           *ExternalDocs             `protobuf:\"bytes,6,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tExample                *Any                      `protobuf:\"bytes,7,opt,name=example,proto3\" json:\"example,omitempty\"`\n\tDeprecated             bool                      `protobuf:\"varint,8,opt,name=deprecated,proto3\" json:\"deprecated,omitempty\"`\n\tTitle                  string                    `protobuf:\"bytes,9,opt,name=title,proto3\" json:\"title,omitempty\"`\n\tMultipleOf             float64                   `protobuf:\"fixed64,10,opt,name=multiple_of,json=multipleOf,proto3\" json:\"multiple_of,omitempty\"`\n\tMaximum                float64                   `protobuf:\"fixed64,11,opt,name=maximum,proto3\" json:\"maximum,omitempty\"`\n\tExclusiveMaximum       bool                      `protobuf:\"varint,12,opt,name=exclusive_maximum,json=exclusiveMaximum,proto3\" json:\"exclusive_maximum,omitempty\"`\n\tMinimum                float64                   `protobuf:\"fixed64,13,opt,name=minimum,proto3\" json:\"minimum,omitempty\"`\n\tExclusiveMinimum       bool                      `protobuf:\"varint,14,opt,name=exclusive_minimum,json=exclusiveMinimum,proto3\" json:\"exclusive_minimum,omitempty\"`\n\tMaxLength              int64                     `protobuf:\"varint,15,opt,name=max_length,json=maxLength,proto3\" json:\"max_length,omitempty\"`\n\tMinLength              int64                     `protobuf:\"varint,16,opt,name=min_length,json=minLength,proto3\" json:\"min_length,omitempty\"`\n\tPattern                string                    `protobuf:\"bytes,17,opt,name=pattern,proto3\" json:\"pattern,omitempty\"`\n\tMaxItems               int64                     `protobuf:\"varint,18,opt,name=max_items,json=maxItems,proto3\" json:\"max_items,omitempty\"`\n\tMinItems               int64                     `protobuf:\"varint,19,opt,name=min_items,json=minItems,proto3\" json:\"min_items,omitempty\"`\n\tUniqueItems            bool                      `protobuf:\"varint,20,opt,name=unique_items,json=uniqueItems,proto3\" json:\"unique_items,omitempty\"`\n\tMaxProperties          int64                     `protobuf:\"varint,21,opt,name=max_properties,json=maxProperties,proto3\" json:\"max_properties,omitempty\"`\n\tMinProperties          int64                     `protobuf:\"varint,22,opt,name=min_properties,json=minProperties,proto3\" json:\"min_properties,omitempty\"`\n\tRequired               []string                  `protobuf:\"bytes,23,rep,name=required,proto3\" json:\"required,omitempty\"`\n\tEnum                   []*Any                    `protobuf:\"bytes,24,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tType                   string                    `protobuf:\"bytes,25,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tAllOf                  []*SchemaOrReference      `protobuf:\"bytes,26,rep,name=all_of,json=allOf,proto3\" json:\"all_of,omitempty\"`\n\tOneOf                  []*SchemaOrReference      `protobuf:\"bytes,27,rep,name=one_of,json=oneOf,proto3\" json:\"one_of,omitempty\"`\n\tAnyOf                  []*SchemaOrReference      `protobuf:\"bytes,28,rep,name=any_of,json=anyOf,proto3\" json:\"any_of,omitempty\"`\n\tNot                    *Schema                   `protobuf:\"bytes,29,opt,name=not,proto3\" json:\"not,omitempty\"`\n\tItems                  *ItemsItem                `protobuf:\"bytes,30,opt,name=items,proto3\" json:\"items,omitempty\"`\n\tProperties             *Properties               `protobuf:\"bytes,31,opt,name=properties,proto3\" json:\"properties,omitempty\"`\n\tAdditionalProperties   *AdditionalPropertiesItem `protobuf:\"bytes,32,opt,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n\tDefault                *DefaultType              `protobuf:\"bytes,33,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tDescription            string                    `protobuf:\"bytes,34,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tFormat                 string                    `protobuf:\"bytes,35,opt,name=format,proto3\" json:\"format,omitempty\"`\n\tSpecificationExtension []*NamedAny               `protobuf:\"bytes,36,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Schema) Reset() {\n\t*x = Schema{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[63]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Schema) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Schema) ProtoMessage() {}\n\nfunc (x *Schema) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[63]\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 Schema.ProtoReflect.Descriptor instead.\nfunc (*Schema) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{63}\n}\n\nfunc (x *Schema) GetNullable() bool {\n\tif x != nil {\n\t\treturn x.Nullable\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetDiscriminator() *Discriminator {\n\tif x != nil {\n\t\treturn x.Discriminator\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetReadOnly() bool {\n\tif x != nil {\n\t\treturn x.ReadOnly\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetWriteOnly() bool {\n\tif x != nil {\n\t\treturn x.WriteOnly\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetXml() *Xml {\n\tif x != nil {\n\t\treturn x.Xml\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetExample() *Any {\n\tif x != nil {\n\t\treturn x.Example\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetDeprecated() bool {\n\tif x != nil {\n\t\treturn x.Deprecated\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetTitle() string {\n\tif x != nil {\n\t\treturn x.Title\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetMultipleOf() float64 {\n\tif x != nil {\n\t\treturn x.MultipleOf\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMaximum() float64 {\n\tif x != nil {\n\t\treturn x.Maximum\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetExclusiveMaximum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMaximum\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetMinimum() float64 {\n\tif x != nil {\n\t\treturn x.Minimum\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetExclusiveMinimum() bool {\n\tif x != nil {\n\t\treturn x.ExclusiveMinimum\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetMaxLength() int64 {\n\tif x != nil {\n\t\treturn x.MaxLength\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMinLength() int64 {\n\tif x != nil {\n\t\treturn x.MinLength\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetPattern() string {\n\tif x != nil {\n\t\treturn x.Pattern\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetMaxItems() int64 {\n\tif x != nil {\n\t\treturn x.MaxItems\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMinItems() int64 {\n\tif x != nil {\n\t\treturn x.MinItems\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetUniqueItems() bool {\n\tif x != nil {\n\t\treturn x.UniqueItems\n\t}\n\treturn false\n}\n\nfunc (x *Schema) GetMaxProperties() int64 {\n\tif x != nil {\n\t\treturn x.MaxProperties\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetMinProperties() int64 {\n\tif x != nil {\n\t\treturn x.MinProperties\n\t}\n\treturn 0\n}\n\nfunc (x *Schema) GetRequired() []string {\n\tif x != nil {\n\t\treturn x.Required\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetEnum() []*Any {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetAllOf() []*SchemaOrReference {\n\tif x != nil {\n\t\treturn x.AllOf\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetOneOf() []*SchemaOrReference {\n\tif x != nil {\n\t\treturn x.OneOf\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetAnyOf() []*SchemaOrReference {\n\tif x != nil {\n\t\treturn x.AnyOf\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetNot() *Schema {\n\tif x != nil {\n\t\treturn x.Not\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetItems() *ItemsItem {\n\tif x != nil {\n\t\treturn x.Items\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetProperties() *Properties {\n\tif x != nil {\n\t\treturn x.Properties\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetAdditionalProperties() *AdditionalPropertiesItem {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetDefault() *DefaultType {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn nil\n}\n\nfunc (x *Schema) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetFormat() string {\n\tif x != nil {\n\t\treturn x.Format\n\t}\n\treturn \"\"\n}\n\nfunc (x *Schema) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype SchemaOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*SchemaOrReference_Schema\n\t//\t*SchemaOrReference_Reference\n\tOneof isSchemaOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *SchemaOrReference) Reset() {\n\t*x = SchemaOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[64]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SchemaOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SchemaOrReference) ProtoMessage() {}\n\nfunc (x *SchemaOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[64]\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 SchemaOrReference.ProtoReflect.Descriptor instead.\nfunc (*SchemaOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{64}\n}\n\nfunc (m *SchemaOrReference) GetOneof() isSchemaOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *SchemaOrReference) GetSchema() *Schema {\n\tif x, ok := x.GetOneof().(*SchemaOrReference_Schema); ok {\n\t\treturn x.Schema\n\t}\n\treturn nil\n}\n\nfunc (x *SchemaOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*SchemaOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isSchemaOrReference_Oneof interface {\n\tisSchemaOrReference_Oneof()\n}\n\ntype SchemaOrReference_Schema struct {\n\tSchema *Schema `protobuf:\"bytes,1,opt,name=schema,proto3,oneof\"`\n}\n\ntype SchemaOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*SchemaOrReference_Schema) isSchemaOrReference_Oneof() {}\n\nfunc (*SchemaOrReference_Reference) isSchemaOrReference_Oneof() {}\n\ntype SchemasOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedSchemaOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *SchemasOrReferences) Reset() {\n\t*x = SchemasOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[65]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SchemasOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SchemasOrReferences) ProtoMessage() {}\n\nfunc (x *SchemasOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[65]\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 SchemasOrReferences.ProtoReflect.Descriptor instead.\nfunc (*SchemasOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{65}\n}\n\nfunc (x *SchemasOrReferences) GetAdditionalProperties() []*NamedSchemaOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object.  Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information.  When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the Security Requirement Objects in the list needs to be satisfied to authorize the request.\ntype SecurityRequirement struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedStringArray `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *SecurityRequirement) Reset() {\n\t*x = SecurityRequirement{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[66]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SecurityRequirement) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecurityRequirement) ProtoMessage() {}\n\nfunc (x *SecurityRequirement) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[66]\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 SecurityRequirement.ProtoReflect.Descriptor instead.\nfunc (*SecurityRequirement) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{66}\n}\n\nfunc (x *SecurityRequirement) GetAdditionalProperties() []*NamedStringArray {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter), mutual TLS (use of a client certificate), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect.   Please note that currently (2019) the implicit flow is about to be deprecated OAuth 2.0 Security Best Current Practice. Recommended for most use case is Authorization Code Grant flow with PKCE.\ntype SecurityScheme struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType                   string      `protobuf:\"bytes,1,opt,name=type,proto3\" json:\"type,omitempty\"`\n\tDescription            string      `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tName                   string      `protobuf:\"bytes,3,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tIn                     string      `protobuf:\"bytes,4,opt,name=in,proto3\" json:\"in,omitempty\"`\n\tScheme                 string      `protobuf:\"bytes,5,opt,name=scheme,proto3\" json:\"scheme,omitempty\"`\n\tBearerFormat           string      `protobuf:\"bytes,6,opt,name=bearer_format,json=bearerFormat,proto3\" json:\"bearer_format,omitempty\"`\n\tFlows                  *OauthFlows `protobuf:\"bytes,7,opt,name=flows,proto3\" json:\"flows,omitempty\"`\n\tOpenIdConnectUrl       string      `protobuf:\"bytes,8,opt,name=open_id_connect_url,json=openIdConnectUrl,proto3\" json:\"open_id_connect_url,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,9,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *SecurityScheme) Reset() {\n\t*x = SecurityScheme{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[67]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SecurityScheme) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecurityScheme) ProtoMessage() {}\n\nfunc (x *SecurityScheme) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[67]\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 SecurityScheme.ProtoReflect.Descriptor instead.\nfunc (*SecurityScheme) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{67}\n}\n\nfunc (x *SecurityScheme) GetType() string {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn \"\"\n}\n\nfunc (x *SecurityScheme) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *SecurityScheme) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *SecurityScheme) GetIn() string {\n\tif x != nil {\n\t\treturn x.In\n\t}\n\treturn \"\"\n}\n\nfunc (x *SecurityScheme) GetScheme() string {\n\tif x != nil {\n\t\treturn x.Scheme\n\t}\n\treturn \"\"\n}\n\nfunc (x *SecurityScheme) GetBearerFormat() string {\n\tif x != nil {\n\t\treturn x.BearerFormat\n\t}\n\treturn \"\"\n}\n\nfunc (x *SecurityScheme) GetFlows() *OauthFlows {\n\tif x != nil {\n\t\treturn x.Flows\n\t}\n\treturn nil\n}\n\nfunc (x *SecurityScheme) GetOpenIdConnectUrl() string {\n\tif x != nil {\n\t\treturn x.OpenIdConnectUrl\n\t}\n\treturn \"\"\n}\n\nfunc (x *SecurityScheme) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype SecuritySchemeOrReference struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*SecuritySchemeOrReference_SecurityScheme\n\t//\t*SecuritySchemeOrReference_Reference\n\tOneof isSecuritySchemeOrReference_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *SecuritySchemeOrReference) Reset() {\n\t*x = SecuritySchemeOrReference{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[68]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SecuritySchemeOrReference) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecuritySchemeOrReference) ProtoMessage() {}\n\nfunc (x *SecuritySchemeOrReference) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[68]\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 SecuritySchemeOrReference.ProtoReflect.Descriptor instead.\nfunc (*SecuritySchemeOrReference) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{68}\n}\n\nfunc (m *SecuritySchemeOrReference) GetOneof() isSecuritySchemeOrReference_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *SecuritySchemeOrReference) GetSecurityScheme() *SecurityScheme {\n\tif x, ok := x.GetOneof().(*SecuritySchemeOrReference_SecurityScheme); ok {\n\t\treturn x.SecurityScheme\n\t}\n\treturn nil\n}\n\nfunc (x *SecuritySchemeOrReference) GetReference() *Reference {\n\tif x, ok := x.GetOneof().(*SecuritySchemeOrReference_Reference); ok {\n\t\treturn x.Reference\n\t}\n\treturn nil\n}\n\ntype isSecuritySchemeOrReference_Oneof interface {\n\tisSecuritySchemeOrReference_Oneof()\n}\n\ntype SecuritySchemeOrReference_SecurityScheme struct {\n\tSecurityScheme *SecurityScheme `protobuf:\"bytes,1,opt,name=security_scheme,json=securityScheme,proto3,oneof\"`\n}\n\ntype SecuritySchemeOrReference_Reference struct {\n\tReference *Reference `protobuf:\"bytes,2,opt,name=reference,proto3,oneof\"`\n}\n\nfunc (*SecuritySchemeOrReference_SecurityScheme) isSecuritySchemeOrReference_Oneof() {}\n\nfunc (*SecuritySchemeOrReference_Reference) isSecuritySchemeOrReference_Oneof() {}\n\ntype SecuritySchemesOrReferences struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedSecuritySchemeOrReference `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *SecuritySchemesOrReferences) Reset() {\n\t*x = SecuritySchemesOrReferences{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[69]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SecuritySchemesOrReferences) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SecuritySchemesOrReferences) ProtoMessage() {}\n\nfunc (x *SecuritySchemesOrReferences) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[69]\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 SecuritySchemesOrReferences.ProtoReflect.Descriptor instead.\nfunc (*SecuritySchemesOrReferences) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{69}\n}\n\nfunc (x *SecuritySchemesOrReferences) GetAdditionalProperties() []*NamedSecuritySchemeOrReference {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// An object representing a Server.\ntype Server struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tUrl                    string           `protobuf:\"bytes,1,opt,name=url,proto3\" json:\"url,omitempty\"`\n\tDescription            string           `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tVariables              *ServerVariables `protobuf:\"bytes,3,opt,name=variables,proto3\" json:\"variables,omitempty\"`\n\tSpecificationExtension []*NamedAny      `protobuf:\"bytes,4,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Server) Reset() {\n\t*x = Server{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[70]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Server) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Server) ProtoMessage() {}\n\nfunc (x *Server) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[70]\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 Server.ProtoReflect.Descriptor instead.\nfunc (*Server) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{70}\n}\n\nfunc (x *Server) GetUrl() string {\n\tif x != nil {\n\t\treturn x.Url\n\t}\n\treturn \"\"\n}\n\nfunc (x *Server) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Server) GetVariables() *ServerVariables {\n\tif x != nil {\n\t\treturn x.Variables\n\t}\n\treturn nil\n}\n\nfunc (x *Server) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// An object representing a Server Variable for server URL template substitution.\ntype ServerVariable struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tEnum                   []string    `protobuf:\"bytes,1,rep,name=enum,proto3\" json:\"enum,omitempty\"`\n\tDefault                string      `protobuf:\"bytes,2,opt,name=default,proto3\" json:\"default,omitempty\"`\n\tDescription            string      `protobuf:\"bytes,3,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,4,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *ServerVariable) Reset() {\n\t*x = ServerVariable{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[71]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ServerVariable) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerVariable) ProtoMessage() {}\n\nfunc (x *ServerVariable) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[71]\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 ServerVariable.ProtoReflect.Descriptor instead.\nfunc (*ServerVariable) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{71}\n}\n\nfunc (x *ServerVariable) GetEnum() []string {\n\tif x != nil {\n\t\treturn x.Enum\n\t}\n\treturn nil\n}\n\nfunc (x *ServerVariable) GetDefault() string {\n\tif x != nil {\n\t\treturn x.Default\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerVariable) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *ServerVariable) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\ntype ServerVariables struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedServerVariable `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *ServerVariables) Reset() {\n\t*x = ServerVariables{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[72]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *ServerVariables) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*ServerVariables) ProtoMessage() {}\n\nfunc (x *ServerVariables) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[72]\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 ServerVariables.ProtoReflect.Descriptor instead.\nfunc (*ServerVariables) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{72}\n}\n\nfunc (x *ServerVariables) GetAdditionalProperties() []*NamedServerVariable {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Any property starting with x- is valid.\ntype SpecificationExtension struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\t// Types that are assignable to Oneof:\n\t//\t*SpecificationExtension_Number\n\t//\t*SpecificationExtension_Boolean\n\t//\t*SpecificationExtension_String_\n\tOneof isSpecificationExtension_Oneof `protobuf_oneof:\"oneof\"`\n}\n\nfunc (x *SpecificationExtension) Reset() {\n\t*x = SpecificationExtension{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[73]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SpecificationExtension) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SpecificationExtension) ProtoMessage() {}\n\nfunc (x *SpecificationExtension) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[73]\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 SpecificationExtension.ProtoReflect.Descriptor instead.\nfunc (*SpecificationExtension) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{73}\n}\n\nfunc (m *SpecificationExtension) GetOneof() isSpecificationExtension_Oneof {\n\tif m != nil {\n\t\treturn m.Oneof\n\t}\n\treturn nil\n}\n\nfunc (x *SpecificationExtension) GetNumber() float64 {\n\tif x, ok := x.GetOneof().(*SpecificationExtension_Number); ok {\n\t\treturn x.Number\n\t}\n\treturn 0\n}\n\nfunc (x *SpecificationExtension) GetBoolean() bool {\n\tif x, ok := x.GetOneof().(*SpecificationExtension_Boolean); ok {\n\t\treturn x.Boolean\n\t}\n\treturn false\n}\n\nfunc (x *SpecificationExtension) GetString_() string {\n\tif x, ok := x.GetOneof().(*SpecificationExtension_String_); ok {\n\t\treturn x.String_\n\t}\n\treturn \"\"\n}\n\ntype isSpecificationExtension_Oneof interface {\n\tisSpecificationExtension_Oneof()\n}\n\ntype SpecificationExtension_Number struct {\n\tNumber float64 `protobuf:\"fixed64,1,opt,name=number,proto3,oneof\"`\n}\n\ntype SpecificationExtension_Boolean struct {\n\tBoolean bool `protobuf:\"varint,2,opt,name=boolean,proto3,oneof\"`\n}\n\ntype SpecificationExtension_String_ struct {\n\tString_ string `protobuf:\"bytes,3,opt,name=string,proto3,oneof\"`\n}\n\nfunc (*SpecificationExtension_Number) isSpecificationExtension_Oneof() {}\n\nfunc (*SpecificationExtension_Boolean) isSpecificationExtension_Oneof() {}\n\nfunc (*SpecificationExtension_String_) isSpecificationExtension_Oneof() {}\n\ntype StringArray struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tValue []string `protobuf:\"bytes,1,rep,name=value,proto3\" json:\"value,omitempty\"`\n}\n\nfunc (x *StringArray) Reset() {\n\t*x = StringArray{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[74]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *StringArray) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StringArray) ProtoMessage() {}\n\nfunc (x *StringArray) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[74]\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 StringArray.ProtoReflect.Descriptor instead.\nfunc (*StringArray) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{74}\n}\n\nfunc (x *StringArray) GetValue() []string {\n\tif x != nil {\n\t\treturn x.Value\n\t}\n\treturn nil\n}\n\ntype Strings struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tAdditionalProperties []*NamedString `protobuf:\"bytes,1,rep,name=additional_properties,json=additionalProperties,proto3\" json:\"additional_properties,omitempty\"`\n}\n\nfunc (x *Strings) Reset() {\n\t*x = Strings{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[75]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Strings) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Strings) ProtoMessage() {}\n\nfunc (x *Strings) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[75]\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 Strings.ProtoReflect.Descriptor instead.\nfunc (*Strings) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{75}\n}\n\nfunc (x *Strings) GetAdditionalProperties() []*NamedString {\n\tif x != nil {\n\t\treturn x.AdditionalProperties\n\t}\n\treturn nil\n}\n\n// Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.\ntype Tag struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName                   string        `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tDescription            string        `protobuf:\"bytes,2,opt,name=description,proto3\" json:\"description,omitempty\"`\n\tExternalDocs           *ExternalDocs `protobuf:\"bytes,3,opt,name=external_docs,json=externalDocs,proto3\" json:\"external_docs,omitempty\"`\n\tSpecificationExtension []*NamedAny   `protobuf:\"bytes,4,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Tag) Reset() {\n\t*x = Tag{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[76]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Tag) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Tag) ProtoMessage() {}\n\nfunc (x *Tag) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[76]\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 Tag.ProtoReflect.Descriptor instead.\nfunc (*Tag) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{76}\n}\n\nfunc (x *Tag) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Tag) GetDescription() string {\n\tif x != nil {\n\t\treturn x.Description\n\t}\n\treturn \"\"\n}\n\nfunc (x *Tag) GetExternalDocs() *ExternalDocs {\n\tif x != nil {\n\t\treturn x.ExternalDocs\n\t}\n\treturn nil\n}\n\nfunc (x *Tag) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\n// A metadata object that allows for more fine-tuned XML model definitions.  When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.\ntype Xml struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName                   string      `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n\tNamespace              string      `protobuf:\"bytes,2,opt,name=namespace,proto3\" json:\"namespace,omitempty\"`\n\tPrefix                 string      `protobuf:\"bytes,3,opt,name=prefix,proto3\" json:\"prefix,omitempty\"`\n\tAttribute              bool        `protobuf:\"varint,4,opt,name=attribute,proto3\" json:\"attribute,omitempty\"`\n\tWrapped                bool        `protobuf:\"varint,5,opt,name=wrapped,proto3\" json:\"wrapped,omitempty\"`\n\tSpecificationExtension []*NamedAny `protobuf:\"bytes,6,rep,name=specification_extension,json=specificationExtension,proto3\" json:\"specification_extension,omitempty\"`\n}\n\nfunc (x *Xml) Reset() {\n\t*x = Xml{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[77]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Xml) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Xml) ProtoMessage() {}\n\nfunc (x *Xml) ProtoReflect() protoreflect.Message {\n\tmi := &file_openapiv3_OpenAPIv3_proto_msgTypes[77]\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 Xml.ProtoReflect.Descriptor instead.\nfunc (*Xml) Descriptor() ([]byte, []int) {\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescGZIP(), []int{77}\n}\n\nfunc (x *Xml) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\nfunc (x *Xml) GetNamespace() string {\n\tif x != nil {\n\t\treturn x.Namespace\n\t}\n\treturn \"\"\n}\n\nfunc (x *Xml) GetPrefix() string {\n\tif x != nil {\n\t\treturn x.Prefix\n\t}\n\treturn \"\"\n}\n\nfunc (x *Xml) GetAttribute() bool {\n\tif x != nil {\n\t\treturn x.Attribute\n\t}\n\treturn false\n}\n\nfunc (x *Xml) GetWrapped() bool {\n\tif x != nil {\n\t\treturn x.Wrapped\n\t}\n\treturn false\n}\n\nfunc (x *Xml) GetSpecificationExtension() []*NamedAny {\n\tif x != nil {\n\t\treturn x.SpecificationExtension\n\t}\n\treturn nil\n}\n\nvar File_openapiv3_OpenAPIv3_proto protoreflect.FileDescriptor\n\nvar file_openapiv3_OpenAPIv3_proto_rawDesc = []byte{\n\t0x0a, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x4f, 0x70, 0x65, 0x6e,\n\t0x41, 0x50, 0x49, 0x76, 0x33, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x22, 0x90, 0x01, 0x0a, 0x18, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61,\n\t0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x12,\n\t0x4f, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61,\n\t0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x11, 0x73,\n\t0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,\n\t0x12, 0x1a, 0x0a, 0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x08, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x42, 0x07, 0x0a, 0x05,\n\t0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x45, 0x0a, 0x03, 0x41, 0x6e, 0x79, 0x12, 0x2a, 0x0a, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f,\n\t0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e,\n\t0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x61, 0x6d, 0x6c,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x79, 0x61, 0x6d, 0x6c, 0x22, 0x79, 0x0a, 0x0f,\n\t0x41, 0x6e, 0x79, 0x4f, 0x72, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12,\n\t0x23, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79, 0x48, 0x00, 0x52,\n\t0x03, 0x61, 0x6e, 0x79, 0x12, 0x38, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69,\n\t0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e,\n\t0x48, 0x00, 0x52, 0x0a, 0x65, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x07,\n\t0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x88, 0x01, 0x0a, 0x08, 0x43, 0x61, 0x6c, 0x6c,\n\t0x62, 0x61, 0x63, 0x6b, 0x12, 0x2d, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03,\n\t0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x70,\n\t0x61, 0x74, 0x68, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02,\n\t0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63,\n\t0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x22, 0x89, 0x01, 0x0a, 0x13, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x4f,\n\t0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x32, 0x0a, 0x08, 0x63, 0x61,\n\t0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61,\n\t0x63, 0x6b, 0x48, 0x00, 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x35,\n\t0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52,\n\t0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65,\n\t0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x72,\n\t0x0a, 0x15, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x59, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,\n\t0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,\n\t0x6b, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x14, 0x61, 0x64,\n\t0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,\n\t0x65, 0x73, 0x22, 0xac, 0x05, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,\n\t0x73, 0x12, 0x39, 0x0a, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x73, 0x52, 0x07, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x12, 0x3f, 0x0a, 0x09,\n\t0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x21, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x73,\n\t0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x42, 0x0a,\n\t0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x50,\n\t0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,\n\t0x73, 0x12, 0x3c, 0x0a, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12,\n\t0x4c, 0x0a, 0x0e, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f, 0x64, 0x69, 0x65,\n\t0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x69,\n\t0x65, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x0d,\n\t0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x69, 0x65, 0x73, 0x12, 0x39, 0x0a,\n\t0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x48, 0x65, 0x61, 0x64,\n\t0x65, 0x72, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52,\n\t0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x52, 0x0a, 0x10, 0x73, 0x65, 0x63, 0x75,\n\t0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x4f,\n\t0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x0f, 0x73, 0x65, 0x63,\n\t0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x05,\n\t0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x4f, 0x72,\n\t0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b,\n\t0x73, 0x12, 0x3f, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x18, 0x09,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,\n\t0x6b, 0x73, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,\n\t0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69,\n\t0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x22, 0x94, 0x01, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x12, 0x0a,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,\n\t0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,\n\t0x75, 0x72, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65,\n\t0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79,\n\t0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45,\n\t0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x66, 0x0a, 0x0b, 0x44, 0x65, 0x66, 0x61,\n\t0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65,\n\t0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65,\n\t0x72, 0x12, 0x1a, 0x0a, 0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x08, 0x48, 0x00, 0x52, 0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x18, 0x0a,\n\t0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52,\n\t0x06, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66,\n\t0x22, 0xb2, 0x01, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74,\n\t0x6f, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x5f, 0x6e,\n\t0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x6d, 0x61, 0x70, 0x70, 0x69,\n\t0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x07, 0x6d,\n\t0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,\n\t0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73,\n\t0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc9, 0x03, 0x0a, 0x08, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65,\n\t0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x12, 0x24, 0x0a, 0x04,\n\t0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e,\n\t0x66, 0x6f, 0x12, 0x2c, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73,\n\t0x12, 0x27, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x11, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x61, 0x74,\n\t0x68, 0x73, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x36, 0x0a, 0x0a, 0x63, 0x6f, 0x6d,\n\t0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6f,\n\t0x6e, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,\n\t0x73, 0x12, 0x3b, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65,\n\t0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x23,\n\t0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74,\n\t0x61, 0x67, 0x73, 0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f,\n\t0x64, 0x6f, 0x63, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,\n\t0x44, 0x6f, 0x63, 0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f,\n\t0x63, 0x73, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,\n\t0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69,\n\t0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x22, 0x8e, 0x02, 0x0a, 0x08, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x21,\n\t0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,\n\t0x65, 0x12, 0x39, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x73, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x14, 0x0a, 0x05,\n\t0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x79,\n\t0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20,\n\t0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x64, 0x65, 0x12, 0x25, 0x0a, 0x0e,\n\t0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x05,\n\t0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73, 0x65, 0x72,\n\t0x76, 0x65, 0x64, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06,\n\t0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63,\n\t0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x22, 0x5b, 0x0a, 0x09, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12,\n\t0x4e, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72,\n\t0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65,\n\t0x64, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22,\n\t0xe2, 0x01, 0x0a, 0x07, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73,\n\t0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75,\n\t0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63,\n\t0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x25,\n\t0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c,\n\t0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70,\n\t0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x22, 0x85, 0x01, 0x0a, 0x12, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,\n\t0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x65,\n\t0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c,\n\t0x65, 0x48, 0x00, 0x52, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x09,\n\t0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x70, 0x0a, 0x14,\n\t0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x73, 0x12, 0x58, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x72, 0x52,\n\t0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69,\n\t0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x57,\n\t0x0a, 0x0a, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x49, 0x0a, 0x15,\n\t0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e,\n\t0x79, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f,\n\t0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x0c, 0x45, 0x78, 0x74, 0x65,\n\t0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,\n\t0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,\n\t0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72,\n\t0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x4d, 0x0a, 0x17,\n\t0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,\n\t0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8a, 0x04, 0x0a, 0x06,\n\t0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,\n\t0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,\n\t0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75,\n\t0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75,\n\t0x69, 0x72, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74,\n\t0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63,\n\t0x61, 0x74, 0x65, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x65, 0x6d,\n\t0x70, 0x74, 0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,\n\t0x0f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65,\n\t0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x05, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x64,\n\t0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x64, 0x65,\n\t0x12, 0x25, 0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76,\n\t0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x52,\n\t0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x29,\n\t0x0a, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79,\n\t0x52, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x65, 0x78, 0x61,\n\t0x6d, 0x70, 0x6c, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,\n\t0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x08, 0x65,\n\t0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65,\n\t0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73,\n\t0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65,\n\t0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79,\n\t0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45,\n\t0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x81, 0x01, 0x0a, 0x11, 0x48, 0x65, 0x61,\n\t0x64, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x2c,\n\t0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x48, 0x65, 0x61, 0x64,\n\t0x65, 0x72, 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x09,\n\t0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x6e, 0x0a, 0x13,\n\t0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61,\n\t0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,\n\t0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xc9, 0x02, 0x0a,\n\t0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64,\n\t0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a,\n\t0x10, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,\n\t0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x4f, 0x66,\n\t0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x61,\n\t0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x52, 0x07, 0x63,\n\t0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73,\n\t0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x52, 0x07, 0x6c, 0x69,\n\t0x63, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,\n\t0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,\n\t0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,\n\t0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18,\n\t0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5a, 0x0a, 0x09, 0x49, 0x74, 0x65, 0x6d,\n\t0x73, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x4d, 0x0a, 0x13, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f,\n\t0x6f, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x03,\n\t0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x52, 0x11, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x22, 0x7e, 0x0a, 0x07, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x12,\n\t0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70,\n\t0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x22, 0xe8, 0x02, 0x0a, 0x04, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x23, 0x0a,\n\t0x0d, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,\n\t0x65, 0x66, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,\n\t0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,\n\t0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,\n\t0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79, 0x4f, 0x72, 0x45, 0x78, 0x70, 0x72,\n\t0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65,\n\t0x72, 0x73, 0x12, 0x3e, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f,\n\t0x64, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79, 0x4f, 0x72, 0x45, 0x78, 0x70, 0x72, 0x65,\n\t0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f,\n\t0x64, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x06,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,\n\t0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,\n\t0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22,\n\t0x79, 0x0a, 0x0f, 0x4c, 0x69, 0x6e, 0x6b, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x10, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69,\n\t0x6e, 0x6b, 0x48, 0x00, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x65,\n\t0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x6a, 0x0a, 0x11, 0x4c, 0x69,\n\t0x6e, 0x6b, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12,\n\t0x55, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72,\n\t0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65,\n\t0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,\n\t0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70,\n\t0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xad, 0x02, 0x0a, 0x09, 0x4d, 0x65, 0x64, 0x69, 0x61,\n\t0x54, 0x79, 0x70, 0x65, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x29, 0x0a, 0x07, 0x65,\n\t0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x65,\n\t0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,\n\t0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x4f, 0x72,\n\t0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x08, 0x65, 0x78, 0x61, 0x6d,\n\t0x70, 0x6c, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x08, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67,\n\t0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x65,\n\t0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69,\n\t0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16,\n\t0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74,\n\t0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x5d, 0x0a, 0x0a, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54,\n\t0x79, 0x70, 0x65, 0x73, 0x12, 0x4f, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52,\n\t0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x45, 0x0a, 0x08, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e,\n\t0x79, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x65, 0x0a, 0x18,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x4f, 0x72, 0x52,\n\t0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,\n\t0x6b, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61,\n\t0x6c, 0x75, 0x65, 0x22, 0x4f, 0x0a, 0x0d, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x45, 0x6e, 0x63, 0x6f,\n\t0x64, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x76,\n\t0x61, 0x6c, 0x75, 0x65, 0x22, 0x63, 0x0a, 0x17, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x45, 0x78, 0x61,\n\t0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12,\n\t0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x61, 0x0a, 0x16, 0x4e, 0x61, 0x6d,\n\t0x65, 0x64, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65,\n\t0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x5d, 0x0a, 0x14,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,\n\t0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4c, 0x69, 0x6e, 0x6b, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x51, 0x0a, 0x0e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,\n\t0x65, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65,\n\t0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x67,\n\t0x0a, 0x19, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,\n\t0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,\n\t0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,\n\t0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x61, 0x72, 0x61,\n\t0x6d, 0x65, 0x74, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,\n\t0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4f, 0x0a, 0x0d, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x50, 0x61, 0x74, 0x68, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x49, 0x74, 0x65,\n\t0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x6b, 0x0a, 0x1b, 0x4e, 0x61, 0x6d, 0x65,\n\t0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x4f, 0x72, 0x52, 0x65,\n\t0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x38, 0x0a, 0x05, 0x76,\n\t0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42,\n\t0x6f, 0x64, 0x79, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05,\n\t0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x65, 0x0a, 0x18, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x52, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65,\n\t0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x61, 0x0a, 0x16,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61,\n\t0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52,\n\t0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,\n\t0x71, 0x0a, 0x1e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,\n\t0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65,\n\t0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c,\n\t0x75, 0x65, 0x22, 0x5b, 0x0a, 0x13, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65,\n\t0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,\n\t0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x30, 0x0a,\n\t0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,\n\t0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,\n\t0x37, 0x0a, 0x0b, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x12,\n\t0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x55, 0x0a, 0x10, 0x4e, 0x61, 0x6d, 0x65,\n\t0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x12, 0x0a, 0x04,\n\t0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,\n\t0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x17, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x74, 0x72,\n\t0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22,\n\t0xf2, 0x01, 0x0a, 0x09, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x46, 0x6c, 0x6f, 0x77, 0x12, 0x2b, 0x0a,\n\t0x11, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x75,\n\t0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,\n\t0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f,\n\t0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74,\n\t0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x72, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x66, 0x72, 0x65,\n\t0x73, 0x68, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65,\n\t0x66, 0x72, 0x65, 0x73, 0x68, 0x55, 0x72, 0x6c, 0x12, 0x2b, 0x0a, 0x06, 0x73, 0x63, 0x6f, 0x70,\n\t0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x06, 0x73,\n\t0x63, 0x6f, 0x70, 0x65, 0x73, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70,\n\t0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x22, 0xcd, 0x02, 0x0a, 0x0a, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x46, 0x6c,\n\t0x6f, 0x77, 0x73, 0x12, 0x31, 0x0a, 0x08, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x08, 0x69, 0x6d,\n\t0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,\n\t0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x46, 0x6c, 0x6f, 0x77, 0x52,\n\t0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x44, 0x0a, 0x12, 0x63, 0x6c, 0x69,\n\t0x65, 0x6e, 0x74, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18,\n\t0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x46, 0x6c, 0x6f, 0x77, 0x52, 0x11, 0x63, 0x6c,\n\t0x69, 0x65, 0x6e, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12,\n\t0x44, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,\n\t0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x46, 0x6c,\n\t0x6f, 0x77, 0x52, 0x11, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,\n\t0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e,\n\t0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70,\n\t0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e,\n\t0x73, 0x69, 0x6f, 0x6e, 0x22, 0x53, 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x49,\n\t0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f,\n\t0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x41, 0x6e, 0x79, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x96, 0x05, 0x0a, 0x09, 0x4f, 0x70,\n\t0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18,\n\t0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73,\n\t0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75,\n\t0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63,\n\t0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72,\n\t0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x74, 0x65,\n\t0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e,\n\t0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74,\n\t0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x70,\n\t0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0a, 0x70, 0x61, 0x72,\n\t0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x65, 0x74, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52,\n\t0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x45, 0x0a, 0x0c, 0x72,\n\t0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52,\n\t0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65,\n\t0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f,\n\t0x64, 0x79, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18,\n\t0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x62,\n\t0x61, 0x63, 0x6b, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b,\n\t0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x09, 0x63,\n\t0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72,\n\t0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65,\n\t0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x3b, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x75,\n\t0x72, 0x69, 0x74, 0x79, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,\n\t0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x73, 0x65, 0x63,\n\t0x75, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2c, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73,\n\t0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76,\n\t0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0d,\n\t0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76,\n\t0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63,\n\t0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x22, 0xb1, 0x04, 0x0a, 0x09, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,\n\t0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,\n\t0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x02, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,\n\t0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,\n\t0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,\n\t0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72,\n\t0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64,\n\t0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74,\n\t0x65, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x65, 0x6d, 0x70, 0x74,\n\t0x79, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x61,\n\t0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14,\n\t0x0a, 0x05, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73,\n\t0x74, 0x79, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x64, 0x65, 0x18,\n\t0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x6c, 0x6f, 0x64, 0x65, 0x12, 0x25,\n\t0x0a, 0x0e, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64,\n\t0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x73,\n\t0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18,\n\t0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x29, 0x0a, 0x07,\n\t0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07,\n\t0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x3c, 0x0a, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70,\n\t0x6c, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x4f,\n\t0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x08, 0x65, 0x78, 0x61,\n\t0x6d, 0x70, 0x6c, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,\n\t0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x07,\n\t0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69,\n\t0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16,\n\t0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74,\n\t0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x8d, 0x01, 0x0a, 0x14, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x65, 0x74, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12,\n\t0x35, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x48, 0x00, 0x52, 0x09, 0x70, 0x61, 0x72,\n\t0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,\n\t0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a,\n\t0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x74, 0x0a, 0x16, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,\n\t0x74, 0x65, 0x72, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73,\n\t0x12, 0x5a, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32,\n\t0x25, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d,\n\t0x65, 0x64, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xfa, 0x04, 0x0a,\n\t0x08, 0x50, 0x61, 0x74, 0x68, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x11, 0x0a, 0x04, 0x5f, 0x72, 0x65,\n\t0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x18, 0x0a, 0x07,\n\t0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73,\n\t0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,\n\t0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73,\n\t0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x03, 0x67, 0x65, 0x74, 0x18,\n\t0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x67, 0x65,\n\t0x74, 0x12, 0x27, 0x0a, 0x03, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, 0x75, 0x74, 0x12, 0x29, 0x0a, 0x04, 0x70, 0x6f,\n\t0x73, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61,\n\t0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,\n\t0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x18,\n\t0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x64, 0x65,\n\t0x6c, 0x65, 0x74, 0x65, 0x12, 0x2f, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18,\n\t0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6f, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x04, 0x68, 0x65, 0x61, 0x64, 0x18, 0x09, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x04, 0x68, 0x65, 0x61, 0x64,\n\t0x12, 0x2b, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65,\n\t0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2b, 0x0a,\n\t0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74,\n\t0x69, 0x6f, 0x6e, 0x52, 0x05, 0x74, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x07, 0x73, 0x65,\n\t0x72, 0x76, 0x65, 0x72, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52,\n\t0x07, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x40, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61,\n\t0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65,\n\t0x74, 0x65, 0x72, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a,\n\t0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70,\n\t0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e,\n\t0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,\n\t0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x85, 0x01, 0x0a, 0x05, 0x50, 0x61,\n\t0x74, 0x68, 0x73, 0x12, 0x2d, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x50, 0x61, 0x74, 0x68, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x04, 0x70, 0x61,\n\t0x74, 0x68, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,\n\t0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69,\n\t0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x22, 0x65, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12,\n\t0x57, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72,\n\t0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65,\n\t0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72,\n\t0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x5a, 0x0a, 0x09, 0x52, 0x65, 0x66, 0x65,\n\t0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x11, 0x0a, 0x04, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x03, 0x52, 0x65, 0x66, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d,\n\t0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61,\n\t0x72, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x22, 0x79, 0x0a, 0x19, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42,\n\t0x6f, 0x64, 0x69, 0x65, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,\n\t0x73, 0x12, 0x5c, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f,\n\t0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x27, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x4f, 0x72,\n\t0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22,\n\t0xcc, 0x01, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x12,\n\t0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74,\n\t0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18,\n\t0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12,\n\t0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,\n\t0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x96,\n\t0x01, 0x0a, 0x16, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x4f, 0x72,\n\t0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x72, 0x65, 0x71,\n\t0x75, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32,\n\t0x17, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x71,\n\t0x75, 0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x48, 0x00, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75,\n\t0x65, 0x73, 0x74, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72,\n\t0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07,\n\t0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x9d, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70,\n\t0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,\n\t0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,\n\t0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,\n\t0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x4f, 0x72, 0x52, 0x65,\n\t0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,\n\t0x73, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74,\n\t0x65, 0x6e, 0x74, 0x12, 0x33, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x4c, 0x69, 0x6e, 0x6b, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,\n\t0x73, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63,\n\t0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,\n\t0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e,\n\t0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52,\n\t0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x89, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x73, 0x70,\n\t0x6f, 0x6e, 0x73, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12,\n\t0x32, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52,\n\t0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f,\n\t0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52,\n\t0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e,\n\t0x65, 0x6f, 0x66, 0x22, 0xef, 0x01, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,\n\t0x73, 0x12, 0x39, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x58, 0x0a, 0x15,\n\t0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65,\n\t0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x52, 0x65,\n\t0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x52, 0x13, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,\n\t0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73,\n\t0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x72, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,\n\t0x65, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x59,\n\t0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f,\n\t0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65,\n\t0x6e, 0x63, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xaf, 0x0b, 0x0a, 0x06, 0x53, 0x63,\n\t0x68, 0x65, 0x6d, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x75, 0x6c, 0x6c, 0x61, 0x62, 0x6c, 0x65,\n\t0x12, 0x3f, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f,\n\t0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74,\n\t0x6f, 0x72, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x72, 0x69, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x6f,\n\t0x72, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x03,\n\t0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1d,\n\t0x0a, 0x0a, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x04, 0x20, 0x01,\n\t0x28, 0x08, 0x52, 0x09, 0x77, 0x72, 0x69, 0x74, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x21, 0x0a,\n\t0x03, 0x78, 0x6d, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x58, 0x6d, 0x6c, 0x52, 0x03, 0x78, 0x6d, 0x6c,\n\t0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63,\n\t0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63,\n\t0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12,\n\t0x29, 0x0a, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x0f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e,\n\t0x79, 0x52, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x65,\n\t0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a,\n\t0x64, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69,\n\t0x74, 0x6c, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65,\n\t0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5f, 0x6f, 0x66, 0x18,\n\t0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0a, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x4f,\n\t0x66, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0b, 0x20, 0x01,\n\t0x28, 0x01, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65,\n\t0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d,\n\t0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76,\n\t0x65, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x69, 0x6e, 0x69,\n\t0x6d, 0x75, 0x6d, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x6d, 0x69, 0x6e, 0x69, 0x6d,\n\t0x75, 0x6d, 0x12, 0x2b, 0x0a, 0x11, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f,\n\t0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65,\n\t0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x12,\n\t0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x78, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0f, 0x20,\n\t0x01, 0x28, 0x03, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1d,\n\t0x0a, 0x0a, 0x6d, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x10, 0x20, 0x01,\n\t0x28, 0x03, 0x52, 0x09, 0x6d, 0x69, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a,\n\t0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,\n\t0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x5f, 0x69,\n\t0x74, 0x65, 0x6d, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x61, 0x78, 0x49,\n\t0x74, 0x65, 0x6d, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6e, 0x5f, 0x69, 0x74, 0x65, 0x6d,\n\t0x73, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x6d, 0x69, 0x6e, 0x49, 0x74, 0x65, 0x6d,\n\t0x73, 0x12, 0x21, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d,\n\t0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x49,\n\t0x74, 0x65, 0x6d, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x72, 0x6f, 0x70,\n\t0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x61,\n\t0x78, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6d,\n\t0x69, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x16, 0x20,\n\t0x01, 0x28, 0x03, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,\n\t0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x17,\n\t0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x23,\n\t0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x18, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f,\n\t0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x65,\n\t0x6e, 0x75, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x19, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x61, 0x6c, 0x6c, 0x5f, 0x6f,\n\t0x66, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x4f, 0x66, 0x12, 0x34, 0x0a,\n\t0x06, 0x6f, 0x6e, 0x65, 0x5f, 0x6f, 0x66, 0x18, 0x1b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d,\n\t0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x05, 0x6f, 0x6e,\n\t0x65, 0x4f, 0x66, 0x12, 0x34, 0x0a, 0x06, 0x61, 0x6e, 0x79, 0x5f, 0x6f, 0x66, 0x18, 0x1c, 0x20,\n\t0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x52, 0x05, 0x61, 0x6e, 0x79, 0x4f, 0x66, 0x12, 0x24, 0x0a, 0x03, 0x6e, 0x6f, 0x74,\n\t0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x03, 0x6e, 0x6f, 0x74, 0x12,\n\t0x2b, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x49, 0x74, 0x65, 0x6d,\n\t0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x36, 0x0a, 0x0a,\n\t0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x50, 0x72,\n\t0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72,\n\t0x74, 0x69, 0x65, 0x73, 0x12, 0x59, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,\n\t0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x20, 0x20,\n\t0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33,\n\t0x2e, 0x41, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65,\n\t0x72, 0x74, 0x69, 0x65, 0x73, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12,\n\t0x31, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0b,\n\t0x32, 0x17, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x44, 0x65,\n\t0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75,\n\t0x6c, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,\n\t0x6e, 0x18, 0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x23,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x4d, 0x0a, 0x17,\n\t0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78,\n\t0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x24, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e,\n\t0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64,\n\t0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,\n\t0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x81, 0x01, 0x0a, 0x11,\n\t0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x53,\n\t0x63, 0x68, 0x65, 0x6d, 0x61, 0x48, 0x00, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12,\n\t0x35, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x72, 0x65, 0x66,\n\t0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22,\n\t0x6e, 0x0a, 0x13, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65,\n\t0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x57, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69,\n\t0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18,\n\t0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x4f, 0x72,\n\t0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74,\n\t0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22,\n\t0x68, 0x0a, 0x13, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x69,\n\t0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x51, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69,\n\t0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18,\n\t0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e,\n\t0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72,\n\t0x72, 0x61, 0x79, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xd3, 0x02, 0x0a, 0x0e, 0x53, 0x65,\n\t0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04,\n\t0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,\n\t0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,\n\t0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01,\n\t0x28, 0x09, 0x52, 0x02, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65,\n\t0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x23,\n\t0x0a, 0x0d, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18,\n\t0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x46, 0x6f, 0x72,\n\t0x6d, 0x61, 0x74, 0x12, 0x2c, 0x0a, 0x05, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, 0x01,\n\t0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x4f, 0x61, 0x75, 0x74, 0x68, 0x46, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x05, 0x66, 0x6c, 0x6f, 0x77,\n\t0x73, 0x12, 0x2d, 0x0a, 0x13, 0x6f, 0x70, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x5f, 0x63, 0x6f, 0x6e,\n\t0x6e, 0x65, 0x63, 0x74, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10,\n\t0x6f, 0x70, 0x65, 0x6e, 0x49, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x55, 0x72, 0x6c,\n\t0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,\n\t0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22,\n\t0xa2, 0x01, 0x0a, 0x19, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65,\n\t0x6d, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x45, 0x0a,\n\t0x0f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65,\n\t0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68, 0x65,\n\t0x6d, 0x65, 0x48, 0x00, 0x52, 0x0e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63,\n\t0x68, 0x65, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63,\n\t0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x48, 0x00,\n\t0x52, 0x09, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x6f,\n\t0x6e, 0x65, 0x6f, 0x66, 0x22, 0x7e, 0x0a, 0x1b, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,\n\t0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x73, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e,\n\t0x63, 0x65, 0x73, 0x12, 0x5f, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61,\n\t0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03,\n\t0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e,\n\t0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x63, 0x68,\n\t0x65, 0x6d, 0x65, 0x4f, 0x72, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x14,\n\t0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72,\n\t0x74, 0x69, 0x65, 0x73, 0x22, 0xc6, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12,\n\t0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72,\n\t0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,\n\t0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,\n\t0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73,\n\t0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69,\n\t0x2e, 0x76, 0x33, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,\n\t0x6c, 0x65, 0x73, 0x52, 0x09, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x4d,\n\t0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f,\n\t0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32,\n\t0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d,\n\t0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xaf, 0x01,\n\t0x0a, 0x0e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65,\n\t0x12, 0x12, 0x0a, 0x04, 0x65, 0x6e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04,\n\t0x65, 0x6e, 0x75, 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x12, 0x20,\n\t0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,\n\t0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,\n\t0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,\n\t0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22,\n\t0x67, 0x0a, 0x0f, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c,\n\t0x65, 0x73, 0x12, 0x54, 0x0a, 0x15, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,\n\t0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,\n\t0x0b, 0x32, 0x1f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e,\n\t0x61, 0x6d, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62,\n\t0x6c, 0x65, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50, 0x72,\n\t0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0x71, 0x0a, 0x16, 0x53, 0x70, 0x65, 0x63,\n\t0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69,\n\t0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01,\n\t0x28, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x07,\n\t0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52,\n\t0x07, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x12, 0x18, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69,\n\t0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69,\n\t0x6e, 0x67, 0x42, 0x07, 0x0a, 0x05, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x23, 0x0a, 0x0b, 0x53,\n\t0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,\n\t0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,\n\t0x22, 0x57, 0x0a, 0x07, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x4c, 0x0a, 0x15, 0x61,\n\t0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72,\n\t0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6f, 0x70, 0x65,\n\t0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x53, 0x74, 0x72,\n\t0x69, 0x6e, 0x67, 0x52, 0x14, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x50,\n\t0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x22, 0xc9, 0x01, 0x0a, 0x03, 0x54, 0x61,\n\t0x67, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63,\n\t0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3d, 0x0a, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72,\n\t0x6e, 0x61, 0x6c, 0x5f, 0x64, 0x6f, 0x63, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18,\n\t0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x45, 0x78, 0x74, 0x65,\n\t0x72, 0x6e, 0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x52, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e,\n\t0x61, 0x6c, 0x44, 0x6f, 0x63, 0x73, 0x12, 0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66,\n\t0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f,\n\t0x6e, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70,\n\t0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73,\n\t0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65,\n\t0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd6, 0x01, 0x0a, 0x03, 0x58, 0x6d, 0x6c, 0x12, 0x12, 0x0a,\n\t0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,\n\t0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12,\n\t0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,\n\t0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69,\n\t0x62, 0x75, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72,\n\t0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64,\n\t0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x12,\n\t0x4d, 0x0a, 0x17, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,\n\t0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b,\n\t0x32, 0x14, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x33, 0x2e, 0x4e, 0x61,\n\t0x6d, 0x65, 0x64, 0x41, 0x6e, 0x79, 0x52, 0x16, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x3e,\n\t0x0a, 0x0e, 0x6f, 0x72, 0x67, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33,\n\t0x42, 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x41, 0x50, 0x49, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01,\n\t0x5a, 0x16, 0x2e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x3b, 0x6f, 0x70,\n\t0x65, 0x6e, 0x61, 0x70, 0x69, 0x5f, 0x76, 0x33, 0xa2, 0x02, 0x03, 0x4f, 0x41, 0x53, 0x62, 0x06,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_openapiv3_OpenAPIv3_proto_rawDescOnce sync.Once\n\tfile_openapiv3_OpenAPIv3_proto_rawDescData = file_openapiv3_OpenAPIv3_proto_rawDesc\n)\n\nfunc file_openapiv3_OpenAPIv3_proto_rawDescGZIP() []byte {\n\tfile_openapiv3_OpenAPIv3_proto_rawDescOnce.Do(func() {\n\t\tfile_openapiv3_OpenAPIv3_proto_rawDescData = protoimpl.X.CompressGZIP(file_openapiv3_OpenAPIv3_proto_rawDescData)\n\t})\n\treturn file_openapiv3_OpenAPIv3_proto_rawDescData\n}\n\nvar file_openapiv3_OpenAPIv3_proto_msgTypes = make([]protoimpl.MessageInfo, 78)\nvar file_openapiv3_OpenAPIv3_proto_goTypes = []interface{}{\n\t(*AdditionalPropertiesItem)(nil),       // 0: openapi.v3.AdditionalPropertiesItem\n\t(*Any)(nil),                            // 1: openapi.v3.Any\n\t(*AnyOrExpression)(nil),                // 2: openapi.v3.AnyOrExpression\n\t(*Callback)(nil),                       // 3: openapi.v3.Callback\n\t(*CallbackOrReference)(nil),            // 4: openapi.v3.CallbackOrReference\n\t(*CallbacksOrReferences)(nil),          // 5: openapi.v3.CallbacksOrReferences\n\t(*Components)(nil),                     // 6: openapi.v3.Components\n\t(*Contact)(nil),                        // 7: openapi.v3.Contact\n\t(*DefaultType)(nil),                    // 8: openapi.v3.DefaultType\n\t(*Discriminator)(nil),                  // 9: openapi.v3.Discriminator\n\t(*Document)(nil),                       // 10: openapi.v3.Document\n\t(*Encoding)(nil),                       // 11: openapi.v3.Encoding\n\t(*Encodings)(nil),                      // 12: openapi.v3.Encodings\n\t(*Example)(nil),                        // 13: openapi.v3.Example\n\t(*ExampleOrReference)(nil),             // 14: openapi.v3.ExampleOrReference\n\t(*ExamplesOrReferences)(nil),           // 15: openapi.v3.ExamplesOrReferences\n\t(*Expression)(nil),                     // 16: openapi.v3.Expression\n\t(*ExternalDocs)(nil),                   // 17: openapi.v3.ExternalDocs\n\t(*Header)(nil),                         // 18: openapi.v3.Header\n\t(*HeaderOrReference)(nil),              // 19: openapi.v3.HeaderOrReference\n\t(*HeadersOrReferences)(nil),            // 20: openapi.v3.HeadersOrReferences\n\t(*Info)(nil),                           // 21: openapi.v3.Info\n\t(*ItemsItem)(nil),                      // 22: openapi.v3.ItemsItem\n\t(*License)(nil),                        // 23: openapi.v3.License\n\t(*Link)(nil),                           // 24: openapi.v3.Link\n\t(*LinkOrReference)(nil),                // 25: openapi.v3.LinkOrReference\n\t(*LinksOrReferences)(nil),              // 26: openapi.v3.LinksOrReferences\n\t(*MediaType)(nil),                      // 27: openapi.v3.MediaType\n\t(*MediaTypes)(nil),                     // 28: openapi.v3.MediaTypes\n\t(*NamedAny)(nil),                       // 29: openapi.v3.NamedAny\n\t(*NamedCallbackOrReference)(nil),       // 30: openapi.v3.NamedCallbackOrReference\n\t(*NamedEncoding)(nil),                  // 31: openapi.v3.NamedEncoding\n\t(*NamedExampleOrReference)(nil),        // 32: openapi.v3.NamedExampleOrReference\n\t(*NamedHeaderOrReference)(nil),         // 33: openapi.v3.NamedHeaderOrReference\n\t(*NamedLinkOrReference)(nil),           // 34: openapi.v3.NamedLinkOrReference\n\t(*NamedMediaType)(nil),                 // 35: openapi.v3.NamedMediaType\n\t(*NamedParameterOrReference)(nil),      // 36: openapi.v3.NamedParameterOrReference\n\t(*NamedPathItem)(nil),                  // 37: openapi.v3.NamedPathItem\n\t(*NamedRequestBodyOrReference)(nil),    // 38: openapi.v3.NamedRequestBodyOrReference\n\t(*NamedResponseOrReference)(nil),       // 39: openapi.v3.NamedResponseOrReference\n\t(*NamedSchemaOrReference)(nil),         // 40: openapi.v3.NamedSchemaOrReference\n\t(*NamedSecuritySchemeOrReference)(nil), // 41: openapi.v3.NamedSecuritySchemeOrReference\n\t(*NamedServerVariable)(nil),            // 42: openapi.v3.NamedServerVariable\n\t(*NamedString)(nil),                    // 43: openapi.v3.NamedString\n\t(*NamedStringArray)(nil),               // 44: openapi.v3.NamedStringArray\n\t(*OauthFlow)(nil),                      // 45: openapi.v3.OauthFlow\n\t(*OauthFlows)(nil),                     // 46: openapi.v3.OauthFlows\n\t(*Object)(nil),                         // 47: openapi.v3.Object\n\t(*Operation)(nil),                      // 48: openapi.v3.Operation\n\t(*Parameter)(nil),                      // 49: openapi.v3.Parameter\n\t(*ParameterOrReference)(nil),           // 50: openapi.v3.ParameterOrReference\n\t(*ParametersOrReferences)(nil),         // 51: openapi.v3.ParametersOrReferences\n\t(*PathItem)(nil),                       // 52: openapi.v3.PathItem\n\t(*Paths)(nil),                          // 53: openapi.v3.Paths\n\t(*Properties)(nil),                     // 54: openapi.v3.Properties\n\t(*Reference)(nil),                      // 55: openapi.v3.Reference\n\t(*RequestBodiesOrReferences)(nil),      // 56: openapi.v3.RequestBodiesOrReferences\n\t(*RequestBody)(nil),                    // 57: openapi.v3.RequestBody\n\t(*RequestBodyOrReference)(nil),         // 58: openapi.v3.RequestBodyOrReference\n\t(*Response)(nil),                       // 59: openapi.v3.Response\n\t(*ResponseOrReference)(nil),            // 60: openapi.v3.ResponseOrReference\n\t(*Responses)(nil),                      // 61: openapi.v3.Responses\n\t(*ResponsesOrReferences)(nil),          // 62: openapi.v3.ResponsesOrReferences\n\t(*Schema)(nil),                         // 63: openapi.v3.Schema\n\t(*SchemaOrReference)(nil),              // 64: openapi.v3.SchemaOrReference\n\t(*SchemasOrReferences)(nil),            // 65: openapi.v3.SchemasOrReferences\n\t(*SecurityRequirement)(nil),            // 66: openapi.v3.SecurityRequirement\n\t(*SecurityScheme)(nil),                 // 67: openapi.v3.SecurityScheme\n\t(*SecuritySchemeOrReference)(nil),      // 68: openapi.v3.SecuritySchemeOrReference\n\t(*SecuritySchemesOrReferences)(nil),    // 69: openapi.v3.SecuritySchemesOrReferences\n\t(*Server)(nil),                         // 70: openapi.v3.Server\n\t(*ServerVariable)(nil),                 // 71: openapi.v3.ServerVariable\n\t(*ServerVariables)(nil),                // 72: openapi.v3.ServerVariables\n\t(*SpecificationExtension)(nil),         // 73: openapi.v3.SpecificationExtension\n\t(*StringArray)(nil),                    // 74: openapi.v3.StringArray\n\t(*Strings)(nil),                        // 75: openapi.v3.Strings\n\t(*Tag)(nil),                            // 76: openapi.v3.Tag\n\t(*Xml)(nil),                            // 77: openapi.v3.Xml\n\t(*anypb.Any)(nil),                      // 78: google.protobuf.Any\n}\nvar file_openapiv3_OpenAPIv3_proto_depIdxs = []int32{\n\t64,  // 0: openapi.v3.AdditionalPropertiesItem.schema_or_reference:type_name -> openapi.v3.SchemaOrReference\n\t78,  // 1: openapi.v3.Any.value:type_name -> google.protobuf.Any\n\t1,   // 2: openapi.v3.AnyOrExpression.any:type_name -> openapi.v3.Any\n\t16,  // 3: openapi.v3.AnyOrExpression.expression:type_name -> openapi.v3.Expression\n\t37,  // 4: openapi.v3.Callback.path:type_name -> openapi.v3.NamedPathItem\n\t29,  // 5: openapi.v3.Callback.specification_extension:type_name -> openapi.v3.NamedAny\n\t3,   // 6: openapi.v3.CallbackOrReference.callback:type_name -> openapi.v3.Callback\n\t55,  // 7: openapi.v3.CallbackOrReference.reference:type_name -> openapi.v3.Reference\n\t30,  // 8: openapi.v3.CallbacksOrReferences.additional_properties:type_name -> openapi.v3.NamedCallbackOrReference\n\t65,  // 9: openapi.v3.Components.schemas:type_name -> openapi.v3.SchemasOrReferences\n\t62,  // 10: openapi.v3.Components.responses:type_name -> openapi.v3.ResponsesOrReferences\n\t51,  // 11: openapi.v3.Components.parameters:type_name -> openapi.v3.ParametersOrReferences\n\t15,  // 12: openapi.v3.Components.examples:type_name -> openapi.v3.ExamplesOrReferences\n\t56,  // 13: openapi.v3.Components.request_bodies:type_name -> openapi.v3.RequestBodiesOrReferences\n\t20,  // 14: openapi.v3.Components.headers:type_name -> openapi.v3.HeadersOrReferences\n\t69,  // 15: openapi.v3.Components.security_schemes:type_name -> openapi.v3.SecuritySchemesOrReferences\n\t26,  // 16: openapi.v3.Components.links:type_name -> openapi.v3.LinksOrReferences\n\t5,   // 17: openapi.v3.Components.callbacks:type_name -> openapi.v3.CallbacksOrReferences\n\t29,  // 18: openapi.v3.Components.specification_extension:type_name -> openapi.v3.NamedAny\n\t29,  // 19: openapi.v3.Contact.specification_extension:type_name -> openapi.v3.NamedAny\n\t75,  // 20: openapi.v3.Discriminator.mapping:type_name -> openapi.v3.Strings\n\t29,  // 21: openapi.v3.Discriminator.specification_extension:type_name -> openapi.v3.NamedAny\n\t21,  // 22: openapi.v3.Document.info:type_name -> openapi.v3.Info\n\t70,  // 23: openapi.v3.Document.servers:type_name -> openapi.v3.Server\n\t53,  // 24: openapi.v3.Document.paths:type_name -> openapi.v3.Paths\n\t6,   // 25: openapi.v3.Document.components:type_name -> openapi.v3.Components\n\t66,  // 26: openapi.v3.Document.security:type_name -> openapi.v3.SecurityRequirement\n\t76,  // 27: openapi.v3.Document.tags:type_name -> openapi.v3.Tag\n\t17,  // 28: openapi.v3.Document.external_docs:type_name -> openapi.v3.ExternalDocs\n\t29,  // 29: openapi.v3.Document.specification_extension:type_name -> openapi.v3.NamedAny\n\t20,  // 30: openapi.v3.Encoding.headers:type_name -> openapi.v3.HeadersOrReferences\n\t29,  // 31: openapi.v3.Encoding.specification_extension:type_name -> openapi.v3.NamedAny\n\t31,  // 32: openapi.v3.Encodings.additional_properties:type_name -> openapi.v3.NamedEncoding\n\t1,   // 33: openapi.v3.Example.value:type_name -> openapi.v3.Any\n\t29,  // 34: openapi.v3.Example.specification_extension:type_name -> openapi.v3.NamedAny\n\t13,  // 35: openapi.v3.ExampleOrReference.example:type_name -> openapi.v3.Example\n\t55,  // 36: openapi.v3.ExampleOrReference.reference:type_name -> openapi.v3.Reference\n\t32,  // 37: openapi.v3.ExamplesOrReferences.additional_properties:type_name -> openapi.v3.NamedExampleOrReference\n\t29,  // 38: openapi.v3.Expression.additional_properties:type_name -> openapi.v3.NamedAny\n\t29,  // 39: openapi.v3.ExternalDocs.specification_extension:type_name -> openapi.v3.NamedAny\n\t64,  // 40: openapi.v3.Header.schema:type_name -> openapi.v3.SchemaOrReference\n\t1,   // 41: openapi.v3.Header.example:type_name -> openapi.v3.Any\n\t15,  // 42: openapi.v3.Header.examples:type_name -> openapi.v3.ExamplesOrReferences\n\t28,  // 43: openapi.v3.Header.content:type_name -> openapi.v3.MediaTypes\n\t29,  // 44: openapi.v3.Header.specification_extension:type_name -> openapi.v3.NamedAny\n\t18,  // 45: openapi.v3.HeaderOrReference.header:type_name -> openapi.v3.Header\n\t55,  // 46: openapi.v3.HeaderOrReference.reference:type_name -> openapi.v3.Reference\n\t33,  // 47: openapi.v3.HeadersOrReferences.additional_properties:type_name -> openapi.v3.NamedHeaderOrReference\n\t7,   // 48: openapi.v3.Info.contact:type_name -> openapi.v3.Contact\n\t23,  // 49: openapi.v3.Info.license:type_name -> openapi.v3.License\n\t29,  // 50: openapi.v3.Info.specification_extension:type_name -> openapi.v3.NamedAny\n\t64,  // 51: openapi.v3.ItemsItem.schema_or_reference:type_name -> openapi.v3.SchemaOrReference\n\t29,  // 52: openapi.v3.License.specification_extension:type_name -> openapi.v3.NamedAny\n\t2,   // 53: openapi.v3.Link.parameters:type_name -> openapi.v3.AnyOrExpression\n\t2,   // 54: openapi.v3.Link.request_body:type_name -> openapi.v3.AnyOrExpression\n\t70,  // 55: openapi.v3.Link.server:type_name -> openapi.v3.Server\n\t29,  // 56: openapi.v3.Link.specification_extension:type_name -> openapi.v3.NamedAny\n\t24,  // 57: openapi.v3.LinkOrReference.link:type_name -> openapi.v3.Link\n\t55,  // 58: openapi.v3.LinkOrReference.reference:type_name -> openapi.v3.Reference\n\t34,  // 59: openapi.v3.LinksOrReferences.additional_properties:type_name -> openapi.v3.NamedLinkOrReference\n\t64,  // 60: openapi.v3.MediaType.schema:type_name -> openapi.v3.SchemaOrReference\n\t1,   // 61: openapi.v3.MediaType.example:type_name -> openapi.v3.Any\n\t15,  // 62: openapi.v3.MediaType.examples:type_name -> openapi.v3.ExamplesOrReferences\n\t12,  // 63: openapi.v3.MediaType.encoding:type_name -> openapi.v3.Encodings\n\t29,  // 64: openapi.v3.MediaType.specification_extension:type_name -> openapi.v3.NamedAny\n\t35,  // 65: openapi.v3.MediaTypes.additional_properties:type_name -> openapi.v3.NamedMediaType\n\t1,   // 66: openapi.v3.NamedAny.value:type_name -> openapi.v3.Any\n\t4,   // 67: openapi.v3.NamedCallbackOrReference.value:type_name -> openapi.v3.CallbackOrReference\n\t11,  // 68: openapi.v3.NamedEncoding.value:type_name -> openapi.v3.Encoding\n\t14,  // 69: openapi.v3.NamedExampleOrReference.value:type_name -> openapi.v3.ExampleOrReference\n\t19,  // 70: openapi.v3.NamedHeaderOrReference.value:type_name -> openapi.v3.HeaderOrReference\n\t25,  // 71: openapi.v3.NamedLinkOrReference.value:type_name -> openapi.v3.LinkOrReference\n\t27,  // 72: openapi.v3.NamedMediaType.value:type_name -> openapi.v3.MediaType\n\t50,  // 73: openapi.v3.NamedParameterOrReference.value:type_name -> openapi.v3.ParameterOrReference\n\t52,  // 74: openapi.v3.NamedPathItem.value:type_name -> openapi.v3.PathItem\n\t58,  // 75: openapi.v3.NamedRequestBodyOrReference.value:type_name -> openapi.v3.RequestBodyOrReference\n\t60,  // 76: openapi.v3.NamedResponseOrReference.value:type_name -> openapi.v3.ResponseOrReference\n\t64,  // 77: openapi.v3.NamedSchemaOrReference.value:type_name -> openapi.v3.SchemaOrReference\n\t68,  // 78: openapi.v3.NamedSecuritySchemeOrReference.value:type_name -> openapi.v3.SecuritySchemeOrReference\n\t71,  // 79: openapi.v3.NamedServerVariable.value:type_name -> openapi.v3.ServerVariable\n\t74,  // 80: openapi.v3.NamedStringArray.value:type_name -> openapi.v3.StringArray\n\t75,  // 81: openapi.v3.OauthFlow.scopes:type_name -> openapi.v3.Strings\n\t29,  // 82: openapi.v3.OauthFlow.specification_extension:type_name -> openapi.v3.NamedAny\n\t45,  // 83: openapi.v3.OauthFlows.implicit:type_name -> openapi.v3.OauthFlow\n\t45,  // 84: openapi.v3.OauthFlows.password:type_name -> openapi.v3.OauthFlow\n\t45,  // 85: openapi.v3.OauthFlows.client_credentials:type_name -> openapi.v3.OauthFlow\n\t45,  // 86: openapi.v3.OauthFlows.authorization_code:type_name -> openapi.v3.OauthFlow\n\t29,  // 87: openapi.v3.OauthFlows.specification_extension:type_name -> openapi.v3.NamedAny\n\t29,  // 88: openapi.v3.Object.additional_properties:type_name -> openapi.v3.NamedAny\n\t17,  // 89: openapi.v3.Operation.external_docs:type_name -> openapi.v3.ExternalDocs\n\t50,  // 90: openapi.v3.Operation.parameters:type_name -> openapi.v3.ParameterOrReference\n\t58,  // 91: openapi.v3.Operation.request_body:type_name -> openapi.v3.RequestBodyOrReference\n\t61,  // 92: openapi.v3.Operation.responses:type_name -> openapi.v3.Responses\n\t5,   // 93: openapi.v3.Operation.callbacks:type_name -> openapi.v3.CallbacksOrReferences\n\t66,  // 94: openapi.v3.Operation.security:type_name -> openapi.v3.SecurityRequirement\n\t70,  // 95: openapi.v3.Operation.servers:type_name -> openapi.v3.Server\n\t29,  // 96: openapi.v3.Operation.specification_extension:type_name -> openapi.v3.NamedAny\n\t64,  // 97: openapi.v3.Parameter.schema:type_name -> openapi.v3.SchemaOrReference\n\t1,   // 98: openapi.v3.Parameter.example:type_name -> openapi.v3.Any\n\t15,  // 99: openapi.v3.Parameter.examples:type_name -> openapi.v3.ExamplesOrReferences\n\t28,  // 100: openapi.v3.Parameter.content:type_name -> openapi.v3.MediaTypes\n\t29,  // 101: openapi.v3.Parameter.specification_extension:type_name -> openapi.v3.NamedAny\n\t49,  // 102: openapi.v3.ParameterOrReference.parameter:type_name -> openapi.v3.Parameter\n\t55,  // 103: openapi.v3.ParameterOrReference.reference:type_name -> openapi.v3.Reference\n\t36,  // 104: openapi.v3.ParametersOrReferences.additional_properties:type_name -> openapi.v3.NamedParameterOrReference\n\t48,  // 105: openapi.v3.PathItem.get:type_name -> openapi.v3.Operation\n\t48,  // 106: openapi.v3.PathItem.put:type_name -> openapi.v3.Operation\n\t48,  // 107: openapi.v3.PathItem.post:type_name -> openapi.v3.Operation\n\t48,  // 108: openapi.v3.PathItem.delete:type_name -> openapi.v3.Operation\n\t48,  // 109: openapi.v3.PathItem.options:type_name -> openapi.v3.Operation\n\t48,  // 110: openapi.v3.PathItem.head:type_name -> openapi.v3.Operation\n\t48,  // 111: openapi.v3.PathItem.patch:type_name -> openapi.v3.Operation\n\t48,  // 112: openapi.v3.PathItem.trace:type_name -> openapi.v3.Operation\n\t70,  // 113: openapi.v3.PathItem.servers:type_name -> openapi.v3.Server\n\t50,  // 114: openapi.v3.PathItem.parameters:type_name -> openapi.v3.ParameterOrReference\n\t29,  // 115: openapi.v3.PathItem.specification_extension:type_name -> openapi.v3.NamedAny\n\t37,  // 116: openapi.v3.Paths.path:type_name -> openapi.v3.NamedPathItem\n\t29,  // 117: openapi.v3.Paths.specification_extension:type_name -> openapi.v3.NamedAny\n\t40,  // 118: openapi.v3.Properties.additional_properties:type_name -> openapi.v3.NamedSchemaOrReference\n\t38,  // 119: openapi.v3.RequestBodiesOrReferences.additional_properties:type_name -> openapi.v3.NamedRequestBodyOrReference\n\t28,  // 120: openapi.v3.RequestBody.content:type_name -> openapi.v3.MediaTypes\n\t29,  // 121: openapi.v3.RequestBody.specification_extension:type_name -> openapi.v3.NamedAny\n\t57,  // 122: openapi.v3.RequestBodyOrReference.request_body:type_name -> openapi.v3.RequestBody\n\t55,  // 123: openapi.v3.RequestBodyOrReference.reference:type_name -> openapi.v3.Reference\n\t20,  // 124: openapi.v3.Response.headers:type_name -> openapi.v3.HeadersOrReferences\n\t28,  // 125: openapi.v3.Response.content:type_name -> openapi.v3.MediaTypes\n\t26,  // 126: openapi.v3.Response.links:type_name -> openapi.v3.LinksOrReferences\n\t29,  // 127: openapi.v3.Response.specification_extension:type_name -> openapi.v3.NamedAny\n\t59,  // 128: openapi.v3.ResponseOrReference.response:type_name -> openapi.v3.Response\n\t55,  // 129: openapi.v3.ResponseOrReference.reference:type_name -> openapi.v3.Reference\n\t60,  // 130: openapi.v3.Responses.default:type_name -> openapi.v3.ResponseOrReference\n\t39,  // 131: openapi.v3.Responses.response_or_reference:type_name -> openapi.v3.NamedResponseOrReference\n\t29,  // 132: openapi.v3.Responses.specification_extension:type_name -> openapi.v3.NamedAny\n\t39,  // 133: openapi.v3.ResponsesOrReferences.additional_properties:type_name -> openapi.v3.NamedResponseOrReference\n\t9,   // 134: openapi.v3.Schema.discriminator:type_name -> openapi.v3.Discriminator\n\t77,  // 135: openapi.v3.Schema.xml:type_name -> openapi.v3.Xml\n\t17,  // 136: openapi.v3.Schema.external_docs:type_name -> openapi.v3.ExternalDocs\n\t1,   // 137: openapi.v3.Schema.example:type_name -> openapi.v3.Any\n\t1,   // 138: openapi.v3.Schema.enum:type_name -> openapi.v3.Any\n\t64,  // 139: openapi.v3.Schema.all_of:type_name -> openapi.v3.SchemaOrReference\n\t64,  // 140: openapi.v3.Schema.one_of:type_name -> openapi.v3.SchemaOrReference\n\t64,  // 141: openapi.v3.Schema.any_of:type_name -> openapi.v3.SchemaOrReference\n\t63,  // 142: openapi.v3.Schema.not:type_name -> openapi.v3.Schema\n\t22,  // 143: openapi.v3.Schema.items:type_name -> openapi.v3.ItemsItem\n\t54,  // 144: openapi.v3.Schema.properties:type_name -> openapi.v3.Properties\n\t0,   // 145: openapi.v3.Schema.additional_properties:type_name -> openapi.v3.AdditionalPropertiesItem\n\t8,   // 146: openapi.v3.Schema.default:type_name -> openapi.v3.DefaultType\n\t29,  // 147: openapi.v3.Schema.specification_extension:type_name -> openapi.v3.NamedAny\n\t63,  // 148: openapi.v3.SchemaOrReference.schema:type_name -> openapi.v3.Schema\n\t55,  // 149: openapi.v3.SchemaOrReference.reference:type_name -> openapi.v3.Reference\n\t40,  // 150: openapi.v3.SchemasOrReferences.additional_properties:type_name -> openapi.v3.NamedSchemaOrReference\n\t44,  // 151: openapi.v3.SecurityRequirement.additional_properties:type_name -> openapi.v3.NamedStringArray\n\t46,  // 152: openapi.v3.SecurityScheme.flows:type_name -> openapi.v3.OauthFlows\n\t29,  // 153: openapi.v3.SecurityScheme.specification_extension:type_name -> openapi.v3.NamedAny\n\t67,  // 154: openapi.v3.SecuritySchemeOrReference.security_scheme:type_name -> openapi.v3.SecurityScheme\n\t55,  // 155: openapi.v3.SecuritySchemeOrReference.reference:type_name -> openapi.v3.Reference\n\t41,  // 156: openapi.v3.SecuritySchemesOrReferences.additional_properties:type_name -> openapi.v3.NamedSecuritySchemeOrReference\n\t72,  // 157: openapi.v3.Server.variables:type_name -> openapi.v3.ServerVariables\n\t29,  // 158: openapi.v3.Server.specification_extension:type_name -> openapi.v3.NamedAny\n\t29,  // 159: openapi.v3.ServerVariable.specification_extension:type_name -> openapi.v3.NamedAny\n\t42,  // 160: openapi.v3.ServerVariables.additional_properties:type_name -> openapi.v3.NamedServerVariable\n\t43,  // 161: openapi.v3.Strings.additional_properties:type_name -> openapi.v3.NamedString\n\t17,  // 162: openapi.v3.Tag.external_docs:type_name -> openapi.v3.ExternalDocs\n\t29,  // 163: openapi.v3.Tag.specification_extension:type_name -> openapi.v3.NamedAny\n\t29,  // 164: openapi.v3.Xml.specification_extension:type_name -> openapi.v3.NamedAny\n\t165, // [165:165] is the sub-list for method output_type\n\t165, // [165:165] is the sub-list for method input_type\n\t165, // [165:165] is the sub-list for extension type_name\n\t165, // [165:165] is the sub-list for extension extendee\n\t0,   // [0:165] is the sub-list for field type_name\n}\n\nfunc init() { file_openapiv3_OpenAPIv3_proto_init() }\nfunc file_openapiv3_OpenAPIv3_proto_init() {\n\tif File_openapiv3_OpenAPIv3_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_openapiv3_OpenAPIv3_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*AdditionalPropertiesItem); 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_openapiv3_OpenAPIv3_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Any); 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_openapiv3_OpenAPIv3_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*AnyOrExpression); 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_openapiv3_OpenAPIv3_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Callback); 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_openapiv3_OpenAPIv3_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*CallbackOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*CallbacksOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Components); 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_openapiv3_OpenAPIv3_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Contact); 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_openapiv3_OpenAPIv3_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*DefaultType); 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_openapiv3_OpenAPIv3_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Discriminator); 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_openapiv3_OpenAPIv3_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Document); 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_openapiv3_OpenAPIv3_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Encoding); 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_openapiv3_OpenAPIv3_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Encodings); 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_openapiv3_OpenAPIv3_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Example); 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_openapiv3_OpenAPIv3_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExampleOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExamplesOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Expression); 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_openapiv3_OpenAPIv3_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ExternalDocs); 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_openapiv3_OpenAPIv3_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Header); 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_openapiv3_OpenAPIv3_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HeaderOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HeadersOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Info); 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_openapiv3_OpenAPIv3_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ItemsItem); 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_openapiv3_OpenAPIv3_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*License); 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_openapiv3_OpenAPIv3_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Link); 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_openapiv3_OpenAPIv3_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*LinkOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*LinksOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*MediaType); 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_openapiv3_OpenAPIv3_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*MediaTypes); 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_openapiv3_OpenAPIv3_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedAny); 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_openapiv3_OpenAPIv3_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedCallbackOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedEncoding); 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_openapiv3_OpenAPIv3_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedExampleOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedHeaderOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedLinkOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedMediaType); 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_openapiv3_OpenAPIv3_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedParameterOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedPathItem); 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_openapiv3_OpenAPIv3_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedRequestBodyOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedResponseOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedSchemaOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedSecuritySchemeOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedServerVariable); 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_openapiv3_OpenAPIv3_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedString); 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_openapiv3_OpenAPIv3_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NamedStringArray); 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_openapiv3_OpenAPIv3_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*OauthFlow); 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_openapiv3_OpenAPIv3_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*OauthFlows); 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_openapiv3_OpenAPIv3_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Object); 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_openapiv3_OpenAPIv3_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Operation); 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_openapiv3_OpenAPIv3_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Parameter); 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_openapiv3_OpenAPIv3_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ParameterOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ParametersOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*PathItem); 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_openapiv3_OpenAPIv3_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Paths); 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_openapiv3_OpenAPIv3_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Properties); 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_openapiv3_OpenAPIv3_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Reference); 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_openapiv3_OpenAPIv3_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*RequestBodiesOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*RequestBody); 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_openapiv3_OpenAPIv3_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*RequestBodyOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Response); 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_openapiv3_OpenAPIv3_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ResponseOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Responses); 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_openapiv3_OpenAPIv3_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ResponsesOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Schema); 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_openapiv3_OpenAPIv3_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SchemaOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SchemasOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SecurityRequirement); 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_openapiv3_OpenAPIv3_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SecurityScheme); 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_openapiv3_OpenAPIv3_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SecuritySchemeOrReference); 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_openapiv3_OpenAPIv3_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SecuritySchemesOrReferences); 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_openapiv3_OpenAPIv3_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Server); 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_openapiv3_OpenAPIv3_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ServerVariable); 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_openapiv3_OpenAPIv3_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*ServerVariables); 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_openapiv3_OpenAPIv3_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SpecificationExtension); 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_openapiv3_OpenAPIv3_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*StringArray); 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_openapiv3_OpenAPIv3_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Strings); 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_openapiv3_OpenAPIv3_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Tag); 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_openapiv3_OpenAPIv3_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Xml); 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\tfile_openapiv3_OpenAPIv3_proto_msgTypes[0].OneofWrappers = []interface{}{\n\t\t(*AdditionalPropertiesItem_SchemaOrReference)(nil),\n\t\t(*AdditionalPropertiesItem_Boolean)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[2].OneofWrappers = []interface{}{\n\t\t(*AnyOrExpression_Any)(nil),\n\t\t(*AnyOrExpression_Expression)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[4].OneofWrappers = []interface{}{\n\t\t(*CallbackOrReference_Callback)(nil),\n\t\t(*CallbackOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[8].OneofWrappers = []interface{}{\n\t\t(*DefaultType_Number)(nil),\n\t\t(*DefaultType_Boolean)(nil),\n\t\t(*DefaultType_String_)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[14].OneofWrappers = []interface{}{\n\t\t(*ExampleOrReference_Example)(nil),\n\t\t(*ExampleOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[19].OneofWrappers = []interface{}{\n\t\t(*HeaderOrReference_Header)(nil),\n\t\t(*HeaderOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[25].OneofWrappers = []interface{}{\n\t\t(*LinkOrReference_Link)(nil),\n\t\t(*LinkOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[50].OneofWrappers = []interface{}{\n\t\t(*ParameterOrReference_Parameter)(nil),\n\t\t(*ParameterOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[58].OneofWrappers = []interface{}{\n\t\t(*RequestBodyOrReference_RequestBody)(nil),\n\t\t(*RequestBodyOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[60].OneofWrappers = []interface{}{\n\t\t(*ResponseOrReference_Response)(nil),\n\t\t(*ResponseOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[64].OneofWrappers = []interface{}{\n\t\t(*SchemaOrReference_Schema)(nil),\n\t\t(*SchemaOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[68].OneofWrappers = []interface{}{\n\t\t(*SecuritySchemeOrReference_SecurityScheme)(nil),\n\t\t(*SecuritySchemeOrReference_Reference)(nil),\n\t}\n\tfile_openapiv3_OpenAPIv3_proto_msgTypes[73].OneofWrappers = []interface{}{\n\t\t(*SpecificationExtension_Number)(nil),\n\t\t(*SpecificationExtension_Boolean)(nil),\n\t\t(*SpecificationExtension_String_)(nil),\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_openapiv3_OpenAPIv3_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   78,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_openapiv3_OpenAPIv3_proto_goTypes,\n\t\tDependencyIndexes: file_openapiv3_OpenAPIv3_proto_depIdxs,\n\t\tMessageInfos:      file_openapiv3_OpenAPIv3_proto_msgTypes,\n\t}.Build()\n\tFile_openapiv3_OpenAPIv3_proto = out.File\n\tfile_openapiv3_OpenAPIv3_proto_rawDesc = nil\n\tfile_openapiv3_OpenAPIv3_proto_goTypes = nil\n\tfile_openapiv3_OpenAPIv3_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv3/OpenAPIv3.proto",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\n// THIS FILE IS AUTOMATICALLY GENERATED.\n\nsyntax = \"proto3\";\n\npackage openapi.v3;\n\nimport \"google/protobuf/any.proto\";\n\n// This option lets the proto compiler generate Java code inside the package\n// name (see below) instead of inside an outer class. It creates a simpler\n// developer experience by reducing one-level of name nesting and be\n// consistent with most programming languages that don't support outer classes.\noption java_multiple_files = true;\n\n// The Java outer classname should be the filename in UpperCamelCase. This\n// class is only used to hold proto descriptor, so developers don't need to\n// work with it directly.\noption java_outer_classname = \"OpenAPIProto\";\n\n// The Java package name must be proto package name with proper prefix.\noption java_package = \"org.openapi_v3\";\n\n// A reasonable prefix for the Objective-C symbols generated from the package.\n// It should at a minimum be 3 characters long, all uppercase, and convention\n// is to use an abbreviation of the package name. Something short, but\n// hopefully unique enough to not conflict with things that may come along in\n// the future. 'GPB' is reserved for the protocol buffer implementation itself.\noption objc_class_prefix = \"OAS\";\n\n// The Go package name.\noption go_package = \"./openapiv3;openapi_v3\";\n\nmessage AdditionalPropertiesItem {\n  oneof oneof {\n    SchemaOrReference schema_or_reference = 1;\n    bool boolean = 2;\n  }\n}\n\nmessage Any {\n  google.protobuf.Any value = 1;\n  string yaml = 2;\n}\n\nmessage AnyOrExpression {\n  oneof oneof {\n    Any any = 1;\n    Expression expression = 2;\n  }\n}\n\n// A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.\nmessage Callback {\n  repeated NamedPathItem path = 1;\n  repeated NamedAny specification_extension = 2;\n}\n\nmessage CallbackOrReference {\n  oneof oneof {\n    Callback callback = 1;\n    Reference reference = 2;\n  }\n}\n\nmessage CallbacksOrReferences {\n  repeated NamedCallbackOrReference additional_properties = 1;\n}\n\n// Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.\nmessage Components {\n  SchemasOrReferences schemas = 1;\n  ResponsesOrReferences responses = 2;\n  ParametersOrReferences parameters = 3;\n  ExamplesOrReferences examples = 4;\n  RequestBodiesOrReferences request_bodies = 5;\n  HeadersOrReferences headers = 6;\n  SecuritySchemesOrReferences security_schemes = 7;\n  LinksOrReferences links = 8;\n  CallbacksOrReferences callbacks = 9;\n  repeated NamedAny specification_extension = 10;\n}\n\n// Contact information for the exposed API.\nmessage Contact {\n  string name = 1;\n  string url = 2;\n  string email = 3;\n  repeated NamedAny specification_extension = 4;\n}\n\nmessage DefaultType {\n  oneof oneof {\n    double number = 1;\n    bool boolean = 2;\n    string string = 3;\n  }\n}\n\n// When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation.  The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it.  When using the discriminator, _inline_ schemas will not be considered.\nmessage Discriminator {\n  string property_name = 1;\n  Strings mapping = 2;\n  repeated NamedAny specification_extension = 3;\n}\n\nmessage Document {\n  string openapi = 1;\n  Info info = 2;\n  repeated Server servers = 3;\n  Paths paths = 4;\n  Components components = 5;\n  repeated SecurityRequirement security = 6;\n  repeated Tag tags = 7;\n  ExternalDocs external_docs = 8;\n  repeated NamedAny specification_extension = 9;\n}\n\n// A single encoding definition applied to a single schema property.\nmessage Encoding {\n  string content_type = 1;\n  HeadersOrReferences headers = 2;\n  string style = 3;\n  bool explode = 4;\n  bool allow_reserved = 5;\n  repeated NamedAny specification_extension = 6;\n}\n\nmessage Encodings {\n  repeated NamedEncoding additional_properties = 1;\n}\n\nmessage Example {\n  string summary = 1;\n  string description = 2;\n  Any value = 3;\n  string external_value = 4;\n  repeated NamedAny specification_extension = 5;\n}\n\nmessage ExampleOrReference {\n  oneof oneof {\n    Example example = 1;\n    Reference reference = 2;\n  }\n}\n\nmessage ExamplesOrReferences {\n  repeated NamedExampleOrReference additional_properties = 1;\n}\n\nmessage Expression {\n  repeated NamedAny additional_properties = 1;\n}\n\n// Allows referencing an external resource for extended documentation.\nmessage ExternalDocs {\n  string description = 1;\n  string url = 2;\n  repeated NamedAny specification_extension = 3;\n}\n\n// The Header Object follows the structure of the Parameter Object with the following changes:  1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).\nmessage Header {\n  string description = 1;\n  bool required = 2;\n  bool deprecated = 3;\n  bool allow_empty_value = 4;\n  string style = 5;\n  bool explode = 6;\n  bool allow_reserved = 7;\n  SchemaOrReference schema = 8;\n  Any example = 9;\n  ExamplesOrReferences examples = 10;\n  MediaTypes content = 11;\n  repeated NamedAny specification_extension = 12;\n}\n\nmessage HeaderOrReference {\n  oneof oneof {\n    Header header = 1;\n    Reference reference = 2;\n  }\n}\n\nmessage HeadersOrReferences {\n  repeated NamedHeaderOrReference additional_properties = 1;\n}\n\n// The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.\nmessage Info {\n  string title = 1;\n  string description = 2;\n  string terms_of_service = 3;\n  Contact contact = 4;\n  License license = 5;\n  string version = 6;\n  repeated NamedAny specification_extension = 7;\n  string summary = 8;\n}\n\nmessage ItemsItem {\n  repeated SchemaOrReference schema_or_reference = 1;\n}\n\n// License information for the exposed API.\nmessage License {\n  string name = 1;\n  string url = 2;\n  repeated NamedAny specification_extension = 3;\n}\n\n// The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.  Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response.  For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.\nmessage Link {\n  string operation_ref = 1;\n  string operation_id = 2;\n  AnyOrExpression parameters = 3;\n  AnyOrExpression request_body = 4;\n  string description = 5;\n  Server server = 6;\n  repeated NamedAny specification_extension = 7;\n}\n\nmessage LinkOrReference {\n  oneof oneof {\n    Link link = 1;\n    Reference reference = 2;\n  }\n}\n\nmessage LinksOrReferences {\n  repeated NamedLinkOrReference additional_properties = 1;\n}\n\n// Each Media Type Object provides schema and examples for the media type identified by its key.\nmessage MediaType {\n  SchemaOrReference schema = 1;\n  Any example = 2;\n  ExamplesOrReferences examples = 3;\n  Encodings encoding = 4;\n  repeated NamedAny specification_extension = 5;\n}\n\nmessage MediaTypes {\n  repeated NamedMediaType additional_properties = 1;\n}\n\n// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs.\nmessage NamedAny {\n  // Map key\n  string name = 1;\n  // Mapped value\n  Any value = 2;\n}\n\n// Automatically-generated message used to represent maps of CallbackOrReference as ordered (name,value) pairs.\nmessage NamedCallbackOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  CallbackOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of Encoding as ordered (name,value) pairs.\nmessage NamedEncoding {\n  // Map key\n  string name = 1;\n  // Mapped value\n  Encoding value = 2;\n}\n\n// Automatically-generated message used to represent maps of ExampleOrReference as ordered (name,value) pairs.\nmessage NamedExampleOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  ExampleOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of HeaderOrReference as ordered (name,value) pairs.\nmessage NamedHeaderOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  HeaderOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of LinkOrReference as ordered (name,value) pairs.\nmessage NamedLinkOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  LinkOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of MediaType as ordered (name,value) pairs.\nmessage NamedMediaType {\n  // Map key\n  string name = 1;\n  // Mapped value\n  MediaType value = 2;\n}\n\n// Automatically-generated message used to represent maps of ParameterOrReference as ordered (name,value) pairs.\nmessage NamedParameterOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  ParameterOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs.\nmessage NamedPathItem {\n  // Map key\n  string name = 1;\n  // Mapped value\n  PathItem value = 2;\n}\n\n// Automatically-generated message used to represent maps of RequestBodyOrReference as ordered (name,value) pairs.\nmessage NamedRequestBodyOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  RequestBodyOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of ResponseOrReference as ordered (name,value) pairs.\nmessage NamedResponseOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  ResponseOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of SchemaOrReference as ordered (name,value) pairs.\nmessage NamedSchemaOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  SchemaOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of SecuritySchemeOrReference as ordered (name,value) pairs.\nmessage NamedSecuritySchemeOrReference {\n  // Map key\n  string name = 1;\n  // Mapped value\n  SecuritySchemeOrReference value = 2;\n}\n\n// Automatically-generated message used to represent maps of ServerVariable as ordered (name,value) pairs.\nmessage NamedServerVariable {\n  // Map key\n  string name = 1;\n  // Mapped value\n  ServerVariable value = 2;\n}\n\n// Automatically-generated message used to represent maps of string as ordered (name,value) pairs.\nmessage NamedString {\n  // Map key\n  string name = 1;\n  // Mapped value\n  string value = 2;\n}\n\n// Automatically-generated message used to represent maps of StringArray as ordered (name,value) pairs.\nmessage NamedStringArray {\n  // Map key\n  string name = 1;\n  // Mapped value\n  StringArray value = 2;\n}\n\n// Configuration details for a supported OAuth Flow\nmessage OauthFlow {\n  string authorization_url = 1;\n  string token_url = 2;\n  string refresh_url = 3;\n  Strings scopes = 4;\n  repeated NamedAny specification_extension = 5;\n}\n\n// Allows configuration of the supported OAuth Flows.\nmessage OauthFlows {\n  OauthFlow implicit = 1;\n  OauthFlow password = 2;\n  OauthFlow client_credentials = 3;\n  OauthFlow authorization_code = 4;\n  repeated NamedAny specification_extension = 5;\n}\n\nmessage Object {\n  repeated NamedAny additional_properties = 1;\n}\n\n// Describes a single API operation on a path.\nmessage Operation {\n  repeated string tags = 1;\n  string summary = 2;\n  string description = 3;\n  ExternalDocs external_docs = 4;\n  string operation_id = 5;\n  repeated ParameterOrReference parameters = 6;\n  RequestBodyOrReference request_body = 7;\n  Responses responses = 8;\n  CallbacksOrReferences callbacks = 9;\n  bool deprecated = 10;\n  repeated SecurityRequirement security = 11;\n  repeated Server servers = 12;\n  repeated NamedAny specification_extension = 13;\n}\n\n// Describes a single operation parameter.  A unique parameter is defined by a combination of a name and location.\nmessage Parameter {\n  string name = 1;\n  string in = 2;\n  string description = 3;\n  bool required = 4;\n  bool deprecated = 5;\n  bool allow_empty_value = 6;\n  string style = 7;\n  bool explode = 8;\n  bool allow_reserved = 9;\n  SchemaOrReference schema = 10;\n  Any example = 11;\n  ExamplesOrReferences examples = 12;\n  MediaTypes content = 13;\n  repeated NamedAny specification_extension = 14;\n}\n\nmessage ParameterOrReference {\n  oneof oneof {\n    Parameter parameter = 1;\n    Reference reference = 2;\n  }\n}\n\nmessage ParametersOrReferences {\n  repeated NamedParameterOrReference additional_properties = 1;\n}\n\n// Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.\nmessage PathItem {\n  string _ref = 1;\n  string summary = 2;\n  string description = 3;\n  Operation get = 4;\n  Operation put = 5;\n  Operation post = 6;\n  Operation delete = 7;\n  Operation options = 8;\n  Operation head = 9;\n  Operation patch = 10;\n  Operation trace = 11;\n  repeated Server servers = 12;\n  repeated ParameterOrReference parameters = 13;\n  repeated NamedAny specification_extension = 14;\n}\n\n// Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL.  The Paths MAY be empty, due to ACL constraints.\nmessage Paths {\n  repeated NamedPathItem path = 1;\n  repeated NamedAny specification_extension = 2;\n}\n\nmessage Properties {\n  repeated NamedSchemaOrReference additional_properties = 1;\n}\n\n// A simple object to allow referencing other components in the specification, internally and externally.  The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules.   For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.\nmessage Reference {\n  string _ref = 1;\n  string summary = 2;\n  string description = 3;\n}\n\nmessage RequestBodiesOrReferences {\n  repeated NamedRequestBodyOrReference additional_properties = 1;\n}\n\n// Describes a single request body.\nmessage RequestBody {\n  string description = 1;\n  MediaTypes content = 2;\n  bool required = 3;\n  repeated NamedAny specification_extension = 4;\n}\n\nmessage RequestBodyOrReference {\n  oneof oneof {\n    RequestBody request_body = 1;\n    Reference reference = 2;\n  }\n}\n\n// Describes a single response from an API Operation, including design-time, static  `links` to operations based on the response.\nmessage Response {\n  string description = 1;\n  HeadersOrReferences headers = 2;\n  MediaTypes content = 3;\n  LinksOrReferences links = 4;\n  repeated NamedAny specification_extension = 5;\n}\n\nmessage ResponseOrReference {\n  oneof oneof {\n    Response response = 1;\n    Reference reference = 2;\n  }\n}\n\n// A container for the expected responses of an operation. The container maps a HTTP response code to the expected response.  The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors.  The `default` MAY be used as a default response object for all HTTP codes  that are not covered individually by the specification.  The `Responses Object` MUST contain at least one response code, and it  SHOULD be the response for a successful operation call.\nmessage Responses {\n  ResponseOrReference default = 1;\n  repeated NamedResponseOrReference response_or_reference = 2;\n  repeated NamedAny specification_extension = 3;\n}\n\nmessage ResponsesOrReferences {\n  repeated NamedResponseOrReference additional_properties = 1;\n}\n\n// The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00.  For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.\nmessage Schema {\n  bool nullable = 1;\n  Discriminator discriminator = 2;\n  bool read_only = 3;\n  bool write_only = 4;\n  Xml xml = 5;\n  ExternalDocs external_docs = 6;\n  Any example = 7;\n  bool deprecated = 8;\n  string title = 9;\n  double multiple_of = 10;\n  double maximum = 11;\n  bool exclusive_maximum = 12;\n  double minimum = 13;\n  bool exclusive_minimum = 14;\n  int64 max_length = 15;\n  int64 min_length = 16;\n  string pattern = 17;\n  int64 max_items = 18;\n  int64 min_items = 19;\n  bool unique_items = 20;\n  int64 max_properties = 21;\n  int64 min_properties = 22;\n  repeated string required = 23;\n  repeated Any enum = 24;\n  string type = 25;\n  repeated SchemaOrReference all_of = 26;\n  repeated SchemaOrReference one_of = 27;\n  repeated SchemaOrReference any_of = 28;\n  Schema not = 29;\n  ItemsItem items = 30;\n  Properties properties = 31;\n  AdditionalPropertiesItem additional_properties = 32;\n  DefaultType default = 33;\n  string description = 34;\n  string format = 35;\n  repeated NamedAny specification_extension = 36;\n}\n\nmessage SchemaOrReference {\n  oneof oneof {\n    Schema schema = 1;\n    Reference reference = 2;\n  }\n}\n\nmessage SchemasOrReferences {\n  repeated NamedSchemaOrReference additional_properties = 1;\n}\n\n// Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object.  Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information.  When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the Security Requirement Objects in the list needs to be satisfied to authorize the request.\nmessage SecurityRequirement {\n  repeated NamedStringArray additional_properties = 1;\n}\n\n// Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter), mutual TLS (use of a client certificate), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect.   Please note that currently (2019) the implicit flow is about to be deprecated OAuth 2.0 Security Best Current Practice. Recommended for most use case is Authorization Code Grant flow with PKCE.\nmessage SecurityScheme {\n  string type = 1;\n  string description = 2;\n  string name = 3;\n  string in = 4;\n  string scheme = 5;\n  string bearer_format = 6;\n  OauthFlows flows = 7;\n  string open_id_connect_url = 8;\n  repeated NamedAny specification_extension = 9;\n}\n\nmessage SecuritySchemeOrReference {\n  oneof oneof {\n    SecurityScheme security_scheme = 1;\n    Reference reference = 2;\n  }\n}\n\nmessage SecuritySchemesOrReferences {\n  repeated NamedSecuritySchemeOrReference additional_properties = 1;\n}\n\n// An object representing a Server.\nmessage Server {\n  string url = 1;\n  string description = 2;\n  ServerVariables variables = 3;\n  repeated NamedAny specification_extension = 4;\n}\n\n// An object representing a Server Variable for server URL template substitution.\nmessage ServerVariable {\n  repeated string enum = 1;\n  string default = 2;\n  string description = 3;\n  repeated NamedAny specification_extension = 4;\n}\n\nmessage ServerVariables {\n  repeated NamedServerVariable additional_properties = 1;\n}\n\n// Any property starting with x- is valid.\nmessage SpecificationExtension {\n  oneof oneof {\n    double number = 1;\n    bool boolean = 2;\n    string string = 3;\n  }\n}\n\nmessage StringArray {\n  repeated string value = 1;\n}\n\nmessage Strings {\n  repeated NamedString additional_properties = 1;\n}\n\n// Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.\nmessage Tag {\n  string name = 1;\n  string description = 2;\n  ExternalDocs external_docs = 3;\n  repeated NamedAny specification_extension = 4;\n}\n\n// A metadata object that allows for more fine-tuned XML model definitions.  When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.\nmessage Xml {\n  string name = 1;\n  string namespace = 2;\n  string prefix = 3;\n  bool attribute = 4;\n  bool wrapped = 5;\n  repeated NamedAny specification_extension = 6;\n}\n\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv3/README.md",
    "content": "# OpenAPI v3 Protocol Buffer Models\n\nThis directory contains a Protocol Buffer-language model and related code for\nsupporting OpenAPI v3.\n\nGnostic applications and plugins can use OpenAPIv3.proto to generate Protocol\nBuffer support code for their preferred languages.\n\nOpenAPIv3.go is used by Gnostic to read JSON and YAML OpenAPI descriptions into\nthe Protocol Buffer-based datastructures generated from OpenAPIv3.proto.\n\nOpenAPIv3.proto and OpenAPIv3.go are generated by the Gnostic compiler\ngenerator, and OpenAPIv3.pb.go is generated by protoc, the Protocol Buffer\ncompiler, and protoc-gen-go, the Protocol Buffer Go code generation plugin.\n\nopenapi-3.1.json is a JSON schema for OpenAPI 3.1 that is automatically\ngenerated from the OpenAPI 3.1 specification. It is not an official JSON Schema\nfor OpenAPI.\n\nThe schema-generator directory contains support code which generates\nopenapi-3.1.json from the OpenAPI 3.1 specification document (Markdown).\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv3/document.go",
    "content": "// Copyright 2020 Google LLC. All Rights Reserved.\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//    http://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\npackage openapi_v3\n\nimport (\n\t\"gopkg.in/yaml.v3\"\n\n\t\"github.com/google/gnostic/compiler\"\n)\n\n// ParseDocument reads an OpenAPI v3 description from a YAML/JSON representation.\nfunc ParseDocument(b []byte) (*Document, error) {\n\tinfo, err := compiler.ReadInfoFromBytes(\"\", b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\troot := info.Content[0]\n\treturn NewDocument(root, compiler.NewContextWithExtensions(\"$root\", root, nil, nil))\n}\n\n// YAMLValue produces a serialized YAML representation of the document.\nfunc (d *Document) YAMLValue(comment string) ([]byte, error) {\n\trawInfo := d.ToRawInfo()\n\trawInfo = &yaml.Node{\n\t\tKind:        yaml.DocumentNode,\n\t\tContent:     []*yaml.Node{rawInfo},\n\t\tHeadComment: comment,\n\t}\n\treturn yaml.Marshal(rawInfo)\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv3/openapi-3.0.json",
    "content": "{\n  \"title\": \"A JSON Schema for OpenAPI 3.0.\",\n  \"id\": \"http://openapis.org/v3/schema.json#\",\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"type\": \"object\",\n  \"description\": \"This is the root document object of the OpenAPI document.\",\n  \"required\": [\n    \"openapi\",\n    \"info\",\n    \"paths\"\n  ],\n  \"additionalProperties\": false,\n  \"patternProperties\": {\n    \"^x-\": {\n      \"$ref\": \"#/definitions/specificationExtension\"\n    }\n  },\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\"\n    },\n    \"info\": {\n      \"$ref\": \"#/definitions/info\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/server\"\n      },\n      \"uniqueItems\": true\n    },\n    \"paths\": {\n      \"$ref\": \"#/definitions/paths\"\n    },\n    \"components\": {\n      \"$ref\": \"#/definitions/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/securityRequirement\"\n      },\n      \"uniqueItems\": true\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/tag\"\n      },\n      \"uniqueItems\": true\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/definitions/externalDocs\"\n    }\n  },\n  \"definitions\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"description\": \"The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.\",\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/definitions/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/definitions/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"description\": \"Contact information for the exposed API.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      }\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"description\": \"License information for the exposed API.\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"server\": {\n      \"type\": \"object\",\n      \"description\": \"An object representing a Server.\",\n      \"required\": [\n        \"url\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"$ref\": \"#/definitions/serverVariables\"\n        }\n      }\n    },\n    \"serverVariable\": {\n      \"type\": \"object\",\n      \"description\": \"An object representing a Server Variable for server URL template substitution.\",\n      \"required\": [\n        \"default\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"uniqueItems\": true\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"components\": {\n      \"type\": \"object\",\n      \"description\": \"Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"schemas\": {\n          \"$ref\": \"#/definitions/schemasOrReferences\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/responsesOrReferences\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/parametersOrReferences\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"requestBodies\": {\n          \"$ref\": \"#/definitions/requestBodiesOrReferences\"\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headersOrReferences\"\n        },\n        \"securitySchemes\": {\n          \"$ref\": \"#/definitions/securitySchemesOrReferences\"\n        },\n        \"links\": {\n          \"$ref\": \"#/definitions/linksOrReferences\"\n        },\n        \"callbacks\": {\n          \"$ref\": \"#/definitions/callbacksOrReferences\"\n        }\n      }\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"description\": \"Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL.  The Paths MAY be empty, due to ACL constraints.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/definitions/pathItem\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      }\n    },\n    \"pathItem\": {\n      \"type\": \"object\",\n      \"description\": \"Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"get\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/server\"\n          },\n          \"uniqueItems\": true\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/parameterOrReference\"\n          },\n          \"uniqueItems\": true\n        }\n      }\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single API operation on a path.\",\n      \"required\": [\n        \"responses\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"uniqueItems\": true\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/parameterOrReference\"\n          },\n          \"uniqueItems\": true\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/definitions/requestBodyOrReference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/responses\"\n        },\n        \"callbacks\": {\n          \"$ref\": \"#/definitions/callbacksOrReferences\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/securityRequirement\"\n          },\n          \"uniqueItems\": true\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/server\"\n          },\n          \"uniqueItems\": true\n        }\n      }\n    },\n    \"externalDocs\": {\n      \"type\": \"object\",\n      \"description\": \"Allows referencing an external resource for extended documentation.\",\n      \"required\": [\n        \"url\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"parameter\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single operation parameter.  A unique parameter is defined by a combination of a name and location.\",\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\"\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$ref\": \"#/definitions/schemaOrReference\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        }\n      }\n    },\n    \"requestBody\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single request body.\",\n      \"required\": [\n        \"content\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        },\n        \"required\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"mediaType\": {\n      \"type\": \"object\",\n      \"description\": \"Each Media Type Object provides schema and examples for the media type identified by its key.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"schema\": {\n          \"$ref\": \"#/definitions/schemaOrReference\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"encoding\": {\n          \"$ref\": \"#/definitions/encodings\"\n        }\n      }\n    },\n    \"encoding\": {\n      \"type\": \"object\",\n      \"description\": \"A single encoding definition applied to a single schema property.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headersOrReferences\"\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"description\": \"A container for the expected responses of an operation. The container maps a HTTP response code to the expected response.  The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors.  The `default` MAY be used as a default response object for all HTTP codes  that are not covered individually by the specification.  The `Responses Object` MUST contain at least one response code, and it  SHOULD be the response for a successful operation call.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^([0-9X]{3})$\": {\n          \"$ref\": \"#/definitions/responseOrReference\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/definitions/responseOrReference\"\n        }\n      }\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single response from an API Operation, including design-time, static  `links` to operations based on the response.\",\n      \"required\": [\n        \"description\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headersOrReferences\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        },\n        \"links\": {\n          \"$ref\": \"#/definitions/linksOrReferences\"\n        }\n      }\n    },\n    \"callback\": {\n      \"type\": \"object\",\n      \"description\": \"A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^\": {\n          \"$ref\": \"#/definitions/pathItem\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      }\n    },\n    \"example\": {\n      \"type\": \"object\",\n      \"description\": \"\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"externalValue\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"link\": {\n      \"type\": \"object\",\n      \"description\": \"The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.  Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response.  For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/anysOrExpressions\"\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/definitions/anyOrExpression\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"server\": {\n          \"$ref\": \"#/definitions/server\"\n        }\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"description\": \"The Header Object follows the structure of the Parameter Object with the following changes:  1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\"\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$ref\": \"#/definitions/schemaOrReference\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        }\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"description\": \"Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        }\n      }\n    },\n    \"reference\": {\n      \"type\": \"object\",\n      \"description\": \"A simple object to allow referencing other components in the specification, internally and externally.  The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules.   For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.\",\n      \"required\": [\n        \"$ref\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"schema\": {\n      \"type\": \"object\",\n      \"description\": \"The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00.  For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"nullable\": {\n          \"type\": \"boolean\"\n        },\n        \"discriminator\": {\n          \"$ref\": \"#/definitions/discriminator\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"writeOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"xml\": {\n          \"$ref\": \"#/definitions/xml\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"title\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/multipleOf\"\n        },\n        \"maximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/uniqueItems\"\n        },\n        \"maxProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maxProperties\"\n        },\n        \"minProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minProperties\"\n        },\n        \"required\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/required\"\n        },\n        \"enum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/enum\"\n        },\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"allOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          },\n          \"minItems\": 1\n        },\n        \"oneOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          },\n          \"minItems\": 1\n        },\n        \"anyOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          },\n          \"minItems\": 1\n        },\n        \"not\": {\n          \"$ref\": \"#/definitions/schema\"\n        },\n        \"items\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/schemaOrReference\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/schemaOrReference\"\n              },\n              \"minItems\": 1\n            }\n          ]\n        },\n        \"properties\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          }\n        },\n        \"additionalProperties\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/schemaOrReference\"\n            },\n            {\n              \"type\": \"boolean\"\n            }\n          ]\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/defaultType\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"format\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"discriminator\": {\n      \"type\": \"object\",\n      \"description\": \"When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation.  The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it.  When using the discriminator, _inline_ schemas will not be considered.\",\n      \"required\": [\n        \"propertyName\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"propertyName\": {\n          \"type\": \"string\"\n        },\n        \"mapping\": {\n          \"$ref\": \"#/definitions/strings\"\n        }\n      }\n    },\n    \"xml\": {\n      \"type\": \"object\",\n      \"description\": \"A metadata object that allows for more fine-tuned XML model definitions.  When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"type\": \"string\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"attribute\": {\n          \"type\": \"boolean\"\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"securityScheme\": {\n      \"type\": \"object\",\n      \"description\": \"Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header or as a query parameter), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect Discovery.\",\n      \"required\": [\n        \"type\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\"\n        },\n        \"scheme\": {\n          \"type\": \"string\"\n        },\n        \"bearerFormat\": {\n          \"type\": \"string\"\n        },\n        \"flows\": {\n          \"$ref\": \"#/definitions/oauthFlows\"\n        },\n        \"openIdConnectUrl\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"oauthFlows\": {\n      \"type\": \"object\",\n      \"description\": \"Allows configuration of the supported OAuth Flows.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        },\n        \"password\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        }\n      }\n    },\n    \"oauthFlow\": {\n      \"type\": \"object\",\n      \"description\": \"Configuration details for a supported OAuth Flow\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"authorizationUrl\": {\n          \"type\": \"string\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\"\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/strings\"\n        }\n      }\n    },\n    \"securityRequirement\": {\n      \"type\": \"object\",\n      \"description\": \"Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object.  Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information.  When a list of Security Requirement Objects is defined on the Open API object or Operation Object, only one of Security Requirement Objects in the list needs to be satisfied to authorize the request.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^[a-zA-Z0-9\\\\.\\\\-_]+$\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"uniqueItems\": true\n        }\n      }\n    },\n    \"anyOrExpression\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/any\"\n        },\n        {\n          \"$ref\": \"#/definitions/expression\"\n        }\n      ]\n    },\n    \"callbackOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/callback\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"exampleOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/example\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"headerOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/header\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"linkOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/link\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"parameterOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/parameter\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"requestBodyOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/requestBody\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"responseOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/response\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"schemaOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/schema\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"securitySchemeOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/securityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"anysOrExpressions\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/anyOrExpression\"\n      }\n    },\n    \"callbacksOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/callbackOrReference\"\n      }\n    },\n    \"encodings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/encoding\"\n      }\n    },\n    \"examplesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/exampleOrReference\"\n      }\n    },\n    \"headersOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/headerOrReference\"\n      }\n    },\n    \"linksOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/linkOrReference\"\n      }\n    },\n    \"mediaTypes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/mediaType\"\n      }\n    },\n    \"parametersOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/parameterOrReference\"\n      }\n    },\n    \"requestBodiesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/requestBodyOrReference\"\n      }\n    },\n    \"responsesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/responseOrReference\"\n      }\n    },\n    \"schemasOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/schemaOrReference\"\n      }\n    },\n    \"securitySchemesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/securitySchemeOrReference\"\n      }\n    },\n    \"serverVariables\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/serverVariable\"\n      }\n    },\n    \"strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"object\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true\n    },\n    \"any\": {\n      \"additionalProperties\": true\n    },\n    \"expression\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true\n    },\n    \"specificationExtension\": {\n      \"description\": \"Any property starting with x- is valid.\",\n      \"oneOf\": [\n        {\n          \"type\": \"null\"\n        },\n        {\n          \"type\": \"number\"\n        },\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"object\"\n        },\n        {\n          \"type\": \"array\"\n        }\n      ]\n    },\n    \"defaultType\": {\n      \"oneOf\": [\n        {\n          \"type\": \"null\"\n        },\n        {\n          \"type\": \"array\"\n        },\n        {\n          \"type\": \"object\"\n        },\n        {\n          \"type\": \"number\"\n        },\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/github.com/google/gnostic/openapiv3/openapi-3.1.json",
    "content": "{\n  \"title\": \"A JSON Schema for OpenAPI 3.0.\",\n  \"id\": \"http://openapis.org/v3/schema.json#\",\n  \"$schema\": \"http://json-schema.org/draft-04/schema#\",\n  \"type\": \"object\",\n  \"description\": \"This is the root document object of the OpenAPI document.\",\n  \"required\": [\n    \"openapi\",\n    \"info\",\n    \"paths\"\n  ],\n  \"additionalProperties\": false,\n  \"patternProperties\": {\n    \"^x-\": {\n      \"$ref\": \"#/definitions/specificationExtension\"\n    }\n  },\n  \"properties\": {\n    \"openapi\": {\n      \"type\": \"string\"\n    },\n    \"info\": {\n      \"$ref\": \"#/definitions/info\"\n    },\n    \"servers\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/server\"\n      },\n      \"uniqueItems\": true\n    },\n    \"paths\": {\n      \"$ref\": \"#/definitions/paths\"\n    },\n    \"components\": {\n      \"$ref\": \"#/definitions/components\"\n    },\n    \"security\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/securityRequirement\"\n      },\n      \"uniqueItems\": true\n    },\n    \"tags\": {\n      \"type\": \"array\",\n      \"items\": {\n        \"$ref\": \"#/definitions/tag\"\n      },\n      \"uniqueItems\": true\n    },\n    \"externalDocs\": {\n      \"$ref\": \"#/definitions/externalDocs\"\n    }\n  },\n  \"definitions\": {\n    \"info\": {\n      \"type\": \"object\",\n      \"description\": \"The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.\",\n      \"required\": [\n        \"title\",\n        \"version\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"title\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"termsOfService\": {\n          \"type\": \"string\"\n        },\n        \"contact\": {\n          \"$ref\": \"#/definitions/contact\"\n        },\n        \"license\": {\n          \"$ref\": \"#/definitions/license\"\n        },\n        \"version\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"contact\": {\n      \"type\": \"object\",\n      \"description\": \"Contact information for the exposed API.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\",\n          \"format\": \"uri\"\n        },\n        \"email\": {\n          \"type\": \"string\",\n          \"format\": \"email\"\n        }\n      }\n    },\n    \"license\": {\n      \"type\": \"object\",\n      \"description\": \"License information for the exposed API.\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"server\": {\n      \"type\": \"object\",\n      \"description\": \"An object representing a Server.\",\n      \"required\": [\n        \"url\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"url\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"variables\": {\n          \"$ref\": \"#/definitions/serverVariables\"\n        }\n      }\n    },\n    \"serverVariable\": {\n      \"type\": \"object\",\n      \"description\": \"An object representing a Server Variable for server URL template substitution.\",\n      \"required\": [\n        \"default\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"enum\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"uniqueItems\": true\n        },\n        \"default\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"components\": {\n      \"type\": \"object\",\n      \"description\": \"Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"schemas\": {\n          \"$ref\": \"#/definitions/schemasOrReferences\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/responsesOrReferences\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/parametersOrReferences\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"requestBodies\": {\n          \"$ref\": \"#/definitions/requestBodiesOrReferences\"\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headersOrReferences\"\n        },\n        \"securitySchemes\": {\n          \"$ref\": \"#/definitions/securitySchemesOrReferences\"\n        },\n        \"links\": {\n          \"$ref\": \"#/definitions/linksOrReferences\"\n        },\n        \"callbacks\": {\n          \"$ref\": \"#/definitions/callbacksOrReferences\"\n        }\n      }\n    },\n    \"paths\": {\n      \"type\": \"object\",\n      \"description\": \"Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL.  The Paths MAY be empty, due to ACL constraints.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^/\": {\n          \"$ref\": \"#/definitions/pathItem\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      }\n    },\n    \"pathItem\": {\n      \"type\": \"object\",\n      \"description\": \"Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"get\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"put\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"post\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"delete\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"options\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"head\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"patch\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"trace\": {\n          \"$ref\": \"#/definitions/operation\"\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/server\"\n          },\n          \"uniqueItems\": true\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/parameterOrReference\"\n          },\n          \"uniqueItems\": true\n        }\n      }\n    },\n    \"operation\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single API operation on a path.\",\n      \"required\": [\n        \"responses\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"tags\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"type\": \"string\"\n          },\n          \"uniqueItems\": true\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/parameterOrReference\"\n          },\n          \"uniqueItems\": true\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/definitions/requestBodyOrReference\"\n        },\n        \"responses\": {\n          \"$ref\": \"#/definitions/responses\"\n        },\n        \"callbacks\": {\n          \"$ref\": \"#/definitions/callbacksOrReferences\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"security\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/securityRequirement\"\n          },\n          \"uniqueItems\": true\n        },\n        \"servers\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/server\"\n          },\n          \"uniqueItems\": true\n        }\n      }\n    },\n    \"externalDocs\": {\n      \"type\": \"object\",\n      \"description\": \"Allows referencing an external resource for extended documentation.\",\n      \"required\": [\n        \"url\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"url\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"parameter\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single operation parameter.  A unique parameter is defined by a combination of a name and location.\",\n      \"required\": [\n        \"name\",\n        \"in\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\"\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$ref\": \"#/definitions/schemaOrReference\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        }\n      }\n    },\n    \"requestBody\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single request body.\",\n      \"required\": [\n        \"content\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        },\n        \"required\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"mediaType\": {\n      \"type\": \"object\",\n      \"description\": \"Each Media Type Object provides schema and examples for the media type identified by its key.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"schema\": {\n          \"$ref\": \"#/definitions/schemaOrReference\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"encoding\": {\n          \"$ref\": \"#/definitions/encodings\"\n        }\n      }\n    },\n    \"encoding\": {\n      \"type\": \"object\",\n      \"description\": \"A single encoding definition applied to a single schema property.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"contentType\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headersOrReferences\"\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"responses\": {\n      \"type\": \"object\",\n      \"description\": \"A container for the expected responses of an operation. The container maps a HTTP response code to the expected response.  The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors.  The `default` MAY be used as a default response object for all HTTP codes  that are not covered individually by the specification.  The `Responses Object` MUST contain at least one response code, and it  SHOULD be the response for a successful operation call.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^([0-9X]{3})$\": {\n          \"$ref\": \"#/definitions/responseOrReference\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"default\": {\n          \"$ref\": \"#/definitions/responseOrReference\"\n        }\n      }\n    },\n    \"response\": {\n      \"type\": \"object\",\n      \"description\": \"Describes a single response from an API Operation, including design-time, static  `links` to operations based on the response.\",\n      \"required\": [\n        \"description\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"headers\": {\n          \"$ref\": \"#/definitions/headersOrReferences\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        },\n        \"links\": {\n          \"$ref\": \"#/definitions/linksOrReferences\"\n        }\n      }\n    },\n    \"callback\": {\n      \"type\": \"object\",\n      \"description\": \"A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^\": {\n          \"$ref\": \"#/definitions/pathItem\"\n        },\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      }\n    },\n    \"example\": {\n      \"type\": \"object\",\n      \"description\": \"\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"value\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"externalValue\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"link\": {\n      \"type\": \"object\",\n      \"description\": \"The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.  Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response.  For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"operationRef\": {\n          \"type\": \"string\"\n        },\n        \"operationId\": {\n          \"type\": \"string\"\n        },\n        \"parameters\": {\n          \"$ref\": \"#/definitions/anyOrExpression\"\n        },\n        \"requestBody\": {\n          \"$ref\": \"#/definitions/anyOrExpression\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"server\": {\n          \"$ref\": \"#/definitions/server\"\n        }\n      }\n    },\n    \"header\": {\n      \"type\": \"object\",\n      \"description\": \"The Header Object follows the structure of the Parameter Object with the following changes:  1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"required\": {\n          \"type\": \"boolean\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"allowEmptyValue\": {\n          \"type\": \"boolean\"\n        },\n        \"style\": {\n          \"type\": \"string\"\n        },\n        \"explode\": {\n          \"type\": \"boolean\"\n        },\n        \"allowReserved\": {\n          \"type\": \"boolean\"\n        },\n        \"schema\": {\n          \"$ref\": \"#/definitions/schemaOrReference\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"examples\": {\n          \"$ref\": \"#/definitions/examplesOrReferences\"\n        },\n        \"content\": {\n          \"$ref\": \"#/definitions/mediaTypes\"\n        }\n      }\n    },\n    \"tag\": {\n      \"type\": \"object\",\n      \"description\": \"Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.\",\n      \"required\": [\n        \"name\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        }\n      }\n    },\n    \"reference\": {\n      \"type\": \"object\",\n      \"description\": \"A simple object to allow referencing other components in the specification, internally and externally.  The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules.   For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.\",\n      \"required\": [\n        \"$ref\"\n      ],\n      \"additionalProperties\": false,\n      \"properties\": {\n        \"$ref\": {\n          \"type\": \"string\"\n        },\n        \"summary\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"schema\": {\n      \"type\": \"object\",\n      \"description\": \"The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00.  For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"nullable\": {\n          \"type\": \"boolean\"\n        },\n        \"discriminator\": {\n          \"$ref\": \"#/definitions/discriminator\"\n        },\n        \"readOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"writeOnly\": {\n          \"type\": \"boolean\"\n        },\n        \"xml\": {\n          \"$ref\": \"#/definitions/xml\"\n        },\n        \"externalDocs\": {\n          \"$ref\": \"#/definitions/externalDocs\"\n        },\n        \"example\": {\n          \"$ref\": \"#/definitions/any\"\n        },\n        \"deprecated\": {\n          \"type\": \"boolean\"\n        },\n        \"title\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/title\"\n        },\n        \"multipleOf\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/multipleOf\"\n        },\n        \"maximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maximum\"\n        },\n        \"exclusiveMaximum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMaximum\"\n        },\n        \"minimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minimum\"\n        },\n        \"exclusiveMinimum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/exclusiveMinimum\"\n        },\n        \"maxLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maxLength\"\n        },\n        \"minLength\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minLength\"\n        },\n        \"pattern\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/pattern\"\n        },\n        \"maxItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maxItems\"\n        },\n        \"minItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minItems\"\n        },\n        \"uniqueItems\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/uniqueItems\"\n        },\n        \"maxProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/maxProperties\"\n        },\n        \"minProperties\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/minProperties\"\n        },\n        \"required\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/required\"\n        },\n        \"enum\": {\n          \"$ref\": \"http://json-schema.org/draft-04/schema#/properties/enum\"\n        },\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"allOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          },\n          \"minItems\": 1\n        },\n        \"oneOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          },\n          \"minItems\": 1\n        },\n        \"anyOf\": {\n          \"type\": \"array\",\n          \"items\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          },\n          \"minItems\": 1\n        },\n        \"not\": {\n          \"$ref\": \"#/definitions/schema\"\n        },\n        \"items\": {\n          \"anyOf\": [\n            {\n              \"$ref\": \"#/definitions/schemaOrReference\"\n            },\n            {\n              \"type\": \"array\",\n              \"items\": {\n                \"$ref\": \"#/definitions/schemaOrReference\"\n              },\n              \"minItems\": 1\n            }\n          ]\n        },\n        \"properties\": {\n          \"type\": \"object\",\n          \"additionalProperties\": {\n            \"$ref\": \"#/definitions/schemaOrReference\"\n          }\n        },\n        \"additionalProperties\": {\n          \"oneOf\": [\n            {\n              \"$ref\": \"#/definitions/schemaOrReference\"\n            },\n            {\n              \"type\": \"boolean\"\n            }\n          ]\n        },\n        \"default\": {\n          \"$ref\": \"#/definitions/defaultType\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"format\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"discriminator\": {\n      \"type\": \"object\",\n      \"description\": \"When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation.  The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it.  When using the discriminator, _inline_ schemas will not be considered.\",\n      \"required\": [\n        \"propertyName\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"propertyName\": {\n          \"type\": \"string\"\n        },\n        \"mapping\": {\n          \"$ref\": \"#/definitions/strings\"\n        }\n      }\n    },\n    \"xml\": {\n      \"type\": \"object\",\n      \"description\": \"A metadata object that allows for more fine-tuned XML model definitions.  When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"namespace\": {\n          \"type\": \"string\"\n        },\n        \"prefix\": {\n          \"type\": \"string\"\n        },\n        \"attribute\": {\n          \"type\": \"boolean\"\n        },\n        \"wrapped\": {\n          \"type\": \"boolean\"\n        }\n      }\n    },\n    \"securityScheme\": {\n      \"type\": \"object\",\n      \"description\": \"Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header, a cookie parameter or as a query parameter), mutual TLS (use of a client certificate), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect.   Please note that currently (2019) the implicit flow is about to be deprecated OAuth 2.0 Security Best Current Practice. Recommended for most use case is Authorization Code Grant flow with PKCE.\",\n      \"required\": [\n        \"type\"\n      ],\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"type\": {\n          \"type\": \"string\"\n        },\n        \"description\": {\n          \"type\": \"string\"\n        },\n        \"name\": {\n          \"type\": \"string\"\n        },\n        \"in\": {\n          \"type\": \"string\"\n        },\n        \"scheme\": {\n          \"type\": \"string\"\n        },\n        \"bearerFormat\": {\n          \"type\": \"string\"\n        },\n        \"flows\": {\n          \"$ref\": \"#/definitions/oauthFlows\"\n        },\n        \"openIdConnectUrl\": {\n          \"type\": \"string\"\n        }\n      }\n    },\n    \"oauthFlows\": {\n      \"type\": \"object\",\n      \"description\": \"Allows configuration of the supported OAuth Flows.\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"implicit\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        },\n        \"password\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        },\n        \"clientCredentials\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        },\n        \"authorizationCode\": {\n          \"$ref\": \"#/definitions/oauthFlow\"\n        }\n      }\n    },\n    \"oauthFlow\": {\n      \"type\": \"object\",\n      \"description\": \"Configuration details for a supported OAuth Flow\",\n      \"additionalProperties\": false,\n      \"patternProperties\": {\n        \"^x-\": {\n          \"$ref\": \"#/definitions/specificationExtension\"\n        }\n      },\n      \"properties\": {\n        \"authorizationUrl\": {\n          \"type\": \"string\"\n        },\n        \"tokenUrl\": {\n          \"type\": \"string\"\n        },\n        \"refreshUrl\": {\n          \"type\": \"string\"\n        },\n        \"scopes\": {\n          \"$ref\": \"#/definitions/strings\"\n        }\n      }\n    },\n    \"securityRequirement\": {\n      \"type\": \"object\",\n      \"description\": \"Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object.  Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information.  When a list of Security Requirement Objects is defined on the OpenAPI Object or Operation Object, only one of the Security Requirement Objects in the list needs to be satisfied to authorize the request.\",\n      \"additionalProperties\": {\n        \"type\": \"array\",\n        \"items\": {\n          \"type\": \"string\"\n        },\n        \"uniqueItems\": true\n      }\n    },\n    \"anyOrExpression\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/any\"\n        },\n        {\n          \"$ref\": \"#/definitions/expression\"\n        }\n      ]\n    },\n    \"callbackOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/callback\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"exampleOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/example\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"headerOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/header\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"linkOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/link\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"parameterOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/parameter\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"requestBodyOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/requestBody\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"responseOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/response\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"schemaOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/schema\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"securitySchemeOrReference\": {\n      \"oneOf\": [\n        {\n          \"$ref\": \"#/definitions/securityScheme\"\n        },\n        {\n          \"$ref\": \"#/definitions/reference\"\n        }\n      ]\n    },\n    \"callbacksOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/callbackOrReference\"\n      }\n    },\n    \"encodings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/encoding\"\n      }\n    },\n    \"examplesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/exampleOrReference\"\n      }\n    },\n    \"headersOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/headerOrReference\"\n      }\n    },\n    \"linksOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/linkOrReference\"\n      }\n    },\n    \"mediaTypes\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/mediaType\"\n      }\n    },\n    \"parametersOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/parameterOrReference\"\n      }\n    },\n    \"requestBodiesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/requestBodyOrReference\"\n      }\n    },\n    \"responsesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/responseOrReference\"\n      }\n    },\n    \"schemasOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/schemaOrReference\"\n      }\n    },\n    \"securitySchemesOrReferences\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/securitySchemeOrReference\"\n      }\n    },\n    \"serverVariables\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"$ref\": \"#/definitions/serverVariable\"\n      }\n    },\n    \"strings\": {\n      \"type\": \"object\",\n      \"additionalProperties\": {\n        \"type\": \"string\"\n      }\n    },\n    \"object\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true\n    },\n    \"any\": {\n      \"additionalProperties\": true\n    },\n    \"expression\": {\n      \"type\": \"object\",\n      \"additionalProperties\": true\n    },\n    \"specificationExtension\": {\n      \"description\": \"Any property starting with x- is valid.\",\n      \"oneOf\": [\n        {\n          \"type\": \"null\"\n        },\n        {\n          \"type\": \"number\"\n        },\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"type\": \"string\"\n        },\n        {\n          \"type\": \"object\"\n        },\n        {\n          \"type\": \"array\"\n        }\n      ]\n    },\n    \"defaultType\": {\n      \"oneOf\": [\n        {\n          \"type\": \"null\"\n        },\n        {\n          \"type\": \"array\"\n        },\n        {\n          \"type\": \"object\"\n        },\n        {\n          \"type\": \"number\"\n        },\n        {\n          \"type\": \"boolean\"\n        },\n        {\n          \"type\": \"string\"\n        }\n      ]\n    }\n  }\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/LICENSE",
    "content": "Copyright (c) 2017 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/google/go-cmp/cmp/compare.go",
    "content": "// Copyright 2017, 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// Package cmp determines equality of values.\n//\n// This package is intended to be a more powerful and safer alternative to\n// [reflect.DeepEqual] for comparing whether two values are semantically equal.\n// It is intended to only be used in tests, as performance is not a goal and\n// it may panic if it cannot compare the values. Its propensity towards\n// panicking means that its unsuitable for production environments where a\n// spurious panic may be fatal.\n//\n// The primary features of cmp are:\n//\n//   - When the default behavior of equality does not suit the test's needs,\n//     custom equality functions can override the equality operation.\n//     For example, an equality function may report floats as equal so long as\n//     they are within some tolerance of each other.\n//\n//   - Types with an Equal method (e.g., [time.Time.Equal]) may use that method\n//     to determine equality. This allows package authors to determine\n//     the equality operation for the types that they define.\n//\n//   - If no custom equality functions are used and no Equal method is defined,\n//     equality is determined by recursively comparing the primitive kinds on\n//     both values, much like [reflect.DeepEqual]. Unlike [reflect.DeepEqual],\n//     unexported fields are not compared by default; they result in panics\n//     unless suppressed by using an [Ignore] option\n//     (see [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported])\n//     or explicitly compared using the [Exporter] option.\npackage cmp\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/google/go-cmp/cmp/internal/diff\"\n\t\"github.com/google/go-cmp/cmp/internal/function\"\n\t\"github.com/google/go-cmp/cmp/internal/value\"\n)\n\n// TODO(≥go1.18): Use any instead of interface{}.\n\n// Equal reports whether x and y are equal by recursively applying the\n// following rules in the given order to x and y and all of their sub-values:\n//\n//   - Let S be the set of all [Ignore], [Transformer], and [Comparer] options that\n//     remain after applying all path filters, value filters, and type filters.\n//     If at least one [Ignore] exists in S, then the comparison is ignored.\n//     If the number of [Transformer] and [Comparer] options in S is non-zero,\n//     then Equal panics because it is ambiguous which option to use.\n//     If S contains a single [Transformer], then use that to transform\n//     the current values and recursively call Equal on the output values.\n//     If S contains a single [Comparer], then use that to compare the current values.\n//     Otherwise, evaluation proceeds to the next rule.\n//\n//   - If the values have an Equal method of the form \"(T) Equal(T) bool\" or\n//     \"(T) Equal(I) bool\" where T is assignable to I, then use the result of\n//     x.Equal(y) even if x or y is nil. Otherwise, no such method exists and\n//     evaluation proceeds to the next rule.\n//\n//   - Lastly, try to compare x and y based on their basic kinds.\n//     Simple kinds like booleans, integers, floats, complex numbers, strings,\n//     and channels are compared using the equivalent of the == operator in Go.\n//     Functions are only equal if they are both nil, otherwise they are unequal.\n//\n// Structs are equal if recursively calling Equal on all fields report equal.\n// If a struct contains unexported fields, Equal panics unless an [Ignore] option\n// (e.g., [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported]) ignores that field\n// or the [Exporter] option explicitly permits comparing the unexported field.\n//\n// Slices are equal if they are both nil or both non-nil, where recursively\n// calling Equal on all non-ignored slice or array elements report equal.\n// Empty non-nil slices and nil slices are not equal; to equate empty slices,\n// consider using [github.com/google/go-cmp/cmp/cmpopts.EquateEmpty].\n//\n// Maps are equal if they are both nil or both non-nil, where recursively\n// calling Equal on all non-ignored map entries report equal.\n// Map keys are equal according to the == operator.\n// To use custom comparisons for map keys, consider using\n// [github.com/google/go-cmp/cmp/cmpopts.SortMaps].\n// Empty non-nil maps and nil maps are not equal; to equate empty maps,\n// consider using [github.com/google/go-cmp/cmp/cmpopts.EquateEmpty].\n//\n// Pointers and interfaces are equal if they are both nil or both non-nil,\n// where they have the same underlying concrete type and recursively\n// calling Equal on the underlying values reports equal.\n//\n// Before recursing into a pointer, slice element, or map, the current path\n// is checked to detect whether the address has already been visited.\n// If there is a cycle, then the pointed at values are considered equal\n// only if both addresses were previously visited in the same path step.\nfunc Equal(x, y interface{}, opts ...Option) bool {\n\ts := newState(opts)\n\ts.compareAny(rootStep(x, y))\n\treturn s.result.Equal()\n}\n\n// Diff returns a human-readable report of the differences between two values:\n// y - x. It returns an empty string if and only if Equal returns true for the\n// same input values and options.\n//\n// The output is displayed as a literal in pseudo-Go syntax.\n// At the start of each line, a \"-\" prefix indicates an element removed from x,\n// a \"+\" prefix to indicates an element added from y, and the lack of a prefix\n// indicates an element common to both x and y. If possible, the output\n// uses fmt.Stringer.String or error.Error methods to produce more humanly\n// readable outputs. In such cases, the string is prefixed with either an\n// 's' or 'e' character, respectively, to indicate that the method was called.\n//\n// Do not depend on this output being stable. If you need the ability to\n// programmatically interpret the difference, consider using a custom Reporter.\nfunc Diff(x, y interface{}, opts ...Option) string {\n\ts := newState(opts)\n\n\t// Optimization: If there are no other reporters, we can optimize for the\n\t// common case where the result is equal (and thus no reported difference).\n\t// This avoids the expensive construction of a difference tree.\n\tif len(s.reporters) == 0 {\n\t\ts.compareAny(rootStep(x, y))\n\t\tif s.result.Equal() {\n\t\t\treturn \"\"\n\t\t}\n\t\ts.result = diff.Result{} // Reset results\n\t}\n\n\tr := new(defaultReporter)\n\ts.reporters = append(s.reporters, reporter{r})\n\ts.compareAny(rootStep(x, y))\n\td := r.String()\n\tif (d == \"\") != s.result.Equal() {\n\t\tpanic(\"inconsistent difference and equality results\")\n\t}\n\treturn d\n}\n\n// rootStep constructs the first path step. If x and y have differing types,\n// then they are stored within an empty interface type.\nfunc rootStep(x, y interface{}) PathStep {\n\tvx := reflect.ValueOf(x)\n\tvy := reflect.ValueOf(y)\n\n\t// If the inputs are different types, auto-wrap them in an empty interface\n\t// so that they have the same parent type.\n\tvar t reflect.Type\n\tif !vx.IsValid() || !vy.IsValid() || vx.Type() != vy.Type() {\n\t\tt = anyType\n\t\tif vx.IsValid() {\n\t\t\tvvx := reflect.New(t).Elem()\n\t\t\tvvx.Set(vx)\n\t\t\tvx = vvx\n\t\t}\n\t\tif vy.IsValid() {\n\t\t\tvvy := reflect.New(t).Elem()\n\t\t\tvvy.Set(vy)\n\t\t\tvy = vvy\n\t\t}\n\t} else {\n\t\tt = vx.Type()\n\t}\n\n\treturn &pathStep{t, vx, vy}\n}\n\ntype state struct {\n\t// These fields represent the \"comparison state\".\n\t// Calling statelessCompare must not result in observable changes to these.\n\tresult    diff.Result // The current result of comparison\n\tcurPath   Path        // The current path in the value tree\n\tcurPtrs   pointerPath // The current set of visited pointers\n\treporters []reporter  // Optional reporters\n\n\t// recChecker checks for infinite cycles applying the same set of\n\t// transformers upon the output of itself.\n\trecChecker recChecker\n\n\t// dynChecker triggers pseudo-random checks for option correctness.\n\t// It is safe for statelessCompare to mutate this value.\n\tdynChecker dynChecker\n\n\t// These fields, once set by processOption, will not change.\n\texporters []exporter // List of exporters for structs with unexported fields\n\topts      Options    // List of all fundamental and filter options\n}\n\nfunc newState(opts []Option) *state {\n\t// Always ensure a validator option exists to validate the inputs.\n\ts := &state{opts: Options{validator{}}}\n\ts.curPtrs.Init()\n\ts.processOption(Options(opts))\n\treturn s\n}\n\nfunc (s *state) processOption(opt Option) {\n\tswitch opt := opt.(type) {\n\tcase nil:\n\tcase Options:\n\t\tfor _, o := range opt {\n\t\t\ts.processOption(o)\n\t\t}\n\tcase coreOption:\n\t\ttype filtered interface {\n\t\t\tisFiltered() bool\n\t\t}\n\t\tif fopt, ok := opt.(filtered); ok && !fopt.isFiltered() {\n\t\t\tpanic(fmt.Sprintf(\"cannot use an unfiltered option: %v\", opt))\n\t\t}\n\t\ts.opts = append(s.opts, opt)\n\tcase exporter:\n\t\ts.exporters = append(s.exporters, opt)\n\tcase reporter:\n\t\ts.reporters = append(s.reporters, opt)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown option %T\", opt))\n\t}\n}\n\n// statelessCompare compares two values and returns the result.\n// This function is stateless in that it does not alter the current result,\n// or output to any registered reporters.\nfunc (s *state) statelessCompare(step PathStep) diff.Result {\n\t// We do not save and restore curPath and curPtrs because all of the\n\t// compareX methods should properly push and pop from them.\n\t// It is an implementation bug if the contents of the paths differ from\n\t// when calling this function to when returning from it.\n\n\toldResult, oldReporters := s.result, s.reporters\n\ts.result = diff.Result{} // Reset result\n\ts.reporters = nil        // Remove reporters to avoid spurious printouts\n\ts.compareAny(step)\n\tres := s.result\n\ts.result, s.reporters = oldResult, oldReporters\n\treturn res\n}\n\nfunc (s *state) compareAny(step PathStep) {\n\t// Update the path stack.\n\ts.curPath.push(step)\n\tdefer s.curPath.pop()\n\tfor _, r := range s.reporters {\n\t\tr.PushStep(step)\n\t\tdefer r.PopStep()\n\t}\n\ts.recChecker.Check(s.curPath)\n\n\t// Cycle-detection for slice elements (see NOTE in compareSlice).\n\tt := step.Type()\n\tvx, vy := step.Values()\n\tif si, ok := step.(SliceIndex); ok && si.isSlice && vx.IsValid() && vy.IsValid() {\n\t\tpx, py := vx.Addr(), vy.Addr()\n\t\tif eq, visited := s.curPtrs.Push(px, py); visited {\n\t\t\ts.report(eq, reportByCycle)\n\t\t\treturn\n\t\t}\n\t\tdefer s.curPtrs.Pop(px, py)\n\t}\n\n\t// Rule 1: Check whether an option applies on this node in the value tree.\n\tif s.tryOptions(t, vx, vy) {\n\t\treturn\n\t}\n\n\t// Rule 2: Check whether the type has a valid Equal method.\n\tif s.tryMethod(t, vx, vy) {\n\t\treturn\n\t}\n\n\t// Rule 3: Compare based on the underlying kind.\n\tswitch t.Kind() {\n\tcase reflect.Bool:\n\t\ts.report(vx.Bool() == vy.Bool(), 0)\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\ts.report(vx.Int() == vy.Int(), 0)\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\ts.report(vx.Uint() == vy.Uint(), 0)\n\tcase reflect.Float32, reflect.Float64:\n\t\ts.report(vx.Float() == vy.Float(), 0)\n\tcase reflect.Complex64, reflect.Complex128:\n\t\ts.report(vx.Complex() == vy.Complex(), 0)\n\tcase reflect.String:\n\t\ts.report(vx.String() == vy.String(), 0)\n\tcase reflect.Chan, reflect.UnsafePointer:\n\t\ts.report(vx.Pointer() == vy.Pointer(), 0)\n\tcase reflect.Func:\n\t\ts.report(vx.IsNil() && vy.IsNil(), 0)\n\tcase reflect.Struct:\n\t\ts.compareStruct(t, vx, vy)\n\tcase reflect.Slice, reflect.Array:\n\t\ts.compareSlice(t, vx, vy)\n\tcase reflect.Map:\n\t\ts.compareMap(t, vx, vy)\n\tcase reflect.Ptr:\n\t\ts.comparePtr(t, vx, vy)\n\tcase reflect.Interface:\n\t\ts.compareInterface(t, vx, vy)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"%v kind not handled\", t.Kind()))\n\t}\n}\n\nfunc (s *state) tryOptions(t reflect.Type, vx, vy reflect.Value) bool {\n\t// Evaluate all filters and apply the remaining options.\n\tif opt := s.opts.filter(s, t, vx, vy); opt != nil {\n\t\topt.apply(s, vx, vy)\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (s *state) tryMethod(t reflect.Type, vx, vy reflect.Value) bool {\n\t// Check if this type even has an Equal method.\n\tm, ok := t.MethodByName(\"Equal\")\n\tif !ok || !function.IsType(m.Type, function.EqualAssignable) {\n\t\treturn false\n\t}\n\n\teq := s.callTTBFunc(m.Func, vx, vy)\n\ts.report(eq, reportByMethod)\n\treturn true\n}\n\nfunc (s *state) callTRFunc(f, v reflect.Value, step Transform) reflect.Value {\n\tif !s.dynChecker.Next() {\n\t\treturn f.Call([]reflect.Value{v})[0]\n\t}\n\n\t// Run the function twice and ensure that we get the same results back.\n\t// We run in goroutines so that the race detector (if enabled) can detect\n\t// unsafe mutations to the input.\n\tc := make(chan reflect.Value)\n\tgo detectRaces(c, f, v)\n\tgot := <-c\n\twant := f.Call([]reflect.Value{v})[0]\n\tif step.vx, step.vy = got, want; !s.statelessCompare(step).Equal() {\n\t\t// To avoid false-positives with non-reflexive equality operations,\n\t\t// we sanity check whether a value is equal to itself.\n\t\tif step.vx, step.vy = want, want; !s.statelessCompare(step).Equal() {\n\t\t\treturn want\n\t\t}\n\t\tpanic(fmt.Sprintf(\"non-deterministic function detected: %s\", function.NameOf(f)))\n\t}\n\treturn want\n}\n\nfunc (s *state) callTTBFunc(f, x, y reflect.Value) bool {\n\tif !s.dynChecker.Next() {\n\t\treturn f.Call([]reflect.Value{x, y})[0].Bool()\n\t}\n\n\t// Swapping the input arguments is sufficient to check that\n\t// f is symmetric and deterministic.\n\t// We run in goroutines so that the race detector (if enabled) can detect\n\t// unsafe mutations to the input.\n\tc := make(chan reflect.Value)\n\tgo detectRaces(c, f, y, x)\n\tgot := <-c\n\twant := f.Call([]reflect.Value{x, y})[0].Bool()\n\tif !got.IsValid() || got.Bool() != want {\n\t\tpanic(fmt.Sprintf(\"non-deterministic or non-symmetric function detected: %s\", function.NameOf(f)))\n\t}\n\treturn want\n}\n\nfunc detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) {\n\tvar ret reflect.Value\n\tdefer func() {\n\t\trecover() // Ignore panics, let the other call to f panic instead\n\t\tc <- ret\n\t}()\n\tret = f.Call(vs)[0]\n}\n\nfunc (s *state) compareStruct(t reflect.Type, vx, vy reflect.Value) {\n\tvar addr bool\n\tvar vax, vay reflect.Value // Addressable versions of vx and vy\n\n\tvar mayForce, mayForceInit bool\n\tstep := StructField{&structField{}}\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tstep.typ = t.Field(i).Type\n\t\tstep.vx = vx.Field(i)\n\t\tstep.vy = vy.Field(i)\n\t\tstep.name = t.Field(i).Name\n\t\tstep.idx = i\n\t\tstep.unexported = !isExported(step.name)\n\t\tif step.unexported {\n\t\t\tif step.name == \"_\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Defer checking of unexported fields until later to give an\n\t\t\t// Ignore a chance to ignore the field.\n\t\t\tif !vax.IsValid() || !vay.IsValid() {\n\t\t\t\t// For retrieveUnexportedField to work, the parent struct must\n\t\t\t\t// be addressable. Create a new copy of the values if\n\t\t\t\t// necessary to make them addressable.\n\t\t\t\taddr = vx.CanAddr() || vy.CanAddr()\n\t\t\t\tvax = makeAddressable(vx)\n\t\t\t\tvay = makeAddressable(vy)\n\t\t\t}\n\t\t\tif !mayForceInit {\n\t\t\t\tfor _, xf := range s.exporters {\n\t\t\t\t\tmayForce = mayForce || xf(t)\n\t\t\t\t}\n\t\t\t\tmayForceInit = true\n\t\t\t}\n\t\t\tstep.mayForce = mayForce\n\t\t\tstep.paddr = addr\n\t\t\tstep.pvx = vax\n\t\t\tstep.pvy = vay\n\t\t\tstep.field = t.Field(i)\n\t\t}\n\t\ts.compareAny(step)\n\t}\n}\n\nfunc (s *state) compareSlice(t reflect.Type, vx, vy reflect.Value) {\n\tisSlice := t.Kind() == reflect.Slice\n\tif isSlice && (vx.IsNil() || vy.IsNil()) {\n\t\ts.report(vx.IsNil() && vy.IsNil(), 0)\n\t\treturn\n\t}\n\n\t// NOTE: It is incorrect to call curPtrs.Push on the slice header pointer\n\t// since slices represents a list of pointers, rather than a single pointer.\n\t// The pointer checking logic must be handled on a per-element basis\n\t// in compareAny.\n\t//\n\t// A slice header (see reflect.SliceHeader) in Go is a tuple of a starting\n\t// pointer P, a length N, and a capacity C. Supposing each slice element has\n\t// a memory size of M, then the slice is equivalent to the list of pointers:\n\t//\t[P+i*M for i in range(N)]\n\t//\n\t// For example, v[:0] and v[:1] are slices with the same starting pointer,\n\t// but they are clearly different values. Using the slice pointer alone\n\t// violates the assumption that equal pointers implies equal values.\n\n\tstep := SliceIndex{&sliceIndex{pathStep: pathStep{typ: t.Elem()}, isSlice: isSlice}}\n\twithIndexes := func(ix, iy int) SliceIndex {\n\t\tif ix >= 0 {\n\t\t\tstep.vx, step.xkey = vx.Index(ix), ix\n\t\t} else {\n\t\t\tstep.vx, step.xkey = reflect.Value{}, -1\n\t\t}\n\t\tif iy >= 0 {\n\t\t\tstep.vy, step.ykey = vy.Index(iy), iy\n\t\t} else {\n\t\t\tstep.vy, step.ykey = reflect.Value{}, -1\n\t\t}\n\t\treturn step\n\t}\n\n\t// Ignore options are able to ignore missing elements in a slice.\n\t// However, detecting these reliably requires an optimal differencing\n\t// algorithm, for which diff.Difference is not.\n\t//\n\t// Instead, we first iterate through both slices to detect which elements\n\t// would be ignored if standing alone. The index of non-discarded elements\n\t// are stored in a separate slice, which diffing is then performed on.\n\tvar indexesX, indexesY []int\n\tvar ignoredX, ignoredY []bool\n\tfor ix := 0; ix < vx.Len(); ix++ {\n\t\tignored := s.statelessCompare(withIndexes(ix, -1)).NumDiff == 0\n\t\tif !ignored {\n\t\t\tindexesX = append(indexesX, ix)\n\t\t}\n\t\tignoredX = append(ignoredX, ignored)\n\t}\n\tfor iy := 0; iy < vy.Len(); iy++ {\n\t\tignored := s.statelessCompare(withIndexes(-1, iy)).NumDiff == 0\n\t\tif !ignored {\n\t\t\tindexesY = append(indexesY, iy)\n\t\t}\n\t\tignoredY = append(ignoredY, ignored)\n\t}\n\n\t// Compute an edit-script for slices vx and vy (excluding ignored elements).\n\tedits := diff.Difference(len(indexesX), len(indexesY), func(ix, iy int) diff.Result {\n\t\treturn s.statelessCompare(withIndexes(indexesX[ix], indexesY[iy]))\n\t})\n\n\t// Replay the ignore-scripts and the edit-script.\n\tvar ix, iy int\n\tfor ix < vx.Len() || iy < vy.Len() {\n\t\tvar e diff.EditType\n\t\tswitch {\n\t\tcase ix < len(ignoredX) && ignoredX[ix]:\n\t\t\te = diff.UniqueX\n\t\tcase iy < len(ignoredY) && ignoredY[iy]:\n\t\t\te = diff.UniqueY\n\t\tdefault:\n\t\t\te, edits = edits[0], edits[1:]\n\t\t}\n\t\tswitch e {\n\t\tcase diff.UniqueX:\n\t\t\ts.compareAny(withIndexes(ix, -1))\n\t\t\tix++\n\t\tcase diff.UniqueY:\n\t\t\ts.compareAny(withIndexes(-1, iy))\n\t\t\tiy++\n\t\tdefault:\n\t\t\ts.compareAny(withIndexes(ix, iy))\n\t\t\tix++\n\t\t\tiy++\n\t\t}\n\t}\n}\n\nfunc (s *state) compareMap(t reflect.Type, vx, vy reflect.Value) {\n\tif vx.IsNil() || vy.IsNil() {\n\t\ts.report(vx.IsNil() && vy.IsNil(), 0)\n\t\treturn\n\t}\n\n\t// Cycle-detection for maps.\n\tif eq, visited := s.curPtrs.Push(vx, vy); visited {\n\t\ts.report(eq, reportByCycle)\n\t\treturn\n\t}\n\tdefer s.curPtrs.Pop(vx, vy)\n\n\t// We combine and sort the two map keys so that we can perform the\n\t// comparisons in a deterministic order.\n\tstep := MapIndex{&mapIndex{pathStep: pathStep{typ: t.Elem()}}}\n\tfor _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) {\n\t\tstep.vx = vx.MapIndex(k)\n\t\tstep.vy = vy.MapIndex(k)\n\t\tstep.key = k\n\t\tif !step.vx.IsValid() && !step.vy.IsValid() {\n\t\t\t// It is possible for both vx and vy to be invalid if the\n\t\t\t// key contained a NaN value in it.\n\t\t\t//\n\t\t\t// Even with the ability to retrieve NaN keys in Go 1.12,\n\t\t\t// there still isn't a sensible way to compare the values since\n\t\t\t// a NaN key may map to multiple unordered values.\n\t\t\t// The most reasonable way to compare NaNs would be to compare the\n\t\t\t// set of values. However, this is impossible to do efficiently\n\t\t\t// since set equality is provably an O(n^2) operation given only\n\t\t\t// an Equal function. If we had a Less function or Hash function,\n\t\t\t// this could be done in O(n*log(n)) or O(n), respectively.\n\t\t\t//\n\t\t\t// Rather than adding complex logic to deal with NaNs, make it\n\t\t\t// the user's responsibility to compare such obscure maps.\n\t\t\tconst help = \"consider providing a Comparer to compare the map\"\n\t\t\tpanic(fmt.Sprintf(\"%#v has map key with NaNs\\n%s\", s.curPath, help))\n\t\t}\n\t\ts.compareAny(step)\n\t}\n}\n\nfunc (s *state) comparePtr(t reflect.Type, vx, vy reflect.Value) {\n\tif vx.IsNil() || vy.IsNil() {\n\t\ts.report(vx.IsNil() && vy.IsNil(), 0)\n\t\treturn\n\t}\n\n\t// Cycle-detection for pointers.\n\tif eq, visited := s.curPtrs.Push(vx, vy); visited {\n\t\ts.report(eq, reportByCycle)\n\t\treturn\n\t}\n\tdefer s.curPtrs.Pop(vx, vy)\n\n\tvx, vy = vx.Elem(), vy.Elem()\n\ts.compareAny(Indirect{&indirect{pathStep{t.Elem(), vx, vy}}})\n}\n\nfunc (s *state) compareInterface(t reflect.Type, vx, vy reflect.Value) {\n\tif vx.IsNil() || vy.IsNil() {\n\t\ts.report(vx.IsNil() && vy.IsNil(), 0)\n\t\treturn\n\t}\n\tvx, vy = vx.Elem(), vy.Elem()\n\tif vx.Type() != vy.Type() {\n\t\ts.report(false, 0)\n\t\treturn\n\t}\n\ts.compareAny(TypeAssertion{&typeAssertion{pathStep{vx.Type(), vx, vy}}})\n}\n\nfunc (s *state) report(eq bool, rf resultFlags) {\n\tif rf&reportByIgnore == 0 {\n\t\tif eq {\n\t\t\ts.result.NumSame++\n\t\t\trf |= reportEqual\n\t\t} else {\n\t\t\ts.result.NumDiff++\n\t\t\trf |= reportUnequal\n\t\t}\n\t}\n\tfor _, r := range s.reporters {\n\t\tr.Report(Result{flags: rf})\n\t}\n}\n\n// recChecker tracks the state needed to periodically perform checks that\n// user provided transformers are not stuck in an infinitely recursive cycle.\ntype recChecker struct{ next int }\n\n// Check scans the Path for any recursive transformers and panics when any\n// recursive transformers are detected. Note that the presence of a\n// recursive Transformer does not necessarily imply an infinite cycle.\n// As such, this check only activates after some minimal number of path steps.\nfunc (rc *recChecker) Check(p Path) {\n\tconst minLen = 1 << 16\n\tif rc.next == 0 {\n\t\trc.next = minLen\n\t}\n\tif len(p) < rc.next {\n\t\treturn\n\t}\n\trc.next <<= 1\n\n\t// Check whether the same transformer has appeared at least twice.\n\tvar ss []string\n\tm := map[Option]int{}\n\tfor _, ps := range p {\n\t\tif t, ok := ps.(Transform); ok {\n\t\t\tt := t.Option()\n\t\t\tif m[t] == 1 { // Transformer was used exactly once before\n\t\t\t\ttf := t.(*transformer).fnc.Type()\n\t\t\t\tss = append(ss, fmt.Sprintf(\"%v: %v => %v\", t, tf.In(0), tf.Out(0)))\n\t\t\t}\n\t\t\tm[t]++\n\t\t}\n\t}\n\tif len(ss) > 0 {\n\t\tconst warning = \"recursive set of Transformers detected\"\n\t\tconst help = \"consider using cmpopts.AcyclicTransformer\"\n\t\tset := strings.Join(ss, \"\\n\\t\")\n\t\tpanic(fmt.Sprintf(\"%s:\\n\\t%s\\n%s\", warning, set, help))\n\t}\n}\n\n// dynChecker tracks the state needed to periodically perform checks that\n// user provided functions are symmetric and deterministic.\n// The zero value is safe for immediate use.\ntype dynChecker struct{ curr, next int }\n\n// Next increments the state and reports whether a check should be performed.\n//\n// Checks occur every Nth function call, where N is a triangular number:\n//\n//\t0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ...\n//\n// See https://en.wikipedia.org/wiki/Triangular_number\n//\n// This sequence ensures that the cost of checks drops significantly as\n// the number of functions calls grows larger.\nfunc (dc *dynChecker) Next() bool {\n\tok := dc.curr == dc.next\n\tif ok {\n\t\tdc.curr = 0\n\t\tdc.next++\n\t}\n\tdc.curr++\n\treturn ok\n}\n\n// makeAddressable returns a value that is always addressable.\n// It returns the input verbatim if it is already addressable,\n// otherwise it creates a new value and returns an addressable copy.\nfunc makeAddressable(v reflect.Value) reflect.Value {\n\tif v.CanAddr() {\n\t\treturn v\n\t}\n\tvc := reflect.New(v.Type()).Elem()\n\tvc.Set(v)\n\treturn vc\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/export.go",
    "content": "// Copyright 2017, 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 cmp\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\n// retrieveUnexportedField uses unsafe to forcibly retrieve any field from\n// a struct such that the value has read-write permissions.\n//\n// The parent struct, v, must be addressable, while f must be a StructField\n// describing the field to retrieve. If addr is false,\n// then the returned value will be shallowed copied to be non-addressable.\nfunc retrieveUnexportedField(v reflect.Value, f reflect.StructField, addr bool) reflect.Value {\n\tve := reflect.NewAt(f.Type, unsafe.Pointer(uintptr(unsafe.Pointer(v.UnsafeAddr()))+f.Offset)).Elem()\n\tif !addr {\n\t\t// A field is addressable if and only if the struct is addressable.\n\t\t// If the original parent value was not addressable, shallow copy the\n\t\t// value to make it non-addressable to avoid leaking an implementation\n\t\t// detail of how forcibly exporting a field works.\n\t\tif ve.Kind() == reflect.Interface && ve.IsNil() {\n\t\t\treturn reflect.Zero(f.Type)\n\t\t}\n\t\treturn reflect.ValueOf(ve.Interface()).Convert(f.Type)\n\t}\n\treturn ve\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go",
    "content": "// Copyright 2017, 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 !cmp_debug\n// +build !cmp_debug\n\npackage diff\n\nvar debug debugger\n\ntype debugger struct{}\n\nfunc (debugger) Begin(_, _ int, f EqualFunc, _, _ *EditScript) EqualFunc {\n\treturn f\n}\nfunc (debugger) Update() {}\nfunc (debugger) Finish() {}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go",
    "content": "// Copyright 2017, 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 cmp_debug\n// +build cmp_debug\n\npackage diff\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\n// The algorithm can be seen running in real-time by enabling debugging:\n//\tgo test -tags=cmp_debug -v\n//\n// Example output:\n//\t=== RUN   TestDifference/#34\n//\t┌───────────────────────────────┐\n//\t│ \\ · · · · · · · · · · · · · · │\n//\t│ · # · · · · · · · · · · · · · │\n//\t│ · \\ · · · · · · · · · · · · · │\n//\t│ · · \\ · · · · · · · · · · · · │\n//\t│ · · · X # · · · · · · · · · · │\n//\t│ · · · # \\ · · · · · · · · · · │\n//\t│ · · · · · # # · · · · · · · · │\n//\t│ · · · · · # \\ · · · · · · · · │\n//\t│ · · · · · · · \\ · · · · · · · │\n//\t│ · · · · · · · · \\ · · · · · · │\n//\t│ · · · · · · · · · \\ · · · · · │\n//\t│ · · · · · · · · · · \\ · · # · │\n//\t│ · · · · · · · · · · · \\ # # · │\n//\t│ · · · · · · · · · · · # # # · │\n//\t│ · · · · · · · · · · # # # # · │\n//\t│ · · · · · · · · · # # # # # · │\n//\t│ · · · · · · · · · · · · · · \\ │\n//\t└───────────────────────────────┘\n//\t[.Y..M.XY......YXYXY.|]\n//\n// The grid represents the edit-graph where the horizontal axis represents\n// list X and the vertical axis represents list Y. The start of the two lists\n// is the top-left, while the ends are the bottom-right. The '·' represents\n// an unexplored node in the graph. The '\\' indicates that the two symbols\n// from list X and Y are equal. The 'X' indicates that two symbols are similar\n// (but not exactly equal) to each other. The '#' indicates that the two symbols\n// are different (and not similar). The algorithm traverses this graph trying to\n// make the paths starting in the top-left and the bottom-right connect.\n//\n// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents\n// the currently established path from the forward and reverse searches,\n// separated by a '|' character.\n\nconst (\n\tupdateDelay  = 100 * time.Millisecond\n\tfinishDelay  = 500 * time.Millisecond\n\tansiTerminal = true // ANSI escape codes used to move terminal cursor\n)\n\nvar debug debugger\n\ntype debugger struct {\n\tsync.Mutex\n\tp1, p2           EditScript\n\tfwdPath, revPath *EditScript\n\tgrid             []byte\n\tlines            int\n}\n\nfunc (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc {\n\tdbg.Lock()\n\tdbg.fwdPath, dbg.revPath = p1, p2\n\ttop := \"┌─\" + strings.Repeat(\"──\", nx) + \"┐\\n\"\n\trow := \"│ \" + strings.Repeat(\"· \", nx) + \"│\\n\"\n\tbtm := \"└─\" + strings.Repeat(\"──\", nx) + \"┘\\n\"\n\tdbg.grid = []byte(top + strings.Repeat(row, ny) + btm)\n\tdbg.lines = strings.Count(dbg.String(), \"\\n\")\n\tfmt.Print(dbg)\n\n\t// Wrap the EqualFunc so that we can intercept each result.\n\treturn func(ix, iy int) (r Result) {\n\t\tcell := dbg.grid[len(top)+iy*len(row):][len(\"│ \")+len(\"· \")*ix:][:len(\"·\")]\n\t\tfor i := range cell {\n\t\t\tcell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot\n\t\t}\n\t\tswitch r = f(ix, iy); {\n\t\tcase r.Equal():\n\t\t\tcell[0] = '\\\\'\n\t\tcase r.Similar():\n\t\t\tcell[0] = 'X'\n\t\tdefault:\n\t\t\tcell[0] = '#'\n\t\t}\n\t\treturn\n\t}\n}\n\nfunc (dbg *debugger) Update() {\n\tdbg.print(updateDelay)\n}\n\nfunc (dbg *debugger) Finish() {\n\tdbg.print(finishDelay)\n\tdbg.Unlock()\n}\n\nfunc (dbg *debugger) String() string {\n\tdbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0]\n\tfor i := len(*dbg.revPath) - 1; i >= 0; i-- {\n\t\tdbg.p2 = append(dbg.p2, (*dbg.revPath)[i])\n\t}\n\treturn fmt.Sprintf(\"%s[%v|%v]\\n\\n\", dbg.grid, dbg.p1, dbg.p2)\n}\n\nfunc (dbg *debugger) print(d time.Duration) {\n\tif ansiTerminal {\n\t\tfmt.Printf(\"\\x1b[%dA\", dbg.lines) // Reset terminal cursor\n\t}\n\tfmt.Print(dbg)\n\ttime.Sleep(d)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go",
    "content": "// Copyright 2017, 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// Package diff implements an algorithm for producing edit-scripts.\n// The edit-script is a sequence of operations needed to transform one list\n// of symbols into another (or vice-versa). The edits allowed are insertions,\n// deletions, and modifications. The summation of all edits is called the\n// Levenshtein distance as this problem is well-known in computer science.\n//\n// This package prioritizes performance over accuracy. That is, the run time\n// is more important than obtaining a minimal Levenshtein distance.\npackage diff\n\nimport (\n\t\"math/rand\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp/internal/flags\"\n)\n\n// EditType represents a single operation within an edit-script.\ntype EditType uint8\n\nconst (\n\t// Identity indicates that a symbol pair is identical in both list X and Y.\n\tIdentity EditType = iota\n\t// UniqueX indicates that a symbol only exists in X and not Y.\n\tUniqueX\n\t// UniqueY indicates that a symbol only exists in Y and not X.\n\tUniqueY\n\t// Modified indicates that a symbol pair is a modification of each other.\n\tModified\n)\n\n// EditScript represents the series of differences between two lists.\ntype EditScript []EditType\n\n// String returns a human-readable string representing the edit-script where\n// Identity, UniqueX, UniqueY, and Modified are represented by the\n// '.', 'X', 'Y', and 'M' characters, respectively.\nfunc (es EditScript) String() string {\n\tb := make([]byte, len(es))\n\tfor i, e := range es {\n\t\tswitch e {\n\t\tcase Identity:\n\t\t\tb[i] = '.'\n\t\tcase UniqueX:\n\t\t\tb[i] = 'X'\n\t\tcase UniqueY:\n\t\t\tb[i] = 'Y'\n\t\tcase Modified:\n\t\t\tb[i] = 'M'\n\t\tdefault:\n\t\t\tpanic(\"invalid edit-type\")\n\t\t}\n\t}\n\treturn string(b)\n}\n\n// stats returns a histogram of the number of each type of edit operation.\nfunc (es EditScript) stats() (s struct{ NI, NX, NY, NM int }) {\n\tfor _, e := range es {\n\t\tswitch e {\n\t\tcase Identity:\n\t\t\ts.NI++\n\t\tcase UniqueX:\n\t\t\ts.NX++\n\t\tcase UniqueY:\n\t\t\ts.NY++\n\t\tcase Modified:\n\t\t\ts.NM++\n\t\tdefault:\n\t\t\tpanic(\"invalid edit-type\")\n\t\t}\n\t}\n\treturn\n}\n\n// Dist is the Levenshtein distance and is guaranteed to be 0 if and only if\n// lists X and Y are equal.\nfunc (es EditScript) Dist() int { return len(es) - es.stats().NI }\n\n// LenX is the length of the X list.\nfunc (es EditScript) LenX() int { return len(es) - es.stats().NY }\n\n// LenY is the length of the Y list.\nfunc (es EditScript) LenY() int { return len(es) - es.stats().NX }\n\n// EqualFunc reports whether the symbols at indexes ix and iy are equal.\n// When called by Difference, the index is guaranteed to be within nx and ny.\ntype EqualFunc func(ix int, iy int) Result\n\n// Result is the result of comparison.\n// NumSame is the number of sub-elements that are equal.\n// NumDiff is the number of sub-elements that are not equal.\ntype Result struct{ NumSame, NumDiff int }\n\n// BoolResult returns a Result that is either Equal or not Equal.\nfunc BoolResult(b bool) Result {\n\tif b {\n\t\treturn Result{NumSame: 1} // Equal, Similar\n\t} else {\n\t\treturn Result{NumDiff: 2} // Not Equal, not Similar\n\t}\n}\n\n// Equal indicates whether the symbols are equal. Two symbols are equal\n// if and only if NumDiff == 0. If Equal, then they are also Similar.\nfunc (r Result) Equal() bool { return r.NumDiff == 0 }\n\n// Similar indicates whether two symbols are similar and may be represented\n// by using the Modified type. As a special case, we consider binary comparisons\n// (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar.\n//\n// The exact ratio of NumSame to NumDiff to determine similarity may change.\nfunc (r Result) Similar() bool {\n\t// Use NumSame+1 to offset NumSame so that binary comparisons are similar.\n\treturn r.NumSame+1 >= r.NumDiff\n}\n\nvar randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0\n\n// Difference reports whether two lists of lengths nx and ny are equal\n// given the definition of equality provided as f.\n//\n// This function returns an edit-script, which is a sequence of operations\n// needed to convert one list into the other. The following invariants for\n// the edit-script are maintained:\n//   - eq == (es.Dist()==0)\n//   - nx == es.LenX()\n//   - ny == es.LenY()\n//\n// This algorithm is not guaranteed to be an optimal solution (i.e., one that\n// produces an edit-script with a minimal Levenshtein distance). This algorithm\n// favors performance over optimality. The exact output is not guaranteed to\n// be stable and may change over time.\nfunc Difference(nx, ny int, f EqualFunc) (es EditScript) {\n\t// This algorithm is based on traversing what is known as an \"edit-graph\".\n\t// See Figure 1 from \"An O(ND) Difference Algorithm and Its Variations\"\n\t// by Eugene W. Myers. Since D can be as large as N itself, this is\n\t// effectively O(N^2). Unlike the algorithm from that paper, we are not\n\t// interested in the optimal path, but at least some \"decent\" path.\n\t//\n\t// For example, let X and Y be lists of symbols:\n\t//\tX = [A B C A B B A]\n\t//\tY = [C B A B A C]\n\t//\n\t// The edit-graph can be drawn as the following:\n\t//\t   A B C A B B A\n\t//\t  ┌─────────────┐\n\t//\tC │_|_|\\|_|_|_|_│ 0\n\t//\tB │_|\\|_|_|\\|\\|_│ 1\n\t//\tA │\\|_|_|\\|_|_|\\│ 2\n\t//\tB │_|\\|_|_|\\|\\|_│ 3\n\t//\tA │\\|_|_|\\|_|_|\\│ 4\n\t//\tC │ | |\\| | | | │ 5\n\t//\t  └─────────────┘ 6\n\t//\t   0 1 2 3 4 5 6 7\n\t//\n\t// List X is written along the horizontal axis, while list Y is written\n\t// along the vertical axis. At any point on this grid, if the symbol in\n\t// list X matches the corresponding symbol in list Y, then a '\\' is drawn.\n\t// The goal of any minimal edit-script algorithm is to find a path from the\n\t// top-left corner to the bottom-right corner, while traveling through the\n\t// fewest horizontal or vertical edges.\n\t// A horizontal edge is equivalent to inserting a symbol from list X.\n\t// A vertical edge is equivalent to inserting a symbol from list Y.\n\t// A diagonal edge is equivalent to a matching symbol between both X and Y.\n\n\t// Invariants:\n\t//   - 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx\n\t//   - 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny\n\t//\n\t// In general:\n\t//   - fwdFrontier.X < revFrontier.X\n\t//   - fwdFrontier.Y < revFrontier.Y\n\t//\n\t// Unless, it is time for the algorithm to terminate.\n\tfwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)}\n\trevPath := path{-1, point{nx, ny}, make(EditScript, 0)}\n\tfwdFrontier := fwdPath.point // Forward search frontier\n\trevFrontier := revPath.point // Reverse search frontier\n\n\t// Search budget bounds the cost of searching for better paths.\n\t// The longest sequence of non-matching symbols that can be tolerated is\n\t// approximately the square-root of the search budget.\n\tsearchBudget := 4 * (nx + ny) // O(n)\n\n\t// Running the tests with the \"cmp_debug\" build tag prints a visualization\n\t// of the algorithm running in real-time. This is educational for\n\t// understanding how the algorithm works. See debug_enable.go.\n\tf = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es)\n\n\t// The algorithm below is a greedy, meet-in-the-middle algorithm for\n\t// computing sub-optimal edit-scripts between two lists.\n\t//\n\t// The algorithm is approximately as follows:\n\t//   - Searching for differences switches back-and-forth between\n\t//     a search that starts at the beginning (the top-left corner), and\n\t//     a search that starts at the end (the bottom-right corner).\n\t//     The goal of the search is connect with the search\n\t//     from the opposite corner.\n\t//   - As we search, we build a path in a greedy manner,\n\t//     where the first match seen is added to the path (this is sub-optimal,\n\t//     but provides a decent result in practice). When matches are found,\n\t//     we try the next pair of symbols in the lists and follow all matches\n\t//     as far as possible.\n\t//   - When searching for matches, we search along a diagonal going through\n\t//     through the \"frontier\" point. If no matches are found,\n\t//     we advance the frontier towards the opposite corner.\n\t//   - This algorithm terminates when either the X coordinates or the\n\t//     Y coordinates of the forward and reverse frontier points ever intersect.\n\n\t// This algorithm is correct even if searching only in the forward direction\n\t// or in the reverse direction. We do both because it is commonly observed\n\t// that two lists commonly differ because elements were added to the front\n\t// or end of the other list.\n\t//\n\t// Non-deterministically start with either the forward or reverse direction\n\t// to introduce some deliberate instability so that we have the flexibility\n\t// to change this algorithm in the future.\n\tif flags.Deterministic || randBool {\n\t\tgoto forwardSearch\n\t} else {\n\t\tgoto reverseSearch\n\t}\n\nforwardSearch:\n\t{\n\t\t// Forward search from the beginning.\n\t\tif fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {\n\t\t\tgoto finishSearch\n\t\t}\n\t\tfor stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {\n\t\t\t// Search in a diagonal pattern for a match.\n\t\t\tz := zigzag(i)\n\t\t\tp := point{fwdFrontier.X + z, fwdFrontier.Y - z}\n\t\t\tswitch {\n\t\t\tcase p.X >= revPath.X || p.Y < fwdPath.Y:\n\t\t\t\tstop1 = true // Hit top-right corner\n\t\t\tcase p.Y >= revPath.Y || p.X < fwdPath.X:\n\t\t\t\tstop2 = true // Hit bottom-left corner\n\t\t\tcase f(p.X, p.Y).Equal():\n\t\t\t\t// Match found, so connect the path to this point.\n\t\t\t\tfwdPath.connect(p, f)\n\t\t\t\tfwdPath.append(Identity)\n\t\t\t\t// Follow sequence of matches as far as possible.\n\t\t\t\tfor fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {\n\t\t\t\t\tif !f(fwdPath.X, fwdPath.Y).Equal() {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tfwdPath.append(Identity)\n\t\t\t\t}\n\t\t\t\tfwdFrontier = fwdPath.point\n\t\t\t\tstop1, stop2 = true, true\n\t\t\tdefault:\n\t\t\t\tsearchBudget-- // Match not found\n\t\t\t}\n\t\t\tdebug.Update()\n\t\t}\n\t\t// Advance the frontier towards reverse point.\n\t\tif revPath.X-fwdFrontier.X >= revPath.Y-fwdFrontier.Y {\n\t\t\tfwdFrontier.X++\n\t\t} else {\n\t\t\tfwdFrontier.Y++\n\t\t}\n\t\tgoto reverseSearch\n\t}\n\nreverseSearch:\n\t{\n\t\t// Reverse search from the end.\n\t\tif fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {\n\t\t\tgoto finishSearch\n\t\t}\n\t\tfor stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {\n\t\t\t// Search in a diagonal pattern for a match.\n\t\t\tz := zigzag(i)\n\t\t\tp := point{revFrontier.X - z, revFrontier.Y + z}\n\t\t\tswitch {\n\t\t\tcase fwdPath.X >= p.X || revPath.Y < p.Y:\n\t\t\t\tstop1 = true // Hit bottom-left corner\n\t\t\tcase fwdPath.Y >= p.Y || revPath.X < p.X:\n\t\t\t\tstop2 = true // Hit top-right corner\n\t\t\tcase f(p.X-1, p.Y-1).Equal():\n\t\t\t\t// Match found, so connect the path to this point.\n\t\t\t\trevPath.connect(p, f)\n\t\t\t\trevPath.append(Identity)\n\t\t\t\t// Follow sequence of matches as far as possible.\n\t\t\t\tfor fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {\n\t\t\t\t\tif !f(revPath.X-1, revPath.Y-1).Equal() {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\trevPath.append(Identity)\n\t\t\t\t}\n\t\t\t\trevFrontier = revPath.point\n\t\t\t\tstop1, stop2 = true, true\n\t\t\tdefault:\n\t\t\t\tsearchBudget-- // Match not found\n\t\t\t}\n\t\t\tdebug.Update()\n\t\t}\n\t\t// Advance the frontier towards forward point.\n\t\tif revFrontier.X-fwdPath.X >= revFrontier.Y-fwdPath.Y {\n\t\t\trevFrontier.X--\n\t\t} else {\n\t\t\trevFrontier.Y--\n\t\t}\n\t\tgoto forwardSearch\n\t}\n\nfinishSearch:\n\t// Join the forward and reverse paths and then append the reverse path.\n\tfwdPath.connect(revPath.point, f)\n\tfor i := len(revPath.es) - 1; i >= 0; i-- {\n\t\tt := revPath.es[i]\n\t\trevPath.es = revPath.es[:i]\n\t\tfwdPath.append(t)\n\t}\n\tdebug.Finish()\n\treturn fwdPath.es\n}\n\ntype path struct {\n\tdir   int // +1 if forward, -1 if reverse\n\tpoint     // Leading point of the EditScript path\n\tes    EditScript\n}\n\n// connect appends any necessary Identity, Modified, UniqueX, or UniqueY types\n// to the edit-script to connect p.point to dst.\nfunc (p *path) connect(dst point, f EqualFunc) {\n\tif p.dir > 0 {\n\t\t// Connect in forward direction.\n\t\tfor dst.X > p.X && dst.Y > p.Y {\n\t\t\tswitch r := f(p.X, p.Y); {\n\t\t\tcase r.Equal():\n\t\t\t\tp.append(Identity)\n\t\t\tcase r.Similar():\n\t\t\t\tp.append(Modified)\n\t\t\tcase dst.X-p.X >= dst.Y-p.Y:\n\t\t\t\tp.append(UniqueX)\n\t\t\tdefault:\n\t\t\t\tp.append(UniqueY)\n\t\t\t}\n\t\t}\n\t\tfor dst.X > p.X {\n\t\t\tp.append(UniqueX)\n\t\t}\n\t\tfor dst.Y > p.Y {\n\t\t\tp.append(UniqueY)\n\t\t}\n\t} else {\n\t\t// Connect in reverse direction.\n\t\tfor p.X > dst.X && p.Y > dst.Y {\n\t\t\tswitch r := f(p.X-1, p.Y-1); {\n\t\t\tcase r.Equal():\n\t\t\t\tp.append(Identity)\n\t\t\tcase r.Similar():\n\t\t\t\tp.append(Modified)\n\t\t\tcase p.Y-dst.Y >= p.X-dst.X:\n\t\t\t\tp.append(UniqueY)\n\t\t\tdefault:\n\t\t\t\tp.append(UniqueX)\n\t\t\t}\n\t\t}\n\t\tfor p.X > dst.X {\n\t\t\tp.append(UniqueX)\n\t\t}\n\t\tfor p.Y > dst.Y {\n\t\t\tp.append(UniqueY)\n\t\t}\n\t}\n}\n\nfunc (p *path) append(t EditType) {\n\tp.es = append(p.es, t)\n\tswitch t {\n\tcase Identity, Modified:\n\t\tp.add(p.dir, p.dir)\n\tcase UniqueX:\n\t\tp.add(p.dir, 0)\n\tcase UniqueY:\n\t\tp.add(0, p.dir)\n\t}\n\tdebug.Update()\n}\n\ntype point struct{ X, Y int }\n\nfunc (p *point) add(dx, dy int) { p.X += dx; p.Y += dy }\n\n// zigzag maps a consecutive sequence of integers to a zig-zag sequence.\n//\n//\t[0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...]\nfunc zigzag(x int) int {\n\tif x&1 != 0 {\n\t\tx = ^x\n\t}\n\treturn x >> 1\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/flags/flags.go",
    "content": "// Copyright 2019, 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 flags\n\n// Deterministic controls whether the output of Diff should be deterministic.\n// This is only used for testing.\nvar Deterministic bool\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/function/func.go",
    "content": "// Copyright 2017, 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// Package function provides functionality for identifying function types.\npackage function\n\nimport (\n\t\"reflect\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strings\"\n)\n\ntype funcType int\n\nconst (\n\t_ funcType = iota\n\n\ttbFunc  // func(T) bool\n\tttbFunc // func(T, T) bool\n\ttrbFunc // func(T, R) bool\n\ttibFunc // func(T, I) bool\n\ttrFunc  // func(T) R\n\n\tEqual             = ttbFunc // func(T, T) bool\n\tEqualAssignable   = tibFunc // func(T, I) bool; encapsulates func(T, T) bool\n\tTransformer       = trFunc  // func(T) R\n\tValueFilter       = ttbFunc // func(T, T) bool\n\tLess              = ttbFunc // func(T, T) bool\n\tValuePredicate    = tbFunc  // func(T) bool\n\tKeyValuePredicate = trbFunc // func(T, R) bool\n)\n\nvar boolType = reflect.TypeOf(true)\n\n// IsType reports whether the reflect.Type is of the specified function type.\nfunc IsType(t reflect.Type, ft funcType) bool {\n\tif t == nil || t.Kind() != reflect.Func || t.IsVariadic() {\n\t\treturn false\n\t}\n\tni, no := t.NumIn(), t.NumOut()\n\tswitch ft {\n\tcase tbFunc: // func(T) bool\n\t\tif ni == 1 && no == 1 && t.Out(0) == boolType {\n\t\t\treturn true\n\t\t}\n\tcase ttbFunc: // func(T, T) bool\n\t\tif ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {\n\t\t\treturn true\n\t\t}\n\tcase trbFunc: // func(T, R) bool\n\t\tif ni == 2 && no == 1 && t.Out(0) == boolType {\n\t\t\treturn true\n\t\t}\n\tcase tibFunc: // func(T, I) bool\n\t\tif ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType {\n\t\t\treturn true\n\t\t}\n\tcase trFunc: // func(T) R\n\t\tif ni == 1 && no == 1 {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nvar lastIdentRx = regexp.MustCompile(`[_\\p{L}][_\\p{L}\\p{N}]*$`)\n\n// NameOf returns the name of the function value.\nfunc NameOf(v reflect.Value) string {\n\tfnc := runtime.FuncForPC(v.Pointer())\n\tif fnc == nil {\n\t\treturn \"<unknown>\"\n\t}\n\tfullName := fnc.Name() // e.g., \"long/path/name/mypkg.(*MyType).(long/path/name/mypkg.myMethod)-fm\"\n\n\t// Method closures have a \"-fm\" suffix.\n\tfullName = strings.TrimSuffix(fullName, \"-fm\")\n\n\tvar name string\n\tfor len(fullName) > 0 {\n\t\tinParen := strings.HasSuffix(fullName, \")\")\n\t\tfullName = strings.TrimSuffix(fullName, \")\")\n\n\t\ts := lastIdentRx.FindString(fullName)\n\t\tif s == \"\" {\n\t\t\tbreak\n\t\t}\n\t\tname = s + \".\" + name\n\t\tfullName = strings.TrimSuffix(fullName, s)\n\n\t\tif i := strings.LastIndexByte(fullName, '('); inParen && i >= 0 {\n\t\t\tfullName = fullName[:i]\n\t\t}\n\t\tfullName = strings.TrimSuffix(fullName, \".\")\n\t}\n\treturn strings.TrimSuffix(name, \".\")\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/value/name.go",
    "content": "// Copyright 2020, 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 value\n\nimport (\n\t\"reflect\"\n\t\"strconv\"\n)\n\nvar anyType = reflect.TypeOf((*interface{})(nil)).Elem()\n\n// TypeString is nearly identical to reflect.Type.String,\n// but has an additional option to specify that full type names be used.\nfunc TypeString(t reflect.Type, qualified bool) string {\n\treturn string(appendTypeName(nil, t, qualified, false))\n}\n\nfunc appendTypeName(b []byte, t reflect.Type, qualified, elideFunc bool) []byte {\n\t// BUG: Go reflection provides no way to disambiguate two named types\n\t// of the same name and within the same package,\n\t// but declared within the namespace of different functions.\n\n\t// Use the \"any\" alias instead of \"interface{}\" for better readability.\n\tif t == anyType {\n\t\treturn append(b, \"any\"...)\n\t}\n\n\t// Named type.\n\tif t.Name() != \"\" {\n\t\tif qualified && t.PkgPath() != \"\" {\n\t\t\tb = append(b, '\"')\n\t\t\tb = append(b, t.PkgPath()...)\n\t\t\tb = append(b, '\"')\n\t\t\tb = append(b, '.')\n\t\t\tb = append(b, t.Name()...)\n\t\t} else {\n\t\t\tb = append(b, t.String()...)\n\t\t}\n\t\treturn b\n\t}\n\n\t// Unnamed type.\n\tswitch k := t.Kind(); k {\n\tcase reflect.Bool, reflect.String, reflect.UnsafePointer,\n\t\treflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,\n\t\treflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:\n\t\tb = append(b, k.String()...)\n\tcase reflect.Chan:\n\t\tif t.ChanDir() == reflect.RecvDir {\n\t\t\tb = append(b, \"<-\"...)\n\t\t}\n\t\tb = append(b, \"chan\"...)\n\t\tif t.ChanDir() == reflect.SendDir {\n\t\t\tb = append(b, \"<-\"...)\n\t\t}\n\t\tb = append(b, ' ')\n\t\tb = appendTypeName(b, t.Elem(), qualified, false)\n\tcase reflect.Func:\n\t\tif !elideFunc {\n\t\t\tb = append(b, \"func\"...)\n\t\t}\n\t\tb = append(b, '(')\n\t\tfor i := 0; i < t.NumIn(); i++ {\n\t\t\tif i > 0 {\n\t\t\t\tb = append(b, \", \"...)\n\t\t\t}\n\t\t\tif i == t.NumIn()-1 && t.IsVariadic() {\n\t\t\t\tb = append(b, \"...\"...)\n\t\t\t\tb = appendTypeName(b, t.In(i).Elem(), qualified, false)\n\t\t\t} else {\n\t\t\t\tb = appendTypeName(b, t.In(i), qualified, false)\n\t\t\t}\n\t\t}\n\t\tb = append(b, ')')\n\t\tswitch t.NumOut() {\n\t\tcase 0:\n\t\t\t// Do nothing\n\t\tcase 1:\n\t\t\tb = append(b, ' ')\n\t\t\tb = appendTypeName(b, t.Out(0), qualified, false)\n\t\tdefault:\n\t\t\tb = append(b, \" (\"...)\n\t\t\tfor i := 0; i < t.NumOut(); i++ {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tb = append(b, \", \"...)\n\t\t\t\t}\n\t\t\t\tb = appendTypeName(b, t.Out(i), qualified, false)\n\t\t\t}\n\t\t\tb = append(b, ')')\n\t\t}\n\tcase reflect.Struct:\n\t\tb = append(b, \"struct{ \"...)\n\t\tfor i := 0; i < t.NumField(); i++ {\n\t\t\tif i > 0 {\n\t\t\t\tb = append(b, \"; \"...)\n\t\t\t}\n\t\t\tsf := t.Field(i)\n\t\t\tif !sf.Anonymous {\n\t\t\t\tif qualified && sf.PkgPath != \"\" {\n\t\t\t\t\tb = append(b, '\"')\n\t\t\t\t\tb = append(b, sf.PkgPath...)\n\t\t\t\t\tb = append(b, '\"')\n\t\t\t\t\tb = append(b, '.')\n\t\t\t\t}\n\t\t\t\tb = append(b, sf.Name...)\n\t\t\t\tb = append(b, ' ')\n\t\t\t}\n\t\t\tb = appendTypeName(b, sf.Type, qualified, false)\n\t\t\tif sf.Tag != \"\" {\n\t\t\t\tb = append(b, ' ')\n\t\t\t\tb = strconv.AppendQuote(b, string(sf.Tag))\n\t\t\t}\n\t\t}\n\t\tif b[len(b)-1] == ' ' {\n\t\t\tb = b[:len(b)-1]\n\t\t} else {\n\t\t\tb = append(b, ' ')\n\t\t}\n\t\tb = append(b, '}')\n\tcase reflect.Slice, reflect.Array:\n\t\tb = append(b, '[')\n\t\tif k == reflect.Array {\n\t\t\tb = strconv.AppendUint(b, uint64(t.Len()), 10)\n\t\t}\n\t\tb = append(b, ']')\n\t\tb = appendTypeName(b, t.Elem(), qualified, false)\n\tcase reflect.Map:\n\t\tb = append(b, \"map[\"...)\n\t\tb = appendTypeName(b, t.Key(), qualified, false)\n\t\tb = append(b, ']')\n\t\tb = appendTypeName(b, t.Elem(), qualified, false)\n\tcase reflect.Ptr:\n\t\tb = append(b, '*')\n\t\tb = appendTypeName(b, t.Elem(), qualified, false)\n\tcase reflect.Interface:\n\t\tb = append(b, \"interface{ \"...)\n\t\tfor i := 0; i < t.NumMethod(); i++ {\n\t\t\tif i > 0 {\n\t\t\t\tb = append(b, \"; \"...)\n\t\t\t}\n\t\t\tm := t.Method(i)\n\t\t\tif qualified && m.PkgPath != \"\" {\n\t\t\t\tb = append(b, '\"')\n\t\t\t\tb = append(b, m.PkgPath...)\n\t\t\t\tb = append(b, '\"')\n\t\t\t\tb = append(b, '.')\n\t\t\t}\n\t\t\tb = append(b, m.Name...)\n\t\t\tb = appendTypeName(b, m.Type, qualified, true)\n\t\t}\n\t\tif b[len(b)-1] == ' ' {\n\t\t\tb = b[:len(b)-1]\n\t\t} else {\n\t\t\tb = append(b, ' ')\n\t\t}\n\t\tb = append(b, '}')\n\tdefault:\n\t\tpanic(\"invalid kind: \" + k.String())\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/value/pointer.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\npackage value\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\n// Pointer is an opaque typed pointer and is guaranteed to be comparable.\ntype Pointer struct {\n\tp unsafe.Pointer\n\tt reflect.Type\n}\n\n// PointerOf returns a Pointer from v, which must be a\n// reflect.Ptr, reflect.Slice, or reflect.Map.\nfunc PointerOf(v reflect.Value) Pointer {\n\t// The proper representation of a pointer is unsafe.Pointer,\n\t// which is necessary if the GC ever uses a moving collector.\n\treturn Pointer{unsafe.Pointer(v.Pointer()), v.Type()}\n}\n\n// IsNil reports whether the pointer is nil.\nfunc (p Pointer) IsNil() bool {\n\treturn p.p == nil\n}\n\n// Uintptr returns the pointer as a uintptr.\nfunc (p Pointer) Uintptr() uintptr {\n\treturn uintptr(p.p)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/internal/value/sort.go",
    "content": "// Copyright 2017, 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 value\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"sort\"\n)\n\n// SortKeys sorts a list of map keys, deduplicating keys if necessary.\n// The type of each value must be comparable.\nfunc SortKeys(vs []reflect.Value) []reflect.Value {\n\tif len(vs) == 0 {\n\t\treturn vs\n\t}\n\n\t// Sort the map keys.\n\tsort.SliceStable(vs, func(i, j int) bool { return isLess(vs[i], vs[j]) })\n\n\t// Deduplicate keys (fails for NaNs).\n\tvs2 := vs[:1]\n\tfor _, v := range vs[1:] {\n\t\tif isLess(vs2[len(vs2)-1], v) {\n\t\t\tvs2 = append(vs2, v)\n\t\t}\n\t}\n\treturn vs2\n}\n\n// isLess is a generic function for sorting arbitrary map keys.\n// The inputs must be of the same type and must be comparable.\nfunc isLess(x, y reflect.Value) bool {\n\tswitch x.Type().Kind() {\n\tcase reflect.Bool:\n\t\treturn !x.Bool() && y.Bool()\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn x.Int() < y.Int()\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn x.Uint() < y.Uint()\n\tcase reflect.Float32, reflect.Float64:\n\t\t// NOTE: This does not sort -0 as less than +0\n\t\t// since Go maps treat -0 and +0 as equal keys.\n\t\tfx, fy := x.Float(), y.Float()\n\t\treturn fx < fy || math.IsNaN(fx) && !math.IsNaN(fy)\n\tcase reflect.Complex64, reflect.Complex128:\n\t\tcx, cy := x.Complex(), y.Complex()\n\t\trx, ix, ry, iy := real(cx), imag(cx), real(cy), imag(cy)\n\t\tif rx == ry || (math.IsNaN(rx) && math.IsNaN(ry)) {\n\t\t\treturn ix < iy || math.IsNaN(ix) && !math.IsNaN(iy)\n\t\t}\n\t\treturn rx < ry || math.IsNaN(rx) && !math.IsNaN(ry)\n\tcase reflect.Ptr, reflect.UnsafePointer, reflect.Chan:\n\t\treturn x.Pointer() < y.Pointer()\n\tcase reflect.String:\n\t\treturn x.String() < y.String()\n\tcase reflect.Array:\n\t\tfor i := 0; i < x.Len(); i++ {\n\t\t\tif isLess(x.Index(i), y.Index(i)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif isLess(y.Index(i), x.Index(i)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn false\n\tcase reflect.Struct:\n\t\tfor i := 0; i < x.NumField(); i++ {\n\t\t\tif isLess(x.Field(i), y.Field(i)) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif isLess(y.Field(i), x.Field(i)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn false\n\tcase reflect.Interface:\n\t\tvx, vy := x.Elem(), y.Elem()\n\t\tif !vx.IsValid() || !vy.IsValid() {\n\t\t\treturn !vx.IsValid() && vy.IsValid()\n\t\t}\n\t\ttx, ty := vx.Type(), vy.Type()\n\t\tif tx == ty {\n\t\t\treturn isLess(x.Elem(), y.Elem())\n\t\t}\n\t\tif tx.Kind() != ty.Kind() {\n\t\t\treturn vx.Kind() < vy.Kind()\n\t\t}\n\t\tif tx.String() != ty.String() {\n\t\t\treturn tx.String() < ty.String()\n\t\t}\n\t\tif tx.PkgPath() != ty.PkgPath() {\n\t\t\treturn tx.PkgPath() < ty.PkgPath()\n\t\t}\n\t\t// This can happen in rare situations, so we fallback to just comparing\n\t\t// the unique pointer for a reflect.Type. This guarantees deterministic\n\t\t// ordering within a program, but it is obviously not stable.\n\t\treturn reflect.ValueOf(vx.Type()).Pointer() < reflect.ValueOf(vy.Type()).Pointer()\n\tdefault:\n\t\t// Must be Func, Map, or Slice; which are not comparable.\n\t\tpanic(fmt.Sprintf(\"%T is not comparable\", x.Type()))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/options.go",
    "content": "// Copyright 2017, 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 cmp\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/google/go-cmp/cmp/internal/function\"\n)\n\n// Option configures for specific behavior of [Equal] and [Diff]. In particular,\n// the fundamental Option functions ([Ignore], [Transformer], and [Comparer]),\n// configure how equality is determined.\n//\n// The fundamental options may be composed with filters ([FilterPath] and\n// [FilterValues]) to control the scope over which they are applied.\n//\n// The [github.com/google/go-cmp/cmp/cmpopts] package provides helper functions\n// for creating options that may be used with [Equal] and [Diff].\ntype Option interface {\n\t// filter applies all filters and returns the option that remains.\n\t// Each option may only read s.curPath and call s.callTTBFunc.\n\t//\n\t// An Options is returned only if multiple comparers or transformers\n\t// can apply simultaneously and will only contain values of those types\n\t// or sub-Options containing values of those types.\n\tfilter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption\n}\n\n// applicableOption represents the following types:\n//\n//\tFundamental: ignore | validator | *comparer | *transformer\n//\tGrouping:    Options\ntype applicableOption interface {\n\tOption\n\n\t// apply executes the option, which may mutate s or panic.\n\tapply(s *state, vx, vy reflect.Value)\n}\n\n// coreOption represents the following types:\n//\n//\tFundamental: ignore | validator | *comparer | *transformer\n//\tFilters:     *pathFilter | *valuesFilter\ntype coreOption interface {\n\tOption\n\tisCore()\n}\n\ntype core struct{}\n\nfunc (core) isCore() {}\n\n// Options is a list of [Option] values that also satisfies the [Option] interface.\n// Helper comparison packages may return an Options value when packing multiple\n// [Option] values into a single [Option]. When this package processes an Options,\n// it will be implicitly expanded into a flat list.\n//\n// Applying a filter on an Options is equivalent to applying that same filter\n// on all individual options held within.\ntype Options []Option\n\nfunc (opts Options) filter(s *state, t reflect.Type, vx, vy reflect.Value) (out applicableOption) {\n\tfor _, opt := range opts {\n\t\tswitch opt := opt.filter(s, t, vx, vy); opt.(type) {\n\t\tcase ignore:\n\t\t\treturn ignore{} // Only ignore can short-circuit evaluation\n\t\tcase validator:\n\t\t\tout = validator{} // Takes precedence over comparer or transformer\n\t\tcase *comparer, *transformer, Options:\n\t\t\tswitch out.(type) {\n\t\t\tcase nil:\n\t\t\t\tout = opt\n\t\t\tcase validator:\n\t\t\t\t// Keep validator\n\t\t\tcase *comparer, *transformer, Options:\n\t\t\t\tout = Options{out, opt} // Conflicting comparers or transformers\n\t\t\t}\n\t\t}\n\t}\n\treturn out\n}\n\nfunc (opts Options) apply(s *state, _, _ reflect.Value) {\n\tconst warning = \"ambiguous set of applicable options\"\n\tconst help = \"consider using filters to ensure at most one Comparer or Transformer may apply\"\n\tvar ss []string\n\tfor _, opt := range flattenOptions(nil, opts) {\n\t\tss = append(ss, fmt.Sprint(opt))\n\t}\n\tset := strings.Join(ss, \"\\n\\t\")\n\tpanic(fmt.Sprintf(\"%s at %#v:\\n\\t%s\\n%s\", warning, s.curPath, set, help))\n}\n\nfunc (opts Options) String() string {\n\tvar ss []string\n\tfor _, opt := range opts {\n\t\tss = append(ss, fmt.Sprint(opt))\n\t}\n\treturn fmt.Sprintf(\"Options{%s}\", strings.Join(ss, \", \"))\n}\n\n// FilterPath returns a new [Option] where opt is only evaluated if filter f\n// returns true for the current [Path] in the value tree.\n//\n// This filter is called even if a slice element or map entry is missing and\n// provides an opportunity to ignore such cases. The filter function must be\n// symmetric such that the filter result is identical regardless of whether the\n// missing value is from x or y.\n//\n// The option passed in may be an [Ignore], [Transformer], [Comparer], [Options], or\n// a previously filtered [Option].\nfunc FilterPath(f func(Path) bool, opt Option) Option {\n\tif f == nil {\n\t\tpanic(\"invalid path filter function\")\n\t}\n\tif opt := normalizeOption(opt); opt != nil {\n\t\treturn &pathFilter{fnc: f, opt: opt}\n\t}\n\treturn nil\n}\n\ntype pathFilter struct {\n\tcore\n\tfnc func(Path) bool\n\topt Option\n}\n\nfunc (f pathFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption {\n\tif f.fnc(s.curPath) {\n\t\treturn f.opt.filter(s, t, vx, vy)\n\t}\n\treturn nil\n}\n\nfunc (f pathFilter) String() string {\n\treturn fmt.Sprintf(\"FilterPath(%s, %v)\", function.NameOf(reflect.ValueOf(f.fnc)), f.opt)\n}\n\n// FilterValues returns a new [Option] where opt is only evaluated if filter f,\n// which is a function of the form \"func(T, T) bool\", returns true for the\n// current pair of values being compared. If either value is invalid or\n// the type of the values is not assignable to T, then this filter implicitly\n// returns false.\n//\n// The filter function must be\n// symmetric (i.e., agnostic to the order of the inputs) and\n// deterministic (i.e., produces the same result when given the same inputs).\n// If T is an interface, it is possible that f is called with two values with\n// different concrete types that both implement T.\n//\n// The option passed in may be an [Ignore], [Transformer], [Comparer], [Options], or\n// a previously filtered [Option].\nfunc FilterValues(f interface{}, opt Option) Option {\n\tv := reflect.ValueOf(f)\n\tif !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() {\n\t\tpanic(fmt.Sprintf(\"invalid values filter function: %T\", f))\n\t}\n\tif opt := normalizeOption(opt); opt != nil {\n\t\tvf := &valuesFilter{fnc: v, opt: opt}\n\t\tif ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {\n\t\t\tvf.typ = ti\n\t\t}\n\t\treturn vf\n\t}\n\treturn nil\n}\n\ntype valuesFilter struct {\n\tcore\n\ttyp reflect.Type  // T\n\tfnc reflect.Value // func(T, T) bool\n\topt Option\n}\n\nfunc (f valuesFilter) filter(s *state, t reflect.Type, vx, vy reflect.Value) applicableOption {\n\tif !vx.IsValid() || !vx.CanInterface() || !vy.IsValid() || !vy.CanInterface() {\n\t\treturn nil\n\t}\n\tif (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) {\n\t\treturn f.opt.filter(s, t, vx, vy)\n\t}\n\treturn nil\n}\n\nfunc (f valuesFilter) String() string {\n\treturn fmt.Sprintf(\"FilterValues(%s, %v)\", function.NameOf(f.fnc), f.opt)\n}\n\n// Ignore is an [Option] that causes all comparisons to be ignored.\n// This value is intended to be combined with [FilterPath] or [FilterValues].\n// It is an error to pass an unfiltered Ignore option to [Equal].\nfunc Ignore() Option { return ignore{} }\n\ntype ignore struct{ core }\n\nfunc (ignore) isFiltered() bool                                                     { return false }\nfunc (ignore) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption { return ignore{} }\nfunc (ignore) apply(s *state, _, _ reflect.Value)                                   { s.report(true, reportByIgnore) }\nfunc (ignore) String() string                                                       { return \"Ignore()\" }\n\n// validator is a sentinel Option type to indicate that some options could not\n// be evaluated due to unexported fields, missing slice elements, or\n// missing map entries. Both values are validator only for unexported fields.\ntype validator struct{ core }\n\nfunc (validator) filter(_ *state, _ reflect.Type, vx, vy reflect.Value) applicableOption {\n\tif !vx.IsValid() || !vy.IsValid() {\n\t\treturn validator{}\n\t}\n\tif !vx.CanInterface() || !vy.CanInterface() {\n\t\treturn validator{}\n\t}\n\treturn nil\n}\nfunc (validator) apply(s *state, vx, vy reflect.Value) {\n\t// Implies missing slice element or map entry.\n\tif !vx.IsValid() || !vy.IsValid() {\n\t\ts.report(vx.IsValid() == vy.IsValid(), 0)\n\t\treturn\n\t}\n\n\t// Unable to Interface implies unexported field without visibility access.\n\tif !vx.CanInterface() || !vy.CanInterface() {\n\t\thelp := \"consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported\"\n\t\tvar name string\n\t\tif t := s.curPath.Index(-2).Type(); t.Name() != \"\" {\n\t\t\t// Named type with unexported fields.\n\t\t\tname = fmt.Sprintf(\"%q.%v\", t.PkgPath(), t.Name()) // e.g., \"path/to/package\".MyType\n\t\t\tif _, ok := reflect.New(t).Interface().(error); ok {\n\t\t\t\thelp = \"consider using cmpopts.EquateErrors to compare error values\"\n\t\t\t} else if t.Comparable() {\n\t\t\t\thelp = \"consider using cmpopts.EquateComparable to compare comparable Go types\"\n\t\t\t}\n\t\t} else {\n\t\t\t// Unnamed type with unexported fields. Derive PkgPath from field.\n\t\t\tvar pkgPath string\n\t\t\tfor i := 0; i < t.NumField() && pkgPath == \"\"; i++ {\n\t\t\t\tpkgPath = t.Field(i).PkgPath\n\t\t\t}\n\t\t\tname = fmt.Sprintf(\"%q.(%v)\", pkgPath, t.String()) // e.g., \"path/to/package\".(struct { a int })\n\t\t}\n\t\tpanic(fmt.Sprintf(\"cannot handle unexported field at %#v:\\n\\t%v\\n%s\", s.curPath, name, help))\n\t}\n\n\tpanic(\"not reachable\")\n}\n\n// identRx represents a valid identifier according to the Go specification.\nconst identRx = `[_\\p{L}][_\\p{L}\\p{N}]*`\n\nvar identsRx = regexp.MustCompile(`^` + identRx + `(\\.` + identRx + `)*$`)\n\n// Transformer returns an [Option] that applies a transformation function that\n// converts values of a certain type into that of another.\n//\n// The transformer f must be a function \"func(T) R\" that converts values of\n// type T to those of type R and is implicitly filtered to input values\n// assignable to T. The transformer must not mutate T in any way.\n//\n// To help prevent some cases of infinite recursive cycles applying the\n// same transform to the output of itself (e.g., in the case where the\n// input and output types are the same), an implicit filter is added such that\n// a transformer is applicable only if that exact transformer is not already\n// in the tail of the [Path] since the last non-[Transform] step.\n// For situations where the implicit filter is still insufficient,\n// consider using [github.com/google/go-cmp/cmp/cmpopts.AcyclicTransformer],\n// which adds a filter to prevent the transformer from\n// being recursively applied upon itself.\n//\n// The name is a user provided label that is used as the [Transform.Name] in the\n// transformation [PathStep] (and eventually shown in the [Diff] output).\n// The name must be a valid identifier or qualified identifier in Go syntax.\n// If empty, an arbitrary name is used.\nfunc Transformer(name string, f interface{}) Option {\n\tv := reflect.ValueOf(f)\n\tif !function.IsType(v.Type(), function.Transformer) || v.IsNil() {\n\t\tpanic(fmt.Sprintf(\"invalid transformer function: %T\", f))\n\t}\n\tif name == \"\" {\n\t\tname = function.NameOf(v)\n\t\tif !identsRx.MatchString(name) {\n\t\t\tname = \"λ\" // Lambda-symbol as placeholder name\n\t\t}\n\t} else if !identsRx.MatchString(name) {\n\t\tpanic(fmt.Sprintf(\"invalid name: %q\", name))\n\t}\n\ttr := &transformer{name: name, fnc: reflect.ValueOf(f)}\n\tif ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {\n\t\ttr.typ = ti\n\t}\n\treturn tr\n}\n\ntype transformer struct {\n\tcore\n\tname string\n\ttyp  reflect.Type  // T\n\tfnc  reflect.Value // func(T) R\n}\n\nfunc (tr *transformer) isFiltered() bool { return tr.typ != nil }\n\nfunc (tr *transformer) filter(s *state, t reflect.Type, _, _ reflect.Value) applicableOption {\n\tfor i := len(s.curPath) - 1; i >= 0; i-- {\n\t\tif t, ok := s.curPath[i].(Transform); !ok {\n\t\t\tbreak // Hit most recent non-Transform step\n\t\t} else if tr == t.trans {\n\t\t\treturn nil // Cannot directly use same Transform\n\t\t}\n\t}\n\tif tr.typ == nil || t.AssignableTo(tr.typ) {\n\t\treturn tr\n\t}\n\treturn nil\n}\n\nfunc (tr *transformer) apply(s *state, vx, vy reflect.Value) {\n\tstep := Transform{&transform{pathStep{typ: tr.fnc.Type().Out(0)}, tr}}\n\tvvx := s.callTRFunc(tr.fnc, vx, step)\n\tvvy := s.callTRFunc(tr.fnc, vy, step)\n\tstep.vx, step.vy = vvx, vvy\n\ts.compareAny(step)\n}\n\nfunc (tr transformer) String() string {\n\treturn fmt.Sprintf(\"Transformer(%s, %s)\", tr.name, function.NameOf(tr.fnc))\n}\n\n// Comparer returns an [Option] that determines whether two values are equal\n// to each other.\n//\n// The comparer f must be a function \"func(T, T) bool\" and is implicitly\n// filtered to input values assignable to T. If T is an interface, it is\n// possible that f is called with two values of different concrete types that\n// both implement T.\n//\n// The equality function must be:\n//   - Symmetric: equal(x, y) == equal(y, x)\n//   - Deterministic: equal(x, y) == equal(x, y)\n//   - Pure: equal(x, y) does not modify x or y\nfunc Comparer(f interface{}) Option {\n\tv := reflect.ValueOf(f)\n\tif !function.IsType(v.Type(), function.Equal) || v.IsNil() {\n\t\tpanic(fmt.Sprintf(\"invalid comparer function: %T\", f))\n\t}\n\tcm := &comparer{fnc: v}\n\tif ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {\n\t\tcm.typ = ti\n\t}\n\treturn cm\n}\n\ntype comparer struct {\n\tcore\n\ttyp reflect.Type  // T\n\tfnc reflect.Value // func(T, T) bool\n}\n\nfunc (cm *comparer) isFiltered() bool { return cm.typ != nil }\n\nfunc (cm *comparer) filter(_ *state, t reflect.Type, _, _ reflect.Value) applicableOption {\n\tif cm.typ == nil || t.AssignableTo(cm.typ) {\n\t\treturn cm\n\t}\n\treturn nil\n}\n\nfunc (cm *comparer) apply(s *state, vx, vy reflect.Value) {\n\teq := s.callTTBFunc(cm.fnc, vx, vy)\n\ts.report(eq, reportByFunc)\n}\n\nfunc (cm comparer) String() string {\n\treturn fmt.Sprintf(\"Comparer(%s)\", function.NameOf(cm.fnc))\n}\n\n// Exporter returns an [Option] that specifies whether [Equal] is allowed to\n// introspect into the unexported fields of certain struct types.\n//\n// Users of this option must understand that comparing on unexported fields\n// from external packages is not safe since changes in the internal\n// implementation of some external package may cause the result of [Equal]\n// to unexpectedly change. However, it may be valid to use this option on types\n// defined in an internal package where the semantic meaning of an unexported\n// field is in the control of the user.\n//\n// In many cases, a custom [Comparer] should be used instead that defines\n// equality as a function of the public API of a type rather than the underlying\n// unexported implementation.\n//\n// For example, the [reflect.Type] documentation defines equality to be determined\n// by the == operator on the interface (essentially performing a shallow pointer\n// comparison) and most attempts to compare *[regexp.Regexp] types are interested\n// in only checking that the regular expression strings are equal.\n// Both of these are accomplished using [Comparer] options:\n//\n//\tComparer(func(x, y reflect.Type) bool { return x == y })\n//\tComparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() })\n//\n// In other cases, the [github.com/google/go-cmp/cmp/cmpopts.IgnoreUnexported]\n// option can be used to ignore all unexported fields on specified struct types.\nfunc Exporter(f func(reflect.Type) bool) Option {\n\treturn exporter(f)\n}\n\ntype exporter func(reflect.Type) bool\n\nfunc (exporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption {\n\tpanic(\"not implemented\")\n}\n\n// AllowUnexported returns an [Option] that allows [Equal] to forcibly introspect\n// unexported fields of the specified struct types.\n//\n// See [Exporter] for the proper use of this option.\nfunc AllowUnexported(types ...interface{}) Option {\n\tm := make(map[reflect.Type]bool)\n\tfor _, typ := range types {\n\t\tt := reflect.TypeOf(typ)\n\t\tif t.Kind() != reflect.Struct {\n\t\t\tpanic(fmt.Sprintf(\"invalid struct type: %T\", typ))\n\t\t}\n\t\tm[t] = true\n\t}\n\treturn exporter(func(t reflect.Type) bool { return m[t] })\n}\n\n// Result represents the comparison result for a single node and\n// is provided by cmp when calling Report (see [Reporter]).\ntype Result struct {\n\t_     [0]func() // Make Result incomparable\n\tflags resultFlags\n}\n\n// Equal reports whether the node was determined to be equal or not.\n// As a special case, ignored nodes are considered equal.\nfunc (r Result) Equal() bool {\n\treturn r.flags&(reportEqual|reportByIgnore) != 0\n}\n\n// ByIgnore reports whether the node is equal because it was ignored.\n// This never reports true if [Result.Equal] reports false.\nfunc (r Result) ByIgnore() bool {\n\treturn r.flags&reportByIgnore != 0\n}\n\n// ByMethod reports whether the Equal method determined equality.\nfunc (r Result) ByMethod() bool {\n\treturn r.flags&reportByMethod != 0\n}\n\n// ByFunc reports whether a [Comparer] function determined equality.\nfunc (r Result) ByFunc() bool {\n\treturn r.flags&reportByFunc != 0\n}\n\n// ByCycle reports whether a reference cycle was detected.\nfunc (r Result) ByCycle() bool {\n\treturn r.flags&reportByCycle != 0\n}\n\ntype resultFlags uint\n\nconst (\n\t_ resultFlags = (1 << iota) / 2\n\n\treportEqual\n\treportUnequal\n\treportByIgnore\n\treportByMethod\n\treportByFunc\n\treportByCycle\n)\n\n// Reporter is an [Option] that can be passed to [Equal]. When [Equal] traverses\n// the value trees, it calls PushStep as it descends into each node in the\n// tree and PopStep as it ascend out of the node. The leaves of the tree are\n// either compared (determined to be equal or not equal) or ignored and reported\n// as such by calling the Report method.\nfunc Reporter(r interface {\n\t// PushStep is called when a tree-traversal operation is performed.\n\t// The PathStep itself is only valid until the step is popped.\n\t// The PathStep.Values are valid for the duration of the entire traversal\n\t// and must not be mutated.\n\t//\n\t// Equal always calls PushStep at the start to provide an operation-less\n\t// PathStep used to report the root values.\n\t//\n\t// Within a slice, the exact set of inserted, removed, or modified elements\n\t// is unspecified and may change in future implementations.\n\t// The entries of a map are iterated through in an unspecified order.\n\tPushStep(PathStep)\n\n\t// Report is called exactly once on leaf nodes to report whether the\n\t// comparison identified the node as equal, unequal, or ignored.\n\t// A leaf node is one that is immediately preceded by and followed by\n\t// a pair of PushStep and PopStep calls.\n\tReport(Result)\n\n\t// PopStep ascends back up the value tree.\n\t// There is always a matching pop call for every push call.\n\tPopStep()\n}) Option {\n\treturn reporter{r}\n}\n\ntype reporter struct{ reporterIface }\ntype reporterIface interface {\n\tPushStep(PathStep)\n\tReport(Result)\n\tPopStep()\n}\n\nfunc (reporter) filter(_ *state, _ reflect.Type, _, _ reflect.Value) applicableOption {\n\tpanic(\"not implemented\")\n}\n\n// normalizeOption normalizes the input options such that all Options groups\n// are flattened and groups with a single element are reduced to that element.\n// Only coreOptions and Options containing coreOptions are allowed.\nfunc normalizeOption(src Option) Option {\n\tswitch opts := flattenOptions(nil, Options{src}); len(opts) {\n\tcase 0:\n\t\treturn nil\n\tcase 1:\n\t\treturn opts[0]\n\tdefault:\n\t\treturn opts\n\t}\n}\n\n// flattenOptions copies all options in src to dst as a flat list.\n// Only coreOptions and Options containing coreOptions are allowed.\nfunc flattenOptions(dst, src Options) Options {\n\tfor _, opt := range src {\n\t\tswitch opt := opt.(type) {\n\t\tcase nil:\n\t\t\tcontinue\n\t\tcase Options:\n\t\t\tdst = flattenOptions(dst, opt)\n\t\tcase coreOption:\n\t\t\tdst = append(dst, opt)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"invalid option type: %T\", opt))\n\t\t}\n\t}\n\treturn dst\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/path.go",
    "content": "// Copyright 2017, 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 cmp\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/google/go-cmp/cmp/internal/value\"\n)\n\n// Path is a list of [PathStep] describing the sequence of operations to get\n// from some root type to the current position in the value tree.\n// The first Path element is always an operation-less [PathStep] that exists\n// simply to identify the initial type.\n//\n// When traversing structs with embedded structs, the embedded struct will\n// always be accessed as a field before traversing the fields of the\n// embedded struct themselves. That is, an exported field from the\n// embedded struct will never be accessed directly from the parent struct.\ntype Path []PathStep\n\n// PathStep is a union-type for specific operations to traverse\n// a value's tree structure. Users of this package never need to implement\n// these types as values of this type will be returned by this package.\n//\n// Implementations of this interface:\n//   - [StructField]\n//   - [SliceIndex]\n//   - [MapIndex]\n//   - [Indirect]\n//   - [TypeAssertion]\n//   - [Transform]\ntype PathStep interface {\n\tString() string\n\n\t// Type is the resulting type after performing the path step.\n\tType() reflect.Type\n\n\t// Values is the resulting values after performing the path step.\n\t// The type of each valid value is guaranteed to be identical to Type.\n\t//\n\t// In some cases, one or both may be invalid or have restrictions:\n\t//   - For StructField, both are not interface-able if the current field\n\t//     is unexported and the struct type is not explicitly permitted by\n\t//     an Exporter to traverse unexported fields.\n\t//   - For SliceIndex, one may be invalid if an element is missing from\n\t//     either the x or y slice.\n\t//   - For MapIndex, one may be invalid if an entry is missing from\n\t//     either the x or y map.\n\t//\n\t// The provided values must not be mutated.\n\tValues() (vx, vy reflect.Value)\n}\n\nvar (\n\t_ PathStep = StructField{}\n\t_ PathStep = SliceIndex{}\n\t_ PathStep = MapIndex{}\n\t_ PathStep = Indirect{}\n\t_ PathStep = TypeAssertion{}\n\t_ PathStep = Transform{}\n)\n\nfunc (pa *Path) push(s PathStep) {\n\t*pa = append(*pa, s)\n}\n\nfunc (pa *Path) pop() {\n\t*pa = (*pa)[:len(*pa)-1]\n}\n\n// Last returns the last [PathStep] in the Path.\n// If the path is empty, this returns a non-nil [PathStep]\n// that reports a nil [PathStep.Type].\nfunc (pa Path) Last() PathStep {\n\treturn pa.Index(-1)\n}\n\n// Index returns the ith step in the Path and supports negative indexing.\n// A negative index starts counting from the tail of the Path such that -1\n// refers to the last step, -2 refers to the second-to-last step, and so on.\n// If index is invalid, this returns a non-nil [PathStep]\n// that reports a nil [PathStep.Type].\nfunc (pa Path) Index(i int) PathStep {\n\tif i < 0 {\n\t\ti = len(pa) + i\n\t}\n\tif i < 0 || i >= len(pa) {\n\t\treturn pathStep{}\n\t}\n\treturn pa[i]\n}\n\n// String returns the simplified path to a node.\n// The simplified path only contains struct field accesses.\n//\n// For example:\n//\n//\tMyMap.MySlices.MyField\nfunc (pa Path) String() string {\n\tvar ss []string\n\tfor _, s := range pa {\n\t\tif _, ok := s.(StructField); ok {\n\t\t\tss = append(ss, s.String())\n\t\t}\n\t}\n\treturn strings.TrimPrefix(strings.Join(ss, \"\"), \".\")\n}\n\n// GoString returns the path to a specific node using Go syntax.\n//\n// For example:\n//\n//\t(*root.MyMap[\"key\"].(*mypkg.MyStruct).MySlices)[2][3].MyField\nfunc (pa Path) GoString() string {\n\tvar ssPre, ssPost []string\n\tvar numIndirect int\n\tfor i, s := range pa {\n\t\tvar nextStep PathStep\n\t\tif i+1 < len(pa) {\n\t\t\tnextStep = pa[i+1]\n\t\t}\n\t\tswitch s := s.(type) {\n\t\tcase Indirect:\n\t\t\tnumIndirect++\n\t\t\tpPre, pPost := \"(\", \")\"\n\t\t\tswitch nextStep.(type) {\n\t\t\tcase Indirect:\n\t\t\t\tcontinue // Next step is indirection, so let them batch up\n\t\t\tcase StructField:\n\t\t\t\tnumIndirect-- // Automatic indirection on struct fields\n\t\t\tcase nil:\n\t\t\t\tpPre, pPost = \"\", \"\" // Last step; no need for parenthesis\n\t\t\t}\n\t\t\tif numIndirect > 0 {\n\t\t\t\tssPre = append(ssPre, pPre+strings.Repeat(\"*\", numIndirect))\n\t\t\t\tssPost = append(ssPost, pPost)\n\t\t\t}\n\t\t\tnumIndirect = 0\n\t\t\tcontinue\n\t\tcase Transform:\n\t\t\tssPre = append(ssPre, s.trans.name+\"(\")\n\t\t\tssPost = append(ssPost, \")\")\n\t\t\tcontinue\n\t\t}\n\t\tssPost = append(ssPost, s.String())\n\t}\n\tfor i, j := 0, len(ssPre)-1; i < j; i, j = i+1, j-1 {\n\t\tssPre[i], ssPre[j] = ssPre[j], ssPre[i]\n\t}\n\treturn strings.Join(ssPre, \"\") + strings.Join(ssPost, \"\")\n}\n\ntype pathStep struct {\n\ttyp    reflect.Type\n\tvx, vy reflect.Value\n}\n\nfunc (ps pathStep) Type() reflect.Type             { return ps.typ }\nfunc (ps pathStep) Values() (vx, vy reflect.Value) { return ps.vx, ps.vy }\nfunc (ps pathStep) String() string {\n\tif ps.typ == nil {\n\t\treturn \"<nil>\"\n\t}\n\ts := value.TypeString(ps.typ, false)\n\tif s == \"\" || strings.ContainsAny(s, \"{}\\n\") {\n\t\treturn \"root\" // Type too simple or complex to print\n\t}\n\treturn fmt.Sprintf(\"{%s}\", s)\n}\n\n// StructField is a [PathStep] that represents a struct field access\n// on a field called [StructField.Name].\ntype StructField struct{ *structField }\ntype structField struct {\n\tpathStep\n\tname string\n\tidx  int\n\n\t// These fields are used for forcibly accessing an unexported field.\n\t// pvx, pvy, and field are only valid if unexported is true.\n\tunexported bool\n\tmayForce   bool                // Forcibly allow visibility\n\tpaddr      bool                // Was parent addressable?\n\tpvx, pvy   reflect.Value       // Parent values (always addressable)\n\tfield      reflect.StructField // Field information\n}\n\nfunc (sf StructField) Type() reflect.Type { return sf.typ }\nfunc (sf StructField) Values() (vx, vy reflect.Value) {\n\tif !sf.unexported {\n\t\treturn sf.vx, sf.vy // CanInterface reports true\n\t}\n\n\t// Forcibly obtain read-write access to an unexported struct field.\n\tif sf.mayForce {\n\t\tvx = retrieveUnexportedField(sf.pvx, sf.field, sf.paddr)\n\t\tvy = retrieveUnexportedField(sf.pvy, sf.field, sf.paddr)\n\t\treturn vx, vy // CanInterface reports true\n\t}\n\treturn sf.vx, sf.vy // CanInterface reports false\n}\nfunc (sf StructField) String() string { return fmt.Sprintf(\".%s\", sf.name) }\n\n// Name is the field name.\nfunc (sf StructField) Name() string { return sf.name }\n\n// Index is the index of the field in the parent struct type.\n// See [reflect.Type.Field].\nfunc (sf StructField) Index() int { return sf.idx }\n\n// SliceIndex is a [PathStep] that represents an index operation on\n// a slice or array at some index [SliceIndex.Key].\ntype SliceIndex struct{ *sliceIndex }\ntype sliceIndex struct {\n\tpathStep\n\txkey, ykey int\n\tisSlice    bool // False for reflect.Array\n}\n\nfunc (si SliceIndex) Type() reflect.Type             { return si.typ }\nfunc (si SliceIndex) Values() (vx, vy reflect.Value) { return si.vx, si.vy }\nfunc (si SliceIndex) String() string {\n\tswitch {\n\tcase si.xkey == si.ykey:\n\t\treturn fmt.Sprintf(\"[%d]\", si.xkey)\n\tcase si.ykey == -1:\n\t\t// [5->?] means \"I don't know where X[5] went\"\n\t\treturn fmt.Sprintf(\"[%d->?]\", si.xkey)\n\tcase si.xkey == -1:\n\t\t// [?->3] means \"I don't know where Y[3] came from\"\n\t\treturn fmt.Sprintf(\"[?->%d]\", si.ykey)\n\tdefault:\n\t\t// [5->3] means \"X[5] moved to Y[3]\"\n\t\treturn fmt.Sprintf(\"[%d->%d]\", si.xkey, si.ykey)\n\t}\n}\n\n// Key is the index key; it may return -1 if in a split state\nfunc (si SliceIndex) Key() int {\n\tif si.xkey != si.ykey {\n\t\treturn -1\n\t}\n\treturn si.xkey\n}\n\n// SplitKeys are the indexes for indexing into slices in the\n// x and y values, respectively. These indexes may differ due to the\n// insertion or removal of an element in one of the slices, causing\n// all of the indexes to be shifted. If an index is -1, then that\n// indicates that the element does not exist in the associated slice.\n//\n// [SliceIndex.Key] is guaranteed to return -1 if and only if the indexes\n// returned by SplitKeys are not the same. SplitKeys will never return -1 for\n// both indexes.\nfunc (si SliceIndex) SplitKeys() (ix, iy int) { return si.xkey, si.ykey }\n\n// MapIndex is a [PathStep] that represents an index operation on a map at some index Key.\ntype MapIndex struct{ *mapIndex }\ntype mapIndex struct {\n\tpathStep\n\tkey reflect.Value\n}\n\nfunc (mi MapIndex) Type() reflect.Type             { return mi.typ }\nfunc (mi MapIndex) Values() (vx, vy reflect.Value) { return mi.vx, mi.vy }\nfunc (mi MapIndex) String() string                 { return fmt.Sprintf(\"[%#v]\", mi.key) }\n\n// Key is the value of the map key.\nfunc (mi MapIndex) Key() reflect.Value { return mi.key }\n\n// Indirect is a [PathStep] that represents pointer indirection on the parent type.\ntype Indirect struct{ *indirect }\ntype indirect struct {\n\tpathStep\n}\n\nfunc (in Indirect) Type() reflect.Type             { return in.typ }\nfunc (in Indirect) Values() (vx, vy reflect.Value) { return in.vx, in.vy }\nfunc (in Indirect) String() string                 { return \"*\" }\n\n// TypeAssertion is a [PathStep] that represents a type assertion on an interface.\ntype TypeAssertion struct{ *typeAssertion }\ntype typeAssertion struct {\n\tpathStep\n}\n\nfunc (ta TypeAssertion) Type() reflect.Type             { return ta.typ }\nfunc (ta TypeAssertion) Values() (vx, vy reflect.Value) { return ta.vx, ta.vy }\nfunc (ta TypeAssertion) String() string                 { return fmt.Sprintf(\".(%v)\", value.TypeString(ta.typ, false)) }\n\n// Transform is a [PathStep] that represents a transformation\n// from the parent type to the current type.\ntype Transform struct{ *transform }\ntype transform struct {\n\tpathStep\n\ttrans *transformer\n}\n\nfunc (tf Transform) Type() reflect.Type             { return tf.typ }\nfunc (tf Transform) Values() (vx, vy reflect.Value) { return tf.vx, tf.vy }\nfunc (tf Transform) String() string                 { return fmt.Sprintf(\"%s()\", tf.trans.name) }\n\n// Name is the name of the [Transformer].\nfunc (tf Transform) Name() string { return tf.trans.name }\n\n// Func is the function pointer to the transformer function.\nfunc (tf Transform) Func() reflect.Value { return tf.trans.fnc }\n\n// Option returns the originally constructed [Transformer] option.\n// The == operator can be used to detect the exact option used.\nfunc (tf Transform) Option() Option { return tf.trans }\n\n// pointerPath represents a dual-stack of pointers encountered when\n// recursively traversing the x and y values. This data structure supports\n// detection of cycles and determining whether the cycles are equal.\n// In Go, cycles can occur via pointers, slices, and maps.\n//\n// The pointerPath uses a map to represent a stack; where descension into a\n// pointer pushes the address onto the stack, and ascension from a pointer\n// pops the address from the stack. Thus, when traversing into a pointer from\n// reflect.Ptr, reflect.Slice element, or reflect.Map, we can detect cycles\n// by checking whether the pointer has already been visited. The cycle detection\n// uses a separate stack for the x and y values.\n//\n// If a cycle is detected we need to determine whether the two pointers\n// should be considered equal. The definition of equality chosen by Equal\n// requires two graphs to have the same structure. To determine this, both the\n// x and y values must have a cycle where the previous pointers were also\n// encountered together as a pair.\n//\n// Semantically, this is equivalent to augmenting Indirect, SliceIndex, and\n// MapIndex with pointer information for the x and y values.\n// Suppose px and py are two pointers to compare, we then search the\n// Path for whether px was ever encountered in the Path history of x, and\n// similarly so with py. If either side has a cycle, the comparison is only\n// equal if both px and py have a cycle resulting from the same PathStep.\n//\n// Using a map as a stack is more performant as we can perform cycle detection\n// in O(1) instead of O(N) where N is len(Path).\ntype pointerPath struct {\n\t// mx is keyed by x pointers, where the value is the associated y pointer.\n\tmx map[value.Pointer]value.Pointer\n\t// my is keyed by y pointers, where the value is the associated x pointer.\n\tmy map[value.Pointer]value.Pointer\n}\n\nfunc (p *pointerPath) Init() {\n\tp.mx = make(map[value.Pointer]value.Pointer)\n\tp.my = make(map[value.Pointer]value.Pointer)\n}\n\n// Push indicates intent to descend into pointers vx and vy where\n// visited reports whether either has been seen before. If visited before,\n// equal reports whether both pointers were encountered together.\n// Pop must be called if and only if the pointers were never visited.\n//\n// The pointers vx and vy must be a reflect.Ptr, reflect.Slice, or reflect.Map\n// and be non-nil.\nfunc (p pointerPath) Push(vx, vy reflect.Value) (equal, visited bool) {\n\tpx := value.PointerOf(vx)\n\tpy := value.PointerOf(vy)\n\t_, ok1 := p.mx[px]\n\t_, ok2 := p.my[py]\n\tif ok1 || ok2 {\n\t\tequal = p.mx[px] == py && p.my[py] == px // Pointers paired together\n\t\treturn equal, true\n\t}\n\tp.mx[px] = py\n\tp.my[py] = px\n\treturn false, false\n}\n\n// Pop ascends from pointers vx and vy.\nfunc (p pointerPath) Pop(vx, vy reflect.Value) {\n\tdelete(p.mx, value.PointerOf(vx))\n\tdelete(p.my, value.PointerOf(vy))\n}\n\n// isExported reports whether the identifier is exported.\nfunc isExported(id string) bool {\n\tr, _ := utf8.DecodeRuneInString(id)\n\treturn unicode.IsUpper(r)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/report.go",
    "content": "// Copyright 2017, 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 cmp\n\n// defaultReporter implements the reporter interface.\n//\n// As Equal serially calls the PushStep, Report, and PopStep methods, the\n// defaultReporter constructs a tree-based representation of the compared value\n// and the result of each comparison (see valueNode).\n//\n// When the String method is called, the FormatDiff method transforms the\n// valueNode tree into a textNode tree, which is a tree-based representation\n// of the textual output (see textNode).\n//\n// Lastly, the textNode.String method produces the final report as a string.\ntype defaultReporter struct {\n\troot *valueNode\n\tcurr *valueNode\n}\n\nfunc (r *defaultReporter) PushStep(ps PathStep) {\n\tr.curr = r.curr.PushStep(ps)\n\tif r.root == nil {\n\t\tr.root = r.curr\n\t}\n}\nfunc (r *defaultReporter) Report(rs Result) {\n\tr.curr.Report(rs)\n}\nfunc (r *defaultReporter) PopStep() {\n\tr.curr = r.curr.PopStep()\n}\n\n// String provides a full report of the differences detected as a structured\n// literal in pseudo-Go syntax. String may only be called after the entire tree\n// has been traversed.\nfunc (r *defaultReporter) String() string {\n\tassert(r.root != nil && r.curr == nil)\n\tif r.root.NumDiff == 0 {\n\t\treturn \"\"\n\t}\n\tptrs := new(pointerReferences)\n\ttext := formatOptions{}.FormatDiff(r.root, ptrs)\n\tresolveReferences(text)\n\treturn text.String()\n}\n\nfunc assert(ok bool) {\n\tif !ok {\n\t\tpanic(\"assertion failure\")\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/report_compare.go",
    "content": "// Copyright 2019, 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 cmp\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// numContextRecords is the number of surrounding equal records to print.\nconst numContextRecords = 2\n\ntype diffMode byte\n\nconst (\n\tdiffUnknown   diffMode = 0\n\tdiffIdentical diffMode = ' '\n\tdiffRemoved   diffMode = '-'\n\tdiffInserted  diffMode = '+'\n)\n\ntype typeMode int\n\nconst (\n\t// emitType always prints the type.\n\temitType typeMode = iota\n\t// elideType never prints the type.\n\telideType\n\t// autoType prints the type only for composite kinds\n\t// (i.e., structs, slices, arrays, and maps).\n\tautoType\n)\n\ntype formatOptions struct {\n\t// DiffMode controls the output mode of FormatDiff.\n\t//\n\t// If diffUnknown,   then produce a diff of the x and y values.\n\t// If diffIdentical, then emit values as if they were equal.\n\t// If diffRemoved,   then only emit x values (ignoring y values).\n\t// If diffInserted,  then only emit y values (ignoring x values).\n\tDiffMode diffMode\n\n\t// TypeMode controls whether to print the type for the current node.\n\t//\n\t// As a general rule of thumb, we always print the type of the next node\n\t// after an interface, and always elide the type of the next node after\n\t// a slice or map node.\n\tTypeMode typeMode\n\n\t// formatValueOptions are options specific to printing reflect.Values.\n\tformatValueOptions\n}\n\nfunc (opts formatOptions) WithDiffMode(d diffMode) formatOptions {\n\topts.DiffMode = d\n\treturn opts\n}\nfunc (opts formatOptions) WithTypeMode(t typeMode) formatOptions {\n\topts.TypeMode = t\n\treturn opts\n}\nfunc (opts formatOptions) WithVerbosity(level int) formatOptions {\n\topts.VerbosityLevel = level\n\topts.LimitVerbosity = true\n\treturn opts\n}\nfunc (opts formatOptions) verbosity() uint {\n\tswitch {\n\tcase opts.VerbosityLevel < 0:\n\t\treturn 0\n\tcase opts.VerbosityLevel > 16:\n\t\treturn 16 // some reasonable maximum to avoid shift overflow\n\tdefault:\n\t\treturn uint(opts.VerbosityLevel)\n\t}\n}\n\nconst maxVerbosityPreset = 6\n\n// verbosityPreset modifies the verbosity settings given an index\n// between 0 and maxVerbosityPreset, inclusive.\nfunc verbosityPreset(opts formatOptions, i int) formatOptions {\n\topts.VerbosityLevel = int(opts.verbosity()) + 2*i\n\tif i > 0 {\n\t\topts.AvoidStringer = true\n\t}\n\tif i >= maxVerbosityPreset {\n\t\topts.PrintAddresses = true\n\t\topts.QualifiedNames = true\n\t}\n\treturn opts\n}\n\n// FormatDiff converts a valueNode tree into a textNode tree, where the later\n// is a textual representation of the differences detected in the former.\nfunc (opts formatOptions) FormatDiff(v *valueNode, ptrs *pointerReferences) (out textNode) {\n\tif opts.DiffMode == diffIdentical {\n\t\topts = opts.WithVerbosity(1)\n\t} else if opts.verbosity() < 3 {\n\t\topts = opts.WithVerbosity(3)\n\t}\n\n\t// Check whether we have specialized formatting for this node.\n\t// This is not necessary, but helpful for producing more readable outputs.\n\tif opts.CanFormatDiffSlice(v) {\n\t\treturn opts.FormatDiffSlice(v)\n\t}\n\n\tvar parentKind reflect.Kind\n\tif v.parent != nil && v.parent.TransformerName == \"\" {\n\t\tparentKind = v.parent.Type.Kind()\n\t}\n\n\t// For leaf nodes, format the value based on the reflect.Values alone.\n\t// As a special case, treat equal []byte as a leaf nodes.\n\tisBytes := v.Type.Kind() == reflect.Slice && v.Type.Elem() == byteType\n\tisEqualBytes := isBytes && v.NumDiff+v.NumIgnored+v.NumTransformed == 0\n\tif v.MaxDepth == 0 || isEqualBytes {\n\t\tswitch opts.DiffMode {\n\t\tcase diffUnknown, diffIdentical:\n\t\t\t// Format Equal.\n\t\t\tif v.NumDiff == 0 {\n\t\t\t\toutx := opts.FormatValue(v.ValueX, parentKind, ptrs)\n\t\t\t\touty := opts.FormatValue(v.ValueY, parentKind, ptrs)\n\t\t\t\tif v.NumIgnored > 0 && v.NumSame == 0 {\n\t\t\t\t\treturn textEllipsis\n\t\t\t\t} else if outx.Len() < outy.Len() {\n\t\t\t\t\treturn outx\n\t\t\t\t} else {\n\t\t\t\t\treturn outy\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Format unequal.\n\t\t\tassert(opts.DiffMode == diffUnknown)\n\t\t\tvar list textList\n\t\t\toutx := opts.WithTypeMode(elideType).FormatValue(v.ValueX, parentKind, ptrs)\n\t\t\touty := opts.WithTypeMode(elideType).FormatValue(v.ValueY, parentKind, ptrs)\n\t\t\tfor i := 0; i <= maxVerbosityPreset && outx != nil && outy != nil && outx.Equal(outy); i++ {\n\t\t\t\topts2 := verbosityPreset(opts, i).WithTypeMode(elideType)\n\t\t\t\toutx = opts2.FormatValue(v.ValueX, parentKind, ptrs)\n\t\t\t\touty = opts2.FormatValue(v.ValueY, parentKind, ptrs)\n\t\t\t}\n\t\t\tif outx != nil {\n\t\t\t\tlist = append(list, textRecord{Diff: '-', Value: outx})\n\t\t\t}\n\t\t\tif outy != nil {\n\t\t\t\tlist = append(list, textRecord{Diff: '+', Value: outy})\n\t\t\t}\n\t\t\treturn opts.WithTypeMode(emitType).FormatType(v.Type, list)\n\t\tcase diffRemoved:\n\t\t\treturn opts.FormatValue(v.ValueX, parentKind, ptrs)\n\t\tcase diffInserted:\n\t\t\treturn opts.FormatValue(v.ValueY, parentKind, ptrs)\n\t\tdefault:\n\t\t\tpanic(\"invalid diff mode\")\n\t\t}\n\t}\n\n\t// Register slice element to support cycle detection.\n\tif parentKind == reflect.Slice {\n\t\tptrRefs := ptrs.PushPair(v.ValueX, v.ValueY, opts.DiffMode, true)\n\t\tdefer ptrs.Pop()\n\t\tdefer func() { out = wrapTrunkReferences(ptrRefs, out) }()\n\t}\n\n\t// Descend into the child value node.\n\tif v.TransformerName != \"\" {\n\t\tout := opts.WithTypeMode(emitType).FormatDiff(v.Value, ptrs)\n\t\tout = &textWrap{Prefix: \"Inverse(\" + v.TransformerName + \", \", Value: out, Suffix: \")\"}\n\t\treturn opts.FormatType(v.Type, out)\n\t} else {\n\t\tswitch k := v.Type.Kind(); k {\n\t\tcase reflect.Struct, reflect.Array, reflect.Slice:\n\t\t\tout = opts.formatDiffList(v.Records, k, ptrs)\n\t\t\tout = opts.FormatType(v.Type, out)\n\t\tcase reflect.Map:\n\t\t\t// Register map to support cycle detection.\n\t\t\tptrRefs := ptrs.PushPair(v.ValueX, v.ValueY, opts.DiffMode, false)\n\t\t\tdefer ptrs.Pop()\n\n\t\t\tout = opts.formatDiffList(v.Records, k, ptrs)\n\t\t\tout = wrapTrunkReferences(ptrRefs, out)\n\t\t\tout = opts.FormatType(v.Type, out)\n\t\tcase reflect.Ptr:\n\t\t\t// Register pointer to support cycle detection.\n\t\t\tptrRefs := ptrs.PushPair(v.ValueX, v.ValueY, opts.DiffMode, false)\n\t\t\tdefer ptrs.Pop()\n\n\t\t\tout = opts.FormatDiff(v.Value, ptrs)\n\t\t\tout = wrapTrunkReferences(ptrRefs, out)\n\t\t\tout = &textWrap{Prefix: \"&\", Value: out}\n\t\tcase reflect.Interface:\n\t\t\tout = opts.WithTypeMode(emitType).FormatDiff(v.Value, ptrs)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"%v cannot have children\", k))\n\t\t}\n\t\treturn out\n\t}\n}\n\nfunc (opts formatOptions) formatDiffList(recs []reportRecord, k reflect.Kind, ptrs *pointerReferences) textNode {\n\t// Derive record name based on the data structure kind.\n\tvar name string\n\tvar formatKey func(reflect.Value) string\n\tswitch k {\n\tcase reflect.Struct:\n\t\tname = \"field\"\n\t\topts = opts.WithTypeMode(autoType)\n\t\tformatKey = func(v reflect.Value) string { return v.String() }\n\tcase reflect.Slice, reflect.Array:\n\t\tname = \"element\"\n\t\topts = opts.WithTypeMode(elideType)\n\t\tformatKey = func(reflect.Value) string { return \"\" }\n\tcase reflect.Map:\n\t\tname = \"entry\"\n\t\topts = opts.WithTypeMode(elideType)\n\t\tformatKey = func(v reflect.Value) string { return formatMapKey(v, false, ptrs) }\n\t}\n\n\tmaxLen := -1\n\tif opts.LimitVerbosity {\n\t\tif opts.DiffMode == diffIdentical {\n\t\t\tmaxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc...\n\t\t} else {\n\t\t\tmaxLen = (1 << opts.verbosity()) << 1 // 2, 4, 8, 16, 32, 64, etc...\n\t\t}\n\t\topts.VerbosityLevel--\n\t}\n\n\t// Handle unification.\n\tswitch opts.DiffMode {\n\tcase diffIdentical, diffRemoved, diffInserted:\n\t\tvar list textList\n\t\tvar deferredEllipsis bool // Add final \"...\" to indicate records were dropped\n\t\tfor _, r := range recs {\n\t\t\tif len(list) == maxLen {\n\t\t\t\tdeferredEllipsis = true\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Elide struct fields that are zero value.\n\t\t\tif k == reflect.Struct {\n\t\t\t\tvar isZero bool\n\t\t\t\tswitch opts.DiffMode {\n\t\t\t\tcase diffIdentical:\n\t\t\t\t\tisZero = r.Value.ValueX.IsZero() || r.Value.ValueY.IsZero()\n\t\t\t\tcase diffRemoved:\n\t\t\t\t\tisZero = r.Value.ValueX.IsZero()\n\t\t\t\tcase diffInserted:\n\t\t\t\t\tisZero = r.Value.ValueY.IsZero()\n\t\t\t\t}\n\t\t\t\tif isZero {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Elide ignored nodes.\n\t\t\tif r.Value.NumIgnored > 0 && r.Value.NumSame+r.Value.NumDiff == 0 {\n\t\t\t\tdeferredEllipsis = !(k == reflect.Slice || k == reflect.Array)\n\t\t\t\tif !deferredEllipsis {\n\t\t\t\t\tlist.AppendEllipsis(diffStats{})\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif out := opts.FormatDiff(r.Value, ptrs); out != nil {\n\t\t\t\tlist = append(list, textRecord{Key: formatKey(r.Key), Value: out})\n\t\t\t}\n\t\t}\n\t\tif deferredEllipsis {\n\t\t\tlist.AppendEllipsis(diffStats{})\n\t\t}\n\t\treturn &textWrap{Prefix: \"{\", Value: list, Suffix: \"}\"}\n\tcase diffUnknown:\n\tdefault:\n\t\tpanic(\"invalid diff mode\")\n\t}\n\n\t// Handle differencing.\n\tvar numDiffs int\n\tvar list textList\n\tvar keys []reflect.Value // invariant: len(list) == len(keys)\n\tgroups := coalesceAdjacentRecords(name, recs)\n\tmaxGroup := diffStats{Name: name}\n\tfor i, ds := range groups {\n\t\tif maxLen >= 0 && numDiffs >= maxLen {\n\t\t\tmaxGroup = maxGroup.Append(ds)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Handle equal records.\n\t\tif ds.NumDiff() == 0 {\n\t\t\t// Compute the number of leading and trailing records to print.\n\t\t\tvar numLo, numHi int\n\t\t\tnumEqual := ds.NumIgnored + ds.NumIdentical\n\t\t\tfor numLo < numContextRecords && numLo+numHi < numEqual && i != 0 {\n\t\t\t\tif r := recs[numLo].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnumLo++\n\t\t\t}\n\t\t\tfor numHi < numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 {\n\t\t\t\tif r := recs[numEqual-numHi-1].Value; r.NumIgnored > 0 && r.NumSame+r.NumDiff == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tnumHi++\n\t\t\t}\n\t\t\tif numEqual-(numLo+numHi) == 1 && ds.NumIgnored == 0 {\n\t\t\t\tnumHi++ // Avoid pointless coalescing of a single equal record\n\t\t\t}\n\n\t\t\t// Format the equal values.\n\t\t\tfor _, r := range recs[:numLo] {\n\t\t\t\tout := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value, ptrs)\n\t\t\t\tlist = append(list, textRecord{Key: formatKey(r.Key), Value: out})\n\t\t\t\tkeys = append(keys, r.Key)\n\t\t\t}\n\t\t\tif numEqual > numLo+numHi {\n\t\t\t\tds.NumIdentical -= numLo + numHi\n\t\t\t\tlist.AppendEllipsis(ds)\n\t\t\t\tfor len(keys) < len(list) {\n\t\t\t\t\tkeys = append(keys, reflect.Value{})\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor _, r := range recs[numEqual-numHi : numEqual] {\n\t\t\t\tout := opts.WithDiffMode(diffIdentical).FormatDiff(r.Value, ptrs)\n\t\t\t\tlist = append(list, textRecord{Key: formatKey(r.Key), Value: out})\n\t\t\t\tkeys = append(keys, r.Key)\n\t\t\t}\n\t\t\trecs = recs[numEqual:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// Handle unequal records.\n\t\tfor _, r := range recs[:ds.NumDiff()] {\n\t\t\tswitch {\n\t\t\tcase opts.CanFormatDiffSlice(r.Value):\n\t\t\t\tout := opts.FormatDiffSlice(r.Value)\n\t\t\t\tlist = append(list, textRecord{Key: formatKey(r.Key), Value: out})\n\t\t\t\tkeys = append(keys, r.Key)\n\t\t\tcase r.Value.NumChildren == r.Value.MaxDepth:\n\t\t\t\toutx := opts.WithDiffMode(diffRemoved).FormatDiff(r.Value, ptrs)\n\t\t\t\touty := opts.WithDiffMode(diffInserted).FormatDiff(r.Value, ptrs)\n\t\t\t\tfor i := 0; i <= maxVerbosityPreset && outx != nil && outy != nil && outx.Equal(outy); i++ {\n\t\t\t\t\topts2 := verbosityPreset(opts, i)\n\t\t\t\t\toutx = opts2.WithDiffMode(diffRemoved).FormatDiff(r.Value, ptrs)\n\t\t\t\t\touty = opts2.WithDiffMode(diffInserted).FormatDiff(r.Value, ptrs)\n\t\t\t\t}\n\t\t\t\tif outx != nil {\n\t\t\t\t\tlist = append(list, textRecord{Diff: diffRemoved, Key: formatKey(r.Key), Value: outx})\n\t\t\t\t\tkeys = append(keys, r.Key)\n\t\t\t\t}\n\t\t\t\tif outy != nil {\n\t\t\t\t\tlist = append(list, textRecord{Diff: diffInserted, Key: formatKey(r.Key), Value: outy})\n\t\t\t\t\tkeys = append(keys, r.Key)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tout := opts.FormatDiff(r.Value, ptrs)\n\t\t\t\tlist = append(list, textRecord{Key: formatKey(r.Key), Value: out})\n\t\t\t\tkeys = append(keys, r.Key)\n\t\t\t}\n\t\t}\n\t\trecs = recs[ds.NumDiff():]\n\t\tnumDiffs += ds.NumDiff()\n\t}\n\tif maxGroup.IsZero() {\n\t\tassert(len(recs) == 0)\n\t} else {\n\t\tlist.AppendEllipsis(maxGroup)\n\t\tfor len(keys) < len(list) {\n\t\t\tkeys = append(keys, reflect.Value{})\n\t\t}\n\t}\n\tassert(len(list) == len(keys))\n\n\t// For maps, the default formatting logic uses fmt.Stringer which may\n\t// produce ambiguous output. Avoid calling String to disambiguate.\n\tif k == reflect.Map {\n\t\tvar ambiguous bool\n\t\tseenKeys := map[string]reflect.Value{}\n\t\tfor i, currKey := range keys {\n\t\t\tif currKey.IsValid() {\n\t\t\t\tstrKey := list[i].Key\n\t\t\t\tprevKey, seen := seenKeys[strKey]\n\t\t\t\tif seen && prevKey.CanInterface() && currKey.CanInterface() {\n\t\t\t\t\tambiguous = prevKey.Interface() != currKey.Interface()\n\t\t\t\t\tif ambiguous {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tseenKeys[strKey] = currKey\n\t\t\t}\n\t\t}\n\t\tif ambiguous {\n\t\t\tfor i, k := range keys {\n\t\t\t\tif k.IsValid() {\n\t\t\t\t\tlist[i].Key = formatMapKey(k, true, ptrs)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &textWrap{Prefix: \"{\", Value: list, Suffix: \"}\"}\n}\n\n// coalesceAdjacentRecords coalesces the list of records into groups of\n// adjacent equal, or unequal counts.\nfunc coalesceAdjacentRecords(name string, recs []reportRecord) (groups []diffStats) {\n\tvar prevCase int // Arbitrary index into which case last occurred\n\tlastStats := func(i int) *diffStats {\n\t\tif prevCase != i {\n\t\t\tgroups = append(groups, diffStats{Name: name})\n\t\t\tprevCase = i\n\t\t}\n\t\treturn &groups[len(groups)-1]\n\t}\n\tfor _, r := range recs {\n\t\tswitch rv := r.Value; {\n\t\tcase rv.NumIgnored > 0 && rv.NumSame+rv.NumDiff == 0:\n\t\t\tlastStats(1).NumIgnored++\n\t\tcase rv.NumDiff == 0:\n\t\t\tlastStats(1).NumIdentical++\n\t\tcase rv.NumDiff > 0 && !rv.ValueY.IsValid():\n\t\t\tlastStats(2).NumRemoved++\n\t\tcase rv.NumDiff > 0 && !rv.ValueX.IsValid():\n\t\t\tlastStats(2).NumInserted++\n\t\tdefault:\n\t\t\tlastStats(2).NumModified++\n\t\t}\n\t}\n\treturn groups\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/report_references.go",
    "content": "// Copyright 2020, 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 cmp\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/google/go-cmp/cmp/internal/flags\"\n\t\"github.com/google/go-cmp/cmp/internal/value\"\n)\n\nconst (\n\tpointerDelimPrefix = \"⟪\"\n\tpointerDelimSuffix = \"⟫\"\n)\n\n// formatPointer prints the address of the pointer.\nfunc formatPointer(p value.Pointer, withDelims bool) string {\n\tv := p.Uintptr()\n\tif flags.Deterministic {\n\t\tv = 0xdeadf00f // Only used for stable testing purposes\n\t}\n\tif withDelims {\n\t\treturn pointerDelimPrefix + formatHex(uint64(v)) + pointerDelimSuffix\n\t}\n\treturn formatHex(uint64(v))\n}\n\n// pointerReferences is a stack of pointers visited so far.\ntype pointerReferences [][2]value.Pointer\n\nfunc (ps *pointerReferences) PushPair(vx, vy reflect.Value, d diffMode, deref bool) (pp [2]value.Pointer) {\n\tif deref && vx.IsValid() {\n\t\tvx = vx.Addr()\n\t}\n\tif deref && vy.IsValid() {\n\t\tvy = vy.Addr()\n\t}\n\tswitch d {\n\tcase diffUnknown, diffIdentical:\n\t\tpp = [2]value.Pointer{value.PointerOf(vx), value.PointerOf(vy)}\n\tcase diffRemoved:\n\t\tpp = [2]value.Pointer{value.PointerOf(vx), value.Pointer{}}\n\tcase diffInserted:\n\t\tpp = [2]value.Pointer{value.Pointer{}, value.PointerOf(vy)}\n\t}\n\t*ps = append(*ps, pp)\n\treturn pp\n}\n\nfunc (ps *pointerReferences) Push(v reflect.Value) (p value.Pointer, seen bool) {\n\tp = value.PointerOf(v)\n\tfor _, pp := range *ps {\n\t\tif p == pp[0] || p == pp[1] {\n\t\t\treturn p, true\n\t\t}\n\t}\n\t*ps = append(*ps, [2]value.Pointer{p, p})\n\treturn p, false\n}\n\nfunc (ps *pointerReferences) Pop() {\n\t*ps = (*ps)[:len(*ps)-1]\n}\n\n// trunkReferences is metadata for a textNode indicating that the sub-tree\n// represents the value for either pointer in a pair of references.\ntype trunkReferences struct{ pp [2]value.Pointer }\n\n// trunkReference is metadata for a textNode indicating that the sub-tree\n// represents the value for the given pointer reference.\ntype trunkReference struct{ p value.Pointer }\n\n// leafReference is metadata for a textNode indicating that the value is\n// truncated as it refers to another part of the tree (i.e., a trunk).\ntype leafReference struct{ p value.Pointer }\n\nfunc wrapTrunkReferences(pp [2]value.Pointer, s textNode) textNode {\n\tswitch {\n\tcase pp[0].IsNil():\n\t\treturn &textWrap{Value: s, Metadata: trunkReference{pp[1]}}\n\tcase pp[1].IsNil():\n\t\treturn &textWrap{Value: s, Metadata: trunkReference{pp[0]}}\n\tcase pp[0] == pp[1]:\n\t\treturn &textWrap{Value: s, Metadata: trunkReference{pp[0]}}\n\tdefault:\n\t\treturn &textWrap{Value: s, Metadata: trunkReferences{pp}}\n\t}\n}\nfunc wrapTrunkReference(p value.Pointer, printAddress bool, s textNode) textNode {\n\tvar prefix string\n\tif printAddress {\n\t\tprefix = formatPointer(p, true)\n\t}\n\treturn &textWrap{Prefix: prefix, Value: s, Metadata: trunkReference{p}}\n}\nfunc makeLeafReference(p value.Pointer, printAddress bool) textNode {\n\tout := &textWrap{Prefix: \"(\", Value: textEllipsis, Suffix: \")\"}\n\tvar prefix string\n\tif printAddress {\n\t\tprefix = formatPointer(p, true)\n\t}\n\treturn &textWrap{Prefix: prefix, Value: out, Metadata: leafReference{p}}\n}\n\n// resolveReferences walks the textNode tree searching for any leaf reference\n// metadata and resolves each against the corresponding trunk references.\n// Since pointer addresses in memory are not particularly readable to the user,\n// it replaces each pointer value with an arbitrary and unique reference ID.\nfunc resolveReferences(s textNode) {\n\tvar walkNodes func(textNode, func(textNode))\n\twalkNodes = func(s textNode, f func(textNode)) {\n\t\tf(s)\n\t\tswitch s := s.(type) {\n\t\tcase *textWrap:\n\t\t\twalkNodes(s.Value, f)\n\t\tcase textList:\n\t\t\tfor _, r := range s {\n\t\t\t\twalkNodes(r.Value, f)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Collect all trunks and leaves with reference metadata.\n\tvar trunks, leaves []*textWrap\n\twalkNodes(s, func(s textNode) {\n\t\tif s, ok := s.(*textWrap); ok {\n\t\t\tswitch s.Metadata.(type) {\n\t\t\tcase leafReference:\n\t\t\t\tleaves = append(leaves, s)\n\t\t\tcase trunkReference, trunkReferences:\n\t\t\t\ttrunks = append(trunks, s)\n\t\t\t}\n\t\t}\n\t})\n\n\t// No leaf references to resolve.\n\tif len(leaves) == 0 {\n\t\treturn\n\t}\n\n\t// Collect the set of all leaf references to resolve.\n\tleafPtrs := make(map[value.Pointer]bool)\n\tfor _, leaf := range leaves {\n\t\tleafPtrs[leaf.Metadata.(leafReference).p] = true\n\t}\n\n\t// Collect the set of trunk pointers that are always paired together.\n\t// This allows us to assign a single ID to both pointers for brevity.\n\t// If a pointer in a pair ever occurs by itself or as a different pair,\n\t// then the pair is broken.\n\tpairedTrunkPtrs := make(map[value.Pointer]value.Pointer)\n\tunpair := func(p value.Pointer) {\n\t\tif !pairedTrunkPtrs[p].IsNil() {\n\t\t\tpairedTrunkPtrs[pairedTrunkPtrs[p]] = value.Pointer{} // invalidate other half\n\t\t}\n\t\tpairedTrunkPtrs[p] = value.Pointer{} // invalidate this half\n\t}\n\tfor _, trunk := range trunks {\n\t\tswitch p := trunk.Metadata.(type) {\n\t\tcase trunkReference:\n\t\t\tunpair(p.p) // standalone pointer cannot be part of a pair\n\t\tcase trunkReferences:\n\t\t\tp0, ok0 := pairedTrunkPtrs[p.pp[0]]\n\t\t\tp1, ok1 := pairedTrunkPtrs[p.pp[1]]\n\t\t\tswitch {\n\t\t\tcase !ok0 && !ok1:\n\t\t\t\t// Register the newly seen pair.\n\t\t\t\tpairedTrunkPtrs[p.pp[0]] = p.pp[1]\n\t\t\t\tpairedTrunkPtrs[p.pp[1]] = p.pp[0]\n\t\t\tcase ok0 && ok1 && p0 == p.pp[1] && p1 == p.pp[0]:\n\t\t\t\t// Exact pair already seen; do nothing.\n\t\t\tdefault:\n\t\t\t\t// Pair conflicts with some other pair; break all pairs.\n\t\t\t\tunpair(p.pp[0])\n\t\t\t\tunpair(p.pp[1])\n\t\t\t}\n\t\t}\n\t}\n\n\t// Correlate each pointer referenced by leaves to a unique identifier,\n\t// and print the IDs for each trunk that matches those pointers.\n\tvar nextID uint\n\tptrIDs := make(map[value.Pointer]uint)\n\tnewID := func() uint {\n\t\tid := nextID\n\t\tnextID++\n\t\treturn id\n\t}\n\tfor _, trunk := range trunks {\n\t\tswitch p := trunk.Metadata.(type) {\n\t\tcase trunkReference:\n\t\t\tif print := leafPtrs[p.p]; print {\n\t\t\t\tid, ok := ptrIDs[p.p]\n\t\t\t\tif !ok {\n\t\t\t\t\tid = newID()\n\t\t\t\t\tptrIDs[p.p] = id\n\t\t\t\t}\n\t\t\t\ttrunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id))\n\t\t\t}\n\t\tcase trunkReferences:\n\t\t\tprint0 := leafPtrs[p.pp[0]]\n\t\t\tprint1 := leafPtrs[p.pp[1]]\n\t\t\tif print0 || print1 {\n\t\t\t\tid0, ok0 := ptrIDs[p.pp[0]]\n\t\t\t\tid1, ok1 := ptrIDs[p.pp[1]]\n\t\t\t\tisPair := pairedTrunkPtrs[p.pp[0]] == p.pp[1] && pairedTrunkPtrs[p.pp[1]] == p.pp[0]\n\t\t\t\tif isPair {\n\t\t\t\t\tvar id uint\n\t\t\t\t\tassert(ok0 == ok1) // must be seen together or not at all\n\t\t\t\t\tif ok0 {\n\t\t\t\t\t\tassert(id0 == id1) // must have the same ID\n\t\t\t\t\t\tid = id0\n\t\t\t\t\t} else {\n\t\t\t\t\t\tid = newID()\n\t\t\t\t\t\tptrIDs[p.pp[0]] = id\n\t\t\t\t\t\tptrIDs[p.pp[1]] = id\n\t\t\t\t\t}\n\t\t\t\t\ttrunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id))\n\t\t\t\t} else {\n\t\t\t\t\tif print0 && !ok0 {\n\t\t\t\t\t\tid0 = newID()\n\t\t\t\t\t\tptrIDs[p.pp[0]] = id0\n\t\t\t\t\t}\n\t\t\t\t\tif print1 && !ok1 {\n\t\t\t\t\t\tid1 = newID()\n\t\t\t\t\t\tptrIDs[p.pp[1]] = id1\n\t\t\t\t\t}\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase print0 && print1:\n\t\t\t\t\t\ttrunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id0)+\",\"+formatReference(id1))\n\t\t\t\t\tcase print0:\n\t\t\t\t\t\ttrunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id0))\n\t\t\t\t\tcase print1:\n\t\t\t\t\t\ttrunk.Prefix = updateReferencePrefix(trunk.Prefix, formatReference(id1))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Update all leaf references with the unique identifier.\n\tfor _, leaf := range leaves {\n\t\tif id, ok := ptrIDs[leaf.Metadata.(leafReference).p]; ok {\n\t\t\tleaf.Prefix = updateReferencePrefix(leaf.Prefix, formatReference(id))\n\t\t}\n\t}\n}\n\nfunc formatReference(id uint) string {\n\treturn fmt.Sprintf(\"ref#%d\", id)\n}\n\nfunc updateReferencePrefix(prefix, ref string) string {\n\tif prefix == \"\" {\n\t\treturn pointerDelimPrefix + ref + pointerDelimSuffix\n\t}\n\tsuffix := strings.TrimPrefix(prefix, pointerDelimPrefix)\n\treturn pointerDelimPrefix + ref + \": \" + suffix\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/report_reflect.go",
    "content": "// Copyright 2019, 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 cmp\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/google/go-cmp/cmp/internal/value\"\n)\n\nvar (\n\tanyType    = reflect.TypeOf((*interface{})(nil)).Elem()\n\tstringType = reflect.TypeOf((*string)(nil)).Elem()\n\tbytesType  = reflect.TypeOf((*[]byte)(nil)).Elem()\n\tbyteType   = reflect.TypeOf((*byte)(nil)).Elem()\n)\n\ntype formatValueOptions struct {\n\t// AvoidStringer controls whether to avoid calling custom stringer\n\t// methods like error.Error or fmt.Stringer.String.\n\tAvoidStringer bool\n\n\t// PrintAddresses controls whether to print the address of all pointers,\n\t// slice elements, and maps.\n\tPrintAddresses bool\n\n\t// QualifiedNames controls whether FormatType uses the fully qualified name\n\t// (including the full package path as opposed to just the package name).\n\tQualifiedNames bool\n\n\t// VerbosityLevel controls the amount of output to produce.\n\t// A higher value produces more output. A value of zero or lower produces\n\t// no output (represented using an ellipsis).\n\t// If LimitVerbosity is false, then the level is treated as infinite.\n\tVerbosityLevel int\n\n\t// LimitVerbosity specifies that formatting should respect VerbosityLevel.\n\tLimitVerbosity bool\n}\n\n// FormatType prints the type as if it were wrapping s.\n// This may return s as-is depending on the current type and TypeMode mode.\nfunc (opts formatOptions) FormatType(t reflect.Type, s textNode) textNode {\n\t// Check whether to emit the type or not.\n\tswitch opts.TypeMode {\n\tcase autoType:\n\t\tswitch t.Kind() {\n\t\tcase reflect.Struct, reflect.Slice, reflect.Array, reflect.Map:\n\t\t\tif s.Equal(textNil) {\n\t\t\t\treturn s\n\t\t\t}\n\t\tdefault:\n\t\t\treturn s\n\t\t}\n\t\tif opts.DiffMode == diffIdentical {\n\t\t\treturn s // elide type for identical nodes\n\t\t}\n\tcase elideType:\n\t\treturn s\n\t}\n\n\t// Determine the type label, applying special handling for unnamed types.\n\ttypeName := value.TypeString(t, opts.QualifiedNames)\n\tif t.Name() == \"\" {\n\t\t// According to Go grammar, certain type literals contain symbols that\n\t\t// do not strongly bind to the next lexicographical token (e.g., *T).\n\t\tswitch t.Kind() {\n\t\tcase reflect.Chan, reflect.Func, reflect.Ptr:\n\t\t\ttypeName = \"(\" + typeName + \")\"\n\t\t}\n\t}\n\treturn &textWrap{Prefix: typeName, Value: wrapParens(s)}\n}\n\n// wrapParens wraps s with a set of parenthesis, but avoids it if the\n// wrapped node itself is already surrounded by a pair of parenthesis or braces.\n// It handles unwrapping one level of pointer-reference nodes.\nfunc wrapParens(s textNode) textNode {\n\tvar refNode *textWrap\n\tif s2, ok := s.(*textWrap); ok {\n\t\t// Unwrap a single pointer reference node.\n\t\tswitch s2.Metadata.(type) {\n\t\tcase leafReference, trunkReference, trunkReferences:\n\t\t\trefNode = s2\n\t\t\tif s3, ok := refNode.Value.(*textWrap); ok {\n\t\t\t\ts2 = s3\n\t\t\t}\n\t\t}\n\n\t\t// Already has delimiters that make parenthesis unnecessary.\n\t\thasParens := strings.HasPrefix(s2.Prefix, \"(\") && strings.HasSuffix(s2.Suffix, \")\")\n\t\thasBraces := strings.HasPrefix(s2.Prefix, \"{\") && strings.HasSuffix(s2.Suffix, \"}\")\n\t\tif hasParens || hasBraces {\n\t\t\treturn s\n\t\t}\n\t}\n\tif refNode != nil {\n\t\trefNode.Value = &textWrap{Prefix: \"(\", Value: refNode.Value, Suffix: \")\"}\n\t\treturn s\n\t}\n\treturn &textWrap{Prefix: \"(\", Value: s, Suffix: \")\"}\n}\n\n// FormatValue prints the reflect.Value, taking extra care to avoid descending\n// into pointers already in ptrs. As pointers are visited, ptrs is also updated.\nfunc (opts formatOptions) FormatValue(v reflect.Value, parentKind reflect.Kind, ptrs *pointerReferences) (out textNode) {\n\tif !v.IsValid() {\n\t\treturn nil\n\t}\n\tt := v.Type()\n\n\t// Check slice element for cycles.\n\tif parentKind == reflect.Slice {\n\t\tptrRef, visited := ptrs.Push(v.Addr())\n\t\tif visited {\n\t\t\treturn makeLeafReference(ptrRef, false)\n\t\t}\n\t\tdefer ptrs.Pop()\n\t\tdefer func() { out = wrapTrunkReference(ptrRef, false, out) }()\n\t}\n\n\t// Check whether there is an Error or String method to call.\n\tif !opts.AvoidStringer && v.CanInterface() {\n\t\t// Avoid calling Error or String methods on nil receivers since many\n\t\t// implementations crash when doing so.\n\t\tif (t.Kind() != reflect.Ptr && t.Kind() != reflect.Interface) || !v.IsNil() {\n\t\t\tvar prefix, strVal string\n\t\t\tfunc() {\n\t\t\t\t// Swallow and ignore any panics from String or Error.\n\t\t\t\tdefer func() { recover() }()\n\t\t\t\tswitch v := v.Interface().(type) {\n\t\t\t\tcase error:\n\t\t\t\t\tstrVal = v.Error()\n\t\t\t\t\tprefix = \"e\"\n\t\t\t\tcase fmt.Stringer:\n\t\t\t\t\tstrVal = v.String()\n\t\t\t\t\tprefix = \"s\"\n\t\t\t\t}\n\t\t\t}()\n\t\t\tif prefix != \"\" {\n\t\t\t\treturn opts.formatString(prefix, strVal)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check whether to explicitly wrap the result with the type.\n\tvar skipType bool\n\tdefer func() {\n\t\tif !skipType {\n\t\t\tout = opts.FormatType(t, out)\n\t\t}\n\t}()\n\n\tswitch t.Kind() {\n\tcase reflect.Bool:\n\t\treturn textLine(fmt.Sprint(v.Bool()))\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn textLine(fmt.Sprint(v.Int()))\n\tcase reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\treturn textLine(fmt.Sprint(v.Uint()))\n\tcase reflect.Uint8:\n\t\tif parentKind == reflect.Slice || parentKind == reflect.Array {\n\t\t\treturn textLine(formatHex(v.Uint()))\n\t\t}\n\t\treturn textLine(fmt.Sprint(v.Uint()))\n\tcase reflect.Uintptr:\n\t\treturn textLine(formatHex(v.Uint()))\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn textLine(fmt.Sprint(v.Float()))\n\tcase reflect.Complex64, reflect.Complex128:\n\t\treturn textLine(fmt.Sprint(v.Complex()))\n\tcase reflect.String:\n\t\treturn opts.formatString(\"\", v.String())\n\tcase reflect.UnsafePointer, reflect.Chan, reflect.Func:\n\t\treturn textLine(formatPointer(value.PointerOf(v), true))\n\tcase reflect.Struct:\n\t\tvar list textList\n\t\tv := makeAddressable(v) // needed for retrieveUnexportedField\n\t\tmaxLen := v.NumField()\n\t\tif opts.LimitVerbosity {\n\t\t\tmaxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc...\n\t\t\topts.VerbosityLevel--\n\t\t}\n\t\tfor i := 0; i < v.NumField(); i++ {\n\t\t\tvv := v.Field(i)\n\t\t\tif vv.IsZero() {\n\t\t\t\tcontinue // Elide fields with zero values\n\t\t\t}\n\t\t\tif len(list) == maxLen {\n\t\t\t\tlist.AppendEllipsis(diffStats{})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsf := t.Field(i)\n\t\t\tif !isExported(sf.Name) {\n\t\t\t\tvv = retrieveUnexportedField(v, sf, true)\n\t\t\t}\n\t\t\ts := opts.WithTypeMode(autoType).FormatValue(vv, t.Kind(), ptrs)\n\t\t\tlist = append(list, textRecord{Key: sf.Name, Value: s})\n\t\t}\n\t\treturn &textWrap{Prefix: \"{\", Value: list, Suffix: \"}\"}\n\tcase reflect.Slice:\n\t\tif v.IsNil() {\n\t\t\treturn textNil\n\t\t}\n\n\t\t// Check whether this is a []byte of text data.\n\t\tif t.Elem() == byteType {\n\t\t\tb := v.Bytes()\n\t\t\tisPrintSpace := func(r rune) bool { return unicode.IsPrint(r) || unicode.IsSpace(r) }\n\t\t\tif len(b) > 0 && utf8.Valid(b) && len(bytes.TrimFunc(b, isPrintSpace)) == 0 {\n\t\t\t\tout = opts.formatString(\"\", string(b))\n\t\t\t\tskipType = true\n\t\t\t\treturn opts.FormatType(t, out)\n\t\t\t}\n\t\t}\n\n\t\tfallthrough\n\tcase reflect.Array:\n\t\tmaxLen := v.Len()\n\t\tif opts.LimitVerbosity {\n\t\t\tmaxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc...\n\t\t\topts.VerbosityLevel--\n\t\t}\n\t\tvar list textList\n\t\tfor i := 0; i < v.Len(); i++ {\n\t\t\tif len(list) == maxLen {\n\t\t\t\tlist.AppendEllipsis(diffStats{})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ts := opts.WithTypeMode(elideType).FormatValue(v.Index(i), t.Kind(), ptrs)\n\t\t\tlist = append(list, textRecord{Value: s})\n\t\t}\n\n\t\tout = &textWrap{Prefix: \"{\", Value: list, Suffix: \"}\"}\n\t\tif t.Kind() == reflect.Slice && opts.PrintAddresses {\n\t\t\theader := fmt.Sprintf(\"ptr:%v, len:%d, cap:%d\", formatPointer(value.PointerOf(v), false), v.Len(), v.Cap())\n\t\t\tout = &textWrap{Prefix: pointerDelimPrefix + header + pointerDelimSuffix, Value: out}\n\t\t}\n\t\treturn out\n\tcase reflect.Map:\n\t\tif v.IsNil() {\n\t\t\treturn textNil\n\t\t}\n\n\t\t// Check pointer for cycles.\n\t\tptrRef, visited := ptrs.Push(v)\n\t\tif visited {\n\t\t\treturn makeLeafReference(ptrRef, opts.PrintAddresses)\n\t\t}\n\t\tdefer ptrs.Pop()\n\n\t\tmaxLen := v.Len()\n\t\tif opts.LimitVerbosity {\n\t\t\tmaxLen = ((1 << opts.verbosity()) >> 1) << 2 // 0, 4, 8, 16, 32, etc...\n\t\t\topts.VerbosityLevel--\n\t\t}\n\t\tvar list textList\n\t\tfor _, k := range value.SortKeys(v.MapKeys()) {\n\t\t\tif len(list) == maxLen {\n\t\t\t\tlist.AppendEllipsis(diffStats{})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsk := formatMapKey(k, false, ptrs)\n\t\t\tsv := opts.WithTypeMode(elideType).FormatValue(v.MapIndex(k), t.Kind(), ptrs)\n\t\t\tlist = append(list, textRecord{Key: sk, Value: sv})\n\t\t}\n\n\t\tout = &textWrap{Prefix: \"{\", Value: list, Suffix: \"}\"}\n\t\tout = wrapTrunkReference(ptrRef, opts.PrintAddresses, out)\n\t\treturn out\n\tcase reflect.Ptr:\n\t\tif v.IsNil() {\n\t\t\treturn textNil\n\t\t}\n\n\t\t// Check pointer for cycles.\n\t\tptrRef, visited := ptrs.Push(v)\n\t\tif visited {\n\t\t\tout = makeLeafReference(ptrRef, opts.PrintAddresses)\n\t\t\treturn &textWrap{Prefix: \"&\", Value: out}\n\t\t}\n\t\tdefer ptrs.Pop()\n\n\t\t// Skip the name only if this is an unnamed pointer type.\n\t\t// Otherwise taking the address of a value does not reproduce\n\t\t// the named pointer type.\n\t\tif v.Type().Name() == \"\" {\n\t\t\tskipType = true // Let the underlying value print the type instead\n\t\t}\n\t\tout = opts.FormatValue(v.Elem(), t.Kind(), ptrs)\n\t\tout = wrapTrunkReference(ptrRef, opts.PrintAddresses, out)\n\t\tout = &textWrap{Prefix: \"&\", Value: out}\n\t\treturn out\n\tcase reflect.Interface:\n\t\tif v.IsNil() {\n\t\t\treturn textNil\n\t\t}\n\t\t// Interfaces accept different concrete types,\n\t\t// so configure the underlying value to explicitly print the type.\n\t\treturn opts.WithTypeMode(emitType).FormatValue(v.Elem(), t.Kind(), ptrs)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"%v kind not handled\", v.Kind()))\n\t}\n}\n\nfunc (opts formatOptions) formatString(prefix, s string) textNode {\n\tmaxLen := len(s)\n\tmaxLines := strings.Count(s, \"\\n\") + 1\n\tif opts.LimitVerbosity {\n\t\tmaxLen = (1 << opts.verbosity()) << 5   // 32, 64, 128, 256, etc...\n\t\tmaxLines = (1 << opts.verbosity()) << 2 //  4, 8, 16, 32, 64, etc...\n\t}\n\n\t// For multiline strings, use the triple-quote syntax,\n\t// but only use it when printing removed or inserted nodes since\n\t// we only want the extra verbosity for those cases.\n\tlines := strings.Split(strings.TrimSuffix(s, \"\\n\"), \"\\n\")\n\tisTripleQuoted := len(lines) >= 4 && (opts.DiffMode == '-' || opts.DiffMode == '+')\n\tfor i := 0; i < len(lines) && isTripleQuoted; i++ {\n\t\tlines[i] = strings.TrimPrefix(strings.TrimSuffix(lines[i], \"\\r\"), \"\\r\") // trim leading/trailing carriage returns for legacy Windows endline support\n\t\tisPrintable := func(r rune) bool {\n\t\t\treturn unicode.IsPrint(r) || r == '\\t' // specially treat tab as printable\n\t\t}\n\t\tline := lines[i]\n\t\tisTripleQuoted = !strings.HasPrefix(strings.TrimPrefix(line, prefix), `\"\"\"`) && !strings.HasPrefix(line, \"...\") && strings.TrimFunc(line, isPrintable) == \"\" && len(line) <= maxLen\n\t}\n\tif isTripleQuoted {\n\t\tvar list textList\n\t\tlist = append(list, textRecord{Diff: opts.DiffMode, Value: textLine(prefix + `\"\"\"`), ElideComma: true})\n\t\tfor i, line := range lines {\n\t\t\tif numElided := len(lines) - i; i == maxLines-1 && numElided > 1 {\n\t\t\t\tcomment := commentString(fmt.Sprintf(\"%d elided lines\", numElided))\n\t\t\t\tlist = append(list, textRecord{Diff: opts.DiffMode, Value: textEllipsis, ElideComma: true, Comment: comment})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlist = append(list, textRecord{Diff: opts.DiffMode, Value: textLine(line), ElideComma: true})\n\t\t}\n\t\tlist = append(list, textRecord{Diff: opts.DiffMode, Value: textLine(prefix + `\"\"\"`), ElideComma: true})\n\t\treturn &textWrap{Prefix: \"(\", Value: list, Suffix: \")\"}\n\t}\n\n\t// Format the string as a single-line quoted string.\n\tif len(s) > maxLen+len(textEllipsis) {\n\t\treturn textLine(prefix + formatString(s[:maxLen]) + string(textEllipsis))\n\t}\n\treturn textLine(prefix + formatString(s))\n}\n\n// formatMapKey formats v as if it were a map key.\n// The result is guaranteed to be a single line.\nfunc formatMapKey(v reflect.Value, disambiguate bool, ptrs *pointerReferences) string {\n\tvar opts formatOptions\n\topts.DiffMode = diffIdentical\n\topts.TypeMode = elideType\n\topts.PrintAddresses = disambiguate\n\topts.AvoidStringer = disambiguate\n\topts.QualifiedNames = disambiguate\n\topts.VerbosityLevel = maxVerbosityPreset\n\topts.LimitVerbosity = true\n\ts := opts.FormatValue(v, reflect.Map, ptrs).String()\n\treturn strings.TrimSpace(s)\n}\n\n// formatString prints s as a double-quoted or backtick-quoted string.\nfunc formatString(s string) string {\n\t// Use quoted string if it the same length as a raw string literal.\n\t// Otherwise, attempt to use the raw string form.\n\tqs := strconv.Quote(s)\n\tif len(qs) == 1+len(s)+1 {\n\t\treturn qs\n\t}\n\n\t// Disallow newlines to ensure output is a single line.\n\t// Only allow printable runes for readability purposes.\n\trawInvalid := func(r rune) bool {\n\t\treturn r == '`' || r == '\\n' || !(unicode.IsPrint(r) || r == '\\t')\n\t}\n\tif utf8.ValidString(s) && strings.IndexFunc(s, rawInvalid) < 0 {\n\t\treturn \"`\" + s + \"`\"\n\t}\n\treturn qs\n}\n\n// formatHex prints u as a hexadecimal integer in Go notation.\nfunc formatHex(u uint64) string {\n\tvar f string\n\tswitch {\n\tcase u <= 0xff:\n\t\tf = \"0x%02x\"\n\tcase u <= 0xffff:\n\t\tf = \"0x%04x\"\n\tcase u <= 0xffffff:\n\t\tf = \"0x%06x\"\n\tcase u <= 0xffffffff:\n\t\tf = \"0x%08x\"\n\tcase u <= 0xffffffffff:\n\t\tf = \"0x%010x\"\n\tcase u <= 0xffffffffffff:\n\t\tf = \"0x%012x\"\n\tcase u <= 0xffffffffffffff:\n\t\tf = \"0x%014x\"\n\tcase u <= 0xffffffffffffffff:\n\t\tf = \"0x%016x\"\n\t}\n\treturn fmt.Sprintf(f, u)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/report_slices.go",
    "content": "// Copyright 2019, 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 cmp\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/google/go-cmp/cmp/internal/diff\"\n)\n\n// CanFormatDiffSlice reports whether we support custom formatting for nodes\n// that are slices of primitive kinds or strings.\nfunc (opts formatOptions) CanFormatDiffSlice(v *valueNode) bool {\n\tswitch {\n\tcase opts.DiffMode != diffUnknown:\n\t\treturn false // Must be formatting in diff mode\n\tcase v.NumDiff == 0:\n\t\treturn false // No differences detected\n\tcase !v.ValueX.IsValid() || !v.ValueY.IsValid():\n\t\treturn false // Both values must be valid\n\tcase v.NumIgnored > 0:\n\t\treturn false // Some ignore option was used\n\tcase v.NumTransformed > 0:\n\t\treturn false // Some transform option was used\n\tcase v.NumCompared > 1:\n\t\treturn false // More than one comparison was used\n\tcase v.NumCompared == 1 && v.Type.Name() != \"\":\n\t\t// The need for cmp to check applicability of options on every element\n\t\t// in a slice is a significant performance detriment for large []byte.\n\t\t// The workaround is to specify Comparer(bytes.Equal),\n\t\t// which enables cmp to compare []byte more efficiently.\n\t\t// If they differ, we still want to provide batched diffing.\n\t\t// The logic disallows named types since they tend to have their own\n\t\t// String method, with nicer formatting than what this provides.\n\t\treturn false\n\t}\n\n\t// Check whether this is an interface with the same concrete types.\n\tt := v.Type\n\tvx, vy := v.ValueX, v.ValueY\n\tif t.Kind() == reflect.Interface && !vx.IsNil() && !vy.IsNil() && vx.Elem().Type() == vy.Elem().Type() {\n\t\tvx, vy = vx.Elem(), vy.Elem()\n\t\tt = vx.Type()\n\t}\n\n\t// Check whether we provide specialized diffing for this type.\n\tswitch t.Kind() {\n\tcase reflect.String:\n\tcase reflect.Array, reflect.Slice:\n\t\t// Only slices of primitive types have specialized handling.\n\t\tswitch t.Elem().Kind() {\n\t\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n\t\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr,\n\t\t\treflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\n\t\t// Both slice values have to be non-empty.\n\t\tif t.Kind() == reflect.Slice && (vx.Len() == 0 || vy.Len() == 0) {\n\t\t\treturn false\n\t\t}\n\n\t\t// If a sufficient number of elements already differ,\n\t\t// use specialized formatting even if length requirement is not met.\n\t\tif v.NumDiff > v.NumSame {\n\t\t\treturn true\n\t\t}\n\tdefault:\n\t\treturn false\n\t}\n\n\t// Use specialized string diffing for longer slices or strings.\n\tconst minLength = 32\n\treturn vx.Len() >= minLength && vy.Len() >= minLength\n}\n\n// FormatDiffSlice prints a diff for the slices (or strings) represented by v.\n// This provides custom-tailored logic to make printing of differences in\n// textual strings and slices of primitive kinds more readable.\nfunc (opts formatOptions) FormatDiffSlice(v *valueNode) textNode {\n\tassert(opts.DiffMode == diffUnknown)\n\tt, vx, vy := v.Type, v.ValueX, v.ValueY\n\tif t.Kind() == reflect.Interface {\n\t\tvx, vy = vx.Elem(), vy.Elem()\n\t\tt = vx.Type()\n\t\topts = opts.WithTypeMode(emitType)\n\t}\n\n\t// Auto-detect the type of the data.\n\tvar sx, sy string\n\tvar ssx, ssy []string\n\tvar isString, isMostlyText, isPureLinedText, isBinary bool\n\tswitch {\n\tcase t.Kind() == reflect.String:\n\t\tsx, sy = vx.String(), vy.String()\n\t\tisString = true\n\tcase t.Kind() == reflect.Slice && t.Elem() == byteType:\n\t\tsx, sy = string(vx.Bytes()), string(vy.Bytes())\n\t\tisString = true\n\tcase t.Kind() == reflect.Array:\n\t\t// Arrays need to be addressable for slice operations to work.\n\t\tvx2, vy2 := reflect.New(t).Elem(), reflect.New(t).Elem()\n\t\tvx2.Set(vx)\n\t\tvy2.Set(vy)\n\t\tvx, vy = vx2, vy2\n\t}\n\tif isString {\n\t\tvar numTotalRunes, numValidRunes, numLines, lastLineIdx, maxLineLen int\n\t\tfor i, r := range sx + sy {\n\t\t\tnumTotalRunes++\n\t\t\tif (unicode.IsPrint(r) || unicode.IsSpace(r)) && r != utf8.RuneError {\n\t\t\t\tnumValidRunes++\n\t\t\t}\n\t\t\tif r == '\\n' {\n\t\t\t\tif maxLineLen < i-lastLineIdx {\n\t\t\t\t\tmaxLineLen = i - lastLineIdx\n\t\t\t\t}\n\t\t\t\tlastLineIdx = i + 1\n\t\t\t\tnumLines++\n\t\t\t}\n\t\t}\n\t\tisPureText := numValidRunes == numTotalRunes\n\t\tisMostlyText = float64(numValidRunes) > math.Floor(0.90*float64(numTotalRunes))\n\t\tisPureLinedText = isPureText && numLines >= 4 && maxLineLen <= 1024\n\t\tisBinary = !isMostlyText\n\n\t\t// Avoid diffing by lines if it produces a significantly more complex\n\t\t// edit script than diffing by bytes.\n\t\tif isPureLinedText {\n\t\t\tssx = strings.Split(sx, \"\\n\")\n\t\t\tssy = strings.Split(sy, \"\\n\")\n\t\t\tesLines := diff.Difference(len(ssx), len(ssy), func(ix, iy int) diff.Result {\n\t\t\t\treturn diff.BoolResult(ssx[ix] == ssy[iy])\n\t\t\t})\n\t\t\tesBytes := diff.Difference(len(sx), len(sy), func(ix, iy int) diff.Result {\n\t\t\t\treturn diff.BoolResult(sx[ix] == sy[iy])\n\t\t\t})\n\t\t\tefficiencyLines := float64(esLines.Dist()) / float64(len(esLines))\n\t\t\tefficiencyBytes := float64(esBytes.Dist()) / float64(len(esBytes))\n\t\t\tquotedLength := len(strconv.Quote(sx + sy))\n\t\t\tunquotedLength := len(sx) + len(sy)\n\t\t\tescapeExpansionRatio := float64(quotedLength) / float64(unquotedLength)\n\t\t\tisPureLinedText = efficiencyLines < 4*efficiencyBytes || escapeExpansionRatio > 1.1\n\t\t}\n\t}\n\n\t// Format the string into printable records.\n\tvar list textList\n\tvar delim string\n\tswitch {\n\t// If the text appears to be multi-lined text,\n\t// then perform differencing across individual lines.\n\tcase isPureLinedText:\n\t\tlist = opts.formatDiffSlice(\n\t\t\treflect.ValueOf(ssx), reflect.ValueOf(ssy), 1, \"line\",\n\t\t\tfunc(v reflect.Value, d diffMode) textRecord {\n\t\t\t\ts := formatString(v.Index(0).String())\n\t\t\t\treturn textRecord{Diff: d, Value: textLine(s)}\n\t\t\t},\n\t\t)\n\t\tdelim = \"\\n\"\n\n\t\t// If possible, use a custom triple-quote (\"\"\") syntax for printing\n\t\t// differences in a string literal. This format is more readable,\n\t\t// but has edge-cases where differences are visually indistinguishable.\n\t\t// This format is avoided under the following conditions:\n\t\t//   - A line starts with `\"\"\"`\n\t\t//   - A line starts with \"...\"\n\t\t//   - A line contains non-printable characters\n\t\t//   - Adjacent different lines differ only by whitespace\n\t\t//\n\t\t// For example:\n\t\t//\n\t\t//\t\t\"\"\"\n\t\t//\t\t... // 3 identical lines\n\t\t//\t\tfoo\n\t\t//\t\tbar\n\t\t//\t-\tbaz\n\t\t//\t+\tBAZ\n\t\t//\t\t\"\"\"\n\t\tisTripleQuoted := true\n\t\tprevRemoveLines := map[string]bool{}\n\t\tprevInsertLines := map[string]bool{}\n\t\tvar list2 textList\n\t\tlist2 = append(list2, textRecord{Value: textLine(`\"\"\"`), ElideComma: true})\n\t\tfor _, r := range list {\n\t\t\tif !r.Value.Equal(textEllipsis) {\n\t\t\t\tline, _ := strconv.Unquote(string(r.Value.(textLine)))\n\t\t\t\tline = strings.TrimPrefix(strings.TrimSuffix(line, \"\\r\"), \"\\r\") // trim leading/trailing carriage returns for legacy Windows endline support\n\t\t\t\tnormLine := strings.Map(func(r rune) rune {\n\t\t\t\t\tif unicode.IsSpace(r) {\n\t\t\t\t\t\treturn -1 // drop whitespace to avoid visually indistinguishable output\n\t\t\t\t\t}\n\t\t\t\t\treturn r\n\t\t\t\t}, line)\n\t\t\t\tisPrintable := func(r rune) bool {\n\t\t\t\t\treturn unicode.IsPrint(r) || r == '\\t' // specially treat tab as printable\n\t\t\t\t}\n\t\t\t\tisTripleQuoted = !strings.HasPrefix(line, `\"\"\"`) && !strings.HasPrefix(line, \"...\") && strings.TrimFunc(line, isPrintable) == \"\"\n\t\t\t\tswitch r.Diff {\n\t\t\t\tcase diffRemoved:\n\t\t\t\t\tisTripleQuoted = isTripleQuoted && !prevInsertLines[normLine]\n\t\t\t\t\tprevRemoveLines[normLine] = true\n\t\t\t\tcase diffInserted:\n\t\t\t\t\tisTripleQuoted = isTripleQuoted && !prevRemoveLines[normLine]\n\t\t\t\t\tprevInsertLines[normLine] = true\n\t\t\t\t}\n\t\t\t\tif !isTripleQuoted {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tr.Value = textLine(line)\n\t\t\t\tr.ElideComma = true\n\t\t\t}\n\t\t\tif !(r.Diff == diffRemoved || r.Diff == diffInserted) { // start a new non-adjacent difference group\n\t\t\t\tprevRemoveLines = map[string]bool{}\n\t\t\t\tprevInsertLines = map[string]bool{}\n\t\t\t}\n\t\t\tlist2 = append(list2, r)\n\t\t}\n\t\tif r := list2[len(list2)-1]; r.Diff == diffIdentical && len(r.Value.(textLine)) == 0 {\n\t\t\tlist2 = list2[:len(list2)-1] // elide single empty line at the end\n\t\t}\n\t\tlist2 = append(list2, textRecord{Value: textLine(`\"\"\"`), ElideComma: true})\n\t\tif isTripleQuoted {\n\t\t\tvar out textNode = &textWrap{Prefix: \"(\", Value: list2, Suffix: \")\"}\n\t\t\tswitch t.Kind() {\n\t\t\tcase reflect.String:\n\t\t\t\tif t != stringType {\n\t\t\t\t\tout = opts.FormatType(t, out)\n\t\t\t\t}\n\t\t\tcase reflect.Slice:\n\t\t\t\t// Always emit type for slices since the triple-quote syntax\n\t\t\t\t// looks like a string (not a slice).\n\t\t\t\topts = opts.WithTypeMode(emitType)\n\t\t\t\tout = opts.FormatType(t, out)\n\t\t\t}\n\t\t\treturn out\n\t\t}\n\n\t// If the text appears to be single-lined text,\n\t// then perform differencing in approximately fixed-sized chunks.\n\t// The output is printed as quoted strings.\n\tcase isMostlyText:\n\t\tlist = opts.formatDiffSlice(\n\t\t\treflect.ValueOf(sx), reflect.ValueOf(sy), 64, \"byte\",\n\t\t\tfunc(v reflect.Value, d diffMode) textRecord {\n\t\t\t\ts := formatString(v.String())\n\t\t\t\treturn textRecord{Diff: d, Value: textLine(s)}\n\t\t\t},\n\t\t)\n\n\t// If the text appears to be binary data,\n\t// then perform differencing in approximately fixed-sized chunks.\n\t// The output is inspired by hexdump.\n\tcase isBinary:\n\t\tlist = opts.formatDiffSlice(\n\t\t\treflect.ValueOf(sx), reflect.ValueOf(sy), 16, \"byte\",\n\t\t\tfunc(v reflect.Value, d diffMode) textRecord {\n\t\t\t\tvar ss []string\n\t\t\t\tfor i := 0; i < v.Len(); i++ {\n\t\t\t\t\tss = append(ss, formatHex(v.Index(i).Uint()))\n\t\t\t\t}\n\t\t\t\ts := strings.Join(ss, \", \")\n\t\t\t\tcomment := commentString(fmt.Sprintf(\"%c|%v|\", d, formatASCII(v.String())))\n\t\t\t\treturn textRecord{Diff: d, Value: textLine(s), Comment: comment}\n\t\t\t},\n\t\t)\n\n\t// For all other slices of primitive types,\n\t// then perform differencing in approximately fixed-sized chunks.\n\t// The size of each chunk depends on the width of the element kind.\n\tdefault:\n\t\tvar chunkSize int\n\t\tif t.Elem().Kind() == reflect.Bool {\n\t\t\tchunkSize = 16\n\t\t} else {\n\t\t\tswitch t.Elem().Bits() {\n\t\t\tcase 8:\n\t\t\t\tchunkSize = 16\n\t\t\tcase 16:\n\t\t\t\tchunkSize = 12\n\t\t\tcase 32:\n\t\t\t\tchunkSize = 8\n\t\t\tdefault:\n\t\t\t\tchunkSize = 8\n\t\t\t}\n\t\t}\n\t\tlist = opts.formatDiffSlice(\n\t\t\tvx, vy, chunkSize, t.Elem().Kind().String(),\n\t\t\tfunc(v reflect.Value, d diffMode) textRecord {\n\t\t\t\tvar ss []string\n\t\t\t\tfor i := 0; i < v.Len(); i++ {\n\t\t\t\t\tswitch t.Elem().Kind() {\n\t\t\t\t\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\t\t\t\t\tss = append(ss, fmt.Sprint(v.Index(i).Int()))\n\t\t\t\t\tcase reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\t\t\t\t\tss = append(ss, fmt.Sprint(v.Index(i).Uint()))\n\t\t\t\t\tcase reflect.Uint8, reflect.Uintptr:\n\t\t\t\t\t\tss = append(ss, formatHex(v.Index(i).Uint()))\n\t\t\t\t\tcase reflect.Bool, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:\n\t\t\t\t\t\tss = append(ss, fmt.Sprint(v.Index(i).Interface()))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ts := strings.Join(ss, \", \")\n\t\t\t\treturn textRecord{Diff: d, Value: textLine(s)}\n\t\t\t},\n\t\t)\n\t}\n\n\t// Wrap the output with appropriate type information.\n\tvar out textNode = &textWrap{Prefix: \"{\", Value: list, Suffix: \"}\"}\n\tif !isMostlyText {\n\t\t// The \"{...}\" byte-sequence literal is not valid Go syntax for strings.\n\t\t// Emit the type for extra clarity (e.g. \"string{...}\").\n\t\tif t.Kind() == reflect.String {\n\t\t\topts = opts.WithTypeMode(emitType)\n\t\t}\n\t\treturn opts.FormatType(t, out)\n\t}\n\tswitch t.Kind() {\n\tcase reflect.String:\n\t\tout = &textWrap{Prefix: \"strings.Join(\", Value: out, Suffix: fmt.Sprintf(\", %q)\", delim)}\n\t\tif t != stringType {\n\t\t\tout = opts.FormatType(t, out)\n\t\t}\n\tcase reflect.Slice:\n\t\tout = &textWrap{Prefix: \"bytes.Join(\", Value: out, Suffix: fmt.Sprintf(\", %q)\", delim)}\n\t\tif t != bytesType {\n\t\t\tout = opts.FormatType(t, out)\n\t\t}\n\t}\n\treturn out\n}\n\n// formatASCII formats s as an ASCII string.\n// This is useful for printing binary strings in a semi-legible way.\nfunc formatASCII(s string) string {\n\tb := bytes.Repeat([]byte{'.'}, len(s))\n\tfor i := 0; i < len(s); i++ {\n\t\tif ' ' <= s[i] && s[i] <= '~' {\n\t\t\tb[i] = s[i]\n\t\t}\n\t}\n\treturn string(b)\n}\n\nfunc (opts formatOptions) formatDiffSlice(\n\tvx, vy reflect.Value, chunkSize int, name string,\n\tmakeRec func(reflect.Value, diffMode) textRecord,\n) (list textList) {\n\teq := func(ix, iy int) bool {\n\t\treturn vx.Index(ix).Interface() == vy.Index(iy).Interface()\n\t}\n\tes := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result {\n\t\treturn diff.BoolResult(eq(ix, iy))\n\t})\n\n\tappendChunks := func(v reflect.Value, d diffMode) int {\n\t\tn0 := v.Len()\n\t\tfor v.Len() > 0 {\n\t\t\tn := chunkSize\n\t\t\tif n > v.Len() {\n\t\t\t\tn = v.Len()\n\t\t\t}\n\t\t\tlist = append(list, makeRec(v.Slice(0, n), d))\n\t\t\tv = v.Slice(n, v.Len())\n\t\t}\n\t\treturn n0 - v.Len()\n\t}\n\n\tvar numDiffs int\n\tmaxLen := -1\n\tif opts.LimitVerbosity {\n\t\tmaxLen = (1 << opts.verbosity()) << 2 // 4, 8, 16, 32, 64, etc...\n\t\topts.VerbosityLevel--\n\t}\n\n\tgroups := coalesceAdjacentEdits(name, es)\n\tgroups = coalesceInterveningIdentical(groups, chunkSize/4)\n\tgroups = cleanupSurroundingIdentical(groups, eq)\n\tmaxGroup := diffStats{Name: name}\n\tfor i, ds := range groups {\n\t\tif maxLen >= 0 && numDiffs >= maxLen {\n\t\t\tmaxGroup = maxGroup.Append(ds)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Print equal.\n\t\tif ds.NumDiff() == 0 {\n\t\t\t// Compute the number of leading and trailing equal bytes to print.\n\t\t\tvar numLo, numHi int\n\t\t\tnumEqual := ds.NumIgnored + ds.NumIdentical\n\t\t\tfor numLo < chunkSize*numContextRecords && numLo+numHi < numEqual && i != 0 {\n\t\t\t\tnumLo++\n\t\t\t}\n\t\t\tfor numHi < chunkSize*numContextRecords && numLo+numHi < numEqual && i != len(groups)-1 {\n\t\t\t\tnumHi++\n\t\t\t}\n\t\t\tif numEqual-(numLo+numHi) <= chunkSize && ds.NumIgnored == 0 {\n\t\t\t\tnumHi = numEqual - numLo // Avoid pointless coalescing of single equal row\n\t\t\t}\n\n\t\t\t// Print the equal bytes.\n\t\t\tappendChunks(vx.Slice(0, numLo), diffIdentical)\n\t\t\tif numEqual > numLo+numHi {\n\t\t\t\tds.NumIdentical -= numLo + numHi\n\t\t\t\tlist.AppendEllipsis(ds)\n\t\t\t}\n\t\t\tappendChunks(vx.Slice(numEqual-numHi, numEqual), diffIdentical)\n\t\t\tvx = vx.Slice(numEqual, vx.Len())\n\t\t\tvy = vy.Slice(numEqual, vy.Len())\n\t\t\tcontinue\n\t\t}\n\n\t\t// Print unequal.\n\t\tlen0 := len(list)\n\t\tnx := appendChunks(vx.Slice(0, ds.NumIdentical+ds.NumRemoved+ds.NumModified), diffRemoved)\n\t\tvx = vx.Slice(nx, vx.Len())\n\t\tny := appendChunks(vy.Slice(0, ds.NumIdentical+ds.NumInserted+ds.NumModified), diffInserted)\n\t\tvy = vy.Slice(ny, vy.Len())\n\t\tnumDiffs += len(list) - len0\n\t}\n\tif maxGroup.IsZero() {\n\t\tassert(vx.Len() == 0 && vy.Len() == 0)\n\t} else {\n\t\tlist.AppendEllipsis(maxGroup)\n\t}\n\treturn list\n}\n\n// coalesceAdjacentEdits coalesces the list of edits into groups of adjacent\n// equal or unequal counts.\n//\n// Example:\n//\n//\tInput:  \"..XXY...Y\"\n//\tOutput: [\n//\t\t{NumIdentical: 2},\n//\t\t{NumRemoved: 2, NumInserted 1},\n//\t\t{NumIdentical: 3},\n//\t\t{NumInserted: 1},\n//\t]\nfunc coalesceAdjacentEdits(name string, es diff.EditScript) (groups []diffStats) {\n\tvar prevMode byte\n\tlastStats := func(mode byte) *diffStats {\n\t\tif prevMode != mode {\n\t\t\tgroups = append(groups, diffStats{Name: name})\n\t\t\tprevMode = mode\n\t\t}\n\t\treturn &groups[len(groups)-1]\n\t}\n\tfor _, e := range es {\n\t\tswitch e {\n\t\tcase diff.Identity:\n\t\t\tlastStats('=').NumIdentical++\n\t\tcase diff.UniqueX:\n\t\t\tlastStats('!').NumRemoved++\n\t\tcase diff.UniqueY:\n\t\t\tlastStats('!').NumInserted++\n\t\tcase diff.Modified:\n\t\t\tlastStats('!').NumModified++\n\t\t}\n\t}\n\treturn groups\n}\n\n// coalesceInterveningIdentical coalesces sufficiently short (<= windowSize)\n// equal groups into adjacent unequal groups that currently result in a\n// dual inserted/removed printout. This acts as a high-pass filter to smooth\n// out high-frequency changes within the windowSize.\n//\n// Example:\n//\n//\tWindowSize: 16,\n//\tInput: [\n//\t\t{NumIdentical: 61},              // group 0\n//\t\t{NumRemoved: 3, NumInserted: 1}, // group 1\n//\t\t{NumIdentical: 6},               // ├── coalesce\n//\t\t{NumInserted: 2},                // ├── coalesce\n//\t\t{NumIdentical: 1},               // ├── coalesce\n//\t\t{NumRemoved: 9},                 // └── coalesce\n//\t\t{NumIdentical: 64},              // group 2\n//\t\t{NumRemoved: 3, NumInserted: 1}, // group 3\n//\t\t{NumIdentical: 6},               // ├── coalesce\n//\t\t{NumInserted: 2},                // ├── coalesce\n//\t\t{NumIdentical: 1},               // ├── coalesce\n//\t\t{NumRemoved: 7},                 // ├── coalesce\n//\t\t{NumIdentical: 1},               // ├── coalesce\n//\t\t{NumRemoved: 2},                 // └── coalesce\n//\t\t{NumIdentical: 63},              // group 4\n//\t]\n//\tOutput: [\n//\t\t{NumIdentical: 61},\n//\t\t{NumIdentical: 7, NumRemoved: 12, NumInserted: 3},\n//\t\t{NumIdentical: 64},\n//\t\t{NumIdentical: 8, NumRemoved: 12, NumInserted: 3},\n//\t\t{NumIdentical: 63},\n//\t]\nfunc coalesceInterveningIdentical(groups []diffStats, windowSize int) []diffStats {\n\tgroups, groupsOrig := groups[:0], groups\n\tfor i, ds := range groupsOrig {\n\t\tif len(groups) >= 2 && ds.NumDiff() > 0 {\n\t\t\tprev := &groups[len(groups)-2] // Unequal group\n\t\t\tcurr := &groups[len(groups)-1] // Equal group\n\t\t\tnext := &groupsOrig[i]         // Unequal group\n\t\t\thadX, hadY := prev.NumRemoved > 0, prev.NumInserted > 0\n\t\t\thasX, hasY := next.NumRemoved > 0, next.NumInserted > 0\n\t\t\tif ((hadX || hasX) && (hadY || hasY)) && curr.NumIdentical <= windowSize {\n\t\t\t\t*prev = prev.Append(*curr).Append(*next)\n\t\t\t\tgroups = groups[:len(groups)-1] // Truncate off equal group\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tgroups = append(groups, ds)\n\t}\n\treturn groups\n}\n\n// cleanupSurroundingIdentical scans through all unequal groups, and\n// moves any leading sequence of equal elements to the preceding equal group and\n// moves and trailing sequence of equal elements to the succeeding equal group.\n//\n// This is necessary since coalesceInterveningIdentical may coalesce edit groups\n// together such that leading/trailing spans of equal elements becomes possible.\n// Note that this can occur even with an optimal diffing algorithm.\n//\n// Example:\n//\n//\tInput: [\n//\t\t{NumIdentical: 61},\n//\t\t{NumIdentical: 1 , NumRemoved: 11, NumInserted: 2}, // assume 3 leading identical elements\n//\t\t{NumIdentical: 67},\n//\t\t{NumIdentical: 7, NumRemoved: 12, NumInserted: 3},  // assume 10 trailing identical elements\n//\t\t{NumIdentical: 54},\n//\t]\n//\tOutput: [\n//\t\t{NumIdentical: 64}, // incremented by 3\n//\t\t{NumRemoved: 9},\n//\t\t{NumIdentical: 67},\n//\t\t{NumRemoved: 9},\n//\t\t{NumIdentical: 64}, // incremented by 10\n//\t]\nfunc cleanupSurroundingIdentical(groups []diffStats, eq func(i, j int) bool) []diffStats {\n\tvar ix, iy int // indexes into sequence x and y\n\tfor i, ds := range groups {\n\t\t// Handle equal group.\n\t\tif ds.NumDiff() == 0 {\n\t\t\tix += ds.NumIdentical\n\t\t\tiy += ds.NumIdentical\n\t\t\tcontinue\n\t\t}\n\n\t\t// Handle unequal group.\n\t\tnx := ds.NumIdentical + ds.NumRemoved + ds.NumModified\n\t\tny := ds.NumIdentical + ds.NumInserted + ds.NumModified\n\t\tvar numLeadingIdentical, numTrailingIdentical int\n\t\tfor j := 0; j < nx && j < ny && eq(ix+j, iy+j); j++ {\n\t\t\tnumLeadingIdentical++\n\t\t}\n\t\tfor j := 0; j < nx && j < ny && eq(ix+nx-1-j, iy+ny-1-j); j++ {\n\t\t\tnumTrailingIdentical++\n\t\t}\n\t\tif numIdentical := numLeadingIdentical + numTrailingIdentical; numIdentical > 0 {\n\t\t\tif numLeadingIdentical > 0 {\n\t\t\t\t// Remove leading identical span from this group and\n\t\t\t\t// insert it into the preceding group.\n\t\t\t\tif i-1 >= 0 {\n\t\t\t\t\tgroups[i-1].NumIdentical += numLeadingIdentical\n\t\t\t\t} else {\n\t\t\t\t\t// No preceding group exists, so prepend a new group,\n\t\t\t\t\t// but do so after we finish iterating over all groups.\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\tgroups = append([]diffStats{{Name: groups[0].Name, NumIdentical: numLeadingIdentical}}, groups...)\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\t// Increment indexes since the preceding group would have handled this.\n\t\t\t\tix += numLeadingIdentical\n\t\t\t\tiy += numLeadingIdentical\n\t\t\t}\n\t\t\tif numTrailingIdentical > 0 {\n\t\t\t\t// Remove trailing identical span from this group and\n\t\t\t\t// insert it into the succeeding group.\n\t\t\t\tif i+1 < len(groups) {\n\t\t\t\t\tgroups[i+1].NumIdentical += numTrailingIdentical\n\t\t\t\t} else {\n\t\t\t\t\t// No succeeding group exists, so append a new group,\n\t\t\t\t\t// but do so after we finish iterating over all groups.\n\t\t\t\t\tdefer func() {\n\t\t\t\t\t\tgroups = append(groups, diffStats{Name: groups[len(groups)-1].Name, NumIdentical: numTrailingIdentical})\n\t\t\t\t\t}()\n\t\t\t\t}\n\t\t\t\t// Do not increment indexes since the succeeding group will handle this.\n\t\t\t}\n\n\t\t\t// Update this group since some identical elements were removed.\n\t\t\tnx -= numIdentical\n\t\t\tny -= numIdentical\n\t\t\tgroups[i] = diffStats{Name: ds.Name, NumRemoved: nx, NumInserted: ny}\n\t\t}\n\t\tix += nx\n\t\tiy += ny\n\t}\n\treturn groups\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/report_text.go",
    "content": "// Copyright 2019, 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 cmp\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode/utf8\"\n\n\t\"github.com/google/go-cmp/cmp/internal/flags\"\n)\n\nvar randBool = rand.New(rand.NewSource(time.Now().Unix())).Intn(2) == 0\n\nconst maxColumnLength = 80\n\ntype indentMode int\n\nfunc (n indentMode) appendIndent(b []byte, d diffMode) []byte {\n\t// The output of Diff is documented as being unstable to provide future\n\t// flexibility in changing the output for more humanly readable reports.\n\t// This logic intentionally introduces instability to the exact output\n\t// so that users can detect accidental reliance on stability early on,\n\t// rather than much later when an actual change to the format occurs.\n\tif flags.Deterministic || randBool {\n\t\t// Use regular spaces (U+0020).\n\t\tswitch d {\n\t\tcase diffUnknown, diffIdentical:\n\t\t\tb = append(b, \"  \"...)\n\t\tcase diffRemoved:\n\t\t\tb = append(b, \"- \"...)\n\t\tcase diffInserted:\n\t\t\tb = append(b, \"+ \"...)\n\t\t}\n\t} else {\n\t\t// Use non-breaking spaces (U+00a0).\n\t\tswitch d {\n\t\tcase diffUnknown, diffIdentical:\n\t\t\tb = append(b, \"  \"...)\n\t\tcase diffRemoved:\n\t\t\tb = append(b, \"- \"...)\n\t\tcase diffInserted:\n\t\t\tb = append(b, \"+ \"...)\n\t\t}\n\t}\n\treturn repeatCount(n).appendChar(b, '\\t')\n}\n\ntype repeatCount int\n\nfunc (n repeatCount) appendChar(b []byte, c byte) []byte {\n\tfor ; n > 0; n-- {\n\t\tb = append(b, c)\n\t}\n\treturn b\n}\n\n// textNode is a simplified tree-based representation of structured text.\n// Possible node types are textWrap, textList, or textLine.\ntype textNode interface {\n\t// Len reports the length in bytes of a single-line version of the tree.\n\t// Nested textRecord.Diff and textRecord.Comment fields are ignored.\n\tLen() int\n\t// Equal reports whether the two trees are structurally identical.\n\t// Nested textRecord.Diff and textRecord.Comment fields are compared.\n\tEqual(textNode) bool\n\t// String returns the string representation of the text tree.\n\t// It is not guaranteed that len(x.String()) == x.Len(),\n\t// nor that x.String() == y.String() implies that x.Equal(y).\n\tString() string\n\n\t// formatCompactTo formats the contents of the tree as a single-line string\n\t// to the provided buffer. Any nested textRecord.Diff and textRecord.Comment\n\t// fields are ignored.\n\t//\n\t// However, not all nodes in the tree should be collapsed as a single-line.\n\t// If a node can be collapsed as a single-line, it is replaced by a textLine\n\t// node. Since the top-level node cannot replace itself, this also returns\n\t// the current node itself.\n\t//\n\t// This does not mutate the receiver.\n\tformatCompactTo([]byte, diffMode) ([]byte, textNode)\n\t// formatExpandedTo formats the contents of the tree as a multi-line string\n\t// to the provided buffer. In order for column alignment to operate well,\n\t// formatCompactTo must be called before calling formatExpandedTo.\n\tformatExpandedTo([]byte, diffMode, indentMode) []byte\n}\n\n// textWrap is a wrapper that concatenates a prefix and/or a suffix\n// to the underlying node.\ntype textWrap struct {\n\tPrefix   string      // e.g., \"bytes.Buffer{\"\n\tValue    textNode    // textWrap | textList | textLine\n\tSuffix   string      // e.g., \"}\"\n\tMetadata interface{} // arbitrary metadata; has no effect on formatting\n}\n\nfunc (s *textWrap) Len() int {\n\treturn len(s.Prefix) + s.Value.Len() + len(s.Suffix)\n}\nfunc (s1 *textWrap) Equal(s2 textNode) bool {\n\tif s2, ok := s2.(*textWrap); ok {\n\t\treturn s1.Prefix == s2.Prefix && s1.Value.Equal(s2.Value) && s1.Suffix == s2.Suffix\n\t}\n\treturn false\n}\nfunc (s *textWrap) String() string {\n\tvar d diffMode\n\tvar n indentMode\n\t_, s2 := s.formatCompactTo(nil, d)\n\tb := n.appendIndent(nil, d)      // Leading indent\n\tb = s2.formatExpandedTo(b, d, n) // Main body\n\tb = append(b, '\\n')              // Trailing newline\n\treturn string(b)\n}\nfunc (s *textWrap) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {\n\tn0 := len(b) // Original buffer length\n\tb = append(b, s.Prefix...)\n\tb, s.Value = s.Value.formatCompactTo(b, d)\n\tb = append(b, s.Suffix...)\n\tif _, ok := s.Value.(textLine); ok {\n\t\treturn b, textLine(b[n0:])\n\t}\n\treturn b, s\n}\nfunc (s *textWrap) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte {\n\tb = append(b, s.Prefix...)\n\tb = s.Value.formatExpandedTo(b, d, n)\n\tb = append(b, s.Suffix...)\n\treturn b\n}\n\n// textList is a comma-separated list of textWrap or textLine nodes.\n// The list may be formatted as multi-lines or single-line at the discretion\n// of the textList.formatCompactTo method.\ntype textList []textRecord\ntype textRecord struct {\n\tDiff       diffMode     // e.g., 0 or '-' or '+'\n\tKey        string       // e.g., \"MyField\"\n\tValue      textNode     // textWrap | textLine\n\tElideComma bool         // avoid trailing comma\n\tComment    fmt.Stringer // e.g., \"6 identical fields\"\n}\n\n// AppendEllipsis appends a new ellipsis node to the list if none already\n// exists at the end. If cs is non-zero it coalesces the statistics with the\n// previous diffStats.\nfunc (s *textList) AppendEllipsis(ds diffStats) {\n\thasStats := !ds.IsZero()\n\tif len(*s) == 0 || !(*s)[len(*s)-1].Value.Equal(textEllipsis) {\n\t\tif hasStats {\n\t\t\t*s = append(*s, textRecord{Value: textEllipsis, ElideComma: true, Comment: ds})\n\t\t} else {\n\t\t\t*s = append(*s, textRecord{Value: textEllipsis, ElideComma: true})\n\t\t}\n\t\treturn\n\t}\n\tif hasStats {\n\t\t(*s)[len(*s)-1].Comment = (*s)[len(*s)-1].Comment.(diffStats).Append(ds)\n\t}\n}\n\nfunc (s textList) Len() (n int) {\n\tfor i, r := range s {\n\t\tn += len(r.Key)\n\t\tif r.Key != \"\" {\n\t\t\tn += len(\": \")\n\t\t}\n\t\tn += r.Value.Len()\n\t\tif i < len(s)-1 {\n\t\t\tn += len(\", \")\n\t\t}\n\t}\n\treturn n\n}\n\nfunc (s1 textList) Equal(s2 textNode) bool {\n\tif s2, ok := s2.(textList); ok {\n\t\tif len(s1) != len(s2) {\n\t\t\treturn false\n\t\t}\n\t\tfor i := range s1 {\n\t\t\tr1, r2 := s1[i], s2[i]\n\t\t\tif !(r1.Diff == r2.Diff && r1.Key == r2.Key && r1.Value.Equal(r2.Value) && r1.Comment == r2.Comment) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (s textList) String() string {\n\treturn (&textWrap{Prefix: \"{\", Value: s, Suffix: \"}\"}).String()\n}\n\nfunc (s textList) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {\n\ts = append(textList(nil), s...) // Avoid mutating original\n\n\t// Determine whether we can collapse this list as a single line.\n\tn0 := len(b) // Original buffer length\n\tvar multiLine bool\n\tfor i, r := range s {\n\t\tif r.Diff == diffInserted || r.Diff == diffRemoved {\n\t\t\tmultiLine = true\n\t\t}\n\t\tb = append(b, r.Key...)\n\t\tif r.Key != \"\" {\n\t\t\tb = append(b, \": \"...)\n\t\t}\n\t\tb, s[i].Value = r.Value.formatCompactTo(b, d|r.Diff)\n\t\tif _, ok := s[i].Value.(textLine); !ok {\n\t\t\tmultiLine = true\n\t\t}\n\t\tif r.Comment != nil {\n\t\t\tmultiLine = true\n\t\t}\n\t\tif i < len(s)-1 {\n\t\t\tb = append(b, \", \"...)\n\t\t}\n\t}\n\t// Force multi-lined output when printing a removed/inserted node that\n\t// is sufficiently long.\n\tif (d == diffInserted || d == diffRemoved) && len(b[n0:]) > maxColumnLength {\n\t\tmultiLine = true\n\t}\n\tif !multiLine {\n\t\treturn b, textLine(b[n0:])\n\t}\n\treturn b, s\n}\n\nfunc (s textList) formatExpandedTo(b []byte, d diffMode, n indentMode) []byte {\n\talignKeyLens := s.alignLens(\n\t\tfunc(r textRecord) bool {\n\t\t\t_, isLine := r.Value.(textLine)\n\t\t\treturn r.Key == \"\" || !isLine\n\t\t},\n\t\tfunc(r textRecord) int { return utf8.RuneCountInString(r.Key) },\n\t)\n\talignValueLens := s.alignLens(\n\t\tfunc(r textRecord) bool {\n\t\t\t_, isLine := r.Value.(textLine)\n\t\t\treturn !isLine || r.Value.Equal(textEllipsis) || r.Comment == nil\n\t\t},\n\t\tfunc(r textRecord) int { return utf8.RuneCount(r.Value.(textLine)) },\n\t)\n\n\t// Format lists of simple lists in a batched form.\n\t// If the list is sequence of only textLine values,\n\t// then batch multiple values on a single line.\n\tvar isSimple bool\n\tfor _, r := range s {\n\t\t_, isLine := r.Value.(textLine)\n\t\tisSimple = r.Diff == 0 && r.Key == \"\" && isLine && r.Comment == nil\n\t\tif !isSimple {\n\t\t\tbreak\n\t\t}\n\t}\n\tif isSimple {\n\t\tn++\n\t\tvar batch []byte\n\t\temitBatch := func() {\n\t\t\tif len(batch) > 0 {\n\t\t\t\tb = n.appendIndent(append(b, '\\n'), d)\n\t\t\t\tb = append(b, bytes.TrimRight(batch, \" \")...)\n\t\t\t\tbatch = batch[:0]\n\t\t\t}\n\t\t}\n\t\tfor _, r := range s {\n\t\t\tline := r.Value.(textLine)\n\t\t\tif len(batch)+len(line)+len(\", \") > maxColumnLength {\n\t\t\t\temitBatch()\n\t\t\t}\n\t\t\tbatch = append(batch, line...)\n\t\t\tbatch = append(batch, \", \"...)\n\t\t}\n\t\temitBatch()\n\t\tn--\n\t\treturn n.appendIndent(append(b, '\\n'), d)\n\t}\n\n\t// Format the list as a multi-lined output.\n\tn++\n\tfor i, r := range s {\n\t\tb = n.appendIndent(append(b, '\\n'), d|r.Diff)\n\t\tif r.Key != \"\" {\n\t\t\tb = append(b, r.Key+\": \"...)\n\t\t}\n\t\tb = alignKeyLens[i].appendChar(b, ' ')\n\n\t\tb = r.Value.formatExpandedTo(b, d|r.Diff, n)\n\t\tif !r.ElideComma {\n\t\t\tb = append(b, ',')\n\t\t}\n\t\tb = alignValueLens[i].appendChar(b, ' ')\n\n\t\tif r.Comment != nil {\n\t\t\tb = append(b, \" // \"+r.Comment.String()...)\n\t\t}\n\t}\n\tn--\n\n\treturn n.appendIndent(append(b, '\\n'), d)\n}\n\nfunc (s textList) alignLens(\n\tskipFunc func(textRecord) bool,\n\tlenFunc func(textRecord) int,\n) []repeatCount {\n\tvar startIdx, endIdx, maxLen int\n\tlens := make([]repeatCount, len(s))\n\tfor i, r := range s {\n\t\tif skipFunc(r) {\n\t\t\tfor j := startIdx; j < endIdx && j < len(s); j++ {\n\t\t\t\tlens[j] = repeatCount(maxLen - lenFunc(s[j]))\n\t\t\t}\n\t\t\tstartIdx, endIdx, maxLen = i+1, i+1, 0\n\t\t} else {\n\t\t\tif maxLen < lenFunc(r) {\n\t\t\t\tmaxLen = lenFunc(r)\n\t\t\t}\n\t\t\tendIdx = i + 1\n\t\t}\n\t}\n\tfor j := startIdx; j < endIdx && j < len(s); j++ {\n\t\tlens[j] = repeatCount(maxLen - lenFunc(s[j]))\n\t}\n\treturn lens\n}\n\n// textLine is a single-line segment of text and is always a leaf node\n// in the textNode tree.\ntype textLine []byte\n\nvar (\n\ttextNil      = textLine(\"nil\")\n\ttextEllipsis = textLine(\"...\")\n)\n\nfunc (s textLine) Len() int {\n\treturn len(s)\n}\nfunc (s1 textLine) Equal(s2 textNode) bool {\n\tif s2, ok := s2.(textLine); ok {\n\t\treturn bytes.Equal([]byte(s1), []byte(s2))\n\t}\n\treturn false\n}\nfunc (s textLine) String() string {\n\treturn string(s)\n}\nfunc (s textLine) formatCompactTo(b []byte, d diffMode) ([]byte, textNode) {\n\treturn append(b, s...), s\n}\nfunc (s textLine) formatExpandedTo(b []byte, _ diffMode, _ indentMode) []byte {\n\treturn append(b, s...)\n}\n\ntype diffStats struct {\n\tName         string\n\tNumIgnored   int\n\tNumIdentical int\n\tNumRemoved   int\n\tNumInserted  int\n\tNumModified  int\n}\n\nfunc (s diffStats) IsZero() bool {\n\ts.Name = \"\"\n\treturn s == diffStats{}\n}\n\nfunc (s diffStats) NumDiff() int {\n\treturn s.NumRemoved + s.NumInserted + s.NumModified\n}\n\nfunc (s diffStats) Append(ds diffStats) diffStats {\n\tassert(s.Name == ds.Name)\n\ts.NumIgnored += ds.NumIgnored\n\ts.NumIdentical += ds.NumIdentical\n\ts.NumRemoved += ds.NumRemoved\n\ts.NumInserted += ds.NumInserted\n\ts.NumModified += ds.NumModified\n\treturn s\n}\n\n// String prints a humanly-readable summary of coalesced records.\n//\n// Example:\n//\n//\tdiffStats{Name: \"Field\", NumIgnored: 5}.String() => \"5 ignored fields\"\nfunc (s diffStats) String() string {\n\tvar ss []string\n\tvar sum int\n\tlabels := [...]string{\"ignored\", \"identical\", \"removed\", \"inserted\", \"modified\"}\n\tcounts := [...]int{s.NumIgnored, s.NumIdentical, s.NumRemoved, s.NumInserted, s.NumModified}\n\tfor i, n := range counts {\n\t\tif n > 0 {\n\t\t\tss = append(ss, fmt.Sprintf(\"%d %v\", n, labels[i]))\n\t\t}\n\t\tsum += n\n\t}\n\n\t// Pluralize the name (adjusting for some obscure English grammar rules).\n\tname := s.Name\n\tif sum > 1 {\n\t\tname += \"s\"\n\t\tif strings.HasSuffix(name, \"ys\") {\n\t\t\tname = name[:len(name)-2] + \"ies\" // e.g., \"entrys\" => \"entries\"\n\t\t}\n\t}\n\n\t// Format the list according to English grammar (with Oxford comma).\n\tswitch n := len(ss); n {\n\tcase 0:\n\t\treturn \"\"\n\tcase 1, 2:\n\t\treturn strings.Join(ss, \" and \") + \" \" + name\n\tdefault:\n\t\treturn strings.Join(ss[:n-1], \", \") + \", and \" + ss[n-1] + \" \" + name\n\t}\n}\n\ntype commentString string\n\nfunc (s commentString) String() string { return string(s) }\n"
  },
  {
    "path": "vendor/github.com/google/go-cmp/cmp/report_value.go",
    "content": "// Copyright 2019, 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 cmp\n\nimport \"reflect\"\n\n// valueNode represents a single node within a report, which is a\n// structured representation of the value tree, containing information\n// regarding which nodes are equal or not.\ntype valueNode struct {\n\tparent *valueNode\n\n\tType   reflect.Type\n\tValueX reflect.Value\n\tValueY reflect.Value\n\n\t// NumSame is the number of leaf nodes that are equal.\n\t// All descendants are equal only if NumDiff is 0.\n\tNumSame int\n\t// NumDiff is the number of leaf nodes that are not equal.\n\tNumDiff int\n\t// NumIgnored is the number of leaf nodes that are ignored.\n\tNumIgnored int\n\t// NumCompared is the number of leaf nodes that were compared\n\t// using an Equal method or Comparer function.\n\tNumCompared int\n\t// NumTransformed is the number of non-leaf nodes that were transformed.\n\tNumTransformed int\n\t// NumChildren is the number of transitive descendants of this node.\n\t// This counts from zero; thus, leaf nodes have no descendants.\n\tNumChildren int\n\t// MaxDepth is the maximum depth of the tree. This counts from zero;\n\t// thus, leaf nodes have a depth of zero.\n\tMaxDepth int\n\n\t// Records is a list of struct fields, slice elements, or map entries.\n\tRecords []reportRecord // If populated, implies Value is not populated\n\n\t// Value is the result of a transformation, pointer indirect, of\n\t// type assertion.\n\tValue *valueNode // If populated, implies Records is not populated\n\n\t// TransformerName is the name of the transformer.\n\tTransformerName string // If non-empty, implies Value is populated\n}\ntype reportRecord struct {\n\tKey   reflect.Value // Invalid for slice element\n\tValue *valueNode\n}\n\nfunc (parent *valueNode) PushStep(ps PathStep) (child *valueNode) {\n\tvx, vy := ps.Values()\n\tchild = &valueNode{parent: parent, Type: ps.Type(), ValueX: vx, ValueY: vy}\n\tswitch s := ps.(type) {\n\tcase StructField:\n\t\tassert(parent.Value == nil)\n\t\tparent.Records = append(parent.Records, reportRecord{Key: reflect.ValueOf(s.Name()), Value: child})\n\tcase SliceIndex:\n\t\tassert(parent.Value == nil)\n\t\tparent.Records = append(parent.Records, reportRecord{Value: child})\n\tcase MapIndex:\n\t\tassert(parent.Value == nil)\n\t\tparent.Records = append(parent.Records, reportRecord{Key: s.Key(), Value: child})\n\tcase Indirect:\n\t\tassert(parent.Value == nil && parent.Records == nil)\n\t\tparent.Value = child\n\tcase TypeAssertion:\n\t\tassert(parent.Value == nil && parent.Records == nil)\n\t\tparent.Value = child\n\tcase Transform:\n\t\tassert(parent.Value == nil && parent.Records == nil)\n\t\tparent.Value = child\n\t\tparent.TransformerName = s.Name()\n\t\tparent.NumTransformed++\n\tdefault:\n\t\tassert(parent == nil) // Must be the root step\n\t}\n\treturn child\n}\n\nfunc (r *valueNode) Report(rs Result) {\n\tassert(r.MaxDepth == 0) // May only be called on leaf nodes\n\n\tif rs.ByIgnore() {\n\t\tr.NumIgnored++\n\t} else {\n\t\tif rs.Equal() {\n\t\t\tr.NumSame++\n\t\t} else {\n\t\t\tr.NumDiff++\n\t\t}\n\t}\n\tassert(r.NumSame+r.NumDiff+r.NumIgnored == 1)\n\n\tif rs.ByMethod() {\n\t\tr.NumCompared++\n\t}\n\tif rs.ByFunc() {\n\t\tr.NumCompared++\n\t}\n\tassert(r.NumCompared <= 1)\n}\n\nfunc (child *valueNode) PopStep() (parent *valueNode) {\n\tif child.parent == nil {\n\t\treturn nil\n\t}\n\tparent = child.parent\n\tparent.NumSame += child.NumSame\n\tparent.NumDiff += child.NumDiff\n\tparent.NumIgnored += child.NumIgnored\n\tparent.NumCompared += child.NumCompared\n\tparent.NumTransformed += child.NumTransformed\n\tparent.NumChildren += child.NumChildren + 1\n\tif parent.MaxDepth < child.MaxDepth+1 {\n\t\tparent.MaxDepth = child.MaxDepth + 1\n\t}\n\treturn parent\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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."
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/and/and_closer.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\n// Package and provides helpers for adding Close to io.{Reader|Writer}.\npackage and\n\nimport (\n\t\"io\"\n)\n\n// ReadCloser implements io.ReadCloser by reading from a particular io.Reader\n// and then calling the provided \"Close()\" method.\ntype ReadCloser struct {\n\tio.Reader\n\tCloseFunc func() error\n}\n\nvar _ io.ReadCloser = (*ReadCloser)(nil)\n\n// Close implements io.ReadCloser\nfunc (rac *ReadCloser) Close() error {\n\treturn rac.CloseFunc()\n}\n\n// WriteCloser implements io.WriteCloser by reading from a particular io.Writer\n// and then calling the provided \"Close()\" method.\ntype WriteCloser struct {\n\tio.Writer\n\tCloseFunc func() error\n}\n\nvar _ io.WriteCloser = (*WriteCloser)(nil)\n\n// Close implements io.WriteCloser\nfunc (wac *WriteCloser) Close() error {\n\treturn wac.CloseFunc()\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/compression/compression.go",
    "content": "// Copyright 2022 Google LLC All Rights Reserved.\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//    http://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\n// Package compression abstracts over gzip and zstd.\npackage compression\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/internal/gzip\"\n\t\"github.com/google/go-containerregistry/internal/zstd\"\n\t\"github.com/google/go-containerregistry/pkg/compression\"\n)\n\n// Opener represents e.g. opening a file.\ntype Opener = func() (io.ReadCloser, error)\n\n// GetCompression detects whether an Opener is compressed and which algorithm is used.\nfunc GetCompression(opener Opener) (compression.Compression, error) {\n\trc, err := opener()\n\tif err != nil {\n\t\treturn compression.None, err\n\t}\n\tdefer rc.Close()\n\n\tcp, _, err := PeekCompression(rc)\n\tif err != nil {\n\t\treturn compression.None, err\n\t}\n\n\treturn cp, nil\n}\n\n// PeekCompression detects whether the input stream is compressed and which algorithm is used.\n//\n// If r implements Peek, we will use that directly, otherwise a small number\n// of bytes are buffered to Peek at the gzip/zstd header, and the returned\n// PeekReader can be used as a replacement for the consumed input io.Reader.\nfunc PeekCompression(r io.Reader) (compression.Compression, PeekReader, error) {\n\tpr := intoPeekReader(r)\n\n\tif isGZip, _, err := checkHeader(pr, gzip.MagicHeader); err != nil {\n\t\treturn compression.None, pr, err\n\t} else if isGZip {\n\t\treturn compression.GZip, pr, nil\n\t}\n\n\tif isZStd, _, err := checkHeader(pr, zstd.MagicHeader); err != nil {\n\t\treturn compression.None, pr, err\n\t} else if isZStd {\n\t\treturn compression.ZStd, pr, nil\n\t}\n\n\treturn compression.None, pr, nil\n}\n\n// PeekReader is an io.Reader that also implements Peek a la bufio.Reader.\ntype PeekReader interface {\n\tio.Reader\n\tPeek(n int) ([]byte, error)\n}\n\n// IntoPeekReader creates a PeekReader from an io.Reader.\n// If the reader already has a Peek method, it will just return the passed reader.\nfunc intoPeekReader(r io.Reader) PeekReader {\n\tif p, ok := r.(PeekReader); ok {\n\t\treturn p\n\t}\n\n\treturn bufio.NewReader(r)\n}\n\n// CheckHeader checks whether the first bytes from a PeekReader match an expected header\nfunc checkHeader(pr PeekReader, expectedHeader []byte) (bool, PeekReader, error) {\n\theader, err := pr.Peek(len(expectedHeader))\n\tif err != nil {\n\t\t// https://github.com/google/go-containerregistry/issues/367\n\t\tif err == io.EOF {\n\t\t\treturn false, pr, nil\n\t\t}\n\t\treturn false, pr, err\n\t}\n\treturn bytes.Equal(header, expectedHeader), pr, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/estargz/estargz.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\n// Package estargz adapts the containerd estargz package to our abstractions.\npackage estargz\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\n\t\"github.com/containerd/stargz-snapshotter/estargz\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\n// Assert that what we're returning is an io.ReadCloser\nvar _ io.ReadCloser = (*estargz.Blob)(nil)\n\n// ReadCloser reads uncompressed tarball input from the io.ReadCloser and\n// returns:\n//   - An io.ReadCloser from which compressed data may be read, and\n//   - A v1.Hash with the hash of the estargz table of contents, or\n//   - An error if the estargz processing encountered a problem.\n//\n// Refer to estargz for the options:\n// https://pkg.go.dev/github.com/containerd/stargz-snapshotter/estargz@v0.4.1#Option\nfunc ReadCloser(r io.ReadCloser, opts ...estargz.Option) (*estargz.Blob, v1.Hash, error) {\n\tdefer r.Close()\n\n\t// TODO(#876): Avoid buffering into memory.\n\tbs, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, v1.Hash{}, err\n\t}\n\tbr := bytes.NewReader(bs)\n\n\trc, err := estargz.Build(io.NewSectionReader(br, 0, int64(len(bs))), opts...)\n\tif err != nil {\n\t\treturn nil, v1.Hash{}, err\n\t}\n\n\th, err := v1.NewHash(rc.TOCDigest().String())\n\treturn rc, h, err\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/gzip/zip.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\n// Package gzip provides helper functions for interacting with gzipped streams.\npackage gzip\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/internal/and\"\n)\n\n// MagicHeader is the start of gzip files.\nvar MagicHeader = []byte{'\\x1f', '\\x8b'}\n\n// ReadCloser reads uncompressed input data from the io.ReadCloser and\n// returns an io.ReadCloser from which compressed data may be read.\n// This uses gzip.BestSpeed for the compression level.\nfunc ReadCloser(r io.ReadCloser) io.ReadCloser {\n\treturn ReadCloserLevel(r, gzip.BestSpeed)\n}\n\n// ReadCloserLevel reads uncompressed input data from the io.ReadCloser and\n// returns an io.ReadCloser from which compressed data may be read.\n// Refer to compress/gzip for the level:\n// https://golang.org/pkg/compress/gzip/#pkg-constants\nfunc ReadCloserLevel(r io.ReadCloser, level int) io.ReadCloser {\n\tpr, pw := io.Pipe()\n\n\t// For highly compressible layers, gzip.Writer will output a very small\n\t// number of bytes per Write(). This is normally fine, but when pushing\n\t// to a registry, we want to ensure that we're taking full advantage of\n\t// the available bandwidth instead of sending tons of tiny writes over\n\t// the wire.\n\t// 64K ought to be small enough for anybody.\n\tbw := bufio.NewWriterSize(pw, 2<<16)\n\n\t// Returns err so we can pw.CloseWithError(err)\n\tgo func() error {\n\t\t// TODO(go1.14): Just defer {pw,gw,r}.Close like you'd expect.\n\t\t// Context: https://golang.org/issue/24283\n\t\tgw, err := gzip.NewWriterLevel(bw, level)\n\t\tif err != nil {\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\tif _, err := io.Copy(gw, r); err != nil {\n\t\t\tdefer r.Close()\n\t\t\tdefer gw.Close()\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\t// Close gzip writer to Flush it and write gzip trailers.\n\t\tif err := gw.Close(); err != nil {\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\t// Flush bufio writer to ensure we write out everything.\n\t\tif err := bw.Flush(); err != nil {\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\t// We don't really care if these fail.\n\t\tdefer pw.Close()\n\t\tdefer r.Close()\n\n\t\treturn nil\n\t}()\n\n\treturn pr\n}\n\n// UnzipReadCloser reads compressed input data from the io.ReadCloser and\n// returns an io.ReadCloser from which uncompressed data may be read.\nfunc UnzipReadCloser(r io.ReadCloser) (io.ReadCloser, error) {\n\tgr, err := gzip.NewReader(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &and.ReadCloser{\n\t\tReader: gr,\n\t\tCloseFunc: func() error {\n\t\t\t// If the unzip fails, then this seems to return the same\n\t\t\t// error as the read.  We don't want this to interfere with\n\t\t\t// us closing the main ReadCloser, since this could leave\n\t\t\t// an open file descriptor (fails on Windows).\n\t\t\tgr.Close()\n\t\t\treturn r.Close()\n\t\t},\n\t}, nil\n}\n\n// Is detects whether the input stream is compressed.\nfunc Is(r io.Reader) (bool, error) {\n\tmagicHeader := make([]byte, 2)\n\tn, err := r.Read(magicHeader)\n\tif n == 0 && err == io.EOF {\n\t\treturn false, nil\n\t}\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn bytes.Equal(magicHeader, MagicHeader), nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/httptest/httptest.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\n// Package httptest provides a method for testing a TLS server a la net/http/httptest.\npackage httptest\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"math/big\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"time\"\n)\n\n// NewTLSServer returns an httptest server, with an http client that has been configured to\n// send all requests to the returned server. The TLS certs are generated for the given domain.\n// If you need a transport, Client().Transport is correctly configured.\nfunc NewTLSServer(domain string, handler http.Handler) (*httptest.Server, error) {\n\ts := httptest.NewUnstartedServer(handler)\n\n\ttemplate := x509.Certificate{\n\t\tSerialNumber: big.NewInt(1),\n\t\tNotBefore:    time.Now().Add(-1 * time.Hour),\n\t\tNotAfter:     time.Now().Add(time.Hour),\n\t\tIPAddresses: []net.IP{\n\t\t\tnet.IPv4(127, 0, 0, 1),\n\t\t\tnet.IPv6loopback,\n\t\t},\n\t\tDNSNames: []string{domain},\n\n\t\tKeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,\n\t\tExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},\n\t\tBasicConstraintsValid: true,\n\t\tIsCA:                  true,\n\t}\n\n\tpriv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tb, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpc := &bytes.Buffer{}\n\tif err := pem.Encode(pc, &pem.Block{Type: \"CERTIFICATE\", Bytes: b}); err != nil {\n\t\treturn nil, err\n\t}\n\n\tek, err := x509.MarshalECPrivateKey(priv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpk := &bytes.Buffer{}\n\tif err := pem.Encode(pk, &pem.Block{Type: \"EC PRIVATE KEY\", Bytes: ek}); err != nil {\n\t\treturn nil, err\n\t}\n\n\tc, err := tls.X509KeyPair(pc.Bytes(), pk.Bytes())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ts.TLS = &tls.Config{\n\t\tCertificates: []tls.Certificate{c},\n\t}\n\ts.StartTLS()\n\n\tcertpool := x509.NewCertPool()\n\tcertpool.AddCert(s.Certificate())\n\n\tt := &http.Transport{\n\t\tTLSClientConfig: &tls.Config{\n\t\t\tRootCAs: certpool,\n\t\t},\n\t\tDialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {\n\t\t\treturn net.Dial(s.Listener.Addr().Network(), s.Listener.Addr().String())\n\t\t},\n\t}\n\ts.Client().Transport = t\n\n\treturn s, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/redact/redact.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\n// Package redact contains a simple context signal for redacting requests.\npackage redact\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/url\"\n)\n\ntype contextKey string\n\nvar redactKey = contextKey(\"redact\")\n\n// NewContext creates a new ctx with the reason for redaction.\nfunc NewContext(ctx context.Context, reason string) context.Context {\n\treturn context.WithValue(ctx, redactKey, reason)\n}\n\n// FromContext returns the redaction reason, if any.\nfunc FromContext(ctx context.Context) (bool, string) {\n\treason, ok := ctx.Value(redactKey).(string)\n\treturn ok, reason\n}\n\n// Error redacts potentially sensitive query parameter values in the URL from the error's message.\n//\n// If the error is a *url.Error, this returns a *url.Error with the URL redacted.\n// Any other error type, or nil, is returned unchanged.\nfunc Error(err error) error {\n\t// If the error is a url.Error, we can redact the URL.\n\t// Otherwise (including if err is nil), we can't redact.\n\tvar uerr *url.Error\n\tif ok := errors.As(err, &uerr); !ok {\n\t\treturn err\n\t}\n\tu, perr := url.Parse(uerr.URL)\n\tif perr != nil {\n\t\treturn err // If the URL can't be parsed, just return the original error.\n\t}\n\tuerr.URL = URL(u).String() // Update the URL to the redacted URL.\n\treturn uerr\n}\n\n// The set of query string keys that we expect to send as part of the registry\n// protocol. Anything else is potentially dangerous to leak, as it's probably\n// from a redirect. These redirects often included tokens or signed URLs.\nvar paramAllowlist = map[string]struct{}{\n\t// Token exchange\n\t\"scope\":   {},\n\t\"service\": {},\n\t// Cross-repo mounting\n\t\"mount\": {},\n\t\"from\":  {},\n\t// Layer PUT\n\t\"digest\": {},\n\t// Listing tags and catalog\n\t\"n\":    {},\n\t\"last\": {},\n}\n\n// URL redacts potentially sensitive query parameter values from the URL's query string.\nfunc URL(u *url.URL) *url.URL {\n\tqs := u.Query()\n\tfor k, v := range qs {\n\t\tfor i := range v {\n\t\t\tif _, ok := paramAllowlist[k]; !ok {\n\t\t\t\t// key is not in the Allowlist\n\t\t\t\tv[i] = \"REDACTED\"\n\t\t\t}\n\t\t}\n\t}\n\tr := *u\n\tr.RawQuery = qs.Encode()\n\treturn &r\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/retry/retry.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\n// Package retry provides methods for retrying operations. It is a thin wrapper\n// around k8s.io/apimachinery/pkg/util/wait to make certain operations easier.\npackage retry\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/internal/retry/wait\"\n)\n\n// Backoff is an alias of our own wait.Backoff to avoid name conflicts with\n// the kubernetes wait package. Typing retry.Backoff is aesier than fixing\n// the wrong import every time you use wait.Backoff.\ntype Backoff = wait.Backoff\n\n// This is implemented by several errors in the net package as well as our\n// transport.Error.\ntype temporary interface {\n\tTemporary() bool\n}\n\n// IsTemporary returns true if err implements Temporary() and it returns true.\nfunc IsTemporary(err error) bool {\n\tif errors.Is(err, context.DeadlineExceeded) {\n\t\treturn false\n\t}\n\tif te, ok := err.(temporary); ok && te.Temporary() {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// IsNotNil returns true if err is not nil.\nfunc IsNotNil(err error) bool {\n\treturn err != nil\n}\n\n// Predicate determines whether an error should be retried.\ntype Predicate func(error) (retry bool)\n\n// Retry retries a given function, f, until a predicate is satisfied, using\n// exponential backoff. If the predicate is never satisfied, it will return the\n// last error returned by f.\nfunc Retry(f func() error, p Predicate, backoff wait.Backoff) (err error) {\n\tif f == nil {\n\t\treturn fmt.Errorf(\"nil f passed to retry\")\n\t}\n\tif p == nil {\n\t\treturn fmt.Errorf(\"nil p passed to retry\")\n\t}\n\n\tcondition := func() (bool, error) {\n\t\terr = f()\n\t\tif p(err) {\n\t\t\treturn false, nil\n\t\t}\n\t\treturn true, err\n\t}\n\n\twait.ExponentialBackoff(backoff, condition)\n\treturn\n}\n\ntype contextKey string\n\nvar key = contextKey(\"never\")\n\n// Never returns a context that signals something should not be retried.\n// This is a hack and can be used to communicate across package boundaries\n// to avoid retry amplification.\nfunc Never(ctx context.Context) context.Context {\n\treturn context.WithValue(ctx, key, true)\n}\n\n// Ever returns true if the context was wrapped by Never.\nfunc Ever(ctx context.Context) bool {\n\treturn ctx.Value(key) == nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/retry/wait/kubernetes_apimachinery_wait.go",
    "content": "/*\nCopyright 2014 The Kubernetes Authors.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package wait is a subset of k8s.io/apimachinery to avoid conflicts\n// in dependencies (specifically, logging).\npackage wait\n\nimport (\n\t\"errors\"\n\t\"math/rand\"\n\t\"time\"\n)\n\n// Jitter returns a time.Duration between duration and duration + maxFactor *\n// duration.\n//\n// This allows clients to avoid converging on periodic behavior. If maxFactor\n// is 0.0, a suggested default value will be chosen.\nfunc Jitter(duration time.Duration, maxFactor float64) time.Duration {\n\tif maxFactor <= 0.0 {\n\t\tmaxFactor = 1.0\n\t}\n\twait := duration + time.Duration(rand.Float64()*maxFactor*float64(duration))\n\treturn wait\n}\n\n// ErrWaitTimeout is returned when the condition exited without success.\nvar ErrWaitTimeout = errors.New(\"timed out waiting for the condition\")\n\n// ConditionFunc returns true if the condition is satisfied, or an error\n// if the loop should be aborted.\ntype ConditionFunc func() (done bool, err error)\n\n// Backoff holds parameters applied to a Backoff function.\ntype Backoff struct {\n\t// The initial duration.\n\tDuration time.Duration\n\t// Duration is multiplied by factor each iteration, if factor is not zero\n\t// and the limits imposed by Steps and Cap have not been reached.\n\t// Should not be negative.\n\t// The jitter does not contribute to the updates to the duration parameter.\n\tFactor float64\n\t// The sleep at each iteration is the duration plus an additional\n\t// amount chosen uniformly at random from the interval between\n\t// zero and `jitter*duration`.\n\tJitter float64\n\t// The remaining number of iterations in which the duration\n\t// parameter may change (but progress can be stopped earlier by\n\t// hitting the cap). If not positive, the duration is not\n\t// changed. Used for exponential backoff in combination with\n\t// Factor and Cap.\n\tSteps int\n\t// A limit on revised values of the duration parameter. If a\n\t// multiplication by the factor parameter would make the duration\n\t// exceed the cap then the duration is set to the cap and the\n\t// steps parameter is set to zero.\n\tCap time.Duration\n}\n\n// Step (1) returns an amount of time to sleep determined by the\n// original Duration and Jitter and (2) mutates the provided Backoff\n// to update its Steps and Duration.\nfunc (b *Backoff) Step() time.Duration {\n\tif b.Steps < 1 {\n\t\tif b.Jitter > 0 {\n\t\t\treturn Jitter(b.Duration, b.Jitter)\n\t\t}\n\t\treturn b.Duration\n\t}\n\tb.Steps--\n\n\tduration := b.Duration\n\n\t// calculate the next step\n\tif b.Factor != 0 {\n\t\tb.Duration = time.Duration(float64(b.Duration) * b.Factor)\n\t\tif b.Cap > 0 && b.Duration > b.Cap {\n\t\t\tb.Duration = b.Cap\n\t\t\tb.Steps = 0\n\t\t}\n\t}\n\n\tif b.Jitter > 0 {\n\t\tduration = Jitter(duration, b.Jitter)\n\t}\n\treturn duration\n}\n\n// ExponentialBackoff repeats a condition check with exponential backoff.\n//\n// It repeatedly checks the condition and then sleeps, using `backoff.Step()`\n// to determine the length of the sleep and adjust Duration and Steps.\n// Stops and returns as soon as:\n// 1. the condition check returns true or an error,\n// 2. `backoff.Steps` checks of the condition have been done, or\n// 3. a sleep truncated by the cap on duration has been completed.\n// In case (1) the returned error is what the condition function returned.\n// In all other cases, ErrWaitTimeout is returned.\nfunc ExponentialBackoff(backoff Backoff, condition ConditionFunc) error {\n\tfor backoff.Steps > 0 {\n\t\tif ok, err := condition(); err != nil || ok {\n\t\t\treturn err\n\t\t}\n\t\tif backoff.Steps == 1 {\n\t\t\tbreak\n\t\t}\n\t\ttime.Sleep(backoff.Step())\n\t}\n\treturn ErrWaitTimeout\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/verify/verify.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\n// Package verify provides a ReadCloser that verifies content matches the\n// expected hash values.\npackage verify\n\nimport (\n\t\"bytes\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/internal/and\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\n// SizeUnknown is a sentinel value to indicate that the expected size is not known.\nconst SizeUnknown = -1\n\ntype verifyReader struct {\n\tinner             io.Reader\n\thasher            hash.Hash\n\texpected          v1.Hash\n\tgotSize, wantSize int64\n}\n\n// Error provides information about the failed hash verification.\ntype Error struct {\n\tgot     string\n\twant    v1.Hash\n\tgotSize int64\n}\n\nfunc (v Error) Error() string {\n\treturn fmt.Sprintf(\"error verifying %s checksum after reading %d bytes; got %q, want %q\",\n\t\tv.want.Algorithm, v.gotSize, v.got, v.want)\n}\n\n// Read implements io.Reader\nfunc (vc *verifyReader) Read(b []byte) (int, error) {\n\tn, err := vc.inner.Read(b)\n\tvc.gotSize += int64(n)\n\tif err == io.EOF {\n\t\tif vc.wantSize != SizeUnknown && vc.gotSize != vc.wantSize {\n\t\t\treturn n, fmt.Errorf(\"error verifying size; got %d, want %d\", vc.gotSize, vc.wantSize)\n\t\t}\n\t\tgot := hex.EncodeToString(vc.hasher.Sum(nil))\n\t\tif want := vc.expected.Hex; got != want {\n\t\t\treturn n, Error{\n\t\t\t\tgot:     vc.expected.Algorithm + \":\" + got,\n\t\t\t\twant:    vc.expected,\n\t\t\t\tgotSize: vc.gotSize,\n\t\t\t}\n\t\t}\n\t}\n\treturn n, err\n}\n\n// ReadCloser wraps the given io.ReadCloser to verify that its contents match\n// the provided v1.Hash before io.EOF is returned.\n//\n// The reader will only be read up to size bytes, to prevent resource\n// exhaustion. If EOF is returned before size bytes are read, an error is\n// returned.\n//\n// A size of SizeUnknown (-1) indicates disables size verification when the size\n// is unknown ahead of time.\nfunc ReadCloser(r io.ReadCloser, size int64, h v1.Hash) (io.ReadCloser, error) {\n\tw, err := v1.Hasher(h.Algorithm)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tr2 := io.TeeReader(r, w) // pass all writes to the hasher.\n\tif size != SizeUnknown {\n\t\tr2 = io.LimitReader(r2, size) // if we know the size, limit to that size.\n\t}\n\treturn &and.ReadCloser{\n\t\tReader: &verifyReader{\n\t\t\tinner:    r2,\n\t\t\thasher:   w,\n\t\t\texpected: h,\n\t\t\twantSize: size,\n\t\t},\n\t\tCloseFunc: r.Close,\n\t}, nil\n}\n\n// Descriptor verifies that the embedded Data field matches the Size and Digest\n// fields of the given v1.Descriptor, returning an error if the Data field is\n// missing or if it contains incorrect data.\nfunc Descriptor(d v1.Descriptor) error {\n\tif d.Data == nil {\n\t\treturn errors.New(\"error verifying descriptor; Data == nil\")\n\t}\n\n\th, sz, err := v1.SHA256(bytes.NewReader(d.Data))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif h != d.Digest {\n\t\treturn fmt.Errorf(\"error verifying Digest; got %q, want %q\", h, d.Digest)\n\t}\n\tif sz != d.Size {\n\t\treturn fmt.Errorf(\"error verifying Size; got %d, want %d\", sz, d.Size)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/windows/windows.go",
    "content": "// Copyright 2021 Google LLC All Rights Reserved.\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//    http://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\npackage windows\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/internal/gzip\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n)\n\n// userOwnerAndGroupSID is a magic value needed to make the binary executable\n// in a Windows container.\n//\n// owner: BUILTIN/Users group: BUILTIN/Users ($sddlValue=\"O:BUG:BU\")\nconst userOwnerAndGroupSID = \"AQAAgBQAAAAkAAAAAAAAAAAAAAABAgAAAAAABSAAAAAhAgAAAQIAAAAAAAUgAAAAIQIAAA==\"\n\n// Windows returns a Layer that is converted to be pullable on Windows.\nfunc Windows(layer v1.Layer) (v1.Layer, error) {\n\t// TODO: do this lazily.\n\n\tlayerReader, err := layer.Uncompressed()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting layer: %w\", err)\n\t}\n\tdefer layerReader.Close()\n\ttarReader := tar.NewReader(layerReader)\n\tw := new(bytes.Buffer)\n\ttarWriter := tar.NewWriter(w)\n\tdefer tarWriter.Close()\n\n\tfor _, dir := range []string{\"Files\", \"Hives\"} {\n\t\tif err := tarWriter.WriteHeader(&tar.Header{\n\t\t\tName:     dir,\n\t\t\tTypeflag: tar.TypeDir,\n\t\t\t// Use a fixed Mode, so that this isn't sensitive to the directory and umask\n\t\t\t// under which it was created. Additionally, windows can only set 0222,\n\t\t\t// 0444, or 0666, none of which are executable.\n\t\t\tMode:   0555,\n\t\t\tFormat: tar.FormatPAX,\n\t\t}); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"writing %s directory: %w\", dir, err)\n\t\t}\n\t}\n\n\tfor {\n\t\theader, err := tarReader.Next()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"reading layer: %w\", err)\n\t\t}\n\n\t\tif strings.HasPrefix(header.Name, \"Files/\") {\n\t\t\treturn nil, fmt.Errorf(\"file path %q already suitable for Windows\", header.Name)\n\t\t}\n\n\t\theader.Name = path.Join(\"Files\", header.Name)\n\t\theader.Format = tar.FormatPAX\n\n\t\t// TODO: this seems to make the file executable on Windows;\n\t\t// only do this if the file should be executable.\n\t\tif header.PAXRecords == nil {\n\t\t\theader.PAXRecords = map[string]string{}\n\t\t}\n\t\theader.PAXRecords[\"MSWINDOWS.rawsd\"] = userOwnerAndGroupSID\n\n\t\tif err := tarWriter.WriteHeader(header); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"writing tar header: %w\", err)\n\t\t}\n\n\t\tif header.Typeflag == tar.TypeReg {\n\t\t\tif _, err = io.Copy(tarWriter, tarReader); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"writing layer file: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := tarWriter.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tb := w.Bytes()\n\t// gzip the contents, then create the layer\n\topener := func() (io.ReadCloser, error) {\n\t\treturn gzip.ReadCloser(io.NopCloser(bytes.NewReader(b))), nil\n\t}\n\tlayer, err = tarball.LayerFromOpener(opener)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating layer: %w\", err)\n\t}\n\n\treturn layer, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/internal/zstd/zstd.go",
    "content": "// Copyright 2022 Google LLC All Rights Reserved.\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//    http://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\n// Package zstd provides helper functions for interacting with zstd streams.\npackage zstd\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/internal/and\"\n\t\"github.com/klauspost/compress/zstd\"\n)\n\n// MagicHeader is the start of zstd files.\nvar MagicHeader = []byte{'\\x28', '\\xb5', '\\x2f', '\\xfd'}\n\n// ReadCloser reads uncompressed input data from the io.ReadCloser and\n// returns an io.ReadCloser from which compressed data may be read.\n// This uses zstd level 1 for the compression.\nfunc ReadCloser(r io.ReadCloser) io.ReadCloser {\n\treturn ReadCloserLevel(r, 1)\n}\n\n// ReadCloserLevel reads uncompressed input data from the io.ReadCloser and\n// returns an io.ReadCloser from which compressed data may be read.\nfunc ReadCloserLevel(r io.ReadCloser, level int) io.ReadCloser {\n\tpr, pw := io.Pipe()\n\n\t// For highly compressible layers, zstd.Writer will output a very small\n\t// number of bytes per Write(). This is normally fine, but when pushing\n\t// to a registry, we want to ensure that we're taking full advantage of\n\t// the available bandwidth instead of sending tons of tiny writes over\n\t// the wire.\n\t// 64K ought to be small enough for anybody.\n\tbw := bufio.NewWriterSize(pw, 2<<16)\n\n\t// Returns err so we can pw.CloseWithError(err)\n\tgo func() error {\n\t\t// TODO(go1.14): Just defer {pw,zw,r}.Close like you'd expect.\n\t\t// Context: https://golang.org/issue/24283\n\t\tzw, err := zstd.NewWriter(bw, zstd.WithEncoderLevel(zstd.EncoderLevelFromZstd(level)))\n\t\tif err != nil {\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\tif _, err := io.Copy(zw, r); err != nil {\n\t\t\tdefer r.Close()\n\t\t\tdefer zw.Close()\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\t// Close zstd writer to Flush it and write zstd trailers.\n\t\tif err := zw.Close(); err != nil {\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\t// Flush bufio writer to ensure we write out everything.\n\t\tif err := bw.Flush(); err != nil {\n\t\t\treturn pw.CloseWithError(err)\n\t\t}\n\n\t\t// We don't really care if these fail.\n\t\tdefer pw.Close()\n\t\tdefer r.Close()\n\n\t\treturn nil\n\t}()\n\n\treturn pr\n}\n\n// UnzipReadCloser reads compressed input data from the io.ReadCloser and\n// returns an io.ReadCloser from which uncompressed data may be read.\nfunc UnzipReadCloser(r io.ReadCloser) (io.ReadCloser, error) {\n\tgr, err := zstd.NewReader(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &and.ReadCloser{\n\t\tReader: gr,\n\t\tCloseFunc: func() error {\n\t\t\t// If the unzip fails, then this seems to return the same\n\t\t\t// error as the read.  We don't want this to interfere with\n\t\t\t// us closing the main ReadCloser, since this could leave\n\t\t\t// an open file descriptor (fails on Windows).\n\t\t\tgr.Close()\n\t\t\treturn r.Close()\n\t\t},\n\t}, nil\n}\n\n// Is detects whether the input stream is compressed.\nfunc Is(r io.Reader) (bool, error) {\n\tmagicHeader := make([]byte, 4)\n\tn, err := r.Read(magicHeader)\n\tif n == 0 && err == io.EOF {\n\t\treturn false, nil\n\t}\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn bytes.Equal(magicHeader, MagicHeader), nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/README.md",
    "content": "# `authn`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/authn?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/authn)\n\nThis README outlines how we acquire and use credentials when interacting with a registry.\n\nAs much as possible, we attempt to emulate `docker`'s authentication behavior and configuration so that this library \"just works\" if you've already configured credentials that work with `docker`; however, when things don't work, a basic understanding of what's going on can help with debugging.\n\nThe official documentation for how authentication with `docker` works is (reasonably) scattered across several different sites and GitHub repositories, so we've tried to summarize the relevant bits here.\n\n## tl;dr for consumers of this package\n\nBy default, [`pkg/v1/remote`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote) uses [`Anonymous`](https://godoc.org/github.com/google/go-containerregistry/pkg/authn#Anonymous) credentials (i.e. _none_), which for most registries will only allow read access to public images.\n\nTo use the credentials found in your Docker config file, you can use the [`DefaultKeychain`](https://godoc.org/github.com/google/go-containerregistry/pkg/authn#DefaultKeychain), e.g.:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\nfunc main() {\n\tref, err := name.ParseReference(\"registry.example.com/private/repo\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Fetch the manifest using default credentials.\n\timg, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Prints the digest of registry.example.com/private/repo\n\tfmt.Println(img.Digest)\n}\n```\n\nThe `DefaultKeychain` will use credentials as described in your Docker config file -- usually `~/.docker/config.json`, or `%USERPROFILE%\\.docker\\config.json` on Windows -- or the location described by the `DOCKER_CONFIG` environment variable, if set.\n\nIf those are not found, `DefaultKeychain` will look for credentials configured using [Podman's expectation](https://docs.podman.io/en/latest/markdown/podman-login.1.html) that these are found in `${XDG_RUNTIME_DIR}/containers/auth.json`.\n\n[See below](#docker-config-auth) for more information about what is configured in this file.\n\n## Emulating Cloud Provider Credential Helpers\n\n[`pkg/v1/google.Keychain`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/v1/google#Keychain) provides a `Keychain` implementation that emulates [`docker-credential-gcr`](https://github.com/GoogleCloudPlatform/docker-credential-gcr) to find credentials in the environment.\nSee [`google.NewEnvAuthenticator`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/v1/google#NewEnvAuthenticator) and [`google.NewGcloudAuthenticator`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/v1/google#NewGcloudAuthenticator) for more information.\n\nTo emulate other credential helpers without requiring them to be available as executables, [`NewKeychainFromHelper`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/authn#NewKeychainFromHelper) provides an adapter that takes a Go implementation satisfying a subset of the [`credentials.Helper`](https://pkg.go.dev/github.com/docker/docker-credential-helpers/credentials#Helper) interface, and makes it available as a `Keychain`.\n\nThis means that you can emulate, for example, [Amazon ECR's `docker-credential-ecr-login` credential helper](https://github.com/awslabs/amazon-ecr-credential-helper) using the same implementation:\n\n```go\nimport (\n\tecr \"github.com/awslabs/amazon-ecr-credential-helper/ecr-login\"\n\t\"github.com/awslabs/amazon-ecr-credential-helper/ecr-login/api\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\nfunc main() {\n\t// ...\n\tecrHelper := ecr.ECRHelper{ClientFactory: api.DefaultClientFactory{}}\n\timg, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.NewKeychainFromHelper(ecrHelper)))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// ...\n}\n```\n\nLikewise, you can emulate [Azure's ACR `docker-credential-acr-env` credential helper](https://github.com/chrismellard/docker-credential-acr-env):\n\n```go\nimport (\n\t\"github.com/chrismellard/docker-credential-acr-env/pkg/credhelper\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\nfunc main() {\n\t// ...\n\tacrHelper := credhelper.NewACRCredentialsHelper()\n\timg, err := remote.Get(ref, remote.WithAuthFromKeychain(authn.NewKeychainFromHelper(acrHelper)))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// ...\n}\n```\n\n<!-- TODO(jasonhall): Wrap these in docker-credential-magic and reference those from here. -->\n\n## Using Multiple `Keychain`s\n\n[`NewMultiKeychain`](https://pkg.go.dev/github.com/google/go-containerregistry/pkg/authn#NewMultiKeychain) allows you to specify multiple `Keychain` implementations, which will be checked in order when credentials are needed.\n\nFor example:\n\n```go\nkc := authn.NewMultiKeychain(\n    authn.DefaultKeychain,\n    google.Keychain,\n    authn.NewKeychainFromHelper(ecr.ECRHelper{ClientFactory: api.DefaultClientFactory{}}),\n    authn.NewKeychainFromHelper(acr.ACRCredHelper{}),\n)\n```\n\nThis multi-keychain will:\n\n- first check for credentials found in the Docker config file, as describe above, then\n- check for GCP credentials available in the environment, as described above, then\n- check for ECR credentials by emulating the ECR credential helper, then\n- check for ACR credentials by emulating the ACR credential helper.\n\nIf any keychain implementation is able to provide credentials for the request, they will be used, and further keychain implementations will not be consulted.\n\nIf no implementations are able to provide credentials, `Anonymous` credentials will be used.\n\n## Docker Config Auth\n\nWhat follows attempts to gather useful information about Docker's config.json and make it available in one place.\n\nIf you have questions, please [file an issue](https://github.com/google/go-containerregistry/issues/new).\n\n### Plaintext\n\nThe config file is where your credentials are stored when you invoke `docker login`, e.g. the contents may look something like this:\n\n```json\n{\n\t\"auths\": {\n\t\t\"registry.example.com\": {\n\t\t\t\"auth\": \"QXp1cmVEaWFtb25kOmh1bnRlcjI=\"\n\t\t}\n\t}\n}\n```\n\nThe `auths` map has an entry per registry, and the `auth` field contains your username and password encoded as [HTTP 'Basic' Auth](https://tools.ietf.org/html/rfc7617).\n\n**NOTE**: This means that your credentials are stored _in plaintext_:\n\n```bash\n$ echo \"QXp1cmVEaWFtb25kOmh1bnRlcjI=\" | base64 -d\nAzureDiamond:hunter2\n```\n\nFor what it's worth, this config file is equivalent to:\n\n```json\n{\n\t\"auths\": {\n\t\t\"registry.example.com\": {\n\t\t\t\"username\": \"AzureDiamond\",\n\t\t\t\"password\": \"hunter2\"\n\t\t}\n\t}\n}\n```\n\n... which is useful to know if e.g. your CI system provides you a registry username and password via environment variables and you want to populate this file manually without invoking `docker login`.\n\n### Helpers\n\nIf you log in like this, `docker` will warn you that you should use a [credential helper](https://docs.docker.com/engine/reference/commandline/login/#credentials-store), and you should!\n\nTo configure a global credential helper:\n```json\n{\n\t\"credsStore\": \"osxkeychain\"\n}\n```\n\nTo configure a per-registry credential helper:\n```json\n{\n\t\"credHelpers\": {\n\t\t\"gcr.io\": \"gcr\"\n\t}\n}\n```\n\nWe use [`github.com/docker/cli/cli/config.Load`](https://godoc.org/github.com/docker/cli/cli/config#Load) to parse the config file and invoke any necessary credential helpers. This handles the logic of taking a [`ConfigFile`](https://github.com/docker/cli/blob/ba63a92655c0bea4857b8d6cc4991498858b3c60/cli/config/configfile/file.go#L25-L54) + registry domain and producing an [`AuthConfig`](https://github.com/docker/cli/blob/ba63a92655c0bea4857b8d6cc4991498858b3c60/cli/config/types/authconfig.go#L3-L22), which determines how we authenticate to the registry.\n\n## Credential Helpers\n\nThe [credential helper protocol](https://github.com/docker/docker-credential-helpers) allows you to configure a binary that supplies credentials for the registry, rather than hard-coding them in the config file.\n\nThe protocol has several verbs, but the one we most care about is `get`.\n\nFor example, using the following config file:\n```json\n{\n\t\"credHelpers\": {\n\t\t\"gcr.io\": \"gcr\",\n\t\t\"eu.gcr.io\": \"gcr\"\n\t}\n}\n```\n\nTo acquire credentials for `gcr.io`, we look in the `credHelpers` map to find\nthe credential helper for `gcr.io` is `gcr`. By appending that value to\n`docker-credential-`, we can get the name of the binary we need to use.\n\nFor this example, that's `docker-credential-gcr`, which must be on our `$PATH`.\nWe'll then invoke that binary to get credentials:\n\n```bash\n$ echo \"gcr.io\" | docker-credential-gcr get\n{\"Username\":\"_token\",\"Secret\":\"<long access token>\"}\n```\n\nYou can configure the same credential helper for multiple registries, which is\nwhy we need to pass the domain in via STDIN, e.g. if we were trying to access\n`eu.gcr.io`, we'd do this instead:\n\n```bash\n$ echo \"eu.gcr.io\" | docker-credential-gcr get\n{\"Username\":\"_token\",\"Secret\":\"<long access token>\"}\n```\n\n### Debugging credential helpers\n\nIf a credential helper is configured but doesn't seem to be working, it can be\nchallenging to debug. Implementing a fake credential helper lets you poke around\nto make it easier to see where the failure is happening.\n\nThis \"implements\" a credential helper with hard-coded values:\n```\n#!/usr/bin/env bash\necho '{\"Username\":\"<token>\",\"Secret\":\"hunter2\"}'\n```\n\n\nThis implements a credential helper that prints the output of\n`docker-credential-gcr` to both stderr and whatever called it, which allows you\nto snoop on another credential helper:\n```\n#!/usr/bin/env bash\ndocker-credential-gcr $@ | tee >(cat 1>&2)\n```\n\nPut those files somewhere on your path, naming them e.g.\n`docker-credential-hardcoded` and `docker-credential-tee`, then modify the\nconfig file to use them:\n\n```json\n{\n\t\"credHelpers\": {\n\t\t\"gcr.io\": \"tee\",\n\t\t\"eu.gcr.io\": \"hardcoded\"\n\t}\n}\n```\n\nThe `docker-credential-tee` trick works with both `crane` and `docker`:\n\n```bash\n$ crane manifest gcr.io/google-containers/pause > /dev/null\n{\"ServerURL\":\"\",\"Username\":\"_dcgcr_1_5_0_token\",\"Secret\":\"<redacted>\"}\n\n$ docker pull gcr.io/google-containers/pause\nUsing default tag: latest\n{\"ServerURL\":\"\",\"Username\":\"_dcgcr_1_5_0_token\",\"Secret\":\"<redacted>\"}\nlatest: Pulling from google-containers/pause\na3ed95caeb02: Pull complete\n4964c72cd024: Pull complete\nDigest: sha256:a78c2d6208eff9b672de43f880093100050983047b7b0afe0217d3656e1b0d5f\nStatus: Downloaded newer image for gcr.io/google-containers/pause:latest\ngcr.io/google-containers/pause:latest\n```\n\n## The Registry\n\nThere are two methods for authenticating against a registry:\n[token](https://docs.docker.com/registry/spec/auth/token/) and\n[oauth2](https://docs.docker.com/registry/spec/auth/oauth/).\n\nBoth methods are used to acquire an opaque `Bearer` token (or\n[RegistryToken](https://github.com/docker/cli/blob/ba63a92655c0bea4857b8d6cc4991498858b3c60/cli/config/types/authconfig.go#L21))\nto use in the `Authorization` header. The registry will return a `401\nUnauthorized` during the [version\ncheck](https://github.com/opencontainers/distribution-spec/blob/2c3975d1f03b67c9a0203199038adea0413f0573/spec.md#api-version-check)\n(or during normal operations) with\n[Www-Authenticate](https://tools.ietf.org/html/rfc7235#section-4.1) challenge\nindicating how to proceed.\n\n### Token\n\nIf we get back an `AuthConfig` containing a [`Username/Password`](https://github.com/docker/cli/blob/ba63a92655c0bea4857b8d6cc4991498858b3c60/cli/config/types/authconfig.go#L5-L6)\nor\n[`Auth`](https://github.com/docker/cli/blob/ba63a92655c0bea4857b8d6cc4991498858b3c60/cli/config/types/authconfig.go#L7),\nwe'll use the token method for authentication:\n\n![basic](../../images/credhelper-basic.svg)\n\n### OAuth 2\n\nIf we get back an `AuthConfig` containing an [`IdentityToken`](https://github.com/docker/cli/blob/ba63a92655c0bea4857b8d6cc4991498858b3c60/cli/config/types/authconfig.go#L18)\nwe'll use the oauth2 method for authentication:\n\n![oauth](../../images/credhelper-oauth.svg)\n\nThis happens when a credential helper returns a response with the\n[`Username`](https://github.com/docker/docker-credential-helpers/blob/f78081d1f7fef6ad74ad6b79368de6348386e591/credentials/credentials.go#L16)\nset to `<token>` (no, that's not a placeholder, the literal string `\"<token>\"`).\nIt is unclear why: [moby/moby#36926](https://github.com/moby/moby/issues/36926).\n\nWe only support the oauth2 `grant_type` for `refresh_token` ([#629](https://github.com/google/go-containerregistry/issues/629)),\nsince it's impossible to determine from the registry response whether we should\nuse oauth, and the token method for authentication is widely implemented by\nregistries.\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/anon.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage authn\n\n// anonymous implements Authenticator for anonymous authentication.\ntype anonymous struct{}\n\n// Authorization implements Authenticator.\nfunc (a *anonymous) Authorization() (*AuthConfig, error) {\n\treturn &AuthConfig{}, nil\n}\n\n// Anonymous is a singleton Authenticator for providing anonymous auth.\nvar Anonymous Authenticator = &anonymous{}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/auth.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage authn\n\n// auth is an Authenticator that simply returns the wrapped AuthConfig.\ntype auth struct {\n\tconfig AuthConfig\n}\n\n// FromConfig returns an Authenticator that just returns the given AuthConfig.\nfunc FromConfig(cfg AuthConfig) Authenticator {\n\treturn &auth{cfg}\n}\n\n// Authorization implements Authenticator.\nfunc (a *auth) Authorization() (*AuthConfig, error) {\n\treturn &a.config, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/authn.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage authn\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// Authenticator is used to authenticate Docker transports.\ntype Authenticator interface {\n\t// Authorization returns the value to use in an http transport's Authorization header.\n\tAuthorization() (*AuthConfig, error)\n}\n\n// AuthConfig contains authorization information for connecting to a Registry\n// Inlined what we use from github.com/docker/cli/cli/config/types\ntype AuthConfig struct {\n\tUsername string `json:\"username,omitempty\"`\n\tPassword string `json:\"password,omitempty\"`\n\tAuth     string `json:\"auth,omitempty\"`\n\n\t// IdentityToken is used to authenticate the user and get\n\t// an access token for the registry.\n\tIdentityToken string `json:\"identitytoken,omitempty\"`\n\n\t// RegistryToken is a bearer token to be sent to a registry\n\tRegistryToken string `json:\"registrytoken,omitempty\"`\n}\n\n// This is effectively a copy of the type AuthConfig. This simplifies\n// JSON unmarshalling since AuthConfig methods are not inherited\ntype authConfig AuthConfig\n\n// UnmarshalJSON implements json.Unmarshaler\nfunc (a *AuthConfig) UnmarshalJSON(data []byte) error {\n\tvar shadow authConfig\n\terr := json.Unmarshal(data, &shadow)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*a = (AuthConfig)(shadow)\n\n\tif len(shadow.Auth) != 0 {\n\t\tvar derr error\n\t\ta.Username, a.Password, derr = decodeDockerConfigFieldAuth(shadow.Auth)\n\t\tif derr != nil {\n\t\t\terr = fmt.Errorf(\"unable to decode auth field: %w\", derr)\n\t\t}\n\t} else if len(a.Username) != 0 && len(a.Password) != 0 {\n\t\ta.Auth = encodeDockerConfigFieldAuth(shadow.Username, shadow.Password)\n\t}\n\n\treturn err\n}\n\n// MarshalJSON implements json.Marshaler\nfunc (a AuthConfig) MarshalJSON() ([]byte, error) {\n\tshadow := (authConfig)(a)\n\tshadow.Auth = encodeDockerConfigFieldAuth(shadow.Username, shadow.Password)\n\treturn json.Marshal(shadow)\n}\n\n// decodeDockerConfigFieldAuth deserializes the \"auth\" field from dockercfg into a\n// username and a password. The format of the auth field is base64(<username>:<password>).\n//\n// From https://github.com/kubernetes/kubernetes/blob/75e49ec824b183288e1dbaccfd7dbe77d89db381/pkg/credentialprovider/config.go\n// Copyright 2014 The Kubernetes Authors.\n// SPDX-License-Identifier: Apache-2.0\nfunc decodeDockerConfigFieldAuth(field string) (username, password string, err error) {\n\tvar decoded []byte\n\t// StdEncoding can only decode padded string\n\t// RawStdEncoding can only decode unpadded string\n\tif strings.HasSuffix(strings.TrimSpace(field), \"=\") {\n\t\t// decode padded data\n\t\tdecoded, err = base64.StdEncoding.DecodeString(field)\n\t} else {\n\t\t// decode unpadded data\n\t\tdecoded, err = base64.RawStdEncoding.DecodeString(field)\n\t}\n\n\tif err != nil {\n\t\treturn\n\t}\n\n\tparts := strings.SplitN(string(decoded), \":\", 2)\n\tif len(parts) != 2 {\n\t\terr = fmt.Errorf(\"must be formatted as base64(username:password)\")\n\t\treturn\n\t}\n\n\tusername = parts[0]\n\tpassword = parts[1]\n\n\treturn\n}\n\nfunc encodeDockerConfigFieldAuth(username, password string) string {\n\treturn base64.StdEncoding.EncodeToString([]byte(username + \":\" + password))\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/basic.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage authn\n\n// Basic implements Authenticator for basic authentication.\ntype Basic struct {\n\tUsername string\n\tPassword string\n}\n\n// Authorization implements Authenticator.\nfunc (b *Basic) Authorization() (*AuthConfig, error) {\n\treturn &AuthConfig{\n\t\tUsername: b.Username,\n\t\tPassword: b.Password,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/bearer.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage authn\n\n// Bearer implements Authenticator for bearer authentication.\ntype Bearer struct {\n\tToken string `json:\"token\"`\n}\n\n// Authorization implements Authenticator.\nfunc (b *Bearer) Authorization() (*AuthConfig, error) {\n\treturn &AuthConfig{\n\t\tRegistryToken: b.Token,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package authn defines different methods of authentication for\n// talking to a container registry.\npackage authn\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage authn\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/docker/cli/cli/config\"\n\t\"github.com/docker/cli/cli/config/configfile\"\n\t\"github.com/docker/cli/cli/config/types\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/mitchellh/go-homedir\"\n)\n\n// Resource represents a registry or repository that can be authenticated against.\ntype Resource interface {\n\t// String returns the full string representation of the target, e.g.\n\t// gcr.io/my-project or just gcr.io.\n\tString() string\n\n\t// RegistryStr returns just the registry portion of the target, e.g. for\n\t// gcr.io/my-project, this should just return gcr.io. This is needed to\n\t// pull out an appropriate hostname.\n\tRegistryStr() string\n}\n\n// Keychain is an interface for resolving an image reference to a credential.\ntype Keychain interface {\n\t// Resolve looks up the most appropriate credential for the specified target.\n\tResolve(Resource) (Authenticator, error)\n}\n\n// defaultKeychain implements Keychain with the semantics of the standard Docker\n// credential keychain.\ntype defaultKeychain struct {\n\tmu sync.Mutex\n}\n\nvar (\n\t// DefaultKeychain implements Keychain by interpreting the docker config file.\n\tDefaultKeychain = &defaultKeychain{}\n)\n\nconst (\n\t// DefaultAuthKey is the key used for dockerhub in config files, which\n\t// is hardcoded for historical reasons.\n\tDefaultAuthKey = \"https://\" + name.DefaultRegistry + \"/v1/\"\n)\n\n// Resolve implements Keychain.\nfunc (dk *defaultKeychain) Resolve(target Resource) (Authenticator, error) {\n\tdk.mu.Lock()\n\tdefer dk.mu.Unlock()\n\n\t// Podman users may have their container registry auth configured in a\n\t// different location, that Docker packages aren't aware of.\n\t// If the Docker config file isn't found, we'll fallback to look where\n\t// Podman configures it, and parse that as a Docker auth config instead.\n\n\t// First, check $HOME/.docker/config.json\n\tfoundDockerConfig := false\n\thome, err := homedir.Dir()\n\tif err == nil {\n\t\tfoundDockerConfig = fileExists(filepath.Join(home, \".docker/config.json\"))\n\t}\n\t// If $HOME/.docker/config.json isn't found, check $DOCKER_CONFIG (if set)\n\tif !foundDockerConfig && os.Getenv(\"DOCKER_CONFIG\") != \"\" {\n\t\tfoundDockerConfig = fileExists(filepath.Join(os.Getenv(\"DOCKER_CONFIG\"), \"config.json\"))\n\t}\n\t// If either of those locations are found, load it using Docker's\n\t// config.Load, which may fail if the config can't be parsed.\n\t//\n\t// If neither was found, look for Podman's auth at\n\t// $XDG_RUNTIME_DIR/containers/auth.json and attempt to load it as a\n\t// Docker config.\n\t//\n\t// If neither are found, fallback to Anonymous.\n\tvar cf *configfile.ConfigFile\n\tif foundDockerConfig {\n\t\tcf, err = config.Load(os.Getenv(\"DOCKER_CONFIG\"))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tf, err := os.Open(filepath.Join(os.Getenv(\"XDG_RUNTIME_DIR\"), \"containers/auth.json\"))\n\t\tif err != nil {\n\t\t\treturn Anonymous, nil\n\t\t}\n\t\tdefer f.Close()\n\t\tcf, err = config.LoadFromReader(f)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// See:\n\t// https://github.com/google/ko/issues/90\n\t// https://github.com/moby/moby/blob/fc01c2b481097a6057bec3cd1ab2d7b4488c50c4/registry/config.go#L397-L404\n\tvar cfg, empty types.AuthConfig\n\tfor _, key := range []string{\n\t\ttarget.String(),\n\t\ttarget.RegistryStr(),\n\t} {\n\t\tif key == name.DefaultRegistry {\n\t\t\tkey = DefaultAuthKey\n\t\t}\n\n\t\tcfg, err = cf.GetAuthConfig(key)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// cf.GetAuthConfig automatically sets the ServerAddress attribute. Since\n\t\t// we don't make use of it, clear the value for a proper \"is-empty\" test.\n\t\t// See: https://github.com/google/go-containerregistry/issues/1510\n\t\tcfg.ServerAddress = \"\"\n\t\tif cfg != empty {\n\t\t\tbreak\n\t\t}\n\t}\n\tif cfg == empty {\n\t\treturn Anonymous, nil\n\t}\n\n\treturn FromConfig(AuthConfig{\n\t\tUsername:      cfg.Username,\n\t\tPassword:      cfg.Password,\n\t\tAuth:          cfg.Auth,\n\t\tIdentityToken: cfg.IdentityToken,\n\t\tRegistryToken: cfg.RegistryToken,\n\t}), nil\n}\n\n// fileExists returns true if the given path exists and is not a directory.\nfunc fileExists(path string) bool {\n\tfi, err := os.Stat(path)\n\treturn err == nil && !fi.IsDir()\n}\n\n// Helper is a subset of the Docker credential helper credentials.Helper\n// interface used by NewKeychainFromHelper.\n//\n// See:\n// https://pkg.go.dev/github.com/docker/docker-credential-helpers/credentials#Helper\ntype Helper interface {\n\tGet(serverURL string) (string, string, error)\n}\n\n// NewKeychainFromHelper returns a Keychain based on a Docker credential helper\n// implementation that can Get username and password credentials for a given\n// server URL.\nfunc NewKeychainFromHelper(h Helper) Keychain { return wrapper{h} }\n\ntype wrapper struct{ h Helper }\n\nfunc (w wrapper) Resolve(r Resource) (Authenticator, error) {\n\tu, p, err := w.h.Get(r.RegistryStr())\n\tif err != nil {\n\t\treturn Anonymous, nil\n\t}\n\t// If the secret being stored is an identity token, the Username should be set to <token>\n\t// ref: https://docs.docker.com/engine/reference/commandline/login/#credential-helper-protocol\n\tif u == \"<token>\" {\n\t\treturn FromConfig(AuthConfig{Username: u, IdentityToken: p}), nil\n\t}\n\treturn FromConfig(AuthConfig{Username: u, Password: p}), nil\n}\n\nfunc RefreshingKeychain(inner Keychain, duration time.Duration) Keychain {\n\treturn &refreshingKeychain{\n\t\tkeychain: inner,\n\t\tduration: duration,\n\t}\n}\n\ntype refreshingKeychain struct {\n\tkeychain Keychain\n\tduration time.Duration\n\tclock    func() time.Time\n}\n\nfunc (r *refreshingKeychain) Resolve(target Resource) (Authenticator, error) {\n\tlast := time.Now()\n\tauth, err := r.keychain.Resolve(target)\n\tif err != nil || auth == Anonymous {\n\t\treturn auth, err\n\t}\n\treturn &refreshing{\n\t\ttarget:   target,\n\t\tkeychain: r.keychain,\n\t\tlast:     last,\n\t\tcached:   auth,\n\t\tduration: r.duration,\n\t\tclock:    r.clock,\n\t}, nil\n}\n\ntype refreshing struct {\n\tsync.Mutex\n\ttarget   Resource\n\tkeychain Keychain\n\n\tduration time.Duration\n\n\tlast   time.Time\n\tcached Authenticator\n\n\t// for testing\n\tclock func() time.Time\n}\n\nfunc (r *refreshing) Authorization() (*AuthConfig, error) {\n\tr.Lock()\n\tdefer r.Unlock()\n\tif r.cached == nil || r.expired() {\n\t\tr.last = r.now()\n\t\tauth, err := r.keychain.Resolve(r.target)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tr.cached = auth\n\t}\n\treturn r.cached.Authorization()\n}\n\nfunc (r *refreshing) now() time.Time {\n\tif r.clock == nil {\n\t\treturn time.Now()\n\t}\n\treturn r.clock()\n}\n\nfunc (r *refreshing) expired() bool {\n\treturn r.now().Sub(r.last) > r.duration\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/authn/multikeychain.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage authn\n\ntype multiKeychain struct {\n\tkeychains []Keychain\n}\n\n// Assert that our multi-keychain implements Keychain.\nvar _ (Keychain) = (*multiKeychain)(nil)\n\n// NewMultiKeychain composes a list of keychains into one new keychain.\nfunc NewMultiKeychain(kcs ...Keychain) Keychain {\n\treturn &multiKeychain{keychains: kcs}\n}\n\n// Resolve implements Keychain.\nfunc (mk *multiKeychain) Resolve(target Resource) (Authenticator, error) {\n\tfor _, kc := range mk.keychains {\n\t\tauth, err := kc.Resolve(target)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif auth != Anonymous {\n\t\t\treturn auth, nil\n\t\t}\n\t}\n\treturn Anonymous, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/compression/compression.go",
    "content": "// Copyright 2022 Google LLC All Rights Reserved.\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//    http://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\n// Package compression abstracts over gzip and zstd.\npackage compression\n\n// Compression is an enumeration of the supported compression algorithms\ntype Compression string\n\n// The collection of known MediaType values.\nconst (\n\tNone Compression = \"none\"\n\tGZip Compression = \"gzip\"\n\tZStd Compression = \"zstd\"\n)\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/append.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/google/go-containerregistry/internal/windows\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/mutate\"\n\t\"github.com/google/go-containerregistry/pkg/v1/stream\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nfunc isWindows(img v1.Image) (bool, error) {\n\tcfg, err := img.ConfigFile()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn cfg != nil && cfg.OS == \"windows\", nil\n}\n\n// Append reads a layer from path and appends it the the v1.Image base.\n//\n// If the base image is a Windows base image (i.e., its config.OS is\n// \"windows\"), the contents of the tarballs will be modified to be suitable for\n// a Windows container image.`,\nfunc Append(base v1.Image, paths ...string) (v1.Image, error) {\n\tif base == nil {\n\t\treturn nil, fmt.Errorf(\"invalid argument: base\")\n\t}\n\n\twin, err := isWindows(base)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting base image: %w\", err)\n\t}\n\n\tbaseMediaType, err := base.MediaType()\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting base image media type: %w\", err)\n\t}\n\n\tlayerType := types.DockerLayer\n\n\tif baseMediaType == types.OCIManifestSchema1 {\n\t\tlayerType = types.OCILayer\n\t}\n\n\tlayers := make([]v1.Layer, 0, len(paths))\n\tfor _, path := range paths {\n\t\tlayer, err := getLayer(path, layerType)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"reading layer %q: %w\", path, err)\n\t\t}\n\n\t\tif win {\n\t\t\tlayer, err = windows.Windows(layer)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"converting %q for Windows: %w\", path, err)\n\t\t\t}\n\t\t}\n\n\t\tlayers = append(layers, layer)\n\t}\n\n\treturn mutate.AppendLayers(base, layers...)\n}\n\nfunc getLayer(path string, layerType types.MediaType) (v1.Layer, error) {\n\tf, err := streamFile(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif f != nil {\n\t\treturn stream.NewLayer(f, stream.WithMediaType(layerType)), nil\n\t}\n\n\treturn tarball.LayerFromFile(path, tarball.WithMediaType(layerType))\n}\n\n// If we're dealing with a named pipe, trying to open it multiple times will\n// fail, so we need to do a streaming upload.\n//\n// returns nil, nil for non-streaming files\nfunc streamFile(path string) (*os.File, error) {\n\tif path == \"-\" {\n\t\treturn os.Stdin, nil\n\t}\n\tfi, err := os.Stat(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !fi.Mode().IsRegular() {\n\t\treturn os.Open(path)\n\t}\n\n\treturn nil, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/catalog.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"context\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\n// Catalog returns the repositories in a registry's catalog.\nfunc Catalog(src string, opt ...Option) (res []string, err error) {\n\to := makeOptions(opt...)\n\treg, err := name.NewRegistry(src, o.Name...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// This context gets overridden by remote.WithContext, which is set by\n\t// crane.WithContext.\n\treturn remote.Catalog(context.Background(), reg, o.Remote...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/config.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\n// Config returns the config file for the remote image ref.\nfunc Config(ref string, opt ...Option) ([]byte, error) {\n\ti, _, err := getImage(ref, opt...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.RawConfigFile()\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/copy.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// Copy copies a remote image or index from src to dst.\nfunc Copy(src, dst string, opt ...Option) error {\n\to := makeOptions(opt...)\n\tsrcRef, err := name.ParseReference(src, o.Name...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference %q: %w\", src, err)\n\t}\n\n\tdstRef, err := name.ParseReference(dst, o.Name...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference for %q: %w\", dst, err)\n\t}\n\n\tpuller, err := remote.NewPuller(o.Remote...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif tag, ok := dstRef.(name.Tag); ok {\n\t\tif o.noclobber {\n\t\t\tlogs.Progress.Printf(\"Checking existing tag %v\", tag)\n\t\t\thead, err := puller.Head(o.ctx, tag)\n\t\t\tvar terr *transport.Error\n\t\t\tif errors.As(err, &terr) {\n\t\t\t\tif terr.StatusCode != http.StatusNotFound && terr.StatusCode != http.StatusForbidden {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else if err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif head != nil {\n\t\t\t\treturn fmt.Errorf(\"refusing to clobber existing tag %s@%s\", tag, head.Digest)\n\t\t\t}\n\t\t}\n\t}\n\n\tpusher, err := remote.NewPusher(o.Remote...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlogs.Progress.Printf(\"Copying from %v to %v\", srcRef, dstRef)\n\tdesc, err := puller.Get(o.ctx, srcRef)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fetching %q: %w\", src, err)\n\t}\n\n\tif o.Platform == nil {\n\t\treturn pusher.Push(o.ctx, dstRef, desc)\n\t}\n\n\t// If platform is explicitly set, don't copy the whole index, just the appropriate image.\n\timg, err := desc.Image()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn pusher.Push(o.ctx, dstRef, img)\n}\n\n// CopyRepository copies every tag from src to dst.\nfunc CopyRepository(src, dst string, opt ...Option) error {\n\to := makeOptions(opt...)\n\n\tsrcRepo, err := name.NewRepository(src, o.Name...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdstRepo, err := name.NewRepository(dst, o.Name...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference for %q: %w\", dst, err)\n\t}\n\n\tpuller, err := remote.NewPuller(o.Remote...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tignoredTags := map[string]struct{}{}\n\tif o.noclobber {\n\t\t// TODO: It would be good to propagate noclobber down into remote so we can use Etags.\n\t\thave, err := puller.List(o.ctx, dstRepo)\n\t\tif err != nil {\n\t\t\tvar terr *transport.Error\n\t\t\tif errors.As(err, &terr) {\n\t\t\t\t// Some registries create repository on first push, so listing tags will fail.\n\t\t\t\t// If we see 404 or 403, assume we failed because the repository hasn't been created yet.\n\t\t\t\tif !(terr.StatusCode == http.StatusNotFound || terr.StatusCode == http.StatusForbidden) {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tfor _, tag := range have {\n\t\t\tignoredTags[tag] = struct{}{}\n\t\t}\n\t}\n\n\tpusher, err := remote.NewPusher(o.Remote...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tlister, err := puller.Lister(o.ctx, srcRepo)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tg, ctx := errgroup.WithContext(o.ctx)\n\tg.SetLimit(o.jobs)\n\n\tfor lister.HasNext() {\n\t\ttags, err := lister.Next(ctx)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfor _, tag := range tags.Tags {\n\t\t\ttag := tag\n\n\t\t\tif o.noclobber {\n\t\t\t\tif _, ok := ignoredTags[tag]; ok {\n\t\t\t\t\tlogs.Progress.Printf(\"Skipping %s due to no-clobber\", tag)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tg.Go(func() error {\n\t\t\t\tsrcTag, err := name.ParseReference(src+\":\"+tag, o.Name...)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to parse tag: %w\", err)\n\t\t\t\t}\n\t\t\t\tdstTag, err := name.ParseReference(dst+\":\"+tag, o.Name...)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to parse tag: %w\", err)\n\t\t\t\t}\n\n\t\t\t\tlogs.Progress.Printf(\"Fetching %s\", srcTag)\n\t\t\t\tdesc, err := puller.Get(ctx, srcTag)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\n\t\t\t\tlogs.Progress.Printf(\"Pushing %s\", dstTag)\n\t\t\t\treturn pusher.Push(ctx, dstTag, desc)\n\t\t\t})\n\t\t}\n\t}\n\n\treturn g.Wait()\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/delete.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\n// Delete deletes the remote reference at src.\nfunc Delete(src string, opt ...Option) error {\n\to := makeOptions(opt...)\n\tref, err := name.ParseReference(src, o.Name...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference %q: %w\", src, err)\n\t}\n\n\treturn remote.Delete(ref, o.Remote...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/digest.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport \"github.com/google/go-containerregistry/pkg/logs\"\n\n// Digest returns the sha256 hash of the remote image at ref.\nfunc Digest(ref string, opt ...Option) (string, error) {\n\to := makeOptions(opt...)\n\tif o.Platform != nil {\n\t\tdesc, err := getManifest(ref, opt...)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tif !desc.MediaType.IsIndex() {\n\t\t\treturn desc.Digest.String(), nil\n\t\t}\n\n\t\t// TODO: does not work for indexes which contain schema v1 manifests\n\t\timg, err := desc.Image()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tdigest, err := img.Digest()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn digest.String(), nil\n\t}\n\tdesc, err := Head(ref, opt...)\n\tif err != nil {\n\t\tlogs.Warn.Printf(\"HEAD request failed, falling back on GET: %v\", err)\n\t\trdesc, err := getManifest(ref, opt...)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn rdesc.Digest.String(), nil\n\t}\n\treturn desc.Digest.String(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/doc.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\n// Package crane holds libraries used to implement the crane CLI.\npackage crane\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/export.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"io\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/mutate\"\n)\n\n// Export writes the filesystem contents (as a tarball) of img to w.\n// If img has a single layer, just write the (uncompressed) contents to w so\n// that this \"just works\" for images that just wrap a single blob.\nfunc Export(img v1.Image, w io.Writer) error {\n\tlayers, err := img.Layers()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(layers) == 1 {\n\t\t// If it's a single layer...\n\t\tl := layers[0]\n\t\tmt, err := l.MediaType()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif !mt.IsLayer() {\n\t\t\t// ...and isn't an OCI mediaType, we don't have to flatten it.\n\t\t\t// This lets export work for single layer, non-tarball images.\n\t\t\trc, err := l.Uncompressed()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t_, err = io.Copy(w, rc)\n\t\t\treturn err\n\t\t}\n\t}\n\tfs := mutate.Extract(img)\n\t_, err = io.Copy(w, fs)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/filemap.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"io\"\n\t\"sort\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/empty\"\n\t\"github.com/google/go-containerregistry/pkg/v1/mutate\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n)\n\n// Layer creates a layer from a single file map. These layers are reproducible and consistent.\n// A filemap is a path -> file content map representing a file system.\nfunc Layer(filemap map[string][]byte) (v1.Layer, error) {\n\tb := &bytes.Buffer{}\n\tw := tar.NewWriter(b)\n\n\tfn := []string{}\n\tfor f := range filemap {\n\t\tfn = append(fn, f)\n\t}\n\tsort.Strings(fn)\n\n\tfor _, f := range fn {\n\t\tc := filemap[f]\n\t\tif err := w.WriteHeader(&tar.Header{\n\t\t\tName: f,\n\t\t\tSize: int64(len(c)),\n\t\t}); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif _, err := w.Write(c); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif err := w.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Return a new copy of the buffer each time it's opened.\n\treturn tarball.LayerFromOpener(func() (io.ReadCloser, error) {\n\t\treturn io.NopCloser(bytes.NewBuffer(b.Bytes())), nil\n\t})\n}\n\n// Image creates a image with the given filemaps as its contents. These images are reproducible and consistent.\n// A filemap is a path -> file content map representing a file system.\nfunc Image(filemap map[string][]byte) (v1.Image, error) {\n\ty, err := Layer(filemap)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn mutate.AppendLayers(empty.Image, y)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/get.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\nfunc getImage(r string, opt ...Option) (v1.Image, name.Reference, error) {\n\to := makeOptions(opt...)\n\tref, err := name.ParseReference(r, o.Name...)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"parsing reference %q: %w\", r, err)\n\t}\n\timg, err := remote.Image(ref, o.Remote...)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"reading image %q: %w\", ref, err)\n\t}\n\treturn img, ref, nil\n}\n\nfunc getManifest(r string, opt ...Option) (*remote.Descriptor, error) {\n\to := makeOptions(opt...)\n\tref, err := name.ParseReference(r, o.Name...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing reference %q: %w\", r, err)\n\t}\n\treturn remote.Get(ref, o.Remote...)\n}\n\n// Get calls remote.Get and returns an uninterpreted response.\nfunc Get(r string, opt ...Option) (*remote.Descriptor, error) {\n\treturn getManifest(r, opt...)\n}\n\n// Head performs a HEAD request for a manifest and returns a content descriptor\n// based on the registry's response.\nfunc Head(r string, opt ...Option) (*v1.Descriptor, error) {\n\to := makeOptions(opt...)\n\tref, err := name.ParseReference(r, o.Name...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn remote.Head(ref, o.Remote...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/list.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\n// ListTags returns the tags in repository src.\nfunc ListTags(src string, opt ...Option) ([]string, error) {\n\to := makeOptions(opt...)\n\trepo, err := name.NewRepository(src, o.Name...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing repo %q: %w\", src, err)\n\t}\n\n\treturn remote.List(repo, o.Remote...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/manifest.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\n// Manifest returns the manifest for the remote image or index ref.\nfunc Manifest(ref string, opt ...Option) ([]byte, error) {\n\tdesc, err := getManifest(ref, opt...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\to := makeOptions(opt...)\n\tif o.Platform != nil {\n\t\timg, err := desc.Image()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn img.RawManifest()\n\t}\n\treturn desc.Manifest, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/options.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"net/http\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\n// Options hold the options that crane uses when calling other packages.\ntype Options struct {\n\tName      []name.Option\n\tRemote    []remote.Option\n\tPlatform  *v1.Platform\n\tKeychain  authn.Keychain\n\tTransport http.RoundTripper\n\n\tauth      authn.Authenticator\n\tinsecure  bool\n\tjobs      int\n\tnoclobber bool\n\tctx       context.Context\n}\n\n// GetOptions exposes the underlying []remote.Option, []name.Option, and\n// platform, based on the passed Option. Generally, you shouldn't need to use\n// this unless you've painted yourself into a dependency corner as we have\n// with the crane and gcrane cli packages.\nfunc GetOptions(opts ...Option) Options {\n\treturn makeOptions(opts...)\n}\n\nfunc makeOptions(opts ...Option) Options {\n\topt := Options{\n\t\tRemote: []remote.Option{\n\t\t\tremote.WithAuthFromKeychain(authn.DefaultKeychain),\n\t\t},\n\t\tKeychain: authn.DefaultKeychain,\n\t\tjobs:     4,\n\t\tctx:      context.Background(),\n\t}\n\n\tfor _, o := range opts {\n\t\to(&opt)\n\t}\n\n\t// Allow for untrusted certificates if the user\n\t// passed Insecure but no custom transport.\n\tif opt.insecure && opt.Transport == nil {\n\t\ttransport := remote.DefaultTransport.(*http.Transport).Clone()\n\t\ttransport.TLSClientConfig = &tls.Config{\n\t\t\tInsecureSkipVerify: true, //nolint: gosec\n\t\t}\n\n\t\tWithTransport(transport)(&opt)\n\t} else if opt.Transport == nil {\n\t\topt.Transport = remote.DefaultTransport\n\t}\n\n\treturn opt\n}\n\n// Option is a functional option for crane.\ntype Option func(*Options)\n\n// WithTransport is a functional option for overriding the default transport\n// for remote operations. Setting a transport will override the Insecure option's\n// configuration allowing for image registries to use untrusted certificates.\nfunc WithTransport(t http.RoundTripper) Option {\n\treturn func(o *Options) {\n\t\to.Remote = append(o.Remote, remote.WithTransport(t))\n\t\to.Transport = t\n\t}\n}\n\n// Insecure is an Option that allows image references to be fetched without TLS.\n// This will also allow for untrusted (e.g. self-signed) certificates in cases where\n// the default transport is used (i.e. when WithTransport is not used).\nfunc Insecure(o *Options) {\n\to.Name = append(o.Name, name.Insecure)\n\to.insecure = true\n}\n\n// WithPlatform is an Option to specify the platform.\nfunc WithPlatform(platform *v1.Platform) Option {\n\treturn func(o *Options) {\n\t\tif platform != nil {\n\t\t\to.Remote = append(o.Remote, remote.WithPlatform(*platform))\n\t\t}\n\t\to.Platform = platform\n\t}\n}\n\n// WithAuthFromKeychain is a functional option for overriding the default\n// authenticator for remote operations, using an authn.Keychain to find\n// credentials.\n//\n// By default, crane will use authn.DefaultKeychain.\nfunc WithAuthFromKeychain(keys authn.Keychain) Option {\n\treturn func(o *Options) {\n\t\t// Replace the default keychain at position 0.\n\t\to.Remote[0] = remote.WithAuthFromKeychain(keys)\n\t\to.Keychain = keys\n\t}\n}\n\n// WithAuth is a functional option for overriding the default authenticator\n// for remote operations.\n//\n// By default, crane will use authn.DefaultKeychain.\nfunc WithAuth(auth authn.Authenticator) Option {\n\treturn func(o *Options) {\n\t\t// Replace the default keychain at position 0.\n\t\to.Remote[0] = remote.WithAuth(auth)\n\t\to.auth = auth\n\t}\n}\n\n// WithUserAgent adds the given string to the User-Agent header for any HTTP\n// requests.\nfunc WithUserAgent(ua string) Option {\n\treturn func(o *Options) {\n\t\to.Remote = append(o.Remote, remote.WithUserAgent(ua))\n\t}\n}\n\n// WithNondistributable is an option that allows pushing non-distributable\n// layers.\nfunc WithNondistributable() Option {\n\treturn func(o *Options) {\n\t\to.Remote = append(o.Remote, remote.WithNondistributable)\n\t}\n}\n\n// WithContext is a functional option for setting the context.\nfunc WithContext(ctx context.Context) Option {\n\treturn func(o *Options) {\n\t\to.ctx = ctx\n\t\to.Remote = append(o.Remote, remote.WithContext(ctx))\n\t}\n}\n\n// WithJobs sets the number of concurrent jobs to run.\n//\n// The default number of jobs is GOMAXPROCS.\nfunc WithJobs(jobs int) Option {\n\treturn func(o *Options) {\n\t\tif jobs > 0 {\n\t\t\to.jobs = jobs\n\t\t}\n\t\to.Remote = append(o.Remote, remote.WithJobs(o.jobs))\n\t}\n}\n\n// WithNoClobber modifies behavior to avoid overwriting existing tags, if possible.\nfunc WithNoClobber(noclobber bool) Option {\n\treturn func(o *Options) {\n\t\to.noclobber = noclobber\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/pull.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tlegacy \"github.com/google/go-containerregistry/pkg/legacy/tarball\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/empty\"\n\t\"github.com/google/go-containerregistry/pkg/v1/layout\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n)\n\n// Tag applied to images that were pulled by digest. This denotes that the\n// image was (probably) never tagged with this, but lets us avoid applying the\n// \":latest\" tag which might be misleading.\nconst iWasADigestTag = \"i-was-a-digest\"\n\n// Pull returns a v1.Image of the remote image src.\nfunc Pull(src string, opt ...Option) (v1.Image, error) {\n\to := makeOptions(opt...)\n\tref, err := name.ParseReference(src, o.Name...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing reference %q: %w\", src, err)\n\t}\n\n\treturn remote.Image(ref, o.Remote...)\n}\n\n// Save writes the v1.Image img as a tarball at path with tag src.\nfunc Save(img v1.Image, src, path string) error {\n\timgMap := map[string]v1.Image{src: img}\n\treturn MultiSave(imgMap, path)\n}\n\n// MultiSave writes collection of v1.Image img with tag as a tarball.\nfunc MultiSave(imgMap map[string]v1.Image, path string, opt ...Option) error {\n\to := makeOptions(opt...)\n\ttagToImage := map[name.Tag]v1.Image{}\n\n\tfor src, img := range imgMap {\n\t\tref, err := name.ParseReference(src, o.Name...)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"parsing ref %q: %w\", src, err)\n\t\t}\n\n\t\t// WriteToFile wants a tag to write to the tarball, but we might have\n\t\t// been given a digest.\n\t\t// If the original ref was a tag, use that. Otherwise, if it was a\n\t\t// digest, tag the image with :i-was-a-digest instead.\n\t\ttag, ok := ref.(name.Tag)\n\t\tif !ok {\n\t\t\td, ok := ref.(name.Digest)\n\t\t\tif !ok {\n\t\t\t\treturn fmt.Errorf(\"ref wasn't a tag or digest\")\n\t\t\t}\n\t\t\ttag = d.Repository.Tag(iWasADigestTag)\n\t\t}\n\t\ttagToImage[tag] = img\n\t}\n\t// no progress channel (for now)\n\treturn tarball.MultiWriteToFile(path, tagToImage)\n}\n\n// PullLayer returns the given layer from a registry.\nfunc PullLayer(ref string, opt ...Option) (v1.Layer, error) {\n\to := makeOptions(opt...)\n\tdigest, err := name.NewDigest(ref, o.Name...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn remote.Layer(digest, o.Remote...)\n}\n\n// SaveLegacy writes the v1.Image img as a legacy tarball at path with tag src.\nfunc SaveLegacy(img v1.Image, src, path string) error {\n\timgMap := map[string]v1.Image{src: img}\n\treturn MultiSave(imgMap, path)\n}\n\n// MultiSaveLegacy writes collection of v1.Image img with tag as a legacy tarball.\nfunc MultiSaveLegacy(imgMap map[string]v1.Image, path string) error {\n\trefToImage := map[name.Reference]v1.Image{}\n\n\tfor src, img := range imgMap {\n\t\tref, err := name.ParseReference(src)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"parsing ref %q: %w\", src, err)\n\t\t}\n\t\trefToImage[ref] = img\n\t}\n\n\tw, err := os.Create(path)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer w.Close()\n\n\treturn legacy.MultiWrite(refToImage, w)\n}\n\n// SaveOCI writes the v1.Image img as an OCI Image Layout at path. If a layout\n// already exists at that path, it will add the image to the index.\nfunc SaveOCI(img v1.Image, path string) error {\n\timgMap := map[string]v1.Image{\"\": img}\n\treturn MultiSaveOCI(imgMap, path)\n}\n\n// MultiSaveOCI writes collection of v1.Image img as an OCI Image Layout at path. If a layout\n// already exists at that path, it will add the image to the index.\nfunc MultiSaveOCI(imgMap map[string]v1.Image, path string) error {\n\tp, err := layout.FromPath(path)\n\tif err != nil {\n\t\tp, err = layout.Write(path, empty.Index)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tfor _, img := range imgMap {\n\t\tif err = p.AppendImage(img); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/push.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n)\n\n// Load reads the tarball at path as a v1.Image.\nfunc Load(path string, opt ...Option) (v1.Image, error) {\n\treturn LoadTag(path, \"\", opt...)\n}\n\n// LoadTag reads a tag from the tarball at path as a v1.Image.\n// If tag is \"\", will attempt to read the tarball as a single image.\nfunc LoadTag(path, tag string, opt ...Option) (v1.Image, error) {\n\tif tag == \"\" {\n\t\treturn tarball.ImageFromPath(path, nil)\n\t}\n\n\to := makeOptions(opt...)\n\tt, err := name.NewTag(tag, o.Name...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing tag %q: %w\", tag, err)\n\t}\n\treturn tarball.ImageFromPath(path, &t)\n}\n\n// Push pushes the v1.Image img to a registry as dst.\nfunc Push(img v1.Image, dst string, opt ...Option) error {\n\to := makeOptions(opt...)\n\ttag, err := name.ParseReference(dst, o.Name...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference %q: %w\", dst, err)\n\t}\n\treturn remote.Write(tag, img, o.Remote...)\n}\n\n// Upload pushes the v1.Layer to a given repo.\nfunc Upload(layer v1.Layer, repo string, opt ...Option) error {\n\to := makeOptions(opt...)\n\tref, err := name.NewRepository(repo, o.Name...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing repo %q: %w\", repo, err)\n\t}\n\n\treturn remote.WriteLayer(ref, layer, o.Remote...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/crane/tag.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage crane\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\n// Tag adds tag to the remote img.\nfunc Tag(img, tag string, opt ...Option) error {\n\to := makeOptions(opt...)\n\tref, err := name.ParseReference(img, o.Name...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference %q: %w\", img, err)\n\t}\n\tdesc, err := remote.Get(ref, o.Remote...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fetching %q: %w\", img, err)\n\t}\n\n\tdst := ref.Context().Tag(tag)\n\n\treturn remote.Tag(dst, desc, o.Remote...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/legacy/config.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage legacy\n\nimport (\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\n// LayerConfigFile is the configuration file that holds the metadata describing\n// a v1 layer. See:\n// https://github.com/moby/moby/blob/master/image/spec/v1.md\ntype LayerConfigFile struct {\n\tv1.ConfigFile\n\n\tContainerConfig v1.Config `json:\"container_config,omitempty\"`\n\n\tID        string `json:\"id,omitempty\"`\n\tParent    string `json:\"parent,omitempty\"`\n\tThrowaway bool   `json:\"throwaway,omitempty\"`\n\tComment   string `json:\"comment,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/legacy/doc.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\n// Package legacy provides functionality to work with docker images in the v1\n// format.\n// See: https://github.com/moby/moby/blob/master/image/spec/v1.md\npackage legacy\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/legacy/tarball/README.md",
    "content": "# `legacy/tarball`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/legacy/tarball?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/legacy/tarball)\n\nThis package implements support for writing legacy tarballs, as described\n[here](https://github.com/moby/moby/blob/749d90e10f989802638ae542daf54257f3bf71f2/image/spec/v1.2.md#combined-image-json--filesystem-changeset-format).\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/legacy/tarball/doc.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\n// Package tarball provides facilities for writing v1 docker images\n// (https://github.com/moby/moby/blob/master/image/spec/v1.md) from/to a tarball\n// on-disk.\npackage tarball\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/legacy/tarball/write.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage tarball\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/pkg/legacy\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n)\n\n// repositoriesTarDescriptor represents the repositories file inside a `docker save` tarball.\ntype repositoriesTarDescriptor map[string]map[string]string\n\n// v1Layer represents a layer with metadata needed by the v1 image spec https://github.com/moby/moby/blob/master/image/spec/v1.md.\ntype v1Layer struct {\n\t// config is the layer metadata.\n\tconfig *legacy.LayerConfigFile\n\t// layer is the v1.Layer object this v1Layer represents.\n\tlayer v1.Layer\n}\n\n// json returns the raw bytes of the json metadata of the given v1Layer.\nfunc (l *v1Layer) json() ([]byte, error) {\n\treturn json.Marshal(l.config)\n}\n\n// version returns the raw bytes of the \"VERSION\" file of the given v1Layer.\nfunc (l *v1Layer) version() []byte {\n\treturn []byte(\"1.0\")\n}\n\n// v1LayerID computes the v1 image format layer id for the given v1.Layer with the given v1 parent ID and raw image config.\nfunc v1LayerID(layer v1.Layer, parentID string, rawConfig []byte) (string, error) {\n\td, err := layer.Digest()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to get layer digest to generate v1 layer ID: %w\", err)\n\t}\n\ts := fmt.Sprintf(\"%s %s\", d.Hex, parentID)\n\tif len(rawConfig) != 0 {\n\t\ts = fmt.Sprintf(\"%s %s\", s, string(rawConfig))\n\t}\n\n\th, _, _ := v1.SHA256(strings.NewReader(s))\n\treturn h.Hex, nil\n}\n\n// newTopV1Layer creates a new v1Layer for a layer other than the top layer in a v1 image tarball.\nfunc newV1Layer(layer v1.Layer, parent *v1Layer, history v1.History) (*v1Layer, error) {\n\tparentID := \"\"\n\tif parent != nil {\n\t\tparentID = parent.config.ID\n\t}\n\tid, err := v1LayerID(layer, parentID, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to generate v1 layer ID: %w\", err)\n\t}\n\tresult := &v1Layer{\n\t\tlayer: layer,\n\t\tconfig: &legacy.LayerConfigFile{\n\t\t\tConfigFile: v1.ConfigFile{\n\t\t\t\tCreated: history.Created,\n\t\t\t\tAuthor:  history.Author,\n\t\t\t},\n\t\t\tContainerConfig: v1.Config{\n\t\t\t\tCmd: []string{history.CreatedBy},\n\t\t\t},\n\t\t\tID:        id,\n\t\t\tParent:    parentID,\n\t\t\tThrowaway: history.EmptyLayer,\n\t\t\tComment:   history.Comment,\n\t\t},\n\t}\n\treturn result, nil\n}\n\n// newTopV1Layer creates a new v1Layer for the top layer in a v1 image tarball.\nfunc newTopV1Layer(layer v1.Layer, parent *v1Layer, history v1.History, imgConfig *v1.ConfigFile, rawConfig []byte) (*v1Layer, error) {\n\tresult, err := newV1Layer(layer, parent, history)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tid, err := v1LayerID(layer, result.config.Parent, rawConfig)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to generate v1 layer ID for top layer: %w\", err)\n\t}\n\tresult.config.ID = id\n\tresult.config.Architecture = imgConfig.Architecture\n\tresult.config.Container = imgConfig.Container\n\tresult.config.DockerVersion = imgConfig.DockerVersion\n\tresult.config.OS = imgConfig.OS\n\tresult.config.Config = imgConfig.Config\n\tresult.config.Created = imgConfig.Created\n\treturn result, nil\n}\n\n// splitTag splits the given tagged image name <registry>/<repository>:<tag>\n// into <registry>/<repository> and <tag>.\nfunc splitTag(name string) (string, string) {\n\t// Split on \":\"\n\tparts := strings.Split(name, \":\")\n\t// Verify that we aren't confusing a tag for a hostname w/ port for the purposes of weak validation.\n\tif len(parts) > 1 && !strings.Contains(parts[len(parts)-1], \"/\") {\n\t\tbase := strings.Join(parts[:len(parts)-1], \":\")\n\t\ttag := parts[len(parts)-1]\n\t\treturn base, tag\n\t}\n\treturn name, \"\"\n}\n\n// addTags adds the given image tags to the given \"repositories\" file descriptor in a v1 image tarball.\nfunc addTags(repos repositoriesTarDescriptor, tags []string, topLayerID string) {\n\tfor _, t := range tags {\n\t\tbase, tag := splitTag(t)\n\t\ttagToID, ok := repos[base]\n\t\tif !ok {\n\t\t\ttagToID = make(map[string]string)\n\t\t\trepos[base] = tagToID\n\t\t}\n\t\ttagToID[tag] = topLayerID\n\t}\n}\n\n// updateLayerSources updates the given layer digest to descriptor map with the descriptor of the given layer in the given image if it's an undistributable layer.\nfunc updateLayerSources(layerSources map[v1.Hash]v1.Descriptor, layer v1.Layer, img v1.Image) error {\n\td, err := layer.Digest()\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Add to LayerSources if it's a foreign layer.\n\tdesc, err := partial.BlobDescriptor(img, d)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !desc.MediaType.IsDistributable() {\n\t\tdiffid, err := partial.BlobToDiffID(img, d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlayerSources[diffid] = *desc\n\t}\n\treturn nil\n}\n\n// Write is a wrapper to write a single image in V1 format and tag to a tarball.\nfunc Write(ref name.Reference, img v1.Image, w io.Writer) error {\n\treturn MultiWrite(map[name.Reference]v1.Image{ref: img}, w)\n}\n\n// filterEmpty filters out the history corresponding to empty layers from the\n// given history.\nfunc filterEmpty(h []v1.History) []v1.History {\n\tresult := []v1.History{}\n\tfor _, i := range h {\n\t\tif i.EmptyLayer {\n\t\t\tcontinue\n\t\t}\n\t\tresult = append(result, i)\n\t}\n\treturn result\n}\n\n// MultiWrite writes the contents of each image to the provided reader, in the V1 image tarball format.\n// The contents are written in the following format:\n// One manifest.json file at the top level containing information about several images.\n// One repositories file mapping from the image <registry>/<repo name> to <tag> to the id of the top most layer.\n// For every layer, a directory named with the layer ID is created with the following contents:\n//\n//\tlayer.tar - The uncompressed layer tarball.\n//\t<layer id>.json- Layer metadata json.\n//\tVERSION- Schema version string. Always set to \"1.0\".\n//\n// One file for the config blob, named after its SHA.\nfunc MultiWrite(refToImage map[name.Reference]v1.Image, w io.Writer) error {\n\ttf := tar.NewWriter(w)\n\tdefer tf.Close()\n\n\tsortedImages, imageToTags := dedupRefToImage(refToImage)\n\tvar m tarball.Manifest\n\trepos := make(repositoriesTarDescriptor)\n\n\tseenLayerIDs := make(map[string]struct{})\n\tfor _, img := range sortedImages {\n\t\ttags := imageToTags[img]\n\n\t\t// Write the config.\n\t\tcfgName, err := img.ConfigName()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcfgFileName := fmt.Sprintf(\"%s.json\", cfgName.Hex)\n\t\tcfgBlob, err := img.RawConfigFile()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := writeTarEntry(tf, cfgFileName, bytes.NewReader(cfgBlob), int64(len(cfgBlob))); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcfg, err := img.ConfigFile()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Store foreign layer info.\n\t\tlayerSources := make(map[v1.Hash]v1.Descriptor)\n\n\t\t// Write the layers.\n\t\tlayers, err := img.Layers()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\thistory := filterEmpty(cfg.History)\n\t\t// Create a blank config history if the config didn't have a history.\n\t\tif len(history) == 0 && len(layers) != 0 {\n\t\t\thistory = make([]v1.History, len(layers))\n\t\t} else if len(layers) != len(history) {\n\t\t\treturn fmt.Errorf(\"image config had layer history which did not match the number of layers, got len(history)=%d, len(layers)=%d, want len(history)=len(layers)\", len(history), len(layers))\n\t\t}\n\t\tlayerFiles := make([]string, len(layers))\n\t\tvar prev *v1Layer\n\t\tfor i, l := range layers {\n\t\t\tif err := updateLayerSources(layerSources, l, img); err != nil {\n\t\t\t\treturn fmt.Errorf(\"unable to update image metadata to include undistributable layer source information: %w\", err)\n\t\t\t}\n\t\t\tvar cur *v1Layer\n\t\t\tif i < (len(layers) - 1) {\n\t\t\t\tcur, err = newV1Layer(l, prev, history[i])\n\t\t\t} else {\n\t\t\t\tcur, err = newTopV1Layer(l, prev, history[i], cfg, cfgBlob)\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tlayerFiles[i] = fmt.Sprintf(\"%s/layer.tar\", cur.config.ID)\n\t\t\tif _, ok := seenLayerIDs[cur.config.ID]; ok {\n\t\t\t\tprev = cur\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tseenLayerIDs[cur.config.ID] = struct{}{}\n\n\t\t\t// If the v1.Layer implements UncompressedSize efficiently, use that\n\t\t\t// for the tar header. Otherwise, this iterates over Uncompressed().\n\t\t\t// NOTE: If using a streaming layer, this may consume the layer.\n\t\t\tsize, err := partial.UncompressedSize(l)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tu, err := l.Uncompressed()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdefer u.Close()\n\t\t\tif err := writeTarEntry(tf, layerFiles[i], u, size); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tj, err := cur.json()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := writeTarEntry(tf, fmt.Sprintf(\"%s/json\", cur.config.ID), bytes.NewReader(j), int64(len(j))); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tv := cur.version()\n\t\t\tif err := writeTarEntry(tf, fmt.Sprintf(\"%s/VERSION\", cur.config.ID), bytes.NewReader(v), int64(len(v))); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tprev = cur\n\t\t}\n\n\t\t// Generate the tar descriptor and write it.\n\t\tm = append(m, tarball.Descriptor{\n\t\t\tConfig:       cfgFileName,\n\t\t\tRepoTags:     tags,\n\t\t\tLayers:       layerFiles,\n\t\t\tLayerSources: layerSources,\n\t\t})\n\t\t// prev should be the top layer here. Use it to add the image tags\n\t\t// to the tarball repositories file.\n\t\taddTags(repos, tags, prev.config.ID)\n\t}\n\n\tmBytes, err := json.Marshal(m)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := writeTarEntry(tf, \"manifest.json\", bytes.NewReader(mBytes), int64(len(mBytes))); err != nil {\n\t\treturn err\n\t}\n\treposBytes, err := json.Marshal(&repos)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn writeTarEntry(tf, \"repositories\", bytes.NewReader(reposBytes), int64(len(reposBytes)))\n}\n\nfunc dedupRefToImage(refToImage map[name.Reference]v1.Image) ([]v1.Image, map[v1.Image][]string) {\n\timageToTags := make(map[v1.Image][]string)\n\n\tfor ref, img := range refToImage {\n\t\tif tag, ok := ref.(name.Tag); ok {\n\t\t\tif tags, ok := imageToTags[img]; ok && tags != nil {\n\t\t\t\timageToTags[img] = append(tags, tag.String())\n\t\t\t} else {\n\t\t\t\timageToTags[img] = []string{tag.String()}\n\t\t\t}\n\t\t} else {\n\t\t\tif _, ok := imageToTags[img]; !ok {\n\t\t\t\timageToTags[img] = nil\n\t\t\t}\n\t\t}\n\t}\n\n\t// Force specific order on tags\n\timgs := []v1.Image{}\n\tfor img, tags := range imageToTags {\n\t\tsort.Strings(tags)\n\t\timgs = append(imgs, img)\n\t}\n\n\tsort.Slice(imgs, func(i, j int) bool {\n\t\tcfI, err := imgs[i].ConfigName()\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\tcfJ, err := imgs[j].ConfigName()\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\treturn cfI.Hex < cfJ.Hex\n\t})\n\n\treturn imgs, imageToTags\n}\n\n// Writes a file to the provided writer with a corresponding tar header\nfunc writeTarEntry(tf *tar.Writer, path string, r io.Reader, size int64) error {\n\thdr := &tar.Header{\n\t\tMode:     0644,\n\t\tTypeflag: tar.TypeReg,\n\t\tSize:     size,\n\t\tName:     path,\n\t}\n\tif err := tf.WriteHeader(hdr); err != nil {\n\t\treturn err\n\t}\n\t_, err := io.Copy(tf, r)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/logs/logs.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package logs exposes the loggers used by this library.\npackage logs\n\nimport (\n\t\"io\"\n\t\"log\"\n)\n\nvar (\n\t// Warn is used to log non-fatal errors.\n\tWarn = log.New(io.Discard, \"\", log.LstdFlags)\n\n\t// Progress is used to log notable, successful events.\n\tProgress = log.New(io.Discard, \"\", log.LstdFlags)\n\n\t// Debug is used to log information that is useful for debugging.\n\tDebug = log.New(io.Discard, \"\", log.LstdFlags)\n)\n\n// Enabled checks to see if the logger's writer is set to something other\n// than io.Discard. This allows callers to avoid expensive operations\n// that will end up in /dev/null anyway.\nfunc Enabled(l *log.Logger) bool {\n\treturn l.Writer() != io.Discard\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/README.md",
    "content": "# `name`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/name?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/name)\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/check.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// stripRunesFn returns a function which returns -1 (i.e. a value which\n// signals deletion in strings.Map) for runes in 'runes', and the rune otherwise.\nfunc stripRunesFn(runes string) func(rune) rune {\n\treturn func(r rune) rune {\n\t\tif strings.ContainsRune(runes, r) {\n\t\t\treturn -1\n\t\t}\n\t\treturn r\n\t}\n}\n\n// checkElement checks a given named element matches character and length restrictions.\n// Returns true if the given element adheres to the given restrictions, false otherwise.\nfunc checkElement(name, element, allowedRunes string, minRunes, maxRunes int) error {\n\tnumRunes := utf8.RuneCountInString(element)\n\tif (numRunes < minRunes) || (maxRunes < numRunes) {\n\t\treturn newErrBadName(\"%s must be between %d and %d characters in length: %s\", name, minRunes, maxRunes, element)\n\t} else if len(strings.Map(stripRunesFn(allowedRunes), element)) != 0 {\n\t\treturn newErrBadName(\"%s can only contain the characters `%s`: %s\", name, allowedRunes, element)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/digest.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nimport (\n\t// nolint: depguard\n\t_ \"crypto/sha256\" // Recommended by go-digest.\n\t\"strings\"\n\n\t\"github.com/opencontainers/go-digest\"\n)\n\nconst digestDelim = \"@\"\n\n// Digest stores a digest name in a structured form.\ntype Digest struct {\n\tRepository\n\tdigest   string\n\toriginal string\n}\n\n// Ensure Digest implements Reference\nvar _ Reference = (*Digest)(nil)\n\n// Context implements Reference.\nfunc (d Digest) Context() Repository {\n\treturn d.Repository\n}\n\n// Identifier implements Reference.\nfunc (d Digest) Identifier() string {\n\treturn d.DigestStr()\n}\n\n// DigestStr returns the digest component of the Digest.\nfunc (d Digest) DigestStr() string {\n\treturn d.digest\n}\n\n// Name returns the name from which the Digest was derived.\nfunc (d Digest) Name() string {\n\treturn d.Repository.Name() + digestDelim + d.DigestStr()\n}\n\n// String returns the original input string.\nfunc (d Digest) String() string {\n\treturn d.original\n}\n\n// NewDigest returns a new Digest representing the given name.\nfunc NewDigest(name string, opts ...Option) (Digest, error) {\n\t// Split on \"@\"\n\tparts := strings.Split(name, digestDelim)\n\tif len(parts) != 2 {\n\t\treturn Digest{}, newErrBadName(\"a digest must contain exactly one '@' separator (e.g. registry/repository@digest) saw: %s\", name)\n\t}\n\tbase := parts[0]\n\tdig := parts[1]\n\tprefix := digest.Canonical.String() + \":\"\n\tif !strings.HasPrefix(dig, prefix) {\n\t\treturn Digest{}, newErrBadName(\"unsupported digest algorithm: %s\", dig)\n\t}\n\thex := strings.TrimPrefix(dig, prefix)\n\tif err := digest.Canonical.Validate(hex); err != nil {\n\t\treturn Digest{}, err\n\t}\n\n\ttag, err := NewTag(base, opts...)\n\tif err == nil {\n\t\tbase = tag.Repository.Name()\n\t}\n\n\trepo, err := NewRepository(base, opts...)\n\tif err != nil {\n\t\treturn Digest{}, err\n\t}\n\treturn Digest{\n\t\tRepository: repo,\n\t\tdigest:     dig,\n\t\toriginal:   name,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package name defines structured types for representing image references.\n//\n// What's in a name? For image references, not nearly enough!\n//\n// Image references look a lot like URLs, but they differ in that they don't\n// contain the scheme (http or https), they can end with a :tag or a @digest\n// (the latter being validated), and they perform defaulting for missing\n// components.\n//\n// Since image references don't contain the scheme, we do our best to infer\n// if we use http or https from the given hostname. We allow http fallback for\n// any host that looks like localhost (localhost, 127.0.0.1, ::1), ends in\n// \".local\", or is in the \"private\" address space per RFC 1918. For everything\n// else, we assume https only. To override this heuristic, use the Insecure\n// option.\n//\n// Image references with a digest signal to us that we should verify the content\n// of the image matches the digest. E.g. when pulling a Digest reference, we'll\n// calculate the sha256 of the manifest returned by the registry and error out\n// if it doesn't match what we asked for.\n//\n// For defaulting, we interpret \"ubuntu\" as\n// \"index.docker.io/library/ubuntu:latest\" because we add the missing repo\n// \"library\", the missing registry \"index.docker.io\", and the missing tag\n// \"latest\". To disable this defaulting, use the StrictValidation option. This\n// is useful e.g. to only allow image references that explicitly set a tag or\n// digest, so that you don't accidentally pull \"latest\".\npackage name\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/errors.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// ErrBadName is an error for when a bad docker name is supplied.\ntype ErrBadName struct {\n\tinfo string\n}\n\nfunc (e *ErrBadName) Error() string {\n\treturn e.info\n}\n\n// Is reports whether target is an error of type ErrBadName\nfunc (e *ErrBadName) Is(target error) bool {\n\tvar berr *ErrBadName\n\treturn errors.As(target, &berr)\n}\n\n// newErrBadName returns a ErrBadName which returns the given formatted string from Error().\nfunc newErrBadName(fmtStr string, args ...any) *ErrBadName {\n\treturn &ErrBadName{fmt.Sprintf(fmtStr, args...)}\n}\n\n// IsErrBadName returns true if the given error is an ErrBadName.\n//\n// Deprecated: Use errors.Is.\nfunc IsErrBadName(err error) bool {\n\tvar berr *ErrBadName\n\treturn errors.As(err, &berr)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/options.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nconst (\n\t// DefaultRegistry is the registry name that will be used if no registry\n\t// provided and the default is not overridden.\n\tDefaultRegistry      = \"index.docker.io\"\n\tdefaultRegistryAlias = \"docker.io\"\n\n\t// DefaultTag is the tag name that will be used if no tag provided and the\n\t// default is not overridden.\n\tDefaultTag = \"latest\"\n)\n\ntype options struct {\n\tstrict          bool // weak by default\n\tinsecure        bool // secure by default\n\tdefaultRegistry string\n\tdefaultTag      string\n}\n\nfunc makeOptions(opts ...Option) options {\n\topt := options{\n\t\tdefaultRegistry: DefaultRegistry,\n\t\tdefaultTag:      DefaultTag,\n\t}\n\tfor _, o := range opts {\n\t\to(&opt)\n\t}\n\treturn opt\n}\n\n// Option is a functional option for name parsing.\ntype Option func(*options)\n\n// StrictValidation is an Option that requires image references to be fully\n// specified; i.e. no defaulting for registry (dockerhub), repo (library),\n// or tag (latest).\nfunc StrictValidation(opts *options) {\n\topts.strict = true\n}\n\n// WeakValidation is an Option that sets defaults when parsing names, see\n// StrictValidation.\nfunc WeakValidation(opts *options) {\n\topts.strict = false\n}\n\n// Insecure is an Option that allows image references to be fetched without TLS.\nfunc Insecure(opts *options) {\n\topts.insecure = true\n}\n\n// OptionFn is a function that returns an option.\ntype OptionFn func() Option\n\n// WithDefaultRegistry sets the default registry that will be used if one is not\n// provided.\nfunc WithDefaultRegistry(r string) Option {\n\treturn func(opts *options) {\n\t\topts.defaultRegistry = r\n\t}\n}\n\n// WithDefaultTag sets the default tag that will be used if one is not provided.\nfunc WithDefaultTag(t string) Option {\n\treturn func(opts *options) {\n\t\topts.defaultTag = t\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/ref.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nimport (\n\t\"fmt\"\n)\n\n// Reference defines the interface that consumers use when they can\n// take either a tag or a digest.\ntype Reference interface {\n\tfmt.Stringer\n\n\t// Context accesses the Repository context of the reference.\n\tContext() Repository\n\n\t// Identifier accesses the type-specific portion of the reference.\n\tIdentifier() string\n\n\t// Name is the fully-qualified reference name.\n\tName() string\n\n\t// Scope is the scope needed to access this reference.\n\tScope(string) string\n}\n\n// ParseReference parses the string as a reference, either by tag or digest.\nfunc ParseReference(s string, opts ...Option) (Reference, error) {\n\tif t, err := NewTag(s, opts...); err == nil {\n\t\treturn t, nil\n\t}\n\tif d, err := NewDigest(s, opts...); err == nil {\n\t\treturn d, nil\n\t}\n\treturn nil, newErrBadName(\"could not parse reference: \" + s)\n}\n\ntype stringConst string\n\n// MustParseReference behaves like ParseReference, but panics instead of\n// returning an error. It's intended for use in tests, or when a value is\n// expected to be valid at code authoring time.\n//\n// To discourage its use in scenarios where the value is not known at code\n// authoring time, it must be passed a string constant:\n//\n//\tconst str = \"valid/string\"\n//\tMustParseReference(str)\n//\tMustParseReference(\"another/valid/string\")\n//\tMustParseReference(str + \"/and/more\")\n//\n// These will not compile:\n//\n//\tvar str = \"valid/string\"\n//\tMustParseReference(str)\n//\tMustParseReference(strings.Join([]string{\"valid\", \"string\"}, \"/\"))\nfunc MustParseReference(s stringConst, opts ...Option) Reference {\n\tref, err := ParseReference(string(s), opts...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn ref\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/registry.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nimport (\n\t\"net\"\n\t\"net/url\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// Detect more complex forms of local references.\nvar reLocal = regexp.MustCompile(`.*\\.local(?:host)?(?::\\d{1,5})?$`)\n\n// Detect the loopback IP (127.0.0.1)\nvar reLoopback = regexp.MustCompile(regexp.QuoteMeta(\"127.0.0.1\"))\n\n// Detect the loopback IPV6 (::1)\nvar reipv6Loopback = regexp.MustCompile(regexp.QuoteMeta(\"::1\"))\n\n// Registry stores a docker registry name in a structured form.\ntype Registry struct {\n\tinsecure bool\n\tregistry string\n}\n\n// RegistryStr returns the registry component of the Registry.\nfunc (r Registry) RegistryStr() string {\n\treturn r.registry\n}\n\n// Name returns the name from which the Registry was derived.\nfunc (r Registry) Name() string {\n\treturn r.RegistryStr()\n}\n\nfunc (r Registry) String() string {\n\treturn r.Name()\n}\n\n// Repo returns a Repository in the Registry with the given name.\nfunc (r Registry) Repo(repo ...string) Repository {\n\treturn Repository{Registry: r, repository: path.Join(repo...)}\n}\n\n// Scope returns the scope required to access the registry.\nfunc (r Registry) Scope(string) string {\n\t// The only resource under 'registry' is 'catalog'. http://goo.gl/N9cN9Z\n\treturn \"registry:catalog:*\"\n}\n\nfunc (r Registry) isRFC1918() bool {\n\tipStr := strings.Split(r.Name(), \":\")[0]\n\tip := net.ParseIP(ipStr)\n\tif ip == nil {\n\t\treturn false\n\t}\n\tfor _, cidr := range []string{\"10.0.0.0/8\", \"172.16.0.0/12\", \"192.168.0.0/16\"} {\n\t\t_, block, _ := net.ParseCIDR(cidr)\n\t\tif block.Contains(ip) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Scheme returns https scheme for all the endpoints except localhost or when explicitly defined.\nfunc (r Registry) Scheme() string {\n\tif r.insecure {\n\t\treturn \"http\"\n\t}\n\tif r.isRFC1918() {\n\t\treturn \"http\"\n\t}\n\tif strings.HasPrefix(r.Name(), \"localhost:\") {\n\t\treturn \"http\"\n\t}\n\tif reLocal.MatchString(r.Name()) {\n\t\treturn \"http\"\n\t}\n\tif reLoopback.MatchString(r.Name()) {\n\t\treturn \"http\"\n\t}\n\tif reipv6Loopback.MatchString(r.Name()) {\n\t\treturn \"http\"\n\t}\n\treturn \"https\"\n}\n\nfunc checkRegistry(name string) error {\n\t// Per RFC 3986, registries (authorities) are required to be prefixed with \"//\"\n\t// url.Host == hostname[:port] == authority\n\tif url, err := url.Parse(\"//\" + name); err != nil || url.Host != name {\n\t\treturn newErrBadName(\"registries must be valid RFC 3986 URI authorities: %s\", name)\n\t}\n\treturn nil\n}\n\n// NewRegistry returns a Registry based on the given name.\n// Strict validation requires explicit, valid RFC 3986 URI authorities to be given.\nfunc NewRegistry(name string, opts ...Option) (Registry, error) {\n\topt := makeOptions(opts...)\n\tif opt.strict && len(name) == 0 {\n\t\treturn Registry{}, newErrBadName(\"strict validation requires the registry to be explicitly defined\")\n\t}\n\n\tif err := checkRegistry(name); err != nil {\n\t\treturn Registry{}, err\n\t}\n\n\tif name == \"\" {\n\t\tname = opt.defaultRegistry\n\t}\n\t// Rewrite \"docker.io\" to \"index.docker.io\".\n\t// See: https://github.com/google/go-containerregistry/issues/68\n\tif name == defaultRegistryAlias {\n\t\tname = DefaultRegistry\n\t}\n\n\treturn Registry{registry: name, insecure: opt.insecure}, nil\n}\n\n// NewInsecureRegistry returns an Insecure Registry based on the given name.\n//\n// Deprecated: Use the Insecure Option with NewRegistry instead.\nfunc NewInsecureRegistry(name string, opts ...Option) (Registry, error) {\n\topts = append(opts, Insecure)\n\treturn NewRegistry(name, opts...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/repository.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nconst (\n\tdefaultNamespace = \"library\"\n\trepositoryChars  = \"abcdefghijklmnopqrstuvwxyz0123456789_-./\"\n\tregRepoDelimiter = \"/\"\n)\n\n// Repository stores a docker repository name in a structured form.\ntype Repository struct {\n\tRegistry\n\trepository string\n}\n\n// See https://docs.docker.com/docker-hub/official_repos\nfunc hasImplicitNamespace(repo string, reg Registry) bool {\n\treturn !strings.ContainsRune(repo, '/') && reg.RegistryStr() == DefaultRegistry\n}\n\n// RepositoryStr returns the repository component of the Repository.\nfunc (r Repository) RepositoryStr() string {\n\tif hasImplicitNamespace(r.repository, r.Registry) {\n\t\treturn fmt.Sprintf(\"%s/%s\", defaultNamespace, r.repository)\n\t}\n\treturn r.repository\n}\n\n// Name returns the name from which the Repository was derived.\nfunc (r Repository) Name() string {\n\tregName := r.Registry.Name()\n\tif regName != \"\" {\n\t\treturn regName + regRepoDelimiter + r.RepositoryStr()\n\t}\n\t// TODO: As far as I can tell, this is unreachable.\n\treturn r.RepositoryStr()\n}\n\nfunc (r Repository) String() string {\n\treturn r.Name()\n}\n\n// Scope returns the scope required to perform the given action on the registry.\n// TODO(jonjohnsonjr): consider moving scopes to a separate package.\nfunc (r Repository) Scope(action string) string {\n\treturn fmt.Sprintf(\"repository:%s:%s\", r.RepositoryStr(), action)\n}\n\nfunc checkRepository(repository string) error {\n\treturn checkElement(\"repository\", repository, repositoryChars, 2, 255)\n}\n\n// NewRepository returns a new Repository representing the given name, according to the given strictness.\nfunc NewRepository(name string, opts ...Option) (Repository, error) {\n\topt := makeOptions(opts...)\n\tif len(name) == 0 {\n\t\treturn Repository{}, newErrBadName(\"a repository name must be specified\")\n\t}\n\n\tvar registry string\n\trepo := name\n\tparts := strings.SplitN(name, regRepoDelimiter, 2)\n\tif len(parts) == 2 && (strings.ContainsRune(parts[0], '.') || strings.ContainsRune(parts[0], ':')) {\n\t\t// The first part of the repository is treated as the registry domain\n\t\t// iff it contains a '.' or ':' character, otherwise it is all repository\n\t\t// and the domain defaults to Docker Hub.\n\t\tregistry = parts[0]\n\t\trepo = parts[1]\n\t}\n\n\tif err := checkRepository(repo); err != nil {\n\t\treturn Repository{}, err\n\t}\n\n\treg, err := NewRegistry(registry, opts...)\n\tif err != nil {\n\t\treturn Repository{}, err\n\t}\n\tif hasImplicitNamespace(repo, reg) && opt.strict {\n\t\treturn Repository{}, newErrBadName(\"strict validation requires the full repository path (missing 'library')\")\n\t}\n\treturn Repository{reg, repo}, nil\n}\n\n// Tag returns a Tag in this Repository.\nfunc (r Repository) Tag(identifier string) Tag {\n\tt := Tag{\n\t\ttag:        identifier,\n\t\tRepository: r,\n\t}\n\tt.original = t.Name()\n\treturn t\n}\n\n// Digest returns a Digest in this Repository.\nfunc (r Repository) Digest(identifier string) Digest {\n\td := Digest{\n\t\tdigest:     identifier,\n\t\tRepository: r,\n\t}\n\td.original = d.Name()\n\treturn d\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/name/tag.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage name\n\nimport (\n\t\"strings\"\n)\n\nconst (\n\t// TODO(dekkagaijin): use the docker/distribution regexes for validation.\n\ttagChars = \"abcdefghijklmnopqrstuvwxyz0123456789_-.ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\ttagDelim = \":\"\n)\n\n// Tag stores a docker tag name in a structured form.\ntype Tag struct {\n\tRepository\n\ttag      string\n\toriginal string\n}\n\n// Ensure Tag implements Reference\nvar _ Reference = (*Tag)(nil)\n\n// Context implements Reference.\nfunc (t Tag) Context() Repository {\n\treturn t.Repository\n}\n\n// Identifier implements Reference.\nfunc (t Tag) Identifier() string {\n\treturn t.TagStr()\n}\n\n// TagStr returns the tag component of the Tag.\nfunc (t Tag) TagStr() string {\n\treturn t.tag\n}\n\n// Name returns the name from which the Tag was derived.\nfunc (t Tag) Name() string {\n\treturn t.Repository.Name() + tagDelim + t.TagStr()\n}\n\n// String returns the original input string.\nfunc (t Tag) String() string {\n\treturn t.original\n}\n\n// Scope returns the scope required to perform the given action on the tag.\nfunc (t Tag) Scope(action string) string {\n\treturn t.Repository.Scope(action)\n}\n\nfunc checkTag(name string) error {\n\treturn checkElement(\"tag\", name, tagChars, 1, 128)\n}\n\n// NewTag returns a new Tag representing the given name, according to the given strictness.\nfunc NewTag(name string, opts ...Option) (Tag, error) {\n\topt := makeOptions(opts...)\n\tbase := name\n\ttag := \"\"\n\n\t// Split on \":\"\n\tparts := strings.Split(name, tagDelim)\n\t// Verify that we aren't confusing a tag for a hostname w/ port for the purposes of weak validation.\n\tif len(parts) > 1 && !strings.Contains(parts[len(parts)-1], regRepoDelimiter) {\n\t\tbase = strings.Join(parts[:len(parts)-1], tagDelim)\n\t\ttag = parts[len(parts)-1]\n\t}\n\n\t// We don't require a tag, but if we get one check it's valid,\n\t// even when not being strict.\n\t// If we are being strict, we want to validate the tag regardless in case\n\t// it's empty.\n\tif tag != \"\" || opt.strict {\n\t\tif err := checkTag(tag); err != nil {\n\t\t\treturn Tag{}, err\n\t\t}\n\t}\n\n\tif tag == \"\" {\n\t\ttag = opt.defaultTag\n\t}\n\n\trepo, err := NewRepository(base, opts...)\n\tif err != nil {\n\t\treturn Tag{}, err\n\t}\n\treturn Tag{\n\t\tRepository: repo,\n\t\ttag:        tag,\n\t\toriginal:   name,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/registry/README.md",
    "content": "# `pkg/registry`\n\nThis package implements a Docker v2 registry and the OCI distribution specification.\n\nIt is designed to be used anywhere a low dependency container registry is needed, with an initial focus on tests.\n\nIts goal is to be standards compliant and its strictness will increase over time.\n\nThis is currently a low flightmiles system. It's likely quite safe to use in tests; If you're using it in production, please let us know how and send us PRs for integration tests.\n\nBefore sending a PR, understand that the expectation of this package is that it remain free of extraneous dependencies.\nThis means that we expect `pkg/registry` to only have dependencies on Go's standard library, and other packages in `go-containerregistry`.\n\nYou may be asked to change your code to reduce dependencies, and your PR might be rejected if this is deemed impossible.\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/registry/blobs.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage registry\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"path\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/internal/verify\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\n// Returns whether this url should be handled by the blob handler\n// This is complicated because blob is indicated by the trailing path, not the leading path.\n// https://github.com/opencontainers/distribution-spec/blob/master/spec.md#pulling-a-layer\n// https://github.com/opencontainers/distribution-spec/blob/master/spec.md#pushing-a-layer\nfunc isBlob(req *http.Request) bool {\n\telem := strings.Split(req.URL.Path, \"/\")\n\telem = elem[1:]\n\tif elem[len(elem)-1] == \"\" {\n\t\telem = elem[:len(elem)-1]\n\t}\n\tif len(elem) < 3 {\n\t\treturn false\n\t}\n\treturn elem[len(elem)-2] == \"blobs\" || (elem[len(elem)-3] == \"blobs\" &&\n\t\telem[len(elem)-2] == \"uploads\")\n}\n\n// BlobHandler represents a minimal blob storage backend, capable of serving\n// blob contents.\ntype BlobHandler interface {\n\t// Get gets the blob contents, or errNotFound if the blob wasn't found.\n\tGet(ctx context.Context, repo string, h v1.Hash) (io.ReadCloser, error)\n}\n\n// BlobStatHandler is an extension interface representing a blob storage\n// backend that can serve metadata about blobs.\ntype BlobStatHandler interface {\n\t// Stat returns the size of the blob, or errNotFound if the blob wasn't\n\t// found, or redirectError if the blob can be found elsewhere.\n\tStat(ctx context.Context, repo string, h v1.Hash) (int64, error)\n}\n\n// BlobPutHandler is an extension interface representing a blob storage backend\n// that can write blob contents.\ntype BlobPutHandler interface {\n\t// Put puts the blob contents.\n\t//\n\t// The contents will be verified against the expected size and digest\n\t// as the contents are read, and an error will be returned if these\n\t// don't match. Implementations should return that error, or a wrapper\n\t// around that error, to return the correct error when these don't match.\n\tPut(ctx context.Context, repo string, h v1.Hash, rc io.ReadCloser) error\n}\n\n// BlobDeleteHandler is an extension interface representing a blob storage\n// backend that can delete blob contents.\ntype BlobDeleteHandler interface {\n\t// Delete the blob contents.\n\tDelete(ctx context.Context, repo string, h v1.Hash) error\n}\n\n// redirectError represents a signal that the blob handler doesn't have the blob\n// contents, but that those contents are at another location which registry\n// clients should redirect to.\ntype redirectError struct {\n\t// Location is the location to find the contents.\n\tLocation string\n\n\t// Code is the HTTP redirect status code to return to clients.\n\tCode int\n}\n\nfunc (e redirectError) Error() string { return fmt.Sprintf(\"redirecting (%d): %s\", e.Code, e.Location) }\n\n// errNotFound represents an error locating the blob.\nvar errNotFound = errors.New(\"not found\")\n\ntype memHandler struct {\n\tm    map[string][]byte\n\tlock sync.Mutex\n}\n\nfunc NewInMemoryBlobHandler() BlobHandler { return &memHandler{m: map[string][]byte{}} }\n\nfunc (m *memHandler) Stat(_ context.Context, _ string, h v1.Hash) (int64, error) {\n\tm.lock.Lock()\n\tdefer m.lock.Unlock()\n\n\tb, found := m.m[h.String()]\n\tif !found {\n\t\treturn 0, errNotFound\n\t}\n\treturn int64(len(b)), nil\n}\nfunc (m *memHandler) Get(_ context.Context, _ string, h v1.Hash) (io.ReadCloser, error) {\n\tm.lock.Lock()\n\tdefer m.lock.Unlock()\n\n\tb, found := m.m[h.String()]\n\tif !found {\n\t\treturn nil, errNotFound\n\t}\n\treturn io.NopCloser(bytes.NewReader(b)), nil\n}\nfunc (m *memHandler) Put(_ context.Context, _ string, h v1.Hash, rc io.ReadCloser) error {\n\tm.lock.Lock()\n\tdefer m.lock.Unlock()\n\n\tdefer rc.Close()\n\tall, err := io.ReadAll(rc)\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.m[h.String()] = all\n\treturn nil\n}\nfunc (m *memHandler) Delete(_ context.Context, _ string, h v1.Hash) error {\n\tm.lock.Lock()\n\tdefer m.lock.Unlock()\n\n\tif _, found := m.m[h.String()]; !found {\n\t\treturn errNotFound\n\t}\n\n\tdelete(m.m, h.String())\n\treturn nil\n}\n\n// blobs\ntype blobs struct {\n\tblobHandler BlobHandler\n\n\t// Each upload gets a unique id that writes occur to until finalized.\n\tuploads map[string][]byte\n\tlock    sync.Mutex\n\tlog     *log.Logger\n}\n\nfunc (b *blobs) handle(resp http.ResponseWriter, req *http.Request) *regError {\n\telem := strings.Split(req.URL.Path, \"/\")\n\telem = elem[1:]\n\tif elem[len(elem)-1] == \"\" {\n\t\telem = elem[:len(elem)-1]\n\t}\n\t// Must have a path of form /v2/{name}/blobs/{upload,sha256:}\n\tif len(elem) < 4 {\n\t\treturn &regError{\n\t\t\tStatus:  http.StatusBadRequest,\n\t\t\tCode:    \"NAME_INVALID\",\n\t\t\tMessage: \"blobs must be attached to a repo\",\n\t\t}\n\t}\n\ttarget := elem[len(elem)-1]\n\tservice := elem[len(elem)-2]\n\tdigest := req.URL.Query().Get(\"digest\")\n\tcontentRange := req.Header.Get(\"Content-Range\")\n\n\trepo := req.URL.Host + path.Join(elem[1:len(elem)-2]...)\n\n\tswitch req.Method {\n\tcase http.MethodHead:\n\t\th, err := v1.NewHash(target)\n\t\tif err != nil {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"NAME_INVALID\",\n\t\t\t\tMessage: \"invalid digest\",\n\t\t\t}\n\t\t}\n\n\t\tvar size int64\n\t\tif bsh, ok := b.blobHandler.(BlobStatHandler); ok {\n\t\t\tsize, err = bsh.Stat(req.Context(), repo, h)\n\t\t\tif errors.Is(err, errNotFound) {\n\t\t\t\treturn regErrBlobUnknown\n\t\t\t} else if err != nil {\n\t\t\t\tvar rerr redirectError\n\t\t\t\tif errors.As(err, &rerr) {\n\t\t\t\t\thttp.Redirect(resp, req, rerr.Location, rerr.Code)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\t\t} else {\n\t\t\trc, err := b.blobHandler.Get(req.Context(), repo, h)\n\t\t\tif errors.Is(err, errNotFound) {\n\t\t\t\treturn regErrBlobUnknown\n\t\t\t} else if err != nil {\n\t\t\t\tvar rerr redirectError\n\t\t\t\tif errors.As(err, &rerr) {\n\t\t\t\t\thttp.Redirect(resp, req, rerr.Location, rerr.Code)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\t\t\tdefer rc.Close()\n\t\t\tsize, err = io.Copy(io.Discard, rc)\n\t\t\tif err != nil {\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\t\t}\n\n\t\tresp.Header().Set(\"Content-Length\", fmt.Sprint(size))\n\t\tresp.Header().Set(\"Docker-Content-Digest\", h.String())\n\t\tresp.WriteHeader(http.StatusOK)\n\t\treturn nil\n\n\tcase http.MethodGet:\n\t\th, err := v1.NewHash(target)\n\t\tif err != nil {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"NAME_INVALID\",\n\t\t\t\tMessage: \"invalid digest\",\n\t\t\t}\n\t\t}\n\n\t\tvar size int64\n\t\tvar r io.Reader\n\t\tif bsh, ok := b.blobHandler.(BlobStatHandler); ok {\n\t\t\tsize, err = bsh.Stat(req.Context(), repo, h)\n\t\t\tif errors.Is(err, errNotFound) {\n\t\t\t\treturn regErrBlobUnknown\n\t\t\t} else if err != nil {\n\t\t\t\tvar rerr redirectError\n\t\t\t\tif errors.As(err, &rerr) {\n\t\t\t\t\thttp.Redirect(resp, req, rerr.Location, rerr.Code)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\n\t\t\trc, err := b.blobHandler.Get(req.Context(), repo, h)\n\t\t\tif errors.Is(err, errNotFound) {\n\t\t\t\treturn regErrBlobUnknown\n\t\t\t} else if err != nil {\n\t\t\t\tvar rerr redirectError\n\t\t\t\tif errors.As(err, &rerr) {\n\t\t\t\t\thttp.Redirect(resp, req, rerr.Location, rerr.Code)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\t\t\tdefer rc.Close()\n\t\t\tr = rc\n\t\t} else {\n\t\t\ttmp, err := b.blobHandler.Get(req.Context(), repo, h)\n\t\t\tif errors.Is(err, errNotFound) {\n\t\t\t\treturn regErrBlobUnknown\n\t\t\t} else if err != nil {\n\t\t\t\tvar rerr redirectError\n\t\t\t\tif errors.As(err, &rerr) {\n\t\t\t\t\thttp.Redirect(resp, req, rerr.Location, rerr.Code)\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\t\t\tdefer tmp.Close()\n\t\t\tvar buf bytes.Buffer\n\t\t\tio.Copy(&buf, tmp)\n\t\t\tsize = int64(buf.Len())\n\t\t\tr = &buf\n\t\t}\n\n\t\tresp.Header().Set(\"Content-Length\", fmt.Sprint(size))\n\t\tresp.Header().Set(\"Docker-Content-Digest\", h.String())\n\t\tresp.WriteHeader(http.StatusOK)\n\t\tio.Copy(resp, r)\n\t\treturn nil\n\n\tcase http.MethodPost:\n\t\tbph, ok := b.blobHandler.(BlobPutHandler)\n\t\tif !ok {\n\t\t\treturn regErrUnsupported\n\t\t}\n\n\t\t// It is weird that this is \"target\" instead of \"service\", but\n\t\t// that's how the index math works out above.\n\t\tif target != \"uploads\" {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"METHOD_UNKNOWN\",\n\t\t\t\tMessage: fmt.Sprintf(\"POST to /blobs must be followed by /uploads, got %s\", target),\n\t\t\t}\n\t\t}\n\n\t\tif digest != \"\" {\n\t\t\th, err := v1.NewHash(digest)\n\t\t\tif err != nil {\n\t\t\t\treturn regErrDigestInvalid\n\t\t\t}\n\n\t\t\tvrc, err := verify.ReadCloser(req.Body, req.ContentLength, h)\n\t\t\tif err != nil {\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\t\t\tdefer vrc.Close()\n\n\t\t\tif err = bph.Put(req.Context(), repo, h, vrc); err != nil {\n\t\t\t\tif errors.As(err, &verify.Error{}) {\n\t\t\t\t\tlog.Printf(\"Digest mismatch: %v\", err)\n\t\t\t\t\treturn regErrDigestMismatch\n\t\t\t\t}\n\t\t\t\treturn regErrInternal(err)\n\t\t\t}\n\t\t\tresp.Header().Set(\"Docker-Content-Digest\", h.String())\n\t\t\tresp.WriteHeader(http.StatusCreated)\n\t\t\treturn nil\n\t\t}\n\n\t\tid := fmt.Sprint(rand.Int63())\n\t\tresp.Header().Set(\"Location\", \"/\"+path.Join(\"v2\", path.Join(elem[1:len(elem)-2]...), \"blobs/uploads\", id))\n\t\tresp.Header().Set(\"Range\", \"0-0\")\n\t\tresp.WriteHeader(http.StatusAccepted)\n\t\treturn nil\n\n\tcase http.MethodPatch:\n\t\tif service != \"uploads\" {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"METHOD_UNKNOWN\",\n\t\t\t\tMessage: fmt.Sprintf(\"PATCH to /blobs must be followed by /uploads, got %s\", service),\n\t\t\t}\n\t\t}\n\n\t\tif contentRange != \"\" {\n\t\t\tstart, end := 0, 0\n\t\t\tif _, err := fmt.Sscanf(contentRange, \"%d-%d\", &start, &end); err != nil {\n\t\t\t\treturn &regError{\n\t\t\t\t\tStatus:  http.StatusRequestedRangeNotSatisfiable,\n\t\t\t\t\tCode:    \"BLOB_UPLOAD_UNKNOWN\",\n\t\t\t\t\tMessage: \"We don't understand your Content-Range\",\n\t\t\t\t}\n\t\t\t}\n\t\t\tb.lock.Lock()\n\t\t\tdefer b.lock.Unlock()\n\t\t\tif start != len(b.uploads[target]) {\n\t\t\t\treturn &regError{\n\t\t\t\t\tStatus:  http.StatusRequestedRangeNotSatisfiable,\n\t\t\t\t\tCode:    \"BLOB_UPLOAD_UNKNOWN\",\n\t\t\t\t\tMessage: \"Your content range doesn't match what we have\",\n\t\t\t\t}\n\t\t\t}\n\t\t\tl := bytes.NewBuffer(b.uploads[target])\n\t\t\tio.Copy(l, req.Body)\n\t\t\tb.uploads[target] = l.Bytes()\n\t\t\tresp.Header().Set(\"Location\", \"/\"+path.Join(\"v2\", path.Join(elem[1:len(elem)-3]...), \"blobs/uploads\", target))\n\t\t\tresp.Header().Set(\"Range\", fmt.Sprintf(\"0-%d\", len(l.Bytes())-1))\n\t\t\tresp.WriteHeader(http.StatusNoContent)\n\t\t\treturn nil\n\t\t}\n\n\t\tb.lock.Lock()\n\t\tdefer b.lock.Unlock()\n\t\tif _, ok := b.uploads[target]; ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"BLOB_UPLOAD_INVALID\",\n\t\t\t\tMessage: \"Stream uploads after first write are not allowed\",\n\t\t\t}\n\t\t}\n\n\t\tl := &bytes.Buffer{}\n\t\tio.Copy(l, req.Body)\n\n\t\tb.uploads[target] = l.Bytes()\n\t\tresp.Header().Set(\"Location\", \"/\"+path.Join(\"v2\", path.Join(elem[1:len(elem)-3]...), \"blobs/uploads\", target))\n\t\tresp.Header().Set(\"Range\", fmt.Sprintf(\"0-%d\", len(l.Bytes())-1))\n\t\tresp.WriteHeader(http.StatusNoContent)\n\t\treturn nil\n\n\tcase http.MethodPut:\n\t\tbph, ok := b.blobHandler.(BlobPutHandler)\n\t\tif !ok {\n\t\t\treturn regErrUnsupported\n\t\t}\n\n\t\tif service != \"uploads\" {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"METHOD_UNKNOWN\",\n\t\t\t\tMessage: fmt.Sprintf(\"PUT to /blobs must be followed by /uploads, got %s\", service),\n\t\t\t}\n\t\t}\n\n\t\tif digest == \"\" {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"DIGEST_INVALID\",\n\t\t\t\tMessage: \"digest not specified\",\n\t\t\t}\n\t\t}\n\n\t\tb.lock.Lock()\n\t\tdefer b.lock.Unlock()\n\n\t\th, err := v1.NewHash(digest)\n\t\tif err != nil {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"NAME_INVALID\",\n\t\t\t\tMessage: \"invalid digest\",\n\t\t\t}\n\t\t}\n\n\t\tdefer req.Body.Close()\n\t\tin := io.NopCloser(io.MultiReader(bytes.NewBuffer(b.uploads[target]), req.Body))\n\n\t\tsize := int64(verify.SizeUnknown)\n\t\tif req.ContentLength > 0 {\n\t\t\tsize = int64(len(b.uploads[target])) + req.ContentLength\n\t\t}\n\n\t\tvrc, err := verify.ReadCloser(in, size, h)\n\t\tif err != nil {\n\t\t\treturn regErrInternal(err)\n\t\t}\n\t\tdefer vrc.Close()\n\n\t\tif err := bph.Put(req.Context(), repo, h, vrc); err != nil {\n\t\t\tif errors.As(err, &verify.Error{}) {\n\t\t\t\tlog.Printf(\"Digest mismatch: %v\", err)\n\t\t\t\treturn regErrDigestMismatch\n\t\t\t}\n\t\t\treturn regErrInternal(err)\n\t\t}\n\n\t\tdelete(b.uploads, target)\n\t\tresp.Header().Set(\"Docker-Content-Digest\", h.String())\n\t\tresp.WriteHeader(http.StatusCreated)\n\t\treturn nil\n\n\tcase http.MethodDelete:\n\t\tbdh, ok := b.blobHandler.(BlobDeleteHandler)\n\t\tif !ok {\n\t\t\treturn regErrUnsupported\n\t\t}\n\n\t\th, err := v1.NewHash(target)\n\t\tif err != nil {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\tCode:    \"NAME_INVALID\",\n\t\t\t\tMessage: \"invalid digest\",\n\t\t\t}\n\t\t}\n\t\tif err := bdh.Delete(req.Context(), repo, h); err != nil {\n\t\t\treturn regErrInternal(err)\n\t\t}\n\t\tresp.WriteHeader(http.StatusAccepted)\n\t\treturn nil\n\n\tdefault:\n\t\treturn &regError{\n\t\t\tStatus:  http.StatusBadRequest,\n\t\t\tCode:    \"METHOD_UNKNOWN\",\n\t\t\tMessage: \"We don't understand your method + url\",\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/registry/blobs_disk.go",
    "content": "// Copyright 2023 Google LLC All Rights Reserved.\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//    http://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\npackage registry\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\ntype diskHandler struct {\n\tdir string\n}\n\nfunc NewDiskBlobHandler(dir string) BlobHandler { return &diskHandler{dir: dir} }\n\nfunc (m *diskHandler) blobHashPath(h v1.Hash) string {\n\treturn filepath.Join(m.dir, h.Algorithm, h.Hex)\n}\n\nfunc (m *diskHandler) Stat(_ context.Context, _ string, h v1.Hash) (int64, error) {\n\tfi, err := os.Stat(m.blobHashPath(h))\n\tif errors.Is(err, os.ErrNotExist) {\n\t\treturn 0, errNotFound\n\t} else if err != nil {\n\t\treturn 0, err\n\t}\n\treturn fi.Size(), nil\n}\nfunc (m *diskHandler) Get(_ context.Context, _ string, h v1.Hash) (io.ReadCloser, error) {\n\treturn os.Open(m.blobHashPath(h))\n}\nfunc (m *diskHandler) Put(_ context.Context, _ string, h v1.Hash, rc io.ReadCloser) error {\n\t// Put the temp file in the same directory to avoid cross-device problems\n\t// during the os.Rename.  The filenames cannot conflict.\n\tf, err := os.CreateTemp(m.dir, \"upload-*\")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := func() error {\n\t\tdefer f.Close()\n\t\t_, err := io.Copy(f, rc)\n\t\treturn err\n\t}(); err != nil {\n\t\treturn err\n\t}\n\tif err := os.MkdirAll(filepath.Join(m.dir, h.Algorithm), os.ModePerm); err != nil {\n\t\treturn err\n\t}\n\treturn os.Rename(f.Name(), m.blobHashPath(h))\n}\nfunc (m *diskHandler) Delete(_ context.Context, _ string, h v1.Hash) error {\n\treturn os.Remove(m.blobHashPath(h))\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/registry/error.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage registry\n\nimport (\n\t\"encoding/json\"\n\t\"net/http\"\n)\n\ntype regError struct {\n\tStatus  int\n\tCode    string\n\tMessage string\n}\n\nfunc (r *regError) Write(resp http.ResponseWriter) error {\n\tresp.WriteHeader(r.Status)\n\n\ttype err struct {\n\t\tCode    string `json:\"code\"`\n\t\tMessage string `json:\"message\"`\n\t}\n\ttype wrap struct {\n\t\tErrors []err `json:\"errors\"`\n\t}\n\treturn json.NewEncoder(resp).Encode(wrap{\n\t\tErrors: []err{\n\t\t\t{\n\t\t\t\tCode:    r.Code,\n\t\t\t\tMessage: r.Message,\n\t\t\t},\n\t\t},\n\t})\n}\n\n// regErrInternal returns an internal server error.\nfunc regErrInternal(err error) *regError {\n\treturn &regError{\n\t\tStatus:  http.StatusInternalServerError,\n\t\tCode:    \"INTERNAL_SERVER_ERROR\",\n\t\tMessage: err.Error(),\n\t}\n}\n\nvar regErrBlobUnknown = &regError{\n\tStatus:  http.StatusNotFound,\n\tCode:    \"BLOB_UNKNOWN\",\n\tMessage: \"Unknown blob\",\n}\n\nvar regErrUnsupported = &regError{\n\tStatus:  http.StatusMethodNotAllowed,\n\tCode:    \"UNSUPPORTED\",\n\tMessage: \"Unsupported operation\",\n}\n\nvar regErrDigestMismatch = &regError{\n\tStatus:  http.StatusBadRequest,\n\tCode:    \"DIGEST_INVALID\",\n\tMessage: \"digest does not match contents\",\n}\n\nvar regErrDigestInvalid = &regError{\n\tStatus:  http.StatusBadRequest,\n\tCode:    \"NAME_INVALID\",\n\tMessage: \"invalid digest\",\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/registry/manifest.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage registry\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype catalog struct {\n\tRepos []string `json:\"repositories\"`\n}\n\ntype listTags struct {\n\tName string   `json:\"name\"`\n\tTags []string `json:\"tags\"`\n}\n\ntype manifest struct {\n\tcontentType string\n\tblob        []byte\n}\n\ntype manifests struct {\n\t// maps repo -> manifest tag/digest -> manifest\n\tmanifests map[string]map[string]manifest\n\tlock      sync.RWMutex\n\tlog       *log.Logger\n}\n\nfunc isManifest(req *http.Request) bool {\n\telems := strings.Split(req.URL.Path, \"/\")\n\telems = elems[1:]\n\tif len(elems) < 4 {\n\t\treturn false\n\t}\n\treturn elems[len(elems)-2] == \"manifests\"\n}\n\nfunc isTags(req *http.Request) bool {\n\telems := strings.Split(req.URL.Path, \"/\")\n\telems = elems[1:]\n\tif len(elems) < 4 {\n\t\treturn false\n\t}\n\treturn elems[len(elems)-2] == \"tags\"\n}\n\nfunc isCatalog(req *http.Request) bool {\n\telems := strings.Split(req.URL.Path, \"/\")\n\telems = elems[1:]\n\tif len(elems) < 2 {\n\t\treturn false\n\t}\n\n\treturn elems[len(elems)-1] == \"_catalog\"\n}\n\n// Returns whether this url should be handled by the referrers handler\nfunc isReferrers(req *http.Request) bool {\n\telems := strings.Split(req.URL.Path, \"/\")\n\telems = elems[1:]\n\tif len(elems) < 4 {\n\t\treturn false\n\t}\n\treturn elems[len(elems)-2] == \"referrers\"\n}\n\n// https://github.com/opencontainers/distribution-spec/blob/master/spec.md#pulling-an-image-manifest\n// https://github.com/opencontainers/distribution-spec/blob/master/spec.md#pushing-an-image\nfunc (m *manifests) handle(resp http.ResponseWriter, req *http.Request) *regError {\n\telem := strings.Split(req.URL.Path, \"/\")\n\telem = elem[1:]\n\ttarget := elem[len(elem)-1]\n\trepo := strings.Join(elem[1:len(elem)-2], \"/\")\n\n\tswitch req.Method {\n\tcase http.MethodGet:\n\t\tm.lock.RLock()\n\t\tdefer m.lock.RUnlock()\n\n\t\tc, ok := m.manifests[repo]\n\t\tif !ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\tCode:    \"NAME_UNKNOWN\",\n\t\t\t\tMessage: \"Unknown name\",\n\t\t\t}\n\t\t}\n\t\tm, ok := c[target]\n\t\tif !ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\tCode:    \"MANIFEST_UNKNOWN\",\n\t\t\t\tMessage: \"Unknown manifest\",\n\t\t\t}\n\t\t}\n\n\t\th, _, _ := v1.SHA256(bytes.NewReader(m.blob))\n\t\tresp.Header().Set(\"Docker-Content-Digest\", h.String())\n\t\tresp.Header().Set(\"Content-Type\", m.contentType)\n\t\tresp.Header().Set(\"Content-Length\", fmt.Sprint(len(m.blob)))\n\t\tresp.WriteHeader(http.StatusOK)\n\t\tio.Copy(resp, bytes.NewReader(m.blob))\n\t\treturn nil\n\n\tcase http.MethodHead:\n\t\tm.lock.RLock()\n\t\tdefer m.lock.RUnlock()\n\n\t\tif _, ok := m.manifests[repo]; !ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\tCode:    \"NAME_UNKNOWN\",\n\t\t\t\tMessage: \"Unknown name\",\n\t\t\t}\n\t\t}\n\t\tm, ok := m.manifests[repo][target]\n\t\tif !ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\tCode:    \"MANIFEST_UNKNOWN\",\n\t\t\t\tMessage: \"Unknown manifest\",\n\t\t\t}\n\t\t}\n\n\t\th, _, _ := v1.SHA256(bytes.NewReader(m.blob))\n\t\tresp.Header().Set(\"Docker-Content-Digest\", h.String())\n\t\tresp.Header().Set(\"Content-Type\", m.contentType)\n\t\tresp.Header().Set(\"Content-Length\", fmt.Sprint(len(m.blob)))\n\t\tresp.WriteHeader(http.StatusOK)\n\t\treturn nil\n\n\tcase http.MethodPut:\n\t\tb := &bytes.Buffer{}\n\t\tio.Copy(b, req.Body)\n\t\th, _, _ := v1.SHA256(bytes.NewReader(b.Bytes()))\n\t\tdigest := h.String()\n\t\tmf := manifest{\n\t\t\tblob:        b.Bytes(),\n\t\t\tcontentType: req.Header.Get(\"Content-Type\"),\n\t\t}\n\n\t\t// If the manifest is a manifest list, check that the manifest\n\t\t// list's constituent manifests are already uploaded.\n\t\t// This isn't strictly required by the registry API, but some\n\t\t// registries require this.\n\t\tif types.MediaType(mf.contentType).IsIndex() {\n\t\t\tif err := func() *regError {\n\t\t\t\tm.lock.RLock()\n\t\t\t\tdefer m.lock.RUnlock()\n\n\t\t\t\tim, err := v1.ParseIndexManifest(b)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn &regError{\n\t\t\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\t\t\tCode:    \"MANIFEST_INVALID\",\n\t\t\t\t\t\tMessage: err.Error(),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor _, desc := range im.Manifests {\n\t\t\t\t\tif !desc.MediaType.IsDistributable() {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif desc.MediaType.IsIndex() || desc.MediaType.IsImage() {\n\t\t\t\t\t\tif _, found := m.manifests[repo][desc.Digest.String()]; !found {\n\t\t\t\t\t\t\treturn &regError{\n\t\t\t\t\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\t\t\t\t\tCode:    \"MANIFEST_UNKNOWN\",\n\t\t\t\t\t\t\t\tMessage: fmt.Sprintf(\"Sub-manifest %q not found\", desc.Digest),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// TODO: Probably want to do an existence check for blobs.\n\t\t\t\t\t\tm.log.Printf(\"TODO: Check blobs for %q\", desc.Digest)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tm.lock.Lock()\n\t\tdefer m.lock.Unlock()\n\n\t\tif _, ok := m.manifests[repo]; !ok {\n\t\t\tm.manifests[repo] = make(map[string]manifest, 2)\n\t\t}\n\n\t\t// Allow future references by target (tag) and immutable digest.\n\t\t// See https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier.\n\t\tm.manifests[repo][digest] = mf\n\t\tm.manifests[repo][target] = mf\n\t\tresp.Header().Set(\"Docker-Content-Digest\", digest)\n\t\tresp.WriteHeader(http.StatusCreated)\n\t\treturn nil\n\n\tcase http.MethodDelete:\n\t\tm.lock.Lock()\n\t\tdefer m.lock.Unlock()\n\t\tif _, ok := m.manifests[repo]; !ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\tCode:    \"NAME_UNKNOWN\",\n\t\t\t\tMessage: \"Unknown name\",\n\t\t\t}\n\t\t}\n\n\t\t_, ok := m.manifests[repo][target]\n\t\tif !ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\tCode:    \"MANIFEST_UNKNOWN\",\n\t\t\t\tMessage: \"Unknown manifest\",\n\t\t\t}\n\t\t}\n\n\t\tdelete(m.manifests[repo], target)\n\t\tresp.WriteHeader(http.StatusAccepted)\n\t\treturn nil\n\n\tdefault:\n\t\treturn &regError{\n\t\t\tStatus:  http.StatusBadRequest,\n\t\t\tCode:    \"METHOD_UNKNOWN\",\n\t\t\tMessage: \"We don't understand your method + url\",\n\t\t}\n\t}\n}\n\nfunc (m *manifests) handleTags(resp http.ResponseWriter, req *http.Request) *regError {\n\telem := strings.Split(req.URL.Path, \"/\")\n\telem = elem[1:]\n\trepo := strings.Join(elem[1:len(elem)-2], \"/\")\n\n\tif req.Method == \"GET\" {\n\t\tm.lock.RLock()\n\t\tdefer m.lock.RUnlock()\n\n\t\tc, ok := m.manifests[repo]\n\t\tif !ok {\n\t\t\treturn &regError{\n\t\t\t\tStatus:  http.StatusNotFound,\n\t\t\t\tCode:    \"NAME_UNKNOWN\",\n\t\t\t\tMessage: \"Unknown name\",\n\t\t\t}\n\t\t}\n\n\t\tvar tags []string\n\t\tfor tag := range c {\n\t\t\tif !strings.Contains(tag, \"sha256:\") {\n\t\t\t\ttags = append(tags, tag)\n\t\t\t}\n\t\t}\n\t\tsort.Strings(tags)\n\n\t\t// https://github.com/opencontainers/distribution-spec/blob/b505e9cc53ec499edbd9c1be32298388921bb705/detail.md#tags-paginated\n\t\t// Offset using last query parameter.\n\t\tif last := req.URL.Query().Get(\"last\"); last != \"\" {\n\t\t\tfor i, t := range tags {\n\t\t\t\tif t > last {\n\t\t\t\t\ttags = tags[i:]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Limit using n query parameter.\n\t\tif ns := req.URL.Query().Get(\"n\"); ns != \"\" {\n\t\t\tif n, err := strconv.Atoi(ns); err != nil {\n\t\t\t\treturn &regError{\n\t\t\t\t\tStatus:  http.StatusBadRequest,\n\t\t\t\t\tCode:    \"BAD_REQUEST\",\n\t\t\t\t\tMessage: fmt.Sprintf(\"parsing n: %v\", err),\n\t\t\t\t}\n\t\t\t} else if n < len(tags) {\n\t\t\t\ttags = tags[:n]\n\t\t\t}\n\t\t}\n\n\t\ttagsToList := listTags{\n\t\t\tName: repo,\n\t\t\tTags: tags,\n\t\t}\n\n\t\tmsg, _ := json.Marshal(tagsToList)\n\t\tresp.Header().Set(\"Content-Length\", fmt.Sprint(len(msg)))\n\t\tresp.WriteHeader(http.StatusOK)\n\t\tio.Copy(resp, bytes.NewReader([]byte(msg)))\n\t\treturn nil\n\t}\n\n\treturn &regError{\n\t\tStatus:  http.StatusBadRequest,\n\t\tCode:    \"METHOD_UNKNOWN\",\n\t\tMessage: \"We don't understand your method + url\",\n\t}\n}\n\nfunc (m *manifests) handleCatalog(resp http.ResponseWriter, req *http.Request) *regError {\n\tquery := req.URL.Query()\n\tnStr := query.Get(\"n\")\n\tn := 10000\n\tif nStr != \"\" {\n\t\tn, _ = strconv.Atoi(nStr)\n\t}\n\n\tif req.Method == \"GET\" {\n\t\tm.lock.RLock()\n\t\tdefer m.lock.RUnlock()\n\n\t\tvar repos []string\n\t\tcountRepos := 0\n\t\t// TODO: implement pagination\n\t\tfor key := range m.manifests {\n\t\t\tif countRepos >= n {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcountRepos++\n\n\t\t\trepos = append(repos, key)\n\t\t}\n\n\t\trepositoriesToList := catalog{\n\t\t\tRepos: repos,\n\t\t}\n\n\t\tmsg, _ := json.Marshal(repositoriesToList)\n\t\tresp.Header().Set(\"Content-Length\", fmt.Sprint(len(msg)))\n\t\tresp.WriteHeader(http.StatusOK)\n\t\tio.Copy(resp, bytes.NewReader([]byte(msg)))\n\t\treturn nil\n\t}\n\n\treturn &regError{\n\t\tStatus:  http.StatusBadRequest,\n\t\tCode:    \"METHOD_UNKNOWN\",\n\t\tMessage: \"We don't understand your method + url\",\n\t}\n}\n\n// TODO: implement handling of artifactType querystring\nfunc (m *manifests) handleReferrers(resp http.ResponseWriter, req *http.Request) *regError {\n\t// Ensure this is a GET request\n\tif req.Method != \"GET\" {\n\t\treturn &regError{\n\t\t\tStatus:  http.StatusBadRequest,\n\t\t\tCode:    \"METHOD_UNKNOWN\",\n\t\t\tMessage: \"We don't understand your method + url\",\n\t\t}\n\t}\n\n\telem := strings.Split(req.URL.Path, \"/\")\n\telem = elem[1:]\n\ttarget := elem[len(elem)-1]\n\trepo := strings.Join(elem[1:len(elem)-2], \"/\")\n\n\t// Validate that incoming target is a valid digest\n\tif _, err := v1.NewHash(target); err != nil {\n\t\treturn &regError{\n\t\t\tStatus:  http.StatusBadRequest,\n\t\t\tCode:    \"UNSUPPORTED\",\n\t\t\tMessage: \"Target must be a valid digest\",\n\t\t}\n\t}\n\n\tm.lock.RLock()\n\tdefer m.lock.RUnlock()\n\n\tdigestToManifestMap, repoExists := m.manifests[repo]\n\tif !repoExists {\n\t\treturn &regError{\n\t\t\tStatus:  http.StatusNotFound,\n\t\t\tCode:    \"NAME_UNKNOWN\",\n\t\t\tMessage: \"Unknown name\",\n\t\t}\n\t}\n\n\tim := v1.IndexManifest{\n\t\tSchemaVersion: 2,\n\t\tMediaType:     types.OCIImageIndex,\n\t\tManifests:     []v1.Descriptor{},\n\t}\n\tfor digest, manifest := range digestToManifestMap {\n\t\th, err := v1.NewHash(digest)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tvar refPointer struct {\n\t\t\tSubject *v1.Descriptor `json:\"subject\"`\n\t\t}\n\t\tjson.Unmarshal(manifest.blob, &refPointer)\n\t\tif refPointer.Subject == nil {\n\t\t\tcontinue\n\t\t}\n\t\treferenceDigest := refPointer.Subject.Digest\n\t\tif referenceDigest.String() != target {\n\t\t\tcontinue\n\t\t}\n\t\t// At this point, we know the current digest references the target\n\t\tvar imageAsArtifact struct {\n\t\t\tConfig struct {\n\t\t\t\tMediaType string `json:\"mediaType\"`\n\t\t\t} `json:\"config\"`\n\t\t}\n\t\tjson.Unmarshal(manifest.blob, &imageAsArtifact)\n\t\tim.Manifests = append(im.Manifests, v1.Descriptor{\n\t\t\tMediaType:    types.MediaType(manifest.contentType),\n\t\t\tSize:         int64(len(manifest.blob)),\n\t\t\tDigest:       h,\n\t\t\tArtifactType: imageAsArtifact.Config.MediaType,\n\t\t})\n\t}\n\tmsg, _ := json.Marshal(&im)\n\tresp.Header().Set(\"Content-Length\", fmt.Sprint(len(msg)))\n\tresp.Header().Set(\"Content-Type\", string(types.OCIImageIndex))\n\tresp.WriteHeader(http.StatusOK)\n\tio.Copy(resp, bytes.NewReader([]byte(msg)))\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/registry/registry.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package registry implements a docker V2 registry and the OCI distribution specification.\n//\n// It is designed to be used anywhere a low dependency container registry is needed, with an\n// initial focus on tests.\n//\n// Its goal is to be standards compliant and its strictness will increase over time.\n//\n// This is currently a low flightmiles system. It's likely quite safe to use in tests; If you're using it\n// in production, please let us know how and send us CL's for integration tests.\npackage registry\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os\"\n)\n\ntype registry struct {\n\tlog              *log.Logger\n\tblobs            blobs\n\tmanifests        manifests\n\treferrersEnabled bool\n\twarnings         map[float64]string\n}\n\n// https://docs.docker.com/registry/spec/api/#api-version-check\n// https://github.com/opencontainers/distribution-spec/blob/master/spec.md#api-version-check\nfunc (r *registry) v2(resp http.ResponseWriter, req *http.Request) *regError {\n\tif r.warnings != nil {\n\t\trnd := rand.Float64()\n\t\tfor prob, msg := range r.warnings {\n\t\t\tif prob > rnd {\n\t\t\t\tresp.Header().Add(\"Warning\", fmt.Sprintf(`299 - \"%s\"`, msg))\n\t\t\t}\n\t\t}\n\t}\n\n\tif isBlob(req) {\n\t\treturn r.blobs.handle(resp, req)\n\t}\n\tif isManifest(req) {\n\t\treturn r.manifests.handle(resp, req)\n\t}\n\tif isTags(req) {\n\t\treturn r.manifests.handleTags(resp, req)\n\t}\n\tif isCatalog(req) {\n\t\treturn r.manifests.handleCatalog(resp, req)\n\t}\n\tif r.referrersEnabled && isReferrers(req) {\n\t\treturn r.manifests.handleReferrers(resp, req)\n\t}\n\tresp.Header().Set(\"Docker-Distribution-API-Version\", \"registry/2.0\")\n\tif req.URL.Path != \"/v2/\" && req.URL.Path != \"/v2\" {\n\t\treturn &regError{\n\t\t\tStatus:  http.StatusNotFound,\n\t\t\tCode:    \"METHOD_UNKNOWN\",\n\t\t\tMessage: \"We don't understand your method + url\",\n\t\t}\n\t}\n\tresp.WriteHeader(200)\n\treturn nil\n}\n\nfunc (r *registry) root(resp http.ResponseWriter, req *http.Request) {\n\tif rerr := r.v2(resp, req); rerr != nil {\n\t\tr.log.Printf(\"%s %s %d %s %s\", req.Method, req.URL, rerr.Status, rerr.Code, rerr.Message)\n\t\trerr.Write(resp)\n\t\treturn\n\t}\n\tr.log.Printf(\"%s %s\", req.Method, req.URL)\n}\n\n// New returns a handler which implements the docker registry protocol.\n// It should be registered at the site root.\nfunc New(opts ...Option) http.Handler {\n\tr := &registry{\n\t\tlog: log.New(os.Stderr, \"\", log.LstdFlags),\n\t\tblobs: blobs{\n\t\t\tblobHandler: &memHandler{m: map[string][]byte{}},\n\t\t\tuploads:     map[string][]byte{},\n\t\t\tlog:         log.New(os.Stderr, \"\", log.LstdFlags),\n\t\t},\n\t\tmanifests: manifests{\n\t\t\tmanifests: map[string]map[string]manifest{},\n\t\t\tlog:       log.New(os.Stderr, \"\", log.LstdFlags),\n\t\t},\n\t}\n\tfor _, o := range opts {\n\t\to(r)\n\t}\n\treturn http.HandlerFunc(r.root)\n}\n\n// Option describes the available options\n// for creating the registry.\ntype Option func(r *registry)\n\n// Logger overrides the logger used to record requests to the registry.\nfunc Logger(l *log.Logger) Option {\n\treturn func(r *registry) {\n\t\tr.log = l\n\t\tr.manifests.log = l\n\t\tr.blobs.log = l\n\t}\n}\n\n// WithReferrersSupport enables the referrers API endpoint (OCI 1.1+)\nfunc WithReferrersSupport(enabled bool) Option {\n\treturn func(r *registry) {\n\t\tr.referrersEnabled = enabled\n\t}\n}\n\nfunc WithWarning(prob float64, msg string) Option {\n\treturn func(r *registry) {\n\t\tif r.warnings == nil {\n\t\t\tr.warnings = map[float64]string{}\n\t\t}\n\t\tr.warnings[prob] = msg\n\t}\n}\n\nfunc WithBlobHandler(h BlobHandler) Option {\n\treturn func(r *registry) {\n\t\tr.blobs.blobHandler = h\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/registry/tls.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage registry\n\nimport (\n\t\"net/http/httptest\"\n\n\tggcrtest \"github.com/google/go-containerregistry/internal/httptest\"\n)\n\n// TLS returns an httptest server, with an http client that has been configured to\n// send all requests to the returned server. The TLS certs are generated for the given domain\n// which should correspond to the domain the image is stored in.\n// If you need a transport, Client().Transport is correctly configured.\nfunc TLS(domain string) (*httptest.Server, error) {\n\treturn ggcrtest.NewTLSServer(domain, New())\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/config.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\t\"time\"\n)\n\n// ConfigFile is the configuration file that holds the metadata describing\n// how to launch a container. See:\n// https://github.com/opencontainers/image-spec/blob/master/config.md\n//\n// docker_version and os.version are not part of the spec but included\n// for backwards compatibility.\ntype ConfigFile struct {\n\tArchitecture  string    `json:\"architecture\"`\n\tAuthor        string    `json:\"author,omitempty\"`\n\tContainer     string    `json:\"container,omitempty\"`\n\tCreated       Time      `json:\"created,omitempty\"`\n\tDockerVersion string    `json:\"docker_version,omitempty\"`\n\tHistory       []History `json:\"history,omitempty\"`\n\tOS            string    `json:\"os\"`\n\tRootFS        RootFS    `json:\"rootfs\"`\n\tConfig        Config    `json:\"config\"`\n\tOSVersion     string    `json:\"os.version,omitempty\"`\n\tVariant       string    `json:\"variant,omitempty\"`\n\tOSFeatures    []string  `json:\"os.features,omitempty\"`\n}\n\n// Platform attempts to generates a Platform from the ConfigFile fields.\nfunc (cf *ConfigFile) Platform() *Platform {\n\tif cf.OS == \"\" && cf.Architecture == \"\" && cf.OSVersion == \"\" && cf.Variant == \"\" && len(cf.OSFeatures) == 0 {\n\t\treturn nil\n\t}\n\treturn &Platform{\n\t\tOS:           cf.OS,\n\t\tArchitecture: cf.Architecture,\n\t\tOSVersion:    cf.OSVersion,\n\t\tVariant:      cf.Variant,\n\t\tOSFeatures:   cf.OSFeatures,\n\t}\n}\n\n// History is one entry of a list recording how this container image was built.\ntype History struct {\n\tAuthor     string `json:\"author,omitempty\"`\n\tCreated    Time   `json:\"created,omitempty\"`\n\tCreatedBy  string `json:\"created_by,omitempty\"`\n\tComment    string `json:\"comment,omitempty\"`\n\tEmptyLayer bool   `json:\"empty_layer,omitempty\"`\n}\n\n// Time is a wrapper around time.Time to help with deep copying\ntype Time struct {\n\ttime.Time\n}\n\n// DeepCopyInto creates a deep-copy of the Time value.  The underlying time.Time\n// type is effectively immutable in the time API, so it is safe to\n// copy-by-assign, despite the presence of (unexported) Pointer fields.\nfunc (t *Time) DeepCopyInto(out *Time) {\n\t*out = *t\n}\n\n// RootFS holds the ordered list of file system deltas that comprise the\n// container image's root filesystem.\ntype RootFS struct {\n\tType    string `json:\"type\"`\n\tDiffIDs []Hash `json:\"diff_ids\"`\n}\n\n// HealthConfig holds configuration settings for the HEALTHCHECK feature.\ntype HealthConfig struct {\n\t// Test is the test to perform to check that the container is healthy.\n\t// An empty slice means to inherit the default.\n\t// The options are:\n\t// {} : inherit healthcheck\n\t// {\"NONE\"} : disable healthcheck\n\t// {\"CMD\", args...} : exec arguments directly\n\t// {\"CMD-SHELL\", command} : run command with system's default shell\n\tTest []string `json:\",omitempty\"`\n\n\t// Zero means to inherit. Durations are expressed as integer nanoseconds.\n\tInterval    time.Duration `json:\",omitempty\"` // Interval is the time to wait between checks.\n\tTimeout     time.Duration `json:\",omitempty\"` // Timeout is the time to wait before considering the check to have hung.\n\tStartPeriod time.Duration `json:\",omitempty\"` // The start period for the container to initialize before the retries starts to count down.\n\n\t// Retries is the number of consecutive failures needed to consider a container as unhealthy.\n\t// Zero means inherit.\n\tRetries int `json:\",omitempty\"`\n}\n\n// Config is a submessage of the config file described as:\n//\n//\tThe execution parameters which SHOULD be used as a base when running\n//\ta container using the image.\n//\n// The names of the fields in this message are chosen to reflect the JSON\n// payload of the Config as defined here:\n// https://git.io/vrAET\n// and\n// https://github.com/opencontainers/image-spec/blob/master/config.md\ntype Config struct {\n\tAttachStderr    bool                `json:\"AttachStderr,omitempty\"`\n\tAttachStdin     bool                `json:\"AttachStdin,omitempty\"`\n\tAttachStdout    bool                `json:\"AttachStdout,omitempty\"`\n\tCmd             []string            `json:\"Cmd,omitempty\"`\n\tHealthcheck     *HealthConfig       `json:\"Healthcheck,omitempty\"`\n\tDomainname      string              `json:\"Domainname,omitempty\"`\n\tEntrypoint      []string            `json:\"Entrypoint,omitempty\"`\n\tEnv             []string            `json:\"Env,omitempty\"`\n\tHostname        string              `json:\"Hostname,omitempty\"`\n\tImage           string              `json:\"Image,omitempty\"`\n\tLabels          map[string]string   `json:\"Labels,omitempty\"`\n\tOnBuild         []string            `json:\"OnBuild,omitempty\"`\n\tOpenStdin       bool                `json:\"OpenStdin,omitempty\"`\n\tStdinOnce       bool                `json:\"StdinOnce,omitempty\"`\n\tTty             bool                `json:\"Tty,omitempty\"`\n\tUser            string              `json:\"User,omitempty\"`\n\tVolumes         map[string]struct{} `json:\"Volumes,omitempty\"`\n\tWorkingDir      string              `json:\"WorkingDir,omitempty\"`\n\tExposedPorts    map[string]struct{} `json:\"ExposedPorts,omitempty\"`\n\tArgsEscaped     bool                `json:\"ArgsEscaped,omitempty\"`\n\tNetworkDisabled bool                `json:\"NetworkDisabled,omitempty\"`\n\tMacAddress      string              `json:\"MacAddress,omitempty\"`\n\tStopSignal      string              `json:\"StopSignal,omitempty\"`\n\tShell           []string            `json:\"Shell,omitempty\"`\n}\n\n// ParseConfigFile parses the io.Reader's contents into a ConfigFile.\nfunc ParseConfigFile(r io.Reader) (*ConfigFile, error) {\n\tcf := ConfigFile{}\n\tif err := json.NewDecoder(r).Decode(&cf); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &cf, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/daemon/README.md",
    "content": "# `daemon`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/daemon?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/daemon)\n\nThe `daemon` package enables reading/writing images from/to the docker daemon.\n\nIt is not fully fleshed out, but is useful for interoperability, see various issues:\n\n* https://github.com/google/go-containerregistry/issues/205\n* https://github.com/google/go-containerregistry/issues/552\n* https://github.com/google/go-containerregistry/issues/627\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/daemon/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package daemon provides facilities for reading/writing v1.Image from/to\n// a running daemon.\npackage daemon\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/daemon/image.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage daemon\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\tapi \"github.com/docker/docker/api/types\"\n\t\"github.com/docker/docker/api/types/container\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype image struct {\n\tref          name.Reference\n\topener       *imageOpener\n\ttarballImage v1.Image\n\tcomputed     bool\n\tid           *v1.Hash\n\tconfigFile   *v1.ConfigFile\n\n\tonce sync.Once\n\terr  error\n}\n\ntype imageOpener struct {\n\tref name.Reference\n\tctx context.Context\n\n\tbuffered bool\n\tclient   Client\n\n\tonce  sync.Once\n\tbytes []byte\n\terr   error\n}\n\nfunc (i *imageOpener) saveImage() (io.ReadCloser, error) {\n\treturn i.client.ImageSave(i.ctx, []string{i.ref.Name()})\n}\n\nfunc (i *imageOpener) bufferedOpener() (io.ReadCloser, error) {\n\t// Store the tarball in memory and return a new reader into the bytes each time we need to access something.\n\ti.once.Do(func() {\n\t\ti.bytes, i.err = func() ([]byte, error) {\n\t\t\trc, err := i.saveImage()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdefer rc.Close()\n\n\t\t\treturn io.ReadAll(rc)\n\t\t}()\n\t})\n\n\t// Wrap the bytes in a ReadCloser so it looks like an opened file.\n\treturn io.NopCloser(bytes.NewReader(i.bytes)), i.err\n}\n\nfunc (i *imageOpener) opener() tarball.Opener {\n\tif i.buffered {\n\t\treturn i.bufferedOpener\n\t}\n\n\t// To avoid storing the tarball in memory, do a save every time we need to access something.\n\treturn i.saveImage\n}\n\n// Image provides access to an image reference from the Docker daemon,\n// applying functional options to the underlying imageOpener before\n// resolving the reference into a v1.Image.\nfunc Image(ref name.Reference, options ...Option) (v1.Image, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ti := &imageOpener{\n\t\tref:      ref,\n\t\tbuffered: o.buffered,\n\t\tclient:   o.client,\n\t\tctx:      o.ctx,\n\t}\n\n\timg := &image{\n\t\tref:    ref,\n\t\topener: i,\n\t}\n\n\t// Eagerly fetch Image ID to ensure it actually exists.\n\t// https://github.com/google/go-containerregistry/issues/1186\n\tid, err := img.ConfigName()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\timg.id = &id\n\n\treturn img, nil\n}\n\nfunc (i *image) initialize() error {\n\t// Don't re-initialize tarball if already initialized.\n\tif i.tarballImage == nil {\n\t\ti.once.Do(func() {\n\t\t\ti.tarballImage, i.err = tarball.Image(i.opener.opener(), nil)\n\t\t})\n\t}\n\treturn i.err\n}\n\nfunc (i *image) compute() error {\n\t// Don't re-compute if already computed.\n\tif i.computed {\n\t\treturn nil\n\t}\n\n\tinspect, _, err := i.opener.client.ImageInspectWithRaw(i.opener.ctx, i.ref.String())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tconfigFile, err := i.computeConfigFile(inspect)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ti.configFile = configFile\n\ti.computed = true\n\n\treturn nil\n}\n\nfunc (i *image) Layers() ([]v1.Layer, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.tarballImage.Layers()\n}\n\nfunc (i *image) MediaType() (types.MediaType, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn i.tarballImage.MediaType()\n}\n\nfunc (i *image) Size() (int64, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn 0, err\n\t}\n\treturn i.tarballImage.Size()\n}\n\nfunc (i *image) ConfigName() (v1.Hash, error) {\n\tif i.id != nil {\n\t\treturn *i.id, nil\n\t}\n\tres, _, err := i.opener.client.ImageInspectWithRaw(i.opener.ctx, i.ref.String())\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\treturn v1.NewHash(res.ID)\n}\n\nfunc (i *image) ConfigFile() (*v1.ConfigFile, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.configFile.DeepCopy(), nil\n}\n\nfunc (i *image) RawConfigFile() ([]byte, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// RawConfigFile cannot be generated from \"docker inspect\" because Docker Engine API returns serialized data,\n\t// and formatting information of the raw config such as indent and prefix will be lost.\n\treturn i.tarballImage.RawConfigFile()\n}\n\nfunc (i *image) Digest() (v1.Hash, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\treturn i.tarballImage.Digest()\n}\n\nfunc (i *image) Manifest() (*v1.Manifest, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.tarballImage.Manifest()\n}\n\nfunc (i *image) RawManifest() ([]byte, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.tarballImage.RawManifest()\n}\n\nfunc (i *image) LayerByDigest(h v1.Hash) (v1.Layer, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.tarballImage.LayerByDigest(h)\n}\n\nfunc (i *image) LayerByDiffID(h v1.Hash) (v1.Layer, error) {\n\tif err := i.initialize(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.tarballImage.LayerByDiffID(h)\n}\n\nfunc (i *image) configHistory(author string) ([]v1.History, error) {\n\thistoryItems, err := i.opener.client.ImageHistory(i.opener.ctx, i.ref.String())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thistory := make([]v1.History, len(historyItems))\n\tfor j, h := range historyItems {\n\t\thistory[j] = v1.History{\n\t\t\tAuthor: author,\n\t\t\tCreated: v1.Time{\n\t\t\t\tTime: time.Unix(h.Created, 0).UTC(),\n\t\t\t},\n\t\t\tCreatedBy:  h.CreatedBy,\n\t\t\tComment:    h.Comment,\n\t\t\tEmptyLayer: h.Size == 0,\n\t\t}\n\t}\n\treturn history, nil\n}\n\nfunc (i *image) diffIDs(rootFS api.RootFS) ([]v1.Hash, error) {\n\tdiffIDs := make([]v1.Hash, len(rootFS.Layers))\n\tfor j, l := range rootFS.Layers {\n\t\th, err := v1.NewHash(l)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdiffIDs[j] = h\n\t}\n\treturn diffIDs, nil\n}\n\nfunc (i *image) computeConfigFile(inspect api.ImageInspect) (*v1.ConfigFile, error) {\n\tdiffIDs, err := i.diffIDs(inspect.RootFS)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thistory, err := i.configHistory(inspect.Author)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcreated, err := time.Parse(time.RFC3339Nano, inspect.Created)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &v1.ConfigFile{\n\t\tArchitecture:  inspect.Architecture,\n\t\tAuthor:        inspect.Author,\n\t\tContainer:     inspect.Container,\n\t\tCreated:       v1.Time{Time: created},\n\t\tDockerVersion: inspect.DockerVersion,\n\t\tHistory:       history,\n\t\tOS:            inspect.Os,\n\t\tRootFS: v1.RootFS{\n\t\t\tType:    inspect.RootFS.Type,\n\t\t\tDiffIDs: diffIDs,\n\t\t},\n\t\tConfig:    i.computeImageConfig(inspect.Config),\n\t\tOSVersion: inspect.OsVersion,\n\t}, nil\n}\n\nfunc (i *image) computeImageConfig(config *container.Config) v1.Config {\n\tif config == nil {\n\t\treturn v1.Config{}\n\t}\n\n\tc := v1.Config{\n\t\tAttachStderr:    config.AttachStderr,\n\t\tAttachStdin:     config.AttachStdin,\n\t\tAttachStdout:    config.AttachStdout,\n\t\tCmd:             config.Cmd,\n\t\tDomainname:      config.Domainname,\n\t\tEntrypoint:      config.Entrypoint,\n\t\tEnv:             config.Env,\n\t\tHostname:        config.Hostname,\n\t\tImage:           config.Image,\n\t\tLabels:          config.Labels,\n\t\tOnBuild:         config.OnBuild,\n\t\tOpenStdin:       config.OpenStdin,\n\t\tStdinOnce:       config.StdinOnce,\n\t\tTty:             config.Tty,\n\t\tUser:            config.User,\n\t\tVolumes:         config.Volumes,\n\t\tWorkingDir:      config.WorkingDir,\n\t\tArgsEscaped:     config.ArgsEscaped,\n\t\tNetworkDisabled: config.NetworkDisabled,\n\t\tMacAddress:      config.MacAddress,\n\t\tStopSignal:      config.StopSignal,\n\t\tShell:           config.Shell,\n\t}\n\n\tif config.Healthcheck != nil {\n\t\tc.Healthcheck = &v1.HealthConfig{\n\t\t\tTest:        config.Healthcheck.Test,\n\t\t\tInterval:    config.Healthcheck.Interval,\n\t\t\tTimeout:     config.Healthcheck.Timeout,\n\t\t\tStartPeriod: config.Healthcheck.StartPeriod,\n\t\t\tRetries:     config.Healthcheck.Retries,\n\t\t}\n\t}\n\n\tif len(config.ExposedPorts) > 0 {\n\t\tc.ExposedPorts = map[string]struct{}{}\n\t\tfor port := range c.ExposedPorts {\n\t\t\tc.ExposedPorts[port] = struct{}{}\n\t\t}\n\t}\n\n\treturn c\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/daemon/options.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage daemon\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/docker/docker/api/types\"\n\tapi \"github.com/docker/docker/api/types/image\"\n\t\"github.com/docker/docker/client\"\n)\n\n// ImageOption is an alias for Option.\n// Deprecated: Use Option instead.\ntype ImageOption Option\n\n// Option is a functional option for daemon operations.\ntype Option func(*options)\n\ntype options struct {\n\tctx      context.Context\n\tclient   Client\n\tbuffered bool\n}\n\nvar defaultClient = func() (Client, error) {\n\treturn client.NewClientWithOpts(client.FromEnv)\n}\n\nfunc makeOptions(opts ...Option) (*options, error) {\n\to := &options{\n\t\tbuffered: true,\n\t\tctx:      context.Background(),\n\t}\n\tfor _, opt := range opts {\n\t\topt(o)\n\t}\n\n\tif o.client == nil {\n\t\tclient, err := defaultClient()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\to.client = client\n\t}\n\to.client.NegotiateAPIVersion(o.ctx)\n\n\treturn o, nil\n}\n\n// WithBufferedOpener buffers the image.\nfunc WithBufferedOpener() Option {\n\treturn func(o *options) {\n\t\to.buffered = true\n\t}\n}\n\n// WithUnbufferedOpener streams the image to avoid buffering.\nfunc WithUnbufferedOpener() Option {\n\treturn func(o *options) {\n\t\to.buffered = false\n\t}\n}\n\n// WithClient is a functional option to allow injecting a docker client.\n//\n// By default, github.com/docker/docker/client.FromEnv is used.\nfunc WithClient(client Client) Option {\n\treturn func(o *options) {\n\t\to.client = client\n\t}\n}\n\n// WithContext is a functional option to pass through a context.Context.\n//\n// By default, context.Background() is used.\nfunc WithContext(ctx context.Context) Option {\n\treturn func(o *options) {\n\t\to.ctx = ctx\n\t}\n}\n\n// Client represents the subset of a docker client that the daemon\n// package uses.\ntype Client interface {\n\tNegotiateAPIVersion(ctx context.Context)\n\tImageSave(context.Context, []string) (io.ReadCloser, error)\n\tImageLoad(context.Context, io.Reader, bool) (types.ImageLoadResponse, error)\n\tImageTag(context.Context, string, string) error\n\tImageInspectWithRaw(context.Context, string) (types.ImageInspect, []byte, error)\n\tImageHistory(context.Context, string) ([]api.HistoryResponseItem, error)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/daemon/write.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage daemon\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n)\n\n// Tag adds a tag to an already existent image.\nfunc Tag(src, dest name.Tag, options ...Option) error {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn o.client.ImageTag(o.ctx, src.String(), dest.String())\n}\n\n// Write saves the image into the daemon as the given tag.\nfunc Write(tag name.Tag, img v1.Image, options ...Option) (string, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// If we already have this image by this image ID, we can skip loading it.\n\tid, err := img.ConfigName()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"computing image ID: %w\", err)\n\t}\n\tif resp, _, err := o.client.ImageInspectWithRaw(o.ctx, id.String()); err == nil {\n\t\twant := tag.String()\n\n\t\t// If we already have this tag, we can skip tagging it.\n\t\tfor _, have := range resp.RepoTags {\n\t\t\tif have == want {\n\t\t\t\treturn \"\", nil\n\t\t\t}\n\t\t}\n\n\t\treturn \"\", o.client.ImageTag(o.ctx, id.String(), want)\n\t}\n\n\tpr, pw := io.Pipe()\n\tgo func() {\n\t\tpw.CloseWithError(tarball.Write(tag, img, pw))\n\t}()\n\n\t// write the image in docker save format first, then load it\n\tresp, err := o.client.ImageLoad(o.ctx, pr, false)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error loading image: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\tb, err := io.ReadAll(resp.Body)\n\tresponse := string(b)\n\tif err != nil {\n\t\treturn response, fmt.Errorf(\"error reading load response body: %w\", err)\n\t}\n\treturn response, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// +k8s:deepcopy-gen=package\n\n// Package v1 defines structured types for OCI v1 images\npackage v1\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/empty/README.md",
    "content": "# `empty`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/empty?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/empty)\n\nThe empty packages provides an empty base for constructing a `v1.Image` or `v1.ImageIndex`.\nThis is especially useful when paired with the [`mutate`](/pkg/v1/mutate) package,\nsee [`mutate.Append`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/mutate#Append)\nand [`mutate.AppendManifests`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/mutate#AppendManifests).\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/empty/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package empty provides an implementation of v1.Image equivalent to \"FROM scratch\".\npackage empty\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/empty/image.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage empty\n\nimport (\n\t\"fmt\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// Image is a singleton empty image, think: FROM scratch.\nvar Image, _ = partial.UncompressedToImage(emptyImage{})\n\ntype emptyImage struct{}\n\n// MediaType implements partial.UncompressedImageCore.\nfunc (i emptyImage) MediaType() (types.MediaType, error) {\n\treturn types.DockerManifestSchema2, nil\n}\n\n// RawConfigFile implements partial.UncompressedImageCore.\nfunc (i emptyImage) RawConfigFile() ([]byte, error) {\n\treturn partial.RawConfigFile(i)\n}\n\n// ConfigFile implements v1.Image.\nfunc (i emptyImage) ConfigFile() (*v1.ConfigFile, error) {\n\treturn &v1.ConfigFile{\n\t\tRootFS: v1.RootFS{\n\t\t\t// Some clients check this.\n\t\t\tType: \"layers\",\n\t\t},\n\t}, nil\n}\n\nfunc (i emptyImage) LayerByDiffID(h v1.Hash) (partial.UncompressedLayer, error) {\n\treturn nil, fmt.Errorf(\"LayerByDiffID(%s): empty image\", h)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/empty/index.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage empty\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// Index is a singleton empty index, think: FROM scratch.\nvar Index = emptyIndex{}\n\ntype emptyIndex struct{}\n\nfunc (i emptyIndex) MediaType() (types.MediaType, error) {\n\treturn types.OCIImageIndex, nil\n}\n\nfunc (i emptyIndex) Digest() (v1.Hash, error) {\n\treturn partial.Digest(i)\n}\n\nfunc (i emptyIndex) Size() (int64, error) {\n\treturn partial.Size(i)\n}\n\nfunc (i emptyIndex) IndexManifest() (*v1.IndexManifest, error) {\n\treturn base(), nil\n}\n\nfunc (i emptyIndex) RawManifest() ([]byte, error) {\n\treturn json.Marshal(base())\n}\n\nfunc (i emptyIndex) Image(v1.Hash) (v1.Image, error) {\n\treturn nil, errors.New(\"empty index\")\n}\n\nfunc (i emptyIndex) ImageIndex(v1.Hash) (v1.ImageIndex, error) {\n\treturn nil, errors.New(\"empty index\")\n}\n\nfunc base() *v1.IndexManifest {\n\treturn &v1.IndexManifest{\n\t\tSchemaVersion: 2,\n\t\tMediaType:     types.OCIImageIndex,\n\t\tManifests:     []v1.Descriptor{},\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/hash.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\nimport (\n\t\"crypto\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Hash is an unqualified digest of some content, e.g. sha256:deadbeef\ntype Hash struct {\n\t// Algorithm holds the algorithm used to compute the hash.\n\tAlgorithm string\n\n\t// Hex holds the hex portion of the content hash.\n\tHex string\n}\n\n// String reverses NewHash returning the string-form of the hash.\nfunc (h Hash) String() string {\n\treturn fmt.Sprintf(\"%s:%s\", h.Algorithm, h.Hex)\n}\n\n// NewHash validates the input string is a hash and returns a strongly type Hash object.\nfunc NewHash(s string) (Hash, error) {\n\th := Hash{}\n\tif err := h.parse(s); err != nil {\n\t\treturn Hash{}, err\n\t}\n\treturn h, nil\n}\n\n// MarshalJSON implements json.Marshaler\nfunc (h Hash) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(h.String())\n}\n\n// UnmarshalJSON implements json.Unmarshaler\nfunc (h *Hash) UnmarshalJSON(data []byte) error {\n\ts, err := strconv.Unquote(string(data))\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn h.parse(s)\n}\n\n// MarshalText implements encoding.TextMarshaler. This is required to use\n// v1.Hash as a key in a map when marshalling JSON.\nfunc (h Hash) MarshalText() (text []byte, err error) {\n\treturn []byte(h.String()), nil\n}\n\n// UnmarshalText implements encoding.TextUnmarshaler. This is required to use\n// v1.Hash as a key in a map when unmarshalling JSON.\nfunc (h *Hash) UnmarshalText(text []byte) error {\n\treturn h.parse(string(text))\n}\n\n// Hasher returns a hash.Hash for the named algorithm (e.g. \"sha256\")\nfunc Hasher(name string) (hash.Hash, error) {\n\tswitch name {\n\tcase \"sha256\":\n\t\treturn crypto.SHA256.New(), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported hash: %q\", name)\n\t}\n}\n\nfunc (h *Hash) parse(unquoted string) error {\n\tparts := strings.Split(unquoted, \":\")\n\tif len(parts) != 2 {\n\t\treturn fmt.Errorf(\"cannot parse hash: %q\", unquoted)\n\t}\n\n\trest := strings.TrimLeft(parts[1], \"0123456789abcdef\")\n\tif len(rest) != 0 {\n\t\treturn fmt.Errorf(\"found non-hex character in hash: %c\", rest[0])\n\t}\n\n\thasher, err := Hasher(parts[0])\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Compare the hex to the expected size (2 hex characters per byte)\n\tif len(parts[1]) != hasher.Size()*2 {\n\t\treturn fmt.Errorf(\"wrong number of hex digits for %s: %s\", parts[0], parts[1])\n\t}\n\n\th.Algorithm = parts[0]\n\th.Hex = parts[1]\n\treturn nil\n}\n\n// SHA256 computes the Hash of the provided io.Reader's content.\nfunc SHA256(r io.Reader) (Hash, int64, error) {\n\thasher := crypto.SHA256.New()\n\tn, err := io.Copy(hasher, r)\n\tif err != nil {\n\t\treturn Hash{}, 0, err\n\t}\n\treturn Hash{\n\t\tAlgorithm: \"sha256\",\n\t\tHex:       hex.EncodeToString(hasher.Sum(make([]byte, 0, hasher.Size()))),\n\t}, n, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/image.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// Image defines the interface for interacting with an OCI v1 image.\ntype Image interface {\n\t// Layers returns the ordered collection of filesystem layers that comprise this image.\n\t// The order of the list is oldest/base layer first, and most-recent/top layer last.\n\tLayers() ([]Layer, error)\n\n\t// MediaType of this image's manifest.\n\tMediaType() (types.MediaType, error)\n\n\t// Size returns the size of the manifest.\n\tSize() (int64, error)\n\n\t// ConfigName returns the hash of the image's config file, also known as\n\t// the Image ID.\n\tConfigName() (Hash, error)\n\n\t// ConfigFile returns this image's config file.\n\tConfigFile() (*ConfigFile, error)\n\n\t// RawConfigFile returns the serialized bytes of ConfigFile().\n\tRawConfigFile() ([]byte, error)\n\n\t// Digest returns the sha256 of this image's manifest.\n\tDigest() (Hash, error)\n\n\t// Manifest returns this image's Manifest object.\n\tManifest() (*Manifest, error)\n\n\t// RawManifest returns the serialized bytes of Manifest()\n\tRawManifest() ([]byte, error)\n\n\t// LayerByDigest returns a Layer for interacting with a particular layer of\n\t// the image, looking it up by \"digest\" (the compressed hash).\n\tLayerByDigest(Hash) (Layer, error)\n\n\t// LayerByDiffID is an analog to LayerByDigest, looking up by \"diff id\"\n\t// (the uncompressed hash).\n\tLayerByDiffID(Hash) (Layer, error)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/index.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// ImageIndex defines the interface for interacting with an OCI image index.\ntype ImageIndex interface {\n\t// MediaType of this image's manifest.\n\tMediaType() (types.MediaType, error)\n\n\t// Digest returns the sha256 of this index's manifest.\n\tDigest() (Hash, error)\n\n\t// Size returns the size of the manifest.\n\tSize() (int64, error)\n\n\t// IndexManifest returns this image index's manifest object.\n\tIndexManifest() (*IndexManifest, error)\n\n\t// RawManifest returns the serialized bytes of IndexManifest().\n\tRawManifest() ([]byte, error)\n\n\t// Image returns a v1.Image that this ImageIndex references.\n\tImage(Hash) (Image, error)\n\n\t// ImageIndex returns a v1.ImageIndex that this ImageIndex references.\n\tImageIndex(Hash) (ImageIndex, error)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layer.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\nimport (\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// Layer is an interface for accessing the properties of a particular layer of a v1.Image\ntype Layer interface {\n\t// Digest returns the Hash of the compressed layer.\n\tDigest() (Hash, error)\n\n\t// DiffID returns the Hash of the uncompressed layer.\n\tDiffID() (Hash, error)\n\n\t// Compressed returns an io.ReadCloser for the compressed layer contents.\n\tCompressed() (io.ReadCloser, error)\n\n\t// Uncompressed returns an io.ReadCloser for the uncompressed layer contents.\n\tUncompressed() (io.ReadCloser, error)\n\n\t// Size returns the compressed size of the Layer.\n\tSize() (int64, error)\n\n\t// MediaType returns the media type of the Layer.\n\tMediaType() (types.MediaType, error)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/README.md",
    "content": "# `layout`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/layout?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/layout)\n\nThe `layout` package implements support for interacting with an [OCI Image Layout](https://github.com/opencontainers/image-spec/blob/master/image-layout.md).\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/blob.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage layout\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\n// Blob returns a blob with the given hash from the Path.\nfunc (l Path) Blob(h v1.Hash) (io.ReadCloser, error) {\n\treturn os.Open(l.blobPath(h))\n}\n\n// Bytes is a convenience function to return a blob from the Path as\n// a byte slice.\nfunc (l Path) Bytes(h v1.Hash) ([]byte, error) {\n\treturn os.ReadFile(l.blobPath(h))\n}\n\nfunc (l Path) blobPath(h v1.Hash) string {\n\treturn l.path(\"blobs\", h.Algorithm, h.Hex)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package layout provides facilities for reading/writing artifacts from/to\n// an OCI image layout on disk, see:\n//\n// https://github.com/opencontainers/image-spec/blob/master/image-layout.md\npackage layout\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/gc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// This is an EXPERIMENTAL package, and may change in arbitrary ways without notice.\npackage layout\n\nimport (\n\t\"fmt\"\n\t\"io/fs\"\n\t\"path/filepath\"\n\t\"strings\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\n// GarbageCollect removes unreferenced blobs from the oci-layout\n//\n//\tThis is an experimental api, and not subject to any stability guarantees\n//\tWe may abandon it at any time, without prior notice.\n//\tDeprecated: Use it at your own risk!\nfunc (l Path) GarbageCollect() ([]v1.Hash, error) {\n\tidx, err := l.ImageIndex()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tblobsToKeep := map[string]bool{}\n\tif err := l.garbageCollectImageIndex(idx, blobsToKeep); err != nil {\n\t\treturn nil, err\n\t}\n\tblobsDir := l.path(\"blobs\")\n\tremovedBlobs := []v1.Hash{}\n\n\terr = filepath.WalkDir(blobsDir, func(path string, d fs.DirEntry, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif d.IsDir() {\n\t\t\treturn nil\n\t\t}\n\n\t\trel, err := filepath.Rel(blobsDir, path)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\thashString := strings.Replace(rel, \"/\", \":\", 1)\n\t\tif present := blobsToKeep[hashString]; !present {\n\t\t\th, err := v1.NewHash(hashString)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tremovedBlobs = append(removedBlobs, h)\n\t\t}\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn removedBlobs, nil\n}\n\nfunc (l Path) garbageCollectImageIndex(index v1.ImageIndex, blobsToKeep map[string]bool) error {\n\tidxm, err := index.IndexManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\th, err := index.Digest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tblobsToKeep[h.String()] = true\n\n\tfor _, descriptor := range idxm.Manifests {\n\t\tif descriptor.MediaType.IsImage() {\n\t\t\timg, err := index.Image(descriptor.Digest)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := l.garbageCollectImage(img, blobsToKeep); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else if descriptor.MediaType.IsIndex() {\n\t\t\tidx, err := index.ImageIndex(descriptor.Digest)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := l.garbageCollectImageIndex(idx, blobsToKeep); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"gc: unknown media type: %s\", descriptor.MediaType)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (l Path) garbageCollectImage(image v1.Image, blobsToKeep map[string]bool) error {\n\th, err := image.Digest()\n\tif err != nil {\n\t\treturn err\n\t}\n\tblobsToKeep[h.String()] = true\n\n\th, err = image.ConfigName()\n\tif err != nil {\n\t\treturn err\n\t}\n\tblobsToKeep[h.String()] = true\n\n\tls, err := image.Layers()\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor _, l := range ls {\n\t\th, err := l.Digest()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tblobsToKeep[h.String()] = true\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/image.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage layout\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype layoutImage struct {\n\tpath         Path\n\tdesc         v1.Descriptor\n\tmanifestLock sync.Mutex // Protects rawManifest\n\trawManifest  []byte\n}\n\nvar _ partial.CompressedImageCore = (*layoutImage)(nil)\n\n// Image reads a v1.Image with digest h from the Path.\nfunc (l Path) Image(h v1.Hash) (v1.Image, error) {\n\tii, err := l.ImageIndex()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn ii.Image(h)\n}\n\nfunc (li *layoutImage) MediaType() (types.MediaType, error) {\n\treturn li.desc.MediaType, nil\n}\n\n// Implements WithManifest for partial.Blobset.\nfunc (li *layoutImage) Manifest() (*v1.Manifest, error) {\n\treturn partial.Manifest(li)\n}\n\nfunc (li *layoutImage) RawManifest() ([]byte, error) {\n\tli.manifestLock.Lock()\n\tdefer li.manifestLock.Unlock()\n\tif li.rawManifest != nil {\n\t\treturn li.rawManifest, nil\n\t}\n\n\tb, err := li.path.Bytes(li.desc.Digest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tli.rawManifest = b\n\treturn li.rawManifest, nil\n}\n\nfunc (li *layoutImage) RawConfigFile() ([]byte, error) {\n\tmanifest, err := li.Manifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn li.path.Bytes(manifest.Config.Digest)\n}\n\nfunc (li *layoutImage) LayerByDigest(h v1.Hash) (partial.CompressedLayer, error) {\n\tmanifest, err := li.Manifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif h == manifest.Config.Digest {\n\t\treturn &compressedBlob{\n\t\t\tpath: li.path,\n\t\t\tdesc: manifest.Config,\n\t\t}, nil\n\t}\n\n\tfor _, desc := range manifest.Layers {\n\t\tif h == desc.Digest {\n\t\t\treturn &compressedBlob{\n\t\t\t\tpath: li.path,\n\t\t\t\tdesc: desc,\n\t\t\t}, nil\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"could not find layer in image: %s\", h)\n}\n\ntype compressedBlob struct {\n\tpath Path\n\tdesc v1.Descriptor\n}\n\nfunc (b *compressedBlob) Digest() (v1.Hash, error) {\n\treturn b.desc.Digest, nil\n}\n\nfunc (b *compressedBlob) Compressed() (io.ReadCloser, error) {\n\treturn b.path.Blob(b.desc.Digest)\n}\n\nfunc (b *compressedBlob) Size() (int64, error) {\n\treturn b.desc.Size, nil\n}\n\nfunc (b *compressedBlob) MediaType() (types.MediaType, error) {\n\treturn b.desc.MediaType, nil\n}\n\n// Descriptor implements partial.withDescriptor.\nfunc (b *compressedBlob) Descriptor() (*v1.Descriptor, error) {\n\treturn &b.desc, nil\n}\n\n// See partial.Exists.\nfunc (b *compressedBlob) Exists() (bool, error) {\n\t_, err := os.Stat(b.path.blobPath(b.desc.Digest))\n\tif os.IsNotExist(err) {\n\t\treturn false, nil\n\t}\n\treturn err == nil, err\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/index.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage layout\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nvar _ v1.ImageIndex = (*layoutIndex)(nil)\n\ntype layoutIndex struct {\n\tmediaType types.MediaType\n\tpath      Path\n\trawIndex  []byte\n}\n\n// ImageIndexFromPath is a convenience function which constructs a Path and returns its v1.ImageIndex.\nfunc ImageIndexFromPath(path string) (v1.ImageIndex, error) {\n\tlp, err := FromPath(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn lp.ImageIndex()\n}\n\n// ImageIndex returns a v1.ImageIndex for the Path.\nfunc (l Path) ImageIndex() (v1.ImageIndex, error) {\n\trawIndex, err := os.ReadFile(l.path(\"index.json\"))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tidx := &layoutIndex{\n\t\tmediaType: types.OCIImageIndex,\n\t\tpath:      l,\n\t\trawIndex:  rawIndex,\n\t}\n\n\treturn idx, nil\n}\n\nfunc (i *layoutIndex) MediaType() (types.MediaType, error) {\n\treturn i.mediaType, nil\n}\n\nfunc (i *layoutIndex) Digest() (v1.Hash, error) {\n\treturn partial.Digest(i)\n}\n\nfunc (i *layoutIndex) Size() (int64, error) {\n\treturn partial.Size(i)\n}\n\nfunc (i *layoutIndex) IndexManifest() (*v1.IndexManifest, error) {\n\tvar index v1.IndexManifest\n\terr := json.Unmarshal(i.rawIndex, &index)\n\treturn &index, err\n}\n\nfunc (i *layoutIndex) RawManifest() ([]byte, error) {\n\treturn i.rawIndex, nil\n}\n\nfunc (i *layoutIndex) Image(h v1.Hash) (v1.Image, error) {\n\t// Look up the digest in our manifest first to return a better error.\n\tdesc, err := i.findDescriptor(h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !isExpectedMediaType(desc.MediaType, types.OCIManifestSchema1, types.DockerManifestSchema2) {\n\t\treturn nil, fmt.Errorf(\"unexpected media type for %v: %s\", h, desc.MediaType)\n\t}\n\n\timg := &layoutImage{\n\t\tpath: i.path,\n\t\tdesc: *desc,\n\t}\n\treturn partial.CompressedToImage(img)\n}\n\nfunc (i *layoutIndex) ImageIndex(h v1.Hash) (v1.ImageIndex, error) {\n\t// Look up the digest in our manifest first to return a better error.\n\tdesc, err := i.findDescriptor(h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif !isExpectedMediaType(desc.MediaType, types.OCIImageIndex, types.DockerManifestList) {\n\t\treturn nil, fmt.Errorf(\"unexpected media type for %v: %s\", h, desc.MediaType)\n\t}\n\n\trawIndex, err := i.path.Bytes(h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &layoutIndex{\n\t\tmediaType: desc.MediaType,\n\t\tpath:      i.path,\n\t\trawIndex:  rawIndex,\n\t}, nil\n}\n\nfunc (i *layoutIndex) Blob(h v1.Hash) (io.ReadCloser, error) {\n\treturn i.path.Blob(h)\n}\n\nfunc (i *layoutIndex) findDescriptor(h v1.Hash) (*v1.Descriptor, error) {\n\tim, err := i.IndexManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif h == (v1.Hash{}) {\n\t\tif len(im.Manifests) != 1 {\n\t\t\treturn nil, errors.New(\"oci layout must contain only a single image to be used with layout.Image\")\n\t\t}\n\t\treturn &(im.Manifests)[0], nil\n\t}\n\n\tfor _, desc := range im.Manifests {\n\t\tif desc.Digest == h {\n\t\t\treturn &desc, nil\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"could not find descriptor in index: %s\", h)\n}\n\n// TODO: Pull this out into methods on types.MediaType? e.g. instead, have:\n// * mt.IsIndex()\n// * mt.IsImage()\nfunc isExpectedMediaType(mt types.MediaType, expected ...types.MediaType) bool {\n\tfor _, allowed := range expected {\n\t\tif mt == allowed {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/layoutpath.go",
    "content": "// Copyright 2019 The original author or authors\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//    http://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\npackage layout\n\nimport \"path/filepath\"\n\n// Path represents an OCI image layout rooted in a file system path\ntype Path string\n\nfunc (l Path) path(elem ...string) string {\n\tcomplete := []string{string(l)}\n\treturn filepath.Join(append(complete, elem...)...)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/options.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage layout\n\nimport v1 \"github.com/google/go-containerregistry/pkg/v1\"\n\n// Option is a functional option for Layout.\ntype Option func(*options)\n\ntype options struct {\n\tdescOpts []descriptorOption\n}\n\nfunc makeOptions(opts ...Option) *options {\n\to := &options{\n\t\tdescOpts: []descriptorOption{},\n\t}\n\tfor _, apply := range opts {\n\t\tapply(o)\n\t}\n\treturn o\n}\n\ntype descriptorOption func(*v1.Descriptor)\n\n// WithAnnotations adds annotations to the artifact descriptor.\nfunc WithAnnotations(annotations map[string]string) Option {\n\treturn func(o *options) {\n\t\to.descOpts = append(o.descOpts, func(desc *v1.Descriptor) {\n\t\t\tif desc.Annotations == nil {\n\t\t\t\tdesc.Annotations = make(map[string]string)\n\t\t\t}\n\t\t\tfor k, v := range annotations {\n\t\t\t\tdesc.Annotations[k] = v\n\t\t\t}\n\t\t})\n\t}\n}\n\n// WithURLs adds urls to the artifact descriptor.\nfunc WithURLs(urls []string) Option {\n\treturn func(o *options) {\n\t\to.descOpts = append(o.descOpts, func(desc *v1.Descriptor) {\n\t\t\tif desc.URLs == nil {\n\t\t\t\tdesc.URLs = []string{}\n\t\t\t}\n\t\t\tdesc.URLs = append(desc.URLs, urls...)\n\t\t})\n\t}\n}\n\n// WithPlatform sets the platform of the artifact descriptor.\nfunc WithPlatform(platform v1.Platform) Option {\n\treturn func(o *options) {\n\t\to.descOpts = append(o.descOpts, func(desc *v1.Descriptor) {\n\t\t\tdesc.Platform = &platform\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/read.go",
    "content": "// Copyright 2019 The original author or authors\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//    http://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\npackage layout\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n)\n\n// FromPath reads an OCI image layout at path and constructs a layout.Path.\nfunc FromPath(path string) (Path, error) {\n\t// TODO: check oci-layout exists\n\n\t_, err := os.Stat(filepath.Join(path, \"index.json\"))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn Path(path), nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/layout/write.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage layout\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/match\"\n\t\"github.com/google/go-containerregistry/pkg/v1/mutate\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/stream\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\nvar layoutFile = `{\n    \"imageLayoutVersion\": \"1.0.0\"\n}`\n\n// AppendImage writes a v1.Image to the Path and updates\n// the index.json to reference it.\nfunc (l Path) AppendImage(img v1.Image, options ...Option) error {\n\tif err := l.WriteImage(img); err != nil {\n\t\treturn err\n\t}\n\n\tdesc, err := partial.Descriptor(img)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\to := makeOptions(options...)\n\tfor _, opt := range o.descOpts {\n\t\topt(desc)\n\t}\n\n\treturn l.AppendDescriptor(*desc)\n}\n\n// AppendIndex writes a v1.ImageIndex to the Path and updates\n// the index.json to reference it.\nfunc (l Path) AppendIndex(ii v1.ImageIndex, options ...Option) error {\n\tif err := l.WriteIndex(ii); err != nil {\n\t\treturn err\n\t}\n\n\tdesc, err := partial.Descriptor(ii)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\to := makeOptions(options...)\n\tfor _, opt := range o.descOpts {\n\t\topt(desc)\n\t}\n\n\treturn l.AppendDescriptor(*desc)\n}\n\n// AppendDescriptor adds a descriptor to the index.json of the Path.\nfunc (l Path) AppendDescriptor(desc v1.Descriptor) error {\n\tii, err := l.ImageIndex()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tindex, err := ii.IndexManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tindex.Manifests = append(index.Manifests, desc)\n\n\trawIndex, err := json.MarshalIndent(index, \"\", \"   \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn l.WriteFile(\"index.json\", rawIndex, os.ModePerm)\n}\n\n// ReplaceImage writes a v1.Image to the Path and updates\n// the index.json to reference it, replacing any existing one that matches matcher, if found.\nfunc (l Path) ReplaceImage(img v1.Image, matcher match.Matcher, options ...Option) error {\n\tif err := l.WriteImage(img); err != nil {\n\t\treturn err\n\t}\n\n\treturn l.replaceDescriptor(img, matcher, options...)\n}\n\n// ReplaceIndex writes a v1.ImageIndex to the Path and updates\n// the index.json to reference it, replacing any existing one that matches matcher, if found.\nfunc (l Path) ReplaceIndex(ii v1.ImageIndex, matcher match.Matcher, options ...Option) error {\n\tif err := l.WriteIndex(ii); err != nil {\n\t\treturn err\n\t}\n\n\treturn l.replaceDescriptor(ii, matcher, options...)\n}\n\n// replaceDescriptor adds a descriptor to the index.json of the Path, replacing\n// any one matching matcher, if found.\nfunc (l Path) replaceDescriptor(append mutate.Appendable, matcher match.Matcher, options ...Option) error {\n\tii, err := l.ImageIndex()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdesc, err := partial.Descriptor(append)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\to := makeOptions(options...)\n\tfor _, opt := range o.descOpts {\n\t\topt(desc)\n\t}\n\n\tadd := mutate.IndexAddendum{\n\t\tAdd:        append,\n\t\tDescriptor: *desc,\n\t}\n\tii = mutate.AppendManifests(mutate.RemoveManifests(ii, matcher), add)\n\n\tindex, err := ii.IndexManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trawIndex, err := json.MarshalIndent(index, \"\", \"   \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn l.WriteFile(\"index.json\", rawIndex, os.ModePerm)\n}\n\n// RemoveDescriptors removes any descriptors that match the match.Matcher from the index.json of the Path.\nfunc (l Path) RemoveDescriptors(matcher match.Matcher) error {\n\tii, err := l.ImageIndex()\n\tif err != nil {\n\t\treturn err\n\t}\n\tii = mutate.RemoveManifests(ii, matcher)\n\n\tindex, err := ii.IndexManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trawIndex, err := json.MarshalIndent(index, \"\", \"   \")\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn l.WriteFile(\"index.json\", rawIndex, os.ModePerm)\n}\n\n// WriteFile write a file with arbitrary data at an arbitrary location in a v1\n// layout. Used mostly internally to write files like \"oci-layout\" and\n// \"index.json\", also can be used to write other arbitrary files. Do *not* use\n// this to write blobs. Use only WriteBlob() for that.\nfunc (l Path) WriteFile(name string, data []byte, perm os.FileMode) error {\n\tif err := os.MkdirAll(l.path(), os.ModePerm); err != nil && !os.IsExist(err) {\n\t\treturn err\n\t}\n\n\treturn os.WriteFile(l.path(name), data, perm)\n}\n\n// WriteBlob copies a file to the blobs/ directory in the Path from the given ReadCloser at\n// blobs/{hash.Algorithm}/{hash.Hex}.\nfunc (l Path) WriteBlob(hash v1.Hash, r io.ReadCloser) error {\n\treturn l.writeBlob(hash, -1, r, nil)\n}\n\nfunc (l Path) writeBlob(hash v1.Hash, size int64, rc io.ReadCloser, renamer func() (v1.Hash, error)) error {\n\tdefer rc.Close()\n\tif hash.Hex == \"\" && renamer == nil {\n\t\tpanic(\"writeBlob called an invalid hash and no renamer\")\n\t}\n\n\tdir := l.path(\"blobs\", hash.Algorithm)\n\tif err := os.MkdirAll(dir, os.ModePerm); err != nil && !os.IsExist(err) {\n\t\treturn err\n\t}\n\n\t// Check if blob already exists and is the correct size\n\tfile := filepath.Join(dir, hash.Hex)\n\tif s, err := os.Stat(file); err == nil && !s.IsDir() && (s.Size() == size || size == -1) {\n\t\treturn nil\n\t}\n\n\t// If a renamer func was provided write to a temporary file\n\topen := func() (*os.File, error) { return os.Create(file) }\n\tif renamer != nil {\n\t\topen = func() (*os.File, error) { return os.CreateTemp(dir, hash.Hex) }\n\t}\n\tw, err := open()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif renamer != nil {\n\t\t// Delete temp file if an error is encountered before renaming\n\t\tdefer func() {\n\t\t\tif err := os.Remove(w.Name()); err != nil && !errors.Is(err, os.ErrNotExist) {\n\t\t\t\tlogs.Warn.Printf(\"error removing temporary file after encountering an error while writing blob: %v\", err)\n\t\t\t}\n\t\t}()\n\t}\n\tdefer w.Close()\n\n\t// Write to file and exit if not renaming\n\tif n, err := io.Copy(w, rc); err != nil || renamer == nil {\n\t\treturn err\n\t} else if size != -1 && n != size {\n\t\treturn fmt.Errorf(\"expected blob size %d, but only wrote %d\", size, n)\n\t}\n\n\t// Always close reader before renaming, since Close computes the digest in\n\t// the case of streaming layers. If Close is not called explicitly, it will\n\t// occur in a goroutine that is not guaranteed to succeed before renamer is\n\t// called. When renamer is the layer's Digest method, it can return\n\t// ErrNotComputed.\n\tif err := rc.Close(); err != nil {\n\t\treturn err\n\t}\n\n\t// Always close file before renaming\n\tif err := w.Close(); err != nil {\n\t\treturn err\n\t}\n\n\t// Rename file based on the final hash\n\tfinalHash, err := renamer()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting final digest of layer: %w\", err)\n\t}\n\n\trenamePath := l.path(\"blobs\", finalHash.Algorithm, finalHash.Hex)\n\treturn os.Rename(w.Name(), renamePath)\n}\n\n// writeLayer writes the compressed layer to a blob. Unlike WriteBlob it will\n// write to a temporary file (suffixed with .tmp) within the layout until the\n// compressed reader is fully consumed and written to disk. Also unlike\n// WriteBlob, it will not skip writing and exit without error when a blob file\n// exists, but does not have the correct size. (The blob hash is not\n// considered, because it may be expensive to compute.)\nfunc (l Path) writeLayer(layer v1.Layer) error {\n\td, err := layer.Digest()\n\tif errors.Is(err, stream.ErrNotComputed) {\n\t\t// Allow digest errors, since streams may not have calculated the hash\n\t\t// yet. Instead, use an empty value, which will be transformed into a\n\t\t// random file name with `os.CreateTemp` and the final digest will be\n\t\t// calculated after writing to a temp file and before renaming to the\n\t\t// final path.\n\t\td = v1.Hash{Algorithm: \"sha256\", Hex: \"\"}\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\ts, err := layer.Size()\n\tif errors.Is(err, stream.ErrNotComputed) {\n\t\t// Allow size errors, since streams may not have calculated the size\n\t\t// yet. Instead, use zero as a sentinel value meaning that no size\n\t\t// comparison can be done and any sized blob file should be considered\n\t\t// valid and not overwritten.\n\t\t//\n\t\t// TODO: Provide an option to always overwrite blobs.\n\t\ts = -1\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\tr, err := layer.Compressed()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif err := l.writeBlob(d, s, r, layer.Digest); err != nil {\n\t\treturn fmt.Errorf(\"error writing layer: %w\", err)\n\t}\n\treturn nil\n}\n\n// RemoveBlob removes a file from the blobs directory in the Path\n// at blobs/{hash.Algorithm}/{hash.Hex}\n// It does *not* remove any reference to it from other manifests or indexes, or\n// from the root index.json.\nfunc (l Path) RemoveBlob(hash v1.Hash) error {\n\tdir := l.path(\"blobs\", hash.Algorithm)\n\terr := os.Remove(filepath.Join(dir, hash.Hex))\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// WriteImage writes an image, including its manifest, config and all of its\n// layers, to the blobs directory. If any blob already exists, as determined by\n// the hash filename, does not write it.\n// This function does *not* update the `index.json` file. If you want to write the\n// image and also update the `index.json`, call AppendImage(), which wraps this\n// and also updates the `index.json`.\nfunc (l Path) WriteImage(img v1.Image) error {\n\tlayers, err := img.Layers()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Write the layers concurrently.\n\tvar g errgroup.Group\n\tfor _, layer := range layers {\n\t\tlayer := layer\n\t\tg.Go(func() error {\n\t\t\treturn l.writeLayer(layer)\n\t\t})\n\t}\n\tif err := g.Wait(); err != nil {\n\t\treturn err\n\t}\n\n\t// Write the config.\n\tcfgName, err := img.ConfigName()\n\tif err != nil {\n\t\treturn err\n\t}\n\tcfgBlob, err := img.RawConfigFile()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := l.WriteBlob(cfgName, io.NopCloser(bytes.NewReader(cfgBlob))); err != nil {\n\t\treturn err\n\t}\n\n\t// Write the img manifest.\n\td, err := img.Digest()\n\tif err != nil {\n\t\treturn err\n\t}\n\tmanifest, err := img.RawManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn l.WriteBlob(d, io.NopCloser(bytes.NewReader(manifest)))\n}\n\ntype withLayer interface {\n\tLayer(v1.Hash) (v1.Layer, error)\n}\n\ntype withBlob interface {\n\tBlob(v1.Hash) (io.ReadCloser, error)\n}\n\nfunc (l Path) writeIndexToFile(indexFile string, ii v1.ImageIndex) error {\n\tindex, err := ii.IndexManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Walk the descriptors and write any v1.Image or v1.ImageIndex that we find.\n\t// If we come across something we don't expect, just write it as a blob.\n\tfor _, desc := range index.Manifests {\n\t\tswitch desc.MediaType {\n\t\tcase types.OCIImageIndex, types.DockerManifestList:\n\t\t\tii, err := ii.ImageIndex(desc.Digest)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := l.WriteIndex(ii); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tcase types.OCIManifestSchema1, types.DockerManifestSchema2:\n\t\t\timg, err := ii.Image(desc.Digest)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := l.WriteImage(img); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\tdefault:\n\t\t\t// TODO: The layout could reference arbitrary things, which we should\n\t\t\t// probably just pass through.\n\n\t\t\tvar blob io.ReadCloser\n\t\t\t// Workaround for #819.\n\t\t\tif wl, ok := ii.(withLayer); ok {\n\t\t\t\tlayer, lerr := wl.Layer(desc.Digest)\n\t\t\t\tif lerr != nil {\n\t\t\t\t\treturn lerr\n\t\t\t\t}\n\t\t\t\tblob, err = layer.Compressed()\n\t\t\t} else if wb, ok := ii.(withBlob); ok {\n\t\t\t\tblob, err = wb.Blob(desc.Digest)\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := l.WriteBlob(desc.Digest, blob); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\trawIndex, err := ii.RawManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn l.WriteFile(indexFile, rawIndex, os.ModePerm)\n}\n\n// WriteIndex writes an index to the blobs directory. Walks down the children,\n// including its children manifests and/or indexes, and down the tree until all of\n// config and all layers, have been written. If any blob already exists, as determined by\n// the hash filename, does not write it.\n// This function does *not* update the `index.json` file. If you want to write the\n// index and also update the `index.json`, call AppendIndex(), which wraps this\n// and also updates the `index.json`.\nfunc (l Path) WriteIndex(ii v1.ImageIndex) error {\n\t// Always just write oci-layout file, since it's small.\n\tif err := l.WriteFile(\"oci-layout\", []byte(layoutFile), os.ModePerm); err != nil {\n\t\treturn err\n\t}\n\n\th, err := ii.Digest()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tindexFile := filepath.Join(\"blobs\", h.Algorithm, h.Hex)\n\treturn l.writeIndexToFile(indexFile, ii)\n}\n\n// Write constructs a Path at path from an ImageIndex.\n//\n// The contents are written in the following format:\n// At the top level, there is:\n//\n//\tOne oci-layout file containing the version of this image-layout.\n//\tOne index.json file listing descriptors for the contained images.\n//\n// Under blobs/, there is, for each image:\n//\n//\tOne file for each layer, named after the layer's SHA.\n//\tOne file for each config blob, named after its SHA.\n//\tOne file for each manifest blob, named after its SHA.\nfunc Write(path string, ii v1.ImageIndex) (Path, error) {\n\tlp := Path(path)\n\t// Always just write oci-layout file, since it's small.\n\tif err := lp.WriteFile(\"oci-layout\", []byte(layoutFile), os.ModePerm); err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// TODO create blobs/ in case there is a blobs file which would prevent the directory from being created\n\n\treturn lp, lp.writeIndexToFile(\"index.json\", ii)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/manifest.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// Manifest represents the OCI image manifest in a structured way.\ntype Manifest struct {\n\tSchemaVersion int64             `json:\"schemaVersion\"`\n\tMediaType     types.MediaType   `json:\"mediaType,omitempty\"`\n\tConfig        Descriptor        `json:\"config\"`\n\tLayers        []Descriptor      `json:\"layers\"`\n\tAnnotations   map[string]string `json:\"annotations,omitempty\"`\n\tSubject       *Descriptor       `json:\"subject,omitempty\"`\n}\n\n// IndexManifest represents an OCI image index in a structured way.\ntype IndexManifest struct {\n\tSchemaVersion int64             `json:\"schemaVersion\"`\n\tMediaType     types.MediaType   `json:\"mediaType,omitempty\"`\n\tManifests     []Descriptor      `json:\"manifests\"`\n\tAnnotations   map[string]string `json:\"annotations,omitempty\"`\n\tSubject       *Descriptor       `json:\"subject,omitempty\"`\n}\n\n// Descriptor holds a reference from the manifest to one of its constituent elements.\ntype Descriptor struct {\n\tMediaType    types.MediaType   `json:\"mediaType\"`\n\tSize         int64             `json:\"size\"`\n\tDigest       Hash              `json:\"digest\"`\n\tData         []byte            `json:\"data,omitempty\"`\n\tURLs         []string          `json:\"urls,omitempty\"`\n\tAnnotations  map[string]string `json:\"annotations,omitempty\"`\n\tPlatform     *Platform         `json:\"platform,omitempty\"`\n\tArtifactType string            `json:\"artifactType,omitempty\"`\n}\n\n// ParseManifest parses the io.Reader's contents into a Manifest.\nfunc ParseManifest(r io.Reader) (*Manifest, error) {\n\tm := Manifest{}\n\tif err := json.NewDecoder(r).Decode(&m); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &m, nil\n}\n\n// ParseIndexManifest parses the io.Reader's contents into an IndexManifest.\nfunc ParseIndexManifest(r io.Reader) (*IndexManifest, error) {\n\tim := IndexManifest{}\n\tif err := json.NewDecoder(r).Decode(&im); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &im, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/match/match.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\n// Package match provides functionality for conveniently matching a v1.Descriptor.\npackage match\n\nimport (\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\timagespec \"github.com/opencontainers/image-spec/specs-go/v1\"\n)\n\n// Matcher function that is given a v1.Descriptor, and returns whether or\n// not it matches a given rule. Can match on anything it wants in the Descriptor.\ntype Matcher func(desc v1.Descriptor) bool\n\n// Name returns a match.Matcher that matches based on the value of the\n//\n//\t\"org.opencontainers.image.ref.name\" annotation:\n//\n// github.com/opencontainers/image-spec/blob/v1.0.1/annotations.md#pre-defined-annotation-keys\nfunc Name(name string) Matcher {\n\treturn Annotation(imagespec.AnnotationRefName, name)\n}\n\n// Annotation returns a match.Matcher that matches based on the provided annotation.\nfunc Annotation(key, value string) Matcher {\n\treturn func(desc v1.Descriptor) bool {\n\t\tif desc.Annotations == nil {\n\t\t\treturn false\n\t\t}\n\t\tif aValue, ok := desc.Annotations[key]; ok && aValue == value {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n}\n\n// Platforms returns a match.Matcher that matches on any one of the provided platforms.\n// Ignores any descriptors that do not have a platform.\nfunc Platforms(platforms ...v1.Platform) Matcher {\n\treturn func(desc v1.Descriptor) bool {\n\t\tif desc.Platform == nil {\n\t\t\treturn false\n\t\t}\n\t\tfor _, platform := range platforms {\n\t\t\tif desc.Platform.Equals(platform) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n\n// MediaTypes returns a match.Matcher that matches at least one of the provided media types.\nfunc MediaTypes(mediaTypes ...string) Matcher {\n\tmts := map[string]bool{}\n\tfor _, media := range mediaTypes {\n\t\tmts[media] = true\n\t}\n\treturn func(desc v1.Descriptor) bool {\n\t\tif desc.MediaType == \"\" {\n\t\t\treturn false\n\t\t}\n\t\tif _, ok := mts[string(desc.MediaType)]; ok {\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n}\n\n// Digests returns a match.Matcher that matches at least one of the provided Digests\nfunc Digests(digests ...v1.Hash) Matcher {\n\tdigs := map[v1.Hash]bool{}\n\tfor _, digest := range digests {\n\t\tdigs[digest] = true\n\t}\n\treturn func(desc v1.Descriptor) bool {\n\t\t_, ok := digs[desc.Digest]\n\t\treturn ok\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/mutate/README.md",
    "content": "# `mutate`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/mutate?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/mutate)\n\nThe `v1.Image`, `v1.ImageIndex`, and `v1.Layer` interfaces provide only\naccessor methods, so they are essentially immutable. If you want to change\nsomething about them, you need to produce a new instance of that interface.\n\nA common use case for this library is to read an image from somewhere (a source),\nchange something about it, and write the image somewhere else (a sink).\n\nGraphically, this looks something like:\n\n<p align=\"center\">\n  <img src=\"/images/mutate.dot.svg\" />\n</p>\n\n## Mutations\n\nThis is obviously not a comprehensive set of useful transformations (PRs welcome!),\nbut a rough summary of what the `mutate` package currently does:\n\n### `Config` and `ConfigFile`\n\nThese allow you to change the [image configuration](https://github.com/opencontainers/image-spec/blob/master/config.md#properties),\ne.g. to change the entrypoint, environment, author, etc.\n\n### `Time`, `Canonical`, and `CreatedAt`\n\nThese are useful in the context of [reproducible builds](https://reproducible-builds.org/),\nwhere you may want to strip timestamps and other non-reproducible information.\n\n### `Append`, `AppendLayers`, and `AppendManifests`\n\nThese functions allow the extension of a `v1.Image` or `v1.ImageIndex` with\nnew layers or manifests.\n\nFor constructing an image `FROM scratch`, see the [`empty`](/pkg/v1/empty) package.\n\n### `MediaType` and `IndexMediaType`\n\nSometimes, it is necessary to change the media type of an image or index,\ne.g. to appease a registry with strict validation of images (_looking at you, GCR_).\n\n### `Rebase`\n\nRebase has [its own README](/cmd/crane/rebase.md).\n\nThis is the underlying implementation of [`crane rebase`](https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane_rebase.md).\n\n### `Extract`\n\nExtract will flatten an image filesystem into a single tar stream,\nrespecting whiteout files.\n\nThis is the underlying implementation of [`crane export`](https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane_export.md).\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/mutate/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package mutate provides facilities for mutating v1.Images of any kind.\npackage mutate\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/mutate/image.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage mutate\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"sync\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/stream\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype image struct {\n\tbase v1.Image\n\tadds []Addendum\n\n\tcomputed        bool\n\tconfigFile      *v1.ConfigFile\n\tmanifest        *v1.Manifest\n\tannotations     map[string]string\n\tmediaType       *types.MediaType\n\tconfigMediaType *types.MediaType\n\tdiffIDMap       map[v1.Hash]v1.Layer\n\tdigestMap       map[v1.Hash]v1.Layer\n\tsubject         *v1.Descriptor\n\n\tsync.Mutex\n}\n\nvar _ v1.Image = (*image)(nil)\n\nfunc (i *image) MediaType() (types.MediaType, error) {\n\tif i.mediaType != nil {\n\t\treturn *i.mediaType, nil\n\t}\n\treturn i.base.MediaType()\n}\n\nfunc (i *image) compute() error {\n\ti.Lock()\n\tdefer i.Unlock()\n\n\t// Don't re-compute if already computed.\n\tif i.computed {\n\t\treturn nil\n\t}\n\tvar configFile *v1.ConfigFile\n\tif i.configFile != nil {\n\t\tconfigFile = i.configFile\n\t} else {\n\t\tcf, err := i.base.ConfigFile()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tconfigFile = cf.DeepCopy()\n\t}\n\tdiffIDs := configFile.RootFS.DiffIDs\n\thistory := configFile.History\n\n\tdiffIDMap := make(map[v1.Hash]v1.Layer)\n\tdigestMap := make(map[v1.Hash]v1.Layer)\n\n\tfor _, add := range i.adds {\n\t\thistory = append(history, add.History)\n\t\tif add.Layer != nil {\n\t\t\tdiffID, err := add.Layer.DiffID()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdiffIDs = append(diffIDs, diffID)\n\t\t\tdiffIDMap[diffID] = add.Layer\n\t\t}\n\t}\n\n\tm, err := i.base.Manifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\tmanifest := m.DeepCopy()\n\tmanifestLayers := manifest.Layers\n\tfor _, add := range i.adds {\n\t\tif add.Layer == nil {\n\t\t\t// Empty layers include only history in manifest.\n\t\t\tcontinue\n\t\t}\n\n\t\tdesc, err := partial.Descriptor(add.Layer)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Fields in the addendum override the original descriptor.\n\t\tif len(add.Annotations) != 0 {\n\t\t\tdesc.Annotations = add.Annotations\n\t\t}\n\t\tif len(add.URLs) != 0 {\n\t\t\tdesc.URLs = add.URLs\n\t\t}\n\n\t\tif add.MediaType != \"\" {\n\t\t\tdesc.MediaType = add.MediaType\n\t\t}\n\n\t\tmanifestLayers = append(manifestLayers, *desc)\n\t\tdigestMap[desc.Digest] = add.Layer\n\t}\n\n\tconfigFile.RootFS.DiffIDs = diffIDs\n\tconfigFile.History = history\n\n\tmanifest.Layers = manifestLayers\n\n\trcfg, err := json.Marshal(configFile)\n\tif err != nil {\n\t\treturn err\n\t}\n\td, sz, err := v1.SHA256(bytes.NewBuffer(rcfg))\n\tif err != nil {\n\t\treturn err\n\t}\n\tmanifest.Config.Digest = d\n\tmanifest.Config.Size = sz\n\n\t// If Data was set in the base image, we need to update it in the mutated image.\n\tif m.Config.Data != nil {\n\t\tmanifest.Config.Data = rcfg\n\t}\n\n\t// If the user wants to mutate the media type of the config\n\tif i.configMediaType != nil {\n\t\tmanifest.Config.MediaType = *i.configMediaType\n\t}\n\n\tif i.mediaType != nil {\n\t\tmanifest.MediaType = *i.mediaType\n\t}\n\n\tif i.annotations != nil {\n\t\tif manifest.Annotations == nil {\n\t\t\tmanifest.Annotations = map[string]string{}\n\t\t}\n\n\t\tfor k, v := range i.annotations {\n\t\t\tmanifest.Annotations[k] = v\n\t\t}\n\t}\n\tmanifest.Subject = i.subject\n\n\ti.configFile = configFile\n\ti.manifest = manifest\n\ti.diffIDMap = diffIDMap\n\ti.digestMap = digestMap\n\ti.computed = true\n\treturn nil\n}\n\n// Layers returns the ordered collection of filesystem layers that comprise this image.\n// The order of the list is oldest/base layer first, and most-recent/top layer last.\nfunc (i *image) Layers() ([]v1.Layer, error) {\n\tif err := i.compute(); errors.Is(err, stream.ErrNotComputed) {\n\t\t// Image contains a streamable layer which has not yet been\n\t\t// consumed. Just return the layers we have in case the caller\n\t\t// is going to consume the layers.\n\t\tlayers, err := i.base.Layers()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, add := range i.adds {\n\t\t\tlayers = append(layers, add.Layer)\n\t\t}\n\t\treturn layers, nil\n\t} else if err != nil {\n\t\treturn nil, err\n\t}\n\n\tdiffIDs, err := partial.DiffIDs(i)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tls := make([]v1.Layer, 0, len(diffIDs))\n\tfor _, h := range diffIDs {\n\t\tl, err := i.LayerByDiffID(h)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tls = append(ls, l)\n\t}\n\treturn ls, nil\n}\n\n// ConfigName returns the hash of the image's config file.\nfunc (i *image) ConfigName() (v1.Hash, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\treturn partial.ConfigName(i)\n}\n\n// ConfigFile returns this image's config file.\nfunc (i *image) ConfigFile() (*v1.ConfigFile, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.configFile.DeepCopy(), nil\n}\n\n// RawConfigFile returns the serialized bytes of ConfigFile()\nfunc (i *image) RawConfigFile() ([]byte, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(i.configFile)\n}\n\n// Digest returns the sha256 of this image's manifest.\nfunc (i *image) Digest() (v1.Hash, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\treturn partial.Digest(i)\n}\n\n// Size implements v1.Image.\nfunc (i *image) Size() (int64, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn -1, err\n\t}\n\treturn partial.Size(i)\n}\n\n// Manifest returns this image's Manifest object.\nfunc (i *image) Manifest() (*v1.Manifest, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.manifest.DeepCopy(), nil\n}\n\n// RawManifest returns the serialized bytes of Manifest()\nfunc (i *image) RawManifest() ([]byte, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(i.manifest)\n}\n\n// LayerByDigest returns a Layer for interacting with a particular layer of\n// the image, looking it up by \"digest\" (the compressed hash).\nfunc (i *image) LayerByDigest(h v1.Hash) (v1.Layer, error) {\n\tif cn, err := i.ConfigName(); err != nil {\n\t\treturn nil, err\n\t} else if h == cn {\n\t\treturn partial.ConfigLayer(i)\n\t}\n\tif layer, ok := i.digestMap[h]; ok {\n\t\treturn layer, nil\n\t}\n\treturn i.base.LayerByDigest(h)\n}\n\n// LayerByDiffID is an analog to LayerByDigest, looking up by \"diff id\"\n// (the uncompressed hash).\nfunc (i *image) LayerByDiffID(h v1.Hash) (v1.Layer, error) {\n\tif layer, ok := i.diffIDMap[h]; ok {\n\t\treturn layer, nil\n\t}\n\treturn i.base.LayerByDiffID(h)\n}\n\nfunc validate(adds []Addendum) error {\n\tfor _, add := range adds {\n\t\tif add.Layer == nil && !add.History.EmptyLayer {\n\t\t\treturn errors.New(\"unable to add a nil layer to the image\")\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/mutate/index.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage mutate\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/match\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/stream\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nfunc computeDescriptor(ia IndexAddendum) (*v1.Descriptor, error) {\n\tdesc, err := partial.Descriptor(ia.Add)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// The IndexAddendum allows overriding Descriptor values.\n\tif ia.Descriptor.Size != 0 {\n\t\tdesc.Size = ia.Descriptor.Size\n\t}\n\tif string(ia.Descriptor.MediaType) != \"\" {\n\t\tdesc.MediaType = ia.Descriptor.MediaType\n\t}\n\tif ia.Descriptor.Digest != (v1.Hash{}) {\n\t\tdesc.Digest = ia.Descriptor.Digest\n\t}\n\tif ia.Descriptor.Platform != nil {\n\t\tdesc.Platform = ia.Descriptor.Platform\n\t}\n\tif len(ia.Descriptor.URLs) != 0 {\n\t\tdesc.URLs = ia.Descriptor.URLs\n\t}\n\tif len(ia.Descriptor.Annotations) != 0 {\n\t\tdesc.Annotations = ia.Descriptor.Annotations\n\t}\n\tif ia.Descriptor.Data != nil {\n\t\tdesc.Data = ia.Descriptor.Data\n\t}\n\n\treturn desc, nil\n}\n\ntype index struct {\n\tbase v1.ImageIndex\n\tadds []IndexAddendum\n\t// remove is removed before adds\n\tremove match.Matcher\n\n\tcomputed    bool\n\tmanifest    *v1.IndexManifest\n\tannotations map[string]string\n\tmediaType   *types.MediaType\n\timageMap    map[v1.Hash]v1.Image\n\tindexMap    map[v1.Hash]v1.ImageIndex\n\tlayerMap    map[v1.Hash]v1.Layer\n\tsubject     *v1.Descriptor\n\n\tsync.Mutex\n}\n\nvar _ v1.ImageIndex = (*index)(nil)\n\nfunc (i *index) MediaType() (types.MediaType, error) {\n\tif i.mediaType != nil {\n\t\treturn *i.mediaType, nil\n\t}\n\treturn i.base.MediaType()\n}\n\nfunc (i *index) Size() (int64, error) { return partial.Size(i) }\n\nfunc (i *index) compute() error {\n\ti.Lock()\n\tdefer i.Unlock()\n\n\t// Don't re-compute if already computed.\n\tif i.computed {\n\t\treturn nil\n\t}\n\n\ti.imageMap = make(map[v1.Hash]v1.Image)\n\ti.indexMap = make(map[v1.Hash]v1.ImageIndex)\n\ti.layerMap = make(map[v1.Hash]v1.Layer)\n\n\tm, err := i.base.IndexManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\tmanifest := m.DeepCopy()\n\tmanifests := manifest.Manifests\n\n\tif i.remove != nil {\n\t\tvar cleanedManifests []v1.Descriptor\n\t\tfor _, m := range manifests {\n\t\t\tif !i.remove(m) {\n\t\t\t\tcleanedManifests = append(cleanedManifests, m)\n\t\t\t}\n\t\t}\n\t\tmanifests = cleanedManifests\n\t}\n\n\tfor _, add := range i.adds {\n\t\tdesc, err := computeDescriptor(add)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tmanifests = append(manifests, *desc)\n\t\tif idx, ok := add.Add.(v1.ImageIndex); ok {\n\t\t\ti.indexMap[desc.Digest] = idx\n\t\t} else if img, ok := add.Add.(v1.Image); ok {\n\t\t\ti.imageMap[desc.Digest] = img\n\t\t} else if l, ok := add.Add.(v1.Layer); ok {\n\t\t\ti.layerMap[desc.Digest] = l\n\t\t} else {\n\t\t\tlogs.Warn.Printf(\"Unexpected index addendum: %T\", add.Add)\n\t\t}\n\t}\n\n\tmanifest.Manifests = manifests\n\n\tif i.mediaType != nil {\n\t\tmanifest.MediaType = *i.mediaType\n\t}\n\n\tif i.annotations != nil {\n\t\tif manifest.Annotations == nil {\n\t\t\tmanifest.Annotations = map[string]string{}\n\t\t}\n\t\tfor k, v := range i.annotations {\n\t\t\tmanifest.Annotations[k] = v\n\t\t}\n\t}\n\tmanifest.Subject = i.subject\n\n\ti.manifest = manifest\n\ti.computed = true\n\treturn nil\n}\n\nfunc (i *index) Image(h v1.Hash) (v1.Image, error) {\n\tif img, ok := i.imageMap[h]; ok {\n\t\treturn img, nil\n\t}\n\treturn i.base.Image(h)\n}\n\nfunc (i *index) ImageIndex(h v1.Hash) (v1.ImageIndex, error) {\n\tif idx, ok := i.indexMap[h]; ok {\n\t\treturn idx, nil\n\t}\n\treturn i.base.ImageIndex(h)\n}\n\ntype withLayer interface {\n\tLayer(v1.Hash) (v1.Layer, error)\n}\n\n// Workaround for #819.\nfunc (i *index) Layer(h v1.Hash) (v1.Layer, error) {\n\tif layer, ok := i.layerMap[h]; ok {\n\t\treturn layer, nil\n\t}\n\tif wl, ok := i.base.(withLayer); ok {\n\t\treturn wl.Layer(h)\n\t}\n\treturn nil, fmt.Errorf(\"layer not found: %s\", h)\n}\n\n// Digest returns the sha256 of this image's manifest.\nfunc (i *index) Digest() (v1.Hash, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\treturn partial.Digest(i)\n}\n\n// Manifest returns this image's Manifest object.\nfunc (i *index) IndexManifest() (*v1.IndexManifest, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.manifest.DeepCopy(), nil\n}\n\n// RawManifest returns the serialized bytes of Manifest()\nfunc (i *index) RawManifest() ([]byte, error) {\n\tif err := i.compute(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(i.manifest)\n}\n\nfunc (i *index) Manifests() ([]partial.Describable, error) {\n\tif err := i.compute(); errors.Is(err, stream.ErrNotComputed) {\n\t\t// Index contains a streamable layer which has not yet been\n\t\t// consumed. Just return the manifests we have in case the caller\n\t\t// is going to consume the streamable layers.\n\t\tmanifests, err := partial.Manifests(i.base)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tfor _, add := range i.adds {\n\t\t\tmanifests = append(manifests, add.Add)\n\t\t}\n\t\treturn manifests, nil\n\t} else if err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn partial.ComputeManifests(i)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/mutate/mutate.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage mutate\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/google/go-containerregistry/internal/gzip\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/empty\"\n\t\"github.com/google/go-containerregistry/pkg/v1/match\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nconst whiteoutPrefix = \".wh.\"\n\n// Addendum contains layers and history to be appended\n// to a base image\ntype Addendum struct {\n\tLayer       v1.Layer\n\tHistory     v1.History\n\tURLs        []string\n\tAnnotations map[string]string\n\tMediaType   types.MediaType\n}\n\n// AppendLayers applies layers to a base image.\nfunc AppendLayers(base v1.Image, layers ...v1.Layer) (v1.Image, error) {\n\tadditions := make([]Addendum, 0, len(layers))\n\tfor _, layer := range layers {\n\t\tadditions = append(additions, Addendum{Layer: layer})\n\t}\n\n\treturn Append(base, additions...)\n}\n\n// Append will apply the list of addendums to the base image\nfunc Append(base v1.Image, adds ...Addendum) (v1.Image, error) {\n\tif len(adds) == 0 {\n\t\treturn base, nil\n\t}\n\tif err := validate(adds); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &image{\n\t\tbase: base,\n\t\tadds: adds,\n\t}, nil\n}\n\n// Appendable is an interface that represents something that can be appended\n// to an ImageIndex. We need to be able to construct a v1.Descriptor in order\n// to append something, and this is the minimum required information for that.\ntype Appendable interface {\n\tMediaType() (types.MediaType, error)\n\tDigest() (v1.Hash, error)\n\tSize() (int64, error)\n}\n\n// IndexAddendum represents an appendable thing and all the properties that\n// we may want to override in the resulting v1.Descriptor.\ntype IndexAddendum struct {\n\tAdd Appendable\n\tv1.Descriptor\n}\n\n// AppendManifests appends a manifest to the ImageIndex.\nfunc AppendManifests(base v1.ImageIndex, adds ...IndexAddendum) v1.ImageIndex {\n\treturn &index{\n\t\tbase: base,\n\t\tadds: adds,\n\t}\n}\n\n// RemoveManifests removes any descriptors that match the match.Matcher.\nfunc RemoveManifests(base v1.ImageIndex, matcher match.Matcher) v1.ImageIndex {\n\treturn &index{\n\t\tbase:   base,\n\t\tremove: matcher,\n\t}\n}\n\n// Config mutates the provided v1.Image to have the provided v1.Config\nfunc Config(base v1.Image, cfg v1.Config) (v1.Image, error) {\n\tcf, err := base.ConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcf.Config = cfg\n\n\treturn ConfigFile(base, cf)\n}\n\n// Subject mutates the subject on an image or index manifest.\n//\n// The input is expected to be a v1.Image or v1.ImageIndex, and\n// returns the same type. You can type-assert the result like so:\n//\n//\timg := Subject(empty.Image, subj).(v1.Image)\n//\n// Or for an index:\n//\n//\tidx := Subject(empty.Index, subj).(v1.ImageIndex)\n//\n// If the input is not an Image or ImageIndex, the result will\n// attempt to lazily annotate the raw manifest.\nfunc Subject(f partial.WithRawManifest, subject v1.Descriptor) partial.WithRawManifest {\n\tif img, ok := f.(v1.Image); ok {\n\t\treturn &image{\n\t\t\tbase:    img,\n\t\t\tsubject: &subject,\n\t\t}\n\t}\n\tif idx, ok := f.(v1.ImageIndex); ok {\n\t\treturn &index{\n\t\t\tbase:    idx,\n\t\t\tsubject: &subject,\n\t\t}\n\t}\n\treturn arbitraryRawManifest{a: f, subject: &subject}\n}\n\n// Annotations mutates the annotations on an annotatable image or index manifest.\n//\n// The annotatable input is expected to be a v1.Image or v1.ImageIndex, and\n// returns the same type. You can type-assert the result like so:\n//\n//\timg := Annotations(empty.Image, map[string]string{\n//\t    \"foo\": \"bar\",\n//\t}).(v1.Image)\n//\n// Or for an index:\n//\n//\tidx := Annotations(empty.Index, map[string]string{\n//\t    \"foo\": \"bar\",\n//\t}).(v1.ImageIndex)\n//\n// If the input Annotatable is not an Image or ImageIndex, the result will\n// attempt to lazily annotate the raw manifest.\nfunc Annotations(f partial.WithRawManifest, anns map[string]string) partial.WithRawManifest {\n\tif img, ok := f.(v1.Image); ok {\n\t\treturn &image{\n\t\t\tbase:        img,\n\t\t\tannotations: anns,\n\t\t}\n\t}\n\tif idx, ok := f.(v1.ImageIndex); ok {\n\t\treturn &index{\n\t\t\tbase:        idx,\n\t\t\tannotations: anns,\n\t\t}\n\t}\n\treturn arbitraryRawManifest{a: f, anns: anns}\n}\n\ntype arbitraryRawManifest struct {\n\ta       partial.WithRawManifest\n\tanns    map[string]string\n\tsubject *v1.Descriptor\n}\n\nfunc (a arbitraryRawManifest) RawManifest() ([]byte, error) {\n\tb, err := a.a.RawManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar m map[string]any\n\tif err := json.Unmarshal(b, &m); err != nil {\n\t\treturn nil, err\n\t}\n\tif ann, ok := m[\"annotations\"]; ok {\n\t\tif annm, ok := ann.(map[string]string); ok {\n\t\t\tfor k, v := range a.anns {\n\t\t\t\tannm[k] = v\n\t\t\t}\n\t\t} else {\n\t\t\treturn nil, fmt.Errorf(\".annotations is not a map: %T\", ann)\n\t\t}\n\t} else {\n\t\tm[\"annotations\"] = a.anns\n\t}\n\tif a.subject != nil {\n\t\tm[\"subject\"] = a.subject\n\t}\n\treturn json.Marshal(m)\n}\n\n// ConfigFile mutates the provided v1.Image to have the provided v1.ConfigFile\nfunc ConfigFile(base v1.Image, cfg *v1.ConfigFile) (v1.Image, error) {\n\tm, err := base.Manifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\timage := &image{\n\t\tbase:       base,\n\t\tmanifest:   m.DeepCopy(),\n\t\tconfigFile: cfg,\n\t}\n\n\treturn image, nil\n}\n\n// CreatedAt mutates the provided v1.Image to have the provided v1.Time\nfunc CreatedAt(base v1.Image, created v1.Time) (v1.Image, error) {\n\tcf, err := base.ConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcfg := cf.DeepCopy()\n\tcfg.Created = created\n\n\treturn ConfigFile(base, cfg)\n}\n\n// Extract takes an image and returns an io.ReadCloser containing the image's\n// flattened filesystem.\n//\n// Callers can read the filesystem contents by passing the reader to\n// tar.NewReader, or io.Copy it directly to some output.\n//\n// If a caller doesn't read the full contents, they should Close it to free up\n// resources used during extraction.\nfunc Extract(img v1.Image) io.ReadCloser {\n\tpr, pw := io.Pipe()\n\n\tgo func() {\n\t\t// Close the writer with any errors encountered during\n\t\t// extraction. These errors will be returned by the reader end\n\t\t// on subsequent reads. If err == nil, the reader will return\n\t\t// EOF.\n\t\tpw.CloseWithError(extract(img, pw))\n\t}()\n\n\treturn pr\n}\n\n// Adapted from https://github.com/google/containerregistry/blob/da03b395ccdc4e149e34fbb540483efce962dc64/client/v2_2/docker_image_.py#L816\nfunc extract(img v1.Image, w io.Writer) error {\n\ttarWriter := tar.NewWriter(w)\n\tdefer tarWriter.Close()\n\n\tfileMap := map[string]bool{}\n\n\tlayers, err := img.Layers()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"retrieving image layers: %w\", err)\n\t}\n\n\t// we iterate through the layers in reverse order because it makes handling\n\t// whiteout layers more efficient, since we can just keep track of the removed\n\t// files as we see .wh. layers and ignore those in previous layers.\n\tfor i := len(layers) - 1; i >= 0; i-- {\n\t\tlayer := layers[i]\n\t\tlayerReader, err := layer.Uncompressed()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"reading layer contents: %w\", err)\n\t\t}\n\t\tdefer layerReader.Close()\n\t\ttarReader := tar.NewReader(layerReader)\n\t\tfor {\n\t\t\theader, err := tarReader.Next()\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"reading tar: %w\", err)\n\t\t\t}\n\n\t\t\t// Some tools prepend everything with \"./\", so if we don't Clean the\n\t\t\t// name, we may have duplicate entries, which angers tar-split.\n\t\t\theader.Name = filepath.Clean(header.Name)\n\t\t\t// force PAX format to remove Name/Linkname length limit of 100 characters\n\t\t\t// required by USTAR and to not depend on internal tar package guess which\n\t\t\t// prefers USTAR over PAX\n\t\t\theader.Format = tar.FormatPAX\n\n\t\t\tbasename := filepath.Base(header.Name)\n\t\t\tdirname := filepath.Dir(header.Name)\n\t\t\ttombstone := strings.HasPrefix(basename, whiteoutPrefix)\n\t\t\tif tombstone {\n\t\t\t\tbasename = basename[len(whiteoutPrefix):]\n\t\t\t}\n\n\t\t\t// check if we have seen value before\n\t\t\t// if we're checking a directory, don't filepath.Join names\n\t\t\tvar name string\n\t\t\tif header.Typeflag == tar.TypeDir {\n\t\t\t\tname = header.Name\n\t\t\t} else {\n\t\t\t\tname = filepath.Join(dirname, basename)\n\t\t\t}\n\n\t\t\tif _, ok := fileMap[name]; ok {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// check for a whited out parent directory\n\t\t\tif inWhiteoutDir(fileMap, name) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// mark file as handled. non-directory implicitly tombstones\n\t\t\t// any entries with a matching (or child) name\n\t\t\tfileMap[name] = tombstone || !(header.Typeflag == tar.TypeDir)\n\t\t\tif !tombstone {\n\t\t\t\tif err := tarWriter.WriteHeader(header); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif header.Size > 0 {\n\t\t\t\t\tif _, err := io.CopyN(tarWriter, tarReader, header.Size); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc inWhiteoutDir(fileMap map[string]bool, file string) bool {\n\tfor {\n\t\tif file == \"\" {\n\t\t\tbreak\n\t\t}\n\t\tdirname := filepath.Dir(file)\n\t\tif file == dirname {\n\t\t\tbreak\n\t\t}\n\t\tif val, ok := fileMap[dirname]; ok && val {\n\t\t\treturn true\n\t\t}\n\t\tfile = dirname\n\t}\n\treturn false\n}\n\nfunc max(a, b int) int {\n\tif a > b {\n\t\treturn a\n\t}\n\treturn b\n}\n\n// Time sets all timestamps in an image to the given timestamp.\nfunc Time(img v1.Image, t time.Time) (v1.Image, error) {\n\tnewImage := empty.Image\n\n\tlayers, err := img.Layers()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting image layers: %w\", err)\n\t}\n\n\tocf, err := img.ConfigFile()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting original config file: %w\", err)\n\t}\n\n\taddendums := make([]Addendum, max(len(ocf.History), len(layers)))\n\tvar historyIdx, addendumIdx int\n\tfor layerIdx := 0; layerIdx < len(layers); addendumIdx, layerIdx = addendumIdx+1, layerIdx+1 {\n\t\tnewLayer, err := layerTime(layers[layerIdx], t)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"setting layer times: %w\", err)\n\t\t}\n\n\t\t// try to search for the history entry that corresponds to this layer\n\t\tfor ; historyIdx < len(ocf.History); historyIdx++ {\n\t\t\taddendums[addendumIdx].History = ocf.History[historyIdx]\n\t\t\t// if it's an EmptyLayer, do not set the Layer and have the Addendum with just the History\n\t\t\t// and move on to the next History entry\n\t\t\tif ocf.History[historyIdx].EmptyLayer {\n\t\t\t\taddendumIdx++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// otherwise, we can exit from the cycle\n\t\t\thistoryIdx++\n\t\t\tbreak\n\t\t}\n\t\tif addendumIdx < len(addendums) {\n\t\t\taddendums[addendumIdx].Layer = newLayer\n\t\t}\n\t}\n\n\t// add all leftover History entries\n\tfor ; historyIdx < len(ocf.History); historyIdx, addendumIdx = historyIdx+1, addendumIdx+1 {\n\t\taddendums[addendumIdx].History = ocf.History[historyIdx]\n\t}\n\n\tnewImage, err = Append(newImage, addendums...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"appending layers: %w\", err)\n\t}\n\n\tcf, err := newImage.ConfigFile()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"setting config file: %w\", err)\n\t}\n\n\tcfg := cf.DeepCopy()\n\n\t// Copy basic config over\n\tcfg.Architecture = ocf.Architecture\n\tcfg.OS = ocf.OS\n\tcfg.OSVersion = ocf.OSVersion\n\tcfg.Config = ocf.Config\n\n\t// Strip away timestamps from the config file\n\tcfg.Created = v1.Time{Time: t}\n\n\tfor i, h := range cfg.History {\n\t\th.Created = v1.Time{Time: t}\n\t\th.CreatedBy = ocf.History[i].CreatedBy\n\t\th.Comment = ocf.History[i].Comment\n\t\th.EmptyLayer = ocf.History[i].EmptyLayer\n\t\t// Explicitly ignore Author field; which hinders reproducibility\n\t\th.Author = \"\"\n\t\tcfg.History[i] = h\n\t}\n\n\treturn ConfigFile(newImage, cfg)\n}\n\nfunc layerTime(layer v1.Layer, t time.Time) (v1.Layer, error) {\n\tlayerReader, err := layer.Uncompressed()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"getting layer: %w\", err)\n\t}\n\tdefer layerReader.Close()\n\tw := new(bytes.Buffer)\n\ttarWriter := tar.NewWriter(w)\n\tdefer tarWriter.Close()\n\n\ttarReader := tar.NewReader(layerReader)\n\tfor {\n\t\theader, err := tarReader.Next()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"reading layer: %w\", err)\n\t\t}\n\n\t\theader.ModTime = t\n\n\t\t//PAX and GNU Format support additional timestamps in the header\n\t\tif header.Format == tar.FormatPAX || header.Format == tar.FormatGNU {\n\t\t\theader.AccessTime = t\n\t\t\theader.ChangeTime = t\n\t\t}\n\n\t\tif err := tarWriter.WriteHeader(header); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"writing tar header: %w\", err)\n\t\t}\n\n\t\tif header.Typeflag == tar.TypeReg {\n\t\t\t// TODO(#1168): This should be lazy, and not buffer the entire layer contents.\n\t\t\tif _, err = io.CopyN(tarWriter, tarReader, header.Size); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"writing layer file: %w\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\tif err := tarWriter.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tb := w.Bytes()\n\t// gzip the contents, then create the layer\n\topener := func() (io.ReadCloser, error) {\n\t\treturn gzip.ReadCloser(io.NopCloser(bytes.NewReader(b))), nil\n\t}\n\tlayer, err = tarball.LayerFromOpener(opener)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating layer: %w\", err)\n\t}\n\n\treturn layer, nil\n}\n\n// Canonical is a helper function to combine Time and configFile\n// to remove any randomness during a docker build.\nfunc Canonical(img v1.Image) (v1.Image, error) {\n\t// Set all timestamps to 0\n\tcreated := time.Time{}\n\timg, err := Time(img, created)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcf, err := img.ConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Get rid of host-dependent random config\n\tcfg := cf.DeepCopy()\n\n\tcfg.Container = \"\"\n\tcfg.Config.Hostname = \"\"\n\tcfg.DockerVersion = \"\"\n\n\treturn ConfigFile(img, cfg)\n}\n\n// MediaType modifies the MediaType() of the given image.\nfunc MediaType(img v1.Image, mt types.MediaType) v1.Image {\n\treturn &image{\n\t\tbase:      img,\n\t\tmediaType: &mt,\n\t}\n}\n\n// ConfigMediaType modifies the MediaType() of the given image's Config.\n//\n// If !mt.IsConfig(), this will be the image's artifactType in any indexes it's a part of.\nfunc ConfigMediaType(img v1.Image, mt types.MediaType) v1.Image {\n\treturn &image{\n\t\tbase:            img,\n\t\tconfigMediaType: &mt,\n\t}\n}\n\n// IndexMediaType modifies the MediaType() of the given index.\nfunc IndexMediaType(idx v1.ImageIndex, mt types.MediaType) v1.ImageIndex {\n\treturn &index{\n\t\tbase:      idx,\n\t\tmediaType: &mt,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/mutate/rebase.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage mutate\n\nimport (\n\t\"fmt\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/empty\"\n)\n\n// Rebase returns a new v1.Image where the oldBase in orig is replaced by newBase.\nfunc Rebase(orig, oldBase, newBase v1.Image) (v1.Image, error) {\n\t// Verify that oldBase's layers are present in orig, otherwise orig is\n\t// not based on oldBase at all.\n\torigLayers, err := orig.Layers()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get layers for original: %w\", err)\n\t}\n\toldBaseLayers, err := oldBase.Layers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(oldBaseLayers) > len(origLayers) {\n\t\treturn nil, fmt.Errorf(\"image %q is not based on %q (too few layers)\", orig, oldBase)\n\t}\n\tfor i, l := range oldBaseLayers {\n\t\toldLayerDigest, err := l.Digest()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get digest of layer %d of %q: %w\", i, oldBase, err)\n\t\t}\n\t\torigLayerDigest, err := origLayers[i].Digest()\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to get digest of layer %d of %q: %w\", i, orig, err)\n\t\t}\n\t\tif oldLayerDigest != origLayerDigest {\n\t\t\treturn nil, fmt.Errorf(\"image %q is not based on %q (layer %d mismatch)\", orig, oldBase, i)\n\t\t}\n\t}\n\n\toldConfig, err := oldBase.ConfigFile()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get config for old base: %w\", err)\n\t}\n\n\torigConfig, err := orig.ConfigFile()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get config for original: %w\", err)\n\t}\n\n\tnewConfig, err := newBase.ConfigFile()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not get config for new base: %w\", err)\n\t}\n\n\t// Stitch together an image that contains:\n\t// - original image's config\n\t// - new base image's os/arch properties\n\t// - new base image's layers + top of original image's layers\n\t// - new base image's history + top of original image's history\n\trebasedImage, err := Config(empty.Image, *origConfig.Config.DeepCopy())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create empty image with original config: %w\", err)\n\t}\n\n\t// Add new config properties from existing images.\n\trebasedConfig, err := rebasedImage.ConfigFile()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not get config for rebased image: %w\", err)\n\t}\n\t// OS/Arch properties from new base\n\trebasedConfig.Architecture = newConfig.Architecture\n\trebasedConfig.OS = newConfig.OS\n\trebasedConfig.OSVersion = newConfig.OSVersion\n\n\t// Apply config properties to rebased.\n\trebasedImage, err = ConfigFile(rebasedImage, rebasedConfig)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to replace config for rebased image: %w\", err)\n\t}\n\n\t// Get new base layers and config for history.\n\tnewBaseLayers, err := newBase.Layers()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"could not get new base layers for new base: %w\", err)\n\t}\n\t// Add new base layers.\n\trebasedImage, err = Append(rebasedImage, createAddendums(0, 0, newConfig.History, newBaseLayers)...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to append new base image: %w\", err)\n\t}\n\n\t// Add original layers above the old base.\n\trebasedImage, err = Append(rebasedImage, createAddendums(len(oldConfig.History), len(oldBaseLayers)+1, origConfig.History, origLayers)...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to append original image: %w\", err)\n\t}\n\n\treturn rebasedImage, nil\n}\n\n// createAddendums makes a list of addendums from a history and layers starting from a specific history and layer\n// indexes.\nfunc createAddendums(startHistory, startLayer int, history []v1.History, layers []v1.Layer) []Addendum {\n\tvar adds []Addendum\n\t// History should be a superset of layers; empty layers (e.g. ENV statements) only exist in history.\n\t// They cannot be iterated identically but must be walked independently, only advancing the iterator for layers\n\t// when a history entry for a non-empty layer is seen.\n\tlayerIndex := 0\n\tfor historyIndex := range history {\n\t\tvar layer v1.Layer\n\t\temptyLayer := history[historyIndex].EmptyLayer\n\t\tif !emptyLayer {\n\t\t\tlayer = layers[layerIndex]\n\t\t\tlayerIndex++\n\t\t}\n\t\tif historyIndex >= startHistory || layerIndex >= startLayer {\n\t\t\tadds = append(adds, Addendum{\n\t\t\t\tLayer:   layer,\n\t\t\t\tHistory: history[historyIndex],\n\t\t\t})\n\t\t}\n\t}\n\t// In the event history was malformed or non-existent, append the remaining layers.\n\tfor i := layerIndex; i < len(layers); i++ {\n\t\tif i >= startLayer {\n\t\t\tadds = append(adds, Addendum{Layer: layers[layerIndex]})\n\t\t}\n\t}\n\n\treturn adds\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/partial/README.md",
    "content": "# `partial`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/partial?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/partial)\n\n## Partial Implementations\n\nThere are roughly two kinds of image representations: compressed and uncompressed.\n\nThe implementations for these kinds of images are almost identical, with the only\nmajor difference being how blobs (config and layers) are fetched. This common\ncode lives in this package, where you provide a _partial_ implementation of a\ncompressed or uncompressed image, and you get back a full `v1.Image` implementation.\n\n### Examples\n\nIn a registry, blobs are compressed, so it's easiest to implement a `v1.Image` in terms\nof compressed layers. `remote.remoteImage` does this by implementing `CompressedImageCore`:\n\n```go\ntype CompressedImageCore interface {\n\tRawConfigFile() ([]byte, error)\n\tMediaType() (types.MediaType, error)\n\tRawManifest() ([]byte, error)\n\tLayerByDigest(v1.Hash) (CompressedLayer, error)\n}\n```\n\nIn a tarball, blobs are (often) uncompressed, so it's easiest to implement a `v1.Image` in terms\nof uncompressed layers. `tarball.uncompressedImage` does this by implementing `UncompressedImageCore`:\n\n```go\ntype UncompressedImageCore interface {\n\tRawConfigFile() ([]byte, error)\n\tMediaType() (types.MediaType, error)\n\tLayerByDiffID(v1.Hash) (UncompressedLayer, error)\n}\n```\n\n## Optional Methods\n\nWhere possible, we access some information via optional methods as an optimization.\n\n### [`partial.Descriptor`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/partial#Descriptor)\n\nThere are some properties of a [`Descriptor`](https://github.com/opencontainers/image-spec/blob/master/descriptor.md#properties) that aren't derivable from just image data:\n\n* `MediaType`\n* `Platform`\n* `URLs`\n* `Annotations`\n\nFor example, in a `tarball.Image`, there is a `LayerSources` field that contains\nan entire layer descriptor with `URLs` information for foreign layers. This\ninformation can be passed through to callers by implementing this optional\n`Descriptor` method.\n\nSee [`#654`](https://github.com/google/go-containerregistry/pull/654).\n\n### [`partial.UncompressedSize`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/partial#UncompressedSize)\n\nUsually, you don't need to know the uncompressed size of a layer, since that\ninformation isn't stored in a config file (just he sha256 is needed); however,\nthere are cases where it is very helpful to know the layer size, e.g. when\nwriting the uncompressed layer into a tarball.\n\nSee [`#655`](https://github.com/google/go-containerregistry/pull/655).\n\n### [`partial.Exists`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/partial#Exists)\n\nWe generally don't care about the existence of something as granular as a\nlayer, and would rather ensure all the invariants of an image are upheld via\nthe `validate` package. However, there are situations where we want to do a\nquick smoke test to ensure that the underlying storage engine hasn't been\ncorrupted by something e.g. deleting files or blobs. Thus, we've exposed an\noptional `Exists` method that does an existence check without actually reading\nany bytes.\n\nThe `remote` package implements this via `HEAD` requests.\n\nThe `layout` package implements this via `os.Stat`.\n\nSee [`#838`](https://github.com/google/go-containerregistry/pull/838).\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/partial/compressed.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage partial\n\nimport (\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/internal/and\"\n\t\"github.com/google/go-containerregistry/internal/compression\"\n\t\"github.com/google/go-containerregistry/internal/gzip\"\n\t\"github.com/google/go-containerregistry/internal/zstd\"\n\tcomp \"github.com/google/go-containerregistry/pkg/compression\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// CompressedLayer represents the bare minimum interface a natively\n// compressed layer must implement for us to produce a v1.Layer\ntype CompressedLayer interface {\n\t// Digest returns the Hash of the compressed layer.\n\tDigest() (v1.Hash, error)\n\n\t// Compressed returns an io.ReadCloser for the compressed layer contents.\n\tCompressed() (io.ReadCloser, error)\n\n\t// Size returns the compressed size of the Layer.\n\tSize() (int64, error)\n\n\t// Returns the mediaType for the compressed Layer\n\tMediaType() (types.MediaType, error)\n}\n\n// compressedLayerExtender implements v1.Image using the compressed base properties.\ntype compressedLayerExtender struct {\n\tCompressedLayer\n}\n\n// Uncompressed implements v1.Layer\nfunc (cle *compressedLayerExtender) Uncompressed() (io.ReadCloser, error) {\n\trc, err := cle.Compressed()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Often, the \"compressed\" bytes are not actually-compressed.\n\t// Peek at the first two bytes to determine whether it's correct to\n\t// wrap this with gzip.UnzipReadCloser or zstd.UnzipReadCloser.\n\tcp, pr, err := compression.PeekCompression(rc)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tprc := &and.ReadCloser{\n\t\tReader:    pr,\n\t\tCloseFunc: rc.Close,\n\t}\n\n\tswitch cp {\n\tcase comp.GZip:\n\t\treturn gzip.UnzipReadCloser(prc)\n\tcase comp.ZStd:\n\t\treturn zstd.UnzipReadCloser(prc)\n\tdefault:\n\t\treturn prc, nil\n\t}\n}\n\n// DiffID implements v1.Layer\nfunc (cle *compressedLayerExtender) DiffID() (v1.Hash, error) {\n\t// If our nested CompressedLayer implements DiffID,\n\t// then delegate to it instead.\n\tif wdi, ok := cle.CompressedLayer.(WithDiffID); ok {\n\t\treturn wdi.DiffID()\n\t}\n\tr, err := cle.Uncompressed()\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\tdefer r.Close()\n\th, _, err := v1.SHA256(r)\n\treturn h, err\n}\n\n// CompressedToLayer fills in the missing methods from a CompressedLayer so that it implements v1.Layer\nfunc CompressedToLayer(ul CompressedLayer) (v1.Layer, error) {\n\treturn &compressedLayerExtender{ul}, nil\n}\n\n// CompressedImageCore represents the base minimum interface a natively\n// compressed image must implement for us to produce a v1.Image.\ntype CompressedImageCore interface {\n\tImageCore\n\n\t// RawManifest returns the serialized bytes of the manifest.\n\tRawManifest() ([]byte, error)\n\n\t// LayerByDigest is a variation on the v1.Image method, which returns\n\t// a CompressedLayer instead.\n\tLayerByDigest(v1.Hash) (CompressedLayer, error)\n}\n\n// compressedImageExtender implements v1.Image by extending CompressedImageCore with the\n// appropriate methods computed from the minimal core.\ntype compressedImageExtender struct {\n\tCompressedImageCore\n}\n\n// Assert that our extender type completes the v1.Image interface\nvar _ v1.Image = (*compressedImageExtender)(nil)\n\n// Digest implements v1.Image\nfunc (i *compressedImageExtender) Digest() (v1.Hash, error) {\n\treturn Digest(i)\n}\n\n// ConfigName implements v1.Image\nfunc (i *compressedImageExtender) ConfigName() (v1.Hash, error) {\n\treturn ConfigName(i)\n}\n\n// Layers implements v1.Image\nfunc (i *compressedImageExtender) Layers() ([]v1.Layer, error) {\n\ths, err := FSLayers(i)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tls := make([]v1.Layer, 0, len(hs))\n\tfor _, h := range hs {\n\t\tl, err := i.LayerByDigest(h)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tls = append(ls, l)\n\t}\n\treturn ls, nil\n}\n\n// LayerByDigest implements v1.Image\nfunc (i *compressedImageExtender) LayerByDigest(h v1.Hash) (v1.Layer, error) {\n\tcl, err := i.CompressedImageCore.LayerByDigest(h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn CompressedToLayer(cl)\n}\n\n// LayerByDiffID implements v1.Image\nfunc (i *compressedImageExtender) LayerByDiffID(h v1.Hash) (v1.Layer, error) {\n\th, err := DiffIDToBlob(i, h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.LayerByDigest(h)\n}\n\n// ConfigFile implements v1.Image\nfunc (i *compressedImageExtender) ConfigFile() (*v1.ConfigFile, error) {\n\treturn ConfigFile(i)\n}\n\n// Manifest implements v1.Image\nfunc (i *compressedImageExtender) Manifest() (*v1.Manifest, error) {\n\treturn Manifest(i)\n}\n\n// Size implements v1.Image\nfunc (i *compressedImageExtender) Size() (int64, error) {\n\treturn Size(i)\n}\n\n// CompressedToImage fills in the missing methods from a CompressedImageCore so that it implements v1.Image\nfunc CompressedToImage(cic CompressedImageCore) (v1.Image, error) {\n\treturn &compressedImageExtender{\n\t\tCompressedImageCore: cic,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/partial/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package partial defines methods for building up a v1.Image from\n// minimal subsets that are sufficient for defining a v1.Image.\npackage partial\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/partial/image.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage partial\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// ImageCore is the core set of properties without which we cannot build a v1.Image\ntype ImageCore interface {\n\t// RawConfigFile returns the serialized bytes of this image's config file.\n\tRawConfigFile() ([]byte, error)\n\n\t// MediaType of this image's manifest.\n\tMediaType() (types.MediaType, error)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/partial/index.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\npackage partial\n\nimport (\n\t\"fmt\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/match\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// FindManifests given a v1.ImageIndex, find the manifests that fit the matcher.\nfunc FindManifests(index v1.ImageIndex, matcher match.Matcher) ([]v1.Descriptor, error) {\n\t// get the actual manifest list\n\tindexManifest, err := index.IndexManifest()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to get raw index: %w\", err)\n\t}\n\tmanifests := []v1.Descriptor{}\n\t// try to get the root of our image\n\tfor _, manifest := range indexManifest.Manifests {\n\t\tif matcher(manifest) {\n\t\t\tmanifests = append(manifests, manifest)\n\t\t}\n\t}\n\treturn manifests, nil\n}\n\n// FindImages given a v1.ImageIndex, find the images that fit the matcher. If a Descriptor\n// matches the provider Matcher, but the referenced item is not an Image, ignores it.\n// Only returns those that match the Matcher and are images.\nfunc FindImages(index v1.ImageIndex, matcher match.Matcher) ([]v1.Image, error) {\n\tmatches := []v1.Image{}\n\tmanifests, err := FindManifests(index, matcher)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, desc := range manifests {\n\t\t// if it is not an image, ignore it\n\t\tif !desc.MediaType.IsImage() {\n\t\t\tcontinue\n\t\t}\n\t\timg, err := index.Image(desc.Digest)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmatches = append(matches, img)\n\t}\n\treturn matches, nil\n}\n\n// FindIndexes given a v1.ImageIndex, find the indexes that fit the matcher. If a Descriptor\n// matches the provider Matcher, but the referenced item is not an Index, ignores it.\n// Only returns those that match the Matcher and are indexes.\nfunc FindIndexes(index v1.ImageIndex, matcher match.Matcher) ([]v1.ImageIndex, error) {\n\tmatches := []v1.ImageIndex{}\n\tmanifests, err := FindManifests(index, matcher)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, desc := range manifests {\n\t\tif !desc.MediaType.IsIndex() {\n\t\t\tcontinue\n\t\t}\n\t\t// if it is not an index, ignore it\n\t\tidx, err := index.ImageIndex(desc.Digest)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmatches = append(matches, idx)\n\t}\n\treturn matches, nil\n}\n\ntype withManifests interface {\n\tManifests() ([]Describable, error)\n}\n\ntype withLayer interface {\n\tLayer(v1.Hash) (v1.Layer, error)\n}\n\ntype describable struct {\n\tdesc v1.Descriptor\n}\n\nfunc (d describable) Digest() (v1.Hash, error) {\n\treturn d.desc.Digest, nil\n}\n\nfunc (d describable) Size() (int64, error) {\n\treturn d.desc.Size, nil\n}\n\nfunc (d describable) MediaType() (types.MediaType, error) {\n\treturn d.desc.MediaType, nil\n}\n\nfunc (d describable) Descriptor() (*v1.Descriptor, error) {\n\treturn &d.desc, nil\n}\n\n// Manifests is analogous to v1.Image.Layers in that it allows values in the\n// returned list to be lazily evaluated, which enables an index to contain\n// an image that contains a streaming layer.\n//\n// This should have been part of the v1.ImageIndex interface, but wasn't.\n// It is instead usable through this extension interface.\nfunc Manifests(idx v1.ImageIndex) ([]Describable, error) {\n\tif wm, ok := idx.(withManifests); ok {\n\t\treturn wm.Manifests()\n\t}\n\n\treturn ComputeManifests(idx)\n}\n\n// ComputeManifests provides a fallback implementation for Manifests.\nfunc ComputeManifests(idx v1.ImageIndex) ([]Describable, error) {\n\tm, err := idx.IndexManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmanifests := []Describable{}\n\tfor _, desc := range m.Manifests {\n\t\tswitch {\n\t\tcase desc.MediaType.IsImage():\n\t\t\timg, err := idx.Image(desc.Digest)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tmanifests = append(manifests, img)\n\t\tcase desc.MediaType.IsIndex():\n\t\t\tidx, err := idx.ImageIndex(desc.Digest)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tmanifests = append(manifests, idx)\n\t\tdefault:\n\t\t\tif wl, ok := idx.(withLayer); ok {\n\t\t\t\tlayer, err := wl.Layer(desc.Digest)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tmanifests = append(manifests, layer)\n\t\t\t} else {\n\t\t\t\tmanifests = append(manifests, describable{desc})\n\t\t\t}\n\t\t}\n\t}\n\n\treturn manifests, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/partial/uncompressed.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage partial\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/internal/gzip\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// UncompressedLayer represents the bare minimum interface a natively\n// uncompressed layer must implement for us to produce a v1.Layer\ntype UncompressedLayer interface {\n\t// DiffID returns the Hash of the uncompressed layer.\n\tDiffID() (v1.Hash, error)\n\n\t// Uncompressed returns an io.ReadCloser for the uncompressed layer contents.\n\tUncompressed() (io.ReadCloser, error)\n\n\t// Returns the mediaType for the compressed Layer\n\tMediaType() (types.MediaType, error)\n}\n\n// uncompressedLayerExtender implements v1.Image using the uncompressed base properties.\ntype uncompressedLayerExtender struct {\n\tUncompressedLayer\n\t// Memoize size/hash so that the methods aren't twice as\n\t// expensive as doing this manually.\n\thash          v1.Hash\n\tsize          int64\n\thashSizeError error\n\tonce          sync.Once\n}\n\n// Compressed implements v1.Layer\nfunc (ule *uncompressedLayerExtender) Compressed() (io.ReadCloser, error) {\n\tu, err := ule.Uncompressed()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn gzip.ReadCloser(u), nil\n}\n\n// Digest implements v1.Layer\nfunc (ule *uncompressedLayerExtender) Digest() (v1.Hash, error) {\n\tule.calcSizeHash()\n\treturn ule.hash, ule.hashSizeError\n}\n\n// Size implements v1.Layer\nfunc (ule *uncompressedLayerExtender) Size() (int64, error) {\n\tule.calcSizeHash()\n\treturn ule.size, ule.hashSizeError\n}\n\nfunc (ule *uncompressedLayerExtender) calcSizeHash() {\n\tule.once.Do(func() {\n\t\tvar r io.ReadCloser\n\t\tr, ule.hashSizeError = ule.Compressed()\n\t\tif ule.hashSizeError != nil {\n\t\t\treturn\n\t\t}\n\t\tdefer r.Close()\n\t\tule.hash, ule.size, ule.hashSizeError = v1.SHA256(r)\n\t})\n}\n\n// UncompressedToLayer fills in the missing methods from an UncompressedLayer so that it implements v1.Layer\nfunc UncompressedToLayer(ul UncompressedLayer) (v1.Layer, error) {\n\treturn &uncompressedLayerExtender{UncompressedLayer: ul}, nil\n}\n\n// UncompressedImageCore represents the bare minimum interface a natively\n// uncompressed image must implement for us to produce a v1.Image\ntype UncompressedImageCore interface {\n\tImageCore\n\n\t// LayerByDiffID is a variation on the v1.Image method, which returns\n\t// an UncompressedLayer instead.\n\tLayerByDiffID(v1.Hash) (UncompressedLayer, error)\n}\n\n// UncompressedToImage fills in the missing methods from an UncompressedImageCore so that it implements v1.Image.\nfunc UncompressedToImage(uic UncompressedImageCore) (v1.Image, error) {\n\treturn &uncompressedImageExtender{\n\t\tUncompressedImageCore: uic,\n\t}, nil\n}\n\n// uncompressedImageExtender implements v1.Image by extending UncompressedImageCore with the\n// appropriate methods computed from the minimal core.\ntype uncompressedImageExtender struct {\n\tUncompressedImageCore\n\n\tlock     sync.Mutex\n\tmanifest *v1.Manifest\n}\n\n// Assert that our extender type completes the v1.Image interface\nvar _ v1.Image = (*uncompressedImageExtender)(nil)\n\n// Digest implements v1.Image\nfunc (i *uncompressedImageExtender) Digest() (v1.Hash, error) {\n\treturn Digest(i)\n}\n\n// Manifest implements v1.Image\nfunc (i *uncompressedImageExtender) Manifest() (*v1.Manifest, error) {\n\ti.lock.Lock()\n\tdefer i.lock.Unlock()\n\tif i.manifest != nil {\n\t\treturn i.manifest, nil\n\t}\n\n\tb, err := i.RawConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcfgHash, cfgSize, err := v1.SHA256(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tm := &v1.Manifest{\n\t\tSchemaVersion: 2,\n\t\tMediaType:     types.DockerManifestSchema2,\n\t\tConfig: v1.Descriptor{\n\t\t\tMediaType: types.DockerConfigJSON,\n\t\t\tSize:      cfgSize,\n\t\t\tDigest:    cfgHash,\n\t\t},\n\t}\n\n\tls, err := i.Layers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tm.Layers = make([]v1.Descriptor, len(ls))\n\tfor i, l := range ls {\n\t\tdesc, err := Descriptor(l)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tm.Layers[i] = *desc\n\t}\n\n\ti.manifest = m\n\treturn i.manifest, nil\n}\n\n// RawManifest implements v1.Image\nfunc (i *uncompressedImageExtender) RawManifest() ([]byte, error) {\n\treturn RawManifest(i)\n}\n\n// Size implements v1.Image\nfunc (i *uncompressedImageExtender) Size() (int64, error) {\n\treturn Size(i)\n}\n\n// ConfigName implements v1.Image\nfunc (i *uncompressedImageExtender) ConfigName() (v1.Hash, error) {\n\treturn ConfigName(i)\n}\n\n// ConfigFile implements v1.Image\nfunc (i *uncompressedImageExtender) ConfigFile() (*v1.ConfigFile, error) {\n\treturn ConfigFile(i)\n}\n\n// Layers implements v1.Image\nfunc (i *uncompressedImageExtender) Layers() ([]v1.Layer, error) {\n\tdiffIDs, err := DiffIDs(i)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tls := make([]v1.Layer, 0, len(diffIDs))\n\tfor _, h := range diffIDs {\n\t\tl, err := i.LayerByDiffID(h)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tls = append(ls, l)\n\t}\n\treturn ls, nil\n}\n\n// LayerByDiffID implements v1.Image\nfunc (i *uncompressedImageExtender) LayerByDiffID(diffID v1.Hash) (v1.Layer, error) {\n\tul, err := i.UncompressedImageCore.LayerByDiffID(diffID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn UncompressedToLayer(ul)\n}\n\n// LayerByDigest implements v1.Image\nfunc (i *uncompressedImageExtender) LayerByDigest(h v1.Hash) (v1.Layer, error) {\n\tdiffID, err := BlobToDiffID(i, h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn i.LayerByDiffID(diffID)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/partial/with.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage partial\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// WithRawConfigFile defines the subset of v1.Image used by these helper methods\ntype WithRawConfigFile interface {\n\t// RawConfigFile returns the serialized bytes of this image's config file.\n\tRawConfigFile() ([]byte, error)\n}\n\n// ConfigFile is a helper for implementing v1.Image\nfunc ConfigFile(i WithRawConfigFile) (*v1.ConfigFile, error) {\n\tb, err := i.RawConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn v1.ParseConfigFile(bytes.NewReader(b))\n}\n\n// ConfigName is a helper for implementing v1.Image\nfunc ConfigName(i WithRawConfigFile) (v1.Hash, error) {\n\tb, err := i.RawConfigFile()\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\th, _, err := v1.SHA256(bytes.NewReader(b))\n\treturn h, err\n}\n\ntype configLayer struct {\n\thash    v1.Hash\n\tcontent []byte\n}\n\n// Digest implements v1.Layer\nfunc (cl *configLayer) Digest() (v1.Hash, error) {\n\treturn cl.hash, nil\n}\n\n// DiffID implements v1.Layer\nfunc (cl *configLayer) DiffID() (v1.Hash, error) {\n\treturn cl.hash, nil\n}\n\n// Uncompressed implements v1.Layer\nfunc (cl *configLayer) Uncompressed() (io.ReadCloser, error) {\n\treturn io.NopCloser(bytes.NewBuffer(cl.content)), nil\n}\n\n// Compressed implements v1.Layer\nfunc (cl *configLayer) Compressed() (io.ReadCloser, error) {\n\treturn io.NopCloser(bytes.NewBuffer(cl.content)), nil\n}\n\n// Size implements v1.Layer\nfunc (cl *configLayer) Size() (int64, error) {\n\treturn int64(len(cl.content)), nil\n}\n\nfunc (cl *configLayer) MediaType() (types.MediaType, error) {\n\t// Defaulting this to OCIConfigJSON as it should remain\n\t// backwards compatible with DockerConfigJSON\n\treturn types.OCIConfigJSON, nil\n}\n\nvar _ v1.Layer = (*configLayer)(nil)\n\n// withConfigLayer allows partial image implementations to provide a layer\n// for their config file.\ntype withConfigLayer interface {\n\tConfigLayer() (v1.Layer, error)\n}\n\n// ConfigLayer implements v1.Layer from the raw config bytes.\n// This is so that clients (e.g. remote) can access the config as a blob.\n//\n// Images that want to return a specific layer implementation can implement\n// withConfigLayer.\nfunc ConfigLayer(i WithRawConfigFile) (v1.Layer, error) {\n\tif wcl, ok := unwrap(i).(withConfigLayer); ok {\n\t\treturn wcl.ConfigLayer()\n\t}\n\n\th, err := ConfigName(i)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trcfg, err := i.RawConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &configLayer{\n\t\thash:    h,\n\t\tcontent: rcfg,\n\t}, nil\n}\n\n// WithConfigFile defines the subset of v1.Image used by these helper methods\ntype WithConfigFile interface {\n\t// ConfigFile returns this image's config file.\n\tConfigFile() (*v1.ConfigFile, error)\n}\n\n// DiffIDs is a helper for implementing v1.Image\nfunc DiffIDs(i WithConfigFile) ([]v1.Hash, error) {\n\tcfg, err := i.ConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn cfg.RootFS.DiffIDs, nil\n}\n\n// RawConfigFile is a helper for implementing v1.Image\nfunc RawConfigFile(i WithConfigFile) ([]byte, error) {\n\tcfg, err := i.ConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(cfg)\n}\n\n// WithRawManifest defines the subset of v1.Image used by these helper methods\ntype WithRawManifest interface {\n\t// RawManifest returns the serialized bytes of this image's config file.\n\tRawManifest() ([]byte, error)\n}\n\n// Digest is a helper for implementing v1.Image\nfunc Digest(i WithRawManifest) (v1.Hash, error) {\n\tmb, err := i.RawManifest()\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\tdigest, _, err := v1.SHA256(bytes.NewReader(mb))\n\treturn digest, err\n}\n\n// Manifest is a helper for implementing v1.Image\nfunc Manifest(i WithRawManifest) (*v1.Manifest, error) {\n\tb, err := i.RawManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn v1.ParseManifest(bytes.NewReader(b))\n}\n\n// WithManifest defines the subset of v1.Image used by these helper methods\ntype WithManifest interface {\n\t// Manifest returns this image's Manifest object.\n\tManifest() (*v1.Manifest, error)\n}\n\n// RawManifest is a helper for implementing v1.Image\nfunc RawManifest(i WithManifest) ([]byte, error) {\n\tm, err := i.Manifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn json.Marshal(m)\n}\n\n// Size is a helper for implementing v1.Image\nfunc Size(i WithRawManifest) (int64, error) {\n\tb, err := i.RawManifest()\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treturn int64(len(b)), nil\n}\n\n// FSLayers is a helper for implementing v1.Image\nfunc FSLayers(i WithManifest) ([]v1.Hash, error) {\n\tm, err := i.Manifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfsl := make([]v1.Hash, len(m.Layers))\n\tfor i, l := range m.Layers {\n\t\tfsl[i] = l.Digest\n\t}\n\treturn fsl, nil\n}\n\n// BlobSize is a helper for implementing v1.Image\nfunc BlobSize(i WithManifest, h v1.Hash) (int64, error) {\n\td, err := BlobDescriptor(i, h)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treturn d.Size, nil\n}\n\n// BlobDescriptor is a helper for implementing v1.Image\nfunc BlobDescriptor(i WithManifest, h v1.Hash) (*v1.Descriptor, error) {\n\tm, err := i.Manifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif m.Config.Digest == h {\n\t\treturn &m.Config, nil\n\t}\n\n\tfor _, l := range m.Layers {\n\t\tif l.Digest == h {\n\t\t\treturn &l, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"blob %v not found\", h)\n}\n\n// WithManifestAndConfigFile defines the subset of v1.Image used by these helper methods\ntype WithManifestAndConfigFile interface {\n\tWithConfigFile\n\n\t// Manifest returns this image's Manifest object.\n\tManifest() (*v1.Manifest, error)\n}\n\n// BlobToDiffID is a helper for mapping between compressed\n// and uncompressed blob hashes.\nfunc BlobToDiffID(i WithManifestAndConfigFile, h v1.Hash) (v1.Hash, error) {\n\tblobs, err := FSLayers(i)\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\tdiffIDs, err := DiffIDs(i)\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\tif len(blobs) != len(diffIDs) {\n\t\treturn v1.Hash{}, fmt.Errorf(\"mismatched fs layers (%d) and diff ids (%d)\", len(blobs), len(diffIDs))\n\t}\n\tfor i, blob := range blobs {\n\t\tif blob == h {\n\t\t\treturn diffIDs[i], nil\n\t\t}\n\t}\n\treturn v1.Hash{}, fmt.Errorf(\"unknown blob %v\", h)\n}\n\n// DiffIDToBlob is a helper for mapping between uncompressed\n// and compressed blob hashes.\nfunc DiffIDToBlob(wm WithManifestAndConfigFile, h v1.Hash) (v1.Hash, error) {\n\tblobs, err := FSLayers(wm)\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\tdiffIDs, err := DiffIDs(wm)\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\tif len(blobs) != len(diffIDs) {\n\t\treturn v1.Hash{}, fmt.Errorf(\"mismatched fs layers (%d) and diff ids (%d)\", len(blobs), len(diffIDs))\n\t}\n\tfor i, diffID := range diffIDs {\n\t\tif diffID == h {\n\t\t\treturn blobs[i], nil\n\t\t}\n\t}\n\treturn v1.Hash{}, fmt.Errorf(\"unknown diffID %v\", h)\n}\n\n// WithDiffID defines the subset of v1.Layer for exposing the DiffID method.\ntype WithDiffID interface {\n\tDiffID() (v1.Hash, error)\n}\n\n// withDescriptor allows partial layer implementations to provide a layer\n// descriptor to the partial image manifest builder. This allows partial\n// uncompressed layers to provide foreign layer metadata like URLs to the\n// uncompressed image manifest.\ntype withDescriptor interface {\n\tDescriptor() (*v1.Descriptor, error)\n}\n\n// Describable represents something for which we can produce a v1.Descriptor.\ntype Describable interface {\n\tDigest() (v1.Hash, error)\n\tMediaType() (types.MediaType, error)\n\tSize() (int64, error)\n}\n\n// Descriptor returns a v1.Descriptor given a Describable. It also encodes\n// some logic for unwrapping things that have been wrapped by\n// CompressedToLayer, UncompressedToLayer, CompressedToImage, or\n// UncompressedToImage.\nfunc Descriptor(d Describable) (*v1.Descriptor, error) {\n\t// If Describable implements Descriptor itself, return that.\n\tif wd, ok := unwrap(d).(withDescriptor); ok {\n\t\treturn wd.Descriptor()\n\t}\n\n\t// If all else fails, compute the descriptor from the individual methods.\n\tvar (\n\t\tdesc v1.Descriptor\n\t\terr  error\n\t)\n\n\tif desc.Size, err = d.Size(); err != nil {\n\t\treturn nil, err\n\t}\n\tif desc.Digest, err = d.Digest(); err != nil {\n\t\treturn nil, err\n\t}\n\tif desc.MediaType, err = d.MediaType(); err != nil {\n\t\treturn nil, err\n\t}\n\tif wat, ok := d.(withArtifactType); ok {\n\t\tif desc.ArtifactType, err = wat.ArtifactType(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\tif wrm, ok := d.(WithRawManifest); ok && desc.MediaType.IsImage() {\n\t\t\tmf, _ := Manifest(wrm)\n\t\t\t// Failing to parse as a manifest should just be ignored.\n\t\t\t// The manifest might not be valid, and that's okay.\n\t\t\tif mf != nil && !mf.Config.MediaType.IsConfig() {\n\t\t\t\tdesc.ArtifactType = string(mf.Config.MediaType)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn &desc, nil\n}\n\ntype withArtifactType interface {\n\tArtifactType() (string, error)\n}\n\ntype withUncompressedSize interface {\n\tUncompressedSize() (int64, error)\n}\n\n// UncompressedSize returns the size of the Uncompressed layer. If the\n// underlying implementation doesn't implement UncompressedSize directly,\n// this will compute the uncompressedSize by reading everything returned\n// by Compressed(). This is potentially expensive and may consume the contents\n// for streaming layers.\nfunc UncompressedSize(l v1.Layer) (int64, error) {\n\t// If the layer implements UncompressedSize itself, return that.\n\tif wus, ok := unwrap(l).(withUncompressedSize); ok {\n\t\treturn wus.UncompressedSize()\n\t}\n\n\t// The layer doesn't implement UncompressedSize, we need to compute it.\n\trc, err := l.Uncompressed()\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\tdefer rc.Close()\n\n\treturn io.Copy(io.Discard, rc)\n}\n\ntype withExists interface {\n\tExists() (bool, error)\n}\n\n// Exists checks to see if a layer exists. This is a hack to work around the\n// mistakes of the partial package. Don't use this.\nfunc Exists(l v1.Layer) (bool, error) {\n\t// If the layer implements Exists itself, return that.\n\tif we, ok := unwrap(l).(withExists); ok {\n\t\treturn we.Exists()\n\t}\n\n\t// The layer doesn't implement Exists, so we hope that calling Compressed()\n\t// is enough to trigger an error if the layer does not exist.\n\trc, err := l.Compressed()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer rc.Close()\n\n\t// We may want to try actually reading a single byte, but if we need to do\n\t// that, we should just fix this hack.\n\treturn true, nil\n}\n\n// Recursively unwrap our wrappers so that we can check for the original implementation.\n// We might want to expose this?\nfunc unwrap(i any) any {\n\tif ule, ok := i.(*uncompressedLayerExtender); ok {\n\t\treturn unwrap(ule.UncompressedLayer)\n\t}\n\tif cle, ok := i.(*compressedLayerExtender); ok {\n\t\treturn unwrap(cle.CompressedLayer)\n\t}\n\tif uie, ok := i.(*uncompressedImageExtender); ok {\n\t\treturn unwrap(uie.UncompressedImageCore)\n\t}\n\tif cie, ok := i.(*compressedImageExtender); ok {\n\t\treturn unwrap(cie.CompressedImageCore)\n\t}\n\treturn i\n}\n\n// ArtifactType returns the artifact type for the given manifest.\n//\n// If the manifest reports its own artifact type, that's returned, otherwise\n// the manifest is parsed and, if successful, its config.mediaType is returned.\nfunc ArtifactType(w WithManifest) (string, error) {\n\tif wat, ok := w.(withArtifactType); ok {\n\t\treturn wat.ArtifactType()\n\t}\n\tmf, _ := w.Manifest()\n\t// Failing to parse as a manifest should just be ignored.\n\t// The manifest might not be valid, and that's okay.\n\tif mf != nil && !mf.Config.MediaType.IsConfig() {\n\t\treturn string(mf.Config.MediaType), nil\n\t}\n\treturn \"\", nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/platform.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// Platform represents the target os/arch for an image.\ntype Platform struct {\n\tArchitecture string   `json:\"architecture\"`\n\tOS           string   `json:\"os\"`\n\tOSVersion    string   `json:\"os.version,omitempty\"`\n\tOSFeatures   []string `json:\"os.features,omitempty\"`\n\tVariant      string   `json:\"variant,omitempty\"`\n\tFeatures     []string `json:\"features,omitempty\"`\n}\n\nfunc (p Platform) String() string {\n\tif p.OS == \"\" {\n\t\treturn \"\"\n\t}\n\tvar b strings.Builder\n\tb.WriteString(p.OS)\n\tif p.Architecture != \"\" {\n\t\tb.WriteString(\"/\")\n\t\tb.WriteString(p.Architecture)\n\t}\n\tif p.Variant != \"\" {\n\t\tb.WriteString(\"/\")\n\t\tb.WriteString(p.Variant)\n\t}\n\tif p.OSVersion != \"\" {\n\t\tb.WriteString(\":\")\n\t\tb.WriteString(p.OSVersion)\n\t}\n\treturn b.String()\n}\n\n// ParsePlatform parses a string representing a Platform, if possible.\nfunc ParsePlatform(s string) (*Platform, error) {\n\tvar p Platform\n\tparts := strings.Split(strings.TrimSpace(s), \":\")\n\tif len(parts) == 2 {\n\t\tp.OSVersion = parts[1]\n\t}\n\tparts = strings.Split(parts[0], \"/\")\n\tif len(parts) > 0 {\n\t\tp.OS = parts[0]\n\t}\n\tif len(parts) > 1 {\n\t\tp.Architecture = parts[1]\n\t}\n\tif len(parts) > 2 {\n\t\tp.Variant = parts[2]\n\t}\n\tif len(parts) > 3 {\n\t\treturn nil, fmt.Errorf(\"too many slashes in platform spec: %s\", s)\n\t}\n\treturn &p, nil\n}\n\n// Equals returns true if the given platform is semantically equivalent to this one.\n// The order of Features and OSFeatures is not important.\nfunc (p Platform) Equals(o Platform) bool {\n\treturn p.OS == o.OS &&\n\t\tp.Architecture == o.Architecture &&\n\t\tp.Variant == o.Variant &&\n\t\tp.OSVersion == o.OSVersion &&\n\t\tstringSliceEqualIgnoreOrder(p.OSFeatures, o.OSFeatures) &&\n\t\tstringSliceEqualIgnoreOrder(p.Features, o.Features)\n}\n\n// Satisfies returns true if this Platform \"satisfies\" the given spec Platform.\n//\n// Note that this is different from Equals and that Satisfies is not reflexive.\n//\n// The given spec represents \"requirements\" such that any missing values in the\n// spec are not compared.\n//\n// For OSFeatures and Features, Satisfies will return true if this Platform's\n// fields contain a superset of the values in the spec's fields (order ignored).\nfunc (p Platform) Satisfies(spec Platform) bool {\n\treturn satisfies(spec.OS, p.OS) &&\n\t\tsatisfies(spec.Architecture, p.Architecture) &&\n\t\tsatisfies(spec.Variant, p.Variant) &&\n\t\tsatisfies(spec.OSVersion, p.OSVersion) &&\n\t\tsatisfiesList(spec.OSFeatures, p.OSFeatures) &&\n\t\tsatisfiesList(spec.Features, p.Features)\n}\n\nfunc satisfies(want, have string) bool {\n\treturn want == \"\" || want == have\n}\n\nfunc satisfiesList(want, have []string) bool {\n\tif len(want) == 0 {\n\t\treturn true\n\t}\n\n\tset := map[string]struct{}{}\n\tfor _, h := range have {\n\t\tset[h] = struct{}{}\n\t}\n\n\tfor _, w := range want {\n\t\tif _, ok := set[w]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n// stringSliceEqual compares 2 string slices and returns if their contents are identical.\nfunc stringSliceEqual(a, b []string) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, elm := range a {\n\t\tif elm != b[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// stringSliceEqualIgnoreOrder compares 2 string slices and returns if their contents are identical, ignoring order\nfunc stringSliceEqualIgnoreOrder(a, b []string) bool {\n\tif a != nil && b != nil {\n\t\tsort.Strings(a)\n\t\tsort.Strings(b)\n\t}\n\treturn stringSliceEqual(a, b)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/progress.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\npackage v1\n\n// Update representation of an update of transfer progress. Some functions\n// in this module can take a channel to which updates will be sent while a\n// transfer is in progress.\n// +k8s:deepcopy-gen=false\ntype Update struct {\n\tTotal    int64\n\tComplete int64\n\tError    error\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/README.md",
    "content": "# `remote`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote)\n\nThe `remote` package implements a client for accessing a registry,\nper the [OCI distribution spec](https://github.com/opencontainers/distribution-spec/blob/master/spec.md).\n\nIt leans heavily on the lower level [`transport`](/pkg/v1/remote/transport) package, which handles the\nauthentication handshake and structured errors.\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n)\n\nfunc main() {\n\tref, err := name.ParseReference(\"gcr.io/google-containers/pause\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\timg, err := remote.Image(ref, remote.WithAuthFromKeychain(authn.DefaultKeychain))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// do stuff with img\n}\n```\n\n## Structure\n\n<p align=\"center\">\n  <img src=\"/images/remote.dot.svg\" />\n</p>\n\n\n## Background\n\nThere are a lot of confusingly similar terms that come up when talking about images in registries.\n\n### Anatomy of an image\n\nIn general...\n\n* A tag refers to an image manifest.\n* An image manifest references a config file and an orderered list of _compressed_ layers by sha256 digest.\n* A config file references an ordered list of _uncompressed_ layers by sha256 digest and contains runtime configuration.\n* The sha256 digest of the config file is the [image id](https://github.com/opencontainers/image-spec/blob/master/config.md#imageid) for the image.\n\nFor example, an image with two layers would look something like this:\n\n![image anatomy](/images/image-anatomy.dot.svg)\n\n### Anatomy of an index\n\nIn the normal case, an [index](https://github.com/opencontainers/image-spec/blob/master/image-index.md) is used to represent a multi-platform image.\nThis was the original use case for a [manifest\nlist](https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list).\n\n![image index anatomy](/images/index-anatomy.dot.svg)\n\nIt is possible for an index to reference another index, per the OCI\n[image-spec](https://github.com/opencontainers/image-spec/blob/master/media-types.md#compatibility-matrix).\nIn theory, both an image and image index can reference arbitrary things via\n[descriptors](https://github.com/opencontainers/image-spec/blob/master/descriptor.md),\ne.g. see the [image layout\nexample](https://github.com/opencontainers/image-spec/blob/master/image-layout.md#index-example),\nwhich references an application/xml file from an image index.\n\nThat could look something like this:\n\n![strange image index anatomy](/images/index-anatomy-strange.dot.svg)\n\nUsing a recursive index like this might not be possible with all registries,\nbut this flexibility allows for some interesting applications, e.g. the\n[OCI Artifacts](https://github.com/opencontainers/artifacts) effort.\n\n### Anatomy of an image upload\n\nThe structure of an image requires a delicate ordering when uploading an image to a registry.\nBelow is a (slightly simplified) figure that describes how an image is prepared for upload\nto a registry and how the data flows between various artifacts:\n\n![upload](/images/upload.dot.svg)\n\nNote that:\n\n* A config file references the uncompressed layer contents by sha256.\n* A manifest references the compressed layer contents by sha256 and the size of the layer.\n* A manifest references the config file contents by sha256 and the size of the file.\n\nIt follows that during an upload, we need to upload layers before the config file,\nand we need to upload the config file before the manifest.\n\nSometimes, we know all of this information ahead of time, (e.g. when copying from remote.Image),\nso the ordering is less important.\n\nIn other cases, e.g. when using a [`stream.Layer`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/stream#Layer),\nwe can't compute anything until we have already uploaded the layer, so we need to be careful about ordering.\n\n## Caveats\n\n### schema 1\n\nThis package does not support schema 1 images, see [`#377`](https://github.com/google/go-containerregistry/issues/377),\nhowever, it's possible to do _something_ useful with them via [`remote.Get`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote#Get),\nwhich doesn't try to interpret what is returned by the registry.\n\n[`crane.Copy`](https://godoc.org/github.com/google/go-containerregistry/pkg/crane#Copy) takes advantage of this to implement support for copying schema 1 images,\nsee [here](https://github.com/google/go-containerregistry/blob/main/pkg/internal/legacy/copy.go).\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/catalog.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n)\n\ntype Catalogs struct {\n\tRepos []string `json:\"repositories\"`\n\tNext  string   `json:\"next,omitempty\"`\n}\n\n// CatalogPage calls /_catalog, returning the list of repositories on the registry.\nfunc CatalogPage(target name.Registry, last string, n int, options ...Option) ([]string, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tf, err := newPuller(o).fetcher(o.context, target)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\turi := url.URL{\n\t\tScheme:   target.Scheme(),\n\t\tHost:     target.RegistryStr(),\n\t\tPath:     \"/v2/_catalog\",\n\t\tRawQuery: fmt.Sprintf(\"last=%s&n=%d\", url.QueryEscape(last), n),\n\t}\n\n\treq, err := http.NewRequest(http.MethodGet, uri.String(), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tresp, err := f.client.Do(req.WithContext(o.context))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar parsed Catalogs\n\tif err := json.NewDecoder(resp.Body).Decode(&parsed); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn parsed.Repos, nil\n}\n\n// Catalog calls /_catalog, returning the list of repositories on the registry.\nfunc Catalog(ctx context.Context, target name.Registry, options ...Option) ([]string, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// WithContext overrides the ctx passed directly.\n\tif o.context != context.Background() {\n\t\tctx = o.context\n\t}\n\n\treturn newPuller(o).catalog(ctx, target, o.pageSize)\n}\n\nfunc (f *fetcher) catalogPage(ctx context.Context, reg name.Registry, next string, pageSize int) (*Catalogs, error) {\n\tif next == \"\" {\n\t\turi := &url.URL{\n\t\t\tScheme: reg.Scheme(),\n\t\t\tHost:   reg.RegistryStr(),\n\t\t\tPath:   \"/v2/_catalog\",\n\t\t}\n\t\tif pageSize > 0 {\n\t\t\turi.RawQuery = fmt.Sprintf(\"n=%d\", pageSize)\n\t\t}\n\t\tnext = uri.String()\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", next, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := f.client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\treturn nil, err\n\t}\n\n\tparsed := Catalogs{}\n\tif err := json.NewDecoder(resp.Body).Decode(&parsed); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := resp.Body.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\n\turi, err := getNextPageURL(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif uri != nil {\n\t\tparsed.Next = uri.String()\n\t}\n\n\treturn &parsed, nil\n}\n\ntype Catalogger struct {\n\tf        *fetcher\n\treg      name.Registry\n\tpageSize int\n\n\tpage *Catalogs\n\terr  error\n\n\tneedMore bool\n}\n\nfunc (l *Catalogger) Next(ctx context.Context) (*Catalogs, error) {\n\tif l.needMore {\n\t\tl.page, l.err = l.f.catalogPage(ctx, l.reg, l.page.Next, l.pageSize)\n\t} else {\n\t\tl.needMore = true\n\t}\n\treturn l.page, l.err\n}\n\nfunc (l *Catalogger) HasNext() bool {\n\treturn l.page != nil && (!l.needMore || l.page.Next != \"\")\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/check.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n)\n\n// CheckPushPermission returns an error if the given keychain cannot authorize\n// a push operation to the given ref.\n//\n// This can be useful to check whether the caller has permission to push an\n// image before doing work to construct the image.\n//\n// TODO(#412): Remove the need for this method.\nfunc CheckPushPermission(ref name.Reference, kc authn.Keychain, t http.RoundTripper) error {\n\tauth, err := kc.Resolve(ref.Context().Registry)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"resolving authorization for %v failed: %w\", ref.Context().Registry, err)\n\t}\n\n\tscopes := []string{ref.Scope(transport.PushScope)}\n\ttr, err := transport.NewWithContext(context.TODO(), ref.Context().Registry, auth, t, scopes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating push check transport for %v failed: %w\", ref.Context().Registry, err)\n\t}\n\t// TODO(jasonhall): Against GCR, just doing the token handshake is\n\t// enough, but this doesn't extend to Dockerhub\n\t// (https://github.com/docker/hub-feedback/issues/1771), so we actually\n\t// need to initiate an upload to tell whether the credentials can\n\t// authorize a push. Figure out how to return early here when we can,\n\t// to avoid a roundtrip for spec-compliant registries.\n\tw := writer{\n\t\trepo:   ref.Context(),\n\t\tclient: &http.Client{Transport: tr},\n\t}\n\tloc, _, err := w.initiateUpload(context.Background(), \"\", \"\", \"\")\n\tif loc != \"\" {\n\t\t// Since we're only initiating the upload to check whether we\n\t\t// can, we should attempt to cancel it, in case initiating\n\t\t// reserves some resources on the server. We shouldn't wait for\n\t\t// cancelling to complete, and we don't care if it fails.\n\t\tgo w.cancelUpload(loc)\n\t}\n\treturn err\n}\n\nfunc (w *writer) cancelUpload(loc string) {\n\treq, err := http.NewRequest(http.MethodDelete, loc, nil)\n\tif err != nil {\n\t\treturn\n\t}\n\t_, _ = w.client.Do(req)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/delete.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/name\"\n)\n\n// Delete removes the specified image reference from the remote registry.\nfunc Delete(ref name.Reference, options ...Option) error {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn newPusher(o).Delete(o.context, ref)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/descriptor.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nvar allManifestMediaTypes = append(append([]types.MediaType{\n\ttypes.DockerManifestSchema1,\n\ttypes.DockerManifestSchema1Signed,\n}, acceptableImageMediaTypes...), acceptableIndexMediaTypes...)\n\n// ErrSchema1 indicates that we received a schema1 manifest from the registry.\n// This library doesn't have plans to support this legacy image format:\n// https://github.com/google/go-containerregistry/issues/377\nvar ErrSchema1 = errors.New(\"see https://github.com/google/go-containerregistry/issues/377\")\n\n// newErrSchema1 returns an ErrSchema1 with the unexpected MediaType.\nfunc newErrSchema1(schema types.MediaType) error {\n\treturn fmt.Errorf(\"unsupported MediaType: %q, %w\", schema, ErrSchema1)\n}\n\n// Descriptor provides access to metadata about remote artifact and accessors\n// for efficiently converting it into a v1.Image or v1.ImageIndex.\ntype Descriptor struct {\n\tfetcher fetcher\n\tv1.Descriptor\n\n\tref      name.Reference\n\tManifest []byte\n\tctx      context.Context\n\n\t// So we can share this implementation with Image.\n\tplatform v1.Platform\n}\n\nfunc (d *Descriptor) toDesc() v1.Descriptor {\n\treturn d.Descriptor\n}\n\n// RawManifest exists to satisfy the Taggable interface.\nfunc (d *Descriptor) RawManifest() ([]byte, error) {\n\treturn d.Manifest, nil\n}\n\n// Get returns a remote.Descriptor for the given reference. The response from\n// the registry is left un-interpreted, for the most part. This is useful for\n// querying what kind of artifact a reference represents.\n//\n// See Head if you don't need the response body.\nfunc Get(ref name.Reference, options ...Option) (*Descriptor, error) {\n\treturn get(ref, allManifestMediaTypes, options...)\n}\n\n// Head returns a v1.Descriptor for the given reference by issuing a HEAD\n// request.\n//\n// Note that the server response will not have a body, so any errors encountered\n// should be retried with Get to get more details.\nfunc Head(ref name.Reference, options ...Option) (*v1.Descriptor, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn newPuller(o).Head(o.context, ref)\n}\n\n// Handle options and fetch the manifest with the acceptable MediaTypes in the\n// Accept header.\nfunc get(ref name.Reference, acceptable []types.MediaType, options ...Option) (*Descriptor, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newPuller(o).get(o.context, ref, acceptable, o.platform)\n}\n\n// Image converts the Descriptor into a v1.Image.\n//\n// If the fetched artifact is already an image, it will just return it.\n//\n// If the fetched artifact is an index, it will attempt to resolve the index to\n// a child image with the appropriate platform.\n//\n// See WithPlatform to set the desired platform.\nfunc (d *Descriptor) Image() (v1.Image, error) {\n\tswitch d.MediaType {\n\tcase types.DockerManifestSchema1, types.DockerManifestSchema1Signed:\n\t\t// We don't care to support schema 1 images:\n\t\t// https://github.com/google/go-containerregistry/issues/377\n\t\treturn nil, newErrSchema1(d.MediaType)\n\tcase types.OCIImageIndex, types.DockerManifestList:\n\t\t// We want an image but the registry has an index, resolve it to an image.\n\t\treturn d.remoteIndex().imageByPlatform(d.platform)\n\tcase types.OCIManifestSchema1, types.DockerManifestSchema2:\n\t\t// These are expected. Enumerated here to allow a default case.\n\tdefault:\n\t\t// We could just return an error here, but some registries (e.g. static\n\t\t// registries) don't set the Content-Type headers correctly, so instead...\n\t\tlogs.Warn.Printf(\"Unexpected media type for Image(): %s\", d.MediaType)\n\t}\n\n\t// Wrap the v1.Layers returned by this v1.Image in a hint for downstream\n\t// remote.Write calls to facilitate cross-repo \"mounting\".\n\timgCore, err := partial.CompressedToImage(d.remoteImage())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &mountableImage{\n\t\tImage:     imgCore,\n\t\tReference: d.ref,\n\t}, nil\n}\n\n// Schema1 converts the Descriptor into a v1.Image for v2 schema 1 media types.\n//\n// The v1.Image returned by this method does not implement the entire interface because it would be inefficient.\n// This exists mostly to make it easier to copy schema 1 images around or look at their filesystems.\n// This is separate from Image() to avoid a backward incompatible change for callers expecting ErrSchema1.\nfunc (d *Descriptor) Schema1() (v1.Image, error) {\n\ti := &schema1{\n\t\tref:        d.ref,\n\t\tfetcher:    d.fetcher,\n\t\tctx:        d.ctx,\n\t\tmanifest:   d.Manifest,\n\t\tmediaType:  d.MediaType,\n\t\tdescriptor: &d.Descriptor,\n\t}\n\n\treturn &mountableImage{\n\t\tImage:     i,\n\t\tReference: d.ref,\n\t}, nil\n}\n\n// ImageIndex converts the Descriptor into a v1.ImageIndex.\nfunc (d *Descriptor) ImageIndex() (v1.ImageIndex, error) {\n\tswitch d.MediaType {\n\tcase types.DockerManifestSchema1, types.DockerManifestSchema1Signed:\n\t\t// We don't care to support schema 1 images:\n\t\t// https://github.com/google/go-containerregistry/issues/377\n\t\treturn nil, newErrSchema1(d.MediaType)\n\tcase types.OCIManifestSchema1, types.DockerManifestSchema2:\n\t\t// We want an index but the registry has an image, nothing we can do.\n\t\treturn nil, fmt.Errorf(\"unexpected media type for ImageIndex(): %s; call Image() instead\", d.MediaType)\n\tcase types.OCIImageIndex, types.DockerManifestList:\n\t\t// These are expected.\n\tdefault:\n\t\t// We could just return an error here, but some registries (e.g. static\n\t\t// registries) don't set the Content-Type headers correctly, so instead...\n\t\tlogs.Warn.Printf(\"Unexpected media type for ImageIndex(): %s\", d.MediaType)\n\t}\n\treturn d.remoteIndex(), nil\n}\n\nfunc (d *Descriptor) remoteImage() *remoteImage {\n\treturn &remoteImage{\n\t\tref:        d.ref,\n\t\tctx:        d.ctx,\n\t\tfetcher:    d.fetcher,\n\t\tmanifest:   d.Manifest,\n\t\tmediaType:  d.MediaType,\n\t\tdescriptor: &d.Descriptor,\n\t}\n}\n\nfunc (d *Descriptor) remoteIndex() *remoteIndex {\n\treturn &remoteIndex{\n\t\tref:        d.ref,\n\t\tctx:        d.ctx,\n\t\tfetcher:    d.fetcher,\n\t\tmanifest:   d.Manifest,\n\t\tmediaType:  d.MediaType,\n\t\tdescriptor: &d.Descriptor,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package remote provides facilities for reading/writing v1.Images from/to\n// a remote image registry.\npackage remote\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/fetcher.go",
    "content": "// Copyright 2023 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/internal/redact\"\n\t\"github.com/google/go-containerregistry/internal/verify\"\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nconst (\n\tkib           = 1024\n\tmib           = 1024 * kib\n\tmanifestLimit = 100 * mib\n)\n\n// fetcher implements methods for reading from a registry.\ntype fetcher struct {\n\ttarget resource\n\tclient *http.Client\n}\n\nfunc makeFetcher(ctx context.Context, target resource, o *options) (*fetcher, error) {\n\tauth := o.auth\n\tif o.keychain != nil {\n\t\tkauth, err := o.keychain.Resolve(target)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tauth = kauth\n\t}\n\n\treg, ok := target.(name.Registry)\n\tif !ok {\n\t\trepo, ok := target.(name.Repository)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"unexpected resource: %T\", target)\n\t\t}\n\t\treg = repo.Registry\n\t}\n\n\ttr, err := transport.NewWithContext(ctx, reg, auth, o.transport, []string{target.Scope(transport.PullScope)})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &fetcher{\n\t\ttarget: target,\n\t\tclient: &http.Client{Transport: tr},\n\t}, nil\n}\n\nfunc (f *fetcher) Do(req *http.Request) (*http.Response, error) {\n\treturn f.client.Do(req)\n}\n\ntype resource interface {\n\tScheme() string\n\tRegistryStr() string\n\tScope(string) string\n\n\tauthn.Resource\n}\n\n// url returns a url.Url for the specified path in the context of this remote image reference.\nfunc (f *fetcher) url(resource, identifier string) url.URL {\n\tu := url.URL{\n\t\tScheme: f.target.Scheme(),\n\t\tHost:   f.target.RegistryStr(),\n\t\t// Default path if this is not a repository.\n\t\tPath: \"/v2/_catalog\",\n\t}\n\tif repo, ok := f.target.(name.Repository); ok {\n\t\tu.Path = fmt.Sprintf(\"/v2/%s/%s/%s\", repo.RepositoryStr(), resource, identifier)\n\t}\n\treturn u\n}\n\nfunc (f *fetcher) get(ctx context.Context, ref name.Reference, acceptable []types.MediaType, platform v1.Platform) (*Descriptor, error) {\n\tb, desc, err := f.fetchManifest(ctx, ref, acceptable)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Descriptor{\n\t\tref:        ref,\n\t\tctx:        ctx,\n\t\tfetcher:    *f,\n\t\tManifest:   b,\n\t\tDescriptor: *desc,\n\t\tplatform:   platform,\n\t}, nil\n}\n\nfunc (f *fetcher) fetchManifest(ctx context.Context, ref name.Reference, acceptable []types.MediaType) ([]byte, *v1.Descriptor, error) {\n\tu := f.url(\"manifests\", ref.Identifier())\n\treq, err := http.NewRequest(http.MethodGet, u.String(), nil)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\taccept := []string{}\n\tfor _, mt := range acceptable {\n\t\taccept = append(accept, string(mt))\n\t}\n\treq.Header.Set(\"Accept\", strings.Join(accept, \",\"))\n\n\tresp, err := f.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tmanifest, err := io.ReadAll(io.LimitReader(resp.Body, manifestLimit))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tdigest, size, err := v1.SHA256(bytes.NewReader(manifest))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tmediaType := types.MediaType(resp.Header.Get(\"Content-Type\"))\n\tcontentDigest, err := v1.NewHash(resp.Header.Get(\"Docker-Content-Digest\"))\n\tif err == nil && mediaType == types.DockerManifestSchema1Signed {\n\t\t// If we can parse the digest from the header, and it's a signed schema 1\n\t\t// manifest, let's use that for the digest to appease older registries.\n\t\tdigest = contentDigest\n\t}\n\n\t// Validate the digest matches what we asked for, if pulling by digest.\n\tif dgst, ok := ref.(name.Digest); ok {\n\t\tif digest.String() != dgst.DigestStr() {\n\t\t\treturn nil, nil, fmt.Errorf(\"manifest digest: %q does not match requested digest: %q for %q\", digest, dgst.DigestStr(), ref)\n\t\t}\n\t}\n\n\tvar artifactType string\n\tmf, _ := v1.ParseManifest(bytes.NewReader(manifest))\n\t// Failing to parse as a manifest should just be ignored.\n\t// The manifest might not be valid, and that's okay.\n\tif mf != nil && !mf.Config.MediaType.IsConfig() {\n\t\tartifactType = string(mf.Config.MediaType)\n\t}\n\n\t// Do nothing for tags; I give up.\n\t//\n\t// We'd like to validate that the \"Docker-Content-Digest\" header matches what is returned by the registry,\n\t// but so many registries implement this incorrectly that it's not worth checking.\n\t//\n\t// For reference:\n\t// https://github.com/GoogleContainerTools/kaniko/issues/298\n\n\t// Return all this info since we have to calculate it anyway.\n\tdesc := v1.Descriptor{\n\t\tDigest:       digest,\n\t\tSize:         size,\n\t\tMediaType:    mediaType,\n\t\tArtifactType: artifactType,\n\t}\n\n\treturn manifest, &desc, nil\n}\n\nfunc (f *fetcher) headManifest(ctx context.Context, ref name.Reference, acceptable []types.MediaType) (*v1.Descriptor, error) {\n\tu := f.url(\"manifests\", ref.Identifier())\n\treq, err := http.NewRequest(http.MethodHead, u.String(), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\taccept := []string{}\n\tfor _, mt := range acceptable {\n\t\taccept = append(accept, string(mt))\n\t}\n\treq.Header.Set(\"Accept\", strings.Join(accept, \",\"))\n\n\tresp, err := f.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\treturn nil, err\n\t}\n\n\tmth := resp.Header.Get(\"Content-Type\")\n\tif mth == \"\" {\n\t\treturn nil, fmt.Errorf(\"HEAD %s: response did not include Content-Type header\", u.String())\n\t}\n\tmediaType := types.MediaType(mth)\n\n\tsize := resp.ContentLength\n\tif size == -1 {\n\t\treturn nil, fmt.Errorf(\"GET %s: response did not include Content-Length header\", u.String())\n\t}\n\n\tdh := resp.Header.Get(\"Docker-Content-Digest\")\n\tif dh == \"\" {\n\t\treturn nil, fmt.Errorf(\"HEAD %s: response did not include Docker-Content-Digest header\", u.String())\n\t}\n\tdigest, err := v1.NewHash(dh)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Validate the digest matches what we asked for, if pulling by digest.\n\tif dgst, ok := ref.(name.Digest); ok {\n\t\tif digest.String() != dgst.DigestStr() {\n\t\t\treturn nil, fmt.Errorf(\"manifest digest: %q does not match requested digest: %q for %q\", digest, dgst.DigestStr(), ref)\n\t\t}\n\t}\n\n\t// Return all this info since we have to calculate it anyway.\n\treturn &v1.Descriptor{\n\t\tDigest:    digest,\n\t\tSize:      size,\n\t\tMediaType: mediaType,\n\t}, nil\n}\n\nfunc (f *fetcher) fetchBlob(ctx context.Context, size int64, h v1.Hash) (io.ReadCloser, error) {\n\tu := f.url(\"blobs\", h.String())\n\treq, err := http.NewRequest(http.MethodGet, u.String(), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := f.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, redact.Error(err)\n\t}\n\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\tresp.Body.Close()\n\t\treturn nil, err\n\t}\n\n\t// Do whatever we can.\n\t// If we have an expected size and Content-Length doesn't match, return an error.\n\t// If we don't have an expected size and we do have a Content-Length, use Content-Length.\n\tif hsize := resp.ContentLength; hsize != -1 {\n\t\tif size == verify.SizeUnknown {\n\t\t\tsize = hsize\n\t\t} else if hsize != size {\n\t\t\treturn nil, fmt.Errorf(\"GET %s: Content-Length header %d does not match expected size %d\", u.String(), hsize, size)\n\t\t}\n\t}\n\n\treturn verify.ReadCloser(resp.Body, size, h)\n}\n\nfunc (f *fetcher) headBlob(ctx context.Context, h v1.Hash) (*http.Response, error) {\n\tu := f.url(\"blobs\", h.String())\n\treq, err := http.NewRequest(http.MethodHead, u.String(), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := f.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, redact.Error(err)\n\t}\n\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\tresp.Body.Close()\n\t\treturn nil, err\n\t}\n\n\treturn resp, nil\n}\n\nfunc (f *fetcher) blobExists(ctx context.Context, h v1.Hash) (bool, error) {\n\tu := f.url(\"blobs\", h.String())\n\treq, err := http.NewRequest(http.MethodHead, u.String(), nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tresp, err := f.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn false, redact.Error(err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound); err != nil {\n\t\treturn false, err\n\t}\n\n\treturn resp.StatusCode == http.StatusOK, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/image.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/internal/redact\"\n\t\"github.com/google/go-containerregistry/internal/verify\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nvar acceptableImageMediaTypes = []types.MediaType{\n\ttypes.DockerManifestSchema2,\n\ttypes.OCIManifestSchema1,\n}\n\n// remoteImage accesses an image from a remote registry\ntype remoteImage struct {\n\tfetcher      fetcher\n\tref          name.Reference\n\tctx          context.Context\n\tmanifestLock sync.Mutex // Protects manifest\n\tmanifest     []byte\n\tconfigLock   sync.Mutex // Protects config\n\tconfig       []byte\n\tmediaType    types.MediaType\n\tdescriptor   *v1.Descriptor\n}\n\nfunc (r *remoteImage) ArtifactType() (string, error) {\n\t// kind of a hack, but RawManifest does appropriate locking/memoization\n\t// and makes sure r.descriptor is populated.\n\tif _, err := r.RawManifest(); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn r.descriptor.ArtifactType, nil\n}\n\nvar _ partial.CompressedImageCore = (*remoteImage)(nil)\n\n// Image provides access to a remote image reference.\nfunc Image(ref name.Reference, options ...Option) (v1.Image, error) {\n\tdesc, err := Get(ref, options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn desc.Image()\n}\n\nfunc (r *remoteImage) MediaType() (types.MediaType, error) {\n\tif string(r.mediaType) != \"\" {\n\t\treturn r.mediaType, nil\n\t}\n\treturn types.DockerManifestSchema2, nil\n}\n\nfunc (r *remoteImage) RawManifest() ([]byte, error) {\n\tr.manifestLock.Lock()\n\tdefer r.manifestLock.Unlock()\n\tif r.manifest != nil {\n\t\treturn r.manifest, nil\n\t}\n\n\t// NOTE(jonjohnsonjr): We should never get here because the public entrypoints\n\t// do type-checking via remote.Descriptor. I've left this here for tests that\n\t// directly instantiate a remoteImage.\n\tmanifest, desc, err := r.fetcher.fetchManifest(r.ctx, r.ref, acceptableImageMediaTypes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif r.descriptor == nil {\n\t\tr.descriptor = desc\n\t}\n\tr.mediaType = desc.MediaType\n\tr.manifest = manifest\n\treturn r.manifest, nil\n}\n\nfunc (r *remoteImage) RawConfigFile() ([]byte, error) {\n\tr.configLock.Lock()\n\tdefer r.configLock.Unlock()\n\tif r.config != nil {\n\t\treturn r.config, nil\n\t}\n\n\tm, err := partial.Manifest(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif m.Config.Data != nil {\n\t\tif err := verify.Descriptor(m.Config); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tr.config = m.Config.Data\n\t\treturn r.config, nil\n\t}\n\n\tbody, err := r.fetcher.fetchBlob(r.ctx, m.Config.Size, m.Config.Digest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer body.Close()\n\n\tr.config, err = io.ReadAll(body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn r.config, nil\n}\n\n// Descriptor retains the original descriptor from an index manifest.\n// See partial.Descriptor.\nfunc (r *remoteImage) Descriptor() (*v1.Descriptor, error) {\n\t// kind of a hack, but RawManifest does appropriate locking/memoization\n\t// and makes sure r.descriptor is populated.\n\t_, err := r.RawManifest()\n\treturn r.descriptor, err\n}\n\nfunc (r *remoteImage) ConfigLayer() (v1.Layer, error) {\n\tif _, err := r.RawManifest(); err != nil {\n\t\treturn nil, err\n\t}\n\tm, err := partial.Manifest(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn partial.CompressedToLayer(&remoteImageLayer{\n\t\tri:     r,\n\t\tctx:    r.ctx,\n\t\tdigest: m.Config.Digest,\n\t})\n}\n\n// remoteImageLayer implements partial.CompressedLayer\ntype remoteImageLayer struct {\n\tri     *remoteImage\n\tctx    context.Context\n\tdigest v1.Hash\n}\n\n// Digest implements partial.CompressedLayer\nfunc (rl *remoteImageLayer) Digest() (v1.Hash, error) {\n\treturn rl.digest, nil\n}\n\n// Compressed implements partial.CompressedLayer\nfunc (rl *remoteImageLayer) Compressed() (io.ReadCloser, error) {\n\turls := []url.URL{rl.ri.fetcher.url(\"blobs\", rl.digest.String())}\n\n\t// Add alternative layer sources from URLs (usually none).\n\td, err := partial.BlobDescriptor(rl, rl.digest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif d.Data != nil {\n\t\treturn verify.ReadCloser(io.NopCloser(bytes.NewReader(d.Data)), d.Size, d.Digest)\n\t}\n\n\t// We don't want to log binary layers -- this can break terminals.\n\tctx := redact.NewContext(rl.ctx, \"omitting binary blobs from logs\")\n\n\tfor _, s := range d.URLs {\n\t\tu, err := url.Parse(s)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\turls = append(urls, *u)\n\t}\n\n\t// The lastErr for most pulls will be the same (the first error), but for\n\t// foreign layers we'll want to surface the last one, since we try to pull\n\t// from the registry first, which would often fail.\n\t// TODO: Maybe we don't want to try pulling from the registry first?\n\tvar lastErr error\n\tfor _, u := range urls {\n\t\treq, err := http.NewRequest(http.MethodGet, u.String(), nil)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tresp, err := rl.ri.fetcher.Do(req.WithContext(ctx))\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t\tcontinue\n\t\t}\n\n\t\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\t\tresp.Body.Close()\n\t\t\tlastErr = err\n\t\t\tcontinue\n\t\t}\n\n\t\treturn verify.ReadCloser(resp.Body, d.Size, rl.digest)\n\t}\n\n\treturn nil, lastErr\n}\n\n// Manifest implements partial.WithManifest so that we can use partial.BlobSize below.\nfunc (rl *remoteImageLayer) Manifest() (*v1.Manifest, error) {\n\treturn partial.Manifest(rl.ri)\n}\n\n// MediaType implements v1.Layer\nfunc (rl *remoteImageLayer) MediaType() (types.MediaType, error) {\n\tbd, err := partial.BlobDescriptor(rl, rl.digest)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn bd.MediaType, nil\n}\n\n// Size implements partial.CompressedLayer\nfunc (rl *remoteImageLayer) Size() (int64, error) {\n\t// Look up the size of this digest in the manifest to avoid a request.\n\treturn partial.BlobSize(rl, rl.digest)\n}\n\n// ConfigFile implements partial.WithManifestAndConfigFile so that we can use partial.BlobToDiffID below.\nfunc (rl *remoteImageLayer) ConfigFile() (*v1.ConfigFile, error) {\n\treturn partial.ConfigFile(rl.ri)\n}\n\n// DiffID implements partial.WithDiffID so that we don't recompute a DiffID that we already have\n// available in our ConfigFile.\nfunc (rl *remoteImageLayer) DiffID() (v1.Hash, error) {\n\treturn partial.BlobToDiffID(rl, rl.digest)\n}\n\n// Descriptor retains the original descriptor from an image manifest.\n// See partial.Descriptor.\nfunc (rl *remoteImageLayer) Descriptor() (*v1.Descriptor, error) {\n\treturn partial.BlobDescriptor(rl, rl.digest)\n}\n\n// See partial.Exists.\nfunc (rl *remoteImageLayer) Exists() (bool, error) {\n\treturn rl.ri.fetcher.blobExists(rl.ri.ctx, rl.digest)\n}\n\n// LayerByDigest implements partial.CompressedLayer\nfunc (r *remoteImage) LayerByDigest(h v1.Hash) (partial.CompressedLayer, error) {\n\treturn &remoteImageLayer{\n\t\tri:     r,\n\t\tctx:    r.ctx,\n\t\tdigest: h,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/index.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/internal/verify\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nvar acceptableIndexMediaTypes = []types.MediaType{\n\ttypes.DockerManifestList,\n\ttypes.OCIImageIndex,\n}\n\n// remoteIndex accesses an index from a remote registry\ntype remoteIndex struct {\n\tfetcher      fetcher\n\tref          name.Reference\n\tctx          context.Context\n\tmanifestLock sync.Mutex // Protects manifest\n\tmanifest     []byte\n\tmediaType    types.MediaType\n\tdescriptor   *v1.Descriptor\n}\n\n// Index provides access to a remote index reference.\nfunc Index(ref name.Reference, options ...Option) (v1.ImageIndex, error) {\n\tdesc, err := get(ref, acceptableIndexMediaTypes, options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn desc.ImageIndex()\n}\n\nfunc (r *remoteIndex) MediaType() (types.MediaType, error) {\n\tif string(r.mediaType) != \"\" {\n\t\treturn r.mediaType, nil\n\t}\n\treturn types.DockerManifestList, nil\n}\n\nfunc (r *remoteIndex) Digest() (v1.Hash, error) {\n\treturn partial.Digest(r)\n}\n\nfunc (r *remoteIndex) Size() (int64, error) {\n\treturn partial.Size(r)\n}\n\nfunc (r *remoteIndex) RawManifest() ([]byte, error) {\n\tr.manifestLock.Lock()\n\tdefer r.manifestLock.Unlock()\n\tif r.manifest != nil {\n\t\treturn r.manifest, nil\n\t}\n\n\t// NOTE(jonjohnsonjr): We should never get here because the public entrypoints\n\t// do type-checking via remote.Descriptor. I've left this here for tests that\n\t// directly instantiate a remoteIndex.\n\tmanifest, desc, err := r.fetcher.fetchManifest(r.ctx, r.ref, acceptableIndexMediaTypes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif r.descriptor == nil {\n\t\tr.descriptor = desc\n\t}\n\tr.mediaType = desc.MediaType\n\tr.manifest = manifest\n\treturn r.manifest, nil\n}\n\nfunc (r *remoteIndex) IndexManifest() (*v1.IndexManifest, error) {\n\tb, err := r.RawManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn v1.ParseIndexManifest(bytes.NewReader(b))\n}\n\nfunc (r *remoteIndex) Image(h v1.Hash) (v1.Image, error) {\n\tdesc, err := r.childByHash(h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Descriptor.Image will handle coercing nested indexes into an Image.\n\treturn desc.Image()\n}\n\n// Descriptor retains the original descriptor from an index manifest.\n// See partial.Descriptor.\nfunc (r *remoteIndex) Descriptor() (*v1.Descriptor, error) {\n\t// kind of a hack, but RawManifest does appropriate locking/memoization\n\t// and makes sure r.descriptor is populated.\n\t_, err := r.RawManifest()\n\treturn r.descriptor, err\n}\n\nfunc (r *remoteIndex) ImageIndex(h v1.Hash) (v1.ImageIndex, error) {\n\tdesc, err := r.childByHash(h)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn desc.ImageIndex()\n}\n\n// Workaround for #819.\nfunc (r *remoteIndex) Layer(h v1.Hash) (v1.Layer, error) {\n\tindex, err := r.IndexManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, childDesc := range index.Manifests {\n\t\tif h == childDesc.Digest {\n\t\t\tl, err := partial.CompressedToLayer(&remoteLayer{\n\t\t\t\tfetcher: r.fetcher,\n\t\t\t\tctx:     r.ctx,\n\t\t\t\tdigest:  h,\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &MountableLayer{\n\t\t\t\tLayer:     l,\n\t\t\t\tReference: r.ref.Context().Digest(h.String()),\n\t\t\t}, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"layer not found: %s\", h)\n}\n\nfunc (r *remoteIndex) imageByPlatform(platform v1.Platform) (v1.Image, error) {\n\tdesc, err := r.childByPlatform(platform)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Descriptor.Image will handle coercing nested indexes into an Image.\n\treturn desc.Image()\n}\n\n// This naively matches the first manifest with matching platform attributes.\n//\n// We should probably use this instead:\n//\n//\tgithub.com/containerd/containerd/platforms\n//\n// But first we'd need to migrate to:\n//\n//\tgithub.com/opencontainers/image-spec/specs-go/v1\nfunc (r *remoteIndex) childByPlatform(platform v1.Platform) (*Descriptor, error) {\n\tindex, err := r.IndexManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, childDesc := range index.Manifests {\n\t\t// If platform is missing from child descriptor, assume it's amd64/linux.\n\t\tp := defaultPlatform\n\t\tif childDesc.Platform != nil {\n\t\t\tp = *childDesc.Platform\n\t\t}\n\n\t\tif matchesPlatform(p, platform) {\n\t\t\treturn r.childDescriptor(childDesc, platform)\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"no child with platform %+v in index %s\", platform, r.ref)\n}\n\nfunc (r *remoteIndex) childByHash(h v1.Hash) (*Descriptor, error) {\n\tindex, err := r.IndexManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor _, childDesc := range index.Manifests {\n\t\tif h == childDesc.Digest {\n\t\t\treturn r.childDescriptor(childDesc, defaultPlatform)\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"no child with digest %s in index %s\", h, r.ref)\n}\n\n// Convert one of this index's child's v1.Descriptor into a remote.Descriptor, with the given platform option.\nfunc (r *remoteIndex) childDescriptor(child v1.Descriptor, platform v1.Platform) (*Descriptor, error) {\n\tref := r.ref.Context().Digest(child.Digest.String())\n\tvar (\n\t\tmanifest []byte\n\t\terr      error\n\t)\n\tif child.Data != nil {\n\t\tif err := verify.Descriptor(child); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tmanifest = child.Data\n\t} else {\n\t\tmanifest, _, err = r.fetcher.fetchManifest(r.ctx, ref, []types.MediaType{child.MediaType})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif child.MediaType.IsImage() {\n\t\tmf, _ := v1.ParseManifest(bytes.NewReader(manifest))\n\t\t// Failing to parse as a manifest should just be ignored.\n\t\t// The manifest might not be valid, and that's okay.\n\t\tif mf != nil && !mf.Config.MediaType.IsConfig() {\n\t\t\tchild.ArtifactType = string(mf.Config.MediaType)\n\t\t}\n\t}\n\n\treturn &Descriptor{\n\t\tref:        ref,\n\t\tctx:        r.ctx,\n\t\tfetcher:    r.fetcher,\n\t\tManifest:   manifest,\n\t\tDescriptor: child,\n\t\tplatform:   platform,\n\t}, nil\n}\n\n// matchesPlatform checks if the given platform matches the required platforms.\n// The given platform matches the required platform if\n// - architecture and OS are identical.\n// - OS version and variant are identical if provided.\n// - features and OS features of the required platform are subsets of those of the given platform.\nfunc matchesPlatform(given, required v1.Platform) bool {\n\t// Required fields that must be identical.\n\tif given.Architecture != required.Architecture || given.OS != required.OS {\n\t\treturn false\n\t}\n\n\t// Optional fields that may be empty, but must be identical if provided.\n\tif required.OSVersion != \"\" && given.OSVersion != required.OSVersion {\n\t\treturn false\n\t}\n\tif required.Variant != \"\" && given.Variant != required.Variant {\n\t\treturn false\n\t}\n\n\t// Verify required platform's features are a subset of given platform's features.\n\tif !isSubset(given.OSFeatures, required.OSFeatures) {\n\t\treturn false\n\t}\n\tif !isSubset(given.Features, required.Features) {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// isSubset checks if the required array of strings is a subset of the given lst.\nfunc isSubset(lst, required []string) bool {\n\tset := make(map[string]bool)\n\tfor _, value := range lst {\n\t\tset[value] = true\n\t}\n\n\tfor _, value := range required {\n\t\tif _, ok := set[value]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/layer.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"context\"\n\t\"io\"\n\n\t\"github.com/google/go-containerregistry/internal/redact\"\n\t\"github.com/google/go-containerregistry/internal/verify\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// remoteImagelayer implements partial.CompressedLayer\ntype remoteLayer struct {\n\tctx     context.Context\n\tfetcher fetcher\n\tdigest  v1.Hash\n}\n\n// Compressed implements partial.CompressedLayer\nfunc (rl *remoteLayer) Compressed() (io.ReadCloser, error) {\n\t// We don't want to log binary layers -- this can break terminals.\n\tctx := redact.NewContext(rl.ctx, \"omitting binary blobs from logs\")\n\treturn rl.fetcher.fetchBlob(ctx, verify.SizeUnknown, rl.digest)\n}\n\n// Compressed implements partial.CompressedLayer\nfunc (rl *remoteLayer) Size() (int64, error) {\n\tresp, err := rl.fetcher.headBlob(rl.ctx, rl.digest)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\tdefer resp.Body.Close()\n\treturn resp.ContentLength, nil\n}\n\n// Digest implements partial.CompressedLayer\nfunc (rl *remoteLayer) Digest() (v1.Hash, error) {\n\treturn rl.digest, nil\n}\n\n// MediaType implements v1.Layer\nfunc (rl *remoteLayer) MediaType() (types.MediaType, error) {\n\treturn types.DockerLayer, nil\n}\n\n// See partial.Exists.\nfunc (rl *remoteLayer) Exists() (bool, error) {\n\treturn rl.fetcher.blobExists(rl.ctx, rl.digest)\n}\n\n// Layer reads the given blob reference from a registry as a Layer. A blob\n// reference here is just a punned name.Digest where the digest portion is the\n// digest of the blob to be read and the repository portion is the repo where\n// that blob lives.\nfunc Layer(ref name.Digest, options ...Option) (v1.Layer, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newPuller(o).Layer(o.context, ref)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/list.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n)\n\n// ListWithContext calls List with the given context.\n//\n// Deprecated: Use List and WithContext. This will be removed in a future release.\nfunc ListWithContext(ctx context.Context, repo name.Repository, options ...Option) ([]string, error) {\n\treturn List(repo, append(options, WithContext(ctx))...)\n}\n\n// List calls /tags/list for the given repository, returning the list of tags\n// in the \"tags\" property.\nfunc List(repo name.Repository, options ...Option) ([]string, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newPuller(o).List(o.context, repo)\n}\n\ntype Tags struct {\n\tName string   `json:\"name\"`\n\tTags []string `json:\"tags\"`\n\tNext string   `json:\"next,omitempty\"`\n}\n\nfunc (f *fetcher) listPage(ctx context.Context, repo name.Repository, next string, pageSize int) (*Tags, error) {\n\tif next == \"\" {\n\t\turi := &url.URL{\n\t\t\tScheme: repo.Scheme(),\n\t\t\tHost:   repo.RegistryStr(),\n\t\t\tPath:   fmt.Sprintf(\"/v2/%s/tags/list\", repo.RepositoryStr()),\n\t\t}\n\t\tif pageSize > 0 {\n\t\t\turi.RawQuery = fmt.Sprintf(\"n=%d\", pageSize)\n\t\t}\n\t\tnext = uri.String()\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", next, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := f.client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\treturn nil, err\n\t}\n\n\tparsed := Tags{}\n\tif err := json.NewDecoder(resp.Body).Decode(&parsed); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := resp.Body.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\n\turi, err := getNextPageURL(resp)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif uri != nil {\n\t\tparsed.Next = uri.String()\n\t}\n\n\treturn &parsed, nil\n}\n\n// getNextPageURL checks if there is a Link header in a http.Response which\n// contains a link to the next page. If yes it returns the url.URL of the next\n// page otherwise it returns nil.\nfunc getNextPageURL(resp *http.Response) (*url.URL, error) {\n\tlink := resp.Header.Get(\"Link\")\n\tif link == \"\" {\n\t\treturn nil, nil\n\t}\n\n\tif link[0] != '<' {\n\t\treturn nil, fmt.Errorf(\"failed to parse link header: missing '<' in: %s\", link)\n\t}\n\n\tend := strings.Index(link, \">\")\n\tif end == -1 {\n\t\treturn nil, fmt.Errorf(\"failed to parse link header: missing '>' in: %s\", link)\n\t}\n\tlink = link[1:end]\n\n\tlinkURL, err := url.Parse(link)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif resp.Request == nil || resp.Request.URL == nil {\n\t\treturn nil, nil\n\t}\n\tlinkURL = resp.Request.URL.ResolveReference(linkURL)\n\treturn linkURL, nil\n}\n\ntype Lister struct {\n\tf        *fetcher\n\trepo     name.Repository\n\tpageSize int\n\n\tpage *Tags\n\terr  error\n\n\tneedMore bool\n}\n\nfunc (l *Lister) Next(ctx context.Context) (*Tags, error) {\n\tif l.needMore {\n\t\tl.page, l.err = l.f.listPage(ctx, l.repo, l.page.Next, l.pageSize)\n\t} else {\n\t\tl.needMore = true\n\t}\n\treturn l.page, l.err\n}\n\nfunc (l *Lister) HasNext() bool {\n\treturn l.page != nil && (!l.needMore || l.page.Next != \"\")\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/mount.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n)\n\n// MountableLayer wraps a v1.Layer in a shim that enables the layer to be\n// \"mounted\" when published to another registry.\ntype MountableLayer struct {\n\tv1.Layer\n\n\tReference name.Reference\n}\n\n// Descriptor retains the original descriptor from an image manifest.\n// See partial.Descriptor.\nfunc (ml *MountableLayer) Descriptor() (*v1.Descriptor, error) {\n\treturn partial.Descriptor(ml.Layer)\n}\n\n// Exists is a hack. See partial.Exists.\nfunc (ml *MountableLayer) Exists() (bool, error) {\n\treturn partial.Exists(ml.Layer)\n}\n\n// mountableImage wraps the v1.Layer references returned by the embedded v1.Image\n// in MountableLayer's so that remote.Write might attempt to mount them from their\n// source repository.\ntype mountableImage struct {\n\tv1.Image\n\n\tReference name.Reference\n}\n\n// Layers implements v1.Image\nfunc (mi *mountableImage) Layers() ([]v1.Layer, error) {\n\tls, err := mi.Image.Layers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tmls := make([]v1.Layer, 0, len(ls))\n\tfor _, l := range ls {\n\t\tmls = append(mls, &MountableLayer{\n\t\t\tLayer:     l,\n\t\t\tReference: mi.Reference,\n\t\t})\n\t}\n\treturn mls, nil\n}\n\n// LayerByDigest implements v1.Image\nfunc (mi *mountableImage) LayerByDigest(d v1.Hash) (v1.Layer, error) {\n\tl, err := mi.Image.LayerByDigest(d)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &MountableLayer{\n\t\tLayer:     l,\n\t\tReference: mi.Reference,\n\t}, nil\n}\n\n// LayerByDiffID implements v1.Image\nfunc (mi *mountableImage) LayerByDiffID(d v1.Hash) (v1.Layer, error) {\n\tl, err := mi.Image.LayerByDiffID(d)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &MountableLayer{\n\t\tLayer:     l,\n\t\tReference: mi.Reference,\n\t}, nil\n}\n\n// Descriptor retains the original descriptor from an index manifest.\n// See partial.Descriptor.\nfunc (mi *mountableImage) Descriptor() (*v1.Descriptor, error) {\n\treturn partial.Descriptor(mi.Image)\n}\n\n// ConfigLayer retains the original reference so that it can be mounted.\n// See partial.ConfigLayer.\nfunc (mi *mountableImage) ConfigLayer() (v1.Layer, error) {\n\tl, err := partial.ConfigLayer(mi.Image)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &MountableLayer{\n\t\tLayer:     l,\n\t\tReference: mi.Reference,\n\t}, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/multi_write.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\n// MultiWrite writes the given Images or ImageIndexes to the given refs, as\n// efficiently as possible, by deduping shared layer blobs while uploading them\n// in parallel.\nfunc MultiWrite(todo map[name.Reference]Taggable, options ...Option) (rerr error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif o.progress != nil {\n\t\tdefer func() { o.progress.Close(rerr) }()\n\t}\n\tp := newPusher(o)\n\n\tg, ctx := errgroup.WithContext(o.context)\n\tg.SetLimit(o.jobs)\n\n\tfor ref, t := range todo {\n\t\tref, t := ref, t\n\t\tg.Go(func() error {\n\t\t\treturn p.Push(ctx, ref, t)\n\t\t})\n\t}\n\n\treturn g.Wait()\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/options.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/google/go-containerregistry/internal/retry\"\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n)\n\n// Option is a functional option for remote operations.\ntype Option func(*options) error\n\ntype options struct {\n\tauth                           authn.Authenticator\n\tkeychain                       authn.Keychain\n\ttransport                      http.RoundTripper\n\tcontext                        context.Context\n\tjobs                           int\n\tuserAgent                      string\n\tallowNondistributableArtifacts bool\n\tprogress                       *progress\n\tretryBackoff                   Backoff\n\tretryPredicate                 retry.Predicate\n\tretryStatusCodes               []int\n\n\t// Only these options can overwrite Reuse()d options.\n\tplatform v1.Platform\n\tpageSize int\n\tfilter   map[string]string\n\n\t// Set by Reuse, we currently store one or the other.\n\tpuller *Puller\n\tpusher *Pusher\n}\n\nvar defaultPlatform = v1.Platform{\n\tArchitecture: \"amd64\",\n\tOS:           \"linux\",\n}\n\n// Backoff is an alias of retry.Backoff to expose this configuration option to consumers of this lib\ntype Backoff = retry.Backoff\n\nvar defaultRetryPredicate retry.Predicate = func(err error) bool {\n\t// Various failure modes here, as we're often reading from and writing to\n\t// the network.\n\tif retry.IsTemporary(err) || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) || errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) || errors.Is(err, net.ErrClosed) {\n\t\tlogs.Warn.Printf(\"retrying %v\", err)\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Try this three times, waiting 1s after first failure, 3s after second.\nvar defaultRetryBackoff = Backoff{\n\tDuration: 1.0 * time.Second,\n\tFactor:   3.0,\n\tJitter:   0.1,\n\tSteps:    3,\n}\n\n// Useful for tests\nvar fastBackoff = Backoff{\n\tDuration: 1.0 * time.Millisecond,\n\tFactor:   3.0,\n\tJitter:   0.1,\n\tSteps:    3,\n}\n\nvar defaultRetryStatusCodes = []int{\n\thttp.StatusRequestTimeout,\n\thttp.StatusInternalServerError,\n\thttp.StatusBadGateway,\n\thttp.StatusServiceUnavailable,\n\thttp.StatusGatewayTimeout,\n\t499, // nginx-specific, client closed request\n\t522, // Cloudflare-specific, connection timeout\n}\n\nconst (\n\tdefaultJobs = 4\n\n\t// ECR returns an error if n > 1000:\n\t// https://github.com/google/go-containerregistry/issues/1091\n\tdefaultPageSize = 1000\n)\n\n// DefaultTransport is based on http.DefaultTransport with modifications\n// documented inline below.\nvar DefaultTransport http.RoundTripper = &http.Transport{\n\tProxy: http.ProxyFromEnvironment,\n\tDialContext: (&net.Dialer{\n\t\tTimeout:   30 * time.Second,\n\t\tKeepAlive: 30 * time.Second,\n\t}).DialContext,\n\tForceAttemptHTTP2:     true,\n\tMaxIdleConns:          100,\n\tIdleConnTimeout:       90 * time.Second,\n\tTLSHandshakeTimeout:   10 * time.Second,\n\tExpectContinueTimeout: 1 * time.Second,\n\t// We usually are dealing with 2 hosts (at most), split MaxIdleConns between them.\n\tMaxIdleConnsPerHost: 50,\n}\n\nfunc makeOptions(opts ...Option) (*options, error) {\n\to := &options{\n\t\ttransport:        DefaultTransport,\n\t\tplatform:         defaultPlatform,\n\t\tcontext:          context.Background(),\n\t\tjobs:             defaultJobs,\n\t\tpageSize:         defaultPageSize,\n\t\tretryPredicate:   defaultRetryPredicate,\n\t\tretryBackoff:     defaultRetryBackoff,\n\t\tretryStatusCodes: defaultRetryStatusCodes,\n\t}\n\n\tfor _, option := range opts {\n\t\tif err := option(o); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tswitch {\n\tcase o.auth != nil && o.keychain != nil:\n\t\t// It is a better experience to explicitly tell a caller their auth is misconfigured\n\t\t// than potentially fail silently when the correct auth is overridden by option misuse.\n\t\treturn nil, errors.New(\"provide an option for either authn.Authenticator or authn.Keychain, not both\")\n\tcase o.auth == nil:\n\t\to.auth = authn.Anonymous\n\t}\n\n\t// transport.Wrapper is a signal that consumers are opt-ing into providing their own transport without any additional wrapping.\n\t// This is to allow consumers full control over the transports logic, such as providing retry logic.\n\tif _, ok := o.transport.(*transport.Wrapper); !ok {\n\t\t// Wrap the transport in something that logs requests and responses.\n\t\t// It's expensive to generate the dumps, so skip it if we're writing\n\t\t// to nothing.\n\t\tif logs.Enabled(logs.Debug) {\n\t\t\to.transport = transport.NewLogger(o.transport)\n\t\t}\n\n\t\t// Wrap the transport in something that can retry network flakes.\n\t\to.transport = transport.NewRetry(o.transport, transport.WithRetryPredicate(defaultRetryPredicate), transport.WithRetryStatusCodes(o.retryStatusCodes...))\n\n\t\t// Wrap this last to prevent transport.New from double-wrapping.\n\t\tif o.userAgent != \"\" {\n\t\t\to.transport = transport.NewUserAgent(o.transport, o.userAgent)\n\t\t}\n\t}\n\n\treturn o, nil\n}\n\n// WithTransport is a functional option for overriding the default transport\n// for remote operations.\n// If transport.Wrapper is provided, this signals that the consumer does *not* want any further wrapping to occur.\n// i.e. logging, retry and useragent\n//\n// The default transport is DefaultTransport.\nfunc WithTransport(t http.RoundTripper) Option {\n\treturn func(o *options) error {\n\t\to.transport = t\n\t\treturn nil\n\t}\n}\n\n// WithAuth is a functional option for overriding the default authenticator\n// for remote operations.\n// It is an error to use both WithAuth and WithAuthFromKeychain in the same Option set.\n//\n// The default authenticator is authn.Anonymous.\nfunc WithAuth(auth authn.Authenticator) Option {\n\treturn func(o *options) error {\n\t\to.auth = auth\n\t\treturn nil\n\t}\n}\n\n// WithAuthFromKeychain is a functional option for overriding the default\n// authenticator for remote operations, using an authn.Keychain to find\n// credentials.\n// It is an error to use both WithAuth and WithAuthFromKeychain in the same Option set.\n//\n// The default authenticator is authn.Anonymous.\nfunc WithAuthFromKeychain(keys authn.Keychain) Option {\n\treturn func(o *options) error {\n\t\to.keychain = keys\n\t\treturn nil\n\t}\n}\n\n// WithPlatform is a functional option for overriding the default platform\n// that Image and Descriptor.Image use for resolving an index to an image.\n//\n// The default platform is amd64/linux.\nfunc WithPlatform(p v1.Platform) Option {\n\treturn func(o *options) error {\n\t\to.platform = p\n\t\treturn nil\n\t}\n}\n\n// WithContext is a functional option for setting the context in http requests\n// performed by a given function. Note that this context is used for _all_\n// http requests, not just the initial volley. E.g., for remote.Image, the\n// context will be set on http requests generated by subsequent calls to\n// RawConfigFile() and even methods on layers returned by Layers().\n//\n// The default context is context.Background().\nfunc WithContext(ctx context.Context) Option {\n\treturn func(o *options) error {\n\t\to.context = ctx\n\t\treturn nil\n\t}\n}\n\n// WithJobs is a functional option for setting the parallelism of remote\n// operations performed by a given function. Note that not all remote\n// operations support parallelism.\n//\n// The default value is 4.\nfunc WithJobs(jobs int) Option {\n\treturn func(o *options) error {\n\t\tif jobs <= 0 {\n\t\t\treturn errors.New(\"jobs must be greater than zero\")\n\t\t}\n\t\to.jobs = jobs\n\t\treturn nil\n\t}\n}\n\n// WithUserAgent adds the given string to the User-Agent header for any HTTP\n// requests. This header will also include \"go-containerregistry/${version}\".\n//\n// If you want to completely overwrite the User-Agent header, use WithTransport.\nfunc WithUserAgent(ua string) Option {\n\treturn func(o *options) error {\n\t\to.userAgent = ua\n\t\treturn nil\n\t}\n}\n\n// WithNondistributable includes non-distributable (foreign) layers\n// when writing images, see:\n// https://github.com/opencontainers/image-spec/blob/master/layer.md#non-distributable-layers\n//\n// The default behaviour is to skip these layers\nfunc WithNondistributable(o *options) error {\n\to.allowNondistributableArtifacts = true\n\treturn nil\n}\n\n// WithProgress takes a channel that will receive progress updates as bytes are written.\n//\n// Sending updates to an unbuffered channel will block writes, so callers\n// should provide a buffered channel to avoid potential deadlocks.\nfunc WithProgress(updates chan<- v1.Update) Option {\n\treturn func(o *options) error {\n\t\to.progress = &progress{updates: updates}\n\t\to.progress.lastUpdate = &v1.Update{}\n\t\treturn nil\n\t}\n}\n\n// WithPageSize sets the given size as the value of parameter 'n' in the request.\n//\n// To omit the `n` parameter entirely, use WithPageSize(0).\n// The default value is 1000.\nfunc WithPageSize(size int) Option {\n\treturn func(o *options) error {\n\t\to.pageSize = size\n\t\treturn nil\n\t}\n}\n\n// WithRetryBackoff sets the httpBackoff for retry HTTP operations.\nfunc WithRetryBackoff(backoff Backoff) Option {\n\treturn func(o *options) error {\n\t\to.retryBackoff = backoff\n\t\treturn nil\n\t}\n}\n\n// WithRetryPredicate sets the predicate for retry HTTP operations.\nfunc WithRetryPredicate(predicate retry.Predicate) Option {\n\treturn func(o *options) error {\n\t\to.retryPredicate = predicate\n\t\treturn nil\n\t}\n}\n\n// WithRetryStatusCodes sets which http response codes will be retried.\nfunc WithRetryStatusCodes(codes ...int) Option {\n\treturn func(o *options) error {\n\t\to.retryStatusCodes = codes\n\t\treturn nil\n\t}\n}\n\n// WithFilter sets the filter querystring for HTTP operations.\nfunc WithFilter(key string, value string) Option {\n\treturn func(o *options) error {\n\t\tif o.filter == nil {\n\t\t\to.filter = map[string]string{}\n\t\t}\n\t\to.filter[key] = value\n\t\treturn nil\n\t}\n}\n\n// Reuse takes a Puller or Pusher and reuses it for remote interactions\n// rather than starting from a clean slate. For example, it will reuse token exchanges\n// when possible and avoid sending redundant HEAD requests.\n//\n// Reuse will take precedence over other options passed to most remote functions because\n// most options deal with setting up auth and transports, which Reuse intetionally skips.\nfunc Reuse[I *Puller | *Pusher](i I) Option {\n\treturn func(o *options) error {\n\t\tif puller, ok := any(i).(*Puller); ok {\n\t\t\to.puller = puller\n\t\t} else if pusher, ok := any(i).(*Pusher); ok {\n\t\t\to.pusher = pusher\n\t\t}\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/progress.go",
    "content": "// Copyright 2022 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"io\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n)\n\ntype progress struct {\n\tsync.Mutex\n\tupdates    chan<- v1.Update\n\tlastUpdate *v1.Update\n}\n\nfunc (p *progress) total(delta int64) {\n\tp.Lock()\n\tdefer p.Unlock()\n\tatomic.AddInt64(&p.lastUpdate.Total, delta)\n}\n\nfunc (p *progress) complete(delta int64) {\n\tp.Lock()\n\tdefer p.Unlock()\n\tp.updates <- v1.Update{\n\t\tTotal:    p.lastUpdate.Total,\n\t\tComplete: atomic.AddInt64(&p.lastUpdate.Complete, delta),\n\t}\n}\n\nfunc (p *progress) err(err error) error {\n\tif err != nil && p.updates != nil {\n\t\tp.updates <- v1.Update{Error: err}\n\t}\n\treturn err\n}\n\nfunc (p *progress) Close(err error) {\n\t_ = p.err(err)\n\tclose(p.updates)\n}\n\ntype progressReader struct {\n\trc io.ReadCloser\n\n\tcount    *int64 // number of bytes this reader has read, to support resetting on retry.\n\tprogress *progress\n}\n\nfunc (r *progressReader) Read(b []byte) (int, error) {\n\tn, err := r.rc.Read(b)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\tatomic.AddInt64(r.count, int64(n))\n\t// TODO: warn/debug log if sending takes too long, or if sending is blocked while context is canceled.\n\tr.progress.complete(int64(n))\n\treturn n, nil\n}\n\nfunc (r *progressReader) Close() error { return r.rc.Close() }\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/puller.go",
    "content": "// Copyright 2023 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype Puller struct {\n\to *options\n\n\t// map[resource]*reader\n\treaders sync.Map\n}\n\nfunc NewPuller(options ...Option) (*Puller, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn newPuller(o), nil\n}\n\nfunc newPuller(o *options) *Puller {\n\tif o.puller != nil {\n\t\treturn o.puller\n\t}\n\treturn &Puller{\n\t\to: o,\n\t}\n}\n\ntype reader struct {\n\t// in\n\ttarget resource\n\to      *options\n\n\t// f()\n\tonce sync.Once\n\n\t// out\n\tf   *fetcher\n\terr error\n}\n\n// this will run once per reader instance\nfunc (r *reader) init(ctx context.Context) error {\n\tr.once.Do(func() {\n\t\tr.f, r.err = makeFetcher(ctx, r.target, r.o)\n\t})\n\treturn r.err\n}\n\nfunc (p *Puller) fetcher(ctx context.Context, target resource) (*fetcher, error) {\n\tv, _ := p.readers.LoadOrStore(target, &reader{\n\t\ttarget: target,\n\t\to:      p.o,\n\t})\n\trr := v.(*reader)\n\treturn rr.f, rr.init(ctx)\n}\n\n// Head is like remote.Head, but avoids re-authenticating when possible.\nfunc (p *Puller) Head(ctx context.Context, ref name.Reference) (*v1.Descriptor, error) {\n\tf, err := p.fetcher(ctx, ref.Context())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn f.headManifest(ctx, ref, allManifestMediaTypes)\n}\n\n// Get is like remote.Get, but avoids re-authenticating when possible.\nfunc (p *Puller) Get(ctx context.Context, ref name.Reference) (*Descriptor, error) {\n\treturn p.get(ctx, ref, allManifestMediaTypes, p.o.platform)\n}\n\nfunc (p *Puller) get(ctx context.Context, ref name.Reference, acceptable []types.MediaType, platform v1.Platform) (*Descriptor, error) {\n\tf, err := p.fetcher(ctx, ref.Context())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn f.get(ctx, ref, acceptable, platform)\n}\n\n// Layer is like remote.Layer, but avoids re-authenticating when possible.\nfunc (p *Puller) Layer(ctx context.Context, ref name.Digest) (v1.Layer, error) {\n\tf, err := p.fetcher(ctx, ref.Context())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\th, err := v1.NewHash(ref.Identifier())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tl, err := partial.CompressedToLayer(&remoteLayer{\n\t\tfetcher: *f,\n\t\tctx:     ctx,\n\t\tdigest:  h,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &MountableLayer{\n\t\tLayer:     l,\n\t\tReference: ref,\n\t}, nil\n}\n\n// List lists tags in a repo and handles pagination, returning the full list of tags.\nfunc (p *Puller) List(ctx context.Context, repo name.Repository) ([]string, error) {\n\tlister, err := p.Lister(ctx, repo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttagList := []string{}\n\tfor lister.HasNext() {\n\t\ttags, err := lister.Next(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\ttagList = append(tagList, tags.Tags...)\n\t}\n\n\treturn tagList, nil\n}\n\n// Lister lists tags in a repo and returns a Lister for paginating through the results.\nfunc (p *Puller) Lister(ctx context.Context, repo name.Repository) (*Lister, error) {\n\treturn p.lister(ctx, repo, p.o.pageSize)\n}\n\nfunc (p *Puller) lister(ctx context.Context, repo name.Repository, pageSize int) (*Lister, error) {\n\tf, err := p.fetcher(ctx, repo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpage, err := f.listPage(ctx, repo, \"\", pageSize)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Lister{\n\t\tf:        f,\n\t\trepo:     repo,\n\t\tpageSize: pageSize,\n\t\tpage:     page,\n\t\terr:      err,\n\t}, nil\n}\n\n// Catalog lists repos in a registry and handles pagination, returning the full list of repos.\nfunc (p *Puller) Catalog(ctx context.Context, reg name.Registry) ([]string, error) {\n\treturn p.catalog(ctx, reg, p.o.pageSize)\n}\n\nfunc (p *Puller) catalog(ctx context.Context, reg name.Registry, pageSize int) ([]string, error) {\n\tcatalogger, err := p.catalogger(ctx, reg, pageSize)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trepoList := []string{}\n\tfor catalogger.HasNext() {\n\t\trepos, err := catalogger.Next(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\trepoList = append(repoList, repos.Repos...)\n\t}\n\treturn repoList, nil\n}\n\n// Catalogger lists repos in a registry and returns a Catalogger for paginating through the results.\nfunc (p *Puller) Catalogger(ctx context.Context, reg name.Registry) (*Catalogger, error) {\n\treturn p.catalogger(ctx, reg, p.o.pageSize)\n}\n\nfunc (p *Puller) catalogger(ctx context.Context, reg name.Registry, pageSize int) (*Catalogger, error) {\n\tf, err := p.fetcher(ctx, reg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tpage, err := f.catalogPage(ctx, reg, \"\", pageSize)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Catalogger{\n\t\tf:        f,\n\t\treg:      reg,\n\t\tpageSize: pageSize,\n\t\tpage:     page,\n\t\terr:      err,\n\t}, nil\n}\n\nfunc (p *Puller) referrers(ctx context.Context, d name.Digest, filter map[string]string) (v1.ImageIndex, error) {\n\tf, err := p.fetcher(ctx, d.Context())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn f.fetchReferrers(ctx, filter, d)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/pusher.go",
    "content": "// Copyright 2023 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n\t\"github.com/google/go-containerregistry/pkg/v1/stream\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n\t\"golang.org/x/sync/errgroup\"\n)\n\ntype manifest interface {\n\tTaggable\n\tpartial.Describable\n}\n\n// key is either v1.Hash or v1.Layer (for stream.Layer)\ntype workers struct {\n\t// map[v1.Hash|v1.Layer]*sync.Once\n\tonces sync.Map\n\n\t// map[v1.Hash|v1.Layer]error\n\terrors sync.Map\n}\n\nfunc nop() error {\n\treturn nil\n}\n\nfunc (w *workers) err(digest v1.Hash) error {\n\tv, ok := w.errors.Load(digest)\n\tif !ok || v == nil {\n\t\treturn nil\n\t}\n\treturn v.(error)\n}\n\nfunc (w *workers) Do(digest v1.Hash, f func() error) error {\n\t// We don't care if it was loaded or not because the sync.Once will do it for us.\n\tonce, _ := w.onces.LoadOrStore(digest, &sync.Once{})\n\n\tonce.(*sync.Once).Do(func() {\n\t\tw.errors.Store(digest, f())\n\t})\n\n\terr := w.err(digest)\n\tif err != nil {\n\t\t// Allow this to be retried by another caller.\n\t\tw.onces.Delete(digest)\n\t}\n\treturn err\n}\n\nfunc (w *workers) Stream(layer v1.Layer, f func() error) error {\n\t// We don't care if it was loaded or not because the sync.Once will do it for us.\n\tonce, _ := w.onces.LoadOrStore(layer, &sync.Once{})\n\n\tonce.(*sync.Once).Do(func() {\n\t\tw.errors.Store(layer, f())\n\t})\n\n\tv, ok := w.errors.Load(layer)\n\tif !ok || v == nil {\n\t\treturn nil\n\t}\n\n\treturn v.(error)\n}\n\ntype Pusher struct {\n\to *options\n\n\t// map[name.Repository]*repoWriter\n\twriters sync.Map\n}\n\nfunc NewPusher(options ...Option) (*Pusher, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn newPusher(o), nil\n}\n\nfunc newPusher(o *options) *Pusher {\n\tif o.pusher != nil {\n\t\treturn o.pusher\n\t}\n\treturn &Pusher{\n\t\to: o,\n\t}\n}\n\nfunc (p *Pusher) writer(ctx context.Context, repo name.Repository, o *options) (*repoWriter, error) {\n\tv, _ := p.writers.LoadOrStore(repo, &repoWriter{\n\t\trepo: repo,\n\t\to:    o,\n\t})\n\trw := v.(*repoWriter)\n\treturn rw, rw.init(ctx)\n}\n\nfunc (p *Pusher) Push(ctx context.Context, ref name.Reference, t Taggable) error {\n\tw, err := p.writer(ctx, ref.Context(), p.o)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn w.writeManifest(ctx, ref, t)\n}\n\nfunc (p *Pusher) Upload(ctx context.Context, repo name.Repository, l v1.Layer) error {\n\tw, err := p.writer(ctx, repo, p.o)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn w.writeLayer(ctx, l)\n}\n\nfunc (p *Pusher) Delete(ctx context.Context, ref name.Reference) error {\n\tw, err := p.writer(ctx, ref.Context(), p.o)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tu := url.URL{\n\t\tScheme: ref.Context().Registry.Scheme(),\n\t\tHost:   ref.Context().RegistryStr(),\n\t\tPath:   fmt.Sprintf(\"/v2/%s/manifests/%s\", ref.Context().RepositoryStr(), ref.Identifier()),\n\t}\n\n\treq, err := http.NewRequest(http.MethodDelete, u.String(), nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresp, err := w.w.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\treturn transport.CheckError(resp, http.StatusOK, http.StatusAccepted)\n\n\t// TODO(jason): If the manifest had a `subject`, and if the registry\n\t// doesn't support Referrers, update the index pointed to by the\n\t// subject's fallback tag to remove the descriptor for this manifest.\n}\n\ntype repoWriter struct {\n\trepo name.Repository\n\to    *options\n\tonce sync.Once\n\n\tw   *writer\n\terr error\n\n\twork *workers\n}\n\n// this will run once per repoWriter instance\nfunc (rw *repoWriter) init(ctx context.Context) error {\n\trw.once.Do(func() {\n\t\trw.work = &workers{}\n\t\trw.w, rw.err = makeWriter(ctx, rw.repo, nil, rw.o)\n\t})\n\treturn rw.err\n}\n\nfunc (rw *repoWriter) writeDeps(ctx context.Context, m manifest) error {\n\tif img, ok := m.(v1.Image); ok {\n\t\treturn rw.writeLayers(ctx, img)\n\t}\n\n\tif idx, ok := m.(v1.ImageIndex); ok {\n\t\treturn rw.writeChildren(ctx, idx)\n\t}\n\n\t// This has no deps, not an error (e.g. something you want to just PUT).\n\treturn nil\n}\n\ntype describable struct {\n\tdesc v1.Descriptor\n}\n\nfunc (d describable) Digest() (v1.Hash, error) {\n\treturn d.desc.Digest, nil\n}\n\nfunc (d describable) Size() (int64, error) {\n\treturn d.desc.Size, nil\n}\n\nfunc (d describable) MediaType() (types.MediaType, error) {\n\treturn d.desc.MediaType, nil\n}\n\ntype tagManifest struct {\n\tTaggable\n\tpartial.Describable\n}\n\nfunc taggableToManifest(t Taggable) (manifest, error) {\n\tif m, ok := t.(manifest); ok {\n\t\treturn m, nil\n\t}\n\n\tif d, ok := t.(*Descriptor); ok {\n\t\tif d.MediaType.IsIndex() {\n\t\t\treturn d.ImageIndex()\n\t\t}\n\n\t\tif d.MediaType.IsImage() {\n\t\t\treturn d.Image()\n\t\t}\n\n\t\tif d.MediaType.IsSchema1() {\n\t\t\treturn d.Schema1()\n\t\t}\n\n\t\treturn tagManifest{t, describable{d.toDesc()}}, nil\n\t}\n\n\tdesc := v1.Descriptor{\n\t\t// A reasonable default if Taggable doesn't implement MediaType.\n\t\tMediaType: types.DockerManifestSchema2,\n\t}\n\n\tb, err := t.RawManifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif wmt, ok := t.(withMediaType); ok {\n\t\tdesc.MediaType, err = wmt.MediaType()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tdesc.Digest, desc.Size, err = v1.SHA256(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn tagManifest{t, describable{desc}}, nil\n}\n\nfunc (rw *repoWriter) writeManifest(ctx context.Context, ref name.Reference, t Taggable) error {\n\tm, err := taggableToManifest(t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tneedDeps := true\n\n\tdigest, err := m.Digest()\n\tif errors.Is(err, stream.ErrNotComputed) {\n\t\tif err := rw.writeDeps(ctx, m); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tneedDeps = false\n\n\t\tdigest, err = m.Digest()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\t// This may be a lazy child where we have no ref until digest is computed.\n\tif ref == nil {\n\t\tref = rw.repo.Digest(digest.String())\n\t}\n\n\t// For tags, we want to do this check outside of our Work.Do closure because\n\t// we don't want to dedupe based on the manifest digest.\n\t_, byTag := ref.(name.Tag)\n\tif byTag {\n\t\tif exists, err := rw.manifestExists(ctx, ref, t); err != nil {\n\t\t\treturn err\n\t\t} else if exists {\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// The following work.Do will get deduped by digest, so it won't happen unless\n\t// this tag happens to be the first commitManifest to run for that digest.\n\tneedPut := byTag\n\n\tif err := rw.work.Do(digest, func() error {\n\t\tif !byTag {\n\t\t\tif exists, err := rw.manifestExists(ctx, ref, t); err != nil {\n\t\t\t\treturn err\n\t\t\t} else if exists {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\n\t\tif needDeps {\n\t\t\tif err := rw.writeDeps(ctx, m); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tneedPut = false\n\t\treturn rw.commitManifest(ctx, ref, m)\n\t}); err != nil {\n\t\treturn err\n\t}\n\n\tif !needPut {\n\t\treturn nil\n\t}\n\n\t// Only runs for tags that got deduped by digest.\n\treturn rw.commitManifest(ctx, ref, m)\n}\n\nfunc (rw *repoWriter) writeChildren(ctx context.Context, idx v1.ImageIndex) error {\n\tchildren, err := partial.Manifests(idx)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tg, ctx := errgroup.WithContext(ctx)\n\tg.SetLimit(rw.o.jobs)\n\n\tfor _, child := range children {\n\t\tchild := child\n\t\tif err := rw.writeChild(ctx, child, g); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn g.Wait()\n}\n\nfunc (rw *repoWriter) writeChild(ctx context.Context, child partial.Describable, g *errgroup.Group) error {\n\tswitch child := child.(type) {\n\tcase v1.ImageIndex:\n\t\t// For recursive index, we want to do a depth-first launching of goroutines\n\t\t// to avoid deadlocking.\n\t\t//\n\t\t// Note that this is rare, so the impact of this should be really small.\n\t\treturn rw.writeManifest(ctx, nil, child)\n\tcase v1.Image:\n\t\tg.Go(func() error {\n\t\t\treturn rw.writeManifest(ctx, nil, child)\n\t\t})\n\tcase v1.Layer:\n\t\tg.Go(func() error {\n\t\t\treturn rw.writeLayer(ctx, child)\n\t\t})\n\tdefault:\n\t\t// This can't happen.\n\t\treturn fmt.Errorf(\"encountered unknown child: %T\", child)\n\t}\n\treturn nil\n}\n\n// TODO: Consider caching some representation of the tags/digests in the destination\n// repository as a hint to avoid this optimistic check in cases where we will most\n// likely have to do a PUT anyway, e.g. if we are overwriting a tag we just wrote.\nfunc (rw *repoWriter) manifestExists(ctx context.Context, ref name.Reference, t Taggable) (bool, error) {\n\tf := &fetcher{\n\t\ttarget: ref.Context(),\n\t\tclient: rw.w.client,\n\t}\n\n\tm, err := taggableToManifest(t)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tdigest, err := m.Digest()\n\tif err != nil {\n\t\t// Possibly due to streaming layers.\n\t\treturn false, nil\n\t}\n\tgot, err := f.headManifest(ctx, ref, allManifestMediaTypes)\n\tif err != nil {\n\t\tvar terr *transport.Error\n\t\tif errors.As(err, &terr) {\n\t\t\tif terr.StatusCode == http.StatusNotFound {\n\t\t\t\treturn false, nil\n\t\t\t}\n\n\t\t\t// We treat a 403 here as non-fatal because this existence check is an optimization and\n\t\t\t// some registries will return a 403 instead of a 404 in certain situations.\n\t\t\t// E.g. https://jfrog.atlassian.net/browse/RTFACT-13797\n\t\t\tif terr.StatusCode == http.StatusForbidden {\n\t\t\t\tlogs.Debug.Printf(\"manifestExists unexpected 403: %v\", err)\n\t\t\t\treturn false, nil\n\t\t\t}\n\t\t}\n\n\t\treturn false, err\n\t}\n\n\tif digest != got.Digest {\n\t\t// Mark that we saw this digest in the registry so we don't have to check it again.\n\t\trw.work.Do(got.Digest, nop)\n\n\t\treturn false, nil\n\t}\n\n\tif tag, ok := ref.(name.Tag); ok {\n\t\tlogs.Progress.Printf(\"existing manifest: %s@%s\", tag.Identifier(), got.Digest)\n\t} else {\n\t\tlogs.Progress.Print(\"existing manifest: \", got.Digest)\n\t}\n\n\treturn true, nil\n}\n\nfunc (rw *repoWriter) commitManifest(ctx context.Context, ref name.Reference, m manifest) error {\n\tif rw.o.progress != nil {\n\t\tsize, err := m.Size()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trw.o.progress.total(size)\n\t}\n\n\treturn rw.w.commitManifest(ctx, m, ref)\n}\n\nfunc (rw *repoWriter) writeLayers(pctx context.Context, img v1.Image) error {\n\tls, err := img.Layers()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tg, ctx := errgroup.WithContext(pctx)\n\tg.SetLimit(rw.o.jobs)\n\n\tfor _, l := range ls {\n\t\tl := l\n\n\t\tg.Go(func() error {\n\t\t\treturn rw.writeLayer(ctx, l)\n\t\t})\n\t}\n\n\tmt, err := img.MediaType()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif mt.IsSchema1() {\n\t\treturn g.Wait()\n\t}\n\n\tcl, err := partial.ConfigLayer(img)\n\tif errors.Is(err, stream.ErrNotComputed) {\n\t\tif err := g.Wait(); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tcl, err := partial.ConfigLayer(img)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn rw.writeLayer(pctx, cl)\n\t} else if err != nil {\n\t\treturn err\n\t}\n\n\tg.Go(func() error {\n\t\treturn rw.writeLayer(ctx, cl)\n\t})\n\n\treturn g.Wait()\n}\n\nfunc (rw *repoWriter) writeLayer(ctx context.Context, l v1.Layer) error {\n\t// Skip any non-distributable things.\n\tmt, err := l.MediaType()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !mt.IsDistributable() && !rw.o.allowNondistributableArtifacts {\n\t\treturn nil\n\t}\n\n\tdigest, err := l.Digest()\n\tif err != nil {\n\t\tif errors.Is(err, stream.ErrNotComputed) {\n\t\t\treturn rw.lazyWriteLayer(ctx, l)\n\t\t}\n\t\treturn err\n\t}\n\n\treturn rw.work.Do(digest, func() error {\n\t\tif rw.o.progress != nil {\n\t\t\tsize, err := l.Size()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\trw.o.progress.total(size)\n\t\t}\n\t\treturn rw.w.uploadOne(ctx, l)\n\t})\n}\n\nfunc (rw *repoWriter) lazyWriteLayer(ctx context.Context, l v1.Layer) error {\n\treturn rw.work.Stream(l, func() error {\n\t\tif err := rw.w.uploadOne(ctx, l); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Mark this upload completed.\n\t\tdigest, err := l.Digest()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\trw.work.Do(digest, nop)\n\n\t\tif rw.o.progress != nil {\n\t\t\tsize, err := l.Size()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\trw.o.progress.total(size)\n\t\t}\n\n\t\treturn nil\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/referrers.go",
    "content": "// Copyright 2023 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/empty\"\n\t\"github.com/google/go-containerregistry/pkg/v1/mutate\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// Referrers returns a list of descriptors that refer to the given manifest digest.\n//\n// The subject manifest doesn't have to exist in the registry for there to be descriptors that refer to it.\nfunc Referrers(d name.Digest, options ...Option) (v1.ImageIndex, error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn newPuller(o).referrers(o.context, d, o.filter)\n}\n\n// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#referrers-tag-schema\nfunc fallbackTag(d name.Digest) name.Tag {\n\treturn d.Context().Tag(strings.Replace(d.DigestStr(), \":\", \"-\", 1))\n}\n\nfunc (f *fetcher) fetchReferrers(ctx context.Context, filter map[string]string, d name.Digest) (v1.ImageIndex, error) {\n\t// Check the Referrers API endpoint first.\n\tu := f.url(\"referrers\", d.DigestStr())\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Accept\", string(types.OCIImageIndex))\n\n\tresp, err := f.client.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound, http.StatusBadRequest); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar b []byte\n\tif resp.StatusCode == http.StatusOK {\n\t\tb, err = io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t} else {\n\t\t// The registry doesn't support the Referrers API endpoint, so we'll use the fallback tag scheme.\n\t\tb, _, err = f.fetchManifest(ctx, fallbackTag(d), []types.MediaType{types.OCIImageIndex})\n\t\tvar terr *transport.Error\n\t\tif errors.As(err, &terr) && terr.StatusCode == http.StatusNotFound {\n\t\t\t// Not found just means there are no attachments yet. Start with an empty manifest.\n\t\t\treturn empty.Index, nil\n\t\t} else if err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\th, sz, err := v1.SHA256(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tidx := &remoteIndex{\n\t\tfetcher:   *f,\n\t\tctx:       ctx,\n\t\tmanifest:  b,\n\t\tmediaType: types.OCIImageIndex,\n\t\tdescriptor: &v1.Descriptor{\n\t\t\tDigest:    h,\n\t\t\tMediaType: types.OCIImageIndex,\n\t\t\tSize:      sz,\n\t\t},\n\t}\n\treturn filterReferrersResponse(filter, idx), nil\n}\n\n// If filter applied, filter out by artifactType.\n// See https://github.com/opencontainers/distribution-spec/blob/main/spec.md#listing-referrers\nfunc filterReferrersResponse(filter map[string]string, in v1.ImageIndex) v1.ImageIndex {\n\tif filter == nil {\n\t\treturn in\n\t}\n\tv, ok := filter[\"artifactType\"]\n\tif !ok {\n\t\treturn in\n\t}\n\treturn mutate.RemoveManifests(in, func(desc v1.Descriptor) bool {\n\t\treturn desc.ArtifactType != v\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/schema1.go",
    "content": "// Copyright 2023 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype schema1 struct {\n\tref        name.Reference\n\tctx        context.Context\n\tfetcher    fetcher\n\tmanifest   []byte\n\tmediaType  types.MediaType\n\tdescriptor *v1.Descriptor\n}\n\nfunc (s *schema1) Layers() ([]v1.Layer, error) {\n\tm := schema1Manifest{}\n\tif err := json.NewDecoder(bytes.NewReader(s.manifest)).Decode(&m); err != nil {\n\t\treturn nil, err\n\t}\n\n\tlayers := []v1.Layer{}\n\tfor i := len(m.FSLayers) - 1; i >= 0; i-- {\n\t\tfsl := m.FSLayers[i]\n\n\t\th, err := v1.NewHash(fsl.BlobSum)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tl, err := s.LayerByDigest(h)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlayers = append(layers, l)\n\t}\n\n\treturn layers, nil\n}\n\nfunc (s *schema1) MediaType() (types.MediaType, error) {\n\treturn s.mediaType, nil\n}\n\nfunc (s *schema1) Size() (int64, error) {\n\treturn s.descriptor.Size, nil\n}\n\nfunc (s *schema1) ConfigName() (v1.Hash, error) {\n\treturn partial.ConfigName(s)\n}\n\nfunc (s *schema1) ConfigFile() (*v1.ConfigFile, error) {\n\treturn nil, newErrSchema1(s.mediaType)\n}\n\nfunc (s *schema1) RawConfigFile() ([]byte, error) {\n\treturn []byte(\"{}\"), nil\n}\n\nfunc (s *schema1) Digest() (v1.Hash, error) {\n\treturn s.descriptor.Digest, nil\n}\n\nfunc (s *schema1) Manifest() (*v1.Manifest, error) {\n\treturn nil, newErrSchema1(s.mediaType)\n}\n\nfunc (s *schema1) RawManifest() ([]byte, error) {\n\treturn s.manifest, nil\n}\n\nfunc (s *schema1) LayerByDigest(h v1.Hash) (v1.Layer, error) {\n\tl, err := partial.CompressedToLayer(&remoteLayer{\n\t\tfetcher: s.fetcher,\n\t\tctx:     s.ctx,\n\t\tdigest:  h,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &MountableLayer{\n\t\tLayer:     l,\n\t\tReference: s.ref.Context().Digest(h.String()),\n\t}, nil\n}\n\nfunc (s *schema1) LayerByDiffID(v1.Hash) (v1.Layer, error) {\n\treturn nil, newErrSchema1(s.mediaType)\n}\n\ntype fslayer struct {\n\tBlobSum string `json:\"blobSum\"`\n}\n\ntype schema1Manifest struct {\n\tFSLayers []fslayer `json:\"fsLayers\"`\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/README.md",
    "content": "# `transport`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/transport?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/transport)\n\nThe [distribution protocol](https://github.com/opencontainers/distribution-spec) is fairly simple, but correctly [implementing authentication](../../../authn/README.md) is **hard**.\n\nThis package [implements](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote/transport#New) an [`http.RoundTripper`](https://godoc.org/net/http#RoundTripper)\nthat transparently performs:\n* [Token\nAuthentication](https://docs.docker.com/registry/spec/auth/token/) and\n* [OAuth2\nAuthentication](https://docs.docker.com/registry/spec/auth/oauth/)\n\nfor registry clients.\n\n## Raison d'être\n\n> Why not just use the [`docker/distribution`](https://godoc.org/github.com/docker/distribution/registry/client/auth) client?\n\nGreat question! Mostly, because I don't want to depend on [`prometheus/client_golang`](https://github.com/prometheus/client_golang).\n\nAs a performance optimization, that client uses [a cache](https://github.com/docker/distribution/blob/a8371794149d1d95f1e846744b05c87f2f825e5a/registry/client/repository.go#L173) to keep track of a mapping between blob digests and their [descriptors](https://github.com/docker/distribution/blob/a8371794149d1d95f1e846744b05c87f2f825e5a/blobs.go#L57-L86). Unfortunately, the cache [uses prometheus](https://github.com/docker/distribution/blob/a8371794149d1d95f1e846744b05c87f2f825e5a/registry/storage/cache/cachedblobdescriptorstore.go#L44) to track hits and misses, so if you want to use that client you have to pull in all of prometheus, which is pretty large.\n\n![docker/distribution](../../../../images/docker.dot.svg)\n\n> Why does it matter if you depend on prometheus? Who cares?\n\nIt's generally polite to your downstream to reduce the number of dependencies your package requires:\n\n* Downloading your package is faster, which helps our Australian friends and people on airplanes.\n* There is less code to compile, which speeds up builds and saves the planet from global warming.\n* You reduce the likelihood of inflicting dependency hell upon your consumers.\n* [Tim Hockin](https://twitter.com/thockin/status/958606077456654336) prefers it based on his experience working on Kubernetes, and he's a pretty smart guy.\n\n> Okay, what about [`containerd/containerd`](https://godoc.org/github.com/containerd/containerd/remotes/docker)?\n\nSimilar reasons! That ends up pulling in grpc, protobuf, and logrus.\n\n![containerd/containerd](../../../../images/containerd.dot.svg)\n\n> Well... what about [`containers/image`](https://godoc.org/github.com/containers/image/docker)?\n\nThat just uses the the `docker/distribution` client... and more!\n\n![containers/image](../../../../images/containers.dot.svg)\n\n> Wow, what about this package?\n\nOf course, this package isn't perfect either. `transport` depends on `authn`,\nwhich in turn depends on docker's config file parsing and handling package,\nwhich you don't strictly need but almost certainly want if you're going to be\ninteracting with a registry.\n\n![google/go-containerregistry](../../../../images/ggcr.dot.svg)\n\n*These graphs were generated by\n[`kisielk/godepgraph`](https://github.com/kisielk/godepgraph).*\n\n## Usage\n\nThis is heavily used by the\n[`remote`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote)\npackage, which implements higher level image-centric functionality, but this\npackage is useful if you want to interact directly with the registry to do\nsomething that `remote` doesn't support, e.g. [to handle with schema 1\nimages](https://github.com/google/go-containerregistry/pull/509).\n\nThis package also includes some [error\nhandling](https://github.com/opencontainers/distribution-spec/blob/60be706c34ee7805bdd1d3d11affec53b0dfb8fb/spec.md#errors)\nfacilities in the form of\n[`CheckError`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/remote/transport#CheckError),\nwhich will parse the response body into a structured error for unexpected http\nstatus codes.\n\nHere's a \"simple\" program that writes the result of\n[listing tags](https://github.com/opencontainers/distribution-spec/blob/60be706c34ee7805bdd1d3d11affec53b0dfb8fb/spec.md#tags)\nfor [`gcr.io/google-containers/pause`](https://gcr.io/google-containers/pause)\nto stdout.\n\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n)\n\nfunc main() {\n\trepo, err := name.NewRepository(\"gcr.io/google-containers/pause\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Fetch credentials based on your docker config file, which is $HOME/.docker/config.json or $DOCKER_CONFIG.\n\tauth, err := authn.DefaultKeychain.Resolve(repo.Registry)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Construct an http.Client that is authorized to pull from gcr.io/google-containers/pause.\n\tscopes := []string{repo.Scope(transport.PullScope)}\n\tt, err := transport.New(repo.Registry, auth, http.DefaultTransport, scopes)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tclient := &http.Client{Transport: t}\n\n\t// Make the actual request.\n\tresp, err := client.Get(\"https://gcr.io/v2/google-containers/pause/tags/list\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Assert that we get a 200, otherwise attempt to parse body as a structured error.\n\tif err := transport.CheckError(resp, http.StatusOK); err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Write the response to stdout.\n\tif _, err := io.Copy(os.Stdout, resp.Body); err != nil {\n\t\tpanic(err)\n\t}\n}\n```\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/basic.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n)\n\ntype basicTransport struct {\n\tinner  http.RoundTripper\n\tauth   authn.Authenticator\n\ttarget string\n}\n\nvar _ http.RoundTripper = (*basicTransport)(nil)\n\n// RoundTrip implements http.RoundTripper\nfunc (bt *basicTransport) RoundTrip(in *http.Request) (*http.Response, error) {\n\tif bt.auth != authn.Anonymous {\n\t\tauth, err := bt.auth.Authorization()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// http.Client handles redirects at a layer above the http.RoundTripper\n\t\t// abstraction, so to avoid forwarding Authorization headers to places\n\t\t// we are redirected, only set it when the authorization header matches\n\t\t// the host with which we are interacting.\n\t\t// In case of redirect http.Client can use an empty Host, check URL too.\n\t\tif in.Host == bt.target || in.URL.Host == bt.target {\n\t\t\tif bearer := auth.RegistryToken; bearer != \"\" {\n\t\t\t\thdr := fmt.Sprintf(\"Bearer %s\", bearer)\n\t\t\t\tin.Header.Set(\"Authorization\", hdr)\n\t\t\t} else if user, pass := auth.Username, auth.Password; user != \"\" && pass != \"\" {\n\t\t\t\tdelimited := fmt.Sprintf(\"%s:%s\", user, pass)\n\t\t\t\tencoded := base64.StdEncoding.EncodeToString([]byte(delimited))\n\t\t\t\thdr := fmt.Sprintf(\"Basic %s\", encoded)\n\t\t\t\tin.Header.Set(\"Authorization\", hdr)\n\t\t\t} else if token := auth.Auth; token != \"\" {\n\t\t\t\thdr := fmt.Sprintf(\"Basic %s\", token)\n\t\t\t\tin.Header.Set(\"Authorization\", hdr)\n\t\t\t}\n\t\t}\n\t}\n\treturn bt.inner.RoundTrip(in)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/bearer.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\n\tauthchallenge \"github.com/docker/distribution/registry/client/auth/challenge\"\n\t\"github.com/google/go-containerregistry/internal/redact\"\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n)\n\ntype Token struct {\n\tToken        string `json:\"token\"`\n\tAccessToken  string `json:\"access_token,omitempty\"`\n\tRefreshToken string `json:\"refresh_token\"`\n\tExpiresIn    int    `json:\"expires_in\"`\n}\n\n// Exchange requests a registry Token with the given scopes.\nfunc Exchange(ctx context.Context, reg name.Registry, auth authn.Authenticator, t http.RoundTripper, scopes []string, pr *Challenge) (*Token, error) {\n\tif strings.ToLower(pr.Scheme) != \"bearer\" {\n\t\t// TODO: Pretend token for basic?\n\t\treturn nil, fmt.Errorf(\"challenge scheme %q is not bearer\", pr.Scheme)\n\t}\n\tbt, err := fromChallenge(reg, auth, t, pr, scopes...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tauthcfg, err := auth.Authorization()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttok, err := bt.Refresh(ctx, authcfg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn tok, nil\n}\n\n// FromToken returns a transport given a Challenge + Token.\nfunc FromToken(reg name.Registry, auth authn.Authenticator, t http.RoundTripper, pr *Challenge, tok *Token) (http.RoundTripper, error) {\n\tif strings.ToLower(pr.Scheme) != \"bearer\" {\n\t\treturn &Wrapper{&basicTransport{inner: t, auth: auth, target: reg.RegistryStr()}}, nil\n\t}\n\tbt, err := fromChallenge(reg, auth, t, pr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif tok.Token != \"\" {\n\t\tbt.bearer.RegistryToken = tok.Token\n\t}\n\treturn &Wrapper{bt}, nil\n}\n\nfunc fromChallenge(reg name.Registry, auth authn.Authenticator, t http.RoundTripper, pr *Challenge, scopes ...string) (*bearerTransport, error) {\n\t// We require the realm, which tells us where to send our Basic auth to turn it into Bearer auth.\n\trealm, ok := pr.Parameters[\"realm\"]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"malformed www-authenticate, missing realm: %v\", pr.Parameters)\n\t}\n\tservice := pr.Parameters[\"service\"]\n\tscheme := \"https\"\n\tif pr.Insecure {\n\t\tscheme = \"http\"\n\t}\n\treturn &bearerTransport{\n\t\tinner:    t,\n\t\tbasic:    auth,\n\t\trealm:    realm,\n\t\tregistry: reg,\n\t\tservice:  service,\n\t\tscopes:   scopes,\n\t\tscheme:   scheme,\n\t}, nil\n}\n\ntype bearerTransport struct {\n\t// Wrapped by bearerTransport.\n\tinner http.RoundTripper\n\t// Basic credentials that we exchange for bearer tokens.\n\tbasic authn.Authenticator\n\t// Holds the bearer response from the token service.\n\tbearer authn.AuthConfig\n\t// Registry to which we send bearer tokens.\n\tregistry name.Registry\n\t// See https://tools.ietf.org/html/rfc6750#section-3\n\trealm string\n\t// See https://docs.docker.com/registry/spec/auth/token/\n\tservice string\n\tscopes  []string\n\t// Scheme we should use, determined by ping response.\n\tscheme string\n}\n\nvar _ http.RoundTripper = (*bearerTransport)(nil)\n\nvar portMap = map[string]string{\n\t\"http\":  \"80\",\n\t\"https\": \"443\",\n}\n\nfunc stringSet(ss []string) map[string]struct{} {\n\tset := make(map[string]struct{})\n\tfor _, s := range ss {\n\t\tset[s] = struct{}{}\n\t}\n\treturn set\n}\n\n// RoundTrip implements http.RoundTripper\nfunc (bt *bearerTransport) RoundTrip(in *http.Request) (*http.Response, error) {\n\tsendRequest := func() (*http.Response, error) {\n\t\t// http.Client handles redirects at a layer above the http.RoundTripper\n\t\t// abstraction, so to avoid forwarding Authorization headers to places\n\t\t// we are redirected, only set it when the authorization header matches\n\t\t// the registry with which we are interacting.\n\t\t// In case of redirect http.Client can use an empty Host, check URL too.\n\t\tif matchesHost(bt.registry.RegistryStr(), in, bt.scheme) {\n\t\t\thdr := fmt.Sprintf(\"Bearer %s\", bt.bearer.RegistryToken)\n\t\t\tin.Header.Set(\"Authorization\", hdr)\n\t\t}\n\t\treturn bt.inner.RoundTrip(in)\n\t}\n\n\tres, err := sendRequest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// If we hit a WWW-Authenticate challenge, it might be due to expired tokens or insufficient scope.\n\tif challenges := authchallenge.ResponseChallenges(res); len(challenges) != 0 {\n\t\t// close out old response, since we will not return it.\n\t\tres.Body.Close()\n\n\t\tnewScopes := []string{}\n\t\tfor _, wac := range challenges {\n\t\t\t// TODO(jonjohnsonjr): Should we also update \"realm\" or \"service\"?\n\t\t\tif want, ok := wac.Parameters[\"scope\"]; ok {\n\t\t\t\t// Add any scopes that we don't already request.\n\t\t\t\tgot := stringSet(bt.scopes)\n\t\t\t\tif _, ok := got[want]; !ok {\n\t\t\t\t\tnewScopes = append(newScopes, want)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Some registries seem to only look at the first scope parameter during a token exchange.\n\t\t// If a request fails because it's missing a scope, we should put those at the beginning,\n\t\t// otherwise the registry might just ignore it :/\n\t\tnewScopes = append(newScopes, bt.scopes...)\n\t\tbt.scopes = newScopes\n\n\t\t// TODO(jonjohnsonjr): Teach transport.Error about \"error\" and \"error_description\" from challenge.\n\n\t\t// Retry the request to attempt to get a valid token.\n\t\tif err = bt.refresh(in.Context()); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn sendRequest()\n\t}\n\n\treturn res, err\n}\n\n// It's unclear which authentication flow to use based purely on the protocol,\n// so we rely on heuristics and fallbacks to support as many registries as possible.\n// The basic token exchange is attempted first, falling back to the oauth flow.\n// If the IdentityToken is set, this indicates that we should start with the oauth flow.\nfunc (bt *bearerTransport) refresh(ctx context.Context) error {\n\tauth, err := bt.basic.Authorization()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif auth.RegistryToken != \"\" {\n\t\tbt.bearer.RegistryToken = auth.RegistryToken\n\t\treturn nil\n\t}\n\n\tresponse, err := bt.Refresh(ctx, auth)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Some registries set access_token instead of token. See #54.\n\tif response.AccessToken != \"\" {\n\t\tresponse.Token = response.AccessToken\n\t}\n\n\t// Find a token to turn into a Bearer authenticator\n\tif response.Token != \"\" {\n\t\tbt.bearer.RegistryToken = response.Token\n\t}\n\n\t// If we obtained a refresh token from the oauth flow, use that for refresh() now.\n\tif response.RefreshToken != \"\" {\n\t\tbt.basic = authn.FromConfig(authn.AuthConfig{\n\t\t\tIdentityToken: response.RefreshToken,\n\t\t})\n\t}\n\n\treturn nil\n}\n\nfunc (bt *bearerTransport) Refresh(ctx context.Context, auth *authn.AuthConfig) (*Token, error) {\n\tvar (\n\t\tcontent []byte\n\t\terr     error\n\t)\n\tif auth.IdentityToken != \"\" {\n\t\t// If the secret being stored is an identity token,\n\t\t// the Username should be set to <token>, which indicates\n\t\t// we are using an oauth flow.\n\t\tcontent, err = bt.refreshOauth(ctx)\n\t\tvar terr *Error\n\t\tif errors.As(err, &terr) && terr.StatusCode == http.StatusNotFound {\n\t\t\t// Note: Not all token servers implement oauth2.\n\t\t\t// If the request to the endpoint returns 404 using the HTTP POST method,\n\t\t\t// refer to Token Documentation for using the HTTP GET method supported by all token servers.\n\t\t\tcontent, err = bt.refreshBasic(ctx)\n\t\t}\n\t} else {\n\t\tcontent, err = bt.refreshBasic(ctx)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar response Token\n\tif err := json.Unmarshal(content, &response); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif response.Token == \"\" && response.AccessToken == \"\" {\n\t\treturn &response, fmt.Errorf(\"no token in bearer response:\\n%s\", content)\n\t}\n\n\treturn &response, nil\n}\n\nfunc matchesHost(host string, in *http.Request, scheme string) bool {\n\tcanonicalHeaderHost := canonicalAddress(in.Host, scheme)\n\tcanonicalURLHost := canonicalAddress(in.URL.Host, scheme)\n\tcanonicalRegistryHost := canonicalAddress(host, scheme)\n\treturn canonicalHeaderHost == canonicalRegistryHost || canonicalURLHost == canonicalRegistryHost\n}\n\nfunc canonicalAddress(host, scheme string) (address string) {\n\t// The host may be any one of:\n\t// - hostname\n\t// - hostname:port\n\t// - ipv4\n\t// - ipv4:port\n\t// - ipv6\n\t// - [ipv6]:port\n\t// As net.SplitHostPort returns an error if the host does not contain a port, we should only attempt\n\t// to call it when we know that the address contains a port\n\tif strings.Count(host, \":\") == 1 || (strings.Count(host, \":\") >= 2 && strings.Contains(host, \"]:\")) {\n\t\thostname, port, err := net.SplitHostPort(host)\n\t\tif err != nil {\n\t\t\treturn host\n\t\t}\n\t\tif port == \"\" {\n\t\t\tport = portMap[scheme]\n\t\t}\n\n\t\treturn net.JoinHostPort(hostname, port)\n\t}\n\n\treturn net.JoinHostPort(host, portMap[scheme])\n}\n\n// https://docs.docker.com/registry/spec/auth/oauth/\nfunc (bt *bearerTransport) refreshOauth(ctx context.Context) ([]byte, error) {\n\tauth, err := bt.basic.Authorization()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tu, err := url.Parse(bt.realm)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tv := url.Values{}\n\tv.Set(\"scope\", strings.Join(bt.scopes, \" \"))\n\tif bt.service != \"\" {\n\t\tv.Set(\"service\", bt.service)\n\t}\n\tv.Set(\"client_id\", defaultUserAgent)\n\tif auth.IdentityToken != \"\" {\n\t\tv.Set(\"grant_type\", \"refresh_token\")\n\t\tv.Set(\"refresh_token\", auth.IdentityToken)\n\t} else if auth.Username != \"\" && auth.Password != \"\" {\n\t\t// TODO(#629): This is unreachable.\n\t\tv.Set(\"grant_type\", \"password\")\n\t\tv.Set(\"username\", auth.Username)\n\t\tv.Set(\"password\", auth.Password)\n\t\tv.Set(\"access_type\", \"offline\")\n\t}\n\n\tclient := http.Client{Transport: bt.inner}\n\treq, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(v.Encode()))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/x-www-form-urlencoded\")\n\n\t// We don't want to log credentials.\n\tctx = redact.NewContext(ctx, \"oauth token response contains credentials\")\n\n\tresp, err := client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := CheckError(resp, http.StatusOK); err != nil {\n\t\tif bt.basic == authn.Anonymous {\n\t\t\tlogs.Warn.Printf(\"No matching credentials were found for %q\", bt.registry)\n\t\t}\n\t\treturn nil, err\n\t}\n\n\treturn io.ReadAll(resp.Body)\n}\n\n// https://docs.docker.com/registry/spec/auth/token/\nfunc (bt *bearerTransport) refreshBasic(ctx context.Context) ([]byte, error) {\n\tu, err := url.Parse(bt.realm)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tb := &basicTransport{\n\t\tinner:  bt.inner,\n\t\tauth:   bt.basic,\n\t\ttarget: u.Host,\n\t}\n\tclient := http.Client{Transport: b}\n\n\tv := u.Query()\n\tv[\"scope\"] = bt.scopes\n\tv.Set(\"service\", bt.service)\n\tu.RawQuery = v.Encode()\n\n\treq, err := http.NewRequest(http.MethodGet, u.String(), nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// We don't want to log credentials.\n\tctx = redact.NewContext(ctx, \"basic token response contains credentials\")\n\n\tresp, err := client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := CheckError(resp, http.StatusOK); err != nil {\n\t\tif bt.basic == authn.Anonymous {\n\t\t\tlogs.Warn.Printf(\"No matching credentials were found for %q\", bt.registry)\n\t\t}\n\t\treturn nil, err\n\t}\n\n\treturn io.ReadAll(resp.Body)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package transport provides facilities for setting up an authenticated\n// http.RoundTripper given an Authenticator and base RoundTripper.  See\n// transport.New for more information.\npackage transport\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/error.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/internal/redact\"\n)\n\n// Error implements error to support the following error specification:\n// https://github.com/docker/distribution/blob/master/docs/spec/api.md#errors\ntype Error struct {\n\tErrors []Diagnostic `json:\"errors,omitempty\"`\n\t// The http status code returned.\n\tStatusCode int\n\t// The request that failed.\n\tRequest *http.Request\n\t// The raw body if we couldn't understand it.\n\trawBody string\n\n\t// Bit of a hack to make it easier to force a retry.\n\ttemporary bool\n}\n\n// Check that Error implements error\nvar _ error = (*Error)(nil)\n\n// Error implements error\nfunc (e *Error) Error() string {\n\tprefix := \"\"\n\tif e.Request != nil {\n\t\tprefix = fmt.Sprintf(\"%s %s: \", e.Request.Method, redact.URL(e.Request.URL))\n\t}\n\treturn prefix + e.responseErr()\n}\n\nfunc (e *Error) responseErr() string {\n\tswitch len(e.Errors) {\n\tcase 0:\n\t\tif len(e.rawBody) == 0 {\n\t\t\tif e.Request != nil && e.Request.Method == http.MethodHead {\n\t\t\t\treturn fmt.Sprintf(\"unexpected status code %d %s (HEAD responses have no body, use GET for details)\", e.StatusCode, http.StatusText(e.StatusCode))\n\t\t\t}\n\t\t\treturn fmt.Sprintf(\"unexpected status code %d %s\", e.StatusCode, http.StatusText(e.StatusCode))\n\t\t}\n\t\treturn fmt.Sprintf(\"unexpected status code %d %s: %s\", e.StatusCode, http.StatusText(e.StatusCode), e.rawBody)\n\tcase 1:\n\t\treturn e.Errors[0].String()\n\tdefault:\n\t\tvar errors []string\n\t\tfor _, d := range e.Errors {\n\t\t\terrors = append(errors, d.String())\n\t\t}\n\t\treturn fmt.Sprintf(\"multiple errors returned: %s\",\n\t\t\tstrings.Join(errors, \"; \"))\n\t}\n}\n\n// Temporary returns whether the request that preceded the error is temporary.\nfunc (e *Error) Temporary() bool {\n\tif e.temporary {\n\t\treturn true\n\t}\n\n\tif len(e.Errors) == 0 {\n\t\t_, ok := temporaryStatusCodes[e.StatusCode]\n\t\treturn ok\n\t}\n\tfor _, d := range e.Errors {\n\t\tif _, ok := temporaryErrorCodes[d.Code]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Diagnostic represents a single error returned by a Docker registry interaction.\ntype Diagnostic struct {\n\tCode    ErrorCode `json:\"code\"`\n\tMessage string    `json:\"message,omitempty\"`\n\tDetail  any       `json:\"detail,omitempty\"`\n}\n\n// String stringifies the Diagnostic in the form: $Code: $Message[; $Detail]\nfunc (d Diagnostic) String() string {\n\tmsg := fmt.Sprintf(\"%s: %s\", d.Code, d.Message)\n\tif d.Detail != nil {\n\t\tmsg = fmt.Sprintf(\"%s; %v\", msg, d.Detail)\n\t}\n\treturn msg\n}\n\n// ErrorCode is an enumeration of supported error codes.\ntype ErrorCode string\n\n// The set of error conditions a registry may return:\n// https://github.com/docker/distribution/blob/master/docs/spec/api.md#errors-2\nconst (\n\tBlobUnknownErrorCode         ErrorCode = \"BLOB_UNKNOWN\"\n\tBlobUploadInvalidErrorCode   ErrorCode = \"BLOB_UPLOAD_INVALID\"\n\tBlobUploadUnknownErrorCode   ErrorCode = \"BLOB_UPLOAD_UNKNOWN\"\n\tDigestInvalidErrorCode       ErrorCode = \"DIGEST_INVALID\"\n\tManifestBlobUnknownErrorCode ErrorCode = \"MANIFEST_BLOB_UNKNOWN\"\n\tManifestInvalidErrorCode     ErrorCode = \"MANIFEST_INVALID\"\n\tManifestUnknownErrorCode     ErrorCode = \"MANIFEST_UNKNOWN\"\n\tManifestUnverifiedErrorCode  ErrorCode = \"MANIFEST_UNVERIFIED\"\n\tNameInvalidErrorCode         ErrorCode = \"NAME_INVALID\"\n\tNameUnknownErrorCode         ErrorCode = \"NAME_UNKNOWN\"\n\tSizeInvalidErrorCode         ErrorCode = \"SIZE_INVALID\"\n\tTagInvalidErrorCode          ErrorCode = \"TAG_INVALID\"\n\tUnauthorizedErrorCode        ErrorCode = \"UNAUTHORIZED\"\n\tDeniedErrorCode              ErrorCode = \"DENIED\"\n\tUnsupportedErrorCode         ErrorCode = \"UNSUPPORTED\"\n\tTooManyRequestsErrorCode     ErrorCode = \"TOOMANYREQUESTS\"\n\tUnknownErrorCode             ErrorCode = \"UNKNOWN\"\n\n\t// This isn't defined by either docker or OCI spec, but is defined by docker/distribution:\n\t// https://github.com/distribution/distribution/blob/6a977a5a754baa213041443f841705888107362a/registry/api/errcode/register.go#L60\n\tUnavailableErrorCode ErrorCode = \"UNAVAILABLE\"\n)\n\n// TODO: Include other error types.\nvar temporaryErrorCodes = map[ErrorCode]struct{}{\n\tBlobUploadInvalidErrorCode: {},\n\tTooManyRequestsErrorCode:   {},\n\tUnknownErrorCode:           {},\n\tUnavailableErrorCode:       {},\n}\n\nvar temporaryStatusCodes = map[int]struct{}{\n\thttp.StatusRequestTimeout:      {},\n\thttp.StatusInternalServerError: {},\n\thttp.StatusBadGateway:          {},\n\thttp.StatusServiceUnavailable:  {},\n\thttp.StatusGatewayTimeout:      {},\n}\n\n// CheckError returns a structured error if the response status is not in codes.\nfunc CheckError(resp *http.Response, codes ...int) error {\n\tfor _, code := range codes {\n\t\tif resp.StatusCode == code {\n\t\t\t// This is one of the supported status codes.\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tb, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn makeError(resp, b)\n}\n\nfunc makeError(resp *http.Response, body []byte) *Error {\n\t// https://github.com/docker/distribution/blob/master/docs/spec/api.md#errors\n\tstructuredError := &Error{}\n\n\t// This can fail if e.g. the response body is not valid JSON. That's fine,\n\t// we'll construct an appropriate error string from the body and status code.\n\t_ = json.Unmarshal(body, structuredError)\n\n\tstructuredError.rawBody = string(body)\n\tstructuredError.StatusCode = resp.StatusCode\n\tstructuredError.Request = resp.Request\n\n\treturn structuredError\n}\n\nfunc retryError(resp *http.Response) error {\n\tb, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\trerr := makeError(resp, b)\n\trerr.temporary = true\n\treturn rerr\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/logger.go",
    "content": "// Copyright 2020 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"time\"\n\n\t\"github.com/google/go-containerregistry/internal/redact\"\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n)\n\ntype logTransport struct {\n\tinner http.RoundTripper\n}\n\n// NewLogger returns a transport that logs requests and responses to\n// github.com/google/go-containerregistry/pkg/logs.Debug.\nfunc NewLogger(inner http.RoundTripper) http.RoundTripper {\n\treturn &logTransport{inner}\n}\n\nfunc (t *logTransport) RoundTrip(in *http.Request) (out *http.Response, err error) {\n\t// Inspired by: github.com/motemen/go-loghttp\n\n\t// We redact token responses and binary blobs in response/request.\n\tomitBody, reason := redact.FromContext(in.Context())\n\tif omitBody {\n\t\tlogs.Debug.Printf(\"--> %s %s [body redacted: %s]\", in.Method, in.URL, reason)\n\t} else {\n\t\tlogs.Debug.Printf(\"--> %s %s\", in.Method, in.URL)\n\t}\n\n\t// Save these headers so we can redact Authorization.\n\tsavedHeaders := in.Header.Clone()\n\tif in.Header != nil && in.Header.Get(\"authorization\") != \"\" {\n\t\tin.Header.Set(\"authorization\", \"<redacted>\")\n\t}\n\n\tb, err := httputil.DumpRequestOut(in, !omitBody)\n\tif err == nil {\n\t\tlogs.Debug.Println(string(b))\n\t} else {\n\t\tlogs.Debug.Printf(\"Failed to dump request %s %s: %v\", in.Method, in.URL, err)\n\t}\n\n\t// Restore the non-redacted headers.\n\tin.Header = savedHeaders\n\n\tstart := time.Now()\n\tout, err = t.inner.RoundTrip(in)\n\tduration := time.Since(start)\n\tif err != nil {\n\t\tlogs.Debug.Printf(\"<-- %v %s %s (%s)\", err, in.Method, in.URL, duration)\n\t}\n\tif out != nil {\n\t\tmsg := fmt.Sprintf(\"<-- %d\", out.StatusCode)\n\t\tif out.Request != nil {\n\t\t\tmsg = fmt.Sprintf(\"%s %s\", msg, out.Request.URL)\n\t\t}\n\t\tmsg = fmt.Sprintf(\"%s (%s)\", msg, duration)\n\n\t\tif omitBody {\n\t\t\tmsg = fmt.Sprintf(\"%s [body redacted: %s]\", msg, reason)\n\t\t}\n\n\t\tlogs.Debug.Print(msg)\n\n\t\tb, err := httputil.DumpResponse(out, !omitBody)\n\t\tif err == nil {\n\t\t\tlogs.Debug.Println(string(b))\n\t\t} else {\n\t\t\tlogs.Debug.Printf(\"Failed to dump response %s %s: %v\", in.Method, in.URL, err)\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/ping.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n\n\tauthchallenge \"github.com/docker/distribution/registry/client/auth/challenge\"\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n)\n\n// 300ms is the default fallback period for go's DNS dialer but we could make this configurable.\nvar fallbackDelay = 300 * time.Millisecond\n\ntype Challenge struct {\n\tScheme string\n\n\t// Following the challenge there are often key/value pairs\n\t// e.g. Bearer service=\"gcr.io\",realm=\"https://auth.gcr.io/v36/tokenz\"\n\tParameters map[string]string\n\n\t// Whether we had to use http to complete the Ping.\n\tInsecure bool\n}\n\n// Ping does a GET /v2/ against the registry and returns the response.\nfunc Ping(ctx context.Context, reg name.Registry, t http.RoundTripper) (*Challenge, error) {\n\t// This first attempts to use \"https\" for every request, falling back to http\n\t// if the registry matches our localhost heuristic or if it is intentionally\n\t// set to insecure via name.NewInsecureRegistry.\n\tschemes := []string{\"https\"}\n\tif reg.Scheme() == \"http\" {\n\t\tschemes = append(schemes, \"http\")\n\t}\n\tif len(schemes) == 1 {\n\t\treturn pingSingle(ctx, reg, t, schemes[0])\n\t}\n\treturn pingParallel(ctx, reg, t, schemes)\n}\n\nfunc pingSingle(ctx context.Context, reg name.Registry, t http.RoundTripper, scheme string) (*Challenge, error) {\n\tclient := http.Client{Transport: t}\n\turl := fmt.Sprintf(\"%s://%s/v2/\", scheme, reg.RegistryStr())\n\treq, err := http.NewRequest(http.MethodGet, url, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tresp, err := client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() {\n\t\t// By draining the body, make sure to reuse the connection made by\n\t\t// the ping for the following access to the registry\n\t\tio.Copy(io.Discard, resp.Body)\n\t\tresp.Body.Close()\n\t}()\n\n\tinsecure := scheme == \"http\"\n\n\tswitch resp.StatusCode {\n\tcase http.StatusOK:\n\t\t// If we get a 200, then no authentication is needed.\n\t\treturn &Challenge{\n\t\t\tInsecure: insecure,\n\t\t}, nil\n\tcase http.StatusUnauthorized:\n\t\tif challenges := authchallenge.ResponseChallenges(resp); len(challenges) != 0 {\n\t\t\t// If we hit more than one, let's try to find one that we know how to handle.\n\t\t\twac := pickFromMultipleChallenges(challenges)\n\t\t\treturn &Challenge{\n\t\t\t\tScheme:     wac.Scheme,\n\t\t\t\tParameters: wac.Parameters,\n\t\t\t\tInsecure:   insecure,\n\t\t\t}, nil\n\t\t}\n\t\t// Otherwise, just return the challenge without parameters.\n\t\treturn &Challenge{\n\t\t\tScheme:   resp.Header.Get(\"WWW-Authenticate\"),\n\t\t\tInsecure: insecure,\n\t\t}, nil\n\tdefault:\n\t\treturn nil, CheckError(resp, http.StatusOK, http.StatusUnauthorized)\n\t}\n}\n\n// Based on the golang happy eyeballs dialParallel impl in net/dial.go.\nfunc pingParallel(ctx context.Context, reg name.Registry, t http.RoundTripper, schemes []string) (*Challenge, error) {\n\treturned := make(chan struct{})\n\tdefer close(returned)\n\n\ttype pingResult struct {\n\t\t*Challenge\n\t\terror\n\t\tprimary bool\n\t\tdone    bool\n\t}\n\n\tresults := make(chan pingResult)\n\n\tstartRacer := func(ctx context.Context, scheme string) {\n\t\tpr, err := pingSingle(ctx, reg, t, scheme)\n\t\tselect {\n\t\tcase results <- pingResult{Challenge: pr, error: err, primary: scheme == \"https\", done: true}:\n\t\tcase <-returned:\n\t\t\tif pr != nil {\n\t\t\t\tlogs.Debug.Printf(\"%s lost race\", scheme)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar primary, fallback pingResult\n\n\tprimaryCtx, primaryCancel := context.WithCancel(ctx)\n\tdefer primaryCancel()\n\tgo startRacer(primaryCtx, schemes[0])\n\n\tfallbackTimer := time.NewTimer(fallbackDelay)\n\tdefer fallbackTimer.Stop()\n\n\tfor {\n\t\tselect {\n\t\tcase <-fallbackTimer.C:\n\t\t\tfallbackCtx, fallbackCancel := context.WithCancel(ctx)\n\t\t\tdefer fallbackCancel()\n\t\t\tgo startRacer(fallbackCtx, schemes[1])\n\n\t\tcase res := <-results:\n\t\t\tif res.error == nil {\n\t\t\t\treturn res.Challenge, nil\n\t\t\t}\n\t\t\tif res.primary {\n\t\t\t\tprimary = res\n\t\t\t} else {\n\t\t\t\tfallback = res\n\t\t\t}\n\t\t\tif primary.done && fallback.done {\n\t\t\t\treturn nil, multierrs{primary.error, fallback.error}\n\t\t\t}\n\t\t\tif res.primary && fallbackTimer.Stop() {\n\t\t\t\t// Primary failed and we haven't started the fallback,\n\t\t\t\t// reset time to start fallback immediately.\n\t\t\t\tfallbackTimer.Reset(0)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc pickFromMultipleChallenges(challenges []authchallenge.Challenge) authchallenge.Challenge {\n\t// It might happen there are multiple www-authenticate headers, e.g. `Negotiate` and `Basic`.\n\t// Picking simply the first one could result eventually in `unrecognized challenge` error,\n\t// that's why we're looping through the challenges in search for one that can be handled.\n\tallowedSchemes := []string{\"basic\", \"bearer\"}\n\n\tfor _, wac := range challenges {\n\t\tcurrentScheme := strings.ToLower(wac.Scheme)\n\t\tfor _, allowed := range allowedSchemes {\n\t\t\tif allowed == currentScheme {\n\t\t\t\treturn wac\n\t\t\t}\n\t\t}\n\t}\n\n\treturn challenges[0]\n}\n\ntype multierrs []error\n\nfunc (m multierrs) Error() string {\n\tvar b strings.Builder\n\thasWritten := false\n\tfor _, err := range m {\n\t\tif hasWritten {\n\t\t\tb.WriteString(\"; \")\n\t\t}\n\t\thasWritten = true\n\t\tb.WriteString(err.Error())\n\t}\n\treturn b.String()\n}\n\nfunc (m multierrs) As(target any) bool {\n\tfor _, err := range m {\n\t\tif errors.As(err, target) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (m multierrs) Is(target error) bool {\n\tfor _, err := range m {\n\t\tif errors.Is(err, target) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/retry.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/google/go-containerregistry/internal/retry\"\n)\n\n// Sleep for 0.1 then 0.3 seconds. This should cover networking blips.\nvar defaultBackoff = retry.Backoff{\n\tDuration: 100 * time.Millisecond,\n\tFactor:   3.0,\n\tJitter:   0.1,\n\tSteps:    3,\n}\n\nvar _ http.RoundTripper = (*retryTransport)(nil)\n\n// retryTransport wraps a RoundTripper and retries temporary network errors.\ntype retryTransport struct {\n\tinner     http.RoundTripper\n\tbackoff   retry.Backoff\n\tpredicate retry.Predicate\n\tcodes     []int\n}\n\n// Option is a functional option for retryTransport.\ntype Option func(*options)\n\ntype options struct {\n\tbackoff   retry.Backoff\n\tpredicate retry.Predicate\n\tcodes     []int\n}\n\n// Backoff is an alias of retry.Backoff to expose this configuration option to consumers of this lib\ntype Backoff = retry.Backoff\n\n// WithRetryBackoff sets the backoff for retry operations.\nfunc WithRetryBackoff(backoff Backoff) Option {\n\treturn func(o *options) {\n\t\to.backoff = backoff\n\t}\n}\n\n// WithRetryPredicate sets the predicate for retry operations.\nfunc WithRetryPredicate(predicate func(error) bool) Option {\n\treturn func(o *options) {\n\t\to.predicate = predicate\n\t}\n}\n\n// WithRetryStatusCodes sets which http response codes will be retried.\nfunc WithRetryStatusCodes(codes ...int) Option {\n\treturn func(o *options) {\n\t\to.codes = codes\n\t}\n}\n\n// NewRetry returns a transport that retries errors.\nfunc NewRetry(inner http.RoundTripper, opts ...Option) http.RoundTripper {\n\to := &options{\n\t\tbackoff:   defaultBackoff,\n\t\tpredicate: retry.IsTemporary,\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(o)\n\t}\n\n\treturn &retryTransport{\n\t\tinner:     inner,\n\t\tbackoff:   o.backoff,\n\t\tpredicate: o.predicate,\n\t\tcodes:     o.codes,\n\t}\n}\n\nfunc (t *retryTransport) RoundTrip(in *http.Request) (out *http.Response, err error) {\n\troundtrip := func() error {\n\t\tout, err = t.inner.RoundTrip(in)\n\t\tif !retry.Ever(in.Context()) {\n\t\t\treturn nil\n\t\t}\n\t\tif out != nil {\n\t\t\tfor _, code := range t.codes {\n\t\t\t\tif out.StatusCode == code {\n\t\t\t\t\treturn retryError(out)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n\tretry.Retry(roundtrip, t.predicate, t.backoff)\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/schemer.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"net/http\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n)\n\ntype schemeTransport struct {\n\t// Scheme we should use, determined by ping response.\n\tscheme string\n\n\t// Registry we're talking to.\n\tregistry name.Registry\n\n\t// Wrapped by schemeTransport.\n\tinner http.RoundTripper\n}\n\n// RoundTrip implements http.RoundTripper\nfunc (st *schemeTransport) RoundTrip(in *http.Request) (*http.Response, error) {\n\t// When we ping() the registry, we determine whether to use http or https\n\t// based on which scheme was successful. That is only valid for the\n\t// registry server and not e.g. a separate token server or blob storage,\n\t// so we should only override the scheme if the host is the registry.\n\tif matchesHost(st.registry.String(), in, st.scheme) {\n\t\tin.URL.Scheme = st.scheme\n\t}\n\treturn st.inner.RoundTrip(in)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/scope.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\n// Scopes suitable to qualify each Repository\nconst (\n\tPullScope string = \"pull\"\n\tPushScope string = \"push,pull\"\n\t// For now DELETE is PUSH, which is the read/write ACL.\n\tDeleteScope  string = PushScope\n\tCatalogScope string = \"catalog\"\n)\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/transport.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n)\n\n// New returns a new RoundTripper based on the provided RoundTripper that has been\n// setup to authenticate with the remote registry \"reg\", in the capacity\n// laid out by the specified scopes.\n//\n// Deprecated: Use NewWithContext.\nfunc New(reg name.Registry, auth authn.Authenticator, t http.RoundTripper, scopes []string) (http.RoundTripper, error) {\n\treturn NewWithContext(context.Background(), reg, auth, t, scopes)\n}\n\n// NewWithContext returns a new RoundTripper based on the provided RoundTripper that has been\n// set up to authenticate with the remote registry \"reg\", in the capacity\n// laid out by the specified scopes.\n// In case the RoundTripper is already of the type Wrapper it assumes\n// authentication was already done prior to this call, so it just returns\n// the provided RoundTripper without further action\nfunc NewWithContext(ctx context.Context, reg name.Registry, auth authn.Authenticator, t http.RoundTripper, scopes []string) (http.RoundTripper, error) {\n\t// When the transport provided is of the type Wrapper this function assumes that the caller already\n\t// executed the necessary login and check.\n\tswitch t.(type) {\n\tcase *Wrapper:\n\t\treturn t, nil\n\t}\n\t// The handshake:\n\t//  1. Use \"t\" to ping() the registry for the authentication challenge.\n\t//\n\t//  2a. If we get back a 200, then simply use \"t\".\n\t//\n\t//  2b. If we get back a 401 with a Basic challenge, then use a transport\n\t//     that just attachs auth each roundtrip.\n\t//\n\t//  2c. If we get back a 401 with a Bearer challenge, then use a transport\n\t//     that attaches a bearer token to each request, and refreshes is on 401s.\n\t//     Perform an initial refresh to seed the bearer token.\n\n\t// First we ping the registry to determine the parameters of the authentication handshake\n\t// (if one is even necessary).\n\tpr, err := Ping(ctx, reg, t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Wrap t with a useragent transport unless we already have one.\n\tif _, ok := t.(*userAgentTransport); !ok {\n\t\tt = NewUserAgent(t, \"\")\n\t}\n\n\tscheme := \"https\"\n\tif pr.Insecure {\n\t\tscheme = \"http\"\n\t}\n\n\t// Wrap t in a transport that selects the appropriate scheme based on the ping response.\n\tt = &schemeTransport{\n\t\tscheme:   scheme,\n\t\tregistry: reg,\n\t\tinner:    t,\n\t}\n\n\tif strings.ToLower(pr.Scheme) != \"bearer\" {\n\t\treturn &Wrapper{&basicTransport{inner: t, auth: auth, target: reg.RegistryStr()}}, nil\n\t}\n\n\tbt, err := fromChallenge(reg, auth, t, pr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbt.scopes = scopes\n\n\tif err := bt.refresh(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Wrapper{bt}, nil\n}\n\n// Wrapper results in *not* wrapping supplied transport with additional logic such as retries, useragent and debug logging\n// Consumers are opt-ing into providing their own transport without any additional wrapping.\ntype Wrapper struct {\n\tinner http.RoundTripper\n}\n\n// RoundTrip delegates to the inner RoundTripper\nfunc (w *Wrapper) RoundTrip(in *http.Request) (*http.Response, error) {\n\treturn w.inner.RoundTrip(in)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/transport/useragent.go",
    "content": "// Copyright 2019 Google LLC All Rights Reserved.\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//    http://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\npackage transport\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"runtime/debug\"\n)\n\nvar (\n\t// Version can be set via:\n\t// -ldflags=\"-X 'github.com/google/go-containerregistry/pkg/v1/remote/transport.Version=$TAG'\"\n\tVersion string\n\n\tggcrVersion = defaultUserAgent\n)\n\nconst (\n\tdefaultUserAgent = \"go-containerregistry\"\n\tmoduleName       = \"github.com/google/go-containerregistry\"\n)\n\ntype userAgentTransport struct {\n\tinner http.RoundTripper\n\tua    string\n}\n\nfunc init() {\n\tif v := version(); v != \"\" {\n\t\tggcrVersion = fmt.Sprintf(\"%s/%s\", defaultUserAgent, v)\n\t}\n}\n\nfunc version() string {\n\tif Version != \"\" {\n\t\t// Version was set via ldflags, just return it.\n\t\treturn Version\n\t}\n\n\tinfo, ok := debug.ReadBuildInfo()\n\tif !ok {\n\t\treturn \"\"\n\t}\n\n\t// Happens for crane and gcrane.\n\tif info.Main.Path == moduleName {\n\t\treturn info.Main.Version\n\t}\n\n\t// Anything else.\n\tfor _, dep := range info.Deps {\n\t\tif dep.Path == moduleName {\n\t\t\treturn dep.Version\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// NewUserAgent returns an http.Roundtripper that sets the user agent to\n// The provided string plus additional go-containerregistry information,\n// e.g. if provided \"crane/v0.1.4\" and this modules was built at v0.1.4:\n//\n// User-Agent: crane/v0.1.4 go-containerregistry/v0.1.4\nfunc NewUserAgent(inner http.RoundTripper, ua string) http.RoundTripper {\n\tif ua == \"\" {\n\t\tua = ggcrVersion\n\t} else {\n\t\tua = fmt.Sprintf(\"%s %s\", ua, ggcrVersion)\n\t}\n\treturn &userAgentTransport{\n\t\tinner: inner,\n\t\tua:    ua,\n\t}\n}\n\n// RoundTrip implements http.RoundTripper\nfunc (ut *userAgentTransport) RoundTrip(in *http.Request) (*http.Response, error) {\n\tin.Header.Set(\"User-Agent\", ut.ua)\n\treturn ut.inner.RoundTrip(in)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage remote\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/google/go-containerregistry/internal/redact\"\n\t\"github.com/google/go-containerregistry/internal/retry\"\n\t\"github.com/google/go-containerregistry/pkg/authn\"\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote/transport\"\n\t\"github.com/google/go-containerregistry/pkg/v1/stream\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\n// Taggable is an interface that enables a manifest PUT (e.g. for tagging).\ntype Taggable interface {\n\tRawManifest() ([]byte, error)\n}\n\n// Write pushes the provided img to the specified image reference.\nfunc Write(ref name.Reference, img v1.Image, options ...Option) (rerr error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif o.progress != nil {\n\t\tdefer func() { o.progress.Close(rerr) }()\n\t}\n\treturn newPusher(o).Push(o.context, ref, img)\n}\n\n// writer writes the elements of an image to a remote image reference.\ntype writer struct {\n\trepo      name.Repository\n\tauth      authn.Authenticator\n\ttransport http.RoundTripper\n\n\tclient *http.Client\n\n\tprogress  *progress\n\tbackoff   Backoff\n\tpredicate retry.Predicate\n\n\tscopeLock sync.Mutex\n\t// Keep track of scopes that we have already requested.\n\tscopeSet map[string]struct{}\n\tscopes   []string\n}\n\nfunc makeWriter(ctx context.Context, repo name.Repository, ls []v1.Layer, o *options) (*writer, error) {\n\tauth := o.auth\n\tif o.keychain != nil {\n\t\tkauth, err := o.keychain.Resolve(repo)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tauth = kauth\n\t}\n\tscopes := scopesForUploadingImage(repo, ls)\n\ttr, err := transport.NewWithContext(ctx, repo.Registry, auth, o.transport, scopes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tscopeSet := map[string]struct{}{}\n\tfor _, scope := range scopes {\n\t\tscopeSet[scope] = struct{}{}\n\t}\n\treturn &writer{\n\t\trepo:      repo,\n\t\tclient:    &http.Client{Transport: tr},\n\t\tauth:      auth,\n\t\ttransport: o.transport,\n\t\tprogress:  o.progress,\n\t\tbackoff:   o.retryBackoff,\n\t\tpredicate: o.retryPredicate,\n\t\tscopes:    scopes,\n\t\tscopeSet:  scopeSet,\n\t}, nil\n}\n\n// url returns a url.Url for the specified path in the context of this remote image reference.\nfunc (w *writer) url(path string) url.URL {\n\treturn url.URL{\n\t\tScheme: w.repo.Registry.Scheme(),\n\t\tHost:   w.repo.RegistryStr(),\n\t\tPath:   path,\n\t}\n}\n\nfunc (w *writer) maybeUpdateScopes(ctx context.Context, ml *MountableLayer) error {\n\tif ml.Reference.Context().String() == w.repo.String() {\n\t\treturn nil\n\t}\n\tif ml.Reference.Context().Registry.String() != w.repo.Registry.String() {\n\t\treturn nil\n\t}\n\n\tscope := ml.Reference.Scope(transport.PullScope)\n\n\tw.scopeLock.Lock()\n\tdefer w.scopeLock.Unlock()\n\n\tif _, ok := w.scopeSet[scope]; !ok {\n\t\tw.scopeSet[scope] = struct{}{}\n\t\tw.scopes = append(w.scopes, scope)\n\n\t\tlogs.Debug.Printf(\"Refreshing token to add scope %q\", scope)\n\t\twt, err := transport.NewWithContext(ctx, w.repo.Registry, w.auth, w.transport, w.scopes)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tw.client = &http.Client{Transport: wt}\n\t}\n\n\treturn nil\n}\n\n// nextLocation extracts the fully-qualified URL to which we should send the next request in an upload sequence.\nfunc (w *writer) nextLocation(resp *http.Response) (string, error) {\n\tloc := resp.Header.Get(\"Location\")\n\tif len(loc) == 0 {\n\t\treturn \"\", errors.New(\"missing Location header\")\n\t}\n\tu, err := url.Parse(loc)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// If the location header returned is just a url path, then fully qualify it.\n\t// We cannot simply call w.url, since there might be an embedded query string.\n\treturn resp.Request.URL.ResolveReference(u).String(), nil\n}\n\n// checkExistingBlob checks if a blob exists already in the repository by making a\n// HEAD request to the blob store API.  GCR performs an existence check on the\n// initiation if \"mount\" is specified, even if no \"from\" sources are specified.\n// However, this is not broadly applicable to all registries, e.g. ECR.\nfunc (w *writer) checkExistingBlob(ctx context.Context, h v1.Hash) (bool, error) {\n\tu := w.url(fmt.Sprintf(\"/v2/%s/blobs/%s\", w.repo.RepositoryStr(), h.String()))\n\n\treq, err := http.NewRequest(http.MethodHead, u.String(), nil)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tresp, err := w.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound); err != nil {\n\t\treturn false, err\n\t}\n\n\treturn resp.StatusCode == http.StatusOK, nil\n}\n\n// initiateUpload initiates the blob upload, which starts with a POST that can\n// optionally include the hash of the layer and a list of repositories from\n// which that layer might be read. On failure, an error is returned.\n// On success, the layer was either mounted (nothing more to do) or a blob\n// upload was initiated and the body of that blob should be sent to the returned\n// location.\nfunc (w *writer) initiateUpload(ctx context.Context, from, mount, origin string) (location string, mounted bool, err error) {\n\tu := w.url(fmt.Sprintf(\"/v2/%s/blobs/uploads/\", w.repo.RepositoryStr()))\n\tuv := url.Values{}\n\tif mount != \"\" && from != \"\" {\n\t\t// Quay will fail if we specify a \"mount\" without a \"from\".\n\t\tuv.Set(\"mount\", mount)\n\t\tuv.Set(\"from\", from)\n\t\tif origin != \"\" {\n\t\t\tuv.Set(\"origin\", origin)\n\t\t}\n\t}\n\tu.RawQuery = uv.Encode()\n\n\t// Make the request to initiate the blob upload.\n\treq, err := http.NewRequest(http.MethodPost, u.String(), nil)\n\tif err != nil {\n\t\treturn \"\", false, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tresp, err := w.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\tif from != \"\" {\n\t\t\t// https://github.com/google/go-containerregistry/issues/1679\n\t\t\tlogs.Warn.Printf(\"retrying without mount: %v\", err)\n\t\t\treturn w.initiateUpload(ctx, \"\", \"\", \"\")\n\t\t}\n\t\treturn \"\", false, err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusCreated, http.StatusAccepted); err != nil {\n\t\tif from != \"\" {\n\t\t\t// https://github.com/google/go-containerregistry/issues/1404\n\t\t\tlogs.Warn.Printf(\"retrying without mount: %v\", err)\n\t\t\treturn w.initiateUpload(ctx, \"\", \"\", \"\")\n\t\t}\n\t\treturn \"\", false, err\n\t}\n\n\t// Check the response code to determine the result.\n\tswitch resp.StatusCode {\n\tcase http.StatusCreated:\n\t\t// We're done, we were able to fast-path.\n\t\treturn \"\", true, nil\n\tcase http.StatusAccepted:\n\t\t// Proceed to PATCH, upload has begun.\n\t\tloc, err := w.nextLocation(resp)\n\t\treturn loc, false, err\n\tdefault:\n\t\tpanic(\"Unreachable: initiateUpload\")\n\t}\n}\n\n// streamBlob streams the contents of the blob to the specified location.\n// On failure, this will return an error.  On success, this will return the location\n// header indicating how to commit the streamed blob.\nfunc (w *writer) streamBlob(ctx context.Context, layer v1.Layer, streamLocation string) (commitLocation string, rerr error) {\n\treset := func() {}\n\tdefer func() {\n\t\tif rerr != nil {\n\t\t\treset()\n\t\t}\n\t}()\n\tblob, err := layer.Compressed()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tgetBody := layer.Compressed\n\tif w.progress != nil {\n\t\tvar count int64\n\t\tblob = &progressReader{rc: blob, progress: w.progress, count: &count}\n\t\tgetBody = func() (io.ReadCloser, error) {\n\t\t\tblob, err := layer.Compressed()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn &progressReader{rc: blob, progress: w.progress, count: &count}, nil\n\t\t}\n\t\treset = func() {\n\t\t\tw.progress.complete(-count)\n\t\t}\n\t}\n\n\treq, err := http.NewRequest(http.MethodPatch, streamLocation, blob)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif _, ok := layer.(*stream.Layer); !ok {\n\t\t// We can't retry streaming layers.\n\t\treq.GetBody = getBody\n\n\t\t// If we know the size, set it.\n\t\tif size, err := layer.Size(); err == nil {\n\t\t\treq.ContentLength = size\n\t\t}\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\n\tresp, err := w.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusNoContent, http.StatusAccepted, http.StatusCreated); err != nil {\n\t\treturn \"\", err\n\t}\n\n\t// The blob has been uploaded, return the location header indicating\n\t// how to commit this layer.\n\treturn w.nextLocation(resp)\n}\n\n// commitBlob commits this blob by sending a PUT to the location returned from\n// streaming the blob.\nfunc (w *writer) commitBlob(ctx context.Context, location, digest string) error {\n\tu, err := url.Parse(location)\n\tif err != nil {\n\t\treturn err\n\t}\n\tv := u.Query()\n\tv.Set(\"digest\", digest)\n\tu.RawQuery = v.Encode()\n\n\treq, err := http.NewRequest(http.MethodPut, u.String(), nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/octet-stream\")\n\n\tresp, err := w.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\treturn transport.CheckError(resp, http.StatusCreated)\n}\n\n// incrProgress increments and sends a progress update, if WithProgress is used.\nfunc (w *writer) incrProgress(written int64) {\n\tif w.progress == nil {\n\t\treturn\n\t}\n\tw.progress.complete(written)\n}\n\n// uploadOne performs a complete upload of a single layer.\nfunc (w *writer) uploadOne(ctx context.Context, l v1.Layer) error {\n\ttryUpload := func() error {\n\t\tctx := retry.Never(ctx)\n\t\tvar from, mount, origin string\n\t\tif h, err := l.Digest(); err == nil {\n\t\t\t// If we know the digest, this isn't a streaming layer. Do an existence\n\t\t\t// check so we can skip uploading the layer if possible.\n\t\t\texisting, err := w.checkExistingBlob(ctx, h)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif existing {\n\t\t\t\tsize, err := l.Size()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tw.incrProgress(size)\n\t\t\t\tlogs.Progress.Printf(\"existing blob: %v\", h)\n\t\t\t\treturn nil\n\t\t\t}\n\n\t\t\tmount = h.String()\n\t\t}\n\t\tif ml, ok := l.(*MountableLayer); ok {\n\t\t\tif err := w.maybeUpdateScopes(ctx, ml); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tfrom = ml.Reference.Context().RepositoryStr()\n\t\t\torigin = ml.Reference.Context().RegistryStr()\n\n\t\t\t// This keeps breaking with DockerHub.\n\t\t\t// https://github.com/google/go-containerregistry/issues/1741\n\t\t\tif w.repo.RegistryStr() == name.DefaultRegistry && origin != w.repo.RegistryStr() {\n\t\t\t\tfrom = \"\"\n\t\t\t\torigin = \"\"\n\t\t\t}\n\t\t}\n\n\t\tlocation, mounted, err := w.initiateUpload(ctx, from, mount, origin)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t} else if mounted {\n\t\t\tsize, err := l.Size()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tw.incrProgress(size)\n\t\t\th, err := l.Digest()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tlogs.Progress.Printf(\"mounted blob: %s\", h.String())\n\t\t\treturn nil\n\t\t}\n\n\t\t// Only log layers with +json or +yaml. We can let through other stuff if it becomes popular.\n\t\t// TODO(opencontainers/image-spec#791): Would be great to have an actual parser.\n\t\tmt, err := l.MediaType()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsmt := string(mt)\n\t\tif !(strings.HasSuffix(smt, \"+json\") || strings.HasSuffix(smt, \"+yaml\")) {\n\t\t\tctx = redact.NewContext(ctx, \"omitting binary blobs from logs\")\n\t\t}\n\n\t\tlocation, err = w.streamBlob(ctx, l, location)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\th, err := l.Digest()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdigest := h.String()\n\n\t\tif err := w.commitBlob(ctx, location, digest); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tlogs.Progress.Printf(\"pushed blob: %s\", digest)\n\t\treturn nil\n\t}\n\n\treturn retry.Retry(tryUpload, w.predicate, w.backoff)\n}\n\ntype withMediaType interface {\n\tMediaType() (types.MediaType, error)\n}\n\n// This is really silly, but go interfaces don't let me satisfy remote.Taggable\n// with remote.Descriptor because of name collisions between method names and\n// struct fields.\n//\n// Use reflection to either pull the v1.Descriptor out of remote.Descriptor or\n// create a descriptor based on the RawManifest and (optionally) MediaType.\nfunc unpackTaggable(t Taggable) ([]byte, *v1.Descriptor, error) {\n\tif d, ok := t.(*Descriptor); ok {\n\t\treturn d.Manifest, &d.Descriptor, nil\n\t}\n\tb, err := t.RawManifest()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\t// A reasonable default if Taggable doesn't implement MediaType.\n\tmt := types.DockerManifestSchema2\n\n\tif wmt, ok := t.(withMediaType); ok {\n\t\tm, err := wmt.MediaType()\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tmt = m\n\t}\n\n\th, sz, err := v1.SHA256(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn b, &v1.Descriptor{\n\t\tMediaType: mt,\n\t\tSize:      sz,\n\t\tDigest:    h,\n\t}, nil\n}\n\n// commitSubjectReferrers is responsible for updating the fallback tag manifest to track descriptors referring to a subject for registries that don't yet support the Referrers API.\n// TODO: use conditional requests to avoid race conditions\nfunc (w *writer) commitSubjectReferrers(ctx context.Context, sub name.Digest, add v1.Descriptor) error {\n\t// Check if the registry supports Referrers API.\n\t// TODO: This should be done once per registry, not once per subject.\n\tu := w.url(fmt.Sprintf(\"/v2/%s/referrers/%s\", w.repo.RepositoryStr(), sub.DigestStr()))\n\treq, err := http.NewRequest(http.MethodGet, u.String(), nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\treq.Header.Set(\"Accept\", string(types.OCIImageIndex))\n\tresp, err := w.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\tif err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound, http.StatusBadRequest); err != nil {\n\t\treturn err\n\t}\n\tif resp.StatusCode == http.StatusOK {\n\t\t// The registry supports Referrers API. The registry is responsible for updating the referrers list.\n\t\treturn nil\n\t}\n\n\t// The registry doesn't support Referrers API, we need to update the manifest tagged with the fallback tag.\n\t// Make the request to GET the current manifest.\n\tt := fallbackTag(sub)\n\tu = w.url(fmt.Sprintf(\"/v2/%s/manifests/%s\", w.repo.RepositoryStr(), t.Identifier()))\n\treq, err = http.NewRequest(http.MethodGet, u.String(), nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\treq.Header.Set(\"Accept\", string(types.OCIImageIndex))\n\tresp, err = w.client.Do(req.WithContext(ctx))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\n\tvar im v1.IndexManifest\n\tif err := transport.CheckError(resp, http.StatusOK, http.StatusNotFound); err != nil {\n\t\treturn err\n\t} else if resp.StatusCode == http.StatusNotFound {\n\t\t// Not found just means there are no attachments. Start with an empty index.\n\t\tim = v1.IndexManifest{\n\t\t\tSchemaVersion: 2,\n\t\t\tMediaType:     types.OCIImageIndex,\n\t\t\tManifests:     []v1.Descriptor{add},\n\t\t}\n\t} else {\n\t\tif err := json.NewDecoder(resp.Body).Decode(&im); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif im.SchemaVersion != 2 {\n\t\t\treturn fmt.Errorf(\"fallback tag manifest is not a schema version 2: %d\", im.SchemaVersion)\n\t\t}\n\t\tif im.MediaType != types.OCIImageIndex {\n\t\t\treturn fmt.Errorf(\"fallback tag manifest is not an OCI image index: %s\", im.MediaType)\n\t\t}\n\t\tfor _, desc := range im.Manifests {\n\t\t\tif desc.Digest == add.Digest {\n\t\t\t\t// The digest is already attached, nothing to do.\n\t\t\t\tlogs.Progress.Printf(\"fallback tag %s already had referrer\", t.Identifier())\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\t// Append the new descriptor to the index.\n\t\tim.Manifests = append(im.Manifests, add)\n\t}\n\n\t// Sort the manifests for reproducibility.\n\tsort.Slice(im.Manifests, func(i, j int) bool {\n\t\treturn im.Manifests[i].Digest.String() < im.Manifests[j].Digest.String()\n\t})\n\tlogs.Progress.Printf(\"updating fallback tag %s with new referrer\", t.Identifier())\n\treturn w.commitManifest(ctx, fallbackTaggable{im}, t)\n}\n\ntype fallbackTaggable struct {\n\tim v1.IndexManifest\n}\n\nfunc (f fallbackTaggable) RawManifest() ([]byte, error)        { return json.Marshal(f.im) }\nfunc (f fallbackTaggable) MediaType() (types.MediaType, error) { return types.OCIImageIndex, nil }\n\n// commitManifest does a PUT of the image's manifest.\nfunc (w *writer) commitManifest(ctx context.Context, t Taggable, ref name.Reference) error {\n\t// If the manifest refers to a subject, we need to check whether we need to update the fallback tag manifest.\n\traw, err := t.RawManifest()\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar mf struct {\n\t\tMediaType types.MediaType `json:\"mediaType\"`\n\t\tSubject   *v1.Descriptor  `json:\"subject,omitempty\"`\n\t\tConfig    struct {\n\t\t\tMediaType types.MediaType `json:\"mediaType\"`\n\t\t} `json:\"config\"`\n\t}\n\tif err := json.Unmarshal(raw, &mf); err != nil {\n\t\treturn err\n\t}\n\n\ttryUpload := func() error {\n\t\tctx := retry.Never(ctx)\n\t\traw, desc, err := unpackTaggable(t)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tu := w.url(fmt.Sprintf(\"/v2/%s/manifests/%s\", w.repo.RepositoryStr(), ref.Identifier()))\n\n\t\t// Make the request to PUT the serialized manifest\n\t\treq, err := http.NewRequest(http.MethodPut, u.String(), bytes.NewBuffer(raw))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treq.Header.Set(\"Content-Type\", string(desc.MediaType))\n\n\t\tresp, err := w.client.Do(req.WithContext(ctx))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer resp.Body.Close()\n\n\t\tif err := transport.CheckError(resp, http.StatusOK, http.StatusCreated, http.StatusAccepted); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// If the manifest referred to a subject, we may need to update the fallback tag manifest.\n\t\t// TODO: If this fails, we'll retry the whole upload. We should retry just this part.\n\t\tif mf.Subject != nil {\n\t\t\th, size, err := v1.SHA256(bytes.NewReader(raw))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tdesc := v1.Descriptor{\n\t\t\t\tArtifactType: string(mf.Config.MediaType),\n\t\t\t\tMediaType:    mf.MediaType,\n\t\t\t\tDigest:       h,\n\t\t\t\tSize:         size,\n\t\t\t}\n\t\t\tif err := w.commitSubjectReferrers(ctx,\n\t\t\t\tref.Context().Digest(mf.Subject.Digest.String()),\n\t\t\t\tdesc); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\t// The image was successfully pushed!\n\t\tlogs.Progress.Printf(\"%v: digest: %v size: %d\", ref, desc.Digest, desc.Size)\n\t\tw.incrProgress(int64(len(raw)))\n\t\treturn nil\n\t}\n\n\treturn retry.Retry(tryUpload, w.predicate, w.backoff)\n}\n\nfunc scopesForUploadingImage(repo name.Repository, layers []v1.Layer) []string {\n\t// use a map as set to remove duplicates scope strings\n\tscopeSet := map[string]struct{}{}\n\n\tfor _, l := range layers {\n\t\tif ml, ok := l.(*MountableLayer); ok {\n\t\t\t// we will add push scope for ref.Context() after the loop.\n\t\t\t// for now we ask pull scope for references of the same registry\n\t\t\tif ml.Reference.Context().String() != repo.String() && ml.Reference.Context().Registry.String() == repo.Registry.String() {\n\t\t\t\tscopeSet[ml.Reference.Scope(transport.PullScope)] = struct{}{}\n\t\t\t}\n\t\t}\n\t}\n\n\tscopes := make([]string, 0)\n\t// Push scope should be the first element because a few registries just look at the first scope to determine access.\n\tscopes = append(scopes, repo.Scope(transport.PushScope))\n\n\tfor scope := range scopeSet {\n\t\tscopes = append(scopes, scope)\n\t}\n\n\treturn scopes\n}\n\n// WriteIndex pushes the provided ImageIndex to the specified image reference.\n// WriteIndex will attempt to push all of the referenced manifests before\n// attempting to push the ImageIndex, to retain referential integrity.\nfunc WriteIndex(ref name.Reference, ii v1.ImageIndex, options ...Option) (rerr error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif o.progress != nil {\n\t\tdefer func() { o.progress.Close(rerr) }()\n\t}\n\treturn newPusher(o).Push(o.context, ref, ii)\n}\n\n// WriteLayer uploads the provided Layer to the specified repo.\nfunc WriteLayer(repo name.Repository, layer v1.Layer, options ...Option) (rerr error) {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif o.progress != nil {\n\t\tdefer func() { o.progress.Close(rerr) }()\n\t}\n\treturn newPusher(o).Upload(o.context, repo, layer)\n}\n\n// Tag adds a tag to the given Taggable via PUT /v2/.../manifests/<tag>\n//\n// Notable implementations of Taggable are v1.Image, v1.ImageIndex, and\n// remote.Descriptor.\n//\n// If t implements MediaType, we will use that for the Content-Type, otherwise\n// we will default to types.DockerManifestSchema2.\n//\n// Tag does not attempt to write anything other than the manifest, so callers\n// should ensure that all blobs or manifests that are referenced by t exist\n// in the target registry.\nfunc Tag(tag name.Tag, t Taggable, options ...Option) error {\n\treturn Put(tag, t, options...)\n}\n\n// Put adds a manifest from the given Taggable via PUT /v1/.../manifest/<ref>\n//\n// Notable implementations of Taggable are v1.Image, v1.ImageIndex, and\n// remote.Descriptor.\n//\n// If t implements MediaType, we will use that for the Content-Type, otherwise\n// we will default to types.DockerManifestSchema2.\n//\n// Put does not attempt to write anything other than the manifest, so callers\n// should ensure that all blobs or manifests that are referenced by t exist\n// in the target registry.\nfunc Put(ref name.Reference, t Taggable, options ...Option) error {\n\to, err := makeOptions(options...)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn newPusher(o).Push(o.context, ref, t)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/stream/README.md",
    "content": "# `stream`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/stream?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/stream)\n\nThe `stream` package contains an implementation of\n[`v1.Layer`](https://godoc.org/github.com/google/go-containerregistry/pkg/v1#Layer)\nthat supports _streaming_ access, i.e. the layer contents are read once and not\nbuffered.\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"os\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/remote\"\n\t\"github.com/google/go-containerregistry/pkg/v1/stream\"\n)\n\n// upload the contents of stdin as a layer to a local registry\nfunc main() {\n\trepo, err := name.NewRepository(\"localhost:5000/stream\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tlayer := stream.NewLayer(os.Stdin)\n\n\tif err := remote.WriteLayer(repo, layer); err != nil {\n\t\tpanic(err)\n\t}\n}\n```\n\n## Structure\n\nThis implements the layer portion of an [image\nupload](/pkg/v1/remote#anatomy-of-an-image-upload). We launch a goroutine that\nis responsible for hashing the uncompressed contents to compute the `DiffID`,\ngzipping them to produce the `Compressed` contents, and hashing/counting the\nbytes to produce the `Digest`/`Size`. This goroutine writes to an\n`io.PipeWriter`, which blocks until `Compressed` reads the gzipped contents from\nthe corresponding `io.PipeReader`.\n\n<p align=\"center\">\n  <img src=\"/images/stream.dot.svg\" />\n</p>\n\n## Caveats\n\nThis assumes that you have an uncompressed layer (i.e. a tarball) and would like\nto compress it. Calling `Uncompressed` is always an error. Likewise, other\nmethods are invalid until the contents of `Compressed` have been completely\nconsumed and `Close`d.\n\nUsing a `stream.Layer` will likely not work without careful consideration. For\nexample, in the `mutate` package, we defer computing the manifest and config\nfile until they are actually called. This allows you to `mutate.Append` a\nstreaming layer to an image without accidentally consuming it. Similarly, in\n`remote.Write`, if calling `Digest` on a layer fails, we attempt to upload the\nlayer anyway, understanding that we may be dealing with a `stream.Layer` whose\ncontents need to be uploaded before we can upload the config file.\n\nGiven the [structure](#structure) of how this is implemented, forgetting to\n`Close` a `stream.Layer` will leak a goroutine.\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/stream/layer.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package stream implements a single-pass streaming v1.Layer.\npackage stream\n\nimport (\n\t\"bufio\"\n\t\"compress/gzip\"\n\t\"crypto\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"hash\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\nvar (\n\t// ErrNotComputed is returned when the requested value is not yet\n\t// computed because the stream has not been consumed yet.\n\tErrNotComputed = errors.New(\"value not computed until stream is consumed\")\n\n\t// ErrConsumed is returned by Compressed when the underlying stream has\n\t// already been consumed and closed.\n\tErrConsumed = errors.New(\"stream was already consumed\")\n)\n\n// Layer is a streaming implementation of v1.Layer.\ntype Layer struct {\n\tblob        io.ReadCloser\n\tconsumed    bool\n\tcompression int\n\n\tmu             sync.Mutex\n\tdigest, diffID *v1.Hash\n\tsize           int64\n\tmediaType      types.MediaType\n}\n\nvar _ v1.Layer = (*Layer)(nil)\n\n// LayerOption applies options to layer\ntype LayerOption func(*Layer)\n\n// WithCompressionLevel sets the gzip compression. See `gzip.NewWriterLevel` for possible values.\nfunc WithCompressionLevel(level int) LayerOption {\n\treturn func(l *Layer) {\n\t\tl.compression = level\n\t}\n}\n\n// WithMediaType is a functional option for overriding the layer's media type.\nfunc WithMediaType(mt types.MediaType) LayerOption {\n\treturn func(l *Layer) {\n\t\tl.mediaType = mt\n\t}\n}\n\n// NewLayer creates a Layer from an io.ReadCloser.\nfunc NewLayer(rc io.ReadCloser, opts ...LayerOption) *Layer {\n\tlayer := &Layer{\n\t\tblob:        rc,\n\t\tcompression: gzip.BestSpeed,\n\t\t// We use DockerLayer for now as uncompressed layers\n\t\t// are unimplemented\n\t\tmediaType: types.DockerLayer,\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(layer)\n\t}\n\n\treturn layer\n}\n\n// Digest implements v1.Layer.\nfunc (l *Layer) Digest() (v1.Hash, error) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif l.digest == nil {\n\t\treturn v1.Hash{}, ErrNotComputed\n\t}\n\treturn *l.digest, nil\n}\n\n// DiffID implements v1.Layer.\nfunc (l *Layer) DiffID() (v1.Hash, error) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif l.diffID == nil {\n\t\treturn v1.Hash{}, ErrNotComputed\n\t}\n\treturn *l.diffID, nil\n}\n\n// Size implements v1.Layer.\nfunc (l *Layer) Size() (int64, error) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif l.size == 0 {\n\t\treturn 0, ErrNotComputed\n\t}\n\treturn l.size, nil\n}\n\n// MediaType implements v1.Layer\nfunc (l *Layer) MediaType() (types.MediaType, error) {\n\treturn l.mediaType, nil\n}\n\n// Uncompressed implements v1.Layer.\nfunc (l *Layer) Uncompressed() (io.ReadCloser, error) {\n\treturn nil, errors.New(\"NYI: stream.Layer.Uncompressed is not implemented\")\n}\n\n// Compressed implements v1.Layer.\nfunc (l *Layer) Compressed() (io.ReadCloser, error) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif l.consumed {\n\t\treturn nil, ErrConsumed\n\t}\n\treturn newCompressedReader(l)\n}\n\n// finalize sets the layer to consumed and computes all hash and size values.\nfunc (l *Layer) finalize(uncompressed, compressed hash.Hash, size int64) error {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\n\tdiffID, err := v1.NewHash(\"sha256:\" + hex.EncodeToString(uncompressed.Sum(nil)))\n\tif err != nil {\n\t\treturn err\n\t}\n\tl.diffID = &diffID\n\n\tdigest, err := v1.NewHash(\"sha256:\" + hex.EncodeToString(compressed.Sum(nil)))\n\tif err != nil {\n\t\treturn err\n\t}\n\tl.digest = &digest\n\n\tl.size = size\n\tl.consumed = true\n\treturn nil\n}\n\ntype compressedReader struct {\n\tpr     io.Reader\n\tcloser func() error\n}\n\nfunc newCompressedReader(l *Layer) (*compressedReader, error) {\n\t// Collect digests of compressed and uncompressed stream and size of\n\t// compressed stream.\n\th := crypto.SHA256.New()\n\tzh := crypto.SHA256.New()\n\tcount := &countWriter{}\n\n\t// gzip.Writer writes to the output stream via pipe, a hasher to\n\t// capture compressed digest, and a countWriter to capture compressed\n\t// size.\n\tpr, pw := io.Pipe()\n\n\t// Write compressed bytes to be read by the pipe.Reader, hashed by zh, and counted by count.\n\tmw := io.MultiWriter(pw, zh, count)\n\n\t// Buffer the output of the gzip writer so we don't have to wait on pr to keep writing.\n\t// 64K ought to be small enough for anybody.\n\tbw := bufio.NewWriterSize(mw, 2<<16)\n\tzw, err := gzip.NewWriterLevel(bw, l.compression)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdoneDigesting := make(chan struct{})\n\n\tcr := &compressedReader{\n\t\tpr: pr,\n\t\tcloser: func() error {\n\t\t\t// Immediately close pw without error. There are three ways to get\n\t\t\t// here.\n\t\t\t//\n\t\t\t// 1. There was a copy error due from the underlying reader, in which\n\t\t\t//    case the error will not be overwritten.\n\t\t\t// 2. Copying from the underlying reader completed successfully.\n\t\t\t// 3. Close has been called before the underlying reader has been\n\t\t\t//    fully consumed. In this case pw must be closed in order to\n\t\t\t//    keep the flush of bw from blocking indefinitely.\n\t\t\t//\n\t\t\t// NOTE: pw.Close never returns an error. The signature is only to\n\t\t\t// implement io.Closer.\n\t\t\t_ = pw.Close()\n\n\t\t\t// Close the inner ReadCloser.\n\t\t\t//\n\t\t\t// NOTE: net/http will call close on success, so if we've already\n\t\t\t// closed the inner rc, it's not an error.\n\t\t\tif err := l.blob.Close(); err != nil && !errors.Is(err, os.ErrClosed) {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// Finalize layer with its digest and size values.\n\t\t\t<-doneDigesting\n\t\t\treturn l.finalize(h, zh, count.n)\n\t\t},\n\t}\n\tgo func() {\n\t\t// Copy blob into the gzip writer, which also hashes and counts the\n\t\t// size of the compressed output, and hasher of the raw contents.\n\t\t_, copyErr := io.Copy(io.MultiWriter(h, zw), l.blob)\n\n\t\t// Close the gzip writer once copying is done. If this is done in the\n\t\t// Close method of compressedReader instead, then it can cause a panic\n\t\t// when the compressedReader is closed before the blob is fully\n\t\t// consumed and io.Copy in this goroutine is still blocking.\n\t\tcloseErr := zw.Close()\n\n\t\t// Check errors from writing and closing streams.\n\t\tif copyErr != nil {\n\t\t\tclose(doneDigesting)\n\t\t\tpw.CloseWithError(copyErr)\n\t\t\treturn\n\t\t}\n\t\tif closeErr != nil {\n\t\t\tclose(doneDigesting)\n\t\t\tpw.CloseWithError(closeErr)\n\t\t\treturn\n\t\t}\n\n\t\t// Flush the buffer once all writes are complete to the gzip writer.\n\t\tif err := bw.Flush(); err != nil {\n\t\t\tclose(doneDigesting)\n\t\t\tpw.CloseWithError(err)\n\t\t\treturn\n\t\t}\n\n\t\t// Notify closer that digests are done being written.\n\t\tclose(doneDigesting)\n\n\t\t// Close the compressed reader to calculate digest/diffID/size. This\n\t\t// will cause pr to return EOF which will cause readers of the\n\t\t// Compressed stream to finish reading.\n\t\tpw.CloseWithError(cr.Close())\n\t}()\n\n\treturn cr, nil\n}\n\nfunc (cr *compressedReader) Read(b []byte) (int, error) { return cr.pr.Read(b) }\n\nfunc (cr *compressedReader) Close() error { return cr.closer() }\n\n// countWriter counts bytes written to it.\ntype countWriter struct{ n int64 }\n\nfunc (c *countWriter) Write(p []byte) (int, error) {\n\tc.n += int64(len(p))\n\treturn len(p), nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/tarball/README.md",
    "content": "# `tarball`\n\n[![GoDoc](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/tarball?status.svg)](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/tarball)\n\nThis package produces tarballs that can consumed via `docker load`. Note\nthat this is a _different_ format from the [`legacy`](/pkg/legacy/tarball)\ntarballs that are produced by `docker save`, but this package is still able to\nread the legacy tarballs produced by `docker save`.\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"os\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\t\"github.com/google/go-containerregistry/pkg/v1/tarball\"\n)\n\nfunc main() {\n\t// Read a tarball from os.Args[1] that contains ubuntu.\n\ttag, err := name.NewTag(\"ubuntu\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\timg, err := tarball.ImageFromPath(os.Args[1], &tag)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// Write that tarball to os.Args[2] with a different tag.\n\tnewTag, err := name.NewTag(\"ubuntu:newest\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tf, err := os.Create(os.Args[2])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer f.Close()\n\n\tif err := tarball.Write(newTag, img, f); err != nil {\n\t\tpanic(err)\n\t}\n}\n```\n\n## Structure\n\n<p align=\"center\">\n  <img src=\"/images/tarball.dot.svg\" />\n</p>\n\nLet's look at what happens when we write out a tarball:\n\n\n### `ubuntu:latest`\n\n```\n$ crane pull ubuntu ubuntu.tar && mkdir ubuntu && tar xf ubuntu.tar -C ubuntu && rm ubuntu.tar\n$ tree ubuntu/\nubuntu/\n├── 423ae2b273f4c17ceee9e8482fa8d071d90c7d052ae208e1fe4963fceb3d6954.tar.gz\n├── b6b53be908de2c0c78070fff0a9f04835211b3156c4e73785747af365e71a0d7.tar.gz\n├── de83a2304fa1f7c4a13708a0d15b9704f5945c2be5cbb2b3ed9b2ccb718d0b3d.tar.gz\n├── f9a83bce3af0648efaa60b9bb28225b09136d2d35d0bed25ac764297076dec1b.tar.gz\n├── manifest.json\n└── sha256:72300a873c2ca11c70d0c8642177ce76ff69ae04d61a5813ef58d40ff66e3e7c\n\n0 directories, 6 files\n```\n\nThere are a couple interesting files here.\n\n`manifest.json` is the entrypoint: a list of [`tarball.Descriptor`s](https://godoc.org/github.com/google/go-containerregistry/pkg/v1/tarball#Descriptor)\nthat describe the images contained in this tarball.\n\nFor each image, this has the `RepoTags` (how it was pulled), a `Config` file\nthat points to the image's config file, a list of `Layers`, and (optionally)\n`LayerSources`.\n\n```\n$ jq < ubuntu/manifest.json\n[\n  {\n    \"Config\": \"sha256:72300a873c2ca11c70d0c8642177ce76ff69ae04d61a5813ef58d40ff66e3e7c\",\n    \"RepoTags\": [\n      \"ubuntu\"\n    ],\n    \"Layers\": [\n      \"423ae2b273f4c17ceee9e8482fa8d071d90c7d052ae208e1fe4963fceb3d6954.tar.gz\",\n      \"de83a2304fa1f7c4a13708a0d15b9704f5945c2be5cbb2b3ed9b2ccb718d0b3d.tar.gz\",\n      \"f9a83bce3af0648efaa60b9bb28225b09136d2d35d0bed25ac764297076dec1b.tar.gz\",\n      \"b6b53be908de2c0c78070fff0a9f04835211b3156c4e73785747af365e71a0d7.tar.gz\"\n    ]\n  }\n]\n```\n\nThe config file and layers are exactly what you would expect, and match the\nregistry representations of the same artifacts. You'll notice that the\n`manifest.json` contains similar information as the registry manifest, but isn't\nquite the same:\n\n```\n$ crane manifest ubuntu@sha256:0925d086715714114c1988f7c947db94064fd385e171a63c07730f1fa014e6f9\n{\n   \"schemaVersion\": 2,\n   \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n   \"config\": {\n      \"mediaType\": \"application/vnd.docker.container.image.v1+json\",\n      \"size\": 3408,\n      \"digest\": \"sha256:72300a873c2ca11c70d0c8642177ce76ff69ae04d61a5813ef58d40ff66e3e7c\"\n   },\n   \"layers\": [\n      {\n         \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n         \"size\": 26692096,\n         \"digest\": \"sha256:423ae2b273f4c17ceee9e8482fa8d071d90c7d052ae208e1fe4963fceb3d6954\"\n      },\n      {\n         \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n         \"size\": 35365,\n         \"digest\": \"sha256:de83a2304fa1f7c4a13708a0d15b9704f5945c2be5cbb2b3ed9b2ccb718d0b3d\"\n      },\n      {\n         \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n         \"size\": 852,\n         \"digest\": \"sha256:f9a83bce3af0648efaa60b9bb28225b09136d2d35d0bed25ac764297076dec1b\"\n      },\n      {\n         \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n         \"size\": 163,\n         \"digest\": \"sha256:b6b53be908de2c0c78070fff0a9f04835211b3156c4e73785747af365e71a0d7\"\n      }\n   ]\n}\n```\n\nThis makes it difficult to maintain image digests when roundtripping images\nthrough the tarball format, so it's not a great format if you care about\nprovenance.\n\nThe ubuntu example didn't have any `LayerSources` -- let's look at another image\nthat does.\n\n### `hello-world:nanoserver`\n\n```\n$ crane pull hello-world:nanoserver@sha256:63c287625c2b0b72900e562de73c0e381472a83b1b39217aef3856cd398eca0b nanoserver.tar\n$ mkdir nanoserver && tar xf nanoserver.tar -C nanoserver && rm nanoserver.tar\n$ tree nanoserver/\nnanoserver/\n├── 10d1439be4eb8819987ec2e9c140d44d74d6b42a823d57fe1953bd99948e1bc0.tar.gz\n├── a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053.tar.gz\n├── be21f08f670160cbae227e3053205b91d6bfa3de750b90c7e00bd2c511ccb63a.tar.gz\n├── manifest.json\n└── sha256:bc5d255ea81f83c8c38a982a6d29a6f2198427d258aea5f166e49856896b2da6\n\n0 directories, 5 files\n\n$ jq < nanoserver/manifest.json\n[\n  {\n    \"Config\": \"sha256:bc5d255ea81f83c8c38a982a6d29a6f2198427d258aea5f166e49856896b2da6\",\n    \"RepoTags\": [\n      \"index.docker.io/library/hello-world:i-was-a-digest\"\n    ],\n    \"Layers\": [\n      \"a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053.tar.gz\",\n      \"be21f08f670160cbae227e3053205b91d6bfa3de750b90c7e00bd2c511ccb63a.tar.gz\",\n      \"10d1439be4eb8819987ec2e9c140d44d74d6b42a823d57fe1953bd99948e1bc0.tar.gz\"\n    ],\n    \"LayerSources\": {\n      \"sha256:26fd2d9d4c64a4f965bbc77939a454a31b607470f430b5d69fc21ded301fa55e\": {\n        \"mediaType\": \"application/vnd.docker.image.rootfs.foreign.diff.tar.gzip\",\n        \"size\": 101145811,\n        \"digest\": \"sha256:a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053\",\n        \"urls\": [\n          \"https://mcr.microsoft.com/v2/windows/nanoserver/blobs/sha256:a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053\"\n        ]\n      }\n    }\n  }\n]\n```\n\nA couple things to note about this `manifest.json` versus the other:\n* The `RepoTags` field is a bit weird here. `hello-world` is a multi-platform\n  image, so We had to pull this image by digest, since we're (I'm) on\n  amd64/linux and wanted to grab a windows image. Since the tarball format\n  expects a tag under `RepoTags`, and we didn't pull by tag, we replace the\n  digest with a sentinel `i-was-a-digest` \"tag\" to appease docker.\n* The `LayerSources` has enough information to reconstruct the foreign layers\n  pointer when pushing/pulling from the registry. For legal reasons, microsoft\n  doesn't want anyone but them to serve windows base images, so the mediaType\n  here indicates a \"foreign\" or \"non-distributable\" layer with an URL for where\n  you can download it from microsoft (see the [OCI\n  image-spec](https://github.com/opencontainers/image-spec/blob/master/layer.md#non-distributable-layers)).\n\nWe can look at what's in the registry to explain both of these things:\n```\n$ crane manifest hello-world:nanoserver | jq .\n{\n  \"manifests\": [\n    {\n      \"digest\": \"sha256:63c287625c2b0b72900e562de73c0e381472a83b1b39217aef3856cd398eca0b\",\n      \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n      \"platform\": {\n        \"architecture\": \"amd64\",\n        \"os\": \"windows\",\n        \"os.version\": \"10.0.17763.1040\"\n      },\n      \"size\": 1124\n    }\n  ],\n  \"mediaType\": \"application/vnd.docker.distribution.manifest.list.v2+json\",\n  \"schemaVersion\": 2\n}\n\n\n# Note the media type and \"urls\" field.\n$ crane manifest hello-world:nanoserver@sha256:63c287625c2b0b72900e562de73c0e381472a83b1b39217aef3856cd398eca0b | jq .\n{\n  \"schemaVersion\": 2,\n  \"mediaType\": \"application/vnd.docker.distribution.manifest.v2+json\",\n  \"config\": {\n    \"mediaType\": \"application/vnd.docker.container.image.v1+json\",\n    \"size\": 1721,\n    \"digest\": \"sha256:bc5d255ea81f83c8c38a982a6d29a6f2198427d258aea5f166e49856896b2da6\"\n  },\n  \"layers\": [\n    {\n      \"mediaType\": \"application/vnd.docker.image.rootfs.foreign.diff.tar.gzip\",\n      \"size\": 101145811,\n      \"digest\": \"sha256:a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053\",\n      \"urls\": [\n        \"https://mcr.microsoft.com/v2/windows/nanoserver/blobs/sha256:a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053\"\n      ]\n    },\n    {\n      \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n      \"size\": 1669,\n      \"digest\": \"sha256:be21f08f670160cbae227e3053205b91d6bfa3de750b90c7e00bd2c511ccb63a\"\n    },\n    {\n      \"mediaType\": \"application/vnd.docker.image.rootfs.diff.tar.gzip\",\n      \"size\": 949,\n      \"digest\": \"sha256:10d1439be4eb8819987ec2e9c140d44d74d6b42a823d57fe1953bd99948e1bc0\"\n    }\n  ]\n}\n```\n\nThe `LayerSources` map is keyed by the diffid. Note that `sha256:26fd2d9d4c64a4f965bbc77939a454a31b607470f430b5d69fc21ded301fa55e` matches the first layer in the config file:\n```\n$ jq '.[0].LayerSources' < nanoserver/manifest.json\n{\n  \"sha256:26fd2d9d4c64a4f965bbc77939a454a31b607470f430b5d69fc21ded301fa55e\": {\n    \"mediaType\": \"application/vnd.docker.image.rootfs.foreign.diff.tar.gzip\",\n    \"size\": 101145811,\n    \"digest\": \"sha256:a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053\",\n    \"urls\": [\n      \"https://mcr.microsoft.com/v2/windows/nanoserver/blobs/sha256:a35da61c356213336e646756218539950461ff2bf096badf307a23add6e70053\"\n    ]\n  }\n}\n\n$ jq < nanoserver/sha256\\:bc5d255ea81f83c8c38a982a6d29a6f2198427d258aea5f166e49856896b2da6 | jq .rootfs\n{\n  \"type\": \"layers\",\n  \"diff_ids\": [\n    \"sha256:26fd2d9d4c64a4f965bbc77939a454a31b607470f430b5d69fc21ded301fa55e\",\n    \"sha256:601cf7d78c62e4b4d32a7bbf96a17606a9cea5bd9d22ffa6f34aa431d056b0e8\",\n    \"sha256:a1e1a3bf6529adcce4d91dce2cad86c2604a66b507ccbc4d2239f3da0ec5aab9\"\n  ]\n}\n```\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/tarball/doc.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package tarball provides facilities for reading/writing v1.Images from/to\n// a tarball on-disk.\npackage tarball\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/tarball/image.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage tarball\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"sync\"\n\n\tcomp \"github.com/google/go-containerregistry/internal/compression\"\n\t\"github.com/google/go-containerregistry/pkg/compression\"\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype image struct {\n\topener        Opener\n\tmanifest      *Manifest\n\tconfig        []byte\n\timgDescriptor *Descriptor\n\n\ttag *name.Tag\n}\n\ntype uncompressedImage struct {\n\t*image\n}\n\ntype compressedImage struct {\n\t*image\n\tmanifestLock sync.Mutex // Protects manifest\n\tmanifest     *v1.Manifest\n}\n\nvar _ partial.UncompressedImageCore = (*uncompressedImage)(nil)\nvar _ partial.CompressedImageCore = (*compressedImage)(nil)\n\n// Opener is a thunk for opening a tar file.\ntype Opener func() (io.ReadCloser, error)\n\nfunc pathOpener(path string) Opener {\n\treturn func() (io.ReadCloser, error) {\n\t\treturn os.Open(path)\n\t}\n}\n\n// ImageFromPath returns a v1.Image from a tarball located on path.\nfunc ImageFromPath(path string, tag *name.Tag) (v1.Image, error) {\n\treturn Image(pathOpener(path), tag)\n}\n\n// LoadManifest load manifest\nfunc LoadManifest(opener Opener) (Manifest, error) {\n\tm, err := extractFileFromTar(opener, \"manifest.json\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer m.Close()\n\n\tvar manifest Manifest\n\n\tif err := json.NewDecoder(m).Decode(&manifest); err != nil {\n\t\treturn nil, err\n\t}\n\treturn manifest, nil\n}\n\n// Image exposes an image from the tarball at the provided path.\nfunc Image(opener Opener, tag *name.Tag) (v1.Image, error) {\n\timg := &image{\n\t\topener: opener,\n\t\ttag:    tag,\n\t}\n\tif err := img.loadTarDescriptorAndConfig(); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Peek at the first layer and see if it's compressed.\n\tif len(img.imgDescriptor.Layers) > 0 {\n\t\tcompressed, err := img.areLayersCompressed()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif compressed {\n\t\t\tc := compressedImage{\n\t\t\t\timage: img,\n\t\t\t}\n\t\t\treturn partial.CompressedToImage(&c)\n\t\t}\n\t}\n\n\tuc := uncompressedImage{\n\t\timage: img,\n\t}\n\treturn partial.UncompressedToImage(&uc)\n}\n\nfunc (i *image) MediaType() (types.MediaType, error) {\n\treturn types.DockerManifestSchema2, nil\n}\n\n// Descriptor stores the manifest data for a single image inside a `docker save` tarball.\ntype Descriptor struct {\n\tConfig   string\n\tRepoTags []string\n\tLayers   []string\n\n\t// Tracks foreign layer info. Key is DiffID.\n\tLayerSources map[v1.Hash]v1.Descriptor `json:\",omitempty\"`\n}\n\n// Manifest represents the manifests of all images as the `manifest.json` file in a `docker save` tarball.\ntype Manifest []Descriptor\n\nfunc (m Manifest) findDescriptor(tag *name.Tag) (*Descriptor, error) {\n\tif tag == nil {\n\t\tif len(m) != 1 {\n\t\t\treturn nil, errors.New(\"tarball must contain only a single image to be used with tarball.Image\")\n\t\t}\n\t\treturn &(m)[0], nil\n\t}\n\tfor _, img := range m {\n\t\tfor _, tagStr := range img.RepoTags {\n\t\t\trepoTag, err := name.NewTag(tagStr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Compare the resolved names, since there are several ways to specify the same tag.\n\t\t\tif repoTag.Name() == tag.Name() {\n\t\t\t\treturn &img, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"tag %s not found in tarball\", tag)\n}\n\nfunc (i *image) areLayersCompressed() (bool, error) {\n\tif len(i.imgDescriptor.Layers) == 0 {\n\t\treturn false, errors.New(\"0 layers found in image\")\n\t}\n\tlayer := i.imgDescriptor.Layers[0]\n\tblob, err := extractFileFromTar(i.opener, layer)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tdefer blob.Close()\n\n\tcp, _, err := comp.PeekCompression(blob)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\treturn cp != compression.None, nil\n}\n\nfunc (i *image) loadTarDescriptorAndConfig() error {\n\tm, err := extractFileFromTar(i.opener, \"manifest.json\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer m.Close()\n\n\tif err := json.NewDecoder(m).Decode(&i.manifest); err != nil {\n\t\treturn err\n\t}\n\n\tif i.manifest == nil {\n\t\treturn errors.New(\"no valid manifest.json in tarball\")\n\t}\n\n\ti.imgDescriptor, err = i.manifest.findDescriptor(i.tag)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcfg, err := extractFileFromTar(i.opener, i.imgDescriptor.Config)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer cfg.Close()\n\n\ti.config, err = io.ReadAll(cfg)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (i *image) RawConfigFile() ([]byte, error) {\n\treturn i.config, nil\n}\n\n// tarFile represents a single file inside a tar. Closing it closes the tar itself.\ntype tarFile struct {\n\tio.Reader\n\tio.Closer\n}\n\nfunc extractFileFromTar(opener Opener, filePath string) (io.ReadCloser, error) {\n\tf, err := opener()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tneedClose := true\n\tdefer func() {\n\t\tif needClose {\n\t\t\tf.Close()\n\t\t}\n\t}()\n\n\ttf := tar.NewReader(f)\n\tfor {\n\t\thdr, err := tf.Next()\n\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif hdr.Name == filePath {\n\t\t\tif hdr.Typeflag == tar.TypeSymlink || hdr.Typeflag == tar.TypeLink {\n\t\t\t\tcurrentDir := filepath.Dir(filePath)\n\t\t\t\treturn extractFileFromTar(opener, path.Join(currentDir, path.Clean(hdr.Linkname)))\n\t\t\t}\n\t\t\tneedClose = false\n\t\t\treturn tarFile{\n\t\t\t\tReader: tf,\n\t\t\t\tCloser: f,\n\t\t\t}, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"file %s not found in tar\", filePath)\n}\n\n// uncompressedLayerFromTarball implements partial.UncompressedLayer\ntype uncompressedLayerFromTarball struct {\n\tdiffID    v1.Hash\n\tmediaType types.MediaType\n\topener    Opener\n\tfilePath  string\n}\n\n// foreignUncompressedLayer implements partial.UncompressedLayer but returns\n// a custom descriptor. This allows the foreign layer URLs to be included in\n// the generated image manifest for uncompressed layers.\ntype foreignUncompressedLayer struct {\n\tuncompressedLayerFromTarball\n\tdesc v1.Descriptor\n}\n\nfunc (fl *foreignUncompressedLayer) Descriptor() (*v1.Descriptor, error) {\n\treturn &fl.desc, nil\n}\n\n// DiffID implements partial.UncompressedLayer\nfunc (ulft *uncompressedLayerFromTarball) DiffID() (v1.Hash, error) {\n\treturn ulft.diffID, nil\n}\n\n// Uncompressed implements partial.UncompressedLayer\nfunc (ulft *uncompressedLayerFromTarball) Uncompressed() (io.ReadCloser, error) {\n\treturn extractFileFromTar(ulft.opener, ulft.filePath)\n}\n\nfunc (ulft *uncompressedLayerFromTarball) MediaType() (types.MediaType, error) {\n\treturn ulft.mediaType, nil\n}\n\nfunc (i *uncompressedImage) LayerByDiffID(h v1.Hash) (partial.UncompressedLayer, error) {\n\tcfg, err := partial.ConfigFile(i)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor idx, diffID := range cfg.RootFS.DiffIDs {\n\t\tif diffID == h {\n\t\t\t// Technically the media type should be 'application/tar' but given that our\n\t\t\t// v1.Layer doesn't force consumers to care about whether the layer is compressed\n\t\t\t// we should be fine returning the DockerLayer media type\n\t\t\tmt := types.DockerLayer\n\t\t\tbd, ok := i.imgDescriptor.LayerSources[h]\n\t\t\tif ok {\n\t\t\t\t// This is janky, but we don't want to implement Descriptor for\n\t\t\t\t// uncompressed layers because it breaks a bunch of assumptions in partial.\n\t\t\t\t// See https://github.com/google/go-containerregistry/issues/1870\n\t\t\t\tdocker25workaround := bd.MediaType == types.DockerUncompressedLayer || bd.MediaType == types.OCIUncompressedLayer\n\n\t\t\t\tif !docker25workaround {\n\t\t\t\t\t// Overwrite the mediaType for foreign layers.\n\t\t\t\t\treturn &foreignUncompressedLayer{\n\t\t\t\t\t\tuncompressedLayerFromTarball: uncompressedLayerFromTarball{\n\t\t\t\t\t\t\tdiffID:    diffID,\n\t\t\t\t\t\t\tmediaType: bd.MediaType,\n\t\t\t\t\t\t\topener:    i.opener,\n\t\t\t\t\t\t\tfilePath:  i.imgDescriptor.Layers[idx],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdesc: bd,\n\t\t\t\t\t}, nil\n\t\t\t\t}\n\n\t\t\t\t// Intentional fall through.\n\t\t\t}\n\n\t\t\treturn &uncompressedLayerFromTarball{\n\t\t\t\tdiffID:    diffID,\n\t\t\t\tmediaType: mt,\n\t\t\t\topener:    i.opener,\n\t\t\t\tfilePath:  i.imgDescriptor.Layers[idx],\n\t\t\t}, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"diff id %q not found\", h)\n}\n\nfunc (c *compressedImage) Manifest() (*v1.Manifest, error) {\n\tc.manifestLock.Lock()\n\tdefer c.manifestLock.Unlock()\n\tif c.manifest != nil {\n\t\treturn c.manifest, nil\n\t}\n\n\tb, err := c.RawConfigFile()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tcfgHash, cfgSize, err := v1.SHA256(bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tc.manifest = &v1.Manifest{\n\t\tSchemaVersion: 2,\n\t\tMediaType:     types.DockerManifestSchema2,\n\t\tConfig: v1.Descriptor{\n\t\t\tMediaType: types.DockerConfigJSON,\n\t\t\tSize:      cfgSize,\n\t\t\tDigest:    cfgHash,\n\t\t},\n\t}\n\n\tfor i, p := range c.imgDescriptor.Layers {\n\t\tcfg, err := partial.ConfigFile(c)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tdiffid := cfg.RootFS.DiffIDs[i]\n\t\tif d, ok := c.imgDescriptor.LayerSources[diffid]; ok {\n\t\t\t// If it's a foreign layer, just append the descriptor so we can avoid\n\t\t\t// reading the entire file.\n\t\t\tc.manifest.Layers = append(c.manifest.Layers, d)\n\t\t} else {\n\t\t\tl, err := extractFileFromTar(c.opener, p)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tdefer l.Close()\n\t\t\tsha, size, err := v1.SHA256(l)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tc.manifest.Layers = append(c.manifest.Layers, v1.Descriptor{\n\t\t\t\tMediaType: types.DockerLayer,\n\t\t\t\tSize:      size,\n\t\t\t\tDigest:    sha,\n\t\t\t})\n\t\t}\n\t}\n\treturn c.manifest, nil\n}\n\nfunc (c *compressedImage) RawManifest() ([]byte, error) {\n\treturn partial.RawManifest(c)\n}\n\n// compressedLayerFromTarball implements partial.CompressedLayer\ntype compressedLayerFromTarball struct {\n\tdesc     v1.Descriptor\n\topener   Opener\n\tfilePath string\n}\n\n// Digest implements partial.CompressedLayer\nfunc (clft *compressedLayerFromTarball) Digest() (v1.Hash, error) {\n\treturn clft.desc.Digest, nil\n}\n\n// Compressed implements partial.CompressedLayer\nfunc (clft *compressedLayerFromTarball) Compressed() (io.ReadCloser, error) {\n\treturn extractFileFromTar(clft.opener, clft.filePath)\n}\n\n// MediaType implements partial.CompressedLayer\nfunc (clft *compressedLayerFromTarball) MediaType() (types.MediaType, error) {\n\treturn clft.desc.MediaType, nil\n}\n\n// Size implements partial.CompressedLayer\nfunc (clft *compressedLayerFromTarball) Size() (int64, error) {\n\treturn clft.desc.Size, nil\n}\n\nfunc (c *compressedImage) LayerByDigest(h v1.Hash) (partial.CompressedLayer, error) {\n\tm, err := c.Manifest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor i, l := range m.Layers {\n\t\tif l.Digest == h {\n\t\t\tfp := c.imgDescriptor.Layers[i]\n\t\t\treturn &compressedLayerFromTarball{\n\t\t\t\tdesc:     l,\n\t\t\t\topener:   c.opener,\n\t\t\t\tfilePath: fp,\n\t\t\t}, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"blob %v not found\", h)\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/tarball/layer.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage tarball\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\n\t\"github.com/containerd/stargz-snapshotter/estargz\"\n\t\"github.com/google/go-containerregistry/internal/and\"\n\tcomp \"github.com/google/go-containerregistry/internal/compression\"\n\tgestargz \"github.com/google/go-containerregistry/internal/estargz\"\n\tggzip \"github.com/google/go-containerregistry/internal/gzip\"\n\t\"github.com/google/go-containerregistry/internal/zstd\"\n\t\"github.com/google/go-containerregistry/pkg/compression\"\n\t\"github.com/google/go-containerregistry/pkg/logs\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/types\"\n)\n\ntype layer struct {\n\tdigest             v1.Hash\n\tdiffID             v1.Hash\n\tsize               int64\n\tcompressedopener   Opener\n\tuncompressedopener Opener\n\tcompression        compression.Compression\n\tcompressionLevel   int\n\tannotations        map[string]string\n\testgzopts          []estargz.Option\n\tmediaType          types.MediaType\n}\n\n// Descriptor implements partial.withDescriptor.\nfunc (l *layer) Descriptor() (*v1.Descriptor, error) {\n\tdigest, err := l.Digest()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &v1.Descriptor{\n\t\tSize:        l.size,\n\t\tDigest:      digest,\n\t\tAnnotations: l.annotations,\n\t\tMediaType:   l.mediaType,\n\t}, nil\n}\n\n// Digest implements v1.Layer\nfunc (l *layer) Digest() (v1.Hash, error) {\n\treturn l.digest, nil\n}\n\n// DiffID implements v1.Layer\nfunc (l *layer) DiffID() (v1.Hash, error) {\n\treturn l.diffID, nil\n}\n\n// Compressed implements v1.Layer\nfunc (l *layer) Compressed() (io.ReadCloser, error) {\n\treturn l.compressedopener()\n}\n\n// Uncompressed implements v1.Layer\nfunc (l *layer) Uncompressed() (io.ReadCloser, error) {\n\treturn l.uncompressedopener()\n}\n\n// Size implements v1.Layer\nfunc (l *layer) Size() (int64, error) {\n\treturn l.size, nil\n}\n\n// MediaType implements v1.Layer\nfunc (l *layer) MediaType() (types.MediaType, error) {\n\treturn l.mediaType, nil\n}\n\n// LayerOption applies options to layer\ntype LayerOption func(*layer)\n\n// WithCompression is a functional option for overriding the default\n// compression algorithm used for compressing uncompressed tarballs.\n// Please note that WithCompression(compression.ZStd) should be used\n// in conjunction with WithMediaType(types.OCILayerZStd)\nfunc WithCompression(comp compression.Compression) LayerOption {\n\treturn func(l *layer) {\n\t\tswitch comp {\n\t\tcase compression.ZStd:\n\t\t\tl.compression = compression.ZStd\n\t\tcase compression.GZip:\n\t\t\tl.compression = compression.GZip\n\t\tcase compression.None:\n\t\t\tlogs.Warn.Printf(\"Compression type 'none' is not supported for tarball layers; using gzip compression.\")\n\t\t\tl.compression = compression.GZip\n\t\tdefault:\n\t\t\tlogs.Warn.Printf(\"Unexpected compression type for WithCompression(): %s; using gzip compression instead.\", comp)\n\t\t\tl.compression = compression.GZip\n\t\t}\n\t}\n}\n\n// WithCompressionLevel is a functional option for overriding the default\n// compression level used for compressing uncompressed tarballs.\nfunc WithCompressionLevel(level int) LayerOption {\n\treturn func(l *layer) {\n\t\tl.compressionLevel = level\n\t}\n}\n\n// WithMediaType is a functional option for overriding the layer's media type.\nfunc WithMediaType(mt types.MediaType) LayerOption {\n\treturn func(l *layer) {\n\t\tl.mediaType = mt\n\t}\n}\n\n// WithCompressedCaching is a functional option that overrides the\n// logic for accessing the compressed bytes to memoize the result\n// and avoid expensive repeated gzips.\nfunc WithCompressedCaching(l *layer) {\n\tvar once sync.Once\n\tvar err error\n\n\tbuf := bytes.NewBuffer(nil)\n\tog := l.compressedopener\n\n\tl.compressedopener = func() (io.ReadCloser, error) {\n\t\tonce.Do(func() {\n\t\t\tvar rc io.ReadCloser\n\t\t\trc, err = og()\n\t\t\tif err == nil {\n\t\t\t\tdefer rc.Close()\n\t\t\t\t_, err = io.Copy(buf, rc)\n\t\t\t}\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\treturn io.NopCloser(bytes.NewBuffer(buf.Bytes())), nil\n\t}\n}\n\n// WithEstargzOptions is a functional option that allow the caller to pass\n// through estargz.Options to the underlying compression layer.  This is\n// only meaningful when estargz is enabled.\n//\n// Deprecated: WithEstargz is deprecated, and will be removed in a future release.\nfunc WithEstargzOptions(opts ...estargz.Option) LayerOption {\n\treturn func(l *layer) {\n\t\tl.estgzopts = opts\n\t}\n}\n\n// WithEstargz is a functional option that explicitly enables estargz support.\n//\n// Deprecated: WithEstargz is deprecated, and will be removed in a future release.\nfunc WithEstargz(l *layer) {\n\toguncompressed := l.uncompressedopener\n\testargz := func() (io.ReadCloser, error) {\n\t\tcrc, err := oguncompressed()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\teopts := append(l.estgzopts, estargz.WithCompressionLevel(l.compressionLevel))\n\t\trc, h, err := gestargz.ReadCloser(crc, eopts...)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tl.annotations[estargz.TOCJSONDigestAnnotation] = h.String()\n\t\treturn &and.ReadCloser{\n\t\t\tReader: rc,\n\t\t\tCloseFunc: func() error {\n\t\t\t\terr := rc.Close()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\t// As an optimization, leverage the DiffID exposed by the estargz ReadCloser\n\t\t\t\tl.diffID, err = v1.NewHash(rc.DiffID().String())\n\t\t\t\treturn err\n\t\t\t},\n\t\t}, nil\n\t}\n\tuncompressed := func() (io.ReadCloser, error) {\n\t\turc, err := estargz()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn ggzip.UnzipReadCloser(urc)\n\t}\n\n\tl.compressedopener = estargz\n\tl.uncompressedopener = uncompressed\n}\n\n// LayerFromFile returns a v1.Layer given a tarball\nfunc LayerFromFile(path string, opts ...LayerOption) (v1.Layer, error) {\n\topener := func() (io.ReadCloser, error) {\n\t\treturn os.Open(path)\n\t}\n\treturn LayerFromOpener(opener, opts...)\n}\n\n// LayerFromOpener returns a v1.Layer given an Opener function.\n// The Opener may return either an uncompressed tarball (common),\n// or a compressed tarball (uncommon).\n//\n// When using this in conjunction with something like remote.Write\n// the uncompressed path may end up gzipping things multiple times:\n//  1. Compute the layer SHA256\n//  2. Upload the compressed layer.\n//\n// Since gzip can be expensive, we support an option to memoize the\n// compression that can be passed here: tarball.WithCompressedCaching\nfunc LayerFromOpener(opener Opener, opts ...LayerOption) (v1.Layer, error) {\n\tcomp, err := comp.GetCompression(opener)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tlayer := &layer{\n\t\tcompression:      compression.GZip,\n\t\tcompressionLevel: gzip.BestSpeed,\n\t\tannotations:      make(map[string]string, 1),\n\t\tmediaType:        types.DockerLayer,\n\t}\n\n\tif estgz := os.Getenv(\"GGCR_EXPERIMENT_ESTARGZ\"); estgz == \"1\" {\n\t\tlogs.Warn.Println(\"GGCR_EXPERIMENT_ESTARGZ is deprecated, and will be removed in a future release.\")\n\t\topts = append([]LayerOption{WithEstargz}, opts...)\n\t}\n\n\tswitch comp {\n\tcase compression.GZip:\n\t\tlayer.compressedopener = opener\n\t\tlayer.uncompressedopener = func() (io.ReadCloser, error) {\n\t\t\turc, err := opener()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn ggzip.UnzipReadCloser(urc)\n\t\t}\n\tcase compression.ZStd:\n\t\tlayer.compressedopener = opener\n\t\tlayer.uncompressedopener = func() (io.ReadCloser, error) {\n\t\t\turc, err := opener()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn zstd.UnzipReadCloser(urc)\n\t\t}\n\tdefault:\n\t\tlayer.uncompressedopener = opener\n\t\tlayer.compressedopener = func() (io.ReadCloser, error) {\n\t\t\tcrc, err := opener()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif layer.compression == compression.ZStd {\n\t\t\t\treturn zstd.ReadCloserLevel(crc, layer.compressionLevel), nil\n\t\t\t}\n\n\t\t\treturn ggzip.ReadCloserLevel(crc, layer.compressionLevel), nil\n\t\t}\n\t}\n\n\tfor _, opt := range opts {\n\t\topt(layer)\n\t}\n\n\t// Warn if media type does not match compression\n\tvar mediaTypeMismatch = false\n\tswitch layer.compression {\n\tcase compression.GZip:\n\t\tmediaTypeMismatch =\n\t\t\tlayer.mediaType != types.OCILayer &&\n\t\t\t\tlayer.mediaType != types.OCIRestrictedLayer &&\n\t\t\t\tlayer.mediaType != types.DockerLayer\n\n\tcase compression.ZStd:\n\t\tmediaTypeMismatch = layer.mediaType != types.OCILayerZStd\n\t}\n\n\tif mediaTypeMismatch {\n\t\tlogs.Warn.Printf(\"Unexpected mediaType (%s) for selected compression in %s in LayerFromOpener().\", layer.mediaType, layer.compression)\n\t}\n\n\tif layer.digest, layer.size, err = computeDigest(layer.compressedopener); err != nil {\n\t\treturn nil, err\n\t}\n\n\tempty := v1.Hash{}\n\tif layer.diffID == empty {\n\t\tif layer.diffID, err = computeDiffID(layer.uncompressedopener); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn layer, nil\n}\n\n// LayerFromReader returns a v1.Layer given a io.Reader.\n//\n// The reader's contents are read and buffered to a temp file in the process.\n//\n// Deprecated: Use LayerFromOpener or stream.NewLayer instead, if possible.\nfunc LayerFromReader(reader io.Reader, opts ...LayerOption) (v1.Layer, error) {\n\ttmp, err := os.CreateTemp(\"\", \"\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating temp file to buffer reader: %w\", err)\n\t}\n\tif _, err := io.Copy(tmp, reader); err != nil {\n\t\treturn nil, fmt.Errorf(\"writing temp file to buffer reader: %w\", err)\n\t}\n\treturn LayerFromFile(tmp.Name(), opts...)\n}\n\nfunc computeDigest(opener Opener) (v1.Hash, int64, error) {\n\trc, err := opener()\n\tif err != nil {\n\t\treturn v1.Hash{}, 0, err\n\t}\n\tdefer rc.Close()\n\n\treturn v1.SHA256(rc)\n}\n\nfunc computeDiffID(opener Opener) (v1.Hash, error) {\n\trc, err := opener()\n\tif err != nil {\n\t\treturn v1.Hash{}, err\n\t}\n\tdefer rc.Close()\n\n\tdigest, _, err := v1.SHA256(rc)\n\treturn digest, err\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/tarball/write.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\npackage tarball\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/google/go-containerregistry/pkg/name\"\n\tv1 \"github.com/google/go-containerregistry/pkg/v1\"\n\t\"github.com/google/go-containerregistry/pkg/v1/partial\"\n)\n\n// WriteToFile writes in the compressed format to a tarball, on disk.\n// This is just syntactic sugar wrapping tarball.Write with a new file.\nfunc WriteToFile(p string, ref name.Reference, img v1.Image, opts ...WriteOption) error {\n\tw, err := os.Create(p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer w.Close()\n\n\treturn Write(ref, img, w, opts...)\n}\n\n// MultiWriteToFile writes in the compressed format to a tarball, on disk.\n// This is just syntactic sugar wrapping tarball.MultiWrite with a new file.\nfunc MultiWriteToFile(p string, tagToImage map[name.Tag]v1.Image, opts ...WriteOption) error {\n\trefToImage := make(map[name.Reference]v1.Image, len(tagToImage))\n\tfor i, d := range tagToImage {\n\t\trefToImage[i] = d\n\t}\n\treturn MultiRefWriteToFile(p, refToImage, opts...)\n}\n\n// MultiRefWriteToFile writes in the compressed format to a tarball, on disk.\n// This is just syntactic sugar wrapping tarball.MultiRefWrite with a new file.\nfunc MultiRefWriteToFile(p string, refToImage map[name.Reference]v1.Image, opts ...WriteOption) error {\n\tw, err := os.Create(p)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer w.Close()\n\n\treturn MultiRefWrite(refToImage, w, opts...)\n}\n\n// Write is a wrapper to write a single image and tag to a tarball.\nfunc Write(ref name.Reference, img v1.Image, w io.Writer, opts ...WriteOption) error {\n\treturn MultiRefWrite(map[name.Reference]v1.Image{ref: img}, w, opts...)\n}\n\n// MultiWrite writes the contents of each image to the provided writer, in the compressed format.\n// The contents are written in the following format:\n// One manifest.json file at the top level containing information about several images.\n// One file for each layer, named after the layer's SHA.\n// One file for the config blob, named after its SHA.\nfunc MultiWrite(tagToImage map[name.Tag]v1.Image, w io.Writer, opts ...WriteOption) error {\n\trefToImage := make(map[name.Reference]v1.Image, len(tagToImage))\n\tfor i, d := range tagToImage {\n\t\trefToImage[i] = d\n\t}\n\treturn MultiRefWrite(refToImage, w, opts...)\n}\n\n// MultiRefWrite writes the contents of each image to the provided writer, in the compressed format.\n// The contents are written in the following format:\n// One manifest.json file at the top level containing information about several images.\n// One file for each layer, named after the layer's SHA.\n// One file for the config blob, named after its SHA.\nfunc MultiRefWrite(refToImage map[name.Reference]v1.Image, w io.Writer, opts ...WriteOption) error {\n\t// process options\n\to := &writeOptions{\n\t\tupdates: nil,\n\t}\n\tfor _, option := range opts {\n\t\tif err := option(o); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\timageToTags := dedupRefToImage(refToImage)\n\tsize, mBytes, err := getSizeAndManifest(imageToTags)\n\tif err != nil {\n\t\treturn sendUpdateReturn(o, err)\n\t}\n\n\treturn writeImagesToTar(imageToTags, mBytes, size, w, o)\n}\n\n// sendUpdateReturn return the passed in error message, also sending on update channel, if it exists\nfunc sendUpdateReturn(o *writeOptions, err error) error {\n\tif o != nil && o.updates != nil {\n\t\to.updates <- v1.Update{\n\t\t\tError: err,\n\t\t}\n\t}\n\treturn err\n}\n\n// sendProgressWriterReturn return the passed in error message, also sending on update channel, if it exists, along with downloaded information\nfunc sendProgressWriterReturn(pw *progressWriter, err error) error {\n\tif pw != nil {\n\t\treturn pw.Error(err)\n\t}\n\treturn err\n}\n\n// writeImagesToTar writes the images to the tarball\nfunc writeImagesToTar(imageToTags map[v1.Image][]string, m []byte, size int64, w io.Writer, o *writeOptions) (err error) {\n\tif w == nil {\n\t\treturn sendUpdateReturn(o, errors.New(\"must pass valid writer\"))\n\t}\n\n\ttw := w\n\tvar pw *progressWriter\n\n\t// we only calculate the sizes and use a progressWriter if we were provided\n\t// an option with a progress channel\n\tif o != nil && o.updates != nil {\n\t\tpw = &progressWriter{\n\t\t\tw:       w,\n\t\t\tupdates: o.updates,\n\t\t\tsize:    size,\n\t\t}\n\t\ttw = pw\n\t}\n\n\ttf := tar.NewWriter(tw)\n\tdefer tf.Close()\n\n\tseenLayerDigests := make(map[string]struct{})\n\n\tfor img := range imageToTags {\n\t\t// Write the config.\n\t\tcfgName, err := img.ConfigName()\n\t\tif err != nil {\n\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t}\n\t\tcfgBlob, err := img.RawConfigFile()\n\t\tif err != nil {\n\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t}\n\t\tif err := writeTarEntry(tf, cfgName.String(), bytes.NewReader(cfgBlob), int64(len(cfgBlob))); err != nil {\n\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t}\n\n\t\t// Write the layers.\n\t\tlayers, err := img.Layers()\n\t\tif err != nil {\n\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t}\n\t\tlayerFiles := make([]string, len(layers))\n\t\tfor i, l := range layers {\n\t\t\td, err := l.Digest()\n\t\t\tif err != nil {\n\t\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t\t}\n\t\t\t// Munge the file name to appease ancient technology.\n\t\t\t//\n\t\t\t// tar assumes anything with a colon is a remote tape drive:\n\t\t\t// https://www.gnu.org/software/tar/manual/html_section/tar_45.html\n\t\t\t// Drop the algorithm prefix, e.g. \"sha256:\"\n\t\t\thex := d.Hex\n\n\t\t\t// gunzip expects certain file extensions:\n\t\t\t// https://www.gnu.org/software/gzip/manual/html_node/Overview.html\n\t\t\tlayerFiles[i] = fmt.Sprintf(\"%s.tar.gz\", hex)\n\n\t\t\tif _, ok := seenLayerDigests[hex]; ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tseenLayerDigests[hex] = struct{}{}\n\n\t\t\tr, err := l.Compressed()\n\t\t\tif err != nil {\n\t\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t\t}\n\t\t\tblobSize, err := l.Size()\n\t\t\tif err != nil {\n\t\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t\t}\n\n\t\t\tif err := writeTarEntry(tf, layerFiles[i], r, blobSize); err != nil {\n\t\t\t\treturn sendProgressWriterReturn(pw, err)\n\t\t\t}\n\t\t}\n\t}\n\tif err := writeTarEntry(tf, \"manifest.json\", bytes.NewReader(m), int64(len(m))); err != nil {\n\t\treturn sendProgressWriterReturn(pw, err)\n\t}\n\n\t// be sure to close the tar writer so everything is flushed out before we send our EOF\n\tif err := tf.Close(); err != nil {\n\t\treturn sendProgressWriterReturn(pw, err)\n\t}\n\t// send an EOF to indicate finished on the channel, but nil as our return error\n\t_ = sendProgressWriterReturn(pw, io.EOF)\n\treturn nil\n}\n\n// calculateManifest calculates the manifest and optionally the size of the tar file\nfunc calculateManifest(imageToTags map[v1.Image][]string) (m Manifest, err error) {\n\tif len(imageToTags) == 0 {\n\t\treturn nil, errors.New(\"set of images is empty\")\n\t}\n\n\tfor img, tags := range imageToTags {\n\t\tcfgName, err := img.ConfigName()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// Store foreign layer info.\n\t\tlayerSources := make(map[v1.Hash]v1.Descriptor)\n\n\t\t// Write the layers.\n\t\tlayers, err := img.Layers()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tlayerFiles := make([]string, len(layers))\n\t\tfor i, l := range layers {\n\t\t\td, err := l.Digest()\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t// Munge the file name to appease ancient technology.\n\t\t\t//\n\t\t\t// tar assumes anything with a colon is a remote tape drive:\n\t\t\t// https://www.gnu.org/software/tar/manual/html_section/tar_45.html\n\t\t\t// Drop the algorithm prefix, e.g. \"sha256:\"\n\t\t\thex := d.Hex\n\n\t\t\t// gunzip expects certain file extensions:\n\t\t\t// https://www.gnu.org/software/gzip/manual/html_node/Overview.html\n\t\t\tlayerFiles[i] = fmt.Sprintf(\"%s.tar.gz\", hex)\n\n\t\t\t// Add to LayerSources if it's a foreign layer.\n\t\t\tdesc, err := partial.BlobDescriptor(img, d)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif !desc.MediaType.IsDistributable() {\n\t\t\t\tdiffid, err := partial.BlobToDiffID(img, d)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tlayerSources[diffid] = *desc\n\t\t\t}\n\t\t}\n\n\t\t// Generate the tar descriptor and write it.\n\t\tm = append(m, Descriptor{\n\t\t\tConfig:       cfgName.String(),\n\t\t\tRepoTags:     tags,\n\t\t\tLayers:       layerFiles,\n\t\t\tLayerSources: layerSources,\n\t\t})\n\t}\n\t// sort by name of the repotags so it is consistent. Alternatively, we could sort by hash of the\n\t// descriptor, but that would make it hard for humans to process\n\tsort.Slice(m, func(i, j int) bool {\n\t\treturn strings.Join(m[i].RepoTags, \",\") < strings.Join(m[j].RepoTags, \",\")\n\t})\n\n\treturn m, nil\n}\n\n// CalculateSize calculates the expected complete size of the output tar file\nfunc CalculateSize(refToImage map[name.Reference]v1.Image) (size int64, err error) {\n\timageToTags := dedupRefToImage(refToImage)\n\tsize, _, err = getSizeAndManifest(imageToTags)\n\treturn size, err\n}\n\nfunc getSizeAndManifest(imageToTags map[v1.Image][]string) (int64, []byte, error) {\n\tm, err := calculateManifest(imageToTags)\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"unable to calculate manifest: %w\", err)\n\t}\n\tmBytes, err := json.Marshal(m)\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"could not marshall manifest to bytes: %w\", err)\n\t}\n\n\tsize, err := calculateTarballSize(imageToTags, mBytes)\n\tif err != nil {\n\t\treturn 0, nil, fmt.Errorf(\"error calculating tarball size: %w\", err)\n\t}\n\treturn size, mBytes, nil\n}\n\n// calculateTarballSize calculates the size of the tar file\nfunc calculateTarballSize(imageToTags map[v1.Image][]string, mBytes []byte) (size int64, err error) {\n\tseenLayerDigests := make(map[string]struct{})\n\tfor img, name := range imageToTags {\n\t\tmanifest, err := img.Manifest()\n\t\tif err != nil {\n\t\t\treturn size, fmt.Errorf(\"unable to get manifest for img %s: %w\", name, err)\n\t\t}\n\t\tsize += calculateSingleFileInTarSize(manifest.Config.Size)\n\t\tfor _, l := range manifest.Layers {\n\t\t\thex := l.Digest.Hex\n\t\t\tif _, ok := seenLayerDigests[hex]; ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tseenLayerDigests[hex] = struct{}{}\n\t\t\tsize += calculateSingleFileInTarSize(l.Size)\n\t\t}\n\t}\n\t// add the manifest\n\tsize += calculateSingleFileInTarSize(int64(len(mBytes)))\n\n\t// add the two padding blocks that indicate end of a tar file\n\tsize += 1024\n\treturn size, nil\n}\n\nfunc dedupRefToImage(refToImage map[name.Reference]v1.Image) map[v1.Image][]string {\n\timageToTags := make(map[v1.Image][]string)\n\n\tfor ref, img := range refToImage {\n\t\tif tag, ok := ref.(name.Tag); ok {\n\t\t\tif tags, ok := imageToTags[img]; !ok || tags == nil {\n\t\t\t\timageToTags[img] = []string{}\n\t\t\t}\n\t\t\t// Docker cannot load tarballs without an explicit tag:\n\t\t\t// https://github.com/google/go-containerregistry/issues/890\n\t\t\t//\n\t\t\t// We can't use the fully qualified tag.Name() because of rules_docker:\n\t\t\t// https://github.com/google/go-containerregistry/issues/527\n\t\t\t//\n\t\t\t// If the tag is \"latest\", but tag.String() doesn't end in \":latest\",\n\t\t\t// just append it. Kind of gross, but should work for now.\n\t\t\tts := tag.String()\n\t\t\tif tag.Identifier() == name.DefaultTag && !strings.HasSuffix(ts, \":\"+name.DefaultTag) {\n\t\t\t\tts = fmt.Sprintf(\"%s:%s\", ts, name.DefaultTag)\n\t\t\t}\n\t\t\timageToTags[img] = append(imageToTags[img], ts)\n\t\t} else if _, ok := imageToTags[img]; !ok {\n\t\t\timageToTags[img] = nil\n\t\t}\n\t}\n\n\treturn imageToTags\n}\n\n// writeTarEntry writes a file to the provided writer with a corresponding tar header\nfunc writeTarEntry(tf *tar.Writer, path string, r io.Reader, size int64) error {\n\thdr := &tar.Header{\n\t\tMode:     0644,\n\t\tTypeflag: tar.TypeReg,\n\t\tSize:     size,\n\t\tName:     path,\n\t}\n\tif err := tf.WriteHeader(hdr); err != nil {\n\t\treturn err\n\t}\n\t_, err := io.Copy(tf, r)\n\treturn err\n}\n\n// ComputeManifest get the manifest.json that will be written to the tarball\n// for multiple references\nfunc ComputeManifest(refToImage map[name.Reference]v1.Image) (Manifest, error) {\n\timageToTags := dedupRefToImage(refToImage)\n\treturn calculateManifest(imageToTags)\n}\n\n// WriteOption a function option to pass to Write()\ntype WriteOption func(*writeOptions) error\ntype writeOptions struct {\n\tupdates chan<- v1.Update\n}\n\n// WithProgress create a WriteOption for passing to Write() that enables\n// a channel to receive updates as they are downloaded and written to disk.\nfunc WithProgress(updates chan<- v1.Update) WriteOption {\n\treturn func(o *writeOptions) error {\n\t\to.updates = updates\n\t\treturn nil\n\t}\n}\n\n// progressWriter is a writer which will send the download progress\ntype progressWriter struct {\n\tw              io.Writer\n\tupdates        chan<- v1.Update\n\tsize, complete int64\n}\n\nfunc (pw *progressWriter) Write(p []byte) (int, error) {\n\tn, err := pw.w.Write(p)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\n\tpw.complete += int64(n)\n\n\tpw.updates <- v1.Update{\n\t\tTotal:    pw.size,\n\t\tComplete: pw.complete,\n\t}\n\n\treturn n, err\n}\n\nfunc (pw *progressWriter) Error(err error) error {\n\tpw.updates <- v1.Update{\n\t\tTotal:    pw.size,\n\t\tComplete: pw.complete,\n\t\tError:    err,\n\t}\n\treturn err\n}\n\nfunc (pw *progressWriter) Close() error {\n\tpw.updates <- v1.Update{\n\t\tTotal:    pw.size,\n\t\tComplete: pw.complete,\n\t\tError:    io.EOF,\n\t}\n\treturn io.EOF\n}\n\n// calculateSingleFileInTarSize calculate the size a file will take up in a tar archive,\n// given the input data. Provided by rounding up to nearest whole block (512)\n// and adding header 512\nfunc calculateSingleFileInTarSize(in int64) (out int64) {\n\t// doing this manually, because math.Round() works with float64\n\tout += in\n\tif remainder := out % 512; remainder != 0 {\n\t\tout += (512 - remainder)\n\t}\n\tout += 512\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/types/types.go",
    "content": "// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Package types holds common OCI media types.\npackage types\n\n// MediaType is an enumeration of the supported mime types that an element of an image might have.\ntype MediaType string\n\n// The collection of known MediaType values.\nconst (\n\tOCIContentDescriptor           MediaType = \"application/vnd.oci.descriptor.v1+json\"\n\tOCIImageIndex                  MediaType = \"application/vnd.oci.image.index.v1+json\"\n\tOCIManifestSchema1             MediaType = \"application/vnd.oci.image.manifest.v1+json\"\n\tOCIConfigJSON                  MediaType = \"application/vnd.oci.image.config.v1+json\"\n\tOCILayer                       MediaType = \"application/vnd.oci.image.layer.v1.tar+gzip\"\n\tOCILayerZStd                   MediaType = \"application/vnd.oci.image.layer.v1.tar+zstd\"\n\tOCIRestrictedLayer             MediaType = \"application/vnd.oci.image.layer.nondistributable.v1.tar+gzip\"\n\tOCIUncompressedLayer           MediaType = \"application/vnd.oci.image.layer.v1.tar\"\n\tOCIUncompressedRestrictedLayer MediaType = \"application/vnd.oci.image.layer.nondistributable.v1.tar\"\n\n\tDockerManifestSchema1       MediaType = \"application/vnd.docker.distribution.manifest.v1+json\"\n\tDockerManifestSchema1Signed MediaType = \"application/vnd.docker.distribution.manifest.v1+prettyjws\"\n\tDockerManifestSchema2       MediaType = \"application/vnd.docker.distribution.manifest.v2+json\"\n\tDockerManifestList          MediaType = \"application/vnd.docker.distribution.manifest.list.v2+json\"\n\tDockerLayer                 MediaType = \"application/vnd.docker.image.rootfs.diff.tar.gzip\"\n\tDockerConfigJSON            MediaType = \"application/vnd.docker.container.image.v1+json\"\n\tDockerPluginConfig          MediaType = \"application/vnd.docker.plugin.v1+json\"\n\tDockerForeignLayer          MediaType = \"application/vnd.docker.image.rootfs.foreign.diff.tar.gzip\"\n\tDockerUncompressedLayer     MediaType = \"application/vnd.docker.image.rootfs.diff.tar\"\n\n\tOCIVendorPrefix    = \"vnd.oci\"\n\tDockerVendorPrefix = \"vnd.docker\"\n)\n\n// IsDistributable returns true if a layer is distributable, see:\n// https://github.com/opencontainers/image-spec/blob/master/layer.md#non-distributable-layers\nfunc (m MediaType) IsDistributable() bool {\n\tswitch m {\n\tcase DockerForeignLayer, OCIRestrictedLayer, OCIUncompressedRestrictedLayer:\n\t\treturn false\n\t}\n\treturn true\n}\n\n// IsImage returns true if the mediaType represents an image manifest, as opposed to something else, like an index.\nfunc (m MediaType) IsImage() bool {\n\tswitch m {\n\tcase OCIManifestSchema1, DockerManifestSchema2:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// IsIndex returns true if the mediaType represents an index, as opposed to something else, like an image.\nfunc (m MediaType) IsIndex() bool {\n\tswitch m {\n\tcase OCIImageIndex, DockerManifestList:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// IsConfig returns true if the mediaType represents a config, as opposed to something else, like an image.\nfunc (m MediaType) IsConfig() bool {\n\tswitch m {\n\tcase OCIConfigJSON, DockerConfigJSON:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (m MediaType) IsSchema1() bool {\n\tswitch m {\n\tcase DockerManifestSchema1, DockerManifestSchema1Signed:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (m MediaType) IsLayer() bool {\n\tswitch m {\n\tcase DockerLayer, DockerUncompressedLayer, OCILayer, OCILayerZStd, OCIUncompressedLayer, DockerForeignLayer, OCIRestrictedLayer, OCIUncompressedRestrictedLayer:\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/google/go-containerregistry/pkg/v1/zz_deepcopy_generated.go",
    "content": "//go:build !ignore_autogenerated\n// +build !ignore_autogenerated\n\n// Copyright 2018 Google LLC All Rights Reserved.\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//    http://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\n// Code generated by deepcopy-gen. DO NOT EDIT.\n\npackage v1\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Config) DeepCopyInto(out *Config) {\n\t*out = *in\n\tif in.Cmd != nil {\n\t\tin, out := &in.Cmd, &out.Cmd\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.Healthcheck != nil {\n\t\tin, out := &in.Healthcheck, &out.Healthcheck\n\t\t*out = new(HealthConfig)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\tif in.Entrypoint != nil {\n\t\tin, out := &in.Entrypoint, &out.Entrypoint\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.Env != nil {\n\t\tin, out := &in.Env, &out.Env\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.Labels != nil {\n\t\tin, out := &in.Labels, &out.Labels\n\t\t*out = make(map[string]string, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.OnBuild != nil {\n\t\tin, out := &in.OnBuild, &out.OnBuild\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.Volumes != nil {\n\t\tin, out := &in.Volumes, &out.Volumes\n\t\t*out = make(map[string]struct{}, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.ExposedPorts != nil {\n\t\tin, out := &in.ExposedPorts, &out.ExposedPorts\n\t\t*out = make(map[string]struct{}, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.Shell != nil {\n\t\tin, out := &in.Shell, &out.Shell\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Config.\nfunc (in *Config) DeepCopy() *Config {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Config)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *ConfigFile) DeepCopyInto(out *ConfigFile) {\n\t*out = *in\n\tin.Created.DeepCopyInto(&out.Created)\n\tif in.History != nil {\n\t\tin, out := &in.History, &out.History\n\t\t*out = make([]History, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n\tin.RootFS.DeepCopyInto(&out.RootFS)\n\tin.Config.DeepCopyInto(&out.Config)\n\tif in.OSFeatures != nil {\n\t\tin, out := &in.OSFeatures, &out.OSFeatures\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigFile.\nfunc (in *ConfigFile) DeepCopy() *ConfigFile {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(ConfigFile)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Descriptor) DeepCopyInto(out *Descriptor) {\n\t*out = *in\n\tout.Digest = in.Digest\n\tif in.Data != nil {\n\t\tin, out := &in.Data, &out.Data\n\t\t*out = make([]byte, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.URLs != nil {\n\t\tin, out := &in.URLs, &out.URLs\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.Annotations != nil {\n\t\tin, out := &in.Annotations, &out.Annotations\n\t\t*out = make(map[string]string, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.Platform != nil {\n\t\tin, out := &in.Platform, &out.Platform\n\t\t*out = new(Platform)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Descriptor.\nfunc (in *Descriptor) DeepCopy() *Descriptor {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Descriptor)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Hash) DeepCopyInto(out *Hash) {\n\t*out = *in\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Hash.\nfunc (in *Hash) DeepCopy() *Hash {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Hash)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *HealthConfig) DeepCopyInto(out *HealthConfig) {\n\t*out = *in\n\tif in.Test != nil {\n\t\tin, out := &in.Test, &out.Test\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthConfig.\nfunc (in *HealthConfig) DeepCopy() *HealthConfig {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(HealthConfig)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *History) DeepCopyInto(out *History) {\n\t*out = *in\n\tin.Created.DeepCopyInto(&out.Created)\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new History.\nfunc (in *History) DeepCopy() *History {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(History)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *IndexManifest) DeepCopyInto(out *IndexManifest) {\n\t*out = *in\n\tif in.Manifests != nil {\n\t\tin, out := &in.Manifests, &out.Manifests\n\t\t*out = make([]Descriptor, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n\tif in.Annotations != nil {\n\t\tin, out := &in.Annotations, &out.Annotations\n\t\t*out = make(map[string]string, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.Subject != nil {\n\t\tin, out := &in.Subject, &out.Subject\n\t\t*out = new(Descriptor)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IndexManifest.\nfunc (in *IndexManifest) DeepCopy() *IndexManifest {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(IndexManifest)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Manifest) DeepCopyInto(out *Manifest) {\n\t*out = *in\n\tin.Config.DeepCopyInto(&out.Config)\n\tif in.Layers != nil {\n\t\tin, out := &in.Layers, &out.Layers\n\t\t*out = make([]Descriptor, len(*in))\n\t\tfor i := range *in {\n\t\t\t(*in)[i].DeepCopyInto(&(*out)[i])\n\t\t}\n\t}\n\tif in.Annotations != nil {\n\t\tin, out := &in.Annotations, &out.Annotations\n\t\t*out = make(map[string]string, len(*in))\n\t\tfor key, val := range *in {\n\t\t\t(*out)[key] = val\n\t\t}\n\t}\n\tif in.Subject != nil {\n\t\tin, out := &in.Subject, &out.Subject\n\t\t*out = new(Descriptor)\n\t\t(*in).DeepCopyInto(*out)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Manifest.\nfunc (in *Manifest) DeepCopy() *Manifest {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Manifest)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *Platform) DeepCopyInto(out *Platform) {\n\t*out = *in\n\tif in.OSFeatures != nil {\n\t\tin, out := &in.OSFeatures, &out.OSFeatures\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\tif in.Features != nil {\n\t\tin, out := &in.Features, &out.Features\n\t\t*out = make([]string, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Platform.\nfunc (in *Platform) DeepCopy() *Platform {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Platform)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\nfunc (in *RootFS) DeepCopyInto(out *RootFS) {\n\t*out = *in\n\tif in.DiffIDs != nil {\n\t\tin, out := &in.DiffIDs, &out.DiffIDs\n\t\t*out = make([]Hash, len(*in))\n\t\tcopy(*out, *in)\n\t}\n\treturn\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RootFS.\nfunc (in *RootFS) DeepCopy() *RootFS {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(RootFS)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n\n// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Time.\nfunc (in *Time) DeepCopy() *Time {\n\tif in == nil {\n\t\treturn nil\n\t}\n\tout := new(Time)\n\tin.DeepCopyInto(out)\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/google/gofuzz/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.11.x\n  - 1.12.x\n  - 1.13.x\n  - master\n\nscript:\n  - go test -cover\n"
  },
  {
    "path": "vendor/github.com/google/gofuzz/CONTRIBUTING.md",
    "content": "# How to contribute #\n\nWe'd love to accept your patches and contributions to this project.  There are\njust a few small guidelines you need to follow.\n\n\n## Contributor License Agreement ##\n\nContributions to any Google project must be accompanied by a Contributor\nLicense Agreement.  This is not a copyright **assignment**, it simply gives\nGoogle permission to use and redistribute your contributions as part of the\nproject.\n\n  * If you are an individual writing original source code and you're sure you\n    own the intellectual property, then you'll need to sign an [individual\n    CLA][].\n\n  * If you work for a company that wants to allow you to contribute your work,\n    then you'll need to sign a [corporate CLA][].\n\nYou generally only need to submit a CLA once, so if you've already submitted\none (even if it was for a different project), you probably don't need to do it\nagain.\n\n[individual CLA]: https://developers.google.com/open-source/cla/individual\n[corporate CLA]: https://developers.google.com/open-source/cla/corporate\n\n\n## Submitting a patch ##\n\n  1. It's generally best to start by opening a new issue describing the bug or\n     feature you're intending to fix.  Even if you think it's relatively minor,\n     it's helpful to know what people are working on.  Mention in the initial\n     issue that you are planning to work on that bug or feature so that it can\n     be assigned to you.\n\n  1. Follow the normal process of [forking][] the project, and setup a new\n     branch to work in.  It's important that each group of changes be done in\n     separate branches in order to ensure that a pull request only includes the\n     commits related to that bug or feature.\n\n  1. Go makes it very simple to ensure properly formatted code, so always run\n     `go fmt` on your code before committing it.  You should also run\n     [golint][] over your code.  As noted in the [golint readme][], it's not\n     strictly necessary that your code be completely \"lint-free\", but this will\n     help you find common style issues.\n\n  1. Any significant changes should almost always be accompanied by tests.  The\n     project already has good test coverage, so look at some of the existing\n     tests if you're unsure how to go about it.  [gocov][] and [gocov-html][]\n     are invaluable tools for seeing which parts of your code aren't being\n     exercised by your tests.\n\n  1. Do your best to have [well-formed commit messages][] for each change.\n     This provides consistency throughout the project, and ensures that commit\n     messages are able to be formatted properly by various git tools.\n\n  1. Finally, push the commits to your fork and submit a [pull request][].\n\n[forking]: https://help.github.com/articles/fork-a-repo\n[golint]: https://github.com/golang/lint\n[golint readme]: https://github.com/golang/lint/blob/master/README\n[gocov]: https://github.com/axw/gocov\n[gocov-html]: https://github.com/matm/gocov-html\n[well-formed commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html\n[squash]: http://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits\n[pull request]: https://help.github.com/articles/creating-a-pull-request\n"
  },
  {
    "path": "vendor/github.com/google/gofuzz/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/google/gofuzz/README.md",
    "content": "gofuzz\n======\n\ngofuzz is a library for populating go objects with random values.\n\n[![GoDoc](https://godoc.org/github.com/google/gofuzz?status.svg)](https://godoc.org/github.com/google/gofuzz)\n[![Travis](https://travis-ci.org/google/gofuzz.svg?branch=master)](https://travis-ci.org/google/gofuzz)\n\nThis is useful for testing:\n\n* Do your project's objects really serialize/unserialize correctly in all cases?\n* Is there an incorrectly formatted object that will cause your project to panic?\n\nImport with ```import \"github.com/google/gofuzz\"```\n\nYou can use it on single variables:\n```go\nf := fuzz.New()\nvar myInt int\nf.Fuzz(&myInt) // myInt gets a random value.\n```\n\nYou can use it on maps:\n```go\nf := fuzz.New().NilChance(0).NumElements(1, 1)\nvar myMap map[ComplexKeyType]string\nf.Fuzz(&myMap) // myMap will have exactly one element.\n```\n\nCustomize the chance of getting a nil pointer:\n```go\nf := fuzz.New().NilChance(.5)\nvar fancyStruct struct {\n  A, B, C, D *string\n}\nf.Fuzz(&fancyStruct) // About half the pointers should be set.\n```\n\nYou can even customize the randomization completely if needed:\n```go\ntype MyEnum string\nconst (\n        A MyEnum = \"A\"\n        B MyEnum = \"B\"\n)\ntype MyInfo struct {\n        Type MyEnum\n        AInfo *string\n        BInfo *string\n}\n\nf := fuzz.New().NilChance(0).Funcs(\n        func(e *MyInfo, c fuzz.Continue) {\n                switch c.Intn(2) {\n                case 0:\n                        e.Type = A\n                        c.Fuzz(&e.AInfo)\n                case 1:\n                        e.Type = B\n                        c.Fuzz(&e.BInfo)\n                }\n        },\n)\n\nvar myObject MyInfo\nf.Fuzz(&myObject) // Type will correspond to whether A or B info is set.\n```\n\nSee more examples in ```example_test.go```.\n\nYou can use this library for easier [go-fuzz](https://github.com/dvyukov/go-fuzz)ing.\ngo-fuzz provides the user a byte-slice, which should be converted to different inputs\nfor the tested function. This library can help convert the byte slice. Consider for\nexample a fuzz test for a the function `mypackage.MyFunc` that takes an int arguments:\n```go\n// +build gofuzz\npackage mypackage\n\nimport fuzz \"github.com/google/gofuzz\"\n\nfunc Fuzz(data []byte) int {\n        var i int\n        fuzz.NewFromGoFuzz(data).Fuzz(&i)\n        MyFunc(i)\n        return 0\n}\n```\n\nHappy testing!\n"
  },
  {
    "path": "vendor/github.com/google/gofuzz/bytesource/bytesource.go",
    "content": "/*\nCopyright 2014 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package bytesource provides a rand.Source64 that is determined by a slice of bytes.\npackage bytesource\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"math/rand\"\n)\n\n// ByteSource implements rand.Source64 determined by a slice of bytes. The random numbers are\n// generated from each 8 bytes in the slice, until the last bytes are consumed, from which a\n// fallback pseudo random source is created in case more random numbers are required.\n// It also exposes a `bytes.Reader` API, which lets callers consume the bytes directly.\ntype ByteSource struct {\n\t*bytes.Reader\n\tfallback rand.Source\n}\n\n// New returns a new ByteSource from a given slice of bytes.\nfunc New(input []byte) *ByteSource {\n\ts := &ByteSource{\n\t\tReader:   bytes.NewReader(input),\n\t\tfallback: rand.NewSource(0),\n\t}\n\tif len(input) > 0 {\n\t\ts.fallback = rand.NewSource(int64(s.consumeUint64()))\n\t}\n\treturn s\n}\n\nfunc (s *ByteSource) Uint64() uint64 {\n\t// Return from input if it was not exhausted.\n\tif s.Len() > 0 {\n\t\treturn s.consumeUint64()\n\t}\n\n\t// Input was exhausted, return random number from fallback (in this case fallback should not be\n\t// nil). Try first having a Uint64 output (Should work in current rand implementation),\n\t// otherwise return a conversion of Int63.\n\tif s64, ok := s.fallback.(rand.Source64); ok {\n\t\treturn s64.Uint64()\n\t}\n\treturn uint64(s.fallback.Int63())\n}\n\nfunc (s *ByteSource) Int63() int64 {\n\treturn int64(s.Uint64() >> 1)\n}\n\nfunc (s *ByteSource) Seed(seed int64) {\n\ts.fallback = rand.NewSource(seed)\n\ts.Reader = bytes.NewReader(nil)\n}\n\n// consumeUint64 reads 8 bytes from the input and convert them to a uint64. It assumes that the the\n// bytes reader is not empty.\nfunc (s *ByteSource) consumeUint64() uint64 {\n\tvar bytes [8]byte\n\t_, err := s.Read(bytes[:])\n\tif err != nil && err != io.EOF {\n\t\tpanic(\"failed reading source\") // Should not happen.\n\t}\n\treturn binary.BigEndian.Uint64(bytes[:])\n}\n"
  },
  {
    "path": "vendor/github.com/google/gofuzz/doc.go",
    "content": "/*\nCopyright 2014 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n// Package fuzz is a library for populating go objects with random values.\npackage fuzz\n"
  },
  {
    "path": "vendor/github.com/google/gofuzz/fuzz.go",
    "content": "/*\nCopyright 2014 Google Inc. All rights reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage fuzz\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"time\"\n\n\t\"github.com/google/gofuzz/bytesource\"\n\t\"strings\"\n)\n\n// fuzzFuncMap is a map from a type to a fuzzFunc that handles that type.\ntype fuzzFuncMap map[reflect.Type]reflect.Value\n\n// Fuzzer knows how to fill any object with random fields.\ntype Fuzzer struct {\n\tfuzzFuncs         fuzzFuncMap\n\tdefaultFuzzFuncs  fuzzFuncMap\n\tr                 *rand.Rand\n\tnilChance         float64\n\tminElements       int\n\tmaxElements       int\n\tmaxDepth          int\n\tskipFieldPatterns []*regexp.Regexp\n}\n\n// New returns a new Fuzzer. Customize your Fuzzer further by calling Funcs,\n// RandSource, NilChance, or NumElements in any order.\nfunc New() *Fuzzer {\n\treturn NewWithSeed(time.Now().UnixNano())\n}\n\nfunc NewWithSeed(seed int64) *Fuzzer {\n\tf := &Fuzzer{\n\t\tdefaultFuzzFuncs: fuzzFuncMap{\n\t\t\treflect.TypeOf(&time.Time{}): reflect.ValueOf(fuzzTime),\n\t\t},\n\n\t\tfuzzFuncs:   fuzzFuncMap{},\n\t\tr:           rand.New(rand.NewSource(seed)),\n\t\tnilChance:   .2,\n\t\tminElements: 1,\n\t\tmaxElements: 10,\n\t\tmaxDepth:    100,\n\t}\n\treturn f\n}\n\n// NewFromGoFuzz is a helper function that enables using gofuzz (this\n// project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous\n// fuzzing. Essentially, it enables translating the fuzzing bytes from\n// go-fuzz to any Go object using this library.\n//\n// This implementation promises a constant translation from a given slice of\n// bytes to the fuzzed objects. This promise will remain over future\n// versions of Go and of this library.\n//\n// Note: the returned Fuzzer should not be shared between multiple goroutines,\n// as its deterministic output will no longer be available.\n//\n// Example: use go-fuzz to test the function `MyFunc(int)` in the package\n// `mypackage`. Add the file: \"mypacakge_fuzz.go\" with the content:\n//\n// // +build gofuzz\n// package mypacakge\n// import fuzz \"github.com/google/gofuzz\"\n// func Fuzz(data []byte) int {\n// \tvar i int\n// \tfuzz.NewFromGoFuzz(data).Fuzz(&i)\n// \tMyFunc(i)\n// \treturn 0\n// }\nfunc NewFromGoFuzz(data []byte) *Fuzzer {\n\treturn New().RandSource(bytesource.New(data))\n}\n\n// Funcs adds each entry in fuzzFuncs as a custom fuzzing function.\n//\n// Each entry in fuzzFuncs must be a function taking two parameters.\n// The first parameter must be a pointer or map. It is the variable that\n// function will fill with random data. The second parameter must be a\n// fuzz.Continue, which will provide a source of randomness and a way\n// to automatically continue fuzzing smaller pieces of the first parameter.\n//\n// These functions are called sensibly, e.g., if you wanted custom string\n// fuzzing, the function `func(s *string, c fuzz.Continue)` would get\n// called and passed the address of strings. Maps and pointers will always\n// be made/new'd for you, ignoring the NilChange option. For slices, it\n// doesn't make much sense to  pre-create them--Fuzzer doesn't know how\n// long you want your slice--so take a pointer to a slice, and make it\n// yourself. (If you don't want your map/pointer type pre-made, take a\n// pointer to it, and make it yourself.) See the examples for a range of\n// custom functions.\nfunc (f *Fuzzer) Funcs(fuzzFuncs ...interface{}) *Fuzzer {\n\tfor i := range fuzzFuncs {\n\t\tv := reflect.ValueOf(fuzzFuncs[i])\n\t\tif v.Kind() != reflect.Func {\n\t\t\tpanic(\"Need only funcs!\")\n\t\t}\n\t\tt := v.Type()\n\t\tif t.NumIn() != 2 || t.NumOut() != 0 {\n\t\t\tpanic(\"Need 2 in and 0 out params!\")\n\t\t}\n\t\targT := t.In(0)\n\t\tswitch argT.Kind() {\n\t\tcase reflect.Ptr, reflect.Map:\n\t\tdefault:\n\t\t\tpanic(\"fuzzFunc must take pointer or map type\")\n\t\t}\n\t\tif t.In(1) != reflect.TypeOf(Continue{}) {\n\t\t\tpanic(\"fuzzFunc's second parameter must be type fuzz.Continue\")\n\t\t}\n\t\tf.fuzzFuncs[argT] = v\n\t}\n\treturn f\n}\n\n// RandSource causes f to get values from the given source of randomness.\n// Use if you want deterministic fuzzing.\nfunc (f *Fuzzer) RandSource(s rand.Source) *Fuzzer {\n\tf.r = rand.New(s)\n\treturn f\n}\n\n// NilChance sets the probability of creating a nil pointer, map, or slice to\n// 'p'. 'p' should be between 0 (no nils) and 1 (all nils), inclusive.\nfunc (f *Fuzzer) NilChance(p float64) *Fuzzer {\n\tif p < 0 || p > 1 {\n\t\tpanic(\"p should be between 0 and 1, inclusive.\")\n\t}\n\tf.nilChance = p\n\treturn f\n}\n\n// NumElements sets the minimum and maximum number of elements that will be\n// added to a non-nil map or slice.\nfunc (f *Fuzzer) NumElements(atLeast, atMost int) *Fuzzer {\n\tif atLeast > atMost {\n\t\tpanic(\"atLeast must be <= atMost\")\n\t}\n\tif atLeast < 0 {\n\t\tpanic(\"atLeast must be >= 0\")\n\t}\n\tf.minElements = atLeast\n\tf.maxElements = atMost\n\treturn f\n}\n\nfunc (f *Fuzzer) genElementCount() int {\n\tif f.minElements == f.maxElements {\n\t\treturn f.minElements\n\t}\n\treturn f.minElements + f.r.Intn(f.maxElements-f.minElements+1)\n}\n\nfunc (f *Fuzzer) genShouldFill() bool {\n\treturn f.r.Float64() >= f.nilChance\n}\n\n// MaxDepth sets the maximum number of recursive fuzz calls that will be made\n// before stopping.  This includes struct members, pointers, and map and slice\n// elements.\nfunc (f *Fuzzer) MaxDepth(d int) *Fuzzer {\n\tf.maxDepth = d\n\treturn f\n}\n\n// Skip fields which match the supplied pattern. Call this multiple times if needed\n// This is useful to skip XXX_ fields generated by protobuf\nfunc (f *Fuzzer) SkipFieldsWithPattern(pattern *regexp.Regexp) *Fuzzer {\n\tf.skipFieldPatterns = append(f.skipFieldPatterns, pattern)\n\treturn f\n}\n\n// Fuzz recursively fills all of obj's fields with something random.  First\n// this tries to find a custom fuzz function (see Funcs).  If there is no\n// custom function this tests whether the object implements fuzz.Interface and,\n// if so, calls Fuzz on it to fuzz itself.  If that fails, this will see if\n// there is a default fuzz function provided by this package.  If all of that\n// fails, this will generate random values for all primitive fields and then\n// recurse for all non-primitives.\n//\n// This is safe for cyclic or tree-like structs, up to a limit.  Use the\n// MaxDepth method to adjust how deep you need it to recurse.\n//\n// obj must be a pointer. Only exported (public) fields can be set (thanks,\n// golang :/ ) Intended for tests, so will panic on bad input or unimplemented\n// fields.\nfunc (f *Fuzzer) Fuzz(obj interface{}) {\n\tv := reflect.ValueOf(obj)\n\tif v.Kind() != reflect.Ptr {\n\t\tpanic(\"needed ptr!\")\n\t}\n\tv = v.Elem()\n\tf.fuzzWithContext(v, 0)\n}\n\n// FuzzNoCustom is just like Fuzz, except that any custom fuzz function for\n// obj's type will not be called and obj will not be tested for fuzz.Interface\n// conformance.  This applies only to obj and not other instances of obj's\n// type.\n// Not safe for cyclic or tree-like structs!\n// obj must be a pointer. Only exported (public) fields can be set (thanks, golang :/ )\n// Intended for tests, so will panic on bad input or unimplemented fields.\nfunc (f *Fuzzer) FuzzNoCustom(obj interface{}) {\n\tv := reflect.ValueOf(obj)\n\tif v.Kind() != reflect.Ptr {\n\t\tpanic(\"needed ptr!\")\n\t}\n\tv = v.Elem()\n\tf.fuzzWithContext(v, flagNoCustomFuzz)\n}\n\nconst (\n\t// Do not try to find a custom fuzz function.  Does not apply recursively.\n\tflagNoCustomFuzz uint64 = 1 << iota\n)\n\nfunc (f *Fuzzer) fuzzWithContext(v reflect.Value, flags uint64) {\n\tfc := &fuzzerContext{fuzzer: f}\n\tfc.doFuzz(v, flags)\n}\n\n// fuzzerContext carries context about a single fuzzing run, which lets Fuzzer\n// be thread-safe.\ntype fuzzerContext struct {\n\tfuzzer   *Fuzzer\n\tcurDepth int\n}\n\nfunc (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) {\n\tif fc.curDepth >= fc.fuzzer.maxDepth {\n\t\treturn\n\t}\n\tfc.curDepth++\n\tdefer func() { fc.curDepth-- }()\n\n\tif !v.CanSet() {\n\t\treturn\n\t}\n\n\tif flags&flagNoCustomFuzz == 0 {\n\t\t// Check for both pointer and non-pointer custom functions.\n\t\tif v.CanAddr() && fc.tryCustom(v.Addr()) {\n\t\t\treturn\n\t\t}\n\t\tif fc.tryCustom(v) {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif fn, ok := fillFuncMap[v.Kind()]; ok {\n\t\tfn(v, fc.fuzzer.r)\n\t\treturn\n\t}\n\n\tswitch v.Kind() {\n\tcase reflect.Map:\n\t\tif fc.fuzzer.genShouldFill() {\n\t\t\tv.Set(reflect.MakeMap(v.Type()))\n\t\t\tn := fc.fuzzer.genElementCount()\n\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\tkey := reflect.New(v.Type().Key()).Elem()\n\t\t\t\tfc.doFuzz(key, 0)\n\t\t\t\tval := reflect.New(v.Type().Elem()).Elem()\n\t\t\t\tfc.doFuzz(val, 0)\n\t\t\t\tv.SetMapIndex(key, val)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tv.Set(reflect.Zero(v.Type()))\n\tcase reflect.Ptr:\n\t\tif fc.fuzzer.genShouldFill() {\n\t\t\tv.Set(reflect.New(v.Type().Elem()))\n\t\t\tfc.doFuzz(v.Elem(), 0)\n\t\t\treturn\n\t\t}\n\t\tv.Set(reflect.Zero(v.Type()))\n\tcase reflect.Slice:\n\t\tif fc.fuzzer.genShouldFill() {\n\t\t\tn := fc.fuzzer.genElementCount()\n\t\t\tv.Set(reflect.MakeSlice(v.Type(), n, n))\n\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\tfc.doFuzz(v.Index(i), 0)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tv.Set(reflect.Zero(v.Type()))\n\tcase reflect.Array:\n\t\tif fc.fuzzer.genShouldFill() {\n\t\t\tn := v.Len()\n\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\tfc.doFuzz(v.Index(i), 0)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tv.Set(reflect.Zero(v.Type()))\n\tcase reflect.Struct:\n\t\tfor i := 0; i < v.NumField(); i++ {\n\t\t\tskipField := false\n\t\t\tfieldName := v.Type().Field(i).Name\n\t\t\tfor _, pattern := range fc.fuzzer.skipFieldPatterns {\n\t\t\t\tif pattern.MatchString(fieldName) {\n\t\t\t\t\tskipField = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !skipField {\n\t\t\t\tfc.doFuzz(v.Field(i), 0)\n\t\t\t}\n\t\t}\n\tcase reflect.Chan:\n\t\tfallthrough\n\tcase reflect.Func:\n\t\tfallthrough\n\tcase reflect.Interface:\n\t\tfallthrough\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Can't handle %#v\", v.Interface()))\n\t}\n}\n\n// tryCustom searches for custom handlers, and returns true iff it finds a match\n// and successfully randomizes v.\nfunc (fc *fuzzerContext) tryCustom(v reflect.Value) bool {\n\t// First: see if we have a fuzz function for it.\n\tdoCustom, ok := fc.fuzzer.fuzzFuncs[v.Type()]\n\tif !ok {\n\t\t// Second: see if it can fuzz itself.\n\t\tif v.CanInterface() {\n\t\t\tintf := v.Interface()\n\t\t\tif fuzzable, ok := intf.(Interface); ok {\n\t\t\t\tfuzzable.Fuzz(Continue{fc: fc, Rand: fc.fuzzer.r})\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\t// Finally: see if there is a default fuzz function.\n\t\tdoCustom, ok = fc.fuzzer.defaultFuzzFuncs[v.Type()]\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tswitch v.Kind() {\n\tcase reflect.Ptr:\n\t\tif v.IsNil() {\n\t\t\tif !v.CanSet() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tv.Set(reflect.New(v.Type().Elem()))\n\t\t}\n\tcase reflect.Map:\n\t\tif v.IsNil() {\n\t\t\tif !v.CanSet() {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tv.Set(reflect.MakeMap(v.Type()))\n\t\t}\n\tdefault:\n\t\treturn false\n\t}\n\n\tdoCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{\n\t\tfc:   fc,\n\t\tRand: fc.fuzzer.r,\n\t})})\n\treturn true\n}\n\n// Interface represents an object that knows how to fuzz itself.  Any time we\n// find a type that implements this interface we will delegate the act of\n// fuzzing itself.\ntype Interface interface {\n\tFuzz(c Continue)\n}\n\n// Continue can be passed to custom fuzzing functions to allow them to use\n// the correct source of randomness and to continue fuzzing their members.\ntype Continue struct {\n\tfc *fuzzerContext\n\n\t// For convenience, Continue implements rand.Rand via embedding.\n\t// Use this for generating any randomness if you want your fuzzing\n\t// to be repeatable for a given seed.\n\t*rand.Rand\n}\n\n// Fuzz continues fuzzing obj. obj must be a pointer.\nfunc (c Continue) Fuzz(obj interface{}) {\n\tv := reflect.ValueOf(obj)\n\tif v.Kind() != reflect.Ptr {\n\t\tpanic(\"needed ptr!\")\n\t}\n\tv = v.Elem()\n\tc.fc.doFuzz(v, 0)\n}\n\n// FuzzNoCustom continues fuzzing obj, except that any custom fuzz function for\n// obj's type will not be called and obj will not be tested for fuzz.Interface\n// conformance.  This applies only to obj and not other instances of obj's\n// type.\nfunc (c Continue) FuzzNoCustom(obj interface{}) {\n\tv := reflect.ValueOf(obj)\n\tif v.Kind() != reflect.Ptr {\n\t\tpanic(\"needed ptr!\")\n\t}\n\tv = v.Elem()\n\tc.fc.doFuzz(v, flagNoCustomFuzz)\n}\n\n// RandString makes a random string up to 20 characters long. The returned string\n// may include a variety of (valid) UTF-8 encodings.\nfunc (c Continue) RandString() string {\n\treturn randString(c.Rand)\n}\n\n// RandUint64 makes random 64 bit numbers.\n// Weirdly, rand doesn't have a function that gives you 64 random bits.\nfunc (c Continue) RandUint64() uint64 {\n\treturn randUint64(c.Rand)\n}\n\n// RandBool returns true or false randomly.\nfunc (c Continue) RandBool() bool {\n\treturn randBool(c.Rand)\n}\n\nfunc fuzzInt(v reflect.Value, r *rand.Rand) {\n\tv.SetInt(int64(randUint64(r)))\n}\n\nfunc fuzzUint(v reflect.Value, r *rand.Rand) {\n\tv.SetUint(randUint64(r))\n}\n\nfunc fuzzTime(t *time.Time, c Continue) {\n\tvar sec, nsec int64\n\t// Allow for about 1000 years of random time values, which keeps things\n\t// like JSON parsing reasonably happy.\n\tsec = c.Rand.Int63n(1000 * 365 * 24 * 60 * 60)\n\tc.Fuzz(&nsec)\n\t*t = time.Unix(sec, nsec)\n}\n\nvar fillFuncMap = map[reflect.Kind]func(reflect.Value, *rand.Rand){\n\treflect.Bool: func(v reflect.Value, r *rand.Rand) {\n\t\tv.SetBool(randBool(r))\n\t},\n\treflect.Int:     fuzzInt,\n\treflect.Int8:    fuzzInt,\n\treflect.Int16:   fuzzInt,\n\treflect.Int32:   fuzzInt,\n\treflect.Int64:   fuzzInt,\n\treflect.Uint:    fuzzUint,\n\treflect.Uint8:   fuzzUint,\n\treflect.Uint16:  fuzzUint,\n\treflect.Uint32:  fuzzUint,\n\treflect.Uint64:  fuzzUint,\n\treflect.Uintptr: fuzzUint,\n\treflect.Float32: func(v reflect.Value, r *rand.Rand) {\n\t\tv.SetFloat(float64(r.Float32()))\n\t},\n\treflect.Float64: func(v reflect.Value, r *rand.Rand) {\n\t\tv.SetFloat(r.Float64())\n\t},\n\treflect.Complex64: func(v reflect.Value, r *rand.Rand) {\n\t\tv.SetComplex(complex128(complex(r.Float32(), r.Float32())))\n\t},\n\treflect.Complex128: func(v reflect.Value, r *rand.Rand) {\n\t\tv.SetComplex(complex(r.Float64(), r.Float64()))\n\t},\n\treflect.String: func(v reflect.Value, r *rand.Rand) {\n\t\tv.SetString(randString(r))\n\t},\n\treflect.UnsafePointer: func(v reflect.Value, r *rand.Rand) {\n\t\tpanic(\"unimplemented\")\n\t},\n}\n\n// randBool returns true or false randomly.\nfunc randBool(r *rand.Rand) bool {\n\treturn r.Int31()&(1<<30) == 0\n}\n\ntype int63nPicker interface {\n\tInt63n(int64) int64\n}\n\n// UnicodeRange describes a sequential range of unicode characters.\n// Last must be numerically greater than First.\ntype UnicodeRange struct {\n\tFirst, Last rune\n}\n\n// UnicodeRanges describes an arbitrary number of sequential ranges of unicode characters.\n// To be useful, each range must have at least one character (First <= Last) and\n// there must be at least one range.\ntype UnicodeRanges []UnicodeRange\n\n// choose returns a random unicode character from the given range, using the\n// given randomness source.\nfunc (ur UnicodeRange) choose(r int63nPicker) rune {\n\tcount := int64(ur.Last - ur.First + 1)\n\treturn ur.First + rune(r.Int63n(count))\n}\n\n// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.\n// Each character is selected from the range ur. If there are no characters\n// in the range (cr.Last < cr.First), this will panic.\nfunc (ur UnicodeRange) CustomStringFuzzFunc() func(s *string, c Continue) {\n\tur.check()\n\treturn func(s *string, c Continue) {\n\t\t*s = ur.randString(c.Rand)\n\t}\n}\n\n// check is a function that used to check whether the first of ur(UnicodeRange)\n// is greater than the last one.\nfunc (ur UnicodeRange) check() {\n\tif ur.Last < ur.First {\n\t\tpanic(\"The last encoding must be greater than the first one.\")\n\t}\n}\n\n// randString of UnicodeRange makes a random string up to 20 characters long.\n// Each character is selected form ur(UnicodeRange).\nfunc (ur UnicodeRange) randString(r *rand.Rand) string {\n\tn := r.Intn(20)\n\tsb := strings.Builder{}\n\tsb.Grow(n)\n\tfor i := 0; i < n; i++ {\n\t\tsb.WriteRune(ur.choose(r))\n\t}\n\treturn sb.String()\n}\n\n// defaultUnicodeRanges sets a default unicode range when user do not set\n// CustomStringFuzzFunc() but wants fuzz string.\nvar defaultUnicodeRanges = UnicodeRanges{\n\t{' ', '~'},           // ASCII characters\n\t{'\\u00a0', '\\u02af'}, // Multi-byte encoded characters\n\t{'\\u4e00', '\\u9fff'}, // Common CJK (even longer encodings)\n}\n\n// CustomStringFuzzFunc constructs a FuzzFunc which produces random strings.\n// Each character is selected from one of the ranges of ur(UnicodeRanges).\n// Each range has an equal probability of being chosen. If there are no ranges,\n// or a selected range has no characters (.Last < .First), this will panic.\n// Do not modify any of the ranges in ur after calling this function.\nfunc (ur UnicodeRanges) CustomStringFuzzFunc() func(s *string, c Continue) {\n\t// Check unicode ranges slice is empty.\n\tif len(ur) == 0 {\n\t\tpanic(\"UnicodeRanges is empty.\")\n\t}\n\t// if not empty, each range should be checked.\n\tfor i := range ur {\n\t\tur[i].check()\n\t}\n\treturn func(s *string, c Continue) {\n\t\t*s = ur.randString(c.Rand)\n\t}\n}\n\n// randString of UnicodeRanges makes a random string up to 20 characters long.\n// Each character is selected form one of the ranges of ur(UnicodeRanges),\n// and each range has an equal probability of being chosen.\nfunc (ur UnicodeRanges) randString(r *rand.Rand) string {\n\tn := r.Intn(20)\n\tsb := strings.Builder{}\n\tsb.Grow(n)\n\tfor i := 0; i < n; i++ {\n\t\tsb.WriteRune(ur[r.Intn(len(ur))].choose(r))\n\t}\n\treturn sb.String()\n}\n\n// randString makes a random string up to 20 characters long. The returned string\n// may include a variety of (valid) UTF-8 encodings.\nfunc randString(r *rand.Rand) string {\n\treturn defaultUnicodeRanges.randString(r)\n}\n\n// randUint64 makes random 64 bit numbers.\n// Weirdly, rand doesn't have a function that gives you 64 random bits.\nfunc randUint64(r *rand.Rand) uint64 {\n\treturn uint64(r.Uint32())<<32 | uint64(r.Uint32())\n}\n"
  },
  {
    "path": "vendor/github.com/google/shlex/COPYING",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/google/shlex/README",
    "content": "go-shlex is a simple lexer for go that supports shell-style quoting,\ncommenting, and escaping.\n"
  },
  {
    "path": "vendor/github.com/google/shlex/shlex.go",
    "content": "/*\nCopyright 2012 Google Inc. All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\n/*\nPackage shlex implements a simple lexer which splits input in to tokens using\nshell-style rules for quoting and commenting.\n\nThe basic use case uses the default ASCII lexer to split a string into sub-strings:\n\n  shlex.Split(\"one \\\"two three\\\" four\") -> []string{\"one\", \"two three\", \"four\"}\n\nTo process a stream of strings:\n\n  l := NewLexer(os.Stdin)\n  for ; token, err := l.Next(); err != nil {\n  \t// process token\n  }\n\nTo access the raw token stream (which includes tokens for comments):\n\n  t := NewTokenizer(os.Stdin)\n  for ; token, err := t.Next(); err != nil {\n\t// process token\n  }\n\n*/\npackage shlex\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\n// TokenType is a top-level token classification: A word, space, comment, unknown.\ntype TokenType int\n\n// runeTokenClass is the type of a UTF-8 character classification: A quote, space, escape.\ntype runeTokenClass int\n\n// the internal state used by the lexer state machine\ntype lexerState int\n\n// Token is a (type, value) pair representing a lexographical token.\ntype Token struct {\n\ttokenType TokenType\n\tvalue     string\n}\n\n// Equal reports whether tokens a, and b, are equal.\n// Two tokens are equal if both their types and values are equal. A nil token can\n// never be equal to another token.\nfunc (a *Token) Equal(b *Token) bool {\n\tif a == nil || b == nil {\n\t\treturn false\n\t}\n\tif a.tokenType != b.tokenType {\n\t\treturn false\n\t}\n\treturn a.value == b.value\n}\n\n// Named classes of UTF-8 runes\nconst (\n\tspaceRunes            = \" \\t\\r\\n\"\n\tescapingQuoteRunes    = `\"`\n\tnonEscapingQuoteRunes = \"'\"\n\tescapeRunes           = `\\`\n\tcommentRunes          = \"#\"\n)\n\n// Classes of rune token\nconst (\n\tunknownRuneClass runeTokenClass = iota\n\tspaceRuneClass\n\tescapingQuoteRuneClass\n\tnonEscapingQuoteRuneClass\n\tescapeRuneClass\n\tcommentRuneClass\n\teofRuneClass\n)\n\n// Classes of lexographic token\nconst (\n\tUnknownToken TokenType = iota\n\tWordToken\n\tSpaceToken\n\tCommentToken\n)\n\n// Lexer state machine states\nconst (\n\tstartState           lexerState = iota // no runes have been seen\n\tinWordState                            // processing regular runes in a word\n\tescapingState                          // we have just consumed an escape rune; the next rune is literal\n\tescapingQuotedState                    // we have just consumed an escape rune within a quoted string\n\tquotingEscapingState                   // we are within a quoted string that supports escaping (\"...\")\n\tquotingState                           // we are within a string that does not support escaping ('...')\n\tcommentState                           // we are within a comment (everything following an unquoted or unescaped #\n)\n\n// tokenClassifier is used for classifying rune characters.\ntype tokenClassifier map[rune]runeTokenClass\n\nfunc (typeMap tokenClassifier) addRuneClass(runes string, tokenType runeTokenClass) {\n\tfor _, runeChar := range runes {\n\t\ttypeMap[runeChar] = tokenType\n\t}\n}\n\n// newDefaultClassifier creates a new classifier for ASCII characters.\nfunc newDefaultClassifier() tokenClassifier {\n\tt := tokenClassifier{}\n\tt.addRuneClass(spaceRunes, spaceRuneClass)\n\tt.addRuneClass(escapingQuoteRunes, escapingQuoteRuneClass)\n\tt.addRuneClass(nonEscapingQuoteRunes, nonEscapingQuoteRuneClass)\n\tt.addRuneClass(escapeRunes, escapeRuneClass)\n\tt.addRuneClass(commentRunes, commentRuneClass)\n\treturn t\n}\n\n// ClassifyRune classifiees a rune\nfunc (t tokenClassifier) ClassifyRune(runeVal rune) runeTokenClass {\n\treturn t[runeVal]\n}\n\n// Lexer turns an input stream into a sequence of tokens. Whitespace and comments are skipped.\ntype Lexer Tokenizer\n\n// NewLexer creates a new lexer from an input stream.\nfunc NewLexer(r io.Reader) *Lexer {\n\n\treturn (*Lexer)(NewTokenizer(r))\n}\n\n// Next returns the next word, or an error. If there are no more words,\n// the error will be io.EOF.\nfunc (l *Lexer) Next() (string, error) {\n\tfor {\n\t\ttoken, err := (*Tokenizer)(l).Next()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tswitch token.tokenType {\n\t\tcase WordToken:\n\t\t\treturn token.value, nil\n\t\tcase CommentToken:\n\t\t\t// skip comments\n\t\tdefault:\n\t\t\treturn \"\", fmt.Errorf(\"Unknown token type: %v\", token.tokenType)\n\t\t}\n\t}\n}\n\n// Tokenizer turns an input stream into a sequence of typed tokens\ntype Tokenizer struct {\n\tinput      bufio.Reader\n\tclassifier tokenClassifier\n}\n\n// NewTokenizer creates a new tokenizer from an input stream.\nfunc NewTokenizer(r io.Reader) *Tokenizer {\n\tinput := bufio.NewReader(r)\n\tclassifier := newDefaultClassifier()\n\treturn &Tokenizer{\n\t\tinput:      *input,\n\t\tclassifier: classifier}\n}\n\n// scanStream scans the stream for the next token using the internal state machine.\n// It will panic if it encounters a rune which it does not know how to handle.\nfunc (t *Tokenizer) scanStream() (*Token, error) {\n\tstate := startState\n\tvar tokenType TokenType\n\tvar value []rune\n\tvar nextRune rune\n\tvar nextRuneType runeTokenClass\n\tvar err error\n\n\tfor {\n\t\tnextRune, _, err = t.input.ReadRune()\n\t\tnextRuneType = t.classifier.ClassifyRune(nextRune)\n\n\t\tif err == io.EOF {\n\t\t\tnextRuneType = eofRuneClass\n\t\t\terr = nil\n\t\t} else if err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tswitch state {\n\t\tcase startState: // no runes read yet\n\t\t\t{\n\t\t\t\tswitch nextRuneType {\n\t\t\t\tcase eofRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\treturn nil, io.EOF\n\t\t\t\t\t}\n\t\t\t\tcase spaceRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t}\n\t\t\t\tcase escapingQuoteRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\ttokenType = WordToken\n\t\t\t\t\t\tstate = quotingEscapingState\n\t\t\t\t\t}\n\t\t\t\tcase nonEscapingQuoteRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\ttokenType = WordToken\n\t\t\t\t\t\tstate = quotingState\n\t\t\t\t\t}\n\t\t\t\tcase escapeRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\ttokenType = WordToken\n\t\t\t\t\t\tstate = escapingState\n\t\t\t\t\t}\n\t\t\t\tcase commentRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\ttokenType = CommentToken\n\t\t\t\t\t\tstate = commentState\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\ttokenType = WordToken\n\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t\tstate = inWordState\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase inWordState: // in a regular word\n\t\t\t{\n\t\t\t\tswitch nextRuneType {\n\t\t\t\tcase eofRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\treturn token, err\n\t\t\t\t\t}\n\t\t\t\tcase spaceRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\treturn token, err\n\t\t\t\t\t}\n\t\t\t\tcase escapingQuoteRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = quotingEscapingState\n\t\t\t\t\t}\n\t\t\t\tcase nonEscapingQuoteRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = quotingState\n\t\t\t\t\t}\n\t\t\t\tcase escapeRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = escapingState\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase escapingState: // the rune after an escape character\n\t\t\t{\n\t\t\t\tswitch nextRuneType {\n\t\t\t\tcase eofRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\terr = fmt.Errorf(\"EOF found after escape character\")\n\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\treturn token, err\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = inWordState\n\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase escapingQuotedState: // the next rune after an escape character, in double quotes\n\t\t\t{\n\t\t\t\tswitch nextRuneType {\n\t\t\t\tcase eofRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\terr = fmt.Errorf(\"EOF found after escape character\")\n\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\treturn token, err\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = quotingEscapingState\n\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase quotingEscapingState: // in escaping double quotes\n\t\t\t{\n\t\t\t\tswitch nextRuneType {\n\t\t\t\tcase eofRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\terr = fmt.Errorf(\"EOF found when expecting closing quote\")\n\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\treturn token, err\n\t\t\t\t\t}\n\t\t\t\tcase escapingQuoteRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = inWordState\n\t\t\t\t\t}\n\t\t\t\tcase escapeRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = escapingQuotedState\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase quotingState: // in non-escaping single quotes\n\t\t\t{\n\t\t\t\tswitch nextRuneType {\n\t\t\t\tcase eofRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\terr = fmt.Errorf(\"EOF found when expecting closing quote\")\n\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\treturn token, err\n\t\t\t\t\t}\n\t\t\t\tcase nonEscapingQuoteRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\tstate = inWordState\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase commentState: // in a comment\n\t\t\t{\n\t\t\t\tswitch nextRuneType {\n\t\t\t\tcase eofRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\treturn token, err\n\t\t\t\t\t}\n\t\t\t\tcase spaceRuneClass:\n\t\t\t\t\t{\n\t\t\t\t\t\tif nextRune == '\\n' {\n\t\t\t\t\t\t\tstate = startState\n\t\t\t\t\t\t\ttoken := &Token{\n\t\t\t\t\t\t\t\ttokenType: tokenType,\n\t\t\t\t\t\t\t\tvalue:     string(value)}\n\t\t\t\t\t\t\treturn token, err\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tdefault:\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue = append(value, nextRune)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\t{\n\t\t\t\treturn nil, fmt.Errorf(\"Unexpected state: %v\", state)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Next returns the next token in the stream.\nfunc (t *Tokenizer) Next() (*Token, error) {\n\treturn t.scanStream()\n}\n\n// Split partitions a string into a slice of strings.\nfunc Split(s string) ([]string, error) {\n\tl := NewLexer(strings.NewReader(s))\n\tsubStrings := make([]string, 0)\n\tfor {\n\t\tword, err := l.Next()\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\treturn subStrings, nil\n\t\t\t}\n\t\t\treturn subStrings, err\n\t\t}\n\t\tsubStrings = append(subStrings, word)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.4.3\n  - 1.5.3\n  - tip\n\nscript:\n  - go test -v ./...\n"
  },
  {
    "path": "vendor/github.com/google/uuid/CONTRIBUTING.md",
    "content": "# How to contribute\n\nWe definitely welcome patches and contribution to this project!\n\n### Legal requirements\n\nIn order to protect both you and ourselves, you will need to sign the\n[Contributor License Agreement](https://cla.developers.google.com/clas).\n\nYou may have already signed it for other Google projects.\n"
  },
  {
    "path": "vendor/github.com/google/uuid/CONTRIBUTORS",
    "content": "Paul Borman <borman@google.com>\nbmatsuo\nshawnps\ntheory\njboverfelt\ndsymonds\ncd1\nwallclockbuilder\ndansouza\n"
  },
  {
    "path": "vendor/github.com/google/uuid/LICENSE",
    "content": "Copyright (c) 2009,2014 Google Inc. 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/google/uuid/README.md",
    "content": "# uuid ![build status](https://travis-ci.org/google/uuid.svg?branch=master)\nThe uuid package generates and inspects UUIDs based on\n[RFC 4122](http://tools.ietf.org/html/rfc4122)\nand DCE 1.1: Authentication and Security Services. \n\nThis package is based on the github.com/pborman/uuid package (previously named\ncode.google.com/p/go-uuid).  It differs from these earlier packages in that\na UUID is a 16 byte array rather than a byte slice.  One loss due to this\nchange is the ability to represent an invalid UUID (vs a NIL UUID).\n\n###### Install\n`go get github.com/google/uuid`\n\n###### Documentation \n[![GoDoc](https://godoc.org/github.com/google/uuid?status.svg)](http://godoc.org/github.com/google/uuid)\n\nFull `go doc` style documentation for the package can be viewed online without\ninstalling this package by using the GoDoc site here: \nhttp://pkg.go.dev/github.com/google/uuid\n"
  },
  {
    "path": "vendor/github.com/google/uuid/dce.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"os\"\n)\n\n// A Domain represents a Version 2 domain\ntype Domain byte\n\n// Domain constants for DCE Security (Version 2) UUIDs.\nconst (\n\tPerson = Domain(0)\n\tGroup  = Domain(1)\n\tOrg    = Domain(2)\n)\n\n// NewDCESecurity returns a DCE Security (Version 2) UUID.\n//\n// The domain should be one of Person, Group or Org.\n// On a POSIX system the id should be the users UID for the Person\n// domain and the users GID for the Group.  The meaning of id for\n// the domain Org or on non-POSIX systems is site defined.\n//\n// For a given domain/id pair the same token may be returned for up to\n// 7 minutes and 10 seconds.\nfunc NewDCESecurity(domain Domain, id uint32) (UUID, error) {\n\tuuid, err := NewUUID()\n\tif err == nil {\n\t\tuuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2\n\t\tuuid[9] = byte(domain)\n\t\tbinary.BigEndian.PutUint32(uuid[0:], id)\n\t}\n\treturn uuid, err\n}\n\n// NewDCEPerson returns a DCE Security (Version 2) UUID in the person\n// domain with the id returned by os.Getuid.\n//\n//  NewDCESecurity(Person, uint32(os.Getuid()))\nfunc NewDCEPerson() (UUID, error) {\n\treturn NewDCESecurity(Person, uint32(os.Getuid()))\n}\n\n// NewDCEGroup returns a DCE Security (Version 2) UUID in the group\n// domain with the id returned by os.Getgid.\n//\n//  NewDCESecurity(Group, uint32(os.Getgid()))\nfunc NewDCEGroup() (UUID, error) {\n\treturn NewDCESecurity(Group, uint32(os.Getgid()))\n}\n\n// Domain returns the domain for a Version 2 UUID.  Domains are only defined\n// for Version 2 UUIDs.\nfunc (uuid UUID) Domain() Domain {\n\treturn Domain(uuid[9])\n}\n\n// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2\n// UUIDs.\nfunc (uuid UUID) ID() uint32 {\n\treturn binary.BigEndian.Uint32(uuid[0:4])\n}\n\nfunc (d Domain) String() string {\n\tswitch d {\n\tcase Person:\n\t\treturn \"Person\"\n\tcase Group:\n\t\treturn \"Group\"\n\tcase Org:\n\t\treturn \"Org\"\n\t}\n\treturn fmt.Sprintf(\"Domain%d\", int(d))\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/doc.go",
    "content": "// Copyright 2016 Google Inc.  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// Package uuid generates and inspects UUIDs.\n//\n// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security\n// Services.\n//\n// A UUID is a 16 byte (128 bit) array.  UUIDs may be used as keys to\n// maps or compared directly.\npackage uuid\n"
  },
  {
    "path": "vendor/github.com/google/uuid/hash.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"crypto/md5\"\n\t\"crypto/sha1\"\n\t\"hash\"\n)\n\n// Well known namespace IDs and UUIDs\nvar (\n\tNameSpaceDNS  = Must(Parse(\"6ba7b810-9dad-11d1-80b4-00c04fd430c8\"))\n\tNameSpaceURL  = Must(Parse(\"6ba7b811-9dad-11d1-80b4-00c04fd430c8\"))\n\tNameSpaceOID  = Must(Parse(\"6ba7b812-9dad-11d1-80b4-00c04fd430c8\"))\n\tNameSpaceX500 = Must(Parse(\"6ba7b814-9dad-11d1-80b4-00c04fd430c8\"))\n\tNil           UUID // empty UUID, all zeros\n)\n\n// NewHash returns a new UUID derived from the hash of space concatenated with\n// data generated by h.  The hash should be at least 16 byte in length.  The\n// first 16 bytes of the hash are used to form the UUID.  The version of the\n// UUID will be the lower 4 bits of version.  NewHash is used to implement\n// NewMD5 and NewSHA1.\nfunc NewHash(h hash.Hash, space UUID, data []byte, version int) UUID {\n\th.Reset()\n\th.Write(space[:]) //nolint:errcheck\n\th.Write(data)     //nolint:errcheck\n\ts := h.Sum(nil)\n\tvar uuid UUID\n\tcopy(uuid[:], s)\n\tuuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4)\n\tuuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant\n\treturn uuid\n}\n\n// NewMD5 returns a new MD5 (Version 3) UUID based on the\n// supplied name space and data.  It is the same as calling:\n//\n//  NewHash(md5.New(), space, data, 3)\nfunc NewMD5(space UUID, data []byte) UUID {\n\treturn NewHash(md5.New(), space, data, 3)\n}\n\n// NewSHA1 returns a new SHA1 (Version 5) UUID based on the\n// supplied name space and data.  It is the same as calling:\n//\n//  NewHash(sha1.New(), space, data, 5)\nfunc NewSHA1(space UUID, data []byte) UUID {\n\treturn NewHash(sha1.New(), space, data, 5)\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/marshal.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport \"fmt\"\n\n// MarshalText implements encoding.TextMarshaler.\nfunc (uuid UUID) MarshalText() ([]byte, error) {\n\tvar js [36]byte\n\tencodeHex(js[:], uuid)\n\treturn js[:], nil\n}\n\n// UnmarshalText implements encoding.TextUnmarshaler.\nfunc (uuid *UUID) UnmarshalText(data []byte) error {\n\tid, err := ParseBytes(data)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*uuid = id\n\treturn nil\n}\n\n// MarshalBinary implements encoding.BinaryMarshaler.\nfunc (uuid UUID) MarshalBinary() ([]byte, error) {\n\treturn uuid[:], nil\n}\n\n// UnmarshalBinary implements encoding.BinaryUnmarshaler.\nfunc (uuid *UUID) UnmarshalBinary(data []byte) error {\n\tif len(data) != 16 {\n\t\treturn fmt.Errorf(\"invalid UUID (got %d bytes)\", len(data))\n\t}\n\tcopy(uuid[:], data)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/node.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"sync\"\n)\n\nvar (\n\tnodeMu sync.Mutex\n\tifname string  // name of interface being used\n\tnodeID [6]byte // hardware for version 1 UUIDs\n\tzeroID [6]byte // nodeID with only 0's\n)\n\n// NodeInterface returns the name of the interface from which the NodeID was\n// derived.  The interface \"user\" is returned if the NodeID was set by\n// SetNodeID.\nfunc NodeInterface() string {\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\treturn ifname\n}\n\n// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs.\n// If name is \"\" then the first usable interface found will be used or a random\n// Node ID will be generated.  If a named interface cannot be found then false\n// is returned.\n//\n// SetNodeInterface never fails when name is \"\".\nfunc SetNodeInterface(name string) bool {\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\treturn setNodeInterface(name)\n}\n\nfunc setNodeInterface(name string) bool {\n\tiname, addr := getHardwareInterface(name) // null implementation for js\n\tif iname != \"\" && addr != nil {\n\t\tifname = iname\n\t\tcopy(nodeID[:], addr)\n\t\treturn true\n\t}\n\n\t// We found no interfaces with a valid hardware address.  If name\n\t// does not specify a specific interface generate a random Node ID\n\t// (section 4.1.6)\n\tif name == \"\" {\n\t\tifname = \"random\"\n\t\trandomBits(nodeID[:])\n\t\treturn true\n\t}\n\treturn false\n}\n\n// NodeID returns a slice of a copy of the current Node ID, setting the Node ID\n// if not already set.\nfunc NodeID() []byte {\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\tif nodeID == zeroID {\n\t\tsetNodeInterface(\"\")\n\t}\n\tnid := nodeID\n\treturn nid[:]\n}\n\n// SetNodeID sets the Node ID to be used for Version 1 UUIDs.  The first 6 bytes\n// of id are used.  If id is less than 6 bytes then false is returned and the\n// Node ID is not set.\nfunc SetNodeID(id []byte) bool {\n\tif len(id) < 6 {\n\t\treturn false\n\t}\n\tdefer nodeMu.Unlock()\n\tnodeMu.Lock()\n\tcopy(nodeID[:], id)\n\tifname = \"user\"\n\treturn true\n}\n\n// NodeID returns the 6 byte node id encoded in uuid.  It returns nil if uuid is\n// not valid.  The NodeID is only well defined for version 1 and 2 UUIDs.\nfunc (uuid UUID) NodeID() []byte {\n\tvar node [6]byte\n\tcopy(node[:], uuid[10:])\n\treturn node[:]\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/node_js.go",
    "content": "// Copyright 2017 Google Inc.  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// +build js\n\npackage uuid\n\n// getHardwareInterface returns nil values for the JS version of the code.\n// This remvoves the \"net\" dependency, because it is not used in the browser.\n// Using the \"net\" library inflates the size of the transpiled JS code by 673k bytes.\nfunc getHardwareInterface(name string) (string, []byte) { return \"\", nil }\n"
  },
  {
    "path": "vendor/github.com/google/uuid/node_net.go",
    "content": "// Copyright 2017 Google Inc.  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// +build !js\n\npackage uuid\n\nimport \"net\"\n\nvar interfaces []net.Interface // cached list of interfaces\n\n// getHardwareInterface returns the name and hardware address of interface name.\n// If name is \"\" then the name and hardware address of one of the system's\n// interfaces is returned.  If no interfaces are found (name does not exist or\n// there are no interfaces) then \"\", nil is returned.\n//\n// Only addresses of at least 6 bytes are returned.\nfunc getHardwareInterface(name string) (string, []byte) {\n\tif interfaces == nil {\n\t\tvar err error\n\t\tinterfaces, err = net.Interfaces()\n\t\tif err != nil {\n\t\t\treturn \"\", nil\n\t\t}\n\t}\n\tfor _, ifs := range interfaces {\n\t\tif len(ifs.HardwareAddr) >= 6 && (name == \"\" || name == ifs.Name) {\n\t\t\treturn ifs.Name, ifs.HardwareAddr\n\t\t}\n\t}\n\treturn \"\", nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/null.go",
    "content": "// Copyright 2021 Google Inc.  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 uuid\n\nimport (\n\t\"bytes\"\n\t\"database/sql/driver\"\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nvar jsonNull = []byte(\"null\")\n\n// NullUUID represents a UUID that may be null.\n// NullUUID implements the SQL driver.Scanner interface so\n// it can be used as a scan destination:\n//\n//  var u uuid.NullUUID\n//  err := db.QueryRow(\"SELECT name FROM foo WHERE id=?\", id).Scan(&u)\n//  ...\n//  if u.Valid {\n//     // use u.UUID\n//  } else {\n//     // NULL value\n//  }\n//\ntype NullUUID struct {\n\tUUID  UUID\n\tValid bool // Valid is true if UUID is not NULL\n}\n\n// Scan implements the SQL driver.Scanner interface.\nfunc (nu *NullUUID) Scan(value interface{}) error {\n\tif value == nil {\n\t\tnu.UUID, nu.Valid = Nil, false\n\t\treturn nil\n\t}\n\n\terr := nu.UUID.Scan(value)\n\tif err != nil {\n\t\tnu.Valid = false\n\t\treturn err\n\t}\n\n\tnu.Valid = true\n\treturn nil\n}\n\n// Value implements the driver Valuer interface.\nfunc (nu NullUUID) Value() (driver.Value, error) {\n\tif !nu.Valid {\n\t\treturn nil, nil\n\t}\n\t// Delegate to UUID Value function\n\treturn nu.UUID.Value()\n}\n\n// MarshalBinary implements encoding.BinaryMarshaler.\nfunc (nu NullUUID) MarshalBinary() ([]byte, error) {\n\tif nu.Valid {\n\t\treturn nu.UUID[:], nil\n\t}\n\n\treturn []byte(nil), nil\n}\n\n// UnmarshalBinary implements encoding.BinaryUnmarshaler.\nfunc (nu *NullUUID) UnmarshalBinary(data []byte) error {\n\tif len(data) != 16 {\n\t\treturn fmt.Errorf(\"invalid UUID (got %d bytes)\", len(data))\n\t}\n\tcopy(nu.UUID[:], data)\n\tnu.Valid = true\n\treturn nil\n}\n\n// MarshalText implements encoding.TextMarshaler.\nfunc (nu NullUUID) MarshalText() ([]byte, error) {\n\tif nu.Valid {\n\t\treturn nu.UUID.MarshalText()\n\t}\n\n\treturn jsonNull, nil\n}\n\n// UnmarshalText implements encoding.TextUnmarshaler.\nfunc (nu *NullUUID) UnmarshalText(data []byte) error {\n\tid, err := ParseBytes(data)\n\tif err != nil {\n\t\tnu.Valid = false\n\t\treturn err\n\t}\n\tnu.UUID = id\n\tnu.Valid = true\n\treturn nil\n}\n\n// MarshalJSON implements json.Marshaler.\nfunc (nu NullUUID) MarshalJSON() ([]byte, error) {\n\tif nu.Valid {\n\t\treturn json.Marshal(nu.UUID)\n\t}\n\n\treturn jsonNull, nil\n}\n\n// UnmarshalJSON implements json.Unmarshaler.\nfunc (nu *NullUUID) UnmarshalJSON(data []byte) error {\n\tif bytes.Equal(data, jsonNull) {\n\t\t*nu = NullUUID{}\n\t\treturn nil // valid null UUID\n\t}\n\terr := json.Unmarshal(data, &nu.UUID)\n\tnu.Valid = err == nil\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/sql.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"database/sql/driver\"\n\t\"fmt\"\n)\n\n// Scan implements sql.Scanner so UUIDs can be read from databases transparently.\n// Currently, database types that map to string and []byte are supported. Please\n// consult database-specific driver documentation for matching types.\nfunc (uuid *UUID) Scan(src interface{}) error {\n\tswitch src := src.(type) {\n\tcase nil:\n\t\treturn nil\n\n\tcase string:\n\t\t// if an empty UUID comes from a table, we return a null UUID\n\t\tif src == \"\" {\n\t\t\treturn nil\n\t\t}\n\n\t\t// see Parse for required string format\n\t\tu, err := Parse(src)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Scan: %v\", err)\n\t\t}\n\n\t\t*uuid = u\n\n\tcase []byte:\n\t\t// if an empty UUID comes from a table, we return a null UUID\n\t\tif len(src) == 0 {\n\t\t\treturn nil\n\t\t}\n\n\t\t// assumes a simple slice of bytes if 16 bytes\n\t\t// otherwise attempts to parse\n\t\tif len(src) != 16 {\n\t\t\treturn uuid.Scan(string(src))\n\t\t}\n\t\tcopy((*uuid)[:], src)\n\n\tdefault:\n\t\treturn fmt.Errorf(\"Scan: unable to scan type %T into UUID\", src)\n\t}\n\n\treturn nil\n}\n\n// Value implements sql.Valuer so that UUIDs can be written to databases\n// transparently. Currently, UUIDs map to strings. Please consult\n// database-specific driver documentation for matching types.\nfunc (uuid UUID) Value() (driver.Value, error) {\n\treturn uuid.String(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/time.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"encoding/binary\"\n\t\"sync\"\n\t\"time\"\n)\n\n// A Time represents a time as the number of 100's of nanoseconds since 15 Oct\n// 1582.\ntype Time int64\n\nconst (\n\tlillian    = 2299160          // Julian day of 15 Oct 1582\n\tunix       = 2440587          // Julian day of 1 Jan 1970\n\tepoch      = unix - lillian   // Days between epochs\n\tg1582      = epoch * 86400    // seconds between epochs\n\tg1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs\n)\n\nvar (\n\ttimeMu   sync.Mutex\n\tlasttime uint64 // last time we returned\n\tclockSeq uint16 // clock sequence for this run\n\n\ttimeNow = time.Now // for testing\n)\n\n// UnixTime converts t the number of seconds and nanoseconds using the Unix\n// epoch of 1 Jan 1970.\nfunc (t Time) UnixTime() (sec, nsec int64) {\n\tsec = int64(t - g1582ns100)\n\tnsec = (sec % 10000000) * 100\n\tsec /= 10000000\n\treturn sec, nsec\n}\n\n// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and\n// clock sequence as well as adjusting the clock sequence as needed.  An error\n// is returned if the current time cannot be determined.\nfunc GetTime() (Time, uint16, error) {\n\tdefer timeMu.Unlock()\n\ttimeMu.Lock()\n\treturn getTime()\n}\n\nfunc getTime() (Time, uint16, error) {\n\tt := timeNow()\n\n\t// If we don't have a clock sequence already, set one.\n\tif clockSeq == 0 {\n\t\tsetClockSequence(-1)\n\t}\n\tnow := uint64(t.UnixNano()/100) + g1582ns100\n\n\t// If time has gone backwards with this clock sequence then we\n\t// increment the clock sequence\n\tif now <= lasttime {\n\t\tclockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000\n\t}\n\tlasttime = now\n\treturn Time(now), clockSeq, nil\n}\n\n// ClockSequence returns the current clock sequence, generating one if not\n// already set.  The clock sequence is only used for Version 1 UUIDs.\n//\n// The uuid package does not use global static storage for the clock sequence or\n// the last time a UUID was generated.  Unless SetClockSequence is used, a new\n// random clock sequence is generated the first time a clock sequence is\n// requested by ClockSequence, GetTime, or NewUUID.  (section 4.2.1.1)\nfunc ClockSequence() int {\n\tdefer timeMu.Unlock()\n\ttimeMu.Lock()\n\treturn clockSequence()\n}\n\nfunc clockSequence() int {\n\tif clockSeq == 0 {\n\t\tsetClockSequence(-1)\n\t}\n\treturn int(clockSeq & 0x3fff)\n}\n\n// SetClockSequence sets the clock sequence to the lower 14 bits of seq.  Setting to\n// -1 causes a new sequence to be generated.\nfunc SetClockSequence(seq int) {\n\tdefer timeMu.Unlock()\n\ttimeMu.Lock()\n\tsetClockSequence(seq)\n}\n\nfunc setClockSequence(seq int) {\n\tif seq == -1 {\n\t\tvar b [2]byte\n\t\trandomBits(b[:]) // clock sequence\n\t\tseq = int(b[0])<<8 | int(b[1])\n\t}\n\toldSeq := clockSeq\n\tclockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant\n\tif oldSeq != clockSeq {\n\t\tlasttime = 0\n\t}\n}\n\n// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in\n// uuid.  The time is only defined for version 1 and 2 UUIDs.\nfunc (uuid UUID) Time() Time {\n\ttime := int64(binary.BigEndian.Uint32(uuid[0:4]))\n\ttime |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32\n\ttime |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48\n\treturn Time(time)\n}\n\n// ClockSequence returns the clock sequence encoded in uuid.\n// The clock sequence is only well defined for version 1 and 2 UUIDs.\nfunc (uuid UUID) ClockSequence() int {\n\treturn int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/util.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"io\"\n)\n\n// randomBits completely fills slice b with random data.\nfunc randomBits(b []byte) {\n\tif _, err := io.ReadFull(rander, b); err != nil {\n\t\tpanic(err.Error()) // rand should never fail\n\t}\n}\n\n// xvalues returns the value of a byte as a hexadecimal digit or 255.\nvar xvalues = [256]byte{\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,\n\t255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n\t255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,\n}\n\n// xtob converts hex characters x1 and x2 into a byte.\nfunc xtob(x1, x2 byte) (byte, bool) {\n\tb1 := xvalues[x1]\n\tb2 := xvalues[x2]\n\treturn (b1 << 4) | b2, b1 != 255 && b2 != 255\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/uuid.go",
    "content": "// Copyright 2018 Google Inc.  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 uuid\n\nimport (\n\t\"bytes\"\n\t\"crypto/rand\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC\n// 4122.\ntype UUID [16]byte\n\n// A Version represents a UUID's version.\ntype Version byte\n\n// A Variant represents a UUID's variant.\ntype Variant byte\n\n// Constants returned by Variant.\nconst (\n\tInvalid   = Variant(iota) // Invalid UUID\n\tRFC4122                   // The variant specified in RFC4122\n\tReserved                  // Reserved, NCS backward compatibility.\n\tMicrosoft                 // Reserved, Microsoft Corporation backward compatibility.\n\tFuture                    // Reserved for future definition.\n)\n\nconst randPoolSize = 16 * 16\n\nvar (\n\trander      = rand.Reader // random function\n\tpoolEnabled = false\n\tpoolMu      sync.Mutex\n\tpoolPos     = randPoolSize     // protected with poolMu\n\tpool        [randPoolSize]byte // protected with poolMu\n)\n\ntype invalidLengthError struct{ len int }\n\nfunc (err invalidLengthError) Error() string {\n\treturn fmt.Sprintf(\"invalid UUID length: %d\", err.len)\n}\n\n// IsInvalidLengthError is matcher function for custom error invalidLengthError\nfunc IsInvalidLengthError(err error) bool {\n\t_, ok := err.(invalidLengthError)\n\treturn ok\n}\n\n// Parse decodes s into a UUID or returns an error.  Both the standard UUID\n// forms of xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and\n// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded as well as the\n// Microsoft encoding {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} and the raw hex\n// encoding: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.\nfunc Parse(s string) (UUID, error) {\n\tvar uuid UUID\n\tswitch len(s) {\n\t// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tcase 36:\n\n\t// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tcase 36 + 9:\n\t\tif strings.ToLower(s[:9]) != \"urn:uuid:\" {\n\t\t\treturn uuid, fmt.Errorf(\"invalid urn prefix: %q\", s[:9])\n\t\t}\n\t\ts = s[9:]\n\n\t// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\n\tcase 36 + 2:\n\t\ts = s[1:]\n\n\t// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\tcase 32:\n\t\tvar ok bool\n\t\tfor i := range uuid {\n\t\t\tuuid[i], ok = xtob(s[i*2], s[i*2+1])\n\t\t\tif !ok {\n\t\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t\t}\n\t\t}\n\t\treturn uuid, nil\n\tdefault:\n\t\treturn uuid, invalidLengthError{len(s)}\n\t}\n\t// s is now at least 36 bytes long\n\t// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tif s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {\n\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t}\n\tfor i, x := range [16]int{\n\t\t0, 2, 4, 6,\n\t\t9, 11,\n\t\t14, 16,\n\t\t19, 21,\n\t\t24, 26, 28, 30, 32, 34} {\n\t\tv, ok := xtob(s[x], s[x+1])\n\t\tif !ok {\n\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t}\n\t\tuuid[i] = v\n\t}\n\treturn uuid, nil\n}\n\n// ParseBytes is like Parse, except it parses a byte slice instead of a string.\nfunc ParseBytes(b []byte) (UUID, error) {\n\tvar uuid UUID\n\tswitch len(b) {\n\tcase 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tcase 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\t\tif !bytes.Equal(bytes.ToLower(b[:9]), []byte(\"urn:uuid:\")) {\n\t\t\treturn uuid, fmt.Errorf(\"invalid urn prefix: %q\", b[:9])\n\t\t}\n\t\tb = b[9:]\n\tcase 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\n\t\tb = b[1:]\n\tcase 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n\t\tvar ok bool\n\t\tfor i := 0; i < 32; i += 2 {\n\t\t\tuuid[i/2], ok = xtob(b[i], b[i+1])\n\t\t\tif !ok {\n\t\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t\t}\n\t\t}\n\t\treturn uuid, nil\n\tdefault:\n\t\treturn uuid, invalidLengthError{len(b)}\n\t}\n\t// s is now at least 36 bytes long\n\t// it must be of the form  xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\tif b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' {\n\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t}\n\tfor i, x := range [16]int{\n\t\t0, 2, 4, 6,\n\t\t9, 11,\n\t\t14, 16,\n\t\t19, 21,\n\t\t24, 26, 28, 30, 32, 34} {\n\t\tv, ok := xtob(b[x], b[x+1])\n\t\tif !ok {\n\t\t\treturn uuid, errors.New(\"invalid UUID format\")\n\t\t}\n\t\tuuid[i] = v\n\t}\n\treturn uuid, nil\n}\n\n// MustParse is like Parse but panics if the string cannot be parsed.\n// It simplifies safe initialization of global variables holding compiled UUIDs.\nfunc MustParse(s string) UUID {\n\tuuid, err := Parse(s)\n\tif err != nil {\n\t\tpanic(`uuid: Parse(` + s + `): ` + err.Error())\n\t}\n\treturn uuid\n}\n\n// FromBytes creates a new UUID from a byte slice. Returns an error if the slice\n// does not have a length of 16. The bytes are copied from the slice.\nfunc FromBytes(b []byte) (uuid UUID, err error) {\n\terr = uuid.UnmarshalBinary(b)\n\treturn uuid, err\n}\n\n// Must returns uuid if err is nil and panics otherwise.\nfunc Must(uuid UUID, err error) UUID {\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn uuid\n}\n\n// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n// , or \"\" if uuid is invalid.\nfunc (uuid UUID) String() string {\n\tvar buf [36]byte\n\tencodeHex(buf[:], uuid)\n\treturn string(buf[:])\n}\n\n// URN returns the RFC 2141 URN form of uuid,\n// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,  or \"\" if uuid is invalid.\nfunc (uuid UUID) URN() string {\n\tvar buf [36 + 9]byte\n\tcopy(buf[:], \"urn:uuid:\")\n\tencodeHex(buf[9:], uuid)\n\treturn string(buf[:])\n}\n\nfunc encodeHex(dst []byte, uuid UUID) {\n\thex.Encode(dst, uuid[:4])\n\tdst[8] = '-'\n\thex.Encode(dst[9:13], uuid[4:6])\n\tdst[13] = '-'\n\thex.Encode(dst[14:18], uuid[6:8])\n\tdst[18] = '-'\n\thex.Encode(dst[19:23], uuid[8:10])\n\tdst[23] = '-'\n\thex.Encode(dst[24:], uuid[10:])\n}\n\n// Variant returns the variant encoded in uuid.\nfunc (uuid UUID) Variant() Variant {\n\tswitch {\n\tcase (uuid[8] & 0xc0) == 0x80:\n\t\treturn RFC4122\n\tcase (uuid[8] & 0xe0) == 0xc0:\n\t\treturn Microsoft\n\tcase (uuid[8] & 0xe0) == 0xe0:\n\t\treturn Future\n\tdefault:\n\t\treturn Reserved\n\t}\n}\n\n// Version returns the version of uuid.\nfunc (uuid UUID) Version() Version {\n\treturn Version(uuid[6] >> 4)\n}\n\nfunc (v Version) String() string {\n\tif v > 15 {\n\t\treturn fmt.Sprintf(\"BAD_VERSION_%d\", v)\n\t}\n\treturn fmt.Sprintf(\"VERSION_%d\", v)\n}\n\nfunc (v Variant) String() string {\n\tswitch v {\n\tcase RFC4122:\n\t\treturn \"RFC4122\"\n\tcase Reserved:\n\t\treturn \"Reserved\"\n\tcase Microsoft:\n\t\treturn \"Microsoft\"\n\tcase Future:\n\t\treturn \"Future\"\n\tcase Invalid:\n\t\treturn \"Invalid\"\n\t}\n\treturn fmt.Sprintf(\"BadVariant%d\", int(v))\n}\n\n// SetRand sets the random number generator to r, which implements io.Reader.\n// If r.Read returns an error when the package requests random data then\n// a panic will be issued.\n//\n// Calling SetRand with nil sets the random number generator to the default\n// generator.\nfunc SetRand(r io.Reader) {\n\tif r == nil {\n\t\trander = rand.Reader\n\t\treturn\n\t}\n\trander = r\n}\n\n// EnableRandPool enables internal randomness pool used for Random\n// (Version 4) UUID generation. The pool contains random bytes read from\n// the random number generator on demand in batches. Enabling the pool\n// may improve the UUID generation throughput significantly.\n//\n// Since the pool is stored on the Go heap, this feature may be a bad fit\n// for security sensitive applications.\n//\n// Both EnableRandPool and DisableRandPool are not thread-safe and should\n// only be called when there is no possibility that New or any other\n// UUID Version 4 generation function will be called concurrently.\nfunc EnableRandPool() {\n\tpoolEnabled = true\n}\n\n// DisableRandPool disables the randomness pool if it was previously\n// enabled with EnableRandPool.\n//\n// Both EnableRandPool and DisableRandPool are not thread-safe and should\n// only be called when there is no possibility that New or any other\n// UUID Version 4 generation function will be called concurrently.\nfunc DisableRandPool() {\n\tpoolEnabled = false\n\tdefer poolMu.Unlock()\n\tpoolMu.Lock()\n\tpoolPos = randPoolSize\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/version1.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport (\n\t\"encoding/binary\"\n)\n\n// NewUUID returns a Version 1 UUID based on the current NodeID and clock\n// sequence, and the current time.  If the NodeID has not been set by SetNodeID\n// or SetNodeInterface then it will be set automatically.  If the NodeID cannot\n// be set NewUUID returns nil.  If clock sequence has not been set by\n// SetClockSequence then it will be set automatically.  If GetTime fails to\n// return the current NewUUID returns nil and an error.\n//\n// In most cases, New should be used.\nfunc NewUUID() (UUID, error) {\n\tvar uuid UUID\n\tnow, seq, err := GetTime()\n\tif err != nil {\n\t\treturn uuid, err\n\t}\n\n\ttimeLow := uint32(now & 0xffffffff)\n\ttimeMid := uint16((now >> 32) & 0xffff)\n\ttimeHi := uint16((now >> 48) & 0x0fff)\n\ttimeHi |= 0x1000 // Version 1\n\n\tbinary.BigEndian.PutUint32(uuid[0:], timeLow)\n\tbinary.BigEndian.PutUint16(uuid[4:], timeMid)\n\tbinary.BigEndian.PutUint16(uuid[6:], timeHi)\n\tbinary.BigEndian.PutUint16(uuid[8:], seq)\n\n\tnodeMu.Lock()\n\tif nodeID == zeroID {\n\t\tsetNodeInterface(\"\")\n\t}\n\tcopy(uuid[10:], nodeID[:])\n\tnodeMu.Unlock()\n\n\treturn uuid, nil\n}\n"
  },
  {
    "path": "vendor/github.com/google/uuid/version4.go",
    "content": "// Copyright 2016 Google Inc.  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 uuid\n\nimport \"io\"\n\n// New creates a new random UUID or panics.  New is equivalent to\n// the expression\n//\n//    uuid.Must(uuid.NewRandom())\nfunc New() UUID {\n\treturn Must(NewRandom())\n}\n\n// NewString creates a new random UUID and returns it as a string or panics.\n// NewString is equivalent to the expression\n//\n//    uuid.New().String()\nfunc NewString() string {\n\treturn Must(NewRandom()).String()\n}\n\n// NewRandom returns a Random (Version 4) UUID.\n//\n// The strength of the UUIDs is based on the strength of the crypto/rand\n// package.\n//\n// Uses the randomness pool if it was enabled with EnableRandPool.\n//\n// A note about uniqueness derived from the UUID Wikipedia entry:\n//\n//  Randomly generated UUIDs have 122 random bits.  One's annual risk of being\n//  hit by a meteorite is estimated to be one chance in 17 billion, that\n//  means the probability is about 0.00000000006 (6 × 10−11),\n//  equivalent to the odds of creating a few tens of trillions of UUIDs in a\n//  year and having one duplicate.\nfunc NewRandom() (UUID, error) {\n\tif !poolEnabled {\n\t\treturn NewRandomFromReader(rander)\n\t}\n\treturn newRandomFromPool()\n}\n\n// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader.\nfunc NewRandomFromReader(r io.Reader) (UUID, error) {\n\tvar uuid UUID\n\t_, err := io.ReadFull(r, uuid[:])\n\tif err != nil {\n\t\treturn Nil, err\n\t}\n\tuuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4\n\tuuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10\n\treturn uuid, nil\n}\n\nfunc newRandomFromPool() (UUID, error) {\n\tvar uuid UUID\n\tpoolMu.Lock()\n\tif poolPos == randPoolSize {\n\t\t_, err := io.ReadFull(rander, pool[:])\n\t\tif err != nil {\n\t\t\tpoolMu.Unlock()\n\t\t\treturn Nil, err\n\t\t}\n\t\tpoolPos = 0\n\t}\n\tcopy(uuid[:], pool[poolPos:(poolPos+16)])\n\tpoolPos += 16\n\tpoolMu.Unlock()\n\n\tuuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4\n\tuuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10\n\treturn uuid, nil\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n\n.idea/\n*.iml\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/AUTHORS",
    "content": "# This is the official list of Gorilla WebSocket authors for copyright\n# purposes.\n#\n# Please keep the list sorted.\n\nGary Burd <gary@beagledreams.com>\nGoogle LLC (https://opensource.google.com/)\nJoachim Bauch <mail@joachim-bauch.de>\n\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/LICENSE",
    "content": "Copyright (c) 2013 The Gorilla WebSocket 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 met:\n\n  Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n  Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (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": "vendor/github.com/gorilla/websocket/README.md",
    "content": "# Gorilla WebSocket\n\n[![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket)\n[![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket)\n\nGorilla WebSocket is a [Go](http://golang.org/) implementation of the\n[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.\n\n### Documentation\n\n* [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc)\n* [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat)\n* [Command example](https://github.com/gorilla/websocket/tree/master/examples/command)\n* [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo)\n* [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch)\n\n### Status\n\nThe Gorilla WebSocket package provides a complete and tested implementation of\nthe [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The\npackage API is stable.\n\n### Installation\n\n    go get github.com/gorilla/websocket\n\n### Protocol Compliance\n\nThe Gorilla WebSocket package passes the server tests in the [Autobahn Test\nSuite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn\nsubdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).\n\n### Gorilla WebSocket compared with other packages\n\n<table>\n<tr>\n<th></th>\n<th><a href=\"http://godoc.org/github.com/gorilla/websocket\">github.com/gorilla</a></th>\n<th><a href=\"http://godoc.org/golang.org/x/net/websocket\">golang.org/x/net</a></th>\n</tr>\n<tr>\n<tr><td colspan=\"3\"><a href=\"http://tools.ietf.org/html/rfc6455\">RFC 6455</a> Features</td></tr>\n<tr><td>Passes <a href=\"https://github.com/crossbario/autobahn-testsuite\">Autobahn Test Suite</a></td><td><a href=\"https://github.com/gorilla/websocket/tree/master/examples/autobahn\">Yes</a></td><td>No</td></tr>\n<tr><td>Receive <a href=\"https://tools.ietf.org/html/rfc6455#section-5.4\">fragmented</a> message<td>Yes</td><td><a href=\"https://code.google.com/p/go/issues/detail?id=7632\">No</a>, see note 1</td></tr>\n<tr><td>Send <a href=\"https://tools.ietf.org/html/rfc6455#section-5.5.1\">close</a> message</td><td><a href=\"http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages\">Yes</a></td><td><a href=\"https://code.google.com/p/go/issues/detail?id=4588\">No</a></td></tr>\n<tr><td>Send <a href=\"https://tools.ietf.org/html/rfc6455#section-5.5.2\">pings</a> and receive <a href=\"https://tools.ietf.org/html/rfc6455#section-5.5.3\">pongs</a></td><td><a href=\"http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages\">Yes</a></td><td>No</td></tr>\n<tr><td>Get the <a href=\"https://tools.ietf.org/html/rfc6455#section-5.6\">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>\n<tr><td colspan=\"3\">Other Features</tr></td>\n<tr><td><a href=\"https://tools.ietf.org/html/rfc7692\">Compression Extensions</a></td><td>Experimental</td><td>No</td></tr>\n<tr><td>Read message using io.Reader</td><td><a href=\"http://godoc.org/github.com/gorilla/websocket#Conn.NextReader\">Yes</a></td><td>No, see note 3</td></tr>\n<tr><td>Write message using io.WriteCloser</td><td><a href=\"http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter\">Yes</a></td><td>No, see note 3</td></tr>\n</table>\n\nNotes:\n\n1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).\n2. The application can get the type of a received data message by implementing\n   a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)\n   function.\n3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.\n  Read returns when the input buffer is full or a frame boundary is\n  encountered. Each call to Write sends a single frame message. The Gorilla\n  io.Reader and io.WriteCloser operate on a single WebSocket message.\n\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/client.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n)\n\n// ErrBadHandshake is returned when the server response to opening handshake is\n// invalid.\nvar ErrBadHandshake = errors.New(\"websocket: bad handshake\")\n\nvar errInvalidCompression = errors.New(\"websocket: invalid compression negotiation\")\n\n// NewClient creates a new client connection using the given net connection.\n// The URL u specifies the host and request URI. Use requestHeader to specify\n// the origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies\n// (Cookie). Use the response.Header to get the selected subprotocol\n// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).\n//\n// If the WebSocket handshake fails, ErrBadHandshake is returned along with a\n// non-nil *http.Response so that callers can handle redirects, authentication,\n// etc.\n//\n// Deprecated: Use Dialer instead.\nfunc NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufSize, writeBufSize int) (c *Conn, response *http.Response, err error) {\n\td := Dialer{\n\t\tReadBufferSize:  readBufSize,\n\t\tWriteBufferSize: writeBufSize,\n\t\tNetDial: func(net, addr string) (net.Conn, error) {\n\t\t\treturn netConn, nil\n\t\t},\n\t}\n\treturn d.Dial(u.String(), requestHeader)\n}\n\n// A Dialer contains options for connecting to WebSocket server.\ntype Dialer struct {\n\t// NetDial specifies the dial function for creating TCP connections. If\n\t// NetDial is nil, net.Dial is used.\n\tNetDial func(network, addr string) (net.Conn, error)\n\n\t// NetDialContext specifies the dial function for creating TCP connections. If\n\t// NetDialContext is nil, net.DialContext is used.\n\tNetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)\n\n\t// Proxy specifies a function to return a proxy for a given\n\t// Request. If the function returns a non-nil error, the\n\t// request is aborted with the provided error.\n\t// If Proxy is nil or returns a nil *URL, no proxy is used.\n\tProxy func(*http.Request) (*url.URL, error)\n\n\t// TLSClientConfig specifies the TLS configuration to use with tls.Client.\n\t// If nil, the default configuration is used.\n\tTLSClientConfig *tls.Config\n\n\t// HandshakeTimeout specifies the duration for the handshake to complete.\n\tHandshakeTimeout time.Duration\n\n\t// ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer\n\t// size is zero, then a useful default size is used. The I/O buffer sizes\n\t// do not limit the size of the messages that can be sent or received.\n\tReadBufferSize, WriteBufferSize int\n\n\t// WriteBufferPool is a pool of buffers for write operations. If the value\n\t// is not set, then write buffers are allocated to the connection for the\n\t// lifetime of the connection.\n\t//\n\t// A pool is most useful when the application has a modest volume of writes\n\t// across a large number of connections.\n\t//\n\t// Applications should use a single pool for each unique value of\n\t// WriteBufferSize.\n\tWriteBufferPool BufferPool\n\n\t// Subprotocols specifies the client's requested subprotocols.\n\tSubprotocols []string\n\n\t// EnableCompression specifies if the client should attempt to negotiate\n\t// per message compression (RFC 7692). Setting this value to true does not\n\t// guarantee that compression will be supported. Currently only \"no context\n\t// takeover\" modes are supported.\n\tEnableCompression bool\n\n\t// Jar specifies the cookie jar.\n\t// If Jar is nil, cookies are not sent in requests and ignored\n\t// in responses.\n\tJar http.CookieJar\n}\n\n// Dial creates a new client connection by calling DialContext with a background context.\nfunc (d *Dialer) Dial(urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {\n\treturn d.DialContext(context.Background(), urlStr, requestHeader)\n}\n\nvar errMalformedURL = errors.New(\"malformed ws or wss URL\")\n\nfunc hostPortNoPort(u *url.URL) (hostPort, hostNoPort string) {\n\thostPort = u.Host\n\thostNoPort = u.Host\n\tif i := strings.LastIndex(u.Host, \":\"); i > strings.LastIndex(u.Host, \"]\") {\n\t\thostNoPort = hostNoPort[:i]\n\t} else {\n\t\tswitch u.Scheme {\n\t\tcase \"wss\":\n\t\t\thostPort += \":443\"\n\t\tcase \"https\":\n\t\t\thostPort += \":443\"\n\t\tdefault:\n\t\t\thostPort += \":80\"\n\t\t}\n\t}\n\treturn hostPort, hostNoPort\n}\n\n// DefaultDialer is a dialer with all fields set to the default values.\nvar DefaultDialer = &Dialer{\n\tProxy:            http.ProxyFromEnvironment,\n\tHandshakeTimeout: 45 * time.Second,\n}\n\n// nilDialer is dialer to use when receiver is nil.\nvar nilDialer = *DefaultDialer\n\n// DialContext creates a new client connection. Use requestHeader to specify the\n// origin (Origin), subprotocols (Sec-WebSocket-Protocol) and cookies (Cookie).\n// Use the response.Header to get the selected subprotocol\n// (Sec-WebSocket-Protocol) and cookies (Set-Cookie).\n//\n// The context will be used in the request and in the Dialer.\n//\n// If the WebSocket handshake fails, ErrBadHandshake is returned along with a\n// non-nil *http.Response so that callers can handle redirects, authentication,\n// etcetera. The response body may not contain the entire response and does not\n// need to be closed by the application.\nfunc (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader http.Header) (*Conn, *http.Response, error) {\n\tif d == nil {\n\t\td = &nilDialer\n\t}\n\n\tchallengeKey, err := generateChallengeKey()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tu, err := url.Parse(urlStr)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tswitch u.Scheme {\n\tcase \"ws\":\n\t\tu.Scheme = \"http\"\n\tcase \"wss\":\n\t\tu.Scheme = \"https\"\n\tdefault:\n\t\treturn nil, nil, errMalformedURL\n\t}\n\n\tif u.User != nil {\n\t\t// User name and password are not allowed in websocket URIs.\n\t\treturn nil, nil, errMalformedURL\n\t}\n\n\treq := &http.Request{\n\t\tMethod:     \"GET\",\n\t\tURL:        u,\n\t\tProto:      \"HTTP/1.1\",\n\t\tProtoMajor: 1,\n\t\tProtoMinor: 1,\n\t\tHeader:     make(http.Header),\n\t\tHost:       u.Host,\n\t}\n\treq = req.WithContext(ctx)\n\n\t// Set the cookies present in the cookie jar of the dialer\n\tif d.Jar != nil {\n\t\tfor _, cookie := range d.Jar.Cookies(u) {\n\t\t\treq.AddCookie(cookie)\n\t\t}\n\t}\n\n\t// Set the request headers using the capitalization for names and values in\n\t// RFC examples. Although the capitalization shouldn't matter, there are\n\t// servers that depend on it. The Header.Set method is not used because the\n\t// method canonicalizes the header names.\n\treq.Header[\"Upgrade\"] = []string{\"websocket\"}\n\treq.Header[\"Connection\"] = []string{\"Upgrade\"}\n\treq.Header[\"Sec-WebSocket-Key\"] = []string{challengeKey}\n\treq.Header[\"Sec-WebSocket-Version\"] = []string{\"13\"}\n\tif len(d.Subprotocols) > 0 {\n\t\treq.Header[\"Sec-WebSocket-Protocol\"] = []string{strings.Join(d.Subprotocols, \", \")}\n\t}\n\tfor k, vs := range requestHeader {\n\t\tswitch {\n\t\tcase k == \"Host\":\n\t\t\tif len(vs) > 0 {\n\t\t\t\treq.Host = vs[0]\n\t\t\t}\n\t\tcase k == \"Upgrade\" ||\n\t\t\tk == \"Connection\" ||\n\t\t\tk == \"Sec-Websocket-Key\" ||\n\t\t\tk == \"Sec-Websocket-Version\" ||\n\t\t\tk == \"Sec-Websocket-Extensions\" ||\n\t\t\t(k == \"Sec-Websocket-Protocol\" && len(d.Subprotocols) > 0):\n\t\t\treturn nil, nil, errors.New(\"websocket: duplicate header not allowed: \" + k)\n\t\tcase k == \"Sec-Websocket-Protocol\":\n\t\t\treq.Header[\"Sec-WebSocket-Protocol\"] = vs\n\t\tdefault:\n\t\t\treq.Header[k] = vs\n\t\t}\n\t}\n\n\tif d.EnableCompression {\n\t\treq.Header[\"Sec-WebSocket-Extensions\"] = []string{\"permessage-deflate; server_no_context_takeover; client_no_context_takeover\"}\n\t}\n\n\tif d.HandshakeTimeout != 0 {\n\t\tvar cancel func()\n\t\tctx, cancel = context.WithTimeout(ctx, d.HandshakeTimeout)\n\t\tdefer cancel()\n\t}\n\n\t// Get network dial function.\n\tvar netDial func(network, add string) (net.Conn, error)\n\n\tif d.NetDialContext != nil {\n\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\treturn d.NetDialContext(ctx, network, addr)\n\t\t}\n\t} else if d.NetDial != nil {\n\t\tnetDial = d.NetDial\n\t} else {\n\t\tnetDialer := &net.Dialer{}\n\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\treturn netDialer.DialContext(ctx, network, addr)\n\t\t}\n\t}\n\n\t// If needed, wrap the dial function to set the connection deadline.\n\tif deadline, ok := ctx.Deadline(); ok {\n\t\tforwardDial := netDial\n\t\tnetDial = func(network, addr string) (net.Conn, error) {\n\t\t\tc, err := forwardDial(network, addr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\terr = c.SetDeadline(deadline)\n\t\t\tif err != nil {\n\t\t\t\tc.Close()\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn c, nil\n\t\t}\n\t}\n\n\t// If needed, wrap the dial function to connect through a proxy.\n\tif d.Proxy != nil {\n\t\tproxyURL, err := d.Proxy(req)\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tif proxyURL != nil {\n\t\t\tdialer, err := proxy_FromURL(proxyURL, netDialerFunc(netDial))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\t\tnetDial = dialer.Dial\n\t\t}\n\t}\n\n\thostPort, hostNoPort := hostPortNoPort(u)\n\ttrace := httptrace.ContextClientTrace(ctx)\n\tif trace != nil && trace.GetConn != nil {\n\t\ttrace.GetConn(hostPort)\n\t}\n\n\tnetConn, err := netDial(\"tcp\", hostPort)\n\tif trace != nil && trace.GotConn != nil {\n\t\ttrace.GotConn(httptrace.GotConnInfo{\n\t\t\tConn: netConn,\n\t\t})\n\t}\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tdefer func() {\n\t\tif netConn != nil {\n\t\t\tnetConn.Close()\n\t\t}\n\t}()\n\n\tif u.Scheme == \"https\" {\n\t\tcfg := cloneTLSConfig(d.TLSClientConfig)\n\t\tif cfg.ServerName == \"\" {\n\t\t\tcfg.ServerName = hostNoPort\n\t\t}\n\t\ttlsConn := tls.Client(netConn, cfg)\n\t\tnetConn = tlsConn\n\n\t\tvar err error\n\t\tif trace != nil {\n\t\t\terr = doHandshakeWithTrace(trace, tlsConn, cfg)\n\t\t} else {\n\t\t\terr = doHandshake(tlsConn, cfg)\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, nil, err\n\t\t}\n\t}\n\n\tconn := newConn(netConn, false, d.ReadBufferSize, d.WriteBufferSize, d.WriteBufferPool, nil, nil)\n\n\tif err := req.Write(netConn); err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif trace != nil && trace.GotFirstResponseByte != nil {\n\t\tif peek, err := conn.br.Peek(1); err == nil && len(peek) == 1 {\n\t\t\ttrace.GotFirstResponseByte()\n\t\t}\n\t}\n\n\tresp, err := http.ReadResponse(conn.br, req)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tif d.Jar != nil {\n\t\tif rc := resp.Cookies(); len(rc) > 0 {\n\t\t\td.Jar.SetCookies(u, rc)\n\t\t}\n\t}\n\n\tif resp.StatusCode != 101 ||\n\t\t!strings.EqualFold(resp.Header.Get(\"Upgrade\"), \"websocket\") ||\n\t\t!strings.EqualFold(resp.Header.Get(\"Connection\"), \"upgrade\") ||\n\t\tresp.Header.Get(\"Sec-Websocket-Accept\") != computeAcceptKey(challengeKey) {\n\t\t// Before closing the network connection on return from this\n\t\t// function, slurp up some of the response to aid application\n\t\t// debugging.\n\t\tbuf := make([]byte, 1024)\n\t\tn, _ := io.ReadFull(resp.Body, buf)\n\t\tresp.Body = ioutil.NopCloser(bytes.NewReader(buf[:n]))\n\t\treturn nil, resp, ErrBadHandshake\n\t}\n\n\tfor _, ext := range parseExtensions(resp.Header) {\n\t\tif ext[\"\"] != \"permessage-deflate\" {\n\t\t\tcontinue\n\t\t}\n\t\t_, snct := ext[\"server_no_context_takeover\"]\n\t\t_, cnct := ext[\"client_no_context_takeover\"]\n\t\tif !snct || !cnct {\n\t\t\treturn nil, resp, errInvalidCompression\n\t\t}\n\t\tconn.newCompressionWriter = compressNoContextTakeover\n\t\tconn.newDecompressionReader = decompressNoContextTakeover\n\t\tbreak\n\t}\n\n\tresp.Body = ioutil.NopCloser(bytes.NewReader([]byte{}))\n\tconn.subprotocol = resp.Header.Get(\"Sec-Websocket-Protocol\")\n\n\tnetConn.SetDeadline(time.Time{})\n\tnetConn = nil // to avoid close in defer.\n\treturn conn, resp, nil\n}\n\nfunc doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error {\n\tif err := tlsConn.Handshake(); err != nil {\n\t\treturn err\n\t}\n\tif !cfg.InsecureSkipVerify {\n\t\tif err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/client_clone.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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// +build go1.8\n\npackage websocket\n\nimport \"crypto/tls\"\n\nfunc cloneTLSConfig(cfg *tls.Config) *tls.Config {\n\tif cfg == nil {\n\t\treturn &tls.Config{}\n\t}\n\treturn cfg.Clone()\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/client_clone_legacy.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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// +build !go1.8\n\npackage websocket\n\nimport \"crypto/tls\"\n\n// cloneTLSConfig clones all public fields except the fields\n// SessionTicketsDisabled and SessionTicketKey. This avoids copying the\n// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a\n// config in active use.\nfunc cloneTLSConfig(cfg *tls.Config) *tls.Config {\n\tif cfg == nil {\n\t\treturn &tls.Config{}\n\t}\n\treturn &tls.Config{\n\t\tRand:                     cfg.Rand,\n\t\tTime:                     cfg.Time,\n\t\tCertificates:             cfg.Certificates,\n\t\tNameToCertificate:        cfg.NameToCertificate,\n\t\tGetCertificate:           cfg.GetCertificate,\n\t\tRootCAs:                  cfg.RootCAs,\n\t\tNextProtos:               cfg.NextProtos,\n\t\tServerName:               cfg.ServerName,\n\t\tClientAuth:               cfg.ClientAuth,\n\t\tClientCAs:                cfg.ClientCAs,\n\t\tInsecureSkipVerify:       cfg.InsecureSkipVerify,\n\t\tCipherSuites:             cfg.CipherSuites,\n\t\tPreferServerCipherSuites: cfg.PreferServerCipherSuites,\n\t\tClientSessionCache:       cfg.ClientSessionCache,\n\t\tMinVersion:               cfg.MinVersion,\n\t\tMaxVersion:               cfg.MaxVersion,\n\t\tCurvePreferences:         cfg.CurvePreferences,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/compression.go",
    "content": "// Copyright 2017 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"compress/flate\"\n\t\"errors\"\n\t\"io\"\n\t\"strings\"\n\t\"sync\"\n)\n\nconst (\n\tminCompressionLevel     = -2 // flate.HuffmanOnly not defined in Go < 1.6\n\tmaxCompressionLevel     = flate.BestCompression\n\tdefaultCompressionLevel = 1\n)\n\nvar (\n\tflateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool\n\tflateReaderPool  = sync.Pool{New: func() interface{} {\n\t\treturn flate.NewReader(nil)\n\t}}\n)\n\nfunc decompressNoContextTakeover(r io.Reader) io.ReadCloser {\n\tconst tail =\n\t// Add four bytes as specified in RFC\n\t\"\\x00\\x00\\xff\\xff\" +\n\t\t// Add final block to squelch unexpected EOF error from flate reader.\n\t\t\"\\x01\\x00\\x00\\xff\\xff\"\n\n\tfr, _ := flateReaderPool.Get().(io.ReadCloser)\n\tfr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil)\n\treturn &flateReadWrapper{fr}\n}\n\nfunc isValidCompressionLevel(level int) bool {\n\treturn minCompressionLevel <= level && level <= maxCompressionLevel\n}\n\nfunc compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser {\n\tp := &flateWriterPools[level-minCompressionLevel]\n\ttw := &truncWriter{w: w}\n\tfw, _ := p.Get().(*flate.Writer)\n\tif fw == nil {\n\t\tfw, _ = flate.NewWriter(tw, level)\n\t} else {\n\t\tfw.Reset(tw)\n\t}\n\treturn &flateWriteWrapper{fw: fw, tw: tw, p: p}\n}\n\n// truncWriter is an io.Writer that writes all but the last four bytes of the\n// stream to another io.Writer.\ntype truncWriter struct {\n\tw io.WriteCloser\n\tn int\n\tp [4]byte\n}\n\nfunc (w *truncWriter) Write(p []byte) (int, error) {\n\tn := 0\n\n\t// fill buffer first for simplicity.\n\tif w.n < len(w.p) {\n\t\tn = copy(w.p[w.n:], p)\n\t\tp = p[n:]\n\t\tw.n += n\n\t\tif len(p) == 0 {\n\t\t\treturn n, nil\n\t\t}\n\t}\n\n\tm := len(p)\n\tif m > len(w.p) {\n\t\tm = len(w.p)\n\t}\n\n\tif nn, err := w.w.Write(w.p[:m]); err != nil {\n\t\treturn n + nn, err\n\t}\n\n\tcopy(w.p[:], w.p[m:])\n\tcopy(w.p[len(w.p)-m:], p[len(p)-m:])\n\tnn, err := w.w.Write(p[:len(p)-m])\n\treturn n + nn, err\n}\n\ntype flateWriteWrapper struct {\n\tfw *flate.Writer\n\ttw *truncWriter\n\tp  *sync.Pool\n}\n\nfunc (w *flateWriteWrapper) Write(p []byte) (int, error) {\n\tif w.fw == nil {\n\t\treturn 0, errWriteClosed\n\t}\n\treturn w.fw.Write(p)\n}\n\nfunc (w *flateWriteWrapper) Close() error {\n\tif w.fw == nil {\n\t\treturn errWriteClosed\n\t}\n\terr1 := w.fw.Flush()\n\tw.p.Put(w.fw)\n\tw.fw = nil\n\tif w.tw.p != [4]byte{0, 0, 0xff, 0xff} {\n\t\treturn errors.New(\"websocket: internal error, unexpected bytes at end of flate stream\")\n\t}\n\terr2 := w.tw.w.Close()\n\tif err1 != nil {\n\t\treturn err1\n\t}\n\treturn err2\n}\n\ntype flateReadWrapper struct {\n\tfr io.ReadCloser\n}\n\nfunc (r *flateReadWrapper) Read(p []byte) (int, error) {\n\tif r.fr == nil {\n\t\treturn 0, io.ErrClosedPipe\n\t}\n\tn, err := r.fr.Read(p)\n\tif err == io.EOF {\n\t\t// Preemptively place the reader back in the pool. This helps with\n\t\t// scenarios where the application does not call NextReader() soon after\n\t\t// this final read.\n\t\tr.Close()\n\t}\n\treturn n, err\n}\n\nfunc (r *flateReadWrapper) Close() error {\n\tif r.fr == nil {\n\t\treturn io.ErrClosedPipe\n\t}\n\terr := r.fr.Close()\n\tflateReaderPool.Put(r.fr)\n\tr.fr = nil\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/conn.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"math/rand\"\n\t\"net\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\t\"unicode/utf8\"\n)\n\nconst (\n\t// Frame header byte 0 bits from Section 5.2 of RFC 6455\n\tfinalBit = 1 << 7\n\trsv1Bit  = 1 << 6\n\trsv2Bit  = 1 << 5\n\trsv3Bit  = 1 << 4\n\n\t// Frame header byte 1 bits from Section 5.2 of RFC 6455\n\tmaskBit = 1 << 7\n\n\tmaxFrameHeaderSize         = 2 + 8 + 4 // Fixed header + length + mask\n\tmaxControlFramePayloadSize = 125\n\n\twriteWait = time.Second\n\n\tdefaultReadBufferSize  = 4096\n\tdefaultWriteBufferSize = 4096\n\n\tcontinuationFrame = 0\n\tnoFrame           = -1\n)\n\n// Close codes defined in RFC 6455, section 11.7.\nconst (\n\tCloseNormalClosure           = 1000\n\tCloseGoingAway               = 1001\n\tCloseProtocolError           = 1002\n\tCloseUnsupportedData         = 1003\n\tCloseNoStatusReceived        = 1005\n\tCloseAbnormalClosure         = 1006\n\tCloseInvalidFramePayloadData = 1007\n\tClosePolicyViolation         = 1008\n\tCloseMessageTooBig           = 1009\n\tCloseMandatoryExtension      = 1010\n\tCloseInternalServerErr       = 1011\n\tCloseServiceRestart          = 1012\n\tCloseTryAgainLater           = 1013\n\tCloseTLSHandshake            = 1015\n)\n\n// The message types are defined in RFC 6455, section 11.8.\nconst (\n\t// TextMessage denotes a text data message. The text message payload is\n\t// interpreted as UTF-8 encoded text data.\n\tTextMessage = 1\n\n\t// BinaryMessage denotes a binary data message.\n\tBinaryMessage = 2\n\n\t// CloseMessage denotes a close control message. The optional message\n\t// payload contains a numeric code and text. Use the FormatCloseMessage\n\t// function to format a close message payload.\n\tCloseMessage = 8\n\n\t// PingMessage denotes a ping control message. The optional message payload\n\t// is UTF-8 encoded text.\n\tPingMessage = 9\n\n\t// PongMessage denotes a pong control message. The optional message payload\n\t// is UTF-8 encoded text.\n\tPongMessage = 10\n)\n\n// ErrCloseSent is returned when the application writes a message to the\n// connection after sending a close message.\nvar ErrCloseSent = errors.New(\"websocket: close sent\")\n\n// ErrReadLimit is returned when reading a message that is larger than the\n// read limit set for the connection.\nvar ErrReadLimit = errors.New(\"websocket: read limit exceeded\")\n\n// netError satisfies the net Error interface.\ntype netError struct {\n\tmsg       string\n\ttemporary bool\n\ttimeout   bool\n}\n\nfunc (e *netError) Error() string   { return e.msg }\nfunc (e *netError) Temporary() bool { return e.temporary }\nfunc (e *netError) Timeout() bool   { return e.timeout }\n\n// CloseError represents a close message.\ntype CloseError struct {\n\t// Code is defined in RFC 6455, section 11.7.\n\tCode int\n\n\t// Text is the optional text payload.\n\tText string\n}\n\nfunc (e *CloseError) Error() string {\n\ts := []byte(\"websocket: close \")\n\ts = strconv.AppendInt(s, int64(e.Code), 10)\n\tswitch e.Code {\n\tcase CloseNormalClosure:\n\t\ts = append(s, \" (normal)\"...)\n\tcase CloseGoingAway:\n\t\ts = append(s, \" (going away)\"...)\n\tcase CloseProtocolError:\n\t\ts = append(s, \" (protocol error)\"...)\n\tcase CloseUnsupportedData:\n\t\ts = append(s, \" (unsupported data)\"...)\n\tcase CloseNoStatusReceived:\n\t\ts = append(s, \" (no status)\"...)\n\tcase CloseAbnormalClosure:\n\t\ts = append(s, \" (abnormal closure)\"...)\n\tcase CloseInvalidFramePayloadData:\n\t\ts = append(s, \" (invalid payload data)\"...)\n\tcase ClosePolicyViolation:\n\t\ts = append(s, \" (policy violation)\"...)\n\tcase CloseMessageTooBig:\n\t\ts = append(s, \" (message too big)\"...)\n\tcase CloseMandatoryExtension:\n\t\ts = append(s, \" (mandatory extension missing)\"...)\n\tcase CloseInternalServerErr:\n\t\ts = append(s, \" (internal server error)\"...)\n\tcase CloseTLSHandshake:\n\t\ts = append(s, \" (TLS handshake error)\"...)\n\t}\n\tif e.Text != \"\" {\n\t\ts = append(s, \": \"...)\n\t\ts = append(s, e.Text...)\n\t}\n\treturn string(s)\n}\n\n// IsCloseError returns boolean indicating whether the error is a *CloseError\n// with one of the specified codes.\nfunc IsCloseError(err error, codes ...int) bool {\n\tif e, ok := err.(*CloseError); ok {\n\t\tfor _, code := range codes {\n\t\t\tif e.Code == code {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\n// IsUnexpectedCloseError returns boolean indicating whether the error is a\n// *CloseError with a code not in the list of expected codes.\nfunc IsUnexpectedCloseError(err error, expectedCodes ...int) bool {\n\tif e, ok := err.(*CloseError); ok {\n\t\tfor _, code := range expectedCodes {\n\t\t\tif e.Code == code {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nvar (\n\terrWriteTimeout        = &netError{msg: \"websocket: write timeout\", timeout: true, temporary: true}\n\terrUnexpectedEOF       = &CloseError{Code: CloseAbnormalClosure, Text: io.ErrUnexpectedEOF.Error()}\n\terrBadWriteOpCode      = errors.New(\"websocket: bad write message type\")\n\terrWriteClosed         = errors.New(\"websocket: write closed\")\n\terrInvalidControlFrame = errors.New(\"websocket: invalid control frame\")\n)\n\nfunc newMaskKey() [4]byte {\n\tn := rand.Uint32()\n\treturn [4]byte{byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24)}\n}\n\nfunc hideTempErr(err error) error {\n\tif e, ok := err.(net.Error); ok && e.Temporary() {\n\t\terr = &netError{msg: e.Error(), timeout: e.Timeout()}\n\t}\n\treturn err\n}\n\nfunc isControl(frameType int) bool {\n\treturn frameType == CloseMessage || frameType == PingMessage || frameType == PongMessage\n}\n\nfunc isData(frameType int) bool {\n\treturn frameType == TextMessage || frameType == BinaryMessage\n}\n\nvar validReceivedCloseCodes = map[int]bool{\n\t// see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number\n\n\tCloseNormalClosure:           true,\n\tCloseGoingAway:               true,\n\tCloseProtocolError:           true,\n\tCloseUnsupportedData:         true,\n\tCloseNoStatusReceived:        false,\n\tCloseAbnormalClosure:         false,\n\tCloseInvalidFramePayloadData: true,\n\tClosePolicyViolation:         true,\n\tCloseMessageTooBig:           true,\n\tCloseMandatoryExtension:      true,\n\tCloseInternalServerErr:       true,\n\tCloseServiceRestart:          true,\n\tCloseTryAgainLater:           true,\n\tCloseTLSHandshake:            false,\n}\n\nfunc isValidReceivedCloseCode(code int) bool {\n\treturn validReceivedCloseCodes[code] || (code >= 3000 && code <= 4999)\n}\n\n// BufferPool represents a pool of buffers. The *sync.Pool type satisfies this\n// interface.  The type of the value stored in a pool is not specified.\ntype BufferPool interface {\n\t// Get gets a value from the pool or returns nil if the pool is empty.\n\tGet() interface{}\n\t// Put adds a value to the pool.\n\tPut(interface{})\n}\n\n// writePoolData is the type added to the write buffer pool. This wrapper is\n// used to prevent applications from peeking at and depending on the values\n// added to the pool.\ntype writePoolData struct{ buf []byte }\n\n// The Conn type represents a WebSocket connection.\ntype Conn struct {\n\tconn        net.Conn\n\tisServer    bool\n\tsubprotocol string\n\n\t// Write fields\n\tmu            chan struct{} // used as mutex to protect write to conn\n\twriteBuf      []byte        // frame is constructed in this buffer.\n\twritePool     BufferPool\n\twriteBufSize  int\n\twriteDeadline time.Time\n\twriter        io.WriteCloser // the current writer returned to the application\n\tisWriting     bool           // for best-effort concurrent write detection\n\n\twriteErrMu sync.Mutex\n\twriteErr   error\n\n\tenableWriteCompression bool\n\tcompressionLevel       int\n\tnewCompressionWriter   func(io.WriteCloser, int) io.WriteCloser\n\n\t// Read fields\n\treader  io.ReadCloser // the current reader returned to the application\n\treadErr error\n\tbr      *bufio.Reader\n\t// bytes remaining in current frame.\n\t// set setReadRemaining to safely update this value and prevent overflow\n\treadRemaining int64\n\treadFinal     bool  // true the current message has more frames.\n\treadLength    int64 // Message size.\n\treadLimit     int64 // Maximum message size.\n\treadMaskPos   int\n\treadMaskKey   [4]byte\n\thandlePong    func(string) error\n\thandlePing    func(string) error\n\thandleClose   func(int, string) error\n\treadErrCount  int\n\tmessageReader *messageReader // the current low-level reader\n\n\treadDecompress         bool // whether last read frame had RSV1 set\n\tnewDecompressionReader func(io.Reader) io.ReadCloser\n}\n\nfunc newConn(conn net.Conn, isServer bool, readBufferSize, writeBufferSize int, writeBufferPool BufferPool, br *bufio.Reader, writeBuf []byte) *Conn {\n\n\tif br == nil {\n\t\tif readBufferSize == 0 {\n\t\t\treadBufferSize = defaultReadBufferSize\n\t\t} else if readBufferSize < maxControlFramePayloadSize {\n\t\t\t// must be large enough for control frame\n\t\t\treadBufferSize = maxControlFramePayloadSize\n\t\t}\n\t\tbr = bufio.NewReaderSize(conn, readBufferSize)\n\t}\n\n\tif writeBufferSize <= 0 {\n\t\twriteBufferSize = defaultWriteBufferSize\n\t}\n\twriteBufferSize += maxFrameHeaderSize\n\n\tif writeBuf == nil && writeBufferPool == nil {\n\t\twriteBuf = make([]byte, writeBufferSize)\n\t}\n\n\tmu := make(chan struct{}, 1)\n\tmu <- struct{}{}\n\tc := &Conn{\n\t\tisServer:               isServer,\n\t\tbr:                     br,\n\t\tconn:                   conn,\n\t\tmu:                     mu,\n\t\treadFinal:              true,\n\t\twriteBuf:               writeBuf,\n\t\twritePool:              writeBufferPool,\n\t\twriteBufSize:           writeBufferSize,\n\t\tenableWriteCompression: true,\n\t\tcompressionLevel:       defaultCompressionLevel,\n\t}\n\tc.SetCloseHandler(nil)\n\tc.SetPingHandler(nil)\n\tc.SetPongHandler(nil)\n\treturn c\n}\n\n// setReadRemaining tracks the number of bytes remaining on the connection. If n\n// overflows, an ErrReadLimit is returned.\nfunc (c *Conn) setReadRemaining(n int64) error {\n\tif n < 0 {\n\t\treturn ErrReadLimit\n\t}\n\n\tc.readRemaining = n\n\treturn nil\n}\n\n// Subprotocol returns the negotiated protocol for the connection.\nfunc (c *Conn) Subprotocol() string {\n\treturn c.subprotocol\n}\n\n// Close closes the underlying network connection without sending or waiting\n// for a close message.\nfunc (c *Conn) Close() error {\n\treturn c.conn.Close()\n}\n\n// LocalAddr returns the local network address.\nfunc (c *Conn) LocalAddr() net.Addr {\n\treturn c.conn.LocalAddr()\n}\n\n// RemoteAddr returns the remote network address.\nfunc (c *Conn) RemoteAddr() net.Addr {\n\treturn c.conn.RemoteAddr()\n}\n\n// Write methods\n\nfunc (c *Conn) writeFatal(err error) error {\n\terr = hideTempErr(err)\n\tc.writeErrMu.Lock()\n\tif c.writeErr == nil {\n\t\tc.writeErr = err\n\t}\n\tc.writeErrMu.Unlock()\n\treturn err\n}\n\nfunc (c *Conn) read(n int) ([]byte, error) {\n\tp, err := c.br.Peek(n)\n\tif err == io.EOF {\n\t\terr = errUnexpectedEOF\n\t}\n\tc.br.Discard(len(p))\n\treturn p, err\n}\n\nfunc (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error {\n\t<-c.mu\n\tdefer func() { c.mu <- struct{}{} }()\n\n\tc.writeErrMu.Lock()\n\terr := c.writeErr\n\tc.writeErrMu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.conn.SetWriteDeadline(deadline)\n\tif len(buf1) == 0 {\n\t\t_, err = c.conn.Write(buf0)\n\t} else {\n\t\terr = c.writeBufs(buf0, buf1)\n\t}\n\tif err != nil {\n\t\treturn c.writeFatal(err)\n\t}\n\tif frameType == CloseMessage {\n\t\tc.writeFatal(ErrCloseSent)\n\t}\n\treturn nil\n}\n\n// WriteControl writes a control message with the given deadline. The allowed\n// message types are CloseMessage, PingMessage and PongMessage.\nfunc (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {\n\tif !isControl(messageType) {\n\t\treturn errBadWriteOpCode\n\t}\n\tif len(data) > maxControlFramePayloadSize {\n\t\treturn errInvalidControlFrame\n\t}\n\n\tb0 := byte(messageType) | finalBit\n\tb1 := byte(len(data))\n\tif !c.isServer {\n\t\tb1 |= maskBit\n\t}\n\n\tbuf := make([]byte, 0, maxFrameHeaderSize+maxControlFramePayloadSize)\n\tbuf = append(buf, b0, b1)\n\n\tif c.isServer {\n\t\tbuf = append(buf, data...)\n\t} else {\n\t\tkey := newMaskKey()\n\t\tbuf = append(buf, key[:]...)\n\t\tbuf = append(buf, data...)\n\t\tmaskBytes(key, 0, buf[6:])\n\t}\n\n\td := 1000 * time.Hour\n\tif !deadline.IsZero() {\n\t\td = deadline.Sub(time.Now())\n\t\tif d < 0 {\n\t\t\treturn errWriteTimeout\n\t\t}\n\t}\n\n\ttimer := time.NewTimer(d)\n\tselect {\n\tcase <-c.mu:\n\t\ttimer.Stop()\n\tcase <-timer.C:\n\t\treturn errWriteTimeout\n\t}\n\tdefer func() { c.mu <- struct{}{} }()\n\n\tc.writeErrMu.Lock()\n\terr := c.writeErr\n\tc.writeErrMu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tc.conn.SetWriteDeadline(deadline)\n\t_, err = c.conn.Write(buf)\n\tif err != nil {\n\t\treturn c.writeFatal(err)\n\t}\n\tif messageType == CloseMessage {\n\t\tc.writeFatal(ErrCloseSent)\n\t}\n\treturn err\n}\n\n// beginMessage prepares a connection and message writer for a new message.\nfunc (c *Conn) beginMessage(mw *messageWriter, messageType int) error {\n\t// Close previous writer if not already closed by the application. It's\n\t// probably better to return an error in this situation, but we cannot\n\t// change this without breaking existing applications.\n\tif c.writer != nil {\n\t\tc.writer.Close()\n\t\tc.writer = nil\n\t}\n\n\tif !isControl(messageType) && !isData(messageType) {\n\t\treturn errBadWriteOpCode\n\t}\n\n\tc.writeErrMu.Lock()\n\terr := c.writeErr\n\tc.writeErrMu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmw.c = c\n\tmw.frameType = messageType\n\tmw.pos = maxFrameHeaderSize\n\n\tif c.writeBuf == nil {\n\t\twpd, ok := c.writePool.Get().(writePoolData)\n\t\tif ok {\n\t\t\tc.writeBuf = wpd.buf\n\t\t} else {\n\t\t\tc.writeBuf = make([]byte, c.writeBufSize)\n\t\t}\n\t}\n\treturn nil\n}\n\n// NextWriter returns a writer for the next message to send. The writer's Close\n// method flushes the complete message to the network.\n//\n// There can be at most one open writer on a connection. NextWriter closes the\n// previous writer if the application has not already done so.\n//\n// All message types (TextMessage, BinaryMessage, CloseMessage, PingMessage and\n// PongMessage) are supported.\nfunc (c *Conn) NextWriter(messageType int) (io.WriteCloser, error) {\n\tvar mw messageWriter\n\tif err := c.beginMessage(&mw, messageType); err != nil {\n\t\treturn nil, err\n\t}\n\tc.writer = &mw\n\tif c.newCompressionWriter != nil && c.enableWriteCompression && isData(messageType) {\n\t\tw := c.newCompressionWriter(c.writer, c.compressionLevel)\n\t\tmw.compress = true\n\t\tc.writer = w\n\t}\n\treturn c.writer, nil\n}\n\ntype messageWriter struct {\n\tc         *Conn\n\tcompress  bool // whether next call to flushFrame should set RSV1\n\tpos       int  // end of data in writeBuf.\n\tframeType int  // type of the current frame.\n\terr       error\n}\n\nfunc (w *messageWriter) endMessage(err error) error {\n\tif w.err != nil {\n\t\treturn err\n\t}\n\tc := w.c\n\tw.err = err\n\tc.writer = nil\n\tif c.writePool != nil {\n\t\tc.writePool.Put(writePoolData{buf: c.writeBuf})\n\t\tc.writeBuf = nil\n\t}\n\treturn err\n}\n\n// flushFrame writes buffered data and extra as a frame to the network. The\n// final argument indicates that this is the last frame in the message.\nfunc (w *messageWriter) flushFrame(final bool, extra []byte) error {\n\tc := w.c\n\tlength := w.pos - maxFrameHeaderSize + len(extra)\n\n\t// Check for invalid control frames.\n\tif isControl(w.frameType) &&\n\t\t(!final || length > maxControlFramePayloadSize) {\n\t\treturn w.endMessage(errInvalidControlFrame)\n\t}\n\n\tb0 := byte(w.frameType)\n\tif final {\n\t\tb0 |= finalBit\n\t}\n\tif w.compress {\n\t\tb0 |= rsv1Bit\n\t}\n\tw.compress = false\n\n\tb1 := byte(0)\n\tif !c.isServer {\n\t\tb1 |= maskBit\n\t}\n\n\t// Assume that the frame starts at beginning of c.writeBuf.\n\tframePos := 0\n\tif c.isServer {\n\t\t// Adjust up if mask not included in the header.\n\t\tframePos = 4\n\t}\n\n\tswitch {\n\tcase length >= 65536:\n\t\tc.writeBuf[framePos] = b0\n\t\tc.writeBuf[framePos+1] = b1 | 127\n\t\tbinary.BigEndian.PutUint64(c.writeBuf[framePos+2:], uint64(length))\n\tcase length > 125:\n\t\tframePos += 6\n\t\tc.writeBuf[framePos] = b0\n\t\tc.writeBuf[framePos+1] = b1 | 126\n\t\tbinary.BigEndian.PutUint16(c.writeBuf[framePos+2:], uint16(length))\n\tdefault:\n\t\tframePos += 8\n\t\tc.writeBuf[framePos] = b0\n\t\tc.writeBuf[framePos+1] = b1 | byte(length)\n\t}\n\n\tif !c.isServer {\n\t\tkey := newMaskKey()\n\t\tcopy(c.writeBuf[maxFrameHeaderSize-4:], key[:])\n\t\tmaskBytes(key, 0, c.writeBuf[maxFrameHeaderSize:w.pos])\n\t\tif len(extra) > 0 {\n\t\t\treturn w.endMessage(c.writeFatal(errors.New(\"websocket: internal error, extra used in client mode\")))\n\t\t}\n\t}\n\n\t// Write the buffers to the connection with best-effort detection of\n\t// concurrent writes. See the concurrency section in the package\n\t// documentation for more info.\n\n\tif c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = true\n\n\terr := c.write(w.frameType, c.writeDeadline, c.writeBuf[framePos:w.pos], extra)\n\n\tif !c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = false\n\n\tif err != nil {\n\t\treturn w.endMessage(err)\n\t}\n\n\tif final {\n\t\tw.endMessage(errWriteClosed)\n\t\treturn nil\n\t}\n\n\t// Setup for next frame.\n\tw.pos = maxFrameHeaderSize\n\tw.frameType = continuationFrame\n\treturn nil\n}\n\nfunc (w *messageWriter) ncopy(max int) (int, error) {\n\tn := len(w.c.writeBuf) - w.pos\n\tif n <= 0 {\n\t\tif err := w.flushFrame(false, nil); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tn = len(w.c.writeBuf) - w.pos\n\t}\n\tif n > max {\n\t\tn = max\n\t}\n\treturn n, nil\n}\n\nfunc (w *messageWriter) Write(p []byte) (int, error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\n\tif len(p) > 2*len(w.c.writeBuf) && w.c.isServer {\n\t\t// Don't buffer large messages.\n\t\terr := w.flushFrame(false, p)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn len(p), nil\n\t}\n\n\tnn := len(p)\n\tfor len(p) > 0 {\n\t\tn, err := w.ncopy(len(p))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tcopy(w.c.writeBuf[w.pos:], p[:n])\n\t\tw.pos += n\n\t\tp = p[n:]\n\t}\n\treturn nn, nil\n}\n\nfunc (w *messageWriter) WriteString(p string) (int, error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\n\tnn := len(p)\n\tfor len(p) > 0 {\n\t\tn, err := w.ncopy(len(p))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tcopy(w.c.writeBuf[w.pos:], p[:n])\n\t\tw.pos += n\n\t\tp = p[n:]\n\t}\n\treturn nn, nil\n}\n\nfunc (w *messageWriter) ReadFrom(r io.Reader) (nn int64, err error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\tfor {\n\t\tif w.pos == len(w.c.writeBuf) {\n\t\t\terr = w.flushFrame(false, nil)\n\t\t\tif err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tvar n int\n\t\tn, err = r.Read(w.c.writeBuf[w.pos:])\n\t\tw.pos += n\n\t\tnn += int64(n)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\terr = nil\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\treturn nn, err\n}\n\nfunc (w *messageWriter) Close() error {\n\tif w.err != nil {\n\t\treturn w.err\n\t}\n\treturn w.flushFrame(true, nil)\n}\n\n// WritePreparedMessage writes prepared message into connection.\nfunc (c *Conn) WritePreparedMessage(pm *PreparedMessage) error {\n\tframeType, frameData, err := pm.frame(prepareKey{\n\t\tisServer:         c.isServer,\n\t\tcompress:         c.newCompressionWriter != nil && c.enableWriteCompression && isData(pm.messageType),\n\t\tcompressionLevel: c.compressionLevel,\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = true\n\terr = c.write(frameType, c.writeDeadline, frameData, nil)\n\tif !c.isWriting {\n\t\tpanic(\"concurrent write to websocket connection\")\n\t}\n\tc.isWriting = false\n\treturn err\n}\n\n// WriteMessage is a helper method for getting a writer using NextWriter,\n// writing the message and closing the writer.\nfunc (c *Conn) WriteMessage(messageType int, data []byte) error {\n\n\tif c.isServer && (c.newCompressionWriter == nil || !c.enableWriteCompression) {\n\t\t// Fast path with no allocations and single frame.\n\n\t\tvar mw messageWriter\n\t\tif err := c.beginMessage(&mw, messageType); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tn := copy(c.writeBuf[mw.pos:], data)\n\t\tmw.pos += n\n\t\tdata = data[n:]\n\t\treturn mw.flushFrame(true, data)\n\t}\n\n\tw, err := c.NextWriter(messageType)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err = w.Write(data); err != nil {\n\t\treturn err\n\t}\n\treturn w.Close()\n}\n\n// SetWriteDeadline sets the write deadline on the underlying network\n// connection. After a write has timed out, the websocket state is corrupt and\n// all future writes will return an error. A zero value for t means writes will\n// not time out.\nfunc (c *Conn) SetWriteDeadline(t time.Time) error {\n\tc.writeDeadline = t\n\treturn nil\n}\n\n// Read methods\n\nfunc (c *Conn) advanceFrame() (int, error) {\n\t// 1. Skip remainder of previous frame.\n\n\tif c.readRemaining > 0 {\n\t\tif _, err := io.CopyN(ioutil.Discard, c.br, c.readRemaining); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t}\n\n\t// 2. Read and parse first two bytes of frame header.\n\n\tp, err := c.read(2)\n\tif err != nil {\n\t\treturn noFrame, err\n\t}\n\n\tfinal := p[0]&finalBit != 0\n\tframeType := int(p[0] & 0xf)\n\tmask := p[1]&maskBit != 0\n\tc.setReadRemaining(int64(p[1] & 0x7f))\n\n\tc.readDecompress = false\n\tif c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 {\n\t\tc.readDecompress = true\n\t\tp[0] &^= rsv1Bit\n\t}\n\n\tif rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 {\n\t\treturn noFrame, c.handleProtocolError(\"unexpected reserved bits 0x\" + strconv.FormatInt(int64(rsv), 16))\n\t}\n\n\tswitch frameType {\n\tcase CloseMessage, PingMessage, PongMessage:\n\t\tif c.readRemaining > maxControlFramePayloadSize {\n\t\t\treturn noFrame, c.handleProtocolError(\"control frame length > 125\")\n\t\t}\n\t\tif !final {\n\t\t\treturn noFrame, c.handleProtocolError(\"control frame not final\")\n\t\t}\n\tcase TextMessage, BinaryMessage:\n\t\tif !c.readFinal {\n\t\t\treturn noFrame, c.handleProtocolError(\"message start before final message frame\")\n\t\t}\n\t\tc.readFinal = final\n\tcase continuationFrame:\n\t\tif c.readFinal {\n\t\t\treturn noFrame, c.handleProtocolError(\"continuation after final message frame\")\n\t\t}\n\t\tc.readFinal = final\n\tdefault:\n\t\treturn noFrame, c.handleProtocolError(\"unknown opcode \" + strconv.Itoa(frameType))\n\t}\n\n\t// 3. Read and parse frame length as per\n\t// https://tools.ietf.org/html/rfc6455#section-5.2\n\t//\n\t// The length of the \"Payload data\", in bytes: if 0-125, that is the payload\n\t// length.\n\t// - If 126, the following 2 bytes interpreted as a 16-bit unsigned\n\t// integer are the payload length.\n\t// - If 127, the following 8 bytes interpreted as\n\t// a 64-bit unsigned integer (the most significant bit MUST be 0) are the\n\t// payload length. Multibyte length quantities are expressed in network byte\n\t// order.\n\n\tswitch c.readRemaining {\n\tcase 126:\n\t\tp, err := c.read(2)\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\n\t\tif err := c.setReadRemaining(int64(binary.BigEndian.Uint16(p))); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\tcase 127:\n\t\tp, err := c.read(8)\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\n\t\tif err := c.setReadRemaining(int64(binary.BigEndian.Uint64(p))); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t}\n\n\t// 4. Handle frame masking.\n\n\tif mask != c.isServer {\n\t\treturn noFrame, c.handleProtocolError(\"incorrect mask flag\")\n\t}\n\n\tif mask {\n\t\tc.readMaskPos = 0\n\t\tp, err := c.read(len(c.readMaskKey))\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t\tcopy(c.readMaskKey[:], p)\n\t}\n\n\t// 5. For text and binary messages, enforce read limit and return.\n\n\tif frameType == continuationFrame || frameType == TextMessage || frameType == BinaryMessage {\n\n\t\tc.readLength += c.readRemaining\n\t\t// Don't allow readLength to overflow in the presence of a large readRemaining\n\t\t// counter.\n\t\tif c.readLength < 0 {\n\t\t\treturn noFrame, ErrReadLimit\n\t\t}\n\n\t\tif c.readLimit > 0 && c.readLength > c.readLimit {\n\t\t\tc.WriteControl(CloseMessage, FormatCloseMessage(CloseMessageTooBig, \"\"), time.Now().Add(writeWait))\n\t\t\treturn noFrame, ErrReadLimit\n\t\t}\n\n\t\treturn frameType, nil\n\t}\n\n\t// 6. Read control frame payload.\n\n\tvar payload []byte\n\tif c.readRemaining > 0 {\n\t\tpayload, err = c.read(int(c.readRemaining))\n\t\tc.setReadRemaining(0)\n\t\tif err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t\tif c.isServer {\n\t\t\tmaskBytes(c.readMaskKey, 0, payload)\n\t\t}\n\t}\n\n\t// 7. Process control frame payload.\n\n\tswitch frameType {\n\tcase PongMessage:\n\t\tif err := c.handlePong(string(payload)); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\tcase PingMessage:\n\t\tif err := c.handlePing(string(payload)); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\tcase CloseMessage:\n\t\tcloseCode := CloseNoStatusReceived\n\t\tcloseText := \"\"\n\t\tif len(payload) >= 2 {\n\t\t\tcloseCode = int(binary.BigEndian.Uint16(payload))\n\t\t\tif !isValidReceivedCloseCode(closeCode) {\n\t\t\t\treturn noFrame, c.handleProtocolError(\"invalid close code\")\n\t\t\t}\n\t\t\tcloseText = string(payload[2:])\n\t\t\tif !utf8.ValidString(closeText) {\n\t\t\t\treturn noFrame, c.handleProtocolError(\"invalid utf8 payload in close frame\")\n\t\t\t}\n\t\t}\n\t\tif err := c.handleClose(closeCode, closeText); err != nil {\n\t\t\treturn noFrame, err\n\t\t}\n\t\treturn noFrame, &CloseError{Code: closeCode, Text: closeText}\n\t}\n\n\treturn frameType, nil\n}\n\nfunc (c *Conn) handleProtocolError(message string) error {\n\tc.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))\n\treturn errors.New(\"websocket: \" + message)\n}\n\n// NextReader returns the next data message received from the peer. The\n// returned messageType is either TextMessage or BinaryMessage.\n//\n// There can be at most one open reader on a connection. NextReader discards\n// the previous message if the application has not already consumed it.\n//\n// Applications must break out of the application's read loop when this method\n// returns a non-nil error value. Errors returned from this method are\n// permanent. Once this method returns a non-nil error, all subsequent calls to\n// this method return the same error.\nfunc (c *Conn) NextReader() (messageType int, r io.Reader, err error) {\n\t// Close previous reader, only relevant for decompression.\n\tif c.reader != nil {\n\t\tc.reader.Close()\n\t\tc.reader = nil\n\t}\n\n\tc.messageReader = nil\n\tc.readLength = 0\n\n\tfor c.readErr == nil {\n\t\tframeType, err := c.advanceFrame()\n\t\tif err != nil {\n\t\t\tc.readErr = hideTempErr(err)\n\t\t\tbreak\n\t\t}\n\n\t\tif frameType == TextMessage || frameType == BinaryMessage {\n\t\t\tc.messageReader = &messageReader{c}\n\t\t\tc.reader = c.messageReader\n\t\t\tif c.readDecompress {\n\t\t\t\tc.reader = c.newDecompressionReader(c.reader)\n\t\t\t}\n\t\t\treturn frameType, c.reader, nil\n\t\t}\n\t}\n\n\t// Applications that do handle the error returned from this method spin in\n\t// tight loop on connection failure. To help application developers detect\n\t// this error, panic on repeated reads to the failed connection.\n\tc.readErrCount++\n\tif c.readErrCount >= 1000 {\n\t\tpanic(\"repeated read on failed websocket connection\")\n\t}\n\n\treturn noFrame, nil, c.readErr\n}\n\ntype messageReader struct{ c *Conn }\n\nfunc (r *messageReader) Read(b []byte) (int, error) {\n\tc := r.c\n\tif c.messageReader != r {\n\t\treturn 0, io.EOF\n\t}\n\n\tfor c.readErr == nil {\n\n\t\tif c.readRemaining > 0 {\n\t\t\tif int64(len(b)) > c.readRemaining {\n\t\t\t\tb = b[:c.readRemaining]\n\t\t\t}\n\t\t\tn, err := c.br.Read(b)\n\t\t\tc.readErr = hideTempErr(err)\n\t\t\tif c.isServer {\n\t\t\t\tc.readMaskPos = maskBytes(c.readMaskKey, c.readMaskPos, b[:n])\n\t\t\t}\n\t\t\trem := c.readRemaining\n\t\t\trem -= int64(n)\n\t\t\tc.setReadRemaining(rem)\n\t\t\tif c.readRemaining > 0 && c.readErr == io.EOF {\n\t\t\t\tc.readErr = errUnexpectedEOF\n\t\t\t}\n\t\t\treturn n, c.readErr\n\t\t}\n\n\t\tif c.readFinal {\n\t\t\tc.messageReader = nil\n\t\t\treturn 0, io.EOF\n\t\t}\n\n\t\tframeType, err := c.advanceFrame()\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\tc.readErr = hideTempErr(err)\n\t\tcase frameType == TextMessage || frameType == BinaryMessage:\n\t\t\tc.readErr = errors.New(\"websocket: internal error, unexpected text or binary in Reader\")\n\t\t}\n\t}\n\n\terr := c.readErr\n\tif err == io.EOF && c.messageReader == r {\n\t\terr = errUnexpectedEOF\n\t}\n\treturn 0, err\n}\n\nfunc (r *messageReader) Close() error {\n\treturn nil\n}\n\n// ReadMessage is a helper method for getting a reader using NextReader and\n// reading from that reader to a buffer.\nfunc (c *Conn) ReadMessage() (messageType int, p []byte, err error) {\n\tvar r io.Reader\n\tmessageType, r, err = c.NextReader()\n\tif err != nil {\n\t\treturn messageType, nil, err\n\t}\n\tp, err = ioutil.ReadAll(r)\n\treturn messageType, p, err\n}\n\n// SetReadDeadline sets the read deadline on the underlying network connection.\n// After a read has timed out, the websocket connection state is corrupt and\n// all future reads will return an error. A zero value for t means reads will\n// not time out.\nfunc (c *Conn) SetReadDeadline(t time.Time) error {\n\treturn c.conn.SetReadDeadline(t)\n}\n\n// SetReadLimit sets the maximum size in bytes for a message read from the peer. If a\n// message exceeds the limit, the connection sends a close message to the peer\n// and returns ErrReadLimit to the application.\nfunc (c *Conn) SetReadLimit(limit int64) {\n\tc.readLimit = limit\n}\n\n// CloseHandler returns the current close handler\nfunc (c *Conn) CloseHandler() func(code int, text string) error {\n\treturn c.handleClose\n}\n\n// SetCloseHandler sets the handler for close messages received from the peer.\n// The code argument to h is the received close code or CloseNoStatusReceived\n// if the close message is empty. The default close handler sends a close\n// message back to the peer.\n//\n// The handler function is called from the NextReader, ReadMessage and message\n// reader Read methods. The application must read the connection to process\n// close messages as described in the section on Control Messages above.\n//\n// The connection read methods return a CloseError when a close message is\n// received. Most applications should handle close messages as part of their\n// normal error handling. Applications should only set a close handler when the\n// application must perform some action before sending a close message back to\n// the peer.\nfunc (c *Conn) SetCloseHandler(h func(code int, text string) error) {\n\tif h == nil {\n\t\th = func(code int, text string) error {\n\t\t\tmessage := FormatCloseMessage(code, \"\")\n\t\t\tc.WriteControl(CloseMessage, message, time.Now().Add(writeWait))\n\t\t\treturn nil\n\t\t}\n\t}\n\tc.handleClose = h\n}\n\n// PingHandler returns the current ping handler\nfunc (c *Conn) PingHandler() func(appData string) error {\n\treturn c.handlePing\n}\n\n// SetPingHandler sets the handler for ping messages received from the peer.\n// The appData argument to h is the PING message application data. The default\n// ping handler sends a pong to the peer.\n//\n// The handler function is called from the NextReader, ReadMessage and message\n// reader Read methods. The application must read the connection to process\n// ping messages as described in the section on Control Messages above.\nfunc (c *Conn) SetPingHandler(h func(appData string) error) {\n\tif h == nil {\n\t\th = func(message string) error {\n\t\t\terr := c.WriteControl(PongMessage, []byte(message), time.Now().Add(writeWait))\n\t\t\tif err == ErrCloseSent {\n\t\t\t\treturn nil\n\t\t\t} else if e, ok := err.(net.Error); ok && e.Temporary() {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\tc.handlePing = h\n}\n\n// PongHandler returns the current pong handler\nfunc (c *Conn) PongHandler() func(appData string) error {\n\treturn c.handlePong\n}\n\n// SetPongHandler sets the handler for pong messages received from the peer.\n// The appData argument to h is the PONG message application data. The default\n// pong handler does nothing.\n//\n// The handler function is called from the NextReader, ReadMessage and message\n// reader Read methods. The application must read the connection to process\n// pong messages as described in the section on Control Messages above.\nfunc (c *Conn) SetPongHandler(h func(appData string) error) {\n\tif h == nil {\n\t\th = func(string) error { return nil }\n\t}\n\tc.handlePong = h\n}\n\n// UnderlyingConn returns the internal net.Conn. This can be used to further\n// modifications to connection specific flags.\nfunc (c *Conn) UnderlyingConn() net.Conn {\n\treturn c.conn\n}\n\n// EnableWriteCompression enables and disables write compression of\n// subsequent text and binary messages. This function is a noop if\n// compression was not negotiated with the peer.\nfunc (c *Conn) EnableWriteCompression(enable bool) {\n\tc.enableWriteCompression = enable\n}\n\n// SetCompressionLevel sets the flate compression level for subsequent text and\n// binary messages. This function is a noop if compression was not negotiated\n// with the peer. See the compress/flate package for a description of\n// compression levels.\nfunc (c *Conn) SetCompressionLevel(level int) error {\n\tif !isValidCompressionLevel(level) {\n\t\treturn errors.New(\"websocket: invalid compression level\")\n\t}\n\tc.compressionLevel = level\n\treturn nil\n}\n\n// FormatCloseMessage formats closeCode and text as a WebSocket close message.\n// An empty message is returned for code CloseNoStatusReceived.\nfunc FormatCloseMessage(closeCode int, text string) []byte {\n\tif closeCode == CloseNoStatusReceived {\n\t\t// Return empty message because it's illegal to send\n\t\t// CloseNoStatusReceived. Return non-nil value in case application\n\t\t// checks for nil.\n\t\treturn []byte{}\n\t}\n\tbuf := make([]byte, 2+len(text))\n\tbinary.BigEndian.PutUint16(buf, uint16(closeCode))\n\tcopy(buf[2:], text)\n\treturn buf\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/conn_write.go",
    "content": "// Copyright 2016 The Gorilla WebSocket 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// +build go1.8\n\npackage websocket\n\nimport \"net\"\n\nfunc (c *Conn) writeBufs(bufs ...[]byte) error {\n\tb := net.Buffers(bufs)\n\t_, err := b.WriteTo(c.conn)\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/conn_write_legacy.go",
    "content": "// Copyright 2016 The Gorilla WebSocket 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// +build !go1.8\n\npackage websocket\n\nfunc (c *Conn) writeBufs(bufs ...[]byte) error {\n\tfor _, buf := range bufs {\n\t\tif len(buf) > 0 {\n\t\t\tif _, err := c.conn.Write(buf); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/doc.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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// Package websocket implements the WebSocket protocol defined in RFC 6455.\n//\n// Overview\n//\n// The Conn type represents a WebSocket connection. A server application calls\n// the Upgrader.Upgrade method from an HTTP request handler to get a *Conn:\n//\n//  var upgrader = websocket.Upgrader{\n//      ReadBufferSize:  1024,\n//      WriteBufferSize: 1024,\n//  }\n//\n//  func handler(w http.ResponseWriter, r *http.Request) {\n//      conn, err := upgrader.Upgrade(w, r, nil)\n//      if err != nil {\n//          log.Println(err)\n//          return\n//      }\n//      ... Use conn to send and receive messages.\n//  }\n//\n// Call the connection's WriteMessage and ReadMessage methods to send and\n// receive messages as a slice of bytes. This snippet of code shows how to echo\n// messages using these methods:\n//\n//  for {\n//      messageType, p, err := conn.ReadMessage()\n//      if err != nil {\n//          log.Println(err)\n//          return\n//      }\n//      if err := conn.WriteMessage(messageType, p); err != nil {\n//          log.Println(err)\n//          return\n//      }\n//  }\n//\n// In above snippet of code, p is a []byte and messageType is an int with value\n// websocket.BinaryMessage or websocket.TextMessage.\n//\n// An application can also send and receive messages using the io.WriteCloser\n// and io.Reader interfaces. To send a message, call the connection NextWriter\n// method to get an io.WriteCloser, write the message to the writer and close\n// the writer when done. To receive a message, call the connection NextReader\n// method to get an io.Reader and read until io.EOF is returned. This snippet\n// shows how to echo messages using the NextWriter and NextReader methods:\n//\n//  for {\n//      messageType, r, err := conn.NextReader()\n//      if err != nil {\n//          return\n//      }\n//      w, err := conn.NextWriter(messageType)\n//      if err != nil {\n//          return err\n//      }\n//      if _, err := io.Copy(w, r); err != nil {\n//          return err\n//      }\n//      if err := w.Close(); err != nil {\n//          return err\n//      }\n//  }\n//\n// Data Messages\n//\n// The WebSocket protocol distinguishes between text and binary data messages.\n// Text messages are interpreted as UTF-8 encoded text. The interpretation of\n// binary messages is left to the application.\n//\n// This package uses the TextMessage and BinaryMessage integer constants to\n// identify the two data message types. The ReadMessage and NextReader methods\n// return the type of the received message. The messageType argument to the\n// WriteMessage and NextWriter methods specifies the type of a sent message.\n//\n// It is the application's responsibility to ensure that text messages are\n// valid UTF-8 encoded text.\n//\n// Control Messages\n//\n// The WebSocket protocol defines three types of control messages: close, ping\n// and pong. Call the connection WriteControl, WriteMessage or NextWriter\n// methods to send a control message to the peer.\n//\n// Connections handle received close messages by calling the handler function\n// set with the SetCloseHandler method and by returning a *CloseError from the\n// NextReader, ReadMessage or the message Read method. The default close\n// handler sends a close message to the peer.\n//\n// Connections handle received ping messages by calling the handler function\n// set with the SetPingHandler method. The default ping handler sends a pong\n// message to the peer.\n//\n// Connections handle received pong messages by calling the handler function\n// set with the SetPongHandler method. The default pong handler does nothing.\n// If an application sends ping messages, then the application should set a\n// pong handler to receive the corresponding pong.\n//\n// The control message handler functions are called from the NextReader,\n// ReadMessage and message reader Read methods. The default close and ping\n// handlers can block these methods for a short time when the handler writes to\n// the connection.\n//\n// The application must read the connection to process close, ping and pong\n// messages sent from the peer. If the application is not otherwise interested\n// in messages from the peer, then the application should start a goroutine to\n// read and discard messages from the peer. A simple example is:\n//\n//  func readLoop(c *websocket.Conn) {\n//      for {\n//          if _, _, err := c.NextReader(); err != nil {\n//              c.Close()\n//              break\n//          }\n//      }\n//  }\n//\n// Concurrency\n//\n// Connections support one concurrent reader and one concurrent writer.\n//\n// Applications are responsible for ensuring that no more than one goroutine\n// calls the write methods (NextWriter, SetWriteDeadline, WriteMessage,\n// WriteJSON, EnableWriteCompression, SetCompressionLevel) concurrently and\n// that no more than one goroutine calls the read methods (NextReader,\n// SetReadDeadline, ReadMessage, ReadJSON, SetPongHandler, SetPingHandler)\n// concurrently.\n//\n// The Close and WriteControl methods can be called concurrently with all other\n// methods.\n//\n// Origin Considerations\n//\n// Web browsers allow Javascript applications to open a WebSocket connection to\n// any host. It's up to the server to enforce an origin policy using the Origin\n// request header sent by the browser.\n//\n// The Upgrader calls the function specified in the CheckOrigin field to check\n// the origin. If the CheckOrigin function returns false, then the Upgrade\n// method fails the WebSocket handshake with HTTP status 403.\n//\n// If the CheckOrigin field is nil, then the Upgrader uses a safe default: fail\n// the handshake if the Origin request header is present and the Origin host is\n// not equal to the Host request header.\n//\n// The deprecated package-level Upgrade function does not perform origin\n// checking. The application is responsible for checking the Origin header\n// before calling the Upgrade function.\n//\n// Buffers\n//\n// Connections buffer network input and output to reduce the number\n// of system calls when reading or writing messages.\n//\n// Write buffers are also used for constructing WebSocket frames. See RFC 6455,\n// Section 5 for a discussion of message framing. A WebSocket frame header is\n// written to the network each time a write buffer is flushed to the network.\n// Decreasing the size of the write buffer can increase the amount of framing\n// overhead on the connection.\n//\n// The buffer sizes in bytes are specified by the ReadBufferSize and\n// WriteBufferSize fields in the Dialer and Upgrader. The Dialer uses a default\n// size of 4096 when a buffer size field is set to zero. The Upgrader reuses\n// buffers created by the HTTP server when a buffer size field is set to zero.\n// The HTTP server buffers have a size of 4096 at the time of this writing.\n//\n// The buffer sizes do not limit the size of a message that can be read or\n// written by a connection.\n//\n// Buffers are held for the lifetime of the connection by default. If the\n// Dialer or Upgrader WriteBufferPool field is set, then a connection holds the\n// write buffer only when writing a message.\n//\n// Applications should tune the buffer sizes to balance memory use and\n// performance. Increasing the buffer size uses more memory, but can reduce the\n// number of system calls to read or write the network. In the case of writing,\n// increasing the buffer size can reduce the number of frame headers written to\n// the network.\n//\n// Some guidelines for setting buffer parameters are:\n//\n// Limit the buffer sizes to the maximum expected message size. Buffers larger\n// than the largest message do not provide any benefit.\n//\n// Depending on the distribution of message sizes, setting the buffer size to\n// a value less than the maximum expected message size can greatly reduce memory\n// use with a small impact on performance. Here's an example: If 99% of the\n// messages are smaller than 256 bytes and the maximum message size is 512\n// bytes, then a buffer size of 256 bytes will result in 1.01 more system calls\n// than a buffer size of 512 bytes. The memory savings is 50%.\n//\n// A write buffer pool is useful when the application has a modest number\n// writes over a large number of connections. when buffers are pooled, a larger\n// buffer size has a reduced impact on total memory use and has the benefit of\n// reducing system calls and frame overhead.\n//\n// Compression EXPERIMENTAL\n//\n// Per message compression extensions (RFC 7692) are experimentally supported\n// by this package in a limited capacity. Setting the EnableCompression option\n// to true in Dialer or Upgrader will attempt to negotiate per message deflate\n// support.\n//\n//  var upgrader = websocket.Upgrader{\n//      EnableCompression: true,\n//  }\n//\n// If compression was successfully negotiated with the connection's peer, any\n// message received in compressed form will be automatically decompressed.\n// All Read methods will return uncompressed bytes.\n//\n// Per message compression of messages written to a connection can be enabled\n// or disabled by calling the corresponding Conn method:\n//\n//  conn.EnableWriteCompression(false)\n//\n// Currently this package does not support compression with \"context takeover\".\n// This means that messages must be compressed and decompressed in isolation,\n// without retaining sliding window or dictionary state across messages. For\n// more details refer to RFC 7692.\n//\n// Use of compression is experimental and may result in decreased performance.\npackage websocket\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/join.go",
    "content": "// Copyright 2019 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"io\"\n\t\"strings\"\n)\n\n// JoinMessages concatenates received messages to create a single io.Reader.\n// The string term is appended to each message. The returned reader does not\n// support concurrent calls to the Read method.\nfunc JoinMessages(c *Conn, term string) io.Reader {\n\treturn &joinReader{c: c, term: term}\n}\n\ntype joinReader struct {\n\tc    *Conn\n\tterm string\n\tr    io.Reader\n}\n\nfunc (r *joinReader) Read(p []byte) (int, error) {\n\tif r.r == nil {\n\t\tvar err error\n\t\t_, r.r, err = r.c.NextReader()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif r.term != \"\" {\n\t\t\tr.r = io.MultiReader(r.r, strings.NewReader(r.term))\n\t\t}\n\t}\n\tn, err := r.r.Read(p)\n\tif err == io.EOF {\n\t\terr = nil\n\t\tr.r = nil\n\t}\n\treturn n, err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/json.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"encoding/json\"\n\t\"io\"\n)\n\n// WriteJSON writes the JSON encoding of v as a message.\n//\n// Deprecated: Use c.WriteJSON instead.\nfunc WriteJSON(c *Conn, v interface{}) error {\n\treturn c.WriteJSON(v)\n}\n\n// WriteJSON writes the JSON encoding of v as a message.\n//\n// See the documentation for encoding/json Marshal for details about the\n// conversion of Go values to JSON.\nfunc (c *Conn) WriteJSON(v interface{}) error {\n\tw, err := c.NextWriter(TextMessage)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr1 := json.NewEncoder(w).Encode(v)\n\terr2 := w.Close()\n\tif err1 != nil {\n\t\treturn err1\n\t}\n\treturn err2\n}\n\n// ReadJSON reads the next JSON-encoded message from the connection and stores\n// it in the value pointed to by v.\n//\n// Deprecated: Use c.ReadJSON instead.\nfunc ReadJSON(c *Conn, v interface{}) error {\n\treturn c.ReadJSON(v)\n}\n\n// ReadJSON reads the next JSON-encoded message from the connection and stores\n// it in the value pointed to by v.\n//\n// See the documentation for the encoding/json Unmarshal function for details\n// about the conversion of JSON to a Go value.\nfunc (c *Conn) ReadJSON(v interface{}) error {\n\t_, r, err := c.NextReader()\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = json.NewDecoder(r).Decode(v)\n\tif err == io.EOF {\n\t\t// One value is expected in the message.\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/mask.go",
    "content": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of\n// this source code is governed by a BSD-style license that can be found in the\n// LICENSE file.\n\n// +build !appengine\n\npackage websocket\n\nimport \"unsafe\"\n\nconst wordSize = int(unsafe.Sizeof(uintptr(0)))\n\nfunc maskBytes(key [4]byte, pos int, b []byte) int {\n\t// Mask one byte at a time for small buffers.\n\tif len(b) < 2*wordSize {\n\t\tfor i := range b {\n\t\t\tb[i] ^= key[pos&3]\n\t\t\tpos++\n\t\t}\n\t\treturn pos & 3\n\t}\n\n\t// Mask one byte at a time to word boundary.\n\tif n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {\n\t\tn = wordSize - n\n\t\tfor i := range b[:n] {\n\t\t\tb[i] ^= key[pos&3]\n\t\t\tpos++\n\t\t}\n\t\tb = b[n:]\n\t}\n\n\t// Create aligned word size key.\n\tvar k [wordSize]byte\n\tfor i := range k {\n\t\tk[i] = key[(pos+i)&3]\n\t}\n\tkw := *(*uintptr)(unsafe.Pointer(&k))\n\n\t// Mask one word at a time.\n\tn := (len(b) / wordSize) * wordSize\n\tfor i := 0; i < n; i += wordSize {\n\t\t*(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw\n\t}\n\n\t// Mask one byte at a time for remaining bytes.\n\tb = b[n:]\n\tfor i := range b {\n\t\tb[i] ^= key[pos&3]\n\t\tpos++\n\t}\n\n\treturn pos & 3\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/mask_safe.go",
    "content": "// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.  Use of\n// this source code is governed by a BSD-style license that can be found in the\n// LICENSE file.\n\n// +build appengine\n\npackage websocket\n\nfunc maskBytes(key [4]byte, pos int, b []byte) int {\n\tfor i := range b {\n\t\tb[i] ^= key[pos&3]\n\t\tpos++\n\t}\n\treturn pos & 3\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/prepared.go",
    "content": "// Copyright 2017 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bytes\"\n\t\"net\"\n\t\"sync\"\n\t\"time\"\n)\n\n// PreparedMessage caches on the wire representations of a message payload.\n// Use PreparedMessage to efficiently send a message payload to multiple\n// connections. PreparedMessage is especially useful when compression is used\n// because the CPU and memory expensive compression operation can be executed\n// once for a given set of compression options.\ntype PreparedMessage struct {\n\tmessageType int\n\tdata        []byte\n\tmu          sync.Mutex\n\tframes      map[prepareKey]*preparedFrame\n}\n\n// prepareKey defines a unique set of options to cache prepared frames in PreparedMessage.\ntype prepareKey struct {\n\tisServer         bool\n\tcompress         bool\n\tcompressionLevel int\n}\n\n// preparedFrame contains data in wire representation.\ntype preparedFrame struct {\n\tonce sync.Once\n\tdata []byte\n}\n\n// NewPreparedMessage returns an initialized PreparedMessage. You can then send\n// it to connection using WritePreparedMessage method. Valid wire\n// representation will be calculated lazily only once for a set of current\n// connection options.\nfunc NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) {\n\tpm := &PreparedMessage{\n\t\tmessageType: messageType,\n\t\tframes:      make(map[prepareKey]*preparedFrame),\n\t\tdata:        data,\n\t}\n\n\t// Prepare a plain server frame.\n\t_, frameData, err := pm.frame(prepareKey{isServer: true, compress: false})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// To protect against caller modifying the data argument, remember the data\n\t// copied to the plain server frame.\n\tpm.data = frameData[len(frameData)-len(data):]\n\treturn pm, nil\n}\n\nfunc (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) {\n\tpm.mu.Lock()\n\tframe, ok := pm.frames[key]\n\tif !ok {\n\t\tframe = &preparedFrame{}\n\t\tpm.frames[key] = frame\n\t}\n\tpm.mu.Unlock()\n\n\tvar err error\n\tframe.once.Do(func() {\n\t\t// Prepare a frame using a 'fake' connection.\n\t\t// TODO: Refactor code in conn.go to allow more direct construction of\n\t\t// the frame.\n\t\tmu := make(chan struct{}, 1)\n\t\tmu <- struct{}{}\n\t\tvar nc prepareConn\n\t\tc := &Conn{\n\t\t\tconn:                   &nc,\n\t\t\tmu:                     mu,\n\t\t\tisServer:               key.isServer,\n\t\t\tcompressionLevel:       key.compressionLevel,\n\t\t\tenableWriteCompression: true,\n\t\t\twriteBuf:               make([]byte, defaultWriteBufferSize+maxFrameHeaderSize),\n\t\t}\n\t\tif key.compress {\n\t\t\tc.newCompressionWriter = compressNoContextTakeover\n\t\t}\n\t\terr = c.WriteMessage(pm.messageType, pm.data)\n\t\tframe.data = nc.buf.Bytes()\n\t})\n\treturn pm.messageType, frame.data, err\n}\n\ntype prepareConn struct {\n\tbuf bytes.Buffer\n\tnet.Conn\n}\n\nfunc (pc *prepareConn) Write(p []byte) (int, error)        { return pc.buf.Write(p) }\nfunc (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil }\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/proxy.go",
    "content": "// Copyright 2017 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"encoding/base64\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\ntype netDialerFunc func(network, addr string) (net.Conn, error)\n\nfunc (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) {\n\treturn fn(network, addr)\n}\n\nfunc init() {\n\tproxy_RegisterDialerType(\"http\", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) {\n\t\treturn &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil\n\t})\n}\n\ntype httpProxyDialer struct {\n\tproxyURL    *url.URL\n\tforwardDial func(network, addr string) (net.Conn, error)\n}\n\nfunc (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) {\n\thostPort, _ := hostPortNoPort(hpd.proxyURL)\n\tconn, err := hpd.forwardDial(network, hostPort)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tconnectHeader := make(http.Header)\n\tif user := hpd.proxyURL.User; user != nil {\n\t\tproxyUser := user.Username()\n\t\tif proxyPassword, passwordSet := user.Password(); passwordSet {\n\t\t\tcredential := base64.StdEncoding.EncodeToString([]byte(proxyUser + \":\" + proxyPassword))\n\t\t\tconnectHeader.Set(\"Proxy-Authorization\", \"Basic \"+credential)\n\t\t}\n\t}\n\n\tconnectReq := &http.Request{\n\t\tMethod: \"CONNECT\",\n\t\tURL:    &url.URL{Opaque: addr},\n\t\tHost:   addr,\n\t\tHeader: connectHeader,\n\t}\n\n\tif err := connectReq.Write(conn); err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\t// Read response. It's OK to use and discard buffered reader here becaue\n\t// the remote server does not speak until spoken to.\n\tbr := bufio.NewReader(conn)\n\tresp, err := http.ReadResponse(br, connectReq)\n\tif err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\n\tif resp.StatusCode != 200 {\n\t\tconn.Close()\n\t\tf := strings.SplitN(resp.Status, \" \", 2)\n\t\treturn nil, errors.New(f[1])\n\t}\n\treturn conn, nil\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/server.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n)\n\n// HandshakeError describes an error with the handshake from the peer.\ntype HandshakeError struct {\n\tmessage string\n}\n\nfunc (e HandshakeError) Error() string { return e.message }\n\n// Upgrader specifies parameters for upgrading an HTTP connection to a\n// WebSocket connection.\ntype Upgrader struct {\n\t// HandshakeTimeout specifies the duration for the handshake to complete.\n\tHandshakeTimeout time.Duration\n\n\t// ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer\n\t// size is zero, then buffers allocated by the HTTP server are used. The\n\t// I/O buffer sizes do not limit the size of the messages that can be sent\n\t// or received.\n\tReadBufferSize, WriteBufferSize int\n\n\t// WriteBufferPool is a pool of buffers for write operations. If the value\n\t// is not set, then write buffers are allocated to the connection for the\n\t// lifetime of the connection.\n\t//\n\t// A pool is most useful when the application has a modest volume of writes\n\t// across a large number of connections.\n\t//\n\t// Applications should use a single pool for each unique value of\n\t// WriteBufferSize.\n\tWriteBufferPool BufferPool\n\n\t// Subprotocols specifies the server's supported protocols in order of\n\t// preference. If this field is not nil, then the Upgrade method negotiates a\n\t// subprotocol by selecting the first match in this list with a protocol\n\t// requested by the client. If there's no match, then no protocol is\n\t// negotiated (the Sec-Websocket-Protocol header is not included in the\n\t// handshake response).\n\tSubprotocols []string\n\n\t// Error specifies the function for generating HTTP error responses. If Error\n\t// is nil, then http.Error is used to generate the HTTP response.\n\tError func(w http.ResponseWriter, r *http.Request, status int, reason error)\n\n\t// CheckOrigin returns true if the request Origin header is acceptable. If\n\t// CheckOrigin is nil, then a safe default is used: return false if the\n\t// Origin request header is present and the origin host is not equal to\n\t// request Host header.\n\t//\n\t// A CheckOrigin function should carefully validate the request origin to\n\t// prevent cross-site request forgery.\n\tCheckOrigin func(r *http.Request) bool\n\n\t// EnableCompression specify if the server should attempt to negotiate per\n\t// message compression (RFC 7692). Setting this value to true does not\n\t// guarantee that compression will be supported. Currently only \"no context\n\t// takeover\" modes are supported.\n\tEnableCompression bool\n}\n\nfunc (u *Upgrader) returnError(w http.ResponseWriter, r *http.Request, status int, reason string) (*Conn, error) {\n\terr := HandshakeError{reason}\n\tif u.Error != nil {\n\t\tu.Error(w, r, status, err)\n\t} else {\n\t\tw.Header().Set(\"Sec-Websocket-Version\", \"13\")\n\t\thttp.Error(w, http.StatusText(status), status)\n\t}\n\treturn nil, err\n}\n\n// checkSameOrigin returns true if the origin is not set or is equal to the request host.\nfunc checkSameOrigin(r *http.Request) bool {\n\torigin := r.Header[\"Origin\"]\n\tif len(origin) == 0 {\n\t\treturn true\n\t}\n\tu, err := url.Parse(origin[0])\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn equalASCIIFold(u.Host, r.Host)\n}\n\nfunc (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header) string {\n\tif u.Subprotocols != nil {\n\t\tclientProtocols := Subprotocols(r)\n\t\tfor _, serverProtocol := range u.Subprotocols {\n\t\t\tfor _, clientProtocol := range clientProtocols {\n\t\t\t\tif clientProtocol == serverProtocol {\n\t\t\t\t\treturn clientProtocol\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if responseHeader != nil {\n\t\treturn responseHeader.Get(\"Sec-Websocket-Protocol\")\n\t}\n\treturn \"\"\n}\n\n// Upgrade upgrades the HTTP server connection to the WebSocket protocol.\n//\n// The responseHeader is included in the response to the client's upgrade\n// request. Use the responseHeader to specify cookies (Set-Cookie) and the\n// application negotiated subprotocol (Sec-WebSocket-Protocol).\n//\n// If the upgrade fails, then Upgrade replies to the client with an HTTP error\n// response.\nfunc (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) {\n\tconst badHandshake = \"websocket: the client is not using the websocket protocol: \"\n\n\tif !tokenListContainsValue(r.Header, \"Connection\", \"upgrade\") {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, badHandshake+\"'upgrade' token not found in 'Connection' header\")\n\t}\n\n\tif !tokenListContainsValue(r.Header, \"Upgrade\", \"websocket\") {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, badHandshake+\"'websocket' token not found in 'Upgrade' header\")\n\t}\n\n\tif r.Method != \"GET\" {\n\t\treturn u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+\"request method is not GET\")\n\t}\n\n\tif !tokenListContainsValue(r.Header, \"Sec-Websocket-Version\", \"13\") {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, \"websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header\")\n\t}\n\n\tif _, ok := responseHeader[\"Sec-Websocket-Extensions\"]; ok {\n\t\treturn u.returnError(w, r, http.StatusInternalServerError, \"websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported\")\n\t}\n\n\tcheckOrigin := u.CheckOrigin\n\tif checkOrigin == nil {\n\t\tcheckOrigin = checkSameOrigin\n\t}\n\tif !checkOrigin(r) {\n\t\treturn u.returnError(w, r, http.StatusForbidden, \"websocket: request origin not allowed by Upgrader.CheckOrigin\")\n\t}\n\n\tchallengeKey := r.Header.Get(\"Sec-Websocket-Key\")\n\tif challengeKey == \"\" {\n\t\treturn u.returnError(w, r, http.StatusBadRequest, \"websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank\")\n\t}\n\n\tsubprotocol := u.selectSubprotocol(r, responseHeader)\n\n\t// Negotiate PMCE\n\tvar compress bool\n\tif u.EnableCompression {\n\t\tfor _, ext := range parseExtensions(r.Header) {\n\t\t\tif ext[\"\"] != \"permessage-deflate\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcompress = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\th, ok := w.(http.Hijacker)\n\tif !ok {\n\t\treturn u.returnError(w, r, http.StatusInternalServerError, \"websocket: response does not implement http.Hijacker\")\n\t}\n\tvar brw *bufio.ReadWriter\n\tnetConn, brw, err := h.Hijack()\n\tif err != nil {\n\t\treturn u.returnError(w, r, http.StatusInternalServerError, err.Error())\n\t}\n\n\tif brw.Reader.Buffered() > 0 {\n\t\tnetConn.Close()\n\t\treturn nil, errors.New(\"websocket: client sent data before handshake is complete\")\n\t}\n\n\tvar br *bufio.Reader\n\tif u.ReadBufferSize == 0 && bufioReaderSize(netConn, brw.Reader) > 256 {\n\t\t// Reuse hijacked buffered reader as connection reader.\n\t\tbr = brw.Reader\n\t}\n\n\tbuf := bufioWriterBuffer(netConn, brw.Writer)\n\n\tvar writeBuf []byte\n\tif u.WriteBufferPool == nil && u.WriteBufferSize == 0 && len(buf) >= maxFrameHeaderSize+256 {\n\t\t// Reuse hijacked write buffer as connection buffer.\n\t\twriteBuf = buf\n\t}\n\n\tc := newConn(netConn, true, u.ReadBufferSize, u.WriteBufferSize, u.WriteBufferPool, br, writeBuf)\n\tc.subprotocol = subprotocol\n\n\tif compress {\n\t\tc.newCompressionWriter = compressNoContextTakeover\n\t\tc.newDecompressionReader = decompressNoContextTakeover\n\t}\n\n\t// Use larger of hijacked buffer and connection write buffer for header.\n\tp := buf\n\tif len(c.writeBuf) > len(p) {\n\t\tp = c.writeBuf\n\t}\n\tp = p[:0]\n\n\tp = append(p, \"HTTP/1.1 101 Switching Protocols\\r\\nUpgrade: websocket\\r\\nConnection: Upgrade\\r\\nSec-WebSocket-Accept: \"...)\n\tp = append(p, computeAcceptKey(challengeKey)...)\n\tp = append(p, \"\\r\\n\"...)\n\tif c.subprotocol != \"\" {\n\t\tp = append(p, \"Sec-WebSocket-Protocol: \"...)\n\t\tp = append(p, c.subprotocol...)\n\t\tp = append(p, \"\\r\\n\"...)\n\t}\n\tif compress {\n\t\tp = append(p, \"Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover\\r\\n\"...)\n\t}\n\tfor k, vs := range responseHeader {\n\t\tif k == \"Sec-Websocket-Protocol\" {\n\t\t\tcontinue\n\t\t}\n\t\tfor _, v := range vs {\n\t\t\tp = append(p, k...)\n\t\t\tp = append(p, \": \"...)\n\t\t\tfor i := 0; i < len(v); i++ {\n\t\t\t\tb := v[i]\n\t\t\t\tif b <= 31 {\n\t\t\t\t\t// prevent response splitting.\n\t\t\t\t\tb = ' '\n\t\t\t\t}\n\t\t\t\tp = append(p, b)\n\t\t\t}\n\t\t\tp = append(p, \"\\r\\n\"...)\n\t\t}\n\t}\n\tp = append(p, \"\\r\\n\"...)\n\n\t// Clear deadlines set by HTTP server.\n\tnetConn.SetDeadline(time.Time{})\n\n\tif u.HandshakeTimeout > 0 {\n\t\tnetConn.SetWriteDeadline(time.Now().Add(u.HandshakeTimeout))\n\t}\n\tif _, err = netConn.Write(p); err != nil {\n\t\tnetConn.Close()\n\t\treturn nil, err\n\t}\n\tif u.HandshakeTimeout > 0 {\n\t\tnetConn.SetWriteDeadline(time.Time{})\n\t}\n\n\treturn c, nil\n}\n\n// Upgrade upgrades the HTTP server connection to the WebSocket protocol.\n//\n// Deprecated: Use websocket.Upgrader instead.\n//\n// Upgrade does not perform origin checking. The application is responsible for\n// checking the Origin header before calling Upgrade. An example implementation\n// of the same origin policy check is:\n//\n//\tif req.Header.Get(\"Origin\") != \"http://\"+req.Host {\n//\t\thttp.Error(w, \"Origin not allowed\", http.StatusForbidden)\n//\t\treturn\n//\t}\n//\n// If the endpoint supports subprotocols, then the application is responsible\n// for negotiating the protocol used on the connection. Use the Subprotocols()\n// function to get the subprotocols requested by the client. Use the\n// Sec-Websocket-Protocol response header to specify the subprotocol selected\n// by the application.\n//\n// The responseHeader is included in the response to the client's upgrade\n// request. Use the responseHeader to specify cookies (Set-Cookie) and the\n// negotiated subprotocol (Sec-Websocket-Protocol).\n//\n// The connection buffers IO to the underlying network connection. The\n// readBufSize and writeBufSize parameters specify the size of the buffers to\n// use. Messages can be larger than the buffers.\n//\n// If the request is not a valid WebSocket handshake, then Upgrade returns an\n// error of type HandshakeError. Applications should handle this error by\n// replying to the client with an HTTP error response.\nfunc Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header, readBufSize, writeBufSize int) (*Conn, error) {\n\tu := Upgrader{ReadBufferSize: readBufSize, WriteBufferSize: writeBufSize}\n\tu.Error = func(w http.ResponseWriter, r *http.Request, status int, reason error) {\n\t\t// don't return errors to maintain backwards compatibility\n\t}\n\tu.CheckOrigin = func(r *http.Request) bool {\n\t\t// allow all connections by default\n\t\treturn true\n\t}\n\treturn u.Upgrade(w, r, responseHeader)\n}\n\n// Subprotocols returns the subprotocols requested by the client in the\n// Sec-Websocket-Protocol header.\nfunc Subprotocols(r *http.Request) []string {\n\th := strings.TrimSpace(r.Header.Get(\"Sec-Websocket-Protocol\"))\n\tif h == \"\" {\n\t\treturn nil\n\t}\n\tprotocols := strings.Split(h, \",\")\n\tfor i := range protocols {\n\t\tprotocols[i] = strings.TrimSpace(protocols[i])\n\t}\n\treturn protocols\n}\n\n// IsWebSocketUpgrade returns true if the client requested upgrade to the\n// WebSocket protocol.\nfunc IsWebSocketUpgrade(r *http.Request) bool {\n\treturn tokenListContainsValue(r.Header, \"Connection\", \"upgrade\") &&\n\t\ttokenListContainsValue(r.Header, \"Upgrade\", \"websocket\")\n}\n\n// bufioReaderSize size returns the size of a bufio.Reader.\nfunc bufioReaderSize(originalReader io.Reader, br *bufio.Reader) int {\n\t// This code assumes that peek on a reset reader returns\n\t// bufio.Reader.buf[:0].\n\t// TODO: Use bufio.Reader.Size() after Go 1.10\n\tbr.Reset(originalReader)\n\tif p, err := br.Peek(0); err == nil {\n\t\treturn cap(p)\n\t}\n\treturn 0\n}\n\n// writeHook is an io.Writer that records the last slice passed to it vio\n// io.Writer.Write.\ntype writeHook struct {\n\tp []byte\n}\n\nfunc (wh *writeHook) Write(p []byte) (int, error) {\n\twh.p = p\n\treturn len(p), nil\n}\n\n// bufioWriterBuffer grabs the buffer from a bufio.Writer.\nfunc bufioWriterBuffer(originalWriter io.Writer, bw *bufio.Writer) []byte {\n\t// This code assumes that bufio.Writer.buf[:1] is passed to the\n\t// bufio.Writer's underlying writer.\n\tvar wh writeHook\n\tbw.Reset(&wh)\n\tbw.WriteByte(0)\n\tbw.Flush()\n\n\tbw.Reset(originalWriter)\n\n\treturn wh.p[:cap(wh.p)]\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/trace.go",
    "content": "// +build go1.8\n\npackage websocket\n\nimport (\n\t\"crypto/tls\"\n\t\"net/http/httptrace\"\n)\n\nfunc doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error {\n\tif trace.TLSHandshakeStart != nil {\n\t\ttrace.TLSHandshakeStart()\n\t}\n\terr := doHandshake(tlsConn, cfg)\n\tif trace.TLSHandshakeDone != nil {\n\t\ttrace.TLSHandshakeDone(tlsConn.ConnectionState(), err)\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/trace_17.go",
    "content": "// +build !go1.8\n\npackage websocket\n\nimport (\n\t\"crypto/tls\"\n\t\"net/http/httptrace\"\n)\n\nfunc doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error {\n\treturn doHandshake(tlsConn, cfg)\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/util.go",
    "content": "// Copyright 2013 The Gorilla WebSocket 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 websocket\n\nimport (\n\t\"crypto/rand\"\n\t\"crypto/sha1\"\n\t\"encoding/base64\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nvar keyGUID = []byte(\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\")\n\nfunc computeAcceptKey(challengeKey string) string {\n\th := sha1.New()\n\th.Write([]byte(challengeKey))\n\th.Write(keyGUID)\n\treturn base64.StdEncoding.EncodeToString(h.Sum(nil))\n}\n\nfunc generateChallengeKey() (string, error) {\n\tp := make([]byte, 16)\n\tif _, err := io.ReadFull(rand.Reader, p); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn base64.StdEncoding.EncodeToString(p), nil\n}\n\n// Token octets per RFC 2616.\nvar isTokenOctet = [256]bool{\n\t'!':  true,\n\t'#':  true,\n\t'$':  true,\n\t'%':  true,\n\t'&':  true,\n\t'\\'': true,\n\t'*':  true,\n\t'+':  true,\n\t'-':  true,\n\t'.':  true,\n\t'0':  true,\n\t'1':  true,\n\t'2':  true,\n\t'3':  true,\n\t'4':  true,\n\t'5':  true,\n\t'6':  true,\n\t'7':  true,\n\t'8':  true,\n\t'9':  true,\n\t'A':  true,\n\t'B':  true,\n\t'C':  true,\n\t'D':  true,\n\t'E':  true,\n\t'F':  true,\n\t'G':  true,\n\t'H':  true,\n\t'I':  true,\n\t'J':  true,\n\t'K':  true,\n\t'L':  true,\n\t'M':  true,\n\t'N':  true,\n\t'O':  true,\n\t'P':  true,\n\t'Q':  true,\n\t'R':  true,\n\t'S':  true,\n\t'T':  true,\n\t'U':  true,\n\t'W':  true,\n\t'V':  true,\n\t'X':  true,\n\t'Y':  true,\n\t'Z':  true,\n\t'^':  true,\n\t'_':  true,\n\t'`':  true,\n\t'a':  true,\n\t'b':  true,\n\t'c':  true,\n\t'd':  true,\n\t'e':  true,\n\t'f':  true,\n\t'g':  true,\n\t'h':  true,\n\t'i':  true,\n\t'j':  true,\n\t'k':  true,\n\t'l':  true,\n\t'm':  true,\n\t'n':  true,\n\t'o':  true,\n\t'p':  true,\n\t'q':  true,\n\t'r':  true,\n\t's':  true,\n\t't':  true,\n\t'u':  true,\n\t'v':  true,\n\t'w':  true,\n\t'x':  true,\n\t'y':  true,\n\t'z':  true,\n\t'|':  true,\n\t'~':  true,\n}\n\n// skipSpace returns a slice of the string s with all leading RFC 2616 linear\n// whitespace removed.\nfunc skipSpace(s string) (rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif b := s[i]; b != ' ' && b != '\\t' {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[i:]\n}\n\n// nextToken returns the leading RFC 2616 token of s and the string following\n// the token.\nfunc nextToken(s string) (token, rest string) {\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif !isTokenOctet[s[i]] {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn s[:i], s[i:]\n}\n\n// nextTokenOrQuoted returns the leading token or quoted string per RFC 2616\n// and the string following the token or quoted string.\nfunc nextTokenOrQuoted(s string) (value string, rest string) {\n\tif !strings.HasPrefix(s, \"\\\"\") {\n\t\treturn nextToken(s)\n\t}\n\ts = s[1:]\n\tfor i := 0; i < len(s); i++ {\n\t\tswitch s[i] {\n\t\tcase '\"':\n\t\t\treturn s[:i], s[i+1:]\n\t\tcase '\\\\':\n\t\t\tp := make([]byte, len(s)-1)\n\t\t\tj := copy(p, s[:i])\n\t\t\tescape := true\n\t\t\tfor i = i + 1; i < len(s); i++ {\n\t\t\t\tb := s[i]\n\t\t\t\tswitch {\n\t\t\t\tcase escape:\n\t\t\t\t\tescape = false\n\t\t\t\t\tp[j] = b\n\t\t\t\t\tj++\n\t\t\t\tcase b == '\\\\':\n\t\t\t\t\tescape = true\n\t\t\t\tcase b == '\"':\n\t\t\t\t\treturn string(p[:j]), s[i+1:]\n\t\t\t\tdefault:\n\t\t\t\t\tp[j] = b\n\t\t\t\t\tj++\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn \"\", \"\"\n\t\t}\n\t}\n\treturn \"\", \"\"\n}\n\n// equalASCIIFold returns true if s is equal to t with ASCII case folding as\n// defined in RFC 4790.\nfunc equalASCIIFold(s, t string) bool {\n\tfor s != \"\" && t != \"\" {\n\t\tsr, size := utf8.DecodeRuneInString(s)\n\t\ts = s[size:]\n\t\ttr, size := utf8.DecodeRuneInString(t)\n\t\tt = t[size:]\n\t\tif sr == tr {\n\t\t\tcontinue\n\t\t}\n\t\tif 'A' <= sr && sr <= 'Z' {\n\t\t\tsr = sr + 'a' - 'A'\n\t\t}\n\t\tif 'A' <= tr && tr <= 'Z' {\n\t\t\ttr = tr + 'a' - 'A'\n\t\t}\n\t\tif sr != tr {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn s == t\n}\n\n// tokenListContainsValue returns true if the 1#token header with the given\n// name contains a token equal to value with ASCII case folding.\nfunc tokenListContainsValue(header http.Header, name string, value string) bool {\nheaders:\n\tfor _, s := range header[name] {\n\t\tfor {\n\t\t\tvar t string\n\t\t\tt, s = nextToken(skipSpace(s))\n\t\t\tif t == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\ts = skipSpace(s)\n\t\t\tif s != \"\" && s[0] != ',' {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\tif equalASCIIFold(t, value) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif s == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\ts = s[1:]\n\t\t}\n\t}\n\treturn false\n}\n\n// parseExtensions parses WebSocket extensions from a header.\nfunc parseExtensions(header http.Header) []map[string]string {\n\t// From RFC 6455:\n\t//\n\t//  Sec-WebSocket-Extensions = extension-list\n\t//  extension-list = 1#extension\n\t//  extension = extension-token *( \";\" extension-param )\n\t//  extension-token = registered-token\n\t//  registered-token = token\n\t//  extension-param = token [ \"=\" (token | quoted-string) ]\n\t//     ;When using the quoted-string syntax variant, the value\n\t//     ;after quoted-string unescaping MUST conform to the\n\t//     ;'token' ABNF.\n\n\tvar result []map[string]string\nheaders:\n\tfor _, s := range header[\"Sec-Websocket-Extensions\"] {\n\t\tfor {\n\t\t\tvar t string\n\t\t\tt, s = nextToken(skipSpace(s))\n\t\t\tif t == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\text := map[string]string{\"\": t}\n\t\t\tfor {\n\t\t\t\ts = skipSpace(s)\n\t\t\t\tif !strings.HasPrefix(s, \";\") {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tvar k string\n\t\t\t\tk, s = nextToken(skipSpace(s[1:]))\n\t\t\t\tif k == \"\" {\n\t\t\t\t\tcontinue headers\n\t\t\t\t}\n\t\t\t\ts = skipSpace(s)\n\t\t\t\tvar v string\n\t\t\t\tif strings.HasPrefix(s, \"=\") {\n\t\t\t\t\tv, s = nextTokenOrQuoted(skipSpace(s[1:]))\n\t\t\t\t\ts = skipSpace(s)\n\t\t\t\t}\n\t\t\t\tif s != \"\" && s[0] != ',' && s[0] != ';' {\n\t\t\t\t\tcontinue headers\n\t\t\t\t}\n\t\t\t\text[k] = v\n\t\t\t}\n\t\t\tif s != \"\" && s[0] != ',' {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\tresult = append(result, ext)\n\t\t\tif s == \"\" {\n\t\t\t\tcontinue headers\n\t\t\t}\n\t\t\ts = s[1:]\n\t\t}\n\t}\n\treturn result\n}\n"
  },
  {
    "path": "vendor/github.com/gorilla/websocket/x_net_proxy.go",
    "content": "// Code generated by golang.org/x/tools/cmd/bundle. DO NOT EDIT.\n//go:generate bundle -o x_net_proxy.go golang.org/x/net/proxy\n\n// Package proxy provides support for a variety of protocols to proxy network\n// data.\n//\n\npackage websocket\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"net\"\n\t\"net/url\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\ntype proxy_direct struct{}\n\n// Direct is a direct proxy: one that makes network connections directly.\nvar proxy_Direct = proxy_direct{}\n\nfunc (proxy_direct) Dial(network, addr string) (net.Conn, error) {\n\treturn net.Dial(network, addr)\n}\n\n// A PerHost directs connections to a default Dialer unless the host name\n// requested matches one of a number of exceptions.\ntype proxy_PerHost struct {\n\tdef, bypass proxy_Dialer\n\n\tbypassNetworks []*net.IPNet\n\tbypassIPs      []net.IP\n\tbypassZones    []string\n\tbypassHosts    []string\n}\n\n// NewPerHost returns a PerHost Dialer that directs connections to either\n// defaultDialer or bypass, depending on whether the connection matches one of\n// the configured rules.\nfunc proxy_NewPerHost(defaultDialer, bypass proxy_Dialer) *proxy_PerHost {\n\treturn &proxy_PerHost{\n\t\tdef:    defaultDialer,\n\t\tbypass: bypass,\n\t}\n}\n\n// Dial connects to the address addr on the given network through either\n// defaultDialer or bypass.\nfunc (p *proxy_PerHost) Dial(network, addr string) (c net.Conn, err error) {\n\thost, _, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn p.dialerForRequest(host).Dial(network, addr)\n}\n\nfunc (p *proxy_PerHost) dialerForRequest(host string) proxy_Dialer {\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tfor _, net := range p.bypassNetworks {\n\t\t\tif net.Contains(ip) {\n\t\t\t\treturn p.bypass\n\t\t\t}\n\t\t}\n\t\tfor _, bypassIP := range p.bypassIPs {\n\t\t\tif bypassIP.Equal(ip) {\n\t\t\t\treturn p.bypass\n\t\t\t}\n\t\t}\n\t\treturn p.def\n\t}\n\n\tfor _, zone := range p.bypassZones {\n\t\tif strings.HasSuffix(host, zone) {\n\t\t\treturn p.bypass\n\t\t}\n\t\tif host == zone[1:] {\n\t\t\t// For a zone \".example.com\", we match \"example.com\"\n\t\t\t// too.\n\t\t\treturn p.bypass\n\t\t}\n\t}\n\tfor _, bypassHost := range p.bypassHosts {\n\t\tif bypassHost == host {\n\t\t\treturn p.bypass\n\t\t}\n\t}\n\treturn p.def\n}\n\n// AddFromString parses a string that contains comma-separated values\n// specifying hosts that should use the bypass proxy. Each value is either an\n// IP address, a CIDR range, a zone (*.example.com) or a host name\n// (localhost). A best effort is made to parse the string and errors are\n// ignored.\nfunc (p *proxy_PerHost) AddFromString(s string) {\n\thosts := strings.Split(s, \",\")\n\tfor _, host := range hosts {\n\t\thost = strings.TrimSpace(host)\n\t\tif len(host) == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.Contains(host, \"/\") {\n\t\t\t// We assume that it's a CIDR address like 127.0.0.0/8\n\t\t\tif _, net, err := net.ParseCIDR(host); err == nil {\n\t\t\t\tp.AddNetwork(net)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif ip := net.ParseIP(host); ip != nil {\n\t\t\tp.AddIP(ip)\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(host, \"*.\") {\n\t\t\tp.AddZone(host[1:])\n\t\t\tcontinue\n\t\t}\n\t\tp.AddHost(host)\n\t}\n}\n\n// AddIP specifies an IP address that will use the bypass proxy. Note that\n// this will only take effect if a literal IP address is dialed. A connection\n// to a named host will never match an IP.\nfunc (p *proxy_PerHost) AddIP(ip net.IP) {\n\tp.bypassIPs = append(p.bypassIPs, ip)\n}\n\n// AddNetwork specifies an IP range that will use the bypass proxy. Note that\n// this will only take effect if a literal IP address is dialed. A connection\n// to a named host will never match.\nfunc (p *proxy_PerHost) AddNetwork(net *net.IPNet) {\n\tp.bypassNetworks = append(p.bypassNetworks, net)\n}\n\n// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of\n// \"example.com\" matches \"example.com\" and all of its subdomains.\nfunc (p *proxy_PerHost) AddZone(zone string) {\n\tif strings.HasSuffix(zone, \".\") {\n\t\tzone = zone[:len(zone)-1]\n\t}\n\tif !strings.HasPrefix(zone, \".\") {\n\t\tzone = \".\" + zone\n\t}\n\tp.bypassZones = append(p.bypassZones, zone)\n}\n\n// AddHost specifies a host name that will use the bypass proxy.\nfunc (p *proxy_PerHost) AddHost(host string) {\n\tif strings.HasSuffix(host, \".\") {\n\t\thost = host[:len(host)-1]\n\t}\n\tp.bypassHosts = append(p.bypassHosts, host)\n}\n\n// A Dialer is a means to establish a connection.\ntype proxy_Dialer interface {\n\t// Dial connects to the given address via the proxy.\n\tDial(network, addr string) (c net.Conn, err error)\n}\n\n// Auth contains authentication parameters that specific Dialers may require.\ntype proxy_Auth struct {\n\tUser, Password string\n}\n\n// FromEnvironment returns the dialer specified by the proxy related variables in\n// the environment.\nfunc proxy_FromEnvironment() proxy_Dialer {\n\tallProxy := proxy_allProxyEnv.Get()\n\tif len(allProxy) == 0 {\n\t\treturn proxy_Direct\n\t}\n\n\tproxyURL, err := url.Parse(allProxy)\n\tif err != nil {\n\t\treturn proxy_Direct\n\t}\n\tproxy, err := proxy_FromURL(proxyURL, proxy_Direct)\n\tif err != nil {\n\t\treturn proxy_Direct\n\t}\n\n\tnoProxy := proxy_noProxyEnv.Get()\n\tif len(noProxy) == 0 {\n\t\treturn proxy\n\t}\n\n\tperHost := proxy_NewPerHost(proxy, proxy_Direct)\n\tperHost.AddFromString(noProxy)\n\treturn perHost\n}\n\n// proxySchemes is a map from URL schemes to a function that creates a Dialer\n// from a URL with such a scheme.\nvar proxy_proxySchemes map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error)\n\n// RegisterDialerType takes a URL scheme and a function to generate Dialers from\n// a URL with that scheme and a forwarding Dialer. Registered schemes are used\n// by FromURL.\nfunc proxy_RegisterDialerType(scheme string, f func(*url.URL, proxy_Dialer) (proxy_Dialer, error)) {\n\tif proxy_proxySchemes == nil {\n\t\tproxy_proxySchemes = make(map[string]func(*url.URL, proxy_Dialer) (proxy_Dialer, error))\n\t}\n\tproxy_proxySchemes[scheme] = f\n}\n\n// FromURL returns a Dialer given a URL specification and an underlying\n// Dialer for it to make network requests.\nfunc proxy_FromURL(u *url.URL, forward proxy_Dialer) (proxy_Dialer, error) {\n\tvar auth *proxy_Auth\n\tif u.User != nil {\n\t\tauth = new(proxy_Auth)\n\t\tauth.User = u.User.Username()\n\t\tif p, ok := u.User.Password(); ok {\n\t\t\tauth.Password = p\n\t\t}\n\t}\n\n\tswitch u.Scheme {\n\tcase \"socks5\":\n\t\treturn proxy_SOCKS5(\"tcp\", u.Host, auth, forward)\n\t}\n\n\t// If the scheme doesn't match any of the built-in schemes, see if it\n\t// was registered by another package.\n\tif proxy_proxySchemes != nil {\n\t\tif f, ok := proxy_proxySchemes[u.Scheme]; ok {\n\t\t\treturn f(u, forward)\n\t\t}\n\t}\n\n\treturn nil, errors.New(\"proxy: unknown scheme: \" + u.Scheme)\n}\n\nvar (\n\tproxy_allProxyEnv = &proxy_envOnce{\n\t\tnames: []string{\"ALL_PROXY\", \"all_proxy\"},\n\t}\n\tproxy_noProxyEnv = &proxy_envOnce{\n\t\tnames: []string{\"NO_PROXY\", \"no_proxy\"},\n\t}\n)\n\n// envOnce looks up an environment variable (optionally by multiple\n// names) once. It mitigates expensive lookups on some platforms\n// (e.g. Windows).\n// (Borrowed from net/http/transport.go)\ntype proxy_envOnce struct {\n\tnames []string\n\tonce  sync.Once\n\tval   string\n}\n\nfunc (e *proxy_envOnce) Get() string {\n\te.once.Do(e.init)\n\treturn e.val\n}\n\nfunc (e *proxy_envOnce) init() {\n\tfor _, n := range e.names {\n\t\te.val = os.Getenv(n)\n\t\tif e.val != \"\" {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address\n// with an optional username and password. See RFC 1928 and RFC 1929.\nfunc proxy_SOCKS5(network, addr string, auth *proxy_Auth, forward proxy_Dialer) (proxy_Dialer, error) {\n\ts := &proxy_socks5{\n\t\tnetwork: network,\n\t\taddr:    addr,\n\t\tforward: forward,\n\t}\n\tif auth != nil {\n\t\ts.user = auth.User\n\t\ts.password = auth.Password\n\t}\n\n\treturn s, nil\n}\n\ntype proxy_socks5 struct {\n\tuser, password string\n\tnetwork, addr  string\n\tforward        proxy_Dialer\n}\n\nconst proxy_socks5Version = 5\n\nconst (\n\tproxy_socks5AuthNone     = 0\n\tproxy_socks5AuthPassword = 2\n)\n\nconst proxy_socks5Connect = 1\n\nconst (\n\tproxy_socks5IP4    = 1\n\tproxy_socks5Domain = 3\n\tproxy_socks5IP6    = 4\n)\n\nvar proxy_socks5Errors = []string{\n\t\"\",\n\t\"general failure\",\n\t\"connection forbidden\",\n\t\"network unreachable\",\n\t\"host unreachable\",\n\t\"connection refused\",\n\t\"TTL expired\",\n\t\"command not supported\",\n\t\"address type not supported\",\n}\n\n// Dial connects to the address addr on the given network via the SOCKS5 proxy.\nfunc (s *proxy_socks5) Dial(network, addr string) (net.Conn, error) {\n\tswitch network {\n\tcase \"tcp\", \"tcp6\", \"tcp4\":\n\tdefault:\n\t\treturn nil, errors.New(\"proxy: no support for SOCKS5 proxy connections of type \" + network)\n\t}\n\n\tconn, err := s.forward.Dial(s.network, s.addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err := s.connect(conn, addr); err != nil {\n\t\tconn.Close()\n\t\treturn nil, err\n\t}\n\treturn conn, nil\n}\n\n// connect takes an existing connection to a socks5 proxy server,\n// and commands the server to extend that connection to target,\n// which must be a canonical address with a host and port.\nfunc (s *proxy_socks5) connect(conn net.Conn, target string) error {\n\thost, portStr, err := net.SplitHostPort(target)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tport, err := strconv.Atoi(portStr)\n\tif err != nil {\n\t\treturn errors.New(\"proxy: failed to parse port number: \" + portStr)\n\t}\n\tif port < 1 || port > 0xffff {\n\t\treturn errors.New(\"proxy: port number out of range: \" + portStr)\n\t}\n\n\t// the size here is just an estimate\n\tbuf := make([]byte, 0, 6+len(host))\n\n\tbuf = append(buf, proxy_socks5Version)\n\tif len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 {\n\t\tbuf = append(buf, 2 /* num auth methods */, proxy_socks5AuthNone, proxy_socks5AuthPassword)\n\t} else {\n\t\tbuf = append(buf, 1 /* num auth methods */, proxy_socks5AuthNone)\n\t}\n\n\tif _, err := conn.Write(buf); err != nil {\n\t\treturn errors.New(\"proxy: failed to write greeting to SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\tif _, err := io.ReadFull(conn, buf[:2]); err != nil {\n\t\treturn errors.New(\"proxy: failed to read greeting from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\tif buf[0] != 5 {\n\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" has unexpected version \" + strconv.Itoa(int(buf[0])))\n\t}\n\tif buf[1] == 0xff {\n\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" requires authentication\")\n\t}\n\n\t// See RFC 1929\n\tif buf[1] == proxy_socks5AuthPassword {\n\t\tbuf = buf[:0]\n\t\tbuf = append(buf, 1 /* password protocol version */)\n\t\tbuf = append(buf, uint8(len(s.user)))\n\t\tbuf = append(buf, s.user...)\n\t\tbuf = append(buf, uint8(len(s.password)))\n\t\tbuf = append(buf, s.password...)\n\n\t\tif _, err := conn.Write(buf); err != nil {\n\t\t\treturn errors.New(\"proxy: failed to write authentication request to SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t\t}\n\n\t\tif _, err := io.ReadFull(conn, buf[:2]); err != nil {\n\t\t\treturn errors.New(\"proxy: failed to read authentication reply from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t\t}\n\n\t\tif buf[1] != 0 {\n\t\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" rejected username/password\")\n\t\t}\n\t}\n\n\tbuf = buf[:0]\n\tbuf = append(buf, proxy_socks5Version, proxy_socks5Connect, 0 /* reserved */)\n\n\tif ip := net.ParseIP(host); ip != nil {\n\t\tif ip4 := ip.To4(); ip4 != nil {\n\t\t\tbuf = append(buf, proxy_socks5IP4)\n\t\t\tip = ip4\n\t\t} else {\n\t\t\tbuf = append(buf, proxy_socks5IP6)\n\t\t}\n\t\tbuf = append(buf, ip...)\n\t} else {\n\t\tif len(host) > 255 {\n\t\t\treturn errors.New(\"proxy: destination host name too long: \" + host)\n\t\t}\n\t\tbuf = append(buf, proxy_socks5Domain)\n\t\tbuf = append(buf, byte(len(host)))\n\t\tbuf = append(buf, host...)\n\t}\n\tbuf = append(buf, byte(port>>8), byte(port))\n\n\tif _, err := conn.Write(buf); err != nil {\n\t\treturn errors.New(\"proxy: failed to write connect request to SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\tif _, err := io.ReadFull(conn, buf[:4]); err != nil {\n\t\treturn errors.New(\"proxy: failed to read connect reply from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\tfailure := \"unknown error\"\n\tif int(buf[1]) < len(proxy_socks5Errors) {\n\t\tfailure = proxy_socks5Errors[buf[1]]\n\t}\n\n\tif len(failure) > 0 {\n\t\treturn errors.New(\"proxy: SOCKS5 proxy at \" + s.addr + \" failed to connect: \" + failure)\n\t}\n\n\tbytesToDiscard := 0\n\tswitch buf[3] {\n\tcase proxy_socks5IP4:\n\t\tbytesToDiscard = net.IPv4len\n\tcase proxy_socks5IP6:\n\t\tbytesToDiscard = net.IPv6len\n\tcase proxy_socks5Domain:\n\t\t_, err := io.ReadFull(conn, buf[:1])\n\t\tif err != nil {\n\t\t\treturn errors.New(\"proxy: failed to read domain length from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t\t}\n\t\tbytesToDiscard = int(buf[0])\n\tdefault:\n\t\treturn errors.New(\"proxy: got unknown address type \" + strconv.Itoa(int(buf[3])) + \" from SOCKS5 proxy at \" + s.addr)\n\t}\n\n\tif cap(buf) < bytesToDiscard {\n\t\tbuf = make([]byte, bytesToDiscard)\n\t} else {\n\t\tbuf = buf[:bytesToDiscard]\n\t}\n\tif _, err := io.ReadFull(conn, buf); err != nil {\n\t\treturn errors.New(\"proxy: failed to read address from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\t// Also need to discard the port number\n\tif _, err := io.ReadFull(conn, buf[:2]); err != nil {\n\t\treturn errors.New(\"proxy: failed to read port from SOCKS5 proxy at \" + s.addr + \": \" + err.Error())\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/gregjones/httpcache/.travis.yml",
    "content": "sudo: false\nlanguage: go\ngo:\n  - 1.6.x\n  - 1.7.x\n  - 1.8.x\n  - 1.9.x\n  - master\nmatrix:\n  allow_failures:\n    - go: master\n  fast_finish: true\ninstall:\n  - # Do nothing. This is needed to prevent default install action \"go get -t -v ./...\" from happening here (we want it to happen inside script step).\nscript:\n  - go get -t -v ./...\n  - diff -u <(echo -n) <(gofmt -d .)\n  - go tool vet .\n  - go test -v -race ./...\n"
  },
  {
    "path": "vendor/github.com/gregjones/httpcache/LICENSE.txt",
    "content": "Copyright © 2012 Greg Jones (greg.jones@gmail.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "vendor/github.com/gregjones/httpcache/README.md",
    "content": "httpcache\n=========\n\n[![Build Status](https://travis-ci.org/gregjones/httpcache.svg?branch=master)](https://travis-ci.org/gregjones/httpcache) [![GoDoc](https://godoc.org/github.com/gregjones/httpcache?status.svg)](https://godoc.org/github.com/gregjones/httpcache)\n\nPackage httpcache provides a http.RoundTripper implementation that works as a mostly [RFC 7234](https://tools.ietf.org/html/rfc7234) compliant cache for http responses.\n\nIt is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client and not for a shared proxy).\n\nCache Backends\n--------------\n\n- The built-in 'memory' cache stores responses in an in-memory map.\n- [`github.com/gregjones/httpcache/diskcache`](https://github.com/gregjones/httpcache/tree/master/diskcache) provides a filesystem-backed cache using the [diskv](https://github.com/peterbourgon/diskv) library.\n- [`github.com/gregjones/httpcache/memcache`](https://github.com/gregjones/httpcache/tree/master/memcache) provides memcache implementations, for both App Engine and 'normal' memcache servers.\n- [`sourcegraph.com/sourcegraph/s3cache`](https://sourcegraph.com/github.com/sourcegraph/s3cache) uses Amazon S3 for storage.\n- [`github.com/gregjones/httpcache/leveldbcache`](https://github.com/gregjones/httpcache/tree/master/leveldbcache) provides a filesystem-backed cache using [leveldb](https://github.com/syndtr/goleveldb/leveldb).\n- [`github.com/die-net/lrucache`](https://github.com/die-net/lrucache) provides an in-memory cache that will evict least-recently used entries.\n- [`github.com/die-net/lrucache/twotier`](https://github.com/die-net/lrucache/tree/master/twotier) allows caches to be combined, for example to use lrucache above with a persistent disk-cache.\n- [`github.com/birkelund/boltdbcache`](https://github.com/birkelund/boltdbcache) provides a BoltDB implementation (based on the [bbolt](https://github.com/coreos/bbolt) fork).\n\nLicense\n-------\n\n-\t[MIT License](LICENSE.txt)\n"
  },
  {
    "path": "vendor/github.com/gregjones/httpcache/httpcache.go",
    "content": "// Package httpcache provides a http.RoundTripper implementation that works as a\n// mostly RFC-compliant cache for http responses.\n//\n// It is only suitable for use as a 'private' cache (i.e. for a web-browser or an API-client\n// and not for a shared proxy).\n//\npackage httpcache\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"net/http/httputil\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\nconst (\n\tstale = iota\n\tfresh\n\ttransparent\n\t// XFromCache is the header added to responses that are returned from the cache\n\tXFromCache = \"X-From-Cache\"\n)\n\n// A Cache interface is used by the Transport to store and retrieve responses.\ntype Cache interface {\n\t// Get returns the []byte representation of a cached response and a bool\n\t// set to true if the value isn't empty\n\tGet(key string) (responseBytes []byte, ok bool)\n\t// Set stores the []byte representation of a response against a key\n\tSet(key string, responseBytes []byte)\n\t// Delete removes the value associated with the key\n\tDelete(key string)\n}\n\n// cacheKey returns the cache key for req.\nfunc cacheKey(req *http.Request) string {\n\tif req.Method == http.MethodGet {\n\t\treturn req.URL.String()\n\t} else {\n\t\treturn req.Method + \" \" + req.URL.String()\n\t}\n}\n\n// CachedResponse returns the cached http.Response for req if present, and nil\n// otherwise.\nfunc CachedResponse(c Cache, req *http.Request) (resp *http.Response, err error) {\n\tcachedVal, ok := c.Get(cacheKey(req))\n\tif !ok {\n\t\treturn\n\t}\n\n\tb := bytes.NewBuffer(cachedVal)\n\treturn http.ReadResponse(bufio.NewReader(b), req)\n}\n\n// MemoryCache is an implemtation of Cache that stores responses in an in-memory map.\ntype MemoryCache struct {\n\tmu    sync.RWMutex\n\titems map[string][]byte\n}\n\n// Get returns the []byte representation of the response and true if present, false if not\nfunc (c *MemoryCache) Get(key string) (resp []byte, ok bool) {\n\tc.mu.RLock()\n\tresp, ok = c.items[key]\n\tc.mu.RUnlock()\n\treturn resp, ok\n}\n\n// Set saves response resp to the cache with key\nfunc (c *MemoryCache) Set(key string, resp []byte) {\n\tc.mu.Lock()\n\tc.items[key] = resp\n\tc.mu.Unlock()\n}\n\n// Delete removes key from the cache\nfunc (c *MemoryCache) Delete(key string) {\n\tc.mu.Lock()\n\tdelete(c.items, key)\n\tc.mu.Unlock()\n}\n\n// NewMemoryCache returns a new Cache that will store items in an in-memory map\nfunc NewMemoryCache() *MemoryCache {\n\tc := &MemoryCache{items: map[string][]byte{}}\n\treturn c\n}\n\n// Transport is an implementation of http.RoundTripper that will return values from a cache\n// where possible (avoiding a network request) and will additionally add validators (etag/if-modified-since)\n// to repeated requests allowing servers to return 304 / Not Modified\ntype Transport struct {\n\t// The RoundTripper interface actually used to make requests\n\t// If nil, http.DefaultTransport is used\n\tTransport http.RoundTripper\n\tCache     Cache\n\t// If true, responses returned from the cache will be given an extra header, X-From-Cache\n\tMarkCachedResponses bool\n}\n\n// NewTransport returns a new Transport with the\n// provided Cache implementation and MarkCachedResponses set to true\nfunc NewTransport(c Cache) *Transport {\n\treturn &Transport{Cache: c, MarkCachedResponses: true}\n}\n\n// Client returns an *http.Client that caches responses.\nfunc (t *Transport) Client() *http.Client {\n\treturn &http.Client{Transport: t}\n}\n\n// varyMatches will return false unless all of the cached values for the headers listed in Vary\n// match the new request\nfunc varyMatches(cachedResp *http.Response, req *http.Request) bool {\n\tfor _, header := range headerAllCommaSepValues(cachedResp.Header, \"vary\") {\n\t\theader = http.CanonicalHeaderKey(header)\n\t\tif header != \"\" && req.Header.Get(header) != cachedResp.Header.Get(\"X-Varied-\"+header) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// RoundTrip takes a Request and returns a Response\n//\n// If there is a fresh Response already in cache, then it will be returned without connecting to\n// the server.\n//\n// If there is a stale Response, then any validators it contains will be set on the new request\n// to give the server a chance to respond with NotModified. If this happens, then the cached Response\n// will be returned.\nfunc (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err error) {\n\tcacheKey := cacheKey(req)\n\tcacheable := (req.Method == \"GET\" || req.Method == \"HEAD\") && req.Header.Get(\"range\") == \"\"\n\tvar cachedResp *http.Response\n\tif cacheable {\n\t\tcachedResp, err = CachedResponse(t.Cache, req)\n\t} else {\n\t\t// Need to invalidate an existing value\n\t\tt.Cache.Delete(cacheKey)\n\t}\n\n\ttransport := t.Transport\n\tif transport == nil {\n\t\ttransport = http.DefaultTransport\n\t}\n\n\tif cacheable && cachedResp != nil && err == nil {\n\t\tif t.MarkCachedResponses {\n\t\t\tcachedResp.Header.Set(XFromCache, \"1\")\n\t\t}\n\n\t\tif varyMatches(cachedResp, req) {\n\t\t\t// Can only use cached value if the new request doesn't Vary significantly\n\t\t\tfreshness := getFreshness(cachedResp.Header, req.Header)\n\t\t\tif freshness == fresh {\n\t\t\t\treturn cachedResp, nil\n\t\t\t}\n\n\t\t\tif freshness == stale {\n\t\t\t\tvar req2 *http.Request\n\t\t\t\t// Add validators if caller hasn't already done so\n\t\t\t\tetag := cachedResp.Header.Get(\"etag\")\n\t\t\t\tif etag != \"\" && req.Header.Get(\"etag\") == \"\" {\n\t\t\t\t\treq2 = cloneRequest(req)\n\t\t\t\t\treq2.Header.Set(\"if-none-match\", etag)\n\t\t\t\t}\n\t\t\t\tlastModified := cachedResp.Header.Get(\"last-modified\")\n\t\t\t\tif lastModified != \"\" && req.Header.Get(\"last-modified\") == \"\" {\n\t\t\t\t\tif req2 == nil {\n\t\t\t\t\t\treq2 = cloneRequest(req)\n\t\t\t\t\t}\n\t\t\t\t\treq2.Header.Set(\"if-modified-since\", lastModified)\n\t\t\t\t}\n\t\t\t\tif req2 != nil {\n\t\t\t\t\treq = req2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tresp, err = transport.RoundTrip(req)\n\t\tif err == nil && req.Method == \"GET\" && resp.StatusCode == http.StatusNotModified {\n\t\t\t// Replace the 304 response with the one from cache, but update with some new headers\n\t\t\tendToEndHeaders := getEndToEndHeaders(resp.Header)\n\t\t\tfor _, header := range endToEndHeaders {\n\t\t\t\tcachedResp.Header[header] = resp.Header[header]\n\t\t\t}\n\t\t\tresp = cachedResp\n\t\t} else if (err != nil || (cachedResp != nil && resp.StatusCode >= 500)) &&\n\t\t\treq.Method == \"GET\" && canStaleOnError(cachedResp.Header, req.Header) {\n\t\t\t// In case of transport failure and stale-if-error activated, returns cached content\n\t\t\t// when available\n\t\t\treturn cachedResp, nil\n\t\t} else {\n\t\t\tif err != nil || resp.StatusCode != http.StatusOK {\n\t\t\t\tt.Cache.Delete(cacheKey)\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t} else {\n\t\treqCacheControl := parseCacheControl(req.Header)\n\t\tif _, ok := reqCacheControl[\"only-if-cached\"]; ok {\n\t\t\tresp = newGatewayTimeoutResponse(req)\n\t\t} else {\n\t\t\tresp, err = transport.RoundTrip(req)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t}\n\n\tif cacheable && canStore(parseCacheControl(req.Header), parseCacheControl(resp.Header)) {\n\t\tfor _, varyKey := range headerAllCommaSepValues(resp.Header, \"vary\") {\n\t\t\tvaryKey = http.CanonicalHeaderKey(varyKey)\n\t\t\tfakeHeader := \"X-Varied-\" + varyKey\n\t\t\treqValue := req.Header.Get(varyKey)\n\t\t\tif reqValue != \"\" {\n\t\t\t\tresp.Header.Set(fakeHeader, reqValue)\n\t\t\t}\n\t\t}\n\t\tswitch req.Method {\n\t\tcase \"GET\":\n\t\t\t// Delay caching until EOF is reached.\n\t\t\tresp.Body = &cachingReadCloser{\n\t\t\t\tR: resp.Body,\n\t\t\t\tOnEOF: func(r io.Reader) {\n\t\t\t\t\tresp := *resp\n\t\t\t\t\tresp.Body = ioutil.NopCloser(r)\n\t\t\t\t\trespBytes, err := httputil.DumpResponse(&resp, true)\n\t\t\t\t\tif err == nil {\n\t\t\t\t\t\tt.Cache.Set(cacheKey, respBytes)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t}\n\t\tdefault:\n\t\t\trespBytes, err := httputil.DumpResponse(resp, true)\n\t\t\tif err == nil {\n\t\t\t\tt.Cache.Set(cacheKey, respBytes)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tt.Cache.Delete(cacheKey)\n\t}\n\treturn resp, nil\n}\n\n// ErrNoDateHeader indicates that the HTTP headers contained no Date header.\nvar ErrNoDateHeader = errors.New(\"no Date header\")\n\n// Date parses and returns the value of the Date header.\nfunc Date(respHeaders http.Header) (date time.Time, err error) {\n\tdateHeader := respHeaders.Get(\"date\")\n\tif dateHeader == \"\" {\n\t\terr = ErrNoDateHeader\n\t\treturn\n\t}\n\n\treturn time.Parse(time.RFC1123, dateHeader)\n}\n\ntype realClock struct{}\n\nfunc (c *realClock) since(d time.Time) time.Duration {\n\treturn time.Since(d)\n}\n\ntype timer interface {\n\tsince(d time.Time) time.Duration\n}\n\nvar clock timer = &realClock{}\n\n// getFreshness will return one of fresh/stale/transparent based on the cache-control\n// values of the request and the response\n//\n// fresh indicates the response can be returned\n// stale indicates that the response needs validating before it is returned\n// transparent indicates the response should not be used to fulfil the request\n//\n// Because this is only a private cache, 'public' and 'private' in cache-control aren't\n// signficant. Similarly, smax-age isn't used.\nfunc getFreshness(respHeaders, reqHeaders http.Header) (freshness int) {\n\trespCacheControl := parseCacheControl(respHeaders)\n\treqCacheControl := parseCacheControl(reqHeaders)\n\tif _, ok := reqCacheControl[\"no-cache\"]; ok {\n\t\treturn transparent\n\t}\n\tif _, ok := respCacheControl[\"no-cache\"]; ok {\n\t\treturn stale\n\t}\n\tif _, ok := reqCacheControl[\"only-if-cached\"]; ok {\n\t\treturn fresh\n\t}\n\n\tdate, err := Date(respHeaders)\n\tif err != nil {\n\t\treturn stale\n\t}\n\tcurrentAge := clock.since(date)\n\n\tvar lifetime time.Duration\n\tvar zeroDuration time.Duration\n\n\t// If a response includes both an Expires header and a max-age directive,\n\t// the max-age directive overrides the Expires header, even if the Expires header is more restrictive.\n\tif maxAge, ok := respCacheControl[\"max-age\"]; ok {\n\t\tlifetime, err = time.ParseDuration(maxAge + \"s\")\n\t\tif err != nil {\n\t\t\tlifetime = zeroDuration\n\t\t}\n\t} else {\n\t\texpiresHeader := respHeaders.Get(\"Expires\")\n\t\tif expiresHeader != \"\" {\n\t\t\texpires, err := time.Parse(time.RFC1123, expiresHeader)\n\t\t\tif err != nil {\n\t\t\t\tlifetime = zeroDuration\n\t\t\t} else {\n\t\t\t\tlifetime = expires.Sub(date)\n\t\t\t}\n\t\t}\n\t}\n\n\tif maxAge, ok := reqCacheControl[\"max-age\"]; ok {\n\t\t// the client is willing to accept a response whose age is no greater than the specified time in seconds\n\t\tlifetime, err = time.ParseDuration(maxAge + \"s\")\n\t\tif err != nil {\n\t\t\tlifetime = zeroDuration\n\t\t}\n\t}\n\tif minfresh, ok := reqCacheControl[\"min-fresh\"]; ok {\n\t\t//  the client wants a response that will still be fresh for at least the specified number of seconds.\n\t\tminfreshDuration, err := time.ParseDuration(minfresh + \"s\")\n\t\tif err == nil {\n\t\t\tcurrentAge = time.Duration(currentAge + minfreshDuration)\n\t\t}\n\t}\n\n\tif maxstale, ok := reqCacheControl[\"max-stale\"]; ok {\n\t\t// Indicates that the client is willing to accept a response that has exceeded its expiration time.\n\t\t// If max-stale is assigned a value, then the client is willing to accept a response that has exceeded\n\t\t// its expiration time by no more than the specified number of seconds.\n\t\t// If no value is assigned to max-stale, then the client is willing to accept a stale response of any age.\n\t\t//\n\t\t// Responses served only because of a max-stale value are supposed to have a Warning header added to them,\n\t\t// but that seems like a  hassle, and is it actually useful? If so, then there needs to be a different\n\t\t// return-value available here.\n\t\tif maxstale == \"\" {\n\t\t\treturn fresh\n\t\t}\n\t\tmaxstaleDuration, err := time.ParseDuration(maxstale + \"s\")\n\t\tif err == nil {\n\t\t\tcurrentAge = time.Duration(currentAge - maxstaleDuration)\n\t\t}\n\t}\n\n\tif lifetime > currentAge {\n\t\treturn fresh\n\t}\n\n\treturn stale\n}\n\n// Returns true if either the request or the response includes the stale-if-error\n// cache control extension: https://tools.ietf.org/html/rfc5861\nfunc canStaleOnError(respHeaders, reqHeaders http.Header) bool {\n\trespCacheControl := parseCacheControl(respHeaders)\n\treqCacheControl := parseCacheControl(reqHeaders)\n\n\tvar err error\n\tlifetime := time.Duration(-1)\n\n\tif staleMaxAge, ok := respCacheControl[\"stale-if-error\"]; ok {\n\t\tif staleMaxAge != \"\" {\n\t\t\tlifetime, err = time.ParseDuration(staleMaxAge + \"s\")\n\t\t\tif err != nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\treturn true\n\t\t}\n\t}\n\tif staleMaxAge, ok := reqCacheControl[\"stale-if-error\"]; ok {\n\t\tif staleMaxAge != \"\" {\n\t\t\tlifetime, err = time.ParseDuration(staleMaxAge + \"s\")\n\t\t\tif err != nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\treturn true\n\t\t}\n\t}\n\n\tif lifetime >= 0 {\n\t\tdate, err := Date(respHeaders)\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\tcurrentAge := clock.since(date)\n\t\tif lifetime > currentAge {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc getEndToEndHeaders(respHeaders http.Header) []string {\n\t// These headers are always hop-by-hop\n\thopByHopHeaders := map[string]struct{}{\n\t\t\"Connection\":          struct{}{},\n\t\t\"Keep-Alive\":          struct{}{},\n\t\t\"Proxy-Authenticate\":  struct{}{},\n\t\t\"Proxy-Authorization\": struct{}{},\n\t\t\"Te\":                struct{}{},\n\t\t\"Trailers\":          struct{}{},\n\t\t\"Transfer-Encoding\": struct{}{},\n\t\t\"Upgrade\":           struct{}{},\n\t}\n\n\tfor _, extra := range strings.Split(respHeaders.Get(\"connection\"), \",\") {\n\t\t// any header listed in connection, if present, is also considered hop-by-hop\n\t\tif strings.Trim(extra, \" \") != \"\" {\n\t\t\thopByHopHeaders[http.CanonicalHeaderKey(extra)] = struct{}{}\n\t\t}\n\t}\n\tendToEndHeaders := []string{}\n\tfor respHeader, _ := range respHeaders {\n\t\tif _, ok := hopByHopHeaders[respHeader]; !ok {\n\t\t\tendToEndHeaders = append(endToEndHeaders, respHeader)\n\t\t}\n\t}\n\treturn endToEndHeaders\n}\n\nfunc canStore(reqCacheControl, respCacheControl cacheControl) (canStore bool) {\n\tif _, ok := respCacheControl[\"no-store\"]; ok {\n\t\treturn false\n\t}\n\tif _, ok := reqCacheControl[\"no-store\"]; ok {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc newGatewayTimeoutResponse(req *http.Request) *http.Response {\n\tvar braw bytes.Buffer\n\tbraw.WriteString(\"HTTP/1.1 504 Gateway Timeout\\r\\n\\r\\n\")\n\tresp, err := http.ReadResponse(bufio.NewReader(&braw), req)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn resp\n}\n\n// cloneRequest returns a clone of the provided *http.Request.\n// The clone is a shallow copy of the struct and its Header map.\n// (This function copyright goauth2 authors: https://code.google.com/p/goauth2)\nfunc cloneRequest(r *http.Request) *http.Request {\n\t// shallow copy of the struct\n\tr2 := new(http.Request)\n\t*r2 = *r\n\t// deep copy of the Header\n\tr2.Header = make(http.Header)\n\tfor k, s := range r.Header {\n\t\tr2.Header[k] = s\n\t}\n\treturn r2\n}\n\ntype cacheControl map[string]string\n\nfunc parseCacheControl(headers http.Header) cacheControl {\n\tcc := cacheControl{}\n\tccHeader := headers.Get(\"Cache-Control\")\n\tfor _, part := range strings.Split(ccHeader, \",\") {\n\t\tpart = strings.Trim(part, \" \")\n\t\tif part == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.ContainsRune(part, '=') {\n\t\t\tkeyval := strings.Split(part, \"=\")\n\t\t\tcc[strings.Trim(keyval[0], \" \")] = strings.Trim(keyval[1], \",\")\n\t\t} else {\n\t\t\tcc[part] = \"\"\n\t\t}\n\t}\n\treturn cc\n}\n\n// headerAllCommaSepValues returns all comma-separated values (each\n// with whitespace trimmed) for header name in headers. According to\n// Section 4.2 of the HTTP/1.1 spec\n// (http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2),\n// values from multiple occurrences of a header should be concatenated, if\n// the header's value is a comma-separated list.\nfunc headerAllCommaSepValues(headers http.Header, name string) []string {\n\tvar vals []string\n\tfor _, val := range headers[http.CanonicalHeaderKey(name)] {\n\t\tfields := strings.Split(val, \",\")\n\t\tfor i, f := range fields {\n\t\t\tfields[i] = strings.TrimSpace(f)\n\t\t}\n\t\tvals = append(vals, fields...)\n\t}\n\treturn vals\n}\n\n// cachingReadCloser is a wrapper around ReadCloser R that calls OnEOF\n// handler with a full copy of the content read from R when EOF is\n// reached.\ntype cachingReadCloser struct {\n\t// Underlying ReadCloser.\n\tR io.ReadCloser\n\t// OnEOF is called with a copy of the content of R when EOF is reached.\n\tOnEOF func(io.Reader)\n\n\tbuf bytes.Buffer // buf stores a copy of the content of R.\n}\n\n// Read reads the next len(p) bytes from R or until R is drained. The\n// return value n is the number of bytes read. If R has no data to\n// return, err is io.EOF and OnEOF is called with a full copy of what\n// has been read so far.\nfunc (r *cachingReadCloser) Read(p []byte) (n int, err error) {\n\tn, err = r.R.Read(p)\n\tr.buf.Write(p[:n])\n\tif err == io.EOF {\n\t\tr.OnEOF(bytes.NewReader(r.buf.Bytes()))\n\t}\n\treturn n, err\n}\n\nfunc (r *cachingReadCloser) Close() error {\n\treturn r.R.Close()\n}\n\n// NewMemoryCacheTransport returns a new Transport using the in-memory cache implementation\nfunc NewMemoryCacheTransport() *Transport {\n\tc := NewMemoryCache()\n\tt := NewTransport(c)\n\treturn t\n}\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/.deepsource.toml",
    "content": "version = 1\n\ntest_patterns = [\n  \"*_test.go\"\n]\n\n[[analyzers]]\nname = \"go\"\nenabled = true\n\n  [analyzers.meta]\n  import_path = \"github.com/imdario/mergo\""
  },
  {
    "path": "vendor/github.com/imdario/mergo/.gitignore",
    "content": "#### joe made this: http://goel.io/joe\n\n#### go ####\n# Binaries for programs and plugins\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# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736\n.glide/\n\n#### vim ####\n# Swap\n[._]*.s[a-v][a-z]\n[._]*.sw[a-p]\n[._]s[a-v][a-z]\n[._]sw[a-p]\n\n# Session\nSession.vim\n\n# Temporary\n.netrwhist\n*~\n# Auto-generated tag files\ntags\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/.travis.yml",
    "content": "language: go\narch:\n    - amd64\n    - ppc64le\ninstall:\n  - go get -t\n  - go get golang.org/x/tools/cmd/cover\n  - go get github.com/mattn/goveralls\nscript:\n  - go test -race -v ./...\nafter_script:\n  - $HOME/gopath/bin/goveralls -service=travis-ci -repotoken $COVERALLS_TOKEN\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment include:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at i@dario.im. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/LICENSE",
    "content": "Copyright (c) 2013 Dario Castañé. All rights reserved.\nCopyright (c) 2012 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/imdario/mergo/README.md",
    "content": "# Mergo\n\n\n[![GoDoc][3]][4]\n[![GitHub release][5]][6]\n[![GoCard][7]][8]\n[![Build Status][1]][2]\n[![Coverage Status][9]][10]\n[![Sourcegraph][11]][12]\n[![FOSSA Status][13]][14]\n[![Become my sponsor][15]][16]\n\n[1]: https://travis-ci.org/imdario/mergo.png\n[2]: https://travis-ci.org/imdario/mergo\n[3]: https://godoc.org/github.com/imdario/mergo?status.svg\n[4]: https://godoc.org/github.com/imdario/mergo\n[5]: https://img.shields.io/github/release/imdario/mergo.svg\n[6]: https://github.com/imdario/mergo/releases\n[7]: https://goreportcard.com/badge/imdario/mergo\n[8]: https://goreportcard.com/report/github.com/imdario/mergo\n[9]: https://coveralls.io/repos/github/imdario/mergo/badge.svg?branch=master\n[10]: https://coveralls.io/github/imdario/mergo?branch=master\n[11]: https://sourcegraph.com/github.com/imdario/mergo/-/badge.svg\n[12]: https://sourcegraph.com/github.com/imdario/mergo?badge\n[13]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=shield\n[14]: https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_shield\n[15]: https://img.shields.io/github/sponsors/imdario\n[16]: https://github.com/sponsors/imdario\n\nA helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.\n\nMergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).\n\nAlso a lovely [comune](http://en.wikipedia.org/wiki/Mergo) (municipality) in the Province of Ancona in the Italian region of Marche.\n\n## Status\n\nIt is ready for production use. [It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, Microsoft, etc](https://github.com/imdario/mergo#mergo-in-the-wild).\n\n### Important note\n\nPlease keep in mind that a problematic PR broke [0.3.9](//github.com/imdario/mergo/releases/tag/0.3.9). I reverted it in [0.3.10](//github.com/imdario/mergo/releases/tag/0.3.10), and I consider it stable but not bug-free. Also, this version adds support for go modules.\n\nKeep in mind that in [0.3.2](//github.com/imdario/mergo/releases/tag/0.3.2), Mergo changed `Merge()`and `Map()` signatures to support [transformers](#transformers). I added an optional/variadic argument so that it won't break the existing code.\n\nIf you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with ```go get -u github.com/imdario/mergo```. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).\n\n### Donations\n\nIf Mergo is useful to you, consider buying me a coffee, a beer, or making a monthly donation to allow me to keep building great free software. :heart_eyes:\n\n<a href='https://ko-fi.com/B0B58839' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>\n<a href=\"https://liberapay.com/dario/donate\"><img alt=\"Donate using Liberapay\" src=\"https://liberapay.com/assets/widgets/donate.svg\"></a>\n<a href='https://github.com/sponsors/imdario' target='_blank'><img alt=\"Become my sponsor\" src=\"https://img.shields.io/github/sponsors/imdario?style=for-the-badge\" /></a>\n\n### Mergo in the wild\n\n- [cli/cli](https://github.com/cli/cli)\n- [moby/moby](https://github.com/moby/moby)\n- [kubernetes/kubernetes](https://github.com/kubernetes/kubernetes)\n- [vmware/dispatch](https://github.com/vmware/dispatch)\n- [Shopify/themekit](https://github.com/Shopify/themekit)\n- [imdario/zas](https://github.com/imdario/zas)\n- [matcornic/hermes](https://github.com/matcornic/hermes)\n- [OpenBazaar/openbazaar-go](https://github.com/OpenBazaar/openbazaar-go)\n- [kataras/iris](https://github.com/kataras/iris)\n- [michaelsauter/crane](https://github.com/michaelsauter/crane)\n- [go-task/task](https://github.com/go-task/task)\n- [sensu/uchiwa](https://github.com/sensu/uchiwa)\n- [ory/hydra](https://github.com/ory/hydra)\n- [sisatech/vcli](https://github.com/sisatech/vcli)\n- [dairycart/dairycart](https://github.com/dairycart/dairycart)\n- [projectcalico/felix](https://github.com/projectcalico/felix)\n- [resin-os/balena](https://github.com/resin-os/balena)\n- [go-kivik/kivik](https://github.com/go-kivik/kivik)\n- [Telefonica/govice](https://github.com/Telefonica/govice)\n- [supergiant/supergiant](supergiant/supergiant)\n- [SergeyTsalkov/brooce](https://github.com/SergeyTsalkov/brooce)\n- [soniah/dnsmadeeasy](https://github.com/soniah/dnsmadeeasy)\n- [ohsu-comp-bio/funnel](https://github.com/ohsu-comp-bio/funnel)\n- [EagerIO/Stout](https://github.com/EagerIO/Stout)\n- [lynndylanhurley/defsynth-api](https://github.com/lynndylanhurley/defsynth-api)\n- [russross/canvasassignments](https://github.com/russross/canvasassignments)\n- [rdegges/cryptly-api](https://github.com/rdegges/cryptly-api)\n- [casualjim/exeggutor](https://github.com/casualjim/exeggutor)\n- [divshot/gitling](https://github.com/divshot/gitling)\n- [RWJMurphy/gorl](https://github.com/RWJMurphy/gorl)\n- [andrerocker/deploy42](https://github.com/andrerocker/deploy42)\n- [elwinar/rambler](https://github.com/elwinar/rambler)\n- [tmaiaroto/gopartman](https://github.com/tmaiaroto/gopartman)\n- [jfbus/impressionist](https://github.com/jfbus/impressionist)\n- [Jmeyering/zealot](https://github.com/Jmeyering/zealot)\n- [godep-migrator/rigger-host](https://github.com/godep-migrator/rigger-host)\n- [Dronevery/MultiwaySwitch-Go](https://github.com/Dronevery/MultiwaySwitch-Go)\n- [thoas/picfit](https://github.com/thoas/picfit)\n- [mantasmatelis/whooplist-server](https://github.com/mantasmatelis/whooplist-server)\n- [jnuthong/item_search](https://github.com/jnuthong/item_search)\n- [bukalapak/snowboard](https://github.com/bukalapak/snowboard)\n- [containerssh/containerssh](https://github.com/containerssh/containerssh)\n- [goreleaser/goreleaser](https://github.com/goreleaser/goreleaser)\n- [tjpnz/structbot](https://github.com/tjpnz/structbot)\n\n## Install\n\n    go get github.com/imdario/mergo\n\n    // use in your .go code\n    import (\n        \"github.com/imdario/mergo\"\n    )\n\n## Usage\n\nYou can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as [they are zero values](https://golang.org/ref/spec#The_zero_value) too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).\n\n```go\nif err := mergo.Merge(&dst, src); err != nil {\n    // ...\n}\n```\n\nAlso, you can merge overwriting values using the transformer `WithOverride`.\n\n```go\nif err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {\n    // ...\n}\n```\n\nAdditionally, you can map a `map[string]interface{}` to a struct (and otherwise, from struct to map), following the same restrictions as in `Merge()`. Keys are capitalized to find each corresponding exported field.\n\n```go\nif err := mergo.Map(&dst, srcMap); err != nil {\n    // ...\n}\n```\n\nWarning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as `map[string]interface{}`. They will be just assigned as values.\n\nHere is a nice example:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/imdario/mergo\"\n)\n\ntype Foo struct {\n\tA string\n\tB int64\n}\n\nfunc main() {\n\tsrc := Foo{\n\t\tA: \"one\",\n\t\tB: 2,\n\t}\n\tdest := Foo{\n\t\tA: \"two\",\n\t}\n\tmergo.Merge(&dest, src)\n\tfmt.Println(dest)\n\t// Will print\n\t// {two 2}\n}\n```\n\nNote: if test are failing due missing package, please execute:\n\n    go get gopkg.in/yaml.v3\n\n### Transformers\n\nTransformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, `time.Time` is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero `time.Time`?\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/imdario/mergo\"\n        \"reflect\"\n        \"time\"\n)\n\ntype timeTransformer struct {\n}\n\nfunc (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {\n\tif typ == reflect.TypeOf(time.Time{}) {\n\t\treturn func(dst, src reflect.Value) error {\n\t\t\tif dst.CanSet() {\n\t\t\t\tisZero := dst.MethodByName(\"IsZero\")\n\t\t\t\tresult := isZero.Call([]reflect.Value{})\n\t\t\t\tif result[0].Bool() {\n\t\t\t\t\tdst.Set(src)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn nil\n}\n\ntype Snapshot struct {\n\tTime time.Time\n\t// ...\n}\n\nfunc main() {\n\tsrc := Snapshot{time.Now()}\n\tdest := Snapshot{}\n\tmergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))\n\tfmt.Println(dest)\n\t// Will print\n\t// { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }\n}\n```\n\n## Contact me\n\nIf I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): [@im_dario](https://twitter.com/im_dario)\n\n## About\n\nWritten by [Dario Castañé](http://dario.im).\n\n## License\n\n[BSD 3-Clause](http://opensource.org/licenses/BSD-3-Clause) license, as [Go language](http://golang.org/LICENSE).\n\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fimdario%2Fmergo.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fimdario%2Fmergo?ref=badge_large)\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/doc.go",
    "content": "// Copyright 2013 Dario Castañé. All rights reserved.\n// Copyright 2009 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/*\nA helper to merge structs and maps in Golang. Useful for configuration default values, avoiding messy if-statements.\n\nMergo merges same-type structs and maps by setting default values in zero-value fields. Mergo won't merge unexported (private) fields. It will do recursively any exported one. It also won't merge structs inside maps (because they are not addressable using Go reflection).\n\nStatus\n\nIt is ready for production use. It is used in several projects by Docker, Google, The Linux Foundation, VMWare, Shopify, etc.\n\nImportant note\n\nPlease keep in mind that a problematic PR broke 0.3.9. We reverted it in 0.3.10. We consider 0.3.10 as stable but not bug-free. . Also, this version adds suppot for go modules.\n\nKeep in mind that in 0.3.2, Mergo changed Merge() and Map() signatures to support transformers. We added an optional/variadic argument so that it won't break the existing code.\n\nIf you were using Mergo before April 6th, 2015, please check your project works as intended after updating your local copy with go get -u github.com/imdario/mergo. I apologize for any issue caused by its previous behavior and any future bug that Mergo could cause in existing projects after the change (release 0.2.0).\n\nInstall\n\nDo your usual installation procedure:\n\n    go get github.com/imdario/mergo\n\n    // use in your .go code\n    import (\n        \"github.com/imdario/mergo\"\n    )\n\nUsage\n\nYou can only merge same-type structs with exported fields initialized as zero value of their type and same-types maps. Mergo won't merge unexported (private) fields but will do recursively any exported one. It won't merge empty structs value as they are zero values too. Also, maps will be merged recursively except for structs inside maps (because they are not addressable using Go reflection).\n\n\tif err := mergo.Merge(&dst, src); err != nil {\n\t\t// ...\n\t}\n\nAlso, you can merge overwriting values using the transformer WithOverride.\n\n\tif err := mergo.Merge(&dst, src, mergo.WithOverride); err != nil {\n\t\t// ...\n\t}\n\nAdditionally, you can map a map[string]interface{} to a struct (and otherwise, from struct to map), following the same restrictions as in Merge(). Keys are capitalized to find each corresponding exported field.\n\n\tif err := mergo.Map(&dst, srcMap); err != nil {\n\t\t// ...\n\t}\n\nWarning: if you map a struct to map, it won't do it recursively. Don't expect Mergo to map struct members of your struct as map[string]interface{}. They will be just assigned as values.\n\nHere is a nice example:\n\n\tpackage main\n\n\timport (\n\t\t\"fmt\"\n\t\t\"github.com/imdario/mergo\"\n\t)\n\n\ttype Foo struct {\n\t\tA string\n\t\tB int64\n\t}\n\n\tfunc main() {\n\t\tsrc := Foo{\n\t\t\tA: \"one\",\n\t\t\tB: 2,\n\t\t}\n\t\tdest := Foo{\n\t\t\tA: \"two\",\n\t\t}\n\t\tmergo.Merge(&dest, src)\n\t\tfmt.Println(dest)\n\t\t// Will print\n\t\t// {two 2}\n\t}\n\nTransformers\n\nTransformers allow to merge specific types differently than in the default behavior. In other words, now you can customize how some types are merged. For example, time.Time is a struct; it doesn't have zero value but IsZero can return true because it has fields with zero value. How can we merge a non-zero time.Time?\n\n\tpackage main\n\n\timport (\n\t\t\"fmt\"\n\t\t\"github.com/imdario/mergo\"\n\t\t\t\"reflect\"\n\t\t\t\"time\"\n\t)\n\n\ttype timeTransformer struct {\n\t}\n\n\tfunc (t timeTransformer) Transformer(typ reflect.Type) func(dst, src reflect.Value) error {\n\t\tif typ == reflect.TypeOf(time.Time{}) {\n\t\t\treturn func(dst, src reflect.Value) error {\n\t\t\t\tif dst.CanSet() {\n\t\t\t\t\tisZero := dst.MethodByName(\"IsZero\")\n\t\t\t\t\tresult := isZero.Call([]reflect.Value{})\n\t\t\t\t\tif result[0].Bool() {\n\t\t\t\t\t\tdst.Set(src)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\ttype Snapshot struct {\n\t\tTime time.Time\n\t\t// ...\n\t}\n\n\tfunc main() {\n\t\tsrc := Snapshot{time.Now()}\n\t\tdest := Snapshot{}\n\t\tmergo.Merge(&dest, src, mergo.WithTransformers(timeTransformer{}))\n\t\tfmt.Println(dest)\n\t\t// Will print\n\t\t// { 2018-01-12 01:15:00 +0000 UTC m=+0.000000001 }\n\t}\n\nContact me\n\nIf I can help you, you have an idea or you are using Mergo in your projects, don't hesitate to drop me a line (or a pull request): https://twitter.com/im_dario\n\nAbout\n\nWritten by Dario Castañé: https://da.rio.hn\n\nLicense\n\nBSD 3-Clause license, as Go language.\n\n*/\npackage mergo\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/map.go",
    "content": "// Copyright 2014 Dario Castañé. All rights reserved.\n// Copyright 2009 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// Based on src/pkg/reflect/deepequal.go from official\n// golang's stdlib.\n\npackage mergo\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\nfunc changeInitialCase(s string, mapper func(rune) rune) string {\n\tif s == \"\" {\n\t\treturn s\n\t}\n\tr, n := utf8.DecodeRuneInString(s)\n\treturn string(mapper(r)) + s[n:]\n}\n\nfunc isExported(field reflect.StructField) bool {\n\tr, _ := utf8.DecodeRuneInString(field.Name)\n\treturn r >= 'A' && r <= 'Z'\n}\n\n// Traverses recursively both values, assigning src's fields values to dst.\n// The map argument tracks comparisons that have already been seen, which allows\n// short circuiting on recursive types.\nfunc deepMap(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {\n\toverwrite := config.Overwrite\n\tif dst.CanAddr() {\n\t\taddr := dst.UnsafeAddr()\n\t\th := 17 * addr\n\t\tseen := visited[h]\n\t\ttyp := dst.Type()\n\t\tfor p := seen; p != nil; p = p.next {\n\t\t\tif p.ptr == addr && p.typ == typ {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\t// Remember, remember...\n\t\tvisited[h] = &visit{addr, typ, seen}\n\t}\n\tzeroValue := reflect.Value{}\n\tswitch dst.Kind() {\n\tcase reflect.Map:\n\t\tdstMap := dst.Interface().(map[string]interface{})\n\t\tfor i, n := 0, src.NumField(); i < n; i++ {\n\t\t\tsrcType := src.Type()\n\t\t\tfield := srcType.Field(i)\n\t\t\tif !isExported(field) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfieldName := field.Name\n\t\t\tfieldName = changeInitialCase(fieldName, unicode.ToLower)\n\t\t\tif v, ok := dstMap[fieldName]; !ok || (isEmptyValue(reflect.ValueOf(v)) || overwrite) {\n\t\t\t\tdstMap[fieldName] = src.Field(i).Interface()\n\t\t\t}\n\t\t}\n\tcase reflect.Ptr:\n\t\tif dst.IsNil() {\n\t\t\tv := reflect.New(dst.Type().Elem())\n\t\t\tdst.Set(v)\n\t\t}\n\t\tdst = dst.Elem()\n\t\tfallthrough\n\tcase reflect.Struct:\n\t\tsrcMap := src.Interface().(map[string]interface{})\n\t\tfor key := range srcMap {\n\t\t\tconfig.overwriteWithEmptyValue = true\n\t\t\tsrcValue := srcMap[key]\n\t\t\tfieldName := changeInitialCase(key, unicode.ToUpper)\n\t\t\tdstElement := dst.FieldByName(fieldName)\n\t\t\tif dstElement == zeroValue {\n\t\t\t\t// We discard it because the field doesn't exist.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsrcElement := reflect.ValueOf(srcValue)\n\t\t\tdstKind := dstElement.Kind()\n\t\t\tsrcKind := srcElement.Kind()\n\t\t\tif srcKind == reflect.Ptr && dstKind != reflect.Ptr {\n\t\t\t\tsrcElement = srcElement.Elem()\n\t\t\t\tsrcKind = reflect.TypeOf(srcElement.Interface()).Kind()\n\t\t\t} else if dstKind == reflect.Ptr {\n\t\t\t\t// Can this work? I guess it can't.\n\t\t\t\tif srcKind != reflect.Ptr && srcElement.CanAddr() {\n\t\t\t\t\tsrcPtr := srcElement.Addr()\n\t\t\t\t\tsrcElement = reflect.ValueOf(srcPtr)\n\t\t\t\t\tsrcKind = reflect.Ptr\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !srcElement.IsValid() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif srcKind == dstKind {\n\t\t\t\tif err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else if dstKind == reflect.Interface && dstElement.Kind() == reflect.Interface {\n\t\t\t\tif err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else if srcKind == reflect.Map {\n\t\t\t\tif err = deepMap(dstElement, srcElement, visited, depth+1, config); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn fmt.Errorf(\"type mismatch on %s field: found %v, expected %v\", fieldName, srcKind, dstKind)\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\n// Map sets fields' values in dst from src.\n// src can be a map with string keys or a struct. dst must be the opposite:\n// if src is a map, dst must be a valid pointer to struct. If src is a struct,\n// dst must be map[string]interface{}.\n// It won't merge unexported (private) fields and will do recursively\n// any exported field.\n// If dst is a map, keys will be src fields' names in lower camel case.\n// Missing key in src that doesn't match a field in dst will be skipped. This\n// doesn't apply if dst is a map.\n// This is separated method from Merge because it is cleaner and it keeps sane\n// semantics: merging equal types, mapping different (restricted) types.\nfunc Map(dst, src interface{}, opts ...func(*Config)) error {\n\treturn _map(dst, src, opts...)\n}\n\n// MapWithOverwrite will do the same as Map except that non-empty dst attributes will be overridden by\n// non-empty src attribute values.\n// Deprecated: Use Map(…) with WithOverride\nfunc MapWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {\n\treturn _map(dst, src, append(opts, WithOverride)...)\n}\n\nfunc _map(dst, src interface{}, opts ...func(*Config)) error {\n\tif dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {\n\t\treturn ErrNonPointerAgument\n\t}\n\tvar (\n\t\tvDst, vSrc reflect.Value\n\t\terr        error\n\t)\n\tconfig := &Config{}\n\n\tfor _, opt := range opts {\n\t\topt(config)\n\t}\n\n\tif vDst, vSrc, err = resolveValues(dst, src); err != nil {\n\t\treturn err\n\t}\n\t// To be friction-less, we redirect equal-type arguments\n\t// to deepMerge. Only because arguments can be anything.\n\tif vSrc.Kind() == vDst.Kind() {\n\t\treturn deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)\n\t}\n\tswitch vSrc.Kind() {\n\tcase reflect.Struct:\n\t\tif vDst.Kind() != reflect.Map {\n\t\t\treturn ErrExpectedMapAsDestination\n\t\t}\n\tcase reflect.Map:\n\t\tif vDst.Kind() != reflect.Struct {\n\t\t\treturn ErrExpectedStructAsDestination\n\t\t}\n\tdefault:\n\t\treturn ErrNotSupported\n\t}\n\treturn deepMap(vDst, vSrc, make(map[uintptr]*visit), 0, config)\n}\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/merge.go",
    "content": "// Copyright 2013 Dario Castañé. All rights reserved.\n// Copyright 2009 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// Based on src/pkg/reflect/deepequal.go from official\n// golang's stdlib.\n\npackage mergo\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\nfunc hasMergeableFields(dst reflect.Value) (exported bool) {\n\tfor i, n := 0, dst.NumField(); i < n; i++ {\n\t\tfield := dst.Type().Field(i)\n\t\tif field.Anonymous && dst.Field(i).Kind() == reflect.Struct {\n\t\t\texported = exported || hasMergeableFields(dst.Field(i))\n\t\t} else if isExportedComponent(&field) {\n\t\t\texported = exported || len(field.PkgPath) == 0\n\t\t}\n\t}\n\treturn\n}\n\nfunc isExportedComponent(field *reflect.StructField) bool {\n\tpkgPath := field.PkgPath\n\tif len(pkgPath) > 0 {\n\t\treturn false\n\t}\n\tc := field.Name[0]\n\tif 'a' <= c && c <= 'z' || c == '_' {\n\t\treturn false\n\t}\n\treturn true\n}\n\ntype Config struct {\n\tOverwrite                    bool\n\tAppendSlice                  bool\n\tTypeCheck                    bool\n\tTransformers                 Transformers\n\toverwriteWithEmptyValue      bool\n\toverwriteSliceWithEmptyValue bool\n\tsliceDeepCopy                bool\n\tdebug                        bool\n}\n\ntype Transformers interface {\n\tTransformer(reflect.Type) func(dst, src reflect.Value) error\n}\n\n// Traverses recursively both values, assigning src's fields values to dst.\n// The map argument tracks comparisons that have already been seen, which allows\n// short circuiting on recursive types.\nfunc deepMerge(dst, src reflect.Value, visited map[uintptr]*visit, depth int, config *Config) (err error) {\n\toverwrite := config.Overwrite\n\ttypeCheck := config.TypeCheck\n\toverwriteWithEmptySrc := config.overwriteWithEmptyValue\n\toverwriteSliceWithEmptySrc := config.overwriteSliceWithEmptyValue\n\tsliceDeepCopy := config.sliceDeepCopy\n\n\tif !src.IsValid() {\n\t\treturn\n\t}\n\tif dst.CanAddr() {\n\t\taddr := dst.UnsafeAddr()\n\t\th := 17 * addr\n\t\tseen := visited[h]\n\t\ttyp := dst.Type()\n\t\tfor p := seen; p != nil; p = p.next {\n\t\t\tif p.ptr == addr && p.typ == typ {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\t// Remember, remember...\n\t\tvisited[h] = &visit{addr, typ, seen}\n\t}\n\n\tif config.Transformers != nil && !isReflectNil(dst) && dst.IsValid() {\n\t\tif fn := config.Transformers.Transformer(dst.Type()); fn != nil {\n\t\t\terr = fn(dst, src)\n\t\t\treturn\n\t\t}\n\t}\n\n\tswitch dst.Kind() {\n\tcase reflect.Struct:\n\t\tif hasMergeableFields(dst) {\n\t\t\tfor i, n := 0, dst.NumField(); i < n; i++ {\n\t\t\t\tif err = deepMerge(dst.Field(i), src.Field(i), visited, depth+1, config); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif dst.CanSet() && (isReflectNil(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc) {\n\t\t\t\tdst.Set(src)\n\t\t\t}\n\t\t}\n\tcase reflect.Map:\n\t\tif dst.IsNil() && !src.IsNil() {\n\t\t\tif dst.CanSet() {\n\t\t\t\tdst.Set(reflect.MakeMap(dst.Type()))\n\t\t\t} else {\n\t\t\t\tdst = src\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif src.Kind() != reflect.Map {\n\t\t\tif overwrite {\n\t\t\t\tdst.Set(src)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tfor _, key := range src.MapKeys() {\n\t\t\tsrcElement := src.MapIndex(key)\n\t\t\tif !srcElement.IsValid() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tdstElement := dst.MapIndex(key)\n\t\t\tswitch srcElement.Kind() {\n\t\t\tcase reflect.Chan, reflect.Func, reflect.Map, reflect.Interface, reflect.Slice:\n\t\t\t\tif srcElement.IsNil() {\n\t\t\t\t\tif overwrite {\n\t\t\t\t\t\tdst.SetMapIndex(key, srcElement)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tfallthrough\n\t\t\tdefault:\n\t\t\t\tif !srcElement.CanInterface() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tswitch reflect.TypeOf(srcElement.Interface()).Kind() {\n\t\t\t\tcase reflect.Struct:\n\t\t\t\t\tfallthrough\n\t\t\t\tcase reflect.Ptr:\n\t\t\t\t\tfallthrough\n\t\t\t\tcase reflect.Map:\n\t\t\t\t\tsrcMapElm := srcElement\n\t\t\t\t\tdstMapElm := dstElement\n\t\t\t\t\tif srcMapElm.CanInterface() {\n\t\t\t\t\t\tsrcMapElm = reflect.ValueOf(srcMapElm.Interface())\n\t\t\t\t\t\tif dstMapElm.IsValid() {\n\t\t\t\t\t\t\tdstMapElm = reflect.ValueOf(dstMapElm.Interface())\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif err = deepMerge(dstMapElm, srcMapElm, visited, depth+1, config); err != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\tcase reflect.Slice:\n\t\t\t\t\tsrcSlice := reflect.ValueOf(srcElement.Interface())\n\n\t\t\t\t\tvar dstSlice reflect.Value\n\t\t\t\t\tif !dstElement.IsValid() || dstElement.IsNil() {\n\t\t\t\t\t\tdstSlice = reflect.MakeSlice(srcSlice.Type(), 0, srcSlice.Len())\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdstSlice = reflect.ValueOf(dstElement.Interface())\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy {\n\t\t\t\t\t\tif typeCheck && srcSlice.Type() != dstSlice.Type() {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"cannot override two slices with different type (%s, %s)\", srcSlice.Type(), dstSlice.Type())\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdstSlice = srcSlice\n\t\t\t\t\t} else if config.AppendSlice {\n\t\t\t\t\t\tif srcSlice.Type() != dstSlice.Type() {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"cannot append two slices with different type (%s, %s)\", srcSlice.Type(), dstSlice.Type())\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdstSlice = reflect.AppendSlice(dstSlice, srcSlice)\n\t\t\t\t\t} else if sliceDeepCopy {\n\t\t\t\t\t\ti := 0\n\t\t\t\t\t\tfor ; i < srcSlice.Len() && i < dstSlice.Len(); i++ {\n\t\t\t\t\t\t\tsrcElement := srcSlice.Index(i)\n\t\t\t\t\t\t\tdstElement := dstSlice.Index(i)\n\n\t\t\t\t\t\t\tif srcElement.CanInterface() {\n\t\t\t\t\t\t\t\tsrcElement = reflect.ValueOf(srcElement.Interface())\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif dstElement.CanInterface() {\n\t\t\t\t\t\t\t\tdstElement = reflect.ValueOf(dstElement.Interface())\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\t\t\t\t\tdst.SetMapIndex(key, dstSlice)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif dstElement.IsValid() && !isEmptyValue(dstElement) && (reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Map || reflect.TypeOf(srcElement.Interface()).Kind() == reflect.Slice) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif srcElement.IsValid() && ((srcElement.Kind() != reflect.Ptr && overwrite) || !dstElement.IsValid() || isEmptyValue(dstElement)) {\n\t\t\t\tif dst.IsNil() {\n\t\t\t\t\tdst.Set(reflect.MakeMap(dst.Type()))\n\t\t\t\t}\n\t\t\t\tdst.SetMapIndex(key, srcElement)\n\t\t\t}\n\t\t}\n\tcase reflect.Slice:\n\t\tif !dst.CanSet() {\n\t\t\tbreak\n\t\t}\n\t\tif (!isEmptyValue(src) || overwriteWithEmptySrc || overwriteSliceWithEmptySrc) && (overwrite || isEmptyValue(dst)) && !config.AppendSlice && !sliceDeepCopy {\n\t\t\tdst.Set(src)\n\t\t} else if config.AppendSlice {\n\t\t\tif src.Type() != dst.Type() {\n\t\t\t\treturn fmt.Errorf(\"cannot append two slice with different type (%s, %s)\", src.Type(), dst.Type())\n\t\t\t}\n\t\t\tdst.Set(reflect.AppendSlice(dst, src))\n\t\t} else if sliceDeepCopy {\n\t\t\tfor i := 0; i < src.Len() && i < dst.Len(); i++ {\n\t\t\t\tsrcElement := src.Index(i)\n\t\t\t\tdstElement := dst.Index(i)\n\t\t\t\tif srcElement.CanInterface() {\n\t\t\t\t\tsrcElement = reflect.ValueOf(srcElement.Interface())\n\t\t\t\t}\n\t\t\t\tif dstElement.CanInterface() {\n\t\t\t\t\tdstElement = reflect.ValueOf(dstElement.Interface())\n\t\t\t\t}\n\n\t\t\t\tif err = deepMerge(dstElement, srcElement, visited, depth+1, config); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tcase reflect.Ptr:\n\t\tfallthrough\n\tcase reflect.Interface:\n\t\tif isReflectNil(src) {\n\t\t\tif overwriteWithEmptySrc && dst.CanSet() && src.Type().AssignableTo(dst.Type()) {\n\t\t\t\tdst.Set(src)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tif src.Kind() != reflect.Interface {\n\t\t\tif dst.IsNil() || (src.Kind() != reflect.Ptr && overwrite) {\n\t\t\t\tif dst.CanSet() && (overwrite || isEmptyValue(dst)) {\n\t\t\t\t\tdst.Set(src)\n\t\t\t\t}\n\t\t\t} else if src.Kind() == reflect.Ptr {\n\t\t\t\tif err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else if dst.Elem().Type() == src.Type() {\n\t\t\t\tif err = deepMerge(dst.Elem(), src, visited, depth+1, config); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn ErrDifferentArgumentsTypes\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tif dst.IsNil() || overwrite {\n\t\t\tif dst.CanSet() && (overwrite || isEmptyValue(dst)) {\n\t\t\t\tdst.Set(src)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tif dst.Elem().Kind() == src.Elem().Kind() {\n\t\t\tif err = deepMerge(dst.Elem(), src.Elem(), visited, depth+1, config); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\tdefault:\n\t\tmustSet := (isEmptyValue(dst) || overwrite) && (!isEmptyValue(src) || overwriteWithEmptySrc)\n\t\tif mustSet {\n\t\t\tif dst.CanSet() {\n\t\t\t\tdst.Set(src)\n\t\t\t} else {\n\t\t\t\tdst = src\n\t\t\t}\n\t\t}\n\t}\n\n\treturn\n}\n\n// Merge will fill any empty for value type attributes on the dst struct using corresponding\n// src attributes if they themselves are not empty. dst and src must be valid same-type structs\n// and dst must be a pointer to struct.\n// It won't merge unexported (private) fields and will do recursively any exported field.\nfunc Merge(dst, src interface{}, opts ...func(*Config)) error {\n\treturn merge(dst, src, opts...)\n}\n\n// MergeWithOverwrite will do the same as Merge except that non-empty dst attributes will be overridden by\n// non-empty src attribute values.\n// Deprecated: use Merge(…) with WithOverride\nfunc MergeWithOverwrite(dst, src interface{}, opts ...func(*Config)) error {\n\treturn merge(dst, src, append(opts, WithOverride)...)\n}\n\n// WithTransformers adds transformers to merge, allowing to customize the merging of some types.\nfunc WithTransformers(transformers Transformers) func(*Config) {\n\treturn func(config *Config) {\n\t\tconfig.Transformers = transformers\n\t}\n}\n\n// WithOverride will make merge override non-empty dst attributes with non-empty src attributes values.\nfunc WithOverride(config *Config) {\n\tconfig.Overwrite = true\n}\n\n// WithOverwriteWithEmptyValue will make merge override non empty dst attributes with empty src attributes values.\nfunc WithOverwriteWithEmptyValue(config *Config) {\n\tconfig.Overwrite = true\n\tconfig.overwriteWithEmptyValue = true\n}\n\n// WithOverrideEmptySlice will make merge override empty dst slice with empty src slice.\nfunc WithOverrideEmptySlice(config *Config) {\n\tconfig.overwriteSliceWithEmptyValue = true\n}\n\n// WithAppendSlice will make merge append slices instead of overwriting it.\nfunc WithAppendSlice(config *Config) {\n\tconfig.AppendSlice = true\n}\n\n// WithTypeCheck will make merge check types while overwriting it (must be used with WithOverride).\nfunc WithTypeCheck(config *Config) {\n\tconfig.TypeCheck = true\n}\n\n// WithSliceDeepCopy will merge slice element one by one with Overwrite flag.\nfunc WithSliceDeepCopy(config *Config) {\n\tconfig.sliceDeepCopy = true\n\tconfig.Overwrite = true\n}\n\nfunc merge(dst, src interface{}, opts ...func(*Config)) error {\n\tif dst != nil && reflect.ValueOf(dst).Kind() != reflect.Ptr {\n\t\treturn ErrNonPointerAgument\n\t}\n\tvar (\n\t\tvDst, vSrc reflect.Value\n\t\terr        error\n\t)\n\n\tconfig := &Config{}\n\n\tfor _, opt := range opts {\n\t\topt(config)\n\t}\n\n\tif vDst, vSrc, err = resolveValues(dst, src); err != nil {\n\t\treturn err\n\t}\n\tif vDst.Type() != vSrc.Type() {\n\t\treturn ErrDifferentArgumentsTypes\n\t}\n\treturn deepMerge(vDst, vSrc, make(map[uintptr]*visit), 0, config)\n}\n\n// IsReflectNil is the reflect value provided nil\nfunc isReflectNil(v reflect.Value) bool {\n\tk := v.Kind()\n\tswitch k {\n\tcase reflect.Interface, reflect.Slice, reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr:\n\t\t// Both interface and slice are nil if first word is 0.\n\t\t// Both are always bigger than a word; assume flagIndir.\n\t\treturn v.IsNil()\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/imdario/mergo/mergo.go",
    "content": "// Copyright 2013 Dario Castañé. All rights reserved.\n// Copyright 2009 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// Based on src/pkg/reflect/deepequal.go from official\n// golang's stdlib.\n\npackage mergo\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n)\n\n// Errors reported by Mergo when it finds invalid arguments.\nvar (\n\tErrNilArguments                = errors.New(\"src and dst must not be nil\")\n\tErrDifferentArgumentsTypes     = errors.New(\"src and dst must be of same type\")\n\tErrNotSupported                = errors.New(\"only structs, maps, and slices are supported\")\n\tErrExpectedMapAsDestination    = errors.New(\"dst was expected to be a map\")\n\tErrExpectedStructAsDestination = errors.New(\"dst was expected to be a struct\")\n\tErrNonPointerAgument           = errors.New(\"dst must be a pointer\")\n)\n\n// During deepMerge, must keep track of checks that are\n// in progress.  The comparison algorithm assumes that all\n// checks in progress are true when it reencounters them.\n// Visited are stored in a map indexed by 17 * a1 + a2;\ntype visit struct {\n\tptr  uintptr\n\ttyp  reflect.Type\n\tnext *visit\n}\n\n// From src/pkg/encoding/json/encode.go.\nfunc isEmptyValue(v reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn v.Len() == 0\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn v.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.Interface, reflect.Ptr:\n\t\tif v.IsNil() {\n\t\t\treturn true\n\t\t}\n\t\treturn isEmptyValue(v.Elem())\n\tcase reflect.Func:\n\t\treturn v.IsNil()\n\tcase reflect.Invalid:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc resolveValues(dst, src interface{}) (vDst, vSrc reflect.Value, err error) {\n\tif dst == nil || src == nil {\n\t\terr = ErrNilArguments\n\t\treturn\n\t}\n\tvDst = reflect.ValueOf(dst).Elem()\n\tif vDst.Kind() != reflect.Struct && vDst.Kind() != reflect.Map && vDst.Kind() != reflect.Slice {\n\t\terr = ErrNotSupported\n\t\treturn\n\t}\n\tvSrc = reflect.ValueOf(src)\n\t// We check if vSrc is a pointer to dereference it.\n\tif vSrc.Kind() == reflect.Ptr {\n\t\tvSrc = vSrc.Elem()\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/inconshreveable/mousetrap/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2022 Alan Shreve (@inconshreveable)\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       http://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": "vendor/github.com/inconshreveable/mousetrap/README.md",
    "content": "# mousetrap\n\nmousetrap is a tiny library that answers a single question.\n\nOn a Windows machine, was the process invoked by someone double clicking on\nthe executable file while browsing in explorer?\n\n### Motivation\n\nWindows developers unfamiliar with command line tools will often \"double-click\"\nthe executable for a tool. Because most CLI tools print the help and then exit\nwhen invoked without arguments, this is often very frustrating for those users.\n\nmousetrap provides a way to detect these invocations so that you can provide\nmore helpful behavior and instructions on how to run the CLI tool. To see what\nthis looks like, both from an organizational and a technical perspective, see\nhttps://inconshreveable.com/09-09-2014/sweat-the-small-stuff/\n\n### The interface\n\nThe library exposes a single interface:\n\n    func StartedByExplorer() (bool)\n"
  },
  {
    "path": "vendor/github.com/inconshreveable/mousetrap/trap_others.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage mousetrap\n\n// StartedByExplorer returns true if the program was invoked by the user\n// double-clicking on the executable from explorer.exe\n//\n// It is conservative and returns false if any of the internal calls fail.\n// It does not guarantee that the program was run from a terminal. It only can tell you\n// whether it was launched from explorer.exe\n//\n// On non-Windows platforms, it always returns false.\nfunc StartedByExplorer() bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/inconshreveable/mousetrap/trap_windows.go",
    "content": "package mousetrap\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc getProcessEntry(pid int) (*syscall.ProcessEntry32, error) {\n\tsnapshot, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPPROCESS, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer syscall.CloseHandle(snapshot)\n\tvar procEntry syscall.ProcessEntry32\n\tprocEntry.Size = uint32(unsafe.Sizeof(procEntry))\n\tif err = syscall.Process32First(snapshot, &procEntry); err != nil {\n\t\treturn nil, err\n\t}\n\tfor {\n\t\tif procEntry.ProcessID == uint32(pid) {\n\t\t\treturn &procEntry, nil\n\t\t}\n\t\terr = syscall.Process32Next(snapshot, &procEntry)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n}\n\n// StartedByExplorer returns true if the program was invoked by the user double-clicking\n// on the executable from explorer.exe\n//\n// It is conservative and returns false if any of the internal calls fail.\n// It does not guarantee that the program was run from a terminal. It only can tell you\n// whether it was launched from explorer.exe\nfunc StartedByExplorer() bool {\n\tpe, err := getProcessEntry(syscall.Getppid())\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn \"explorer.exe\" == syscall.UTF16ToString(pe.ExeFile[:])\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 jedib0t\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": "vendor/github.com/jedib0t/go-pretty/v6/table/README.md",
    "content": "# Table\n[![Go Reference](https://pkg.go.dev/badge/github.com/jedib0t/go-pretty/v6/table.svg)](https://pkg.go.dev/github.com/jedib0t/go-pretty/v6/table)\n\nPretty-print tables into ASCII/Unicode strings.\n\n  - Add Rows one-by-one or as a group (`AppendRow`/`AppendRows`)\n  - Add Header(s) and Footer(s) (`AppendHeader`/`AppendFooter`)\n  - Add a Separator manually after any Row (`AppendSeparator`)\n  - Auto Index Rows (1, 2, 3 ...) and Columns (A, B, C, ...) (`SetAutoIndex`)\n  - Auto Merge\n    - Cells in a Row (`RowConfig.AutoMerge`)\n    - Columns (`ColumnConfig.AutoMerge`)\n  - Limit the length of\n    - Rows (`SetAllowedRowLength`)\n    - Columns (`ColumnConfig.Width*`)\n  - Page results by a specified number of Lines (`SetPageSize`)\n  - Alignment - Horizontal & Vertical\n    - Auto (horizontal) Align (numeric columns aligned Right)\n    - Custom (horizontal) Align per column (`ColumnConfig.Align*`)\n    - Custom (vertical) VAlign per column with multi-line cell support (`ColumnConfig.VAlign*`)\n  - Mirror output to an `io.Writer` (ex. `os.StdOut`) (`SetOutputMirror`)\n  - Sort by one or more Columns (`SortBy`)\n  - Suppress/hide columns with no content (`SuppressEmptyColumns`) \n  - Customizable Cell rendering per Column (`ColumnConfig.Transformer*`)\n  - Hide any columns that you don't want displayed (`ColumnConfig.Hidden`)\n  - Reset Headers/Rows/Footers at will to reuse the same Table Writer (`Reset*`)\n  - Completely customizable styles (`SetStyle`/`Style`)\n    - Many ready-to-use styles: [style.go](style.go)\n    - Colorize Headers/Body/Footers using [../text/color.go](../text/color.go)\n    - Custom text-case for Headers/Body/Footers\n    - Enable separators between each row\n    - Render table without a Border\n    - and a lot more...\n  - Render as:\n    - (ASCII/Unicode) Table\n    - CSV\n    - HTML Table (with custom CSS Class)\n    - Markdown Table\n\n```\n+---------------------------------------------------------------------+\n| Game of Thrones                                                     +\n+-----+------------+-----------+--------+-----------------------------+\n|   # | FIRST NAME | LAST NAME | SALARY |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|   1 | Arya       | Stark     |   3000 |                             |\n|  20 | Jon        | Snow      |   2000 | You know nothing, Jon Snow! |\n| 300 | Tyrion     | Lannister |   5000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|     |            | TOTAL     |  10000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n```\n\nA demonstration of all the capabilities can be found here:\n[../cmd/demo-table](../cmd/demo-table)\n\nIf you want very specific examples, read ahead.\n\n**Hint**: I've tried to ensure that almost all supported use-cases are covered\nby unit-tests and that they print the table rendered. Run\n`go test -v github.com/jedib0t/go-pretty/v6/table` to see the test outputs and\nhelp you figure out how to do something.\n\n# Examples\n\nAll the examples below are going to start with the following block, although\nnothing except a single Row is mandatory for the `Render()` function to render\nsomething:\n```golang\npackage main\n\nimport (\n    \"os\"\n\n    \"github.com/jedib0t/go-pretty/v6/table\"\n)\n\nfunc main() {\n    t := table.NewWriter()\n    t.SetOutputMirror(os.Stdout)\n    t.AppendHeader(table.Row{\"#\", \"First Name\", \"Last Name\", \"Salary\"})\n    t.AppendRows([]table.Row{\n        {1, \"Arya\", \"Stark\", 3000},\n        {20, \"Jon\", \"Snow\", 2000, \"You know nothing, Jon Snow!\"},\n    })\n    t.AppendSeparator()\n    t.AppendRow([]interface{}{300, \"Tyrion\", \"Lannister\", 5000})\n    t.AppendFooter(table.Row{\"\", \"\", \"Total\", 10000})\n    t.Render()\n}\n```\nRunning the above will result in:\n```\n+-----+------------+-----------+--------+-----------------------------+\n|   # | FIRST NAME | LAST NAME | SALARY |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|   1 | Arya       | Stark     |   3000 |                             |\n|  20 | Jon        | Snow      |   2000 | You know nothing, Jon Snow! |\n+-----+------------+-----------+--------+-----------------------------+\n| 300 | Tyrion     | Lannister |   5000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|     |            | TOTAL     |  10000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n```\n\n## Styles\n\nYou can customize almost every single thing about the table above. The previous\nexample just defaulted to `StyleDefault` during `Render()`. You can use a\nready-to-use style (as in [style.go](style.go)) or customize it as you want.\n\n### Ready-to-use Styles\n\nTable comes with a bunch of ready-to-use Styles that make the table look really\ngood. Set or Change the style using:\n```golang\n    t.SetStyle(table.StyleLight)\n    t.Render()\n```\nto get:\n```\n┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐\n│   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n│   1 │ Arya       │ Stark     │   3000 │                             │\n│  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n│ 300 │ Tyrion     │ Lannister │   5000 │                             │\n├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n│     │            │ TOTAL     │  10000 │                             │\n└─────┴────────────┴───────────┴────────┴─────────────────────────────┘\n```\n\nOr if you want to use a full-color mode, and don't care for boxes, use:\n```golang\n    t.SetStyle(table.StyleColoredBright)\n    t.Render()\n```\nto get:\n\n<img src=\"images/table-StyleColoredBright.png\" width=\"640px\" alt=\"Colored Table\"/>\n\n### Roll your own Style\n\nYou can also roll your own style:\n```golang\n    t.SetStyle(table.Style{\n        Name: \"myNewStyle\",\n        Box: table.BoxStyle{\n            BottomLeft:       \"\\\\\",\n            BottomRight:      \"/\",\n            BottomSeparator:  \"v\",\n            Left:             \"[\",\n            LeftSeparator:    \"{\",\n            MiddleHorizontal: \"-\",\n            MiddleSeparator:  \"+\",\n            MiddleVertical:   \"|\",\n            PaddingLeft:      \"<\",\n            PaddingRight:     \">\",\n            Right:            \"]\",\n            RightSeparator:   \"}\",\n            TopLeft:          \"(\",\n            TopRight:         \")\",\n            TopSeparator:     \"^\",\n            UnfinishedRow:    \" ~~~\",\n        },\n        Color: table.ColorOptions{\n            IndexColumn:     text.Colors{text.BgCyan, text.FgBlack},\n            Footer:          text.Colors{text.BgCyan, text.FgBlack},\n            Header:          text.Colors{text.BgHiCyan, text.FgBlack},\n            Row:             text.Colors{text.BgHiWhite, text.FgBlack},\n            RowAlternate:    text.Colors{text.BgWhite, text.FgBlack},\n        },\n        Format: table.FormatOptions{\n            Footer: text.FormatUpper,\n            Header: text.FormatUpper,\n            Row:    text.FormatDefault,\n        },\n        Options: table.Options{\n            DrawBorder:      true,\n            SeparateColumns: true,\n            SeparateFooter:  true,\n            SeparateHeader:  true,\n            SeparateRows:    false,\n        },\n    })\n```\n\nOr you can use one of the ready-to-use Styles, and just make a few tweaks:\n```golang\n    t.SetStyle(table.StyleLight)\n    t.Style().Color.Header = text.Colors{text.BgHiCyan, text.FgBlack}\n    t.Style().Color.IndexColumn = text.Colors{text.BgHiCyan, text.FgBlack}\n    t.Style().Format.Footer = text.FormatLower\n    t.Style().Options.DrawBorder = false\n```\n\n## Auto-Merge\n\nYou can auto-merge cells horizontally and vertically, but you have request for\nit specifically for each row/column using `RowConfig` or `ColumnConfig`.\n\n```golang\n    rowConfigAutoMerge := table.RowConfig{AutoMerge: true}\n\n    t := table.NewWriter()\n    t.AppendHeader(table.Row{\"Node IP\", \"Pods\", \"Namespace\", \"Container\", \"RCE\", \"RCE\"}, rowConfigAutoMerge)\n    t.AppendHeader(table.Row{\"\", \"\", \"\", \"\", \"EXE\", \"RUN\"})\n    t.AppendRow(table.Row{\"1.1.1.1\", \"Pod 1A\", \"NS 1A\", \"C 1\", \"Y\", \"Y\"}, rowConfigAutoMerge)\n    t.AppendRow(table.Row{\"1.1.1.1\", \"Pod 1A\", \"NS 1A\", \"C 2\", \"Y\", \"N\"}, rowConfigAutoMerge)\n    t.AppendRow(table.Row{\"1.1.1.1\", \"Pod 1A\", \"NS 1B\", \"C 3\", \"N\", \"N\"}, rowConfigAutoMerge)\n    t.AppendRow(table.Row{\"1.1.1.1\", \"Pod 1B\", \"NS 2\", \"C 4\", \"N\", \"N\"}, rowConfigAutoMerge)\n    t.AppendRow(table.Row{\"1.1.1.1\", \"Pod 1B\", \"NS 2\", \"C 5\", \"Y\", \"N\"}, rowConfigAutoMerge)\n    t.AppendRow(table.Row{\"2.2.2.2\", \"Pod 2\", \"NS 3\", \"C 6\", \"Y\", \"Y\"}, rowConfigAutoMerge)\n    t.AppendRow(table.Row{\"2.2.2.2\", \"Pod 2\", \"NS 3\", \"C 7\", \"Y\", \"Y\"}, rowConfigAutoMerge)\n    t.AppendFooter(table.Row{\"\", \"\", \"\", 7, 5, 3})\n    t.SetAutoIndex(true)\n    t.SetColumnConfigs([]table.ColumnConfig{\n        {Number: 1, AutoMerge: true},\n        {Number: 2, AutoMerge: true},\n        {Number: 3, AutoMerge: true},\n        {Number: 4, AutoMerge: true},\n        {Number: 5, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},\n        {Number: 6, Align: text.AlignCenter, AlignFooter: text.AlignCenter, AlignHeader: text.AlignCenter},\n    })\n    t.SetOutputMirror(os.Stdout)\n    t.SetStyle(table.StyleLight)\n    t.Style().Options.SeparateRows = true\n    fmt.Println(t.Render())\n```\nto get:\n```\n┌───┬─────────┬────────┬───────────┬───────────┬───────────┐\n│   │ NODE IP │ PODS   │ NAMESPACE │ CONTAINER │    RCE    │\n│   │         │        │           │           ├─────┬─────┤\n│   │         │        │           │           │ EXE │ RUN │\n├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤\n│ 1 │ 1.1.1.1 │ Pod 1A │ NS 1A     │ C 1       │     Y     │\n├───┤         │        │           ├───────────┼─────┬─────┤\n│ 2 │         │        │           │ C 2       │  Y  │  N  │\n├───┤         │        ├───────────┼───────────┼─────┴─────┤\n│ 3 │         │        │ NS 1B     │ C 3       │     N     │\n├───┤         ├────────┼───────────┼───────────┼───────────┤\n│ 4 │         │ Pod 1B │ NS 2      │ C 4       │     N     │\n├───┤         │        │           ├───────────┼─────┬─────┤\n│ 5 │         │        │           │ C 5       │  Y  │  N  │\n├───┼─────────┼────────┼───────────┼───────────┼─────┴─────┤\n│ 6 │ 2.2.2.2 │ Pod 2  │ NS 3      │ C 6       │     Y     │\n├───┤         │        │           ├───────────┼───────────┤\n│ 7 │         │        │           │ C 7       │     Y     │\n├───┼─────────┼────────┼───────────┼───────────┼─────┬─────┤\n│   │         │        │           │ 7         │  5  │  3  │\n└───┴─────────┴────────┴───────────┴───────────┴─────┴─────┘\n```\n\n## Paging\n\nYou can limit then number of lines rendered in a single \"Page\". This logic\ncan handle rows with multiple lines too. Here is a simple example:\n```golang\n    t.SetPageSize(1)\n    t.Render()\n```\nto get:\n```\n+-----+------------+-----------+--------+-----------------------------+\n|   # | FIRST NAME | LAST NAME | SALARY |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|   1 | Arya       | Stark     |   3000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|     |            | TOTAL     |  10000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n\n+-----+------------+-----------+--------+-----------------------------+\n|   # | FIRST NAME | LAST NAME | SALARY |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|  20 | Jon        | Snow      |   2000 | You know nothing, Jon Snow! |\n+-----+------------+-----------+--------+-----------------------------+\n|     |            | TOTAL     |  10000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n\n+-----+------------+-----------+--------+-----------------------------+\n|   # | FIRST NAME | LAST NAME | SALARY |                             |\n+-----+------------+-----------+--------+-----------------------------+\n| 300 | Tyrion     | Lannister |   5000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n|     |            | TOTAL     |  10000 |                             |\n+-----+------------+-----------+--------+-----------------------------+\n```\n\n## Sorting\n\nSorting can be done on one or more columns. The following code will make the\nrows be sorted first by \"First Name\" and then by \"Last Name\" (in case of similar\n\"First Name\" entries).\n```golang\n    t.SortBy([]table.SortBy{\n\t    {Name: \"First Name\", Mode: table.Asc},\n\t    {Name: \"Last Name\", Mode: table.Asc},\n    })\n```\n\n## Wrapping (or) Row/Column Width restrictions\n\nYou can restrict the maximum (text) width for a Row:\n```golang\n    t.SetAllowedRowLength(50)\n    t.Render()\n```\nto get:\n```\n+-----+------------+-----------+--------+------- ~\n|   # | FIRST NAME | LAST NAME | SALARY |        ~\n+-----+------------+-----------+--------+------- ~\n|   1 | Arya       | Stark     |   3000 |        ~\n|  20 | Jon        | Snow      |   2000 | You kn ~\n+-----+------------+-----------+--------+------- ~\n| 300 | Tyrion     | Lannister |   5000 |        ~\n+-----+------------+-----------+--------+------- ~\n|     |            | TOTAL     |  10000 |        ~\n+-----+------------+-----------+--------+------- ~\n```\n\n## Column Control - Alignment, Colors, Width and more\n\nYou can control a lot of things about individual cells/columns which overrides\nglobal properties/styles using the `SetColumnConfig()` interface:\n- Alignment (horizontal & vertical)\n- Colorization\n- Transform individual cells based on the content\n- Visibility\n- Width (minimum & maximum)\n\n```golang\n    nameTransformer := text.Transformer(func(val interface{}) string {\n        return text.Bold.Sprint(val)\n    })\n\n    t.SetColumnConfigs([]ColumnConfig{\n        {\n            Name:              \"First Name\",\n            Align:             text.AlignLeft,\n            AlignFooter:       text.AlignLeft,\n            AlignHeader:       text.AlignLeft,\n            Colors:            text.Colors{text.BgBlack, text.FgRed},\n            ColorsHeader:      text.Colors{text.BgRed, text.FgBlack, text.Bold},\n            ColorsFooter:      text.Colors{text.BgRed, text.FgBlack},\n            Hidden:            false,\n            Transformer:       nameTransformer,\n            TransformerFooter: nameTransformer,\n            TransformerHeader: nameTransformer,\n            VAlign:            text.VAlignMiddle,\n            VAlignFooter:      text.VAlignTop,\n            VAlignHeader:      text.VAlignBottom,\n            WidthMin:          6,\n            WidthMax:          64,\n        }\n    })\n```\n\n## Render As ...\n\nTables can be rendered in other common formats such as:\n\n### ... CSV\n\n```golang\n    t.RenderCSV()\n```\nto get:\n```\n,First Name,Last Name,Salary,\n1,Arya,Stark,3000,\n20,Jon,Snow,2000,\"You know nothing\\, Jon Snow!\"\n300,Tyrion,Lannister,5000,\n,,Total,10000,\n```\n\n### ... HTML Table\n\n```golang\n    t.Style().HTML = table.HTMLOptions{\n        CSSClass:    \"game-of-thrones\",\n        EmptyColumn: \"&nbsp;\",\n        EscapeText:  true,\n        Newline:     \"<br/>\",\n    }\n    t.RenderHTML()\n```\nto get:\n```html\n<table class=\"game-of-thrones\">\n  <thead>\n  <tr>\n    <th align=\"right\">#</th>\n    <th>First Name</th>\n    <th>Last Name</th>\n    <th align=\"right\">Salary</th>\n    <th>&nbsp;</th>\n  </tr>\n  </thead>\n  <tbody>\n  <tr>\n    <td align=\"right\">1</td>\n    <td>Arya</td>\n    <td>Stark</td>\n    <td align=\"right\">3000</td>\n    <td>&nbsp;</td>\n  </tr>\n  <tr>\n    <td align=\"right\">20</td>\n    <td>Jon</td>\n    <td>Snow</td>\n    <td align=\"right\">2000</td>\n    <td>You know nothing, Jon Snow!</td>\n  </tr>\n  <tr>\n    <td align=\"right\">300</td>\n    <td>Tyrion</td>\n    <td>Lannister</td>\n    <td align=\"right\">5000</td>\n    <td>&nbsp;</td>\n  </tr>\n  </tbody>\n  <tfoot>\n  <tr>\n    <td align=\"right\">&nbsp;</td>\n    <td>&nbsp;</td>\n    <td>Total</td>\n    <td align=\"right\">10000</td>\n    <td>&nbsp;</td>\n  </tr>\n  </tfoot>\n</table>\n```\n\n### ... Markdown Table\n\n```golang\n    t.RenderMarkdown()\n```\nto get:\n```markdown\n| # | First Name | Last Name | Salary |  |\n| ---:| --- | --- | ---:| --- |\n| 1 | Arya | Stark | 3000 |  |\n| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! |\n| 300 | Tyrion | Lannister | 5000 |  |\n|  |  | Total | 10000 |  |\n```\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/config.go",
    "content": "package table\n\nimport (\n\t\"github.com/jedib0t/go-pretty/v6/text\"\n)\n\n// ColumnConfig contains configurations that determine and modify the way the\n// contents of the column get rendered.\ntype ColumnConfig struct {\n\t// Name is the name of the Column as it appears in the first Header row.\n\t// If a Header is not provided, or the name is not found in the header, this\n\t// will not work.\n\tName string\n\t// Number is the Column # from left. When specified, it overrides the Name\n\t// property. If you know the exact Column number, use this instead of Name.\n\tNumber int\n\n\t// Align defines the horizontal alignment\n\tAlign text.Align\n\t// AlignFooter defines the horizontal alignment of Footer rows\n\tAlignFooter text.Align\n\t// AlignHeader defines the horizontal alignment of Header rows\n\tAlignHeader text.Align\n\n\t// AutoMerge merges cells with similar values and prevents separators from\n\t// being drawn. Caveats:\n\t// * VAlign is applied on the individual cell and not on the merged cell\n\t// * Does not work in CSV/HTML/Markdown render modes\n\t// * Does not work well with horizontal auto-merge (RowConfig.AutoMerge)\n\t//\n\t// Works best when:\n\t// * Style().Options.SeparateRows == true\n\t// * Style().Color.Row == Style().Color.RowAlternate (or not set)\n\tAutoMerge bool\n\n\t// Colors defines the colors to be used on the column\n\tColors text.Colors\n\t// ColorsFooter defines the colors to be used on the column in Footer rows\n\tColorsFooter text.Colors\n\t// ColorsHeader defines the colors to be used on the column in Header rows\n\tColorsHeader text.Colors\n\n\t// Hidden when set to true will prevent the column from being rendered.\n\t// This is useful in cases like needing a column for sorting, but not for\n\t// display.\n\tHidden bool\n\n\t// Transformer is a custom-function that changes the way the value gets\n\t// rendered to the console. Refer to text/transformer.go for ready-to-use\n\t// Transformer functions.\n\tTransformer text.Transformer\n\t// TransformerFooter is like Transformer but for Footer rows\n\tTransformerFooter text.Transformer\n\t// TransformerHeader is like Transformer but for Header rows\n\tTransformerHeader text.Transformer\n\n\t// VAlign defines the vertical alignment\n\tVAlign text.VAlign\n\t// VAlignFooter defines the vertical alignment in Footer rows\n\tVAlignFooter text.VAlign\n\t// VAlignHeader defines the vertical alignment in Header rows\n\tVAlignHeader text.VAlign\n\n\t// WidthMax defines the maximum character length of the column\n\tWidthMax int\n\t// WidthEnforcer enforces the WidthMax value on the column contents;\n\t// default: text.WrapText\n\tWidthMaxEnforcer WidthEnforcer\n\t// WidthMin defines the minimum character length of the column\n\tWidthMin int\n}\n\nfunc (c ColumnConfig) getWidthMaxEnforcer() WidthEnforcer {\n\tif c.WidthMax == 0 {\n\t\treturn widthEnforcerNone\n\t}\n\tif c.WidthMaxEnforcer != nil {\n\t\treturn c.WidthMaxEnforcer\n\t}\n\treturn text.WrapText\n}\n\n// RowConfig contains configurations that determine and modify the way the\n// contents of a row get rendered.\ntype RowConfig struct {\n\t// AutoMerge merges cells with similar values and prevents separators from\n\t// being drawn. Caveats:\n\t// * Align is overridden to text.AlignCenter on the merged cell (unless set\n\t//   by AutoMergeAlign value below)\n\t// * Does not work in CSV/HTML/Markdown render modes\n\t// * Does not work well with vertical auto-merge (ColumnConfig.AutoMerge)\n\tAutoMerge bool\n\n\t// Alignment to use on a merge (defaults to text.AlignCenter)\n\tAutoMergeAlign text.Align\n}\n\nfunc (rc RowConfig) getAutoMergeAlign() text.Align {\n\tif rc.AutoMergeAlign == text.AlignDefault {\n\t\treturn text.AlignCenter\n\t}\n\treturn rc.AutoMergeAlign\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/render.go",
    "content": "package table\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/jedib0t/go-pretty/v6/text\"\n)\n\n// Render renders the Table in a human-readable \"pretty\" format. Example:\n//\n//\t┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐\n//\t│   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n//\t├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n//\t│   1 │ Arya       │ Stark     │   3000 │                             │\n//\t│  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n//\t│ 300 │ Tyrion     │ Lannister │   5000 │                             │\n//\t├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n//\t│     │            │ TOTAL     │  10000 │                             │\n//\t└─────┴────────────┴───────────┴────────┴─────────────────────────────┘\nfunc (t *Table) Render() string {\n\tt.initForRender()\n\n\tvar out strings.Builder\n\tif t.numColumns > 0 {\n\t\tt.renderTitle(&out)\n\n\t\t// top-most border\n\t\tt.renderRowsBorderTop(&out)\n\n\t\t// header rows\n\t\tt.renderRowsHeader(&out)\n\n\t\t// (data) rows\n\t\tt.renderRows(&out, t.rows, renderHint{})\n\n\t\t// footer rows\n\t\tt.renderRowsFooter(&out)\n\n\t\t// bottom-most border\n\t\tt.renderRowsBorderBottom(&out)\n\n\t\t// caption\n\t\tif t.caption != \"\" {\n\t\t\tout.WriteRune('\\n')\n\t\t\tout.WriteString(t.caption)\n\t\t}\n\t}\n\treturn t.render(&out)\n}\n\nfunc (t *Table) renderColumn(out *strings.Builder, row rowStr, colIdx int, maxColumnLength int, hint renderHint) int {\n\tnumColumnsRendered := 1\n\n\t// when working on the first column, and autoIndex is true, insert a new\n\t// column with the row number on it.\n\tif colIdx == 0 && t.autoIndex {\n\t\thintAutoIndex := hint\n\t\thintAutoIndex.isAutoIndexColumn = true\n\t\tt.renderColumnAutoIndex(out, hintAutoIndex)\n\t}\n\n\t// when working on column number 2 or more, render the column separator\n\tif colIdx > 0 {\n\t\tt.renderColumnSeparator(out, row, colIdx, hint)\n\t}\n\n\t// extract the text, convert-case if not-empty and align horizontally\n\tmergeVertically := t.shouldMergeCellsVertically(colIdx, hint)\n\tvar colStr string\n\tif mergeVertically {\n\t\t// leave colStr empty; align will expand the column as necessary\n\t} else if colIdx < len(row) {\n\t\tcolStr = t.getFormat(hint).Apply(row[colIdx])\n\t}\n\talign := t.getAlign(colIdx, hint)\n\n\t// if horizontal cell merges are enabled, look ahead and see how many cells\n\t// have the same content and merge them all until a cell with a different\n\t// content is found; override alignment to Center in this case\n\trowConfig := t.getRowConfig(hint)\n\tif rowConfig.AutoMerge && !hint.isSeparatorRow {\n\t\t// get the real row to consider all lines in each column instead of just\n\t\t// looking at the current \"line\"\n\t\trowUnwrapped := t.getRow(hint.rowNumber-1, hint)\n\t\tfor idx := colIdx + 1; idx < len(rowUnwrapped); idx++ {\n\t\t\tif rowUnwrapped[colIdx] != rowUnwrapped[idx] {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\talign = rowConfig.getAutoMergeAlign()\n\t\t\tmaxColumnLength += t.getMaxColumnLengthForMerging(idx)\n\t\t\tnumColumnsRendered++\n\t\t}\n\t}\n\tcolStr = align.Apply(colStr, maxColumnLength)\n\n\t// pad both sides of the column\n\tif !hint.isSeparatorRow || (hint.isSeparatorRow && mergeVertically) {\n\t\tcolStr = t.style.Box.PaddingLeft + colStr + t.style.Box.PaddingRight\n\t}\n\n\tt.renderColumnColorized(out, colIdx, colStr, hint)\n\n\treturn colIdx + numColumnsRendered\n}\n\nfunc (t *Table) renderColumnAutoIndex(out *strings.Builder, hint renderHint) {\n\tvar outAutoIndex strings.Builder\n\toutAutoIndex.Grow(t.maxColumnLengths[0])\n\n\tif hint.isSeparatorRow {\n\t\tnumChars := t.autoIndexVIndexMaxLength + utf8.RuneCountInString(t.style.Box.PaddingLeft) +\n\t\t\tutf8.RuneCountInString(t.style.Box.PaddingRight)\n\t\tchars := t.style.Box.MiddleHorizontal\n\t\tif hint.isAutoIndexColumn && hint.isHeaderOrFooterSeparator() {\n\t\t\tchars = text.RepeatAndTrim(\" \", len(t.style.Box.MiddleHorizontal))\n\t\t}\n\t\toutAutoIndex.WriteString(text.RepeatAndTrim(chars, numChars))\n\t} else {\n\t\toutAutoIndex.WriteString(t.style.Box.PaddingLeft)\n\t\trowNumStr := fmt.Sprint(hint.rowNumber)\n\t\tif hint.isHeaderRow || hint.isFooterRow || hint.rowLineNumber > 1 {\n\t\t\trowNumStr = strings.Repeat(\" \", t.autoIndexVIndexMaxLength)\n\t\t}\n\t\toutAutoIndex.WriteString(text.AlignRight.Apply(rowNumStr, t.autoIndexVIndexMaxLength))\n\t\toutAutoIndex.WriteString(t.style.Box.PaddingRight)\n\t}\n\n\tif t.style.Color.IndexColumn != nil {\n\t\tcolors := t.style.Color.IndexColumn\n\t\tif hint.isFooterRow {\n\t\t\tcolors = t.style.Color.Footer\n\t\t}\n\t\tout.WriteString(colors.Sprint(outAutoIndex.String()))\n\t} else {\n\t\tout.WriteString(outAutoIndex.String())\n\t}\n\thint.isAutoIndexColumn = true\n\tt.renderColumnSeparator(out, rowStr{}, 0, hint)\n}\n\nfunc (t *Table) renderColumnColorized(out *strings.Builder, colIdx int, colStr string, hint renderHint) {\n\tcolors := t.getColumnColors(colIdx, hint)\n\tif colors != nil {\n\t\tout.WriteString(colors.Sprint(colStr))\n\t} else if hint.isHeaderRow && t.style.Color.Header != nil {\n\t\tout.WriteString(t.style.Color.Header.Sprint(colStr))\n\t} else if hint.isFooterRow && t.style.Color.Footer != nil {\n\t\tout.WriteString(t.style.Color.Footer.Sprint(colStr))\n\t} else if hint.isRegularRow() {\n\t\tif colIdx == t.indexColumn-1 && t.style.Color.IndexColumn != nil {\n\t\t\tout.WriteString(t.style.Color.IndexColumn.Sprint(colStr))\n\t\t} else if hint.rowNumber%2 == 0 && t.style.Color.RowAlternate != nil {\n\t\t\tout.WriteString(t.style.Color.RowAlternate.Sprint(colStr))\n\t\t} else if t.style.Color.Row != nil {\n\t\t\tout.WriteString(t.style.Color.Row.Sprint(colStr))\n\t\t} else {\n\t\t\tout.WriteString(colStr)\n\t\t}\n\t} else {\n\t\tout.WriteString(colStr)\n\t}\n}\n\nfunc (t *Table) renderColumnSeparator(out *strings.Builder, row rowStr, colIdx int, hint renderHint) {\n\tif t.style.Options.SeparateColumns {\n\t\tseparator := t.getColumnSeparator(row, colIdx, hint)\n\n\t\tcolors := t.getSeparatorColors(hint)\n\t\tif colors.EscapeSeq() != \"\" {\n\t\t\tout.WriteString(colors.Sprint(separator))\n\t\t} else {\n\t\t\tout.WriteString(separator)\n\t\t}\n\t}\n}\n\nfunc (t *Table) renderLine(out *strings.Builder, row rowStr, hint renderHint) {\n\t// if the output has content, it means that this call is working on line\n\t// number 2 or more; separate them with a newline\n\tif out.Len() > 0 {\n\t\tout.WriteRune('\\n')\n\t}\n\n\t// use a brand-new strings.Builder if a row length limit has been set\n\tvar outLine *strings.Builder\n\tif t.allowedRowLength > 0 {\n\t\toutLine = &strings.Builder{}\n\t} else {\n\t\toutLine = out\n\t}\n\t// grow the strings.Builder to the maximum possible row length\n\toutLine.Grow(t.maxRowLength)\n\n\tnextColIdx := 0\n\tt.renderMarginLeft(outLine, hint)\n\tfor colIdx, maxColumnLength := range t.maxColumnLengths {\n\t\tif colIdx != nextColIdx {\n\t\t\tcontinue\n\t\t}\n\t\tnextColIdx = t.renderColumn(outLine, row, colIdx, maxColumnLength, hint)\n\t}\n\tt.renderMarginRight(outLine, hint)\n\n\t// merge the strings.Builder objects if a new one was created earlier\n\tif outLine != out {\n\t\tt.renderLineMergeOutputs(out, outLine)\n\t}\n\n\t// if a page size has been set, and said number of lines has already\n\t// been rendered, and the header is not being rendered right now, render\n\t// the header all over again with a spacing line\n\tif hint.isRegularRow() {\n\t\tt.numLinesRendered++\n\t\tif t.pageSize > 0 && t.numLinesRendered%t.pageSize == 0 && !hint.isLastLineOfLastRow() {\n\t\t\tt.renderRowsFooter(out)\n\t\t\tt.renderRowsBorderBottom(out)\n\t\t\tout.WriteString(t.style.Box.PageSeparator)\n\t\t\tt.renderRowsBorderTop(out)\n\t\t\tt.renderRowsHeader(out)\n\t\t}\n\t}\n}\n\nfunc (t *Table) renderLineMergeOutputs(out *strings.Builder, outLine *strings.Builder) {\n\toutLineStr := outLine.String()\n\tif text.RuneWidthWithoutEscSequences(outLineStr) > t.allowedRowLength {\n\t\ttrimLength := t.allowedRowLength - utf8.RuneCountInString(t.style.Box.UnfinishedRow)\n\t\tif trimLength > 0 {\n\t\t\tout.WriteString(text.Trim(outLineStr, trimLength))\n\t\t\tout.WriteString(t.style.Box.UnfinishedRow)\n\t\t}\n\t} else {\n\t\tout.WriteString(outLineStr)\n\t}\n}\n\nfunc (t *Table) renderMarginLeft(out *strings.Builder, hint renderHint) {\n\tout.WriteString(t.style.Format.Direction.Modifier())\n\tif t.style.Options.DrawBorder {\n\t\tborder := t.getBorderLeft(hint)\n\t\tcolors := t.getBorderColors(hint)\n\t\tif colors.EscapeSeq() != \"\" {\n\t\t\tout.WriteString(colors.Sprint(border))\n\t\t} else {\n\t\t\tout.WriteString(border)\n\t\t}\n\t}\n}\n\nfunc (t *Table) renderMarginRight(out *strings.Builder, hint renderHint) {\n\tif t.style.Options.DrawBorder {\n\t\tborder := t.getBorderRight(hint)\n\t\tcolors := t.getBorderColors(hint)\n\t\tif colors.EscapeSeq() != \"\" {\n\t\t\tout.WriteString(colors.Sprint(border))\n\t\t} else {\n\t\t\tout.WriteString(border)\n\t\t}\n\t}\n}\n\nfunc (t *Table) renderRow(out *strings.Builder, row rowStr, hint renderHint) {\n\tif len(row) > 0 {\n\t\t// fit every column into the allowedColumnLength/maxColumnLength limit\n\t\t// and in the process find the max. number of lines in any column in\n\t\t// this row\n\t\tcolMaxLines, rowWrapped := t.wrapRow(row)\n\n\t\t// if there is just 1 line in all columns, add the row as such; else\n\t\t// split each column into individual lines and render them one-by-one\n\t\tif colMaxLines == 1 {\n\t\t\thint.isLastLineOfRow = true\n\t\t\tt.renderLine(out, rowWrapped, hint)\n\t\t} else {\n\t\t\t// convert one row into N # of rows based on colMaxLines\n\t\t\trowLines := make([]rowStr, len(row))\n\t\t\tfor colIdx, colStr := range rowWrapped {\n\t\t\t\trowLines[colIdx] = t.getVAlign(colIdx, hint).ApplyStr(colStr, colMaxLines)\n\t\t\t}\n\t\t\tfor colLineIdx := 0; colLineIdx < colMaxLines; colLineIdx++ {\n\t\t\t\trowLine := make(rowStr, len(rowLines))\n\t\t\t\tfor colIdx, colLines := range rowLines {\n\t\t\t\t\trowLine[colIdx] = colLines[colLineIdx]\n\t\t\t\t}\n\t\t\t\thint.isLastLineOfRow = colLineIdx == colMaxLines-1\n\t\t\t\thint.rowLineNumber = colLineIdx + 1\n\t\t\t\tt.renderLine(out, rowLine, hint)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (t *Table) renderRowSeparator(out *strings.Builder, hint renderHint) {\n\tif hint.isBorderTop || hint.isBorderBottom {\n\t\tif !t.style.Options.DrawBorder {\n\t\t\treturn\n\t\t}\n\t} else if hint.isHeaderRow && !t.style.Options.SeparateHeader {\n\t\treturn\n\t} else if hint.isFooterRow && !t.style.Options.SeparateFooter {\n\t\treturn\n\t}\n\thint.isSeparatorRow = true\n\tt.renderLine(out, t.rowSeparator, hint)\n}\n\nfunc (t *Table) renderRows(out *strings.Builder, rows []rowStr, hint renderHint) {\n\tfor rowIdx, row := range rows {\n\t\thint.isFirstRow = rowIdx == 0\n\t\thint.isLastRow = rowIdx == len(rows)-1\n\t\thint.rowNumber = rowIdx + 1\n\t\tt.renderRow(out, row, hint)\n\n\t\tif (t.style.Options.SeparateRows && rowIdx < len(rows)-1) || // last row before footer\n\t\t\t(t.separators[rowIdx] && rowIdx != len(rows)-1) { // manually added separator not after last row\n\t\t\thint.isFirstRow = false\n\t\t\tt.renderRowSeparator(out, hint)\n\t\t}\n\t}\n}\n\nfunc (t *Table) renderRowsBorderBottom(out *strings.Builder) {\n\tif len(t.rowsFooter) > 0 {\n\t\tt.renderRowSeparator(out, renderHint{isBorderBottom: true, isFooterRow: true, rowNumber: len(t.rowsFooter)})\n\t} else {\n\t\tt.renderRowSeparator(out, renderHint{isBorderBottom: true, isFooterRow: false, rowNumber: len(t.rows)})\n\t}\n}\n\nfunc (t *Table) renderRowsBorderTop(out *strings.Builder) {\n\tif len(t.rowsHeader) > 0 || t.autoIndex {\n\t\tt.renderRowSeparator(out, renderHint{isBorderTop: true, isHeaderRow: true, rowNumber: 0})\n\t} else {\n\t\tt.renderRowSeparator(out, renderHint{isBorderTop: true, isHeaderRow: false, rowNumber: 0})\n\t}\n}\n\nfunc (t *Table) renderRowsFooter(out *strings.Builder) {\n\tif len(t.rowsFooter) > 0 {\n\t\tt.renderRowSeparator(out, renderHint{\n\t\t\tisFooterRow:    true,\n\t\t\tisFirstRow:     true,\n\t\t\tisSeparatorRow: true,\n\t\t})\n\t\tt.renderRows(out, t.rowsFooter, renderHint{isFooterRow: true})\n\t}\n}\n\nfunc (t *Table) renderRowsHeader(out *strings.Builder) {\n\tif len(t.rowsHeader) > 0 || t.autoIndex {\n\t\thintSeparator := renderHint{isHeaderRow: true, isLastRow: true, isSeparatorRow: true}\n\n\t\tif len(t.rowsHeader) > 0 {\n\t\t\tt.renderRows(out, t.rowsHeader, renderHint{isHeaderRow: true})\n\t\t\thintSeparator.rowNumber = len(t.rowsHeader)\n\t\t} else if t.autoIndex {\n\t\t\tt.renderRow(out, t.getAutoIndexColumnIDs(), renderHint{isAutoIndexRow: true, isHeaderRow: true})\n\t\t\thintSeparator.rowNumber = 1\n\t\t}\n\t\tt.renderRowSeparator(out, hintSeparator)\n\t}\n}\n\nfunc (t *Table) renderTitle(out *strings.Builder) {\n\tif t.title != \"\" {\n\t\tcolors := t.style.Title.Colors\n\t\tcolorsBorder := t.getBorderColors(renderHint{isTitleRow: true})\n\t\trowLength := t.maxRowLength\n\t\tif t.allowedRowLength != 0 && t.allowedRowLength < rowLength {\n\t\t\trowLength = t.allowedRowLength\n\t\t}\n\t\tif t.style.Options.DrawBorder {\n\t\t\tlenBorder := rowLength - text.RuneWidthWithoutEscSequences(t.style.Box.TopLeft+t.style.Box.TopRight)\n\t\t\tout.WriteString(colorsBorder.Sprint(t.style.Box.TopLeft))\n\t\t\tout.WriteString(colorsBorder.Sprint(text.RepeatAndTrim(t.style.Box.MiddleHorizontal, lenBorder)))\n\t\t\tout.WriteString(colorsBorder.Sprint(t.style.Box.TopRight))\n\t\t}\n\n\t\tlenText := rowLength - text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft+t.style.Box.PaddingRight)\n\t\tif t.style.Options.DrawBorder {\n\t\t\tlenText -= text.RuneWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)\n\t\t}\n\t\ttitleText := text.WrapText(t.title, lenText)\n\t\tfor _, titleLine := range strings.Split(titleText, \"\\n\") {\n\t\t\tt.renderTitleLine(out, lenText, titleLine, colors, colorsBorder)\n\t\t}\n\t}\n}\n\nfunc (t *Table) renderTitleLine(out *strings.Builder, lenText int, titleLine string, colors text.Colors, colorsBorder text.Colors) {\n\ttitleLine = strings.TrimSpace(titleLine)\n\ttitleLine = t.style.Title.Format.Apply(titleLine)\n\ttitleLine = t.style.Title.Align.Apply(titleLine, lenText)\n\ttitleLine = t.style.Box.PaddingLeft + titleLine + t.style.Box.PaddingRight\n\n\tif out.Len() > 0 {\n\t\tout.WriteRune('\\n')\n\t}\n\tif t.style.Options.DrawBorder {\n\t\tout.WriteString(colorsBorder.Sprint(t.style.Box.Left))\n\t}\n\tout.WriteString(colors.Sprint(titleLine))\n\tif t.style.Options.DrawBorder {\n\t\tout.WriteString(colorsBorder.Sprint(t.style.Box.Right))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/render_csv.go",
    "content": "package table\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// RenderCSV renders the Table in CSV format. Example:\n//\n//\t#,First Name,Last Name,Salary,\n//\t1,Arya,Stark,3000,\n//\t20,Jon,Snow,2000,\"You know nothing\\, Jon Snow!\"\n//\t300,Tyrion,Lannister,5000,\n//\t,,Total,10000,\nfunc (t *Table) RenderCSV() string {\n\tt.initForRender()\n\n\tvar out strings.Builder\n\tif t.numColumns > 0 {\n\t\tif t.title != \"\" {\n\t\t\tout.WriteString(t.title)\n\t\t}\n\t\tif t.autoIndex && len(t.rowsHeader) == 0 {\n\t\t\tt.csvRenderRow(&out, t.getAutoIndexColumnIDs(), renderHint{isAutoIndexRow: true, isHeaderRow: true})\n\t\t}\n\t\tt.csvRenderRows(&out, t.rowsHeader, renderHint{isHeaderRow: true})\n\t\tt.csvRenderRows(&out, t.rows, renderHint{})\n\t\tt.csvRenderRows(&out, t.rowsFooter, renderHint{isFooterRow: true})\n\t\tif t.caption != \"\" {\n\t\t\tout.WriteRune('\\n')\n\t\t\tout.WriteString(t.caption)\n\t\t}\n\t}\n\treturn t.render(&out)\n}\n\nfunc (t *Table) csvFixCommas(str string) string {\n\treturn strings.Replace(str, \",\", \"\\\\,\", -1)\n}\n\nfunc (t *Table) csvFixDoubleQuotes(str string) string {\n\treturn strings.Replace(str, \"\\\"\", \"\\\\\\\"\", -1)\n}\n\nfunc (t *Table) csvRenderRow(out *strings.Builder, row rowStr, hint renderHint) {\n\t// when working on line number 2 or more, insert a newline first\n\tif out.Len() > 0 {\n\t\tout.WriteRune('\\n')\n\t}\n\n\t// generate the columns to render in CSV format and append to \"out\"\n\tfor colIdx, colStr := range row {\n\t\t// auto-index column\n\t\tif colIdx == 0 && t.autoIndex {\n\t\t\tif hint.isRegularRow() {\n\t\t\t\tout.WriteString(fmt.Sprint(hint.rowNumber))\n\t\t\t}\n\t\t\tout.WriteRune(',')\n\t\t}\n\t\tif colIdx > 0 {\n\t\t\tout.WriteRune(',')\n\t\t}\n\t\tif strings.ContainsAny(colStr, \"\\\",\\n\") {\n\t\t\tout.WriteRune('\"')\n\t\t\tout.WriteString(t.csvFixCommas(t.csvFixDoubleQuotes(colStr)))\n\t\t\tout.WriteRune('\"')\n\t\t} else if utf8.RuneCountInString(colStr) > 0 {\n\t\t\tout.WriteString(colStr)\n\t\t}\n\t}\n\tfor colIdx := len(row); colIdx < t.numColumns; colIdx++ {\n\t\tout.WriteRune(',')\n\t}\n}\n\nfunc (t *Table) csvRenderRows(out *strings.Builder, rows []rowStr, hint renderHint) {\n\tfor rowIdx, row := range rows {\n\t\thint.rowNumber = rowIdx + 1\n\t\tt.csvRenderRow(out, row, hint)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/render_hint.go",
    "content": "package table\n\n// renderHint has hints for the Render*() logic\ntype renderHint struct {\n\tisAutoIndexColumn bool // auto-index column?\n\tisAutoIndexRow    bool // auto-index row?\n\tisBorderBottom    bool // bottom-border?\n\tisBorderTop       bool // top-border?\n\tisFirstRow        bool // first-row of header/footer/regular-rows?\n\tisFooterRow       bool // footer row?\n\tisHeaderRow       bool // header row?\n\tisLastLineOfRow   bool // last-line of the current row?\n\tisLastRow         bool // last-row of header/footer/regular-rows?\n\tisSeparatorRow    bool // separator row?\n\tisTitleRow        bool // title row?\n\trowLineNumber     int  // the line number for a multi-line row\n\trowNumber         int  // the row number/index\n}\n\nfunc (h *renderHint) isBorderOrSeparator() bool {\n\treturn h.isBorderTop || h.isSeparatorRow || h.isBorderBottom\n}\n\nfunc (h *renderHint) isRegularRow() bool {\n\treturn !h.isHeaderRow && !h.isFooterRow\n}\n\nfunc (h *renderHint) isRegularNonSeparatorRow() bool {\n\treturn !h.isHeaderRow && !h.isFooterRow && !h.isSeparatorRow\n}\n\nfunc (h *renderHint) isHeaderOrFooterSeparator() bool {\n\treturn h.isSeparatorRow && !h.isBorderBottom && !h.isBorderTop &&\n\t\t((h.isHeaderRow && !h.isLastRow) || (h.isFooterRow && (!h.isFirstRow || h.rowNumber > 0)))\n}\n\nfunc (h *renderHint) isLastLineOfLastRow() bool {\n\treturn h.isLastLineOfRow && h.isLastRow\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/render_html.go",
    "content": "package table\n\nimport (\n\t\"fmt\"\n\t\"html\"\n\t\"strings\"\n)\n\nconst (\n\t// DefaultHTMLCSSClass stores the css-class to use when none-provided via\n\t// SetHTMLCSSClass(cssClass string).\n\tDefaultHTMLCSSClass = \"go-pretty-table\"\n)\n\n// RenderHTML renders the Table in HTML format. Example:\n//\n//\t<table class=\"go-pretty-table\">\n//\t  <thead>\n//\t  <tr>\n//\t    <th align=\"right\">#</th>\n//\t    <th>First Name</th>\n//\t    <th>Last Name</th>\n//\t    <th align=\"right\">Salary</th>\n//\t    <th>&nbsp;</th>\n//\t  </tr>\n//\t  </thead>\n//\t  <tbody>\n//\t  <tr>\n//\t    <td align=\"right\">1</td>\n//\t    <td>Arya</td>\n//\t    <td>Stark</td>\n//\t    <td align=\"right\">3000</td>\n//\t    <td>&nbsp;</td>\n//\t  </tr>\n//\t  <tr>\n//\t    <td align=\"right\">20</td>\n//\t    <td>Jon</td>\n//\t    <td>Snow</td>\n//\t    <td align=\"right\">2000</td>\n//\t    <td>You know nothing, Jon Snow!</td>\n//\t  </tr>\n//\t  <tr>\n//\t    <td align=\"right\">300</td>\n//\t    <td>Tyrion</td>\n//\t    <td>Lannister</td>\n//\t    <td align=\"right\">5000</td>\n//\t    <td>&nbsp;</td>\n//\t  </tr>\n//\t  </tbody>\n//\t  <tfoot>\n//\t  <tr>\n//\t    <td align=\"right\">&nbsp;</td>\n//\t    <td>&nbsp;</td>\n//\t    <td>Total</td>\n//\t    <td align=\"right\">10000</td>\n//\t    <td>&nbsp;</td>\n//\t  </tr>\n//\t  </tfoot>\n//\t</table>\nfunc (t *Table) RenderHTML() string {\n\tt.initForRender()\n\n\tvar out strings.Builder\n\tif t.numColumns > 0 {\n\t\tout.WriteString(\"<table class=\\\"\")\n\t\tif t.htmlCSSClass != \"\" {\n\t\t\tout.WriteString(t.htmlCSSClass)\n\t\t} else {\n\t\t\tout.WriteString(t.style.HTML.CSSClass)\n\t\t}\n\t\tout.WriteString(\"\\\">\\n\")\n\t\tt.htmlRenderTitle(&out)\n\t\tt.htmlRenderRowsHeader(&out)\n\t\tt.htmlRenderRows(&out, t.rows, renderHint{})\n\t\tt.htmlRenderRowsFooter(&out)\n\t\tt.htmlRenderCaption(&out)\n\t\tout.WriteString(\"</table>\")\n\t}\n\treturn t.render(&out)\n}\n\nfunc (t *Table) htmlGetColStrAndTag(row rowStr, colIdx int, hint renderHint) (string, string) {\n\t// get the column contents\n\tvar colStr string\n\tif colIdx < len(row) {\n\t\tcolStr = row[colIdx]\n\t}\n\n\t// header uses \"th\" instead of \"td\"\n\tcolTagName := \"td\"\n\tif hint.isHeaderRow {\n\t\tcolTagName = \"th\"\n\t}\n\n\treturn colStr, colTagName\n}\n\nfunc (t *Table) htmlRenderCaption(out *strings.Builder) {\n\tif t.caption != \"\" {\n\t\tout.WriteString(\"  <caption class=\\\"caption\\\" style=\\\"caption-side: bottom;\\\">\")\n\t\tout.WriteString(t.caption)\n\t\tout.WriteString(\"</caption>\\n\")\n\t}\n}\n\nfunc (t *Table) htmlRenderColumn(out *strings.Builder, colStr string) {\n\tif t.style.HTML.EscapeText {\n\t\tcolStr = html.EscapeString(colStr)\n\t}\n\tif t.style.HTML.Newline != \"\\n\" {\n\t\tcolStr = strings.Replace(colStr, \"\\n\", t.style.HTML.Newline, -1)\n\t}\n\tout.WriteString(colStr)\n}\n\nfunc (t *Table) htmlRenderColumnAttributes(out *strings.Builder, colIdx int, hint renderHint) {\n\t// determine the HTML \"align\"/\"valign\" property values\n\talign := t.getAlign(colIdx, hint).HTMLProperty()\n\tvAlign := t.getVAlign(colIdx, hint).HTMLProperty()\n\t// determine the HTML \"class\" property values for the colors\n\tclass := t.getColumnColors(colIdx, hint).HTMLProperty()\n\n\tif align != \"\" {\n\t\tout.WriteRune(' ')\n\t\tout.WriteString(align)\n\t}\n\tif class != \"\" {\n\t\tout.WriteRune(' ')\n\t\tout.WriteString(class)\n\t}\n\tif vAlign != \"\" {\n\t\tout.WriteRune(' ')\n\t\tout.WriteString(vAlign)\n\t}\n}\n\nfunc (t *Table) htmlRenderColumnAutoIndex(out *strings.Builder, hint renderHint) {\n\tif hint.isHeaderRow {\n\t\tout.WriteString(\"    <th>\")\n\t\tout.WriteString(t.style.HTML.EmptyColumn)\n\t\tout.WriteString(\"</th>\\n\")\n\t} else if hint.isFooterRow {\n\t\tout.WriteString(\"    <td>\")\n\t\tout.WriteString(t.style.HTML.EmptyColumn)\n\t\tout.WriteString(\"</td>\\n\")\n\t} else {\n\t\tout.WriteString(\"    <td align=\\\"right\\\">\")\n\t\tout.WriteString(fmt.Sprint(hint.rowNumber))\n\t\tout.WriteString(\"</td>\\n\")\n\t}\n}\n\nfunc (t *Table) htmlRenderRow(out *strings.Builder, row rowStr, hint renderHint) {\n\tout.WriteString(\"  <tr>\\n\")\n\tfor colIdx := 0; colIdx < t.numColumns; colIdx++ {\n\t\t// auto-index column\n\t\tif colIdx == 0 && t.autoIndex {\n\t\t\tt.htmlRenderColumnAutoIndex(out, hint)\n\t\t}\n\n\t\tcolStr, colTagName := t.htmlGetColStrAndTag(row, colIdx, hint)\n\t\t// write the row\n\t\tout.WriteString(\"    <\")\n\t\tout.WriteString(colTagName)\n\t\tt.htmlRenderColumnAttributes(out, colIdx, hint)\n\t\tout.WriteString(\">\")\n\t\tif len(colStr) == 0 {\n\t\t\tout.WriteString(t.style.HTML.EmptyColumn)\n\t\t} else {\n\t\t\tt.htmlRenderColumn(out, colStr)\n\t\t}\n\t\tout.WriteString(\"</\")\n\t\tout.WriteString(colTagName)\n\t\tout.WriteString(\">\\n\")\n\t}\n\tout.WriteString(\"  </tr>\\n\")\n}\n\nfunc (t *Table) htmlRenderRows(out *strings.Builder, rows []rowStr, hint renderHint) {\n\tif len(rows) > 0 {\n\t\t// determine that tag to use based on the type of the row\n\t\trowsTag := \"tbody\"\n\t\tif hint.isHeaderRow {\n\t\t\trowsTag = \"thead\"\n\t\t} else if hint.isFooterRow {\n\t\t\trowsTag = \"tfoot\"\n\t\t}\n\n\t\tvar renderedTagOpen, shouldRenderTagClose bool\n\t\tfor idx, row := range rows {\n\t\t\thint.rowNumber = idx + 1\n\t\t\tif len(row) > 0 {\n\t\t\t\tif !renderedTagOpen {\n\t\t\t\t\tout.WriteString(\"  <\")\n\t\t\t\t\tout.WriteString(rowsTag)\n\t\t\t\t\tout.WriteString(\">\\n\")\n\t\t\t\t\trenderedTagOpen = true\n\t\t\t\t}\n\t\t\t\tt.htmlRenderRow(out, row, hint)\n\t\t\t\tshouldRenderTagClose = true\n\t\t\t}\n\t\t}\n\t\tif shouldRenderTagClose {\n\t\t\tout.WriteString(\"  </\")\n\t\t\tout.WriteString(rowsTag)\n\t\t\tout.WriteString(\">\\n\")\n\t\t}\n\t}\n}\n\nfunc (t *Table) htmlRenderRowsFooter(out *strings.Builder) {\n\tif len(t.rowsFooter) > 0 {\n\t\tt.htmlRenderRows(out, t.rowsFooter, renderHint{isFooterRow: true})\n\t}\n}\n\nfunc (t *Table) htmlRenderRowsHeader(out *strings.Builder) {\n\tif len(t.rowsHeader) > 0 {\n\t\tt.htmlRenderRows(out, t.rowsHeader, renderHint{isHeaderRow: true})\n\t} else if t.autoIndex {\n\t\thint := renderHint{isAutoIndexRow: true, isHeaderRow: true}\n\t\tt.htmlRenderRows(out, []rowStr{t.getAutoIndexColumnIDs()}, hint)\n\t}\n}\n\nfunc (t *Table) htmlRenderTitle(out *strings.Builder) {\n\tif t.title != \"\" {\n\t\talign := t.style.Title.Align.HTMLProperty()\n\t\tcolors := t.style.Title.Colors.HTMLProperty()\n\t\ttitle := t.style.Title.Format.Apply(t.title)\n\n\t\tout.WriteString(\"  <caption class=\\\"title\\\"\")\n\t\tif align != \"\" {\n\t\t\tout.WriteRune(' ')\n\t\t\tout.WriteString(align)\n\t\t}\n\t\tif colors != \"\" {\n\t\t\tout.WriteRune(' ')\n\t\t\tout.WriteString(colors)\n\t\t}\n\t\tout.WriteRune('>')\n\t\tout.WriteString(title)\n\t\tout.WriteString(\"</caption>\\n\")\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/render_init.go",
    "content": "package table\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/jedib0t/go-pretty/v6/text\"\n)\n\nfunc (t *Table) analyzeAndStringify(row Row, hint renderHint) rowStr {\n\t// update t.numColumns if this row is the longest seen till now\n\tif len(row) > t.numColumns {\n\t\t// init the slice for the first time; and pad it the rest of the time\n\t\tif t.numColumns == 0 {\n\t\t\tt.columnIsNonNumeric = make([]bool, len(row))\n\t\t} else {\n\t\t\tt.columnIsNonNumeric = append(t.columnIsNonNumeric, make([]bool, len(row)-t.numColumns)...)\n\t\t}\n\t\t// update t.numColumns\n\t\tt.numColumns = len(row)\n\t}\n\n\t// convert each column to string and figure out if it has non-numeric data\n\trowOut := make(rowStr, len(row))\n\tfor colIdx, col := range row {\n\t\t// if the column is not a number, keep track of it\n\t\tif !hint.isHeaderRow && !hint.isFooterRow && !t.columnIsNonNumeric[colIdx] && !isNumber(col) {\n\t\t\tt.columnIsNonNumeric[colIdx] = true\n\t\t}\n\n\t\trowOut[colIdx] = t.analyzeAndStringifyColumn(colIdx, col, hint)\n\t}\n\treturn rowOut\n}\n\nfunc (t *Table) analyzeAndStringifyColumn(colIdx int, col interface{}, hint renderHint) string {\n\t// convert to a string and store it in the row\n\tvar colStr string\n\tif transformer := t.getColumnTransformer(colIdx, hint); transformer != nil {\n\t\tcolStr = transformer(col)\n\t} else if colStrVal, ok := col.(string); ok {\n\t\tcolStr = colStrVal\n\t} else {\n\t\tcolStr = fmt.Sprint(col)\n\t}\n\tcolStr = strings.ReplaceAll(colStr, \"\\t\", \"    \")\n\tcolStr = strings.ReplaceAll(colStr, \"\\r\", \"\")\n\treturn fmt.Sprintf(\"%s%s\", t.style.Format.Direction.Modifier(), colStr)\n}\n\nfunc (t *Table) extractMaxColumnLengths(rows []rowStr, hint renderHint) {\n\tfor rowIdx, row := range rows {\n\t\thint.rowNumber = rowIdx + 1\n\t\tt.extractMaxColumnLengthsFromRow(row, t.getMergedColumnIndices(row, hint))\n\t}\n}\n\nfunc (t *Table) extractMaxColumnLengthsFromRow(row rowStr, mci mergedColumnIndices) {\n\tfor colIdx, colStr := range row {\n\t\tlongestLineLen := text.LongestLineLen(colStr)\n\t\tmaxColWidth := t.getColumnWidthMax(colIdx)\n\t\tif maxColWidth > 0 && maxColWidth < longestLineLen {\n\t\t\tlongestLineLen = maxColWidth\n\t\t}\n\t\tmergedColumnsLength := mci.mergedLength(colIdx, t.maxColumnLengths)\n\t\tif longestLineLen > mergedColumnsLength {\n\t\t\tif mergedColumnsLength > 0 {\n\t\t\t\tt.extractMaxColumnLengthsFromRowForMergedColumns(colIdx, longestLineLen, mci)\n\t\t\t} else {\n\t\t\t\tt.maxColumnLengths[colIdx] = longestLineLen\n\t\t\t}\n\t\t} else if maxColWidth == 0 && longestLineLen > t.maxColumnLengths[colIdx] {\n\t\t\tt.maxColumnLengths[colIdx] = longestLineLen\n\t\t}\n\t}\n}\n\nfunc (t *Table) extractMaxColumnLengthsFromRowForMergedColumns(colIdx int, mergedColumnLength int, mci mergedColumnIndices) {\n\tnumMergedColumns := mci.len(colIdx)\n\tmergedColumnLength -= (numMergedColumns - 1) * text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator)\n\tmaxLengthSplitAcrossColumns := mergedColumnLength / numMergedColumns\n\tif maxLengthSplitAcrossColumns > t.maxColumnLengths[colIdx] {\n\t\tt.maxColumnLengths[colIdx] = maxLengthSplitAcrossColumns\n\t}\n\tfor otherColIdx := range mci[colIdx] {\n\t\tif maxLengthSplitAcrossColumns > t.maxColumnLengths[otherColIdx] {\n\t\t\tt.maxColumnLengths[otherColIdx] = maxLengthSplitAcrossColumns\n\t\t}\n\t}\n}\n\nfunc (t *Table) initForRender() {\n\t// pick a default style if none was set until now\n\tt.Style()\n\n\t// reset rendering state\n\tt.reset()\n\n\t// initialize the column configs and normalize them\n\tt.initForRenderColumnConfigs()\n\n\t// initialize and stringify all the raw rows\n\tt.initForRenderRows()\n\n\t// find the longest continuous line in each column\n\tt.initForRenderColumnLengths()\n\n\t// generate a separator row and calculate maximum row length\n\tt.initForRenderRowSeparator()\n\n\t// reset the counter for the number of lines rendered\n\tt.numLinesRendered = 0\n}\n\nfunc (t *Table) initForRenderColumnConfigs() {\n\tt.columnConfigMap = map[int]ColumnConfig{}\n\tfor _, colCfg := range t.columnConfigs {\n\t\t// find the column number if none provided; this logic can work only if\n\t\t// a header row is present and has a column with the given name\n\t\tif colCfg.Number == 0 {\n\t\t\tfor _, row := range t.rowsHeaderRaw {\n\t\t\t\tcolCfg.Number = row.findColumnNumber(colCfg.Name)\n\t\t\t\tif colCfg.Number > 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif colCfg.Number > 0 {\n\t\t\tt.columnConfigMap[colCfg.Number-1] = colCfg\n\t\t}\n\t}\n}\n\nfunc (t *Table) initForRenderColumnLengths() {\n\tt.maxColumnLengths = make([]int, t.numColumns)\n\tt.extractMaxColumnLengths(t.rowsHeader, renderHint{isHeaderRow: true})\n\tt.extractMaxColumnLengths(t.rows, renderHint{})\n\tt.extractMaxColumnLengths(t.rowsFooter, renderHint{isFooterRow: true})\n\n\t// increase the column lengths if any are under the limits\n\tfor colIdx := range t.maxColumnLengths {\n\t\tminWidth := t.getColumnWidthMin(colIdx)\n\t\tif minWidth > 0 && t.maxColumnLengths[colIdx] < minWidth {\n\t\t\tt.maxColumnLengths[colIdx] = minWidth\n\t\t}\n\t}\n}\n\nfunc (t *Table) initForRenderHideColumns() {\n\tif !t.hasHiddenColumns() {\n\t\treturn\n\t}\n\tcolIdxMap := t.hideColumns()\n\n\t// re-create columnIsNonNumeric with new column indices\n\tcolumnIsNonNumeric := make([]bool, t.numColumns)\n\tfor oldColIdx, nonNumeric := range t.columnIsNonNumeric {\n\t\tif newColIdx, ok := colIdxMap[oldColIdx]; ok {\n\t\t\tcolumnIsNonNumeric[newColIdx] = nonNumeric\n\t\t}\n\t}\n\tt.columnIsNonNumeric = columnIsNonNumeric\n\n\t// re-create columnConfigMap with new column indices\n\tcolumnConfigMap := make(map[int]ColumnConfig)\n\tfor oldColIdx, cc := range t.columnConfigMap {\n\t\tif newColIdx, ok := colIdxMap[oldColIdx]; ok {\n\t\t\tcolumnConfigMap[newColIdx] = cc\n\t\t}\n\t}\n\tt.columnConfigMap = columnConfigMap\n}\n\nfunc (t *Table) initForRenderRows() {\n\t// auto-index: calc the index column's max length\n\tt.autoIndexVIndexMaxLength = len(fmt.Sprint(len(t.rowsRaw)))\n\n\t// stringify all the rows to make it easy to render\n\tif t.rowPainter != nil {\n\t\tt.rowsColors = make([]text.Colors, len(t.rowsRaw))\n\t}\n\tt.rows = t.initForRenderRowsStringify(t.rowsRaw, renderHint{})\n\tt.rowsFooter = t.initForRenderRowsStringify(t.rowsFooterRaw, renderHint{isFooterRow: true})\n\tt.rowsHeader = t.initForRenderRowsStringify(t.rowsHeaderRaw, renderHint{isHeaderRow: true})\n\n\t// sort the rows as requested\n\tt.initForRenderSortRows()\n\n\t// suppress columns without any content\n\tt.initForRenderSuppressColumns()\n\n\t// strip out hidden columns\n\tt.initForRenderHideColumns()\n}\n\nfunc (t *Table) initForRenderRowsStringify(rows []Row, hint renderHint) []rowStr {\n\trowsStr := make([]rowStr, len(rows))\n\tfor idx, row := range rows {\n\t\tif t.rowPainter != nil && hint.isRegularRow() {\n\t\t\tt.rowsColors[idx] = t.rowPainter(row)\n\t\t}\n\t\trowsStr[idx] = t.analyzeAndStringify(row, hint)\n\t}\n\treturn rowsStr\n}\n\nfunc (t *Table) initForRenderRowSeparator() {\n\tt.maxRowLength = 0\n\tif t.autoIndex {\n\t\tt.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft)\n\t\tt.maxRowLength += len(fmt.Sprint(len(t.rows)))\n\t\tt.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingRight)\n\t\tif t.style.Options.SeparateColumns {\n\t\t\tt.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator)\n\t\t}\n\t}\n\tif t.style.Options.SeparateColumns {\n\t\tt.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.MiddleSeparator) * (t.numColumns - 1)\n\t}\n\tt.rowSeparator = make(rowStr, t.numColumns)\n\tfor colIdx, maxColumnLength := range t.maxColumnLengths {\n\t\tmaxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingLeft + t.style.Box.PaddingRight)\n\t\tt.maxRowLength += maxColumnLength\n\t\tt.rowSeparator[colIdx] = text.RepeatAndTrim(t.style.Box.MiddleHorizontal, maxColumnLength)\n\t}\n\tif t.style.Options.DrawBorder {\n\t\tt.maxRowLength += text.RuneWidthWithoutEscSequences(t.style.Box.Left + t.style.Box.Right)\n\t}\n}\n\nfunc (t *Table) initForRenderSortRows() {\n\tif len(t.sortBy) == 0 {\n\t\treturn\n\t}\n\n\t// sort the rows\n\tsortedRowIndices := t.getSortedRowIndices()\n\tsortedRows := make([]rowStr, len(t.rows))\n\tfor idx := range t.rows {\n\t\tsortedRows[idx] = t.rows[sortedRowIndices[idx]]\n\t}\n\tt.rows = sortedRows\n\n\t// sort the rowsColors\n\tif len(t.rowsColors) > 0 {\n\t\tsortedRowsColors := make([]text.Colors, len(t.rows))\n\t\tfor idx := range t.rows {\n\t\t\tsortedRowsColors[idx] = t.rowsColors[sortedRowIndices[idx]]\n\t\t}\n\t\tt.rowsColors = sortedRowsColors\n\t}\n}\n\nfunc (t *Table) initForRenderSuppressColumns() {\n\tshouldSuppressColumn := func(colIdx int) bool {\n\t\tfor _, row := range t.rows {\n\t\t\tif colIdx < len(row) && row[colIdx] != \"\" {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\n\tif t.suppressEmptyColumns {\n\t\tfor colIdx := 0; colIdx < t.numColumns; colIdx++ {\n\t\t\tif shouldSuppressColumn(colIdx) {\n\t\t\t\tcc := t.columnConfigMap[colIdx]\n\t\t\t\tcc.Hidden = true\n\t\t\t\tt.columnConfigMap[colIdx] = cc\n\t\t\t}\n\t\t}\n\t}\n}\n\n// reset initializes all the variables used to maintain rendering information\n// that are written to in this file\nfunc (t *Table) reset() {\n\tt.autoIndexVIndexMaxLength = 0\n\tt.columnConfigMap = nil\n\tt.columnIsNonNumeric = nil\n\tt.maxColumnLengths = nil\n\tt.maxRowLength = 0\n\tt.numColumns = 0\n\tt.numLinesRendered = 0\n\tt.rowSeparator = nil\n\tt.rows = nil\n\tt.rowsColors = nil\n\tt.rowsFooter = nil\n\tt.rowsHeader = nil\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/render_markdown.go",
    "content": "package table\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// RenderMarkdown renders the Table in Markdown format. Example:\n//\n//\t| # | First Name | Last Name | Salary |  |\n//\t| ---:| --- | --- | ---:| --- |\n//\t| 1 | Arya | Stark | 3000 |  |\n//\t| 20 | Jon | Snow | 2000 | You know nothing, Jon Snow! |\n//\t| 300 | Tyrion | Lannister | 5000 |  |\n//\t|  |  | Total | 10000 |  |\nfunc (t *Table) RenderMarkdown() string {\n\tt.initForRender()\n\n\tvar out strings.Builder\n\tif t.numColumns > 0 {\n\t\tt.markdownRenderTitle(&out)\n\t\tt.markdownRenderRowsHeader(&out)\n\t\tt.markdownRenderRows(&out, t.rows, renderHint{})\n\t\tt.markdownRenderRowsFooter(&out)\n\t\tt.markdownRenderCaption(&out)\n\t}\n\treturn t.render(&out)\n}\n\nfunc (t *Table) markdownRenderCaption(out *strings.Builder) {\n\tif t.caption != \"\" {\n\t\tout.WriteRune('\\n')\n\t\tout.WriteRune('_')\n\t\tout.WriteString(t.caption)\n\t\tout.WriteRune('_')\n\t}\n}\n\nfunc (t *Table) markdownRenderRow(out *strings.Builder, row rowStr, hint renderHint) {\n\t// when working on line number 2 or more, insert a newline first\n\tif out.Len() > 0 {\n\t\tout.WriteRune('\\n')\n\t}\n\n\t// render each column up to the max. columns seen in all the rows\n\tout.WriteRune('|')\n\tfor colIdx := 0; colIdx < t.numColumns; colIdx++ {\n\t\tt.markdownRenderRowAutoIndex(out, colIdx, hint)\n\n\t\tif hint.isSeparatorRow {\n\t\t\tout.WriteString(t.getAlign(colIdx, hint).MarkdownProperty())\n\t\t} else {\n\t\t\tvar colStr string\n\t\t\tif colIdx < len(row) {\n\t\t\t\tcolStr = row[colIdx]\n\t\t\t}\n\t\t\tout.WriteRune(' ')\n\t\t\tcolStr = strings.ReplaceAll(colStr, \"|\", \"\\\\|\")\n\t\t\tcolStr = strings.ReplaceAll(colStr, \"\\n\", \"<br/>\")\n\t\t\tout.WriteString(colStr)\n\t\t\tout.WriteRune(' ')\n\t\t}\n\t\tout.WriteRune('|')\n\t}\n}\n\nfunc (t *Table) markdownRenderRowAutoIndex(out *strings.Builder, colIdx int, hint renderHint) {\n\tif colIdx == 0 && t.autoIndex {\n\t\tout.WriteRune(' ')\n\t\tif hint.isSeparatorRow {\n\t\t\tout.WriteString(\"---:\")\n\t\t} else if hint.isRegularRow() {\n\t\t\tout.WriteString(fmt.Sprintf(\"%d \", hint.rowNumber))\n\t\t}\n\t\tout.WriteRune('|')\n\t}\n}\n\nfunc (t *Table) markdownRenderRows(out *strings.Builder, rows []rowStr, hint renderHint) {\n\tif len(rows) > 0 {\n\t\tfor idx, row := range rows {\n\t\t\thint.rowNumber = idx + 1\n\t\t\tt.markdownRenderRow(out, row, hint)\n\n\t\t\tif idx == len(rows)-1 && hint.isHeaderRow {\n\t\t\t\tt.markdownRenderRow(out, t.rowSeparator, renderHint{isSeparatorRow: true})\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (t *Table) markdownRenderRowsFooter(out *strings.Builder) {\n\tt.markdownRenderRows(out, t.rowsFooter, renderHint{isFooterRow: true})\n}\n\nfunc (t *Table) markdownRenderRowsHeader(out *strings.Builder) {\n\tif len(t.rowsHeader) > 0 {\n\t\tt.markdownRenderRows(out, t.rowsHeader, renderHint{isHeaderRow: true})\n\t} else if t.autoIndex {\n\t\tt.markdownRenderRows(out, []rowStr{t.getAutoIndexColumnIDs()}, renderHint{isAutoIndexRow: true, isHeaderRow: true})\n\t}\n}\n\nfunc (t *Table) markdownRenderTitle(out *strings.Builder) {\n\tif t.title != \"\" {\n\t\tout.WriteString(\"# \")\n\t\tout.WriteString(t.title)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/render_tsv.go",
    "content": "package table\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc (t *Table) RenderTSV() string {\n\tt.initForRender()\n\n\tvar out strings.Builder\n\n\tif t.numColumns > 0 {\n\t\tif t.title != \"\" {\n\t\t\tout.WriteString(t.title)\n\t\t}\n\n\t\tif t.autoIndex && len(t.rowsHeader) == 0 {\n\t\t\tt.tsvRenderRow(&out, t.getAutoIndexColumnIDs(), renderHint{isAutoIndexRow: true, isHeaderRow: true})\n\t\t}\n\n\t\tt.tsvRenderRows(&out, t.rowsHeader, renderHint{isHeaderRow: true})\n\t\tt.tsvRenderRows(&out, t.rows, renderHint{})\n\t\tt.tsvRenderRows(&out, t.rowsFooter, renderHint{isFooterRow: true})\n\n\t\tif t.caption != \"\" {\n\t\t\tout.WriteRune('\\n')\n\t\t\tout.WriteString(t.caption)\n\t\t}\n\t}\n\n\treturn t.render(&out)\n}\n\nfunc (t *Table) tsvRenderRow(out *strings.Builder, row rowStr, hint renderHint) {\n\tif out.Len() > 0 {\n\t\tout.WriteRune('\\n')\n\t}\n\n\tfor idx, col := range row {\n\t\tif idx == 0 && t.autoIndex {\n\t\t\tif hint.isRegularRow() {\n\t\t\t\tout.WriteString(fmt.Sprint(hint.rowNumber))\n\t\t\t}\n\t\t\tout.WriteRune('\\t')\n\t\t}\n\n\t\tif idx > 0 {\n\t\t\tout.WriteRune('\\t')\n\t\t}\n\n\t\tif strings.ContainsAny(col, \"\\t\\n\\\"\") || strings.Contains(col, \"    \") {\n\t\t\tout.WriteString(fmt.Sprintf(\"\\\"%s\\\"\", t.tsvFixDoubleQuotes(col)))\n\t\t} else {\n\t\t\tout.WriteString(col)\n\t\t}\n\t}\n\n\tfor colIdx := len(row); colIdx < t.numColumns; colIdx++ {\n\t\tout.WriteRune('\\t')\n\t}\n}\n\nfunc (t *Table) tsvFixDoubleQuotes(str string) string {\n\treturn strings.Replace(str, \"\\\"\", \"\\\"\\\"\", -1)\n}\n\nfunc (t *Table) tsvRenderRows(out *strings.Builder, rows []rowStr, hint renderHint) {\n\tfor idx, row := range rows {\n\t\thint.rowNumber = idx + 1\n\t\tt.tsvRenderRow(out, row, hint)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/sort.go",
    "content": "package table\n\nimport (\n\t\"sort\"\n\t\"strconv\"\n)\n\n// SortBy defines What to sort (Column Name or Number), and How to sort (Mode).\ntype SortBy struct {\n\t// Name is the name of the Column as it appears in the first Header row.\n\t// If a Header is not provided, or the name is not found in the header, this\n\t// will not work.\n\tName string\n\t// Number is the Column # from left. When specified, it overrides the Name\n\t// property. If you know the exact Column number, use this instead of Name.\n\tNumber int\n\n\t// Mode tells the Writer how to Sort. Asc/Dsc/etc.\n\tMode SortMode\n}\n\n// SortMode defines How to sort.\ntype SortMode int\n\nconst (\n\t// Asc sorts the column in Ascending order alphabetically.\n\tAsc SortMode = iota\n\t// AscNumeric sorts the column in Ascending order numerically.\n\tAscNumeric\n\t// Dsc sorts the column in Descending order alphabetically.\n\tDsc\n\t// DscNumeric sorts the column in Descending order numerically.\n\tDscNumeric\n)\n\ntype rowsSorter struct {\n\trows          []rowStr\n\tsortBy        []SortBy\n\tsortedIndices []int\n}\n\n// getSortedRowIndices sorts and returns the row indices in Sorted order as\n// directed by Table.sortBy which can be set using Table.SortBy(...)\nfunc (t *Table) getSortedRowIndices() []int {\n\tsortedIndices := make([]int, len(t.rows))\n\tfor idx := range t.rows {\n\t\tsortedIndices[idx] = idx\n\t}\n\n\tif t.sortBy != nil && len(t.sortBy) > 0 {\n\t\tsort.Sort(rowsSorter{\n\t\t\trows:          t.rows,\n\t\t\tsortBy:        t.parseSortBy(t.sortBy),\n\t\t\tsortedIndices: sortedIndices,\n\t\t})\n\t}\n\n\treturn sortedIndices\n}\n\nfunc (t *Table) parseSortBy(sortBy []SortBy) []SortBy {\n\tvar resSortBy []SortBy\n\tfor _, col := range sortBy {\n\t\tcolNum := 0\n\t\tif col.Number > 0 && col.Number <= t.numColumns {\n\t\t\tcolNum = col.Number\n\t\t} else if col.Name != \"\" && len(t.rowsHeader) > 0 {\n\t\t\tfor idx, colName := range t.rowsHeader[0] {\n\t\t\t\tif col.Name == colName {\n\t\t\t\t\tcolNum = idx + 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif colNum > 0 {\n\t\t\tresSortBy = append(resSortBy, SortBy{\n\t\t\t\tName:   col.Name,\n\t\t\t\tNumber: colNum,\n\t\t\t\tMode:   col.Mode,\n\t\t\t})\n\t\t}\n\t}\n\treturn resSortBy\n}\n\nfunc (rs rowsSorter) Len() int {\n\treturn len(rs.rows)\n}\n\nfunc (rs rowsSorter) Swap(i, j int) {\n\trs.sortedIndices[i], rs.sortedIndices[j] = rs.sortedIndices[j], rs.sortedIndices[i]\n}\n\nfunc (rs rowsSorter) Less(i, j int) bool {\n\trealI, realJ := rs.sortedIndices[i], rs.sortedIndices[j]\n\tfor _, col := range rs.sortBy {\n\t\trowI, rowJ, colIdx := rs.rows[realI], rs.rows[realJ], col.Number-1\n\t\tif colIdx < len(rowI) && colIdx < len(rowJ) {\n\t\t\tshouldContinue, returnValue := rs.lessColumns(rowI, rowJ, colIdx, col)\n\t\t\tif !shouldContinue {\n\t\t\t\treturn returnValue\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (rs rowsSorter) lessColumns(rowI rowStr, rowJ rowStr, colIdx int, col SortBy) (bool, bool) {\n\tif rowI[colIdx] == rowJ[colIdx] {\n\t\treturn true, false\n\t} else if col.Mode == Asc {\n\t\treturn false, rowI[colIdx] < rowJ[colIdx]\n\t} else if col.Mode == Dsc {\n\t\treturn false, rowI[colIdx] > rowJ[colIdx]\n\t}\n\n\tiVal, iErr := strconv.ParseFloat(rowI[colIdx], 64)\n\tjVal, jErr := strconv.ParseFloat(rowJ[colIdx], 64)\n\tif iErr == nil && jErr == nil {\n\t\tif col.Mode == AscNumeric {\n\t\t\treturn false, iVal < jVal\n\t\t} else if col.Mode == DscNumeric {\n\t\t\treturn false, jVal < iVal\n\t\t}\n\t}\n\treturn true, false\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/style.go",
    "content": "package table\n\nimport (\n\t\"github.com/jedib0t/go-pretty/v6/text\"\n)\n\n// Style declares how to render the Table and provides very fine-grained control\n// on how the Table gets rendered on the Console.\ntype Style struct {\n\tName    string        // name of the Style\n\tBox     BoxStyle      // characters to use for the boxes\n\tColor   ColorOptions  // colors to use for the rows and columns\n\tFormat  FormatOptions // formatting options for the rows and columns\n\tHTML    HTMLOptions   // rendering options for HTML mode\n\tOptions Options       // misc. options for the table\n\tTitle   TitleOptions  // formation options for the title text\n}\n\nvar (\n\t// StyleDefault renders a Table like below:\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\t//  |   # | FIRST NAME | LAST NAME | SALARY |                             |\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\t//  |   1 | Arya       | Stark     |   3000 |                             |\n\t//  |  20 | Jon        | Snow      |   2000 | You know nothing, Jon Snow! |\n\t//  | 300 | Tyrion     | Lannister |   5000 |                             |\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\t//  |     |            | TOTAL     |  10000 |                             |\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\tStyleDefault = Style{\n\t\tName:    \"StyleDefault\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsDefault,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsDefault,\n\t\tTitle:   TitleOptionsDefault,\n\t}\n\n\t// StyleBold renders a Table like below:\n\t//  ┏━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n\t//  ┃   # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃                             ┃\n\t//  ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n\t//  ┃   1 ┃ Arya       ┃ Stark     ┃   3000 ┃                             ┃\n\t//  ┃  20 ┃ Jon        ┃ Snow      ┃   2000 ┃ You know nothing, Jon Snow! ┃\n\t//  ┃ 300 ┃ Tyrion     ┃ Lannister ┃   5000 ┃                             ┃\n\t//  ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n\t//  ┃     ┃            ┃ TOTAL     ┃  10000 ┃                             ┃\n\t//  ┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n\tStyleBold = Style{\n\t\tName:    \"StyleBold\",\n\t\tBox:     StyleBoxBold,\n\t\tColor:   ColorOptionsDefault,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsDefault,\n\t\tTitle:   TitleOptionsDefault,\n\t}\n\n\t// StyleColoredBright renders a Table without any borders or separators,\n\t// and with Black text on Cyan background for Header/Footer and\n\t// White background for other rows.\n\tStyleColoredBright = Style{\n\t\tName:    \"StyleColoredBright\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBright,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsDark,\n\t}\n\n\t// StyleColoredDark renders a Table without any borders or separators, and\n\t// with Header/Footer in Cyan text and other rows with White text, all on\n\t// Black background.\n\tStyleColoredDark = Style{\n\t\tName:    \"StyleColoredDark\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsDark,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBright,\n\t}\n\n\t// StyleColoredBlackOnBlueWhite renders a Table without any borders or\n\t// separators, and with Black text on Blue background for Header/Footer and\n\t// White background for other rows.\n\tStyleColoredBlackOnBlueWhite = Style{\n\t\tName:    \"StyleColoredBlackOnBlueWhite\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBlackOnBlueWhite,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBlueOnBlack,\n\t}\n\n\t// StyleColoredBlackOnCyanWhite renders a Table without any borders or\n\t// separators, and with Black text on Cyan background for Header/Footer and\n\t// White background for other rows.\n\tStyleColoredBlackOnCyanWhite = Style{\n\t\tName:    \"StyleColoredBlackOnCyanWhite\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBlackOnCyanWhite,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsCyanOnBlack,\n\t}\n\n\t// StyleColoredBlackOnGreenWhite renders a Table without any borders or\n\t// separators, and with Black text on Green background for Header/Footer and\n\t// White background for other rows.\n\tStyleColoredBlackOnGreenWhite = Style{\n\t\tName:    \"StyleColoredBlackOnGreenWhite\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBlackOnGreenWhite,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsGreenOnBlack,\n\t}\n\n\t// StyleColoredBlackOnMagentaWhite renders a Table without any borders or\n\t// separators, and with Black text on Magenta background for Header/Footer and\n\t// White background for other rows.\n\tStyleColoredBlackOnMagentaWhite = Style{\n\t\tName:    \"StyleColoredBlackOnMagentaWhite\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBlackOnMagentaWhite,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsMagentaOnBlack,\n\t}\n\n\t// StyleColoredBlackOnYellowWhite renders a Table without any borders or\n\t// separators, and with Black text on Yellow background for Header/Footer and\n\t// White background for other rows.\n\tStyleColoredBlackOnYellowWhite = Style{\n\t\tName:    \"StyleColoredBlackOnYellowWhite\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBlackOnYellowWhite,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsYellowOnBlack,\n\t}\n\n\t// StyleColoredBlackOnRedWhite renders a Table without any borders or\n\t// separators, and with Black text on Red background for Header/Footer and\n\t// White background for other rows.\n\tStyleColoredBlackOnRedWhite = Style{\n\t\tName:    \"StyleColoredBlackOnRedWhite\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBlackOnRedWhite,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsRedOnBlack,\n\t}\n\n\t// StyleColoredBlueWhiteOnBlack renders a Table without any borders or\n\t// separators, and with Header/Footer in Blue text and other rows with\n\t// White text, all on Black background.\n\tStyleColoredBlueWhiteOnBlack = Style{\n\t\tName:    \"StyleColoredBlueWhiteOnBlack\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsBlueWhiteOnBlack,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBlackOnBlue,\n\t}\n\n\t// StyleColoredCyanWhiteOnBlack renders a Table without any borders or\n\t// separators, and with Header/Footer in Cyan text and other rows with\n\t// White text, all on Black background.\n\tStyleColoredCyanWhiteOnBlack = Style{\n\t\tName:    \"StyleColoredCyanWhiteOnBlack\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsCyanWhiteOnBlack,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBlackOnCyan,\n\t}\n\n\t// StyleColoredGreenWhiteOnBlack renders a Table without any borders or\n\t// separators, and with Header/Footer in Green text and other rows with\n\t// White text, all on Black background.\n\tStyleColoredGreenWhiteOnBlack = Style{\n\t\tName:    \"StyleColoredGreenWhiteOnBlack\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsGreenWhiteOnBlack,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBlackOnGreen,\n\t}\n\n\t// StyleColoredMagentaWhiteOnBlack renders a Table without any borders or\n\t// separators, and with Header/Footer in Magenta text and other rows with\n\t// White text, all on Black background.\n\tStyleColoredMagentaWhiteOnBlack = Style{\n\t\tName:    \"StyleColoredMagentaWhiteOnBlack\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsMagentaWhiteOnBlack,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBlackOnMagenta,\n\t}\n\n\t// StyleColoredRedWhiteOnBlack renders a Table without any borders or\n\t// separators, and with Header/Footer in Red text and other rows with\n\t// White text, all on Black background.\n\tStyleColoredRedWhiteOnBlack = Style{\n\t\tName:    \"StyleColoredRedWhiteOnBlack\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsRedWhiteOnBlack,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBlackOnRed,\n\t}\n\n\t// StyleColoredYellowWhiteOnBlack renders a Table without any borders or\n\t// separators, and with Header/Footer in Yellow text and other rows with\n\t// White text, all on Black background.\n\tStyleColoredYellowWhiteOnBlack = Style{\n\t\tName:    \"StyleColoredYellowWhiteOnBlack\",\n\t\tBox:     StyleBoxDefault,\n\t\tColor:   ColorOptionsYellowWhiteOnBlack,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsNoBordersAndSeparators,\n\t\tTitle:   TitleOptionsBlackOnYellow,\n\t}\n\n\t// StyleDouble renders a Table like below:\n\t//  ╔═════╦════════════╦═══════════╦════════╦═════════════════════════════╗\n\t//  ║   # ║ FIRST NAME ║ LAST NAME ║ SALARY ║                             ║\n\t//  ╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣\n\t//  ║   1 ║ Arya       ║ Stark     ║   3000 ║                             ║\n\t//  ║  20 ║ Jon        ║ Snow      ║   2000 ║ You know nothing, Jon Snow! ║\n\t//  ║ 300 ║ Tyrion     ║ Lannister ║   5000 ║                             ║\n\t//  ╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣\n\t//  ║     ║            ║ TOTAL     ║  10000 ║                             ║\n\t//  ╚═════╩════════════╩═══════════╩════════╩═════════════════════════════╝\n\tStyleDouble = Style{\n\t\tName:    \"StyleDouble\",\n\t\tBox:     StyleBoxDouble,\n\t\tColor:   ColorOptionsDefault,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsDefault,\n\t\tTitle:   TitleOptionsDefault,\n\t}\n\n\t// StyleLight renders a Table like below:\n\t//  ┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐\n\t//  │   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │   1 │ Arya       │ Stark     │   3000 │                             │\n\t//  │  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n\t//  │ 300 │ Tyrion     │ Lannister │   5000 │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │     │            │ TOTAL     │  10000 │                             │\n\t//  └─────┴────────────┴───────────┴────────┴─────────────────────────────┘\n\tStyleLight = Style{\n\t\tName:    \"StyleLight\",\n\t\tBox:     StyleBoxLight,\n\t\tColor:   ColorOptionsDefault,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsDefault,\n\t\tTitle:   TitleOptionsDefault,\n\t}\n\n\t// StyleRounded renders a Table like below:\n\t//  ╭─────┬────────────┬───────────┬────────┬─────────────────────────────╮\n\t//  │   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │   1 │ Arya       │ Stark     │   3000 │                             │\n\t//  │  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n\t//  │ 300 │ Tyrion     │ Lannister │   5000 │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │     │            │ TOTAL     │  10000 │                             │\n\t//  ╰─────┴────────────┴───────────┴────────┴─────────────────────────────╯\n\tStyleRounded = Style{\n\t\tName:    \"StyleRounded\",\n\t\tBox:     StyleBoxRounded,\n\t\tColor:   ColorOptionsDefault,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsDefault,\n\t\tTitle:   TitleOptionsDefault,\n\t}\n\n\t// styleTest renders a Table like below:\n\t//  (-----^------------^-----------^--------^-----------------------------)\n\t//  [<  #>|<FIRST NAME>|<LAST NAME>|<SALARY>|<                           >]\n\t//  {-----+------------+-----------+--------+-----------------------------}\n\t//  [<  1>|<Arya      >|<Stark    >|<  3000>|<                           >]\n\t//  [< 20>|<Jon       >|<Snow     >|<  2000>|<You know nothing, Jon Snow!>]\n\t//  [<300>|<Tyrion    >|<Lannister>|<  5000>|<                           >]\n\t//  {-----+------------+-----------+--------+-----------------------------}\n\t//  [<   >|<          >|<TOTAL    >|< 10000>|<                           >]\n\t//  \\-----v------------v-----------v--------v-----------------------------/\n\tstyleTest = Style{\n\t\tName:    \"styleTest\",\n\t\tBox:     styleBoxTest,\n\t\tColor:   ColorOptionsDefault,\n\t\tFormat:  FormatOptionsDefault,\n\t\tHTML:    DefaultHTMLOptions,\n\t\tOptions: OptionsDefault,\n\t\tTitle:   TitleOptionsDefault,\n\t}\n)\n\n// BoxStyle defines the characters/strings to use to render the borders and\n// separators for the Table.\ntype BoxStyle struct {\n\tBottomLeft       string\n\tBottomRight      string\n\tBottomSeparator  string\n\tEmptySeparator   string\n\tLeft             string\n\tLeftSeparator    string\n\tMiddleHorizontal string\n\tMiddleSeparator  string\n\tMiddleVertical   string\n\tPaddingLeft      string\n\tPaddingRight     string\n\tPageSeparator    string\n\tRight            string\n\tRightSeparator   string\n\tTopLeft          string\n\tTopRight         string\n\tTopSeparator     string\n\tUnfinishedRow    string\n}\n\nvar (\n\t// StyleBoxDefault defines a Boxed-Table like below:\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\t//  |   # | FIRST NAME | LAST NAME | SALARY |                             |\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\t//  |   1 | Arya       | Stark     |   3000 |                             |\n\t//  |  20 | Jon        | Snow      |   2000 | You know nothing, Jon Snow! |\n\t//  | 300 | Tyrion     | Lannister |   5000 |                             |\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\t//  |     |            | TOTAL     |  10000 |                             |\n\t//  +-----+------------+-----------+--------+-----------------------------+\n\tStyleBoxDefault = BoxStyle{\n\t\tBottomLeft:       \"+\",\n\t\tBottomRight:      \"+\",\n\t\tBottomSeparator:  \"+\",\n\t\tEmptySeparator:   text.RepeatAndTrim(\" \", text.RuneWidthWithoutEscSequences(\"+\")),\n\t\tLeft:             \"|\",\n\t\tLeftSeparator:    \"+\",\n\t\tMiddleHorizontal: \"-\",\n\t\tMiddleSeparator:  \"+\",\n\t\tMiddleVertical:   \"|\",\n\t\tPaddingLeft:      \" \",\n\t\tPaddingRight:     \" \",\n\t\tPageSeparator:    \"\\n\",\n\t\tRight:            \"|\",\n\t\tRightSeparator:   \"+\",\n\t\tTopLeft:          \"+\",\n\t\tTopRight:         \"+\",\n\t\tTopSeparator:     \"+\",\n\t\tUnfinishedRow:    \" ~\",\n\t}\n\n\t// StyleBoxBold defines a Boxed-Table like below:\n\t//  ┏━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n\t//  ┃   # ┃ FIRST NAME ┃ LAST NAME ┃ SALARY ┃                             ┃\n\t//  ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n\t//  ┃   1 ┃ Arya       ┃ Stark     ┃   3000 ┃                             ┃\n\t//  ┃  20 ┃ Jon        ┃ Snow      ┃   2000 ┃ You know nothing, Jon Snow! ┃\n\t//  ┃ 300 ┃ Tyrion     ┃ Lannister ┃   5000 ┃                             ┃\n\t//  ┣━━━━━╋━━━━━━━━━━━━╋━━━━━━━━━━━╋━━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n\t//  ┃     ┃            ┃ TOTAL     ┃  10000 ┃                             ┃\n\t//  ┗━━━━━┻━━━━━━━━━━━━┻━━━━━━━━━━━┻━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n\tStyleBoxBold = BoxStyle{\n\t\tBottomLeft:       \"┗\",\n\t\tBottomRight:      \"┛\",\n\t\tBottomSeparator:  \"┻\",\n\t\tEmptySeparator:   text.RepeatAndTrim(\" \", text.RuneWidthWithoutEscSequences(\"╋\")),\n\t\tLeft:             \"┃\",\n\t\tLeftSeparator:    \"┣\",\n\t\tMiddleHorizontal: \"━\",\n\t\tMiddleSeparator:  \"╋\",\n\t\tMiddleVertical:   \"┃\",\n\t\tPaddingLeft:      \" \",\n\t\tPaddingRight:     \" \",\n\t\tPageSeparator:    \"\\n\",\n\t\tRight:            \"┃\",\n\t\tRightSeparator:   \"┫\",\n\t\tTopLeft:          \"┏\",\n\t\tTopRight:         \"┓\",\n\t\tTopSeparator:     \"┳\",\n\t\tUnfinishedRow:    \" ≈\",\n\t}\n\n\t// StyleBoxDouble defines a Boxed-Table like below:\n\t//  ╔═════╦════════════╦═══════════╦════════╦═════════════════════════════╗\n\t//  ║   # ║ FIRST NAME ║ LAST NAME ║ SALARY ║                             ║\n\t//  ╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣\n\t//  ║   1 ║ Arya       ║ Stark     ║   3000 ║                             ║\n\t//  ║  20 ║ Jon        ║ Snow      ║   2000 ║ You know nothing, Jon Snow! ║\n\t//  ║ 300 ║ Tyrion     ║ Lannister ║   5000 ║                             ║\n\t//  ╠═════╬════════════╬═══════════╬════════╬═════════════════════════════╣\n\t//  ║     ║            ║ TOTAL     ║  10000 ║                             ║\n\t//  ╚═════╩════════════╩═══════════╩════════╩═════════════════════════════╝\n\tStyleBoxDouble = BoxStyle{\n\t\tBottomLeft:       \"╚\",\n\t\tBottomRight:      \"╝\",\n\t\tBottomSeparator:  \"╩\",\n\t\tEmptySeparator:   text.RepeatAndTrim(\" \", text.RuneWidthWithoutEscSequences(\"╬\")),\n\t\tLeft:             \"║\",\n\t\tLeftSeparator:    \"╠\",\n\t\tMiddleHorizontal: \"═\",\n\t\tMiddleSeparator:  \"╬\",\n\t\tMiddleVertical:   \"║\",\n\t\tPaddingLeft:      \" \",\n\t\tPaddingRight:     \" \",\n\t\tPageSeparator:    \"\\n\",\n\t\tRight:            \"║\",\n\t\tRightSeparator:   \"╣\",\n\t\tTopLeft:          \"╔\",\n\t\tTopRight:         \"╗\",\n\t\tTopSeparator:     \"╦\",\n\t\tUnfinishedRow:    \" ≈\",\n\t}\n\n\t// StyleBoxLight defines a Boxed-Table like below:\n\t//  ┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐\n\t//  │   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │   1 │ Arya       │ Stark     │   3000 │                             │\n\t//  │  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n\t//  │ 300 │ Tyrion     │ Lannister │   5000 │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │     │            │ TOTAL     │  10000 │                             │\n\t//  └─────┴────────────┴───────────┴────────┴─────────────────────────────┘\n\tStyleBoxLight = BoxStyle{\n\t\tBottomLeft:       \"└\",\n\t\tBottomRight:      \"┘\",\n\t\tBottomSeparator:  \"┴\",\n\t\tEmptySeparator:   text.RepeatAndTrim(\" \", text.RuneWidthWithoutEscSequences(\"┼\")),\n\t\tLeft:             \"│\",\n\t\tLeftSeparator:    \"├\",\n\t\tMiddleHorizontal: \"─\",\n\t\tMiddleSeparator:  \"┼\",\n\t\tMiddleVertical:   \"│\",\n\t\tPaddingLeft:      \" \",\n\t\tPaddingRight:     \" \",\n\t\tPageSeparator:    \"\\n\",\n\t\tRight:            \"│\",\n\t\tRightSeparator:   \"┤\",\n\t\tTopLeft:          \"┌\",\n\t\tTopRight:         \"┐\",\n\t\tTopSeparator:     \"┬\",\n\t\tUnfinishedRow:    \" ≈\",\n\t}\n\n\t// StyleBoxRounded defines a Boxed-Table like below:\n\t//  ╭─────┬────────────┬───────────┬────────┬─────────────────────────────╮\n\t//  │   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │   1 │ Arya       │ Stark     │   3000 │                             │\n\t//  │  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n\t//  │ 300 │ Tyrion     │ Lannister │   5000 │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │     │            │ TOTAL     │  10000 │                             │\n\t//  ╰─────┴────────────┴───────────┴────────┴─────────────────────────────╯\n\tStyleBoxRounded = BoxStyle{\n\t\tBottomLeft:       \"╰\",\n\t\tBottomRight:      \"╯\",\n\t\tBottomSeparator:  \"┴\",\n\t\tEmptySeparator:   text.RepeatAndTrim(\" \", text.RuneWidthWithoutEscSequences(\"┼\")),\n\t\tLeft:             \"│\",\n\t\tLeftSeparator:    \"├\",\n\t\tMiddleHorizontal: \"─\",\n\t\tMiddleSeparator:  \"┼\",\n\t\tMiddleVertical:   \"│\",\n\t\tPaddingLeft:      \" \",\n\t\tPaddingRight:     \" \",\n\t\tPageSeparator:    \"\\n\",\n\t\tRight:            \"│\",\n\t\tRightSeparator:   \"┤\",\n\t\tTopLeft:          \"╭\",\n\t\tTopRight:         \"╮\",\n\t\tTopSeparator:     \"┬\",\n\t\tUnfinishedRow:    \" ≈\",\n\t}\n\n\t// styleBoxTest defines a Boxed-Table like below:\n\t//  (-----^------------^-----------^--------^-----------------------------)\n\t//  [<  #>|<FIRST NAME>|<LAST NAME>|<SALARY>|<                           >]\n\t//  {-----+------------+-----------+--------+-----------------------------}\n\t//  [<  1>|<Arya      >|<Stark    >|<  3000>|<                           >]\n\t//  [< 20>|<Jon       >|<Snow     >|<  2000>|<You know nothing, Jon Snow!>]\n\t//  [<300>|<Tyrion    >|<Lannister>|<  5000>|<                           >]\n\t//  {-----+------------+-----------+--------+-----------------------------}\n\t//  [<   >|<          >|<TOTAL    >|< 10000>|<                           >]\n\t//  \\-----v------------v-----------v--------v-----------------------------/\n\tstyleBoxTest = BoxStyle{\n\t\tBottomLeft:       \"\\\\\",\n\t\tBottomRight:      \"/\",\n\t\tBottomSeparator:  \"v\",\n\t\tEmptySeparator:   text.RepeatAndTrim(\" \", text.RuneWidthWithoutEscSequences(\"+\")),\n\t\tLeft:             \"[\",\n\t\tLeftSeparator:    \"{\",\n\t\tMiddleHorizontal: \"--\",\n\t\tMiddleSeparator:  \"+\",\n\t\tMiddleVertical:   \"|\",\n\t\tPaddingLeft:      \"<\",\n\t\tPaddingRight:     \">\",\n\t\tPageSeparator:    \"\\n\",\n\t\tRight:            \"]\",\n\t\tRightSeparator:   \"}\",\n\t\tTopLeft:          \"(\",\n\t\tTopRight:         \")\",\n\t\tTopSeparator:     \"^\",\n\t\tUnfinishedRow:    \" ~~~\",\n\t}\n)\n\n// ColorOptions defines the ANSI colors to use for parts of the Table.\ntype ColorOptions struct {\n\tBorder       text.Colors // borders (if nil, uses one of the below)\n\tFooter       text.Colors // footer row(s) colors\n\tHeader       text.Colors // header row(s) colors\n\tIndexColumn  text.Colors // index-column colors (row #, etc.)\n\tRow          text.Colors // regular row(s) colors\n\tRowAlternate text.Colors // regular row(s) colors for the even-numbered rows\n\tSeparator    text.Colors // separators (if nil, uses one of the above)\n}\n\nvar (\n\t// ColorOptionsDefault defines sensible ANSI color options - basically NONE.\n\tColorOptionsDefault = ColorOptions{}\n\n\t// ColorOptionsBright renders dark text on bright background.\n\tColorOptionsBright = ColorOptionsBlackOnCyanWhite\n\n\t// ColorOptionsDark renders bright text on dark background.\n\tColorOptionsDark = ColorOptionsCyanWhiteOnBlack\n\n\t// ColorOptionsBlackOnBlueWhite renders Black text on Blue/White background.\n\tColorOptionsBlackOnBlueWhite = ColorOptions{\n\t\tFooter:       text.Colors{text.BgBlue, text.FgBlack},\n\t\tHeader:       text.Colors{text.BgHiBlue, text.FgBlack},\n\t\tIndexColumn:  text.Colors{text.BgHiBlue, text.FgBlack},\n\t\tRow:          text.Colors{text.BgHiWhite, text.FgBlack},\n\t\tRowAlternate: text.Colors{text.BgWhite, text.FgBlack},\n\t}\n\n\t// ColorOptionsBlackOnCyanWhite renders Black text on Cyan/White background.\n\tColorOptionsBlackOnCyanWhite = ColorOptions{\n\t\tFooter:       text.Colors{text.BgCyan, text.FgBlack},\n\t\tHeader:       text.Colors{text.BgHiCyan, text.FgBlack},\n\t\tIndexColumn:  text.Colors{text.BgHiCyan, text.FgBlack},\n\t\tRow:          text.Colors{text.BgHiWhite, text.FgBlack},\n\t\tRowAlternate: text.Colors{text.BgWhite, text.FgBlack},\n\t}\n\n\t// ColorOptionsBlackOnGreenWhite renders Black text on Green/White\n\t// background.\n\tColorOptionsBlackOnGreenWhite = ColorOptions{\n\t\tFooter:       text.Colors{text.BgGreen, text.FgBlack},\n\t\tHeader:       text.Colors{text.BgHiGreen, text.FgBlack},\n\t\tIndexColumn:  text.Colors{text.BgHiGreen, text.FgBlack},\n\t\tRow:          text.Colors{text.BgHiWhite, text.FgBlack},\n\t\tRowAlternate: text.Colors{text.BgWhite, text.FgBlack},\n\t}\n\n\t// ColorOptionsBlackOnMagentaWhite renders Black text on Magenta/White\n\t// background.\n\tColorOptionsBlackOnMagentaWhite = ColorOptions{\n\t\tFooter:       text.Colors{text.BgMagenta, text.FgBlack},\n\t\tHeader:       text.Colors{text.BgHiMagenta, text.FgBlack},\n\t\tIndexColumn:  text.Colors{text.BgHiMagenta, text.FgBlack},\n\t\tRow:          text.Colors{text.BgHiWhite, text.FgBlack},\n\t\tRowAlternate: text.Colors{text.BgWhite, text.FgBlack},\n\t}\n\n\t// ColorOptionsBlackOnRedWhite renders Black text on Red/White background.\n\tColorOptionsBlackOnRedWhite = ColorOptions{\n\t\tFooter:       text.Colors{text.BgRed, text.FgBlack},\n\t\tHeader:       text.Colors{text.BgHiRed, text.FgBlack},\n\t\tIndexColumn:  text.Colors{text.BgHiRed, text.FgBlack},\n\t\tRow:          text.Colors{text.BgHiWhite, text.FgBlack},\n\t\tRowAlternate: text.Colors{text.BgWhite, text.FgBlack},\n\t}\n\n\t// ColorOptionsBlackOnYellowWhite renders Black text on Yellow/White\n\t// background.\n\tColorOptionsBlackOnYellowWhite = ColorOptions{\n\t\tFooter:       text.Colors{text.BgYellow, text.FgBlack},\n\t\tHeader:       text.Colors{text.BgHiYellow, text.FgBlack},\n\t\tIndexColumn:  text.Colors{text.BgHiYellow, text.FgBlack},\n\t\tRow:          text.Colors{text.BgHiWhite, text.FgBlack},\n\t\tRowAlternate: text.Colors{text.BgWhite, text.FgBlack},\n\t}\n\n\t// ColorOptionsBlueWhiteOnBlack renders Blue/White text on Black background.\n\tColorOptionsBlueWhiteOnBlack = ColorOptions{\n\t\tFooter:       text.Colors{text.FgBlue, text.BgHiBlack},\n\t\tHeader:       text.Colors{text.FgHiBlue, text.BgHiBlack},\n\t\tIndexColumn:  text.Colors{text.FgHiBlue, text.BgHiBlack},\n\t\tRow:          text.Colors{text.FgHiWhite, text.BgBlack},\n\t\tRowAlternate: text.Colors{text.FgWhite, text.BgBlack},\n\t}\n\n\t// ColorOptionsCyanWhiteOnBlack renders Cyan/White text on Black background.\n\tColorOptionsCyanWhiteOnBlack = ColorOptions{\n\t\tFooter:       text.Colors{text.FgCyan, text.BgHiBlack},\n\t\tHeader:       text.Colors{text.FgHiCyan, text.BgHiBlack},\n\t\tIndexColumn:  text.Colors{text.FgHiCyan, text.BgHiBlack},\n\t\tRow:          text.Colors{text.FgHiWhite, text.BgBlack},\n\t\tRowAlternate: text.Colors{text.FgWhite, text.BgBlack},\n\t}\n\n\t// ColorOptionsGreenWhiteOnBlack renders Green/White text on Black\n\t// background.\n\tColorOptionsGreenWhiteOnBlack = ColorOptions{\n\t\tFooter:       text.Colors{text.FgGreen, text.BgHiBlack},\n\t\tHeader:       text.Colors{text.FgHiGreen, text.BgHiBlack},\n\t\tIndexColumn:  text.Colors{text.FgHiGreen, text.BgHiBlack},\n\t\tRow:          text.Colors{text.FgHiWhite, text.BgBlack},\n\t\tRowAlternate: text.Colors{text.FgWhite, text.BgBlack},\n\t}\n\n\t// ColorOptionsMagentaWhiteOnBlack renders Magenta/White text on Black\n\t// background.\n\tColorOptionsMagentaWhiteOnBlack = ColorOptions{\n\t\tFooter:       text.Colors{text.FgMagenta, text.BgHiBlack},\n\t\tHeader:       text.Colors{text.FgHiMagenta, text.BgHiBlack},\n\t\tIndexColumn:  text.Colors{text.FgHiMagenta, text.BgHiBlack},\n\t\tRow:          text.Colors{text.FgHiWhite, text.BgBlack},\n\t\tRowAlternate: text.Colors{text.FgWhite, text.BgBlack},\n\t}\n\n\t// ColorOptionsRedWhiteOnBlack renders Red/White text on Black background.\n\tColorOptionsRedWhiteOnBlack = ColorOptions{\n\t\tFooter:       text.Colors{text.FgRed, text.BgHiBlack},\n\t\tHeader:       text.Colors{text.FgHiRed, text.BgHiBlack},\n\t\tIndexColumn:  text.Colors{text.FgHiRed, text.BgHiBlack},\n\t\tRow:          text.Colors{text.FgHiWhite, text.BgBlack},\n\t\tRowAlternate: text.Colors{text.FgWhite, text.BgBlack},\n\t}\n\n\t// ColorOptionsYellowWhiteOnBlack renders Yellow/White text on Black\n\t// background.\n\tColorOptionsYellowWhiteOnBlack = ColorOptions{\n\t\tFooter:       text.Colors{text.FgYellow, text.BgHiBlack},\n\t\tHeader:       text.Colors{text.FgHiYellow, text.BgHiBlack},\n\t\tIndexColumn:  text.Colors{text.FgHiYellow, text.BgHiBlack},\n\t\tRow:          text.Colors{text.FgHiWhite, text.BgBlack},\n\t\tRowAlternate: text.Colors{text.FgWhite, text.BgBlack},\n\t}\n)\n\n// FormatOptions defines the text-formatting to perform on parts of the Table.\ntype FormatOptions struct {\n\tDirection text.Direction // (forced) BiDi direction for each Column\n\tFooter    text.Format    // footer row(s) text format\n\tHeader    text.Format    // header row(s) text format\n\tRow       text.Format    // (data) row(s) text format\n}\n\n// FormatOptionsDefault defines sensible formatting options.\nvar FormatOptionsDefault = FormatOptions{\n\tFooter: text.FormatUpper,\n\tHeader: text.FormatUpper,\n\tRow:    text.FormatDefault,\n}\n\n// HTMLOptions defines the global options to control HTML rendering.\ntype HTMLOptions struct {\n\tCSSClass    string // CSS class to set on the overall <table> tag\n\tEmptyColumn string // string to replace \"\" columns with (entire content being \"\")\n\tEscapeText  bool   // escape text into HTML-safe content?\n\tNewline     string // string to replace \"\\n\" characters with\n}\n\n// DefaultHTMLOptions defines sensible HTML rendering defaults.\nvar DefaultHTMLOptions = HTMLOptions{\n\tCSSClass:    DefaultHTMLCSSClass,\n\tEmptyColumn: \"&nbsp;\",\n\tEscapeText:  true,\n\tNewline:     \"<br/>\",\n}\n\n// Options defines the global options that determine how the Table is\n// rendered.\ntype Options struct {\n\t// DoNotColorBordersAndSeparators disables coloring all the borders and row\n\t// or column separators.\n\tDoNotColorBordersAndSeparators bool\n\n\t// DrawBorder enables or disables drawing the border around the Table.\n\t// Example of a table where it is disabled:\n\t//     # │ FIRST NAME │ LAST NAME │ SALARY │\n\t//  ─────┼────────────┼───────────┼────────┼─────────────────────────────\n\t//     1 │ Arya       │ Stark     │   3000 │\n\t//    20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow!\n\t//   300 │ Tyrion     │ Lannister │   5000 │\n\t//  ─────┼────────────┼───────────┼────────┼─────────────────────────────\n\t//       │            │ TOTAL     │  10000 │\n\tDrawBorder bool\n\n\t// SeparateColumns enables or disable drawing border between columns.\n\t// Example of a table where it is disabled:\n\t//  ┌─────────────────────────────────────────────────────────────────┐\n\t//  │   #  FIRST NAME  LAST NAME  SALARY                              │\n\t//  ├─────────────────────────────────────────────────────────────────┤\n\t//  │   1  Arya        Stark        3000                              │\n\t//  │  20  Jon         Snow         2000  You know nothing, Jon Snow! │\n\t//  │ 300  Tyrion      Lannister    5000                              │\n\t//  │                  TOTAL       10000                              │\n\t//  └─────────────────────────────────────────────────────────────────┘\n\tSeparateColumns bool\n\n\t// SeparateFooter enables or disable drawing border between the footer and\n\t// the rows. Example of a table where it is disabled:\n\t//  ┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐\n\t//  │   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │   1 │ Arya       │ Stark     │   3000 │                             │\n\t//  │  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n\t//  │ 300 │ Tyrion     │ Lannister │   5000 │                             │\n\t//  │     │            │ TOTAL     │  10000 │                             │\n\t//  └─────┴────────────┴───────────┴────────┴─────────────────────────────┘\n\tSeparateFooter bool\n\n\t// SeparateHeader enables or disable drawing border between the header and\n\t// the rows. Example of a table where it is disabled:\n\t//  ┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐\n\t//  │   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n\t//  │   1 │ Arya       │ Stark     │   3000 │                             │\n\t//  │  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n\t//  │ 300 │ Tyrion     │ Lannister │   5000 │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │     │            │ TOTAL     │  10000 │                             │\n\t//  └─────┴────────────┴───────────┴────────┴─────────────────────────────┘\n\tSeparateHeader bool\n\n\t// SeparateRows enables or disables drawing separators between each row.\n\t// Example of a table where it is enabled:\n\t//  ┌─────┬────────────┬───────────┬────────┬─────────────────────────────┐\n\t//  │   # │ FIRST NAME │ LAST NAME │ SALARY │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │   1 │ Arya       │ Stark     │   3000 │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │  20 │ Jon        │ Snow      │   2000 │ You know nothing, Jon Snow! │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │ 300 │ Tyrion     │ Lannister │   5000 │                             │\n\t//  ├─────┼────────────┼───────────┼────────┼─────────────────────────────┤\n\t//  │     │            │ TOTAL     │  10000 │                             │\n\t//  └─────┴────────────┴───────────┴────────┴─────────────────────────────┘\n\tSeparateRows bool\n}\n\nvar (\n\t// OptionsDefault defines sensible global options.\n\tOptionsDefault = Options{\n\t\tDrawBorder:      true,\n\t\tSeparateColumns: true,\n\t\tSeparateFooter:  true,\n\t\tSeparateHeader:  true,\n\t\tSeparateRows:    false,\n\t}\n\n\t// OptionsNoBorders sets up a table without any borders.\n\tOptionsNoBorders = Options{\n\t\tDrawBorder:      false,\n\t\tSeparateColumns: true,\n\t\tSeparateFooter:  true,\n\t\tSeparateHeader:  true,\n\t\tSeparateRows:    false,\n\t}\n\n\t// OptionsNoBordersAndSeparators sets up a table without any borders or\n\t// separators.\n\tOptionsNoBordersAndSeparators = Options{\n\t\tDrawBorder:      false,\n\t\tSeparateColumns: false,\n\t\tSeparateFooter:  false,\n\t\tSeparateHeader:  false,\n\t\tSeparateRows:    false,\n\t}\n)\n\n// TitleOptions defines the way the title text is to be rendered.\ntype TitleOptions struct {\n\tAlign  text.Align\n\tColors text.Colors\n\tFormat text.Format\n}\n\nvar (\n\t// TitleOptionsDefault defines sensible title options - basically NONE.\n\tTitleOptionsDefault = TitleOptions{}\n\n\t// TitleOptionsBright renders Bright Bold text on Dark background.\n\tTitleOptionsBright = TitleOptionsBlackOnCyan\n\n\t// TitleOptionsDark renders Dark Bold text on Bright background.\n\tTitleOptionsDark = TitleOptionsCyanOnBlack\n\n\t// TitleOptionsBlackOnBlue renders Black text on Blue background.\n\tTitleOptionsBlackOnBlue = TitleOptions{\n\t\tColors: append(ColorOptionsBlackOnBlueWhite.Header, text.Bold),\n\t}\n\n\t// TitleOptionsBlackOnCyan renders Black Bold text on Cyan background.\n\tTitleOptionsBlackOnCyan = TitleOptions{\n\t\tColors: append(ColorOptionsBlackOnCyanWhite.Header, text.Bold),\n\t}\n\n\t// TitleOptionsBlackOnGreen renders Black Bold text onGreen background.\n\tTitleOptionsBlackOnGreen = TitleOptions{\n\t\tColors: append(ColorOptionsBlackOnGreenWhite.Header, text.Bold),\n\t}\n\n\t// TitleOptionsBlackOnMagenta renders Black Bold text on Magenta background.\n\tTitleOptionsBlackOnMagenta = TitleOptions{\n\t\tColors: append(ColorOptionsBlackOnMagentaWhite.Header, text.Bold),\n\t}\n\n\t// TitleOptionsBlackOnRed renders Black Bold text on Red background.\n\tTitleOptionsBlackOnRed = TitleOptions{\n\t\tColors: append(ColorOptionsBlackOnRedWhite.Header, text.Bold),\n\t}\n\n\t// TitleOptionsBlackOnYellow renders Black Bold text on Yellow background.\n\tTitleOptionsBlackOnYellow = TitleOptions{\n\t\tColors: append(ColorOptionsBlackOnYellowWhite.Header, text.Bold),\n\t}\n\n\t// TitleOptionsBlueOnBlack renders Blue Bold text on Black background.\n\tTitleOptionsBlueOnBlack = TitleOptions{\n\t\tColors: append(ColorOptionsBlueWhiteOnBlack.Header, text.Bold),\n\t}\n\n\t// TitleOptionsCyanOnBlack renders Cyan Bold text on Black background.\n\tTitleOptionsCyanOnBlack = TitleOptions{\n\t\tColors: append(ColorOptionsCyanWhiteOnBlack.Header, text.Bold),\n\t}\n\n\t// TitleOptionsGreenOnBlack renders Green Bold text on Black background.\n\tTitleOptionsGreenOnBlack = TitleOptions{\n\t\tColors: append(ColorOptionsGreenWhiteOnBlack.Header, text.Bold),\n\t}\n\n\t// TitleOptionsMagentaOnBlack renders Magenta Bold text on Black background.\n\tTitleOptionsMagentaOnBlack = TitleOptions{\n\t\tColors: append(ColorOptionsMagentaWhiteOnBlack.Header, text.Bold),\n\t}\n\n\t// TitleOptionsRedOnBlack renders Red Bold text on Black background.\n\tTitleOptionsRedOnBlack = TitleOptions{\n\t\tColors: append(ColorOptionsRedWhiteOnBlack.Header, text.Bold),\n\t}\n\n\t// TitleOptionsYellowOnBlack renders Yellow Bold text on Black background.\n\tTitleOptionsYellowOnBlack = TitleOptions{\n\t\tColors: append(ColorOptionsYellowWhiteOnBlack.Header, text.Bold),\n\t}\n)\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/table.go",
    "content": "package table\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/jedib0t/go-pretty/v6/text\"\n)\n\n// Row defines a single row in the Table.\ntype Row []interface{}\n\nfunc (r Row) findColumnNumber(colName string) int {\n\tfor colIdx, col := range r {\n\t\tif fmt.Sprint(col) == colName {\n\t\t\treturn colIdx + 1\n\t\t}\n\t}\n\treturn 0\n}\n\n// RowPainter is a custom function that takes a Row as input and returns the\n// text.Colors{} to use on the entire row\ntype RowPainter func(row Row) text.Colors\n\n// rowStr defines a single row in the Table comprised of just string objects.\ntype rowStr []string\n\n// areEqual returns true if the contents of the 2 given columns are the same\nfunc (row rowStr) areEqual(colIdx1 int, colIdx2 int) bool {\n\treturn colIdx1 >= 0 && colIdx2 < len(row) && row[colIdx1] == row[colIdx2]\n}\n\n// Table helps print a 2-dimensional array in a human-readable pretty-table.\ntype Table struct {\n\t// allowedRowLength is the max allowed length for a row (or line of output)\n\tallowedRowLength int\n\t// enable automatic indexing of the rows and columns like a spreadsheet?\n\tautoIndex bool\n\t// autoIndexVIndexMaxLength denotes the length in chars for the last row\n\tautoIndexVIndexMaxLength int\n\t// caption stores the text to be rendered just below the table; and doesn't\n\t// get used when rendered as a CSV\n\tcaption string\n\t// columnIsNonNumeric stores if a column contains non-numbers in all rows\n\tcolumnIsNonNumeric []bool\n\t// columnConfigs stores the custom-configuration for 1 or more columns\n\tcolumnConfigs []ColumnConfig\n\t// columnConfigMap stores the custom-configuration by column\n\t// number and is generated before rendering\n\tcolumnConfigMap map[int]ColumnConfig\n\t// htmlCSSClass stores the HTML CSS Class to use on the <table> node\n\thtmlCSSClass string\n\t// indexColumn stores the number of the column considered as the \"index\"\n\tindexColumn int\n\t// maxColumnLengths stores the length of the longest line in each column\n\tmaxColumnLengths []int\n\t// maxRowLength stores the length of the longest row\n\tmaxRowLength int\n\t// numColumns stores the (max.) number of columns seen\n\tnumColumns int\n\t// numLinesRendered keeps track of the number of lines rendered and helps in\n\t// paginating long tables\n\tnumLinesRendered int\n\t// outputMirror stores an io.Writer where the \"Render\" functions would write\n\toutputMirror io.Writer\n\t// pageSize stores the maximum lines to render before rendering the header\n\t// again (to denote a page break) - useful when you are dealing with really\n\t// long tables\n\tpageSize int\n\t// rows stores the rows that make up the body (in string form)\n\trows []rowStr\n\t// rowsColors stores the text.Colors over-rides for each row as defined by\n\t// rowPainter\n\trowsColors []text.Colors\n\t// rowsConfigs stores RowConfig for each row\n\trowsConfigMap map[int]RowConfig\n\t// rowsRaw stores the rows that make up the body\n\trowsRaw []Row\n\t// rowsFooter stores the rows that make up the footer (in string form)\n\trowsFooter []rowStr\n\t// rowsFooterConfigs stores RowConfig for each footer row\n\trowsFooterConfigMap map[int]RowConfig\n\t// rowsFooterRaw stores the rows that make up the footer\n\trowsFooterRaw []Row\n\t// rowsHeader stores the rows that make up the header (in string form)\n\trowsHeader []rowStr\n\t// rowsHeaderConfigs stores RowConfig for each header row\n\trowsHeaderConfigMap map[int]RowConfig\n\t// rowsHeaderRaw stores the rows that make up the header\n\trowsHeaderRaw []Row\n\t// rowPainter is a custom function that given a Row, returns the colors to\n\t// use on the entire row\n\trowPainter RowPainter\n\t// rowSeparator is a dummy row that contains the separator columns (dashes\n\t// that make up the separator between header/body/footer\n\trowSeparator rowStr\n\t// separators is used to keep track of all rowIndices after which a\n\t// separator has to be rendered\n\tseparators map[int]bool\n\t// sortBy stores a map of Column\n\tsortBy []SortBy\n\t// style contains all the strings used to draw the table, and more\n\tstyle *Style\n\t// suppressEmptyColumns hides columns which have no content on all regular\n\t// rows\n\tsuppressEmptyColumns bool\n\t// title contains the text to appear above the table\n\ttitle string\n}\n\n// AppendFooter appends the row to the List of footers to render.\n//\n// Only the first item in the \"config\" will be tagged against this row.\nfunc (t *Table) AppendFooter(row Row, config ...RowConfig) {\n\tt.rowsFooterRaw = append(t.rowsFooterRaw, row)\n\tif len(config) > 0 {\n\t\tif t.rowsFooterConfigMap == nil {\n\t\t\tt.rowsFooterConfigMap = make(map[int]RowConfig)\n\t\t}\n\t\tt.rowsFooterConfigMap[len(t.rowsFooterRaw)-1] = config[0]\n\t}\n}\n\n// AppendHeader appends the row to the List of headers to render.\n//\n// Only the first item in the \"config\" will be tagged against this row.\nfunc (t *Table) AppendHeader(row Row, config ...RowConfig) {\n\tt.rowsHeaderRaw = append(t.rowsHeaderRaw, row)\n\tif len(config) > 0 {\n\t\tif t.rowsHeaderConfigMap == nil {\n\t\t\tt.rowsHeaderConfigMap = make(map[int]RowConfig)\n\t\t}\n\t\tt.rowsHeaderConfigMap[len(t.rowsHeaderRaw)-1] = config[0]\n\t}\n}\n\n// AppendRow appends the row to the List of rows to render.\n//\n// Only the first item in the \"config\" will be tagged against this row.\nfunc (t *Table) AppendRow(row Row, config ...RowConfig) {\n\tt.rowsRaw = append(t.rowsRaw, row)\n\tif len(config) > 0 {\n\t\tif t.rowsConfigMap == nil {\n\t\t\tt.rowsConfigMap = make(map[int]RowConfig)\n\t\t}\n\t\tt.rowsConfigMap[len(t.rowsRaw)-1] = config[0]\n\t}\n}\n\n// AppendRows appends the rows to the List of rows to render.\n//\n// Only the first item in the \"config\" will be tagged against all the rows.\nfunc (t *Table) AppendRows(rows []Row, config ...RowConfig) {\n\tfor _, row := range rows {\n\t\tt.AppendRow(row, config...)\n\t}\n}\n\n// AppendSeparator helps render a separator row after the current last row. You\n// could call this function over and over, but it will be a no-op unless you\n// call AppendRow or AppendRows in between. Likewise, if the last thing you\n// append is a separator, it will not be rendered in addition to the usual table\n// separator.\n//\n// ******************************************************************************\n// Please note the following caveats:\n//  1. SetPageSize(): this may end up creating consecutive separator rows near\n//     the end of a page or at the beginning of a page\n//  2. SortBy(): since SortBy could inherently alter the ordering of rows, the\n//     separators may not appear after the row it was originally intended to\n//     follow\n//\n// ******************************************************************************\nfunc (t *Table) AppendSeparator() {\n\tif t.separators == nil {\n\t\tt.separators = make(map[int]bool)\n\t}\n\tif len(t.rowsRaw) > 0 {\n\t\tt.separators[len(t.rowsRaw)-1] = true\n\t}\n}\n\n// Length returns the number of rows to be rendered.\nfunc (t *Table) Length() int {\n\treturn len(t.rowsRaw)\n}\n\n// ResetFooters resets and clears all the Footer rows appended earlier.\nfunc (t *Table) ResetFooters() {\n\tt.rowsFooterRaw = nil\n}\n\n// ResetHeaders resets and clears all the Header rows appended earlier.\nfunc (t *Table) ResetHeaders() {\n\tt.rowsHeaderRaw = nil\n}\n\n// ResetRows resets and clears all the rows appended earlier.\nfunc (t *Table) ResetRows() {\n\tt.rowsRaw = nil\n\tt.separators = nil\n}\n\n// SetAllowedRowLength sets the maximum allowed length or a row (or line of\n// output) when rendered as a table. Rows that are longer than this limit will\n// be \"snipped\" to the length. Length has to be a positive value to take effect.\nfunc (t *Table) SetAllowedRowLength(length int) {\n\tt.allowedRowLength = length\n}\n\n// SetAutoIndex adds a generated header with columns such as \"A\", \"B\", \"C\", etc.\n// and a leading column with the row number similar to what you'd see on any\n// spreadsheet application. NOTE: Appending a Header will void this\n// functionality.\nfunc (t *Table) SetAutoIndex(autoIndex bool) {\n\tt.autoIndex = autoIndex\n}\n\n// SetCaption sets the text to be rendered just below the table. This will not\n// show up when the Table is rendered as a CSV.\nfunc (t *Table) SetCaption(format string, a ...interface{}) {\n\tt.caption = fmt.Sprintf(format, a...)\n}\n\n// SetColumnConfigs sets the configs for each Column.\nfunc (t *Table) SetColumnConfigs(configs []ColumnConfig) {\n\tt.columnConfigs = configs\n}\n\n// SetHTMLCSSClass sets the HTML CSS Class to use on the <table> node\n// when rendering the Table in HTML format.\n//\n// Deprecated: in favor of Style().HTML.CSSClass\nfunc (t *Table) SetHTMLCSSClass(cssClass string) {\n\tt.htmlCSSClass = cssClass\n}\n\n// SetIndexColumn sets the given Column # as the column that has the row\n// \"Number\". Valid values range from 1 to N. Note that this is not 0-indexed.\nfunc (t *Table) SetIndexColumn(colNum int) {\n\tt.indexColumn = colNum\n}\n\n// SetOutputMirror sets an io.Writer for all the Render functions to \"Write\" to\n// in addition to returning a string.\nfunc (t *Table) SetOutputMirror(mirror io.Writer) {\n\tt.outputMirror = mirror\n}\n\n// SetPageSize sets the maximum number of lines to render before rendering the\n// header rows again. This can be useful when dealing with tables containing a\n// long list of rows that can span pages. Please note that the pagination logic\n// will not consider Header/Footer lines for paging.\nfunc (t *Table) SetPageSize(numLines int) {\n\tt.pageSize = numLines\n}\n\n// SetRowPainter sets the RowPainter function which determines the colors to use\n// on a row. Before rendering, this function is invoked on all rows and the\n// color of each row is determined. This color takes precedence over other ways\n// to set color (ColumnConfig.Color*, SetColor*()).\nfunc (t *Table) SetRowPainter(painter RowPainter) {\n\tt.rowPainter = painter\n}\n\n// SetStyle overrides the DefaultStyle with the provided one.\nfunc (t *Table) SetStyle(style Style) {\n\tt.style = &style\n}\n\n// SetTitle sets the title text to be rendered above the table.\nfunc (t *Table) SetTitle(format string, a ...interface{}) {\n\tt.title = fmt.Sprintf(format, a...)\n}\n\n// SortBy sets the rules for sorting the Rows in the order specified. i.e., the\n// first SortBy instruction takes precedence over the second and so on. Any\n// duplicate instructions on the same column will be discarded while sorting.\nfunc (t *Table) SortBy(sortBy []SortBy) {\n\tt.sortBy = sortBy\n}\n\n// Style returns the current style.\nfunc (t *Table) Style() *Style {\n\tif t.style == nil {\n\t\ttempStyle := StyleDefault\n\t\tt.style = &tempStyle\n\t}\n\treturn t.style\n}\n\n// SuppressEmptyColumns hides columns when the column is empty in ALL the\n// regular rows.\nfunc (t *Table) SuppressEmptyColumns() {\n\tt.suppressEmptyColumns = true\n}\n\nfunc (t *Table) getAlign(colIdx int, hint renderHint) text.Align {\n\talign := text.AlignDefault\n\tif cfg, ok := t.columnConfigMap[colIdx]; ok {\n\t\tif hint.isHeaderRow {\n\t\t\talign = cfg.AlignHeader\n\t\t} else if hint.isFooterRow {\n\t\t\talign = cfg.AlignFooter\n\t\t} else {\n\t\t\talign = cfg.Align\n\t\t}\n\t}\n\tif align == text.AlignDefault {\n\t\tif !t.columnIsNonNumeric[colIdx] {\n\t\t\talign = text.AlignRight\n\t\t} else if hint.isAutoIndexRow {\n\t\t\talign = text.AlignCenter\n\t\t}\n\t}\n\treturn align\n}\n\nfunc (t *Table) getAutoIndexColumnIDs() rowStr {\n\trow := make(rowStr, t.numColumns)\n\tfor colIdx := range row {\n\t\trow[colIdx] = AutoIndexColumnID(colIdx)\n\t}\n\treturn row\n}\n\nfunc (t *Table) getBorderColors(hint renderHint) text.Colors {\n\tif t.style.Options.DoNotColorBordersAndSeparators {\n\t\treturn nil\n\t} else if t.style.Color.Border != nil {\n\t\treturn t.style.Color.Border\n\t} else if hint.isTitleRow {\n\t\treturn t.style.Title.Colors\n\t} else if hint.isHeaderRow {\n\t\treturn t.style.Color.Header\n\t} else if hint.isFooterRow {\n\t\treturn t.style.Color.Footer\n\t} else if t.autoIndex {\n\t\treturn t.style.Color.IndexColumn\n\t} else if hint.rowNumber%2 == 0 && t.style.Color.RowAlternate != nil {\n\t\treturn t.style.Color.RowAlternate\n\t}\n\treturn t.style.Color.Row\n}\n\nfunc (t *Table) getBorderLeft(hint renderHint) string {\n\tborder := t.style.Box.Left\n\tif hint.isBorderTop {\n\t\tif t.title != \"\" {\n\t\t\tborder = t.style.Box.LeftSeparator\n\t\t} else {\n\t\t\tborder = t.style.Box.TopLeft\n\t\t}\n\t} else if hint.isBorderBottom {\n\t\tborder = t.style.Box.BottomLeft\n\t} else if hint.isSeparatorRow {\n\t\tif t.autoIndex && hint.isHeaderOrFooterSeparator() {\n\t\t\tborder = t.style.Box.Left\n\t\t} else if !t.autoIndex && t.shouldMergeCellsVertically(0, hint) {\n\t\t\tborder = t.style.Box.Left\n\t\t} else {\n\t\t\tborder = t.style.Box.LeftSeparator\n\t\t}\n\t}\n\treturn border\n}\n\nfunc (t *Table) getBorderRight(hint renderHint) string {\n\tborder := t.style.Box.Right\n\tif hint.isBorderTop {\n\t\tif t.title != \"\" {\n\t\t\tborder = t.style.Box.RightSeparator\n\t\t} else {\n\t\t\tborder = t.style.Box.TopRight\n\t\t}\n\t} else if hint.isBorderBottom {\n\t\tborder = t.style.Box.BottomRight\n\t} else if hint.isSeparatorRow {\n\t\tif t.shouldMergeCellsVertically(t.numColumns-1, hint) {\n\t\t\tborder = t.style.Box.Right\n\t\t} else {\n\t\t\tborder = t.style.Box.RightSeparator\n\t\t}\n\t}\n\treturn border\n}\n\nfunc (t *Table) getColumnColors(colIdx int, hint renderHint) text.Colors {\n\tif hint.isBorderOrSeparator() {\n\t\tif colors := t.getColumnColorsForBorderOrSeparator(hint); colors != nil {\n\t\t\treturn colors\n\t\t}\n\t}\n\tif t.rowPainter != nil && hint.isRegularNonSeparatorRow() && !t.isIndexColumn(colIdx, hint) {\n\t\tif colors := t.rowsColors[hint.rowNumber-1]; colors != nil {\n\t\t\treturn colors\n\t\t}\n\t}\n\tif cfg, ok := t.columnConfigMap[colIdx]; ok {\n\t\tif hint.isSeparatorRow {\n\t\t\treturn nil\n\t\t} else if hint.isHeaderRow {\n\t\t\treturn cfg.ColorsHeader\n\t\t} else if hint.isFooterRow {\n\t\t\treturn cfg.ColorsFooter\n\t\t}\n\t\treturn cfg.Colors\n\t}\n\treturn nil\n}\n\nfunc (t *Table) getColumnColorsForBorderOrSeparator(hint renderHint) text.Colors {\n\tif t.style.Options.DoNotColorBordersAndSeparators {\n\t\treturn text.Colors{} // not nil to force caller to paint with no colors\n\t}\n\tif (hint.isBorderBottom || hint.isBorderTop) && t.style.Color.Border != nil {\n\t\treturn t.style.Color.Border\n\t}\n\tif hint.isSeparatorRow && t.style.Color.Separator != nil {\n\t\treturn t.style.Color.Separator\n\t}\n\treturn nil\n}\n\nfunc (t *Table) getColumnSeparator(row rowStr, colIdx int, hint renderHint) string {\n\tseparator := t.style.Box.MiddleVertical\n\tif hint.isSeparatorRow {\n\t\tif hint.isBorderTop {\n\t\t\tif t.shouldMergeCellsHorizontallyBelow(row, colIdx, hint) {\n\t\t\t\tseparator = t.style.Box.MiddleHorizontal\n\t\t\t} else {\n\t\t\t\tseparator = t.style.Box.TopSeparator\n\t\t\t}\n\t\t} else if hint.isBorderBottom {\n\t\t\tif t.shouldMergeCellsHorizontallyAbove(row, colIdx, hint) {\n\t\t\t\tseparator = t.style.Box.MiddleHorizontal\n\t\t\t} else {\n\t\t\t\tseparator = t.style.Box.BottomSeparator\n\t\t\t}\n\t\t} else {\n\t\t\tsm1 := t.shouldMergeCellsHorizontallyAbove(row, colIdx, hint)\n\t\t\tsm2 := t.shouldMergeCellsHorizontallyBelow(row, colIdx, hint)\n\t\t\tseparator = t.getColumnSeparatorNonBorder(sm1, sm2, colIdx, hint)\n\t\t}\n\t}\n\treturn separator\n}\n\nfunc (t *Table) getColumnSeparatorNonBorder(mergeCellsAbove bool, mergeCellsBelow bool, colIdx int, hint renderHint) string {\n\tmergeNextCol := t.shouldMergeCellsVertically(colIdx, hint)\n\tif hint.isAutoIndexColumn {\n\t\treturn t.getColumnSeparatorNonBorderAutoIndex(mergeNextCol, hint)\n\t}\n\n\tmergeCurrCol := t.shouldMergeCellsVertically(colIdx-1, hint)\n\treturn t.getColumnSeparatorNonBorderNonAutoIndex(mergeCellsAbove, mergeCellsBelow, mergeCurrCol, mergeNextCol)\n}\n\nfunc (t *Table) getColumnSeparatorNonBorderAutoIndex(mergeNextCol bool, hint renderHint) string {\n\tif hint.isHeaderOrFooterSeparator() {\n\t\tif mergeNextCol {\n\t\t\treturn t.style.Box.MiddleVertical\n\t\t}\n\t\treturn t.style.Box.LeftSeparator\n\t} else if mergeNextCol {\n\t\treturn t.style.Box.RightSeparator\n\t}\n\treturn t.style.Box.MiddleSeparator\n}\n\nfunc (t *Table) getColumnSeparatorNonBorderNonAutoIndex(mergeCellsAbove bool, mergeCellsBelow bool, mergeCurrCol bool, mergeNextCol bool) string {\n\tif mergeCellsAbove && mergeCellsBelow && mergeCurrCol && mergeNextCol {\n\t\treturn t.style.Box.EmptySeparator\n\t} else if mergeCellsAbove && mergeCellsBelow {\n\t\treturn t.style.Box.MiddleHorizontal\n\t} else if mergeCellsAbove {\n\t\treturn t.style.Box.TopSeparator\n\t} else if mergeCellsBelow {\n\t\treturn t.style.Box.BottomSeparator\n\t} else if mergeCurrCol && mergeNextCol {\n\t\treturn t.style.Box.MiddleVertical\n\t} else if mergeCurrCol {\n\t\treturn t.style.Box.LeftSeparator\n\t} else if mergeNextCol {\n\t\treturn t.style.Box.RightSeparator\n\t}\n\treturn t.style.Box.MiddleSeparator\n}\n\nfunc (t *Table) getColumnTransformer(colIdx int, hint renderHint) text.Transformer {\n\tvar transformer text.Transformer\n\tif cfg, ok := t.columnConfigMap[colIdx]; ok {\n\t\tif hint.isHeaderRow {\n\t\t\ttransformer = cfg.TransformerHeader\n\t\t} else if hint.isFooterRow {\n\t\t\ttransformer = cfg.TransformerFooter\n\t\t} else {\n\t\t\ttransformer = cfg.Transformer\n\t\t}\n\t}\n\treturn transformer\n}\n\nfunc (t *Table) getColumnWidthMax(colIdx int) int {\n\tif cfg, ok := t.columnConfigMap[colIdx]; ok {\n\t\treturn cfg.WidthMax\n\t}\n\treturn 0\n}\n\nfunc (t *Table) getColumnWidthMin(colIdx int) int {\n\tif cfg, ok := t.columnConfigMap[colIdx]; ok {\n\t\treturn cfg.WidthMin\n\t}\n\treturn 0\n}\n\nfunc (t *Table) getFormat(hint renderHint) text.Format {\n\tif hint.isSeparatorRow {\n\t\treturn text.FormatDefault\n\t} else if hint.isHeaderRow {\n\t\treturn t.style.Format.Header\n\t} else if hint.isFooterRow {\n\t\treturn t.style.Format.Footer\n\t}\n\treturn t.style.Format.Row\n}\n\nfunc (t *Table) getMaxColumnLengthForMerging(colIdx int) int {\n\tmaxColumnLength := t.maxColumnLengths[colIdx]\n\tmaxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.PaddingRight + t.style.Box.PaddingLeft)\n\tif t.style.Options.SeparateColumns {\n\t\tmaxColumnLength += text.RuneWidthWithoutEscSequences(t.style.Box.EmptySeparator)\n\t}\n\treturn maxColumnLength\n}\n\n// getMergedColumnIndices returns a map of colIdx values to all the other colIdx\n// values (that are being merged) and their lengths.\nfunc (t *Table) getMergedColumnIndices(row rowStr, hint renderHint) mergedColumnIndices {\n\tif !t.getRowConfig(hint).AutoMerge {\n\t\treturn nil\n\t}\n\n\tmci := make(mergedColumnIndices)\n\tfor colIdx := 0; colIdx < t.numColumns-1; colIdx++ {\n\t\t// look backward\n\t\tfor otherColIdx := colIdx - 1; colIdx >= 0 && otherColIdx >= 0; otherColIdx-- {\n\t\t\tif row[colIdx] != row[otherColIdx] {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tmci.safeAppend(colIdx, otherColIdx)\n\t\t}\n\t\t// look forward\n\t\tfor otherColIdx := colIdx + 1; colIdx < len(row) && otherColIdx < len(row); otherColIdx++ {\n\t\t\tif row[colIdx] != row[otherColIdx] {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tmci.safeAppend(colIdx, otherColIdx)\n\t\t}\n\t}\n\treturn mci\n}\n\nfunc (t *Table) getRow(rowIdx int, hint renderHint) rowStr {\n\tswitch {\n\tcase hint.isHeaderRow:\n\t\tif rowIdx >= 0 && rowIdx < len(t.rowsHeader) {\n\t\t\treturn t.rowsHeader[rowIdx]\n\t\t}\n\tcase hint.isFooterRow:\n\t\tif rowIdx >= 0 && rowIdx < len(t.rowsFooter) {\n\t\t\treturn t.rowsFooter[rowIdx]\n\t\t}\n\tdefault:\n\t\tif rowIdx >= 0 && rowIdx < len(t.rows) {\n\t\t\treturn t.rows[rowIdx]\n\t\t}\n\t}\n\treturn rowStr{}\n}\n\nfunc (t *Table) getRowConfig(hint renderHint) RowConfig {\n\trowIdx := hint.rowNumber - 1\n\tif rowIdx < 0 {\n\t\trowIdx = 0\n\t}\n\n\tswitch {\n\tcase hint.isHeaderRow:\n\t\treturn t.rowsHeaderConfigMap[rowIdx]\n\tcase hint.isFooterRow:\n\t\treturn t.rowsFooterConfigMap[rowIdx]\n\tdefault:\n\t\treturn t.rowsConfigMap[rowIdx]\n\t}\n}\n\nfunc (t *Table) getSeparatorColors(hint renderHint) text.Colors {\n\tif t.style.Options.DoNotColorBordersAndSeparators {\n\t\treturn nil\n\t} else if (hint.isBorderBottom || hint.isBorderTop) && t.style.Color.Border != nil {\n\t\treturn t.style.Color.Border\n\t} else if t.style.Color.Separator != nil {\n\t\treturn t.style.Color.Separator\n\t} else if hint.isHeaderRow {\n\t\treturn t.style.Color.Header\n\t} else if hint.isFooterRow {\n\t\treturn t.style.Color.Footer\n\t} else if hint.isAutoIndexColumn {\n\t\treturn t.style.Color.IndexColumn\n\t} else if hint.rowNumber > 0 && hint.rowNumber%2 == 0 {\n\t\treturn t.style.Color.RowAlternate\n\t}\n\treturn t.style.Color.Row\n}\n\nfunc (t *Table) getVAlign(colIdx int, hint renderHint) text.VAlign {\n\tvAlign := text.VAlignDefault\n\tif cfg, ok := t.columnConfigMap[colIdx]; ok {\n\t\tif hint.isHeaderRow {\n\t\t\tvAlign = cfg.VAlignHeader\n\t\t} else if hint.isFooterRow {\n\t\t\tvAlign = cfg.VAlignFooter\n\t\t} else {\n\t\t\tvAlign = cfg.VAlign\n\t\t}\n\t}\n\treturn vAlign\n}\n\nfunc (t *Table) hasHiddenColumns() bool {\n\tfor _, cc := range t.columnConfigMap {\n\t\tif cc.Hidden {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (t *Table) hideColumns() map[int]int {\n\tcolIdxMap := make(map[int]int)\n\tnumColumns := 0\n\thideColumnsInRows := func(rows []rowStr) []rowStr {\n\t\tvar rsp []rowStr\n\t\tfor _, row := range rows {\n\t\t\tvar rowNew rowStr\n\t\t\tfor colIdx, col := range row {\n\t\t\t\tcc := t.columnConfigMap[colIdx]\n\t\t\t\tif !cc.Hidden {\n\t\t\t\t\trowNew = append(rowNew, col)\n\t\t\t\t\tcolIdxMap[colIdx] = len(rowNew) - 1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(rowNew) > numColumns {\n\t\t\t\tnumColumns = len(rowNew)\n\t\t\t}\n\t\t\trsp = append(rsp, rowNew)\n\t\t}\n\t\treturn rsp\n\t}\n\n\t// hide columns as directed\n\tt.rows = hideColumnsInRows(t.rows)\n\tt.rowsFooter = hideColumnsInRows(t.rowsFooter)\n\tt.rowsHeader = hideColumnsInRows(t.rowsHeader)\n\n\t// reset numColumns to the new number of columns\n\tt.numColumns = numColumns\n\n\treturn colIdxMap\n}\n\nfunc (t *Table) isIndexColumn(colIdx int, hint renderHint) bool {\n\treturn t.indexColumn == colIdx+1 || hint.isAutoIndexColumn\n}\n\nfunc (t *Table) render(out *strings.Builder) string {\n\toutStr := out.String()\n\tif t.outputMirror != nil && len(outStr) > 0 {\n\t\t_, _ = t.outputMirror.Write([]byte(outStr))\n\t\t_, _ = t.outputMirror.Write([]byte(\"\\n\"))\n\t}\n\treturn outStr\n}\n\nfunc (t *Table) shouldMergeCellsHorizontallyAbove(row rowStr, colIdx int, hint renderHint) bool {\n\tif hint.isAutoIndexColumn || hint.isAutoIndexRow {\n\t\treturn false\n\t}\n\n\trowConfig := t.getRowConfig(hint)\n\tif hint.isSeparatorRow {\n\t\tif hint.isHeaderRow && hint.rowNumber == 1 {\n\t\t\trowConfig = t.getRowConfig(hint)\n\t\t\trow = t.getRow(hint.rowNumber-1, hint)\n\t\t} else if hint.isFooterRow && hint.isFirstRow {\n\t\t\trowConfig = t.getRowConfig(renderHint{isLastRow: true, rowNumber: len(t.rows)})\n\t\t\trow = t.getRow(len(t.rows)-1, renderHint{})\n\t\t} else if hint.isFooterRow && hint.isBorderBottom {\n\t\t\trow = t.getRow(len(t.rowsFooter)-1, renderHint{isFooterRow: true})\n\t\t} else {\n\t\t\trow = t.getRow(hint.rowNumber-1, hint)\n\t\t}\n\t}\n\n\tif rowConfig.AutoMerge {\n\t\treturn row.areEqual(colIdx-1, colIdx)\n\t}\n\treturn false\n}\n\nfunc (t *Table) shouldMergeCellsHorizontallyBelow(row rowStr, colIdx int, hint renderHint) bool {\n\tif hint.isAutoIndexColumn || hint.isAutoIndexRow {\n\t\treturn false\n\t}\n\n\tvar rowConfig RowConfig\n\tif hint.isSeparatorRow {\n\t\tif hint.isRegularRow() {\n\t\t\trowConfig = t.getRowConfig(renderHint{rowNumber: hint.rowNumber + 1})\n\t\t\trow = t.getRow(hint.rowNumber, renderHint{})\n\t\t} else if hint.isHeaderRow && hint.rowNumber == 0 {\n\t\t\trowConfig = t.getRowConfig(renderHint{isHeaderRow: true, rowNumber: 1})\n\t\t\trow = t.getRow(0, hint)\n\t\t} else if hint.isHeaderRow && hint.isLastRow {\n\t\t\trowConfig = t.getRowConfig(renderHint{rowNumber: 1})\n\t\t\trow = t.getRow(0, renderHint{})\n\t\t} else if hint.isHeaderRow {\n\t\t\trowConfig = t.getRowConfig(renderHint{isHeaderRow: true, rowNumber: hint.rowNumber + 1})\n\t\t\trow = t.getRow(hint.rowNumber, hint)\n\t\t} else if hint.isFooterRow && hint.rowNumber >= 0 {\n\t\t\trowConfig = t.getRowConfig(renderHint{isFooterRow: true, rowNumber: 1})\n\t\t\trow = t.getRow(hint.rowNumber, renderHint{isFooterRow: true})\n\t\t}\n\t}\n\n\tif rowConfig.AutoMerge {\n\t\treturn row.areEqual(colIdx-1, colIdx)\n\t}\n\treturn false\n}\n\nfunc (t *Table) shouldMergeCellsVertically(colIdx int, hint renderHint) bool {\n\tif t.columnConfigMap[colIdx].AutoMerge && colIdx < t.numColumns {\n\t\tif hint.isSeparatorRow {\n\t\t\trowPrev := t.getRow(hint.rowNumber-1, hint)\n\t\t\trowNext := t.getRow(hint.rowNumber, hint)\n\t\t\tif colIdx < len(rowPrev) && colIdx < len(rowNext) {\n\t\t\t\treturn rowPrev[colIdx] == rowNext[colIdx]\n\t\t\t}\n\t\t} else {\n\t\t\trowPrev := t.getRow(hint.rowNumber-2, hint)\n\t\t\trowCurr := t.getRow(hint.rowNumber-1, hint)\n\t\t\tif colIdx < len(rowPrev) && colIdx < len(rowCurr) {\n\t\t\t\treturn rowPrev[colIdx] == rowCurr[colIdx]\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (t *Table) wrapRow(row rowStr) (int, rowStr) {\n\tcolMaxLines := 0\n\trowWrapped := make(rowStr, len(row))\n\tfor colIdx, colStr := range row {\n\t\twidthEnforcer := t.columnConfigMap[colIdx].getWidthMaxEnforcer()\n\t\tmaxWidth := t.getColumnWidthMax(colIdx)\n\t\tif maxWidth == 0 {\n\t\t\tmaxWidth = t.maxColumnLengths[colIdx]\n\t\t}\n\t\trowWrapped[colIdx] = widthEnforcer(colStr, maxWidth)\n\t\tcolNumLines := strings.Count(rowWrapped[colIdx], \"\\n\") + 1\n\t\tif colNumLines > colMaxLines {\n\t\t\tcolMaxLines = colNumLines\n\t\t}\n\t}\n\treturn colMaxLines, rowWrapped\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/util.go",
    "content": "package table\n\nimport (\n\t\"reflect\"\n)\n\n// AutoIndexColumnID returns a unique Column ID/Name for the given Column Number.\n// The functionality is similar to what you get in an Excel spreadsheet w.r.t.\n// the Column ID/Name.\nfunc AutoIndexColumnID(colIdx int) string {\n\tcharIdx := colIdx % 26\n\tout := string(rune(65 + charIdx))\n\tcolIdx = colIdx / 26\n\tif colIdx > 0 {\n\t\treturn AutoIndexColumnID(colIdx-1) + out\n\t}\n\treturn out\n}\n\n// WidthEnforcer is a function that helps enforce a width condition on a string.\ntype WidthEnforcer func(col string, maxLen int) string\n\n// widthEnforcerNone returns the input string as is without any modifications.\nfunc widthEnforcerNone(col string, _ int) string {\n\treturn col\n}\n\n// isNumber returns true if the argument is a numeric type; false otherwise.\nfunc isNumber(x interface{}) bool {\n\tif x == nil {\n\t\treturn false\n\t}\n\n\tswitch reflect.TypeOf(x).Kind() {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,\n\t\treflect.Float32, reflect.Float64:\n\t\treturn true\n\t}\n\treturn false\n}\n\ntype mergedColumnIndices map[int]map[int]bool\n\nfunc (m mergedColumnIndices) mergedLength(colIdx int, maxColumnLengths []int) int {\n\tmergedLength := maxColumnLengths[colIdx]\n\tfor otherColIdx := range m[colIdx] {\n\t\tmergedLength += maxColumnLengths[otherColIdx]\n\t}\n\treturn mergedLength\n}\n\nfunc (m mergedColumnIndices) len(colIdx int) int {\n\treturn len(m[colIdx]) + 1\n}\n\nfunc (m mergedColumnIndices) safeAppend(colIdx, otherColIdx int) {\n\t// map\n\tif m[colIdx] == nil {\n\t\tm[colIdx] = make(map[int]bool)\n\t}\n\tm[colIdx][otherColIdx] = true\n\n\t// reverse map\n\tif m[otherColIdx] == nil {\n\t\tm[otherColIdx] = make(map[int]bool)\n\t}\n\tm[otherColIdx][colIdx] = true\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/table/writer.go",
    "content": "package table\n\nimport (\n\t\"io\"\n)\n\n// Writer declares the interfaces that can be used to set up and render a table.\ntype Writer interface {\n\tAppendFooter(row Row, configs ...RowConfig)\n\tAppendHeader(row Row, configs ...RowConfig)\n\tAppendRow(row Row, configs ...RowConfig)\n\tAppendRows(rows []Row, configs ...RowConfig)\n\tAppendSeparator()\n\tLength() int\n\tRender() string\n\tRenderCSV() string\n\tRenderHTML() string\n\tRenderMarkdown() string\n\tRenderTSV() string\n\tResetFooters()\n\tResetHeaders()\n\tResetRows()\n\tSetAllowedRowLength(length int)\n\tSetAutoIndex(autoIndex bool)\n\tSetCaption(format string, a ...interface{})\n\tSetColumnConfigs(configs []ColumnConfig)\n\tSetIndexColumn(colNum int)\n\tSetOutputMirror(mirror io.Writer)\n\tSetPageSize(numLines int)\n\tSetRowPainter(painter RowPainter)\n\tSetStyle(style Style)\n\tSetTitle(format string, a ...interface{})\n\tSortBy(sortBy []SortBy)\n\tStyle() *Style\n\tSuppressEmptyColumns()\n\n\t// deprecated; in favor of Style().HTML.CSSClass\n\tSetHTMLCSSClass(cssClass string)\n}\n\n// NewWriter initializes and returns a Writer.\nfunc NewWriter() Writer {\n\treturn &Table{}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/README.md",
    "content": "# text\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/jedib0t/go-pretty/v6.svg)](https://pkg.go.dev/github.com/jedib0t/go-pretty/v6/text)\n\nPackage with utility functions to manipulate strings/text.\n\nUsed heavily in the other packages in this repo ([list](../list),\n[progress](../progress), and [table](../table))."
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/align.go",
    "content": "package text\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// Align denotes how text is to be aligned horizontally.\ntype Align int\n\n// Align enumerations\nconst (\n\tAlignDefault Align = iota // same as AlignLeft\n\tAlignLeft                 // \"left        \"\n\tAlignCenter               // \"   center   \"\n\tAlignJustify              // \"justify   it\"\n\tAlignRight                // \"       right\"\n)\n\n// Apply aligns the text as directed. For ex.:\n//   - AlignDefault.Apply(\"Jon Snow\", 12) returns \"Jon Snow    \"\n//   - AlignLeft.Apply(\"Jon Snow\",    12) returns \"Jon Snow    \"\n//   - AlignCenter.Apply(\"Jon Snow\",  12) returns \"  Jon Snow  \"\n//   - AlignJustify.Apply(\"Jon Snow\", 12) returns \"Jon     Snow\"\n//   - AlignRight.Apply(\"Jon Snow\",   12) returns \"    Jon Snow\"\nfunc (a Align) Apply(text string, maxLength int) string {\n\ttext = a.trimString(text)\n\tsLen := utf8.RuneCountInString(text)\n\tsLenWoE := RuneWidthWithoutEscSequences(text)\n\tnumEscChars := sLen - sLenWoE\n\n\t// now, align the text\n\tswitch a {\n\tcase AlignDefault, AlignLeft:\n\t\treturn fmt.Sprintf(\"%-\"+strconv.Itoa(maxLength+numEscChars)+\"s\", text)\n\tcase AlignCenter:\n\t\tif sLenWoE < maxLength {\n\t\t\t// left pad with half the number of spaces needed before using %text\n\t\t\treturn fmt.Sprintf(\"%\"+strconv.Itoa(maxLength+numEscChars)+\"s\",\n\t\t\t\ttext+strings.Repeat(\" \", (maxLength-sLenWoE)/2))\n\t\t}\n\tcase AlignJustify:\n\t\treturn a.justifyText(text, sLenWoE, maxLength)\n\t}\n\treturn fmt.Sprintf(\"%\"+strconv.Itoa(maxLength+numEscChars)+\"s\", text)\n}\n\n// HTMLProperty returns the equivalent HTML horizontal-align tag property.\nfunc (a Align) HTMLProperty() string {\n\tswitch a {\n\tcase AlignLeft:\n\t\treturn \"align=\\\"left\\\"\"\n\tcase AlignCenter:\n\t\treturn \"align=\\\"center\\\"\"\n\tcase AlignJustify:\n\t\treturn \"align=\\\"justify\\\"\"\n\tcase AlignRight:\n\t\treturn \"align=\\\"right\\\"\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// MarkdownProperty returns the equivalent Markdown horizontal-align separator.\nfunc (a Align) MarkdownProperty() string {\n\tswitch a {\n\tcase AlignLeft:\n\t\treturn \":--- \"\n\tcase AlignCenter:\n\t\treturn \":---:\"\n\tcase AlignRight:\n\t\treturn \" ---:\"\n\tdefault:\n\t\treturn \" --- \"\n\t}\n}\n\nfunc (a Align) justifyText(text string, textLength int, maxLength int) string {\n\t// split the text into individual words\n\twordsUnfiltered := strings.Split(text, \" \")\n\twords := Filter(wordsUnfiltered, func(item string) bool {\n\t\treturn item != \"\"\n\t})\n\t// empty string implies spaces for maxLength\n\tif len(words) == 0 {\n\t\treturn strings.Repeat(\" \", maxLength)\n\t}\n\t// get the number of spaces to insert into the text\n\tnumSpacesNeeded := maxLength - textLength + strings.Count(text, \" \")\n\tnumSpacesNeededBetweenWords := 0\n\tif len(words) > 1 {\n\t\tnumSpacesNeededBetweenWords = numSpacesNeeded / (len(words) - 1)\n\t}\n\t// create the output string word by word with spaces in between\n\tvar outText strings.Builder\n\toutText.Grow(maxLength)\n\tfor idx, word := range words {\n\t\tif idx > 0 {\n\t\t\t// insert spaces only after the first word\n\t\t\tif idx == len(words)-1 {\n\t\t\t\t// insert all the remaining space before the last word\n\t\t\t\toutText.WriteString(strings.Repeat(\" \", numSpacesNeeded))\n\t\t\t\tnumSpacesNeeded = 0\n\t\t\t} else {\n\t\t\t\t// insert the determined number of spaces between each word\n\t\t\t\toutText.WriteString(strings.Repeat(\" \", numSpacesNeededBetweenWords))\n\t\t\t\t// and reduce the number of spaces needed after this\n\t\t\t\tnumSpacesNeeded -= numSpacesNeededBetweenWords\n\t\t\t}\n\t\t}\n\t\toutText.WriteString(word)\n\t\tif idx == len(words)-1 && numSpacesNeeded > 0 {\n\t\t\toutText.WriteString(strings.Repeat(\" \", numSpacesNeeded))\n\t\t}\n\t}\n\treturn outText.String()\n}\n\nfunc (a Align) trimString(text string) string {\n\tswitch a {\n\tcase AlignDefault, AlignLeft:\n\t\tif strings.HasSuffix(text, \" \") {\n\t\t\treturn strings.TrimRight(text, \" \")\n\t\t}\n\tcase AlignRight:\n\t\tif strings.HasPrefix(text, \" \") {\n\t\t\treturn strings.TrimLeft(text, \" \")\n\t\t}\n\tdefault:\n\t\tif strings.HasPrefix(text, \" \") || strings.HasSuffix(text, \" \") {\n\t\t\treturn strings.Trim(text, \" \")\n\t\t}\n\t}\n\treturn text\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/ansi.go",
    "content": "package text\n\nimport \"strings\"\n\n// ANSICodesSupported will be true on consoles where ANSI Escape Codes/Sequences\n// are supported.\nvar ANSICodesSupported = areANSICodesSupported()\n\n// Escape encodes the string with the ANSI Escape Sequence.\n// For ex.:\n//\n//\tEscape(\"Ghost\", \"\") == \"Ghost\"\n//\tEscape(\"Ghost\", \"\\x1b[91m\") == \"\\x1b[91mGhost\\x1b[0m\"\n//\tEscape(\"\\x1b[94mGhost\\x1b[0mLady\", \"\\x1b[91m\") == \"\\x1b[94mGhost\\x1b[0m\\x1b[91mLady\\x1b[0m\"\n//\tEscape(\"Nymeria\\x1b[94mGhost\\x1b[0mLady\", \"\\x1b[91m\") == \"\\x1b[91mNymeria\\x1b[94mGhost\\x1b[0m\\x1b[91mLady\\x1b[0m\"\n//\tEscape(\"Nymeria \\x1b[94mGhost\\x1b[0m Lady\", \"\\x1b[91m\") == \"\\x1b[91mNymeria \\x1b[94mGhost\\x1b[0m\\x1b[91m Lady\\x1b[0m\"\nfunc Escape(str string, escapeSeq string) string {\n\tout := \"\"\n\tif !strings.HasPrefix(str, EscapeStart) {\n\t\tout += escapeSeq\n\t}\n\tout += strings.Replace(str, EscapeReset, EscapeReset+escapeSeq, -1)\n\tif !strings.HasSuffix(out, EscapeReset) {\n\t\tout += EscapeReset\n\t}\n\tif strings.Contains(out, escapeSeq+EscapeReset) {\n\t\tout = strings.Replace(out, escapeSeq+EscapeReset, \"\", -1)\n\t}\n\treturn out\n}\n\n// StripEscape strips all ANSI Escape Sequence from the string.\n// For ex.:\n//\n//\tStripEscape(\"Ghost\") == \"Ghost\"\n//\tStripEscape(\"\\x1b[91mGhost\\x1b[0m\") == \"Ghost\"\n//\tStripEscape(\"\\x1b[94mGhost\\x1b[0m\\x1b[91mLady\\x1b[0m\") == \"GhostLady\"\n//\tStripEscape(\"\\x1b[91mNymeria\\x1b[94mGhost\\x1b[0m\\x1b[91mLady\\x1b[0m\") == \"NymeriaGhostLady\"\n//\tStripEscape(\"\\x1b[91mNymeria \\x1b[94mGhost\\x1b[0m\\x1b[91m Lady\\x1b[0m\") == \"Nymeria Ghost Lady\"\nfunc StripEscape(str string) string {\n\tvar out strings.Builder\n\tout.Grow(RuneWidthWithoutEscSequences(str))\n\n\tisEscSeq := false\n\tfor _, sChr := range str {\n\t\tif sChr == EscapeStartRune {\n\t\t\tisEscSeq = true\n\t\t}\n\t\tif !isEscSeq {\n\t\t\tout.WriteRune(sChr)\n\t\t}\n\t\tif isEscSeq && sChr == EscapeStopRune {\n\t\t\tisEscSeq = false\n\t\t}\n\t}\n\treturn out.String()\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/ansi_unix.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage text\n\nfunc areANSICodesSupported() bool {\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/ansi_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage text\n\nimport (\n\t\"os\"\n\t\"sync\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\nvar enableVTPMutex = sync.Mutex{}\n\nfunc areANSICodesSupported() bool {\n\tenableVTPMutex.Lock()\n\tdefer enableVTPMutex.Unlock()\n\n\toutHandle := windows.Handle(os.Stdout.Fd())\n\tvar outMode uint32\n\tif err := windows.GetConsoleMode(outHandle, &outMode); err == nil {\n\t\tif outMode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 {\n\t\t\treturn true\n\t\t}\n\t\tif err := windows.SetConsoleMode(outHandle, outMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING); err == nil {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/color.go",
    "content": "package text\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\nvar colorsEnabled = areANSICodesSupported()\n\n// DisableColors (forcefully) disables color coding globally.\nfunc DisableColors() {\n\tcolorsEnabled = false\n}\n\n// EnableColors (forcefully) enables color coding globally.\nfunc EnableColors() {\n\tcolorsEnabled = true\n}\n\n// The logic here is inspired from github.com/fatih/color; the following is\n// the bare minimum logic required to print Colored to the console.\n// The differences:\n// * This one caches the escape sequences for cases with multiple colors\n// * This one handles cases where the incoming already has colors in the\n//   form of escape sequences; in which case, text that does not have any\n//   escape sequences are colored/escaped\n\n// Color represents a single color to render with.\ntype Color int\n\n// Base colors -- attributes in reality\nconst (\n\tReset Color = iota\n\tBold\n\tFaint\n\tItalic\n\tUnderline\n\tBlinkSlow\n\tBlinkRapid\n\tReverseVideo\n\tConcealed\n\tCrossedOut\n)\n\n// Foreground colors\nconst (\n\tFgBlack Color = iota + 30\n\tFgRed\n\tFgGreen\n\tFgYellow\n\tFgBlue\n\tFgMagenta\n\tFgCyan\n\tFgWhite\n)\n\n// Foreground Hi-Intensity colors\nconst (\n\tFgHiBlack Color = iota + 90\n\tFgHiRed\n\tFgHiGreen\n\tFgHiYellow\n\tFgHiBlue\n\tFgHiMagenta\n\tFgHiCyan\n\tFgHiWhite\n)\n\n// Background colors\nconst (\n\tBgBlack Color = iota + 40\n\tBgRed\n\tBgGreen\n\tBgYellow\n\tBgBlue\n\tBgMagenta\n\tBgCyan\n\tBgWhite\n)\n\n// Background Hi-Intensity colors\nconst (\n\tBgHiBlack Color = iota + 100\n\tBgHiRed\n\tBgHiGreen\n\tBgHiYellow\n\tBgHiBlue\n\tBgHiMagenta\n\tBgHiCyan\n\tBgHiWhite\n)\n\n// EscapeSeq returns the ANSI escape sequence for the color.\nfunc (c Color) EscapeSeq() string {\n\treturn EscapeStart + strconv.Itoa(int(c)) + EscapeStop\n}\n\n// HTMLProperty returns the \"class\" attribute for the color.\nfunc (c Color) HTMLProperty() string {\n\tout := \"\"\n\tif class, ok := colorCSSClassMap[c]; ok {\n\t\tout = fmt.Sprintf(\"class=\\\"%s\\\"\", class)\n\t}\n\treturn out\n}\n\n// Sprint colorizes and prints the given string(s).\nfunc (c Color) Sprint(a ...interface{}) string {\n\treturn colorize(fmt.Sprint(a...), c.EscapeSeq())\n}\n\n// Sprintf formats and colorizes and prints the given string(s).\nfunc (c Color) Sprintf(format string, a ...interface{}) string {\n\treturn colorize(fmt.Sprintf(format, a...), c.EscapeSeq())\n}\n\n// Colors represents an array of Color objects to render with.\n// Example: Colors{FgCyan, BgBlack}\ntype Colors []Color\n\n// colorsSeqMap caches the escape sequence for a set of colors\nvar colorsSeqMap = sync.Map{}\n\n// EscapeSeq returns the ANSI escape sequence for the colors set.\nfunc (c Colors) EscapeSeq() string {\n\tif len(c) == 0 {\n\t\treturn \"\"\n\t}\n\n\tcolorsKey := fmt.Sprintf(\"%#v\", c)\n\tescapeSeq, ok := colorsSeqMap.Load(colorsKey)\n\tif !ok || escapeSeq == \"\" {\n\t\tcolorNums := make([]string, len(c))\n\t\tfor idx, color := range c {\n\t\t\tcolorNums[idx] = strconv.Itoa(int(color))\n\t\t}\n\t\tescapeSeq = EscapeStart + strings.Join(colorNums, \";\") + EscapeStop\n\t\tcolorsSeqMap.Store(colorsKey, escapeSeq)\n\t}\n\treturn escapeSeq.(string)\n}\n\n// HTMLProperty returns the \"class\" attribute for the colors.\nfunc (c Colors) HTMLProperty() string {\n\tif len(c) == 0 {\n\t\treturn \"\"\n\t}\n\n\tvar classes []string\n\tfor _, color := range c {\n\t\tif class, ok := colorCSSClassMap[color]; ok {\n\t\t\tclasses = append(classes, class)\n\t\t}\n\t}\n\tif len(classes) > 1 {\n\t\tsort.Strings(classes)\n\t}\n\treturn fmt.Sprintf(\"class=\\\"%s\\\"\", strings.Join(classes, \" \"))\n}\n\n// Sprint colorizes and prints the given string(s).\nfunc (c Colors) Sprint(a ...interface{}) string {\n\treturn colorize(fmt.Sprint(a...), c.EscapeSeq())\n}\n\n// Sprintf formats and colorizes and prints the given string(s).\nfunc (c Colors) Sprintf(format string, a ...interface{}) string {\n\treturn colorize(fmt.Sprintf(format, a...), c.EscapeSeq())\n}\n\nfunc colorize(s string, escapeSeq string) string {\n\tif !colorsEnabled || escapeSeq == \"\" {\n\t\treturn s\n\t}\n\treturn Escape(s, escapeSeq)\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/color_html.go",
    "content": "package text\n\n// colorCSSClassMap contains the equivalent CSS-class for all colors\nvar colorCSSClassMap = map[Color]string{\n\tBold:         \"bold\",\n\tFaint:        \"faint\",\n\tItalic:       \"italic\",\n\tUnderline:    \"underline\",\n\tBlinkSlow:    \"blink-slow\",\n\tBlinkRapid:   \"blink-rapid\",\n\tReverseVideo: \"reverse-video\",\n\tConcealed:    \"concealed\",\n\tCrossedOut:   \"crossed-out\",\n\tFgBlack:      \"fg-black\",\n\tFgRed:        \"fg-red\",\n\tFgGreen:      \"fg-green\",\n\tFgYellow:     \"fg-yellow\",\n\tFgBlue:       \"fg-blue\",\n\tFgMagenta:    \"fg-magenta\",\n\tFgCyan:       \"fg-cyan\",\n\tFgWhite:      \"fg-white\",\n\tFgHiBlack:    \"fg-hi-black\",\n\tFgHiRed:      \"fg-hi-red\",\n\tFgHiGreen:    \"fg-hi-green\",\n\tFgHiYellow:   \"fg-hi-yellow\",\n\tFgHiBlue:     \"fg-hi-blue\",\n\tFgHiMagenta:  \"fg-hi-magenta\",\n\tFgHiCyan:     \"fg-hi-cyan\",\n\tFgHiWhite:    \"fg-hi-white\",\n\tBgBlack:      \"bg-black\",\n\tBgRed:        \"bg-red\",\n\tBgGreen:      \"bg-green\",\n\tBgYellow:     \"bg-yellow\",\n\tBgBlue:       \"bg-blue\",\n\tBgMagenta:    \"bg-magenta\",\n\tBgCyan:       \"bg-cyan\",\n\tBgWhite:      \"bg-white\",\n\tBgHiBlack:    \"bg-hi-black\",\n\tBgHiRed:      \"bg-hi-red\",\n\tBgHiGreen:    \"bg-hi-green\",\n\tBgHiYellow:   \"bg-hi-yellow\",\n\tBgHiBlue:     \"bg-hi-blue\",\n\tBgHiMagenta:  \"bg-hi-magenta\",\n\tBgHiCyan:     \"bg-hi-cyan\",\n\tBgHiWhite:    \"bg-hi-white\",\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/cursor.go",
    "content": "package text\n\nimport (\n\t\"fmt\"\n)\n\n// Cursor helps move the cursor on the console in multiple directions.\ntype Cursor rune\n\nconst (\n\t// CursorDown helps move the Cursor Down X lines\n\tCursorDown Cursor = 'B'\n\n\t// CursorLeft helps move the Cursor Left X characters\n\tCursorLeft Cursor = 'D'\n\n\t// CursorRight helps move the Cursor Right X characters\n\tCursorRight Cursor = 'C'\n\n\t// CursorUp helps move the Cursor Up X lines\n\tCursorUp Cursor = 'A'\n\n\t// EraseLine helps erase all characters to the Right of the Cursor in the\n\t// current line\n\tEraseLine Cursor = 'K'\n)\n\n// Sprint prints the Escape Sequence to move the Cursor once.\nfunc (c Cursor) Sprint() string {\n\treturn fmt.Sprintf(\"%s%c\", EscapeStart, c)\n}\n\n// Sprintn prints the Escape Sequence to move the Cursor \"n\" times.\nfunc (c Cursor) Sprintn(n int) string {\n\tif c == EraseLine {\n\t\treturn c.Sprint()\n\t}\n\treturn fmt.Sprintf(\"%s%d%c\", EscapeStart, n, c)\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/direction.go",
    "content": "package text\n\n// Direction defines the overall flow of text. Similar to bidi.Direction, but\n// simplified and specific to this package.\ntype Direction int\n\n// Available Directions.\nconst (\n\tDefault Direction = iota\n\tLeftToRight\n\tRightToLeft\n)\n\n// Modifier returns a character to force the given direction for the text that\n// follows the modifier.\nfunc (d Direction) Modifier() string {\n\tswitch d {\n\tcase LeftToRight:\n\t\treturn \"\\u202a\"\n\tcase RightToLeft:\n\t\treturn \"\\u202b\"\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/escape.go",
    "content": "package text\n\nimport \"strings\"\n\n// Constants\nconst (\n\tCSIStartRune    = rune(91) // [\n\tCSIStopRune     = 'm'\n\tEscapeReset     = EscapeStart + \"0\" + EscapeStop\n\tEscapeStart     = \"\\x1b[\"\n\tEscapeStartRune = rune(27) // \\x1b\n\tEscapeStop      = \"m\"\n\tEscapeStopRune  = 'm'\n\tOSIStartRune    = rune(93) // ]\n\tOSIStopRune     = '\\\\'\n)\n\ntype escKind int\n\nconst (\n\tescKindUnknown escKind = iota\n\tescKindCSI\n\tescKindOSI\n)\n\ntype escSeq struct {\n\tisIn    bool\n\tcontent strings.Builder\n\tkind    escKind\n}\n\nfunc (e *escSeq) InspectRune(r rune) {\n\tif !e.isIn && r == EscapeStartRune {\n\t\te.isIn = true\n\t\te.kind = escKindUnknown\n\t\te.content.Reset()\n\t\te.content.WriteRune(r)\n\t} else if e.isIn {\n\t\tswitch {\n\t\tcase e.kind == escKindUnknown && r == CSIStartRune:\n\t\t\te.kind = escKindCSI\n\t\tcase e.kind == escKindUnknown && r == OSIStartRune:\n\t\t\te.kind = escKindOSI\n\t\tcase e.kind == escKindCSI && r == CSIStopRune || e.kind == escKindOSI && r == OSIStopRune:\n\t\t\te.isIn = false\n\t\t\te.kind = escKindUnknown\n\t\t}\n\t\te.content.WriteRune(r)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/filter.go",
    "content": "package text\n\n// Filter filters the slice 's' to items which return truth when passed to 'f'.\nfunc Filter(s []string, f func(string) bool) []string {\n\tvar out []string\n\tfor _, item := range s {\n\t\tif f(item) {\n\t\t\tout = append(out, item)\n\t\t}\n\t}\n\treturn out\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/format.go",
    "content": "package text\n\nimport (\n\t\"strings\"\n\t\"unicode\"\n)\n\n// Format lets you transform the text in supported methods while keeping escape\n// sequences in the string intact and untouched.\ntype Format int\n\n// Format enumerations\nconst (\n\tFormatDefault Format = iota // default_Case\n\tFormatLower                 // lower\n\tFormatTitle                 // Title\n\tFormatUpper                 // UPPER\n)\n\n// Apply converts the text as directed.\nfunc (tc Format) Apply(text string) string {\n\tswitch tc {\n\tcase FormatLower:\n\t\treturn strings.ToLower(text)\n\tcase FormatTitle:\n\t\treturn toTitle(text)\n\tcase FormatUpper:\n\t\treturn toUpper(text)\n\tdefault:\n\t\treturn text\n\t}\n}\n\nfunc toTitle(text string) string {\n\tprev, inEscSeq := ' ', false\n\treturn strings.Map(\n\t\tfunc(r rune) rune {\n\t\t\tif r == EscapeStartRune {\n\t\t\t\tinEscSeq = true\n\t\t\t}\n\t\t\tif !inEscSeq {\n\t\t\t\tif isSeparator(prev) {\n\t\t\t\t\tprev = r\n\t\t\t\t\tr = unicode.ToUpper(r)\n\t\t\t\t} else {\n\t\t\t\t\tprev = r\n\t\t\t\t}\n\t\t\t}\n\t\t\tif inEscSeq && r == EscapeStopRune {\n\t\t\t\tinEscSeq = false\n\t\t\t}\n\t\t\treturn r\n\t\t},\n\t\ttext,\n\t)\n}\n\nfunc toUpper(text string) string {\n\tinEscSeq := false\n\treturn strings.Map(\n\t\tfunc(r rune) rune {\n\t\t\tif r == EscapeStartRune {\n\t\t\t\tinEscSeq = true\n\t\t\t}\n\t\t\tif !inEscSeq {\n\t\t\t\tr = unicode.ToUpper(r)\n\t\t\t}\n\t\t\tif inEscSeq && r == EscapeStopRune {\n\t\t\t\tinEscSeq = false\n\t\t\t}\n\t\t\treturn r\n\t\t},\n\t\ttext,\n\t)\n}\n\n// isSeparator returns true if the given rune is a separator. This function is\n// lifted straight out of the standard library @ strings/strings.go.\nfunc isSeparator(r rune) bool {\n\t// ASCII alphanumerics and underscore are not separators\n\tif r <= 0x7F {\n\t\tswitch {\n\t\tcase '0' <= r && r <= '9':\n\t\t\treturn false\n\t\tcase 'a' <= r && r <= 'z':\n\t\t\treturn false\n\t\tcase 'A' <= r && r <= 'Z':\n\t\t\treturn false\n\t\tcase r == '_':\n\t\t\treturn false\n\t\t}\n\t\treturn true\n\t}\n\t// Letters and digits are not separators\n\tif unicode.IsLetter(r) || unicode.IsDigit(r) {\n\t\treturn false\n\t}\n\t// Otherwise, all we can do for now is treat spaces as separators.\n\treturn unicode.IsSpace(r)\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/hyperlink.go",
    "content": "package text\n\nimport \"fmt\"\n\nfunc Hyperlink(url, text string) string {\n\tif url == \"\" {\n\t\treturn text\n\t}\n\tif text == \"\" {\n\t\treturn url\n\t}\n\t// source https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda\n\treturn fmt.Sprintf(\"\\x1b]8;;%s\\x1b\\\\%s\\x1b]8;;\\x1b\\\\\", url, text)\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/string.go",
    "content": "package text\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/mattn/go-runewidth\"\n)\n\n// RuneWidth stuff\nvar (\n\trwCondition = runewidth.NewCondition()\n)\n\n// InsertEveryN inserts the rune every N characters in the string. For ex.:\n//\n//\tInsertEveryN(\"Ghost\", '-', 1) == \"G-h-o-s-t\"\n//\tInsertEveryN(\"Ghost\", '-', 2) == \"Gh-os-t\"\n//\tInsertEveryN(\"Ghost\", '-', 3) == \"Gho-st\"\n//\tInsertEveryN(\"Ghost\", '-', 4) == \"Ghos-t\"\n//\tInsertEveryN(\"Ghost\", '-', 5) == \"Ghost\"\nfunc InsertEveryN(str string, runeToInsert rune, n int) string {\n\tif n <= 0 {\n\t\treturn str\n\t}\n\n\tsLen := RuneWidthWithoutEscSequences(str)\n\tvar out strings.Builder\n\tout.Grow(sLen + (sLen / n))\n\toutLen, eSeq := 0, escSeq{}\n\tfor idx, c := range str {\n\t\tif eSeq.isIn {\n\t\t\teSeq.InspectRune(c)\n\t\t\tout.WriteRune(c)\n\t\t\tcontinue\n\t\t}\n\t\teSeq.InspectRune(c)\n\t\tif !eSeq.isIn && outLen > 0 && (outLen%n) == 0 && idx != sLen {\n\t\t\tout.WriteRune(runeToInsert)\n\t\t}\n\t\tout.WriteRune(c)\n\t\tif !eSeq.isIn {\n\t\t\toutLen += RuneWidth(c)\n\t\t}\n\t}\n\treturn out.String()\n}\n\n// LongestLineLen returns the length of the longest \"line\" within the\n// argument string. For ex.:\n//\n//\tLongestLineLen(\"Ghost!\\nCome back here!\\nRight now!\") == 15\nfunc LongestLineLen(str string) int {\n\tmaxLength, currLength, eSeq := 0, 0, escSeq{}\n\tfor _, c := range str {\n\t\tif eSeq.isIn {\n\t\t\teSeq.InspectRune(c)\n\t\t\tcontinue\n\t\t}\n\t\teSeq.InspectRune(c)\n\t\tif c == '\\n' {\n\t\t\tif currLength > maxLength {\n\t\t\t\tmaxLength = currLength\n\t\t\t}\n\t\t\tcurrLength = 0\n\t\t} else if !eSeq.isIn {\n\t\t\tcurrLength += RuneWidth(c)\n\t\t}\n\t}\n\tif currLength > maxLength {\n\t\tmaxLength = currLength\n\t}\n\treturn maxLength\n}\n\n// OverrideRuneWidthEastAsianWidth can *probably* help with alignment, and\n// length calculation issues when dealing with Unicode character-set and a\n// non-English language set in the LANG variable.\n//\n// Set this to 'false' to force the \"runewidth\" library to pretend to deal with\n// English character-set. Be warned that if the text/content you are dealing\n// with contains East Asian character-set, this may result in unexpected\n// behavior.\n//\n// References:\n// * https://github.com/mattn/go-runewidth/issues/64#issuecomment-1221642154\n// * https://github.com/jedib0t/go-pretty/issues/220\n// * https://github.com/jedib0t/go-pretty/issues/204\nfunc OverrideRuneWidthEastAsianWidth(val bool) {\n\trwCondition.EastAsianWidth = val\n}\n\n// Pad pads the given string with as many characters as needed to make it as\n// long as specified (maxLen). This function does not count escape sequences\n// while calculating length of the string. Ex.:\n//\n//\tPad(\"Ghost\", 0, ' ') == \"Ghost\"\n//\tPad(\"Ghost\", 3, ' ') == \"Ghost\"\n//\tPad(\"Ghost\", 5, ' ') == \"Ghost\"\n//\tPad(\"Ghost\", 7, ' ') == \"Ghost  \"\n//\tPad(\"Ghost\", 10, '.') == \"Ghost.....\"\nfunc Pad(str string, maxLen int, paddingChar rune) string {\n\tstrLen := RuneWidthWithoutEscSequences(str)\n\tif strLen < maxLen {\n\t\tstr += strings.Repeat(string(paddingChar), maxLen-strLen)\n\t}\n\treturn str\n}\n\n// RepeatAndTrim repeats the given string until it is as long as maxRunes.\n// For ex.:\n//\n//\tRepeatAndTrim(\"\", 5) == \"\"\n//\tRepeatAndTrim(\"Ghost\", 0) == \"\"\n//\tRepeatAndTrim(\"Ghost\", 5) == \"Ghost\"\n//\tRepeatAndTrim(\"Ghost\", 7) == \"GhostGh\"\n//\tRepeatAndTrim(\"Ghost\", 10) == \"GhostGhost\"\nfunc RepeatAndTrim(str string, maxRunes int) string {\n\tif str == \"\" || maxRunes == 0 {\n\t\treturn \"\"\n\t} else if maxRunes == utf8.RuneCountInString(str) {\n\t\treturn str\n\t}\n\trepeatedS := strings.Repeat(str, int(maxRunes/utf8.RuneCountInString(str))+1)\n\treturn Trim(repeatedS, maxRunes)\n}\n\n// RuneCount is similar to utf8.RuneCountInString, except for the fact that it\n// ignores escape sequences while counting. For ex.:\n//\n//\tRuneCount(\"\") == 0\n//\tRuneCount(\"Ghost\") == 5\n//\tRuneCount(\"\\x1b[33mGhost\\x1b[0m\") == 5\n//\tRuneCount(\"\\x1b[33mGhost\\x1b[0\") == 5\n//\n// Deprecated: in favor of RuneWidthWithoutEscSequences\nfunc RuneCount(str string) int {\n\treturn RuneWidthWithoutEscSequences(str)\n}\n\n// RuneWidth returns the mostly accurate character-width of the rune. This is\n// not 100% accurate as the character width is usually dependent on the\n// typeface (font) used in the console/terminal. For ex.:\n//\n//\tRuneWidth('A') == 1\n//\tRuneWidth('ツ') == 2\n//\tRuneWidth('⊙') == 1\n//\tRuneWidth('︿') == 2\n//\tRuneWidth(0x27) == 0\nfunc RuneWidth(r rune) int {\n\treturn rwCondition.RuneWidth(r)\n}\n\n// RuneWidthWithoutEscSequences is similar to RuneWidth, except for the fact\n// that it ignores escape sequences while counting. For ex.:\n//\n//\tRuneWidthWithoutEscSequences(\"\") == 0\n//\tRuneWidthWithoutEscSequences(\"Ghost\") == 5\n//\tRuneWidthWithoutEscSequences(\"\\x1b[33mGhost\\x1b[0m\") == 5\n//\tRuneWidthWithoutEscSequences(\"\\x1b[33mGhost\\x1b[0\") == 5\nfunc RuneWidthWithoutEscSequences(str string) int {\n\tcount, eSeq := 0, escSeq{}\n\tfor _, c := range str {\n\t\tif eSeq.isIn {\n\t\t\teSeq.InspectRune(c)\n\t\t\tcontinue\n\t\t}\n\t\teSeq.InspectRune(c)\n\t\tif !eSeq.isIn {\n\t\t\tcount += RuneWidth(c)\n\t\t}\n\t}\n\treturn count\n}\n\n// Snip returns the given string with a fixed length. For ex.:\n//\n//\tSnip(\"Ghost\", 0, \"~\") == \"Ghost\"\n//\tSnip(\"Ghost\", 1, \"~\") == \"~\"\n//\tSnip(\"Ghost\", 3, \"~\") == \"Gh~\"\n//\tSnip(\"Ghost\", 5, \"~\") == \"Ghost\"\n//\tSnip(\"Ghost\", 7, \"~\") == \"Ghost  \"\n//\tSnip(\"\\x1b[33mGhost\\x1b[0m\", 7, \"~\") == \"\\x1b[33mGhost\\x1b[0m  \"\nfunc Snip(str string, length int, snipIndicator string) string {\n\tif length > 0 {\n\t\tlenStr := RuneWidthWithoutEscSequences(str)\n\t\tif lenStr > length {\n\t\t\tlenStrFinal := length - RuneWidthWithoutEscSequences(snipIndicator)\n\t\t\treturn Trim(str, lenStrFinal) + snipIndicator\n\t\t}\n\t}\n\treturn str\n}\n\n// Trim trims a string to the given length while ignoring escape sequences. For\n// ex.:\n//\n//\tTrim(\"Ghost\", 3) == \"Gho\"\n//\tTrim(\"Ghost\", 6) == \"Ghost\"\n//\tTrim(\"\\x1b[33mGhost\\x1b[0m\", 3) == \"\\x1b[33mGho\\x1b[0m\"\n//\tTrim(\"\\x1b[33mGhost\\x1b[0m\", 6) == \"\\x1b[33mGhost\\x1b[0m\"\nfunc Trim(str string, maxLen int) string {\n\tif maxLen <= 0 {\n\t\treturn \"\"\n\t}\n\n\tvar out strings.Builder\n\tout.Grow(maxLen)\n\n\toutLen, eSeq := 0, escSeq{}\n\tfor _, sChr := range str {\n\t\tif eSeq.isIn {\n\t\t\teSeq.InspectRune(sChr)\n\t\t\tout.WriteRune(sChr)\n\t\t\tcontinue\n\t\t}\n\t\teSeq.InspectRune(sChr)\n\t\tif eSeq.isIn {\n\t\t\tout.WriteRune(sChr)\n\t\t\tcontinue\n\t\t}\n\t\tif outLen < maxLen {\n\t\t\toutLen++\n\t\t\tout.WriteRune(sChr)\n\t\t\tcontinue\n\t\t}\n\t}\n\treturn out.String()\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/transformer.go",
    "content": "package text\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Transformer related constants\nconst (\n\tunixTimeMinMilliseconds = int64(10000000000)\n\tunixTimeMinMicroseconds = unixTimeMinMilliseconds * 1000\n\tunixTimeMinNanoSeconds  = unixTimeMinMicroseconds * 1000\n)\n\n// Transformer related variables\nvar (\n\tcolorsNumberPositive = Colors{FgHiGreen}\n\tcolorsNumberNegative = Colors{FgHiRed}\n\tcolorsNumberZero     = Colors{}\n\tcolorsURL            = Colors{Underline, FgBlue}\n\trfc3339Milli         = \"2006-01-02T15:04:05.000Z07:00\"\n\trfc3339Micro         = \"2006-01-02T15:04:05.000000Z07:00\"\n\n\tpossibleTimeLayouts = []string{\n\t\ttime.RFC3339,\n\t\trfc3339Milli, // strfmt.DateTime.String()'s default layout\n\t\trfc3339Micro,\n\t\ttime.RFC3339Nano,\n\t}\n)\n\n// Transformer helps format the contents of an object to the user's liking.\ntype Transformer func(val interface{}) string\n\n// NewNumberTransformer returns a number Transformer that:\n//   - transforms the number as directed by 'format' (ex.: %.2f)\n//   - colors negative values Red\n//   - colors positive values Green\nfunc NewNumberTransformer(format string) Transformer {\n\treturn func(val interface{}) string {\n\t\tif valStr := transformInt(format, val); valStr != \"\" {\n\t\t\treturn valStr\n\t\t}\n\t\tif valStr := transformUint(format, val); valStr != \"\" {\n\t\t\treturn valStr\n\t\t}\n\t\tif valStr := transformFloat(format, val); valStr != \"\" {\n\t\t\treturn valStr\n\t\t}\n\t\treturn fmt.Sprint(val)\n\t}\n}\n\nfunc transformInt(format string, val interface{}) string {\n\ttransform := func(val int64) string {\n\t\tif val < 0 {\n\t\t\treturn colorsNumberNegative.Sprintf(\"-\"+format, -val)\n\t\t}\n\t\tif val > 0 {\n\t\t\treturn colorsNumberPositive.Sprintf(format, val)\n\t\t}\n\t\treturn colorsNumberZero.Sprintf(format, val)\n\t}\n\n\tif number, ok := val.(int); ok {\n\t\treturn transform(int64(number))\n\t}\n\tif number, ok := val.(int8); ok {\n\t\treturn transform(int64(number))\n\t}\n\tif number, ok := val.(int16); ok {\n\t\treturn transform(int64(number))\n\t}\n\tif number, ok := val.(int32); ok {\n\t\treturn transform(int64(number))\n\t}\n\tif number, ok := val.(int64); ok {\n\t\treturn transform(number)\n\t}\n\treturn \"\"\n}\n\nfunc transformUint(format string, val interface{}) string {\n\ttransform := func(val uint64) string {\n\t\tif val > 0 {\n\t\t\treturn colorsNumberPositive.Sprintf(format, val)\n\t\t}\n\t\treturn colorsNumberZero.Sprintf(format, val)\n\t}\n\n\tif number, ok := val.(uint); ok {\n\t\treturn transform(uint64(number))\n\t}\n\tif number, ok := val.(uint8); ok {\n\t\treturn transform(uint64(number))\n\t}\n\tif number, ok := val.(uint16); ok {\n\t\treturn transform(uint64(number))\n\t}\n\tif number, ok := val.(uint32); ok {\n\t\treturn transform(uint64(number))\n\t}\n\tif number, ok := val.(uint64); ok {\n\t\treturn transform(number)\n\t}\n\treturn \"\"\n}\n\nfunc transformFloat(format string, val interface{}) string {\n\ttransform := func(val float64) string {\n\t\tif val < 0 {\n\t\t\treturn colorsNumberNegative.Sprintf(\"-\"+format, -val)\n\t\t}\n\t\tif val > 0 {\n\t\t\treturn colorsNumberPositive.Sprintf(format, val)\n\t\t}\n\t\treturn colorsNumberZero.Sprintf(format, val)\n\t}\n\n\tif number, ok := val.(float32); ok {\n\t\treturn transform(float64(number))\n\t}\n\tif number, ok := val.(float64); ok {\n\t\treturn transform(number)\n\t}\n\treturn \"\"\n}\n\n// NewJSONTransformer returns a Transformer that can format a JSON string or an\n// object into pretty-indented JSON-strings.\nfunc NewJSONTransformer(prefix string, indent string) Transformer {\n\treturn func(val interface{}) string {\n\t\tif valStr, ok := val.(string); ok {\n\t\t\tvar b bytes.Buffer\n\t\t\tif err := json.Indent(&b, []byte(strings.TrimSpace(valStr)), prefix, indent); err == nil {\n\t\t\t\treturn b.String()\n\t\t\t}\n\t\t} else if b, err := json.MarshalIndent(val, prefix, indent); err == nil {\n\t\t\treturn string(b)\n\t\t}\n\t\treturn fmt.Sprintf(\"%#v\", val)\n\t}\n}\n\n// NewTimeTransformer returns a Transformer that can format a timestamp (a\n// time.Time) into a well-defined time format defined using the provided layout\n// (ex.: time.RFC3339).\n//\n// If a non-nil location value is provided, the time will be localized to that\n// location (use time.Local to get localized timestamps).\nfunc NewTimeTransformer(layout string, location *time.Location) Transformer {\n\treturn func(val interface{}) string {\n\t\trsp := fmt.Sprint(val)\n\t\tif valTime, ok := val.(time.Time); ok {\n\t\t\trsp = formatTime(valTime, layout, location)\n\t\t} else {\n\t\t\t// cycle through some supported layouts to see if the string form\n\t\t\t// of the object matches any of these layouts\n\t\t\tfor _, possibleTimeLayout := range possibleTimeLayouts {\n\t\t\t\tif valTime, err := time.Parse(possibleTimeLayout, rsp); err == nil {\n\t\t\t\t\trsp = formatTime(valTime, layout, location)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn rsp\n\t}\n}\n\n// NewUnixTimeTransformer returns a Transformer that can format a unix-timestamp\n// into a well-defined time format as defined by 'layout'. This can handle\n// unix-time in Seconds, MilliSeconds, Microseconds and Nanoseconds.\n//\n// If a non-nil location value is provided, the time will be localized to that\n// location (use time.Local to get localized timestamps).\nfunc NewUnixTimeTransformer(layout string, location *time.Location) Transformer {\n\ttransformer := NewTimeTransformer(layout, location)\n\n\treturn func(val interface{}) string {\n\t\tif unixTime, ok := val.(int64); ok {\n\t\t\treturn formatTimeUnix(unixTime, transformer)\n\t\t} else if unixTimeStr, ok := val.(string); ok {\n\t\t\tif unixTime, err := strconv.ParseInt(unixTimeStr, 10, 64); err == nil {\n\t\t\t\treturn formatTimeUnix(unixTime, transformer)\n\t\t\t}\n\t\t}\n\t\treturn fmt.Sprint(val)\n\t}\n}\n\n// NewURLTransformer returns a Transformer that can format and pretty print a string\n// that contains a URL (the text is underlined and colored Blue).\nfunc NewURLTransformer(colors ...Color) Transformer {\n\tcolorsToUse := colorsURL\n\tif len(colors) > 0 {\n\t\tcolorsToUse = colors\n\t}\n\n\treturn func(val interface{}) string {\n\t\treturn colorsToUse.Sprint(val)\n\t}\n}\n\nfunc formatTime(t time.Time, layout string, location *time.Location) string {\n\trsp := \"\"\n\tif t.Unix() > 0 {\n\t\tif location != nil {\n\t\t\tt = t.In(location)\n\t\t}\n\t\trsp = t.Format(layout)\n\t}\n\treturn rsp\n}\n\nfunc formatTimeUnix(unixTime int64, timeTransformer Transformer) string {\n\tif unixTime >= unixTimeMinNanoSeconds {\n\t\tunixTime = unixTime / time.Second.Nanoseconds()\n\t} else if unixTime >= unixTimeMinMicroseconds {\n\t\tunixTime = unixTime / (time.Second.Nanoseconds() / 1000)\n\t} else if unixTime >= unixTimeMinMilliseconds {\n\t\tunixTime = unixTime / (time.Second.Nanoseconds() / 1000000)\n\t}\n\treturn timeTransformer(time.Unix(unixTime, 0))\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/valign.go",
    "content": "package text\n\nimport \"strings\"\n\n// VAlign denotes how text is to be aligned vertically.\ntype VAlign int\n\n// VAlign enumerations\nconst (\n\tVAlignDefault VAlign = iota // same as VAlignTop\n\tVAlignTop                   // \"top\\n\\n\"\n\tVAlignMiddle                // \"\\nmiddle\\n\"\n\tVAlignBottom                // \"\\n\\nbottom\"\n)\n\n// Apply aligns the lines vertically. For ex.:\n//   - VAlignTop.Apply({\"Game\", \"Of\", \"Thrones\"},    5)\n//     returns {\"Game\", \"Of\", \"Thrones\", \"\", \"\"}\n//   - VAlignMiddle.Apply({\"Game\", \"Of\", \"Thrones\"}, 5)\n//     returns {\"\", \"Game\", \"Of\", \"Thrones\", \"\"}\n//   - VAlignBottom.Apply({\"Game\", \"Of\", \"Thrones\"}, 5)\n//     returns {\"\", \"\", \"Game\", \"Of\", \"Thrones\"}\nfunc (va VAlign) Apply(lines []string, maxLines int) []string {\n\tif len(lines) == maxLines {\n\t\treturn lines\n\t} else if len(lines) > maxLines {\n\t\tmaxLines = len(lines)\n\t}\n\n\tinsertIdx := 0\n\tif va == VAlignMiddle {\n\t\tinsertIdx = int(maxLines-len(lines)) / 2\n\t} else if va == VAlignBottom {\n\t\tinsertIdx = maxLines - len(lines)\n\t}\n\n\tlinesOut := strings.Split(strings.Repeat(\"\\n\", maxLines-1), \"\\n\")\n\tfor idx, line := range lines {\n\t\tlinesOut[idx+insertIdx] = line\n\t}\n\treturn linesOut\n}\n\n// ApplyStr aligns the string (of 1 or more lines) vertically. For ex.:\n//   - VAlignTop.ApplyStr(\"Game\\nOf\\nThrones\",    5)\n//     returns {\"Game\", \"Of\", \"Thrones\", \"\", \"\"}\n//   - VAlignMiddle.ApplyStr(\"Game\\nOf\\nThrones\", 5)\n//     returns {\"\", \"Game\", \"Of\", \"Thrones\", \"\"}\n//   - VAlignBottom.ApplyStr(\"Game\\nOf\\nThrones\", 5)\n//     returns {\"\", \"\", \"Game\", \"Of\", \"Thrones\"}\nfunc (va VAlign) ApplyStr(text string, maxLines int) []string {\n\treturn va.Apply(strings.Split(text, \"\\n\"), maxLines)\n}\n\n// HTMLProperty returns the equivalent HTML vertical-align tag property.\nfunc (va VAlign) HTMLProperty() string {\n\tswitch va {\n\tcase VAlignTop:\n\t\treturn \"valign=\\\"top\\\"\"\n\tcase VAlignMiddle:\n\t\treturn \"valign=\\\"middle\\\"\"\n\tcase VAlignBottom:\n\t\treturn \"valign=\\\"bottom\\\"\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/jedib0t/go-pretty/v6/text/wrap.go",
    "content": "package text\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// WrapHard wraps a string to the given length using a newline. Handles strings\n// with ANSI escape sequences (such as text color) without breaking the text\n// formatting. Breaks all words that go beyond the line boundary.\n//\n// For examples, refer to the unit-tests or GoDoc examples.\nfunc WrapHard(str string, wrapLen int) string {\n\tif wrapLen <= 0 {\n\t\treturn \"\"\n\t}\n\tstr = strings.Replace(str, \"\\t\", \"    \", -1)\n\tsLen := utf8.RuneCountInString(str)\n\tif sLen <= wrapLen {\n\t\treturn str\n\t}\n\n\tout := &strings.Builder{}\n\tout.Grow(sLen + (sLen / wrapLen))\n\tfor idx, paragraph := range strings.Split(str, \"\\n\\n\") {\n\t\tif idx > 0 {\n\t\t\tout.WriteString(\"\\n\\n\")\n\t\t}\n\t\twrapHard(paragraph, wrapLen, out)\n\t}\n\n\treturn out.String()\n}\n\n// WrapSoft wraps a string to the given length using a newline. Handles strings\n// with ANSI escape sequences (such as text color) without breaking the text\n// formatting. Tries to move words that go beyond the line boundary to the next\n// line.\n//\n// For examples, refer to the unit-tests or GoDoc examples.\nfunc WrapSoft(str string, wrapLen int) string {\n\tif wrapLen <= 0 {\n\t\treturn \"\"\n\t}\n\tstr = strings.Replace(str, \"\\t\", \"    \", -1)\n\tsLen := utf8.RuneCountInString(str)\n\tif sLen <= wrapLen {\n\t\treturn str\n\t}\n\n\tout := &strings.Builder{}\n\tout.Grow(sLen + (sLen / wrapLen))\n\tfor idx, paragraph := range strings.Split(str, \"\\n\\n\") {\n\t\tif idx > 0 {\n\t\t\tout.WriteString(\"\\n\\n\")\n\t\t}\n\t\twrapSoft(paragraph, wrapLen, out)\n\t}\n\n\treturn out.String()\n}\n\n// WrapText is very similar to WrapHard except for one minor difference. Unlike\n// WrapHard which discards line-breaks and respects only paragraph-breaks, this\n// function respects line-breaks too.\n//\n// For examples, refer to the unit-tests or GoDoc examples.\nfunc WrapText(str string, wrapLen int) string {\n\tif wrapLen <= 0 {\n\t\treturn \"\"\n\t}\n\n\tvar out strings.Builder\n\tsLen := utf8.RuneCountInString(str)\n\tout.Grow(sLen + (sLen / wrapLen))\n\tlineIdx, isEscSeq, lastEscSeq := 0, false, \"\"\n\tfor _, char := range str {\n\t\tif char == EscapeStartRune {\n\t\t\tisEscSeq = true\n\t\t\tlastEscSeq = \"\"\n\t\t}\n\t\tif isEscSeq {\n\t\t\tlastEscSeq += string(char)\n\t\t}\n\n\t\tappendChar(char, wrapLen, &lineIdx, isEscSeq, lastEscSeq, &out)\n\n\t\tif isEscSeq && char == EscapeStopRune {\n\t\t\tisEscSeq = false\n\t\t}\n\t\tif lastEscSeq == EscapeReset {\n\t\t\tlastEscSeq = \"\"\n\t\t}\n\t}\n\tif lastEscSeq != \"\" && lastEscSeq != EscapeReset {\n\t\tout.WriteString(EscapeReset)\n\t}\n\treturn out.String()\n}\n\nfunc appendChar(char rune, wrapLen int, lineLen *int, inEscSeq bool, lastSeenEscSeq string, out *strings.Builder) {\n\t// handle reaching the end of the line as dictated by wrapLen or by finding\n\t// a newline character\n\tif (*lineLen == wrapLen && !inEscSeq && char != '\\n') || (char == '\\n') {\n\t\tif lastSeenEscSeq != \"\" {\n\t\t\t// terminate escape sequence and the line; and restart the escape\n\t\t\t// sequence in the next line\n\t\t\tout.WriteString(EscapeReset)\n\t\t\tout.WriteRune('\\n')\n\t\t\tout.WriteString(lastSeenEscSeq)\n\t\t} else {\n\t\t\t// just start a new line\n\t\t\tout.WriteRune('\\n')\n\t\t}\n\t\t// reset line index to 0th character\n\t\t*lineLen = 0\n\t}\n\n\t// if the rune is not a new line, output it\n\tif char != '\\n' {\n\t\tout.WriteRune(char)\n\n\t\t// increment the line index if not in the middle of an escape sequence\n\t\tif !inEscSeq {\n\t\t\t*lineLen++\n\t\t}\n\t}\n}\n\nfunc appendWord(word string, lineIdx *int, lastSeenEscSeq string, wrapLen int, out *strings.Builder) {\n\tinEscSeq := false\n\tfor _, char := range word {\n\t\tif char == EscapeStartRune {\n\t\t\tinEscSeq = true\n\t\t\tlastSeenEscSeq = \"\"\n\t\t}\n\t\tif inEscSeq {\n\t\t\tlastSeenEscSeq += string(char)\n\t\t}\n\n\t\tappendChar(char, wrapLen, lineIdx, inEscSeq, lastSeenEscSeq, out)\n\n\t\tif inEscSeq && char == EscapeStopRune {\n\t\t\tinEscSeq = false\n\t\t}\n\t\tif lastSeenEscSeq == EscapeReset {\n\t\t\tlastSeenEscSeq = \"\"\n\t\t}\n\t}\n}\n\nfunc extractOpenEscapeSeq(str string) string {\n\tescapeSeq, inEscSeq := \"\", false\n\tfor _, char := range str {\n\t\tif char == EscapeStartRune {\n\t\t\tinEscSeq = true\n\t\t\tescapeSeq = \"\"\n\t\t}\n\t\tif inEscSeq {\n\t\t\tescapeSeq += string(char)\n\t\t}\n\t\tif char == EscapeStopRune {\n\t\t\tinEscSeq = false\n\t\t}\n\t}\n\tif escapeSeq == EscapeReset {\n\t\tescapeSeq = \"\"\n\t}\n\treturn escapeSeq\n}\n\nfunc terminateLine(wrapLen int, lineLen *int, lastSeenEscSeq string, out *strings.Builder) {\n\tif *lineLen < wrapLen {\n\t\tout.WriteString(strings.Repeat(\" \", wrapLen-*lineLen))\n\t}\n\t// something is already on the line; terminate it\n\tif lastSeenEscSeq != \"\" {\n\t\tout.WriteString(EscapeReset)\n\t}\n\tout.WriteRune('\\n')\n\tout.WriteString(lastSeenEscSeq)\n\t*lineLen = 0\n}\n\nfunc terminateOutput(lastSeenEscSeq string, out *strings.Builder) {\n\tif lastSeenEscSeq != \"\" && lastSeenEscSeq != EscapeReset && !strings.HasSuffix(out.String(), EscapeReset) {\n\t\tout.WriteString(EscapeReset)\n\t}\n}\n\nfunc wrapHard(paragraph string, wrapLen int, out *strings.Builder) {\n\tlineLen, lastSeenEscSeq := 0, \"\"\n\twords := strings.Fields(paragraph)\n\tfor wordIdx, word := range words {\n\t\tescSeq := extractOpenEscapeSeq(word)\n\t\tif escSeq != \"\" {\n\t\t\tlastSeenEscSeq = escSeq\n\t\t}\n\t\tif lineLen > 0 {\n\t\t\tout.WriteRune(' ')\n\t\t\tlineLen++\n\t\t}\n\n\t\twordLen := RuneWidthWithoutEscSequences(word)\n\t\tif lineLen+wordLen <= wrapLen { // word fits within the line\n\t\t\tout.WriteString(word)\n\t\t\tlineLen += wordLen\n\t\t} else { // word doesn't fit within the line; hard-wrap\n\t\t\tappendWord(word, &lineLen, lastSeenEscSeq, wrapLen, out)\n\t\t}\n\n\t\t// end of line; but more words incoming\n\t\tif lineLen == wrapLen && wordIdx < len(words)-1 {\n\t\t\tterminateLine(wrapLen, &lineLen, lastSeenEscSeq, out)\n\t\t}\n\t}\n\tterminateOutput(lastSeenEscSeq, out)\n}\n\nfunc wrapSoft(paragraph string, wrapLen int, out *strings.Builder) {\n\tlineLen, lastSeenEscSeq := 0, \"\"\n\twords := strings.Fields(paragraph)\n\tfor wordIdx, word := range words {\n\t\tescSeq := extractOpenEscapeSeq(word)\n\t\tif escSeq != \"\" {\n\t\t\tlastSeenEscSeq = escSeq\n\t\t}\n\n\t\tspacing, spacingLen := wrapSoftSpacing(lineLen)\n\t\twordLen := RuneWidthWithoutEscSequences(word)\n\t\tif lineLen+spacingLen+wordLen <= wrapLen { // word fits within the line\n\t\t\tout.WriteString(spacing)\n\t\t\tout.WriteString(word)\n\t\t\tlineLen += spacingLen + wordLen\n\t\t} else { // word doesn't fit within the line\n\t\t\tlineLen = wrapSoftLastWordInLine(wrapLen, lineLen, lastSeenEscSeq, wordLen, word, out)\n\t\t}\n\n\t\t// end of line; but more words incoming\n\t\tif lineLen == wrapLen && wordIdx < len(words)-1 {\n\t\t\tterminateLine(wrapLen, &lineLen, lastSeenEscSeq, out)\n\t\t}\n\t}\n\tterminateOutput(lastSeenEscSeq, out)\n}\n\nfunc wrapSoftLastWordInLine(wrapLen int, lineLen int, lastSeenEscSeq string, wordLen int, word string, out *strings.Builder) int {\n\tif lineLen > 0 { // something is already on the line; terminate it\n\t\tterminateLine(wrapLen, &lineLen, lastSeenEscSeq, out)\n\t}\n\tif wordLen <= wrapLen { // word fits within a single line\n\t\tout.WriteString(word)\n\t\tlineLen = wordLen\n\t} else { // word doesn't fit within a single line; hard-wrap\n\t\tappendWord(word, &lineLen, lastSeenEscSeq, wrapLen, out)\n\t}\n\treturn lineLen\n}\n\nfunc wrapSoftSpacing(lineLen int) (string, int) {\n\tspacing, spacingLen := \"\", 0\n\tif lineLen > 0 {\n\t\tspacing, spacingLen = \" \", 1\n\t}\n\treturn spacing, spacingLen\n}\n"
  },
  {
    "path": "vendor/github.com/josharian/intern/README.md",
    "content": "Docs: https://godoc.org/github.com/josharian/intern\n\nSee also [Go issue 5160](https://golang.org/issue/5160).\n\nLicense: MIT\n"
  },
  {
    "path": "vendor/github.com/josharian/intern/intern.go",
    "content": "// Package intern interns strings.\n// Interning is best effort only.\n// Interned strings may be removed automatically\n// at any time without notification.\n// All functions may be called concurrently\n// with themselves and each other.\npackage intern\n\nimport \"sync\"\n\nvar (\n\tpool sync.Pool = sync.Pool{\n\t\tNew: func() interface{} {\n\t\t\treturn make(map[string]string)\n\t\t},\n\t}\n)\n\n// String returns s, interned.\nfunc String(s string) string {\n\tm := pool.Get().(map[string]string)\n\tc, ok := m[s]\n\tif ok {\n\t\tpool.Put(m)\n\t\treturn c\n\t}\n\tm[s] = s\n\tpool.Put(m)\n\treturn s\n}\n\n// Bytes returns b converted to a string, interned.\nfunc Bytes(b []byte) string {\n\tm := pool.Get().(map[string]string)\n\tc, ok := m[string(b)]\n\tif ok {\n\t\tpool.Put(m)\n\t\treturn c\n\t}\n\ts := string(b)\n\tm[s] = s\n\tpool.Put(m)\n\treturn s\n}\n"
  },
  {
    "path": "vendor/github.com/josharian/intern/license.md",
    "content": "MIT License\n\nCopyright (c) 2019 Josh Bleecher Snyder\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": "vendor/github.com/kennygrant/sanitize/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n"
  },
  {
    "path": "vendor/github.com/kennygrant/sanitize/.travis.yml",
    "content": "language: go\n"
  },
  {
    "path": "vendor/github.com/kennygrant/sanitize/LICENSE",
    "content": "Copyright (c) 2017 Mechanism Design. 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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."
  },
  {
    "path": "vendor/github.com/kennygrant/sanitize/README.md",
    "content": "sanitize [![GoDoc](https://godoc.org/github.com/kennygrant/sanitize?status.svg)](https://godoc.org/github.com/kennygrant/sanitize) [![Go Report Card](https://goreportcard.com/badge/github.com/kennygrant/sanitize)](https://goreportcard.com/report/github.com/kennygrant/sanitize) [![CircleCI](https://circleci.com/gh/kennygrant/sanitize.svg?style=svg)](https://circleci.com/gh/kennygrant/sanitize)\n========\n\nPackage sanitize provides functions to sanitize html and paths with go (golang).\n\nFUNCTIONS\n\n\n```go\nsanitize.Accents(s string) string\n```\n\nAccents replaces a set of accented characters with ascii equivalents.\n\n```go\nsanitize.BaseName(s string) string\n```\n\nBaseName makes a string safe to use in a file name, producing a sanitized basename replacing . or / with -. Unlike Name no attempt is made to normalise text as a path.\n\n```go\nsanitize.HTML(s string) string\n```\n\nHTML strips html tags with a very simple parser, replace common entities, and escape < and > in the result. The result is intended to be used as plain text. \n\n```go\nsanitize.HTMLAllowing(s string, args...[]string) (string, error)\n```\n\nHTMLAllowing parses html and allow certain tags and attributes from the lists optionally specified by args - args[0] is a list of allowed tags, args[1] is a list of allowed attributes. If either is missing default sets are used. \n\n```go\nsanitize.Name(s string) string\n```\n\nName makes a string safe to use in a file name by first finding the path basename, then replacing non-ascii characters.\n\n```go\nsanitize.Path(s string) string\n```\n\nPath makes a string safe to use as an url path.\n\n\nChanges\n-------\n\nVersion 1.2\n\nAdjusted HTML function to avoid linter warning\nAdded more tests from https://githubengineering.com/githubs-post-csp-journey/\nChnaged name of license file\nAdded badges and change log to readme\n\nVersion 1.1\nFixed type in comments. \nMerge pull request from Povilas Balzaravicius Pawka \n - replace br tags with newline even when they contain a space\n\nVersion 1.0\nFirst release"
  },
  {
    "path": "vendor/github.com/kennygrant/sanitize/sanitize.go",
    "content": "// Package sanitize provides functions for sanitizing text.\npackage sanitize\n\nimport (\n\t\"bytes\"\n\t\"html\"\n\t\"html/template\"\n\t\"io\"\n\t\"path\"\n\t\"regexp\"\n\t\"strings\"\n\n\tparser \"golang.org/x/net/html\"\n)\n\nvar (\n\tignoreTags = []string{\"title\", \"script\", \"style\", \"iframe\", \"frame\", \"frameset\", \"noframes\", \"noembed\", \"embed\", \"applet\", \"object\", \"base\"}\n\n\tdefaultTags = []string{\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"div\", \"span\", \"hr\", \"p\", \"br\", \"b\", \"i\", \"strong\", \"em\", \"ol\", \"ul\", \"li\", \"a\", \"img\", \"pre\", \"code\", \"blockquote\", \"article\", \"section\"}\n\n\tdefaultAttributes = []string{\"id\", \"class\", \"src\", \"href\", \"title\", \"alt\", \"name\", \"rel\"}\n)\n\n// HTMLAllowing sanitizes html, allowing some tags.\n// Arrays of allowed tags and allowed attributes may optionally be passed as the second and third arguments.\nfunc HTMLAllowing(s string, args ...[]string) (string, error) {\n\n\tallowedTags := defaultTags\n\tif len(args) > 0 {\n\t\tallowedTags = args[0]\n\t}\n\tallowedAttributes := defaultAttributes\n\tif len(args) > 1 {\n\t\tallowedAttributes = args[1]\n\t}\n\n\t// Parse the html\n\ttokenizer := parser.NewTokenizer(strings.NewReader(s))\n\n\tbuffer := bytes.NewBufferString(\"\")\n\tignore := \"\"\n\n\tfor {\n\t\ttokenType := tokenizer.Next()\n\t\ttoken := tokenizer.Token()\n\n\t\tswitch tokenType {\n\n\t\tcase parser.ErrorToken:\n\t\t\terr := tokenizer.Err()\n\t\t\tif err == io.EOF {\n\t\t\t\treturn buffer.String(), nil\n\t\t\t}\n\t\t\treturn \"\", err\n\n\t\tcase parser.StartTagToken:\n\n\t\t\tif len(ignore) == 0 && includes(allowedTags, token.Data) {\n\t\t\t\ttoken.Attr = cleanAttributes(token.Attr, allowedAttributes)\n\t\t\t\tbuffer.WriteString(token.String())\n\t\t\t} else if includes(ignoreTags, token.Data) {\n\t\t\t\tignore = token.Data\n\t\t\t}\n\n\t\tcase parser.SelfClosingTagToken:\n\n\t\t\tif len(ignore) == 0 && includes(allowedTags, token.Data) {\n\t\t\t\ttoken.Attr = cleanAttributes(token.Attr, allowedAttributes)\n\t\t\t\tbuffer.WriteString(token.String())\n\t\t\t} else if token.Data == ignore {\n\t\t\t\tignore = \"\"\n\t\t\t}\n\n\t\tcase parser.EndTagToken:\n\t\t\tif len(ignore) == 0 && includes(allowedTags, token.Data) {\n\t\t\t\ttoken.Attr = []parser.Attribute{}\n\t\t\t\tbuffer.WriteString(token.String())\n\t\t\t} else if token.Data == ignore {\n\t\t\t\tignore = \"\"\n\t\t\t}\n\n\t\tcase parser.TextToken:\n\t\t\t// We allow text content through, unless ignoring this entire tag and its contents (including other tags)\n\t\t\tif ignore == \"\" {\n\t\t\t\tbuffer.WriteString(token.String())\n\t\t\t}\n\t\tcase parser.CommentToken:\n\t\t\t// We ignore comments by default\n\t\tcase parser.DoctypeToken:\n\t\t\t// We ignore doctypes by default - html5 does not require them and this is intended for sanitizing snippets of text\n\t\tdefault:\n\t\t\t// We ignore unknown token types by default\n\n\t\t}\n\n\t}\n\n}\n\n// HTML strips html tags, replace common entities, and escapes <>&;'\" in the result.\n// Note the returned text may contain entities as it is escaped by HTMLEscapeString, and most entities are not translated.\nfunc HTML(s string) (output string) {\n\n\t// Shortcut strings with no tags in them\n\tif !strings.ContainsAny(s, \"<>\") {\n\t\toutput = s\n\t} else {\n\n\t\t// First remove line breaks etc as these have no meaning outside html tags (except pre)\n\t\t// this means pre sections will lose formatting... but will result in less unintentional paras.\n\t\ts = strings.Replace(s, \"\\n\", \"\", -1)\n\n\t\t// Then replace line breaks with newlines, to preserve that formatting\n\t\ts = strings.Replace(s, \"</p>\", \"\\n\", -1)\n\t\ts = strings.Replace(s, \"<br>\", \"\\n\", -1)\n\t\ts = strings.Replace(s, \"</br>\", \"\\n\", -1)\n\t\ts = strings.Replace(s, \"<br/>\", \"\\n\", -1)\n\t\ts = strings.Replace(s, \"<br />\", \"\\n\", -1)\n\n\t\t// Walk through the string removing all tags\n\t\tb := bytes.NewBufferString(\"\")\n\t\tinTag := false\n\t\tfor _, r := range s {\n\t\t\tswitch r {\n\t\t\tcase '<':\n\t\t\t\tinTag = true\n\t\t\tcase '>':\n\t\t\t\tinTag = false\n\t\t\tdefault:\n\t\t\t\tif !inTag {\n\t\t\t\t\tb.WriteRune(r)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\toutput = b.String()\n\t}\n\n\t// Remove a few common harmless entities, to arrive at something more like plain text\n\toutput = strings.Replace(output, \"&#8216;\", \"'\", -1)\n\toutput = strings.Replace(output, \"&#8217;\", \"'\", -1)\n\toutput = strings.Replace(output, \"&#8220;\", \"\\\"\", -1)\n\toutput = strings.Replace(output, \"&#8221;\", \"\\\"\", -1)\n\toutput = strings.Replace(output, \"&nbsp;\", \" \", -1)\n\toutput = strings.Replace(output, \"&quot;\", \"\\\"\", -1)\n\toutput = strings.Replace(output, \"&apos;\", \"'\", -1)\n\n\t// Translate some entities into their plain text equivalent (for example accents, if encoded as entities)\n\toutput = html.UnescapeString(output)\n\n\t// In case we have missed any tags above, escape the text - removes <, >, &, ' and \".\n\toutput = template.HTMLEscapeString(output)\n\n\t// After processing, remove some harmless entities &, ' and \" which are encoded by HTMLEscapeString\n\toutput = strings.Replace(output, \"&#34;\", \"\\\"\", -1)\n\toutput = strings.Replace(output, \"&#39;\", \"'\", -1)\n\toutput = strings.Replace(output, \"&amp; \", \"& \", -1)     // NB space after\n\toutput = strings.Replace(output, \"&amp;amp; \", \"& \", -1) // NB space after\n\n\treturn output\n}\n\n// We are very restrictive as this is intended for ascii url slugs\nvar illegalPath = regexp.MustCompile(`[^[:alnum:]\\~\\-\\./]`)\n\n// Path makes a string safe to use as a URL path,\n// removing accents and replacing separators with -.\n// The path may still start at / and is not intended\n// for use as a file system path without prefix.\nfunc Path(s string) string {\n\t// Start with lowercase string\n\tfilePath := strings.ToLower(s)\n\tfilePath = strings.Replace(filePath, \"..\", \"\", -1)\n\tfilePath = path.Clean(filePath)\n\n\t// Remove illegal characters for paths, flattening accents\n\t// and replacing some common separators with -\n\tfilePath = cleanString(filePath, illegalPath)\n\n\t// NB this may be of length 0, caller must check\n\treturn filePath\n}\n\n// Remove all other unrecognised characters apart from\nvar illegalName = regexp.MustCompile(`[^[:alnum:]-.]`)\n\n// Name makes a string safe to use in a file name by first finding the path basename, then replacing non-ascii characters.\nfunc Name(s string) string {\n\t// Start with lowercase string\n\tfileName := strings.ToLower(s)\n\tfileName = path.Clean(path.Base(fileName))\n\n\t// Remove illegal characters for names, replacing some common separators with -\n\tfileName = cleanString(fileName, illegalName)\n\n\t// NB this may be of length 0, caller must check\n\treturn fileName\n}\n\n// Replace these separators with -\nvar baseNameSeparators = regexp.MustCompile(`[./]`)\n\n// BaseName makes a string safe to use in a file name, producing a sanitized basename replacing . or / with -.\n// No attempt is made to normalise a path or normalise case.\nfunc BaseName(s string) string {\n\n\t// Replace certain joining characters with a dash\n\tbaseName := baseNameSeparators.ReplaceAllString(s, \"-\")\n\n\t// Remove illegal characters for names, replacing some common separators with -\n\tbaseName = cleanString(baseName, illegalName)\n\n\t// NB this may be of length 0, caller must check\n\treturn baseName\n}\n\n// A very limited list of transliterations to catch common european names translated to urls.\n// This set could be expanded with at least caps and many more characters.\nvar transliterations = map[rune]string{\n\t'À': \"A\",\n\t'Á': \"A\",\n\t'Â': \"A\",\n\t'Ã': \"A\",\n\t'Ä': \"A\",\n\t'Å': \"AA\",\n\t'Æ': \"AE\",\n\t'Ç': \"C\",\n\t'È': \"E\",\n\t'É': \"E\",\n\t'Ê': \"E\",\n\t'Ë': \"E\",\n\t'Ì': \"I\",\n\t'Í': \"I\",\n\t'Î': \"I\",\n\t'Ï': \"I\",\n\t'Ð': \"D\",\n\t'Ł': \"L\",\n\t'Ñ': \"N\",\n\t'Ò': \"O\",\n\t'Ó': \"O\",\n\t'Ô': \"O\",\n\t'Õ': \"O\",\n\t'Ö': \"OE\",\n\t'Ø': \"OE\",\n\t'Œ': \"OE\",\n\t'Ù': \"U\",\n\t'Ú': \"U\",\n\t'Ü': \"UE\",\n\t'Û': \"U\",\n\t'Ý': \"Y\",\n\t'Þ': \"TH\",\n\t'ẞ': \"SS\",\n\t'à': \"a\",\n\t'á': \"a\",\n\t'â': \"a\",\n\t'ã': \"a\",\n\t'ä': \"ae\",\n\t'å': \"aa\",\n\t'æ': \"ae\",\n\t'ç': \"c\",\n\t'è': \"e\",\n\t'é': \"e\",\n\t'ê': \"e\",\n\t'ë': \"e\",\n\t'ì': \"i\",\n\t'í': \"i\",\n\t'î': \"i\",\n\t'ï': \"i\",\n\t'ð': \"d\",\n\t'ł': \"l\",\n\t'ñ': \"n\",\n\t'ń': \"n\",\n\t'ò': \"o\",\n\t'ó': \"o\",\n\t'ô': \"o\",\n\t'õ': \"o\",\n\t'ō': \"o\",\n\t'ö': \"oe\",\n\t'ø': \"oe\",\n\t'œ': \"oe\",\n\t'ś': \"s\",\n\t'ù': \"u\",\n\t'ú': \"u\",\n\t'û': \"u\",\n\t'ū': \"u\",\n\t'ü': \"ue\",\n\t'ý': \"y\",\n\t'ÿ': \"y\",\n\t'ż': \"z\",\n\t'þ': \"th\",\n\t'ß': \"ss\",\n}\n\n// Accents replaces a set of accented characters with ascii equivalents.\nfunc Accents(s string) string {\n\t// Replace some common accent characters\n\tb := bytes.NewBufferString(\"\")\n\tfor _, c := range s {\n\t\t// Check transliterations first\n\t\tif val, ok := transliterations[c]; ok {\n\t\t\tb.WriteString(val)\n\t\t} else {\n\t\t\tb.WriteRune(c)\n\t\t}\n\t}\n\treturn b.String()\n}\n\nvar (\n\t// If the attribute contains data: or javascript: anywhere, ignore it\n\t// we don't allow this in attributes as it is so frequently used for xss\n\t// NB we allow spaces in the value, and lowercase.\n\tillegalAttr = regexp.MustCompile(`(d\\s*a\\s*t\\s*a|j\\s*a\\s*v\\s*a\\s*s\\s*c\\s*r\\s*i\\s*p\\s*t\\s*)\\s*:`)\n\n\t// We are far more restrictive with href attributes.\n\tlegalHrefAttr = regexp.MustCompile(`\\A[/#][^/\\\\]?|mailto:|http://|https://`)\n)\n\n// cleanAttributes returns an array of attributes after removing malicious ones.\nfunc cleanAttributes(a []parser.Attribute, allowed []string) []parser.Attribute {\n\tif len(a) == 0 {\n\t\treturn a\n\t}\n\n\tvar cleaned []parser.Attribute\n\tfor _, attr := range a {\n\t\tif includes(allowed, attr.Key) {\n\n\t\t\tval := strings.ToLower(attr.Val)\n\n\t\t\t// Check for illegal attribute values\n\t\t\tif illegalAttr.FindString(val) != \"\" {\n\t\t\t\tattr.Val = \"\"\n\t\t\t}\n\n\t\t\t// Check for legal href values - / mailto:// http:// or https://\n\t\t\tif attr.Key == \"href\" {\n\t\t\t\tif legalHrefAttr.FindString(val) == \"\" {\n\t\t\t\t\tattr.Val = \"\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we still have an attribute, append it to the array\n\t\t\tif attr.Val != \"\" {\n\t\t\t\tcleaned = append(cleaned, attr)\n\t\t\t}\n\t\t}\n\t}\n\treturn cleaned\n}\n\n// A list of characters we consider separators in normal strings and replace with our canonical separator - rather than removing.\nvar (\n\tseparators = regexp.MustCompile(`[ &_=+:]`)\n\n\tdashes = regexp.MustCompile(`[\\-]+`)\n)\n\n// cleanString replaces separators with - and removes characters listed in the regexp provided from string.\n// Accents, spaces, and all characters not in A-Za-z0-9 are replaced.\nfunc cleanString(s string, r *regexp.Regexp) string {\n\n\t// Remove any trailing space to avoid ending on -\n\ts = strings.Trim(s, \" \")\n\n\t// Flatten accents first so that if we remove non-ascii we still get a legible name\n\ts = Accents(s)\n\n\t// Replace certain joining characters with a dash\n\ts = separators.ReplaceAllString(s, \"-\")\n\n\t// Remove all other unrecognised characters - NB we do allow any printable characters\n\ts = r.ReplaceAllString(s, \"\")\n\n\t// Remove any multiple dashes caused by replacements above\n\ts = dashes.ReplaceAllString(s, \"-\")\n\n\treturn s\n}\n\n// includes checks for inclusion of a string in a []string.\nfunc includes(a []string, s string) bool {\n\tfor _, as := range a {\n\t\tif as == s {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/.gitattributes",
    "content": "* -text\n*.bin -text -diff\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n/s2/cmd/_s2sx/sfx-exe\n\n# Linux perf files\nperf.data\nperf.data.old\n\n# gdb history\n.gdb_history\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/.goreleaser.yml",
    "content": "# This is an example goreleaser.yaml file with some sane defaults.\n# Make sure to check the documentation at http://goreleaser.com\nbefore:\n  hooks:\n    - ./gen.sh\n    - go install mvdan.cc/garble@v0.10.1\n\nbuilds:\n  -\n    id: \"s2c\"\n    binary: s2c\n    main: ./s2/cmd/s2c/main.go\n    flags:\n      - -trimpath\n    env:\n      - CGO_ENABLED=0\n    goos:\n      - aix\n      - linux\n      - freebsd\n      - netbsd\n      - windows\n      - darwin\n    goarch:\n      - 386\n      - amd64\n      - arm\n      - arm64\n      - ppc64\n      - ppc64le\n      - mips64\n      - mips64le\n    goarm:\n      - 7\n    gobinary: garble\n  -\n    id: \"s2d\"\n    binary: s2d\n    main: ./s2/cmd/s2d/main.go\n    flags:\n      - -trimpath\n    env:\n      - CGO_ENABLED=0\n    goos:\n      - aix\n      - linux\n      - freebsd\n      - netbsd\n      - windows\n      - darwin\n    goarch:\n      - 386\n      - amd64\n      - arm\n      - arm64\n      - ppc64\n      - ppc64le\n      - mips64\n      - mips64le\n    goarm:\n      - 7\n    gobinary: garble\n  -\n    id: \"s2sx\"\n    binary: s2sx\n    main: ./s2/cmd/_s2sx/main.go\n    flags:\n      - -modfile=s2sx.mod\n      - -trimpath\n    env:\n      - CGO_ENABLED=0\n    goos:\n      - aix\n      - linux\n      - freebsd\n      - netbsd\n      - windows\n      - darwin\n    goarch:\n      - 386\n      - amd64\n      - arm\n      - arm64\n      - ppc64\n      - ppc64le\n      - mips64\n      - mips64le\n    goarm:\n      - 7\n    gobinary: garble\n\narchives:\n  -\n    id: s2-binaries\n    name_template: \"s2-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}\"\n    format_overrides:\n      - goos: windows\n        format: zip\n    files:\n      - unpack/*\n      - s2/LICENSE\n      - s2/README.md\nchecksum:\n  name_template: 'checksums.txt'\nsnapshot:\n  name_template: \"{{ .Tag }}-next\"\nchangelog:\n  sort: asc\n  filters:\n    exclude:\n    - '^doc:'\n    - '^docs:'\n    - '^test:'\n    - '^tests:'\n    - '^Update\\sREADME.md'\n\nnfpms:\n  -\n    file_name_template: \"s2_package__{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}\"\n    vendor: Klaus Post\n    homepage: https://github.com/klauspost/compress\n    maintainer: Klaus Post <klauspost@gmail.com>\n    description: S2 Compression Tool\n    license: BSD 3-Clause\n    formats:\n      - deb\n      - rpm\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/LICENSE",
    "content": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2019 Klaus Post. 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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\n------------------\n\nFiles: gzhttp/*\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2016-2017 The New York Times Company\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       http://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\n------------------\n\nFiles: s2/cmd/internal/readahead/*\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Klaus Post\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\n---------------------\nFiles: snappy/*\nFiles: internal/snapref/*\n\nCopyright (c) 2011 The Snappy-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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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\n-----------------\n\nFiles: s2/cmd/internal/filepathx/*\n\nCopyright 2016 The filepathx Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/README.md",
    "content": "# compress\r\n\r\nThis package provides various compression algorithms.\r\n\r\n* [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and decompression in pure Go.\r\n* [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) is a high performance replacement for Snappy.\r\n* Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib).\r\n* [snappy](https://github.com/klauspost/compress/tree/master/snappy) is a drop-in replacement for `github.com/golang/snappy` offering better compression and concurrent streams.\r\n* [huff0](https://github.com/klauspost/compress/tree/master/huff0) and [FSE](https://github.com/klauspost/compress/tree/master/fse) implementations for raw entropy encoding.\r\n* [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp) Provides client and server wrappers for handling gzipped requests efficiently.\r\n* [pgzip](https://github.com/klauspost/pgzip) is a separate package that provides a very fast parallel gzip implementation.\r\n\r\n[![Go Reference](https://pkg.go.dev/badge/klauspost/compress.svg)](https://pkg.go.dev/github.com/klauspost/compress?tab=subdirectories)\r\n[![Go](https://github.com/klauspost/compress/actions/workflows/go.yml/badge.svg)](https://github.com/klauspost/compress/actions/workflows/go.yml)\r\n[![Sourcegraph Badge](https://sourcegraph.com/github.com/klauspost/compress/-/badge.svg)](https://sourcegraph.com/github.com/klauspost/compress?badge)\r\n\r\n# changelog\r\n\r\n* Oct 22nd, 2023 - [v1.17.2](https://github.com/klauspost/compress/releases/tag/v1.17.2)\r\n\t* zstd: Fix rare *CORRUPTION* output in \"best\" mode. See https://github.com/klauspost/compress/pull/876\r\n\r\n* Oct 14th, 2023 - [v1.17.1](https://github.com/klauspost/compress/releases/tag/v1.17.1)\r\n\t* s2: Fix S2 \"best\" dictionary wrong encoding by @klauspost in https://github.com/klauspost/compress/pull/871\r\n\t* flate: Reduce allocations in decompressor and minor code improvements by @fakefloordiv in https://github.com/klauspost/compress/pull/869\r\n\t* s2: Fix EstimateBlockSize on 6&7 length input by @klauspost in https://github.com/klauspost/compress/pull/867\r\n\r\n* Sept 19th, 2023 - [v1.17.0](https://github.com/klauspost/compress/releases/tag/v1.17.0)\r\n\t* Add experimental dictionary builder  https://github.com/klauspost/compress/pull/853\r\n\t* Add xerial snappy read/writer https://github.com/klauspost/compress/pull/838\r\n\t* flate: Add limited window compression https://github.com/klauspost/compress/pull/843\r\n\t* s2: Do 2 overlapping match checks https://github.com/klauspost/compress/pull/839\r\n\t* flate: Add amd64 assembly matchlen https://github.com/klauspost/compress/pull/837\r\n\t* gzip: Copy bufio.Reader on Reset by @thatguystone in https://github.com/klauspost/compress/pull/860\r\n   \r\n* July 1st, 2023 - [v1.16.7](https://github.com/klauspost/compress/releases/tag/v1.16.7)\r\n\t* zstd: Fix default level first dictionary encode https://github.com/klauspost/compress/pull/829\r\n\t* s2: add GetBufferCapacity() method by @GiedriusS in https://github.com/klauspost/compress/pull/832\r\n\r\n* June 13, 2023 - [v1.16.6](https://github.com/klauspost/compress/releases/tag/v1.16.6)\r\n\t* zstd: correctly ignore WithEncoderPadding(1) by @ianlancetaylor in https://github.com/klauspost/compress/pull/806\r\n\t* zstd: Add amd64 match length assembly https://github.com/klauspost/compress/pull/824\r\n\t* gzhttp: Handle informational headers by @rtribotte in https://github.com/klauspost/compress/pull/815\r\n\t* s2: Improve Better compression slightly https://github.com/klauspost/compress/pull/663\r\n\r\n* Apr 16, 2023 - [v1.16.5](https://github.com/klauspost/compress/releases/tag/v1.16.5)\r\n\t* zstd: readByte needs to use io.ReadFull by @jnoxon in https://github.com/klauspost/compress/pull/802\r\n\t* gzip: Fix WriterTo after initial read https://github.com/klauspost/compress/pull/804\r\n\r\n* Apr 5, 2023 - [v1.16.4](https://github.com/klauspost/compress/releases/tag/v1.16.4)\r\n\t* zstd: Improve zstd best efficiency by @greatroar and @klauspost in https://github.com/klauspost/compress/pull/784\r\n\t* zstd: Respect WithAllLitEntropyCompression https://github.com/klauspost/compress/pull/792\r\n\t* zstd: Fix amd64 not always detecting corrupt data https://github.com/klauspost/compress/pull/785\r\n\t* zstd: Various minor improvements by @greatroar in https://github.com/klauspost/compress/pull/788 https://github.com/klauspost/compress/pull/794 https://github.com/klauspost/compress/pull/795\r\n\t* s2: Fix huge block overflow https://github.com/klauspost/compress/pull/779\r\n\t* s2: Allow CustomEncoder fallback https://github.com/klauspost/compress/pull/780\r\n\t* gzhttp: Suppport ResponseWriter Unwrap() in gzhttp handler by @jgimenez in https://github.com/klauspost/compress/pull/799\r\n\r\n* Mar 13, 2023 - [v1.16.1](https://github.com/klauspost/compress/releases/tag/v1.16.1)\r\n\t* zstd: Speed up + improve best encoder by @greatroar in https://github.com/klauspost/compress/pull/776\r\n\t* gzhttp: Add optional [BREACH mitigation](https://github.com/klauspost/compress/tree/master/gzhttp#breach-mitigation). https://github.com/klauspost/compress/pull/762 https://github.com/klauspost/compress/pull/768 https://github.com/klauspost/compress/pull/769 https://github.com/klauspost/compress/pull/770 https://github.com/klauspost/compress/pull/767\r\n\t* s2: Add Intel LZ4s converter https://github.com/klauspost/compress/pull/766\r\n\t* zstd: Minor bug fixes https://github.com/klauspost/compress/pull/771 https://github.com/klauspost/compress/pull/772 https://github.com/klauspost/compress/pull/773\r\n\t* huff0: Speed up compress1xDo by @greatroar in https://github.com/klauspost/compress/pull/774\r\n\r\n* Feb 26, 2023 - [v1.16.0](https://github.com/klauspost/compress/releases/tag/v1.16.0)\r\n\t* s2: Add [Dictionary](https://github.com/klauspost/compress/tree/master/s2#dictionaries) support.  https://github.com/klauspost/compress/pull/685\r\n\t* s2: Add Compression Size Estimate.  https://github.com/klauspost/compress/pull/752\r\n\t* s2: Add support for custom stream encoder. https://github.com/klauspost/compress/pull/755\r\n\t* s2: Add LZ4 block converter. https://github.com/klauspost/compress/pull/748\r\n\t* s2: Support io.ReaderAt in ReadSeeker. https://github.com/klauspost/compress/pull/747\r\n\t* s2c/s2sx: Use concurrent decoding. https://github.com/klauspost/compress/pull/746\r\n\r\n<details>\r\n\t<summary>See changes to v1.15.x</summary>\r\n\t\r\n* Jan 21st, 2023 (v1.15.15)\r\n\t* deflate: Improve level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/739\r\n\t* zstd: Add delta encoding support by @greatroar in https://github.com/klauspost/compress/pull/728\r\n\t* zstd: Various speed improvements by @greatroar https://github.com/klauspost/compress/pull/741 https://github.com/klauspost/compress/pull/734 https://github.com/klauspost/compress/pull/736 https://github.com/klauspost/compress/pull/744 https://github.com/klauspost/compress/pull/743 https://github.com/klauspost/compress/pull/745\r\n\t* gzhttp: Add SuffixETag() and DropETag() options to prevent ETag collisions on compressed responses by @willbicks in https://github.com/klauspost/compress/pull/740\r\n\r\n* Jan 3rd, 2023 (v1.15.14)\r\n\r\n\t* flate: Improve speed in big stateless blocks https://github.com/klauspost/compress/pull/718\r\n\t* zstd: Minor speed tweaks by @greatroar in https://github.com/klauspost/compress/pull/716 https://github.com/klauspost/compress/pull/720\r\n\t* export NoGzipResponseWriter for custom ResponseWriter wrappers by @harshavardhana in https://github.com/klauspost/compress/pull/722\r\n\t* s2: Add example for indexing and existing stream https://github.com/klauspost/compress/pull/723\r\n\r\n* Dec 11, 2022 (v1.15.13)\r\n\t* zstd: Add [MaxEncodedSize](https://pkg.go.dev/github.com/klauspost/compress@v1.15.13/zstd#Encoder.MaxEncodedSize) to encoder  https://github.com/klauspost/compress/pull/691\r\n\t* zstd: Various tweaks and improvements https://github.com/klauspost/compress/pull/693 https://github.com/klauspost/compress/pull/695 https://github.com/klauspost/compress/pull/696 https://github.com/klauspost/compress/pull/701 https://github.com/klauspost/compress/pull/702 https://github.com/klauspost/compress/pull/703 https://github.com/klauspost/compress/pull/704 https://github.com/klauspost/compress/pull/705 https://github.com/klauspost/compress/pull/706 https://github.com/klauspost/compress/pull/707 https://github.com/klauspost/compress/pull/708\r\n\r\n* Oct 26, 2022 (v1.15.12)\r\n\r\n\t* zstd: Tweak decoder allocs. https://github.com/klauspost/compress/pull/680\r\n\t* gzhttp: Always delete `HeaderNoCompression` https://github.com/klauspost/compress/pull/683\r\n\r\n* Sept 26, 2022 (v1.15.11)\r\n\r\n\t* flate: Improve level 1-3 compression  https://github.com/klauspost/compress/pull/678\r\n\t* zstd: Improve \"best\" compression by @nightwolfz in https://github.com/klauspost/compress/pull/677\r\n\t* zstd: Fix+reduce decompression allocations https://github.com/klauspost/compress/pull/668\r\n\t* zstd: Fix non-effective noescape tag https://github.com/klauspost/compress/pull/667\r\n\r\n* Sept 16, 2022 (v1.15.10)\r\n\r\n\t* zstd: Add [WithDecodeAllCapLimit](https://pkg.go.dev/github.com/klauspost/compress@v1.15.10/zstd#WithDecodeAllCapLimit) https://github.com/klauspost/compress/pull/649\r\n\t* Add Go 1.19 - deprecate Go 1.16  https://github.com/klauspost/compress/pull/651\r\n\t* flate: Improve level 5+6 compression https://github.com/klauspost/compress/pull/656\r\n\t* zstd: Improve \"better\" compresssion  https://github.com/klauspost/compress/pull/657\r\n\t* s2: Improve \"best\" compression https://github.com/klauspost/compress/pull/658\r\n\t* s2: Improve \"better\" compression. https://github.com/klauspost/compress/pull/635\r\n\t* s2: Slightly faster non-assembly decompression https://github.com/klauspost/compress/pull/646\r\n\t* Use arrays for constant size copies https://github.com/klauspost/compress/pull/659\r\n\r\n* July 21, 2022 (v1.15.9)\r\n\r\n\t* zstd: Fix decoder crash on amd64 (no BMI) on invalid input https://github.com/klauspost/compress/pull/645\r\n\t* zstd: Disable decoder extended memory copies (amd64) due to possible crashes https://github.com/klauspost/compress/pull/644\r\n\t* zstd: Allow single segments up to \"max decoded size\" by @klauspost in https://github.com/klauspost/compress/pull/643\r\n\r\n* July 13, 2022 (v1.15.8)\r\n\r\n\t* gzip: fix stack exhaustion bug in Reader.Read https://github.com/klauspost/compress/pull/641\r\n\t* s2: Add Index header trim/restore https://github.com/klauspost/compress/pull/638\r\n\t* zstd: Optimize seqdeq amd64 asm by @greatroar in https://github.com/klauspost/compress/pull/636\r\n\t* zstd: Improve decoder memcopy https://github.com/klauspost/compress/pull/637\r\n\t* huff0: Pass a single bitReader pointer to asm by @greatroar in https://github.com/klauspost/compress/pull/634\r\n\t* zstd: Branchless getBits for amd64 w/o BMI2 by @greatroar in https://github.com/klauspost/compress/pull/640\r\n\t* gzhttp: Remove header before writing https://github.com/klauspost/compress/pull/639\r\n\r\n* June 29, 2022 (v1.15.7)\r\n\r\n\t* s2: Fix absolute forward seeks  https://github.com/klauspost/compress/pull/633\r\n\t* zip: Merge upstream  https://github.com/klauspost/compress/pull/631\r\n\t* zip: Re-add zip64 fix https://github.com/klauspost/compress/pull/624\r\n\t* zstd: translate fseDecoder.buildDtable into asm by @WojciechMula in https://github.com/klauspost/compress/pull/598\r\n\t* flate: Faster histograms  https://github.com/klauspost/compress/pull/620\r\n\t* deflate: Use compound hcode  https://github.com/klauspost/compress/pull/622\r\n\r\n* June 3, 2022 (v1.15.6)\r\n\t* s2: Improve coding for long, close matches https://github.com/klauspost/compress/pull/613\r\n\t* s2c: Add Snappy/S2 stream recompression https://github.com/klauspost/compress/pull/611\r\n\t* zstd: Always use configured block size https://github.com/klauspost/compress/pull/605\r\n\t* zstd: Fix incorrect hash table placement for dict encoding in default https://github.com/klauspost/compress/pull/606\r\n\t* zstd: Apply default config to ZipDecompressor without options https://github.com/klauspost/compress/pull/608\r\n\t* gzhttp: Exclude more common archive formats https://github.com/klauspost/compress/pull/612\r\n\t* s2: Add ReaderIgnoreCRC https://github.com/klauspost/compress/pull/609\r\n\t* s2: Remove sanity load on index creation https://github.com/klauspost/compress/pull/607\r\n\t* snappy: Use dedicated function for scoring https://github.com/klauspost/compress/pull/614\r\n\t* s2c+s2d: Use official snappy framed extension https://github.com/klauspost/compress/pull/610\r\n\r\n* May 25, 2022 (v1.15.5)\r\n\t* s2: Add concurrent stream decompression https://github.com/klauspost/compress/pull/602\r\n\t* s2: Fix final emit oob read crash on amd64 https://github.com/klauspost/compress/pull/601\r\n\t* huff0: asm implementation of Decompress1X by @WojciechMula https://github.com/klauspost/compress/pull/596\r\n\t* zstd: Use 1 less goroutine for stream decoding https://github.com/klauspost/compress/pull/588\r\n\t* zstd: Copy literal in 16 byte blocks when possible https://github.com/klauspost/compress/pull/592\r\n\t* zstd: Speed up when WithDecoderLowmem(false) https://github.com/klauspost/compress/pull/599\r\n\t* zstd: faster next state update in BMI2 version of decode by @WojciechMula in https://github.com/klauspost/compress/pull/593\r\n\t* huff0: Do not check max size when reading table. https://github.com/klauspost/compress/pull/586\r\n\t* flate: Inplace hashing for level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/590\r\n\r\n\r\n* May 11, 2022 (v1.15.4)\r\n\t* huff0: decompress directly into output by @WojciechMula in [#577](https://github.com/klauspost/compress/pull/577)\r\n\t* inflate: Keep dict on stack [#581](https://github.com/klauspost/compress/pull/581)\r\n\t* zstd: Faster decoding memcopy in asm [#583](https://github.com/klauspost/compress/pull/583)\r\n\t* zstd: Fix ignored crc [#580](https://github.com/klauspost/compress/pull/580)\r\n\r\n* May 5, 2022 (v1.15.3)\r\n\t* zstd: Allow to ignore checksum checking by @WojciechMula [#572](https://github.com/klauspost/compress/pull/572)\r\n\t* s2: Fix incorrect seek for io.SeekEnd in [#575](https://github.com/klauspost/compress/pull/575)\r\n\r\n* Apr 26, 2022 (v1.15.2)\r\n\t* zstd: Add x86-64 assembly for decompression on streams and blocks. Contributed by [@WojciechMula](https://github.com/WojciechMula). Typically 2x faster.  [#528](https://github.com/klauspost/compress/pull/528) [#531](https://github.com/klauspost/compress/pull/531) [#545](https://github.com/klauspost/compress/pull/545) [#537](https://github.com/klauspost/compress/pull/537)\r\n\t* zstd: Add options to ZipDecompressor and fixes [#539](https://github.com/klauspost/compress/pull/539)\r\n\t* s2: Use sorted search for index [#555](https://github.com/klauspost/compress/pull/555)\r\n\t* Minimum version is Go 1.16, added CI test on 1.18.\r\n\r\n* Mar 11, 2022 (v1.15.1)\r\n\t* huff0: Add x86 assembly of Decode4X by @WojciechMula in [#512](https://github.com/klauspost/compress/pull/512)\r\n\t* zstd: Reuse zip decoders in [#514](https://github.com/klauspost/compress/pull/514)\r\n\t* zstd: Detect extra block data and report as corrupted in [#520](https://github.com/klauspost/compress/pull/520)\r\n\t* zstd: Handle zero sized frame content size stricter in [#521](https://github.com/klauspost/compress/pull/521)\r\n\t* zstd: Add stricter block size checks in [#523](https://github.com/klauspost/compress/pull/523)\r\n\r\n* Mar 3, 2022 (v1.15.0)\r\n\t* zstd: Refactor decoder by @klauspost in [#498](https://github.com/klauspost/compress/pull/498)\r\n\t* zstd: Add stream encoding without goroutines by @klauspost in [#505](https://github.com/klauspost/compress/pull/505)\r\n\t* huff0: Prevent single blocks exceeding 16 bits by @klauspost in[#507](https://github.com/klauspost/compress/pull/507)\r\n\t* flate: Inline literal emission by @klauspost in [#509](https://github.com/klauspost/compress/pull/509)\r\n\t* gzhttp: Add zstd to transport by @klauspost in [#400](https://github.com/klauspost/compress/pull/400)\r\n\t* gzhttp: Make content-type optional by @klauspost in [#510](https://github.com/klauspost/compress/pull/510)\r\n\r\nBoth compression and decompression now supports \"synchronous\" stream operations. This means that whenever \"concurrency\" is set to 1, they will operate without spawning goroutines.\r\n\r\nStream decompression is now faster on asynchronous, since the goroutine allocation much more effectively splits the workload. On typical streams this will typically use 2 cores fully for decompression. When a stream has finished decoding no goroutines will be left over, so decoders can now safely be pooled and still be garbage collected.\r\n\r\nWhile the release has been extensively tested, it is recommended to testing when upgrading.\r\n\r\n</details>\r\n\r\n<details>\r\n\t<summary>See changes to v1.14.x</summary>\r\n\t\r\n* Feb 22, 2022 (v1.14.4)\r\n\t* flate: Fix rare huffman only (-2) corruption. [#503](https://github.com/klauspost/compress/pull/503)\r\n\t* zip: Update deprecated CreateHeaderRaw to correctly call CreateRaw by @saracen in [#502](https://github.com/klauspost/compress/pull/502)\r\n\t* zip: don't read data descriptor early by @saracen in [#501](https://github.com/klauspost/compress/pull/501)  #501\r\n\t* huff0: Use static decompression buffer up to 30% faster by @klauspost in [#499](https://github.com/klauspost/compress/pull/499) [#500](https://github.com/klauspost/compress/pull/500)\r\n\r\n* Feb 17, 2022 (v1.14.3)\r\n\t* flate: Improve fastest levels compression speed ~10% more throughput. [#482](https://github.com/klauspost/compress/pull/482) [#489](https://github.com/klauspost/compress/pull/489) [#490](https://github.com/klauspost/compress/pull/490) [#491](https://github.com/klauspost/compress/pull/491) [#494](https://github.com/klauspost/compress/pull/494)  [#478](https://github.com/klauspost/compress/pull/478)\r\n\t* flate: Faster decompression speed, ~5-10%. [#483](https://github.com/klauspost/compress/pull/483)\r\n\t* s2: Faster compression with Go v1.18 and amd64 microarch level 3+. [#484](https://github.com/klauspost/compress/pull/484) [#486](https://github.com/klauspost/compress/pull/486)\r\n\r\n* Jan 25, 2022 (v1.14.2)\r\n\t* zstd: improve header decoder by @dsnet  [#476](https://github.com/klauspost/compress/pull/476)\r\n\t* zstd: Add bigger default blocks  [#469](https://github.com/klauspost/compress/pull/469)\r\n\t* zstd: Remove unused decompression buffer [#470](https://github.com/klauspost/compress/pull/470)\r\n\t* zstd: Fix logically dead code by @ningmingxiao [#472](https://github.com/klauspost/compress/pull/472)\r\n\t* flate: Improve level 7-9 [#471](https://github.com/klauspost/compress/pull/471) [#473](https://github.com/klauspost/compress/pull/473)\r\n\t* zstd: Add noasm tag for xxhash [#475](https://github.com/klauspost/compress/pull/475)\r\n\r\n* Jan 11, 2022 (v1.14.1)\r\n\t* s2: Add stream index in [#462](https://github.com/klauspost/compress/pull/462)\r\n\t* flate: Speed and efficiency improvements in [#439](https://github.com/klauspost/compress/pull/439) [#461](https://github.com/klauspost/compress/pull/461) [#455](https://github.com/klauspost/compress/pull/455) [#452](https://github.com/klauspost/compress/pull/452) [#458](https://github.com/klauspost/compress/pull/458)\r\n\t* zstd: Performance improvement in [#420]( https://github.com/klauspost/compress/pull/420) [#456](https://github.com/klauspost/compress/pull/456) [#437](https://github.com/klauspost/compress/pull/437) [#467](https://github.com/klauspost/compress/pull/467) [#468](https://github.com/klauspost/compress/pull/468)\r\n\t* zstd: add arm64 xxhash assembly in [#464](https://github.com/klauspost/compress/pull/464)\r\n\t* Add garbled for binaries for s2 in [#445](https://github.com/klauspost/compress/pull/445)\r\n</details>\r\n\r\n<details>\r\n\t<summary>See changes to v1.13.x</summary>\r\n\t\r\n* Aug 30, 2021 (v1.13.5)\r\n\t* gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425)\r\n\t* s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413)\r\n\t* zstd: pooledZipWriter should return Writers to the same pool [#426](https://github.com/klauspost/compress/pull/426)\r\n\t* Removed golang/snappy as external dependency for tests [#421](https://github.com/klauspost/compress/pull/421)\r\n\r\n* Aug 12, 2021 (v1.13.4)\r\n\t* Add [snappy replacement package](https://github.com/klauspost/compress/tree/master/snappy).\r\n\t* zstd: Fix incorrect encoding in \"best\" mode [#415](https://github.com/klauspost/compress/pull/415)\r\n\r\n* Aug 3, 2021 (v1.13.3) \r\n\t* zstd: Improve Best compression [#404](https://github.com/klauspost/compress/pull/404)\r\n\t* zstd: Fix WriteTo error forwarding [#411](https://github.com/klauspost/compress/pull/411)\r\n\t* gzhttp: Return http.HandlerFunc instead of http.Handler. Unlikely breaking change. [#406](https://github.com/klauspost/compress/pull/406)\r\n\t* s2sx: Fix max size error [#399](https://github.com/klauspost/compress/pull/399)\r\n\t* zstd: Add optional stream content size on reset [#401](https://github.com/klauspost/compress/pull/401)\r\n\t* zstd: use SpeedBestCompression for level >= 10 [#410](https://github.com/klauspost/compress/pull/410)\r\n\r\n* Jun 14, 2021 (v1.13.1)\r\n\t* s2: Add full Snappy output support  [#396](https://github.com/klauspost/compress/pull/396)\r\n\t* zstd: Add configurable [Decoder window](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithDecoderMaxWindow) size [#394](https://github.com/klauspost/compress/pull/394)\r\n\t* gzhttp: Add header to skip compression  [#389](https://github.com/klauspost/compress/pull/389)\r\n\t* s2: Improve speed with bigger output margin  [#395](https://github.com/klauspost/compress/pull/395)\r\n\r\n* Jun 3, 2021 (v1.13.0)\r\n\t* Added [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp#gzip-handler) which allows wrapping HTTP servers and clients with GZIP compressors.\r\n\t* zstd: Detect short invalid signatures [#382](https://github.com/klauspost/compress/pull/382)\r\n\t* zstd: Spawn decoder goroutine only if needed. [#380](https://github.com/klauspost/compress/pull/380)\r\n</details>\r\n\r\n\r\n<details>\r\n\t<summary>See changes to v1.12.x</summary>\r\n\t\r\n* May 25, 2021 (v1.12.3)\r\n\t* deflate: Better/faster Huffman encoding [#374](https://github.com/klauspost/compress/pull/374)\r\n\t* deflate: Allocate less for history. [#375](https://github.com/klauspost/compress/pull/375)\r\n\t* zstd: Forward read errors [#373](https://github.com/klauspost/compress/pull/373) \r\n\r\n* Apr 27, 2021 (v1.12.2)\r\n\t* zstd: Improve better/best compression [#360](https://github.com/klauspost/compress/pull/360) [#364](https://github.com/klauspost/compress/pull/364) [#365](https://github.com/klauspost/compress/pull/365)\r\n\t* zstd: Add helpers to compress/decompress zstd inside zip files [#363](https://github.com/klauspost/compress/pull/363)\r\n\t* deflate: Improve level 5+6 compression [#367](https://github.com/klauspost/compress/pull/367)\r\n\t* s2: Improve better/best compression [#358](https://github.com/klauspost/compress/pull/358) [#359](https://github.com/klauspost/compress/pull/358)\r\n\t* s2: Load after checking src limit on amd64. [#362](https://github.com/klauspost/compress/pull/362)\r\n\t* s2sx: Limit max executable size [#368](https://github.com/klauspost/compress/pull/368) \r\n\r\n* Apr 14, 2021 (v1.12.1)\r\n\t* snappy package removed. Upstream added as dependency.\r\n\t* s2: Better compression in \"best\" mode [#353](https://github.com/klauspost/compress/pull/353)\r\n\t* s2sx: Add stdin input and detect pre-compressed from signature [#352](https://github.com/klauspost/compress/pull/352)\r\n\t* s2c/s2d: Add http as possible input [#348](https://github.com/klauspost/compress/pull/348)\r\n\t* s2c/s2d/s2sx: Always truncate when writing files [#352](https://github.com/klauspost/compress/pull/352)\r\n\t* zstd: Reduce memory usage further when using [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) [#346](https://github.com/klauspost/compress/pull/346)\r\n\t* s2: Fix potential problem with amd64 assembly and profilers [#349](https://github.com/klauspost/compress/pull/349)\r\n</details>\r\n\r\n<details>\r\n\t<summary>See changes to v1.11.x</summary>\r\n\t\r\n* Mar 26, 2021 (v1.11.13)\r\n\t* zstd: Big speedup on small dictionary encodes [#344](https://github.com/klauspost/compress/pull/344) [#345](https://github.com/klauspost/compress/pull/345)\r\n\t* zstd: Add [WithLowerEncoderMem](https://pkg.go.dev/github.com/klauspost/compress/zstd#WithLowerEncoderMem) encoder option [#336](https://github.com/klauspost/compress/pull/336)\r\n\t* deflate: Improve entropy compression [#338](https://github.com/klauspost/compress/pull/338)\r\n\t* s2: Clean up and minor performance improvement in best [#341](https://github.com/klauspost/compress/pull/341)\r\n\r\n* Mar 5, 2021 (v1.11.12)\r\n\t* s2: Add `s2sx` binary that creates [self extracting archives](https://github.com/klauspost/compress/tree/master/s2#s2sx-self-extracting-archives).\r\n\t* s2: Speed up decompression on non-assembly platforms [#328](https://github.com/klauspost/compress/pull/328)\r\n\r\n* Mar 1, 2021 (v1.11.9)\r\n\t* s2: Add ARM64 decompression assembly. Around 2x output speed. [#324](https://github.com/klauspost/compress/pull/324)\r\n\t* s2: Improve \"better\" speed and efficiency. [#325](https://github.com/klauspost/compress/pull/325)\r\n\t* s2: Fix binaries.\r\n\r\n* Feb 25, 2021 (v1.11.8)\r\n\t* s2: Fixed occational out-of-bounds write on amd64. Upgrade recommended.\r\n\t* s2: Add AMD64 assembly for better mode. 25-50% faster. [#315](https://github.com/klauspost/compress/pull/315)\r\n\t* s2: Less upfront decoder allocation. [#322](https://github.com/klauspost/compress/pull/322)\r\n\t* zstd: Faster \"compression\" of incompressible data. [#314](https://github.com/klauspost/compress/pull/314)\r\n\t* zip: Fix zip64 headers. [#313](https://github.com/klauspost/compress/pull/313)\r\n  \r\n* Jan 14, 2021 (v1.11.7)\r\n\t* Use Bytes() interface to get bytes across packages. [#309](https://github.com/klauspost/compress/pull/309)\r\n\t* s2: Add 'best' compression option.  [#310](https://github.com/klauspost/compress/pull/310)\r\n\t* s2: Add ReaderMaxBlockSize, changes `s2.NewReader` signature to include varargs. [#311](https://github.com/klauspost/compress/pull/311)\r\n\t* s2: Fix crash on small better buffers. [#308](https://github.com/klauspost/compress/pull/308)\r\n\t* s2: Clean up decoder. [#312](https://github.com/klauspost/compress/pull/312)\r\n\r\n* Jan 7, 2021 (v1.11.6)\r\n\t* zstd: Make decoder allocations smaller [#306](https://github.com/klauspost/compress/pull/306)\r\n\t* zstd: Free Decoder resources when Reset is called with a nil io.Reader  [#305](https://github.com/klauspost/compress/pull/305)\r\n\r\n* Dec 20, 2020 (v1.11.4)\r\n\t* zstd: Add Best compression mode [#304](https://github.com/klauspost/compress/pull/304)\r\n\t* Add header decoder [#299](https://github.com/klauspost/compress/pull/299)\r\n\t* s2: Add uncompressed stream option [#297](https://github.com/klauspost/compress/pull/297)\r\n\t* Simplify/speed up small blocks with known max size. [#300](https://github.com/klauspost/compress/pull/300)\r\n\t* zstd: Always reset literal dict encoder [#303](https://github.com/klauspost/compress/pull/303)\r\n\r\n* Nov 15, 2020 (v1.11.3)\r\n\t* inflate: 10-15% faster decompression  [#293](https://github.com/klauspost/compress/pull/293)\r\n\t* zstd: Tweak DecodeAll default allocation [#295](https://github.com/klauspost/compress/pull/295)\r\n\r\n* Oct 11, 2020 (v1.11.2)\r\n\t* s2: Fix out of bounds read in \"better\" block compression [#291](https://github.com/klauspost/compress/pull/291)\r\n\r\n* Oct 1, 2020 (v1.11.1)\r\n\t* zstd: Set allLitEntropy true in default configuration [#286](https://github.com/klauspost/compress/pull/286)\r\n\r\n* Sept 8, 2020 (v1.11.0)\r\n\t* zstd: Add experimental compression [dictionaries](https://github.com/klauspost/compress/tree/master/zstd#dictionaries) [#281](https://github.com/klauspost/compress/pull/281)\r\n\t* zstd: Fix mixed Write and ReadFrom calls [#282](https://github.com/klauspost/compress/pull/282)\r\n\t* inflate/gz: Limit variable shifts, ~5% faster decompression [#274](https://github.com/klauspost/compress/pull/274)\r\n</details>\r\n\r\n<details>\r\n\t<summary>See changes to v1.10.x</summary>\r\n \r\n* July 8, 2020 (v1.10.11) \r\n\t* zstd: Fix extra block when compressing with ReadFrom. [#278](https://github.com/klauspost/compress/pull/278)\r\n\t* huff0: Also populate compression table when reading decoding table. [#275](https://github.com/klauspost/compress/pull/275)\r\n\t\r\n* June 23, 2020 (v1.10.10) \r\n\t* zstd: Skip entropy compression in fastest mode when no matches. [#270](https://github.com/klauspost/compress/pull/270)\r\n\t\r\n* June 16, 2020 (v1.10.9): \r\n\t* zstd: API change for specifying dictionaries. See [#268](https://github.com/klauspost/compress/pull/268)\r\n\t* zip: update CreateHeaderRaw to handle zip64 fields. [#266](https://github.com/klauspost/compress/pull/266)\r\n\t* Fuzzit tests removed. The service has been purchased and is no longer available.\r\n\t\r\n* June 5, 2020 (v1.10.8): \r\n\t* 1.15x faster zstd block decompression. [#265](https://github.com/klauspost/compress/pull/265)\r\n\t\r\n* June 1, 2020 (v1.10.7): \r\n\t* Added zstd decompression [dictionary support](https://github.com/klauspost/compress/tree/master/zstd#dictionaries)\r\n\t* Increase zstd decompression speed up to 1.19x.  [#259](https://github.com/klauspost/compress/pull/259)\r\n\t* Remove internal reset call in zstd compression and reduce allocations. [#263](https://github.com/klauspost/compress/pull/263)\r\n\t\r\n* May 21, 2020: (v1.10.6) \r\n\t* zstd: Reduce allocations while decoding. [#258](https://github.com/klauspost/compress/pull/258), [#252](https://github.com/klauspost/compress/pull/252)\r\n\t* zstd: Stricter decompression checks.\r\n\t\r\n* April 12, 2020: (v1.10.5)\r\n\t* s2-commands: Flush output when receiving SIGINT. [#239](https://github.com/klauspost/compress/pull/239)\r\n\t\r\n* Apr 8, 2020: (v1.10.4) \r\n\t* zstd: Minor/special case optimizations. [#251](https://github.com/klauspost/compress/pull/251),  [#250](https://github.com/klauspost/compress/pull/250),  [#249](https://github.com/klauspost/compress/pull/249),  [#247](https://github.com/klauspost/compress/pull/247)\r\n* Mar 11, 2020: (v1.10.3) \r\n\t* s2: Use S2 encoder in pure Go mode for Snappy output as well. [#245](https://github.com/klauspost/compress/pull/245)\r\n\t* s2: Fix pure Go block encoder. [#244](https://github.com/klauspost/compress/pull/244)\r\n\t* zstd: Added \"better compression\" mode. [#240](https://github.com/klauspost/compress/pull/240)\r\n\t* zstd: Improve speed of fastest compression mode by 5-10% [#241](https://github.com/klauspost/compress/pull/241)\r\n\t* zstd: Skip creating encoders when not needed. [#238](https://github.com/klauspost/compress/pull/238)\r\n\t\r\n* Feb 27, 2020: (v1.10.2) \r\n\t* Close to 50% speedup in inflate (gzip/zip decompression). [#236](https://github.com/klauspost/compress/pull/236) [#234](https://github.com/klauspost/compress/pull/234) [#232](https://github.com/klauspost/compress/pull/232)\r\n\t* Reduce deflate level 1-6 memory usage up to 59%. [#227](https://github.com/klauspost/compress/pull/227)\r\n\t\r\n* Feb 18, 2020: (v1.10.1)\r\n\t* Fix zstd crash when resetting multiple times without sending data. [#226](https://github.com/klauspost/compress/pull/226)\r\n\t* deflate: Fix dictionary use on level 1-6. [#224](https://github.com/klauspost/compress/pull/224)\r\n\t* Remove deflate writer reference when closing. [#224](https://github.com/klauspost/compress/pull/224)\r\n\t\r\n* Feb 4, 2020: (v1.10.0) \r\n\t* Add optional dictionary to [stateless deflate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc#StatelessDeflate). Breaking change, send `nil` for previous behaviour. [#216](https://github.com/klauspost/compress/pull/216)\r\n\t* Fix buffer overflow on repeated small block deflate.  [#218](https://github.com/klauspost/compress/pull/218)\r\n\t* Allow copying content from an existing ZIP file without decompressing+compressing. [#214](https://github.com/klauspost/compress/pull/214)\r\n\t* Added [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) AMD64 assembler and various optimizations. Stream speed >10GB/s.  [#186](https://github.com/klauspost/compress/pull/186)\r\n\r\n</details>\r\n\r\n<details>\r\n\t<summary>See changes prior to v1.10.0</summary>\r\n\r\n* Jan 20,2020 (v1.9.8) Optimize gzip/deflate with better size estimates and faster table generation. [#207](https://github.com/klauspost/compress/pull/207) by [luyu6056](https://github.com/luyu6056),  [#206](https://github.com/klauspost/compress/pull/206).\r\n* Jan 11, 2020: S2 Encode/Decode will use provided buffer if capacity is big enough. [#204](https://github.com/klauspost/compress/pull/204) \r\n* Jan 5, 2020: (v1.9.7) Fix another zstd regression in v1.9.5 - v1.9.6 removed.\r\n* Jan 4, 2020: (v1.9.6) Regression in v1.9.5 fixed causing corrupt zstd encodes in rare cases.\r\n* Jan 4, 2020: Faster IO in [s2c + s2d commandline tools](https://github.com/klauspost/compress/tree/master/s2#commandline-tools) compression/decompression. [#192](https://github.com/klauspost/compress/pull/192)\r\n* Dec 29, 2019: Removed v1.9.5 since fuzz tests showed a compatibility problem with the reference zstandard decoder.\r\n* Dec 29, 2019: (v1.9.5) zstd: 10-20% faster block compression. [#199](https://github.com/klauspost/compress/pull/199)\r\n* Dec 29, 2019: [zip](https://godoc.org/github.com/klauspost/compress/zip) package updated with latest Go features\r\n* Dec 29, 2019: zstd: Single segment flag condintions tweaked. [#197](https://github.com/klauspost/compress/pull/197)\r\n* Dec 18, 2019: s2: Faster compression when ReadFrom is used. [#198](https://github.com/klauspost/compress/pull/198)\r\n* Dec 10, 2019: s2: Fix repeat length output when just above at 16MB limit.\r\n* Dec 10, 2019: zstd: Add function to get decoder as io.ReadCloser. [#191](https://github.com/klauspost/compress/pull/191)\r\n* Dec 3, 2019: (v1.9.4) S2: limit max repeat length. [#188](https://github.com/klauspost/compress/pull/188)\r\n* Dec 3, 2019: Add [WithNoEntropyCompression](https://godoc.org/github.com/klauspost/compress/zstd#WithNoEntropyCompression) to zstd [#187](https://github.com/klauspost/compress/pull/187)\r\n* Dec 3, 2019: Reduce memory use for tests. Check for leaked goroutines.\r\n* Nov 28, 2019 (v1.9.3) Less allocations in stateless deflate.\r\n* Nov 28, 2019: 5-20% Faster huff0 decode. Impacts zstd as well. [#184](https://github.com/klauspost/compress/pull/184)\r\n* Nov 12, 2019 (v1.9.2) Added [Stateless Compression](#stateless-compression) for gzip/deflate.\r\n* Nov 12, 2019: Fixed zstd decompression of large single blocks. [#180](https://github.com/klauspost/compress/pull/180)\r\n* Nov 11, 2019: Set default  [s2c](https://github.com/klauspost/compress/tree/master/s2#commandline-tools) block size to 4MB.\r\n* Nov 11, 2019: Reduce inflate memory use by 1KB.\r\n* Nov 10, 2019: Less allocations in deflate bit writer.\r\n* Nov 10, 2019: Fix inconsistent error returned by zstd decoder.\r\n* Oct 28, 2019 (v1.9.1) ztsd: Fix crash when compressing blocks. [#174](https://github.com/klauspost/compress/pull/174)\r\n* Oct 24, 2019 (v1.9.0) zstd: Fix rare data corruption [#173](https://github.com/klauspost/compress/pull/173)\r\n* Oct 24, 2019 zstd: Fix huff0 out of buffer write [#171](https://github.com/klauspost/compress/pull/171) and always return errors [#172](https://github.com/klauspost/compress/pull/172) \r\n* Oct 10, 2019: Big deflate rewrite, 30-40% faster with better compression [#105](https://github.com/klauspost/compress/pull/105)\r\n\r\n</details>\r\n\r\n<details>\r\n\t<summary>See changes prior to v1.9.0</summary>\r\n\r\n* Oct 10, 2019: (v1.8.6) zstd: Allow partial reads to get flushed data. [#169](https://github.com/klauspost/compress/pull/169)\r\n* Oct 3, 2019: Fix inconsistent results on broken zstd streams.\r\n* Sep 25, 2019: Added `-rm` (remove source files) and `-q` (no output except errors) to `s2c` and `s2d` [commands](https://github.com/klauspost/compress/tree/master/s2#commandline-tools)\r\n* Sep 16, 2019: (v1.8.4) Add `s2c` and `s2d` [commandline tools](https://github.com/klauspost/compress/tree/master/s2#commandline-tools).\r\n* Sep 10, 2019: (v1.8.3) Fix s2 decoder [Skip](https://godoc.org/github.com/klauspost/compress/s2#Reader.Skip).\r\n* Sep 7, 2019: zstd: Added [WithWindowSize](https://godoc.org/github.com/klauspost/compress/zstd#WithWindowSize), contributed by [ianwilkes](https://github.com/ianwilkes).\r\n* Sep 5, 2019: (v1.8.2) Add [WithZeroFrames](https://godoc.org/github.com/klauspost/compress/zstd#WithZeroFrames) which adds full zero payload block encoding option.\r\n* Sep 5, 2019: Lazy initialization of zstandard predefined en/decoder tables.\r\n* Aug 26, 2019: (v1.8.1) S2: 1-2% compression increase in \"better\" compression mode.\r\n* Aug 26, 2019: zstd: Check maximum size of Huffman 1X compressed literals while decoding.\r\n* Aug 24, 2019: (v1.8.0) Added [S2 compression](https://github.com/klauspost/compress/tree/master/s2#s2-compression), a high performance replacement for Snappy. \r\n* Aug 21, 2019: (v1.7.6) Fixed minor issues found by fuzzer. One could lead to zstd not decompressing.\r\n* Aug 18, 2019: Add [fuzzit](https://fuzzit.dev/) continuous fuzzing.\r\n* Aug 14, 2019: zstd: Skip incompressible data 2x faster.  [#147](https://github.com/klauspost/compress/pull/147)\r\n* Aug 4, 2019 (v1.7.5): Better literal compression. [#146](https://github.com/klauspost/compress/pull/146)\r\n* Aug 4, 2019: Faster zstd compression. [#143](https://github.com/klauspost/compress/pull/143) [#144](https://github.com/klauspost/compress/pull/144)\r\n* Aug 4, 2019: Faster zstd decompression. [#145](https://github.com/klauspost/compress/pull/145) [#143](https://github.com/klauspost/compress/pull/143) [#142](https://github.com/klauspost/compress/pull/142)\r\n* July 15, 2019 (v1.7.4): Fix double EOF block in rare cases on zstd encoder.\r\n* July 15, 2019 (v1.7.3): Minor speedup/compression increase in default zstd encoder.\r\n* July 14, 2019: zstd decoder: Fix decompression error on multiple uses with mixed content.\r\n* July 7, 2019 (v1.7.2): Snappy update, zstd decoder potential race fix.\r\n* June 17, 2019: zstd decompression bugfix.\r\n* June 17, 2019: fix 32 bit builds.\r\n* June 17, 2019: Easier use in modules (less dependencies).\r\n* June 9, 2019: New stronger \"default\" [zstd](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression mode. Matches zstd default compression ratio.\r\n* June 5, 2019: 20-40% throughput in [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and better compression.\r\n* June 5, 2019: deflate/gzip compression: Reduce memory usage of lower compression levels.\r\n* June 2, 2019: Added [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression!\r\n* May 25, 2019: deflate/gzip: 10% faster bit writer, mostly visible in lower levels.\r\n* Apr 22, 2019: [zstd](https://github.com/klauspost/compress/tree/master/zstd#zstd) decompression added.\r\n* Aug 1, 2018: Added [huff0 README](https://github.com/klauspost/compress/tree/master/huff0#huff0-entropy-compression).\r\n* Jul 8, 2018: Added [Performance Update 2018](#performance-update-2018) below.\r\n* Jun 23, 2018: Merged [Go 1.11 inflate optimizations](https://go-review.googlesource.com/c/go/+/102235). Go 1.9 is now required. Backwards compatible version tagged with [v1.3.0](https://github.com/klauspost/compress/releases/tag/v1.3.0).\r\n* Apr 2, 2018: Added [huff0](https://godoc.org/github.com/klauspost/compress/huff0) en/decoder. Experimental for now, API may change.\r\n* Mar 4, 2018: Added [FSE Entropy](https://godoc.org/github.com/klauspost/compress/fse) en/decoder. Experimental for now, API may change.\r\n* Nov 3, 2017: Add compression [Estimate](https://godoc.org/github.com/klauspost/compress#Estimate) function.\r\n* May 28, 2017: Reduce allocations when resetting decoder.\r\n* Apr 02, 2017: Change back to official crc32, since changes were merged in Go 1.7.\r\n* Jan 14, 2017: Reduce stack pressure due to array copies. See [Issue #18625](https://github.com/golang/go/issues/18625).\r\n* Oct 25, 2016: Level 2-4 have been rewritten and now offers significantly better performance than before.\r\n* Oct 20, 2016: Port zlib changes from Go 1.7 to fix zlib writer issue. Please update.\r\n* Oct 16, 2016: Go 1.7 changes merged. Apples to apples this package is a few percent faster, but has a significantly better balance between speed and compression per level. \r\n* Mar 24, 2016: Always attempt Huffman encoding on level 4-7. This improves base 64 encoded data compression.\r\n* Mar 24, 2016: Small speedup for level 1-3.\r\n* Feb 19, 2016: Faster bit writer, level -2 is 15% faster, level 1 is 4% faster.\r\n* Feb 19, 2016: Handle small payloads faster in level 1-3.\r\n* Feb 19, 2016: Added faster level 2 + 3 compression modes.\r\n* Feb 19, 2016: [Rebalanced compression levels](https://blog.klauspost.com/rebalancing-deflate-compression-levels/), so there is a more even progresssion in terms of compression. New default level is 5.\r\n* Feb 14, 2016: Snappy: Merge upstream changes. \r\n* Feb 14, 2016: Snappy: Fix aggressive skipping.\r\n* Feb 14, 2016: Snappy: Update benchmark.\r\n* Feb 13, 2016: Deflate: Fixed assembler problem that could lead to sub-optimal compression.\r\n* Feb 12, 2016: Snappy: Added AMD64 SSE 4.2 optimizations to matching, which makes easy to compress material run faster. Typical speedup is around 25%.\r\n* Feb 9, 2016: Added Snappy package fork. This version is 5-7% faster, much more on hard to compress content.\r\n* Jan 30, 2016: Optimize level 1 to 3 by not considering static dictionary or storing uncompressed. ~4-5% speedup.\r\n* Jan 16, 2016: Optimization on deflate level 1,2,3 compression.\r\n* Jan 8 2016: Merge [CL 18317](https://go-review.googlesource.com/#/c/18317): fix reading, writing of zip64 archives.\r\n* Dec 8 2015: Make level 1 and -2 deterministic even if write size differs.\r\n* Dec 8 2015: Split encoding functions, so hashing and matching can potentially be inlined. 1-3% faster on AMD64. 5% faster on other platforms.\r\n* Dec 8 2015: Fixed rare [one byte out-of bounds read](https://github.com/klauspost/compress/issues/20). Please update!\r\n* Nov 23 2015: Optimization on token writer. ~2-4% faster. Contributed by [@dsnet](https://github.com/dsnet).\r\n* Nov 20 2015: Small optimization to bit writer on 64 bit systems.\r\n* Nov 17 2015: Fixed out-of-bound errors if the underlying Writer returned an error. See [#15](https://github.com/klauspost/compress/issues/15).\r\n* Nov 12 2015: Added [io.WriterTo](https://golang.org/pkg/io/#WriterTo) support to gzip/inflate.\r\n* Nov 11 2015: Merged [CL 16669](https://go-review.googlesource.com/#/c/16669/4): archive/zip: enable overriding (de)compressors per file\r\n* Oct 15 2015: Added skipping on uncompressible data. Random data speed up >5x.\r\n\r\n</details>\r\n\r\n# deflate usage\r\n\r\nThe packages are drop-in replacements for standard libraries. Simply replace the import path to use them:\r\n\r\n| old import         | new import                              | Documentation\r\n|--------------------|-----------------------------------------|--------------------|\r\n| `compress/gzip`    | `github.com/klauspost/compress/gzip`    | [gzip](https://pkg.go.dev/github.com/klauspost/compress/gzip?tab=doc)\r\n| `compress/zlib`    | `github.com/klauspost/compress/zlib`    | [zlib](https://pkg.go.dev/github.com/klauspost/compress/zlib?tab=doc)\r\n| `archive/zip`      | `github.com/klauspost/compress/zip`     | [zip](https://pkg.go.dev/github.com/klauspost/compress/zip?tab=doc)\r\n| `compress/flate`   | `github.com/klauspost/compress/flate`   | [flate](https://pkg.go.dev/github.com/klauspost/compress/flate?tab=doc)\r\n\r\n* Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib).\r\n\r\nYou may also be interested in [pgzip](https://github.com/klauspost/pgzip), which is a drop in replacement for gzip, which support multithreaded compression on big files and the optimized [crc32](https://github.com/klauspost/crc32) package used by these packages.\r\n\r\nThe packages contains the same as the standard library, so you can use the godoc for that: [gzip](http://golang.org/pkg/compress/gzip/), [zip](http://golang.org/pkg/archive/zip/),  [zlib](http://golang.org/pkg/compress/zlib/), [flate](http://golang.org/pkg/compress/flate/).\r\n\r\nCurrently there is only minor speedup on decompression (mostly CRC32 calculation).\r\n\r\nMemory usage is typically 1MB for a Writer. stdlib is in the same range. \r\nIf you expect to have a lot of concurrently allocated Writers consider using \r\nthe stateless compress described below.\r\n\r\nFor compression performance, see: [this spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing).\r\n\r\n# Stateless compression\r\n\r\nThis package offers stateless compression as a special option for gzip/deflate. \r\nIt will do compression but without maintaining any state between Write calls.\r\n\r\nThis means there will be no memory kept between Write calls, but compression and speed will be suboptimal.\r\n\r\nThis is only relevant in cases where you expect to run many thousands of compressors concurrently, \r\nbut with very little activity. This is *not* intended for regular web servers serving individual requests.  \r\n\r\nBecause of this, the size of actual Write calls will affect output size.\r\n\r\nIn gzip, specify level `-3` / `gzip.StatelessCompression` to enable.\r\n\r\nFor direct deflate use, NewStatelessWriter and StatelessDeflate are available. See [documentation](https://godoc.org/github.com/klauspost/compress/flate#NewStatelessWriter)\r\n\r\nA `bufio.Writer` can of course be used to control write sizes. For example, to use a 4KB buffer:\r\n\r\n```\r\n\t// replace 'ioutil.Discard' with your output.\r\n\tgzw, err := gzip.NewWriterLevel(ioutil.Discard, gzip.StatelessCompression)\r\n\tif err != nil {\r\n\t\treturn err\r\n\t}\r\n\tdefer gzw.Close()\r\n\r\n\tw := bufio.NewWriterSize(gzw, 4096)\r\n\tdefer w.Flush()\r\n\t\r\n\t// Write to 'w' \r\n```\r\n\r\nThis will only use up to 4KB in memory when the writer is idle. \r\n\r\nCompression is almost always worse than the fastest compression level \r\nand each write will allocate (a little) memory. \r\n\r\n# Performance Update 2018\r\n\r\nIt has been a while since we have been looking at the speed of this package compared to the standard library, so I thought I would re-do my tests and give some overall recommendations based on the current state. All benchmarks have been performed with Go 1.10 on my Desktop Intel(R) Core(TM) i7-2600 CPU @3.40GHz. Since I last ran the tests, I have gotten more RAM, which means tests with big files are no longer limited by my SSD.\r\n\r\nThe raw results are in my [updated spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing). Due to cgo changes and upstream updates i could not get the cgo version of gzip to compile. Instead I included the [zstd](https://github.com/datadog/zstd) cgo implementation. If I get cgo gzip to work again, I might replace the results in the sheet.\r\n\r\nThe columns to take note of are: *MB/s* - the throughput. *Reduction* - the data size reduction in percent of the original. *Rel Speed* relative speed compared to the standard library at the same level. *Smaller* - how many percent smaller is the compressed output compared to stdlib. Negative means the output was bigger. *Loss* means the loss (or gain) in compression as a percentage difference of the input.\r\n\r\nThe `gzstd` (standard library gzip) and `gzkp` (this package gzip) only uses one CPU core. [`pgzip`](https://github.com/klauspost/pgzip), [`bgzf`](https://github.com/biogo/hts/tree/master/bgzf) uses all 4 cores. [`zstd`](https://github.com/DataDog/zstd) uses one core, and is a beast (but not Go, yet).\r\n\r\n\r\n## Overall differences.\r\n\r\nThere appears to be a roughly 5-10% speed advantage over the standard library when comparing at similar compression levels.\r\n\r\nThe biggest difference you will see is the result of [re-balancing](https://blog.klauspost.com/rebalancing-deflate-compression-levels/) the compression levels. I wanted by library to give a smoother transition between the compression levels than the standard library.\r\n\r\nThis package attempts to provide a more smooth transition, where \"1\" is taking a lot of shortcuts, \"5\" is the reasonable trade-off and \"9\" is the \"give me the best compression\", and the values in between gives something reasonable in between. The standard library has big differences in levels 1-4, but levels 5-9 having no significant gains - often spending a lot more time than can be justified by the achieved compression.\r\n\r\nThere are links to all the test data in the [spreadsheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing) in the top left field on each tab.\r\n\r\n## Web Content\r\n\r\nThis test set aims to emulate typical use in a web server. The test-set is 4GB data in 53k files, and is a mixture of (mostly) HTML, JS, CSS.\r\n\r\nSince level 1 and 9 are close to being the same code, they are quite close. But looking at the levels in-between the differences are quite big.\r\n\r\nLooking at level 6, this package is 88% faster, but will output about 6% more data. For a web server, this means you can serve 88% more data, but have to pay for 6% more bandwidth. You can draw your own conclusions on what would be the most expensive for your case.\r\n\r\n## Object files\r\n\r\nThis test is for typical data files stored on a server. In this case it is a collection of Go precompiled objects. They are very compressible.\r\n\r\nThe picture is similar to the web content, but with small differences since this is very compressible. Levels 2-3 offer good speed, but is sacrificing quite a bit of compression. \r\n\r\nThe standard library seems suboptimal on level 3 and 4 - offering both worse compression and speed than level 6 & 7 of this package respectively.\r\n\r\n## Highly Compressible File\r\n\r\nThis is a JSON file with very high redundancy. The reduction starts at 95% on level 1, so in real life terms we are dealing with something like a highly redundant stream of data, etc.\r\n\r\nIt is definitely visible that we are dealing with specialized content here, so the results are very scattered. This package does not do very well at levels 1-4, but picks up significantly at level 5 and levels 7 and 8 offering great speed for the achieved compression.\r\n\r\nSo if you know you content is extremely compressible you might want to go slightly higher than the defaults. The standard library has a huge gap between levels 3 and 4 in terms of speed (2.75x slowdown), so it offers little \"middle ground\".\r\n\r\n## Medium-High Compressible\r\n\r\nThis is a pretty common test corpus: [enwik9](http://mattmahoney.net/dc/textdata.html). It contains the first 10^9 bytes of the English Wikipedia dump on Mar. 3, 2006. This is a very good test of typical text based compression and more data heavy streams.\r\n\r\nWe see a similar picture here as in \"Web Content\". On equal levels some compression is sacrificed for more speed. Level 5 seems to be the best trade-off between speed and size, beating stdlib level 3 in both.\r\n\r\n## Medium Compressible\r\n\r\nI will combine two test sets, one [10GB file set](http://mattmahoney.net/dc/10gb.html) and a VM disk image (~8GB). Both contain different data types and represent a typical backup scenario.\r\n\r\nThe most notable thing is how quickly the standard library drops to very low compression speeds around level 5-6 without any big gains in compression. Since this type of data is fairly common, this does not seem like good behavior.\r\n\r\n\r\n## Un-compressible Content\r\n\r\nThis is mainly a test of how good the algorithms are at detecting un-compressible input. The standard library only offers this feature with very conservative settings at level 1. Obviously there is no reason for the algorithms to try to compress input that cannot be compressed.  The only downside is that it might skip some compressible data on false detections.\r\n\r\n\r\n## Huffman only compression\r\n\r\nThis compression library adds a special compression level, named `HuffmanOnly`, which allows near linear time compression. This is done by completely disabling matching of previous data, and only reduce the number of bits to represent each character. \r\n\r\nThis means that often used characters, like 'e' and ' ' (space) in text use the fewest bits to represent, and rare characters like '¤' takes more bits to represent. For more information see [wikipedia](https://en.wikipedia.org/wiki/Huffman_coding) or this nice [video](https://youtu.be/ZdooBTdW5bM).\r\n\r\nSince this type of compression has much less variance, the compression speed is mostly unaffected by the input data, and is usually more than *180MB/s* for a single core.\r\n\r\nThe downside is that the compression ratio is usually considerably worse than even the fastest conventional compression. The compression ratio can never be better than 8:1 (12.5%). \r\n\r\nThe linear time compression can be used as a \"better than nothing\" mode, where you cannot risk the encoder to slow down on some content. For comparison, the size of the \"Twain\" text is *233460 bytes* (+29% vs. level 1) and encode speed is 144MB/s (4.5x level 1). So in this case you trade a 30% size increase for a 4 times speedup.\r\n\r\nFor more information see my blog post on [Fast Linear Time Compression](http://blog.klauspost.com/constant-time-gzipzip-compression/).\r\n\r\nThis is implemented on Go 1.7 as \"Huffman Only\" mode, though not exposed for gzip.\r\n\r\n# Other packages\r\n\r\nHere are other packages of good quality and pure Go (no cgo wrappers or autoconverted code):\r\n\r\n* [github.com/pierrec/lz4](https://github.com/pierrec/lz4) - strong multithreaded LZ4 compression.\r\n* [github.com/cosnicolaou/pbzip2](https://github.com/cosnicolaou/pbzip2) - multithreaded bzip2 decompression.\r\n* [github.com/dsnet/compress](https://github.com/dsnet/compress) - brotli decompression, bzip2 writer.\r\n* [github.com/ronanh/intcomp](https://github.com/ronanh/intcomp) - Integer compression.\r\n* [github.com/spenczar/fpc](https://github.com/spenczar/fpc) - Float compression.\r\n* [github.com/minio/zipindex](https://github.com/minio/zipindex) - External ZIP directory index.\r\n* [github.com/ybirader/pzip](https://github.com/ybirader/pzip) - Fast concurrent zip archiver and extractor.\r\n\r\n# license\r\n\r\nThis code is licensed under the same conditions as the original Go code. See LICENSE file.\r\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nSecurity updates are applied only to the latest release.\n\n## Vulnerability Definition\n\nA security vulnerability is a bug that with certain input triggers a crash or an infinite loop. Most calls will have varying execution time and only in rare cases will slow operation be considered a security vulnerability.\n\nCorrupted output generally is not considered a security vulnerability, unless independent operations are able to affect each other. Note that not all functionality is re-entrant and safe to use concurrently.\n\nOut-of-memory crashes only applies if the en/decoder uses an abnormal amount of memory, with appropriate options applied, to limit maximum window size, concurrency, etc. However, if you are in doubt you are welcome to file a security issue.\n\nIt is assumed that all callers are trusted, meaning internal data exposed through reflection or inspection of returned data structures is not considered a vulnerability.\n\nVulnerabilities resulting from compiler/assembler errors should be reported upstream. Depending on the severity this package may or may not implement a workaround.\n\n## Reporting a Vulnerability\n\nIf you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.\n\nPlease disclose it at [security advisory](https://github.com/klauspost/compress/security/advisories/new). If possible please provide a minimal reproducer. If the issue only applies to a single platform, it would be helpful to provide access to that.\n\nThis project is maintained by a team of volunteers on a reasonable-effort basis. As such, vulnerabilities will be disclosed in a best effort base.\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/compressible.go",
    "content": "package compress\n\nimport \"math\"\n\n// Estimate returns a normalized compressibility estimate of block b.\n// Values close to zero are likely uncompressible.\n// Values above 0.1 are likely to be compressible.\n// Values above 0.5 are very compressible.\n// Very small lengths will return 0.\nfunc Estimate(b []byte) float64 {\n\tif len(b) < 16 {\n\t\treturn 0\n\t}\n\n\t// Correctly predicted order 1\n\thits := 0\n\tlastMatch := false\n\tvar o1 [256]byte\n\tvar hist [256]int\n\tc1 := byte(0)\n\tfor _, c := range b {\n\t\tif c == o1[c1] {\n\t\t\t// We only count a hit if there was two correct predictions in a row.\n\t\t\tif lastMatch {\n\t\t\t\thits++\n\t\t\t}\n\t\t\tlastMatch = true\n\t\t} else {\n\t\t\tlastMatch = false\n\t\t}\n\t\to1[c1] = c\n\t\tc1 = c\n\t\thist[c]++\n\t}\n\n\t// Use x^0.6 to give better spread\n\tprediction := math.Pow(float64(hits)/float64(len(b)), 0.6)\n\n\t// Calculate histogram distribution\n\tvariance := float64(0)\n\tavg := float64(len(b)) / 256\n\n\tfor _, v := range hist {\n\t\tΔ := float64(v) - avg\n\t\tvariance += Δ * Δ\n\t}\n\n\tstddev := math.Sqrt(float64(variance)) / float64(len(b))\n\texp := math.Sqrt(1 / float64(len(b)))\n\n\t// Subtract expected stddev\n\tstddev -= exp\n\tif stddev < 0 {\n\t\tstddev = 0\n\t}\n\tstddev *= 1 + exp\n\n\t// Use x^0.4 to give better spread\n\tentropy := math.Pow(stddev, 0.4)\n\n\t// 50/50 weight between prediction and histogram distribution\n\treturn math.Pow((prediction+entropy)/2, 0.9)\n}\n\n// ShannonEntropyBits returns the number of bits minimum required to represent\n// an entropy encoding of the input bytes.\n// https://en.wiktionary.org/wiki/Shannon_entropy\nfunc ShannonEntropyBits(b []byte) int {\n\tif len(b) == 0 {\n\t\treturn 0\n\t}\n\tvar hist [256]int\n\tfor _, c := range b {\n\t\thist[c]++\n\t}\n\tshannon := float64(0)\n\tinvTotal := 1.0 / float64(len(b))\n\tfor _, v := range hist[:] {\n\t\tif v > 0 {\n\t\t\tn := float64(v)\n\t\t\tshannon += math.Ceil(-math.Log2(n*invTotal) * n)\n\t\t}\n\t}\n\treturn int(math.Ceil(shannon))\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/deflate.go",
    "content": "// Copyright 2009 The Go Authors. All rights reserved.\n// Copyright (c) 2015 Klaus Post\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage flate\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n)\n\nconst (\n\tNoCompression      = 0\n\tBestSpeed          = 1\n\tBestCompression    = 9\n\tDefaultCompression = -1\n\n\t// HuffmanOnly disables Lempel-Ziv match searching and only performs Huffman\n\t// entropy encoding. This mode is useful in compressing data that has\n\t// already been compressed with an LZ style algorithm (e.g. Snappy or LZ4)\n\t// that lacks an entropy encoder. Compression gains are achieved when\n\t// certain bytes in the input stream occur more frequently than others.\n\t//\n\t// Note that HuffmanOnly produces a compressed output that is\n\t// RFC 1951 compliant. That is, any valid DEFLATE decompressor will\n\t// continue to be able to decompress this output.\n\tHuffmanOnly         = -2\n\tConstantCompression = HuffmanOnly // compatibility alias.\n\n\tlogWindowSize    = 15\n\twindowSize       = 1 << logWindowSize\n\twindowMask       = windowSize - 1\n\tlogMaxOffsetSize = 15  // Standard DEFLATE\n\tminMatchLength   = 4   // The smallest match that the compressor looks for\n\tmaxMatchLength   = 258 // The longest match for the compressor\n\tminOffsetSize    = 1   // The shortest offset that makes any sense\n\n\t// The maximum number of tokens we will encode at the time.\n\t// Smaller sizes usually creates less optimal blocks.\n\t// Bigger can make context switching slow.\n\t// We use this for levels 7-9, so we make it big.\n\tmaxFlateBlockTokens = 1 << 15\n\tmaxStoreBlockSize   = 65535\n\thashBits            = 17 // After 17 performance degrades\n\thashSize            = 1 << hashBits\n\thashMask            = (1 << hashBits) - 1\n\thashShift           = (hashBits + minMatchLength - 1) / minMatchLength\n\tmaxHashOffset       = 1 << 28\n\n\tskipNever = math.MaxInt32\n\n\tdebugDeflate = false\n)\n\ntype compressionLevel struct {\n\tgood, lazy, nice, chain, fastSkipHashing, level int\n}\n\n// Compression levels have been rebalanced from zlib deflate defaults\n// to give a bigger spread in speed and compression.\n// See https://blog.klauspost.com/rebalancing-deflate-compression-levels/\nvar levels = []compressionLevel{\n\t{}, // 0\n\t// Level 1-6 uses specialized algorithm - values not used\n\t{0, 0, 0, 0, 0, 1},\n\t{0, 0, 0, 0, 0, 2},\n\t{0, 0, 0, 0, 0, 3},\n\t{0, 0, 0, 0, 0, 4},\n\t{0, 0, 0, 0, 0, 5},\n\t{0, 0, 0, 0, 0, 6},\n\t// Levels 7-9 use increasingly more lazy matching\n\t// and increasingly stringent conditions for \"good enough\".\n\t{8, 12, 16, 24, skipNever, 7},\n\t{16, 30, 40, 64, skipNever, 8},\n\t{32, 258, 258, 1024, skipNever, 9},\n}\n\n// advancedState contains state for the advanced levels, with bigger hash tables, etc.\ntype advancedState struct {\n\t// deflate state\n\tlength         int\n\toffset         int\n\tmaxInsertIndex int\n\tchainHead      int\n\thashOffset     int\n\n\tii uint16 // position of last match, intended to overflow to reset.\n\n\t// input window: unprocessed data is window[index:windowEnd]\n\tindex     int\n\thashMatch [maxMatchLength + minMatchLength]uint32\n\n\t// Input hash chains\n\t// hashHead[hashValue] contains the largest inputIndex with the specified hash value\n\t// If hashHead[hashValue] is within the current window, then\n\t// hashPrev[hashHead[hashValue] & windowMask] contains the previous index\n\t// with the same hash value.\n\thashHead [hashSize]uint32\n\thashPrev [windowSize]uint32\n}\n\ntype compressor struct {\n\tcompressionLevel\n\n\th *huffmanEncoder\n\tw *huffmanBitWriter\n\n\t// compression algorithm\n\tfill func(*compressor, []byte) int // copy data to window\n\tstep func(*compressor)             // process window\n\n\twindow     []byte\n\twindowEnd  int\n\tblockStart int // window index where current tokens start\n\terr        error\n\n\t// queued output tokens\n\ttokens tokens\n\tfast   fastEnc\n\tstate  *advancedState\n\n\tsync          bool // requesting flush\n\tbyteAvailable bool // if true, still need to process window[index-1].\n}\n\nfunc (d *compressor) fillDeflate(b []byte) int {\n\ts := d.state\n\tif s.index >= 2*windowSize-(minMatchLength+maxMatchLength) {\n\t\t// shift the window by windowSize\n\t\t//copy(d.window[:], d.window[windowSize:2*windowSize])\n\t\t*(*[windowSize]byte)(d.window) = *(*[windowSize]byte)(d.window[windowSize:])\n\t\ts.index -= windowSize\n\t\td.windowEnd -= windowSize\n\t\tif d.blockStart >= windowSize {\n\t\t\td.blockStart -= windowSize\n\t\t} else {\n\t\t\td.blockStart = math.MaxInt32\n\t\t}\n\t\ts.hashOffset += windowSize\n\t\tif s.hashOffset > maxHashOffset {\n\t\t\tdelta := s.hashOffset - 1\n\t\t\ts.hashOffset -= delta\n\t\t\ts.chainHead -= delta\n\t\t\t// Iterate over slices instead of arrays to avoid copying\n\t\t\t// the entire table onto the stack (Issue #18625).\n\t\t\tfor i, v := range s.hashPrev[:] {\n\t\t\t\tif int(v) > delta {\n\t\t\t\t\ts.hashPrev[i] = uint32(int(v) - delta)\n\t\t\t\t} else {\n\t\t\t\t\ts.hashPrev[i] = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor i, v := range s.hashHead[:] {\n\t\t\t\tif int(v) > delta {\n\t\t\t\t\ts.hashHead[i] = uint32(int(v) - delta)\n\t\t\t\t} else {\n\t\t\t\t\ts.hashHead[i] = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tn := copy(d.window[d.windowEnd:], b)\n\td.windowEnd += n\n\treturn n\n}\n\nfunc (d *compressor) writeBlock(tok *tokens, index int, eof bool) error {\n\tif index > 0 || eof {\n\t\tvar window []byte\n\t\tif d.blockStart <= index {\n\t\t\twindow = d.window[d.blockStart:index]\n\t\t}\n\t\td.blockStart = index\n\t\t//d.w.writeBlock(tok, eof, window)\n\t\td.w.writeBlockDynamic(tok, eof, window, d.sync)\n\t\treturn d.w.err\n\t}\n\treturn nil\n}\n\n// writeBlockSkip writes the current block and uses the number of tokens\n// to determine if the block should be stored on no matches, or\n// only huffman encoded.\nfunc (d *compressor) writeBlockSkip(tok *tokens, index int, eof bool) error {\n\tif index > 0 || eof {\n\t\tif d.blockStart <= index {\n\t\t\twindow := d.window[d.blockStart:index]\n\t\t\t// If we removed less than a 64th of all literals\n\t\t\t// we huffman compress the block.\n\t\t\tif int(tok.n) > len(window)-int(tok.n>>6) {\n\t\t\t\td.w.writeBlockHuff(eof, window, d.sync)\n\t\t\t} else {\n\t\t\t\t// Write a dynamic huffman block.\n\t\t\t\td.w.writeBlockDynamic(tok, eof, window, d.sync)\n\t\t\t}\n\t\t} else {\n\t\t\td.w.writeBlock(tok, eof, nil)\n\t\t}\n\t\td.blockStart = index\n\t\treturn d.w.err\n\t}\n\treturn nil\n}\n\n// fillWindow will fill the current window with the supplied\n// dictionary and calculate all hashes.\n// This is much faster than doing a full encode.\n// Should only be used after a start/reset.\nfunc (d *compressor) fillWindow(b []byte) {\n\t// Do not fill window if we are in store-only or huffman mode.\n\tif d.level <= 0 {\n\t\treturn\n\t}\n\tif d.fast != nil {\n\t\t// encode the last data, but discard the result\n\t\tif len(b) > maxMatchOffset {\n\t\t\tb = b[len(b)-maxMatchOffset:]\n\t\t}\n\t\td.fast.Encode(&d.tokens, b)\n\t\td.tokens.Reset()\n\t\treturn\n\t}\n\ts := d.state\n\t// If we are given too much, cut it.\n\tif len(b) > windowSize {\n\t\tb = b[len(b)-windowSize:]\n\t}\n\t// Add all to window.\n\tn := copy(d.window[d.windowEnd:], b)\n\n\t// Calculate 256 hashes at the time (more L1 cache hits)\n\tloops := (n + 256 - minMatchLength) / 256\n\tfor j := 0; j < loops; j++ {\n\t\tstartindex := j * 256\n\t\tend := startindex + 256 + minMatchLength - 1\n\t\tif end > n {\n\t\t\tend = n\n\t\t}\n\t\ttocheck := d.window[startindex:end]\n\t\tdstSize := len(tocheck) - minMatchLength + 1\n\n\t\tif dstSize <= 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tdst := s.hashMatch[:dstSize]\n\t\tbulkHash4(tocheck, dst)\n\t\tvar newH uint32\n\t\tfor i, val := range dst {\n\t\t\tdi := i + startindex\n\t\t\tnewH = val & hashMask\n\t\t\t// Get previous value with the same hash.\n\t\t\t// Our chain should point to the previous value.\n\t\t\ts.hashPrev[di&windowMask] = s.hashHead[newH]\n\t\t\t// Set the head of the hash chain to us.\n\t\t\ts.hashHead[newH] = uint32(di + s.hashOffset)\n\t\t}\n\t}\n\t// Update window information.\n\td.windowEnd += n\n\ts.index = n\n}\n\n// Try to find a match starting at index whose length is greater than prevSize.\n// We only look at chainCount possibilities before giving up.\n// pos = s.index, prevHead = s.chainHead-s.hashOffset, prevLength=minMatchLength-1, lookahead\nfunc (d *compressor) findMatch(pos int, prevHead int, lookahead int) (length, offset int, ok bool) {\n\tminMatchLook := maxMatchLength\n\tif lookahead < minMatchLook {\n\t\tminMatchLook = lookahead\n\t}\n\n\twin := d.window[0 : pos+minMatchLook]\n\n\t// We quit when we get a match that's at least nice long\n\tnice := len(win) - pos\n\tif d.nice < nice {\n\t\tnice = d.nice\n\t}\n\n\t// If we've got a match that's good enough, only look in 1/4 the chain.\n\ttries := d.chain\n\tlength = minMatchLength - 1\n\n\twEnd := win[pos+length]\n\twPos := win[pos:]\n\tminIndex := pos - windowSize\n\tif minIndex < 0 {\n\t\tminIndex = 0\n\t}\n\toffset = 0\n\n\tif d.chain < 100 {\n\t\tfor i := prevHead; tries > 0; tries-- {\n\t\t\tif wEnd == win[i+length] {\n\t\t\t\tn := matchLen(win[i:i+minMatchLook], wPos)\n\t\t\t\tif n > length {\n\t\t\t\t\tlength = n\n\t\t\t\t\toffset = pos - i\n\t\t\t\t\tok = true\n\t\t\t\t\tif n >= nice {\n\t\t\t\t\t\t// The match is good enough that we don't try to find a better one.\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\twEnd = win[pos+n]\n\t\t\t\t}\n\t\t\t}\n\t\t\tif i <= minIndex {\n\t\t\t\t// hashPrev[i & windowMask] has already been overwritten, so stop now.\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ti = int(d.state.hashPrev[i&windowMask]) - d.state.hashOffset\n\t\t\tif i < minIndex {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\t// Minimum gain to accept a match.\n\tcGain := 4\n\n\t// Some like it higher (CSV), some like it lower (JSON)\n\tconst baseCost = 3\n\t// Base is 4 bytes at with an additional cost.\n\t// Matches must be better than this.\n\n\tfor i := prevHead; tries > 0; tries-- {\n\t\tif wEnd == win[i+length] {\n\t\t\tn := matchLen(win[i:i+minMatchLook], wPos)\n\t\t\tif n > length {\n\t\t\t\t// Calculate gain. Estimate\n\t\t\t\tnewGain := d.h.bitLengthRaw(wPos[:n]) - int(offsetExtraBits[offsetCode(uint32(pos-i))]) - baseCost - int(lengthExtraBits[lengthCodes[(n-3)&255]])\n\n\t\t\t\t//fmt.Println(\"gain:\", newGain, \"prev:\", cGain, \"raw:\", d.h.bitLengthRaw(wPos[:n]), \"this-len:\", n, \"prev-len:\", length)\n\t\t\t\tif newGain > cGain {\n\t\t\t\t\tlength = n\n\t\t\t\t\toffset = pos - i\n\t\t\t\t\tcGain = newGain\n\t\t\t\t\tok = true\n\t\t\t\t\tif n >= nice {\n\t\t\t\t\t\t// The match is good enough that we don't try to find a better one.\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\twEnd = win[pos+n]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif i <= minIndex {\n\t\t\t// hashPrev[i & windowMask] has already been overwritten, so stop now.\n\t\t\tbreak\n\t\t}\n\t\ti = int(d.state.hashPrev[i&windowMask]) - d.state.hashOffset\n\t\tif i < minIndex {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn\n}\n\nfunc (d *compressor) writeStoredBlock(buf []byte) error {\n\tif d.w.writeStoredHeader(len(buf), false); d.w.err != nil {\n\t\treturn d.w.err\n\t}\n\td.w.writeBytes(buf)\n\treturn d.w.err\n}\n\n// hash4 returns a hash representation of the first 4 bytes\n// of the supplied slice.\n// The caller must ensure that len(b) >= 4.\nfunc hash4(b []byte) uint32 {\n\treturn hash4u(binary.LittleEndian.Uint32(b), hashBits)\n}\n\n// hash4 returns the hash of u to fit in a hash table with h bits.\n// Preferably h should be a constant and should always be <32.\nfunc hash4u(u uint32, h uint8) uint32 {\n\treturn (u * prime4bytes) >> (32 - h)\n}\n\n// bulkHash4 will compute hashes using the same\n// algorithm as hash4\nfunc bulkHash4(b []byte, dst []uint32) {\n\tif len(b) < 4 {\n\t\treturn\n\t}\n\thb := binary.LittleEndian.Uint32(b)\n\n\tdst[0] = hash4u(hb, hashBits)\n\tend := len(b) - 4 + 1\n\tfor i := 1; i < end; i++ {\n\t\thb = (hb >> 8) | uint32(b[i+3])<<24\n\t\tdst[i] = hash4u(hb, hashBits)\n\t}\n}\n\nfunc (d *compressor) initDeflate() {\n\td.window = make([]byte, 2*windowSize)\n\td.byteAvailable = false\n\td.err = nil\n\tif d.state == nil {\n\t\treturn\n\t}\n\ts := d.state\n\ts.index = 0\n\ts.hashOffset = 1\n\ts.length = minMatchLength - 1\n\ts.offset = 0\n\ts.chainHead = -1\n}\n\n// deflateLazy is the same as deflate, but with d.fastSkipHashing == skipNever,\n// meaning it always has lazy matching on.\nfunc (d *compressor) deflateLazy() {\n\ts := d.state\n\t// Sanity enables additional runtime tests.\n\t// It's intended to be used during development\n\t// to supplement the currently ad-hoc unit tests.\n\tconst sanity = debugDeflate\n\n\tif d.windowEnd-s.index < minMatchLength+maxMatchLength && !d.sync {\n\t\treturn\n\t}\n\tif d.windowEnd != s.index && d.chain > 100 {\n\t\t// Get literal huffman coder.\n\t\tif d.h == nil {\n\t\t\td.h = newHuffmanEncoder(maxFlateBlockTokens)\n\t\t}\n\t\tvar tmp [256]uint16\n\t\tfor _, v := range d.window[s.index:d.windowEnd] {\n\t\t\ttmp[v]++\n\t\t}\n\t\td.h.generate(tmp[:], 15)\n\t}\n\n\ts.maxInsertIndex = d.windowEnd - (minMatchLength - 1)\n\n\tfor {\n\t\tif sanity && s.index > d.windowEnd {\n\t\t\tpanic(\"index > windowEnd\")\n\t\t}\n\t\tlookahead := d.windowEnd - s.index\n\t\tif lookahead < minMatchLength+maxMatchLength {\n\t\t\tif !d.sync {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif sanity && s.index > d.windowEnd {\n\t\t\t\tpanic(\"index > windowEnd\")\n\t\t\t}\n\t\t\tif lookahead == 0 {\n\t\t\t\t// Flush current output block if any.\n\t\t\t\tif d.byteAvailable {\n\t\t\t\t\t// There is still one pending token that needs to be flushed\n\t\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\t\td.byteAvailable = false\n\t\t\t\t}\n\t\t\t\tif d.tokens.n > 0 {\n\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\td.tokens.Reset()\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif s.index < s.maxInsertIndex {\n\t\t\t// Update the hash\n\t\t\thash := hash4(d.window[s.index:])\n\t\t\tch := s.hashHead[hash]\n\t\t\ts.chainHead = int(ch)\n\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\ts.hashHead[hash] = uint32(s.index + s.hashOffset)\n\t\t}\n\t\tprevLength := s.length\n\t\tprevOffset := s.offset\n\t\ts.length = minMatchLength - 1\n\t\ts.offset = 0\n\t\tminIndex := s.index - windowSize\n\t\tif minIndex < 0 {\n\t\t\tminIndex = 0\n\t\t}\n\n\t\tif s.chainHead-s.hashOffset >= minIndex && lookahead > prevLength && prevLength < d.lazy {\n\t\t\tif newLength, newOffset, ok := d.findMatch(s.index, s.chainHead-s.hashOffset, lookahead); ok {\n\t\t\t\ts.length = newLength\n\t\t\t\ts.offset = newOffset\n\t\t\t}\n\t\t}\n\n\t\tif prevLength >= minMatchLength && s.length <= prevLength {\n\t\t\t// No better match, but check for better match at end...\n\t\t\t//\n\t\t\t// Skip forward a number of bytes.\n\t\t\t// Offset of 2 seems to yield best results. 3 is sometimes better.\n\t\t\tconst checkOff = 2\n\n\t\t\t// Check all, except full length\n\t\t\tif prevLength < maxMatchLength-checkOff {\n\t\t\t\tprevIndex := s.index - 1\n\t\t\t\tif prevIndex+prevLength < s.maxInsertIndex {\n\t\t\t\t\tend := lookahead\n\t\t\t\t\tif lookahead > maxMatchLength+checkOff {\n\t\t\t\t\t\tend = maxMatchLength + checkOff\n\t\t\t\t\t}\n\t\t\t\t\tend += prevIndex\n\n\t\t\t\t\t// Hash at match end.\n\t\t\t\t\th := hash4(d.window[prevIndex+prevLength:])\n\t\t\t\t\tch2 := int(s.hashHead[h]) - s.hashOffset - prevLength\n\t\t\t\t\tif prevIndex-ch2 != prevOffset && ch2 > minIndex+checkOff {\n\t\t\t\t\t\tlength := matchLen(d.window[prevIndex+checkOff:end], d.window[ch2+checkOff:])\n\t\t\t\t\t\t// It seems like a pure length metric is best.\n\t\t\t\t\t\tif length > prevLength {\n\t\t\t\t\t\t\tprevLength = length\n\t\t\t\t\t\t\tprevOffset = prevIndex - ch2\n\n\t\t\t\t\t\t\t// Extend back...\n\t\t\t\t\t\t\tfor i := checkOff - 1; i >= 0; i-- {\n\t\t\t\t\t\t\t\tif prevLength >= maxMatchLength || d.window[prevIndex+i] != d.window[ch2+i] {\n\t\t\t\t\t\t\t\t\t// Emit tokens we \"owe\"\n\t\t\t\t\t\t\t\t\tfor j := 0; j <= i; j++ {\n\t\t\t\t\t\t\t\t\t\td.tokens.AddLiteral(d.window[prevIndex+j])\n\t\t\t\t\t\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\t\t\t\t\t\t// The block includes the current character\n\t\t\t\t\t\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\td.tokens.Reset()\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\ts.index++\n\t\t\t\t\t\t\t\t\t\tif s.index < s.maxInsertIndex {\n\t\t\t\t\t\t\t\t\t\t\th := hash4(d.window[s.index:])\n\t\t\t\t\t\t\t\t\t\t\tch := s.hashHead[h]\n\t\t\t\t\t\t\t\t\t\t\ts.chainHead = int(ch)\n\t\t\t\t\t\t\t\t\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\t\t\t\t\t\t\t\t\ts.hashHead[h] = uint32(s.index + s.hashOffset)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tprevLength++\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if false {\n\t\t\t\t\t\t\t// Check one further ahead.\n\t\t\t\t\t\t\t// Only rarely better, disabled for now.\n\t\t\t\t\t\t\tprevIndex++\n\t\t\t\t\t\t\th := hash4(d.window[prevIndex+prevLength:])\n\t\t\t\t\t\t\tch2 := int(s.hashHead[h]) - s.hashOffset - prevLength\n\t\t\t\t\t\t\tif prevIndex-ch2 != prevOffset && ch2 > minIndex+checkOff {\n\t\t\t\t\t\t\t\tlength := matchLen(d.window[prevIndex+checkOff:end], d.window[ch2+checkOff:])\n\t\t\t\t\t\t\t\t// It seems like a pure length metric is best.\n\t\t\t\t\t\t\t\tif length > prevLength+checkOff {\n\t\t\t\t\t\t\t\t\tprevLength = length\n\t\t\t\t\t\t\t\t\tprevOffset = prevIndex - ch2\n\t\t\t\t\t\t\t\t\tprevIndex--\n\n\t\t\t\t\t\t\t\t\t// Extend back...\n\t\t\t\t\t\t\t\t\tfor i := checkOff; i >= 0; i-- {\n\t\t\t\t\t\t\t\t\t\tif prevLength >= maxMatchLength || d.window[prevIndex+i] != d.window[ch2+i-1] {\n\t\t\t\t\t\t\t\t\t\t\t// Emit tokens we \"owe\"\n\t\t\t\t\t\t\t\t\t\t\tfor j := 0; j <= i; j++ {\n\t\t\t\t\t\t\t\t\t\t\t\td.tokens.AddLiteral(d.window[prevIndex+j])\n\t\t\t\t\t\t\t\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\t\t\t\t\t\t\t\t// The block includes the current character\n\t\t\t\t\t\t\t\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\td.tokens.Reset()\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\ts.index++\n\t\t\t\t\t\t\t\t\t\t\t\tif s.index < s.maxInsertIndex {\n\t\t\t\t\t\t\t\t\t\t\t\t\th := hash4(d.window[s.index:])\n\t\t\t\t\t\t\t\t\t\t\t\t\tch := s.hashHead[h]\n\t\t\t\t\t\t\t\t\t\t\t\t\ts.chainHead = int(ch)\n\t\t\t\t\t\t\t\t\t\t\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\t\t\t\t\t\t\t\t\t\t\ts.hashHead[h] = uint32(s.index + s.hashOffset)\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tprevLength++\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\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\t// There was a match at the previous step, and the current match is\n\t\t\t// not better. Output the previous match.\n\t\t\td.tokens.AddMatch(uint32(prevLength-3), uint32(prevOffset-minOffsetSize))\n\n\t\t\t// Insert in the hash table all strings up to the end of the match.\n\t\t\t// index and index-1 are already inserted. If there is not enough\n\t\t\t// lookahead, the last two strings are not inserted into the hash\n\t\t\t// table.\n\t\t\tnewIndex := s.index + prevLength - 1\n\t\t\t// Calculate missing hashes\n\t\t\tend := newIndex\n\t\t\tif end > s.maxInsertIndex {\n\t\t\t\tend = s.maxInsertIndex\n\t\t\t}\n\t\t\tend += minMatchLength - 1\n\t\t\tstartindex := s.index + 1\n\t\t\tif startindex > s.maxInsertIndex {\n\t\t\t\tstartindex = s.maxInsertIndex\n\t\t\t}\n\t\t\ttocheck := d.window[startindex:end]\n\t\t\tdstSize := len(tocheck) - minMatchLength + 1\n\t\t\tif dstSize > 0 {\n\t\t\t\tdst := s.hashMatch[:dstSize]\n\t\t\t\tbulkHash4(tocheck, dst)\n\t\t\t\tvar newH uint32\n\t\t\t\tfor i, val := range dst {\n\t\t\t\t\tdi := i + startindex\n\t\t\t\t\tnewH = val & hashMask\n\t\t\t\t\t// Get previous value with the same hash.\n\t\t\t\t\t// Our chain should point to the previous value.\n\t\t\t\t\ts.hashPrev[di&windowMask] = s.hashHead[newH]\n\t\t\t\t\t// Set the head of the hash chain to us.\n\t\t\t\t\ts.hashHead[newH] = uint32(di + s.hashOffset)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ts.index = newIndex\n\t\t\td.byteAvailable = false\n\t\t\ts.length = minMatchLength - 1\n\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t// The block includes the current character\n\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\td.tokens.Reset()\n\t\t\t}\n\t\t\ts.ii = 0\n\t\t} else {\n\t\t\t// Reset, if we got a match this run.\n\t\t\tif s.length >= minMatchLength {\n\t\t\t\ts.ii = 0\n\t\t\t}\n\t\t\t// We have a byte waiting. Emit it.\n\t\t\tif d.byteAvailable {\n\t\t\t\ts.ii++\n\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\td.tokens.Reset()\n\t\t\t\t}\n\t\t\t\ts.index++\n\n\t\t\t\t// If we have a long run of no matches, skip additional bytes\n\t\t\t\t// Resets when s.ii overflows after 64KB.\n\t\t\t\tif n := int(s.ii) - d.chain; n > 0 {\n\t\t\t\t\tn = 1 + int(n>>6)\n\t\t\t\t\tfor j := 0; j < n; j++ {\n\t\t\t\t\t\tif s.index >= d.windowEnd-1 {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\td.tokens.Reset()\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Index...\n\t\t\t\t\t\tif s.index < s.maxInsertIndex {\n\t\t\t\t\t\t\th := hash4(d.window[s.index:])\n\t\t\t\t\t\t\tch := s.hashHead[h]\n\t\t\t\t\t\t\ts.chainHead = int(ch)\n\t\t\t\t\t\t\ts.hashPrev[s.index&windowMask] = ch\n\t\t\t\t\t\t\ts.hashHead[h] = uint32(s.index + s.hashOffset)\n\t\t\t\t\t\t}\n\t\t\t\t\t\ts.index++\n\t\t\t\t\t}\n\t\t\t\t\t// Flush last byte\n\t\t\t\t\td.tokens.AddLiteral(d.window[s.index-1])\n\t\t\t\t\td.byteAvailable = false\n\t\t\t\t\t// s.length = minMatchLength - 1 // not needed, since s.ii is reset above, so it should never be > minMatchLength\n\t\t\t\t\tif d.tokens.n == maxFlateBlockTokens {\n\t\t\t\t\t\tif d.err = d.writeBlock(&d.tokens, s.index, false); d.err != nil {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\td.tokens.Reset()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ts.index++\n\t\t\t\td.byteAvailable = true\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (d *compressor) store() {\n\tif d.windowEnd > 0 && (d.windowEnd == maxStoreBlockSize || d.sync) {\n\t\td.err = d.writeStoredBlock(d.window[:d.windowEnd])\n\t\td.windowEnd = 0\n\t}\n}\n\n// fillWindow will fill the buffer with data for huffman-only compression.\n// The number of bytes copied is returned.\nfunc (d *compressor) fillBlock(b []byte) int {\n\tn := copy(d.window[d.windowEnd:], b)\n\td.windowEnd += n\n\treturn n\n}\n\n// storeHuff will compress and store the currently added data,\n// if enough has been accumulated or we at the end of the stream.\n// Any error that occurred will be in d.err\nfunc (d *compressor) storeHuff() {\n\tif d.windowEnd < len(d.window) && !d.sync || d.windowEnd == 0 {\n\t\treturn\n\t}\n\td.w.writeBlockHuff(false, d.window[:d.windowEnd], d.sync)\n\td.err = d.w.err\n\td.windowEnd = 0\n}\n\n// storeFast will compress and store the currently added data,\n// if enough has been accumulated or we at the end of the stream.\n// Any error that occurred will be in d.err\nfunc (d *compressor) storeFast() {\n\t// We only compress if we have maxStoreBlockSize.\n\tif d.windowEnd < len(d.window) {\n\t\tif !d.sync {\n\t\t\treturn\n\t\t}\n\t\t// Handle extremely small sizes.\n\t\tif d.windowEnd < 128 {\n\t\t\tif d.windowEnd == 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif d.windowEnd <= 32 {\n\t\t\t\td.err = d.writeStoredBlock(d.window[:d.windowEnd])\n\t\t\t} else {\n\t\t\t\td.w.writeBlockHuff(false, d.window[:d.windowEnd], true)\n\t\t\t\td.err = d.w.err\n\t\t\t}\n\t\t\td.tokens.Reset()\n\t\t\td.windowEnd = 0\n\t\t\td.fast.Reset()\n\t\t\treturn\n\t\t}\n\t}\n\n\td.fast.Encode(&d.tokens, d.window[:d.windowEnd])\n\t// If we made zero matches, store the block as is.\n\tif d.tokens.n == 0 {\n\t\td.err = d.writeStoredBlock(d.window[:d.windowEnd])\n\t\t// If we removed less than 1/16th, huffman compress the block.\n\t} else if int(d.tokens.n) > d.windowEnd-(d.windowEnd>>4) {\n\t\td.w.writeBlockHuff(false, d.window[:d.windowEnd], d.sync)\n\t\td.err = d.w.err\n\t} else {\n\t\td.w.writeBlockDynamic(&d.tokens, false, d.window[:d.windowEnd], d.sync)\n\t\td.err = d.w.err\n\t}\n\td.tokens.Reset()\n\td.windowEnd = 0\n}\n\n// write will add input byte to the stream.\n// Unless an error occurs all bytes will be consumed.\nfunc (d *compressor) write(b []byte) (n int, err error) {\n\tif d.err != nil {\n\t\treturn 0, d.err\n\t}\n\tn = len(b)\n\tfor len(b) > 0 {\n\t\tif d.windowEnd == len(d.window) || d.sync {\n\t\t\td.step(d)\n\t\t}\n\t\tb = b[d.fill(d, b):]\n\t\tif d.err != nil {\n\t\t\treturn 0, d.err\n\t\t}\n\t}\n\treturn n, d.err\n}\n\nfunc (d *compressor) syncFlush() error {\n\td.sync = true\n\tif d.err != nil {\n\t\treturn d.err\n\t}\n\td.step(d)\n\tif d.err == nil {\n\t\td.w.writeStoredHeader(0, false)\n\t\td.w.flush()\n\t\td.err = d.w.err\n\t}\n\td.sync = false\n\treturn d.err\n}\n\nfunc (d *compressor) init(w io.Writer, level int) (err error) {\n\td.w = newHuffmanBitWriter(w)\n\n\tswitch {\n\tcase level == NoCompression:\n\t\td.window = make([]byte, maxStoreBlockSize)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).store\n\tcase level == ConstantCompression:\n\t\td.w.logNewTablePenalty = 10\n\t\td.window = make([]byte, 32<<10)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).storeHuff\n\tcase level == DefaultCompression:\n\t\tlevel = 5\n\t\tfallthrough\n\tcase level >= 1 && level <= 6:\n\t\td.w.logNewTablePenalty = 7\n\t\td.fast = newFastEnc(level)\n\t\td.window = make([]byte, maxStoreBlockSize)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).storeFast\n\tcase 7 <= level && level <= 9:\n\t\td.w.logNewTablePenalty = 8\n\t\td.state = &advancedState{}\n\t\td.compressionLevel = levels[level]\n\t\td.initDeflate()\n\t\td.fill = (*compressor).fillDeflate\n\t\td.step = (*compressor).deflateLazy\n\tcase -level >= MinCustomWindowSize && -level <= MaxCustomWindowSize:\n\t\td.w.logNewTablePenalty = 7\n\t\td.fast = &fastEncL5Window{maxOffset: int32(-level), cur: maxStoreBlockSize}\n\t\td.window = make([]byte, maxStoreBlockSize)\n\t\td.fill = (*compressor).fillBlock\n\t\td.step = (*compressor).storeFast\n\tdefault:\n\t\treturn fmt.Errorf(\"flate: invalid compression level %d: want value in range [-2, 9]\", level)\n\t}\n\td.level = level\n\treturn nil\n}\n\n// reset the state of the compressor.\nfunc (d *compressor) reset(w io.Writer) {\n\td.w.reset(w)\n\td.sync = false\n\td.err = nil\n\t// We only need to reset a few things for Snappy.\n\tif d.fast != nil {\n\t\td.fast.Reset()\n\t\td.windowEnd = 0\n\t\td.tokens.Reset()\n\t\treturn\n\t}\n\tswitch d.compressionLevel.chain {\n\tcase 0:\n\t\t// level was NoCompression or ConstantCompresssion.\n\t\td.windowEnd = 0\n\tdefault:\n\t\ts := d.state\n\t\ts.chainHead = -1\n\t\tfor i := range s.hashHead {\n\t\t\ts.hashHead[i] = 0\n\t\t}\n\t\tfor i := range s.hashPrev {\n\t\t\ts.hashPrev[i] = 0\n\t\t}\n\t\ts.hashOffset = 1\n\t\ts.index, d.windowEnd = 0, 0\n\t\td.blockStart, d.byteAvailable = 0, false\n\t\td.tokens.Reset()\n\t\ts.length = minMatchLength - 1\n\t\ts.offset = 0\n\t\ts.ii = 0\n\t\ts.maxInsertIndex = 0\n\t}\n}\n\nfunc (d *compressor) close() error {\n\tif d.err != nil {\n\t\treturn d.err\n\t}\n\td.sync = true\n\td.step(d)\n\tif d.err != nil {\n\t\treturn d.err\n\t}\n\tif d.w.writeStoredHeader(0, true); d.w.err != nil {\n\t\treturn d.w.err\n\t}\n\td.w.flush()\n\td.w.reset(nil)\n\treturn d.w.err\n}\n\n// NewWriter returns a new Writer compressing data at the given level.\n// Following zlib, levels range from 1 (BestSpeed) to 9 (BestCompression);\n// higher levels typically run slower but compress more.\n// Level 0 (NoCompression) does not attempt any compression; it only adds the\n// necessary DEFLATE framing.\n// Level -1 (DefaultCompression) uses the default compression level.\n// Level -2 (ConstantCompression) will use Huffman compression only, giving\n// a very fast compression for all types of input, but sacrificing considerable\n// compression efficiency.\n//\n// If level is in the range [-2, 9] then the error returned will be nil.\n// Otherwise the error returned will be non-nil.\nfunc NewWriter(w io.Writer, level int) (*Writer, error) {\n\tvar dw Writer\n\tif err := dw.d.init(w, level); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &dw, nil\n}\n\n// NewWriterDict is like NewWriter but initializes the new\n// Writer with a preset dictionary.  The returned Writer behaves\n// as if the dictionary had been written to it without producing\n// any compressed output.  The compressed data written to w\n// can only be decompressed by a Reader initialized with the\n// same dictionary.\nfunc NewWriterDict(w io.Writer, level int, dict []byte) (*Writer, error) {\n\tzw, err := NewWriter(w, level)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tzw.d.fillWindow(dict)\n\tzw.dict = append(zw.dict, dict...) // duplicate dictionary for Reset method.\n\treturn zw, err\n}\n\n// MinCustomWindowSize is the minimum window size that can be sent to NewWriterWindow.\nconst MinCustomWindowSize = 32\n\n// MaxCustomWindowSize is the maximum custom window that can be sent to NewWriterWindow.\nconst MaxCustomWindowSize = windowSize\n\n// NewWriterWindow returns a new Writer compressing data with a custom window size.\n// windowSize must be from MinCustomWindowSize to MaxCustomWindowSize.\nfunc NewWriterWindow(w io.Writer, windowSize int) (*Writer, error) {\n\tif windowSize < MinCustomWindowSize {\n\t\treturn nil, errors.New(\"flate: requested window size less than MinWindowSize\")\n\t}\n\tif windowSize > MaxCustomWindowSize {\n\t\treturn nil, errors.New(\"flate: requested window size bigger than MaxCustomWindowSize\")\n\t}\n\tvar dw Writer\n\tif err := dw.d.init(w, -windowSize); err != nil {\n\t\treturn nil, err\n\t}\n\treturn &dw, nil\n}\n\n// A Writer takes data written to it and writes the compressed\n// form of that data to an underlying writer (see NewWriter).\ntype Writer struct {\n\td    compressor\n\tdict []byte\n}\n\n// Write writes data to w, which will eventually write the\n// compressed form of data to its underlying writer.\nfunc (w *Writer) Write(data []byte) (n int, err error) {\n\treturn w.d.write(data)\n}\n\n// Flush flushes any pending data to the underlying writer.\n// It is useful mainly in compressed network protocols, to ensure that\n// a remote reader has enough data to reconstruct a packet.\n// Flush does not return until the data has been written.\n// Calling Flush when there is no pending data still causes the Writer\n// to emit a sync marker of at least 4 bytes.\n// If the underlying writer returns an error, Flush returns that error.\n//\n// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.\nfunc (w *Writer) Flush() error {\n\t// For more about flushing:\n\t// http://www.bolet.org/~pornin/deflate-flush.html\n\treturn w.d.syncFlush()\n}\n\n// Close flushes and closes the writer.\nfunc (w *Writer) Close() error {\n\treturn w.d.close()\n}\n\n// Reset discards the writer's state and makes it equivalent to\n// the result of NewWriter or NewWriterDict called with dst\n// and w's level and dictionary.\nfunc (w *Writer) Reset(dst io.Writer) {\n\tif len(w.dict) > 0 {\n\t\t// w was created with NewWriterDict\n\t\tw.d.reset(dst)\n\t\tif dst != nil {\n\t\t\tw.d.fillWindow(w.dict)\n\t\t}\n\t} else {\n\t\t// w was created with NewWriter\n\t\tw.d.reset(dst)\n\t}\n}\n\n// ResetDict discards the writer's state and makes it equivalent to\n// the result of NewWriter or NewWriterDict called with dst\n// and w's level, but sets a specific dictionary.\nfunc (w *Writer) ResetDict(dst io.Writer, dict []byte) {\n\tw.dict = dict\n\tw.d.reset(dst)\n\tw.d.fillWindow(w.dict)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/dict_decoder.go",
    "content": "// Copyright 2016 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 flate\n\n// dictDecoder implements the LZ77 sliding dictionary as used in decompression.\n// LZ77 decompresses data through sequences of two forms of commands:\n//\n//   - Literal insertions: Runs of one or more symbols are inserted into the data\n//     stream as is. This is accomplished through the writeByte method for a\n//     single symbol, or combinations of writeSlice/writeMark for multiple symbols.\n//     Any valid stream must start with a literal insertion if no preset dictionary\n//     is used.\n//\n//   - Backward copies: Runs of one or more symbols are copied from previously\n//     emitted data. Backward copies come as the tuple (dist, length) where dist\n//     determines how far back in the stream to copy from and length determines how\n//     many bytes to copy. Note that it is valid for the length to be greater than\n//     the distance. Since LZ77 uses forward copies, that situation is used to\n//     perform a form of run-length encoding on repeated runs of symbols.\n//     The writeCopy and tryWriteCopy are used to implement this command.\n//\n// For performance reasons, this implementation performs little to no sanity\n// checks about the arguments. As such, the invariants documented for each\n// method call must be respected.\ntype dictDecoder struct {\n\thist []byte // Sliding window history\n\n\t// Invariant: 0 <= rdPos <= wrPos <= len(hist)\n\twrPos int  // Current output position in buffer\n\trdPos int  // Have emitted hist[:rdPos] already\n\tfull  bool // Has a full window length been written yet?\n}\n\n// init initializes dictDecoder to have a sliding window dictionary of the given\n// size. If a preset dict is provided, it will initialize the dictionary with\n// the contents of dict.\nfunc (dd *dictDecoder) init(size int, dict []byte) {\n\t*dd = dictDecoder{hist: dd.hist}\n\n\tif cap(dd.hist) < size {\n\t\tdd.hist = make([]byte, size)\n\t}\n\tdd.hist = dd.hist[:size]\n\n\tif len(dict) > len(dd.hist) {\n\t\tdict = dict[len(dict)-len(dd.hist):]\n\t}\n\tdd.wrPos = copy(dd.hist, dict)\n\tif dd.wrPos == len(dd.hist) {\n\t\tdd.wrPos = 0\n\t\tdd.full = true\n\t}\n\tdd.rdPos = dd.wrPos\n}\n\n// histSize reports the total amount of historical data in the dictionary.\nfunc (dd *dictDecoder) histSize() int {\n\tif dd.full {\n\t\treturn len(dd.hist)\n\t}\n\treturn dd.wrPos\n}\n\n// availRead reports the number of bytes that can be flushed by readFlush.\nfunc (dd *dictDecoder) availRead() int {\n\treturn dd.wrPos - dd.rdPos\n}\n\n// availWrite reports the available amount of output buffer space.\nfunc (dd *dictDecoder) availWrite() int {\n\treturn len(dd.hist) - dd.wrPos\n}\n\n// writeSlice returns a slice of the available buffer to write data to.\n//\n// This invariant will be kept: len(s) <= availWrite()\nfunc (dd *dictDecoder) writeSlice() []byte {\n\treturn dd.hist[dd.wrPos:]\n}\n\n// writeMark advances the writer pointer by cnt.\n//\n// This invariant must be kept: 0 <= cnt <= availWrite()\nfunc (dd *dictDecoder) writeMark(cnt int) {\n\tdd.wrPos += cnt\n}\n\n// writeByte writes a single byte to the dictionary.\n//\n// This invariant must be kept: 0 < availWrite()\nfunc (dd *dictDecoder) writeByte(c byte) {\n\tdd.hist[dd.wrPos] = c\n\tdd.wrPos++\n}\n\n// writeCopy copies a string at a given (dist, length) to the output.\n// This returns the number of bytes copied and may be less than the requested\n// length if the available space in the output buffer is too small.\n//\n// This invariant must be kept: 0 < dist <= histSize()\nfunc (dd *dictDecoder) writeCopy(dist, length int) int {\n\tdstBase := dd.wrPos\n\tdstPos := dstBase\n\tsrcPos := dstPos - dist\n\tendPos := dstPos + length\n\tif endPos > len(dd.hist) {\n\t\tendPos = len(dd.hist)\n\t}\n\n\t// Copy non-overlapping section after destination position.\n\t//\n\t// This section is non-overlapping in that the copy length for this section\n\t// is always less than or equal to the backwards distance. This can occur\n\t// if a distance refers to data that wraps-around in the buffer.\n\t// Thus, a backwards copy is performed here; that is, the exact bytes in\n\t// the source prior to the copy is placed in the destination.\n\tif srcPos < 0 {\n\t\tsrcPos += len(dd.hist)\n\t\tdstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:])\n\t\tsrcPos = 0\n\t}\n\n\t// Copy possibly overlapping section before destination position.\n\t//\n\t// This section can overlap if the copy length for this section is larger\n\t// than the backwards distance. This is allowed by LZ77 so that repeated\n\t// strings can be succinctly represented using (dist, length) pairs.\n\t// Thus, a forwards copy is performed here; that is, the bytes copied is\n\t// possibly dependent on the resulting bytes in the destination as the copy\n\t// progresses along. This is functionally equivalent to the following:\n\t//\n\t//\tfor i := 0; i < endPos-dstPos; i++ {\n\t//\t\tdd.hist[dstPos+i] = dd.hist[srcPos+i]\n\t//\t}\n\t//\tdstPos = endPos\n\t//\n\tfor dstPos < endPos {\n\t\tdstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos])\n\t}\n\n\tdd.wrPos = dstPos\n\treturn dstPos - dstBase\n}\n\n// tryWriteCopy tries to copy a string at a given (distance, length) to the\n// output. This specialized version is optimized for short distances.\n//\n// This method is designed to be inlined for performance reasons.\n//\n// This invariant must be kept: 0 < dist <= histSize()\nfunc (dd *dictDecoder) tryWriteCopy(dist, length int) int {\n\tdstPos := dd.wrPos\n\tendPos := dstPos + length\n\tif dstPos < dist || endPos > len(dd.hist) {\n\t\treturn 0\n\t}\n\tdstBase := dstPos\n\tsrcPos := dstPos - dist\n\n\t// Copy possibly overlapping section before destination position.\nloop:\n\tdstPos += copy(dd.hist[dstPos:endPos], dd.hist[srcPos:dstPos])\n\tif dstPos < endPos {\n\t\tgoto loop // Avoid for-loop so that this function can be inlined\n\t}\n\n\tdd.wrPos = dstPos\n\treturn dstPos - dstBase\n}\n\n// readFlush returns a slice of the historical buffer that is ready to be\n// emitted to the user. The data returned by readFlush must be fully consumed\n// before calling any other dictDecoder methods.\nfunc (dd *dictDecoder) readFlush() []byte {\n\ttoRead := dd.hist[dd.rdPos:dd.wrPos]\n\tdd.rdPos = dd.wrPos\n\tif dd.wrPos == len(dd.hist) {\n\t\tdd.wrPos, dd.rdPos = 0, 0\n\t\tdd.full = true\n\t}\n\treturn toRead\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/fast_encoder.go",
    "content": "// Copyright 2011 The Snappy-Go Authors. All rights reserved.\n// Modified for deflate by Klaus Post (c) 2015.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage flate\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n)\n\ntype fastEnc interface {\n\tEncode(dst *tokens, src []byte)\n\tReset()\n}\n\nfunc newFastEnc(level int) fastEnc {\n\tswitch level {\n\tcase 1:\n\t\treturn &fastEncL1{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 2:\n\t\treturn &fastEncL2{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 3:\n\t\treturn &fastEncL3{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 4:\n\t\treturn &fastEncL4{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 5:\n\t\treturn &fastEncL5{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tcase 6:\n\t\treturn &fastEncL6{fastGen: fastGen{cur: maxStoreBlockSize}}\n\tdefault:\n\t\tpanic(\"invalid level specified\")\n\t}\n}\n\nconst (\n\ttableBits       = 15             // Bits used in the table\n\ttableSize       = 1 << tableBits // Size of the table\n\ttableShift      = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32.\n\tbaseMatchOffset = 1              // The smallest match offset\n\tbaseMatchLength = 3              // The smallest match length per the RFC section 3.2.5\n\tmaxMatchOffset  = 1 << 15        // The largest match offset\n\n\tbTableBits   = 17                                               // Bits used in the big tables\n\tbTableSize   = 1 << bTableBits                                  // Size of the table\n\tallocHistory = maxStoreBlockSize * 5                            // Size to preallocate for history.\n\tbufferReset  = (1 << 31) - allocHistory - maxStoreBlockSize - 1 // Reset the buffer offset when reaching this.\n)\n\nconst (\n\tprime3bytes = 506832829\n\tprime4bytes = 2654435761\n\tprime5bytes = 889523592379\n\tprime6bytes = 227718039650203\n\tprime7bytes = 58295818150454627\n\tprime8bytes = 0xcf1bbcdcb7a56463\n)\n\nfunc load3232(b []byte, i int32) uint32 {\n\treturn binary.LittleEndian.Uint32(b[i:])\n}\n\nfunc load6432(b []byte, i int32) uint64 {\n\treturn binary.LittleEndian.Uint64(b[i:])\n}\n\ntype tableEntry struct {\n\toffset int32\n}\n\n// fastGen maintains the table for matches,\n// and the previous byte block for level 2.\n// This is the generic implementation.\ntype fastGen struct {\n\thist []byte\n\tcur  int32\n}\n\nfunc (e *fastGen) addBlock(src []byte) int32 {\n\t// check if we have space already\n\tif len(e.hist)+len(src) > cap(e.hist) {\n\t\tif cap(e.hist) == 0 {\n\t\t\te.hist = make([]byte, 0, allocHistory)\n\t\t} else {\n\t\t\tif cap(e.hist) < maxMatchOffset*2 {\n\t\t\t\tpanic(\"unexpected buffer size\")\n\t\t\t}\n\t\t\t// Move down\n\t\t\toffset := int32(len(e.hist)) - maxMatchOffset\n\t\t\t// copy(e.hist[0:maxMatchOffset], e.hist[offset:])\n\t\t\t*(*[maxMatchOffset]byte)(e.hist) = *(*[maxMatchOffset]byte)(e.hist[offset:])\n\t\t\te.cur += offset\n\t\t\te.hist = e.hist[:maxMatchOffset]\n\t\t}\n\t}\n\ts := int32(len(e.hist))\n\te.hist = append(e.hist, src...)\n\treturn s\n}\n\ntype tableEntryPrev struct {\n\tCur  tableEntry\n\tPrev tableEntry\n}\n\n// hash7 returns the hash of the lowest 7 bytes of u to fit in a hash table with h bits.\n// Preferably h should be a constant and should always be <64.\nfunc hash7(u uint64, h uint8) uint32 {\n\treturn uint32(((u << (64 - 56)) * prime7bytes) >> ((64 - h) & reg8SizeMask64))\n}\n\n// hashLen returns a hash of the lowest mls bytes of with length output bits.\n// mls must be >=3 and <=8. Any other value will return hash for 4 bytes.\n// length should always be < 32.\n// Preferably length and mls should be a constant for inlining.\nfunc hashLen(u uint64, length, mls uint8) uint32 {\n\tswitch mls {\n\tcase 3:\n\t\treturn (uint32(u<<8) * prime3bytes) >> (32 - length)\n\tcase 5:\n\t\treturn uint32(((u << (64 - 40)) * prime5bytes) >> (64 - length))\n\tcase 6:\n\t\treturn uint32(((u << (64 - 48)) * prime6bytes) >> (64 - length))\n\tcase 7:\n\t\treturn uint32(((u << (64 - 56)) * prime7bytes) >> (64 - length))\n\tcase 8:\n\t\treturn uint32((u * prime8bytes) >> (64 - length))\n\tdefault:\n\t\treturn (uint32(u) * prime4bytes) >> (32 - length)\n\t}\n}\n\n// matchlen will return the match length between offsets and t in src.\n// The maximum length returned is maxMatchLength - 4.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastGen) matchlen(s, t int32, src []byte) int32 {\n\tif debugDecode {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > maxMatchOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\ts1 := int(s) + maxMatchLength - 4\n\tif s1 > len(src) {\n\t\ts1 = len(src)\n\t}\n\n\t// Extend the match to be as long as possible.\n\treturn int32(matchLen(src[s:s1], src[t:]))\n}\n\n// matchlenLong will return the match length between offsets and t in src.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastGen) matchlenLong(s, t int32, src []byte) int32 {\n\tif debugDeflate {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > maxMatchOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\t// Extend the match to be as long as possible.\n\treturn int32(matchLen(src[s:], src[t:]))\n}\n\n// Reset the encoding table.\nfunc (e *fastGen) Reset() {\n\tif cap(e.hist) < allocHistory {\n\t\te.hist = make([]byte, 0, allocHistory)\n\t}\n\t// We offset current position so everything will be out of reach.\n\t// If we are above the buffer reset it will be cleared anyway since len(hist) == 0.\n\tif e.cur <= bufferReset {\n\t\te.cur += maxMatchOffset + int32(len(e.hist))\n\t}\n\te.hist = e.hist[:0]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_bit_writer.go",
    "content": "// Copyright 2009 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 flate\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n)\n\nconst (\n\t// The largest offset code.\n\toffsetCodeCount = 30\n\n\t// The special code used to mark the end of a block.\n\tendBlockMarker = 256\n\n\t// The first length code.\n\tlengthCodesStart = 257\n\n\t// The number of codegen codes.\n\tcodegenCodeCount = 19\n\tbadCode          = 255\n\n\t// maxPredefinedTokens is the maximum number of tokens\n\t// where we check if fixed size is smaller.\n\tmaxPredefinedTokens = 250\n\n\t// bufferFlushSize indicates the buffer size\n\t// after which bytes are flushed to the writer.\n\t// Should preferably be a multiple of 6, since\n\t// we accumulate 6 bytes between writes to the buffer.\n\tbufferFlushSize = 246\n)\n\n// Minimum length code that emits bits.\nconst lengthExtraBitsMinCode = 8\n\n// The number of extra bits needed by length code X - LENGTH_CODES_START.\nvar lengthExtraBits = [32]uint8{\n\t/* 257 */ 0, 0, 0,\n\t/* 260 */ 0, 0, 0, 0, 0, 1, 1, 1, 1, 2,\n\t/* 270 */ 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,\n\t/* 280 */ 4, 5, 5, 5, 5, 0,\n}\n\n// The length indicated by length code X - LENGTH_CODES_START.\nvar lengthBase = [32]uint8{\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 10,\n\t12, 14, 16, 20, 24, 28, 32, 40, 48, 56,\n\t64, 80, 96, 112, 128, 160, 192, 224, 255,\n}\n\n// Minimum offset code that emits bits.\nconst offsetExtraBitsMinCode = 4\n\n// offset code word extra bits.\nvar offsetExtraBits = [32]int8{\n\t0, 0, 0, 0, 1, 1, 2, 2, 3, 3,\n\t4, 4, 5, 5, 6, 6, 7, 7, 8, 8,\n\t9, 9, 10, 10, 11, 11, 12, 12, 13, 13,\n\t/* extended window */\n\t14, 14,\n}\n\nvar offsetCombined = [32]uint32{}\n\nfunc init() {\n\tvar offsetBase = [32]uint32{\n\t\t/* normal deflate */\n\t\t0x000000, 0x000001, 0x000002, 0x000003, 0x000004,\n\t\t0x000006, 0x000008, 0x00000c, 0x000010, 0x000018,\n\t\t0x000020, 0x000030, 0x000040, 0x000060, 0x000080,\n\t\t0x0000c0, 0x000100, 0x000180, 0x000200, 0x000300,\n\t\t0x000400, 0x000600, 0x000800, 0x000c00, 0x001000,\n\t\t0x001800, 0x002000, 0x003000, 0x004000, 0x006000,\n\n\t\t/* extended window */\n\t\t0x008000, 0x00c000,\n\t}\n\n\tfor i := range offsetCombined[:] {\n\t\t// Don't use extended window values...\n\t\tif offsetExtraBits[i] == 0 || offsetBase[i] > 0x006000 {\n\t\t\tcontinue\n\t\t}\n\t\toffsetCombined[i] = uint32(offsetExtraBits[i]) | (offsetBase[i] << 8)\n\t}\n}\n\n// The odd order in which the codegen code sizes are written.\nvar codegenOrder = []uint32{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}\n\ntype huffmanBitWriter struct {\n\t// writer is the underlying writer.\n\t// Do not use it directly; use the write method, which ensures\n\t// that Write errors are sticky.\n\twriter io.Writer\n\n\t// Data waiting to be written is bytes[0:nbytes]\n\t// and then the low nbits of bits.\n\tbits            uint64\n\tnbits           uint8\n\tnbytes          uint8\n\tlastHuffMan     bool\n\tliteralEncoding *huffmanEncoder\n\ttmpLitEncoding  *huffmanEncoder\n\toffsetEncoding  *huffmanEncoder\n\tcodegenEncoding *huffmanEncoder\n\terr             error\n\tlastHeader      int\n\t// Set between 0 (reused block can be up to 2x the size)\n\tlogNewTablePenalty uint\n\tbytes              [256 + 8]byte\n\tliteralFreq        [lengthCodesStart + 32]uint16\n\toffsetFreq         [32]uint16\n\tcodegenFreq        [codegenCodeCount]uint16\n\n\t// codegen must have an extra space for the final symbol.\n\tcodegen [literalCount + offsetCodeCount + 1]uint8\n}\n\n// Huffman reuse.\n//\n// The huffmanBitWriter supports reusing huffman tables and thereby combining block sections.\n//\n// This is controlled by several variables:\n//\n// If lastHeader is non-zero the Huffman table can be reused.\n// This also indicates that a Huffman table has been generated that can output all\n// possible symbols.\n// It also indicates that an EOB has not yet been emitted, so if a new tabel is generated\n// an EOB with the previous table must be written.\n//\n// If lastHuffMan is set, a table for outputting literals has been generated and offsets are invalid.\n//\n// An incoming block estimates the output size of a new table using a 'fresh' by calculating the\n// optimal size and adding a penalty in 'logNewTablePenalty'.\n// A Huffman table is not optimal, which is why we add a penalty, and generating a new table\n// is slower both for compression and decompression.\n\nfunc newHuffmanBitWriter(w io.Writer) *huffmanBitWriter {\n\treturn &huffmanBitWriter{\n\t\twriter:          w,\n\t\tliteralEncoding: newHuffmanEncoder(literalCount),\n\t\ttmpLitEncoding:  newHuffmanEncoder(literalCount),\n\t\tcodegenEncoding: newHuffmanEncoder(codegenCodeCount),\n\t\toffsetEncoding:  newHuffmanEncoder(offsetCodeCount),\n\t}\n}\n\nfunc (w *huffmanBitWriter) reset(writer io.Writer) {\n\tw.writer = writer\n\tw.bits, w.nbits, w.nbytes, w.err = 0, 0, 0, nil\n\tw.lastHeader = 0\n\tw.lastHuffMan = false\n}\n\nfunc (w *huffmanBitWriter) canReuse(t *tokens) (ok bool) {\n\ta := t.offHist[:offsetCodeCount]\n\tb := w.offsetEncoding.codes\n\tb = b[:len(a)]\n\tfor i, v := range a {\n\t\tif v != 0 && b[i].zero() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\ta = t.extraHist[:literalCount-256]\n\tb = w.literalEncoding.codes[256:literalCount]\n\tb = b[:len(a)]\n\tfor i, v := range a {\n\t\tif v != 0 && b[i].zero() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\ta = t.litHist[:256]\n\tb = w.literalEncoding.codes[:len(a)]\n\tfor i, v := range a {\n\t\tif v != 0 && b[i].zero() {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (w *huffmanBitWriter) flush() {\n\tif w.err != nil {\n\t\tw.nbits = 0\n\t\treturn\n\t}\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\tn := w.nbytes\n\tfor w.nbits != 0 {\n\t\tw.bytes[n] = byte(w.bits)\n\t\tw.bits >>= 8\n\t\tif w.nbits > 8 { // Avoid underflow\n\t\t\tw.nbits -= 8\n\t\t} else {\n\t\t\tw.nbits = 0\n\t\t}\n\t\tn++\n\t}\n\tw.bits = 0\n\tw.write(w.bytes[:n])\n\tw.nbytes = 0\n}\n\nfunc (w *huffmanBitWriter) write(b []byte) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\t_, w.err = w.writer.Write(b)\n}\n\nfunc (w *huffmanBitWriter) writeBits(b int32, nb uint8) {\n\tw.bits |= uint64(b) << (w.nbits & 63)\n\tw.nbits += nb\n\tif w.nbits >= 48 {\n\t\tw.writeOutBits()\n\t}\n}\n\nfunc (w *huffmanBitWriter) writeBytes(bytes []byte) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tn := w.nbytes\n\tif w.nbits&7 != 0 {\n\t\tw.err = InternalError(\"writeBytes with unfinished bits\")\n\t\treturn\n\t}\n\tfor w.nbits != 0 {\n\t\tw.bytes[n] = byte(w.bits)\n\t\tw.bits >>= 8\n\t\tw.nbits -= 8\n\t\tn++\n\t}\n\tif n != 0 {\n\t\tw.write(w.bytes[:n])\n\t}\n\tw.nbytes = 0\n\tw.write(bytes)\n}\n\n// RFC 1951 3.2.7 specifies a special run-length encoding for specifying\n// the literal and offset lengths arrays (which are concatenated into a single\n// array).  This method generates that run-length encoding.\n//\n// The result is written into the codegen array, and the frequencies\n// of each code is written into the codegenFreq array.\n// Codes 0-15 are single byte codes. Codes 16-18 are followed by additional\n// information. Code badCode is an end marker\n//\n//\tnumLiterals      The number of literals in literalEncoding\n//\tnumOffsets       The number of offsets in offsetEncoding\n//\tlitenc, offenc   The literal and offset encoder to use\nfunc (w *huffmanBitWriter) generateCodegen(numLiterals int, numOffsets int, litEnc, offEnc *huffmanEncoder) {\n\tfor i := range w.codegenFreq {\n\t\tw.codegenFreq[i] = 0\n\t}\n\t// Note that we are using codegen both as a temporary variable for holding\n\t// a copy of the frequencies, and as the place where we put the result.\n\t// This is fine because the output is always shorter than the input used\n\t// so far.\n\tcodegen := w.codegen[:] // cache\n\t// Copy the concatenated code sizes to codegen. Put a marker at the end.\n\tcgnl := codegen[:numLiterals]\n\tfor i := range cgnl {\n\t\tcgnl[i] = litEnc.codes[i].len()\n\t}\n\n\tcgnl = codegen[numLiterals : numLiterals+numOffsets]\n\tfor i := range cgnl {\n\t\tcgnl[i] = offEnc.codes[i].len()\n\t}\n\tcodegen[numLiterals+numOffsets] = badCode\n\n\tsize := codegen[0]\n\tcount := 1\n\toutIndex := 0\n\tfor inIndex := 1; size != badCode; inIndex++ {\n\t\t// INVARIANT: We have seen \"count\" copies of size that have not yet\n\t\t// had output generated for them.\n\t\tnextSize := codegen[inIndex]\n\t\tif nextSize == size {\n\t\t\tcount++\n\t\t\tcontinue\n\t\t}\n\t\t// We need to generate codegen indicating \"count\" of size.\n\t\tif size != 0 {\n\t\t\tcodegen[outIndex] = size\n\t\t\toutIndex++\n\t\t\tw.codegenFreq[size]++\n\t\t\tcount--\n\t\t\tfor count >= 3 {\n\t\t\t\tn := 6\n\t\t\t\tif n > count {\n\t\t\t\t\tn = count\n\t\t\t\t}\n\t\t\t\tcodegen[outIndex] = 16\n\t\t\t\toutIndex++\n\t\t\t\tcodegen[outIndex] = uint8(n - 3)\n\t\t\t\toutIndex++\n\t\t\t\tw.codegenFreq[16]++\n\t\t\t\tcount -= n\n\t\t\t}\n\t\t} else {\n\t\t\tfor count >= 11 {\n\t\t\t\tn := 138\n\t\t\t\tif n > count {\n\t\t\t\t\tn = count\n\t\t\t\t}\n\t\t\t\tcodegen[outIndex] = 18\n\t\t\t\toutIndex++\n\t\t\t\tcodegen[outIndex] = uint8(n - 11)\n\t\t\t\toutIndex++\n\t\t\t\tw.codegenFreq[18]++\n\t\t\t\tcount -= n\n\t\t\t}\n\t\t\tif count >= 3 {\n\t\t\t\t// count >= 3 && count <= 10\n\t\t\t\tcodegen[outIndex] = 17\n\t\t\t\toutIndex++\n\t\t\t\tcodegen[outIndex] = uint8(count - 3)\n\t\t\t\toutIndex++\n\t\t\t\tw.codegenFreq[17]++\n\t\t\t\tcount = 0\n\t\t\t}\n\t\t}\n\t\tcount--\n\t\tfor ; count >= 0; count-- {\n\t\t\tcodegen[outIndex] = size\n\t\t\toutIndex++\n\t\t\tw.codegenFreq[size]++\n\t\t}\n\t\t// Set up invariant for next time through the loop.\n\t\tsize = nextSize\n\t\tcount = 1\n\t}\n\t// Marker indicating the end of the codegen.\n\tcodegen[outIndex] = badCode\n}\n\nfunc (w *huffmanBitWriter) codegens() int {\n\tnumCodegens := len(w.codegenFreq)\n\tfor numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {\n\t\tnumCodegens--\n\t}\n\treturn numCodegens\n}\n\nfunc (w *huffmanBitWriter) headerSize() (size, numCodegens int) {\n\tnumCodegens = len(w.codegenFreq)\n\tfor numCodegens > 4 && w.codegenFreq[codegenOrder[numCodegens-1]] == 0 {\n\t\tnumCodegens--\n\t}\n\treturn 3 + 5 + 5 + 4 + (3 * numCodegens) +\n\t\tw.codegenEncoding.bitLength(w.codegenFreq[:]) +\n\t\tint(w.codegenFreq[16])*2 +\n\t\tint(w.codegenFreq[17])*3 +\n\t\tint(w.codegenFreq[18])*7, numCodegens\n}\n\n// dynamicSize returns the size of dynamically encoded data in bits.\nfunc (w *huffmanBitWriter) dynamicReuseSize(litEnc, offEnc *huffmanEncoder) (size int) {\n\tsize = litEnc.bitLength(w.literalFreq[:]) +\n\t\toffEnc.bitLength(w.offsetFreq[:])\n\treturn size\n}\n\n// dynamicSize returns the size of dynamically encoded data in bits.\nfunc (w *huffmanBitWriter) dynamicSize(litEnc, offEnc *huffmanEncoder, extraBits int) (size, numCodegens int) {\n\theader, numCodegens := w.headerSize()\n\tsize = header +\n\t\tlitEnc.bitLength(w.literalFreq[:]) +\n\t\toffEnc.bitLength(w.offsetFreq[:]) +\n\t\textraBits\n\treturn size, numCodegens\n}\n\n// extraBitSize will return the number of bits that will be written\n// as \"extra\" bits on matches.\nfunc (w *huffmanBitWriter) extraBitSize() int {\n\ttotal := 0\n\tfor i, n := range w.literalFreq[257:literalCount] {\n\t\ttotal += int(n) * int(lengthExtraBits[i&31])\n\t}\n\tfor i, n := range w.offsetFreq[:offsetCodeCount] {\n\t\ttotal += int(n) * int(offsetExtraBits[i&31])\n\t}\n\treturn total\n}\n\n// fixedSize returns the size of dynamically encoded data in bits.\nfunc (w *huffmanBitWriter) fixedSize(extraBits int) int {\n\treturn 3 +\n\t\tfixedLiteralEncoding.bitLength(w.literalFreq[:]) +\n\t\tfixedOffsetEncoding.bitLength(w.offsetFreq[:]) +\n\t\textraBits\n}\n\n// storedSize calculates the stored size, including header.\n// The function returns the size in bits and whether the block\n// fits inside a single block.\nfunc (w *huffmanBitWriter) storedSize(in []byte) (int, bool) {\n\tif in == nil {\n\t\treturn 0, false\n\t}\n\tif len(in) <= maxStoreBlockSize {\n\t\treturn (len(in) + 5) * 8, true\n\t}\n\treturn 0, false\n}\n\nfunc (w *huffmanBitWriter) writeCode(c hcode) {\n\t// The function does not get inlined if we \"& 63\" the shift.\n\tw.bits |= c.code64() << (w.nbits & 63)\n\tw.nbits += c.len()\n\tif w.nbits >= 48 {\n\t\tw.writeOutBits()\n\t}\n}\n\n// writeOutBits will write bits to the buffer.\nfunc (w *huffmanBitWriter) writeOutBits() {\n\tbits := w.bits\n\tw.bits >>= 48\n\tw.nbits -= 48\n\tn := w.nbytes\n\n\t// We over-write, but faster...\n\tbinary.LittleEndian.PutUint64(w.bytes[n:], bits)\n\tn += 6\n\n\tif n >= bufferFlushSize {\n\t\tif w.err != nil {\n\t\t\tn = 0\n\t\t\treturn\n\t\t}\n\t\tw.write(w.bytes[:n])\n\t\tn = 0\n\t}\n\n\tw.nbytes = n\n}\n\n// Write the header of a dynamic Huffman block to the output stream.\n//\n//\tnumLiterals  The number of literals specified in codegen\n//\tnumOffsets   The number of offsets specified in codegen\n//\tnumCodegens  The number of codegens used in codegen\nfunc (w *huffmanBitWriter) writeDynamicHeader(numLiterals int, numOffsets int, numCodegens int, isEof bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tvar firstBits int32 = 4\n\tif isEof {\n\t\tfirstBits = 5\n\t}\n\tw.writeBits(firstBits, 3)\n\tw.writeBits(int32(numLiterals-257), 5)\n\tw.writeBits(int32(numOffsets-1), 5)\n\tw.writeBits(int32(numCodegens-4), 4)\n\n\tfor i := 0; i < numCodegens; i++ {\n\t\tvalue := uint(w.codegenEncoding.codes[codegenOrder[i]].len())\n\t\tw.writeBits(int32(value), 3)\n\t}\n\n\ti := 0\n\tfor {\n\t\tvar codeWord = uint32(w.codegen[i])\n\t\ti++\n\t\tif codeWord == badCode {\n\t\t\tbreak\n\t\t}\n\t\tw.writeCode(w.codegenEncoding.codes[codeWord])\n\n\t\tswitch codeWord {\n\t\tcase 16:\n\t\t\tw.writeBits(int32(w.codegen[i]), 2)\n\t\t\ti++\n\t\tcase 17:\n\t\t\tw.writeBits(int32(w.codegen[i]), 3)\n\t\t\ti++\n\t\tcase 18:\n\t\t\tw.writeBits(int32(w.codegen[i]), 7)\n\t\t\ti++\n\t\t}\n\t}\n}\n\n// writeStoredHeader will write a stored header.\n// If the stored block is only used for EOF,\n// it is replaced with a fixed huffman block.\nfunc (w *huffmanBitWriter) writeStoredHeader(length int, isEof bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\n\t// To write EOF, use a fixed encoding block. 10 bits instead of 5 bytes.\n\tif length == 0 && isEof {\n\t\tw.writeFixedHeader(isEof)\n\t\t// EOB: 7 bits, value: 0\n\t\tw.writeBits(0, 7)\n\t\tw.flush()\n\t\treturn\n\t}\n\n\tvar flag int32\n\tif isEof {\n\t\tflag = 1\n\t}\n\tw.writeBits(flag, 3)\n\tw.flush()\n\tw.writeBits(int32(length), 16)\n\tw.writeBits(int32(^uint16(length)), 16)\n}\n\nfunc (w *huffmanBitWriter) writeFixedHeader(isEof bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\n\t// Indicate that we are a fixed Huffman block\n\tvar value int32 = 2\n\tif isEof {\n\t\tvalue = 3\n\t}\n\tw.writeBits(value, 3)\n}\n\n// writeBlock will write a block of tokens with the smallest encoding.\n// The original input can be supplied, and if the huffman encoded data\n// is larger than the original bytes, the data will be written as a\n// stored block.\n// If the input is nil, the tokens will always be Huffman encoded.\nfunc (w *huffmanBitWriter) writeBlock(tokens *tokens, eof bool, input []byte) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\n\ttokens.AddEOB()\n\tif w.lastHeader > 0 {\n\t\t// We owe an EOB\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\tnumLiterals, numOffsets := w.indexTokens(tokens, false)\n\tw.generate()\n\tvar extraBits int\n\tstoredSize, storable := w.storedSize(input)\n\tif storable {\n\t\textraBits = w.extraBitSize()\n\t}\n\n\t// Figure out smallest code.\n\t// Fixed Huffman baseline.\n\tvar literalEncoding = fixedLiteralEncoding\n\tvar offsetEncoding = fixedOffsetEncoding\n\tvar size = math.MaxInt32\n\tif tokens.n < maxPredefinedTokens {\n\t\tsize = w.fixedSize(extraBits)\n\t}\n\n\t// Dynamic Huffman?\n\tvar numCodegens int\n\n\t// Generate codegen and codegenFrequencies, which indicates how to encode\n\t// the literalEncoding and the offsetEncoding.\n\tw.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)\n\tw.codegenEncoding.generate(w.codegenFreq[:], 7)\n\tdynamicSize, numCodegens := w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits)\n\n\tif dynamicSize < size {\n\t\tsize = dynamicSize\n\t\tliteralEncoding = w.literalEncoding\n\t\toffsetEncoding = w.offsetEncoding\n\t}\n\n\t// Stored bytes?\n\tif storable && storedSize <= size {\n\t\tw.writeStoredHeader(len(input), eof)\n\t\tw.writeBytes(input)\n\t\treturn\n\t}\n\n\t// Huffman.\n\tif literalEncoding == fixedLiteralEncoding {\n\t\tw.writeFixedHeader(eof)\n\t} else {\n\t\tw.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)\n\t}\n\n\t// Write the tokens.\n\tw.writeTokens(tokens.Slice(), literalEncoding.codes, offsetEncoding.codes)\n}\n\n// writeBlockDynamic encodes a block using a dynamic Huffman table.\n// This should be used if the symbols used have a disproportionate\n// histogram distribution.\n// If input is supplied and the compression savings are below 1/16th of the\n// input size the block is stored.\nfunc (w *huffmanBitWriter) writeBlockDynamic(tokens *tokens, eof bool, input []byte, sync bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\n\tsync = sync || eof\n\tif sync {\n\t\ttokens.AddEOB()\n\t}\n\n\t// We cannot reuse pure huffman table, and must mark as EOF.\n\tif (w.lastHuffMan || eof) && w.lastHeader > 0 {\n\t\t// We will not try to reuse.\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t\tw.lastHuffMan = false\n\t}\n\n\t// fillReuse enables filling of empty values.\n\t// This will make encodings always reusable without testing.\n\t// However, this does not appear to benefit on most cases.\n\tconst fillReuse = false\n\n\t// Check if we can reuse...\n\tif !fillReuse && w.lastHeader > 0 && !w.canReuse(tokens) {\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t}\n\n\tnumLiterals, numOffsets := w.indexTokens(tokens, !sync)\n\textraBits := 0\n\tssize, storable := w.storedSize(input)\n\n\tconst usePrefs = true\n\tif storable || w.lastHeader > 0 {\n\t\textraBits = w.extraBitSize()\n\t}\n\n\tvar size int\n\n\t// Check if we should reuse.\n\tif w.lastHeader > 0 {\n\t\t// Estimate size for using a new table.\n\t\t// Use the previous header size as the best estimate.\n\t\tnewSize := w.lastHeader + tokens.EstimatedBits()\n\t\tnewSize += int(w.literalEncoding.codes[endBlockMarker].len()) + newSize>>w.logNewTablePenalty\n\n\t\t// The estimated size is calculated as an optimal table.\n\t\t// We add a penalty to make it more realistic and re-use a bit more.\n\t\treuseSize := w.dynamicReuseSize(w.literalEncoding, w.offsetEncoding) + extraBits\n\n\t\t// Check if a new table is better.\n\t\tif newSize < reuseSize {\n\t\t\t// Write the EOB we owe.\n\t\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\t\tsize = newSize\n\t\t\tw.lastHeader = 0\n\t\t} else {\n\t\t\tsize = reuseSize\n\t\t}\n\n\t\tif tokens.n < maxPredefinedTokens {\n\t\t\tif preSize := w.fixedSize(extraBits) + 7; usePrefs && preSize < size {\n\t\t\t\t// Check if we get a reasonable size decrease.\n\t\t\t\tif storable && ssize <= size {\n\t\t\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\t\t\tw.writeBytes(input)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tw.writeFixedHeader(eof)\n\t\t\t\tif !sync {\n\t\t\t\t\ttokens.AddEOB()\n\t\t\t\t}\n\t\t\t\tw.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\t// Check if we get a reasonable size decrease.\n\t\tif storable && ssize <= size {\n\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\tw.writeBytes(input)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// We want a new block/table\n\tif w.lastHeader == 0 {\n\t\tif fillReuse && !sync {\n\t\t\tw.fillTokens()\n\t\t\tnumLiterals, numOffsets = maxNumLit, maxNumDist\n\t\t} else {\n\t\t\tw.literalFreq[endBlockMarker] = 1\n\t\t}\n\n\t\tw.generate()\n\t\t// Generate codegen and codegenFrequencies, which indicates how to encode\n\t\t// the literalEncoding and the offsetEncoding.\n\t\tw.generateCodegen(numLiterals, numOffsets, w.literalEncoding, w.offsetEncoding)\n\t\tw.codegenEncoding.generate(w.codegenFreq[:], 7)\n\n\t\tvar numCodegens int\n\t\tif fillReuse && !sync {\n\t\t\t// Reindex for accurate size...\n\t\t\tw.indexTokens(tokens, true)\n\t\t}\n\t\tsize, numCodegens = w.dynamicSize(w.literalEncoding, w.offsetEncoding, extraBits)\n\n\t\t// Store predefined, if we don't get a reasonable improvement.\n\t\tif tokens.n < maxPredefinedTokens {\n\t\t\tif preSize := w.fixedSize(extraBits); usePrefs && preSize <= size {\n\t\t\t\t// Store bytes, if we don't get an improvement.\n\t\t\t\tif storable && ssize <= preSize {\n\t\t\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\t\t\tw.writeBytes(input)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tw.writeFixedHeader(eof)\n\t\t\t\tif !sync {\n\t\t\t\t\ttokens.AddEOB()\n\t\t\t\t}\n\t\t\t\tw.writeTokens(tokens.Slice(), fixedLiteralEncoding.codes, fixedOffsetEncoding.codes)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif storable && ssize <= size {\n\t\t\t// Store bytes, if we don't get an improvement.\n\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\tw.writeBytes(input)\n\t\t\treturn\n\t\t}\n\n\t\t// Write Huffman table.\n\t\tw.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)\n\t\tif !sync {\n\t\t\tw.lastHeader, _ = w.headerSize()\n\t\t}\n\t\tw.lastHuffMan = false\n\t}\n\n\tif sync {\n\t\tw.lastHeader = 0\n\t}\n\t// Write the tokens.\n\tw.writeTokens(tokens.Slice(), w.literalEncoding.codes, w.offsetEncoding.codes)\n}\n\nfunc (w *huffmanBitWriter) fillTokens() {\n\tfor i, v := range w.literalFreq[:literalCount] {\n\t\tif v == 0 {\n\t\t\tw.literalFreq[i] = 1\n\t\t}\n\t}\n\tfor i, v := range w.offsetFreq[:offsetCodeCount] {\n\t\tif v == 0 {\n\t\t\tw.offsetFreq[i] = 1\n\t\t}\n\t}\n}\n\n// indexTokens indexes a slice of tokens, and updates\n// literalFreq and offsetFreq, and generates literalEncoding\n// and offsetEncoding.\n// The number of literal and offset tokens is returned.\nfunc (w *huffmanBitWriter) indexTokens(t *tokens, filled bool) (numLiterals, numOffsets int) {\n\t//copy(w.literalFreq[:], t.litHist[:])\n\t*(*[256]uint16)(w.literalFreq[:]) = t.litHist\n\t//copy(w.literalFreq[256:], t.extraHist[:])\n\t*(*[32]uint16)(w.literalFreq[256:]) = t.extraHist\n\tw.offsetFreq = t.offHist\n\n\tif t.n == 0 {\n\t\treturn\n\t}\n\tif filled {\n\t\treturn maxNumLit, maxNumDist\n\t}\n\t// get the number of literals\n\tnumLiterals = len(w.literalFreq)\n\tfor w.literalFreq[numLiterals-1] == 0 {\n\t\tnumLiterals--\n\t}\n\t// get the number of offsets\n\tnumOffsets = len(w.offsetFreq)\n\tfor numOffsets > 0 && w.offsetFreq[numOffsets-1] == 0 {\n\t\tnumOffsets--\n\t}\n\tif numOffsets == 0 {\n\t\t// We haven't found a single match. If we want to go with the dynamic encoding,\n\t\t// we should count at least one offset to be sure that the offset huffman tree could be encoded.\n\t\tw.offsetFreq[0] = 1\n\t\tnumOffsets = 1\n\t}\n\treturn\n}\n\nfunc (w *huffmanBitWriter) generate() {\n\tw.literalEncoding.generate(w.literalFreq[:literalCount], 15)\n\tw.offsetEncoding.generate(w.offsetFreq[:offsetCodeCount], 15)\n}\n\n// writeTokens writes a slice of tokens to the output.\n// codes for literal and offset encoding must be supplied.\nfunc (w *huffmanBitWriter) writeTokens(tokens []token, leCodes, oeCodes []hcode) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\tif len(tokens) == 0 {\n\t\treturn\n\t}\n\n\t// Only last token should be endBlockMarker.\n\tvar deferEOB bool\n\tif tokens[len(tokens)-1] == endBlockMarker {\n\t\ttokens = tokens[:len(tokens)-1]\n\t\tdeferEOB = true\n\t}\n\n\t// Create slices up to the next power of two to avoid bounds checks.\n\tlits := leCodes[:256]\n\toffs := oeCodes[:32]\n\tlengths := leCodes[lengthCodesStart:]\n\tlengths = lengths[:32]\n\n\t// Go 1.16 LOVES having these on stack.\n\tbits, nbits, nbytes := w.bits, w.nbits, w.nbytes\n\n\tfor _, t := range tokens {\n\t\tif t < 256 {\n\t\t\t//w.writeCode(lits[t.literal()])\n\t\t\tc := lits[t]\n\t\t\tbits |= c.code64() << (nbits & 63)\n\t\t\tnbits += c.len()\n\t\t\tif nbits >= 48 {\n\t\t\t\tbinary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Write the length\n\t\tlength := t.length()\n\t\tlengthCode := lengthCode(length) & 31\n\t\tif false {\n\t\t\tw.writeCode(lengths[lengthCode])\n\t\t} else {\n\t\t\t// inlined\n\t\t\tc := lengths[lengthCode]\n\t\t\tbits |= c.code64() << (nbits & 63)\n\t\t\tnbits += c.len()\n\t\t\tif nbits >= 48 {\n\t\t\t\tbinary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif lengthCode >= lengthExtraBitsMinCode {\n\t\t\textraLengthBits := lengthExtraBits[lengthCode]\n\t\t\t//w.writeBits(extraLength, extraLengthBits)\n\t\t\textraLength := int32(length - lengthBase[lengthCode])\n\t\t\tbits |= uint64(extraLength) << (nbits & 63)\n\t\t\tnbits += extraLengthBits\n\t\t\tif nbits >= 48 {\n\t\t\t\tbinary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Write the offset\n\t\toffset := t.offset()\n\t\toffsetCode := (offset >> 16) & 31\n\t\tif false {\n\t\t\tw.writeCode(offs[offsetCode])\n\t\t} else {\n\t\t\t// inlined\n\t\t\tc := offs[offsetCode]\n\t\t\tbits |= c.code64() << (nbits & 63)\n\t\t\tnbits += c.len()\n\t\t\tif nbits >= 48 {\n\t\t\t\tbinary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif offsetCode >= offsetExtraBitsMinCode {\n\t\t\toffsetComb := offsetCombined[offsetCode]\n\t\t\t//w.writeBits(extraOffset, extraOffsetBits)\n\t\t\tbits |= uint64((offset-(offsetComb>>8))&matchOffsetOnlyMask) << (nbits & 63)\n\t\t\tnbits += uint8(offsetComb)\n\t\t\tif nbits >= 48 {\n\t\t\t\tbinary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)\n\t\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\t\tbits >>= 48\n\t\t\t\tnbits -= 48\n\t\t\t\tnbytes += 6\n\t\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\t\tif w.err != nil {\n\t\t\t\t\t\tnbytes = 0\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\t\tnbytes = 0\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Restore...\n\tw.bits, w.nbits, w.nbytes = bits, nbits, nbytes\n\n\tif deferEOB {\n\t\tw.writeCode(leCodes[endBlockMarker])\n\t}\n}\n\n// huffOffset is a static offset encoder used for huffman only encoding.\n// It can be reused since we will not be encoding offset values.\nvar huffOffset *huffmanEncoder\n\nfunc init() {\n\tw := newHuffmanBitWriter(nil)\n\tw.offsetFreq[0] = 1\n\thuffOffset = newHuffmanEncoder(offsetCodeCount)\n\thuffOffset.generate(w.offsetFreq[:offsetCodeCount], 15)\n}\n\n// writeBlockHuff encodes a block of bytes as either\n// Huffman encoded literals or uncompressed bytes if the\n// results only gains very little from compression.\nfunc (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte, sync bool) {\n\tif w.err != nil {\n\t\treturn\n\t}\n\n\t// Clear histogram\n\tfor i := range w.literalFreq[:] {\n\t\tw.literalFreq[i] = 0\n\t}\n\tif !w.lastHuffMan {\n\t\tfor i := range w.offsetFreq[:] {\n\t\t\tw.offsetFreq[i] = 0\n\t\t}\n\t}\n\n\tconst numLiterals = endBlockMarker + 1\n\tconst numOffsets = 1\n\n\t// Add everything as literals\n\t// We have to estimate the header size.\n\t// Assume header is around 70 bytes:\n\t// https://stackoverflow.com/a/25454430\n\tconst guessHeaderSizeBits = 70 * 8\n\thistogram(input, w.literalFreq[:numLiterals])\n\tssize, storable := w.storedSize(input)\n\tif storable && len(input) > 1024 {\n\t\t// Quick check for incompressible content.\n\t\tabs := float64(0)\n\t\tavg := float64(len(input)) / 256\n\t\tmax := float64(len(input) * 2)\n\t\tfor _, v := range w.literalFreq[:256] {\n\t\t\tdiff := float64(v) - avg\n\t\t\tabs += diff * diff\n\t\t\tif abs > max {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif abs < max {\n\t\t\tif debugDeflate {\n\t\t\t\tfmt.Println(\"stored\", abs, \"<\", max)\n\t\t\t}\n\t\t\t// No chance we can compress this...\n\t\t\tw.writeStoredHeader(len(input), eof)\n\t\t\tw.writeBytes(input)\n\t\t\treturn\n\t\t}\n\t}\n\tw.literalFreq[endBlockMarker] = 1\n\tw.tmpLitEncoding.generate(w.literalFreq[:numLiterals], 15)\n\testBits := w.tmpLitEncoding.canReuseBits(w.literalFreq[:numLiterals])\n\tif estBits < math.MaxInt32 {\n\t\testBits += w.lastHeader\n\t\tif w.lastHeader == 0 {\n\t\t\testBits += guessHeaderSizeBits\n\t\t}\n\t\testBits += estBits >> w.logNewTablePenalty\n\t}\n\n\t// Store bytes, if we don't get a reasonable improvement.\n\tif storable && ssize <= estBits {\n\t\tif debugDeflate {\n\t\t\tfmt.Println(\"stored,\", ssize, \"<=\", estBits)\n\t\t}\n\t\tw.writeStoredHeader(len(input), eof)\n\t\tw.writeBytes(input)\n\t\treturn\n\t}\n\n\tif w.lastHeader > 0 {\n\t\treuseSize := w.literalEncoding.canReuseBits(w.literalFreq[:256])\n\n\t\tif estBits < reuseSize {\n\t\t\tif debugDeflate {\n\t\t\t\tfmt.Println(\"NOT reusing, reuse:\", reuseSize/8, \"> new:\", estBits/8, \"header est:\", w.lastHeader/8, \"bytes\")\n\t\t\t}\n\t\t\t// We owe an EOB\n\t\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\t\tw.lastHeader = 0\n\t\t} else if debugDeflate {\n\t\t\tfmt.Println(\"reusing, reuse:\", reuseSize/8, \"> new:\", estBits/8, \"- header est:\", w.lastHeader/8)\n\t\t}\n\t}\n\n\tcount := 0\n\tif w.lastHeader == 0 {\n\t\t// Use the temp encoding, so swap.\n\t\tw.literalEncoding, w.tmpLitEncoding = w.tmpLitEncoding, w.literalEncoding\n\t\t// Generate codegen and codegenFrequencies, which indicates how to encode\n\t\t// the literalEncoding and the offsetEncoding.\n\t\tw.generateCodegen(numLiterals, numOffsets, w.literalEncoding, huffOffset)\n\t\tw.codegenEncoding.generate(w.codegenFreq[:], 7)\n\t\tnumCodegens := w.codegens()\n\n\t\t// Huffman.\n\t\tw.writeDynamicHeader(numLiterals, numOffsets, numCodegens, eof)\n\t\tw.lastHuffMan = true\n\t\tw.lastHeader, _ = w.headerSize()\n\t\tif debugDeflate {\n\t\t\tcount += w.lastHeader\n\t\t\tfmt.Println(\"header:\", count/8)\n\t\t}\n\t}\n\n\tencoding := w.literalEncoding.codes[:256]\n\t// Go 1.16 LOVES having these on stack. At least 1.5x the speed.\n\tbits, nbits, nbytes := w.bits, w.nbits, w.nbytes\n\n\tif debugDeflate {\n\t\tcount -= int(nbytes)*8 + int(nbits)\n\t}\n\t// Unroll, write 3 codes/loop.\n\t// Fastest number of unrolls.\n\tfor len(input) > 3 {\n\t\t// We must have at least 48 bits free.\n\t\tif nbits >= 8 {\n\t\t\tn := nbits >> 3\n\t\t\tbinary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)\n\t\t\tbits >>= (n * 8) & 63\n\t\t\tnbits -= n * 8\n\t\t\tnbytes += n\n\t\t}\n\t\tif nbytes >= bufferFlushSize {\n\t\t\tif w.err != nil {\n\t\t\t\tnbytes = 0\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif debugDeflate {\n\t\t\t\tcount += int(nbytes) * 8\n\t\t\t}\n\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\tnbytes = 0\n\t\t}\n\t\ta, b := encoding[input[0]], encoding[input[1]]\n\t\tbits |= a.code64() << (nbits & 63)\n\t\tbits |= b.code64() << ((nbits + a.len()) & 63)\n\t\tc := encoding[input[2]]\n\t\tnbits += b.len() + a.len()\n\t\tbits |= c.code64() << (nbits & 63)\n\t\tnbits += c.len()\n\t\tinput = input[3:]\n\t}\n\n\t// Remaining...\n\tfor _, t := range input {\n\t\tif nbits >= 48 {\n\t\t\tbinary.LittleEndian.PutUint64(w.bytes[nbytes:], bits)\n\t\t\t//*(*uint64)(unsafe.Pointer(&w.bytes[nbytes])) = bits\n\t\t\tbits >>= 48\n\t\t\tnbits -= 48\n\t\t\tnbytes += 6\n\t\t\tif nbytes >= bufferFlushSize {\n\t\t\t\tif w.err != nil {\n\t\t\t\t\tnbytes = 0\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif debugDeflate {\n\t\t\t\t\tcount += int(nbytes) * 8\n\t\t\t\t}\n\t\t\t\t_, w.err = w.writer.Write(w.bytes[:nbytes])\n\t\t\t\tnbytes = 0\n\t\t\t}\n\t\t}\n\t\t// Bitwriting inlined, ~30% speedup\n\t\tc := encoding[t]\n\t\tbits |= c.code64() << (nbits & 63)\n\n\t\tnbits += c.len()\n\t\tif debugDeflate {\n\t\t\tcount += int(c.len())\n\t\t}\n\t}\n\t// Restore...\n\tw.bits, w.nbits, w.nbytes = bits, nbits, nbytes\n\n\tif debugDeflate {\n\t\tnb := count + int(nbytes)*8 + int(nbits)\n\t\tfmt.Println(\"wrote\", nb, \"bits,\", nb/8, \"bytes.\")\n\t}\n\t// Flush if needed to have space.\n\tif w.nbits >= 48 {\n\t\tw.writeOutBits()\n\t}\n\n\tif eof || sync {\n\t\tw.writeCode(w.literalEncoding.codes[endBlockMarker])\n\t\tw.lastHeader = 0\n\t\tw.lastHuffMan = false\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_code.go",
    "content": "// Copyright 2009 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 flate\n\nimport (\n\t\"math\"\n\t\"math/bits\"\n)\n\nconst (\n\tmaxBitsLimit = 16\n\t// number of valid literals\n\tliteralCount = 286\n)\n\n// hcode is a huffman code with a bit code and bit length.\ntype hcode uint32\n\nfunc (h hcode) len() uint8 {\n\treturn uint8(h)\n}\n\nfunc (h hcode) code64() uint64 {\n\treturn uint64(h >> 8)\n}\n\nfunc (h hcode) zero() bool {\n\treturn h == 0\n}\n\ntype huffmanEncoder struct {\n\tcodes    []hcode\n\tbitCount [17]int32\n\n\t// Allocate a reusable buffer with the longest possible frequency table.\n\t// Possible lengths are codegenCodeCount, offsetCodeCount and literalCount.\n\t// The largest of these is literalCount, so we allocate for that case.\n\tfreqcache [literalCount + 1]literalNode\n}\n\ntype literalNode struct {\n\tliteral uint16\n\tfreq    uint16\n}\n\n// A levelInfo describes the state of the constructed tree for a given depth.\ntype levelInfo struct {\n\t// Our level.  for better printing\n\tlevel int32\n\n\t// The frequency of the last node at this level\n\tlastFreq int32\n\n\t// The frequency of the next character to add to this level\n\tnextCharFreq int32\n\n\t// The frequency of the next pair (from level below) to add to this level.\n\t// Only valid if the \"needed\" value of the next lower level is 0.\n\tnextPairFreq int32\n\n\t// The number of chains remaining to generate for this level before moving\n\t// up to the next level\n\tneeded int32\n}\n\n// set sets the code and length of an hcode.\nfunc (h *hcode) set(code uint16, length uint8) {\n\t*h = hcode(length) | (hcode(code) << 8)\n}\n\nfunc newhcode(code uint16, length uint8) hcode {\n\treturn hcode(length) | (hcode(code) << 8)\n}\n\nfunc reverseBits(number uint16, bitLength byte) uint16 {\n\treturn bits.Reverse16(number << ((16 - bitLength) & 15))\n}\n\nfunc maxNode() literalNode { return literalNode{math.MaxUint16, math.MaxUint16} }\n\nfunc newHuffmanEncoder(size int) *huffmanEncoder {\n\t// Make capacity to next power of two.\n\tc := uint(bits.Len32(uint32(size - 1)))\n\treturn &huffmanEncoder{codes: make([]hcode, size, 1<<c)}\n}\n\n// Generates a HuffmanCode corresponding to the fixed literal table\nfunc generateFixedLiteralEncoding() *huffmanEncoder {\n\th := newHuffmanEncoder(literalCount)\n\tcodes := h.codes\n\tvar ch uint16\n\tfor ch = 0; ch < literalCount; ch++ {\n\t\tvar bits uint16\n\t\tvar size uint8\n\t\tswitch {\n\t\tcase ch < 144:\n\t\t\t// size 8, 000110000  .. 10111111\n\t\t\tbits = ch + 48\n\t\t\tsize = 8\n\t\tcase ch < 256:\n\t\t\t// size 9, 110010000 .. 111111111\n\t\t\tbits = ch + 400 - 144\n\t\t\tsize = 9\n\t\tcase ch < 280:\n\t\t\t// size 7, 0000000 .. 0010111\n\t\t\tbits = ch - 256\n\t\t\tsize = 7\n\t\tdefault:\n\t\t\t// size 8, 11000000 .. 11000111\n\t\t\tbits = ch + 192 - 280\n\t\t\tsize = 8\n\t\t}\n\t\tcodes[ch] = newhcode(reverseBits(bits, size), size)\n\t}\n\treturn h\n}\n\nfunc generateFixedOffsetEncoding() *huffmanEncoder {\n\th := newHuffmanEncoder(30)\n\tcodes := h.codes\n\tfor ch := range codes {\n\t\tcodes[ch] = newhcode(reverseBits(uint16(ch), 5), 5)\n\t}\n\treturn h\n}\n\nvar fixedLiteralEncoding = generateFixedLiteralEncoding()\nvar fixedOffsetEncoding = generateFixedOffsetEncoding()\n\nfunc (h *huffmanEncoder) bitLength(freq []uint16) int {\n\tvar total int\n\tfor i, f := range freq {\n\t\tif f != 0 {\n\t\t\ttotal += int(f) * int(h.codes[i].len())\n\t\t}\n\t}\n\treturn total\n}\n\nfunc (h *huffmanEncoder) bitLengthRaw(b []byte) int {\n\tvar total int\n\tfor _, f := range b {\n\t\ttotal += int(h.codes[f].len())\n\t}\n\treturn total\n}\n\n// canReuseBits returns the number of bits or math.MaxInt32 if the encoder cannot be reused.\nfunc (h *huffmanEncoder) canReuseBits(freq []uint16) int {\n\tvar total int\n\tfor i, f := range freq {\n\t\tif f != 0 {\n\t\t\tcode := h.codes[i]\n\t\t\tif code.zero() {\n\t\t\t\treturn math.MaxInt32\n\t\t\t}\n\t\t\ttotal += int(f) * int(code.len())\n\t\t}\n\t}\n\treturn total\n}\n\n// Return the number of literals assigned to each bit size in the Huffman encoding\n//\n// This method is only called when list.length >= 3\n// The cases of 0, 1, and 2 literals are handled by special case code.\n//\n// list  An array of the literals with non-zero frequencies\n//\n//\tand their associated frequencies. The array is in order of increasing\n//\tfrequency, and has as its last element a special element with frequency\n//\tMaxInt32\n//\n// maxBits     The maximum number of bits that should be used to encode any literal.\n//\n//\tMust be less than 16.\n//\n// return      An integer array in which array[i] indicates the number of literals\n//\n//\tthat should be encoded in i bits.\nfunc (h *huffmanEncoder) bitCounts(list []literalNode, maxBits int32) []int32 {\n\tif maxBits >= maxBitsLimit {\n\t\tpanic(\"flate: maxBits too large\")\n\t}\n\tn := int32(len(list))\n\tlist = list[0 : n+1]\n\tlist[n] = maxNode()\n\n\t// The tree can't have greater depth than n - 1, no matter what. This\n\t// saves a little bit of work in some small cases\n\tif maxBits > n-1 {\n\t\tmaxBits = n - 1\n\t}\n\n\t// Create information about each of the levels.\n\t// A bogus \"Level 0\" whose sole purpose is so that\n\t// level1.prev.needed==0.  This makes level1.nextPairFreq\n\t// be a legitimate value that never gets chosen.\n\tvar levels [maxBitsLimit]levelInfo\n\t// leafCounts[i] counts the number of literals at the left\n\t// of ancestors of the rightmost node at level i.\n\t// leafCounts[i][j] is the number of literals at the left\n\t// of the level j ancestor.\n\tvar leafCounts [maxBitsLimit][maxBitsLimit]int32\n\n\t// Descending to only have 1 bounds check.\n\tl2f := int32(list[2].freq)\n\tl1f := int32(list[1].freq)\n\tl0f := int32(list[0].freq) + int32(list[1].freq)\n\n\tfor level := int32(1); level <= maxBits; level++ {\n\t\t// For every level, the first two items are the first two characters.\n\t\t// We initialize the levels as if we had already figured this out.\n\t\tlevels[level] = levelInfo{\n\t\t\tlevel:        level,\n\t\t\tlastFreq:     l1f,\n\t\t\tnextCharFreq: l2f,\n\t\t\tnextPairFreq: l0f,\n\t\t}\n\t\tleafCounts[level][level] = 2\n\t\tif level == 1 {\n\t\t\tlevels[level].nextPairFreq = math.MaxInt32\n\t\t}\n\t}\n\n\t// We need a total of 2*n - 2 items at top level and have already generated 2.\n\tlevels[maxBits].needed = 2*n - 4\n\n\tlevel := uint32(maxBits)\n\tfor level < 16 {\n\t\tl := &levels[level]\n\t\tif l.nextPairFreq == math.MaxInt32 && l.nextCharFreq == math.MaxInt32 {\n\t\t\t// We've run out of both leafs and pairs.\n\t\t\t// End all calculations for this level.\n\t\t\t// To make sure we never come back to this level or any lower level,\n\t\t\t// set nextPairFreq impossibly large.\n\t\t\tl.needed = 0\n\t\t\tlevels[level+1].nextPairFreq = math.MaxInt32\n\t\t\tlevel++\n\t\t\tcontinue\n\t\t}\n\n\t\tprevFreq := l.lastFreq\n\t\tif l.nextCharFreq < l.nextPairFreq {\n\t\t\t// The next item on this row is a leaf node.\n\t\t\tn := leafCounts[level][level] + 1\n\t\t\tl.lastFreq = l.nextCharFreq\n\t\t\t// Lower leafCounts are the same of the previous node.\n\t\t\tleafCounts[level][level] = n\n\t\t\te := list[n]\n\t\t\tif e.literal < math.MaxUint16 {\n\t\t\t\tl.nextCharFreq = int32(e.freq)\n\t\t\t} else {\n\t\t\t\tl.nextCharFreq = math.MaxInt32\n\t\t\t}\n\t\t} else {\n\t\t\t// The next item on this row is a pair from the previous row.\n\t\t\t// nextPairFreq isn't valid until we generate two\n\t\t\t// more values in the level below\n\t\t\tl.lastFreq = l.nextPairFreq\n\t\t\t// Take leaf counts from the lower level, except counts[level] remains the same.\n\t\t\tif true {\n\t\t\t\tsave := leafCounts[level][level]\n\t\t\t\tleafCounts[level] = leafCounts[level-1]\n\t\t\t\tleafCounts[level][level] = save\n\t\t\t} else {\n\t\t\t\tcopy(leafCounts[level][:level], leafCounts[level-1][:level])\n\t\t\t}\n\t\t\tlevels[l.level-1].needed = 2\n\t\t}\n\n\t\tif l.needed--; l.needed == 0 {\n\t\t\t// We've done everything we need to do for this level.\n\t\t\t// Continue calculating one level up. Fill in nextPairFreq\n\t\t\t// of that level with the sum of the two nodes we've just calculated on\n\t\t\t// this level.\n\t\t\tif l.level == maxBits {\n\t\t\t\t// All done!\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlevels[l.level+1].nextPairFreq = prevFreq + l.lastFreq\n\t\t\tlevel++\n\t\t} else {\n\t\t\t// If we stole from below, move down temporarily to replenish it.\n\t\t\tfor levels[level-1].needed > 0 {\n\t\t\t\tlevel--\n\t\t\t}\n\t\t}\n\t}\n\n\t// Somethings is wrong if at the end, the top level is null or hasn't used\n\t// all of the leaves.\n\tif leafCounts[maxBits][maxBits] != n {\n\t\tpanic(\"leafCounts[maxBits][maxBits] != n\")\n\t}\n\n\tbitCount := h.bitCount[:maxBits+1]\n\tbits := 1\n\tcounts := &leafCounts[maxBits]\n\tfor level := maxBits; level > 0; level-- {\n\t\t// chain.leafCount gives the number of literals requiring at least \"bits\"\n\t\t// bits to encode.\n\t\tbitCount[bits] = counts[level] - counts[level-1]\n\t\tbits++\n\t}\n\treturn bitCount\n}\n\n// Look at the leaves and assign them a bit count and an encoding as specified\n// in RFC 1951 3.2.2\nfunc (h *huffmanEncoder) assignEncodingAndSize(bitCount []int32, list []literalNode) {\n\tcode := uint16(0)\n\tfor n, bits := range bitCount {\n\t\tcode <<= 1\n\t\tif n == 0 || bits == 0 {\n\t\t\tcontinue\n\t\t}\n\t\t// The literals list[len(list)-bits] .. list[len(list)-bits]\n\t\t// are encoded using \"bits\" bits, and get the values\n\t\t// code, code + 1, ....  The code values are\n\t\t// assigned in literal order (not frequency order).\n\t\tchunk := list[len(list)-int(bits):]\n\n\t\tsortByLiteral(chunk)\n\t\tfor _, node := range chunk {\n\t\t\th.codes[node.literal] = newhcode(reverseBits(code, uint8(n)), uint8(n))\n\t\t\tcode++\n\t\t}\n\t\tlist = list[0 : len(list)-int(bits)]\n\t}\n}\n\n// Update this Huffman Code object to be the minimum code for the specified frequency count.\n//\n// freq  An array of frequencies, in which frequency[i] gives the frequency of literal i.\n// maxBits  The maximum number of bits to use for any literal.\nfunc (h *huffmanEncoder) generate(freq []uint16, maxBits int32) {\n\tlist := h.freqcache[:len(freq)+1]\n\tcodes := h.codes[:len(freq)]\n\t// Number of non-zero literals\n\tcount := 0\n\t// Set list to be the set of all non-zero literals and their frequencies\n\tfor i, f := range freq {\n\t\tif f != 0 {\n\t\t\tlist[count] = literalNode{uint16(i), f}\n\t\t\tcount++\n\t\t} else {\n\t\t\tcodes[i] = 0\n\t\t}\n\t}\n\tlist[count] = literalNode{}\n\n\tlist = list[:count]\n\tif count <= 2 {\n\t\t// Handle the small cases here, because they are awkward for the general case code. With\n\t\t// two or fewer literals, everything has bit length 1.\n\t\tfor i, node := range list {\n\t\t\t// \"list\" is in order of increasing literal value.\n\t\t\th.codes[node.literal].set(uint16(i), 1)\n\t\t}\n\t\treturn\n\t}\n\tsortByFreq(list)\n\n\t// Get the number of literals for each bit count\n\tbitCount := h.bitCounts(list, maxBits)\n\t// And do the assignment\n\th.assignEncodingAndSize(bitCount, list)\n}\n\n// atLeastOne clamps the result between 1 and 15.\nfunc atLeastOne(v float32) float32 {\n\tif v < 1 {\n\t\treturn 1\n\t}\n\tif v > 15 {\n\t\treturn 15\n\t}\n\treturn v\n}\n\nfunc histogram(b []byte, h []uint16) {\n\tif true && len(b) >= 8<<10 {\n\t\t// Split for bigger inputs\n\t\thistogramSplit(b, h)\n\t} else {\n\t\th = h[:256]\n\t\tfor _, t := range b {\n\t\t\th[t]++\n\t\t}\n\t}\n}\n\nfunc histogramSplit(b []byte, h []uint16) {\n\t// Tested, and slightly faster than 2-way.\n\t// Writing to separate arrays and combining is also slightly slower.\n\th = h[:256]\n\tfor len(b)&3 != 0 {\n\t\th[b[0]]++\n\t\tb = b[1:]\n\t}\n\tn := len(b) / 4\n\tx, y, z, w := b[:n], b[n:], b[n+n:], b[n+n+n:]\n\ty, z, w = y[:len(x)], z[:len(x)], w[:len(x)]\n\tfor i, t := range x {\n\t\tv0 := &h[t]\n\t\tv1 := &h[y[i]]\n\t\tv3 := &h[w[i]]\n\t\tv2 := &h[z[i]]\n\t\t*v0++\n\t\t*v1++\n\t\t*v2++\n\t\t*v3++\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_sortByFreq.go",
    "content": "// Copyright 2009 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 flate\n\n// Sort sorts data.\n// It makes one call to data.Len to determine n, and O(n*log(n)) calls to\n// data.Less and data.Swap. The sort is not guaranteed to be stable.\nfunc sortByFreq(data []literalNode) {\n\tn := len(data)\n\tquickSortByFreq(data, 0, n, maxDepth(n))\n}\n\nfunc quickSortByFreq(data []literalNode, a, b, maxDepth int) {\n\tfor b-a > 12 { // Use ShellSort for slices <= 12 elements\n\t\tif maxDepth == 0 {\n\t\t\theapSort(data, a, b)\n\t\t\treturn\n\t\t}\n\t\tmaxDepth--\n\t\tmlo, mhi := doPivotByFreq(data, a, b)\n\t\t// Avoiding recursion on the larger subproblem guarantees\n\t\t// a stack depth of at most lg(b-a).\n\t\tif mlo-a < b-mhi {\n\t\t\tquickSortByFreq(data, a, mlo, maxDepth)\n\t\t\ta = mhi // i.e., quickSortByFreq(data, mhi, b)\n\t\t} else {\n\t\t\tquickSortByFreq(data, mhi, b, maxDepth)\n\t\t\tb = mlo // i.e., quickSortByFreq(data, a, mlo)\n\t\t}\n\t}\n\tif b-a > 1 {\n\t\t// Do ShellSort pass with gap 6\n\t\t// It could be written in this simplified form cause b-a <= 12\n\t\tfor i := a + 6; i < b; i++ {\n\t\t\tif data[i].freq == data[i-6].freq && data[i].literal < data[i-6].literal || data[i].freq < data[i-6].freq {\n\t\t\t\tdata[i], data[i-6] = data[i-6], data[i]\n\t\t\t}\n\t\t}\n\t\tinsertionSortByFreq(data, a, b)\n\t}\n}\n\nfunc doPivotByFreq(data []literalNode, lo, hi int) (midlo, midhi int) {\n\tm := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.\n\tif hi-lo > 40 {\n\t\t// Tukey's ``Ninther,'' median of three medians of three.\n\t\ts := (hi - lo) / 8\n\t\tmedianOfThreeSortByFreq(data, lo, lo+s, lo+2*s)\n\t\tmedianOfThreeSortByFreq(data, m, m-s, m+s)\n\t\tmedianOfThreeSortByFreq(data, hi-1, hi-1-s, hi-1-2*s)\n\t}\n\tmedianOfThreeSortByFreq(data, lo, m, hi-1)\n\n\t// Invariants are:\n\t//\tdata[lo] = pivot (set up by ChoosePivot)\n\t//\tdata[lo < i < a] < pivot\n\t//\tdata[a <= i < b] <= pivot\n\t//\tdata[b <= i < c] unexamined\n\t//\tdata[c <= i < hi-1] > pivot\n\t//\tdata[hi-1] >= pivot\n\tpivot := lo\n\ta, c := lo+1, hi-1\n\n\tfor ; a < c && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ {\n\t}\n\tb := a\n\tfor {\n\t\tfor ; b < c && (data[pivot].freq == data[b].freq && data[pivot].literal > data[b].literal || data[pivot].freq > data[b].freq); b++ { // data[b] <= pivot\n\t\t}\n\t\tfor ; b < c && (data[pivot].freq == data[c-1].freq && data[pivot].literal < data[c-1].literal || data[pivot].freq < data[c-1].freq); c-- { // data[c-1] > pivot\n\t\t}\n\t\tif b >= c {\n\t\t\tbreak\n\t\t}\n\t\t// data[b] > pivot; data[c-1] <= pivot\n\t\tdata[b], data[c-1] = data[c-1], data[b]\n\t\tb++\n\t\tc--\n\t}\n\t// If hi-c<3 then there are duplicates (by property of median of nine).\n\t// Let's be a bit more conservative, and set border to 5.\n\tprotect := hi-c < 5\n\tif !protect && hi-c < (hi-lo)/4 {\n\t\t// Lets test some points for equality to pivot\n\t\tdups := 0\n\t\tif data[pivot].freq == data[hi-1].freq && data[pivot].literal > data[hi-1].literal || data[pivot].freq > data[hi-1].freq { // data[hi-1] = pivot\n\t\t\tdata[c], data[hi-1] = data[hi-1], data[c]\n\t\t\tc++\n\t\t\tdups++\n\t\t}\n\t\tif data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq { // data[b-1] = pivot\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// m-lo = (hi-lo)/2 > 6\n\t\t// b-lo > (hi-lo)*3/4-1 > 8\n\t\t// ==> m < b ==> data[m] <= pivot\n\t\tif data[m].freq == data[pivot].freq && data[m].literal > data[pivot].literal || data[m].freq > data[pivot].freq { // data[m] = pivot\n\t\t\tdata[m], data[b-1] = data[b-1], data[m]\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// if at least 2 points are equal to pivot, assume skewed distribution\n\t\tprotect = dups > 1\n\t}\n\tif protect {\n\t\t// Protect against a lot of duplicates\n\t\t// Add invariant:\n\t\t//\tdata[a <= i < b] unexamined\n\t\t//\tdata[b <= i < c] = pivot\n\t\tfor {\n\t\t\tfor ; a < b && (data[b-1].freq == data[pivot].freq && data[b-1].literal > data[pivot].literal || data[b-1].freq > data[pivot].freq); b-- { // data[b] == pivot\n\t\t\t}\n\t\t\tfor ; a < b && (data[a].freq == data[pivot].freq && data[a].literal < data[pivot].literal || data[a].freq < data[pivot].freq); a++ { // data[a] < pivot\n\t\t\t}\n\t\t\tif a >= b {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// data[a] == pivot; data[b-1] < pivot\n\t\t\tdata[a], data[b-1] = data[b-1], data[a]\n\t\t\ta++\n\t\t\tb--\n\t\t}\n\t}\n\t// Swap pivot into middle\n\tdata[pivot], data[b-1] = data[b-1], data[pivot]\n\treturn b - 1, c\n}\n\n// Insertion sort\nfunc insertionSortByFreq(data []literalNode, a, b int) {\n\tfor i := a + 1; i < b; i++ {\n\t\tfor j := i; j > a && (data[j].freq == data[j-1].freq && data[j].literal < data[j-1].literal || data[j].freq < data[j-1].freq); j-- {\n\t\t\tdata[j], data[j-1] = data[j-1], data[j]\n\t\t}\n\t}\n}\n\n// quickSortByFreq, loosely following Bentley and McIlroy,\n// ``Engineering a Sort Function,'' SP&E November 1993.\n\n// medianOfThreeSortByFreq moves the median of the three values data[m0], data[m1], data[m2] into data[m1].\nfunc medianOfThreeSortByFreq(data []literalNode, m1, m0, m2 int) {\n\t// sort 3 elements\n\tif data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {\n\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t}\n\t// data[m0] <= data[m1]\n\tif data[m2].freq == data[m1].freq && data[m2].literal < data[m1].literal || data[m2].freq < data[m1].freq {\n\t\tdata[m2], data[m1] = data[m1], data[m2]\n\t\t// data[m0] <= data[m2] && data[m1] < data[m2]\n\t\tif data[m1].freq == data[m0].freq && data[m1].literal < data[m0].literal || data[m1].freq < data[m0].freq {\n\t\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t\t}\n\t}\n\t// now data[m0] <= data[m1] <= data[m2]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/huffman_sortByLiteral.go",
    "content": "// Copyright 2009 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 flate\n\n// Sort sorts data.\n// It makes one call to data.Len to determine n, and O(n*log(n)) calls to\n// data.Less and data.Swap. The sort is not guaranteed to be stable.\nfunc sortByLiteral(data []literalNode) {\n\tn := len(data)\n\tquickSort(data, 0, n, maxDepth(n))\n}\n\nfunc quickSort(data []literalNode, a, b, maxDepth int) {\n\tfor b-a > 12 { // Use ShellSort for slices <= 12 elements\n\t\tif maxDepth == 0 {\n\t\t\theapSort(data, a, b)\n\t\t\treturn\n\t\t}\n\t\tmaxDepth--\n\t\tmlo, mhi := doPivot(data, a, b)\n\t\t// Avoiding recursion on the larger subproblem guarantees\n\t\t// a stack depth of at most lg(b-a).\n\t\tif mlo-a < b-mhi {\n\t\t\tquickSort(data, a, mlo, maxDepth)\n\t\t\ta = mhi // i.e., quickSort(data, mhi, b)\n\t\t} else {\n\t\t\tquickSort(data, mhi, b, maxDepth)\n\t\t\tb = mlo // i.e., quickSort(data, a, mlo)\n\t\t}\n\t}\n\tif b-a > 1 {\n\t\t// Do ShellSort pass with gap 6\n\t\t// It could be written in this simplified form cause b-a <= 12\n\t\tfor i := a + 6; i < b; i++ {\n\t\t\tif data[i].literal < data[i-6].literal {\n\t\t\t\tdata[i], data[i-6] = data[i-6], data[i]\n\t\t\t}\n\t\t}\n\t\tinsertionSort(data, a, b)\n\t}\n}\nfunc heapSort(data []literalNode, a, b int) {\n\tfirst := a\n\tlo := 0\n\thi := b - a\n\n\t// Build heap with greatest element at top.\n\tfor i := (hi - 1) / 2; i >= 0; i-- {\n\t\tsiftDown(data, i, hi, first)\n\t}\n\n\t// Pop elements, largest first, into end of data.\n\tfor i := hi - 1; i >= 0; i-- {\n\t\tdata[first], data[first+i] = data[first+i], data[first]\n\t\tsiftDown(data, lo, i, first)\n\t}\n}\n\n// siftDown implements the heap property on data[lo, hi).\n// first is an offset into the array where the root of the heap lies.\nfunc siftDown(data []literalNode, lo, hi, first int) {\n\troot := lo\n\tfor {\n\t\tchild := 2*root + 1\n\t\tif child >= hi {\n\t\t\tbreak\n\t\t}\n\t\tif child+1 < hi && data[first+child].literal < data[first+child+1].literal {\n\t\t\tchild++\n\t\t}\n\t\tif data[first+root].literal > data[first+child].literal {\n\t\t\treturn\n\t\t}\n\t\tdata[first+root], data[first+child] = data[first+child], data[first+root]\n\t\troot = child\n\t}\n}\nfunc doPivot(data []literalNode, lo, hi int) (midlo, midhi int) {\n\tm := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.\n\tif hi-lo > 40 {\n\t\t// Tukey's ``Ninther,'' median of three medians of three.\n\t\ts := (hi - lo) / 8\n\t\tmedianOfThree(data, lo, lo+s, lo+2*s)\n\t\tmedianOfThree(data, m, m-s, m+s)\n\t\tmedianOfThree(data, hi-1, hi-1-s, hi-1-2*s)\n\t}\n\tmedianOfThree(data, lo, m, hi-1)\n\n\t// Invariants are:\n\t//\tdata[lo] = pivot (set up by ChoosePivot)\n\t//\tdata[lo < i < a] < pivot\n\t//\tdata[a <= i < b] <= pivot\n\t//\tdata[b <= i < c] unexamined\n\t//\tdata[c <= i < hi-1] > pivot\n\t//\tdata[hi-1] >= pivot\n\tpivot := lo\n\ta, c := lo+1, hi-1\n\n\tfor ; a < c && data[a].literal < data[pivot].literal; a++ {\n\t}\n\tb := a\n\tfor {\n\t\tfor ; b < c && data[pivot].literal > data[b].literal; b++ { // data[b] <= pivot\n\t\t}\n\t\tfor ; b < c && data[pivot].literal < data[c-1].literal; c-- { // data[c-1] > pivot\n\t\t}\n\t\tif b >= c {\n\t\t\tbreak\n\t\t}\n\t\t// data[b] > pivot; data[c-1] <= pivot\n\t\tdata[b], data[c-1] = data[c-1], data[b]\n\t\tb++\n\t\tc--\n\t}\n\t// If hi-c<3 then there are duplicates (by property of median of nine).\n\t// Let's be a bit more conservative, and set border to 5.\n\tprotect := hi-c < 5\n\tif !protect && hi-c < (hi-lo)/4 {\n\t\t// Lets test some points for equality to pivot\n\t\tdups := 0\n\t\tif data[pivot].literal > data[hi-1].literal { // data[hi-1] = pivot\n\t\t\tdata[c], data[hi-1] = data[hi-1], data[c]\n\t\t\tc++\n\t\t\tdups++\n\t\t}\n\t\tif data[b-1].literal > data[pivot].literal { // data[b-1] = pivot\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// m-lo = (hi-lo)/2 > 6\n\t\t// b-lo > (hi-lo)*3/4-1 > 8\n\t\t// ==> m < b ==> data[m] <= pivot\n\t\tif data[m].literal > data[pivot].literal { // data[m] = pivot\n\t\t\tdata[m], data[b-1] = data[b-1], data[m]\n\t\t\tb--\n\t\t\tdups++\n\t\t}\n\t\t// if at least 2 points are equal to pivot, assume skewed distribution\n\t\tprotect = dups > 1\n\t}\n\tif protect {\n\t\t// Protect against a lot of duplicates\n\t\t// Add invariant:\n\t\t//\tdata[a <= i < b] unexamined\n\t\t//\tdata[b <= i < c] = pivot\n\t\tfor {\n\t\t\tfor ; a < b && data[b-1].literal > data[pivot].literal; b-- { // data[b] == pivot\n\t\t\t}\n\t\t\tfor ; a < b && data[a].literal < data[pivot].literal; a++ { // data[a] < pivot\n\t\t\t}\n\t\t\tif a >= b {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// data[a] == pivot; data[b-1] < pivot\n\t\t\tdata[a], data[b-1] = data[b-1], data[a]\n\t\t\ta++\n\t\t\tb--\n\t\t}\n\t}\n\t// Swap pivot into middle\n\tdata[pivot], data[b-1] = data[b-1], data[pivot]\n\treturn b - 1, c\n}\n\n// Insertion sort\nfunc insertionSort(data []literalNode, a, b int) {\n\tfor i := a + 1; i < b; i++ {\n\t\tfor j := i; j > a && data[j].literal < data[j-1].literal; j-- {\n\t\t\tdata[j], data[j-1] = data[j-1], data[j]\n\t\t}\n\t}\n}\n\n// maxDepth returns a threshold at which quicksort should switch\n// to heapsort. It returns 2*ceil(lg(n+1)).\nfunc maxDepth(n int) int {\n\tvar depth int\n\tfor i := n; i > 0; i >>= 1 {\n\t\tdepth++\n\t}\n\treturn depth * 2\n}\n\n// medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1].\nfunc medianOfThree(data []literalNode, m1, m0, m2 int) {\n\t// sort 3 elements\n\tif data[m1].literal < data[m0].literal {\n\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t}\n\t// data[m0] <= data[m1]\n\tif data[m2].literal < data[m1].literal {\n\t\tdata[m2], data[m1] = data[m1], data[m2]\n\t\t// data[m0] <= data[m2] && data[m1] < data[m2]\n\t\tif data[m1].literal < data[m0].literal {\n\t\t\tdata[m1], data[m0] = data[m0], data[m1]\n\t\t}\n\t}\n\t// now data[m0] <= data[m1] <= data[m2]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/inflate.go",
    "content": "// Copyright 2009 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// Package flate implements the DEFLATE compressed data format, described in\n// RFC 1951.  The gzip and zlib packages implement access to DEFLATE-based file\n// formats.\npackage flate\n\nimport (\n\t\"bufio\"\n\t\"compress/flate\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/bits\"\n\t\"sync\"\n)\n\nconst (\n\tmaxCodeLen     = 16 // max length of Huffman code\n\tmaxCodeLenMask = 15 // mask for max length of Huffman code\n\t// The next three numbers come from the RFC section 3.2.7, with the\n\t// additional proviso in section 3.2.5 which implies that distance codes\n\t// 30 and 31 should never occur in compressed data.\n\tmaxNumLit  = 286\n\tmaxNumDist = 30\n\tnumCodes   = 19 // number of codes in Huffman meta-code\n\n\tdebugDecode = false\n)\n\n// Value of length - 3 and extra bits.\ntype lengthExtra struct {\n\tlength, extra uint8\n}\n\nvar decCodeToLen = [32]lengthExtra{{length: 0x0, extra: 0x0}, {length: 0x1, extra: 0x0}, {length: 0x2, extra: 0x0}, {length: 0x3, extra: 0x0}, {length: 0x4, extra: 0x0}, {length: 0x5, extra: 0x0}, {length: 0x6, extra: 0x0}, {length: 0x7, extra: 0x0}, {length: 0x8, extra: 0x1}, {length: 0xa, extra: 0x1}, {length: 0xc, extra: 0x1}, {length: 0xe, extra: 0x1}, {length: 0x10, extra: 0x2}, {length: 0x14, extra: 0x2}, {length: 0x18, extra: 0x2}, {length: 0x1c, extra: 0x2}, {length: 0x20, extra: 0x3}, {length: 0x28, extra: 0x3}, {length: 0x30, extra: 0x3}, {length: 0x38, extra: 0x3}, {length: 0x40, extra: 0x4}, {length: 0x50, extra: 0x4}, {length: 0x60, extra: 0x4}, {length: 0x70, extra: 0x4}, {length: 0x80, extra: 0x5}, {length: 0xa0, extra: 0x5}, {length: 0xc0, extra: 0x5}, {length: 0xe0, extra: 0x5}, {length: 0xff, extra: 0x0}, {length: 0x0, extra: 0x0}, {length: 0x0, extra: 0x0}, {length: 0x0, extra: 0x0}}\n\nvar bitMask32 = [32]uint32{\n\t0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF,\n\t0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,\n\t0x1ffff, 0x3ffff, 0x7FFFF, 0xfFFFF, 0x1fFFFF, 0x3fFFFF, 0x7fFFFF, 0xffFFFF,\n\t0x1ffFFFF, 0x3ffFFFF, 0x7ffFFFF, 0xfffFFFF, 0x1fffFFFF, 0x3fffFFFF, 0x7fffFFFF,\n} // up to 32 bits\n\n// Initialize the fixedHuffmanDecoder only once upon first use.\nvar fixedOnce sync.Once\nvar fixedHuffmanDecoder huffmanDecoder\n\n// A CorruptInputError reports the presence of corrupt input at a given offset.\ntype CorruptInputError = flate.CorruptInputError\n\n// An InternalError reports an error in the flate code itself.\ntype InternalError string\n\nfunc (e InternalError) Error() string { return \"flate: internal error: \" + string(e) }\n\n// A ReadError reports an error encountered while reading input.\n//\n// Deprecated: No longer returned.\ntype ReadError = flate.ReadError\n\n// A WriteError reports an error encountered while writing output.\n//\n// Deprecated: No longer returned.\ntype WriteError = flate.WriteError\n\n// Resetter resets a ReadCloser returned by NewReader or NewReaderDict to\n// to switch to a new underlying Reader. This permits reusing a ReadCloser\n// instead of allocating a new one.\ntype Resetter interface {\n\t// Reset discards any buffered data and resets the Resetter as if it was\n\t// newly initialized with the given reader.\n\tReset(r io.Reader, dict []byte) error\n}\n\n// The data structure for decoding Huffman tables is based on that of\n// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits),\n// For codes smaller than the table width, there are multiple entries\n// (each combination of trailing bits has the same value). For codes\n// larger than the table width, the table contains a link to an overflow\n// table. The width of each entry in the link table is the maximum code\n// size minus the chunk width.\n//\n// Note that you can do a lookup in the table even without all bits\n// filled. Since the extra bits are zero, and the DEFLATE Huffman codes\n// have the property that shorter codes come before longer ones, the\n// bit length estimate in the result is a lower bound on the actual\n// number of bits.\n//\n// See the following:\n//\thttp://www.gzip.org/algorithm.txt\n\n// chunk & 15 is number of bits\n// chunk >> 4 is value, including table link\n\nconst (\n\thuffmanChunkBits  = 9\n\thuffmanNumChunks  = 1 << huffmanChunkBits\n\thuffmanCountMask  = 15\n\thuffmanValueShift = 4\n)\n\ntype huffmanDecoder struct {\n\tmaxRead  int                       // the maximum number of bits we can read and not overread\n\tchunks   *[huffmanNumChunks]uint16 // chunks as described above\n\tlinks    [][]uint16                // overflow links\n\tlinkMask uint32                    // mask the width of the link table\n}\n\n// Initialize Huffman decoding tables from array of code lengths.\n// Following this function, h is guaranteed to be initialized into a complete\n// tree (i.e., neither over-subscribed nor under-subscribed). The exception is a\n// degenerate case where the tree has only a single symbol with length 1. Empty\n// trees are permitted.\nfunc (h *huffmanDecoder) init(lengths []int) bool {\n\t// Sanity enables additional runtime tests during Huffman\n\t// table construction. It's intended to be used during\n\t// development to supplement the currently ad-hoc unit tests.\n\tconst sanity = false\n\n\tif h.chunks == nil {\n\t\th.chunks = new([huffmanNumChunks]uint16)\n\t}\n\n\tif h.maxRead != 0 {\n\t\t*h = huffmanDecoder{chunks: h.chunks, links: h.links}\n\t}\n\n\t// Count number of codes of each length,\n\t// compute maxRead and max length.\n\tvar count [maxCodeLen]int\n\tvar min, max int\n\tfor _, n := range lengths {\n\t\tif n == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif min == 0 || n < min {\n\t\t\tmin = n\n\t\t}\n\t\tif n > max {\n\t\t\tmax = n\n\t\t}\n\t\tcount[n&maxCodeLenMask]++\n\t}\n\n\t// Empty tree. The decompressor.huffSym function will fail later if the tree\n\t// is used. Technically, an empty tree is only valid for the HDIST tree and\n\t// not the HCLEN and HLIT tree. However, a stream with an empty HCLEN tree\n\t// is guaranteed to fail since it will attempt to use the tree to decode the\n\t// codes for the HLIT and HDIST trees. Similarly, an empty HLIT tree is\n\t// guaranteed to fail later since the compressed data section must be\n\t// composed of at least one symbol (the end-of-block marker).\n\tif max == 0 {\n\t\treturn true\n\t}\n\n\tcode := 0\n\tvar nextcode [maxCodeLen]int\n\tfor i := min; i <= max; i++ {\n\t\tcode <<= 1\n\t\tnextcode[i&maxCodeLenMask] = code\n\t\tcode += count[i&maxCodeLenMask]\n\t}\n\n\t// Check that the coding is complete (i.e., that we've\n\t// assigned all 2-to-the-max possible bit sequences).\n\t// Exception: To be compatible with zlib, we also need to\n\t// accept degenerate single-code codings. See also\n\t// TestDegenerateHuffmanCoding.\n\tif code != 1<<uint(max) && !(code == 1 && max == 1) {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"coding failed, code, max:\", code, max, code == 1<<uint(max), code == 1 && max == 1, \"(one should be true)\")\n\t\t}\n\t\treturn false\n\t}\n\n\th.maxRead = min\n\n\tchunks := h.chunks[:]\n\tfor i := range chunks {\n\t\tchunks[i] = 0\n\t}\n\n\tif max > huffmanChunkBits {\n\t\tnumLinks := 1 << (uint(max) - huffmanChunkBits)\n\t\th.linkMask = uint32(numLinks - 1)\n\n\t\t// create link tables\n\t\tlink := nextcode[huffmanChunkBits+1] >> 1\n\t\tif cap(h.links) < huffmanNumChunks-link {\n\t\t\th.links = make([][]uint16, huffmanNumChunks-link)\n\t\t} else {\n\t\t\th.links = h.links[:huffmanNumChunks-link]\n\t\t}\n\t\tfor j := uint(link); j < huffmanNumChunks; j++ {\n\t\t\treverse := int(bits.Reverse16(uint16(j)))\n\t\t\treverse >>= uint(16 - huffmanChunkBits)\n\t\t\toff := j - uint(link)\n\t\t\tif sanity && h.chunks[reverse] != 0 {\n\t\t\t\tpanic(\"impossible: overwriting existing chunk\")\n\t\t\t}\n\t\t\th.chunks[reverse] = uint16(off<<huffmanValueShift | (huffmanChunkBits + 1))\n\t\t\tif cap(h.links[off]) < numLinks {\n\t\t\t\th.links[off] = make([]uint16, numLinks)\n\t\t\t} else {\n\t\t\t\th.links[off] = h.links[off][:numLinks]\n\t\t\t}\n\t\t}\n\t} else {\n\t\th.links = h.links[:0]\n\t}\n\n\tfor i, n := range lengths {\n\t\tif n == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tcode := nextcode[n]\n\t\tnextcode[n]++\n\t\tchunk := uint16(i<<huffmanValueShift | n)\n\t\treverse := int(bits.Reverse16(uint16(code)))\n\t\treverse >>= uint(16 - n)\n\t\tif n <= huffmanChunkBits {\n\t\t\tfor off := reverse; off < len(h.chunks); off += 1 << uint(n) {\n\t\t\t\t// We should never need to overwrite\n\t\t\t\t// an existing chunk. Also, 0 is\n\t\t\t\t// never a valid chunk, because the\n\t\t\t\t// lower 4 \"count\" bits should be\n\t\t\t\t// between 1 and 15.\n\t\t\t\tif sanity && h.chunks[off] != 0 {\n\t\t\t\t\tpanic(\"impossible: overwriting existing chunk\")\n\t\t\t\t}\n\t\t\t\th.chunks[off] = chunk\n\t\t\t}\n\t\t} else {\n\t\t\tj := reverse & (huffmanNumChunks - 1)\n\t\t\tif sanity && h.chunks[j]&huffmanCountMask != huffmanChunkBits+1 {\n\t\t\t\t// Longer codes should have been\n\t\t\t\t// associated with a link table above.\n\t\t\t\tpanic(\"impossible: not an indirect chunk\")\n\t\t\t}\n\t\t\tvalue := h.chunks[j] >> huffmanValueShift\n\t\t\tlinktab := h.links[value]\n\t\t\treverse >>= huffmanChunkBits\n\t\t\tfor off := reverse; off < len(linktab); off += 1 << uint(n-huffmanChunkBits) {\n\t\t\t\tif sanity && linktab[off] != 0 {\n\t\t\t\t\tpanic(\"impossible: overwriting existing chunk\")\n\t\t\t\t}\n\t\t\t\tlinktab[off] = chunk\n\t\t\t}\n\t\t}\n\t}\n\n\tif sanity {\n\t\t// Above we've sanity checked that we never overwrote\n\t\t// an existing entry. Here we additionally check that\n\t\t// we filled the tables completely.\n\t\tfor i, chunk := range h.chunks {\n\t\t\tif chunk == 0 {\n\t\t\t\t// As an exception, in the degenerate\n\t\t\t\t// single-code case, we allow odd\n\t\t\t\t// chunks to be missing.\n\t\t\t\tif code == 1 && i%2 == 1 {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tpanic(\"impossible: missing chunk\")\n\t\t\t}\n\t\t}\n\t\tfor _, linktab := range h.links {\n\t\t\tfor _, chunk := range linktab {\n\t\t\t\tif chunk == 0 {\n\t\t\t\t\tpanic(\"impossible: missing chunk\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\n// Reader is the actual read interface needed by NewReader.\n// If the passed in io.Reader does not also have ReadByte,\n// the NewReader will introduce its own buffering.\ntype Reader interface {\n\tio.Reader\n\tio.ByteReader\n}\n\ntype step uint8\n\nconst (\n\tcopyData step = iota + 1\n\tnextBlock\n\thuffmanBytesBuffer\n\thuffmanBytesReader\n\thuffmanBufioReader\n\thuffmanStringsReader\n\thuffmanGenericReader\n)\n\n// Decompress state.\ntype decompressor struct {\n\t// Input source.\n\tr       Reader\n\troffset int64\n\n\t// Huffman decoders for literal/length, distance.\n\th1, h2 huffmanDecoder\n\n\t// Length arrays used to define Huffman codes.\n\tbits     *[maxNumLit + maxNumDist]int\n\tcodebits *[numCodes]int\n\n\t// Output history, buffer.\n\tdict dictDecoder\n\n\t// Next step in the decompression,\n\t// and decompression state.\n\tstep      step\n\tstepState int\n\terr       error\n\ttoRead    []byte\n\thl, hd    *huffmanDecoder\n\tcopyLen   int\n\tcopyDist  int\n\n\t// Temporary buffer (avoids repeated allocation).\n\tbuf [4]byte\n\n\t// Input bits, in top of b.\n\tb uint32\n\n\tnb    uint\n\tfinal bool\n}\n\nfunc (f *decompressor) nextBlock() {\n\tfor f.nb < 1+2 {\n\t\tif f.err = f.moreBits(); f.err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\tf.final = f.b&1 == 1\n\tf.b >>= 1\n\ttyp := f.b & 3\n\tf.b >>= 2\n\tf.nb -= 1 + 2\n\tswitch typ {\n\tcase 0:\n\t\tf.dataBlock()\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"stored block\")\n\t\t}\n\tcase 1:\n\t\t// compressed, fixed Huffman tables\n\t\tf.hl = &fixedHuffmanDecoder\n\t\tf.hd = nil\n\t\tf.huffmanBlockDecoder()\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"predefinied huffman block\")\n\t\t}\n\tcase 2:\n\t\t// compressed, dynamic Huffman tables\n\t\tif f.err = f.readHuffman(); f.err != nil {\n\t\t\tbreak\n\t\t}\n\t\tf.hl = &f.h1\n\t\tf.hd = &f.h2\n\t\tf.huffmanBlockDecoder()\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"dynamic huffman block\")\n\t\t}\n\tdefault:\n\t\t// 3 is reserved.\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"reserved data block encountered\")\n\t\t}\n\t\tf.err = CorruptInputError(f.roffset)\n\t}\n}\n\nfunc (f *decompressor) Read(b []byte) (int, error) {\n\tfor {\n\t\tif len(f.toRead) > 0 {\n\t\t\tn := copy(b, f.toRead)\n\t\t\tf.toRead = f.toRead[n:]\n\t\t\tif len(f.toRead) == 0 {\n\t\t\t\treturn n, f.err\n\t\t\t}\n\t\t\treturn n, nil\n\t\t}\n\t\tif f.err != nil {\n\t\t\treturn 0, f.err\n\t\t}\n\n\t\tf.doStep()\n\n\t\tif f.err != nil && len(f.toRead) == 0 {\n\t\t\tf.toRead = f.dict.readFlush() // Flush what's left in case of error\n\t\t}\n\t}\n}\n\n// WriteTo implements the io.WriteTo interface for io.Copy and friends.\nfunc (f *decompressor) WriteTo(w io.Writer) (int64, error) {\n\ttotal := int64(0)\n\tflushed := false\n\tfor {\n\t\tif len(f.toRead) > 0 {\n\t\t\tn, err := w.Write(f.toRead)\n\t\t\ttotal += int64(n)\n\t\t\tif err != nil {\n\t\t\t\tf.err = err\n\t\t\t\treturn total, err\n\t\t\t}\n\t\t\tif n != len(f.toRead) {\n\t\t\t\treturn total, io.ErrShortWrite\n\t\t\t}\n\t\t\tf.toRead = f.toRead[:0]\n\t\t}\n\t\tif f.err != nil && flushed {\n\t\t\tif f.err == io.EOF {\n\t\t\t\treturn total, nil\n\t\t\t}\n\t\t\treturn total, f.err\n\t\t}\n\t\tif f.err == nil {\n\t\t\tf.doStep()\n\t\t}\n\t\tif len(f.toRead) == 0 && f.err != nil && !flushed {\n\t\t\tf.toRead = f.dict.readFlush() // Flush what's left in case of error\n\t\t\tflushed = true\n\t\t}\n\t}\n}\n\nfunc (f *decompressor) Close() error {\n\tif f.err == io.EOF {\n\t\treturn nil\n\t}\n\treturn f.err\n}\n\n// RFC 1951 section 3.2.7.\n// Compression with dynamic Huffman codes\n\nvar codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}\n\nfunc (f *decompressor) readHuffman() error {\n\t// HLIT[5], HDIST[5], HCLEN[4].\n\tfor f.nb < 5+5+4 {\n\t\tif err := f.moreBits(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tnlit := int(f.b&0x1F) + 257\n\tif nlit > maxNumLit {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"nlit > maxNumLit\", nlit)\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\tf.b >>= 5\n\tndist := int(f.b&0x1F) + 1\n\tif ndist > maxNumDist {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"ndist > maxNumDist\", ndist)\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\tf.b >>= 5\n\tnclen := int(f.b&0xF) + 4\n\t// numCodes is 19, so nclen is always valid.\n\tf.b >>= 4\n\tf.nb -= 5 + 5 + 4\n\n\t// (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.\n\tfor i := 0; i < nclen; i++ {\n\t\tfor f.nb < 3 {\n\t\t\tif err := f.moreBits(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tf.codebits[codeOrder[i]] = int(f.b & 0x7)\n\t\tf.b >>= 3\n\t\tf.nb -= 3\n\t}\n\tfor i := nclen; i < len(codeOrder); i++ {\n\t\tf.codebits[codeOrder[i]] = 0\n\t}\n\tif !f.h1.init(f.codebits[0:]) {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"init codebits failed\")\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\n\t// HLIT + 257 code lengths, HDIST + 1 code lengths,\n\t// using the code length Huffman code.\n\tfor i, n := 0, nlit+ndist; i < n; {\n\t\tx, err := f.huffSym(&f.h1)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif x < 16 {\n\t\t\t// Actual length.\n\t\t\tf.bits[i] = x\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\t// Repeat previous length or zero.\n\t\tvar rep int\n\t\tvar nb uint\n\t\tvar b int\n\t\tswitch x {\n\t\tdefault:\n\t\t\treturn InternalError(\"unexpected length code\")\n\t\tcase 16:\n\t\t\trep = 3\n\t\t\tnb = 2\n\t\t\tif i == 0 {\n\t\t\t\tif debugDecode {\n\t\t\t\t\tfmt.Println(\"i==0\")\n\t\t\t\t}\n\t\t\t\treturn CorruptInputError(f.roffset)\n\t\t\t}\n\t\t\tb = f.bits[i-1]\n\t\tcase 17:\n\t\t\trep = 3\n\t\t\tnb = 3\n\t\t\tb = 0\n\t\tcase 18:\n\t\t\trep = 11\n\t\t\tnb = 7\n\t\t\tb = 0\n\t\t}\n\t\tfor f.nb < nb {\n\t\t\tif err := f.moreBits(); err != nil {\n\t\t\t\tif debugDecode {\n\t\t\t\t\tfmt.Println(\"morebits:\", err)\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\trep += int(f.b & uint32(1<<(nb&regSizeMaskUint32)-1))\n\t\tf.b >>= nb & regSizeMaskUint32\n\t\tf.nb -= nb\n\t\tif i+rep > n {\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"i+rep > n\", i, rep, n)\n\t\t\t}\n\t\t\treturn CorruptInputError(f.roffset)\n\t\t}\n\t\tfor j := 0; j < rep; j++ {\n\t\t\tf.bits[i] = b\n\t\t\ti++\n\t\t}\n\t}\n\n\tif !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {\n\t\tif debugDecode {\n\t\t\tfmt.Println(\"init2 failed\")\n\t\t}\n\t\treturn CorruptInputError(f.roffset)\n\t}\n\n\t// As an optimization, we can initialize the maxRead bits to read at a time\n\t// for the HLIT tree to the length of the EOB marker since we know that\n\t// every block must terminate with one. This preserves the property that\n\t// we never read any extra bytes after the end of the DEFLATE stream.\n\tif f.h1.maxRead < f.bits[endBlockMarker] {\n\t\tf.h1.maxRead = f.bits[endBlockMarker]\n\t}\n\tif !f.final {\n\t\t// If not the final block, the smallest block possible is\n\t\t// a predefined table, BTYPE=01, with a single EOB marker.\n\t\t// This will take up 3 + 7 bits.\n\t\tf.h1.maxRead += 10\n\t}\n\n\treturn nil\n}\n\n// Copy a single uncompressed data block from input to output.\nfunc (f *decompressor) dataBlock() {\n\t// Uncompressed.\n\t// Discard current half-byte.\n\tleft := (f.nb) & 7\n\tf.nb -= left\n\tf.b >>= left\n\n\toffBytes := f.nb >> 3\n\t// Unfilled values will be overwritten.\n\tf.buf[0] = uint8(f.b)\n\tf.buf[1] = uint8(f.b >> 8)\n\tf.buf[2] = uint8(f.b >> 16)\n\tf.buf[3] = uint8(f.b >> 24)\n\n\tf.roffset += int64(offBytes)\n\tf.nb, f.b = 0, 0\n\n\t// Length then ones-complement of length.\n\tnr, err := io.ReadFull(f.r, f.buf[offBytes:4])\n\tf.roffset += int64(nr)\n\tif err != nil {\n\t\tf.err = noEOF(err)\n\t\treturn\n\t}\n\tn := uint16(f.buf[0]) | uint16(f.buf[1])<<8\n\tnn := uint16(f.buf[2]) | uint16(f.buf[3])<<8\n\tif nn != ^n {\n\t\tif debugDecode {\n\t\t\tncomp := ^n\n\t\t\tfmt.Println(\"uint16(nn) != uint16(^n)\", nn, ncomp)\n\t\t}\n\t\tf.err = CorruptInputError(f.roffset)\n\t\treturn\n\t}\n\n\tif n == 0 {\n\t\tf.toRead = f.dict.readFlush()\n\t\tf.finishBlock()\n\t\treturn\n\t}\n\n\tf.copyLen = int(n)\n\tf.copyData()\n}\n\n// copyData copies f.copyLen bytes from the underlying reader into f.hist.\n// It pauses for reads when f.hist is full.\nfunc (f *decompressor) copyData() {\n\tbuf := f.dict.writeSlice()\n\tif len(buf) > f.copyLen {\n\t\tbuf = buf[:f.copyLen]\n\t}\n\n\tcnt, err := io.ReadFull(f.r, buf)\n\tf.roffset += int64(cnt)\n\tf.copyLen -= cnt\n\tf.dict.writeMark(cnt)\n\tif err != nil {\n\t\tf.err = noEOF(err)\n\t\treturn\n\t}\n\n\tif f.dict.availWrite() == 0 || f.copyLen > 0 {\n\t\tf.toRead = f.dict.readFlush()\n\t\tf.step = copyData\n\t\treturn\n\t}\n\tf.finishBlock()\n}\n\nfunc (f *decompressor) finishBlock() {\n\tif f.final {\n\t\tif f.dict.availRead() > 0 {\n\t\t\tf.toRead = f.dict.readFlush()\n\t\t}\n\t\tf.err = io.EOF\n\t}\n\tf.step = nextBlock\n}\n\nfunc (f *decompressor) doStep() {\n\tswitch f.step {\n\tcase copyData:\n\t\tf.copyData()\n\tcase nextBlock:\n\t\tf.nextBlock()\n\tcase huffmanBytesBuffer:\n\t\tf.huffmanBytesBuffer()\n\tcase huffmanBytesReader:\n\t\tf.huffmanBytesReader()\n\tcase huffmanBufioReader:\n\t\tf.huffmanBufioReader()\n\tcase huffmanStringsReader:\n\t\tf.huffmanStringsReader()\n\tcase huffmanGenericReader:\n\t\tf.huffmanGenericReader()\n\tdefault:\n\t\tpanic(\"BUG: unexpected step state\")\n\t}\n}\n\n// noEOF returns err, unless err == io.EOF, in which case it returns io.ErrUnexpectedEOF.\nfunc noEOF(e error) error {\n\tif e == io.EOF {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn e\n}\n\nfunc (f *decompressor) moreBits() error {\n\tc, err := f.r.ReadByte()\n\tif err != nil {\n\t\treturn noEOF(err)\n\t}\n\tf.roffset++\n\tf.b |= uint32(c) << (f.nb & regSizeMaskUint32)\n\tf.nb += 8\n\treturn nil\n}\n\n// Read the next Huffman-encoded symbol from f according to h.\nfunc (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {\n\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t// with single element, huffSym must error on these two edge cases. In both\n\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t// satisfy the n == 0 check below.\n\tn := uint(h.maxRead)\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tnb, b := f.nb, f.b\n\tfor {\n\t\tfor nb < n {\n\t\t\tc, err := f.r.ReadByte()\n\t\t\tif err != nil {\n\t\t\t\tf.b = b\n\t\t\t\tf.nb = nb\n\t\t\t\treturn 0, noEOF(err)\n\t\t\t}\n\t\t\tf.roffset++\n\t\t\tb |= uint32(c) << (nb & regSizeMaskUint32)\n\t\t\tnb += 8\n\t\t}\n\t\tchunk := h.chunks[b&(huffmanNumChunks-1)]\n\t\tn = uint(chunk & huffmanCountMask)\n\t\tif n > huffmanChunkBits {\n\t\t\tchunk = h.links[chunk>>huffmanValueShift][(b>>huffmanChunkBits)&h.linkMask]\n\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t}\n\t\tif n <= nb {\n\t\t\tif n == 0 {\n\t\t\t\tf.b = b\n\t\t\t\tf.nb = nb\n\t\t\t\tif debugDecode {\n\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t}\n\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\treturn 0, f.err\n\t\t\t}\n\t\t\tf.b = b >> (n & regSizeMaskUint32)\n\t\t\tf.nb = nb - n\n\t\t\treturn int(chunk >> huffmanValueShift), nil\n\t\t}\n\t}\n}\n\nfunc makeReader(r io.Reader) Reader {\n\tif rr, ok := r.(Reader); ok {\n\t\treturn rr\n\t}\n\treturn bufio.NewReader(r)\n}\n\nfunc fixedHuffmanDecoderInit() {\n\tfixedOnce.Do(func() {\n\t\t// These come from the RFC section 3.2.6.\n\t\tvar bits [288]int\n\t\tfor i := 0; i < 144; i++ {\n\t\t\tbits[i] = 8\n\t\t}\n\t\tfor i := 144; i < 256; i++ {\n\t\t\tbits[i] = 9\n\t\t}\n\t\tfor i := 256; i < 280; i++ {\n\t\t\tbits[i] = 7\n\t\t}\n\t\tfor i := 280; i < 288; i++ {\n\t\t\tbits[i] = 8\n\t\t}\n\t\tfixedHuffmanDecoder.init(bits[:])\n\t})\n}\n\nfunc (f *decompressor) Reset(r io.Reader, dict []byte) error {\n\t*f = decompressor{\n\t\tr:        makeReader(r),\n\t\tbits:     f.bits,\n\t\tcodebits: f.codebits,\n\t\th1:       f.h1,\n\t\th2:       f.h2,\n\t\tdict:     f.dict,\n\t\tstep:     nextBlock,\n\t}\n\tf.dict.init(maxMatchOffset, dict)\n\treturn nil\n}\n\n// NewReader returns a new ReadCloser that can be used\n// to read the uncompressed version of r.\n// If r does not also implement io.ByteReader,\n// the decompressor may read more data than necessary from r.\n// It is the caller's responsibility to call Close on the ReadCloser\n// when finished reading.\n//\n// The ReadCloser returned by NewReader also implements Resetter.\nfunc NewReader(r io.Reader) io.ReadCloser {\n\tfixedHuffmanDecoderInit()\n\n\tvar f decompressor\n\tf.r = makeReader(r)\n\tf.bits = new([maxNumLit + maxNumDist]int)\n\tf.codebits = new([numCodes]int)\n\tf.step = nextBlock\n\tf.dict.init(maxMatchOffset, nil)\n\treturn &f\n}\n\n// NewReaderDict is like NewReader but initializes the reader\n// with a preset dictionary. The returned Reader behaves as if\n// the uncompressed data stream started with the given dictionary,\n// which has already been read. NewReaderDict is typically used\n// to read data compressed by NewWriterDict.\n//\n// The ReadCloser returned by NewReader also implements Resetter.\nfunc NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {\n\tfixedHuffmanDecoderInit()\n\n\tvar f decompressor\n\tf.r = makeReader(r)\n\tf.bits = new([maxNumLit + maxNumDist]int)\n\tf.codebits = new([numCodes]int)\n\tf.step = nextBlock\n\tf.dict.init(maxMatchOffset, dict)\n\treturn &f\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/inflate_gen.go",
    "content": "// Code generated by go generate gen_inflate.go. DO NOT EDIT.\n\npackage flate\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"math/bits\"\n\t\"strings\"\n)\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanBytesBuffer() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*bytes.Buffer)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanBytesBuffer\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanBytesBuffer // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanBytesReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*bytes.Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanBytesReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanBytesReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanBufioReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*bufio.Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanBufioReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanBufioReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanStringsReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(*strings.Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanStringsReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanStringsReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\n// Decode a single Huffman block from f.\n// hl and hd are the Huffman states for the lit/length values\n// and the distance values, respectively. If hd == nil, using the\n// fixed distance encoding associated with fixed Huffman blocks.\nfunc (f *decompressor) huffmanGenericReader() {\n\tconst (\n\t\tstateInit = iota // Zero value must be stateInit\n\t\tstateDict\n\t)\n\tfr := f.r.(Reader)\n\n\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t// inline call to moreBits and reassign b,nb back to f on return.\n\tfnb, fb, dict := f.nb, f.b, &f.dict\n\n\tswitch f.stepState {\n\tcase stateInit:\n\t\tgoto readLiteral\n\tcase stateDict:\n\t\tgoto copyHistory\n\t}\n\nreadLiteral:\n\t// Read literal and/or (length, distance) according to RFC section 3.2.3.\n\t{\n\t\tvar v int\n\t\t{\n\t\t\t// Inlined v, err := f.huffSym(f.hl)\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hl.maxRead)\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hl.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hl.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hl.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tv = int(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvar length int\n\t\tswitch {\n\t\tcase v < 256:\n\t\t\tdict.writeByte(byte(v))\n\t\t\tif dict.availWrite() == 0 {\n\t\t\t\tf.toRead = dict.readFlush()\n\t\t\t\tf.step = huffmanGenericReader\n\t\t\t\tf.stepState = stateInit\n\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\treturn\n\t\t\t}\n\t\t\tgoto readLiteral\n\t\tcase v == 256:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tf.finishBlock()\n\t\t\treturn\n\t\t// otherwise, reference to older data\n\t\tcase v < 265:\n\t\t\tlength = v - (257 - 3)\n\t\tcase v < maxNumLit:\n\t\t\tval := decCodeToLen[(v - 257)]\n\t\t\tlength = int(val.length) + 3\n\t\t\tn := uint(val.extra)\n\t\t\tfor fnb < n {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits n>0:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tlength += int(fb & bitMask32[n])\n\t\t\tfb >>= n & regSizeMaskUint32\n\t\t\tfnb -= n\n\t\tdefault:\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(v, \">= maxNumLit\")\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\n\t\tvar dist uint32\n\t\tif f.hd == nil {\n\t\t\tfor fnb < 5 {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<5:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\tdist = uint32(bits.Reverse8(uint8(fb & 0x1F << 3)))\n\t\t\tfb >>= 5\n\t\t\tfnb -= 5\n\t\t} else {\n\t\t\t// Since a huffmanDecoder can be empty or be composed of a degenerate tree\n\t\t\t// with single element, huffSym must error on these two edge cases. In both\n\t\t\t// cases, the chunks slice will be 0 for the invalid sequence, leading it\n\t\t\t// satisfy the n == 0 check below.\n\t\t\tn := uint(f.hd.maxRead)\n\t\t\t// Optimization. Compiler isn't smart enough to keep f.b,f.nb in registers,\n\t\t\t// but is smart enough to keep local variables in registers, so use nb and b,\n\t\t\t// inline call to moreBits and reassign b,nb back to f on return.\n\t\t\tfor {\n\t\t\t\tfor fnb < n {\n\t\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tf.err = noEOF(err)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tf.roffset++\n\t\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\t\tfnb += 8\n\t\t\t\t}\n\t\t\t\tchunk := f.hd.chunks[fb&(huffmanNumChunks-1)]\n\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\tif n > huffmanChunkBits {\n\t\t\t\t\tchunk = f.hd.links[chunk>>huffmanValueShift][(fb>>huffmanChunkBits)&f.hd.linkMask]\n\t\t\t\t\tn = uint(chunk & huffmanCountMask)\n\t\t\t\t}\n\t\t\t\tif n <= fnb {\n\t\t\t\t\tif n == 0 {\n\t\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\t\tfmt.Println(\"huffsym: n==0\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tfb = fb >> (n & regSizeMaskUint32)\n\t\t\t\t\tfnb = fnb - n\n\t\t\t\t\tdist = uint32(chunk >> huffmanValueShift)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tswitch {\n\t\tcase dist < 4:\n\t\t\tdist++\n\t\tcase dist < maxNumDist:\n\t\t\tnb := uint(dist-2) >> 1\n\t\t\t// have 1 bit in bottom of dist, need nb more.\n\t\t\textra := (dist & 1) << (nb & regSizeMaskUint32)\n\t\t\tfor fnb < nb {\n\t\t\t\tc, err := fr.ReadByte()\n\t\t\t\tif err != nil {\n\t\t\t\t\tf.b, f.nb = fb, fnb\n\t\t\t\t\tif debugDecode {\n\t\t\t\t\t\tfmt.Println(\"morebits f.nb<nb:\", err)\n\t\t\t\t\t}\n\t\t\t\t\tf.err = err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tf.roffset++\n\t\t\t\tfb |= uint32(c) << (fnb & regSizeMaskUint32)\n\t\t\t\tfnb += 8\n\t\t\t}\n\t\t\textra |= fb & bitMask32[nb]\n\t\t\tfb >>= nb & regSizeMaskUint32\n\t\t\tfnb -= nb\n\t\t\tdist = 1<<((nb+1)&regSizeMaskUint32) + 1 + extra\n\t\t\t// slower: dist = bitMask32[nb+1] + 2 + extra\n\t\tdefault:\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist too big:\", dist, maxNumDist)\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\t// No check on length; encoding can be prescient.\n\t\tif dist > uint32(dict.histSize()) {\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\tif debugDecode {\n\t\t\t\tfmt.Println(\"dist > dict.histSize():\", dist, dict.histSize())\n\t\t\t}\n\t\t\tf.err = CorruptInputError(f.roffset)\n\t\t\treturn\n\t\t}\n\n\t\tf.copyLen, f.copyDist = length, int(dist)\n\t\tgoto copyHistory\n\t}\n\ncopyHistory:\n\t// Perform a backwards copy according to RFC section 3.2.3.\n\t{\n\t\tcnt := dict.tryWriteCopy(f.copyDist, f.copyLen)\n\t\tif cnt == 0 {\n\t\t\tcnt = dict.writeCopy(f.copyDist, f.copyLen)\n\t\t}\n\t\tf.copyLen -= cnt\n\n\t\tif dict.availWrite() == 0 || f.copyLen > 0 {\n\t\t\tf.toRead = dict.readFlush()\n\t\t\tf.step = huffmanGenericReader // We need to continue this work\n\t\t\tf.stepState = stateDict\n\t\t\tf.b, f.nb = fb, fnb\n\t\t\treturn\n\t\t}\n\t\tgoto readLiteral\n\t}\n\t// Not reached\n}\n\nfunc (f *decompressor) huffmanBlockDecoder() {\n\tswitch f.r.(type) {\n\tcase *bytes.Buffer:\n\t\tf.huffmanBytesBuffer()\n\tcase *bytes.Reader:\n\t\tf.huffmanBytesReader()\n\tcase *bufio.Reader:\n\t\tf.huffmanBufioReader()\n\tcase *strings.Reader:\n\t\tf.huffmanStringsReader()\n\tcase Reader:\n\t\tf.huffmanGenericReader()\n\tdefault:\n\t\tf.huffmanGenericReader()\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level1.go",
    "content": "package flate\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math/bits\"\n)\n\n// fastGen maintains the table for matches,\n// and the previous byte block for level 2.\n// This is the generic implementation.\ntype fastEncL1 struct {\n\tfastGen\n\ttable [tableSize]tableEntry\n}\n\n// EncodeL1 uses a similar algorithm to level 1\nfunc (e *fastEncL1) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashBytes              = 5\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\n\tfor {\n\t\tconst skipLog = 5\n\t\tconst doEvery = 2\n\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tfor {\n\t\t\tnextHash := hashLen(cv, tableBits, hashBytes)\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\tnow := load6432(src, nextS)\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\t\t\tnextHash = hashLen(now, tableBits, hashBytes)\n\n\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\tif offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\te.table[nextHash] = tableEntry{offset: nextS + e.cur}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Do one right away...\n\t\t\tcv = now\n\t\t\ts = nextS\n\t\t\tnextS++\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnow >>= 8\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\n\t\t\toffset = s - (candidate.offset - e.cur)\n\t\t\tif offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\te.table[nextHash] = tableEntry{offset: nextS + e.cur}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = now\n\t\t\ts = nextS\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tt := candidate.offset - e.cur\n\t\t\tvar l = int32(4)\n\t\t\tif false {\n\t\t\t\tl = e.matchlenLong(s+4, t+4, src) + 4\n\t\t\t} else {\n\t\t\t\t// inlined:\n\t\t\t\ta := src[s+4:]\n\t\t\t\tb := src[t+4:]\n\t\t\t\tfor len(a) >= 8 {\n\t\t\t\t\tif diff := binary.LittleEndian.Uint64(a) ^ binary.LittleEndian.Uint64(b); diff != 0 {\n\t\t\t\t\t\tl += int32(bits.TrailingZeros64(diff) >> 3)\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tl += 8\n\t\t\t\t\ta = a[8:]\n\t\t\t\t\tb = b[8:]\n\t\t\t\t}\n\t\t\t\tif len(a) < 8 {\n\t\t\t\t\tb = b[:len(a)]\n\t\t\t\t\tfor i := range a {\n\t\t\t\t\t\tif a[i] != b[i] {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tl++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Save the match found\n\t\t\tif false {\n\t\t\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\t\t} else {\n\t\t\t\t// Inlined...\n\t\t\t\txoffset := uint32(s - t - baseMatchOffset)\n\t\t\t\txlength := l\n\t\t\t\toc := offsetCode(xoffset)\n\t\t\t\txoffset |= oc << 16\n\t\t\t\tfor xlength > 0 {\n\t\t\t\t\txl := xlength\n\t\t\t\t\tif xl > 258 {\n\t\t\t\t\t\tif xl > 258+baseMatchLength {\n\t\t\t\t\t\t\txl = 258\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\txl = 258 - baseMatchLength\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\txlength -= xl\n\t\t\t\t\txl -= baseMatchLength\n\t\t\t\t\tdst.extraHist[lengthCodes1[uint8(xl)]]++\n\t\t\t\t\tdst.offHist[oc]++\n\t\t\t\t\tdst.tokens[dst.n] = token(matchType | uint32(xl)<<lengthShift | xoffset)\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\t\t\tif s >= sLimit {\n\t\t\t\t// Index first pair after match end.\n\t\t\t\tif int(s+l+8) < len(src) {\n\t\t\t\t\tcv := load6432(src, s)\n\t\t\t\t\te.table[hashLen(cv, tableBits, hashBytes)] = tableEntry{offset: s + e.cur}\n\t\t\t\t}\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 and at s. If\n\t\t\t// another emitCopy is not our next move, also calculate nextHash\n\t\t\t// at s+1. At least on GOARCH=amd64, these three hash calculations\n\t\t\t// are faster as one load64 call (with some shifts) instead of\n\t\t\t// three load32 calls.\n\t\t\tx := load6432(src, s-2)\n\t\t\to := e.cur + s - 2\n\t\t\tprevHash := hashLen(x, tableBits, hashBytes)\n\t\t\te.table[prevHash] = tableEntry{offset: o}\n\t\t\tx >>= 16\n\t\t\tcurrHash := hashLen(x, tableBits, hashBytes)\n\t\t\tcandidate = e.table[currHash]\n\t\t\te.table[currHash] = tableEntry{offset: o + 2}\n\n\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\tif offset > maxMatchOffset || uint32(x) != load3232(src, candidate.offset-e.cur) {\n\t\t\t\tcv = x >> 8\n\t\t\t\ts++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level2.go",
    "content": "package flate\n\nimport \"fmt\"\n\n// fastGen maintains the table for matches,\n// and the previous byte block for level 2.\n// This is the generic implementation.\ntype fastEncL2 struct {\n\tfastGen\n\ttable [bTableSize]tableEntry\n}\n\n// EncodeL2 uses a similar algorithm to level 1, but is capable\n// of matching across blocks giving better compression at a small slowdown.\nfunc (e *fastEncL2) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashBytes              = 5\n\t)\n\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\t// When should we start skipping if we haven't found matches in a long while.\n\t\tconst skipLog = 5\n\t\tconst doEvery = 2\n\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tfor {\n\t\t\tnextHash := hashLen(cv, bTableBits, hashBytes)\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnow := load6432(src, nextS)\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\t\t\tnextHash = hashLen(now, bTableBits, hashBytes)\n\n\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\tif offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\te.table[nextHash] = tableEntry{offset: nextS + e.cur}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Do one right away...\n\t\t\tcv = now\n\t\t\ts = nextS\n\t\t\tnextS++\n\t\t\tcandidate = e.table[nextHash]\n\t\t\tnow >>= 8\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur}\n\n\t\t\toffset = s - (candidate.offset - e.cur)\n\t\t\tif offset < maxMatchOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = now\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\t// Call emitCopy, and then see if another emitCopy could be our next\n\t\t// move. Repeat until we find no match for the input immediately after\n\t\t// what was consumed by the last emitCopy call.\n\t\t//\n\t\t// If we exit this loop normally then we need to call emitLiteral next,\n\t\t// though we don't yet know how big the literal will be. We handle that\n\t\t// by proceeding to the next iteration of the main loop. We also can\n\t\t// exit this loop via goto if we get close to exhausting the input.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tt := candidate.offset - e.cur\n\t\t\tl := e.matchlenLong(s+4, t+4, src) + 4\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\n\t\t\tif s >= sLimit {\n\t\t\t\t// Index first pair after match end.\n\t\t\t\tif int(s+l+8) < len(src) {\n\t\t\t\t\tcv := load6432(src, s)\n\t\t\t\t\te.table[hashLen(cv, bTableBits, hashBytes)] = tableEntry{offset: s + e.cur}\n\t\t\t\t}\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// Store every second hash in-between, but offset by 1.\n\t\t\tfor i := s - l + 2; i < s-5; i += 7 {\n\t\t\t\tx := load6432(src, i)\n\t\t\t\tnextHash := hashLen(x, bTableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntry{offset: e.cur + i}\n\t\t\t\t// Skip one\n\t\t\t\tx >>= 16\n\t\t\t\tnextHash = hashLen(x, bTableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntry{offset: e.cur + i + 2}\n\t\t\t\t// Skip one\n\t\t\t\tx >>= 16\n\t\t\t\tnextHash = hashLen(x, bTableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntry{offset: e.cur + i + 4}\n\t\t\t}\n\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 to s. If\n\t\t\t// another emitCopy is not our next move, also calculate nextHash\n\t\t\t// at s+1. At least on GOARCH=amd64, these three hash calculations\n\t\t\t// are faster as one load64 call (with some shifts) instead of\n\t\t\t// three load32 calls.\n\t\t\tx := load6432(src, s-2)\n\t\t\to := e.cur + s - 2\n\t\t\tprevHash := hashLen(x, bTableBits, hashBytes)\n\t\t\tprevHash2 := hashLen(x>>8, bTableBits, hashBytes)\n\t\t\te.table[prevHash] = tableEntry{offset: o}\n\t\t\te.table[prevHash2] = tableEntry{offset: o + 1}\n\t\t\tcurrHash := hashLen(x>>16, bTableBits, hashBytes)\n\t\t\tcandidate = e.table[currHash]\n\t\t\te.table[currHash] = tableEntry{offset: o + 2}\n\n\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\tif offset > maxMatchOffset || uint32(x>>16) != load3232(src, candidate.offset-e.cur) {\n\t\t\t\tcv = x >> 24\n\t\t\t\ts++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level3.go",
    "content": "package flate\n\nimport \"fmt\"\n\n// fastEncL3\ntype fastEncL3 struct {\n\tfastGen\n\ttable [1 << 16]tableEntryPrev\n}\n\n// Encode uses a similar algorithm to level 2, will check up to two candidates.\nfunc (e *fastEncL3) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\ttableBits              = 16\n\t\ttableSize              = 1 << tableBits\n\t\thashBytes              = 5\n\t)\n\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// Skip if too small.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 7\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tfor {\n\t\t\tnextHash := hashLen(cv, tableBits, hashBytes)\n\t\t\ts = nextS\n\t\t\tnextS = s + 1 + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\tcandidates := e.table[nextHash]\n\t\t\tnow := load6432(src, nextS)\n\n\t\t\t// Safe offset distance until s + 4...\n\t\t\tminOffset := e.cur + s - (maxMatchOffset - 4)\n\t\t\te.table[nextHash] = tableEntryPrev{Prev: candidates.Cur, Cur: tableEntry{offset: s + e.cur}}\n\n\t\t\t// Check both candidates\n\t\t\tcandidate = candidates.Cur\n\t\t\tif candidate.offset < minOffset {\n\t\t\t\tcv = now\n\t\t\t\t// Previous will also be invalid, we have nothing.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\tif candidates.Prev.offset < minOffset || uint32(cv) != load3232(src, candidates.Prev.offset-e.cur) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// Both match and are valid, pick longest.\n\t\t\t\toffset := s - (candidate.offset - e.cur)\n\t\t\t\to2 := s - (candidates.Prev.offset - e.cur)\n\t\t\t\tl1, l2 := matchLen(src[s+4:], src[s-offset+4:]), matchLen(src[s+4:], src[s-o2+4:])\n\t\t\t\tif l2 > l1 {\n\t\t\t\t\tcandidate = candidates.Prev\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\t// We only check if value mismatches.\n\t\t\t\t// Offset will always be invalid in other cases.\n\t\t\t\tcandidate = candidates.Prev\n\t\t\t\tif candidate.offset > minOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tcv = now\n\t\t}\n\n\t\t// Call emitCopy, and then see if another emitCopy could be our next\n\t\t// move. Repeat until we find no match for the input immediately after\n\t\t// what was consumed by the last emitCopy call.\n\t\t//\n\t\t// If we exit this loop normally then we need to call emitLiteral next,\n\t\t// though we don't yet know how big the literal will be. We handle that\n\t\t// by proceeding to the next iteration of the main loop. We also can\n\t\t// exit this loop via goto if we get close to exhausting the input.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\t//\n\t\t\tt := candidate.offset - e.cur\n\t\t\tl := e.matchlenLong(s+4, t+4, src) + 4\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\n\t\t\tif s >= sLimit {\n\t\t\t\tt += l\n\t\t\t\t// Index first pair after match end.\n\t\t\t\tif int(t+8) < len(src) && t > 0 {\n\t\t\t\t\tcv = load6432(src, t)\n\t\t\t\t\tnextHash := hashLen(cv, tableBits, hashBytes)\n\t\t\t\t\te.table[nextHash] = tableEntryPrev{\n\t\t\t\t\t\tPrev: e.table[nextHash].Cur,\n\t\t\t\t\t\tCur:  tableEntry{offset: e.cur + t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// Store every 5th hash in-between.\n\t\t\tfor i := s - l + 2; i < s-5; i += 6 {\n\t\t\t\tnextHash := hashLen(load6432(src, i), tableBits, hashBytes)\n\t\t\t\te.table[nextHash] = tableEntryPrev{\n\t\t\t\t\tPrev: e.table[nextHash].Cur,\n\t\t\t\t\tCur:  tableEntry{offset: e.cur + i}}\n\t\t\t}\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 to s.\n\t\t\tx := load6432(src, s-2)\n\t\t\tprevHash := hashLen(x, tableBits, hashBytes)\n\n\t\t\te.table[prevHash] = tableEntryPrev{\n\t\t\t\tPrev: e.table[prevHash].Cur,\n\t\t\t\tCur:  tableEntry{offset: e.cur + s - 2},\n\t\t\t}\n\t\t\tx >>= 8\n\t\t\tprevHash = hashLen(x, tableBits, hashBytes)\n\n\t\t\te.table[prevHash] = tableEntryPrev{\n\t\t\t\tPrev: e.table[prevHash].Cur,\n\t\t\t\tCur:  tableEntry{offset: e.cur + s - 1},\n\t\t\t}\n\t\t\tx >>= 8\n\t\t\tcurrHash := hashLen(x, tableBits, hashBytes)\n\t\t\tcandidates := e.table[currHash]\n\t\t\tcv = x\n\t\t\te.table[currHash] = tableEntryPrev{\n\t\t\t\tPrev: candidates.Cur,\n\t\t\t\tCur:  tableEntry{offset: s + e.cur},\n\t\t\t}\n\n\t\t\t// Check both candidates\n\t\t\tcandidate = candidates.Cur\n\t\t\tminOffset := e.cur + s - (maxMatchOffset - 4)\n\n\t\t\tif candidate.offset > minOffset {\n\t\t\t\tif uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\t\t// Found a match...\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tcandidate = candidates.Prev\n\t\t\t\tif candidate.offset > minOffset && uint32(cv) == load3232(src, candidate.offset-e.cur) {\n\t\t\t\t\t// Match at prev...\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tcv = x >> 8\n\t\t\ts++\n\t\t\tbreak\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level4.go",
    "content": "package flate\n\nimport \"fmt\"\n\ntype fastEncL4 struct {\n\tfastGen\n\ttable  [tableSize]tableEntry\n\tbTable [tableSize]tableEntry\n}\n\nfunc (e *fastEncL4) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntry{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.bTable[i].offset = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 6\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\te.bTable[nextHashL] = entry\n\n\t\t\tt = lCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.offset-e.cur) {\n\t\t\t\t// We got a long match. Use that.\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tlCandidate = e.bTable[hash7(next, tableBits)]\n\n\t\t\t\t// If the next long is a candidate, check if we should use that instead...\n\t\t\t\tlOff := nextS - (lCandidate.offset - e.cur)\n\t\t\t\tif lOff < maxMatchOffset && load3232(src, lCandidate.offset-e.cur) == uint32(next) {\n\t\t\t\t\tl1, l2 := matchLen(src[s+4:], src[t+4:]), matchLen(src[nextS+4:], src[nextS-lOff+4:])\n\t\t\t\t\tif l2 > l1 {\n\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\tt = lCandidate.offset - e.cur\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tl := e.matchlenLong(s+4, t+4, src) + 4\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif debugDeflate {\n\t\t\tif t >= s {\n\t\t\t\tpanic(\"s-t\")\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\t// Index first pair after match end.\n\t\t\tif int(s+8) < len(src) {\n\t\t\t\tcv := load6432(src, s)\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: s + e.cur}\n\t\t\t\te.bTable[hash7(cv, tableBits)] = tableEntry{offset: s + e.cur}\n\t\t\t}\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every 3rd hash in-between\n\t\tif true {\n\t\t\ti := nextS\n\t\t\tif i < s-1 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\te.bTable[hash7(cv, tableBits)] = t\n\t\t\t\te.bTable[hash7(cv>>8, tableBits)] = t2\n\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\n\t\t\t\ti += 3\n\t\t\t\tfor ; i < s-1; i += 3 {\n\t\t\t\t\tcv := load6432(src, i)\n\t\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\t\te.bTable[hash7(cv, tableBits)] = t\n\t\t\t\t\te.bTable[hash7(cv>>8, tableBits)] = t2\n\t\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tx := load6432(src, s-1)\n\t\to := e.cur + s - 1\n\t\tprevHashS := hashLen(x, tableBits, hashShortBytes)\n\t\tprevHashL := hash7(x, tableBits)\n\t\te.table[prevHashS] = tableEntry{offset: o}\n\t\te.bTable[prevHashL] = tableEntry{offset: o}\n\t\tcv = x >> 8\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level5.go",
    "content": "package flate\n\nimport \"fmt\"\n\ntype fastEncL5 struct {\n\tfastGen\n\ttable  [tableSize]tableEntry\n\tbTable [tableSize]tableEntryPrev\n}\n\nfunc (e *fastEncL5) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\t\tv.Prev.offset = 0\n\t\t\t\t} else {\n\t\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t\t}\n\t\t\t}\n\t\t\te.bTable[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 6\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar l int32\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\teLong := &e.bTable[nextHashL]\n\t\t\teLong.Cur, eLong.Prev = entry, eLong.Cur\n\n\t\t\tnextHashS = hashLen(next, tableBits, hashShortBytes)\n\t\t\tnextHashL = hash7(next, tableBits)\n\n\t\t\tt = lCandidate.Cur.offset - e.cur\n\t\t\tif s-t < maxMatchOffset {\n\t\t\t\tif uint32(cv) == load3232(src, lCandidate.Cur.offset-e.cur) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t\tt2 := lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif s-t2 < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {\n\t\t\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\t\t\t\t\t\tml1 := e.matchlen(s+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml1 > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\tl = ml1\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tt = lCandidate.Prev.offset - e.cur\n\t\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\t\t\t\tlCandidate = e.bTable[nextHashL]\n\t\t\t\t// Store the next match\n\n\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t// If the next long is a candidate, use that...\n\t\t\t\tt2 := lCandidate.Cur.offset - e.cur\n\t\t\t\tif nextS-t2 < maxMatchOffset {\n\t\t\t\t\tif load3232(src, lCandidate.Cur.offset-e.cur) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the previous long is a candidate, use that...\n\t\t\t\t\tt2 = lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif nextS-t2 < maxMatchOffset && load3232(src, lCandidate.Prev.offset-e.cur) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\tif l == 0 {\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tl = e.matchlenLong(s+4, t+4, src) + 4\n\t\t} else if l == maxMatchLength {\n\t\t\tl += e.matchlenLong(s+l, t+l, src)\n\t\t}\n\n\t\t// Try to locate a better match by checking the end of best match...\n\t\tif sAt := s + l; l < 30 && sAt < sLimit {\n\t\t\t// Allow some bytes at the beginning to mismatch.\n\t\t\t// Sweet spot is 2/3 bytes depending on input.\n\t\t\t// 3 is only a little better when it is but sometimes a lot worse.\n\t\t\t// The skipped bytes are tested in Extend backwards,\n\t\t\t// and still picked up as part of the match if they do.\n\t\t\tconst skipBeginning = 2\n\t\t\teLong := e.bTable[hash7(load6432(src, sAt), tableBits)].Cur.offset\n\t\t\tt2 := eLong - e.cur - l + skipBeginning\n\t\t\ts2 := s + skipBeginning\n\t\t\toff := s2 - t2\n\t\t\tif t2 >= 0 && off < maxMatchOffset && off > 0 {\n\t\t\t\tif l2 := e.matchlenLong(s2, t2, src); l2 > l {\n\t\t\t\t\tt = t2\n\t\t\t\t\tl = l2\n\t\t\t\t\ts = s2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif debugDeflate {\n\t\t\tif t >= s {\n\t\t\t\tpanic(fmt.Sprintln(\"s-t\", s, t))\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", s-t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every 3rd hash in-between.\n\t\tif true {\n\t\t\tconst hashEvery = 3\n\t\t\ti := s - l + 1\n\t\t\tif i < s-1 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// Do an long at i+1\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\teLong = &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// We only have enough bits for a short entry at i+2\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\n\t\t\t\t// Skip one - otherwise we risk hitting 's'\n\t\t\t\ti += 4\n\t\t\t\tfor ; i < s-1; i += hashEvery {\n\t\t\t\t\tcv := load6432(src, i)\n\t\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\t\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tx := load6432(src, s-1)\n\t\to := e.cur + s - 1\n\t\tprevHashS := hashLen(x, tableBits, hashShortBytes)\n\t\tprevHashL := hash7(x, tableBits)\n\t\te.table[prevHashS] = tableEntry{offset: o}\n\t\teLong := &e.bTable[prevHashL]\n\t\teLong.Cur, eLong.Prev = tableEntry{offset: o}, eLong.Cur\n\t\tcv = x >> 8\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n\n// fastEncL5Window is a level 5 encoder,\n// but with a custom window size.\ntype fastEncL5Window struct {\n\thist      []byte\n\tcur       int32\n\tmaxOffset int32\n\ttable     [tableSize]tableEntry\n\tbTable    [tableSize]tableEntryPrev\n}\n\nfunc (e *fastEncL5Window) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tmaxMatchOffset := e.maxOffset\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\t\tv.Prev.offset = 0\n\t\t\t\t} else {\n\t\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t\t}\n\t\t\t}\n\t\t\te.bTable[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\tfor {\n\t\tconst skipLog = 6\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar l int32\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\teLong := &e.bTable[nextHashL]\n\t\t\teLong.Cur, eLong.Prev = entry, eLong.Cur\n\n\t\t\tnextHashS = hashLen(next, tableBits, hashShortBytes)\n\t\t\tnextHashL = hash7(next, tableBits)\n\n\t\t\tt = lCandidate.Cur.offset - e.cur\n\t\t\tif s-t < maxMatchOffset {\n\t\t\t\tif uint32(cv) == load3232(src, lCandidate.Cur.offset-e.cur) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t\tt2 := lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif s-t2 < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {\n\t\t\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\t\t\t\t\t\tml1 := e.matchlen(s+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml1 > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\tl = ml1\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tt = lCandidate.Prev.offset - e.cur\n\t\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\t\t\t\tlCandidate = e.bTable[nextHashL]\n\t\t\t\t// Store the next match\n\n\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t// If the next long is a candidate, use that...\n\t\t\t\tt2 := lCandidate.Cur.offset - e.cur\n\t\t\t\tif nextS-t2 < maxMatchOffset {\n\t\t\t\t\tif load3232(src, lCandidate.Cur.offset-e.cur) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the previous long is a candidate, use that...\n\t\t\t\t\tt2 = lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif nextS-t2 < maxMatchOffset && load3232(src, lCandidate.Prev.offset-e.cur) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\tif l == 0 {\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tl = e.matchlenLong(s+4, t+4, src) + 4\n\t\t} else if l == maxMatchLength {\n\t\t\tl += e.matchlenLong(s+l, t+l, src)\n\t\t}\n\n\t\t// Try to locate a better match by checking the end of best match...\n\t\tif sAt := s + l; l < 30 && sAt < sLimit {\n\t\t\t// Allow some bytes at the beginning to mismatch.\n\t\t\t// Sweet spot is 2/3 bytes depending on input.\n\t\t\t// 3 is only a little better when it is but sometimes a lot worse.\n\t\t\t// The skipped bytes are tested in Extend backwards,\n\t\t\t// and still picked up as part of the match if they do.\n\t\t\tconst skipBeginning = 2\n\t\t\teLong := e.bTable[hash7(load6432(src, sAt), tableBits)].Cur.offset\n\t\t\tt2 := eLong - e.cur - l + skipBeginning\n\t\t\ts2 := s + skipBeginning\n\t\t\toff := s2 - t2\n\t\t\tif t2 >= 0 && off < maxMatchOffset && off > 0 {\n\t\t\t\tif l2 := e.matchlenLong(s2, t2, src); l2 > l {\n\t\t\t\t\tt = t2\n\t\t\t\t\tl = l2\n\t\t\t\t\ts = s2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif debugDeflate {\n\t\t\tif t >= s {\n\t\t\t\tpanic(fmt.Sprintln(\"s-t\", s, t))\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", s-t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every 3rd hash in-between.\n\t\tif true {\n\t\t\tconst hashEvery = 3\n\t\t\ti := s - l + 1\n\t\t\tif i < s-1 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// Do an long at i+1\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\teLong = &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\n\t\t\t\t// We only have enough bits for a short entry at i+2\n\t\t\t\tcv >>= 8\n\t\t\t\tt = tableEntry{offset: t.offset + 1}\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\n\t\t\t\t// Skip one - otherwise we risk hitting 's'\n\t\t\t\ti += 4\n\t\t\t\tfor ; i < s-1; i += hashEvery {\n\t\t\t\t\tcv := load6432(src, i)\n\t\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\t\t\t\t\te.table[hashLen(cv>>8, tableBits, hashShortBytes)] = t2\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tx := load6432(src, s-1)\n\t\to := e.cur + s - 1\n\t\tprevHashS := hashLen(x, tableBits, hashShortBytes)\n\t\tprevHashL := hash7(x, tableBits)\n\t\te.table[prevHashS] = tableEntry{offset: o}\n\t\teLong := &e.bTable[prevHashL]\n\t\teLong.Cur, eLong.Prev = tableEntry{offset: o}, eLong.Cur\n\t\tcv = x >> 8\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n\n// Reset the encoding table.\nfunc (e *fastEncL5Window) Reset() {\n\t// We keep the same allocs, since we are compressing the same block sizes.\n\tif cap(e.hist) < allocHistory {\n\t\te.hist = make([]byte, 0, allocHistory)\n\t}\n\n\t// We offset current position so everything will be out of reach.\n\t// If we are above the buffer reset it will be cleared anyway since len(hist) == 0.\n\tif e.cur <= int32(bufferReset) {\n\t\te.cur += e.maxOffset + int32(len(e.hist))\n\t}\n\te.hist = e.hist[:0]\n}\n\nfunc (e *fastEncL5Window) addBlock(src []byte) int32 {\n\t// check if we have space already\n\tmaxMatchOffset := e.maxOffset\n\n\tif len(e.hist)+len(src) > cap(e.hist) {\n\t\tif cap(e.hist) == 0 {\n\t\t\te.hist = make([]byte, 0, allocHistory)\n\t\t} else {\n\t\t\tif cap(e.hist) < int(maxMatchOffset*2) {\n\t\t\t\tpanic(\"unexpected buffer size\")\n\t\t\t}\n\t\t\t// Move down\n\t\t\toffset := int32(len(e.hist)) - maxMatchOffset\n\t\t\tcopy(e.hist[0:maxMatchOffset], e.hist[offset:])\n\t\t\te.cur += offset\n\t\t\te.hist = e.hist[:maxMatchOffset]\n\t\t}\n\t}\n\ts := int32(len(e.hist))\n\te.hist = append(e.hist, src...)\n\treturn s\n}\n\n// matchlen will return the match length between offsets and t in src.\n// The maximum length returned is maxMatchLength - 4.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastEncL5Window) matchlen(s, t int32, src []byte) int32 {\n\tif debugDecode {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > e.maxOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\ts1 := int(s) + maxMatchLength - 4\n\tif s1 > len(src) {\n\t\ts1 = len(src)\n\t}\n\n\t// Extend the match to be as long as possible.\n\treturn int32(matchLen(src[s:s1], src[t:]))\n}\n\n// matchlenLong will return the match length between offsets and t in src.\n// It is assumed that s > t, that t >=0 and s < len(src).\nfunc (e *fastEncL5Window) matchlenLong(s, t int32, src []byte) int32 {\n\tif debugDeflate {\n\t\tif t >= s {\n\t\t\tpanic(fmt.Sprint(\"t >=s:\", t, s))\n\t\t}\n\t\tif int(s) >= len(src) {\n\t\t\tpanic(fmt.Sprint(\"s >= len(src):\", s, len(src)))\n\t\t}\n\t\tif t < 0 {\n\t\t\tpanic(fmt.Sprint(\"t < 0:\", t))\n\t\t}\n\t\tif s-t > e.maxOffset {\n\t\t\tpanic(fmt.Sprint(s, \"-\", t, \"(\", s-t, \") > maxMatchLength (\", maxMatchOffset, \")\"))\n\t\t}\n\t}\n\t// Extend the match to be as long as possible.\n\treturn int32(matchLen(src[s:], src[t:]))\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/level6.go",
    "content": "package flate\n\nimport \"fmt\"\n\ntype fastEncL6 struct {\n\tfastGen\n\ttable  [tableSize]tableEntry\n\tbTable [tableSize]tableEntryPrev\n}\n\nfunc (e *fastEncL6) Encode(dst *tokens, src []byte) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t\thashShortBytes         = 4\n\t)\n\tif debugDeflate && e.cur < 0 {\n\t\tpanic(fmt.Sprint(\"e.cur < 0: \", e.cur))\n\t}\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= bufferReset {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.bTable[:] {\n\t\t\t\te.bTable[i] = tableEntryPrev{}\n\t\t\t}\n\t\t\te.cur = maxMatchOffset\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - maxMatchOffset\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v <= minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + maxMatchOffset\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.bTable[:] {\n\t\t\tv := e.bTable[i]\n\t\t\tif v.Cur.offset <= minOff {\n\t\t\t\tv.Cur.offset = 0\n\t\t\t\tv.Prev.offset = 0\n\t\t\t} else {\n\t\t\t\tv.Cur.offset = v.Cur.offset - e.cur + maxMatchOffset\n\t\t\t\tif v.Prev.offset <= minOff {\n\t\t\t\t\tv.Prev.offset = 0\n\t\t\t\t} else {\n\t\t\t\t\tv.Prev.offset = v.Prev.offset - e.cur + maxMatchOffset\n\t\t\t\t}\n\t\t\t}\n\t\t\te.bTable[i] = v\n\t\t}\n\t\te.cur = maxMatchOffset\n\t}\n\n\ts := e.addBlock(src)\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = uint16(len(src))\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tnextEmit := s\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int32(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load6432(src, s)\n\t// Repeat MUST be > 1 and within range\n\trepeat := int32(1)\n\tfor {\n\t\tconst skipLog = 7\n\t\tconst doEvery = 1\n\n\t\tnextS := s\n\t\tvar l int32\n\t\tvar t int32\n\t\tfor {\n\t\t\tnextHashS := hashLen(cv, tableBits, hashShortBytes)\n\t\t\tnextHashL := hash7(cv, tableBits)\n\t\t\ts = nextS\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\t// Fetch a short+long candidate\n\t\t\tsCandidate := e.table[nextHashS]\n\t\t\tlCandidate := e.bTable[nextHashL]\n\t\t\tnext := load6432(src, nextS)\n\t\t\tentry := tableEntry{offset: s + e.cur}\n\t\t\te.table[nextHashS] = entry\n\t\t\teLong := &e.bTable[nextHashL]\n\t\t\teLong.Cur, eLong.Prev = entry, eLong.Cur\n\n\t\t\t// Calculate hashes of 'next'\n\t\t\tnextHashS = hashLen(next, tableBits, hashShortBytes)\n\t\t\tnextHashL = hash7(next, tableBits)\n\n\t\t\tt = lCandidate.Cur.offset - e.cur\n\t\t\tif s-t < maxMatchOffset {\n\t\t\t\tif uint32(cv) == load3232(src, lCandidate.Cur.offset-e.cur) {\n\t\t\t\t\t// Long candidate matches at least 4 bytes.\n\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t\t// Check the previous long candidate as well.\n\t\t\t\t\tt2 := lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif s-t2 < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {\n\t\t\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\t\t\t\t\t\tml1 := e.matchlen(s+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml1 > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\tl = ml1\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// Current value did not match, but check if previous long value does.\n\t\t\t\tt = lCandidate.Prev.offset - e.cur\n\t\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, lCandidate.Prev.offset-e.cur) {\n\t\t\t\t\t// Store the next match\n\t\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tt = sCandidate.offset - e.cur\n\t\t\tif s-t < maxMatchOffset && uint32(cv) == load3232(src, sCandidate.offset-e.cur) {\n\t\t\t\t// Found a 4 match...\n\t\t\t\tl = e.matchlen(s+4, t+4, src) + 4\n\n\t\t\t\t// Look up next long candidate (at nextS)\n\t\t\t\tlCandidate = e.bTable[nextHashL]\n\n\t\t\t\t// Store the next match\n\t\t\t\te.table[nextHashS] = tableEntry{offset: nextS + e.cur}\n\t\t\t\teLong := &e.bTable[nextHashL]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: nextS + e.cur}, eLong.Cur\n\n\t\t\t\t// Check repeat at s + repOff\n\t\t\t\tconst repOff = 1\n\t\t\t\tt2 := s - repeat + repOff\n\t\t\t\tif load3232(src, t2) == uint32(cv>>(8*repOff)) {\n\t\t\t\t\tml := e.matchlen(s+4+repOff, t2+4, src) + 4\n\t\t\t\t\tif ml > l {\n\t\t\t\t\t\tt = t2\n\t\t\t\t\t\tl = ml\n\t\t\t\t\t\ts += repOff\n\t\t\t\t\t\t// Not worth checking more.\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// If the next long is a candidate, use that...\n\t\t\t\tt2 = lCandidate.Cur.offset - e.cur\n\t\t\t\tif nextS-t2 < maxMatchOffset {\n\t\t\t\t\tif load3232(src, lCandidate.Cur.offset-e.cur) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\t// This is ok, but check previous as well.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If the previous long is a candidate, use that...\n\t\t\t\t\tt2 = lCandidate.Prev.offset - e.cur\n\t\t\t\t\tif nextS-t2 < maxMatchOffset && load3232(src, lCandidate.Prev.offset-e.cur) == uint32(next) {\n\t\t\t\t\t\tml := e.matchlen(nextS+4, t2+4, src) + 4\n\t\t\t\t\t\tif ml > l {\n\t\t\t\t\t\t\tt = t2\n\t\t\t\t\t\t\ts = nextS\n\t\t\t\t\t\t\tl = ml\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = next\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tif l == 0 {\n\t\t\tl = e.matchlenLong(s+4, t+4, src) + 4\n\t\t} else if l == maxMatchLength {\n\t\t\tl += e.matchlenLong(s+l, t+l, src)\n\t\t}\n\n\t\t// Try to locate a better match by checking the end-of-match...\n\t\tif sAt := s + l; sAt < sLimit {\n\t\t\t// Allow some bytes at the beginning to mismatch.\n\t\t\t// Sweet spot is 2/3 bytes depending on input.\n\t\t\t// 3 is only a little better when it is but sometimes a lot worse.\n\t\t\t// The skipped bytes are tested in Extend backwards,\n\t\t\t// and still picked up as part of the match if they do.\n\t\t\tconst skipBeginning = 2\n\t\t\teLong := &e.bTable[hash7(load6432(src, sAt), tableBits)]\n\t\t\t// Test current\n\t\t\tt2 := eLong.Cur.offset - e.cur - l + skipBeginning\n\t\t\ts2 := s + skipBeginning\n\t\t\toff := s2 - t2\n\t\t\tif off < maxMatchOffset {\n\t\t\t\tif off > 0 && t2 >= 0 {\n\t\t\t\t\tif l2 := e.matchlenLong(s2, t2, src); l2 > l {\n\t\t\t\t\t\tt = t2\n\t\t\t\t\t\tl = l2\n\t\t\t\t\t\ts = s2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Test next:\n\t\t\t\tt2 = eLong.Prev.offset - e.cur - l + skipBeginning\n\t\t\t\toff := s2 - t2\n\t\t\t\tif off > 0 && off < maxMatchOffset && t2 >= 0 {\n\t\t\t\t\tif l2 := e.matchlenLong(s2, t2, src); l2 > l {\n\t\t\t\t\t\tt = t2\n\t\t\t\t\t\tl = l2\n\t\t\t\t\t\ts = s2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Extend backwards\n\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\t\tif nextEmit < s {\n\t\t\tif false {\n\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t} else {\n\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\tdst.n++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif false {\n\t\t\tif t >= s {\n\t\t\t\tpanic(fmt.Sprintln(\"s-t\", s, t))\n\t\t\t}\n\t\t\tif (s - t) > maxMatchOffset {\n\t\t\t\tpanic(fmt.Sprintln(\"mmo\", s-t))\n\t\t\t}\n\t\t\tif l < baseMatchLength {\n\t\t\t\tpanic(\"bml\")\n\t\t\t}\n\t\t}\n\n\t\tdst.AddMatchLong(l, uint32(s-t-baseMatchOffset))\n\t\trepeat = s - t\n\t\ts += l\n\t\tnextEmit = s\n\t\tif nextS >= s {\n\t\t\ts = nextS + 1\n\t\t}\n\n\t\tif s >= sLimit {\n\t\t\t// Index after match end.\n\t\t\tfor i := nextS + 1; i < int32(len(src))-8; i += 2 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = tableEntry{offset: i + e.cur}\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong.Cur, eLong.Prev = tableEntry{offset: i + e.cur}, eLong.Cur\n\t\t\t}\n\t\t\tgoto emitRemainder\n\t\t}\n\n\t\t// Store every long hash in-between and every second short.\n\t\tif true {\n\t\t\tfor i := nextS + 1; i < s-1; i += 2 {\n\t\t\t\tcv := load6432(src, i)\n\t\t\t\tt := tableEntry{offset: i + e.cur}\n\t\t\t\tt2 := tableEntry{offset: t.offset + 1}\n\t\t\t\teLong := &e.bTable[hash7(cv, tableBits)]\n\t\t\t\teLong2 := &e.bTable[hash7(cv>>8, tableBits)]\n\t\t\t\te.table[hashLen(cv, tableBits, hashShortBytes)] = t\n\t\t\t\teLong.Cur, eLong.Prev = t, eLong.Cur\n\t\t\t\teLong2.Cur, eLong2.Prev = t2, eLong2.Cur\n\t\t\t}\n\t\t}\n\n\t\t// We could immediately start working at s now, but to improve\n\t\t// compression we first update the hash table at s-1 and at s.\n\t\tcv = load6432(src, s)\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/matchlen_amd64.go",
    "content": "//go:build amd64 && !appengine && !noasm && gc\n// +build amd64,!appengine,!noasm,gc\n\n// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n\npackage flate\n\n// matchLen returns how many bytes match in a and b\n//\n// It assumes that:\n//\n//\tlen(a) <= len(b) and len(a) > 0\n//\n//go:noescape\nfunc matchLen(a []byte, b []byte) int\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/matchlen_amd64.s",
    "content": "// Copied from S2 implementation.\n\n//go:build !appengine && !noasm && gc && !noasm\n\n#include \"textflag.h\"\n\n// func matchLen(a []byte, b []byte) int\n// Requires: BMI\nTEXT ·matchLen(SB), NOSPLIT, $0-56\n\tMOVQ a_base+0(FP), AX\n\tMOVQ b_base+24(FP), CX\n\tMOVQ a_len+8(FP), DX\n\n\t// matchLen\n\tXORL SI, SI\n\tCMPL DX, $0x08\n\tJB   matchlen_match4_standalone\n\nmatchlen_loopback_standalone:\n\tMOVQ  (AX)(SI*1), BX\n\tXORQ  (CX)(SI*1), BX\n\tTESTQ BX, BX\n\tJZ    matchlen_loop_standalone\n\n#ifdef GOAMD64_v3\n\tTZCNTQ BX, BX\n#else\n\tBSFQ BX, BX\n#endif\n\tSARQ $0x03, BX\n\tLEAL (SI)(BX*1), SI\n\tJMP  gen_match_len_end\n\nmatchlen_loop_standalone:\n\tLEAL -8(DX), DX\n\tLEAL 8(SI), SI\n\tCMPL DX, $0x08\n\tJAE  matchlen_loopback_standalone\n\nmatchlen_match4_standalone:\n\tCMPL DX, $0x04\n\tJB   matchlen_match2_standalone\n\tMOVL (AX)(SI*1), BX\n\tCMPL (CX)(SI*1), BX\n\tJNE  matchlen_match2_standalone\n\tLEAL -4(DX), DX\n\tLEAL 4(SI), SI\n\nmatchlen_match2_standalone:\n\tCMPL DX, $0x02\n\tJB   matchlen_match1_standalone\n\tMOVW (AX)(SI*1), BX\n\tCMPW (CX)(SI*1), BX\n\tJNE  matchlen_match1_standalone\n\tLEAL -2(DX), DX\n\tLEAL 2(SI), SI\n\nmatchlen_match1_standalone:\n\tCMPL DX, $0x01\n\tJB   gen_match_len_end\n\tMOVB (AX)(SI*1), BL\n\tCMPB (CX)(SI*1), BL\n\tJNE  gen_match_len_end\n\tINCL SI\n\ngen_match_len_end:\n\tMOVQ SI, ret+48(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/matchlen_generic.go",
    "content": "//go:build !amd64 || appengine || !gc || noasm\n// +build !amd64 appengine !gc noasm\n\n// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n\npackage flate\n\nimport (\n\t\"encoding/binary\"\n\t\"math/bits\"\n)\n\n// matchLen returns the maximum common prefix length of a and b.\n// a must be the shortest of the two.\nfunc matchLen(a, b []byte) (n int) {\n\tfor ; len(a) >= 8 && len(b) >= 8; a, b = a[8:], b[8:] {\n\t\tdiff := binary.LittleEndian.Uint64(a) ^ binary.LittleEndian.Uint64(b)\n\t\tif diff != 0 {\n\t\t\treturn n + bits.TrailingZeros64(diff)>>3\n\t\t}\n\t\tn += 8\n\t}\n\n\tfor i := range a {\n\t\tif a[i] != b[i] {\n\t\t\tbreak\n\t\t}\n\t\tn++\n\t}\n\treturn n\n\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/regmask_amd64.go",
    "content": "package flate\n\nconst (\n\t// Masks for shifts with register sizes of the shift value.\n\t// This can be used to work around the x86 design of shifting by mod register size.\n\t// It can be used when a variable shift is always smaller than the register size.\n\n\t// reg8SizeMaskX - shift value is 8 bits, shifted is X\n\treg8SizeMask8  = 7\n\treg8SizeMask16 = 15\n\treg8SizeMask32 = 31\n\treg8SizeMask64 = 63\n\n\t// reg16SizeMaskX - shift value is 16 bits, shifted is X\n\treg16SizeMask8  = reg8SizeMask8\n\treg16SizeMask16 = reg8SizeMask16\n\treg16SizeMask32 = reg8SizeMask32\n\treg16SizeMask64 = reg8SizeMask64\n\n\t// reg32SizeMaskX - shift value is 32 bits, shifted is X\n\treg32SizeMask8  = reg8SizeMask8\n\treg32SizeMask16 = reg8SizeMask16\n\treg32SizeMask32 = reg8SizeMask32\n\treg32SizeMask64 = reg8SizeMask64\n\n\t// reg64SizeMaskX - shift value is 64 bits, shifted is X\n\treg64SizeMask8  = reg8SizeMask8\n\treg64SizeMask16 = reg8SizeMask16\n\treg64SizeMask32 = reg8SizeMask32\n\treg64SizeMask64 = reg8SizeMask64\n\n\t// regSizeMaskUintX - shift value is uint, shifted is X\n\tregSizeMaskUint8  = reg8SizeMask8\n\tregSizeMaskUint16 = reg8SizeMask16\n\tregSizeMaskUint32 = reg8SizeMask32\n\tregSizeMaskUint64 = reg8SizeMask64\n)\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/regmask_other.go",
    "content": "//go:build !amd64\n// +build !amd64\n\npackage flate\n\nconst (\n\t// Masks for shifts with register sizes of the shift value.\n\t// This can be used to work around the x86 design of shifting by mod register size.\n\t// It can be used when a variable shift is always smaller than the register size.\n\n\t// reg8SizeMaskX - shift value is 8 bits, shifted is X\n\treg8SizeMask8  = 0xff\n\treg8SizeMask16 = 0xff\n\treg8SizeMask32 = 0xff\n\treg8SizeMask64 = 0xff\n\n\t// reg16SizeMaskX - shift value is 16 bits, shifted is X\n\treg16SizeMask8  = 0xffff\n\treg16SizeMask16 = 0xffff\n\treg16SizeMask32 = 0xffff\n\treg16SizeMask64 = 0xffff\n\n\t// reg32SizeMaskX - shift value is 32 bits, shifted is X\n\treg32SizeMask8  = 0xffffffff\n\treg32SizeMask16 = 0xffffffff\n\treg32SizeMask32 = 0xffffffff\n\treg32SizeMask64 = 0xffffffff\n\n\t// reg64SizeMaskX - shift value is 64 bits, shifted is X\n\treg64SizeMask8  = 0xffffffffffffffff\n\treg64SizeMask16 = 0xffffffffffffffff\n\treg64SizeMask32 = 0xffffffffffffffff\n\treg64SizeMask64 = 0xffffffffffffffff\n\n\t// regSizeMaskUintX - shift value is uint, shifted is X\n\tregSizeMaskUint8  = ^uint(0)\n\tregSizeMaskUint16 = ^uint(0)\n\tregSizeMaskUint32 = ^uint(0)\n\tregSizeMaskUint64 = ^uint(0)\n)\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/stateless.go",
    "content": "package flate\n\nimport (\n\t\"io\"\n\t\"math\"\n\t\"sync\"\n)\n\nconst (\n\tmaxStatelessBlock = math.MaxInt16\n\t// dictionary will be taken from maxStatelessBlock, so limit it.\n\tmaxStatelessDict = 8 << 10\n\n\tslTableBits  = 13\n\tslTableSize  = 1 << slTableBits\n\tslTableShift = 32 - slTableBits\n)\n\ntype statelessWriter struct {\n\tdst    io.Writer\n\tclosed bool\n}\n\nfunc (s *statelessWriter) Close() error {\n\tif s.closed {\n\t\treturn nil\n\t}\n\ts.closed = true\n\t// Emit EOF block\n\treturn StatelessDeflate(s.dst, nil, true, nil)\n}\n\nfunc (s *statelessWriter) Write(p []byte) (n int, err error) {\n\terr = StatelessDeflate(s.dst, p, false, nil)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn len(p), nil\n}\n\nfunc (s *statelessWriter) Reset(w io.Writer) {\n\ts.dst = w\n\ts.closed = false\n}\n\n// NewStatelessWriter will do compression but without maintaining any state\n// between Write calls.\n// There will be no memory kept between Write calls,\n// but compression and speed will be suboptimal.\n// Because of this, the size of actual Write calls will affect output size.\nfunc NewStatelessWriter(dst io.Writer) io.WriteCloser {\n\treturn &statelessWriter{dst: dst}\n}\n\n// bitWriterPool contains bit writers that can be reused.\nvar bitWriterPool = sync.Pool{\n\tNew: func() interface{} {\n\t\treturn newHuffmanBitWriter(nil)\n\t},\n}\n\n// StatelessDeflate allows compressing directly to a Writer without retaining state.\n// When returning everything will be flushed.\n// Up to 8KB of an optional dictionary can be given which is presumed to precede the block.\n// Longer dictionaries will be truncated and will still produce valid output.\n// Sending nil dictionary is perfectly fine.\nfunc StatelessDeflate(out io.Writer, in []byte, eof bool, dict []byte) error {\n\tvar dst tokens\n\tbw := bitWriterPool.Get().(*huffmanBitWriter)\n\tbw.reset(out)\n\tdefer func() {\n\t\t// don't keep a reference to our output\n\t\tbw.reset(nil)\n\t\tbitWriterPool.Put(bw)\n\t}()\n\tif eof && len(in) == 0 {\n\t\t// Just write an EOF block.\n\t\t// Could be faster...\n\t\tbw.writeStoredHeader(0, true)\n\t\tbw.flush()\n\t\treturn bw.err\n\t}\n\n\t// Truncate dict\n\tif len(dict) > maxStatelessDict {\n\t\tdict = dict[len(dict)-maxStatelessDict:]\n\t}\n\n\t// For subsequent loops, keep shallow dict reference to avoid alloc+copy.\n\tvar inDict []byte\n\n\tfor len(in) > 0 {\n\t\ttodo := in\n\t\tif len(inDict) > 0 {\n\t\t\tif len(todo) > maxStatelessBlock-maxStatelessDict {\n\t\t\t\ttodo = todo[:maxStatelessBlock-maxStatelessDict]\n\t\t\t}\n\t\t} else if len(todo) > maxStatelessBlock-len(dict) {\n\t\t\ttodo = todo[:maxStatelessBlock-len(dict)]\n\t\t}\n\t\tinOrg := in\n\t\tin = in[len(todo):]\n\t\tuncompressed := todo\n\t\tif len(dict) > 0 {\n\t\t\t// combine dict and source\n\t\t\tbufLen := len(todo) + len(dict)\n\t\t\tcombined := make([]byte, bufLen)\n\t\t\tcopy(combined, dict)\n\t\t\tcopy(combined[len(dict):], todo)\n\t\t\ttodo = combined\n\t\t}\n\t\t// Compress\n\t\tif len(inDict) == 0 {\n\t\t\tstatelessEnc(&dst, todo, int16(len(dict)))\n\t\t} else {\n\t\t\tstatelessEnc(&dst, inDict[:maxStatelessDict+len(todo)], maxStatelessDict)\n\t\t}\n\t\tisEof := eof && len(in) == 0\n\n\t\tif dst.n == 0 {\n\t\t\tbw.writeStoredHeader(len(uncompressed), isEof)\n\t\t\tif bw.err != nil {\n\t\t\t\treturn bw.err\n\t\t\t}\n\t\t\tbw.writeBytes(uncompressed)\n\t\t} else if int(dst.n) > len(uncompressed)-len(uncompressed)>>4 {\n\t\t\t// If we removed less than 1/16th, huffman compress the block.\n\t\t\tbw.writeBlockHuff(isEof, uncompressed, len(in) == 0)\n\t\t} else {\n\t\t\tbw.writeBlockDynamic(&dst, isEof, uncompressed, len(in) == 0)\n\t\t}\n\t\tif len(in) > 0 {\n\t\t\t// Retain a dict if we have more\n\t\t\tinDict = inOrg[len(uncompressed)-maxStatelessDict:]\n\t\t\tdict = nil\n\t\t\tdst.Reset()\n\t\t}\n\t\tif bw.err != nil {\n\t\t\treturn bw.err\n\t\t}\n\t}\n\tif !eof {\n\t\t// Align, only a stored block can do that.\n\t\tbw.writeStoredHeader(0, false)\n\t}\n\tbw.flush()\n\treturn bw.err\n}\n\nfunc hashSL(u uint32) uint32 {\n\treturn (u * 0x1e35a7bd) >> slTableShift\n}\n\nfunc load3216(b []byte, i int16) uint32 {\n\t// Help the compiler eliminate bounds checks on the read so it can be done in a single read.\n\tb = b[i:]\n\tb = b[:4]\n\treturn uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n}\n\nfunc load6416(b []byte, i int16) uint64 {\n\t// Help the compiler eliminate bounds checks on the read so it can be done in a single read.\n\tb = b[i:]\n\tb = b[:8]\n\treturn uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |\n\t\tuint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n}\n\nfunc statelessEnc(dst *tokens, src []byte, startAt int16) {\n\tconst (\n\t\tinputMargin            = 12 - 1\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t)\n\n\ttype tableEntry struct {\n\t\toffset int16\n\t}\n\n\tvar table [slTableSize]tableEntry\n\n\t// This check isn't in the Snappy implementation, but there, the caller\n\t// instead of the callee handles this case.\n\tif len(src)-int(startAt) < minNonLiteralBlockSize {\n\t\t// We do not fill the token table.\n\t\t// This will be picked up by caller.\n\t\tdst.n = 0\n\t\treturn\n\t}\n\t// Index until startAt\n\tif startAt > 0 {\n\t\tcv := load3232(src, 0)\n\t\tfor i := int16(0); i < startAt; i++ {\n\t\t\ttable[hashSL(cv)] = tableEntry{offset: i}\n\t\t\tcv = (cv >> 8) | (uint32(src[i+4]) << 24)\n\t\t}\n\t}\n\n\ts := startAt + 1\n\tnextEmit := startAt\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := int16(len(src) - inputMargin)\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tcv := load3216(src, s)\n\n\tfor {\n\t\tconst skipLog = 5\n\t\tconst doEvery = 2\n\n\t\tnextS := s\n\t\tvar candidate tableEntry\n\t\tfor {\n\t\t\tnextHash := hashSL(cv)\n\t\t\tcandidate = table[nextHash]\n\t\t\tnextS = s + doEvery + (s-nextEmit)>>skipLog\n\t\t\tif nextS > sLimit || nextS <= 0 {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\tnow := load6416(src, nextS)\n\t\t\ttable[nextHash] = tableEntry{offset: s}\n\t\t\tnextHash = hashSL(uint32(now))\n\n\t\t\tif cv == load3216(src, candidate.offset) {\n\t\t\t\ttable[nextHash] = tableEntry{offset: nextS}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Do one right away...\n\t\t\tcv = uint32(now)\n\t\t\ts = nextS\n\t\t\tnextS++\n\t\t\tcandidate = table[nextHash]\n\t\t\tnow >>= 8\n\t\t\ttable[nextHash] = tableEntry{offset: s}\n\n\t\t\tif cv == load3216(src, candidate.offset) {\n\t\t\t\ttable[nextHash] = tableEntry{offset: nextS}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcv = uint32(now)\n\t\t\ts = nextS\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\tt := candidate.offset\n\t\t\tl := int16(matchLen(src[s+4:], src[t+4:]) + 4)\n\n\t\t\t// Extend backwards\n\t\t\tfor t > 0 && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\t\ts--\n\t\t\t\tt--\n\t\t\t\tl++\n\t\t\t}\n\t\t\tif nextEmit < s {\n\t\t\t\tif false {\n\t\t\t\t\temitLiteral(dst, src[nextEmit:s])\n\t\t\t\t} else {\n\t\t\t\t\tfor _, v := range src[nextEmit:s] {\n\t\t\t\t\t\tdst.tokens[dst.n] = token(v)\n\t\t\t\t\t\tdst.litHist[v]++\n\t\t\t\t\t\tdst.n++\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Save the match found\n\t\t\tdst.AddMatchLong(int32(l), uint32(s-t-baseMatchOffset))\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif nextS >= s {\n\t\t\t\ts = nextS + 1\n\t\t\t}\n\t\t\tif s >= sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-2 and at s. If\n\t\t\t// another emitCopy is not our next move, also calculate nextHash\n\t\t\t// at s+1. At least on GOARCH=amd64, these three hash calculations\n\t\t\t// are faster as one load64 call (with some shifts) instead of\n\t\t\t// three load32 calls.\n\t\t\tx := load6416(src, s-2)\n\t\t\to := s - 2\n\t\t\tprevHash := hashSL(uint32(x))\n\t\t\ttable[prevHash] = tableEntry{offset: o}\n\t\t\tx >>= 16\n\t\t\tcurrHash := hashSL(uint32(x))\n\t\t\tcandidate = table[currHash]\n\t\t\ttable[currHash] = tableEntry{offset: o + 2}\n\n\t\t\tif uint32(x) != load3216(src, candidate.offset) {\n\t\t\t\tcv = uint32(x >> 8)\n\t\t\t\ts++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\nemitRemainder:\n\tif int(nextEmit) < len(src) {\n\t\t// If nothing was added, don't encode literals.\n\t\tif dst.n == 0 {\n\t\t\treturn\n\t\t}\n\t\temitLiteral(dst, src[nextEmit:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/flate/token.go",
    "content": "// Copyright 2009 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 flate\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n)\n\nconst (\n\t// bits 0-16  \txoffset = offset - MIN_OFFSET_SIZE, or literal - 16 bits\n\t// bits 16-22\toffsetcode - 5 bits\n\t// bits 22-30   xlength = length - MIN_MATCH_LENGTH - 8 bits\n\t// bits 30-32   type   0 = literal  1=EOF  2=Match   3=Unused - 2 bits\n\tlengthShift         = 22\n\toffsetMask          = 1<<lengthShift - 1\n\ttypeMask            = 3 << 30\n\tliteralType         = 0 << 30\n\tmatchType           = 1 << 30\n\tmatchOffsetOnlyMask = 0xffff\n)\n\n// The length code for length X (MIN_MATCH_LENGTH <= X <= MAX_MATCH_LENGTH)\n// is lengthCodes[length - MIN_MATCH_LENGTH]\nvar lengthCodes = [256]uint8{\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 8,\n\t9, 9, 10, 10, 11, 11, 12, 12, 12, 12,\n\t13, 13, 13, 13, 14, 14, 14, 14, 15, 15,\n\t15, 15, 16, 16, 16, 16, 16, 16, 16, 16,\n\t17, 17, 17, 17, 17, 17, 17, 17, 18, 18,\n\t18, 18, 18, 18, 18, 18, 19, 19, 19, 19,\n\t19, 19, 19, 19, 20, 20, 20, 20, 20, 20,\n\t20, 20, 20, 20, 20, 20, 20, 20, 20, 20,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 22, 22, 22, 22,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 23, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 28,\n}\n\n// lengthCodes1 is length codes, but starting at 1.\nvar lengthCodes1 = [256]uint8{\n\t1, 2, 3, 4, 5, 6, 7, 8, 9, 9,\n\t10, 10, 11, 11, 12, 12, 13, 13, 13, 13,\n\t14, 14, 14, 14, 15, 15, 15, 15, 16, 16,\n\t16, 16, 17, 17, 17, 17, 17, 17, 17, 17,\n\t18, 18, 18, 18, 18, 18, 18, 18, 19, 19,\n\t19, 19, 19, 19, 19, 19, 20, 20, 20, 20,\n\t20, 20, 20, 20, 21, 21, 21, 21, 21, 21,\n\t21, 21, 21, 21, 21, 21, 21, 21, 21, 21,\n\t22, 22, 22, 22, 22, 22, 22, 22, 22, 22,\n\t22, 22, 22, 22, 22, 22, 23, 23, 23, 23,\n\t23, 23, 23, 23, 23, 23, 23, 23, 23, 23,\n\t23, 23, 24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 29,\n}\n\nvar offsetCodes = [256]uint32{\n\t0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,\n\t8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,\n\t10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n\t11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n\t15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n}\n\n// offsetCodes14 are offsetCodes, but with 14 added.\nvar offsetCodes14 = [256]uint32{\n\t14, 15, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,\n\t22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,\n\t24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,\n\t25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n\t29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,\n}\n\ntype token uint32\n\ntype tokens struct {\n\textraHist [32]uint16  // codes 256->maxnumlit\n\toffHist   [32]uint16  // offset codes\n\tlitHist   [256]uint16 // codes 0->255\n\tnFilled   int\n\tn         uint16 // Must be able to contain maxStoreBlockSize\n\ttokens    [maxStoreBlockSize + 1]token\n}\n\nfunc (t *tokens) Reset() {\n\tif t.n == 0 {\n\t\treturn\n\t}\n\tt.n = 0\n\tt.nFilled = 0\n\tfor i := range t.litHist[:] {\n\t\tt.litHist[i] = 0\n\t}\n\tfor i := range t.extraHist[:] {\n\t\tt.extraHist[i] = 0\n\t}\n\tfor i := range t.offHist[:] {\n\t\tt.offHist[i] = 0\n\t}\n}\n\nfunc (t *tokens) Fill() {\n\tif t.n == 0 {\n\t\treturn\n\t}\n\tfor i, v := range t.litHist[:] {\n\t\tif v == 0 {\n\t\t\tt.litHist[i] = 1\n\t\t\tt.nFilled++\n\t\t}\n\t}\n\tfor i, v := range t.extraHist[:literalCount-256] {\n\t\tif v == 0 {\n\t\t\tt.nFilled++\n\t\t\tt.extraHist[i] = 1\n\t\t}\n\t}\n\tfor i, v := range t.offHist[:offsetCodeCount] {\n\t\tif v == 0 {\n\t\t\tt.offHist[i] = 1\n\t\t}\n\t}\n}\n\nfunc indexTokens(in []token) tokens {\n\tvar t tokens\n\tt.indexTokens(in)\n\treturn t\n}\n\nfunc (t *tokens) indexTokens(in []token) {\n\tt.Reset()\n\tfor _, tok := range in {\n\t\tif tok < matchType {\n\t\t\tt.AddLiteral(tok.literal())\n\t\t\tcontinue\n\t\t}\n\t\tt.AddMatch(uint32(tok.length()), tok.offset()&matchOffsetOnlyMask)\n\t}\n}\n\n// emitLiteral writes a literal chunk and returns the number of bytes written.\nfunc emitLiteral(dst *tokens, lit []byte) {\n\tfor _, v := range lit {\n\t\tdst.tokens[dst.n] = token(v)\n\t\tdst.litHist[v]++\n\t\tdst.n++\n\t}\n}\n\nfunc (t *tokens) AddLiteral(lit byte) {\n\tt.tokens[t.n] = token(lit)\n\tt.litHist[lit]++\n\tt.n++\n}\n\n// from https://stackoverflow.com/a/28730362\nfunc mFastLog2(val float32) float32 {\n\tux := int32(math.Float32bits(val))\n\tlog2 := (float32)(((ux >> 23) & 255) - 128)\n\tux &= -0x7f800001\n\tux += 127 << 23\n\tuval := math.Float32frombits(uint32(ux))\n\tlog2 += ((-0.34484843)*uval+2.02466578)*uval - 0.67487759\n\treturn log2\n}\n\n// EstimatedBits will return an minimum size estimated by an *optimal*\n// compression of the block.\n// The size of the block\nfunc (t *tokens) EstimatedBits() int {\n\tshannon := float32(0)\n\tbits := int(0)\n\tnMatches := 0\n\ttotal := int(t.n) + t.nFilled\n\tif total > 0 {\n\t\tinvTotal := 1.0 / float32(total)\n\t\tfor _, v := range t.litHist[:] {\n\t\t\tif v > 0 {\n\t\t\t\tn := float32(v)\n\t\t\t\tshannon += atLeastOne(-mFastLog2(n*invTotal)) * n\n\t\t\t}\n\t\t}\n\t\t// Just add 15 for EOB\n\t\tshannon += 15\n\t\tfor i, v := range t.extraHist[1 : literalCount-256] {\n\t\t\tif v > 0 {\n\t\t\t\tn := float32(v)\n\t\t\t\tshannon += atLeastOne(-mFastLog2(n*invTotal)) * n\n\t\t\t\tbits += int(lengthExtraBits[i&31]) * int(v)\n\t\t\t\tnMatches += int(v)\n\t\t\t}\n\t\t}\n\t}\n\tif nMatches > 0 {\n\t\tinvTotal := 1.0 / float32(nMatches)\n\t\tfor i, v := range t.offHist[:offsetCodeCount] {\n\t\t\tif v > 0 {\n\t\t\t\tn := float32(v)\n\t\t\t\tshannon += atLeastOne(-mFastLog2(n*invTotal)) * n\n\t\t\t\tbits += int(offsetExtraBits[i&31]) * int(v)\n\t\t\t}\n\t\t}\n\t}\n\treturn int(shannon) + bits\n}\n\n// AddMatch adds a match to the tokens.\n// This function is very sensitive to inlining and right on the border.\nfunc (t *tokens) AddMatch(xlength uint32, xoffset uint32) {\n\tif debugDeflate {\n\t\tif xlength >= maxMatchLength+baseMatchLength {\n\t\t\tpanic(fmt.Errorf(\"invalid length: %v\", xlength))\n\t\t}\n\t\tif xoffset >= maxMatchOffset+baseMatchOffset {\n\t\t\tpanic(fmt.Errorf(\"invalid offset: %v\", xoffset))\n\t\t}\n\t}\n\toCode := offsetCode(xoffset)\n\txoffset |= oCode << 16\n\n\tt.extraHist[lengthCodes1[uint8(xlength)]]++\n\tt.offHist[oCode&31]++\n\tt.tokens[t.n] = token(matchType | xlength<<lengthShift | xoffset)\n\tt.n++\n}\n\n// AddMatchLong adds a match to the tokens, potentially longer than max match length.\n// Length should NOT have the base subtracted, only offset should.\nfunc (t *tokens) AddMatchLong(xlength int32, xoffset uint32) {\n\tif debugDeflate {\n\t\tif xoffset >= maxMatchOffset+baseMatchOffset {\n\t\t\tpanic(fmt.Errorf(\"invalid offset: %v\", xoffset))\n\t\t}\n\t}\n\toc := offsetCode(xoffset)\n\txoffset |= oc << 16\n\tfor xlength > 0 {\n\t\txl := xlength\n\t\tif xl > 258 {\n\t\t\t// We need to have at least baseMatchLength left over for next loop.\n\t\t\tif xl > 258+baseMatchLength {\n\t\t\t\txl = 258\n\t\t\t} else {\n\t\t\t\txl = 258 - baseMatchLength\n\t\t\t}\n\t\t}\n\t\txlength -= xl\n\t\txl -= baseMatchLength\n\t\tt.extraHist[lengthCodes1[uint8(xl)]]++\n\t\tt.offHist[oc&31]++\n\t\tt.tokens[t.n] = token(matchType | uint32(xl)<<lengthShift | xoffset)\n\t\tt.n++\n\t}\n}\n\nfunc (t *tokens) AddEOB() {\n\tt.tokens[t.n] = token(endBlockMarker)\n\tt.extraHist[0]++\n\tt.n++\n}\n\nfunc (t *tokens) Slice() []token {\n\treturn t.tokens[:t.n]\n}\n\n// VarInt returns the tokens as varint encoded bytes.\nfunc (t *tokens) VarInt() []byte {\n\tvar b = make([]byte, binary.MaxVarintLen32*int(t.n))\n\tvar off int\n\tfor _, v := range t.tokens[:t.n] {\n\t\toff += binary.PutUvarint(b[off:], uint64(v))\n\t}\n\treturn b[:off]\n}\n\n// FromVarInt restores t to the varint encoded tokens provided.\n// Any data in t is removed.\nfunc (t *tokens) FromVarInt(b []byte) error {\n\tvar buf = bytes.NewReader(b)\n\tvar toks []token\n\tfor {\n\t\tr, err := binary.ReadUvarint(buf)\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttoks = append(toks, token(r))\n\t}\n\tt.indexTokens(toks)\n\treturn nil\n}\n\n// Returns the type of a token\nfunc (t token) typ() uint32 { return uint32(t) & typeMask }\n\n// Returns the literal of a literal token\nfunc (t token) literal() uint8 { return uint8(t) }\n\n// Returns the extra offset of a match token\nfunc (t token) offset() uint32 { return uint32(t) & offsetMask }\n\nfunc (t token) length() uint8 { return uint8(t >> lengthShift) }\n\n// Convert length to code.\nfunc lengthCode(len uint8) uint8 { return lengthCodes[len] }\n\n// Returns the offset code corresponding to a specific offset\nfunc offsetCode(off uint32) uint32 {\n\tif false {\n\t\tif off < uint32(len(offsetCodes)) {\n\t\t\treturn offsetCodes[off&255]\n\t\t} else if off>>7 < uint32(len(offsetCodes)) {\n\t\t\treturn offsetCodes[(off>>7)&255] + 14\n\t\t} else {\n\t\t\treturn offsetCodes[(off>>14)&255] + 28\n\t\t}\n\t}\n\tif off < uint32(len(offsetCodes)) {\n\t\treturn offsetCodes[uint8(off)]\n\t}\n\treturn offsetCodes14[uint8(off>>7)]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/fse/README.md",
    "content": "# Finite State Entropy\r\n\r\nThis package provides Finite State Entropy encoding and decoding.\r\n            \r\nFinite State Entropy (also referenced as [tANS](https://en.wikipedia.org/wiki/Asymmetric_numeral_systems#tANS)) \r\nencoding provides a fast near-optimal symbol encoding/decoding\r\nfor byte blocks as implemented in [zstandard](https://github.com/facebook/zstd).\r\n\r\nThis can be used for compressing input with a lot of similar input values to the smallest number of bytes.\r\nThis does not perform any multi-byte [dictionary coding](https://en.wikipedia.org/wiki/Dictionary_coder) as LZ coders,\r\nbut it can be used as a secondary step to compressors (like Snappy) that does not do entropy encoding. \r\n\r\n* [Godoc documentation](https://godoc.org/github.com/klauspost/compress/fse)\r\n\r\n## News\r\n\r\n * Feb 2018: First implementation released. Consider this beta software for now.\r\n\r\n# Usage\r\n\r\nThis package provides a low level interface that allows to compress single independent blocks. \r\n\r\nEach block is separate, and there is no built in integrity checks. \r\nThis means that the caller should keep track of block sizes and also do checksums if needed.  \r\n\r\nCompressing a block is done via the [`Compress`](https://godoc.org/github.com/klauspost/compress/fse#Compress) function.\r\nYou must provide input and will receive the output and maybe an error.\r\n\r\nThese error values can be returned:\r\n\r\n| Error               | Description                                                                 |\r\n|---------------------|-----------------------------------------------------------------------------|\r\n| `<nil>`             | Everything ok, output is returned                                           |\r\n| `ErrIncompressible` | Returned when input is judged to be too hard to compress                    |\r\n| `ErrUseRLE`         | Returned from the compressor when the input is a single byte value repeated |\r\n| `(error)`           | An internal error occurred.                                                 |\r\n\r\nAs can be seen above there are errors that will be returned even under normal operation so it is important to handle these.\r\n\r\nTo reduce allocations you can provide a [`Scratch`](https://godoc.org/github.com/klauspost/compress/fse#Scratch) object \r\nthat can be re-used for successive calls. Both compression and decompression accepts a `Scratch` object, and the same \r\nobject can be used for both.   \r\n\r\nBe aware, that when re-using a `Scratch` object that the *output* buffer is also re-used, so if you are still using this\r\nyou must set the `Out` field in the scratch to nil. The same buffer is used for compression and decompression output.\r\n\r\nDecompressing is done by calling the [`Decompress`](https://godoc.org/github.com/klauspost/compress/fse#Decompress) function.\r\nYou must provide the output from the compression stage, at exactly the size you got back. If you receive an error back\r\nyour input was likely corrupted. \r\n\r\nIt is important to note that a successful decoding does *not* mean your output matches your original input. \r\nThere are no integrity checks, so relying on errors from the decompressor does not assure your data is valid.\r\n\r\nFor more detailed usage, see examples in the [godoc documentation](https://godoc.org/github.com/klauspost/compress/fse#pkg-examples).\r\n\r\n# Performance\r\n\r\nA lot of factors are affecting speed. Block sizes and compressibility of the material are primary factors.  \r\nAll compression functions are currently only running on the calling goroutine so only one core will be used per block.  \r\n\r\nThe compressor is significantly faster if symbols are kept as small as possible. The highest byte value of the input\r\nis used to reduce some of the processing, so if all your input is above byte value 64 for instance, it may be \r\nbeneficial to transpose all your input values down by 64.   \r\n\r\nWith moderate block sizes around 64k speed are typically 200MB/s per core for compression and \r\naround 300MB/s decompression speed. \r\n\r\nThe same hardware typically does Huffman (deflate) encoding at 125MB/s and decompression at 100MB/s. \r\n\r\n# Plans\r\n\r\nAt one point, more internals will be exposed to facilitate more \"expert\" usage of the components. \r\n\r\nA streaming interface is also likely to be implemented. Likely compatible with [FSE stream format](https://github.com/Cyan4973/FiniteStateEntropy/blob/dev/programs/fileio.c#L261).  \r\n\r\n# Contributing\r\n\r\nContributions are always welcome. Be aware that adding public functions will require good justification and breaking \r\nchanges will likely not be accepted. If in doubt open an issue before writing the PR.  "
  },
  {
    "path": "vendor/github.com/klauspost/compress/fse/bitreader.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage fse\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n)\n\n// bitReader reads a bitstream in reverse.\n// The last set bit indicates the start of the stream and is used\n// for aligning the input.\ntype bitReader struct {\n\tin       []byte\n\toff      uint // next byte to read is at in[off - 1]\n\tvalue    uint64\n\tbitsRead uint8\n}\n\n// init initializes and resets the bit reader.\nfunc (b *bitReader) init(in []byte) error {\n\tif len(in) < 1 {\n\t\treturn errors.New(\"corrupt stream: too short\")\n\t}\n\tb.in = in\n\tb.off = uint(len(in))\n\t// The highest bit of the last byte indicates where to start\n\tv := in[len(in)-1]\n\tif v == 0 {\n\t\treturn errors.New(\"corrupt stream, did not find end of stream\")\n\t}\n\tb.bitsRead = 64\n\tb.value = 0\n\tif len(in) >= 8 {\n\t\tb.fillFastStart()\n\t} else {\n\t\tb.fill()\n\t\tb.fill()\n\t}\n\tb.bitsRead += 8 - uint8(highBits(uint32(v)))\n\treturn nil\n}\n\n// getBits will return n bits. n can be 0.\nfunc (b *bitReader) getBits(n uint8) uint16 {\n\tif n == 0 || b.bitsRead >= 64 {\n\t\treturn 0\n\t}\n\treturn b.getBitsFast(n)\n}\n\n// getBitsFast requires that at least one bit is requested every time.\n// There are no checks if the buffer is filled.\nfunc (b *bitReader) getBitsFast(n uint8) uint16 {\n\tconst regMask = 64 - 1\n\tv := uint16((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask))\n\tb.bitsRead += n\n\treturn v\n}\n\n// fillFast() will make sure at least 32 bits are available.\n// There must be at least 4 bytes available.\nfunc (b *bitReader) fillFast() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\t// 2 bounds checks.\n\tv := b.in[b.off-4:]\n\tv = v[:4]\n\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\tb.value = (b.value << 32) | uint64(low)\n\tb.bitsRead -= 32\n\tb.off -= 4\n}\n\n// fill() will make sure at least 32 bits are available.\nfunc (b *bitReader) fill() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\tif b.off > 4 {\n\t\tv := b.in[b.off-4:]\n\t\tv = v[:4]\n\t\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\t\tb.value = (b.value << 32) | uint64(low)\n\t\tb.bitsRead -= 32\n\t\tb.off -= 4\n\t\treturn\n\t}\n\tfor b.off > 0 {\n\t\tb.value = (b.value << 8) | uint64(b.in[b.off-1])\n\t\tb.bitsRead -= 8\n\t\tb.off--\n\t}\n}\n\n// fillFastStart() assumes the bitreader is empty and there is at least 8 bytes to read.\nfunc (b *bitReader) fillFastStart() {\n\t// Do single re-slice to avoid bounds checks.\n\tb.value = binary.LittleEndian.Uint64(b.in[b.off-8:])\n\tb.bitsRead = 0\n\tb.off -= 8\n}\n\n// finished returns true if all bits have been read from the bit stream.\nfunc (b *bitReader) finished() bool {\n\treturn b.bitsRead >= 64 && b.off == 0\n}\n\n// close the bitstream and returns an error if out-of-buffer reads occurred.\nfunc (b *bitReader) close() error {\n\t// Release reference.\n\tb.in = nil\n\tif b.bitsRead > 64 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/fse/bitwriter.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage fse\n\nimport \"fmt\"\n\n// bitWriter will write bits.\n// First bit will be LSB of the first byte of output.\ntype bitWriter struct {\n\tbitContainer uint64\n\tnBits        uint8\n\tout          []byte\n}\n\n// bitMask16 is bitmasks. Has extra to avoid bounds check.\nvar bitMask16 = [32]uint16{\n\t0, 1, 3, 7, 0xF, 0x1F,\n\t0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,\n\t0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0xFFFF,\n\t0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,\n\t0xFFFF, 0xFFFF} /* up to 16 bits */\n\n// addBits16NC will add up to 16 bits.\n// It will not check if there is space for them,\n// so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) addBits16NC(value uint16, bits uint8) {\n\tb.bitContainer |= uint64(value&bitMask16[bits&31]) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated.\n// It will not check if there is space for them, so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) addBits16Clean(value uint16, bits uint8) {\n\tb.bitContainer |= uint64(value) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// addBits16ZeroNC will add up to 16 bits.\n// It will not check if there is space for them,\n// so the caller must ensure that it has flushed recently.\n// This is fastest if bits can be zero.\nfunc (b *bitWriter) addBits16ZeroNC(value uint16, bits uint8) {\n\tif bits == 0 {\n\t\treturn\n\t}\n\tvalue <<= (16 - bits) & 15\n\tvalue >>= (16 - bits) & 15\n\tb.bitContainer |= uint64(value) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// flush will flush all pending full bytes.\n// There will be at least 56 bits available for writing when this has been called.\n// Using flush32 is faster, but leaves less space for writing.\nfunc (b *bitWriter) flush() {\n\tv := b.nBits >> 3\n\tswitch v {\n\tcase 0:\n\tcase 1:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t)\n\tcase 2:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t\tbyte(b.bitContainer>>8),\n\t\t)\n\tcase 3:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t\tbyte(b.bitContainer>>8),\n\t\t\tbyte(b.bitContainer>>16),\n\t\t)\n\tcase 4:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t\tbyte(b.bitContainer>>8),\n\t\t\tbyte(b.bitContainer>>16),\n\t\t\tbyte(b.bitContainer>>24),\n\t\t)\n\tcase 5:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t\tbyte(b.bitContainer>>8),\n\t\t\tbyte(b.bitContainer>>16),\n\t\t\tbyte(b.bitContainer>>24),\n\t\t\tbyte(b.bitContainer>>32),\n\t\t)\n\tcase 6:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t\tbyte(b.bitContainer>>8),\n\t\t\tbyte(b.bitContainer>>16),\n\t\t\tbyte(b.bitContainer>>24),\n\t\t\tbyte(b.bitContainer>>32),\n\t\t\tbyte(b.bitContainer>>40),\n\t\t)\n\tcase 7:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t\tbyte(b.bitContainer>>8),\n\t\t\tbyte(b.bitContainer>>16),\n\t\t\tbyte(b.bitContainer>>24),\n\t\t\tbyte(b.bitContainer>>32),\n\t\t\tbyte(b.bitContainer>>40),\n\t\t\tbyte(b.bitContainer>>48),\n\t\t)\n\tcase 8:\n\t\tb.out = append(b.out,\n\t\t\tbyte(b.bitContainer),\n\t\t\tbyte(b.bitContainer>>8),\n\t\t\tbyte(b.bitContainer>>16),\n\t\t\tbyte(b.bitContainer>>24),\n\t\t\tbyte(b.bitContainer>>32),\n\t\t\tbyte(b.bitContainer>>40),\n\t\t\tbyte(b.bitContainer>>48),\n\t\t\tbyte(b.bitContainer>>56),\n\t\t)\n\tdefault:\n\t\tpanic(fmt.Errorf(\"bits (%d) > 64\", b.nBits))\n\t}\n\tb.bitContainer >>= v << 3\n\tb.nBits &= 7\n}\n\n// flush32 will flush out, so there are at least 32 bits available for writing.\nfunc (b *bitWriter) flush32() {\n\tif b.nBits < 32 {\n\t\treturn\n\t}\n\tb.out = append(b.out,\n\t\tbyte(b.bitContainer),\n\t\tbyte(b.bitContainer>>8),\n\t\tbyte(b.bitContainer>>16),\n\t\tbyte(b.bitContainer>>24))\n\tb.nBits -= 32\n\tb.bitContainer >>= 32\n}\n\n// flushAlign will flush remaining full bytes and align to next byte boundary.\nfunc (b *bitWriter) flushAlign() {\n\tnbBytes := (b.nBits + 7) >> 3\n\tfor i := uint8(0); i < nbBytes; i++ {\n\t\tb.out = append(b.out, byte(b.bitContainer>>(i*8)))\n\t}\n\tb.nBits = 0\n\tb.bitContainer = 0\n}\n\n// close will write the alignment bit and write the final byte(s)\n// to the output.\nfunc (b *bitWriter) close() {\n\t// End mark\n\tb.addBits16Clean(1, 1)\n\t// flush until next byte.\n\tb.flushAlign()\n}\n\n// reset and continue writing by appending to out.\nfunc (b *bitWriter) reset(out []byte) {\n\tb.bitContainer = 0\n\tb.nBits = 0\n\tb.out = out\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/fse/bytereader.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage fse\n\n// byteReader provides a byte reader that reads\n// little endian values from a byte stream.\n// The input stream is manually advanced.\n// The reader performs no bounds checks.\ntype byteReader struct {\n\tb   []byte\n\toff int\n}\n\n// init will initialize the reader and set the input.\nfunc (b *byteReader) init(in []byte) {\n\tb.b = in\n\tb.off = 0\n}\n\n// advance the stream b n bytes.\nfunc (b *byteReader) advance(n uint) {\n\tb.off += int(n)\n}\n\n// Uint32 returns a little endian uint32 starting at current offset.\nfunc (b byteReader) Uint32() uint32 {\n\tb2 := b.b[b.off:]\n\tb2 = b2[:4]\n\tv3 := uint32(b2[3])\n\tv2 := uint32(b2[2])\n\tv1 := uint32(b2[1])\n\tv0 := uint32(b2[0])\n\treturn v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)\n}\n\n// unread returns the unread portion of the input.\nfunc (b byteReader) unread() []byte {\n\treturn b.b[b.off:]\n}\n\n// remain will return the number of bytes remaining.\nfunc (b byteReader) remain() int {\n\treturn len(b.b) - b.off\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/fse/compress.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage fse\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// Compress the input bytes. Input must be < 2GB.\n// Provide a Scratch buffer to avoid memory allocations.\n// Note that the output is also kept in the scratch buffer.\n// If input is too hard to compress, ErrIncompressible is returned.\n// If input is a single byte value repeated ErrUseRLE is returned.\nfunc Compress(in []byte, s *Scratch) ([]byte, error) {\n\tif len(in) <= 1 {\n\t\treturn nil, ErrIncompressible\n\t}\n\tif len(in) > (2<<30)-1 {\n\t\treturn nil, errors.New(\"input too big, must be < 2GB\")\n\t}\n\ts, err := s.prepare(in)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Create histogram, if none was provided.\n\tmaxCount := s.maxCount\n\tif maxCount == 0 {\n\t\tmaxCount = s.countSimple(in)\n\t}\n\t// Reset for next run.\n\ts.clearCount = true\n\ts.maxCount = 0\n\tif maxCount == len(in) {\n\t\t// One symbol, use RLE\n\t\treturn nil, ErrUseRLE\n\t}\n\tif maxCount == 1 || maxCount < (len(in)>>7) {\n\t\t// Each symbol present maximum once or too well distributed.\n\t\treturn nil, ErrIncompressible\n\t}\n\ts.optimalTableLog()\n\terr = s.normalizeCount()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = s.writeCount()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif false {\n\t\terr = s.validateNorm()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\terr = s.buildCTable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = s.compress(in)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ts.Out = s.bw.out\n\t// Check if we compressed.\n\tif len(s.Out) >= len(in) {\n\t\treturn nil, ErrIncompressible\n\t}\n\treturn s.Out, nil\n}\n\n// cState contains the compression state of a stream.\ntype cState struct {\n\tbw         *bitWriter\n\tstateTable []uint16\n\tstate      uint16\n}\n\n// init will initialize the compression state to the first symbol of the stream.\nfunc (c *cState) init(bw *bitWriter, ct *cTable, tableLog uint8, first symbolTransform) {\n\tc.bw = bw\n\tc.stateTable = ct.stateTable\n\n\tnbBitsOut := (first.deltaNbBits + (1 << 15)) >> 16\n\tim := int32((nbBitsOut << 16) - first.deltaNbBits)\n\tlu := (im >> nbBitsOut) + first.deltaFindState\n\tc.state = c.stateTable[lu]\n}\n\n// encode the output symbol provided and write it to the bitstream.\nfunc (c *cState) encode(symbolTT symbolTransform) {\n\tnbBitsOut := (uint32(c.state) + symbolTT.deltaNbBits) >> 16\n\tdstState := int32(c.state>>(nbBitsOut&15)) + symbolTT.deltaFindState\n\tc.bw.addBits16NC(c.state, uint8(nbBitsOut))\n\tc.state = c.stateTable[dstState]\n}\n\n// encode the output symbol provided and write it to the bitstream.\nfunc (c *cState) encodeZero(symbolTT symbolTransform) {\n\tnbBitsOut := (uint32(c.state) + symbolTT.deltaNbBits) >> 16\n\tdstState := int32(c.state>>(nbBitsOut&15)) + symbolTT.deltaFindState\n\tc.bw.addBits16ZeroNC(c.state, uint8(nbBitsOut))\n\tc.state = c.stateTable[dstState]\n}\n\n// flush will write the tablelog to the output and flush the remaining full bytes.\nfunc (c *cState) flush(tableLog uint8) {\n\tc.bw.flush32()\n\tc.bw.addBits16NC(c.state, tableLog)\n\tc.bw.flush()\n}\n\n// compress is the main compression loop that will encode the input from the last byte to the first.\nfunc (s *Scratch) compress(src []byte) error {\n\tif len(src) <= 2 {\n\t\treturn errors.New(\"compress: src too small\")\n\t}\n\ttt := s.ct.symbolTT[:256]\n\ts.bw.reset(s.Out)\n\n\t// Our two states each encodes every second byte.\n\t// Last byte encoded (first byte decoded) will always be encoded by c1.\n\tvar c1, c2 cState\n\n\t// Encode so remaining size is divisible by 4.\n\tip := len(src)\n\tif ip&1 == 1 {\n\t\tc1.init(&s.bw, &s.ct, s.actualTableLog, tt[src[ip-1]])\n\t\tc2.init(&s.bw, &s.ct, s.actualTableLog, tt[src[ip-2]])\n\t\tc1.encodeZero(tt[src[ip-3]])\n\t\tip -= 3\n\t} else {\n\t\tc2.init(&s.bw, &s.ct, s.actualTableLog, tt[src[ip-1]])\n\t\tc1.init(&s.bw, &s.ct, s.actualTableLog, tt[src[ip-2]])\n\t\tip -= 2\n\t}\n\tif ip&2 != 0 {\n\t\tc2.encodeZero(tt[src[ip-1]])\n\t\tc1.encodeZero(tt[src[ip-2]])\n\t\tip -= 2\n\t}\n\tsrc = src[:ip]\n\n\t// Main compression loop.\n\tswitch {\n\tcase !s.zeroBits && s.actualTableLog <= 8:\n\t\t// We can encode 4 symbols without requiring a flush.\n\t\t// We do not need to check if any output is 0 bits.\n\t\tfor ; len(src) >= 4; src = src[:len(src)-4] {\n\t\t\ts.bw.flush32()\n\t\t\tv3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1]\n\t\t\tc2.encode(tt[v0])\n\t\t\tc1.encode(tt[v1])\n\t\t\tc2.encode(tt[v2])\n\t\t\tc1.encode(tt[v3])\n\t\t}\n\tcase !s.zeroBits:\n\t\t// We do not need to check if any output is 0 bits.\n\t\tfor ; len(src) >= 4; src = src[:len(src)-4] {\n\t\t\ts.bw.flush32()\n\t\t\tv3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1]\n\t\t\tc2.encode(tt[v0])\n\t\t\tc1.encode(tt[v1])\n\t\t\ts.bw.flush32()\n\t\t\tc2.encode(tt[v2])\n\t\t\tc1.encode(tt[v3])\n\t\t}\n\tcase s.actualTableLog <= 8:\n\t\t// We can encode 4 symbols without requiring a flush\n\t\tfor ; len(src) >= 4; src = src[:len(src)-4] {\n\t\t\ts.bw.flush32()\n\t\t\tv3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1]\n\t\t\tc2.encodeZero(tt[v0])\n\t\t\tc1.encodeZero(tt[v1])\n\t\t\tc2.encodeZero(tt[v2])\n\t\t\tc1.encodeZero(tt[v3])\n\t\t}\n\tdefault:\n\t\tfor ; len(src) >= 4; src = src[:len(src)-4] {\n\t\t\ts.bw.flush32()\n\t\t\tv3, v2, v1, v0 := src[len(src)-4], src[len(src)-3], src[len(src)-2], src[len(src)-1]\n\t\t\tc2.encodeZero(tt[v0])\n\t\t\tc1.encodeZero(tt[v1])\n\t\t\ts.bw.flush32()\n\t\t\tc2.encodeZero(tt[v2])\n\t\t\tc1.encodeZero(tt[v3])\n\t\t}\n\t}\n\n\t// Flush final state.\n\t// Used to initialize state when decoding.\n\tc2.flush(s.actualTableLog)\n\tc1.flush(s.actualTableLog)\n\n\ts.bw.close()\n\treturn nil\n}\n\n// writeCount will write the normalized histogram count to header.\n// This is read back by readNCount.\nfunc (s *Scratch) writeCount() error {\n\tvar (\n\t\ttableLog  = s.actualTableLog\n\t\ttableSize = 1 << tableLog\n\t\tprevious0 bool\n\t\tcharnum   uint16\n\n\t\tmaxHeaderSize = ((int(s.symbolLen)*int(tableLog) + 4 + 2) >> 3) + 3\n\n\t\t// Write Table Size\n\t\tbitStream = uint32(tableLog - minTablelog)\n\t\tbitCount  = uint(4)\n\t\tremaining = int16(tableSize + 1) /* +1 for extra accuracy */\n\t\tthreshold = int16(tableSize)\n\t\tnbBits    = uint(tableLog + 1)\n\t)\n\tif cap(s.Out) < maxHeaderSize {\n\t\ts.Out = make([]byte, 0, s.br.remain()+maxHeaderSize)\n\t}\n\toutP := uint(0)\n\tout := s.Out[:maxHeaderSize]\n\n\t// stops at 1\n\tfor remaining > 1 {\n\t\tif previous0 {\n\t\t\tstart := charnum\n\t\t\tfor s.norm[charnum] == 0 {\n\t\t\t\tcharnum++\n\t\t\t}\n\t\t\tfor charnum >= start+24 {\n\t\t\t\tstart += 24\n\t\t\t\tbitStream += uint32(0xFFFF) << bitCount\n\t\t\t\tout[outP] = byte(bitStream)\n\t\t\t\tout[outP+1] = byte(bitStream >> 8)\n\t\t\t\toutP += 2\n\t\t\t\tbitStream >>= 16\n\t\t\t}\n\t\t\tfor charnum >= start+3 {\n\t\t\t\tstart += 3\n\t\t\t\tbitStream += 3 << bitCount\n\t\t\t\tbitCount += 2\n\t\t\t}\n\t\t\tbitStream += uint32(charnum-start) << bitCount\n\t\t\tbitCount += 2\n\t\t\tif bitCount > 16 {\n\t\t\t\tout[outP] = byte(bitStream)\n\t\t\t\tout[outP+1] = byte(bitStream >> 8)\n\t\t\t\toutP += 2\n\t\t\t\tbitStream >>= 16\n\t\t\t\tbitCount -= 16\n\t\t\t}\n\t\t}\n\n\t\tcount := s.norm[charnum]\n\t\tcharnum++\n\t\tmax := (2*threshold - 1) - remaining\n\t\tif count < 0 {\n\t\t\tremaining += count\n\t\t} else {\n\t\t\tremaining -= count\n\t\t}\n\t\tcount++ // +1 for extra accuracy\n\t\tif count >= threshold {\n\t\t\tcount += max // [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[\n\t\t}\n\t\tbitStream += uint32(count) << bitCount\n\t\tbitCount += nbBits\n\t\tif count < max {\n\t\t\tbitCount--\n\t\t}\n\n\t\tprevious0 = count == 1\n\t\tif remaining < 1 {\n\t\t\treturn errors.New(\"internal error: remaining<1\")\n\t\t}\n\t\tfor remaining < threshold {\n\t\t\tnbBits--\n\t\t\tthreshold >>= 1\n\t\t}\n\n\t\tif bitCount > 16 {\n\t\t\tout[outP] = byte(bitStream)\n\t\t\tout[outP+1] = byte(bitStream >> 8)\n\t\t\toutP += 2\n\t\t\tbitStream >>= 16\n\t\t\tbitCount -= 16\n\t\t}\n\t}\n\n\tout[outP] = byte(bitStream)\n\tout[outP+1] = byte(bitStream >> 8)\n\toutP += (bitCount + 7) / 8\n\n\tif charnum > s.symbolLen {\n\t\treturn errors.New(\"internal error: charnum > s.symbolLen\")\n\t}\n\ts.Out = out[:outP]\n\treturn nil\n}\n\n// symbolTransform contains the state transform for a symbol.\ntype symbolTransform struct {\n\tdeltaFindState int32\n\tdeltaNbBits    uint32\n}\n\n// String prints values as a human readable string.\nfunc (s symbolTransform) String() string {\n\treturn fmt.Sprintf(\"dnbits: %08x, fs:%d\", s.deltaNbBits, s.deltaFindState)\n}\n\n// cTable contains tables used for compression.\ntype cTable struct {\n\ttableSymbol []byte\n\tstateTable  []uint16\n\tsymbolTT    []symbolTransform\n}\n\n// allocCtable will allocate tables needed for compression.\n// If existing tables a re big enough, they are simply re-used.\nfunc (s *Scratch) allocCtable() {\n\ttableSize := 1 << s.actualTableLog\n\t// get tableSymbol that is big enough.\n\tif cap(s.ct.tableSymbol) < tableSize {\n\t\ts.ct.tableSymbol = make([]byte, tableSize)\n\t}\n\ts.ct.tableSymbol = s.ct.tableSymbol[:tableSize]\n\n\tctSize := tableSize\n\tif cap(s.ct.stateTable) < ctSize {\n\t\ts.ct.stateTable = make([]uint16, ctSize)\n\t}\n\ts.ct.stateTable = s.ct.stateTable[:ctSize]\n\n\tif cap(s.ct.symbolTT) < 256 {\n\t\ts.ct.symbolTT = make([]symbolTransform, 256)\n\t}\n\ts.ct.symbolTT = s.ct.symbolTT[:256]\n}\n\n// buildCTable will populate the compression table so it is ready to be used.\nfunc (s *Scratch) buildCTable() error {\n\ttableSize := uint32(1 << s.actualTableLog)\n\thighThreshold := tableSize - 1\n\tvar cumul [maxSymbolValue + 2]int16\n\n\ts.allocCtable()\n\ttableSymbol := s.ct.tableSymbol[:tableSize]\n\t// symbol start positions\n\t{\n\t\tcumul[0] = 0\n\t\tfor ui, v := range s.norm[:s.symbolLen-1] {\n\t\t\tu := byte(ui) // one less than reference\n\t\t\tif v == -1 {\n\t\t\t\t// Low proba symbol\n\t\t\t\tcumul[u+1] = cumul[u] + 1\n\t\t\t\ttableSymbol[highThreshold] = u\n\t\t\t\thighThreshold--\n\t\t\t} else {\n\t\t\t\tcumul[u+1] = cumul[u] + v\n\t\t\t}\n\t\t}\n\t\t// Encode last symbol separately to avoid overflowing u\n\t\tu := int(s.symbolLen - 1)\n\t\tv := s.norm[s.symbolLen-1]\n\t\tif v == -1 {\n\t\t\t// Low proba symbol\n\t\t\tcumul[u+1] = cumul[u] + 1\n\t\t\ttableSymbol[highThreshold] = byte(u)\n\t\t\thighThreshold--\n\t\t} else {\n\t\t\tcumul[u+1] = cumul[u] + v\n\t\t}\n\t\tif uint32(cumul[s.symbolLen]) != tableSize {\n\t\t\treturn fmt.Errorf(\"internal error: expected cumul[s.symbolLen] (%d) == tableSize (%d)\", cumul[s.symbolLen], tableSize)\n\t\t}\n\t\tcumul[s.symbolLen] = int16(tableSize) + 1\n\t}\n\t// Spread symbols\n\ts.zeroBits = false\n\t{\n\t\tstep := tableStep(tableSize)\n\t\ttableMask := tableSize - 1\n\t\tvar position uint32\n\t\t// if any symbol > largeLimit, we may have 0 bits output.\n\t\tlargeLimit := int16(1 << (s.actualTableLog - 1))\n\t\tfor ui, v := range s.norm[:s.symbolLen] {\n\t\t\tsymbol := byte(ui)\n\t\t\tif v > largeLimit {\n\t\t\t\ts.zeroBits = true\n\t\t\t}\n\t\t\tfor nbOccurrences := int16(0); nbOccurrences < v; nbOccurrences++ {\n\t\t\t\ttableSymbol[position] = symbol\n\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\tfor position > highThreshold {\n\t\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\t} /* Low proba area */\n\t\t\t}\n\t\t}\n\n\t\t// Check if we have gone through all positions\n\t\tif position != 0 {\n\t\t\treturn errors.New(\"position!=0\")\n\t\t}\n\t}\n\n\t// Build table\n\ttable := s.ct.stateTable\n\t{\n\t\ttsi := int(tableSize)\n\t\tfor u, v := range tableSymbol {\n\t\t\t// TableU16 : sorted by symbol order; gives next state value\n\t\t\ttable[cumul[v]] = uint16(tsi + u)\n\t\t\tcumul[v]++\n\t\t}\n\t}\n\n\t// Build Symbol Transformation Table\n\t{\n\t\ttotal := int16(0)\n\t\tsymbolTT := s.ct.symbolTT[:s.symbolLen]\n\t\ttableLog := s.actualTableLog\n\t\ttl := (uint32(tableLog) << 16) - (1 << tableLog)\n\t\tfor i, v := range s.norm[:s.symbolLen] {\n\t\t\tswitch v {\n\t\t\tcase 0:\n\t\t\tcase -1, 1:\n\t\t\t\tsymbolTT[i].deltaNbBits = tl\n\t\t\t\tsymbolTT[i].deltaFindState = int32(total - 1)\n\t\t\t\ttotal++\n\t\t\tdefault:\n\t\t\t\tmaxBitsOut := uint32(tableLog) - highBits(uint32(v-1))\n\t\t\t\tminStatePlus := uint32(v) << maxBitsOut\n\t\t\t\tsymbolTT[i].deltaNbBits = (maxBitsOut << 16) - minStatePlus\n\t\t\t\tsymbolTT[i].deltaFindState = int32(total - v)\n\t\t\t\ttotal += v\n\t\t\t}\n\t\t}\n\t\tif total != int16(tableSize) {\n\t\t\treturn fmt.Errorf(\"total mismatch %d (got) != %d (want)\", total, tableSize)\n\t\t}\n\t}\n\treturn nil\n}\n\n// countSimple will create a simple histogram in s.count.\n// Returns the biggest count.\n// Does not update s.clearCount.\nfunc (s *Scratch) countSimple(in []byte) (max int) {\n\tfor _, v := range in {\n\t\ts.count[v]++\n\t}\n\tm, symlen := uint32(0), s.symbolLen\n\tfor i, v := range s.count[:] {\n\t\tif v == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif v > m {\n\t\t\tm = v\n\t\t}\n\t\tsymlen = uint16(i) + 1\n\t}\n\ts.symbolLen = symlen\n\treturn int(m)\n}\n\n// minTableLog provides the minimum logSize to safely represent a distribution.\nfunc (s *Scratch) minTableLog() uint8 {\n\tminBitsSrc := highBits(uint32(s.br.remain()-1)) + 1\n\tminBitsSymbols := highBits(uint32(s.symbolLen-1)) + 2\n\tif minBitsSrc < minBitsSymbols {\n\t\treturn uint8(minBitsSrc)\n\t}\n\treturn uint8(minBitsSymbols)\n}\n\n// optimalTableLog calculates and sets the optimal tableLog in s.actualTableLog\nfunc (s *Scratch) optimalTableLog() {\n\ttableLog := s.TableLog\n\tminBits := s.minTableLog()\n\tmaxBitsSrc := uint8(highBits(uint32(s.br.remain()-1))) - 2\n\tif maxBitsSrc < tableLog {\n\t\t// Accuracy can be reduced\n\t\ttableLog = maxBitsSrc\n\t}\n\tif minBits > tableLog {\n\t\ttableLog = minBits\n\t}\n\t// Need a minimum to safely represent all symbol values\n\tif tableLog < minTablelog {\n\t\ttableLog = minTablelog\n\t}\n\tif tableLog > maxTableLog {\n\t\ttableLog = maxTableLog\n\t}\n\ts.actualTableLog = tableLog\n}\n\nvar rtbTable = [...]uint32{0, 473195, 504333, 520860, 550000, 700000, 750000, 830000}\n\n// normalizeCount will normalize the count of the symbols so\n// the total is equal to the table size.\nfunc (s *Scratch) normalizeCount() error {\n\tvar (\n\t\ttableLog          = s.actualTableLog\n\t\tscale             = 62 - uint64(tableLog)\n\t\tstep              = (1 << 62) / uint64(s.br.remain())\n\t\tvStep             = uint64(1) << (scale - 20)\n\t\tstillToDistribute = int16(1 << tableLog)\n\t\tlargest           int\n\t\tlargestP          int16\n\t\tlowThreshold      = (uint32)(s.br.remain() >> tableLog)\n\t)\n\n\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\t// already handled\n\t\t// if (count[s] == s.length) return 0;   /* rle special case */\n\n\t\tif cnt == 0 {\n\t\t\ts.norm[i] = 0\n\t\t\tcontinue\n\t\t}\n\t\tif cnt <= lowThreshold {\n\t\t\ts.norm[i] = -1\n\t\t\tstillToDistribute--\n\t\t} else {\n\t\t\tproba := (int16)((uint64(cnt) * step) >> scale)\n\t\t\tif proba < 8 {\n\t\t\t\trestToBeat := vStep * uint64(rtbTable[proba])\n\t\t\t\tv := uint64(cnt)*step - (uint64(proba) << scale)\n\t\t\t\tif v > restToBeat {\n\t\t\t\t\tproba++\n\t\t\t\t}\n\t\t\t}\n\t\t\tif proba > largestP {\n\t\t\t\tlargestP = proba\n\t\t\t\tlargest = i\n\t\t\t}\n\t\t\ts.norm[i] = proba\n\t\t\tstillToDistribute -= proba\n\t\t}\n\t}\n\n\tif -stillToDistribute >= (s.norm[largest] >> 1) {\n\t\t// corner case, need another normalization method\n\t\treturn s.normalizeCount2()\n\t}\n\ts.norm[largest] += stillToDistribute\n\treturn nil\n}\n\n// Secondary normalization method.\n// To be used when primary method fails.\nfunc (s *Scratch) normalizeCount2() error {\n\tconst notYetAssigned = -2\n\tvar (\n\t\tdistributed  uint32\n\t\ttotal        = uint32(s.br.remain())\n\t\ttableLog     = s.actualTableLog\n\t\tlowThreshold = total >> tableLog\n\t\tlowOne       = (total * 3) >> (tableLog + 1)\n\t)\n\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\tif cnt == 0 {\n\t\t\ts.norm[i] = 0\n\t\t\tcontinue\n\t\t}\n\t\tif cnt <= lowThreshold {\n\t\t\ts.norm[i] = -1\n\t\t\tdistributed++\n\t\t\ttotal -= cnt\n\t\t\tcontinue\n\t\t}\n\t\tif cnt <= lowOne {\n\t\t\ts.norm[i] = 1\n\t\t\tdistributed++\n\t\t\ttotal -= cnt\n\t\t\tcontinue\n\t\t}\n\t\ts.norm[i] = notYetAssigned\n\t}\n\ttoDistribute := (1 << tableLog) - distributed\n\n\tif (total / toDistribute) > lowOne {\n\t\t// risk of rounding to zero\n\t\tlowOne = (total * 3) / (toDistribute * 2)\n\t\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\t\tif (s.norm[i] == notYetAssigned) && (cnt <= lowOne) {\n\t\t\t\ts.norm[i] = 1\n\t\t\t\tdistributed++\n\t\t\t\ttotal -= cnt\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\ttoDistribute = (1 << tableLog) - distributed\n\t}\n\tif distributed == uint32(s.symbolLen)+1 {\n\t\t// all values are pretty poor;\n\t\t//   probably incompressible data (should have already been detected);\n\t\t//   find max, then give all remaining points to max\n\t\tvar maxV int\n\t\tvar maxC uint32\n\t\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\t\tif cnt > maxC {\n\t\t\t\tmaxV = i\n\t\t\t\tmaxC = cnt\n\t\t\t}\n\t\t}\n\t\ts.norm[maxV] += int16(toDistribute)\n\t\treturn nil\n\t}\n\n\tif total == 0 {\n\t\t// all of the symbols were low enough for the lowOne or lowThreshold\n\t\tfor i := uint32(0); toDistribute > 0; i = (i + 1) % (uint32(s.symbolLen)) {\n\t\t\tif s.norm[i] > 0 {\n\t\t\t\ttoDistribute--\n\t\t\t\ts.norm[i]++\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tvar (\n\t\tvStepLog = 62 - uint64(tableLog)\n\t\tmid      = uint64((1 << (vStepLog - 1)) - 1)\n\t\trStep    = (((1 << vStepLog) * uint64(toDistribute)) + mid) / uint64(total) // scale on remaining\n\t\ttmpTotal = mid\n\t)\n\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\tif s.norm[i] == notYetAssigned {\n\t\t\tvar (\n\t\t\t\tend    = tmpTotal + uint64(cnt)*rStep\n\t\t\t\tsStart = uint32(tmpTotal >> vStepLog)\n\t\t\t\tsEnd   = uint32(end >> vStepLog)\n\t\t\t\tweight = sEnd - sStart\n\t\t\t)\n\t\t\tif weight < 1 {\n\t\t\t\treturn errors.New(\"weight < 1\")\n\t\t\t}\n\t\t\ts.norm[i] = int16(weight)\n\t\t\ttmpTotal = end\n\t\t}\n\t}\n\treturn nil\n}\n\n// validateNorm validates the normalized histogram table.\nfunc (s *Scratch) validateNorm() (err error) {\n\tvar total int\n\tfor _, v := range s.norm[:s.symbolLen] {\n\t\tif v >= 0 {\n\t\t\ttotal += int(v)\n\t\t} else {\n\t\t\ttotal -= int(v)\n\t\t}\n\t}\n\tdefer func() {\n\t\tif err == nil {\n\t\t\treturn\n\t\t}\n\t\tfmt.Printf(\"selected TableLog: %d, Symbol length: %d\\n\", s.actualTableLog, s.symbolLen)\n\t\tfor i, v := range s.norm[:s.symbolLen] {\n\t\t\tfmt.Printf(\"%3d: %5d -> %4d \\n\", i, s.count[i], v)\n\t\t}\n\t}()\n\tif total != (1 << s.actualTableLog) {\n\t\treturn fmt.Errorf(\"warning: Total == %d != %d\", total, 1<<s.actualTableLog)\n\t}\n\tfor i, v := range s.count[s.symbolLen:] {\n\t\tif v != 0 {\n\t\t\treturn fmt.Errorf(\"warning: Found symbol out of range, %d after cut\", i)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/fse/decompress.go",
    "content": "package fse\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nconst (\n\ttablelogAbsoluteMax = 15\n)\n\n// Decompress a block of data.\n// You can provide a scratch buffer to avoid allocations.\n// If nil is provided a temporary one will be allocated.\n// It is possible, but by no way guaranteed that corrupt data will\n// return an error.\n// It is up to the caller to verify integrity of the returned data.\n// Use a predefined Scrach to set maximum acceptable output size.\nfunc Decompress(b []byte, s *Scratch) ([]byte, error) {\n\ts, err := s.prepare(b)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ts.Out = s.Out[:0]\n\terr = s.readNCount()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = s.buildDtable()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = s.decompress()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn s.Out, nil\n}\n\n// readNCount will read the symbol distribution so decoding tables can be constructed.\nfunc (s *Scratch) readNCount() error {\n\tvar (\n\t\tcharnum   uint16\n\t\tprevious0 bool\n\t\tb         = &s.br\n\t)\n\tiend := b.remain()\n\tif iend < 4 {\n\t\treturn errors.New(\"input too small\")\n\t}\n\tbitStream := b.Uint32()\n\tnbBits := uint((bitStream & 0xF) + minTablelog) // extract tableLog\n\tif nbBits > tablelogAbsoluteMax {\n\t\treturn errors.New(\"tableLog too large\")\n\t}\n\tbitStream >>= 4\n\tbitCount := uint(4)\n\n\ts.actualTableLog = uint8(nbBits)\n\tremaining := int32((1 << nbBits) + 1)\n\tthreshold := int32(1 << nbBits)\n\tgotTotal := int32(0)\n\tnbBits++\n\n\tfor remaining > 1 {\n\t\tif previous0 {\n\t\t\tn0 := charnum\n\t\t\tfor (bitStream & 0xFFFF) == 0xFFFF {\n\t\t\t\tn0 += 24\n\t\t\t\tif b.off < iend-5 {\n\t\t\t\t\tb.advance(2)\n\t\t\t\t\tbitStream = b.Uint32() >> bitCount\n\t\t\t\t} else {\n\t\t\t\t\tbitStream >>= 16\n\t\t\t\t\tbitCount += 16\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (bitStream & 3) == 3 {\n\t\t\t\tn0 += 3\n\t\t\t\tbitStream >>= 2\n\t\t\t\tbitCount += 2\n\t\t\t}\n\t\t\tn0 += uint16(bitStream & 3)\n\t\t\tbitCount += 2\n\t\t\tif n0 > maxSymbolValue {\n\t\t\t\treturn errors.New(\"maxSymbolValue too small\")\n\t\t\t}\n\t\t\tfor charnum < n0 {\n\t\t\t\ts.norm[charnum&0xff] = 0\n\t\t\t\tcharnum++\n\t\t\t}\n\n\t\t\tif b.off <= iend-7 || b.off+int(bitCount>>3) <= iend-4 {\n\t\t\t\tb.advance(bitCount >> 3)\n\t\t\t\tbitCount &= 7\n\t\t\t\tbitStream = b.Uint32() >> bitCount\n\t\t\t} else {\n\t\t\t\tbitStream >>= 2\n\t\t\t}\n\t\t}\n\n\t\tmax := (2*(threshold) - 1) - (remaining)\n\t\tvar count int32\n\n\t\tif (int32(bitStream) & (threshold - 1)) < max {\n\t\t\tcount = int32(bitStream) & (threshold - 1)\n\t\t\tbitCount += nbBits - 1\n\t\t} else {\n\t\t\tcount = int32(bitStream) & (2*threshold - 1)\n\t\t\tif count >= threshold {\n\t\t\t\tcount -= max\n\t\t\t}\n\t\t\tbitCount += nbBits\n\t\t}\n\n\t\tcount-- // extra accuracy\n\t\tif count < 0 {\n\t\t\t// -1 means +1\n\t\t\tremaining += count\n\t\t\tgotTotal -= count\n\t\t} else {\n\t\t\tremaining -= count\n\t\t\tgotTotal += count\n\t\t}\n\t\ts.norm[charnum&0xff] = int16(count)\n\t\tcharnum++\n\t\tprevious0 = count == 0\n\t\tfor remaining < threshold {\n\t\t\tnbBits--\n\t\t\tthreshold >>= 1\n\t\t}\n\t\tif b.off <= iend-7 || b.off+int(bitCount>>3) <= iend-4 {\n\t\t\tb.advance(bitCount >> 3)\n\t\t\tbitCount &= 7\n\t\t} else {\n\t\t\tbitCount -= (uint)(8 * (len(b.b) - 4 - b.off))\n\t\t\tb.off = len(b.b) - 4\n\t\t}\n\t\tbitStream = b.Uint32() >> (bitCount & 31)\n\t}\n\ts.symbolLen = charnum\n\n\tif s.symbolLen <= 1 {\n\t\treturn fmt.Errorf(\"symbolLen (%d) too small\", s.symbolLen)\n\t}\n\tif s.symbolLen > maxSymbolValue+1 {\n\t\treturn fmt.Errorf(\"symbolLen (%d) too big\", s.symbolLen)\n\t}\n\tif remaining != 1 {\n\t\treturn fmt.Errorf(\"corruption detected (remaining %d != 1)\", remaining)\n\t}\n\tif bitCount > 32 {\n\t\treturn fmt.Errorf(\"corruption detected (bitCount %d > 32)\", bitCount)\n\t}\n\tif gotTotal != 1<<s.actualTableLog {\n\t\treturn fmt.Errorf(\"corruption detected (total %d != %d)\", gotTotal, 1<<s.actualTableLog)\n\t}\n\tb.advance((bitCount + 7) >> 3)\n\treturn nil\n}\n\n// decSymbol contains information about a state entry,\n// Including the state offset base, the output symbol and\n// the number of bits to read for the low part of the destination state.\ntype decSymbol struct {\n\tnewState uint16\n\tsymbol   uint8\n\tnbBits   uint8\n}\n\n// allocDtable will allocate decoding tables if they are not big enough.\nfunc (s *Scratch) allocDtable() {\n\ttableSize := 1 << s.actualTableLog\n\tif cap(s.decTable) < tableSize {\n\t\ts.decTable = make([]decSymbol, tableSize)\n\t}\n\ts.decTable = s.decTable[:tableSize]\n\n\tif cap(s.ct.tableSymbol) < 256 {\n\t\ts.ct.tableSymbol = make([]byte, 256)\n\t}\n\ts.ct.tableSymbol = s.ct.tableSymbol[:256]\n\n\tif cap(s.ct.stateTable) < 256 {\n\t\ts.ct.stateTable = make([]uint16, 256)\n\t}\n\ts.ct.stateTable = s.ct.stateTable[:256]\n}\n\n// buildDtable will build the decoding table.\nfunc (s *Scratch) buildDtable() error {\n\ttableSize := uint32(1 << s.actualTableLog)\n\thighThreshold := tableSize - 1\n\ts.allocDtable()\n\tsymbolNext := s.ct.stateTable[:256]\n\n\t// Init, lay down lowprob symbols\n\ts.zeroBits = false\n\t{\n\t\tlargeLimit := int16(1 << (s.actualTableLog - 1))\n\t\tfor i, v := range s.norm[:s.symbolLen] {\n\t\t\tif v == -1 {\n\t\t\t\ts.decTable[highThreshold].symbol = uint8(i)\n\t\t\t\thighThreshold--\n\t\t\t\tsymbolNext[i] = 1\n\t\t\t} else {\n\t\t\t\tif v >= largeLimit {\n\t\t\t\t\ts.zeroBits = true\n\t\t\t\t}\n\t\t\t\tsymbolNext[i] = uint16(v)\n\t\t\t}\n\t\t}\n\t}\n\t// Spread symbols\n\t{\n\t\ttableMask := tableSize - 1\n\t\tstep := tableStep(tableSize)\n\t\tposition := uint32(0)\n\t\tfor ss, v := range s.norm[:s.symbolLen] {\n\t\t\tfor i := 0; i < int(v); i++ {\n\t\t\t\ts.decTable[position].symbol = uint8(ss)\n\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\tfor position > highThreshold {\n\t\t\t\t\t// lowprob area\n\t\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif position != 0 {\n\t\t\t// position must reach all cells once, otherwise normalizedCounter is incorrect\n\t\t\treturn errors.New(\"corrupted input (position != 0)\")\n\t\t}\n\t}\n\n\t// Build Decoding table\n\t{\n\t\ttableSize := uint16(1 << s.actualTableLog)\n\t\tfor u, v := range s.decTable {\n\t\t\tsymbol := v.symbol\n\t\t\tnextState := symbolNext[symbol]\n\t\t\tsymbolNext[symbol] = nextState + 1\n\t\t\tnBits := s.actualTableLog - byte(highBits(uint32(nextState)))\n\t\t\ts.decTable[u].nbBits = nBits\n\t\t\tnewState := (nextState << nBits) - tableSize\n\t\t\tif newState >= tableSize {\n\t\t\t\treturn fmt.Errorf(\"newState (%d) outside table size (%d)\", newState, tableSize)\n\t\t\t}\n\t\t\tif newState == uint16(u) && nBits == 0 {\n\t\t\t\t// Seems weird that this is possible with nbits > 0.\n\t\t\t\treturn fmt.Errorf(\"newState (%d) == oldState (%d) and no bits\", newState, u)\n\t\t\t}\n\t\t\ts.decTable[u].newState = newState\n\t\t}\n\t}\n\treturn nil\n}\n\n// decompress will decompress the bitstream.\n// If the buffer is over-read an error is returned.\nfunc (s *Scratch) decompress() error {\n\tbr := &s.bits\n\tif err := br.init(s.br.unread()); err != nil {\n\t\treturn err\n\t}\n\n\tvar s1, s2 decoder\n\t// Initialize and decode first state and symbol.\n\ts1.init(br, s.decTable, s.actualTableLog)\n\ts2.init(br, s.decTable, s.actualTableLog)\n\n\t// Use temp table to avoid bound checks/append penalty.\n\tvar tmp = s.ct.tableSymbol[:256]\n\tvar off uint8\n\n\t// Main part\n\tif !s.zeroBits {\n\t\tfor br.off >= 8 {\n\t\t\tbr.fillFast()\n\t\t\ttmp[off+0] = s1.nextFast()\n\t\t\ttmp[off+1] = s2.nextFast()\n\t\t\tbr.fillFast()\n\t\t\ttmp[off+2] = s1.nextFast()\n\t\t\ttmp[off+3] = s2.nextFast()\n\t\t\toff += 4\n\t\t\t// When off is 0, we have overflowed and should write.\n\t\t\tif off == 0 {\n\t\t\t\ts.Out = append(s.Out, tmp...)\n\t\t\t\tif len(s.Out) >= s.DecompressLimit {\n\t\t\t\t\treturn fmt.Errorf(\"output size (%d) > DecompressLimit (%d)\", len(s.Out), s.DecompressLimit)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor br.off >= 8 {\n\t\t\tbr.fillFast()\n\t\t\ttmp[off+0] = s1.next()\n\t\t\ttmp[off+1] = s2.next()\n\t\t\tbr.fillFast()\n\t\t\ttmp[off+2] = s1.next()\n\t\t\ttmp[off+3] = s2.next()\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\ts.Out = append(s.Out, tmp...)\n\t\t\t\t// When off is 0, we have overflowed and should write.\n\t\t\t\tif len(s.Out) >= s.DecompressLimit {\n\t\t\t\t\treturn fmt.Errorf(\"output size (%d) > DecompressLimit (%d)\", len(s.Out), s.DecompressLimit)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\ts.Out = append(s.Out, tmp[:off]...)\n\n\t// Final bits, a bit more expensive check\n\tfor {\n\t\tif s1.finished() {\n\t\t\ts.Out = append(s.Out, s1.final(), s2.final())\n\t\t\tbreak\n\t\t}\n\t\tbr.fill()\n\t\ts.Out = append(s.Out, s1.next())\n\t\tif s2.finished() {\n\t\t\ts.Out = append(s.Out, s2.final(), s1.final())\n\t\t\tbreak\n\t\t}\n\t\ts.Out = append(s.Out, s2.next())\n\t\tif len(s.Out) >= s.DecompressLimit {\n\t\t\treturn fmt.Errorf(\"output size (%d) > DecompressLimit (%d)\", len(s.Out), s.DecompressLimit)\n\t\t}\n\t}\n\treturn br.close()\n}\n\n// decoder keeps track of the current state and updates it from the bitstream.\ntype decoder struct {\n\tstate uint16\n\tbr    *bitReader\n\tdt    []decSymbol\n}\n\n// init will initialize the decoder and read the first state from the stream.\nfunc (d *decoder) init(in *bitReader, dt []decSymbol, tableLog uint8) {\n\td.dt = dt\n\td.br = in\n\td.state = in.getBits(tableLog)\n}\n\n// next returns the next symbol and sets the next state.\n// At least tablelog bits must be available in the bit reader.\nfunc (d *decoder) next() uint8 {\n\tn := &d.dt[d.state]\n\tlowBits := d.br.getBits(n.nbBits)\n\td.state = n.newState + lowBits\n\treturn n.symbol\n}\n\n// finished returns true if all bits have been read from the bitstream\n// and the next state would require reading bits from the input.\nfunc (d *decoder) finished() bool {\n\treturn d.br.finished() && d.dt[d.state].nbBits > 0\n}\n\n// final returns the current state symbol without decoding the next.\nfunc (d *decoder) final() uint8 {\n\treturn d.dt[d.state].symbol\n}\n\n// nextFast returns the next symbol and sets the next state.\n// This can only be used if no symbols are 0 bits.\n// At least tablelog bits must be available in the bit reader.\nfunc (d *decoder) nextFast() uint8 {\n\tn := d.dt[d.state]\n\tlowBits := d.br.getBitsFast(n.nbBits)\n\td.state = n.newState + lowBits\n\treturn n.symbol\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/fse/fse.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\n// Package fse provides Finite State Entropy encoding and decoding.\n//\n// Finite State Entropy encoding provides a fast near-optimal symbol encoding/decoding\n// for byte blocks as implemented in zstd.\n//\n// See https://github.com/klauspost/compress/tree/master/fse for more information.\npackage fse\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/bits\"\n)\n\nconst (\n\t/*!MEMORY_USAGE :\n\t *  Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)\n\t *  Increasing memory usage improves compression ratio\n\t *  Reduced memory usage can improve speed, due to cache effect\n\t *  Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */\n\tmaxMemoryUsage     = 14\n\tdefaultMemoryUsage = 13\n\n\tmaxTableLog     = maxMemoryUsage - 2\n\tmaxTablesize    = 1 << maxTableLog\n\tdefaultTablelog = defaultMemoryUsage - 2\n\tminTablelog     = 5\n\tmaxSymbolValue  = 255\n)\n\nvar (\n\t// ErrIncompressible is returned when input is judged to be too hard to compress.\n\tErrIncompressible = errors.New(\"input is not compressible\")\n\n\t// ErrUseRLE is returned from the compressor when the input is a single byte value repeated.\n\tErrUseRLE = errors.New(\"input is single value repeated\")\n)\n\n// Scratch provides temporary storage for compression and decompression.\ntype Scratch struct {\n\t// Private\n\tcount    [maxSymbolValue + 1]uint32\n\tnorm     [maxSymbolValue + 1]int16\n\tbr       byteReader\n\tbits     bitReader\n\tbw       bitWriter\n\tct       cTable      // Compression tables.\n\tdecTable []decSymbol // Decompression table.\n\tmaxCount int         // count of the most probable symbol\n\n\t// Per block parameters.\n\t// These can be used to override compression parameters of the block.\n\t// Do not touch, unless you know what you are doing.\n\n\t// Out is output buffer.\n\t// If the scratch is re-used before the caller is done processing the output,\n\t// set this field to nil.\n\t// Otherwise the output buffer will be re-used for next Compression/Decompression step\n\t// and allocation will be avoided.\n\tOut []byte\n\n\t// DecompressLimit limits the maximum decoded size acceptable.\n\t// If > 0 decompression will stop when approximately this many bytes\n\t// has been decoded.\n\t// If 0, maximum size will be 2GB.\n\tDecompressLimit int\n\n\tsymbolLen      uint16 // Length of active part of the symbol table.\n\tactualTableLog uint8  // Selected tablelog.\n\tzeroBits       bool   // no bits has prob > 50%.\n\tclearCount     bool   // clear count\n\n\t// MaxSymbolValue will override the maximum symbol value of the next block.\n\tMaxSymbolValue uint8\n\n\t// TableLog will attempt to override the tablelog for the next block.\n\tTableLog uint8\n}\n\n// Histogram allows to populate the histogram and skip that step in the compression,\n// It otherwise allows to inspect the histogram when compression is done.\n// To indicate that you have populated the histogram call HistogramFinished\n// with the value of the highest populated symbol, as well as the number of entries\n// in the most populated entry. These are accepted at face value.\n// The returned slice will always be length 256.\nfunc (s *Scratch) Histogram() []uint32 {\n\treturn s.count[:]\n}\n\n// HistogramFinished can be called to indicate that the histogram has been populated.\n// maxSymbol is the index of the highest set symbol of the next data segment.\n// maxCount is the number of entries in the most populated entry.\n// These are accepted at face value.\nfunc (s *Scratch) HistogramFinished(maxSymbol uint8, maxCount int) {\n\ts.maxCount = maxCount\n\ts.symbolLen = uint16(maxSymbol) + 1\n\ts.clearCount = maxCount != 0\n}\n\n// prepare will prepare and allocate scratch tables used for both compression and decompression.\nfunc (s *Scratch) prepare(in []byte) (*Scratch, error) {\n\tif s == nil {\n\t\ts = &Scratch{}\n\t}\n\tif s.MaxSymbolValue == 0 {\n\t\ts.MaxSymbolValue = 255\n\t}\n\tif s.TableLog == 0 {\n\t\ts.TableLog = defaultTablelog\n\t}\n\tif s.TableLog > maxTableLog {\n\t\treturn nil, fmt.Errorf(\"tableLog (%d) > maxTableLog (%d)\", s.TableLog, maxTableLog)\n\t}\n\tif cap(s.Out) == 0 {\n\t\ts.Out = make([]byte, 0, len(in))\n\t}\n\tif s.clearCount && s.maxCount == 0 {\n\t\tfor i := range s.count {\n\t\t\ts.count[i] = 0\n\t\t}\n\t\ts.clearCount = false\n\t}\n\ts.br.init(in)\n\tif s.DecompressLimit == 0 {\n\t\t// Max size 2GB.\n\t\ts.DecompressLimit = (2 << 30) - 1\n\t}\n\n\treturn s, nil\n}\n\n// tableStep returns the next table index.\nfunc tableStep(tableSize uint32) uint32 {\n\treturn (tableSize >> 1) + (tableSize >> 3) + 3\n}\n\nfunc highBits(val uint32) (n uint32) {\n\treturn uint32(bits.Len32(val) - 1)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/gen.sh",
    "content": "#!/bin/sh\n\ncd s2/cmd/_s2sx/ || exit 1\ngo generate .\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/.gitignore",
    "content": "/huff0-fuzz.zip\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/README.md",
    "content": "# Huff0 entropy compression\r\n\r\nThis package provides Huff0 encoding and decoding as used in zstd.\r\n            \r\n[Huff0](https://github.com/Cyan4973/FiniteStateEntropy#new-generation-entropy-coders), \r\na Huffman codec designed for modern CPU, featuring OoO (Out of Order) operations on multiple ALU \r\n(Arithmetic Logic Unit), achieving extremely fast compression and decompression speeds.\r\n\r\nThis can be used for compressing input with a lot of similar input values to the smallest number of bytes.\r\nThis does not perform any multi-byte [dictionary coding](https://en.wikipedia.org/wiki/Dictionary_coder) as LZ coders,\r\nbut it can be used as a secondary step to compressors (like Snappy) that does not do entropy encoding. \r\n\r\n* [Godoc documentation](https://godoc.org/github.com/klauspost/compress/huff0)\r\n\r\n## News\r\n\r\nThis is used as part of the [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and decompression package.\r\n\r\nThis ensures that most functionality is well tested.\r\n\r\n# Usage\r\n\r\nThis package provides a low level interface that allows to compress single independent blocks. \r\n\r\nEach block is separate, and there is no built in integrity checks. \r\nThis means that the caller should keep track of block sizes and also do checksums if needed.  \r\n\r\nCompressing a block is done via the [`Compress1X`](https://godoc.org/github.com/klauspost/compress/huff0#Compress1X) and \r\n[`Compress4X`](https://godoc.org/github.com/klauspost/compress/huff0#Compress4X) functions.\r\nYou must provide input and will receive the output and maybe an error.\r\n\r\nThese error values can be returned:\r\n\r\n| Error               | Description                                                                 |\r\n|---------------------|-----------------------------------------------------------------------------|\r\n| `<nil>`             | Everything ok, output is returned                                           |\r\n| `ErrIncompressible` | Returned when input is judged to be too hard to compress                    |\r\n| `ErrUseRLE`         | Returned from the compressor when the input is a single byte value repeated |\r\n| `ErrTooBig`         | Returned if the input block exceeds the maximum allowed size (128 Kib)      |\r\n| `(error)`           | An internal error occurred.                                                 |\r\n\r\n\r\nAs can be seen above some of there are errors that will be returned even under normal operation so it is important to handle these.\r\n\r\nTo reduce allocations you can provide a [`Scratch`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch) object \r\nthat can be re-used for successive calls. Both compression and decompression accepts a `Scratch` object, and the same \r\nobject can be used for both.   \r\n\r\nBe aware, that when re-using a `Scratch` object that the *output* buffer is also re-used, so if you are still using this\r\nyou must set the `Out` field in the scratch to nil. The same buffer is used for compression and decompression output.\r\n\r\nThe `Scratch` object will retain state that allows to re-use previous tables for encoding and decoding.  \r\n\r\n## Tables and re-use\r\n\r\nHuff0 allows for reusing tables from the previous block to save space if that is expected to give better/faster results. \r\n\r\nThe Scratch object allows you to set a [`ReusePolicy`](https://godoc.org/github.com/klauspost/compress/huff0#ReusePolicy) \r\nthat controls this behaviour. See the documentation for details. This can be altered between each block.\r\n\r\nDo however note that this information is *not* stored in the output block and it is up to the users of the package to\r\nrecord whether [`ReadTable`](https://godoc.org/github.com/klauspost/compress/huff0#ReadTable) should be called,\r\nbased on the boolean reported back from the CompressXX call. \r\n\r\nIf you want to store the table separate from the data, you can access them as `OutData` and `OutTable` on the \r\n[`Scratch`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch) object.\r\n\r\n## Decompressing\r\n\r\nThe first part of decoding is to initialize the decoding table through [`ReadTable`](https://godoc.org/github.com/klauspost/compress/huff0#ReadTable).\r\nThis will initialize the decoding tables. \r\nYou can supply the complete block to `ReadTable` and it will return the data part of the block \r\nwhich can be given to the decompressor. \r\n\r\nDecompressing is done by calling the [`Decompress1X`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch.Decompress1X) \r\nor [`Decompress4X`](https://godoc.org/github.com/klauspost/compress/huff0#Scratch.Decompress4X) function.\r\n\r\nFor concurrently decompressing content with a fixed table a stateless [`Decoder`](https://godoc.org/github.com/klauspost/compress/huff0#Decoder) can be requested which will remain correct as long as the scratch is unchanged. The capacity of the provided slice indicates the expected output size.\r\n\r\nYou must provide the output from the compression stage, at exactly the size you got back. If you receive an error back\r\nyour input was likely corrupted. \r\n\r\nIt is important to note that a successful decoding does *not* mean your output matches your original input. \r\nThere are no integrity checks, so relying on errors from the decompressor does not assure your data is valid.\r\n\r\n# Contributing\r\n\r\nContributions are always welcome. Be aware that adding public functions will require good justification and breaking \r\nchanges will likely not be accepted. If in doubt open an issue before writing the PR.\r\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/bitreader.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage huff0\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// bitReader reads a bitstream in reverse.\n// The last set bit indicates the start of the stream and is used\n// for aligning the input.\ntype bitReaderBytes struct {\n\tin       []byte\n\toff      uint // next byte to read is at in[off - 1]\n\tvalue    uint64\n\tbitsRead uint8\n}\n\n// init initializes and resets the bit reader.\nfunc (b *bitReaderBytes) init(in []byte) error {\n\tif len(in) < 1 {\n\t\treturn errors.New(\"corrupt stream: too short\")\n\t}\n\tb.in = in\n\tb.off = uint(len(in))\n\t// The highest bit of the last byte indicates where to start\n\tv := in[len(in)-1]\n\tif v == 0 {\n\t\treturn errors.New(\"corrupt stream, did not find end of stream\")\n\t}\n\tb.bitsRead = 64\n\tb.value = 0\n\tif len(in) >= 8 {\n\t\tb.fillFastStart()\n\t} else {\n\t\tb.fill()\n\t\tb.fill()\n\t}\n\tb.advance(8 - uint8(highBit32(uint32(v))))\n\treturn nil\n}\n\n// peekBitsFast requires that at least one bit is requested every time.\n// There are no checks if the buffer is filled.\nfunc (b *bitReaderBytes) peekByteFast() uint8 {\n\tgot := uint8(b.value >> 56)\n\treturn got\n}\n\nfunc (b *bitReaderBytes) advance(n uint8) {\n\tb.bitsRead += n\n\tb.value <<= n & 63\n}\n\n// fillFast() will make sure at least 32 bits are available.\n// There must be at least 4 bytes available.\nfunc (b *bitReaderBytes) fillFast() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\n\t// 2 bounds checks.\n\tv := b.in[b.off-4 : b.off]\n\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\tb.value |= uint64(low) << (b.bitsRead - 32)\n\tb.bitsRead -= 32\n\tb.off -= 4\n}\n\n// fillFastStart() assumes the bitReaderBytes is empty and there is at least 8 bytes to read.\nfunc (b *bitReaderBytes) fillFastStart() {\n\t// Do single re-slice to avoid bounds checks.\n\tb.value = binary.LittleEndian.Uint64(b.in[b.off-8:])\n\tb.bitsRead = 0\n\tb.off -= 8\n}\n\n// fill() will make sure at least 32 bits are available.\nfunc (b *bitReaderBytes) fill() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\tif b.off > 4 {\n\t\tv := b.in[b.off-4 : b.off]\n\t\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\t\tb.value |= uint64(low) << (b.bitsRead - 32)\n\t\tb.bitsRead -= 32\n\t\tb.off -= 4\n\t\treturn\n\t}\n\tfor b.off > 0 {\n\t\tb.value |= uint64(b.in[b.off-1]) << (b.bitsRead - 8)\n\t\tb.bitsRead -= 8\n\t\tb.off--\n\t}\n}\n\n// finished returns true if all bits have been read from the bit stream.\nfunc (b *bitReaderBytes) finished() bool {\n\treturn b.off == 0 && b.bitsRead >= 64\n}\n\nfunc (b *bitReaderBytes) remaining() uint {\n\treturn b.off*8 + uint(64-b.bitsRead)\n}\n\n// close the bitstream and returns an error if out-of-buffer reads occurred.\nfunc (b *bitReaderBytes) close() error {\n\t// Release reference.\n\tb.in = nil\n\tif b.remaining() > 0 {\n\t\treturn fmt.Errorf(\"corrupt input: %d bits remain on stream\", b.remaining())\n\t}\n\tif b.bitsRead > 64 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\n\n// bitReaderShifted reads a bitstream in reverse.\n// The last set bit indicates the start of the stream and is used\n// for aligning the input.\ntype bitReaderShifted struct {\n\tin       []byte\n\toff      uint // next byte to read is at in[off - 1]\n\tvalue    uint64\n\tbitsRead uint8\n}\n\n// init initializes and resets the bit reader.\nfunc (b *bitReaderShifted) init(in []byte) error {\n\tif len(in) < 1 {\n\t\treturn errors.New(\"corrupt stream: too short\")\n\t}\n\tb.in = in\n\tb.off = uint(len(in))\n\t// The highest bit of the last byte indicates where to start\n\tv := in[len(in)-1]\n\tif v == 0 {\n\t\treturn errors.New(\"corrupt stream, did not find end of stream\")\n\t}\n\tb.bitsRead = 64\n\tb.value = 0\n\tif len(in) >= 8 {\n\t\tb.fillFastStart()\n\t} else {\n\t\tb.fill()\n\t\tb.fill()\n\t}\n\tb.advance(8 - uint8(highBit32(uint32(v))))\n\treturn nil\n}\n\n// peekBitsFast requires that at least one bit is requested every time.\n// There are no checks if the buffer is filled.\nfunc (b *bitReaderShifted) peekBitsFast(n uint8) uint16 {\n\treturn uint16(b.value >> ((64 - n) & 63))\n}\n\nfunc (b *bitReaderShifted) advance(n uint8) {\n\tb.bitsRead += n\n\tb.value <<= n & 63\n}\n\n// fillFast() will make sure at least 32 bits are available.\n// There must be at least 4 bytes available.\nfunc (b *bitReaderShifted) fillFast() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\n\t// 2 bounds checks.\n\tv := b.in[b.off-4 : b.off]\n\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\tb.value |= uint64(low) << ((b.bitsRead - 32) & 63)\n\tb.bitsRead -= 32\n\tb.off -= 4\n}\n\n// fillFastStart() assumes the bitReaderShifted is empty and there is at least 8 bytes to read.\nfunc (b *bitReaderShifted) fillFastStart() {\n\t// Do single re-slice to avoid bounds checks.\n\tb.value = binary.LittleEndian.Uint64(b.in[b.off-8:])\n\tb.bitsRead = 0\n\tb.off -= 8\n}\n\n// fill() will make sure at least 32 bits are available.\nfunc (b *bitReaderShifted) fill() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\tif b.off > 4 {\n\t\tv := b.in[b.off-4 : b.off]\n\t\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\t\tb.value |= uint64(low) << ((b.bitsRead - 32) & 63)\n\t\tb.bitsRead -= 32\n\t\tb.off -= 4\n\t\treturn\n\t}\n\tfor b.off > 0 {\n\t\tb.value |= uint64(b.in[b.off-1]) << ((b.bitsRead - 8) & 63)\n\t\tb.bitsRead -= 8\n\t\tb.off--\n\t}\n}\n\nfunc (b *bitReaderShifted) remaining() uint {\n\treturn b.off*8 + uint(64-b.bitsRead)\n}\n\n// close the bitstream and returns an error if out-of-buffer reads occurred.\nfunc (b *bitReaderShifted) close() error {\n\t// Release reference.\n\tb.in = nil\n\tif b.remaining() > 0 {\n\t\treturn fmt.Errorf(\"corrupt input: %d bits remain on stream\", b.remaining())\n\t}\n\tif b.bitsRead > 64 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/bitwriter.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage huff0\n\n// bitWriter will write bits.\n// First bit will be LSB of the first byte of output.\ntype bitWriter struct {\n\tbitContainer uint64\n\tnBits        uint8\n\tout          []byte\n}\n\n// addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated.\n// It will not check if there is space for them, so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) addBits16Clean(value uint16, bits uint8) {\n\tb.bitContainer |= uint64(value) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// encSymbol will add up to 16 bits. value may not contain more set bits than indicated.\n// It will not check if there is space for them, so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) encSymbol(ct cTable, symbol byte) {\n\tenc := ct[symbol]\n\tb.bitContainer |= uint64(enc.val) << (b.nBits & 63)\n\tif false {\n\t\tif enc.nBits == 0 {\n\t\t\tpanic(\"nbits 0\")\n\t\t}\n\t}\n\tb.nBits += enc.nBits\n}\n\n// encTwoSymbols will add up to 32 bits. value may not contain more set bits than indicated.\n// It will not check if there is space for them, so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) encTwoSymbols(ct cTable, av, bv byte) {\n\tencA := ct[av]\n\tencB := ct[bv]\n\tsh := b.nBits & 63\n\tcombined := uint64(encA.val) | (uint64(encB.val) << (encA.nBits & 63))\n\tb.bitContainer |= combined << sh\n\tif false {\n\t\tif encA.nBits == 0 {\n\t\t\tpanic(\"nbitsA 0\")\n\t\t}\n\t\tif encB.nBits == 0 {\n\t\t\tpanic(\"nbitsB 0\")\n\t\t}\n\t}\n\tb.nBits += encA.nBits + encB.nBits\n}\n\n// encFourSymbols adds up to 32 bits from four symbols.\n// It will not check if there is space for them,\n// so the caller must ensure that b has been flushed recently.\nfunc (b *bitWriter) encFourSymbols(encA, encB, encC, encD cTableEntry) {\n\tbitsA := encA.nBits\n\tbitsB := bitsA + encB.nBits\n\tbitsC := bitsB + encC.nBits\n\tbitsD := bitsC + encD.nBits\n\tcombined := uint64(encA.val) |\n\t\t(uint64(encB.val) << (bitsA & 63)) |\n\t\t(uint64(encC.val) << (bitsB & 63)) |\n\t\t(uint64(encD.val) << (bitsC & 63))\n\tb.bitContainer |= combined << (b.nBits & 63)\n\tb.nBits += bitsD\n}\n\n// flush32 will flush out, so there are at least 32 bits available for writing.\nfunc (b *bitWriter) flush32() {\n\tif b.nBits < 32 {\n\t\treturn\n\t}\n\tb.out = append(b.out,\n\t\tbyte(b.bitContainer),\n\t\tbyte(b.bitContainer>>8),\n\t\tbyte(b.bitContainer>>16),\n\t\tbyte(b.bitContainer>>24))\n\tb.nBits -= 32\n\tb.bitContainer >>= 32\n}\n\n// flushAlign will flush remaining full bytes and align to next byte boundary.\nfunc (b *bitWriter) flushAlign() {\n\tnbBytes := (b.nBits + 7) >> 3\n\tfor i := uint8(0); i < nbBytes; i++ {\n\t\tb.out = append(b.out, byte(b.bitContainer>>(i*8)))\n\t}\n\tb.nBits = 0\n\tb.bitContainer = 0\n}\n\n// close will write the alignment bit and write the final byte(s)\n// to the output.\nfunc (b *bitWriter) close() {\n\t// End mark\n\tb.addBits16Clean(1, 1)\n\t// flush until next byte.\n\tb.flushAlign()\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/bytereader.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage huff0\n\n// byteReader provides a byte reader that reads\n// little endian values from a byte stream.\n// The input stream is manually advanced.\n// The reader performs no bounds checks.\ntype byteReader struct {\n\tb   []byte\n\toff int\n}\n\n// init will initialize the reader and set the input.\nfunc (b *byteReader) init(in []byte) {\n\tb.b = in\n\tb.off = 0\n}\n\n// Int32 returns a little endian int32 starting at current offset.\nfunc (b byteReader) Int32() int32 {\n\tv3 := int32(b.b[b.off+3])\n\tv2 := int32(b.b[b.off+2])\n\tv1 := int32(b.b[b.off+1])\n\tv0 := int32(b.b[b.off])\n\treturn (v3 << 24) | (v2 << 16) | (v1 << 8) | v0\n}\n\n// Uint32 returns a little endian uint32 starting at current offset.\nfunc (b byteReader) Uint32() uint32 {\n\tv3 := uint32(b.b[b.off+3])\n\tv2 := uint32(b.b[b.off+2])\n\tv1 := uint32(b.b[b.off+1])\n\tv0 := uint32(b.b[b.off])\n\treturn (v3 << 24) | (v2 << 16) | (v1 << 8) | v0\n}\n\n// remain will return the number of bytes remaining.\nfunc (b byteReader) remain() int {\n\treturn len(b.b) - b.off\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/compress.go",
    "content": "package huff0\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"runtime\"\n\t\"sync\"\n)\n\n// Compress1X will compress the input.\n// The output can be decoded using Decompress1X.\n// Supply a Scratch object. The scratch object contains state about re-use,\n// So when sharing across independent encodes, be sure to set the re-use policy.\nfunc Compress1X(in []byte, s *Scratch) (out []byte, reUsed bool, err error) {\n\ts, err = s.prepare(in)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\treturn compress(in, s, s.compress1X)\n}\n\n// Compress4X will compress the input. The input is split into 4 independent blocks\n// and compressed similar to Compress1X.\n// The output can be decoded using Decompress4X.\n// Supply a Scratch object. The scratch object contains state about re-use,\n// So when sharing across independent encodes, be sure to set the re-use policy.\nfunc Compress4X(in []byte, s *Scratch) (out []byte, reUsed bool, err error) {\n\ts, err = s.prepare(in)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tif false {\n\t\t// TODO: compress4Xp only slightly faster.\n\t\tconst parallelThreshold = 8 << 10\n\t\tif len(in) < parallelThreshold || runtime.GOMAXPROCS(0) == 1 {\n\t\t\treturn compress(in, s, s.compress4X)\n\t\t}\n\t\treturn compress(in, s, s.compress4Xp)\n\t}\n\treturn compress(in, s, s.compress4X)\n}\n\nfunc compress(in []byte, s *Scratch, compressor func(src []byte) ([]byte, error)) (out []byte, reUsed bool, err error) {\n\t// Nuke previous table if we cannot reuse anyway.\n\tif s.Reuse == ReusePolicyNone {\n\t\ts.prevTable = s.prevTable[:0]\n\t}\n\n\t// Create histogram, if none was provided.\n\tmaxCount := s.maxCount\n\tvar canReuse = false\n\tif maxCount == 0 {\n\t\tmaxCount, canReuse = s.countSimple(in)\n\t} else {\n\t\tcanReuse = s.canUseTable(s.prevTable)\n\t}\n\n\t// We want the output size to be less than this:\n\twantSize := len(in)\n\tif s.WantLogLess > 0 {\n\t\twantSize -= wantSize >> s.WantLogLess\n\t}\n\n\t// Reset for next run.\n\ts.clearCount = true\n\ts.maxCount = 0\n\tif maxCount >= len(in) {\n\t\tif maxCount > len(in) {\n\t\t\treturn nil, false, fmt.Errorf(\"maxCount (%d) > length (%d)\", maxCount, len(in))\n\t\t}\n\t\tif len(in) == 1 {\n\t\t\treturn nil, false, ErrIncompressible\n\t\t}\n\t\t// One symbol, use RLE\n\t\treturn nil, false, ErrUseRLE\n\t}\n\tif maxCount == 1 || maxCount < (len(in)>>7) {\n\t\t// Each symbol present maximum once or too well distributed.\n\t\treturn nil, false, ErrIncompressible\n\t}\n\tif s.Reuse == ReusePolicyMust && !canReuse {\n\t\t// We must reuse, but we can't.\n\t\treturn nil, false, ErrIncompressible\n\t}\n\tif (s.Reuse == ReusePolicyPrefer || s.Reuse == ReusePolicyMust) && canReuse {\n\t\tkeepTable := s.cTable\n\t\tkeepTL := s.actualTableLog\n\t\ts.cTable = s.prevTable\n\t\ts.actualTableLog = s.prevTableLog\n\t\ts.Out, err = compressor(in)\n\t\ts.cTable = keepTable\n\t\ts.actualTableLog = keepTL\n\t\tif err == nil && len(s.Out) < wantSize {\n\t\t\ts.OutData = s.Out\n\t\t\treturn s.Out, true, nil\n\t\t}\n\t\tif s.Reuse == ReusePolicyMust {\n\t\t\treturn nil, false, ErrIncompressible\n\t\t}\n\t\t// Do not attempt to re-use later.\n\t\ts.prevTable = s.prevTable[:0]\n\t}\n\n\t// Calculate new table.\n\terr = s.buildCTable()\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\n\tif false && !s.canUseTable(s.cTable) {\n\t\tpanic(\"invalid table generated\")\n\t}\n\n\tif s.Reuse == ReusePolicyAllow && canReuse {\n\t\thSize := len(s.Out)\n\t\toldSize := s.prevTable.estimateSize(s.count[:s.symbolLen])\n\t\tnewSize := s.cTable.estimateSize(s.count[:s.symbolLen])\n\t\tif oldSize <= hSize+newSize || hSize+12 >= wantSize {\n\t\t\t// Retain cTable even if we re-use.\n\t\t\tkeepTable := s.cTable\n\t\t\tkeepTL := s.actualTableLog\n\n\t\t\ts.cTable = s.prevTable\n\t\t\ts.actualTableLog = s.prevTableLog\n\t\t\ts.Out, err = compressor(in)\n\n\t\t\t// Restore ctable.\n\t\t\ts.cTable = keepTable\n\t\t\ts.actualTableLog = keepTL\n\t\t\tif err != nil {\n\t\t\t\treturn nil, false, err\n\t\t\t}\n\t\t\tif len(s.Out) >= wantSize {\n\t\t\t\treturn nil, false, ErrIncompressible\n\t\t\t}\n\t\t\ts.OutData = s.Out\n\t\t\treturn s.Out, true, nil\n\t\t}\n\t}\n\n\t// Use new table\n\terr = s.cTable.write(s)\n\tif err != nil {\n\t\ts.OutTable = nil\n\t\treturn nil, false, err\n\t}\n\ts.OutTable = s.Out\n\n\t// Compress using new table\n\ts.Out, err = compressor(in)\n\tif err != nil {\n\t\ts.OutTable = nil\n\t\treturn nil, false, err\n\t}\n\tif len(s.Out) >= wantSize {\n\t\ts.OutTable = nil\n\t\treturn nil, false, ErrIncompressible\n\t}\n\t// Move current table into previous.\n\ts.prevTable, s.prevTableLog, s.cTable = s.cTable, s.actualTableLog, s.prevTable[:0]\n\ts.OutData = s.Out[len(s.OutTable):]\n\treturn s.Out, false, nil\n}\n\n// EstimateSizes will estimate the data sizes\nfunc EstimateSizes(in []byte, s *Scratch) (tableSz, dataSz, reuseSz int, err error) {\n\ts, err = s.prepare(in)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\t// Create histogram, if none was provided.\n\ttableSz, dataSz, reuseSz = -1, -1, -1\n\tmaxCount := s.maxCount\n\tvar canReuse = false\n\tif maxCount == 0 {\n\t\tmaxCount, canReuse = s.countSimple(in)\n\t} else {\n\t\tcanReuse = s.canUseTable(s.prevTable)\n\t}\n\n\t// We want the output size to be less than this:\n\twantSize := len(in)\n\tif s.WantLogLess > 0 {\n\t\twantSize -= wantSize >> s.WantLogLess\n\t}\n\n\t// Reset for next run.\n\ts.clearCount = true\n\ts.maxCount = 0\n\tif maxCount >= len(in) {\n\t\tif maxCount > len(in) {\n\t\t\treturn 0, 0, 0, fmt.Errorf(\"maxCount (%d) > length (%d)\", maxCount, len(in))\n\t\t}\n\t\tif len(in) == 1 {\n\t\t\treturn 0, 0, 0, ErrIncompressible\n\t\t}\n\t\t// One symbol, use RLE\n\t\treturn 0, 0, 0, ErrUseRLE\n\t}\n\tif maxCount == 1 || maxCount < (len(in)>>7) {\n\t\t// Each symbol present maximum once or too well distributed.\n\t\treturn 0, 0, 0, ErrIncompressible\n\t}\n\n\t// Calculate new table.\n\terr = s.buildCTable()\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\n\tif false && !s.canUseTable(s.cTable) {\n\t\tpanic(\"invalid table generated\")\n\t}\n\n\ttableSz, err = s.cTable.estTableSize(s)\n\tif err != nil {\n\t\treturn 0, 0, 0, err\n\t}\n\tif canReuse {\n\t\treuseSz = s.prevTable.estimateSize(s.count[:s.symbolLen])\n\t}\n\tdataSz = s.cTable.estimateSize(s.count[:s.symbolLen])\n\n\t// Restore\n\treturn tableSz, dataSz, reuseSz, nil\n}\n\nfunc (s *Scratch) compress1X(src []byte) ([]byte, error) {\n\treturn s.compress1xDo(s.Out, src), nil\n}\n\nfunc (s *Scratch) compress1xDo(dst, src []byte) []byte {\n\tvar bw = bitWriter{out: dst}\n\n\t// N is length divisible by 4.\n\tn := len(src)\n\tn -= n & 3\n\tcTable := s.cTable[:256]\n\n\t// Encode last bytes.\n\tfor i := len(src) & 3; i > 0; i-- {\n\t\tbw.encSymbol(cTable, src[n+i-1])\n\t}\n\tn -= 4\n\tif s.actualTableLog <= 8 {\n\t\tfor ; n >= 0; n -= 4 {\n\t\t\ttmp := src[n : n+4]\n\t\t\t// tmp should be len 4\n\t\t\tbw.flush32()\n\t\t\tbw.encFourSymbols(cTable[tmp[3]], cTable[tmp[2]], cTable[tmp[1]], cTable[tmp[0]])\n\t\t}\n\t} else {\n\t\tfor ; n >= 0; n -= 4 {\n\t\t\ttmp := src[n : n+4]\n\t\t\t// tmp should be len 4\n\t\t\tbw.flush32()\n\t\t\tbw.encTwoSymbols(cTable, tmp[3], tmp[2])\n\t\t\tbw.flush32()\n\t\t\tbw.encTwoSymbols(cTable, tmp[1], tmp[0])\n\t\t}\n\t}\n\tbw.close()\n\treturn bw.out\n}\n\nvar sixZeros [6]byte\n\nfunc (s *Scratch) compress4X(src []byte) ([]byte, error) {\n\tif len(src) < 12 {\n\t\treturn nil, ErrIncompressible\n\t}\n\tsegmentSize := (len(src) + 3) / 4\n\n\t// Add placeholder for output length\n\toffsetIdx := len(s.Out)\n\ts.Out = append(s.Out, sixZeros[:]...)\n\n\tfor i := 0; i < 4; i++ {\n\t\ttoDo := src\n\t\tif len(toDo) > segmentSize {\n\t\t\ttoDo = toDo[:segmentSize]\n\t\t}\n\t\tsrc = src[len(toDo):]\n\n\t\tidx := len(s.Out)\n\t\ts.Out = s.compress1xDo(s.Out, toDo)\n\t\tif len(s.Out)-idx > math.MaxUint16 {\n\t\t\t// We cannot store the size in the jump table\n\t\t\treturn nil, ErrIncompressible\n\t\t}\n\t\t// Write compressed length as little endian before block.\n\t\tif i < 3 {\n\t\t\t// Last length is not written.\n\t\t\tlength := len(s.Out) - idx\n\t\t\ts.Out[i*2+offsetIdx] = byte(length)\n\t\t\ts.Out[i*2+offsetIdx+1] = byte(length >> 8)\n\t\t}\n\t}\n\n\treturn s.Out, nil\n}\n\n// compress4Xp will compress 4 streams using separate goroutines.\nfunc (s *Scratch) compress4Xp(src []byte) ([]byte, error) {\n\tif len(src) < 12 {\n\t\treturn nil, ErrIncompressible\n\t}\n\t// Add placeholder for output length\n\ts.Out = s.Out[:6]\n\n\tsegmentSize := (len(src) + 3) / 4\n\tvar wg sync.WaitGroup\n\twg.Add(4)\n\tfor i := 0; i < 4; i++ {\n\t\ttoDo := src\n\t\tif len(toDo) > segmentSize {\n\t\t\ttoDo = toDo[:segmentSize]\n\t\t}\n\t\tsrc = src[len(toDo):]\n\n\t\t// Separate goroutine for each block.\n\t\tgo func(i int) {\n\t\t\ts.tmpOut[i] = s.compress1xDo(s.tmpOut[i][:0], toDo)\n\t\t\twg.Done()\n\t\t}(i)\n\t}\n\twg.Wait()\n\tfor i := 0; i < 4; i++ {\n\t\to := s.tmpOut[i]\n\t\tif len(o) > math.MaxUint16 {\n\t\t\t// We cannot store the size in the jump table\n\t\t\treturn nil, ErrIncompressible\n\t\t}\n\t\t// Write compressed length as little endian before block.\n\t\tif i < 3 {\n\t\t\t// Last length is not written.\n\t\t\ts.Out[i*2] = byte(len(o))\n\t\t\ts.Out[i*2+1] = byte(len(o) >> 8)\n\t\t}\n\n\t\t// Write output.\n\t\ts.Out = append(s.Out, o...)\n\t}\n\treturn s.Out, nil\n}\n\n// countSimple will create a simple histogram in s.count.\n// Returns the biggest count.\n// Does not update s.clearCount.\nfunc (s *Scratch) countSimple(in []byte) (max int, reuse bool) {\n\treuse = true\n\tfor _, v := range in {\n\t\ts.count[v]++\n\t}\n\tm := uint32(0)\n\tif len(s.prevTable) > 0 {\n\t\tfor i, v := range s.count[:] {\n\t\t\tif v == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif v > m {\n\t\t\t\tm = v\n\t\t\t}\n\t\t\ts.symbolLen = uint16(i) + 1\n\t\t\tif i >= len(s.prevTable) {\n\t\t\t\treuse = false\n\t\t\t} else if s.prevTable[i].nBits == 0 {\n\t\t\t\treuse = false\n\t\t\t}\n\t\t}\n\t\treturn int(m), reuse\n\t}\n\tfor i, v := range s.count[:] {\n\t\tif v == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif v > m {\n\t\t\tm = v\n\t\t}\n\t\ts.symbolLen = uint16(i) + 1\n\t}\n\treturn int(m), false\n}\n\nfunc (s *Scratch) canUseTable(c cTable) bool {\n\tif len(c) < int(s.symbolLen) {\n\t\treturn false\n\t}\n\tfor i, v := range s.count[:s.symbolLen] {\n\t\tif v != 0 && c[i].nBits == 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n//lint:ignore U1000 used for debugging\nfunc (s *Scratch) validateTable(c cTable) bool {\n\tif len(c) < int(s.symbolLen) {\n\t\treturn false\n\t}\n\tfor i, v := range s.count[:s.symbolLen] {\n\t\tif v != 0 {\n\t\t\tif c[i].nBits == 0 {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif c[i].nBits > s.actualTableLog {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\n// minTableLog provides the minimum logSize to safely represent a distribution.\nfunc (s *Scratch) minTableLog() uint8 {\n\tminBitsSrc := highBit32(uint32(s.br.remain())) + 1\n\tminBitsSymbols := highBit32(uint32(s.symbolLen-1)) + 2\n\tif minBitsSrc < minBitsSymbols {\n\t\treturn uint8(minBitsSrc)\n\t}\n\treturn uint8(minBitsSymbols)\n}\n\n// optimalTableLog calculates and sets the optimal tableLog in s.actualTableLog\nfunc (s *Scratch) optimalTableLog() {\n\ttableLog := s.TableLog\n\tminBits := s.minTableLog()\n\tmaxBitsSrc := uint8(highBit32(uint32(s.br.remain()-1))) - 1\n\tif maxBitsSrc < tableLog {\n\t\t// Accuracy can be reduced\n\t\ttableLog = maxBitsSrc\n\t}\n\tif minBits > tableLog {\n\t\ttableLog = minBits\n\t}\n\t// Need a minimum to safely represent all symbol values\n\tif tableLog < minTablelog {\n\t\ttableLog = minTablelog\n\t}\n\tif tableLog > tableLogMax {\n\t\ttableLog = tableLogMax\n\t}\n\ts.actualTableLog = tableLog\n}\n\ntype cTableEntry struct {\n\tval   uint16\n\tnBits uint8\n\t// We have 8 bits extra\n}\n\nconst huffNodesMask = huffNodesLen - 1\n\nfunc (s *Scratch) buildCTable() error {\n\ts.optimalTableLog()\n\ts.huffSort()\n\tif cap(s.cTable) < maxSymbolValue+1 {\n\t\ts.cTable = make([]cTableEntry, s.symbolLen, maxSymbolValue+1)\n\t} else {\n\t\ts.cTable = s.cTable[:s.symbolLen]\n\t\tfor i := range s.cTable {\n\t\t\ts.cTable[i] = cTableEntry{}\n\t\t}\n\t}\n\n\tvar startNode = int16(s.symbolLen)\n\tnonNullRank := s.symbolLen - 1\n\n\tnodeNb := startNode\n\thuffNode := s.nodes[1 : huffNodesLen+1]\n\n\t// This overlays the slice above, but allows \"-1\" index lookups.\n\t// Different from reference implementation.\n\thuffNode0 := s.nodes[0 : huffNodesLen+1]\n\n\tfor huffNode[nonNullRank].count() == 0 {\n\t\tnonNullRank--\n\t}\n\n\tlowS := int16(nonNullRank)\n\tnodeRoot := nodeNb + lowS - 1\n\tlowN := nodeNb\n\thuffNode[nodeNb].setCount(huffNode[lowS].count() + huffNode[lowS-1].count())\n\thuffNode[lowS].setParent(nodeNb)\n\thuffNode[lowS-1].setParent(nodeNb)\n\tnodeNb++\n\tlowS -= 2\n\tfor n := nodeNb; n <= nodeRoot; n++ {\n\t\thuffNode[n].setCount(1 << 30)\n\t}\n\t// fake entry, strong barrier\n\thuffNode0[0].setCount(1 << 31)\n\n\t// create parents\n\tfor nodeNb <= nodeRoot {\n\t\tvar n1, n2 int16\n\t\tif huffNode0[lowS+1].count() < huffNode0[lowN+1].count() {\n\t\t\tn1 = lowS\n\t\t\tlowS--\n\t\t} else {\n\t\t\tn1 = lowN\n\t\t\tlowN++\n\t\t}\n\t\tif huffNode0[lowS+1].count() < huffNode0[lowN+1].count() {\n\t\t\tn2 = lowS\n\t\t\tlowS--\n\t\t} else {\n\t\t\tn2 = lowN\n\t\t\tlowN++\n\t\t}\n\n\t\thuffNode[nodeNb].setCount(huffNode0[n1+1].count() + huffNode0[n2+1].count())\n\t\thuffNode0[n1+1].setParent(nodeNb)\n\t\thuffNode0[n2+1].setParent(nodeNb)\n\t\tnodeNb++\n\t}\n\n\t// distribute weights (unlimited tree height)\n\thuffNode[nodeRoot].setNbBits(0)\n\tfor n := nodeRoot - 1; n >= startNode; n-- {\n\t\thuffNode[n].setNbBits(huffNode[huffNode[n].parent()].nbBits() + 1)\n\t}\n\tfor n := uint16(0); n <= nonNullRank; n++ {\n\t\thuffNode[n].setNbBits(huffNode[huffNode[n].parent()].nbBits() + 1)\n\t}\n\ts.actualTableLog = s.setMaxHeight(int(nonNullRank))\n\tmaxNbBits := s.actualTableLog\n\n\t// fill result into tree (val, nbBits)\n\tif maxNbBits > tableLogMax {\n\t\treturn fmt.Errorf(\"internal error: maxNbBits (%d) > tableLogMax (%d)\", maxNbBits, tableLogMax)\n\t}\n\tvar nbPerRank [tableLogMax + 1]uint16\n\tvar valPerRank [16]uint16\n\tfor _, v := range huffNode[:nonNullRank+1] {\n\t\tnbPerRank[v.nbBits()]++\n\t}\n\t// determine stating value per rank\n\t{\n\t\tmin := uint16(0)\n\t\tfor n := maxNbBits; n > 0; n-- {\n\t\t\t// get starting value within each rank\n\t\t\tvalPerRank[n] = min\n\t\t\tmin += nbPerRank[n]\n\t\t\tmin >>= 1\n\t\t}\n\t}\n\n\t// push nbBits per symbol, symbol order\n\tfor _, v := range huffNode[:nonNullRank+1] {\n\t\ts.cTable[v.symbol()].nBits = v.nbBits()\n\t}\n\n\t// assign value within rank, symbol order\n\tt := s.cTable[:s.symbolLen]\n\tfor n, val := range t {\n\t\tnbits := val.nBits & 15\n\t\tv := valPerRank[nbits]\n\t\tt[n].val = v\n\t\tvalPerRank[nbits] = v + 1\n\t}\n\n\treturn nil\n}\n\n// huffSort will sort symbols, decreasing order.\nfunc (s *Scratch) huffSort() {\n\ttype rankPos struct {\n\t\tbase    uint32\n\t\tcurrent uint32\n\t}\n\n\t// Clear nodes\n\tnodes := s.nodes[:huffNodesLen+1]\n\ts.nodes = nodes\n\tnodes = nodes[1 : huffNodesLen+1]\n\n\t// Sort into buckets based on length of symbol count.\n\tvar rank [32]rankPos\n\tfor _, v := range s.count[:s.symbolLen] {\n\t\tr := highBit32(v+1) & 31\n\t\trank[r].base++\n\t}\n\t// maxBitLength is log2(BlockSizeMax) + 1\n\tconst maxBitLength = 18 + 1\n\tfor n := maxBitLength; n > 0; n-- {\n\t\trank[n-1].base += rank[n].base\n\t}\n\tfor n := range rank[:maxBitLength] {\n\t\trank[n].current = rank[n].base\n\t}\n\tfor n, c := range s.count[:s.symbolLen] {\n\t\tr := (highBit32(c+1) + 1) & 31\n\t\tpos := rank[r].current\n\t\trank[r].current++\n\t\tprev := nodes[(pos-1)&huffNodesMask]\n\t\tfor pos > rank[r].base && c > prev.count() {\n\t\t\tnodes[pos&huffNodesMask] = prev\n\t\t\tpos--\n\t\t\tprev = nodes[(pos-1)&huffNodesMask]\n\t\t}\n\t\tnodes[pos&huffNodesMask] = makeNodeElt(c, byte(n))\n\t}\n}\n\nfunc (s *Scratch) setMaxHeight(lastNonNull int) uint8 {\n\tmaxNbBits := s.actualTableLog\n\thuffNode := s.nodes[1 : huffNodesLen+1]\n\t//huffNode = huffNode[: huffNodesLen]\n\n\tlargestBits := huffNode[lastNonNull].nbBits()\n\n\t// early exit : no elt > maxNbBits\n\tif largestBits <= maxNbBits {\n\t\treturn largestBits\n\t}\n\ttotalCost := int(0)\n\tbaseCost := int(1) << (largestBits - maxNbBits)\n\tn := uint32(lastNonNull)\n\n\tfor huffNode[n].nbBits() > maxNbBits {\n\t\ttotalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits()))\n\t\thuffNode[n].setNbBits(maxNbBits)\n\t\tn--\n\t}\n\t// n stops at huffNode[n].nbBits <= maxNbBits\n\n\tfor huffNode[n].nbBits() == maxNbBits {\n\t\tn--\n\t}\n\t// n end at index of smallest symbol using < maxNbBits\n\n\t// renorm totalCost\n\ttotalCost >>= largestBits - maxNbBits /* note : totalCost is necessarily a multiple of baseCost */\n\n\t// repay normalized cost\n\t{\n\t\tconst noSymbol = 0xF0F0F0F0\n\t\tvar rankLast [tableLogMax + 2]uint32\n\n\t\tfor i := range rankLast[:] {\n\t\t\trankLast[i] = noSymbol\n\t\t}\n\n\t\t// Get pos of last (smallest) symbol per rank\n\t\t{\n\t\t\tcurrentNbBits := maxNbBits\n\t\t\tfor pos := int(n); pos >= 0; pos-- {\n\t\t\t\tif huffNode[pos].nbBits() >= currentNbBits {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tcurrentNbBits = huffNode[pos].nbBits() // < maxNbBits\n\t\t\t\trankLast[maxNbBits-currentNbBits] = uint32(pos)\n\t\t\t}\n\t\t}\n\n\t\tfor totalCost > 0 {\n\t\t\tnBitsToDecrease := uint8(highBit32(uint32(totalCost))) + 1\n\n\t\t\tfor ; nBitsToDecrease > 1; nBitsToDecrease-- {\n\t\t\t\thighPos := rankLast[nBitsToDecrease]\n\t\t\t\tlowPos := rankLast[nBitsToDecrease-1]\n\t\t\t\tif highPos == noSymbol {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif lowPos == noSymbol {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\thighTotal := huffNode[highPos].count()\n\t\t\t\tlowTotal := 2 * huffNode[lowPos].count()\n\t\t\t\tif highTotal <= lowTotal {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\t// only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !)\n\t\t\t// HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary\n\t\t\t// FIXME: try to remove\n\t\t\tfor (nBitsToDecrease <= tableLogMax) && (rankLast[nBitsToDecrease] == noSymbol) {\n\t\t\t\tnBitsToDecrease++\n\t\t\t}\n\t\t\ttotalCost -= 1 << (nBitsToDecrease - 1)\n\t\t\tif rankLast[nBitsToDecrease-1] == noSymbol {\n\t\t\t\t// this rank is no longer empty\n\t\t\t\trankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]\n\t\t\t}\n\t\t\thuffNode[rankLast[nBitsToDecrease]].setNbBits(1 +\n\t\t\t\thuffNode[rankLast[nBitsToDecrease]].nbBits())\n\t\t\tif rankLast[nBitsToDecrease] == 0 {\n\t\t\t\t/* special case, reached largest symbol */\n\t\t\t\trankLast[nBitsToDecrease] = noSymbol\n\t\t\t} else {\n\t\t\t\trankLast[nBitsToDecrease]--\n\t\t\t\tif huffNode[rankLast[nBitsToDecrease]].nbBits() != maxNbBits-nBitsToDecrease {\n\t\t\t\t\trankLast[nBitsToDecrease] = noSymbol /* this rank is now empty */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor totalCost < 0 { /* Sometimes, cost correction overshoot */\n\t\t\tif rankLast[1] == noSymbol { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */\n\t\t\t\tfor huffNode[n].nbBits() == maxNbBits {\n\t\t\t\t\tn--\n\t\t\t\t}\n\t\t\t\thuffNode[n+1].setNbBits(huffNode[n+1].nbBits() - 1)\n\t\t\t\trankLast[1] = n + 1\n\t\t\t\ttotalCost++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\thuffNode[rankLast[1]+1].setNbBits(huffNode[rankLast[1]+1].nbBits() - 1)\n\t\t\trankLast[1]++\n\t\t\ttotalCost++\n\t\t}\n\t}\n\treturn maxNbBits\n}\n\n// A nodeElt is the fields\n//\n//\tcount  uint32\n//\tparent uint16\n//\tsymbol byte\n//\tnbBits uint8\n//\n// in some order, all squashed into an integer so that the compiler\n// always loads and stores entire nodeElts instead of separate fields.\ntype nodeElt uint64\n\nfunc makeNodeElt(count uint32, symbol byte) nodeElt {\n\treturn nodeElt(count) | nodeElt(symbol)<<48\n}\n\nfunc (e *nodeElt) count() uint32  { return uint32(*e) }\nfunc (e *nodeElt) parent() uint16 { return uint16(*e >> 32) }\nfunc (e *nodeElt) symbol() byte   { return byte(*e >> 48) }\nfunc (e *nodeElt) nbBits() uint8  { return uint8(*e >> 56) }\n\nfunc (e *nodeElt) setCount(c uint32) { *e = (*e)&0xffffffff00000000 | nodeElt(c) }\nfunc (e *nodeElt) setParent(p int16) { *e = (*e)&0xffff0000ffffffff | nodeElt(uint16(p))<<32 }\nfunc (e *nodeElt) setNbBits(n uint8) { *e = (*e)&0x00ffffffffffffff | nodeElt(n)<<56 }\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/decompress.go",
    "content": "package huff0\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\n\t\"github.com/klauspost/compress/fse\"\n)\n\ntype dTable struct {\n\tsingle []dEntrySingle\n}\n\n// single-symbols decoding\ntype dEntrySingle struct {\n\tentry uint16\n}\n\n// Uses special code for all tables that are < 8 bits.\nconst use8BitTables = true\n\n// ReadTable will read a table from the input.\n// The size of the input may be larger than the table definition.\n// Any content remaining after the table definition will be returned.\n// If no Scratch is provided a new one is allocated.\n// The returned Scratch can be used for encoding or decoding input using this table.\nfunc ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) {\n\ts, err = s.prepare(nil)\n\tif err != nil {\n\t\treturn s, nil, err\n\t}\n\tif len(in) <= 1 {\n\t\treturn s, nil, errors.New(\"input too small for table\")\n\t}\n\tiSize := in[0]\n\tin = in[1:]\n\tif iSize >= 128 {\n\t\t// Uncompressed\n\t\toSize := iSize - 127\n\t\tiSize = (oSize + 1) / 2\n\t\tif int(iSize) > len(in) {\n\t\t\treturn s, nil, errors.New(\"input too small for table\")\n\t\t}\n\t\tfor n := uint8(0); n < oSize; n += 2 {\n\t\t\tv := in[n/2]\n\t\t\ts.huffWeight[n] = v >> 4\n\t\t\ts.huffWeight[n+1] = v & 15\n\t\t}\n\t\ts.symbolLen = uint16(oSize)\n\t\tin = in[iSize:]\n\t} else {\n\t\tif len(in) < int(iSize) {\n\t\t\treturn s, nil, fmt.Errorf(\"input too small for table, want %d bytes, have %d\", iSize, len(in))\n\t\t}\n\t\t// FSE compressed weights\n\t\ts.fse.DecompressLimit = 255\n\t\thw := s.huffWeight[:]\n\t\ts.fse.Out = hw\n\t\tb, err := fse.Decompress(in[:iSize], s.fse)\n\t\ts.fse.Out = nil\n\t\tif err != nil {\n\t\t\treturn s, nil, fmt.Errorf(\"fse decompress returned: %w\", err)\n\t\t}\n\t\tif len(b) > 255 {\n\t\t\treturn s, nil, errors.New(\"corrupt input: output table too large\")\n\t\t}\n\t\ts.symbolLen = uint16(len(b))\n\t\tin = in[iSize:]\n\t}\n\n\t// collect weight stats\n\tvar rankStats [16]uint32\n\tweightTotal := uint32(0)\n\tfor _, v := range s.huffWeight[:s.symbolLen] {\n\t\tif v > tableLogMax {\n\t\t\treturn s, nil, errors.New(\"corrupt input: weight too large\")\n\t\t}\n\t\tv2 := v & 15\n\t\trankStats[v2]++\n\t\t// (1 << (v2-1)) is slower since the compiler cannot prove that v2 isn't 0.\n\t\tweightTotal += (1 << v2) >> 1\n\t}\n\tif weightTotal == 0 {\n\t\treturn s, nil, errors.New(\"corrupt input: weights zero\")\n\t}\n\n\t// get last non-null symbol weight (implied, total must be 2^n)\n\t{\n\t\ttableLog := highBit32(weightTotal) + 1\n\t\tif tableLog > tableLogMax {\n\t\t\treturn s, nil, errors.New(\"corrupt input: tableLog too big\")\n\t\t}\n\t\ts.actualTableLog = uint8(tableLog)\n\t\t// determine last weight\n\t\t{\n\t\t\ttotal := uint32(1) << tableLog\n\t\t\trest := total - weightTotal\n\t\t\tverif := uint32(1) << highBit32(rest)\n\t\t\tlastWeight := highBit32(rest) + 1\n\t\t\tif verif != rest {\n\t\t\t\t// last value must be a clean power of 2\n\t\t\t\treturn s, nil, errors.New(\"corrupt input: last value not power of two\")\n\t\t\t}\n\t\t\ts.huffWeight[s.symbolLen] = uint8(lastWeight)\n\t\t\ts.symbolLen++\n\t\t\trankStats[lastWeight]++\n\t\t}\n\t}\n\n\tif (rankStats[1] < 2) || (rankStats[1]&1 != 0) {\n\t\t// by construction : at least 2 elts of rank 1, must be even\n\t\treturn s, nil, errors.New(\"corrupt input: min elt size, even check failed \")\n\t}\n\n\t// TODO: Choose between single/double symbol decoding\n\n\t// Calculate starting value for each rank\n\t{\n\t\tvar nextRankStart uint32\n\t\tfor n := uint8(1); n < s.actualTableLog+1; n++ {\n\t\t\tcurrent := nextRankStart\n\t\t\tnextRankStart += rankStats[n] << (n - 1)\n\t\t\trankStats[n] = current\n\t\t}\n\t}\n\n\t// fill DTable (always full size)\n\ttSize := 1 << tableLogMax\n\tif len(s.dt.single) != tSize {\n\t\ts.dt.single = make([]dEntrySingle, tSize)\n\t}\n\tcTable := s.prevTable\n\tif cap(cTable) < maxSymbolValue+1 {\n\t\tcTable = make([]cTableEntry, 0, maxSymbolValue+1)\n\t}\n\tcTable = cTable[:maxSymbolValue+1]\n\ts.prevTable = cTable[:s.symbolLen]\n\ts.prevTableLog = s.actualTableLog\n\n\tfor n, w := range s.huffWeight[:s.symbolLen] {\n\t\tif w == 0 {\n\t\t\tcTable[n] = cTableEntry{\n\t\t\t\tval:   0,\n\t\t\t\tnBits: 0,\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tlength := (uint32(1) << w) >> 1\n\t\td := dEntrySingle{\n\t\t\tentry: uint16(s.actualTableLog+1-w) | (uint16(n) << 8),\n\t\t}\n\n\t\trank := &rankStats[w]\n\t\tcTable[n] = cTableEntry{\n\t\t\tval:   uint16(*rank >> (w - 1)),\n\t\t\tnBits: uint8(d.entry),\n\t\t}\n\n\t\tsingle := s.dt.single[*rank : *rank+length]\n\t\tfor i := range single {\n\t\t\tsingle[i] = d\n\t\t}\n\t\t*rank += length\n\t}\n\n\treturn s, in, nil\n}\n\n// Decompress1X will decompress a 1X encoded stream.\n// The length of the supplied input must match the end of a block exactly.\n// Before this is called, the table must be initialized with ReadTable unless\n// the encoder re-used the table.\n// deprecated: Use the stateless Decoder() to get a concurrent version.\nfunc (s *Scratch) Decompress1X(in []byte) (out []byte, err error) {\n\tif cap(s.Out) < s.MaxDecodedSize {\n\t\ts.Out = make([]byte, s.MaxDecodedSize)\n\t}\n\ts.Out = s.Out[:0:s.MaxDecodedSize]\n\ts.Out, err = s.Decoder().Decompress1X(s.Out, in)\n\treturn s.Out, err\n}\n\n// Decompress4X will decompress a 4X encoded stream.\n// Before this is called, the table must be initialized with ReadTable unless\n// the encoder re-used the table.\n// The length of the supplied input must match the end of a block exactly.\n// The destination size of the uncompressed data must be known and provided.\n// deprecated: Use the stateless Decoder() to get a concurrent version.\nfunc (s *Scratch) Decompress4X(in []byte, dstSize int) (out []byte, err error) {\n\tif dstSize > s.MaxDecodedSize {\n\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t}\n\tif cap(s.Out) < dstSize {\n\t\ts.Out = make([]byte, s.MaxDecodedSize)\n\t}\n\ts.Out = s.Out[:0:dstSize]\n\ts.Out, err = s.Decoder().Decompress4X(s.Out, in)\n\treturn s.Out, err\n}\n\n// Decoder will return a stateless decoder that can be used by multiple\n// decompressors concurrently.\n// Before this is called, the table must be initialized with ReadTable.\n// The Decoder is still linked to the scratch buffer so that cannot be reused.\n// However, it is safe to discard the scratch.\nfunc (s *Scratch) Decoder() *Decoder {\n\treturn &Decoder{\n\t\tdt:             s.dt,\n\t\tactualTableLog: s.actualTableLog,\n\t\tbufs:           &s.decPool,\n\t}\n}\n\n// Decoder provides stateless decoding.\ntype Decoder struct {\n\tdt             dTable\n\tactualTableLog uint8\n\tbufs           *sync.Pool\n}\n\nfunc (d *Decoder) buffer() *[4][256]byte {\n\tbuf, ok := d.bufs.Get().(*[4][256]byte)\n\tif ok {\n\t\treturn buf\n\t}\n\treturn &[4][256]byte{}\n}\n\n// decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8.\n// The cap of the output buffer will be the maximum decompressed size.\n// The length of the supplied input must match the end of a block exactly.\nfunc (d *Decoder) decompress1X8Bit(dst, src []byte) ([]byte, error) {\n\tif d.actualTableLog == 8 {\n\t\treturn d.decompress1X8BitExactly(dst, src)\n\t}\n\tvar br bitReaderBytes\n\terr := br.init(src)\n\tif err != nil {\n\t\treturn dst, err\n\t}\n\tmaxDecodedSize := cap(dst)\n\tdst = dst[:0]\n\n\t// Avoid bounds check by always having full sized table.\n\tdt := d.dt.single[:256]\n\n\t// Use temp table to avoid bound checks/append penalty.\n\tbufs := d.buffer()\n\tbuf := &bufs[0]\n\tvar off uint8\n\n\tswitch d.actualTableLog {\n\tcase 8:\n\t\tconst shift = 0\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\tbr.close()\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tcase 7:\n\t\tconst shift = 8 - 7\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\tbr.close()\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tcase 6:\n\t\tconst shift = 8 - 6\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\tbr.close()\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tcase 5:\n\t\tconst shift = 8 - 5\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\tbr.close()\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tcase 4:\n\t\tconst shift = 8 - 4\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\tbr.close()\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tcase 3:\n\t\tconst shift = 8 - 3\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\tbr.close()\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tcase 2:\n\t\tconst shift = 8 - 2\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\tbr.close()\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tcase 1:\n\t\tconst shift = 8 - 1\n\t\tfor br.off >= 4 {\n\t\t\tbr.fillFast()\n\t\t\tv := dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\t\tv = dt[uint8(br.value>>(56+shift))]\n\t\t\tbr.advance(uint8(v.entry))\n\t\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\t\toff += 4\n\t\t\tif off == 0 {\n\t\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\t\td.bufs.Put(bufs)\n\t\t\t\t\tbr.close()\n\t\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t\t}\n\t\t\t\tdst = append(dst, buf[:]...)\n\t\t\t}\n\t\t}\n\tdefault:\n\t\td.bufs.Put(bufs)\n\t\treturn nil, fmt.Errorf(\"invalid tablelog: %d\", d.actualTableLog)\n\t}\n\n\tif len(dst)+int(off) > maxDecodedSize {\n\t\td.bufs.Put(bufs)\n\t\tbr.close()\n\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t}\n\tdst = append(dst, buf[:off]...)\n\n\t// br < 4, so uint8 is fine\n\tbitsLeft := int8(uint8(br.off)*8 + (64 - br.bitsRead))\n\tshift := (8 - d.actualTableLog) & 7\n\n\tfor bitsLeft > 0 {\n\t\tif br.bitsRead >= 64-8 {\n\t\t\tfor br.off > 0 {\n\t\t\t\tbr.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)\n\t\t\t\tbr.bitsRead -= 8\n\t\t\t\tbr.off--\n\t\t\t}\n\t\t}\n\t\tif len(dst) >= maxDecodedSize {\n\t\t\tbr.close()\n\t\t\td.bufs.Put(bufs)\n\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t}\n\t\tv := dt[br.peekByteFast()>>shift]\n\t\tnBits := uint8(v.entry)\n\t\tbr.advance(nBits)\n\t\tbitsLeft -= int8(nBits)\n\t\tdst = append(dst, uint8(v.entry>>8))\n\t}\n\td.bufs.Put(bufs)\n\treturn dst, br.close()\n}\n\n// decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8.\n// The cap of the output buffer will be the maximum decompressed size.\n// The length of the supplied input must match the end of a block exactly.\nfunc (d *Decoder) decompress1X8BitExactly(dst, src []byte) ([]byte, error) {\n\tvar br bitReaderBytes\n\terr := br.init(src)\n\tif err != nil {\n\t\treturn dst, err\n\t}\n\tmaxDecodedSize := cap(dst)\n\tdst = dst[:0]\n\n\t// Avoid bounds check by always having full sized table.\n\tdt := d.dt.single[:256]\n\n\t// Use temp table to avoid bound checks/append penalty.\n\tbufs := d.buffer()\n\tbuf := &bufs[0]\n\tvar off uint8\n\n\tconst shift = 56\n\n\t//fmt.Printf(\"mask: %b, tl:%d\\n\", mask, d.actualTableLog)\n\tfor br.off >= 4 {\n\t\tbr.fillFast()\n\t\tv := dt[uint8(br.value>>shift)]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\tv = dt[uint8(br.value>>shift)]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\tv = dt[uint8(br.value>>shift)]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\tv = dt[uint8(br.value>>shift)]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\toff += 4\n\t\tif off == 0 {\n\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\td.bufs.Put(bufs)\n\t\t\t\tbr.close()\n\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t}\n\t\t\tdst = append(dst, buf[:]...)\n\t\t}\n\t}\n\n\tif len(dst)+int(off) > maxDecodedSize {\n\t\td.bufs.Put(bufs)\n\t\tbr.close()\n\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t}\n\tdst = append(dst, buf[:off]...)\n\n\t// br < 4, so uint8 is fine\n\tbitsLeft := int8(uint8(br.off)*8 + (64 - br.bitsRead))\n\tfor bitsLeft > 0 {\n\t\tif br.bitsRead >= 64-8 {\n\t\t\tfor br.off > 0 {\n\t\t\t\tbr.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)\n\t\t\t\tbr.bitsRead -= 8\n\t\t\t\tbr.off--\n\t\t\t}\n\t\t}\n\t\tif len(dst) >= maxDecodedSize {\n\t\t\td.bufs.Put(bufs)\n\t\t\tbr.close()\n\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t}\n\t\tv := dt[br.peekByteFast()]\n\t\tnBits := uint8(v.entry)\n\t\tbr.advance(nBits)\n\t\tbitsLeft -= int8(nBits)\n\t\tdst = append(dst, uint8(v.entry>>8))\n\t}\n\td.bufs.Put(bufs)\n\treturn dst, br.close()\n}\n\n// Decompress4X will decompress a 4X encoded stream.\n// The length of the supplied input must match the end of a block exactly.\n// The *capacity* of the dst slice must match the destination size of\n// the uncompressed data exactly.\nfunc (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) {\n\tif d.actualTableLog == 8 {\n\t\treturn d.decompress4X8bitExactly(dst, src)\n\t}\n\n\tvar br [4]bitReaderBytes\n\tstart := 6\n\tfor i := 0; i < 3; i++ {\n\t\tlength := int(src[i*2]) | (int(src[i*2+1]) << 8)\n\t\tif start+length >= len(src) {\n\t\t\treturn nil, errors.New(\"truncated input (or invalid offset)\")\n\t\t}\n\t\terr := br[i].init(src[start : start+length])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstart += length\n\t}\n\terr := br[3].init(src[start:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// destination, offset to match first output\n\tdstSize := cap(dst)\n\tdst = dst[:dstSize]\n\tout := dst\n\tdstEvery := (dstSize + 3) / 4\n\n\tshift := (56 + (8 - d.actualTableLog)) & 63\n\n\tconst tlSize = 1 << 8\n\tsingle := d.dt.single[:tlSize]\n\n\t// Use temp table to avoid bound checks/append penalty.\n\tbuf := d.buffer()\n\tvar off uint8\n\tvar decoded int\n\n\t// Decode 4 values from each decoder/loop.\n\tconst bufoff = 256\n\tfor {\n\t\tif br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {\n\t\t\tbreak\n\t\t}\n\n\t\t{\n\t\t\t// Interleave 2 decodes.\n\t\t\tconst stream = 0\n\t\t\tconst stream2 = 1\n\t\t\tbr1 := &br[stream]\n\t\t\tbr2 := &br[stream2]\n\t\t\tbr1.fillFast()\n\t\t\tbr2.fillFast()\n\n\t\t\tv := single[uint8(br1.value>>shift)].entry\n\t\t\tv2 := single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off] = uint8(v >> 8)\n\t\t\tbuf[stream2][off] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+1] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+1] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+2] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+2] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+3] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+3] = uint8(v2 >> 8)\n\t\t}\n\n\t\t{\n\t\t\tconst stream = 2\n\t\t\tconst stream2 = 3\n\t\t\tbr1 := &br[stream]\n\t\t\tbr2 := &br[stream2]\n\t\t\tbr1.fillFast()\n\t\t\tbr2.fillFast()\n\n\t\t\tv := single[uint8(br1.value>>shift)].entry\n\t\t\tv2 := single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off] = uint8(v >> 8)\n\t\t\tbuf[stream2][off] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+1] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+1] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+2] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+2] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+3] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+3] = uint8(v2 >> 8)\n\t\t}\n\n\t\toff += 4\n\n\t\tif off == 0 {\n\t\t\tif bufoff > dstEvery {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 1\")\n\t\t\t}\n\t\t\t// There must at least be 3 buffers left.\n\t\t\tif len(out)-bufoff < dstEvery*3 {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 2\")\n\t\t\t}\n\t\t\t//copy(out, buf[0][:])\n\t\t\t//copy(out[dstEvery:], buf[1][:])\n\t\t\t//copy(out[dstEvery*2:], buf[2][:])\n\t\t\t*(*[bufoff]byte)(out) = buf[0]\n\t\t\t*(*[bufoff]byte)(out[dstEvery:]) = buf[1]\n\t\t\t*(*[bufoff]byte)(out[dstEvery*2:]) = buf[2]\n\t\t\t*(*[bufoff]byte)(out[dstEvery*3:]) = buf[3]\n\t\t\tout = out[bufoff:]\n\t\t\tdecoded += bufoff * 4\n\t\t}\n\t}\n\tif off > 0 {\n\t\tioff := int(off)\n\t\tif len(out) < dstEvery*3+ioff {\n\t\t\td.bufs.Put(buf)\n\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 3\")\n\t\t}\n\t\tcopy(out, buf[0][:off])\n\t\tcopy(out[dstEvery:], buf[1][:off])\n\t\tcopy(out[dstEvery*2:], buf[2][:off])\n\t\tcopy(out[dstEvery*3:], buf[3][:off])\n\t\tdecoded += int(off) * 4\n\t\tout = out[off:]\n\t}\n\n\t// Decode remaining.\n\t// Decode remaining.\n\tremainBytes := dstEvery - (decoded / 4)\n\tfor i := range br {\n\t\toffset := dstEvery * i\n\t\tendsAt := offset + remainBytes\n\t\tif endsAt > len(out) {\n\t\t\tendsAt = len(out)\n\t\t}\n\t\tbr := &br[i]\n\t\tbitsLeft := br.remaining()\n\t\tfor bitsLeft > 0 {\n\t\t\tif br.finished() {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tif br.bitsRead >= 56 {\n\t\t\t\tif br.off >= 4 {\n\t\t\t\t\tv := br.in[br.off-4:]\n\t\t\t\t\tv = v[:4]\n\t\t\t\t\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\t\t\t\t\tbr.value |= uint64(low) << (br.bitsRead - 32)\n\t\t\t\t\tbr.bitsRead -= 32\n\t\t\t\t\tbr.off -= 4\n\t\t\t\t} else {\n\t\t\t\t\tfor br.off > 0 {\n\t\t\t\t\t\tbr.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)\n\t\t\t\t\t\tbr.bitsRead -= 8\n\t\t\t\t\t\tbr.off--\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// end inline...\n\t\t\tif offset >= endsAt {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 4\")\n\t\t\t}\n\n\t\t\t// Read value and increment offset.\n\t\t\tv := single[uint8(br.value>>shift)].entry\n\t\t\tnBits := uint8(v)\n\t\t\tbr.advance(nBits)\n\t\t\tbitsLeft -= uint(nBits)\n\t\t\tout[offset] = uint8(v >> 8)\n\t\t\toffset++\n\t\t}\n\t\tif offset != endsAt {\n\t\t\td.bufs.Put(buf)\n\t\t\treturn nil, fmt.Errorf(\"corruption detected: short output block %d, end %d != %d\", i, offset, endsAt)\n\t\t}\n\t\tdecoded += offset - dstEvery*i\n\t\terr = br.close()\n\t\tif err != nil {\n\t\t\td.bufs.Put(buf)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\td.bufs.Put(buf)\n\tif dstSize != decoded {\n\t\treturn nil, errors.New(\"corruption detected: short output block\")\n\t}\n\treturn dst, nil\n}\n\n// Decompress4X will decompress a 4X encoded stream.\n// The length of the supplied input must match the end of a block exactly.\n// The *capacity* of the dst slice must match the destination size of\n// the uncompressed data exactly.\nfunc (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) {\n\tvar br [4]bitReaderBytes\n\tstart := 6\n\tfor i := 0; i < 3; i++ {\n\t\tlength := int(src[i*2]) | (int(src[i*2+1]) << 8)\n\t\tif start+length >= len(src) {\n\t\t\treturn nil, errors.New(\"truncated input (or invalid offset)\")\n\t\t}\n\t\terr := br[i].init(src[start : start+length])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstart += length\n\t}\n\terr := br[3].init(src[start:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// destination, offset to match first output\n\tdstSize := cap(dst)\n\tdst = dst[:dstSize]\n\tout := dst\n\tdstEvery := (dstSize + 3) / 4\n\n\tconst shift = 56\n\tconst tlSize = 1 << 8\n\tsingle := d.dt.single[:tlSize]\n\n\t// Use temp table to avoid bound checks/append penalty.\n\tbuf := d.buffer()\n\tvar off uint8\n\tvar decoded int\n\n\t// Decode 4 values from each decoder/loop.\n\tconst bufoff = 256\n\tfor {\n\t\tif br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {\n\t\t\tbreak\n\t\t}\n\n\t\t{\n\t\t\t// Interleave 2 decodes.\n\t\t\tconst stream = 0\n\t\t\tconst stream2 = 1\n\t\t\tbr1 := &br[stream]\n\t\t\tbr2 := &br[stream2]\n\t\t\tbr1.fillFast()\n\t\t\tbr2.fillFast()\n\n\t\t\tv := single[uint8(br1.value>>shift)].entry\n\t\t\tv2 := single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off] = uint8(v >> 8)\n\t\t\tbuf[stream2][off] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+1] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+1] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+2] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+2] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+3] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+3] = uint8(v2 >> 8)\n\t\t}\n\n\t\t{\n\t\t\tconst stream = 2\n\t\t\tconst stream2 = 3\n\t\t\tbr1 := &br[stream]\n\t\t\tbr2 := &br[stream2]\n\t\t\tbr1.fillFast()\n\t\t\tbr2.fillFast()\n\n\t\t\tv := single[uint8(br1.value>>shift)].entry\n\t\t\tv2 := single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off] = uint8(v >> 8)\n\t\t\tbuf[stream2][off] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+1] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+1] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+2] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+2] = uint8(v2 >> 8)\n\n\t\t\tv = single[uint8(br1.value>>shift)].entry\n\t\t\tv2 = single[uint8(br2.value>>shift)].entry\n\t\t\tbr1.bitsRead += uint8(v)\n\t\t\tbr1.value <<= v & 63\n\t\t\tbr2.bitsRead += uint8(v2)\n\t\t\tbr2.value <<= v2 & 63\n\t\t\tbuf[stream][off+3] = uint8(v >> 8)\n\t\t\tbuf[stream2][off+3] = uint8(v2 >> 8)\n\t\t}\n\n\t\toff += 4\n\n\t\tif off == 0 {\n\t\t\tif bufoff > dstEvery {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 1\")\n\t\t\t}\n\t\t\t// There must at least be 3 buffers left.\n\t\t\tif len(out)-bufoff < dstEvery*3 {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 2\")\n\t\t\t}\n\n\t\t\t//copy(out, buf[0][:])\n\t\t\t//copy(out[dstEvery:], buf[1][:])\n\t\t\t//copy(out[dstEvery*2:], buf[2][:])\n\t\t\t// copy(out[dstEvery*3:], buf[3][:])\n\t\t\t*(*[bufoff]byte)(out) = buf[0]\n\t\t\t*(*[bufoff]byte)(out[dstEvery:]) = buf[1]\n\t\t\t*(*[bufoff]byte)(out[dstEvery*2:]) = buf[2]\n\t\t\t*(*[bufoff]byte)(out[dstEvery*3:]) = buf[3]\n\t\t\tout = out[bufoff:]\n\t\t\tdecoded += bufoff * 4\n\t\t}\n\t}\n\tif off > 0 {\n\t\tioff := int(off)\n\t\tif len(out) < dstEvery*3+ioff {\n\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 3\")\n\t\t}\n\t\tcopy(out, buf[0][:off])\n\t\tcopy(out[dstEvery:], buf[1][:off])\n\t\tcopy(out[dstEvery*2:], buf[2][:off])\n\t\tcopy(out[dstEvery*3:], buf[3][:off])\n\t\tdecoded += int(off) * 4\n\t\tout = out[off:]\n\t}\n\n\t// Decode remaining.\n\tremainBytes := dstEvery - (decoded / 4)\n\tfor i := range br {\n\t\toffset := dstEvery * i\n\t\tendsAt := offset + remainBytes\n\t\tif endsAt > len(out) {\n\t\t\tendsAt = len(out)\n\t\t}\n\t\tbr := &br[i]\n\t\tbitsLeft := br.remaining()\n\t\tfor bitsLeft > 0 {\n\t\t\tif br.finished() {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tif br.bitsRead >= 56 {\n\t\t\t\tif br.off >= 4 {\n\t\t\t\t\tv := br.in[br.off-4:]\n\t\t\t\t\tv = v[:4]\n\t\t\t\t\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\t\t\t\t\tbr.value |= uint64(low) << (br.bitsRead - 32)\n\t\t\t\t\tbr.bitsRead -= 32\n\t\t\t\t\tbr.off -= 4\n\t\t\t\t} else {\n\t\t\t\t\tfor br.off > 0 {\n\t\t\t\t\t\tbr.value |= uint64(br.in[br.off-1]) << (br.bitsRead - 8)\n\t\t\t\t\t\tbr.bitsRead -= 8\n\t\t\t\t\t\tbr.off--\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// end inline...\n\t\t\tif offset >= endsAt {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 4\")\n\t\t\t}\n\n\t\t\t// Read value and increment offset.\n\t\t\tv := single[br.peekByteFast()].entry\n\t\t\tnBits := uint8(v)\n\t\t\tbr.advance(nBits)\n\t\t\tbitsLeft -= uint(nBits)\n\t\t\tout[offset] = uint8(v >> 8)\n\t\t\toffset++\n\t\t}\n\t\tif offset != endsAt {\n\t\t\td.bufs.Put(buf)\n\t\t\treturn nil, fmt.Errorf(\"corruption detected: short output block %d, end %d != %d\", i, offset, endsAt)\n\t\t}\n\n\t\tdecoded += offset - dstEvery*i\n\t\terr = br.close()\n\t\tif err != nil {\n\t\t\td.bufs.Put(buf)\n\t\t\treturn nil, err\n\t\t}\n\t}\n\td.bufs.Put(buf)\n\tif dstSize != decoded {\n\t\treturn nil, errors.New(\"corruption detected: short output block\")\n\t}\n\treturn dst, nil\n}\n\n// matches will compare a decoding table to a coding table.\n// Errors are written to the writer.\n// Nothing will be written if table is ok.\nfunc (s *Scratch) matches(ct cTable, w io.Writer) {\n\tif s == nil || len(s.dt.single) == 0 {\n\t\treturn\n\t}\n\tdt := s.dt.single[:1<<s.actualTableLog]\n\ttablelog := s.actualTableLog\n\tok := 0\n\tbroken := 0\n\tfor sym, enc := range ct {\n\t\terrs := 0\n\t\tbroken++\n\t\tif enc.nBits == 0 {\n\t\t\tfor _, dec := range dt {\n\t\t\t\tif uint8(dec.entry>>8) == byte(sym) {\n\t\t\t\t\tfmt.Fprintf(w, \"symbol %x has decoder, but no encoder\\n\", sym)\n\t\t\t\t\terrs++\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif errs == 0 {\n\t\t\t\tbroken--\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\t// Unused bits in input\n\t\tub := tablelog - enc.nBits\n\t\ttop := enc.val << ub\n\t\t// decoder looks at top bits.\n\t\tdec := dt[top]\n\t\tif uint8(dec.entry) != enc.nBits {\n\t\t\tfmt.Fprintf(w, \"symbol 0x%x bit size mismatch (enc: %d, dec:%d).\\n\", sym, enc.nBits, uint8(dec.entry))\n\t\t\terrs++\n\t\t}\n\t\tif uint8(dec.entry>>8) != uint8(sym) {\n\t\t\tfmt.Fprintf(w, \"symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\\n\", sym, sym, uint8(dec.entry>>8))\n\t\t\terrs++\n\t\t}\n\t\tif errs > 0 {\n\t\t\tfmt.Fprintf(w, \"%d errros in base, stopping\\n\", errs)\n\t\t\tcontinue\n\t\t}\n\t\t// Ensure that all combinations are covered.\n\t\tfor i := uint16(0); i < (1 << ub); i++ {\n\t\t\tvval := top | i\n\t\t\tdec := dt[vval]\n\t\t\tif uint8(dec.entry) != enc.nBits {\n\t\t\t\tfmt.Fprintf(w, \"symbol 0x%x bit size mismatch (enc: %d, dec:%d).\\n\", vval, enc.nBits, uint8(dec.entry))\n\t\t\t\terrs++\n\t\t\t}\n\t\t\tif uint8(dec.entry>>8) != uint8(sym) {\n\t\t\t\tfmt.Fprintf(w, \"symbol 0x%x decoder output mismatch (enc: %d, dec:%d).\\n\", vval, sym, uint8(dec.entry>>8))\n\t\t\t\terrs++\n\t\t\t}\n\t\t\tif errs > 20 {\n\t\t\t\tfmt.Fprintf(w, \"%d errros, stopping\\n\", errs)\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif errs == 0 {\n\t\t\tok++\n\t\t\tbroken--\n\t\t}\n\t}\n\tif broken > 0 {\n\t\tfmt.Fprintf(w, \"%d broken, %d ok\\n\", broken, ok)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/decompress_amd64.go",
    "content": "//go:build amd64 && !appengine && !noasm && gc\n// +build amd64,!appengine,!noasm,gc\n\n// This file contains the specialisation of Decoder.Decompress4X\n// and Decoder.Decompress1X that use an asm implementation of thir main loops.\npackage huff0\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/klauspost/compress/internal/cpuinfo\"\n)\n\n// decompress4x_main_loop_x86 is an x86 assembler implementation\n// of Decompress4X when tablelog > 8.\n//\n//go:noescape\nfunc decompress4x_main_loop_amd64(ctx *decompress4xContext)\n\n// decompress4x_8b_loop_x86 is an x86 assembler implementation\n// of Decompress4X when tablelog <= 8 which decodes 4 entries\n// per loop.\n//\n//go:noescape\nfunc decompress4x_8b_main_loop_amd64(ctx *decompress4xContext)\n\n// fallback8BitSize is the size where using Go version is faster.\nconst fallback8BitSize = 800\n\ntype decompress4xContext struct {\n\tpbr      *[4]bitReaderShifted\n\tpeekBits uint8\n\tout      *byte\n\tdstEvery int\n\ttbl      *dEntrySingle\n\tdecoded  int\n\tlimit    *byte\n}\n\n// Decompress4X will decompress a 4X encoded stream.\n// The length of the supplied input must match the end of a block exactly.\n// The *capacity* of the dst slice must match the destination size of\n// the uncompressed data exactly.\nfunc (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {\n\tif len(d.dt.single) == 0 {\n\t\treturn nil, errors.New(\"no table loaded\")\n\t}\n\tif len(src) < 6+(4*1) {\n\t\treturn nil, errors.New(\"input too small\")\n\t}\n\n\tuse8BitTables := d.actualTableLog <= 8\n\tif cap(dst) < fallback8BitSize && use8BitTables {\n\t\treturn d.decompress4X8bit(dst, src)\n\t}\n\n\tvar br [4]bitReaderShifted\n\t// Decode \"jump table\"\n\tstart := 6\n\tfor i := 0; i < 3; i++ {\n\t\tlength := int(src[i*2]) | (int(src[i*2+1]) << 8)\n\t\tif start+length >= len(src) {\n\t\t\treturn nil, errors.New(\"truncated input (or invalid offset)\")\n\t\t}\n\t\terr := br[i].init(src[start : start+length])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstart += length\n\t}\n\terr := br[3].init(src[start:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// destination, offset to match first output\n\tdstSize := cap(dst)\n\tdst = dst[:dstSize]\n\tout := dst\n\tdstEvery := (dstSize + 3) / 4\n\n\tconst tlSize = 1 << tableLogMax\n\tconst tlMask = tlSize - 1\n\tsingle := d.dt.single[:tlSize]\n\n\tvar decoded int\n\n\tif len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) {\n\t\tctx := decompress4xContext{\n\t\t\tpbr:      &br,\n\t\t\tpeekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()\n\t\t\tout:      &out[0],\n\t\t\tdstEvery: dstEvery,\n\t\t\ttbl:      &single[0],\n\t\t\tlimit:    &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last.\n\t\t}\n\t\tif use8BitTables {\n\t\t\tdecompress4x_8b_main_loop_amd64(&ctx)\n\t\t} else {\n\t\t\tdecompress4x_main_loop_amd64(&ctx)\n\t\t}\n\n\t\tdecoded = ctx.decoded\n\t\tout = out[decoded/4:]\n\t}\n\n\t// Decode remaining.\n\tremainBytes := dstEvery - (decoded / 4)\n\tfor i := range br {\n\t\toffset := dstEvery * i\n\t\tendsAt := offset + remainBytes\n\t\tif endsAt > len(out) {\n\t\t\tendsAt = len(out)\n\t\t}\n\t\tbr := &br[i]\n\t\tbitsLeft := br.remaining()\n\t\tfor bitsLeft > 0 {\n\t\t\tbr.fill()\n\t\t\tif offset >= endsAt {\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 4\")\n\t\t\t}\n\n\t\t\t// Read value and increment offset.\n\t\t\tval := br.peekBitsFast(d.actualTableLog)\n\t\t\tv := single[val&tlMask].entry\n\t\t\tnBits := uint8(v)\n\t\t\tbr.advance(nBits)\n\t\t\tbitsLeft -= uint(nBits)\n\t\t\tout[offset] = uint8(v >> 8)\n\t\t\toffset++\n\t\t}\n\t\tif offset != endsAt {\n\t\t\treturn nil, fmt.Errorf(\"corruption detected: short output block %d, end %d != %d\", i, offset, endsAt)\n\t\t}\n\t\tdecoded += offset - dstEvery*i\n\t\terr = br.close()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif dstSize != decoded {\n\t\treturn nil, errors.New(\"corruption detected: short output block\")\n\t}\n\treturn dst, nil\n}\n\n// decompress4x_main_loop_x86 is an x86 assembler implementation\n// of Decompress1X when tablelog > 8.\n//\n//go:noescape\nfunc decompress1x_main_loop_amd64(ctx *decompress1xContext)\n\n// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation\n// of Decompress1X when tablelog > 8.\n//\n//go:noescape\nfunc decompress1x_main_loop_bmi2(ctx *decompress1xContext)\n\ntype decompress1xContext struct {\n\tpbr      *bitReaderShifted\n\tpeekBits uint8\n\tout      *byte\n\toutCap   int\n\ttbl      *dEntrySingle\n\tdecoded  int\n}\n\n// Error reported by asm implementations\nconst error_max_decoded_size_exeeded = -1\n\n// Decompress1X will decompress a 1X encoded stream.\n// The cap of the output buffer will be the maximum decompressed size.\n// The length of the supplied input must match the end of a block exactly.\nfunc (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {\n\tif len(d.dt.single) == 0 {\n\t\treturn nil, errors.New(\"no table loaded\")\n\t}\n\tvar br bitReaderShifted\n\terr := br.init(src)\n\tif err != nil {\n\t\treturn dst, err\n\t}\n\tmaxDecodedSize := cap(dst)\n\tdst = dst[:maxDecodedSize]\n\n\tconst tlSize = 1 << tableLogMax\n\tconst tlMask = tlSize - 1\n\n\tif maxDecodedSize >= 4 {\n\t\tctx := decompress1xContext{\n\t\t\tpbr:      &br,\n\t\t\tout:      &dst[0],\n\t\t\toutCap:   maxDecodedSize,\n\t\t\tpeekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()\n\t\t\ttbl:      &d.dt.single[0],\n\t\t}\n\n\t\tif cpuinfo.HasBMI2() {\n\t\t\tdecompress1x_main_loop_bmi2(&ctx)\n\t\t} else {\n\t\t\tdecompress1x_main_loop_amd64(&ctx)\n\t\t}\n\t\tif ctx.decoded == error_max_decoded_size_exeeded {\n\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t}\n\n\t\tdst = dst[:ctx.decoded]\n\t}\n\n\t// br < 8, so uint8 is fine\n\tbitsLeft := uint8(br.off)*8 + 64 - br.bitsRead\n\tfor bitsLeft > 0 {\n\t\tbr.fill()\n\t\tif len(dst) >= maxDecodedSize {\n\t\t\tbr.close()\n\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t}\n\t\tv := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]\n\t\tnBits := uint8(v.entry)\n\t\tbr.advance(nBits)\n\t\tbitsLeft -= nBits\n\t\tdst = append(dst, uint8(v.entry>>8))\n\t}\n\treturn dst, br.close()\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/decompress_amd64.s",
    "content": "// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT.\n\n//go:build amd64 && !appengine && !noasm && gc\n\n// func decompress4x_main_loop_amd64(ctx *decompress4xContext)\nTEXT ·decompress4x_main_loop_amd64(SB), $0-8\n\t// Preload values\n\tMOVQ    ctx+0(FP), AX\n\tMOVBQZX 8(AX), DI\n\tMOVQ    16(AX), BX\n\tMOVQ    48(AX), SI\n\tMOVQ    24(AX), R8\n\tMOVQ    32(AX), R9\n\tMOVQ    (AX), R10\n\n\t// Main loop\nmain_loop:\n\tXORL  DX, DX\n\tCMPQ  BX, SI\n\tSETGE DL\n\n\t// br0.fillFast32()\n\tMOVQ    32(R10), R11\n\tMOVBQZX 40(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill0\n\tMOVQ    24(R10), AX\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, AX\n\tMOVQ    (R10), R13\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (AX)(R13*1), R13\n\tMOVQ R12, CX\n\tSHLQ CL, R13\n\tMOVQ AX, 24(R10)\n\tORQ  R13, R11\n\n\t// exhausted += (br0.off < 4)\n\tCMPQ AX, $0x04\n\tADCB $+0, DL\n\nskip_fill0:\n\t// val0 := br0.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br0.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br0.peekTopBits(peekBits)\n\tMOVQ DI, CX\n\tMOVQ R11, R13\n\tSHRQ CL, R13\n\n\t// v1 := table[val1&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br0.advance(uint8(v1.entry))\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// these two writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\tMOVW AX, (BX)\n\n\t// update the bitreader structure\n\tMOVQ R11, 32(R10)\n\tMOVB R12, 40(R10)\n\n\t// br1.fillFast32()\n\tMOVQ    80(R10), R11\n\tMOVBQZX 88(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill1\n\tMOVQ    72(R10), AX\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, AX\n\tMOVQ    48(R10), R13\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (AX)(R13*1), R13\n\tMOVQ R12, CX\n\tSHLQ CL, R13\n\tMOVQ AX, 72(R10)\n\tORQ  R13, R11\n\n\t// exhausted += (br1.off < 4)\n\tCMPQ AX, $0x04\n\tADCB $+0, DL\n\nskip_fill1:\n\t// val0 := br1.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br1.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br1.peekTopBits(peekBits)\n\tMOVQ DI, CX\n\tMOVQ R11, R13\n\tSHRQ CL, R13\n\n\t// v1 := table[val1&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br1.advance(uint8(v1.entry))\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// these two writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\tMOVW AX, (BX)(R8*1)\n\n\t// update the bitreader structure\n\tMOVQ R11, 80(R10)\n\tMOVB R12, 88(R10)\n\n\t// br2.fillFast32()\n\tMOVQ    128(R10), R11\n\tMOVBQZX 136(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill2\n\tMOVQ    120(R10), AX\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, AX\n\tMOVQ    96(R10), R13\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (AX)(R13*1), R13\n\tMOVQ R12, CX\n\tSHLQ CL, R13\n\tMOVQ AX, 120(R10)\n\tORQ  R13, R11\n\n\t// exhausted += (br2.off < 4)\n\tCMPQ AX, $0x04\n\tADCB $+0, DL\n\nskip_fill2:\n\t// val0 := br2.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br2.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br2.peekTopBits(peekBits)\n\tMOVQ DI, CX\n\tMOVQ R11, R13\n\tSHRQ CL, R13\n\n\t// v1 := table[val1&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br2.advance(uint8(v1.entry))\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// these two writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\tMOVW AX, (BX)(R8*2)\n\n\t// update the bitreader structure\n\tMOVQ R11, 128(R10)\n\tMOVB R12, 136(R10)\n\n\t// br3.fillFast32()\n\tMOVQ    176(R10), R11\n\tMOVBQZX 184(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill3\n\tMOVQ    168(R10), AX\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, AX\n\tMOVQ    144(R10), R13\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (AX)(R13*1), R13\n\tMOVQ R12, CX\n\tSHLQ CL, R13\n\tMOVQ AX, 168(R10)\n\tORQ  R13, R11\n\n\t// exhausted += (br3.off < 4)\n\tCMPQ AX, $0x04\n\tADCB $+0, DL\n\nskip_fill3:\n\t// val0 := br3.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br3.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br3.peekTopBits(peekBits)\n\tMOVQ DI, CX\n\tMOVQ R11, R13\n\tSHRQ CL, R13\n\n\t// v1 := table[val1&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br3.advance(uint8(v1.entry))\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// these two writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\tLEAQ (R8)(R8*2), CX\n\tMOVW AX, (BX)(CX*1)\n\n\t// update the bitreader structure\n\tMOVQ  R11, 176(R10)\n\tMOVB  R12, 184(R10)\n\tADDQ  $0x02, BX\n\tTESTB DL, DL\n\tJZ    main_loop\n\tMOVQ  ctx+0(FP), AX\n\tSUBQ  16(AX), BX\n\tSHLQ  $0x02, BX\n\tMOVQ  BX, 40(AX)\n\tRET\n\n// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext)\nTEXT ·decompress4x_8b_main_loop_amd64(SB), $0-8\n\t// Preload values\n\tMOVQ    ctx+0(FP), CX\n\tMOVBQZX 8(CX), DI\n\tMOVQ    16(CX), BX\n\tMOVQ    48(CX), SI\n\tMOVQ    24(CX), R8\n\tMOVQ    32(CX), R9\n\tMOVQ    (CX), R10\n\n\t// Main loop\nmain_loop:\n\tXORL  DX, DX\n\tCMPQ  BX, SI\n\tSETGE DL\n\n\t// br0.fillFast32()\n\tMOVQ    32(R10), R11\n\tMOVBQZX 40(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill0\n\tMOVQ    24(R10), R13\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, R13\n\tMOVQ    (R10), R14\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (R13)(R14*1), R14\n\tMOVQ R12, CX\n\tSHLQ CL, R14\n\tMOVQ R13, 24(R10)\n\tORQ  R14, R11\n\n\t// exhausted += (br0.off < 4)\n\tCMPQ R13, $0x04\n\tADCB $+0, DL\n\nskip_fill0:\n\t// val0 := br0.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br0.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br0.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v1 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br0.advance(uint8(v1.entry)\n\tMOVB   CH, AH\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// val2 := br0.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v2 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br0.advance(uint8(v2.entry)\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val3 := br0.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v3 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br0.advance(uint8(v3.entry)\n\tMOVB   CH, AL\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// these four writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\t// out[id * dstEvery + 3] = uint8(v2.entry >> 8)\n\t// out[id * dstEvery + 4] = uint8(v3.entry >> 8)\n\tMOVL AX, (BX)\n\n\t// update the bitreader structure\n\tMOVQ R11, 32(R10)\n\tMOVB R12, 40(R10)\n\n\t// br1.fillFast32()\n\tMOVQ    80(R10), R11\n\tMOVBQZX 88(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill1\n\tMOVQ    72(R10), R13\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, R13\n\tMOVQ    48(R10), R14\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (R13)(R14*1), R14\n\tMOVQ R12, CX\n\tSHLQ CL, R14\n\tMOVQ R13, 72(R10)\n\tORQ  R14, R11\n\n\t// exhausted += (br1.off < 4)\n\tCMPQ R13, $0x04\n\tADCB $+0, DL\n\nskip_fill1:\n\t// val0 := br1.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br1.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br1.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v1 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br1.advance(uint8(v1.entry)\n\tMOVB   CH, AH\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// val2 := br1.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v2 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br1.advance(uint8(v2.entry)\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val3 := br1.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v3 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br1.advance(uint8(v3.entry)\n\tMOVB   CH, AL\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// these four writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\t// out[id * dstEvery + 3] = uint8(v2.entry >> 8)\n\t// out[id * dstEvery + 4] = uint8(v3.entry >> 8)\n\tMOVL AX, (BX)(R8*1)\n\n\t// update the bitreader structure\n\tMOVQ R11, 80(R10)\n\tMOVB R12, 88(R10)\n\n\t// br2.fillFast32()\n\tMOVQ    128(R10), R11\n\tMOVBQZX 136(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill2\n\tMOVQ    120(R10), R13\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, R13\n\tMOVQ    96(R10), R14\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (R13)(R14*1), R14\n\tMOVQ R12, CX\n\tSHLQ CL, R14\n\tMOVQ R13, 120(R10)\n\tORQ  R14, R11\n\n\t// exhausted += (br2.off < 4)\n\tCMPQ R13, $0x04\n\tADCB $+0, DL\n\nskip_fill2:\n\t// val0 := br2.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br2.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br2.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v1 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br2.advance(uint8(v1.entry)\n\tMOVB   CH, AH\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// val2 := br2.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v2 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br2.advance(uint8(v2.entry)\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val3 := br2.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v3 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br2.advance(uint8(v3.entry)\n\tMOVB   CH, AL\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// these four writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\t// out[id * dstEvery + 3] = uint8(v2.entry >> 8)\n\t// out[id * dstEvery + 4] = uint8(v3.entry >> 8)\n\tMOVL AX, (BX)(R8*2)\n\n\t// update the bitreader structure\n\tMOVQ R11, 128(R10)\n\tMOVB R12, 136(R10)\n\n\t// br3.fillFast32()\n\tMOVQ    176(R10), R11\n\tMOVBQZX 184(R10), R12\n\tCMPQ    R12, $0x20\n\tJBE     skip_fill3\n\tMOVQ    168(R10), R13\n\tSUBQ    $0x20, R12\n\tSUBQ    $0x04, R13\n\tMOVQ    144(R10), R14\n\n\t// b.value |= uint64(low) << (b.bitsRead & 63)\n\tMOVL (R13)(R14*1), R14\n\tMOVQ R12, CX\n\tSHLQ CL, R14\n\tMOVQ R13, 168(R10)\n\tORQ  R14, R11\n\n\t// exhausted += (br3.off < 4)\n\tCMPQ R13, $0x04\n\tADCB $+0, DL\n\nskip_fill3:\n\t// val0 := br3.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v0 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br3.advance(uint8(v0.entry)\n\tMOVB CH, AL\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val1 := br3.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v1 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br3.advance(uint8(v1.entry)\n\tMOVB   CH, AH\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// val2 := br3.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v2 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br3.advance(uint8(v2.entry)\n\tMOVB CH, AH\n\tSHLQ CL, R11\n\tADDB CL, R12\n\n\t// val3 := br3.peekTopBits(peekBits)\n\tMOVQ R11, R13\n\tMOVQ DI, CX\n\tSHRQ CL, R13\n\n\t// v3 := table[val0&mask]\n\tMOVW (R9)(R13*2), CX\n\n\t// br3.advance(uint8(v3.entry)\n\tMOVB   CH, AL\n\tSHLQ   CL, R11\n\tADDB   CL, R12\n\tBSWAPL AX\n\n\t// these four writes get coalesced\n\t// out[id * dstEvery + 0] = uint8(v0.entry >> 8)\n\t// out[id * dstEvery + 1] = uint8(v1.entry >> 8)\n\t// out[id * dstEvery + 3] = uint8(v2.entry >> 8)\n\t// out[id * dstEvery + 4] = uint8(v3.entry >> 8)\n\tLEAQ (R8)(R8*2), CX\n\tMOVL AX, (BX)(CX*1)\n\n\t// update the bitreader structure\n\tMOVQ  R11, 176(R10)\n\tMOVB  R12, 184(R10)\n\tADDQ  $0x04, BX\n\tTESTB DL, DL\n\tJZ    main_loop\n\tMOVQ  ctx+0(FP), AX\n\tSUBQ  16(AX), BX\n\tSHLQ  $0x02, BX\n\tMOVQ  BX, 40(AX)\n\tRET\n\n// func decompress1x_main_loop_amd64(ctx *decompress1xContext)\nTEXT ·decompress1x_main_loop_amd64(SB), $0-8\n\tMOVQ    ctx+0(FP), CX\n\tMOVQ    16(CX), DX\n\tMOVQ    24(CX), BX\n\tCMPQ    BX, $0x04\n\tJB      error_max_decoded_size_exceeded\n\tLEAQ    (DX)(BX*1), BX\n\tMOVQ    (CX), SI\n\tMOVQ    (SI), R8\n\tMOVQ    24(SI), R9\n\tMOVQ    32(SI), R10\n\tMOVBQZX 40(SI), R11\n\tMOVQ    32(CX), SI\n\tMOVBQZX 8(CX), DI\n\tJMP     loop_condition\n\nmain_loop:\n\t// Check if we have room for 4 bytes in the output buffer\n\tLEAQ 4(DX), CX\n\tCMPQ CX, BX\n\tJGE  error_max_decoded_size_exceeded\n\n\t// Decode 4 values\n\tCMPQ R11, $0x20\n\tJL   bitReader_fillFast_1_end\n\tSUBQ $0x20, R11\n\tSUBQ $0x04, R9\n\tMOVL (R8)(R9*1), R12\n\tMOVQ R11, CX\n\tSHLQ CL, R12\n\tORQ  R12, R10\n\nbitReader_fillFast_1_end:\n\tMOVQ    DI, CX\n\tMOVQ    R10, R12\n\tSHRQ    CL, R12\n\tMOVW    (SI)(R12*2), CX\n\tMOVB    CH, AL\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLQ    CL, R10\n\tMOVQ    DI, CX\n\tMOVQ    R10, R12\n\tSHRQ    CL, R12\n\tMOVW    (SI)(R12*2), CX\n\tMOVB    CH, AH\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLQ    CL, R10\n\tBSWAPL  AX\n\tCMPQ    R11, $0x20\n\tJL      bitReader_fillFast_2_end\n\tSUBQ    $0x20, R11\n\tSUBQ    $0x04, R9\n\tMOVL    (R8)(R9*1), R12\n\tMOVQ    R11, CX\n\tSHLQ    CL, R12\n\tORQ     R12, R10\n\nbitReader_fillFast_2_end:\n\tMOVQ    DI, CX\n\tMOVQ    R10, R12\n\tSHRQ    CL, R12\n\tMOVW    (SI)(R12*2), CX\n\tMOVB    CH, AH\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLQ    CL, R10\n\tMOVQ    DI, CX\n\tMOVQ    R10, R12\n\tSHRQ    CL, R12\n\tMOVW    (SI)(R12*2), CX\n\tMOVB    CH, AL\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLQ    CL, R10\n\tBSWAPL  AX\n\n\t// Store the decoded values\n\tMOVL AX, (DX)\n\tADDQ $0x04, DX\n\nloop_condition:\n\tCMPQ R9, $0x08\n\tJGE  main_loop\n\n\t// Update ctx structure\n\tMOVQ ctx+0(FP), AX\n\tSUBQ 16(AX), DX\n\tMOVQ DX, 40(AX)\n\tMOVQ (AX), AX\n\tMOVQ R9, 24(AX)\n\tMOVQ R10, 32(AX)\n\tMOVB R11, 40(AX)\n\tRET\n\n\t// Report error\nerror_max_decoded_size_exceeded:\n\tMOVQ ctx+0(FP), AX\n\tMOVQ $-1, CX\n\tMOVQ CX, 40(AX)\n\tRET\n\n// func decompress1x_main_loop_bmi2(ctx *decompress1xContext)\n// Requires: BMI2\nTEXT ·decompress1x_main_loop_bmi2(SB), $0-8\n\tMOVQ    ctx+0(FP), CX\n\tMOVQ    16(CX), DX\n\tMOVQ    24(CX), BX\n\tCMPQ    BX, $0x04\n\tJB      error_max_decoded_size_exceeded\n\tLEAQ    (DX)(BX*1), BX\n\tMOVQ    (CX), SI\n\tMOVQ    (SI), R8\n\tMOVQ    24(SI), R9\n\tMOVQ    32(SI), R10\n\tMOVBQZX 40(SI), R11\n\tMOVQ    32(CX), SI\n\tMOVBQZX 8(CX), DI\n\tJMP     loop_condition\n\nmain_loop:\n\t// Check if we have room for 4 bytes in the output buffer\n\tLEAQ 4(DX), CX\n\tCMPQ CX, BX\n\tJGE  error_max_decoded_size_exceeded\n\n\t// Decode 4 values\n\tCMPQ  R11, $0x20\n\tJL    bitReader_fillFast_1_end\n\tSUBQ  $0x20, R11\n\tSUBQ  $0x04, R9\n\tMOVL  (R8)(R9*1), CX\n\tSHLXQ R11, CX, CX\n\tORQ   CX, R10\n\nbitReader_fillFast_1_end:\n\tSHRXQ   DI, R10, CX\n\tMOVW    (SI)(CX*2), CX\n\tMOVB    CH, AL\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLXQ   CX, R10, R10\n\tSHRXQ   DI, R10, CX\n\tMOVW    (SI)(CX*2), CX\n\tMOVB    CH, AH\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLXQ   CX, R10, R10\n\tBSWAPL  AX\n\tCMPQ    R11, $0x20\n\tJL      bitReader_fillFast_2_end\n\tSUBQ    $0x20, R11\n\tSUBQ    $0x04, R9\n\tMOVL    (R8)(R9*1), CX\n\tSHLXQ   R11, CX, CX\n\tORQ     CX, R10\n\nbitReader_fillFast_2_end:\n\tSHRXQ   DI, R10, CX\n\tMOVW    (SI)(CX*2), CX\n\tMOVB    CH, AH\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLXQ   CX, R10, R10\n\tSHRXQ   DI, R10, CX\n\tMOVW    (SI)(CX*2), CX\n\tMOVB    CH, AL\n\tMOVBQZX CL, CX\n\tADDQ    CX, R11\n\tSHLXQ   CX, R10, R10\n\tBSWAPL  AX\n\n\t// Store the decoded values\n\tMOVL AX, (DX)\n\tADDQ $0x04, DX\n\nloop_condition:\n\tCMPQ R9, $0x08\n\tJGE  main_loop\n\n\t// Update ctx structure\n\tMOVQ ctx+0(FP), AX\n\tSUBQ 16(AX), DX\n\tMOVQ DX, 40(AX)\n\tMOVQ (AX), AX\n\tMOVQ R9, 24(AX)\n\tMOVQ R10, 32(AX)\n\tMOVB R11, 40(AX)\n\tRET\n\n\t// Report error\nerror_max_decoded_size_exceeded:\n\tMOVQ ctx+0(FP), AX\n\tMOVQ $-1, CX\n\tMOVQ CX, 40(AX)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/decompress_generic.go",
    "content": "//go:build !amd64 || appengine || !gc || noasm\n// +build !amd64 appengine !gc noasm\n\n// This file contains a generic implementation of Decoder.Decompress4X.\npackage huff0\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// Decompress4X will decompress a 4X encoded stream.\n// The length of the supplied input must match the end of a block exactly.\n// The *capacity* of the dst slice must match the destination size of\n// the uncompressed data exactly.\nfunc (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {\n\tif len(d.dt.single) == 0 {\n\t\treturn nil, errors.New(\"no table loaded\")\n\t}\n\tif len(src) < 6+(4*1) {\n\t\treturn nil, errors.New(\"input too small\")\n\t}\n\tif use8BitTables && d.actualTableLog <= 8 {\n\t\treturn d.decompress4X8bit(dst, src)\n\t}\n\n\tvar br [4]bitReaderShifted\n\t// Decode \"jump table\"\n\tstart := 6\n\tfor i := 0; i < 3; i++ {\n\t\tlength := int(src[i*2]) | (int(src[i*2+1]) << 8)\n\t\tif start+length >= len(src) {\n\t\t\treturn nil, errors.New(\"truncated input (or invalid offset)\")\n\t\t}\n\t\terr := br[i].init(src[start : start+length])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tstart += length\n\t}\n\terr := br[3].init(src[start:])\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// destination, offset to match first output\n\tdstSize := cap(dst)\n\tdst = dst[:dstSize]\n\tout := dst\n\tdstEvery := (dstSize + 3) / 4\n\n\tconst tlSize = 1 << tableLogMax\n\tconst tlMask = tlSize - 1\n\tsingle := d.dt.single[:tlSize]\n\n\t// Use temp table to avoid bound checks/append penalty.\n\tbuf := d.buffer()\n\tvar off uint8\n\tvar decoded int\n\n\t// Decode 2 values from each decoder/loop.\n\tconst bufoff = 256\n\tfor {\n\t\tif br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 {\n\t\t\tbreak\n\t\t}\n\n\t\t{\n\t\t\tconst stream = 0\n\t\t\tconst stream2 = 1\n\t\t\tbr[stream].fillFast()\n\t\t\tbr[stream2].fillFast()\n\n\t\t\tval := br[stream].peekBitsFast(d.actualTableLog)\n\t\t\tval2 := br[stream2].peekBitsFast(d.actualTableLog)\n\t\t\tv := single[val&tlMask]\n\t\t\tv2 := single[val2&tlMask]\n\t\t\tbr[stream].advance(uint8(v.entry))\n\t\t\tbr[stream2].advance(uint8(v2.entry))\n\t\t\tbuf[stream][off] = uint8(v.entry >> 8)\n\t\t\tbuf[stream2][off] = uint8(v2.entry >> 8)\n\n\t\t\tval = br[stream].peekBitsFast(d.actualTableLog)\n\t\t\tval2 = br[stream2].peekBitsFast(d.actualTableLog)\n\t\t\tv = single[val&tlMask]\n\t\t\tv2 = single[val2&tlMask]\n\t\t\tbr[stream].advance(uint8(v.entry))\n\t\t\tbr[stream2].advance(uint8(v2.entry))\n\t\t\tbuf[stream][off+1] = uint8(v.entry >> 8)\n\t\t\tbuf[stream2][off+1] = uint8(v2.entry >> 8)\n\t\t}\n\n\t\t{\n\t\t\tconst stream = 2\n\t\t\tconst stream2 = 3\n\t\t\tbr[stream].fillFast()\n\t\t\tbr[stream2].fillFast()\n\n\t\t\tval := br[stream].peekBitsFast(d.actualTableLog)\n\t\t\tval2 := br[stream2].peekBitsFast(d.actualTableLog)\n\t\t\tv := single[val&tlMask]\n\t\t\tv2 := single[val2&tlMask]\n\t\t\tbr[stream].advance(uint8(v.entry))\n\t\t\tbr[stream2].advance(uint8(v2.entry))\n\t\t\tbuf[stream][off] = uint8(v.entry >> 8)\n\t\t\tbuf[stream2][off] = uint8(v2.entry >> 8)\n\n\t\t\tval = br[stream].peekBitsFast(d.actualTableLog)\n\t\t\tval2 = br[stream2].peekBitsFast(d.actualTableLog)\n\t\t\tv = single[val&tlMask]\n\t\t\tv2 = single[val2&tlMask]\n\t\t\tbr[stream].advance(uint8(v.entry))\n\t\t\tbr[stream2].advance(uint8(v2.entry))\n\t\t\tbuf[stream][off+1] = uint8(v.entry >> 8)\n\t\t\tbuf[stream2][off+1] = uint8(v2.entry >> 8)\n\t\t}\n\n\t\toff += 2\n\n\t\tif off == 0 {\n\t\t\tif bufoff > dstEvery {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 1\")\n\t\t\t}\n\t\t\t// There must at least be 3 buffers left.\n\t\t\tif len(out)-bufoff < dstEvery*3 {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 2\")\n\t\t\t}\n\t\t\t//copy(out, buf[0][:])\n\t\t\t//copy(out[dstEvery:], buf[1][:])\n\t\t\t//copy(out[dstEvery*2:], buf[2][:])\n\t\t\t//copy(out[dstEvery*3:], buf[3][:])\n\t\t\t*(*[bufoff]byte)(out) = buf[0]\n\t\t\t*(*[bufoff]byte)(out[dstEvery:]) = buf[1]\n\t\t\t*(*[bufoff]byte)(out[dstEvery*2:]) = buf[2]\n\t\t\t*(*[bufoff]byte)(out[dstEvery*3:]) = buf[3]\n\t\t\tout = out[bufoff:]\n\t\t\tdecoded += bufoff * 4\n\t\t}\n\t}\n\tif off > 0 {\n\t\tioff := int(off)\n\t\tif len(out) < dstEvery*3+ioff {\n\t\t\td.bufs.Put(buf)\n\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 3\")\n\t\t}\n\t\tcopy(out, buf[0][:off])\n\t\tcopy(out[dstEvery:], buf[1][:off])\n\t\tcopy(out[dstEvery*2:], buf[2][:off])\n\t\tcopy(out[dstEvery*3:], buf[3][:off])\n\t\tdecoded += int(off) * 4\n\t\tout = out[off:]\n\t}\n\n\t// Decode remaining.\n\tremainBytes := dstEvery - (decoded / 4)\n\tfor i := range br {\n\t\toffset := dstEvery * i\n\t\tendsAt := offset + remainBytes\n\t\tif endsAt > len(out) {\n\t\t\tendsAt = len(out)\n\t\t}\n\t\tbr := &br[i]\n\t\tbitsLeft := br.remaining()\n\t\tfor bitsLeft > 0 {\n\t\t\tbr.fill()\n\t\t\tif offset >= endsAt {\n\t\t\t\td.bufs.Put(buf)\n\t\t\t\treturn nil, errors.New(\"corruption detected: stream overrun 4\")\n\t\t\t}\n\n\t\t\t// Read value and increment offset.\n\t\t\tval := br.peekBitsFast(d.actualTableLog)\n\t\t\tv := single[val&tlMask].entry\n\t\t\tnBits := uint8(v)\n\t\t\tbr.advance(nBits)\n\t\t\tbitsLeft -= uint(nBits)\n\t\t\tout[offset] = uint8(v >> 8)\n\t\t\toffset++\n\t\t}\n\t\tif offset != endsAt {\n\t\t\td.bufs.Put(buf)\n\t\t\treturn nil, fmt.Errorf(\"corruption detected: short output block %d, end %d != %d\", i, offset, endsAt)\n\t\t}\n\t\tdecoded += offset - dstEvery*i\n\t\terr = br.close()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\td.bufs.Put(buf)\n\tif dstSize != decoded {\n\t\treturn nil, errors.New(\"corruption detected: short output block\")\n\t}\n\treturn dst, nil\n}\n\n// Decompress1X will decompress a 1X encoded stream.\n// The cap of the output buffer will be the maximum decompressed size.\n// The length of the supplied input must match the end of a block exactly.\nfunc (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {\n\tif len(d.dt.single) == 0 {\n\t\treturn nil, errors.New(\"no table loaded\")\n\t}\n\tif use8BitTables && d.actualTableLog <= 8 {\n\t\treturn d.decompress1X8Bit(dst, src)\n\t}\n\tvar br bitReaderShifted\n\terr := br.init(src)\n\tif err != nil {\n\t\treturn dst, err\n\t}\n\tmaxDecodedSize := cap(dst)\n\tdst = dst[:0]\n\n\t// Avoid bounds check by always having full sized table.\n\tconst tlSize = 1 << tableLogMax\n\tconst tlMask = tlSize - 1\n\tdt := d.dt.single[:tlSize]\n\n\t// Use temp table to avoid bound checks/append penalty.\n\tbufs := d.buffer()\n\tbuf := &bufs[0]\n\tvar off uint8\n\n\tfor br.off >= 8 {\n\t\tbr.fillFast()\n\t\tv := dt[br.peekBitsFast(d.actualTableLog)&tlMask]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+0] = uint8(v.entry >> 8)\n\n\t\tv = dt[br.peekBitsFast(d.actualTableLog)&tlMask]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+1] = uint8(v.entry >> 8)\n\n\t\t// Refill\n\t\tbr.fillFast()\n\n\t\tv = dt[br.peekBitsFast(d.actualTableLog)&tlMask]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+2] = uint8(v.entry >> 8)\n\n\t\tv = dt[br.peekBitsFast(d.actualTableLog)&tlMask]\n\t\tbr.advance(uint8(v.entry))\n\t\tbuf[off+3] = uint8(v.entry >> 8)\n\n\t\toff += 4\n\t\tif off == 0 {\n\t\t\tif len(dst)+256 > maxDecodedSize {\n\t\t\t\tbr.close()\n\t\t\t\td.bufs.Put(bufs)\n\t\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t\t}\n\t\t\tdst = append(dst, buf[:]...)\n\t\t}\n\t}\n\n\tif len(dst)+int(off) > maxDecodedSize {\n\t\td.bufs.Put(bufs)\n\t\tbr.close()\n\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t}\n\tdst = append(dst, buf[:off]...)\n\n\t// br < 8, so uint8 is fine\n\tbitsLeft := uint8(br.off)*8 + 64 - br.bitsRead\n\tfor bitsLeft > 0 {\n\t\tbr.fill()\n\t\tif false && br.bitsRead >= 32 {\n\t\t\tif br.off >= 4 {\n\t\t\t\tv := br.in[br.off-4:]\n\t\t\t\tv = v[:4]\n\t\t\t\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\t\t\t\tbr.value = (br.value << 32) | uint64(low)\n\t\t\t\tbr.bitsRead -= 32\n\t\t\t\tbr.off -= 4\n\t\t\t} else {\n\t\t\t\tfor br.off > 0 {\n\t\t\t\t\tbr.value = (br.value << 8) | uint64(br.in[br.off-1])\n\t\t\t\t\tbr.bitsRead -= 8\n\t\t\t\t\tbr.off--\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif len(dst) >= maxDecodedSize {\n\t\t\td.bufs.Put(bufs)\n\t\t\tbr.close()\n\t\t\treturn nil, ErrMaxDecodedSizeExceeded\n\t\t}\n\t\tv := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]\n\t\tnBits := uint8(v.entry)\n\t\tbr.advance(nBits)\n\t\tbitsLeft -= nBits\n\t\tdst = append(dst, uint8(v.entry>>8))\n\t}\n\td.bufs.Put(bufs)\n\treturn dst, br.close()\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/huff0/huff0.go",
    "content": "// Package huff0 provides fast huffman encoding as used in zstd.\n//\n// See README.md at https://github.com/klauspost/compress/tree/master/huff0 for details.\npackage huff0\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/bits\"\n\t\"sync\"\n\n\t\"github.com/klauspost/compress/fse\"\n)\n\nconst (\n\tmaxSymbolValue = 255\n\n\t// zstandard limits tablelog to 11, see:\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#huffman-tree-description\n\ttableLogMax     = 11\n\ttableLogDefault = 11\n\tminTablelog     = 5\n\thuffNodesLen    = 512\n\n\t// BlockSizeMax is maximum input size for a single block uncompressed.\n\tBlockSizeMax = 1<<18 - 1\n)\n\nvar (\n\t// ErrIncompressible is returned when input is judged to be too hard to compress.\n\tErrIncompressible = errors.New(\"input is not compressible\")\n\n\t// ErrUseRLE is returned from the compressor when the input is a single byte value repeated.\n\tErrUseRLE = errors.New(\"input is single value repeated\")\n\n\t// ErrTooBig is return if input is too large for a single block.\n\tErrTooBig = errors.New(\"input too big\")\n\n\t// ErrMaxDecodedSizeExceeded is return if input is too large for a single block.\n\tErrMaxDecodedSizeExceeded = errors.New(\"maximum output size exceeded\")\n)\n\ntype ReusePolicy uint8\n\nconst (\n\t// ReusePolicyAllow will allow reuse if it produces smaller output.\n\tReusePolicyAllow ReusePolicy = iota\n\n\t// ReusePolicyPrefer will re-use aggressively if possible.\n\t// This will not check if a new table will produce smaller output,\n\t// except if the current table is impossible to use or\n\t// compressed output is bigger than input.\n\tReusePolicyPrefer\n\n\t// ReusePolicyNone will disable re-use of tables.\n\t// This is slightly faster than ReusePolicyAllow but may produce larger output.\n\tReusePolicyNone\n\n\t// ReusePolicyMust must allow reuse and produce smaller output.\n\tReusePolicyMust\n)\n\ntype Scratch struct {\n\tcount [maxSymbolValue + 1]uint32\n\n\t// Per block parameters.\n\t// These can be used to override compression parameters of the block.\n\t// Do not touch, unless you know what you are doing.\n\n\t// Out is output buffer.\n\t// If the scratch is re-used before the caller is done processing the output,\n\t// set this field to nil.\n\t// Otherwise the output buffer will be re-used for next Compression/Decompression step\n\t// and allocation will be avoided.\n\tOut []byte\n\n\t// OutTable will contain the table data only, if a new table has been generated.\n\t// Slice of the returned data.\n\tOutTable []byte\n\n\t// OutData will contain the compressed data.\n\t// Slice of the returned data.\n\tOutData []byte\n\n\t// MaxDecodedSize will set the maximum allowed output size.\n\t// This value will automatically be set to BlockSizeMax if not set.\n\t// Decoders will return ErrMaxDecodedSizeExceeded is this limit is exceeded.\n\tMaxDecodedSize int\n\n\tbr byteReader\n\n\t// MaxSymbolValue will override the maximum symbol value of the next block.\n\tMaxSymbolValue uint8\n\n\t// TableLog will attempt to override the tablelog for the next block.\n\t// Must be <= 11 and >= 5.\n\tTableLog uint8\n\n\t// Reuse will specify the reuse policy\n\tReuse ReusePolicy\n\n\t// WantLogLess allows to specify a log 2 reduction that should at least be achieved,\n\t// otherwise the block will be returned as incompressible.\n\t// The reduction should then at least be (input size >> WantLogLess)\n\t// If WantLogLess == 0 any improvement will do.\n\tWantLogLess uint8\n\n\tsymbolLen      uint16 // Length of active part of the symbol table.\n\tmaxCount       int    // count of the most probable symbol\n\tclearCount     bool   // clear count\n\tactualTableLog uint8  // Selected tablelog.\n\tprevTableLog   uint8  // Tablelog for previous table\n\tprevTable      cTable // Table used for previous compression.\n\tcTable         cTable // compression table\n\tdt             dTable // decompression table\n\tnodes          []nodeElt\n\ttmpOut         [4][]byte\n\tfse            *fse.Scratch\n\tdecPool        sync.Pool // *[4][256]byte buffers.\n\thuffWeight     [maxSymbolValue + 1]byte\n}\n\n// TransferCTable will transfer the previously used compression table.\nfunc (s *Scratch) TransferCTable(src *Scratch) {\n\tif cap(s.prevTable) < len(src.prevTable) {\n\t\ts.prevTable = make(cTable, 0, maxSymbolValue+1)\n\t}\n\ts.prevTable = s.prevTable[:len(src.prevTable)]\n\tcopy(s.prevTable, src.prevTable)\n\ts.prevTableLog = src.prevTableLog\n}\n\nfunc (s *Scratch) prepare(in []byte) (*Scratch, error) {\n\tif len(in) > BlockSizeMax {\n\t\treturn nil, ErrTooBig\n\t}\n\tif s == nil {\n\t\ts = &Scratch{}\n\t}\n\tif s.MaxSymbolValue == 0 {\n\t\ts.MaxSymbolValue = maxSymbolValue\n\t}\n\tif s.TableLog == 0 {\n\t\ts.TableLog = tableLogDefault\n\t}\n\tif s.TableLog > tableLogMax || s.TableLog < minTablelog {\n\t\treturn nil, fmt.Errorf(\" invalid tableLog %d (%d -> %d)\", s.TableLog, minTablelog, tableLogMax)\n\t}\n\tif s.MaxDecodedSize <= 0 || s.MaxDecodedSize > BlockSizeMax {\n\t\ts.MaxDecodedSize = BlockSizeMax\n\t}\n\tif s.clearCount && s.maxCount == 0 {\n\t\tfor i := range s.count {\n\t\t\ts.count[i] = 0\n\t\t}\n\t\ts.clearCount = false\n\t}\n\tif cap(s.Out) == 0 {\n\t\ts.Out = make([]byte, 0, len(in))\n\t}\n\ts.Out = s.Out[:0]\n\n\ts.OutTable = nil\n\ts.OutData = nil\n\tif cap(s.nodes) < huffNodesLen+1 {\n\t\ts.nodes = make([]nodeElt, 0, huffNodesLen+1)\n\t}\n\ts.nodes = s.nodes[:0]\n\tif s.fse == nil {\n\t\ts.fse = &fse.Scratch{}\n\t}\n\ts.br.init(in)\n\n\treturn s, nil\n}\n\ntype cTable []cTableEntry\n\nfunc (c cTable) write(s *Scratch) error {\n\tvar (\n\t\t// precomputed conversion table\n\t\tbitsToWeight [tableLogMax + 1]byte\n\t\thuffLog      = s.actualTableLog\n\t\t// last weight is not saved.\n\t\tmaxSymbolValue = uint8(s.symbolLen - 1)\n\t\thuffWeight     = s.huffWeight[:256]\n\t)\n\tconst (\n\t\tmaxFSETableLog = 6\n\t)\n\t// convert to weight\n\tbitsToWeight[0] = 0\n\tfor n := uint8(1); n < huffLog+1; n++ {\n\t\tbitsToWeight[n] = huffLog + 1 - n\n\t}\n\n\t// Acquire histogram for FSE.\n\thist := s.fse.Histogram()\n\thist = hist[:256]\n\tfor i := range hist[:16] {\n\t\thist[i] = 0\n\t}\n\tfor n := uint8(0); n < maxSymbolValue; n++ {\n\t\tv := bitsToWeight[c[n].nBits] & 15\n\t\thuffWeight[n] = v\n\t\thist[v]++\n\t}\n\n\t// FSE compress if feasible.\n\tif maxSymbolValue >= 2 {\n\t\thuffMaxCnt := uint32(0)\n\t\thuffMax := uint8(0)\n\t\tfor i, v := range hist[:16] {\n\t\t\tif v == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\thuffMax = byte(i)\n\t\t\tif v > huffMaxCnt {\n\t\t\t\thuffMaxCnt = v\n\t\t\t}\n\t\t}\n\t\ts.fse.HistogramFinished(huffMax, int(huffMaxCnt))\n\t\ts.fse.TableLog = maxFSETableLog\n\t\tb, err := fse.Compress(huffWeight[:maxSymbolValue], s.fse)\n\t\tif err == nil && len(b) < int(s.symbolLen>>1) {\n\t\t\ts.Out = append(s.Out, uint8(len(b)))\n\t\t\ts.Out = append(s.Out, b...)\n\t\t\treturn nil\n\t\t}\n\t\t// Unable to compress (RLE/uncompressible)\n\t}\n\t// write raw values as 4-bits (max : 15)\n\tif maxSymbolValue > (256 - 128) {\n\t\t// should not happen : likely means source cannot be compressed\n\t\treturn ErrIncompressible\n\t}\n\top := s.Out\n\t// special case, pack weights 4 bits/weight.\n\top = append(op, 128|(maxSymbolValue-1))\n\t// be sure it doesn't cause msan issue in final combination\n\thuffWeight[maxSymbolValue] = 0\n\tfor n := uint16(0); n < uint16(maxSymbolValue); n += 2 {\n\t\top = append(op, (huffWeight[n]<<4)|huffWeight[n+1])\n\t}\n\ts.Out = op\n\treturn nil\n}\n\nfunc (c cTable) estTableSize(s *Scratch) (sz int, err error) {\n\tvar (\n\t\t// precomputed conversion table\n\t\tbitsToWeight [tableLogMax + 1]byte\n\t\thuffLog      = s.actualTableLog\n\t\t// last weight is not saved.\n\t\tmaxSymbolValue = uint8(s.symbolLen - 1)\n\t\thuffWeight     = s.huffWeight[:256]\n\t)\n\tconst (\n\t\tmaxFSETableLog = 6\n\t)\n\t// convert to weight\n\tbitsToWeight[0] = 0\n\tfor n := uint8(1); n < huffLog+1; n++ {\n\t\tbitsToWeight[n] = huffLog + 1 - n\n\t}\n\n\t// Acquire histogram for FSE.\n\thist := s.fse.Histogram()\n\thist = hist[:256]\n\tfor i := range hist[:16] {\n\t\thist[i] = 0\n\t}\n\tfor n := uint8(0); n < maxSymbolValue; n++ {\n\t\tv := bitsToWeight[c[n].nBits] & 15\n\t\thuffWeight[n] = v\n\t\thist[v]++\n\t}\n\n\t// FSE compress if feasible.\n\tif maxSymbolValue >= 2 {\n\t\thuffMaxCnt := uint32(0)\n\t\thuffMax := uint8(0)\n\t\tfor i, v := range hist[:16] {\n\t\t\tif v == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\thuffMax = byte(i)\n\t\t\tif v > huffMaxCnt {\n\t\t\t\thuffMaxCnt = v\n\t\t\t}\n\t\t}\n\t\ts.fse.HistogramFinished(huffMax, int(huffMaxCnt))\n\t\ts.fse.TableLog = maxFSETableLog\n\t\tb, err := fse.Compress(huffWeight[:maxSymbolValue], s.fse)\n\t\tif err == nil && len(b) < int(s.symbolLen>>1) {\n\t\t\tsz += 1 + len(b)\n\t\t\treturn sz, nil\n\t\t}\n\t\t// Unable to compress (RLE/uncompressible)\n\t}\n\t// write raw values as 4-bits (max : 15)\n\tif maxSymbolValue > (256 - 128) {\n\t\t// should not happen : likely means source cannot be compressed\n\t\treturn 0, ErrIncompressible\n\t}\n\t// special case, pack weights 4 bits/weight.\n\tsz += 1 + int(maxSymbolValue/2)\n\treturn sz, nil\n}\n\n// estimateSize returns the estimated size in bytes of the input represented in the\n// histogram supplied.\nfunc (c cTable) estimateSize(hist []uint32) int {\n\tnbBits := uint32(7)\n\tfor i, v := range c[:len(hist)] {\n\t\tnbBits += uint32(v.nBits) * hist[i]\n\t}\n\treturn int(nbBits >> 3)\n}\n\n// minSize returns the minimum possible size considering the shannon limit.\nfunc (s *Scratch) minSize(total int) int {\n\tnbBits := float64(7)\n\tfTotal := float64(total)\n\tfor _, v := range s.count[:s.symbolLen] {\n\t\tn := float64(v)\n\t\tif n > 0 {\n\t\t\tnbBits += math.Log2(fTotal/n) * n\n\t\t}\n\t}\n\treturn int(nbBits) >> 3\n}\n\nfunc highBit32(val uint32) (n uint32) {\n\treturn uint32(bits.Len32(val) - 1)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go",
    "content": "// Package cpuinfo gives runtime info about the current CPU.\n//\n// This is a very limited module meant for use internally\n// in this project. For more versatile solution check\n// https://github.com/klauspost/cpuid.\npackage cpuinfo\n\n// HasBMI1 checks whether an x86 CPU supports the BMI1 extension.\nfunc HasBMI1() bool {\n\treturn hasBMI1\n}\n\n// HasBMI2 checks whether an x86 CPU supports the BMI2 extension.\nfunc HasBMI2() bool {\n\treturn hasBMI2\n}\n\n// DisableBMI2 will disable BMI2, for testing purposes.\n// Call returned function to restore previous state.\nfunc DisableBMI2() func() {\n\told := hasBMI2\n\thasBMI2 = false\n\treturn func() {\n\t\thasBMI2 = old\n\t}\n}\n\n// HasBMI checks whether an x86 CPU supports both BMI1 and BMI2 extensions.\nfunc HasBMI() bool {\n\treturn HasBMI1() && HasBMI2()\n}\n\nvar hasBMI1 bool\nvar hasBMI2 bool\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go",
    "content": "//go:build amd64 && !appengine && !noasm && gc\n// +build amd64,!appengine,!noasm,gc\n\npackage cpuinfo\n\n// go:noescape\nfunc x86extensions() (bmi1, bmi2 bool)\n\nfunc init() {\n\thasBMI1, hasBMI2 = x86extensions()\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s",
    "content": "// +build !appengine\n// +build gc\n// +build !noasm\n\n#include \"textflag.h\"\n#include \"funcdata.h\"\n#include \"go_asm.h\"\n\nTEXT ·x86extensions(SB), NOSPLIT, $0\n\t// 1. determine max EAX value\n\tXORQ AX, AX\n\tCPUID\n\n\tCMPQ AX, $7\n\tJB   unsupported\n\n\t// 2. EAX = 7, ECX = 0 --- see Table 3-8 \"Information Returned by CPUID Instruction\"\n\tMOVQ $7, AX\n\tMOVQ $0, CX\n\tCPUID\n\n\tBTQ   $3, BX // bit 3 = BMI1\n\tSETCS AL\n\n\tBTQ   $8, BX // bit 8 = BMI2\n\tSETCS AH\n\n\tMOVB AL, bmi1+0(FP)\n\tMOVB AH, bmi2+1(FP)\n\tRET\n\nunsupported:\n\tXORQ AX, AX\n\tMOVB AL, bmi1+0(FP)\n\tMOVB AL, bmi2+1(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/snapref/LICENSE",
    "content": "Copyright (c) 2011 The Snappy-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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/klauspost/compress/internal/snapref/decode.go",
    "content": "// Copyright 2011 The Snappy-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 snapref\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n)\n\nvar (\n\t// ErrCorrupt reports that the input is invalid.\n\tErrCorrupt = errors.New(\"snappy: corrupt input\")\n\t// ErrTooLarge reports that the uncompressed length is too large.\n\tErrTooLarge = errors.New(\"snappy: decoded block is too large\")\n\t// ErrUnsupported reports that the input isn't supported.\n\tErrUnsupported = errors.New(\"snappy: unsupported input\")\n\n\terrUnsupportedLiteralLength = errors.New(\"snappy: unsupported literal length\")\n)\n\n// DecodedLen returns the length of the decoded block.\nfunc DecodedLen(src []byte) (int, error) {\n\tv, _, err := decodedLen(src)\n\treturn v, err\n}\n\n// decodedLen returns the length of the decoded block and the number of bytes\n// that the length header occupied.\nfunc decodedLen(src []byte) (blockLen, headerLen int, err error) {\n\tv, n := binary.Uvarint(src)\n\tif n <= 0 || v > 0xffffffff {\n\t\treturn 0, 0, ErrCorrupt\n\t}\n\n\tconst wordSize = 32 << (^uint(0) >> 32 & 1)\n\tif wordSize == 32 && v > 0x7fffffff {\n\t\treturn 0, 0, ErrTooLarge\n\t}\n\treturn int(v), n, nil\n}\n\nconst (\n\tdecodeErrCodeCorrupt                  = 1\n\tdecodeErrCodeUnsupportedLiteralLength = 2\n)\n\n// Decode returns the decoded form of src. The returned slice may be a sub-\n// slice of dst if dst was large enough to hold the entire decoded block.\n// Otherwise, a newly allocated slice will be returned.\n//\n// The dst and src must not overlap. It is valid to pass a nil dst.\n//\n// Decode handles the Snappy block format, not the Snappy stream format.\nfunc Decode(dst, src []byte) ([]byte, error) {\n\tdLen, s, err := decodedLen(src)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif dLen <= len(dst) {\n\t\tdst = dst[:dLen]\n\t} else {\n\t\tdst = make([]byte, dLen)\n\t}\n\tswitch decode(dst, src[s:]) {\n\tcase 0:\n\t\treturn dst, nil\n\tcase decodeErrCodeUnsupportedLiteralLength:\n\t\treturn nil, errUnsupportedLiteralLength\n\t}\n\treturn nil, ErrCorrupt\n}\n\n// NewReader returns a new Reader that decompresses from r, using the framing\n// format described at\n// https://github.com/google/snappy/blob/master/framing_format.txt\nfunc NewReader(r io.Reader) *Reader {\n\treturn &Reader{\n\t\tr:       r,\n\t\tdecoded: make([]byte, maxBlockSize),\n\t\tbuf:     make([]byte, maxEncodedLenOfMaxBlockSize+checksumSize),\n\t}\n}\n\n// Reader is an io.Reader that can read Snappy-compressed bytes.\n//\n// Reader handles the Snappy stream format, not the Snappy block format.\ntype Reader struct {\n\tr       io.Reader\n\terr     error\n\tdecoded []byte\n\tbuf     []byte\n\t// decoded[i:j] contains decoded bytes that have not yet been passed on.\n\ti, j       int\n\treadHeader bool\n}\n\n// Reset discards any buffered data, resets all state, and switches the Snappy\n// reader to read from r. This permits reusing a Reader rather than allocating\n// a new one.\nfunc (r *Reader) Reset(reader io.Reader) {\n\tr.r = reader\n\tr.err = nil\n\tr.i = 0\n\tr.j = 0\n\tr.readHeader = false\n}\n\nfunc (r *Reader) readFull(p []byte, allowEOF bool) (ok bool) {\n\tif _, r.err = io.ReadFull(r.r, p); r.err != nil {\n\t\tif r.err == io.ErrUnexpectedEOF || (r.err == io.EOF && !allowEOF) {\n\t\t\tr.err = ErrCorrupt\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (r *Reader) fill() error {\n\tfor r.i >= r.j {\n\t\tif !r.readFull(r.buf[:4], true) {\n\t\t\treturn r.err\n\t\t}\n\t\tchunkType := r.buf[0]\n\t\tif !r.readHeader {\n\t\t\tif chunkType != chunkTypeStreamIdentifier {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tr.readHeader = true\n\t\t}\n\t\tchunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16\n\t\tif chunkLen > len(r.buf) {\n\t\t\tr.err = ErrUnsupported\n\t\t\treturn r.err\n\t\t}\n\n\t\t// The chunk types are specified at\n\t\t// https://github.com/google/snappy/blob/master/framing_format.txt\n\t\tswitch chunkType {\n\t\tcase chunkTypeCompressedData:\n\t\t\t// Section 4.2. Compressed data (chunk type 0x00).\n\t\t\tif chunkLen < checksumSize {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tbuf := r.buf[:chunkLen]\n\t\t\tif !r.readFull(buf, false) {\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tchecksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24\n\t\t\tbuf = buf[checksumSize:]\n\n\t\t\tn, err := DecodedLen(buf)\n\t\t\tif err != nil {\n\t\t\t\tr.err = err\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tif n > len(r.decoded) {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tif _, err := Decode(r.decoded, buf); err != nil {\n\t\t\t\tr.err = err\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tif crc(r.decoded[:n]) != checksum {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tr.i, r.j = 0, n\n\t\t\tcontinue\n\n\t\tcase chunkTypeUncompressedData:\n\t\t\t// Section 4.3. Uncompressed data (chunk type 0x01).\n\t\t\tif chunkLen < checksumSize {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tbuf := r.buf[:checksumSize]\n\t\t\tif !r.readFull(buf, false) {\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tchecksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24\n\t\t\t// Read directly into r.decoded instead of via r.buf.\n\t\t\tn := chunkLen - checksumSize\n\t\t\tif n > len(r.decoded) {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tif !r.readFull(r.decoded[:n], false) {\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tif crc(r.decoded[:n]) != checksum {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tr.i, r.j = 0, n\n\t\t\tcontinue\n\n\t\tcase chunkTypeStreamIdentifier:\n\t\t\t// Section 4.1. Stream identifier (chunk type 0xff).\n\t\t\tif chunkLen != len(magicBody) {\n\t\t\t\tr.err = ErrCorrupt\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tif !r.readFull(r.buf[:len(magicBody)], false) {\n\t\t\t\treturn r.err\n\t\t\t}\n\t\t\tfor i := 0; i < len(magicBody); i++ {\n\t\t\t\tif r.buf[i] != magicBody[i] {\n\t\t\t\t\tr.err = ErrCorrupt\n\t\t\t\t\treturn r.err\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif chunkType <= 0x7f {\n\t\t\t// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).\n\t\t\tr.err = ErrUnsupported\n\t\t\treturn r.err\n\t\t}\n\t\t// Section 4.4 Padding (chunk type 0xfe).\n\t\t// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).\n\t\tif !r.readFull(r.buf[:chunkLen], false) {\n\t\t\treturn r.err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Read satisfies the io.Reader interface.\nfunc (r *Reader) Read(p []byte) (int, error) {\n\tif r.err != nil {\n\t\treturn 0, r.err\n\t}\n\n\tif err := r.fill(); err != nil {\n\t\treturn 0, err\n\t}\n\n\tn := copy(p, r.decoded[r.i:r.j])\n\tr.i += n\n\treturn n, nil\n}\n\n// ReadByte satisfies the io.ByteReader interface.\nfunc (r *Reader) ReadByte() (byte, error) {\n\tif r.err != nil {\n\t\treturn 0, r.err\n\t}\n\n\tif err := r.fill(); err != nil {\n\t\treturn 0, err\n\t}\n\n\tc := r.decoded[r.i]\n\tr.i++\n\treturn c, nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/snapref/decode_other.go",
    "content": "// Copyright 2016 The Snappy-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 snapref\n\n// decode writes the decoding of src to dst. It assumes that the varint-encoded\n// length of the decompressed bytes has already been read, and that len(dst)\n// equals that length.\n//\n// It returns 0 on success or a decodeErrCodeXxx error code on failure.\nfunc decode(dst, src []byte) int {\n\tvar d, s, offset, length int\n\tfor s < len(src) {\n\t\tswitch src[s] & 0x03 {\n\t\tcase tagLiteral:\n\t\t\tx := uint32(src[s] >> 2)\n\t\t\tswitch {\n\t\t\tcase x < 60:\n\t\t\t\ts++\n\t\t\tcase x == 60:\n\t\t\t\ts += 2\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-1])\n\t\t\tcase x == 61:\n\t\t\t\ts += 3\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-2]) | uint32(src[s-1])<<8\n\t\t\tcase x == 62:\n\t\t\t\ts += 4\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16\n\t\t\tcase x == 63:\n\t\t\t\ts += 5\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24\n\t\t\t}\n\t\t\tlength = int(x) + 1\n\t\t\tif length <= 0 {\n\t\t\t\treturn decodeErrCodeUnsupportedLiteralLength\n\t\t\t}\n\t\t\tif length > len(dst)-d || length > len(src)-s {\n\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t}\n\t\t\tcopy(dst[d:], src[s:s+length])\n\t\t\td += length\n\t\t\ts += length\n\t\t\tcontinue\n\n\t\tcase tagCopy1:\n\t\t\ts += 2\n\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t}\n\t\t\tlength = 4 + int(src[s-2])>>2&0x7\n\t\t\toffset = int(uint32(src[s-2])&0xe0<<3 | uint32(src[s-1]))\n\n\t\tcase tagCopy2:\n\t\t\ts += 3\n\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t}\n\t\t\tlength = 1 + int(src[s-3])>>2\n\t\t\toffset = int(uint32(src[s-2]) | uint32(src[s-1])<<8)\n\n\t\tcase tagCopy4:\n\t\t\ts += 5\n\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\treturn decodeErrCodeCorrupt\n\t\t\t}\n\t\t\tlength = 1 + int(src[s-5])>>2\n\t\t\toffset = int(uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24)\n\t\t}\n\n\t\tif offset <= 0 || d < offset || length > len(dst)-d {\n\t\t\treturn decodeErrCodeCorrupt\n\t\t}\n\t\t// Copy from an earlier sub-slice of dst to a later sub-slice.\n\t\t// If no overlap, use the built-in copy:\n\t\tif offset >= length {\n\t\t\tcopy(dst[d:d+length], dst[d-offset:])\n\t\t\td += length\n\t\t\tcontinue\n\t\t}\n\n\t\t// Unlike the built-in copy function, this byte-by-byte copy always runs\n\t\t// forwards, even if the slices overlap. Conceptually, this is:\n\t\t//\n\t\t// d += forwardCopy(dst[d:d+length], dst[d-offset:])\n\t\t//\n\t\t// We align the slices into a and b and show the compiler they are the same size.\n\t\t// This allows the loop to run without bounds checks.\n\t\ta := dst[d : d+length]\n\t\tb := dst[d-offset:]\n\t\tb = b[:len(a)]\n\t\tfor i := range a {\n\t\t\ta[i] = b[i]\n\t\t}\n\t\td += length\n\t}\n\tif d != len(dst) {\n\t\treturn decodeErrCodeCorrupt\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/snapref/encode.go",
    "content": "// Copyright 2011 The Snappy-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 snapref\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n)\n\n// Encode returns the encoded form of src. The returned slice may be a sub-\n// slice of dst if dst was large enough to hold the entire encoded block.\n// Otherwise, a newly allocated slice will be returned.\n//\n// The dst and src must not overlap. It is valid to pass a nil dst.\n//\n// Encode handles the Snappy block format, not the Snappy stream format.\nfunc Encode(dst, src []byte) []byte {\n\tif n := MaxEncodedLen(len(src)); n < 0 {\n\t\tpanic(ErrTooLarge)\n\t} else if len(dst) < n {\n\t\tdst = make([]byte, n)\n\t}\n\n\t// The block starts with the varint-encoded length of the decompressed bytes.\n\td := binary.PutUvarint(dst, uint64(len(src)))\n\n\tfor len(src) > 0 {\n\t\tp := src\n\t\tsrc = nil\n\t\tif len(p) > maxBlockSize {\n\t\t\tp, src = p[:maxBlockSize], p[maxBlockSize:]\n\t\t}\n\t\tif len(p) < minNonLiteralBlockSize {\n\t\t\td += emitLiteral(dst[d:], p)\n\t\t} else {\n\t\t\td += encodeBlock(dst[d:], p)\n\t\t}\n\t}\n\treturn dst[:d]\n}\n\n// inputMargin is the minimum number of extra input bytes to keep, inside\n// encodeBlock's inner loop. On some architectures, this margin lets us\n// implement a fast path for emitLiteral, where the copy of short (<= 16 byte)\n// literals can be implemented as a single load to and store from a 16-byte\n// register. That literal's actual length can be as short as 1 byte, so this\n// can copy up to 15 bytes too much, but that's OK as subsequent iterations of\n// the encoding loop will fix up the copy overrun, and this inputMargin ensures\n// that we don't overrun the dst and src buffers.\nconst inputMargin = 16 - 1\n\n// minNonLiteralBlockSize is the minimum size of the input to encodeBlock that\n// could be encoded with a copy tag. This is the minimum with respect to the\n// algorithm used by encodeBlock, not a minimum enforced by the file format.\n//\n// The encoded output must start with at least a 1 byte literal, as there are\n// no previous bytes to copy. A minimal (1 byte) copy after that, generated\n// from an emitCopy call in encodeBlock's main loop, would require at least\n// another inputMargin bytes, for the reason above: we want any emitLiteral\n// calls inside encodeBlock's main loop to use the fast path if possible, which\n// requires being able to overrun by inputMargin bytes. Thus,\n// minNonLiteralBlockSize equals 1 + 1 + inputMargin.\n//\n// The C++ code doesn't use this exact threshold, but it could, as discussed at\n// https://groups.google.com/d/topic/snappy-compression/oGbhsdIJSJ8/discussion\n// The difference between Go (2+inputMargin) and C++ (inputMargin) is purely an\n// optimization. It should not affect the encoded form. This is tested by\n// TestSameEncodingAsCppShortCopies.\nconst minNonLiteralBlockSize = 1 + 1 + inputMargin\n\n// MaxEncodedLen returns the maximum length of a snappy block, given its\n// uncompressed length.\n//\n// It will return a negative value if srcLen is too large to encode.\nfunc MaxEncodedLen(srcLen int) int {\n\tn := uint64(srcLen)\n\tif n > 0xffffffff {\n\t\treturn -1\n\t}\n\t// Compressed data can be defined as:\n\t//    compressed := item* literal*\n\t//    item       := literal* copy\n\t//\n\t// The trailing literal sequence has a space blowup of at most 62/60\n\t// since a literal of length 60 needs one tag byte + one extra byte\n\t// for length information.\n\t//\n\t// Item blowup is trickier to measure. Suppose the \"copy\" op copies\n\t// 4 bytes of data. Because of a special check in the encoding code,\n\t// we produce a 4-byte copy only if the offset is < 65536. Therefore\n\t// the copy op takes 3 bytes to encode, and this type of item leads\n\t// to at most the 62/60 blowup for representing literals.\n\t//\n\t// Suppose the \"copy\" op copies 5 bytes of data. If the offset is big\n\t// enough, it will take 5 bytes to encode the copy op. Therefore the\n\t// worst case here is a one-byte literal followed by a five-byte copy.\n\t// That is, 6 bytes of input turn into 7 bytes of \"compressed\" data.\n\t//\n\t// This last factor dominates the blowup, so the final estimate is:\n\tn = 32 + n + n/6\n\tif n > 0xffffffff {\n\t\treturn -1\n\t}\n\treturn int(n)\n}\n\nvar errClosed = errors.New(\"snappy: Writer is closed\")\n\n// NewWriter returns a new Writer that compresses to w.\n//\n// The Writer returned does not buffer writes. There is no need to Flush or\n// Close such a Writer.\n//\n// Deprecated: the Writer returned is not suitable for many small writes, only\n// for few large writes. Use NewBufferedWriter instead, which is efficient\n// regardless of the frequency and shape of the writes, and remember to Close\n// that Writer when done.\nfunc NewWriter(w io.Writer) *Writer {\n\treturn &Writer{\n\t\tw:    w,\n\t\tobuf: make([]byte, obufLen),\n\t}\n}\n\n// NewBufferedWriter returns a new Writer that compresses to w, using the\n// framing format described at\n// https://github.com/google/snappy/blob/master/framing_format.txt\n//\n// The Writer returned buffers writes. Users must call Close to guarantee all\n// data has been forwarded to the underlying io.Writer. They may also call\n// Flush zero or more times before calling Close.\nfunc NewBufferedWriter(w io.Writer) *Writer {\n\treturn &Writer{\n\t\tw:    w,\n\t\tibuf: make([]byte, 0, maxBlockSize),\n\t\tobuf: make([]byte, obufLen),\n\t}\n}\n\n// Writer is an io.Writer that can write Snappy-compressed bytes.\n//\n// Writer handles the Snappy stream format, not the Snappy block format.\ntype Writer struct {\n\tw   io.Writer\n\terr error\n\n\t// ibuf is a buffer for the incoming (uncompressed) bytes.\n\t//\n\t// Its use is optional. For backwards compatibility, Writers created by the\n\t// NewWriter function have ibuf == nil, do not buffer incoming bytes, and\n\t// therefore do not need to be Flush'ed or Close'd.\n\tibuf []byte\n\n\t// obuf is a buffer for the outgoing (compressed) bytes.\n\tobuf []byte\n\n\t// wroteStreamHeader is whether we have written the stream header.\n\twroteStreamHeader bool\n}\n\n// Reset discards the writer's state and switches the Snappy writer to write to\n// w. This permits reusing a Writer rather than allocating a new one.\nfunc (w *Writer) Reset(writer io.Writer) {\n\tw.w = writer\n\tw.err = nil\n\tif w.ibuf != nil {\n\t\tw.ibuf = w.ibuf[:0]\n\t}\n\tw.wroteStreamHeader = false\n}\n\n// Write satisfies the io.Writer interface.\nfunc (w *Writer) Write(p []byte) (nRet int, errRet error) {\n\tif w.ibuf == nil {\n\t\t// Do not buffer incoming bytes. This does not perform or compress well\n\t\t// if the caller of Writer.Write writes many small slices. This\n\t\t// behavior is therefore deprecated, but still supported for backwards\n\t\t// compatibility with code that doesn't explicitly Flush or Close.\n\t\treturn w.write(p)\n\t}\n\n\t// The remainder of this method is based on bufio.Writer.Write from the\n\t// standard library.\n\n\tfor len(p) > (cap(w.ibuf)-len(w.ibuf)) && w.err == nil {\n\t\tvar n int\n\t\tif len(w.ibuf) == 0 {\n\t\t\t// Large write, empty buffer.\n\t\t\t// Write directly from p to avoid copy.\n\t\t\tn, _ = w.write(p)\n\t\t} else {\n\t\t\tn = copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p)\n\t\t\tw.ibuf = w.ibuf[:len(w.ibuf)+n]\n\t\t\tw.Flush()\n\t\t}\n\t\tnRet += n\n\t\tp = p[n:]\n\t}\n\tif w.err != nil {\n\t\treturn nRet, w.err\n\t}\n\tn := copy(w.ibuf[len(w.ibuf):cap(w.ibuf)], p)\n\tw.ibuf = w.ibuf[:len(w.ibuf)+n]\n\tnRet += n\n\treturn nRet, nil\n}\n\nfunc (w *Writer) write(p []byte) (nRet int, errRet error) {\n\tif w.err != nil {\n\t\treturn 0, w.err\n\t}\n\tfor len(p) > 0 {\n\t\tobufStart := len(magicChunk)\n\t\tif !w.wroteStreamHeader {\n\t\t\tw.wroteStreamHeader = true\n\t\t\tcopy(w.obuf, magicChunk)\n\t\t\tobufStart = 0\n\t\t}\n\n\t\tvar uncompressed []byte\n\t\tif len(p) > maxBlockSize {\n\t\t\tuncompressed, p = p[:maxBlockSize], p[maxBlockSize:]\n\t\t} else {\n\t\t\tuncompressed, p = p, nil\n\t\t}\n\t\tchecksum := crc(uncompressed)\n\n\t\t// Compress the buffer, discarding the result if the improvement\n\t\t// isn't at least 12.5%.\n\t\tcompressed := Encode(w.obuf[obufHeaderLen:], uncompressed)\n\t\tchunkType := uint8(chunkTypeCompressedData)\n\t\tchunkLen := 4 + len(compressed)\n\t\tobufEnd := obufHeaderLen + len(compressed)\n\t\tif len(compressed) >= len(uncompressed)-len(uncompressed)/8 {\n\t\t\tchunkType = chunkTypeUncompressedData\n\t\t\tchunkLen = 4 + len(uncompressed)\n\t\t\tobufEnd = obufHeaderLen\n\t\t}\n\n\t\t// Fill in the per-chunk header that comes before the body.\n\t\tw.obuf[len(magicChunk)+0] = chunkType\n\t\tw.obuf[len(magicChunk)+1] = uint8(chunkLen >> 0)\n\t\tw.obuf[len(magicChunk)+2] = uint8(chunkLen >> 8)\n\t\tw.obuf[len(magicChunk)+3] = uint8(chunkLen >> 16)\n\t\tw.obuf[len(magicChunk)+4] = uint8(checksum >> 0)\n\t\tw.obuf[len(magicChunk)+5] = uint8(checksum >> 8)\n\t\tw.obuf[len(magicChunk)+6] = uint8(checksum >> 16)\n\t\tw.obuf[len(magicChunk)+7] = uint8(checksum >> 24)\n\n\t\tif _, err := w.w.Write(w.obuf[obufStart:obufEnd]); err != nil {\n\t\t\tw.err = err\n\t\t\treturn nRet, err\n\t\t}\n\t\tif chunkType == chunkTypeUncompressedData {\n\t\t\tif _, err := w.w.Write(uncompressed); err != nil {\n\t\t\t\tw.err = err\n\t\t\t\treturn nRet, err\n\t\t\t}\n\t\t}\n\t\tnRet += len(uncompressed)\n\t}\n\treturn nRet, nil\n}\n\n// Flush flushes the Writer to its underlying io.Writer.\nfunc (w *Writer) Flush() error {\n\tif w.err != nil {\n\t\treturn w.err\n\t}\n\tif len(w.ibuf) == 0 {\n\t\treturn nil\n\t}\n\tw.write(w.ibuf)\n\tw.ibuf = w.ibuf[:0]\n\treturn w.err\n}\n\n// Close calls Flush and then closes the Writer.\nfunc (w *Writer) Close() error {\n\tw.Flush()\n\tret := w.err\n\tif w.err == nil {\n\t\tw.err = errClosed\n\t}\n\treturn ret\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/snapref/encode_other.go",
    "content": "// Copyright 2016 The Snappy-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 snapref\n\nfunc load32(b []byte, i int) uint32 {\n\tb = b[i : i+4 : len(b)] // Help the compiler eliminate bounds checks on the next line.\n\treturn uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24\n}\n\nfunc load64(b []byte, i int) uint64 {\n\tb = b[i : i+8 : len(b)] // Help the compiler eliminate bounds checks on the next line.\n\treturn uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |\n\t\tuint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56\n}\n\n// emitLiteral writes a literal chunk and returns the number of bytes written.\n//\n// It assumes that:\n//\n//\tdst is long enough to hold the encoded bytes\n//\t1 <= len(lit) && len(lit) <= 65536\nfunc emitLiteral(dst, lit []byte) int {\n\ti, n := 0, uint(len(lit)-1)\n\tswitch {\n\tcase n < 60:\n\t\tdst[0] = uint8(n)<<2 | tagLiteral\n\t\ti = 1\n\tcase n < 1<<8:\n\t\tdst[0] = 60<<2 | tagLiteral\n\t\tdst[1] = uint8(n)\n\t\ti = 2\n\tdefault:\n\t\tdst[0] = 61<<2 | tagLiteral\n\t\tdst[1] = uint8(n)\n\t\tdst[2] = uint8(n >> 8)\n\t\ti = 3\n\t}\n\treturn i + copy(dst[i:], lit)\n}\n\n// emitCopy writes a copy chunk and returns the number of bytes written.\n//\n// It assumes that:\n//\n//\tdst is long enough to hold the encoded bytes\n//\t1 <= offset && offset <= 65535\n//\t4 <= length && length <= 65535\nfunc emitCopy(dst []byte, offset, length int) int {\n\ti := 0\n\t// The maximum length for a single tagCopy1 or tagCopy2 op is 64 bytes. The\n\t// threshold for this loop is a little higher (at 68 = 64 + 4), and the\n\t// length emitted down below is is a little lower (at 60 = 64 - 4), because\n\t// it's shorter to encode a length 67 copy as a length 60 tagCopy2 followed\n\t// by a length 7 tagCopy1 (which encodes as 3+2 bytes) than to encode it as\n\t// a length 64 tagCopy2 followed by a length 3 tagCopy2 (which encodes as\n\t// 3+3 bytes). The magic 4 in the 64±4 is because the minimum length for a\n\t// tagCopy1 op is 4 bytes, which is why a length 3 copy has to be an\n\t// encodes-as-3-bytes tagCopy2 instead of an encodes-as-2-bytes tagCopy1.\n\tfor length >= 68 {\n\t\t// Emit a length 64 copy, encoded as 3 bytes.\n\t\tdst[i+0] = 63<<2 | tagCopy2\n\t\tdst[i+1] = uint8(offset)\n\t\tdst[i+2] = uint8(offset >> 8)\n\t\ti += 3\n\t\tlength -= 64\n\t}\n\tif length > 64 {\n\t\t// Emit a length 60 copy, encoded as 3 bytes.\n\t\tdst[i+0] = 59<<2 | tagCopy2\n\t\tdst[i+1] = uint8(offset)\n\t\tdst[i+2] = uint8(offset >> 8)\n\t\ti += 3\n\t\tlength -= 60\n\t}\n\tif length >= 12 || offset >= 2048 {\n\t\t// Emit the remaining copy, encoded as 3 bytes.\n\t\tdst[i+0] = uint8(length-1)<<2 | tagCopy2\n\t\tdst[i+1] = uint8(offset)\n\t\tdst[i+2] = uint8(offset >> 8)\n\t\treturn i + 3\n\t}\n\t// Emit the remaining copy, encoded as 2 bytes.\n\tdst[i+0] = uint8(offset>>8)<<5 | uint8(length-4)<<2 | tagCopy1\n\tdst[i+1] = uint8(offset)\n\treturn i + 2\n}\n\nfunc hash(u, shift uint32) uint32 {\n\treturn (u * 0x1e35a7bd) >> shift\n}\n\n// EncodeBlockInto exposes encodeBlock but checks dst size.\nfunc EncodeBlockInto(dst, src []byte) (d int) {\n\tif MaxEncodedLen(len(src)) > len(dst) {\n\t\treturn 0\n\t}\n\n\t// encodeBlock breaks on too big blocks, so split.\n\tfor len(src) > 0 {\n\t\tp := src\n\t\tsrc = nil\n\t\tif len(p) > maxBlockSize {\n\t\t\tp, src = p[:maxBlockSize], p[maxBlockSize:]\n\t\t}\n\t\tif len(p) < minNonLiteralBlockSize {\n\t\t\td += emitLiteral(dst[d:], p)\n\t\t} else {\n\t\t\td += encodeBlock(dst[d:], p)\n\t\t}\n\t}\n\treturn d\n}\n\n// encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It\n// assumes that the varint-encoded length of the decompressed bytes has already\n// been written.\n//\n// It also assumes that:\n//\n//\tlen(dst) >= MaxEncodedLen(len(src)) &&\n//\tminNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize\nfunc encodeBlock(dst, src []byte) (d int) {\n\t// Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive.\n\t// The table element type is uint16, as s < sLimit and sLimit < len(src)\n\t// and len(src) <= maxBlockSize and maxBlockSize == 65536.\n\tconst (\n\t\tmaxTableSize = 1 << 14\n\t\t// tableMask is redundant, but helps the compiler eliminate bounds\n\t\t// checks.\n\t\ttableMask = maxTableSize - 1\n\t)\n\tshift := uint32(32 - 8)\n\tfor tableSize := 1 << 8; tableSize < maxTableSize && tableSize < len(src); tableSize *= 2 {\n\t\tshift--\n\t}\n\t// In Go, all array elements are zero-initialized, so there is no advantage\n\t// to a smaller tableSize per se. However, it matches the C++ algorithm,\n\t// and in the asm versions of this code, we can get away with zeroing only\n\t// the first tableSize elements.\n\tvar table [maxTableSize]uint16\n\n\t// sLimit is when to stop looking for offset/length copies. The inputMargin\n\t// lets us use a fast path for emitLiteral in the main loop, while we are\n\t// looking for copies.\n\tsLimit := len(src) - inputMargin\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := 0\n\n\t// The encoded form must start with a literal, as there are no previous\n\t// bytes to copy, so we start looking for hash matches at s == 1.\n\ts := 1\n\tnextHash := hash(load32(src, s), shift)\n\n\tfor {\n\t\t// Copied from the C++ snappy implementation:\n\t\t//\n\t\t// Heuristic match skipping: If 32 bytes are scanned with no matches\n\t\t// found, start looking only at every other byte. If 32 more bytes are\n\t\t// scanned (or skipped), look at every third byte, etc.. When a match\n\t\t// is found, immediately go back to looking at every byte. This is a\n\t\t// small loss (~5% performance, ~0.1% density) for compressible data\n\t\t// due to more bookkeeping, but for non-compressible data (such as\n\t\t// JPEG) it's a huge win since the compressor quickly \"realizes\" the\n\t\t// data is incompressible and doesn't bother looking for matches\n\t\t// everywhere.\n\t\t//\n\t\t// The \"skip\" variable keeps track of how many bytes there are since\n\t\t// the last match; dividing it by 32 (ie. right-shifting by five) gives\n\t\t// the number of bytes to move ahead for each iteration.\n\t\tskip := 32\n\n\t\tnextS := s\n\t\tcandidate := 0\n\t\tfor {\n\t\t\ts = nextS\n\t\t\tbytesBetweenHashLookups := skip >> 5\n\t\t\tnextS = s + bytesBetweenHashLookups\n\t\t\tskip += bytesBetweenHashLookups\n\t\t\tif nextS > sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\t\t\tcandidate = int(table[nextHash&tableMask])\n\t\t\ttable[nextHash&tableMask] = uint16(s)\n\t\t\tnextHash = hash(load32(src, nextS), shift)\n\t\t\tif load32(src, s) == load32(src, candidate) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes\n\t\t// match. But, prior to the match, src[nextEmit:s] are unmatched. Emit\n\t\t// them as literal bytes.\n\t\td += emitLiteral(dst[d:], src[nextEmit:s])\n\n\t\t// Call emitCopy, and then see if another emitCopy could be our next\n\t\t// move. Repeat until we find no match for the input immediately after\n\t\t// what was consumed by the last emitCopy call.\n\t\t//\n\t\t// If we exit this loop normally then we need to call emitLiteral next,\n\t\t// though we don't yet know how big the literal will be. We handle that\n\t\t// by proceeding to the next iteration of the main loop. We also can\n\t\t// exit this loop via goto if we get close to exhausting the input.\n\t\tfor {\n\t\t\t// Invariant: we have a 4-byte match at s, and no need to emit any\n\t\t\t// literal bytes prior to s.\n\t\t\tbase := s\n\n\t\t\t// Extend the 4-byte match as long as possible.\n\t\t\t//\n\t\t\t// This is an inlined version of:\n\t\t\t//\ts = extendMatch(src, candidate+4, s+4)\n\t\t\ts += 4\n\t\t\tfor i := candidate + 4; s < len(src) && src[i] == src[s]; i, s = i+1, s+1 {\n\t\t\t}\n\n\t\t\td += emitCopy(dst[d:], base-candidate, s-base)\n\t\t\tnextEmit = s\n\t\t\tif s >= sLimit {\n\t\t\t\tgoto emitRemainder\n\t\t\t}\n\n\t\t\t// We could immediately start working at s now, but to improve\n\t\t\t// compression we first update the hash table at s-1 and at s. If\n\t\t\t// another emitCopy is not our next move, also calculate nextHash\n\t\t\t// at s+1. At least on GOARCH=amd64, these three hash calculations\n\t\t\t// are faster as one load64 call (with some shifts) instead of\n\t\t\t// three load32 calls.\n\t\t\tx := load64(src, s-1)\n\t\t\tprevHash := hash(uint32(x>>0), shift)\n\t\t\ttable[prevHash&tableMask] = uint16(s - 1)\n\t\t\tcurrHash := hash(uint32(x>>8), shift)\n\t\t\tcandidate = int(table[currHash&tableMask])\n\t\t\ttable[currHash&tableMask] = uint16(s)\n\t\t\tif uint32(x>>8) != load32(src, candidate) {\n\t\t\t\tnextHash = hash(uint32(x>>16), shift)\n\t\t\t\ts++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\nemitRemainder:\n\tif nextEmit < len(src) {\n\t\td += emitLiteral(dst[d:], src[nextEmit:])\n\t}\n\treturn d\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/internal/snapref/snappy.go",
    "content": "// Copyright 2011 The Snappy-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// Package snapref implements the Snappy compression format. It aims for very\n// high speeds and reasonable compression.\n//\n// There are actually two Snappy formats: block and stream. They are related,\n// but different: trying to decompress block-compressed data as a Snappy stream\n// will fail, and vice versa. The block format is the Decode and Encode\n// functions and the stream format is the Reader and Writer types.\n//\n// The block format, the more common case, is used when the complete size (the\n// number of bytes) of the original data is known upfront, at the time\n// compression starts. The stream format, also known as the framing format, is\n// for when that isn't always true.\n//\n// The canonical, C++ implementation is at https://github.com/google/snappy and\n// it only implements the block format.\npackage snapref\n\nimport (\n\t\"hash/crc32\"\n)\n\n/*\nEach encoded block begins with the varint-encoded length of the decoded data,\nfollowed by a sequence of chunks. Chunks begin and end on byte boundaries. The\nfirst byte of each chunk is broken into its 2 least and 6 most significant bits\ncalled l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag.\nZero means a literal tag. All other values mean a copy tag.\n\nFor literal tags:\n  - If m < 60, the next 1 + m bytes are literal bytes.\n  - Otherwise, let n be the little-endian unsigned integer denoted by the next\n    m - 59 bytes. The next 1 + n bytes after that are literal bytes.\n\nFor copy tags, length bytes are copied from offset bytes ago, in the style of\nLempel-Ziv compression algorithms. In particular:\n  - For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12).\n    The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10\n    of the offset. The next byte is bits 0-7 of the offset.\n  - For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65).\n    The length is 1 + m. The offset is the little-endian unsigned integer\n    denoted by the next 2 bytes.\n  - For l == 3, this tag is a legacy format that is no longer issued by most\n    encoders. Nonetheless, the offset ranges in [0, 1<<32) and the length in\n    [1, 65). The length is 1 + m. The offset is the little-endian unsigned\n    integer denoted by the next 4 bytes.\n*/\nconst (\n\ttagLiteral = 0x00\n\ttagCopy1   = 0x01\n\ttagCopy2   = 0x02\n\ttagCopy4   = 0x03\n)\n\nconst (\n\tchecksumSize    = 4\n\tchunkHeaderSize = 4\n\tmagicChunk      = \"\\xff\\x06\\x00\\x00\" + magicBody\n\tmagicBody       = \"sNaPpY\"\n\n\t// maxBlockSize is the maximum size of the input to encodeBlock. It is not\n\t// part of the wire format per se, but some parts of the encoder assume\n\t// that an offset fits into a uint16.\n\t//\n\t// Also, for the framing format (Writer type instead of Encode function),\n\t// https://github.com/google/snappy/blob/master/framing_format.txt says\n\t// that \"the uncompressed data in a chunk must be no longer than 65536\n\t// bytes\".\n\tmaxBlockSize = 65536\n\n\t// maxEncodedLenOfMaxBlockSize equals MaxEncodedLen(maxBlockSize), but is\n\t// hard coded to be a const instead of a variable, so that obufLen can also\n\t// be a const. Their equivalence is confirmed by\n\t// TestMaxEncodedLenOfMaxBlockSize.\n\tmaxEncodedLenOfMaxBlockSize = 76490\n\n\tobufHeaderLen = len(magicChunk) + checksumSize + chunkHeaderSize\n\tobufLen       = obufHeaderLen + maxEncodedLenOfMaxBlockSize\n)\n\nconst (\n\tchunkTypeCompressedData   = 0x00\n\tchunkTypeUncompressedData = 0x01\n\tchunkTypePadding          = 0xfe\n\tchunkTypeStreamIdentifier = 0xff\n)\n\nvar crcTable = crc32.MakeTable(crc32.Castagnoli)\n\n// crc implements the checksum specified in section 3 of\n// https://github.com/google/snappy/blob/master/framing_format.txt\nfunc crc(b []byte) uint32 {\n\tc := crc32.Update(0, crcTable, b)\n\treturn uint32(c>>15|c<<17) + 0xa282ead8\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/s2sx.mod",
    "content": "module github.com/klauspost/compress\n\ngo 1.16\n\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/s2sx.sum",
    "content": ""
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/README.md",
    "content": "# zstd \n\n[Zstandard](https://facebook.github.io/zstd/) is a real-time compression algorithm, providing high compression ratios. \nIt offers a very wide range of compression / speed trade-off, while being backed by a very fast decoder.\nA high performance compression algorithm is implemented. For now focused on speed. \n\nThis package provides [compression](#Compressor) to and [decompression](#Decompressor) of Zstandard content. \n\nThis package is pure Go and without use of \"unsafe\". \n\nThe `zstd` package is provided as open source software using a Go standard license.\n\nCurrently the package is heavily optimized for 64 bit processors and will be significantly slower on 32 bit processors.\n\nFor seekable zstd streams, see [this excellent package](https://github.com/SaveTheRbtz/zstd-seekable-format-go).\n\n## Installation\n\nInstall using `go get -u github.com/klauspost/compress`. The package is located in `github.com/klauspost/compress/zstd`.\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/klauspost/compress/zstd.svg)](https://pkg.go.dev/github.com/klauspost/compress/zstd)\n\n## Compressor\n\n### Status: \n\nSTABLE - there may always be subtle bugs, a wide variety of content has been tested and the library is actively \nused by several projects. This library is being [fuzz-tested](https://github.com/klauspost/compress-fuzz) for all updates.\n\nThere may still be specific combinations of data types/size/settings that could lead to edge cases, \nso as always, testing is recommended.  \n\nFor now, a high speed (fastest) and medium-fast (default) compressor has been implemented. \n\n* The \"Fastest\" compression ratio is roughly equivalent to zstd level 1. \n* The \"Default\" compression ratio is roughly equivalent to zstd level 3 (default).\n* The \"Better\" compression ratio is roughly equivalent to zstd level 7.\n* The \"Best\" compression ratio is roughly equivalent to zstd level 11.\n\nIn terms of speed, it is typically 2x as fast as the stdlib deflate/gzip in its fastest mode. \nThe compression ratio compared to stdlib is around level 3, but usually 3x as fast.\n\n \n### Usage\n\nAn Encoder can be used for either compressing a stream via the\n`io.WriteCloser` interface supported by the Encoder or as multiple independent\ntasks via the `EncodeAll` function.\nSmaller encodes are encouraged to use the EncodeAll function.\nUse `NewWriter` to create a new instance that can be used for both.\n\nTo create a writer with default options, do like this:\n\n```Go\n// Compress input to output.\nfunc Compress(in io.Reader, out io.Writer) error {\n    enc, err := zstd.NewWriter(out)\n    if err != nil {\n        return err\n    }\n    _, err = io.Copy(enc, in)\n    if err != nil {\n        enc.Close()\n        return err\n    }\n    return enc.Close()\n}\n```\n\nNow you can encode by writing data to `enc`. The output will be finished writing when `Close()` is called.\nEven if your encode fails, you should still call `Close()` to release any resources that may be held up.  \n\nThe above is fine for big encodes. However, whenever possible try to *reuse* the writer.\n\nTo reuse the encoder, you can use the `Reset(io.Writer)` function to change to another output. \nThis will allow the encoder to reuse all resources and avoid wasteful allocations. \n\nCurrently stream encoding has 'light' concurrency, meaning up to 2 goroutines can be working on part \nof a stream. This is independent of the `WithEncoderConcurrency(n)`, but that is likely to change \nin the future. So if you want to limit concurrency for future updates, specify the concurrency\nyou would like.\n\nIf you would like stream encoding to be done without spawning async goroutines, use `WithEncoderConcurrency(1)`\nwhich will compress input as each block is completed, blocking on writes until each has completed.\n\nYou can specify your desired compression level using `WithEncoderLevel()` option. Currently only pre-defined \ncompression settings can be specified.\n\n#### Future Compatibility Guarantees\n\nThis will be an evolving project. When using this package it is important to note that both the compression efficiency and speed may change.\n\nThe goal will be to keep the default efficiency at the default zstd (level 3). \nHowever the encoding should never be assumed to remain the same, \nand you should not use hashes of compressed output for similarity checks.\n\nThe Encoder can be assumed to produce the same output from the exact same code version.\nHowever, the may be modes in the future that break this, \nalthough they will not be enabled without an explicit option.   \n\nThis encoder is not designed to (and will probably never) output the exact same bitstream as the reference encoder.\n\nAlso note, that the cgo decompressor currently does not [report all errors on invalid input](https://github.com/DataDog/zstd/issues/59),\n[omits error checks](https://github.com/DataDog/zstd/issues/61), [ignores checksums](https://github.com/DataDog/zstd/issues/43) \nand seems to ignore concatenated streams, even though [it is part of the spec](https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#frames).\n\n#### Blocks\n\nFor compressing small blocks, the returned encoder has a function called `EncodeAll(src, dst []byte) []byte`.\n\n`EncodeAll` will encode all input in src and append it to dst.\nThis function can be called concurrently. \nEach call will only run on a same goroutine as the caller.\n\nEncoded blocks can be concatenated and the result will be the combined input stream.\nData compressed with EncodeAll can be decoded with the Decoder, using either a stream or `DecodeAll`.\n\nEspecially when encoding blocks you should take special care to reuse the encoder. \nThis will effectively make it run without allocations after a warmup period. \nTo make it run completely without allocations, supply a destination buffer with space for all content.   \n\n```Go\nimport \"github.com/klauspost/compress/zstd\"\n\n// Create a writer that caches compressors.\n// For this operation type we supply a nil Reader.\nvar encoder, _ = zstd.NewWriter(nil)\n\n// Compress a buffer. \n// If you have a destination buffer, the allocation in the call can also be eliminated.\nfunc Compress(src []byte) []byte {\n    return encoder.EncodeAll(src, make([]byte, 0, len(src)))\n} \n```\n\nYou can control the maximum number of concurrent encodes using the `WithEncoderConcurrency(n)` \noption when creating the writer.\n\nUsing the Encoder for both a stream and individual blocks concurrently is safe. \n\n### Performance\n\nI have collected some speed examples to compare speed and compression against other compressors.\n\n* `file` is the input file.\n* `out` is the compressor used. `zskp` is this package. `zstd` is the Datadog cgo library. `gzstd/gzkp` is gzip standard and this library.\n* `level` is the compression level used. For `zskp` level 1 is \"fastest\", level 2 is \"default\"; 3 is \"better\", 4 is \"best\".\n* `insize`/`outsize` is the input/output size.\n* `millis` is the number of milliseconds used for compression.\n* `mb/s` is megabytes (2^20 bytes) per second.\n\n```\nSilesia Corpus:\nhttp://sun.aei.polsl.pl/~sdeor/corpus/silesia.zip\n\nThis package:\nfile    out     level   insize      outsize     millis  mb/s\nsilesia.tar zskp    1   211947520   73821326    634     318.47\nsilesia.tar zskp    2   211947520   67655404    1508    133.96\nsilesia.tar zskp    3   211947520   64746933    3000    67.37\nsilesia.tar zskp    4   211947520   60073508    16926   11.94\n\ncgo zstd:\nsilesia.tar zstd    1   211947520   73605392    543     371.56\nsilesia.tar zstd    3   211947520   66793289    864     233.68\nsilesia.tar zstd    6   211947520   62916450    1913    105.66\nsilesia.tar zstd    9   211947520   60212393    5063    39.92\n\ngzip, stdlib/this package:\nsilesia.tar gzstd   1   211947520   80007735    1498    134.87\nsilesia.tar gzkp    1   211947520   80088272    1009    200.31\n\nGOB stream of binary data. Highly compressible.\nhttps://files.klauspost.com/compress/gob-stream.7z\n\nfile        out     level   insize  outsize     millis  mb/s\ngob-stream  zskp    1   1911399616  233948096   3230    564.34\ngob-stream  zskp    2   1911399616  203997694   4997    364.73\ngob-stream  zskp    3   1911399616  173526523   13435   135.68\ngob-stream  zskp    4   1911399616  162195235   47559   38.33\n\ngob-stream  zstd    1   1911399616  249810424   2637    691.26\ngob-stream  zstd    3   1911399616  208192146   3490    522.31\ngob-stream  zstd    6   1911399616  193632038   6687    272.56\ngob-stream  zstd    9   1911399616  177620386   16175   112.70\n\ngob-stream  gzstd   1   1911399616  357382013   9046    201.49\ngob-stream  gzkp    1   1911399616  359136669   4885    373.08\n\nThe test data for the Large Text Compression Benchmark is the first\n10^9 bytes of the English Wikipedia dump on Mar. 3, 2006.\nhttp://mattmahoney.net/dc/textdata.html\n\nfile    out level   insize      outsize     millis  mb/s\nenwik9  zskp    1   1000000000  343833605   3687    258.64\nenwik9  zskp    2   1000000000  317001237   7672    124.29\nenwik9  zskp    3   1000000000  291915823   15923   59.89\nenwik9  zskp    4   1000000000  261710291   77697   12.27\n\nenwik9  zstd    1   1000000000  358072021   3110    306.65\nenwik9  zstd    3   1000000000  313734672   4784    199.35\nenwik9  zstd    6   1000000000  295138875   10290   92.68\nenwik9  zstd    9   1000000000  278348700   28549   33.40\n\nenwik9  gzstd   1   1000000000  382578136   8608    110.78\nenwik9  gzkp    1   1000000000  382781160   5628    169.45\n\nHighly compressible JSON file.\nhttps://files.klauspost.com/compress/github-june-2days-2019.json.zst\n\nfile                        out level   insize      outsize     millis  mb/s\ngithub-june-2days-2019.json zskp    1   6273951764  697439532   9789    611.17\ngithub-june-2days-2019.json zskp    2   6273951764  610876538   18553   322.49\ngithub-june-2days-2019.json zskp    3   6273951764  517662858   44186   135.41\ngithub-june-2days-2019.json zskp    4   6273951764  464617114   165373  36.18\n\ngithub-june-2days-2019.json zstd    1   6273951764  766284037   8450    708.00\ngithub-june-2days-2019.json zstd    3   6273951764  661889476   10927   547.57\ngithub-june-2days-2019.json zstd    6   6273951764  642756859   22996   260.18\ngithub-june-2days-2019.json zstd    9   6273951764  601974523   52413   114.16\n\ngithub-june-2days-2019.json gzstd   1   6273951764  1164397768  26793   223.32\ngithub-june-2days-2019.json gzkp    1   6273951764  1120631856  17693   338.16\n\nVM Image, Linux mint with a few installed applications:\nhttps://files.klauspost.com/compress/rawstudio-mint14.7z\n\nfile                    out level   insize      outsize     millis  mb/s\nrawstudio-mint14.tar    zskp    1   8558382592  3718400221  18206   448.29\nrawstudio-mint14.tar    zskp    2   8558382592  3326118337  37074   220.15\nrawstudio-mint14.tar    zskp    3   8558382592  3163842361  87306   93.49\nrawstudio-mint14.tar    zskp    4   8558382592  2970480650  783862  10.41\n\nrawstudio-mint14.tar    zstd    1   8558382592  3609250104  17136   476.27\nrawstudio-mint14.tar    zstd    3   8558382592  3341679997  29262   278.92\nrawstudio-mint14.tar    zstd    6   8558382592  3235846406  77904   104.77\nrawstudio-mint14.tar    zstd    9   8558382592  3160778861  140946  57.91\n\nrawstudio-mint14.tar    gzstd   1   8558382592  3926234992  51345   158.96\nrawstudio-mint14.tar    gzkp    1   8558382592  3960117298  36722   222.26\n\nCSV data:\nhttps://files.klauspost.com/compress/nyc-taxi-data-10M.csv.zst\n\nfile                    out level   insize      outsize     millis  mb/s\nnyc-taxi-data-10M.csv   zskp    1   3325605752  641319332   9462    335.17\nnyc-taxi-data-10M.csv   zskp    2   3325605752  588976126   17570   180.50\nnyc-taxi-data-10M.csv   zskp    3   3325605752  529329260   32432   97.79\nnyc-taxi-data-10M.csv   zskp    4   3325605752  474949772   138025  22.98\n\nnyc-taxi-data-10M.csv   zstd    1   3325605752  687399637   8233    385.18\nnyc-taxi-data-10M.csv   zstd    3   3325605752  598514411   10065   315.07\nnyc-taxi-data-10M.csv   zstd    6   3325605752  570522953   20038   158.27\nnyc-taxi-data-10M.csv   zstd    9   3325605752  517554797   64565   49.12\n\nnyc-taxi-data-10M.csv   gzstd   1   3325605752  928654908   21270   149.11\nnyc-taxi-data-10M.csv   gzkp    1   3325605752  922273214   13929   227.68\n```\n\n## Decompressor\n\nStaus: STABLE - there may still be subtle bugs, but a wide variety of content has been tested.\n\nThis library is being continuously [fuzz-tested](https://github.com/klauspost/compress-fuzz),\nkindly supplied by [fuzzit.dev](https://fuzzit.dev/). \nThe main purpose of the fuzz testing is to ensure that it is not possible to crash the decoder, \nor run it past its limits with ANY input provided.  \n \n### Usage\n\nThe package has been designed for two main usages, big streams of data and smaller in-memory buffers. \nThere are two main usages of the package for these. Both of them are accessed by creating a `Decoder`.\n\nFor streaming use a simple setup could look like this:\n\n```Go\nimport \"github.com/klauspost/compress/zstd\"\n\nfunc Decompress(in io.Reader, out io.Writer) error {\n    d, err := zstd.NewReader(in)\n    if err != nil {\n        return err\n    }\n    defer d.Close()\n    \n    // Copy content...\n    _, err = io.Copy(out, d)\n    return err\n}\n```\n\nIt is important to use the \"Close\" function when you no longer need the Reader to stop running goroutines, \nwhen running with default settings.\nGoroutines will exit once an error has been returned, including `io.EOF` at the end of a stream.\n\nStreams are decoded concurrently in 4 asynchronous stages to give the best possible throughput.\nHowever, if you prefer synchronous decompression, use `WithDecoderConcurrency(1)` which will decompress data \nas it is being requested only.\n\nFor decoding buffers, it could look something like this:\n\n```Go\nimport \"github.com/klauspost/compress/zstd\"\n\n// Create a reader that caches decompressors.\n// For this operation type we supply a nil Reader.\nvar decoder, _ = zstd.NewReader(nil, zstd.WithDecoderConcurrency(0))\n\n// Decompress a buffer. We don't supply a destination buffer,\n// so it will be allocated by the decoder.\nfunc Decompress(src []byte) ([]byte, error) {\n    return decoder.DecodeAll(src, nil)\n} \n```\n\nBoth of these cases should provide the functionality needed. \nThe decoder can be used for *concurrent* decompression of multiple buffers.\nBy default 4 decompressors will be created. \n\nIt will only allow a certain number of concurrent operations to run. \nTo tweak that yourself use the `WithDecoderConcurrency(n)` option when creating the decoder.\nIt is possible to use `WithDecoderConcurrency(0)` to create GOMAXPROCS decoders.\n\n### Dictionaries\n\nData compressed with [dictionaries](https://github.com/facebook/zstd#the-case-for-small-data-compression) can be decompressed.\n\nDictionaries are added individually to Decoders.\nDictionaries are generated by the `zstd --train` command and contains an initial state for the decoder.\nTo add a dictionary use the `WithDecoderDicts(dicts ...[]byte)` option with the dictionary data.\nSeveral dictionaries can be added at once.\n\nThe dictionary will be used automatically for the data that specifies them.\nA re-used Decoder will still contain the dictionaries registered.\n\nWhen registering multiple dictionaries with the same ID, the last one will be used.\n\nIt is possible to use dictionaries when compressing data.\n\nTo enable a dictionary use `WithEncoderDict(dict []byte)`. Here only one dictionary will be used \nand it will likely be used even if it doesn't improve compression. \n\nThe used dictionary must be used to decompress the content.\n\nFor any real gains, the dictionary should be built with similar data. \nIf an unsuitable dictionary is used the output may be slightly larger than using no dictionary.\nUse the [zstd commandline tool](https://github.com/facebook/zstd/releases) to build a dictionary from sample data.\nFor information see [zstd dictionary information](https://github.com/facebook/zstd#the-case-for-small-data-compression). \n\nFor now there is a fixed startup performance penalty for compressing content with dictionaries. \nThis will likely be improved over time. Just be aware to test performance when implementing.  \n\n### Allocation-less operation\n\nThe decoder has been designed to operate without allocations after a warmup. \n\nThis means that you should *store* the decoder for best performance. \nTo re-use a stream decoder, use the `Reset(r io.Reader) error` to switch to another stream.\nA decoder can safely be re-used even if the previous stream failed.\n\nTo release the resources, you must call the `Close()` function on a decoder.\nAfter this it can *no longer be reused*, but all running goroutines will be stopped.\nSo you *must* use this if you will no longer need the Reader.\n\nFor decompressing smaller buffers a single decoder can be used.\nWhen decoding buffers, you can supply a destination slice with length 0 and your expected capacity.\nIn this case no unneeded allocations should be made. \n\n### Concurrency\n\nThe buffer decoder does everything on the same goroutine and does nothing concurrently.\nIt can however decode several buffers concurrently. Use `WithDecoderConcurrency(n)` to limit that.\n\nThe stream decoder will create goroutines that:\n\n1) Reads input and splits the input into blocks.\n2) Decompression of literals.\n3) Decompression of sequences.\n4) Reconstruction of output stream.\n\nSo effectively this also means the decoder will \"read ahead\" and prepare data to always be available for output.\n\nThe concurrency level will, for streams, determine how many blocks ahead the compression will start.\n\nSince \"blocks\" are quite dependent on the output of the previous block stream decoding will only have limited concurrency.\n\nIn practice this means that concurrency is often limited to utilizing about 3 cores effectively.\n  \n### Benchmarks\n\nThe first two are streaming decodes and the last are smaller inputs. \n\nRunning on AMD Ryzen 9 3950X 16-Core Processor. AMD64 assembly used.\n\n```\nBenchmarkDecoderSilesia-32    \t                   5\t 206878840 ns/op\t1024.50 MB/s\t   49808 B/op\t      43 allocs/op\nBenchmarkDecoderEnwik9-32                          1\t1271809000 ns/op\t 786.28 MB/s\t   72048 B/op\t      52 allocs/op\n\nConcurrent blocks, performance:\n\nBenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-32         \t   67356\t     17857 ns/op\t10321.96 MB/s\t        22.48 pct\t     102 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-32     \t  266656\t      4421 ns/op\t26823.21 MB/s\t        11.89 pct\t      19 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-32      \t   20992\t     56842 ns/op\t8477.17 MB/s\t        39.90 pct\t     754 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-32        \t   27456\t     43932 ns/op\t9714.01 MB/s\t        33.27 pct\t     524 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-32      \t   78432\t     15047 ns/op\t8319.15 MB/s\t        40.34 pct\t      66 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-32       \t   65800\t     18436 ns/op\t8249.63 MB/s\t        37.75 pct\t      88 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/html_x_4.zst-32          \t  102993\t     11523 ns/op\t35546.09 MB/s\t         3.637 pct\t     143 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-32    \t 1000000\t      1070 ns/op\t95720.98 MB/s\t        80.53 pct\t       3 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-32    \t  749802\t      1752 ns/op\t70272.35 MB/s\t       100.0 pct\t       5 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/urls.10K.zst-32          \t   22640\t     52934 ns/op\t13263.37 MB/s\t        26.25 pct\t    1014 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/html.zst-32              \t  226412\t      5232 ns/op\t19572.27 MB/s\t        14.49 pct\t      20 B/op\t       0 allocs/op\nBenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-32     \t  923041\t      1276 ns/op\t3194.71 MB/s\t        31.26 pct\t       0 B/op\t       0 allocs/op\n```\n\nThis reflects the performance around May 2022, but this may be out of date.\n\n## Zstd inside ZIP files\n\nIt is possible to use zstandard to compress individual files inside zip archives.\nWhile this isn't widely supported it can be useful for internal files.\n\nTo support the compression and decompression of these files you must register a compressor and decompressor.\n\nIt is highly recommended registering the (de)compressors on individual zip Reader/Writer and NOT\nuse the global registration functions. The main reason for this is that 2 registrations from \ndifferent packages will result in a panic.\n\nIt is a good idea to only have a single compressor and decompressor, since they can be used for multiple zip\nfiles concurrently, and using a single instance will allow reusing some resources.\n\nSee [this example](https://pkg.go.dev/github.com/klauspost/compress/zstd#example-ZipCompressor) for \nhow to compress and decompress files inside zip archives.\n\n# Contributions\n\nContributions are always welcome. \nFor new features/fixes, remember to add tests and for performance enhancements include benchmarks.\n\nFor general feedback and experience reports, feel free to open an issue or write me on [Twitter](https://twitter.com/sh0dan).\n\nThis package includes the excellent [`github.com/cespare/xxhash`](https://github.com/cespare/xxhash) package Copyright (c) 2016 Caleb Spare.\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/bitreader.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/bits\"\n)\n\n// bitReader reads a bitstream in reverse.\n// The last set bit indicates the start of the stream and is used\n// for aligning the input.\ntype bitReader struct {\n\tin       []byte\n\tvalue    uint64 // Maybe use [16]byte, but shifting is awkward.\n\tbitsRead uint8\n}\n\n// init initializes and resets the bit reader.\nfunc (b *bitReader) init(in []byte) error {\n\tif len(in) < 1 {\n\t\treturn errors.New(\"corrupt stream: too short\")\n\t}\n\tb.in = in\n\t// The highest bit of the last byte indicates where to start\n\tv := in[len(in)-1]\n\tif v == 0 {\n\t\treturn errors.New(\"corrupt stream, did not find end of stream\")\n\t}\n\tb.bitsRead = 64\n\tb.value = 0\n\tif len(in) >= 8 {\n\t\tb.fillFastStart()\n\t} else {\n\t\tb.fill()\n\t\tb.fill()\n\t}\n\tb.bitsRead += 8 - uint8(highBits(uint32(v)))\n\treturn nil\n}\n\n// getBits will return n bits. n can be 0.\nfunc (b *bitReader) getBits(n uint8) int {\n\tif n == 0 /*|| b.bitsRead >= 64 */ {\n\t\treturn 0\n\t}\n\treturn int(b.get32BitsFast(n))\n}\n\n// get32BitsFast requires that at least one bit is requested every time.\n// There are no checks if the buffer is filled.\nfunc (b *bitReader) get32BitsFast(n uint8) uint32 {\n\tconst regMask = 64 - 1\n\tv := uint32((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask))\n\tb.bitsRead += n\n\treturn v\n}\n\n// fillFast() will make sure at least 32 bits are available.\n// There must be at least 4 bytes available.\nfunc (b *bitReader) fillFast() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\tv := b.in[len(b.in)-4:]\n\tb.in = b.in[:len(b.in)-4]\n\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\tb.value = (b.value << 32) | uint64(low)\n\tb.bitsRead -= 32\n}\n\n// fillFastStart() assumes the bitreader is empty and there is at least 8 bytes to read.\nfunc (b *bitReader) fillFastStart() {\n\tv := b.in[len(b.in)-8:]\n\tb.in = b.in[:len(b.in)-8]\n\tb.value = binary.LittleEndian.Uint64(v)\n\tb.bitsRead = 0\n}\n\n// fill() will make sure at least 32 bits are available.\nfunc (b *bitReader) fill() {\n\tif b.bitsRead < 32 {\n\t\treturn\n\t}\n\tif len(b.in) >= 4 {\n\t\tv := b.in[len(b.in)-4:]\n\t\tb.in = b.in[:len(b.in)-4]\n\t\tlow := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)\n\t\tb.value = (b.value << 32) | uint64(low)\n\t\tb.bitsRead -= 32\n\t\treturn\n\t}\n\n\tb.bitsRead -= uint8(8 * len(b.in))\n\tfor len(b.in) > 0 {\n\t\tb.value = (b.value << 8) | uint64(b.in[len(b.in)-1])\n\t\tb.in = b.in[:len(b.in)-1]\n\t}\n}\n\n// finished returns true if all bits have been read from the bit stream.\nfunc (b *bitReader) finished() bool {\n\treturn len(b.in) == 0 && b.bitsRead >= 64\n}\n\n// overread returns true if more bits have been requested than is on the stream.\nfunc (b *bitReader) overread() bool {\n\treturn b.bitsRead > 64\n}\n\n// remain returns the number of bits remaining.\nfunc (b *bitReader) remain() uint {\n\treturn 8*uint(len(b.in)) + 64 - uint(b.bitsRead)\n}\n\n// close the bitstream and returns an error if out-of-buffer reads occurred.\nfunc (b *bitReader) close() error {\n\t// Release reference.\n\tb.in = nil\n\tif !b.finished() {\n\t\treturn fmt.Errorf(\"%d extra bits on block, should be 0\", b.remain())\n\t}\n\tif b.bitsRead > 64 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn nil\n}\n\nfunc highBits(val uint32) (n uint32) {\n\treturn uint32(bits.Len32(val) - 1)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/bitwriter.go",
    "content": "// Copyright 2018 Klaus Post. 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// Based on work Copyright (c) 2013, Yann Collet, released under BSD License.\n\npackage zstd\n\n// bitWriter will write bits.\n// First bit will be LSB of the first byte of output.\ntype bitWriter struct {\n\tbitContainer uint64\n\tnBits        uint8\n\tout          []byte\n}\n\n// bitMask16 is bitmasks. Has extra to avoid bounds check.\nvar bitMask16 = [32]uint16{\n\t0, 1, 3, 7, 0xF, 0x1F,\n\t0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,\n\t0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0xFFFF,\n\t0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,\n\t0xFFFF, 0xFFFF} /* up to 16 bits */\n\nvar bitMask32 = [32]uint32{\n\t0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF,\n\t0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF,\n\t0x1ffff, 0x3ffff, 0x7FFFF, 0xfFFFF, 0x1fFFFF, 0x3fFFFF, 0x7fFFFF, 0xffFFFF,\n\t0x1ffFFFF, 0x3ffFFFF, 0x7ffFFFF, 0xfffFFFF, 0x1fffFFFF, 0x3fffFFFF, 0x7fffFFFF,\n} // up to 32 bits\n\n// addBits16NC will add up to 16 bits.\n// It will not check if there is space for them,\n// so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) addBits16NC(value uint16, bits uint8) {\n\tb.bitContainer |= uint64(value&bitMask16[bits&31]) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// addBits32NC will add up to 31 bits.\n// It will not check if there is space for them,\n// so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) addBits32NC(value uint32, bits uint8) {\n\tb.bitContainer |= uint64(value&bitMask32[bits&31]) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// addBits64NC will add up to 64 bits.\n// There must be space for 32 bits.\nfunc (b *bitWriter) addBits64NC(value uint64, bits uint8) {\n\tif bits <= 31 {\n\t\tb.addBits32Clean(uint32(value), bits)\n\t\treturn\n\t}\n\tb.addBits32Clean(uint32(value), 32)\n\tb.flush32()\n\tb.addBits32Clean(uint32(value>>32), bits-32)\n}\n\n// addBits32Clean will add up to 32 bits.\n// It will not check if there is space for them.\n// The input must not contain more bits than specified.\nfunc (b *bitWriter) addBits32Clean(value uint32, bits uint8) {\n\tb.bitContainer |= uint64(value) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated.\n// It will not check if there is space for them, so the caller must ensure that it has flushed recently.\nfunc (b *bitWriter) addBits16Clean(value uint16, bits uint8) {\n\tb.bitContainer |= uint64(value) << (b.nBits & 63)\n\tb.nBits += bits\n}\n\n// flush32 will flush out, so there are at least 32 bits available for writing.\nfunc (b *bitWriter) flush32() {\n\tif b.nBits < 32 {\n\t\treturn\n\t}\n\tb.out = append(b.out,\n\t\tbyte(b.bitContainer),\n\t\tbyte(b.bitContainer>>8),\n\t\tbyte(b.bitContainer>>16),\n\t\tbyte(b.bitContainer>>24))\n\tb.nBits -= 32\n\tb.bitContainer >>= 32\n}\n\n// flushAlign will flush remaining full bytes and align to next byte boundary.\nfunc (b *bitWriter) flushAlign() {\n\tnbBytes := (b.nBits + 7) >> 3\n\tfor i := uint8(0); i < nbBytes; i++ {\n\t\tb.out = append(b.out, byte(b.bitContainer>>(i*8)))\n\t}\n\tb.nBits = 0\n\tb.bitContainer = 0\n}\n\n// close will write the alignment bit and write the final byte(s)\n// to the output.\nfunc (b *bitWriter) close() {\n\t// End mark\n\tb.addBits16Clean(1, 1)\n\t// flush until next byte.\n\tb.flushAlign()\n}\n\n// reset and continue writing by appending to out.\nfunc (b *bitWriter) reset(out []byte) {\n\tb.bitContainer = 0\n\tb.nBits = 0\n\tb.out = out\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/blockdec.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash/crc32\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sync\"\n\n\t\"github.com/klauspost/compress/huff0\"\n\t\"github.com/klauspost/compress/zstd/internal/xxhash\"\n)\n\ntype blockType uint8\n\n//go:generate stringer -type=blockType,literalsBlockType,seqCompMode,tableIndex\n\nconst (\n\tblockTypeRaw blockType = iota\n\tblockTypeRLE\n\tblockTypeCompressed\n\tblockTypeReserved\n)\n\ntype literalsBlockType uint8\n\nconst (\n\tliteralsBlockRaw literalsBlockType = iota\n\tliteralsBlockRLE\n\tliteralsBlockCompressed\n\tliteralsBlockTreeless\n)\n\nconst (\n\t// maxCompressedBlockSize is the biggest allowed compressed block size (128KB)\n\tmaxCompressedBlockSize = 128 << 10\n\n\tcompressedBlockOverAlloc    = 16\n\tmaxCompressedBlockSizeAlloc = 128<<10 + compressedBlockOverAlloc\n\n\t// Maximum possible block size (all Raw+Uncompressed).\n\tmaxBlockSize = (1 << 21) - 1\n\n\tmaxMatchLen  = 131074\n\tmaxSequences = 0x7f00 + 0xffff\n\n\t// We support slightly less than the reference decoder to be able to\n\t// use ints on 32 bit archs.\n\tmaxOffsetBits = 30\n)\n\nvar (\n\thuffDecoderPool = sync.Pool{New: func() interface{} {\n\t\treturn &huff0.Scratch{}\n\t}}\n\n\tfseDecoderPool = sync.Pool{New: func() interface{} {\n\t\treturn &fseDecoder{}\n\t}}\n)\n\ntype blockDec struct {\n\t// Raw source data of the block.\n\tdata        []byte\n\tdataStorage []byte\n\n\t// Destination of the decoded data.\n\tdst []byte\n\n\t// Buffer for literals data.\n\tliteralBuf []byte\n\n\t// Window size of the block.\n\tWindowSize uint64\n\n\terr error\n\n\t// Check against this crc, if hasCRC is true.\n\tcheckCRC uint32\n\thasCRC   bool\n\n\t// Frame to use for singlethreaded decoding.\n\t// Should not be used by the decoder itself since parent may be another frame.\n\tlocalFrame *frameDec\n\n\tsequence []seqVals\n\n\tasync struct {\n\t\tnewHist  *history\n\t\tliterals []byte\n\t\tseqData  []byte\n\t\tseqSize  int // Size of uncompressed sequences\n\t\tfcs      uint64\n\t}\n\n\t// Block is RLE, this is the size.\n\tRLESize uint32\n\n\tType blockType\n\n\t// Is this the last block of a frame?\n\tLast bool\n\n\t// Use less memory\n\tlowMem bool\n}\n\nfunc (b *blockDec) String() string {\n\tif b == nil {\n\t\treturn \"<nil>\"\n\t}\n\treturn fmt.Sprintf(\"Steam Size: %d, Type: %v, Last: %t, Window: %d\", len(b.data), b.Type, b.Last, b.WindowSize)\n}\n\nfunc newBlockDec(lowMem bool) *blockDec {\n\tb := blockDec{\n\t\tlowMem: lowMem,\n\t}\n\treturn &b\n}\n\n// reset will reset the block.\n// Input must be a start of a block and will be at the end of the block when returned.\nfunc (b *blockDec) reset(br byteBuffer, windowSize uint64) error {\n\tb.WindowSize = windowSize\n\ttmp, err := br.readSmall(3)\n\tif err != nil {\n\t\tprintln(\"Reading block header:\", err)\n\t\treturn err\n\t}\n\tbh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16)\n\tb.Last = bh&1 != 0\n\tb.Type = blockType((bh >> 1) & 3)\n\t// find size.\n\tcSize := int(bh >> 3)\n\tmaxSize := maxCompressedBlockSizeAlloc\n\tswitch b.Type {\n\tcase blockTypeReserved:\n\t\treturn ErrReservedBlockType\n\tcase blockTypeRLE:\n\t\tif cSize > maxCompressedBlockSize || cSize > int(b.WindowSize) {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"rle block too big: csize:%d block: %+v\\n\", uint64(cSize), b)\n\t\t\t}\n\t\t\treturn ErrWindowSizeExceeded\n\t\t}\n\t\tb.RLESize = uint32(cSize)\n\t\tif b.lowMem {\n\t\t\tmaxSize = cSize\n\t\t}\n\t\tcSize = 1\n\tcase blockTypeCompressed:\n\t\tif debugDecoder {\n\t\t\tprintln(\"Data size on stream:\", cSize)\n\t\t}\n\t\tb.RLESize = 0\n\t\tmaxSize = maxCompressedBlockSizeAlloc\n\t\tif windowSize < maxCompressedBlockSize && b.lowMem {\n\t\t\tmaxSize = int(windowSize) + compressedBlockOverAlloc\n\t\t}\n\t\tif cSize > maxCompressedBlockSize || uint64(cSize) > b.WindowSize {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"compressed block too big: csize:%d block: %+v\\n\", uint64(cSize), b)\n\t\t\t}\n\t\t\treturn ErrCompressedSizeTooBig\n\t\t}\n\t\t// Empty compressed blocks must at least be 2 bytes\n\t\t// for Literals_Block_Type and one for Sequences_Section_Header.\n\t\tif cSize < 2 {\n\t\t\treturn ErrBlockTooSmall\n\t\t}\n\tcase blockTypeRaw:\n\t\tif cSize > maxCompressedBlockSize || cSize > int(b.WindowSize) {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"rle block too big: csize:%d block: %+v\\n\", uint64(cSize), b)\n\t\t\t}\n\t\t\treturn ErrWindowSizeExceeded\n\t\t}\n\n\t\tb.RLESize = 0\n\t\t// We do not need a destination for raw blocks.\n\t\tmaxSize = -1\n\tdefault:\n\t\tpanic(\"Invalid block type\")\n\t}\n\n\t// Read block data.\n\tif _, ok := br.(*byteBuf); !ok && cap(b.dataStorage) < cSize {\n\t\t// byteBuf doesn't need a destination buffer.\n\t\tif b.lowMem || cSize > maxCompressedBlockSize {\n\t\t\tb.dataStorage = make([]byte, 0, cSize+compressedBlockOverAlloc)\n\t\t} else {\n\t\t\tb.dataStorage = make([]byte, 0, maxCompressedBlockSizeAlloc)\n\t\t}\n\t}\n\tb.data, err = br.readBig(cSize, b.dataStorage)\n\tif err != nil {\n\t\tif debugDecoder {\n\t\t\tprintln(\"Reading block:\", err, \"(\", cSize, \")\", len(b.data))\n\t\t\tprintf(\"%T\", br)\n\t\t}\n\t\treturn err\n\t}\n\tif cap(b.dst) <= maxSize {\n\t\tb.dst = make([]byte, 0, maxSize+1)\n\t}\n\treturn nil\n}\n\n// sendEOF will make the decoder send EOF on this frame.\nfunc (b *blockDec) sendErr(err error) {\n\tb.Last = true\n\tb.Type = blockTypeReserved\n\tb.err = err\n}\n\n// Close will release resources.\n// Closed blockDec cannot be reset.\nfunc (b *blockDec) Close() {\n}\n\n// decodeBuf\nfunc (b *blockDec) decodeBuf(hist *history) error {\n\tswitch b.Type {\n\tcase blockTypeRLE:\n\t\tif cap(b.dst) < int(b.RLESize) {\n\t\t\tif b.lowMem {\n\t\t\t\tb.dst = make([]byte, b.RLESize)\n\t\t\t} else {\n\t\t\t\tb.dst = make([]byte, maxCompressedBlockSize)\n\t\t\t}\n\t\t}\n\t\tb.dst = b.dst[:b.RLESize]\n\t\tv := b.data[0]\n\t\tfor i := range b.dst {\n\t\t\tb.dst[i] = v\n\t\t}\n\t\thist.appendKeep(b.dst)\n\t\treturn nil\n\tcase blockTypeRaw:\n\t\thist.appendKeep(b.data)\n\t\treturn nil\n\tcase blockTypeCompressed:\n\t\tsaved := b.dst\n\t\t// Append directly to history\n\t\tif hist.ignoreBuffer == 0 {\n\t\t\tb.dst = hist.b\n\t\t\thist.b = nil\n\t\t} else {\n\t\t\tb.dst = b.dst[:0]\n\t\t}\n\t\terr := b.decodeCompressed(hist)\n\t\tif debugDecoder {\n\t\t\tprintln(\"Decompressed to total\", len(b.dst), \"bytes, hash:\", xxhash.Sum64(b.dst), \"error:\", err)\n\t\t}\n\t\tif hist.ignoreBuffer == 0 {\n\t\t\thist.b = b.dst\n\t\t\tb.dst = saved\n\t\t} else {\n\t\t\thist.appendKeep(b.dst)\n\t\t}\n\t\treturn err\n\tcase blockTypeReserved:\n\t\t// Used for returning errors.\n\t\treturn b.err\n\tdefault:\n\t\tpanic(\"Invalid block type\")\n\t}\n}\n\nfunc (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err error) {\n\t// There must be at least one byte for Literals_Block_Type and one for Sequences_Section_Header\n\tif len(in) < 2 {\n\t\treturn in, ErrBlockTooSmall\n\t}\n\n\tlitType := literalsBlockType(in[0] & 3)\n\tvar litRegenSize int\n\tvar litCompSize int\n\tsizeFormat := (in[0] >> 2) & 3\n\tvar fourStreams bool\n\tvar literals []byte\n\tswitch litType {\n\tcase literalsBlockRaw, literalsBlockRLE:\n\t\tswitch sizeFormat {\n\t\tcase 0, 2:\n\t\t\t// Regenerated_Size uses 5 bits (0-31). Literals_Section_Header uses 1 byte.\n\t\t\tlitRegenSize = int(in[0] >> 3)\n\t\t\tin = in[1:]\n\t\tcase 1:\n\t\t\t// Regenerated_Size uses 12 bits (0-4095). Literals_Section_Header uses 2 bytes.\n\t\t\tlitRegenSize = int(in[0]>>4) + (int(in[1]) << 4)\n\t\t\tin = in[2:]\n\t\tcase 3:\n\t\t\t//  Regenerated_Size uses 20 bits (0-1048575). Literals_Section_Header uses 3 bytes.\n\t\t\tif len(in) < 3 {\n\t\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, len(in))\n\t\t\t\treturn in, ErrBlockTooSmall\n\t\t\t}\n\t\t\tlitRegenSize = int(in[0]>>4) + (int(in[1]) << 4) + (int(in[2]) << 12)\n\t\t\tin = in[3:]\n\t\t}\n\tcase literalsBlockCompressed, literalsBlockTreeless:\n\t\tswitch sizeFormat {\n\t\tcase 0, 1:\n\t\t\t// Both Regenerated_Size and Compressed_Size use 10 bits (0-1023).\n\t\t\tif len(in) < 3 {\n\t\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, len(in))\n\t\t\t\treturn in, ErrBlockTooSmall\n\t\t\t}\n\t\t\tn := uint64(in[0]>>4) + (uint64(in[1]) << 4) + (uint64(in[2]) << 12)\n\t\t\tlitRegenSize = int(n & 1023)\n\t\t\tlitCompSize = int(n >> 10)\n\t\t\tfourStreams = sizeFormat == 1\n\t\t\tin = in[3:]\n\t\tcase 2:\n\t\t\tfourStreams = true\n\t\t\tif len(in) < 4 {\n\t\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, len(in))\n\t\t\t\treturn in, ErrBlockTooSmall\n\t\t\t}\n\t\t\tn := uint64(in[0]>>4) + (uint64(in[1]) << 4) + (uint64(in[2]) << 12) + (uint64(in[3]) << 20)\n\t\t\tlitRegenSize = int(n & 16383)\n\t\t\tlitCompSize = int(n >> 14)\n\t\t\tin = in[4:]\n\t\tcase 3:\n\t\t\tfourStreams = true\n\t\t\tif len(in) < 5 {\n\t\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, len(in))\n\t\t\t\treturn in, ErrBlockTooSmall\n\t\t\t}\n\t\t\tn := uint64(in[0]>>4) + (uint64(in[1]) << 4) + (uint64(in[2]) << 12) + (uint64(in[3]) << 20) + (uint64(in[4]) << 28)\n\t\t\tlitRegenSize = int(n & 262143)\n\t\t\tlitCompSize = int(n >> 18)\n\t\t\tin = in[5:]\n\t\t}\n\t}\n\tif debugDecoder {\n\t\tprintln(\"literals type:\", litType, \"litRegenSize:\", litRegenSize, \"litCompSize:\", litCompSize, \"sizeFormat:\", sizeFormat, \"4X:\", fourStreams)\n\t}\n\tif litRegenSize > int(b.WindowSize) || litRegenSize > maxCompressedBlockSize {\n\t\treturn in, ErrWindowSizeExceeded\n\t}\n\n\tswitch litType {\n\tcase literalsBlockRaw:\n\t\tif len(in) < litRegenSize {\n\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, \"remain:\", len(in), \"want:\", litRegenSize)\n\t\t\treturn in, ErrBlockTooSmall\n\t\t}\n\t\tliterals = in[:litRegenSize]\n\t\tin = in[litRegenSize:]\n\t\t//printf(\"Found %d uncompressed literals\\n\", litRegenSize)\n\tcase literalsBlockRLE:\n\t\tif len(in) < 1 {\n\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, \"remain:\", len(in), \"want:\", 1)\n\t\t\treturn in, ErrBlockTooSmall\n\t\t}\n\t\tif cap(b.literalBuf) < litRegenSize {\n\t\t\tif b.lowMem {\n\t\t\t\tb.literalBuf = make([]byte, litRegenSize, litRegenSize+compressedBlockOverAlloc)\n\t\t\t} else {\n\t\t\t\tb.literalBuf = make([]byte, litRegenSize, maxCompressedBlockSize+compressedBlockOverAlloc)\n\t\t\t}\n\t\t}\n\t\tliterals = b.literalBuf[:litRegenSize]\n\t\tv := in[0]\n\t\tfor i := range literals {\n\t\t\tliterals[i] = v\n\t\t}\n\t\tin = in[1:]\n\t\tif debugDecoder {\n\t\t\tprintf(\"Found %d RLE compressed literals\\n\", litRegenSize)\n\t\t}\n\tcase literalsBlockTreeless:\n\t\tif len(in) < litCompSize {\n\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, \"remain:\", len(in), \"want:\", litCompSize)\n\t\t\treturn in, ErrBlockTooSmall\n\t\t}\n\t\t// Store compressed literals, so we defer decoding until we get history.\n\t\tliterals = in[:litCompSize]\n\t\tin = in[litCompSize:]\n\t\tif debugDecoder {\n\t\t\tprintf(\"Found %d compressed literals\\n\", litCompSize)\n\t\t}\n\t\thuff := hist.huffTree\n\t\tif huff == nil {\n\t\t\treturn in, errors.New(\"literal block was treeless, but no history was defined\")\n\t\t}\n\t\t// Ensure we have space to store it.\n\t\tif cap(b.literalBuf) < litRegenSize {\n\t\t\tif b.lowMem {\n\t\t\t\tb.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc)\n\t\t\t} else {\n\t\t\t\tb.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc)\n\t\t\t}\n\t\t}\n\t\tvar err error\n\t\t// Use our out buffer.\n\t\thuff.MaxDecodedSize = litRegenSize\n\t\tif fourStreams {\n\t\t\tliterals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals)\n\t\t} else {\n\t\t\tliterals, err = huff.Decoder().Decompress1X(b.literalBuf[:0:litRegenSize], literals)\n\t\t}\n\t\t// Make sure we don't leak our literals buffer\n\t\tif err != nil {\n\t\t\tprintln(\"decompressing literals:\", err)\n\t\t\treturn in, err\n\t\t}\n\t\tif len(literals) != litRegenSize {\n\t\t\treturn in, fmt.Errorf(\"literal output size mismatch want %d, got %d\", litRegenSize, len(literals))\n\t\t}\n\n\tcase literalsBlockCompressed:\n\t\tif len(in) < litCompSize {\n\t\t\tprintln(\"too small: litType:\", litType, \" sizeFormat\", sizeFormat, \"remain:\", len(in), \"want:\", litCompSize)\n\t\t\treturn in, ErrBlockTooSmall\n\t\t}\n\t\tliterals = in[:litCompSize]\n\t\tin = in[litCompSize:]\n\t\t// Ensure we have space to store it.\n\t\tif cap(b.literalBuf) < litRegenSize {\n\t\t\tif b.lowMem {\n\t\t\t\tb.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc)\n\t\t\t} else {\n\t\t\t\tb.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc)\n\t\t\t}\n\t\t}\n\t\thuff := hist.huffTree\n\t\tif huff == nil || (hist.dict != nil && huff == hist.dict.litEnc) {\n\t\t\thuff = huffDecoderPool.Get().(*huff0.Scratch)\n\t\t\tif huff == nil {\n\t\t\t\thuff = &huff0.Scratch{}\n\t\t\t}\n\t\t}\n\t\tvar err error\n\t\tif debugDecoder {\n\t\t\tprintln(\"huff table input:\", len(literals), \"CRC:\", crc32.ChecksumIEEE(literals))\n\t\t}\n\t\thuff, literals, err = huff0.ReadTable(literals, huff)\n\t\tif err != nil {\n\t\t\tprintln(\"reading huffman table:\", err)\n\t\t\treturn in, err\n\t\t}\n\t\thist.huffTree = huff\n\t\thuff.MaxDecodedSize = litRegenSize\n\t\t// Use our out buffer.\n\t\tif fourStreams {\n\t\t\tliterals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals)\n\t\t} else {\n\t\t\tliterals, err = huff.Decoder().Decompress1X(b.literalBuf[:0:litRegenSize], literals)\n\t\t}\n\t\tif err != nil {\n\t\t\tprintln(\"decoding compressed literals:\", err)\n\t\t\treturn in, err\n\t\t}\n\t\t// Make sure we don't leak our literals buffer\n\t\tif len(literals) != litRegenSize {\n\t\t\treturn in, fmt.Errorf(\"literal output size mismatch want %d, got %d\", litRegenSize, len(literals))\n\t\t}\n\t\t// Re-cap to get extra size.\n\t\tliterals = b.literalBuf[:len(literals)]\n\t\tif debugDecoder {\n\t\t\tprintf(\"Decompressed %d literals into %d bytes\\n\", litCompSize, litRegenSize)\n\t\t}\n\t}\n\thist.decoders.literals = literals\n\treturn in, nil\n}\n\n// decodeCompressed will start decompressing a block.\nfunc (b *blockDec) decodeCompressed(hist *history) error {\n\tin := b.data\n\tin, err := b.decodeLiterals(in, hist)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = b.prepareSequences(in, hist)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif hist.decoders.nSeqs == 0 {\n\t\tb.dst = append(b.dst, hist.decoders.literals...)\n\t\treturn nil\n\t}\n\tbefore := len(hist.decoders.out)\n\terr = hist.decoders.decodeSync(hist.b[hist.ignoreBuffer:])\n\tif err != nil {\n\t\treturn err\n\t}\n\tif hist.decoders.maxSyncLen > 0 {\n\t\thist.decoders.maxSyncLen += uint64(before)\n\t\thist.decoders.maxSyncLen -= uint64(len(hist.decoders.out))\n\t}\n\tb.dst = hist.decoders.out\n\thist.recentOffsets = hist.decoders.prevOffset\n\treturn nil\n}\n\nfunc (b *blockDec) prepareSequences(in []byte, hist *history) (err error) {\n\tif debugDecoder {\n\t\tprintf(\"prepareSequences: %d byte(s) input\\n\", len(in))\n\t}\n\t// Decode Sequences\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#sequences-section\n\tif len(in) < 1 {\n\t\treturn ErrBlockTooSmall\n\t}\n\tvar nSeqs int\n\tseqHeader := in[0]\n\tswitch {\n\tcase seqHeader < 128:\n\t\tnSeqs = int(seqHeader)\n\t\tin = in[1:]\n\tcase seqHeader < 255:\n\t\tif len(in) < 2 {\n\t\t\treturn ErrBlockTooSmall\n\t\t}\n\t\tnSeqs = int(seqHeader-128)<<8 | int(in[1])\n\t\tin = in[2:]\n\tcase seqHeader == 255:\n\t\tif len(in) < 3 {\n\t\t\treturn ErrBlockTooSmall\n\t\t}\n\t\tnSeqs = 0x7f00 + int(in[1]) + (int(in[2]) << 8)\n\t\tin = in[3:]\n\t}\n\tif nSeqs == 0 && len(in) != 0 {\n\t\t// When no sequences, there should not be any more data...\n\t\tif debugDecoder {\n\t\t\tprintf(\"prepareSequences: 0 sequences, but %d byte(s) left on stream\\n\", len(in))\n\t\t}\n\t\treturn ErrUnexpectedBlockSize\n\t}\n\n\tvar seqs = &hist.decoders\n\tseqs.nSeqs = nSeqs\n\tif nSeqs > 0 {\n\t\tif len(in) < 1 {\n\t\t\treturn ErrBlockTooSmall\n\t\t}\n\t\tbr := byteReader{b: in, off: 0}\n\t\tcompMode := br.Uint8()\n\t\tbr.advance(1)\n\t\tif debugDecoder {\n\t\t\tprintf(\"Compression modes: 0b%b\", compMode)\n\t\t}\n\t\tfor i := uint(0); i < 3; i++ {\n\t\t\tmode := seqCompMode((compMode >> (6 - i*2)) & 3)\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"Table\", tableIndex(i), \"is\", mode)\n\t\t\t}\n\t\t\tvar seq *sequenceDec\n\t\t\tswitch tableIndex(i) {\n\t\t\tcase tableLiteralLengths:\n\t\t\t\tseq = &seqs.litLengths\n\t\t\tcase tableOffsets:\n\t\t\t\tseq = &seqs.offsets\n\t\t\tcase tableMatchLengths:\n\t\t\t\tseq = &seqs.matchLengths\n\t\t\tdefault:\n\t\t\t\tpanic(\"unknown table\")\n\t\t\t}\n\t\t\tswitch mode {\n\t\t\tcase compModePredefined:\n\t\t\t\tif seq.fse != nil && !seq.fse.preDefined {\n\t\t\t\t\tfseDecoderPool.Put(seq.fse)\n\t\t\t\t}\n\t\t\t\tseq.fse = &fsePredef[i]\n\t\t\tcase compModeRLE:\n\t\t\t\tif br.remain() < 1 {\n\t\t\t\t\treturn ErrBlockTooSmall\n\t\t\t\t}\n\t\t\t\tv := br.Uint8()\n\t\t\t\tbr.advance(1)\n\t\t\t\tif seq.fse == nil || seq.fse.preDefined {\n\t\t\t\t\tseq.fse = fseDecoderPool.Get().(*fseDecoder)\n\t\t\t\t}\n\t\t\t\tsymb, err := decSymbolValue(v, symbolTableX[i])\n\t\t\t\tif err != nil {\n\t\t\t\t\tprintf(\"RLE Transform table (%v) error: %v\", tableIndex(i), err)\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tseq.fse.setRLE(symb)\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintf(\"RLE set to 0x%x, code: %v\", symb, v)\n\t\t\t\t}\n\t\t\tcase compModeFSE:\n\t\t\t\tprintln(\"Reading table for\", tableIndex(i))\n\t\t\t\tif seq.fse == nil || seq.fse.preDefined {\n\t\t\t\t\tseq.fse = fseDecoderPool.Get().(*fseDecoder)\n\t\t\t\t}\n\t\t\t\terr := seq.fse.readNCount(&br, uint16(maxTableSymbol[i]))\n\t\t\t\tif err != nil {\n\t\t\t\t\tprintln(\"Read table error:\", err)\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\terr = seq.fse.transform(symbolTableX[i])\n\t\t\t\tif err != nil {\n\t\t\t\t\tprintln(\"Transform table error:\", err)\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"Read table ok\", \"symbolLen:\", seq.fse.symbolLen)\n\t\t\t\t}\n\t\t\tcase compModeRepeat:\n\t\t\t\tseq.repeat = true\n\t\t\t}\n\t\t\tif br.overread() {\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t}\n\t\tin = br.unread()\n\t}\n\tif debugDecoder {\n\t\tprintln(\"Literals:\", len(seqs.literals), \"hash:\", xxhash.Sum64(seqs.literals), \"and\", seqs.nSeqs, \"sequences.\")\n\t}\n\n\tif nSeqs == 0 {\n\t\tif len(b.sequence) > 0 {\n\t\t\tb.sequence = b.sequence[:0]\n\t\t}\n\t\treturn nil\n\t}\n\tbr := seqs.br\n\tif br == nil {\n\t\tbr = &bitReader{}\n\t}\n\tif err := br.init(in); err != nil {\n\t\treturn err\n\t}\n\n\tif err := seqs.initialize(br, hist, b.dst); err != nil {\n\t\tprintln(\"initializing sequences:\", err)\n\t\treturn err\n\t}\n\t// Extract blocks...\n\tif false && hist.dict == nil {\n\t\tfatalErr := func(err error) {\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t}\n\t\tfn := fmt.Sprintf(\"n-%d-lits-%d-prev-%d-%d-%d-win-%d.blk\", hist.decoders.nSeqs, len(hist.decoders.literals), hist.recentOffsets[0], hist.recentOffsets[1], hist.recentOffsets[2], hist.windowSize)\n\t\tvar buf bytes.Buffer\n\t\tfatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.litLengths.fse))\n\t\tfatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.matchLengths.fse))\n\t\tfatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.offsets.fse))\n\t\tbuf.Write(in)\n\t\tos.WriteFile(filepath.Join(\"testdata\", \"seqs\", fn), buf.Bytes(), os.ModePerm)\n\t}\n\n\treturn nil\n}\n\nfunc (b *blockDec) decodeSequences(hist *history) error {\n\tif cap(b.sequence) < hist.decoders.nSeqs {\n\t\tif b.lowMem {\n\t\t\tb.sequence = make([]seqVals, 0, hist.decoders.nSeqs)\n\t\t} else {\n\t\t\tb.sequence = make([]seqVals, 0, 0x7F00+0xffff)\n\t\t}\n\t}\n\tb.sequence = b.sequence[:hist.decoders.nSeqs]\n\tif hist.decoders.nSeqs == 0 {\n\t\thist.decoders.seqSize = len(hist.decoders.literals)\n\t\treturn nil\n\t}\n\thist.decoders.windowSize = hist.windowSize\n\thist.decoders.prevOffset = hist.recentOffsets\n\n\terr := hist.decoders.decode(b.sequence)\n\thist.recentOffsets = hist.decoders.prevOffset\n\treturn err\n}\n\nfunc (b *blockDec) executeSequences(hist *history) error {\n\thbytes := hist.b\n\tif len(hbytes) > hist.windowSize {\n\t\thbytes = hbytes[len(hbytes)-hist.windowSize:]\n\t\t// We do not need history anymore.\n\t\tif hist.dict != nil {\n\t\t\thist.dict.content = nil\n\t\t}\n\t}\n\thist.decoders.windowSize = hist.windowSize\n\thist.decoders.out = b.dst[:0]\n\terr := hist.decoders.execute(b.sequence, hbytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn b.updateHistory(hist)\n}\n\nfunc (b *blockDec) updateHistory(hist *history) error {\n\tif len(b.data) > maxCompressedBlockSize {\n\t\treturn fmt.Errorf(\"compressed block size too large (%d)\", len(b.data))\n\t}\n\t// Set output and release references.\n\tb.dst = hist.decoders.out\n\thist.recentOffsets = hist.decoders.prevOffset\n\n\tif b.Last {\n\t\t// if last block we don't care about history.\n\t\tprintln(\"Last block, no history returned\")\n\t\thist.b = hist.b[:0]\n\t\treturn nil\n\t} else {\n\t\thist.append(b.dst)\n\t\tif debugDecoder {\n\t\t\tprintln(\"Finished block with \", len(b.sequence), \"sequences. Added\", len(b.dst), \"to history, now length\", len(hist.b))\n\t\t}\n\t}\n\thist.decoders.out, hist.decoders.literals = nil, nil\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/blockenc.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/bits\"\n\n\t\"github.com/klauspost/compress/huff0\"\n)\n\ntype blockEnc struct {\n\tsize       int\n\tliterals   []byte\n\tsequences  []seq\n\tcoders     seqCoders\n\tlitEnc     *huff0.Scratch\n\tdictLitEnc *huff0.Scratch\n\twr         bitWriter\n\n\textraLits         int\n\toutput            []byte\n\trecentOffsets     [3]uint32\n\tprevRecentOffsets [3]uint32\n\n\tlast   bool\n\tlowMem bool\n}\n\n// init should be used once the block has been created.\n// If called more than once, the effect is the same as calling reset.\nfunc (b *blockEnc) init() {\n\tif b.lowMem {\n\t\t// 1K literals\n\t\tif cap(b.literals) < 1<<10 {\n\t\t\tb.literals = make([]byte, 0, 1<<10)\n\t\t}\n\t\tconst defSeqs = 20\n\t\tif cap(b.sequences) < defSeqs {\n\t\t\tb.sequences = make([]seq, 0, defSeqs)\n\t\t}\n\t\t// 1K\n\t\tif cap(b.output) < 1<<10 {\n\t\t\tb.output = make([]byte, 0, 1<<10)\n\t\t}\n\t} else {\n\t\tif cap(b.literals) < maxCompressedBlockSize {\n\t\t\tb.literals = make([]byte, 0, maxCompressedBlockSize)\n\t\t}\n\t\tconst defSeqs = 2000\n\t\tif cap(b.sequences) < defSeqs {\n\t\t\tb.sequences = make([]seq, 0, defSeqs)\n\t\t}\n\t\tif cap(b.output) < maxCompressedBlockSize {\n\t\t\tb.output = make([]byte, 0, maxCompressedBlockSize)\n\t\t}\n\t}\n\n\tif b.coders.mlEnc == nil {\n\t\tb.coders.mlEnc = &fseEncoder{}\n\t\tb.coders.mlPrev = &fseEncoder{}\n\t\tb.coders.ofEnc = &fseEncoder{}\n\t\tb.coders.ofPrev = &fseEncoder{}\n\t\tb.coders.llEnc = &fseEncoder{}\n\t\tb.coders.llPrev = &fseEncoder{}\n\t}\n\tb.litEnc = &huff0.Scratch{WantLogLess: 4}\n\tb.reset(nil)\n}\n\n// initNewEncode can be used to reset offsets and encoders to the initial state.\nfunc (b *blockEnc) initNewEncode() {\n\tb.recentOffsets = [3]uint32{1, 4, 8}\n\tb.litEnc.Reuse = huff0.ReusePolicyNone\n\tb.coders.setPrev(nil, nil, nil)\n}\n\n// reset will reset the block for a new encode, but in the same stream,\n// meaning that state will be carried over, but the block content is reset.\n// If a previous block is provided, the recent offsets are carried over.\nfunc (b *blockEnc) reset(prev *blockEnc) {\n\tb.extraLits = 0\n\tb.literals = b.literals[:0]\n\tb.size = 0\n\tb.sequences = b.sequences[:0]\n\tb.output = b.output[:0]\n\tb.last = false\n\tif prev != nil {\n\t\tb.recentOffsets = prev.prevRecentOffsets\n\t}\n\tb.dictLitEnc = nil\n}\n\n// reset will reset the block for a new encode, but in the same stream,\n// meaning that state will be carried over, but the block content is reset.\n// If a previous block is provided, the recent offsets are carried over.\nfunc (b *blockEnc) swapEncoders(prev *blockEnc) {\n\tb.coders.swap(&prev.coders)\n\tb.litEnc, prev.litEnc = prev.litEnc, b.litEnc\n}\n\n// blockHeader contains the information for a block header.\ntype blockHeader uint32\n\n// setLast sets the 'last' indicator on a block.\nfunc (h *blockHeader) setLast(b bool) {\n\tif b {\n\t\t*h = *h | 1\n\t} else {\n\t\tconst mask = (1 << 24) - 2\n\t\t*h = *h & mask\n\t}\n}\n\n// setSize will store the compressed size of a block.\nfunc (h *blockHeader) setSize(v uint32) {\n\tconst mask = 7\n\t*h = (*h)&mask | blockHeader(v<<3)\n}\n\n// setType sets the block type.\nfunc (h *blockHeader) setType(t blockType) {\n\tconst mask = 1 | (((1 << 24) - 1) ^ 7)\n\t*h = (*h & mask) | blockHeader(t<<1)\n}\n\n// appendTo will append the block header to a slice.\nfunc (h blockHeader) appendTo(b []byte) []byte {\n\treturn append(b, uint8(h), uint8(h>>8), uint8(h>>16))\n}\n\n// String returns a string representation of the block.\nfunc (h blockHeader) String() string {\n\treturn fmt.Sprintf(\"Type: %d, Size: %d, Last:%t\", (h>>1)&3, h>>3, h&1 == 1)\n}\n\n// literalsHeader contains literals header information.\ntype literalsHeader uint64\n\n// setType can be used to set the type of literal block.\nfunc (h *literalsHeader) setType(t literalsBlockType) {\n\tconst mask = math.MaxUint64 - 3\n\t*h = (*h & mask) | literalsHeader(t)\n}\n\n// setSize can be used to set a single size, for uncompressed and RLE content.\nfunc (h *literalsHeader) setSize(regenLen int) {\n\tinBits := bits.Len32(uint32(regenLen))\n\t// Only retain 2 bits\n\tconst mask = 3\n\tlh := uint64(*h & mask)\n\tswitch {\n\tcase inBits < 5:\n\t\tlh |= (uint64(regenLen) << 3) | (1 << 60)\n\t\tif debugEncoder {\n\t\t\tgot := int(lh>>3) & 0xff\n\t\t\tif got != regenLen {\n\t\t\t\tpanic(fmt.Sprint(\"litRegenSize = \", regenLen, \"(want) != \", got, \"(got)\"))\n\t\t\t}\n\t\t}\n\tcase inBits < 12:\n\t\tlh |= (1 << 2) | (uint64(regenLen) << 4) | (2 << 60)\n\tcase inBits < 20:\n\t\tlh |= (3 << 2) | (uint64(regenLen) << 4) | (3 << 60)\n\tdefault:\n\t\tpanic(fmt.Errorf(\"internal error: block too big (%d)\", regenLen))\n\t}\n\t*h = literalsHeader(lh)\n}\n\n// setSizes will set the size of a compressed literals section and the input length.\nfunc (h *literalsHeader) setSizes(compLen, inLen int, single bool) {\n\tcompBits, inBits := bits.Len32(uint32(compLen)), bits.Len32(uint32(inLen))\n\t// Only retain 2 bits\n\tconst mask = 3\n\tlh := uint64(*h & mask)\n\tswitch {\n\tcase compBits <= 10 && inBits <= 10:\n\t\tif !single {\n\t\t\tlh |= 1 << 2\n\t\t}\n\t\tlh |= (uint64(inLen) << 4) | (uint64(compLen) << (10 + 4)) | (3 << 60)\n\t\tif debugEncoder {\n\t\t\tconst mmask = (1 << 24) - 1\n\t\t\tn := (lh >> 4) & mmask\n\t\t\tif int(n&1023) != inLen {\n\t\t\t\tpanic(fmt.Sprint(\"regensize:\", int(n&1023), \"!=\", inLen, inBits))\n\t\t\t}\n\t\t\tif int(n>>10) != compLen {\n\t\t\t\tpanic(fmt.Sprint(\"compsize:\", int(n>>10), \"!=\", compLen, compBits))\n\t\t\t}\n\t\t}\n\tcase compBits <= 14 && inBits <= 14:\n\t\tlh |= (2 << 2) | (uint64(inLen) << 4) | (uint64(compLen) << (14 + 4)) | (4 << 60)\n\t\tif single {\n\t\t\tpanic(\"single stream used with more than 10 bits length.\")\n\t\t}\n\tcase compBits <= 18 && inBits <= 18:\n\t\tlh |= (3 << 2) | (uint64(inLen) << 4) | (uint64(compLen) << (18 + 4)) | (5 << 60)\n\t\tif single {\n\t\t\tpanic(\"single stream used with more than 10 bits length.\")\n\t\t}\n\tdefault:\n\t\tpanic(\"internal error: block too big\")\n\t}\n\t*h = literalsHeader(lh)\n}\n\n// appendTo will append the literals header to a byte slice.\nfunc (h literalsHeader) appendTo(b []byte) []byte {\n\tsize := uint8(h >> 60)\n\tswitch size {\n\tcase 1:\n\t\tb = append(b, uint8(h))\n\tcase 2:\n\t\tb = append(b, uint8(h), uint8(h>>8))\n\tcase 3:\n\t\tb = append(b, uint8(h), uint8(h>>8), uint8(h>>16))\n\tcase 4:\n\t\tb = append(b, uint8(h), uint8(h>>8), uint8(h>>16), uint8(h>>24))\n\tcase 5:\n\t\tb = append(b, uint8(h), uint8(h>>8), uint8(h>>16), uint8(h>>24), uint8(h>>32))\n\tdefault:\n\t\tpanic(fmt.Errorf(\"internal error: literalsHeader has invalid size (%d)\", size))\n\t}\n\treturn b\n}\n\n// size returns the output size with currently set values.\nfunc (h literalsHeader) size() int {\n\treturn int(h >> 60)\n}\n\nfunc (h literalsHeader) String() string {\n\treturn fmt.Sprintf(\"Type: %d, SizeFormat: %d, Size: 0x%d, Bytes:%d\", literalsBlockType(h&3), (h>>2)&3, h&((1<<60)-1)>>4, h>>60)\n}\n\n// pushOffsets will push the recent offsets to the backup store.\nfunc (b *blockEnc) pushOffsets() {\n\tb.prevRecentOffsets = b.recentOffsets\n}\n\n// pushOffsets will push the recent offsets to the backup store.\nfunc (b *blockEnc) popOffsets() {\n\tb.recentOffsets = b.prevRecentOffsets\n}\n\n// matchOffset will adjust recent offsets and return the adjusted one,\n// if it matches a previous offset.\nfunc (b *blockEnc) matchOffset(offset, lits uint32) uint32 {\n\t// Check if offset is one of the recent offsets.\n\t// Adjusts the output offset accordingly.\n\t// Gives a tiny bit of compression, typically around 1%.\n\tif true {\n\t\tif lits > 0 {\n\t\t\tswitch offset {\n\t\t\tcase b.recentOffsets[0]:\n\t\t\t\toffset = 1\n\t\t\tcase b.recentOffsets[1]:\n\t\t\t\tb.recentOffsets[1] = b.recentOffsets[0]\n\t\t\t\tb.recentOffsets[0] = offset\n\t\t\t\toffset = 2\n\t\t\tcase b.recentOffsets[2]:\n\t\t\t\tb.recentOffsets[2] = b.recentOffsets[1]\n\t\t\t\tb.recentOffsets[1] = b.recentOffsets[0]\n\t\t\t\tb.recentOffsets[0] = offset\n\t\t\t\toffset = 3\n\t\t\tdefault:\n\t\t\t\tb.recentOffsets[2] = b.recentOffsets[1]\n\t\t\t\tb.recentOffsets[1] = b.recentOffsets[0]\n\t\t\t\tb.recentOffsets[0] = offset\n\t\t\t\toffset += 3\n\t\t\t}\n\t\t} else {\n\t\t\tswitch offset {\n\t\t\tcase b.recentOffsets[1]:\n\t\t\t\tb.recentOffsets[1] = b.recentOffsets[0]\n\t\t\t\tb.recentOffsets[0] = offset\n\t\t\t\toffset = 1\n\t\t\tcase b.recentOffsets[2]:\n\t\t\t\tb.recentOffsets[2] = b.recentOffsets[1]\n\t\t\t\tb.recentOffsets[1] = b.recentOffsets[0]\n\t\t\t\tb.recentOffsets[0] = offset\n\t\t\t\toffset = 2\n\t\t\tcase b.recentOffsets[0] - 1:\n\t\t\t\tb.recentOffsets[2] = b.recentOffsets[1]\n\t\t\t\tb.recentOffsets[1] = b.recentOffsets[0]\n\t\t\t\tb.recentOffsets[0] = offset\n\t\t\t\toffset = 3\n\t\t\tdefault:\n\t\t\t\tb.recentOffsets[2] = b.recentOffsets[1]\n\t\t\t\tb.recentOffsets[1] = b.recentOffsets[0]\n\t\t\t\tb.recentOffsets[0] = offset\n\t\t\t\toffset += 3\n\t\t\t}\n\t\t}\n\t} else {\n\t\toffset += 3\n\t}\n\treturn offset\n}\n\n// encodeRaw can be used to set the output to a raw representation of supplied bytes.\nfunc (b *blockEnc) encodeRaw(a []byte) {\n\tvar bh blockHeader\n\tbh.setLast(b.last)\n\tbh.setSize(uint32(len(a)))\n\tbh.setType(blockTypeRaw)\n\tb.output = bh.appendTo(b.output[:0])\n\tb.output = append(b.output, a...)\n\tif debugEncoder {\n\t\tprintln(\"Adding RAW block, length\", len(a), \"last:\", b.last)\n\t}\n}\n\n// encodeRaw can be used to set the output to a raw representation of supplied bytes.\nfunc (b *blockEnc) encodeRawTo(dst, src []byte) []byte {\n\tvar bh blockHeader\n\tbh.setLast(b.last)\n\tbh.setSize(uint32(len(src)))\n\tbh.setType(blockTypeRaw)\n\tdst = bh.appendTo(dst)\n\tdst = append(dst, src...)\n\tif debugEncoder {\n\t\tprintln(\"Adding RAW block, length\", len(src), \"last:\", b.last)\n\t}\n\treturn dst\n}\n\n// encodeLits can be used if the block is only litLen.\nfunc (b *blockEnc) encodeLits(lits []byte, raw bool) error {\n\tvar bh blockHeader\n\tbh.setLast(b.last)\n\tbh.setSize(uint32(len(lits)))\n\n\t// Don't compress extremely small blocks\n\tif len(lits) < 8 || (len(lits) < 32 && b.dictLitEnc == nil) || raw {\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding RAW block, length\", len(lits), \"last:\", b.last)\n\t\t}\n\t\tbh.setType(blockTypeRaw)\n\t\tb.output = bh.appendTo(b.output)\n\t\tb.output = append(b.output, lits...)\n\t\treturn nil\n\t}\n\n\tvar (\n\t\tout            []byte\n\t\treUsed, single bool\n\t\terr            error\n\t)\n\tif b.dictLitEnc != nil {\n\t\tb.litEnc.TransferCTable(b.dictLitEnc)\n\t\tb.litEnc.Reuse = huff0.ReusePolicyAllow\n\t\tb.dictLitEnc = nil\n\t}\n\tif len(lits) >= 1024 {\n\t\t// Use 4 Streams.\n\t\tout, reUsed, err = huff0.Compress4X(lits, b.litEnc)\n\t} else if len(lits) > 16 {\n\t\t// Use 1 stream\n\t\tsingle = true\n\t\tout, reUsed, err = huff0.Compress1X(lits, b.litEnc)\n\t} else {\n\t\terr = huff0.ErrIncompressible\n\t}\n\tif err == nil && len(out)+5 > len(lits) {\n\t\t// If we are close, we may still be worse or equal to raw.\n\t\tvar lh literalsHeader\n\t\tlh.setSizes(len(out), len(lits), single)\n\t\tif len(out)+lh.size() >= len(lits) {\n\t\t\terr = huff0.ErrIncompressible\n\t\t}\n\t}\n\tswitch err {\n\tcase huff0.ErrIncompressible:\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding RAW block, length\", len(lits), \"last:\", b.last)\n\t\t}\n\t\tbh.setType(blockTypeRaw)\n\t\tb.output = bh.appendTo(b.output)\n\t\tb.output = append(b.output, lits...)\n\t\treturn nil\n\tcase huff0.ErrUseRLE:\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding RLE block, length\", len(lits))\n\t\t}\n\t\tbh.setType(blockTypeRLE)\n\t\tb.output = bh.appendTo(b.output)\n\t\tb.output = append(b.output, lits[0])\n\t\treturn nil\n\tcase nil:\n\tdefault:\n\t\treturn err\n\t}\n\t// Compressed...\n\t// Now, allow reuse\n\tb.litEnc.Reuse = huff0.ReusePolicyAllow\n\tbh.setType(blockTypeCompressed)\n\tvar lh literalsHeader\n\tif reUsed {\n\t\tif debugEncoder {\n\t\t\tprintln(\"Reused tree, compressed to\", len(out))\n\t\t}\n\t\tlh.setType(literalsBlockTreeless)\n\t} else {\n\t\tif debugEncoder {\n\t\t\tprintln(\"New tree, compressed to\", len(out), \"tree size:\", len(b.litEnc.OutTable))\n\t\t}\n\t\tlh.setType(literalsBlockCompressed)\n\t}\n\t// Set sizes\n\tlh.setSizes(len(out), len(lits), single)\n\tbh.setSize(uint32(len(out) + lh.size() + 1))\n\n\t// Write block headers.\n\tb.output = bh.appendTo(b.output)\n\tb.output = lh.appendTo(b.output)\n\t// Add compressed data.\n\tb.output = append(b.output, out...)\n\t// No sequences.\n\tb.output = append(b.output, 0)\n\treturn nil\n}\n\n// fuzzFseEncoder can be used to fuzz the FSE encoder.\nfunc fuzzFseEncoder(data []byte) int {\n\tif len(data) > maxSequences || len(data) < 2 {\n\t\treturn 0\n\t}\n\tenc := fseEncoder{}\n\thist := enc.Histogram()\n\tmaxSym := uint8(0)\n\tfor i, v := range data {\n\t\tv = v & 63\n\t\tdata[i] = v\n\t\thist[v]++\n\t\tif v > maxSym {\n\t\t\tmaxSym = v\n\t\t}\n\t}\n\tif maxSym == 0 {\n\t\t// All 0\n\t\treturn 0\n\t}\n\tmaxCount := func(a []uint32) int {\n\t\tvar max uint32\n\t\tfor _, v := range a {\n\t\t\tif v > max {\n\t\t\t\tmax = v\n\t\t\t}\n\t\t}\n\t\treturn int(max)\n\t}\n\tcnt := maxCount(hist[:maxSym])\n\tif cnt == len(data) {\n\t\t// RLE\n\t\treturn 0\n\t}\n\tenc.HistogramFinished(maxSym, cnt)\n\terr := enc.normalizeCount(len(data))\n\tif err != nil {\n\t\treturn 0\n\t}\n\t_, err = enc.writeCount(nil)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn 1\n}\n\n// encode will encode the block and append the output in b.output.\n// Previous offset codes must be pushed if more blocks are expected.\nfunc (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {\n\tif len(b.sequences) == 0 {\n\t\treturn b.encodeLits(b.literals, rawAllLits)\n\t}\n\t// We want some difference to at least account for the headers.\n\tsaved := b.size - len(b.literals) - (b.size >> 6)\n\tif saved < 16 {\n\t\tif org == nil {\n\t\t\treturn errIncompressible\n\t\t}\n\t\tb.popOffsets()\n\t\treturn b.encodeLits(org, rawAllLits)\n\t}\n\n\tvar bh blockHeader\n\tvar lh literalsHeader\n\tbh.setLast(b.last)\n\tbh.setType(blockTypeCompressed)\n\t// Store offset of the block header. Needed when we know the size.\n\tbhOffset := len(b.output)\n\tb.output = bh.appendTo(b.output)\n\n\tvar (\n\t\tout            []byte\n\t\treUsed, single bool\n\t\terr            error\n\t)\n\tif b.dictLitEnc != nil {\n\t\tb.litEnc.TransferCTable(b.dictLitEnc)\n\t\tb.litEnc.Reuse = huff0.ReusePolicyAllow\n\t\tb.dictLitEnc = nil\n\t}\n\tif len(b.literals) >= 1024 && !raw {\n\t\t// Use 4 Streams.\n\t\tout, reUsed, err = huff0.Compress4X(b.literals, b.litEnc)\n\t} else if len(b.literals) > 16 && !raw {\n\t\t// Use 1 stream\n\t\tsingle = true\n\t\tout, reUsed, err = huff0.Compress1X(b.literals, b.litEnc)\n\t} else {\n\t\terr = huff0.ErrIncompressible\n\t}\n\n\tif err == nil && len(out)+5 > len(b.literals) {\n\t\t// If we are close, we may still be worse or equal to raw.\n\t\tvar lh literalsHeader\n\t\tlh.setSize(len(b.literals))\n\t\tszRaw := lh.size()\n\t\tlh.setSizes(len(out), len(b.literals), single)\n\t\tszComp := lh.size()\n\t\tif len(out)+szComp >= len(b.literals)+szRaw {\n\t\t\terr = huff0.ErrIncompressible\n\t\t}\n\t}\n\tswitch err {\n\tcase huff0.ErrIncompressible:\n\t\tlh.setType(literalsBlockRaw)\n\t\tlh.setSize(len(b.literals))\n\t\tb.output = lh.appendTo(b.output)\n\t\tb.output = append(b.output, b.literals...)\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding literals RAW, length\", len(b.literals))\n\t\t}\n\tcase huff0.ErrUseRLE:\n\t\tlh.setType(literalsBlockRLE)\n\t\tlh.setSize(len(b.literals))\n\t\tb.output = lh.appendTo(b.output)\n\t\tb.output = append(b.output, b.literals[0])\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding literals RLE\")\n\t\t}\n\tcase nil:\n\t\t// Compressed litLen...\n\t\tif reUsed {\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"reused tree\")\n\t\t\t}\n\t\t\tlh.setType(literalsBlockTreeless)\n\t\t} else {\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"new tree, size:\", len(b.litEnc.OutTable))\n\t\t\t}\n\t\t\tlh.setType(literalsBlockCompressed)\n\t\t\tif debugEncoder {\n\t\t\t\t_, _, err := huff0.ReadTable(out, nil)\n\t\t\t\tif err != nil {\n\t\t\t\t\tpanic(err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlh.setSizes(len(out), len(b.literals), single)\n\t\tif debugEncoder {\n\t\t\tprintf(\"Compressed %d literals to %d bytes\", len(b.literals), len(out))\n\t\t\tprintln(\"Adding literal header:\", lh)\n\t\t}\n\t\tb.output = lh.appendTo(b.output)\n\t\tb.output = append(b.output, out...)\n\t\tb.litEnc.Reuse = huff0.ReusePolicyAllow\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding literals compressed\")\n\t\t}\n\tdefault:\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding literals ERROR:\", err)\n\t\t}\n\t\treturn err\n\t}\n\t// Sequence compression\n\n\t// Write the number of sequences\n\tswitch {\n\tcase len(b.sequences) < 128:\n\t\tb.output = append(b.output, uint8(len(b.sequences)))\n\tcase len(b.sequences) < 0x7f00: // TODO: this could be wrong\n\t\tn := len(b.sequences)\n\t\tb.output = append(b.output, 128+uint8(n>>8), uint8(n))\n\tdefault:\n\t\tn := len(b.sequences) - 0x7f00\n\t\tb.output = append(b.output, 255, uint8(n), uint8(n>>8))\n\t}\n\tif debugEncoder {\n\t\tprintln(\"Encoding\", len(b.sequences), \"sequences\")\n\t}\n\tb.genCodes()\n\tllEnc := b.coders.llEnc\n\tofEnc := b.coders.ofEnc\n\tmlEnc := b.coders.mlEnc\n\terr = llEnc.normalizeCount(len(b.sequences))\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = ofEnc.normalizeCount(len(b.sequences))\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = mlEnc.normalizeCount(len(b.sequences))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Choose the best compression mode for each type.\n\t// Will evaluate the new vs predefined and previous.\n\tchooseComp := func(cur, prev, preDef *fseEncoder) (*fseEncoder, seqCompMode) {\n\t\t// See if predefined/previous is better\n\t\thist := cur.count[:cur.symbolLen]\n\t\tnSize := cur.approxSize(hist) + cur.maxHeaderSize()\n\t\tpredefSize := preDef.approxSize(hist)\n\t\tprevSize := prev.approxSize(hist)\n\n\t\t// Add a small penalty for new encoders.\n\t\t// Don't bother with extremely small (<2 byte gains).\n\t\tnSize = nSize + (nSize+2*8*16)>>4\n\t\tswitch {\n\t\tcase predefSize <= prevSize && predefSize <= nSize || forcePreDef:\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"Using predefined\", predefSize>>3, \"<=\", nSize>>3)\n\t\t\t}\n\t\t\treturn preDef, compModePredefined\n\t\tcase prevSize <= nSize:\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"Using previous\", prevSize>>3, \"<=\", nSize>>3)\n\t\t\t}\n\t\t\treturn prev, compModeRepeat\n\t\tdefault:\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"Using new, predef\", predefSize>>3, \". previous:\", prevSize>>3, \">\", nSize>>3, \"header max:\", cur.maxHeaderSize()>>3, \"bytes\")\n\t\t\t\tprintln(\"tl:\", cur.actualTableLog, \"symbolLen:\", cur.symbolLen, \"norm:\", cur.norm[:cur.symbolLen], \"hist\", cur.count[:cur.symbolLen])\n\t\t\t}\n\t\t\treturn cur, compModeFSE\n\t\t}\n\t}\n\n\t// Write compression mode\n\tvar mode uint8\n\tif llEnc.useRLE {\n\t\tmode |= uint8(compModeRLE) << 6\n\t\tllEnc.setRLE(b.sequences[0].llCode)\n\t\tif debugEncoder {\n\t\t\tprintln(\"llEnc.useRLE\")\n\t\t}\n\t} else {\n\t\tvar m seqCompMode\n\t\tllEnc, m = chooseComp(llEnc, b.coders.llPrev, &fsePredefEnc[tableLiteralLengths])\n\t\tmode |= uint8(m) << 6\n\t}\n\tif ofEnc.useRLE {\n\t\tmode |= uint8(compModeRLE) << 4\n\t\tofEnc.setRLE(b.sequences[0].ofCode)\n\t\tif debugEncoder {\n\t\t\tprintln(\"ofEnc.useRLE\")\n\t\t}\n\t} else {\n\t\tvar m seqCompMode\n\t\tofEnc, m = chooseComp(ofEnc, b.coders.ofPrev, &fsePredefEnc[tableOffsets])\n\t\tmode |= uint8(m) << 4\n\t}\n\n\tif mlEnc.useRLE {\n\t\tmode |= uint8(compModeRLE) << 2\n\t\tmlEnc.setRLE(b.sequences[0].mlCode)\n\t\tif debugEncoder {\n\t\t\tprintln(\"mlEnc.useRLE, code: \", b.sequences[0].mlCode, \"value\", b.sequences[0].matchLen)\n\t\t}\n\t} else {\n\t\tvar m seqCompMode\n\t\tmlEnc, m = chooseComp(mlEnc, b.coders.mlPrev, &fsePredefEnc[tableMatchLengths])\n\t\tmode |= uint8(m) << 2\n\t}\n\tb.output = append(b.output, mode)\n\tif debugEncoder {\n\t\tprintf(\"Compression modes: 0b%b\", mode)\n\t}\n\tb.output, err = llEnc.writeCount(b.output)\n\tif err != nil {\n\t\treturn err\n\t}\n\tstart := len(b.output)\n\tb.output, err = ofEnc.writeCount(b.output)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif false {\n\t\tprintln(\"block:\", b.output[start:], \"tablelog\", ofEnc.actualTableLog, \"maxcount:\", ofEnc.maxCount)\n\t\tfmt.Printf(\"selected TableLog: %d, Symbol length: %d\\n\", ofEnc.actualTableLog, ofEnc.symbolLen)\n\t\tfor i, v := range ofEnc.norm[:ofEnc.symbolLen] {\n\t\t\tfmt.Printf(\"%3d: %5d -> %4d \\n\", i, ofEnc.count[i], v)\n\t\t}\n\t}\n\tb.output, err = mlEnc.writeCount(b.output)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Maybe in block?\n\twr := &b.wr\n\twr.reset(b.output)\n\n\tvar ll, of, ml cState\n\n\t// Current sequence\n\tseq := len(b.sequences) - 1\n\ts := b.sequences[seq]\n\tllEnc.setBits(llBitsTable[:])\n\tmlEnc.setBits(mlBitsTable[:])\n\tofEnc.setBits(nil)\n\n\tllTT, ofTT, mlTT := llEnc.ct.symbolTT[:256], ofEnc.ct.symbolTT[:256], mlEnc.ct.symbolTT[:256]\n\n\t// We have 3 bounds checks here (and in the loop).\n\t// Since we are iterating backwards it is kinda hard to avoid.\n\tllB, ofB, mlB := llTT[s.llCode], ofTT[s.ofCode], mlTT[s.mlCode]\n\tll.init(wr, &llEnc.ct, llB)\n\tof.init(wr, &ofEnc.ct, ofB)\n\twr.flush32()\n\tml.init(wr, &mlEnc.ct, mlB)\n\n\t// Each of these lookups also generates a bounds check.\n\twr.addBits32NC(s.litLen, llB.outBits)\n\twr.addBits32NC(s.matchLen, mlB.outBits)\n\twr.flush32()\n\twr.addBits32NC(s.offset, ofB.outBits)\n\tif debugSequences {\n\t\tprintln(\"Encoded seq\", seq, s, \"codes:\", s.llCode, s.mlCode, s.ofCode, \"states:\", ll.state, ml.state, of.state, \"bits:\", llB, mlB, ofB)\n\t}\n\tseq--\n\t// Store sequences in reverse...\n\tfor seq >= 0 {\n\t\ts = b.sequences[seq]\n\n\t\tofB := ofTT[s.ofCode]\n\t\twr.flush32() // tablelog max is below 8 for each, so it will fill max 24 bits.\n\t\t//of.encode(ofB)\n\t\tnbBitsOut := (uint32(of.state) + ofB.deltaNbBits) >> 16\n\t\tdstState := int32(of.state>>(nbBitsOut&15)) + int32(ofB.deltaFindState)\n\t\twr.addBits16NC(of.state, uint8(nbBitsOut))\n\t\tof.state = of.stateTable[dstState]\n\n\t\t// Accumulate extra bits.\n\t\toutBits := ofB.outBits & 31\n\t\textraBits := uint64(s.offset & bitMask32[outBits])\n\t\textraBitsN := outBits\n\n\t\tmlB := mlTT[s.mlCode]\n\t\t//ml.encode(mlB)\n\t\tnbBitsOut = (uint32(ml.state) + mlB.deltaNbBits) >> 16\n\t\tdstState = int32(ml.state>>(nbBitsOut&15)) + int32(mlB.deltaFindState)\n\t\twr.addBits16NC(ml.state, uint8(nbBitsOut))\n\t\tml.state = ml.stateTable[dstState]\n\n\t\toutBits = mlB.outBits & 31\n\t\textraBits = extraBits<<outBits | uint64(s.matchLen&bitMask32[outBits])\n\t\textraBitsN += outBits\n\n\t\tllB := llTT[s.llCode]\n\t\t//ll.encode(llB)\n\t\tnbBitsOut = (uint32(ll.state) + llB.deltaNbBits) >> 16\n\t\tdstState = int32(ll.state>>(nbBitsOut&15)) + int32(llB.deltaFindState)\n\t\twr.addBits16NC(ll.state, uint8(nbBitsOut))\n\t\tll.state = ll.stateTable[dstState]\n\n\t\toutBits = llB.outBits & 31\n\t\textraBits = extraBits<<outBits | uint64(s.litLen&bitMask32[outBits])\n\t\textraBitsN += outBits\n\n\t\twr.flush32()\n\t\twr.addBits64NC(extraBits, extraBitsN)\n\n\t\tif debugSequences {\n\t\t\tprintln(\"Encoded seq\", seq, s)\n\t\t}\n\n\t\tseq--\n\t}\n\tml.flush(mlEnc.actualTableLog)\n\tof.flush(ofEnc.actualTableLog)\n\tll.flush(llEnc.actualTableLog)\n\twr.close()\n\tb.output = wr.out\n\n\t// Maybe even add a bigger margin.\n\tif len(b.output)-3-bhOffset >= b.size {\n\t\t// Discard and encode as raw block.\n\t\tb.output = b.encodeRawTo(b.output[:bhOffset], org)\n\t\tb.popOffsets()\n\t\tb.litEnc.Reuse = huff0.ReusePolicyNone\n\t\treturn nil\n\t}\n\n\t// Size is output minus block header.\n\tbh.setSize(uint32(len(b.output)-bhOffset) - 3)\n\tif debugEncoder {\n\t\tprintln(\"Rewriting block header\", bh)\n\t}\n\t_ = bh.appendTo(b.output[bhOffset:bhOffset])\n\tb.coders.setPrev(llEnc, mlEnc, ofEnc)\n\treturn nil\n}\n\nvar errIncompressible = errors.New(\"incompressible\")\n\nfunc (b *blockEnc) genCodes() {\n\tif len(b.sequences) == 0 {\n\t\t// nothing to do\n\t\treturn\n\t}\n\tif len(b.sequences) > math.MaxUint16 {\n\t\tpanic(\"can only encode up to 64K sequences\")\n\t}\n\t// No bounds checks after here:\n\tllH := b.coders.llEnc.Histogram()\n\tofH := b.coders.ofEnc.Histogram()\n\tmlH := b.coders.mlEnc.Histogram()\n\tfor i := range llH {\n\t\tllH[i] = 0\n\t}\n\tfor i := range ofH {\n\t\tofH[i] = 0\n\t}\n\tfor i := range mlH {\n\t\tmlH[i] = 0\n\t}\n\n\tvar llMax, ofMax, mlMax uint8\n\tfor i := range b.sequences {\n\t\tseq := &b.sequences[i]\n\t\tv := llCode(seq.litLen)\n\t\tseq.llCode = v\n\t\tllH[v]++\n\t\tif v > llMax {\n\t\t\tllMax = v\n\t\t}\n\n\t\tv = ofCode(seq.offset)\n\t\tseq.ofCode = v\n\t\tofH[v]++\n\t\tif v > ofMax {\n\t\t\tofMax = v\n\t\t}\n\n\t\tv = mlCode(seq.matchLen)\n\t\tseq.mlCode = v\n\t\tmlH[v]++\n\t\tif v > mlMax {\n\t\t\tmlMax = v\n\t\t\tif debugAsserts && mlMax > maxMatchLengthSymbol {\n\t\t\t\tpanic(fmt.Errorf(\"mlMax > maxMatchLengthSymbol (%d), matchlen: %d\", mlMax, seq.matchLen))\n\t\t\t}\n\t\t}\n\t}\n\tmaxCount := func(a []uint32) int {\n\t\tvar max uint32\n\t\tfor _, v := range a {\n\t\t\tif v > max {\n\t\t\t\tmax = v\n\t\t\t}\n\t\t}\n\t\treturn int(max)\n\t}\n\tif debugAsserts && mlMax > maxMatchLengthSymbol {\n\t\tpanic(fmt.Errorf(\"mlMax > maxMatchLengthSymbol (%d)\", mlMax))\n\t}\n\tif debugAsserts && ofMax > maxOffsetBits {\n\t\tpanic(fmt.Errorf(\"ofMax > maxOffsetBits (%d)\", ofMax))\n\t}\n\tif debugAsserts && llMax > maxLiteralLengthSymbol {\n\t\tpanic(fmt.Errorf(\"llMax > maxLiteralLengthSymbol (%d)\", llMax))\n\t}\n\n\tb.coders.mlEnc.HistogramFinished(mlMax, maxCount(mlH[:mlMax+1]))\n\tb.coders.ofEnc.HistogramFinished(ofMax, maxCount(ofH[:ofMax+1]))\n\tb.coders.llEnc.HistogramFinished(llMax, maxCount(llH[:llMax+1]))\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/blocktype_string.go",
    "content": "// Code generated by \"stringer -type=blockType,literalsBlockType,seqCompMode,tableIndex\"; DO NOT EDIT.\n\npackage zstd\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[blockTypeRaw-0]\n\t_ = x[blockTypeRLE-1]\n\t_ = x[blockTypeCompressed-2]\n\t_ = x[blockTypeReserved-3]\n}\n\nconst _blockType_name = \"blockTypeRawblockTypeRLEblockTypeCompressedblockTypeReserved\"\n\nvar _blockType_index = [...]uint8{0, 12, 24, 43, 60}\n\nfunc (i blockType) String() string {\n\tif i >= blockType(len(_blockType_index)-1) {\n\t\treturn \"blockType(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _blockType_name[_blockType_index[i]:_blockType_index[i+1]]\n}\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[literalsBlockRaw-0]\n\t_ = x[literalsBlockRLE-1]\n\t_ = x[literalsBlockCompressed-2]\n\t_ = x[literalsBlockTreeless-3]\n}\n\nconst _literalsBlockType_name = \"literalsBlockRawliteralsBlockRLEliteralsBlockCompressedliteralsBlockTreeless\"\n\nvar _literalsBlockType_index = [...]uint8{0, 16, 32, 55, 76}\n\nfunc (i literalsBlockType) String() string {\n\tif i >= literalsBlockType(len(_literalsBlockType_index)-1) {\n\t\treturn \"literalsBlockType(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _literalsBlockType_name[_literalsBlockType_index[i]:_literalsBlockType_index[i+1]]\n}\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[compModePredefined-0]\n\t_ = x[compModeRLE-1]\n\t_ = x[compModeFSE-2]\n\t_ = x[compModeRepeat-3]\n}\n\nconst _seqCompMode_name = \"compModePredefinedcompModeRLEcompModeFSEcompModeRepeat\"\n\nvar _seqCompMode_index = [...]uint8{0, 18, 29, 40, 54}\n\nfunc (i seqCompMode) String() string {\n\tif i >= seqCompMode(len(_seqCompMode_index)-1) {\n\t\treturn \"seqCompMode(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _seqCompMode_name[_seqCompMode_index[i]:_seqCompMode_index[i+1]]\n}\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[tableLiteralLengths-0]\n\t_ = x[tableOffsets-1]\n\t_ = x[tableMatchLengths-2]\n}\n\nconst _tableIndex_name = \"tableLiteralLengthstableOffsetstableMatchLengths\"\n\nvar _tableIndex_index = [...]uint8{0, 19, 31, 48}\n\nfunc (i tableIndex) String() string {\n\tif i >= tableIndex(len(_tableIndex_index)-1) {\n\t\treturn \"tableIndex(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _tableIndex_name[_tableIndex_index[i]:_tableIndex_index[i+1]]\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/bytebuf.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype byteBuffer interface {\n\t// Read up to 8 bytes.\n\t// Returns io.ErrUnexpectedEOF if this cannot be satisfied.\n\treadSmall(n int) ([]byte, error)\n\n\t// Read >8 bytes.\n\t// MAY use the destination slice.\n\treadBig(n int, dst []byte) ([]byte, error)\n\n\t// Read a single byte.\n\treadByte() (byte, error)\n\n\t// Skip n bytes.\n\tskipN(n int64) error\n}\n\n// in-memory buffer\ntype byteBuf []byte\n\nfunc (b *byteBuf) readSmall(n int) ([]byte, error) {\n\tif debugAsserts && n > 8 {\n\t\tpanic(fmt.Errorf(\"small read > 8 (%d). use readBig\", n))\n\t}\n\tbb := *b\n\tif len(bb) < n {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tr := bb[:n]\n\t*b = bb[n:]\n\treturn r, nil\n}\n\nfunc (b *byteBuf) readBig(n int, dst []byte) ([]byte, error) {\n\tbb := *b\n\tif len(bb) < n {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\tr := bb[:n]\n\t*b = bb[n:]\n\treturn r, nil\n}\n\nfunc (b *byteBuf) readByte() (byte, error) {\n\tbb := *b\n\tif len(bb) < 1 {\n\t\treturn 0, io.ErrUnexpectedEOF\n\t}\n\tr := bb[0]\n\t*b = bb[1:]\n\treturn r, nil\n}\n\nfunc (b *byteBuf) skipN(n int64) error {\n\tbb := *b\n\tif n < 0 {\n\t\treturn fmt.Errorf(\"negative skip (%d) requested\", n)\n\t}\n\tif int64(len(bb)) < n {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\t*b = bb[n:]\n\treturn nil\n}\n\n// wrapper around a reader.\ntype readerWrapper struct {\n\tr   io.Reader\n\ttmp [8]byte\n}\n\nfunc (r *readerWrapper) readSmall(n int) ([]byte, error) {\n\tif debugAsserts && n > 8 {\n\t\tpanic(fmt.Errorf(\"small read > 8 (%d). use readBig\", n))\n\t}\n\tn2, err := io.ReadFull(r.r, r.tmp[:n])\n\t// We only really care about the actual bytes read.\n\tif err != nil {\n\t\tif err == io.EOF {\n\t\t\treturn nil, io.ErrUnexpectedEOF\n\t\t}\n\t\tif debugDecoder {\n\t\t\tprintln(\"readSmall: got\", n2, \"want\", n, \"err\", err)\n\t\t}\n\t\treturn nil, err\n\t}\n\treturn r.tmp[:n], nil\n}\n\nfunc (r *readerWrapper) readBig(n int, dst []byte) ([]byte, error) {\n\tif cap(dst) < n {\n\t\tdst = make([]byte, n)\n\t}\n\tn2, err := io.ReadFull(r.r, dst[:n])\n\tif err == io.EOF && n > 0 {\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\treturn dst[:n2], err\n}\n\nfunc (r *readerWrapper) readByte() (byte, error) {\n\tn2, err := io.ReadFull(r.r, r.tmp[:1])\n\tif err != nil {\n\t\tif err == io.EOF {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t}\n\t\treturn 0, err\n\t}\n\tif n2 != 1 {\n\t\treturn 0, io.ErrUnexpectedEOF\n\t}\n\treturn r.tmp[0], nil\n}\n\nfunc (r *readerWrapper) skipN(n int64) error {\n\tn2, err := io.CopyN(io.Discard, r.r, n)\n\tif n2 != n {\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/bytereader.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\n// byteReader provides a byte reader that reads\n// little endian values from a byte stream.\n// The input stream is manually advanced.\n// The reader performs no bounds checks.\ntype byteReader struct {\n\tb   []byte\n\toff int\n}\n\n// advance the stream b n bytes.\nfunc (b *byteReader) advance(n uint) {\n\tb.off += int(n)\n}\n\n// overread returns whether we have advanced too far.\nfunc (b *byteReader) overread() bool {\n\treturn b.off > len(b.b)\n}\n\n// Int32 returns a little endian int32 starting at current offset.\nfunc (b byteReader) Int32() int32 {\n\tb2 := b.b[b.off:]\n\tb2 = b2[:4]\n\tv3 := int32(b2[3])\n\tv2 := int32(b2[2])\n\tv1 := int32(b2[1])\n\tv0 := int32(b2[0])\n\treturn v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)\n}\n\n// Uint8 returns the next byte\nfunc (b *byteReader) Uint8() uint8 {\n\tv := b.b[b.off]\n\treturn v\n}\n\n// Uint32 returns a little endian uint32 starting at current offset.\nfunc (b byteReader) Uint32() uint32 {\n\tif r := b.remain(); r < 4 {\n\t\t// Very rare\n\t\tv := uint32(0)\n\t\tfor i := 1; i <= r; i++ {\n\t\t\tv = (v << 8) | uint32(b.b[len(b.b)-i])\n\t\t}\n\t\treturn v\n\t}\n\tb2 := b.b[b.off:]\n\tb2 = b2[:4]\n\tv3 := uint32(b2[3])\n\tv2 := uint32(b2[2])\n\tv1 := uint32(b2[1])\n\tv0 := uint32(b2[0])\n\treturn v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)\n}\n\n// Uint32NC returns a little endian uint32 starting at current offset.\n// The caller must be sure if there are at least 4 bytes left.\nfunc (b byteReader) Uint32NC() uint32 {\n\tb2 := b.b[b.off:]\n\tb2 = b2[:4]\n\tv3 := uint32(b2[3])\n\tv2 := uint32(b2[2])\n\tv1 := uint32(b2[1])\n\tv0 := uint32(b2[0])\n\treturn v0 | (v1 << 8) | (v2 << 16) | (v3 << 24)\n}\n\n// unread returns the unread portion of the input.\nfunc (b byteReader) unread() []byte {\n\treturn b.b[b.off:]\n}\n\n// remain will return the number of bytes remaining.\nfunc (b byteReader) remain() int {\n\treturn len(b.b) - b.off\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/decodeheader.go",
    "content": "// Copyright 2020+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n\npackage zstd\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n)\n\n// HeaderMaxSize is the maximum size of a Frame and Block Header.\n// If less is sent to Header.Decode it *may* still contain enough information.\nconst HeaderMaxSize = 14 + 3\n\n// Header contains information about the first frame and block within that.\ntype Header struct {\n\t// SingleSegment specifies whether the data is to be decompressed into a\n\t// single contiguous memory segment.\n\t// It implies that WindowSize is invalid and that FrameContentSize is valid.\n\tSingleSegment bool\n\n\t// WindowSize is the window of data to keep while decoding.\n\t// Will only be set if SingleSegment is false.\n\tWindowSize uint64\n\n\t// Dictionary ID.\n\t// If 0, no dictionary.\n\tDictionaryID uint32\n\n\t// HasFCS specifies whether FrameContentSize has a valid value.\n\tHasFCS bool\n\n\t// FrameContentSize is the expected uncompressed size of the entire frame.\n\tFrameContentSize uint64\n\n\t// Skippable will be true if the frame is meant to be skipped.\n\t// This implies that FirstBlock.OK is false.\n\tSkippable bool\n\n\t// SkippableID is the user-specific ID for the skippable frame.\n\t// Valid values are between 0 to 15, inclusive.\n\tSkippableID int\n\n\t// SkippableSize is the length of the user data to skip following\n\t// the header.\n\tSkippableSize uint32\n\n\t// HeaderSize is the raw size of the frame header.\n\t//\n\t// For normal frames, it includes the size of the magic number and\n\t// the size of the header (per section 3.1.1.1).\n\t// It does not include the size for any data blocks (section 3.1.1.2) nor\n\t// the size for the trailing content checksum.\n\t//\n\t// For skippable frames, this counts the size of the magic number\n\t// along with the size of the size field of the payload.\n\t// It does not include the size of the skippable payload itself.\n\t// The total frame size is the HeaderSize plus the SkippableSize.\n\tHeaderSize int\n\n\t// First block information.\n\tFirstBlock struct {\n\t\t// OK will be set if first block could be decoded.\n\t\tOK bool\n\n\t\t// Is this the last block of a frame?\n\t\tLast bool\n\n\t\t// Is the data compressed?\n\t\t// If true CompressedSize will be populated.\n\t\t// Unfortunately DecompressedSize cannot be determined\n\t\t// without decoding the blocks.\n\t\tCompressed bool\n\n\t\t// DecompressedSize is the expected decompressed size of the block.\n\t\t// Will be 0 if it cannot be determined.\n\t\tDecompressedSize int\n\n\t\t// CompressedSize of the data in the block.\n\t\t// Does not include the block header.\n\t\t// Will be equal to DecompressedSize if not Compressed.\n\t\tCompressedSize int\n\t}\n\n\t// If set there is a checksum present for the block content.\n\t// The checksum field at the end is always 4 bytes long.\n\tHasCheckSum bool\n}\n\n// Decode the header from the beginning of the stream.\n// This will decode the frame header and the first block header if enough bytes are provided.\n// It is recommended to provide at least HeaderMaxSize bytes.\n// If the frame header cannot be read an error will be returned.\n// If there isn't enough input, io.ErrUnexpectedEOF is returned.\n// The FirstBlock.OK will indicate if enough information was available to decode the first block header.\nfunc (h *Header) Decode(in []byte) error {\n\t*h = Header{}\n\tif len(in) < 4 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\th.HeaderSize += 4\n\tb, in := in[:4], in[4:]\n\tif string(b) != frameMagic {\n\t\tif string(b[1:4]) != skippableFrameMagic || b[0]&0xf0 != 0x50 {\n\t\t\treturn ErrMagicMismatch\n\t\t}\n\t\tif len(in) < 4 {\n\t\t\treturn io.ErrUnexpectedEOF\n\t\t}\n\t\th.HeaderSize += 4\n\t\th.Skippable = true\n\t\th.SkippableID = int(b[0] & 0xf)\n\t\th.SkippableSize = binary.LittleEndian.Uint32(in)\n\t\treturn nil\n\t}\n\n\t// Read Window_Descriptor\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor\n\tif len(in) < 1 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\tfhd, in := in[0], in[1:]\n\th.HeaderSize++\n\th.SingleSegment = fhd&(1<<5) != 0\n\th.HasCheckSum = fhd&(1<<2) != 0\n\tif fhd&(1<<3) != 0 {\n\t\treturn errors.New(\"reserved bit set on frame header\")\n\t}\n\n\tif !h.SingleSegment {\n\t\tif len(in) < 1 {\n\t\t\treturn io.ErrUnexpectedEOF\n\t\t}\n\t\tvar wd byte\n\t\twd, in = in[0], in[1:]\n\t\th.HeaderSize++\n\t\twindowLog := 10 + (wd >> 3)\n\t\twindowBase := uint64(1) << windowLog\n\t\twindowAdd := (windowBase / 8) * uint64(wd&0x7)\n\t\th.WindowSize = windowBase + windowAdd\n\t}\n\n\t// Read Dictionary_ID\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary_id\n\tif size := fhd & 3; size != 0 {\n\t\tif size == 3 {\n\t\t\tsize = 4\n\t\t}\n\t\tif len(in) < int(size) {\n\t\t\treturn io.ErrUnexpectedEOF\n\t\t}\n\t\tb, in = in[:size], in[size:]\n\t\th.HeaderSize += int(size)\n\t\tswitch len(b) {\n\t\tcase 1:\n\t\t\th.DictionaryID = uint32(b[0])\n\t\tcase 2:\n\t\t\th.DictionaryID = uint32(b[0]) | (uint32(b[1]) << 8)\n\t\tcase 4:\n\t\t\th.DictionaryID = uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)\n\t\t}\n\t}\n\n\t// Read Frame_Content_Size\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#frame_content_size\n\tvar fcsSize int\n\tv := fhd >> 6\n\tswitch v {\n\tcase 0:\n\t\tif h.SingleSegment {\n\t\t\tfcsSize = 1\n\t\t}\n\tdefault:\n\t\tfcsSize = 1 << v\n\t}\n\n\tif fcsSize > 0 {\n\t\th.HasFCS = true\n\t\tif len(in) < fcsSize {\n\t\t\treturn io.ErrUnexpectedEOF\n\t\t}\n\t\tb, in = in[:fcsSize], in[fcsSize:]\n\t\th.HeaderSize += int(fcsSize)\n\t\tswitch len(b) {\n\t\tcase 1:\n\t\t\th.FrameContentSize = uint64(b[0])\n\t\tcase 2:\n\t\t\t// When FCS_Field_Size is 2, the offset of 256 is added.\n\t\t\th.FrameContentSize = uint64(b[0]) | (uint64(b[1]) << 8) + 256\n\t\tcase 4:\n\t\t\th.FrameContentSize = uint64(b[0]) | (uint64(b[1]) << 8) | (uint64(b[2]) << 16) | (uint64(b[3]) << 24)\n\t\tcase 8:\n\t\t\td1 := uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)\n\t\t\td2 := uint32(b[4]) | (uint32(b[5]) << 8) | (uint32(b[6]) << 16) | (uint32(b[7]) << 24)\n\t\t\th.FrameContentSize = uint64(d1) | (uint64(d2) << 32)\n\t\t}\n\t}\n\n\t// Frame Header done, we will not fail from now on.\n\tif len(in) < 3 {\n\t\treturn nil\n\t}\n\ttmp := in[:3]\n\tbh := uint32(tmp[0]) | (uint32(tmp[1]) << 8) | (uint32(tmp[2]) << 16)\n\th.FirstBlock.Last = bh&1 != 0\n\tblockType := blockType((bh >> 1) & 3)\n\t// find size.\n\tcSize := int(bh >> 3)\n\tswitch blockType {\n\tcase blockTypeReserved:\n\t\treturn nil\n\tcase blockTypeRLE:\n\t\th.FirstBlock.Compressed = true\n\t\th.FirstBlock.DecompressedSize = cSize\n\t\th.FirstBlock.CompressedSize = 1\n\tcase blockTypeCompressed:\n\t\th.FirstBlock.Compressed = true\n\t\th.FirstBlock.CompressedSize = cSize\n\tcase blockTypeRaw:\n\t\th.FirstBlock.DecompressedSize = cSize\n\t\th.FirstBlock.CompressedSize = cSize\n\tdefault:\n\t\tpanic(\"Invalid block type\")\n\t}\n\n\th.FirstBlock.OK = true\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/decoder.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"context\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"sync\"\n\n\t\"github.com/klauspost/compress/zstd/internal/xxhash\"\n)\n\n// Decoder provides decoding of zstandard streams.\n// The decoder has been designed to operate without allocations after a warmup.\n// This means that you should store the decoder for best performance.\n// To re-use a stream decoder, use the Reset(r io.Reader) error to switch to another stream.\n// A decoder can safely be re-used even if the previous stream failed.\n// To release the resources, you must call the Close() function on a decoder.\ntype Decoder struct {\n\to decoderOptions\n\n\t// Unreferenced decoders, ready for use.\n\tdecoders chan *blockDec\n\n\t// Current read position used for Reader functionality.\n\tcurrent decoderState\n\n\t// sync stream decoding\n\tsyncStream struct {\n\t\tdecodedFrame uint64\n\t\tbr           readerWrapper\n\t\tenabled      bool\n\t\tinFrame      bool\n\t\tdstBuf       []byte\n\t}\n\n\tframe *frameDec\n\n\t// Custom dictionaries.\n\tdicts map[uint32]*dict\n\n\t// streamWg is the waitgroup for all streams\n\tstreamWg sync.WaitGroup\n}\n\n// decoderState is used for maintaining state when the decoder\n// is used for streaming.\ntype decoderState struct {\n\t// current block being written to stream.\n\tdecodeOutput\n\n\t// output in order to be written to stream.\n\toutput chan decodeOutput\n\n\t// cancel remaining output.\n\tcancel context.CancelFunc\n\n\t// crc of current frame\n\tcrc *xxhash.Digest\n\n\tflushed bool\n}\n\nvar (\n\t// Check the interfaces we want to support.\n\t_ = io.WriterTo(&Decoder{})\n\t_ = io.Reader(&Decoder{})\n)\n\n// NewReader creates a new decoder.\n// A nil Reader can be provided in which case Reset can be used to start a decode.\n//\n// A Decoder can be used in two modes:\n//\n// 1) As a stream, or\n// 2) For stateless decoding using DecodeAll.\n//\n// Only a single stream can be decoded concurrently, but the same decoder\n// can run multiple concurrent stateless decodes. It is even possible to\n// use stateless decodes while a stream is being decoded.\n//\n// The Reset function can be used to initiate a new stream, which is will considerably\n// reduce the allocations normally caused by NewReader.\nfunc NewReader(r io.Reader, opts ...DOption) (*Decoder, error) {\n\tinitPredefined()\n\tvar d Decoder\n\td.o.setDefault()\n\tfor _, o := range opts {\n\t\terr := o(&d.o)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\td.current.crc = xxhash.New()\n\td.current.flushed = true\n\n\tif r == nil {\n\t\td.current.err = ErrDecoderNilInput\n\t}\n\n\t// Transfer option dicts.\n\td.dicts = make(map[uint32]*dict, len(d.o.dicts))\n\tfor _, dc := range d.o.dicts {\n\t\td.dicts[dc.id] = dc\n\t}\n\td.o.dicts = nil\n\n\t// Create decoders\n\td.decoders = make(chan *blockDec, d.o.concurrent)\n\tfor i := 0; i < d.o.concurrent; i++ {\n\t\tdec := newBlockDec(d.o.lowMem)\n\t\tdec.localFrame = newFrameDec(d.o)\n\t\td.decoders <- dec\n\t}\n\n\tif r == nil {\n\t\treturn &d, nil\n\t}\n\treturn &d, d.Reset(r)\n}\n\n// Read bytes from the decompressed stream into p.\n// Returns the number of bytes written and any error that occurred.\n// When the stream is done, io.EOF will be returned.\nfunc (d *Decoder) Read(p []byte) (int, error) {\n\tvar n int\n\tfor {\n\t\tif len(d.current.b) > 0 {\n\t\t\tfilled := copy(p, d.current.b)\n\t\t\tp = p[filled:]\n\t\t\td.current.b = d.current.b[filled:]\n\t\t\tn += filled\n\t\t}\n\t\tif len(p) == 0 {\n\t\t\tbreak\n\t\t}\n\t\tif len(d.current.b) == 0 {\n\t\t\t// We have an error and no more data\n\t\t\tif d.current.err != nil {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif !d.nextBlock(n == 0) {\n\t\t\t\treturn n, d.current.err\n\t\t\t}\n\t\t}\n\t}\n\tif len(d.current.b) > 0 {\n\t\tif debugDecoder {\n\t\t\tprintln(\"returning\", n, \"still bytes left:\", len(d.current.b))\n\t\t}\n\t\t// Only return error at end of block\n\t\treturn n, nil\n\t}\n\tif d.current.err != nil {\n\t\td.drainOutput()\n\t}\n\tif debugDecoder {\n\t\tprintln(\"returning\", n, d.current.err, len(d.decoders))\n\t}\n\treturn n, d.current.err\n}\n\n// Reset will reset the decoder the supplied stream after the current has finished processing.\n// Note that this functionality cannot be used after Close has been called.\n// Reset can be called with a nil reader to release references to the previous reader.\n// After being called with a nil reader, no other operations than Reset or DecodeAll or Close\n// should be used.\nfunc (d *Decoder) Reset(r io.Reader) error {\n\tif d.current.err == ErrDecoderClosed {\n\t\treturn d.current.err\n\t}\n\n\td.drainOutput()\n\n\td.syncStream.br.r = nil\n\tif r == nil {\n\t\td.current.err = ErrDecoderNilInput\n\t\tif len(d.current.b) > 0 {\n\t\t\td.current.b = d.current.b[:0]\n\t\t}\n\t\td.current.flushed = true\n\t\treturn nil\n\t}\n\n\t// If bytes buffer and < 5MB, do sync decoding anyway.\n\tif bb, ok := r.(byter); ok && bb.Len() < d.o.decodeBufsBelow && !d.o.limitToCap {\n\t\tbb2 := bb\n\t\tif debugDecoder {\n\t\t\tprintln(\"*bytes.Buffer detected, doing sync decode, len:\", bb.Len())\n\t\t}\n\t\tb := bb2.Bytes()\n\t\tvar dst []byte\n\t\tif cap(d.syncStream.dstBuf) > 0 {\n\t\t\tdst = d.syncStream.dstBuf[:0]\n\t\t}\n\n\t\tdst, err := d.DecodeAll(b, dst)\n\t\tif err == nil {\n\t\t\terr = io.EOF\n\t\t}\n\t\t// Save output buffer\n\t\td.syncStream.dstBuf = dst\n\t\td.current.b = dst\n\t\td.current.err = err\n\t\td.current.flushed = true\n\t\tif debugDecoder {\n\t\t\tprintln(\"sync decode to\", len(dst), \"bytes, err:\", err)\n\t\t}\n\t\treturn nil\n\t}\n\t// Remove current block.\n\td.stashDecoder()\n\td.current.decodeOutput = decodeOutput{}\n\td.current.err = nil\n\td.current.flushed = false\n\td.current.d = nil\n\td.syncStream.dstBuf = nil\n\n\t// Ensure no-one else is still running...\n\td.streamWg.Wait()\n\tif d.frame == nil {\n\t\td.frame = newFrameDec(d.o)\n\t}\n\n\tif d.o.concurrent == 1 {\n\t\treturn d.startSyncDecoder(r)\n\t}\n\n\td.current.output = make(chan decodeOutput, d.o.concurrent)\n\tctx, cancel := context.WithCancel(context.Background())\n\td.current.cancel = cancel\n\td.streamWg.Add(1)\n\tgo d.startStreamDecoder(ctx, r, d.current.output)\n\n\treturn nil\n}\n\n// drainOutput will drain the output until errEndOfStream is sent.\nfunc (d *Decoder) drainOutput() {\n\tif d.current.cancel != nil {\n\t\tif debugDecoder {\n\t\t\tprintln(\"cancelling current\")\n\t\t}\n\t\td.current.cancel()\n\t\td.current.cancel = nil\n\t}\n\tif d.current.d != nil {\n\t\tif debugDecoder {\n\t\t\tprintf(\"re-adding current decoder %p, decoders: %d\", d.current.d, len(d.decoders))\n\t\t}\n\t\td.decoders <- d.current.d\n\t\td.current.d = nil\n\t\td.current.b = nil\n\t}\n\tif d.current.output == nil || d.current.flushed {\n\t\tprintln(\"current already flushed\")\n\t\treturn\n\t}\n\tfor v := range d.current.output {\n\t\tif v.d != nil {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"re-adding decoder %p\", v.d)\n\t\t\t}\n\t\t\td.decoders <- v.d\n\t\t}\n\t}\n\td.current.output = nil\n\td.current.flushed = true\n}\n\n// WriteTo writes data to w until there's no more data to write or when an error occurs.\n// The return value n is the number of bytes written.\n// Any error encountered during the write is also returned.\nfunc (d *Decoder) WriteTo(w io.Writer) (int64, error) {\n\tvar n int64\n\tfor {\n\t\tif len(d.current.b) > 0 {\n\t\t\tn2, err2 := w.Write(d.current.b)\n\t\t\tn += int64(n2)\n\t\t\tif err2 != nil && (d.current.err == nil || d.current.err == io.EOF) {\n\t\t\t\td.current.err = err2\n\t\t\t} else if n2 != len(d.current.b) {\n\t\t\t\td.current.err = io.ErrShortWrite\n\t\t\t}\n\t\t}\n\t\tif d.current.err != nil {\n\t\t\tbreak\n\t\t}\n\t\td.nextBlock(true)\n\t}\n\terr := d.current.err\n\tif err != nil {\n\t\td.drainOutput()\n\t}\n\tif err == io.EOF {\n\t\terr = nil\n\t}\n\treturn n, err\n}\n\n// DecodeAll allows stateless decoding of a blob of bytes.\n// Output will be appended to dst, so if the destination size is known\n// you can pre-allocate the destination slice to avoid allocations.\n// DecodeAll can be used concurrently.\n// The Decoder concurrency limits will be respected.\nfunc (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) {\n\tif d.decoders == nil {\n\t\treturn dst, ErrDecoderClosed\n\t}\n\n\t// Grab a block decoder and frame decoder.\n\tblock := <-d.decoders\n\tframe := block.localFrame\n\tinitialSize := len(dst)\n\tdefer func() {\n\t\tif debugDecoder {\n\t\t\tprintf(\"re-adding decoder: %p\", block)\n\t\t}\n\t\tframe.rawInput = nil\n\t\tframe.bBuf = nil\n\t\tif frame.history.decoders.br != nil {\n\t\t\tframe.history.decoders.br.in = nil\n\t\t}\n\t\td.decoders <- block\n\t}()\n\tframe.bBuf = input\n\n\tfor {\n\t\tframe.history.reset()\n\t\terr := frame.reset(&frame.bBuf)\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"frame reset return EOF\")\n\t\t\t\t}\n\t\t\t\treturn dst, nil\n\t\t\t}\n\t\t\treturn dst, err\n\t\t}\n\t\tif err = d.setDict(frame); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif frame.WindowSize > d.o.maxWindowSize {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"window size exceeded:\", frame.WindowSize, \">\", d.o.maxWindowSize)\n\t\t\t}\n\t\t\treturn dst, ErrWindowSizeExceeded\n\t\t}\n\t\tif frame.FrameContentSize != fcsUnknown {\n\t\t\tif frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)-initialSize) {\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"decoder size exceeded; fcs:\", frame.FrameContentSize, \"> mcs:\", d.o.maxDecodedSize-uint64(len(dst)-initialSize), \"len:\", len(dst))\n\t\t\t\t}\n\t\t\t\treturn dst, ErrDecoderSizeExceeded\n\t\t\t}\n\t\t\tif d.o.limitToCap && frame.FrameContentSize > uint64(cap(dst)-len(dst)) {\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"decoder size exceeded; fcs:\", frame.FrameContentSize, \"> (cap-len)\", cap(dst)-len(dst))\n\t\t\t\t}\n\t\t\t\treturn dst, ErrDecoderSizeExceeded\n\t\t\t}\n\t\t\tif cap(dst)-len(dst) < int(frame.FrameContentSize) {\n\t\t\t\tdst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize)+compressedBlockOverAlloc)\n\t\t\t\tcopy(dst2, dst)\n\t\t\t\tdst = dst2\n\t\t\t}\n\t\t}\n\n\t\tif cap(dst) == 0 && !d.o.limitToCap {\n\t\t\t// Allocate len(input) * 2 by default if nothing is provided\n\t\t\t// and we didn't get frame content size.\n\t\t\tsize := len(input) * 2\n\t\t\t// Cap to 1 MB.\n\t\t\tif size > 1<<20 {\n\t\t\t\tsize = 1 << 20\n\t\t\t}\n\t\t\tif uint64(size) > d.o.maxDecodedSize {\n\t\t\t\tsize = int(d.o.maxDecodedSize)\n\t\t\t}\n\t\t\tdst = make([]byte, 0, size)\n\t\t}\n\n\t\tdst, err = frame.runDecoder(dst, block)\n\t\tif err != nil {\n\t\t\treturn dst, err\n\t\t}\n\t\tif uint64(len(dst)-initialSize) > d.o.maxDecodedSize {\n\t\t\treturn dst, ErrDecoderSizeExceeded\n\t\t}\n\t\tif len(frame.bBuf) == 0 {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"frame dbuf empty\")\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\treturn dst, nil\n}\n\n// nextBlock returns the next block.\n// If an error occurs d.err will be set.\n// Optionally the function can block for new output.\n// If non-blocking mode is used the returned boolean will be false\n// if no data was available without blocking.\nfunc (d *Decoder) nextBlock(blocking bool) (ok bool) {\n\tif d.current.err != nil {\n\t\t// Keep error state.\n\t\treturn false\n\t}\n\td.current.b = d.current.b[:0]\n\n\t// SYNC:\n\tif d.syncStream.enabled {\n\t\tif !blocking {\n\t\t\treturn false\n\t\t}\n\t\tok = d.nextBlockSync()\n\t\tif !ok {\n\t\t\td.stashDecoder()\n\t\t}\n\t\treturn ok\n\t}\n\n\t//ASYNC:\n\td.stashDecoder()\n\tif blocking {\n\t\td.current.decodeOutput, ok = <-d.current.output\n\t} else {\n\t\tselect {\n\t\tcase d.current.decodeOutput, ok = <-d.current.output:\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\tif !ok {\n\t\t// This should not happen, so signal error state...\n\t\td.current.err = io.ErrUnexpectedEOF\n\t\treturn false\n\t}\n\tnext := d.current.decodeOutput\n\tif next.d != nil && next.d.async.newHist != nil {\n\t\td.current.crc.Reset()\n\t}\n\tif debugDecoder {\n\t\tvar tmp [4]byte\n\t\tbinary.LittleEndian.PutUint32(tmp[:], uint32(xxhash.Sum64(next.b)))\n\t\tprintln(\"got\", len(d.current.b), \"bytes, error:\", d.current.err, \"data crc:\", tmp)\n\t}\n\n\tif d.o.ignoreChecksum {\n\t\treturn true\n\t}\n\n\tif len(next.b) > 0 {\n\t\td.current.crc.Write(next.b)\n\t}\n\tif next.err == nil && next.d != nil && next.d.hasCRC {\n\t\tgot := uint32(d.current.crc.Sum64())\n\t\tif got != next.d.checkCRC {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"CRC Check Failed: %08x (got) != %08x (on stream)\\n\", got, next.d.checkCRC)\n\t\t\t}\n\t\t\td.current.err = ErrCRCMismatch\n\t\t} else {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"CRC ok %08x\\n\", got)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (d *Decoder) nextBlockSync() (ok bool) {\n\tif d.current.d == nil {\n\t\td.current.d = <-d.decoders\n\t}\n\tfor len(d.current.b) == 0 {\n\t\tif !d.syncStream.inFrame {\n\t\t\td.frame.history.reset()\n\t\t\td.current.err = d.frame.reset(&d.syncStream.br)\n\t\t\tif d.current.err == nil {\n\t\t\t\td.current.err = d.setDict(d.frame)\n\t\t\t}\n\t\t\tif d.current.err != nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif d.frame.WindowSize > d.o.maxDecodedSize || d.frame.WindowSize > d.o.maxWindowSize {\n\t\t\t\td.current.err = ErrDecoderSizeExceeded\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\td.syncStream.decodedFrame = 0\n\t\t\td.syncStream.inFrame = true\n\t\t}\n\t\td.current.err = d.frame.next(d.current.d)\n\t\tif d.current.err != nil {\n\t\t\treturn false\n\t\t}\n\t\td.frame.history.ensureBlock()\n\t\tif debugDecoder {\n\t\t\tprintln(\"History trimmed:\", len(d.frame.history.b), \"decoded already:\", d.syncStream.decodedFrame)\n\t\t}\n\t\thistBefore := len(d.frame.history.b)\n\t\td.current.err = d.current.d.decodeBuf(&d.frame.history)\n\n\t\tif d.current.err != nil {\n\t\t\tprintln(\"error after:\", d.current.err)\n\t\t\treturn false\n\t\t}\n\t\td.current.b = d.frame.history.b[histBefore:]\n\t\tif debugDecoder {\n\t\t\tprintln(\"history after:\", len(d.frame.history.b))\n\t\t}\n\n\t\t// Check frame size (before CRC)\n\t\td.syncStream.decodedFrame += uint64(len(d.current.b))\n\t\tif d.syncStream.decodedFrame > d.frame.FrameContentSize {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"DecodedFrame (%d) > FrameContentSize (%d)\\n\", d.syncStream.decodedFrame, d.frame.FrameContentSize)\n\t\t\t}\n\t\t\td.current.err = ErrFrameSizeExceeded\n\t\t\treturn false\n\t\t}\n\n\t\t// Check FCS\n\t\tif d.current.d.Last && d.frame.FrameContentSize != fcsUnknown && d.syncStream.decodedFrame != d.frame.FrameContentSize {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"DecodedFrame (%d) != FrameContentSize (%d)\\n\", d.syncStream.decodedFrame, d.frame.FrameContentSize)\n\t\t\t}\n\t\t\td.current.err = ErrFrameSizeMismatch\n\t\t\treturn false\n\t\t}\n\n\t\t// Update/Check CRC\n\t\tif d.frame.HasCheckSum {\n\t\t\tif !d.o.ignoreChecksum {\n\t\t\t\td.frame.crc.Write(d.current.b)\n\t\t\t}\n\t\t\tif d.current.d.Last {\n\t\t\t\tif !d.o.ignoreChecksum {\n\t\t\t\t\td.current.err = d.frame.checkCRC()\n\t\t\t\t} else {\n\t\t\t\t\td.current.err = d.frame.consumeCRC()\n\t\t\t\t}\n\t\t\t\tif d.current.err != nil {\n\t\t\t\t\tprintln(\"CRC error:\", d.current.err)\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\td.syncStream.inFrame = !d.current.d.Last\n\t}\n\treturn true\n}\n\nfunc (d *Decoder) stashDecoder() {\n\tif d.current.d != nil {\n\t\tif debugDecoder {\n\t\t\tprintf(\"re-adding current decoder %p\", d.current.d)\n\t\t}\n\t\td.decoders <- d.current.d\n\t\td.current.d = nil\n\t}\n}\n\n// Close will release all resources.\n// It is NOT possible to reuse the decoder after this.\nfunc (d *Decoder) Close() {\n\tif d.current.err == ErrDecoderClosed {\n\t\treturn\n\t}\n\td.drainOutput()\n\tif d.current.cancel != nil {\n\t\td.current.cancel()\n\t\td.streamWg.Wait()\n\t\td.current.cancel = nil\n\t}\n\tif d.decoders != nil {\n\t\tclose(d.decoders)\n\t\tfor dec := range d.decoders {\n\t\t\tdec.Close()\n\t\t}\n\t\td.decoders = nil\n\t}\n\tif d.current.d != nil {\n\t\td.current.d.Close()\n\t\td.current.d = nil\n\t}\n\td.current.err = ErrDecoderClosed\n}\n\n// IOReadCloser returns the decoder as an io.ReadCloser for convenience.\n// Any changes to the decoder will be reflected, so the returned ReadCloser\n// can be reused along with the decoder.\n// io.WriterTo is also supported by the returned ReadCloser.\nfunc (d *Decoder) IOReadCloser() io.ReadCloser {\n\treturn closeWrapper{d: d}\n}\n\n// closeWrapper wraps a function call as a closer.\ntype closeWrapper struct {\n\td *Decoder\n}\n\n// WriteTo forwards WriteTo calls to the decoder.\nfunc (c closeWrapper) WriteTo(w io.Writer) (n int64, err error) {\n\treturn c.d.WriteTo(w)\n}\n\n// Read forwards read calls to the decoder.\nfunc (c closeWrapper) Read(p []byte) (n int, err error) {\n\treturn c.d.Read(p)\n}\n\n// Close closes the decoder.\nfunc (c closeWrapper) Close() error {\n\tc.d.Close()\n\treturn nil\n}\n\ntype decodeOutput struct {\n\td   *blockDec\n\tb   []byte\n\terr error\n}\n\nfunc (d *Decoder) startSyncDecoder(r io.Reader) error {\n\td.frame.history.reset()\n\td.syncStream.br = readerWrapper{r: r}\n\td.syncStream.inFrame = false\n\td.syncStream.enabled = true\n\td.syncStream.decodedFrame = 0\n\treturn nil\n}\n\n// Create Decoder:\n// ASYNC:\n// Spawn 3 go routines.\n// 0: Read frames and decode block literals.\n// 1: Decode sequences.\n// 2: Execute sequences, send to output.\nfunc (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output chan decodeOutput) {\n\tdefer d.streamWg.Done()\n\tbr := readerWrapper{r: r}\n\n\tvar seqDecode = make(chan *blockDec, d.o.concurrent)\n\tvar seqExecute = make(chan *blockDec, d.o.concurrent)\n\n\t// Async 1: Decode sequences...\n\tgo func() {\n\t\tvar hist history\n\t\tvar hasErr bool\n\n\t\tfor block := range seqDecode {\n\t\t\tif hasErr {\n\t\t\t\tif block != nil {\n\t\t\t\t\tseqExecute <- block\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif block.async.newHist != nil {\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"Async 1: new history, recent:\", block.async.newHist.recentOffsets)\n\t\t\t\t}\n\t\t\t\thist.reset()\n\t\t\t\thist.decoders = block.async.newHist.decoders\n\t\t\t\thist.recentOffsets = block.async.newHist.recentOffsets\n\t\t\t\thist.windowSize = block.async.newHist.windowSize\n\t\t\t\tif block.async.newHist.dict != nil {\n\t\t\t\t\thist.setDict(block.async.newHist.dict)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif block.err != nil || block.Type != blockTypeCompressed {\n\t\t\t\thasErr = block.err != nil\n\t\t\t\tseqExecute <- block\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\thist.decoders.literals = block.async.literals\n\t\t\tblock.err = block.prepareSequences(block.async.seqData, &hist)\n\t\t\tif debugDecoder && block.err != nil {\n\t\t\t\tprintln(\"prepareSequences returned:\", block.err)\n\t\t\t}\n\t\t\thasErr = block.err != nil\n\t\t\tif block.err == nil {\n\t\t\t\tblock.err = block.decodeSequences(&hist)\n\t\t\t\tif debugDecoder && block.err != nil {\n\t\t\t\t\tprintln(\"decodeSequences returned:\", block.err)\n\t\t\t\t}\n\t\t\t\thasErr = block.err != nil\n\t\t\t\t//\t\t\t\tblock.async.sequence = hist.decoders.seq[:hist.decoders.nSeqs]\n\t\t\t\tblock.async.seqSize = hist.decoders.seqSize\n\t\t\t}\n\t\t\tseqExecute <- block\n\t\t}\n\t\tclose(seqExecute)\n\t\thist.reset()\n\t}()\n\n\tvar wg sync.WaitGroup\n\twg.Add(1)\n\n\t// Async 3: Execute sequences...\n\tframeHistCache := d.frame.history.b\n\tgo func() {\n\t\tvar hist history\n\t\tvar decodedFrame uint64\n\t\tvar fcs uint64\n\t\tvar hasErr bool\n\t\tfor block := range seqExecute {\n\t\t\tout := decodeOutput{err: block.err, d: block}\n\t\t\tif block.err != nil || hasErr {\n\t\t\t\thasErr = true\n\t\t\t\toutput <- out\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif block.async.newHist != nil {\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"Async 2: new history\")\n\t\t\t\t}\n\t\t\t\thist.reset()\n\t\t\t\thist.windowSize = block.async.newHist.windowSize\n\t\t\t\thist.allocFrameBuffer = block.async.newHist.allocFrameBuffer\n\t\t\t\tif block.async.newHist.dict != nil {\n\t\t\t\t\thist.setDict(block.async.newHist.dict)\n\t\t\t\t}\n\n\t\t\t\tif cap(hist.b) < hist.allocFrameBuffer {\n\t\t\t\t\tif cap(frameHistCache) >= hist.allocFrameBuffer {\n\t\t\t\t\t\thist.b = frameHistCache\n\t\t\t\t\t} else {\n\t\t\t\t\t\thist.b = make([]byte, 0, hist.allocFrameBuffer)\n\t\t\t\t\t\tprintln(\"Alloc history sized\", hist.allocFrameBuffer)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\thist.b = hist.b[:0]\n\t\t\t\tfcs = block.async.fcs\n\t\t\t\tdecodedFrame = 0\n\t\t\t}\n\t\t\tdo := decodeOutput{err: block.err, d: block}\n\t\t\tswitch block.Type {\n\t\t\tcase blockTypeRLE:\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"add rle block length:\", block.RLESize)\n\t\t\t\t}\n\n\t\t\t\tif cap(block.dst) < int(block.RLESize) {\n\t\t\t\t\tif block.lowMem {\n\t\t\t\t\t\tblock.dst = make([]byte, block.RLESize)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tblock.dst = make([]byte, maxCompressedBlockSize)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tblock.dst = block.dst[:block.RLESize]\n\t\t\t\tv := block.data[0]\n\t\t\t\tfor i := range block.dst {\n\t\t\t\t\tblock.dst[i] = v\n\t\t\t\t}\n\t\t\t\thist.append(block.dst)\n\t\t\t\tdo.b = block.dst\n\t\t\tcase blockTypeRaw:\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"add raw block length:\", len(block.data))\n\t\t\t\t}\n\t\t\t\thist.append(block.data)\n\t\t\t\tdo.b = block.data\n\t\t\tcase blockTypeCompressed:\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"execute with history length:\", len(hist.b), \"window:\", hist.windowSize)\n\t\t\t\t}\n\t\t\t\thist.decoders.seqSize = block.async.seqSize\n\t\t\t\thist.decoders.literals = block.async.literals\n\t\t\t\tdo.err = block.executeSequences(&hist)\n\t\t\t\thasErr = do.err != nil\n\t\t\t\tif debugDecoder && hasErr {\n\t\t\t\t\tprintln(\"executeSequences returned:\", do.err)\n\t\t\t\t}\n\t\t\t\tdo.b = block.dst\n\t\t\t}\n\t\t\tif !hasErr {\n\t\t\t\tdecodedFrame += uint64(len(do.b))\n\t\t\t\tif decodedFrame > fcs {\n\t\t\t\t\tprintln(\"fcs exceeded\", block.Last, fcs, decodedFrame)\n\t\t\t\t\tdo.err = ErrFrameSizeExceeded\n\t\t\t\t\thasErr = true\n\t\t\t\t} else if block.Last && fcs != fcsUnknown && decodedFrame != fcs {\n\t\t\t\t\tdo.err = ErrFrameSizeMismatch\n\t\t\t\t\thasErr = true\n\t\t\t\t} else {\n\t\t\t\t\tif debugDecoder {\n\t\t\t\t\t\tprintln(\"fcs ok\", block.Last, fcs, decodedFrame)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\toutput <- do\n\t\t}\n\t\tclose(output)\n\t\tframeHistCache = hist.b\n\t\twg.Done()\n\t\tif debugDecoder {\n\t\t\tprintln(\"decoder goroutines finished\")\n\t\t}\n\t\thist.reset()\n\t}()\n\n\tvar hist history\ndecodeStream:\n\tfor {\n\t\tvar hasErr bool\n\t\thist.reset()\n\t\tdecodeBlock := func(block *blockDec) {\n\t\t\tif hasErr {\n\t\t\t\tif block != nil {\n\t\t\t\t\tseqDecode <- block\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif block.err != nil || block.Type != blockTypeCompressed {\n\t\t\t\thasErr = block.err != nil\n\t\t\t\tseqDecode <- block\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tremain, err := block.decodeLiterals(block.data, &hist)\n\t\t\tblock.err = err\n\t\t\thasErr = block.err != nil\n\t\t\tif err == nil {\n\t\t\t\tblock.async.literals = hist.decoders.literals\n\t\t\t\tblock.async.seqData = remain\n\t\t\t} else if debugDecoder {\n\t\t\t\tprintln(\"decodeLiterals error:\", err)\n\t\t\t}\n\t\t\tseqDecode <- block\n\t\t}\n\t\tframe := d.frame\n\t\tif debugDecoder {\n\t\t\tprintln(\"New frame...\")\n\t\t}\n\t\tvar historySent bool\n\t\tframe.history.reset()\n\t\terr := frame.reset(&br)\n\t\tif debugDecoder && err != nil {\n\t\t\tprintln(\"Frame decoder returned\", err)\n\t\t}\n\t\tif err == nil {\n\t\t\terr = d.setDict(frame)\n\t\t}\n\t\tif err == nil && d.frame.WindowSize > d.o.maxWindowSize {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"decoder size exceeded, fws:\", d.frame.WindowSize, \"> mws:\", d.o.maxWindowSize)\n\t\t\t}\n\n\t\t\terr = ErrDecoderSizeExceeded\n\t\t}\n\t\tif err != nil {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\tcase dec := <-d.decoders:\n\t\t\t\tdec.sendErr(err)\n\t\t\t\tdecodeBlock(dec)\n\t\t\t}\n\t\t\tbreak decodeStream\n\t\t}\n\n\t\t// Go through all blocks of the frame.\n\t\tfor {\n\t\t\tvar dec *blockDec\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\tbreak decodeStream\n\t\t\tcase dec = <-d.decoders:\n\t\t\t\t// Once we have a decoder, we MUST return it.\n\t\t\t}\n\t\t\terr := frame.next(dec)\n\t\t\tif !historySent {\n\t\t\t\th := frame.history\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintln(\"Alloc History:\", h.allocFrameBuffer)\n\t\t\t\t}\n\t\t\t\thist.reset()\n\t\t\t\tif h.dict != nil {\n\t\t\t\t\thist.setDict(h.dict)\n\t\t\t\t}\n\t\t\t\tdec.async.newHist = &h\n\t\t\t\tdec.async.fcs = frame.FrameContentSize\n\t\t\t\thistorySent = true\n\t\t\t} else {\n\t\t\t\tdec.async.newHist = nil\n\t\t\t}\n\t\t\tif debugDecoder && err != nil {\n\t\t\t\tprintln(\"next block returned error:\", err)\n\t\t\t}\n\t\t\tdec.err = err\n\t\t\tdec.hasCRC = false\n\t\t\tif dec.Last && frame.HasCheckSum && err == nil {\n\t\t\t\tcrc, err := frame.rawInput.readSmall(4)\n\t\t\t\tif len(crc) < 4 {\n\t\t\t\t\tif err == nil {\n\t\t\t\t\t\terr = io.ErrUnexpectedEOF\n\n\t\t\t\t\t}\n\t\t\t\t\tprintln(\"CRC missing?\", err)\n\t\t\t\t\tdec.err = err\n\t\t\t\t} else {\n\t\t\t\t\tdec.checkCRC = binary.LittleEndian.Uint32(crc)\n\t\t\t\t\tdec.hasCRC = true\n\t\t\t\t\tif debugDecoder {\n\t\t\t\t\t\tprintf(\"found crc to check: %08x\\n\", dec.checkCRC)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\terr = dec.err\n\t\t\tlast := dec.Last\n\t\t\tdecodeBlock(dec)\n\t\t\tif err != nil {\n\t\t\t\tbreak decodeStream\n\t\t\t}\n\t\t\tif last {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tclose(seqDecode)\n\twg.Wait()\n\thist.reset()\n\td.frame.history.b = frameHistCache\n}\n\nfunc (d *Decoder) setDict(frame *frameDec) (err error) {\n\tdict, ok := d.dicts[frame.DictionaryID]\n\tif ok {\n\t\tif debugDecoder {\n\t\t\tprintln(\"setting dict\", frame.DictionaryID)\n\t\t}\n\t\tframe.history.setDict(dict)\n\t} else if frame.DictionaryID != 0 {\n\t\t// A zero or missing dictionary id is ambiguous:\n\t\t// either dictionary zero, or no dictionary. In particular,\n\t\t// zstd --patch-from uses this id for the source file,\n\t\t// so only return an error if the dictionary id is not zero.\n\t\terr = ErrUnknownDictionary\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/decoder_options.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/bits\"\n\t\"runtime\"\n)\n\n// DOption is an option for creating a decoder.\ntype DOption func(*decoderOptions) error\n\n// options retains accumulated state of multiple options.\ntype decoderOptions struct {\n\tlowMem          bool\n\tconcurrent      int\n\tmaxDecodedSize  uint64\n\tmaxWindowSize   uint64\n\tdicts           []*dict\n\tignoreChecksum  bool\n\tlimitToCap      bool\n\tdecodeBufsBelow int\n}\n\nfunc (o *decoderOptions) setDefault() {\n\t*o = decoderOptions{\n\t\t// use less ram: true for now, but may change.\n\t\tlowMem:          true,\n\t\tconcurrent:      runtime.GOMAXPROCS(0),\n\t\tmaxWindowSize:   MaxWindowSize,\n\t\tdecodeBufsBelow: 128 << 10,\n\t}\n\tif o.concurrent > 4 {\n\t\to.concurrent = 4\n\t}\n\to.maxDecodedSize = 64 << 30\n}\n\n// WithDecoderLowmem will set whether to use a lower amount of memory,\n// but possibly have to allocate more while running.\nfunc WithDecoderLowmem(b bool) DOption {\n\treturn func(o *decoderOptions) error { o.lowMem = b; return nil }\n}\n\n// WithDecoderConcurrency sets the number of created decoders.\n// When decoding block with DecodeAll, this will limit the number\n// of possible concurrently running decodes.\n// When decoding streams, this will limit the number of\n// inflight blocks.\n// When decoding streams and setting maximum to 1,\n// no async decoding will be done.\n// When a value of 0 is provided GOMAXPROCS will be used.\n// By default this will be set to 4 or GOMAXPROCS, whatever is lower.\nfunc WithDecoderConcurrency(n int) DOption {\n\treturn func(o *decoderOptions) error {\n\t\tif n < 0 {\n\t\t\treturn errors.New(\"concurrency must be at least 1\")\n\t\t}\n\t\tif n == 0 {\n\t\t\to.concurrent = runtime.GOMAXPROCS(0)\n\t\t} else {\n\t\t\to.concurrent = n\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithDecoderMaxMemory allows to set a maximum decoded size for in-memory\n// non-streaming operations or maximum window size for streaming operations.\n// This can be used to control memory usage of potentially hostile content.\n// Maximum is 1 << 63 bytes. Default is 64GiB.\nfunc WithDecoderMaxMemory(n uint64) DOption {\n\treturn func(o *decoderOptions) error {\n\t\tif n == 0 {\n\t\t\treturn errors.New(\"WithDecoderMaxMemory must be at least 1\")\n\t\t}\n\t\tif n > 1<<63 {\n\t\t\treturn errors.New(\"WithDecoderMaxmemory must be less than 1 << 63\")\n\t\t}\n\t\to.maxDecodedSize = n\n\t\treturn nil\n\t}\n}\n\n// WithDecoderDicts allows to register one or more dictionaries for the decoder.\n//\n// Each slice in dict must be in the [dictionary format] produced by\n// \"zstd --train\" from the Zstandard reference implementation.\n//\n// If several dictionaries with the same ID are provided, the last one will be used.\n//\n// [dictionary format]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary-format\nfunc WithDecoderDicts(dicts ...[]byte) DOption {\n\treturn func(o *decoderOptions) error {\n\t\tfor _, b := range dicts {\n\t\t\td, err := loadDict(b)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\to.dicts = append(o.dicts, d)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithDecoderDictRaw registers a dictionary that may be used by the decoder.\n// The slice content can be arbitrary data.\nfunc WithDecoderDictRaw(id uint32, content []byte) DOption {\n\treturn func(o *decoderOptions) error {\n\t\tif bits.UintSize > 32 && uint(len(content)) > dictMaxLength {\n\t\t\treturn fmt.Errorf(\"dictionary of size %d > 2GiB too large\", len(content))\n\t\t}\n\t\to.dicts = append(o.dicts, &dict{id: id, content: content, offsets: [3]int{1, 4, 8}})\n\t\treturn nil\n\t}\n}\n\n// WithDecoderMaxWindow allows to set a maximum window size for decodes.\n// This allows rejecting packets that will cause big memory usage.\n// The Decoder will likely allocate more memory based on the WithDecoderLowmem setting.\n// If WithDecoderMaxMemory is set to a lower value, that will be used.\n// Default is 512MB, Maximum is ~3.75 TB as per zstandard spec.\nfunc WithDecoderMaxWindow(size uint64) DOption {\n\treturn func(o *decoderOptions) error {\n\t\tif size < MinWindowSize {\n\t\t\treturn errors.New(\"WithMaxWindowSize must be at least 1KB, 1024 bytes\")\n\t\t}\n\t\tif size > (1<<41)+7*(1<<38) {\n\t\t\treturn errors.New(\"WithMaxWindowSize must be less than (1<<41) + 7*(1<<38) ~ 3.75TB\")\n\t\t}\n\t\to.maxWindowSize = size\n\t\treturn nil\n\t}\n}\n\n// WithDecodeAllCapLimit will limit DecodeAll to decoding cap(dst)-len(dst) bytes,\n// or any size set in WithDecoderMaxMemory.\n// This can be used to limit decoding to a specific maximum output size.\n// Disabled by default.\nfunc WithDecodeAllCapLimit(b bool) DOption {\n\treturn func(o *decoderOptions) error {\n\t\to.limitToCap = b\n\t\treturn nil\n\t}\n}\n\n// WithDecodeBuffersBelow will fully decode readers that have a\n// `Bytes() []byte` and `Len() int` interface similar to bytes.Buffer.\n// This typically uses less allocations but will have the full decompressed object in memory.\n// Note that DecodeAllCapLimit will disable this, as well as giving a size of 0 or less.\n// Default is 128KiB.\nfunc WithDecodeBuffersBelow(size int) DOption {\n\treturn func(o *decoderOptions) error {\n\t\to.decodeBufsBelow = size\n\t\treturn nil\n\t}\n}\n\n// IgnoreChecksum allows to forcibly ignore checksum checking.\nfunc IgnoreChecksum(b bool) DOption {\n\treturn func(o *decoderOptions) error {\n\t\to.ignoreChecksum = b\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/dict.go",
    "content": "package zstd\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"sort\"\n\n\t\"github.com/klauspost/compress/huff0\"\n)\n\ntype dict struct {\n\tid uint32\n\n\tlitEnc              *huff0.Scratch\n\tllDec, ofDec, mlDec sequenceDec\n\toffsets             [3]int\n\tcontent             []byte\n}\n\nconst dictMagic = \"\\x37\\xa4\\x30\\xec\"\n\n// Maximum dictionary size for the reference implementation (1.5.3) is 2 GiB.\nconst dictMaxLength = 1 << 31\n\n// ID returns the dictionary id or 0 if d is nil.\nfunc (d *dict) ID() uint32 {\n\tif d == nil {\n\t\treturn 0\n\t}\n\treturn d.id\n}\n\n// ContentSize returns the dictionary content size or 0 if d is nil.\nfunc (d *dict) ContentSize() int {\n\tif d == nil {\n\t\treturn 0\n\t}\n\treturn len(d.content)\n}\n\n// Content returns the dictionary content.\nfunc (d *dict) Content() []byte {\n\tif d == nil {\n\t\treturn nil\n\t}\n\treturn d.content\n}\n\n// Offsets returns the initial offsets.\nfunc (d *dict) Offsets() [3]int {\n\tif d == nil {\n\t\treturn [3]int{}\n\t}\n\treturn d.offsets\n}\n\n// LitEncoder returns the literal encoder.\nfunc (d *dict) LitEncoder() *huff0.Scratch {\n\tif d == nil {\n\t\treturn nil\n\t}\n\treturn d.litEnc\n}\n\n// Load a dictionary as described in\n// https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format\nfunc loadDict(b []byte) (*dict, error) {\n\t// Check static field size.\n\tif len(b) <= 8+(3*4) {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\td := dict{\n\t\tllDec: sequenceDec{fse: &fseDecoder{}},\n\t\tofDec: sequenceDec{fse: &fseDecoder{}},\n\t\tmlDec: sequenceDec{fse: &fseDecoder{}},\n\t}\n\tif string(b[:4]) != dictMagic {\n\t\treturn nil, ErrMagicMismatch\n\t}\n\td.id = binary.LittleEndian.Uint32(b[4:8])\n\tif d.id == 0 {\n\t\treturn nil, errors.New(\"dictionaries cannot have ID 0\")\n\t}\n\n\t// Read literal table\n\tvar err error\n\td.litEnc, b, err = huff0.ReadTable(b[8:], nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"loading literal table: %w\", err)\n\t}\n\td.litEnc.Reuse = huff0.ReusePolicyMust\n\n\tbr := byteReader{\n\t\tb:   b,\n\t\toff: 0,\n\t}\n\treadDec := func(i tableIndex, dec *fseDecoder) error {\n\t\tif err := dec.readNCount(&br, uint16(maxTableSymbol[i])); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif br.overread() {\n\t\t\treturn io.ErrUnexpectedEOF\n\t\t}\n\t\terr = dec.transform(symbolTableX[i])\n\t\tif err != nil {\n\t\t\tprintln(\"Transform table error:\", err)\n\t\t\treturn err\n\t\t}\n\t\tif debugDecoder || debugEncoder {\n\t\t\tprintln(\"Read table ok\", \"symbolLen:\", dec.symbolLen)\n\t\t}\n\t\t// Set decoders as predefined so they aren't reused.\n\t\tdec.preDefined = true\n\t\treturn nil\n\t}\n\n\tif err := readDec(tableOffsets, d.ofDec.fse); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := readDec(tableMatchLengths, d.mlDec.fse); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := readDec(tableLiteralLengths, d.llDec.fse); err != nil {\n\t\treturn nil, err\n\t}\n\tif br.remain() < 12 {\n\t\treturn nil, io.ErrUnexpectedEOF\n\t}\n\n\td.offsets[0] = int(br.Uint32())\n\tbr.advance(4)\n\td.offsets[1] = int(br.Uint32())\n\tbr.advance(4)\n\td.offsets[2] = int(br.Uint32())\n\tbr.advance(4)\n\tif d.offsets[0] <= 0 || d.offsets[1] <= 0 || d.offsets[2] <= 0 {\n\t\treturn nil, errors.New(\"invalid offset in dictionary\")\n\t}\n\td.content = make([]byte, br.remain())\n\tcopy(d.content, br.unread())\n\tif d.offsets[0] > len(d.content) || d.offsets[1] > len(d.content) || d.offsets[2] > len(d.content) {\n\t\treturn nil, fmt.Errorf(\"initial offset bigger than dictionary content size %d, offsets: %v\", len(d.content), d.offsets)\n\t}\n\n\treturn &d, nil\n}\n\n// InspectDictionary loads a zstd dictionary and provides functions to inspect the content.\nfunc InspectDictionary(b []byte) (interface {\n\tID() uint32\n\tContentSize() int\n\tContent() []byte\n\tOffsets() [3]int\n\tLitEncoder() *huff0.Scratch\n}, error) {\n\tinitPredefined()\n\td, err := loadDict(b)\n\treturn d, err\n}\n\ntype BuildDictOptions struct {\n\t// Dictionary ID.\n\tID uint32\n\n\t// Content to use to create dictionary tables.\n\tContents [][]byte\n\n\t// History to use for all blocks.\n\tHistory []byte\n\n\t// Offsets to use.\n\tOffsets [3]int\n\n\t// CompatV155 will make the dictionary compatible with Zstd v1.5.5 and earlier.\n\t// See https://github.com/facebook/zstd/issues/3724\n\tCompatV155 bool\n\n\t// Use the specified encoder level.\n\t// The dictionary will be built using the specified encoder level,\n\t// which will reflect speed and make the dictionary tailored for that level.\n\t// If not set SpeedBestCompression will be used.\n\tLevel EncoderLevel\n\n\t// DebugOut will write stats and other details here if set.\n\tDebugOut io.Writer\n}\n\nfunc BuildDict(o BuildDictOptions) ([]byte, error) {\n\tinitPredefined()\n\thist := o.History\n\tcontents := o.Contents\n\tdebug := o.DebugOut != nil\n\tprintln := func(args ...interface{}) {\n\t\tif o.DebugOut != nil {\n\t\t\tfmt.Fprintln(o.DebugOut, args...)\n\t\t}\n\t}\n\tprintf := func(s string, args ...interface{}) {\n\t\tif o.DebugOut != nil {\n\t\t\tfmt.Fprintf(o.DebugOut, s, args...)\n\t\t}\n\t}\n\tprint := func(args ...interface{}) {\n\t\tif o.DebugOut != nil {\n\t\t\tfmt.Fprint(o.DebugOut, args...)\n\t\t}\n\t}\n\n\tif int64(len(hist)) > dictMaxLength {\n\t\treturn nil, fmt.Errorf(\"dictionary of size %d > %d\", len(hist), int64(dictMaxLength))\n\t}\n\tif len(hist) < 8 {\n\t\treturn nil, fmt.Errorf(\"dictionary of size %d < %d\", len(hist), 8)\n\t}\n\tif len(contents) == 0 {\n\t\treturn nil, errors.New(\"no content provided\")\n\t}\n\td := dict{\n\t\tid:      o.ID,\n\t\tlitEnc:  nil,\n\t\tllDec:   sequenceDec{},\n\t\tofDec:   sequenceDec{},\n\t\tmlDec:   sequenceDec{},\n\t\toffsets: o.Offsets,\n\t\tcontent: hist,\n\t}\n\tblock := blockEnc{lowMem: false}\n\tblock.init()\n\tenc := encoder(&bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(maxMatchLen), bufferReset: math.MaxInt32 - int32(maxMatchLen*2), lowMem: false}})\n\tif o.Level != 0 {\n\t\teOpts := encoderOptions{\n\t\t\tlevel:      o.Level,\n\t\t\tblockSize:  maxMatchLen,\n\t\t\twindowSize: maxMatchLen,\n\t\t\tdict:       &d,\n\t\t\tlowMem:     false,\n\t\t}\n\t\tenc = eOpts.encoder()\n\t} else {\n\t\to.Level = SpeedBestCompression\n\t}\n\tvar (\n\t\tremain [256]int\n\t\tll     [256]int\n\t\tml     [256]int\n\t\tof     [256]int\n\t)\n\taddValues := func(dst *[256]int, src []byte) {\n\t\tfor _, v := range src {\n\t\t\tdst[v]++\n\t\t}\n\t}\n\taddHist := func(dst *[256]int, src *[256]uint32) {\n\t\tfor i, v := range src {\n\t\t\tdst[i] += int(v)\n\t\t}\n\t}\n\tseqs := 0\n\tnUsed := 0\n\tlitTotal := 0\n\tnewOffsets := make(map[uint32]int, 1000)\n\tfor _, b := range contents {\n\t\tblock.reset(nil)\n\t\tif len(b) < 8 {\n\t\t\tcontinue\n\t\t}\n\t\tnUsed++\n\t\tenc.Reset(&d, true)\n\t\tenc.Encode(&block, b)\n\t\taddValues(&remain, block.literals)\n\t\tlitTotal += len(block.literals)\n\t\tseqs += len(block.sequences)\n\t\tblock.genCodes()\n\t\taddHist(&ll, block.coders.llEnc.Histogram())\n\t\taddHist(&ml, block.coders.mlEnc.Histogram())\n\t\taddHist(&of, block.coders.ofEnc.Histogram())\n\t\tfor i, seq := range block.sequences {\n\t\t\tif i > 3 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\toffset := seq.offset\n\t\t\tif offset == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif offset > 3 {\n\t\t\t\tnewOffsets[offset-3]++\n\t\t\t} else {\n\t\t\t\tnewOffsets[uint32(o.Offsets[offset-1])]++\n\t\t\t}\n\t\t}\n\t}\n\t// Find most used offsets.\n\tvar sortedOffsets []uint32\n\tfor k := range newOffsets {\n\t\tsortedOffsets = append(sortedOffsets, k)\n\t}\n\tsort.Slice(sortedOffsets, func(i, j int) bool {\n\t\ta, b := sortedOffsets[i], sortedOffsets[j]\n\t\tif a == b {\n\t\t\t// Prefer the longer offset\n\t\t\treturn sortedOffsets[i] > sortedOffsets[j]\n\t\t}\n\t\treturn newOffsets[sortedOffsets[i]] > newOffsets[sortedOffsets[j]]\n\t})\n\tif len(sortedOffsets) > 3 {\n\t\tif debug {\n\t\t\tprint(\"Offsets:\")\n\t\t\tfor i, v := range sortedOffsets {\n\t\t\t\tif i > 20 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tprintf(\"[%d: %d],\", v, newOffsets[v])\n\t\t\t}\n\t\t\tprintln(\"\")\n\t\t}\n\n\t\tsortedOffsets = sortedOffsets[:3]\n\t}\n\tfor i, v := range sortedOffsets {\n\t\to.Offsets[i] = int(v)\n\t}\n\tif debug {\n\t\tprintln(\"New repeat offsets\", o.Offsets)\n\t}\n\n\tif nUsed == 0 || seqs == 0 {\n\t\treturn nil, fmt.Errorf(\"%d blocks, %d sequences found\", nUsed, seqs)\n\t}\n\tif debug {\n\t\tprintln(\"Sequences:\", seqs, \"Blocks:\", nUsed, \"Literals:\", litTotal)\n\t}\n\tif seqs/nUsed < 512 {\n\t\t// Use 512 as minimum.\n\t\tnUsed = seqs / 512\n\t}\n\tcopyHist := func(dst *fseEncoder, src *[256]int) ([]byte, error) {\n\t\thist := dst.Histogram()\n\t\tvar maxSym uint8\n\t\tvar maxCount int\n\t\tvar fakeLength int\n\t\tfor i, v := range src {\n\t\t\tif v > 0 {\n\t\t\t\tv = v / nUsed\n\t\t\t\tif v == 0 {\n\t\t\t\t\tv = 1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif v > maxCount {\n\t\t\t\tmaxCount = v\n\t\t\t}\n\t\t\tif v != 0 {\n\t\t\t\tmaxSym = uint8(i)\n\t\t\t}\n\t\t\tfakeLength += v\n\t\t\thist[i] = uint32(v)\n\t\t}\n\t\tdst.HistogramFinished(maxSym, maxCount)\n\t\tdst.reUsed = false\n\t\tdst.useRLE = false\n\t\terr := dst.normalizeCount(fakeLength)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif debug {\n\t\t\tprintln(\"RAW:\", dst.count[:maxSym+1], \"NORM:\", dst.norm[:maxSym+1], \"LEN:\", fakeLength)\n\t\t}\n\t\treturn dst.writeCount(nil)\n\t}\n\tif debug {\n\t\tprint(\"Literal lengths: \")\n\t}\n\tllTable, err := copyHist(block.coders.llEnc, &ll)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif debug {\n\t\tprint(\"Match lengths: \")\n\t}\n\tmlTable, err := copyHist(block.coders.mlEnc, &ml)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif debug {\n\t\tprint(\"Offsets: \")\n\t}\n\tofTable, err := copyHist(block.coders.ofEnc, &of)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Literal table\n\tavgSize := litTotal\n\tif avgSize > huff0.BlockSizeMax/2 {\n\t\tavgSize = huff0.BlockSizeMax / 2\n\t}\n\thuffBuff := make([]byte, 0, avgSize)\n\t// Target size\n\tdiv := litTotal / avgSize\n\tif div < 1 {\n\t\tdiv = 1\n\t}\n\tif debug {\n\t\tprintln(\"Huffman weights:\")\n\t}\n\tfor i, n := range remain[:] {\n\t\tif n > 0 {\n\t\t\tn = n / div\n\t\t\t// Allow all entries to be represented.\n\t\t\tif n == 0 {\n\t\t\t\tn = 1\n\t\t\t}\n\t\t\thuffBuff = append(huffBuff, bytes.Repeat([]byte{byte(i)}, n)...)\n\t\t\tif debug {\n\t\t\t\tprintf(\"[%d: %d], \", i, n)\n\t\t\t}\n\t\t}\n\t}\n\tif o.CompatV155 && remain[255]/div == 0 {\n\t\thuffBuff = append(huffBuff, 255)\n\t}\n\tscratch := &huff0.Scratch{TableLog: 11}\n\tfor tries := 0; tries < 255; tries++ {\n\t\tscratch = &huff0.Scratch{TableLog: 11}\n\t\t_, _, err = huff0.Compress1X(huffBuff, scratch)\n\t\tif err == nil {\n\t\t\tbreak\n\t\t}\n\t\tif debug {\n\t\t\tprintf(\"Try %d: Huffman error: %v\\n\", tries+1, err)\n\t\t}\n\t\thuffBuff = huffBuff[:0]\n\t\tif tries == 250 {\n\t\t\tif debug {\n\t\t\t\tprintln(\"Huffman: Bailing out with predefined table\")\n\t\t\t}\n\n\t\t\t// Bail out.... Just generate something\n\t\t\thuffBuff = append(huffBuff, bytes.Repeat([]byte{255}, 10000)...)\n\t\t\tfor i := 0; i < 128; i++ {\n\t\t\t\thuffBuff = append(huffBuff, byte(i))\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif errors.Is(err, huff0.ErrIncompressible) {\n\t\t\t// Try truncating least common.\n\t\t\tfor i, n := range remain[:] {\n\t\t\t\tif n > 0 {\n\t\t\t\t\tn = n / (div * (i + 1))\n\t\t\t\t\tif n > 0 {\n\t\t\t\t\t\thuffBuff = append(huffBuff, bytes.Repeat([]byte{byte(i)}, n)...)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif o.CompatV155 && len(huffBuff) > 0 && huffBuff[len(huffBuff)-1] != 255 {\n\t\t\t\thuffBuff = append(huffBuff, 255)\n\t\t\t}\n\t\t\tif len(huffBuff) == 0 {\n\t\t\t\thuffBuff = append(huffBuff, 0, 255)\n\t\t\t}\n\t\t}\n\t\tif errors.Is(err, huff0.ErrUseRLE) {\n\t\t\tfor i, n := range remain[:] {\n\t\t\t\tn = n / (div * (i + 1))\n\t\t\t\t// Allow all entries to be represented.\n\t\t\t\tif n == 0 {\n\t\t\t\t\tn = 1\n\t\t\t\t}\n\t\t\t\thuffBuff = append(huffBuff, bytes.Repeat([]byte{byte(i)}, n)...)\n\t\t\t}\n\t\t}\n\t}\n\n\tvar out bytes.Buffer\n\tout.Write([]byte(dictMagic))\n\tout.Write(binary.LittleEndian.AppendUint32(nil, o.ID))\n\tout.Write(scratch.OutTable)\n\tif debug {\n\t\tprintln(\"huff table:\", len(scratch.OutTable), \"bytes\")\n\t\tprintln(\"of table:\", len(ofTable), \"bytes\")\n\t\tprintln(\"ml table:\", len(mlTable), \"bytes\")\n\t\tprintln(\"ll table:\", len(llTable), \"bytes\")\n\t}\n\tout.Write(ofTable)\n\tout.Write(mlTable)\n\tout.Write(llTable)\n\tout.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[0])))\n\tout.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[1])))\n\tout.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[2])))\n\tout.Write(hist)\n\tif debug {\n\t\t_, err := loadDict(out.Bytes())\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\ti, err := InspectDictionary(out.Bytes())\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tprintln(\"ID:\", i.ID())\n\t\tprintln(\"Content size:\", i.ContentSize())\n\t\tprintln(\"Encoder:\", i.LitEncoder() != nil)\n\t\tprintln(\"Offsets:\", i.Offsets())\n\t\tvar totalSize int\n\t\tfor _, b := range contents {\n\t\t\ttotalSize += len(b)\n\t\t}\n\n\t\tencWith := func(opts ...EOption) int {\n\t\t\tenc, err := NewWriter(nil, opts...)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tdefer enc.Close()\n\t\t\tvar dst []byte\n\t\t\tvar totalSize int\n\t\t\tfor _, b := range contents {\n\t\t\t\tdst = enc.EncodeAll(b, dst[:0])\n\t\t\t\ttotalSize += len(dst)\n\t\t\t}\n\t\t\treturn totalSize\n\t\t}\n\t\tplain := encWith(WithEncoderLevel(o.Level))\n\t\twithDict := encWith(WithEncoderLevel(o.Level), WithEncoderDict(out.Bytes()))\n\t\tprintln(\"Input size:\", totalSize)\n\t\tprintln(\"Plain Compressed:\", plain)\n\t\tprintln(\"Dict Compressed:\", withDict)\n\t\tprintln(\"Saved:\", plain-withDict, (plain-withDict)/len(contents), \"bytes per input (rounded down)\")\n\t}\n\treturn out.Bytes(), nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/enc_base.go",
    "content": "package zstd\n\nimport (\n\t\"fmt\"\n\t\"math/bits\"\n\n\t\"github.com/klauspost/compress/zstd/internal/xxhash\"\n)\n\nconst (\n\tdictShardBits = 6\n)\n\ntype fastBase struct {\n\t// cur is the offset at the start of hist\n\tcur int32\n\t// maximum offset. Should be at least 2x block size.\n\tmaxMatchOff int32\n\tbufferReset int32\n\thist        []byte\n\tcrc         *xxhash.Digest\n\ttmp         [8]byte\n\tblk         *blockEnc\n\tlastDictID  uint32\n\tlowMem      bool\n}\n\n// CRC returns the underlying CRC writer.\nfunc (e *fastBase) CRC() *xxhash.Digest {\n\treturn e.crc\n}\n\n// AppendCRC will append the CRC to the destination slice and return it.\nfunc (e *fastBase) AppendCRC(dst []byte) []byte {\n\tcrc := e.crc.Sum(e.tmp[:0])\n\tdst = append(dst, crc[7], crc[6], crc[5], crc[4])\n\treturn dst\n}\n\n// WindowSize returns the window size of the encoder,\n// or a window size small enough to contain the input size, if > 0.\nfunc (e *fastBase) WindowSize(size int64) int32 {\n\tif size > 0 && size < int64(e.maxMatchOff) {\n\t\tb := int32(1) << uint(bits.Len(uint(size)))\n\t\t// Keep minimum window.\n\t\tif b < 1024 {\n\t\t\tb = 1024\n\t\t}\n\t\treturn b\n\t}\n\treturn e.maxMatchOff\n}\n\n// Block returns the current block.\nfunc (e *fastBase) Block() *blockEnc {\n\treturn e.blk\n}\n\nfunc (e *fastBase) addBlock(src []byte) int32 {\n\tif debugAsserts && e.cur > e.bufferReset {\n\t\tpanic(fmt.Sprintf(\"ecur (%d) > buffer reset (%d)\", e.cur, e.bufferReset))\n\t}\n\t// check if we have space already\n\tif len(e.hist)+len(src) > cap(e.hist) {\n\t\tif cap(e.hist) == 0 {\n\t\t\te.ensureHist(len(src))\n\t\t} else {\n\t\t\tif cap(e.hist) < int(e.maxMatchOff+maxCompressedBlockSize) {\n\t\t\t\tpanic(fmt.Errorf(\"unexpected buffer cap %d, want at least %d with window %d\", cap(e.hist), e.maxMatchOff+maxCompressedBlockSize, e.maxMatchOff))\n\t\t\t}\n\t\t\t// Move down\n\t\t\toffset := int32(len(e.hist)) - e.maxMatchOff\n\t\t\tcopy(e.hist[0:e.maxMatchOff], e.hist[offset:])\n\t\t\te.cur += offset\n\t\t\te.hist = e.hist[:e.maxMatchOff]\n\t\t}\n\t}\n\ts := int32(len(e.hist))\n\te.hist = append(e.hist, src...)\n\treturn s\n}\n\n// ensureHist will ensure that history can keep at least this many bytes.\nfunc (e *fastBase) ensureHist(n int) {\n\tif cap(e.hist) >= n {\n\t\treturn\n\t}\n\tl := e.maxMatchOff\n\tif (e.lowMem && e.maxMatchOff > maxCompressedBlockSize) || e.maxMatchOff <= maxCompressedBlockSize {\n\t\tl += maxCompressedBlockSize\n\t} else {\n\t\tl += e.maxMatchOff\n\t}\n\t// Make it at least 1MB.\n\tif l < 1<<20 && !e.lowMem {\n\t\tl = 1 << 20\n\t}\n\t// Make it at least the requested size.\n\tif l < int32(n) {\n\t\tl = int32(n)\n\t}\n\te.hist = make([]byte, 0, l)\n}\n\n// useBlock will replace the block with the provided one,\n// but transfer recent offsets from the previous.\nfunc (e *fastBase) UseBlock(enc *blockEnc) {\n\tenc.reset(e.blk)\n\te.blk = enc\n}\n\nfunc (e *fastBase) matchlen(s, t int32, src []byte) int32 {\n\tif debugAsserts {\n\t\tif s < 0 {\n\t\t\terr := fmt.Sprintf(\"s (%d) < 0\", s)\n\t\t\tpanic(err)\n\t\t}\n\t\tif t < 0 {\n\t\t\terr := fmt.Sprintf(\"s (%d) < 0\", s)\n\t\t\tpanic(err)\n\t\t}\n\t\tif s-t > e.maxMatchOff {\n\t\t\terr := fmt.Sprintf(\"s (%d) - t (%d) > maxMatchOff (%d)\", s, t, e.maxMatchOff)\n\t\t\tpanic(err)\n\t\t}\n\t\tif len(src)-int(s) > maxCompressedBlockSize {\n\t\t\tpanic(fmt.Sprintf(\"len(src)-s (%d) > maxCompressedBlockSize (%d)\", len(src)-int(s), maxCompressedBlockSize))\n\t\t}\n\t}\n\treturn int32(matchLen(src[s:], src[t:]))\n}\n\n// Reset the encoding table.\nfunc (e *fastBase) resetBase(d *dict, singleBlock bool) {\n\tif e.blk == nil {\n\t\te.blk = &blockEnc{lowMem: e.lowMem}\n\t\te.blk.init()\n\t} else {\n\t\te.blk.reset(nil)\n\t}\n\te.blk.initNewEncode()\n\tif e.crc == nil {\n\t\te.crc = xxhash.New()\n\t} else {\n\t\te.crc.Reset()\n\t}\n\te.blk.dictLitEnc = nil\n\tif d != nil {\n\t\tlow := e.lowMem\n\t\tif singleBlock {\n\t\t\te.lowMem = true\n\t\t}\n\t\te.ensureHist(d.ContentSize() + maxCompressedBlockSize)\n\t\te.lowMem = low\n\t}\n\n\t// We offset current position so everything will be out of reach.\n\t// If above reset line, history will be purged.\n\tif e.cur < e.bufferReset {\n\t\te.cur += e.maxMatchOff + int32(len(e.hist))\n\t}\n\te.hist = e.hist[:0]\n\tif d != nil {\n\t\t// Set offsets (currently not used)\n\t\tfor i, off := range d.offsets {\n\t\t\te.blk.recentOffsets[i] = uint32(off)\n\t\t\te.blk.prevRecentOffsets[i] = e.blk.recentOffsets[i]\n\t\t}\n\t\t// Transfer litenc.\n\t\te.blk.dictLitEnc = d.litEnc\n\t\te.hist = append(e.hist, d.content...)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/enc_best.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\n\t\"github.com/klauspost/compress\"\n)\n\nconst (\n\tbestLongTableBits = 22                     // Bits used in the long match table\n\tbestLongTableSize = 1 << bestLongTableBits // Size of the table\n\tbestLongLen       = 8                      // Bytes used for table hash\n\n\t// Note: Increasing the short table bits or making the hash shorter\n\t// can actually lead to compression degradation since it will 'steal' more from the\n\t// long match table and match offsets are quite big.\n\t// This greatly depends on the type of input.\n\tbestShortTableBits = 18                      // Bits used in the short match table\n\tbestShortTableSize = 1 << bestShortTableBits // Size of the table\n\tbestShortLen       = 4                       // Bytes used for table hash\n\n)\n\ntype match struct {\n\toffset int32\n\ts      int32\n\tlength int32\n\trep    int32\n\test    int32\n}\n\nconst highScore = maxMatchLen * 8\n\n// estBits will estimate output bits from predefined tables.\nfunc (m *match) estBits(bitsPerByte int32) {\n\tmlc := mlCode(uint32(m.length - zstdMinMatch))\n\tvar ofc uint8\n\tif m.rep < 0 {\n\t\tofc = ofCode(uint32(m.s-m.offset) + 3)\n\t} else {\n\t\tofc = ofCode(uint32(m.rep) & 3)\n\t}\n\t// Cost, excluding\n\tofTT, mlTT := fsePredefEnc[tableOffsets].ct.symbolTT[ofc], fsePredefEnc[tableMatchLengths].ct.symbolTT[mlc]\n\n\t// Add cost of match encoding...\n\tm.est = int32(ofTT.outBits + mlTT.outBits)\n\tm.est += int32(ofTT.deltaNbBits>>16 + mlTT.deltaNbBits>>16)\n\t// Subtract savings compared to literal encoding...\n\tm.est -= (m.length * bitsPerByte) >> 10\n\tif m.est > 0 {\n\t\t// Unlikely gain..\n\t\tm.length = 0\n\t\tm.est = highScore\n\t}\n}\n\n// bestFastEncoder uses 2 tables, one for short matches (5 bytes) and one for long matches.\n// The long match table contains the previous entry with the same hash,\n// effectively making it a \"chain\" of length 2.\n// When we find a long match we choose between the two values and select the longest.\n// When we find a short match, after checking the long, we check if we can find a long at n+1\n// and that it is longer (lazy matching).\ntype bestFastEncoder struct {\n\tfastBase\n\ttable         [bestShortTableSize]prevEntry\n\tlongTable     [bestLongTableSize]prevEntry\n\tdictTable     []prevEntry\n\tdictLongTable []prevEntry\n}\n\n// Encode improves compression...\nfunc (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) {\n\tconst (\n\t\t// Input margin is the number of bytes we read (8)\n\t\t// and the maximum we will read ahead (2)\n\t\tinputMargin            = 8 + 4\n\t\tminNonLiteralBlockSize = 16\n\t)\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= e.bufferReset-int32(len(e.hist)) {\n\t\tif len(e.hist) == 0 {\n\t\t\te.table = [bestShortTableSize]prevEntry{}\n\t\t\te.longTable = [bestLongTableSize]prevEntry{}\n\t\t\te.cur = e.maxMatchOff\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - e.maxMatchOff\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tv2 := e.table[i].prev\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t\tv2 = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t\tif v2 < minOff {\n\t\t\t\t\tv2 = 0\n\t\t\t\t} else {\n\t\t\t\t\tv2 = v2 - e.cur + e.maxMatchOff\n\t\t\t\t}\n\t\t\t}\n\t\t\te.table[i] = prevEntry{\n\t\t\t\toffset: v,\n\t\t\t\tprev:   v2,\n\t\t\t}\n\t\t}\n\t\tfor i := range e.longTable[:] {\n\t\t\tv := e.longTable[i].offset\n\t\t\tv2 := e.longTable[i].prev\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t\tv2 = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t\tif v2 < minOff {\n\t\t\t\t\tv2 = 0\n\t\t\t\t} else {\n\t\t\t\t\tv2 = v2 - e.cur + e.maxMatchOff\n\t\t\t\t}\n\t\t\t}\n\t\t\te.longTable[i] = prevEntry{\n\t\t\t\toffset: v,\n\t\t\t\tprev:   v2,\n\t\t\t}\n\t\t}\n\t\te.cur = e.maxMatchOff\n\t\tbreak\n\t}\n\n\ts := e.addBlock(src)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Use this to estimate literal cost.\n\t// Scaled by 10 bits.\n\tbitsPerByte := int32((compress.ShannonEntropyBits(src) * 1024) / len(src))\n\t// Huffman can never go < 1 bit/byte\n\tif bitsPerByte < 1024 {\n\t\tbitsPerByte = 1024\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tsLimit := int32(len(src)) - inputMargin\n\tconst kSearchStrength = 10\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\toffset3 := int32(blk.recentOffsets[2])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\t// We allow the encoder to optionally turn off repeat offsets across blocks\n\t\tcanRepeat := len(blk.sequences) > 2\n\n\t\tif debugAsserts && canRepeat && offset1 == 0 {\n\t\t\tpanic(\"offset0 was 0\")\n\t\t}\n\n\t\tconst goodEnough = 250\n\n\t\tcv := load6432(src, s)\n\n\t\tnextHashL := hashLen(cv, bestLongTableBits, bestLongLen)\n\t\tnextHashS := hashLen(cv, bestShortTableBits, bestShortLen)\n\t\tcandidateL := e.longTable[nextHashL]\n\t\tcandidateS := e.table[nextHashS]\n\n\t\t// Set m to a match at offset if it looks like that will improve compression.\n\t\timprove := func(m *match, offset int32, s int32, first uint32, rep int32) {\n\t\t\tdelta := s - offset\n\t\t\tif delta >= e.maxMatchOff || delta <= 0 || load3232(src, offset) != first {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif debugAsserts {\n\t\t\t\tif offset >= s {\n\t\t\t\t\tpanic(fmt.Sprintf(\"offset: %d - s:%d - rep: %d - cur :%d - max: %d\", offset, s, rep, e.cur, e.maxMatchOff))\n\t\t\t\t}\n\t\t\t\tif !bytes.Equal(src[s:s+4], src[offset:offset+4]) {\n\t\t\t\t\tpanic(fmt.Sprintf(\"first match mismatch: %v != %v, first: %08x\", src[s:s+4], src[offset:offset+4], first))\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Try to quick reject if we already have a long match.\n\t\t\tif m.length > 16 {\n\t\t\t\tleft := len(src) - int(m.s+m.length)\n\t\t\t\t// If we are too close to the end, keep as is.\n\t\t\t\tif left <= 0 {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tcheckLen := m.length - (s - m.s) - 8\n\t\t\t\tif left > 2 && checkLen > 4 {\n\t\t\t\t\t// Check 4 bytes, 4 bytes from the end of the current match.\n\t\t\t\t\ta := load3232(src, offset+checkLen)\n\t\t\t\t\tb := load3232(src, s+checkLen)\n\t\t\t\t\tif a != b {\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tl := 4 + e.matchlen(s+4, offset+4, src)\n\t\t\tif true {\n\t\t\t\t// Extend candidate match backwards as far as possible.\n\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\tif tMin < 0 {\n\t\t\t\t\ttMin = 0\n\t\t\t\t}\n\t\t\t\tfor offset > tMin && s > nextEmit && src[offset-1] == src[s-1] && l < maxMatchLength {\n\t\t\t\t\ts--\n\t\t\t\t\toffset--\n\t\t\t\t\tl++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcand := match{offset: offset, s: s, length: l, rep: rep}\n\t\t\tcand.estBits(bitsPerByte)\n\t\t\tif m.est >= highScore || cand.est-m.est+(cand.s-m.s)*bitsPerByte>>10 < 0 {\n\t\t\t\t*m = cand\n\t\t\t}\n\t\t}\n\n\t\tbest := match{s: s, est: highScore}\n\t\timprove(&best, candidateL.offset-e.cur, s, uint32(cv), -1)\n\t\timprove(&best, candidateL.prev-e.cur, s, uint32(cv), -1)\n\t\timprove(&best, candidateS.offset-e.cur, s, uint32(cv), -1)\n\t\timprove(&best, candidateS.prev-e.cur, s, uint32(cv), -1)\n\n\t\tif canRepeat && best.length < goodEnough {\n\t\t\tif s == nextEmit {\n\t\t\t\t// Check repeats straight after a match.\n\t\t\t\timprove(&best, s-offset2, s, uint32(cv), 1|4)\n\t\t\t\timprove(&best, s-offset3, s, uint32(cv), 2|4)\n\t\t\t\tif offset1 > 1 {\n\t\t\t\t\timprove(&best, s-(offset1-1), s, uint32(cv), 3|4)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If either no match or a non-repeat match, check at + 1\n\t\t\tif best.rep <= 0 {\n\t\t\t\tcv32 := uint32(cv >> 8)\n\t\t\t\tspp := s + 1\n\t\t\t\timprove(&best, spp-offset1, spp, cv32, 1)\n\t\t\t\timprove(&best, spp-offset2, spp, cv32, 2)\n\t\t\t\timprove(&best, spp-offset3, spp, cv32, 3)\n\t\t\t\tif best.rep < 0 {\n\t\t\t\t\tcv32 = uint32(cv >> 24)\n\t\t\t\t\tspp += 2\n\t\t\t\t\timprove(&best, spp-offset1, spp, cv32, 1)\n\t\t\t\t\timprove(&best, spp-offset2, spp, cv32, 2)\n\t\t\t\t\timprove(&best, spp-offset3, spp, cv32, 3)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Load next and check...\n\t\te.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: candidateL.offset}\n\t\te.table[nextHashS] = prevEntry{offset: s + e.cur, prev: candidateS.offset}\n\t\tindex0 := s + 1\n\n\t\t// Look far ahead, unless we have a really long match already...\n\t\tif best.length < goodEnough {\n\t\t\t// No match found, move forward on input, no need to check forward...\n\t\t\tif best.length < 4 {\n\t\t\t\ts += 1 + (s-nextEmit)>>(kSearchStrength-1)\n\t\t\t\tif s >= sLimit {\n\t\t\t\t\tbreak encodeLoop\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tcandidateS = e.table[hashLen(cv>>8, bestShortTableBits, bestShortLen)]\n\t\t\tcv = load6432(src, s+1)\n\t\t\tcv2 := load6432(src, s+2)\n\t\t\tcandidateL = e.longTable[hashLen(cv, bestLongTableBits, bestLongLen)]\n\t\t\tcandidateL2 := e.longTable[hashLen(cv2, bestLongTableBits, bestLongLen)]\n\n\t\t\t// Short at s+1\n\t\t\timprove(&best, candidateS.offset-e.cur, s+1, uint32(cv), -1)\n\t\t\t// Long at s+1, s+2\n\t\t\timprove(&best, candidateL.offset-e.cur, s+1, uint32(cv), -1)\n\t\t\timprove(&best, candidateL.prev-e.cur, s+1, uint32(cv), -1)\n\t\t\timprove(&best, candidateL2.offset-e.cur, s+2, uint32(cv2), -1)\n\t\t\timprove(&best, candidateL2.prev-e.cur, s+2, uint32(cv2), -1)\n\t\t\tif false {\n\t\t\t\t// Short at s+3.\n\t\t\t\t// Too often worse...\n\t\t\t\timprove(&best, e.table[hashLen(cv2>>8, bestShortTableBits, bestShortLen)].offset-e.cur, s+3, uint32(cv2>>8), -1)\n\t\t\t}\n\n\t\t\t// Start check at a fixed offset to allow for a few mismatches.\n\t\t\t// For this compression level 2 yields the best results.\n\t\t\t// We cannot do this if we have already indexed this position.\n\t\t\tconst skipBeginning = 2\n\t\t\tif best.s > s-skipBeginning {\n\t\t\t\t// See if we can find a better match by checking where the current best ends.\n\t\t\t\t// Use that offset to see if we can find a better full match.\n\t\t\t\tif sAt := best.s + best.length; sAt < sLimit {\n\t\t\t\t\tnextHashL := hashLen(load6432(src, sAt), bestLongTableBits, bestLongLen)\n\t\t\t\t\tcandidateEnd := e.longTable[nextHashL]\n\n\t\t\t\t\tif off := candidateEnd.offset - e.cur - best.length + skipBeginning; off >= 0 {\n\t\t\t\t\t\timprove(&best, off, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1)\n\t\t\t\t\t\tif off := candidateEnd.prev - e.cur - best.length + skipBeginning; off >= 0 {\n\t\t\t\t\t\t\timprove(&best, off, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1)\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\n\t\tif debugAsserts {\n\t\t\tif !bytes.Equal(src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]) {\n\t\t\t\tpanic(fmt.Sprintf(\"match mismatch: %v != %v\", src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]))\n\t\t\t}\n\t\t}\n\n\t\t// We have a match, we can store the forward value\n\t\tif best.rep > 0 {\n\t\t\tvar seq seq\n\t\t\tseq.matchLen = uint32(best.length - zstdMinMatch)\n\t\t\tif debugAsserts && s < nextEmit {\n\t\t\t\tpanic(\"s < nextEmit\")\n\t\t\t}\n\t\t\taddLiterals(&seq, best.s)\n\n\t\t\t// Repeat. If bit 4 is set, this is a non-lit repeat.\n\t\t\tseq.offset = uint32(best.rep & 3)\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Index old s + 1 -> s - 1\n\t\t\ts = best.s + best.length\n\t\t\tnextEmit = s\n\n\t\t\t// Index skipped...\n\t\t\tend := s\n\t\t\tif s > sLimit+4 {\n\t\t\t\tend = sLimit + 4\n\t\t\t}\n\t\t\toff := index0 + e.cur\n\t\t\tfor index0 < end {\n\t\t\t\tcv0 := load6432(src, index0)\n\t\t\t\th0 := hashLen(cv0, bestLongTableBits, bestLongLen)\n\t\t\t\th1 := hashLen(cv0, bestShortTableBits, bestShortLen)\n\t\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\t\te.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset}\n\t\t\t\toff++\n\t\t\t\tindex0++\n\t\t\t}\n\n\t\t\tswitch best.rep {\n\t\t\tcase 2, 4 | 1:\n\t\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tcase 3, 4 | 2:\n\t\t\t\toffset1, offset2, offset3 = offset3, offset1, offset2\n\t\t\tcase 4 | 3:\n\t\t\t\toffset1, offset2, offset3 = offset1-1, offset1, offset2\n\t\t\t}\n\t\t\tif s >= sLimit {\n\t\t\t\tif debugEncoder {\n\t\t\t\t\tprintln(\"repeat ended\", s, best.length)\n\t\t\t\t}\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// A 4-byte match has been found. Update recent offsets.\n\t\t// We'll later see if more than 4 bytes.\n\t\ts = best.s\n\t\tt := best.offset\n\t\toffset1, offset2, offset3 = s-t, offset1, offset2\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && int(offset1) > len(src) {\n\t\t\tpanic(\"invalid offset\")\n\t\t}\n\n\t\t// Write our sequence\n\t\tvar seq seq\n\t\tl := best.length\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\n\t\t// Index old s + 1 -> s - 1 or sLimit\n\t\tend := s\n\t\tif s > sLimit-4 {\n\t\t\tend = sLimit - 4\n\t\t}\n\n\t\toff := index0 + e.cur\n\t\tfor index0 < end {\n\t\t\tcv0 := load6432(src, index0)\n\t\t\th0 := hashLen(cv0, bestLongTableBits, bestLongLen)\n\t\t\th1 := hashLen(cv0, bestShortTableBits, bestShortLen)\n\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\te.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset}\n\t\t\tindex0++\n\t\t\toff++\n\t\t}\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tblk.recentOffsets[0] = uint32(offset1)\n\tblk.recentOffsets[1] = uint32(offset2)\n\tblk.recentOffsets[2] = uint32(offset3)\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n}\n\n// EncodeNoHist will encode a block with no history and no following blocks.\n// Most notable difference is that src will not be copied for history and\n// we do not need to check for max match length.\nfunc (e *bestFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) {\n\te.ensureHist(len(src))\n\te.Encode(blk, src)\n}\n\n// Reset will reset and set a dictionary if not nil\nfunc (e *bestFastEncoder) Reset(d *dict, singleBlock bool) {\n\te.resetBase(d, singleBlock)\n\tif d == nil {\n\t\treturn\n\t}\n\t// Init or copy dict table\n\tif len(e.dictTable) != len(e.table) || d.id != e.lastDictID {\n\t\tif len(e.dictTable) != len(e.table) {\n\t\t\te.dictTable = make([]prevEntry, len(e.table))\n\t\t}\n\t\tend := int32(len(d.content)) - 8 + e.maxMatchOff\n\t\tfor i := e.maxMatchOff; i < end; i += 4 {\n\t\t\tconst hashLog = bestShortTableBits\n\n\t\t\tcv := load6432(d.content, i-e.maxMatchOff)\n\t\t\tnextHash := hashLen(cv, hashLog, bestShortLen)      // 0 -> 4\n\t\t\tnextHash1 := hashLen(cv>>8, hashLog, bestShortLen)  // 1 -> 5\n\t\t\tnextHash2 := hashLen(cv>>16, hashLog, bestShortLen) // 2 -> 6\n\t\t\tnextHash3 := hashLen(cv>>24, hashLog, bestShortLen) // 3 -> 7\n\t\t\te.dictTable[nextHash] = prevEntry{\n\t\t\t\tprev:   e.dictTable[nextHash].offset,\n\t\t\t\toffset: i,\n\t\t\t}\n\t\t\te.dictTable[nextHash1] = prevEntry{\n\t\t\t\tprev:   e.dictTable[nextHash1].offset,\n\t\t\t\toffset: i + 1,\n\t\t\t}\n\t\t\te.dictTable[nextHash2] = prevEntry{\n\t\t\t\tprev:   e.dictTable[nextHash2].offset,\n\t\t\t\toffset: i + 2,\n\t\t\t}\n\t\t\te.dictTable[nextHash3] = prevEntry{\n\t\t\t\tprev:   e.dictTable[nextHash3].offset,\n\t\t\t\toffset: i + 3,\n\t\t\t}\n\t\t}\n\t\te.lastDictID = d.id\n\t}\n\n\t// Init or copy dict table\n\tif len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {\n\t\tif len(e.dictLongTable) != len(e.longTable) {\n\t\t\te.dictLongTable = make([]prevEntry, len(e.longTable))\n\t\t}\n\t\tif len(d.content) >= 8 {\n\t\t\tcv := load6432(d.content, 0)\n\t\t\th := hashLen(cv, bestLongTableBits, bestLongLen)\n\t\t\te.dictLongTable[h] = prevEntry{\n\t\t\t\toffset: e.maxMatchOff,\n\t\t\t\tprev:   e.dictLongTable[h].offset,\n\t\t\t}\n\n\t\t\tend := int32(len(d.content)) - 8 + e.maxMatchOff\n\t\t\toff := 8 // First to read\n\t\t\tfor i := e.maxMatchOff + 1; i < end; i++ {\n\t\t\t\tcv = cv>>8 | (uint64(d.content[off]) << 56)\n\t\t\t\th := hashLen(cv, bestLongTableBits, bestLongLen)\n\t\t\t\te.dictLongTable[h] = prevEntry{\n\t\t\t\t\toffset: i,\n\t\t\t\t\tprev:   e.dictLongTable[h].offset,\n\t\t\t\t}\n\t\t\t\toff++\n\t\t\t}\n\t\t}\n\t\te.lastDictID = d.id\n\t}\n\t// Reset table to initial state\n\tcopy(e.longTable[:], e.dictLongTable)\n\n\te.cur = e.maxMatchOff\n\t// Reset table to initial state\n\tcopy(e.table[:], e.dictTable)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/enc_better.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport \"fmt\"\n\nconst (\n\tbetterLongTableBits = 19                       // Bits used in the long match table\n\tbetterLongTableSize = 1 << betterLongTableBits // Size of the table\n\tbetterLongLen       = 8                        // Bytes used for table hash\n\n\t// Note: Increasing the short table bits or making the hash shorter\n\t// can actually lead to compression degradation since it will 'steal' more from the\n\t// long match table and match offsets are quite big.\n\t// This greatly depends on the type of input.\n\tbetterShortTableBits = 13                        // Bits used in the short match table\n\tbetterShortTableSize = 1 << betterShortTableBits // Size of the table\n\tbetterShortLen       = 5                         // Bytes used for table hash\n\n\tbetterLongTableShardCnt  = 1 << (betterLongTableBits - dictShardBits)    // Number of shards in the table\n\tbetterLongTableShardSize = betterLongTableSize / betterLongTableShardCnt // Size of an individual shard\n\n\tbetterShortTableShardCnt  = 1 << (betterShortTableBits - dictShardBits)     // Number of shards in the table\n\tbetterShortTableShardSize = betterShortTableSize / betterShortTableShardCnt // Size of an individual shard\n)\n\ntype prevEntry struct {\n\toffset int32\n\tprev   int32\n}\n\n// betterFastEncoder uses 2 tables, one for short matches (5 bytes) and one for long matches.\n// The long match table contains the previous entry with the same hash,\n// effectively making it a \"chain\" of length 2.\n// When we find a long match we choose between the two values and select the longest.\n// When we find a short match, after checking the long, we check if we can find a long at n+1\n// and that it is longer (lazy matching).\ntype betterFastEncoder struct {\n\tfastBase\n\ttable     [betterShortTableSize]tableEntry\n\tlongTable [betterLongTableSize]prevEntry\n}\n\ntype betterFastEncoderDict struct {\n\tbetterFastEncoder\n\tdictTable            []tableEntry\n\tdictLongTable        []prevEntry\n\tshortTableShardDirty [betterShortTableShardCnt]bool\n\tlongTableShardDirty  [betterLongTableShardCnt]bool\n\tallDirty             bool\n}\n\n// Encode improves compression...\nfunc (e *betterFastEncoder) Encode(blk *blockEnc, src []byte) {\n\tconst (\n\t\t// Input margin is the number of bytes we read (8)\n\t\t// and the maximum we will read ahead (2)\n\t\tinputMargin            = 8 + 2\n\t\tminNonLiteralBlockSize = 16\n\t)\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= e.bufferReset-int32(len(e.hist)) {\n\t\tif len(e.hist) == 0 {\n\t\t\te.table = [betterShortTableSize]tableEntry{}\n\t\t\te.longTable = [betterLongTableSize]prevEntry{}\n\t\t\te.cur = e.maxMatchOff\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - e.maxMatchOff\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.longTable[:] {\n\t\t\tv := e.longTable[i].offset\n\t\t\tv2 := e.longTable[i].prev\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t\tv2 = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t\tif v2 < minOff {\n\t\t\t\t\tv2 = 0\n\t\t\t\t} else {\n\t\t\t\t\tv2 = v2 - e.cur + e.maxMatchOff\n\t\t\t\t}\n\t\t\t}\n\t\t\te.longTable[i] = prevEntry{\n\t\t\t\toffset: v,\n\t\t\t\tprev:   v2,\n\t\t\t}\n\t\t}\n\t\te.cur = e.maxMatchOff\n\t\tbreak\n\t}\n\n\ts := e.addBlock(src)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 1.\n\tconst stepSize = 1\n\n\tconst kSearchStrength = 9\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\tvar t int32\n\t\t// We allow the encoder to optionally turn off repeat offsets across blocks\n\t\tcanRepeat := len(blk.sequences) > 2\n\t\tvar matched, index0 int32\n\n\t\tfor {\n\t\t\tif debugAsserts && canRepeat && offset1 == 0 {\n\t\t\t\tpanic(\"offset0 was 0\")\n\t\t\t}\n\n\t\t\tnextHashL := hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\tnextHashS := hashLen(cv, betterShortTableBits, betterShortLen)\n\t\t\tcandidateL := e.longTable[nextHashL]\n\t\t\tcandidateS := e.table[nextHashS]\n\n\t\t\tconst repOff = 1\n\t\t\trepIndex := s - offset1 + repOff\n\t\t\toff := s + e.cur\n\t\t\te.longTable[nextHashL] = prevEntry{offset: off, prev: candidateL.offset}\n\t\t\te.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}\n\t\t\tindex0 = s + 1\n\n\t\t\tif canRepeat {\n\t\t\t\tif repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {\n\t\t\t\t\t// Consider history as well.\n\t\t\t\t\tvar seq seq\n\t\t\t\t\tlenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)\n\n\t\t\t\t\tseq.matchLen = uint32(lenght - zstdMinMatch)\n\n\t\t\t\t\t// We might be able to match backwards.\n\t\t\t\t\t// Extend as long as we can.\n\t\t\t\t\tstart := s + repOff\n\t\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t\t// and have to do special offset treatment.\n\t\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\t\tif tMin < 0 {\n\t\t\t\t\t\ttMin = 0\n\t\t\t\t\t}\n\t\t\t\t\tfor repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {\n\t\t\t\t\t\trepIndex--\n\t\t\t\t\t\tstart--\n\t\t\t\t\t\tseq.matchLen++\n\t\t\t\t\t}\n\t\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t\t// rep 0\n\t\t\t\t\tseq.offset = 1\n\t\t\t\t\tif debugSequences {\n\t\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t\t}\n\t\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t\t\t// Index match start+1 (long) -> s - 1\n\t\t\t\t\tindex0 := s + repOff\n\t\t\t\t\ts += lenght + repOff\n\n\t\t\t\t\tnextEmit = s\n\t\t\t\t\tif s >= sLimit {\n\t\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\t\tprintln(\"repeat ended\", s, lenght)\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak encodeLoop\n\t\t\t\t\t}\n\t\t\t\t\t// Index skipped...\n\t\t\t\t\tfor index0 < s-1 {\n\t\t\t\t\t\tcv0 := load6432(src, index0)\n\t\t\t\t\t\tcv1 := cv0 >> 8\n\t\t\t\t\t\th0 := hashLen(cv0, betterLongTableBits, betterLongLen)\n\t\t\t\t\t\toff := index0 + e.cur\n\t\t\t\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\t\t\t\te.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)}\n\t\t\t\t\t\tindex0 += 2\n\t\t\t\t\t}\n\t\t\t\t\tcv = load6432(src, s)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst repOff2 = 1\n\n\t\t\t\t// We deviate from the reference encoder and also check offset 2.\n\t\t\t\t// Still slower and not much better, so disabled.\n\t\t\t\t// repIndex = s - offset2 + repOff2\n\t\t\t\tif false && repIndex >= 0 && load6432(src, repIndex) == load6432(src, s+repOff) {\n\t\t\t\t\t// Consider history as well.\n\t\t\t\t\tvar seq seq\n\t\t\t\t\tlenght := 8 + e.matchlen(s+8+repOff2, repIndex+8, src)\n\n\t\t\t\t\tseq.matchLen = uint32(lenght - zstdMinMatch)\n\n\t\t\t\t\t// We might be able to match backwards.\n\t\t\t\t\t// Extend as long as we can.\n\t\t\t\t\tstart := s + repOff2\n\t\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t\t// and have to do special offset treatment.\n\t\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\t\tif tMin < 0 {\n\t\t\t\t\t\ttMin = 0\n\t\t\t\t\t}\n\t\t\t\t\tfor repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {\n\t\t\t\t\t\trepIndex--\n\t\t\t\t\t\tstart--\n\t\t\t\t\t\tseq.matchLen++\n\t\t\t\t\t}\n\t\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t\t// rep 2\n\t\t\t\t\tseq.offset = 2\n\t\t\t\t\tif debugSequences {\n\t\t\t\t\t\tprintln(\"repeat sequence 2\", seq, \"next s:\", s)\n\t\t\t\t\t}\n\t\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t\t\ts += lenght + repOff2\n\t\t\t\t\tnextEmit = s\n\t\t\t\t\tif s >= sLimit {\n\t\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\t\tprintln(\"repeat ended\", s, lenght)\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak encodeLoop\n\t\t\t\t\t}\n\n\t\t\t\t\t// Index skipped...\n\t\t\t\t\tfor index0 < s-1 {\n\t\t\t\t\t\tcv0 := load6432(src, index0)\n\t\t\t\t\t\tcv1 := cv0 >> 8\n\t\t\t\t\t\th0 := hashLen(cv0, betterLongTableBits, betterLongLen)\n\t\t\t\t\t\toff := index0 + e.cur\n\t\t\t\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\t\t\t\te.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)}\n\t\t\t\t\t\tindex0 += 2\n\t\t\t\t\t}\n\t\t\t\t\tcv = load6432(src, s)\n\t\t\t\t\t// Swap offsets\n\t\t\t\t\toffset1, offset2 = offset2, offset1\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Find the offsets of our two matches.\n\t\t\tcoffsetL := candidateL.offset - e.cur\n\t\t\tcoffsetLP := candidateL.prev - e.cur\n\n\t\t\t// Check if we have a long match.\n\t\t\tif s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {\n\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\tmatched = e.matchlen(s+8, coffsetL+8, src) + 8\n\t\t\t\tt = coffsetL\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t}\n\n\t\t\t\tif s-coffsetLP < e.maxMatchOff && cv == load6432(src, coffsetLP) {\n\t\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\t\tprevMatch := e.matchlen(s+8, coffsetLP+8, src) + 8\n\t\t\t\t\tif prevMatch > matched {\n\t\t\t\t\t\tmatched = prevMatch\n\t\t\t\t\t\tt = coffsetLP\n\t\t\t\t\t}\n\t\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t\t}\n\t\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t\t}\n\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Check if we have a long match on prev.\n\t\t\tif s-coffsetLP < e.maxMatchOff && cv == load6432(src, coffsetLP) {\n\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\tmatched = e.matchlen(s+8, coffsetLP+8, src) + 8\n\t\t\t\tt = coffsetLP\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcoffsetS := candidateS.offset - e.cur\n\n\t\t\t// Check if we have a short match.\n\t\t\tif s-coffsetS < e.maxMatchOff && uint32(cv) == candidateS.val {\n\t\t\t\t// found a regular match\n\t\t\t\tmatched = e.matchlen(s+4, coffsetS+4, src) + 4\n\n\t\t\t\t// See if we can find a long match at s+1\n\t\t\t\tconst checkAt = 1\n\t\t\t\tcv := load6432(src, s+checkAt)\n\t\t\t\tnextHashL = hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\t\tcandidateL = e.longTable[nextHashL]\n\t\t\t\tcoffsetL = candidateL.offset - e.cur\n\n\t\t\t\t// We can store it, since we have at least a 4 byte match.\n\t\t\t\te.longTable[nextHashL] = prevEntry{offset: s + checkAt + e.cur, prev: candidateL.offset}\n\t\t\t\tif s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {\n\t\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\t\tmatchedNext := e.matchlen(s+8+checkAt, coffsetL+8, src) + 8\n\t\t\t\t\tif matchedNext > matched {\n\t\t\t\t\t\tt = coffsetL\n\t\t\t\t\t\ts += checkAt\n\t\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\t\tprintln(\"long match (after short)\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check prev long...\n\t\t\t\tcoffsetL = candidateL.prev - e.cur\n\t\t\t\tif s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {\n\t\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\t\tmatchedNext := e.matchlen(s+8+checkAt, coffsetL+8, src) + 8\n\t\t\t\t\tif matchedNext > matched {\n\t\t\t\t\t\tt = coffsetL\n\t\t\t\t\t\ts += checkAt\n\t\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\t\tprintln(\"prev long match (after short)\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tt = coffsetS\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"short match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// No match found, move forward in input.\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\n\t\t// Try to find a better match by searching for a long match at the end of the current best match\n\t\tif s+matched < sLimit {\n\t\t\t// Allow some bytes at the beginning to mismatch.\n\t\t\t// Sweet spot is around 3 bytes, but depends on input.\n\t\t\t// The skipped bytes are tested in Extend backwards,\n\t\t\t// and still picked up as part of the match if they do.\n\t\t\tconst skipBeginning = 3\n\n\t\t\tnextHashL := hashLen(load6432(src, s+matched), betterLongTableBits, betterLongLen)\n\t\t\ts2 := s + skipBeginning\n\t\t\tcv := load3232(src, s2)\n\t\t\tcandidateL := e.longTable[nextHashL]\n\t\t\tcoffsetL := candidateL.offset - e.cur - matched + skipBeginning\n\t\t\tif coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) {\n\t\t\t\t// Found a long match, at least 4 bytes.\n\t\t\t\tmatchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4\n\t\t\t\tif matchedNext > matched {\n\t\t\t\t\tt = coffsetL\n\t\t\t\t\ts = s2\n\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\tprintln(\"long match at end-of-match\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check prev long...\n\t\t\tif true {\n\t\t\t\tcoffsetL = candidateL.prev - e.cur - matched + skipBeginning\n\t\t\t\tif coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) {\n\t\t\t\t\t// Found a long match, at least 4 bytes.\n\t\t\t\t\tmatchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4\n\t\t\t\t\tif matchedNext > matched {\n\t\t\t\t\t\tt = coffsetL\n\t\t\t\t\t\ts = s2\n\t\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\t\tprintln(\"prev long match at end-of-match\")\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\t// A match has been found. Update recent offsets.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && canRepeat && int(offset1) > len(src) {\n\t\t\tpanic(\"invalid offset\")\n\t\t}\n\n\t\t// Extend the n-byte match as long as possible.\n\t\tl := matched\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\n\t\t// Index match start+1 (long) -> s - 1\n\t\toff := index0 + e.cur\n\t\tfor index0 < s-1 {\n\t\t\tcv0 := load6432(src, index0)\n\t\t\tcv1 := cv0 >> 8\n\t\t\th0 := hashLen(cv0, betterLongTableBits, betterLongLen)\n\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\te.table[hashLen(cv1, betterShortTableBits, betterShortLen)] = tableEntry{offset: off + 1, val: uint32(cv1)}\n\t\t\tindex0 += 2\n\t\t\toff += 2\n\t\t}\n\n\t\tcv = load6432(src, s)\n\t\tif !canRepeat {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check offset 2\n\t\tfor {\n\t\t\to2 := s - offset2\n\t\t\tif load3232(src, o2) != uint32(cv) {\n\t\t\t\t// Do regular search\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHashL := hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\tnextHashS := hashLen(cv, betterShortTableBits, betterShortLen)\n\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\tl := 4 + e.matchlen(s+4, o2+4, src)\n\n\t\t\te.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: e.longTable[nextHashL].offset}\n\t\t\te.table[nextHashS] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\t// Finished\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tblk.recentOffsets[0] = uint32(offset1)\n\tblk.recentOffsets[1] = uint32(offset2)\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n}\n\n// EncodeNoHist will encode a block with no history and no following blocks.\n// Most notable difference is that src will not be copied for history and\n// we do not need to check for max match length.\nfunc (e *betterFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) {\n\te.ensureHist(len(src))\n\te.Encode(blk, src)\n}\n\n// Encode improves compression...\nfunc (e *betterFastEncoderDict) Encode(blk *blockEnc, src []byte) {\n\tconst (\n\t\t// Input margin is the number of bytes we read (8)\n\t\t// and the maximum we will read ahead (2)\n\t\tinputMargin            = 8 + 2\n\t\tminNonLiteralBlockSize = 16\n\t)\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= e.bufferReset-int32(len(e.hist)) {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.longTable[:] {\n\t\t\t\te.longTable[i] = prevEntry{}\n\t\t\t}\n\t\t\te.cur = e.maxMatchOff\n\t\t\te.allDirty = true\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - e.maxMatchOff\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.longTable[:] {\n\t\t\tv := e.longTable[i].offset\n\t\t\tv2 := e.longTable[i].prev\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t\tv2 = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t\tif v2 < minOff {\n\t\t\t\t\tv2 = 0\n\t\t\t\t} else {\n\t\t\t\t\tv2 = v2 - e.cur + e.maxMatchOff\n\t\t\t\t}\n\t\t\t}\n\t\t\te.longTable[i] = prevEntry{\n\t\t\t\toffset: v,\n\t\t\t\tprev:   v2,\n\t\t\t}\n\t\t}\n\t\te.allDirty = true\n\t\te.cur = e.maxMatchOff\n\t\tbreak\n\t}\n\n\ts := e.addBlock(src)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 1.\n\tconst stepSize = 1\n\n\tconst kSearchStrength = 9\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\tvar t int32\n\t\t// We allow the encoder to optionally turn off repeat offsets across blocks\n\t\tcanRepeat := len(blk.sequences) > 2\n\t\tvar matched, index0 int32\n\n\t\tfor {\n\t\t\tif debugAsserts && canRepeat && offset1 == 0 {\n\t\t\t\tpanic(\"offset0 was 0\")\n\t\t\t}\n\n\t\t\tnextHashL := hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\tnextHashS := hashLen(cv, betterShortTableBits, betterShortLen)\n\t\t\tcandidateL := e.longTable[nextHashL]\n\t\t\tcandidateS := e.table[nextHashS]\n\n\t\t\tconst repOff = 1\n\t\t\trepIndex := s - offset1 + repOff\n\t\t\toff := s + e.cur\n\t\t\te.longTable[nextHashL] = prevEntry{offset: off, prev: candidateL.offset}\n\t\t\te.markLongShardDirty(nextHashL)\n\t\t\te.table[nextHashS] = tableEntry{offset: off, val: uint32(cv)}\n\t\t\te.markShortShardDirty(nextHashS)\n\t\t\tindex0 = s + 1\n\n\t\t\tif canRepeat {\n\t\t\t\tif repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {\n\t\t\t\t\t// Consider history as well.\n\t\t\t\t\tvar seq seq\n\t\t\t\t\tlenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)\n\n\t\t\t\t\tseq.matchLen = uint32(lenght - zstdMinMatch)\n\n\t\t\t\t\t// We might be able to match backwards.\n\t\t\t\t\t// Extend as long as we can.\n\t\t\t\t\tstart := s + repOff\n\t\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t\t// and have to do special offset treatment.\n\t\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\t\tif tMin < 0 {\n\t\t\t\t\t\ttMin = 0\n\t\t\t\t\t}\n\t\t\t\t\tfor repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {\n\t\t\t\t\t\trepIndex--\n\t\t\t\t\t\tstart--\n\t\t\t\t\t\tseq.matchLen++\n\t\t\t\t\t}\n\t\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t\t// rep 0\n\t\t\t\t\tseq.offset = 1\n\t\t\t\t\tif debugSequences {\n\t\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t\t}\n\t\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t\t\t// Index match start+1 (long) -> s - 1\n\t\t\t\t\ts += lenght + repOff\n\n\t\t\t\t\tnextEmit = s\n\t\t\t\t\tif s >= sLimit {\n\t\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\t\tprintln(\"repeat ended\", s, lenght)\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak encodeLoop\n\t\t\t\t\t}\n\t\t\t\t\t// Index skipped...\n\t\t\t\t\tfor index0 < s-1 {\n\t\t\t\t\t\tcv0 := load6432(src, index0)\n\t\t\t\t\t\tcv1 := cv0 >> 8\n\t\t\t\t\t\th0 := hashLen(cv0, betterLongTableBits, betterLongLen)\n\t\t\t\t\t\toff := index0 + e.cur\n\t\t\t\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\t\t\t\te.markLongShardDirty(h0)\n\t\t\t\t\t\th1 := hashLen(cv1, betterShortTableBits, betterShortLen)\n\t\t\t\t\t\te.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)}\n\t\t\t\t\t\te.markShortShardDirty(h1)\n\t\t\t\t\t\tindex0 += 2\n\t\t\t\t\t}\n\t\t\t\t\tcv = load6432(src, s)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst repOff2 = 1\n\n\t\t\t\t// We deviate from the reference encoder and also check offset 2.\n\t\t\t\t// Still slower and not much better, so disabled.\n\t\t\t\t// repIndex = s - offset2 + repOff2\n\t\t\t\tif false && repIndex >= 0 && load6432(src, repIndex) == load6432(src, s+repOff) {\n\t\t\t\t\t// Consider history as well.\n\t\t\t\t\tvar seq seq\n\t\t\t\t\tlenght := 8 + e.matchlen(s+8+repOff2, repIndex+8, src)\n\n\t\t\t\t\tseq.matchLen = uint32(lenght - zstdMinMatch)\n\n\t\t\t\t\t// We might be able to match backwards.\n\t\t\t\t\t// Extend as long as we can.\n\t\t\t\t\tstart := s + repOff2\n\t\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t\t// and have to do special offset treatment.\n\t\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\t\tif tMin < 0 {\n\t\t\t\t\t\ttMin = 0\n\t\t\t\t\t}\n\t\t\t\t\tfor repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {\n\t\t\t\t\t\trepIndex--\n\t\t\t\t\t\tstart--\n\t\t\t\t\t\tseq.matchLen++\n\t\t\t\t\t}\n\t\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t\t// rep 2\n\t\t\t\t\tseq.offset = 2\n\t\t\t\t\tif debugSequences {\n\t\t\t\t\t\tprintln(\"repeat sequence 2\", seq, \"next s:\", s)\n\t\t\t\t\t}\n\t\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t\t\ts += lenght + repOff2\n\t\t\t\t\tnextEmit = s\n\t\t\t\t\tif s >= sLimit {\n\t\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\t\tprintln(\"repeat ended\", s, lenght)\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak encodeLoop\n\t\t\t\t\t}\n\n\t\t\t\t\t// Index skipped...\n\t\t\t\t\tfor index0 < s-1 {\n\t\t\t\t\t\tcv0 := load6432(src, index0)\n\t\t\t\t\t\tcv1 := cv0 >> 8\n\t\t\t\t\t\th0 := hashLen(cv0, betterLongTableBits, betterLongLen)\n\t\t\t\t\t\toff := index0 + e.cur\n\t\t\t\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\t\t\t\te.markLongShardDirty(h0)\n\t\t\t\t\t\th1 := hashLen(cv1, betterShortTableBits, betterShortLen)\n\t\t\t\t\t\te.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)}\n\t\t\t\t\t\te.markShortShardDirty(h1)\n\t\t\t\t\t\tindex0 += 2\n\t\t\t\t\t}\n\t\t\t\t\tcv = load6432(src, s)\n\t\t\t\t\t// Swap offsets\n\t\t\t\t\toffset1, offset2 = offset2, offset1\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Find the offsets of our two matches.\n\t\t\tcoffsetL := candidateL.offset - e.cur\n\t\t\tcoffsetLP := candidateL.prev - e.cur\n\n\t\t\t// Check if we have a long match.\n\t\t\tif s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {\n\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\tmatched = e.matchlen(s+8, coffsetL+8, src) + 8\n\t\t\t\tt = coffsetL\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t}\n\n\t\t\t\tif s-coffsetLP < e.maxMatchOff && cv == load6432(src, coffsetLP) {\n\t\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\t\tprevMatch := e.matchlen(s+8, coffsetLP+8, src) + 8\n\t\t\t\t\tif prevMatch > matched {\n\t\t\t\t\t\tmatched = prevMatch\n\t\t\t\t\t\tt = coffsetLP\n\t\t\t\t\t}\n\t\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t\t}\n\t\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t\t}\n\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Check if we have a long match on prev.\n\t\t\tif s-coffsetLP < e.maxMatchOff && cv == load6432(src, coffsetLP) {\n\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\tmatched = e.matchlen(s+8, coffsetLP+8, src) + 8\n\t\t\t\tt = coffsetLP\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tcoffsetS := candidateS.offset - e.cur\n\n\t\t\t// Check if we have a short match.\n\t\t\tif s-coffsetS < e.maxMatchOff && uint32(cv) == candidateS.val {\n\t\t\t\t// found a regular match\n\t\t\t\tmatched = e.matchlen(s+4, coffsetS+4, src) + 4\n\n\t\t\t\t// See if we can find a long match at s+1\n\t\t\t\tconst checkAt = 1\n\t\t\t\tcv := load6432(src, s+checkAt)\n\t\t\t\tnextHashL = hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\t\tcandidateL = e.longTable[nextHashL]\n\t\t\t\tcoffsetL = candidateL.offset - e.cur\n\n\t\t\t\t// We can store it, since we have at least a 4 byte match.\n\t\t\t\te.longTable[nextHashL] = prevEntry{offset: s + checkAt + e.cur, prev: candidateL.offset}\n\t\t\t\te.markLongShardDirty(nextHashL)\n\t\t\t\tif s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {\n\t\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\t\tmatchedNext := e.matchlen(s+8+checkAt, coffsetL+8, src) + 8\n\t\t\t\t\tif matchedNext > matched {\n\t\t\t\t\t\tt = coffsetL\n\t\t\t\t\t\ts += checkAt\n\t\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\t\tprintln(\"long match (after short)\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Check prev long...\n\t\t\t\tcoffsetL = candidateL.prev - e.cur\n\t\t\t\tif s-coffsetL < e.maxMatchOff && cv == load6432(src, coffsetL) {\n\t\t\t\t\t// Found a long match, at least 8 bytes.\n\t\t\t\t\tmatchedNext := e.matchlen(s+8+checkAt, coffsetL+8, src) + 8\n\t\t\t\t\tif matchedNext > matched {\n\t\t\t\t\t\tt = coffsetL\n\t\t\t\t\t\ts += checkAt\n\t\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\t\tprintln(\"prev long match (after short)\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tt = coffsetS\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"short match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// No match found, move forward in input.\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t\t// Try to find a better match by searching for a long match at the end of the current best match\n\t\tif s+matched < sLimit {\n\t\t\tnextHashL := hashLen(load6432(src, s+matched), betterLongTableBits, betterLongLen)\n\t\t\tcv := load3232(src, s)\n\t\t\tcandidateL := e.longTable[nextHashL]\n\t\t\tcoffsetL := candidateL.offset - e.cur - matched\n\t\t\tif coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) {\n\t\t\t\t// Found a long match, at least 4 bytes.\n\t\t\t\tmatchedNext := e.matchlen(s+4, coffsetL+4, src) + 4\n\t\t\t\tif matchedNext > matched {\n\t\t\t\t\tt = coffsetL\n\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\tprintln(\"long match at end-of-match\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check prev long...\n\t\t\tif true {\n\t\t\t\tcoffsetL = candidateL.prev - e.cur - matched\n\t\t\t\tif coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) {\n\t\t\t\t\t// Found a long match, at least 4 bytes.\n\t\t\t\t\tmatchedNext := e.matchlen(s+4, coffsetL+4, src) + 4\n\t\t\t\t\tif matchedNext > matched {\n\t\t\t\t\t\tt = coffsetL\n\t\t\t\t\t\tmatched = matchedNext\n\t\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\t\tprintln(\"prev long match at end-of-match\")\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\t// A match has been found. Update recent offsets.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && canRepeat && int(offset1) > len(src) {\n\t\t\tpanic(\"invalid offset\")\n\t\t}\n\n\t\t// Extend the n-byte match as long as possible.\n\t\tl := matched\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\n\t\t// Index match start+1 (long) -> s - 1\n\t\toff := index0 + e.cur\n\t\tfor index0 < s-1 {\n\t\t\tcv0 := load6432(src, index0)\n\t\t\tcv1 := cv0 >> 8\n\t\t\th0 := hashLen(cv0, betterLongTableBits, betterLongLen)\n\t\t\te.longTable[h0] = prevEntry{offset: off, prev: e.longTable[h0].offset}\n\t\t\te.markLongShardDirty(h0)\n\t\t\th1 := hashLen(cv1, betterShortTableBits, betterShortLen)\n\t\t\te.table[h1] = tableEntry{offset: off + 1, val: uint32(cv1)}\n\t\t\te.markShortShardDirty(h1)\n\t\t\tindex0 += 2\n\t\t\toff += 2\n\t\t}\n\n\t\tcv = load6432(src, s)\n\t\tif !canRepeat {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check offset 2\n\t\tfor {\n\t\t\to2 := s - offset2\n\t\t\tif load3232(src, o2) != uint32(cv) {\n\t\t\t\t// Do regular search\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHashL := hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\tnextHashS := hashLen(cv, betterShortTableBits, betterShortLen)\n\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\tl := 4 + e.matchlen(s+4, o2+4, src)\n\n\t\t\te.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: e.longTable[nextHashL].offset}\n\t\t\te.markLongShardDirty(nextHashL)\n\t\t\te.table[nextHashS] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.markShortShardDirty(nextHashS)\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\t// Finished\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tblk.recentOffsets[0] = uint32(offset1)\n\tblk.recentOffsets[1] = uint32(offset2)\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n}\n\n// ResetDict will reset and set a dictionary if not nil\nfunc (e *betterFastEncoder) Reset(d *dict, singleBlock bool) {\n\te.resetBase(d, singleBlock)\n\tif d != nil {\n\t\tpanic(\"betterFastEncoder: Reset with dict\")\n\t}\n}\n\n// ResetDict will reset and set a dictionary if not nil\nfunc (e *betterFastEncoderDict) Reset(d *dict, singleBlock bool) {\n\te.resetBase(d, singleBlock)\n\tif d == nil {\n\t\treturn\n\t}\n\t// Init or copy dict table\n\tif len(e.dictTable) != len(e.table) || d.id != e.lastDictID {\n\t\tif len(e.dictTable) != len(e.table) {\n\t\t\te.dictTable = make([]tableEntry, len(e.table))\n\t\t}\n\t\tend := int32(len(d.content)) - 8 + e.maxMatchOff\n\t\tfor i := e.maxMatchOff; i < end; i += 4 {\n\t\t\tconst hashLog = betterShortTableBits\n\n\t\t\tcv := load6432(d.content, i-e.maxMatchOff)\n\t\t\tnextHash := hashLen(cv, hashLog, betterShortLen)      // 0 -> 4\n\t\t\tnextHash1 := hashLen(cv>>8, hashLog, betterShortLen)  // 1 -> 5\n\t\t\tnextHash2 := hashLen(cv>>16, hashLog, betterShortLen) // 2 -> 6\n\t\t\tnextHash3 := hashLen(cv>>24, hashLog, betterShortLen) // 3 -> 7\n\t\t\te.dictTable[nextHash] = tableEntry{\n\t\t\t\tval:    uint32(cv),\n\t\t\t\toffset: i,\n\t\t\t}\n\t\t\te.dictTable[nextHash1] = tableEntry{\n\t\t\t\tval:    uint32(cv >> 8),\n\t\t\t\toffset: i + 1,\n\t\t\t}\n\t\t\te.dictTable[nextHash2] = tableEntry{\n\t\t\t\tval:    uint32(cv >> 16),\n\t\t\t\toffset: i + 2,\n\t\t\t}\n\t\t\te.dictTable[nextHash3] = tableEntry{\n\t\t\t\tval:    uint32(cv >> 24),\n\t\t\t\toffset: i + 3,\n\t\t\t}\n\t\t}\n\t\te.lastDictID = d.id\n\t\te.allDirty = true\n\t}\n\n\t// Init or copy dict table\n\tif len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {\n\t\tif len(e.dictLongTable) != len(e.longTable) {\n\t\t\te.dictLongTable = make([]prevEntry, len(e.longTable))\n\t\t}\n\t\tif len(d.content) >= 8 {\n\t\t\tcv := load6432(d.content, 0)\n\t\t\th := hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\te.dictLongTable[h] = prevEntry{\n\t\t\t\toffset: e.maxMatchOff,\n\t\t\t\tprev:   e.dictLongTable[h].offset,\n\t\t\t}\n\n\t\t\tend := int32(len(d.content)) - 8 + e.maxMatchOff\n\t\t\toff := 8 // First to read\n\t\t\tfor i := e.maxMatchOff + 1; i < end; i++ {\n\t\t\t\tcv = cv>>8 | (uint64(d.content[off]) << 56)\n\t\t\t\th := hashLen(cv, betterLongTableBits, betterLongLen)\n\t\t\t\te.dictLongTable[h] = prevEntry{\n\t\t\t\t\toffset: i,\n\t\t\t\t\tprev:   e.dictLongTable[h].offset,\n\t\t\t\t}\n\t\t\t\toff++\n\t\t\t}\n\t\t}\n\t\te.lastDictID = d.id\n\t\te.allDirty = true\n\t}\n\n\t// Reset table to initial state\n\t{\n\t\tdirtyShardCnt := 0\n\t\tif !e.allDirty {\n\t\t\tfor i := range e.shortTableShardDirty {\n\t\t\t\tif e.shortTableShardDirty[i] {\n\t\t\t\t\tdirtyShardCnt++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst shardCnt = betterShortTableShardCnt\n\t\tconst shardSize = betterShortTableShardSize\n\t\tif e.allDirty || dirtyShardCnt > shardCnt*4/6 {\n\t\t\tcopy(e.table[:], e.dictTable)\n\t\t\tfor i := range e.shortTableShardDirty {\n\t\t\t\te.shortTableShardDirty[i] = false\n\t\t\t}\n\t\t} else {\n\t\t\tfor i := range e.shortTableShardDirty {\n\t\t\t\tif !e.shortTableShardDirty[i] {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tcopy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize])\n\t\t\t\te.shortTableShardDirty[i] = false\n\t\t\t}\n\t\t}\n\t}\n\t{\n\t\tdirtyShardCnt := 0\n\t\tif !e.allDirty {\n\t\t\tfor i := range e.shortTableShardDirty {\n\t\t\t\tif e.shortTableShardDirty[i] {\n\t\t\t\t\tdirtyShardCnt++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst shardCnt = betterLongTableShardCnt\n\t\tconst shardSize = betterLongTableShardSize\n\t\tif e.allDirty || dirtyShardCnt > shardCnt*4/6 {\n\t\t\tcopy(e.longTable[:], e.dictLongTable)\n\t\t\tfor i := range e.longTableShardDirty {\n\t\t\t\te.longTableShardDirty[i] = false\n\t\t\t}\n\t\t} else {\n\t\t\tfor i := range e.longTableShardDirty {\n\t\t\t\tif !e.longTableShardDirty[i] {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tcopy(e.longTable[i*shardSize:(i+1)*shardSize], e.dictLongTable[i*shardSize:(i+1)*shardSize])\n\t\t\t\te.longTableShardDirty[i] = false\n\t\t\t}\n\t\t}\n\t}\n\te.cur = e.maxMatchOff\n\te.allDirty = false\n}\n\nfunc (e *betterFastEncoderDict) markLongShardDirty(entryNum uint32) {\n\te.longTableShardDirty[entryNum/betterLongTableShardSize] = true\n}\n\nfunc (e *betterFastEncoderDict) markShortShardDirty(entryNum uint32) {\n\te.shortTableShardDirty[entryNum/betterShortTableShardSize] = true\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/enc_dfast.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport \"fmt\"\n\nconst (\n\tdFastLongTableBits = 17                      // Bits used in the long match table\n\tdFastLongTableSize = 1 << dFastLongTableBits // Size of the table\n\tdFastLongTableMask = dFastLongTableSize - 1  // Mask for table indices. Redundant, but can eliminate bounds checks.\n\tdFastLongLen       = 8                       // Bytes used for table hash\n\n\tdLongTableShardCnt  = 1 << (dFastLongTableBits - dictShardBits) // Number of shards in the table\n\tdLongTableShardSize = dFastLongTableSize / tableShardCnt        // Size of an individual shard\n\n\tdFastShortTableBits = tableBits                // Bits used in the short match table\n\tdFastShortTableSize = 1 << dFastShortTableBits // Size of the table\n\tdFastShortTableMask = dFastShortTableSize - 1  // Mask for table indices. Redundant, but can eliminate bounds checks.\n\tdFastShortLen       = 5                        // Bytes used for table hash\n\n)\n\ntype doubleFastEncoder struct {\n\tfastEncoder\n\tlongTable [dFastLongTableSize]tableEntry\n}\n\ntype doubleFastEncoderDict struct {\n\tfastEncoderDict\n\tlongTable           [dFastLongTableSize]tableEntry\n\tdictLongTable       []tableEntry\n\tlongTableShardDirty [dLongTableShardCnt]bool\n}\n\n// Encode mimmics functionality in zstd_dfast.c\nfunc (e *doubleFastEncoder) Encode(blk *blockEnc, src []byte) {\n\tconst (\n\t\t// Input margin is the number of bytes we read (8)\n\t\t// and the maximum we will read ahead (2)\n\t\tinputMargin            = 8 + 2\n\t\tminNonLiteralBlockSize = 16\n\t)\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= e.bufferReset-int32(len(e.hist)) {\n\t\tif len(e.hist) == 0 {\n\t\t\te.table = [dFastShortTableSize]tableEntry{}\n\t\t\te.longTable = [dFastLongTableSize]tableEntry{}\n\t\t\te.cur = e.maxMatchOff\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - e.maxMatchOff\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.longTable[:] {\n\t\t\tv := e.longTable[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.longTable[i].offset = v\n\t\t}\n\t\te.cur = e.maxMatchOff\n\t\tbreak\n\t}\n\n\ts := e.addBlock(src)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 1.\n\tconst stepSize = 1\n\n\tconst kSearchStrength = 8\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\tvar t int32\n\t\t// We allow the encoder to optionally turn off repeat offsets across blocks\n\t\tcanRepeat := len(blk.sequences) > 2\n\n\t\tfor {\n\t\t\tif debugAsserts && canRepeat && offset1 == 0 {\n\t\t\t\tpanic(\"offset0 was 0\")\n\t\t\t}\n\n\t\t\tnextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)\n\t\t\tnextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)\n\t\t\tcandidateL := e.longTable[nextHashL]\n\t\t\tcandidateS := e.table[nextHashS]\n\n\t\t\tconst repOff = 1\n\t\t\trepIndex := s - offset1 + repOff\n\t\t\tentry := tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.longTable[nextHashL] = entry\n\t\t\te.table[nextHashS] = entry\n\n\t\t\tif canRepeat {\n\t\t\t\tif repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {\n\t\t\t\t\t// Consider history as well.\n\t\t\t\t\tvar seq seq\n\t\t\t\t\tlenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)\n\n\t\t\t\t\tseq.matchLen = uint32(lenght - zstdMinMatch)\n\n\t\t\t\t\t// We might be able to match backwards.\n\t\t\t\t\t// Extend as long as we can.\n\t\t\t\t\tstart := s + repOff\n\t\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t\t// and have to do special offset treatment.\n\t\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\t\tif tMin < 0 {\n\t\t\t\t\t\ttMin = 0\n\t\t\t\t\t}\n\t\t\t\t\tfor repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {\n\t\t\t\t\t\trepIndex--\n\t\t\t\t\t\tstart--\n\t\t\t\t\t\tseq.matchLen++\n\t\t\t\t\t}\n\t\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t\t// rep 0\n\t\t\t\t\tseq.offset = 1\n\t\t\t\t\tif debugSequences {\n\t\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t\t}\n\t\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\t\t\t\t\ts += lenght + repOff\n\t\t\t\t\tnextEmit = s\n\t\t\t\t\tif s >= sLimit {\n\t\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\t\tprintln(\"repeat ended\", s, lenght)\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak encodeLoop\n\t\t\t\t\t}\n\t\t\t\t\tcv = load6432(src, s)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Find the offsets of our two matches.\n\t\t\tcoffsetL := s - (candidateL.offset - e.cur)\n\t\t\tcoffsetS := s - (candidateS.offset - e.cur)\n\n\t\t\t// Check if we have a long match.\n\t\t\tif coffsetL < e.maxMatchOff && uint32(cv) == candidateL.val {\n\t\t\t\t// Found a long match, likely at least 8 bytes.\n\t\t\t\t// Reference encoder checks all 8 bytes, we only check 4,\n\t\t\t\t// but the likelihood of both the first 4 bytes and the hash matching should be enough.\n\t\t\t\tt = candidateL.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Check if we have a short match.\n\t\t\tif coffsetS < e.maxMatchOff && uint32(cv) == candidateS.val {\n\t\t\t\t// found a regular match\n\t\t\t\t// See if we can find a long match at s+1\n\t\t\t\tconst checkAt = 1\n\t\t\t\tcv := load6432(src, s+checkAt)\n\t\t\t\tnextHashL = hashLen(cv, dFastLongTableBits, dFastLongLen)\n\t\t\t\tcandidateL = e.longTable[nextHashL]\n\t\t\t\tcoffsetL = s - (candidateL.offset - e.cur) + checkAt\n\n\t\t\t\t// We can store it, since we have at least a 4 byte match.\n\t\t\t\te.longTable[nextHashL] = tableEntry{offset: s + checkAt + e.cur, val: uint32(cv)}\n\t\t\t\tif coffsetL < e.maxMatchOff && uint32(cv) == candidateL.val {\n\t\t\t\t\t// Found a long match, likely at least 8 bytes.\n\t\t\t\t\t// Reference encoder checks all 8 bytes, we only check 4,\n\t\t\t\t\t// but the likelihood of both the first 4 bytes and the hash matching should be enough.\n\t\t\t\t\tt = candidateL.offset - e.cur\n\t\t\t\t\ts += checkAt\n\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\tprintln(\"long match (after short)\")\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tt = candidateS.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"short match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// No match found, move forward in input.\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\n\t\t// A 4-byte match has been found. Update recent offsets.\n\t\t// We'll later see if more than 4 bytes.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && canRepeat && int(offset1) > len(src) {\n\t\t\tpanic(\"invalid offset\")\n\t\t}\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tl := e.matchlen(s+4, t+4, src) + 4\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\n\t\t// Index match start+1 (long) and start+2 (short)\n\t\tindex0 := s - l + 1\n\t\t// Index match end-2 (long) and end-1 (short)\n\t\tindex1 := s - 2\n\n\t\tcv0 := load6432(src, index0)\n\t\tcv1 := load6432(src, index1)\n\t\tte0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)}\n\t\tte1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)}\n\t\te.longTable[hashLen(cv0, dFastLongTableBits, dFastLongLen)] = te0\n\t\te.longTable[hashLen(cv1, dFastLongTableBits, dFastLongLen)] = te1\n\t\tcv0 >>= 8\n\t\tcv1 >>= 8\n\t\tte0.offset++\n\t\tte1.offset++\n\t\tte0.val = uint32(cv0)\n\t\tte1.val = uint32(cv1)\n\t\te.table[hashLen(cv0, dFastShortTableBits, dFastShortLen)] = te0\n\t\te.table[hashLen(cv1, dFastShortTableBits, dFastShortLen)] = te1\n\n\t\tcv = load6432(src, s)\n\n\t\tif !canRepeat {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check offset 2\n\t\tfor {\n\t\t\to2 := s - offset2\n\t\t\tif load3232(src, o2) != uint32(cv) {\n\t\t\t\t// Do regular search\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)\n\t\t\tnextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)\n\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\tl := 4 + e.matchlen(s+4, o2+4, src)\n\n\t\t\tentry := tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.longTable[nextHashL] = entry\n\t\t\te.table[nextHashS] = entry\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\t// Finished\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tblk.recentOffsets[0] = uint32(offset1)\n\tblk.recentOffsets[1] = uint32(offset2)\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n}\n\n// EncodeNoHist will encode a block with no history and no following blocks.\n// Most notable difference is that src will not be copied for history and\n// we do not need to check for max match length.\nfunc (e *doubleFastEncoder) EncodeNoHist(blk *blockEnc, src []byte) {\n\tconst (\n\t\t// Input margin is the number of bytes we read (8)\n\t\t// and the maximum we will read ahead (2)\n\t\tinputMargin            = 8 + 2\n\t\tminNonLiteralBlockSize = 16\n\t)\n\n\t// Protect against e.cur wraparound.\n\tif e.cur >= e.bufferReset {\n\t\tfor i := range e.table[:] {\n\t\t\te.table[i] = tableEntry{}\n\t\t}\n\t\tfor i := range e.longTable[:] {\n\t\t\te.longTable[i] = tableEntry{}\n\t\t}\n\t\te.cur = e.maxMatchOff\n\t}\n\n\ts := int32(0)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Override src\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 1.\n\tconst stepSize = 1\n\n\tconst kSearchStrength = 8\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\tvar t int32\n\t\tfor {\n\n\t\t\tnextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)\n\t\t\tnextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)\n\t\t\tcandidateL := e.longTable[nextHashL]\n\t\t\tcandidateS := e.table[nextHashS]\n\n\t\t\tconst repOff = 1\n\t\t\trepIndex := s - offset1 + repOff\n\t\t\tentry := tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.longTable[nextHashL] = entry\n\t\t\te.table[nextHashS] = entry\n\n\t\t\tif len(blk.sequences) > 2 {\n\t\t\t\tif load3232(src, repIndex) == uint32(cv>>(repOff*8)) {\n\t\t\t\t\t// Consider history as well.\n\t\t\t\t\tvar seq seq\n\t\t\t\t\t//length := 4 + e.matchlen(s+4+repOff, repIndex+4, src)\n\t\t\t\t\tlength := 4 + int32(matchLen(src[s+4+repOff:], src[repIndex+4:]))\n\n\t\t\t\t\tseq.matchLen = uint32(length - zstdMinMatch)\n\n\t\t\t\t\t// We might be able to match backwards.\n\t\t\t\t\t// Extend as long as we can.\n\t\t\t\t\tstart := s + repOff\n\t\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t\t// and have to do special offset treatment.\n\t\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\t\tif tMin < 0 {\n\t\t\t\t\t\ttMin = 0\n\t\t\t\t\t}\n\t\t\t\t\tfor repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] {\n\t\t\t\t\t\trepIndex--\n\t\t\t\t\t\tstart--\n\t\t\t\t\t\tseq.matchLen++\n\t\t\t\t\t}\n\t\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t\t// rep 0\n\t\t\t\t\tseq.offset = 1\n\t\t\t\t\tif debugSequences {\n\t\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t\t}\n\t\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\t\t\t\t\ts += length + repOff\n\t\t\t\t\tnextEmit = s\n\t\t\t\t\tif s >= sLimit {\n\t\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\t\tprintln(\"repeat ended\", s, length)\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak encodeLoop\n\t\t\t\t\t}\n\t\t\t\t\tcv = load6432(src, s)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Find the offsets of our two matches.\n\t\t\tcoffsetL := s - (candidateL.offset - e.cur)\n\t\t\tcoffsetS := s - (candidateS.offset - e.cur)\n\n\t\t\t// Check if we have a long match.\n\t\t\tif coffsetL < e.maxMatchOff && uint32(cv) == candidateL.val {\n\t\t\t\t// Found a long match, likely at least 8 bytes.\n\t\t\t\t// Reference encoder checks all 8 bytes, we only check 4,\n\t\t\t\t// but the likelihood of both the first 4 bytes and the hash matching should be enough.\n\t\t\t\tt = candidateL.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d). cur: %d\", s, t, e.cur))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Check if we have a short match.\n\t\t\tif coffsetS < e.maxMatchOff && uint32(cv) == candidateS.val {\n\t\t\t\t// found a regular match\n\t\t\t\t// See if we can find a long match at s+1\n\t\t\t\tconst checkAt = 1\n\t\t\t\tcv := load6432(src, s+checkAt)\n\t\t\t\tnextHashL = hashLen(cv, dFastLongTableBits, dFastLongLen)\n\t\t\t\tcandidateL = e.longTable[nextHashL]\n\t\t\t\tcoffsetL = s - (candidateL.offset - e.cur) + checkAt\n\n\t\t\t\t// We can store it, since we have at least a 4 byte match.\n\t\t\t\te.longTable[nextHashL] = tableEntry{offset: s + checkAt + e.cur, val: uint32(cv)}\n\t\t\t\tif coffsetL < e.maxMatchOff && uint32(cv) == candidateL.val {\n\t\t\t\t\t// Found a long match, likely at least 8 bytes.\n\t\t\t\t\t// Reference encoder checks all 8 bytes, we only check 4,\n\t\t\t\t\t// but the likelihood of both the first 4 bytes and the hash matching should be enough.\n\t\t\t\t\tt = candidateL.offset - e.cur\n\t\t\t\t\ts += checkAt\n\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\tprintln(\"long match (after short)\")\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tt = candidateS.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"short match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// No match found, move forward in input.\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\n\t\t// A 4-byte match has been found. Update recent offsets.\n\t\t// We'll later see if more than 4 bytes.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\t//l := e.matchlen(s+4, t+4, src) + 4\n\t\tl := int32(matchLen(src[s+4:], src[t+4:])) + 4\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\n\t\t// Index match start+1 (long) and start+2 (short)\n\t\tindex0 := s - l + 1\n\t\t// Index match end-2 (long) and end-1 (short)\n\t\tindex1 := s - 2\n\n\t\tcv0 := load6432(src, index0)\n\t\tcv1 := load6432(src, index1)\n\t\tte0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)}\n\t\tte1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)}\n\t\te.longTable[hashLen(cv0, dFastLongTableBits, dFastLongLen)] = te0\n\t\te.longTable[hashLen(cv1, dFastLongTableBits, dFastLongLen)] = te1\n\t\tcv0 >>= 8\n\t\tcv1 >>= 8\n\t\tte0.offset++\n\t\tte1.offset++\n\t\tte0.val = uint32(cv0)\n\t\tte1.val = uint32(cv1)\n\t\te.table[hashLen(cv0, dFastShortTableBits, dFastShortLen)] = te0\n\t\te.table[hashLen(cv1, dFastShortTableBits, dFastShortLen)] = te1\n\n\t\tcv = load6432(src, s)\n\n\t\tif len(blk.sequences) <= 2 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check offset 2\n\t\tfor {\n\t\t\to2 := s - offset2\n\t\t\tif load3232(src, o2) != uint32(cv) {\n\t\t\t\t// Do regular search\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHashS := hashLen(cv1>>8, dFastShortTableBits, dFastShortLen)\n\t\t\tnextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)\n\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\t//l := 4 + e.matchlen(s+4, o2+4, src)\n\t\t\tl := 4 + int32(matchLen(src[s+4:], src[o2+4:]))\n\n\t\t\tentry := tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.longTable[nextHashL] = entry\n\t\t\te.table[nextHashS] = entry\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\t// Finished\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n\n\t// We do not store history, so we must offset e.cur to avoid false matches for next user.\n\tif e.cur < e.bufferReset {\n\t\te.cur += int32(len(src))\n\t}\n}\n\n// Encode will encode the content, with a dictionary if initialized for it.\nfunc (e *doubleFastEncoderDict) Encode(blk *blockEnc, src []byte) {\n\tconst (\n\t\t// Input margin is the number of bytes we read (8)\n\t\t// and the maximum we will read ahead (2)\n\t\tinputMargin            = 8 + 2\n\t\tminNonLiteralBlockSize = 16\n\t)\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= e.bufferReset-int32(len(e.hist)) {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\tfor i := range e.longTable[:] {\n\t\t\t\te.longTable[i] = tableEntry{}\n\t\t\t}\n\t\t\te.markAllShardsDirty()\n\t\t\te.cur = e.maxMatchOff\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - e.maxMatchOff\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\tfor i := range e.longTable[:] {\n\t\t\tv := e.longTable[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.longTable[i].offset = v\n\t\t}\n\t\te.markAllShardsDirty()\n\t\te.cur = e.maxMatchOff\n\t\tbreak\n\t}\n\n\ts := e.addBlock(src)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 1.\n\tconst stepSize = 1\n\n\tconst kSearchStrength = 8\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\tvar t int32\n\t\t// We allow the encoder to optionally turn off repeat offsets across blocks\n\t\tcanRepeat := len(blk.sequences) > 2\n\n\t\tfor {\n\t\t\tif debugAsserts && canRepeat && offset1 == 0 {\n\t\t\t\tpanic(\"offset0 was 0\")\n\t\t\t}\n\n\t\t\tnextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)\n\t\t\tnextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)\n\t\t\tcandidateL := e.longTable[nextHashL]\n\t\t\tcandidateS := e.table[nextHashS]\n\n\t\t\tconst repOff = 1\n\t\t\trepIndex := s - offset1 + repOff\n\t\t\tentry := tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.longTable[nextHashL] = entry\n\t\t\te.markLongShardDirty(nextHashL)\n\t\t\te.table[nextHashS] = entry\n\t\t\te.markShardDirty(nextHashS)\n\n\t\t\tif canRepeat {\n\t\t\t\tif repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>(repOff*8)) {\n\t\t\t\t\t// Consider history as well.\n\t\t\t\t\tvar seq seq\n\t\t\t\t\tlenght := 4 + e.matchlen(s+4+repOff, repIndex+4, src)\n\n\t\t\t\t\tseq.matchLen = uint32(lenght - zstdMinMatch)\n\n\t\t\t\t\t// We might be able to match backwards.\n\t\t\t\t\t// Extend as long as we can.\n\t\t\t\t\tstart := s + repOff\n\t\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t\t// and have to do special offset treatment.\n\t\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\t\ttMin := s - e.maxMatchOff\n\t\t\t\t\tif tMin < 0 {\n\t\t\t\t\t\ttMin = 0\n\t\t\t\t\t}\n\t\t\t\t\tfor repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {\n\t\t\t\t\t\trepIndex--\n\t\t\t\t\t\tstart--\n\t\t\t\t\t\tseq.matchLen++\n\t\t\t\t\t}\n\t\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t\t// rep 0\n\t\t\t\t\tseq.offset = 1\n\t\t\t\t\tif debugSequences {\n\t\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t\t}\n\t\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\t\t\t\t\ts += lenght + repOff\n\t\t\t\t\tnextEmit = s\n\t\t\t\t\tif s >= sLimit {\n\t\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\t\tprintln(\"repeat ended\", s, lenght)\n\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak encodeLoop\n\t\t\t\t\t}\n\t\t\t\t\tcv = load6432(src, s)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Find the offsets of our two matches.\n\t\t\tcoffsetL := s - (candidateL.offset - e.cur)\n\t\t\tcoffsetS := s - (candidateS.offset - e.cur)\n\n\t\t\t// Check if we have a long match.\n\t\t\tif coffsetL < e.maxMatchOff && uint32(cv) == candidateL.val {\n\t\t\t\t// Found a long match, likely at least 8 bytes.\n\t\t\t\t// Reference encoder checks all 8 bytes, we only check 4,\n\t\t\t\t// but the likelihood of both the first 4 bytes and the hash matching should be enough.\n\t\t\t\tt = candidateL.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"long match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Check if we have a short match.\n\t\t\tif coffsetS < e.maxMatchOff && uint32(cv) == candidateS.val {\n\t\t\t\t// found a regular match\n\t\t\t\t// See if we can find a long match at s+1\n\t\t\t\tconst checkAt = 1\n\t\t\t\tcv := load6432(src, s+checkAt)\n\t\t\t\tnextHashL = hashLen(cv, dFastLongTableBits, dFastLongLen)\n\t\t\t\tcandidateL = e.longTable[nextHashL]\n\t\t\t\tcoffsetL = s - (candidateL.offset - e.cur) + checkAt\n\n\t\t\t\t// We can store it, since we have at least a 4 byte match.\n\t\t\t\te.longTable[nextHashL] = tableEntry{offset: s + checkAt + e.cur, val: uint32(cv)}\n\t\t\t\te.markLongShardDirty(nextHashL)\n\t\t\t\tif coffsetL < e.maxMatchOff && uint32(cv) == candidateL.val {\n\t\t\t\t\t// Found a long match, likely at least 8 bytes.\n\t\t\t\t\t// Reference encoder checks all 8 bytes, we only check 4,\n\t\t\t\t\t// but the likelihood of both the first 4 bytes and the hash matching should be enough.\n\t\t\t\t\tt = candidateL.offset - e.cur\n\t\t\t\t\ts += checkAt\n\t\t\t\t\tif debugMatches {\n\t\t\t\t\t\tprintln(\"long match (after short)\")\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tt = candidateS.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tif debugMatches {\n\t\t\t\t\tprintln(\"short match\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// No match found, move forward in input.\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\n\t\t// A 4-byte match has been found. Update recent offsets.\n\t\t// We'll later see if more than 4 bytes.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && canRepeat && int(offset1) > len(src) {\n\t\t\tpanic(\"invalid offset\")\n\t\t}\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tl := e.matchlen(s+4, t+4, src) + 4\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\n\t\t// Index match start+1 (long) and start+2 (short)\n\t\tindex0 := s - l + 1\n\t\t// Index match end-2 (long) and end-1 (short)\n\t\tindex1 := s - 2\n\n\t\tcv0 := load6432(src, index0)\n\t\tcv1 := load6432(src, index1)\n\t\tte0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)}\n\t\tte1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)}\n\t\tlongHash1 := hashLen(cv0, dFastLongTableBits, dFastLongLen)\n\t\tlongHash2 := hashLen(cv1, dFastLongTableBits, dFastLongLen)\n\t\te.longTable[longHash1] = te0\n\t\te.longTable[longHash2] = te1\n\t\te.markLongShardDirty(longHash1)\n\t\te.markLongShardDirty(longHash2)\n\t\tcv0 >>= 8\n\t\tcv1 >>= 8\n\t\tte0.offset++\n\t\tte1.offset++\n\t\tte0.val = uint32(cv0)\n\t\tte1.val = uint32(cv1)\n\t\thashVal1 := hashLen(cv0, dFastShortTableBits, dFastShortLen)\n\t\thashVal2 := hashLen(cv1, dFastShortTableBits, dFastShortLen)\n\t\te.table[hashVal1] = te0\n\t\te.markShardDirty(hashVal1)\n\t\te.table[hashVal2] = te1\n\t\te.markShardDirty(hashVal2)\n\n\t\tcv = load6432(src, s)\n\n\t\tif !canRepeat {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Check offset 2\n\t\tfor {\n\t\t\to2 := s - offset2\n\t\t\tif load3232(src, o2) != uint32(cv) {\n\t\t\t\t// Do regular search\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen)\n\t\t\tnextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen)\n\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\tl := 4 + e.matchlen(s+4, o2+4, src)\n\n\t\t\tentry := tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.longTable[nextHashL] = entry\n\t\t\te.markLongShardDirty(nextHashL)\n\t\t\te.table[nextHashS] = entry\n\t\t\te.markShardDirty(nextHashS)\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\t// Finished\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tblk.recentOffsets[0] = uint32(offset1)\n\tblk.recentOffsets[1] = uint32(offset2)\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n\t// If we encoded more than 64K mark all dirty.\n\tif len(src) > 64<<10 {\n\t\te.markAllShardsDirty()\n\t}\n}\n\n// ResetDict will reset and set a dictionary if not nil\nfunc (e *doubleFastEncoder) Reset(d *dict, singleBlock bool) {\n\te.fastEncoder.Reset(d, singleBlock)\n\tif d != nil {\n\t\tpanic(\"doubleFastEncoder: Reset with dict not supported\")\n\t}\n}\n\n// ResetDict will reset and set a dictionary if not nil\nfunc (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) {\n\tallDirty := e.allDirty\n\te.fastEncoderDict.Reset(d, singleBlock)\n\tif d == nil {\n\t\treturn\n\t}\n\n\t// Init or copy dict table\n\tif len(e.dictLongTable) != len(e.longTable) || d.id != e.lastDictID {\n\t\tif len(e.dictLongTable) != len(e.longTable) {\n\t\t\te.dictLongTable = make([]tableEntry, len(e.longTable))\n\t\t}\n\t\tif len(d.content) >= 8 {\n\t\t\tcv := load6432(d.content, 0)\n\t\t\te.dictLongTable[hashLen(cv, dFastLongTableBits, dFastLongLen)] = tableEntry{\n\t\t\t\tval:    uint32(cv),\n\t\t\t\toffset: e.maxMatchOff,\n\t\t\t}\n\t\t\tend := int32(len(d.content)) - 8 + e.maxMatchOff\n\t\t\tfor i := e.maxMatchOff + 1; i < end; i++ {\n\t\t\t\tcv = cv>>8 | (uint64(d.content[i-e.maxMatchOff+7]) << 56)\n\t\t\t\te.dictLongTable[hashLen(cv, dFastLongTableBits, dFastLongLen)] = tableEntry{\n\t\t\t\t\tval:    uint32(cv),\n\t\t\t\t\toffset: i,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\te.lastDictID = d.id\n\t\tallDirty = true\n\t}\n\t// Reset table to initial state\n\te.cur = e.maxMatchOff\n\n\tdirtyShardCnt := 0\n\tif !allDirty {\n\t\tfor i := range e.longTableShardDirty {\n\t\t\tif e.longTableShardDirty[i] {\n\t\t\t\tdirtyShardCnt++\n\t\t\t}\n\t\t}\n\t}\n\n\tif allDirty || dirtyShardCnt > dLongTableShardCnt/2 {\n\t\t//copy(e.longTable[:], e.dictLongTable)\n\t\te.longTable = *(*[dFastLongTableSize]tableEntry)(e.dictLongTable)\n\t\tfor i := range e.longTableShardDirty {\n\t\t\te.longTableShardDirty[i] = false\n\t\t}\n\t\treturn\n\t}\n\tfor i := range e.longTableShardDirty {\n\t\tif !e.longTableShardDirty[i] {\n\t\t\tcontinue\n\t\t}\n\n\t\t// copy(e.longTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize], e.dictLongTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize])\n\t\t*(*[dLongTableShardSize]tableEntry)(e.longTable[i*dLongTableShardSize:]) = *(*[dLongTableShardSize]tableEntry)(e.dictLongTable[i*dLongTableShardSize:])\n\n\t\te.longTableShardDirty[i] = false\n\t}\n}\n\nfunc (e *doubleFastEncoderDict) markLongShardDirty(entryNum uint32) {\n\te.longTableShardDirty[entryNum/dLongTableShardSize] = true\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/enc_fast.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"fmt\"\n)\n\nconst (\n\ttableBits        = 15                               // Bits used in the table\n\ttableSize        = 1 << tableBits                   // Size of the table\n\ttableShardCnt    = 1 << (tableBits - dictShardBits) // Number of shards in the table\n\ttableShardSize   = tableSize / tableShardCnt        // Size of an individual shard\n\ttableFastHashLen = 6\n\ttableMask        = tableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks.\n\tmaxMatchLength   = 131074\n)\n\ntype tableEntry struct {\n\tval    uint32\n\toffset int32\n}\n\ntype fastEncoder struct {\n\tfastBase\n\ttable [tableSize]tableEntry\n}\n\ntype fastEncoderDict struct {\n\tfastEncoder\n\tdictTable       []tableEntry\n\ttableShardDirty [tableShardCnt]bool\n\tallDirty        bool\n}\n\n// Encode mimmics functionality in zstd_fast.c\nfunc (e *fastEncoder) Encode(blk *blockEnc, src []byte) {\n\tconst (\n\t\tinputMargin            = 8\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t)\n\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= e.bufferReset-int32(len(e.hist)) {\n\t\tif len(e.hist) == 0 {\n\t\t\tfor i := range e.table[:] {\n\t\t\t\te.table[i] = tableEntry{}\n\t\t\t}\n\t\t\te.cur = e.maxMatchOff\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - e.maxMatchOff\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\te.cur = e.maxMatchOff\n\t\tbreak\n\t}\n\n\ts := e.addBlock(src)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 2.\n\tconst stepSize = 2\n\n\t// TEMPLATE\n\tconst hashLog = tableBits\n\t// seems global, but would be nice to tweak.\n\tconst kSearchStrength = 6\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\t// t will contain the match offset when we find one.\n\t\t// When existing the search loop, we have already checked 4 bytes.\n\t\tvar t int32\n\n\t\t// We will not use repeat offsets across blocks.\n\t\t// By not using them for the first 3 matches\n\t\tcanRepeat := len(blk.sequences) > 2\n\n\t\tfor {\n\t\t\tif debugAsserts && canRepeat && offset1 == 0 {\n\t\t\t\tpanic(\"offset0 was 0\")\n\t\t\t}\n\n\t\t\tnextHash := hashLen(cv, hashLog, tableFastHashLen)\n\t\t\tnextHash2 := hashLen(cv>>8, hashLog, tableFastHashLen)\n\t\t\tcandidate := e.table[nextHash]\n\t\t\tcandidate2 := e.table[nextHash2]\n\t\t\trepIndex := s - offset1 + 2\n\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.table[nextHash2] = tableEntry{offset: s + e.cur + 1, val: uint32(cv >> 8)}\n\n\t\t\tif canRepeat && repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>16) {\n\t\t\t\t// Consider history as well.\n\t\t\t\tvar seq seq\n\t\t\t\tlength := 4 + e.matchlen(s+6, repIndex+4, src)\n\t\t\t\tseq.matchLen = uint32(length - zstdMinMatch)\n\n\t\t\t\t// We might be able to match backwards.\n\t\t\t\t// Extend as long as we can.\n\t\t\t\tstart := s + 2\n\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t// and have to do special offset treatment.\n\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\tsMin := s - e.maxMatchOff\n\t\t\t\tif sMin < 0 {\n\t\t\t\t\tsMin = 0\n\t\t\t\t}\n\t\t\t\tfor repIndex > sMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch {\n\t\t\t\t\trepIndex--\n\t\t\t\t\tstart--\n\t\t\t\t\tseq.matchLen++\n\t\t\t\t}\n\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t// rep 0\n\t\t\t\tseq.offset = 1\n\t\t\t\tif debugSequences {\n\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t}\n\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\t\t\t\ts += length + 2\n\t\t\t\tnextEmit = s\n\t\t\t\tif s >= sLimit {\n\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\tprintln(\"repeat ended\", s, length)\n\n\t\t\t\t\t}\n\t\t\t\t\tbreak encodeLoop\n\t\t\t\t}\n\t\t\t\tcv = load6432(src, s)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcoffset0 := s - (candidate.offset - e.cur)\n\t\t\tcoffset1 := s - (candidate2.offset - e.cur) + 1\n\t\t\tif coffset0 < e.maxMatchOff && uint32(cv) == candidate.val {\n\t\t\t\t// found a regular match\n\t\t\t\tt = candidate.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif coffset1 < e.maxMatchOff && uint32(cv>>8) == candidate2.val {\n\t\t\t\t// found a regular match\n\t\t\t\tt = candidate2.offset - e.cur\n\t\t\t\ts++\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && canRepeat && int(offset1) > len(src) {\n\t\t\tpanic(\"invalid offset\")\n\t\t}\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tl := e.matchlen(s+4, t+4, src) + 4\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence.\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\t// Don't use repeat offsets\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\t\tcv = load6432(src, s)\n\n\t\t// Check offset 2\n\t\tif o2 := s - offset2; canRepeat && load3232(src, o2) == uint32(cv) {\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\tl := 4 + e.matchlen(s+4, o2+4, src)\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHash := hashLen(cv, hashLog, tableFastHashLen)\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\t// Prepare next loop.\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tblk.recentOffsets[0] = uint32(offset1)\n\tblk.recentOffsets[1] = uint32(offset2)\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n}\n\n// EncodeNoHist will encode a block with no history and no following blocks.\n// Most notable difference is that src will not be copied for history and\n// we do not need to check for max match length.\nfunc (e *fastEncoder) EncodeNoHist(blk *blockEnc, src []byte) {\n\tconst (\n\t\tinputMargin            = 8\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t)\n\tif debugEncoder {\n\t\tif len(src) > maxCompressedBlockSize {\n\t\t\tpanic(\"src too big\")\n\t\t}\n\t}\n\n\t// Protect against e.cur wraparound.\n\tif e.cur >= e.bufferReset {\n\t\tfor i := range e.table[:] {\n\t\t\te.table[i] = tableEntry{}\n\t\t}\n\t\te.cur = e.maxMatchOff\n\t}\n\n\ts := int32(0)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 2.\n\tconst stepSize = 2\n\n\t// TEMPLATE\n\tconst hashLog = tableBits\n\t// seems global, but would be nice to tweak.\n\tconst kSearchStrength = 6\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\t// t will contain the match offset when we find one.\n\t\t// When existing the search loop, we have already checked 4 bytes.\n\t\tvar t int32\n\n\t\t// We will not use repeat offsets across blocks.\n\t\t// By not using them for the first 3 matches\n\n\t\tfor {\n\t\t\tnextHash := hashLen(cv, hashLog, tableFastHashLen)\n\t\t\tnextHash2 := hashLen(cv>>8, hashLog, tableFastHashLen)\n\t\t\tcandidate := e.table[nextHash]\n\t\t\tcandidate2 := e.table[nextHash2]\n\t\t\trepIndex := s - offset1 + 2\n\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.table[nextHash2] = tableEntry{offset: s + e.cur + 1, val: uint32(cv >> 8)}\n\n\t\t\tif len(blk.sequences) > 2 && load3232(src, repIndex) == uint32(cv>>16) {\n\t\t\t\t// Consider history as well.\n\t\t\t\tvar seq seq\n\t\t\t\tlength := 4 + e.matchlen(s+6, repIndex+4, src)\n\n\t\t\t\tseq.matchLen = uint32(length - zstdMinMatch)\n\n\t\t\t\t// We might be able to match backwards.\n\t\t\t\t// Extend as long as we can.\n\t\t\t\tstart := s + 2\n\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t// and have to do special offset treatment.\n\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\tsMin := s - e.maxMatchOff\n\t\t\t\tif sMin < 0 {\n\t\t\t\t\tsMin = 0\n\t\t\t\t}\n\t\t\t\tfor repIndex > sMin && start > startLimit && src[repIndex-1] == src[start-1] {\n\t\t\t\t\trepIndex--\n\t\t\t\t\tstart--\n\t\t\t\t\tseq.matchLen++\n\t\t\t\t}\n\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t// rep 0\n\t\t\t\tseq.offset = 1\n\t\t\t\tif debugSequences {\n\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t}\n\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\t\t\t\ts += length + 2\n\t\t\t\tnextEmit = s\n\t\t\t\tif s >= sLimit {\n\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\tprintln(\"repeat ended\", s, length)\n\n\t\t\t\t\t}\n\t\t\t\t\tbreak encodeLoop\n\t\t\t\t}\n\t\t\t\tcv = load6432(src, s)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcoffset0 := s - (candidate.offset - e.cur)\n\t\t\tcoffset1 := s - (candidate2.offset - e.cur) + 1\n\t\t\tif coffset0 < e.maxMatchOff && uint32(cv) == candidate.val {\n\t\t\t\t// found a regular match\n\t\t\t\tt = candidate.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(fmt.Sprintf(\"t (%d) < 0, candidate.offset: %d, e.cur: %d, coffset0: %d, e.maxMatchOff: %d\", t, candidate.offset, e.cur, coffset0, e.maxMatchOff))\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif coffset1 < e.maxMatchOff && uint32(cv>>8) == candidate2.val {\n\t\t\t\t// found a regular match\n\t\t\t\tt = candidate2.offset - e.cur\n\t\t\t\ts++\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && t < 0 {\n\t\t\tpanic(fmt.Sprintf(\"t (%d) < 0 \", t))\n\t\t}\n\t\t// Extend the 4-byte match as long as possible.\n\t\tl := e.matchlen(s+4, t+4, src) + 4\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence.\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\t// Don't use repeat offsets\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\t\tcv = load6432(src, s)\n\n\t\t// Check offset 2\n\t\tif o2 := s - offset2; len(blk.sequences) > 2 && load3232(src, o2) == uint32(cv) {\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\tl := 4 + e.matchlen(s+4, o2+4, src)\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHash := hashLen(cv, hashLog, tableFastHashLen)\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\t// Prepare next loop.\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n\t// We do not store history, so we must offset e.cur to avoid false matches for next user.\n\tif e.cur < e.bufferReset {\n\t\te.cur += int32(len(src))\n\t}\n}\n\n// Encode will encode the content, with a dictionary if initialized for it.\nfunc (e *fastEncoderDict) Encode(blk *blockEnc, src []byte) {\n\tconst (\n\t\tinputMargin            = 8\n\t\tminNonLiteralBlockSize = 1 + 1 + inputMargin\n\t)\n\tif e.allDirty || len(src) > 32<<10 {\n\t\te.fastEncoder.Encode(blk, src)\n\t\te.allDirty = true\n\t\treturn\n\t}\n\t// Protect against e.cur wraparound.\n\tfor e.cur >= e.bufferReset-int32(len(e.hist)) {\n\t\tif len(e.hist) == 0 {\n\t\t\te.table = [tableSize]tableEntry{}\n\t\t\te.cur = e.maxMatchOff\n\t\t\tbreak\n\t\t}\n\t\t// Shift down everything in the table that isn't already too far away.\n\t\tminOff := e.cur + int32(len(e.hist)) - e.maxMatchOff\n\t\tfor i := range e.table[:] {\n\t\t\tv := e.table[i].offset\n\t\t\tif v < minOff {\n\t\t\t\tv = 0\n\t\t\t} else {\n\t\t\t\tv = v - e.cur + e.maxMatchOff\n\t\t\t}\n\t\t\te.table[i].offset = v\n\t\t}\n\t\te.cur = e.maxMatchOff\n\t\tbreak\n\t}\n\n\ts := e.addBlock(src)\n\tblk.size = len(src)\n\tif len(src) < minNonLiteralBlockSize {\n\t\tblk.extraLits = len(src)\n\t\tblk.literals = blk.literals[:len(src)]\n\t\tcopy(blk.literals, src)\n\t\treturn\n\t}\n\n\t// Override src\n\tsrc = e.hist\n\tsLimit := int32(len(src)) - inputMargin\n\t// stepSize is the number of bytes to skip on every main loop iteration.\n\t// It should be >= 2.\n\tconst stepSize = 2\n\n\t// TEMPLATE\n\tconst hashLog = tableBits\n\t// seems global, but would be nice to tweak.\n\tconst kSearchStrength = 7\n\n\t// nextEmit is where in src the next emitLiteral should start from.\n\tnextEmit := s\n\tcv := load6432(src, s)\n\n\t// Relative offsets\n\toffset1 := int32(blk.recentOffsets[0])\n\toffset2 := int32(blk.recentOffsets[1])\n\n\taddLiterals := func(s *seq, until int32) {\n\t\tif until == nextEmit {\n\t\t\treturn\n\t\t}\n\t\tblk.literals = append(blk.literals, src[nextEmit:until]...)\n\t\ts.litLen = uint32(until - nextEmit)\n\t}\n\tif debugEncoder {\n\t\tprintln(\"recent offsets:\", blk.recentOffsets)\n\t}\n\nencodeLoop:\n\tfor {\n\t\t// t will contain the match offset when we find one.\n\t\t// When existing the search loop, we have already checked 4 bytes.\n\t\tvar t int32\n\n\t\t// We will not use repeat offsets across blocks.\n\t\t// By not using them for the first 3 matches\n\t\tcanRepeat := len(blk.sequences) > 2\n\n\t\tfor {\n\t\t\tif debugAsserts && canRepeat && offset1 == 0 {\n\t\t\t\tpanic(\"offset0 was 0\")\n\t\t\t}\n\n\t\t\tnextHash := hashLen(cv, hashLog, tableFastHashLen)\n\t\t\tnextHash2 := hashLen(cv>>8, hashLog, tableFastHashLen)\n\t\t\tcandidate := e.table[nextHash]\n\t\t\tcandidate2 := e.table[nextHash2]\n\t\t\trepIndex := s - offset1 + 2\n\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.markShardDirty(nextHash)\n\t\t\te.table[nextHash2] = tableEntry{offset: s + e.cur + 1, val: uint32(cv >> 8)}\n\t\t\te.markShardDirty(nextHash2)\n\n\t\t\tif canRepeat && repIndex >= 0 && load3232(src, repIndex) == uint32(cv>>16) {\n\t\t\t\t// Consider history as well.\n\t\t\t\tvar seq seq\n\t\t\t\tlength := 4 + e.matchlen(s+6, repIndex+4, src)\n\n\t\t\t\tseq.matchLen = uint32(length - zstdMinMatch)\n\n\t\t\t\t// We might be able to match backwards.\n\t\t\t\t// Extend as long as we can.\n\t\t\t\tstart := s + 2\n\t\t\t\t// We end the search early, so we don't risk 0 literals\n\t\t\t\t// and have to do special offset treatment.\n\t\t\t\tstartLimit := nextEmit + 1\n\n\t\t\t\tsMin := s - e.maxMatchOff\n\t\t\t\tif sMin < 0 {\n\t\t\t\t\tsMin = 0\n\t\t\t\t}\n\t\t\t\tfor repIndex > sMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch {\n\t\t\t\t\trepIndex--\n\t\t\t\t\tstart--\n\t\t\t\t\tseq.matchLen++\n\t\t\t\t}\n\t\t\t\taddLiterals(&seq, start)\n\n\t\t\t\t// rep 0\n\t\t\t\tseq.offset = 1\n\t\t\t\tif debugSequences {\n\t\t\t\t\tprintln(\"repeat sequence\", seq, \"next s:\", s)\n\t\t\t\t}\n\t\t\t\tblk.sequences = append(blk.sequences, seq)\n\t\t\t\ts += length + 2\n\t\t\t\tnextEmit = s\n\t\t\t\tif s >= sLimit {\n\t\t\t\t\tif debugEncoder {\n\t\t\t\t\t\tprintln(\"repeat ended\", s, length)\n\n\t\t\t\t\t}\n\t\t\t\t\tbreak encodeLoop\n\t\t\t\t}\n\t\t\t\tcv = load6432(src, s)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcoffset0 := s - (candidate.offset - e.cur)\n\t\t\tcoffset1 := s - (candidate2.offset - e.cur) + 1\n\t\t\tif coffset0 < e.maxMatchOff && uint32(cv) == candidate.val {\n\t\t\t\t// found a regular match\n\t\t\t\tt = candidate.offset - e.cur\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif coffset1 < e.maxMatchOff && uint32(cv>>8) == candidate2.val {\n\t\t\t\t// found a regular match\n\t\t\t\tt = candidate2.offset - e.cur\n\t\t\t\ts++\n\t\t\t\tif debugAsserts && s <= t {\n\t\t\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t\t\t}\n\t\t\t\tif debugAsserts && s-t > e.maxMatchOff {\n\t\t\t\t\tpanic(\"s - t >e.maxMatchOff\")\n\t\t\t\t}\n\t\t\t\tif debugAsserts && t < 0 {\n\t\t\t\t\tpanic(\"t<0\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ts += stepSize + ((s - nextEmit) >> (kSearchStrength - 1))\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t\t// A 4-byte match has been found. We'll later see if more than 4 bytes.\n\t\toffset2 = offset1\n\t\toffset1 = s - t\n\n\t\tif debugAsserts && s <= t {\n\t\t\tpanic(fmt.Sprintf(\"s (%d) <= t (%d)\", s, t))\n\t\t}\n\n\t\tif debugAsserts && canRepeat && int(offset1) > len(src) {\n\t\t\tpanic(\"invalid offset\")\n\t\t}\n\n\t\t// Extend the 4-byte match as long as possible.\n\t\tl := e.matchlen(s+4, t+4, src) + 4\n\n\t\t// Extend backwards\n\t\ttMin := s - e.maxMatchOff\n\t\tif tMin < 0 {\n\t\t\ttMin = 0\n\t\t}\n\t\tfor t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {\n\t\t\ts--\n\t\t\tt--\n\t\t\tl++\n\t\t}\n\n\t\t// Write our sequence.\n\t\tvar seq seq\n\t\tseq.litLen = uint32(s - nextEmit)\n\t\tseq.matchLen = uint32(l - zstdMinMatch)\n\t\tif seq.litLen > 0 {\n\t\t\tblk.literals = append(blk.literals, src[nextEmit:s]...)\n\t\t}\n\t\t// Don't use repeat offsets\n\t\tseq.offset = uint32(s-t) + 3\n\t\ts += l\n\t\tif debugSequences {\n\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t}\n\t\tblk.sequences = append(blk.sequences, seq)\n\t\tnextEmit = s\n\t\tif s >= sLimit {\n\t\t\tbreak encodeLoop\n\t\t}\n\t\tcv = load6432(src, s)\n\n\t\t// Check offset 2\n\t\tif o2 := s - offset2; canRepeat && load3232(src, o2) == uint32(cv) {\n\t\t\t// We have at least 4 byte match.\n\t\t\t// No need to check backwards. We come straight from a match\n\t\t\tl := 4 + e.matchlen(s+4, o2+4, src)\n\n\t\t\t// Store this, since we have it.\n\t\t\tnextHash := hashLen(cv, hashLog, tableFastHashLen)\n\t\t\te.table[nextHash] = tableEntry{offset: s + e.cur, val: uint32(cv)}\n\t\t\te.markShardDirty(nextHash)\n\t\t\tseq.matchLen = uint32(l) - zstdMinMatch\n\t\t\tseq.litLen = 0\n\t\t\t// Since litlen is always 0, this is offset 1.\n\t\t\tseq.offset = 1\n\t\t\ts += l\n\t\t\tnextEmit = s\n\t\t\tif debugSequences {\n\t\t\t\tprintln(\"sequence\", seq, \"next s:\", s)\n\t\t\t}\n\t\t\tblk.sequences = append(blk.sequences, seq)\n\n\t\t\t// Swap offset 1 and 2.\n\t\t\toffset1, offset2 = offset2, offset1\n\t\t\tif s >= sLimit {\n\t\t\t\tbreak encodeLoop\n\t\t\t}\n\t\t\t// Prepare next loop.\n\t\t\tcv = load6432(src, s)\n\t\t}\n\t}\n\n\tif int(nextEmit) < len(src) {\n\t\tblk.literals = append(blk.literals, src[nextEmit:]...)\n\t\tblk.extraLits = len(src) - int(nextEmit)\n\t}\n\tblk.recentOffsets[0] = uint32(offset1)\n\tblk.recentOffsets[1] = uint32(offset2)\n\tif debugEncoder {\n\t\tprintln(\"returning, recent offsets:\", blk.recentOffsets, \"extra literals:\", blk.extraLits)\n\t}\n}\n\n// ResetDict will reset and set a dictionary if not nil\nfunc (e *fastEncoder) Reset(d *dict, singleBlock bool) {\n\te.resetBase(d, singleBlock)\n\tif d != nil {\n\t\tpanic(\"fastEncoder: Reset with dict\")\n\t}\n}\n\n// ResetDict will reset and set a dictionary if not nil\nfunc (e *fastEncoderDict) Reset(d *dict, singleBlock bool) {\n\te.resetBase(d, singleBlock)\n\tif d == nil {\n\t\treturn\n\t}\n\n\t// Init or copy dict table\n\tif len(e.dictTable) != len(e.table) || d.id != e.lastDictID {\n\t\tif len(e.dictTable) != len(e.table) {\n\t\t\te.dictTable = make([]tableEntry, len(e.table))\n\t\t}\n\t\tif true {\n\t\t\tend := e.maxMatchOff + int32(len(d.content)) - 8\n\t\t\tfor i := e.maxMatchOff; i < end; i += 2 {\n\t\t\t\tconst hashLog = tableBits\n\n\t\t\t\tcv := load6432(d.content, i-e.maxMatchOff)\n\t\t\t\tnextHash := hashLen(cv, hashLog, tableFastHashLen)     // 0 -> 6\n\t\t\t\tnextHash1 := hashLen(cv>>8, hashLog, tableFastHashLen) // 1 -> 7\n\t\t\t\te.dictTable[nextHash] = tableEntry{\n\t\t\t\t\tval:    uint32(cv),\n\t\t\t\t\toffset: i,\n\t\t\t\t}\n\t\t\t\te.dictTable[nextHash1] = tableEntry{\n\t\t\t\t\tval:    uint32(cv >> 8),\n\t\t\t\t\toffset: i + 1,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\te.lastDictID = d.id\n\t\te.allDirty = true\n\t}\n\n\te.cur = e.maxMatchOff\n\tdirtyShardCnt := 0\n\tif !e.allDirty {\n\t\tfor i := range e.tableShardDirty {\n\t\t\tif e.tableShardDirty[i] {\n\t\t\t\tdirtyShardCnt++\n\t\t\t}\n\t\t}\n\t}\n\n\tconst shardCnt = tableShardCnt\n\tconst shardSize = tableShardSize\n\tif e.allDirty || dirtyShardCnt > shardCnt*4/6 {\n\t\t//copy(e.table[:], e.dictTable)\n\t\te.table = *(*[tableSize]tableEntry)(e.dictTable)\n\t\tfor i := range e.tableShardDirty {\n\t\t\te.tableShardDirty[i] = false\n\t\t}\n\t\te.allDirty = false\n\t\treturn\n\t}\n\tfor i := range e.tableShardDirty {\n\t\tif !e.tableShardDirty[i] {\n\t\t\tcontinue\n\t\t}\n\n\t\t//copy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize])\n\t\t*(*[shardSize]tableEntry)(e.table[i*shardSize:]) = *(*[shardSize]tableEntry)(e.dictTable[i*shardSize:])\n\t\te.tableShardDirty[i] = false\n\t}\n\te.allDirty = false\n}\n\nfunc (e *fastEncoderDict) markAllShardsDirty() {\n\te.allDirty = true\n}\n\nfunc (e *fastEncoderDict) markShardDirty(entryNum uint32) {\n\te.tableShardDirty[entryNum/tableShardSize] = true\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/encoder.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\trdebug \"runtime/debug\"\n\t\"sync\"\n\n\t\"github.com/klauspost/compress/zstd/internal/xxhash\"\n)\n\n// Encoder provides encoding to Zstandard.\n// An Encoder can be used for either compressing a stream via the\n// io.WriteCloser interface supported by the Encoder or as multiple independent\n// tasks via the EncodeAll function.\n// Smaller encodes are encouraged to use the EncodeAll function.\n// Use NewWriter to create a new instance.\ntype Encoder struct {\n\to        encoderOptions\n\tencoders chan encoder\n\tstate    encoderState\n\tinit     sync.Once\n}\n\ntype encoder interface {\n\tEncode(blk *blockEnc, src []byte)\n\tEncodeNoHist(blk *blockEnc, src []byte)\n\tBlock() *blockEnc\n\tCRC() *xxhash.Digest\n\tAppendCRC([]byte) []byte\n\tWindowSize(size int64) int32\n\tUseBlock(*blockEnc)\n\tReset(d *dict, singleBlock bool)\n}\n\ntype encoderState struct {\n\tw                io.Writer\n\tfilling          []byte\n\tcurrent          []byte\n\tprevious         []byte\n\tencoder          encoder\n\twriting          *blockEnc\n\terr              error\n\twriteErr         error\n\tnWritten         int64\n\tnInput           int64\n\tframeContentSize int64\n\theaderWritten    bool\n\teofWritten       bool\n\tfullFrameWritten bool\n\n\t// This waitgroup indicates an encode is running.\n\twg sync.WaitGroup\n\t// This waitgroup indicates we have a block encoding/writing.\n\twWg sync.WaitGroup\n}\n\n// NewWriter will create a new Zstandard encoder.\n// If the encoder will be used for encoding blocks a nil writer can be used.\nfunc NewWriter(w io.Writer, opts ...EOption) (*Encoder, error) {\n\tinitPredefined()\n\tvar e Encoder\n\te.o.setDefault()\n\tfor _, o := range opts {\n\t\terr := o(&e.o)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif w != nil {\n\t\te.Reset(w)\n\t}\n\treturn &e, nil\n}\n\nfunc (e *Encoder) initialize() {\n\tif e.o.concurrent == 0 {\n\t\te.o.setDefault()\n\t}\n\te.encoders = make(chan encoder, e.o.concurrent)\n\tfor i := 0; i < e.o.concurrent; i++ {\n\t\tenc := e.o.encoder()\n\t\te.encoders <- enc\n\t}\n}\n\n// Reset will re-initialize the writer and new writes will encode to the supplied writer\n// as a new, independent stream.\nfunc (e *Encoder) Reset(w io.Writer) {\n\ts := &e.state\n\ts.wg.Wait()\n\ts.wWg.Wait()\n\tif cap(s.filling) == 0 {\n\t\ts.filling = make([]byte, 0, e.o.blockSize)\n\t}\n\tif e.o.concurrent > 1 {\n\t\tif cap(s.current) == 0 {\n\t\t\ts.current = make([]byte, 0, e.o.blockSize)\n\t\t}\n\t\tif cap(s.previous) == 0 {\n\t\t\ts.previous = make([]byte, 0, e.o.blockSize)\n\t\t}\n\t\ts.current = s.current[:0]\n\t\ts.previous = s.previous[:0]\n\t\tif s.writing == nil {\n\t\t\ts.writing = &blockEnc{lowMem: e.o.lowMem}\n\t\t\ts.writing.init()\n\t\t}\n\t\ts.writing.initNewEncode()\n\t}\n\tif s.encoder == nil {\n\t\ts.encoder = e.o.encoder()\n\t}\n\ts.filling = s.filling[:0]\n\ts.encoder.Reset(e.o.dict, false)\n\ts.headerWritten = false\n\ts.eofWritten = false\n\ts.fullFrameWritten = false\n\ts.w = w\n\ts.err = nil\n\ts.nWritten = 0\n\ts.nInput = 0\n\ts.writeErr = nil\n\ts.frameContentSize = 0\n}\n\n// ResetContentSize will reset and set a content size for the next stream.\n// If the bytes written does not match the size given an error will be returned\n// when calling Close().\n// This is removed when Reset is called.\n// Sizes <= 0 results in no content size set.\nfunc (e *Encoder) ResetContentSize(w io.Writer, size int64) {\n\te.Reset(w)\n\tif size >= 0 {\n\t\te.state.frameContentSize = size\n\t}\n}\n\n// Write data to the encoder.\n// Input data will be buffered and as the buffer fills up\n// content will be compressed and written to the output.\n// When done writing, use Close to flush the remaining output\n// and write CRC if requested.\nfunc (e *Encoder) Write(p []byte) (n int, err error) {\n\ts := &e.state\n\tfor len(p) > 0 {\n\t\tif len(p)+len(s.filling) < e.o.blockSize {\n\t\t\tif e.o.crc {\n\t\t\t\t_, _ = s.encoder.CRC().Write(p)\n\t\t\t}\n\t\t\ts.filling = append(s.filling, p...)\n\t\t\treturn n + len(p), nil\n\t\t}\n\t\tadd := p\n\t\tif len(p)+len(s.filling) > e.o.blockSize {\n\t\t\tadd = add[:e.o.blockSize-len(s.filling)]\n\t\t}\n\t\tif e.o.crc {\n\t\t\t_, _ = s.encoder.CRC().Write(add)\n\t\t}\n\t\ts.filling = append(s.filling, add...)\n\t\tp = p[len(add):]\n\t\tn += len(add)\n\t\tif len(s.filling) < e.o.blockSize {\n\t\t\treturn n, nil\n\t\t}\n\t\terr := e.nextBlock(false)\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tif debugAsserts && len(s.filling) > 0 {\n\t\t\tpanic(len(s.filling))\n\t\t}\n\t}\n\treturn n, nil\n}\n\n// nextBlock will synchronize and start compressing input in e.state.filling.\n// If an error has occurred during encoding it will be returned.\nfunc (e *Encoder) nextBlock(final bool) error {\n\ts := &e.state\n\t// Wait for current block.\n\ts.wg.Wait()\n\tif s.err != nil {\n\t\treturn s.err\n\t}\n\tif len(s.filling) > e.o.blockSize {\n\t\treturn fmt.Errorf(\"block > maxStoreBlockSize\")\n\t}\n\tif !s.headerWritten {\n\t\t// If we have a single block encode, do a sync compression.\n\t\tif final && len(s.filling) == 0 && !e.o.fullZero {\n\t\t\ts.headerWritten = true\n\t\t\ts.fullFrameWritten = true\n\t\t\ts.eofWritten = true\n\t\t\treturn nil\n\t\t}\n\t\tif final && len(s.filling) > 0 {\n\t\t\ts.current = e.EncodeAll(s.filling, s.current[:0])\n\t\t\tvar n2 int\n\t\t\tn2, s.err = s.w.Write(s.current)\n\t\t\tif s.err != nil {\n\t\t\t\treturn s.err\n\t\t\t}\n\t\t\ts.nWritten += int64(n2)\n\t\t\ts.nInput += int64(len(s.filling))\n\t\t\ts.current = s.current[:0]\n\t\t\ts.filling = s.filling[:0]\n\t\t\ts.headerWritten = true\n\t\t\ts.fullFrameWritten = true\n\t\t\ts.eofWritten = true\n\t\t\treturn nil\n\t\t}\n\n\t\tvar tmp [maxHeaderSize]byte\n\t\tfh := frameHeader{\n\t\t\tContentSize:   uint64(s.frameContentSize),\n\t\t\tWindowSize:    uint32(s.encoder.WindowSize(s.frameContentSize)),\n\t\t\tSingleSegment: false,\n\t\t\tChecksum:      e.o.crc,\n\t\t\tDictID:        e.o.dict.ID(),\n\t\t}\n\n\t\tdst := fh.appendTo(tmp[:0])\n\t\ts.headerWritten = true\n\t\ts.wWg.Wait()\n\t\tvar n2 int\n\t\tn2, s.err = s.w.Write(dst)\n\t\tif s.err != nil {\n\t\t\treturn s.err\n\t\t}\n\t\ts.nWritten += int64(n2)\n\t}\n\tif s.eofWritten {\n\t\t// Ensure we only write it once.\n\t\tfinal = false\n\t}\n\n\tif len(s.filling) == 0 {\n\t\t// Final block, but no data.\n\t\tif final {\n\t\t\tenc := s.encoder\n\t\t\tblk := enc.Block()\n\t\t\tblk.reset(nil)\n\t\t\tblk.last = true\n\t\t\tblk.encodeRaw(nil)\n\t\t\ts.wWg.Wait()\n\t\t\t_, s.err = s.w.Write(blk.output)\n\t\t\ts.nWritten += int64(len(blk.output))\n\t\t\ts.eofWritten = true\n\t\t}\n\t\treturn s.err\n\t}\n\n\t// SYNC:\n\tif e.o.concurrent == 1 {\n\t\tsrc := s.filling\n\t\ts.nInput += int64(len(s.filling))\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding sync block,\", len(src), \"bytes, final:\", final)\n\t\t}\n\t\tenc := s.encoder\n\t\tblk := enc.Block()\n\t\tblk.reset(nil)\n\t\tenc.Encode(blk, src)\n\t\tblk.last = final\n\t\tif final {\n\t\t\ts.eofWritten = true\n\t\t}\n\n\t\ts.err = blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)\n\t\tif s.err != nil {\n\t\t\treturn s.err\n\t\t}\n\t\t_, s.err = s.w.Write(blk.output)\n\t\ts.nWritten += int64(len(blk.output))\n\t\ts.filling = s.filling[:0]\n\t\treturn s.err\n\t}\n\n\t// Move blocks forward.\n\ts.filling, s.current, s.previous = s.previous[:0], s.filling, s.current\n\ts.nInput += int64(len(s.current))\n\ts.wg.Add(1)\n\tgo func(src []byte) {\n\t\tif debugEncoder {\n\t\t\tprintln(\"Adding block,\", len(src), \"bytes, final:\", final)\n\t\t}\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\ts.err = fmt.Errorf(\"panic while encoding: %v\", r)\n\t\t\t\trdebug.PrintStack()\n\t\t\t}\n\t\t\ts.wg.Done()\n\t\t}()\n\t\tenc := s.encoder\n\t\tblk := enc.Block()\n\t\tenc.Encode(blk, src)\n\t\tblk.last = final\n\t\tif final {\n\t\t\ts.eofWritten = true\n\t\t}\n\t\t// Wait for pending writes.\n\t\ts.wWg.Wait()\n\t\tif s.writeErr != nil {\n\t\t\ts.err = s.writeErr\n\t\t\treturn\n\t\t}\n\t\t// Transfer encoders from previous write block.\n\t\tblk.swapEncoders(s.writing)\n\t\t// Transfer recent offsets to next.\n\t\tenc.UseBlock(s.writing)\n\t\ts.writing = blk\n\t\ts.wWg.Add(1)\n\t\tgo func() {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\ts.writeErr = fmt.Errorf(\"panic while encoding/writing: %v\", r)\n\t\t\t\t\trdebug.PrintStack()\n\t\t\t\t}\n\t\t\t\ts.wWg.Done()\n\t\t\t}()\n\t\t\ts.writeErr = blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)\n\t\t\tif s.writeErr != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t_, s.writeErr = s.w.Write(blk.output)\n\t\t\ts.nWritten += int64(len(blk.output))\n\t\t}()\n\t}(s.current)\n\treturn nil\n}\n\n// ReadFrom reads data from r until EOF or error.\n// The return value n is the number of bytes read.\n// Any error except io.EOF encountered during the read is also returned.\n//\n// The Copy function uses ReaderFrom if available.\nfunc (e *Encoder) ReadFrom(r io.Reader) (n int64, err error) {\n\tif debugEncoder {\n\t\tprintln(\"Using ReadFrom\")\n\t}\n\n\t// Flush any current writes.\n\tif len(e.state.filling) > 0 {\n\t\tif err := e.nextBlock(false); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t}\n\te.state.filling = e.state.filling[:e.o.blockSize]\n\tsrc := e.state.filling\n\tfor {\n\t\tn2, err := r.Read(src)\n\t\tif e.o.crc {\n\t\t\t_, _ = e.state.encoder.CRC().Write(src[:n2])\n\t\t}\n\t\t// src is now the unfilled part...\n\t\tsrc = src[n2:]\n\t\tn += int64(n2)\n\t\tswitch err {\n\t\tcase io.EOF:\n\t\t\te.state.filling = e.state.filling[:len(e.state.filling)-len(src)]\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"ReadFrom: got EOF final block:\", len(e.state.filling))\n\t\t\t}\n\t\t\treturn n, nil\n\t\tcase nil:\n\t\tdefault:\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"ReadFrom: got error:\", err)\n\t\t\t}\n\t\t\te.state.err = err\n\t\t\treturn n, err\n\t\t}\n\t\tif len(src) > 0 {\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"ReadFrom: got space left in source:\", len(src))\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\terr = e.nextBlock(false)\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\te.state.filling = e.state.filling[:e.o.blockSize]\n\t\tsrc = e.state.filling\n\t}\n}\n\n// Flush will send the currently written data to output\n// and block until everything has been written.\n// This should only be used on rare occasions where pushing the currently queued data is critical.\nfunc (e *Encoder) Flush() error {\n\ts := &e.state\n\tif len(s.filling) > 0 {\n\t\terr := e.nextBlock(false)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\ts.wg.Wait()\n\ts.wWg.Wait()\n\tif s.err != nil {\n\t\treturn s.err\n\t}\n\treturn s.writeErr\n}\n\n// Close will flush the final output and close the stream.\n// The function will block until everything has been written.\n// The Encoder can still be re-used after calling this.\nfunc (e *Encoder) Close() error {\n\ts := &e.state\n\tif s.encoder == nil {\n\t\treturn nil\n\t}\n\terr := e.nextBlock(true)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif s.frameContentSize > 0 {\n\t\tif s.nInput != s.frameContentSize {\n\t\t\treturn fmt.Errorf(\"frame content size %d given, but %d bytes was written\", s.frameContentSize, s.nInput)\n\t\t}\n\t}\n\tif e.state.fullFrameWritten {\n\t\treturn s.err\n\t}\n\ts.wg.Wait()\n\ts.wWg.Wait()\n\n\tif s.err != nil {\n\t\treturn s.err\n\t}\n\tif s.writeErr != nil {\n\t\treturn s.writeErr\n\t}\n\n\t// Write CRC\n\tif e.o.crc && s.err == nil {\n\t\t// heap alloc.\n\t\tvar tmp [4]byte\n\t\t_, s.err = s.w.Write(s.encoder.AppendCRC(tmp[:0]))\n\t\ts.nWritten += 4\n\t}\n\n\t// Add padding with content from crypto/rand.Reader\n\tif s.err == nil && e.o.pad > 0 {\n\t\tadd := calcSkippableFrame(s.nWritten, int64(e.o.pad))\n\t\tframe, err := skippableFrame(s.filling[:0], add, rand.Reader)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, s.err = s.w.Write(frame)\n\t}\n\treturn s.err\n}\n\n// EncodeAll will encode all input in src and append it to dst.\n// This function can be called concurrently, but each call will only run on a single goroutine.\n// If empty input is given, nothing is returned, unless WithZeroFrames is specified.\n// Encoded blocks can be concatenated and the result will be the combined input stream.\n// Data compressed with EncodeAll can be decoded with the Decoder,\n// using either a stream or DecodeAll.\nfunc (e *Encoder) EncodeAll(src, dst []byte) []byte {\n\tif len(src) == 0 {\n\t\tif e.o.fullZero {\n\t\t\t// Add frame header.\n\t\t\tfh := frameHeader{\n\t\t\t\tContentSize:   0,\n\t\t\t\tWindowSize:    MinWindowSize,\n\t\t\t\tSingleSegment: true,\n\t\t\t\t// Adding a checksum would be a waste of space.\n\t\t\t\tChecksum: false,\n\t\t\t\tDictID:   0,\n\t\t\t}\n\t\t\tdst = fh.appendTo(dst)\n\n\t\t\t// Write raw block as last one only.\n\t\t\tvar blk blockHeader\n\t\t\tblk.setSize(0)\n\t\t\tblk.setType(blockTypeRaw)\n\t\t\tblk.setLast(true)\n\t\t\tdst = blk.appendTo(dst)\n\t\t}\n\t\treturn dst\n\t}\n\te.init.Do(e.initialize)\n\tenc := <-e.encoders\n\tdefer func() {\n\t\t// Release encoder reference to last block.\n\t\t// If a non-single block is needed the encoder will reset again.\n\t\te.encoders <- enc\n\t}()\n\t// Use single segments when above minimum window and below window size.\n\tsingle := len(src) <= e.o.windowSize && len(src) > MinWindowSize\n\tif e.o.single != nil {\n\t\tsingle = *e.o.single\n\t}\n\tfh := frameHeader{\n\t\tContentSize:   uint64(len(src)),\n\t\tWindowSize:    uint32(enc.WindowSize(int64(len(src)))),\n\t\tSingleSegment: single,\n\t\tChecksum:      e.o.crc,\n\t\tDictID:        e.o.dict.ID(),\n\t}\n\n\t// If less than 1MB, allocate a buffer up front.\n\tif len(dst) == 0 && cap(dst) == 0 && len(src) < 1<<20 && !e.o.lowMem {\n\t\tdst = make([]byte, 0, len(src))\n\t}\n\tdst = fh.appendTo(dst)\n\n\t// If we can do everything in one block, prefer that.\n\tif len(src) <= e.o.blockSize {\n\t\tenc.Reset(e.o.dict, true)\n\t\t// Slightly faster with no history and everything in one block.\n\t\tif e.o.crc {\n\t\t\t_, _ = enc.CRC().Write(src)\n\t\t}\n\t\tblk := enc.Block()\n\t\tblk.last = true\n\t\tif e.o.dict == nil {\n\t\t\tenc.EncodeNoHist(blk, src)\n\t\t} else {\n\t\t\tenc.Encode(blk, src)\n\t\t}\n\n\t\t// If we got the exact same number of literals as input,\n\t\t// assume the literals cannot be compressed.\n\t\toldout := blk.output\n\t\t// Output directly to dst\n\t\tblk.output = dst\n\n\t\terr := blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tdst = blk.output\n\t\tblk.output = oldout\n\t} else {\n\t\tenc.Reset(e.o.dict, false)\n\t\tblk := enc.Block()\n\t\tfor len(src) > 0 {\n\t\t\ttodo := src\n\t\t\tif len(todo) > e.o.blockSize {\n\t\t\t\ttodo = todo[:e.o.blockSize]\n\t\t\t}\n\t\t\tsrc = src[len(todo):]\n\t\t\tif e.o.crc {\n\t\t\t\t_, _ = enc.CRC().Write(todo)\n\t\t\t}\n\t\t\tblk.pushOffsets()\n\t\t\tenc.Encode(blk, todo)\n\t\t\tif len(src) == 0 {\n\t\t\t\tblk.last = true\n\t\t\t}\n\t\t\terr := blk.encode(todo, e.o.noEntropy, !e.o.allLitEntropy)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tdst = append(dst, blk.output...)\n\t\t\tblk.reset(nil)\n\t\t}\n\t}\n\tif e.o.crc {\n\t\tdst = enc.AppendCRC(dst)\n\t}\n\t// Add padding with content from crypto/rand.Reader\n\tif e.o.pad > 0 {\n\t\tadd := calcSkippableFrame(int64(len(dst)), int64(e.o.pad))\n\t\tvar err error\n\t\tdst, err = skippableFrame(dst, add, rand.Reader)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\treturn dst\n}\n\n// MaxEncodedSize returns the expected maximum\n// size of an encoded block or stream.\nfunc (e *Encoder) MaxEncodedSize(size int) int {\n\tframeHeader := 4 + 2 // magic + frame header & window descriptor\n\tif e.o.dict != nil {\n\t\tframeHeader += 4\n\t}\n\t// Frame content size:\n\tif size < 256 {\n\t\tframeHeader++\n\t} else if size < 65536+256 {\n\t\tframeHeader += 2\n\t} else if size < math.MaxInt32 {\n\t\tframeHeader += 4\n\t} else {\n\t\tframeHeader += 8\n\t}\n\t// Final crc\n\tif e.o.crc {\n\t\tframeHeader += 4\n\t}\n\n\t// Max overhead is 3 bytes/block.\n\t// There cannot be 0 blocks.\n\tblocks := (size + e.o.blockSize) / e.o.blockSize\n\n\t// Combine, add padding.\n\tmaxSz := frameHeader + 3*blocks + size\n\tif e.o.pad > 1 {\n\t\tmaxSz += calcSkippableFrame(int64(maxSz), int64(e.o.pad))\n\t}\n\treturn maxSz\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/encoder_options.go",
    "content": "package zstd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/bits\"\n\t\"runtime\"\n\t\"strings\"\n)\n\n// EOption is an option for creating a encoder.\ntype EOption func(*encoderOptions) error\n\n// options retains accumulated state of multiple options.\ntype encoderOptions struct {\n\tconcurrent      int\n\tlevel           EncoderLevel\n\tsingle          *bool\n\tpad             int\n\tblockSize       int\n\twindowSize      int\n\tcrc             bool\n\tfullZero        bool\n\tnoEntropy       bool\n\tallLitEntropy   bool\n\tcustomWindow    bool\n\tcustomALEntropy bool\n\tcustomBlockSize bool\n\tlowMem          bool\n\tdict            *dict\n}\n\nfunc (o *encoderOptions) setDefault() {\n\t*o = encoderOptions{\n\t\tconcurrent:    runtime.GOMAXPROCS(0),\n\t\tcrc:           true,\n\t\tsingle:        nil,\n\t\tblockSize:     maxCompressedBlockSize,\n\t\twindowSize:    8 << 20,\n\t\tlevel:         SpeedDefault,\n\t\tallLitEntropy: false,\n\t\tlowMem:        false,\n\t}\n}\n\n// encoder returns an encoder with the selected options.\nfunc (o encoderOptions) encoder() encoder {\n\tswitch o.level {\n\tcase SpeedFastest:\n\t\tif o.dict != nil {\n\t\t\treturn &fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}}\n\t\t}\n\t\treturn &fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}\n\n\tcase SpeedDefault:\n\t\tif o.dict != nil {\n\t\t\treturn &doubleFastEncoderDict{fastEncoderDict: fastEncoderDict{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}}}\n\t\t}\n\t\treturn &doubleFastEncoder{fastEncoder: fastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}}\n\tcase SpeedBetterCompression:\n\t\tif o.dict != nil {\n\t\t\treturn &betterFastEncoderDict{betterFastEncoder: betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}}\n\t\t}\n\t\treturn &betterFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}\n\tcase SpeedBestCompression:\n\t\treturn &bestFastEncoder{fastBase: fastBase{maxMatchOff: int32(o.windowSize), bufferReset: math.MaxInt32 - int32(o.windowSize*2), lowMem: o.lowMem}}\n\t}\n\tpanic(\"unknown compression level\")\n}\n\n// WithEncoderCRC will add CRC value to output.\n// Output will be 4 bytes larger.\nfunc WithEncoderCRC(b bool) EOption {\n\treturn func(o *encoderOptions) error { o.crc = b; return nil }\n}\n\n// WithEncoderConcurrency will set the concurrency,\n// meaning the maximum number of encoders to run concurrently.\n// The value supplied must be at least 1.\n// For streams, setting a value of 1 will disable async compression.\n// By default this will be set to GOMAXPROCS.\nfunc WithEncoderConcurrency(n int) EOption {\n\treturn func(o *encoderOptions) error {\n\t\tif n <= 0 {\n\t\t\treturn fmt.Errorf(\"concurrency must be at least 1\")\n\t\t}\n\t\to.concurrent = n\n\t\treturn nil\n\t}\n}\n\n// WithWindowSize will set the maximum allowed back-reference distance.\n// The value must be a power of two between MinWindowSize and MaxWindowSize.\n// A larger value will enable better compression but allocate more memory and,\n// for above-default values, take considerably longer.\n// The default value is determined by the compression level.\nfunc WithWindowSize(n int) EOption {\n\treturn func(o *encoderOptions) error {\n\t\tswitch {\n\t\tcase n < MinWindowSize:\n\t\t\treturn fmt.Errorf(\"window size must be at least %d\", MinWindowSize)\n\t\tcase n > MaxWindowSize:\n\t\t\treturn fmt.Errorf(\"window size must be at most %d\", MaxWindowSize)\n\t\tcase (n & (n - 1)) != 0:\n\t\t\treturn errors.New(\"window size must be a power of 2\")\n\t\t}\n\n\t\to.windowSize = n\n\t\to.customWindow = true\n\t\tif o.blockSize > o.windowSize {\n\t\t\to.blockSize = o.windowSize\n\t\t\to.customBlockSize = true\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// WithEncoderPadding will add padding to all output so the size will be a multiple of n.\n// This can be used to obfuscate the exact output size or make blocks of a certain size.\n// The contents will be a skippable frame, so it will be invisible by the decoder.\n// n must be > 0 and <= 1GB, 1<<30 bytes.\n// The padded area will be filled with data from crypto/rand.Reader.\n// If `EncodeAll` is used with data already in the destination, the total size will be multiple of this.\nfunc WithEncoderPadding(n int) EOption {\n\treturn func(o *encoderOptions) error {\n\t\tif n <= 0 {\n\t\t\treturn fmt.Errorf(\"padding must be at least 1\")\n\t\t}\n\t\t// No need to waste our time.\n\t\tif n == 1 {\n\t\t\tn = 0\n\t\t}\n\t\tif n > 1<<30 {\n\t\t\treturn fmt.Errorf(\"padding must less than 1GB (1<<30 bytes) \")\n\t\t}\n\t\to.pad = n\n\t\treturn nil\n\t}\n}\n\n// EncoderLevel predefines encoder compression levels.\n// Only use the constants made available, since the actual mapping\n// of these values are very likely to change and your compression could change\n// unpredictably when upgrading the library.\ntype EncoderLevel int\n\nconst (\n\tspeedNotSet EncoderLevel = iota\n\n\t// SpeedFastest will choose the fastest reasonable compression.\n\t// This is roughly equivalent to the fastest Zstandard mode.\n\tSpeedFastest\n\n\t// SpeedDefault is the default \"pretty fast\" compression option.\n\t// This is roughly equivalent to the default Zstandard mode (level 3).\n\tSpeedDefault\n\n\t// SpeedBetterCompression will yield better compression than the default.\n\t// Currently it is about zstd level 7-8 with ~ 2x-3x the default CPU usage.\n\t// By using this, notice that CPU usage may go up in the future.\n\tSpeedBetterCompression\n\n\t// SpeedBestCompression will choose the best available compression option.\n\t// This will offer the best compression no matter the CPU cost.\n\tSpeedBestCompression\n\n\t// speedLast should be kept as the last actual compression option.\n\t// The is not for external usage, but is used to keep track of the valid options.\n\tspeedLast\n)\n\n// EncoderLevelFromString will convert a string representation of an encoding level back\n// to a compression level. The compare is not case sensitive.\n// If the string wasn't recognized, (false, SpeedDefault) will be returned.\nfunc EncoderLevelFromString(s string) (bool, EncoderLevel) {\n\tfor l := speedNotSet + 1; l < speedLast; l++ {\n\t\tif strings.EqualFold(s, l.String()) {\n\t\t\treturn true, l\n\t\t}\n\t}\n\treturn false, SpeedDefault\n}\n\n// EncoderLevelFromZstd will return an encoder level that closest matches the compression\n// ratio of a specific zstd compression level.\n// Many input values will provide the same compression level.\nfunc EncoderLevelFromZstd(level int) EncoderLevel {\n\tswitch {\n\tcase level < 3:\n\t\treturn SpeedFastest\n\tcase level >= 3 && level < 6:\n\t\treturn SpeedDefault\n\tcase level >= 6 && level < 10:\n\t\treturn SpeedBetterCompression\n\tdefault:\n\t\treturn SpeedBestCompression\n\t}\n}\n\n// String provides a string representation of the compression level.\nfunc (e EncoderLevel) String() string {\n\tswitch e {\n\tcase SpeedFastest:\n\t\treturn \"fastest\"\n\tcase SpeedDefault:\n\t\treturn \"default\"\n\tcase SpeedBetterCompression:\n\t\treturn \"better\"\n\tcase SpeedBestCompression:\n\t\treturn \"best\"\n\tdefault:\n\t\treturn \"invalid\"\n\t}\n}\n\n// WithEncoderLevel specifies a predefined compression level.\nfunc WithEncoderLevel(l EncoderLevel) EOption {\n\treturn func(o *encoderOptions) error {\n\t\tswitch {\n\t\tcase l <= speedNotSet || l >= speedLast:\n\t\t\treturn fmt.Errorf(\"unknown encoder level\")\n\t\t}\n\t\to.level = l\n\t\tif !o.customWindow {\n\t\t\tswitch o.level {\n\t\t\tcase SpeedFastest:\n\t\t\t\to.windowSize = 4 << 20\n\t\t\t\tif !o.customBlockSize {\n\t\t\t\t\to.blockSize = 1 << 16\n\t\t\t\t}\n\t\t\tcase SpeedDefault:\n\t\t\t\to.windowSize = 8 << 20\n\t\t\tcase SpeedBetterCompression:\n\t\t\t\to.windowSize = 16 << 20\n\t\t\tcase SpeedBestCompression:\n\t\t\t\to.windowSize = 32 << 20\n\t\t\t}\n\t\t}\n\t\tif !o.customALEntropy {\n\t\t\to.allLitEntropy = l > SpeedDefault\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\n// WithZeroFrames will encode 0 length input as full frames.\n// This can be needed for compatibility with zstandard usage,\n// but is not needed for this package.\nfunc WithZeroFrames(b bool) EOption {\n\treturn func(o *encoderOptions) error {\n\t\to.fullZero = b\n\t\treturn nil\n\t}\n}\n\n// WithAllLitEntropyCompression will apply entropy compression if no matches are found.\n// Disabling this will skip incompressible data faster, but in cases with no matches but\n// skewed character distribution compression is lost.\n// Default value depends on the compression level selected.\nfunc WithAllLitEntropyCompression(b bool) EOption {\n\treturn func(o *encoderOptions) error {\n\t\to.customALEntropy = true\n\t\to.allLitEntropy = b\n\t\treturn nil\n\t}\n}\n\n// WithNoEntropyCompression will always skip entropy compression of literals.\n// This can be useful if content has matches, but unlikely to benefit from entropy\n// compression. Usually the slight speed improvement is not worth enabling this.\nfunc WithNoEntropyCompression(b bool) EOption {\n\treturn func(o *encoderOptions) error {\n\t\to.noEntropy = b\n\t\treturn nil\n\t}\n}\n\n// WithSingleSegment will set the \"single segment\" flag when EncodeAll is used.\n// If this flag is set, data must be regenerated within a single continuous memory segment.\n// In this case, Window_Descriptor byte is skipped, but Frame_Content_Size is necessarily present.\n// As a consequence, the decoder must allocate a memory segment of size equal or larger than size of your content.\n// In order to preserve the decoder from unreasonable memory requirements,\n// a decoder is allowed to reject a compressed frame which requests a memory size beyond decoder's authorized range.\n// For broader compatibility, decoders are recommended to support memory sizes of at least 8 MB.\n// This is only a recommendation, each decoder is free to support higher or lower limits, depending on local limitations.\n// If this is not specified, block encodes will automatically choose this based on the input size and the window size.\n// This setting has no effect on streamed encodes.\nfunc WithSingleSegment(b bool) EOption {\n\treturn func(o *encoderOptions) error {\n\t\to.single = &b\n\t\treturn nil\n\t}\n}\n\n// WithLowerEncoderMem will trade in some memory cases trade less memory usage for\n// slower encoding speed.\n// This will not change the window size which is the primary function for reducing\n// memory usage. See WithWindowSize.\nfunc WithLowerEncoderMem(b bool) EOption {\n\treturn func(o *encoderOptions) error {\n\t\to.lowMem = b\n\t\treturn nil\n\t}\n}\n\n// WithEncoderDict allows to register a dictionary that will be used for the encode.\n//\n// The slice dict must be in the [dictionary format] produced by\n// \"zstd --train\" from the Zstandard reference implementation.\n//\n// The encoder *may* choose to use no dictionary instead for certain payloads.\n//\n// [dictionary format]: https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary-format\nfunc WithEncoderDict(dict []byte) EOption {\n\treturn func(o *encoderOptions) error {\n\t\td, err := loadDict(dict)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\to.dict = d\n\t\treturn nil\n\t}\n}\n\n// WithEncoderDictRaw registers a dictionary that may be used by the encoder.\n//\n// The slice content may contain arbitrary data. It will be used as an initial\n// history.\nfunc WithEncoderDictRaw(id uint32, content []byte) EOption {\n\treturn func(o *encoderOptions) error {\n\t\tif bits.UintSize > 32 && uint(len(content)) > dictMaxLength {\n\t\t\treturn fmt.Errorf(\"dictionary of size %d > 2GiB too large\", len(content))\n\t\t}\n\t\to.dict = &dict{id: id, content: content, offsets: [3]int{1, 4, 8}}\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/framedec.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/klauspost/compress/zstd/internal/xxhash\"\n)\n\ntype frameDec struct {\n\to   decoderOptions\n\tcrc *xxhash.Digest\n\n\tWindowSize uint64\n\n\t// Frame history passed between blocks\n\thistory history\n\n\trawInput byteBuffer\n\n\t// Byte buffer that can be reused for small input blocks.\n\tbBuf byteBuf\n\n\tFrameContentSize uint64\n\n\tDictionaryID  uint32\n\tHasCheckSum   bool\n\tSingleSegment bool\n}\n\nconst (\n\t// MinWindowSize is the minimum Window Size, which is 1 KB.\n\tMinWindowSize = 1 << 10\n\n\t// MaxWindowSize is the maximum encoder window size\n\t// and the default decoder maximum window size.\n\tMaxWindowSize = 1 << 29\n)\n\nconst (\n\tframeMagic          = \"\\x28\\xb5\\x2f\\xfd\"\n\tskippableFrameMagic = \"\\x2a\\x4d\\x18\"\n)\n\nfunc newFrameDec(o decoderOptions) *frameDec {\n\tif o.maxWindowSize > o.maxDecodedSize {\n\t\to.maxWindowSize = o.maxDecodedSize\n\t}\n\td := frameDec{\n\t\to: o,\n\t}\n\treturn &d\n}\n\n// reset will read the frame header and prepare for block decoding.\n// If nothing can be read from the input, io.EOF will be returned.\n// Any other error indicated that the stream contained data, but\n// there was a problem.\nfunc (d *frameDec) reset(br byteBuffer) error {\n\td.HasCheckSum = false\n\td.WindowSize = 0\n\tvar signature [4]byte\n\tfor {\n\t\tvar err error\n\t\t// Check if we can read more...\n\t\tb, err := br.readSmall(1)\n\t\tswitch err {\n\t\tcase io.EOF, io.ErrUnexpectedEOF:\n\t\t\treturn io.EOF\n\t\tcase nil:\n\t\t\tsignature[0] = b[0]\n\t\tdefault:\n\t\t\treturn err\n\t\t}\n\t\t// Read the rest, don't allow io.ErrUnexpectedEOF\n\t\tb, err = br.readSmall(3)\n\t\tswitch err {\n\t\tcase io.EOF:\n\t\t\treturn io.EOF\n\t\tcase nil:\n\t\t\tcopy(signature[1:], b)\n\t\tdefault:\n\t\t\treturn err\n\t\t}\n\n\t\tif string(signature[1:4]) != skippableFrameMagic || signature[0]&0xf0 != 0x50 {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"Not skippable\", hex.EncodeToString(signature[:]), hex.EncodeToString([]byte(skippableFrameMagic)))\n\t\t\t}\n\t\t\t// Break if not skippable frame.\n\t\t\tbreak\n\t\t}\n\t\t// Read size to skip\n\t\tb, err = br.readSmall(4)\n\t\tif err != nil {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"Reading Frame Size\", err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\tn := uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)\n\t\tprintln(\"Skipping frame with\", n, \"bytes.\")\n\t\terr = br.skipN(int64(n))\n\t\tif err != nil {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"Reading discarded frame\", err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\tif string(signature[:]) != frameMagic {\n\t\tif debugDecoder {\n\t\t\tprintln(\"Got magic numbers: \", signature, \"want:\", []byte(frameMagic))\n\t\t}\n\t\treturn ErrMagicMismatch\n\t}\n\n\t// Read Frame_Header_Descriptor\n\tfhd, err := br.readByte()\n\tif err != nil {\n\t\tif debugDecoder {\n\t\t\tprintln(\"Reading Frame_Header_Descriptor\", err)\n\t\t}\n\t\treturn err\n\t}\n\td.SingleSegment = fhd&(1<<5) != 0\n\n\tif fhd&(1<<3) != 0 {\n\t\treturn errors.New(\"reserved bit set on frame header\")\n\t}\n\n\t// Read Window_Descriptor\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor\n\td.WindowSize = 0\n\tif !d.SingleSegment {\n\t\twd, err := br.readByte()\n\t\tif err != nil {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"Reading Window_Descriptor\", err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\tprintf(\"raw: %x, mantissa: %d, exponent: %d\\n\", wd, wd&7, wd>>3)\n\t\twindowLog := 10 + (wd >> 3)\n\t\twindowBase := uint64(1) << windowLog\n\t\twindowAdd := (windowBase / 8) * uint64(wd&0x7)\n\t\td.WindowSize = windowBase + windowAdd\n\t}\n\n\t// Read Dictionary_ID\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#dictionary_id\n\td.DictionaryID = 0\n\tif size := fhd & 3; size != 0 {\n\t\tif size == 3 {\n\t\t\tsize = 4\n\t\t}\n\n\t\tb, err := br.readSmall(int(size))\n\t\tif err != nil {\n\t\t\tprintln(\"Reading Dictionary_ID\", err)\n\t\t\treturn err\n\t\t}\n\t\tvar id uint32\n\t\tswitch len(b) {\n\t\tcase 1:\n\t\t\tid = uint32(b[0])\n\t\tcase 2:\n\t\t\tid = uint32(b[0]) | (uint32(b[1]) << 8)\n\t\tcase 4:\n\t\t\tid = uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)\n\t\t}\n\t\tif debugDecoder {\n\t\t\tprintln(\"Dict size\", size, \"ID:\", id)\n\t\t}\n\t\td.DictionaryID = id\n\t}\n\n\t// Read Frame_Content_Size\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#frame_content_size\n\tvar fcsSize int\n\tv := fhd >> 6\n\tswitch v {\n\tcase 0:\n\t\tif d.SingleSegment {\n\t\t\tfcsSize = 1\n\t\t}\n\tdefault:\n\t\tfcsSize = 1 << v\n\t}\n\td.FrameContentSize = fcsUnknown\n\tif fcsSize > 0 {\n\t\tb, err := br.readSmall(fcsSize)\n\t\tif err != nil {\n\t\t\tprintln(\"Reading Frame content\", err)\n\t\t\treturn err\n\t\t}\n\t\tswitch len(b) {\n\t\tcase 1:\n\t\t\td.FrameContentSize = uint64(b[0])\n\t\tcase 2:\n\t\t\t// When FCS_Field_Size is 2, the offset of 256 is added.\n\t\t\td.FrameContentSize = uint64(b[0]) | (uint64(b[1]) << 8) + 256\n\t\tcase 4:\n\t\t\td.FrameContentSize = uint64(b[0]) | (uint64(b[1]) << 8) | (uint64(b[2]) << 16) | (uint64(b[3]) << 24)\n\t\tcase 8:\n\t\t\td1 := uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24)\n\t\t\td2 := uint32(b[4]) | (uint32(b[5]) << 8) | (uint32(b[6]) << 16) | (uint32(b[7]) << 24)\n\t\t\td.FrameContentSize = uint64(d1) | (uint64(d2) << 32)\n\t\t}\n\t\tif debugDecoder {\n\t\t\tprintln(\"Read FCS:\", d.FrameContentSize)\n\t\t}\n\t}\n\n\t// Move this to shared.\n\td.HasCheckSum = fhd&(1<<2) != 0\n\tif d.HasCheckSum {\n\t\tif d.crc == nil {\n\t\t\td.crc = xxhash.New()\n\t\t}\n\t\td.crc.Reset()\n\t}\n\n\tif d.WindowSize > d.o.maxWindowSize {\n\t\tif debugDecoder {\n\t\t\tprintf(\"window size %d > max %d\\n\", d.WindowSize, d.o.maxWindowSize)\n\t\t}\n\t\treturn ErrWindowSizeExceeded\n\t}\n\n\tif d.WindowSize == 0 && d.SingleSegment {\n\t\t// We may not need window in this case.\n\t\td.WindowSize = d.FrameContentSize\n\t\tif d.WindowSize < MinWindowSize {\n\t\t\td.WindowSize = MinWindowSize\n\t\t}\n\t\tif d.WindowSize > d.o.maxDecodedSize {\n\t\t\tif debugDecoder {\n\t\t\t\tprintf(\"window size %d > max %d\\n\", d.WindowSize, d.o.maxWindowSize)\n\t\t\t}\n\t\t\treturn ErrDecoderSizeExceeded\n\t\t}\n\t}\n\n\t// The minimum Window_Size is 1 KB.\n\tif d.WindowSize < MinWindowSize {\n\t\tif debugDecoder {\n\t\t\tprintln(\"got window size: \", d.WindowSize)\n\t\t}\n\t\treturn ErrWindowSizeTooSmall\n\t}\n\td.history.windowSize = int(d.WindowSize)\n\tif !d.o.lowMem || d.history.windowSize < maxBlockSize {\n\t\t// Alloc 2x window size if not low-mem, or window size below 2MB.\n\t\td.history.allocFrameBuffer = d.history.windowSize * 2\n\t} else {\n\t\tif d.o.lowMem {\n\t\t\t// Alloc with 1MB extra.\n\t\t\td.history.allocFrameBuffer = d.history.windowSize + maxBlockSize/2\n\t\t} else {\n\t\t\t// Alloc with 2MB extra.\n\t\t\td.history.allocFrameBuffer = d.history.windowSize + maxBlockSize\n\t\t}\n\t}\n\n\tif debugDecoder {\n\t\tprintln(\"Frame: Dict:\", d.DictionaryID, \"FrameContentSize:\", d.FrameContentSize, \"singleseg:\", d.SingleSegment, \"window:\", d.WindowSize, \"crc:\", d.HasCheckSum)\n\t}\n\n\t// history contains input - maybe we do something\n\td.rawInput = br\n\treturn nil\n}\n\n// next will start decoding the next block from stream.\nfunc (d *frameDec) next(block *blockDec) error {\n\tif debugDecoder {\n\t\tprintln(\"decoding new block\")\n\t}\n\terr := block.reset(d.rawInput, d.WindowSize)\n\tif err != nil {\n\t\tprintln(\"block error:\", err)\n\t\t// Signal the frame decoder we have a problem.\n\t\tblock.sendErr(err)\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// checkCRC will check the checksum, assuming the frame has one.\n// Will return ErrCRCMismatch if crc check failed, otherwise nil.\nfunc (d *frameDec) checkCRC() error {\n\t// We can overwrite upper tmp now\n\tbuf, err := d.rawInput.readSmall(4)\n\tif err != nil {\n\t\tprintln(\"CRC missing?\", err)\n\t\treturn err\n\t}\n\n\twant := binary.LittleEndian.Uint32(buf[:4])\n\tgot := uint32(d.crc.Sum64())\n\n\tif got != want {\n\t\tif debugDecoder {\n\t\t\tprintf(\"CRC check failed: got %08x, want %08x\\n\", got, want)\n\t\t}\n\t\treturn ErrCRCMismatch\n\t}\n\tif debugDecoder {\n\t\tprintf(\"CRC ok %08x\\n\", got)\n\t}\n\treturn nil\n}\n\n// consumeCRC skips over the checksum, assuming the frame has one.\nfunc (d *frameDec) consumeCRC() error {\n\t_, err := d.rawInput.readSmall(4)\n\tif err != nil {\n\t\tprintln(\"CRC missing?\", err)\n\t}\n\treturn err\n}\n\n// runDecoder will run the decoder for the remainder of the frame.\nfunc (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {\n\tsaved := d.history.b\n\n\t// We use the history for output to avoid copying it.\n\td.history.b = dst\n\td.history.ignoreBuffer = len(dst)\n\t// Store input length, so we only check new data.\n\tcrcStart := len(dst)\n\td.history.decoders.maxSyncLen = 0\n\tif d.o.limitToCap {\n\t\td.history.decoders.maxSyncLen = uint64(cap(dst) - len(dst))\n\t}\n\tif d.FrameContentSize != fcsUnknown {\n\t\tif !d.o.limitToCap || d.FrameContentSize+uint64(len(dst)) < d.history.decoders.maxSyncLen {\n\t\t\td.history.decoders.maxSyncLen = d.FrameContentSize + uint64(len(dst))\n\t\t}\n\t\tif d.history.decoders.maxSyncLen > d.o.maxDecodedSize {\n\t\t\tif debugDecoder {\n\t\t\t\tprintln(\"maxSyncLen:\", d.history.decoders.maxSyncLen, \"> maxDecodedSize:\", d.o.maxDecodedSize)\n\t\t\t}\n\t\t\treturn dst, ErrDecoderSizeExceeded\n\t\t}\n\t\tif debugDecoder {\n\t\t\tprintln(\"maxSyncLen:\", d.history.decoders.maxSyncLen)\n\t\t}\n\t\tif !d.o.limitToCap && uint64(cap(dst)) < d.history.decoders.maxSyncLen {\n\t\t\t// Alloc for output\n\t\t\tdst2 := make([]byte, len(dst), d.history.decoders.maxSyncLen+compressedBlockOverAlloc)\n\t\t\tcopy(dst2, dst)\n\t\t\tdst = dst2\n\t\t}\n\t}\n\tvar err error\n\tfor {\n\t\terr = dec.reset(d.rawInput, d.WindowSize)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\tif debugDecoder {\n\t\t\tprintln(\"next block:\", dec)\n\t\t}\n\t\terr = dec.decodeBuf(&d.history)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\tif uint64(len(d.history.b)-crcStart) > d.o.maxDecodedSize {\n\t\t\tprintln(\"runDecoder: maxDecodedSize exceeded\", uint64(len(d.history.b)-crcStart), \">\", d.o.maxDecodedSize)\n\t\t\terr = ErrDecoderSizeExceeded\n\t\t\tbreak\n\t\t}\n\t\tif d.o.limitToCap && len(d.history.b) > cap(dst) {\n\t\t\tprintln(\"runDecoder: cap exceeded\", uint64(len(d.history.b)), \">\", cap(dst))\n\t\t\terr = ErrDecoderSizeExceeded\n\t\t\tbreak\n\t\t}\n\t\tif uint64(len(d.history.b)-crcStart) > d.FrameContentSize {\n\t\t\tprintln(\"runDecoder: FrameContentSize exceeded\", uint64(len(d.history.b)-crcStart), \">\", d.FrameContentSize)\n\t\t\terr = ErrFrameSizeExceeded\n\t\t\tbreak\n\t\t}\n\t\tif dec.Last {\n\t\t\tbreak\n\t\t}\n\t\tif debugDecoder {\n\t\t\tprintln(\"runDecoder: FrameContentSize\", uint64(len(d.history.b)-crcStart), \"<=\", d.FrameContentSize)\n\t\t}\n\t}\n\tdst = d.history.b\n\tif err == nil {\n\t\tif d.FrameContentSize != fcsUnknown && uint64(len(d.history.b)-crcStart) != d.FrameContentSize {\n\t\t\terr = ErrFrameSizeMismatch\n\t\t} else if d.HasCheckSum {\n\t\t\tif d.o.ignoreChecksum {\n\t\t\t\terr = d.consumeCRC()\n\t\t\t} else {\n\t\t\t\td.crc.Write(dst[crcStart:])\n\t\t\t\terr = d.checkCRC()\n\t\t\t}\n\t\t}\n\t}\n\td.history.b = saved\n\treturn dst, err\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/frameenc.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"math/bits\"\n)\n\ntype frameHeader struct {\n\tContentSize   uint64\n\tWindowSize    uint32\n\tSingleSegment bool\n\tChecksum      bool\n\tDictID        uint32\n}\n\nconst maxHeaderSize = 14\n\nfunc (f frameHeader) appendTo(dst []byte) []byte {\n\tdst = append(dst, frameMagic...)\n\tvar fhd uint8\n\tif f.Checksum {\n\t\tfhd |= 1 << 2\n\t}\n\tif f.SingleSegment {\n\t\tfhd |= 1 << 5\n\t}\n\n\tvar dictIDContent []byte\n\tif f.DictID > 0 {\n\t\tvar tmp [4]byte\n\t\tif f.DictID < 256 {\n\t\t\tfhd |= 1\n\t\t\ttmp[0] = uint8(f.DictID)\n\t\t\tdictIDContent = tmp[:1]\n\t\t} else if f.DictID < 1<<16 {\n\t\t\tfhd |= 2\n\t\t\tbinary.LittleEndian.PutUint16(tmp[:2], uint16(f.DictID))\n\t\t\tdictIDContent = tmp[:2]\n\t\t} else {\n\t\t\tfhd |= 3\n\t\t\tbinary.LittleEndian.PutUint32(tmp[:4], f.DictID)\n\t\t\tdictIDContent = tmp[:4]\n\t\t}\n\t}\n\tvar fcs uint8\n\tif f.ContentSize >= 256 {\n\t\tfcs++\n\t}\n\tif f.ContentSize >= 65536+256 {\n\t\tfcs++\n\t}\n\tif f.ContentSize >= 0xffffffff {\n\t\tfcs++\n\t}\n\n\tfhd |= fcs << 6\n\n\tdst = append(dst, fhd)\n\tif !f.SingleSegment {\n\t\tconst winLogMin = 10\n\t\twindowLog := (bits.Len32(f.WindowSize-1) - winLogMin) << 3\n\t\tdst = append(dst, uint8(windowLog))\n\t}\n\tif f.DictID > 0 {\n\t\tdst = append(dst, dictIDContent...)\n\t}\n\tswitch fcs {\n\tcase 0:\n\t\tif f.SingleSegment {\n\t\t\tdst = append(dst, uint8(f.ContentSize))\n\t\t}\n\t\t// Unless SingleSegment is set, framessizes < 256 are nto stored.\n\tcase 1:\n\t\tf.ContentSize -= 256\n\t\tdst = append(dst, uint8(f.ContentSize), uint8(f.ContentSize>>8))\n\tcase 2:\n\t\tdst = append(dst, uint8(f.ContentSize), uint8(f.ContentSize>>8), uint8(f.ContentSize>>16), uint8(f.ContentSize>>24))\n\tcase 3:\n\t\tdst = append(dst, uint8(f.ContentSize), uint8(f.ContentSize>>8), uint8(f.ContentSize>>16), uint8(f.ContentSize>>24),\n\t\t\tuint8(f.ContentSize>>32), uint8(f.ContentSize>>40), uint8(f.ContentSize>>48), uint8(f.ContentSize>>56))\n\tdefault:\n\t\tpanic(\"invalid fcs\")\n\t}\n\treturn dst\n}\n\nconst skippableFrameHeader = 4 + 4\n\n// calcSkippableFrame will return a total size to be added for written\n// to be divisible by multiple.\n// The value will always be > skippableFrameHeader.\n// The function will panic if written < 0 or wantMultiple <= 0.\nfunc calcSkippableFrame(written, wantMultiple int64) int {\n\tif wantMultiple <= 0 {\n\t\tpanic(\"wantMultiple <= 0\")\n\t}\n\tif written < 0 {\n\t\tpanic(\"written < 0\")\n\t}\n\tleftOver := written % wantMultiple\n\tif leftOver == 0 {\n\t\treturn 0\n\t}\n\ttoAdd := wantMultiple - leftOver\n\tfor toAdd < skippableFrameHeader {\n\t\ttoAdd += wantMultiple\n\t}\n\treturn int(toAdd)\n}\n\n// skippableFrame will add a skippable frame with a total size of bytes.\n// total should be >= skippableFrameHeader and < math.MaxUint32.\nfunc skippableFrame(dst []byte, total int, r io.Reader) ([]byte, error) {\n\tif total == 0 {\n\t\treturn dst, nil\n\t}\n\tif total < skippableFrameHeader {\n\t\treturn dst, fmt.Errorf(\"requested skippable frame (%d) < 8\", total)\n\t}\n\tif int64(total) > math.MaxUint32 {\n\t\treturn dst, fmt.Errorf(\"requested skippable frame (%d) > max uint32\", total)\n\t}\n\tdst = append(dst, 0x50, 0x2a, 0x4d, 0x18)\n\tf := uint32(total - skippableFrameHeader)\n\tdst = append(dst, uint8(f), uint8(f>>8), uint8(f>>16), uint8(f>>24))\n\tstart := len(dst)\n\tdst = append(dst, make([]byte, f)...)\n\t_, err := io.ReadFull(r, dst[start:])\n\treturn dst, err\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/fse_decoder.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\nconst (\n\ttablelogAbsoluteMax = 9\n)\n\nconst (\n\t/*!MEMORY_USAGE :\n\t *  Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)\n\t *  Increasing memory usage improves compression ratio\n\t *  Reduced memory usage can improve speed, due to cache effect\n\t *  Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */\n\tmaxMemoryUsage = tablelogAbsoluteMax + 2\n\n\tmaxTableLog    = maxMemoryUsage - 2\n\tmaxTablesize   = 1 << maxTableLog\n\tmaxTableMask   = (1 << maxTableLog) - 1\n\tminTablelog    = 5\n\tmaxSymbolValue = 255\n)\n\n// fseDecoder provides temporary storage for compression and decompression.\ntype fseDecoder struct {\n\tdt             [maxTablesize]decSymbol // Decompression table.\n\tsymbolLen      uint16                  // Length of active part of the symbol table.\n\tactualTableLog uint8                   // Selected tablelog.\n\tmaxBits        uint8                   // Maximum number of additional bits\n\n\t// used for table creation to avoid allocations.\n\tstateTable [256]uint16\n\tnorm       [maxSymbolValue + 1]int16\n\tpreDefined bool\n}\n\n// tableStep returns the next table index.\nfunc tableStep(tableSize uint32) uint32 {\n\treturn (tableSize >> 1) + (tableSize >> 3) + 3\n}\n\n// readNCount will read the symbol distribution so decoding tables can be constructed.\nfunc (s *fseDecoder) readNCount(b *byteReader, maxSymbol uint16) error {\n\tvar (\n\t\tcharnum   uint16\n\t\tprevious0 bool\n\t)\n\tif b.remain() < 4 {\n\t\treturn errors.New(\"input too small\")\n\t}\n\tbitStream := b.Uint32NC()\n\tnbBits := uint((bitStream & 0xF) + minTablelog) // extract tableLog\n\tif nbBits > tablelogAbsoluteMax {\n\t\tprintln(\"Invalid tablelog:\", nbBits)\n\t\treturn errors.New(\"tableLog too large\")\n\t}\n\tbitStream >>= 4\n\tbitCount := uint(4)\n\n\ts.actualTableLog = uint8(nbBits)\n\tremaining := int32((1 << nbBits) + 1)\n\tthreshold := int32(1 << nbBits)\n\tgotTotal := int32(0)\n\tnbBits++\n\n\tfor remaining > 1 && charnum <= maxSymbol {\n\t\tif previous0 {\n\t\t\t//println(\"prev0\")\n\t\t\tn0 := charnum\n\t\t\tfor (bitStream & 0xFFFF) == 0xFFFF {\n\t\t\t\t//println(\"24 x 0\")\n\t\t\t\tn0 += 24\n\t\t\t\tif r := b.remain(); r > 5 {\n\t\t\t\t\tb.advance(2)\n\t\t\t\t\t// The check above should make sure we can read 32 bits\n\t\t\t\t\tbitStream = b.Uint32NC() >> bitCount\n\t\t\t\t} else {\n\t\t\t\t\t// end of bit stream\n\t\t\t\t\tbitStream >>= 16\n\t\t\t\t\tbitCount += 16\n\t\t\t\t}\n\t\t\t}\n\t\t\t//printf(\"bitstream: %d, 0b%b\", bitStream&3, bitStream)\n\t\t\tfor (bitStream & 3) == 3 {\n\t\t\t\tn0 += 3\n\t\t\t\tbitStream >>= 2\n\t\t\t\tbitCount += 2\n\t\t\t}\n\t\t\tn0 += uint16(bitStream & 3)\n\t\t\tbitCount += 2\n\n\t\t\tif n0 > maxSymbolValue {\n\t\t\t\treturn errors.New(\"maxSymbolValue too small\")\n\t\t\t}\n\t\t\t//println(\"inserting \", n0-charnum, \"zeroes from idx\", charnum, \"ending before\", n0)\n\t\t\tfor charnum < n0 {\n\t\t\t\ts.norm[uint8(charnum)] = 0\n\t\t\t\tcharnum++\n\t\t\t}\n\n\t\t\tif r := b.remain(); r >= 7 || r-int(bitCount>>3) >= 4 {\n\t\t\t\tb.advance(bitCount >> 3)\n\t\t\t\tbitCount &= 7\n\t\t\t\t// The check above should make sure we can read 32 bits\n\t\t\t\tbitStream = b.Uint32NC() >> bitCount\n\t\t\t} else {\n\t\t\t\tbitStream >>= 2\n\t\t\t}\n\t\t}\n\n\t\tmax := (2*threshold - 1) - remaining\n\t\tvar count int32\n\n\t\tif int32(bitStream)&(threshold-1) < max {\n\t\t\tcount = int32(bitStream) & (threshold - 1)\n\t\t\tif debugAsserts && nbBits < 1 {\n\t\t\t\tpanic(\"nbBits underflow\")\n\t\t\t}\n\t\t\tbitCount += nbBits - 1\n\t\t} else {\n\t\t\tcount = int32(bitStream) & (2*threshold - 1)\n\t\t\tif count >= threshold {\n\t\t\t\tcount -= max\n\t\t\t}\n\t\t\tbitCount += nbBits\n\t\t}\n\n\t\t// extra accuracy\n\t\tcount--\n\t\tif count < 0 {\n\t\t\t// -1 means +1\n\t\t\tremaining += count\n\t\t\tgotTotal -= count\n\t\t} else {\n\t\t\tremaining -= count\n\t\t\tgotTotal += count\n\t\t}\n\t\ts.norm[charnum&0xff] = int16(count)\n\t\tcharnum++\n\t\tprevious0 = count == 0\n\t\tfor remaining < threshold {\n\t\t\tnbBits--\n\t\t\tthreshold >>= 1\n\t\t}\n\n\t\tif r := b.remain(); r >= 7 || r-int(bitCount>>3) >= 4 {\n\t\t\tb.advance(bitCount >> 3)\n\t\t\tbitCount &= 7\n\t\t\t// The check above should make sure we can read 32 bits\n\t\t\tbitStream = b.Uint32NC() >> (bitCount & 31)\n\t\t} else {\n\t\t\tbitCount -= (uint)(8 * (len(b.b) - 4 - b.off))\n\t\t\tb.off = len(b.b) - 4\n\t\t\tbitStream = b.Uint32() >> (bitCount & 31)\n\t\t}\n\t}\n\ts.symbolLen = charnum\n\tif s.symbolLen <= 1 {\n\t\treturn fmt.Errorf(\"symbolLen (%d) too small\", s.symbolLen)\n\t}\n\tif s.symbolLen > maxSymbolValue+1 {\n\t\treturn fmt.Errorf(\"symbolLen (%d) too big\", s.symbolLen)\n\t}\n\tif remaining != 1 {\n\t\treturn fmt.Errorf(\"corruption detected (remaining %d != 1)\", remaining)\n\t}\n\tif bitCount > 32 {\n\t\treturn fmt.Errorf(\"corruption detected (bitCount %d > 32)\", bitCount)\n\t}\n\tif gotTotal != 1<<s.actualTableLog {\n\t\treturn fmt.Errorf(\"corruption detected (total %d != %d)\", gotTotal, 1<<s.actualTableLog)\n\t}\n\tb.advance((bitCount + 7) >> 3)\n\treturn s.buildDtable()\n}\n\nfunc (s *fseDecoder) mustReadFrom(r io.Reader) {\n\tfatalErr := func(err error) {\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\t// \tdt             [maxTablesize]decSymbol // Decompression table.\n\t//\tsymbolLen      uint16                  // Length of active part of the symbol table.\n\t//\tactualTableLog uint8                   // Selected tablelog.\n\t//\tmaxBits        uint8                   // Maximum number of additional bits\n\t//\t// used for table creation to avoid allocations.\n\t//\tstateTable [256]uint16\n\t//\tnorm       [maxSymbolValue + 1]int16\n\t//\tpreDefined bool\n\tfatalErr(binary.Read(r, binary.LittleEndian, &s.dt))\n\tfatalErr(binary.Read(r, binary.LittleEndian, &s.symbolLen))\n\tfatalErr(binary.Read(r, binary.LittleEndian, &s.actualTableLog))\n\tfatalErr(binary.Read(r, binary.LittleEndian, &s.maxBits))\n\tfatalErr(binary.Read(r, binary.LittleEndian, &s.stateTable))\n\tfatalErr(binary.Read(r, binary.LittleEndian, &s.norm))\n\tfatalErr(binary.Read(r, binary.LittleEndian, &s.preDefined))\n}\n\n// decSymbol contains information about a state entry,\n// Including the state offset base, the output symbol and\n// the number of bits to read for the low part of the destination state.\n// Using a composite uint64 is faster than a struct with separate members.\ntype decSymbol uint64\n\nfunc newDecSymbol(nbits, addBits uint8, newState uint16, baseline uint32) decSymbol {\n\treturn decSymbol(nbits) | (decSymbol(addBits) << 8) | (decSymbol(newState) << 16) | (decSymbol(baseline) << 32)\n}\n\nfunc (d decSymbol) nbBits() uint8 {\n\treturn uint8(d)\n}\n\nfunc (d decSymbol) addBits() uint8 {\n\treturn uint8(d >> 8)\n}\n\nfunc (d decSymbol) newState() uint16 {\n\treturn uint16(d >> 16)\n}\n\nfunc (d decSymbol) baselineInt() int {\n\treturn int(d >> 32)\n}\n\nfunc (d *decSymbol) setNBits(nBits uint8) {\n\tconst mask = 0xffffffffffffff00\n\t*d = (*d & mask) | decSymbol(nBits)\n}\n\nfunc (d *decSymbol) setAddBits(addBits uint8) {\n\tconst mask = 0xffffffffffff00ff\n\t*d = (*d & mask) | (decSymbol(addBits) << 8)\n}\n\nfunc (d *decSymbol) setNewState(state uint16) {\n\tconst mask = 0xffffffff0000ffff\n\t*d = (*d & mask) | decSymbol(state)<<16\n}\n\nfunc (d *decSymbol) setExt(addBits uint8, baseline uint32) {\n\tconst mask = 0xffff00ff\n\t*d = (*d & mask) | (decSymbol(addBits) << 8) | (decSymbol(baseline) << 32)\n}\n\n// decSymbolValue returns the transformed decSymbol for the given symbol.\nfunc decSymbolValue(symb uint8, t []baseOffset) (decSymbol, error) {\n\tif int(symb) >= len(t) {\n\t\treturn 0, fmt.Errorf(\"rle symbol %d >= max %d\", symb, len(t))\n\t}\n\tlu := t[symb]\n\treturn newDecSymbol(0, lu.addBits, 0, lu.baseLine), nil\n}\n\n// setRLE will set the decoder til RLE mode.\nfunc (s *fseDecoder) setRLE(symbol decSymbol) {\n\ts.actualTableLog = 0\n\ts.maxBits = symbol.addBits()\n\ts.dt[0] = symbol\n}\n\n// transform will transform the decoder table into a table usable for\n// decoding without having to apply the transformation while decoding.\n// The state will contain the base value and the number of bits to read.\nfunc (s *fseDecoder) transform(t []baseOffset) error {\n\ttableSize := uint16(1 << s.actualTableLog)\n\ts.maxBits = 0\n\tfor i, v := range s.dt[:tableSize] {\n\t\tadd := v.addBits()\n\t\tif int(add) >= len(t) {\n\t\t\treturn fmt.Errorf(\"invalid decoding table entry %d, symbol %d >= max (%d)\", i, v.addBits(), len(t))\n\t\t}\n\t\tlu := t[add]\n\t\tif lu.addBits > s.maxBits {\n\t\t\ts.maxBits = lu.addBits\n\t\t}\n\t\tv.setExt(lu.addBits, lu.baseLine)\n\t\ts.dt[i] = v\n\t}\n\treturn nil\n}\n\ntype fseState struct {\n\tdt    []decSymbol\n\tstate decSymbol\n}\n\n// Initialize and decodeAsync first state and symbol.\nfunc (s *fseState) init(br *bitReader, tableLog uint8, dt []decSymbol) {\n\ts.dt = dt\n\tbr.fill()\n\ts.state = dt[br.getBits(tableLog)]\n}\n\n// final returns the current state symbol without decoding the next.\nfunc (s decSymbol) final() (int, uint8) {\n\treturn s.baselineInt(), s.addBits()\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go",
    "content": "//go:build amd64 && !appengine && !noasm && gc\n// +build amd64,!appengine,!noasm,gc\n\npackage zstd\n\nimport (\n\t\"fmt\"\n)\n\ntype buildDtableAsmContext struct {\n\t// inputs\n\tstateTable *uint16\n\tnorm       *int16\n\tdt         *uint64\n\n\t// outputs --- set by the procedure in the case of error;\n\t// for interpretation please see the error handling part below\n\terrParam1 uint64\n\terrParam2 uint64\n}\n\n// buildDtable_asm is an x86 assembly implementation of fseDecoder.buildDtable.\n// Function returns non-zero exit code on error.\n//\n//go:noescape\nfunc buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int\n\n// please keep in sync with _generate/gen_fse.go\nconst (\n\terrorCorruptedNormalizedCounter = 1\n\terrorNewStateTooBig             = 2\n\terrorNewStateNoBits             = 3\n)\n\n// buildDtable will build the decoding table.\nfunc (s *fseDecoder) buildDtable() error {\n\tctx := buildDtableAsmContext{\n\t\tstateTable: &s.stateTable[0],\n\t\tnorm:       &s.norm[0],\n\t\tdt:         (*uint64)(&s.dt[0]),\n\t}\n\tcode := buildDtable_asm(s, &ctx)\n\n\tif code != 0 {\n\t\tswitch code {\n\t\tcase errorCorruptedNormalizedCounter:\n\t\t\tposition := ctx.errParam1\n\t\t\treturn fmt.Errorf(\"corrupted input (position=%d, expected 0)\", position)\n\n\t\tcase errorNewStateTooBig:\n\t\t\tnewState := decSymbol(ctx.errParam1)\n\t\t\tsize := ctx.errParam2\n\t\t\treturn fmt.Errorf(\"newState (%d) outside table size (%d)\", newState, size)\n\n\t\tcase errorNewStateNoBits:\n\t\t\tnewState := decSymbol(ctx.errParam1)\n\t\t\toldState := decSymbol(ctx.errParam2)\n\t\t\treturn fmt.Errorf(\"newState (%d) == oldState (%d) and no bits\", newState, oldState)\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"buildDtable_asm returned unhandled nonzero code = %d\", code)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s",
    "content": "// Code generated by command: go run gen_fse.go -out ../fse_decoder_amd64.s -pkg=zstd. DO NOT EDIT.\n\n//go:build !appengine && !noasm && gc && !noasm\n\n// func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int\nTEXT ·buildDtable_asm(SB), $0-24\n\tMOVQ ctx+8(FP), CX\n\tMOVQ s+0(FP), DI\n\n\t// Load values\n\tMOVBQZX 4098(DI), DX\n\tXORQ    AX, AX\n\tBTSQ    DX, AX\n\tMOVQ    (CX), BX\n\tMOVQ    16(CX), SI\n\tLEAQ    -1(AX), R8\n\tMOVQ    8(CX), CX\n\tMOVWQZX 4096(DI), DI\n\n\t// End load values\n\t// Init, lay down lowprob symbols\n\tXORQ R9, R9\n\tJMP  init_main_loop_condition\n\ninit_main_loop:\n\tMOVWQSX (CX)(R9*2), R10\n\tCMPW    R10, $-1\n\tJNE     do_not_update_high_threshold\n\tMOVB    R9, 1(SI)(R8*8)\n\tDECQ    R8\n\tMOVQ    $0x0000000000000001, R10\n\ndo_not_update_high_threshold:\n\tMOVW R10, (BX)(R9*2)\n\tINCQ R9\n\ninit_main_loop_condition:\n\tCMPQ R9, DI\n\tJL   init_main_loop\n\n\t// Spread symbols\n\t// Calculate table step\n\tMOVQ AX, R9\n\tSHRQ $0x01, R9\n\tMOVQ AX, R10\n\tSHRQ $0x03, R10\n\tLEAQ 3(R9)(R10*1), R9\n\n\t// Fill add bits values\n\tLEAQ -1(AX), R10\n\tXORQ R11, R11\n\tXORQ R12, R12\n\tJMP  spread_main_loop_condition\n\nspread_main_loop:\n\tXORQ    R13, R13\n\tMOVWQSX (CX)(R12*2), R14\n\tJMP     spread_inner_loop_condition\n\nspread_inner_loop:\n\tMOVB R12, 1(SI)(R11*8)\n\nadjust_position:\n\tADDQ R9, R11\n\tANDQ R10, R11\n\tCMPQ R11, R8\n\tJG   adjust_position\n\tINCQ R13\n\nspread_inner_loop_condition:\n\tCMPQ R13, R14\n\tJL   spread_inner_loop\n\tINCQ R12\n\nspread_main_loop_condition:\n\tCMPQ  R12, DI\n\tJL    spread_main_loop\n\tTESTQ R11, R11\n\tJZ    spread_check_ok\n\tMOVQ  ctx+8(FP), AX\n\tMOVQ  R11, 24(AX)\n\tMOVQ  $+1, ret+16(FP)\n\tRET\n\nspread_check_ok:\n\t// Build Decoding table\n\tXORQ DI, DI\n\nbuild_table_main_table:\n\tMOVBQZX 1(SI)(DI*8), CX\n\tMOVWQZX (BX)(CX*2), R8\n\tLEAQ    1(R8), R9\n\tMOVW    R9, (BX)(CX*2)\n\tMOVQ    R8, R9\n\tBSRQ    R9, R9\n\tMOVQ    DX, CX\n\tSUBQ    R9, CX\n\tSHLQ    CL, R8\n\tSUBQ    AX, R8\n\tMOVB    CL, (SI)(DI*8)\n\tMOVW    R8, 2(SI)(DI*8)\n\tCMPQ    R8, AX\n\tJLE     build_table_check1_ok\n\tMOVQ    ctx+8(FP), CX\n\tMOVQ    R8, 24(CX)\n\tMOVQ    AX, 32(CX)\n\tMOVQ    $+2, ret+16(FP)\n\tRET\n\nbuild_table_check1_ok:\n\tTESTB CL, CL\n\tJNZ   build_table_check2_ok\n\tCMPW  R8, DI\n\tJNE   build_table_check2_ok\n\tMOVQ  ctx+8(FP), AX\n\tMOVQ  R8, 24(AX)\n\tMOVQ  DI, 32(AX)\n\tMOVQ  $+3, ret+16(FP)\n\tRET\n\nbuild_table_check2_ok:\n\tINCQ DI\n\tCMPQ DI, AX\n\tJL   build_table_main_table\n\tMOVQ $+0, ret+16(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go",
    "content": "//go:build !amd64 || appengine || !gc || noasm\n// +build !amd64 appengine !gc noasm\n\npackage zstd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// buildDtable will build the decoding table.\nfunc (s *fseDecoder) buildDtable() error {\n\ttableSize := uint32(1 << s.actualTableLog)\n\thighThreshold := tableSize - 1\n\tsymbolNext := s.stateTable[:256]\n\n\t// Init, lay down lowprob symbols\n\t{\n\t\tfor i, v := range s.norm[:s.symbolLen] {\n\t\t\tif v == -1 {\n\t\t\t\ts.dt[highThreshold].setAddBits(uint8(i))\n\t\t\t\thighThreshold--\n\t\t\t\tsymbolNext[i] = 1\n\t\t\t} else {\n\t\t\t\tsymbolNext[i] = uint16(v)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Spread symbols\n\t{\n\t\ttableMask := tableSize - 1\n\t\tstep := tableStep(tableSize)\n\t\tposition := uint32(0)\n\t\tfor ss, v := range s.norm[:s.symbolLen] {\n\t\t\tfor i := 0; i < int(v); i++ {\n\t\t\t\ts.dt[position].setAddBits(uint8(ss))\n\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\tfor position > highThreshold {\n\t\t\t\t\t// lowprob area\n\t\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif position != 0 {\n\t\t\t// position must reach all cells once, otherwise normalizedCounter is incorrect\n\t\t\treturn errors.New(\"corrupted input (position != 0)\")\n\t\t}\n\t}\n\n\t// Build Decoding table\n\t{\n\t\ttableSize := uint16(1 << s.actualTableLog)\n\t\tfor u, v := range s.dt[:tableSize] {\n\t\t\tsymbol := v.addBits()\n\t\t\tnextState := symbolNext[symbol]\n\t\t\tsymbolNext[symbol] = nextState + 1\n\t\t\tnBits := s.actualTableLog - byte(highBits(uint32(nextState)))\n\t\t\ts.dt[u&maxTableMask].setNBits(nBits)\n\t\t\tnewState := (nextState << nBits) - tableSize\n\t\t\tif newState > tableSize {\n\t\t\t\treturn fmt.Errorf(\"newState (%d) outside table size (%d)\", newState, tableSize)\n\t\t\t}\n\t\t\tif newState == uint16(u) && nBits == 0 {\n\t\t\t\t// Seems weird that this is possible with nbits > 0.\n\t\t\t\treturn fmt.Errorf(\"newState (%d) == oldState (%d) and no bits\", newState, u)\n\t\t\t}\n\t\t\ts.dt[u&maxTableMask].setNewState(newState)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/fse_encoder.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\nconst (\n\t// For encoding we only support up to\n\tmaxEncTableLog    = 8\n\tmaxEncTablesize   = 1 << maxTableLog\n\tmaxEncTableMask   = (1 << maxTableLog) - 1\n\tminEncTablelog    = 5\n\tmaxEncSymbolValue = maxMatchLengthSymbol\n)\n\n// Scratch provides temporary storage for compression and decompression.\ntype fseEncoder struct {\n\tsymbolLen      uint16 // Length of active part of the symbol table.\n\tactualTableLog uint8  // Selected tablelog.\n\tct             cTable // Compression tables.\n\tmaxCount       int    // count of the most probable symbol\n\tzeroBits       bool   // no bits has prob > 50%.\n\tclearCount     bool   // clear count\n\tuseRLE         bool   // This encoder is for RLE\n\tpreDefined     bool   // This encoder is predefined.\n\treUsed         bool   // Set to know when the encoder has been reused.\n\trleVal         uint8  // RLE Symbol\n\tmaxBits        uint8  // Maximum output bits after transform.\n\n\t// TODO: Technically zstd should be fine with 64 bytes.\n\tcount [256]uint32\n\tnorm  [256]int16\n}\n\n// cTable contains tables used for compression.\ntype cTable struct {\n\ttableSymbol []byte\n\tstateTable  []uint16\n\tsymbolTT    []symbolTransform\n}\n\n// symbolTransform contains the state transform for a symbol.\ntype symbolTransform struct {\n\tdeltaNbBits    uint32\n\tdeltaFindState int16\n\toutBits        uint8\n}\n\n// String prints values as a human readable string.\nfunc (s symbolTransform) String() string {\n\treturn fmt.Sprintf(\"{deltabits: %08x, findstate:%d outbits:%d}\", s.deltaNbBits, s.deltaFindState, s.outBits)\n}\n\n// Histogram allows to populate the histogram and skip that step in the compression,\n// It otherwise allows to inspect the histogram when compression is done.\n// To indicate that you have populated the histogram call HistogramFinished\n// with the value of the highest populated symbol, as well as the number of entries\n// in the most populated entry. These are accepted at face value.\nfunc (s *fseEncoder) Histogram() *[256]uint32 {\n\treturn &s.count\n}\n\n// HistogramFinished can be called to indicate that the histogram has been populated.\n// maxSymbol is the index of the highest set symbol of the next data segment.\n// maxCount is the number of entries in the most populated entry.\n// These are accepted at face value.\nfunc (s *fseEncoder) HistogramFinished(maxSymbol uint8, maxCount int) {\n\ts.maxCount = maxCount\n\ts.symbolLen = uint16(maxSymbol) + 1\n\ts.clearCount = maxCount != 0\n}\n\n// allocCtable will allocate tables needed for compression.\n// If existing tables a re big enough, they are simply re-used.\nfunc (s *fseEncoder) allocCtable() {\n\ttableSize := 1 << s.actualTableLog\n\t// get tableSymbol that is big enough.\n\tif cap(s.ct.tableSymbol) < tableSize {\n\t\ts.ct.tableSymbol = make([]byte, tableSize)\n\t}\n\ts.ct.tableSymbol = s.ct.tableSymbol[:tableSize]\n\n\tctSize := tableSize\n\tif cap(s.ct.stateTable) < ctSize {\n\t\ts.ct.stateTable = make([]uint16, ctSize)\n\t}\n\ts.ct.stateTable = s.ct.stateTable[:ctSize]\n\n\tif cap(s.ct.symbolTT) < 256 {\n\t\ts.ct.symbolTT = make([]symbolTransform, 256)\n\t}\n\ts.ct.symbolTT = s.ct.symbolTT[:256]\n}\n\n// buildCTable will populate the compression table so it is ready to be used.\nfunc (s *fseEncoder) buildCTable() error {\n\ttableSize := uint32(1 << s.actualTableLog)\n\thighThreshold := tableSize - 1\n\tvar cumul [256]int16\n\n\ts.allocCtable()\n\ttableSymbol := s.ct.tableSymbol[:tableSize]\n\t// symbol start positions\n\t{\n\t\tcumul[0] = 0\n\t\tfor ui, v := range s.norm[:s.symbolLen-1] {\n\t\t\tu := byte(ui) // one less than reference\n\t\t\tif v == -1 {\n\t\t\t\t// Low proba symbol\n\t\t\t\tcumul[u+1] = cumul[u] + 1\n\t\t\t\ttableSymbol[highThreshold] = u\n\t\t\t\thighThreshold--\n\t\t\t} else {\n\t\t\t\tcumul[u+1] = cumul[u] + v\n\t\t\t}\n\t\t}\n\t\t// Encode last symbol separately to avoid overflowing u\n\t\tu := int(s.symbolLen - 1)\n\t\tv := s.norm[s.symbolLen-1]\n\t\tif v == -1 {\n\t\t\t// Low proba symbol\n\t\t\tcumul[u+1] = cumul[u] + 1\n\t\t\ttableSymbol[highThreshold] = byte(u)\n\t\t\thighThreshold--\n\t\t} else {\n\t\t\tcumul[u+1] = cumul[u] + v\n\t\t}\n\t\tif uint32(cumul[s.symbolLen]) != tableSize {\n\t\t\treturn fmt.Errorf(\"internal error: expected cumul[s.symbolLen] (%d) == tableSize (%d)\", cumul[s.symbolLen], tableSize)\n\t\t}\n\t\tcumul[s.symbolLen] = int16(tableSize) + 1\n\t}\n\t// Spread symbols\n\ts.zeroBits = false\n\t{\n\t\tstep := tableStep(tableSize)\n\t\ttableMask := tableSize - 1\n\t\tvar position uint32\n\t\t// if any symbol > largeLimit, we may have 0 bits output.\n\t\tlargeLimit := int16(1 << (s.actualTableLog - 1))\n\t\tfor ui, v := range s.norm[:s.symbolLen] {\n\t\t\tsymbol := byte(ui)\n\t\t\tif v > largeLimit {\n\t\t\t\ts.zeroBits = true\n\t\t\t}\n\t\t\tfor nbOccurrences := int16(0); nbOccurrences < v; nbOccurrences++ {\n\t\t\t\ttableSymbol[position] = symbol\n\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\tfor position > highThreshold {\n\t\t\t\t\tposition = (position + step) & tableMask\n\t\t\t\t} /* Low proba area */\n\t\t\t}\n\t\t}\n\n\t\t// Check if we have gone through all positions\n\t\tif position != 0 {\n\t\t\treturn errors.New(\"position!=0\")\n\t\t}\n\t}\n\n\t// Build table\n\ttable := s.ct.stateTable\n\t{\n\t\ttsi := int(tableSize)\n\t\tfor u, v := range tableSymbol {\n\t\t\t// TableU16 : sorted by symbol order; gives next state value\n\t\t\ttable[cumul[v]] = uint16(tsi + u)\n\t\t\tcumul[v]++\n\t\t}\n\t}\n\n\t// Build Symbol Transformation Table\n\t{\n\t\ttotal := int16(0)\n\t\tsymbolTT := s.ct.symbolTT[:s.symbolLen]\n\t\ttableLog := s.actualTableLog\n\t\ttl := (uint32(tableLog) << 16) - (1 << tableLog)\n\t\tfor i, v := range s.norm[:s.symbolLen] {\n\t\t\tswitch v {\n\t\t\tcase 0:\n\t\t\tcase -1, 1:\n\t\t\t\tsymbolTT[i].deltaNbBits = tl\n\t\t\t\tsymbolTT[i].deltaFindState = total - 1\n\t\t\t\ttotal++\n\t\t\tdefault:\n\t\t\t\tmaxBitsOut := uint32(tableLog) - highBit(uint32(v-1))\n\t\t\t\tminStatePlus := uint32(v) << maxBitsOut\n\t\t\t\tsymbolTT[i].deltaNbBits = (maxBitsOut << 16) - minStatePlus\n\t\t\t\tsymbolTT[i].deltaFindState = total - v\n\t\t\t\ttotal += v\n\t\t\t}\n\t\t}\n\t\tif total != int16(tableSize) {\n\t\t\treturn fmt.Errorf(\"total mismatch %d (got) != %d (want)\", total, tableSize)\n\t\t}\n\t}\n\treturn nil\n}\n\nvar rtbTable = [...]uint32{0, 473195, 504333, 520860, 550000, 700000, 750000, 830000}\n\nfunc (s *fseEncoder) setRLE(val byte) {\n\ts.allocCtable()\n\ts.actualTableLog = 0\n\ts.ct.stateTable = s.ct.stateTable[:1]\n\ts.ct.symbolTT[val] = symbolTransform{\n\t\tdeltaFindState: 0,\n\t\tdeltaNbBits:    0,\n\t}\n\tif debugEncoder {\n\t\tprintln(\"setRLE: val\", val, \"symbolTT\", s.ct.symbolTT[val])\n\t}\n\ts.rleVal = val\n\ts.useRLE = true\n}\n\n// setBits will set output bits for the transform.\n// if nil is provided, the number of bits is equal to the index.\nfunc (s *fseEncoder) setBits(transform []byte) {\n\tif s.reUsed || s.preDefined {\n\t\treturn\n\t}\n\tif s.useRLE {\n\t\tif transform == nil {\n\t\t\ts.ct.symbolTT[s.rleVal].outBits = s.rleVal\n\t\t\ts.maxBits = s.rleVal\n\t\t\treturn\n\t\t}\n\t\ts.maxBits = transform[s.rleVal]\n\t\ts.ct.symbolTT[s.rleVal].outBits = s.maxBits\n\t\treturn\n\t}\n\tif transform == nil {\n\t\tfor i := range s.ct.symbolTT[:s.symbolLen] {\n\t\t\ts.ct.symbolTT[i].outBits = uint8(i)\n\t\t}\n\t\ts.maxBits = uint8(s.symbolLen - 1)\n\t\treturn\n\t}\n\ts.maxBits = 0\n\tfor i, v := range transform[:s.symbolLen] {\n\t\ts.ct.symbolTT[i].outBits = v\n\t\tif v > s.maxBits {\n\t\t\t// We could assume bits always going up, but we play safe.\n\t\t\ts.maxBits = v\n\t\t}\n\t}\n}\n\n// normalizeCount will normalize the count of the symbols so\n// the total is equal to the table size.\n// If successful, compression tables will also be made ready.\nfunc (s *fseEncoder) normalizeCount(length int) error {\n\tif s.reUsed {\n\t\treturn nil\n\t}\n\ts.optimalTableLog(length)\n\tvar (\n\t\ttableLog          = s.actualTableLog\n\t\tscale             = 62 - uint64(tableLog)\n\t\tstep              = (1 << 62) / uint64(length)\n\t\tvStep             = uint64(1) << (scale - 20)\n\t\tstillToDistribute = int16(1 << tableLog)\n\t\tlargest           int\n\t\tlargestP          int16\n\t\tlowThreshold      = (uint32)(length >> tableLog)\n\t)\n\tif s.maxCount == length {\n\t\ts.useRLE = true\n\t\treturn nil\n\t}\n\ts.useRLE = false\n\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\t// already handled\n\t\t// if (count[s] == s.length) return 0;   /* rle special case */\n\n\t\tif cnt == 0 {\n\t\t\ts.norm[i] = 0\n\t\t\tcontinue\n\t\t}\n\t\tif cnt <= lowThreshold {\n\t\t\ts.norm[i] = -1\n\t\t\tstillToDistribute--\n\t\t} else {\n\t\t\tproba := (int16)((uint64(cnt) * step) >> scale)\n\t\t\tif proba < 8 {\n\t\t\t\trestToBeat := vStep * uint64(rtbTable[proba])\n\t\t\t\tv := uint64(cnt)*step - (uint64(proba) << scale)\n\t\t\t\tif v > restToBeat {\n\t\t\t\t\tproba++\n\t\t\t\t}\n\t\t\t}\n\t\t\tif proba > largestP {\n\t\t\t\tlargestP = proba\n\t\t\t\tlargest = i\n\t\t\t}\n\t\t\ts.norm[i] = proba\n\t\t\tstillToDistribute -= proba\n\t\t}\n\t}\n\n\tif -stillToDistribute >= (s.norm[largest] >> 1) {\n\t\t// corner case, need another normalization method\n\t\terr := s.normalizeCount2(length)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif debugAsserts {\n\t\t\terr = s.validateNorm()\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn s.buildCTable()\n\t}\n\ts.norm[largest] += stillToDistribute\n\tif debugAsserts {\n\t\terr := s.validateNorm()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn s.buildCTable()\n}\n\n// Secondary normalization method.\n// To be used when primary method fails.\nfunc (s *fseEncoder) normalizeCount2(length int) error {\n\tconst notYetAssigned = -2\n\tvar (\n\t\tdistributed  uint32\n\t\ttotal        = uint32(length)\n\t\ttableLog     = s.actualTableLog\n\t\tlowThreshold = total >> tableLog\n\t\tlowOne       = (total * 3) >> (tableLog + 1)\n\t)\n\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\tif cnt == 0 {\n\t\t\ts.norm[i] = 0\n\t\t\tcontinue\n\t\t}\n\t\tif cnt <= lowThreshold {\n\t\t\ts.norm[i] = -1\n\t\t\tdistributed++\n\t\t\ttotal -= cnt\n\t\t\tcontinue\n\t\t}\n\t\tif cnt <= lowOne {\n\t\t\ts.norm[i] = 1\n\t\t\tdistributed++\n\t\t\ttotal -= cnt\n\t\t\tcontinue\n\t\t}\n\t\ts.norm[i] = notYetAssigned\n\t}\n\ttoDistribute := (1 << tableLog) - distributed\n\n\tif (total / toDistribute) > lowOne {\n\t\t// risk of rounding to zero\n\t\tlowOne = (total * 3) / (toDistribute * 2)\n\t\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\t\tif (s.norm[i] == notYetAssigned) && (cnt <= lowOne) {\n\t\t\t\ts.norm[i] = 1\n\t\t\t\tdistributed++\n\t\t\t\ttotal -= cnt\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\ttoDistribute = (1 << tableLog) - distributed\n\t}\n\tif distributed == uint32(s.symbolLen)+1 {\n\t\t// all values are pretty poor;\n\t\t//   probably incompressible data (should have already been detected);\n\t\t//   find max, then give all remaining points to max\n\t\tvar maxV int\n\t\tvar maxC uint32\n\t\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\t\tif cnt > maxC {\n\t\t\t\tmaxV = i\n\t\t\t\tmaxC = cnt\n\t\t\t}\n\t\t}\n\t\ts.norm[maxV] += int16(toDistribute)\n\t\treturn nil\n\t}\n\n\tif total == 0 {\n\t\t// all of the symbols were low enough for the lowOne or lowThreshold\n\t\tfor i := uint32(0); toDistribute > 0; i = (i + 1) % (uint32(s.symbolLen)) {\n\t\t\tif s.norm[i] > 0 {\n\t\t\t\ttoDistribute--\n\t\t\t\ts.norm[i]++\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tvar (\n\t\tvStepLog = 62 - uint64(tableLog)\n\t\tmid      = uint64((1 << (vStepLog - 1)) - 1)\n\t\trStep    = (((1 << vStepLog) * uint64(toDistribute)) + mid) / uint64(total) // scale on remaining\n\t\ttmpTotal = mid\n\t)\n\tfor i, cnt := range s.count[:s.symbolLen] {\n\t\tif s.norm[i] == notYetAssigned {\n\t\t\tvar (\n\t\t\t\tend    = tmpTotal + uint64(cnt)*rStep\n\t\t\t\tsStart = uint32(tmpTotal >> vStepLog)\n\t\t\t\tsEnd   = uint32(end >> vStepLog)\n\t\t\t\tweight = sEnd - sStart\n\t\t\t)\n\t\t\tif weight < 1 {\n\t\t\t\treturn errors.New(\"weight < 1\")\n\t\t\t}\n\t\t\ts.norm[i] = int16(weight)\n\t\t\ttmpTotal = end\n\t\t}\n\t}\n\treturn nil\n}\n\n// optimalTableLog calculates and sets the optimal tableLog in s.actualTableLog\nfunc (s *fseEncoder) optimalTableLog(length int) {\n\ttableLog := uint8(maxEncTableLog)\n\tminBitsSrc := highBit(uint32(length)) + 1\n\tminBitsSymbols := highBit(uint32(s.symbolLen-1)) + 2\n\tminBits := uint8(minBitsSymbols)\n\tif minBitsSrc < minBitsSymbols {\n\t\tminBits = uint8(minBitsSrc)\n\t}\n\n\tmaxBitsSrc := uint8(highBit(uint32(length-1))) - 2\n\tif maxBitsSrc < tableLog {\n\t\t// Accuracy can be reduced\n\t\ttableLog = maxBitsSrc\n\t}\n\tif minBits > tableLog {\n\t\ttableLog = minBits\n\t}\n\t// Need a minimum to safely represent all symbol values\n\tif tableLog < minEncTablelog {\n\t\ttableLog = minEncTablelog\n\t}\n\tif tableLog > maxEncTableLog {\n\t\ttableLog = maxEncTableLog\n\t}\n\ts.actualTableLog = tableLog\n}\n\n// validateNorm validates the normalized histogram table.\nfunc (s *fseEncoder) validateNorm() (err error) {\n\tvar total int\n\tfor _, v := range s.norm[:s.symbolLen] {\n\t\tif v >= 0 {\n\t\t\ttotal += int(v)\n\t\t} else {\n\t\t\ttotal -= int(v)\n\t\t}\n\t}\n\tdefer func() {\n\t\tif err == nil {\n\t\t\treturn\n\t\t}\n\t\tfmt.Printf(\"selected TableLog: %d, Symbol length: %d\\n\", s.actualTableLog, s.symbolLen)\n\t\tfor i, v := range s.norm[:s.symbolLen] {\n\t\t\tfmt.Printf(\"%3d: %5d -> %4d \\n\", i, s.count[i], v)\n\t\t}\n\t}()\n\tif total != (1 << s.actualTableLog) {\n\t\treturn fmt.Errorf(\"warning: Total == %d != %d\", total, 1<<s.actualTableLog)\n\t}\n\tfor i, v := range s.count[s.symbolLen:] {\n\t\tif v != 0 {\n\t\t\treturn fmt.Errorf(\"warning: Found symbol out of range, %d after cut\", i)\n\t\t}\n\t}\n\treturn nil\n}\n\n// writeCount will write the normalized histogram count to header.\n// This is read back by readNCount.\nfunc (s *fseEncoder) writeCount(out []byte) ([]byte, error) {\n\tif s.useRLE {\n\t\treturn append(out, s.rleVal), nil\n\t}\n\tif s.preDefined || s.reUsed {\n\t\t// Never write predefined.\n\t\treturn out, nil\n\t}\n\n\tvar (\n\t\ttableLog  = s.actualTableLog\n\t\ttableSize = 1 << tableLog\n\t\tprevious0 bool\n\t\tcharnum   uint16\n\n\t\t// maximum header size plus 2 extra bytes for final output if bitCount == 0.\n\t\tmaxHeaderSize = ((int(s.symbolLen) * int(tableLog)) >> 3) + 3 + 2\n\n\t\t// Write Table Size\n\t\tbitStream = uint32(tableLog - minEncTablelog)\n\t\tbitCount  = uint(4)\n\t\tremaining = int16(tableSize + 1) /* +1 for extra accuracy */\n\t\tthreshold = int16(tableSize)\n\t\tnbBits    = uint(tableLog + 1)\n\t\toutP      = len(out)\n\t)\n\tif cap(out) < outP+maxHeaderSize {\n\t\tout = append(out, make([]byte, maxHeaderSize*3)...)\n\t\tout = out[:len(out)-maxHeaderSize*3]\n\t}\n\tout = out[:outP+maxHeaderSize]\n\n\t// stops at 1\n\tfor remaining > 1 {\n\t\tif previous0 {\n\t\t\tstart := charnum\n\t\t\tfor s.norm[charnum] == 0 {\n\t\t\t\tcharnum++\n\t\t\t}\n\t\t\tfor charnum >= start+24 {\n\t\t\t\tstart += 24\n\t\t\t\tbitStream += uint32(0xFFFF) << bitCount\n\t\t\t\tout[outP] = byte(bitStream)\n\t\t\t\tout[outP+1] = byte(bitStream >> 8)\n\t\t\t\toutP += 2\n\t\t\t\tbitStream >>= 16\n\t\t\t}\n\t\t\tfor charnum >= start+3 {\n\t\t\t\tstart += 3\n\t\t\t\tbitStream += 3 << bitCount\n\t\t\t\tbitCount += 2\n\t\t\t}\n\t\t\tbitStream += uint32(charnum-start) << bitCount\n\t\t\tbitCount += 2\n\t\t\tif bitCount > 16 {\n\t\t\t\tout[outP] = byte(bitStream)\n\t\t\t\tout[outP+1] = byte(bitStream >> 8)\n\t\t\t\toutP += 2\n\t\t\t\tbitStream >>= 16\n\t\t\t\tbitCount -= 16\n\t\t\t}\n\t\t}\n\n\t\tcount := s.norm[charnum]\n\t\tcharnum++\n\t\tmax := (2*threshold - 1) - remaining\n\t\tif count < 0 {\n\t\t\tremaining += count\n\t\t} else {\n\t\t\tremaining -= count\n\t\t}\n\t\tcount++ // +1 for extra accuracy\n\t\tif count >= threshold {\n\t\t\tcount += max // [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[\n\t\t}\n\t\tbitStream += uint32(count) << bitCount\n\t\tbitCount += nbBits\n\t\tif count < max {\n\t\t\tbitCount--\n\t\t}\n\n\t\tprevious0 = count == 1\n\t\tif remaining < 1 {\n\t\t\treturn nil, errors.New(\"internal error: remaining < 1\")\n\t\t}\n\t\tfor remaining < threshold {\n\t\t\tnbBits--\n\t\t\tthreshold >>= 1\n\t\t}\n\n\t\tif bitCount > 16 {\n\t\t\tout[outP] = byte(bitStream)\n\t\t\tout[outP+1] = byte(bitStream >> 8)\n\t\t\toutP += 2\n\t\t\tbitStream >>= 16\n\t\t\tbitCount -= 16\n\t\t}\n\t}\n\n\tif outP+2 > len(out) {\n\t\treturn nil, fmt.Errorf(\"internal error: %d > %d, maxheader: %d, sl: %d, tl: %d, normcount: %v\", outP+2, len(out), maxHeaderSize, s.symbolLen, int(tableLog), s.norm[:s.symbolLen])\n\t}\n\tout[outP] = byte(bitStream)\n\tout[outP+1] = byte(bitStream >> 8)\n\toutP += int((bitCount + 7) / 8)\n\n\tif charnum > s.symbolLen {\n\t\treturn nil, errors.New(\"internal error: charnum > s.symbolLen\")\n\t}\n\treturn out[:outP], nil\n}\n\n// Approximate symbol cost, as fractional value, using fixed-point format (accuracyLog fractional bits)\n// note 1 : assume symbolValue is valid (<= maxSymbolValue)\n// note 2 : if freq[symbolValue]==0, @return a fake cost of tableLog+1 bits *\nfunc (s *fseEncoder) bitCost(symbolValue uint8, accuracyLog uint32) uint32 {\n\tminNbBits := s.ct.symbolTT[symbolValue].deltaNbBits >> 16\n\tthreshold := (minNbBits + 1) << 16\n\tif debugAsserts {\n\t\tif !(s.actualTableLog < 16) {\n\t\t\tpanic(\"!s.actualTableLog < 16\")\n\t\t}\n\t\t// ensure enough room for renormalization double shift\n\t\tif !(uint8(accuracyLog) < 31-s.actualTableLog) {\n\t\t\tpanic(\"!uint8(accuracyLog) < 31-s.actualTableLog\")\n\t\t}\n\t}\n\ttableSize := uint32(1) << s.actualTableLog\n\tdeltaFromThreshold := threshold - (s.ct.symbolTT[symbolValue].deltaNbBits + tableSize)\n\t// linear interpolation (very approximate)\n\tnormalizedDeltaFromThreshold := (deltaFromThreshold << accuracyLog) >> s.actualTableLog\n\tbitMultiplier := uint32(1) << accuracyLog\n\tif debugAsserts {\n\t\tif s.ct.symbolTT[symbolValue].deltaNbBits+tableSize > threshold {\n\t\t\tpanic(\"s.ct.symbolTT[symbolValue].deltaNbBits+tableSize > threshold\")\n\t\t}\n\t\tif normalizedDeltaFromThreshold > bitMultiplier {\n\t\t\tpanic(\"normalizedDeltaFromThreshold > bitMultiplier\")\n\t\t}\n\t}\n\treturn (minNbBits+1)*bitMultiplier - normalizedDeltaFromThreshold\n}\n\n// Returns the cost in bits of encoding the distribution in count using ctable.\n// Histogram should only be up to the last non-zero symbol.\n// Returns an -1 if ctable cannot represent all the symbols in count.\nfunc (s *fseEncoder) approxSize(hist []uint32) uint32 {\n\tif int(s.symbolLen) < len(hist) {\n\t\t// More symbols than we have.\n\t\treturn math.MaxUint32\n\t}\n\tif s.useRLE {\n\t\t// We will never reuse RLE encoders.\n\t\treturn math.MaxUint32\n\t}\n\tconst kAccuracyLog = 8\n\tbadCost := (uint32(s.actualTableLog) + 1) << kAccuracyLog\n\tvar cost uint32\n\tfor i, v := range hist {\n\t\tif v == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif s.norm[i] == 0 {\n\t\t\treturn math.MaxUint32\n\t\t}\n\t\tbitCost := s.bitCost(uint8(i), kAccuracyLog)\n\t\tif bitCost > badCost {\n\t\t\treturn math.MaxUint32\n\t\t}\n\t\tcost += v * bitCost\n\t}\n\treturn cost >> kAccuracyLog\n}\n\n// maxHeaderSize returns the maximum header size in bits.\n// This is not exact size, but we want a penalty for new tables anyway.\nfunc (s *fseEncoder) maxHeaderSize() uint32 {\n\tif s.preDefined {\n\t\treturn 0\n\t}\n\tif s.useRLE {\n\t\treturn 8\n\t}\n\treturn (((uint32(s.symbolLen) * uint32(s.actualTableLog)) >> 3) + 3) * 8\n}\n\n// cState contains the compression state of a stream.\ntype cState struct {\n\tbw         *bitWriter\n\tstateTable []uint16\n\tstate      uint16\n}\n\n// init will initialize the compression state to the first symbol of the stream.\nfunc (c *cState) init(bw *bitWriter, ct *cTable, first symbolTransform) {\n\tc.bw = bw\n\tc.stateTable = ct.stateTable\n\tif len(c.stateTable) == 1 {\n\t\t// RLE\n\t\tc.stateTable[0] = uint16(0)\n\t\tc.state = 0\n\t\treturn\n\t}\n\tnbBitsOut := (first.deltaNbBits + (1 << 15)) >> 16\n\tim := int32((nbBitsOut << 16) - first.deltaNbBits)\n\tlu := (im >> nbBitsOut) + int32(first.deltaFindState)\n\tc.state = c.stateTable[lu]\n}\n\n// flush will write the tablelog to the output and flush the remaining full bytes.\nfunc (c *cState) flush(tableLog uint8) {\n\tc.bw.flush32()\n\tc.bw.addBits16NC(c.state, tableLog)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/fse_predefined.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"sync\"\n)\n\nvar (\n\t// fsePredef are the predefined fse tables as defined here:\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#default-distributions\n\t// These values are already transformed.\n\tfsePredef [3]fseDecoder\n\n\t// fsePredefEnc are the predefined encoder based on fse tables as defined here:\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#default-distributions\n\t// These values are already transformed.\n\tfsePredefEnc [3]fseEncoder\n\n\t// symbolTableX contain the transformations needed for each type as defined in\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#the-codes-for-literals-lengths-match-lengths-and-offsets\n\tsymbolTableX [3][]baseOffset\n\n\t// maxTableSymbol is the biggest supported symbol for each table type\n\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#the-codes-for-literals-lengths-match-lengths-and-offsets\n\tmaxTableSymbol = [3]uint8{tableLiteralLengths: maxLiteralLengthSymbol, tableOffsets: maxOffsetLengthSymbol, tableMatchLengths: maxMatchLengthSymbol}\n\n\t// bitTables is the bits table for each table.\n\tbitTables = [3][]byte{tableLiteralLengths: llBitsTable[:], tableOffsets: nil, tableMatchLengths: mlBitsTable[:]}\n)\n\ntype tableIndex uint8\n\nconst (\n\t// indexes for fsePredef and symbolTableX\n\ttableLiteralLengths tableIndex = 0\n\ttableOffsets        tableIndex = 1\n\ttableMatchLengths   tableIndex = 2\n\n\tmaxLiteralLengthSymbol = 35\n\tmaxOffsetLengthSymbol  = 30\n\tmaxMatchLengthSymbol   = 52\n)\n\n// baseOffset is used for calculating transformations.\ntype baseOffset struct {\n\tbaseLine uint32\n\taddBits  uint8\n}\n\n// fillBase will precalculate base offsets with the given bit distributions.\nfunc fillBase(dst []baseOffset, base uint32, bits ...uint8) {\n\tif len(bits) != len(dst) {\n\t\tpanic(fmt.Sprintf(\"len(dst) (%d) != len(bits) (%d)\", len(dst), len(bits)))\n\t}\n\tfor i, bit := range bits {\n\t\tif base > math.MaxInt32 {\n\t\t\tpanic(\"invalid decoding table, base overflows int32\")\n\t\t}\n\n\t\tdst[i] = baseOffset{\n\t\t\tbaseLine: base,\n\t\t\taddBits:  bit,\n\t\t}\n\t\tbase += 1 << bit\n\t}\n}\n\nvar predef sync.Once\n\nfunc initPredefined() {\n\tpredef.Do(func() {\n\t\t// Literals length codes\n\t\ttmp := make([]baseOffset, 36)\n\t\tfor i := range tmp[:16] {\n\t\t\ttmp[i] = baseOffset{\n\t\t\t\tbaseLine: uint32(i),\n\t\t\t\taddBits:  0,\n\t\t\t}\n\t\t}\n\t\tfillBase(tmp[16:], 16, 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)\n\t\tsymbolTableX[tableLiteralLengths] = tmp\n\n\t\t// Match length codes\n\t\ttmp = make([]baseOffset, 53)\n\t\tfor i := range tmp[:32] {\n\t\t\ttmp[i] = baseOffset{\n\t\t\t\t// The transformation adds the 3 length.\n\t\t\t\tbaseLine: uint32(i) + 3,\n\t\t\t\taddBits:  0,\n\t\t\t}\n\t\t}\n\t\tfillBase(tmp[32:], 35, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)\n\t\tsymbolTableX[tableMatchLengths] = tmp\n\n\t\t// Offset codes\n\t\ttmp = make([]baseOffset, maxOffsetBits+1)\n\t\ttmp[1] = baseOffset{\n\t\t\tbaseLine: 1,\n\t\t\taddBits:  1,\n\t\t}\n\t\tfillBase(tmp[2:], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30)\n\t\tsymbolTableX[tableOffsets] = tmp\n\n\t\t// Fill predefined tables and transform them.\n\t\t// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#default-distributions\n\t\tfor i := range fsePredef[:] {\n\t\t\tf := &fsePredef[i]\n\t\t\tswitch tableIndex(i) {\n\t\t\tcase tableLiteralLengths:\n\t\t\t\t// https://github.com/facebook/zstd/blob/ededcfca57366461021c922720878c81a5854a0a/lib/decompress/zstd_decompress_block.c#L243\n\t\t\t\tf.actualTableLog = 6\n\t\t\t\tcopy(f.norm[:], []int16{4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,\n\t\t\t\t\t2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,\n\t\t\t\t\t-1, -1, -1, -1})\n\t\t\t\tf.symbolLen = 36\n\t\t\tcase tableOffsets:\n\t\t\t\t// https://github.com/facebook/zstd/blob/ededcfca57366461021c922720878c81a5854a0a/lib/decompress/zstd_decompress_block.c#L281\n\t\t\t\tf.actualTableLog = 5\n\t\t\t\tcopy(f.norm[:], []int16{\n\t\t\t\t\t1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t\t\t1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1})\n\t\t\t\tf.symbolLen = 29\n\t\t\tcase tableMatchLengths:\n\t\t\t\t//https://github.com/facebook/zstd/blob/ededcfca57366461021c922720878c81a5854a0a/lib/decompress/zstd_decompress_block.c#L304\n\t\t\t\tf.actualTableLog = 6\n\t\t\t\tcopy(f.norm[:], []int16{\n\t\t\t\t\t1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,\n\t\t\t\t\t1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1,\n\t\t\t\t\t-1, -1, -1, -1, -1})\n\t\t\t\tf.symbolLen = 53\n\t\t\t}\n\t\t\tif err := f.buildDtable(); err != nil {\n\t\t\t\tpanic(fmt.Errorf(\"building table %v: %v\", tableIndex(i), err))\n\t\t\t}\n\t\t\tif err := f.transform(symbolTableX[i]); err != nil {\n\t\t\t\tpanic(fmt.Errorf(\"building table %v: %v\", tableIndex(i), err))\n\t\t\t}\n\t\t\tf.preDefined = true\n\n\t\t\t// Create encoder as well\n\t\t\tenc := &fsePredefEnc[i]\n\t\t\tcopy(enc.norm[:], f.norm[:])\n\t\t\tenc.symbolLen = f.symbolLen\n\t\t\tenc.actualTableLog = f.actualTableLog\n\t\t\tif err := enc.buildCTable(); err != nil {\n\t\t\t\tpanic(fmt.Errorf(\"building encoding table %v: %v\", tableIndex(i), err))\n\t\t\t}\n\t\t\tenc.setBits(bitTables[i])\n\t\t\tenc.preDefined = true\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/hash.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nconst (\n\tprime3bytes = 506832829\n\tprime4bytes = 2654435761\n\tprime5bytes = 889523592379\n\tprime6bytes = 227718039650203\n\tprime7bytes = 58295818150454627\n\tprime8bytes = 0xcf1bbcdcb7a56463\n)\n\n// hashLen returns a hash of the lowest mls bytes of with length output bits.\n// mls must be >=3 and <=8. Any other value will return hash for 4 bytes.\n// length should always be < 32.\n// Preferably length and mls should be a constant for inlining.\nfunc hashLen(u uint64, length, mls uint8) uint32 {\n\tswitch mls {\n\tcase 3:\n\t\treturn (uint32(u<<8) * prime3bytes) >> (32 - length)\n\tcase 5:\n\t\treturn uint32(((u << (64 - 40)) * prime5bytes) >> (64 - length))\n\tcase 6:\n\t\treturn uint32(((u << (64 - 48)) * prime6bytes) >> (64 - length))\n\tcase 7:\n\t\treturn uint32(((u << (64 - 56)) * prime7bytes) >> (64 - length))\n\tcase 8:\n\t\treturn uint32((u * prime8bytes) >> (64 - length))\n\tdefault:\n\t\treturn (uint32(u) * prime4bytes) >> (32 - length)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/history.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"github.com/klauspost/compress/huff0\"\n)\n\n// history contains the information transferred between blocks.\ntype history struct {\n\t// Literal decompression\n\thuffTree *huff0.Scratch\n\n\t// Sequence decompression\n\tdecoders      sequenceDecs\n\trecentOffsets [3]int\n\n\t// History buffer...\n\tb []byte\n\n\t// ignoreBuffer is meant to ignore a number of bytes\n\t// when checking for matches in history\n\tignoreBuffer int\n\n\twindowSize       int\n\tallocFrameBuffer int // needed?\n\terror            bool\n\tdict             *dict\n}\n\n// reset will reset the history to initial state of a frame.\n// The history must already have been initialized to the desired size.\nfunc (h *history) reset() {\n\th.b = h.b[:0]\n\th.ignoreBuffer = 0\n\th.error = false\n\th.recentOffsets = [3]int{1, 4, 8}\n\th.decoders.freeDecoders()\n\th.decoders = sequenceDecs{br: h.decoders.br}\n\th.freeHuffDecoder()\n\th.huffTree = nil\n\th.dict = nil\n\t//printf(\"history created: %+v (l: %d, c: %d)\", *h, len(h.b), cap(h.b))\n}\n\nfunc (h *history) freeHuffDecoder() {\n\tif h.huffTree != nil {\n\t\tif h.dict == nil || h.dict.litEnc != h.huffTree {\n\t\t\thuffDecoderPool.Put(h.huffTree)\n\t\t\th.huffTree = nil\n\t\t}\n\t}\n}\n\nfunc (h *history) setDict(dict *dict) {\n\tif dict == nil {\n\t\treturn\n\t}\n\th.dict = dict\n\th.decoders.litLengths = dict.llDec\n\th.decoders.offsets = dict.ofDec\n\th.decoders.matchLengths = dict.mlDec\n\th.decoders.dict = dict.content\n\th.recentOffsets = dict.offsets\n\th.huffTree = dict.litEnc\n}\n\n// append bytes to history.\n// This function will make sure there is space for it,\n// if the buffer has been allocated with enough extra space.\nfunc (h *history) append(b []byte) {\n\tif len(b) >= h.windowSize {\n\t\t// Discard all history by simply overwriting\n\t\th.b = h.b[:h.windowSize]\n\t\tcopy(h.b, b[len(b)-h.windowSize:])\n\t\treturn\n\t}\n\n\t// If there is space, append it.\n\tif len(b) < cap(h.b)-len(h.b) {\n\t\th.b = append(h.b, b...)\n\t\treturn\n\t}\n\n\t// Move data down so we only have window size left.\n\t// We know we have less than window size in b at this point.\n\tdiscard := len(b) + len(h.b) - h.windowSize\n\tcopy(h.b, h.b[discard:])\n\th.b = h.b[:h.windowSize]\n\tcopy(h.b[h.windowSize-len(b):], b)\n}\n\n// ensureBlock will ensure there is space for at least one block...\nfunc (h *history) ensureBlock() {\n\tif cap(h.b) < h.allocFrameBuffer {\n\t\th.b = make([]byte, 0, h.allocFrameBuffer)\n\t\treturn\n\t}\n\n\tavail := cap(h.b) - len(h.b)\n\tif avail >= h.windowSize || avail > maxCompressedBlockSize {\n\t\treturn\n\t}\n\t// Move data down so we only have window size left.\n\t// We know we have less than window size in b at this point.\n\tdiscard := len(h.b) - h.windowSize\n\tcopy(h.b, h.b[discard:])\n\th.b = h.b[:h.windowSize]\n}\n\n// append bytes to history without ever discarding anything.\nfunc (h *history) appendKeep(b []byte) {\n\th.b = append(h.b, b...)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/LICENSE.txt",
    "content": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/README.md",
    "content": "# xxhash\n\nVENDORED: Go to [github.com/cespare/xxhash](https://github.com/cespare/xxhash) for original package.\n\nxxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a\nhigh-quality hashing algorithm that is much faster than anything in the Go\nstandard library.\n\nThis package provides a straightforward API:\n\n```\nfunc Sum64(b []byte) uint64\nfunc Sum64String(s string) uint64\ntype Digest struct{ ... }\n    func New() *Digest\n```\n\nThe `Digest` type implements hash.Hash64. Its key methods are:\n\n```\nfunc (*Digest) Write([]byte) (int, error)\nfunc (*Digest) WriteString(string) (int, error)\nfunc (*Digest) Sum64() uint64\n```\n\nThe package is written with optimized pure Go and also contains even faster\nassembly implementations for amd64 and arm64. If desired, the `purego` build tag\nopts into using the Go code even on those architectures.\n\n[xxHash]: http://cyan4973.github.io/xxHash/\n\n## Compatibility\n\nThis package is in a module and the latest code is in version 2 of the module.\nYou need a version of Go with at least \"minimal module compatibility\" to use\ngithub.com/cespare/xxhash/v2:\n\n* 1.9.7+ for Go 1.9\n* 1.10.3+ for Go 1.10\n* Go 1.11 or later\n\nI recommend using the latest release of Go.\n\n## Benchmarks\n\nHere are some quick benchmarks comparing the pure-Go and assembly\nimplementations of Sum64.\n\n| input size | purego    | asm       |\n| ---------- | --------- | --------- |\n| 4 B        |  1.3 GB/s |  1.2 GB/s |\n| 16 B       |  2.9 GB/s |  3.5 GB/s |\n| 100 B      |  6.9 GB/s |  8.1 GB/s |\n| 4 KB       | 11.7 GB/s | 16.7 GB/s |\n| 10 MB      | 12.0 GB/s | 17.3 GB/s |\n\nThese numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C\nCPU using the following commands under Go 1.19.2:\n\n```\nbenchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')\nbenchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')\n```\n\n## Projects using this package\n\n- [InfluxDB](https://github.com/influxdata/influxdb)\n- [Prometheus](https://github.com/prometheus/prometheus)\n- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)\n- [FreeCache](https://github.com/coocood/freecache)\n- [FastCache](https://github.com/VictoriaMetrics/fastcache)\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash.go",
    "content": "// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described\n// at http://cyan4973.github.io/xxHash/.\n// THIS IS VENDORED: Go to github.com/cespare/xxhash for original package.\n\npackage xxhash\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math/bits\"\n)\n\nconst (\n\tprime1 uint64 = 11400714785074694791\n\tprime2 uint64 = 14029467366897019727\n\tprime3 uint64 = 1609587929392839161\n\tprime4 uint64 = 9650029242287828579\n\tprime5 uint64 = 2870177450012600261\n)\n\n// Store the primes in an array as well.\n//\n// The consts are used when possible in Go code to avoid MOVs but we need a\n// contiguous array of the assembly code.\nvar primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}\n\n// Digest implements hash.Hash64.\ntype Digest struct {\n\tv1    uint64\n\tv2    uint64\n\tv3    uint64\n\tv4    uint64\n\ttotal uint64\n\tmem   [32]byte\n\tn     int // how much of mem is used\n}\n\n// New creates a new Digest that computes the 64-bit xxHash algorithm.\nfunc New() *Digest {\n\tvar d Digest\n\td.Reset()\n\treturn &d\n}\n\n// Reset clears the Digest's state so that it can be reused.\nfunc (d *Digest) Reset() {\n\td.v1 = primes[0] + prime2\n\td.v2 = prime2\n\td.v3 = 0\n\td.v4 = -primes[0]\n\td.total = 0\n\td.n = 0\n}\n\n// Size always returns 8 bytes.\nfunc (d *Digest) Size() int { return 8 }\n\n// BlockSize always returns 32 bytes.\nfunc (d *Digest) BlockSize() int { return 32 }\n\n// Write adds more data to d. It always returns len(b), nil.\nfunc (d *Digest) Write(b []byte) (n int, err error) {\n\tn = len(b)\n\td.total += uint64(n)\n\n\tmemleft := d.mem[d.n&(len(d.mem)-1):]\n\n\tif d.n+n < 32 {\n\t\t// This new data doesn't even fill the current block.\n\t\tcopy(memleft, b)\n\t\td.n += n\n\t\treturn\n\t}\n\n\tif d.n > 0 {\n\t\t// Finish off the partial block.\n\t\tc := copy(memleft, b)\n\t\td.v1 = round(d.v1, u64(d.mem[0:8]))\n\t\td.v2 = round(d.v2, u64(d.mem[8:16]))\n\t\td.v3 = round(d.v3, u64(d.mem[16:24]))\n\t\td.v4 = round(d.v4, u64(d.mem[24:32]))\n\t\tb = b[c:]\n\t\td.n = 0\n\t}\n\n\tif len(b) >= 32 {\n\t\t// One or more full blocks left.\n\t\tnw := writeBlocks(d, b)\n\t\tb = b[nw:]\n\t}\n\n\t// Store any remaining partial block.\n\tcopy(d.mem[:], b)\n\td.n = len(b)\n\n\treturn\n}\n\n// Sum appends the current hash to b and returns the resulting slice.\nfunc (d *Digest) Sum(b []byte) []byte {\n\ts := d.Sum64()\n\treturn append(\n\t\tb,\n\t\tbyte(s>>56),\n\t\tbyte(s>>48),\n\t\tbyte(s>>40),\n\t\tbyte(s>>32),\n\t\tbyte(s>>24),\n\t\tbyte(s>>16),\n\t\tbyte(s>>8),\n\t\tbyte(s),\n\t)\n}\n\n// Sum64 returns the current hash.\nfunc (d *Digest) Sum64() uint64 {\n\tvar h uint64\n\n\tif d.total >= 32 {\n\t\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = d.v3 + prime5\n\t}\n\n\th += d.total\n\n\tb := d.mem[:d.n&(len(d.mem)-1)]\n\tfor ; len(b) >= 8; b = b[8:] {\n\t\tk1 := round(0, u64(b[:8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif len(b) >= 4 {\n\t\th ^= uint64(u32(b[:4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\tb = b[4:]\n\t}\n\tfor ; len(b) > 0; b = b[1:] {\n\t\th ^= uint64(b[0]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nconst (\n\tmagic         = \"xxh\\x06\"\n\tmarshaledSize = len(magic) + 8*5 + 32\n)\n\n// MarshalBinary implements the encoding.BinaryMarshaler interface.\nfunc (d *Digest) MarshalBinary() ([]byte, error) {\n\tb := make([]byte, 0, marshaledSize)\n\tb = append(b, magic...)\n\tb = appendUint64(b, d.v1)\n\tb = appendUint64(b, d.v2)\n\tb = appendUint64(b, d.v3)\n\tb = appendUint64(b, d.v4)\n\tb = appendUint64(b, d.total)\n\tb = append(b, d.mem[:d.n]...)\n\tb = b[:len(b)+len(d.mem)-d.n]\n\treturn b, nil\n}\n\n// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.\nfunc (d *Digest) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic) || string(b[:len(magic)]) != magic {\n\t\treturn errors.New(\"xxhash: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize {\n\t\treturn errors.New(\"xxhash: invalid hash state size\")\n\t}\n\tb = b[len(magic):]\n\tb, d.v1 = consumeUint64(b)\n\tb, d.v2 = consumeUint64(b)\n\tb, d.v3 = consumeUint64(b)\n\tb, d.v4 = consumeUint64(b)\n\tb, d.total = consumeUint64(b)\n\tcopy(d.mem[:], b)\n\td.n = int(d.total % uint64(len(d.mem)))\n\treturn nil\n}\n\nfunc appendUint64(b []byte, x uint64) []byte {\n\tvar a [8]byte\n\tbinary.LittleEndian.PutUint64(a[:], x)\n\treturn append(b, a[:]...)\n}\n\nfunc consumeUint64(b []byte) ([]byte, uint64) {\n\tx := u64(b)\n\treturn b[8:], x\n}\n\nfunc u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }\nfunc u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }\n\nfunc round(acc, input uint64) uint64 {\n\tacc += input * prime2\n\tacc = rol31(acc)\n\tacc *= prime1\n\treturn acc\n}\n\nfunc mergeRound(acc, val uint64) uint64 {\n\tval = round(0, val)\n\tacc ^= val\n\tacc = acc*prime1 + prime4\n\treturn acc\n}\n\nfunc rol1(x uint64) uint64  { return bits.RotateLeft64(x, 1) }\nfunc rol7(x uint64) uint64  { return bits.RotateLeft64(x, 7) }\nfunc rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) }\nfunc rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) }\nfunc rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) }\nfunc rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) }\nfunc rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) }\nfunc rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) }\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s",
    "content": "//go:build !appengine && gc && !purego && !noasm\n// +build !appengine\n// +build gc\n// +build !purego\n// +build !noasm\n\n#include \"textflag.h\"\n\n// Registers:\n#define h      AX\n#define d      AX\n#define p      SI // pointer to advance through b\n#define n      DX\n#define end    BX // loop end\n#define v1     R8\n#define v2     R9\n#define v3     R10\n#define v4     R11\n#define x      R12\n#define prime1 R13\n#define prime2 R14\n#define prime4 DI\n\n#define round(acc, x) \\\n\tIMULQ prime2, x   \\\n\tADDQ  x, acc      \\\n\tROLQ  $31, acc    \\\n\tIMULQ prime1, acc\n\n// round0 performs the operation x = round(0, x).\n#define round0(x) \\\n\tIMULQ prime2, x \\\n\tROLQ  $31, x    \\\n\tIMULQ prime1, x\n\n// mergeRound applies a merge round on the two registers acc and x.\n// It assumes that prime1, prime2, and prime4 have been loaded.\n#define mergeRound(acc, x) \\\n\tround0(x)         \\\n\tXORQ  x, acc      \\\n\tIMULQ prime1, acc \\\n\tADDQ  prime4, acc\n\n// blockLoop processes as many 32-byte blocks as possible,\n// updating v1, v2, v3, and v4. It assumes that there is at least one block\n// to process.\n#define blockLoop() \\\nloop:  \\\n\tMOVQ +0(p), x  \\\n\tround(v1, x)   \\\n\tMOVQ +8(p), x  \\\n\tround(v2, x)   \\\n\tMOVQ +16(p), x \\\n\tround(v3, x)   \\\n\tMOVQ +24(p), x \\\n\tround(v4, x)   \\\n\tADDQ $32, p    \\\n\tCMPQ p, end    \\\n\tJLE  loop\n\n// func Sum64(b []byte) uint64\nTEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32\n\t// Load fixed primes.\n\tMOVQ ·primes+0(SB), prime1\n\tMOVQ ·primes+8(SB), prime2\n\tMOVQ ·primes+24(SB), prime4\n\n\t// Load slice.\n\tMOVQ b_base+0(FP), p\n\tMOVQ b_len+8(FP), n\n\tLEAQ (p)(n*1), end\n\n\t// The first loop limit will be len(b)-32.\n\tSUBQ $32, end\n\n\t// Check whether we have at least one block.\n\tCMPQ n, $32\n\tJLT  noBlocks\n\n\t// Set up initial state (v1, v2, v3, v4).\n\tMOVQ prime1, v1\n\tADDQ prime2, v1\n\tMOVQ prime2, v2\n\tXORQ v3, v3\n\tXORQ v4, v4\n\tSUBQ prime1, v4\n\n\tblockLoop()\n\n\tMOVQ v1, h\n\tROLQ $1, h\n\tMOVQ v2, x\n\tROLQ $7, x\n\tADDQ x, h\n\tMOVQ v3, x\n\tROLQ $12, x\n\tADDQ x, h\n\tMOVQ v4, x\n\tROLQ $18, x\n\tADDQ x, h\n\n\tmergeRound(h, v1)\n\tmergeRound(h, v2)\n\tmergeRound(h, v3)\n\tmergeRound(h, v4)\n\n\tJMP afterBlocks\n\nnoBlocks:\n\tMOVQ ·primes+32(SB), h\n\nafterBlocks:\n\tADDQ n, h\n\n\tADDQ $24, end\n\tCMPQ p, end\n\tJG   try4\n\nloop8:\n\tMOVQ  (p), x\n\tADDQ  $8, p\n\tround0(x)\n\tXORQ  x, h\n\tROLQ  $27, h\n\tIMULQ prime1, h\n\tADDQ  prime4, h\n\n\tCMPQ p, end\n\tJLE  loop8\n\ntry4:\n\tADDQ $4, end\n\tCMPQ p, end\n\tJG   try1\n\n\tMOVL  (p), x\n\tADDQ  $4, p\n\tIMULQ prime1, x\n\tXORQ  x, h\n\n\tROLQ  $23, h\n\tIMULQ prime2, h\n\tADDQ  ·primes+16(SB), h\n\ntry1:\n\tADDQ $4, end\n\tCMPQ p, end\n\tJGE  finalize\n\nloop1:\n\tMOVBQZX (p), x\n\tADDQ    $1, p\n\tIMULQ   ·primes+32(SB), x\n\tXORQ    x, h\n\tROLQ    $11, h\n\tIMULQ   prime1, h\n\n\tCMPQ p, end\n\tJL   loop1\n\nfinalize:\n\tMOVQ  h, x\n\tSHRQ  $33, x\n\tXORQ  x, h\n\tIMULQ prime2, h\n\tMOVQ  h, x\n\tSHRQ  $29, x\n\tXORQ  x, h\n\tIMULQ ·primes+16(SB), h\n\tMOVQ  h, x\n\tSHRQ  $32, x\n\tXORQ  x, h\n\n\tMOVQ h, ret+24(FP)\n\tRET\n\n// func writeBlocks(d *Digest, b []byte) int\nTEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40\n\t// Load fixed primes needed for round.\n\tMOVQ ·primes+0(SB), prime1\n\tMOVQ ·primes+8(SB), prime2\n\n\t// Load slice.\n\tMOVQ b_base+8(FP), p\n\tMOVQ b_len+16(FP), n\n\tLEAQ (p)(n*1), end\n\tSUBQ $32, end\n\n\t// Load vN from d.\n\tMOVQ s+0(FP), d\n\tMOVQ 0(d), v1\n\tMOVQ 8(d), v2\n\tMOVQ 16(d), v3\n\tMOVQ 24(d), v4\n\n\t// We don't need to check the loop condition here; this function is\n\t// always called with at least one block of data to process.\n\tblockLoop()\n\n\t// Copy vN back to d.\n\tMOVQ v1, 0(d)\n\tMOVQ v2, 8(d)\n\tMOVQ v3, 16(d)\n\tMOVQ v4, 24(d)\n\n\t// The number of bytes written is p minus the old base pointer.\n\tSUBQ b_base+8(FP), p\n\tMOVQ p, ret+32(FP)\n\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s",
    "content": "//go:build !appengine && gc && !purego && !noasm\n// +build !appengine\n// +build gc\n// +build !purego\n// +build !noasm\n\n#include \"textflag.h\"\n\n// Registers:\n#define digest\tR1\n#define h\tR2 // return value\n#define p\tR3 // input pointer\n#define n\tR4 // input length\n#define nblocks\tR5 // n / 32\n#define prime1\tR7\n#define prime2\tR8\n#define prime3\tR9\n#define prime4\tR10\n#define prime5\tR11\n#define v1\tR12\n#define v2\tR13\n#define v3\tR14\n#define v4\tR15\n#define x1\tR20\n#define x2\tR21\n#define x3\tR22\n#define x4\tR23\n\n#define round(acc, x) \\\n\tMADD prime2, acc, x, acc \\\n\tROR  $64-31, acc         \\\n\tMUL  prime1, acc\n\n// round0 performs the operation x = round(0, x).\n#define round0(x) \\\n\tMUL prime2, x \\\n\tROR $64-31, x \\\n\tMUL prime1, x\n\n#define mergeRound(acc, x) \\\n\tround0(x)                     \\\n\tEOR  x, acc                   \\\n\tMADD acc, prime4, prime1, acc\n\n// blockLoop processes as many 32-byte blocks as possible,\n// updating v1, v2, v3, and v4. It assumes that n >= 32.\n#define blockLoop() \\\n\tLSR     $5, n, nblocks  \\\n\tPCALIGN $16             \\\n\tloop:                   \\\n\tLDP.P   16(p), (x1, x2) \\\n\tLDP.P   16(p), (x3, x4) \\\n\tround(v1, x1)           \\\n\tround(v2, x2)           \\\n\tround(v3, x3)           \\\n\tround(v4, x4)           \\\n\tSUB     $1, nblocks     \\\n\tCBNZ    nblocks, loop\n\n// func Sum64(b []byte) uint64\nTEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32\n\tLDP b_base+0(FP), (p, n)\n\n\tLDP  ·primes+0(SB), (prime1, prime2)\n\tLDP  ·primes+16(SB), (prime3, prime4)\n\tMOVD ·primes+32(SB), prime5\n\n\tCMP  $32, n\n\tCSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 }\n\tBLT  afterLoop\n\n\tADD  prime1, prime2, v1\n\tMOVD prime2, v2\n\tMOVD $0, v3\n\tNEG  prime1, v4\n\n\tblockLoop()\n\n\tROR $64-1, v1, x1\n\tROR $64-7, v2, x2\n\tADD x1, x2\n\tROR $64-12, v3, x3\n\tROR $64-18, v4, x4\n\tADD x3, x4\n\tADD x2, x4, h\n\n\tmergeRound(h, v1)\n\tmergeRound(h, v2)\n\tmergeRound(h, v3)\n\tmergeRound(h, v4)\n\nafterLoop:\n\tADD n, h\n\n\tTBZ   $4, n, try8\n\tLDP.P 16(p), (x1, x2)\n\n\tround0(x1)\n\n\t// NOTE: here and below, sequencing the EOR after the ROR (using a\n\t// rotated register) is worth a small but measurable speedup for small\n\t// inputs.\n\tROR  $64-27, h\n\tEOR  x1 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\n\tround0(x2)\n\tROR  $64-27, h\n\tEOR  x2 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\ntry8:\n\tTBZ    $3, n, try4\n\tMOVD.P 8(p), x1\n\n\tround0(x1)\n\tROR  $64-27, h\n\tEOR  x1 @> 64-27, h, h\n\tMADD h, prime4, prime1, h\n\ntry4:\n\tTBZ     $2, n, try2\n\tMOVWU.P 4(p), x2\n\n\tMUL  prime1, x2\n\tROR  $64-23, h\n\tEOR  x2 @> 64-23, h, h\n\tMADD h, prime3, prime2, h\n\ntry2:\n\tTBZ     $1, n, try1\n\tMOVHU.P 2(p), x3\n\tAND     $255, x3, x1\n\tLSR     $8, x3, x2\n\n\tMUL prime5, x1\n\tROR $64-11, h\n\tEOR x1 @> 64-11, h, h\n\tMUL prime1, h\n\n\tMUL prime5, x2\n\tROR $64-11, h\n\tEOR x2 @> 64-11, h, h\n\tMUL prime1, h\n\ntry1:\n\tTBZ   $0, n, finalize\n\tMOVBU (p), x4\n\n\tMUL prime5, x4\n\tROR $64-11, h\n\tEOR x4 @> 64-11, h, h\n\tMUL prime1, h\n\nfinalize:\n\tEOR h >> 33, h\n\tMUL prime2, h\n\tEOR h >> 29, h\n\tMUL prime3, h\n\tEOR h >> 32, h\n\n\tMOVD h, ret+24(FP)\n\tRET\n\n// func writeBlocks(d *Digest, b []byte) int\nTEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40\n\tLDP ·primes+0(SB), (prime1, prime2)\n\n\t// Load state. Assume v[1-4] are stored contiguously.\n\tMOVD d+0(FP), digest\n\tLDP  0(digest), (v1, v2)\n\tLDP  16(digest), (v3, v4)\n\n\tLDP b_base+8(FP), (p, n)\n\n\tblockLoop()\n\n\t// Store updated state.\n\tSTP (v1, v2), 0(digest)\n\tSTP (v3, v4), 16(digest)\n\n\tBIC  $31, n\n\tMOVD n, ret+32(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go",
    "content": "//go:build (amd64 || arm64) && !appengine && gc && !purego && !noasm\n// +build amd64 arm64\n// +build !appengine\n// +build gc\n// +build !purego\n// +build !noasm\n\npackage xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b.\n//\n//go:noescape\nfunc Sum64(b []byte) uint64\n\n//go:noescape\nfunc writeBlocks(s *Digest, b []byte) int\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go",
    "content": "//go:build (!amd64 && !arm64) || appengine || !gc || purego || noasm\n// +build !amd64,!arm64 appengine !gc purego noasm\n\npackage xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b.\nfunc Sum64(b []byte) uint64 {\n\t// A simpler version would be\n\t//   d := New()\n\t//   d.Write(b)\n\t//   return d.Sum64()\n\t// but this is faster, particularly for small inputs.\n\n\tn := len(b)\n\tvar h uint64\n\n\tif n >= 32 {\n\t\tv1 := primes[0] + prime2\n\t\tv2 := prime2\n\t\tv3 := uint64(0)\n\t\tv4 := -primes[0]\n\t\tfor len(b) >= 32 {\n\t\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\t\tb = b[32:len(b):len(b)]\n\t\t}\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = prime5\n\t}\n\n\th += uint64(n)\n\n\tfor ; len(b) >= 8; b = b[8:] {\n\t\tk1 := round(0, u64(b[:8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif len(b) >= 4 {\n\t\th ^= uint64(u32(b[:4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\tb = b[4:]\n\t}\n\tfor ; len(b) > 0; b = b[1:] {\n\t\th ^= uint64(b[0]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nfunc writeBlocks(d *Digest, b []byte) int {\n\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\tn := len(b)\n\tfor len(b) >= 32 {\n\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\tb = b[32:len(b):len(b)]\n\t}\n\td.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4\n\treturn n - len(b)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_safe.go",
    "content": "package xxhash\n\n// Sum64String computes the 64-bit xxHash digest of s.\nfunc Sum64String(s string) uint64 {\n\treturn Sum64([]byte(s))\n}\n\n// WriteString adds more data to d. It always returns len(s), nil.\nfunc (d *Digest) WriteString(s string) (n int, err error) {\n\treturn d.Write([]byte(s))\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/matchlen_amd64.go",
    "content": "//go:build amd64 && !appengine && !noasm && gc\n// +build amd64,!appengine,!noasm,gc\n\n// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n\npackage zstd\n\n// matchLen returns how many bytes match in a and b\n//\n// It assumes that:\n//\n//\tlen(a) <= len(b) and len(a) > 0\n//\n//go:noescape\nfunc matchLen(a []byte, b []byte) int\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/matchlen_amd64.s",
    "content": "// Copied from S2 implementation.\n\n//go:build !appengine && !noasm && gc && !noasm\n\n#include \"textflag.h\"\n\n// func matchLen(a []byte, b []byte) int\n// Requires: BMI\nTEXT ·matchLen(SB), NOSPLIT, $0-56\n\tMOVQ a_base+0(FP), AX\n\tMOVQ b_base+24(FP), CX\n\tMOVQ a_len+8(FP), DX\n\n\t// matchLen\n\tXORL SI, SI\n\tCMPL DX, $0x08\n\tJB   matchlen_match4_standalone\n\nmatchlen_loopback_standalone:\n\tMOVQ  (AX)(SI*1), BX\n\tXORQ  (CX)(SI*1), BX\n\tTESTQ BX, BX\n\tJZ    matchlen_loop_standalone\n\n#ifdef GOAMD64_v3\n\tTZCNTQ BX, BX\n#else\n\tBSFQ BX, BX\n#endif\n\tSARQ $0x03, BX\n\tLEAL (SI)(BX*1), SI\n\tJMP  gen_match_len_end\n\nmatchlen_loop_standalone:\n\tLEAL -8(DX), DX\n\tLEAL 8(SI), SI\n\tCMPL DX, $0x08\n\tJAE  matchlen_loopback_standalone\n\nmatchlen_match4_standalone:\n\tCMPL DX, $0x04\n\tJB   matchlen_match2_standalone\n\tMOVL (AX)(SI*1), BX\n\tCMPL (CX)(SI*1), BX\n\tJNE  matchlen_match2_standalone\n\tLEAL -4(DX), DX\n\tLEAL 4(SI), SI\n\nmatchlen_match2_standalone:\n\tCMPL DX, $0x02\n\tJB   matchlen_match1_standalone\n\tMOVW (AX)(SI*1), BX\n\tCMPW (CX)(SI*1), BX\n\tJNE  matchlen_match1_standalone\n\tLEAL -2(DX), DX\n\tLEAL 2(SI), SI\n\nmatchlen_match1_standalone:\n\tCMPL DX, $0x01\n\tJB   gen_match_len_end\n\tMOVB (AX)(SI*1), BL\n\tCMPB (CX)(SI*1), BL\n\tJNE  gen_match_len_end\n\tINCL SI\n\ngen_match_len_end:\n\tMOVQ SI, ret+48(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/matchlen_generic.go",
    "content": "//go:build !amd64 || appengine || !gc || noasm\n// +build !amd64 appengine !gc noasm\n\n// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n\npackage zstd\n\nimport (\n\t\"encoding/binary\"\n\t\"math/bits\"\n)\n\n// matchLen returns the maximum common prefix length of a and b.\n// a must be the shortest of the two.\nfunc matchLen(a, b []byte) (n int) {\n\tfor ; len(a) >= 8 && len(b) >= 8; a, b = a[8:], b[8:] {\n\t\tdiff := binary.LittleEndian.Uint64(a) ^ binary.LittleEndian.Uint64(b)\n\t\tif diff != 0 {\n\t\t\treturn n + bits.TrailingZeros64(diff)>>3\n\t\t}\n\t\tn += 8\n\t}\n\n\tfor i := range a {\n\t\tif a[i] != b[i] {\n\t\t\tbreak\n\t\t}\n\t\tn++\n\t}\n\treturn n\n\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/seqdec.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\ntype seq struct {\n\tlitLen   uint32\n\tmatchLen uint32\n\toffset   uint32\n\n\t// Codes are stored here for the encoder\n\t// so they only have to be looked up once.\n\tllCode, mlCode, ofCode uint8\n}\n\ntype seqVals struct {\n\tll, ml, mo int\n}\n\nfunc (s seq) String() string {\n\tif s.offset <= 3 {\n\t\tif s.offset == 0 {\n\t\t\treturn fmt.Sprint(\"litLen:\", s.litLen, \", matchLen:\", s.matchLen+zstdMinMatch, \", offset: INVALID (0)\")\n\t\t}\n\t\treturn fmt.Sprint(\"litLen:\", s.litLen, \", matchLen:\", s.matchLen+zstdMinMatch, \", offset:\", s.offset, \" (repeat)\")\n\t}\n\treturn fmt.Sprint(\"litLen:\", s.litLen, \", matchLen:\", s.matchLen+zstdMinMatch, \", offset:\", s.offset-3, \" (new)\")\n}\n\ntype seqCompMode uint8\n\nconst (\n\tcompModePredefined seqCompMode = iota\n\tcompModeRLE\n\tcompModeFSE\n\tcompModeRepeat\n)\n\ntype sequenceDec struct {\n\t// decoder keeps track of the current state and updates it from the bitstream.\n\tfse    *fseDecoder\n\tstate  fseState\n\trepeat bool\n}\n\n// init the state of the decoder with input from stream.\nfunc (s *sequenceDec) init(br *bitReader) error {\n\tif s.fse == nil {\n\t\treturn errors.New(\"sequence decoder not defined\")\n\t}\n\ts.state.init(br, s.fse.actualTableLog, s.fse.dt[:1<<s.fse.actualTableLog])\n\treturn nil\n}\n\n// sequenceDecs contains all 3 sequence decoders and their state.\ntype sequenceDecs struct {\n\tlitLengths   sequenceDec\n\toffsets      sequenceDec\n\tmatchLengths sequenceDec\n\tprevOffset   [3]int\n\tdict         []byte\n\tliterals     []byte\n\tout          []byte\n\tnSeqs        int\n\tbr           *bitReader\n\tseqSize      int\n\twindowSize   int\n\tmaxBits      uint8\n\tmaxSyncLen   uint64\n}\n\n// initialize all 3 decoders from the stream input.\nfunc (s *sequenceDecs) initialize(br *bitReader, hist *history, out []byte) error {\n\tif err := s.litLengths.init(br); err != nil {\n\t\treturn errors.New(\"litLengths:\" + err.Error())\n\t}\n\tif err := s.offsets.init(br); err != nil {\n\t\treturn errors.New(\"offsets:\" + err.Error())\n\t}\n\tif err := s.matchLengths.init(br); err != nil {\n\t\treturn errors.New(\"matchLengths:\" + err.Error())\n\t}\n\ts.br = br\n\ts.prevOffset = hist.recentOffsets\n\ts.maxBits = s.litLengths.fse.maxBits + s.offsets.fse.maxBits + s.matchLengths.fse.maxBits\n\ts.windowSize = hist.windowSize\n\ts.out = out\n\ts.dict = nil\n\tif hist.dict != nil {\n\t\ts.dict = hist.dict.content\n\t}\n\treturn nil\n}\n\nfunc (s *sequenceDecs) freeDecoders() {\n\tif f := s.litLengths.fse; f != nil && !f.preDefined {\n\t\tfseDecoderPool.Put(f)\n\t\ts.litLengths.fse = nil\n\t}\n\tif f := s.offsets.fse; f != nil && !f.preDefined {\n\t\tfseDecoderPool.Put(f)\n\t\ts.offsets.fse = nil\n\t}\n\tif f := s.matchLengths.fse; f != nil && !f.preDefined {\n\t\tfseDecoderPool.Put(f)\n\t\ts.matchLengths.fse = nil\n\t}\n}\n\n// execute will execute the decoded sequence with the provided history.\n// The sequence must be evaluated before being sent.\nfunc (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error {\n\tif len(s.dict) == 0 {\n\t\treturn s.executeSimple(seqs, hist)\n\t}\n\n\t// Ensure we have enough output size...\n\tif len(s.out)+s.seqSize > cap(s.out) {\n\t\taddBytes := s.seqSize + len(s.out)\n\t\ts.out = append(s.out, make([]byte, addBytes)...)\n\t\ts.out = s.out[:len(s.out)-addBytes]\n\t}\n\n\tif debugDecoder {\n\t\tprintf(\"Execute %d seqs with hist %d, dict %d, literals: %d into %d bytes\\n\", len(seqs), len(hist), len(s.dict), len(s.literals), s.seqSize)\n\t}\n\n\tvar t = len(s.out)\n\tout := s.out[:t+s.seqSize]\n\n\tfor _, seq := range seqs {\n\t\t// Add literals\n\t\tcopy(out[t:], s.literals[:seq.ll])\n\t\tt += seq.ll\n\t\ts.literals = s.literals[seq.ll:]\n\n\t\t// Copy from dictionary...\n\t\tif seq.mo > t+len(hist) || seq.mo > s.windowSize {\n\t\t\tif len(s.dict) == 0 {\n\t\t\t\treturn fmt.Errorf(\"match offset (%d) bigger than current history (%d)\", seq.mo, t+len(hist))\n\t\t\t}\n\n\t\t\t// we may be in dictionary.\n\t\t\tdictO := len(s.dict) - (seq.mo - (t + len(hist)))\n\t\t\tif dictO < 0 || dictO >= len(s.dict) {\n\t\t\t\treturn fmt.Errorf(\"match offset (%d) bigger than current history+dict (%d)\", seq.mo, t+len(hist)+len(s.dict))\n\t\t\t}\n\t\t\tend := dictO + seq.ml\n\t\t\tif end > len(s.dict) {\n\t\t\t\tn := len(s.dict) - dictO\n\t\t\t\tcopy(out[t:], s.dict[dictO:])\n\t\t\t\tt += n\n\t\t\t\tseq.ml -= n\n\t\t\t} else {\n\t\t\t\tcopy(out[t:], s.dict[dictO:end])\n\t\t\t\tt += end - dictO\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Copy from history.\n\t\tif v := seq.mo - t; v > 0 {\n\t\t\t// v is the start position in history from end.\n\t\t\tstart := len(hist) - v\n\t\t\tif seq.ml > v {\n\t\t\t\t// Some goes into current block.\n\t\t\t\t// Copy remainder of history\n\t\t\t\tcopy(out[t:], hist[start:])\n\t\t\t\tt += v\n\t\t\t\tseq.ml -= v\n\t\t\t} else {\n\t\t\t\tcopy(out[t:], hist[start:start+seq.ml])\n\t\t\t\tt += seq.ml\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\t// We must be in current buffer now\n\t\tif seq.ml > 0 {\n\t\t\tstart := t - seq.mo\n\t\t\tif seq.ml <= t-start {\n\t\t\t\t// No overlap\n\t\t\t\tcopy(out[t:], out[start:start+seq.ml])\n\t\t\t\tt += seq.ml\n\t\t\t\tcontinue\n\t\t\t} else {\n\t\t\t\t// Overlapping copy\n\t\t\t\t// Extend destination slice and copy one byte at the time.\n\t\t\t\tsrc := out[start : start+seq.ml]\n\t\t\t\tdst := out[t:]\n\t\t\t\tdst = dst[:len(src)]\n\t\t\t\tt += len(src)\n\t\t\t\t// Destination is the space we just added.\n\t\t\t\tfor i := range src {\n\t\t\t\t\tdst[i] = src[i]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Add final literals\n\tcopy(out[t:], s.literals)\n\tif debugDecoder {\n\t\tt += len(s.literals)\n\t\tif t != len(out) {\n\t\t\tpanic(fmt.Errorf(\"length mismatch, want %d, got %d, ss: %d\", len(out), t, s.seqSize))\n\t\t}\n\t}\n\ts.out = out\n\n\treturn nil\n}\n\n// decode sequences from the stream with the provided history.\nfunc (s *sequenceDecs) decodeSync(hist []byte) error {\n\tsupported, err := s.decodeSyncSimple(hist)\n\tif supported {\n\t\treturn err\n\t}\n\n\tbr := s.br\n\tseqs := s.nSeqs\n\tstartSize := len(s.out)\n\t// Grab full sizes tables, to avoid bounds checks.\n\tllTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize]\n\tllState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state\n\tout := s.out\n\tmaxBlockSize := maxCompressedBlockSize\n\tif s.windowSize < maxBlockSize {\n\t\tmaxBlockSize = s.windowSize\n\t}\n\n\tif debugDecoder {\n\t\tprintln(\"decodeSync: decoding\", seqs, \"sequences\", br.remain(), \"bits remain on stream\")\n\t}\n\tfor i := seqs - 1; i >= 0; i-- {\n\t\tif br.overread() {\n\t\t\tprintf(\"reading sequence %d, exceeded available data. Overread by %d\\n\", seqs-i, -br.remain())\n\t\t\treturn io.ErrUnexpectedEOF\n\t\t}\n\t\tvar ll, mo, ml int\n\t\tif len(br.in) > 4+((maxOffsetBits+16+16)>>3) {\n\t\t\t// inlined function:\n\t\t\t// ll, mo, ml = s.nextFast(br, llState, mlState, ofState)\n\n\t\t\t// Final will not read from stream.\n\t\t\tvar llB, mlB, moB uint8\n\t\t\tll, llB = llState.final()\n\t\t\tml, mlB = mlState.final()\n\t\t\tmo, moB = ofState.final()\n\n\t\t\t// extra bits are stored in reverse order.\n\t\t\tbr.fillFast()\n\t\t\tmo += br.getBits(moB)\n\t\t\tif s.maxBits > 32 {\n\t\t\t\tbr.fillFast()\n\t\t\t}\n\t\t\tml += br.getBits(mlB)\n\t\t\tll += br.getBits(llB)\n\n\t\t\tif moB > 1 {\n\t\t\t\ts.prevOffset[2] = s.prevOffset[1]\n\t\t\t\ts.prevOffset[1] = s.prevOffset[0]\n\t\t\t\ts.prevOffset[0] = mo\n\t\t\t} else {\n\t\t\t\t// mo = s.adjustOffset(mo, ll, moB)\n\t\t\t\t// Inlined for rather big speedup\n\t\t\t\tif ll == 0 {\n\t\t\t\t\t// There is an exception though, when current sequence's literals_length = 0.\n\t\t\t\t\t// In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2,\n\t\t\t\t\t// an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte.\n\t\t\t\t\tmo++\n\t\t\t\t}\n\n\t\t\t\tif mo == 0 {\n\t\t\t\t\tmo = s.prevOffset[0]\n\t\t\t\t} else {\n\t\t\t\t\tvar temp int\n\t\t\t\t\tif mo == 3 {\n\t\t\t\t\t\ttemp = s.prevOffset[0] - 1\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttemp = s.prevOffset[mo]\n\t\t\t\t\t}\n\n\t\t\t\t\tif temp == 0 {\n\t\t\t\t\t\t// 0 is not valid; input is corrupted; force offset to 1\n\t\t\t\t\t\tprintln(\"WARNING: temp was 0\")\n\t\t\t\t\t\ttemp = 1\n\t\t\t\t\t}\n\n\t\t\t\t\tif mo != 1 {\n\t\t\t\t\t\ts.prevOffset[2] = s.prevOffset[1]\n\t\t\t\t\t}\n\t\t\t\t\ts.prevOffset[1] = s.prevOffset[0]\n\t\t\t\t\ts.prevOffset[0] = temp\n\t\t\t\t\tmo = temp\n\t\t\t\t}\n\t\t\t}\n\t\t\tbr.fillFast()\n\t\t} else {\n\t\t\tll, mo, ml = s.next(br, llState, mlState, ofState)\n\t\t\tbr.fill()\n\t\t}\n\n\t\tif debugSequences {\n\t\t\tprintln(\"Seq\", seqs-i-1, \"Litlen:\", ll, \"mo:\", mo, \"(abs) ml:\", ml)\n\t\t}\n\n\t\tif ll > len(s.literals) {\n\t\t\treturn fmt.Errorf(\"unexpected literal count, want %d bytes, but only %d is available\", ll, len(s.literals))\n\t\t}\n\t\tsize := ll + ml + len(out)\n\t\tif size-startSize > maxBlockSize {\n\t\t\treturn fmt.Errorf(\"output bigger than max block size (%d)\", maxBlockSize)\n\t\t}\n\t\tif size > cap(out) {\n\t\t\t// Not enough size, which can happen under high volume block streaming conditions\n\t\t\t// but could be if destination slice is too small for sync operations.\n\t\t\t// over-allocating here can create a large amount of GC pressure so we try to keep\n\t\t\t// it as contained as possible\n\t\t\tused := len(out) - startSize\n\t\t\taddBytes := 256 + ll + ml + used>>2\n\t\t\t// Clamp to max block size.\n\t\t\tif used+addBytes > maxBlockSize {\n\t\t\t\taddBytes = maxBlockSize - used\n\t\t\t}\n\t\t\tout = append(out, make([]byte, addBytes)...)\n\t\t\tout = out[:len(out)-addBytes]\n\t\t}\n\t\tif ml > maxMatchLen {\n\t\t\treturn fmt.Errorf(\"match len (%d) bigger than max allowed length\", ml)\n\t\t}\n\n\t\t// Add literals\n\t\tout = append(out, s.literals[:ll]...)\n\t\ts.literals = s.literals[ll:]\n\n\t\tif mo == 0 && ml > 0 {\n\t\t\treturn fmt.Errorf(\"zero matchoff and matchlen (%d) > 0\", ml)\n\t\t}\n\n\t\tif mo > len(out)+len(hist) || mo > s.windowSize {\n\t\t\tif len(s.dict) == 0 {\n\t\t\t\treturn fmt.Errorf(\"match offset (%d) bigger than current history (%d)\", mo, len(out)+len(hist)-startSize)\n\t\t\t}\n\n\t\t\t// we may be in dictionary.\n\t\t\tdictO := len(s.dict) - (mo - (len(out) + len(hist)))\n\t\t\tif dictO < 0 || dictO >= len(s.dict) {\n\t\t\t\treturn fmt.Errorf(\"match offset (%d) bigger than current history (%d)\", mo, len(out)+len(hist)-startSize)\n\t\t\t}\n\t\t\tend := dictO + ml\n\t\t\tif end > len(s.dict) {\n\t\t\t\tout = append(out, s.dict[dictO:]...)\n\t\t\t\tml -= len(s.dict) - dictO\n\t\t\t} else {\n\t\t\t\tout = append(out, s.dict[dictO:end]...)\n\t\t\t\tmo = 0\n\t\t\t\tml = 0\n\t\t\t}\n\t\t}\n\n\t\t// Copy from history.\n\t\t// TODO: Blocks without history could be made to ignore this completely.\n\t\tif v := mo - len(out); v > 0 {\n\t\t\t// v is the start position in history from end.\n\t\t\tstart := len(hist) - v\n\t\t\tif ml > v {\n\t\t\t\t// Some goes into current block.\n\t\t\t\t// Copy remainder of history\n\t\t\t\tout = append(out, hist[start:]...)\n\t\t\t\tml -= v\n\t\t\t} else {\n\t\t\t\tout = append(out, hist[start:start+ml]...)\n\t\t\t\tml = 0\n\t\t\t}\n\t\t}\n\t\t// We must be in current buffer now\n\t\tif ml > 0 {\n\t\t\tstart := len(out) - mo\n\t\t\tif ml <= len(out)-start {\n\t\t\t\t// No overlap\n\t\t\t\tout = append(out, out[start:start+ml]...)\n\t\t\t} else {\n\t\t\t\t// Overlapping copy\n\t\t\t\t// Extend destination slice and copy one byte at the time.\n\t\t\t\tout = out[:len(out)+ml]\n\t\t\t\tsrc := out[start : start+ml]\n\t\t\t\t// Destination is the space we just added.\n\t\t\t\tdst := out[len(out)-ml:]\n\t\t\t\tdst = dst[:len(src)]\n\t\t\t\tfor i := range src {\n\t\t\t\t\tdst[i] = src[i]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif i == 0 {\n\t\t\t// This is the last sequence, so we shouldn't update state.\n\t\t\tbreak\n\t\t}\n\n\t\t// Manually inlined, ~ 5-20% faster\n\t\t// Update all 3 states at once. Approx 20% faster.\n\t\tnBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits()\n\t\tif nBits == 0 {\n\t\t\tllState = llTable[llState.newState()&maxTableMask]\n\t\t\tmlState = mlTable[mlState.newState()&maxTableMask]\n\t\t\tofState = ofTable[ofState.newState()&maxTableMask]\n\t\t} else {\n\t\t\tbits := br.get32BitsFast(nBits)\n\n\t\t\tlowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31))\n\t\t\tllState = llTable[(llState.newState()+lowBits)&maxTableMask]\n\n\t\t\tlowBits = uint16(bits >> (ofState.nbBits() & 31))\n\t\t\tlowBits &= bitMask[mlState.nbBits()&15]\n\t\t\tmlState = mlTable[(mlState.newState()+lowBits)&maxTableMask]\n\n\t\t\tlowBits = uint16(bits) & bitMask[ofState.nbBits()&15]\n\t\t\tofState = ofTable[(ofState.newState()+lowBits)&maxTableMask]\n\t\t}\n\t}\n\n\tif size := len(s.literals) + len(out) - startSize; size > maxBlockSize {\n\t\treturn fmt.Errorf(\"output bigger than max block size (%d)\", maxBlockSize)\n\t}\n\n\t// Add final literals\n\ts.out = append(out, s.literals...)\n\treturn br.close()\n}\n\nvar bitMask [16]uint16\n\nfunc init() {\n\tfor i := range bitMask[:] {\n\t\tbitMask[i] = uint16((1 << uint(i)) - 1)\n\t}\n}\n\nfunc (s *sequenceDecs) next(br *bitReader, llState, mlState, ofState decSymbol) (ll, mo, ml int) {\n\t// Final will not read from stream.\n\tll, llB := llState.final()\n\tml, mlB := mlState.final()\n\tmo, moB := ofState.final()\n\n\t// extra bits are stored in reverse order.\n\tbr.fill()\n\tmo += br.getBits(moB)\n\tif s.maxBits > 32 {\n\t\tbr.fill()\n\t}\n\t// matchlength+literal length, max 32 bits\n\tml += br.getBits(mlB)\n\tll += br.getBits(llB)\n\tmo = s.adjustOffset(mo, ll, moB)\n\treturn\n}\n\nfunc (s *sequenceDecs) adjustOffset(offset, litLen int, offsetB uint8) int {\n\tif offsetB > 1 {\n\t\ts.prevOffset[2] = s.prevOffset[1]\n\t\ts.prevOffset[1] = s.prevOffset[0]\n\t\ts.prevOffset[0] = offset\n\t\treturn offset\n\t}\n\n\tif litLen == 0 {\n\t\t// There is an exception though, when current sequence's literals_length = 0.\n\t\t// In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2,\n\t\t// an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte.\n\t\toffset++\n\t}\n\n\tif offset == 0 {\n\t\treturn s.prevOffset[0]\n\t}\n\tvar temp int\n\tif offset == 3 {\n\t\ttemp = s.prevOffset[0] - 1\n\t} else {\n\t\ttemp = s.prevOffset[offset]\n\t}\n\n\tif temp == 0 {\n\t\t// 0 is not valid; input is corrupted; force offset to 1\n\t\tprintln(\"temp was 0\")\n\t\ttemp = 1\n\t}\n\n\tif offset != 1 {\n\t\ts.prevOffset[2] = s.prevOffset[1]\n\t}\n\ts.prevOffset[1] = s.prevOffset[0]\n\ts.prevOffset[0] = temp\n\treturn temp\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go",
    "content": "//go:build amd64 && !appengine && !noasm && gc\n// +build amd64,!appengine,!noasm,gc\n\npackage zstd\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/klauspost/compress/internal/cpuinfo\"\n)\n\ntype decodeSyncAsmContext struct {\n\tllTable     []decSymbol\n\tmlTable     []decSymbol\n\tofTable     []decSymbol\n\tllState     uint64\n\tmlState     uint64\n\tofState     uint64\n\titeration   int\n\tlitRemain   int\n\tout         []byte\n\toutPosition int\n\tliterals    []byte\n\tlitPosition int\n\thistory     []byte\n\twindowSize  int\n\tll          int // set on error (not for all errors, please refer to _generate/gen.go)\n\tml          int // set on error (not for all errors, please refer to _generate/gen.go)\n\tmo          int // set on error (not for all errors, please refer to _generate/gen.go)\n}\n\n// sequenceDecs_decodeSync_amd64 implements the main loop of sequenceDecs.decodeSync in x86 asm.\n//\n// Please refer to seqdec_generic.go for the reference implementation.\n//\n//go:noescape\nfunc sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n\n// sequenceDecs_decodeSync_bmi2 implements the main loop of sequenceDecs.decodeSync in x86 asm with BMI2 extensions.\n//\n//go:noescape\nfunc sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n\n// sequenceDecs_decodeSync_safe_amd64 does the same as above, but does not write more than output buffer.\n//\n//go:noescape\nfunc sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n\n// sequenceDecs_decodeSync_safe_bmi2 does the same as above, but does not write more than output buffer.\n//\n//go:noescape\nfunc sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n\n// decode sequences from the stream with the provided history but without a dictionary.\nfunc (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {\n\tif len(s.dict) > 0 {\n\t\treturn false, nil\n\t}\n\tif s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSize {\n\t\treturn false, nil\n\t}\n\n\t// FIXME: Using unsafe memory copies leads to rare, random crashes\n\t// with fuzz testing. It is therefore disabled for now.\n\tconst useSafe = true\n\t/*\n\t\tuseSafe := false\n\t\tif s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc {\n\t\t\tuseSafe = true\n\t\t}\n\t\tif s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) {\n\t\t\tuseSafe = true\n\t\t}\n\t\tif cap(s.literals) < len(s.literals)+compressedBlockOverAlloc {\n\t\t\tuseSafe = true\n\t\t}\n\t*/\n\n\tbr := s.br\n\n\tmaxBlockSize := maxCompressedBlockSize\n\tif s.windowSize < maxBlockSize {\n\t\tmaxBlockSize = s.windowSize\n\t}\n\n\tctx := decodeSyncAsmContext{\n\t\tllTable:     s.litLengths.fse.dt[:maxTablesize],\n\t\tmlTable:     s.matchLengths.fse.dt[:maxTablesize],\n\t\tofTable:     s.offsets.fse.dt[:maxTablesize],\n\t\tllState:     uint64(s.litLengths.state.state),\n\t\tmlState:     uint64(s.matchLengths.state.state),\n\t\tofState:     uint64(s.offsets.state.state),\n\t\titeration:   s.nSeqs - 1,\n\t\tlitRemain:   len(s.literals),\n\t\tout:         s.out,\n\t\toutPosition: len(s.out),\n\t\tliterals:    s.literals,\n\t\twindowSize:  s.windowSize,\n\t\thistory:     hist,\n\t}\n\n\ts.seqSize = 0\n\tstartSize := len(s.out)\n\n\tvar errCode int\n\tif cpuinfo.HasBMI2() {\n\t\tif useSafe {\n\t\t\terrCode = sequenceDecs_decodeSync_safe_bmi2(s, br, &ctx)\n\t\t} else {\n\t\t\terrCode = sequenceDecs_decodeSync_bmi2(s, br, &ctx)\n\t\t}\n\t} else {\n\t\tif useSafe {\n\t\t\terrCode = sequenceDecs_decodeSync_safe_amd64(s, br, &ctx)\n\t\t} else {\n\t\t\terrCode = sequenceDecs_decodeSync_amd64(s, br, &ctx)\n\t\t}\n\t}\n\tswitch errCode {\n\tcase noError:\n\t\tbreak\n\n\tcase errorMatchLenOfsMismatch:\n\t\treturn true, fmt.Errorf(\"zero matchoff and matchlen (%d) > 0\", ctx.ml)\n\n\tcase errorMatchLenTooBig:\n\t\treturn true, fmt.Errorf(\"match len (%d) bigger than max allowed length\", ctx.ml)\n\n\tcase errorMatchOffTooBig:\n\t\treturn true, fmt.Errorf(\"match offset (%d) bigger than current history (%d)\",\n\t\t\tctx.mo, ctx.outPosition+len(hist)-startSize)\n\n\tcase errorNotEnoughLiterals:\n\t\treturn true, fmt.Errorf(\"unexpected literal count, want %d bytes, but only %d is available\",\n\t\t\tctx.ll, ctx.litRemain+ctx.ll)\n\n\tcase errorOverread:\n\t\treturn true, io.ErrUnexpectedEOF\n\n\tcase errorNotEnoughSpace:\n\t\tsize := ctx.outPosition + ctx.ll + ctx.ml\n\t\tif debugDecoder {\n\t\t\tprintln(\"msl:\", s.maxSyncLen, \"cap\", cap(s.out), \"bef:\", startSize, \"sz:\", size-startSize, \"mbs:\", maxBlockSize, \"outsz:\", cap(s.out)-startSize)\n\t\t}\n\t\treturn true, fmt.Errorf(\"output bigger than max block size (%d)\", maxBlockSize)\n\n\tdefault:\n\t\treturn true, fmt.Errorf(\"sequenceDecs_decode returned erronous code %d\", errCode)\n\t}\n\n\ts.seqSize += ctx.litRemain\n\tif s.seqSize > maxBlockSize {\n\t\treturn true, fmt.Errorf(\"output bigger than max block size (%d)\", maxBlockSize)\n\t}\n\terr := br.close()\n\tif err != nil {\n\t\tprintf(\"Closing sequences: %v, %+v\\n\", err, *br)\n\t\treturn true, err\n\t}\n\n\ts.literals = s.literals[ctx.litPosition:]\n\tt := ctx.outPosition\n\ts.out = s.out[:t]\n\n\t// Add final literals\n\ts.out = append(s.out, s.literals...)\n\tif debugDecoder {\n\t\tt += len(s.literals)\n\t\tif t != len(s.out) {\n\t\t\tpanic(fmt.Errorf(\"length mismatch, want %d, got %d\", len(s.out), t))\n\t\t}\n\t}\n\n\treturn true, nil\n}\n\n// --------------------------------------------------------------------------------\n\ntype decodeAsmContext struct {\n\tllTable   []decSymbol\n\tmlTable   []decSymbol\n\tofTable   []decSymbol\n\tllState   uint64\n\tmlState   uint64\n\tofState   uint64\n\titeration int\n\tseqs      []seqVals\n\tlitRemain int\n}\n\nconst noError = 0\n\n// error reported when mo == 0 && ml > 0\nconst errorMatchLenOfsMismatch = 1\n\n// error reported when ml > maxMatchLen\nconst errorMatchLenTooBig = 2\n\n// error reported when mo > available history or mo > s.windowSize\nconst errorMatchOffTooBig = 3\n\n// error reported when the sum of literal lengths exeeceds the literal buffer size\nconst errorNotEnoughLiterals = 4\n\n// error reported when capacity of `out` is too small\nconst errorNotEnoughSpace = 5\n\n// error reported when bits are overread.\nconst errorOverread = 6\n\n// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm.\n//\n// Please refer to seqdec_generic.go for the reference implementation.\n//\n//go:noescape\nfunc sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n\n// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm.\n//\n// Please refer to seqdec_generic.go for the reference implementation.\n//\n//go:noescape\nfunc sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n\n// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions.\n//\n//go:noescape\nfunc sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n\n// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions.\n//\n//go:noescape\nfunc sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n\n// decode sequences from the stream without the provided history.\nfunc (s *sequenceDecs) decode(seqs []seqVals) error {\n\tbr := s.br\n\n\tmaxBlockSize := maxCompressedBlockSize\n\tif s.windowSize < maxBlockSize {\n\t\tmaxBlockSize = s.windowSize\n\t}\n\n\tctx := decodeAsmContext{\n\t\tllTable:   s.litLengths.fse.dt[:maxTablesize],\n\t\tmlTable:   s.matchLengths.fse.dt[:maxTablesize],\n\t\tofTable:   s.offsets.fse.dt[:maxTablesize],\n\t\tllState:   uint64(s.litLengths.state.state),\n\t\tmlState:   uint64(s.matchLengths.state.state),\n\t\tofState:   uint64(s.offsets.state.state),\n\t\tseqs:      seqs,\n\t\titeration: len(seqs) - 1,\n\t\tlitRemain: len(s.literals),\n\t}\n\n\tif debugDecoder {\n\t\tprintln(\"decode: decoding\", len(seqs), \"sequences\", br.remain(), \"bits remain on stream\")\n\t}\n\n\ts.seqSize = 0\n\tlte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56\n\tvar errCode int\n\tif cpuinfo.HasBMI2() {\n\t\tif lte56bits {\n\t\t\terrCode = sequenceDecs_decode_56_bmi2(s, br, &ctx)\n\t\t} else {\n\t\t\terrCode = sequenceDecs_decode_bmi2(s, br, &ctx)\n\t\t}\n\t} else {\n\t\tif lte56bits {\n\t\t\terrCode = sequenceDecs_decode_56_amd64(s, br, &ctx)\n\t\t} else {\n\t\t\terrCode = sequenceDecs_decode_amd64(s, br, &ctx)\n\t\t}\n\t}\n\tif errCode != 0 {\n\t\ti := len(seqs) - ctx.iteration - 1\n\t\tswitch errCode {\n\t\tcase errorMatchLenOfsMismatch:\n\t\t\tml := ctx.seqs[i].ml\n\t\t\treturn fmt.Errorf(\"zero matchoff and matchlen (%d) > 0\", ml)\n\n\t\tcase errorMatchLenTooBig:\n\t\t\tml := ctx.seqs[i].ml\n\t\t\treturn fmt.Errorf(\"match len (%d) bigger than max allowed length\", ml)\n\n\t\tcase errorNotEnoughLiterals:\n\t\t\tll := ctx.seqs[i].ll\n\t\t\treturn fmt.Errorf(\"unexpected literal count, want %d bytes, but only %d is available\", ll, ctx.litRemain+ll)\n\t\tcase errorOverread:\n\t\t\treturn io.ErrUnexpectedEOF\n\t\t}\n\n\t\treturn fmt.Errorf(\"sequenceDecs_decode_amd64 returned erronous code %d\", errCode)\n\t}\n\n\tif ctx.litRemain < 0 {\n\t\treturn fmt.Errorf(\"literal count is too big: total available %d, total requested %d\",\n\t\t\tlen(s.literals), len(s.literals)-ctx.litRemain)\n\t}\n\n\ts.seqSize += ctx.litRemain\n\tif s.seqSize > maxBlockSize {\n\t\treturn fmt.Errorf(\"output bigger than max block size (%d)\", maxBlockSize)\n\t}\n\tif debugDecoder {\n\t\tprintln(\"decode: \", br.remain(), \"bits remain on stream. code:\", errCode)\n\t}\n\terr := br.close()\n\tif err != nil {\n\t\tprintf(\"Closing sequences: %v, %+v\\n\", err, *br)\n\t}\n\treturn err\n}\n\n// --------------------------------------------------------------------------------\n\ntype executeAsmContext struct {\n\tseqs        []seqVals\n\tseqIndex    int\n\tout         []byte\n\thistory     []byte\n\tliterals    []byte\n\toutPosition int\n\tlitPosition int\n\twindowSize  int\n}\n\n// sequenceDecs_executeSimple_amd64 implements the main loop of sequenceDecs.executeSimple in x86 asm.\n//\n// Returns false if a match offset is too big.\n//\n// Please refer to seqdec_generic.go for the reference implementation.\n//\n//go:noescape\nfunc sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool\n\n// Same as above, but with safe memcopies\n//\n//go:noescape\nfunc sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool\n\n// executeSimple handles cases when dictionary is not used.\nfunc (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error {\n\t// Ensure we have enough output size...\n\tif len(s.out)+s.seqSize+compressedBlockOverAlloc > cap(s.out) {\n\t\taddBytes := s.seqSize + len(s.out) + compressedBlockOverAlloc\n\t\ts.out = append(s.out, make([]byte, addBytes)...)\n\t\ts.out = s.out[:len(s.out)-addBytes]\n\t}\n\n\tif debugDecoder {\n\t\tprintf(\"Execute %d seqs with literals: %d into %d bytes\\n\", len(seqs), len(s.literals), s.seqSize)\n\t}\n\n\tvar t = len(s.out)\n\tout := s.out[:t+s.seqSize]\n\n\tctx := executeAsmContext{\n\t\tseqs:        seqs,\n\t\tseqIndex:    0,\n\t\tout:         out,\n\t\thistory:     hist,\n\t\toutPosition: t,\n\t\tlitPosition: 0,\n\t\tliterals:    s.literals,\n\t\twindowSize:  s.windowSize,\n\t}\n\tvar ok bool\n\tif cap(s.literals) < len(s.literals)+compressedBlockOverAlloc {\n\t\tok = sequenceDecs_executeSimple_safe_amd64(&ctx)\n\t} else {\n\t\tok = sequenceDecs_executeSimple_amd64(&ctx)\n\t}\n\tif !ok {\n\t\treturn fmt.Errorf(\"match offset (%d) bigger than current history (%d)\",\n\t\t\tseqs[ctx.seqIndex].mo, ctx.outPosition+len(hist))\n\t}\n\ts.literals = s.literals[ctx.litPosition:]\n\tt = ctx.outPosition\n\n\t// Add final literals\n\tcopy(out[t:], s.literals)\n\tif debugDecoder {\n\t\tt += len(s.literals)\n\t\tif t != len(out) {\n\t\t\tpanic(fmt.Errorf(\"length mismatch, want %d, got %d, ss: %d\", len(out), t, s.seqSize))\n\t\t}\n\t}\n\ts.out = out\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s",
    "content": "// Code generated by command: go run gen.go -out ../seqdec_amd64.s -pkg=zstd. DO NOT EDIT.\n\n//go:build !appengine && !noasm && gc && !noasm\n\n// func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n// Requires: CMOV\nTEXT ·sequenceDecs_decode_amd64(SB), $8-32\n\tMOVQ    br+8(FP), CX\n\tMOVQ    24(CX), DX\n\tMOVBQZX 32(CX), BX\n\tMOVQ    (CX), AX\n\tMOVQ    8(CX), SI\n\tADDQ    SI, AX\n\tMOVQ    AX, (SP)\n\tMOVQ    ctx+16(FP), AX\n\tMOVQ    72(AX), DI\n\tMOVQ    80(AX), R8\n\tMOVQ    88(AX), R9\n\tMOVQ    104(AX), R10\n\tMOVQ    s+0(FP), AX\n\tMOVQ    144(AX), R11\n\tMOVQ    152(AX), R12\n\tMOVQ    160(AX), R13\n\nsequenceDecs_decode_amd64_main_loop:\n\tMOVQ (SP), R14\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ SI, $0x08\n\tJL   sequenceDecs_decode_amd64_fill_byte_by_byte\n\tMOVQ BX, AX\n\tSHRQ $0x03, AX\n\tSUBQ AX, R14\n\tMOVQ (R14), DX\n\tSUBQ AX, SI\n\tANDQ $0x07, BX\n\tJMP  sequenceDecs_decode_amd64_fill_end\n\nsequenceDecs_decode_amd64_fill_byte_by_byte:\n\tCMPQ    SI, $0x00\n\tJLE     sequenceDecs_decode_amd64_fill_check_overread\n\tCMPQ    BX, $0x07\n\tJLE     sequenceDecs_decode_amd64_fill_end\n\tSHLQ    $0x08, DX\n\tSUBQ    $0x01, R14\n\tSUBQ    $0x01, SI\n\tSUBQ    $0x08, BX\n\tMOVBQZX (R14), AX\n\tORQ     AX, DX\n\tJMP     sequenceDecs_decode_amd64_fill_byte_by_byte\n\nsequenceDecs_decode_amd64_fill_check_overread:\n\tCMPQ BX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decode_amd64_fill_end:\n\t// Update offset\n\tMOVQ  R9, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R15\n\tSHLQ  CL, R15\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decode_amd64_of_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decode_amd64_of_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decode_amd64_of_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R15\n\tADDQ  R15, AX\n\nsequenceDecs_decode_amd64_of_update_zero:\n\tMOVQ AX, 16(R10)\n\n\t// Update match length\n\tMOVQ  R8, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R15\n\tSHLQ  CL, R15\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decode_amd64_ml_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decode_amd64_ml_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decode_amd64_ml_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R15\n\tADDQ  R15, AX\n\nsequenceDecs_decode_amd64_ml_update_zero:\n\tMOVQ AX, 8(R10)\n\n\t// Fill bitreader to have enough for the remaining\n\tCMPQ SI, $0x08\n\tJL   sequenceDecs_decode_amd64_fill_2_byte_by_byte\n\tMOVQ BX, AX\n\tSHRQ $0x03, AX\n\tSUBQ AX, R14\n\tMOVQ (R14), DX\n\tSUBQ AX, SI\n\tANDQ $0x07, BX\n\tJMP  sequenceDecs_decode_amd64_fill_2_end\n\nsequenceDecs_decode_amd64_fill_2_byte_by_byte:\n\tCMPQ    SI, $0x00\n\tJLE     sequenceDecs_decode_amd64_fill_2_check_overread\n\tCMPQ    BX, $0x07\n\tJLE     sequenceDecs_decode_amd64_fill_2_end\n\tSHLQ    $0x08, DX\n\tSUBQ    $0x01, R14\n\tSUBQ    $0x01, SI\n\tSUBQ    $0x08, BX\n\tMOVBQZX (R14), AX\n\tORQ     AX, DX\n\tJMP     sequenceDecs_decode_amd64_fill_2_byte_by_byte\n\nsequenceDecs_decode_amd64_fill_2_check_overread:\n\tCMPQ BX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decode_amd64_fill_2_end:\n\t// Update literal length\n\tMOVQ  DI, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R15\n\tSHLQ  CL, R15\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decode_amd64_ll_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decode_amd64_ll_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decode_amd64_ll_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R15\n\tADDQ  R15, AX\n\nsequenceDecs_decode_amd64_ll_update_zero:\n\tMOVQ AX, (R10)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R14, (SP)\n\tMOVQ    R9, AX\n\tSHRQ    $0x08, AX\n\tMOVBQZX AL, AX\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decode_amd64_skip_update\n\n\t// Update Literal Length State\n\tMOVBQZX DI, R14\n\tSHRQ    $0x10, DI\n\tMOVWQZX DI, DI\n\tLEAQ    (BX)(R14*1), CX\n\tMOVQ    DX, R15\n\tMOVQ    CX, BX\n\tROLQ    CL, R15\n\tMOVL    $0x00000001, BP\n\tMOVB    R14, CL\n\tSHLL    CL, BP\n\tDECL    BP\n\tANDQ    BP, R15\n\tADDQ    R15, DI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Match Length State\n\tMOVBQZX R8, R14\n\tSHRQ    $0x10, R8\n\tMOVWQZX R8, R8\n\tLEAQ    (BX)(R14*1), CX\n\tMOVQ    DX, R15\n\tMOVQ    CX, BX\n\tROLQ    CL, R15\n\tMOVL    $0x00000001, BP\n\tMOVB    R14, CL\n\tSHLL    CL, BP\n\tDECL    BP\n\tANDQ    BP, R15\n\tADDQ    R15, R8\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Offset State\n\tMOVBQZX R9, R14\n\tSHRQ    $0x10, R9\n\tMOVWQZX R9, R9\n\tLEAQ    (BX)(R14*1), CX\n\tMOVQ    DX, R15\n\tMOVQ    CX, BX\n\tROLQ    CL, R15\n\tMOVL    $0x00000001, BP\n\tMOVB    R14, CL\n\tSHLL    CL, BP\n\tDECL    BP\n\tANDQ    BP, R15\n\tADDQ    R15, R9\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R9*8), R9\n\nsequenceDecs_decode_amd64_skip_update:\n\t// Adjust offset\n\tMOVQ 16(R10), CX\n\tCMPQ AX, $0x01\n\tJBE  sequenceDecs_decode_amd64_adjust_offsetB_1_or_0\n\tMOVQ R12, R13\n\tMOVQ R11, R12\n\tMOVQ CX, R11\n\tJMP  sequenceDecs_decode_amd64_after_adjust\n\nsequenceDecs_decode_amd64_adjust_offsetB_1_or_0:\n\tCMPQ (R10), $0x00000000\n\tJNE  sequenceDecs_decode_amd64_adjust_offset_maybezero\n\tINCQ CX\n\tJMP  sequenceDecs_decode_amd64_adjust_offset_nonzero\n\nsequenceDecs_decode_amd64_adjust_offset_maybezero:\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_amd64_adjust_offset_nonzero\n\tMOVQ  R11, CX\n\tJMP   sequenceDecs_decode_amd64_after_adjust\n\nsequenceDecs_decode_amd64_adjust_offset_nonzero:\n\tCMPQ CX, $0x01\n\tJB   sequenceDecs_decode_amd64_adjust_zero\n\tJEQ  sequenceDecs_decode_amd64_adjust_one\n\tCMPQ CX, $0x02\n\tJA   sequenceDecs_decode_amd64_adjust_three\n\tJMP  sequenceDecs_decode_amd64_adjust_two\n\nsequenceDecs_decode_amd64_adjust_zero:\n\tMOVQ R11, AX\n\tJMP  sequenceDecs_decode_amd64_adjust_test_temp_valid\n\nsequenceDecs_decode_amd64_adjust_one:\n\tMOVQ R12, AX\n\tJMP  sequenceDecs_decode_amd64_adjust_test_temp_valid\n\nsequenceDecs_decode_amd64_adjust_two:\n\tMOVQ R13, AX\n\tJMP  sequenceDecs_decode_amd64_adjust_test_temp_valid\n\nsequenceDecs_decode_amd64_adjust_three:\n\tLEAQ -1(R11), AX\n\nsequenceDecs_decode_amd64_adjust_test_temp_valid:\n\tTESTQ AX, AX\n\tJNZ   sequenceDecs_decode_amd64_adjust_temp_valid\n\tMOVQ  $0x00000001, AX\n\nsequenceDecs_decode_amd64_adjust_temp_valid:\n\tCMPQ    CX, $0x01\n\tCMOVQNE R12, R13\n\tMOVQ    R11, R12\n\tMOVQ    AX, R11\n\tMOVQ    AX, CX\n\nsequenceDecs_decode_amd64_after_adjust:\n\tMOVQ CX, 16(R10)\n\n\t// Check values\n\tMOVQ  8(R10), AX\n\tMOVQ  (R10), R14\n\tLEAQ  (AX)(R14*1), R15\n\tMOVQ  s+0(FP), BP\n\tADDQ  R15, 256(BP)\n\tMOVQ  ctx+16(FP), R15\n\tSUBQ  R14, 128(R15)\n\tJS    error_not_enough_literals\n\tCMPQ  AX, $0x00020002\n\tJA    sequenceDecs_decode_amd64_error_match_len_too_big\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_amd64_match_len_ofs_ok\n\tTESTQ AX, AX\n\tJNZ   sequenceDecs_decode_amd64_error_match_len_ofs_mismatch\n\nsequenceDecs_decode_amd64_match_len_ofs_ok:\n\tADDQ $0x18, R10\n\tMOVQ ctx+16(FP), AX\n\tDECQ 96(AX)\n\tJNS  sequenceDecs_decode_amd64_main_loop\n\tMOVQ s+0(FP), AX\n\tMOVQ R11, 144(AX)\n\tMOVQ R12, 152(AX)\n\tMOVQ R13, 160(AX)\n\tMOVQ br+8(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVB BL, 32(AX)\n\tMOVQ SI, 8(AX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decode_amd64_error_match_len_ofs_mismatch:\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decode_amd64_error_match_len_too_big:\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n// func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n// Requires: CMOV\nTEXT ·sequenceDecs_decode_56_amd64(SB), $8-32\n\tMOVQ    br+8(FP), CX\n\tMOVQ    24(CX), DX\n\tMOVBQZX 32(CX), BX\n\tMOVQ    (CX), AX\n\tMOVQ    8(CX), SI\n\tADDQ    SI, AX\n\tMOVQ    AX, (SP)\n\tMOVQ    ctx+16(FP), AX\n\tMOVQ    72(AX), DI\n\tMOVQ    80(AX), R8\n\tMOVQ    88(AX), R9\n\tMOVQ    104(AX), R10\n\tMOVQ    s+0(FP), AX\n\tMOVQ    144(AX), R11\n\tMOVQ    152(AX), R12\n\tMOVQ    160(AX), R13\n\nsequenceDecs_decode_56_amd64_main_loop:\n\tMOVQ (SP), R14\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ SI, $0x08\n\tJL   sequenceDecs_decode_56_amd64_fill_byte_by_byte\n\tMOVQ BX, AX\n\tSHRQ $0x03, AX\n\tSUBQ AX, R14\n\tMOVQ (R14), DX\n\tSUBQ AX, SI\n\tANDQ $0x07, BX\n\tJMP  sequenceDecs_decode_56_amd64_fill_end\n\nsequenceDecs_decode_56_amd64_fill_byte_by_byte:\n\tCMPQ    SI, $0x00\n\tJLE     sequenceDecs_decode_56_amd64_fill_check_overread\n\tCMPQ    BX, $0x07\n\tJLE     sequenceDecs_decode_56_amd64_fill_end\n\tSHLQ    $0x08, DX\n\tSUBQ    $0x01, R14\n\tSUBQ    $0x01, SI\n\tSUBQ    $0x08, BX\n\tMOVBQZX (R14), AX\n\tORQ     AX, DX\n\tJMP     sequenceDecs_decode_56_amd64_fill_byte_by_byte\n\nsequenceDecs_decode_56_amd64_fill_check_overread:\n\tCMPQ BX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decode_56_amd64_fill_end:\n\t// Update offset\n\tMOVQ  R9, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R15\n\tSHLQ  CL, R15\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decode_56_amd64_of_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decode_56_amd64_of_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decode_56_amd64_of_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R15\n\tADDQ  R15, AX\n\nsequenceDecs_decode_56_amd64_of_update_zero:\n\tMOVQ AX, 16(R10)\n\n\t// Update match length\n\tMOVQ  R8, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R15\n\tSHLQ  CL, R15\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decode_56_amd64_ml_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decode_56_amd64_ml_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decode_56_amd64_ml_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R15\n\tADDQ  R15, AX\n\nsequenceDecs_decode_56_amd64_ml_update_zero:\n\tMOVQ AX, 8(R10)\n\n\t// Update literal length\n\tMOVQ  DI, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R15\n\tSHLQ  CL, R15\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decode_56_amd64_ll_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decode_56_amd64_ll_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decode_56_amd64_ll_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R15\n\tADDQ  R15, AX\n\nsequenceDecs_decode_56_amd64_ll_update_zero:\n\tMOVQ AX, (R10)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R14, (SP)\n\tMOVQ    R9, AX\n\tSHRQ    $0x08, AX\n\tMOVBQZX AL, AX\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decode_56_amd64_skip_update\n\n\t// Update Literal Length State\n\tMOVBQZX DI, R14\n\tSHRQ    $0x10, DI\n\tMOVWQZX DI, DI\n\tLEAQ    (BX)(R14*1), CX\n\tMOVQ    DX, R15\n\tMOVQ    CX, BX\n\tROLQ    CL, R15\n\tMOVL    $0x00000001, BP\n\tMOVB    R14, CL\n\tSHLL    CL, BP\n\tDECL    BP\n\tANDQ    BP, R15\n\tADDQ    R15, DI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Match Length State\n\tMOVBQZX R8, R14\n\tSHRQ    $0x10, R8\n\tMOVWQZX R8, R8\n\tLEAQ    (BX)(R14*1), CX\n\tMOVQ    DX, R15\n\tMOVQ    CX, BX\n\tROLQ    CL, R15\n\tMOVL    $0x00000001, BP\n\tMOVB    R14, CL\n\tSHLL    CL, BP\n\tDECL    BP\n\tANDQ    BP, R15\n\tADDQ    R15, R8\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Offset State\n\tMOVBQZX R9, R14\n\tSHRQ    $0x10, R9\n\tMOVWQZX R9, R9\n\tLEAQ    (BX)(R14*1), CX\n\tMOVQ    DX, R15\n\tMOVQ    CX, BX\n\tROLQ    CL, R15\n\tMOVL    $0x00000001, BP\n\tMOVB    R14, CL\n\tSHLL    CL, BP\n\tDECL    BP\n\tANDQ    BP, R15\n\tADDQ    R15, R9\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R9*8), R9\n\nsequenceDecs_decode_56_amd64_skip_update:\n\t// Adjust offset\n\tMOVQ 16(R10), CX\n\tCMPQ AX, $0x01\n\tJBE  sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0\n\tMOVQ R12, R13\n\tMOVQ R11, R12\n\tMOVQ CX, R11\n\tJMP  sequenceDecs_decode_56_amd64_after_adjust\n\nsequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0:\n\tCMPQ (R10), $0x00000000\n\tJNE  sequenceDecs_decode_56_amd64_adjust_offset_maybezero\n\tINCQ CX\n\tJMP  sequenceDecs_decode_56_amd64_adjust_offset_nonzero\n\nsequenceDecs_decode_56_amd64_adjust_offset_maybezero:\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_56_amd64_adjust_offset_nonzero\n\tMOVQ  R11, CX\n\tJMP   sequenceDecs_decode_56_amd64_after_adjust\n\nsequenceDecs_decode_56_amd64_adjust_offset_nonzero:\n\tCMPQ CX, $0x01\n\tJB   sequenceDecs_decode_56_amd64_adjust_zero\n\tJEQ  sequenceDecs_decode_56_amd64_adjust_one\n\tCMPQ CX, $0x02\n\tJA   sequenceDecs_decode_56_amd64_adjust_three\n\tJMP  sequenceDecs_decode_56_amd64_adjust_two\n\nsequenceDecs_decode_56_amd64_adjust_zero:\n\tMOVQ R11, AX\n\tJMP  sequenceDecs_decode_56_amd64_adjust_test_temp_valid\n\nsequenceDecs_decode_56_amd64_adjust_one:\n\tMOVQ R12, AX\n\tJMP  sequenceDecs_decode_56_amd64_adjust_test_temp_valid\n\nsequenceDecs_decode_56_amd64_adjust_two:\n\tMOVQ R13, AX\n\tJMP  sequenceDecs_decode_56_amd64_adjust_test_temp_valid\n\nsequenceDecs_decode_56_amd64_adjust_three:\n\tLEAQ -1(R11), AX\n\nsequenceDecs_decode_56_amd64_adjust_test_temp_valid:\n\tTESTQ AX, AX\n\tJNZ   sequenceDecs_decode_56_amd64_adjust_temp_valid\n\tMOVQ  $0x00000001, AX\n\nsequenceDecs_decode_56_amd64_adjust_temp_valid:\n\tCMPQ    CX, $0x01\n\tCMOVQNE R12, R13\n\tMOVQ    R11, R12\n\tMOVQ    AX, R11\n\tMOVQ    AX, CX\n\nsequenceDecs_decode_56_amd64_after_adjust:\n\tMOVQ CX, 16(R10)\n\n\t// Check values\n\tMOVQ  8(R10), AX\n\tMOVQ  (R10), R14\n\tLEAQ  (AX)(R14*1), R15\n\tMOVQ  s+0(FP), BP\n\tADDQ  R15, 256(BP)\n\tMOVQ  ctx+16(FP), R15\n\tSUBQ  R14, 128(R15)\n\tJS    error_not_enough_literals\n\tCMPQ  AX, $0x00020002\n\tJA    sequenceDecs_decode_56_amd64_error_match_len_too_big\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_56_amd64_match_len_ofs_ok\n\tTESTQ AX, AX\n\tJNZ   sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch\n\nsequenceDecs_decode_56_amd64_match_len_ofs_ok:\n\tADDQ $0x18, R10\n\tMOVQ ctx+16(FP), AX\n\tDECQ 96(AX)\n\tJNS  sequenceDecs_decode_56_amd64_main_loop\n\tMOVQ s+0(FP), AX\n\tMOVQ R11, 144(AX)\n\tMOVQ R12, 152(AX)\n\tMOVQ R13, 160(AX)\n\tMOVQ br+8(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVB BL, 32(AX)\n\tMOVQ SI, 8(AX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch:\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decode_56_amd64_error_match_len_too_big:\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n// func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n// Requires: BMI, BMI2, CMOV\nTEXT ·sequenceDecs_decode_bmi2(SB), $8-32\n\tMOVQ    br+8(FP), BX\n\tMOVQ    24(BX), AX\n\tMOVBQZX 32(BX), DX\n\tMOVQ    (BX), CX\n\tMOVQ    8(BX), BX\n\tADDQ    BX, CX\n\tMOVQ    CX, (SP)\n\tMOVQ    ctx+16(FP), CX\n\tMOVQ    72(CX), SI\n\tMOVQ    80(CX), DI\n\tMOVQ    88(CX), R8\n\tMOVQ    104(CX), R9\n\tMOVQ    s+0(FP), CX\n\tMOVQ    144(CX), R10\n\tMOVQ    152(CX), R11\n\tMOVQ    160(CX), R12\n\nsequenceDecs_decode_bmi2_main_loop:\n\tMOVQ (SP), R13\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ BX, $0x08\n\tJL   sequenceDecs_decode_bmi2_fill_byte_by_byte\n\tMOVQ DX, CX\n\tSHRQ $0x03, CX\n\tSUBQ CX, R13\n\tMOVQ (R13), AX\n\tSUBQ CX, BX\n\tANDQ $0x07, DX\n\tJMP  sequenceDecs_decode_bmi2_fill_end\n\nsequenceDecs_decode_bmi2_fill_byte_by_byte:\n\tCMPQ    BX, $0x00\n\tJLE     sequenceDecs_decode_bmi2_fill_check_overread\n\tCMPQ    DX, $0x07\n\tJLE     sequenceDecs_decode_bmi2_fill_end\n\tSHLQ    $0x08, AX\n\tSUBQ    $0x01, R13\n\tSUBQ    $0x01, BX\n\tSUBQ    $0x08, DX\n\tMOVBQZX (R13), CX\n\tORQ     CX, AX\n\tJMP     sequenceDecs_decode_bmi2_fill_byte_by_byte\n\nsequenceDecs_decode_bmi2_fill_check_overread:\n\tCMPQ DX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decode_bmi2_fill_end:\n\t// Update offset\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, R8, R14\n\tMOVQ   AX, R15\n\tLEAQ   (DX)(R14*1), CX\n\tROLQ   CL, R15\n\tBZHIQ  R14, R15, R15\n\tMOVQ   CX, DX\n\tMOVQ   R8, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R15, CX\n\tMOVQ   CX, 16(R9)\n\n\t// Update match length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, DI, R14\n\tMOVQ   AX, R15\n\tLEAQ   (DX)(R14*1), CX\n\tROLQ   CL, R15\n\tBZHIQ  R14, R15, R15\n\tMOVQ   CX, DX\n\tMOVQ   DI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R15, CX\n\tMOVQ   CX, 8(R9)\n\n\t// Fill bitreader to have enough for the remaining\n\tCMPQ BX, $0x08\n\tJL   sequenceDecs_decode_bmi2_fill_2_byte_by_byte\n\tMOVQ DX, CX\n\tSHRQ $0x03, CX\n\tSUBQ CX, R13\n\tMOVQ (R13), AX\n\tSUBQ CX, BX\n\tANDQ $0x07, DX\n\tJMP  sequenceDecs_decode_bmi2_fill_2_end\n\nsequenceDecs_decode_bmi2_fill_2_byte_by_byte:\n\tCMPQ    BX, $0x00\n\tJLE     sequenceDecs_decode_bmi2_fill_2_check_overread\n\tCMPQ    DX, $0x07\n\tJLE     sequenceDecs_decode_bmi2_fill_2_end\n\tSHLQ    $0x08, AX\n\tSUBQ    $0x01, R13\n\tSUBQ    $0x01, BX\n\tSUBQ    $0x08, DX\n\tMOVBQZX (R13), CX\n\tORQ     CX, AX\n\tJMP     sequenceDecs_decode_bmi2_fill_2_byte_by_byte\n\nsequenceDecs_decode_bmi2_fill_2_check_overread:\n\tCMPQ DX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decode_bmi2_fill_2_end:\n\t// Update literal length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, SI, R14\n\tMOVQ   AX, R15\n\tLEAQ   (DX)(R14*1), CX\n\tROLQ   CL, R15\n\tBZHIQ  R14, R15, R15\n\tMOVQ   CX, DX\n\tMOVQ   SI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R15, CX\n\tMOVQ   CX, (R9)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R13, (SP)\n\tMOVQ    $0x00000808, CX\n\tBEXTRQ  CX, R8, R13\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decode_bmi2_skip_update\n\tLEAQ    (SI)(DI*1), R14\n\tADDQ    R8, R14\n\tMOVBQZX R14, R14\n\tLEAQ    (DX)(R14*1), CX\n\tMOVQ    AX, R15\n\tMOVQ    CX, DX\n\tROLQ    CL, R15\n\tBZHIQ   R14, R15, R15\n\n\t// Update Offset State\n\tBZHIQ  R8, R15, CX\n\tSHRXQ  R8, R15, R15\n\tMOVQ   $0x00001010, R14\n\tBEXTRQ R14, R8, R8\n\tADDQ   CX, R8\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Match Length State\n\tBZHIQ  DI, R15, CX\n\tSHRXQ  DI, R15, R15\n\tMOVQ   $0x00001010, R14\n\tBEXTRQ R14, DI, DI\n\tADDQ   CX, DI\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Literal Length State\n\tBZHIQ  SI, R15, CX\n\tMOVQ   $0x00001010, R14\n\tBEXTRQ R14, SI, SI\n\tADDQ   CX, SI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(SI*8), SI\n\nsequenceDecs_decode_bmi2_skip_update:\n\t// Adjust offset\n\tMOVQ 16(R9), CX\n\tCMPQ R13, $0x01\n\tJBE  sequenceDecs_decode_bmi2_adjust_offsetB_1_or_0\n\tMOVQ R11, R12\n\tMOVQ R10, R11\n\tMOVQ CX, R10\n\tJMP  sequenceDecs_decode_bmi2_after_adjust\n\nsequenceDecs_decode_bmi2_adjust_offsetB_1_or_0:\n\tCMPQ (R9), $0x00000000\n\tJNE  sequenceDecs_decode_bmi2_adjust_offset_maybezero\n\tINCQ CX\n\tJMP  sequenceDecs_decode_bmi2_adjust_offset_nonzero\n\nsequenceDecs_decode_bmi2_adjust_offset_maybezero:\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_bmi2_adjust_offset_nonzero\n\tMOVQ  R10, CX\n\tJMP   sequenceDecs_decode_bmi2_after_adjust\n\nsequenceDecs_decode_bmi2_adjust_offset_nonzero:\n\tCMPQ CX, $0x01\n\tJB   sequenceDecs_decode_bmi2_adjust_zero\n\tJEQ  sequenceDecs_decode_bmi2_adjust_one\n\tCMPQ CX, $0x02\n\tJA   sequenceDecs_decode_bmi2_adjust_three\n\tJMP  sequenceDecs_decode_bmi2_adjust_two\n\nsequenceDecs_decode_bmi2_adjust_zero:\n\tMOVQ R10, R13\n\tJMP  sequenceDecs_decode_bmi2_adjust_test_temp_valid\n\nsequenceDecs_decode_bmi2_adjust_one:\n\tMOVQ R11, R13\n\tJMP  sequenceDecs_decode_bmi2_adjust_test_temp_valid\n\nsequenceDecs_decode_bmi2_adjust_two:\n\tMOVQ R12, R13\n\tJMP  sequenceDecs_decode_bmi2_adjust_test_temp_valid\n\nsequenceDecs_decode_bmi2_adjust_three:\n\tLEAQ -1(R10), R13\n\nsequenceDecs_decode_bmi2_adjust_test_temp_valid:\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decode_bmi2_adjust_temp_valid\n\tMOVQ  $0x00000001, R13\n\nsequenceDecs_decode_bmi2_adjust_temp_valid:\n\tCMPQ    CX, $0x01\n\tCMOVQNE R11, R12\n\tMOVQ    R10, R11\n\tMOVQ    R13, R10\n\tMOVQ    R13, CX\n\nsequenceDecs_decode_bmi2_after_adjust:\n\tMOVQ CX, 16(R9)\n\n\t// Check values\n\tMOVQ  8(R9), R13\n\tMOVQ  (R9), R14\n\tLEAQ  (R13)(R14*1), R15\n\tMOVQ  s+0(FP), BP\n\tADDQ  R15, 256(BP)\n\tMOVQ  ctx+16(FP), R15\n\tSUBQ  R14, 128(R15)\n\tJS    error_not_enough_literals\n\tCMPQ  R13, $0x00020002\n\tJA    sequenceDecs_decode_bmi2_error_match_len_too_big\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_bmi2_match_len_ofs_ok\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decode_bmi2_error_match_len_ofs_mismatch\n\nsequenceDecs_decode_bmi2_match_len_ofs_ok:\n\tADDQ $0x18, R9\n\tMOVQ ctx+16(FP), CX\n\tDECQ 96(CX)\n\tJNS  sequenceDecs_decode_bmi2_main_loop\n\tMOVQ s+0(FP), CX\n\tMOVQ R10, 144(CX)\n\tMOVQ R11, 152(CX)\n\tMOVQ R12, 160(CX)\n\tMOVQ br+8(FP), CX\n\tMOVQ AX, 24(CX)\n\tMOVB DL, 32(CX)\n\tMOVQ BX, 8(CX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decode_bmi2_error_match_len_ofs_mismatch:\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decode_bmi2_error_match_len_too_big:\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n// func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int\n// Requires: BMI, BMI2, CMOV\nTEXT ·sequenceDecs_decode_56_bmi2(SB), $8-32\n\tMOVQ    br+8(FP), BX\n\tMOVQ    24(BX), AX\n\tMOVBQZX 32(BX), DX\n\tMOVQ    (BX), CX\n\tMOVQ    8(BX), BX\n\tADDQ    BX, CX\n\tMOVQ    CX, (SP)\n\tMOVQ    ctx+16(FP), CX\n\tMOVQ    72(CX), SI\n\tMOVQ    80(CX), DI\n\tMOVQ    88(CX), R8\n\tMOVQ    104(CX), R9\n\tMOVQ    s+0(FP), CX\n\tMOVQ    144(CX), R10\n\tMOVQ    152(CX), R11\n\tMOVQ    160(CX), R12\n\nsequenceDecs_decode_56_bmi2_main_loop:\n\tMOVQ (SP), R13\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ BX, $0x08\n\tJL   sequenceDecs_decode_56_bmi2_fill_byte_by_byte\n\tMOVQ DX, CX\n\tSHRQ $0x03, CX\n\tSUBQ CX, R13\n\tMOVQ (R13), AX\n\tSUBQ CX, BX\n\tANDQ $0x07, DX\n\tJMP  sequenceDecs_decode_56_bmi2_fill_end\n\nsequenceDecs_decode_56_bmi2_fill_byte_by_byte:\n\tCMPQ    BX, $0x00\n\tJLE     sequenceDecs_decode_56_bmi2_fill_check_overread\n\tCMPQ    DX, $0x07\n\tJLE     sequenceDecs_decode_56_bmi2_fill_end\n\tSHLQ    $0x08, AX\n\tSUBQ    $0x01, R13\n\tSUBQ    $0x01, BX\n\tSUBQ    $0x08, DX\n\tMOVBQZX (R13), CX\n\tORQ     CX, AX\n\tJMP     sequenceDecs_decode_56_bmi2_fill_byte_by_byte\n\nsequenceDecs_decode_56_bmi2_fill_check_overread:\n\tCMPQ DX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decode_56_bmi2_fill_end:\n\t// Update offset\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, R8, R14\n\tMOVQ   AX, R15\n\tLEAQ   (DX)(R14*1), CX\n\tROLQ   CL, R15\n\tBZHIQ  R14, R15, R15\n\tMOVQ   CX, DX\n\tMOVQ   R8, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R15, CX\n\tMOVQ   CX, 16(R9)\n\n\t// Update match length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, DI, R14\n\tMOVQ   AX, R15\n\tLEAQ   (DX)(R14*1), CX\n\tROLQ   CL, R15\n\tBZHIQ  R14, R15, R15\n\tMOVQ   CX, DX\n\tMOVQ   DI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R15, CX\n\tMOVQ   CX, 8(R9)\n\n\t// Update literal length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, SI, R14\n\tMOVQ   AX, R15\n\tLEAQ   (DX)(R14*1), CX\n\tROLQ   CL, R15\n\tBZHIQ  R14, R15, R15\n\tMOVQ   CX, DX\n\tMOVQ   SI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R15, CX\n\tMOVQ   CX, (R9)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R13, (SP)\n\tMOVQ    $0x00000808, CX\n\tBEXTRQ  CX, R8, R13\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decode_56_bmi2_skip_update\n\tLEAQ    (SI)(DI*1), R14\n\tADDQ    R8, R14\n\tMOVBQZX R14, R14\n\tLEAQ    (DX)(R14*1), CX\n\tMOVQ    AX, R15\n\tMOVQ    CX, DX\n\tROLQ    CL, R15\n\tBZHIQ   R14, R15, R15\n\n\t// Update Offset State\n\tBZHIQ  R8, R15, CX\n\tSHRXQ  R8, R15, R15\n\tMOVQ   $0x00001010, R14\n\tBEXTRQ R14, R8, R8\n\tADDQ   CX, R8\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Match Length State\n\tBZHIQ  DI, R15, CX\n\tSHRXQ  DI, R15, R15\n\tMOVQ   $0x00001010, R14\n\tBEXTRQ R14, DI, DI\n\tADDQ   CX, DI\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Literal Length State\n\tBZHIQ  SI, R15, CX\n\tMOVQ   $0x00001010, R14\n\tBEXTRQ R14, SI, SI\n\tADDQ   CX, SI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(SI*8), SI\n\nsequenceDecs_decode_56_bmi2_skip_update:\n\t// Adjust offset\n\tMOVQ 16(R9), CX\n\tCMPQ R13, $0x01\n\tJBE  sequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0\n\tMOVQ R11, R12\n\tMOVQ R10, R11\n\tMOVQ CX, R10\n\tJMP  sequenceDecs_decode_56_bmi2_after_adjust\n\nsequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0:\n\tCMPQ (R9), $0x00000000\n\tJNE  sequenceDecs_decode_56_bmi2_adjust_offset_maybezero\n\tINCQ CX\n\tJMP  sequenceDecs_decode_56_bmi2_adjust_offset_nonzero\n\nsequenceDecs_decode_56_bmi2_adjust_offset_maybezero:\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_56_bmi2_adjust_offset_nonzero\n\tMOVQ  R10, CX\n\tJMP   sequenceDecs_decode_56_bmi2_after_adjust\n\nsequenceDecs_decode_56_bmi2_adjust_offset_nonzero:\n\tCMPQ CX, $0x01\n\tJB   sequenceDecs_decode_56_bmi2_adjust_zero\n\tJEQ  sequenceDecs_decode_56_bmi2_adjust_one\n\tCMPQ CX, $0x02\n\tJA   sequenceDecs_decode_56_bmi2_adjust_three\n\tJMP  sequenceDecs_decode_56_bmi2_adjust_two\n\nsequenceDecs_decode_56_bmi2_adjust_zero:\n\tMOVQ R10, R13\n\tJMP  sequenceDecs_decode_56_bmi2_adjust_test_temp_valid\n\nsequenceDecs_decode_56_bmi2_adjust_one:\n\tMOVQ R11, R13\n\tJMP  sequenceDecs_decode_56_bmi2_adjust_test_temp_valid\n\nsequenceDecs_decode_56_bmi2_adjust_two:\n\tMOVQ R12, R13\n\tJMP  sequenceDecs_decode_56_bmi2_adjust_test_temp_valid\n\nsequenceDecs_decode_56_bmi2_adjust_three:\n\tLEAQ -1(R10), R13\n\nsequenceDecs_decode_56_bmi2_adjust_test_temp_valid:\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decode_56_bmi2_adjust_temp_valid\n\tMOVQ  $0x00000001, R13\n\nsequenceDecs_decode_56_bmi2_adjust_temp_valid:\n\tCMPQ    CX, $0x01\n\tCMOVQNE R11, R12\n\tMOVQ    R10, R11\n\tMOVQ    R13, R10\n\tMOVQ    R13, CX\n\nsequenceDecs_decode_56_bmi2_after_adjust:\n\tMOVQ CX, 16(R9)\n\n\t// Check values\n\tMOVQ  8(R9), R13\n\tMOVQ  (R9), R14\n\tLEAQ  (R13)(R14*1), R15\n\tMOVQ  s+0(FP), BP\n\tADDQ  R15, 256(BP)\n\tMOVQ  ctx+16(FP), R15\n\tSUBQ  R14, 128(R15)\n\tJS    error_not_enough_literals\n\tCMPQ  R13, $0x00020002\n\tJA    sequenceDecs_decode_56_bmi2_error_match_len_too_big\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decode_56_bmi2_match_len_ofs_ok\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch\n\nsequenceDecs_decode_56_bmi2_match_len_ofs_ok:\n\tADDQ $0x18, R9\n\tMOVQ ctx+16(FP), CX\n\tDECQ 96(CX)\n\tJNS  sequenceDecs_decode_56_bmi2_main_loop\n\tMOVQ s+0(FP), CX\n\tMOVQ R10, 144(CX)\n\tMOVQ R11, 152(CX)\n\tMOVQ R12, 160(CX)\n\tMOVQ br+8(FP), CX\n\tMOVQ AX, 24(CX)\n\tMOVB DL, 32(CX)\n\tMOVQ BX, 8(CX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch:\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decode_56_bmi2_error_match_len_too_big:\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n// func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool\n// Requires: SSE\nTEXT ·sequenceDecs_executeSimple_amd64(SB), $8-9\n\tMOVQ  ctx+0(FP), R10\n\tMOVQ  8(R10), CX\n\tTESTQ CX, CX\n\tJZ    empty_seqs\n\tMOVQ  (R10), AX\n\tMOVQ  24(R10), DX\n\tMOVQ  32(R10), BX\n\tMOVQ  80(R10), SI\n\tMOVQ  104(R10), DI\n\tMOVQ  120(R10), R8\n\tMOVQ  56(R10), R9\n\tMOVQ  64(R10), R10\n\tADDQ  R10, R9\n\n\t// seqsBase += 24 * seqIndex\n\tLEAQ (DX)(DX*2), R11\n\tSHLQ $0x03, R11\n\tADDQ R11, AX\n\n\t// outBase += outPosition\n\tADDQ DI, BX\n\nmain_loop:\n\tMOVQ (AX), R11\n\tMOVQ 16(AX), R12\n\tMOVQ 8(AX), R13\n\n\t// Copy literals\n\tTESTQ R11, R11\n\tJZ    check_offset\n\tXORQ  R14, R14\n\ncopy_1:\n\tMOVUPS (SI)(R14*1), X0\n\tMOVUPS X0, (BX)(R14*1)\n\tADDQ   $0x10, R14\n\tCMPQ   R14, R11\n\tJB     copy_1\n\tADDQ   R11, SI\n\tADDQ   R11, BX\n\tADDQ   R11, DI\n\n\t// Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize)\ncheck_offset:\n\tLEAQ (DI)(R10*1), R11\n\tCMPQ R12, R11\n\tJG   error_match_off_too_big\n\tCMPQ R12, R8\n\tJG   error_match_off_too_big\n\n\t// Copy match from history\n\tMOVQ R12, R11\n\tSUBQ DI, R11\n\tJLS  copy_match\n\tMOVQ R9, R14\n\tSUBQ R11, R14\n\tCMPQ R13, R11\n\tJG   copy_all_from_history\n\tMOVQ R13, R11\n\tSUBQ $0x10, R11\n\tJB   copy_4_small\n\ncopy_4_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (BX)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, BX\n\tSUBQ   $0x10, R11\n\tJAE    copy_4_loop\n\tLEAQ   16(R14)(R11*1), R14\n\tLEAQ   16(BX)(R11*1), BX\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(BX)\n\tJMP    copy_4_end\n\ncopy_4_small:\n\tCMPQ R13, $0x03\n\tJE   copy_4_move_3\n\tCMPQ R13, $0x08\n\tJB   copy_4_move_4through7\n\tJMP  copy_4_move_8through16\n\ncopy_4_move_3:\n\tMOVW (R14), R11\n\tMOVB 2(R14), R12\n\tMOVW R11, (BX)\n\tMOVB R12, 2(BX)\n\tADDQ R13, R14\n\tADDQ R13, BX\n\tJMP  copy_4_end\n\ncopy_4_move_4through7:\n\tMOVL (R14), R11\n\tMOVL -4(R14)(R13*1), R12\n\tMOVL R11, (BX)\n\tMOVL R12, -4(BX)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, BX\n\tJMP  copy_4_end\n\ncopy_4_move_8through16:\n\tMOVQ (R14), R11\n\tMOVQ -8(R14)(R13*1), R12\n\tMOVQ R11, (BX)\n\tMOVQ R12, -8(BX)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, BX\n\ncopy_4_end:\n\tADDQ R13, DI\n\tADDQ $0x18, AX\n\tINCQ DX\n\tCMPQ DX, CX\n\tJB   main_loop\n\tJMP  loop_finished\n\ncopy_all_from_history:\n\tMOVQ R11, R15\n\tSUBQ $0x10, R15\n\tJB   copy_5_small\n\ncopy_5_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (BX)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, BX\n\tSUBQ   $0x10, R15\n\tJAE    copy_5_loop\n\tLEAQ   16(R14)(R15*1), R14\n\tLEAQ   16(BX)(R15*1), BX\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(BX)\n\tJMP    copy_5_end\n\ncopy_5_small:\n\tCMPQ R11, $0x03\n\tJE   copy_5_move_3\n\tJB   copy_5_move_1or2\n\tCMPQ R11, $0x08\n\tJB   copy_5_move_4through7\n\tJMP  copy_5_move_8through16\n\ncopy_5_move_1or2:\n\tMOVB (R14), R15\n\tMOVB -1(R14)(R11*1), BP\n\tMOVB R15, (BX)\n\tMOVB BP, -1(BX)(R11*1)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\tJMP  copy_5_end\n\ncopy_5_move_3:\n\tMOVW (R14), R15\n\tMOVB 2(R14), BP\n\tMOVW R15, (BX)\n\tMOVB BP, 2(BX)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\tJMP  copy_5_end\n\ncopy_5_move_4through7:\n\tMOVL (R14), R15\n\tMOVL -4(R14)(R11*1), BP\n\tMOVL R15, (BX)\n\tMOVL BP, -4(BX)(R11*1)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\tJMP  copy_5_end\n\ncopy_5_move_8through16:\n\tMOVQ (R14), R15\n\tMOVQ -8(R14)(R11*1), BP\n\tMOVQ R15, (BX)\n\tMOVQ BP, -8(BX)(R11*1)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\ncopy_5_end:\n\tADDQ R11, DI\n\tSUBQ R11, R13\n\n\t// Copy match from the current buffer\ncopy_match:\n\tMOVQ BX, R11\n\tSUBQ R12, R11\n\n\t// ml <= mo\n\tCMPQ R13, R12\n\tJA   copy_overlapping_match\n\n\t// Copy non-overlapping match\n\tADDQ R13, DI\n\tMOVQ BX, R12\n\tADDQ R13, BX\n\ncopy_2:\n\tMOVUPS (R11), X0\n\tMOVUPS X0, (R12)\n\tADDQ   $0x10, R11\n\tADDQ   $0x10, R12\n\tSUBQ   $0x10, R13\n\tJHI    copy_2\n\tJMP    handle_loop\n\n\t// Copy overlapping match\ncopy_overlapping_match:\n\tADDQ R13, DI\n\ncopy_slow_3:\n\tMOVB (R11), R12\n\tMOVB R12, (BX)\n\tINCQ R11\n\tINCQ BX\n\tDECQ R13\n\tJNZ  copy_slow_3\n\nhandle_loop:\n\tADDQ $0x18, AX\n\tINCQ DX\n\tCMPQ DX, CX\n\tJB   main_loop\n\nloop_finished:\n\t// Return value\n\tMOVB $0x01, ret+8(FP)\n\n\t// Update the context\n\tMOVQ ctx+0(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVQ DI, 104(AX)\n\tSUBQ 80(AX), SI\n\tMOVQ SI, 112(AX)\n\tRET\n\nerror_match_off_too_big:\n\t// Return value\n\tMOVB $0x00, ret+8(FP)\n\n\t// Update the context\n\tMOVQ ctx+0(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVQ DI, 104(AX)\n\tSUBQ 80(AX), SI\n\tMOVQ SI, 112(AX)\n\tRET\n\nempty_seqs:\n\t// Return value\n\tMOVB $0x01, ret+8(FP)\n\tRET\n\n// func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool\n// Requires: SSE\nTEXT ·sequenceDecs_executeSimple_safe_amd64(SB), $8-9\n\tMOVQ  ctx+0(FP), R10\n\tMOVQ  8(R10), CX\n\tTESTQ CX, CX\n\tJZ    empty_seqs\n\tMOVQ  (R10), AX\n\tMOVQ  24(R10), DX\n\tMOVQ  32(R10), BX\n\tMOVQ  80(R10), SI\n\tMOVQ  104(R10), DI\n\tMOVQ  120(R10), R8\n\tMOVQ  56(R10), R9\n\tMOVQ  64(R10), R10\n\tADDQ  R10, R9\n\n\t// seqsBase += 24 * seqIndex\n\tLEAQ (DX)(DX*2), R11\n\tSHLQ $0x03, R11\n\tADDQ R11, AX\n\n\t// outBase += outPosition\n\tADDQ DI, BX\n\nmain_loop:\n\tMOVQ (AX), R11\n\tMOVQ 16(AX), R12\n\tMOVQ 8(AX), R13\n\n\t// Copy literals\n\tTESTQ R11, R11\n\tJZ    check_offset\n\tMOVQ  R11, R14\n\tSUBQ  $0x10, R14\n\tJB    copy_1_small\n\ncopy_1_loop:\n\tMOVUPS (SI), X0\n\tMOVUPS X0, (BX)\n\tADDQ   $0x10, SI\n\tADDQ   $0x10, BX\n\tSUBQ   $0x10, R14\n\tJAE    copy_1_loop\n\tLEAQ   16(SI)(R14*1), SI\n\tLEAQ   16(BX)(R14*1), BX\n\tMOVUPS -16(SI), X0\n\tMOVUPS X0, -16(BX)\n\tJMP    copy_1_end\n\ncopy_1_small:\n\tCMPQ R11, $0x03\n\tJE   copy_1_move_3\n\tJB   copy_1_move_1or2\n\tCMPQ R11, $0x08\n\tJB   copy_1_move_4through7\n\tJMP  copy_1_move_8through16\n\ncopy_1_move_1or2:\n\tMOVB (SI), R14\n\tMOVB -1(SI)(R11*1), R15\n\tMOVB R14, (BX)\n\tMOVB R15, -1(BX)(R11*1)\n\tADDQ R11, SI\n\tADDQ R11, BX\n\tJMP  copy_1_end\n\ncopy_1_move_3:\n\tMOVW (SI), R14\n\tMOVB 2(SI), R15\n\tMOVW R14, (BX)\n\tMOVB R15, 2(BX)\n\tADDQ R11, SI\n\tADDQ R11, BX\n\tJMP  copy_1_end\n\ncopy_1_move_4through7:\n\tMOVL (SI), R14\n\tMOVL -4(SI)(R11*1), R15\n\tMOVL R14, (BX)\n\tMOVL R15, -4(BX)(R11*1)\n\tADDQ R11, SI\n\tADDQ R11, BX\n\tJMP  copy_1_end\n\ncopy_1_move_8through16:\n\tMOVQ (SI), R14\n\tMOVQ -8(SI)(R11*1), R15\n\tMOVQ R14, (BX)\n\tMOVQ R15, -8(BX)(R11*1)\n\tADDQ R11, SI\n\tADDQ R11, BX\n\ncopy_1_end:\n\tADDQ R11, DI\n\n\t// Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize)\ncheck_offset:\n\tLEAQ (DI)(R10*1), R11\n\tCMPQ R12, R11\n\tJG   error_match_off_too_big\n\tCMPQ R12, R8\n\tJG   error_match_off_too_big\n\n\t// Copy match from history\n\tMOVQ R12, R11\n\tSUBQ DI, R11\n\tJLS  copy_match\n\tMOVQ R9, R14\n\tSUBQ R11, R14\n\tCMPQ R13, R11\n\tJG   copy_all_from_history\n\tMOVQ R13, R11\n\tSUBQ $0x10, R11\n\tJB   copy_4_small\n\ncopy_4_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (BX)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, BX\n\tSUBQ   $0x10, R11\n\tJAE    copy_4_loop\n\tLEAQ   16(R14)(R11*1), R14\n\tLEAQ   16(BX)(R11*1), BX\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(BX)\n\tJMP    copy_4_end\n\ncopy_4_small:\n\tCMPQ R13, $0x03\n\tJE   copy_4_move_3\n\tCMPQ R13, $0x08\n\tJB   copy_4_move_4through7\n\tJMP  copy_4_move_8through16\n\ncopy_4_move_3:\n\tMOVW (R14), R11\n\tMOVB 2(R14), R12\n\tMOVW R11, (BX)\n\tMOVB R12, 2(BX)\n\tADDQ R13, R14\n\tADDQ R13, BX\n\tJMP  copy_4_end\n\ncopy_4_move_4through7:\n\tMOVL (R14), R11\n\tMOVL -4(R14)(R13*1), R12\n\tMOVL R11, (BX)\n\tMOVL R12, -4(BX)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, BX\n\tJMP  copy_4_end\n\ncopy_4_move_8through16:\n\tMOVQ (R14), R11\n\tMOVQ -8(R14)(R13*1), R12\n\tMOVQ R11, (BX)\n\tMOVQ R12, -8(BX)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, BX\n\ncopy_4_end:\n\tADDQ R13, DI\n\tADDQ $0x18, AX\n\tINCQ DX\n\tCMPQ DX, CX\n\tJB   main_loop\n\tJMP  loop_finished\n\ncopy_all_from_history:\n\tMOVQ R11, R15\n\tSUBQ $0x10, R15\n\tJB   copy_5_small\n\ncopy_5_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (BX)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, BX\n\tSUBQ   $0x10, R15\n\tJAE    copy_5_loop\n\tLEAQ   16(R14)(R15*1), R14\n\tLEAQ   16(BX)(R15*1), BX\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(BX)\n\tJMP    copy_5_end\n\ncopy_5_small:\n\tCMPQ R11, $0x03\n\tJE   copy_5_move_3\n\tJB   copy_5_move_1or2\n\tCMPQ R11, $0x08\n\tJB   copy_5_move_4through7\n\tJMP  copy_5_move_8through16\n\ncopy_5_move_1or2:\n\tMOVB (R14), R15\n\tMOVB -1(R14)(R11*1), BP\n\tMOVB R15, (BX)\n\tMOVB BP, -1(BX)(R11*1)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\tJMP  copy_5_end\n\ncopy_5_move_3:\n\tMOVW (R14), R15\n\tMOVB 2(R14), BP\n\tMOVW R15, (BX)\n\tMOVB BP, 2(BX)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\tJMP  copy_5_end\n\ncopy_5_move_4through7:\n\tMOVL (R14), R15\n\tMOVL -4(R14)(R11*1), BP\n\tMOVL R15, (BX)\n\tMOVL BP, -4(BX)(R11*1)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\tJMP  copy_5_end\n\ncopy_5_move_8through16:\n\tMOVQ (R14), R15\n\tMOVQ -8(R14)(R11*1), BP\n\tMOVQ R15, (BX)\n\tMOVQ BP, -8(BX)(R11*1)\n\tADDQ R11, R14\n\tADDQ R11, BX\n\ncopy_5_end:\n\tADDQ R11, DI\n\tSUBQ R11, R13\n\n\t// Copy match from the current buffer\ncopy_match:\n\tMOVQ BX, R11\n\tSUBQ R12, R11\n\n\t// ml <= mo\n\tCMPQ R13, R12\n\tJA   copy_overlapping_match\n\n\t// Copy non-overlapping match\n\tADDQ R13, DI\n\tMOVQ R13, R12\n\tSUBQ $0x10, R12\n\tJB   copy_2_small\n\ncopy_2_loop:\n\tMOVUPS (R11), X0\n\tMOVUPS X0, (BX)\n\tADDQ   $0x10, R11\n\tADDQ   $0x10, BX\n\tSUBQ   $0x10, R12\n\tJAE    copy_2_loop\n\tLEAQ   16(R11)(R12*1), R11\n\tLEAQ   16(BX)(R12*1), BX\n\tMOVUPS -16(R11), X0\n\tMOVUPS X0, -16(BX)\n\tJMP    copy_2_end\n\ncopy_2_small:\n\tCMPQ R13, $0x03\n\tJE   copy_2_move_3\n\tJB   copy_2_move_1or2\n\tCMPQ R13, $0x08\n\tJB   copy_2_move_4through7\n\tJMP  copy_2_move_8through16\n\ncopy_2_move_1or2:\n\tMOVB (R11), R12\n\tMOVB -1(R11)(R13*1), R14\n\tMOVB R12, (BX)\n\tMOVB R14, -1(BX)(R13*1)\n\tADDQ R13, R11\n\tADDQ R13, BX\n\tJMP  copy_2_end\n\ncopy_2_move_3:\n\tMOVW (R11), R12\n\tMOVB 2(R11), R14\n\tMOVW R12, (BX)\n\tMOVB R14, 2(BX)\n\tADDQ R13, R11\n\tADDQ R13, BX\n\tJMP  copy_2_end\n\ncopy_2_move_4through7:\n\tMOVL (R11), R12\n\tMOVL -4(R11)(R13*1), R14\n\tMOVL R12, (BX)\n\tMOVL R14, -4(BX)(R13*1)\n\tADDQ R13, R11\n\tADDQ R13, BX\n\tJMP  copy_2_end\n\ncopy_2_move_8through16:\n\tMOVQ (R11), R12\n\tMOVQ -8(R11)(R13*1), R14\n\tMOVQ R12, (BX)\n\tMOVQ R14, -8(BX)(R13*1)\n\tADDQ R13, R11\n\tADDQ R13, BX\n\ncopy_2_end:\n\tJMP handle_loop\n\n\t// Copy overlapping match\ncopy_overlapping_match:\n\tADDQ R13, DI\n\ncopy_slow_3:\n\tMOVB (R11), R12\n\tMOVB R12, (BX)\n\tINCQ R11\n\tINCQ BX\n\tDECQ R13\n\tJNZ  copy_slow_3\n\nhandle_loop:\n\tADDQ $0x18, AX\n\tINCQ DX\n\tCMPQ DX, CX\n\tJB   main_loop\n\nloop_finished:\n\t// Return value\n\tMOVB $0x01, ret+8(FP)\n\n\t// Update the context\n\tMOVQ ctx+0(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVQ DI, 104(AX)\n\tSUBQ 80(AX), SI\n\tMOVQ SI, 112(AX)\n\tRET\n\nerror_match_off_too_big:\n\t// Return value\n\tMOVB $0x00, ret+8(FP)\n\n\t// Update the context\n\tMOVQ ctx+0(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVQ DI, 104(AX)\n\tSUBQ 80(AX), SI\n\tMOVQ SI, 112(AX)\n\tRET\n\nempty_seqs:\n\t// Return value\n\tMOVB $0x01, ret+8(FP)\n\tRET\n\n// func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n// Requires: CMOV, SSE\nTEXT ·sequenceDecs_decodeSync_amd64(SB), $64-32\n\tMOVQ    br+8(FP), CX\n\tMOVQ    24(CX), DX\n\tMOVBQZX 32(CX), BX\n\tMOVQ    (CX), AX\n\tMOVQ    8(CX), SI\n\tADDQ    SI, AX\n\tMOVQ    AX, (SP)\n\tMOVQ    ctx+16(FP), AX\n\tMOVQ    72(AX), DI\n\tMOVQ    80(AX), R8\n\tMOVQ    88(AX), R9\n\tXORQ    CX, CX\n\tMOVQ    CX, 8(SP)\n\tMOVQ    CX, 16(SP)\n\tMOVQ    CX, 24(SP)\n\tMOVQ    112(AX), R10\n\tMOVQ    128(AX), CX\n\tMOVQ    CX, 32(SP)\n\tMOVQ    144(AX), R11\n\tMOVQ    136(AX), R12\n\tMOVQ    200(AX), CX\n\tMOVQ    CX, 56(SP)\n\tMOVQ    176(AX), CX\n\tMOVQ    CX, 48(SP)\n\tMOVQ    184(AX), AX\n\tMOVQ    AX, 40(SP)\n\tMOVQ    40(SP), AX\n\tADDQ    AX, 48(SP)\n\n\t// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)\n\tADDQ R10, 32(SP)\n\n\t// outBase += outPosition\n\tADDQ R12, R10\n\nsequenceDecs_decodeSync_amd64_main_loop:\n\tMOVQ (SP), R13\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ SI, $0x08\n\tJL   sequenceDecs_decodeSync_amd64_fill_byte_by_byte\n\tMOVQ BX, AX\n\tSHRQ $0x03, AX\n\tSUBQ AX, R13\n\tMOVQ (R13), DX\n\tSUBQ AX, SI\n\tANDQ $0x07, BX\n\tJMP  sequenceDecs_decodeSync_amd64_fill_end\n\nsequenceDecs_decodeSync_amd64_fill_byte_by_byte:\n\tCMPQ    SI, $0x00\n\tJLE     sequenceDecs_decodeSync_amd64_fill_check_overread\n\tCMPQ    BX, $0x07\n\tJLE     sequenceDecs_decodeSync_amd64_fill_end\n\tSHLQ    $0x08, DX\n\tSUBQ    $0x01, R13\n\tSUBQ    $0x01, SI\n\tSUBQ    $0x08, BX\n\tMOVBQZX (R13), AX\n\tORQ     AX, DX\n\tJMP     sequenceDecs_decodeSync_amd64_fill_byte_by_byte\n\nsequenceDecs_decodeSync_amd64_fill_check_overread:\n\tCMPQ BX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_amd64_fill_end:\n\t// Update offset\n\tMOVQ  R9, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R14\n\tSHLQ  CL, R14\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decodeSync_amd64_of_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decodeSync_amd64_of_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decodeSync_amd64_of_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R14\n\tADDQ  R14, AX\n\nsequenceDecs_decodeSync_amd64_of_update_zero:\n\tMOVQ AX, 8(SP)\n\n\t// Update match length\n\tMOVQ  R8, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R14\n\tSHLQ  CL, R14\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decodeSync_amd64_ml_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decodeSync_amd64_ml_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decodeSync_amd64_ml_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R14\n\tADDQ  R14, AX\n\nsequenceDecs_decodeSync_amd64_ml_update_zero:\n\tMOVQ AX, 16(SP)\n\n\t// Fill bitreader to have enough for the remaining\n\tCMPQ SI, $0x08\n\tJL   sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte\n\tMOVQ BX, AX\n\tSHRQ $0x03, AX\n\tSUBQ AX, R13\n\tMOVQ (R13), DX\n\tSUBQ AX, SI\n\tANDQ $0x07, BX\n\tJMP  sequenceDecs_decodeSync_amd64_fill_2_end\n\nsequenceDecs_decodeSync_amd64_fill_2_byte_by_byte:\n\tCMPQ    SI, $0x00\n\tJLE     sequenceDecs_decodeSync_amd64_fill_2_check_overread\n\tCMPQ    BX, $0x07\n\tJLE     sequenceDecs_decodeSync_amd64_fill_2_end\n\tSHLQ    $0x08, DX\n\tSUBQ    $0x01, R13\n\tSUBQ    $0x01, SI\n\tSUBQ    $0x08, BX\n\tMOVBQZX (R13), AX\n\tORQ     AX, DX\n\tJMP     sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte\n\nsequenceDecs_decodeSync_amd64_fill_2_check_overread:\n\tCMPQ BX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_amd64_fill_2_end:\n\t// Update literal length\n\tMOVQ  DI, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R14\n\tSHLQ  CL, R14\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decodeSync_amd64_ll_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decodeSync_amd64_ll_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decodeSync_amd64_ll_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R14\n\tADDQ  R14, AX\n\nsequenceDecs_decodeSync_amd64_ll_update_zero:\n\tMOVQ AX, 24(SP)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R13, (SP)\n\tMOVQ    R9, AX\n\tSHRQ    $0x08, AX\n\tMOVBQZX AL, AX\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decodeSync_amd64_skip_update\n\n\t// Update Literal Length State\n\tMOVBQZX DI, R13\n\tSHRQ    $0x10, DI\n\tMOVWQZX DI, DI\n\tLEAQ    (BX)(R13*1), CX\n\tMOVQ    DX, R14\n\tMOVQ    CX, BX\n\tROLQ    CL, R14\n\tMOVL    $0x00000001, R15\n\tMOVB    R13, CL\n\tSHLL    CL, R15\n\tDECL    R15\n\tANDQ    R15, R14\n\tADDQ    R14, DI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Match Length State\n\tMOVBQZX R8, R13\n\tSHRQ    $0x10, R8\n\tMOVWQZX R8, R8\n\tLEAQ    (BX)(R13*1), CX\n\tMOVQ    DX, R14\n\tMOVQ    CX, BX\n\tROLQ    CL, R14\n\tMOVL    $0x00000001, R15\n\tMOVB    R13, CL\n\tSHLL    CL, R15\n\tDECL    R15\n\tANDQ    R15, R14\n\tADDQ    R14, R8\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Offset State\n\tMOVBQZX R9, R13\n\tSHRQ    $0x10, R9\n\tMOVWQZX R9, R9\n\tLEAQ    (BX)(R13*1), CX\n\tMOVQ    DX, R14\n\tMOVQ    CX, BX\n\tROLQ    CL, R14\n\tMOVL    $0x00000001, R15\n\tMOVB    R13, CL\n\tSHLL    CL, R15\n\tDECL    R15\n\tANDQ    R15, R14\n\tADDQ    R14, R9\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R9*8), R9\n\nsequenceDecs_decodeSync_amd64_skip_update:\n\t// Adjust offset\n\tMOVQ   s+0(FP), CX\n\tMOVQ   8(SP), R13\n\tCMPQ   AX, $0x01\n\tJBE    sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0\n\tMOVUPS 144(CX), X0\n\tMOVQ   R13, 144(CX)\n\tMOVUPS X0, 152(CX)\n\tJMP    sequenceDecs_decodeSync_amd64_after_adjust\n\nsequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0:\n\tCMPQ 24(SP), $0x00000000\n\tJNE  sequenceDecs_decodeSync_amd64_adjust_offset_maybezero\n\tINCQ R13\n\tJMP  sequenceDecs_decodeSync_amd64_adjust_offset_nonzero\n\nsequenceDecs_decodeSync_amd64_adjust_offset_maybezero:\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_amd64_adjust_offset_nonzero\n\tMOVQ  144(CX), R13\n\tJMP   sequenceDecs_decodeSync_amd64_after_adjust\n\nsequenceDecs_decodeSync_amd64_adjust_offset_nonzero:\n\tMOVQ    R13, AX\n\tXORQ    R14, R14\n\tMOVQ    $-1, R15\n\tCMPQ    R13, $0x03\n\tCMOVQEQ R14, AX\n\tCMOVQEQ R15, R14\n\tADDQ    144(CX)(AX*8), R14\n\tJNZ     sequenceDecs_decodeSync_amd64_adjust_temp_valid\n\tMOVQ    $0x00000001, R14\n\nsequenceDecs_decodeSync_amd64_adjust_temp_valid:\n\tCMPQ R13, $0x01\n\tJZ   sequenceDecs_decodeSync_amd64_adjust_skip\n\tMOVQ 152(CX), AX\n\tMOVQ AX, 160(CX)\n\nsequenceDecs_decodeSync_amd64_adjust_skip:\n\tMOVQ 144(CX), AX\n\tMOVQ AX, 152(CX)\n\tMOVQ R14, 144(CX)\n\tMOVQ R14, R13\n\nsequenceDecs_decodeSync_amd64_after_adjust:\n\tMOVQ R13, 8(SP)\n\n\t// Check values\n\tMOVQ  16(SP), AX\n\tMOVQ  24(SP), CX\n\tLEAQ  (AX)(CX*1), R14\n\tMOVQ  s+0(FP), R15\n\tADDQ  R14, 256(R15)\n\tMOVQ  ctx+16(FP), R14\n\tSUBQ  CX, 104(R14)\n\tJS    error_not_enough_literals\n\tCMPQ  AX, $0x00020002\n\tJA    sequenceDecs_decodeSync_amd64_error_match_len_too_big\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_amd64_match_len_ofs_ok\n\tTESTQ AX, AX\n\tJNZ   sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch\n\nsequenceDecs_decodeSync_amd64_match_len_ofs_ok:\n\tMOVQ 24(SP), AX\n\tMOVQ 8(SP), CX\n\tMOVQ 16(SP), R13\n\n\t// Check if we have enough space in s.out\n\tLEAQ (AX)(R13*1), R14\n\tADDQ R10, R14\n\tCMPQ R14, 32(SP)\n\tJA   error_not_enough_space\n\n\t// Copy literals\n\tTESTQ AX, AX\n\tJZ    check_offset\n\tXORQ  R14, R14\n\ncopy_1:\n\tMOVUPS (R11)(R14*1), X0\n\tMOVUPS X0, (R10)(R14*1)\n\tADDQ   $0x10, R14\n\tCMPQ   R14, AX\n\tJB     copy_1\n\tADDQ   AX, R11\n\tADDQ   AX, R10\n\tADDQ   AX, R12\n\n\t// Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize)\ncheck_offset:\n\tMOVQ R12, AX\n\tADDQ 40(SP), AX\n\tCMPQ CX, AX\n\tJG   error_match_off_too_big\n\tCMPQ CX, 56(SP)\n\tJG   error_match_off_too_big\n\n\t// Copy match from history\n\tMOVQ CX, AX\n\tSUBQ R12, AX\n\tJLS  copy_match\n\tMOVQ 48(SP), R14\n\tSUBQ AX, R14\n\tCMPQ R13, AX\n\tJG   copy_all_from_history\n\tMOVQ R13, AX\n\tSUBQ $0x10, AX\n\tJB   copy_4_small\n\ncopy_4_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R10)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R10\n\tSUBQ   $0x10, AX\n\tJAE    copy_4_loop\n\tLEAQ   16(R14)(AX*1), R14\n\tLEAQ   16(R10)(AX*1), R10\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R10)\n\tJMP    copy_4_end\n\ncopy_4_small:\n\tCMPQ R13, $0x03\n\tJE   copy_4_move_3\n\tCMPQ R13, $0x08\n\tJB   copy_4_move_4through7\n\tJMP  copy_4_move_8through16\n\ncopy_4_move_3:\n\tMOVW (R14), AX\n\tMOVB 2(R14), CL\n\tMOVW AX, (R10)\n\tMOVB CL, 2(R10)\n\tADDQ R13, R14\n\tADDQ R13, R10\n\tJMP  copy_4_end\n\ncopy_4_move_4through7:\n\tMOVL (R14), AX\n\tMOVL -4(R14)(R13*1), CX\n\tMOVL AX, (R10)\n\tMOVL CX, -4(R10)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R10\n\tJMP  copy_4_end\n\ncopy_4_move_8through16:\n\tMOVQ (R14), AX\n\tMOVQ -8(R14)(R13*1), CX\n\tMOVQ AX, (R10)\n\tMOVQ CX, -8(R10)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R10\n\ncopy_4_end:\n\tADDQ R13, R12\n\tJMP  handle_loop\n\tJMP loop_finished\n\ncopy_all_from_history:\n\tMOVQ AX, R15\n\tSUBQ $0x10, R15\n\tJB   copy_5_small\n\ncopy_5_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R10)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R10\n\tSUBQ   $0x10, R15\n\tJAE    copy_5_loop\n\tLEAQ   16(R14)(R15*1), R14\n\tLEAQ   16(R10)(R15*1), R10\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R10)\n\tJMP    copy_5_end\n\ncopy_5_small:\n\tCMPQ AX, $0x03\n\tJE   copy_5_move_3\n\tJB   copy_5_move_1or2\n\tCMPQ AX, $0x08\n\tJB   copy_5_move_4through7\n\tJMP  copy_5_move_8through16\n\ncopy_5_move_1or2:\n\tMOVB (R14), R15\n\tMOVB -1(R14)(AX*1), BP\n\tMOVB R15, (R10)\n\tMOVB BP, -1(R10)(AX*1)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\tJMP  copy_5_end\n\ncopy_5_move_3:\n\tMOVW (R14), R15\n\tMOVB 2(R14), BP\n\tMOVW R15, (R10)\n\tMOVB BP, 2(R10)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\tJMP  copy_5_end\n\ncopy_5_move_4through7:\n\tMOVL (R14), R15\n\tMOVL -4(R14)(AX*1), BP\n\tMOVL R15, (R10)\n\tMOVL BP, -4(R10)(AX*1)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\tJMP  copy_5_end\n\ncopy_5_move_8through16:\n\tMOVQ (R14), R15\n\tMOVQ -8(R14)(AX*1), BP\n\tMOVQ R15, (R10)\n\tMOVQ BP, -8(R10)(AX*1)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\ncopy_5_end:\n\tADDQ AX, R12\n\tSUBQ AX, R13\n\n\t// Copy match from the current buffer\ncopy_match:\n\tMOVQ R10, AX\n\tSUBQ CX, AX\n\n\t// ml <= mo\n\tCMPQ R13, CX\n\tJA   copy_overlapping_match\n\n\t// Copy non-overlapping match\n\tADDQ R13, R12\n\tMOVQ R10, CX\n\tADDQ R13, R10\n\ncopy_2:\n\tMOVUPS (AX), X0\n\tMOVUPS X0, (CX)\n\tADDQ   $0x10, AX\n\tADDQ   $0x10, CX\n\tSUBQ   $0x10, R13\n\tJHI    copy_2\n\tJMP    handle_loop\n\n\t// Copy overlapping match\ncopy_overlapping_match:\n\tADDQ R13, R12\n\ncopy_slow_3:\n\tMOVB (AX), CL\n\tMOVB CL, (R10)\n\tINCQ AX\n\tINCQ R10\n\tDECQ R13\n\tJNZ  copy_slow_3\n\nhandle_loop:\n\tMOVQ ctx+16(FP), AX\n\tDECQ 96(AX)\n\tJNS  sequenceDecs_decodeSync_amd64_main_loop\n\nloop_finished:\n\tMOVQ br+8(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVB BL, 32(AX)\n\tMOVQ SI, 8(AX)\n\n\t// Update the context\n\tMOVQ ctx+16(FP), AX\n\tMOVQ R12, 136(AX)\n\tMOVQ 144(AX), CX\n\tSUBQ CX, R11\n\tMOVQ R11, 168(AX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch:\n\tMOVQ 16(SP), AX\n\tMOVQ ctx+16(FP), CX\n\tMOVQ AX, 216(CX)\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decodeSync_amd64_error_match_len_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\nerror_match_off_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 8(SP), CX\n\tMOVQ CX, 224(AX)\n\tMOVQ R12, 136(AX)\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n\t// Return with not enough output space error\nerror_not_enough_space:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ R12, 136(AX)\n\tMOVQ $0x00000005, ret+24(FP)\n\tRET\n\n// func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n// Requires: BMI, BMI2, CMOV, SSE\nTEXT ·sequenceDecs_decodeSync_bmi2(SB), $64-32\n\tMOVQ    br+8(FP), BX\n\tMOVQ    24(BX), AX\n\tMOVBQZX 32(BX), DX\n\tMOVQ    (BX), CX\n\tMOVQ    8(BX), BX\n\tADDQ    BX, CX\n\tMOVQ    CX, (SP)\n\tMOVQ    ctx+16(FP), CX\n\tMOVQ    72(CX), SI\n\tMOVQ    80(CX), DI\n\tMOVQ    88(CX), R8\n\tXORQ    R9, R9\n\tMOVQ    R9, 8(SP)\n\tMOVQ    R9, 16(SP)\n\tMOVQ    R9, 24(SP)\n\tMOVQ    112(CX), R9\n\tMOVQ    128(CX), R10\n\tMOVQ    R10, 32(SP)\n\tMOVQ    144(CX), R10\n\tMOVQ    136(CX), R11\n\tMOVQ    200(CX), R12\n\tMOVQ    R12, 56(SP)\n\tMOVQ    176(CX), R12\n\tMOVQ    R12, 48(SP)\n\tMOVQ    184(CX), CX\n\tMOVQ    CX, 40(SP)\n\tMOVQ    40(SP), CX\n\tADDQ    CX, 48(SP)\n\n\t// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)\n\tADDQ R9, 32(SP)\n\n\t// outBase += outPosition\n\tADDQ R11, R9\n\nsequenceDecs_decodeSync_bmi2_main_loop:\n\tMOVQ (SP), R12\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ BX, $0x08\n\tJL   sequenceDecs_decodeSync_bmi2_fill_byte_by_byte\n\tMOVQ DX, CX\n\tSHRQ $0x03, CX\n\tSUBQ CX, R12\n\tMOVQ (R12), AX\n\tSUBQ CX, BX\n\tANDQ $0x07, DX\n\tJMP  sequenceDecs_decodeSync_bmi2_fill_end\n\nsequenceDecs_decodeSync_bmi2_fill_byte_by_byte:\n\tCMPQ    BX, $0x00\n\tJLE     sequenceDecs_decodeSync_bmi2_fill_check_overread\n\tCMPQ    DX, $0x07\n\tJLE     sequenceDecs_decodeSync_bmi2_fill_end\n\tSHLQ    $0x08, AX\n\tSUBQ    $0x01, R12\n\tSUBQ    $0x01, BX\n\tSUBQ    $0x08, DX\n\tMOVBQZX (R12), CX\n\tORQ     CX, AX\n\tJMP     sequenceDecs_decodeSync_bmi2_fill_byte_by_byte\n\nsequenceDecs_decodeSync_bmi2_fill_check_overread:\n\tCMPQ DX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_bmi2_fill_end:\n\t// Update offset\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, R8, R13\n\tMOVQ   AX, R14\n\tLEAQ   (DX)(R13*1), CX\n\tROLQ   CL, R14\n\tBZHIQ  R13, R14, R14\n\tMOVQ   CX, DX\n\tMOVQ   R8, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R14, CX\n\tMOVQ   CX, 8(SP)\n\n\t// Update match length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, DI, R13\n\tMOVQ   AX, R14\n\tLEAQ   (DX)(R13*1), CX\n\tROLQ   CL, R14\n\tBZHIQ  R13, R14, R14\n\tMOVQ   CX, DX\n\tMOVQ   DI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R14, CX\n\tMOVQ   CX, 16(SP)\n\n\t// Fill bitreader to have enough for the remaining\n\tCMPQ BX, $0x08\n\tJL   sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte\n\tMOVQ DX, CX\n\tSHRQ $0x03, CX\n\tSUBQ CX, R12\n\tMOVQ (R12), AX\n\tSUBQ CX, BX\n\tANDQ $0x07, DX\n\tJMP  sequenceDecs_decodeSync_bmi2_fill_2_end\n\nsequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte:\n\tCMPQ    BX, $0x00\n\tJLE     sequenceDecs_decodeSync_bmi2_fill_2_check_overread\n\tCMPQ    DX, $0x07\n\tJLE     sequenceDecs_decodeSync_bmi2_fill_2_end\n\tSHLQ    $0x08, AX\n\tSUBQ    $0x01, R12\n\tSUBQ    $0x01, BX\n\tSUBQ    $0x08, DX\n\tMOVBQZX (R12), CX\n\tORQ     CX, AX\n\tJMP     sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte\n\nsequenceDecs_decodeSync_bmi2_fill_2_check_overread:\n\tCMPQ DX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_bmi2_fill_2_end:\n\t// Update literal length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, SI, R13\n\tMOVQ   AX, R14\n\tLEAQ   (DX)(R13*1), CX\n\tROLQ   CL, R14\n\tBZHIQ  R13, R14, R14\n\tMOVQ   CX, DX\n\tMOVQ   SI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R14, CX\n\tMOVQ   CX, 24(SP)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R12, (SP)\n\tMOVQ    $0x00000808, CX\n\tBEXTRQ  CX, R8, R12\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decodeSync_bmi2_skip_update\n\tLEAQ    (SI)(DI*1), R13\n\tADDQ    R8, R13\n\tMOVBQZX R13, R13\n\tLEAQ    (DX)(R13*1), CX\n\tMOVQ    AX, R14\n\tMOVQ    CX, DX\n\tROLQ    CL, R14\n\tBZHIQ   R13, R14, R14\n\n\t// Update Offset State\n\tBZHIQ  R8, R14, CX\n\tSHRXQ  R8, R14, R14\n\tMOVQ   $0x00001010, R13\n\tBEXTRQ R13, R8, R8\n\tADDQ   CX, R8\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Match Length State\n\tBZHIQ  DI, R14, CX\n\tSHRXQ  DI, R14, R14\n\tMOVQ   $0x00001010, R13\n\tBEXTRQ R13, DI, DI\n\tADDQ   CX, DI\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Literal Length State\n\tBZHIQ  SI, R14, CX\n\tMOVQ   $0x00001010, R13\n\tBEXTRQ R13, SI, SI\n\tADDQ   CX, SI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(SI*8), SI\n\nsequenceDecs_decodeSync_bmi2_skip_update:\n\t// Adjust offset\n\tMOVQ   s+0(FP), CX\n\tMOVQ   8(SP), R13\n\tCMPQ   R12, $0x01\n\tJBE    sequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0\n\tMOVUPS 144(CX), X0\n\tMOVQ   R13, 144(CX)\n\tMOVUPS X0, 152(CX)\n\tJMP    sequenceDecs_decodeSync_bmi2_after_adjust\n\nsequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0:\n\tCMPQ 24(SP), $0x00000000\n\tJNE  sequenceDecs_decodeSync_bmi2_adjust_offset_maybezero\n\tINCQ R13\n\tJMP  sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero\n\nsequenceDecs_decodeSync_bmi2_adjust_offset_maybezero:\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero\n\tMOVQ  144(CX), R13\n\tJMP   sequenceDecs_decodeSync_bmi2_after_adjust\n\nsequenceDecs_decodeSync_bmi2_adjust_offset_nonzero:\n\tMOVQ    R13, R12\n\tXORQ    R14, R14\n\tMOVQ    $-1, R15\n\tCMPQ    R13, $0x03\n\tCMOVQEQ R14, R12\n\tCMOVQEQ R15, R14\n\tADDQ    144(CX)(R12*8), R14\n\tJNZ     sequenceDecs_decodeSync_bmi2_adjust_temp_valid\n\tMOVQ    $0x00000001, R14\n\nsequenceDecs_decodeSync_bmi2_adjust_temp_valid:\n\tCMPQ R13, $0x01\n\tJZ   sequenceDecs_decodeSync_bmi2_adjust_skip\n\tMOVQ 152(CX), R12\n\tMOVQ R12, 160(CX)\n\nsequenceDecs_decodeSync_bmi2_adjust_skip:\n\tMOVQ 144(CX), R12\n\tMOVQ R12, 152(CX)\n\tMOVQ R14, 144(CX)\n\tMOVQ R14, R13\n\nsequenceDecs_decodeSync_bmi2_after_adjust:\n\tMOVQ R13, 8(SP)\n\n\t// Check values\n\tMOVQ  16(SP), CX\n\tMOVQ  24(SP), R12\n\tLEAQ  (CX)(R12*1), R14\n\tMOVQ  s+0(FP), R15\n\tADDQ  R14, 256(R15)\n\tMOVQ  ctx+16(FP), R14\n\tSUBQ  R12, 104(R14)\n\tJS    error_not_enough_literals\n\tCMPQ  CX, $0x00020002\n\tJA    sequenceDecs_decodeSync_bmi2_error_match_len_too_big\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_bmi2_match_len_ofs_ok\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch\n\nsequenceDecs_decodeSync_bmi2_match_len_ofs_ok:\n\tMOVQ 24(SP), CX\n\tMOVQ 8(SP), R12\n\tMOVQ 16(SP), R13\n\n\t// Check if we have enough space in s.out\n\tLEAQ (CX)(R13*1), R14\n\tADDQ R9, R14\n\tCMPQ R14, 32(SP)\n\tJA   error_not_enough_space\n\n\t// Copy literals\n\tTESTQ CX, CX\n\tJZ    check_offset\n\tXORQ  R14, R14\n\ncopy_1:\n\tMOVUPS (R10)(R14*1), X0\n\tMOVUPS X0, (R9)(R14*1)\n\tADDQ   $0x10, R14\n\tCMPQ   R14, CX\n\tJB     copy_1\n\tADDQ   CX, R10\n\tADDQ   CX, R9\n\tADDQ   CX, R11\n\n\t// Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize)\ncheck_offset:\n\tMOVQ R11, CX\n\tADDQ 40(SP), CX\n\tCMPQ R12, CX\n\tJG   error_match_off_too_big\n\tCMPQ R12, 56(SP)\n\tJG   error_match_off_too_big\n\n\t// Copy match from history\n\tMOVQ R12, CX\n\tSUBQ R11, CX\n\tJLS  copy_match\n\tMOVQ 48(SP), R14\n\tSUBQ CX, R14\n\tCMPQ R13, CX\n\tJG   copy_all_from_history\n\tMOVQ R13, CX\n\tSUBQ $0x10, CX\n\tJB   copy_4_small\n\ncopy_4_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R9)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R9\n\tSUBQ   $0x10, CX\n\tJAE    copy_4_loop\n\tLEAQ   16(R14)(CX*1), R14\n\tLEAQ   16(R9)(CX*1), R9\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R9)\n\tJMP    copy_4_end\n\ncopy_4_small:\n\tCMPQ R13, $0x03\n\tJE   copy_4_move_3\n\tCMPQ R13, $0x08\n\tJB   copy_4_move_4through7\n\tJMP  copy_4_move_8through16\n\ncopy_4_move_3:\n\tMOVW (R14), CX\n\tMOVB 2(R14), R12\n\tMOVW CX, (R9)\n\tMOVB R12, 2(R9)\n\tADDQ R13, R14\n\tADDQ R13, R9\n\tJMP  copy_4_end\n\ncopy_4_move_4through7:\n\tMOVL (R14), CX\n\tMOVL -4(R14)(R13*1), R12\n\tMOVL CX, (R9)\n\tMOVL R12, -4(R9)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R9\n\tJMP  copy_4_end\n\ncopy_4_move_8through16:\n\tMOVQ (R14), CX\n\tMOVQ -8(R14)(R13*1), R12\n\tMOVQ CX, (R9)\n\tMOVQ R12, -8(R9)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R9\n\ncopy_4_end:\n\tADDQ R13, R11\n\tJMP  handle_loop\n\tJMP loop_finished\n\ncopy_all_from_history:\n\tMOVQ CX, R15\n\tSUBQ $0x10, R15\n\tJB   copy_5_small\n\ncopy_5_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R9)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R9\n\tSUBQ   $0x10, R15\n\tJAE    copy_5_loop\n\tLEAQ   16(R14)(R15*1), R14\n\tLEAQ   16(R9)(R15*1), R9\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R9)\n\tJMP    copy_5_end\n\ncopy_5_small:\n\tCMPQ CX, $0x03\n\tJE   copy_5_move_3\n\tJB   copy_5_move_1or2\n\tCMPQ CX, $0x08\n\tJB   copy_5_move_4through7\n\tJMP  copy_5_move_8through16\n\ncopy_5_move_1or2:\n\tMOVB (R14), R15\n\tMOVB -1(R14)(CX*1), BP\n\tMOVB R15, (R9)\n\tMOVB BP, -1(R9)(CX*1)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\tJMP  copy_5_end\n\ncopy_5_move_3:\n\tMOVW (R14), R15\n\tMOVB 2(R14), BP\n\tMOVW R15, (R9)\n\tMOVB BP, 2(R9)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\tJMP  copy_5_end\n\ncopy_5_move_4through7:\n\tMOVL (R14), R15\n\tMOVL -4(R14)(CX*1), BP\n\tMOVL R15, (R9)\n\tMOVL BP, -4(R9)(CX*1)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\tJMP  copy_5_end\n\ncopy_5_move_8through16:\n\tMOVQ (R14), R15\n\tMOVQ -8(R14)(CX*1), BP\n\tMOVQ R15, (R9)\n\tMOVQ BP, -8(R9)(CX*1)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\ncopy_5_end:\n\tADDQ CX, R11\n\tSUBQ CX, R13\n\n\t// Copy match from the current buffer\ncopy_match:\n\tMOVQ R9, CX\n\tSUBQ R12, CX\n\n\t// ml <= mo\n\tCMPQ R13, R12\n\tJA   copy_overlapping_match\n\n\t// Copy non-overlapping match\n\tADDQ R13, R11\n\tMOVQ R9, R12\n\tADDQ R13, R9\n\ncopy_2:\n\tMOVUPS (CX), X0\n\tMOVUPS X0, (R12)\n\tADDQ   $0x10, CX\n\tADDQ   $0x10, R12\n\tSUBQ   $0x10, R13\n\tJHI    copy_2\n\tJMP    handle_loop\n\n\t// Copy overlapping match\ncopy_overlapping_match:\n\tADDQ R13, R11\n\ncopy_slow_3:\n\tMOVB (CX), R12\n\tMOVB R12, (R9)\n\tINCQ CX\n\tINCQ R9\n\tDECQ R13\n\tJNZ  copy_slow_3\n\nhandle_loop:\n\tMOVQ ctx+16(FP), CX\n\tDECQ 96(CX)\n\tJNS  sequenceDecs_decodeSync_bmi2_main_loop\n\nloop_finished:\n\tMOVQ br+8(FP), CX\n\tMOVQ AX, 24(CX)\n\tMOVB DL, 32(CX)\n\tMOVQ BX, 8(CX)\n\n\t// Update the context\n\tMOVQ ctx+16(FP), AX\n\tMOVQ R11, 136(AX)\n\tMOVQ 144(AX), CX\n\tSUBQ CX, R10\n\tMOVQ R10, 168(AX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch:\n\tMOVQ 16(SP), AX\n\tMOVQ ctx+16(FP), CX\n\tMOVQ AX, 216(CX)\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decodeSync_bmi2_error_match_len_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\nerror_match_off_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 8(SP), CX\n\tMOVQ CX, 224(AX)\n\tMOVQ R11, 136(AX)\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n\t// Return with not enough output space error\nerror_not_enough_space:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ R11, 136(AX)\n\tMOVQ $0x00000005, ret+24(FP)\n\tRET\n\n// func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n// Requires: CMOV, SSE\nTEXT ·sequenceDecs_decodeSync_safe_amd64(SB), $64-32\n\tMOVQ    br+8(FP), CX\n\tMOVQ    24(CX), DX\n\tMOVBQZX 32(CX), BX\n\tMOVQ    (CX), AX\n\tMOVQ    8(CX), SI\n\tADDQ    SI, AX\n\tMOVQ    AX, (SP)\n\tMOVQ    ctx+16(FP), AX\n\tMOVQ    72(AX), DI\n\tMOVQ    80(AX), R8\n\tMOVQ    88(AX), R9\n\tXORQ    CX, CX\n\tMOVQ    CX, 8(SP)\n\tMOVQ    CX, 16(SP)\n\tMOVQ    CX, 24(SP)\n\tMOVQ    112(AX), R10\n\tMOVQ    128(AX), CX\n\tMOVQ    CX, 32(SP)\n\tMOVQ    144(AX), R11\n\tMOVQ    136(AX), R12\n\tMOVQ    200(AX), CX\n\tMOVQ    CX, 56(SP)\n\tMOVQ    176(AX), CX\n\tMOVQ    CX, 48(SP)\n\tMOVQ    184(AX), AX\n\tMOVQ    AX, 40(SP)\n\tMOVQ    40(SP), AX\n\tADDQ    AX, 48(SP)\n\n\t// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)\n\tADDQ R10, 32(SP)\n\n\t// outBase += outPosition\n\tADDQ R12, R10\n\nsequenceDecs_decodeSync_safe_amd64_main_loop:\n\tMOVQ (SP), R13\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ SI, $0x08\n\tJL   sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte\n\tMOVQ BX, AX\n\tSHRQ $0x03, AX\n\tSUBQ AX, R13\n\tMOVQ (R13), DX\n\tSUBQ AX, SI\n\tANDQ $0x07, BX\n\tJMP  sequenceDecs_decodeSync_safe_amd64_fill_end\n\nsequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte:\n\tCMPQ    SI, $0x00\n\tJLE     sequenceDecs_decodeSync_safe_amd64_fill_check_overread\n\tCMPQ    BX, $0x07\n\tJLE     sequenceDecs_decodeSync_safe_amd64_fill_end\n\tSHLQ    $0x08, DX\n\tSUBQ    $0x01, R13\n\tSUBQ    $0x01, SI\n\tSUBQ    $0x08, BX\n\tMOVBQZX (R13), AX\n\tORQ     AX, DX\n\tJMP     sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte\n\nsequenceDecs_decodeSync_safe_amd64_fill_check_overread:\n\tCMPQ BX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_safe_amd64_fill_end:\n\t// Update offset\n\tMOVQ  R9, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R14\n\tSHLQ  CL, R14\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decodeSync_safe_amd64_of_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decodeSync_safe_amd64_of_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decodeSync_safe_amd64_of_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R14\n\tADDQ  R14, AX\n\nsequenceDecs_decodeSync_safe_amd64_of_update_zero:\n\tMOVQ AX, 8(SP)\n\n\t// Update match length\n\tMOVQ  R8, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R14\n\tSHLQ  CL, R14\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decodeSync_safe_amd64_ml_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decodeSync_safe_amd64_ml_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decodeSync_safe_amd64_ml_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R14\n\tADDQ  R14, AX\n\nsequenceDecs_decodeSync_safe_amd64_ml_update_zero:\n\tMOVQ AX, 16(SP)\n\n\t// Fill bitreader to have enough for the remaining\n\tCMPQ SI, $0x08\n\tJL   sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte\n\tMOVQ BX, AX\n\tSHRQ $0x03, AX\n\tSUBQ AX, R13\n\tMOVQ (R13), DX\n\tSUBQ AX, SI\n\tANDQ $0x07, BX\n\tJMP  sequenceDecs_decodeSync_safe_amd64_fill_2_end\n\nsequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte:\n\tCMPQ    SI, $0x00\n\tJLE     sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread\n\tCMPQ    BX, $0x07\n\tJLE     sequenceDecs_decodeSync_safe_amd64_fill_2_end\n\tSHLQ    $0x08, DX\n\tSUBQ    $0x01, R13\n\tSUBQ    $0x01, SI\n\tSUBQ    $0x08, BX\n\tMOVBQZX (R13), AX\n\tORQ     AX, DX\n\tJMP     sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte\n\nsequenceDecs_decodeSync_safe_amd64_fill_2_check_overread:\n\tCMPQ BX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_safe_amd64_fill_2_end:\n\t// Update literal length\n\tMOVQ  DI, AX\n\tMOVQ  BX, CX\n\tMOVQ  DX, R14\n\tSHLQ  CL, R14\n\tMOVB  AH, CL\n\tSHRQ  $0x20, AX\n\tTESTQ CX, CX\n\tJZ    sequenceDecs_decodeSync_safe_amd64_ll_update_zero\n\tADDQ  CX, BX\n\tCMPQ  BX, $0x40\n\tJA    sequenceDecs_decodeSync_safe_amd64_ll_update_zero\n\tCMPQ  CX, $0x40\n\tJAE   sequenceDecs_decodeSync_safe_amd64_ll_update_zero\n\tNEGQ  CX\n\tSHRQ  CL, R14\n\tADDQ  R14, AX\n\nsequenceDecs_decodeSync_safe_amd64_ll_update_zero:\n\tMOVQ AX, 24(SP)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R13, (SP)\n\tMOVQ    R9, AX\n\tSHRQ    $0x08, AX\n\tMOVBQZX AL, AX\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decodeSync_safe_amd64_skip_update\n\n\t// Update Literal Length State\n\tMOVBQZX DI, R13\n\tSHRQ    $0x10, DI\n\tMOVWQZX DI, DI\n\tLEAQ    (BX)(R13*1), CX\n\tMOVQ    DX, R14\n\tMOVQ    CX, BX\n\tROLQ    CL, R14\n\tMOVL    $0x00000001, R15\n\tMOVB    R13, CL\n\tSHLL    CL, R15\n\tDECL    R15\n\tANDQ    R15, R14\n\tADDQ    R14, DI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Match Length State\n\tMOVBQZX R8, R13\n\tSHRQ    $0x10, R8\n\tMOVWQZX R8, R8\n\tLEAQ    (BX)(R13*1), CX\n\tMOVQ    DX, R14\n\tMOVQ    CX, BX\n\tROLQ    CL, R14\n\tMOVL    $0x00000001, R15\n\tMOVB    R13, CL\n\tSHLL    CL, R15\n\tDECL    R15\n\tANDQ    R15, R14\n\tADDQ    R14, R8\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Offset State\n\tMOVBQZX R9, R13\n\tSHRQ    $0x10, R9\n\tMOVWQZX R9, R9\n\tLEAQ    (BX)(R13*1), CX\n\tMOVQ    DX, R14\n\tMOVQ    CX, BX\n\tROLQ    CL, R14\n\tMOVL    $0x00000001, R15\n\tMOVB    R13, CL\n\tSHLL    CL, R15\n\tDECL    R15\n\tANDQ    R15, R14\n\tADDQ    R14, R9\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R9*8), R9\n\nsequenceDecs_decodeSync_safe_amd64_skip_update:\n\t// Adjust offset\n\tMOVQ   s+0(FP), CX\n\tMOVQ   8(SP), R13\n\tCMPQ   AX, $0x01\n\tJBE    sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0\n\tMOVUPS 144(CX), X0\n\tMOVQ   R13, 144(CX)\n\tMOVUPS X0, 152(CX)\n\tJMP    sequenceDecs_decodeSync_safe_amd64_after_adjust\n\nsequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0:\n\tCMPQ 24(SP), $0x00000000\n\tJNE  sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero\n\tINCQ R13\n\tJMP  sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero\n\nsequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero:\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero\n\tMOVQ  144(CX), R13\n\tJMP   sequenceDecs_decodeSync_safe_amd64_after_adjust\n\nsequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero:\n\tMOVQ    R13, AX\n\tXORQ    R14, R14\n\tMOVQ    $-1, R15\n\tCMPQ    R13, $0x03\n\tCMOVQEQ R14, AX\n\tCMOVQEQ R15, R14\n\tADDQ    144(CX)(AX*8), R14\n\tJNZ     sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid\n\tMOVQ    $0x00000001, R14\n\nsequenceDecs_decodeSync_safe_amd64_adjust_temp_valid:\n\tCMPQ R13, $0x01\n\tJZ   sequenceDecs_decodeSync_safe_amd64_adjust_skip\n\tMOVQ 152(CX), AX\n\tMOVQ AX, 160(CX)\n\nsequenceDecs_decodeSync_safe_amd64_adjust_skip:\n\tMOVQ 144(CX), AX\n\tMOVQ AX, 152(CX)\n\tMOVQ R14, 144(CX)\n\tMOVQ R14, R13\n\nsequenceDecs_decodeSync_safe_amd64_after_adjust:\n\tMOVQ R13, 8(SP)\n\n\t// Check values\n\tMOVQ  16(SP), AX\n\tMOVQ  24(SP), CX\n\tLEAQ  (AX)(CX*1), R14\n\tMOVQ  s+0(FP), R15\n\tADDQ  R14, 256(R15)\n\tMOVQ  ctx+16(FP), R14\n\tSUBQ  CX, 104(R14)\n\tJS    error_not_enough_literals\n\tCMPQ  AX, $0x00020002\n\tJA    sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok\n\tTESTQ AX, AX\n\tJNZ   sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch\n\nsequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok:\n\tMOVQ 24(SP), AX\n\tMOVQ 8(SP), CX\n\tMOVQ 16(SP), R13\n\n\t// Check if we have enough space in s.out\n\tLEAQ (AX)(R13*1), R14\n\tADDQ R10, R14\n\tCMPQ R14, 32(SP)\n\tJA   error_not_enough_space\n\n\t// Copy literals\n\tTESTQ AX, AX\n\tJZ    check_offset\n\tMOVQ  AX, R14\n\tSUBQ  $0x10, R14\n\tJB    copy_1_small\n\ncopy_1_loop:\n\tMOVUPS (R11), X0\n\tMOVUPS X0, (R10)\n\tADDQ   $0x10, R11\n\tADDQ   $0x10, R10\n\tSUBQ   $0x10, R14\n\tJAE    copy_1_loop\n\tLEAQ   16(R11)(R14*1), R11\n\tLEAQ   16(R10)(R14*1), R10\n\tMOVUPS -16(R11), X0\n\tMOVUPS X0, -16(R10)\n\tJMP    copy_1_end\n\ncopy_1_small:\n\tCMPQ AX, $0x03\n\tJE   copy_1_move_3\n\tJB   copy_1_move_1or2\n\tCMPQ AX, $0x08\n\tJB   copy_1_move_4through7\n\tJMP  copy_1_move_8through16\n\ncopy_1_move_1or2:\n\tMOVB (R11), R14\n\tMOVB -1(R11)(AX*1), R15\n\tMOVB R14, (R10)\n\tMOVB R15, -1(R10)(AX*1)\n\tADDQ AX, R11\n\tADDQ AX, R10\n\tJMP  copy_1_end\n\ncopy_1_move_3:\n\tMOVW (R11), R14\n\tMOVB 2(R11), R15\n\tMOVW R14, (R10)\n\tMOVB R15, 2(R10)\n\tADDQ AX, R11\n\tADDQ AX, R10\n\tJMP  copy_1_end\n\ncopy_1_move_4through7:\n\tMOVL (R11), R14\n\tMOVL -4(R11)(AX*1), R15\n\tMOVL R14, (R10)\n\tMOVL R15, -4(R10)(AX*1)\n\tADDQ AX, R11\n\tADDQ AX, R10\n\tJMP  copy_1_end\n\ncopy_1_move_8through16:\n\tMOVQ (R11), R14\n\tMOVQ -8(R11)(AX*1), R15\n\tMOVQ R14, (R10)\n\tMOVQ R15, -8(R10)(AX*1)\n\tADDQ AX, R11\n\tADDQ AX, R10\n\ncopy_1_end:\n\tADDQ AX, R12\n\n\t// Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize)\ncheck_offset:\n\tMOVQ R12, AX\n\tADDQ 40(SP), AX\n\tCMPQ CX, AX\n\tJG   error_match_off_too_big\n\tCMPQ CX, 56(SP)\n\tJG   error_match_off_too_big\n\n\t// Copy match from history\n\tMOVQ CX, AX\n\tSUBQ R12, AX\n\tJLS  copy_match\n\tMOVQ 48(SP), R14\n\tSUBQ AX, R14\n\tCMPQ R13, AX\n\tJG   copy_all_from_history\n\tMOVQ R13, AX\n\tSUBQ $0x10, AX\n\tJB   copy_4_small\n\ncopy_4_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R10)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R10\n\tSUBQ   $0x10, AX\n\tJAE    copy_4_loop\n\tLEAQ   16(R14)(AX*1), R14\n\tLEAQ   16(R10)(AX*1), R10\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R10)\n\tJMP    copy_4_end\n\ncopy_4_small:\n\tCMPQ R13, $0x03\n\tJE   copy_4_move_3\n\tCMPQ R13, $0x08\n\tJB   copy_4_move_4through7\n\tJMP  copy_4_move_8through16\n\ncopy_4_move_3:\n\tMOVW (R14), AX\n\tMOVB 2(R14), CL\n\tMOVW AX, (R10)\n\tMOVB CL, 2(R10)\n\tADDQ R13, R14\n\tADDQ R13, R10\n\tJMP  copy_4_end\n\ncopy_4_move_4through7:\n\tMOVL (R14), AX\n\tMOVL -4(R14)(R13*1), CX\n\tMOVL AX, (R10)\n\tMOVL CX, -4(R10)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R10\n\tJMP  copy_4_end\n\ncopy_4_move_8through16:\n\tMOVQ (R14), AX\n\tMOVQ -8(R14)(R13*1), CX\n\tMOVQ AX, (R10)\n\tMOVQ CX, -8(R10)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R10\n\ncopy_4_end:\n\tADDQ R13, R12\n\tJMP  handle_loop\n\tJMP loop_finished\n\ncopy_all_from_history:\n\tMOVQ AX, R15\n\tSUBQ $0x10, R15\n\tJB   copy_5_small\n\ncopy_5_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R10)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R10\n\tSUBQ   $0x10, R15\n\tJAE    copy_5_loop\n\tLEAQ   16(R14)(R15*1), R14\n\tLEAQ   16(R10)(R15*1), R10\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R10)\n\tJMP    copy_5_end\n\ncopy_5_small:\n\tCMPQ AX, $0x03\n\tJE   copy_5_move_3\n\tJB   copy_5_move_1or2\n\tCMPQ AX, $0x08\n\tJB   copy_5_move_4through7\n\tJMP  copy_5_move_8through16\n\ncopy_5_move_1or2:\n\tMOVB (R14), R15\n\tMOVB -1(R14)(AX*1), BP\n\tMOVB R15, (R10)\n\tMOVB BP, -1(R10)(AX*1)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\tJMP  copy_5_end\n\ncopy_5_move_3:\n\tMOVW (R14), R15\n\tMOVB 2(R14), BP\n\tMOVW R15, (R10)\n\tMOVB BP, 2(R10)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\tJMP  copy_5_end\n\ncopy_5_move_4through7:\n\tMOVL (R14), R15\n\tMOVL -4(R14)(AX*1), BP\n\tMOVL R15, (R10)\n\tMOVL BP, -4(R10)(AX*1)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\tJMP  copy_5_end\n\ncopy_5_move_8through16:\n\tMOVQ (R14), R15\n\tMOVQ -8(R14)(AX*1), BP\n\tMOVQ R15, (R10)\n\tMOVQ BP, -8(R10)(AX*1)\n\tADDQ AX, R14\n\tADDQ AX, R10\n\ncopy_5_end:\n\tADDQ AX, R12\n\tSUBQ AX, R13\n\n\t// Copy match from the current buffer\ncopy_match:\n\tMOVQ R10, AX\n\tSUBQ CX, AX\n\n\t// ml <= mo\n\tCMPQ R13, CX\n\tJA   copy_overlapping_match\n\n\t// Copy non-overlapping match\n\tADDQ R13, R12\n\tMOVQ R13, CX\n\tSUBQ $0x10, CX\n\tJB   copy_2_small\n\ncopy_2_loop:\n\tMOVUPS (AX), X0\n\tMOVUPS X0, (R10)\n\tADDQ   $0x10, AX\n\tADDQ   $0x10, R10\n\tSUBQ   $0x10, CX\n\tJAE    copy_2_loop\n\tLEAQ   16(AX)(CX*1), AX\n\tLEAQ   16(R10)(CX*1), R10\n\tMOVUPS -16(AX), X0\n\tMOVUPS X0, -16(R10)\n\tJMP    copy_2_end\n\ncopy_2_small:\n\tCMPQ R13, $0x03\n\tJE   copy_2_move_3\n\tJB   copy_2_move_1or2\n\tCMPQ R13, $0x08\n\tJB   copy_2_move_4through7\n\tJMP  copy_2_move_8through16\n\ncopy_2_move_1or2:\n\tMOVB (AX), CL\n\tMOVB -1(AX)(R13*1), R14\n\tMOVB CL, (R10)\n\tMOVB R14, -1(R10)(R13*1)\n\tADDQ R13, AX\n\tADDQ R13, R10\n\tJMP  copy_2_end\n\ncopy_2_move_3:\n\tMOVW (AX), CX\n\tMOVB 2(AX), R14\n\tMOVW CX, (R10)\n\tMOVB R14, 2(R10)\n\tADDQ R13, AX\n\tADDQ R13, R10\n\tJMP  copy_2_end\n\ncopy_2_move_4through7:\n\tMOVL (AX), CX\n\tMOVL -4(AX)(R13*1), R14\n\tMOVL CX, (R10)\n\tMOVL R14, -4(R10)(R13*1)\n\tADDQ R13, AX\n\tADDQ R13, R10\n\tJMP  copy_2_end\n\ncopy_2_move_8through16:\n\tMOVQ (AX), CX\n\tMOVQ -8(AX)(R13*1), R14\n\tMOVQ CX, (R10)\n\tMOVQ R14, -8(R10)(R13*1)\n\tADDQ R13, AX\n\tADDQ R13, R10\n\ncopy_2_end:\n\tJMP handle_loop\n\n\t// Copy overlapping match\ncopy_overlapping_match:\n\tADDQ R13, R12\n\ncopy_slow_3:\n\tMOVB (AX), CL\n\tMOVB CL, (R10)\n\tINCQ AX\n\tINCQ R10\n\tDECQ R13\n\tJNZ  copy_slow_3\n\nhandle_loop:\n\tMOVQ ctx+16(FP), AX\n\tDECQ 96(AX)\n\tJNS  sequenceDecs_decodeSync_safe_amd64_main_loop\n\nloop_finished:\n\tMOVQ br+8(FP), AX\n\tMOVQ DX, 24(AX)\n\tMOVB BL, 32(AX)\n\tMOVQ SI, 8(AX)\n\n\t// Update the context\n\tMOVQ ctx+16(FP), AX\n\tMOVQ R12, 136(AX)\n\tMOVQ 144(AX), CX\n\tSUBQ CX, R11\n\tMOVQ R11, 168(AX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch:\n\tMOVQ 16(SP), AX\n\tMOVQ ctx+16(FP), CX\n\tMOVQ AX, 216(CX)\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decodeSync_safe_amd64_error_match_len_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\nerror_match_off_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 8(SP), CX\n\tMOVQ CX, 224(AX)\n\tMOVQ R12, 136(AX)\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n\t// Return with not enough output space error\nerror_not_enough_space:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ R12, 136(AX)\n\tMOVQ $0x00000005, ret+24(FP)\n\tRET\n\n// func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int\n// Requires: BMI, BMI2, CMOV, SSE\nTEXT ·sequenceDecs_decodeSync_safe_bmi2(SB), $64-32\n\tMOVQ    br+8(FP), BX\n\tMOVQ    24(BX), AX\n\tMOVBQZX 32(BX), DX\n\tMOVQ    (BX), CX\n\tMOVQ    8(BX), BX\n\tADDQ    BX, CX\n\tMOVQ    CX, (SP)\n\tMOVQ    ctx+16(FP), CX\n\tMOVQ    72(CX), SI\n\tMOVQ    80(CX), DI\n\tMOVQ    88(CX), R8\n\tXORQ    R9, R9\n\tMOVQ    R9, 8(SP)\n\tMOVQ    R9, 16(SP)\n\tMOVQ    R9, 24(SP)\n\tMOVQ    112(CX), R9\n\tMOVQ    128(CX), R10\n\tMOVQ    R10, 32(SP)\n\tMOVQ    144(CX), R10\n\tMOVQ    136(CX), R11\n\tMOVQ    200(CX), R12\n\tMOVQ    R12, 56(SP)\n\tMOVQ    176(CX), R12\n\tMOVQ    R12, 48(SP)\n\tMOVQ    184(CX), CX\n\tMOVQ    CX, 40(SP)\n\tMOVQ    40(SP), CX\n\tADDQ    CX, 48(SP)\n\n\t// Calculate poiter to s.out[cap(s.out)] (a past-end pointer)\n\tADDQ R9, 32(SP)\n\n\t// outBase += outPosition\n\tADDQ R11, R9\n\nsequenceDecs_decodeSync_safe_bmi2_main_loop:\n\tMOVQ (SP), R12\n\n\t// Fill bitreader to have enough for the offset and match length.\n\tCMPQ BX, $0x08\n\tJL   sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte\n\tMOVQ DX, CX\n\tSHRQ $0x03, CX\n\tSUBQ CX, R12\n\tMOVQ (R12), AX\n\tSUBQ CX, BX\n\tANDQ $0x07, DX\n\tJMP  sequenceDecs_decodeSync_safe_bmi2_fill_end\n\nsequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte:\n\tCMPQ    BX, $0x00\n\tJLE     sequenceDecs_decodeSync_safe_bmi2_fill_check_overread\n\tCMPQ    DX, $0x07\n\tJLE     sequenceDecs_decodeSync_safe_bmi2_fill_end\n\tSHLQ    $0x08, AX\n\tSUBQ    $0x01, R12\n\tSUBQ    $0x01, BX\n\tSUBQ    $0x08, DX\n\tMOVBQZX (R12), CX\n\tORQ     CX, AX\n\tJMP     sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte\n\nsequenceDecs_decodeSync_safe_bmi2_fill_check_overread:\n\tCMPQ DX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_safe_bmi2_fill_end:\n\t// Update offset\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, R8, R13\n\tMOVQ   AX, R14\n\tLEAQ   (DX)(R13*1), CX\n\tROLQ   CL, R14\n\tBZHIQ  R13, R14, R14\n\tMOVQ   CX, DX\n\tMOVQ   R8, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R14, CX\n\tMOVQ   CX, 8(SP)\n\n\t// Update match length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, DI, R13\n\tMOVQ   AX, R14\n\tLEAQ   (DX)(R13*1), CX\n\tROLQ   CL, R14\n\tBZHIQ  R13, R14, R14\n\tMOVQ   CX, DX\n\tMOVQ   DI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R14, CX\n\tMOVQ   CX, 16(SP)\n\n\t// Fill bitreader to have enough for the remaining\n\tCMPQ BX, $0x08\n\tJL   sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte\n\tMOVQ DX, CX\n\tSHRQ $0x03, CX\n\tSUBQ CX, R12\n\tMOVQ (R12), AX\n\tSUBQ CX, BX\n\tANDQ $0x07, DX\n\tJMP  sequenceDecs_decodeSync_safe_bmi2_fill_2_end\n\nsequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte:\n\tCMPQ    BX, $0x00\n\tJLE     sequenceDecs_decodeSync_safe_bmi2_fill_2_check_overread\n\tCMPQ    DX, $0x07\n\tJLE     sequenceDecs_decodeSync_safe_bmi2_fill_2_end\n\tSHLQ    $0x08, AX\n\tSUBQ    $0x01, R12\n\tSUBQ    $0x01, BX\n\tSUBQ    $0x08, DX\n\tMOVBQZX (R12), CX\n\tORQ     CX, AX\n\tJMP     sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte\n\nsequenceDecs_decodeSync_safe_bmi2_fill_2_check_overread:\n\tCMPQ DX, $0x40\n\tJA   error_overread\n\nsequenceDecs_decodeSync_safe_bmi2_fill_2_end:\n\t// Update literal length\n\tMOVQ   $0x00000808, CX\n\tBEXTRQ CX, SI, R13\n\tMOVQ   AX, R14\n\tLEAQ   (DX)(R13*1), CX\n\tROLQ   CL, R14\n\tBZHIQ  R13, R14, R14\n\tMOVQ   CX, DX\n\tMOVQ   SI, CX\n\tSHRQ   $0x20, CX\n\tADDQ   R14, CX\n\tMOVQ   CX, 24(SP)\n\n\t// Fill bitreader for state updates\n\tMOVQ    R12, (SP)\n\tMOVQ    $0x00000808, CX\n\tBEXTRQ  CX, R8, R12\n\tMOVQ    ctx+16(FP), CX\n\tCMPQ    96(CX), $0x00\n\tJZ      sequenceDecs_decodeSync_safe_bmi2_skip_update\n\tLEAQ    (SI)(DI*1), R13\n\tADDQ    R8, R13\n\tMOVBQZX R13, R13\n\tLEAQ    (DX)(R13*1), CX\n\tMOVQ    AX, R14\n\tMOVQ    CX, DX\n\tROLQ    CL, R14\n\tBZHIQ   R13, R14, R14\n\n\t// Update Offset State\n\tBZHIQ  R8, R14, CX\n\tSHRXQ  R8, R14, R14\n\tMOVQ   $0x00001010, R13\n\tBEXTRQ R13, R8, R8\n\tADDQ   CX, R8\n\n\t// Load ctx.ofTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 48(CX), CX\n\tMOVQ (CX)(R8*8), R8\n\n\t// Update Match Length State\n\tBZHIQ  DI, R14, CX\n\tSHRXQ  DI, R14, R14\n\tMOVQ   $0x00001010, R13\n\tBEXTRQ R13, DI, DI\n\tADDQ   CX, DI\n\n\t// Load ctx.mlTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ 24(CX), CX\n\tMOVQ (CX)(DI*8), DI\n\n\t// Update Literal Length State\n\tBZHIQ  SI, R14, CX\n\tMOVQ   $0x00001010, R13\n\tBEXTRQ R13, SI, SI\n\tADDQ   CX, SI\n\n\t// Load ctx.llTable\n\tMOVQ ctx+16(FP), CX\n\tMOVQ (CX), CX\n\tMOVQ (CX)(SI*8), SI\n\nsequenceDecs_decodeSync_safe_bmi2_skip_update:\n\t// Adjust offset\n\tMOVQ   s+0(FP), CX\n\tMOVQ   8(SP), R13\n\tCMPQ   R12, $0x01\n\tJBE    sequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0\n\tMOVUPS 144(CX), X0\n\tMOVQ   R13, 144(CX)\n\tMOVUPS X0, 152(CX)\n\tJMP    sequenceDecs_decodeSync_safe_bmi2_after_adjust\n\nsequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0:\n\tCMPQ 24(SP), $0x00000000\n\tJNE  sequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero\n\tINCQ R13\n\tJMP  sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero\n\nsequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero:\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero\n\tMOVQ  144(CX), R13\n\tJMP   sequenceDecs_decodeSync_safe_bmi2_after_adjust\n\nsequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero:\n\tMOVQ    R13, R12\n\tXORQ    R14, R14\n\tMOVQ    $-1, R15\n\tCMPQ    R13, $0x03\n\tCMOVQEQ R14, R12\n\tCMOVQEQ R15, R14\n\tADDQ    144(CX)(R12*8), R14\n\tJNZ     sequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid\n\tMOVQ    $0x00000001, R14\n\nsequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid:\n\tCMPQ R13, $0x01\n\tJZ   sequenceDecs_decodeSync_safe_bmi2_adjust_skip\n\tMOVQ 152(CX), R12\n\tMOVQ R12, 160(CX)\n\nsequenceDecs_decodeSync_safe_bmi2_adjust_skip:\n\tMOVQ 144(CX), R12\n\tMOVQ R12, 152(CX)\n\tMOVQ R14, 144(CX)\n\tMOVQ R14, R13\n\nsequenceDecs_decodeSync_safe_bmi2_after_adjust:\n\tMOVQ R13, 8(SP)\n\n\t// Check values\n\tMOVQ  16(SP), CX\n\tMOVQ  24(SP), R12\n\tLEAQ  (CX)(R12*1), R14\n\tMOVQ  s+0(FP), R15\n\tADDQ  R14, 256(R15)\n\tMOVQ  ctx+16(FP), R14\n\tSUBQ  R12, 104(R14)\n\tJS    error_not_enough_literals\n\tCMPQ  CX, $0x00020002\n\tJA    sequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big\n\tTESTQ R13, R13\n\tJNZ   sequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok\n\tTESTQ CX, CX\n\tJNZ   sequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch\n\nsequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok:\n\tMOVQ 24(SP), CX\n\tMOVQ 8(SP), R12\n\tMOVQ 16(SP), R13\n\n\t// Check if we have enough space in s.out\n\tLEAQ (CX)(R13*1), R14\n\tADDQ R9, R14\n\tCMPQ R14, 32(SP)\n\tJA   error_not_enough_space\n\n\t// Copy literals\n\tTESTQ CX, CX\n\tJZ    check_offset\n\tMOVQ  CX, R14\n\tSUBQ  $0x10, R14\n\tJB    copy_1_small\n\ncopy_1_loop:\n\tMOVUPS (R10), X0\n\tMOVUPS X0, (R9)\n\tADDQ   $0x10, R10\n\tADDQ   $0x10, R9\n\tSUBQ   $0x10, R14\n\tJAE    copy_1_loop\n\tLEAQ   16(R10)(R14*1), R10\n\tLEAQ   16(R9)(R14*1), R9\n\tMOVUPS -16(R10), X0\n\tMOVUPS X0, -16(R9)\n\tJMP    copy_1_end\n\ncopy_1_small:\n\tCMPQ CX, $0x03\n\tJE   copy_1_move_3\n\tJB   copy_1_move_1or2\n\tCMPQ CX, $0x08\n\tJB   copy_1_move_4through7\n\tJMP  copy_1_move_8through16\n\ncopy_1_move_1or2:\n\tMOVB (R10), R14\n\tMOVB -1(R10)(CX*1), R15\n\tMOVB R14, (R9)\n\tMOVB R15, -1(R9)(CX*1)\n\tADDQ CX, R10\n\tADDQ CX, R9\n\tJMP  copy_1_end\n\ncopy_1_move_3:\n\tMOVW (R10), R14\n\tMOVB 2(R10), R15\n\tMOVW R14, (R9)\n\tMOVB R15, 2(R9)\n\tADDQ CX, R10\n\tADDQ CX, R9\n\tJMP  copy_1_end\n\ncopy_1_move_4through7:\n\tMOVL (R10), R14\n\tMOVL -4(R10)(CX*1), R15\n\tMOVL R14, (R9)\n\tMOVL R15, -4(R9)(CX*1)\n\tADDQ CX, R10\n\tADDQ CX, R9\n\tJMP  copy_1_end\n\ncopy_1_move_8through16:\n\tMOVQ (R10), R14\n\tMOVQ -8(R10)(CX*1), R15\n\tMOVQ R14, (R9)\n\tMOVQ R15, -8(R9)(CX*1)\n\tADDQ CX, R10\n\tADDQ CX, R9\n\ncopy_1_end:\n\tADDQ CX, R11\n\n\t// Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize)\ncheck_offset:\n\tMOVQ R11, CX\n\tADDQ 40(SP), CX\n\tCMPQ R12, CX\n\tJG   error_match_off_too_big\n\tCMPQ R12, 56(SP)\n\tJG   error_match_off_too_big\n\n\t// Copy match from history\n\tMOVQ R12, CX\n\tSUBQ R11, CX\n\tJLS  copy_match\n\tMOVQ 48(SP), R14\n\tSUBQ CX, R14\n\tCMPQ R13, CX\n\tJG   copy_all_from_history\n\tMOVQ R13, CX\n\tSUBQ $0x10, CX\n\tJB   copy_4_small\n\ncopy_4_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R9)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R9\n\tSUBQ   $0x10, CX\n\tJAE    copy_4_loop\n\tLEAQ   16(R14)(CX*1), R14\n\tLEAQ   16(R9)(CX*1), R9\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R9)\n\tJMP    copy_4_end\n\ncopy_4_small:\n\tCMPQ R13, $0x03\n\tJE   copy_4_move_3\n\tCMPQ R13, $0x08\n\tJB   copy_4_move_4through7\n\tJMP  copy_4_move_8through16\n\ncopy_4_move_3:\n\tMOVW (R14), CX\n\tMOVB 2(R14), R12\n\tMOVW CX, (R9)\n\tMOVB R12, 2(R9)\n\tADDQ R13, R14\n\tADDQ R13, R9\n\tJMP  copy_4_end\n\ncopy_4_move_4through7:\n\tMOVL (R14), CX\n\tMOVL -4(R14)(R13*1), R12\n\tMOVL CX, (R9)\n\tMOVL R12, -4(R9)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R9\n\tJMP  copy_4_end\n\ncopy_4_move_8through16:\n\tMOVQ (R14), CX\n\tMOVQ -8(R14)(R13*1), R12\n\tMOVQ CX, (R9)\n\tMOVQ R12, -8(R9)(R13*1)\n\tADDQ R13, R14\n\tADDQ R13, R9\n\ncopy_4_end:\n\tADDQ R13, R11\n\tJMP  handle_loop\n\tJMP loop_finished\n\ncopy_all_from_history:\n\tMOVQ CX, R15\n\tSUBQ $0x10, R15\n\tJB   copy_5_small\n\ncopy_5_loop:\n\tMOVUPS (R14), X0\n\tMOVUPS X0, (R9)\n\tADDQ   $0x10, R14\n\tADDQ   $0x10, R9\n\tSUBQ   $0x10, R15\n\tJAE    copy_5_loop\n\tLEAQ   16(R14)(R15*1), R14\n\tLEAQ   16(R9)(R15*1), R9\n\tMOVUPS -16(R14), X0\n\tMOVUPS X0, -16(R9)\n\tJMP    copy_5_end\n\ncopy_5_small:\n\tCMPQ CX, $0x03\n\tJE   copy_5_move_3\n\tJB   copy_5_move_1or2\n\tCMPQ CX, $0x08\n\tJB   copy_5_move_4through7\n\tJMP  copy_5_move_8through16\n\ncopy_5_move_1or2:\n\tMOVB (R14), R15\n\tMOVB -1(R14)(CX*1), BP\n\tMOVB R15, (R9)\n\tMOVB BP, -1(R9)(CX*1)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\tJMP  copy_5_end\n\ncopy_5_move_3:\n\tMOVW (R14), R15\n\tMOVB 2(R14), BP\n\tMOVW R15, (R9)\n\tMOVB BP, 2(R9)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\tJMP  copy_5_end\n\ncopy_5_move_4through7:\n\tMOVL (R14), R15\n\tMOVL -4(R14)(CX*1), BP\n\tMOVL R15, (R9)\n\tMOVL BP, -4(R9)(CX*1)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\tJMP  copy_5_end\n\ncopy_5_move_8through16:\n\tMOVQ (R14), R15\n\tMOVQ -8(R14)(CX*1), BP\n\tMOVQ R15, (R9)\n\tMOVQ BP, -8(R9)(CX*1)\n\tADDQ CX, R14\n\tADDQ CX, R9\n\ncopy_5_end:\n\tADDQ CX, R11\n\tSUBQ CX, R13\n\n\t// Copy match from the current buffer\ncopy_match:\n\tMOVQ R9, CX\n\tSUBQ R12, CX\n\n\t// ml <= mo\n\tCMPQ R13, R12\n\tJA   copy_overlapping_match\n\n\t// Copy non-overlapping match\n\tADDQ R13, R11\n\tMOVQ R13, R12\n\tSUBQ $0x10, R12\n\tJB   copy_2_small\n\ncopy_2_loop:\n\tMOVUPS (CX), X0\n\tMOVUPS X0, (R9)\n\tADDQ   $0x10, CX\n\tADDQ   $0x10, R9\n\tSUBQ   $0x10, R12\n\tJAE    copy_2_loop\n\tLEAQ   16(CX)(R12*1), CX\n\tLEAQ   16(R9)(R12*1), R9\n\tMOVUPS -16(CX), X0\n\tMOVUPS X0, -16(R9)\n\tJMP    copy_2_end\n\ncopy_2_small:\n\tCMPQ R13, $0x03\n\tJE   copy_2_move_3\n\tJB   copy_2_move_1or2\n\tCMPQ R13, $0x08\n\tJB   copy_2_move_4through7\n\tJMP  copy_2_move_8through16\n\ncopy_2_move_1or2:\n\tMOVB (CX), R12\n\tMOVB -1(CX)(R13*1), R14\n\tMOVB R12, (R9)\n\tMOVB R14, -1(R9)(R13*1)\n\tADDQ R13, CX\n\tADDQ R13, R9\n\tJMP  copy_2_end\n\ncopy_2_move_3:\n\tMOVW (CX), R12\n\tMOVB 2(CX), R14\n\tMOVW R12, (R9)\n\tMOVB R14, 2(R9)\n\tADDQ R13, CX\n\tADDQ R13, R9\n\tJMP  copy_2_end\n\ncopy_2_move_4through7:\n\tMOVL (CX), R12\n\tMOVL -4(CX)(R13*1), R14\n\tMOVL R12, (R9)\n\tMOVL R14, -4(R9)(R13*1)\n\tADDQ R13, CX\n\tADDQ R13, R9\n\tJMP  copy_2_end\n\ncopy_2_move_8through16:\n\tMOVQ (CX), R12\n\tMOVQ -8(CX)(R13*1), R14\n\tMOVQ R12, (R9)\n\tMOVQ R14, -8(R9)(R13*1)\n\tADDQ R13, CX\n\tADDQ R13, R9\n\ncopy_2_end:\n\tJMP handle_loop\n\n\t// Copy overlapping match\ncopy_overlapping_match:\n\tADDQ R13, R11\n\ncopy_slow_3:\n\tMOVB (CX), R12\n\tMOVB R12, (R9)\n\tINCQ CX\n\tINCQ R9\n\tDECQ R13\n\tJNZ  copy_slow_3\n\nhandle_loop:\n\tMOVQ ctx+16(FP), CX\n\tDECQ 96(CX)\n\tJNS  sequenceDecs_decodeSync_safe_bmi2_main_loop\n\nloop_finished:\n\tMOVQ br+8(FP), CX\n\tMOVQ AX, 24(CX)\n\tMOVB DL, 32(CX)\n\tMOVQ BX, 8(CX)\n\n\t// Update the context\n\tMOVQ ctx+16(FP), AX\n\tMOVQ R11, 136(AX)\n\tMOVQ 144(AX), CX\n\tSUBQ CX, R10\n\tMOVQ R10, 168(AX)\n\n\t// Return success\n\tMOVQ $0x00000000, ret+24(FP)\n\tRET\n\n\t// Return with match length error\nsequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch:\n\tMOVQ 16(SP), AX\n\tMOVQ ctx+16(FP), CX\n\tMOVQ AX, 216(CX)\n\tMOVQ $0x00000001, ret+24(FP)\n\tRET\n\n\t// Return with match too long error\nsequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ $0x00000002, ret+24(FP)\n\tRET\n\n\t// Return with match offset too long error\nerror_match_off_too_big:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 8(SP), CX\n\tMOVQ CX, 224(AX)\n\tMOVQ R11, 136(AX)\n\tMOVQ $0x00000003, ret+24(FP)\n\tRET\n\n\t// Return with not enough literals error\nerror_not_enough_literals:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ $0x00000004, ret+24(FP)\n\tRET\n\n\t// Return with overread error\nerror_overread:\n\tMOVQ $0x00000006, ret+24(FP)\n\tRET\n\n\t// Return with not enough output space error\nerror_not_enough_space:\n\tMOVQ ctx+16(FP), AX\n\tMOVQ 24(SP), CX\n\tMOVQ CX, 208(AX)\n\tMOVQ 16(SP), CX\n\tMOVQ CX, 216(AX)\n\tMOVQ R11, 136(AX)\n\tMOVQ $0x00000005, ret+24(FP)\n\tRET\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/seqdec_generic.go",
    "content": "//go:build !amd64 || appengine || !gc || noasm\n// +build !amd64 appengine !gc noasm\n\npackage zstd\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// decode sequences from the stream with the provided history but without dictionary.\nfunc (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {\n\treturn false, nil\n}\n\n// decode sequences from the stream without the provided history.\nfunc (s *sequenceDecs) decode(seqs []seqVals) error {\n\tbr := s.br\n\n\t// Grab full sizes tables, to avoid bounds checks.\n\tllTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize]\n\tllState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state\n\ts.seqSize = 0\n\tlitRemain := len(s.literals)\n\n\tmaxBlockSize := maxCompressedBlockSize\n\tif s.windowSize < maxBlockSize {\n\t\tmaxBlockSize = s.windowSize\n\t}\n\tfor i := range seqs {\n\t\tvar ll, mo, ml int\n\t\tif len(br.in) > 4+((maxOffsetBits+16+16)>>3) {\n\t\t\t// inlined function:\n\t\t\t// ll, mo, ml = s.nextFast(br, llState, mlState, ofState)\n\n\t\t\t// Final will not read from stream.\n\t\t\tvar llB, mlB, moB uint8\n\t\t\tll, llB = llState.final()\n\t\t\tml, mlB = mlState.final()\n\t\t\tmo, moB = ofState.final()\n\n\t\t\t// extra bits are stored in reverse order.\n\t\t\tbr.fillFast()\n\t\t\tmo += br.getBits(moB)\n\t\t\tif s.maxBits > 32 {\n\t\t\t\tbr.fillFast()\n\t\t\t}\n\t\t\tml += br.getBits(mlB)\n\t\t\tll += br.getBits(llB)\n\n\t\t\tif moB > 1 {\n\t\t\t\ts.prevOffset[2] = s.prevOffset[1]\n\t\t\t\ts.prevOffset[1] = s.prevOffset[0]\n\t\t\t\ts.prevOffset[0] = mo\n\t\t\t} else {\n\t\t\t\t// mo = s.adjustOffset(mo, ll, moB)\n\t\t\t\t// Inlined for rather big speedup\n\t\t\t\tif ll == 0 {\n\t\t\t\t\t// There is an exception though, when current sequence's literals_length = 0.\n\t\t\t\t\t// In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2,\n\t\t\t\t\t// an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte.\n\t\t\t\t\tmo++\n\t\t\t\t}\n\n\t\t\t\tif mo == 0 {\n\t\t\t\t\tmo = s.prevOffset[0]\n\t\t\t\t} else {\n\t\t\t\t\tvar temp int\n\t\t\t\t\tif mo == 3 {\n\t\t\t\t\t\ttemp = s.prevOffset[0] - 1\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttemp = s.prevOffset[mo]\n\t\t\t\t\t}\n\n\t\t\t\t\tif temp == 0 {\n\t\t\t\t\t\t// 0 is not valid; input is corrupted; force offset to 1\n\t\t\t\t\t\tprintln(\"WARNING: temp was 0\")\n\t\t\t\t\t\ttemp = 1\n\t\t\t\t\t}\n\n\t\t\t\t\tif mo != 1 {\n\t\t\t\t\t\ts.prevOffset[2] = s.prevOffset[1]\n\t\t\t\t\t}\n\t\t\t\t\ts.prevOffset[1] = s.prevOffset[0]\n\t\t\t\t\ts.prevOffset[0] = temp\n\t\t\t\t\tmo = temp\n\t\t\t\t}\n\t\t\t}\n\t\t\tbr.fillFast()\n\t\t} else {\n\t\t\tif br.overread() {\n\t\t\t\tif debugDecoder {\n\t\t\t\t\tprintf(\"reading sequence %d, exceeded available data\\n\", i)\n\t\t\t\t}\n\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t}\n\t\t\tll, mo, ml = s.next(br, llState, mlState, ofState)\n\t\t\tbr.fill()\n\t\t}\n\n\t\tif debugSequences {\n\t\t\tprintln(\"Seq\", i, \"Litlen:\", ll, \"mo:\", mo, \"(abs) ml:\", ml)\n\t\t}\n\t\t// Evaluate.\n\t\t// We might be doing this async, so do it early.\n\t\tif mo == 0 && ml > 0 {\n\t\t\treturn fmt.Errorf(\"zero matchoff and matchlen (%d) > 0\", ml)\n\t\t}\n\t\tif ml > maxMatchLen {\n\t\t\treturn fmt.Errorf(\"match len (%d) bigger than max allowed length\", ml)\n\t\t}\n\t\ts.seqSize += ll + ml\n\t\tif s.seqSize > maxBlockSize {\n\t\t\treturn fmt.Errorf(\"output bigger than max block size (%d)\", maxBlockSize)\n\t\t}\n\t\tlitRemain -= ll\n\t\tif litRemain < 0 {\n\t\t\treturn fmt.Errorf(\"unexpected literal count, want %d bytes, but only %d is available\", ll, litRemain+ll)\n\t\t}\n\t\tseqs[i] = seqVals{\n\t\t\tll: ll,\n\t\t\tml: ml,\n\t\t\tmo: mo,\n\t\t}\n\t\tif i == len(seqs)-1 {\n\t\t\t// This is the last sequence, so we shouldn't update state.\n\t\t\tbreak\n\t\t}\n\n\t\t// Manually inlined, ~ 5-20% faster\n\t\t// Update all 3 states at once. Approx 20% faster.\n\t\tnBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits()\n\t\tif nBits == 0 {\n\t\t\tllState = llTable[llState.newState()&maxTableMask]\n\t\t\tmlState = mlTable[mlState.newState()&maxTableMask]\n\t\t\tofState = ofTable[ofState.newState()&maxTableMask]\n\t\t} else {\n\t\t\tbits := br.get32BitsFast(nBits)\n\t\t\tlowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31))\n\t\t\tllState = llTable[(llState.newState()+lowBits)&maxTableMask]\n\n\t\t\tlowBits = uint16(bits >> (ofState.nbBits() & 31))\n\t\t\tlowBits &= bitMask[mlState.nbBits()&15]\n\t\t\tmlState = mlTable[(mlState.newState()+lowBits)&maxTableMask]\n\n\t\t\tlowBits = uint16(bits) & bitMask[ofState.nbBits()&15]\n\t\t\tofState = ofTable[(ofState.newState()+lowBits)&maxTableMask]\n\t\t}\n\t}\n\ts.seqSize += litRemain\n\tif s.seqSize > maxBlockSize {\n\t\treturn fmt.Errorf(\"output bigger than max block size (%d)\", maxBlockSize)\n\t}\n\terr := br.close()\n\tif err != nil {\n\t\tprintf(\"Closing sequences: %v, %+v\\n\", err, *br)\n\t}\n\treturn err\n}\n\n// executeSimple handles cases when a dictionary is not used.\nfunc (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error {\n\t// Ensure we have enough output size...\n\tif len(s.out)+s.seqSize > cap(s.out) {\n\t\taddBytes := s.seqSize + len(s.out)\n\t\ts.out = append(s.out, make([]byte, addBytes)...)\n\t\ts.out = s.out[:len(s.out)-addBytes]\n\t}\n\n\tif debugDecoder {\n\t\tprintf(\"Execute %d seqs with literals: %d into %d bytes\\n\", len(seqs), len(s.literals), s.seqSize)\n\t}\n\n\tvar t = len(s.out)\n\tout := s.out[:t+s.seqSize]\n\n\tfor _, seq := range seqs {\n\t\t// Add literals\n\t\tcopy(out[t:], s.literals[:seq.ll])\n\t\tt += seq.ll\n\t\ts.literals = s.literals[seq.ll:]\n\n\t\t// Malformed input\n\t\tif seq.mo > t+len(hist) || seq.mo > s.windowSize {\n\t\t\treturn fmt.Errorf(\"match offset (%d) bigger than current history (%d)\", seq.mo, t+len(hist))\n\t\t}\n\n\t\t// Copy from history.\n\t\tif v := seq.mo - t; v > 0 {\n\t\t\t// v is the start position in history from end.\n\t\t\tstart := len(hist) - v\n\t\t\tif seq.ml > v {\n\t\t\t\t// Some goes into the current block.\n\t\t\t\t// Copy remainder of history\n\t\t\t\tcopy(out[t:], hist[start:])\n\t\t\t\tt += v\n\t\t\t\tseq.ml -= v\n\t\t\t} else {\n\t\t\t\tcopy(out[t:], hist[start:start+seq.ml])\n\t\t\t\tt += seq.ml\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// We must be in the current buffer now\n\t\tif seq.ml > 0 {\n\t\t\tstart := t - seq.mo\n\t\t\tif seq.ml <= t-start {\n\t\t\t\t// No overlap\n\t\t\t\tcopy(out[t:], out[start:start+seq.ml])\n\t\t\t\tt += seq.ml\n\t\t\t} else {\n\t\t\t\t// Overlapping copy\n\t\t\t\t// Extend destination slice and copy one byte at the time.\n\t\t\t\tsrc := out[start : start+seq.ml]\n\t\t\t\tdst := out[t:]\n\t\t\t\tdst = dst[:len(src)]\n\t\t\t\tt += len(src)\n\t\t\t\t// Destination is the space we just added.\n\t\t\t\tfor i := range src {\n\t\t\t\t\tdst[i] = src[i]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Add final literals\n\tcopy(out[t:], s.literals)\n\tif debugDecoder {\n\t\tt += len(s.literals)\n\t\tif t != len(out) {\n\t\t\tpanic(fmt.Errorf(\"length mismatch, want %d, got %d, ss: %d\", len(out), t, s.seqSize))\n\t\t}\n\t}\n\ts.out = out\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/seqenc.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport \"math/bits\"\n\ntype seqCoders struct {\n\tllEnc, ofEnc, mlEnc    *fseEncoder\n\tllPrev, ofPrev, mlPrev *fseEncoder\n}\n\n// swap coders with another (block).\nfunc (s *seqCoders) swap(other *seqCoders) {\n\t*s, *other = *other, *s\n}\n\n// setPrev will update the previous encoders to the actually used ones\n// and make sure a fresh one is in the main slot.\nfunc (s *seqCoders) setPrev(ll, ml, of *fseEncoder) {\n\tcompareSwap := func(used *fseEncoder, current, prev **fseEncoder) {\n\t\t// We used the new one, more current to history and reuse the previous history\n\t\tif *current == used {\n\t\t\t*prev, *current = *current, *prev\n\t\t\tc := *current\n\t\t\tp := *prev\n\t\t\tc.reUsed = false\n\t\t\tp.reUsed = true\n\t\t\treturn\n\t\t}\n\t\tif used == *prev {\n\t\t\treturn\n\t\t}\n\t\t// Ensure we cannot reuse by accident\n\t\tprevEnc := *prev\n\t\tprevEnc.symbolLen = 0\n\t}\n\tcompareSwap(ll, &s.llEnc, &s.llPrev)\n\tcompareSwap(ml, &s.mlEnc, &s.mlPrev)\n\tcompareSwap(of, &s.ofEnc, &s.ofPrev)\n}\n\nfunc highBit(val uint32) (n uint32) {\n\treturn uint32(bits.Len32(val) - 1)\n}\n\nvar llCodeTable = [64]byte{0, 1, 2, 3, 4, 5, 6, 7,\n\t8, 9, 10, 11, 12, 13, 14, 15,\n\t16, 16, 17, 17, 18, 18, 19, 19,\n\t20, 20, 20, 20, 21, 21, 21, 21,\n\t22, 22, 22, 22, 22, 22, 22, 22,\n\t23, 23, 23, 23, 23, 23, 23, 23,\n\t24, 24, 24, 24, 24, 24, 24, 24,\n\t24, 24, 24, 24, 24, 24, 24, 24}\n\n// Up to 6 bits\nconst maxLLCode = 35\n\n// llBitsTable translates from ll code to number of bits.\nvar llBitsTable = [maxLLCode + 1]byte{\n\t0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0,\n\t1, 1, 1, 1, 2, 2, 3, 3,\n\t4, 6, 7, 8, 9, 10, 11, 12,\n\t13, 14, 15, 16}\n\n// llCode returns the code that represents the literal length requested.\nfunc llCode(litLength uint32) uint8 {\n\tconst llDeltaCode = 19\n\tif litLength <= 63 {\n\t\t// Compiler insists on bounds check (Go 1.12)\n\t\treturn llCodeTable[litLength&63]\n\t}\n\treturn uint8(highBit(litLength)) + llDeltaCode\n}\n\nvar mlCodeTable = [128]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\n\t16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,\n\t32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,\n\t38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,\n\t40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,\n\t41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,\n\t42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,\n\t42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42}\n\n// Up to 6 bits\nconst maxMLCode = 52\n\n// mlBitsTable translates from ml code to number of bits.\nvar mlBitsTable = [maxMLCode + 1]byte{\n\t0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0,\n\t0, 0, 0, 0, 0, 0, 0, 0,\n\t1, 1, 1, 1, 2, 2, 3, 3,\n\t4, 4, 5, 7, 8, 9, 10, 11,\n\t12, 13, 14, 15, 16}\n\n// note : mlBase = matchLength - MINMATCH;\n// because it's the format it's stored in seqStore->sequences\nfunc mlCode(mlBase uint32) uint8 {\n\tconst mlDeltaCode = 36\n\tif mlBase <= 127 {\n\t\t// Compiler insists on bounds check (Go 1.12)\n\t\treturn mlCodeTable[mlBase&127]\n\t}\n\treturn uint8(highBit(mlBase)) + mlDeltaCode\n}\n\nfunc ofCode(offset uint32) uint8 {\n\t// A valid offset will always be > 0.\n\treturn uint8(bits.Len32(offset) - 1)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/snappy.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n// Based on work by Yann Collet, released under BSD License.\n\npackage zstd\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"hash/crc32\"\n\t\"io\"\n\n\t\"github.com/klauspost/compress/huff0\"\n\tsnappy \"github.com/klauspost/compress/internal/snapref\"\n)\n\nconst (\n\tsnappyTagLiteral = 0x00\n\tsnappyTagCopy1   = 0x01\n\tsnappyTagCopy2   = 0x02\n\tsnappyTagCopy4   = 0x03\n)\n\nconst (\n\tsnappyChecksumSize = 4\n\tsnappyMagicBody    = \"sNaPpY\"\n\n\t// snappyMaxBlockSize is the maximum size of the input to encodeBlock. It is not\n\t// part of the wire format per se, but some parts of the encoder assume\n\t// that an offset fits into a uint16.\n\t//\n\t// Also, for the framing format (Writer type instead of Encode function),\n\t// https://github.com/google/snappy/blob/master/framing_format.txt says\n\t// that \"the uncompressed data in a chunk must be no longer than 65536\n\t// bytes\".\n\tsnappyMaxBlockSize = 65536\n\n\t// snappyMaxEncodedLenOfMaxBlockSize equals MaxEncodedLen(snappyMaxBlockSize), but is\n\t// hard coded to be a const instead of a variable, so that obufLen can also\n\t// be a const. Their equivalence is confirmed by\n\t// TestMaxEncodedLenOfMaxBlockSize.\n\tsnappyMaxEncodedLenOfMaxBlockSize = 76490\n)\n\nconst (\n\tchunkTypeCompressedData   = 0x00\n\tchunkTypeUncompressedData = 0x01\n\tchunkTypePadding          = 0xfe\n\tchunkTypeStreamIdentifier = 0xff\n)\n\nvar (\n\t// ErrSnappyCorrupt reports that the input is invalid.\n\tErrSnappyCorrupt = errors.New(\"snappy: corrupt input\")\n\t// ErrSnappyTooLarge reports that the uncompressed length is too large.\n\tErrSnappyTooLarge = errors.New(\"snappy: decoded block is too large\")\n\t// ErrSnappyUnsupported reports that the input isn't supported.\n\tErrSnappyUnsupported = errors.New(\"snappy: unsupported input\")\n\n\terrUnsupportedLiteralLength = errors.New(\"snappy: unsupported literal length\")\n)\n\n// SnappyConverter can read SnappyConverter-compressed streams and convert them to zstd.\n// Conversion is done by converting the stream directly from Snappy without intermediate\n// full decoding.\n// Therefore the compression ratio is much less than what can be done by a full decompression\n// and compression, and a faulty Snappy stream may lead to a faulty Zstandard stream without\n// any errors being generated.\n// No CRC value is being generated and not all CRC values of the Snappy stream are checked.\n// However, it provides really fast recompression of Snappy streams.\n// The converter can be reused to avoid allocations, even after errors.\ntype SnappyConverter struct {\n\tr     io.Reader\n\terr   error\n\tbuf   []byte\n\tblock *blockEnc\n}\n\n// Convert the Snappy stream supplied in 'in' and write the zStandard stream to 'w'.\n// If any error is detected on the Snappy stream it is returned.\n// The number of bytes written is returned.\nfunc (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) {\n\tinitPredefined()\n\tr.err = nil\n\tr.r = in\n\tif r.block == nil {\n\t\tr.block = &blockEnc{}\n\t\tr.block.init()\n\t}\n\tr.block.initNewEncode()\n\tif len(r.buf) != snappyMaxEncodedLenOfMaxBlockSize+snappyChecksumSize {\n\t\tr.buf = make([]byte, snappyMaxEncodedLenOfMaxBlockSize+snappyChecksumSize)\n\t}\n\tr.block.litEnc.Reuse = huff0.ReusePolicyNone\n\tvar written int64\n\tvar readHeader bool\n\t{\n\t\theader := frameHeader{WindowSize: snappyMaxBlockSize}.appendTo(r.buf[:0])\n\n\t\tvar n int\n\t\tn, r.err = w.Write(header)\n\t\tif r.err != nil {\n\t\t\treturn written, r.err\n\t\t}\n\t\twritten += int64(n)\n\t}\n\n\tfor {\n\t\tif !r.readFull(r.buf[:4], true) {\n\t\t\t// Add empty last block\n\t\t\tr.block.reset(nil)\n\t\t\tr.block.last = true\n\t\t\terr := r.block.encodeLits(r.block.literals, false)\n\t\t\tif err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t\tn, err := w.Write(r.block.output)\n\t\t\tif err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t\twritten += int64(n)\n\n\t\t\treturn written, r.err\n\t\t}\n\t\tchunkType := r.buf[0]\n\t\tif !readHeader {\n\t\t\tif chunkType != chunkTypeStreamIdentifier {\n\t\t\t\tprintln(\"chunkType != chunkTypeStreamIdentifier\", chunkType)\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\treadHeader = true\n\t\t}\n\t\tchunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16\n\t\tif chunkLen > len(r.buf) {\n\t\t\tprintln(\"chunkLen > len(r.buf)\", chunkType)\n\t\t\tr.err = ErrSnappyUnsupported\n\t\t\treturn written, r.err\n\t\t}\n\n\t\t// The chunk types are specified at\n\t\t// https://github.com/google/snappy/blob/master/framing_format.txt\n\t\tswitch chunkType {\n\t\tcase chunkTypeCompressedData:\n\t\t\t// Section 4.2. Compressed data (chunk type 0x00).\n\t\t\tif chunkLen < snappyChecksumSize {\n\t\t\t\tprintln(\"chunkLen < snappyChecksumSize\", chunkLen, snappyChecksumSize)\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tbuf := r.buf[:chunkLen]\n\t\t\tif !r.readFull(buf, false) {\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\t//checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24\n\t\t\tbuf = buf[snappyChecksumSize:]\n\n\t\t\tn, hdr, err := snappyDecodedLen(buf)\n\t\t\tif err != nil {\n\t\t\t\tr.err = err\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tbuf = buf[hdr:]\n\t\t\tif n > snappyMaxBlockSize {\n\t\t\t\tprintln(\"n > snappyMaxBlockSize\", n, snappyMaxBlockSize)\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tr.block.reset(nil)\n\t\t\tr.block.pushOffsets()\n\t\t\tif err := decodeSnappy(r.block, buf); err != nil {\n\t\t\t\tr.err = err\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tif r.block.size+r.block.extraLits != n {\n\t\t\t\tprintf(\"invalid size, want %d, got %d\\n\", n, r.block.size+r.block.extraLits)\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\terr = r.block.encode(nil, false, false)\n\t\t\tswitch err {\n\t\t\tcase errIncompressible:\n\t\t\t\tr.block.popOffsets()\n\t\t\t\tr.block.reset(nil)\n\t\t\t\tr.block.literals, err = snappy.Decode(r.block.literals[:n], r.buf[snappyChecksumSize:chunkLen])\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn written, err\n\t\t\t\t}\n\t\t\t\terr = r.block.encodeLits(r.block.literals, false)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn written, err\n\t\t\t\t}\n\t\t\tcase nil:\n\t\t\tdefault:\n\t\t\t\treturn written, err\n\t\t\t}\n\n\t\t\tn, r.err = w.Write(r.block.output)\n\t\t\tif r.err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t\twritten += int64(n)\n\t\t\tcontinue\n\t\tcase chunkTypeUncompressedData:\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"Uncompressed, chunklen\", chunkLen)\n\t\t\t}\n\t\t\t// Section 4.3. Uncompressed data (chunk type 0x01).\n\t\t\tif chunkLen < snappyChecksumSize {\n\t\t\t\tprintln(\"chunkLen < snappyChecksumSize\", chunkLen, snappyChecksumSize)\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tr.block.reset(nil)\n\t\t\tbuf := r.buf[:snappyChecksumSize]\n\t\t\tif !r.readFull(buf, false) {\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tchecksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24\n\t\t\t// Read directly into r.decoded instead of via r.buf.\n\t\t\tn := chunkLen - snappyChecksumSize\n\t\t\tif n > snappyMaxBlockSize {\n\t\t\t\tprintln(\"n > snappyMaxBlockSize\", n, snappyMaxBlockSize)\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tr.block.literals = r.block.literals[:n]\n\t\t\tif !r.readFull(r.block.literals, false) {\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tif snappyCRC(r.block.literals) != checksum {\n\t\t\t\tprintln(\"literals crc mismatch\")\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\terr := r.block.encodeLits(r.block.literals, false)\n\t\t\tif err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t\tn, r.err = w.Write(r.block.output)\n\t\t\tif r.err != nil {\n\t\t\t\treturn written, err\n\t\t\t}\n\t\t\twritten += int64(n)\n\t\t\tcontinue\n\n\t\tcase chunkTypeStreamIdentifier:\n\t\t\tif debugEncoder {\n\t\t\t\tprintln(\"stream id\", chunkLen, len(snappyMagicBody))\n\t\t\t}\n\t\t\t// Section 4.1. Stream identifier (chunk type 0xff).\n\t\t\tif chunkLen != len(snappyMagicBody) {\n\t\t\t\tprintln(\"chunkLen != len(snappyMagicBody)\", chunkLen, len(snappyMagicBody))\n\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tif !r.readFull(r.buf[:len(snappyMagicBody)], false) {\n\t\t\t\treturn written, r.err\n\t\t\t}\n\t\t\tfor i := 0; i < len(snappyMagicBody); i++ {\n\t\t\t\tif r.buf[i] != snappyMagicBody[i] {\n\t\t\t\t\tprintln(\"r.buf[i] != snappyMagicBody[i]\", r.buf[i], snappyMagicBody[i], i)\n\t\t\t\t\tr.err = ErrSnappyCorrupt\n\t\t\t\t\treturn written, r.err\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif chunkType <= 0x7f {\n\t\t\t// Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f).\n\t\t\tprintln(\"chunkType <= 0x7f\")\n\t\t\tr.err = ErrSnappyUnsupported\n\t\t\treturn written, r.err\n\t\t}\n\t\t// Section 4.4 Padding (chunk type 0xfe).\n\t\t// Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd).\n\t\tif !r.readFull(r.buf[:chunkLen], false) {\n\t\t\treturn written, r.err\n\t\t}\n\t}\n}\n\n// decodeSnappy writes the decoding of src to dst. It assumes that the varint-encoded\n// length of the decompressed bytes has already been read.\nfunc decodeSnappy(blk *blockEnc, src []byte) error {\n\t//decodeRef(make([]byte, snappyMaxBlockSize), src)\n\tvar s, length int\n\tlits := blk.extraLits\n\tvar offset uint32\n\tfor s < len(src) {\n\t\tswitch src[s] & 0x03 {\n\t\tcase snappyTagLiteral:\n\t\t\tx := uint32(src[s] >> 2)\n\t\t\tswitch {\n\t\t\tcase x < 60:\n\t\t\t\ts++\n\t\t\tcase x == 60:\n\t\t\t\ts += 2\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\tprintln(\"uint(s) > uint(len(src)\", s, src)\n\t\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-1])\n\t\t\tcase x == 61:\n\t\t\t\ts += 3\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\tprintln(\"uint(s) > uint(len(src)\", s, src)\n\t\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-2]) | uint32(src[s-1])<<8\n\t\t\tcase x == 62:\n\t\t\t\ts += 4\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\tprintln(\"uint(s) > uint(len(src)\", s, src)\n\t\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16\n\t\t\tcase x == 63:\n\t\t\t\ts += 5\n\t\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\t\tprintln(\"uint(s) > uint(len(src)\", s, src)\n\t\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t\t}\n\t\t\t\tx = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24\n\t\t\t}\n\t\t\tif x > snappyMaxBlockSize {\n\t\t\t\tprintln(\"x > snappyMaxBlockSize\", x, snappyMaxBlockSize)\n\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t}\n\t\t\tlength = int(x) + 1\n\t\t\tif length <= 0 {\n\t\t\t\tprintln(\"length <= 0 \", length)\n\n\t\t\t\treturn errUnsupportedLiteralLength\n\t\t\t}\n\t\t\t//if length > snappyMaxBlockSize-d || uint32(length) > len(src)-s {\n\t\t\t//\treturn ErrSnappyCorrupt\n\t\t\t//}\n\n\t\t\tblk.literals = append(blk.literals, src[s:s+length]...)\n\t\t\t//println(length, \"litLen\")\n\t\t\tlits += length\n\t\t\ts += length\n\t\t\tcontinue\n\n\t\tcase snappyTagCopy1:\n\t\t\ts += 2\n\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\tprintln(\"uint(s) > uint(len(src)\", s, len(src))\n\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t}\n\t\t\tlength = 4 + int(src[s-2])>>2&0x7\n\t\t\toffset = uint32(src[s-2])&0xe0<<3 | uint32(src[s-1])\n\n\t\tcase snappyTagCopy2:\n\t\t\ts += 3\n\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\tprintln(\"uint(s) > uint(len(src)\", s, len(src))\n\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t}\n\t\t\tlength = 1 + int(src[s-3])>>2\n\t\t\toffset = uint32(src[s-2]) | uint32(src[s-1])<<8\n\n\t\tcase snappyTagCopy4:\n\t\t\ts += 5\n\t\t\tif uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.\n\t\t\t\tprintln(\"uint(s) > uint(len(src)\", s, len(src))\n\t\t\t\treturn ErrSnappyCorrupt\n\t\t\t}\n\t\t\tlength = 1 + int(src[s-5])>>2\n\t\t\toffset = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24\n\t\t}\n\n\t\tif offset <= 0 || blk.size+lits < int(offset) /*|| length > len(blk)-d */ {\n\t\t\tprintln(\"offset <= 0 || blk.size+lits < int(offset)\", offset, blk.size+lits, int(offset), blk.size, lits)\n\n\t\t\treturn ErrSnappyCorrupt\n\t\t}\n\n\t\t// Check if offset is one of the recent offsets.\n\t\t// Adjusts the output offset accordingly.\n\t\t// Gives a tiny bit of compression, typically around 1%.\n\t\tif false {\n\t\t\toffset = blk.matchOffset(offset, uint32(lits))\n\t\t} else {\n\t\t\toffset += 3\n\t\t}\n\n\t\tblk.sequences = append(blk.sequences, seq{\n\t\t\tlitLen:   uint32(lits),\n\t\t\toffset:   offset,\n\t\t\tmatchLen: uint32(length) - zstdMinMatch,\n\t\t})\n\t\tblk.size += length + lits\n\t\tlits = 0\n\t}\n\tblk.extraLits = lits\n\treturn nil\n}\n\nfunc (r *SnappyConverter) readFull(p []byte, allowEOF bool) (ok bool) {\n\tif _, r.err = io.ReadFull(r.r, p); r.err != nil {\n\t\tif r.err == io.ErrUnexpectedEOF || (r.err == io.EOF && !allowEOF) {\n\t\t\tr.err = ErrSnappyCorrupt\n\t\t}\n\t\treturn false\n\t}\n\treturn true\n}\n\nvar crcTable = crc32.MakeTable(crc32.Castagnoli)\n\n// crc implements the checksum specified in section 3 of\n// https://github.com/google/snappy/blob/master/framing_format.txt\nfunc snappyCRC(b []byte) uint32 {\n\tc := crc32.Update(0, crcTable, b)\n\treturn c>>15 | c<<17 + 0xa282ead8\n}\n\n// snappyDecodedLen returns the length of the decoded block and the number of bytes\n// that the length header occupied.\nfunc snappyDecodedLen(src []byte) (blockLen, headerLen int, err error) {\n\tv, n := binary.Uvarint(src)\n\tif n <= 0 || v > 0xffffffff {\n\t\treturn 0, 0, ErrSnappyCorrupt\n\t}\n\n\tconst wordSize = 32 << (^uint(0) >> 32 & 1)\n\tif wordSize == 32 && v > 0x7fffffff {\n\t\treturn 0, 0, ErrSnappyTooLarge\n\t}\n\treturn int(v), n, nil\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/zip.go",
    "content": "// Copyright 2019+ Klaus Post. All rights reserved.\n// License information can be found in the LICENSE file.\n\npackage zstd\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n)\n\n// ZipMethodWinZip is the method for Zstandard compressed data inside Zip files for WinZip.\n// See https://www.winzip.com/win/en/comp_info.html\nconst ZipMethodWinZip = 93\n\n// ZipMethodPKWare is the original method number used by PKWARE to indicate Zstandard compression.\n// Deprecated: This has been deprecated by PKWARE, use ZipMethodWinZip instead for compression.\n// See https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.9.TXT\nconst ZipMethodPKWare = 20\n\n// zipReaderPool is the default reader pool.\nvar zipReaderPool = sync.Pool{New: func() interface{} {\n\tz, err := NewReader(nil, WithDecoderLowmem(true), WithDecoderMaxWindow(128<<20), WithDecoderConcurrency(1))\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn z\n}}\n\n// newZipReader creates a pooled zip decompressor.\nfunc newZipReader(opts ...DOption) func(r io.Reader) io.ReadCloser {\n\tpool := &zipReaderPool\n\tif len(opts) > 0 {\n\t\topts = append([]DOption{WithDecoderLowmem(true), WithDecoderMaxWindow(128 << 20)}, opts...)\n\t\t// Force concurrency 1\n\t\topts = append(opts, WithDecoderConcurrency(1))\n\t\t// Create our own pool\n\t\tpool = &sync.Pool{}\n\t}\n\treturn func(r io.Reader) io.ReadCloser {\n\t\tdec, ok := pool.Get().(*Decoder)\n\t\tif ok {\n\t\t\tdec.Reset(r)\n\t\t} else {\n\t\t\td, err := NewReader(r, opts...)\n\t\t\tif err != nil {\n\t\t\t\tpanic(err)\n\t\t\t}\n\t\t\tdec = d\n\t\t}\n\t\treturn &pooledZipReader{dec: dec, pool: pool}\n\t}\n}\n\ntype pooledZipReader struct {\n\tmu   sync.Mutex // guards Close and Read\n\tpool *sync.Pool\n\tdec  *Decoder\n}\n\nfunc (r *pooledZipReader) Read(p []byte) (n int, err error) {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tif r.dec == nil {\n\t\treturn 0, errors.New(\"read after close or EOF\")\n\t}\n\tdec, err := r.dec.Read(p)\n\tif err == io.EOF {\n\t\tr.dec.Reset(nil)\n\t\tr.pool.Put(r.dec)\n\t\tr.dec = nil\n\t}\n\treturn dec, err\n}\n\nfunc (r *pooledZipReader) Close() error {\n\tr.mu.Lock()\n\tdefer r.mu.Unlock()\n\tvar err error\n\tif r.dec != nil {\n\t\terr = r.dec.Reset(nil)\n\t\tr.pool.Put(r.dec)\n\t\tr.dec = nil\n\t}\n\treturn err\n}\n\ntype pooledZipWriter struct {\n\tmu   sync.Mutex // guards Close and Read\n\tenc  *Encoder\n\tpool *sync.Pool\n}\n\nfunc (w *pooledZipWriter) Write(p []byte) (n int, err error) {\n\tw.mu.Lock()\n\tdefer w.mu.Unlock()\n\tif w.enc == nil {\n\t\treturn 0, errors.New(\"Write after Close\")\n\t}\n\treturn w.enc.Write(p)\n}\n\nfunc (w *pooledZipWriter) Close() error {\n\tw.mu.Lock()\n\tdefer w.mu.Unlock()\n\tvar err error\n\tif w.enc != nil {\n\t\terr = w.enc.Close()\n\t\tw.pool.Put(w.enc)\n\t\tw.enc = nil\n\t}\n\treturn err\n}\n\n// ZipCompressor returns a compressor that can be registered with zip libraries.\n// The provided encoder options will be used on all encodes.\nfunc ZipCompressor(opts ...EOption) func(w io.Writer) (io.WriteCloser, error) {\n\tvar pool sync.Pool\n\treturn func(w io.Writer) (io.WriteCloser, error) {\n\t\tenc, ok := pool.Get().(*Encoder)\n\t\tif ok {\n\t\t\tenc.Reset(w)\n\t\t} else {\n\t\t\tvar err error\n\t\t\tenc, err = NewWriter(w, opts...)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn &pooledZipWriter{enc: enc, pool: &pool}, nil\n\t}\n}\n\n// ZipDecompressor returns a decompressor that can be registered with zip libraries.\n// See ZipCompressor for example.\n// Options can be specified. WithDecoderConcurrency(1) is forced,\n// and by default a 128MB maximum decompression window is specified.\n// The window size can be overridden if required.\nfunc ZipDecompressor(opts ...DOption) func(r io.Reader) io.ReadCloser {\n\treturn newZipReader(opts...)\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/compress/zstd/zstd.go",
    "content": "// Package zstd provides decompression of zstandard files.\n//\n// For advanced usage and examples, go to the README: https://github.com/klauspost/compress/tree/master/zstd#zstd\npackage zstd\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"log\"\n\t\"math\"\n)\n\n// enable debug printing\nconst debug = false\n\n// enable encoding debug printing\nconst debugEncoder = debug\n\n// enable decoding debug printing\nconst debugDecoder = debug\n\n// Enable extra assertions.\nconst debugAsserts = debug || false\n\n// print sequence details\nconst debugSequences = false\n\n// print detailed matching information\nconst debugMatches = false\n\n// force encoder to use predefined tables.\nconst forcePreDef = false\n\n// zstdMinMatch is the minimum zstd match length.\nconst zstdMinMatch = 3\n\n// fcsUnknown is used for unknown frame content size.\nconst fcsUnknown = math.MaxUint64\n\nvar (\n\t// ErrReservedBlockType is returned when a reserved block type is found.\n\t// Typically this indicates wrong or corrupted input.\n\tErrReservedBlockType = errors.New(\"invalid input: reserved block type encountered\")\n\n\t// ErrCompressedSizeTooBig is returned when a block is bigger than allowed.\n\t// Typically this indicates wrong or corrupted input.\n\tErrCompressedSizeTooBig = errors.New(\"invalid input: compressed size too big\")\n\n\t// ErrBlockTooSmall is returned when a block is too small to be decoded.\n\t// Typically returned on invalid input.\n\tErrBlockTooSmall = errors.New(\"block too small\")\n\n\t// ErrUnexpectedBlockSize is returned when a block has unexpected size.\n\t// Typically returned on invalid input.\n\tErrUnexpectedBlockSize = errors.New(\"unexpected block size\")\n\n\t// ErrMagicMismatch is returned when a \"magic\" number isn't what is expected.\n\t// Typically this indicates wrong or corrupted input.\n\tErrMagicMismatch = errors.New(\"invalid input: magic number mismatch\")\n\n\t// ErrWindowSizeExceeded is returned when a reference exceeds the valid window size.\n\t// Typically this indicates wrong or corrupted input.\n\tErrWindowSizeExceeded = errors.New(\"window size exceeded\")\n\n\t// ErrWindowSizeTooSmall is returned when no window size is specified.\n\t// Typically this indicates wrong or corrupted input.\n\tErrWindowSizeTooSmall = errors.New(\"invalid input: window size was too small\")\n\n\t// ErrDecoderSizeExceeded is returned if decompressed size exceeds the configured limit.\n\tErrDecoderSizeExceeded = errors.New(\"decompressed size exceeds configured limit\")\n\n\t// ErrUnknownDictionary is returned if the dictionary ID is unknown.\n\tErrUnknownDictionary = errors.New(\"unknown dictionary\")\n\n\t// ErrFrameSizeExceeded is returned if the stated frame size is exceeded.\n\t// This is only returned if SingleSegment is specified on the frame.\n\tErrFrameSizeExceeded = errors.New(\"frame size exceeded\")\n\n\t// ErrFrameSizeMismatch is returned if the stated frame size does not match the expected size.\n\t// This is only returned if SingleSegment is specified on the frame.\n\tErrFrameSizeMismatch = errors.New(\"frame size does not match size on stream\")\n\n\t// ErrCRCMismatch is returned if CRC mismatches.\n\tErrCRCMismatch = errors.New(\"CRC check failed\")\n\n\t// ErrDecoderClosed will be returned if the Decoder was used after\n\t// Close has been called.\n\tErrDecoderClosed = errors.New(\"decoder used after Close\")\n\n\t// ErrDecoderNilInput is returned when a nil Reader was provided\n\t// and an operation other than Reset/DecodeAll/Close was attempted.\n\tErrDecoderNilInput = errors.New(\"nil input provided as reader\")\n)\n\nfunc println(a ...interface{}) {\n\tif debug || debugDecoder || debugEncoder {\n\t\tlog.Println(a...)\n\t}\n}\n\nfunc printf(format string, a ...interface{}) {\n\tif debug || debugDecoder || debugEncoder {\n\t\tlog.Printf(format, a...)\n\t}\n}\n\nfunc load3232(b []byte, i int32) uint32 {\n\treturn binary.LittleEndian.Uint32(b[:len(b):len(b)][i:])\n}\n\nfunc load6432(b []byte, i int32) uint64 {\n\treturn binary.LittleEndian.Uint64(b[:len(b):len(b)][i:])\n}\n\ntype byter interface {\n\tBytes() []byte\n\tLen() int\n}\n\nvar _ byter = &bytes.Buffer{}\n"
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n"
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/.travis.yml",
    "content": "language: go\n\nsudo: false\n\nos:\n  - linux\n  - osx\n\ngo:\n  - 1.9.x\n  - 1.10.x\n  - master\n\nscript: \n - go test -v -cpu=1,2,4 .\n - go test -v -cpu=2 -race -short .\n\nmatrix:\n  allow_failures:\n    - go: 'master'\n  fast_finish: true \n"
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/GO_LICENSE",
    "content": "Copyright (c) 2012 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/klauspost/pgzip/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2014 Klaus Post\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": "vendor/github.com/klauspost/pgzip/README.md",
    "content": "pgzip\n=====\n\nGo parallel gzip compression/decompression. This is a fully gzip compatible drop in replacement for \"compress/gzip\".\n\nThis will split compression into blocks that are compressed in parallel. \nThis can be useful for compressing big amounts of data. The output is a standard gzip file.\n\nThe gzip decompression is modified so it decompresses ahead of the current reader. \nThis means that reads will be non-blocking if the decompressor can keep ahead of your code reading from it. \nCRC calculation also takes place in a separate goroutine.\n\nYou should only use this if you are (de)compressing big amounts of data, \nsay **more than 1MB** at the time, otherwise you will not see any benefit, \nand it will likely be faster to use the internal gzip library \nor [this package](https://github.com/klauspost/compress).\n\nIt is important to note that this library creates and reads *standard gzip files*. \nYou do not have to match the compressor/decompressor to get the described speedups, \nand the gzip files are fully compatible with other gzip readers/writers.\n\nA golang variant of this is [bgzf](https://godoc.org/github.com/biogo/hts/bgzf), \nwhich has the same feature, as well as seeking in the resulting file. \nThe only drawback is a slightly bigger overhead compared to this and pure gzip. \nSee a comparison below.\n\n[![GoDoc][1]][2] [![Build Status][3]][4]\n\n[1]: https://godoc.org/github.com/klauspost/pgzip?status.svg\n[2]: https://godoc.org/github.com/klauspost/pgzip\n[3]: https://travis-ci.org/klauspost/pgzip.svg\n[4]: https://travis-ci.org/klauspost/pgzip\n\nInstallation\n====\n```go get github.com/klauspost/pgzip/...```\n\nYou might need to get/update the dependencies:\n\n```\ngo get -u github.com/klauspost/compress\n```\n\nUsage\n====\n[Godoc Doumentation](https://godoc.org/github.com/klauspost/pgzip)\n\nTo use as a replacement for gzip, exchange \n\n```import \"compress/gzip\"``` \nwith \n```import gzip \"github.com/klauspost/pgzip\"```.\n\n# Changes\n\n* Oct 6, 2016: Fixed an issue if the destination writer returned an error.\n* Oct 6, 2016: Better buffer reuse, should now generate less garbage.\n* Oct 6, 2016: Output does not change based on write sizes.\n* Dec 8, 2015: Decoder now supports the io.WriterTo interface, giving a speedup and less GC pressure.\n* Oct 9, 2015: Reduced allocations by ~35 by using sync.Pool. ~15% overall speedup.\n\nChanges in [github.com/klauspost/compress](https://github.com/klauspost/compress#changelog) are also carried over, so see that for more changes.\n\n## Compression\nThe simplest way to use this is to simply do the same as you would when using [compress/gzip](http://golang.org/pkg/compress/gzip). \n\nTo change the block size, use the added (*pgzip.Writer).SetConcurrency(blockSize, blocks int) function. With this you can control the approximate size of your blocks, as well as how many you want to be processing in parallel. Default values for this is SetConcurrency(1MB, runtime.GOMAXPROCS(0)), meaning blocks are split at 1 MB and up to the number of CPU threads blocks can be processing at once before the writer blocks.\n\n\nExample:\n```\nvar b bytes.Buffer\nw := gzip.NewWriter(&b)\nw.SetConcurrency(100000, 10)\nw.Write([]byte(\"hello, world\\n\"))\nw.Close()\n```\n\nTo get any performance gains, you should at least be compressing more than 1 megabyte of data at the time.\n\nYou should at least have a block size of 100k and at least a number of blocks that match the number of cores your would like to utilize, but about twice the number of blocks would be the best.\n\nAnother side effect of this is, that it is likely to speed up your other code, since writes to the compressor only blocks if the compressor is already compressing the number of blocks you have specified. This also means you don't have worry about buffering input to the compressor.\n\n## Decompression\n\nDecompression works similar to compression. That means that you simply call pgzip the same way as you would call [compress/gzip](http://golang.org/pkg/compress/gzip). \n\nThe only difference is that if you want to specify your own readahead, you have to use `pgzip.NewReaderN(r io.Reader, blockSize, blocks int)` to get a reader with your custom blocksizes. The `blockSize` is the size of each block decoded, and `blocks` is the maximum number of blocks that is decoded ahead.\n\nSee [Example on playground](http://play.golang.org/p/uHv1B5NbDh)\n\nPerformance\n====\n## Compression\n\nSee my blog post in [Benchmarks of Golang Gzip](https://blog.klauspost.com/go-gzipdeflate-benchmarks/).\n\nCompression cost is usually about 0.2% with default settings with a block size of 250k.\n\nExample with GOMAXPROC set to 32 (16 core CPU)\n\nContent is [Matt Mahoneys 10GB corpus](http://mattmahoney.net/dc/10gb.html). Compression level 6.\n\nCompressor  | MB/sec   | speedup | size | size overhead (lower=better)\n------------|----------|---------|------|---------\n[gzip](http://golang.org/pkg/compress/gzip) (golang) | 15.44MB/s (1 thread) | 1.0x | 4781329307 | 0%\n[gzip](http://github.com/klauspost/compress/gzip) (klauspost) | 135.04MB/s (1 thread) | 8.74x | 4894858258 | +2.37%\n[pgzip](https://github.com/klauspost/pgzip) (klauspost) | 1573.23MB/s| 101.9x | 4902285651 | +2.53%\n[bgzf](https://godoc.org/github.com/biogo/hts/bgzf) (biogo) | 361.40MB/s | 23.4x | 4869686090 | +1.85%\n[pargzip](https://godoc.org/github.com/golang/build/pargzip) (builder) | 306.01MB/s | 19.8x | 4786890417 | +0.12%\n\npgzip also contains a [linear time compression](https://github.com/klauspost/compress#linear-time-compression-huffman-only) mode, that will allow compression at ~250MB per core per second, independent of the content.\n\nSee the [complete sheet](https://docs.google.com/spreadsheets/d/1nuNE2nPfuINCZJRMt6wFWhKpToF95I47XjSsc-1rbPQ/edit?usp=sharing) for different content types and compression settings.\n\n## Decompression\n\nThe decompression speedup is there because it allows you to do other work while the decompression is taking place.\n\nIn the example above, the numbers are as follows on a 4 CPU machine:\n\nDecompressor | Time | Speedup\n-------------|------|--------\n[gzip](http://golang.org/pkg/compress/gzip) (golang) | 1m28.85s | 0%\n[pgzip](https://github.com/klauspost/pgzip) (golang) | 43.48s | 104%\n\nBut wait, since gzip decompression is inherently singlethreaded (aside from CRC calculation) how can it be more than 100% faster?  Because pgzip due to its design also acts as a buffer. When using unbuffered gzip, you are also waiting for io when you are decompressing. If the gzip decoder can keep up, it will always have data ready for your reader, and you will not be waiting for input to the gzip decompressor to complete.\n\nThis is pretty much an optimal situation for pgzip, but it reflects most common usecases for CPU intensive gzip usage.\n\nI haven't included [bgzf](https://godoc.org/github.com/biogo/hts/bgzf) in this comparison, since it only can decompress files created by a compatible encoder, and therefore cannot be considered a generic gzip decompressor. But if you are able to compress your files with a bgzf compatible program, you can expect it to scale beyond 100%.\n\n# License\nThis contains large portions of code from the go repository - see GO_LICENSE for more information. The changes are released under MIT License. See LICENSE for more information.\n"
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/gunzip.go",
    "content": "// Copyright 2009 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// Package pgzip implements reading and writing of gzip format compressed files,\n// as specified in RFC 1952.\n//\n// This is a drop in replacement for \"compress/gzip\".\n// This will split compression into blocks that are compressed in parallel.\n// This can be useful for compressing big amounts of data.\n// The gzip decompression has not been modified, but remains in the package,\n// so you can use it as a complete replacement for \"compress/gzip\".\n//\n// See more at https://github.com/klauspost/pgzip\npackage pgzip\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"hash\"\n\t\"hash/crc32\"\n\t\"io\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/klauspost/compress/flate\"\n)\n\nconst (\n\tgzipID1     = 0x1f\n\tgzipID2     = 0x8b\n\tgzipDeflate = 8\n\tflagText    = 1 << 0\n\tflagHdrCrc  = 1 << 1\n\tflagExtra   = 1 << 2\n\tflagName    = 1 << 3\n\tflagComment = 1 << 4\n)\n\nfunc makeReader(r io.Reader) flate.Reader {\n\tif rr, ok := r.(flate.Reader); ok {\n\t\treturn rr\n\t}\n\treturn bufio.NewReader(r)\n}\n\nvar (\n\t// ErrChecksum is returned when reading GZIP data that has an invalid checksum.\n\tErrChecksum = errors.New(\"gzip: invalid checksum\")\n\t// ErrHeader is returned when reading GZIP data that has an invalid header.\n\tErrHeader = errors.New(\"gzip: invalid header\")\n)\n\n// The gzip file stores a header giving metadata about the compressed file.\n// That header is exposed as the fields of the Writer and Reader structs.\ntype Header struct {\n\tComment string    // comment\n\tExtra   []byte    // \"extra data\"\n\tModTime time.Time // modification time\n\tName    string    // file name\n\tOS      byte      // operating system type\n}\n\n// A Reader is an io.Reader that can be read to retrieve\n// uncompressed data from a gzip-format compressed file.\n//\n// In general, a gzip file can be a concatenation of gzip files,\n// each with its own header.  Reads from the Reader\n// return the concatenation of the uncompressed data of each.\n// Only the first header is recorded in the Reader fields.\n//\n// Gzip files store a length and checksum of the uncompressed data.\n// The Reader will return a ErrChecksum when Read\n// reaches the end of the uncompressed data if it does not\n// have the expected length or checksum.  Clients should treat data\n// returned by Read as tentative until they receive the io.EOF\n// marking the end of the data.\ntype Reader struct {\n\tHeader\n\tr            flate.Reader\n\tdecompressor io.ReadCloser\n\tdigest       hash.Hash32\n\tsize         uint32\n\tflg          byte\n\tbuf          [512]byte\n\terr          error\n\tcloseErr     chan error\n\tmultistream  bool\n\n\treadAhead   chan read\n\troff        int // read offset\n\tcurrent     []byte\n\tcloseReader chan struct{}\n\tlastBlock   bool\n\tblockSize   int\n\tblocks      int\n\n\tactiveRA bool       // Indication if readahead is active\n\tmu       sync.Mutex // Lock for above\n\n\tblockPool chan []byte\n}\n\ntype read struct {\n\tb   []byte\n\terr error\n}\n\n// NewReader creates a new Reader reading the given reader.\n// The implementation buffers input and may read more data than necessary from r.\n// It is the caller's responsibility to call Close on the Reader when done.\nfunc NewReader(r io.Reader) (*Reader, error) {\n\tz := new(Reader)\n\tz.blocks = defaultBlocks\n\tz.blockSize = defaultBlockSize\n\tz.r = makeReader(r)\n\tz.digest = crc32.NewIEEE()\n\tz.multistream = true\n\tz.blockPool = make(chan []byte, z.blocks)\n\tfor i := 0; i < z.blocks; i++ {\n\t\tz.blockPool <- make([]byte, z.blockSize)\n\t}\n\tif err := z.readHeader(true); err != nil {\n\t\treturn nil, err\n\t}\n\treturn z, nil\n}\n\n// NewReaderN creates a new Reader reading the given reader.\n// The implementation buffers input and may read more data than necessary from r.\n// It is the caller's responsibility to call Close on the Reader when done.\n//\n// With this you can control the approximate size of your blocks,\n// as well as how many blocks you want to have prefetched.\n//\n// Default values for this is blockSize = 250000, blocks = 16,\n// meaning up to 16 blocks of maximum 250000 bytes will be\n// prefetched.\nfunc NewReaderN(r io.Reader, blockSize, blocks int) (*Reader, error) {\n\tz := new(Reader)\n\tz.blocks = blocks\n\tz.blockSize = blockSize\n\tz.r = makeReader(r)\n\tz.digest = crc32.NewIEEE()\n\tz.multistream = true\n\n\t// Account for too small values\n\tif z.blocks <= 0 {\n\t\tz.blocks = defaultBlocks\n\t}\n\tif z.blockSize <= 512 {\n\t\tz.blockSize = defaultBlockSize\n\t}\n\tz.blockPool = make(chan []byte, z.blocks)\n\tfor i := 0; i < z.blocks; i++ {\n\t\tz.blockPool <- make([]byte, z.blockSize)\n\t}\n\tif err := z.readHeader(true); err != nil {\n\t\treturn nil, err\n\t}\n\treturn z, nil\n}\n\n// Reset discards the Reader z's state and makes it equivalent to the\n// result of its original state from NewReader, but reading from r instead.\n// This permits reusing a Reader rather than allocating a new one.\nfunc (z *Reader) Reset(r io.Reader) error {\n\tz.killReadAhead()\n\tz.r = makeReader(r)\n\tz.digest = crc32.NewIEEE()\n\tz.size = 0\n\tz.err = nil\n\tz.multistream = true\n\n\t// Account for uninitialized values\n\tif z.blocks <= 0 {\n\t\tz.blocks = defaultBlocks\n\t}\n\tif z.blockSize <= 512 {\n\t\tz.blockSize = defaultBlockSize\n\t}\n\n\tif z.blockPool == nil {\n\t\tz.blockPool = make(chan []byte, z.blocks)\n\t\tfor i := 0; i < z.blocks; i++ {\n\t\t\tz.blockPool <- make([]byte, z.blockSize)\n\t\t}\n\t}\n\n\treturn z.readHeader(true)\n}\n\n// Multistream controls whether the reader supports multistream files.\n//\n// If enabled (the default), the Reader expects the input to be a sequence\n// of individually gzipped data streams, each with its own header and\n// trailer, ending at EOF. The effect is that the concatenation of a sequence\n// of gzipped files is treated as equivalent to the gzip of the concatenation\n// of the sequence. This is standard behavior for gzip readers.\n//\n// Calling Multistream(false) disables this behavior; disabling the behavior\n// can be useful when reading file formats that distinguish individual gzip\n// data streams or mix gzip data streams with other data streams.\n// In this mode, when the Reader reaches the end of the data stream,\n// Read returns io.EOF. If the underlying reader implements io.ByteReader,\n// it will be left positioned just after the gzip stream.\n// To start the next stream, call z.Reset(r) followed by z.Multistream(false).\n// If there is no next stream, z.Reset(r) will return io.EOF.\nfunc (z *Reader) Multistream(ok bool) {\n\tz.multistream = ok\n}\n\n// GZIP (RFC 1952) is little-endian, unlike ZLIB (RFC 1950).\nfunc get4(p []byte) uint32 {\n\treturn uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24\n}\n\nfunc (z *Reader) readString() (string, error) {\n\tvar err error\n\tneedconv := false\n\tfor i := 0; ; i++ {\n\t\tif i >= len(z.buf) {\n\t\t\treturn \"\", ErrHeader\n\t\t}\n\t\tz.buf[i], err = z.r.ReadByte()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tif z.buf[i] > 0x7f {\n\t\t\tneedconv = true\n\t\t}\n\t\tif z.buf[i] == 0 {\n\t\t\t// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).\n\t\t\tif needconv {\n\t\t\t\ts := make([]rune, 0, i)\n\t\t\t\tfor _, v := range z.buf[0:i] {\n\t\t\t\t\ts = append(s, rune(v))\n\t\t\t\t}\n\t\t\t\treturn string(s), nil\n\t\t\t}\n\t\t\treturn string(z.buf[0:i]), nil\n\t\t}\n\t}\n}\n\nfunc (z *Reader) read2() (uint32, error) {\n\t_, err := io.ReadFull(z.r, z.buf[0:2])\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint32(z.buf[0]) | uint32(z.buf[1])<<8, nil\n}\n\nfunc (z *Reader) readHeader(save bool) error {\n\tz.killReadAhead()\n\n\t_, err := io.ReadFull(z.r, z.buf[0:10])\n\tif err != nil {\n\t\treturn err\n\t}\n\tif z.buf[0] != gzipID1 || z.buf[1] != gzipID2 || z.buf[2] != gzipDeflate {\n\t\treturn ErrHeader\n\t}\n\tz.flg = z.buf[3]\n\tif save {\n\t\tz.ModTime = time.Unix(int64(get4(z.buf[4:8])), 0)\n\t\t// z.buf[8] is xfl, ignored\n\t\tz.OS = z.buf[9]\n\t}\n\tz.digest.Reset()\n\tz.digest.Write(z.buf[0:10])\n\n\tif z.flg&flagExtra != 0 {\n\t\tn, err := z.read2()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdata := make([]byte, n)\n\t\tif _, err = io.ReadFull(z.r, data); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif save {\n\t\t\tz.Extra = data\n\t\t}\n\t}\n\n\tvar s string\n\tif z.flg&flagName != 0 {\n\t\tif s, err = z.readString(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif save {\n\t\t\tz.Name = s\n\t\t}\n\t}\n\n\tif z.flg&flagComment != 0 {\n\t\tif s, err = z.readString(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif save {\n\t\t\tz.Comment = s\n\t\t}\n\t}\n\n\tif z.flg&flagHdrCrc != 0 {\n\t\tn, err := z.read2()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsum := z.digest.Sum32() & 0xFFFF\n\t\tif n != sum {\n\t\t\treturn ErrHeader\n\t\t}\n\t}\n\n\tz.digest.Reset()\n\tz.decompressor = flate.NewReader(z.r)\n\tz.doReadAhead()\n\treturn nil\n}\n\nfunc (z *Reader) killReadAhead() error {\n\tz.mu.Lock()\n\tdefer z.mu.Unlock()\n\tif z.activeRA {\n\t\tif z.closeReader != nil {\n\t\t\tclose(z.closeReader)\n\t\t}\n\n\t\t// Wait for decompressor to be closed and return error, if any.\n\t\te, ok := <-z.closeErr\n\t\tz.activeRA = false\n\t\tif !ok {\n\t\t\t// Channel is closed, so if there was any error it has already been returned.\n\t\t\treturn nil\n\t\t}\n\t\treturn e\n\t}\n\treturn nil\n}\n\n// Starts readahead.\n// Will return on error (including io.EOF)\n// or when z.closeReader is closed.\nfunc (z *Reader) doReadAhead() {\n\tz.mu.Lock()\n\tdefer z.mu.Unlock()\n\tz.activeRA = true\n\n\tif z.blocks <= 0 {\n\t\tz.blocks = defaultBlocks\n\t}\n\tif z.blockSize <= 512 {\n\t\tz.blockSize = defaultBlockSize\n\t}\n\tra := make(chan read, z.blocks)\n\tz.readAhead = ra\n\tcloseReader := make(chan struct{}, 0)\n\tz.closeReader = closeReader\n\tz.lastBlock = false\n\tcloseErr := make(chan error, 1)\n\tz.closeErr = closeErr\n\tz.size = 0\n\tz.roff = 0\n\tz.current = nil\n\tdecomp := z.decompressor\n\n\tgo func() {\n\t\tdefer func() {\n\t\t\tcloseErr <- decomp.Close()\n\t\t\tclose(closeErr)\n\t\t\tclose(ra)\n\t\t}()\n\n\t\t// We hold a local reference to digest, since\n\t\t// it way be changed by reset.\n\t\tdigest := z.digest\n\t\tvar wg sync.WaitGroup\n\t\tfor {\n\t\t\tvar buf []byte\n\t\t\tselect {\n\t\t\tcase buf = <-z.blockPool:\n\t\t\tcase <-closeReader:\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbuf = buf[0:z.blockSize]\n\t\t\t// Try to fill the buffer\n\t\t\tn, err := io.ReadFull(decomp, buf)\n\t\t\tif err == io.ErrUnexpectedEOF {\n\t\t\t\tif n > 0 {\n\t\t\t\t\terr = nil\n\t\t\t\t} else {\n\t\t\t\t\t// If we got zero bytes, we need to establish if\n\t\t\t\t\t// we reached end of stream or truncated stream.\n\t\t\t\t\t_, err = decomp.Read([]byte{})\n\t\t\t\t\tif err == io.EOF {\n\t\t\t\t\t\terr = nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif n < len(buf) {\n\t\t\t\tbuf = buf[0:n]\n\t\t\t}\n\t\t\twg.Wait()\n\t\t\twg.Add(1)\n\t\t\tgo func() {\n\t\t\t\tdigest.Write(buf)\n\t\t\t\twg.Done()\n\t\t\t}()\n\t\t\tz.size += uint32(n)\n\n\t\t\t// If we return any error, out digest must be ready\n\t\t\tif err != nil {\n\t\t\t\twg.Wait()\n\t\t\t}\n\t\t\tselect {\n\t\t\tcase z.readAhead <- read{b: buf, err: err}:\n\t\t\tcase <-closeReader:\n\t\t\t\t// Sent on close, we don't care about the next results\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\nfunc (z *Reader) Read(p []byte) (n int, err error) {\n\tif z.err != nil {\n\t\treturn 0, z.err\n\t}\n\tif len(p) == 0 {\n\t\treturn 0, nil\n\t}\n\n\tfor {\n\t\tif len(z.current) == 0 && !z.lastBlock {\n\t\t\tread := <-z.readAhead\n\n\t\t\tif read.err != nil {\n\t\t\t\t// If not nil, the reader will have exited\n\t\t\t\tz.closeReader = nil\n\n\t\t\t\tif read.err != io.EOF {\n\t\t\t\t\tz.err = read.err\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif read.err == io.EOF {\n\t\t\t\t\tz.lastBlock = true\n\t\t\t\t\terr = nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tz.current = read.b\n\t\t\tz.roff = 0\n\t\t}\n\t\tavail := z.current[z.roff:]\n\t\tif len(p) >= len(avail) {\n\t\t\t// If len(p) >= len(current), return all content of current\n\t\t\tn = copy(p, avail)\n\t\t\tz.blockPool <- z.current\n\t\t\tz.current = nil\n\t\t\tif z.lastBlock {\n\t\t\t\terr = io.EOF\n\t\t\t\tbreak\n\t\t\t}\n\t\t} else {\n\t\t\t// We copy as much as there is space for\n\t\t\tn = copy(p, avail)\n\t\t\tz.roff += n\n\t\t}\n\t\treturn\n\t}\n\n\t// Finished file; check checksum + size.\n\tif _, err := io.ReadFull(z.r, z.buf[0:8]); err != nil {\n\t\tz.err = err\n\t\treturn 0, err\n\t}\n\tcrc32, isize := get4(z.buf[0:4]), get4(z.buf[4:8])\n\tsum := z.digest.Sum32()\n\tif sum != crc32 || isize != z.size {\n\t\tz.err = ErrChecksum\n\t\treturn 0, z.err\n\t}\n\n\t// File is ok; should we attempt reading one more?\n\tif !z.multistream {\n\t\treturn 0, io.EOF\n\t}\n\n\t// Is there another?\n\tif err = z.readHeader(false); err != nil {\n\t\tz.err = err\n\t\treturn\n\t}\n\n\t// Yes.  Reset and read from it.\n\treturn z.Read(p)\n}\n\nfunc (z *Reader) WriteTo(w io.Writer) (n int64, err error) {\n\ttotal := int64(0)\n\tfor {\n\t\tif z.err != nil {\n\t\t\treturn total, z.err\n\t\t}\n\t\t// We write both to output and digest.\n\t\tfor {\n\t\t\t// Read from input\n\t\t\tread := <-z.readAhead\n\t\t\tif read.err != nil {\n\t\t\t\t// If not nil, the reader will have exited\n\t\t\t\tz.closeReader = nil\n\n\t\t\t\tif read.err != io.EOF {\n\t\t\t\t\tz.err = read.err\n\t\t\t\t\treturn total, z.err\n\t\t\t\t}\n\t\t\t\tif read.err == io.EOF {\n\t\t\t\t\tz.lastBlock = true\n\t\t\t\t\terr = nil\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Write what we got\n\t\t\tn, err := w.Write(read.b)\n\t\t\tif n != len(read.b) {\n\t\t\t\treturn total, io.ErrShortWrite\n\t\t\t}\n\t\t\ttotal += int64(n)\n\t\t\tif err != nil {\n\t\t\t\treturn total, err\n\t\t\t}\n\t\t\t// Put block back\n\t\t\tz.blockPool <- read.b\n\t\t\tif z.lastBlock {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Finished file; check checksum + size.\n\t\tif _, err := io.ReadFull(z.r, z.buf[0:8]); err != nil {\n\t\t\tz.err = err\n\t\t\treturn total, err\n\t\t}\n\t\tcrc32, isize := get4(z.buf[0:4]), get4(z.buf[4:8])\n\t\tsum := z.digest.Sum32()\n\t\tif sum != crc32 || isize != z.size {\n\t\t\tz.err = ErrChecksum\n\t\t\treturn total, z.err\n\t\t}\n\t\t// File is ok; should we attempt reading one more?\n\t\tif !z.multistream {\n\t\t\treturn total, nil\n\t\t}\n\n\t\t// Is there another?\n\t\terr = z.readHeader(false)\n\t\tif err == io.EOF {\n\t\t\treturn total, nil\n\t\t}\n\t\tif err != nil {\n\t\t\tz.err = err\n\t\t\treturn total, err\n\t\t}\n\t}\n}\n\n// Close closes the Reader. It does not close the underlying io.Reader.\nfunc (z *Reader) Close() error {\n\treturn z.killReadAhead()\n}\n"
  },
  {
    "path": "vendor/github.com/klauspost/pgzip/gzip.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 pgzip\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"hash/crc32\"\n\t\"io\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/klauspost/compress/flate\"\n)\n\nconst (\n\tdefaultBlockSize = 1 << 20\n\ttailSize         = 16384\n\tdefaultBlocks    = 4\n)\n\n// These constants are copied from the flate package, so that code that imports\n// \"compress/gzip\" does not also have to import \"compress/flate\".\nconst (\n\tNoCompression       = flate.NoCompression\n\tBestSpeed           = flate.BestSpeed\n\tBestCompression     = flate.BestCompression\n\tDefaultCompression  = flate.DefaultCompression\n\tConstantCompression = flate.ConstantCompression\n\tHuffmanOnly         = flate.HuffmanOnly\n)\n\n// A Writer is an io.WriteCloser.\n// Writes to a Writer are compressed and written to w.\ntype Writer struct {\n\tHeader\n\tw             io.Writer\n\tlevel         int\n\twroteHeader   bool\n\tblockSize     int\n\tblocks        int\n\tcurrentBuffer []byte\n\tprevTail      []byte\n\tdigest        hash.Hash32\n\tsize          int\n\tclosed        bool\n\tbuf           [10]byte\n\terrMu         sync.RWMutex\n\terr           error\n\tpushedErr     chan struct{}\n\tresults       chan result\n\tdictFlatePool sync.Pool\n\tdstPool       sync.Pool\n\twg            sync.WaitGroup\n}\n\ntype result struct {\n\tresult        chan []byte\n\tnotifyWritten chan struct{}\n}\n\n// Use SetConcurrency to finetune the concurrency level if needed.\n//\n// With this you can control the approximate size of your blocks,\n// as well as how many you want to be processing in parallel.\n//\n// Default values for this is SetConcurrency(defaultBlockSize, runtime.GOMAXPROCS(0)),\n// meaning blocks are split at 1 MB and up to the number of CPU threads\n// can be processing at once before the writer blocks.\nfunc (z *Writer) SetConcurrency(blockSize, blocks int) error {\n\tif blockSize <= tailSize {\n\t\treturn fmt.Errorf(\"gzip: block size cannot be less than or equal to %d\", tailSize)\n\t}\n\tif blocks <= 0 {\n\t\treturn errors.New(\"gzip: blocks cannot be zero or less\")\n\t}\n\tif blockSize == z.blockSize && blocks == z.blocks {\n\t\treturn nil\n\t}\n\tz.blockSize = blockSize\n\tz.results = make(chan result, blocks)\n\tz.blocks = blocks\n\tz.dstPool.New = func() interface{} { return make([]byte, 0, blockSize+(blockSize)>>4) }\n\treturn nil\n}\n\n// NewWriter returns a new Writer.\n// Writes to the returned writer are compressed and written to w.\n//\n// It is the caller's responsibility to call Close on the WriteCloser when done.\n// Writes may be buffered and not flushed until Close.\n//\n// Callers that wish to set the fields in Writer.Header must do so before\n// the first call to Write or Close. The Comment and Name header fields are\n// UTF-8 strings in Go, but the underlying format requires NUL-terminated ISO\n// 8859-1 (Latin-1). NUL or non-Latin-1 runes in those strings will lead to an\n// error on Write.\nfunc NewWriter(w io.Writer) *Writer {\n\tz, _ := NewWriterLevel(w, DefaultCompression)\n\treturn z\n}\n\n// NewWriterLevel is like NewWriter but specifies the compression level instead\n// of assuming DefaultCompression.\n//\n// The compression level can be DefaultCompression, NoCompression, or any\n// integer value between BestSpeed and BestCompression inclusive. The error\n// returned will be nil if the level is valid.\nfunc NewWriterLevel(w io.Writer, level int) (*Writer, error) {\n\tif level < ConstantCompression || level > BestCompression {\n\t\treturn nil, fmt.Errorf(\"gzip: invalid compression level: %d\", level)\n\t}\n\tz := new(Writer)\n\tz.SetConcurrency(defaultBlockSize, runtime.GOMAXPROCS(0))\n\tz.init(w, level)\n\treturn z, nil\n}\n\n// This function must be used by goroutines to set an\n// error condition, since z.err access is restricted\n// to the callers goruotine.\nfunc (z *Writer) pushError(err error) {\n\tz.errMu.Lock()\n\tif z.err != nil {\n\t\tz.errMu.Unlock()\n\t\treturn\n\t}\n\tz.err = err\n\tclose(z.pushedErr)\n\tz.errMu.Unlock()\n}\n\nfunc (z *Writer) init(w io.Writer, level int) {\n\tz.wg.Wait()\n\tdigest := z.digest\n\tif digest != nil {\n\t\tdigest.Reset()\n\t} else {\n\t\tdigest = crc32.NewIEEE()\n\t}\n\tz.Header = Header{OS: 255}\n\tz.w = w\n\tz.level = level\n\tz.digest = digest\n\tz.pushedErr = make(chan struct{}, 0)\n\tz.results = make(chan result, z.blocks)\n\tz.err = nil\n\tz.closed = false\n\tz.Comment = \"\"\n\tz.Extra = nil\n\tz.ModTime = time.Time{}\n\tz.wroteHeader = false\n\tz.currentBuffer = nil\n\tz.buf = [10]byte{}\n\tz.prevTail = nil\n\tz.size = 0\n\tif z.dictFlatePool.New == nil {\n\t\tz.dictFlatePool.New = func() interface{} {\n\t\t\tf, _ := flate.NewWriterDict(w, level, nil)\n\t\t\treturn f\n\t\t}\n\t}\n}\n\n// Reset discards the Writer z's state and makes it equivalent to the\n// result of its original state from NewWriter or NewWriterLevel, but\n// writing to w instead. This permits reusing a Writer rather than\n// allocating a new one.\nfunc (z *Writer) Reset(w io.Writer) {\n\tif z.results != nil && !z.closed {\n\t\tclose(z.results)\n\t}\n\tz.SetConcurrency(defaultBlockSize, runtime.GOMAXPROCS(0))\n\tz.init(w, z.level)\n}\n\n// GZIP (RFC 1952) is little-endian, unlike ZLIB (RFC 1950).\nfunc put2(p []byte, v uint16) {\n\tp[0] = uint8(v >> 0)\n\tp[1] = uint8(v >> 8)\n}\n\nfunc put4(p []byte, v uint32) {\n\tp[0] = uint8(v >> 0)\n\tp[1] = uint8(v >> 8)\n\tp[2] = uint8(v >> 16)\n\tp[3] = uint8(v >> 24)\n}\n\n// writeBytes writes a length-prefixed byte slice to z.w.\nfunc (z *Writer) writeBytes(b []byte) error {\n\tif len(b) > 0xffff {\n\t\treturn errors.New(\"gzip.Write: Extra data is too large\")\n\t}\n\tput2(z.buf[0:2], uint16(len(b)))\n\t_, err := z.w.Write(z.buf[0:2])\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = z.w.Write(b)\n\treturn err\n}\n\n// writeString writes a UTF-8 string s in GZIP's format to z.w.\n// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).\nfunc (z *Writer) writeString(s string) (err error) {\n\t// GZIP stores Latin-1 strings; error if non-Latin-1; convert if non-ASCII.\n\tneedconv := false\n\tfor _, v := range s {\n\t\tif v == 0 || v > 0xff {\n\t\t\treturn errors.New(\"gzip.Write: non-Latin-1 header string\")\n\t\t}\n\t\tif v > 0x7f {\n\t\t\tneedconv = true\n\t\t}\n\t}\n\tif needconv {\n\t\tb := make([]byte, 0, len(s))\n\t\tfor _, v := range s {\n\t\t\tb = append(b, byte(v))\n\t\t}\n\t\t_, err = z.w.Write(b)\n\t} else {\n\t\t_, err = io.WriteString(z.w, s)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\t// GZIP strings are NUL-terminated.\n\tz.buf[0] = 0\n\t_, err = z.w.Write(z.buf[0:1])\n\treturn err\n}\n\n// compressCurrent will compress the data currently buffered\n// This should only be called from the main writer/flush/closer\nfunc (z *Writer) compressCurrent(flush bool) {\n\tc := z.currentBuffer\n\tif len(c) > z.blockSize {\n\t\t// This can never happen through the public interface.\n\t\tpanic(\"len(z.currentBuffer) > z.blockSize (most likely due to concurrent Write race)\")\n\t}\n\n\tr := result{}\n\tr.result = make(chan []byte, 1)\n\tr.notifyWritten = make(chan struct{}, 0)\n\t// Reserve a result slot\n\tselect {\n\tcase z.results <- r:\n\tcase <-z.pushedErr:\n\t\treturn\n\t}\n\n\tz.wg.Add(1)\n\ttail := z.prevTail\n\tif len(c) > tailSize {\n\t\tbuf := z.dstPool.Get().([]byte) // Put in .compressBlock\n\t\t// Copy tail from current buffer before handing the buffer over to the\n\t\t// compressBlock goroutine.\n\t\tbuf = append(buf[:0], c[len(c)-tailSize:]...)\n\t\tz.prevTail = buf\n\t} else {\n\t\tz.prevTail = nil\n\t}\n\tgo z.compressBlock(c, tail, r, z.closed)\n\n\tz.currentBuffer = z.dstPool.Get().([]byte) // Put in .compressBlock\n\tz.currentBuffer = z.currentBuffer[:0]\n\n\t// Wait if flushing\n\tif flush {\n\t\t<-r.notifyWritten\n\t}\n}\n\n// Returns an error if it has been set.\n// Cannot be used by functions that are from internal goroutines.\nfunc (z *Writer) checkError() error {\n\tz.errMu.RLock()\n\terr := z.err\n\tz.errMu.RUnlock()\n\treturn err\n}\n\n// Write writes a compressed form of p to the underlying io.Writer. The\n// compressed bytes are not necessarily flushed to output until\n// the Writer is closed or Flush() is called.\n//\n// The function will return quickly, if there are unused buffers.\n// The sent slice (p) is copied, and the caller is free to re-use the buffer\n// when the function returns.\n//\n// Errors that occur during compression will be reported later, and a nil error\n// does not signify that the compression succeeded (since it is most likely still running)\n// That means that the call that returns an error may not be the call that caused it.\n// Only Flush and Close functions are guaranteed to return any errors up to that point.\nfunc (z *Writer) Write(p []byte) (int, error) {\n\tif err := z.checkError(); err != nil {\n\t\treturn 0, err\n\t}\n\t// Write the GZIP header lazily.\n\tif !z.wroteHeader {\n\t\tz.wroteHeader = true\n\t\tz.buf[0] = gzipID1\n\t\tz.buf[1] = gzipID2\n\t\tz.buf[2] = gzipDeflate\n\t\tz.buf[3] = 0\n\t\tif z.Extra != nil {\n\t\t\tz.buf[3] |= 0x04\n\t\t}\n\t\tif z.Name != \"\" {\n\t\t\tz.buf[3] |= 0x08\n\t\t}\n\t\tif z.Comment != \"\" {\n\t\t\tz.buf[3] |= 0x10\n\t\t}\n\t\tput4(z.buf[4:8], uint32(z.ModTime.Unix()))\n\t\tif z.level == BestCompression {\n\t\t\tz.buf[8] = 2\n\t\t} else if z.level == BestSpeed {\n\t\t\tz.buf[8] = 4\n\t\t} else {\n\t\t\tz.buf[8] = 0\n\t\t}\n\t\tz.buf[9] = z.OS\n\t\tvar n int\n\t\tvar err error\n\t\tn, err = z.w.Write(z.buf[0:10])\n\t\tif err != nil {\n\t\t\tz.pushError(err)\n\t\t\treturn n, err\n\t\t}\n\t\tif z.Extra != nil {\n\t\t\terr = z.writeBytes(z.Extra)\n\t\t\tif err != nil {\n\t\t\t\tz.pushError(err)\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t\tif z.Name != \"\" {\n\t\t\terr = z.writeString(z.Name)\n\t\t\tif err != nil {\n\t\t\t\tz.pushError(err)\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t\tif z.Comment != \"\" {\n\t\t\terr = z.writeString(z.Comment)\n\t\t\tif err != nil {\n\t\t\t\tz.pushError(err)\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t\t// Start receiving data from compressors\n\t\tgo func() {\n\t\t\tlisten := z.results\n\t\t\tvar failed bool\n\t\t\tfor {\n\t\t\t\tr, ok := <-listen\n\t\t\t\t// If closed, we are finished.\n\t\t\t\tif !ok {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif failed {\n\t\t\t\t\tclose(r.notifyWritten)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbuf := <-r.result\n\t\t\t\tn, err := z.w.Write(buf)\n\t\t\t\tif err != nil {\n\t\t\t\t\tz.pushError(err)\n\t\t\t\t\tclose(r.notifyWritten)\n\t\t\t\t\tfailed = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif n != len(buf) {\n\t\t\t\t\tz.pushError(fmt.Errorf(\"gzip: short write %d should be %d\", n, len(buf)))\n\t\t\t\t\tfailed = true\n\t\t\t\t\tclose(r.notifyWritten)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tz.dstPool.Put(buf)\n\t\t\t\tclose(r.notifyWritten)\n\t\t\t}\n\t\t}()\n\t\tz.currentBuffer = z.dstPool.Get().([]byte)\n\t\tz.currentBuffer = z.currentBuffer[:0]\n\t}\n\tq := p\n\tfor len(q) > 0 {\n\t\tlength := len(q)\n\t\tif length+len(z.currentBuffer) > z.blockSize {\n\t\t\tlength = z.blockSize - len(z.currentBuffer)\n\t\t}\n\t\tz.digest.Write(q[:length])\n\t\tz.currentBuffer = append(z.currentBuffer, q[:length]...)\n\t\tif len(z.currentBuffer) > z.blockSize {\n\t\t\tpanic(\"z.currentBuffer too large (most likely due to concurrent Write race)\")\n\t\t}\n\t\tif len(z.currentBuffer) == z.blockSize {\n\t\t\tz.compressCurrent(false)\n\t\t\tif err := z.checkError(); err != nil {\n\t\t\t\treturn len(p) - len(q), err\n\t\t\t}\n\t\t}\n\t\tz.size += length\n\t\tq = q[length:]\n\t}\n\treturn len(p), z.checkError()\n}\n\n// Step 1: compresses buffer to buffer\n// Step 2: send writer to channel\n// Step 3: Close result channel to indicate we are done\nfunc (z *Writer) compressBlock(p, prevTail []byte, r result, closed bool) {\n\tdefer func() {\n\t\tclose(r.result)\n\t\tz.wg.Done()\n\t}()\n\tbuf := z.dstPool.Get().([]byte) // Corresponding Put in .Write's result writer\n\tdest := bytes.NewBuffer(buf[:0])\n\n\tcompressor := z.dictFlatePool.Get().(*flate.Writer) // Put below\n\tcompressor.ResetDict(dest, prevTail)\n\tcompressor.Write(p)\n\tz.dstPool.Put(p) // Corresponding Get in .Write and .compressCurrent\n\n\terr := compressor.Flush()\n\tif err != nil {\n\t\tz.pushError(err)\n\t\treturn\n\t}\n\tif closed {\n\t\terr = compressor.Close()\n\t\tif err != nil {\n\t\t\tz.pushError(err)\n\t\t\treturn\n\t\t}\n\t}\n\tz.dictFlatePool.Put(compressor) // Get above\n\n\tif prevTail != nil {\n\t\tz.dstPool.Put(prevTail) // Get in .compressCurrent\n\t}\n\n\t// Read back buffer\n\tbuf = dest.Bytes()\n\tr.result <- buf\n}\n\n// Flush flushes any pending compressed data to the underlying writer.\n//\n// It is useful mainly in compressed network protocols, to ensure that\n// a remote reader has enough data to reconstruct a packet. Flush does\n// not return until the data has been written. If the underlying\n// writer returns an error, Flush returns that error.\n//\n// In the terminology of the zlib library, Flush is equivalent to Z_SYNC_FLUSH.\nfunc (z *Writer) Flush() error {\n\tif err := z.checkError(); err != nil {\n\t\treturn err\n\t}\n\tif z.closed {\n\t\treturn nil\n\t}\n\tif !z.wroteHeader {\n\t\t_, err := z.Write(nil)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t// We send current block to compression\n\tz.compressCurrent(true)\n\n\treturn z.checkError()\n}\n\n// UncompressedSize will return the number of bytes written.\n// pgzip only, not a function in the official gzip package.\nfunc (z *Writer) UncompressedSize() int {\n\treturn z.size\n}\n\n// Close closes the Writer, flushing any unwritten data to the underlying\n// io.Writer, but does not close the underlying io.Writer.\nfunc (z *Writer) Close() error {\n\tif err := z.checkError(); err != nil {\n\t\treturn err\n\t}\n\tif z.closed {\n\t\treturn nil\n\t}\n\n\tz.closed = true\n\tif !z.wroteHeader {\n\t\tz.Write(nil)\n\t\tif err := z.checkError(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tz.compressCurrent(true)\n\tif err := z.checkError(); err != nil {\n\t\treturn err\n\t}\n\tclose(z.results)\n\tput4(z.buf[0:4], z.digest.Sum32())\n\tput4(z.buf[4:8], uint32(z.size))\n\t_, err := z.w.Write(z.buf[0:8])\n\tif err != nil {\n\t\tz.pushError(err)\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/liggitt/tabwriter/.travis.yml",
    "content": "language: go\n\ngo:\n  - \"1.8\"\n  - \"1.9\"\n  - \"1.10\"\n  - \"1.11\"\n  - \"1.12\"\n  - master\n\nscript: go test -v ./...\n"
  },
  {
    "path": "vendor/github.com/liggitt/tabwriter/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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/liggitt/tabwriter/README.md",
    "content": "This repo is a drop-in replacement for the golang [text/tabwriter](https://golang.org/pkg/text/tabwriter/) package.\n\nIt is based on that package at [cf2c2ea8](https://github.com/golang/go/tree/cf2c2ea89d09d486bb018b1817c5874388038c3a/src/text/tabwriter) and inherits its license.\n\nThe following additional features are supported:\n* `RememberWidths` flag allows remembering maximum widths seen per column even after Flush() is called.\n* `RememberedWidths() []int` and `SetRememberedWidths([]int) *Writer` allows obtaining and transferring remembered column width between writers.\n"
  },
  {
    "path": "vendor/github.com/liggitt/tabwriter/tabwriter.go",
    "content": "// Copyright 2009 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// Package tabwriter implements a write filter (tabwriter.Writer) that\n// translates tabbed columns in input into properly aligned text.\n//\n// It is a drop-in replacement for the golang text/tabwriter package (https://golang.org/pkg/text/tabwriter),\n// based on that package at https://github.com/golang/go/tree/cf2c2ea89d09d486bb018b1817c5874388038c3a\n// with support for additional features.\n//\n// The package is using the Elastic Tabstops algorithm described at\n// http://nickgravgaard.com/elastictabstops/index.html.\npackage tabwriter\n\nimport (\n\t\"io\"\n\t\"unicode/utf8\"\n)\n\n// ----------------------------------------------------------------------------\n// Filter implementation\n\n// A cell represents a segment of text terminated by tabs or line breaks.\n// The text itself is stored in a separate buffer; cell only describes the\n// segment's size in bytes, its width in runes, and whether it's an htab\n// ('\\t') terminated cell.\n//\ntype cell struct {\n\tsize  int  // cell size in bytes\n\twidth int  // cell width in runes\n\thtab  bool // true if the cell is terminated by an htab ('\\t')\n}\n\n// A Writer is a filter that inserts padding around tab-delimited\n// columns in its input to align them in the output.\n//\n// The Writer treats incoming bytes as UTF-8-encoded text consisting\n// of cells terminated by horizontal ('\\t') or vertical ('\\v') tabs,\n// and newline ('\\n') or formfeed ('\\f') characters; both newline and\n// formfeed act as line breaks.\n//\n// Tab-terminated cells in contiguous lines constitute a column. The\n// Writer inserts padding as needed to make all cells in a column have\n// the same width, effectively aligning the columns. It assumes that\n// all characters have the same width, except for tabs for which a\n// tabwidth must be specified. Column cells must be tab-terminated, not\n// tab-separated: non-tab terminated trailing text at the end of a line\n// forms a cell but that cell is not part of an aligned column.\n// For instance, in this example (where | stands for a horizontal tab):\n//\n//\taaaa|bbb|d\n//\taa  |b  |dd\n//\ta   |\n//\taa  |cccc|eee\n//\n// the b and c are in distinct columns (the b column is not contiguous\n// all the way). The d and e are not in a column at all (there's no\n// terminating tab, nor would the column be contiguous).\n//\n// The Writer assumes that all Unicode code points have the same width;\n// this may not be true in some fonts or if the string contains combining\n// characters.\n//\n// If DiscardEmptyColumns is set, empty columns that are terminated\n// entirely by vertical (or \"soft\") tabs are discarded. Columns\n// terminated by horizontal (or \"hard\") tabs are not affected by\n// this flag.\n//\n// If a Writer is configured to filter HTML, HTML tags and entities\n// are passed through. The widths of tags and entities are\n// assumed to be zero (tags) and one (entities) for formatting purposes.\n//\n// A segment of text may be escaped by bracketing it with Escape\n// characters. The tabwriter passes escaped text segments through\n// unchanged. In particular, it does not interpret any tabs or line\n// breaks within the segment. If the StripEscape flag is set, the\n// Escape characters are stripped from the output; otherwise they\n// are passed through as well. For the purpose of formatting, the\n// width of the escaped text is always computed excluding the Escape\n// characters.\n//\n// The formfeed character acts like a newline but it also terminates\n// all columns in the current line (effectively calling Flush). Tab-\n// terminated cells in the next line start new columns. Unless found\n// inside an HTML tag or inside an escaped text segment, formfeed\n// characters appear as newlines in the output.\n//\n// The Writer must buffer input internally, because proper spacing\n// of one line may depend on the cells in future lines. Clients must\n// call Flush when done calling Write.\n//\ntype Writer struct {\n\t// configuration\n\toutput   io.Writer\n\tminwidth int\n\ttabwidth int\n\tpadding  int\n\tpadbytes [8]byte\n\tflags    uint\n\n\t// current state\n\tbuf     []byte   // collected text excluding tabs or line breaks\n\tpos     int      // buffer position up to which cell.width of incomplete cell has been computed\n\tcell    cell     // current incomplete cell; cell.width is up to buf[pos] excluding ignored sections\n\tendChar byte     // terminating char of escaped sequence (Escape for escapes, '>', ';' for HTML tags/entities, or 0)\n\tlines   [][]cell // list of lines; each line is a list of cells\n\twidths  []int    // list of column widths in runes - re-used during formatting\n\n\tmaxwidths []int // list of max column widths in runes\n}\n\n// addLine adds a new line.\n// flushed is a hint indicating whether the underlying writer was just flushed.\n// If so, the previous line is not likely to be a good indicator of the new line's cells.\nfunc (b *Writer) addLine(flushed bool) {\n\t// Grow slice instead of appending,\n\t// as that gives us an opportunity\n\t// to re-use an existing []cell.\n\tif n := len(b.lines) + 1; n <= cap(b.lines) {\n\t\tb.lines = b.lines[:n]\n\t\tb.lines[n-1] = b.lines[n-1][:0]\n\t} else {\n\t\tb.lines = append(b.lines, nil)\n\t}\n\n\tif !flushed {\n\t\t// The previous line is probably a good indicator\n\t\t// of how many cells the current line will have.\n\t\t// If the current line's capacity is smaller than that,\n\t\t// abandon it and make a new one.\n\t\tif n := len(b.lines); n >= 2 {\n\t\t\tif prev := len(b.lines[n-2]); prev > cap(b.lines[n-1]) {\n\t\t\t\tb.lines[n-1] = make([]cell, 0, prev)\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Reset the current state.\nfunc (b *Writer) reset() {\n\tb.buf = b.buf[:0]\n\tb.pos = 0\n\tb.cell = cell{}\n\tb.endChar = 0\n\tb.lines = b.lines[0:0]\n\tb.widths = b.widths[0:0]\n\tb.addLine(true)\n}\n\n// Internal representation (current state):\n//\n// - all text written is appended to buf; tabs and line breaks are stripped away\n// - at any given time there is a (possibly empty) incomplete cell at the end\n//   (the cell starts after a tab or line break)\n// - cell.size is the number of bytes belonging to the cell so far\n// - cell.width is text width in runes of that cell from the start of the cell to\n//   position pos; html tags and entities are excluded from this width if html\n//   filtering is enabled\n// - the sizes and widths of processed text are kept in the lines list\n//   which contains a list of cells for each line\n// - the widths list is a temporary list with current widths used during\n//   formatting; it is kept in Writer because it's re-used\n//\n//                    |<---------- size ---------->|\n//                    |                            |\n//                    |<- width ->|<- ignored ->|  |\n//                    |           |             |  |\n// [---processed---tab------------<tag>...</tag>...]\n// ^                  ^                         ^\n// |                  |                         |\n// buf                start of incomplete cell  pos\n\n// Formatting can be controlled with these flags.\nconst (\n\t// Ignore html tags and treat entities (starting with '&'\n\t// and ending in ';') as single characters (width = 1).\n\tFilterHTML uint = 1 << iota\n\n\t// Strip Escape characters bracketing escaped text segments\n\t// instead of passing them through unchanged with the text.\n\tStripEscape\n\n\t// Force right-alignment of cell content.\n\t// Default is left-alignment.\n\tAlignRight\n\n\t// Handle empty columns as if they were not present in\n\t// the input in the first place.\n\tDiscardEmptyColumns\n\n\t// Always use tabs for indentation columns (i.e., padding of\n\t// leading empty cells on the left) independent of padchar.\n\tTabIndent\n\n\t// Print a vertical bar ('|') between columns (after formatting).\n\t// Discarded columns appear as zero-width columns (\"||\").\n\tDebug\n\n\t// Remember maximum widths seen per column even after Flush() is called.\n\tRememberWidths\n)\n\n// A Writer must be initialized with a call to Init. The first parameter (output)\n// specifies the filter output. The remaining parameters control the formatting:\n//\n//\tminwidth\tminimal cell width including any padding\n//\ttabwidth\twidth of tab characters (equivalent number of spaces)\n//\tpadding\t\tpadding added to a cell before computing its width\n//\tpadchar\t\tASCII char used for padding\n//\t\t\tif padchar == '\\t', the Writer will assume that the\n//\t\t\twidth of a '\\t' in the formatted output is tabwidth,\n//\t\t\tand cells are left-aligned independent of align_left\n//\t\t\t(for correct-looking results, tabwidth must correspond\n//\t\t\tto the tab width in the viewer displaying the result)\n//\tflags\t\tformatting control\n//\nfunc (b *Writer) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer {\n\tif minwidth < 0 || tabwidth < 0 || padding < 0 {\n\t\tpanic(\"negative minwidth, tabwidth, or padding\")\n\t}\n\tb.output = output\n\tb.minwidth = minwidth\n\tb.tabwidth = tabwidth\n\tb.padding = padding\n\tfor i := range b.padbytes {\n\t\tb.padbytes[i] = padchar\n\t}\n\tif padchar == '\\t' {\n\t\t// tab padding enforces left-alignment\n\t\tflags &^= AlignRight\n\t}\n\tb.flags = flags\n\n\tb.reset()\n\n\treturn b\n}\n\n// debugging support (keep code around)\nfunc (b *Writer) dump() {\n\tpos := 0\n\tfor i, line := range b.lines {\n\t\tprint(\"(\", i, \") \")\n\t\tfor _, c := range line {\n\t\t\tprint(\"[\", string(b.buf[pos:pos+c.size]), \"]\")\n\t\t\tpos += c.size\n\t\t}\n\t\tprint(\"\\n\")\n\t}\n\tprint(\"\\n\")\n}\n\n// local error wrapper so we can distinguish errors we want to return\n// as errors from genuine panics (which we don't want to return as errors)\ntype osError struct {\n\terr error\n}\n\nfunc (b *Writer) write0(buf []byte) {\n\tn, err := b.output.Write(buf)\n\tif n != len(buf) && err == nil {\n\t\terr = io.ErrShortWrite\n\t}\n\tif err != nil {\n\t\tpanic(osError{err})\n\t}\n}\n\nfunc (b *Writer) writeN(src []byte, n int) {\n\tfor n > len(src) {\n\t\tb.write0(src)\n\t\tn -= len(src)\n\t}\n\tb.write0(src[0:n])\n}\n\nvar (\n\tnewline = []byte{'\\n'}\n\ttabs    = []byte(\"\\t\\t\\t\\t\\t\\t\\t\\t\")\n)\n\nfunc (b *Writer) writePadding(textw, cellw int, useTabs bool) {\n\tif b.padbytes[0] == '\\t' || useTabs {\n\t\t// padding is done with tabs\n\t\tif b.tabwidth == 0 {\n\t\t\treturn // tabs have no width - can't do any padding\n\t\t}\n\t\t// make cellw the smallest multiple of b.tabwidth\n\t\tcellw = (cellw + b.tabwidth - 1) / b.tabwidth * b.tabwidth\n\t\tn := cellw - textw // amount of padding\n\t\tif n < 0 {\n\t\t\tpanic(\"internal error\")\n\t\t}\n\t\tb.writeN(tabs, (n+b.tabwidth-1)/b.tabwidth)\n\t\treturn\n\t}\n\n\t// padding is done with non-tab characters\n\tb.writeN(b.padbytes[0:], cellw-textw)\n}\n\nvar vbar = []byte{'|'}\n\nfunc (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) {\n\tpos = pos0\n\tfor i := line0; i < line1; i++ {\n\t\tline := b.lines[i]\n\n\t\t// if TabIndent is set, use tabs to pad leading empty cells\n\t\tuseTabs := b.flags&TabIndent != 0\n\n\t\tfor j, c := range line {\n\t\t\tif j > 0 && b.flags&Debug != 0 {\n\t\t\t\t// indicate column break\n\t\t\t\tb.write0(vbar)\n\t\t\t}\n\n\t\t\tif c.size == 0 {\n\t\t\t\t// empty cell\n\t\t\t\tif j < len(b.widths) {\n\t\t\t\t\tb.writePadding(c.width, b.widths[j], useTabs)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// non-empty cell\n\t\t\t\tuseTabs = false\n\t\t\t\tif b.flags&AlignRight == 0 { // align left\n\t\t\t\t\tb.write0(b.buf[pos : pos+c.size])\n\t\t\t\t\tpos += c.size\n\t\t\t\t\tif j < len(b.widths) {\n\t\t\t\t\t\tb.writePadding(c.width, b.widths[j], false)\n\t\t\t\t\t}\n\t\t\t\t} else { // align right\n\t\t\t\t\tif j < len(b.widths) {\n\t\t\t\t\t\tb.writePadding(c.width, b.widths[j], false)\n\t\t\t\t\t}\n\t\t\t\t\tb.write0(b.buf[pos : pos+c.size])\n\t\t\t\t\tpos += c.size\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif i+1 == len(b.lines) {\n\t\t\t// last buffered line - we don't have a newline, so just write\n\t\t\t// any outstanding buffered data\n\t\t\tb.write0(b.buf[pos : pos+b.cell.size])\n\t\t\tpos += b.cell.size\n\t\t} else {\n\t\t\t// not the last line - write newline\n\t\t\tb.write0(newline)\n\t\t}\n\t}\n\treturn\n}\n\n// Format the text between line0 and line1 (excluding line1); pos\n// is the buffer position corresponding to the beginning of line0.\n// Returns the buffer position corresponding to the beginning of\n// line1 and an error, if any.\n//\nfunc (b *Writer) format(pos0 int, line0, line1 int) (pos int) {\n\tpos = pos0\n\tcolumn := len(b.widths)\n\tfor this := line0; this < line1; this++ {\n\t\tline := b.lines[this]\n\n\t\tif column >= len(line)-1 {\n\t\t\tcontinue\n\t\t}\n\t\t// cell exists in this column => this line\n\t\t// has more cells than the previous line\n\t\t// (the last cell per line is ignored because cells are\n\t\t// tab-terminated; the last cell per line describes the\n\t\t// text before the newline/formfeed and does not belong\n\t\t// to a column)\n\n\t\t// print unprinted lines until beginning of block\n\t\tpos = b.writeLines(pos, line0, this)\n\t\tline0 = this\n\n\t\t// column block begin\n\t\twidth := b.minwidth // minimal column width\n\t\tdiscardable := true // true if all cells in this column are empty and \"soft\"\n\t\tfor ; this < line1; this++ {\n\t\t\tline = b.lines[this]\n\t\t\tif column >= len(line)-1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// cell exists in this column\n\t\t\tc := line[column]\n\t\t\t// update width\n\t\t\tif w := c.width + b.padding; w > width {\n\t\t\t\twidth = w\n\t\t\t}\n\t\t\t// update discardable\n\t\t\tif c.width > 0 || c.htab {\n\t\t\t\tdiscardable = false\n\t\t\t}\n\t\t}\n\t\t// column block end\n\n\t\t// discard empty columns if necessary\n\t\tif discardable && b.flags&DiscardEmptyColumns != 0 {\n\t\t\twidth = 0\n\t\t}\n\n\t\tif b.flags&RememberWidths != 0 {\n\t\t\tif len(b.maxwidths) < len(b.widths) {\n\t\t\t\tb.maxwidths = append(b.maxwidths, b.widths[len(b.maxwidths):]...)\n\t\t\t}\n\n\t\t\tswitch {\n\t\t\tcase len(b.maxwidths) == len(b.widths):\n\t\t\t\tb.maxwidths = append(b.maxwidths, width)\n\t\t\tcase b.maxwidths[len(b.widths)] > width:\n\t\t\t\twidth = b.maxwidths[len(b.widths)]\n\t\t\tcase b.maxwidths[len(b.widths)] < width:\n\t\t\t\tb.maxwidths[len(b.widths)] = width\n\t\t\t}\n\t\t}\n\n\t\t// format and print all columns to the right of this column\n\t\t// (we know the widths of this column and all columns to the left)\n\t\tb.widths = append(b.widths, width) // push width\n\t\tpos = b.format(pos, line0, this)\n\t\tb.widths = b.widths[0 : len(b.widths)-1] // pop width\n\t\tline0 = this\n\t}\n\n\t// print unprinted lines until end\n\treturn b.writeLines(pos, line0, line1)\n}\n\n// Append text to current cell.\nfunc (b *Writer) append(text []byte) {\n\tb.buf = append(b.buf, text...)\n\tb.cell.size += len(text)\n}\n\n// Update the cell width.\nfunc (b *Writer) updateWidth() {\n\tb.cell.width += utf8.RuneCount(b.buf[b.pos:])\n\tb.pos = len(b.buf)\n}\n\n// To escape a text segment, bracket it with Escape characters.\n// For instance, the tab in this string \"Ignore this tab: \\xff\\t\\xff\"\n// does not terminate a cell and constitutes a single character of\n// width one for formatting purposes.\n//\n// The value 0xff was chosen because it cannot appear in a valid UTF-8 sequence.\n//\nconst Escape = '\\xff'\n\n// Start escaped mode.\nfunc (b *Writer) startEscape(ch byte) {\n\tswitch ch {\n\tcase Escape:\n\t\tb.endChar = Escape\n\tcase '<':\n\t\tb.endChar = '>'\n\tcase '&':\n\t\tb.endChar = ';'\n\t}\n}\n\n// Terminate escaped mode. If the escaped text was an HTML tag, its width\n// is assumed to be zero for formatting purposes; if it was an HTML entity,\n// its width is assumed to be one. In all other cases, the width is the\n// unicode width of the text.\n//\nfunc (b *Writer) endEscape() {\n\tswitch b.endChar {\n\tcase Escape:\n\t\tb.updateWidth()\n\t\tif b.flags&StripEscape == 0 {\n\t\t\tb.cell.width -= 2 // don't count the Escape chars\n\t\t}\n\tcase '>': // tag of zero width\n\tcase ';':\n\t\tb.cell.width++ // entity, count as one rune\n\t}\n\tb.pos = len(b.buf)\n\tb.endChar = 0\n}\n\n// Terminate the current cell by adding it to the list of cells of the\n// current line. Returns the number of cells in that line.\n//\nfunc (b *Writer) terminateCell(htab bool) int {\n\tb.cell.htab = htab\n\tline := &b.lines[len(b.lines)-1]\n\t*line = append(*line, b.cell)\n\tb.cell = cell{}\n\treturn len(*line)\n}\n\nfunc handlePanic(err *error, op string) {\n\tif e := recover(); e != nil {\n\t\tif nerr, ok := e.(osError); ok {\n\t\t\t*err = nerr.err\n\t\t\treturn\n\t\t}\n\t\tpanic(\"tabwriter: panic during \" + op)\n\t}\n}\n\n// RememberedWidths returns a copy of the remembered per-column maximum widths.\n// Requires use of the RememberWidths flag, and is not threadsafe.\nfunc (b *Writer) RememberedWidths() []int {\n\tretval := make([]int, len(b.maxwidths))\n\tcopy(retval, b.maxwidths)\n\treturn retval\n}\n\n// SetRememberedWidths sets the remembered per-column maximum widths.\n// Requires use of the RememberWidths flag, and is not threadsafe.\nfunc (b *Writer) SetRememberedWidths(widths []int) *Writer {\n\tb.maxwidths = make([]int, len(widths))\n\tcopy(b.maxwidths, widths)\n\treturn b\n}\n\n// Flush should be called after the last call to Write to ensure\n// that any data buffered in the Writer is written to output. Any\n// incomplete escape sequence at the end is considered\n// complete for formatting purposes.\nfunc (b *Writer) Flush() error {\n\treturn b.flush()\n}\n\nfunc (b *Writer) flush() (err error) {\n\tdefer b.reset() // even in the presence of errors\n\tdefer handlePanic(&err, \"Flush\")\n\n\t// add current cell if not empty\n\tif b.cell.size > 0 {\n\t\tif b.endChar != 0 {\n\t\t\t// inside escape - terminate it even if incomplete\n\t\t\tb.endEscape()\n\t\t}\n\t\tb.terminateCell(false)\n\t}\n\n\t// format contents of buffer\n\tb.format(0, 0, len(b.lines))\n\treturn nil\n}\n\nvar hbar = []byte(\"---\\n\")\n\n// Write writes buf to the writer b.\n// The only errors returned are ones encountered\n// while writing to the underlying output stream.\n//\nfunc (b *Writer) Write(buf []byte) (n int, err error) {\n\tdefer handlePanic(&err, \"Write\")\n\n\t// split text into cells\n\tn = 0\n\tfor i, ch := range buf {\n\t\tif b.endChar == 0 {\n\t\t\t// outside escape\n\t\t\tswitch ch {\n\t\t\tcase '\\t', '\\v', '\\n', '\\f':\n\t\t\t\t// end of cell\n\t\t\t\tb.append(buf[n:i])\n\t\t\t\tb.updateWidth()\n\t\t\t\tn = i + 1 // ch consumed\n\t\t\t\tncells := b.terminateCell(ch == '\\t')\n\t\t\t\tif ch == '\\n' || ch == '\\f' {\n\t\t\t\t\t// terminate line\n\t\t\t\t\tb.addLine(ch == '\\f')\n\t\t\t\t\tif ch == '\\f' || ncells == 1 {\n\t\t\t\t\t\t// A '\\f' always forces a flush. Otherwise, if the previous\n\t\t\t\t\t\t// line has only one cell which does not have an impact on\n\t\t\t\t\t\t// the formatting of the following lines (the last cell per\n\t\t\t\t\t\t// line is ignored by format()), thus we can flush the\n\t\t\t\t\t\t// Writer contents.\n\t\t\t\t\t\tif err = b.Flush(); err != nil {\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ch == '\\f' && b.flags&Debug != 0 {\n\t\t\t\t\t\t\t// indicate section break\n\t\t\t\t\t\t\tb.write0(hbar)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase Escape:\n\t\t\t\t// start of escaped sequence\n\t\t\t\tb.append(buf[n:i])\n\t\t\t\tb.updateWidth()\n\t\t\t\tn = i\n\t\t\t\tif b.flags&StripEscape != 0 {\n\t\t\t\t\tn++ // strip Escape\n\t\t\t\t}\n\t\t\t\tb.startEscape(Escape)\n\n\t\t\tcase '<', '&':\n\t\t\t\t// possibly an html tag/entity\n\t\t\t\tif b.flags&FilterHTML != 0 {\n\t\t\t\t\t// begin of tag/entity\n\t\t\t\t\tb.append(buf[n:i])\n\t\t\t\t\tb.updateWidth()\n\t\t\t\t\tn = i\n\t\t\t\t\tb.startEscape(ch)\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// inside escape\n\t\t\tif ch == b.endChar {\n\t\t\t\t// end of tag/entity\n\t\t\t\tj := i + 1\n\t\t\t\tif ch == Escape && b.flags&StripEscape != 0 {\n\t\t\t\t\tj = i // strip Escape\n\t\t\t\t}\n\t\t\t\tb.append(buf[n:j])\n\t\t\t\tn = i + 1 // ch consumed\n\t\t\t\tb.endEscape()\n\t\t\t}\n\t\t}\n\t}\n\n\t// append leftover text\n\tb.append(buf[n:])\n\tn = len(buf)\n\treturn\n}\n\n// NewWriter allocates and initializes a new tabwriter.Writer.\n// The parameters are the same as for the Init function.\n//\nfunc NewWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer {\n\treturn new(Writer).Init(output, minwidth, tabwidth, padding, padchar, flags)\n}\n"
  },
  {
    "path": "vendor/github.com/mailru/easyjson/LICENSE",
    "content": "Copyright (c) 2016 Mail.Ru Group\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/mailru/easyjson/buffer/pool.go",
    "content": "// Package buffer implements a buffer for serialization, consisting of a chain of []byte-s to\n// reduce copying and to allow reuse of individual chunks.\npackage buffer\n\nimport (\n\t\"io\"\n\t\"net\"\n\t\"sync\"\n)\n\n// PoolConfig contains configuration for the allocation and reuse strategy.\ntype PoolConfig struct {\n\tStartSize  int // Minimum chunk size that is allocated.\n\tPooledSize int // Minimum chunk size that is reused, reusing chunks too small will result in overhead.\n\tMaxSize    int // Maximum chunk size that will be allocated.\n}\n\nvar config = PoolConfig{\n\tStartSize:  128,\n\tPooledSize: 512,\n\tMaxSize:    32768,\n}\n\n// Reuse pool: chunk size -> pool.\nvar buffers = map[int]*sync.Pool{}\n\nfunc initBuffers() {\n\tfor l := config.PooledSize; l <= config.MaxSize; l *= 2 {\n\t\tbuffers[l] = new(sync.Pool)\n\t}\n}\n\nfunc init() {\n\tinitBuffers()\n}\n\n// Init sets up a non-default pooling and allocation strategy. Should be run before serialization is done.\nfunc Init(cfg PoolConfig) {\n\tconfig = cfg\n\tinitBuffers()\n}\n\n// putBuf puts a chunk to reuse pool if it can be reused.\nfunc putBuf(buf []byte) {\n\tsize := cap(buf)\n\tif size < config.PooledSize {\n\t\treturn\n\t}\n\tif c := buffers[size]; c != nil {\n\t\tc.Put(buf[:0])\n\t}\n}\n\n// getBuf gets a chunk from reuse pool or creates a new one if reuse failed.\nfunc getBuf(size int) []byte {\n\tif size >= config.PooledSize {\n\t\tif c := buffers[size]; c != nil {\n\t\t\tv := c.Get()\n\t\t\tif v != nil {\n\t\t\t\treturn v.([]byte)\n\t\t\t}\n\t\t}\n\t}\n\treturn make([]byte, 0, size)\n}\n\n// Buffer is a buffer optimized for serialization without extra copying.\ntype Buffer struct {\n\n\t// Buf is the current chunk that can be used for serialization.\n\tBuf []byte\n\n\ttoPool []byte\n\tbufs   [][]byte\n}\n\n// EnsureSpace makes sure that the current chunk contains at least s free bytes,\n// possibly creating a new chunk.\nfunc (b *Buffer) EnsureSpace(s int) {\n\tif cap(b.Buf)-len(b.Buf) < s {\n\t\tb.ensureSpaceSlow(s)\n\t}\n}\n\nfunc (b *Buffer) ensureSpaceSlow(s int) {\n\tl := len(b.Buf)\n\tif l > 0 {\n\t\tif cap(b.toPool) != cap(b.Buf) {\n\t\t\t// Chunk was reallocated, toPool can be pooled.\n\t\t\tputBuf(b.toPool)\n\t\t}\n\t\tif cap(b.bufs) == 0 {\n\t\t\tb.bufs = make([][]byte, 0, 8)\n\t\t}\n\t\tb.bufs = append(b.bufs, b.Buf)\n\t\tl = cap(b.toPool) * 2\n\t} else {\n\t\tl = config.StartSize\n\t}\n\n\tif l > config.MaxSize {\n\t\tl = config.MaxSize\n\t}\n\tb.Buf = getBuf(l)\n\tb.toPool = b.Buf\n}\n\n// AppendByte appends a single byte to buffer.\nfunc (b *Buffer) AppendByte(data byte) {\n\tb.EnsureSpace(1)\n\tb.Buf = append(b.Buf, data)\n}\n\n// AppendBytes appends a byte slice to buffer.\nfunc (b *Buffer) AppendBytes(data []byte) {\n\tif len(data) <= cap(b.Buf)-len(b.Buf) {\n\t\tb.Buf = append(b.Buf, data...) // fast path\n\t} else {\n\t\tb.appendBytesSlow(data)\n\t}\n}\n\nfunc (b *Buffer) appendBytesSlow(data []byte) {\n\tfor len(data) > 0 {\n\t\tb.EnsureSpace(1)\n\n\t\tsz := cap(b.Buf) - len(b.Buf)\n\t\tif sz > len(data) {\n\t\t\tsz = len(data)\n\t\t}\n\n\t\tb.Buf = append(b.Buf, data[:sz]...)\n\t\tdata = data[sz:]\n\t}\n}\n\n// AppendString appends a string to buffer.\nfunc (b *Buffer) AppendString(data string) {\n\tif len(data) <= cap(b.Buf)-len(b.Buf) {\n\t\tb.Buf = append(b.Buf, data...) // fast path\n\t} else {\n\t\tb.appendStringSlow(data)\n\t}\n}\n\nfunc (b *Buffer) appendStringSlow(data string) {\n\tfor len(data) > 0 {\n\t\tb.EnsureSpace(1)\n\n\t\tsz := cap(b.Buf) - len(b.Buf)\n\t\tif sz > len(data) {\n\t\t\tsz = len(data)\n\t\t}\n\n\t\tb.Buf = append(b.Buf, data[:sz]...)\n\t\tdata = data[sz:]\n\t}\n}\n\n// Size computes the size of a buffer by adding sizes of every chunk.\nfunc (b *Buffer) Size() int {\n\tsize := len(b.Buf)\n\tfor _, buf := range b.bufs {\n\t\tsize += len(buf)\n\t}\n\treturn size\n}\n\n// DumpTo outputs the contents of a buffer to a writer and resets the buffer.\nfunc (b *Buffer) DumpTo(w io.Writer) (written int, err error) {\n\tbufs := net.Buffers(b.bufs)\n\tif len(b.Buf) > 0 {\n\t\tbufs = append(bufs, b.Buf)\n\t}\n\tn, err := bufs.WriteTo(w)\n\n\tfor _, buf := range b.bufs {\n\t\tputBuf(buf)\n\t}\n\tputBuf(b.toPool)\n\n\tb.bufs = nil\n\tb.Buf = nil\n\tb.toPool = nil\n\n\treturn int(n), err\n}\n\n// BuildBytes creates a single byte slice with all the contents of the buffer. Data is\n// copied if it does not fit in a single chunk. You can optionally provide one byte\n// slice as argument that it will try to reuse.\nfunc (b *Buffer) BuildBytes(reuse ...[]byte) []byte {\n\tif len(b.bufs) == 0 {\n\t\tret := b.Buf\n\t\tb.toPool = nil\n\t\tb.Buf = nil\n\t\treturn ret\n\t}\n\n\tvar ret []byte\n\tsize := b.Size()\n\n\t// If we got a buffer as argument and it is big enough, reuse it.\n\tif len(reuse) == 1 && cap(reuse[0]) >= size {\n\t\tret = reuse[0][:0]\n\t} else {\n\t\tret = make([]byte, 0, size)\n\t}\n\tfor _, buf := range b.bufs {\n\t\tret = append(ret, buf...)\n\t\tputBuf(buf)\n\t}\n\n\tret = append(ret, b.Buf...)\n\tputBuf(b.toPool)\n\n\tb.bufs = nil\n\tb.toPool = nil\n\tb.Buf = nil\n\n\treturn ret\n}\n\ntype readCloser struct {\n\toffset int\n\tbufs   [][]byte\n}\n\nfunc (r *readCloser) Read(p []byte) (n int, err error) {\n\tfor _, buf := range r.bufs {\n\t\t// Copy as much as we can.\n\t\tx := copy(p[n:], buf[r.offset:])\n\t\tn += x // Increment how much we filled.\n\n\t\t// Did we empty the whole buffer?\n\t\tif r.offset+x == len(buf) {\n\t\t\t// On to the next buffer.\n\t\t\tr.offset = 0\n\t\t\tr.bufs = r.bufs[1:]\n\n\t\t\t// We can release this buffer.\n\t\t\tputBuf(buf)\n\t\t} else {\n\t\t\tr.offset += x\n\t\t}\n\n\t\tif n == len(p) {\n\t\t\tbreak\n\t\t}\n\t}\n\t// No buffers left or nothing read?\n\tif len(r.bufs) == 0 {\n\t\terr = io.EOF\n\t}\n\treturn\n}\n\nfunc (r *readCloser) Close() error {\n\t// Release all remaining buffers.\n\tfor _, buf := range r.bufs {\n\t\tputBuf(buf)\n\t}\n\t// In case Close gets called multiple times.\n\tr.bufs = nil\n\n\treturn nil\n}\n\n// ReadCloser creates an io.ReadCloser with all the contents of the buffer.\nfunc (b *Buffer) ReadCloser() io.ReadCloser {\n\tret := &readCloser{0, append(b.bufs, b.Buf)}\n\n\tb.bufs = nil\n\tb.toPool = nil\n\tb.Buf = nil\n\n\treturn ret\n}\n"
  },
  {
    "path": "vendor/github.com/mailru/easyjson/jlexer/bytestostr.go",
    "content": "// This file will only be included to the build if neither\n// easyjson_nounsafe nor appengine build tag is set. See README notes\n// for more details.\n\n//+build !easyjson_nounsafe\n//+build !appengine\n\npackage jlexer\n\nimport (\n\t\"reflect\"\n\t\"unsafe\"\n)\n\n// bytesToStr creates a string pointing at the slice to avoid copying.\n//\n// Warning: the string returned by the function should be used with care, as the whole input data\n// chunk may be either blocked from being freed by GC because of a single string or the buffer.Data\n// may be garbage-collected even when the string exists.\nfunc bytesToStr(data []byte) string {\n\th := (*reflect.SliceHeader)(unsafe.Pointer(&data))\n\tshdr := reflect.StringHeader{Data: h.Data, Len: h.Len}\n\treturn *(*string)(unsafe.Pointer(&shdr))\n}\n"
  },
  {
    "path": "vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go",
    "content": "// This file is included to the build if any of the buildtags below\n// are defined. Refer to README notes for more details.\n\n//+build easyjson_nounsafe appengine\n\npackage jlexer\n\n// bytesToStr creates a string normally from []byte\n//\n// Note that this method is roughly 1.5x slower than using the 'unsafe' method.\nfunc bytesToStr(data []byte) string {\n\treturn string(data)\n}\n"
  },
  {
    "path": "vendor/github.com/mailru/easyjson/jlexer/error.go",
    "content": "package jlexer\n\nimport \"fmt\"\n\n// LexerError implements the error interface and represents all possible errors that can be\n// generated during parsing the JSON data.\ntype LexerError struct {\n\tReason string\n\tOffset int\n\tData   string\n}\n\nfunc (l *LexerError) Error() string {\n\treturn fmt.Sprintf(\"parse error: %s near offset %d of '%s'\", l.Reason, l.Offset, l.Data)\n}\n"
  },
  {
    "path": "vendor/github.com/mailru/easyjson/jlexer/lexer.go",
    "content": "// Package jlexer contains a JSON lexer implementation.\n//\n// It is expected that it is mostly used with generated parser code, so the interface is tuned\n// for a parser that knows what kind of data is expected.\npackage jlexer\n\nimport (\n\t\"bytes\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"unicode\"\n\t\"unicode/utf16\"\n\t\"unicode/utf8\"\n\n\t\"github.com/josharian/intern\"\n)\n\n// tokenKind determines type of a token.\ntype tokenKind byte\n\nconst (\n\ttokenUndef  tokenKind = iota // No token.\n\ttokenDelim                   // Delimiter: one of '{', '}', '[' or ']'.\n\ttokenString                  // A string literal, e.g. \"abc\\u1234\"\n\ttokenNumber                  // Number literal, e.g. 1.5e5\n\ttokenBool                    // Boolean literal: true or false.\n\ttokenNull                    // null keyword.\n)\n\n// token describes a single token: type, position in the input and value.\ntype token struct {\n\tkind tokenKind // Type of a token.\n\n\tboolValue       bool   // Value if a boolean literal token.\n\tbyteValueCloned bool   // true if byteValue was allocated and does not refer to original json body\n\tbyteValue       []byte // Raw value of a token.\n\tdelimValue      byte\n}\n\n// Lexer is a JSON lexer: it iterates over JSON tokens in a byte slice.\ntype Lexer struct {\n\tData []byte // Input data given to the lexer.\n\n\tstart int   // Start of the current token.\n\tpos   int   // Current unscanned position in the input stream.\n\ttoken token // Last scanned token, if token.kind != tokenUndef.\n\n\tfirstElement bool // Whether current element is the first in array or an object.\n\twantSep      byte // A comma or a colon character, which need to occur before a token.\n\n\tUseMultipleErrors bool          // If we want to use multiple errors.\n\tfatalError        error         // Fatal error occurred during lexing. It is usually a syntax error.\n\tmultipleErrors    []*LexerError // Semantic errors occurred during lexing. Marshalling will be continued after finding this errors.\n}\n\n// FetchToken scans the input for the next token.\nfunc (r *Lexer) FetchToken() {\n\tr.token.kind = tokenUndef\n\tr.start = r.pos\n\n\t// Check if r.Data has r.pos element\n\t// If it doesn't, it mean corrupted input data\n\tif len(r.Data) < r.pos {\n\t\tr.errParse(\"Unexpected end of data\")\n\t\treturn\n\t}\n\t// Determine the type of a token by skipping whitespace and reading the\n\t// first character.\n\tfor _, c := range r.Data[r.pos:] {\n\t\tswitch c {\n\t\tcase ':', ',':\n\t\t\tif r.wantSep == c {\n\t\t\t\tr.pos++\n\t\t\t\tr.start++\n\t\t\t\tr.wantSep = 0\n\t\t\t} else {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\n\t\tcase ' ', '\\t', '\\r', '\\n':\n\t\t\tr.pos++\n\t\t\tr.start++\n\n\t\tcase '\"':\n\t\t\tif r.wantSep != 0 {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\n\t\t\tr.token.kind = tokenString\n\t\t\tr.fetchString()\n\t\t\treturn\n\n\t\tcase '{', '[':\n\t\t\tif r.wantSep != 0 {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\t\t\tr.firstElement = true\n\t\t\tr.token.kind = tokenDelim\n\t\t\tr.token.delimValue = r.Data[r.pos]\n\t\t\tr.pos++\n\t\t\treturn\n\n\t\tcase '}', ']':\n\t\t\tif !r.firstElement && (r.wantSep != ',') {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\t\t\tr.wantSep = 0\n\t\t\tr.token.kind = tokenDelim\n\t\t\tr.token.delimValue = r.Data[r.pos]\n\t\t\tr.pos++\n\t\t\treturn\n\n\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-':\n\t\t\tif r.wantSep != 0 {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\t\t\tr.token.kind = tokenNumber\n\t\t\tr.fetchNumber()\n\t\t\treturn\n\n\t\tcase 'n':\n\t\t\tif r.wantSep != 0 {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\n\t\t\tr.token.kind = tokenNull\n\t\t\tr.fetchNull()\n\t\t\treturn\n\n\t\tcase 't':\n\t\t\tif r.wantSep != 0 {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\n\t\t\tr.token.kind = tokenBool\n\t\t\tr.token.boolValue = true\n\t\t\tr.fetchTrue()\n\t\t\treturn\n\n\t\tcase 'f':\n\t\t\tif r.wantSep != 0 {\n\t\t\t\tr.errSyntax()\n\t\t\t}\n\n\t\t\tr.token.kind = tokenBool\n\t\t\tr.token.boolValue = false\n\t\t\tr.fetchFalse()\n\t\t\treturn\n\n\t\tdefault:\n\t\t\tr.errSyntax()\n\t\t\treturn\n\t\t}\n\t}\n\tr.fatalError = io.EOF\n\treturn\n}\n\n// isTokenEnd returns true if the char can follow a non-delimiter token\nfunc isTokenEnd(c byte) bool {\n\treturn c == ' ' || c == '\\t' || c == '\\r' || c == '\\n' || c == '[' || c == ']' || c == '{' || c == '}' || c == ',' || c == ':'\n}\n\n// fetchNull fetches and checks remaining bytes of null keyword.\nfunc (r *Lexer) fetchNull() {\n\tr.pos += 4\n\tif r.pos > len(r.Data) ||\n\t\tr.Data[r.pos-3] != 'u' ||\n\t\tr.Data[r.pos-2] != 'l' ||\n\t\tr.Data[r.pos-1] != 'l' ||\n\t\t(r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) {\n\n\t\tr.pos -= 4\n\t\tr.errSyntax()\n\t}\n}\n\n// fetchTrue fetches and checks remaining bytes of true keyword.\nfunc (r *Lexer) fetchTrue() {\n\tr.pos += 4\n\tif r.pos > len(r.Data) ||\n\t\tr.Data[r.pos-3] != 'r' ||\n\t\tr.Data[r.pos-2] != 'u' ||\n\t\tr.Data[r.pos-1] != 'e' ||\n\t\t(r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) {\n\n\t\tr.pos -= 4\n\t\tr.errSyntax()\n\t}\n}\n\n// fetchFalse fetches and checks remaining bytes of false keyword.\nfunc (r *Lexer) fetchFalse() {\n\tr.pos += 5\n\tif r.pos > len(r.Data) ||\n\t\tr.Data[r.pos-4] != 'a' ||\n\t\tr.Data[r.pos-3] != 'l' ||\n\t\tr.Data[r.pos-2] != 's' ||\n\t\tr.Data[r.pos-1] != 'e' ||\n\t\t(r.pos != len(r.Data) && !isTokenEnd(r.Data[r.pos])) {\n\n\t\tr.pos -= 5\n\t\tr.errSyntax()\n\t}\n}\n\n// fetchNumber scans a number literal token.\nfunc (r *Lexer) fetchNumber() {\n\thasE := false\n\tafterE := false\n\thasDot := false\n\n\tr.pos++\n\tfor i, c := range r.Data[r.pos:] {\n\t\tswitch {\n\t\tcase c >= '0' && c <= '9':\n\t\t\tafterE = false\n\t\tcase c == '.' && !hasDot:\n\t\t\thasDot = true\n\t\tcase (c == 'e' || c == 'E') && !hasE:\n\t\t\thasE = true\n\t\t\thasDot = true\n\t\t\tafterE = true\n\t\tcase (c == '+' || c == '-') && afterE:\n\t\t\tafterE = false\n\t\tdefault:\n\t\t\tr.pos += i\n\t\t\tif !isTokenEnd(c) {\n\t\t\t\tr.errSyntax()\n\t\t\t} else {\n\t\t\t\tr.token.byteValue = r.Data[r.start:r.pos]\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n\n\tr.pos = len(r.Data)\n\tr.token.byteValue = r.Data[r.start:]\n}\n\n// findStringLen tries to scan into the string literal for ending quote char to determine required size.\n// The size will be exact if no escapes are present and may be inexact if there are escaped chars.\nfunc findStringLen(data []byte) (isValid bool, length int) {\n\tfor {\n\t\tidx := bytes.IndexByte(data, '\"')\n\t\tif idx == -1 {\n\t\t\treturn false, len(data)\n\t\t}\n\t\tif idx == 0 || (idx > 0 && data[idx-1] != '\\\\') {\n\t\t\treturn true, length + idx\n\t\t}\n\n\t\t// count \\\\\\\\\\\\\\ sequences. even number of slashes means quote is not really escaped\n\t\tcnt := 1\n\t\tfor idx-cnt-1 >= 0 && data[idx-cnt-1] == '\\\\' {\n\t\t\tcnt++\n\t\t}\n\t\tif cnt%2 == 0 {\n\t\t\treturn true, length + idx\n\t\t}\n\n\t\tlength += idx + 1\n\t\tdata = data[idx+1:]\n\t}\n}\n\n// unescapeStringToken performs unescaping of string token.\n// if no escaping is needed, original string is returned, otherwise - a new one allocated\nfunc (r *Lexer) unescapeStringToken() (err error) {\n\tdata := r.token.byteValue\n\tvar unescapedData []byte\n\n\tfor {\n\t\ti := bytes.IndexByte(data, '\\\\')\n\t\tif i == -1 {\n\t\t\tbreak\n\t\t}\n\n\t\tescapedRune, escapedBytes, err := decodeEscape(data[i:])\n\t\tif err != nil {\n\t\t\tr.errParse(err.Error())\n\t\t\treturn err\n\t\t}\n\n\t\tif unescapedData == nil {\n\t\t\tunescapedData = make([]byte, 0, len(r.token.byteValue))\n\t\t}\n\n\t\tvar d [4]byte\n\t\ts := utf8.EncodeRune(d[:], escapedRune)\n\t\tunescapedData = append(unescapedData, data[:i]...)\n\t\tunescapedData = append(unescapedData, d[:s]...)\n\n\t\tdata = data[i+escapedBytes:]\n\t}\n\n\tif unescapedData != nil {\n\t\tr.token.byteValue = append(unescapedData, data...)\n\t\tr.token.byteValueCloned = true\n\t}\n\treturn\n}\n\n// getu4 decodes \\uXXXX from the beginning of s, returning the hex value,\n// or it returns -1.\nfunc getu4(s []byte) rune {\n\tif len(s) < 6 || s[0] != '\\\\' || s[1] != 'u' {\n\t\treturn -1\n\t}\n\tvar val rune\n\tfor i := 2; i < len(s) && i < 6; i++ {\n\t\tvar v byte\n\t\tc := s[i]\n\t\tswitch c {\n\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\t\tv = c - '0'\n\t\tcase 'a', 'b', 'c', 'd', 'e', 'f':\n\t\t\tv = c - 'a' + 10\n\t\tcase 'A', 'B', 'C', 'D', 'E', 'F':\n\t\t\tv = c - 'A' + 10\n\t\tdefault:\n\t\t\treturn -1\n\t\t}\n\n\t\tval <<= 4\n\t\tval |= rune(v)\n\t}\n\treturn val\n}\n\n// decodeEscape processes a single escape sequence and returns number of bytes processed.\nfunc decodeEscape(data []byte) (decoded rune, bytesProcessed int, err error) {\n\tif len(data) < 2 {\n\t\treturn 0, 0, errors.New(\"incorrect escape symbol \\\\ at the end of token\")\n\t}\n\n\tc := data[1]\n\tswitch c {\n\tcase '\"', '/', '\\\\':\n\t\treturn rune(c), 2, nil\n\tcase 'b':\n\t\treturn '\\b', 2, nil\n\tcase 'f':\n\t\treturn '\\f', 2, nil\n\tcase 'n':\n\t\treturn '\\n', 2, nil\n\tcase 'r':\n\t\treturn '\\r', 2, nil\n\tcase 't':\n\t\treturn '\\t', 2, nil\n\tcase 'u':\n\t\trr := getu4(data)\n\t\tif rr < 0 {\n\t\t\treturn 0, 0, errors.New(\"incorrectly escaped \\\\uXXXX sequence\")\n\t\t}\n\n\t\tread := 6\n\t\tif utf16.IsSurrogate(rr) {\n\t\t\trr1 := getu4(data[read:])\n\t\t\tif dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {\n\t\t\t\tread += 6\n\t\t\t\trr = dec\n\t\t\t} else {\n\t\t\t\trr = unicode.ReplacementChar\n\t\t\t}\n\t\t}\n\t\treturn rr, read, nil\n\t}\n\n\treturn 0, 0, errors.New(\"incorrectly escaped bytes\")\n}\n\n// fetchString scans a string literal token.\nfunc (r *Lexer) fetchString() {\n\tr.pos++\n\tdata := r.Data[r.pos:]\n\n\tisValid, length := findStringLen(data)\n\tif !isValid {\n\t\tr.pos += length\n\t\tr.errParse(\"unterminated string literal\")\n\t\treturn\n\t}\n\tr.token.byteValue = data[:length]\n\tr.pos += length + 1 // skip closing '\"' as well\n}\n\n// scanToken scans the next token if no token is currently available in the lexer.\nfunc (r *Lexer) scanToken() {\n\tif r.token.kind != tokenUndef || r.fatalError != nil {\n\t\treturn\n\t}\n\n\tr.FetchToken()\n}\n\n// consume resets the current token to allow scanning the next one.\nfunc (r *Lexer) consume() {\n\tr.token.kind = tokenUndef\n\tr.token.byteValueCloned = false\n\tr.token.delimValue = 0\n}\n\n// Ok returns true if no error (including io.EOF) was encountered during scanning.\nfunc (r *Lexer) Ok() bool {\n\treturn r.fatalError == nil\n}\n\nconst maxErrorContextLen = 13\n\nfunc (r *Lexer) errParse(what string) {\n\tif r.fatalError == nil {\n\t\tvar str string\n\t\tif len(r.Data)-r.pos <= maxErrorContextLen {\n\t\t\tstr = string(r.Data)\n\t\t} else {\n\t\t\tstr = string(r.Data[r.pos:r.pos+maxErrorContextLen-3]) + \"...\"\n\t\t}\n\t\tr.fatalError = &LexerError{\n\t\t\tReason: what,\n\t\t\tOffset: r.pos,\n\t\t\tData:   str,\n\t\t}\n\t}\n}\n\nfunc (r *Lexer) errSyntax() {\n\tr.errParse(\"syntax error\")\n}\n\nfunc (r *Lexer) errInvalidToken(expected string) {\n\tif r.fatalError != nil {\n\t\treturn\n\t}\n\tif r.UseMultipleErrors {\n\t\tr.pos = r.start\n\t\tr.consume()\n\t\tr.SkipRecursive()\n\t\tswitch expected {\n\t\tcase \"[\":\n\t\t\tr.token.delimValue = ']'\n\t\t\tr.token.kind = tokenDelim\n\t\tcase \"{\":\n\t\t\tr.token.delimValue = '}'\n\t\t\tr.token.kind = tokenDelim\n\t\t}\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tReason: fmt.Sprintf(\"expected %s\", expected),\n\t\t\tOffset: r.start,\n\t\t\tData:   string(r.Data[r.start:r.pos]),\n\t\t})\n\t\treturn\n\t}\n\n\tvar str string\n\tif len(r.token.byteValue) <= maxErrorContextLen {\n\t\tstr = string(r.token.byteValue)\n\t} else {\n\t\tstr = string(r.token.byteValue[:maxErrorContextLen-3]) + \"...\"\n\t}\n\tr.fatalError = &LexerError{\n\t\tReason: fmt.Sprintf(\"expected %s\", expected),\n\t\tOffset: r.pos,\n\t\tData:   str,\n\t}\n}\n\nfunc (r *Lexer) GetPos() int {\n\treturn r.pos\n}\n\n// Delim consumes a token and verifies that it is the given delimiter.\nfunc (r *Lexer) Delim(c byte) {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\n\tif !r.Ok() || r.token.delimValue != c {\n\t\tr.consume() // errInvalidToken can change token if UseMultipleErrors is enabled.\n\t\tr.errInvalidToken(string([]byte{c}))\n\t} else {\n\t\tr.consume()\n\t}\n}\n\n// IsDelim returns true if there was no scanning error and next token is the given delimiter.\nfunc (r *Lexer) IsDelim(c byte) bool {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\treturn !r.Ok() || r.token.delimValue == c\n}\n\n// Null verifies that the next token is null and consumes it.\nfunc (r *Lexer) Null() {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() || r.token.kind != tokenNull {\n\t\tr.errInvalidToken(\"null\")\n\t}\n\tr.consume()\n}\n\n// IsNull returns true if the next token is a null keyword.\nfunc (r *Lexer) IsNull() bool {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\treturn r.Ok() && r.token.kind == tokenNull\n}\n\n// Skip skips a single token.\nfunc (r *Lexer) Skip() {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tr.consume()\n}\n\n// SkipRecursive skips next array or object completely, or just skips a single token if not\n// an array/object.\n//\n// Note: no syntax validation is performed on the skipped data.\nfunc (r *Lexer) SkipRecursive() {\n\tr.scanToken()\n\tvar start, end byte\n\tstartPos := r.start\n\n\tswitch r.token.delimValue {\n\tcase '{':\n\t\tstart, end = '{', '}'\n\tcase '[':\n\t\tstart, end = '[', ']'\n\tdefault:\n\t\tr.consume()\n\t\treturn\n\t}\n\n\tr.consume()\n\n\tlevel := 1\n\tinQuotes := false\n\twasEscape := false\n\n\tfor i, c := range r.Data[r.pos:] {\n\t\tswitch {\n\t\tcase c == start && !inQuotes:\n\t\t\tlevel++\n\t\tcase c == end && !inQuotes:\n\t\t\tlevel--\n\t\t\tif level == 0 {\n\t\t\t\tr.pos += i + 1\n\t\t\t\tif !json.Valid(r.Data[startPos:r.pos]) {\n\t\t\t\t\tr.pos = len(r.Data)\n\t\t\t\t\tr.fatalError = &LexerError{\n\t\t\t\t\t\tReason: \"skipped array/object json value is invalid\",\n\t\t\t\t\t\tOffset: r.pos,\n\t\t\t\t\t\tData:   string(r.Data[r.pos:]),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\tcase c == '\\\\' && inQuotes:\n\t\t\twasEscape = !wasEscape\n\t\t\tcontinue\n\t\tcase c == '\"' && inQuotes:\n\t\t\tinQuotes = wasEscape\n\t\tcase c == '\"':\n\t\t\tinQuotes = true\n\t\t}\n\t\twasEscape = false\n\t}\n\tr.pos = len(r.Data)\n\tr.fatalError = &LexerError{\n\t\tReason: \"EOF reached while skipping array/object or token\",\n\t\tOffset: r.pos,\n\t\tData:   string(r.Data[r.pos:]),\n\t}\n}\n\n// Raw fetches the next item recursively as a data slice\nfunc (r *Lexer) Raw() []byte {\n\tr.SkipRecursive()\n\tif !r.Ok() {\n\t\treturn nil\n\t}\n\treturn r.Data[r.start:r.pos]\n}\n\n// IsStart returns whether the lexer is positioned at the start\n// of an input string.\nfunc (r *Lexer) IsStart() bool {\n\treturn r.pos == 0\n}\n\n// Consumed reads all remaining bytes from the input, publishing an error if\n// there is anything but whitespace remaining.\nfunc (r *Lexer) Consumed() {\n\tif r.pos > len(r.Data) || !r.Ok() {\n\t\treturn\n\t}\n\n\tfor _, c := range r.Data[r.pos:] {\n\t\tif c != ' ' && c != '\\t' && c != '\\r' && c != '\\n' {\n\t\t\tr.AddError(&LexerError{\n\t\t\t\tReason: \"invalid character '\" + string(c) + \"' after top-level value\",\n\t\t\t\tOffset: r.pos,\n\t\t\t\tData:   string(r.Data[r.pos:]),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tr.pos++\n\t\tr.start++\n\t}\n}\n\nfunc (r *Lexer) unsafeString(skipUnescape bool) (string, []byte) {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() || r.token.kind != tokenString {\n\t\tr.errInvalidToken(\"string\")\n\t\treturn \"\", nil\n\t}\n\tif !skipUnescape {\n\t\tif err := r.unescapeStringToken(); err != nil {\n\t\t\tr.errInvalidToken(\"string\")\n\t\t\treturn \"\", nil\n\t\t}\n\t}\n\n\tbytes := r.token.byteValue\n\tret := bytesToStr(r.token.byteValue)\n\tr.consume()\n\treturn ret, bytes\n}\n\n// UnsafeString returns the string value if the token is a string literal.\n//\n// Warning: returned string may point to the input buffer, so the string should not outlive\n// the input buffer. Intended pattern of usage is as an argument to a switch statement.\nfunc (r *Lexer) UnsafeString() string {\n\tret, _ := r.unsafeString(false)\n\treturn ret\n}\n\n// UnsafeBytes returns the byte slice if the token is a string literal.\nfunc (r *Lexer) UnsafeBytes() []byte {\n\t_, ret := r.unsafeString(false)\n\treturn ret\n}\n\n// UnsafeFieldName returns current member name string token\nfunc (r *Lexer) UnsafeFieldName(skipUnescape bool) string {\n\tret, _ := r.unsafeString(skipUnescape)\n\treturn ret\n}\n\n// String reads a string literal.\nfunc (r *Lexer) String() string {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() || r.token.kind != tokenString {\n\t\tr.errInvalidToken(\"string\")\n\t\treturn \"\"\n\t}\n\tif err := r.unescapeStringToken(); err != nil {\n\t\tr.errInvalidToken(\"string\")\n\t\treturn \"\"\n\t}\n\tvar ret string\n\tif r.token.byteValueCloned {\n\t\tret = bytesToStr(r.token.byteValue)\n\t} else {\n\t\tret = string(r.token.byteValue)\n\t}\n\tr.consume()\n\treturn ret\n}\n\n// StringIntern reads a string literal, and performs string interning on it.\nfunc (r *Lexer) StringIntern() string {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() || r.token.kind != tokenString {\n\t\tr.errInvalidToken(\"string\")\n\t\treturn \"\"\n\t}\n\tif err := r.unescapeStringToken(); err != nil {\n\t\tr.errInvalidToken(\"string\")\n\t\treturn \"\"\n\t}\n\tret := intern.Bytes(r.token.byteValue)\n\tr.consume()\n\treturn ret\n}\n\n// Bytes reads a string literal and base64 decodes it into a byte slice.\nfunc (r *Lexer) Bytes() []byte {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() || r.token.kind != tokenString {\n\t\tr.errInvalidToken(\"string\")\n\t\treturn nil\n\t}\n\tif err := r.unescapeStringToken(); err != nil {\n\t\tr.errInvalidToken(\"string\")\n\t\treturn nil\n\t}\n\tret := make([]byte, base64.StdEncoding.DecodedLen(len(r.token.byteValue)))\n\tn, err := base64.StdEncoding.Decode(ret, r.token.byteValue)\n\tif err != nil {\n\t\tr.fatalError = &LexerError{\n\t\t\tReason: err.Error(),\n\t\t}\n\t\treturn nil\n\t}\n\n\tr.consume()\n\treturn ret[:n]\n}\n\n// Bool reads a true or false boolean keyword.\nfunc (r *Lexer) Bool() bool {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() || r.token.kind != tokenBool {\n\t\tr.errInvalidToken(\"bool\")\n\t\treturn false\n\t}\n\tret := r.token.boolValue\n\tr.consume()\n\treturn ret\n}\n\nfunc (r *Lexer) number() string {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() || r.token.kind != tokenNumber {\n\t\tr.errInvalidToken(\"number\")\n\t\treturn \"\"\n\t}\n\tret := bytesToStr(r.token.byteValue)\n\tr.consume()\n\treturn ret\n}\n\nfunc (r *Lexer) Uint8() uint8 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 8)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn uint8(n)\n}\n\nfunc (r *Lexer) Uint16() uint16 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 16)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn uint16(n)\n}\n\nfunc (r *Lexer) Uint32() uint32 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 32)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn uint32(n)\n}\n\nfunc (r *Lexer) Uint64() uint64 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 64)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn n\n}\n\nfunc (r *Lexer) Uint() uint {\n\treturn uint(r.Uint64())\n}\n\nfunc (r *Lexer) Int8() int8 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 8)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn int8(n)\n}\n\nfunc (r *Lexer) Int16() int16 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 16)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn int16(n)\n}\n\nfunc (r *Lexer) Int32() int32 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 32)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn int32(n)\n}\n\nfunc (r *Lexer) Int64() int64 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 64)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn n\n}\n\nfunc (r *Lexer) Int() int {\n\treturn int(r.Int64())\n}\n\nfunc (r *Lexer) Uint8Str() uint8 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 8)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn uint8(n)\n}\n\nfunc (r *Lexer) Uint16Str() uint16 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 16)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn uint16(n)\n}\n\nfunc (r *Lexer) Uint32Str() uint32 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 32)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn uint32(n)\n}\n\nfunc (r *Lexer) Uint64Str() uint64 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseUint(s, 10, 64)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn n\n}\n\nfunc (r *Lexer) UintStr() uint {\n\treturn uint(r.Uint64Str())\n}\n\nfunc (r *Lexer) UintptrStr() uintptr {\n\treturn uintptr(r.Uint64Str())\n}\n\nfunc (r *Lexer) Int8Str() int8 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 8)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn int8(n)\n}\n\nfunc (r *Lexer) Int16Str() int16 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 16)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn int16(n)\n}\n\nfunc (r *Lexer) Int32Str() int32 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 32)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn int32(n)\n}\n\nfunc (r *Lexer) Int64Str() int64 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseInt(s, 10, 64)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn n\n}\n\nfunc (r *Lexer) IntStr() int {\n\treturn int(r.Int64Str())\n}\n\nfunc (r *Lexer) Float32() float32 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseFloat(s, 32)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn float32(n)\n}\n\nfunc (r *Lexer) Float32Str() float32 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\tn, err := strconv.ParseFloat(s, 32)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn float32(n)\n}\n\nfunc (r *Lexer) Float64() float64 {\n\ts := r.number()\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\n\tn, err := strconv.ParseFloat(s, 64)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   s,\n\t\t})\n\t}\n\treturn n\n}\n\nfunc (r *Lexer) Float64Str() float64 {\n\ts, b := r.unsafeString(false)\n\tif !r.Ok() {\n\t\treturn 0\n\t}\n\tn, err := strconv.ParseFloat(s, 64)\n\tif err != nil {\n\t\tr.addNonfatalError(&LexerError{\n\t\t\tOffset: r.start,\n\t\t\tReason: err.Error(),\n\t\t\tData:   string(b),\n\t\t})\n\t}\n\treturn n\n}\n\nfunc (r *Lexer) Error() error {\n\treturn r.fatalError\n}\n\nfunc (r *Lexer) AddError(e error) {\n\tif r.fatalError == nil {\n\t\tr.fatalError = e\n\t}\n}\n\nfunc (r *Lexer) AddNonFatalError(e error) {\n\tr.addNonfatalError(&LexerError{\n\t\tOffset: r.start,\n\t\tData:   string(r.Data[r.start:r.pos]),\n\t\tReason: e.Error(),\n\t})\n}\n\nfunc (r *Lexer) addNonfatalError(err *LexerError) {\n\tif r.UseMultipleErrors {\n\t\t// We don't want to add errors with the same offset.\n\t\tif len(r.multipleErrors) != 0 && r.multipleErrors[len(r.multipleErrors)-1].Offset == err.Offset {\n\t\t\treturn\n\t\t}\n\t\tr.multipleErrors = append(r.multipleErrors, err)\n\t\treturn\n\t}\n\tr.fatalError = err\n}\n\nfunc (r *Lexer) GetNonFatalErrors() []*LexerError {\n\treturn r.multipleErrors\n}\n\n// JsonNumber fetches and json.Number from 'encoding/json' package.\n// Both int, float or string, contains them are valid values\nfunc (r *Lexer) JsonNumber() json.Number {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\tif !r.Ok() {\n\t\tr.errInvalidToken(\"json.Number\")\n\t\treturn json.Number(\"\")\n\t}\n\n\tswitch r.token.kind {\n\tcase tokenString:\n\t\treturn json.Number(r.String())\n\tcase tokenNumber:\n\t\treturn json.Number(r.Raw())\n\tcase tokenNull:\n\t\tr.Null()\n\t\treturn json.Number(\"\")\n\tdefault:\n\t\tr.errSyntax()\n\t\treturn json.Number(\"\")\n\t}\n}\n\n// Interface fetches an interface{} analogous to the 'encoding/json' package.\nfunc (r *Lexer) Interface() interface{} {\n\tif r.token.kind == tokenUndef && r.Ok() {\n\t\tr.FetchToken()\n\t}\n\n\tif !r.Ok() {\n\t\treturn nil\n\t}\n\tswitch r.token.kind {\n\tcase tokenString:\n\t\treturn r.String()\n\tcase tokenNumber:\n\t\treturn r.Float64()\n\tcase tokenBool:\n\t\treturn r.Bool()\n\tcase tokenNull:\n\t\tr.Null()\n\t\treturn nil\n\t}\n\n\tif r.token.delimValue == '{' {\n\t\tr.consume()\n\n\t\tret := map[string]interface{}{}\n\t\tfor !r.IsDelim('}') {\n\t\t\tkey := r.String()\n\t\t\tr.WantColon()\n\t\t\tret[key] = r.Interface()\n\t\t\tr.WantComma()\n\t\t}\n\t\tr.Delim('}')\n\n\t\tif r.Ok() {\n\t\t\treturn ret\n\t\t} else {\n\t\t\treturn nil\n\t\t}\n\t} else if r.token.delimValue == '[' {\n\t\tr.consume()\n\n\t\tret := []interface{}{}\n\t\tfor !r.IsDelim(']') {\n\t\t\tret = append(ret, r.Interface())\n\t\t\tr.WantComma()\n\t\t}\n\t\tr.Delim(']')\n\n\t\tif r.Ok() {\n\t\t\treturn ret\n\t\t} else {\n\t\t\treturn nil\n\t\t}\n\t}\n\tr.errSyntax()\n\treturn nil\n}\n\n// WantComma requires a comma to be present before fetching next token.\nfunc (r *Lexer) WantComma() {\n\tr.wantSep = ','\n\tr.firstElement = false\n}\n\n// WantColon requires a colon to be present before fetching next token.\nfunc (r *Lexer) WantColon() {\n\tr.wantSep = ':'\n\tr.firstElement = false\n}\n"
  },
  {
    "path": "vendor/github.com/mailru/easyjson/jwriter/writer.go",
    "content": "// Package jwriter contains a JSON writer.\npackage jwriter\n\nimport (\n\t\"io\"\n\t\"strconv\"\n\t\"unicode/utf8\"\n\n\t\"github.com/mailru/easyjson/buffer\"\n)\n\n// Flags describe various encoding options. The behavior may be actually implemented in the encoder, but\n// Flags field in Writer is used to set and pass them around.\ntype Flags int\n\nconst (\n\tNilMapAsEmpty   Flags = 1 << iota // Encode nil map as '{}' rather than 'null'.\n\tNilSliceAsEmpty                   // Encode nil slice as '[]' rather than 'null'.\n)\n\n// Writer is a JSON writer.\ntype Writer struct {\n\tFlags Flags\n\n\tError        error\n\tBuffer       buffer.Buffer\n\tNoEscapeHTML bool\n}\n\n// Size returns the size of the data that was written out.\nfunc (w *Writer) Size() int {\n\treturn w.Buffer.Size()\n}\n\n// DumpTo outputs the data to given io.Writer, resetting the buffer.\nfunc (w *Writer) DumpTo(out io.Writer) (written int, err error) {\n\treturn w.Buffer.DumpTo(out)\n}\n\n// BuildBytes returns writer data as a single byte slice. You can optionally provide one byte slice\n// as argument that it will try to reuse.\nfunc (w *Writer) BuildBytes(reuse ...[]byte) ([]byte, error) {\n\tif w.Error != nil {\n\t\treturn nil, w.Error\n\t}\n\n\treturn w.Buffer.BuildBytes(reuse...), nil\n}\n\n// ReadCloser returns an io.ReadCloser that can be used to read the data.\n// ReadCloser also resets the buffer.\nfunc (w *Writer) ReadCloser() (io.ReadCloser, error) {\n\tif w.Error != nil {\n\t\treturn nil, w.Error\n\t}\n\n\treturn w.Buffer.ReadCloser(), nil\n}\n\n// RawByte appends raw binary data to the buffer.\nfunc (w *Writer) RawByte(c byte) {\n\tw.Buffer.AppendByte(c)\n}\n\n// RawByte appends raw binary data to the buffer.\nfunc (w *Writer) RawString(s string) {\n\tw.Buffer.AppendString(s)\n}\n\n// Raw appends raw binary data to the buffer or sets the error if it is given. Useful for\n// calling with results of MarshalJSON-like functions.\nfunc (w *Writer) Raw(data []byte, err error) {\n\tswitch {\n\tcase w.Error != nil:\n\t\treturn\n\tcase err != nil:\n\t\tw.Error = err\n\tcase len(data) > 0:\n\t\tw.Buffer.AppendBytes(data)\n\tdefault:\n\t\tw.RawString(\"null\")\n\t}\n}\n\n// RawText encloses raw binary data in quotes and appends in to the buffer.\n// Useful for calling with results of MarshalText-like functions.\nfunc (w *Writer) RawText(data []byte, err error) {\n\tswitch {\n\tcase w.Error != nil:\n\t\treturn\n\tcase err != nil:\n\t\tw.Error = err\n\tcase len(data) > 0:\n\t\tw.String(string(data))\n\tdefault:\n\t\tw.RawString(\"null\")\n\t}\n}\n\n// Base64Bytes appends data to the buffer after base64 encoding it\nfunc (w *Writer) Base64Bytes(data []byte) {\n\tif data == nil {\n\t\tw.Buffer.AppendString(\"null\")\n\t\treturn\n\t}\n\tw.Buffer.AppendByte('\"')\n\tw.base64(data)\n\tw.Buffer.AppendByte('\"')\n}\n\nfunc (w *Writer) Uint8(n uint8) {\n\tw.Buffer.EnsureSpace(3)\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n}\n\nfunc (w *Writer) Uint16(n uint16) {\n\tw.Buffer.EnsureSpace(5)\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n}\n\nfunc (w *Writer) Uint32(n uint32) {\n\tw.Buffer.EnsureSpace(10)\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n}\n\nfunc (w *Writer) Uint(n uint) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n}\n\nfunc (w *Writer) Uint64(n uint64) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10)\n}\n\nfunc (w *Writer) Int8(n int8) {\n\tw.Buffer.EnsureSpace(4)\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n}\n\nfunc (w *Writer) Int16(n int16) {\n\tw.Buffer.EnsureSpace(6)\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n}\n\nfunc (w *Writer) Int32(n int32) {\n\tw.Buffer.EnsureSpace(11)\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n}\n\nfunc (w *Writer) Int(n int) {\n\tw.Buffer.EnsureSpace(21)\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n}\n\nfunc (w *Writer) Int64(n int64) {\n\tw.Buffer.EnsureSpace(21)\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10)\n}\n\nfunc (w *Writer) Uint8Str(n uint8) {\n\tw.Buffer.EnsureSpace(3)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Uint16Str(n uint16) {\n\tw.Buffer.EnsureSpace(5)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Uint32Str(n uint32) {\n\tw.Buffer.EnsureSpace(10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) UintStr(n uint) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Uint64Str(n uint64) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, n, 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) UintptrStr(n uintptr) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendUint(w.Buffer.Buf, uint64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Int8Str(n int8) {\n\tw.Buffer.EnsureSpace(4)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Int16Str(n int16) {\n\tw.Buffer.EnsureSpace(6)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Int32Str(n int32) {\n\tw.Buffer.EnsureSpace(11)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) IntStr(n int) {\n\tw.Buffer.EnsureSpace(21)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, int64(n), 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Int64Str(n int64) {\n\tw.Buffer.EnsureSpace(21)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendInt(w.Buffer.Buf, n, 10)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Float32(n float32) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)\n}\n\nfunc (w *Writer) Float32Str(n float32) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Float64(n float64) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, 'g', -1, 64)\n}\n\nfunc (w *Writer) Float64Str(n float64) {\n\tw.Buffer.EnsureSpace(20)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n\tw.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 64)\n\tw.Buffer.Buf = append(w.Buffer.Buf, '\"')\n}\n\nfunc (w *Writer) Bool(v bool) {\n\tw.Buffer.EnsureSpace(5)\n\tif v {\n\t\tw.Buffer.Buf = append(w.Buffer.Buf, \"true\"...)\n\t} else {\n\t\tw.Buffer.Buf = append(w.Buffer.Buf, \"false\"...)\n\t}\n}\n\nconst chars = \"0123456789abcdef\"\n\nfunc getTable(falseValues ...int) [128]bool {\n\ttable := [128]bool{}\n\n\tfor i := 0; i < 128; i++ {\n\t\ttable[i] = true\n\t}\n\n\tfor _, v := range falseValues {\n\t\ttable[v] = false\n\t}\n\n\treturn table\n}\n\nvar (\n\thtmlEscapeTable   = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '\"', '&', '<', '>', '\\\\')\n\thtmlNoEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '\"', '\\\\')\n)\n\nfunc (w *Writer) String(s string) {\n\tw.Buffer.AppendByte('\"')\n\n\t// Portions of the string that contain no escapes are appended as\n\t// byte slices.\n\n\tp := 0 // last non-escape symbol\n\n\tescapeTable := &htmlEscapeTable\n\tif w.NoEscapeHTML {\n\t\tescapeTable = &htmlNoEscapeTable\n\t}\n\n\tfor i := 0; i < len(s); {\n\t\tc := s[i]\n\n\t\tif c < utf8.RuneSelf {\n\t\t\tif escapeTable[c] {\n\t\t\t\t// single-width character, no escaping is required\n\t\t\t\ti++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tw.Buffer.AppendString(s[p:i])\n\t\t\tswitch c {\n\t\t\tcase '\\t':\n\t\t\t\tw.Buffer.AppendString(`\\t`)\n\t\t\tcase '\\r':\n\t\t\t\tw.Buffer.AppendString(`\\r`)\n\t\t\tcase '\\n':\n\t\t\t\tw.Buffer.AppendString(`\\n`)\n\t\t\tcase '\\\\':\n\t\t\t\tw.Buffer.AppendString(`\\\\`)\n\t\t\tcase '\"':\n\t\t\t\tw.Buffer.AppendString(`\\\"`)\n\t\t\tdefault:\n\t\t\t\tw.Buffer.AppendString(`\\u00`)\n\t\t\t\tw.Buffer.AppendByte(chars[c>>4])\n\t\t\t\tw.Buffer.AppendByte(chars[c&0xf])\n\t\t\t}\n\n\t\t\ti++\n\t\t\tp = i\n\t\t\tcontinue\n\t\t}\n\n\t\t// broken utf\n\t\truneValue, runeWidth := utf8.DecodeRuneInString(s[i:])\n\t\tif runeValue == utf8.RuneError && runeWidth == 1 {\n\t\t\tw.Buffer.AppendString(s[p:i])\n\t\t\tw.Buffer.AppendString(`\\ufffd`)\n\t\t\ti++\n\t\t\tp = i\n\t\t\tcontinue\n\t\t}\n\n\t\t// jsonp stuff - tab separator and line separator\n\t\tif runeValue == '\\u2028' || runeValue == '\\u2029' {\n\t\t\tw.Buffer.AppendString(s[p:i])\n\t\t\tw.Buffer.AppendString(`\\u202`)\n\t\t\tw.Buffer.AppendByte(chars[runeValue&0xf])\n\t\t\ti += runeWidth\n\t\t\tp = i\n\t\t\tcontinue\n\t\t}\n\t\ti += runeWidth\n\t}\n\tw.Buffer.AppendString(s[p:])\n\tw.Buffer.AppendByte('\"')\n}\n\nconst encode = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\nconst padChar = '='\n\nfunc (w *Writer) base64(in []byte) {\n\n\tif len(in) == 0 {\n\t\treturn\n\t}\n\n\tw.Buffer.EnsureSpace(((len(in)-1)/3 + 1) * 4)\n\n\tsi := 0\n\tn := (len(in) / 3) * 3\n\n\tfor si < n {\n\t\t// Convert 3x 8bit source bytes into 4 bytes\n\t\tval := uint(in[si+0])<<16 | uint(in[si+1])<<8 | uint(in[si+2])\n\n\t\tw.Buffer.Buf = append(w.Buffer.Buf, encode[val>>18&0x3F], encode[val>>12&0x3F], encode[val>>6&0x3F], encode[val&0x3F])\n\n\t\tsi += 3\n\t}\n\n\tremain := len(in) - si\n\tif remain == 0 {\n\t\treturn\n\t}\n\n\t// Add the remaining small block\n\tval := uint(in[si+0]) << 16\n\tif remain == 2 {\n\t\tval |= uint(in[si+1]) << 8\n\t}\n\n\tw.Buffer.Buf = append(w.Buffer.Buf, encode[val>>18&0x3F], encode[val>>12&0x3F])\n\n\tswitch remain {\n\tcase 2:\n\t\tw.Buffer.Buf = append(w.Buffer.Buf, encode[val>>6&0x3F], byte(padChar))\n\tcase 1:\n\t\tw.Buffer.Buf = append(w.Buffer.Buf, byte(padChar), byte(padChar))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Yasuhiro Matsumoto\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": "vendor/github.com/mattn/go-colorable/README.md",
    "content": "# go-colorable\n\n[![Build Status](https://github.com/mattn/go-colorable/workflows/test/badge.svg)](https://github.com/mattn/go-colorable/actions?query=workflow%3Atest)\n[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable)\n[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable)\n[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable)\n\nColorable writer for windows.\n\nFor example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.)\nThis package is possible to handle escape sequence for ansi color on windows.\n\n## Too Bad!\n\n![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png)\n\n\n## So Good!\n\n![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png)\n\n## Usage\n\n```go\nlogrus.SetFormatter(&logrus.TextFormatter{ForceColors: true})\nlogrus.SetOutput(colorable.NewColorableStdout())\n\nlogrus.Info(\"succeeded\")\nlogrus.Warn(\"not correct\")\nlogrus.Error(\"something error\")\nlogrus.Fatal(\"panic\")\n```\n\nYou can compile above code on non-windows OSs.\n\n## Installation\n\n```\n$ go get github.com/mattn/go-colorable\n```\n\n# License\n\nMIT\n\n# Author\n\nYasuhiro Matsumoto (a.k.a mattn)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/colorable_appengine.go",
    "content": "//go:build appengine\n// +build appengine\n\npackage colorable\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t_ \"github.com/mattn/go-isatty\"\n)\n\n// NewColorable returns new instance of Writer which handles escape sequence.\nfunc NewColorable(file *os.File) io.Writer {\n\tif file == nil {\n\t\tpanic(\"nil passed instead of *os.File to NewColorable()\")\n\t}\n\n\treturn file\n}\n\n// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.\nfunc NewColorableStdout() io.Writer {\n\treturn os.Stdout\n}\n\n// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.\nfunc NewColorableStderr() io.Writer {\n\treturn os.Stderr\n}\n\n// EnableColorsStdout enable colors if possible.\nfunc EnableColorsStdout(enabled *bool) func() {\n\tif enabled != nil {\n\t\t*enabled = true\n\t}\n\treturn func() {}\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/colorable_others.go",
    "content": "//go:build !windows && !appengine\n// +build !windows,!appengine\n\npackage colorable\n\nimport (\n\t\"io\"\n\t\"os\"\n\n\t_ \"github.com/mattn/go-isatty\"\n)\n\n// NewColorable returns new instance of Writer which handles escape sequence.\nfunc NewColorable(file *os.File) io.Writer {\n\tif file == nil {\n\t\tpanic(\"nil passed instead of *os.File to NewColorable()\")\n\t}\n\n\treturn file\n}\n\n// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.\nfunc NewColorableStdout() io.Writer {\n\treturn os.Stdout\n}\n\n// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.\nfunc NewColorableStderr() io.Writer {\n\treturn os.Stderr\n}\n\n// EnableColorsStdout enable colors if possible.\nfunc EnableColorsStdout(enabled *bool) func() {\n\tif enabled != nil {\n\t\t*enabled = true\n\t}\n\treturn func() {}\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/colorable_windows.go",
    "content": "//go:build windows && !appengine\n// +build windows,!appengine\n\npackage colorable\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"math\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/mattn/go-isatty\"\n)\n\nconst (\n\tforegroundBlue      = 0x1\n\tforegroundGreen     = 0x2\n\tforegroundRed       = 0x4\n\tforegroundIntensity = 0x8\n\tforegroundMask      = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity)\n\tbackgroundBlue      = 0x10\n\tbackgroundGreen     = 0x20\n\tbackgroundRed       = 0x40\n\tbackgroundIntensity = 0x80\n\tbackgroundMask      = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)\n\tcommonLvbUnderscore = 0x8000\n\n\tcENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4\n)\n\nconst (\n\tgenericRead  = 0x80000000\n\tgenericWrite = 0x40000000\n)\n\nconst (\n\tconsoleTextmodeBuffer = 0x1\n)\n\ntype wchar uint16\ntype short int16\ntype dword uint32\ntype word uint16\n\ntype coord struct {\n\tx short\n\ty short\n}\n\ntype smallRect struct {\n\tleft   short\n\ttop    short\n\tright  short\n\tbottom short\n}\n\ntype consoleScreenBufferInfo struct {\n\tsize              coord\n\tcursorPosition    coord\n\tattributes        word\n\twindow            smallRect\n\tmaximumWindowSize coord\n}\n\ntype consoleCursorInfo struct {\n\tsize    dword\n\tvisible int32\n}\n\nvar (\n\tkernel32                       = syscall.NewLazyDLL(\"kernel32.dll\")\n\tprocGetConsoleScreenBufferInfo = kernel32.NewProc(\"GetConsoleScreenBufferInfo\")\n\tprocSetConsoleTextAttribute    = kernel32.NewProc(\"SetConsoleTextAttribute\")\n\tprocSetConsoleCursorPosition   = kernel32.NewProc(\"SetConsoleCursorPosition\")\n\tprocFillConsoleOutputCharacter = kernel32.NewProc(\"FillConsoleOutputCharacterW\")\n\tprocFillConsoleOutputAttribute = kernel32.NewProc(\"FillConsoleOutputAttribute\")\n\tprocGetConsoleCursorInfo       = kernel32.NewProc(\"GetConsoleCursorInfo\")\n\tprocSetConsoleCursorInfo       = kernel32.NewProc(\"SetConsoleCursorInfo\")\n\tprocSetConsoleTitle            = kernel32.NewProc(\"SetConsoleTitleW\")\n\tprocGetConsoleMode             = kernel32.NewProc(\"GetConsoleMode\")\n\tprocSetConsoleMode             = kernel32.NewProc(\"SetConsoleMode\")\n\tprocCreateConsoleScreenBuffer  = kernel32.NewProc(\"CreateConsoleScreenBuffer\")\n)\n\n// Writer provides colorable Writer to the console\ntype Writer struct {\n\tout       io.Writer\n\thandle    syscall.Handle\n\talthandle syscall.Handle\n\toldattr   word\n\toldpos    coord\n\trest      bytes.Buffer\n\tmutex     sync.Mutex\n}\n\n// NewColorable returns new instance of Writer which handles escape sequence from File.\nfunc NewColorable(file *os.File) io.Writer {\n\tif file == nil {\n\t\tpanic(\"nil passed instead of *os.File to NewColorable()\")\n\t}\n\n\tif isatty.IsTerminal(file.Fd()) {\n\t\tvar mode uint32\n\t\tif r, _, _ := procGetConsoleMode.Call(file.Fd(), uintptr(unsafe.Pointer(&mode))); r != 0 && mode&cENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 {\n\t\t\treturn file\n\t\t}\n\t\tvar csbi consoleScreenBufferInfo\n\t\thandle := syscall.Handle(file.Fd())\n\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\treturn &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}}\n\t}\n\treturn file\n}\n\n// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout.\nfunc NewColorableStdout() io.Writer {\n\treturn NewColorable(os.Stdout)\n}\n\n// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr.\nfunc NewColorableStderr() io.Writer {\n\treturn NewColorable(os.Stderr)\n}\n\nvar color256 = map[int]int{\n\t0:   0x000000,\n\t1:   0x800000,\n\t2:   0x008000,\n\t3:   0x808000,\n\t4:   0x000080,\n\t5:   0x800080,\n\t6:   0x008080,\n\t7:   0xc0c0c0,\n\t8:   0x808080,\n\t9:   0xff0000,\n\t10:  0x00ff00,\n\t11:  0xffff00,\n\t12:  0x0000ff,\n\t13:  0xff00ff,\n\t14:  0x00ffff,\n\t15:  0xffffff,\n\t16:  0x000000,\n\t17:  0x00005f,\n\t18:  0x000087,\n\t19:  0x0000af,\n\t20:  0x0000d7,\n\t21:  0x0000ff,\n\t22:  0x005f00,\n\t23:  0x005f5f,\n\t24:  0x005f87,\n\t25:  0x005faf,\n\t26:  0x005fd7,\n\t27:  0x005fff,\n\t28:  0x008700,\n\t29:  0x00875f,\n\t30:  0x008787,\n\t31:  0x0087af,\n\t32:  0x0087d7,\n\t33:  0x0087ff,\n\t34:  0x00af00,\n\t35:  0x00af5f,\n\t36:  0x00af87,\n\t37:  0x00afaf,\n\t38:  0x00afd7,\n\t39:  0x00afff,\n\t40:  0x00d700,\n\t41:  0x00d75f,\n\t42:  0x00d787,\n\t43:  0x00d7af,\n\t44:  0x00d7d7,\n\t45:  0x00d7ff,\n\t46:  0x00ff00,\n\t47:  0x00ff5f,\n\t48:  0x00ff87,\n\t49:  0x00ffaf,\n\t50:  0x00ffd7,\n\t51:  0x00ffff,\n\t52:  0x5f0000,\n\t53:  0x5f005f,\n\t54:  0x5f0087,\n\t55:  0x5f00af,\n\t56:  0x5f00d7,\n\t57:  0x5f00ff,\n\t58:  0x5f5f00,\n\t59:  0x5f5f5f,\n\t60:  0x5f5f87,\n\t61:  0x5f5faf,\n\t62:  0x5f5fd7,\n\t63:  0x5f5fff,\n\t64:  0x5f8700,\n\t65:  0x5f875f,\n\t66:  0x5f8787,\n\t67:  0x5f87af,\n\t68:  0x5f87d7,\n\t69:  0x5f87ff,\n\t70:  0x5faf00,\n\t71:  0x5faf5f,\n\t72:  0x5faf87,\n\t73:  0x5fafaf,\n\t74:  0x5fafd7,\n\t75:  0x5fafff,\n\t76:  0x5fd700,\n\t77:  0x5fd75f,\n\t78:  0x5fd787,\n\t79:  0x5fd7af,\n\t80:  0x5fd7d7,\n\t81:  0x5fd7ff,\n\t82:  0x5fff00,\n\t83:  0x5fff5f,\n\t84:  0x5fff87,\n\t85:  0x5fffaf,\n\t86:  0x5fffd7,\n\t87:  0x5fffff,\n\t88:  0x870000,\n\t89:  0x87005f,\n\t90:  0x870087,\n\t91:  0x8700af,\n\t92:  0x8700d7,\n\t93:  0x8700ff,\n\t94:  0x875f00,\n\t95:  0x875f5f,\n\t96:  0x875f87,\n\t97:  0x875faf,\n\t98:  0x875fd7,\n\t99:  0x875fff,\n\t100: 0x878700,\n\t101: 0x87875f,\n\t102: 0x878787,\n\t103: 0x8787af,\n\t104: 0x8787d7,\n\t105: 0x8787ff,\n\t106: 0x87af00,\n\t107: 0x87af5f,\n\t108: 0x87af87,\n\t109: 0x87afaf,\n\t110: 0x87afd7,\n\t111: 0x87afff,\n\t112: 0x87d700,\n\t113: 0x87d75f,\n\t114: 0x87d787,\n\t115: 0x87d7af,\n\t116: 0x87d7d7,\n\t117: 0x87d7ff,\n\t118: 0x87ff00,\n\t119: 0x87ff5f,\n\t120: 0x87ff87,\n\t121: 0x87ffaf,\n\t122: 0x87ffd7,\n\t123: 0x87ffff,\n\t124: 0xaf0000,\n\t125: 0xaf005f,\n\t126: 0xaf0087,\n\t127: 0xaf00af,\n\t128: 0xaf00d7,\n\t129: 0xaf00ff,\n\t130: 0xaf5f00,\n\t131: 0xaf5f5f,\n\t132: 0xaf5f87,\n\t133: 0xaf5faf,\n\t134: 0xaf5fd7,\n\t135: 0xaf5fff,\n\t136: 0xaf8700,\n\t137: 0xaf875f,\n\t138: 0xaf8787,\n\t139: 0xaf87af,\n\t140: 0xaf87d7,\n\t141: 0xaf87ff,\n\t142: 0xafaf00,\n\t143: 0xafaf5f,\n\t144: 0xafaf87,\n\t145: 0xafafaf,\n\t146: 0xafafd7,\n\t147: 0xafafff,\n\t148: 0xafd700,\n\t149: 0xafd75f,\n\t150: 0xafd787,\n\t151: 0xafd7af,\n\t152: 0xafd7d7,\n\t153: 0xafd7ff,\n\t154: 0xafff00,\n\t155: 0xafff5f,\n\t156: 0xafff87,\n\t157: 0xafffaf,\n\t158: 0xafffd7,\n\t159: 0xafffff,\n\t160: 0xd70000,\n\t161: 0xd7005f,\n\t162: 0xd70087,\n\t163: 0xd700af,\n\t164: 0xd700d7,\n\t165: 0xd700ff,\n\t166: 0xd75f00,\n\t167: 0xd75f5f,\n\t168: 0xd75f87,\n\t169: 0xd75faf,\n\t170: 0xd75fd7,\n\t171: 0xd75fff,\n\t172: 0xd78700,\n\t173: 0xd7875f,\n\t174: 0xd78787,\n\t175: 0xd787af,\n\t176: 0xd787d7,\n\t177: 0xd787ff,\n\t178: 0xd7af00,\n\t179: 0xd7af5f,\n\t180: 0xd7af87,\n\t181: 0xd7afaf,\n\t182: 0xd7afd7,\n\t183: 0xd7afff,\n\t184: 0xd7d700,\n\t185: 0xd7d75f,\n\t186: 0xd7d787,\n\t187: 0xd7d7af,\n\t188: 0xd7d7d7,\n\t189: 0xd7d7ff,\n\t190: 0xd7ff00,\n\t191: 0xd7ff5f,\n\t192: 0xd7ff87,\n\t193: 0xd7ffaf,\n\t194: 0xd7ffd7,\n\t195: 0xd7ffff,\n\t196: 0xff0000,\n\t197: 0xff005f,\n\t198: 0xff0087,\n\t199: 0xff00af,\n\t200: 0xff00d7,\n\t201: 0xff00ff,\n\t202: 0xff5f00,\n\t203: 0xff5f5f,\n\t204: 0xff5f87,\n\t205: 0xff5faf,\n\t206: 0xff5fd7,\n\t207: 0xff5fff,\n\t208: 0xff8700,\n\t209: 0xff875f,\n\t210: 0xff8787,\n\t211: 0xff87af,\n\t212: 0xff87d7,\n\t213: 0xff87ff,\n\t214: 0xffaf00,\n\t215: 0xffaf5f,\n\t216: 0xffaf87,\n\t217: 0xffafaf,\n\t218: 0xffafd7,\n\t219: 0xffafff,\n\t220: 0xffd700,\n\t221: 0xffd75f,\n\t222: 0xffd787,\n\t223: 0xffd7af,\n\t224: 0xffd7d7,\n\t225: 0xffd7ff,\n\t226: 0xffff00,\n\t227: 0xffff5f,\n\t228: 0xffff87,\n\t229: 0xffffaf,\n\t230: 0xffffd7,\n\t231: 0xffffff,\n\t232: 0x080808,\n\t233: 0x121212,\n\t234: 0x1c1c1c,\n\t235: 0x262626,\n\t236: 0x303030,\n\t237: 0x3a3a3a,\n\t238: 0x444444,\n\t239: 0x4e4e4e,\n\t240: 0x585858,\n\t241: 0x626262,\n\t242: 0x6c6c6c,\n\t243: 0x767676,\n\t244: 0x808080,\n\t245: 0x8a8a8a,\n\t246: 0x949494,\n\t247: 0x9e9e9e,\n\t248: 0xa8a8a8,\n\t249: 0xb2b2b2,\n\t250: 0xbcbcbc,\n\t251: 0xc6c6c6,\n\t252: 0xd0d0d0,\n\t253: 0xdadada,\n\t254: 0xe4e4e4,\n\t255: 0xeeeeee,\n}\n\n// `\\033]0;TITLESTR\\007`\nfunc doTitleSequence(er *bytes.Reader) error {\n\tvar c byte\n\tvar err error\n\n\tc, err = er.ReadByte()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c != '0' && c != '2' {\n\t\treturn nil\n\t}\n\tc, err = er.ReadByte()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif c != ';' {\n\t\treturn nil\n\t}\n\ttitle := make([]byte, 0, 80)\n\tfor {\n\t\tc, err = er.ReadByte()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif c == 0x07 || c == '\\n' {\n\t\t\tbreak\n\t\t}\n\t\ttitle = append(title, c)\n\t}\n\tif len(title) > 0 {\n\t\ttitle8, err := syscall.UTF16PtrFromString(string(title))\n\t\tif err == nil {\n\t\t\tprocSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8)))\n\t\t}\n\t}\n\treturn nil\n}\n\n// returns Atoi(s) unless s == \"\" in which case it returns def\nfunc atoiWithDefault(s string, def int) (int, error) {\n\tif s == \"\" {\n\t\treturn def, nil\n\t}\n\treturn strconv.Atoi(s)\n}\n\n// Write writes data on console\nfunc (w *Writer) Write(data []byte) (n int, err error) {\n\tw.mutex.Lock()\n\tdefer w.mutex.Unlock()\n\tvar csbi consoleScreenBufferInfo\n\tprocGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))\n\n\thandle := w.handle\n\n\tvar er *bytes.Reader\n\tif w.rest.Len() > 0 {\n\t\tvar rest bytes.Buffer\n\t\tw.rest.WriteTo(&rest)\n\t\tw.rest.Reset()\n\t\trest.Write(data)\n\t\ter = bytes.NewReader(rest.Bytes())\n\t} else {\n\t\ter = bytes.NewReader(data)\n\t}\n\tvar plaintext bytes.Buffer\nloop:\n\tfor {\n\t\tc1, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tplaintext.WriteTo(w.out)\n\t\t\tbreak loop\n\t\t}\n\t\tif c1 != 0x1b {\n\t\t\tplaintext.WriteByte(c1)\n\t\t\tcontinue\n\t\t}\n\t\t_, err = plaintext.WriteTo(w.out)\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tc2, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\n\t\tswitch c2 {\n\t\tcase '>':\n\t\t\tcontinue\n\t\tcase ']':\n\t\t\tw.rest.WriteByte(c1)\n\t\t\tw.rest.WriteByte(c2)\n\t\t\ter.WriteTo(&w.rest)\n\t\t\tif bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\ter = bytes.NewReader(w.rest.Bytes()[2:])\n\t\t\terr := doTitleSequence(er)\n\t\t\tif err != nil {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tw.rest.Reset()\n\t\t\tcontinue\n\t\t// https://github.com/mattn/go-colorable/issues/27\n\t\tcase '7':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tw.oldpos = csbi.cursorPosition\n\t\t\tcontinue\n\t\tcase '8':\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))\n\t\t\tcontinue\n\t\tcase 0x5b:\n\t\t\t// execute part after switch\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\n\t\tw.rest.WriteByte(c1)\n\t\tw.rest.WriteByte(c2)\n\t\ter.WriteTo(&w.rest)\n\n\t\tvar buf bytes.Buffer\n\t\tvar m byte\n\t\tfor i, c := range w.rest.Bytes()[2:] {\n\t\t\tif ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {\n\t\t\t\tm = c\n\t\t\t\ter = bytes.NewReader(w.rest.Bytes()[2+i+1:])\n\t\t\t\tw.rest.Reset()\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbuf.Write([]byte(string(c)))\n\t\t}\n\t\tif m == 0 {\n\t\t\tbreak loop\n\t\t}\n\n\t\tswitch m {\n\t\tcase 'A':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.y -= short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'B':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.y += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'C':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'D':\n\t\t\tn, err = atoiWithDefault(buf.String(), 1)\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x -= short(n)\n\t\t\tif csbi.cursorPosition.x < 0 {\n\t\t\t\tcsbi.cursorPosition.x = 0\n\t\t\t}\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'E':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = 0\n\t\t\tcsbi.cursorPosition.y += short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'F':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = 0\n\t\t\tcsbi.cursorPosition.y -= short(n)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'G':\n\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif n < 1 {\n\t\t\t\tn = 1\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tcsbi.cursorPosition.x = short(n - 1)\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'H', 'f':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tif buf.Len() > 0 {\n\t\t\t\ttoken := strings.Split(buf.String(), \";\")\n\t\t\t\tswitch len(token) {\n\t\t\t\tcase 1:\n\t\t\t\t\tn1, err := strconv.Atoi(token[0])\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tcsbi.cursorPosition.y = short(n1 - 1)\n\t\t\t\tcase 2:\n\t\t\t\t\tn1, err := strconv.Atoi(token[0])\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tn2, err := strconv.Atoi(token[1])\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tcsbi.cursorPosition.x = short(n2 - 1)\n\t\t\t\t\tcsbi.cursorPosition.y = short(n1 - 1)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcsbi.cursorPosition.y = 0\n\t\t\t}\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))\n\t\tcase 'J':\n\t\t\tn := 0\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar count, written dword\n\t\t\tvar cursor coord\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tswitch n {\n\t\t\tcase 0:\n\t\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)\n\t\t\tcase 1:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top}\n\t\t\t\tcount = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x)\n\t\t\tcase 2:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.window.top}\n\t\t\t\tcount = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)\n\t\t\t}\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'K':\n\t\t\tn := 0\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tvar cursor coord\n\t\t\tvar count, written dword\n\t\t\tswitch n {\n\t\t\tcase 0:\n\t\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x - csbi.cursorPosition.x)\n\t\t\tcase 1:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x - csbi.cursorPosition.x)\n\t\t\tcase 2:\n\t\t\t\tcursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}\n\t\t\t\tcount = dword(csbi.size.x)\n\t\t\t}\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'X':\n\t\t\tn := 0\n\t\t\tif buf.Len() > 0 {\n\t\t\t\tn, err = strconv.Atoi(buf.String())\n\t\t\t\tif err != nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tvar cursor coord\n\t\t\tvar written dword\n\t\t\tcursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}\n\t\t\tprocFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\t\tprocFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))\n\t\tcase 'm':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tattr := csbi.attributes\n\t\t\tcs := buf.String()\n\t\t\tif cs == \"\" {\n\t\t\t\tprocSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttoken := strings.Split(cs, \";\")\n\t\t\tfor i := 0; i < len(token); i++ {\n\t\t\t\tns := token[i]\n\t\t\t\tif n, err = strconv.Atoi(ns); err == nil {\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase n == 0 || n == 100:\n\t\t\t\t\t\tattr = w.oldattr\n\t\t\t\t\tcase n == 4:\n\t\t\t\t\t\tattr |= commonLvbUnderscore\n\t\t\t\t\tcase (1 <= n && n <= 3) || n == 5:\n\t\t\t\t\t\tattr |= foregroundIntensity\n\t\t\t\t\tcase n == 7 || n == 27:\n\t\t\t\t\t\tattr =\n\t\t\t\t\t\t\t(attr &^ (foregroundMask | backgroundMask)) |\n\t\t\t\t\t\t\t\t((attr & foregroundMask) << 4) |\n\t\t\t\t\t\t\t\t((attr & backgroundMask) >> 4)\n\t\t\t\t\tcase n == 22:\n\t\t\t\t\t\tattr &^= foregroundIntensity\n\t\t\t\t\tcase n == 24:\n\t\t\t\t\t\tattr &^= commonLvbUnderscore\n\t\t\t\t\tcase 30 <= n && n <= 37:\n\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\tif (n-30)&1 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-30)&2 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-30)&4 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 38: // set foreground color.\n\t\t\t\t\t\tif i < len(token)-2 && (token[i+1] == \"5\" || token[i+1] == \"05\") {\n\t\t\t\t\t\t\tif n256, err := strconv.Atoi(token[i+2]); err == nil {\n\t\t\t\t\t\t\t\tif n256foreAttr == nil {\n\t\t\t\t\t\t\t\t\tn256setup()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\t\t\tattr |= n256foreAttr[n256%len(n256foreAttr)]\n\t\t\t\t\t\t\t\ti += 2\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if len(token) == 5 && token[i+1] == \"2\" {\n\t\t\t\t\t\t\tvar r, g, b int\n\t\t\t\t\t\t\tr, _ = strconv.Atoi(token[i+2])\n\t\t\t\t\t\t\tg, _ = strconv.Atoi(token[i+3])\n\t\t\t\t\t\t\tb, _ = strconv.Atoi(token[i+4])\n\t\t\t\t\t\t\ti += 4\n\t\t\t\t\t\t\tif r > 127 {\n\t\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif g > 127 {\n\t\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif b > 127 {\n\t\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattr = attr & (w.oldattr & backgroundMask)\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 39: // reset foreground color.\n\t\t\t\t\t\tattr &= backgroundMask\n\t\t\t\t\t\tattr |= w.oldattr & foregroundMask\n\t\t\t\t\tcase 40 <= n && n <= 47:\n\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\tif (n-40)&1 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-40)&2 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-40)&4 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 48: // set background color.\n\t\t\t\t\t\tif i < len(token)-2 && token[i+1] == \"5\" {\n\t\t\t\t\t\t\tif n256, err := strconv.Atoi(token[i+2]); err == nil {\n\t\t\t\t\t\t\t\tif n256backAttr == nil {\n\t\t\t\t\t\t\t\t\tn256setup()\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\t\t\tattr |= n256backAttr[n256%len(n256backAttr)]\n\t\t\t\t\t\t\t\ti += 2\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if len(token) == 5 && token[i+1] == \"2\" {\n\t\t\t\t\t\t\tvar r, g, b int\n\t\t\t\t\t\t\tr, _ = strconv.Atoi(token[i+2])\n\t\t\t\t\t\t\tg, _ = strconv.Atoi(token[i+3])\n\t\t\t\t\t\t\tb, _ = strconv.Atoi(token[i+4])\n\t\t\t\t\t\t\ti += 4\n\t\t\t\t\t\t\tif r > 127 {\n\t\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif g > 127 {\n\t\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif b > 127 {\n\t\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattr = attr & (w.oldattr & foregroundMask)\n\t\t\t\t\t\t}\n\t\t\t\t\tcase n == 49: // reset foreground color.\n\t\t\t\t\t\tattr &= foregroundMask\n\t\t\t\t\t\tattr |= w.oldattr & backgroundMask\n\t\t\t\t\tcase 90 <= n && n <= 97:\n\t\t\t\t\t\tattr = (attr & backgroundMask)\n\t\t\t\t\t\tattr |= foregroundIntensity\n\t\t\t\t\t\tif (n-90)&1 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-90)&2 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-90)&4 != 0 {\n\t\t\t\t\t\t\tattr |= foregroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\tcase 100 <= n && n <= 107:\n\t\t\t\t\t\tattr = (attr & foregroundMask)\n\t\t\t\t\t\tattr |= backgroundIntensity\n\t\t\t\t\t\tif (n-100)&1 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundRed\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-100)&2 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundGreen\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (n-100)&4 != 0 {\n\t\t\t\t\t\t\tattr |= backgroundBlue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tprocSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr))\n\t\t\t\t}\n\t\t\t}\n\t\tcase 'h':\n\t\t\tvar ci consoleCursorInfo\n\t\t\tcs := buf.String()\n\t\t\tif cs == \"5>\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 0\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?25\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 1\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?1049\" {\n\t\t\t\tif w.althandle == 0 {\n\t\t\t\t\th, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0)\n\t\t\t\t\tw.althandle = syscall.Handle(h)\n\t\t\t\t\tif w.althandle != 0 {\n\t\t\t\t\t\thandle = w.althandle\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tcase 'l':\n\t\t\tvar ci consoleCursorInfo\n\t\t\tcs := buf.String()\n\t\t\tif cs == \"5>\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 1\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?25\" {\n\t\t\t\tprocGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t\tci.visible = 0\n\t\t\t\tprocSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))\n\t\t\t} else if cs == \"?1049\" {\n\t\t\t\tif w.althandle != 0 {\n\t\t\t\t\tsyscall.CloseHandle(w.althandle)\n\t\t\t\t\tw.althandle = 0\n\t\t\t\t\thandle = w.handle\n\t\t\t\t}\n\t\t\t}\n\t\tcase 's':\n\t\t\tprocGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))\n\t\t\tw.oldpos = csbi.cursorPosition\n\t\tcase 'u':\n\t\t\tprocSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))\n\t\t}\n\t}\n\n\treturn len(data), nil\n}\n\ntype consoleColor struct {\n\trgb       int\n\tred       bool\n\tgreen     bool\n\tblue      bool\n\tintensity bool\n}\n\nfunc (c consoleColor) foregroundAttr() (attr word) {\n\tif c.red {\n\t\tattr |= foregroundRed\n\t}\n\tif c.green {\n\t\tattr |= foregroundGreen\n\t}\n\tif c.blue {\n\t\tattr |= foregroundBlue\n\t}\n\tif c.intensity {\n\t\tattr |= foregroundIntensity\n\t}\n\treturn\n}\n\nfunc (c consoleColor) backgroundAttr() (attr word) {\n\tif c.red {\n\t\tattr |= backgroundRed\n\t}\n\tif c.green {\n\t\tattr |= backgroundGreen\n\t}\n\tif c.blue {\n\t\tattr |= backgroundBlue\n\t}\n\tif c.intensity {\n\t\tattr |= backgroundIntensity\n\t}\n\treturn\n}\n\nvar color16 = []consoleColor{\n\t{0x000000, false, false, false, false},\n\t{0x000080, false, false, true, false},\n\t{0x008000, false, true, false, false},\n\t{0x008080, false, true, true, false},\n\t{0x800000, true, false, false, false},\n\t{0x800080, true, false, true, false},\n\t{0x808000, true, true, false, false},\n\t{0xc0c0c0, true, true, true, false},\n\t{0x808080, false, false, false, true},\n\t{0x0000ff, false, false, true, true},\n\t{0x00ff00, false, true, false, true},\n\t{0x00ffff, false, true, true, true},\n\t{0xff0000, true, false, false, true},\n\t{0xff00ff, true, false, true, true},\n\t{0xffff00, true, true, false, true},\n\t{0xffffff, true, true, true, true},\n}\n\ntype hsv struct {\n\th, s, v float32\n}\n\nfunc (a hsv) dist(b hsv) float32 {\n\tdh := a.h - b.h\n\tswitch {\n\tcase dh > 0.5:\n\t\tdh = 1 - dh\n\tcase dh < -0.5:\n\t\tdh = -1 - dh\n\t}\n\tds := a.s - b.s\n\tdv := a.v - b.v\n\treturn float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv)))\n}\n\nfunc toHSV(rgb int) hsv {\n\tr, g, b := float32((rgb&0xFF0000)>>16)/256.0,\n\t\tfloat32((rgb&0x00FF00)>>8)/256.0,\n\t\tfloat32(rgb&0x0000FF)/256.0\n\tmin, max := minmax3f(r, g, b)\n\th := max - min\n\tif h > 0 {\n\t\tif max == r {\n\t\t\th = (g - b) / h\n\t\t\tif h < 0 {\n\t\t\t\th += 6\n\t\t\t}\n\t\t} else if max == g {\n\t\t\th = 2 + (b-r)/h\n\t\t} else {\n\t\t\th = 4 + (r-g)/h\n\t\t}\n\t}\n\th /= 6.0\n\ts := max - min\n\tif max != 0 {\n\t\ts /= max\n\t}\n\tv := max\n\treturn hsv{h: h, s: s, v: v}\n}\n\ntype hsvTable []hsv\n\nfunc toHSVTable(rgbTable []consoleColor) hsvTable {\n\tt := make(hsvTable, len(rgbTable))\n\tfor i, c := range rgbTable {\n\t\tt[i] = toHSV(c.rgb)\n\t}\n\treturn t\n}\n\nfunc (t hsvTable) find(rgb int) consoleColor {\n\thsv := toHSV(rgb)\n\tn := 7\n\tl := float32(5.0)\n\tfor i, p := range t {\n\t\td := hsv.dist(p)\n\t\tif d < l {\n\t\t\tl, n = d, i\n\t\t}\n\t}\n\treturn color16[n]\n}\n\nfunc minmax3f(a, b, c float32) (min, max float32) {\n\tif a < b {\n\t\tif b < c {\n\t\t\treturn a, c\n\t\t} else if a < c {\n\t\t\treturn a, b\n\t\t} else {\n\t\t\treturn c, b\n\t\t}\n\t} else {\n\t\tif a < c {\n\t\t\treturn b, c\n\t\t} else if b < c {\n\t\t\treturn b, a\n\t\t} else {\n\t\t\treturn c, a\n\t\t}\n\t}\n}\n\nvar n256foreAttr []word\nvar n256backAttr []word\n\nfunc n256setup() {\n\tn256foreAttr = make([]word, 256)\n\tn256backAttr = make([]word, 256)\n\tt := toHSVTable(color16)\n\tfor i, rgb := range color256 {\n\t\tc := t.find(rgb)\n\t\tn256foreAttr[i] = c.foregroundAttr()\n\t\tn256backAttr[i] = c.backgroundAttr()\n\t}\n}\n\n// EnableColorsStdout enable colors if possible.\nfunc EnableColorsStdout(enabled *bool) func() {\n\tvar mode uint32\n\th := os.Stdout.Fd()\n\tif r, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 {\n\t\tif r, _, _ = procSetConsoleMode.Call(h, uintptr(mode|cENABLE_VIRTUAL_TERMINAL_PROCESSING)); r != 0 {\n\t\t\tif enabled != nil {\n\t\t\t\t*enabled = true\n\t\t\t}\n\t\t\treturn func() {\n\t\t\t\tprocSetConsoleMode.Call(h, uintptr(mode))\n\t\t\t}\n\t\t}\n\t}\n\tif enabled != nil {\n\t\t*enabled = true\n\t}\n\treturn func() {}\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/go.test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -race -coverprofile=profile.out -covermode=atomic \"$d\"\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/mattn/go-colorable/noncolorable.go",
    "content": "package colorable\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// NonColorable holds writer but removes escape sequence.\ntype NonColorable struct {\n\tout io.Writer\n}\n\n// NewNonColorable returns new instance of Writer which removes escape sequence from Writer.\nfunc NewNonColorable(w io.Writer) io.Writer {\n\treturn &NonColorable{out: w}\n}\n\n// Write writes data on console\nfunc (w *NonColorable) Write(data []byte) (n int, err error) {\n\ter := bytes.NewReader(data)\n\tvar plaintext bytes.Buffer\nloop:\n\tfor {\n\t\tc1, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tplaintext.WriteTo(w.out)\n\t\t\tbreak loop\n\t\t}\n\t\tif c1 != 0x1b {\n\t\t\tplaintext.WriteByte(c1)\n\t\t\tcontinue\n\t\t}\n\t\t_, err = plaintext.WriteTo(w.out)\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tc2, err := er.ReadByte()\n\t\tif err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tif c2 != 0x5b {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor {\n\t\t\tc, err := er.ReadByte()\n\t\t\tif err != nil {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\treturn len(data), nil\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/LICENSE",
    "content": "Copyright (c) Yasuhiro MATSUMOTO <mattn.jp@gmail.com>\n\nMIT License (Expat)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/README.md",
    "content": "# go-isatty\n\n[![Godoc Reference](https://godoc.org/github.com/mattn/go-isatty?status.svg)](http://godoc.org/github.com/mattn/go-isatty)\n[![Codecov](https://codecov.io/gh/mattn/go-isatty/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-isatty)\n[![Coverage Status](https://coveralls.io/repos/github/mattn/go-isatty/badge.svg?branch=master)](https://coveralls.io/github/mattn/go-isatty?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/mattn/go-isatty)](https://goreportcard.com/report/mattn/go-isatty)\n\nisatty for golang\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/mattn/go-isatty\"\n\t\"os\"\n)\n\nfunc main() {\n\tif isatty.IsTerminal(os.Stdout.Fd()) {\n\t\tfmt.Println(\"Is Terminal\")\n\t} else if isatty.IsCygwinTerminal(os.Stdout.Fd()) {\n\t\tfmt.Println(\"Is Cygwin/MSYS2 Terminal\")\n\t} else {\n\t\tfmt.Println(\"Is Not Terminal\")\n\t}\n}\n```\n\n## Installation\n\n```\n$ go get github.com/mattn/go-isatty\n```\n\n## License\n\nMIT\n\n## Author\n\nYasuhiro Matsumoto (a.k.a mattn)\n\n## Thanks\n\n* k-takata: base idea for IsCygwinTerminal\n\n    https://github.com/k-takata/go-iscygpty\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/doc.go",
    "content": "// Package isatty implements interface to isatty\npackage isatty\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/go.test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -race -coverprofile=profile.out -covermode=atomic \"$d\"\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_bsd.go",
    "content": "//go:build (darwin || freebsd || openbsd || netbsd || dragonfly) && !appengine\n// +build darwin freebsd openbsd netbsd dragonfly\n// +build !appengine\n\npackage isatty\n\nimport \"golang.org/x/sys/unix\"\n\n// IsTerminal return true if the file descriptor is terminal.\nfunc IsTerminal(fd uintptr) bool {\n\t_, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA)\n\treturn err == nil\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_others.go",
    "content": "//go:build appengine || js || nacl || wasm\n// +build appengine js nacl wasm\n\npackage isatty\n\n// IsTerminal returns true if the file descriptor is terminal which\n// is always false on js and appengine classic which is a sandboxed PaaS.\nfunc IsTerminal(fd uintptr) bool {\n\treturn false\n}\n\n// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_plan9.go",
    "content": "//go:build plan9\n// +build plan9\n\npackage isatty\n\nimport (\n\t\"syscall\"\n)\n\n// IsTerminal returns true if the given file descriptor is a terminal.\nfunc IsTerminal(fd uintptr) bool {\n\tpath, err := syscall.Fd2path(int(fd))\n\tif err != nil {\n\t\treturn false\n\t}\n\treturn path == \"/dev/cons\" || path == \"/mnt/term/dev/cons\"\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_solaris.go",
    "content": "//go:build solaris && !appengine\n// +build solaris,!appengine\n\npackage isatty\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\n// IsTerminal returns true if the given file descriptor is a terminal.\n// see: https://src.illumos.org/source/xref/illumos-gate/usr/src/lib/libc/port/gen/isatty.c\nfunc IsTerminal(fd uintptr) bool {\n\t_, err := unix.IoctlGetTermio(int(fd), unix.TCGETA)\n\treturn err == nil\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_tcgets.go",
    "content": "//go:build (linux || aix || zos) && !appengine\n// +build linux aix zos\n// +build !appengine\n\npackage isatty\n\nimport \"golang.org/x/sys/unix\"\n\n// IsTerminal return true if the file descriptor is terminal.\nfunc IsTerminal(fd uintptr) bool {\n\t_, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)\n\treturn err == nil\n}\n\n// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2\n// terminal. This is also always false on this environment.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-isatty/isatty_windows.go",
    "content": "//go:build windows && !appengine\n// +build windows,!appengine\n\npackage isatty\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unicode/utf16\"\n\t\"unsafe\"\n)\n\nconst (\n\tobjectNameInfo uintptr = 1\n\tfileNameInfo           = 2\n\tfileTypePipe           = 3\n)\n\nvar (\n\tkernel32                         = syscall.NewLazyDLL(\"kernel32.dll\")\n\tntdll                            = syscall.NewLazyDLL(\"ntdll.dll\")\n\tprocGetConsoleMode               = kernel32.NewProc(\"GetConsoleMode\")\n\tprocGetFileInformationByHandleEx = kernel32.NewProc(\"GetFileInformationByHandleEx\")\n\tprocGetFileType                  = kernel32.NewProc(\"GetFileType\")\n\tprocNtQueryObject                = ntdll.NewProc(\"NtQueryObject\")\n)\n\nfunc init() {\n\t// Check if GetFileInformationByHandleEx is available.\n\tif procGetFileInformationByHandleEx.Find() != nil {\n\t\tprocGetFileInformationByHandleEx = nil\n\t}\n}\n\n// IsTerminal return true if the file descriptor is terminal.\nfunc IsTerminal(fd uintptr) bool {\n\tvar st uint32\n\tr, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&st)), 0)\n\treturn r != 0 && e == 0\n}\n\n// Check pipe name is used for cygwin/msys2 pty.\n// Cygwin/MSYS2 PTY has a name like:\n//   \\{cygwin,msys}-XXXXXXXXXXXXXXXX-ptyN-{from,to}-master\nfunc isCygwinPipeName(name string) bool {\n\ttoken := strings.Split(name, \"-\")\n\tif len(token) < 5 {\n\t\treturn false\n\t}\n\n\tif token[0] != `\\msys` &&\n\t\ttoken[0] != `\\cygwin` &&\n\t\ttoken[0] != `\\Device\\NamedPipe\\msys` &&\n\t\ttoken[0] != `\\Device\\NamedPipe\\cygwin` {\n\t\treturn false\n\t}\n\n\tif token[1] == \"\" {\n\t\treturn false\n\t}\n\n\tif !strings.HasPrefix(token[2], \"pty\") {\n\t\treturn false\n\t}\n\n\tif token[3] != `from` && token[3] != `to` {\n\t\treturn false\n\t}\n\n\tif token[4] != \"master\" {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// getFileNameByHandle use the undocomented ntdll NtQueryObject to get file full name from file handler\n// since GetFileInformationByHandleEx is not available under windows Vista and still some old fashion\n// guys are using Windows XP, this is a workaround for those guys, it will also work on system from\n// Windows vista to 10\n// see https://stackoverflow.com/a/18792477 for details\nfunc getFileNameByHandle(fd uintptr) (string, error) {\n\tif procNtQueryObject == nil {\n\t\treturn \"\", errors.New(\"ntdll.dll: NtQueryObject not supported\")\n\t}\n\n\tvar buf [4 + syscall.MAX_PATH]uint16\n\tvar result int\n\tr, _, e := syscall.Syscall6(procNtQueryObject.Addr(), 5,\n\t\tfd, objectNameInfo, uintptr(unsafe.Pointer(&buf)), uintptr(2*len(buf)), uintptr(unsafe.Pointer(&result)), 0)\n\tif r != 0 {\n\t\treturn \"\", e\n\t}\n\treturn string(utf16.Decode(buf[4 : 4+buf[0]/2])), nil\n}\n\n// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2\n// terminal.\nfunc IsCygwinTerminal(fd uintptr) bool {\n\tif procGetFileInformationByHandleEx == nil {\n\t\tname, err := getFileNameByHandle(fd)\n\t\tif err != nil {\n\t\t\treturn false\n\t\t}\n\t\treturn isCygwinPipeName(name)\n\t}\n\n\t// Cygwin/msys's pty is a pipe.\n\tft, _, e := syscall.Syscall(procGetFileType.Addr(), 1, fd, 0, 0)\n\tif ft != fileTypePipe || e != 0 {\n\t\treturn false\n\t}\n\n\tvar buf [2 + syscall.MAX_PATH]uint16\n\tr, _, e := syscall.Syscall6(procGetFileInformationByHandleEx.Addr(),\n\t\t4, fd, fileNameInfo, uintptr(unsafe.Pointer(&buf)),\n\t\tuintptr(len(buf)*2), 0, 0)\n\tif r == 0 || e != 0 {\n\t\treturn false\n\t}\n\n\tl := *(*uint32)(unsafe.Pointer(&buf))\n\treturn isCygwinPipeName(string(utf16.Decode(buf[2 : 2+l/2])))\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/.travis.yml",
    "content": "language: go\nsudo: false\ngo:\n  - 1.13.x\n  - tip\n\nbefore_install:\n  - go get -t -v ./...\n\nscript:\n  - go generate\n  - git diff --cached --exit-code\n  - ./go.test.sh\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Yasuhiro Matsumoto\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": "vendor/github.com/mattn/go-runewidth/README.md",
    "content": "go-runewidth\n============\n\n[![Build Status](https://travis-ci.org/mattn/go-runewidth.png?branch=master)](https://travis-ci.org/mattn/go-runewidth)\n[![Codecov](https://codecov.io/gh/mattn/go-runewidth/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-runewidth)\n[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth)\n[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth)\n\nProvides functions to get fixed width of the character or string.\n\nUsage\n-----\n\n```go\nrunewidth.StringWidth(\"つのだ☆HIRO\") == 12\n```\n\n\nAuthor\n------\n\nYasuhiro Matsumoto\n\nLicense\n-------\n\nunder the MIT License: http://mattn.mit-license.org/2013\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/go.test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -race -coverprofile=profile.out -covermode=atomic \"$d\"\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/runewidth.go",
    "content": "package runewidth\n\nimport (\n\t\"os\"\n\n\t\"github.com/rivo/uniseg\"\n)\n\n//go:generate go run script/generate.go\n\nvar (\n\t// EastAsianWidth will be set true if the current locale is CJK\n\tEastAsianWidth bool\n\n\t// StrictEmojiNeutral should be set false if handle broken fonts\n\tStrictEmojiNeutral bool = true\n\n\t// DefaultCondition is a condition in current locale\n\tDefaultCondition = &Condition{\n\t\tEastAsianWidth:     false,\n\t\tStrictEmojiNeutral: true,\n\t}\n)\n\nfunc init() {\n\thandleEnv()\n}\n\nfunc handleEnv() {\n\tenv := os.Getenv(\"RUNEWIDTH_EASTASIAN\")\n\tif env == \"\" {\n\t\tEastAsianWidth = IsEastAsian()\n\t} else {\n\t\tEastAsianWidth = env == \"1\"\n\t}\n\t// update DefaultCondition\n\tDefaultCondition.EastAsianWidth = EastAsianWidth\n}\n\ntype interval struct {\n\tfirst rune\n\tlast  rune\n}\n\ntype table []interval\n\nfunc inTables(r rune, ts ...table) bool {\n\tfor _, t := range ts {\n\t\tif inTable(r, t) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc inTable(r rune, t table) bool {\n\tif r < t[0].first {\n\t\treturn false\n\t}\n\n\tbot := 0\n\ttop := len(t) - 1\n\tfor top >= bot {\n\t\tmid := (bot + top) >> 1\n\n\t\tswitch {\n\t\tcase t[mid].last < r:\n\t\t\tbot = mid + 1\n\t\tcase t[mid].first > r:\n\t\t\ttop = mid - 1\n\t\tdefault:\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nvar private = table{\n\t{0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD},\n}\n\nvar nonprint = table{\n\t{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},\n\t{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},\n\t{0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},\n\t{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},\n}\n\n// Condition have flag EastAsianWidth whether the current locale is CJK or not.\ntype Condition struct {\n\tEastAsianWidth     bool\n\tStrictEmojiNeutral bool\n}\n\n// NewCondition return new instance of Condition which is current locale.\nfunc NewCondition() *Condition {\n\treturn &Condition{\n\t\tEastAsianWidth:     EastAsianWidth,\n\t\tStrictEmojiNeutral: StrictEmojiNeutral,\n\t}\n}\n\n// RuneWidth returns the number of cells in r.\n// See http://www.unicode.org/reports/tr11/\nfunc (c *Condition) RuneWidth(r rune) int {\n\t// optimized version, verified by TestRuneWidthChecksums()\n\tif !c.EastAsianWidth {\n\t\tswitch {\n\t\tcase r < 0x20 || r > 0x10FFFF:\n\t\t\treturn 0\n\t\tcase (r >= 0x7F && r <= 0x9F) || r == 0xAD: // nonprint\n\t\t\treturn 0\n\t\tcase r < 0x300:\n\t\t\treturn 1\n\t\tcase inTable(r, narrow):\n\t\t\treturn 1\n\t\tcase inTables(r, nonprint, combining):\n\t\t\treturn 0\n\t\tcase inTable(r, doublewidth):\n\t\t\treturn 2\n\t\tdefault:\n\t\t\treturn 1\n\t\t}\n\t} else {\n\t\tswitch {\n\t\tcase r < 0 || r > 0x10FFFF || inTables(r, nonprint, combining):\n\t\t\treturn 0\n\t\tcase inTable(r, narrow):\n\t\t\treturn 1\n\t\tcase inTables(r, ambiguous, doublewidth):\n\t\t\treturn 2\n\t\tcase !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow):\n\t\t\treturn 2\n\t\tdefault:\n\t\t\treturn 1\n\t\t}\n\t}\n}\n\n// StringWidth return width as you can see\nfunc (c *Condition) StringWidth(s string) (width int) {\n\tg := uniseg.NewGraphemes(s)\n\tfor g.Next() {\n\t\tvar chWidth int\n\t\tfor _, r := range g.Runes() {\n\t\t\tchWidth = c.RuneWidth(r)\n\t\t\tif chWidth > 0 {\n\t\t\t\tbreak // Our best guess at this point is to use the width of the first non-zero-width rune.\n\t\t\t}\n\t\t}\n\t\twidth += chWidth\n\t}\n\treturn\n}\n\n// Truncate return string truncated with w cells\nfunc (c *Condition) Truncate(s string, w int, tail string) string {\n\tif c.StringWidth(s) <= w {\n\t\treturn s\n\t}\n\tw -= c.StringWidth(tail)\n\tvar width int\n\tpos := len(s)\n\tg := uniseg.NewGraphemes(s)\n\tfor g.Next() {\n\t\tvar chWidth int\n\t\tfor _, r := range g.Runes() {\n\t\t\tchWidth = c.RuneWidth(r)\n\t\t\tif chWidth > 0 {\n\t\t\t\tbreak // See StringWidth() for details.\n\t\t\t}\n\t\t}\n\t\tif width+chWidth > w {\n\t\t\tpos, _ = g.Positions()\n\t\t\tbreak\n\t\t}\n\t\twidth += chWidth\n\t}\n\treturn s[:pos] + tail\n}\n\n// Wrap return string wrapped with w cells\nfunc (c *Condition) Wrap(s string, w int) string {\n\twidth := 0\n\tout := \"\"\n\tfor _, r := range []rune(s) {\n\t\tcw := c.RuneWidth(r)\n\t\tif r == '\\n' {\n\t\t\tout += string(r)\n\t\t\twidth = 0\n\t\t\tcontinue\n\t\t} else if width+cw > w {\n\t\t\tout += \"\\n\"\n\t\t\twidth = 0\n\t\t\tout += string(r)\n\t\t\twidth += cw\n\t\t\tcontinue\n\t\t}\n\t\tout += string(r)\n\t\twidth += cw\n\t}\n\treturn out\n}\n\n// FillLeft return string filled in left by spaces in w cells\nfunc (c *Condition) FillLeft(s string, w int) string {\n\twidth := c.StringWidth(s)\n\tcount := w - width\n\tif count > 0 {\n\t\tb := make([]byte, count)\n\t\tfor i := range b {\n\t\t\tb[i] = ' '\n\t\t}\n\t\treturn string(b) + s\n\t}\n\treturn s\n}\n\n// FillRight return string filled in left by spaces in w cells\nfunc (c *Condition) FillRight(s string, w int) string {\n\twidth := c.StringWidth(s)\n\tcount := w - width\n\tif count > 0 {\n\t\tb := make([]byte, count)\n\t\tfor i := range b {\n\t\t\tb[i] = ' '\n\t\t}\n\t\treturn s + string(b)\n\t}\n\treturn s\n}\n\n// RuneWidth returns the number of cells in r.\n// See http://www.unicode.org/reports/tr11/\nfunc RuneWidth(r rune) int {\n\treturn DefaultCondition.RuneWidth(r)\n}\n\n// IsAmbiguousWidth returns whether is ambiguous width or not.\nfunc IsAmbiguousWidth(r rune) bool {\n\treturn inTables(r, private, ambiguous)\n}\n\n// IsNeutralWidth returns whether is neutral width or not.\nfunc IsNeutralWidth(r rune) bool {\n\treturn inTable(r, neutral)\n}\n\n// StringWidth return width as you can see\nfunc StringWidth(s string) (width int) {\n\treturn DefaultCondition.StringWidth(s)\n}\n\n// Truncate return string truncated with w cells\nfunc Truncate(s string, w int, tail string) string {\n\treturn DefaultCondition.Truncate(s, w, tail)\n}\n\n// Wrap return string wrapped with w cells\nfunc Wrap(s string, w int) string {\n\treturn DefaultCondition.Wrap(s, w)\n}\n\n// FillLeft return string filled in left by spaces in w cells\nfunc FillLeft(s string, w int) string {\n\treturn DefaultCondition.FillLeft(s, w)\n}\n\n// FillRight return string filled in left by spaces in w cells\nfunc FillRight(s string, w int) string {\n\treturn DefaultCondition.FillRight(s, w)\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/runewidth_appengine.go",
    "content": "// +build appengine\n\npackage runewidth\n\n// IsEastAsian return true if the current locale is CJK\nfunc IsEastAsian() bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/runewidth_js.go",
    "content": "// +build js\n// +build !appengine\n\npackage runewidth\n\nfunc IsEastAsian() bool {\n\t// TODO: Implement this for the web. Detect east asian in a compatible way, and return true.\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/runewidth_posix.go",
    "content": "// +build !windows\n// +build !js\n// +build !appengine\n\npackage runewidth\n\nimport (\n\t\"os\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nvar reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\\.(.+)`)\n\nvar mblenTable = map[string]int{\n\t\"utf-8\":   6,\n\t\"utf8\":    6,\n\t\"jis\":     8,\n\t\"eucjp\":   3,\n\t\"euckr\":   2,\n\t\"euccn\":   2,\n\t\"sjis\":    2,\n\t\"cp932\":   2,\n\t\"cp51932\": 2,\n\t\"cp936\":   2,\n\t\"cp949\":   2,\n\t\"cp950\":   2,\n\t\"big5\":    2,\n\t\"gbk\":     2,\n\t\"gb2312\":  2,\n}\n\nfunc isEastAsian(locale string) bool {\n\tcharset := strings.ToLower(locale)\n\tr := reLoc.FindStringSubmatch(locale)\n\tif len(r) == 2 {\n\t\tcharset = strings.ToLower(r[1])\n\t}\n\n\tif strings.HasSuffix(charset, \"@cjk_narrow\") {\n\t\treturn false\n\t}\n\n\tfor pos, b := range []byte(charset) {\n\t\tif b == '@' {\n\t\t\tcharset = charset[:pos]\n\t\t\tbreak\n\t\t}\n\t}\n\tmax := 1\n\tif m, ok := mblenTable[charset]; ok {\n\t\tmax = m\n\t}\n\tif max > 1 && (charset[0] != 'u' ||\n\t\tstrings.HasPrefix(locale, \"ja\") ||\n\t\tstrings.HasPrefix(locale, \"ko\") ||\n\t\tstrings.HasPrefix(locale, \"zh\")) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// IsEastAsian return true if the current locale is CJK\nfunc IsEastAsian() bool {\n\tlocale := os.Getenv(\"LC_ALL\")\n\tif locale == \"\" {\n\t\tlocale = os.Getenv(\"LC_CTYPE\")\n\t}\n\tif locale == \"\" {\n\t\tlocale = os.Getenv(\"LANG\")\n\t}\n\n\t// ignore C locale\n\tif locale == \"POSIX\" || locale == \"C\" {\n\t\treturn false\n\t}\n\tif len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {\n\t\treturn false\n\t}\n\n\treturn isEastAsian(locale)\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/runewidth_table.go",
    "content": "// Code generated by script/generate.go. DO NOT EDIT.\n\npackage runewidth\n\nvar combining = table{\n\t{0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3},\n\t{0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0D00, 0x0D01},\n\t{0x135D, 0x135F}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1AC0},\n\t{0x1B6B, 0x1B73}, {0x1DC0, 0x1DF9}, {0x1DFB, 0x1DFF},\n\t{0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF},\n\t{0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D},\n\t{0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1},\n\t{0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A},\n\t{0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x11300, 0x11301},\n\t{0x1133B, 0x1133C}, {0x11366, 0x1136C}, {0x11370, 0x11374},\n\t{0x16AF0, 0x16AF4}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172},\n\t{0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},\n\t{0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018},\n\t{0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A},\n\t{0x1E8D0, 0x1E8D6},\n}\n\nvar doublewidth = table{\n\t{0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A},\n\t{0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3},\n\t{0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653},\n\t{0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1},\n\t{0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},\n\t{0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA},\n\t{0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA},\n\t{0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B},\n\t{0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E},\n\t{0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},\n\t{0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},\n\t{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},\n\t{0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB},\n\t{0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF},\n\t{0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E3},\n\t{0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x4DBF},\n\t{0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},\n\t{0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19},\n\t{0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B},\n\t{0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4},\n\t{0x16FF0, 0x16FF1}, {0x17000, 0x187F7}, {0x18800, 0x18CD5},\n\t{0x18D00, 0x18D08}, {0x1B000, 0x1B11E}, {0x1B150, 0x1B152},\n\t{0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1F004, 0x1F004},\n\t{0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},\n\t{0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},\n\t{0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F320},\n\t{0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393},\n\t{0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0},\n\t{0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440},\n\t{0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E},\n\t{0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596},\n\t{0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5},\n\t{0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, {0x1F6D5, 0x1F6D7},\n\t{0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB},\n\t{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F978},\n\t{0x1F97A, 0x1F9CB}, {0x1F9CD, 0x1F9FF}, {0x1FA70, 0x1FA74},\n\t{0x1FA78, 0x1FA7A}, {0x1FA80, 0x1FA86}, {0x1FA90, 0x1FAA8},\n\t{0x1FAB0, 0x1FAB6}, {0x1FAC0, 0x1FAC2}, {0x1FAD0, 0x1FAD6},\n\t{0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},\n}\n\nvar ambiguous = table{\n\t{0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},\n\t{0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4},\n\t{0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},\n\t{0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},\n\t{0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},\n\t{0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},\n\t{0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},\n\t{0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},\n\t{0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},\n\t{0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},\n\t{0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},\n\t{0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},\n\t{0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},\n\t{0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},\n\t{0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},\n\t{0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},\n\t{0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},\n\t{0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F},\n\t{0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1},\n\t{0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F},\n\t{0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016},\n\t{0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022},\n\t{0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033},\n\t{0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E},\n\t{0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084},\n\t{0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105},\n\t{0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116},\n\t{0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B},\n\t{0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B},\n\t{0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199},\n\t{0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4},\n\t{0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203},\n\t{0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F},\n\t{0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A},\n\t{0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225},\n\t{0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237},\n\t{0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C},\n\t{0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267},\n\t{0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283},\n\t{0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299},\n\t{0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312},\n\t{0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573},\n\t{0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1},\n\t{0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7},\n\t{0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8},\n\t{0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5},\n\t{0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609},\n\t{0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E},\n\t{0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661},\n\t{0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D},\n\t{0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF},\n\t{0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1},\n\t{0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1},\n\t{0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC},\n\t{0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F},\n\t{0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF},\n\t{0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A},\n\t{0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D},\n\t{0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF},\n\t{0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},\n}\nvar narrow = table{\n\t{0x0020, 0x007E}, {0x00A2, 0x00A3}, {0x00A5, 0x00A6},\n\t{0x00AC, 0x00AC}, {0x00AF, 0x00AF}, {0x27E6, 0x27ED},\n\t{0x2985, 0x2986},\n}\n\nvar neutral = table{\n\t{0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9},\n\t{0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB},\n\t{0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6},\n\t{0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7},\n\t{0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1},\n\t{0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD},\n\t{0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},\n\t{0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A},\n\t{0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E},\n\t{0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C},\n\t{0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A},\n\t{0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1},\n\t{0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7},\n\t{0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250},\n\t{0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6},\n\t{0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF},\n\t{0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},\n\t{0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F},\n\t{0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390},\n\t{0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400},\n\t{0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F},\n\t{0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F},\n\t{0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4},\n\t{0x0600, 0x061C}, {0x061E, 0x070D}, {0x070F, 0x074A},\n\t{0x074D, 0x07B1}, {0x07C0, 0x07FA}, {0x07FD, 0x082D},\n\t{0x0830, 0x083E}, {0x0840, 0x085B}, {0x085E, 0x085E},\n\t{0x0860, 0x086A}, {0x08A0, 0x08B4}, {0x08B6, 0x08C7},\n\t{0x08D3, 0x0983}, {0x0985, 0x098C}, {0x098F, 0x0990},\n\t{0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B2, 0x09B2},\n\t{0x09B6, 0x09B9}, {0x09BC, 0x09C4}, {0x09C7, 0x09C8},\n\t{0x09CB, 0x09CE}, {0x09D7, 0x09D7}, {0x09DC, 0x09DD},\n\t{0x09DF, 0x09E3}, {0x09E6, 0x09FE}, {0x0A01, 0x0A03},\n\t{0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28},\n\t{0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, {0x0A35, 0x0A36},\n\t{0x0A38, 0x0A39}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42},\n\t{0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},\n\t{0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76},\n\t{0x0A81, 0x0A83}, {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91},\n\t{0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3},\n\t{0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9},\n\t{0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3},\n\t{0x0AE6, 0x0AF1}, {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03},\n\t{0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28},\n\t{0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, {0x0B35, 0x0B39},\n\t{0x0B3C, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D},\n\t{0x0B55, 0x0B57}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63},\n\t{0x0B66, 0x0B77}, {0x0B82, 0x0B83}, {0x0B85, 0x0B8A},\n\t{0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A},\n\t{0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4},\n\t{0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2},\n\t{0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0},\n\t{0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C},\n\t{0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C39},\n\t{0x0C3D, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},\n\t{0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C63},\n\t{0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90},\n\t{0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},\n\t{0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},\n\t{0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3},\n\t{0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D00, 0x0D0C},\n\t{0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48},\n\t{0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F},\n\t{0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1},\n\t{0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6},\n\t{0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6},\n\t{0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4},\n\t{0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82},\n\t{0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3},\n\t{0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4},\n\t{0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9},\n\t{0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},\n\t{0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},\n\t{0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},\n\t{0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248},\n\t{0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258},\n\t{0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D},\n\t{0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE},\n\t{0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6},\n\t{0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},\n\t{0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},\n\t{0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},\n\t{0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736},\n\t{0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},\n\t{0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9},\n\t{0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819},\n\t{0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5},\n\t{0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B},\n\t{0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974},\n\t{0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA},\n\t{0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C},\n\t{0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD},\n\t{0x1AB0, 0x1AC0}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C},\n\t{0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49},\n\t{0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7},\n\t{0x1CD0, 0x1CFA}, {0x1D00, 0x1DF9}, {0x1DFB, 0x1F15},\n\t{0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},\n\t{0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},\n\t{0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},\n\t{0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},\n\t{0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE},\n\t{0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017},\n\t{0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023},\n\t{0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},\n\t{0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},\n\t{0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},\n\t{0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},\n\t{0x20AA, 0x20AB}, {0x20AD, 0x20BF}, {0x20D0, 0x20F0},\n\t{0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},\n\t{0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},\n\t{0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},\n\t{0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},\n\t{0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7},\n\t{0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6},\n\t{0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206},\n\t{0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210},\n\t{0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C},\n\t{0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226},\n\t{0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B},\n\t{0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251},\n\t{0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269},\n\t{0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285},\n\t{0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4},\n\t{0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319},\n\t{0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF},\n\t{0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A},\n\t{0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F},\n\t{0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2},\n\t{0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB},\n\t{0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA},\n\t{0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE},\n\t{0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608},\n\t{0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B},\n\t{0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641},\n\t{0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662},\n\t{0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E},\n\t{0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D},\n\t{0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC},\n\t{0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7},\n\t{0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727},\n\t{0x2729, 0x273C}, {0x273E, 0x274B}, {0x274D, 0x274D},\n\t{0x274F, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x2775},\n\t{0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE},\n\t{0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A},\n\t{0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73},\n\t{0x2B76, 0x2B95}, {0x2B97, 0x2C2E}, {0x2C30, 0x2C5E},\n\t{0x2C60, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27},\n\t{0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70},\n\t{0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE},\n\t{0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6},\n\t{0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE},\n\t{0x2DE0, 0x2E52}, {0x303F, 0x303F}, {0x4DC0, 0x4DFF},\n\t{0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7BF},\n\t{0xA7C2, 0xA7CA}, {0xA7F5, 0xA82C}, {0xA830, 0xA839},\n\t{0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9},\n\t{0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},\n\t{0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},\n\t{0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2},\n\t{0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},\n\t{0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},\n\t{0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9},\n\t{0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},\n\t{0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},\n\t{0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},\n\t{0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F},\n\t{0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD},\n\t{0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},\n\t{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},\n\t{0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},\n\t{0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},\n\t{0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},\n\t{0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},\n\t{0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},\n\t{0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A},\n\t{0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},\n\t{0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},\n\t{0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},\n\t{0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755},\n\t{0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808},\n\t{0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},\n\t{0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF},\n\t{0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B},\n\t{0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7},\n\t{0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06},\n\t{0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35},\n\t{0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58},\n\t{0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6},\n\t{0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72},\n\t{0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},\n\t{0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},\n\t{0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10E60, 0x10E7E},\n\t{0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1},\n\t{0x10F00, 0x10F27}, {0x10F30, 0x10F59}, {0x10FB0, 0x10FCB},\n\t{0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x1106F},\n\t{0x1107F, 0x110C1}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8},\n\t{0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147},\n\t{0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4},\n\t{0x11200, 0x11211}, {0x11213, 0x1123E}, {0x11280, 0x11286},\n\t{0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D},\n\t{0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9},\n\t{0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310},\n\t{0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333},\n\t{0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348},\n\t{0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357},\n\t{0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},\n\t{0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7},\n\t{0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD},\n\t{0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C},\n\t{0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x11700, 0x1171A},\n\t{0x1171D, 0x1172B}, {0x11730, 0x1173F}, {0x11800, 0x1183B},\n\t{0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909},\n\t{0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935},\n\t{0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959},\n\t{0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4},\n\t{0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AC0, 0x11AF8},\n\t{0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45},\n\t{0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7},\n\t{0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},\n\t{0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D},\n\t{0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65},\n\t{0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91},\n\t{0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8},\n\t{0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399},\n\t{0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},\n\t{0x13000, 0x1342E}, {0x13430, 0x13438}, {0x14400, 0x14646},\n\t{0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69},\n\t{0x16A6E, 0x16A6F}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5},\n\t{0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},\n\t{0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16E40, 0x16E9A},\n\t{0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F},\n\t{0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88},\n\t{0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1D000, 0x1D0F5},\n\t{0x1D100, 0x1D126}, {0x1D129, 0x1D1E8}, {0x1D200, 0x1D245},\n\t{0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378},\n\t{0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F},\n\t{0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC},\n\t{0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3},\n\t{0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514},\n\t{0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E},\n\t{0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550},\n\t{0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B},\n\t{0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},\n\t{0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},\n\t{0x1E026, 0x1E02A}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},\n\t{0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E2C0, 0x1E2F9},\n\t{0x1E2FF, 0x1E2FF}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},\n\t{0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},\n\t{0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03},\n\t{0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24},\n\t{0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37},\n\t{0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42},\n\t{0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B},\n\t{0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54},\n\t{0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B},\n\t{0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62},\n\t{0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72},\n\t{0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E},\n\t{0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3},\n\t{0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1},\n\t{0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093},\n\t{0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE},\n\t{0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F},\n\t{0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF},\n\t{0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D},\n\t{0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF},\n\t{0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F},\n\t{0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A},\n\t{0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},\n\t{0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},\n\t{0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4},\n\t{0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773},\n\t{0x1F780, 0x1F7D8}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},\n\t{0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},\n\t{0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B},\n\t{0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D},\n\t{0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9},\n\t{0xE0001, 0xE0001}, {0xE0020, 0xE007F},\n}\n\nvar emoji = table{\n\t{0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122},\n\t{0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA},\n\t{0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388},\n\t{0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA},\n\t{0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6},\n\t{0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605},\n\t{0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705},\n\t{0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716},\n\t{0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728},\n\t{0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747},\n\t{0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},\n\t{0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797},\n\t{0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF},\n\t{0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C},\n\t{0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030},\n\t{0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299},\n\t{0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F},\n\t{0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E},\n\t{0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F},\n\t{0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A},\n\t{0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D},\n\t{0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F},\n\t{0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F},\n\t{0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF},\n\t{0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF},\n\t{0x1FC00, 0x1FFFD},\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-runewidth/runewidth_windows.go",
    "content": "// +build windows\n// +build !appengine\n\npackage runewidth\n\nimport (\n\t\"syscall\"\n)\n\nvar (\n\tkernel32               = syscall.NewLazyDLL(\"kernel32\")\n\tprocGetConsoleOutputCP = kernel32.NewProc(\"GetConsoleOutputCP\")\n)\n\n// IsEastAsian return true if the current locale is CJK\nfunc IsEastAsian() bool {\n\tr1, _, _ := procGetConsoleOutputCP.Call()\n\tif r1 == 0 {\n\t\treturn false\n\t}\n\n\tswitch int(r1) {\n\tcase 932, 51932, 936, 949, 950:\n\t\treturn true\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-shellwords/.travis.yml",
    "content": "arch:\n  - amd64\n  - ppc64le\nlanguage: go\nsudo: false\ngo:\n  - tip\n\nbefore_install:\n  - go get -t -v ./...\n\nscript:\n  - ./go.test.sh\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-shellwords/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Yasuhiro Matsumoto\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": "vendor/github.com/mattn/go-shellwords/README.md",
    "content": "# go-shellwords\n\n[![codecov](https://codecov.io/gh/mattn/go-shellwords/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-shellwords)\n[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords)\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/mattn/go-shellwords)](https://pkg.go.dev/github.com/mattn/go-shellwords)\n[![ci](https://github.com/mattn/go-shellwords/ci/badge.svg)](https://github.com/mattn/go-shellwords/actions)\n\nParse line as shell words.\n\n## Usage\n\n```go\nargs, err := shellwords.Parse(\"./foo --bar=baz\")\n// args should be [\"./foo\", \"--bar=baz\"]\n```\n\n```go\nenvs, args, err := shellwords.ParseWithEnvs(\"FOO=foo BAR=baz ./foo --bar=baz\")\n// envs should be [\"FOO=foo\", \"BAR=baz\"]\n// args should be [\"./foo\", \"--bar=baz\"]\n```\n\n```go\nos.Setenv(\"FOO\", \"bar\")\np := shellwords.NewParser()\np.ParseEnv = true\nargs, err := p.Parse(\"./foo $FOO\")\n// args should be [\"./foo\", \"bar\"]\n```\n\n```go\np := shellwords.NewParser()\np.ParseBacktick = true\nargs, err := p.Parse(\"./foo `echo $SHELL`\")\n// args should be [\"./foo\", \"/bin/bash\"]\n```\n\n```go\nshellwords.ParseBacktick = true\np := shellwords.NewParser()\nargs, err := p.Parse(\"./foo `echo $SHELL`\")\n// args should be [\"./foo\", \"/bin/bash\"]\n```\n\n# Thanks\n\nThis is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine).\n\n# License\n\nunder the MIT License: http://mattn.mit-license.org/2017\n\n# Author\n\nYasuhiro Matsumoto (a.k.a mattn)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-shellwords/go.test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -coverprofile=profile.out -covermode=atomic \"$d\"\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/mattn/go-shellwords/shellwords.go",
    "content": "package shellwords\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"os\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nvar (\n\tParseEnv      bool = false\n\tParseBacktick bool = false\n)\n\nfunc isSpace(r rune) bool {\n\tswitch r {\n\tcase ' ', '\\t', '\\r', '\\n':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc replaceEnv(getenv func(string) string, s string) string {\n\tif getenv == nil {\n\t\tgetenv = os.Getenv\n\t}\n\n\tvar buf bytes.Buffer\n\trs := []rune(s)\n\tfor i := 0; i < len(rs); i++ {\n\t\tr := rs[i]\n\t\tif r == '\\\\' {\n\t\t\ti++\n\t\t\tif i == len(rs) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tbuf.WriteRune(rs[i])\n\t\t\tcontinue\n\t\t} else if r == '$' {\n\t\t\ti++\n\t\t\tif i == len(rs) {\n\t\t\t\tbuf.WriteRune(r)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif rs[i] == 0x7b {\n\t\t\t\ti++\n\t\t\t\tp := i\n\t\t\t\tfor ; i < len(rs); i++ {\n\t\t\t\t\tr = rs[i]\n\t\t\t\t\tif r == '\\\\' {\n\t\t\t\t\t\ti++\n\t\t\t\t\t\tif i == len(rs) {\n\t\t\t\t\t\t\treturn s\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif r == 0x7d || (!unicode.IsLetter(r) && r != '_' && !unicode.IsDigit(r)) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif r != 0x7d {\n\t\t\t\t\treturn s\n\t\t\t\t}\n\t\t\t\tif i > p {\n\t\t\t\t\tbuf.WriteString(getenv(s[p:i]))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tp := i\n\t\t\t\tfor ; i < len(rs); i++ {\n\t\t\t\t\tr := rs[i]\n\t\t\t\t\tif r == '\\\\' {\n\t\t\t\t\t\ti++\n\t\t\t\t\t\tif i == len(rs) {\n\t\t\t\t\t\t\treturn s\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif !unicode.IsLetter(r) && r != '_' && !unicode.IsDigit(r) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif i > p {\n\t\t\t\t\tbuf.WriteString(getenv(s[p:i]))\n\t\t\t\t\ti--\n\t\t\t\t} else {\n\t\t\t\t\tbuf.WriteString(s[p:])\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbuf.WriteRune(r)\n\t\t}\n\t}\n\treturn buf.String()\n}\n\ntype Parser struct {\n\tParseEnv      bool\n\tParseBacktick bool\n\tPosition      int\n\tDir           string\n\n\t// If ParseEnv is true, use this for getenv.\n\t// If nil, use os.Getenv.\n\tGetenv func(string) string\n}\n\nfunc NewParser() *Parser {\n\treturn &Parser{\n\t\tParseEnv:      ParseEnv,\n\t\tParseBacktick: ParseBacktick,\n\t\tPosition:      0,\n\t\tDir:           \"\",\n\t}\n}\n\ntype argType int\n\nconst (\n\targNo argType = iota\n\targSingle\n\targQuoted\n)\n\nfunc (p *Parser) Parse(line string) ([]string, error) {\n\targs := []string{}\n\tbuf := \"\"\n\tvar escaped, doubleQuoted, singleQuoted, backQuote, dollarQuote bool\n\tbacktick := \"\"\n\n\tpos := -1\n\tgot := argNo\n\n\ti := -1\nloop:\n\tfor _, r := range line {\n\t\ti++\n\t\tif escaped {\n\t\t\tbuf += string(r)\n\t\t\tescaped = false\n\t\t\tgot = argSingle\n\t\t\tcontinue\n\t\t}\n\n\t\tif r == '\\\\' {\n\t\t\tif singleQuoted {\n\t\t\t\tbuf += string(r)\n\t\t\t} else {\n\t\t\t\tescaped = true\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif isSpace(r) {\n\t\t\tif singleQuoted || doubleQuoted || backQuote || dollarQuote {\n\t\t\t\tbuf += string(r)\n\t\t\t\tbacktick += string(r)\n\t\t\t} else if got != argNo {\n\t\t\t\tif p.ParseEnv {\n\t\t\t\t\tif got == argSingle {\n\t\t\t\t\t\tparser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}\n\t\t\t\t\t\tstrs, err := parser.Parse(replaceEnv(p.Getenv, buf))\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t\t}\n\t\t\t\t\t\targs = append(args, strs...)\n\t\t\t\t\t} else {\n\t\t\t\t\t\targs = append(args, replaceEnv(p.Getenv, buf))\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\targs = append(args, buf)\n\t\t\t\t}\n\t\t\t\tbuf = \"\"\n\t\t\t\tgot = argNo\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch r {\n\t\tcase '`':\n\t\t\tif !singleQuoted && !doubleQuoted && !dollarQuote {\n\t\t\t\tif p.ParseBacktick {\n\t\t\t\t\tif backQuote {\n\t\t\t\t\t\tout, err := shellRun(backtick, p.Dir)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbuf = buf[:len(buf)-len(backtick)] + out\n\t\t\t\t\t}\n\t\t\t\t\tbacktick = \"\"\n\t\t\t\t\tbackQuote = !backQuote\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbacktick = \"\"\n\t\t\t\tbackQuote = !backQuote\n\t\t\t}\n\t\tcase ')':\n\t\t\tif !singleQuoted && !doubleQuoted && !backQuote {\n\t\t\t\tif p.ParseBacktick {\n\t\t\t\t\tif dollarQuote {\n\t\t\t\t\t\tout, err := shellRun(backtick, p.Dir)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbuf = buf[:len(buf)-len(backtick)-2] + out\n\t\t\t\t\t}\n\t\t\t\t\tbacktick = \"\"\n\t\t\t\t\tdollarQuote = !dollarQuote\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbacktick = \"\"\n\t\t\t\tdollarQuote = !dollarQuote\n\t\t\t}\n\t\tcase '(':\n\t\t\tif !singleQuoted && !doubleQuoted && !backQuote {\n\t\t\t\tif !dollarQuote && strings.HasSuffix(buf, \"$\") {\n\t\t\t\t\tdollarQuote = true\n\t\t\t\t\tbuf += \"(\"\n\t\t\t\t\tcontinue\n\t\t\t\t} else {\n\t\t\t\t\treturn nil, errors.New(\"invalid command line string\")\n\t\t\t\t}\n\t\t\t}\n\t\tcase '\"':\n\t\t\tif !singleQuoted && !dollarQuote {\n\t\t\t\tif doubleQuoted {\n\t\t\t\t\tgot = argQuoted\n\t\t\t\t}\n\t\t\t\tdoubleQuoted = !doubleQuoted\n\t\t\t\tcontinue\n\t\t\t}\n\t\tcase '\\'':\n\t\t\tif !doubleQuoted && !dollarQuote {\n\t\t\t\tif singleQuoted {\n\t\t\t\t\tgot = argQuoted\n\t\t\t\t}\n\t\t\t\tsingleQuoted = !singleQuoted\n\t\t\t\tcontinue\n\t\t\t}\n\t\tcase ';', '&', '|', '<', '>':\n\t\t\tif !(escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote) {\n\t\t\t\tif r == '>' && len(buf) > 0 {\n\t\t\t\t\tif c := buf[0]; '0' <= c && c <= '9' {\n\t\t\t\t\t\ti -= 1\n\t\t\t\t\t\tgot = argNo\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tpos = i\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t}\n\n\t\tgot = argSingle\n\t\tbuf += string(r)\n\t\tif backQuote || dollarQuote {\n\t\t\tbacktick += string(r)\n\t\t}\n\t}\n\n\tif got != argNo {\n\t\tif p.ParseEnv {\n\t\t\tif got == argSingle {\n\t\t\t\tparser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir}\n\t\t\t\tstrs, err := parser.Parse(replaceEnv(p.Getenv, buf))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\targs = append(args, strs...)\n\t\t\t} else {\n\t\t\t\targs = append(args, replaceEnv(p.Getenv, buf))\n\t\t\t}\n\t\t} else {\n\t\t\targs = append(args, buf)\n\t\t}\n\t}\n\n\tif escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote {\n\t\treturn nil, errors.New(\"invalid command line string\")\n\t}\n\n\tp.Position = pos\n\n\treturn args, nil\n}\n\nfunc (p *Parser) ParseWithEnvs(line string) (envs []string, args []string, err error) {\n\t_args, err := p.Parse(line)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tenvs = []string{}\n\targs = []string{}\n\tparsingEnv := true\n\tfor _, arg := range _args {\n\t\tif parsingEnv && isEnv(arg) {\n\t\t\tenvs = append(envs, arg)\n\t\t} else {\n\t\t\tif parsingEnv {\n\t\t\t\tparsingEnv = false\n\t\t\t}\n\t\t\targs = append(args, arg)\n\t\t}\n\t}\n\treturn envs, args, nil\n}\n\nfunc isEnv(arg string) bool {\n\treturn len(strings.Split(arg, \"=\")) == 2\n}\n\nfunc Parse(line string) ([]string, error) {\n\treturn NewParser().Parse(line)\n}\n\nfunc ParseWithEnvs(line string) (envs []string, args []string, err error) {\n\treturn NewParser().ParseWithEnvs(line)\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-shellwords/util_posix.go",
    "content": "// +build !windows\n\npackage shellwords\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\nfunc shellRun(line, dir string) (string, error) {\n\tvar shell string\n\tif shell = os.Getenv(\"SHELL\"); shell == \"\" {\n\t\tshell = \"/bin/sh\"\n\t}\n\tcmd := exec.Command(shell, \"-c\", line)\n\tif dir != \"\" {\n\t\tcmd.Dir = dir\n\t}\n\tb, err := cmd.Output()\n\tif err != nil {\n\t\tif eerr, ok := err.(*exec.ExitError); ok {\n\t\t\tb = eerr.Stderr\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"%s: %w\", string(b), err)\n\t}\n\treturn strings.TrimSpace(string(b)), nil\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-shellwords/util_windows.go",
    "content": "// +build windows\n\npackage shellwords\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n)\n\nfunc shellRun(line, dir string) (string, error) {\n\tvar shell string\n\tif shell = os.Getenv(\"COMSPEC\"); shell == \"\" {\n\t\tshell = \"cmd\"\n\t}\n\tcmd := exec.Command(shell, \"/c\", line)\n\tif dir != \"\" {\n\t\tcmd.Dir = dir\n\t}\n\tb, err := cmd.Output()\n\tif err != nil {\n\t\tif eerr, ok := err.(*exec.ExitError); ok {\n\t\t\tb = eerr.Stderr\n\t\t}\n\t\treturn \"\", fmt.Errorf(\"%s: %w\", string(b), err)\n\t}\n\treturn strings.TrimSpace(string(b)), nil\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/.travis.yml",
    "content": "language: go\nsudo: false\ngo:\n  - tip\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2018 Yasuhiro Matsumoto\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": "vendor/github.com/mattn/go-tty/README.md",
    "content": "# go-tty\n\nSimple tty utility\n\n## Usage\n\n```go\ntty, err := tty.Open()\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer tty.Close()\n\nfor {\n\tr, err := tty.ReadRune()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\t// handle key event\n}\n```\n\nif you are on windows and want to display ANSI colors, use <a href=\"https://github.com/mattn/go-colorable\">go-colorable</a>.\n\n```go\ntty, err := tty.Open()\nif err != nil {\n\tlog.Fatal(err)\n}\ndefer tty.Close()\n\nout := colorable.NewColorable(tty.Output())\n\nfmt.Fprintln(out, \"\\x1b[2J\")\n```\n\n## Installation\n\n```\n$ go get github.com/mattn/go-tty\n```\n\n## License\n\nMIT\n\n## Author\n\nYasuhiro Matsumoto (a.k.a mattn)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/tty.go",
    "content": "package tty\n\nimport (\n\t\"os\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nfunc Open() (*TTY, error) {\n\treturn open(\"/dev/tty\")\n}\n\nfunc OpenDevice(path string) (*TTY, error) {\n\treturn open(path)\n}\n\nfunc (tty *TTY) Raw() (func() error, error) {\n\treturn tty.raw()\n}\n\nfunc (tty *TTY) MustRaw() func() error {\n\tf, err := tty.raw()\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\treturn f\n}\n\nfunc (tty *TTY) Buffered() bool {\n\treturn tty.buffered()\n}\n\nfunc (tty *TTY) ReadRune() (rune, error) {\n\treturn tty.readRune()\n}\n\nfunc (tty *TTY) Close() error {\n\treturn tty.close()\n}\n\nfunc (tty *TTY) Size() (int, int, error) {\n\treturn tty.size()\n}\n\nfunc (tty *TTY) SizePixel() (int, int, int, int, error) {\n\treturn tty.sizePixel()\n}\n\nfunc (tty *TTY) Input() *os.File {\n\treturn tty.input()\n}\n\nfunc (tty *TTY) Output() *os.File {\n\treturn tty.output()\n}\n\n// Display types.\nconst (\n\tdisplayNone = iota\n\tdisplayRune\n\tdisplayMask\n)\n\nfunc (tty *TTY) readString(displayType int) (string, error) {\n\trs := []rune{}\nloop:\n\tfor {\n\t\tr, err := tty.readRune()\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tswitch r {\n\t\tcase 13:\n\t\t\tbreak loop\n\t\tcase 8, 127:\n\t\t\tif len(rs) > 0 {\n\t\t\t\trs = rs[:len(rs)-1]\n\t\t\t\tif displayType != displayNone {\n\t\t\t\t\ttty.Output().WriteString(\"\\b \\b\")\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\tif unicode.IsPrint(r) {\n\t\t\t\trs = append(rs, r)\n\t\t\t\tswitch displayType {\n\t\t\t\tcase displayRune:\n\t\t\t\t\ttty.Output().WriteString(string(r))\n\t\t\t\tcase displayMask:\n\t\t\t\t\ttty.Output().WriteString(\"*\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn string(rs), nil\n}\n\nfunc (tty *TTY) ReadString() (string, error) {\n\tdefer tty.Output().WriteString(\"\\n\")\n\treturn tty.readString(displayRune)\n}\n\nfunc (tty *TTY) ReadPassword() (string, error) {\n\tdefer tty.Output().WriteString(\"\\n\")\n\treturn tty.readString(displayMask)\n}\n\nfunc (tty *TTY) ReadPasswordNoEcho() (string, error) {\n\tdefer tty.Output().WriteString(\"\\n\")\n\treturn tty.readString(displayNone)\n}\n\nfunc (tty *TTY) ReadPasswordClear() (string, error) {\n\ts, err := tty.readString(displayMask)\n\ttty.Output().WriteString(\n\t\tstrings.Repeat(\"\\b\", len(s)) +\n\t\t\tstrings.Repeat(\" \", len(s)) +\n\t\t\tstrings.Repeat(\"\\b\", len(s)))\n\treturn s, err\n}\n\ntype WINSIZE struct {\n\tW int\n\tH int\n}\n\nfunc (tty *TTY) SIGWINCH() <-chan WINSIZE {\n\treturn tty.sigwinch()\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/tty_bsd.go",
    "content": "// +build darwin dragonfly freebsd netbsd openbsd\n\npackage tty\n\nimport (\n\t\"syscall\"\n)\n\nconst (\n\tioctlReadTermios  = syscall.TIOCGETA\n\tioctlWriteTermios = syscall.TIOCSETA\n)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/tty_linux.go",
    "content": "// +build linux\n\npackage tty\n\nconst (\n\tioctlReadTermios  = 0x5401 // syscall.TCGETS\n\tioctlWriteTermios = 0x5402 // syscall.TCSETS\n)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/tty_plan9.go",
    "content": "package tty\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n)\n\ntype TTY struct {\n\tin  *os.File\n\tbin *bufio.Reader\n\tout *os.File\n}\n\nfunc open(path string) (*TTY, error) {\n\ttty := new(TTY)\n\n\tin, err := os.Open(\"/dev/cons\")\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttty.in = in\n\ttty.bin = bufio.NewReader(in)\n\n\tout, err := os.OpenFile(\"/dev/cons\", syscall.O_WRONLY, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttty.out = out\n\n\treturn tty, nil\n}\n\nfunc (tty *TTY) buffered() bool {\n\treturn tty.bin.Buffered() > 0\n}\n\nfunc (tty *TTY) readRune() (rune, error) {\n\tr, _, err := tty.bin.ReadRune()\n\treturn r, err\n}\n\nfunc (tty *TTY) close() (err error) {\n\tif err2 := tty.in.Close(); err2 != nil {\n\t\terr = err2\n\t}\n\tif err2 := tty.out.Close(); err2 != nil {\n\t\terr = err2\n\t}\n\treturn\n}\n\nfunc (tty *TTY) size() (int, int, error) {\n\treturn 80, 24, nil\n}\n\nfunc (tty *TTY) sizePixel() (int, int, int, int, error) {\n\tx, y, _ := tty.size()\n\treturn x, y, -1, -1, errors.New(\"no implemented method for querying size in pixels on Plan 9\")\n}\n\nfunc (tty *TTY) input() *os.File {\n\treturn tty.in\n}\n\nfunc (tty *TTY) output() *os.File {\n\treturn tty.out\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/tty_sys5.go",
    "content": "// +build solaris\n\npackage tty\n\nimport (\n\t\"golang.org/x/sys/unix\"\n)\n\nconst (\n\tioctlReadTermios  = unix.TCGETA\n\tioctlWriteTermios = unix.TCSETA\n)\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/tty_unix.go",
    "content": "// +build !windows\n// +build !plan9\n\npackage tty\n\nimport (\n\t\"bufio\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\ntype TTY struct {\n\tin      *os.File\n\tbin     *bufio.Reader\n\tout     *os.File\n\ttermios syscall.Termios\n\tss      chan os.Signal\n}\n\nfunc open(path string) (*TTY, error) {\n\ttty := new(TTY)\n\n\tin, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttty.in = in\n\ttty.bin = bufio.NewReader(in)\n\n\tout, err := os.OpenFile(path, syscall.O_WRONLY, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttty.out = out\n\n\tif _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(tty.in.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&tty.termios))); err != 0 {\n\t\treturn nil, err\n\t}\n\tnewios := tty.termios\n\tnewios.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXOFF\n\tnewios.Lflag &^= syscall.ECHO | syscall.ICANON /*| syscall.ISIG*/\n\tif _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(tty.in.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&newios))); err != 0 {\n\t\treturn nil, err\n\t}\n\n\ttty.ss = make(chan os.Signal, 1)\n\n\treturn tty, nil\n}\n\nfunc (tty *TTY) buffered() bool {\n\treturn tty.bin.Buffered() > 0\n}\n\nfunc (tty *TTY) readRune() (rune, error) {\n\tr, _, err := tty.bin.ReadRune()\n\treturn r, err\n}\n\nfunc (tty *TTY) close() error {\n\tsignal.Stop(tty.ss)\n\tclose(tty.ss)\n\t_, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(tty.in.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&tty.termios)))\n\treturn err\n}\n\nfunc (tty *TTY) size() (int, int, error) {\n\tx, y, _, _, err := tty.sizePixel()\n\treturn x, y, err\n}\n\nfunc (tty *TTY) sizePixel() (int, int, int, int, error) {\n\tvar dim [4]uint16\n\tif _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(tty.out.Fd()), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dim))); err != 0 {\n\t\treturn -1, -1, -1, -1, err\n\t}\n\treturn int(dim[1]), int(dim[0]), int(dim[2]), int(dim[3]), nil\n}\n\nfunc (tty *TTY) input() *os.File {\n\treturn tty.in\n}\n\nfunc (tty *TTY) output() *os.File {\n\treturn tty.out\n}\n\nfunc (tty *TTY) raw() (func() error, error) {\n\ttermios, err := unix.IoctlGetTermios(int(tty.in.Fd()), ioctlReadTermios)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbackup := *termios\n\n\ttermios.Iflag &^= unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON\n\ttermios.Oflag &^= unix.OPOST\n\ttermios.Lflag &^= unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN\n\ttermios.Cflag &^= unix.CSIZE | unix.PARENB\n\ttermios.Cflag |= unix.CS8\n\ttermios.Cc[unix.VMIN] = 1\n\ttermios.Cc[unix.VTIME] = 0\n\tif err := unix.IoctlSetTermios(int(tty.in.Fd()), ioctlWriteTermios, termios); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn func() error {\n\t\tif err := unix.IoctlSetTermios(int(tty.in.Fd()), ioctlWriteTermios, &backup); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}, nil\n}\n\nfunc (tty *TTY) sigwinch() <-chan WINSIZE {\n\tsignal.Notify(tty.ss, syscall.SIGWINCH)\n\n\tws := make(chan WINSIZE)\n\tgo func() {\n\t\tdefer close(ws)\n\t\tfor sig := range tty.ss {\n\t\t\tif sig != syscall.SIGWINCH {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tw, h, err := tty.size()\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// send but do not block for it\n\t\t\tselect {\n\t\t\tcase ws <- WINSIZE{W: w, H: h}:\n\t\t\tdefault:\n\t\t\t}\n\n\t\t}\n\t}()\n\treturn ws\n}\n"
  },
  {
    "path": "vendor/github.com/mattn/go-tty/tty_windows.go",
    "content": "// +build windows\n\npackage tty\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"os\"\n\t\"syscall\"\n\t\"unsafe\"\n\n\t\"github.com/mattn/go-isatty\"\n)\n\nconst (\n\trightAltPressed  = 1\n\tleftAltPressed   = 2\n\trightCtrlPressed = 4\n\tleftCtrlPressed  = 8\n\tshiftPressed     = 0x0010\n\tctrlPressed      = rightCtrlPressed | leftCtrlPressed\n\taltPressed       = rightAltPressed | leftAltPressed\n)\n\nconst (\n\tenableProcessedInput = 0x1\n\tenableLineInput      = 0x2\n\tenableEchoInput      = 0x4\n\tenableWindowInput    = 0x8\n\tenableMouseInput     = 0x10\n\tenableInsertMode     = 0x20\n\tenableQuickEditMode  = 0x40\n\tenableExtendedFlag   = 0x80\n\n\tenableProcessedOutput = 1\n\tenableWrapAtEolOutput = 2\n\n\tkeyEvent              = 0x1\n\tmouseEvent            = 0x2\n\twindowBufferSizeEvent = 0x4\n)\n\nvar kernel32 = syscall.NewLazyDLL(\"kernel32.dll\")\n\nvar (\n\tprocAllocConsole                = kernel32.NewProc(\"AllocConsole\")\n\tprocSetStdHandle                = kernel32.NewProc(\"SetStdHandle\")\n\tprocGetStdHandle                = kernel32.NewProc(\"GetStdHandle\")\n\tprocSetConsoleScreenBufferSize  = kernel32.NewProc(\"SetConsoleScreenBufferSize\")\n\tprocCreateConsoleScreenBuffer   = kernel32.NewProc(\"CreateConsoleScreenBuffer\")\n\tprocGetConsoleScreenBufferInfo  = kernel32.NewProc(\"GetConsoleScreenBufferInfo\")\n\tprocWriteConsoleOutputCharacter = kernel32.NewProc(\"WriteConsoleOutputCharacterW\")\n\tprocWriteConsoleOutputAttribute = kernel32.NewProc(\"WriteConsoleOutputAttribute\")\n\tprocGetConsoleCursorInfo        = kernel32.NewProc(\"GetConsoleCursorInfo\")\n\tprocSetConsoleCursorInfo        = kernel32.NewProc(\"SetConsoleCursorInfo\")\n\tprocSetConsoleCursorPosition    = kernel32.NewProc(\"SetConsoleCursorPosition\")\n\tprocReadConsoleInput            = kernel32.NewProc(\"ReadConsoleInputW\")\n\tprocGetConsoleMode              = kernel32.NewProc(\"GetConsoleMode\")\n\tprocSetConsoleMode              = kernel32.NewProc(\"SetConsoleMode\")\n\tprocFillConsoleOutputCharacter  = kernel32.NewProc(\"FillConsoleOutputCharacterW\")\n\tprocFillConsoleOutputAttribute  = kernel32.NewProc(\"FillConsoleOutputAttribute\")\n\tprocScrollConsoleScreenBuffer   = kernel32.NewProc(\"ScrollConsoleScreenBufferW\")\n)\n\ntype wchar uint16\ntype short int16\ntype dword uint32\ntype word uint16\n\ntype coord struct {\n\tx short\n\ty short\n}\n\ntype smallRect struct {\n\tleft   short\n\ttop    short\n\tright  short\n\tbottom short\n}\n\ntype consoleScreenBufferInfo struct {\n\tsize              coord\n\tcursorPosition    coord\n\tattributes        word\n\twindow            smallRect\n\tmaximumWindowSize coord\n}\n\ntype consoleCursorInfo struct {\n\tsize    dword\n\tvisible int32\n}\n\ntype inputRecord struct {\n\teventType word\n\t_         [2]byte\n\tevent     [16]byte\n}\n\ntype keyEventRecord struct {\n\tkeyDown         int32\n\trepeatCount     word\n\tvirtualKeyCode  word\n\tvirtualScanCode word\n\tunicodeChar     wchar\n\tcontrolKeyState dword\n}\n\ntype windowBufferSizeRecord struct {\n\tsize coord\n}\n\ntype mouseEventRecord struct {\n\tmousePos        coord\n\tbuttonState     dword\n\tcontrolKeyState dword\n\teventFlags      dword\n}\n\ntype charInfo struct {\n\tunicodeChar wchar\n\tattributes  word\n}\n\ntype TTY struct {\n\tin                *os.File\n\tout               *os.File\n\tst                uint32\n\trs                []rune\n\tws                chan WINSIZE\n\tsigwinchCtx       context.Context\n\tsigwinchCtxCancel context.CancelFunc\n}\n\nfunc readConsoleInput(fd uintptr, record *inputRecord) (err error) {\n\tvar w uint32\n\tr1, _, err := procReadConsoleInput.Call(fd, uintptr(unsafe.Pointer(record)), 1, uintptr(unsafe.Pointer(&w)))\n\tif r1 == 0 {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc open(path string) (*TTY, error) {\n\ttty := new(TTY)\n\tif false && isatty.IsTerminal(os.Stdin.Fd()) {\n\t\ttty.in = os.Stdin\n\t} else {\n\t\tin, err := syscall.Open(\"CONIN$\", syscall.O_RDWR, 0)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\ttty.in = os.NewFile(uintptr(in), \"/dev/tty\")\n\t}\n\n\tif isatty.IsTerminal(os.Stdout.Fd()) {\n\t\ttty.out = os.Stdout\n\t} else {\n\t\tprocAllocConsole.Call()\n\t\tout, err := syscall.Open(\"CONOUT$\", syscall.O_RDWR, 0)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\ttty.out = os.NewFile(uintptr(out), \"/dev/tty\")\n\t}\n\n\th := tty.in.Fd()\n\tvar st uint32\n\tr1, _, err := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&st)))\n\tif r1 == 0 {\n\t\treturn nil, err\n\t}\n\ttty.st = st\n\n\tst &^= enableEchoInput\n\tst &^= enableInsertMode\n\tst &^= enableLineInput\n\tst &^= enableMouseInput\n\tst &^= enableWindowInput\n\tst &^= enableExtendedFlag\n\tst &^= enableQuickEditMode\n\n\t// ignore error\n\tprocSetConsoleMode.Call(h, uintptr(st))\n\n\ttty.ws = make(chan WINSIZE)\n\ttty.sigwinchCtx, tty.sigwinchCtxCancel = context.WithCancel(context.Background())\n\n\treturn tty, nil\n}\n\nfunc (tty *TTY) buffered() bool {\n\treturn len(tty.rs) > 0\n}\n\nfunc (tty *TTY) readRune() (rune, error) {\n\tif len(tty.rs) > 0 {\n\t\tr := tty.rs[0]\n\t\ttty.rs = tty.rs[1:]\n\t\treturn r, nil\n\t}\n\tvar ir inputRecord\n\terr := readConsoleInput(tty.in.Fd(), &ir)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tswitch ir.eventType {\n\tcase windowBufferSizeEvent:\n\t\twr := (*windowBufferSizeRecord)(unsafe.Pointer(&ir.event))\n\t\tws := WINSIZE{\n\t\t\tW: int(wr.size.x),\n\t\t\tH: int(wr.size.y),\n\t\t}\n\n\t\tif err := tty.sigwinchCtx.Err(); err != nil {\n\t\t\t// closing\n\t\t\t// the following select might panic without this guard close\n\t\t\treturn 0, err\n\t\t}\n\n\t\tselect {\n\t\tcase tty.ws <- ws:\n\t\tcase <-tty.sigwinchCtx.Done():\n\t\t\treturn 0, tty.sigwinchCtx.Err()\n\t\tdefault:\n\t\t\treturn 0, nil // no one is currently trying to read\n\t\t}\n\tcase keyEvent:\n\t\tkr := (*keyEventRecord)(unsafe.Pointer(&ir.event))\n\t\tif kr.keyDown != 0 {\n\t\t\tif kr.controlKeyState&altPressed != 0 && kr.unicodeChar > 0 {\n\t\t\t\ttty.rs = []rune{rune(kr.unicodeChar)}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\t}\n\t\t\tif kr.unicodeChar > 0 {\n\t\t\t\tif kr.controlKeyState&shiftPressed != 0 {\n\t\t\t\t\tswitch kr.unicodeChar {\n\t\t\t\t\tcase 0x09:\n\t\t\t\t\t\ttty.rs = []rune{0x5b, 0x5a}\n\t\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn rune(kr.unicodeChar), nil\n\t\t\t}\n\t\t\tvk := kr.virtualKeyCode\n\t\t\tif kr.controlKeyState&ctrlPressed != 0 {\n\t\t\t\tswitch vk {\n\t\t\t\tcase 0x21: // ctrl-page-up\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x35, 0x3B, 0x35, 0x7e}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x22: // ctrl-page-down\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x36, 0x3B, 0x35, 0x7e}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x23: // ctrl-end\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x31, 0x3B, 0x35, 0x46}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x24: // ctrl-home\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x31, 0x3B, 0x35, 0x48}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x25: // ctrl-left\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x31, 0x3B, 0x35, 0x44}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x26: // ctrl-up\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x31, 0x3B, 0x35, 0x41}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x27: // ctrl-right\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x31, 0x3B, 0x35, 0x43}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x28: // ctrl-down\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x31, 0x3B, 0x35, 0x42}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\tcase 0x2e: // ctrl-delete\n\t\t\t\t\ttty.rs = []rune{0x5b, 0x33, 0x3B, 0x35, 0x7e}\n\t\t\t\t\treturn rune(0x1b), nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch vk {\n\t\t\tcase 0x21: // page-up\n\t\t\t\ttty.rs = []rune{0x5b, 0x35, 0x7e}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x22: // page-down\n\t\t\t\ttty.rs = []rune{0x5b, 0x36, 0x7e}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x23: // end\n\t\t\t\ttty.rs = []rune{0x5b, 0x46}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x24: // home\n\t\t\t\ttty.rs = []rune{0x5b, 0x48}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x25: // left\n\t\t\t\ttty.rs = []rune{0x5b, 0x44}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x26: // up\n\t\t\t\ttty.rs = []rune{0x5b, 0x41}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x27: // right\n\t\t\t\ttty.rs = []rune{0x5b, 0x43}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x28: // down\n\t\t\t\ttty.rs = []rune{0x5b, 0x42}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x2e: // delete\n\t\t\t\ttty.rs = []rune{0x5b, 0x33, 0x7e}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x70, 0x71, 0x72, 0x73: // F1,F2,F3,F4\n\t\t\t\ttty.rs = []rune{0x5b, 0x4f, rune(vk) - 0x20}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x074, 0x75, 0x76, 0x77: // F5,F6,F7,F8\n\t\t\t\ttty.rs = []rune{0x5b, 0x31, rune(vk) - 0x3f, 0x7e}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x78, 0x79: // F9,F10\n\t\t\t\ttty.rs = []rune{0x5b, 0x32, rune(vk) - 0x48, 0x7e}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\tcase 0x7a, 0x7b: // F11,F12\n\t\t\t\ttty.rs = []rune{0x5b, 0x32, rune(vk) - 0x47, 0x7e}\n\t\t\t\treturn rune(0x1b), nil\n\t\t\t}\n\t\t\treturn 0, nil\n\t\t}\n\t}\n\treturn 0, nil\n}\n\nfunc (tty *TTY) close() error {\n\tprocSetConsoleMode.Call(tty.in.Fd(), uintptr(tty.st))\n\ttty.sigwinchCtxCancel()\n\tclose(tty.ws)\n\treturn nil\n}\n\nfunc (tty *TTY) size() (int, int, error) {\n\tvar csbi consoleScreenBufferInfo\n\tr1, _, err := procGetConsoleScreenBufferInfo.Call(tty.out.Fd(), uintptr(unsafe.Pointer(&csbi)))\n\tif r1 == 0 {\n\t\treturn 0, 0, err\n\t}\n\treturn int(csbi.window.right - csbi.window.left + 1), int(csbi.window.bottom - csbi.window.top + 1), nil\n}\n\nfunc (tty *TTY) sizePixel() (int, int, int, int, error) {\n\tx, y, err := tty.size()\n\tif err != nil {\n\t\tx = -1\n\t\ty = -1\n\t}\n\treturn x, y, -1, -1, errors.New(\"no implemented method for querying size in pixels on Windows\")\n}\n\nfunc (tty *TTY) input() *os.File {\n\treturn tty.in\n}\n\nfunc (tty *TTY) output() *os.File {\n\treturn tty.out\n}\n\nfunc (tty *TTY) raw() (func() error, error) {\n\tvar st uint32\n\tr1, _, err := procGetConsoleMode.Call(tty.in.Fd(), uintptr(unsafe.Pointer(&st)))\n\tif r1 == 0 {\n\t\treturn nil, err\n\t}\n\tmode := st &^ (enableEchoInput | enableProcessedInput | enableLineInput | enableProcessedOutput)\n\tr1, _, err = procSetConsoleMode.Call(tty.in.Fd(), uintptr(mode))\n\tif r1 == 0 {\n\t\treturn nil, err\n\t}\n\treturn func() error {\n\t\tr1, _, err := procSetConsoleMode.Call(tty.in.Fd(), uintptr(st))\n\t\tif r1 == 0 {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}, nil\n}\n\nfunc (tty *TTY) sigwinch() <-chan WINSIZE {\n\treturn tty.ws\n}\n"
  },
  {
    "path": "vendor/github.com/mitchellh/go-homedir/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Mitchell Hashimoto\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/mitchellh/go-homedir/README.md",
    "content": "# go-homedir\n\nThis is a Go library for detecting the user's home directory without\nthe use of cgo, so the library can be used in cross-compilation environments.\n\nUsage is incredibly simple, just call `homedir.Dir()` to get the home directory\nfor a user, and `homedir.Expand()` to expand the `~` in a path to the home\ndirectory.\n\n**Why not just use `os/user`?** The built-in `os/user` package requires\ncgo on Darwin systems. This means that any Go code that uses that package\ncannot cross compile. But 99% of the time the use for `os/user` is just to\nretrieve the home directory, which we can do for the current user without\ncgo. This library does that, enabling cross-compilation.\n"
  },
  {
    "path": "vendor/github.com/mitchellh/go-homedir/homedir.go",
    "content": "package homedir\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// DisableCache will disable caching of the home directory. Caching is enabled\n// by default.\nvar DisableCache bool\n\nvar homedirCache string\nvar cacheLock sync.RWMutex\n\n// Dir returns the home directory for the executing user.\n//\n// This uses an OS-specific method for discovering the home directory.\n// An error is returned if a home directory cannot be detected.\nfunc Dir() (string, error) {\n\tif !DisableCache {\n\t\tcacheLock.RLock()\n\t\tcached := homedirCache\n\t\tcacheLock.RUnlock()\n\t\tif cached != \"\" {\n\t\t\treturn cached, nil\n\t\t}\n\t}\n\n\tcacheLock.Lock()\n\tdefer cacheLock.Unlock()\n\n\tvar result string\n\tvar err error\n\tif runtime.GOOS == \"windows\" {\n\t\tresult, err = dirWindows()\n\t} else {\n\t\t// Unix-like system, so just assume Unix\n\t\tresult, err = dirUnix()\n\t}\n\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\thomedirCache = result\n\treturn result, nil\n}\n\n// Expand expands the path to include the home directory if the path\n// is prefixed with `~`. If it isn't prefixed with `~`, the path is\n// returned as-is.\nfunc Expand(path string) (string, error) {\n\tif len(path) == 0 {\n\t\treturn path, nil\n\t}\n\n\tif path[0] != '~' {\n\t\treturn path, nil\n\t}\n\n\tif len(path) > 1 && path[1] != '/' && path[1] != '\\\\' {\n\t\treturn \"\", errors.New(\"cannot expand user-specific home dir\")\n\t}\n\n\tdir, err := Dir()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn filepath.Join(dir, path[1:]), nil\n}\n\n// Reset clears the cache, forcing the next call to Dir to re-detect\n// the home directory. This generally never has to be called, but can be\n// useful in tests if you're modifying the home directory via the HOME\n// env var or something.\nfunc Reset() {\n\tcacheLock.Lock()\n\tdefer cacheLock.Unlock()\n\thomedirCache = \"\"\n}\n\nfunc dirUnix() (string, error) {\n\thomeEnv := \"HOME\"\n\tif runtime.GOOS == \"plan9\" {\n\t\t// On plan9, env vars are lowercase.\n\t\thomeEnv = \"home\"\n\t}\n\n\t// First prefer the HOME environmental variable\n\tif home := os.Getenv(homeEnv); home != \"\" {\n\t\treturn home, nil\n\t}\n\n\tvar stdout bytes.Buffer\n\n\t// If that fails, try OS specific commands\n\tif runtime.GOOS == \"darwin\" {\n\t\tcmd := exec.Command(\"sh\", \"-c\", `dscl -q . -read /Users/\"$(whoami)\" NFSHomeDirectory | sed 's/^[^ ]*: //'`)\n\t\tcmd.Stdout = &stdout\n\t\tif err := cmd.Run(); err == nil {\n\t\t\tresult := strings.TrimSpace(stdout.String())\n\t\t\tif result != \"\" {\n\t\t\t\treturn result, nil\n\t\t\t}\n\t\t}\n\t} else {\n\t\tcmd := exec.Command(\"getent\", \"passwd\", strconv.Itoa(os.Getuid()))\n\t\tcmd.Stdout = &stdout\n\t\tif err := cmd.Run(); err != nil {\n\t\t\t// If the error is ErrNotFound, we ignore it. Otherwise, return it.\n\t\t\tif err != exec.ErrNotFound {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t} else {\n\t\t\tif passwd := strings.TrimSpace(stdout.String()); passwd != \"\" {\n\t\t\t\t// username:password:uid:gid:gecos:home:shell\n\t\t\t\tpasswdParts := strings.SplitN(passwd, \":\", 7)\n\t\t\t\tif len(passwdParts) > 5 {\n\t\t\t\t\treturn passwdParts[5], nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If all else fails, try the shell\n\tstdout.Reset()\n\tcmd := exec.Command(\"sh\", \"-c\", \"cd && pwd\")\n\tcmd.Stdout = &stdout\n\tif err := cmd.Run(); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tresult := strings.TrimSpace(stdout.String())\n\tif result == \"\" {\n\t\treturn \"\", errors.New(\"blank output when reading home directory\")\n\t}\n\n\treturn result, nil\n}\n\nfunc dirWindows() (string, error) {\n\t// First prefer the HOME environmental variable\n\tif home := os.Getenv(\"HOME\"); home != \"\" {\n\t\treturn home, nil\n\t}\n\n\t// Prefer standard environment variable USERPROFILE\n\tif home := os.Getenv(\"USERPROFILE\"); home != \"\" {\n\t\treturn home, nil\n\t}\n\n\tdrive := os.Getenv(\"HOMEDRIVE\")\n\tpath := os.Getenv(\"HOMEPATH\")\n\thome := drive + path\n\tif drive == \"\" || path == \"\" {\n\t\treturn \"\", errors.New(\"HOMEDRIVE, HOMEPATH, or USERPROFILE are blank\")\n\t}\n\n\treturn home, nil\n}\n"
  },
  {
    "path": "vendor/github.com/mitchellh/mapstructure/CHANGELOG.md",
    "content": "## 1.4.3\n\n* Fix cases where `json.Number` didn't decode properly [GH-261]\n\n## 1.4.2\n\n* Custom name matchers to support any sort of casing, formatting, etc. for\n  field names. [GH-250]\n* Fix possible panic in ComposeDecodeHookFunc [GH-251]\n\n## 1.4.1\n\n* Fix regression where `*time.Time` value would be set to empty and not be sent\n  to decode hooks properly [GH-232]\n\n## 1.4.0\n\n* A new decode hook type `DecodeHookFuncValue` has been added that has\n  access to the full values. [GH-183]\n* Squash is now supported with embedded fields that are struct pointers [GH-205]\n* Empty strings will convert to 0 for all numeric types when weakly decoding [GH-206]\n\n## 1.3.3\n\n* Decoding maps from maps creates a settable value for decode hooks [GH-203]\n\n## 1.3.2\n\n* Decode into interface type with a struct value is supported [GH-187]\n\n## 1.3.1\n\n* Squash should only squash embedded structs. [GH-194]\n\n## 1.3.0\n\n* Added `\",omitempty\"` support. This will ignore zero values in the source\n  structure when encoding. [GH-145]\n\n## 1.2.3\n\n* Fix duplicate entries in Keys list with pointer values. [GH-185]\n\n## 1.2.2\n\n* Do not add unsettable (unexported) values to the unused metadata key\n  or \"remain\" value. [GH-150]\n\n## 1.2.1\n\n* Go modules checksum mismatch fix\n\n## 1.2.0\n\n* Added support to capture unused values in a field using the `\",remain\"` value\n  in the mapstructure tag. There is an example to showcase usage.\n* Added `DecoderConfig` option to always squash embedded structs\n* `json.Number` can decode into `uint` types\n* Empty slices are preserved and not replaced with nil slices\n* Fix panic that can occur in when decoding a map into a nil slice of structs\n* Improved package documentation for godoc\n\n## 1.1.2\n\n* Fix error when decode hook decodes interface implementation into interface\n  type. [GH-140]\n\n## 1.1.1\n\n* Fix panic that can happen in `decodePtr`\n\n## 1.1.0\n\n* Added `StringToIPHookFunc` to convert `string` to `net.IP` and `net.IPNet` [GH-133]\n* Support struct to struct decoding [GH-137]\n* If source map value is nil, then destination map value is nil (instead of empty)\n* If source slice value is nil, then destination slice value is nil (instead of empty)\n* If source pointer is nil, then destination pointer is set to nil (instead of\n  allocated zero value of type)\n\n## 1.0.0\n\n* Initial tagged stable release.\n"
  },
  {
    "path": "vendor/github.com/mitchellh/mapstructure/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Mitchell Hashimoto\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/mitchellh/mapstructure/README.md",
    "content": "# mapstructure [![Godoc](https://godoc.org/github.com/mitchellh/mapstructure?status.svg)](https://godoc.org/github.com/mitchellh/mapstructure)\n\nmapstructure is a Go library for decoding generic map values to structures\nand vice versa, while providing helpful error handling.\n\nThis library is most useful when decoding values from some data stream (JSON,\nGob, etc.) where you don't _quite_ know the structure of the underlying data\nuntil you read a part of it. You can therefore read a `map[string]interface{}`\nand use this library to decode it into the proper underlying native Go\nstructure.\n\n## Installation\n\nStandard `go get`:\n\n```\n$ go get github.com/mitchellh/mapstructure\n```\n\n## Usage & Example\n\nFor usage and examples see the [Godoc](http://godoc.org/github.com/mitchellh/mapstructure).\n\nThe `Decode` function has examples associated with it there.\n\n## But Why?!\n\nGo offers fantastic standard libraries for decoding formats such as JSON.\nThe standard method is to have a struct pre-created, and populate that struct\nfrom the bytes of the encoded format. This is great, but the problem is if\nyou have configuration or an encoding that changes slightly depending on\nspecific fields. For example, consider this JSON:\n\n```json\n{\n  \"type\": \"person\",\n  \"name\": \"Mitchell\"\n}\n```\n\nPerhaps we can't populate a specific structure without first reading\nthe \"type\" field from the JSON. We could always do two passes over the\ndecoding of the JSON (reading the \"type\" first, and the rest later).\nHowever, it is much simpler to just decode this into a `map[string]interface{}`\nstructure, read the \"type\" key, then use something like this library\nto decode it into the proper structure.\n"
  },
  {
    "path": "vendor/github.com/mitchellh/mapstructure/decode_hooks.go",
    "content": "package mapstructure\n\nimport (\n\t\"encoding\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// typedDecodeHook takes a raw DecodeHookFunc (an interface{}) and turns\n// it into the proper DecodeHookFunc type, such as DecodeHookFuncType.\nfunc typedDecodeHook(h DecodeHookFunc) DecodeHookFunc {\n\t// Create variables here so we can reference them with the reflect pkg\n\tvar f1 DecodeHookFuncType\n\tvar f2 DecodeHookFuncKind\n\tvar f3 DecodeHookFuncValue\n\n\t// Fill in the variables into this interface and the rest is done\n\t// automatically using the reflect package.\n\tpotential := []interface{}{f1, f2, f3}\n\n\tv := reflect.ValueOf(h)\n\tvt := v.Type()\n\tfor _, raw := range potential {\n\t\tpt := reflect.ValueOf(raw).Type()\n\t\tif vt.ConvertibleTo(pt) {\n\t\t\treturn v.Convert(pt).Interface()\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// DecodeHookExec executes the given decode hook. This should be used\n// since it'll naturally degrade to the older backwards compatible DecodeHookFunc\n// that took reflect.Kind instead of reflect.Type.\nfunc DecodeHookExec(\n\traw DecodeHookFunc,\n\tfrom reflect.Value, to reflect.Value) (interface{}, error) {\n\n\tswitch f := typedDecodeHook(raw).(type) {\n\tcase DecodeHookFuncType:\n\t\treturn f(from.Type(), to.Type(), from.Interface())\n\tcase DecodeHookFuncKind:\n\t\treturn f(from.Kind(), to.Kind(), from.Interface())\n\tcase DecodeHookFuncValue:\n\t\treturn f(from, to)\n\tdefault:\n\t\treturn nil, errors.New(\"invalid decode hook signature\")\n\t}\n}\n\n// ComposeDecodeHookFunc creates a single DecodeHookFunc that\n// automatically composes multiple DecodeHookFuncs.\n//\n// The composed funcs are called in order, with the result of the\n// previous transformation.\nfunc ComposeDecodeHookFunc(fs ...DecodeHookFunc) DecodeHookFunc {\n\treturn func(f reflect.Value, t reflect.Value) (interface{}, error) {\n\t\tvar err error\n\t\tdata := f.Interface()\n\n\t\tnewFrom := f\n\t\tfor _, f1 := range fs {\n\t\t\tdata, err = DecodeHookExec(f1, newFrom, t)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tnewFrom = reflect.ValueOf(data)\n\t\t}\n\n\t\treturn data, nil\n\t}\n}\n\n// StringToSliceHookFunc returns a DecodeHookFunc that converts\n// string to []string by splitting on the given sep.\nfunc StringToSliceHookFunc(sep string) DecodeHookFunc {\n\treturn func(\n\t\tf reflect.Kind,\n\t\tt reflect.Kind,\n\t\tdata interface{}) (interface{}, error) {\n\t\tif f != reflect.String || t != reflect.Slice {\n\t\t\treturn data, nil\n\t\t}\n\n\t\traw := data.(string)\n\t\tif raw == \"\" {\n\t\t\treturn []string{}, nil\n\t\t}\n\n\t\treturn strings.Split(raw, sep), nil\n\t}\n}\n\n// StringToTimeDurationHookFunc returns a DecodeHookFunc that converts\n// strings to time.Duration.\nfunc StringToTimeDurationHookFunc() DecodeHookFunc {\n\treturn func(\n\t\tf reflect.Type,\n\t\tt reflect.Type,\n\t\tdata interface{}) (interface{}, error) {\n\t\tif f.Kind() != reflect.String {\n\t\t\treturn data, nil\n\t\t}\n\t\tif t != reflect.TypeOf(time.Duration(5)) {\n\t\t\treturn data, nil\n\t\t}\n\n\t\t// Convert it by parsing\n\t\treturn time.ParseDuration(data.(string))\n\t}\n}\n\n// StringToIPHookFunc returns a DecodeHookFunc that converts\n// strings to net.IP\nfunc StringToIPHookFunc() DecodeHookFunc {\n\treturn func(\n\t\tf reflect.Type,\n\t\tt reflect.Type,\n\t\tdata interface{}) (interface{}, error) {\n\t\tif f.Kind() != reflect.String {\n\t\t\treturn data, nil\n\t\t}\n\t\tif t != reflect.TypeOf(net.IP{}) {\n\t\t\treturn data, nil\n\t\t}\n\n\t\t// Convert it by parsing\n\t\tip := net.ParseIP(data.(string))\n\t\tif ip == nil {\n\t\t\treturn net.IP{}, fmt.Errorf(\"failed parsing ip %v\", data)\n\t\t}\n\n\t\treturn ip, nil\n\t}\n}\n\n// StringToIPNetHookFunc returns a DecodeHookFunc that converts\n// strings to net.IPNet\nfunc StringToIPNetHookFunc() DecodeHookFunc {\n\treturn func(\n\t\tf reflect.Type,\n\t\tt reflect.Type,\n\t\tdata interface{}) (interface{}, error) {\n\t\tif f.Kind() != reflect.String {\n\t\t\treturn data, nil\n\t\t}\n\t\tif t != reflect.TypeOf(net.IPNet{}) {\n\t\t\treturn data, nil\n\t\t}\n\n\t\t// Convert it by parsing\n\t\t_, net, err := net.ParseCIDR(data.(string))\n\t\treturn net, err\n\t}\n}\n\n// StringToTimeHookFunc returns a DecodeHookFunc that converts\n// strings to time.Time.\nfunc StringToTimeHookFunc(layout string) DecodeHookFunc {\n\treturn func(\n\t\tf reflect.Type,\n\t\tt reflect.Type,\n\t\tdata interface{}) (interface{}, error) {\n\t\tif f.Kind() != reflect.String {\n\t\t\treturn data, nil\n\t\t}\n\t\tif t != reflect.TypeOf(time.Time{}) {\n\t\t\treturn data, nil\n\t\t}\n\n\t\t// Convert it by parsing\n\t\treturn time.Parse(layout, data.(string))\n\t}\n}\n\n// WeaklyTypedHook is a DecodeHookFunc which adds support for weak typing to\n// the decoder.\n//\n// Note that this is significantly different from the WeaklyTypedInput option\n// of the DecoderConfig.\nfunc WeaklyTypedHook(\n\tf reflect.Kind,\n\tt reflect.Kind,\n\tdata interface{}) (interface{}, error) {\n\tdataVal := reflect.ValueOf(data)\n\tswitch t {\n\tcase reflect.String:\n\t\tswitch f {\n\t\tcase reflect.Bool:\n\t\t\tif dataVal.Bool() {\n\t\t\t\treturn \"1\", nil\n\t\t\t}\n\t\t\treturn \"0\", nil\n\t\tcase reflect.Float32:\n\t\t\treturn strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil\n\t\tcase reflect.Int:\n\t\t\treturn strconv.FormatInt(dataVal.Int(), 10), nil\n\t\tcase reflect.Slice:\n\t\t\tdataType := dataVal.Type()\n\t\t\telemKind := dataType.Elem().Kind()\n\t\t\tif elemKind == reflect.Uint8 {\n\t\t\t\treturn string(dataVal.Interface().([]uint8)), nil\n\t\t\t}\n\t\tcase reflect.Uint:\n\t\t\treturn strconv.FormatUint(dataVal.Uint(), 10), nil\n\t\t}\n\t}\n\n\treturn data, nil\n}\n\nfunc RecursiveStructToMapHookFunc() DecodeHookFunc {\n\treturn func(f reflect.Value, t reflect.Value) (interface{}, error) {\n\t\tif f.Kind() != reflect.Struct {\n\t\t\treturn f.Interface(), nil\n\t\t}\n\n\t\tvar i interface{} = struct{}{}\n\t\tif t.Type() != reflect.TypeOf(&i).Elem() {\n\t\t\treturn f.Interface(), nil\n\t\t}\n\n\t\tm := make(map[string]interface{})\n\t\tt.Set(reflect.ValueOf(m))\n\n\t\treturn f.Interface(), nil\n\t}\n}\n\n// TextUnmarshallerHookFunc returns a DecodeHookFunc that applies\n// strings to the UnmarshalText function, when the target type\n// implements the encoding.TextUnmarshaler interface\nfunc TextUnmarshallerHookFunc() DecodeHookFuncType {\n\treturn func(\n\t\tf reflect.Type,\n\t\tt reflect.Type,\n\t\tdata interface{}) (interface{}, error) {\n\t\tif f.Kind() != reflect.String {\n\t\t\treturn data, nil\n\t\t}\n\t\tresult := reflect.New(t).Interface()\n\t\tunmarshaller, ok := result.(encoding.TextUnmarshaler)\n\t\tif !ok {\n\t\t\treturn data, nil\n\t\t}\n\t\tif err := unmarshaller.UnmarshalText([]byte(data.(string))); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn result, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/mitchellh/mapstructure/error.go",
    "content": "package mapstructure\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// Error implements the error interface and can represents multiple\n// errors that occur in the course of a single decode.\ntype Error struct {\n\tErrors []string\n}\n\nfunc (e *Error) Error() string {\n\tpoints := make([]string, len(e.Errors))\n\tfor i, err := range e.Errors {\n\t\tpoints[i] = fmt.Sprintf(\"* %s\", err)\n\t}\n\n\tsort.Strings(points)\n\treturn fmt.Sprintf(\n\t\t\"%d error(s) decoding:\\n\\n%s\",\n\t\tlen(e.Errors), strings.Join(points, \"\\n\"))\n}\n\n// WrappedErrors implements the errwrap.Wrapper interface to make this\n// return value more useful with the errwrap and go-multierror libraries.\nfunc (e *Error) WrappedErrors() []error {\n\tif e == nil {\n\t\treturn nil\n\t}\n\n\tresult := make([]error, len(e.Errors))\n\tfor i, e := range e.Errors {\n\t\tresult[i] = errors.New(e)\n\t}\n\n\treturn result\n}\n\nfunc appendErrors(errors []string, err error) []string {\n\tswitch e := err.(type) {\n\tcase *Error:\n\t\treturn append(errors, e.Errors...)\n\tdefault:\n\t\treturn append(errors, e.Error())\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/mitchellh/mapstructure/mapstructure.go",
    "content": "// Package mapstructure exposes functionality to convert one arbitrary\n// Go type into another, typically to convert a map[string]interface{}\n// into a native Go structure.\n//\n// The Go structure can be arbitrarily complex, containing slices,\n// other structs, etc. and the decoder will properly decode nested\n// maps and so on into the proper structures in the native Go struct.\n// See the examples to see what the decoder is capable of.\n//\n// The simplest function to start with is Decode.\n//\n// Field Tags\n//\n// When decoding to a struct, mapstructure will use the field name by\n// default to perform the mapping. For example, if a struct has a field\n// \"Username\" then mapstructure will look for a key in the source value\n// of \"username\" (case insensitive).\n//\n//     type User struct {\n//         Username string\n//     }\n//\n// You can change the behavior of mapstructure by using struct tags.\n// The default struct tag that mapstructure looks for is \"mapstructure\"\n// but you can customize it using DecoderConfig.\n//\n// Renaming Fields\n//\n// To rename the key that mapstructure looks for, use the \"mapstructure\"\n// tag and set a value directly. For example, to change the \"username\" example\n// above to \"user\":\n//\n//     type User struct {\n//         Username string `mapstructure:\"user\"`\n//     }\n//\n// Embedded Structs and Squashing\n//\n// Embedded structs are treated as if they're another field with that name.\n// By default, the two structs below are equivalent when decoding with\n// mapstructure:\n//\n//     type Person struct {\n//         Name string\n//     }\n//\n//     type Friend struct {\n//         Person\n//     }\n//\n//     type Friend struct {\n//         Person Person\n//     }\n//\n// This would require an input that looks like below:\n//\n//     map[string]interface{}{\n//         \"person\": map[string]interface{}{\"name\": \"alice\"},\n//     }\n//\n// If your \"person\" value is NOT nested, then you can append \",squash\" to\n// your tag value and mapstructure will treat it as if the embedded struct\n// were part of the struct directly. Example:\n//\n//     type Friend struct {\n//         Person `mapstructure:\",squash\"`\n//     }\n//\n// Now the following input would be accepted:\n//\n//     map[string]interface{}{\n//         \"name\": \"alice\",\n//     }\n//\n// When decoding from a struct to a map, the squash tag squashes the struct\n// fields into a single map. Using the example structs from above:\n//\n//     Friend{Person: Person{Name: \"alice\"}}\n//\n// Will be decoded into a map:\n//\n//     map[string]interface{}{\n//         \"name\": \"alice\",\n//     }\n//\n// DecoderConfig has a field that changes the behavior of mapstructure\n// to always squash embedded structs.\n//\n// Remainder Values\n//\n// If there are any unmapped keys in the source value, mapstructure by\n// default will silently ignore them. You can error by setting ErrorUnused\n// in DecoderConfig. If you're using Metadata you can also maintain a slice\n// of the unused keys.\n//\n// You can also use the \",remain\" suffix on your tag to collect all unused\n// values in a map. The field with this tag MUST be a map type and should\n// probably be a \"map[string]interface{}\" or \"map[interface{}]interface{}\".\n// See example below:\n//\n//     type Friend struct {\n//         Name  string\n//         Other map[string]interface{} `mapstructure:\",remain\"`\n//     }\n//\n// Given the input below, Other would be populated with the other\n// values that weren't used (everything but \"name\"):\n//\n//     map[string]interface{}{\n//         \"name\":    \"bob\",\n//         \"address\": \"123 Maple St.\",\n//     }\n//\n// Omit Empty Values\n//\n// When decoding from a struct to any other value, you may use the\n// \",omitempty\" suffix on your tag to omit that value if it equates to\n// the zero value. The zero value of all types is specified in the Go\n// specification.\n//\n// For example, the zero type of a numeric type is zero (\"0\"). If the struct\n// field value is zero and a numeric type, the field is empty, and it won't\n// be encoded into the destination type.\n//\n//     type Source {\n//         Age int `mapstructure:\",omitempty\"`\n//     }\n//\n// Unexported fields\n//\n// Since unexported (private) struct fields cannot be set outside the package\n// where they are defined, the decoder will simply skip them.\n//\n// For this output type definition:\n//\n//     type Exported struct {\n//         private string // this unexported field will be skipped\n//         Public string\n//     }\n//\n// Using this map as input:\n//\n//     map[string]interface{}{\n//         \"private\": \"I will be ignored\",\n//         \"Public\":  \"I made it through!\",\n//     }\n//\n// The following struct will be decoded:\n//\n//     type Exported struct {\n//         private: \"\" // field is left with an empty string (zero value)\n//         Public: \"I made it through!\"\n//     }\n//\n// Other Configuration\n//\n// mapstructure is highly configurable. See the DecoderConfig struct\n// for other features and options that are supported.\npackage mapstructure\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// DecodeHookFunc is the callback function that can be used for\n// data transformations. See \"DecodeHook\" in the DecoderConfig\n// struct.\n//\n// The type must be one of DecodeHookFuncType, DecodeHookFuncKind, or\n// DecodeHookFuncValue.\n// Values are a superset of Types (Values can return types), and Types are a\n// superset of Kinds (Types can return Kinds) and are generally a richer thing\n// to use, but Kinds are simpler if you only need those.\n//\n// The reason DecodeHookFunc is multi-typed is for backwards compatibility:\n// we started with Kinds and then realized Types were the better solution,\n// but have a promise to not break backwards compat so we now support\n// both.\ntype DecodeHookFunc interface{}\n\n// DecodeHookFuncType is a DecodeHookFunc which has complete information about\n// the source and target types.\ntype DecodeHookFuncType func(reflect.Type, reflect.Type, interface{}) (interface{}, error)\n\n// DecodeHookFuncKind is a DecodeHookFunc which knows only the Kinds of the\n// source and target types.\ntype DecodeHookFuncKind func(reflect.Kind, reflect.Kind, interface{}) (interface{}, error)\n\n// DecodeHookFuncValue is a DecodeHookFunc which has complete access to both the source and target\n// values.\ntype DecodeHookFuncValue func(from reflect.Value, to reflect.Value) (interface{}, error)\n\n// DecoderConfig is the configuration that is used to create a new decoder\n// and allows customization of various aspects of decoding.\ntype DecoderConfig struct {\n\t// DecodeHook, if set, will be called before any decoding and any\n\t// type conversion (if WeaklyTypedInput is on). This lets you modify\n\t// the values before they're set down onto the resulting struct. The\n\t// DecodeHook is called for every map and value in the input. This means\n\t// that if a struct has embedded fields with squash tags the decode hook\n\t// is called only once with all of the input data, not once for each\n\t// embedded struct.\n\t//\n\t// If an error is returned, the entire decode will fail with that error.\n\tDecodeHook DecodeHookFunc\n\n\t// If ErrorUnused is true, then it is an error for there to exist\n\t// keys in the original map that were unused in the decoding process\n\t// (extra keys).\n\tErrorUnused bool\n\n\t// ZeroFields, if set to true, will zero fields before writing them.\n\t// For example, a map will be emptied before decoded values are put in\n\t// it. If this is false, a map will be merged.\n\tZeroFields bool\n\n\t// If WeaklyTypedInput is true, the decoder will make the following\n\t// \"weak\" conversions:\n\t//\n\t//   - bools to string (true = \"1\", false = \"0\")\n\t//   - numbers to string (base 10)\n\t//   - bools to int/uint (true = 1, false = 0)\n\t//   - strings to int/uint (base implied by prefix)\n\t//   - int to bool (true if value != 0)\n\t//   - string to bool (accepts: 1, t, T, TRUE, true, True, 0, f, F,\n\t//     FALSE, false, False. Anything else is an error)\n\t//   - empty array = empty map and vice versa\n\t//   - negative numbers to overflowed uint values (base 10)\n\t//   - slice of maps to a merged map\n\t//   - single values are converted to slices if required. Each\n\t//     element is weakly decoded. For example: \"4\" can become []int{4}\n\t//     if the target type is an int slice.\n\t//\n\tWeaklyTypedInput bool\n\n\t// Squash will squash embedded structs.  A squash tag may also be\n\t// added to an individual struct field using a tag.  For example:\n\t//\n\t//  type Parent struct {\n\t//      Child `mapstructure:\",squash\"`\n\t//  }\n\tSquash bool\n\n\t// Metadata is the struct that will contain extra metadata about\n\t// the decoding. If this is nil, then no metadata will be tracked.\n\tMetadata *Metadata\n\n\t// Result is a pointer to the struct that will contain the decoded\n\t// value.\n\tResult interface{}\n\n\t// The tag name that mapstructure reads for field names. This\n\t// defaults to \"mapstructure\"\n\tTagName string\n\n\t// MatchName is the function used to match the map key to the struct\n\t// field name or tag. Defaults to `strings.EqualFold`. This can be used\n\t// to implement case-sensitive tag values, support snake casing, etc.\n\tMatchName func(mapKey, fieldName string) bool\n}\n\n// A Decoder takes a raw interface value and turns it into structured\n// data, keeping track of rich error information along the way in case\n// anything goes wrong. Unlike the basic top-level Decode method, you can\n// more finely control how the Decoder behaves using the DecoderConfig\n// structure. The top-level Decode method is just a convenience that sets\n// up the most basic Decoder.\ntype Decoder struct {\n\tconfig *DecoderConfig\n}\n\n// Metadata contains information about decoding a structure that\n// is tedious or difficult to get otherwise.\ntype Metadata struct {\n\t// Keys are the keys of the structure which were successfully decoded\n\tKeys []string\n\n\t// Unused is a slice of keys that were found in the raw value but\n\t// weren't decoded since there was no matching field in the result interface\n\tUnused []string\n}\n\n// Decode takes an input structure and uses reflection to translate it to\n// the output structure. output must be a pointer to a map or struct.\nfunc Decode(input interface{}, output interface{}) error {\n\tconfig := &DecoderConfig{\n\t\tMetadata: nil,\n\t\tResult:   output,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn decoder.Decode(input)\n}\n\n// WeakDecode is the same as Decode but is shorthand to enable\n// WeaklyTypedInput. See DecoderConfig for more info.\nfunc WeakDecode(input, output interface{}) error {\n\tconfig := &DecoderConfig{\n\t\tMetadata:         nil,\n\t\tResult:           output,\n\t\tWeaklyTypedInput: true,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn decoder.Decode(input)\n}\n\n// DecodeMetadata is the same as Decode, but is shorthand to\n// enable metadata collection. See DecoderConfig for more info.\nfunc DecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {\n\tconfig := &DecoderConfig{\n\t\tMetadata: metadata,\n\t\tResult:   output,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn decoder.Decode(input)\n}\n\n// WeakDecodeMetadata is the same as Decode, but is shorthand to\n// enable both WeaklyTypedInput and metadata collection. See\n// DecoderConfig for more info.\nfunc WeakDecodeMetadata(input interface{}, output interface{}, metadata *Metadata) error {\n\tconfig := &DecoderConfig{\n\t\tMetadata:         metadata,\n\t\tResult:           output,\n\t\tWeaklyTypedInput: true,\n\t}\n\n\tdecoder, err := NewDecoder(config)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn decoder.Decode(input)\n}\n\n// NewDecoder returns a new decoder for the given configuration. Once\n// a decoder has been returned, the same configuration must not be used\n// again.\nfunc NewDecoder(config *DecoderConfig) (*Decoder, error) {\n\tval := reflect.ValueOf(config.Result)\n\tif val.Kind() != reflect.Ptr {\n\t\treturn nil, errors.New(\"result must be a pointer\")\n\t}\n\n\tval = val.Elem()\n\tif !val.CanAddr() {\n\t\treturn nil, errors.New(\"result must be addressable (a pointer)\")\n\t}\n\n\tif config.Metadata != nil {\n\t\tif config.Metadata.Keys == nil {\n\t\t\tconfig.Metadata.Keys = make([]string, 0)\n\t\t}\n\n\t\tif config.Metadata.Unused == nil {\n\t\t\tconfig.Metadata.Unused = make([]string, 0)\n\t\t}\n\t}\n\n\tif config.TagName == \"\" {\n\t\tconfig.TagName = \"mapstructure\"\n\t}\n\n\tif config.MatchName == nil {\n\t\tconfig.MatchName = strings.EqualFold\n\t}\n\n\tresult := &Decoder{\n\t\tconfig: config,\n\t}\n\n\treturn result, nil\n}\n\n// Decode decodes the given raw interface to the target pointer specified\n// by the configuration.\nfunc (d *Decoder) Decode(input interface{}) error {\n\treturn d.decode(\"\", input, reflect.ValueOf(d.config.Result).Elem())\n}\n\n// Decodes an unknown data type into a specific reflection value.\nfunc (d *Decoder) decode(name string, input interface{}, outVal reflect.Value) error {\n\tvar inputVal reflect.Value\n\tif input != nil {\n\t\tinputVal = reflect.ValueOf(input)\n\n\t\t// We need to check here if input is a typed nil. Typed nils won't\n\t\t// match the \"input == nil\" below so we check that here.\n\t\tif inputVal.Kind() == reflect.Ptr && inputVal.IsNil() {\n\t\t\tinput = nil\n\t\t}\n\t}\n\n\tif input == nil {\n\t\t// If the data is nil, then we don't set anything, unless ZeroFields is set\n\t\t// to true.\n\t\tif d.config.ZeroFields {\n\t\t\toutVal.Set(reflect.Zero(outVal.Type()))\n\n\t\t\tif d.config.Metadata != nil && name != \"\" {\n\t\t\t\td.config.Metadata.Keys = append(d.config.Metadata.Keys, name)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\tif !inputVal.IsValid() {\n\t\t// If the input value is invalid, then we just set the value\n\t\t// to be the zero value.\n\t\toutVal.Set(reflect.Zero(outVal.Type()))\n\t\tif d.config.Metadata != nil && name != \"\" {\n\t\t\td.config.Metadata.Keys = append(d.config.Metadata.Keys, name)\n\t\t}\n\t\treturn nil\n\t}\n\n\tif d.config.DecodeHook != nil {\n\t\t// We have a DecodeHook, so let's pre-process the input.\n\t\tvar err error\n\t\tinput, err = DecodeHookExec(d.config.DecodeHook, inputVal, outVal)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error decoding '%s': %s\", name, err)\n\t\t}\n\t}\n\n\tvar err error\n\toutputKind := getKind(outVal)\n\taddMetaKey := true\n\tswitch outputKind {\n\tcase reflect.Bool:\n\t\terr = d.decodeBool(name, input, outVal)\n\tcase reflect.Interface:\n\t\terr = d.decodeBasic(name, input, outVal)\n\tcase reflect.String:\n\t\terr = d.decodeString(name, input, outVal)\n\tcase reflect.Int:\n\t\terr = d.decodeInt(name, input, outVal)\n\tcase reflect.Uint:\n\t\terr = d.decodeUint(name, input, outVal)\n\tcase reflect.Float32:\n\t\terr = d.decodeFloat(name, input, outVal)\n\tcase reflect.Struct:\n\t\terr = d.decodeStruct(name, input, outVal)\n\tcase reflect.Map:\n\t\terr = d.decodeMap(name, input, outVal)\n\tcase reflect.Ptr:\n\t\taddMetaKey, err = d.decodePtr(name, input, outVal)\n\tcase reflect.Slice:\n\t\terr = d.decodeSlice(name, input, outVal)\n\tcase reflect.Array:\n\t\terr = d.decodeArray(name, input, outVal)\n\tcase reflect.Func:\n\t\terr = d.decodeFunc(name, input, outVal)\n\tdefault:\n\t\t// If we reached this point then we weren't able to decode it\n\t\treturn fmt.Errorf(\"%s: unsupported type: %s\", name, outputKind)\n\t}\n\n\t// If we reached here, then we successfully decoded SOMETHING, so\n\t// mark the key as used if we're tracking metainput.\n\tif addMetaKey && d.config.Metadata != nil && name != \"\" {\n\t\td.config.Metadata.Keys = append(d.config.Metadata.Keys, name)\n\t}\n\n\treturn err\n}\n\n// This decodes a basic type (bool, int, string, etc.) and sets the\n// value to \"data\" of that type.\nfunc (d *Decoder) decodeBasic(name string, data interface{}, val reflect.Value) error {\n\tif val.IsValid() && val.Elem().IsValid() {\n\t\telem := val.Elem()\n\n\t\t// If we can't address this element, then its not writable. Instead,\n\t\t// we make a copy of the value (which is a pointer and therefore\n\t\t// writable), decode into that, and replace the whole value.\n\t\tcopied := false\n\t\tif !elem.CanAddr() {\n\t\t\tcopied = true\n\n\t\t\t// Make *T\n\t\t\tcopy := reflect.New(elem.Type())\n\n\t\t\t// *T = elem\n\t\t\tcopy.Elem().Set(elem)\n\n\t\t\t// Set elem so we decode into it\n\t\t\telem = copy\n\t\t}\n\n\t\t// Decode. If we have an error then return. We also return right\n\t\t// away if we're not a copy because that means we decoded directly.\n\t\tif err := d.decode(name, data, elem); err != nil || !copied {\n\t\t\treturn err\n\t\t}\n\n\t\t// If we're a copy, we need to set te final result\n\t\tval.Set(elem.Elem())\n\t\treturn nil\n\t}\n\n\tdataVal := reflect.ValueOf(data)\n\n\t// If the input data is a pointer, and the assigned type is the dereference\n\t// of that exact pointer, then indirect it so that we can assign it.\n\t// Example: *string to string\n\tif dataVal.Kind() == reflect.Ptr && dataVal.Type().Elem() == val.Type() {\n\t\tdataVal = reflect.Indirect(dataVal)\n\t}\n\n\tif !dataVal.IsValid() {\n\t\tdataVal = reflect.Zero(val.Type())\n\t}\n\n\tdataValType := dataVal.Type()\n\tif !dataValType.AssignableTo(val.Type()) {\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got '%s'\",\n\t\t\tname, val.Type(), dataValType)\n\t}\n\n\tval.Set(dataVal)\n\treturn nil\n}\n\nfunc (d *Decoder) decodeString(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataKind := getKind(dataVal)\n\n\tconverted := true\n\tswitch {\n\tcase dataKind == reflect.String:\n\t\tval.SetString(dataVal.String())\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetString(\"1\")\n\t\t} else {\n\t\t\tval.SetString(\"0\")\n\t\t}\n\tcase dataKind == reflect.Int && d.config.WeaklyTypedInput:\n\t\tval.SetString(strconv.FormatInt(dataVal.Int(), 10))\n\tcase dataKind == reflect.Uint && d.config.WeaklyTypedInput:\n\t\tval.SetString(strconv.FormatUint(dataVal.Uint(), 10))\n\tcase dataKind == reflect.Float32 && d.config.WeaklyTypedInput:\n\t\tval.SetString(strconv.FormatFloat(dataVal.Float(), 'f', -1, 64))\n\tcase dataKind == reflect.Slice && d.config.WeaklyTypedInput,\n\t\tdataKind == reflect.Array && d.config.WeaklyTypedInput:\n\t\tdataType := dataVal.Type()\n\t\telemKind := dataType.Elem().Kind()\n\t\tswitch elemKind {\n\t\tcase reflect.Uint8:\n\t\t\tvar uints []uint8\n\t\t\tif dataKind == reflect.Array {\n\t\t\t\tuints = make([]uint8, dataVal.Len(), dataVal.Len())\n\t\t\t\tfor i := range uints {\n\t\t\t\t\tuints[i] = dataVal.Index(i).Interface().(uint8)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tuints = dataVal.Interface().([]uint8)\n\t\t\t}\n\t\t\tval.SetString(string(uints))\n\t\tdefault:\n\t\t\tconverted = false\n\t\t}\n\tdefault:\n\t\tconverted = false\n\t}\n\n\tif !converted {\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s', value: '%v'\",\n\t\t\tname, val.Type(), dataVal.Type(), data)\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataKind := getKind(dataVal)\n\tdataType := dataVal.Type()\n\n\tswitch {\n\tcase dataKind == reflect.Int:\n\t\tval.SetInt(dataVal.Int())\n\tcase dataKind == reflect.Uint:\n\t\tval.SetInt(int64(dataVal.Uint()))\n\tcase dataKind == reflect.Float32:\n\t\tval.SetInt(int64(dataVal.Float()))\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetInt(1)\n\t\t} else {\n\t\t\tval.SetInt(0)\n\t\t}\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\tstr := dataVal.String()\n\t\tif str == \"\" {\n\t\t\tstr = \"0\"\n\t\t}\n\n\t\ti, err := strconv.ParseInt(str, 0, val.Type().Bits())\n\t\tif err == nil {\n\t\t\tval.SetInt(i)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as int: %s\", name, err)\n\t\t}\n\tcase dataType.PkgPath() == \"encoding/json\" && dataType.Name() == \"Number\":\n\t\tjn := data.(json.Number)\n\t\ti, err := jn.Int64()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"error decoding json.Number into %s: %s\", name, err)\n\t\t}\n\t\tval.SetInt(i)\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s', value: '%v'\",\n\t\t\tname, val.Type(), dataVal.Type(), data)\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataKind := getKind(dataVal)\n\tdataType := dataVal.Type()\n\n\tswitch {\n\tcase dataKind == reflect.Int:\n\t\ti := dataVal.Int()\n\t\tif i < 0 && !d.config.WeaklyTypedInput {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s', %d overflows uint\",\n\t\t\t\tname, i)\n\t\t}\n\t\tval.SetUint(uint64(i))\n\tcase dataKind == reflect.Uint:\n\t\tval.SetUint(dataVal.Uint())\n\tcase dataKind == reflect.Float32:\n\t\tf := dataVal.Float()\n\t\tif f < 0 && !d.config.WeaklyTypedInput {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s', %f overflows uint\",\n\t\t\t\tname, f)\n\t\t}\n\t\tval.SetUint(uint64(f))\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetUint(1)\n\t\t} else {\n\t\t\tval.SetUint(0)\n\t\t}\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\tstr := dataVal.String()\n\t\tif str == \"\" {\n\t\t\tstr = \"0\"\n\t\t}\n\n\t\ti, err := strconv.ParseUint(str, 0, val.Type().Bits())\n\t\tif err == nil {\n\t\t\tval.SetUint(i)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as uint: %s\", name, err)\n\t\t}\n\tcase dataType.PkgPath() == \"encoding/json\" && dataType.Name() == \"Number\":\n\t\tjn := data.(json.Number)\n\t\ti, err := strconv.ParseUint(string(jn), 0, 64)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"error decoding json.Number into %s: %s\", name, err)\n\t\t}\n\t\tval.SetUint(i)\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s', value: '%v'\",\n\t\t\tname, val.Type(), dataVal.Type(), data)\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeBool(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataKind := getKind(dataVal)\n\n\tswitch {\n\tcase dataKind == reflect.Bool:\n\t\tval.SetBool(dataVal.Bool())\n\tcase dataKind == reflect.Int && d.config.WeaklyTypedInput:\n\t\tval.SetBool(dataVal.Int() != 0)\n\tcase dataKind == reflect.Uint && d.config.WeaklyTypedInput:\n\t\tval.SetBool(dataVal.Uint() != 0)\n\tcase dataKind == reflect.Float32 && d.config.WeaklyTypedInput:\n\t\tval.SetBool(dataVal.Float() != 0)\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\tb, err := strconv.ParseBool(dataVal.String())\n\t\tif err == nil {\n\t\t\tval.SetBool(b)\n\t\t} else if dataVal.String() == \"\" {\n\t\t\tval.SetBool(false)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as bool: %s\", name, err)\n\t\t}\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s', value: '%v'\",\n\t\t\tname, val.Type(), dataVal.Type(), data)\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeFloat(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataKind := getKind(dataVal)\n\tdataType := dataVal.Type()\n\n\tswitch {\n\tcase dataKind == reflect.Int:\n\t\tval.SetFloat(float64(dataVal.Int()))\n\tcase dataKind == reflect.Uint:\n\t\tval.SetFloat(float64(dataVal.Uint()))\n\tcase dataKind == reflect.Float32:\n\t\tval.SetFloat(dataVal.Float())\n\tcase dataKind == reflect.Bool && d.config.WeaklyTypedInput:\n\t\tif dataVal.Bool() {\n\t\t\tval.SetFloat(1)\n\t\t} else {\n\t\t\tval.SetFloat(0)\n\t\t}\n\tcase dataKind == reflect.String && d.config.WeaklyTypedInput:\n\t\tstr := dataVal.String()\n\t\tif str == \"\" {\n\t\t\tstr = \"0\"\n\t\t}\n\n\t\tf, err := strconv.ParseFloat(str, val.Type().Bits())\n\t\tif err == nil {\n\t\t\tval.SetFloat(f)\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"cannot parse '%s' as float: %s\", name, err)\n\t\t}\n\tcase dataType.PkgPath() == \"encoding/json\" && dataType.Name() == \"Number\":\n\t\tjn := data.(json.Number)\n\t\ti, err := jn.Float64()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"error decoding json.Number into %s: %s\", name, err)\n\t\t}\n\t\tval.SetFloat(i)\n\tdefault:\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s', value: '%v'\",\n\t\t\tname, val.Type(), dataVal.Type(), data)\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeMap(name string, data interface{}, val reflect.Value) error {\n\tvalType := val.Type()\n\tvalKeyType := valType.Key()\n\tvalElemType := valType.Elem()\n\n\t// By default we overwrite keys in the current map\n\tvalMap := val\n\n\t// If the map is nil or we're purposely zeroing fields, make a new map\n\tif valMap.IsNil() || d.config.ZeroFields {\n\t\t// Make a new map to hold our result\n\t\tmapType := reflect.MapOf(valKeyType, valElemType)\n\t\tvalMap = reflect.MakeMap(mapType)\n\t}\n\n\t// Check input type and based on the input type jump to the proper func\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tswitch dataVal.Kind() {\n\tcase reflect.Map:\n\t\treturn d.decodeMapFromMap(name, dataVal, val, valMap)\n\n\tcase reflect.Struct:\n\t\treturn d.decodeMapFromStruct(name, dataVal, val, valMap)\n\n\tcase reflect.Array, reflect.Slice:\n\t\tif d.config.WeaklyTypedInput {\n\t\t\treturn d.decodeMapFromSlice(name, dataVal, val, valMap)\n\t\t}\n\n\t\tfallthrough\n\n\tdefault:\n\t\treturn fmt.Errorf(\"'%s' expected a map, got '%s'\", name, dataVal.Kind())\n\t}\n}\n\nfunc (d *Decoder) decodeMapFromSlice(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {\n\t// Special case for BC reasons (covered by tests)\n\tif dataVal.Len() == 0 {\n\t\tval.Set(valMap)\n\t\treturn nil\n\t}\n\n\tfor i := 0; i < dataVal.Len(); i++ {\n\t\terr := d.decode(\n\t\t\tname+\"[\"+strconv.Itoa(i)+\"]\",\n\t\t\tdataVal.Index(i).Interface(), val)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeMapFromMap(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {\n\tvalType := val.Type()\n\tvalKeyType := valType.Key()\n\tvalElemType := valType.Elem()\n\n\t// Accumulate errors\n\terrors := make([]string, 0)\n\n\t// If the input data is empty, then we just match what the input data is.\n\tif dataVal.Len() == 0 {\n\t\tif dataVal.IsNil() {\n\t\t\tif !val.IsNil() {\n\t\t\t\tval.Set(dataVal)\n\t\t\t}\n\t\t} else {\n\t\t\t// Set to empty allocated value\n\t\t\tval.Set(valMap)\n\t\t}\n\n\t\treturn nil\n\t}\n\n\tfor _, k := range dataVal.MapKeys() {\n\t\tfieldName := name + \"[\" + k.String() + \"]\"\n\n\t\t// First decode the key into the proper type\n\t\tcurrentKey := reflect.Indirect(reflect.New(valKeyType))\n\t\tif err := d.decode(fieldName, k.Interface(), currentKey); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Next decode the data into the proper type\n\t\tv := dataVal.MapIndex(k).Interface()\n\t\tcurrentVal := reflect.Indirect(reflect.New(valElemType))\n\t\tif err := d.decode(fieldName, v, currentVal); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t\tcontinue\n\t\t}\n\n\t\tvalMap.SetMapIndex(currentKey, currentVal)\n\t}\n\n\t// Set the built up map to the value\n\tval.Set(valMap)\n\n\t// If we had errors, return those\n\tif len(errors) > 0 {\n\t\treturn &Error{errors}\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val reflect.Value, valMap reflect.Value) error {\n\ttyp := dataVal.Type()\n\tfor i := 0; i < typ.NumField(); i++ {\n\t\t// Get the StructField first since this is a cheap operation. If the\n\t\t// field is unexported, then ignore it.\n\t\tf := typ.Field(i)\n\t\tif f.PkgPath != \"\" {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Next get the actual value of this field and verify it is assignable\n\t\t// to the map value.\n\t\tv := dataVal.Field(i)\n\t\tif !v.Type().AssignableTo(valMap.Type().Elem()) {\n\t\t\treturn fmt.Errorf(\"cannot assign type '%s' to map value field of type '%s'\", v.Type(), valMap.Type().Elem())\n\t\t}\n\n\t\ttagValue := f.Tag.Get(d.config.TagName)\n\t\tkeyName := f.Name\n\n\t\t// If Squash is set in the config, we squash the field down.\n\t\tsquash := d.config.Squash && v.Kind() == reflect.Struct && f.Anonymous\n\n\t\t// Determine the name of the key in the map\n\t\tif index := strings.Index(tagValue, \",\"); index != -1 {\n\t\t\tif tagValue[:index] == \"-\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// If \"omitempty\" is specified in the tag, it ignores empty values.\n\t\t\tif strings.Index(tagValue[index+1:], \"omitempty\") != -1 && isEmptyValue(v) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If \"squash\" is specified in the tag, we squash the field down.\n\t\t\tsquash = !squash && strings.Index(tagValue[index+1:], \"squash\") != -1\n\t\t\tif squash {\n\t\t\t\t// When squashing, the embedded type can be a pointer to a struct.\n\t\t\t\tif v.Kind() == reflect.Ptr && v.Elem().Kind() == reflect.Struct {\n\t\t\t\t\tv = v.Elem()\n\t\t\t\t}\n\n\t\t\t\t// The final type must be a struct\n\t\t\t\tif v.Kind() != reflect.Struct {\n\t\t\t\t\treturn fmt.Errorf(\"cannot squash non-struct type '%s'\", v.Type())\n\t\t\t\t}\n\t\t\t}\n\t\t\tkeyName = tagValue[:index]\n\t\t} else if len(tagValue) > 0 {\n\t\t\tif tagValue == \"-\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tkeyName = tagValue\n\t\t}\n\n\t\tswitch v.Kind() {\n\t\t// this is an embedded struct, so handle it differently\n\t\tcase reflect.Struct:\n\t\t\tx := reflect.New(v.Type())\n\t\t\tx.Elem().Set(v)\n\n\t\t\tvType := valMap.Type()\n\t\t\tvKeyType := vType.Key()\n\t\t\tvElemType := vType.Elem()\n\t\t\tmType := reflect.MapOf(vKeyType, vElemType)\n\t\t\tvMap := reflect.MakeMap(mType)\n\n\t\t\t// Creating a pointer to a map so that other methods can completely\n\t\t\t// overwrite the map if need be (looking at you decodeMapFromMap). The\n\t\t\t// indirection allows the underlying map to be settable (CanSet() == true)\n\t\t\t// where as reflect.MakeMap returns an unsettable map.\n\t\t\taddrVal := reflect.New(vMap.Type())\n\t\t\treflect.Indirect(addrVal).Set(vMap)\n\n\t\t\terr := d.decode(keyName, x.Interface(), reflect.Indirect(addrVal))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// the underlying map may have been completely overwritten so pull\n\t\t\t// it indirectly out of the enclosing value.\n\t\t\tvMap = reflect.Indirect(addrVal)\n\n\t\t\tif squash {\n\t\t\t\tfor _, k := range vMap.MapKeys() {\n\t\t\t\t\tvalMap.SetMapIndex(k, vMap.MapIndex(k))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tvalMap.SetMapIndex(reflect.ValueOf(keyName), vMap)\n\t\t\t}\n\n\t\tdefault:\n\t\t\tvalMap.SetMapIndex(reflect.ValueOf(keyName), v)\n\t\t}\n\t}\n\n\tif val.CanAddr() {\n\t\tval.Set(valMap)\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodePtr(name string, data interface{}, val reflect.Value) (bool, error) {\n\t// If the input data is nil, then we want to just set the output\n\t// pointer to be nil as well.\n\tisNil := data == nil\n\tif !isNil {\n\t\tswitch v := reflect.Indirect(reflect.ValueOf(data)); v.Kind() {\n\t\tcase reflect.Chan,\n\t\t\treflect.Func,\n\t\t\treflect.Interface,\n\t\t\treflect.Map,\n\t\t\treflect.Ptr,\n\t\t\treflect.Slice:\n\t\t\tisNil = v.IsNil()\n\t\t}\n\t}\n\tif isNil {\n\t\tif !val.IsNil() && val.CanSet() {\n\t\t\tnilValue := reflect.New(val.Type()).Elem()\n\t\t\tval.Set(nilValue)\n\t\t}\n\n\t\treturn true, nil\n\t}\n\n\t// Create an element of the concrete (non pointer) type and decode\n\t// into that. Then set the value of the pointer to this type.\n\tvalType := val.Type()\n\tvalElemType := valType.Elem()\n\tif val.CanSet() {\n\t\trealVal := val\n\t\tif realVal.IsNil() || d.config.ZeroFields {\n\t\t\trealVal = reflect.New(valElemType)\n\t\t}\n\n\t\tif err := d.decode(name, data, reflect.Indirect(realVal)); err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tval.Set(realVal)\n\t} else {\n\t\tif err := d.decode(name, data, reflect.Indirect(val)); err != nil {\n\t\t\treturn false, err\n\t\t}\n\t}\n\treturn false, nil\n}\n\nfunc (d *Decoder) decodeFunc(name string, data interface{}, val reflect.Value) error {\n\t// Create an element of the concrete (non pointer) type and decode\n\t// into that. Then set the value of the pointer to this type.\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tif val.Type() != dataVal.Type() {\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' expected type '%s', got unconvertible type '%s', value: '%v'\",\n\t\t\tname, val.Type(), dataVal.Type(), data)\n\t}\n\tval.Set(dataVal)\n\treturn nil\n}\n\nfunc (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataValKind := dataVal.Kind()\n\tvalType := val.Type()\n\tvalElemType := valType.Elem()\n\tsliceType := reflect.SliceOf(valElemType)\n\n\t// If we have a non array/slice type then we first attempt to convert.\n\tif dataValKind != reflect.Array && dataValKind != reflect.Slice {\n\t\tif d.config.WeaklyTypedInput {\n\t\t\tswitch {\n\t\t\t// Slice and array we use the normal logic\n\t\t\tcase dataValKind == reflect.Slice, dataValKind == reflect.Array:\n\t\t\t\tbreak\n\n\t\t\t// Empty maps turn into empty slices\n\t\t\tcase dataValKind == reflect.Map:\n\t\t\t\tif dataVal.Len() == 0 {\n\t\t\t\t\tval.Set(reflect.MakeSlice(sliceType, 0, 0))\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\t// Create slice of maps of other sizes\n\t\t\t\treturn d.decodeSlice(name, []interface{}{data}, val)\n\n\t\t\tcase dataValKind == reflect.String && valElemType.Kind() == reflect.Uint8:\n\t\t\t\treturn d.decodeSlice(name, []byte(dataVal.String()), val)\n\n\t\t\t// All other types we try to convert to the slice type\n\t\t\t// and \"lift\" it into it. i.e. a string becomes a string slice.\n\t\t\tdefault:\n\t\t\t\t// Just re-try this function with data as a slice.\n\t\t\t\treturn d.decodeSlice(name, []interface{}{data}, val)\n\t\t\t}\n\t\t}\n\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s': source data must be an array or slice, got %s\", name, dataValKind)\n\t}\n\n\t// If the input value is nil, then don't allocate since empty != nil\n\tif dataVal.IsNil() {\n\t\treturn nil\n\t}\n\n\tvalSlice := val\n\tif valSlice.IsNil() || d.config.ZeroFields {\n\t\t// Make a new slice to hold our result, same size as the original data.\n\t\tvalSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())\n\t}\n\n\t// Accumulate any errors\n\terrors := make([]string, 0)\n\n\tfor i := 0; i < dataVal.Len(); i++ {\n\t\tcurrentData := dataVal.Index(i).Interface()\n\t\tfor valSlice.Len() <= i {\n\t\t\tvalSlice = reflect.Append(valSlice, reflect.Zero(valElemType))\n\t\t}\n\t\tcurrentField := valSlice.Index(i)\n\n\t\tfieldName := name + \"[\" + strconv.Itoa(i) + \"]\"\n\t\tif err := d.decode(fieldName, currentData, currentField); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t}\n\t}\n\n\t// Finally, set the value to the slice we built up\n\tval.Set(valSlice)\n\n\t// If there were errors, we return those\n\tif len(errors) > 0 {\n\t\treturn &Error{errors}\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeArray(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\tdataValKind := dataVal.Kind()\n\tvalType := val.Type()\n\tvalElemType := valType.Elem()\n\tarrayType := reflect.ArrayOf(valType.Len(), valElemType)\n\n\tvalArray := val\n\n\tif valArray.Interface() == reflect.Zero(valArray.Type()).Interface() || d.config.ZeroFields {\n\t\t// Check input type\n\t\tif dataValKind != reflect.Array && dataValKind != reflect.Slice {\n\t\t\tif d.config.WeaklyTypedInput {\n\t\t\t\tswitch {\n\t\t\t\t// Empty maps turn into empty arrays\n\t\t\t\tcase dataValKind == reflect.Map:\n\t\t\t\t\tif dataVal.Len() == 0 {\n\t\t\t\t\t\tval.Set(reflect.Zero(arrayType))\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\n\t\t\t\t// All other types we try to convert to the array type\n\t\t\t\t// and \"lift\" it into it. i.e. a string becomes a string array.\n\t\t\t\tdefault:\n\t\t\t\t\t// Just re-try this function with data as a slice.\n\t\t\t\t\treturn d.decodeArray(name, []interface{}{data}, val)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"'%s': source data must be an array or slice, got %s\", name, dataValKind)\n\n\t\t}\n\t\tif dataVal.Len() > arrayType.Len() {\n\t\t\treturn fmt.Errorf(\n\t\t\t\t\"'%s': expected source data to have length less or equal to %d, got %d\", name, arrayType.Len(), dataVal.Len())\n\n\t\t}\n\n\t\t// Make a new array to hold our result, same size as the original data.\n\t\tvalArray = reflect.New(arrayType).Elem()\n\t}\n\n\t// Accumulate any errors\n\terrors := make([]string, 0)\n\n\tfor i := 0; i < dataVal.Len(); i++ {\n\t\tcurrentData := dataVal.Index(i).Interface()\n\t\tcurrentField := valArray.Index(i)\n\n\t\tfieldName := name + \"[\" + strconv.Itoa(i) + \"]\"\n\t\tif err := d.decode(fieldName, currentData, currentField); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t}\n\t}\n\n\t// Finally, set the value to the array we built up\n\tval.Set(valArray)\n\n\t// If there were errors, we return those\n\tif len(errors) > 0 {\n\t\treturn &Error{errors}\n\t}\n\n\treturn nil\n}\n\nfunc (d *Decoder) decodeStruct(name string, data interface{}, val reflect.Value) error {\n\tdataVal := reflect.Indirect(reflect.ValueOf(data))\n\n\t// If the type of the value to write to and the data match directly,\n\t// then we just set it directly instead of recursing into the structure.\n\tif dataVal.Type() == val.Type() {\n\t\tval.Set(dataVal)\n\t\treturn nil\n\t}\n\n\tdataValKind := dataVal.Kind()\n\tswitch dataValKind {\n\tcase reflect.Map:\n\t\treturn d.decodeStructFromMap(name, dataVal, val)\n\n\tcase reflect.Struct:\n\t\t// Not the most efficient way to do this but we can optimize later if\n\t\t// we want to. To convert from struct to struct we go to map first\n\t\t// as an intermediary.\n\n\t\t// Make a new map to hold our result\n\t\tmapType := reflect.TypeOf((map[string]interface{})(nil))\n\t\tmval := reflect.MakeMap(mapType)\n\n\t\t// Creating a pointer to a map so that other methods can completely\n\t\t// overwrite the map if need be (looking at you decodeMapFromMap). The\n\t\t// indirection allows the underlying map to be settable (CanSet() == true)\n\t\t// where as reflect.MakeMap returns an unsettable map.\n\t\taddrVal := reflect.New(mval.Type())\n\n\t\treflect.Indirect(addrVal).Set(mval)\n\t\tif err := d.decodeMapFromStruct(name, dataVal, reflect.Indirect(addrVal), mval); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tresult := d.decodeStructFromMap(name, reflect.Indirect(addrVal), val)\n\t\treturn result\n\n\tdefault:\n\t\treturn fmt.Errorf(\"'%s' expected a map, got '%s'\", name, dataVal.Kind())\n\t}\n}\n\nfunc (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) error {\n\tdataValType := dataVal.Type()\n\tif kind := dataValType.Key().Kind(); kind != reflect.String && kind != reflect.Interface {\n\t\treturn fmt.Errorf(\n\t\t\t\"'%s' needs a map with string keys, has '%s' keys\",\n\t\t\tname, dataValType.Key().Kind())\n\t}\n\n\tdataValKeys := make(map[reflect.Value]struct{})\n\tdataValKeysUnused := make(map[interface{}]struct{})\n\tfor _, dataValKey := range dataVal.MapKeys() {\n\t\tdataValKeys[dataValKey] = struct{}{}\n\t\tdataValKeysUnused[dataValKey.Interface()] = struct{}{}\n\t}\n\n\terrors := make([]string, 0)\n\n\t// This slice will keep track of all the structs we'll be decoding.\n\t// There can be more than one struct if there are embedded structs\n\t// that are squashed.\n\tstructs := make([]reflect.Value, 1, 5)\n\tstructs[0] = val\n\n\t// Compile the list of all the fields that we're going to be decoding\n\t// from all the structs.\n\ttype field struct {\n\t\tfield reflect.StructField\n\t\tval   reflect.Value\n\t}\n\n\t// remainField is set to a valid field set with the \"remain\" tag if\n\t// we are keeping track of remaining values.\n\tvar remainField *field\n\n\tfields := []field{}\n\tfor len(structs) > 0 {\n\t\tstructVal := structs[0]\n\t\tstructs = structs[1:]\n\n\t\tstructType := structVal.Type()\n\n\t\tfor i := 0; i < structType.NumField(); i++ {\n\t\t\tfieldType := structType.Field(i)\n\t\t\tfieldVal := structVal.Field(i)\n\t\t\tif fieldVal.Kind() == reflect.Ptr && fieldVal.Elem().Kind() == reflect.Struct {\n\t\t\t\t// Handle embedded struct pointers as embedded structs.\n\t\t\t\tfieldVal = fieldVal.Elem()\n\t\t\t}\n\n\t\t\t// If \"squash\" is specified in the tag, we squash the field down.\n\t\t\tsquash := d.config.Squash && fieldVal.Kind() == reflect.Struct && fieldType.Anonymous\n\t\t\tremain := false\n\n\t\t\t// We always parse the tags cause we're looking for other tags too\n\t\t\ttagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), \",\")\n\t\t\tfor _, tag := range tagParts[1:] {\n\t\t\t\tif tag == \"squash\" {\n\t\t\t\t\tsquash = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif tag == \"remain\" {\n\t\t\t\t\tremain = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif squash {\n\t\t\t\tif fieldVal.Kind() != reflect.Struct {\n\t\t\t\t\terrors = appendErrors(errors,\n\t\t\t\t\t\tfmt.Errorf(\"%s: unsupported type for squash: %s\", fieldType.Name, fieldVal.Kind()))\n\t\t\t\t} else {\n\t\t\t\t\tstructs = append(structs, fieldVal)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Build our field\n\t\t\tif remain {\n\t\t\t\tremainField = &field{fieldType, fieldVal}\n\t\t\t} else {\n\t\t\t\t// Normal struct field, store it away\n\t\t\t\tfields = append(fields, field{fieldType, fieldVal})\n\t\t\t}\n\t\t}\n\t}\n\n\t// for fieldType, field := range fields {\n\tfor _, f := range fields {\n\t\tfield, fieldValue := f.field, f.val\n\t\tfieldName := field.Name\n\n\t\ttagValue := field.Tag.Get(d.config.TagName)\n\t\ttagValue = strings.SplitN(tagValue, \",\", 2)[0]\n\t\tif tagValue != \"\" {\n\t\t\tfieldName = tagValue\n\t\t}\n\n\t\trawMapKey := reflect.ValueOf(fieldName)\n\t\trawMapVal := dataVal.MapIndex(rawMapKey)\n\t\tif !rawMapVal.IsValid() {\n\t\t\t// Do a slower search by iterating over each key and\n\t\t\t// doing case-insensitive search.\n\t\t\tfor dataValKey := range dataValKeys {\n\t\t\t\tmK, ok := dataValKey.Interface().(string)\n\t\t\t\tif !ok {\n\t\t\t\t\t// Not a string key\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif d.config.MatchName(mK, fieldName) {\n\t\t\t\t\trawMapKey = dataValKey\n\t\t\t\t\trawMapVal = dataVal.MapIndex(dataValKey)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !rawMapVal.IsValid() {\n\t\t\t\t// There was no matching key in the map for the value in\n\t\t\t\t// the struct. Just ignore.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif !fieldValue.IsValid() {\n\t\t\t// This should never happen\n\t\t\tpanic(\"field is not valid\")\n\t\t}\n\n\t\t// If we can't set the field, then it is unexported or something,\n\t\t// and we just continue onwards.\n\t\tif !fieldValue.CanSet() {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Delete the key we're using from the unused map so we stop tracking\n\t\tdelete(dataValKeysUnused, rawMapKey.Interface())\n\n\t\t// If the name is empty string, then we're at the root, and we\n\t\t// don't dot-join the fields.\n\t\tif name != \"\" {\n\t\t\tfieldName = name + \".\" + fieldName\n\t\t}\n\n\t\tif err := d.decode(fieldName, rawMapVal.Interface(), fieldValue); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t}\n\t}\n\n\t// If we have a \"remain\"-tagged field and we have unused keys then\n\t// we put the unused keys directly into the remain field.\n\tif remainField != nil && len(dataValKeysUnused) > 0 {\n\t\t// Build a map of only the unused values\n\t\tremain := map[interface{}]interface{}{}\n\t\tfor key := range dataValKeysUnused {\n\t\t\tremain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface()\n\t\t}\n\n\t\t// Decode it as-if we were just decoding this map onto our map.\n\t\tif err := d.decodeMap(name, remain, remainField.val); err != nil {\n\t\t\terrors = appendErrors(errors, err)\n\t\t}\n\n\t\t// Set the map to nil so we have none so that the next check will\n\t\t// not error (ErrorUnused)\n\t\tdataValKeysUnused = nil\n\t}\n\n\tif d.config.ErrorUnused && len(dataValKeysUnused) > 0 {\n\t\tkeys := make([]string, 0, len(dataValKeysUnused))\n\t\tfor rawKey := range dataValKeysUnused {\n\t\t\tkeys = append(keys, rawKey.(string))\n\t\t}\n\t\tsort.Strings(keys)\n\n\t\terr := fmt.Errorf(\"'%s' has invalid keys: %s\", name, strings.Join(keys, \", \"))\n\t\terrors = appendErrors(errors, err)\n\t}\n\n\tif len(errors) > 0 {\n\t\treturn &Error{errors}\n\t}\n\n\t// Add the unused keys to the list of unused keys if we're tracking metadata\n\tif d.config.Metadata != nil {\n\t\tfor rawKey := range dataValKeysUnused {\n\t\t\tkey := rawKey.(string)\n\t\t\tif name != \"\" {\n\t\t\t\tkey = name + \".\" + key\n\t\t\t}\n\n\t\t\td.config.Metadata.Unused = append(d.config.Metadata.Unused, key)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc isEmptyValue(v reflect.Value) bool {\n\tswitch getKind(v) {\n\tcase reflect.Array, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn v.Len() == 0\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn v.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.Interface, reflect.Ptr:\n\t\treturn v.IsNil()\n\t}\n\treturn false\n}\n\nfunc getKind(val reflect.Value) reflect.Kind {\n\tkind := val.Kind()\n\n\tswitch {\n\tcase kind >= reflect.Int && kind <= reflect.Int64:\n\t\treturn reflect.Int\n\tcase kind >= reflect.Uint && kind <= reflect.Uint64:\n\t\treturn reflect.Uint\n\tcase kind >= reflect.Float32 && kind <= reflect.Float64:\n\t\treturn reflect.Float32\n\tdefault:\n\t\treturn kind\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/moby/patternmatcher/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-2018 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": "vendor/github.com/moby/patternmatcher/NOTICE",
    "content": "Docker\nCopyright 2012-2017 Docker, Inc.\n\nThis product includes software developed at Docker, Inc. (https://www.docker.com).\n\nThe following is courtesy of our legal counsel:\n\n\nUse and transfer of Docker may be subject to certain restrictions by the\nUnited States and other governments.\nIt is your responsibility to ensure that your use and/or transfer does not\nviolate applicable laws.\n\nFor more information, please see https://www.bis.doc.gov\n\nSee also https://www.apache.org/dev/crypto.html and/or seek legal counsel.\n"
  },
  {
    "path": "vendor/github.com/moby/patternmatcher/patternmatcher.go",
    "content": "package patternmatcher\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regexp\"\n\t\"strings\"\n\t\"text/scanner\"\n\t\"unicode/utf8\"\n)\n\n// escapeBytes is a bitmap used to check whether a character should be escaped when creating the regex.\nvar escapeBytes [8]byte\n\n// shouldEscape reports whether a rune should be escaped as part of the regex.\n//\n// This only includes characters that require escaping in regex but are also NOT valid filepath pattern characters.\n// Additionally, '\\' is not excluded because there is specific logic to properly handle this, as it's a path separator\n// on Windows.\n//\n// Adapted from regexp::QuoteMeta in go stdlib.\n// See https://cs.opensource.google/go/go/+/refs/tags/go1.17.2:src/regexp/regexp.go;l=703-715;drc=refs%2Ftags%2Fgo1.17.2\nfunc shouldEscape(b rune) bool {\n\treturn b < utf8.RuneSelf && escapeBytes[b%8]&(1<<(b/8)) != 0\n}\n\nfunc init() {\n\tfor _, b := range []byte(`.+()|{}$`) {\n\t\tescapeBytes[b%8] |= 1 << (b / 8)\n\t}\n}\n\n// PatternMatcher allows checking paths against a list of patterns\ntype PatternMatcher struct {\n\tpatterns   []*Pattern\n\texclusions bool\n}\n\n// New creates a new matcher object for specific patterns that can\n// be used later to match against patterns against paths\nfunc New(patterns []string) (*PatternMatcher, error) {\n\tpm := &PatternMatcher{\n\t\tpatterns: make([]*Pattern, 0, len(patterns)),\n\t}\n\tfor _, p := range patterns {\n\t\t// Eliminate leading and trailing whitespace.\n\t\tp = strings.TrimSpace(p)\n\t\tif p == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tp = filepath.Clean(p)\n\t\tnewp := &Pattern{}\n\t\tif p[0] == '!' {\n\t\t\tif len(p) == 1 {\n\t\t\t\treturn nil, errors.New(\"illegal exclusion pattern: \\\"!\\\"\")\n\t\t\t}\n\t\t\tnewp.exclusion = true\n\t\t\tp = p[1:]\n\t\t\tpm.exclusions = true\n\t\t}\n\t\t// Do some syntax checking on the pattern.\n\t\t// filepath's Match() has some really weird rules that are inconsistent\n\t\t// so instead of trying to dup their logic, just call Match() for its\n\t\t// error state and if there is an error in the pattern return it.\n\t\t// If this becomes an issue we can remove this since its really only\n\t\t// needed in the error (syntax) case - which isn't really critical.\n\t\tif _, err := filepath.Match(p, \".\"); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnewp.cleanedPattern = p\n\t\tnewp.dirs = strings.Split(p, string(os.PathSeparator))\n\t\tpm.patterns = append(pm.patterns, newp)\n\t}\n\treturn pm, nil\n}\n\n// Matches returns true if \"file\" matches any of the patterns\n// and isn't excluded by any of the subsequent patterns.\n//\n// The \"file\" argument should be a slash-delimited path.\n//\n// Matches is not safe to call concurrently.\n//\n// Deprecated: This implementation is buggy (it only checks a single parent dir\n// against the pattern) and will be removed soon. Use either\n// MatchesOrParentMatches or MatchesUsingParentResults instead.\nfunc (pm *PatternMatcher) Matches(file string) (bool, error) {\n\tmatched := false\n\tfile = filepath.FromSlash(file)\n\tparentPath := filepath.Dir(file)\n\tparentPathDirs := strings.Split(parentPath, string(os.PathSeparator))\n\n\tfor _, pattern := range pm.patterns {\n\t\t// Skip evaluation if this is an inclusion and the filename\n\t\t// already matched the pattern, or it's an exclusion and it has\n\t\t// not matched the pattern yet.\n\t\tif pattern.exclusion != matched {\n\t\t\tcontinue\n\t\t}\n\n\t\tmatch, err := pattern.match(file)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tif !match && parentPath != \".\" {\n\t\t\t// Check to see if the pattern matches one of our parent dirs.\n\t\t\tif len(pattern.dirs) <= len(parentPathDirs) {\n\t\t\t\tmatch, _ = pattern.match(strings.Join(parentPathDirs[:len(pattern.dirs)], string(os.PathSeparator)))\n\t\t\t}\n\t\t}\n\n\t\tif match {\n\t\t\tmatched = !pattern.exclusion\n\t\t}\n\t}\n\n\treturn matched, nil\n}\n\n// MatchesOrParentMatches returns true if \"file\" matches any of the patterns\n// and isn't excluded by any of the subsequent patterns.\n//\n// The \"file\" argument should be a slash-delimited path.\n//\n// Matches is not safe to call concurrently.\nfunc (pm *PatternMatcher) MatchesOrParentMatches(file string) (bool, error) {\n\tmatched := false\n\tfile = filepath.FromSlash(file)\n\tparentPath := filepath.Dir(file)\n\tparentPathDirs := strings.Split(parentPath, string(os.PathSeparator))\n\n\tfor _, pattern := range pm.patterns {\n\t\t// Skip evaluation if this is an inclusion and the filename\n\t\t// already matched the pattern, or it's an exclusion and it has\n\t\t// not matched the pattern yet.\n\t\tif pattern.exclusion != matched {\n\t\t\tcontinue\n\t\t}\n\n\t\tmatch, err := pattern.match(file)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tif !match && parentPath != \".\" {\n\t\t\t// Check to see if the pattern matches one of our parent dirs.\n\t\t\tfor i := range parentPathDirs {\n\t\t\t\tmatch, _ = pattern.match(strings.Join(parentPathDirs[:i+1], string(os.PathSeparator)))\n\t\t\t\tif match {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif match {\n\t\t\tmatched = !pattern.exclusion\n\t\t}\n\t}\n\n\treturn matched, nil\n}\n\n// MatchesUsingParentResult returns true if \"file\" matches any of the patterns\n// and isn't excluded by any of the subsequent patterns. The functionality is\n// the same as Matches, but as an optimization, the caller keeps track of\n// whether the parent directory matched.\n//\n// The \"file\" argument should be a slash-delimited path.\n//\n// MatchesUsingParentResult is not safe to call concurrently.\n//\n// Deprecated: this function does behave correctly in some cases (see\n// https://github.com/docker/buildx/issues/850).\n//\n// Use MatchesUsingParentResults instead.\nfunc (pm *PatternMatcher) MatchesUsingParentResult(file string, parentMatched bool) (bool, error) {\n\tmatched := parentMatched\n\tfile = filepath.FromSlash(file)\n\n\tfor _, pattern := range pm.patterns {\n\t\t// Skip evaluation if this is an inclusion and the filename\n\t\t// already matched the pattern, or it's an exclusion and it has\n\t\t// not matched the pattern yet.\n\t\tif pattern.exclusion != matched {\n\t\t\tcontinue\n\t\t}\n\n\t\tmatch, err := pattern.match(file)\n\t\tif err != nil {\n\t\t\treturn false, err\n\t\t}\n\n\t\tif match {\n\t\t\tmatched = !pattern.exclusion\n\t\t}\n\t}\n\treturn matched, nil\n}\n\n// MatchInfo tracks information about parent dir matches while traversing a\n// filesystem.\ntype MatchInfo struct {\n\tparentMatched []bool\n}\n\n// MatchesUsingParentResults returns true if \"file\" matches any of the patterns\n// and isn't excluded by any of the subsequent patterns. The functionality is\n// the same as Matches, but as an optimization, the caller passes in\n// intermediate results from matching the parent directory.\n//\n// The \"file\" argument should be a slash-delimited path.\n//\n// MatchesUsingParentResults is not safe to call concurrently.\nfunc (pm *PatternMatcher) MatchesUsingParentResults(file string, parentMatchInfo MatchInfo) (bool, MatchInfo, error) {\n\tparentMatched := parentMatchInfo.parentMatched\n\tif len(parentMatched) != 0 && len(parentMatched) != len(pm.patterns) {\n\t\treturn false, MatchInfo{}, errors.New(\"wrong number of values in parentMatched\")\n\t}\n\n\tfile = filepath.FromSlash(file)\n\tmatched := false\n\n\tmatchInfo := MatchInfo{\n\t\tparentMatched: make([]bool, len(pm.patterns)),\n\t}\n\tfor i, pattern := range pm.patterns {\n\t\tmatch := false\n\t\t// If the parent matched this pattern, we don't need to recheck.\n\t\tif len(parentMatched) != 0 {\n\t\t\tmatch = parentMatched[i]\n\t\t}\n\n\t\tif !match {\n\t\t\t// Skip evaluation if this is an inclusion and the filename\n\t\t\t// already matched the pattern, or it's an exclusion and it has\n\t\t\t// not matched the pattern yet.\n\t\t\tif pattern.exclusion != matched {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar err error\n\t\t\tmatch, err = pattern.match(file)\n\t\t\tif err != nil {\n\t\t\t\treturn false, matchInfo, err\n\t\t\t}\n\n\t\t\t// If the zero value of MatchInfo was passed in, we don't have\n\t\t\t// any information about the parent dir's match results, and we\n\t\t\t// apply the same logic as MatchesOrParentMatches.\n\t\t\tif !match && len(parentMatched) == 0 {\n\t\t\t\tif parentPath := filepath.Dir(file); parentPath != \".\" {\n\t\t\t\t\tparentPathDirs := strings.Split(parentPath, string(os.PathSeparator))\n\t\t\t\t\t// Check to see if the pattern matches one of our parent dirs.\n\t\t\t\t\tfor i := range parentPathDirs {\n\t\t\t\t\t\tmatch, _ = pattern.match(strings.Join(parentPathDirs[:i+1], string(os.PathSeparator)))\n\t\t\t\t\t\tif match {\n\t\t\t\t\t\t\tbreak\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\tmatchInfo.parentMatched[i] = match\n\n\t\tif match {\n\t\t\tmatched = !pattern.exclusion\n\t\t}\n\t}\n\treturn matched, matchInfo, nil\n}\n\n// Exclusions returns true if any of the patterns define exclusions\nfunc (pm *PatternMatcher) Exclusions() bool {\n\treturn pm.exclusions\n}\n\n// Patterns returns array of active patterns\nfunc (pm *PatternMatcher) Patterns() []*Pattern {\n\treturn pm.patterns\n}\n\n// Pattern defines a single regexp used to filter file paths.\ntype Pattern struct {\n\tmatchType      matchType\n\tcleanedPattern string\n\tdirs           []string\n\tregexp         *regexp.Regexp\n\texclusion      bool\n}\n\ntype matchType int\n\nconst (\n\tunknownMatch matchType = iota\n\texactMatch\n\tprefixMatch\n\tsuffixMatch\n\tregexpMatch\n)\n\nfunc (p *Pattern) String() string {\n\treturn p.cleanedPattern\n}\n\n// Exclusion returns true if this pattern defines exclusion\nfunc (p *Pattern) Exclusion() bool {\n\treturn p.exclusion\n}\n\nfunc (p *Pattern) match(path string) (bool, error) {\n\tif p.matchType == unknownMatch {\n\t\tif err := p.compile(string(os.PathSeparator)); err != nil {\n\t\t\treturn false, filepath.ErrBadPattern\n\t\t}\n\t}\n\n\tswitch p.matchType {\n\tcase exactMatch:\n\t\treturn path == p.cleanedPattern, nil\n\tcase prefixMatch:\n\t\t// strip trailing **\n\t\treturn strings.HasPrefix(path, p.cleanedPattern[:len(p.cleanedPattern)-2]), nil\n\tcase suffixMatch:\n\t\t// strip leading **\n\t\tsuffix := p.cleanedPattern[2:]\n\t\tif strings.HasSuffix(path, suffix) {\n\t\t\treturn true, nil\n\t\t}\n\t\t// **/foo matches \"foo\"\n\t\treturn suffix[0] == os.PathSeparator && path == suffix[1:], nil\n\tcase regexpMatch:\n\t\treturn p.regexp.MatchString(path), nil\n\t}\n\n\treturn false, nil\n}\n\nfunc (p *Pattern) compile(sl string) error {\n\tregStr := \"^\"\n\tpattern := p.cleanedPattern\n\t// Go through the pattern and convert it to a regexp.\n\t// We use a scanner so we can support utf-8 chars.\n\tvar scan scanner.Scanner\n\tscan.Init(strings.NewReader(pattern))\n\n\tescSL := sl\n\tif sl == `\\` {\n\t\tescSL += `\\`\n\t}\n\n\tp.matchType = exactMatch\n\tfor i := 0; scan.Peek() != scanner.EOF; i++ {\n\t\tch := scan.Next()\n\n\t\tif ch == '*' {\n\t\t\tif scan.Peek() == '*' {\n\t\t\t\t// is some flavor of \"**\"\n\t\t\t\tscan.Next()\n\n\t\t\t\t// Treat **/ as ** so eat the \"/\"\n\t\t\t\tif string(scan.Peek()) == sl {\n\t\t\t\t\tscan.Next()\n\t\t\t\t}\n\n\t\t\t\tif scan.Peek() == scanner.EOF {\n\t\t\t\t\t// is \"**EOF\" - to align with .gitignore just accept all\n\t\t\t\t\tif p.matchType == exactMatch {\n\t\t\t\t\t\tp.matchType = prefixMatch\n\t\t\t\t\t} else {\n\t\t\t\t\t\tregStr += \".*\"\n\t\t\t\t\t\tp.matchType = regexpMatch\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// is \"**\"\n\t\t\t\t\t// Note that this allows for any # of /'s (even 0) because\n\t\t\t\t\t// the .* will eat everything, even /'s\n\t\t\t\t\tregStr += \"(.*\" + escSL + \")?\"\n\t\t\t\t\tp.matchType = regexpMatch\n\t\t\t\t}\n\n\t\t\t\tif i == 0 {\n\t\t\t\t\tp.matchType = suffixMatch\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// is \"*\" so map it to anything but \"/\"\n\t\t\t\tregStr += \"[^\" + escSL + \"]*\"\n\t\t\t\tp.matchType = regexpMatch\n\t\t\t}\n\t\t} else if ch == '?' {\n\t\t\t// \"?\" is any char except \"/\"\n\t\t\tregStr += \"[^\" + escSL + \"]\"\n\t\t\tp.matchType = regexpMatch\n\t\t} else if shouldEscape(ch) {\n\t\t\t// Escape some regexp special chars that have no meaning\n\t\t\t// in golang's filepath.Match\n\t\t\tregStr += `\\` + string(ch)\n\t\t} else if ch == '\\\\' {\n\t\t\t// escape next char. Note that a trailing \\ in the pattern\n\t\t\t// will be left alone (but need to escape it)\n\t\t\tif sl == `\\` {\n\t\t\t\t// On windows map \"\\\" to \"\\\\\", meaning an escaped backslash,\n\t\t\t\t// and then just continue because filepath.Match on\n\t\t\t\t// Windows doesn't allow escaping at all\n\t\t\t\tregStr += escSL\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif scan.Peek() != scanner.EOF {\n\t\t\t\tregStr += `\\` + string(scan.Next())\n\t\t\t\tp.matchType = regexpMatch\n\t\t\t} else {\n\t\t\t\tregStr += `\\`\n\t\t\t}\n\t\t} else if ch == '[' || ch == ']' {\n\t\t\tregStr += string(ch)\n\t\t\tp.matchType = regexpMatch\n\t\t} else {\n\t\t\tregStr += string(ch)\n\t\t}\n\t}\n\n\tif p.matchType != regexpMatch {\n\t\treturn nil\n\t}\n\n\tregStr += \"$\"\n\n\tre, err := regexp.Compile(regStr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tp.regexp = re\n\tp.matchType = regexpMatch\n\treturn nil\n}\n\n// Matches returns true if file matches any of the patterns\n// and isn't excluded by any of the subsequent patterns.\n//\n// This implementation is buggy (it only checks a single parent dir against the\n// pattern) and will be removed soon. Use MatchesOrParentMatches instead.\nfunc Matches(file string, patterns []string) (bool, error) {\n\tpm, err := New(patterns)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tfile = filepath.Clean(file)\n\n\tif file == \".\" {\n\t\t// Don't let them exclude everything, kind of silly.\n\t\treturn false, nil\n\t}\n\n\treturn pm.Matches(file)\n}\n\n// MatchesOrParentMatches returns true if file matches any of the patterns\n// and isn't excluded by any of the subsequent patterns.\nfunc MatchesOrParentMatches(file string, patterns []string) (bool, error) {\n\tpm, err := New(patterns)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\tfile = filepath.Clean(file)\n\n\tif file == \".\" {\n\t\t// Don't let them exclude everything, kind of silly.\n\t\treturn false, nil\n\t}\n\n\treturn pm.MatchesOrParentMatches(file)\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/CONTRIBUTING.md",
    "content": "# Contributing to SpdyStream\n\nWant to hack on spdystream? Awesome! Here are instructions to get you\nstarted.\n\nSpdyStream is a part of the [Docker](https://docker.io) project, and follows\nthe same rules and principles. If you're already familiar with the way\nDocker does things, you'll feel right at home.\n\nOtherwise, go read\n[Docker's contributions guidelines](https://github.com/dotcloud/docker/blob/master/CONTRIBUTING.md).\n\nHappy hacking!\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/moby/spdystream/MAINTAINERS",
    "content": "# Spdystream maintainers file\n#\n# This file describes who runs the moby/spdystream project and how.\n# This is a living document - if you see something out of date or missing, speak up!\n#\n# It is structured to be consumable by both humans and programs.\n# To extract its contents programmatically, use any TOML-compliant parser.\n#\n# This file is compiled into the MAINTAINERS file in docker/opensource.\n#\n[Org]\n\t[Org.\"Core maintainers\"]\n\t\tpeople = [\n\t\t\t\"adisky\",\n\t\t\t\"dims\",\n\t\t\t\"dmcgowan\",\n\t\t]\n\n[people]\n\n# A reference list of all people associated with the project.\n# All other sections should refer to people by their canonical key\n# in the people section.\n\n\t# ADD YOURSELF HERE IN ALPHABETICAL ORDER\n\n\t[people.adisky]\n\tName = \"Aditi Sharma\"\n\tEmail = \"adi.sky17@gmail.com\"\n\tGitHub = \"adisky\"\n\n\t[people.dims]\n\tName = \"Davanum Srinivas\"\n\tEmail = \"davanum@gmail.com\"\n\tGitHub = \"dims\"\n\n\t[people.dmcgowan]\n\tName = \"Derek McGowan\"\n\tEmail = \"derek@mcg.dev\"\n\tGitHub = \"dmcgowan\"\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/NOTICE",
    "content": "SpdyStream\nCopyright 2014-2021 Docker Inc.\n\nThis product includes software developed at\nDocker Inc. (https://www.docker.com/).\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/README.md",
    "content": "# SpdyStream\n\nA multiplexed stream library using spdy\n\n## Usage\n\nClient example (connecting to mirroring server without auth)\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/moby/spdystream\"\n\t\"net\"\n\t\"net/http\"\n)\n\nfunc main() {\n\tconn, err := net.Dial(\"tcp\", \"localhost:8080\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tspdyConn, err := spdystream.NewConnection(conn, false)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tgo spdyConn.Serve(spdystream.NoOpStreamHandler)\n\tstream, err := spdyConn.CreateStream(http.Header{}, nil, false)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tstream.Wait()\n\n\tfmt.Fprint(stream, \"Writing to stream\")\n\n\tbuf := make([]byte, 25)\n\tstream.Read(buf)\n\tfmt.Println(string(buf))\n\n\tstream.Close()\n}\n```\n\nServer example (mirroring server without auth)\n\n```go\npackage main\n\nimport (\n\t\"github.com/moby/spdystream\"\n\t\"net\"\n)\n\nfunc main() {\n\tlistener, err := net.Listen(\"tcp\", \"localhost:8080\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfor {\n\t\tconn, err := listener.Accept()\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tspdyConn, err := spdystream.NewConnection(conn, true)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tgo spdyConn.Serve(spdystream.MirrorStreamHandler)\n\t}\n}\n```\n\n## Copyright and license\n\nCopyright 2013-2021 Docker, inc. Released under the [Apache 2.0 license](LICENSE).\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/connection.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\npackage spdystream\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/moby/spdystream/spdy\"\n)\n\nvar (\n\tErrInvalidStreamId   = errors.New(\"Invalid stream id\")\n\tErrTimeout           = errors.New(\"Timeout occurred\")\n\tErrReset             = errors.New(\"Stream reset\")\n\tErrWriteClosedStream = errors.New(\"Write on closed stream\")\n)\n\nconst (\n\tFRAME_WORKERS = 5\n\tQUEUE_SIZE    = 50\n)\n\ntype StreamHandler func(stream *Stream)\n\ntype AuthHandler func(header http.Header, slot uint8, parent uint32) bool\n\ntype idleAwareFramer struct {\n\tf              *spdy.Framer\n\tconn           *Connection\n\twriteLock      sync.Mutex\n\tresetChan      chan struct{}\n\tsetTimeoutLock sync.Mutex\n\tsetTimeoutChan chan time.Duration\n\ttimeout        time.Duration\n}\n\nfunc newIdleAwareFramer(framer *spdy.Framer) *idleAwareFramer {\n\tiaf := &idleAwareFramer{\n\t\tf:         framer,\n\t\tresetChan: make(chan struct{}, 2),\n\t\t// setTimeoutChan needs to be buffered to avoid deadlocks when calling setIdleTimeout at about\n\t\t// the same time the connection is being closed\n\t\tsetTimeoutChan: make(chan time.Duration, 1),\n\t}\n\treturn iaf\n}\n\nfunc (i *idleAwareFramer) monitor() {\n\tvar (\n\t\ttimer          *time.Timer\n\t\texpired        <-chan time.Time\n\t\tresetChan      = i.resetChan\n\t\tsetTimeoutChan = i.setTimeoutChan\n\t)\nLoop:\n\tfor {\n\t\tselect {\n\t\tcase timeout := <-i.setTimeoutChan:\n\t\t\ti.timeout = timeout\n\t\t\tif timeout == 0 {\n\t\t\t\tif timer != nil {\n\t\t\t\t\ttimer.Stop()\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif timer == nil {\n\t\t\t\t\ttimer = time.NewTimer(timeout)\n\t\t\t\t\texpired = timer.C\n\t\t\t\t} else {\n\t\t\t\t\ttimer.Reset(timeout)\n\t\t\t\t}\n\t\t\t}\n\t\tcase <-resetChan:\n\t\t\tif timer != nil && i.timeout > 0 {\n\t\t\t\ttimer.Reset(i.timeout)\n\t\t\t}\n\t\tcase <-expired:\n\t\t\ti.conn.streamCond.L.Lock()\n\t\t\tstreams := i.conn.streams\n\t\t\ti.conn.streams = make(map[spdy.StreamId]*Stream)\n\t\t\ti.conn.streamCond.Broadcast()\n\t\t\ti.conn.streamCond.L.Unlock()\n\t\t\tgo func() {\n\t\t\t\tfor _, stream := range streams {\n\t\t\t\t\tstream.resetStream()\n\t\t\t\t}\n\t\t\t\ti.conn.Close()\n\t\t\t}()\n\t\tcase <-i.conn.closeChan:\n\t\t\tif timer != nil {\n\t\t\t\ttimer.Stop()\n\t\t\t}\n\n\t\t\t// Start a goroutine to drain resetChan. This is needed because we've seen\n\t\t\t// some unit tests with large numbers of goroutines get into a situation\n\t\t\t// where resetChan fills up, at least 1 call to Write() is still trying to\n\t\t\t// send to resetChan, the connection gets closed, and this case statement\n\t\t\t// attempts to grab the write lock that Write() already has, causing a\n\t\t\t// deadlock.\n\t\t\t//\n\t\t\t// See https://github.com/moby/spdystream/issues/49 for more details.\n\t\t\tgo func() {\n\t\t\t\tfor range resetChan {\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\tgo func() {\n\t\t\t\tfor range setTimeoutChan {\n\t\t\t\t}\n\t\t\t}()\n\n\t\t\ti.writeLock.Lock()\n\t\t\tclose(resetChan)\n\t\t\ti.resetChan = nil\n\t\t\ti.writeLock.Unlock()\n\n\t\t\ti.setTimeoutLock.Lock()\n\t\t\tclose(i.setTimeoutChan)\n\t\t\ti.setTimeoutChan = nil\n\t\t\ti.setTimeoutLock.Unlock()\n\n\t\t\tbreak Loop\n\t\t}\n\t}\n\n\t// Drain resetChan\n\tfor range resetChan {\n\t}\n}\n\nfunc (i *idleAwareFramer) WriteFrame(frame spdy.Frame) error {\n\ti.writeLock.Lock()\n\tdefer i.writeLock.Unlock()\n\tif i.resetChan == nil {\n\t\treturn io.EOF\n\t}\n\terr := i.f.WriteFrame(frame)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ti.resetChan <- struct{}{}\n\n\treturn nil\n}\n\nfunc (i *idleAwareFramer) ReadFrame() (spdy.Frame, error) {\n\tframe, err := i.f.ReadFrame()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// resetChan should never be closed since it is only closed\n\t// when the connection has closed its closeChan. This closure\n\t// only occurs after all Reads have finished\n\t// TODO (dmcgowan): refactor relationship into connection\n\ti.resetChan <- struct{}{}\n\n\treturn frame, nil\n}\n\nfunc (i *idleAwareFramer) setIdleTimeout(timeout time.Duration) {\n\ti.setTimeoutLock.Lock()\n\tdefer i.setTimeoutLock.Unlock()\n\n\tif i.setTimeoutChan == nil {\n\t\treturn\n\t}\n\n\ti.setTimeoutChan <- timeout\n}\n\ntype Connection struct {\n\tconn   net.Conn\n\tframer *idleAwareFramer\n\n\tcloseChan      chan bool\n\tgoneAway       bool\n\tlastStreamChan chan<- *Stream\n\tgoAwayTimeout  time.Duration\n\tcloseTimeout   time.Duration\n\n\tstreamLock *sync.RWMutex\n\tstreamCond *sync.Cond\n\tstreams    map[spdy.StreamId]*Stream\n\n\tnextIdLock       sync.Mutex\n\treceiveIdLock    sync.Mutex\n\tnextStreamId     spdy.StreamId\n\treceivedStreamId spdy.StreamId\n\n\tpingIdLock sync.Mutex\n\tpingId     uint32\n\tpingChans  map[uint32]chan error\n\n\tshutdownLock sync.Mutex\n\tshutdownChan chan error\n\thasShutdown  bool\n\n\t// for testing https://github.com/moby/spdystream/pull/56\n\tdataFrameHandler func(*spdy.DataFrame) error\n}\n\n// NewConnection creates a new spdy connection from an existing\n// network connection.\nfunc NewConnection(conn net.Conn, server bool) (*Connection, error) {\n\tframer, framerErr := spdy.NewFramer(conn, conn)\n\tif framerErr != nil {\n\t\treturn nil, framerErr\n\t}\n\tidleAwareFramer := newIdleAwareFramer(framer)\n\tvar sid spdy.StreamId\n\tvar rid spdy.StreamId\n\tvar pid uint32\n\tif server {\n\t\tsid = 2\n\t\trid = 1\n\t\tpid = 2\n\t} else {\n\t\tsid = 1\n\t\trid = 2\n\t\tpid = 1\n\t}\n\n\tstreamLock := new(sync.RWMutex)\n\tstreamCond := sync.NewCond(streamLock)\n\n\tsession := &Connection{\n\t\tconn:   conn,\n\t\tframer: idleAwareFramer,\n\n\t\tcloseChan:     make(chan bool),\n\t\tgoAwayTimeout: time.Duration(0),\n\t\tcloseTimeout:  time.Duration(0),\n\n\t\tstreamLock:       streamLock,\n\t\tstreamCond:       streamCond,\n\t\tstreams:          make(map[spdy.StreamId]*Stream),\n\t\tnextStreamId:     sid,\n\t\treceivedStreamId: rid,\n\n\t\tpingId:    pid,\n\t\tpingChans: make(map[uint32]chan error),\n\n\t\tshutdownChan: make(chan error),\n\t}\n\tsession.dataFrameHandler = session.handleDataFrame\n\tidleAwareFramer.conn = session\n\tgo idleAwareFramer.monitor()\n\n\treturn session, nil\n}\n\n// Ping sends a ping frame across the connection and\n// returns the response time\nfunc (s *Connection) Ping() (time.Duration, error) {\n\tpid := s.pingId\n\ts.pingIdLock.Lock()\n\tif s.pingId > 0x7ffffffe {\n\t\ts.pingId = s.pingId - 0x7ffffffe\n\t} else {\n\t\ts.pingId = s.pingId + 2\n\t}\n\ts.pingIdLock.Unlock()\n\tpingChan := make(chan error)\n\ts.pingChans[pid] = pingChan\n\tdefer delete(s.pingChans, pid)\n\n\tframe := &spdy.PingFrame{Id: pid}\n\tstartTime := time.Now()\n\twriteErr := s.framer.WriteFrame(frame)\n\tif writeErr != nil {\n\t\treturn time.Duration(0), writeErr\n\t}\n\tselect {\n\tcase <-s.closeChan:\n\t\treturn time.Duration(0), errors.New(\"connection closed\")\n\tcase err, ok := <-pingChan:\n\t\tif ok && err != nil {\n\t\t\treturn time.Duration(0), err\n\t\t}\n\t\tbreak\n\t}\n\treturn time.Since(startTime), nil\n}\n\n// Serve handles frames sent from the server, including reply frames\n// which are needed to fully initiate connections.  Both clients and servers\n// should call Serve in a separate goroutine before creating streams.\nfunc (s *Connection) Serve(newHandler StreamHandler) {\n\t// use a WaitGroup to wait for all frames to be drained after receiving\n\t// go-away.\n\tvar wg sync.WaitGroup\n\n\t// Parition queues to ensure stream frames are handled\n\t// by the same worker, ensuring order is maintained\n\tframeQueues := make([]*PriorityFrameQueue, FRAME_WORKERS)\n\tfor i := 0; i < FRAME_WORKERS; i++ {\n\t\tframeQueues[i] = NewPriorityFrameQueue(QUEUE_SIZE)\n\n\t\t// Ensure frame queue is drained when connection is closed\n\t\tgo func(frameQueue *PriorityFrameQueue) {\n\t\t\t<-s.closeChan\n\t\t\tframeQueue.Drain()\n\t\t}(frameQueues[i])\n\n\t\twg.Add(1)\n\t\tgo func(frameQueue *PriorityFrameQueue) {\n\t\t\t// let the WaitGroup know this worker is done\n\t\t\tdefer wg.Done()\n\n\t\t\ts.frameHandler(frameQueue, newHandler)\n\t\t}(frameQueues[i])\n\t}\n\n\tvar (\n\t\tpartitionRoundRobin int\n\t\tgoAwayFrame         *spdy.GoAwayFrame\n\t)\nLoop:\n\tfor {\n\t\treadFrame, err := s.framer.ReadFrame()\n\t\tif err != nil {\n\t\t\tif err != io.EOF {\n\t\t\t\tdebugMessage(\"frame read error: %s\", err)\n\t\t\t} else {\n\t\t\t\tdebugMessage(\"(%p) EOF received\", s)\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tvar priority uint8\n\t\tvar partition int\n\t\tswitch frame := readFrame.(type) {\n\t\tcase *spdy.SynStreamFrame:\n\t\t\tif s.checkStreamFrame(frame) {\n\t\t\t\tpriority = frame.Priority\n\t\t\t\tpartition = int(frame.StreamId % FRAME_WORKERS)\n\t\t\t\tdebugMessage(\"(%p) Add stream frame: %d \", s, frame.StreamId)\n\t\t\t\ts.addStreamFrame(frame)\n\t\t\t} else {\n\t\t\t\tdebugMessage(\"(%p) Rejected stream frame: %d \", s, frame.StreamId)\n\t\t\t\tcontinue\n\t\t\t}\n\t\tcase *spdy.SynReplyFrame:\n\t\t\tpriority = s.getStreamPriority(frame.StreamId)\n\t\t\tpartition = int(frame.StreamId % FRAME_WORKERS)\n\t\tcase *spdy.DataFrame:\n\t\t\tpriority = s.getStreamPriority(frame.StreamId)\n\t\t\tpartition = int(frame.StreamId % FRAME_WORKERS)\n\t\tcase *spdy.RstStreamFrame:\n\t\t\tpriority = s.getStreamPriority(frame.StreamId)\n\t\t\tpartition = int(frame.StreamId % FRAME_WORKERS)\n\t\tcase *spdy.HeadersFrame:\n\t\t\tpriority = s.getStreamPriority(frame.StreamId)\n\t\t\tpartition = int(frame.StreamId % FRAME_WORKERS)\n\t\tcase *spdy.PingFrame:\n\t\t\tpriority = 0\n\t\t\tpartition = partitionRoundRobin\n\t\t\tpartitionRoundRobin = (partitionRoundRobin + 1) % FRAME_WORKERS\n\t\tcase *spdy.GoAwayFrame:\n\t\t\t// hold on to the go away frame and exit the loop\n\t\t\tgoAwayFrame = frame\n\t\t\tbreak Loop\n\t\tdefault:\n\t\t\tpriority = 7\n\t\t\tpartition = partitionRoundRobin\n\t\t\tpartitionRoundRobin = (partitionRoundRobin + 1) % FRAME_WORKERS\n\t\t}\n\t\tframeQueues[partition].Push(readFrame, priority)\n\t}\n\tclose(s.closeChan)\n\n\t// wait for all frame handler workers to indicate they've drained their queues\n\t// before handling the go away frame\n\twg.Wait()\n\n\tif goAwayFrame != nil {\n\t\ts.handleGoAwayFrame(goAwayFrame)\n\t}\n\n\t// now it's safe to close remote channels and empty s.streams\n\ts.streamCond.L.Lock()\n\t// notify streams that they're now closed, which will\n\t// unblock any stream Read() calls\n\tfor _, stream := range s.streams {\n\t\tstream.closeRemoteChannels()\n\t}\n\ts.streams = make(map[spdy.StreamId]*Stream)\n\ts.streamCond.Broadcast()\n\ts.streamCond.L.Unlock()\n}\n\nfunc (s *Connection) frameHandler(frameQueue *PriorityFrameQueue, newHandler StreamHandler) {\n\tfor {\n\t\tpopFrame := frameQueue.Pop()\n\t\tif popFrame == nil {\n\t\t\treturn\n\t\t}\n\n\t\tvar frameErr error\n\t\tswitch frame := popFrame.(type) {\n\t\tcase *spdy.SynStreamFrame:\n\t\t\tframeErr = s.handleStreamFrame(frame, newHandler)\n\t\tcase *spdy.SynReplyFrame:\n\t\t\tframeErr = s.handleReplyFrame(frame)\n\t\tcase *spdy.DataFrame:\n\t\t\tframeErr = s.dataFrameHandler(frame)\n\t\tcase *spdy.RstStreamFrame:\n\t\t\tframeErr = s.handleResetFrame(frame)\n\t\tcase *spdy.HeadersFrame:\n\t\t\tframeErr = s.handleHeaderFrame(frame)\n\t\tcase *spdy.PingFrame:\n\t\t\tframeErr = s.handlePingFrame(frame)\n\t\tcase *spdy.GoAwayFrame:\n\t\t\tframeErr = s.handleGoAwayFrame(frame)\n\t\tdefault:\n\t\t\tframeErr = fmt.Errorf(\"unhandled frame type: %T\", frame)\n\t\t}\n\n\t\tif frameErr != nil {\n\t\t\tdebugMessage(\"frame handling error: %s\", frameErr)\n\t\t}\n\t}\n}\n\nfunc (s *Connection) getStreamPriority(streamId spdy.StreamId) uint8 {\n\tstream, streamOk := s.getStream(streamId)\n\tif !streamOk {\n\t\treturn 7\n\t}\n\treturn stream.priority\n}\n\nfunc (s *Connection) addStreamFrame(frame *spdy.SynStreamFrame) {\n\tvar parent *Stream\n\tif frame.AssociatedToStreamId != spdy.StreamId(0) {\n\t\tparent, _ = s.getStream(frame.AssociatedToStreamId)\n\t}\n\n\tstream := &Stream{\n\t\tstreamId:   frame.StreamId,\n\t\tparent:     parent,\n\t\tconn:       s,\n\t\tstartChan:  make(chan error),\n\t\theaders:    frame.Headers,\n\t\tfinished:   (frame.CFHeader.Flags & spdy.ControlFlagUnidirectional) != 0x00,\n\t\treplyCond:  sync.NewCond(new(sync.Mutex)),\n\t\tdataChan:   make(chan []byte),\n\t\theaderChan: make(chan http.Header),\n\t\tcloseChan:  make(chan bool),\n\t\tpriority:   frame.Priority,\n\t}\n\tif frame.CFHeader.Flags&spdy.ControlFlagFin != 0x00 {\n\t\tstream.closeRemoteChannels()\n\t}\n\n\ts.addStream(stream)\n}\n\n// checkStreamFrame checks to see if a stream frame is allowed.\n// If the stream is invalid, then a reset frame with protocol error\n// will be returned.\nfunc (s *Connection) checkStreamFrame(frame *spdy.SynStreamFrame) bool {\n\ts.receiveIdLock.Lock()\n\tdefer s.receiveIdLock.Unlock()\n\tif s.goneAway {\n\t\treturn false\n\t}\n\tvalidationErr := s.validateStreamId(frame.StreamId)\n\tif validationErr != nil {\n\t\tgo func() {\n\t\t\tresetErr := s.sendResetFrame(spdy.ProtocolError, frame.StreamId)\n\t\t\tif resetErr != nil {\n\t\t\t\tdebugMessage(\"reset error: %s\", resetErr)\n\t\t\t}\n\t\t}()\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (s *Connection) handleStreamFrame(frame *spdy.SynStreamFrame, newHandler StreamHandler) error {\n\tstream, ok := s.getStream(frame.StreamId)\n\tif !ok {\n\t\treturn fmt.Errorf(\"Missing stream: %d\", frame.StreamId)\n\t}\n\n\tnewHandler(stream)\n\n\treturn nil\n}\n\nfunc (s *Connection) handleReplyFrame(frame *spdy.SynReplyFrame) error {\n\tdebugMessage(\"(%p) Reply frame received for %d\", s, frame.StreamId)\n\tstream, streamOk := s.getStream(frame.StreamId)\n\tif !streamOk {\n\t\tdebugMessage(\"Reply frame gone away for %d\", frame.StreamId)\n\t\t// Stream has already gone away\n\t\treturn nil\n\t}\n\tif stream.replied {\n\t\t// Stream has already received reply\n\t\treturn nil\n\t}\n\tstream.replied = true\n\n\t// TODO Check for error\n\tif (frame.CFHeader.Flags & spdy.ControlFlagFin) != 0x00 {\n\t\ts.remoteStreamFinish(stream)\n\t}\n\n\tclose(stream.startChan)\n\n\treturn nil\n}\n\nfunc (s *Connection) handleResetFrame(frame *spdy.RstStreamFrame) error {\n\tstream, streamOk := s.getStream(frame.StreamId)\n\tif !streamOk {\n\t\t// Stream has already been removed\n\t\treturn nil\n\t}\n\ts.removeStream(stream)\n\tstream.closeRemoteChannels()\n\n\tif !stream.replied {\n\t\tstream.replied = true\n\t\tstream.startChan <- ErrReset\n\t\tclose(stream.startChan)\n\t}\n\n\tstream.finishLock.Lock()\n\tstream.finished = true\n\tstream.finishLock.Unlock()\n\n\treturn nil\n}\n\nfunc (s *Connection) handleHeaderFrame(frame *spdy.HeadersFrame) error {\n\tstream, streamOk := s.getStream(frame.StreamId)\n\tif !streamOk {\n\t\t// Stream has already gone away\n\t\treturn nil\n\t}\n\tif !stream.replied {\n\t\t// No reply received...Protocol error?\n\t\treturn nil\n\t}\n\n\t// TODO limit headers while not blocking (use buffered chan or goroutine?)\n\tselect {\n\tcase <-stream.closeChan:\n\t\treturn nil\n\tcase stream.headerChan <- frame.Headers:\n\t}\n\n\tif (frame.CFHeader.Flags & spdy.ControlFlagFin) != 0x00 {\n\t\ts.remoteStreamFinish(stream)\n\t}\n\n\treturn nil\n}\n\nfunc (s *Connection) handleDataFrame(frame *spdy.DataFrame) error {\n\tdebugMessage(\"(%p) Data frame received for %d\", s, frame.StreamId)\n\tstream, streamOk := s.getStream(frame.StreamId)\n\tif !streamOk {\n\t\tdebugMessage(\"(%p) Data frame gone away for %d\", s, frame.StreamId)\n\t\t// Stream has already gone away\n\t\treturn nil\n\t}\n\tif !stream.replied {\n\t\tdebugMessage(\"(%p) Data frame not replied %d\", s, frame.StreamId)\n\t\t// No reply received...Protocol error?\n\t\treturn nil\n\t}\n\n\tdebugMessage(\"(%p) (%d) Data frame handling\", stream, stream.streamId)\n\tif len(frame.Data) > 0 {\n\t\tstream.dataLock.RLock()\n\t\tselect {\n\t\tcase <-stream.closeChan:\n\t\t\tdebugMessage(\"(%p) (%d) Data frame not sent (stream shut down)\", stream, stream.streamId)\n\t\tcase stream.dataChan <- frame.Data:\n\t\t\tdebugMessage(\"(%p) (%d) Data frame sent\", stream, stream.streamId)\n\t\t}\n\t\tstream.dataLock.RUnlock()\n\t}\n\tif (frame.Flags & spdy.DataFlagFin) != 0x00 {\n\t\ts.remoteStreamFinish(stream)\n\t}\n\treturn nil\n}\n\nfunc (s *Connection) handlePingFrame(frame *spdy.PingFrame) error {\n\tif s.pingId&0x01 != frame.Id&0x01 {\n\t\treturn s.framer.WriteFrame(frame)\n\t}\n\tpingChan, pingOk := s.pingChans[frame.Id]\n\tif pingOk {\n\t\tclose(pingChan)\n\t}\n\treturn nil\n}\n\nfunc (s *Connection) handleGoAwayFrame(frame *spdy.GoAwayFrame) error {\n\tdebugMessage(\"(%p) Go away received\", s)\n\ts.receiveIdLock.Lock()\n\tif s.goneAway {\n\t\ts.receiveIdLock.Unlock()\n\t\treturn nil\n\t}\n\ts.goneAway = true\n\ts.receiveIdLock.Unlock()\n\n\tif s.lastStreamChan != nil {\n\t\tstream, _ := s.getStream(frame.LastGoodStreamId)\n\t\tgo func() {\n\t\t\ts.lastStreamChan <- stream\n\t\t}()\n\t}\n\n\t// Do not block frame handler waiting for closure\n\tgo s.shutdown(s.goAwayTimeout)\n\n\treturn nil\n}\n\nfunc (s *Connection) remoteStreamFinish(stream *Stream) {\n\tstream.closeRemoteChannels()\n\n\tstream.finishLock.Lock()\n\tif stream.finished {\n\t\t// Stream is fully closed, cleanup\n\t\ts.removeStream(stream)\n\t}\n\tstream.finishLock.Unlock()\n}\n\n// CreateStream creates a new spdy stream using the parameters for\n// creating the stream frame.  The stream frame will be sent upon\n// calling this function, however this function does not wait for\n// the reply frame.  If waiting for the reply is desired, use\n// the stream Wait or WaitTimeout function on the stream returned\n// by this function.\nfunc (s *Connection) CreateStream(headers http.Header, parent *Stream, fin bool) (*Stream, error) {\n\t// MUST synchronize stream creation (all the way to writing the frame)\n\t// as stream IDs **MUST** increase monotonically.\n\ts.nextIdLock.Lock()\n\tdefer s.nextIdLock.Unlock()\n\n\tstreamId := s.getNextStreamId()\n\tif streamId == 0 {\n\t\treturn nil, fmt.Errorf(\"Unable to get new stream id\")\n\t}\n\n\tstream := &Stream{\n\t\tstreamId:   streamId,\n\t\tparent:     parent,\n\t\tconn:       s,\n\t\tstartChan:  make(chan error),\n\t\theaders:    headers,\n\t\tdataChan:   make(chan []byte),\n\t\theaderChan: make(chan http.Header),\n\t\tcloseChan:  make(chan bool),\n\t}\n\n\tdebugMessage(\"(%p) (%p) Create stream\", s, stream)\n\n\ts.addStream(stream)\n\n\treturn stream, s.sendStream(stream, fin)\n}\n\nfunc (s *Connection) shutdown(closeTimeout time.Duration) {\n\t// TODO Ensure this isn't called multiple times\n\ts.shutdownLock.Lock()\n\tif s.hasShutdown {\n\t\ts.shutdownLock.Unlock()\n\t\treturn\n\t}\n\ts.hasShutdown = true\n\ts.shutdownLock.Unlock()\n\n\tvar timeout <-chan time.Time\n\tif closeTimeout > time.Duration(0) {\n\t\ttimeout = time.After(closeTimeout)\n\t}\n\tstreamsClosed := make(chan bool)\n\n\tgo func() {\n\t\ts.streamCond.L.Lock()\n\t\tfor len(s.streams) > 0 {\n\t\t\tdebugMessage(\"Streams opened: %d, %#v\", len(s.streams), s.streams)\n\t\t\ts.streamCond.Wait()\n\t\t}\n\t\ts.streamCond.L.Unlock()\n\t\tclose(streamsClosed)\n\t}()\n\n\tvar err error\n\tselect {\n\tcase <-streamsClosed:\n\t\t// No active streams, close should be safe\n\t\terr = s.conn.Close()\n\tcase <-timeout:\n\t\t// Force ungraceful close\n\t\terr = s.conn.Close()\n\t\t// Wait for cleanup to clear active streams\n\t\t<-streamsClosed\n\t}\n\n\tif err != nil {\n\t\tduration := 10 * time.Minute\n\t\ttime.AfterFunc(duration, func() {\n\t\t\tselect {\n\t\t\tcase err, ok := <-s.shutdownChan:\n\t\t\t\tif ok {\n\t\t\t\t\tdebugMessage(\"Unhandled close error after %s: %s\", duration, err)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t}\n\t\t})\n\t\ts.shutdownChan <- err\n\t}\n\tclose(s.shutdownChan)\n}\n\n// Closes spdy connection by sending GoAway frame and initiating shutdown\nfunc (s *Connection) Close() error {\n\ts.receiveIdLock.Lock()\n\tif s.goneAway {\n\t\ts.receiveIdLock.Unlock()\n\t\treturn nil\n\t}\n\ts.goneAway = true\n\ts.receiveIdLock.Unlock()\n\n\tvar lastStreamId spdy.StreamId\n\tif s.receivedStreamId > 2 {\n\t\tlastStreamId = s.receivedStreamId - 2\n\t}\n\n\tgoAwayFrame := &spdy.GoAwayFrame{\n\t\tLastGoodStreamId: lastStreamId,\n\t\tStatus:           spdy.GoAwayOK,\n\t}\n\n\terr := s.framer.WriteFrame(goAwayFrame)\n\tgo s.shutdown(s.closeTimeout)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// CloseWait closes the connection and waits for shutdown\n// to finish.  Note the underlying network Connection\n// is not closed until the end of shutdown.\nfunc (s *Connection) CloseWait() error {\n\tcloseErr := s.Close()\n\tif closeErr != nil {\n\t\treturn closeErr\n\t}\n\tshutdownErr, ok := <-s.shutdownChan\n\tif ok {\n\t\treturn shutdownErr\n\t}\n\treturn nil\n}\n\n// Wait waits for the connection to finish shutdown or for\n// the wait timeout duration to expire.  This needs to be\n// called either after Close has been called or the GOAWAYFRAME\n// has been received.  If the wait timeout is 0, this function\n// will block until shutdown finishes.  If wait is never called\n// and a shutdown error occurs, that error will be logged as an\n// unhandled error.\nfunc (s *Connection) Wait(waitTimeout time.Duration) error {\n\tvar timeout <-chan time.Time\n\tif waitTimeout > time.Duration(0) {\n\t\ttimeout = time.After(waitTimeout)\n\t}\n\n\tselect {\n\tcase err, ok := <-s.shutdownChan:\n\t\tif ok {\n\t\t\treturn err\n\t\t}\n\tcase <-timeout:\n\t\treturn ErrTimeout\n\t}\n\treturn nil\n}\n\n// NotifyClose registers a channel to be called when the remote\n// peer inidicates connection closure.  The last stream to be\n// received by the remote will be sent on the channel.  The notify\n// timeout will determine the duration between go away received\n// and the connection being closed.\nfunc (s *Connection) NotifyClose(c chan<- *Stream, timeout time.Duration) {\n\ts.goAwayTimeout = timeout\n\ts.lastStreamChan = c\n}\n\n// SetCloseTimeout sets the amount of time close will wait for\n// streams to finish before terminating the underlying network\n// connection.  Setting the timeout to 0 will cause close to\n// wait forever, which is the default.\nfunc (s *Connection) SetCloseTimeout(timeout time.Duration) {\n\ts.closeTimeout = timeout\n}\n\n// SetIdleTimeout sets the amount of time the connection may sit idle before\n// it is forcefully terminated.\nfunc (s *Connection) SetIdleTimeout(timeout time.Duration) {\n\ts.framer.setIdleTimeout(timeout)\n}\n\nfunc (s *Connection) sendHeaders(headers http.Header, stream *Stream, fin bool) error {\n\tvar flags spdy.ControlFlags\n\tif fin {\n\t\tflags = spdy.ControlFlagFin\n\t}\n\n\theaderFrame := &spdy.HeadersFrame{\n\t\tStreamId: stream.streamId,\n\t\tHeaders:  headers,\n\t\tCFHeader: spdy.ControlFrameHeader{Flags: flags},\n\t}\n\n\treturn s.framer.WriteFrame(headerFrame)\n}\n\nfunc (s *Connection) sendReply(headers http.Header, stream *Stream, fin bool) error {\n\tvar flags spdy.ControlFlags\n\tif fin {\n\t\tflags = spdy.ControlFlagFin\n\t}\n\n\treplyFrame := &spdy.SynReplyFrame{\n\t\tStreamId: stream.streamId,\n\t\tHeaders:  headers,\n\t\tCFHeader: spdy.ControlFrameHeader{Flags: flags},\n\t}\n\n\treturn s.framer.WriteFrame(replyFrame)\n}\n\nfunc (s *Connection) sendResetFrame(status spdy.RstStreamStatus, streamId spdy.StreamId) error {\n\tresetFrame := &spdy.RstStreamFrame{\n\t\tStreamId: streamId,\n\t\tStatus:   status,\n\t}\n\n\treturn s.framer.WriteFrame(resetFrame)\n}\n\nfunc (s *Connection) sendReset(status spdy.RstStreamStatus, stream *Stream) error {\n\treturn s.sendResetFrame(status, stream.streamId)\n}\n\nfunc (s *Connection) sendStream(stream *Stream, fin bool) error {\n\tvar flags spdy.ControlFlags\n\tif fin {\n\t\tflags = spdy.ControlFlagFin\n\t\tstream.finished = true\n\t}\n\n\tvar parentId spdy.StreamId\n\tif stream.parent != nil {\n\t\tparentId = stream.parent.streamId\n\t}\n\n\tstreamFrame := &spdy.SynStreamFrame{\n\t\tStreamId:             spdy.StreamId(stream.streamId),\n\t\tAssociatedToStreamId: spdy.StreamId(parentId),\n\t\tHeaders:              stream.headers,\n\t\tCFHeader:             spdy.ControlFrameHeader{Flags: flags},\n\t}\n\n\treturn s.framer.WriteFrame(streamFrame)\n}\n\n// getNextStreamId returns the next sequential id\n// every call should produce a unique value or an error\nfunc (s *Connection) getNextStreamId() spdy.StreamId {\n\tsid := s.nextStreamId\n\tif sid > 0x7fffffff {\n\t\treturn 0\n\t}\n\ts.nextStreamId = s.nextStreamId + 2\n\treturn sid\n}\n\n// PeekNextStreamId returns the next sequential id and keeps the next id untouched\nfunc (s *Connection) PeekNextStreamId() spdy.StreamId {\n\tsid := s.nextStreamId\n\treturn sid\n}\n\nfunc (s *Connection) validateStreamId(rid spdy.StreamId) error {\n\tif rid > 0x7fffffff || rid < s.receivedStreamId {\n\t\treturn ErrInvalidStreamId\n\t}\n\ts.receivedStreamId = rid + 2\n\treturn nil\n}\n\nfunc (s *Connection) addStream(stream *Stream) {\n\ts.streamCond.L.Lock()\n\ts.streams[stream.streamId] = stream\n\tdebugMessage(\"(%p) (%p) Stream added, broadcasting: %d\", s, stream, stream.streamId)\n\ts.streamCond.Broadcast()\n\ts.streamCond.L.Unlock()\n}\n\nfunc (s *Connection) removeStream(stream *Stream) {\n\ts.streamCond.L.Lock()\n\tdelete(s.streams, stream.streamId)\n\tdebugMessage(\"(%p) (%p) Stream removed, broadcasting: %d\", s, stream, stream.streamId)\n\ts.streamCond.Broadcast()\n\ts.streamCond.L.Unlock()\n}\n\nfunc (s *Connection) getStream(streamId spdy.StreamId) (stream *Stream, ok bool) {\n\ts.streamLock.RLock()\n\tstream, ok = s.streams[streamId]\n\ts.streamLock.RUnlock()\n\treturn\n}\n\n// FindStream looks up the given stream id and either waits for the\n// stream to be found or returns nil if the stream id is no longer\n// valid.\nfunc (s *Connection) FindStream(streamId uint32) *Stream {\n\tvar stream *Stream\n\tvar ok bool\n\ts.streamCond.L.Lock()\n\tstream, ok = s.streams[spdy.StreamId(streamId)]\n\tdebugMessage(\"(%p) Found stream %d? %t\", s, spdy.StreamId(streamId), ok)\n\tfor !ok && streamId >= uint32(s.receivedStreamId) {\n\t\ts.streamCond.Wait()\n\t\tstream, ok = s.streams[spdy.StreamId(streamId)]\n\t}\n\ts.streamCond.L.Unlock()\n\treturn stream\n}\n\nfunc (s *Connection) CloseChan() <-chan bool {\n\treturn s.closeChan\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/handlers.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\npackage spdystream\n\nimport (\n\t\"io\"\n\t\"net/http\"\n)\n\n// MirrorStreamHandler mirrors all streams.\nfunc MirrorStreamHandler(stream *Stream) {\n\treplyErr := stream.SendReply(http.Header{}, false)\n\tif replyErr != nil {\n\t\treturn\n\t}\n\n\tgo func() {\n\t\tio.Copy(stream, stream)\n\t\tstream.Close()\n\t}()\n\tgo func() {\n\t\tfor {\n\t\t\theader, receiveErr := stream.ReceiveHeader()\n\t\t\tif receiveErr != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsendErr := stream.SendHeader(header, false)\n\t\t\tif sendErr != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\n// NoopStreamHandler does nothing when stream connects.\nfunc NoOpStreamHandler(stream *Stream) {\n\tstream.SendReply(http.Header{}, false)\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/priority.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\npackage spdystream\n\nimport (\n\t\"container/heap\"\n\t\"sync\"\n\n\t\"github.com/moby/spdystream/spdy\"\n)\n\ntype prioritizedFrame struct {\n\tframe    spdy.Frame\n\tpriority uint8\n\tinsertId uint64\n}\n\ntype frameQueue []*prioritizedFrame\n\nfunc (fq frameQueue) Len() int {\n\treturn len(fq)\n}\n\nfunc (fq frameQueue) Less(i, j int) bool {\n\tif fq[i].priority == fq[j].priority {\n\t\treturn fq[i].insertId < fq[j].insertId\n\t}\n\treturn fq[i].priority < fq[j].priority\n}\n\nfunc (fq frameQueue) Swap(i, j int) {\n\tfq[i], fq[j] = fq[j], fq[i]\n}\n\nfunc (fq *frameQueue) Push(x interface{}) {\n\t*fq = append(*fq, x.(*prioritizedFrame))\n}\n\nfunc (fq *frameQueue) Pop() interface{} {\n\told := *fq\n\tn := len(old)\n\t*fq = old[0 : n-1]\n\treturn old[n-1]\n}\n\ntype PriorityFrameQueue struct {\n\tqueue        *frameQueue\n\tc            *sync.Cond\n\tsize         int\n\tnextInsertId uint64\n\tdrain        bool\n}\n\nfunc NewPriorityFrameQueue(size int) *PriorityFrameQueue {\n\tqueue := make(frameQueue, 0, size)\n\theap.Init(&queue)\n\n\treturn &PriorityFrameQueue{\n\t\tqueue: &queue,\n\t\tsize:  size,\n\t\tc:     sync.NewCond(&sync.Mutex{}),\n\t}\n}\n\nfunc (q *PriorityFrameQueue) Push(frame spdy.Frame, priority uint8) {\n\tq.c.L.Lock()\n\tdefer q.c.L.Unlock()\n\tfor q.queue.Len() >= q.size {\n\t\tq.c.Wait()\n\t}\n\tpFrame := &prioritizedFrame{\n\t\tframe:    frame,\n\t\tpriority: priority,\n\t\tinsertId: q.nextInsertId,\n\t}\n\tq.nextInsertId = q.nextInsertId + 1\n\theap.Push(q.queue, pFrame)\n\tq.c.Signal()\n}\n\nfunc (q *PriorityFrameQueue) Pop() spdy.Frame {\n\tq.c.L.Lock()\n\tdefer q.c.L.Unlock()\n\tfor q.queue.Len() == 0 {\n\t\tif q.drain {\n\t\t\treturn nil\n\t\t}\n\t\tq.c.Wait()\n\t}\n\tframe := heap.Pop(q.queue).(*prioritizedFrame).frame\n\tq.c.Signal()\n\treturn frame\n}\n\nfunc (q *PriorityFrameQueue) Drain() {\n\tq.c.L.Lock()\n\tdefer q.c.L.Unlock()\n\tq.drain = true\n\tq.c.Broadcast()\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/spdy/dictionary.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\n// Copyright 2013 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 spdy\n\n// headerDictionary is the dictionary sent to the zlib compressor/decompressor.\nvar headerDictionary = []byte{\n\t0x00, 0x00, 0x00, 0x07, 0x6f, 0x70, 0x74, 0x69,\n\t0x6f, 0x6e, 0x73, 0x00, 0x00, 0x00, 0x04, 0x68,\n\t0x65, 0x61, 0x64, 0x00, 0x00, 0x00, 0x04, 0x70,\n\t0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x03, 0x70,\n\t0x75, 0x74, 0x00, 0x00, 0x00, 0x06, 0x64, 0x65,\n\t0x6c, 0x65, 0x74, 0x65, 0x00, 0x00, 0x00, 0x05,\n\t0x74, 0x72, 0x61, 0x63, 0x65, 0x00, 0x00, 0x00,\n\t0x06, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x00,\n\t0x00, 0x00, 0x0e, 0x61, 0x63, 0x63, 0x65, 0x70,\n\t0x74, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,\n\t0x74, 0x00, 0x00, 0x00, 0x0f, 0x61, 0x63, 0x63,\n\t0x65, 0x70, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,\n\t0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x0f,\n\t0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x6c,\n\t0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x00,\n\t0x00, 0x00, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x70,\n\t0x74, 0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x73,\n\t0x00, 0x00, 0x00, 0x03, 0x61, 0x67, 0x65, 0x00,\n\t0x00, 0x00, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77,\n\t0x00, 0x00, 0x00, 0x0d, 0x61, 0x75, 0x74, 0x68,\n\t0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,\n\t0x6e, 0x00, 0x00, 0x00, 0x0d, 0x63, 0x61, 0x63,\n\t0x68, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72,\n\t0x6f, 0x6c, 0x00, 0x00, 0x00, 0x0a, 0x63, 0x6f,\n\t0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,\n\t0x00, 0x00, 0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74,\n\t0x65, 0x6e, 0x74, 0x2d, 0x62, 0x61, 0x73, 0x65,\n\t0x00, 0x00, 0x00, 0x10, 0x63, 0x6f, 0x6e, 0x74,\n\t0x65, 0x6e, 0x74, 0x2d, 0x65, 0x6e, 0x63, 0x6f,\n\t0x64, 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x10,\n\t0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d,\n\t0x6c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65,\n\t0x00, 0x00, 0x00, 0x0e, 0x63, 0x6f, 0x6e, 0x74,\n\t0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x65, 0x6e, 0x67,\n\t0x74, 0x68, 0x00, 0x00, 0x00, 0x10, 0x63, 0x6f,\n\t0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x6c, 0x6f,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00,\n\t0x00, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,\n\t0x74, 0x2d, 0x6d, 0x64, 0x35, 0x00, 0x00, 0x00,\n\t0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74,\n\t0x2d, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00,\n\t0x00, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e,\n\t0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00,\n\t0x00, 0x04, 0x64, 0x61, 0x74, 0x65, 0x00, 0x00,\n\t0x00, 0x04, 0x65, 0x74, 0x61, 0x67, 0x00, 0x00,\n\t0x00, 0x06, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74,\n\t0x00, 0x00, 0x00, 0x07, 0x65, 0x78, 0x70, 0x69,\n\t0x72, 0x65, 0x73, 0x00, 0x00, 0x00, 0x04, 0x66,\n\t0x72, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x04, 0x68,\n\t0x6f, 0x73, 0x74, 0x00, 0x00, 0x00, 0x08, 0x69,\n\t0x66, 0x2d, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x00,\n\t0x00, 0x00, 0x11, 0x69, 0x66, 0x2d, 0x6d, 0x6f,\n\t0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2d, 0x73,\n\t0x69, 0x6e, 0x63, 0x65, 0x00, 0x00, 0x00, 0x0d,\n\t0x69, 0x66, 0x2d, 0x6e, 0x6f, 0x6e, 0x65, 0x2d,\n\t0x6d, 0x61, 0x74, 0x63, 0x68, 0x00, 0x00, 0x00,\n\t0x08, 0x69, 0x66, 0x2d, 0x72, 0x61, 0x6e, 0x67,\n\t0x65, 0x00, 0x00, 0x00, 0x13, 0x69, 0x66, 0x2d,\n\t0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,\n\t0x65, 0x64, 0x2d, 0x73, 0x69, 0x6e, 0x63, 0x65,\n\t0x00, 0x00, 0x00, 0x0d, 0x6c, 0x61, 0x73, 0x74,\n\t0x2d, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,\n\t0x64, 0x00, 0x00, 0x00, 0x08, 0x6c, 0x6f, 0x63,\n\t0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,\n\t0x0c, 0x6d, 0x61, 0x78, 0x2d, 0x66, 0x6f, 0x72,\n\t0x77, 0x61, 0x72, 0x64, 0x73, 0x00, 0x00, 0x00,\n\t0x06, 0x70, 0x72, 0x61, 0x67, 0x6d, 0x61, 0x00,\n\t0x00, 0x00, 0x12, 0x70, 0x72, 0x6f, 0x78, 0x79,\n\t0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74,\n\t0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00,\n\t0x13, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x2d, 0x61,\n\t0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x05,\n\t0x72, 0x61, 0x6e, 0x67, 0x65, 0x00, 0x00, 0x00,\n\t0x07, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72,\n\t0x00, 0x00, 0x00, 0x0b, 0x72, 0x65, 0x74, 0x72,\n\t0x79, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x00,\n\t0x00, 0x00, 0x06, 0x73, 0x65, 0x72, 0x76, 0x65,\n\t0x72, 0x00, 0x00, 0x00, 0x02, 0x74, 0x65, 0x00,\n\t0x00, 0x00, 0x07, 0x74, 0x72, 0x61, 0x69, 0x6c,\n\t0x65, 0x72, 0x00, 0x00, 0x00, 0x11, 0x74, 0x72,\n\t0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x2d, 0x65,\n\t0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x00,\n\t0x00, 0x00, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61,\n\t0x64, 0x65, 0x00, 0x00, 0x00, 0x0a, 0x75, 0x73,\n\t0x65, 0x72, 0x2d, 0x61, 0x67, 0x65, 0x6e, 0x74,\n\t0x00, 0x00, 0x00, 0x04, 0x76, 0x61, 0x72, 0x79,\n\t0x00, 0x00, 0x00, 0x03, 0x76, 0x69, 0x61, 0x00,\n\t0x00, 0x00, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69,\n\t0x6e, 0x67, 0x00, 0x00, 0x00, 0x10, 0x77, 0x77,\n\t0x77, 0x2d, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e,\n\t0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x00, 0x00,\n\t0x00, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,\n\t0x00, 0x00, 0x00, 0x03, 0x67, 0x65, 0x74, 0x00,\n\t0x00, 0x00, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,\n\t0x73, 0x00, 0x00, 0x00, 0x06, 0x32, 0x30, 0x30,\n\t0x20, 0x4f, 0x4b, 0x00, 0x00, 0x00, 0x07, 0x76,\n\t0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x00, 0x00,\n\t0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31,\n\t0x2e, 0x31, 0x00, 0x00, 0x00, 0x03, 0x75, 0x72,\n\t0x6c, 0x00, 0x00, 0x00, 0x06, 0x70, 0x75, 0x62,\n\t0x6c, 0x69, 0x63, 0x00, 0x00, 0x00, 0x0a, 0x73,\n\t0x65, 0x74, 0x2d, 0x63, 0x6f, 0x6f, 0x6b, 0x69,\n\t0x65, 0x00, 0x00, 0x00, 0x0a, 0x6b, 0x65, 0x65,\n\t0x70, 0x2d, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x00,\n\t0x00, 0x00, 0x06, 0x6f, 0x72, 0x69, 0x67, 0x69,\n\t0x6e, 0x31, 0x30, 0x30, 0x31, 0x30, 0x31, 0x32,\n\t0x30, 0x31, 0x32, 0x30, 0x32, 0x32, 0x30, 0x35,\n\t0x32, 0x30, 0x36, 0x33, 0x30, 0x30, 0x33, 0x30,\n\t0x32, 0x33, 0x30, 0x33, 0x33, 0x30, 0x34, 0x33,\n\t0x30, 0x35, 0x33, 0x30, 0x36, 0x33, 0x30, 0x37,\n\t0x34, 0x30, 0x32, 0x34, 0x30, 0x35, 0x34, 0x30,\n\t0x36, 0x34, 0x30, 0x37, 0x34, 0x30, 0x38, 0x34,\n\t0x30, 0x39, 0x34, 0x31, 0x30, 0x34, 0x31, 0x31,\n\t0x34, 0x31, 0x32, 0x34, 0x31, 0x33, 0x34, 0x31,\n\t0x34, 0x34, 0x31, 0x35, 0x34, 0x31, 0x36, 0x34,\n\t0x31, 0x37, 0x35, 0x30, 0x32, 0x35, 0x30, 0x34,\n\t0x35, 0x30, 0x35, 0x32, 0x30, 0x33, 0x20, 0x4e,\n\t0x6f, 0x6e, 0x2d, 0x41, 0x75, 0x74, 0x68, 0x6f,\n\t0x72, 0x69, 0x74, 0x61, 0x74, 0x69, 0x76, 0x65,\n\t0x20, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61,\n\t0x74, 0x69, 0x6f, 0x6e, 0x32, 0x30, 0x34, 0x20,\n\t0x4e, 0x6f, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x65,\n\t0x6e, 0x74, 0x33, 0x30, 0x31, 0x20, 0x4d, 0x6f,\n\t0x76, 0x65, 0x64, 0x20, 0x50, 0x65, 0x72, 0x6d,\n\t0x61, 0x6e, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x34,\n\t0x30, 0x30, 0x20, 0x42, 0x61, 0x64, 0x20, 0x52,\n\t0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x34, 0x30,\n\t0x31, 0x20, 0x55, 0x6e, 0x61, 0x75, 0x74, 0x68,\n\t0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x34, 0x30,\n\t0x33, 0x20, 0x46, 0x6f, 0x72, 0x62, 0x69, 0x64,\n\t0x64, 0x65, 0x6e, 0x34, 0x30, 0x34, 0x20, 0x4e,\n\t0x6f, 0x74, 0x20, 0x46, 0x6f, 0x75, 0x6e, 0x64,\n\t0x35, 0x30, 0x30, 0x20, 0x49, 0x6e, 0x74, 0x65,\n\t0x72, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72,\n\t0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6f,\n\t0x72, 0x35, 0x30, 0x31, 0x20, 0x4e, 0x6f, 0x74,\n\t0x20, 0x49, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65,\n\t0x6e, 0x74, 0x65, 0x64, 0x35, 0x30, 0x33, 0x20,\n\t0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20,\n\t0x55, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61,\n\t0x62, 0x6c, 0x65, 0x4a, 0x61, 0x6e, 0x20, 0x46,\n\t0x65, 0x62, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x41,\n\t0x70, 0x72, 0x20, 0x4d, 0x61, 0x79, 0x20, 0x4a,\n\t0x75, 0x6e, 0x20, 0x4a, 0x75, 0x6c, 0x20, 0x41,\n\t0x75, 0x67, 0x20, 0x53, 0x65, 0x70, 0x74, 0x20,\n\t0x4f, 0x63, 0x74, 0x20, 0x4e, 0x6f, 0x76, 0x20,\n\t0x44, 0x65, 0x63, 0x20, 0x30, 0x30, 0x3a, 0x30,\n\t0x30, 0x3a, 0x30, 0x30, 0x20, 0x4d, 0x6f, 0x6e,\n\t0x2c, 0x20, 0x54, 0x75, 0x65, 0x2c, 0x20, 0x57,\n\t0x65, 0x64, 0x2c, 0x20, 0x54, 0x68, 0x75, 0x2c,\n\t0x20, 0x46, 0x72, 0x69, 0x2c, 0x20, 0x53, 0x61,\n\t0x74, 0x2c, 0x20, 0x53, 0x75, 0x6e, 0x2c, 0x20,\n\t0x47, 0x4d, 0x54, 0x63, 0x68, 0x75, 0x6e, 0x6b,\n\t0x65, 0x64, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f,\n\t0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x69, 0x6d, 0x61,\n\t0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0x2c, 0x69,\n\t0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x67,\n\t0x2c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67,\n\t0x69, 0x66, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,\n\t0x6d, 0x6c, 0x2c, 0x61, 0x70, 0x70, 0x6c, 0x69,\n\t0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x78,\n\t0x68, 0x74, 0x6d, 0x6c, 0x2b, 0x78, 0x6d, 0x6c,\n\t0x2c, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c,\n\t0x61, 0x69, 0x6e, 0x2c, 0x74, 0x65, 0x78, 0x74,\n\t0x2f, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72,\n\t0x69, 0x70, 0x74, 0x2c, 0x70, 0x75, 0x62, 0x6c,\n\t0x69, 0x63, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74,\n\t0x65, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65,\n\t0x3d, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x64, 0x65,\n\t0x66, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x64,\n\t0x63, 0x68, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65,\n\t0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x63,\n\t0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x69,\n\t0x73, 0x6f, 0x2d, 0x38, 0x38, 0x35, 0x39, 0x2d,\n\t0x31, 0x2c, 0x75, 0x74, 0x66, 0x2d, 0x2c, 0x2a,\n\t0x2c, 0x65, 0x6e, 0x71, 0x3d, 0x30, 0x2e,\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/spdy/read.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\n// 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 spdy\n\nimport (\n\t\"compress/zlib\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) error {\n\treturn f.readSynStreamFrame(h, frame)\n}\n\nfunc (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) error {\n\treturn f.readSynReplyFrame(h, frame)\n}\n\nfunc (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) error {\n\tframe.CFHeader = h\n\tif err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {\n\t\treturn err\n\t}\n\tif err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {\n\t\treturn err\n\t}\n\tif frame.Status == 0 {\n\t\treturn &Error{InvalidControlFrame, frame.StreamId}\n\t}\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\treturn nil\n}\n\nfunc (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error {\n\tframe.CFHeader = h\n\tvar numSettings uint32\n\tif err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil {\n\t\treturn err\n\t}\n\tframe.FlagIdValues = make([]SettingsFlagIdValue, numSettings)\n\tfor i := uint32(0); i < numSettings; i++ {\n\t\tif err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Id); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tframe.FlagIdValues[i].Flag = SettingsFlag((frame.FlagIdValues[i].Id & 0xff000000) >> 24)\n\t\tframe.FlagIdValues[i].Id &= 0xffffff\n\t\tif err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Value); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (frame *PingFrame) read(h ControlFrameHeader, f *Framer) error {\n\tframe.CFHeader = h\n\tif err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil {\n\t\treturn err\n\t}\n\tif frame.Id == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\tif frame.CFHeader.Flags != 0 {\n\t\treturn &Error{InvalidControlFrame, StreamId(frame.Id)}\n\t}\n\treturn nil\n}\n\nfunc (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) error {\n\tframe.CFHeader = h\n\tif err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); err != nil {\n\t\treturn err\n\t}\n\tif frame.CFHeader.Flags != 0 {\n\t\treturn &Error{InvalidControlFrame, frame.LastGoodStreamId}\n\t}\n\tif frame.CFHeader.length != 8 {\n\t\treturn &Error{InvalidControlFrame, frame.LastGoodStreamId}\n\t}\n\tif err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) error {\n\treturn f.readHeadersFrame(h, frame)\n}\n\nfunc (frame *WindowUpdateFrame) read(h ControlFrameHeader, f *Framer) error {\n\tframe.CFHeader = h\n\tif err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {\n\t\treturn err\n\t}\n\tif frame.CFHeader.Flags != 0 {\n\t\treturn &Error{InvalidControlFrame, frame.StreamId}\n\t}\n\tif frame.CFHeader.length != 8 {\n\t\treturn &Error{InvalidControlFrame, frame.StreamId}\n\t}\n\tif err := binary.Read(f.r, binary.BigEndian, &frame.DeltaWindowSize); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc newControlFrame(frameType ControlFrameType) (controlFrame, error) {\n\tctor, ok := cframeCtor[frameType]\n\tif !ok {\n\t\treturn nil, &Error{Err: InvalidControlFrame}\n\t}\n\treturn ctor(), nil\n}\n\nvar cframeCtor = map[ControlFrameType]func() controlFrame{\n\tTypeSynStream:    func() controlFrame { return new(SynStreamFrame) },\n\tTypeSynReply:     func() controlFrame { return new(SynReplyFrame) },\n\tTypeRstStream:    func() controlFrame { return new(RstStreamFrame) },\n\tTypeSettings:     func() controlFrame { return new(SettingsFrame) },\n\tTypePing:         func() controlFrame { return new(PingFrame) },\n\tTypeGoAway:       func() controlFrame { return new(GoAwayFrame) },\n\tTypeHeaders:      func() controlFrame { return new(HeadersFrame) },\n\tTypeWindowUpdate: func() controlFrame { return new(WindowUpdateFrame) },\n}\n\nfunc (f *Framer) uncorkHeaderDecompressor(payloadSize int64) error {\n\tif f.headerDecompressor != nil {\n\t\tf.headerReader.N = payloadSize\n\t\treturn nil\n\t}\n\tf.headerReader = io.LimitedReader{R: f.r, N: payloadSize}\n\tdecompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(headerDictionary))\n\tif err != nil {\n\t\treturn err\n\t}\n\tf.headerDecompressor = decompressor\n\treturn nil\n}\n\n// ReadFrame reads SPDY encoded data and returns a decompressed Frame.\nfunc (f *Framer) ReadFrame() (Frame, error) {\n\tvar firstWord uint32\n\tif err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil {\n\t\treturn nil, err\n\t}\n\tif firstWord&0x80000000 != 0 {\n\t\tframeType := ControlFrameType(firstWord & 0xffff)\n\t\tversion := uint16(firstWord >> 16 & 0x7fff)\n\t\treturn f.parseControlFrame(version, frameType)\n\t}\n\treturn f.parseDataFrame(StreamId(firstWord & 0x7fffffff))\n}\n\nfunc (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) (Frame, error) {\n\tvar length uint32\n\tif err := binary.Read(f.r, binary.BigEndian, &length); err != nil {\n\t\treturn nil, err\n\t}\n\tflags := ControlFlags((length & 0xff000000) >> 24)\n\tlength &= 0xffffff\n\theader := ControlFrameHeader{version, frameType, flags, length}\n\tcframe, err := newControlFrame(frameType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err = cframe.read(header, f); err != nil {\n\t\treturn nil, err\n\t}\n\treturn cframe, nil\n}\n\nfunc parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) {\n\tvar numHeaders uint32\n\tif err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil {\n\t\treturn nil, err\n\t}\n\tvar e error\n\th := make(http.Header, int(numHeaders))\n\tfor i := 0; i < int(numHeaders); i++ {\n\t\tvar length uint32\n\t\tif err := binary.Read(r, binary.BigEndian, &length); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnameBytes := make([]byte, length)\n\t\tif _, err := io.ReadFull(r, nameBytes); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tname := string(nameBytes)\n\t\tif name != strings.ToLower(name) {\n\t\t\te = &Error{UnlowercasedHeaderName, streamId}\n\t\t\tname = strings.ToLower(name)\n\t\t}\n\t\tif h[name] != nil {\n\t\t\te = &Error{DuplicateHeaders, streamId}\n\t\t}\n\t\tif err := binary.Read(r, binary.BigEndian, &length); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalue := make([]byte, length)\n\t\tif _, err := io.ReadFull(r, value); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvalueList := strings.Split(string(value), headerValueSeparator)\n\t\tfor _, v := range valueList {\n\t\t\th.Add(name, v)\n\t\t}\n\t}\n\tif e != nil {\n\t\treturn h, e\n\t}\n\treturn h, nil\n}\n\nfunc (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) error {\n\tframe.CFHeader = h\n\tvar err error\n\tif err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {\n\t\treturn err\n\t}\n\tif err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId); err != nil {\n\t\treturn err\n\t}\n\tif err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil {\n\t\treturn err\n\t}\n\tframe.Priority >>= 5\n\tif err = binary.Read(f.r, binary.BigEndian, &frame.Slot); err != nil {\n\t\treturn err\n\t}\n\treader := f.r\n\tif !f.headerCompressionDisabled {\n\t\terr := f.uncorkHeaderDecompressor(int64(h.length - 10))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treader = f.headerDecompressor\n\t}\n\tframe.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)\n\tif !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {\n\t\terr = &Error{WrongCompressedPayloadSize, 0}\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor h := range frame.Headers {\n\t\tif invalidReqHeaders[h] {\n\t\t\treturn &Error{InvalidHeaderPresent, frame.StreamId}\n\t\t}\n\t}\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\treturn nil\n}\n\nfunc (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) error {\n\tframe.CFHeader = h\n\tvar err error\n\tif err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {\n\t\treturn err\n\t}\n\treader := f.r\n\tif !f.headerCompressionDisabled {\n\t\terr := f.uncorkHeaderDecompressor(int64(h.length - 4))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treader = f.headerDecompressor\n\t}\n\tframe.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)\n\tif !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {\n\t\terr = &Error{WrongCompressedPayloadSize, 0}\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor h := range frame.Headers {\n\t\tif invalidRespHeaders[h] {\n\t\t\treturn &Error{InvalidHeaderPresent, frame.StreamId}\n\t\t}\n\t}\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\treturn nil\n}\n\nfunc (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) error {\n\tframe.CFHeader = h\n\tvar err error\n\tif err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {\n\t\treturn err\n\t}\n\treader := f.r\n\tif !f.headerCompressionDisabled {\n\t\terr := f.uncorkHeaderDecompressor(int64(h.length - 4))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treader = f.headerDecompressor\n\t}\n\tframe.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)\n\tif !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {\n\t\terr = &Error{WrongCompressedPayloadSize, 0}\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar invalidHeaders map[string]bool\n\tif frame.StreamId%2 == 0 {\n\t\tinvalidHeaders = invalidReqHeaders\n\t} else {\n\t\tinvalidHeaders = invalidRespHeaders\n\t}\n\tfor h := range frame.Headers {\n\t\tif invalidHeaders[h] {\n\t\t\treturn &Error{InvalidHeaderPresent, frame.StreamId}\n\t\t}\n\t}\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\treturn nil\n}\n\nfunc (f *Framer) parseDataFrame(streamId StreamId) (*DataFrame, error) {\n\tvar length uint32\n\tif err := binary.Read(f.r, binary.BigEndian, &length); err != nil {\n\t\treturn nil, err\n\t}\n\tvar frame DataFrame\n\tframe.StreamId = streamId\n\tframe.Flags = DataFlags(length >> 24)\n\tlength &= 0xffffff\n\tframe.Data = make([]byte, length)\n\tif _, err := io.ReadFull(f.r, frame.Data); err != nil {\n\t\treturn nil, err\n\t}\n\tif frame.StreamId == 0 {\n\t\treturn nil, &Error{ZeroStreamId, 0}\n\t}\n\treturn &frame, nil\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/spdy/types.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\n// 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\n// Package spdy implements the SPDY protocol (currently SPDY/3), described in\n// http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3.\npackage spdy\n\nimport (\n\t\"bytes\"\n\t\"compress/zlib\"\n\t\"io\"\n\t\"net/http\"\n)\n\n// Version is the protocol version number that this package implements.\nconst Version = 3\n\n// ControlFrameType stores the type field in a control frame header.\ntype ControlFrameType uint16\n\nconst (\n\tTypeSynStream    ControlFrameType = 0x0001\n\tTypeSynReply     ControlFrameType = 0x0002\n\tTypeRstStream    ControlFrameType = 0x0003\n\tTypeSettings     ControlFrameType = 0x0004\n\tTypePing         ControlFrameType = 0x0006\n\tTypeGoAway       ControlFrameType = 0x0007\n\tTypeHeaders      ControlFrameType = 0x0008\n\tTypeWindowUpdate ControlFrameType = 0x0009\n)\n\n// ControlFlags are the flags that can be set on a control frame.\ntype ControlFlags uint8\n\nconst (\n\tControlFlagFin                   ControlFlags = 0x01\n\tControlFlagUnidirectional        ControlFlags = 0x02\n\tControlFlagSettingsClearSettings ControlFlags = 0x01\n)\n\n// DataFlags are the flags that can be set on a data frame.\ntype DataFlags uint8\n\nconst (\n\tDataFlagFin DataFlags = 0x01\n)\n\n// MaxDataLength is the maximum number of bytes that can be stored in one frame.\nconst MaxDataLength = 1<<24 - 1\n\n// headerValueSepator separates multiple header values.\nconst headerValueSeparator = \"\\x00\"\n\n// Frame is a single SPDY frame in its unpacked in-memory representation. Use\n// Framer to read and write it.\ntype Frame interface {\n\twrite(f *Framer) error\n}\n\n// ControlFrameHeader contains all the fields in a control frame header,\n// in its unpacked in-memory representation.\ntype ControlFrameHeader struct {\n\t// Note, high bit is the \"Control\" bit.\n\tversion   uint16 // spdy version number\n\tframeType ControlFrameType\n\tFlags     ControlFlags\n\tlength    uint32 // length of data field\n}\n\ntype controlFrame interface {\n\tFrame\n\tread(h ControlFrameHeader, f *Framer) error\n}\n\n// StreamId represents a 31-bit value identifying the stream.\ntype StreamId uint32\n\n// SynStreamFrame is the unpacked, in-memory representation of a SYN_STREAM\n// frame.\ntype SynStreamFrame struct {\n\tCFHeader             ControlFrameHeader\n\tStreamId             StreamId\n\tAssociatedToStreamId StreamId // stream id for a stream which this stream is associated to\n\tPriority             uint8    // priority of this frame (3-bit)\n\tSlot                 uint8    // index in the server's credential vector of the client certificate\n\tHeaders              http.Header\n}\n\n// SynReplyFrame is the unpacked, in-memory representation of a SYN_REPLY frame.\ntype SynReplyFrame struct {\n\tCFHeader ControlFrameHeader\n\tStreamId StreamId\n\tHeaders  http.Header\n}\n\n// RstStreamStatus represents the status that led to a RST_STREAM.\ntype RstStreamStatus uint32\n\nconst (\n\tProtocolError RstStreamStatus = iota + 1\n\tInvalidStream\n\tRefusedStream\n\tUnsupportedVersion\n\tCancel\n\tInternalError\n\tFlowControlError\n\tStreamInUse\n\tStreamAlreadyClosed\n\tInvalidCredentials\n\tFrameTooLarge\n)\n\n// RstStreamFrame is the unpacked, in-memory representation of a RST_STREAM\n// frame.\ntype RstStreamFrame struct {\n\tCFHeader ControlFrameHeader\n\tStreamId StreamId\n\tStatus   RstStreamStatus\n}\n\n// SettingsFlag represents a flag in a SETTINGS frame.\ntype SettingsFlag uint8\n\nconst (\n\tFlagSettingsPersistValue SettingsFlag = 0x1\n\tFlagSettingsPersisted    SettingsFlag = 0x2\n)\n\n// SettingsFlag represents the id of an id/value pair in a SETTINGS frame.\ntype SettingsId uint32\n\nconst (\n\tSettingsUploadBandwidth SettingsId = iota + 1\n\tSettingsDownloadBandwidth\n\tSettingsRoundTripTime\n\tSettingsMaxConcurrentStreams\n\tSettingsCurrentCwnd\n\tSettingsDownloadRetransRate\n\tSettingsInitialWindowSize\n\tSettingsClientCretificateVectorSize\n)\n\n// SettingsFlagIdValue is the unpacked, in-memory representation of the\n// combined flag/id/value for a setting in a SETTINGS frame.\ntype SettingsFlagIdValue struct {\n\tFlag  SettingsFlag\n\tId    SettingsId\n\tValue uint32\n}\n\n// SettingsFrame is the unpacked, in-memory representation of a SPDY\n// SETTINGS frame.\ntype SettingsFrame struct {\n\tCFHeader     ControlFrameHeader\n\tFlagIdValues []SettingsFlagIdValue\n}\n\n// PingFrame is the unpacked, in-memory representation of a PING frame.\ntype PingFrame struct {\n\tCFHeader ControlFrameHeader\n\tId       uint32 // unique id for this ping, from server is even, from client is odd.\n}\n\n// GoAwayStatus represents the status in a GoAwayFrame.\ntype GoAwayStatus uint32\n\nconst (\n\tGoAwayOK GoAwayStatus = iota\n\tGoAwayProtocolError\n\tGoAwayInternalError\n)\n\n// GoAwayFrame is the unpacked, in-memory representation of a GOAWAY frame.\ntype GoAwayFrame struct {\n\tCFHeader         ControlFrameHeader\n\tLastGoodStreamId StreamId // last stream id which was accepted by sender\n\tStatus           GoAwayStatus\n}\n\n// HeadersFrame is the unpacked, in-memory representation of a HEADERS frame.\ntype HeadersFrame struct {\n\tCFHeader ControlFrameHeader\n\tStreamId StreamId\n\tHeaders  http.Header\n}\n\n// WindowUpdateFrame is the unpacked, in-memory representation of a\n// WINDOW_UPDATE frame.\ntype WindowUpdateFrame struct {\n\tCFHeader        ControlFrameHeader\n\tStreamId        StreamId\n\tDeltaWindowSize uint32 // additional number of bytes to existing window size\n}\n\n// TODO: Implement credential frame and related methods.\n\n// DataFrame is the unpacked, in-memory representation of a DATA frame.\ntype DataFrame struct {\n\t// Note, high bit is the \"Control\" bit. Should be 0 for data frames.\n\tStreamId StreamId\n\tFlags    DataFlags\n\tData     []byte // payload data of this frame\n}\n\n// A SPDY specific error.\ntype ErrorCode string\n\nconst (\n\tUnlowercasedHeaderName     ErrorCode = \"header was not lowercased\"\n\tDuplicateHeaders           ErrorCode = \"multiple headers with same name\"\n\tWrongCompressedPayloadSize ErrorCode = \"compressed payload size was incorrect\"\n\tUnknownFrameType           ErrorCode = \"unknown frame type\"\n\tInvalidControlFrame        ErrorCode = \"invalid control frame\"\n\tInvalidDataFrame           ErrorCode = \"invalid data frame\"\n\tInvalidHeaderPresent       ErrorCode = \"frame contained invalid header\"\n\tZeroStreamId               ErrorCode = \"stream id zero is disallowed\"\n)\n\n// Error contains both the type of error and additional values. StreamId is 0\n// if Error is not associated with a stream.\ntype Error struct {\n\tErr      ErrorCode\n\tStreamId StreamId\n}\n\nfunc (e *Error) Error() string {\n\treturn string(e.Err)\n}\n\nvar invalidReqHeaders = map[string]bool{\n\t\"Connection\":        true,\n\t\"Host\":              true,\n\t\"Keep-Alive\":        true,\n\t\"Proxy-Connection\":  true,\n\t\"Transfer-Encoding\": true,\n}\n\nvar invalidRespHeaders = map[string]bool{\n\t\"Connection\":        true,\n\t\"Keep-Alive\":        true,\n\t\"Proxy-Connection\":  true,\n\t\"Transfer-Encoding\": true,\n}\n\n// Framer handles serializing/deserializing SPDY frames, including compressing/\n// decompressing payloads.\ntype Framer struct {\n\theaderCompressionDisabled bool\n\tw                         io.Writer\n\theaderBuf                 *bytes.Buffer\n\theaderCompressor          *zlib.Writer\n\tr                         io.Reader\n\theaderReader              io.LimitedReader\n\theaderDecompressor        io.ReadCloser\n}\n\n// NewFramer allocates a new Framer for a given SPDY connection, represented by\n// a io.Writer and io.Reader. Note that Framer will read and write individual fields\n// from/to the Reader and Writer, so the caller should pass in an appropriately\n// buffered implementation to optimize performance.\nfunc NewFramer(w io.Writer, r io.Reader) (*Framer, error) {\n\tcompressBuf := new(bytes.Buffer)\n\tcompressor, err := zlib.NewWriterLevelDict(compressBuf, zlib.BestCompression, []byte(headerDictionary))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tframer := &Framer{\n\t\tw:                w,\n\t\theaderBuf:        compressBuf,\n\t\theaderCompressor: compressor,\n\t\tr:                r,\n\t}\n\treturn framer, nil\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/spdy/write.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\n// 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 spdy\n\nimport (\n\t\"encoding/binary\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n)\n\nfunc (frame *SynStreamFrame) write(f *Framer) error {\n\treturn f.writeSynStreamFrame(frame)\n}\n\nfunc (frame *SynReplyFrame) write(f *Framer) error {\n\treturn f.writeSynReplyFrame(frame)\n}\n\nfunc (frame *RstStreamFrame) write(f *Framer) (err error) {\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypeRstStream\n\tframe.CFHeader.Flags = 0\n\tframe.CFHeader.length = 8\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {\n\t\treturn\n\t}\n\tif frame.Status == 0 {\n\t\treturn &Error{InvalidControlFrame, frame.StreamId}\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil {\n\t\treturn\n\t}\n\treturn\n}\n\nfunc (frame *SettingsFrame) write(f *Framer) (err error) {\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypeSettings\n\tframe.CFHeader.length = uint32(len(frame.FlagIdValues)*8 + 4)\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, uint32(len(frame.FlagIdValues))); err != nil {\n\t\treturn\n\t}\n\tfor _, flagIdValue := range frame.FlagIdValues {\n\t\tflagId := uint32(flagIdValue.Flag)<<24 | uint32(flagIdValue.Id)\n\t\tif err = binary.Write(f.w, binary.BigEndian, flagId); err != nil {\n\t\t\treturn\n\t\t}\n\t\tif err = binary.Write(f.w, binary.BigEndian, flagIdValue.Value); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\nfunc (frame *PingFrame) write(f *Framer) (err error) {\n\tif frame.Id == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypePing\n\tframe.CFHeader.Flags = 0\n\tframe.CFHeader.length = 4\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.Id); err != nil {\n\t\treturn\n\t}\n\treturn\n}\n\nfunc (frame *GoAwayFrame) write(f *Framer) (err error) {\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypeGoAway\n\tframe.CFHeader.Flags = 0\n\tframe.CFHeader.length = 8\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.LastGoodStreamId); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.Status); err != nil {\n\t\treturn\n\t}\n\treturn nil\n}\n\nfunc (frame *HeadersFrame) write(f *Framer) error {\n\treturn f.writeHeadersFrame(frame)\n}\n\nfunc (frame *WindowUpdateFrame) write(f *Framer) (err error) {\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypeWindowUpdate\n\tframe.CFHeader.Flags = 0\n\tframe.CFHeader.length = 8\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.DeltaWindowSize); err != nil {\n\t\treturn\n\t}\n\treturn nil\n}\n\nfunc (frame *DataFrame) write(f *Framer) error {\n\treturn f.writeDataFrame(frame)\n}\n\n// WriteFrame writes a frame.\nfunc (f *Framer) WriteFrame(frame Frame) error {\n\treturn frame.write(f)\n}\n\nfunc writeControlFrameHeader(w io.Writer, h ControlFrameHeader) error {\n\tif err := binary.Write(w, binary.BigEndian, 0x8000|h.version); err != nil {\n\t\treturn err\n\t}\n\tif err := binary.Write(w, binary.BigEndian, h.frameType); err != nil {\n\t\treturn err\n\t}\n\tflagsAndLength := uint32(h.Flags)<<24 | h.length\n\tif err := binary.Write(w, binary.BigEndian, flagsAndLength); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc writeHeaderValueBlock(w io.Writer, h http.Header) (n int, err error) {\n\tn = 0\n\tif err = binary.Write(w, binary.BigEndian, uint32(len(h))); err != nil {\n\t\treturn\n\t}\n\tn += 2\n\tfor name, values := range h {\n\t\tif err = binary.Write(w, binary.BigEndian, uint32(len(name))); err != nil {\n\t\t\treturn\n\t\t}\n\t\tn += 2\n\t\tname = strings.ToLower(name)\n\t\tif _, err = io.WriteString(w, name); err != nil {\n\t\t\treturn\n\t\t}\n\t\tn += len(name)\n\t\tv := strings.Join(values, headerValueSeparator)\n\t\tif err = binary.Write(w, binary.BigEndian, uint32(len(v))); err != nil {\n\t\t\treturn\n\t\t}\n\t\tn += 2\n\t\tif _, err = io.WriteString(w, v); err != nil {\n\t\t\treturn\n\t\t}\n\t\tn += len(v)\n\t}\n\treturn\n}\n\nfunc (f *Framer) writeSynStreamFrame(frame *SynStreamFrame) (err error) {\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\t// Marshal the headers.\n\tvar writer io.Writer = f.headerBuf\n\tif !f.headerCompressionDisabled {\n\t\twriter = f.headerCompressor\n\t}\n\tif _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {\n\t\treturn\n\t}\n\tif !f.headerCompressionDisabled {\n\t\tf.headerCompressor.Flush()\n\t}\n\n\t// Set ControlFrameHeader.\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypeSynStream\n\tframe.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 10)\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn err\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {\n\t\treturn err\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.AssociatedToStreamId); err != nil {\n\t\treturn err\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.Priority<<5); err != nil {\n\t\treturn err\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.Slot); err != nil {\n\t\treturn err\n\t}\n\tif _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {\n\t\treturn err\n\t}\n\tf.headerBuf.Reset()\n\treturn nil\n}\n\nfunc (f *Framer) writeSynReplyFrame(frame *SynReplyFrame) (err error) {\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\t// Marshal the headers.\n\tvar writer io.Writer = f.headerBuf\n\tif !f.headerCompressionDisabled {\n\t\twriter = f.headerCompressor\n\t}\n\tif _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {\n\t\treturn\n\t}\n\tif !f.headerCompressionDisabled {\n\t\tf.headerCompressor.Flush()\n\t}\n\n\t// Set ControlFrameHeader.\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypeSynReply\n\tframe.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4)\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {\n\t\treturn\n\t}\n\tif _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {\n\t\treturn\n\t}\n\tf.headerBuf.Reset()\n\treturn\n}\n\nfunc (f *Framer) writeHeadersFrame(frame *HeadersFrame) (err error) {\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\t// Marshal the headers.\n\tvar writer io.Writer = f.headerBuf\n\tif !f.headerCompressionDisabled {\n\t\twriter = f.headerCompressor\n\t}\n\tif _, err = writeHeaderValueBlock(writer, frame.Headers); err != nil {\n\t\treturn\n\t}\n\tif !f.headerCompressionDisabled {\n\t\tf.headerCompressor.Flush()\n\t}\n\n\t// Set ControlFrameHeader.\n\tframe.CFHeader.version = Version\n\tframe.CFHeader.frameType = TypeHeaders\n\tframe.CFHeader.length = uint32(len(f.headerBuf.Bytes()) + 4)\n\n\t// Serialize frame to Writer.\n\tif err = writeControlFrameHeader(f.w, frame.CFHeader); err != nil {\n\t\treturn\n\t}\n\tif err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {\n\t\treturn\n\t}\n\tif _, err = f.w.Write(f.headerBuf.Bytes()); err != nil {\n\t\treturn\n\t}\n\tf.headerBuf.Reset()\n\treturn\n}\n\nfunc (f *Framer) writeDataFrame(frame *DataFrame) (err error) {\n\tif frame.StreamId == 0 {\n\t\treturn &Error{ZeroStreamId, 0}\n\t}\n\tif frame.StreamId&0x80000000 != 0 || len(frame.Data) > MaxDataLength {\n\t\treturn &Error{InvalidDataFrame, frame.StreamId}\n\t}\n\n\t// Serialize frame to Writer.\n\tif err = binary.Write(f.w, binary.BigEndian, frame.StreamId); err != nil {\n\t\treturn\n\t}\n\tflagsAndLength := uint32(frame.Flags)<<24 | uint32(len(frame.Data))\n\tif err = binary.Write(f.w, binary.BigEndian, flagsAndLength); err != nil {\n\t\treturn\n\t}\n\tif _, err = f.w.Write(frame.Data); err != nil {\n\t\treturn\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/stream.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\npackage spdystream\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/moby/spdystream/spdy\"\n)\n\nvar (\n\tErrUnreadPartialData = errors.New(\"unread partial data\")\n)\n\ntype Stream struct {\n\tstreamId  spdy.StreamId\n\tparent    *Stream\n\tconn      *Connection\n\tstartChan chan error\n\n\tdataLock sync.RWMutex\n\tdataChan chan []byte\n\tunread   []byte\n\n\tpriority   uint8\n\theaders    http.Header\n\theaderChan chan http.Header\n\tfinishLock sync.Mutex\n\tfinished   bool\n\treplyCond  *sync.Cond\n\treplied    bool\n\tcloseLock  sync.Mutex\n\tcloseChan  chan bool\n}\n\n// WriteData writes data to stream, sending a dataframe per call\nfunc (s *Stream) WriteData(data []byte, fin bool) error {\n\ts.waitWriteReply()\n\tvar flags spdy.DataFlags\n\n\tif fin {\n\t\tflags = spdy.DataFlagFin\n\t\ts.finishLock.Lock()\n\t\tif s.finished {\n\t\t\ts.finishLock.Unlock()\n\t\t\treturn ErrWriteClosedStream\n\t\t}\n\t\ts.finished = true\n\t\ts.finishLock.Unlock()\n\t}\n\n\tdataFrame := &spdy.DataFrame{\n\t\tStreamId: s.streamId,\n\t\tFlags:    flags,\n\t\tData:     data,\n\t}\n\n\tdebugMessage(\"(%p) (%d) Writing data frame\", s, s.streamId)\n\treturn s.conn.framer.WriteFrame(dataFrame)\n}\n\n// Write writes bytes to a stream, calling write data for each call.\nfunc (s *Stream) Write(data []byte) (n int, err error) {\n\terr = s.WriteData(data, false)\n\tif err == nil {\n\t\tn = len(data)\n\t}\n\treturn\n}\n\n// Read reads bytes from a stream, a single read will never get more\n// than what is sent on a single data frame, but a multiple calls to\n// read may get data from the same data frame.\nfunc (s *Stream) Read(p []byte) (n int, err error) {\n\tif s.unread == nil {\n\t\tselect {\n\t\tcase <-s.closeChan:\n\t\t\treturn 0, io.EOF\n\t\tcase read, ok := <-s.dataChan:\n\t\t\tif !ok {\n\t\t\t\treturn 0, io.EOF\n\t\t\t}\n\t\t\ts.unread = read\n\t\t}\n\t}\n\tn = copy(p, s.unread)\n\tif n < len(s.unread) {\n\t\ts.unread = s.unread[n:]\n\t} else {\n\t\ts.unread = nil\n\t}\n\treturn\n}\n\n// ReadData reads an entire data frame and returns the byte array\n// from the data frame.  If there is unread data from the result\n// of a Read call, this function will return an ErrUnreadPartialData.\nfunc (s *Stream) ReadData() ([]byte, error) {\n\tdebugMessage(\"(%p) Reading data from %d\", s, s.streamId)\n\tif s.unread != nil {\n\t\treturn nil, ErrUnreadPartialData\n\t}\n\tselect {\n\tcase <-s.closeChan:\n\t\treturn nil, io.EOF\n\tcase read, ok := <-s.dataChan:\n\t\tif !ok {\n\t\t\treturn nil, io.EOF\n\t\t}\n\t\treturn read, nil\n\t}\n}\n\nfunc (s *Stream) waitWriteReply() {\n\tif s.replyCond != nil {\n\t\ts.replyCond.L.Lock()\n\t\tfor !s.replied {\n\t\t\ts.replyCond.Wait()\n\t\t}\n\t\ts.replyCond.L.Unlock()\n\t}\n}\n\n// Wait waits for the stream to receive a reply.\nfunc (s *Stream) Wait() error {\n\treturn s.WaitTimeout(time.Duration(0))\n}\n\n// WaitTimeout waits for the stream to receive a reply or for timeout.\n// When the timeout is reached, ErrTimeout will be returned.\nfunc (s *Stream) WaitTimeout(timeout time.Duration) error {\n\tvar timeoutChan <-chan time.Time\n\tif timeout > time.Duration(0) {\n\t\ttimeoutChan = time.After(timeout)\n\t}\n\n\tselect {\n\tcase err := <-s.startChan:\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tbreak\n\tcase <-timeoutChan:\n\t\treturn ErrTimeout\n\t}\n\treturn nil\n}\n\n// Close closes the stream by sending an empty data frame with the\n// finish flag set, indicating this side is finished with the stream.\nfunc (s *Stream) Close() error {\n\tselect {\n\tcase <-s.closeChan:\n\t\t// Stream is now fully closed\n\t\ts.conn.removeStream(s)\n\tdefault:\n\t\tbreak\n\t}\n\treturn s.WriteData([]byte{}, true)\n}\n\n// Reset sends a reset frame, putting the stream into the fully closed state.\nfunc (s *Stream) Reset() error {\n\ts.conn.removeStream(s)\n\treturn s.resetStream()\n}\n\nfunc (s *Stream) resetStream() error {\n\t// Always call closeRemoteChannels, even if s.finished is already true.\n\t// This makes it so that stream.Close() followed by stream.Reset() allows\n\t// stream.Read() to unblock.\n\ts.closeRemoteChannels()\n\n\ts.finishLock.Lock()\n\tif s.finished {\n\t\ts.finishLock.Unlock()\n\t\treturn nil\n\t}\n\ts.finished = true\n\ts.finishLock.Unlock()\n\n\tresetFrame := &spdy.RstStreamFrame{\n\t\tStreamId: s.streamId,\n\t\tStatus:   spdy.Cancel,\n\t}\n\treturn s.conn.framer.WriteFrame(resetFrame)\n}\n\n// CreateSubStream creates a stream using the current as the parent\nfunc (s *Stream) CreateSubStream(headers http.Header, fin bool) (*Stream, error) {\n\treturn s.conn.CreateStream(headers, s, fin)\n}\n\n// SetPriority sets the stream priority, does not affect the\n// remote priority of this stream after Open has been called.\n// Valid values are 0 through 7, 0 being the highest priority\n// and 7 the lowest.\nfunc (s *Stream) SetPriority(priority uint8) {\n\ts.priority = priority\n}\n\n// SendHeader sends a header frame across the stream\nfunc (s *Stream) SendHeader(headers http.Header, fin bool) error {\n\treturn s.conn.sendHeaders(headers, s, fin)\n}\n\n// SendReply sends a reply on a stream, only valid to be called once\n// when handling a new stream\nfunc (s *Stream) SendReply(headers http.Header, fin bool) error {\n\tif s.replyCond == nil {\n\t\treturn errors.New(\"cannot reply on initiated stream\")\n\t}\n\ts.replyCond.L.Lock()\n\tdefer s.replyCond.L.Unlock()\n\tif s.replied {\n\t\treturn nil\n\t}\n\n\terr := s.conn.sendReply(headers, s, fin)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ts.replied = true\n\ts.replyCond.Broadcast()\n\treturn nil\n}\n\n// Refuse sends a reset frame with the status refuse, only\n// valid to be called once when handling a new stream.  This\n// may be used to indicate that a stream is not allowed\n// when http status codes are not being used.\nfunc (s *Stream) Refuse() error {\n\tif s.replied {\n\t\treturn nil\n\t}\n\ts.replied = true\n\treturn s.conn.sendReset(spdy.RefusedStream, s)\n}\n\n// Cancel sends a reset frame with the status canceled. This\n// can be used at any time by the creator of the Stream to\n// indicate the stream is no longer needed.\nfunc (s *Stream) Cancel() error {\n\treturn s.conn.sendReset(spdy.Cancel, s)\n}\n\n// ReceiveHeader receives a header sent on the other side\n// of the stream.  This function will block until a header\n// is received or stream is closed.\nfunc (s *Stream) ReceiveHeader() (http.Header, error) {\n\tselect {\n\tcase <-s.closeChan:\n\t\tbreak\n\tcase header, ok := <-s.headerChan:\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"header chan closed\")\n\t\t}\n\t\treturn header, nil\n\t}\n\treturn nil, fmt.Errorf(\"stream closed\")\n}\n\n// Parent returns the parent stream\nfunc (s *Stream) Parent() *Stream {\n\treturn s.parent\n}\n\n// Headers returns the headers used to create the stream\nfunc (s *Stream) Headers() http.Header {\n\treturn s.headers\n}\n\n// String returns the string version of stream using the\n// streamId to uniquely identify the stream\nfunc (s *Stream) String() string {\n\treturn fmt.Sprintf(\"stream:%d\", s.streamId)\n}\n\n// Identifier returns a 32 bit identifier for the stream\nfunc (s *Stream) Identifier() uint32 {\n\treturn uint32(s.streamId)\n}\n\n// IsFinished returns whether the stream has finished\n// sending data\nfunc (s *Stream) IsFinished() bool {\n\treturn s.finished\n}\n\n// Implement net.Conn interface\n\nfunc (s *Stream) LocalAddr() net.Addr {\n\treturn s.conn.conn.LocalAddr()\n}\n\nfunc (s *Stream) RemoteAddr() net.Addr {\n\treturn s.conn.conn.RemoteAddr()\n}\n\n// TODO set per stream values instead of connection-wide\n\nfunc (s *Stream) SetDeadline(t time.Time) error {\n\treturn s.conn.conn.SetDeadline(t)\n}\n\nfunc (s *Stream) SetReadDeadline(t time.Time) error {\n\treturn s.conn.conn.SetReadDeadline(t)\n}\n\nfunc (s *Stream) SetWriteDeadline(t time.Time) error {\n\treturn s.conn.conn.SetWriteDeadline(t)\n}\n\nfunc (s *Stream) closeRemoteChannels() {\n\ts.closeLock.Lock()\n\tdefer s.closeLock.Unlock()\n\tselect {\n\tcase <-s.closeChan:\n\tdefault:\n\t\tclose(s.closeChan)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/moby/spdystream/utils.go",
    "content": "/*\n   Copyright 2014-2021 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       http://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*/\n\npackage spdystream\n\nimport (\n\t\"log\"\n\t\"os\"\n)\n\nvar (\n\tDEBUG = os.Getenv(\"DEBUG\")\n)\n\nfunc debugMessage(fmt string, args ...interface{}) {\n\tif DEBUG != \"\" {\n\t\tlog.Printf(fmt, args...)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/moby/sys/sequential/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/moby/sys/sequential/doc.go",
    "content": "// Package sequential provides a set of functions for managing sequential\n// files on Windows.\n//\n// The origin of these functions are the golang OS and windows packages,\n// slightly modified to only cope with files, not directories due to the\n// specific use case.\n//\n// The alteration is to allow a file on Windows to be opened with\n// FILE_FLAG_SEQUENTIAL_SCAN (particular for docker load), to avoid eating\n// the standby list, particularly when accessing large files such as layer.tar.\n//\n// For non-Windows platforms, the package provides wrappers for the equivalents\n// in the os packages. They are passthrough on Unix platforms, and only relevant\n// on Windows.\npackage sequential\n"
  },
  {
    "path": "vendor/github.com/moby/sys/sequential/sequential_unix.go",
    "content": "//go:build !windows\n// +build !windows\n\npackage sequential\n\nimport \"os\"\n\n// Create creates the named file with mode 0666 (before umask), truncating\n// it if it already exists. If successful, methods on the returned\n// File can be used for I/O; the associated file descriptor has mode\n// O_RDWR.\n// If there is an error, it will be of type *PathError.\nfunc Create(name string) (*os.File, error) {\n\treturn os.Create(name)\n}\n\n// Open opens the named file for reading. If successful, methods on\n// the returned file can be used for reading; the associated file\n// descriptor has mode O_RDONLY.\n// If there is an error, it will be of type *PathError.\nfunc Open(name string) (*os.File, error) {\n\treturn os.Open(name)\n}\n\n// OpenFile is the generalized open call; most users will use Open\n// or Create instead. It opens the named file with specified flag\n// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,\n// methods on the returned File can be used for I/O.\n// If there is an error, it will be of type *PathError.\nfunc OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {\n\treturn os.OpenFile(name, flag, perm)\n}\n\n// CreateTemp creates a new temporary file in the directory dir\n// with a name beginning with prefix, opens the file for reading\n// and writing, and returns the resulting *os.File.\n// If dir is the empty string, TempFile uses the default directory\n// for temporary files (see os.TempDir).\n// Multiple programs calling TempFile simultaneously\n// will not choose the same file. The caller can use f.Name()\n// to find the pathname of the file. It is the caller's responsibility\n// to remove the file when no longer needed.\nfunc CreateTemp(dir, prefix string) (f *os.File, err error) {\n\treturn os.CreateTemp(dir, prefix)\n}\n"
  },
  {
    "path": "vendor/github.com/moby/sys/sequential/sequential_windows.go",
    "content": "package sequential\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"sync\"\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"golang.org/x/sys/windows\"\n)\n\n// Create creates the named file with mode 0666 (before umask), truncating\n// it if it already exists. If successful, methods on the returned\n// File can be used for I/O; the associated file descriptor has mode\n// O_RDWR.\n// If there is an error, it will be of type *PathError.\nfunc Create(name string) (*os.File, error) {\n\treturn OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0)\n}\n\n// Open opens the named file for reading. If successful, methods on\n// the returned file can be used for reading; the associated file\n// descriptor has mode O_RDONLY.\n// If there is an error, it will be of type *PathError.\nfunc Open(name string) (*os.File, error) {\n\treturn OpenFile(name, os.O_RDONLY, 0)\n}\n\n// OpenFile is the generalized open call; most users will use Open\n// or Create instead.\n// If there is an error, it will be of type *PathError.\nfunc OpenFile(name string, flag int, _ os.FileMode) (*os.File, error) {\n\tif name == \"\" {\n\t\treturn nil, &os.PathError{Op: \"open\", Path: name, Err: syscall.ENOENT}\n\t}\n\tr, err := openFileSequential(name, flag, 0)\n\tif err == nil {\n\t\treturn r, nil\n\t}\n\treturn nil, &os.PathError{Op: \"open\", Path: name, Err: err}\n}\n\nfunc openFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {\n\tr, e := openSequential(name, flag|windows.O_CLOEXEC, 0)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\treturn os.NewFile(uintptr(r), name), nil\n}\n\nfunc makeInheritSa() *windows.SecurityAttributes {\n\tvar sa windows.SecurityAttributes\n\tsa.Length = uint32(unsafe.Sizeof(sa))\n\tsa.InheritHandle = 1\n\treturn &sa\n}\n\nfunc openSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) {\n\tif len(path) == 0 {\n\t\treturn windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND\n\t}\n\tpathp, err := windows.UTF16PtrFromString(path)\n\tif err != nil {\n\t\treturn windows.InvalidHandle, err\n\t}\n\tvar access uint32\n\tswitch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) {\n\tcase windows.O_RDONLY:\n\t\taccess = windows.GENERIC_READ\n\tcase windows.O_WRONLY:\n\t\taccess = windows.GENERIC_WRITE\n\tcase windows.O_RDWR:\n\t\taccess = windows.GENERIC_READ | windows.GENERIC_WRITE\n\t}\n\tif mode&windows.O_CREAT != 0 {\n\t\taccess |= windows.GENERIC_WRITE\n\t}\n\tif mode&windows.O_APPEND != 0 {\n\t\taccess &^= windows.GENERIC_WRITE\n\t\taccess |= windows.FILE_APPEND_DATA\n\t}\n\tsharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE)\n\tvar sa *windows.SecurityAttributes\n\tif mode&windows.O_CLOEXEC == 0 {\n\t\tsa = makeInheritSa()\n\t}\n\tvar createmode uint32\n\tswitch {\n\tcase mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL):\n\t\tcreatemode = windows.CREATE_NEW\n\tcase mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC):\n\t\tcreatemode = windows.CREATE_ALWAYS\n\tcase mode&windows.O_CREAT == windows.O_CREAT:\n\t\tcreatemode = windows.OPEN_ALWAYS\n\tcase mode&windows.O_TRUNC == windows.O_TRUNC:\n\t\tcreatemode = windows.TRUNCATE_EXISTING\n\tdefault:\n\t\tcreatemode = windows.OPEN_EXISTING\n\t}\n\t// Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang.\n\t// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx\n\tconst fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN\n\th, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)\n\treturn h, e\n}\n\n// Helpers for CreateTemp\nvar rand uint32\nvar randmu sync.Mutex\n\nfunc reseed() uint32 {\n\treturn uint32(time.Now().UnixNano() + int64(os.Getpid()))\n}\n\nfunc nextSuffix() string {\n\trandmu.Lock()\n\tr := rand\n\tif r == 0 {\n\t\tr = reseed()\n\t}\n\tr = r*1664525 + 1013904223 // constants from Numerical Recipes\n\trand = r\n\trandmu.Unlock()\n\treturn strconv.Itoa(int(1e9 + r%1e9))[1:]\n}\n\n// CreateTemp is a copy of os.CreateTemp, modified to use sequential\n// file access. Below is the original comment from golang:\n// TempFile creates a new temporary file in the directory dir\n// with a name beginning with prefix, opens the file for reading\n// and writing, and returns the resulting *os.File.\n// If dir is the empty string, TempFile uses the default directory\n// for temporary files (see os.TempDir).\n// Multiple programs calling TempFile simultaneously\n// will not choose the same file. The caller can use f.Name()\n// to find the pathname of the file. It is the caller's responsibility\n// to remove the file when no longer needed.\nfunc CreateTemp(dir, prefix string) (f *os.File, err error) {\n\tif dir == \"\" {\n\t\tdir = os.TempDir()\n\t}\n\n\tnconflict := 0\n\tfor i := 0; i < 10000; i++ {\n\t\tname := filepath.Join(dir, prefix+nextSuffix())\n\t\tf, err = OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)\n\t\tif os.IsExist(err) {\n\t\t\tif nconflict++; nconflict > 10 {\n\t\t\t\trandmu.Lock()\n\t\t\t\trand = reseed()\n\t\t\t\trandmu.Unlock()\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tbreak\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/moby/sys/user/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/moby/sys/user/lookup_unix.go",
    "content": "//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris\n// +build darwin dragonfly freebsd linux netbsd openbsd solaris\n\npackage user\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\n// Unix-specific path to the passwd and group formatted files.\nconst (\n\tunixPasswdPath = \"/etc/passwd\"\n\tunixGroupPath  = \"/etc/group\"\n)\n\n// LookupUser looks up a user by their username in /etc/passwd. If the user\n// cannot be found (or there is no /etc/passwd file on the filesystem), then\n// LookupUser returns an error.\nfunc LookupUser(username string) (User, error) {\n\treturn lookupUserFunc(func(u User) bool {\n\t\treturn u.Name == username\n\t})\n}\n\n// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot\n// be found (or there is no /etc/passwd file on the filesystem), then LookupId\n// returns an error.\nfunc LookupUid(uid int) (User, error) {\n\treturn lookupUserFunc(func(u User) bool {\n\t\treturn u.Uid == uid\n\t})\n}\n\nfunc lookupUserFunc(filter func(u User) bool) (User, error) {\n\t// Get operating system-specific passwd reader-closer.\n\tpasswd, err := GetPasswd()\n\tif err != nil {\n\t\treturn User{}, err\n\t}\n\tdefer passwd.Close()\n\n\t// Get the users.\n\tusers, err := ParsePasswdFilter(passwd, filter)\n\tif err != nil {\n\t\treturn User{}, err\n\t}\n\n\t// No user entries found.\n\tif len(users) == 0 {\n\t\treturn User{}, ErrNoPasswdEntries\n\t}\n\n\t// Assume the first entry is the \"correct\" one.\n\treturn users[0], nil\n}\n\n// LookupGroup looks up a group by its name in /etc/group. If the group cannot\n// be found (or there is no /etc/group file on the filesystem), then LookupGroup\n// returns an error.\nfunc LookupGroup(groupname string) (Group, error) {\n\treturn lookupGroupFunc(func(g Group) bool {\n\t\treturn g.Name == groupname\n\t})\n}\n\n// LookupGid looks up a group by its group id in /etc/group. If the group cannot\n// be found (or there is no /etc/group file on the filesystem), then LookupGid\n// returns an error.\nfunc LookupGid(gid int) (Group, error) {\n\treturn lookupGroupFunc(func(g Group) bool {\n\t\treturn g.Gid == gid\n\t})\n}\n\nfunc lookupGroupFunc(filter func(g Group) bool) (Group, error) {\n\t// Get operating system-specific group reader-closer.\n\tgroup, err := GetGroup()\n\tif err != nil {\n\t\treturn Group{}, err\n\t}\n\tdefer group.Close()\n\n\t// Get the users.\n\tgroups, err := ParseGroupFilter(group, filter)\n\tif err != nil {\n\t\treturn Group{}, err\n\t}\n\n\t// No user entries found.\n\tif len(groups) == 0 {\n\t\treturn Group{}, ErrNoGroupEntries\n\t}\n\n\t// Assume the first entry is the \"correct\" one.\n\treturn groups[0], nil\n}\n\nfunc GetPasswdPath() (string, error) {\n\treturn unixPasswdPath, nil\n}\n\nfunc GetPasswd() (io.ReadCloser, error) {\n\treturn os.Open(unixPasswdPath)\n}\n\nfunc GetGroupPath() (string, error) {\n\treturn unixGroupPath, nil\n}\n\nfunc GetGroup() (io.ReadCloser, error) {\n\treturn os.Open(unixGroupPath)\n}\n\n// CurrentUser looks up the current user by their user id in /etc/passwd. If the\n// user cannot be found (or there is no /etc/passwd file on the filesystem),\n// then CurrentUser returns an error.\nfunc CurrentUser() (User, error) {\n\treturn LookupUid(unix.Getuid())\n}\n\n// CurrentGroup looks up the current user's group by their primary group id's\n// entry in /etc/passwd. If the group cannot be found (or there is no\n// /etc/group file on the filesystem), then CurrentGroup returns an error.\nfunc CurrentGroup() (Group, error) {\n\treturn LookupGid(unix.Getgid())\n}\n\nfunc currentUserSubIDs(fileName string) ([]SubID, error) {\n\tu, err := CurrentUser()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfilter := func(entry SubID) bool {\n\t\treturn entry.Name == u.Name || entry.Name == strconv.Itoa(u.Uid)\n\t}\n\treturn ParseSubIDFileFilter(fileName, filter)\n}\n\nfunc CurrentUserSubUIDs() ([]SubID, error) {\n\treturn currentUserSubIDs(\"/etc/subuid\")\n}\n\nfunc CurrentUserSubGIDs() ([]SubID, error) {\n\treturn currentUserSubIDs(\"/etc/subgid\")\n}\n\nfunc CurrentProcessUIDMap() ([]IDMap, error) {\n\treturn ParseIDMapFile(\"/proc/self/uid_map\")\n}\n\nfunc CurrentProcessGIDMap() ([]IDMap, error) {\n\treturn ParseIDMapFile(\"/proc/self/gid_map\")\n}\n"
  },
  {
    "path": "vendor/github.com/moby/sys/user/user.go",
    "content": "package user\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst (\n\tminID = 0\n\tmaxID = 1<<31 - 1 // for 32-bit systems compatibility\n)\n\nvar (\n\t// ErrNoPasswdEntries is returned if no matching entries were found in /etc/group.\n\tErrNoPasswdEntries = errors.New(\"no matching entries in passwd file\")\n\t// ErrNoGroupEntries is returned if no matching entries were found in /etc/passwd.\n\tErrNoGroupEntries = errors.New(\"no matching entries in group file\")\n\t// ErrRange is returned if a UID or GID is outside of the valid range.\n\tErrRange = fmt.Errorf(\"uids and gids must be in range %d-%d\", minID, maxID)\n)\n\ntype User struct {\n\tName  string\n\tPass  string\n\tUid   int\n\tGid   int\n\tGecos string\n\tHome  string\n\tShell string\n}\n\ntype Group struct {\n\tName string\n\tPass string\n\tGid  int\n\tList []string\n}\n\n// SubID represents an entry in /etc/sub{u,g}id\ntype SubID struct {\n\tName  string\n\tSubID int64\n\tCount int64\n}\n\n// IDMap represents an entry in /proc/PID/{u,g}id_map\ntype IDMap struct {\n\tID       int64\n\tParentID int64\n\tCount    int64\n}\n\nfunc parseLine(line []byte, v ...interface{}) {\n\tparseParts(bytes.Split(line, []byte(\":\")), v...)\n}\n\nfunc parseParts(parts [][]byte, v ...interface{}) {\n\tif len(parts) == 0 {\n\t\treturn\n\t}\n\n\tfor i, p := range parts {\n\t\t// Ignore cases where we don't have enough fields to populate the arguments.\n\t\t// Some configuration files like to misbehave.\n\t\tif len(v) <= i {\n\t\t\tbreak\n\t\t}\n\n\t\t// Use the type of the argument to figure out how to parse it, scanf() style.\n\t\t// This is legit.\n\t\tswitch e := v[i].(type) {\n\t\tcase *string:\n\t\t\t*e = string(p)\n\t\tcase *int:\n\t\t\t// \"numbers\", with conversion errors ignored because of some misbehaving configuration files.\n\t\t\t*e, _ = strconv.Atoi(string(p))\n\t\tcase *int64:\n\t\t\t*e, _ = strconv.ParseInt(string(p), 10, 64)\n\t\tcase *[]string:\n\t\t\t// Comma-separated lists.\n\t\t\tif len(p) != 0 {\n\t\t\t\t*e = strings.Split(string(p), \",\")\n\t\t\t} else {\n\t\t\t\t*e = []string{}\n\t\t\t}\n\t\tdefault:\n\t\t\t// Someone goof'd when writing code using this function. Scream so they can hear us.\n\t\t\tpanic(fmt.Sprintf(\"parseLine only accepts {*string, *int, *int64, *[]string} as arguments! %#v is not a pointer!\", e))\n\t\t}\n\t}\n}\n\nfunc ParsePasswdFile(path string) ([]User, error) {\n\tpasswd, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer passwd.Close()\n\treturn ParsePasswd(passwd)\n}\n\nfunc ParsePasswd(passwd io.Reader) ([]User, error) {\n\treturn ParsePasswdFilter(passwd, nil)\n}\n\nfunc ParsePasswdFileFilter(path string, filter func(User) bool) ([]User, error) {\n\tpasswd, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer passwd.Close()\n\treturn ParsePasswdFilter(passwd, filter)\n}\n\nfunc ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) {\n\tif r == nil {\n\t\treturn nil, errors.New(\"nil source for passwd-formatted data\")\n\t}\n\n\tvar (\n\t\ts   = bufio.NewScanner(r)\n\t\tout = []User{}\n\t)\n\n\tfor s.Scan() {\n\t\tline := bytes.TrimSpace(s.Bytes())\n\t\tif len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// see: man 5 passwd\n\t\t//  name:password:UID:GID:GECOS:directory:shell\n\t\t// Name:Pass:Uid:Gid:Gecos:Home:Shell\n\t\t//  root:x:0:0:root:/root:/bin/bash\n\t\t//  adm:x:3:4:adm:/var/adm:/bin/false\n\t\tp := User{}\n\t\tparseLine(line, &p.Name, &p.Pass, &p.Uid, &p.Gid, &p.Gecos, &p.Home, &p.Shell)\n\n\t\tif filter == nil || filter(p) {\n\t\t\tout = append(out, p)\n\t\t}\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn out, nil\n}\n\nfunc ParseGroupFile(path string) ([]Group, error) {\n\tgroup, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer group.Close()\n\treturn ParseGroup(group)\n}\n\nfunc ParseGroup(group io.Reader) ([]Group, error) {\n\treturn ParseGroupFilter(group, nil)\n}\n\nfunc ParseGroupFileFilter(path string, filter func(Group) bool) ([]Group, error) {\n\tgroup, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer group.Close()\n\treturn ParseGroupFilter(group, filter)\n}\n\nfunc ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {\n\tif r == nil {\n\t\treturn nil, errors.New(\"nil source for group-formatted data\")\n\t}\n\trd := bufio.NewReader(r)\n\tout := []Group{}\n\n\t// Read the file line-by-line.\n\tfor {\n\t\tvar (\n\t\t\tisPrefix  bool\n\t\t\twholeLine []byte\n\t\t\terr       error\n\t\t)\n\n\t\t// Read the next line. We do so in chunks (as much as reader's\n\t\t// buffer is able to keep), check if we read enough columns\n\t\t// already on each step and store final result in wholeLine.\n\t\tfor {\n\t\t\tvar line []byte\n\t\t\tline, isPrefix, err = rd.ReadLine()\n\t\t\tif err != nil {\n\t\t\t\t// We should return no error if EOF is reached\n\t\t\t\t// without a match.\n\t\t\t\tif err == io.EOF {\n\t\t\t\t\terr = nil\n\t\t\t\t}\n\t\t\t\treturn out, err\n\t\t\t}\n\n\t\t\t// Simple common case: line is short enough to fit in a\n\t\t\t// single reader's buffer.\n\t\t\tif !isPrefix && len(wholeLine) == 0 {\n\t\t\t\twholeLine = line\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\twholeLine = append(wholeLine, line...)\n\n\t\t\t// Check if we read the whole line already.\n\t\t\tif !isPrefix {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// There's no spec for /etc/passwd or /etc/group, but we try to follow\n\t\t// the same rules as the glibc parser, which allows comments and blank\n\t\t// space at the beginning of a line.\n\t\twholeLine = bytes.TrimSpace(wholeLine)\n\t\tif len(wholeLine) == 0 || wholeLine[0] == '#' {\n\t\t\tcontinue\n\t\t}\n\n\t\t// see: man 5 group\n\t\t//  group_name:password:GID:user_list\n\t\t// Name:Pass:Gid:List\n\t\t//  root:x:0:root\n\t\t//  adm:x:4:root,adm,daemon\n\t\tp := Group{}\n\t\tparseLine(wholeLine, &p.Name, &p.Pass, &p.Gid, &p.List)\n\n\t\tif filter == nil || filter(p) {\n\t\t\tout = append(out, p)\n\t\t}\n\t}\n}\n\ntype ExecUser struct {\n\tUid   int\n\tGid   int\n\tSgids []int\n\tHome  string\n}\n\n// GetExecUserPath is a wrapper for GetExecUser. It reads data from each of the\n// given file paths and uses that data as the arguments to GetExecUser. If the\n// files cannot be opened for any reason, the error is ignored and a nil\n// io.Reader is passed instead.\nfunc GetExecUserPath(userSpec string, defaults *ExecUser, passwdPath, groupPath string) (*ExecUser, error) {\n\tvar passwd, group io.Reader\n\n\tif passwdFile, err := os.Open(passwdPath); err == nil {\n\t\tpasswd = passwdFile\n\t\tdefer passwdFile.Close()\n\t}\n\n\tif groupFile, err := os.Open(groupPath); err == nil {\n\t\tgroup = groupFile\n\t\tdefer groupFile.Close()\n\t}\n\n\treturn GetExecUser(userSpec, defaults, passwd, group)\n}\n\n// GetExecUser parses a user specification string (using the passwd and group\n// readers as sources for /etc/passwd and /etc/group data, respectively). In\n// the case of blank fields or missing data from the sources, the values in\n// defaults is used.\n//\n// GetExecUser will return an error if a user or group literal could not be\n// found in any entry in passwd and group respectively.\n//\n// Examples of valid user specifications are:\n//   - \"\"\n//   - \"user\"\n//   - \"uid\"\n//   - \"user:group\"\n//   - \"uid:gid\n//   - \"user:gid\"\n//   - \"uid:group\"\n//\n// It should be noted that if you specify a numeric user or group id, they will\n// not be evaluated as usernames (only the metadata will be filled). So attempting\n// to parse a user with user.Name = \"1337\" will produce the user with a UID of\n// 1337.\nfunc GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (*ExecUser, error) {\n\tif defaults == nil {\n\t\tdefaults = new(ExecUser)\n\t}\n\n\t// Copy over defaults.\n\tuser := &ExecUser{\n\t\tUid:   defaults.Uid,\n\t\tGid:   defaults.Gid,\n\t\tSgids: defaults.Sgids,\n\t\tHome:  defaults.Home,\n\t}\n\n\t// Sgids slice *cannot* be nil.\n\tif user.Sgids == nil {\n\t\tuser.Sgids = []int{}\n\t}\n\n\t// Allow for userArg to have either \"user\" syntax, or optionally \"user:group\" syntax\n\tvar userArg, groupArg string\n\tparseLine([]byte(userSpec), &userArg, &groupArg)\n\n\t// Convert userArg and groupArg to be numeric, so we don't have to execute\n\t// Atoi *twice* for each iteration over lines.\n\tuidArg, uidErr := strconv.Atoi(userArg)\n\tgidArg, gidErr := strconv.Atoi(groupArg)\n\n\t// Find the matching user.\n\tusers, err := ParsePasswdFilter(passwd, func(u User) bool {\n\t\tif userArg == \"\" {\n\t\t\t// Default to current state of the user.\n\t\t\treturn u.Uid == user.Uid\n\t\t}\n\n\t\tif uidErr == nil {\n\t\t\t// If the userArg is numeric, always treat it as a UID.\n\t\t\treturn uidArg == u.Uid\n\t\t}\n\n\t\treturn u.Name == userArg\n\t})\n\n\t// If we can't find the user, we have to bail.\n\tif err != nil && passwd != nil {\n\t\tif userArg == \"\" {\n\t\t\tuserArg = strconv.Itoa(user.Uid)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"unable to find user %s: %w\", userArg, err)\n\t}\n\n\tvar matchedUserName string\n\tif len(users) > 0 {\n\t\t// First match wins, even if there's more than one matching entry.\n\t\tmatchedUserName = users[0].Name\n\t\tuser.Uid = users[0].Uid\n\t\tuser.Gid = users[0].Gid\n\t\tuser.Home = users[0].Home\n\t} else if userArg != \"\" {\n\t\t// If we can't find a user with the given username, the only other valid\n\t\t// option is if it's a numeric username with no associated entry in passwd.\n\n\t\tif uidErr != nil {\n\t\t\t// Not numeric.\n\t\t\treturn nil, fmt.Errorf(\"unable to find user %s: %w\", userArg, ErrNoPasswdEntries)\n\t\t}\n\t\tuser.Uid = uidArg\n\n\t\t// Must be inside valid uid range.\n\t\tif user.Uid < minID || user.Uid > maxID {\n\t\t\treturn nil, ErrRange\n\t\t}\n\n\t\t// Okay, so it's numeric. We can just roll with this.\n\t}\n\n\t// On to the groups. If we matched a username, we need to do this because of\n\t// the supplementary group IDs.\n\tif groupArg != \"\" || matchedUserName != \"\" {\n\t\tgroups, err := ParseGroupFilter(group, func(g Group) bool {\n\t\t\t// If the group argument isn't explicit, we'll just search for it.\n\t\t\tif groupArg == \"\" {\n\t\t\t\t// Check if user is a member of this group.\n\t\t\t\tfor _, u := range g.List {\n\t\t\t\t\tif u == matchedUserName {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif gidErr == nil {\n\t\t\t\t// If the groupArg is numeric, always treat it as a GID.\n\t\t\t\treturn gidArg == g.Gid\n\t\t\t}\n\n\t\t\treturn g.Name == groupArg\n\t\t})\n\t\tif err != nil && group != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to find groups for spec %v: %w\", matchedUserName, err)\n\t\t}\n\n\t\t// Only start modifying user.Gid if it is in explicit form.\n\t\tif groupArg != \"\" {\n\t\t\tif len(groups) > 0 {\n\t\t\t\t// First match wins, even if there's more than one matching entry.\n\t\t\t\tuser.Gid = groups[0].Gid\n\t\t\t} else {\n\t\t\t\t// If we can't find a group with the given name, the only other valid\n\t\t\t\t// option is if it's a numeric group name with no associated entry in group.\n\n\t\t\t\tif gidErr != nil {\n\t\t\t\t\t// Not numeric.\n\t\t\t\t\treturn nil, fmt.Errorf(\"unable to find group %s: %w\", groupArg, ErrNoGroupEntries)\n\t\t\t\t}\n\t\t\t\tuser.Gid = gidArg\n\n\t\t\t\t// Must be inside valid gid range.\n\t\t\t\tif user.Gid < minID || user.Gid > maxID {\n\t\t\t\t\treturn nil, ErrRange\n\t\t\t\t}\n\n\t\t\t\t// Okay, so it's numeric. We can just roll with this.\n\t\t\t}\n\t\t} else if len(groups) > 0 {\n\t\t\t// Supplementary group ids only make sense if in the implicit form.\n\t\t\tuser.Sgids = make([]int, len(groups))\n\t\t\tfor i, group := range groups {\n\t\t\t\tuser.Sgids[i] = group.Gid\n\t\t\t}\n\t\t}\n\t}\n\n\treturn user, nil\n}\n\n// GetAdditionalGroups looks up a list of groups by name or group id\n// against the given /etc/group formatted data. If a group name cannot\n// be found, an error will be returned. If a group id cannot be found,\n// or the given group data is nil, the id will be returned as-is\n// provided it is in the legal range.\nfunc GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) {\n\tgroups := []Group{}\n\tif group != nil {\n\t\tvar err error\n\t\tgroups, err = ParseGroupFilter(group, func(g Group) bool {\n\t\t\tfor _, ag := range additionalGroups {\n\t\t\t\tif g.Name == ag || strconv.Itoa(g.Gid) == ag {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"Unable to find additional groups %v: %w\", additionalGroups, err)\n\t\t}\n\t}\n\n\tgidMap := make(map[int]struct{})\n\tfor _, ag := range additionalGroups {\n\t\tvar found bool\n\t\tfor _, g := range groups {\n\t\t\t// if we found a matched group either by name or gid, take the\n\t\t\t// first matched as correct\n\t\t\tif g.Name == ag || strconv.Itoa(g.Gid) == ag {\n\t\t\t\tif _, ok := gidMap[g.Gid]; !ok {\n\t\t\t\t\tgidMap[g.Gid] = struct{}{}\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}\n\t\t// we asked for a group but didn't find it. let's check to see\n\t\t// if we wanted a numeric group\n\t\tif !found {\n\t\t\tgid, err := strconv.ParseInt(ag, 10, 64)\n\t\t\tif err != nil {\n\t\t\t\t// Not a numeric ID either.\n\t\t\t\treturn nil, fmt.Errorf(\"Unable to find group %s: %w\", ag, ErrNoGroupEntries)\n\t\t\t}\n\t\t\t// Ensure gid is inside gid range.\n\t\t\tif gid < minID || gid > maxID {\n\t\t\t\treturn nil, ErrRange\n\t\t\t}\n\t\t\tgidMap[int(gid)] = struct{}{}\n\t\t}\n\t}\n\tgids := []int{}\n\tfor gid := range gidMap {\n\t\tgids = append(gids, gid)\n\t}\n\treturn gids, nil\n}\n\n// GetAdditionalGroupsPath is a wrapper around GetAdditionalGroups\n// that opens the groupPath given and gives it as an argument to\n// GetAdditionalGroups.\nfunc GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) {\n\tvar group io.Reader\n\n\tif groupFile, err := os.Open(groupPath); err == nil {\n\t\tgroup = groupFile\n\t\tdefer groupFile.Close()\n\t}\n\treturn GetAdditionalGroups(additionalGroups, group)\n}\n\nfunc ParseSubIDFile(path string) ([]SubID, error) {\n\tsubid, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer subid.Close()\n\treturn ParseSubID(subid)\n}\n\nfunc ParseSubID(subid io.Reader) ([]SubID, error) {\n\treturn ParseSubIDFilter(subid, nil)\n}\n\nfunc ParseSubIDFileFilter(path string, filter func(SubID) bool) ([]SubID, error) {\n\tsubid, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer subid.Close()\n\treturn ParseSubIDFilter(subid, filter)\n}\n\nfunc ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) {\n\tif r == nil {\n\t\treturn nil, errors.New(\"nil source for subid-formatted data\")\n\t}\n\n\tvar (\n\t\ts   = bufio.NewScanner(r)\n\t\tout = []SubID{}\n\t)\n\n\tfor s.Scan() {\n\t\tline := bytes.TrimSpace(s.Bytes())\n\t\tif len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// see: man 5 subuid\n\t\tp := SubID{}\n\t\tparseLine(line, &p.Name, &p.SubID, &p.Count)\n\n\t\tif filter == nil || filter(p) {\n\t\t\tout = append(out, p)\n\t\t}\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn out, nil\n}\n\nfunc ParseIDMapFile(path string) ([]IDMap, error) {\n\tr, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer r.Close()\n\treturn ParseIDMap(r)\n}\n\nfunc ParseIDMap(r io.Reader) ([]IDMap, error) {\n\treturn ParseIDMapFilter(r, nil)\n}\n\nfunc ParseIDMapFileFilter(path string, filter func(IDMap) bool) ([]IDMap, error) {\n\tr, err := os.Open(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer r.Close()\n\treturn ParseIDMapFilter(r, filter)\n}\n\nfunc ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) {\n\tif r == nil {\n\t\treturn nil, errors.New(\"nil source for idmap-formatted data\")\n\t}\n\n\tvar (\n\t\ts   = bufio.NewScanner(r)\n\t\tout = []IDMap{}\n\t)\n\n\tfor s.Scan() {\n\t\tline := bytes.TrimSpace(s.Bytes())\n\t\tif len(line) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// see: man 7 user_namespaces\n\t\tp := IDMap{}\n\t\tparseParts(bytes.Fields(line), &p.ID, &p.ParentID, &p.Count)\n\n\t\tif filter == nil || filter(p) {\n\t\t\tout = append(out, p)\n\t\t}\n\t}\n\tif err := s.Err(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn out, nil\n}\n"
  },
  {
    "path": "vendor/github.com/moby/sys/user/user_fuzzer.go",
    "content": "//go:build gofuzz\n// +build gofuzz\n\npackage user\n\nimport (\n\t\"io\"\n\t\"strings\"\n)\n\nfunc IsDivisbleBy(n int, divisibleby int) bool {\n\treturn (n % divisibleby) == 0\n}\n\nfunc FuzzUser(data []byte) int {\n\tif len(data) == 0 {\n\t\treturn -1\n\t}\n\tif !IsDivisbleBy(len(data), 5) {\n\t\treturn -1\n\t}\n\n\tvar divided [][]byte\n\n\tchunkSize := len(data) / 5\n\n\tfor i := 0; i < len(data); i += chunkSize {\n\t\tend := i + chunkSize\n\n\t\tdivided = append(divided, data[i:end])\n\t}\n\n\t_, _ = ParsePasswdFilter(strings.NewReader(string(divided[0])), nil)\n\n\tvar passwd, group io.Reader\n\n\tgroup = strings.NewReader(string(divided[1]))\n\t_, _ = GetAdditionalGroups([]string{string(divided[2])}, group)\n\n\tpasswd = strings.NewReader(string(divided[3]))\n\t_, _ = GetExecUser(string(divided[4]), nil, passwd, group)\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/.gitignore",
    "content": "/coverage.txt\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/.travis.yml",
    "content": "language: go\n\ngo:\n  - 1.8.x\n  - 1.x\n\nbefore_install:\n  - go get -t -v ./...\n\nscript:\n  - ./test.sh\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/github.com/modern-go/concurrent/README.md",
    "content": "# concurrent\n\n[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/concurrent/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/concurrent?badge)\n[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/concurrent)\n[![Build Status](https://travis-ci.org/modern-go/concurrent.svg?branch=master)](https://travis-ci.org/modern-go/concurrent)\n[![codecov](https://codecov.io/gh/modern-go/concurrent/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/concurrent)\n[![rcard](https://goreportcard.com/badge/github.com/modern-go/concurrent)](https://goreportcard.com/report/github.com/modern-go/concurrent)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE)\n\n* concurrent.Map: backport sync.Map for go below 1.9\n* concurrent.Executor: goroutine with explicit ownership and cancellable\n\n# concurrent.Map\n\nbecause sync.Map is only available in go 1.9, we can use concurrent.Map to make code portable\n\n```go\nm := concurrent.NewMap()\nm.Store(\"hello\", \"world\")\nelem, found := m.Load(\"hello\")\n// elem will be \"world\"\n// found will be true\n```\n\n# concurrent.Executor\n\n```go\nexecutor := concurrent.NewUnboundedExecutor()\nexecutor.Go(func(ctx context.Context) {\n    everyMillisecond := time.NewTicker(time.Millisecond)\n    for {\n        select {\n        case <-ctx.Done():\n            fmt.Println(\"goroutine exited\")\n            return\n        case <-everyMillisecond.C:\n            // do something\n        }\n    }\n})\ntime.Sleep(time.Second)\nexecutor.StopAndWaitForever()\nfmt.Println(\"executor stopped\")\n```\n\nattach goroutine to executor instance, so that we can\n\n* cancel it by stop the executor with Stop/StopAndWait/StopAndWaitForever\n* handle panic by callback: the default behavior will no longer crash your application"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/executor.go",
    "content": "package concurrent\n\nimport \"context\"\n\n// Executor replace go keyword to start a new goroutine\n// the goroutine should cancel itself if the context passed in has been cancelled\n// the goroutine started by the executor, is owned by the executor\n// we can cancel all executors owned by the executor just by stop the executor itself\n// however Executor interface does not Stop method, the one starting and owning executor\n// should use the concrete type of executor, instead of this interface.\ntype Executor interface {\n\t// Go starts a new goroutine controlled by the context\n\tGo(handler func(ctx context.Context))\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/go_above_19.go",
    "content": "//+build go1.9\n\npackage concurrent\n\nimport \"sync\"\n\n// Map is a wrapper for sync.Map introduced in go1.9\ntype Map struct {\n\tsync.Map\n}\n\n// NewMap creates a thread safe Map\nfunc NewMap() *Map {\n\treturn &Map{}\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/go_below_19.go",
    "content": "//+build !go1.9\n\npackage concurrent\n\nimport \"sync\"\n\n// Map implements a thread safe map for go version below 1.9 using mutex\ntype Map struct {\n\tlock sync.RWMutex\n\tdata map[interface{}]interface{}\n}\n\n// NewMap creates a thread safe map\nfunc NewMap() *Map {\n\treturn &Map{\n\t\tdata: make(map[interface{}]interface{}, 32),\n\t}\n}\n\n// Load is same as sync.Map Load\nfunc (m *Map) Load(key interface{}) (elem interface{}, found bool) {\n\tm.lock.RLock()\n\telem, found = m.data[key]\n\tm.lock.RUnlock()\n\treturn\n}\n\n// Load is same as sync.Map Store\nfunc (m *Map) Store(key interface{}, elem interface{}) {\n\tm.lock.Lock()\n\tm.data[key] = elem\n\tm.lock.Unlock()\n}\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/log.go",
    "content": "package concurrent\n\nimport (\n\t\"os\"\n\t\"log\"\n\t\"io/ioutil\"\n)\n\n// ErrorLogger is used to print out error, can be set to writer other than stderr\nvar ErrorLogger = log.New(os.Stderr, \"\", 0)\n\n// InfoLogger is used to print informational message, default to off\nvar InfoLogger = log.New(ioutil.Discard, \"\", 0)"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/test.sh",
    "content": "#!/usr/bin/env bash\n\nset -e\necho \"\" > coverage.txt\n\nfor d in $(go list ./... | grep -v vendor); do\n    go test -coverprofile=profile.out -coverpkg=github.com/modern-go/concurrent $d\n    if [ -f profile.out ]; then\n        cat profile.out >> coverage.txt\n        rm profile.out\n    fi\ndone\n"
  },
  {
    "path": "vendor/github.com/modern-go/concurrent/unbounded_executor.go",
    "content": "package concurrent\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"sync\"\n\t\"time\"\n\t\"reflect\"\n)\n\n// HandlePanic logs goroutine panic by default\nvar HandlePanic = func(recovered interface{}, funcName string) {\n\tErrorLogger.Println(fmt.Sprintf(\"%s panic: %v\", funcName, recovered))\n\tErrorLogger.Println(string(debug.Stack()))\n}\n\n// UnboundedExecutor is a executor without limits on counts of alive goroutines\n// it tracks the goroutine started by it, and can cancel them when shutdown\ntype UnboundedExecutor struct {\n\tctx                   context.Context\n\tcancel                context.CancelFunc\n\tactiveGoroutinesMutex *sync.Mutex\n\tactiveGoroutines      map[string]int\n\tHandlePanic           func(recovered interface{}, funcName string)\n}\n\n// GlobalUnboundedExecutor has the life cycle of the program itself\n// any goroutine want to be shutdown before main exit can be started from this executor\n// GlobalUnboundedExecutor expects the main function to call stop\n// it does not magically knows the main function exits\nvar GlobalUnboundedExecutor = NewUnboundedExecutor()\n\n// NewUnboundedExecutor creates a new UnboundedExecutor,\n// UnboundedExecutor can not be created by &UnboundedExecutor{}\n// HandlePanic can be set with a callback to override global HandlePanic\nfunc NewUnboundedExecutor() *UnboundedExecutor {\n\tctx, cancel := context.WithCancel(context.TODO())\n\treturn &UnboundedExecutor{\n\t\tctx:                   ctx,\n\t\tcancel:                cancel,\n\t\tactiveGoroutinesMutex: &sync.Mutex{},\n\t\tactiveGoroutines:      map[string]int{},\n\t}\n}\n\n// Go starts a new goroutine and tracks its lifecycle.\n// Panic will be recovered and logged automatically, except for StopSignal\nfunc (executor *UnboundedExecutor) Go(handler func(ctx context.Context)) {\n\tpc := reflect.ValueOf(handler).Pointer()\n\tf := runtime.FuncForPC(pc)\n\tfuncName := f.Name()\n\tfile, line := f.FileLine(pc)\n\texecutor.activeGoroutinesMutex.Lock()\n\tdefer executor.activeGoroutinesMutex.Unlock()\n\tstartFrom := fmt.Sprintf(\"%s:%d\", file, line)\n\texecutor.activeGoroutines[startFrom] += 1\n\tgo func() {\n\t\tdefer func() {\n\t\t\trecovered := recover()\n\t\t\t// if you want to quit a goroutine without trigger HandlePanic\n\t\t\t// use runtime.Goexit() to quit\n\t\t\tif recovered != nil {\n\t\t\t\tif executor.HandlePanic == nil {\n\t\t\t\t\tHandlePanic(recovered, funcName)\n\t\t\t\t} else {\n\t\t\t\t\texecutor.HandlePanic(recovered, funcName)\n\t\t\t\t}\n\t\t\t}\n\t\t\texecutor.activeGoroutinesMutex.Lock()\n\t\t\texecutor.activeGoroutines[startFrom] -= 1\n\t\t\texecutor.activeGoroutinesMutex.Unlock()\n\t\t}()\n\t\thandler(executor.ctx)\n\t}()\n}\n\n// Stop cancel all goroutines started by this executor without wait\nfunc (executor *UnboundedExecutor) Stop() {\n\texecutor.cancel()\n}\n\n// StopAndWaitForever cancel all goroutines started by this executor and\n// wait until all goroutines exited\nfunc (executor *UnboundedExecutor) StopAndWaitForever() {\n\texecutor.StopAndWait(context.Background())\n}\n\n// StopAndWait cancel all goroutines started by this executor and wait.\n// Wait can be cancelled by the context passed in.\nfunc (executor *UnboundedExecutor) StopAndWait(ctx context.Context) {\n\texecutor.cancel()\n\tfor {\n\t\toneHundredMilliseconds := time.NewTimer(time.Millisecond * 100)\n\t\tselect {\n\t\tcase <-oneHundredMilliseconds.C:\n\t\t\tif executor.checkNoActiveGoroutines() {\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-ctx.Done():\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (executor *UnboundedExecutor) checkNoActiveGoroutines() bool {\n\texecutor.activeGoroutinesMutex.Lock()\n\tdefer executor.activeGoroutinesMutex.Unlock()\n\tfor startFrom, count := range executor.activeGoroutines {\n\t\tif count > 0 {\n\t\t\tInfoLogger.Println(\"UnboundedExecutor is still waiting goroutines to quit\",\n\t\t\t\t\"startFrom\", startFrom,\n\t\t\t\t\"count\", count)\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/mohae/deepcopy/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*~\n*.out\n*.log\n"
  },
  {
    "path": "vendor/github.com/mohae/deepcopy/.travis.yml",
    "content": "language: go\n\ngo:\n  - tip\n\nmatrix:\n  allow_failures:\n    - go: tip\n\nscript:\n  - go test ./...\n"
  },
  {
    "path": "vendor/github.com/mohae/deepcopy/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Joel\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": "vendor/github.com/mohae/deepcopy/README.md",
    "content": "deepCopy\n========\n[![GoDoc](https://godoc.org/github.com/mohae/deepcopy?status.svg)](https://godoc.org/github.com/mohae/deepcopy)[![Build Status](https://travis-ci.org/mohae/deepcopy.png)](https://travis-ci.org/mohae/deepcopy)\n\nDeepCopy makes deep copies of things: unexported field values are not copied.\n\n## Usage\n    cpy := deepcopy.Copy(orig)\n"
  },
  {
    "path": "vendor/github.com/mohae/deepcopy/deepcopy.go",
    "content": "// deepcopy makes deep copies of things. A standard copy will copy the\n// pointers: deep copy copies the values pointed to.  Unexported field\n// values are not copied.\n//\n// Copyright (c)2014-2016, Joel Scoble (github.com/mohae), all rights reserved.\n// License: MIT, for more details check the included LICENSE file.\npackage deepcopy\n\nimport (\n\t\"reflect\"\n\t\"time\"\n)\n\n// Interface for delegating copy process to type\ntype Interface interface {\n\tDeepCopy() interface{}\n}\n\n// Iface is an alias to Copy; this exists for backwards compatibility reasons.\nfunc Iface(iface interface{}) interface{} {\n\treturn Copy(iface)\n}\n\n// Copy creates a deep copy of whatever is passed to it and returns the copy\n// in an interface{}.  The returned value will need to be asserted to the\n// correct type.\nfunc Copy(src interface{}) interface{} {\n\tif src == nil {\n\t\treturn nil\n\t}\n\n\t// Make the interface a reflect.Value\n\toriginal := reflect.ValueOf(src)\n\n\t// Make a copy of the same type as the original.\n\tcpy := reflect.New(original.Type()).Elem()\n\n\t// Recursively copy the original.\n\tcopyRecursive(original, cpy)\n\n\t// Return the copy as an interface.\n\treturn cpy.Interface()\n}\n\n// copyRecursive does the actual copying of the interface. It currently has\n// limited support for what it can handle. Add as needed.\nfunc copyRecursive(original, cpy reflect.Value) {\n\t// check for implement deepcopy.Interface\n\tif original.CanInterface() {\n\t\tif copier, ok := original.Interface().(Interface); ok {\n\t\t\tcpy.Set(reflect.ValueOf(copier.DeepCopy()))\n\t\t\treturn\n\t\t}\n\t}\n\n\t// handle according to original's Kind\n\tswitch original.Kind() {\n\tcase reflect.Ptr:\n\t\t// Get the actual value being pointed to.\n\t\toriginalValue := original.Elem()\n\n\t\t// if  it isn't valid, return.\n\t\tif !originalValue.IsValid() {\n\t\t\treturn\n\t\t}\n\t\tcpy.Set(reflect.New(originalValue.Type()))\n\t\tcopyRecursive(originalValue, cpy.Elem())\n\n\tcase reflect.Interface:\n\t\t// If this is a nil, don't do anything\n\t\tif original.IsNil() {\n\t\t\treturn\n\t\t}\n\t\t// Get the value for the interface, not the pointer.\n\t\toriginalValue := original.Elem()\n\n\t\t// Get the value by calling Elem().\n\t\tcopyValue := reflect.New(originalValue.Type()).Elem()\n\t\tcopyRecursive(originalValue, copyValue)\n\t\tcpy.Set(copyValue)\n\n\tcase reflect.Struct:\n\t\tt, ok := original.Interface().(time.Time)\n\t\tif ok {\n\t\t\tcpy.Set(reflect.ValueOf(t))\n\t\t\treturn\n\t\t}\n\t\t// Go through each field of the struct and copy it.\n\t\tfor i := 0; i < original.NumField(); i++ {\n\t\t\t// The Type's StructField for a given field is checked to see if StructField.PkgPath\n\t\t\t// is set to determine if the field is exported or not because CanSet() returns false\n\t\t\t// for settable fields.  I'm not sure why.  -mohae\n\t\t\tif original.Type().Field(i).PkgPath != \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcopyRecursive(original.Field(i), cpy.Field(i))\n\t\t}\n\n\tcase reflect.Slice:\n\t\tif original.IsNil() {\n\t\t\treturn\n\t\t}\n\t\t// Make a new slice and copy each element.\n\t\tcpy.Set(reflect.MakeSlice(original.Type(), original.Len(), original.Cap()))\n\t\tfor i := 0; i < original.Len(); i++ {\n\t\t\tcopyRecursive(original.Index(i), cpy.Index(i))\n\t\t}\n\n\tcase reflect.Map:\n\t\tif original.IsNil() {\n\t\t\treturn\n\t\t}\n\t\tcpy.Set(reflect.MakeMap(original.Type()))\n\t\tfor _, key := range original.MapKeys() {\n\t\t\toriginalValue := original.MapIndex(key)\n\t\t\tcopyValue := reflect.New(originalValue.Type()).Elem()\n\t\t\tcopyRecursive(originalValue, copyValue)\n\t\t\tcopyKey := Copy(key.Interface())\n\t\t\tcpy.SetMapIndex(reflect.ValueOf(copyKey), copyValue)\n\t\t}\n\n\tdefault:\n\t\tcpy.Set(original)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/.travis.yml",
    "content": "language: go\ngo:\n  - 1.14.x\n  - master\nscript:\n  - go test -v ./...\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) [2015] [go-gitignore]\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": "vendor/github.com/monochromegane/go-gitignore/README.md",
    "content": "# go-gitignore [![Build Status](https://travis-ci.org/monochromegane/go-gitignore.svg)](https://travis-ci.org/monochromegane/go-gitignore)\n\nA fast gitignore matching library for Go.\n\nThis library use simple tree index for matching, so keep fast if gitignore file has many pattern.\n\n## Usage\n\n```go\ngitignore, _ := gitignore.NewGitIgnore(\"/path/to/gitignore\")\n\npath := \"/path/to/file\"\nisDir := false\ngitignore.Match(path, isDir)\n```\n\n### Specify base directory\n\ngo-gitignore treat `path` as a base directory.\nIf you want to specify other base (e.g. current directory and Global gitignore), you can like the following.\n\n```go\ngitignore, _ := gitignore.NewGitIgnore(\"/home/you/.gitignore\", \".\")\n```\n\n### From io.Reader\n\ngo-gitignore can initialize from io.Reader.\n\n```go\ngitignore, _ := gitignore.NewGitIgnoreFromReader(base, reader)\n```\n\n## Simple tree index\n\ngo-gitignore parse gitignore file, and generate a simple tree index for matching like the following.\n\n```\n.\n├── accept\n│   ├── absolute\n│   │   └── depth\n│   │       ├── initial\n│   │       └── other\n│   └── relative\n│       └── depth\n│           ├── initial\n│           └── other\n└── ignore\n    ├── absolute\n    │   └── depth\n    │       ├── initial\n    │       └── other\n    └── relative\n        └── depth\n            ├── initial\n            └── other\n```\n\n## Features\n\n- Support absolute path (/path/to/ignore)\n- Support relative path (path/to/ignore)\n- Support accept pattern (!path/to/accept)\n- Support directory pattern (path/to/directory/)\n- Support glob pattern (path/to/\\*.txt)\n\n*note: glob pattern*\n\ngo-gitignore use [filepath.Match](https://golang.org/pkg/path/filepath/#Match) for matching meta char pattern, so not support recursive pattern (path/`**`/file).\n\n## Installation\n\n```sh\n$ go get github.com/monochromegane/go-gitignore\n```\n\n## Contribution\n\n1. Fork it\n2. Create a feature branch\n3. Commit your changes\n4. Rebase your local changes against the master branch\n5. Run test suite with the `go test ./...` command and confirm that it passes\n6. Run `gofmt -s`\n7. Create new Pull Request\n\n## License\n\n[MIT](https://github.com/monochromegane/go-gitignore/blob/master/LICENSE)\n\n## Author\n\n[monochromegane](https://github.com/monochromegane)\n\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/depth_holder.go",
    "content": "package gitignore\n\nimport \"strings\"\n\nconst (\n\tasc = iota\n\tdesc\n)\n\ntype depthPatternHolder struct {\n\tpatterns depthPatterns\n\torder    int\n}\n\nfunc newDepthPatternHolder(order int) depthPatternHolder {\n\treturn depthPatternHolder{\n\t\tpatterns: depthPatterns{m: map[int]initialPatternHolder{}},\n\t\torder:    order,\n\t}\n}\n\nfunc (h *depthPatternHolder) add(pattern string) {\n\tcount := strings.Count(strings.Trim(pattern, \"/\"), \"/\")\n\th.patterns.set(count+1, pattern)\n}\n\nfunc (h depthPatternHolder) match(path string, isDir bool) bool {\n\tif h.patterns.size() == 0 {\n\t\treturn false\n\t}\n\n\tfor depth := 1; ; depth++ {\n\t\tvar part string\n\t\tvar isLast, isDirCurrent bool\n\t\tif h.order == asc {\n\t\t\tpart, isLast = cutN(path, depth)\n\t\t\tif isLast {\n\t\t\t\tisDirCurrent = isDir\n\t\t\t} else {\n\t\t\t\tisDirCurrent = false\n\t\t\t}\n\t\t} else {\n\t\t\tpart, isLast = cutLastN(path, depth)\n\t\t\tisDirCurrent = isDir\n\t\t}\n\t\tif patterns, ok := h.patterns.get(depth); ok {\n\t\t\tif patterns.match(part, isDirCurrent) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\tif isLast {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn false\n}\n\ntype depthPatterns struct {\n\tm map[int]initialPatternHolder\n}\n\nfunc (p *depthPatterns) set(depth int, pattern string) {\n\tif ps, ok := p.m[depth]; ok {\n\t\tps.add(pattern)\n\t} else {\n\t\tholder := newInitialPatternHolder()\n\t\tholder.add(pattern)\n\t\tp.m[depth] = holder\n\t}\n}\n\nfunc (p depthPatterns) get(depth int) (initialPatternHolder, bool) {\n\tpatterns, ok := p.m[depth]\n\treturn patterns, ok\n}\n\nfunc (p depthPatterns) size() int {\n\treturn len(p.m)\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/full_scan_patterns.go",
    "content": "package gitignore\n\nimport \"strings\"\n\n// Only benchmark use\ntype fullScanPatterns struct {\n\tabsolute patterns\n\trelative patterns\n}\n\nfunc newFullScanPatterns() *fullScanPatterns {\n\treturn &fullScanPatterns{\n\t\tabsolute: patterns{},\n\t\trelative: patterns{},\n\t}\n}\n\nfunc (ps *fullScanPatterns) add(pattern string) {\n\tif strings.HasPrefix(pattern, \"/\") {\n\t\tps.absolute.add(newPattern(pattern))\n\t} else {\n\t\tps.relative.add(newPattern(pattern))\n\t}\n}\n\nfunc (ps fullScanPatterns) match(path string, isDir bool) bool {\n\tif ps.absolute.match(path, isDir) {\n\t\treturn true\n\t}\n\treturn ps.relative.match(path, isDir)\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/gitignore.go",
    "content": "package gitignore\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\ntype IgnoreMatcher interface {\n\tMatch(path string, isDir bool) bool\n}\n\ntype DummyIgnoreMatcher bool\n\nfunc (d DummyIgnoreMatcher) Match(path string, isDir bool) bool {\n\treturn bool(d)\n}\n\ntype gitIgnore struct {\n\tignorePatterns scanStrategy\n\tacceptPatterns scanStrategy\n\tpath           string\n}\n\nfunc NewGitIgnore(gitignore string, base ...string) (IgnoreMatcher, error) {\n\tvar path string\n\tif len(base) > 0 {\n\t\tpath = base[0]\n\t} else {\n\t\tpath = filepath.Dir(gitignore)\n\t}\n\n\tfile, err := os.Open(gitignore)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer file.Close()\n\n\treturn NewGitIgnoreFromReader(path, file), nil\n}\n\nfunc NewGitIgnoreFromReader(path string, r io.Reader) IgnoreMatcher {\n\tg := gitIgnore{\n\t\tignorePatterns: newIndexScanPatterns(),\n\t\tacceptPatterns: newIndexScanPatterns(),\n\t\tpath:           path,\n\t}\n\tscanner := bufio.NewScanner(r)\n\tfor scanner.Scan() {\n\t\tline := strings.Trim(scanner.Text(), \" \")\n\t\tif len(line) == 0 || strings.HasPrefix(line, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, `\\#`) {\n\t\t\tline = strings.TrimPrefix(line, `\\`)\n\t\t}\n\n\t\tif strings.HasPrefix(line, \"!\") {\n\t\t\tg.acceptPatterns.add(strings.TrimPrefix(line, \"!\"))\n\t\t} else {\n\t\t\tg.ignorePatterns.add(line)\n\t\t}\n\t}\n\treturn g\n}\n\nfunc (g gitIgnore) Match(path string, isDir bool) bool {\n\trelativePath, err := filepath.Rel(g.path, path)\n\tif err != nil {\n\t\treturn false\n\t}\n\trelativePath = filepath.ToSlash(relativePath)\n\n\tif g.acceptPatterns.match(relativePath, isDir) {\n\t\treturn false\n\t}\n\treturn g.ignorePatterns.match(relativePath, isDir)\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/index_scan_patterns.go",
    "content": "package gitignore\n\nimport \"strings\"\n\ntype indexScanPatterns struct {\n\tabsolute depthPatternHolder\n\trelative depthPatternHolder\n}\n\nfunc newIndexScanPatterns() *indexScanPatterns {\n\treturn &indexScanPatterns{\n\t\tabsolute: newDepthPatternHolder(asc),\n\t\trelative: newDepthPatternHolder(desc),\n\t}\n}\n\nfunc (ps *indexScanPatterns) add(pattern string) {\n\tif strings.HasPrefix(pattern, \"/\") {\n\t\tps.absolute.add(pattern)\n\t} else {\n\t\tps.relative.add(pattern)\n\t}\n}\n\nfunc (ps indexScanPatterns) match(path string, isDir bool) bool {\n\tif ps.absolute.match(path, isDir) {\n\t\treturn true\n\t}\n\treturn ps.relative.match(path, isDir)\n}\n\ntype scanStrategy interface {\n\tadd(pattern string)\n\tmatch(path string, isDir bool) bool\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/initial_holder.go",
    "content": "package gitignore\n\nimport \"strings\"\n\nconst initials = \"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.\"\n\ntype initialPatternHolder struct {\n\tpatterns      initialPatterns\n\totherPatterns *patterns\n}\n\nfunc newInitialPatternHolder() initialPatternHolder {\n\treturn initialPatternHolder{\n\t\tpatterns:      initialPatterns{m: map[byte]*patterns{}},\n\t\totherPatterns: &patterns{},\n\t}\n}\n\nfunc (h *initialPatternHolder) add(pattern string) {\n\ttrimedPattern := strings.TrimPrefix(pattern, \"/\")\n\tif strings.IndexAny(trimedPattern[0:1], initials) != -1 {\n\t\th.patterns.set(trimedPattern[0], newPatternForEqualizedPath(pattern))\n\t} else {\n\t\th.otherPatterns.add(newPatternForEqualizedPath(pattern))\n\t}\n}\n\nfunc (h initialPatternHolder) match(path string, isDir bool) bool {\n\tif h.patterns.size() == 0 && h.otherPatterns.size() == 0 {\n\t\treturn false\n\t}\n\tif patterns, ok := h.patterns.get(path[0]); ok {\n\t\tif patterns.match(path, isDir) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn h.otherPatterns.match(path, isDir)\n}\n\ntype initialPatterns struct {\n\tm map[byte]*patterns\n}\n\nfunc (p *initialPatterns) set(initial byte, pattern pattern) {\n\tif ps, ok := p.m[initial]; ok {\n\t\tps.add(pattern)\n\t} else {\n\t\tpatterns := &patterns{}\n\t\tpatterns.add(pattern)\n\t\tp.m[initial] = patterns\n\n\t}\n}\n\nfunc (p initialPatterns) get(initial byte) (*patterns, bool) {\n\tpatterns, ok := p.m[initial]\n\treturn patterns, ok\n}\n\nfunc (p initialPatterns) size() int {\n\treturn len(p.m)\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/match.go",
    "content": "package gitignore\n\nimport \"path/filepath\"\n\ntype pathMatcher interface {\n\tmatch(path string) bool\n}\n\ntype simpleMatcher struct {\n\tpath string\n}\n\nfunc (m simpleMatcher) match(path string) bool {\n\treturn m.path == path\n}\n\ntype filepathMatcher struct {\n\tpath string\n}\n\nfunc (m filepathMatcher) match(path string) bool {\n\tmatch, _ := filepath.Match(m.path, path)\n\treturn match\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/pattern.go",
    "content": "package gitignore\n\nimport (\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nvar Separator = string(filepath.Separator)\n\ntype pattern struct {\n\thasRootPrefix     bool\n\thasDirSuffix      bool\n\tpathDepth         int\n\tmatcher           pathMatcher\n\tonlyEqualizedPath bool\n}\n\nfunc newPattern(path string) pattern {\n\thasRootPrefix := path[0] == '/'\n\thasDirSuffix := path[len(path)-1] == '/'\n\n\tvar pathDepth int\n\tif !hasRootPrefix {\n\t\tpathDepth = strings.Count(path, \"/\")\n\t}\n\n\tvar matcher pathMatcher\n\tmatchingPath := strings.Trim(path, \"/\")\n\tif hasMeta(path) {\n\t\tmatcher = filepathMatcher{path: matchingPath}\n\t} else {\n\t\tmatcher = simpleMatcher{path: matchingPath}\n\t}\n\n\treturn pattern{\n\t\thasRootPrefix: hasRootPrefix,\n\t\thasDirSuffix:  hasDirSuffix,\n\t\tpathDepth:     pathDepth,\n\t\tmatcher:       matcher,\n\t}\n}\n\nfunc newPatternForEqualizedPath(path string) pattern {\n\tpattern := newPattern(path)\n\tpattern.onlyEqualizedPath = true\n\treturn pattern\n}\n\nfunc (p pattern) match(path string, isDir bool) bool {\n\n\tif p.hasDirSuffix && !isDir {\n\t\treturn false\n\t}\n\n\tvar targetPath string\n\tif p.hasRootPrefix || p.onlyEqualizedPath {\n\t\t// absolute pattern or only equalized path mode\n\t\ttargetPath = path\n\t} else {\n\t\t// relative pattern\n\t\ttargetPath = p.equalizeDepth(path)\n\t}\n\treturn p.matcher.match(targetPath)\n}\n\nfunc (p pattern) equalizeDepth(path string) string {\n\tequalizedPath, _ := cutLastN(path, p.pathDepth+1)\n\treturn equalizedPath\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/patterns.go",
    "content": "package gitignore\n\ntype patterns struct {\n\tpatterns []pattern\n}\n\nfunc (ps *patterns) add(pattern pattern) {\n\tps.patterns = append(ps.patterns, pattern)\n}\n\nfunc (ps *patterns) size() int {\n\treturn len(ps.patterns)\n}\n\nfunc (ps patterns) match(path string, isDir bool) bool {\n\tfor _, p := range ps.patterns {\n\t\tif match := p.match(path, isDir); match {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/monochromegane/go-gitignore/util.go",
    "content": "package gitignore\n\nimport (\n\t\"os\"\n\t\"strings\"\n)\n\nfunc cutN(path string, n int) (string, bool) {\n\tisLast := true\n\n\tvar i, count int\n\tfor i < len(path)-1 {\n\t\tif os.IsPathSeparator(path[i]) {\n\t\t\tcount++\n\t\t\tif count >= n {\n\t\t\t\tisLast = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\ti++\n\t}\n\treturn path[:i+1], isLast\n}\n\nfunc cutLastN(path string, n int) (string, bool) {\n\tisLast := true\n\ti := len(path) - 1\n\n\tvar count int\n\tfor i >= 0 {\n\t\tif os.IsPathSeparator(path[i]) {\n\t\t\tcount++\n\t\t\tif count >= n {\n\t\t\t\tisLast = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\ti--\n\t}\n\treturn path[i+1:], isLast\n}\n\nfunc hasMeta(path string) bool {\n\treturn strings.IndexAny(path, \"*?[\") >= 0\n}\n"
  },
  {
    "path": "vendor/github.com/morikuni/aec/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2016 Taihei Morikuni\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": "vendor/github.com/morikuni/aec/README.md",
    "content": "# aec\n\n[![GoDoc](https://godoc.org/github.com/morikuni/aec?status.svg)](https://godoc.org/github.com/morikuni/aec)\n\nGo wrapper for ANSI escape code.\n\n## Install\n\n```bash\ngo get github.com/morikuni/aec\n```\n\n## Features\n\nANSI escape codes depend on terminal environment.  \nSome of these features may not work.  \nCheck supported Font-Style/Font-Color features with [checkansi](./checkansi).\n\n[Wikipedia](https://en.wikipedia.org/wiki/ANSI_escape_code) for more detail.\n\n### Cursor\n\n- `Up(n)`\n- `Down(n)`\n- `Right(n)`\n- `Left(n)`\n- `NextLine(n)`\n- `PreviousLine(n)`\n- `Column(col)`\n- `Position(row, col)`\n- `Save`\n- `Restore`\n- `Hide`\n- `Show`\n- `Report`\n\n### Erase\n\n- `EraseDisplay(mode)`\n- `EraseLine(mode)`\n\n### Scroll\n\n- `ScrollUp(n)`\n- `ScrollDown(n)`\n\n### Font Style\n\n- `Bold`\n- `Faint`\n- `Italic`\n- `Underline`\n- `BlinkSlow`\n- `BlinkRapid`\n- `Inverse`\n- `Conceal`\n- `CrossOut`\n- `Frame`\n- `Encircle`\n- `Overline`\n\n### Font Color\n\nForeground color.\n\n- `DefaultF`\n- `BlackF`\n- `RedF`\n- `GreenF`\n- `YellowF`\n- `BlueF`\n- `MagentaF`\n- `CyanF`\n- `WhiteF`\n- `LightBlackF`\n- `LightRedF`\n- `LightGreenF`\n- `LightYellowF`\n- `LightBlueF`\n- `LightMagentaF`\n- `LightCyanF`\n- `LightWhiteF`\n- `Color3BitF(color)`\n- `Color8BitF(color)`\n- `FullColorF(r, g, b)`\n\nBackground color.\n\n- `DefaultB`\n- `BlackB`\n- `RedB`\n- `GreenB`\n- `YellowB`\n- `BlueB`\n- `MagentaB`\n- `CyanB`\n- `WhiteB`\n- `LightBlackB`\n- `LightRedB`\n- `LightGreenB`\n- `LightYellowB`\n- `LightBlueB`\n- `LightMagentaB`\n- `LightCyanB`\n- `LightWhiteB`\n- `Color3BitB(color)`\n- `Color8BitB(color)`\n- `FullColorB(r, g, b)`\n\n### Color Converter\n\n24bit RGB color to ANSI color.\n\n- `NewRGB3Bit(r, g, b)`\n- `NewRGB8Bit(r, g, b)`\n\n### Builder\n\nTo mix these features.\n\n```go\ncustom := aec.EmptyBuilder.Right(2).RGB8BitF(128, 255, 64).RedB().ANSI\ncustom.Apply(\"Hello World\")\n```\n\n## Usage\n\n1. Create ANSI by `aec.XXX().With(aec.YYY())` or `aec.EmptyBuilder.XXX().YYY().ANSI`\n2. Print ANSI by `fmt.Print(ansi, \"some string\", aec.Reset)` or `fmt.Print(ansi.Apply(\"some string\"))`\n\n`aec.Reset` should be added when using font style or font color features.\n\n## Example\n\nSimple progressbar.\n\n![sample](./sample.gif)\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/morikuni/aec\"\n)\n\nfunc main() {\n\tconst n = 20\n\tbuilder := aec.EmptyBuilder\n\n\tup2 := aec.Up(2)\n\tcol := aec.Column(n + 2)\n\tbar := aec.Color8BitF(aec.NewRGB8Bit(64, 255, 64))\n\tlabel := builder.LightRedF().Underline().With(col).Right(1).ANSI\n\n\t// for up2\n\tfmt.Println()\n\tfmt.Println()\n\n\tfor i := 0; i <= n; i++ {\n\t\tfmt.Print(up2)\n\t\tfmt.Println(label.Apply(fmt.Sprint(i, \"/\", n)))\n\t\tfmt.Print(\"[\")\n\t\tfmt.Print(bar.Apply(strings.Repeat(\"=\", i)))\n\t\tfmt.Println(col.Apply(\"]\"))\n\t\ttime.Sleep(100 * time.Millisecond)\n\t}\n}\n```\n\n## License\n\n[MIT](./LICENSE)\n\n\n"
  },
  {
    "path": "vendor/github.com/morikuni/aec/aec.go",
    "content": "package aec\n\nimport \"fmt\"\n\n// EraseMode is listed in a variable EraseModes.\ntype EraseMode uint\n\nvar (\n\t// EraseModes is a list of EraseMode.\n\tEraseModes struct {\n\t\t// All erase all.\n\t\tAll EraseMode\n\n\t\t// Head erase to head.\n\t\tHead EraseMode\n\n\t\t// Tail erase to tail.\n\t\tTail EraseMode\n\t}\n\n\t// Save saves the cursor position.\n\tSave ANSI\n\n\t// Restore restores the cursor position.\n\tRestore ANSI\n\n\t// Hide hides the cursor.\n\tHide ANSI\n\n\t// Show shows the cursor.\n\tShow ANSI\n\n\t// Report reports the cursor position.\n\tReport ANSI\n)\n\n// Up moves up the cursor.\nfunc Up(n uint) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dA\", n))\n}\n\n// Down moves down the cursor.\nfunc Down(n uint) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dB\", n))\n}\n\n// Right moves right the cursor.\nfunc Right(n uint) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dC\", n))\n}\n\n// Left moves left the cursor.\nfunc Left(n uint) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dD\", n))\n}\n\n// NextLine moves down the cursor to head of a line.\nfunc NextLine(n uint) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dE\", n))\n}\n\n// PreviousLine moves up the cursor to head of a line.\nfunc PreviousLine(n uint) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dF\", n))\n}\n\n// Column set the cursor position to a given column.\nfunc Column(col uint) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"%dG\", col))\n}\n\n// Position set the cursor position to a given absolute position.\nfunc Position(row, col uint) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"%d;%dH\", row, col))\n}\n\n// EraseDisplay erases display by given EraseMode.\nfunc EraseDisplay(m EraseMode) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"%dJ\", m))\n}\n\n// EraseLine erases lines by given EraseMode.\nfunc EraseLine(m EraseMode) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"%dK\", m))\n}\n\n// ScrollUp scrolls up the page.\nfunc ScrollUp(n int) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dS\", n))\n}\n\n// ScrollDown scrolls down the page.\nfunc ScrollDown(n int) ANSI {\n\tif n == 0 {\n\t\treturn empty\n\t}\n\treturn newAnsi(fmt.Sprintf(esc+\"%dT\", n))\n}\n\nfunc init() {\n\tEraseModes = struct {\n\t\tAll  EraseMode\n\t\tHead EraseMode\n\t\tTail EraseMode\n\t}{\n\t\tTail: 0,\n\t\tHead: 1,\n\t\tAll:  2,\n\t}\n\n\tSave = newAnsi(esc + \"s\")\n\tRestore = newAnsi(esc + \"u\")\n\tHide = newAnsi(esc + \"?25l\")\n\tShow = newAnsi(esc + \"?25h\")\n\tReport = newAnsi(esc + \"6n\")\n}\n"
  },
  {
    "path": "vendor/github.com/morikuni/aec/ansi.go",
    "content": "package aec\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nconst esc = \"\\x1b[\"\n\n// Reset resets SGR effect.\nconst Reset string = \"\\x1b[0m\"\n\nvar empty = newAnsi(\"\")\n\n// ANSI represents ANSI escape code.\ntype ANSI interface {\n\tfmt.Stringer\n\n\t// With adapts given ANSIs.\n\tWith(...ANSI) ANSI\n\n\t// Apply wraps given string in ANSI.\n\tApply(string) string\n}\n\ntype ansiImpl string\n\nfunc newAnsi(s string) *ansiImpl {\n\tr := ansiImpl(s)\n\treturn &r\n}\n\nfunc (a *ansiImpl) With(ansi ...ANSI) ANSI {\n\treturn concat(append([]ANSI{a}, ansi...))\n}\n\nfunc (a *ansiImpl) Apply(s string) string {\n\treturn a.String() + s + Reset\n}\n\nfunc (a *ansiImpl) String() string {\n\treturn string(*a)\n}\n\n// Apply wraps given string in ANSIs.\nfunc Apply(s string, ansi ...ANSI) string {\n\tif len(ansi) == 0 {\n\t\treturn s\n\t}\n\treturn concat(ansi).Apply(s)\n}\n\nfunc concat(ansi []ANSI) ANSI {\n\tstrs := make([]string, 0, len(ansi))\n\tfor _, p := range ansi {\n\t\tstrs = append(strs, p.String())\n\t}\n\treturn newAnsi(strings.Join(strs, \"\"))\n}\n"
  },
  {
    "path": "vendor/github.com/morikuni/aec/builder.go",
    "content": "package aec\n\n// Builder is a lightweight syntax to construct customized ANSI.\ntype Builder struct {\n\tANSI ANSI\n}\n\n// EmptyBuilder is an initialized Builder.\nvar EmptyBuilder *Builder\n\n// NewBuilder creates a Builder from existing ANSI.\nfunc NewBuilder(a ...ANSI) *Builder {\n\treturn &Builder{concat(a)}\n}\n\n// With is a syntax for With.\nfunc (builder *Builder) With(a ...ANSI) *Builder {\n\treturn NewBuilder(builder.ANSI.With(a...))\n}\n\n// Up is a syntax for Up.\nfunc (builder *Builder) Up(n uint) *Builder {\n\treturn builder.With(Up(n))\n}\n\n// Down is a syntax for Down.\nfunc (builder *Builder) Down(n uint) *Builder {\n\treturn builder.With(Down(n))\n}\n\n// Right is a syntax for Right.\nfunc (builder *Builder) Right(n uint) *Builder {\n\treturn builder.With(Right(n))\n}\n\n// Left is a syntax for Left.\nfunc (builder *Builder) Left(n uint) *Builder {\n\treturn builder.With(Left(n))\n}\n\n// NextLine is a syntax for NextLine.\nfunc (builder *Builder) NextLine(n uint) *Builder {\n\treturn builder.With(NextLine(n))\n}\n\n// PreviousLine is a syntax for PreviousLine.\nfunc (builder *Builder) PreviousLine(n uint) *Builder {\n\treturn builder.With(PreviousLine(n))\n}\n\n// Column is a syntax for Column.\nfunc (builder *Builder) Column(col uint) *Builder {\n\treturn builder.With(Column(col))\n}\n\n// Position is a syntax for Position.\nfunc (builder *Builder) Position(row, col uint) *Builder {\n\treturn builder.With(Position(row, col))\n}\n\n// EraseDisplay is a syntax for EraseDisplay.\nfunc (builder *Builder) EraseDisplay(m EraseMode) *Builder {\n\treturn builder.With(EraseDisplay(m))\n}\n\n// EraseLine is a syntax for EraseLine.\nfunc (builder *Builder) EraseLine(m EraseMode) *Builder {\n\treturn builder.With(EraseLine(m))\n}\n\n// ScrollUp is a syntax for ScrollUp.\nfunc (builder *Builder) ScrollUp(n int) *Builder {\n\treturn builder.With(ScrollUp(n))\n}\n\n// ScrollDown is a syntax for ScrollDown.\nfunc (builder *Builder) ScrollDown(n int) *Builder {\n\treturn builder.With(ScrollDown(n))\n}\n\n// Save is a syntax for Save.\nfunc (builder *Builder) Save() *Builder {\n\treturn builder.With(Save)\n}\n\n// Restore is a syntax for Restore.\nfunc (builder *Builder) Restore() *Builder {\n\treturn builder.With(Restore)\n}\n\n// Hide is a syntax for Hide.\nfunc (builder *Builder) Hide() *Builder {\n\treturn builder.With(Hide)\n}\n\n// Show is a syntax for Show.\nfunc (builder *Builder) Show() *Builder {\n\treturn builder.With(Show)\n}\n\n// Report is a syntax for Report.\nfunc (builder *Builder) Report() *Builder {\n\treturn builder.With(Report)\n}\n\n// Bold is a syntax for Bold.\nfunc (builder *Builder) Bold() *Builder {\n\treturn builder.With(Bold)\n}\n\n// Faint is a syntax for Faint.\nfunc (builder *Builder) Faint() *Builder {\n\treturn builder.With(Faint)\n}\n\n// Italic is a syntax for Italic.\nfunc (builder *Builder) Italic() *Builder {\n\treturn builder.With(Italic)\n}\n\n// Underline is a syntax for Underline.\nfunc (builder *Builder) Underline() *Builder {\n\treturn builder.With(Underline)\n}\n\n// BlinkSlow is a syntax for BlinkSlow.\nfunc (builder *Builder) BlinkSlow() *Builder {\n\treturn builder.With(BlinkSlow)\n}\n\n// BlinkRapid is a syntax for BlinkRapid.\nfunc (builder *Builder) BlinkRapid() *Builder {\n\treturn builder.With(BlinkRapid)\n}\n\n// Inverse is a syntax for Inverse.\nfunc (builder *Builder) Inverse() *Builder {\n\treturn builder.With(Inverse)\n}\n\n// Conceal is a syntax for Conceal.\nfunc (builder *Builder) Conceal() *Builder {\n\treturn builder.With(Conceal)\n}\n\n// CrossOut is a syntax for CrossOut.\nfunc (builder *Builder) CrossOut() *Builder {\n\treturn builder.With(CrossOut)\n}\n\n// BlackF is a syntax for BlackF.\nfunc (builder *Builder) BlackF() *Builder {\n\treturn builder.With(BlackF)\n}\n\n// RedF is a syntax for RedF.\nfunc (builder *Builder) RedF() *Builder {\n\treturn builder.With(RedF)\n}\n\n// GreenF is a syntax for GreenF.\nfunc (builder *Builder) GreenF() *Builder {\n\treturn builder.With(GreenF)\n}\n\n// YellowF is a syntax for YellowF.\nfunc (builder *Builder) YellowF() *Builder {\n\treturn builder.With(YellowF)\n}\n\n// BlueF is a syntax for BlueF.\nfunc (builder *Builder) BlueF() *Builder {\n\treturn builder.With(BlueF)\n}\n\n// MagentaF is a syntax for MagentaF.\nfunc (builder *Builder) MagentaF() *Builder {\n\treturn builder.With(MagentaF)\n}\n\n// CyanF is a syntax for CyanF.\nfunc (builder *Builder) CyanF() *Builder {\n\treturn builder.With(CyanF)\n}\n\n// WhiteF is a syntax for WhiteF.\nfunc (builder *Builder) WhiteF() *Builder {\n\treturn builder.With(WhiteF)\n}\n\n// DefaultF is a syntax for DefaultF.\nfunc (builder *Builder) DefaultF() *Builder {\n\treturn builder.With(DefaultF)\n}\n\n// BlackB is a syntax for BlackB.\nfunc (builder *Builder) BlackB() *Builder {\n\treturn builder.With(BlackB)\n}\n\n// RedB is a syntax for RedB.\nfunc (builder *Builder) RedB() *Builder {\n\treturn builder.With(RedB)\n}\n\n// GreenB is a syntax for GreenB.\nfunc (builder *Builder) GreenB() *Builder {\n\treturn builder.With(GreenB)\n}\n\n// YellowB is a syntax for YellowB.\nfunc (builder *Builder) YellowB() *Builder {\n\treturn builder.With(YellowB)\n}\n\n// BlueB is a syntax for BlueB.\nfunc (builder *Builder) BlueB() *Builder {\n\treturn builder.With(BlueB)\n}\n\n// MagentaB is a syntax for MagentaB.\nfunc (builder *Builder) MagentaB() *Builder {\n\treturn builder.With(MagentaB)\n}\n\n// CyanB is a syntax for CyanB.\nfunc (builder *Builder) CyanB() *Builder {\n\treturn builder.With(CyanB)\n}\n\n// WhiteB is a syntax for WhiteB.\nfunc (builder *Builder) WhiteB() *Builder {\n\treturn builder.With(WhiteB)\n}\n\n// DefaultB is a syntax for DefaultB.\nfunc (builder *Builder) DefaultB() *Builder {\n\treturn builder.With(DefaultB)\n}\n\n// Frame is a syntax for Frame.\nfunc (builder *Builder) Frame() *Builder {\n\treturn builder.With(Frame)\n}\n\n// Encircle is a syntax for Encircle.\nfunc (builder *Builder) Encircle() *Builder {\n\treturn builder.With(Encircle)\n}\n\n// Overline is a syntax for Overline.\nfunc (builder *Builder) Overline() *Builder {\n\treturn builder.With(Overline)\n}\n\n// LightBlackF is a syntax for LightBlueF.\nfunc (builder *Builder) LightBlackF() *Builder {\n\treturn builder.With(LightBlackF)\n}\n\n// LightRedF is a syntax for LightRedF.\nfunc (builder *Builder) LightRedF() *Builder {\n\treturn builder.With(LightRedF)\n}\n\n// LightGreenF is a syntax for LightGreenF.\nfunc (builder *Builder) LightGreenF() *Builder {\n\treturn builder.With(LightGreenF)\n}\n\n// LightYellowF is a syntax for LightYellowF.\nfunc (builder *Builder) LightYellowF() *Builder {\n\treturn builder.With(LightYellowF)\n}\n\n// LightBlueF is a syntax for LightBlueF.\nfunc (builder *Builder) LightBlueF() *Builder {\n\treturn builder.With(LightBlueF)\n}\n\n// LightMagentaF is a syntax for LightMagentaF.\nfunc (builder *Builder) LightMagentaF() *Builder {\n\treturn builder.With(LightMagentaF)\n}\n\n// LightCyanF is a syntax for LightCyanF.\nfunc (builder *Builder) LightCyanF() *Builder {\n\treturn builder.With(LightCyanF)\n}\n\n// LightWhiteF is a syntax for LightWhiteF.\nfunc (builder *Builder) LightWhiteF() *Builder {\n\treturn builder.With(LightWhiteF)\n}\n\n// LightBlackB is a syntax for LightBlackB.\nfunc (builder *Builder) LightBlackB() *Builder {\n\treturn builder.With(LightBlackB)\n}\n\n// LightRedB is a syntax for LightRedB.\nfunc (builder *Builder) LightRedB() *Builder {\n\treturn builder.With(LightRedB)\n}\n\n// LightGreenB is a syntax for LightGreenB.\nfunc (builder *Builder) LightGreenB() *Builder {\n\treturn builder.With(LightGreenB)\n}\n\n// LightYellowB is a syntax for LightYellowB.\nfunc (builder *Builder) LightYellowB() *Builder {\n\treturn builder.With(LightYellowB)\n}\n\n// LightBlueB is a syntax for LightBlueB.\nfunc (builder *Builder) LightBlueB() *Builder {\n\treturn builder.With(LightBlueB)\n}\n\n// LightMagentaB is a syntax for LightMagentaB.\nfunc (builder *Builder) LightMagentaB() *Builder {\n\treturn builder.With(LightMagentaB)\n}\n\n// LightCyanB is a syntax for LightCyanB.\nfunc (builder *Builder) LightCyanB() *Builder {\n\treturn builder.With(LightCyanB)\n}\n\n// LightWhiteB is a syntax for LightWhiteB.\nfunc (builder *Builder) LightWhiteB() *Builder {\n\treturn builder.With(LightWhiteB)\n}\n\n// Color3BitF is a syntax for Color3BitF.\nfunc (builder *Builder) Color3BitF(c RGB3Bit) *Builder {\n\treturn builder.With(Color3BitF(c))\n}\n\n// Color3BitB is a syntax for Color3BitB.\nfunc (builder *Builder) Color3BitB(c RGB3Bit) *Builder {\n\treturn builder.With(Color3BitB(c))\n}\n\n// Color8BitF is a syntax for Color8BitF.\nfunc (builder *Builder) Color8BitF(c RGB8Bit) *Builder {\n\treturn builder.With(Color8BitF(c))\n}\n\n// Color8BitB is a syntax for Color8BitB.\nfunc (builder *Builder) Color8BitB(c RGB8Bit) *Builder {\n\treturn builder.With(Color8BitB(c))\n}\n\n// FullColorF is a syntax for FullColorF.\nfunc (builder *Builder) FullColorF(r, g, b uint8) *Builder {\n\treturn builder.With(FullColorF(r, g, b))\n}\n\n// FullColorB is a syntax for FullColorB.\nfunc (builder *Builder) FullColorB(r, g, b uint8) *Builder {\n\treturn builder.With(FullColorB(r, g, b))\n}\n\n// RGB3BitF is a syntax for Color3BitF with NewRGB3Bit.\nfunc (builder *Builder) RGB3BitF(r, g, b uint8) *Builder {\n\treturn builder.Color3BitF(NewRGB3Bit(r, g, b))\n}\n\n// RGB3BitB is a syntax for Color3BitB with NewRGB3Bit.\nfunc (builder *Builder) RGB3BitB(r, g, b uint8) *Builder {\n\treturn builder.Color3BitB(NewRGB3Bit(r, g, b))\n}\n\n// RGB8BitF is a syntax for Color8BitF with NewRGB8Bit.\nfunc (builder *Builder) RGB8BitF(r, g, b uint8) *Builder {\n\treturn builder.Color8BitF(NewRGB8Bit(r, g, b))\n}\n\n// RGB8BitB is a syntax for Color8BitB with NewRGB8Bit.\nfunc (builder *Builder) RGB8BitB(r, g, b uint8) *Builder {\n\treturn builder.Color8BitB(NewRGB8Bit(r, g, b))\n}\n\nfunc init() {\n\tEmptyBuilder = &Builder{empty}\n}\n"
  },
  {
    "path": "vendor/github.com/morikuni/aec/sgr.go",
    "content": "package aec\n\nimport (\n\t\"fmt\"\n)\n\n// RGB3Bit is a 3bit RGB color.\ntype RGB3Bit uint8\n\n// RGB8Bit is a 8bit RGB color.\ntype RGB8Bit uint8\n\nfunc newSGR(n uint) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"%dm\", n))\n}\n\n// NewRGB3Bit create a RGB3Bit from given RGB.\nfunc NewRGB3Bit(r, g, b uint8) RGB3Bit {\n\treturn RGB3Bit((r >> 7) | ((g >> 6) & 0x2) | ((b >> 5) & 0x4))\n}\n\n// NewRGB8Bit create a RGB8Bit from given RGB.\nfunc NewRGB8Bit(r, g, b uint8) RGB8Bit {\n\treturn RGB8Bit(16 + 36*(r/43) + 6*(g/43) + b/43)\n}\n\n// Color3BitF set the foreground color of text.\nfunc Color3BitF(c RGB3Bit) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"%dm\", c+30))\n}\n\n// Color3BitB set the background color of text.\nfunc Color3BitB(c RGB3Bit) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"%dm\", c+40))\n}\n\n// Color8BitF set the foreground color of text.\nfunc Color8BitF(c RGB8Bit) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"38;5;%dm\", c))\n}\n\n// Color8BitB set the background color of text.\nfunc Color8BitB(c RGB8Bit) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"48;5;%dm\", c))\n}\n\n// FullColorF set the foreground color of text.\nfunc FullColorF(r, g, b uint8) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"38;2;%d;%d;%dm\", r, g, b))\n}\n\n// FullColorB set the foreground color of text.\nfunc FullColorB(r, g, b uint8) ANSI {\n\treturn newAnsi(fmt.Sprintf(esc+\"48;2;%d;%d;%dm\", r, g, b))\n}\n\n// Style\nvar (\n\t// Bold set the text style to bold or increased intensity.\n\tBold ANSI\n\n\t// Faint set the text style to faint.\n\tFaint ANSI\n\n\t// Italic set the text style to italic.\n\tItalic ANSI\n\n\t// Underline set the text style to underline.\n\tUnderline ANSI\n\n\t// BlinkSlow set the text style to slow blink.\n\tBlinkSlow ANSI\n\n\t// BlinkRapid set the text style to rapid blink.\n\tBlinkRapid ANSI\n\n\t// Inverse swap the foreground color and background color.\n\tInverse ANSI\n\n\t// Conceal set the text style to conceal.\n\tConceal ANSI\n\n\t// CrossOut set the text style to crossed out.\n\tCrossOut ANSI\n\n\t// Frame set the text style to framed.\n\tFrame ANSI\n\n\t// Encircle set the text style to encircled.\n\tEncircle ANSI\n\n\t// Overline set the text style to overlined.\n\tOverline ANSI\n)\n\n// Foreground color of text.\nvar (\n\t// DefaultF is the default color of foreground.\n\tDefaultF ANSI\n\n\t// Normal color\n\tBlackF   ANSI\n\tRedF     ANSI\n\tGreenF   ANSI\n\tYellowF  ANSI\n\tBlueF    ANSI\n\tMagentaF ANSI\n\tCyanF    ANSI\n\tWhiteF   ANSI\n\n\t// Light color\n\tLightBlackF   ANSI\n\tLightRedF     ANSI\n\tLightGreenF   ANSI\n\tLightYellowF  ANSI\n\tLightBlueF    ANSI\n\tLightMagentaF ANSI\n\tLightCyanF    ANSI\n\tLightWhiteF   ANSI\n)\n\n// Background color of text.\nvar (\n\t// DefaultB is the default color of background.\n\tDefaultB ANSI\n\n\t// Normal color\n\tBlackB   ANSI\n\tRedB     ANSI\n\tGreenB   ANSI\n\tYellowB  ANSI\n\tBlueB    ANSI\n\tMagentaB ANSI\n\tCyanB    ANSI\n\tWhiteB   ANSI\n\n\t// Light color\n\tLightBlackB   ANSI\n\tLightRedB     ANSI\n\tLightGreenB   ANSI\n\tLightYellowB  ANSI\n\tLightBlueB    ANSI\n\tLightMagentaB ANSI\n\tLightCyanB    ANSI\n\tLightWhiteB   ANSI\n)\n\nfunc init() {\n\tBold = newSGR(1)\n\tFaint = newSGR(2)\n\tItalic = newSGR(3)\n\tUnderline = newSGR(4)\n\tBlinkSlow = newSGR(5)\n\tBlinkRapid = newSGR(6)\n\tInverse = newSGR(7)\n\tConceal = newSGR(8)\n\tCrossOut = newSGR(9)\n\n\tBlackF = newSGR(30)\n\tRedF = newSGR(31)\n\tGreenF = newSGR(32)\n\tYellowF = newSGR(33)\n\tBlueF = newSGR(34)\n\tMagentaF = newSGR(35)\n\tCyanF = newSGR(36)\n\tWhiteF = newSGR(37)\n\n\tDefaultF = newSGR(39)\n\n\tBlackB = newSGR(40)\n\tRedB = newSGR(41)\n\tGreenB = newSGR(42)\n\tYellowB = newSGR(43)\n\tBlueB = newSGR(44)\n\tMagentaB = newSGR(45)\n\tCyanB = newSGR(46)\n\tWhiteB = newSGR(47)\n\n\tDefaultB = newSGR(49)\n\n\tFrame = newSGR(51)\n\tEncircle = newSGR(52)\n\tOverline = newSGR(53)\n\n\tLightBlackF = newSGR(90)\n\tLightRedF = newSGR(91)\n\tLightGreenF = newSGR(92)\n\tLightYellowF = newSGR(93)\n\tLightBlueF = newSGR(94)\n\tLightMagentaF = newSGR(95)\n\tLightCyanF = newSGR(96)\n\tLightWhiteF = newSGR(97)\n\n\tLightBlackB = newSGR(100)\n\tLightRedB = newSGR(101)\n\tLightGreenB = newSGR(102)\n\tLightYellowB = newSGR(103)\n\tLightBlueB = newSGR(104)\n\tLightMagentaB = newSGR(105)\n\tLightCyanB = newSGR(106)\n\tLightWhiteB = newSGR(107)\n}\n"
  },
  {
    "path": "vendor/github.com/munnerz/goautoneg/LICENSE",
    "content": "Copyright (c) 2011, Open Knowledge Foundation Ltd.\nAll 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    Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in\n    the documentation and/or other materials provided with the\n    distribution.\n\n    Neither the name of the Open Knowledge Foundation Ltd. nor the\n    names of its contributors may be used to endorse or promote\n    products derived from this software without specific prior written\n    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\nHOLDER 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": "vendor/github.com/munnerz/goautoneg/Makefile",
    "content": "include $(GOROOT)/src/Make.inc\n\nTARG=bitbucket.org/ww/goautoneg\nGOFILES=autoneg.go\n\ninclude $(GOROOT)/src/Make.pkg\n\nformat:\n\tgofmt -w *.go\n\ndocs:\n\tgomake clean\n\tgodoc ${TARG} > README.txt\n"
  },
  {
    "path": "vendor/github.com/munnerz/goautoneg/README.txt",
    "content": "PACKAGE\n\npackage goautoneg\nimport \"bitbucket.org/ww/goautoneg\"\n\nHTTP Content-Type Autonegotiation.\n\nThe functions in this package implement the behaviour specified in\nhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html\n\nCopyright (c) 2011, Open Knowledge Foundation Ltd.\nAll 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    Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in\n    the documentation and/or other materials provided with the\n    distribution.\n\n    Neither the name of the Open Knowledge Foundation Ltd. nor the\n    names of its contributors may be used to endorse or promote\n    products derived from this software without specific prior written\n    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\nHOLDER 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\n\nFUNCTIONS\n\nfunc Negotiate(header string, alternatives []string) (content_type string)\nNegotiate the most appropriate content_type given the accept header\nand a list of alternatives.\n\nfunc ParseAccept(header string) (accept []Accept)\nParse an Accept Header string returning a sorted list\nof clauses\n\n\nTYPES\n\ntype Accept struct {\n    Type, SubType string\n    Q             float32\n    Params        map[string]string\n}\nStructure to represent a clause in an HTTP Accept Header\n\n\nSUBDIRECTORIES\n\n\t.hg\n"
  },
  {
    "path": "vendor/github.com/munnerz/goautoneg/autoneg.go",
    "content": "/*\nHTTP Content-Type Autonegotiation.\n\nThe functions in this package implement the behaviour specified in\nhttp://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html\n\nCopyright (c) 2011, Open Knowledge Foundation Ltd.\nAll 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    Redistributions of source code must retain the above copyright\n    notice, this list of conditions and the following disclaimer.\n\n    Redistributions in binary form must reproduce the above copyright\n    notice, this list of conditions and the following disclaimer in\n    the documentation and/or other materials provided with the\n    distribution.\n\n    Neither the name of the Open Knowledge Foundation Ltd. nor the\n    names of its contributors may be used to endorse or promote\n    products derived from this software without specific prior written\n    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\nHOLDER 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*/\n\npackage goautoneg\n\nimport (\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Structure to represent a clause in an HTTP Accept Header\ntype Accept struct {\n\tType, SubType string\n\tQ             float64\n\tParams        map[string]string\n}\n\n// acceptSlice is defined to implement sort interface.\ntype acceptSlice []Accept\n\nfunc (slice acceptSlice) Len() int {\n\treturn len(slice)\n}\n\nfunc (slice acceptSlice) Less(i, j int) bool {\n\tai, aj := slice[i], slice[j]\n\tif ai.Q > aj.Q {\n\t\treturn true\n\t}\n\tif ai.Type != \"*\" && aj.Type == \"*\" {\n\t\treturn true\n\t}\n\tif ai.SubType != \"*\" && aj.SubType == \"*\" {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (slice acceptSlice) Swap(i, j int) {\n\tslice[i], slice[j] = slice[j], slice[i]\n}\n\nfunc stringTrimSpaceCutset(r rune) bool {\n\treturn r == ' '\n}\n\nfunc nextSplitElement(s, sep string) (item string, remaining string) {\n\tif index := strings.Index(s, sep); index != -1 {\n\t\treturn s[:index], s[index+1:]\n\t}\n\treturn s, \"\"\n}\n\n// Parse an Accept Header string returning a sorted list\n// of clauses\nfunc ParseAccept(header string) acceptSlice {\n\tpartsCount := 0\n\tremaining := header\n\tfor len(remaining) > 0 {\n\t\tpartsCount++\n\t\t_, remaining = nextSplitElement(remaining, \",\")\n\t}\n\taccept := make(acceptSlice, 0, partsCount)\n\n\tremaining = header\n\tvar part string\n\tfor len(remaining) > 0 {\n\t\tpart, remaining = nextSplitElement(remaining, \",\")\n\t\tpart = strings.TrimFunc(part, stringTrimSpaceCutset)\n\n\t\ta := Accept{\n\t\t\tQ: 1.0,\n\t\t}\n\n\t\tsp, remainingPart := nextSplitElement(part, \";\")\n\n\t\tsp0, spRemaining := nextSplitElement(sp, \"/\")\n\t\ta.Type = strings.TrimFunc(sp0, stringTrimSpaceCutset)\n\n\t\tswitch {\n\t\tcase len(spRemaining) == 0:\n\t\t\tif a.Type == \"*\" {\n\t\t\t\ta.SubType = \"*\"\n\t\t\t} else {\n\t\t\t\tcontinue\n\t\t\t}\n\t\tdefault:\n\t\t\tvar sp1 string\n\t\t\tsp1, spRemaining = nextSplitElement(spRemaining, \"/\")\n\t\t\tif len(spRemaining) > 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ta.SubType = strings.TrimFunc(sp1, stringTrimSpaceCutset)\n\t\t}\n\n\t\tif len(remainingPart) == 0 {\n\t\t\taccept = append(accept, a)\n\t\t\tcontinue\n\t\t}\n\n\t\ta.Params = make(map[string]string)\n\t\tfor len(remainingPart) > 0 {\n\t\t\tsp, remainingPart = nextSplitElement(remainingPart, \";\")\n\t\t\tsp0, spRemaining = nextSplitElement(sp, \"=\")\n\t\t\tif len(spRemaining) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvar sp1 string\n\t\t\tsp1, spRemaining = nextSplitElement(spRemaining, \"=\")\n\t\t\tif len(spRemaining) != 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttoken := strings.TrimFunc(sp0, stringTrimSpaceCutset)\n\t\t\tif token == \"q\" {\n\t\t\t\ta.Q, _ = strconv.ParseFloat(sp1, 32)\n\t\t\t} else {\n\t\t\t\ta.Params[token] = strings.TrimFunc(sp1, stringTrimSpaceCutset)\n\t\t\t}\n\t\t}\n\n\t\taccept = append(accept, a)\n\t}\n\n\tsort.Sort(accept)\n\treturn accept\n}\n\n// Negotiate the most appropriate content_type given the accept header\n// and a list of alternatives.\nfunc Negotiate(header string, alternatives []string) (content_type string) {\n\tasp := make([][]string, 0, len(alternatives))\n\tfor _, ctype := range alternatives {\n\t\tasp = append(asp, strings.SplitN(ctype, \"/\", 2))\n\t}\n\tfor _, clause := range ParseAccept(header) {\n\t\tfor i, ctsp := range asp {\n\t\t\tif clause.Type == ctsp[0] && clause.SubType == ctsp[1] {\n\t\t\t\tcontent_type = alternatives[i]\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif clause.Type == ctsp[0] && clause.SubType == \"*\" {\n\t\t\t\tcontent_type = alternatives[i]\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif clause.Type == \"*\" && clause.SubType == \"*\" {\n\t\t\t\tcontent_type = alternatives[i]\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml/.gitignore",
    "content": "# OSX leaves these everywhere on SMB shares\n._*\n\n# Eclipse files\n.classpath\n.project\n.settings/**\n\n# Emacs save files\n*~\n\n# Vim-related files\n[._]*.s[a-w][a-z]\n[._]s[a-w][a-z]\n*.un~\nSession.vim\n.netrwhist\n\n# Go test binaries\n*.test\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml/.golangci.toml",
    "content": "[run]\ntimeout = \"120s\"\n\n[output]\nformat = \"colored-line-number\"\n\n[linters]\nenable = [\n    \"gocyclo\", \"unconvert\", \"goimports\", \"unused\", \"unused\",\n    \"vetshadow\", \"nakedret\", \"errcheck\", \"revive\", \"ineffassign\",\n    \"goconst\", \"vet\", \"unparam\", \"gofmt\"\n]\n\n[issues]\nexclude-use-default = false\n\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Sam Ghods\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\n\nCopyright (c) 2012 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/oasdiff/yaml/README.md",
    "content": "# YAML marshaling and unmarshaling support for Go\n\n[![Lint](https://github.com/invopop/yaml/actions/workflows/lint.yaml/badge.svg)](https://github.com/invopop/yaml/actions/workflows/lint.yaml)\n[![Test Go](https://github.com/invopop/yaml/actions/workflows/test.yaml/badge.svg)](https://github.com/invopop/yaml/actions/workflows/test.yaml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/invopop/yaml)](https://goreportcard.com/report/github.com/invopop/yaml)\n![Latest Tag](https://img.shields.io/github/v/tag/invopop/yaml)\n\n## Fork\nThis fork is an improved version of the invopop/yaml package, designed to include line and column location information for YAML elements during unmarshalling.  \nTo include location information use ```UnmarshalWithOrigin``` instead of ```Unmarshal```.  \nThe heavy lifting is done by the underlying [oasdiff/yaml3](https://github.com/oasdiff/yaml3) package.\n\n## Introduction\n\nA wrapper around [go-yaml](https://github.com/go-yaml/yaml) designed to enable a better way of handling YAML when marshaling to and from structs.\n\nThis is a fork and split of the original [ghodss/yaml](https://github.com/ghodss/yaml) repository which no longer appears to be maintained.\n\nIn short, this library first converts YAML to JSON using go-yaml and then uses `json.Marshal` and `json.Unmarshal` to convert to or from the struct. This means that it effectively reuses the JSON struct tags as well as the custom JSON methods `MarshalJSON` and `UnmarshalJSON` unlike go-yaml. For a detailed overview of the rationale behind this method, [see this blog post](https://web.archive.org/web/20150812020634/http://ghodss.com/2014/the-right-way-to-handle-yaml-in-golang/).\n\n## Compatibility\n\nThis package uses [go-yaml](https://github.com/go-yaml/yaml) and therefore supports [everything go-yaml supports](https://github.com/go-yaml/yaml#compatibility).\n\nTested against Go versions 1.14 and onwards.\n\n## Caveats\n\n**Caveat #1:** When using `yaml.Marshal` and `yaml.Unmarshal`, binary data should NOT be preceded with the `!!binary` YAML tag. If you do, go-yaml will convert the binary data from base64 to native binary data, which is not compatible with JSON. You can still use binary in your YAML files though - just store them without the `!!binary` tag and decode the base64 in your code (e.g. in the custom JSON methods `MarshalJSON` and `UnmarshalJSON`). This also has the benefit that your YAML and your JSON binary data will be decoded exactly the same way. As an example:\n\n```\nBAD:\n\texampleKey: !!binary gIGC\n\nGOOD:\n\texampleKey: gIGC\n... and decode the base64 data in your code.\n```\n\n**Caveat #2:** When using `YAMLToJSON` directly, maps with keys that are maps will result in an error since this is not supported by JSON. This error will occur in `Unmarshal` as well since you can't unmarshal map keys anyways since struct fields can't be keys.\n\n## Installation and usage\n\nTo install, run:\n\n```\n$ go get github.com/invopop/yaml\n```\n\nAnd import using:\n\n```\nimport \"github.com/invopop/yaml\"\n```\n\nUsage is very similar to the JSON library:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/invopop/yaml\"\n)\n\ntype Person struct {\n\tName string `json:\"name\"` // Affects YAML field names too.\n\tAge  int    `json:\"age\"`\n}\n\nfunc main() {\n\t// Marshal a Person struct to YAML.\n\tp := Person{\"John\", 30}\n\ty, err := yaml.Marshal(p)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(string(y))\n\t/* Output:\n\tage: 30\n\tname: John\n\t*/\n\n\t// Unmarshal the YAML back into a Person struct.\n\tvar p2 Person\n\terr = yaml.Unmarshal(y, &p2)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(p2)\n\t/* Output:\n\t{John 30}\n\t*/\n}\n```\n\n`yaml.YAMLToJSON` and `yaml.JSONToYAML` methods are also available:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/invopop/yaml\"\n)\n\nfunc main() {\n\tj := []byte(`{\"name\": \"John\", \"age\": 30}`)\n\ty, err := yaml.JSONToYAML(j)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(string(y))\n\t/* Output:\n\tname: John\n\tage: 30\n\t*/\n\tj2, err := yaml.YAMLToJSON(y)\n\tif err != nil {\n\t\tfmt.Printf(\"err: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Println(string(j2))\n\t/* Output:\n\t{\"age\":30,\"name\":\"John\"}\n\t*/\n}\n```\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml/fields.go",
    "content": "// Copyright 2013 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 yaml\n\nimport (\n\t\"bytes\"\n\t\"encoding\"\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\n// indirect walks down v allocating pointers as needed,\n// until it gets to a non-pointer.\n// if it encounters an Unmarshaler, indirect stops and returns that.\n// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.\nfunc indirect(v reflect.Value, decodingNull bool) (json.Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {\n\t// If v is a named type and is addressable,\n\t// start with its address, so that if the type has pointer methods,\n\t// we find them.\n\tif v.Kind() != reflect.Ptr && v.Type().Name() != \"\" && v.CanAddr() {\n\t\tv = v.Addr()\n\t}\n\tfor {\n\t\t// Load value from interface, but only if the result will be\n\t\t// usefully addressable.\n\t\tif v.Kind() == reflect.Interface && !v.IsNil() {\n\t\t\te := v.Elem()\n\t\t\tif e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {\n\t\t\t\tv = e\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif v.Kind() != reflect.Ptr {\n\t\t\tbreak\n\t\t}\n\n\t\tif v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {\n\t\t\tbreak\n\t\t}\n\t\tif v.IsNil() {\n\t\t\tif v.CanSet() {\n\t\t\t\tv.Set(reflect.New(v.Type().Elem()))\n\t\t\t} else {\n\t\t\t\tv = reflect.New(v.Type().Elem())\n\t\t\t}\n\t\t}\n\t\tif v.Type().NumMethod() > 0 {\n\t\t\tif u, ok := v.Interface().(json.Unmarshaler); ok {\n\t\t\t\treturn u, nil, reflect.Value{}\n\t\t\t}\n\t\t\tif u, ok := v.Interface().(encoding.TextUnmarshaler); ok {\n\t\t\t\treturn nil, u, reflect.Value{}\n\t\t\t}\n\t\t}\n\t\tv = v.Elem()\n\t}\n\treturn nil, nil, v\n}\n\n// A field represents a single field found in a struct.\ntype field struct {\n\tname      string\n\tnameBytes []byte                 // []byte(name)\n\tequalFold func(s, t []byte) bool // bytes.EqualFold or equivalent\n\n\ttag       bool\n\tindex     []int\n\ttyp       reflect.Type\n\tomitEmpty bool\n\tquoted    bool\n}\n\nfunc fillField(f field) field {\n\tf.nameBytes = []byte(f.name)\n\tf.equalFold = foldFunc(f.nameBytes)\n\treturn f\n}\n\n// byName sorts field by name, breaking ties with depth,\n// then breaking ties with \"name came from json tag\", then\n// breaking ties with index sequence.\ntype byName []field\n\nfunc (x byName) Len() int { return len(x) }\n\nfunc (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byName) Less(i, j int) bool {\n\tif x[i].name != x[j].name {\n\t\treturn x[i].name < x[j].name\n\t}\n\tif len(x[i].index) != len(x[j].index) {\n\t\treturn len(x[i].index) < len(x[j].index)\n\t}\n\tif x[i].tag != x[j].tag {\n\t\treturn x[i].tag\n\t}\n\treturn byIndex(x).Less(i, j)\n}\n\n// byIndex sorts field by index sequence.\ntype byIndex []field\n\nfunc (x byIndex) Len() int { return len(x) }\n\nfunc (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }\n\nfunc (x byIndex) Less(i, j int) bool {\n\tfor k, xik := range x[i].index {\n\t\tif k >= len(x[j].index) {\n\t\t\treturn false\n\t\t}\n\t\tif xik != x[j].index[k] {\n\t\t\treturn xik < x[j].index[k]\n\t\t}\n\t}\n\treturn len(x[i].index) < len(x[j].index)\n}\n\n// typeFields returns a list of fields that JSON should recognize for the given type.\n// The algorithm is breadth-first search over the set of structs to include - the top struct\n// and then any reachable anonymous structs.\nfunc typeFields(t reflect.Type) []field {\n\t// Anonymous fields to explore at the current level and the next.\n\tcurrent := []field{}\n\tnext := []field{{typ: t}}\n\n\t// Count of queued names for current level and the next.\n\tvar count, nextCount map[reflect.Type]int\n\n\t// Types already visited at an earlier level.\n\tvisited := map[reflect.Type]bool{}\n\n\t// Fields found.\n\tvar fields []field\n\n\tfor len(next) > 0 {\n\t\tcurrent, next = next, current[:0]\n\t\tcount, nextCount = nextCount, map[reflect.Type]int{}\n\n\t\tfor _, f := range current {\n\t\t\tif visited[f.typ] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tvisited[f.typ] = true\n\n\t\t\t// Scan f.typ for fields to include.\n\t\t\tfor i := 0; i < f.typ.NumField(); i++ {\n\t\t\t\tsf := f.typ.Field(i)\n\t\t\t\tif sf.PkgPath != \"\" { // unexported\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\ttag := sf.Tag.Get(\"json\")\n\t\t\t\tif tag == \"-\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tname, opts := parseTag(tag)\n\t\t\t\tif !isValidTag(name) {\n\t\t\t\t\tname = \"\"\n\t\t\t\t}\n\t\t\t\tindex := make([]int, len(f.index)+1)\n\t\t\t\tcopy(index, f.index)\n\t\t\t\tindex[len(f.index)] = i\n\n\t\t\t\tft := sf.Type\n\t\t\t\tif ft.Name() == \"\" && ft.Kind() == reflect.Ptr {\n\t\t\t\t\t// Follow pointer.\n\t\t\t\t\tft = ft.Elem()\n\t\t\t\t}\n\n\t\t\t\t// Record found field and index sequence.\n\t\t\t\tif name != \"\" || !sf.Anonymous || ft.Kind() != reflect.Struct {\n\t\t\t\t\ttagged := name != \"\"\n\t\t\t\t\tif name == \"\" {\n\t\t\t\t\t\tname = sf.Name\n\t\t\t\t\t}\n\t\t\t\t\tfields = append(fields, fillField(field{\n\t\t\t\t\t\tname:      name,\n\t\t\t\t\t\ttag:       tagged,\n\t\t\t\t\t\tindex:     index,\n\t\t\t\t\t\ttyp:       ft,\n\t\t\t\t\t\tomitEmpty: opts.Contains(\"omitempty\"),\n\t\t\t\t\t\tquoted:    opts.Contains(\"string\"),\n\t\t\t\t\t}))\n\t\t\t\t\tif count[f.typ] > 1 {\n\t\t\t\t\t\t// If there were multiple instances, add a second,\n\t\t\t\t\t\t// so that the annihilation code will see a duplicate.\n\t\t\t\t\t\t// It only cares about the distinction between 1 or 2,\n\t\t\t\t\t\t// so don't bother generating any more copies.\n\t\t\t\t\t\tfields = append(fields, fields[len(fields)-1])\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Record new anonymous struct to explore in next round.\n\t\t\t\tnextCount[ft]++\n\t\t\t\tif nextCount[ft] == 1 {\n\t\t\t\t\tnext = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tsort.Sort(byName(fields))\n\n\t// Delete all fields that are hidden by the Go rules for embedded fields,\n\t// except that fields with JSON tags are promoted.\n\n\t// The fields are sorted in primary order of name, secondary order\n\t// of field index length. Loop over names; for each name, delete\n\t// hidden fields by choosing the one dominant field that survives.\n\tout := fields[:0]\n\tfor advance, i := 0, 0; i < len(fields); i += advance {\n\t\t// One iteration per name.\n\t\t// Find the sequence of fields with the name of this first field.\n\t\tfi := fields[i]\n\t\tname := fi.name\n\t\tfor advance = 1; i+advance < len(fields); advance++ {\n\t\t\tfj := fields[i+advance]\n\t\t\tif fj.name != name {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif advance == 1 { // Only one field with this name\n\t\t\tout = append(out, fi)\n\t\t\tcontinue\n\t\t}\n\t\tdominant, ok := dominantField(fields[i : i+advance])\n\t\tif ok {\n\t\t\tout = append(out, dominant)\n\t\t}\n\t}\n\n\tfields = out\n\tsort.Sort(byIndex(fields))\n\n\treturn fields\n}\n\n// dominantField looks through the fields, all of which are known to\n// have the same name, to find the single field that dominates the\n// others using Go's embedding rules, modified by the presence of\n// JSON tags. If there are multiple top-level fields, the boolean\n// will be false: This condition is an error in Go and we skip all\n// the fields.\nfunc dominantField(fields []field) (field, bool) {\n\t// The fields are sorted in increasing index-length order. The winner\n\t// must therefore be one with the shortest index length. Drop all\n\t// longer entries, which is easy: just truncate the slice.\n\tlength := len(fields[0].index)\n\ttagged := -1 // Index of first tagged field.\n\tfor i, f := range fields {\n\t\tif len(f.index) > length {\n\t\t\tfields = fields[:i]\n\t\t\tbreak\n\t\t}\n\t\tif f.tag {\n\t\t\tif tagged >= 0 {\n\t\t\t\t// Multiple tagged fields at the same level: conflict.\n\t\t\t\t// Return no field.\n\t\t\t\treturn field{}, false\n\t\t\t}\n\t\t\ttagged = i\n\t\t}\n\t}\n\tif tagged >= 0 {\n\t\treturn fields[tagged], true\n\t}\n\t// All remaining fields have the same length. If there's more than one,\n\t// we have a conflict (two fields named \"X\" at the same level) and we\n\t// return no field.\n\tif len(fields) > 1 {\n\t\treturn field{}, false\n\t}\n\treturn fields[0], true\n}\n\nvar fieldCache struct {\n\tsync.RWMutex\n\tm map[reflect.Type][]field\n}\n\n// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.\nfunc cachedTypeFields(t reflect.Type) []field {\n\tfieldCache.RLock()\n\tf := fieldCache.m[t]\n\tfieldCache.RUnlock()\n\tif f != nil {\n\t\treturn f\n\t}\n\n\t// Compute fields without lock.\n\t// Might duplicate effort but won't hold other computations back.\n\tf = typeFields(t)\n\tif f == nil {\n\t\tf = []field{}\n\t}\n\n\tfieldCache.Lock()\n\tif fieldCache.m == nil {\n\t\tfieldCache.m = map[reflect.Type][]field{}\n\t}\n\tfieldCache.m[t] = f\n\tfieldCache.Unlock()\n\treturn f\n}\n\nfunc isValidTag(s string) bool {\n\tif s == \"\" {\n\t\treturn false\n\t}\n\tfor _, c := range s {\n\t\tswitch {\n\t\tcase strings.ContainsRune(\"!#$%&()*+-./:<=>?@[]^_{|}~ \", c):\n\t\t\t// Backslash and quote chars are reserved, but\n\t\t\t// otherwise any punctuation chars are allowed\n\t\t\t// in a tag name.\n\t\tdefault:\n\t\t\tif !unicode.IsLetter(c) && !unicode.IsDigit(c) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nconst (\n\tcaseMask     = ^byte(0x20) // Mask to ignore case in ASCII.\n\tkelvin       = '\\u212a'\n\tsmallLongEss = '\\u017f'\n)\n\n// foldFunc returns one of four different case folding equivalence\n// functions, from most general (and slow) to fastest:\n//\n// 1) bytes.EqualFold, if the key s contains any non-ASCII UTF-8\n// 2) equalFoldRight, if s contains special folding ASCII ('k', 'K', 's', 'S')\n// 3) asciiEqualFold, no special, but includes non-letters (including _)\n// 4) simpleLetterEqualFold, no specials, no non-letters.\n//\n// The letters S and K are special because they map to 3 runes, not just 2:\n//   - S maps to s and to U+017F 'ſ' Latin small letter long s\n//   - k maps to K and to U+212A 'K' Kelvin sign\n//\n// See http://play.golang.org/p/tTxjOc0OGo\n//\n// The returned function is specialized for matching against s and\n// should only be given s. It's not curried for performance reasons.\nfunc foldFunc(s []byte) func(s, t []byte) bool {\n\tnonLetter := false\n\tspecial := false // special letter\n\tfor _, b := range s {\n\t\tif b >= utf8.RuneSelf {\n\t\t\treturn bytes.EqualFold\n\t\t}\n\t\tupper := b & caseMask\n\t\tif upper < 'A' || upper > 'Z' {\n\t\t\tnonLetter = true\n\t\t} else if upper == 'K' || upper == 'S' {\n\t\t\t// See above for why these letters are special.\n\t\t\tspecial = true\n\t\t}\n\t}\n\tif special {\n\t\treturn equalFoldRight\n\t}\n\tif nonLetter {\n\t\treturn asciiEqualFold\n\t}\n\treturn simpleLetterEqualFold\n}\n\n// equalFoldRight is a specialization of bytes.EqualFold when s is\n// known to be all ASCII (including punctuation), but contains an 's',\n// 'S', 'k', or 'K', requiring a Unicode fold on the bytes in t.\n// See comments on foldFunc.\nfunc equalFoldRight(s, t []byte) bool {\n\tfor _, sb := range s {\n\t\tif len(t) == 0 {\n\t\t\treturn false\n\t\t}\n\t\ttb := t[0]\n\t\tif tb < utf8.RuneSelf {\n\t\t\tif sb != tb {\n\t\t\t\tsbUpper := sb & caseMask\n\t\t\t\tif 'A' <= sbUpper && sbUpper <= 'Z' {\n\t\t\t\t\tif sbUpper != tb&caseMask {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tt = t[1:]\n\t\t\tcontinue\n\t\t}\n\t\t// sb is ASCII and t is not. t must be either kelvin\n\t\t// sign or long s; sb must be s, S, k, or K.\n\t\ttr, size := utf8.DecodeRune(t)\n\t\tswitch sb {\n\t\tcase 's', 'S':\n\t\t\tif tr != smallLongEss {\n\t\t\t\treturn false\n\t\t\t}\n\t\tcase 'k', 'K':\n\t\t\tif tr != kelvin {\n\t\t\t\treturn false\n\t\t\t}\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t\tt = t[size:]\n\n\t}\n\treturn len(t) <= 0\n}\n\n// asciiEqualFold is a specialization of bytes.EqualFold for use when\n// s is all ASCII (but may contain non-letters) and contains no\n// special-folding letters.\n// See comments on foldFunc.\nfunc asciiEqualFold(s, t []byte) bool {\n\tif len(s) != len(t) {\n\t\treturn false\n\t}\n\tfor i, sb := range s {\n\t\ttb := t[i]\n\t\tif sb == tb {\n\t\t\tcontinue\n\t\t}\n\t\tif ('a' <= sb && sb <= 'z') || ('A' <= sb && sb <= 'Z') {\n\t\t\tif sb&caseMask != tb&caseMask {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// simpleLetterEqualFold is a specialization of bytes.EqualFold for\n// use when s is all ASCII letters (no underscores, etc) and also\n// doesn't contain 'k', 'K', 's', or 'S'.\n// See comments on foldFunc.\nfunc simpleLetterEqualFold(s, t []byte) bool {\n\tif len(s) != len(t) {\n\t\treturn false\n\t}\n\tfor i, b := range s {\n\t\tif b&caseMask != t[i]&caseMask {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// tagOptions is the string following a comma in a struct field's \"json\"\n// tag, or the empty string. It does not include the leading comma.\ntype tagOptions string\n\n// parseTag splits a struct field's json tag into its name and\n// comma-separated options.\nfunc parseTag(tag string) (string, tagOptions) {\n\tif idx := strings.Index(tag, \",\"); idx != -1 {\n\t\treturn tag[:idx], tagOptions(tag[idx+1:])\n\t}\n\treturn tag, tagOptions(\"\")\n}\n\n// Contains reports whether a comma-separated list of options\n// contains a particular substr flag. substr must be surrounded by a\n// string boundary or commas.\nfunc (o tagOptions) Contains(optionName string) bool {\n\tif len(o) == 0 {\n\t\treturn false\n\t}\n\ts := string(o)\n\tfor s != \"\" {\n\t\tvar next string\n\t\ti := strings.Index(s, \",\")\n\t\tif i >= 0 {\n\t\t\ts, next = s[:i], s[i+1:]\n\t\t}\n\t\tif s == optionName {\n\t\t\treturn true\n\t\t}\n\t\ts = next\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml/yaml.go",
    "content": "// Package yaml provides a wrapper around go-yaml designed to enable a better\n// way of handling YAML when marshaling to and from structs.\n//\n// In short, this package first converts YAML to JSON using go-yaml and then\n// uses json.Marshal and json.Unmarshal to convert to or from the struct. This\n// means that it effectively reuses the JSON struct tags as well as the custom\n// JSON methods MarshalJSON and UnmarshalJSON unlike go-yaml.\npackage yaml // import \"github.com/invopop/yaml\"\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strconv\"\n\n\t\"github.com/oasdiff/yaml3\"\n)\n\n// Marshal the object into JSON then converts JSON to YAML and returns the\n// YAML.\nfunc Marshal(o interface{}) ([]byte, error) {\n\tj, err := json.Marshal(o)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error marshaling into JSON: %v\", err)\n\t}\n\n\ty, err := JSONToYAML(j)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error converting JSON to YAML: %v\", err)\n\t}\n\n\treturn y, nil\n}\n\n// JSONOpt is a decoding option for decoding from JSON format.\ntype JSONOpt func(*json.Decoder) *json.Decoder\n\n// YAMLOpt is a decoding option for decoding from YAML format.\ntype YAMLOpt func(*yaml.Decoder) *yaml.Decoder\n\n// Unmarshal converts YAML to JSON then uses JSON to unmarshal into an object,\n// optionally configuring the behavior of the JSON unmarshal.\nfunc Unmarshal(y []byte, o interface{}, opts ...JSONOpt) error {\n\treturn UnmarshalWithOrigin(y, o, false, opts...)\n}\n\n// UnmarshalWithOrigin is like Unmarshal but if withOrigin is true, it will\n// include the origin information in the output.\nfunc UnmarshalWithOrigin(y []byte, o interface{}, withOrigin bool, opts ...JSONOpt) error {\n\tdec := yaml.NewDecoder(bytes.NewReader(y))\n\tdec.Origin(withOrigin)\n\treturn unmarshal(dec, o, opts)\n}\n\nfunc unmarshal(dec *yaml.Decoder, o interface{}, opts []JSONOpt) error {\n\tvo := reflect.ValueOf(o)\n\tj, err := yamlToJSON(dec, &vo)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error converting YAML to JSON: %v\", err)\n\t}\n\n\terr = jsonUnmarshal(bytes.NewReader(j), o, opts...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error unmarshaling JSON: %v\", err)\n\t}\n\n\treturn nil\n}\n\n// jsonUnmarshal unmarshals the JSON byte stream from the given reader into the\n// object, optionally applying decoder options prior to decoding.  We are not\n// using json.Unmarshal directly as we want the chance to pass in non-default\n// options.\nfunc jsonUnmarshal(r io.Reader, o interface{}, opts ...JSONOpt) error {\n\td := json.NewDecoder(r)\n\tfor _, opt := range opts {\n\t\td = opt(d)\n\t}\n\tif err := d.Decode(&o); err != nil {\n\t\treturn fmt.Errorf(\"while decoding JSON: %v\", err)\n\t}\n\treturn nil\n}\n\n// JSONToYAML converts JSON to YAML.\nfunc JSONToYAML(j []byte) ([]byte, error) {\n\t// Convert the JSON to an object.\n\tvar jsonObj interface{}\n\t// We are using yaml.Unmarshal here (instead of json.Unmarshal) because the\n\t// Go JSON library doesn't try to pick the right number type (int, float,\n\t// etc.) when unmarshalling to interface{}, it just picks float64\n\t// universally. go-yaml does go through the effort of picking the right\n\t// number type, so we can preserve number type throughout this process.\n\terr := yaml.Unmarshal(j, &jsonObj)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Marshal this object into YAML.\n\treturn yaml.Marshal(jsonObj)\n}\n\n// YAMLToJSON converts YAML to JSON. Since JSON is a subset of YAML,\n// passing JSON through this method should be a no-op.\n//\n// Things YAML can do that are not supported by JSON:\n//   - In YAML you can have binary and null keys in your maps. These are invalid\n//     in JSON. (int and float keys are converted to strings.)\n//   - Binary data in YAML with the !!binary tag is not supported. If you want to\n//     use binary data with this library, encode the data as base64 as usual but do\n//     not use the !!binary tag in your YAML. This will ensure the original base64\n//     encoded data makes it all the way through to the JSON.\nfunc YAMLToJSON(y []byte) ([]byte, error) { //nolint:revive\n\tdec := yaml.NewDecoder(bytes.NewReader(y))\n\treturn yamlToJSON(dec, nil)\n}\n\nfunc yamlToJSON(dec *yaml.Decoder, jsonTarget *reflect.Value) ([]byte, error) {\n\t// Convert the YAML to an object.\n\tvar yamlObj interface{}\n\tif err := dec.Decode(&yamlObj); err != nil {\n\t\t// Functionality changed in v3 which means we need to ignore EOF error.\n\t\t// See https://github.com/go-yaml/yaml/issues/639\n\t\tif !errors.Is(err, io.EOF) {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\t// YAML objects are not completely compatible with JSON objects (e.g. you\n\t// can have non-string keys in YAML). So, convert the YAML-compatible object\n\t// to a JSON-compatible object, failing with an error if irrecoverable\n\t// incompatibilities happen along the way.\n\tjsonObj, err := convertToJSONableObject(yamlObj, jsonTarget)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Convert this object to JSON and return the data.\n\treturn json.Marshal(jsonObj)\n}\n\nfunc convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (interface{}, error) { //nolint:gocyclo\n\tvar err error\n\n\t// Resolve jsonTarget to a concrete value (i.e. not a pointer or an\n\t// interface). We pass decodingNull as false because we're not actually\n\t// decoding into the value, we're just checking if the ultimate target is a\n\t// string.\n\tif jsonTarget != nil {\n\t\tju, tu, pv := indirect(*jsonTarget, false)\n\t\t// We have a JSON or Text Umarshaler at this level, so we can't be trying\n\t\t// to decode into a string.\n\t\tif ju != nil || tu != nil {\n\t\t\tjsonTarget = nil\n\t\t} else {\n\t\t\tjsonTarget = &pv\n\t\t}\n\t}\n\n\t// go-yaml v3 changed from v2 and now will provide map[string]interface{} by\n\t// default and map[interface{}]interface{} when none of the keys strings.\n\t// To get around this, we run a pre-loop to convert the map.\n\t// JSON only supports strings as keys, so we must convert.\n\n\tswitch typedYAMLObj := yamlObj.(type) {\n\tcase map[interface{}]interface{}:\n\t\t// From my reading of go-yaml v2 (specifically the resolve function),\n\t\t// keys can only have the types string, int, int64, float64, binary\n\t\t// (unsupported), or null (unsupported).\n\t\tstrMap := make(map[string]interface{})\n\t\tfor k, v := range typedYAMLObj {\n\t\t\t// Resolve the key to a string first.\n\t\t\tvar keyString string\n\t\t\tswitch typedKey := k.(type) {\n\t\t\tcase string:\n\t\t\t\tkeyString = typedKey\n\t\t\tcase int:\n\t\t\t\tkeyString = strconv.Itoa(typedKey)\n\t\t\tcase int64:\n\t\t\t\t// go-yaml will only return an int64 as a key if the system\n\t\t\t\t// architecture is 32-bit and the key's value is between 32-bit\n\t\t\t\t// and 64-bit. Otherwise the key type will simply be int.\n\t\t\t\tkeyString = strconv.FormatInt(typedKey, 10)\n\t\t\tcase float64:\n\t\t\t\t// Float64 is now supported in keys\n\t\t\t\tkeyString = strconv.FormatFloat(typedKey, 'g', -1, 64)\n\t\t\tcase bool:\n\t\t\t\tif typedKey {\n\t\t\t\t\tkeyString = \"true\"\n\t\t\t\t} else {\n\t\t\t\t\tkeyString = \"false\"\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"unsupported map key of type: %s, key: %+#v, value: %+#v\",\n\t\t\t\t\treflect.TypeOf(k), k, v)\n\t\t\t}\n\t\t\tstrMap[keyString] = v\n\t\t}\n\t\t// replace yamlObj with our new string map\n\t\tyamlObj = strMap\n\t}\n\n\t// If yamlObj is a number or a boolean, check if jsonTarget is a string -\n\t// if so, coerce.  Else return normal.\n\t// If yamlObj is a map or array, find the field that each key is\n\t// unmarshaling to, and when you recurse pass the reflect.Value for that\n\t// field back into this function.\n\tswitch typedYAMLObj := yamlObj.(type) {\n\tcase map[string]interface{}:\n\t\tfor k, v := range typedYAMLObj {\n\n\t\t\t// jsonTarget should be a struct or a map. If it's a struct, find\n\t\t\t// the field it's going to map to and pass its reflect.Value. If\n\t\t\t// it's a map, find the element type of the map and pass the\n\t\t\t// reflect.Value created from that type. If it's neither, just pass\n\t\t\t// nil - JSON conversion will error for us if it's a real issue.\n\t\t\tif jsonTarget != nil {\n\t\t\t\tt := *jsonTarget\n\t\t\t\tif t.Kind() == reflect.Struct {\n\t\t\t\t\tkeyBytes := []byte(k)\n\t\t\t\t\t// Find the field that the JSON library would use.\n\t\t\t\t\tvar f *field\n\t\t\t\t\tfields := cachedTypeFields(t.Type())\n\t\t\t\t\tfor i := range fields {\n\t\t\t\t\t\tff := &fields[i]\n\t\t\t\t\t\tif bytes.Equal(ff.nameBytes, keyBytes) {\n\t\t\t\t\t\t\tf = ff\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Do case-insensitive comparison.\n\t\t\t\t\t\tif f == nil && ff.equalFold(ff.nameBytes, keyBytes) {\n\t\t\t\t\t\t\tf = ff\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif f != nil {\n\t\t\t\t\t\t// Find the reflect.Value of the most preferential\n\t\t\t\t\t\t// struct field.\n\t\t\t\t\t\tjtf := t.Field(f.index[0])\n\t\t\t\t\t\ttypedYAMLObj[k], err = convertToJSONableObject(v, &jtf)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else if t.Kind() == reflect.Map {\n\t\t\t\t\t// Create a zero value of the map's element type to use as\n\t\t\t\t\t// the JSON target.\n\t\t\t\t\tjtv := reflect.Zero(t.Type().Elem())\n\t\t\t\t\ttypedYAMLObj[k], err = convertToJSONableObject(v, &jtv)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\ttypedYAMLObj[k], err = convertToJSONableObject(v, nil)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn typedYAMLObj, nil\n\tcase []interface{}:\n\t\t// We need to recurse into arrays in case there are any\n\t\t// map[interface{}]interface{}'s inside and to convert any\n\t\t// numbers to strings.\n\n\t\t// If jsonTarget is a slice (which it really should be), find the\n\t\t// thing it's going to map to. If it's not a slice, just pass nil\n\t\t// - JSON conversion will error for us if it's a real issue.\n\t\tvar jsonSliceElemValue *reflect.Value\n\t\tif jsonTarget != nil {\n\t\t\tt := *jsonTarget\n\t\t\tif t.Kind() == reflect.Slice {\n\t\t\t\t// By default slices point to nil, but we need a reflect.Value\n\t\t\t\t// pointing to a value of the slice type, so we create one here.\n\t\t\t\tev := reflect.Indirect(reflect.New(t.Type().Elem()))\n\t\t\t\tjsonSliceElemValue = &ev\n\t\t\t}\n\t\t}\n\n\t\t// Make and use a new array.\n\t\tarr := make([]interface{}, len(typedYAMLObj))\n\t\tfor i, v := range typedYAMLObj {\n\t\t\tarr[i], err = convertToJSONableObject(v, jsonSliceElemValue)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn arr, nil\n\tdefault:\n\t\t// If the target type is a string and the YAML type is a number,\n\t\t// convert the YAML type to a string.\n\t\tif jsonTarget != nil && (*jsonTarget).Kind() == reflect.String {\n\t\t\t// Based on my reading of go-yaml, it may return int, int64,\n\t\t\t// float64, or uint64.\n\t\t\tvar s string\n\t\t\tswitch typedVal := typedYAMLObj.(type) {\n\t\t\tcase int:\n\t\t\t\ts = strconv.FormatInt(int64(typedVal), 10)\n\t\t\tcase int64:\n\t\t\t\ts = strconv.FormatInt(typedVal, 10)\n\t\t\tcase float64:\n\t\t\t\ts = strconv.FormatFloat(typedVal, 'g', -1, 64)\n\t\t\tcase uint64:\n\t\t\t\ts = strconv.FormatUint(typedVal, 10)\n\t\t\tcase bool:\n\t\t\t\tif typedVal {\n\t\t\t\t\ts = \"true\"\n\t\t\t\t} else {\n\t\t\t\t\ts = \"false\"\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(s) > 0 {\n\t\t\t\tyamlObj = interface{}(s)\n\t\t\t}\n\t\t}\n\t\treturn yamlObj, nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/LICENSE",
    "content": "\nThis project is covered by two different licenses: MIT and Apache.\n\n#### MIT License ####\n\nThe following files were ported to Go from C files of libyaml, and thus\nare still covered by their original MIT license, with the additional\ncopyright staring in 2011 when the project was ported over:\n\n    apic.go emitterc.go parserc.go readerc.go scannerc.go\n    writerc.go yamlh.go yamlprivateh.go\n\nCopyright (c) 2006-2010 Kirill Simonov\nCopyright (c) 2006-2011 Kirill Simonov\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, 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\n### Apache License ###\n\nAll the remaining project files are covered by the Apache license:\n\nCopyright (c) 2011-2019 Canonical Ltd\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/NOTICE",
    "content": "Copyright 2011-2016 Canonical Ltd.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/README.md",
    "content": "# YAML support for the Go language\n\nFork\n----\nThis fork is an improved version of the go-yaml/yaml package, designed to include line and column location information for YAML elements during unmarshalling.\n\nIntroduction\n------------\n\nThe yaml package enables Go programs to comfortably encode and decode YAML\nvalues. It was developed within [Canonical](https://www.canonical.com) as\npart of the [juju](https://juju.ubuntu.com) project, and is based on a\npure Go port of the well-known [libyaml](http://pyyaml.org/wiki/LibYAML)\nC library to parse and generate YAML data quickly and reliably.\n\nCompatibility\n-------------\n\nThe yaml package supports most of YAML 1.2, but preserves some behavior\nfrom 1.1 for backwards compatibility.\n\nSpecifically, as of v3 of the yaml package:\n\n - YAML 1.1 bools (_yes/no, on/off_) are supported as long as they are being\n   decoded into a typed bool value. Otherwise they behave as a string. Booleans\n   in YAML 1.2 are _true/false_ only.\n - Octals encode and decode as _0777_ per YAML 1.1, rather than _0o777_\n   as specified in YAML 1.2, because most parsers still use the old format.\n   Octals in the  _0o777_ format are supported though, so new files work.\n - Does not support base-60 floats. These are gone from YAML 1.2, and were\n   actually never supported by this package as it's clearly a poor choice.\n\nand offers backwards\ncompatibility with YAML 1.1 in some cases.\n1.2, including support for\nanchors, tags, map merging, etc. Multi-document unmarshalling is not yet\nimplemented, and base-60 floats from YAML 1.1 are purposefully not\nsupported since they're a poor design and are gone in YAML 1.2.\n\nInstallation and usage\n----------------------\n\nThe import path for the package is *gopkg.in/yaml.v3*.\n\nTo install it, run:\n\n    go get gopkg.in/yaml.v3\n\nAPI documentation\n-----------------\n\nIf opened in a browser, the import path itself leads to the API documentation:\n\n  - [https://gopkg.in/yaml.v3](https://gopkg.in/yaml.v3)\n\nAPI stability\n-------------\n\nThe package API for yaml v3 will remain stable as described in [gopkg.in](https://gopkg.in).\n\n\nLicense\n-------\n\nThe yaml package is licensed under the MIT and Apache License 2.0 licenses.\nPlease see the LICENSE file for details.\n\n\nExample\n-------\n\n```Go\npackage main\n\nimport (\n        \"fmt\"\n        \"log\"\n\n        \"oasdiff/yaml\"\n)\n\nvar data = `\na: Easy!\nb:\n  c: 2\n  d: [3, 4]\n`\n\n// Note: struct fields must be public in order for unmarshal to\n// correctly populate the data.\ntype T struct {\n        A string\n        B struct {\n                RenamedC int   `yaml:\"c\"`\n                D        []int `yaml:\",flow\"`\n        }\n}\n\nfunc main() {\n        t := T{}\n    \n        err := yaml.Unmarshal([]byte(data), &t)\n        if err != nil {\n                log.Fatalf(\"error: %v\", err)\n        }\n        fmt.Printf(\"--- t:\\n%v\\n\\n\", t)\n    \n        d, err := yaml.Marshal(&t)\n        if err != nil {\n                log.Fatalf(\"error: %v\", err)\n        }\n        fmt.Printf(\"--- t dump:\\n%s\\n\\n\", string(d))\n    \n        m := make(map[interface{}]interface{})\n    \n        err = yaml.Unmarshal([]byte(data), &m)\n        if err != nil {\n                log.Fatalf(\"error: %v\", err)\n        }\n        fmt.Printf(\"--- m:\\n%v\\n\\n\", m)\n    \n        d, err = yaml.Marshal(&m)\n        if err != nil {\n                log.Fatalf(\"error: %v\", err)\n        }\n        fmt.Printf(\"--- m dump:\\n%s\\n\\n\", string(d))\n}\n```\n\nThis example will generate the following output:\n\n```\n--- t:\n{Easy! {2 [3 4]}}\n\n--- t dump:\na: Easy!\nb:\n  c: 2\n  d: [3, 4]\n\n\n--- m:\nmap[a:Easy! b:map[c:2 d:[3 4]]]\n\n--- m dump:\na: Easy!\nb:\n  c: 2\n  d:\n  - 3\n  - 4\n```\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/apic.go",
    "content": "// \n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\nimport (\n\t\"io\"\n)\n\nfunc yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {\n\t//fmt.Println(\"yaml_insert_token\", \"pos:\", pos, \"typ:\", token.typ, \"head:\", parser.tokens_head, \"len:\", len(parser.tokens))\n\n\t// Check if we can move the queue at the beginning of the buffer.\n\tif parser.tokens_head > 0 && len(parser.tokens) == cap(parser.tokens) {\n\t\tif parser.tokens_head != len(parser.tokens) {\n\t\t\tcopy(parser.tokens, parser.tokens[parser.tokens_head:])\n\t\t}\n\t\tparser.tokens = parser.tokens[:len(parser.tokens)-parser.tokens_head]\n\t\tparser.tokens_head = 0\n\t}\n\tparser.tokens = append(parser.tokens, *token)\n\tif pos < 0 {\n\t\treturn\n\t}\n\tcopy(parser.tokens[parser.tokens_head+pos+1:], parser.tokens[parser.tokens_head+pos:])\n\tparser.tokens[parser.tokens_head+pos] = *token\n}\n\n// Create a new parser object.\nfunc yaml_parser_initialize(parser *yaml_parser_t) bool {\n\t*parser = yaml_parser_t{\n\t\traw_buffer: make([]byte, 0, input_raw_buffer_size),\n\t\tbuffer:     make([]byte, 0, input_buffer_size),\n\t}\n\treturn true\n}\n\n// Destroy a parser object.\nfunc yaml_parser_delete(parser *yaml_parser_t) {\n\t*parser = yaml_parser_t{}\n}\n\n// String read handler.\nfunc yaml_string_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {\n\tif parser.input_pos == len(parser.input) {\n\t\treturn 0, io.EOF\n\t}\n\tn = copy(buffer, parser.input[parser.input_pos:])\n\tparser.input_pos += n\n\treturn n, nil\n}\n\n// Reader read handler.\nfunc yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {\n\treturn parser.input_reader.Read(buffer)\n}\n\n// Set a string input.\nfunc yaml_parser_set_input_string(parser *yaml_parser_t, input []byte) {\n\tif parser.read_handler != nil {\n\t\tpanic(\"must set the input source only once\")\n\t}\n\tparser.read_handler = yaml_string_read_handler\n\tparser.input = input\n\tparser.input_pos = 0\n}\n\n// Set a file input.\nfunc yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {\n\tif parser.read_handler != nil {\n\t\tpanic(\"must set the input source only once\")\n\t}\n\tparser.read_handler = yaml_reader_read_handler\n\tparser.input_reader = r\n}\n\n// Set the source encoding.\nfunc yaml_parser_set_encoding(parser *yaml_parser_t, encoding yaml_encoding_t) {\n\tif parser.encoding != yaml_ANY_ENCODING {\n\t\tpanic(\"must set the encoding only once\")\n\t}\n\tparser.encoding = encoding\n}\n\n// Create a new emitter object.\nfunc yaml_emitter_initialize(emitter *yaml_emitter_t) {\n\t*emitter = yaml_emitter_t{\n\t\tbuffer:     make([]byte, output_buffer_size),\n\t\traw_buffer: make([]byte, 0, output_raw_buffer_size),\n\t\tstates:     make([]yaml_emitter_state_t, 0, initial_stack_size),\n\t\tevents:     make([]yaml_event_t, 0, initial_queue_size),\n\t\tbest_width: -1,\n\t}\n}\n\n// Destroy an emitter object.\nfunc yaml_emitter_delete(emitter *yaml_emitter_t) {\n\t*emitter = yaml_emitter_t{}\n}\n\n// String write handler.\nfunc yaml_string_write_handler(emitter *yaml_emitter_t, buffer []byte) error {\n\t*emitter.output_buffer = append(*emitter.output_buffer, buffer...)\n\treturn nil\n}\n\n// yaml_writer_write_handler uses emitter.output_writer to write the\n// emitted text.\nfunc yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {\n\t_, err := emitter.output_writer.Write(buffer)\n\treturn err\n}\n\n// Set a string output.\nfunc yaml_emitter_set_output_string(emitter *yaml_emitter_t, output_buffer *[]byte) {\n\tif emitter.write_handler != nil {\n\t\tpanic(\"must set the output target only once\")\n\t}\n\temitter.write_handler = yaml_string_write_handler\n\temitter.output_buffer = output_buffer\n}\n\n// Set a file output.\nfunc yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {\n\tif emitter.write_handler != nil {\n\t\tpanic(\"must set the output target only once\")\n\t}\n\temitter.write_handler = yaml_writer_write_handler\n\temitter.output_writer = w\n}\n\n// Set the output encoding.\nfunc yaml_emitter_set_encoding(emitter *yaml_emitter_t, encoding yaml_encoding_t) {\n\tif emitter.encoding != yaml_ANY_ENCODING {\n\t\tpanic(\"must set the output encoding only once\")\n\t}\n\temitter.encoding = encoding\n}\n\n// Set the canonical output style.\nfunc yaml_emitter_set_canonical(emitter *yaml_emitter_t, canonical bool) {\n\temitter.canonical = canonical\n}\n\n// Set the indentation increment.\nfunc yaml_emitter_set_indent(emitter *yaml_emitter_t, indent int) {\n\tif indent < 2 || indent > 9 {\n\t\tindent = 2\n\t}\n\temitter.best_indent = indent\n}\n\n// Set the preferred line width.\nfunc yaml_emitter_set_width(emitter *yaml_emitter_t, width int) {\n\tif width < 0 {\n\t\twidth = -1\n\t}\n\temitter.best_width = width\n}\n\n// Set if unescaped non-ASCII characters are allowed.\nfunc yaml_emitter_set_unicode(emitter *yaml_emitter_t, unicode bool) {\n\temitter.unicode = unicode\n}\n\n// Set the preferred line break character.\nfunc yaml_emitter_set_break(emitter *yaml_emitter_t, line_break yaml_break_t) {\n\temitter.line_break = line_break\n}\n\n///*\n// * Destroy a token object.\n// */\n//\n//YAML_DECLARE(void)\n//yaml_token_delete(yaml_token_t *token)\n//{\n//    assert(token);  // Non-NULL token object expected.\n//\n//    switch (token.type)\n//    {\n//        case YAML_TAG_DIRECTIVE_TOKEN:\n//            yaml_free(token.data.tag_directive.handle);\n//            yaml_free(token.data.tag_directive.prefix);\n//            break;\n//\n//        case YAML_ALIAS_TOKEN:\n//            yaml_free(token.data.alias.value);\n//            break;\n//\n//        case YAML_ANCHOR_TOKEN:\n//            yaml_free(token.data.anchor.value);\n//            break;\n//\n//        case YAML_TAG_TOKEN:\n//            yaml_free(token.data.tag.handle);\n//            yaml_free(token.data.tag.suffix);\n//            break;\n//\n//        case YAML_SCALAR_TOKEN:\n//            yaml_free(token.data.scalar.value);\n//            break;\n//\n//        default:\n//            break;\n//    }\n//\n//    memset(token, 0, sizeof(yaml_token_t));\n//}\n//\n///*\n// * Check if a string is a valid UTF-8 sequence.\n// *\n// * Check 'reader.c' for more details on UTF-8 encoding.\n// */\n//\n//static int\n//yaml_check_utf8(yaml_char_t *start, size_t length)\n//{\n//    yaml_char_t *end = start+length;\n//    yaml_char_t *pointer = start;\n//\n//    while (pointer < end) {\n//        unsigned char octet;\n//        unsigned int width;\n//        unsigned int value;\n//        size_t k;\n//\n//        octet = pointer[0];\n//        width = (octet & 0x80) == 0x00 ? 1 :\n//                (octet & 0xE0) == 0xC0 ? 2 :\n//                (octet & 0xF0) == 0xE0 ? 3 :\n//                (octet & 0xF8) == 0xF0 ? 4 : 0;\n//        value = (octet & 0x80) == 0x00 ? octet & 0x7F :\n//                (octet & 0xE0) == 0xC0 ? octet & 0x1F :\n//                (octet & 0xF0) == 0xE0 ? octet & 0x0F :\n//                (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;\n//        if (!width) return 0;\n//        if (pointer+width > end) return 0;\n//        for (k = 1; k < width; k ++) {\n//            octet = pointer[k];\n//            if ((octet & 0xC0) != 0x80) return 0;\n//            value = (value << 6) + (octet & 0x3F);\n//        }\n//        if (!((width == 1) ||\n//            (width == 2 && value >= 0x80) ||\n//            (width == 3 && value >= 0x800) ||\n//            (width == 4 && value >= 0x10000))) return 0;\n//\n//        pointer += width;\n//    }\n//\n//    return 1;\n//}\n//\n\n// Create STREAM-START.\nfunc yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {\n\t*event = yaml_event_t{\n\t\ttyp:      yaml_STREAM_START_EVENT,\n\t\tencoding: encoding,\n\t}\n}\n\n// Create STREAM-END.\nfunc yaml_stream_end_event_initialize(event *yaml_event_t) {\n\t*event = yaml_event_t{\n\t\ttyp: yaml_STREAM_END_EVENT,\n\t}\n}\n\n// Create DOCUMENT-START.\nfunc yaml_document_start_event_initialize(\n\tevent *yaml_event_t,\n\tversion_directive *yaml_version_directive_t,\n\ttag_directives []yaml_tag_directive_t,\n\timplicit bool,\n) {\n\t*event = yaml_event_t{\n\t\ttyp:               yaml_DOCUMENT_START_EVENT,\n\t\tversion_directive: version_directive,\n\t\ttag_directives:    tag_directives,\n\t\timplicit:          implicit,\n\t}\n}\n\n// Create DOCUMENT-END.\nfunc yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {\n\t*event = yaml_event_t{\n\t\ttyp:      yaml_DOCUMENT_END_EVENT,\n\t\timplicit: implicit,\n\t}\n}\n\n// Create ALIAS.\nfunc yaml_alias_event_initialize(event *yaml_event_t, anchor []byte) bool {\n\t*event = yaml_event_t{\n\t\ttyp:    yaml_ALIAS_EVENT,\n\t\tanchor: anchor,\n\t}\n\treturn true\n}\n\n// Create SCALAR.\nfunc yaml_scalar_event_initialize(event *yaml_event_t, anchor, tag, value []byte, plain_implicit, quoted_implicit bool, style yaml_scalar_style_t) bool {\n\t*event = yaml_event_t{\n\t\ttyp:             yaml_SCALAR_EVENT,\n\t\tanchor:          anchor,\n\t\ttag:             tag,\n\t\tvalue:           value,\n\t\timplicit:        plain_implicit,\n\t\tquoted_implicit: quoted_implicit,\n\t\tstyle:           yaml_style_t(style),\n\t}\n\treturn true\n}\n\n// Create SEQUENCE-START.\nfunc yaml_sequence_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_sequence_style_t) bool {\n\t*event = yaml_event_t{\n\t\ttyp:      yaml_SEQUENCE_START_EVENT,\n\t\tanchor:   anchor,\n\t\ttag:      tag,\n\t\timplicit: implicit,\n\t\tstyle:    yaml_style_t(style),\n\t}\n\treturn true\n}\n\n// Create SEQUENCE-END.\nfunc yaml_sequence_end_event_initialize(event *yaml_event_t) bool {\n\t*event = yaml_event_t{\n\t\ttyp: yaml_SEQUENCE_END_EVENT,\n\t}\n\treturn true\n}\n\n// Create MAPPING-START.\nfunc yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {\n\t*event = yaml_event_t{\n\t\ttyp:      yaml_MAPPING_START_EVENT,\n\t\tanchor:   anchor,\n\t\ttag:      tag,\n\t\timplicit: implicit,\n\t\tstyle:    yaml_style_t(style),\n\t}\n}\n\n// Create MAPPING-END.\nfunc yaml_mapping_end_event_initialize(event *yaml_event_t) {\n\t*event = yaml_event_t{\n\t\ttyp: yaml_MAPPING_END_EVENT,\n\t}\n}\n\n// Destroy an event object.\nfunc yaml_event_delete(event *yaml_event_t) {\n\t*event = yaml_event_t{}\n}\n\n///*\n// * Create a document object.\n// */\n//\n//YAML_DECLARE(int)\n//yaml_document_initialize(document *yaml_document_t,\n//        version_directive *yaml_version_directive_t,\n//        tag_directives_start *yaml_tag_directive_t,\n//        tag_directives_end *yaml_tag_directive_t,\n//        start_implicit int, end_implicit int)\n//{\n//    struct {\n//        error yaml_error_type_t\n//    } context\n//    struct {\n//        start *yaml_node_t\n//        end *yaml_node_t\n//        top *yaml_node_t\n//    } nodes = { NULL, NULL, NULL }\n//    version_directive_copy *yaml_version_directive_t = NULL\n//    struct {\n//        start *yaml_tag_directive_t\n//        end *yaml_tag_directive_t\n//        top *yaml_tag_directive_t\n//    } tag_directives_copy = { NULL, NULL, NULL }\n//    value yaml_tag_directive_t = { NULL, NULL }\n//    mark yaml_mark_t = { 0, 0, 0 }\n//\n//    assert(document) // Non-NULL document object is expected.\n//    assert((tag_directives_start && tag_directives_end) ||\n//            (tag_directives_start == tag_directives_end))\n//                            // Valid tag directives are expected.\n//\n//    if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error\n//\n//    if (version_directive) {\n//        version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t))\n//        if (!version_directive_copy) goto error\n//        version_directive_copy.major = version_directive.major\n//        version_directive_copy.minor = version_directive.minor\n//    }\n//\n//    if (tag_directives_start != tag_directives_end) {\n//        tag_directive *yaml_tag_directive_t\n//        if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE))\n//            goto error\n//        for (tag_directive = tag_directives_start\n//                tag_directive != tag_directives_end; tag_directive ++) {\n//            assert(tag_directive.handle)\n//            assert(tag_directive.prefix)\n//            if (!yaml_check_utf8(tag_directive.handle,\n//                        strlen((char *)tag_directive.handle)))\n//                goto error\n//            if (!yaml_check_utf8(tag_directive.prefix,\n//                        strlen((char *)tag_directive.prefix)))\n//                goto error\n//            value.handle = yaml_strdup(tag_directive.handle)\n//            value.prefix = yaml_strdup(tag_directive.prefix)\n//            if (!value.handle || !value.prefix) goto error\n//            if (!PUSH(&context, tag_directives_copy, value))\n//                goto error\n//            value.handle = NULL\n//            value.prefix = NULL\n//        }\n//    }\n//\n//    DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy,\n//            tag_directives_copy.start, tag_directives_copy.top,\n//            start_implicit, end_implicit, mark, mark)\n//\n//    return 1\n//\n//error:\n//    STACK_DEL(&context, nodes)\n//    yaml_free(version_directive_copy)\n//    while (!STACK_EMPTY(&context, tag_directives_copy)) {\n//        value yaml_tag_directive_t = POP(&context, tag_directives_copy)\n//        yaml_free(value.handle)\n//        yaml_free(value.prefix)\n//    }\n//    STACK_DEL(&context, tag_directives_copy)\n//    yaml_free(value.handle)\n//    yaml_free(value.prefix)\n//\n//    return 0\n//}\n//\n///*\n// * Destroy a document object.\n// */\n//\n//YAML_DECLARE(void)\n//yaml_document_delete(document *yaml_document_t)\n//{\n//    struct {\n//        error yaml_error_type_t\n//    } context\n//    tag_directive *yaml_tag_directive_t\n//\n//    context.error = YAML_NO_ERROR // Eliminate a compiler warning.\n//\n//    assert(document) // Non-NULL document object is expected.\n//\n//    while (!STACK_EMPTY(&context, document.nodes)) {\n//        node yaml_node_t = POP(&context, document.nodes)\n//        yaml_free(node.tag)\n//        switch (node.type) {\n//            case YAML_SCALAR_NODE:\n//                yaml_free(node.data.scalar.value)\n//                break\n//            case YAML_SEQUENCE_NODE:\n//                STACK_DEL(&context, node.data.sequence.items)\n//                break\n//            case YAML_MAPPING_NODE:\n//                STACK_DEL(&context, node.data.mapping.pairs)\n//                break\n//            default:\n//                assert(0) // Should not happen.\n//        }\n//    }\n//    STACK_DEL(&context, document.nodes)\n//\n//    yaml_free(document.version_directive)\n//    for (tag_directive = document.tag_directives.start\n//            tag_directive != document.tag_directives.end\n//            tag_directive++) {\n//        yaml_free(tag_directive.handle)\n//        yaml_free(tag_directive.prefix)\n//    }\n//    yaml_free(document.tag_directives.start)\n//\n//    memset(document, 0, sizeof(yaml_document_t))\n//}\n//\n///**\n// * Get a document node.\n// */\n//\n//YAML_DECLARE(yaml_node_t *)\n//yaml_document_get_node(document *yaml_document_t, index int)\n//{\n//    assert(document) // Non-NULL document object is expected.\n//\n//    if (index > 0 && document.nodes.start + index <= document.nodes.top) {\n//        return document.nodes.start + index - 1\n//    }\n//    return NULL\n//}\n//\n///**\n// * Get the root object.\n// */\n//\n//YAML_DECLARE(yaml_node_t *)\n//yaml_document_get_root_node(document *yaml_document_t)\n//{\n//    assert(document) // Non-NULL document object is expected.\n//\n//    if (document.nodes.top != document.nodes.start) {\n//        return document.nodes.start\n//    }\n//    return NULL\n//}\n//\n///*\n// * Add a scalar node to a document.\n// */\n//\n//YAML_DECLARE(int)\n//yaml_document_add_scalar(document *yaml_document_t,\n//        tag *yaml_char_t, value *yaml_char_t, length int,\n//        style yaml_scalar_style_t)\n//{\n//    struct {\n//        error yaml_error_type_t\n//    } context\n//    mark yaml_mark_t = { 0, 0, 0 }\n//    tag_copy *yaml_char_t = NULL\n//    value_copy *yaml_char_t = NULL\n//    node yaml_node_t\n//\n//    assert(document) // Non-NULL document object is expected.\n//    assert(value) // Non-NULL value is expected.\n//\n//    if (!tag) {\n//        tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG\n//    }\n//\n//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error\n//    tag_copy = yaml_strdup(tag)\n//    if (!tag_copy) goto error\n//\n//    if (length < 0) {\n//        length = strlen((char *)value)\n//    }\n//\n//    if (!yaml_check_utf8(value, length)) goto error\n//    value_copy = yaml_malloc(length+1)\n//    if (!value_copy) goto error\n//    memcpy(value_copy, value, length)\n//    value_copy[length] = '\\0'\n//\n//    SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark)\n//    if (!PUSH(&context, document.nodes, node)) goto error\n//\n//    return document.nodes.top - document.nodes.start\n//\n//error:\n//    yaml_free(tag_copy)\n//    yaml_free(value_copy)\n//\n//    return 0\n//}\n//\n///*\n// * Add a sequence node to a document.\n// */\n//\n//YAML_DECLARE(int)\n//yaml_document_add_sequence(document *yaml_document_t,\n//        tag *yaml_char_t, style yaml_sequence_style_t)\n//{\n//    struct {\n//        error yaml_error_type_t\n//    } context\n//    mark yaml_mark_t = { 0, 0, 0 }\n//    tag_copy *yaml_char_t = NULL\n//    struct {\n//        start *yaml_node_item_t\n//        end *yaml_node_item_t\n//        top *yaml_node_item_t\n//    } items = { NULL, NULL, NULL }\n//    node yaml_node_t\n//\n//    assert(document) // Non-NULL document object is expected.\n//\n//    if (!tag) {\n//        tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG\n//    }\n//\n//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error\n//    tag_copy = yaml_strdup(tag)\n//    if (!tag_copy) goto error\n//\n//    if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error\n//\n//    SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end,\n//            style, mark, mark)\n//    if (!PUSH(&context, document.nodes, node)) goto error\n//\n//    return document.nodes.top - document.nodes.start\n//\n//error:\n//    STACK_DEL(&context, items)\n//    yaml_free(tag_copy)\n//\n//    return 0\n//}\n//\n///*\n// * Add a mapping node to a document.\n// */\n//\n//YAML_DECLARE(int)\n//yaml_document_add_mapping(document *yaml_document_t,\n//        tag *yaml_char_t, style yaml_mapping_style_t)\n//{\n//    struct {\n//        error yaml_error_type_t\n//    } context\n//    mark yaml_mark_t = { 0, 0, 0 }\n//    tag_copy *yaml_char_t = NULL\n//    struct {\n//        start *yaml_node_pair_t\n//        end *yaml_node_pair_t\n//        top *yaml_node_pair_t\n//    } pairs = { NULL, NULL, NULL }\n//    node yaml_node_t\n//\n//    assert(document) // Non-NULL document object is expected.\n//\n//    if (!tag) {\n//        tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG\n//    }\n//\n//    if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error\n//    tag_copy = yaml_strdup(tag)\n//    if (!tag_copy) goto error\n//\n//    if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error\n//\n//    MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end,\n//            style, mark, mark)\n//    if (!PUSH(&context, document.nodes, node)) goto error\n//\n//    return document.nodes.top - document.nodes.start\n//\n//error:\n//    STACK_DEL(&context, pairs)\n//    yaml_free(tag_copy)\n//\n//    return 0\n//}\n//\n///*\n// * Append an item to a sequence node.\n// */\n//\n//YAML_DECLARE(int)\n//yaml_document_append_sequence_item(document *yaml_document_t,\n//        sequence int, item int)\n//{\n//    struct {\n//        error yaml_error_type_t\n//    } context\n//\n//    assert(document) // Non-NULL document is required.\n//    assert(sequence > 0\n//            && document.nodes.start + sequence <= document.nodes.top)\n//                            // Valid sequence id is required.\n//    assert(document.nodes.start[sequence-1].type == YAML_SEQUENCE_NODE)\n//                            // A sequence node is required.\n//    assert(item > 0 && document.nodes.start + item <= document.nodes.top)\n//                            // Valid item id is required.\n//\n//    if (!PUSH(&context,\n//                document.nodes.start[sequence-1].data.sequence.items, item))\n//        return 0\n//\n//    return 1\n//}\n//\n///*\n// * Append a pair of a key and a value to a mapping node.\n// */\n//\n//YAML_DECLARE(int)\n//yaml_document_append_mapping_pair(document *yaml_document_t,\n//        mapping int, key int, value int)\n//{\n//    struct {\n//        error yaml_error_type_t\n//    } context\n//\n//    pair yaml_node_pair_t\n//\n//    assert(document) // Non-NULL document is required.\n//    assert(mapping > 0\n//            && document.nodes.start + mapping <= document.nodes.top)\n//                            // Valid mapping id is required.\n//    assert(document.nodes.start[mapping-1].type == YAML_MAPPING_NODE)\n//                            // A mapping node is required.\n//    assert(key > 0 && document.nodes.start + key <= document.nodes.top)\n//                            // Valid key id is required.\n//    assert(value > 0 && document.nodes.start + value <= document.nodes.top)\n//                            // Valid value id is required.\n//\n//    pair.key = key\n//    pair.value = value\n//\n//    if (!PUSH(&context,\n//                document.nodes.start[mapping-1].data.mapping.pairs, pair))\n//        return 0\n//\n//    return 1\n//}\n//\n//\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/decode.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\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//     http://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\npackage yaml\n\nimport (\n\t\"encoding\"\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"time\"\n)\n\n// ----------------------------------------------------------------------------\n// Parser, produces a node tree out of a libyaml event stream.\n\ntype parser struct {\n\tparser   yaml_parser_t\n\tevent    yaml_event_t\n\tdoc      *Node\n\tanchors  map[string]*Node\n\tdoneInit bool\n\ttextless bool\n}\n\nfunc newParser(b []byte) *parser {\n\tp := parser{}\n\tif !yaml_parser_initialize(&p.parser) {\n\t\tpanic(\"failed to initialize YAML emitter\")\n\t}\n\tif len(b) == 0 {\n\t\tb = []byte{'\\n'}\n\t}\n\tyaml_parser_set_input_string(&p.parser, b)\n\treturn &p\n}\n\nfunc newParserFromReader(r io.Reader) *parser {\n\tp := parser{}\n\tif !yaml_parser_initialize(&p.parser) {\n\t\tpanic(\"failed to initialize YAML emitter\")\n\t}\n\tyaml_parser_set_input_reader(&p.parser, r)\n\treturn &p\n}\n\nfunc (p *parser) init() {\n\tif p.doneInit {\n\t\treturn\n\t}\n\tp.anchors = make(map[string]*Node)\n\tp.expect(yaml_STREAM_START_EVENT)\n\tp.doneInit = true\n}\n\nfunc (p *parser) destroy() {\n\tif p.event.typ != yaml_NO_EVENT {\n\t\tyaml_event_delete(&p.event)\n\t}\n\tyaml_parser_delete(&p.parser)\n}\n\n// expect consumes an event from the event stream and\n// checks that it's of the expected type.\nfunc (p *parser) expect(e yaml_event_type_t) {\n\tif p.event.typ == yaml_NO_EVENT {\n\t\tif !yaml_parser_parse(&p.parser, &p.event) {\n\t\t\tp.fail()\n\t\t}\n\t}\n\tif p.event.typ == yaml_STREAM_END_EVENT {\n\t\tfailf(\"attempted to go past the end of stream; corrupted value?\")\n\t}\n\tif p.event.typ != e {\n\t\tp.parser.problem = fmt.Sprintf(\"expected %s event but got %s\", e, p.event.typ)\n\t\tp.fail()\n\t}\n\tyaml_event_delete(&p.event)\n\tp.event.typ = yaml_NO_EVENT\n}\n\n// peek peeks at the next event in the event stream,\n// puts the results into p.event and returns the event type.\nfunc (p *parser) peek() yaml_event_type_t {\n\tif p.event.typ != yaml_NO_EVENT {\n\t\treturn p.event.typ\n\t}\n\t// It's curious choice from the underlying API to generally return a\n\t// positive result on success, but on this case return true in an error\n\t// scenario. This was the source of bugs in the past (issue #666).\n\tif !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR {\n\t\tp.fail()\n\t}\n\treturn p.event.typ\n}\n\nfunc (p *parser) fail() {\n\tvar where string\n\tvar line int\n\tif p.parser.context_mark.line != 0 {\n\t\tline = p.parser.context_mark.line\n\t\t// Scanner errors don't iterate line before returning error\n\t\tif p.parser.error == yaml_SCANNER_ERROR {\n\t\t\tline++\n\t\t}\n\t} else if p.parser.problem_mark.line != 0 {\n\t\tline = p.parser.problem_mark.line\n\t\t// Scanner errors don't iterate line before returning error\n\t\tif p.parser.error == yaml_SCANNER_ERROR {\n\t\t\tline++\n\t\t}\n\t}\n\tif line != 0 {\n\t\twhere = \"line \" + strconv.Itoa(line) + \": \"\n\t}\n\tvar msg string\n\tif len(p.parser.problem) > 0 {\n\t\tmsg = p.parser.problem\n\t} else {\n\t\tmsg = \"unknown problem parsing YAML content\"\n\t}\n\tfailf(\"%s%s\", where, msg)\n}\n\nfunc (p *parser) anchor(n *Node, anchor []byte) {\n\tif anchor != nil {\n\t\tn.Anchor = string(anchor)\n\t\tp.anchors[n.Anchor] = n\n\t}\n}\n\nfunc (p *parser) parse() *Node {\n\tp.init()\n\tswitch p.peek() {\n\tcase yaml_SCALAR_EVENT:\n\t\treturn p.scalar()\n\tcase yaml_ALIAS_EVENT:\n\t\treturn p.alias()\n\tcase yaml_MAPPING_START_EVENT:\n\t\treturn p.mapping()\n\tcase yaml_SEQUENCE_START_EVENT:\n\t\treturn p.sequence()\n\tcase yaml_DOCUMENT_START_EVENT:\n\t\treturn p.document()\n\tcase yaml_STREAM_END_EVENT:\n\t\t// Happens when attempting to decode an empty buffer.\n\t\treturn nil\n\tcase yaml_TAIL_COMMENT_EVENT:\n\t\tpanic(\"internal error: unexpected tail comment event (please report)\")\n\tdefault:\n\t\tpanic(\"internal error: attempted to parse unknown event (please report): \" + p.event.typ.String())\n\t}\n}\n\nfunc (p *parser) node(kind Kind, defaultTag, tag, value string) *Node {\n\tvar style Style\n\tif tag != \"\" && tag != \"!\" {\n\t\ttag = shortTag(tag)\n\t\tstyle = TaggedStyle\n\t} else if defaultTag != \"\" {\n\t\ttag = defaultTag\n\t} else if kind == ScalarNode {\n\t\ttag, _ = resolve(\"\", value)\n\t}\n\tn := &Node{\n\t\tKind:  kind,\n\t\tTag:   tag,\n\t\tValue: value,\n\t\tStyle: style,\n\t}\n\tif !p.textless {\n\t\tn.Line = p.event.start_mark.line + 1\n\t\tn.Column = p.event.start_mark.column + 1\n\t\tn.HeadComment = string(p.event.head_comment)\n\t\tn.LineComment = string(p.event.line_comment)\n\t\tn.FootComment = string(p.event.foot_comment)\n\t}\n\treturn n\n}\n\nfunc (p *parser) parseChild(parent *Node) *Node {\n\tchild := p.parse()\n\tparent.Content = append(parent.Content, child)\n\treturn child\n}\n\nfunc (p *parser) document() *Node {\n\tn := p.node(DocumentNode, \"\", \"\", \"\")\n\tp.doc = n\n\tp.expect(yaml_DOCUMENT_START_EVENT)\n\tp.parseChild(n)\n\tif p.peek() == yaml_DOCUMENT_END_EVENT {\n\t\tn.FootComment = string(p.event.foot_comment)\n\t}\n\tp.expect(yaml_DOCUMENT_END_EVENT)\n\treturn n\n}\n\nfunc (p *parser) alias() *Node {\n\tn := p.node(AliasNode, \"\", \"\", string(p.event.anchor))\n\tn.Alias = p.anchors[n.Value]\n\tif n.Alias == nil {\n\t\tfailf(\"unknown anchor '%s' referenced\", n.Value)\n\t}\n\tp.expect(yaml_ALIAS_EVENT)\n\treturn n\n}\n\nfunc (p *parser) scalar() *Node {\n\tvar parsedStyle = p.event.scalar_style()\n\tvar nodeStyle Style\n\tswitch {\n\tcase parsedStyle&yaml_DOUBLE_QUOTED_SCALAR_STYLE != 0:\n\t\tnodeStyle = DoubleQuotedStyle\n\tcase parsedStyle&yaml_SINGLE_QUOTED_SCALAR_STYLE != 0:\n\t\tnodeStyle = SingleQuotedStyle\n\tcase parsedStyle&yaml_LITERAL_SCALAR_STYLE != 0:\n\t\tnodeStyle = LiteralStyle\n\tcase parsedStyle&yaml_FOLDED_SCALAR_STYLE != 0:\n\t\tnodeStyle = FoldedStyle\n\t}\n\tvar nodeValue = string(p.event.value)\n\tvar nodeTag = string(p.event.tag)\n\tvar defaultTag string\n\tif nodeStyle == 0 {\n\t\tif nodeValue == \"<<\" {\n\t\t\tdefaultTag = mergeTag\n\t\t}\n\t} else {\n\t\tdefaultTag = strTag\n\t}\n\tn := p.node(ScalarNode, defaultTag, nodeTag, nodeValue)\n\tn.Style |= nodeStyle\n\tp.anchor(n, p.event.anchor)\n\tp.expect(yaml_SCALAR_EVENT)\n\treturn n\n}\n\nfunc (p *parser) sequence() *Node {\n\tn := p.node(SequenceNode, seqTag, string(p.event.tag), \"\")\n\tif p.event.sequence_style()&yaml_FLOW_SEQUENCE_STYLE != 0 {\n\t\tn.Style |= FlowStyle\n\t}\n\tp.anchor(n, p.event.anchor)\n\tp.expect(yaml_SEQUENCE_START_EVENT)\n\tfor p.peek() != yaml_SEQUENCE_END_EVENT {\n\t\tp.parseChild(n)\n\t}\n\tn.LineComment = string(p.event.line_comment)\n\tn.FootComment = string(p.event.foot_comment)\n\tp.expect(yaml_SEQUENCE_END_EVENT)\n\treturn n\n}\n\nfunc (p *parser) mapping() *Node {\n\tn := p.node(MappingNode, mapTag, string(p.event.tag), \"\")\n\tblock := true\n\tif p.event.mapping_style()&yaml_FLOW_MAPPING_STYLE != 0 {\n\t\tblock = false\n\t\tn.Style |= FlowStyle\n\t}\n\tp.anchor(n, p.event.anchor)\n\tp.expect(yaml_MAPPING_START_EVENT)\n\tfor p.peek() != yaml_MAPPING_END_EVENT {\n\t\tk := p.parseChild(n)\n\t\tif block && k.FootComment != \"\" {\n\t\t\t// Must be a foot comment for the prior value when being dedented.\n\t\t\tif len(n.Content) > 2 {\n\t\t\t\tn.Content[len(n.Content)-3].FootComment = k.FootComment\n\t\t\t\tk.FootComment = \"\"\n\t\t\t}\n\t\t}\n\t\tv := p.parseChild(n)\n\t\tif k.FootComment == \"\" && v.FootComment != \"\" {\n\t\t\tk.FootComment = v.FootComment\n\t\t\tv.FootComment = \"\"\n\t\t}\n\t\tif p.peek() == yaml_TAIL_COMMENT_EVENT {\n\t\t\tif k.FootComment == \"\" {\n\t\t\t\tk.FootComment = string(p.event.foot_comment)\n\t\t\t}\n\t\t\tp.expect(yaml_TAIL_COMMENT_EVENT)\n\t\t}\n\t}\n\tn.LineComment = string(p.event.line_comment)\n\tn.FootComment = string(p.event.foot_comment)\n\tif n.Style&FlowStyle == 0 && n.FootComment != \"\" && len(n.Content) > 1 {\n\t\tn.Content[len(n.Content)-2].FootComment = n.FootComment\n\t\tn.FootComment = \"\"\n\t}\n\tp.expect(yaml_MAPPING_END_EVENT)\n\treturn n\n}\n\n// ----------------------------------------------------------------------------\n// Decoder, unmarshals a node into a provided value.\n\ntype decoder struct {\n\tdoc     *Node\n\taliases map[*Node]bool\n\tterrors []string\n\n\tstringMapType  reflect.Type\n\tgeneralMapType reflect.Type\n\n\tknownFields bool\n\torigin      bool\n\tuniqueKeys  bool\n\tdecodeCount int\n\taliasCount  int\n\taliasDepth  int\n\n\tmergedFields map[interface{}]bool\n}\n\nvar (\n\tnodeType       = reflect.TypeOf(Node{})\n\tdurationType   = reflect.TypeOf(time.Duration(0))\n\tstringMapType  = reflect.TypeOf(map[string]interface{}{})\n\tgeneralMapType = reflect.TypeOf(map[interface{}]interface{}{})\n\tifaceType      = generalMapType.Elem()\n\ttimeType       = reflect.TypeOf(time.Time{})\n\tptrTimeType    = reflect.TypeOf(&time.Time{})\n)\n\nfunc newDecoder() *decoder {\n\td := &decoder{\n\t\tstringMapType:  stringMapType,\n\t\tgeneralMapType: generalMapType,\n\t\tuniqueKeys:     true,\n\t}\n\td.aliases = make(map[*Node]bool)\n\treturn d\n}\n\nfunc (d *decoder) terror(n *Node, tag string, out reflect.Value) {\n\tif n.Tag != \"\" {\n\t\ttag = n.Tag\n\t}\n\tvalue := n.Value\n\tif tag != seqTag && tag != mapTag {\n\t\tif len(value) > 10 {\n\t\t\tvalue = \" `\" + value[:7] + \"...`\"\n\t\t} else {\n\t\t\tvalue = \" `\" + value + \"`\"\n\t\t}\n\t}\n\td.terrors = append(d.terrors, fmt.Sprintf(\"line %d: cannot unmarshal %s%s into %s\", n.Line, shortTag(tag), value, out.Type()))\n}\n\nfunc (d *decoder) callUnmarshaler(n *Node, u Unmarshaler) (good bool) {\n\terr := u.UnmarshalYAML(n)\n\tif e, ok := err.(*TypeError); ok {\n\t\td.terrors = append(d.terrors, e.Errors...)\n\t\treturn false\n\t}\n\tif err != nil {\n\t\tfail(err)\n\t}\n\treturn true\n}\n\nfunc (d *decoder) callObsoleteUnmarshaler(n *Node, u obsoleteUnmarshaler) (good bool) {\n\tterrlen := len(d.terrors)\n\terr := u.UnmarshalYAML(func(v interface{}) (err error) {\n\t\tdefer handleErr(&err)\n\t\td.unmarshal(n, reflect.ValueOf(v))\n\t\tif len(d.terrors) > terrlen {\n\t\t\tissues := d.terrors[terrlen:]\n\t\t\td.terrors = d.terrors[:terrlen]\n\t\t\treturn &TypeError{issues}\n\t\t}\n\t\treturn nil\n\t})\n\tif e, ok := err.(*TypeError); ok {\n\t\td.terrors = append(d.terrors, e.Errors...)\n\t\treturn false\n\t}\n\tif err != nil {\n\t\tfail(err)\n\t}\n\treturn true\n}\n\n// d.prepare initializes and dereferences pointers and calls UnmarshalYAML\n// if a value is found to implement it.\n// It returns the initialized and dereferenced out value, whether\n// unmarshalling was already done by UnmarshalYAML, and if so whether\n// its types unmarshalled appropriately.\n//\n// If n holds a null value, prepare returns before doing anything.\nfunc (d *decoder) prepare(n *Node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {\n\tif n.ShortTag() == nullTag {\n\t\treturn out, false, false\n\t}\n\tagain := true\n\tfor again {\n\t\tagain = false\n\t\tif out.Kind() == reflect.Ptr {\n\t\t\tif out.IsNil() {\n\t\t\t\tout.Set(reflect.New(out.Type().Elem()))\n\t\t\t}\n\t\t\tout = out.Elem()\n\t\t\tagain = true\n\t\t}\n\t\tif out.CanAddr() {\n\t\t\touti := out.Addr().Interface()\n\t\t\tif u, ok := outi.(Unmarshaler); ok {\n\t\t\t\tgood = d.callUnmarshaler(n, u)\n\t\t\t\treturn out, true, good\n\t\t\t}\n\t\t\tif u, ok := outi.(obsoleteUnmarshaler); ok {\n\t\t\t\tgood = d.callObsoleteUnmarshaler(n, u)\n\t\t\t\treturn out, true, good\n\t\t\t}\n\t\t}\n\t}\n\treturn out, false, false\n}\n\nfunc (d *decoder) fieldByIndex(n *Node, v reflect.Value, index []int) (field reflect.Value) {\n\tif n.ShortTag() == nullTag {\n\t\treturn reflect.Value{}\n\t}\n\tfor _, num := range index {\n\t\tfor {\n\t\t\tif v.Kind() == reflect.Ptr {\n\t\t\t\tif v.IsNil() {\n\t\t\t\t\tv.Set(reflect.New(v.Type().Elem()))\n\t\t\t\t}\n\t\t\t\tv = v.Elem()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tv = v.Field(num)\n\t}\n\treturn v\n}\n\nconst (\n\t// 400,000 decode operations is ~500kb of dense object declarations, or\n\t// ~5kb of dense object declarations with 10000% alias expansion\n\talias_ratio_range_low = 400000\n\n\t// 4,000,000 decode operations is ~5MB of dense object declarations, or\n\t// ~4.5MB of dense object declarations with 10% alias expansion\n\talias_ratio_range_high = 4000000\n\n\t// alias_ratio_range is the range over which we scale allowed alias ratios\n\talias_ratio_range = float64(alias_ratio_range_high - alias_ratio_range_low)\n)\n\nfunc allowedAliasRatio(decodeCount int) float64 {\n\tswitch {\n\tcase decodeCount <= alias_ratio_range_low:\n\t\t// allow 99% to come from alias expansion for small-to-medium documents\n\t\treturn 0.99\n\tcase decodeCount >= alias_ratio_range_high:\n\t\t// allow 10% to come from alias expansion for very large documents\n\t\treturn 0.10\n\tdefault:\n\t\t// scale smoothly from 99% down to 10% over the range.\n\t\t// this maps to 396,000 - 400,000 allowed alias-driven decodes over the range.\n\t\t// 400,000 decode operations is ~100MB of allocations in worst-case scenarios (single-item maps).\n\t\treturn 0.99 - 0.89*(float64(decodeCount-alias_ratio_range_low)/alias_ratio_range)\n\t}\n}\n\nfunc (d *decoder) unmarshal(n *Node, out reflect.Value) (good bool) {\n\td.decodeCount++\n\tif d.aliasDepth > 0 {\n\t\td.aliasCount++\n\t}\n\tif d.aliasCount > 100 && d.decodeCount > 1000 && float64(d.aliasCount)/float64(d.decodeCount) > allowedAliasRatio(d.decodeCount) {\n\t\tfailf(\"document contains excessive aliasing\")\n\t}\n\tif out.Type() == nodeType {\n\t\tout.Set(reflect.ValueOf(n).Elem())\n\t\treturn true\n\t}\n\tswitch n.Kind {\n\tcase DocumentNode:\n\t\treturn d.document(n, out)\n\tcase AliasNode:\n\t\treturn d.alias(n, out)\n\t}\n\tout, unmarshaled, good := d.prepare(n, out)\n\tif unmarshaled {\n\t\treturn good\n\t}\n\tswitch n.Kind {\n\tcase ScalarNode:\n\t\tgood = d.scalar(n, out)\n\tcase MappingNode:\n\t\tgood = d.mapping(n, out)\n\tcase SequenceNode:\n\t\tgood = d.sequence(n, out)\n\tcase 0:\n\t\tif n.IsZero() {\n\t\t\treturn d.null(out)\n\t\t}\n\t\tfallthrough\n\tdefault:\n\t\tfailf(\"cannot decode node with unknown kind %d\", n.Kind)\n\t}\n\treturn good\n}\n\nfunc (d *decoder) document(n *Node, out reflect.Value) (good bool) {\n\tif len(n.Content) == 1 {\n\t\td.doc = n\n\t\td.unmarshal(n.Content[0], out)\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (d *decoder) alias(n *Node, out reflect.Value) (good bool) {\n\tif d.aliases[n] {\n\t\t// TODO this could actually be allowed in some circumstances.\n\t\tfailf(\"anchor '%s' value contains itself\", n.Value)\n\t}\n\td.aliases[n] = true\n\td.aliasDepth++\n\tgood = d.unmarshal(n.Alias, out)\n\td.aliasDepth--\n\tdelete(d.aliases, n)\n\treturn good\n}\n\nvar zeroValue reflect.Value\n\nfunc resetMap(out reflect.Value) {\n\tfor _, k := range out.MapKeys() {\n\t\tout.SetMapIndex(k, zeroValue)\n\t}\n}\n\nfunc (d *decoder) null(out reflect.Value) bool {\n\tif out.CanAddr() {\n\t\tswitch out.Kind() {\n\t\tcase reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:\n\t\t\tout.Set(reflect.Zero(out.Type()))\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (d *decoder) scalar(n *Node, out reflect.Value) bool {\n\tvar tag string\n\tvar resolved interface{}\n\tif n.indicatedString() {\n\t\ttag = strTag\n\t\tresolved = n.Value\n\t} else {\n\t\ttag, resolved = resolve(n.Tag, n.Value)\n\t\tif tag == binaryTag {\n\t\t\tdata, err := base64.StdEncoding.DecodeString(resolved.(string))\n\t\t\tif err != nil {\n\t\t\t\tfailf(\"!!binary value contains invalid base64 data\")\n\t\t\t}\n\t\t\tresolved = string(data)\n\t\t}\n\t}\n\tif resolved == nil {\n\t\treturn d.null(out)\n\t}\n\tif resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {\n\t\t// We've resolved to exactly the type we want, so use that.\n\t\tout.Set(resolvedv)\n\t\treturn true\n\t}\n\t// Perhaps we can use the value as a TextUnmarshaler to\n\t// set its value.\n\tif out.CanAddr() {\n\t\tu, ok := out.Addr().Interface().(encoding.TextUnmarshaler)\n\t\tif ok {\n\t\t\tvar text []byte\n\t\t\tif tag == binaryTag {\n\t\t\t\ttext = []byte(resolved.(string))\n\t\t\t} else {\n\t\t\t\t// We let any value be unmarshaled into TextUnmarshaler.\n\t\t\t\t// That might be more lax than we'd like, but the\n\t\t\t\t// TextUnmarshaler itself should bowl out any dubious values.\n\t\t\t\ttext = []byte(n.Value)\n\t\t\t}\n\t\t\terr := u.UnmarshalText(text)\n\t\t\tif err != nil {\n\t\t\t\tfail(err)\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t}\n\tswitch out.Kind() {\n\tcase reflect.String:\n\t\tif tag == binaryTag {\n\t\t\tout.SetString(resolved.(string))\n\t\t\treturn true\n\t\t}\n\t\tout.SetString(n.Value)\n\t\treturn true\n\tcase reflect.Interface:\n\t\tout.Set(reflect.ValueOf(resolved))\n\t\treturn true\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\t// This used to work in v2, but it's very unfriendly.\n\t\tisDuration := out.Type() == durationType\n\n\t\tswitch resolved := resolved.(type) {\n\t\tcase int:\n\t\t\tif !isDuration && !out.OverflowInt(int64(resolved)) {\n\t\t\t\tout.SetInt(int64(resolved))\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase int64:\n\t\t\tif !isDuration && !out.OverflowInt(resolved) {\n\t\t\t\tout.SetInt(resolved)\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase uint64:\n\t\t\tif !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {\n\t\t\t\tout.SetInt(int64(resolved))\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase float64:\n\t\t\tif !isDuration && resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {\n\t\t\t\tout.SetInt(int64(resolved))\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase string:\n\t\t\tif out.Type() == durationType {\n\t\t\t\td, err := time.ParseDuration(resolved)\n\t\t\t\tif err == nil {\n\t\t\t\t\tout.SetInt(int64(d))\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\tswitch resolved := resolved.(type) {\n\t\tcase int:\n\t\t\tif resolved >= 0 && !out.OverflowUint(uint64(resolved)) {\n\t\t\t\tout.SetUint(uint64(resolved))\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase int64:\n\t\t\tif resolved >= 0 && !out.OverflowUint(uint64(resolved)) {\n\t\t\t\tout.SetUint(uint64(resolved))\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase uint64:\n\t\t\tif !out.OverflowUint(uint64(resolved)) {\n\t\t\t\tout.SetUint(uint64(resolved))\n\t\t\t\treturn true\n\t\t\t}\n\t\tcase float64:\n\t\t\tif resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {\n\t\t\t\tout.SetUint(uint64(resolved))\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase reflect.Bool:\n\t\tswitch resolved := resolved.(type) {\n\t\tcase bool:\n\t\t\tout.SetBool(resolved)\n\t\t\treturn true\n\t\tcase string:\n\t\t\t// This offers some compatibility with the 1.1 spec (https://yaml.org/type/bool.html).\n\t\t\t// It only works if explicitly attempting to unmarshal into a typed bool value.\n\t\t\tswitch resolved {\n\t\t\tcase \"y\", \"Y\", \"yes\", \"Yes\", \"YES\", \"on\", \"On\", \"ON\":\n\t\t\t\tout.SetBool(true)\n\t\t\t\treturn true\n\t\t\tcase \"n\", \"N\", \"no\", \"No\", \"NO\", \"off\", \"Off\", \"OFF\":\n\t\t\t\tout.SetBool(false)\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase reflect.Float32, reflect.Float64:\n\t\tswitch resolved := resolved.(type) {\n\t\tcase int:\n\t\t\tout.SetFloat(float64(resolved))\n\t\t\treturn true\n\t\tcase int64:\n\t\t\tout.SetFloat(float64(resolved))\n\t\t\treturn true\n\t\tcase uint64:\n\t\t\tout.SetFloat(float64(resolved))\n\t\t\treturn true\n\t\tcase float64:\n\t\t\tout.SetFloat(resolved)\n\t\t\treturn true\n\t\t}\n\tcase reflect.Struct:\n\t\tif resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {\n\t\t\tout.Set(resolvedv)\n\t\t\treturn true\n\t\t}\n\tcase reflect.Ptr:\n\t\tpanic(\"yaml internal error: please report the issue\")\n\t}\n\td.terror(n, tag, out)\n\treturn false\n}\n\nfunc settableValueOf(i interface{}) reflect.Value {\n\tv := reflect.ValueOf(i)\n\tsv := reflect.New(v.Type()).Elem()\n\tsv.Set(v)\n\treturn sv\n}\n\nfunc (d *decoder) sequence(n *Node, out reflect.Value) (good bool) {\n\tl := len(n.Content)\n\n\tvar iface reflect.Value\n\tswitch out.Kind() {\n\tcase reflect.Slice:\n\t\tout.Set(reflect.MakeSlice(out.Type(), l, l))\n\tcase reflect.Array:\n\t\tif l != out.Len() {\n\t\t\tfailf(\"invalid array: want %d elements but got %d\", out.Len(), l)\n\t\t}\n\tcase reflect.Interface:\n\t\t// No type hints. Will have to use a generic sequence.\n\t\tiface = out\n\t\tout = settableValueOf(make([]interface{}, l))\n\tdefault:\n\t\td.terror(n, seqTag, out)\n\t\treturn false\n\t}\n\tet := out.Type().Elem()\n\n\tj := 0\n\tfor i := 0; i < l; i++ {\n\t\te := reflect.New(et).Elem()\n\t\tif d.origin {\n\t\t\taddOriginInSeq(n.Content[i])\n\t\t}\n\t\tif ok := d.unmarshal(n.Content[i], e); ok {\n\t\t\tout.Index(j).Set(e)\n\t\t\tj++\n\t\t}\n\t}\n\tif out.Kind() != reflect.Array {\n\t\tout.Set(out.Slice(0, j))\n\t}\n\tif iface.IsValid() {\n\t\tiface.Set(out)\n\t}\n\treturn true\n}\n\nfunc (d *decoder) mapping(n *Node, out reflect.Value) (good bool) {\n\tl := len(n.Content)\n\tif d.uniqueKeys {\n\t\tnerrs := len(d.terrors)\n\t\tfor i := 0; i < l; i += 2 {\n\t\t\tni := n.Content[i]\n\t\t\tfor j := i + 2; j < l; j += 2 {\n\t\t\t\tnj := n.Content[j]\n\t\t\t\tif ni.Kind == nj.Kind && ni.Value == nj.Value {\n\t\t\t\t\td.terrors = append(d.terrors, fmt.Sprintf(\"line %d: mapping key %#v already defined at line %d\", nj.Line, nj.Value, ni.Line))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif len(d.terrors) > nerrs {\n\t\t\treturn false\n\t\t}\n\t}\n\tswitch out.Kind() {\n\tcase reflect.Struct:\n\t\treturn d.mappingStruct(n, out)\n\tcase reflect.Map:\n\t\t// okay\n\tcase reflect.Interface:\n\t\tiface := out\n\t\tif isStringMap(n) {\n\t\t\tout = reflect.MakeMap(d.stringMapType)\n\t\t} else {\n\t\t\tout = reflect.MakeMap(d.generalMapType)\n\t\t}\n\t\tiface.Set(out)\n\tdefault:\n\t\td.terror(n, mapTag, out)\n\t\treturn false\n\t}\n\n\toutt := out.Type()\n\tkt := outt.Key()\n\tet := outt.Elem()\n\n\tstringMapType := d.stringMapType\n\tgeneralMapType := d.generalMapType\n\tif outt.Elem() == ifaceType {\n\t\tif outt.Key().Kind() == reflect.String {\n\t\t\td.stringMapType = outt\n\t\t} else if outt.Key() == ifaceType {\n\t\t\td.generalMapType = outt\n\t\t}\n\t}\n\n\tmergedFields := d.mergedFields\n\td.mergedFields = nil\n\n\tvar mergeNode *Node\n\n\tmapIsNew := false\n\tif out.IsNil() {\n\t\tout.Set(reflect.MakeMap(outt))\n\t\tmapIsNew = true\n\t}\n\tfor i := 0; i < l; i += 2 {\n\t\tif isMerge(n.Content[i]) {\n\t\t\tmergeNode = n.Content[i+1]\n\t\t\tcontinue\n\t\t}\n\t\tk := reflect.New(kt).Elem()\n\t\tif d.unmarshal(n.Content[i], k) {\n\t\t\tif mergedFields != nil {\n\t\t\t\tki := k.Interface()\n\t\t\t\tif mergedFields[ki] {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tmergedFields[ki] = true\n\t\t\t}\n\t\t\tkkind := k.Kind()\n\t\t\tif kkind == reflect.Interface {\n\t\t\t\tkkind = k.Elem().Kind()\n\t\t\t}\n\t\t\tif kkind == reflect.Map || kkind == reflect.Slice {\n\t\t\t\tfailf(\"invalid map key: %#v\", k.Interface())\n\t\t\t}\n\t\t\te := reflect.New(et).Elem()\n\n\t\t\tif d.origin {\n\t\t\t\taddOriginInMap(n.Content[i], n.Content[i+1])\n\t\t\t}\n\t\t\tif d.unmarshal(n.Content[i+1], e) || n.Content[i+1].ShortTag() == nullTag && (mapIsNew || !out.MapIndex(k).IsValid()) {\n\t\t\t\tout.SetMapIndex(k, e)\n\t\t\t}\n\t\t}\n\t}\n\n\td.mergedFields = mergedFields\n\tif mergeNode != nil {\n\t\td.merge(n, mergeNode, out)\n\t}\n\n\td.stringMapType = stringMapType\n\td.generalMapType = generalMapType\n\treturn true\n}\n\nfunc isStringMap(n *Node) bool {\n\tif n.Kind != MappingNode {\n\t\treturn false\n\t}\n\tl := len(n.Content)\n\tfor i := 0; i < l; i += 2 {\n\t\tshortTag := n.Content[i].ShortTag()\n\t\tif shortTag != strTag && shortTag != mergeTag {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (d *decoder) mappingStruct(n *Node, out reflect.Value) (good bool) {\n\tsinfo, err := getStructInfo(out.Type())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tvar inlineMap reflect.Value\n\tvar elemType reflect.Type\n\tif sinfo.InlineMap != -1 {\n\t\tinlineMap = out.Field(sinfo.InlineMap)\n\t\telemType = inlineMap.Type().Elem()\n\t}\n\n\tfor _, index := range sinfo.InlineUnmarshalers {\n\t\tfield := d.fieldByIndex(n, out, index)\n\t\td.prepare(n, field)\n\t}\n\n\tmergedFields := d.mergedFields\n\td.mergedFields = nil\n\tvar mergeNode *Node\n\tvar doneFields []bool\n\tif d.uniqueKeys {\n\t\tdoneFields = make([]bool, len(sinfo.FieldsList))\n\t}\n\tname := settableValueOf(\"\")\n\tl := len(n.Content)\n\tfor i := 0; i < l; i += 2 {\n\t\tni := n.Content[i]\n\t\tif isMerge(ni) {\n\t\t\tmergeNode = n.Content[i+1]\n\t\t\tcontinue\n\t\t}\n\t\tif !d.unmarshal(ni, name) {\n\t\t\tcontinue\n\t\t}\n\t\tsname := name.String()\n\t\tif mergedFields != nil {\n\t\t\tif mergedFields[sname] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmergedFields[sname] = true\n\t\t}\n\t\tif info, ok := sinfo.FieldsMap[sname]; ok {\n\t\t\tif d.uniqueKeys {\n\t\t\t\tif doneFields[info.Id] {\n\t\t\t\t\td.terrors = append(d.terrors, fmt.Sprintf(\"line %d: field %s already set in type %s\", ni.Line, name.String(), out.Type()))\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tdoneFields[info.Id] = true\n\t\t\t}\n\t\t\tvar field reflect.Value\n\t\t\tif info.Inline == nil {\n\t\t\t\tfield = out.Field(info.Num)\n\t\t\t} else {\n\t\t\t\tfield = d.fieldByIndex(n, out, info.Inline)\n\t\t\t}\n\t\t\td.unmarshal(n.Content[i+1], field)\n\t\t} else if sinfo.InlineMap != -1 {\n\t\t\tif inlineMap.IsNil() {\n\t\t\t\tinlineMap.Set(reflect.MakeMap(inlineMap.Type()))\n\t\t\t}\n\t\t\tvalue := reflect.New(elemType).Elem()\n\t\t\td.unmarshal(n.Content[i+1], value)\n\t\t\tinlineMap.SetMapIndex(name, value)\n\t\t} else if d.knownFields {\n\t\t\td.terrors = append(d.terrors, fmt.Sprintf(\"line %d: field %s not found in type %s\", ni.Line, name.String(), out.Type()))\n\t\t}\n\t}\n\n\td.mergedFields = mergedFields\n\tif mergeNode != nil {\n\t\td.merge(n, mergeNode, out)\n\t}\n\treturn true\n}\n\nfunc failWantMap() {\n\tfailf(\"map merge requires map or sequence of maps as the value\")\n}\n\nfunc (d *decoder) merge(parent *Node, merge *Node, out reflect.Value) {\n\tmergedFields := d.mergedFields\n\tif mergedFields == nil {\n\t\td.mergedFields = make(map[interface{}]bool)\n\t\tfor i := 0; i < len(parent.Content); i += 2 {\n\t\t\tk := reflect.New(ifaceType).Elem()\n\t\t\tif d.unmarshal(parent.Content[i], k) {\n\t\t\t\td.mergedFields[k.Interface()] = true\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch merge.Kind {\n\tcase MappingNode:\n\t\td.unmarshal(merge, out)\n\tcase AliasNode:\n\t\tif merge.Alias != nil && merge.Alias.Kind != MappingNode {\n\t\t\tfailWantMap()\n\t\t}\n\t\td.unmarshal(merge, out)\n\tcase SequenceNode:\n\t\tfor i := 0; i < len(merge.Content); i++ {\n\t\t\tni := merge.Content[i]\n\t\t\tif ni.Kind == AliasNode {\n\t\t\t\tif ni.Alias != nil && ni.Alias.Kind != MappingNode {\n\t\t\t\t\tfailWantMap()\n\t\t\t\t}\n\t\t\t} else if ni.Kind != MappingNode {\n\t\t\t\tfailWantMap()\n\t\t\t}\n\t\t\td.unmarshal(ni, out)\n\t\t}\n\tdefault:\n\t\tfailWantMap()\n\t}\n\n\td.mergedFields = mergedFields\n}\n\nfunc isMerge(n *Node) bool {\n\treturn n.Kind == ScalarNode && n.Value == \"<<\" && (n.Tag == \"\" || n.Tag == \"!\" || shortTag(n.Tag) == mergeTag)\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/emitterc.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n)\n\n// Flush the buffer if needed.\nfunc flush(emitter *yaml_emitter_t) bool {\n\tif emitter.buffer_pos+5 >= len(emitter.buffer) {\n\t\treturn yaml_emitter_flush(emitter)\n\t}\n\treturn true\n}\n\n// Put a character to the output buffer.\nfunc put(emitter *yaml_emitter_t, value byte) bool {\n\tif emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {\n\t\treturn false\n\t}\n\temitter.buffer[emitter.buffer_pos] = value\n\temitter.buffer_pos++\n\temitter.column++\n\treturn true\n}\n\n// Put a line break to the output buffer.\nfunc put_break(emitter *yaml_emitter_t) bool {\n\tif emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {\n\t\treturn false\n\t}\n\tswitch emitter.line_break {\n\tcase yaml_CR_BREAK:\n\t\temitter.buffer[emitter.buffer_pos] = '\\r'\n\t\temitter.buffer_pos += 1\n\tcase yaml_LN_BREAK:\n\t\temitter.buffer[emitter.buffer_pos] = '\\n'\n\t\temitter.buffer_pos += 1\n\tcase yaml_CRLN_BREAK:\n\t\temitter.buffer[emitter.buffer_pos+0] = '\\r'\n\t\temitter.buffer[emitter.buffer_pos+1] = '\\n'\n\t\temitter.buffer_pos += 2\n\tdefault:\n\t\tpanic(\"unknown line break setting\")\n\t}\n\tif emitter.column == 0 {\n\t\temitter.space_above = true\n\t}\n\temitter.column = 0\n\temitter.line++\n\t// [Go] Do this here and below and drop from everywhere else (see commented lines).\n\temitter.indention = true\n\treturn true\n}\n\n// Copy a character from a string into buffer.\nfunc write(emitter *yaml_emitter_t, s []byte, i *int) bool {\n\tif emitter.buffer_pos+5 >= len(emitter.buffer) && !yaml_emitter_flush(emitter) {\n\t\treturn false\n\t}\n\tp := emitter.buffer_pos\n\tw := width(s[*i])\n\tswitch w {\n\tcase 4:\n\t\temitter.buffer[p+3] = s[*i+3]\n\t\tfallthrough\n\tcase 3:\n\t\temitter.buffer[p+2] = s[*i+2]\n\t\tfallthrough\n\tcase 2:\n\t\temitter.buffer[p+1] = s[*i+1]\n\t\tfallthrough\n\tcase 1:\n\t\temitter.buffer[p+0] = s[*i+0]\n\tdefault:\n\t\tpanic(\"unknown character width\")\n\t}\n\temitter.column++\n\temitter.buffer_pos += w\n\t*i += w\n\treturn true\n}\n\n// Write a whole string into buffer.\nfunc write_all(emitter *yaml_emitter_t, s []byte) bool {\n\tfor i := 0; i < len(s); {\n\t\tif !write(emitter, s, &i) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Copy a line break character from a string into buffer.\nfunc write_break(emitter *yaml_emitter_t, s []byte, i *int) bool {\n\tif s[*i] == '\\n' {\n\t\tif !put_break(emitter) {\n\t\t\treturn false\n\t\t}\n\t\t*i++\n\t} else {\n\t\tif !write(emitter, s, i) {\n\t\t\treturn false\n\t\t}\n\t\tif emitter.column == 0 {\n\t\t\temitter.space_above = true\n\t\t}\n\t\temitter.column = 0\n\t\temitter.line++\n\t\t// [Go] Do this here and above and drop from everywhere else (see commented lines).\n\t\temitter.indention = true\n\t}\n\treturn true\n}\n\n// Set an emitter error and return false.\nfunc yaml_emitter_set_emitter_error(emitter *yaml_emitter_t, problem string) bool {\n\temitter.error = yaml_EMITTER_ERROR\n\temitter.problem = problem\n\treturn false\n}\n\n// Emit an event.\nfunc yaml_emitter_emit(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\temitter.events = append(emitter.events, *event)\n\tfor !yaml_emitter_need_more_events(emitter) {\n\t\tevent := &emitter.events[emitter.events_head]\n\t\tif !yaml_emitter_analyze_event(emitter, event) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_state_machine(emitter, event) {\n\t\t\treturn false\n\t\t}\n\t\tyaml_event_delete(event)\n\t\temitter.events_head++\n\t}\n\treturn true\n}\n\n// Check if we need to accumulate more events before emitting.\n//\n// We accumulate extra\n//  - 1 event for DOCUMENT-START\n//  - 2 events for SEQUENCE-START\n//  - 3 events for MAPPING-START\n//\nfunc yaml_emitter_need_more_events(emitter *yaml_emitter_t) bool {\n\tif emitter.events_head == len(emitter.events) {\n\t\treturn true\n\t}\n\tvar accumulate int\n\tswitch emitter.events[emitter.events_head].typ {\n\tcase yaml_DOCUMENT_START_EVENT:\n\t\taccumulate = 1\n\t\tbreak\n\tcase yaml_SEQUENCE_START_EVENT:\n\t\taccumulate = 2\n\t\tbreak\n\tcase yaml_MAPPING_START_EVENT:\n\t\taccumulate = 3\n\t\tbreak\n\tdefault:\n\t\treturn false\n\t}\n\tif len(emitter.events)-emitter.events_head > accumulate {\n\t\treturn false\n\t}\n\tvar level int\n\tfor i := emitter.events_head; i < len(emitter.events); i++ {\n\t\tswitch emitter.events[i].typ {\n\t\tcase yaml_STREAM_START_EVENT, yaml_DOCUMENT_START_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT:\n\t\t\tlevel++\n\t\tcase yaml_STREAM_END_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_END_EVENT, yaml_MAPPING_END_EVENT:\n\t\t\tlevel--\n\t\t}\n\t\tif level == 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Append a directive to the directives stack.\nfunc yaml_emitter_append_tag_directive(emitter *yaml_emitter_t, value *yaml_tag_directive_t, allow_duplicates bool) bool {\n\tfor i := 0; i < len(emitter.tag_directives); i++ {\n\t\tif bytes.Equal(value.handle, emitter.tag_directives[i].handle) {\n\t\t\tif allow_duplicates {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn yaml_emitter_set_emitter_error(emitter, \"duplicate %TAG directive\")\n\t\t}\n\t}\n\n\t// [Go] Do we actually need to copy this given garbage collection\n\t// and the lack of deallocating destructors?\n\ttag_copy := yaml_tag_directive_t{\n\t\thandle: make([]byte, len(value.handle)),\n\t\tprefix: make([]byte, len(value.prefix)),\n\t}\n\tcopy(tag_copy.handle, value.handle)\n\tcopy(tag_copy.prefix, value.prefix)\n\temitter.tag_directives = append(emitter.tag_directives, tag_copy)\n\treturn true\n}\n\n// Increase the indentation level.\nfunc yaml_emitter_increase_indent(emitter *yaml_emitter_t, flow, indentless bool) bool {\n\temitter.indents = append(emitter.indents, emitter.indent)\n\tif emitter.indent < 0 {\n\t\tif flow {\n\t\t\temitter.indent = emitter.best_indent\n\t\t} else {\n\t\t\temitter.indent = 0\n\t\t}\n\t} else if !indentless {\n\t\t// [Go] This was changed so that indentations are more regular.\n\t\tif emitter.states[len(emitter.states)-1] == yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE {\n\t\t\t// The first indent inside a sequence will just skip the \"- \" indicator.\n\t\t\temitter.indent += 2\n\t\t} else {\n\t\t\t// Everything else aligns to the chosen indentation.\n\t\t\temitter.indent = emitter.best_indent*((emitter.indent+emitter.best_indent)/emitter.best_indent)\n\t\t}\n\t}\n\treturn true\n}\n\n// State dispatcher.\nfunc yaml_emitter_state_machine(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\tswitch emitter.state {\n\tdefault:\n\tcase yaml_EMIT_STREAM_START_STATE:\n\t\treturn yaml_emitter_emit_stream_start(emitter, event)\n\n\tcase yaml_EMIT_FIRST_DOCUMENT_START_STATE:\n\t\treturn yaml_emitter_emit_document_start(emitter, event, true)\n\n\tcase yaml_EMIT_DOCUMENT_START_STATE:\n\t\treturn yaml_emitter_emit_document_start(emitter, event, false)\n\n\tcase yaml_EMIT_DOCUMENT_CONTENT_STATE:\n\t\treturn yaml_emitter_emit_document_content(emitter, event)\n\n\tcase yaml_EMIT_DOCUMENT_END_STATE:\n\t\treturn yaml_emitter_emit_document_end(emitter, event)\n\n\tcase yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE:\n\t\treturn yaml_emitter_emit_flow_sequence_item(emitter, event, true, false)\n\n\tcase yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE:\n\t\treturn yaml_emitter_emit_flow_sequence_item(emitter, event, false, true)\n\n\tcase yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE:\n\t\treturn yaml_emitter_emit_flow_sequence_item(emitter, event, false, false)\n\n\tcase yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE:\n\t\treturn yaml_emitter_emit_flow_mapping_key(emitter, event, true, false)\n\n\tcase yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE:\n\t\treturn yaml_emitter_emit_flow_mapping_key(emitter, event, false, true)\n\n\tcase yaml_EMIT_FLOW_MAPPING_KEY_STATE:\n\t\treturn yaml_emitter_emit_flow_mapping_key(emitter, event, false, false)\n\n\tcase yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE:\n\t\treturn yaml_emitter_emit_flow_mapping_value(emitter, event, true)\n\n\tcase yaml_EMIT_FLOW_MAPPING_VALUE_STATE:\n\t\treturn yaml_emitter_emit_flow_mapping_value(emitter, event, false)\n\n\tcase yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE:\n\t\treturn yaml_emitter_emit_block_sequence_item(emitter, event, true)\n\n\tcase yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE:\n\t\treturn yaml_emitter_emit_block_sequence_item(emitter, event, false)\n\n\tcase yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE:\n\t\treturn yaml_emitter_emit_block_mapping_key(emitter, event, true)\n\n\tcase yaml_EMIT_BLOCK_MAPPING_KEY_STATE:\n\t\treturn yaml_emitter_emit_block_mapping_key(emitter, event, false)\n\n\tcase yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE:\n\t\treturn yaml_emitter_emit_block_mapping_value(emitter, event, true)\n\n\tcase yaml_EMIT_BLOCK_MAPPING_VALUE_STATE:\n\t\treturn yaml_emitter_emit_block_mapping_value(emitter, event, false)\n\n\tcase yaml_EMIT_END_STATE:\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"expected nothing after STREAM-END\")\n\t}\n\tpanic(\"invalid emitter state\")\n}\n\n// Expect STREAM-START.\nfunc yaml_emitter_emit_stream_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\tif event.typ != yaml_STREAM_START_EVENT {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"expected STREAM-START\")\n\t}\n\tif emitter.encoding == yaml_ANY_ENCODING {\n\t\temitter.encoding = event.encoding\n\t\tif emitter.encoding == yaml_ANY_ENCODING {\n\t\t\temitter.encoding = yaml_UTF8_ENCODING\n\t\t}\n\t}\n\tif emitter.best_indent < 2 || emitter.best_indent > 9 {\n\t\temitter.best_indent = 2\n\t}\n\tif emitter.best_width >= 0 && emitter.best_width <= emitter.best_indent*2 {\n\t\temitter.best_width = 80\n\t}\n\tif emitter.best_width < 0 {\n\t\temitter.best_width = 1<<31 - 1\n\t}\n\tif emitter.line_break == yaml_ANY_BREAK {\n\t\temitter.line_break = yaml_LN_BREAK\n\t}\n\n\temitter.indent = -1\n\temitter.line = 0\n\temitter.column = 0\n\temitter.whitespace = true\n\temitter.indention = true\n\temitter.space_above = true\n\temitter.foot_indent = -1\n\n\tif emitter.encoding != yaml_UTF8_ENCODING {\n\t\tif !yaml_emitter_write_bom(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\temitter.state = yaml_EMIT_FIRST_DOCUMENT_START_STATE\n\treturn true\n}\n\n// Expect DOCUMENT-START or STREAM-END.\nfunc yaml_emitter_emit_document_start(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {\n\n\tif event.typ == yaml_DOCUMENT_START_EVENT {\n\n\t\tif event.version_directive != nil {\n\t\t\tif !yaml_emitter_analyze_version_directive(emitter, event.version_directive) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\tfor i := 0; i < len(event.tag_directives); i++ {\n\t\t\ttag_directive := &event.tag_directives[i]\n\t\t\tif !yaml_emitter_analyze_tag_directive(emitter, tag_directive) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !yaml_emitter_append_tag_directive(emitter, tag_directive, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\tfor i := 0; i < len(default_tag_directives); i++ {\n\t\t\ttag_directive := &default_tag_directives[i]\n\t\t\tif !yaml_emitter_append_tag_directive(emitter, tag_directive, true) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\timplicit := event.implicit\n\t\tif !first || emitter.canonical {\n\t\t\timplicit = false\n\t\t}\n\n\t\tif emitter.open_ended && (event.version_directive != nil || len(event.tag_directives) > 0) {\n\t\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"...\"), true, false, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\tif event.version_directive != nil {\n\t\t\timplicit = false\n\t\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"%YAML\"), true, false, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"1.1\"), true, false, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\tif len(event.tag_directives) > 0 {\n\t\t\timplicit = false\n\t\t\tfor i := 0; i < len(event.tag_directives); i++ {\n\t\t\t\ttag_directive := &event.tag_directives[i]\n\t\t\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"%TAG\"), true, false, false) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif !yaml_emitter_write_tag_handle(emitter, tag_directive.handle) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif !yaml_emitter_write_tag_content(emitter, tag_directive.prefix, true) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif yaml_emitter_check_empty_document(emitter) {\n\t\t\timplicit = false\n\t\t}\n\t\tif !implicit {\n\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"---\"), true, false, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif emitter.canonical || true {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif len(emitter.head_comment) > 0 {\n\t\t\tif !yaml_emitter_process_head_comment(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !put_break(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\temitter.state = yaml_EMIT_DOCUMENT_CONTENT_STATE\n\t\treturn true\n\t}\n\n\tif event.typ == yaml_STREAM_END_EVENT {\n\t\tif emitter.open_ended {\n\t\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"...\"), true, false, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !yaml_emitter_flush(emitter) {\n\t\t\treturn false\n\t\t}\n\t\temitter.state = yaml_EMIT_END_STATE\n\t\treturn true\n\t}\n\n\treturn yaml_emitter_set_emitter_error(emitter, \"expected DOCUMENT-START or STREAM-END\")\n}\n\n// Expect the root node.\nfunc yaml_emitter_emit_document_content(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\temitter.states = append(emitter.states, yaml_EMIT_DOCUMENT_END_STATE)\n\n\tif !yaml_emitter_process_head_comment(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_emit_node(emitter, event, true, false, false, false) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_line_comment(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Expect DOCUMENT-END.\nfunc yaml_emitter_emit_document_end(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\tif event.typ != yaml_DOCUMENT_END_EVENT {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"expected DOCUMENT-END\")\n\t}\n\t// [Go] Force document foot separation.\n\temitter.foot_indent = 0\n\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\treturn false\n\t}\n\temitter.foot_indent = -1\n\tif !yaml_emitter_write_indent(emitter) {\n\t\treturn false\n\t}\n\tif !event.implicit {\n\t\t// [Go] Allocate the slice elsewhere.\n\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"...\"), true, false, false) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !yaml_emitter_flush(emitter) {\n\t\treturn false\n\t}\n\temitter.state = yaml_EMIT_DOCUMENT_START_STATE\n\temitter.tag_directives = emitter.tag_directives[:0]\n\treturn true\n}\n\n// Expect a flow item node.\nfunc yaml_emitter_emit_flow_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {\n\tif first {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{'['}, true, true, false) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_increase_indent(emitter, true, false) {\n\t\t\treturn false\n\t\t}\n\t\temitter.flow_level++\n\t}\n\n\tif event.typ == yaml_SEQUENCE_END_EVENT {\n\t\tif emitter.canonical && !first && !trail {\n\t\t\tif !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\temitter.flow_level--\n\t\temitter.indent = emitter.indents[len(emitter.indents)-1]\n\t\temitter.indents = emitter.indents[:len(emitter.indents)-1]\n\t\tif emitter.column == 0 || emitter.canonical && !first {\n\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{']'}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_process_line_comment(emitter) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\t\treturn false\n\t\t}\n\t\temitter.state = emitter.states[len(emitter.states)-1]\n\t\temitter.states = emitter.states[:len(emitter.states)-1]\n\n\t\treturn true\n\t}\n\n\tif !first && !trail {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif !yaml_emitter_process_head_comment(emitter) {\n\t\treturn false\n\t}\n\tif emitter.column == 0 {\n\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif emitter.canonical || emitter.column > emitter.best_width {\n\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {\n\t\temitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE)\n\t} else {\n\t\temitter.states = append(emitter.states, yaml_EMIT_FLOW_SEQUENCE_ITEM_STATE)\n\t}\n\tif !yaml_emitter_emit_node(emitter, event, false, true, false, false) {\n\t\treturn false\n\t}\n\tif len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !yaml_emitter_process_line_comment(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Expect a flow key node.\nfunc yaml_emitter_emit_flow_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first, trail bool) bool {\n\tif first {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{'{'}, true, true, false) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_increase_indent(emitter, true, false) {\n\t\t\treturn false\n\t\t}\n\t\temitter.flow_level++\n\t}\n\n\tif event.typ == yaml_MAPPING_END_EVENT {\n\t\tif (emitter.canonical || len(emitter.head_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0) && !first && !trail {\n\t\t\tif !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !yaml_emitter_process_head_comment(emitter) {\n\t\t\treturn false\n\t\t}\n\t\temitter.flow_level--\n\t\temitter.indent = emitter.indents[len(emitter.indents)-1]\n\t\temitter.indents = emitter.indents[:len(emitter.indents)-1]\n\t\tif emitter.canonical && !first {\n\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{'}'}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_process_line_comment(emitter) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\t\treturn false\n\t\t}\n\t\temitter.state = emitter.states[len(emitter.states)-1]\n\t\temitter.states = emitter.states[:len(emitter.states)-1]\n\t\treturn true\n\t}\n\n\tif !first && !trail {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif !yaml_emitter_process_head_comment(emitter) {\n\t\treturn false\n\t}\n\n\tif emitter.column == 0 {\n\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif emitter.canonical || emitter.column > emitter.best_width {\n\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif !emitter.canonical && yaml_emitter_check_simple_key(emitter) {\n\t\temitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)\n\t\treturn yaml_emitter_emit_node(emitter, event, false, false, true, true)\n\t}\n\tif !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, false) {\n\t\treturn false\n\t}\n\temitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_VALUE_STATE)\n\treturn yaml_emitter_emit_node(emitter, event, false, false, true, false)\n}\n\n// Expect a flow value node.\nfunc yaml_emitter_emit_flow_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {\n\tif simple {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t} else {\n\t\tif emitter.canonical || emitter.column > emitter.best_width {\n\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {\n\t\temitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE)\n\t} else {\n\t\temitter.states = append(emitter.states, yaml_EMIT_FLOW_MAPPING_KEY_STATE)\n\t}\n\tif !yaml_emitter_emit_node(emitter, event, false, false, true, false) {\n\t\treturn false\n\t}\n\tif len(emitter.line_comment)+len(emitter.foot_comment)+len(emitter.tail_comment) > 0 {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{','}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !yaml_emitter_process_line_comment(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Expect a block item node.\nfunc yaml_emitter_emit_block_sequence_item(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {\n\tif first {\n\t\tif !yaml_emitter_increase_indent(emitter, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif event.typ == yaml_SEQUENCE_END_EVENT {\n\t\temitter.indent = emitter.indents[len(emitter.indents)-1]\n\t\temitter.indents = emitter.indents[:len(emitter.indents)-1]\n\t\temitter.state = emitter.states[len(emitter.states)-1]\n\t\temitter.states = emitter.states[:len(emitter.states)-1]\n\t\treturn true\n\t}\n\tif !yaml_emitter_process_head_comment(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_write_indent(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_write_indicator(emitter, []byte{'-'}, true, false, true) {\n\t\treturn false\n\t}\n\temitter.states = append(emitter.states, yaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE)\n\tif !yaml_emitter_emit_node(emitter, event, false, true, false, false) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_line_comment(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// Expect a block key node.\nfunc yaml_emitter_emit_block_mapping_key(emitter *yaml_emitter_t, event *yaml_event_t, first bool) bool {\n\tif first {\n\t\tif !yaml_emitter_increase_indent(emitter, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !yaml_emitter_process_head_comment(emitter) {\n\t\treturn false\n\t}\n\tif event.typ == yaml_MAPPING_END_EVENT {\n\t\temitter.indent = emitter.indents[len(emitter.indents)-1]\n\t\temitter.indents = emitter.indents[:len(emitter.indents)-1]\n\t\temitter.state = emitter.states[len(emitter.states)-1]\n\t\temitter.states = emitter.states[:len(emitter.states)-1]\n\t\treturn true\n\t}\n\tif !yaml_emitter_write_indent(emitter) {\n\t\treturn false\n\t}\n\tif len(emitter.line_comment) > 0 {\n\t\t// [Go] A line comment was provided for the key. That's unusual as the\n\t\t//      scanner associates line comments with the value. Either way,\n\t\t//      save the line comment and render it appropriately later.\n\t\temitter.key_line_comment = emitter.line_comment\n\t\temitter.line_comment = nil\n\t}\n\tif yaml_emitter_check_simple_key(emitter) {\n\t\temitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)\n\t\treturn yaml_emitter_emit_node(emitter, event, false, false, true, true)\n\t}\n\tif !yaml_emitter_write_indicator(emitter, []byte{'?'}, true, false, true) {\n\t\treturn false\n\t}\n\temitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_VALUE_STATE)\n\treturn yaml_emitter_emit_node(emitter, event, false, false, true, false)\n}\n\n// Expect a block value node.\nfunc yaml_emitter_emit_block_mapping_value(emitter *yaml_emitter_t, event *yaml_event_t, simple bool) bool {\n\tif simple {\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{':'}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t} else {\n\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{':'}, true, false, true) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif len(emitter.key_line_comment) > 0 {\n\t\t// [Go] Line comments are generally associated with the value, but when there's\n\t\t//      no value on the same line as a mapping key they end up attached to the\n\t\t//      key itself.\n\t\tif event.typ == yaml_SCALAR_EVENT {\n\t\t\tif len(emitter.line_comment) == 0 {\n\t\t\t\t// A scalar is coming and it has no line comments by itself yet,\n\t\t\t\t// so just let it handle the line comment as usual. If it has a\n\t\t\t\t// line comment, we can't have both so the one from the key is lost.\n\t\t\t\temitter.line_comment = emitter.key_line_comment\n\t\t\t\temitter.key_line_comment = nil\n\t\t\t}\n\t\t} else if event.sequence_style() != yaml_FLOW_SEQUENCE_STYLE && (event.typ == yaml_MAPPING_START_EVENT || event.typ == yaml_SEQUENCE_START_EVENT) {\n\t\t\t// An indented block follows, so write the comment right now.\n\t\t\temitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment\n\t\t\tif !yaml_emitter_process_line_comment(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\temitter.line_comment, emitter.key_line_comment = emitter.key_line_comment, emitter.line_comment\n\t\t}\n\t}\n\temitter.states = append(emitter.states, yaml_EMIT_BLOCK_MAPPING_KEY_STATE)\n\tif !yaml_emitter_emit_node(emitter, event, false, false, true, false) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_line_comment(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_foot_comment(emitter) {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc yaml_emitter_silent_nil_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\treturn event.typ == yaml_SCALAR_EVENT && event.implicit && !emitter.canonical && len(emitter.scalar_data.value) == 0\n}\n\n// Expect a node.\nfunc yaml_emitter_emit_node(emitter *yaml_emitter_t, event *yaml_event_t,\n\troot bool, sequence bool, mapping bool, simple_key bool) bool {\n\n\temitter.root_context = root\n\temitter.sequence_context = sequence\n\temitter.mapping_context = mapping\n\temitter.simple_key_context = simple_key\n\n\tswitch event.typ {\n\tcase yaml_ALIAS_EVENT:\n\t\treturn yaml_emitter_emit_alias(emitter, event)\n\tcase yaml_SCALAR_EVENT:\n\t\treturn yaml_emitter_emit_scalar(emitter, event)\n\tcase yaml_SEQUENCE_START_EVENT:\n\t\treturn yaml_emitter_emit_sequence_start(emitter, event)\n\tcase yaml_MAPPING_START_EVENT:\n\t\treturn yaml_emitter_emit_mapping_start(emitter, event)\n\tdefault:\n\t\treturn yaml_emitter_set_emitter_error(emitter,\n\t\t\tfmt.Sprintf(\"expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v\", event.typ))\n\t}\n}\n\n// Expect ALIAS.\nfunc yaml_emitter_emit_alias(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\tif !yaml_emitter_process_anchor(emitter) {\n\t\treturn false\n\t}\n\temitter.state = emitter.states[len(emitter.states)-1]\n\temitter.states = emitter.states[:len(emitter.states)-1]\n\treturn true\n}\n\n// Expect SCALAR.\nfunc yaml_emitter_emit_scalar(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\tif !yaml_emitter_select_scalar_style(emitter, event) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_anchor(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_tag(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_increase_indent(emitter, true, false) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_scalar(emitter) {\n\t\treturn false\n\t}\n\temitter.indent = emitter.indents[len(emitter.indents)-1]\n\temitter.indents = emitter.indents[:len(emitter.indents)-1]\n\temitter.state = emitter.states[len(emitter.states)-1]\n\temitter.states = emitter.states[:len(emitter.states)-1]\n\treturn true\n}\n\n// Expect SEQUENCE-START.\nfunc yaml_emitter_emit_sequence_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\tif !yaml_emitter_process_anchor(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_tag(emitter) {\n\t\treturn false\n\t}\n\tif emitter.flow_level > 0 || emitter.canonical || event.sequence_style() == yaml_FLOW_SEQUENCE_STYLE ||\n\t\tyaml_emitter_check_empty_sequence(emitter) {\n\t\temitter.state = yaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE\n\t} else {\n\t\temitter.state = yaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE\n\t}\n\treturn true\n}\n\n// Expect MAPPING-START.\nfunc yaml_emitter_emit_mapping_start(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\tif !yaml_emitter_process_anchor(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_tag(emitter) {\n\t\treturn false\n\t}\n\tif emitter.flow_level > 0 || emitter.canonical || event.mapping_style() == yaml_FLOW_MAPPING_STYLE ||\n\t\tyaml_emitter_check_empty_mapping(emitter) {\n\t\temitter.state = yaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE\n\t} else {\n\t\temitter.state = yaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE\n\t}\n\treturn true\n}\n\n// Check if the document content is an empty scalar.\nfunc yaml_emitter_check_empty_document(emitter *yaml_emitter_t) bool {\n\treturn false // [Go] Huh?\n}\n\n// Check if the next events represent an empty sequence.\nfunc yaml_emitter_check_empty_sequence(emitter *yaml_emitter_t) bool {\n\tif len(emitter.events)-emitter.events_head < 2 {\n\t\treturn false\n\t}\n\treturn emitter.events[emitter.events_head].typ == yaml_SEQUENCE_START_EVENT &&\n\t\temitter.events[emitter.events_head+1].typ == yaml_SEQUENCE_END_EVENT\n}\n\n// Check if the next events represent an empty mapping.\nfunc yaml_emitter_check_empty_mapping(emitter *yaml_emitter_t) bool {\n\tif len(emitter.events)-emitter.events_head < 2 {\n\t\treturn false\n\t}\n\treturn emitter.events[emitter.events_head].typ == yaml_MAPPING_START_EVENT &&\n\t\temitter.events[emitter.events_head+1].typ == yaml_MAPPING_END_EVENT\n}\n\n// Check if the next node can be expressed as a simple key.\nfunc yaml_emitter_check_simple_key(emitter *yaml_emitter_t) bool {\n\tlength := 0\n\tswitch emitter.events[emitter.events_head].typ {\n\tcase yaml_ALIAS_EVENT:\n\t\tlength += len(emitter.anchor_data.anchor)\n\tcase yaml_SCALAR_EVENT:\n\t\tif emitter.scalar_data.multiline {\n\t\t\treturn false\n\t\t}\n\t\tlength += len(emitter.anchor_data.anchor) +\n\t\t\tlen(emitter.tag_data.handle) +\n\t\t\tlen(emitter.tag_data.suffix) +\n\t\t\tlen(emitter.scalar_data.value)\n\tcase yaml_SEQUENCE_START_EVENT:\n\t\tif !yaml_emitter_check_empty_sequence(emitter) {\n\t\t\treturn false\n\t\t}\n\t\tlength += len(emitter.anchor_data.anchor) +\n\t\t\tlen(emitter.tag_data.handle) +\n\t\t\tlen(emitter.tag_data.suffix)\n\tcase yaml_MAPPING_START_EVENT:\n\t\tif !yaml_emitter_check_empty_mapping(emitter) {\n\t\t\treturn false\n\t\t}\n\t\tlength += len(emitter.anchor_data.anchor) +\n\t\t\tlen(emitter.tag_data.handle) +\n\t\t\tlen(emitter.tag_data.suffix)\n\tdefault:\n\t\treturn false\n\t}\n\treturn length <= 128\n}\n\n// Determine an acceptable scalar style.\nfunc yaml_emitter_select_scalar_style(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\n\tno_tag := len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0\n\tif no_tag && !event.implicit && !event.quoted_implicit {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"neither tag nor implicit flags are specified\")\n\t}\n\n\tstyle := event.scalar_style()\n\tif style == yaml_ANY_SCALAR_STYLE {\n\t\tstyle = yaml_PLAIN_SCALAR_STYLE\n\t}\n\tif emitter.canonical {\n\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t}\n\tif emitter.simple_key_context && emitter.scalar_data.multiline {\n\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t}\n\n\tif style == yaml_PLAIN_SCALAR_STYLE {\n\t\tif emitter.flow_level > 0 && !emitter.scalar_data.flow_plain_allowed ||\n\t\t\temitter.flow_level == 0 && !emitter.scalar_data.block_plain_allowed {\n\t\t\tstyle = yaml_SINGLE_QUOTED_SCALAR_STYLE\n\t\t}\n\t\tif len(emitter.scalar_data.value) == 0 && (emitter.flow_level > 0 || emitter.simple_key_context) {\n\t\t\tstyle = yaml_SINGLE_QUOTED_SCALAR_STYLE\n\t\t}\n\t\tif no_tag && !event.implicit {\n\t\t\tstyle = yaml_SINGLE_QUOTED_SCALAR_STYLE\n\t\t}\n\t}\n\tif style == yaml_SINGLE_QUOTED_SCALAR_STYLE {\n\t\tif !emitter.scalar_data.single_quoted_allowed {\n\t\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t\t}\n\t}\n\tif style == yaml_LITERAL_SCALAR_STYLE || style == yaml_FOLDED_SCALAR_STYLE {\n\t\tif !emitter.scalar_data.block_allowed || emitter.flow_level > 0 || emitter.simple_key_context {\n\t\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t\t}\n\t}\n\n\tif no_tag && !event.quoted_implicit && style != yaml_PLAIN_SCALAR_STYLE {\n\t\temitter.tag_data.handle = []byte{'!'}\n\t}\n\temitter.scalar_data.style = style\n\treturn true\n}\n\n// Write an anchor.\nfunc yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {\n\tif emitter.anchor_data.anchor == nil {\n\t\treturn true\n\t}\n\tc := []byte{'&'}\n\tif emitter.anchor_data.alias {\n\t\tc[0] = '*'\n\t}\n\tif !yaml_emitter_write_indicator(emitter, c, true, false, false) {\n\t\treturn false\n\t}\n\treturn yaml_emitter_write_anchor(emitter, emitter.anchor_data.anchor)\n}\n\n// Write a tag.\nfunc yaml_emitter_process_tag(emitter *yaml_emitter_t) bool {\n\tif len(emitter.tag_data.handle) == 0 && len(emitter.tag_data.suffix) == 0 {\n\t\treturn true\n\t}\n\tif len(emitter.tag_data.handle) > 0 {\n\t\tif !yaml_emitter_write_tag_handle(emitter, emitter.tag_data.handle) {\n\t\t\treturn false\n\t\t}\n\t\tif len(emitter.tag_data.suffix) > 0 {\n\t\t\tif !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// [Go] Allocate these slices elsewhere.\n\t\tif !yaml_emitter_write_indicator(emitter, []byte(\"!<\"), true, false, false) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_write_tag_content(emitter, emitter.tag_data.suffix, false) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_write_indicator(emitter, []byte{'>'}, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Write a scalar.\nfunc yaml_emitter_process_scalar(emitter *yaml_emitter_t) bool {\n\tswitch emitter.scalar_data.style {\n\tcase yaml_PLAIN_SCALAR_STYLE:\n\t\treturn yaml_emitter_write_plain_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)\n\n\tcase yaml_SINGLE_QUOTED_SCALAR_STYLE:\n\t\treturn yaml_emitter_write_single_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)\n\n\tcase yaml_DOUBLE_QUOTED_SCALAR_STYLE:\n\t\treturn yaml_emitter_write_double_quoted_scalar(emitter, emitter.scalar_data.value, !emitter.simple_key_context)\n\n\tcase yaml_LITERAL_SCALAR_STYLE:\n\t\treturn yaml_emitter_write_literal_scalar(emitter, emitter.scalar_data.value)\n\n\tcase yaml_FOLDED_SCALAR_STYLE:\n\t\treturn yaml_emitter_write_folded_scalar(emitter, emitter.scalar_data.value)\n\t}\n\tpanic(\"unknown scalar style\")\n}\n\n// Write a head comment.\nfunc yaml_emitter_process_head_comment(emitter *yaml_emitter_t) bool {\n\tif len(emitter.tail_comment) > 0 {\n\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\treturn false\n\t\t}\n\t\tif !yaml_emitter_write_comment(emitter, emitter.tail_comment) {\n\t\t\treturn false\n\t\t}\n\t\temitter.tail_comment = emitter.tail_comment[:0]\n\t\temitter.foot_indent = emitter.indent\n\t\tif emitter.foot_indent < 0 {\n\t\t\temitter.foot_indent = 0\n\t\t}\n\t}\n\n\tif len(emitter.head_comment) == 0 {\n\t\treturn true\n\t}\n\tif !yaml_emitter_write_indent(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_write_comment(emitter, emitter.head_comment) {\n\t\treturn false\n\t}\n\temitter.head_comment = emitter.head_comment[:0]\n\treturn true\n}\n\n// Write an line comment.\nfunc yaml_emitter_process_line_comment(emitter *yaml_emitter_t) bool {\n\tif len(emitter.line_comment) == 0 {\n\t\treturn true\n\t}\n\tif !emitter.whitespace {\n\t\tif !put(emitter, ' ') {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !yaml_emitter_write_comment(emitter, emitter.line_comment) {\n\t\treturn false\n\t}\n\temitter.line_comment = emitter.line_comment[:0]\n\treturn true\n}\n\n// Write a foot comment.\nfunc yaml_emitter_process_foot_comment(emitter *yaml_emitter_t) bool {\n\tif len(emitter.foot_comment) == 0 {\n\t\treturn true\n\t}\n\tif !yaml_emitter_write_indent(emitter) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_write_comment(emitter, emitter.foot_comment) {\n\t\treturn false\n\t}\n\temitter.foot_comment = emitter.foot_comment[:0]\n\temitter.foot_indent = emitter.indent\n\tif emitter.foot_indent < 0 {\n\t\temitter.foot_indent = 0\n\t}\n\treturn true\n}\n\n// Check if a %YAML directive is valid.\nfunc yaml_emitter_analyze_version_directive(emitter *yaml_emitter_t, version_directive *yaml_version_directive_t) bool {\n\tif version_directive.major != 1 || version_directive.minor != 1 {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"incompatible %YAML directive\")\n\t}\n\treturn true\n}\n\n// Check if a %TAG directive is valid.\nfunc yaml_emitter_analyze_tag_directive(emitter *yaml_emitter_t, tag_directive *yaml_tag_directive_t) bool {\n\thandle := tag_directive.handle\n\tprefix := tag_directive.prefix\n\tif len(handle) == 0 {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"tag handle must not be empty\")\n\t}\n\tif handle[0] != '!' {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"tag handle must start with '!'\")\n\t}\n\tif handle[len(handle)-1] != '!' {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"tag handle must end with '!'\")\n\t}\n\tfor i := 1; i < len(handle)-1; i += width(handle[i]) {\n\t\tif !is_alpha(handle, i) {\n\t\t\treturn yaml_emitter_set_emitter_error(emitter, \"tag handle must contain alphanumerical characters only\")\n\t\t}\n\t}\n\tif len(prefix) == 0 {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"tag prefix must not be empty\")\n\t}\n\treturn true\n}\n\n// Check if an anchor is valid.\nfunc yaml_emitter_analyze_anchor(emitter *yaml_emitter_t, anchor []byte, alias bool) bool {\n\tif len(anchor) == 0 {\n\t\tproblem := \"anchor value must not be empty\"\n\t\tif alias {\n\t\t\tproblem = \"alias value must not be empty\"\n\t\t}\n\t\treturn yaml_emitter_set_emitter_error(emitter, problem)\n\t}\n\tfor i := 0; i < len(anchor); i += width(anchor[i]) {\n\t\tif !is_alpha(anchor, i) {\n\t\t\tproblem := \"anchor value must contain alphanumerical characters only\"\n\t\t\tif alias {\n\t\t\t\tproblem = \"alias value must contain alphanumerical characters only\"\n\t\t\t}\n\t\t\treturn yaml_emitter_set_emitter_error(emitter, problem)\n\t\t}\n\t}\n\temitter.anchor_data.anchor = anchor\n\temitter.anchor_data.alias = alias\n\treturn true\n}\n\n// Check if a tag is valid.\nfunc yaml_emitter_analyze_tag(emitter *yaml_emitter_t, tag []byte) bool {\n\tif len(tag) == 0 {\n\t\treturn yaml_emitter_set_emitter_error(emitter, \"tag value must not be empty\")\n\t}\n\tfor i := 0; i < len(emitter.tag_directives); i++ {\n\t\ttag_directive := &emitter.tag_directives[i]\n\t\tif bytes.HasPrefix(tag, tag_directive.prefix) {\n\t\t\temitter.tag_data.handle = tag_directive.handle\n\t\t\temitter.tag_data.suffix = tag[len(tag_directive.prefix):]\n\t\t\treturn true\n\t\t}\n\t}\n\temitter.tag_data.suffix = tag\n\treturn true\n}\n\n// Check if a scalar is valid.\nfunc yaml_emitter_analyze_scalar(emitter *yaml_emitter_t, value []byte) bool {\n\tvar (\n\t\tblock_indicators   = false\n\t\tflow_indicators    = false\n\t\tline_breaks        = false\n\t\tspecial_characters = false\n\t\ttab_characters     = false\n\n\t\tleading_space  = false\n\t\tleading_break  = false\n\t\ttrailing_space = false\n\t\ttrailing_break = false\n\t\tbreak_space    = false\n\t\tspace_break    = false\n\n\t\tpreceded_by_whitespace = false\n\t\tfollowed_by_whitespace = false\n\t\tprevious_space         = false\n\t\tprevious_break         = false\n\t)\n\n\temitter.scalar_data.value = value\n\n\tif len(value) == 0 {\n\t\temitter.scalar_data.multiline = false\n\t\temitter.scalar_data.flow_plain_allowed = false\n\t\temitter.scalar_data.block_plain_allowed = true\n\t\temitter.scalar_data.single_quoted_allowed = true\n\t\temitter.scalar_data.block_allowed = false\n\t\treturn true\n\t}\n\n\tif len(value) >= 3 && ((value[0] == '-' && value[1] == '-' && value[2] == '-') || (value[0] == '.' && value[1] == '.' && value[2] == '.')) {\n\t\tblock_indicators = true\n\t\tflow_indicators = true\n\t}\n\n\tpreceded_by_whitespace = true\n\tfor i, w := 0, 0; i < len(value); i += w {\n\t\tw = width(value[i])\n\t\tfollowed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)\n\n\t\tif i == 0 {\n\t\t\tswitch value[i] {\n\t\t\tcase '#', ',', '[', ']', '{', '}', '&', '*', '!', '|', '>', '\\'', '\"', '%', '@', '`':\n\t\t\t\tflow_indicators = true\n\t\t\t\tblock_indicators = true\n\t\t\tcase '?', ':':\n\t\t\t\tflow_indicators = true\n\t\t\t\tif followed_by_whitespace {\n\t\t\t\t\tblock_indicators = true\n\t\t\t\t}\n\t\t\tcase '-':\n\t\t\t\tif followed_by_whitespace {\n\t\t\t\t\tflow_indicators = true\n\t\t\t\t\tblock_indicators = true\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tswitch value[i] {\n\t\t\tcase ',', '?', '[', ']', '{', '}':\n\t\t\t\tflow_indicators = true\n\t\t\tcase ':':\n\t\t\t\tflow_indicators = true\n\t\t\t\tif followed_by_whitespace {\n\t\t\t\t\tblock_indicators = true\n\t\t\t\t}\n\t\t\tcase '#':\n\t\t\t\tif preceded_by_whitespace {\n\t\t\t\t\tflow_indicators = true\n\t\t\t\t\tblock_indicators = true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif value[i] == '\\t' {\n\t\t\ttab_characters = true\n\t\t} else if !is_printable(value, i) || !is_ascii(value, i) && !emitter.unicode {\n\t\t\tspecial_characters = true\n\t\t}\n\t\tif is_space(value, i) {\n\t\t\tif i == 0 {\n\t\t\t\tleading_space = true\n\t\t\t}\n\t\t\tif i+width(value[i]) == len(value) {\n\t\t\t\ttrailing_space = true\n\t\t\t}\n\t\t\tif previous_break {\n\t\t\t\tbreak_space = true\n\t\t\t}\n\t\t\tprevious_space = true\n\t\t\tprevious_break = false\n\t\t} else if is_break(value, i) {\n\t\t\tline_breaks = true\n\t\t\tif i == 0 {\n\t\t\t\tleading_break = true\n\t\t\t}\n\t\t\tif i+width(value[i]) == len(value) {\n\t\t\t\ttrailing_break = true\n\t\t\t}\n\t\t\tif previous_space {\n\t\t\t\tspace_break = true\n\t\t\t}\n\t\t\tprevious_space = false\n\t\t\tprevious_break = true\n\t\t} else {\n\t\t\tprevious_space = false\n\t\t\tprevious_break = false\n\t\t}\n\n\t\t// [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.\n\t\tpreceded_by_whitespace = is_blankz(value, i)\n\t}\n\n\temitter.scalar_data.multiline = line_breaks\n\temitter.scalar_data.flow_plain_allowed = true\n\temitter.scalar_data.block_plain_allowed = true\n\temitter.scalar_data.single_quoted_allowed = true\n\temitter.scalar_data.block_allowed = true\n\n\tif leading_space || leading_break || trailing_space || trailing_break {\n\t\temitter.scalar_data.flow_plain_allowed = false\n\t\temitter.scalar_data.block_plain_allowed = false\n\t}\n\tif trailing_space {\n\t\temitter.scalar_data.block_allowed = false\n\t}\n\tif break_space {\n\t\temitter.scalar_data.flow_plain_allowed = false\n\t\temitter.scalar_data.block_plain_allowed = false\n\t\temitter.scalar_data.single_quoted_allowed = false\n\t}\n\tif space_break || tab_characters || special_characters {\n\t\temitter.scalar_data.flow_plain_allowed = false\n\t\temitter.scalar_data.block_plain_allowed = false\n\t\temitter.scalar_data.single_quoted_allowed = false\n\t}\n\tif space_break || special_characters {\n\t\temitter.scalar_data.block_allowed = false\n\t}\n\tif line_breaks {\n\t\temitter.scalar_data.flow_plain_allowed = false\n\t\temitter.scalar_data.block_plain_allowed = false\n\t}\n\tif flow_indicators {\n\t\temitter.scalar_data.flow_plain_allowed = false\n\t}\n\tif block_indicators {\n\t\temitter.scalar_data.block_plain_allowed = false\n\t}\n\treturn true\n}\n\n// Check if the event data is valid.\nfunc yaml_emitter_analyze_event(emitter *yaml_emitter_t, event *yaml_event_t) bool {\n\n\temitter.anchor_data.anchor = nil\n\temitter.tag_data.handle = nil\n\temitter.tag_data.suffix = nil\n\temitter.scalar_data.value = nil\n\n\tif len(event.head_comment) > 0 {\n\t\temitter.head_comment = event.head_comment\n\t}\n\tif len(event.line_comment) > 0 {\n\t\temitter.line_comment = event.line_comment\n\t}\n\tif len(event.foot_comment) > 0 {\n\t\temitter.foot_comment = event.foot_comment\n\t}\n\tif len(event.tail_comment) > 0 {\n\t\temitter.tail_comment = event.tail_comment\n\t}\n\n\tswitch event.typ {\n\tcase yaml_ALIAS_EVENT:\n\t\tif !yaml_emitter_analyze_anchor(emitter, event.anchor, true) {\n\t\t\treturn false\n\t\t}\n\n\tcase yaml_SCALAR_EVENT:\n\t\tif len(event.anchor) > 0 {\n\t\t\tif !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif len(event.tag) > 0 && (emitter.canonical || (!event.implicit && !event.quoted_implicit)) {\n\t\t\tif !yaml_emitter_analyze_tag(emitter, event.tag) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif !yaml_emitter_analyze_scalar(emitter, event.value) {\n\t\t\treturn false\n\t\t}\n\n\tcase yaml_SEQUENCE_START_EVENT:\n\t\tif len(event.anchor) > 0 {\n\t\t\tif !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif len(event.tag) > 0 && (emitter.canonical || !event.implicit) {\n\t\t\tif !yaml_emitter_analyze_tag(emitter, event.tag) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\tcase yaml_MAPPING_START_EVENT:\n\t\tif len(event.anchor) > 0 {\n\t\t\tif !yaml_emitter_analyze_anchor(emitter, event.anchor, false) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif len(event.tag) > 0 && (emitter.canonical || !event.implicit) {\n\t\t\tif !yaml_emitter_analyze_tag(emitter, event.tag) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\n// Write the BOM character.\nfunc yaml_emitter_write_bom(emitter *yaml_emitter_t) bool {\n\tif !flush(emitter) {\n\t\treturn false\n\t}\n\tpos := emitter.buffer_pos\n\temitter.buffer[pos+0] = '\\xEF'\n\temitter.buffer[pos+1] = '\\xBB'\n\temitter.buffer[pos+2] = '\\xBF'\n\temitter.buffer_pos += 3\n\treturn true\n}\n\nfunc yaml_emitter_write_indent(emitter *yaml_emitter_t) bool {\n\tindent := emitter.indent\n\tif indent < 0 {\n\t\tindent = 0\n\t}\n\tif !emitter.indention || emitter.column > indent || (emitter.column == indent && !emitter.whitespace) {\n\t\tif !put_break(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif emitter.foot_indent == indent {\n\t\tif !put_break(emitter) {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor emitter.column < indent {\n\t\tif !put(emitter, ' ') {\n\t\t\treturn false\n\t\t}\n\t}\n\temitter.whitespace = true\n\t//emitter.indention = true\n\temitter.space_above = false\n\temitter.foot_indent = -1\n\treturn true\n}\n\nfunc yaml_emitter_write_indicator(emitter *yaml_emitter_t, indicator []byte, need_whitespace, is_whitespace, is_indention bool) bool {\n\tif need_whitespace && !emitter.whitespace {\n\t\tif !put(emitter, ' ') {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !write_all(emitter, indicator) {\n\t\treturn false\n\t}\n\temitter.whitespace = is_whitespace\n\temitter.indention = (emitter.indention && is_indention)\n\temitter.open_ended = false\n\treturn true\n}\n\nfunc yaml_emitter_write_anchor(emitter *yaml_emitter_t, value []byte) bool {\n\tif !write_all(emitter, value) {\n\t\treturn false\n\t}\n\temitter.whitespace = false\n\temitter.indention = false\n\treturn true\n}\n\nfunc yaml_emitter_write_tag_handle(emitter *yaml_emitter_t, value []byte) bool {\n\tif !emitter.whitespace {\n\t\tif !put(emitter, ' ') {\n\t\t\treturn false\n\t\t}\n\t}\n\tif !write_all(emitter, value) {\n\t\treturn false\n\t}\n\temitter.whitespace = false\n\temitter.indention = false\n\treturn true\n}\n\nfunc yaml_emitter_write_tag_content(emitter *yaml_emitter_t, value []byte, need_whitespace bool) bool {\n\tif need_whitespace && !emitter.whitespace {\n\t\tif !put(emitter, ' ') {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor i := 0; i < len(value); {\n\t\tvar must_write bool\n\t\tswitch value[i] {\n\t\tcase ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '_', '.', '~', '*', '\\'', '(', ')', '[', ']':\n\t\t\tmust_write = true\n\t\tdefault:\n\t\t\tmust_write = is_alpha(value, i)\n\t\t}\n\t\tif must_write {\n\t\t\tif !write(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\tw := width(value[i])\n\t\t\tfor k := 0; k < w; k++ {\n\t\t\t\toctet := value[i]\n\t\t\t\ti++\n\t\t\t\tif !put(emitter, '%') {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\tc := octet >> 4\n\t\t\t\tif c < 10 {\n\t\t\t\t\tc += '0'\n\t\t\t\t} else {\n\t\t\t\t\tc += 'A' - 10\n\t\t\t\t}\n\t\t\t\tif !put(emitter, c) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\tc = octet & 0x0f\n\t\t\t\tif c < 10 {\n\t\t\t\t\tc += '0'\n\t\t\t\t} else {\n\t\t\t\t\tc += 'A' - 10\n\t\t\t\t}\n\t\t\t\tif !put(emitter, c) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\temitter.whitespace = false\n\temitter.indention = false\n\treturn true\n}\n\nfunc yaml_emitter_write_plain_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {\n\tif len(value) > 0 && !emitter.whitespace {\n\t\tif !put(emitter, ' ') {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tspaces := false\n\tbreaks := false\n\tfor i := 0; i < len(value); {\n\t\tif is_space(value, i) {\n\t\t\tif allow_breaks && !spaces && emitter.column > emitter.best_width && !is_space(value, i+1) {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\ti += width(value[i])\n\t\t\t} else {\n\t\t\t\tif !write(emitter, value, &i) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tspaces = true\n\t\t} else if is_break(value, i) {\n\t\t\tif !breaks && value[i] == '\\n' {\n\t\t\t\tif !put_break(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !write_break(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t//emitter.indention = true\n\t\t\tbreaks = true\n\t\t} else {\n\t\t\tif breaks {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !write(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\temitter.indention = false\n\t\t\tspaces = false\n\t\t\tbreaks = false\n\t\t}\n\t}\n\n\tif len(value) > 0 {\n\t\temitter.whitespace = false\n\t}\n\temitter.indention = false\n\tif emitter.root_context {\n\t\temitter.open_ended = true\n\t}\n\n\treturn true\n}\n\nfunc yaml_emitter_write_single_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {\n\n\tif !yaml_emitter_write_indicator(emitter, []byte{'\\''}, true, false, false) {\n\t\treturn false\n\t}\n\n\tspaces := false\n\tbreaks := false\n\tfor i := 0; i < len(value); {\n\t\tif is_space(value, i) {\n\t\t\tif allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 && !is_space(value, i+1) {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\ti += width(value[i])\n\t\t\t} else {\n\t\t\t\tif !write(emitter, value, &i) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tspaces = true\n\t\t} else if is_break(value, i) {\n\t\t\tif !breaks && value[i] == '\\n' {\n\t\t\t\tif !put_break(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !write_break(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t//emitter.indention = true\n\t\t\tbreaks = true\n\t\t} else {\n\t\t\tif breaks {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif value[i] == '\\'' {\n\t\t\t\tif !put(emitter, '\\'') {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !write(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\temitter.indention = false\n\t\t\tspaces = false\n\t\t\tbreaks = false\n\t\t}\n\t}\n\tif !yaml_emitter_write_indicator(emitter, []byte{'\\''}, false, false, false) {\n\t\treturn false\n\t}\n\temitter.whitespace = false\n\temitter.indention = false\n\treturn true\n}\n\nfunc yaml_emitter_write_double_quoted_scalar(emitter *yaml_emitter_t, value []byte, allow_breaks bool) bool {\n\tspaces := false\n\tif !yaml_emitter_write_indicator(emitter, []byte{'\"'}, true, false, false) {\n\t\treturn false\n\t}\n\n\tfor i := 0; i < len(value); {\n\t\tif !is_printable(value, i) || (!emitter.unicode && !is_ascii(value, i)) ||\n\t\t\tis_bom(value, i) || is_break(value, i) ||\n\t\t\tvalue[i] == '\"' || value[i] == '\\\\' {\n\n\t\t\toctet := value[i]\n\n\t\t\tvar w int\n\t\t\tvar v rune\n\t\t\tswitch {\n\t\t\tcase octet&0x80 == 0x00:\n\t\t\t\tw, v = 1, rune(octet&0x7F)\n\t\t\tcase octet&0xE0 == 0xC0:\n\t\t\t\tw, v = 2, rune(octet&0x1F)\n\t\t\tcase octet&0xF0 == 0xE0:\n\t\t\t\tw, v = 3, rune(octet&0x0F)\n\t\t\tcase octet&0xF8 == 0xF0:\n\t\t\t\tw, v = 4, rune(octet&0x07)\n\t\t\t}\n\t\t\tfor k := 1; k < w; k++ {\n\t\t\t\toctet = value[i+k]\n\t\t\t\tv = (v << 6) + (rune(octet) & 0x3F)\n\t\t\t}\n\t\t\ti += w\n\n\t\t\tif !put(emitter, '\\\\') {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tvar ok bool\n\t\t\tswitch v {\n\t\t\tcase 0x00:\n\t\t\t\tok = put(emitter, '0')\n\t\t\tcase 0x07:\n\t\t\t\tok = put(emitter, 'a')\n\t\t\tcase 0x08:\n\t\t\t\tok = put(emitter, 'b')\n\t\t\tcase 0x09:\n\t\t\t\tok = put(emitter, 't')\n\t\t\tcase 0x0A:\n\t\t\t\tok = put(emitter, 'n')\n\t\t\tcase 0x0b:\n\t\t\t\tok = put(emitter, 'v')\n\t\t\tcase 0x0c:\n\t\t\t\tok = put(emitter, 'f')\n\t\t\tcase 0x0d:\n\t\t\t\tok = put(emitter, 'r')\n\t\t\tcase 0x1b:\n\t\t\t\tok = put(emitter, 'e')\n\t\t\tcase 0x22:\n\t\t\t\tok = put(emitter, '\"')\n\t\t\tcase 0x5c:\n\t\t\t\tok = put(emitter, '\\\\')\n\t\t\tcase 0x85:\n\t\t\t\tok = put(emitter, 'N')\n\t\t\tcase 0xA0:\n\t\t\t\tok = put(emitter, '_')\n\t\t\tcase 0x2028:\n\t\t\t\tok = put(emitter, 'L')\n\t\t\tcase 0x2029:\n\t\t\t\tok = put(emitter, 'P')\n\t\t\tdefault:\n\t\t\t\tif v <= 0xFF {\n\t\t\t\t\tok = put(emitter, 'x')\n\t\t\t\t\tw = 2\n\t\t\t\t} else if v <= 0xFFFF {\n\t\t\t\t\tok = put(emitter, 'u')\n\t\t\t\t\tw = 4\n\t\t\t\t} else {\n\t\t\t\t\tok = put(emitter, 'U')\n\t\t\t\t\tw = 8\n\t\t\t\t}\n\t\t\t\tfor k := (w - 1) * 4; ok && k >= 0; k -= 4 {\n\t\t\t\t\tdigit := byte((v >> uint(k)) & 0x0F)\n\t\t\t\t\tif digit < 10 {\n\t\t\t\t\t\tok = put(emitter, digit+'0')\n\t\t\t\t\t} else {\n\t\t\t\t\t\tok = put(emitter, digit+'A'-10)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !ok {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tspaces = false\n\t\t} else if is_space(value, i) {\n\t\t\tif allow_breaks && !spaces && emitter.column > emitter.best_width && i > 0 && i < len(value)-1 {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif is_space(value, i+1) {\n\t\t\t\t\tif !put(emitter, '\\\\') {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti += width(value[i])\n\t\t\t} else if !write(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tspaces = true\n\t\t} else {\n\t\t\tif !write(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tspaces = false\n\t\t}\n\t}\n\tif !yaml_emitter_write_indicator(emitter, []byte{'\"'}, false, false, false) {\n\t\treturn false\n\t}\n\temitter.whitespace = false\n\temitter.indention = false\n\treturn true\n}\n\nfunc yaml_emitter_write_block_scalar_hints(emitter *yaml_emitter_t, value []byte) bool {\n\tif is_space(value, 0) || is_break(value, 0) {\n\t\tindent_hint := []byte{'0' + byte(emitter.best_indent)}\n\t\tif !yaml_emitter_write_indicator(emitter, indent_hint, false, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\temitter.open_ended = false\n\n\tvar chomp_hint [1]byte\n\tif len(value) == 0 {\n\t\tchomp_hint[0] = '-'\n\t} else {\n\t\ti := len(value) - 1\n\t\tfor value[i]&0xC0 == 0x80 {\n\t\t\ti--\n\t\t}\n\t\tif !is_break(value, i) {\n\t\t\tchomp_hint[0] = '-'\n\t\t} else if i == 0 {\n\t\t\tchomp_hint[0] = '+'\n\t\t\temitter.open_ended = true\n\t\t} else {\n\t\t\ti--\n\t\t\tfor value[i]&0xC0 == 0x80 {\n\t\t\t\ti--\n\t\t\t}\n\t\t\tif is_break(value, i) {\n\t\t\t\tchomp_hint[0] = '+'\n\t\t\t\temitter.open_ended = true\n\t\t\t}\n\t\t}\n\t}\n\tif chomp_hint[0] != 0 {\n\t\tif !yaml_emitter_write_indicator(emitter, chomp_hint[:], false, false, false) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc yaml_emitter_write_literal_scalar(emitter *yaml_emitter_t, value []byte) bool {\n\tif !yaml_emitter_write_indicator(emitter, []byte{'|'}, true, false, false) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_write_block_scalar_hints(emitter, value) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_line_comment(emitter) {\n\t\treturn false\n\t}\n\t//emitter.indention = true\n\temitter.whitespace = true\n\tbreaks := true\n\tfor i := 0; i < len(value); {\n\t\tif is_break(value, i) {\n\t\t\tif !write_break(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t//emitter.indention = true\n\t\t\tbreaks = true\n\t\t} else {\n\t\t\tif breaks {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !write(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\temitter.indention = false\n\t\t\tbreaks = false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc yaml_emitter_write_folded_scalar(emitter *yaml_emitter_t, value []byte) bool {\n\tif !yaml_emitter_write_indicator(emitter, []byte{'>'}, true, false, false) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_write_block_scalar_hints(emitter, value) {\n\t\treturn false\n\t}\n\tif !yaml_emitter_process_line_comment(emitter) {\n\t\treturn false\n\t}\n\n\t//emitter.indention = true\n\temitter.whitespace = true\n\n\tbreaks := true\n\tleading_spaces := true\n\tfor i := 0; i < len(value); {\n\t\tif is_break(value, i) {\n\t\t\tif !breaks && !leading_spaces && value[i] == '\\n' {\n\t\t\t\tk := 0\n\t\t\t\tfor is_break(value, k) {\n\t\t\t\t\tk += width(value[k])\n\t\t\t\t}\n\t\t\t\tif !is_blankz(value, k) {\n\t\t\t\t\tif !put_break(emitter) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !write_break(emitter, value, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t//emitter.indention = true\n\t\t\tbreaks = true\n\t\t} else {\n\t\t\tif breaks {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tleading_spaces = is_blank(value, i)\n\t\t\t}\n\t\t\tif !breaks && is_space(value, i) && !is_space(value, i+1) && emitter.column > emitter.best_width {\n\t\t\t\tif !yaml_emitter_write_indent(emitter) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\ti += width(value[i])\n\t\t\t} else {\n\t\t\t\tif !write(emitter, value, &i) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\temitter.indention = false\n\t\t\tbreaks = false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc yaml_emitter_write_comment(emitter *yaml_emitter_t, comment []byte) bool {\n\tbreaks := false\n\tpound := false\n\tfor i := 0; i < len(comment); {\n\t\tif is_break(comment, i) {\n\t\t\tif !write_break(emitter, comment, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t//emitter.indention = true\n\t\t\tbreaks = true\n\t\t\tpound = false\n\t\t} else {\n\t\t\tif breaks && !yaml_emitter_write_indent(emitter) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif !pound {\n\t\t\t\tif comment[i] != '#' && (!put(emitter, '#') || !put(emitter, ' ')) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tpound = true\n\t\t\t}\n\t\t\tif !write(emitter, comment, &i) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\temitter.indention = false\n\t\t\tbreaks = false\n\t\t}\n\t}\n\tif !breaks && !put_break(emitter) {\n\t\treturn false\n\t}\n\n\temitter.whitespace = true\n\t//emitter.indention = true\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/encode.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\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//     http://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\npackage yaml\n\nimport (\n\t\"encoding\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode/utf8\"\n)\n\ntype encoder struct {\n\temitter  yaml_emitter_t\n\tevent    yaml_event_t\n\tout      []byte\n\tflow     bool\n\tindent   int\n\tdoneInit bool\n}\n\nfunc newEncoder() *encoder {\n\te := &encoder{}\n\tyaml_emitter_initialize(&e.emitter)\n\tyaml_emitter_set_output_string(&e.emitter, &e.out)\n\tyaml_emitter_set_unicode(&e.emitter, true)\n\treturn e\n}\n\nfunc newEncoderWithWriter(w io.Writer) *encoder {\n\te := &encoder{}\n\tyaml_emitter_initialize(&e.emitter)\n\tyaml_emitter_set_output_writer(&e.emitter, w)\n\tyaml_emitter_set_unicode(&e.emitter, true)\n\treturn e\n}\n\nfunc (e *encoder) init() {\n\tif e.doneInit {\n\t\treturn\n\t}\n\tif e.indent == 0 {\n\t\te.indent = 4\n\t}\n\te.emitter.best_indent = e.indent\n\tyaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)\n\te.emit()\n\te.doneInit = true\n}\n\nfunc (e *encoder) finish() {\n\te.emitter.open_ended = false\n\tyaml_stream_end_event_initialize(&e.event)\n\te.emit()\n}\n\nfunc (e *encoder) destroy() {\n\tyaml_emitter_delete(&e.emitter)\n}\n\nfunc (e *encoder) emit() {\n\t// This will internally delete the e.event value.\n\te.must(yaml_emitter_emit(&e.emitter, &e.event))\n}\n\nfunc (e *encoder) must(ok bool) {\n\tif !ok {\n\t\tmsg := e.emitter.problem\n\t\tif msg == \"\" {\n\t\t\tmsg = \"unknown problem generating YAML content\"\n\t\t}\n\t\tfailf(\"%s\", msg)\n\t}\n}\n\nfunc (e *encoder) marshalDoc(tag string, in reflect.Value) {\n\te.init()\n\tvar node *Node\n\tif in.IsValid() {\n\t\tnode, _ = in.Interface().(*Node)\n\t}\n\tif node != nil && node.Kind == DocumentNode {\n\t\te.nodev(in)\n\t} else {\n\t\tyaml_document_start_event_initialize(&e.event, nil, nil, true)\n\t\te.emit()\n\t\te.marshal(tag, in)\n\t\tyaml_document_end_event_initialize(&e.event, true)\n\t\te.emit()\n\t}\n}\n\nfunc (e *encoder) marshal(tag string, in reflect.Value) {\n\ttag = shortTag(tag)\n\tif !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {\n\t\te.nilv()\n\t\treturn\n\t}\n\tiface := in.Interface()\n\tswitch value := iface.(type) {\n\tcase *Node:\n\t\te.nodev(in)\n\t\treturn\n\tcase Node:\n\t\tif !in.CanAddr() {\n\t\t\tvar n = reflect.New(in.Type()).Elem()\n\t\t\tn.Set(in)\n\t\t\tin = n\n\t\t}\n\t\te.nodev(in.Addr())\n\t\treturn\n\tcase time.Time:\n\t\te.timev(tag, in)\n\t\treturn\n\tcase *time.Time:\n\t\te.timev(tag, in.Elem())\n\t\treturn\n\tcase time.Duration:\n\t\te.stringv(tag, reflect.ValueOf(value.String()))\n\t\treturn\n\tcase Marshaler:\n\t\tv, err := value.MarshalYAML()\n\t\tif err != nil {\n\t\t\tfail(err)\n\t\t}\n\t\tif v == nil {\n\t\t\te.nilv()\n\t\t\treturn\n\t\t}\n\t\te.marshal(tag, reflect.ValueOf(v))\n\t\treturn\n\tcase encoding.TextMarshaler:\n\t\ttext, err := value.MarshalText()\n\t\tif err != nil {\n\t\t\tfail(err)\n\t\t}\n\t\tin = reflect.ValueOf(string(text))\n\tcase nil:\n\t\te.nilv()\n\t\treturn\n\t}\n\tswitch in.Kind() {\n\tcase reflect.Interface:\n\t\te.marshal(tag, in.Elem())\n\tcase reflect.Map:\n\t\te.mapv(tag, in)\n\tcase reflect.Ptr:\n\t\te.marshal(tag, in.Elem())\n\tcase reflect.Struct:\n\t\te.structv(tag, in)\n\tcase reflect.Slice, reflect.Array:\n\t\te.slicev(tag, in)\n\tcase reflect.String:\n\t\te.stringv(tag, in)\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\te.intv(tag, in)\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\te.uintv(tag, in)\n\tcase reflect.Float32, reflect.Float64:\n\t\te.floatv(tag, in)\n\tcase reflect.Bool:\n\t\te.boolv(tag, in)\n\tdefault:\n\t\tpanic(\"cannot marshal type: \" + in.Type().String())\n\t}\n}\n\nfunc (e *encoder) mapv(tag string, in reflect.Value) {\n\te.mappingv(tag, func() {\n\t\tkeys := keyList(in.MapKeys())\n\t\tsort.Sort(keys)\n\t\tfor _, k := range keys {\n\t\t\te.marshal(\"\", k)\n\t\t\te.marshal(\"\", in.MapIndex(k))\n\t\t}\n\t})\n}\n\nfunc (e *encoder) fieldByIndex(v reflect.Value, index []int) (field reflect.Value) {\n\tfor _, num := range index {\n\t\tfor {\n\t\t\tif v.Kind() == reflect.Ptr {\n\t\t\t\tif v.IsNil() {\n\t\t\t\t\treturn reflect.Value{}\n\t\t\t\t}\n\t\t\t\tv = v.Elem()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tv = v.Field(num)\n\t}\n\treturn v\n}\n\nfunc (e *encoder) structv(tag string, in reflect.Value) {\n\tsinfo, err := getStructInfo(in.Type())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\te.mappingv(tag, func() {\n\t\tfor _, info := range sinfo.FieldsList {\n\t\t\tvar value reflect.Value\n\t\t\tif info.Inline == nil {\n\t\t\t\tvalue = in.Field(info.Num)\n\t\t\t} else {\n\t\t\t\tvalue = e.fieldByIndex(in, info.Inline)\n\t\t\t\tif !value.IsValid() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tif info.OmitEmpty && isZero(value) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\te.marshal(\"\", reflect.ValueOf(info.Key))\n\t\t\te.flow = info.Flow\n\t\t\te.marshal(\"\", value)\n\t\t}\n\t\tif sinfo.InlineMap >= 0 {\n\t\t\tm := in.Field(sinfo.InlineMap)\n\t\t\tif m.Len() > 0 {\n\t\t\t\te.flow = false\n\t\t\t\tkeys := keyList(m.MapKeys())\n\t\t\t\tsort.Sort(keys)\n\t\t\t\tfor _, k := range keys {\n\t\t\t\t\tif _, found := sinfo.FieldsMap[k.String()]; found {\n\t\t\t\t\t\tpanic(fmt.Sprintf(\"cannot have key %q in inlined map: conflicts with struct field\", k.String()))\n\t\t\t\t\t}\n\t\t\t\t\te.marshal(\"\", k)\n\t\t\t\t\te.flow = false\n\t\t\t\t\te.marshal(\"\", m.MapIndex(k))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc (e *encoder) mappingv(tag string, f func()) {\n\timplicit := tag == \"\"\n\tstyle := yaml_BLOCK_MAPPING_STYLE\n\tif e.flow {\n\t\te.flow = false\n\t\tstyle = yaml_FLOW_MAPPING_STYLE\n\t}\n\tyaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)\n\te.emit()\n\tf()\n\tyaml_mapping_end_event_initialize(&e.event)\n\te.emit()\n}\n\nfunc (e *encoder) slicev(tag string, in reflect.Value) {\n\timplicit := tag == \"\"\n\tstyle := yaml_BLOCK_SEQUENCE_STYLE\n\tif e.flow {\n\t\te.flow = false\n\t\tstyle = yaml_FLOW_SEQUENCE_STYLE\n\t}\n\te.must(yaml_sequence_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))\n\te.emit()\n\tn := in.Len()\n\tfor i := 0; i < n; i++ {\n\t\te.marshal(\"\", in.Index(i))\n\t}\n\te.must(yaml_sequence_end_event_initialize(&e.event))\n\te.emit()\n}\n\n// isBase60 returns whether s is in base 60 notation as defined in YAML 1.1.\n//\n// The base 60 float notation in YAML 1.1 is a terrible idea and is unsupported\n// in YAML 1.2 and by this package, but these should be marshalled quoted for\n// the time being for compatibility with other parsers.\nfunc isBase60Float(s string) (result bool) {\n\t// Fast path.\n\tif s == \"\" {\n\t\treturn false\n\t}\n\tc := s[0]\n\tif !(c == '+' || c == '-' || c >= '0' && c <= '9') || strings.IndexByte(s, ':') < 0 {\n\t\treturn false\n\t}\n\t// Do the full match.\n\treturn base60float.MatchString(s)\n}\n\n// From http://yaml.org/type/float.html, except the regular expression there\n// is bogus. In practice parsers do not enforce the \"\\.[0-9_]*\" suffix.\nvar base60float = regexp.MustCompile(`^[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+(?:\\.[0-9_]*)?$`)\n\n// isOldBool returns whether s is bool notation as defined in YAML 1.1.\n//\n// We continue to force strings that YAML 1.1 would interpret as booleans to be\n// rendered as quotes strings so that the marshalled output valid for YAML 1.1\n// parsing.\nfunc isOldBool(s string) (result bool) {\n\tswitch s {\n\tcase \"y\", \"Y\", \"yes\", \"Yes\", \"YES\", \"on\", \"On\", \"ON\",\n\t\t\"n\", \"N\", \"no\", \"No\", \"NO\", \"off\", \"Off\", \"OFF\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (e *encoder) stringv(tag string, in reflect.Value) {\n\tvar style yaml_scalar_style_t\n\ts := in.String()\n\tcanUsePlain := true\n\tswitch {\n\tcase !utf8.ValidString(s):\n\t\tif tag == binaryTag {\n\t\t\tfailf(\"explicitly tagged !!binary data must be base64-encoded\")\n\t\t}\n\t\tif tag != \"\" {\n\t\t\tfailf(\"cannot marshal invalid UTF-8 data as %s\", shortTag(tag))\n\t\t}\n\t\t// It can't be encoded directly as YAML so use a binary tag\n\t\t// and encode it as base64.\n\t\ttag = binaryTag\n\t\ts = encodeBase64(s)\n\tcase tag == \"\":\n\t\t// Check to see if it would resolve to a specific\n\t\t// tag when encoded unquoted. If it doesn't,\n\t\t// there's no need to quote it.\n\t\trtag, _ := resolve(\"\", s)\n\t\tcanUsePlain = rtag == strTag && !(isBase60Float(s) || isOldBool(s))\n\t}\n\t// Note: it's possible for user code to emit invalid YAML\n\t// if they explicitly specify a tag and a string containing\n\t// text that's incompatible with that tag.\n\tswitch {\n\tcase strings.Contains(s, \"\\n\"):\n\t\tif e.flow {\n\t\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t\t} else {\n\t\t\tstyle = yaml_LITERAL_SCALAR_STYLE\n\t\t}\n\tcase canUsePlain:\n\t\tstyle = yaml_PLAIN_SCALAR_STYLE\n\tdefault:\n\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t}\n\te.emitScalar(s, \"\", tag, style, nil, nil, nil, nil)\n}\n\nfunc (e *encoder) boolv(tag string, in reflect.Value) {\n\tvar s string\n\tif in.Bool() {\n\t\ts = \"true\"\n\t} else {\n\t\ts = \"false\"\n\t}\n\te.emitScalar(s, \"\", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)\n}\n\nfunc (e *encoder) intv(tag string, in reflect.Value) {\n\ts := strconv.FormatInt(in.Int(), 10)\n\te.emitScalar(s, \"\", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)\n}\n\nfunc (e *encoder) uintv(tag string, in reflect.Value) {\n\ts := strconv.FormatUint(in.Uint(), 10)\n\te.emitScalar(s, \"\", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)\n}\n\nfunc (e *encoder) timev(tag string, in reflect.Value) {\n\tt := in.Interface().(time.Time)\n\ts := t.Format(time.RFC3339Nano)\n\te.emitScalar(s, \"\", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)\n}\n\nfunc (e *encoder) floatv(tag string, in reflect.Value) {\n\t// Issue #352: When formatting, use the precision of the underlying value\n\tprecision := 64\n\tif in.Kind() == reflect.Float32 {\n\t\tprecision = 32\n\t}\n\n\ts := strconv.FormatFloat(in.Float(), 'g', -1, precision)\n\tswitch s {\n\tcase \"+Inf\":\n\t\ts = \".inf\"\n\tcase \"-Inf\":\n\t\ts = \"-.inf\"\n\tcase \"NaN\":\n\t\ts = \".nan\"\n\t}\n\te.emitScalar(s, \"\", tag, yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)\n}\n\nfunc (e *encoder) nilv() {\n\te.emitScalar(\"null\", \"\", \"\", yaml_PLAIN_SCALAR_STYLE, nil, nil, nil, nil)\n}\n\nfunc (e *encoder) emitScalar(value, anchor, tag string, style yaml_scalar_style_t, head, line, foot, tail []byte) {\n\t// TODO Kill this function. Replace all initialize calls by their underlining Go literals.\n\timplicit := tag == \"\"\n\tif !implicit {\n\t\ttag = longTag(tag)\n\t}\n\te.must(yaml_scalar_event_initialize(&e.event, []byte(anchor), []byte(tag), []byte(value), implicit, implicit, style))\n\te.event.head_comment = head\n\te.event.line_comment = line\n\te.event.foot_comment = foot\n\te.event.tail_comment = tail\n\te.emit()\n}\n\nfunc (e *encoder) nodev(in reflect.Value) {\n\te.node(in.Interface().(*Node), \"\")\n}\n\nfunc (e *encoder) node(node *Node, tail string) {\n\t// Zero nodes behave as nil.\n\tif node.Kind == 0 && node.IsZero() {\n\t\te.nilv()\n\t\treturn\n\t}\n\n\t// If the tag was not explicitly requested, and dropping it won't change the\n\t// implicit tag of the value, don't include it in the presentation.\n\tvar tag = node.Tag\n\tvar stag = shortTag(tag)\n\tvar forceQuoting bool\n\tif tag != \"\" && node.Style&TaggedStyle == 0 {\n\t\tif node.Kind == ScalarNode {\n\t\t\tif stag == strTag && node.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0 {\n\t\t\t\ttag = \"\"\n\t\t\t} else {\n\t\t\t\trtag, _ := resolve(\"\", node.Value)\n\t\t\t\tif rtag == stag {\n\t\t\t\t\ttag = \"\"\n\t\t\t\t} else if stag == strTag {\n\t\t\t\t\ttag = \"\"\n\t\t\t\t\tforceQuoting = true\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tvar rtag string\n\t\t\tswitch node.Kind {\n\t\t\tcase MappingNode:\n\t\t\t\trtag = mapTag\n\t\t\tcase SequenceNode:\n\t\t\t\trtag = seqTag\n\t\t\t}\n\t\t\tif rtag == stag {\n\t\t\t\ttag = \"\"\n\t\t\t}\n\t\t}\n\t}\n\n\tswitch node.Kind {\n\tcase DocumentNode:\n\t\tyaml_document_start_event_initialize(&e.event, nil, nil, true)\n\t\te.event.head_comment = []byte(node.HeadComment)\n\t\te.emit()\n\t\tfor _, node := range node.Content {\n\t\t\te.node(node, \"\")\n\t\t}\n\t\tyaml_document_end_event_initialize(&e.event, true)\n\t\te.event.foot_comment = []byte(node.FootComment)\n\t\te.emit()\n\n\tcase SequenceNode:\n\t\tstyle := yaml_BLOCK_SEQUENCE_STYLE\n\t\tif node.Style&FlowStyle != 0 {\n\t\t\tstyle = yaml_FLOW_SEQUENCE_STYLE\n\t\t}\n\t\te.must(yaml_sequence_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == \"\", style))\n\t\te.event.head_comment = []byte(node.HeadComment)\n\t\te.emit()\n\t\tfor _, node := range node.Content {\n\t\t\te.node(node, \"\")\n\t\t}\n\t\te.must(yaml_sequence_end_event_initialize(&e.event))\n\t\te.event.line_comment = []byte(node.LineComment)\n\t\te.event.foot_comment = []byte(node.FootComment)\n\t\te.emit()\n\n\tcase MappingNode:\n\t\tstyle := yaml_BLOCK_MAPPING_STYLE\n\t\tif node.Style&FlowStyle != 0 {\n\t\t\tstyle = yaml_FLOW_MAPPING_STYLE\n\t\t}\n\t\tyaml_mapping_start_event_initialize(&e.event, []byte(node.Anchor), []byte(longTag(tag)), tag == \"\", style)\n\t\te.event.tail_comment = []byte(tail)\n\t\te.event.head_comment = []byte(node.HeadComment)\n\t\te.emit()\n\n\t\t// The tail logic below moves the foot comment of prior keys to the following key,\n\t\t// since the value for each key may be a nested structure and the foot needs to be\n\t\t// processed only the entirety of the value is streamed. The last tail is processed\n\t\t// with the mapping end event.\n\t\tvar tail string\n\t\tfor i := 0; i+1 < len(node.Content); i += 2 {\n\t\t\tk := node.Content[i]\n\t\t\tfoot := k.FootComment\n\t\t\tif foot != \"\" {\n\t\t\t\tkopy := *k\n\t\t\t\tkopy.FootComment = \"\"\n\t\t\t\tk = &kopy\n\t\t\t}\n\t\t\te.node(k, tail)\n\t\t\ttail = foot\n\n\t\t\tv := node.Content[i+1]\n\t\t\te.node(v, \"\")\n\t\t}\n\n\t\tyaml_mapping_end_event_initialize(&e.event)\n\t\te.event.tail_comment = []byte(tail)\n\t\te.event.line_comment = []byte(node.LineComment)\n\t\te.event.foot_comment = []byte(node.FootComment)\n\t\te.emit()\n\n\tcase AliasNode:\n\t\tyaml_alias_event_initialize(&e.event, []byte(node.Value))\n\t\te.event.head_comment = []byte(node.HeadComment)\n\t\te.event.line_comment = []byte(node.LineComment)\n\t\te.event.foot_comment = []byte(node.FootComment)\n\t\te.emit()\n\n\tcase ScalarNode:\n\t\tvalue := node.Value\n\t\tif !utf8.ValidString(value) {\n\t\t\tif stag == binaryTag {\n\t\t\t\tfailf(\"explicitly tagged !!binary data must be base64-encoded\")\n\t\t\t}\n\t\t\tif stag != \"\" {\n\t\t\t\tfailf(\"cannot marshal invalid UTF-8 data as %s\", stag)\n\t\t\t}\n\t\t\t// It can't be encoded directly as YAML so use a binary tag\n\t\t\t// and encode it as base64.\n\t\t\ttag = binaryTag\n\t\t\tvalue = encodeBase64(value)\n\t\t}\n\n\t\tstyle := yaml_PLAIN_SCALAR_STYLE\n\t\tswitch {\n\t\tcase node.Style&DoubleQuotedStyle != 0:\n\t\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t\tcase node.Style&SingleQuotedStyle != 0:\n\t\t\tstyle = yaml_SINGLE_QUOTED_SCALAR_STYLE\n\t\tcase node.Style&LiteralStyle != 0:\n\t\t\tstyle = yaml_LITERAL_SCALAR_STYLE\n\t\tcase node.Style&FoldedStyle != 0:\n\t\t\tstyle = yaml_FOLDED_SCALAR_STYLE\n\t\tcase strings.Contains(value, \"\\n\"):\n\t\t\tstyle = yaml_LITERAL_SCALAR_STYLE\n\t\tcase forceQuoting:\n\t\t\tstyle = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t\t}\n\n\t\te.emitScalar(value, node.Anchor, tag, style, []byte(node.HeadComment), []byte(node.LineComment), []byte(node.FootComment), []byte(tail))\n\tdefault:\n\t\tfailf(\"cannot encode node with unknown kind %d\", node.Kind)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/origin.go",
    "content": "package yaml\n\nimport \"fmt\"\n\nconst originTag = \"__origin__\"\n\nfunc isScalar(n *Node) bool {\n\treturn n.Kind == ScalarNode\n}\n\nfunc addOriginInSeq(n *Node) *Node {\n\n\tif n.Kind != MappingNode {\n\t\treturn n\n\t}\n\n\t// in case of a sequence, we use the first element as the key\n\treturn addOrigin(n.Content[0], n)\n}\n\nfunc addOriginInMap(key, n *Node) *Node {\n\n\tif n.Kind != MappingNode {\n\t\treturn n\n\t}\n\n\treturn addOrigin(key, n)\n}\n\nfunc addOrigin(key, n *Node) *Node {\n\tif isOrigin(key) {\n\t\treturn n\n\t}\n\n\tn.Content = append(n.Content, getNamedMap(originTag, append(getKeyLocation(key), getNamedMap(\"fields\", getFieldLocations(n))...))...)\n\treturn n\n}\n\nfunc getFieldLocations(n *Node) []*Node {\n\n\tl := len(n.Content)\n\tsize := 0\n\tfor i := 0; i < l; i += 2 {\n\t\tif isScalar(n.Content[i+1]) {\n\t\t\tsize += 2\n\t\t}\n\t}\n\n\tnodes := make([]*Node, 0, size)\n\tfor i := 0; i < l; i += 2 {\n\t\tif isScalar(n.Content[i+1]) {\n\t\t\tnodes = append(nodes, getNodeLocation(n.Content[i])...)\n\t\t}\n\t}\n\treturn nodes\n}\n\n// isOrigin returns true if the key is an \"origin\" element\n// the current implementation is not optimal, as it relies on the key's line number\n// a better design would be to use a dedicated field in the Node struct\nfunc isOrigin(key *Node) bool {\n\treturn key.Line == 0\n}\n\nfunc getNodeLocation(n *Node) []*Node {\n\treturn getNamedMap(n.Value, getLocationObject(n))\n}\n\nfunc getKeyLocation(n *Node) []*Node {\n\treturn getNamedMap(\"key\", getLocationObject(n))\n}\n\nfunc getNamedMap(title string, content []*Node) []*Node {\n\tif len(content) == 0 {\n\t\treturn nil\n\t}\n\n\treturn []*Node{\n\t\t{\n\t\t\tKind:  ScalarNode,\n\t\t\tTag:   \"!!str\",\n\t\t\tValue: title,\n\t\t},\n\t\tgetMap(content),\n\t}\n}\n\nfunc getMap(content []*Node) *Node {\n\treturn &Node{\n\t\tKind:    MappingNode,\n\t\tTag:     \"!!map\",\n\t\tContent: content,\n\t}\n}\n\nfunc getLocationObject(key *Node) []*Node {\n\treturn []*Node{\n\t\t{\n\t\t\tKind:  ScalarNode,\n\t\t\tTag:   \"!!str\",\n\t\t\tValue: \"line\",\n\t\t},\n\t\t{\n\t\t\tKind:  ScalarNode,\n\t\t\tTag:   \"!!int\",\n\t\t\tValue: fmt.Sprintf(\"%d\", key.Line),\n\t\t},\n\t\t{\n\t\t\tKind:  ScalarNode,\n\t\t\tTag:   \"!!str\",\n\t\t\tValue: \"column\",\n\t\t},\n\t\t{\n\t\t\tKind:  ScalarNode,\n\t\t\tTag:   \"!!int\",\n\t\t\tValue: fmt.Sprintf(\"%d\", key.Column),\n\t\t},\n\t\t{\n\t\t\tKind:  ScalarNode,\n\t\t\tTag:   \"!!str\",\n\t\t\tValue: \"name\",\n\t\t},\n\t\t{\n\t\t\tKind:  ScalarNode,\n\t\t\tTag:   \"!!string\",\n\t\t\tValue: key.Value,\n\t\t},\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/parserc.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\nimport (\n\t\"bytes\"\n)\n\n// The parser implements the following grammar:\n//\n// stream               ::= STREAM-START implicit_document? explicit_document* STREAM-END\n// implicit_document    ::= block_node DOCUMENT-END*\n// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*\n// block_node_or_indentless_sequence    ::=\n//                          ALIAS\n//                          | properties (block_content | indentless_block_sequence)?\n//                          | block_content\n//                          | indentless_block_sequence\n// block_node           ::= ALIAS\n//                          | properties block_content?\n//                          | block_content\n// flow_node            ::= ALIAS\n//                          | properties flow_content?\n//                          | flow_content\n// properties           ::= TAG ANCHOR? | ANCHOR TAG?\n// block_content        ::= block_collection | flow_collection | SCALAR\n// flow_content         ::= flow_collection | SCALAR\n// block_collection     ::= block_sequence | block_mapping\n// flow_collection      ::= flow_sequence | flow_mapping\n// block_sequence       ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END\n// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+\n// block_mapping        ::= BLOCK-MAPPING_START\n//                          ((KEY block_node_or_indentless_sequence?)?\n//                          (VALUE block_node_or_indentless_sequence?)?)*\n//                          BLOCK-END\n// flow_sequence        ::= FLOW-SEQUENCE-START\n//                          (flow_sequence_entry FLOW-ENTRY)*\n//                          flow_sequence_entry?\n//                          FLOW-SEQUENCE-END\n// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n// flow_mapping         ::= FLOW-MAPPING-START\n//                          (flow_mapping_entry FLOW-ENTRY)*\n//                          flow_mapping_entry?\n//                          FLOW-MAPPING-END\n// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n\n// Peek the next token in the token queue.\nfunc peek_token(parser *yaml_parser_t) *yaml_token_t {\n\tif parser.token_available || yaml_parser_fetch_more_tokens(parser) {\n\t\ttoken := &parser.tokens[parser.tokens_head]\n\t\tyaml_parser_unfold_comments(parser, token)\n\t\treturn token\n\t}\n\treturn nil\n}\n\n// yaml_parser_unfold_comments walks through the comments queue and joins all\n// comments behind the position of the provided token into the respective\n// top-level comment slices in the parser.\nfunc yaml_parser_unfold_comments(parser *yaml_parser_t, token *yaml_token_t) {\n\tfor parser.comments_head < len(parser.comments) && token.start_mark.index >= parser.comments[parser.comments_head].token_mark.index {\n\t\tcomment := &parser.comments[parser.comments_head]\n\t\tif len(comment.head) > 0 {\n\t\t\tif token.typ == yaml_BLOCK_END_TOKEN {\n\t\t\t\t// No heads on ends, so keep comment.head for a follow up token.\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif len(parser.head_comment) > 0 {\n\t\t\t\tparser.head_comment = append(parser.head_comment, '\\n')\n\t\t\t}\n\t\t\tparser.head_comment = append(parser.head_comment, comment.head...)\n\t\t}\n\t\tif len(comment.foot) > 0 {\n\t\t\tif len(parser.foot_comment) > 0 {\n\t\t\t\tparser.foot_comment = append(parser.foot_comment, '\\n')\n\t\t\t}\n\t\t\tparser.foot_comment = append(parser.foot_comment, comment.foot...)\n\t\t}\n\t\tif len(comment.line) > 0 {\n\t\t\tif len(parser.line_comment) > 0 {\n\t\t\t\tparser.line_comment = append(parser.line_comment, '\\n')\n\t\t\t}\n\t\t\tparser.line_comment = append(parser.line_comment, comment.line...)\n\t\t}\n\t\t*comment = yaml_comment_t{}\n\t\tparser.comments_head++\n\t}\n}\n\n// Remove the next token from the queue (must be called after peek_token).\nfunc skip_token(parser *yaml_parser_t) {\n\tparser.token_available = false\n\tparser.tokens_parsed++\n\tparser.stream_end_produced = parser.tokens[parser.tokens_head].typ == yaml_STREAM_END_TOKEN\n\tparser.tokens_head++\n}\n\n// Get the next event.\nfunc yaml_parser_parse(parser *yaml_parser_t, event *yaml_event_t) bool {\n\t// Erase the event object.\n\t*event = yaml_event_t{}\n\n\t// No events after the end of the stream or error.\n\tif parser.stream_end_produced || parser.error != yaml_NO_ERROR || parser.state == yaml_PARSE_END_STATE {\n\t\treturn true\n\t}\n\n\t// Generate the next event.\n\treturn yaml_parser_state_machine(parser, event)\n}\n\n// Set parser error.\nfunc yaml_parser_set_parser_error(parser *yaml_parser_t, problem string, problem_mark yaml_mark_t) bool {\n\tparser.error = yaml_PARSER_ERROR\n\tparser.problem = problem\n\tparser.problem_mark = problem_mark\n\treturn false\n}\n\nfunc yaml_parser_set_parser_error_context(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string, problem_mark yaml_mark_t) bool {\n\tparser.error = yaml_PARSER_ERROR\n\tparser.context = context\n\tparser.context_mark = context_mark\n\tparser.problem = problem\n\tparser.problem_mark = problem_mark\n\treturn false\n}\n\n// State dispatcher.\nfunc yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool {\n\t//trace(\"yaml_parser_state_machine\", \"state:\", parser.state.String())\n\n\tswitch parser.state {\n\tcase yaml_PARSE_STREAM_START_STATE:\n\t\treturn yaml_parser_parse_stream_start(parser, event)\n\n\tcase yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:\n\t\treturn yaml_parser_parse_document_start(parser, event, true)\n\n\tcase yaml_PARSE_DOCUMENT_START_STATE:\n\t\treturn yaml_parser_parse_document_start(parser, event, false)\n\n\tcase yaml_PARSE_DOCUMENT_CONTENT_STATE:\n\t\treturn yaml_parser_parse_document_content(parser, event)\n\n\tcase yaml_PARSE_DOCUMENT_END_STATE:\n\t\treturn yaml_parser_parse_document_end(parser, event)\n\n\tcase yaml_PARSE_BLOCK_NODE_STATE:\n\t\treturn yaml_parser_parse_node(parser, event, true, false)\n\n\tcase yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:\n\t\treturn yaml_parser_parse_node(parser, event, true, true)\n\n\tcase yaml_PARSE_FLOW_NODE_STATE:\n\t\treturn yaml_parser_parse_node(parser, event, false, false)\n\n\tcase yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:\n\t\treturn yaml_parser_parse_block_sequence_entry(parser, event, true)\n\n\tcase yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:\n\t\treturn yaml_parser_parse_block_sequence_entry(parser, event, false)\n\n\tcase yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:\n\t\treturn yaml_parser_parse_indentless_sequence_entry(parser, event)\n\n\tcase yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:\n\t\treturn yaml_parser_parse_block_mapping_key(parser, event, true)\n\n\tcase yaml_PARSE_BLOCK_MAPPING_KEY_STATE:\n\t\treturn yaml_parser_parse_block_mapping_key(parser, event, false)\n\n\tcase yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:\n\t\treturn yaml_parser_parse_block_mapping_value(parser, event)\n\n\tcase yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:\n\t\treturn yaml_parser_parse_flow_sequence_entry(parser, event, true)\n\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:\n\t\treturn yaml_parser_parse_flow_sequence_entry(parser, event, false)\n\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:\n\t\treturn yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event)\n\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:\n\t\treturn yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event)\n\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:\n\t\treturn yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event)\n\n\tcase yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:\n\t\treturn yaml_parser_parse_flow_mapping_key(parser, event, true)\n\n\tcase yaml_PARSE_FLOW_MAPPING_KEY_STATE:\n\t\treturn yaml_parser_parse_flow_mapping_key(parser, event, false)\n\n\tcase yaml_PARSE_FLOW_MAPPING_VALUE_STATE:\n\t\treturn yaml_parser_parse_flow_mapping_value(parser, event, false)\n\n\tcase yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:\n\t\treturn yaml_parser_parse_flow_mapping_value(parser, event, true)\n\n\tdefault:\n\t\tpanic(\"invalid parser state\")\n\t}\n}\n\n// Parse the production:\n// stream   ::= STREAM-START implicit_document? explicit_document* STREAM-END\n//              ************\nfunc yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\tif token.typ != yaml_STREAM_START_TOKEN {\n\t\treturn yaml_parser_set_parser_error(parser, \"did not find expected <stream-start>\", token.start_mark)\n\t}\n\tparser.state = yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE\n\t*event = yaml_event_t{\n\t\ttyp:        yaml_STREAM_START_EVENT,\n\t\tstart_mark: token.start_mark,\n\t\tend_mark:   token.end_mark,\n\t\tencoding:   token.encoding,\n\t}\n\tskip_token(parser)\n\treturn true\n}\n\n// Parse the productions:\n// implicit_document    ::= block_node DOCUMENT-END*\n//                          *\n// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*\n//                          *************************\nfunc yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool {\n\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\t// Parse extra document end indicators.\n\tif !implicit {\n\t\tfor token.typ == yaml_DOCUMENT_END_TOKEN {\n\t\t\tskip_token(parser)\n\t\t\ttoken = peek_token(parser)\n\t\t\tif token == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\tif implicit && token.typ != yaml_VERSION_DIRECTIVE_TOKEN &&\n\t\ttoken.typ != yaml_TAG_DIRECTIVE_TOKEN &&\n\t\ttoken.typ != yaml_DOCUMENT_START_TOKEN &&\n\t\ttoken.typ != yaml_STREAM_END_TOKEN {\n\t\t// Parse an implicit document.\n\t\tif !yaml_parser_process_directives(parser, nil, nil) {\n\t\t\treturn false\n\t\t}\n\t\tparser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)\n\t\tparser.state = yaml_PARSE_BLOCK_NODE_STATE\n\n\t\tvar head_comment []byte\n\t\tif len(parser.head_comment) > 0 {\n\t\t\t// [Go] Scan the header comment backwards, and if an empty line is found, break\n\t\t\t//      the header so the part before the last empty line goes into the\n\t\t\t//      document header, while the bottom of it goes into a follow up event.\n\t\t\tfor i := len(parser.head_comment) - 1; i > 0; i-- {\n\t\t\t\tif parser.head_comment[i] == '\\n' {\n\t\t\t\t\tif i == len(parser.head_comment)-1 {\n\t\t\t\t\t\thead_comment = parser.head_comment[:i]\n\t\t\t\t\t\tparser.head_comment = parser.head_comment[i+1:]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t} else if parser.head_comment[i-1] == '\\n' {\n\t\t\t\t\t\thead_comment = parser.head_comment[:i-1]\n\t\t\t\t\t\tparser.head_comment = parser.head_comment[i+1:]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_DOCUMENT_START_EVENT,\n\t\t\tstart_mark: token.start_mark,\n\t\t\tend_mark:   token.end_mark,\n\n\t\t\thead_comment: head_comment,\n\t\t}\n\n\t} else if token.typ != yaml_STREAM_END_TOKEN {\n\t\t// Parse an explicit document.\n\t\tvar version_directive *yaml_version_directive_t\n\t\tvar tag_directives []yaml_tag_directive_t\n\t\tstart_mark := token.start_mark\n\t\tif !yaml_parser_process_directives(parser, &version_directive, &tag_directives) {\n\t\t\treturn false\n\t\t}\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ != yaml_DOCUMENT_START_TOKEN {\n\t\t\tyaml_parser_set_parser_error(parser,\n\t\t\t\t\"did not find expected <document start>\", token.start_mark)\n\t\t\treturn false\n\t\t}\n\t\tparser.states = append(parser.states, yaml_PARSE_DOCUMENT_END_STATE)\n\t\tparser.state = yaml_PARSE_DOCUMENT_CONTENT_STATE\n\t\tend_mark := token.end_mark\n\n\t\t*event = yaml_event_t{\n\t\t\ttyp:               yaml_DOCUMENT_START_EVENT,\n\t\t\tstart_mark:        start_mark,\n\t\t\tend_mark:          end_mark,\n\t\t\tversion_directive: version_directive,\n\t\t\ttag_directives:    tag_directives,\n\t\t\timplicit:          false,\n\t\t}\n\t\tskip_token(parser)\n\n\t} else {\n\t\t// Parse the stream end.\n\t\tparser.state = yaml_PARSE_END_STATE\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_STREAM_END_EVENT,\n\t\t\tstart_mark: token.start_mark,\n\t\t\tend_mark:   token.end_mark,\n\t\t}\n\t\tskip_token(parser)\n\t}\n\n\treturn true\n}\n\n// Parse the productions:\n// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*\n//                                                    ***********\n//\nfunc yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\tif token.typ == yaml_VERSION_DIRECTIVE_TOKEN ||\n\t\ttoken.typ == yaml_TAG_DIRECTIVE_TOKEN ||\n\t\ttoken.typ == yaml_DOCUMENT_START_TOKEN ||\n\t\ttoken.typ == yaml_DOCUMENT_END_TOKEN ||\n\t\ttoken.typ == yaml_STREAM_END_TOKEN {\n\t\tparser.state = parser.states[len(parser.states)-1]\n\t\tparser.states = parser.states[:len(parser.states)-1]\n\t\treturn yaml_parser_process_empty_scalar(parser, event,\n\t\t\ttoken.start_mark)\n\t}\n\treturn yaml_parser_parse_node(parser, event, true, false)\n}\n\n// Parse the productions:\n// implicit_document    ::= block_node DOCUMENT-END*\n//                                     *************\n// explicit_document    ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END*\n//\nfunc yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\tstart_mark := token.start_mark\n\tend_mark := token.start_mark\n\n\timplicit := true\n\tif token.typ == yaml_DOCUMENT_END_TOKEN {\n\t\tend_mark = token.end_mark\n\t\tskip_token(parser)\n\t\timplicit = false\n\t}\n\n\tparser.tag_directives = parser.tag_directives[:0]\n\n\tparser.state = yaml_PARSE_DOCUMENT_START_STATE\n\t*event = yaml_event_t{\n\t\ttyp:        yaml_DOCUMENT_END_EVENT,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t\timplicit:   implicit,\n\t}\n\tyaml_parser_set_event_comments(parser, event)\n\tif len(event.head_comment) > 0 && len(event.foot_comment) == 0 {\n\t\tevent.foot_comment = event.head_comment\n\t\tevent.head_comment = nil\n\t}\n\treturn true\n}\n\nfunc yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) {\n\tevent.head_comment = parser.head_comment\n\tevent.line_comment = parser.line_comment\n\tevent.foot_comment = parser.foot_comment\n\tparser.head_comment = nil\n\tparser.line_comment = nil\n\tparser.foot_comment = nil\n\tparser.tail_comment = nil\n\tparser.stem_comment = nil\n}\n\n// Parse the productions:\n// block_node_or_indentless_sequence    ::=\n//                          ALIAS\n//                          *****\n//                          | properties (block_content | indentless_block_sequence)?\n//                            **********  *\n//                          | block_content | indentless_block_sequence\n//                            *\n// block_node           ::= ALIAS\n//                          *****\n//                          | properties block_content?\n//                            ********** *\n//                          | block_content\n//                            *\n// flow_node            ::= ALIAS\n//                          *****\n//                          | properties flow_content?\n//                            ********** *\n//                          | flow_content\n//                            *\n// properties           ::= TAG ANCHOR? | ANCHOR TAG?\n//                          *************************\n// block_content        ::= block_collection | flow_collection | SCALAR\n//                                                               ******\n// flow_content         ::= flow_collection | SCALAR\n//                                            ******\nfunc yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool {\n\t//defer trace(\"yaml_parser_parse_node\", \"block:\", block, \"indentless_sequence:\", indentless_sequence)()\n\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\tif token.typ == yaml_ALIAS_TOKEN {\n\t\tparser.state = parser.states[len(parser.states)-1]\n\t\tparser.states = parser.states[:len(parser.states)-1]\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_ALIAS_EVENT,\n\t\t\tstart_mark: token.start_mark,\n\t\t\tend_mark:   token.end_mark,\n\t\t\tanchor:     token.value,\n\t\t}\n\t\tyaml_parser_set_event_comments(parser, event)\n\t\tskip_token(parser)\n\t\treturn true\n\t}\n\n\tstart_mark := token.start_mark\n\tend_mark := token.start_mark\n\n\tvar tag_token bool\n\tvar tag_handle, tag_suffix, anchor []byte\n\tvar tag_mark yaml_mark_t\n\tif token.typ == yaml_ANCHOR_TOKEN {\n\t\tanchor = token.value\n\t\tstart_mark = token.start_mark\n\t\tend_mark = token.end_mark\n\t\tskip_token(parser)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ == yaml_TAG_TOKEN {\n\t\t\ttag_token = true\n\t\t\ttag_handle = token.value\n\t\t\ttag_suffix = token.suffix\n\t\t\ttag_mark = token.start_mark\n\t\t\tend_mark = token.end_mark\n\t\t\tskip_token(parser)\n\t\t\ttoken = peek_token(parser)\n\t\t\tif token == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t} else if token.typ == yaml_TAG_TOKEN {\n\t\ttag_token = true\n\t\ttag_handle = token.value\n\t\ttag_suffix = token.suffix\n\t\tstart_mark = token.start_mark\n\t\ttag_mark = token.start_mark\n\t\tend_mark = token.end_mark\n\t\tskip_token(parser)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ == yaml_ANCHOR_TOKEN {\n\t\t\tanchor = token.value\n\t\t\tend_mark = token.end_mark\n\t\t\tskip_token(parser)\n\t\t\ttoken = peek_token(parser)\n\t\t\tif token == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\tvar tag []byte\n\tif tag_token {\n\t\tif len(tag_handle) == 0 {\n\t\t\ttag = tag_suffix\n\t\t\ttag_suffix = nil\n\t\t} else {\n\t\t\tfor i := range parser.tag_directives {\n\t\t\t\tif bytes.Equal(parser.tag_directives[i].handle, tag_handle) {\n\t\t\t\t\ttag = append([]byte(nil), parser.tag_directives[i].prefix...)\n\t\t\t\t\ttag = append(tag, tag_suffix...)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(tag) == 0 {\n\t\t\t\tyaml_parser_set_parser_error_context(parser,\n\t\t\t\t\t\"while parsing a node\", start_mark,\n\t\t\t\t\t\"found undefined tag handle\", tag_mark)\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\timplicit := len(tag) == 0\n\tif indentless_sequence && token.typ == yaml_BLOCK_ENTRY_TOKEN {\n\t\tend_mark = token.end_mark\n\t\tparser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_SEQUENCE_START_EVENT,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   end_mark,\n\t\t\tanchor:     anchor,\n\t\t\ttag:        tag,\n\t\t\timplicit:   implicit,\n\t\t\tstyle:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),\n\t\t}\n\t\treturn true\n\t}\n\tif token.typ == yaml_SCALAR_TOKEN {\n\t\tvar plain_implicit, quoted_implicit bool\n\t\tend_mark = token.end_mark\n\t\tif (len(tag) == 0 && token.style == yaml_PLAIN_SCALAR_STYLE) || (len(tag) == 1 && tag[0] == '!') {\n\t\t\tplain_implicit = true\n\t\t} else if len(tag) == 0 {\n\t\t\tquoted_implicit = true\n\t\t}\n\t\tparser.state = parser.states[len(parser.states)-1]\n\t\tparser.states = parser.states[:len(parser.states)-1]\n\n\t\t*event = yaml_event_t{\n\t\t\ttyp:             yaml_SCALAR_EVENT,\n\t\t\tstart_mark:      start_mark,\n\t\t\tend_mark:        end_mark,\n\t\t\tanchor:          anchor,\n\t\t\ttag:             tag,\n\t\t\tvalue:           token.value,\n\t\t\timplicit:        plain_implicit,\n\t\t\tquoted_implicit: quoted_implicit,\n\t\t\tstyle:           yaml_style_t(token.style),\n\t\t}\n\t\tyaml_parser_set_event_comments(parser, event)\n\t\tskip_token(parser)\n\t\treturn true\n\t}\n\tif token.typ == yaml_FLOW_SEQUENCE_START_TOKEN {\n\t\t// [Go] Some of the events below can be merged as they differ only on style.\n\t\tend_mark = token.end_mark\n\t\tparser.state = yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_SEQUENCE_START_EVENT,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   end_mark,\n\t\t\tanchor:     anchor,\n\t\t\ttag:        tag,\n\t\t\timplicit:   implicit,\n\t\t\tstyle:      yaml_style_t(yaml_FLOW_SEQUENCE_STYLE),\n\t\t}\n\t\tyaml_parser_set_event_comments(parser, event)\n\t\treturn true\n\t}\n\tif token.typ == yaml_FLOW_MAPPING_START_TOKEN {\n\t\tend_mark = token.end_mark\n\t\tparser.state = yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_MAPPING_START_EVENT,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   end_mark,\n\t\t\tanchor:     anchor,\n\t\t\ttag:        tag,\n\t\t\timplicit:   implicit,\n\t\t\tstyle:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),\n\t\t}\n\t\tyaml_parser_set_event_comments(parser, event)\n\t\treturn true\n\t}\n\tif block && token.typ == yaml_BLOCK_SEQUENCE_START_TOKEN {\n\t\tend_mark = token.end_mark\n\t\tparser.state = yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_SEQUENCE_START_EVENT,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   end_mark,\n\t\t\tanchor:     anchor,\n\t\t\ttag:        tag,\n\t\t\timplicit:   implicit,\n\t\t\tstyle:      yaml_style_t(yaml_BLOCK_SEQUENCE_STYLE),\n\t\t}\n\t\tif parser.stem_comment != nil {\n\t\t\tevent.head_comment = parser.stem_comment\n\t\t\tparser.stem_comment = nil\n\t\t}\n\t\treturn true\n\t}\n\tif block && token.typ == yaml_BLOCK_MAPPING_START_TOKEN {\n\t\tend_mark = token.end_mark\n\t\tparser.state = yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_MAPPING_START_EVENT,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   end_mark,\n\t\t\tanchor:     anchor,\n\t\t\ttag:        tag,\n\t\t\timplicit:   implicit,\n\t\t\tstyle:      yaml_style_t(yaml_BLOCK_MAPPING_STYLE),\n\t\t}\n\t\tif parser.stem_comment != nil {\n\t\t\tevent.head_comment = parser.stem_comment\n\t\t\tparser.stem_comment = nil\n\t\t}\n\t\treturn true\n\t}\n\tif len(anchor) > 0 || len(tag) > 0 {\n\t\tparser.state = parser.states[len(parser.states)-1]\n\t\tparser.states = parser.states[:len(parser.states)-1]\n\n\t\t*event = yaml_event_t{\n\t\t\ttyp:             yaml_SCALAR_EVENT,\n\t\t\tstart_mark:      start_mark,\n\t\t\tend_mark:        end_mark,\n\t\t\tanchor:          anchor,\n\t\t\ttag:             tag,\n\t\t\timplicit:        implicit,\n\t\t\tquoted_implicit: false,\n\t\t\tstyle:           yaml_style_t(yaml_PLAIN_SCALAR_STYLE),\n\t\t}\n\t\treturn true\n\t}\n\n\tcontext := \"while parsing a flow node\"\n\tif block {\n\t\tcontext = \"while parsing a block node\"\n\t}\n\tyaml_parser_set_parser_error_context(parser, context, start_mark,\n\t\t\"did not find expected node content\", token.start_mark)\n\treturn false\n}\n\n// Parse the productions:\n// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END\n//                    ********************  *********** *             *********\n//\nfunc yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {\n\tif first {\n\t\ttoken := peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tparser.marks = append(parser.marks, token.start_mark)\n\t\tskip_token(parser)\n\t}\n\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\tif token.typ == yaml_BLOCK_ENTRY_TOKEN {\n\t\tmark := token.end_mark\n\t\tprior_head_len := len(parser.head_comment)\n\t\tskip_token(parser)\n\t\tyaml_parser_split_stem_comment(parser, prior_head_len)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ != yaml_BLOCK_ENTRY_TOKEN && token.typ != yaml_BLOCK_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, true, false)\n\t\t} else {\n\t\t\tparser.state = yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE\n\t\t\treturn yaml_parser_process_empty_scalar(parser, event, mark)\n\t\t}\n\t}\n\tif token.typ == yaml_BLOCK_END_TOKEN {\n\t\tparser.state = parser.states[len(parser.states)-1]\n\t\tparser.states = parser.states[:len(parser.states)-1]\n\t\tparser.marks = parser.marks[:len(parser.marks)-1]\n\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_SEQUENCE_END_EVENT,\n\t\t\tstart_mark: token.start_mark,\n\t\t\tend_mark:   token.end_mark,\n\t\t}\n\n\t\tskip_token(parser)\n\t\treturn true\n\t}\n\n\tcontext_mark := parser.marks[len(parser.marks)-1]\n\tparser.marks = parser.marks[:len(parser.marks)-1]\n\treturn yaml_parser_set_parser_error_context(parser,\n\t\t\"while parsing a block collection\", context_mark,\n\t\t\"did not find expected '-' indicator\", token.start_mark)\n}\n\n// Parse the productions:\n// indentless_sequence  ::= (BLOCK-ENTRY block_node?)+\n//                           *********** *\nfunc yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\tif token.typ == yaml_BLOCK_ENTRY_TOKEN {\n\t\tmark := token.end_mark\n\t\tprior_head_len := len(parser.head_comment)\n\t\tskip_token(parser)\n\t\tyaml_parser_split_stem_comment(parser, prior_head_len)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ != yaml_BLOCK_ENTRY_TOKEN &&\n\t\t\ttoken.typ != yaml_KEY_TOKEN &&\n\t\t\ttoken.typ != yaml_VALUE_TOKEN &&\n\t\t\ttoken.typ != yaml_BLOCK_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, true, false)\n\t\t}\n\t\tparser.state = yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE\n\t\treturn yaml_parser_process_empty_scalar(parser, event, mark)\n\t}\n\tparser.state = parser.states[len(parser.states)-1]\n\tparser.states = parser.states[:len(parser.states)-1]\n\n\t*event = yaml_event_t{\n\t\ttyp:        yaml_SEQUENCE_END_EVENT,\n\t\tstart_mark: token.start_mark,\n\t\tend_mark:   token.start_mark, // [Go] Shouldn't this be token.end_mark?\n\t}\n\treturn true\n}\n\n// Split stem comment from head comment.\n//\n// When a sequence or map is found under a sequence entry, the former head comment\n// is assigned to the underlying sequence or map as a whole, not the individual\n// sequence or map entry as would be expected otherwise. To handle this case the\n// previous head comment is moved aside as the stem comment.\nfunc yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) {\n\tif stem_len == 0 {\n\t\treturn\n\t}\n\n\ttoken := peek_token(parser)\n\tif token == nil || token.typ != yaml_BLOCK_SEQUENCE_START_TOKEN && token.typ != yaml_BLOCK_MAPPING_START_TOKEN {\n\t\treturn\n\t}\n\n\tparser.stem_comment = parser.head_comment[:stem_len]\n\tif len(parser.head_comment) == stem_len {\n\t\tparser.head_comment = nil\n\t} else {\n\t\t// Copy suffix to prevent very strange bugs if someone ever appends\n\t\t// further bytes to the prefix in the stem_comment slice above.\n\t\tparser.head_comment = append([]byte(nil), parser.head_comment[stem_len+1:]...)\n\t}\n}\n\n// Parse the productions:\n// block_mapping        ::= BLOCK-MAPPING_START\n//                          *******************\n//                          ((KEY block_node_or_indentless_sequence?)?\n//                            *** *\n//                          (VALUE block_node_or_indentless_sequence?)?)*\n//\n//                          BLOCK-END\n//                          *********\n//\nfunc yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {\n\tif first {\n\t\ttoken := peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tparser.marks = append(parser.marks, token.start_mark)\n\t\tskip_token(parser)\n\t}\n\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\t// [Go] A tail comment was left from the prior mapping value processed. Emit an event\n\t//      as it needs to be processed with that value and not the following key.\n\tif len(parser.tail_comment) > 0 {\n\t\t*event = yaml_event_t{\n\t\t\ttyp:          yaml_TAIL_COMMENT_EVENT,\n\t\t\tstart_mark:   token.start_mark,\n\t\t\tend_mark:     token.end_mark,\n\t\t\tfoot_comment: parser.tail_comment,\n\t\t}\n\t\tparser.tail_comment = nil\n\t\treturn true\n\t}\n\n\tif token.typ == yaml_KEY_TOKEN {\n\t\tmark := token.end_mark\n\t\tskip_token(parser)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ != yaml_KEY_TOKEN &&\n\t\t\ttoken.typ != yaml_VALUE_TOKEN &&\n\t\t\ttoken.typ != yaml_BLOCK_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_VALUE_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, true, true)\n\t\t} else {\n\t\t\tparser.state = yaml_PARSE_BLOCK_MAPPING_VALUE_STATE\n\t\t\treturn yaml_parser_process_empty_scalar(parser, event, mark)\n\t\t}\n\t} else if token.typ == yaml_BLOCK_END_TOKEN {\n\t\tparser.state = parser.states[len(parser.states)-1]\n\t\tparser.states = parser.states[:len(parser.states)-1]\n\t\tparser.marks = parser.marks[:len(parser.marks)-1]\n\t\t*event = yaml_event_t{\n\t\t\ttyp:        yaml_MAPPING_END_EVENT,\n\t\t\tstart_mark: token.start_mark,\n\t\t\tend_mark:   token.end_mark,\n\t\t}\n\t\tyaml_parser_set_event_comments(parser, event)\n\t\tskip_token(parser)\n\t\treturn true\n\t}\n\n\tcontext_mark := parser.marks[len(parser.marks)-1]\n\tparser.marks = parser.marks[:len(parser.marks)-1]\n\treturn yaml_parser_set_parser_error_context(parser,\n\t\t\"while parsing a block mapping\", context_mark,\n\t\t\"did not find expected key\", token.start_mark)\n}\n\n// Parse the productions:\n// block_mapping        ::= BLOCK-MAPPING_START\n//\n//                          ((KEY block_node_or_indentless_sequence?)?\n//\n//                          (VALUE block_node_or_indentless_sequence?)?)*\n//                           ***** *\n//                          BLOCK-END\n//\n//\nfunc yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\tif token.typ == yaml_VALUE_TOKEN {\n\t\tmark := token.end_mark\n\t\tskip_token(parser)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ != yaml_KEY_TOKEN &&\n\t\t\ttoken.typ != yaml_VALUE_TOKEN &&\n\t\t\ttoken.typ != yaml_BLOCK_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_BLOCK_MAPPING_KEY_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, true, true)\n\t\t}\n\t\tparser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE\n\t\treturn yaml_parser_process_empty_scalar(parser, event, mark)\n\t}\n\tparser.state = yaml_PARSE_BLOCK_MAPPING_KEY_STATE\n\treturn yaml_parser_process_empty_scalar(parser, event, token.start_mark)\n}\n\n// Parse the productions:\n// flow_sequence        ::= FLOW-SEQUENCE-START\n//                          *******************\n//                          (flow_sequence_entry FLOW-ENTRY)*\n//                           *                   **********\n//                          flow_sequence_entry?\n//                          *\n//                          FLOW-SEQUENCE-END\n//                          *****************\n// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n//                          *\n//\nfunc yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {\n\tif first {\n\t\ttoken := peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tparser.marks = append(parser.marks, token.start_mark)\n\t\tskip_token(parser)\n\t}\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\tif token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {\n\t\tif !first {\n\t\t\tif token.typ == yaml_FLOW_ENTRY_TOKEN {\n\t\t\t\tskip_token(parser)\n\t\t\t\ttoken = peek_token(parser)\n\t\t\t\tif token == nil {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontext_mark := parser.marks[len(parser.marks)-1]\n\t\t\t\tparser.marks = parser.marks[:len(parser.marks)-1]\n\t\t\t\treturn yaml_parser_set_parser_error_context(parser,\n\t\t\t\t\t\"while parsing a flow sequence\", context_mark,\n\t\t\t\t\t\"did not find expected ',' or ']'\", token.start_mark)\n\t\t\t}\n\t\t}\n\n\t\tif token.typ == yaml_KEY_TOKEN {\n\t\t\tparser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE\n\t\t\t*event = yaml_event_t{\n\t\t\t\ttyp:        yaml_MAPPING_START_EVENT,\n\t\t\t\tstart_mark: token.start_mark,\n\t\t\t\tend_mark:   token.end_mark,\n\t\t\t\timplicit:   true,\n\t\t\t\tstyle:      yaml_style_t(yaml_FLOW_MAPPING_STYLE),\n\t\t\t}\n\t\t\tskip_token(parser)\n\t\t\treturn true\n\t\t} else if token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, false, false)\n\t\t}\n\t}\n\n\tparser.state = parser.states[len(parser.states)-1]\n\tparser.states = parser.states[:len(parser.states)-1]\n\tparser.marks = parser.marks[:len(parser.marks)-1]\n\n\t*event = yaml_event_t{\n\t\ttyp:        yaml_SEQUENCE_END_EVENT,\n\t\tstart_mark: token.start_mark,\n\t\tend_mark:   token.end_mark,\n\t}\n\tyaml_parser_set_event_comments(parser, event)\n\n\tskip_token(parser)\n\treturn true\n}\n\n//\n// Parse the productions:\n// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n//                                      *** *\n//\nfunc yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\tif token.typ != yaml_VALUE_TOKEN &&\n\t\ttoken.typ != yaml_FLOW_ENTRY_TOKEN &&\n\t\ttoken.typ != yaml_FLOW_SEQUENCE_END_TOKEN {\n\t\tparser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)\n\t\treturn yaml_parser_parse_node(parser, event, false, false)\n\t}\n\tmark := token.end_mark\n\tskip_token(parser)\n\tparser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE\n\treturn yaml_parser_process_empty_scalar(parser, event, mark)\n}\n\n// Parse the productions:\n// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n//                                                      ***** *\n//\nfunc yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\tif token.typ == yaml_VALUE_TOKEN {\n\t\tskip_token(parser)\n\t\ttoken := peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_SEQUENCE_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, false, false)\n\t\t}\n\t}\n\tparser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE\n\treturn yaml_parser_process_empty_scalar(parser, event, token.start_mark)\n}\n\n// Parse the productions:\n// flow_sequence_entry  ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n//                                                                      *\n//\nfunc yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\tparser.state = yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE\n\t*event = yaml_event_t{\n\t\ttyp:        yaml_MAPPING_END_EVENT,\n\t\tstart_mark: token.start_mark,\n\t\tend_mark:   token.start_mark, // [Go] Shouldn't this be end_mark?\n\t}\n\treturn true\n}\n\n// Parse the productions:\n// flow_mapping         ::= FLOW-MAPPING-START\n//                          ******************\n//                          (flow_mapping_entry FLOW-ENTRY)*\n//                           *                  **********\n//                          flow_mapping_entry?\n//                          ******************\n//                          FLOW-MAPPING-END\n//                          ****************\n// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n//                          *           *** *\n//\nfunc yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool {\n\tif first {\n\t\ttoken := peek_token(parser)\n\t\tparser.marks = append(parser.marks, token.start_mark)\n\t\tskip_token(parser)\n\t}\n\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\tif token.typ != yaml_FLOW_MAPPING_END_TOKEN {\n\t\tif !first {\n\t\t\tif token.typ == yaml_FLOW_ENTRY_TOKEN {\n\t\t\t\tskip_token(parser)\n\t\t\t\ttoken = peek_token(parser)\n\t\t\t\tif token == nil {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontext_mark := parser.marks[len(parser.marks)-1]\n\t\t\t\tparser.marks = parser.marks[:len(parser.marks)-1]\n\t\t\t\treturn yaml_parser_set_parser_error_context(parser,\n\t\t\t\t\t\"while parsing a flow mapping\", context_mark,\n\t\t\t\t\t\"did not find expected ',' or '}'\", token.start_mark)\n\t\t\t}\n\t\t}\n\n\t\tif token.typ == yaml_KEY_TOKEN {\n\t\t\tskip_token(parser)\n\t\t\ttoken = peek_token(parser)\n\t\t\tif token == nil {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif token.typ != yaml_VALUE_TOKEN &&\n\t\t\t\ttoken.typ != yaml_FLOW_ENTRY_TOKEN &&\n\t\t\t\ttoken.typ != yaml_FLOW_MAPPING_END_TOKEN {\n\t\t\t\tparser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_VALUE_STATE)\n\t\t\t\treturn yaml_parser_parse_node(parser, event, false, false)\n\t\t\t} else {\n\t\t\t\tparser.state = yaml_PARSE_FLOW_MAPPING_VALUE_STATE\n\t\t\t\treturn yaml_parser_process_empty_scalar(parser, event, token.start_mark)\n\t\t\t}\n\t\t} else if token.typ != yaml_FLOW_MAPPING_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, false, false)\n\t\t}\n\t}\n\n\tparser.state = parser.states[len(parser.states)-1]\n\tparser.states = parser.states[:len(parser.states)-1]\n\tparser.marks = parser.marks[:len(parser.marks)-1]\n\t*event = yaml_event_t{\n\t\ttyp:        yaml_MAPPING_END_EVENT,\n\t\tstart_mark: token.start_mark,\n\t\tend_mark:   token.end_mark,\n\t}\n\tyaml_parser_set_event_comments(parser, event)\n\tskip_token(parser)\n\treturn true\n}\n\n// Parse the productions:\n// flow_mapping_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?\n//                                   *                  ***** *\n//\nfunc yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool {\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\tif empty {\n\t\tparser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE\n\t\treturn yaml_parser_process_empty_scalar(parser, event, token.start_mark)\n\t}\n\tif token.typ == yaml_VALUE_TOKEN {\n\t\tskip_token(parser)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t\tif token.typ != yaml_FLOW_ENTRY_TOKEN && token.typ != yaml_FLOW_MAPPING_END_TOKEN {\n\t\t\tparser.states = append(parser.states, yaml_PARSE_FLOW_MAPPING_KEY_STATE)\n\t\t\treturn yaml_parser_parse_node(parser, event, false, false)\n\t\t}\n\t}\n\tparser.state = yaml_PARSE_FLOW_MAPPING_KEY_STATE\n\treturn yaml_parser_process_empty_scalar(parser, event, token.start_mark)\n}\n\n// Generate an empty scalar event.\nfunc yaml_parser_process_empty_scalar(parser *yaml_parser_t, event *yaml_event_t, mark yaml_mark_t) bool {\n\t*event = yaml_event_t{\n\t\ttyp:        yaml_SCALAR_EVENT,\n\t\tstart_mark: mark,\n\t\tend_mark:   mark,\n\t\tvalue:      nil, // Empty\n\t\timplicit:   true,\n\t\tstyle:      yaml_style_t(yaml_PLAIN_SCALAR_STYLE),\n\t}\n\treturn true\n}\n\nvar default_tag_directives = []yaml_tag_directive_t{\n\t{[]byte(\"!\"), []byte(\"!\")},\n\t{[]byte(\"!!\"), []byte(\"tag:yaml.org,2002:\")},\n}\n\n// Parse directives.\nfunc yaml_parser_process_directives(parser *yaml_parser_t,\n\tversion_directive_ref **yaml_version_directive_t,\n\ttag_directives_ref *[]yaml_tag_directive_t) bool {\n\n\tvar version_directive *yaml_version_directive_t\n\tvar tag_directives []yaml_tag_directive_t\n\n\ttoken := peek_token(parser)\n\tif token == nil {\n\t\treturn false\n\t}\n\n\tfor token.typ == yaml_VERSION_DIRECTIVE_TOKEN || token.typ == yaml_TAG_DIRECTIVE_TOKEN {\n\t\tif token.typ == yaml_VERSION_DIRECTIVE_TOKEN {\n\t\t\tif version_directive != nil {\n\t\t\t\tyaml_parser_set_parser_error(parser,\n\t\t\t\t\t\"found duplicate %YAML directive\", token.start_mark)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif token.major != 1 || token.minor != 1 {\n\t\t\t\tyaml_parser_set_parser_error(parser,\n\t\t\t\t\t\"found incompatible YAML document\", token.start_mark)\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tversion_directive = &yaml_version_directive_t{\n\t\t\t\tmajor: token.major,\n\t\t\t\tminor: token.minor,\n\t\t\t}\n\t\t} else if token.typ == yaml_TAG_DIRECTIVE_TOKEN {\n\t\t\tvalue := yaml_tag_directive_t{\n\t\t\t\thandle: token.value,\n\t\t\t\tprefix: token.prefix,\n\t\t\t}\n\t\t\tif !yaml_parser_append_tag_directive(parser, value, false, token.start_mark) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\ttag_directives = append(tag_directives, value)\n\t\t}\n\n\t\tskip_token(parser)\n\t\ttoken = peek_token(parser)\n\t\tif token == nil {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tfor i := range default_tag_directives {\n\t\tif !yaml_parser_append_tag_directive(parser, default_tag_directives[i], true, token.start_mark) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif version_directive_ref != nil {\n\t\t*version_directive_ref = version_directive\n\t}\n\tif tag_directives_ref != nil {\n\t\t*tag_directives_ref = tag_directives\n\t}\n\treturn true\n}\n\n// Append a tag directive to the directives stack.\nfunc yaml_parser_append_tag_directive(parser *yaml_parser_t, value yaml_tag_directive_t, allow_duplicates bool, mark yaml_mark_t) bool {\n\tfor i := range parser.tag_directives {\n\t\tif bytes.Equal(value.handle, parser.tag_directives[i].handle) {\n\t\t\tif allow_duplicates {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn yaml_parser_set_parser_error(parser, \"found duplicate %TAG directive\", mark)\n\t\t}\n\t}\n\n\t// [Go] I suspect the copy is unnecessary. This was likely done\n\t// because there was no way to track ownership of the data.\n\tvalue_copy := yaml_tag_directive_t{\n\t\thandle: make([]byte, len(value.handle)),\n\t\tprefix: make([]byte, len(value.prefix)),\n\t}\n\tcopy(value_copy.handle, value.handle)\n\tcopy(value_copy.prefix, value.prefix)\n\tparser.tag_directives = append(parser.tag_directives, value_copy)\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/readerc.go",
    "content": "// \n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\nimport (\n\t\"io\"\n)\n\n// Set the reader error and return 0.\nfunc yaml_parser_set_reader_error(parser *yaml_parser_t, problem string, offset int, value int) bool {\n\tparser.error = yaml_READER_ERROR\n\tparser.problem = problem\n\tparser.problem_offset = offset\n\tparser.problem_value = value\n\treturn false\n}\n\n// Byte order marks.\nconst (\n\tbom_UTF8    = \"\\xef\\xbb\\xbf\"\n\tbom_UTF16LE = \"\\xff\\xfe\"\n\tbom_UTF16BE = \"\\xfe\\xff\"\n)\n\n// Determine the input stream encoding by checking the BOM symbol. If no BOM is\n// found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.\nfunc yaml_parser_determine_encoding(parser *yaml_parser_t) bool {\n\t// Ensure that we had enough bytes in the raw buffer.\n\tfor !parser.eof && len(parser.raw_buffer)-parser.raw_buffer_pos < 3 {\n\t\tif !yaml_parser_update_raw_buffer(parser) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Determine the encoding.\n\tbuf := parser.raw_buffer\n\tpos := parser.raw_buffer_pos\n\tavail := len(buf) - pos\n\tif avail >= 2 && buf[pos] == bom_UTF16LE[0] && buf[pos+1] == bom_UTF16LE[1] {\n\t\tparser.encoding = yaml_UTF16LE_ENCODING\n\t\tparser.raw_buffer_pos += 2\n\t\tparser.offset += 2\n\t} else if avail >= 2 && buf[pos] == bom_UTF16BE[0] && buf[pos+1] == bom_UTF16BE[1] {\n\t\tparser.encoding = yaml_UTF16BE_ENCODING\n\t\tparser.raw_buffer_pos += 2\n\t\tparser.offset += 2\n\t} else if avail >= 3 && buf[pos] == bom_UTF8[0] && buf[pos+1] == bom_UTF8[1] && buf[pos+2] == bom_UTF8[2] {\n\t\tparser.encoding = yaml_UTF8_ENCODING\n\t\tparser.raw_buffer_pos += 3\n\t\tparser.offset += 3\n\t} else {\n\t\tparser.encoding = yaml_UTF8_ENCODING\n\t}\n\treturn true\n}\n\n// Update the raw buffer.\nfunc yaml_parser_update_raw_buffer(parser *yaml_parser_t) bool {\n\tsize_read := 0\n\n\t// Return if the raw buffer is full.\n\tif parser.raw_buffer_pos == 0 && len(parser.raw_buffer) == cap(parser.raw_buffer) {\n\t\treturn true\n\t}\n\n\t// Return on EOF.\n\tif parser.eof {\n\t\treturn true\n\t}\n\n\t// Move the remaining bytes in the raw buffer to the beginning.\n\tif parser.raw_buffer_pos > 0 && parser.raw_buffer_pos < len(parser.raw_buffer) {\n\t\tcopy(parser.raw_buffer, parser.raw_buffer[parser.raw_buffer_pos:])\n\t}\n\tparser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)-parser.raw_buffer_pos]\n\tparser.raw_buffer_pos = 0\n\n\t// Call the read handler to fill the buffer.\n\tsize_read, err := parser.read_handler(parser, parser.raw_buffer[len(parser.raw_buffer):cap(parser.raw_buffer)])\n\tparser.raw_buffer = parser.raw_buffer[:len(parser.raw_buffer)+size_read]\n\tif err == io.EOF {\n\t\tparser.eof = true\n\t} else if err != nil {\n\t\treturn yaml_parser_set_reader_error(parser, \"input error: \"+err.Error(), parser.offset, -1)\n\t}\n\treturn true\n}\n\n// Ensure that the buffer contains at least `length` characters.\n// Return true on success, false on failure.\n//\n// The length is supposed to be significantly less that the buffer size.\nfunc yaml_parser_update_buffer(parser *yaml_parser_t, length int) bool {\n\tif parser.read_handler == nil {\n\t\tpanic(\"read handler must be set\")\n\t}\n\n\t// [Go] This function was changed to guarantee the requested length size at EOF.\n\t// The fact we need to do this is pretty awful, but the description above implies\n\t// for that to be the case, and there are tests\n\n\t// If the EOF flag is set and the raw buffer is empty, do nothing.\n\tif parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {\n\t\t// [Go] ACTUALLY! Read the documentation of this function above.\n\t\t// This is just broken. To return true, we need to have the\n\t\t// given length in the buffer. Not doing that means every single\n\t\t// check that calls this function to make sure the buffer has a\n\t\t// given length is Go) panicking; or C) accessing invalid memory.\n\t\t//return true\n\t}\n\n\t// Return if the buffer contains enough characters.\n\tif parser.unread >= length {\n\t\treturn true\n\t}\n\n\t// Determine the input encoding if it is not known yet.\n\tif parser.encoding == yaml_ANY_ENCODING {\n\t\tif !yaml_parser_determine_encoding(parser) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Move the unread characters to the beginning of the buffer.\n\tbuffer_len := len(parser.buffer)\n\tif parser.buffer_pos > 0 && parser.buffer_pos < buffer_len {\n\t\tcopy(parser.buffer, parser.buffer[parser.buffer_pos:])\n\t\tbuffer_len -= parser.buffer_pos\n\t\tparser.buffer_pos = 0\n\t} else if parser.buffer_pos == buffer_len {\n\t\tbuffer_len = 0\n\t\tparser.buffer_pos = 0\n\t}\n\n\t// Open the whole buffer for writing, and cut it before returning.\n\tparser.buffer = parser.buffer[:cap(parser.buffer)]\n\n\t// Fill the buffer until it has enough characters.\n\tfirst := true\n\tfor parser.unread < length {\n\n\t\t// Fill the raw buffer if necessary.\n\t\tif !first || parser.raw_buffer_pos == len(parser.raw_buffer) {\n\t\t\tif !yaml_parser_update_raw_buffer(parser) {\n\t\t\t\tparser.buffer = parser.buffer[:buffer_len]\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tfirst = false\n\n\t\t// Decode the raw buffer.\n\tinner:\n\t\tfor parser.raw_buffer_pos != len(parser.raw_buffer) {\n\t\t\tvar value rune\n\t\t\tvar width int\n\n\t\t\traw_unread := len(parser.raw_buffer) - parser.raw_buffer_pos\n\n\t\t\t// Decode the next character.\n\t\t\tswitch parser.encoding {\n\t\t\tcase yaml_UTF8_ENCODING:\n\t\t\t\t// Decode a UTF-8 character.  Check RFC 3629\n\t\t\t\t// (http://www.ietf.org/rfc/rfc3629.txt) for more details.\n\t\t\t\t//\n\t\t\t\t// The following table (taken from the RFC) is used for\n\t\t\t\t// decoding.\n\t\t\t\t//\n\t\t\t\t//    Char. number range |        UTF-8 octet sequence\n\t\t\t\t//      (hexadecimal)    |              (binary)\n\t\t\t\t//   --------------------+------------------------------------\n\t\t\t\t//   0000 0000-0000 007F | 0xxxxxxx\n\t\t\t\t//   0000 0080-0000 07FF | 110xxxxx 10xxxxxx\n\t\t\t\t//   0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx\n\t\t\t\t//   0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n\t\t\t\t//\n\t\t\t\t// Additionally, the characters in the range 0xD800-0xDFFF\n\t\t\t\t// are prohibited as they are reserved for use with UTF-16\n\t\t\t\t// surrogate pairs.\n\n\t\t\t\t// Determine the length of the UTF-8 sequence.\n\t\t\t\toctet := parser.raw_buffer[parser.raw_buffer_pos]\n\t\t\t\tswitch {\n\t\t\t\tcase octet&0x80 == 0x00:\n\t\t\t\t\twidth = 1\n\t\t\t\tcase octet&0xE0 == 0xC0:\n\t\t\t\t\twidth = 2\n\t\t\t\tcase octet&0xF0 == 0xE0:\n\t\t\t\t\twidth = 3\n\t\t\t\tcase octet&0xF8 == 0xF0:\n\t\t\t\t\twidth = 4\n\t\t\t\tdefault:\n\t\t\t\t\t// The leading octet is invalid.\n\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\"invalid leading UTF-8 octet\",\n\t\t\t\t\t\tparser.offset, int(octet))\n\t\t\t\t}\n\n\t\t\t\t// Check if the raw buffer contains an incomplete character.\n\t\t\t\tif width > raw_unread {\n\t\t\t\t\tif parser.eof {\n\t\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\t\"incomplete UTF-8 octet sequence\",\n\t\t\t\t\t\t\tparser.offset, -1)\n\t\t\t\t\t}\n\t\t\t\t\tbreak inner\n\t\t\t\t}\n\n\t\t\t\t// Decode the leading octet.\n\t\t\t\tswitch {\n\t\t\t\tcase octet&0x80 == 0x00:\n\t\t\t\t\tvalue = rune(octet & 0x7F)\n\t\t\t\tcase octet&0xE0 == 0xC0:\n\t\t\t\t\tvalue = rune(octet & 0x1F)\n\t\t\t\tcase octet&0xF0 == 0xE0:\n\t\t\t\t\tvalue = rune(octet & 0x0F)\n\t\t\t\tcase octet&0xF8 == 0xF0:\n\t\t\t\t\tvalue = rune(octet & 0x07)\n\t\t\t\tdefault:\n\t\t\t\t\tvalue = 0\n\t\t\t\t}\n\n\t\t\t\t// Check and decode the trailing octets.\n\t\t\t\tfor k := 1; k < width; k++ {\n\t\t\t\t\toctet = parser.raw_buffer[parser.raw_buffer_pos+k]\n\n\t\t\t\t\t// Check if the octet is valid.\n\t\t\t\t\tif (octet & 0xC0) != 0x80 {\n\t\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\t\"invalid trailing UTF-8 octet\",\n\t\t\t\t\t\t\tparser.offset+k, int(octet))\n\t\t\t\t\t}\n\n\t\t\t\t\t// Decode the octet.\n\t\t\t\t\tvalue = (value << 6) + rune(octet&0x3F)\n\t\t\t\t}\n\n\t\t\t\t// Check the length of the sequence against the value.\n\t\t\t\tswitch {\n\t\t\t\tcase width == 1:\n\t\t\t\tcase width == 2 && value >= 0x80:\n\t\t\t\tcase width == 3 && value >= 0x800:\n\t\t\t\tcase width == 4 && value >= 0x10000:\n\t\t\t\tdefault:\n\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\"invalid length of a UTF-8 sequence\",\n\t\t\t\t\t\tparser.offset, -1)\n\t\t\t\t}\n\n\t\t\t\t// Check the range of the value.\n\t\t\t\tif value >= 0xD800 && value <= 0xDFFF || value > 0x10FFFF {\n\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\"invalid Unicode character\",\n\t\t\t\t\t\tparser.offset, int(value))\n\t\t\t\t}\n\n\t\t\tcase yaml_UTF16LE_ENCODING, yaml_UTF16BE_ENCODING:\n\t\t\t\tvar low, high int\n\t\t\t\tif parser.encoding == yaml_UTF16LE_ENCODING {\n\t\t\t\t\tlow, high = 0, 1\n\t\t\t\t} else {\n\t\t\t\t\tlow, high = 1, 0\n\t\t\t\t}\n\n\t\t\t\t// The UTF-16 encoding is not as simple as one might\n\t\t\t\t// naively think.  Check RFC 2781\n\t\t\t\t// (http://www.ietf.org/rfc/rfc2781.txt).\n\t\t\t\t//\n\t\t\t\t// Normally, two subsequent bytes describe a Unicode\n\t\t\t\t// character.  However a special technique (called a\n\t\t\t\t// surrogate pair) is used for specifying character\n\t\t\t\t// values larger than 0xFFFF.\n\t\t\t\t//\n\t\t\t\t// A surrogate pair consists of two pseudo-characters:\n\t\t\t\t//      high surrogate area (0xD800-0xDBFF)\n\t\t\t\t//      low surrogate area (0xDC00-0xDFFF)\n\t\t\t\t//\n\t\t\t\t// The following formulas are used for decoding\n\t\t\t\t// and encoding characters using surrogate pairs:\n\t\t\t\t//\n\t\t\t\t//  U  = U' + 0x10000   (0x01 00 00 <= U <= 0x10 FF FF)\n\t\t\t\t//  U' = yyyyyyyyyyxxxxxxxxxx   (0 <= U' <= 0x0F FF FF)\n\t\t\t\t//  W1 = 110110yyyyyyyyyy\n\t\t\t\t//  W2 = 110111xxxxxxxxxx\n\t\t\t\t//\n\t\t\t\t// where U is the character value, W1 is the high surrogate\n\t\t\t\t// area, W2 is the low surrogate area.\n\n\t\t\t\t// Check for incomplete UTF-16 character.\n\t\t\t\tif raw_unread < 2 {\n\t\t\t\t\tif parser.eof {\n\t\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\t\"incomplete UTF-16 character\",\n\t\t\t\t\t\t\tparser.offset, -1)\n\t\t\t\t\t}\n\t\t\t\t\tbreak inner\n\t\t\t\t}\n\n\t\t\t\t// Get the character.\n\t\t\t\tvalue = rune(parser.raw_buffer[parser.raw_buffer_pos+low]) +\n\t\t\t\t\t(rune(parser.raw_buffer[parser.raw_buffer_pos+high]) << 8)\n\n\t\t\t\t// Check for unexpected low surrogate area.\n\t\t\t\tif value&0xFC00 == 0xDC00 {\n\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\"unexpected low surrogate area\",\n\t\t\t\t\t\tparser.offset, int(value))\n\t\t\t\t}\n\n\t\t\t\t// Check for a high surrogate area.\n\t\t\t\tif value&0xFC00 == 0xD800 {\n\t\t\t\t\twidth = 4\n\n\t\t\t\t\t// Check for incomplete surrogate pair.\n\t\t\t\t\tif raw_unread < 4 {\n\t\t\t\t\t\tif parser.eof {\n\t\t\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\t\t\"incomplete UTF-16 surrogate pair\",\n\t\t\t\t\t\t\t\tparser.offset, -1)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak inner\n\t\t\t\t\t}\n\n\t\t\t\t\t// Get the next character.\n\t\t\t\t\tvalue2 := rune(parser.raw_buffer[parser.raw_buffer_pos+low+2]) +\n\t\t\t\t\t\t(rune(parser.raw_buffer[parser.raw_buffer_pos+high+2]) << 8)\n\n\t\t\t\t\t// Check for a low surrogate area.\n\t\t\t\t\tif value2&0xFC00 != 0xDC00 {\n\t\t\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\t\t\"expected low surrogate area\",\n\t\t\t\t\t\t\tparser.offset+2, int(value2))\n\t\t\t\t\t}\n\n\t\t\t\t\t// Generate the value of the surrogate pair.\n\t\t\t\t\tvalue = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF)\n\t\t\t\t} else {\n\t\t\t\t\twidth = 2\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tpanic(\"impossible\")\n\t\t\t}\n\n\t\t\t// Check if the character is in the allowed range:\n\t\t\t//      #x9 | #xA | #xD | [#x20-#x7E]               (8 bit)\n\t\t\t//      | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD]    (16 bit)\n\t\t\t//      | [#x10000-#x10FFFF]                        (32 bit)\n\t\t\tswitch {\n\t\t\tcase value == 0x09:\n\t\t\tcase value == 0x0A:\n\t\t\tcase value == 0x0D:\n\t\t\tcase value >= 0x20 && value <= 0x7E:\n\t\t\tcase value == 0x85:\n\t\t\tcase value >= 0xA0 && value <= 0xD7FF:\n\t\t\tcase value >= 0xE000 && value <= 0xFFFD:\n\t\t\tcase value >= 0x10000 && value <= 0x10FFFF:\n\t\t\tdefault:\n\t\t\t\treturn yaml_parser_set_reader_error(parser,\n\t\t\t\t\t\"control characters are not allowed\",\n\t\t\t\t\tparser.offset, int(value))\n\t\t\t}\n\n\t\t\t// Move the raw pointers.\n\t\t\tparser.raw_buffer_pos += width\n\t\t\tparser.offset += width\n\n\t\t\t// Finally put the character into the buffer.\n\t\t\tif value <= 0x7F {\n\t\t\t\t// 0000 0000-0000 007F . 0xxxxxxx\n\t\t\t\tparser.buffer[buffer_len+0] = byte(value)\n\t\t\t\tbuffer_len += 1\n\t\t\t} else if value <= 0x7FF {\n\t\t\t\t// 0000 0080-0000 07FF . 110xxxxx 10xxxxxx\n\t\t\t\tparser.buffer[buffer_len+0] = byte(0xC0 + (value >> 6))\n\t\t\t\tparser.buffer[buffer_len+1] = byte(0x80 + (value & 0x3F))\n\t\t\t\tbuffer_len += 2\n\t\t\t} else if value <= 0xFFFF {\n\t\t\t\t// 0000 0800-0000 FFFF . 1110xxxx 10xxxxxx 10xxxxxx\n\t\t\t\tparser.buffer[buffer_len+0] = byte(0xE0 + (value >> 12))\n\t\t\t\tparser.buffer[buffer_len+1] = byte(0x80 + ((value >> 6) & 0x3F))\n\t\t\t\tparser.buffer[buffer_len+2] = byte(0x80 + (value & 0x3F))\n\t\t\t\tbuffer_len += 3\n\t\t\t} else {\n\t\t\t\t// 0001 0000-0010 FFFF . 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n\t\t\t\tparser.buffer[buffer_len+0] = byte(0xF0 + (value >> 18))\n\t\t\t\tparser.buffer[buffer_len+1] = byte(0x80 + ((value >> 12) & 0x3F))\n\t\t\t\tparser.buffer[buffer_len+2] = byte(0x80 + ((value >> 6) & 0x3F))\n\t\t\t\tparser.buffer[buffer_len+3] = byte(0x80 + (value & 0x3F))\n\t\t\t\tbuffer_len += 4\n\t\t\t}\n\n\t\t\tparser.unread++\n\t\t}\n\n\t\t// On EOF, put NUL into the buffer and return.\n\t\tif parser.eof {\n\t\t\tparser.buffer[buffer_len] = 0\n\t\t\tbuffer_len++\n\t\t\tparser.unread++\n\t\t\tbreak\n\t\t}\n\t}\n\t// [Go] Read the documentation of this function above. To return true,\n\t// we need to have the given length in the buffer. Not doing that means\n\t// every single check that calls this function to make sure the buffer\n\t// has a given length is Go) panicking; or C) accessing invalid memory.\n\t// This happens here due to the EOF above breaking early.\n\tfor buffer_len < length {\n\t\tparser.buffer[buffer_len] = 0\n\t\tbuffer_len++\n\t}\n\tparser.buffer = parser.buffer[:buffer_len]\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/resolve.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\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//     http://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\npackage yaml\n\nimport (\n\t\"encoding/base64\"\n\t\"math\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype resolveMapItem struct {\n\tvalue interface{}\n\ttag   string\n}\n\nvar resolveTable = make([]byte, 256)\nvar resolveMap = make(map[string]resolveMapItem)\n\nfunc init() {\n\tt := resolveTable\n\tt[int('+')] = 'S' // Sign\n\tt[int('-')] = 'S'\n\tfor _, c := range \"0123456789\" {\n\t\tt[int(c)] = 'D' // Digit\n\t}\n\tfor _, c := range \"yYnNtTfFoO~\" {\n\t\tt[int(c)] = 'M' // In map\n\t}\n\tt[int('.')] = '.' // Float (potentially in map)\n\n\tvar resolveMapList = []struct {\n\t\tv   interface{}\n\t\ttag string\n\t\tl   []string\n\t}{\n\t\t{true, boolTag, []string{\"true\", \"True\", \"TRUE\"}},\n\t\t{false, boolTag, []string{\"false\", \"False\", \"FALSE\"}},\n\t\t{nil, nullTag, []string{\"\", \"~\", \"null\", \"Null\", \"NULL\"}},\n\t\t{math.NaN(), floatTag, []string{\".nan\", \".NaN\", \".NAN\"}},\n\t\t{math.Inf(+1), floatTag, []string{\".inf\", \".Inf\", \".INF\"}},\n\t\t{math.Inf(+1), floatTag, []string{\"+.inf\", \"+.Inf\", \"+.INF\"}},\n\t\t{math.Inf(-1), floatTag, []string{\"-.inf\", \"-.Inf\", \"-.INF\"}},\n\t\t{\"<<\", mergeTag, []string{\"<<\"}},\n\t}\n\n\tm := resolveMap\n\tfor _, item := range resolveMapList {\n\t\tfor _, s := range item.l {\n\t\t\tm[s] = resolveMapItem{item.v, item.tag}\n\t\t}\n\t}\n}\n\nconst (\n\tnullTag      = \"!!null\"\n\tboolTag      = \"!!bool\"\n\tstrTag       = \"!!str\"\n\tintTag       = \"!!int\"\n\tfloatTag     = \"!!float\"\n\ttimestampTag = \"!!timestamp\"\n\tseqTag       = \"!!seq\"\n\tmapTag       = \"!!map\"\n\tbinaryTag    = \"!!binary\"\n\tmergeTag     = \"!!merge\"\n)\n\nvar longTags = make(map[string]string)\nvar shortTags = make(map[string]string)\n\nfunc init() {\n\tfor _, stag := range []string{nullTag, boolTag, strTag, intTag, floatTag, timestampTag, seqTag, mapTag, binaryTag, mergeTag} {\n\t\tltag := longTag(stag)\n\t\tlongTags[stag] = ltag\n\t\tshortTags[ltag] = stag\n\t}\n}\n\nconst longTagPrefix = \"tag:yaml.org,2002:\"\n\nfunc shortTag(tag string) string {\n\tif strings.HasPrefix(tag, longTagPrefix) {\n\t\tif stag, ok := shortTags[tag]; ok {\n\t\t\treturn stag\n\t\t}\n\t\treturn \"!!\" + tag[len(longTagPrefix):]\n\t}\n\treturn tag\n}\n\nfunc longTag(tag string) string {\n\tif strings.HasPrefix(tag, \"!!\") {\n\t\tif ltag, ok := longTags[tag]; ok {\n\t\t\treturn ltag\n\t\t}\n\t\treturn longTagPrefix + tag[2:]\n\t}\n\treturn tag\n}\n\nfunc resolvableTag(tag string) bool {\n\tswitch tag {\n\tcase \"\", strTag, boolTag, intTag, floatTag, nullTag, timestampTag:\n\t\treturn true\n\t}\n\treturn false\n}\n\nvar yamlStyleFloat = regexp.MustCompile(`^[-+]?(\\.[0-9]+|[0-9]+(\\.[0-9]*)?)([eE][-+]?[0-9]+)?$`)\n\nfunc resolve(tag string, in string) (rtag string, out interface{}) {\n\ttag = shortTag(tag)\n\tif !resolvableTag(tag) {\n\t\treturn tag, in\n\t}\n\n\tdefer func() {\n\t\tswitch tag {\n\t\tcase \"\", rtag, strTag, binaryTag:\n\t\t\treturn\n\t\tcase floatTag:\n\t\t\tif rtag == intTag {\n\t\t\t\tswitch v := out.(type) {\n\t\t\t\tcase int64:\n\t\t\t\t\trtag = floatTag\n\t\t\t\t\tout = float64(v)\n\t\t\t\t\treturn\n\t\t\t\tcase int:\n\t\t\t\t\trtag = floatTag\n\t\t\t\t\tout = float64(v)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfailf(\"cannot decode %s `%s` as a %s\", shortTag(rtag), in, shortTag(tag))\n\t}()\n\n\t// Any data is accepted as a !!str or !!binary.\n\t// Otherwise, the prefix is enough of a hint about what it might be.\n\thint := byte('N')\n\tif in != \"\" {\n\t\thint = resolveTable[in[0]]\n\t}\n\tif hint != 0 && tag != strTag && tag != binaryTag {\n\t\t// Handle things we can lookup in a map.\n\t\tif item, ok := resolveMap[in]; ok {\n\t\t\treturn item.tag, item.value\n\t\t}\n\n\t\t// Base 60 floats are a bad idea, were dropped in YAML 1.2, and\n\t\t// are purposefully unsupported here. They're still quoted on\n\t\t// the way out for compatibility with other parser, though.\n\n\t\tswitch hint {\n\t\tcase 'M':\n\t\t\t// We've already checked the map above.\n\n\t\tcase '.':\n\t\t\t// Not in the map, so maybe a normal float.\n\t\t\tfloatv, err := strconv.ParseFloat(in, 64)\n\t\t\tif err == nil {\n\t\t\t\treturn floatTag, floatv\n\t\t\t}\n\n\t\tcase 'D', 'S':\n\t\t\t// Int, float, or timestamp.\n\t\t\t// Only try values as a timestamp if the value is unquoted or there's an explicit\n\t\t\t// !!timestamp tag.\n\t\t\tif tag == \"\" || tag == timestampTag {\n\t\t\t\tt, ok := parseTimestamp(in)\n\t\t\t\tif ok {\n\t\t\t\t\treturn timestampTag, t\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplain := strings.Replace(in, \"_\", \"\", -1)\n\t\t\tintv, err := strconv.ParseInt(plain, 0, 64)\n\t\t\tif err == nil {\n\t\t\t\tif intv == int64(int(intv)) {\n\t\t\t\t\treturn intTag, int(intv)\n\t\t\t\t} else {\n\t\t\t\t\treturn intTag, intv\n\t\t\t\t}\n\t\t\t}\n\t\t\tuintv, err := strconv.ParseUint(plain, 0, 64)\n\t\t\tif err == nil {\n\t\t\t\treturn intTag, uintv\n\t\t\t}\n\t\t\tif yamlStyleFloat.MatchString(plain) {\n\t\t\t\tfloatv, err := strconv.ParseFloat(plain, 64)\n\t\t\t\tif err == nil {\n\t\t\t\t\treturn floatTag, floatv\n\t\t\t\t}\n\t\t\t}\n\t\t\tif strings.HasPrefix(plain, \"0b\") {\n\t\t\t\tintv, err := strconv.ParseInt(plain[2:], 2, 64)\n\t\t\t\tif err == nil {\n\t\t\t\t\tif intv == int64(int(intv)) {\n\t\t\t\t\t\treturn intTag, int(intv)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn intTag, intv\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tuintv, err := strconv.ParseUint(plain[2:], 2, 64)\n\t\t\t\tif err == nil {\n\t\t\t\t\treturn intTag, uintv\n\t\t\t\t}\n\t\t\t} else if strings.HasPrefix(plain, \"-0b\") {\n\t\t\t\tintv, err := strconv.ParseInt(\"-\"+plain[3:], 2, 64)\n\t\t\t\tif err == nil {\n\t\t\t\t\tif true || intv == int64(int(intv)) {\n\t\t\t\t\t\treturn intTag, int(intv)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn intTag, intv\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Octals as introduced in version 1.2 of the spec.\n\t\t\t// Octals from the 1.1 spec, spelled as 0777, are still\n\t\t\t// decoded by default in v3 as well for compatibility.\n\t\t\t// May be dropped in v4 depending on how usage evolves.\n\t\t\tif strings.HasPrefix(plain, \"0o\") {\n\t\t\t\tintv, err := strconv.ParseInt(plain[2:], 8, 64)\n\t\t\t\tif err == nil {\n\t\t\t\t\tif intv == int64(int(intv)) {\n\t\t\t\t\t\treturn intTag, int(intv)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn intTag, intv\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tuintv, err := strconv.ParseUint(plain[2:], 8, 64)\n\t\t\t\tif err == nil {\n\t\t\t\t\treturn intTag, uintv\n\t\t\t\t}\n\t\t\t} else if strings.HasPrefix(plain, \"-0o\") {\n\t\t\t\tintv, err := strconv.ParseInt(\"-\"+plain[3:], 8, 64)\n\t\t\t\tif err == nil {\n\t\t\t\t\tif true || intv == int64(int(intv)) {\n\t\t\t\t\t\treturn intTag, int(intv)\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn intTag, intv\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"internal error: missing handler for resolver table: \" + string(rune(hint)) + \" (with \" + in + \")\")\n\t\t}\n\t}\n\treturn strTag, in\n}\n\n// encodeBase64 encodes s as base64 that is broken up into multiple lines\n// as appropriate for the resulting length.\nfunc encodeBase64(s string) string {\n\tconst lineLen = 70\n\tencLen := base64.StdEncoding.EncodedLen(len(s))\n\tlines := encLen/lineLen + 1\n\tbuf := make([]byte, encLen*2+lines)\n\tin := buf[0:encLen]\n\tout := buf[encLen:]\n\tbase64.StdEncoding.Encode(in, []byte(s))\n\tk := 0\n\tfor i := 0; i < len(in); i += lineLen {\n\t\tj := i + lineLen\n\t\tif j > len(in) {\n\t\t\tj = len(in)\n\t\t}\n\t\tk += copy(out[k:], in[i:j])\n\t\tif lines > 1 {\n\t\t\tout[k] = '\\n'\n\t\t\tk++\n\t\t}\n\t}\n\treturn string(out[:k])\n}\n\n// This is a subset of the formats allowed by the regular expression\n// defined at http://yaml.org/type/timestamp.html.\nvar allowedTimestampFormats = []string{\n\t\"2006-1-2T15:4:5.999999999Z07:00\", // RCF3339Nano with short date fields.\n\t\"2006-1-2t15:4:5.999999999Z07:00\", // RFC3339Nano with short date fields and lower-case \"t\".\n\t\"2006-1-2 15:4:5.999999999\",       // space separated with no time zone\n\t\"2006-1-2\",                        // date only\n\t// Notable exception: time.Parse cannot handle: \"2001-12-14 21:59:43.10 -5\"\n\t// from the set of examples.\n}\n\n// parseTimestamp parses s as a timestamp string and\n// returns the timestamp and reports whether it succeeded.\n// Timestamp formats are defined at http://yaml.org/type/timestamp.html\nfunc parseTimestamp(s string) (time.Time, bool) {\n\t// TODO write code to check all the formats supported by\n\t// http://yaml.org/type/timestamp.html instead of using time.Parse.\n\n\t// Quick check: all date formats start with YYYY-.\n\ti := 0\n\tfor ; i < len(s); i++ {\n\t\tif c := s[i]; c < '0' || c > '9' {\n\t\t\tbreak\n\t\t}\n\t}\n\tif i != 4 || i == len(s) || s[i] != '-' {\n\t\treturn time.Time{}, false\n\t}\n\tfor _, format := range allowedTimestampFormats {\n\t\tif t, err := time.Parse(format, s); err == nil {\n\t\t\treturn t, true\n\t\t}\n\t}\n\treturn time.Time{}, false\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/scannerc.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n)\n\n// Introduction\n// ************\n//\n// The following notes assume that you are familiar with the YAML specification\n// (http://yaml.org/spec/1.2/spec.html).  We mostly follow it, although in\n// some cases we are less restrictive that it requires.\n//\n// The process of transforming a YAML stream into a sequence of events is\n// divided on two steps: Scanning and Parsing.\n//\n// The Scanner transforms the input stream into a sequence of tokens, while the\n// parser transform the sequence of tokens produced by the Scanner into a\n// sequence of parsing events.\n//\n// The Scanner is rather clever and complicated. The Parser, on the contrary,\n// is a straightforward implementation of a recursive-descendant parser (or,\n// LL(1) parser, as it is usually called).\n//\n// Actually there are two issues of Scanning that might be called \"clever\", the\n// rest is quite straightforward.  The issues are \"block collection start\" and\n// \"simple keys\".  Both issues are explained below in details.\n//\n// Here the Scanning step is explained and implemented.  We start with the list\n// of all the tokens produced by the Scanner together with short descriptions.\n//\n// Now, tokens:\n//\n//      STREAM-START(encoding)          # The stream start.\n//      STREAM-END                      # The stream end.\n//      VERSION-DIRECTIVE(major,minor)  # The '%YAML' directive.\n//      TAG-DIRECTIVE(handle,prefix)    # The '%TAG' directive.\n//      DOCUMENT-START                  # '---'\n//      DOCUMENT-END                    # '...'\n//      BLOCK-SEQUENCE-START            # Indentation increase denoting a block\n//      BLOCK-MAPPING-START             # sequence or a block mapping.\n//      BLOCK-END                       # Indentation decrease.\n//      FLOW-SEQUENCE-START             # '['\n//      FLOW-SEQUENCE-END               # ']'\n//      BLOCK-SEQUENCE-START            # '{'\n//      BLOCK-SEQUENCE-END              # '}'\n//      BLOCK-ENTRY                     # '-'\n//      FLOW-ENTRY                      # ','\n//      KEY                             # '?' or nothing (simple keys).\n//      VALUE                           # ':'\n//      ALIAS(anchor)                   # '*anchor'\n//      ANCHOR(anchor)                  # '&anchor'\n//      TAG(handle,suffix)              # '!handle!suffix'\n//      SCALAR(value,style)             # A scalar.\n//\n// The following two tokens are \"virtual\" tokens denoting the beginning and the\n// end of the stream:\n//\n//      STREAM-START(encoding)\n//      STREAM-END\n//\n// We pass the information about the input stream encoding with the\n// STREAM-START token.\n//\n// The next two tokens are responsible for tags:\n//\n//      VERSION-DIRECTIVE(major,minor)\n//      TAG-DIRECTIVE(handle,prefix)\n//\n// Example:\n//\n//      %YAML   1.1\n//      %TAG    !   !foo\n//      %TAG    !yaml!  tag:yaml.org,2002:\n//      ---\n//\n// The correspoding sequence of tokens:\n//\n//      STREAM-START(utf-8)\n//      VERSION-DIRECTIVE(1,1)\n//      TAG-DIRECTIVE(\"!\",\"!foo\")\n//      TAG-DIRECTIVE(\"!yaml\",\"tag:yaml.org,2002:\")\n//      DOCUMENT-START\n//      STREAM-END\n//\n// Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole\n// line.\n//\n// The document start and end indicators are represented by:\n//\n//      DOCUMENT-START\n//      DOCUMENT-END\n//\n// Note that if a YAML stream contains an implicit document (without '---'\n// and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be\n// produced.\n//\n// In the following examples, we present whole documents together with the\n// produced tokens.\n//\n//      1. An implicit document:\n//\n//          'a scalar'\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          SCALAR(\"a scalar\",single-quoted)\n//          STREAM-END\n//\n//      2. An explicit document:\n//\n//          ---\n//          'a scalar'\n//          ...\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          DOCUMENT-START\n//          SCALAR(\"a scalar\",single-quoted)\n//          DOCUMENT-END\n//          STREAM-END\n//\n//      3. Several documents in a stream:\n//\n//          'a scalar'\n//          ---\n//          'another scalar'\n//          ---\n//          'yet another scalar'\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          SCALAR(\"a scalar\",single-quoted)\n//          DOCUMENT-START\n//          SCALAR(\"another scalar\",single-quoted)\n//          DOCUMENT-START\n//          SCALAR(\"yet another scalar\",single-quoted)\n//          STREAM-END\n//\n// We have already introduced the SCALAR token above.  The following tokens are\n// used to describe aliases, anchors, tag, and scalars:\n//\n//      ALIAS(anchor)\n//      ANCHOR(anchor)\n//      TAG(handle,suffix)\n//      SCALAR(value,style)\n//\n// The following series of examples illustrate the usage of these tokens:\n//\n//      1. A recursive sequence:\n//\n//          &A [ *A ]\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          ANCHOR(\"A\")\n//          FLOW-SEQUENCE-START\n//          ALIAS(\"A\")\n//          FLOW-SEQUENCE-END\n//          STREAM-END\n//\n//      2. A tagged scalar:\n//\n//          !!float \"3.14\"  # A good approximation.\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          TAG(\"!!\",\"float\")\n//          SCALAR(\"3.14\",double-quoted)\n//          STREAM-END\n//\n//      3. Various scalar styles:\n//\n//          --- # Implicit empty plain scalars do not produce tokens.\n//          --- a plain scalar\n//          --- 'a single-quoted scalar'\n//          --- \"a double-quoted scalar\"\n//          --- |-\n//            a literal scalar\n//          --- >-\n//            a folded\n//            scalar\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          DOCUMENT-START\n//          DOCUMENT-START\n//          SCALAR(\"a plain scalar\",plain)\n//          DOCUMENT-START\n//          SCALAR(\"a single-quoted scalar\",single-quoted)\n//          DOCUMENT-START\n//          SCALAR(\"a double-quoted scalar\",double-quoted)\n//          DOCUMENT-START\n//          SCALAR(\"a literal scalar\",literal)\n//          DOCUMENT-START\n//          SCALAR(\"a folded scalar\",folded)\n//          STREAM-END\n//\n// Now it's time to review collection-related tokens. We will start with\n// flow collections:\n//\n//      FLOW-SEQUENCE-START\n//      FLOW-SEQUENCE-END\n//      FLOW-MAPPING-START\n//      FLOW-MAPPING-END\n//      FLOW-ENTRY\n//      KEY\n//      VALUE\n//\n// The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and\n// FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}'\n// correspondingly.  FLOW-ENTRY represent the ',' indicator.  Finally the\n// indicators '?' and ':', which are used for denoting mapping keys and values,\n// are represented by the KEY and VALUE tokens.\n//\n// The following examples show flow collections:\n//\n//      1. A flow sequence:\n//\n//          [item 1, item 2, item 3]\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          FLOW-SEQUENCE-START\n//          SCALAR(\"item 1\",plain)\n//          FLOW-ENTRY\n//          SCALAR(\"item 2\",plain)\n//          FLOW-ENTRY\n//          SCALAR(\"item 3\",plain)\n//          FLOW-SEQUENCE-END\n//          STREAM-END\n//\n//      2. A flow mapping:\n//\n//          {\n//              a simple key: a value,  # Note that the KEY token is produced.\n//              ? a complex key: another value,\n//          }\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          FLOW-MAPPING-START\n//          KEY\n//          SCALAR(\"a simple key\",plain)\n//          VALUE\n//          SCALAR(\"a value\",plain)\n//          FLOW-ENTRY\n//          KEY\n//          SCALAR(\"a complex key\",plain)\n//          VALUE\n//          SCALAR(\"another value\",plain)\n//          FLOW-ENTRY\n//          FLOW-MAPPING-END\n//          STREAM-END\n//\n// A simple key is a key which is not denoted by the '?' indicator.  Note that\n// the Scanner still produce the KEY token whenever it encounters a simple key.\n//\n// For scanning block collections, the following tokens are used (note that we\n// repeat KEY and VALUE here):\n//\n//      BLOCK-SEQUENCE-START\n//      BLOCK-MAPPING-START\n//      BLOCK-END\n//      BLOCK-ENTRY\n//      KEY\n//      VALUE\n//\n// The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation\n// increase that precedes a block collection (cf. the INDENT token in Python).\n// The token BLOCK-END denote indentation decrease that ends a block collection\n// (cf. the DEDENT token in Python).  However YAML has some syntax pecularities\n// that makes detections of these tokens more complex.\n//\n// The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators\n// '-', '?', and ':' correspondingly.\n//\n// The following examples show how the tokens BLOCK-SEQUENCE-START,\n// BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner:\n//\n//      1. Block sequences:\n//\n//          - item 1\n//          - item 2\n//          -\n//            - item 3.1\n//            - item 3.2\n//          -\n//            key 1: value 1\n//            key 2: value 2\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          BLOCK-SEQUENCE-START\n//          BLOCK-ENTRY\n//          SCALAR(\"item 1\",plain)\n//          BLOCK-ENTRY\n//          SCALAR(\"item 2\",plain)\n//          BLOCK-ENTRY\n//          BLOCK-SEQUENCE-START\n//          BLOCK-ENTRY\n//          SCALAR(\"item 3.1\",plain)\n//          BLOCK-ENTRY\n//          SCALAR(\"item 3.2\",plain)\n//          BLOCK-END\n//          BLOCK-ENTRY\n//          BLOCK-MAPPING-START\n//          KEY\n//          SCALAR(\"key 1\",plain)\n//          VALUE\n//          SCALAR(\"value 1\",plain)\n//          KEY\n//          SCALAR(\"key 2\",plain)\n//          VALUE\n//          SCALAR(\"value 2\",plain)\n//          BLOCK-END\n//          BLOCK-END\n//          STREAM-END\n//\n//      2. Block mappings:\n//\n//          a simple key: a value   # The KEY token is produced here.\n//          ? a complex key\n//          : another value\n//          a mapping:\n//            key 1: value 1\n//            key 2: value 2\n//          a sequence:\n//            - item 1\n//            - item 2\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          BLOCK-MAPPING-START\n//          KEY\n//          SCALAR(\"a simple key\",plain)\n//          VALUE\n//          SCALAR(\"a value\",plain)\n//          KEY\n//          SCALAR(\"a complex key\",plain)\n//          VALUE\n//          SCALAR(\"another value\",plain)\n//          KEY\n//          SCALAR(\"a mapping\",plain)\n//          BLOCK-MAPPING-START\n//          KEY\n//          SCALAR(\"key 1\",plain)\n//          VALUE\n//          SCALAR(\"value 1\",plain)\n//          KEY\n//          SCALAR(\"key 2\",plain)\n//          VALUE\n//          SCALAR(\"value 2\",plain)\n//          BLOCK-END\n//          KEY\n//          SCALAR(\"a sequence\",plain)\n//          VALUE\n//          BLOCK-SEQUENCE-START\n//          BLOCK-ENTRY\n//          SCALAR(\"item 1\",plain)\n//          BLOCK-ENTRY\n//          SCALAR(\"item 2\",plain)\n//          BLOCK-END\n//          BLOCK-END\n//          STREAM-END\n//\n// YAML does not always require to start a new block collection from a new\n// line.  If the current line contains only '-', '?', and ':' indicators, a new\n// block collection may start at the current line.  The following examples\n// illustrate this case:\n//\n//      1. Collections in a sequence:\n//\n//          - - item 1\n//            - item 2\n//          - key 1: value 1\n//            key 2: value 2\n//          - ? complex key\n//            : complex value\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          BLOCK-SEQUENCE-START\n//          BLOCK-ENTRY\n//          BLOCK-SEQUENCE-START\n//          BLOCK-ENTRY\n//          SCALAR(\"item 1\",plain)\n//          BLOCK-ENTRY\n//          SCALAR(\"item 2\",plain)\n//          BLOCK-END\n//          BLOCK-ENTRY\n//          BLOCK-MAPPING-START\n//          KEY\n//          SCALAR(\"key 1\",plain)\n//          VALUE\n//          SCALAR(\"value 1\",plain)\n//          KEY\n//          SCALAR(\"key 2\",plain)\n//          VALUE\n//          SCALAR(\"value 2\",plain)\n//          BLOCK-END\n//          BLOCK-ENTRY\n//          BLOCK-MAPPING-START\n//          KEY\n//          SCALAR(\"complex key\")\n//          VALUE\n//          SCALAR(\"complex value\")\n//          BLOCK-END\n//          BLOCK-END\n//          STREAM-END\n//\n//      2. Collections in a mapping:\n//\n//          ? a sequence\n//          : - item 1\n//            - item 2\n//          ? a mapping\n//          : key 1: value 1\n//            key 2: value 2\n//\n//      Tokens:\n//\n//          STREAM-START(utf-8)\n//          BLOCK-MAPPING-START\n//          KEY\n//          SCALAR(\"a sequence\",plain)\n//          VALUE\n//          BLOCK-SEQUENCE-START\n//          BLOCK-ENTRY\n//          SCALAR(\"item 1\",plain)\n//          BLOCK-ENTRY\n//          SCALAR(\"item 2\",plain)\n//          BLOCK-END\n//          KEY\n//          SCALAR(\"a mapping\",plain)\n//          VALUE\n//          BLOCK-MAPPING-START\n//          KEY\n//          SCALAR(\"key 1\",plain)\n//          VALUE\n//          SCALAR(\"value 1\",plain)\n//          KEY\n//          SCALAR(\"key 2\",plain)\n//          VALUE\n//          SCALAR(\"value 2\",plain)\n//          BLOCK-END\n//          BLOCK-END\n//          STREAM-END\n//\n// YAML also permits non-indented sequences if they are included into a block\n// mapping.  In this case, the token BLOCK-SEQUENCE-START is not produced:\n//\n//      key:\n//      - item 1    # BLOCK-SEQUENCE-START is NOT produced here.\n//      - item 2\n//\n// Tokens:\n//\n//      STREAM-START(utf-8)\n//      BLOCK-MAPPING-START\n//      KEY\n//      SCALAR(\"key\",plain)\n//      VALUE\n//      BLOCK-ENTRY\n//      SCALAR(\"item 1\",plain)\n//      BLOCK-ENTRY\n//      SCALAR(\"item 2\",plain)\n//      BLOCK-END\n//\n\n// Ensure that the buffer contains the required number of characters.\n// Return true on success, false on failure (reader error or memory error).\nfunc cache(parser *yaml_parser_t, length int) bool {\n\t// [Go] This was inlined: !cache(A, B) -> unread < B && !update(A, B)\n\treturn parser.unread >= length || yaml_parser_update_buffer(parser, length)\n}\n\n// Advance the buffer pointer.\nfunc skip(parser *yaml_parser_t) {\n\tif !is_blank(parser.buffer, parser.buffer_pos) {\n\t\tparser.newlines = 0\n\t}\n\tparser.mark.index++\n\tparser.mark.column++\n\tparser.unread--\n\tparser.buffer_pos += width(parser.buffer[parser.buffer_pos])\n}\n\nfunc skip_line(parser *yaml_parser_t) {\n\tif is_crlf(parser.buffer, parser.buffer_pos) {\n\t\tparser.mark.index += 2\n\t\tparser.mark.column = 0\n\t\tparser.mark.line++\n\t\tparser.unread -= 2\n\t\tparser.buffer_pos += 2\n\t\tparser.newlines++\n\t} else if is_break(parser.buffer, parser.buffer_pos) {\n\t\tparser.mark.index++\n\t\tparser.mark.column = 0\n\t\tparser.mark.line++\n\t\tparser.unread--\n\t\tparser.buffer_pos += width(parser.buffer[parser.buffer_pos])\n\t\tparser.newlines++\n\t}\n}\n\n// Copy a character to a string buffer and advance pointers.\nfunc read(parser *yaml_parser_t, s []byte) []byte {\n\tif !is_blank(parser.buffer, parser.buffer_pos) {\n\t\tparser.newlines = 0\n\t}\n\tw := width(parser.buffer[parser.buffer_pos])\n\tif w == 0 {\n\t\tpanic(\"invalid character sequence\")\n\t}\n\tif len(s) == 0 {\n\t\ts = make([]byte, 0, 32)\n\t}\n\tif w == 1 && len(s)+w <= cap(s) {\n\t\ts = s[:len(s)+1]\n\t\ts[len(s)-1] = parser.buffer[parser.buffer_pos]\n\t\tparser.buffer_pos++\n\t} else {\n\t\ts = append(s, parser.buffer[parser.buffer_pos:parser.buffer_pos+w]...)\n\t\tparser.buffer_pos += w\n\t}\n\tparser.mark.index++\n\tparser.mark.column++\n\tparser.unread--\n\treturn s\n}\n\n// Copy a line break character to a string buffer and advance pointers.\nfunc read_line(parser *yaml_parser_t, s []byte) []byte {\n\tbuf := parser.buffer\n\tpos := parser.buffer_pos\n\tswitch {\n\tcase buf[pos] == '\\r' && buf[pos+1] == '\\n':\n\t\t// CR LF . LF\n\t\ts = append(s, '\\n')\n\t\tparser.buffer_pos += 2\n\t\tparser.mark.index++\n\t\tparser.unread--\n\tcase buf[pos] == '\\r' || buf[pos] == '\\n':\n\t\t// CR|LF . LF\n\t\ts = append(s, '\\n')\n\t\tparser.buffer_pos += 1\n\tcase buf[pos] == '\\xC2' && buf[pos+1] == '\\x85':\n\t\t// NEL . LF\n\t\ts = append(s, '\\n')\n\t\tparser.buffer_pos += 2\n\tcase buf[pos] == '\\xE2' && buf[pos+1] == '\\x80' && (buf[pos+2] == '\\xA8' || buf[pos+2] == '\\xA9'):\n\t\t// LS|PS . LS|PS\n\t\ts = append(s, buf[parser.buffer_pos:pos+3]...)\n\t\tparser.buffer_pos += 3\n\tdefault:\n\t\treturn s\n\t}\n\tparser.mark.index++\n\tparser.mark.column = 0\n\tparser.mark.line++\n\tparser.unread--\n\tparser.newlines++\n\treturn s\n}\n\n// Get the next token.\nfunc yaml_parser_scan(parser *yaml_parser_t, token *yaml_token_t) bool {\n\t// Erase the token object.\n\t*token = yaml_token_t{} // [Go] Is this necessary?\n\n\t// No tokens after STREAM-END or error.\n\tif parser.stream_end_produced || parser.error != yaml_NO_ERROR {\n\t\treturn true\n\t}\n\n\t// Ensure that the tokens queue contains enough tokens.\n\tif !parser.token_available {\n\t\tif !yaml_parser_fetch_more_tokens(parser) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Fetch the next token from the queue.\n\t*token = parser.tokens[parser.tokens_head]\n\tparser.tokens_head++\n\tparser.tokens_parsed++\n\tparser.token_available = false\n\n\tif token.typ == yaml_STREAM_END_TOKEN {\n\t\tparser.stream_end_produced = true\n\t}\n\treturn true\n}\n\n// Set the scanner error and return false.\nfunc yaml_parser_set_scanner_error(parser *yaml_parser_t, context string, context_mark yaml_mark_t, problem string) bool {\n\tparser.error = yaml_SCANNER_ERROR\n\tparser.context = context\n\tparser.context_mark = context_mark\n\tparser.problem = problem\n\tparser.problem_mark = parser.mark\n\treturn false\n}\n\nfunc yaml_parser_set_scanner_tag_error(parser *yaml_parser_t, directive bool, context_mark yaml_mark_t, problem string) bool {\n\tcontext := \"while parsing a tag\"\n\tif directive {\n\t\tcontext = \"while parsing a %TAG directive\"\n\t}\n\treturn yaml_parser_set_scanner_error(parser, context, context_mark, problem)\n}\n\nfunc trace(args ...interface{}) func() {\n\tpargs := append([]interface{}{\"+++\"}, args...)\n\tfmt.Println(pargs...)\n\tpargs = append([]interface{}{\"---\"}, args...)\n\treturn func() { fmt.Println(pargs...) }\n}\n\n// Ensure that the tokens queue contains at least one token which can be\n// returned to the Parser.\nfunc yaml_parser_fetch_more_tokens(parser *yaml_parser_t) bool {\n\t// While we need more tokens to fetch, do it.\n\tfor {\n\t\t// [Go] The comment parsing logic requires a lookahead of two tokens\n\t\t// so that foot comments may be parsed in time of associating them\n\t\t// with the tokens that are parsed before them, and also for line\n\t\t// comments to be transformed into head comments in some edge cases.\n\t\tif parser.tokens_head < len(parser.tokens)-2 {\n\t\t\t// If a potential simple key is at the head position, we need to fetch\n\t\t\t// the next token to disambiguate it.\n\t\t\thead_tok_idx, ok := parser.simple_keys_by_tok[parser.tokens_parsed]\n\t\t\tif !ok {\n\t\t\t\tbreak\n\t\t\t} else if valid, ok := yaml_simple_key_is_valid(parser, &parser.simple_keys[head_tok_idx]); !ok {\n\t\t\t\treturn false\n\t\t\t} else if !valid {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\t// Fetch the next token.\n\t\tif !yaml_parser_fetch_next_token(parser) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tparser.token_available = true\n\treturn true\n}\n\n// The dispatcher for token fetchers.\nfunc yaml_parser_fetch_next_token(parser *yaml_parser_t) (ok bool) {\n\t// Ensure that the buffer is initialized.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\n\t// Check if we just started scanning.  Fetch STREAM-START then.\n\tif !parser.stream_start_produced {\n\t\treturn yaml_parser_fetch_stream_start(parser)\n\t}\n\n\tscan_mark := parser.mark\n\n\t// Eat whitespaces and comments until we reach the next token.\n\tif !yaml_parser_scan_to_next_token(parser) {\n\t\treturn false\n\t}\n\n\t// [Go] While unrolling indents, transform the head comments of prior\n\t// indentation levels observed after scan_start into foot comments at\n\t// the respective indexes.\n\n\t// Check the indentation level against the current column.\n\tif !yaml_parser_unroll_indent(parser, parser.mark.column, scan_mark) {\n\t\treturn false\n\t}\n\n\t// Ensure that the buffer contains at least 4 characters.  4 is the length\n\t// of the longest indicators ('--- ' and '... ').\n\tif parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {\n\t\treturn false\n\t}\n\n\t// Is it the end of the stream?\n\tif is_z(parser.buffer, parser.buffer_pos) {\n\t\treturn yaml_parser_fetch_stream_end(parser)\n\t}\n\n\t// Is it a directive?\n\tif parser.mark.column == 0 && parser.buffer[parser.buffer_pos] == '%' {\n\t\treturn yaml_parser_fetch_directive(parser)\n\t}\n\n\tbuf := parser.buffer\n\tpos := parser.buffer_pos\n\n\t// Is it the document start indicator?\n\tif parser.mark.column == 0 && buf[pos] == '-' && buf[pos+1] == '-' && buf[pos+2] == '-' && is_blankz(buf, pos+3) {\n\t\treturn yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_START_TOKEN)\n\t}\n\n\t// Is it the document end indicator?\n\tif parser.mark.column == 0 && buf[pos] == '.' && buf[pos+1] == '.' && buf[pos+2] == '.' && is_blankz(buf, pos+3) {\n\t\treturn yaml_parser_fetch_document_indicator(parser, yaml_DOCUMENT_END_TOKEN)\n\t}\n\n\tcomment_mark := parser.mark\n\tif len(parser.tokens) > 0 && (parser.flow_level == 0 && buf[pos] == ':' || parser.flow_level > 0 && buf[pos] == ',') {\n\t\t// Associate any following comments with the prior token.\n\t\tcomment_mark = parser.tokens[len(parser.tokens)-1].start_mark\n\t}\n\tdefer func() {\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\t\tif len(parser.tokens) > 0 && parser.tokens[len(parser.tokens)-1].typ == yaml_BLOCK_ENTRY_TOKEN {\n\t\t\t// Sequence indicators alone have no line comments. It becomes\n\t\t\t// a head comment for whatever follows.\n\t\t\treturn\n\t\t}\n\t\tif !yaml_parser_scan_line_comment(parser, comment_mark) {\n\t\t\tok = false\n\t\t\treturn\n\t\t}\n\t}()\n\n\t// Is it the flow sequence start indicator?\n\tif buf[pos] == '[' {\n\t\treturn yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_SEQUENCE_START_TOKEN)\n\t}\n\n\t// Is it the flow mapping start indicator?\n\tif parser.buffer[parser.buffer_pos] == '{' {\n\t\treturn yaml_parser_fetch_flow_collection_start(parser, yaml_FLOW_MAPPING_START_TOKEN)\n\t}\n\n\t// Is it the flow sequence end indicator?\n\tif parser.buffer[parser.buffer_pos] == ']' {\n\t\treturn yaml_parser_fetch_flow_collection_end(parser,\n\t\t\tyaml_FLOW_SEQUENCE_END_TOKEN)\n\t}\n\n\t// Is it the flow mapping end indicator?\n\tif parser.buffer[parser.buffer_pos] == '}' {\n\t\treturn yaml_parser_fetch_flow_collection_end(parser,\n\t\t\tyaml_FLOW_MAPPING_END_TOKEN)\n\t}\n\n\t// Is it the flow entry indicator?\n\tif parser.buffer[parser.buffer_pos] == ',' {\n\t\treturn yaml_parser_fetch_flow_entry(parser)\n\t}\n\n\t// Is it the block entry indicator?\n\tif parser.buffer[parser.buffer_pos] == '-' && is_blankz(parser.buffer, parser.buffer_pos+1) {\n\t\treturn yaml_parser_fetch_block_entry(parser)\n\t}\n\n\t// Is it the key indicator?\n\tif parser.buffer[parser.buffer_pos] == '?' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {\n\t\treturn yaml_parser_fetch_key(parser)\n\t}\n\n\t// Is it the value indicator?\n\tif parser.buffer[parser.buffer_pos] == ':' && (parser.flow_level > 0 || is_blankz(parser.buffer, parser.buffer_pos+1)) {\n\t\treturn yaml_parser_fetch_value(parser)\n\t}\n\n\t// Is it an alias?\n\tif parser.buffer[parser.buffer_pos] == '*' {\n\t\treturn yaml_parser_fetch_anchor(parser, yaml_ALIAS_TOKEN)\n\t}\n\n\t// Is it an anchor?\n\tif parser.buffer[parser.buffer_pos] == '&' {\n\t\treturn yaml_parser_fetch_anchor(parser, yaml_ANCHOR_TOKEN)\n\t}\n\n\t// Is it a tag?\n\tif parser.buffer[parser.buffer_pos] == '!' {\n\t\treturn yaml_parser_fetch_tag(parser)\n\t}\n\n\t// Is it a literal scalar?\n\tif parser.buffer[parser.buffer_pos] == '|' && parser.flow_level == 0 {\n\t\treturn yaml_parser_fetch_block_scalar(parser, true)\n\t}\n\n\t// Is it a folded scalar?\n\tif parser.buffer[parser.buffer_pos] == '>' && parser.flow_level == 0 {\n\t\treturn yaml_parser_fetch_block_scalar(parser, false)\n\t}\n\n\t// Is it a single-quoted scalar?\n\tif parser.buffer[parser.buffer_pos] == '\\'' {\n\t\treturn yaml_parser_fetch_flow_scalar(parser, true)\n\t}\n\n\t// Is it a double-quoted scalar?\n\tif parser.buffer[parser.buffer_pos] == '\"' {\n\t\treturn yaml_parser_fetch_flow_scalar(parser, false)\n\t}\n\n\t// Is it a plain scalar?\n\t//\n\t// A plain scalar may start with any non-blank characters except\n\t//\n\t//      '-', '?', ':', ',', '[', ']', '{', '}',\n\t//      '#', '&', '*', '!', '|', '>', '\\'', '\\\"',\n\t//      '%', '@', '`'.\n\t//\n\t// In the block context (and, for the '-' indicator, in the flow context\n\t// too), it may also start with the characters\n\t//\n\t//      '-', '?', ':'\n\t//\n\t// if it is followed by a non-space character.\n\t//\n\t// The last rule is more restrictive than the specification requires.\n\t// [Go] TODO Make this logic more reasonable.\n\t//switch parser.buffer[parser.buffer_pos] {\n\t//case '-', '?', ':', ',', '?', '-', ',', ':', ']', '[', '}', '{', '&', '#', '!', '*', '>', '|', '\"', '\\'', '@', '%', '-', '`':\n\t//}\n\tif !(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '-' ||\n\t\tparser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':' ||\n\t\tparser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '[' ||\n\t\tparser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||\n\t\tparser.buffer[parser.buffer_pos] == '}' || parser.buffer[parser.buffer_pos] == '#' ||\n\t\tparser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '*' ||\n\t\tparser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '|' ||\n\t\tparser.buffer[parser.buffer_pos] == '>' || parser.buffer[parser.buffer_pos] == '\\'' ||\n\t\tparser.buffer[parser.buffer_pos] == '\"' || parser.buffer[parser.buffer_pos] == '%' ||\n\t\tparser.buffer[parser.buffer_pos] == '@' || parser.buffer[parser.buffer_pos] == '`') ||\n\t\t(parser.buffer[parser.buffer_pos] == '-' && !is_blank(parser.buffer, parser.buffer_pos+1)) ||\n\t\t(parser.flow_level == 0 &&\n\t\t\t(parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == ':') &&\n\t\t\t!is_blankz(parser.buffer, parser.buffer_pos+1)) {\n\t\treturn yaml_parser_fetch_plain_scalar(parser)\n\t}\n\n\t// If we don't determine the token type so far, it is an error.\n\treturn yaml_parser_set_scanner_error(parser,\n\t\t\"while scanning for the next token\", parser.mark,\n\t\t\"found character that cannot start any token\")\n}\n\nfunc yaml_simple_key_is_valid(parser *yaml_parser_t, simple_key *yaml_simple_key_t) (valid, ok bool) {\n\tif !simple_key.possible {\n\t\treturn false, true\n\t}\n\n\t// The 1.2 specification says:\n\t//\n\t//     \"If the ? indicator is omitted, parsing needs to see past the\n\t//     implicit key to recognize it as such. To limit the amount of\n\t//     lookahead required, the “:” indicator must appear at most 1024\n\t//     Unicode characters beyond the start of the key. In addition, the key\n\t//     is restricted to a single line.\"\n\t//\n\tif simple_key.mark.line < parser.mark.line || simple_key.mark.index+1024 < parser.mark.index {\n\t\t// Check if the potential simple key to be removed is required.\n\t\tif simple_key.required {\n\t\t\treturn false, yaml_parser_set_scanner_error(parser,\n\t\t\t\t\"while scanning a simple key\", simple_key.mark,\n\t\t\t\t\"could not find expected ':'\")\n\t\t}\n\t\tsimple_key.possible = false\n\t\treturn false, true\n\t}\n\treturn true, true\n}\n\n// Check if a simple key may start at the current position and add it if\n// needed.\nfunc yaml_parser_save_simple_key(parser *yaml_parser_t) bool {\n\t// A simple key is required at the current position if the scanner is in\n\t// the block context and the current column coincides with the indentation\n\t// level.\n\n\trequired := parser.flow_level == 0 && parser.indent == parser.mark.column\n\n\t//\n\t// If the current position may start a simple key, save it.\n\t//\n\tif parser.simple_key_allowed {\n\t\tsimple_key := yaml_simple_key_t{\n\t\t\tpossible:     true,\n\t\t\trequired:     required,\n\t\t\ttoken_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),\n\t\t\tmark:         parser.mark,\n\t\t}\n\n\t\tif !yaml_parser_remove_simple_key(parser) {\n\t\t\treturn false\n\t\t}\n\t\tparser.simple_keys[len(parser.simple_keys)-1] = simple_key\n\t\tparser.simple_keys_by_tok[simple_key.token_number] = len(parser.simple_keys) - 1\n\t}\n\treturn true\n}\n\n// Remove a potential simple key at the current flow level.\nfunc yaml_parser_remove_simple_key(parser *yaml_parser_t) bool {\n\ti := len(parser.simple_keys) - 1\n\tif parser.simple_keys[i].possible {\n\t\t// If the key is required, it is an error.\n\t\tif parser.simple_keys[i].required {\n\t\t\treturn yaml_parser_set_scanner_error(parser,\n\t\t\t\t\"while scanning a simple key\", parser.simple_keys[i].mark,\n\t\t\t\t\"could not find expected ':'\")\n\t\t}\n\t\t// Remove the key from the stack.\n\t\tparser.simple_keys[i].possible = false\n\t\tdelete(parser.simple_keys_by_tok, parser.simple_keys[i].token_number)\n\t}\n\treturn true\n}\n\n// max_flow_level limits the flow_level\nconst max_flow_level = 10000\n\n// Increase the flow level and resize the simple key list if needed.\nfunc yaml_parser_increase_flow_level(parser *yaml_parser_t) bool {\n\t// Reset the simple key on the next level.\n\tparser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{\n\t\tpossible:     false,\n\t\trequired:     false,\n\t\ttoken_number: parser.tokens_parsed + (len(parser.tokens) - parser.tokens_head),\n\t\tmark:         parser.mark,\n\t})\n\n\t// Increase the flow level.\n\tparser.flow_level++\n\tif parser.flow_level > max_flow_level {\n\t\treturn yaml_parser_set_scanner_error(parser,\n\t\t\t\"while increasing flow level\", parser.simple_keys[len(parser.simple_keys)-1].mark,\n\t\t\tfmt.Sprintf(\"exceeded max depth of %d\", max_flow_level))\n\t}\n\treturn true\n}\n\n// Decrease the flow level.\nfunc yaml_parser_decrease_flow_level(parser *yaml_parser_t) bool {\n\tif parser.flow_level > 0 {\n\t\tparser.flow_level--\n\t\tlast := len(parser.simple_keys) - 1\n\t\tdelete(parser.simple_keys_by_tok, parser.simple_keys[last].token_number)\n\t\tparser.simple_keys = parser.simple_keys[:last]\n\t}\n\treturn true\n}\n\n// max_indents limits the indents stack size\nconst max_indents = 10000\n\n// Push the current indentation level to the stack and set the new level\n// the current column is greater than the indentation level.  In this case,\n// append or insert the specified token into the token queue.\nfunc yaml_parser_roll_indent(parser *yaml_parser_t, column, number int, typ yaml_token_type_t, mark yaml_mark_t) bool {\n\t// In the flow context, do nothing.\n\tif parser.flow_level > 0 {\n\t\treturn true\n\t}\n\n\tif parser.indent < column {\n\t\t// Push the current indentation level to the stack and set the new\n\t\t// indentation level.\n\t\tparser.indents = append(parser.indents, parser.indent)\n\t\tparser.indent = column\n\t\tif len(parser.indents) > max_indents {\n\t\t\treturn yaml_parser_set_scanner_error(parser,\n\t\t\t\t\"while increasing indent level\", parser.simple_keys[len(parser.simple_keys)-1].mark,\n\t\t\t\tfmt.Sprintf(\"exceeded max depth of %d\", max_indents))\n\t\t}\n\n\t\t// Create a token and insert it into the queue.\n\t\ttoken := yaml_token_t{\n\t\t\ttyp:        typ,\n\t\t\tstart_mark: mark,\n\t\t\tend_mark:   mark,\n\t\t}\n\t\tif number > -1 {\n\t\t\tnumber -= parser.tokens_parsed\n\t\t}\n\t\tyaml_insert_token(parser, number, &token)\n\t}\n\treturn true\n}\n\n// Pop indentation levels from the indents stack until the current level\n// becomes less or equal to the column.  For each indentation level, append\n// the BLOCK-END token.\nfunc yaml_parser_unroll_indent(parser *yaml_parser_t, column int, scan_mark yaml_mark_t) bool {\n\t// In the flow context, do nothing.\n\tif parser.flow_level > 0 {\n\t\treturn true\n\t}\n\n\tblock_mark := scan_mark\n\tblock_mark.index--\n\n\t// Loop through the indentation levels in the stack.\n\tfor parser.indent > column {\n\n\t\t// [Go] Reposition the end token before potential following\n\t\t//      foot comments of parent blocks. For that, search\n\t\t//      backwards for recent comments that were at the same\n\t\t//      indent as the block that is ending now.\n\t\tstop_index := block_mark.index\n\t\tfor i := len(parser.comments) - 1; i >= 0; i-- {\n\t\t\tcomment := &parser.comments[i]\n\n\t\t\tif comment.end_mark.index < stop_index {\n\t\t\t\t// Don't go back beyond the start of the comment/whitespace scan, unless column < 0.\n\t\t\t\t// If requested indent column is < 0, then the document is over and everything else\n\t\t\t\t// is a foot anyway.\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif comment.start_mark.column == parser.indent+1 {\n\t\t\t\t// This is a good match. But maybe there's a former comment\n\t\t\t\t// at that same indent level, so keep searching.\n\t\t\t\tblock_mark = comment.start_mark\n\t\t\t}\n\n\t\t\t// While the end of the former comment matches with\n\t\t\t// the start of the following one, we know there's\n\t\t\t// nothing in between and scanning is still safe.\n\t\t\tstop_index = comment.scan_mark.index\n\t\t}\n\n\t\t// Create a token and append it to the queue.\n\t\ttoken := yaml_token_t{\n\t\t\ttyp:        yaml_BLOCK_END_TOKEN,\n\t\t\tstart_mark: block_mark,\n\t\t\tend_mark:   block_mark,\n\t\t}\n\t\tyaml_insert_token(parser, -1, &token)\n\n\t\t// Pop the indentation level.\n\t\tparser.indent = parser.indents[len(parser.indents)-1]\n\t\tparser.indents = parser.indents[:len(parser.indents)-1]\n\t}\n\treturn true\n}\n\n// Initialize the scanner and produce the STREAM-START token.\nfunc yaml_parser_fetch_stream_start(parser *yaml_parser_t) bool {\n\n\t// Set the initial indentation.\n\tparser.indent = -1\n\n\t// Initialize the simple key stack.\n\tparser.simple_keys = append(parser.simple_keys, yaml_simple_key_t{})\n\n\tparser.simple_keys_by_tok = make(map[int]int)\n\n\t// A simple key is allowed at the beginning of the stream.\n\tparser.simple_key_allowed = true\n\n\t// We have started.\n\tparser.stream_start_produced = true\n\n\t// Create the STREAM-START token and append it to the queue.\n\ttoken := yaml_token_t{\n\t\ttyp:        yaml_STREAM_START_TOKEN,\n\t\tstart_mark: parser.mark,\n\t\tend_mark:   parser.mark,\n\t\tencoding:   parser.encoding,\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the STREAM-END token and shut down the scanner.\nfunc yaml_parser_fetch_stream_end(parser *yaml_parser_t) bool {\n\n\t// Force new line.\n\tif parser.mark.column != 0 {\n\t\tparser.mark.column = 0\n\t\tparser.mark.line++\n\t}\n\n\t// Reset the indentation level.\n\tif !yaml_parser_unroll_indent(parser, -1, parser.mark) {\n\t\treturn false\n\t}\n\n\t// Reset simple keys.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\tparser.simple_key_allowed = false\n\n\t// Create the STREAM-END token and append it to the queue.\n\ttoken := yaml_token_t{\n\t\ttyp:        yaml_STREAM_END_TOKEN,\n\t\tstart_mark: parser.mark,\n\t\tend_mark:   parser.mark,\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token.\nfunc yaml_parser_fetch_directive(parser *yaml_parser_t) bool {\n\t// Reset the indentation level.\n\tif !yaml_parser_unroll_indent(parser, -1, parser.mark) {\n\t\treturn false\n\t}\n\n\t// Reset simple keys.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\tparser.simple_key_allowed = false\n\n\t// Create the YAML-DIRECTIVE or TAG-DIRECTIVE token.\n\ttoken := yaml_token_t{}\n\tif !yaml_parser_scan_directive(parser, &token) {\n\t\treturn false\n\t}\n\t// Append the token to the queue.\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the DOCUMENT-START or DOCUMENT-END token.\nfunc yaml_parser_fetch_document_indicator(parser *yaml_parser_t, typ yaml_token_type_t) bool {\n\t// Reset the indentation level.\n\tif !yaml_parser_unroll_indent(parser, -1, parser.mark) {\n\t\treturn false\n\t}\n\n\t// Reset simple keys.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\tparser.simple_key_allowed = false\n\n\t// Consume the token.\n\tstart_mark := parser.mark\n\n\tskip(parser)\n\tskip(parser)\n\tskip(parser)\n\n\tend_mark := parser.mark\n\n\t// Create the DOCUMENT-START or DOCUMENT-END token.\n\ttoken := yaml_token_t{\n\t\ttyp:        typ,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t}\n\t// Append the token to the queue.\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token.\nfunc yaml_parser_fetch_flow_collection_start(parser *yaml_parser_t, typ yaml_token_type_t) bool {\n\n\t// The indicators '[' and '{' may start a simple key.\n\tif !yaml_parser_save_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// Increase the flow level.\n\tif !yaml_parser_increase_flow_level(parser) {\n\t\treturn false\n\t}\n\n\t// A simple key may follow the indicators '[' and '{'.\n\tparser.simple_key_allowed = true\n\n\t// Consume the token.\n\tstart_mark := parser.mark\n\tskip(parser)\n\tend_mark := parser.mark\n\n\t// Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token.\n\ttoken := yaml_token_t{\n\t\ttyp:        typ,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t}\n\t// Append the token to the queue.\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token.\nfunc yaml_parser_fetch_flow_collection_end(parser *yaml_parser_t, typ yaml_token_type_t) bool {\n\t// Reset any potential simple key on the current flow level.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// Decrease the flow level.\n\tif !yaml_parser_decrease_flow_level(parser) {\n\t\treturn false\n\t}\n\n\t// No simple keys after the indicators ']' and '}'.\n\tparser.simple_key_allowed = false\n\n\t// Consume the token.\n\n\tstart_mark := parser.mark\n\tskip(parser)\n\tend_mark := parser.mark\n\n\t// Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token.\n\ttoken := yaml_token_t{\n\t\ttyp:        typ,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t}\n\t// Append the token to the queue.\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the FLOW-ENTRY token.\nfunc yaml_parser_fetch_flow_entry(parser *yaml_parser_t) bool {\n\t// Reset any potential simple keys on the current flow level.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// Simple keys are allowed after ','.\n\tparser.simple_key_allowed = true\n\n\t// Consume the token.\n\tstart_mark := parser.mark\n\tskip(parser)\n\tend_mark := parser.mark\n\n\t// Create the FLOW-ENTRY token and append it to the queue.\n\ttoken := yaml_token_t{\n\t\ttyp:        yaml_FLOW_ENTRY_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the BLOCK-ENTRY token.\nfunc yaml_parser_fetch_block_entry(parser *yaml_parser_t) bool {\n\t// Check if the scanner is in the block context.\n\tif parser.flow_level == 0 {\n\t\t// Check if we are allowed to start a new entry.\n\t\tif !parser.simple_key_allowed {\n\t\t\treturn yaml_parser_set_scanner_error(parser, \"\", parser.mark,\n\t\t\t\t\"block sequence entries are not allowed in this context\")\n\t\t}\n\t\t// Add the BLOCK-SEQUENCE-START token if needed.\n\t\tif !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_SEQUENCE_START_TOKEN, parser.mark) {\n\t\t\treturn false\n\t\t}\n\t} else {\n\t\t// It is an error for the '-' indicator to occur in the flow context,\n\t\t// but we let the Parser detect and report about it because the Parser\n\t\t// is able to point to the context.\n\t}\n\n\t// Reset any potential simple keys on the current flow level.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// Simple keys are allowed after '-'.\n\tparser.simple_key_allowed = true\n\n\t// Consume the token.\n\tstart_mark := parser.mark\n\tskip(parser)\n\tend_mark := parser.mark\n\n\t// Create the BLOCK-ENTRY token and append it to the queue.\n\ttoken := yaml_token_t{\n\t\ttyp:        yaml_BLOCK_ENTRY_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the KEY token.\nfunc yaml_parser_fetch_key(parser *yaml_parser_t) bool {\n\n\t// In the block context, additional checks are required.\n\tif parser.flow_level == 0 {\n\t\t// Check if we are allowed to start a new key (not nessesary simple).\n\t\tif !parser.simple_key_allowed {\n\t\t\treturn yaml_parser_set_scanner_error(parser, \"\", parser.mark,\n\t\t\t\t\"mapping keys are not allowed in this context\")\n\t\t}\n\t\t// Add the BLOCK-MAPPING-START token if needed.\n\t\tif !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Reset any potential simple keys on the current flow level.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// Simple keys are allowed after '?' in the block context.\n\tparser.simple_key_allowed = parser.flow_level == 0\n\n\t// Consume the token.\n\tstart_mark := parser.mark\n\tskip(parser)\n\tend_mark := parser.mark\n\n\t// Create the KEY token and append it to the queue.\n\ttoken := yaml_token_t{\n\t\ttyp:        yaml_KEY_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the VALUE token.\nfunc yaml_parser_fetch_value(parser *yaml_parser_t) bool {\n\n\tsimple_key := &parser.simple_keys[len(parser.simple_keys)-1]\n\n\t// Have we found a simple key?\n\tif valid, ok := yaml_simple_key_is_valid(parser, simple_key); !ok {\n\t\treturn false\n\n\t} else if valid {\n\n\t\t// Create the KEY token and insert it into the queue.\n\t\ttoken := yaml_token_t{\n\t\t\ttyp:        yaml_KEY_TOKEN,\n\t\t\tstart_mark: simple_key.mark,\n\t\t\tend_mark:   simple_key.mark,\n\t\t}\n\t\tyaml_insert_token(parser, simple_key.token_number-parser.tokens_parsed, &token)\n\n\t\t// In the block context, we may need to add the BLOCK-MAPPING-START token.\n\t\tif !yaml_parser_roll_indent(parser, simple_key.mark.column,\n\t\t\tsimple_key.token_number,\n\t\t\tyaml_BLOCK_MAPPING_START_TOKEN, simple_key.mark) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Remove the simple key.\n\t\tsimple_key.possible = false\n\t\tdelete(parser.simple_keys_by_tok, simple_key.token_number)\n\n\t\t// A simple key cannot follow another simple key.\n\t\tparser.simple_key_allowed = false\n\n\t} else {\n\t\t// The ':' indicator follows a complex key.\n\n\t\t// In the block context, extra checks are required.\n\t\tif parser.flow_level == 0 {\n\n\t\t\t// Check if we are allowed to start a complex value.\n\t\t\tif !parser.simple_key_allowed {\n\t\t\t\treturn yaml_parser_set_scanner_error(parser, \"\", parser.mark,\n\t\t\t\t\t\"mapping values are not allowed in this context\")\n\t\t\t}\n\n\t\t\t// Add the BLOCK-MAPPING-START token if needed.\n\t\t\tif !yaml_parser_roll_indent(parser, parser.mark.column, -1, yaml_BLOCK_MAPPING_START_TOKEN, parser.mark) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// Simple keys after ':' are allowed in the block context.\n\t\tparser.simple_key_allowed = parser.flow_level == 0\n\t}\n\n\t// Consume the token.\n\tstart_mark := parser.mark\n\tskip(parser)\n\tend_mark := parser.mark\n\n\t// Create the VALUE token and append it to the queue.\n\ttoken := yaml_token_t{\n\t\ttyp:        yaml_VALUE_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the ALIAS or ANCHOR token.\nfunc yaml_parser_fetch_anchor(parser *yaml_parser_t, typ yaml_token_type_t) bool {\n\t// An anchor or an alias could be a simple key.\n\tif !yaml_parser_save_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// A simple key cannot follow an anchor or an alias.\n\tparser.simple_key_allowed = false\n\n\t// Create the ALIAS or ANCHOR token and append it to the queue.\n\tvar token yaml_token_t\n\tif !yaml_parser_scan_anchor(parser, &token, typ) {\n\t\treturn false\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the TAG token.\nfunc yaml_parser_fetch_tag(parser *yaml_parser_t) bool {\n\t// A tag could be a simple key.\n\tif !yaml_parser_save_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// A simple key cannot follow a tag.\n\tparser.simple_key_allowed = false\n\n\t// Create the TAG token and append it to the queue.\n\tvar token yaml_token_t\n\tif !yaml_parser_scan_tag(parser, &token) {\n\t\treturn false\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens.\nfunc yaml_parser_fetch_block_scalar(parser *yaml_parser_t, literal bool) bool {\n\t// Remove any potential simple keys.\n\tif !yaml_parser_remove_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// A simple key may follow a block scalar.\n\tparser.simple_key_allowed = true\n\n\t// Create the SCALAR token and append it to the queue.\n\tvar token yaml_token_t\n\tif !yaml_parser_scan_block_scalar(parser, &token, literal) {\n\t\treturn false\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens.\nfunc yaml_parser_fetch_flow_scalar(parser *yaml_parser_t, single bool) bool {\n\t// A plain scalar could be a simple key.\n\tif !yaml_parser_save_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// A simple key cannot follow a flow scalar.\n\tparser.simple_key_allowed = false\n\n\t// Create the SCALAR token and append it to the queue.\n\tvar token yaml_token_t\n\tif !yaml_parser_scan_flow_scalar(parser, &token, single) {\n\t\treturn false\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Produce the SCALAR(...,plain) token.\nfunc yaml_parser_fetch_plain_scalar(parser *yaml_parser_t) bool {\n\t// A plain scalar could be a simple key.\n\tif !yaml_parser_save_simple_key(parser) {\n\t\treturn false\n\t}\n\n\t// A simple key cannot follow a flow scalar.\n\tparser.simple_key_allowed = false\n\n\t// Create the SCALAR token and append it to the queue.\n\tvar token yaml_token_t\n\tif !yaml_parser_scan_plain_scalar(parser, &token) {\n\t\treturn false\n\t}\n\tyaml_insert_token(parser, -1, &token)\n\treturn true\n}\n\n// Eat whitespaces and comments until the next token is found.\nfunc yaml_parser_scan_to_next_token(parser *yaml_parser_t) bool {\n\n\tscan_mark := parser.mark\n\n\t// Until the next token is not found.\n\tfor {\n\t\t// Allow the BOM mark to start a line.\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t\tif parser.mark.column == 0 && is_bom(parser.buffer, parser.buffer_pos) {\n\t\t\tskip(parser)\n\t\t}\n\n\t\t// Eat whitespaces.\n\t\t// Tabs are allowed:\n\t\t//  - in the flow context\n\t\t//  - in the block context, but not at the beginning of the line or\n\t\t//  after '-', '?', or ':' (complex value).\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\n\t\tfor parser.buffer[parser.buffer_pos] == ' ' || ((parser.flow_level > 0 || !parser.simple_key_allowed) && parser.buffer[parser.buffer_pos] == '\\t') {\n\t\t\tskip(parser)\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// Check if we just had a line comment under a sequence entry that\n\t\t// looks more like a header to the following content. Similar to this:\n\t\t//\n\t\t// - # The comment\n\t\t//   - Some data\n\t\t//\n\t\t// If so, transform the line comment to a head comment and reposition.\n\t\tif len(parser.comments) > 0 && len(parser.tokens) > 1 {\n\t\t\ttokenA := parser.tokens[len(parser.tokens)-2]\n\t\t\ttokenB := parser.tokens[len(parser.tokens)-1]\n\t\t\tcomment := &parser.comments[len(parser.comments)-1]\n\t\t\tif tokenA.typ == yaml_BLOCK_SEQUENCE_START_TOKEN && tokenB.typ == yaml_BLOCK_ENTRY_TOKEN && len(comment.line) > 0 && !is_break(parser.buffer, parser.buffer_pos) {\n\t\t\t\t// If it was in the prior line, reposition so it becomes a\n\t\t\t\t// header of the follow up token. Otherwise, keep it in place\n\t\t\t\t// so it becomes a header of the former.\n\t\t\t\tcomment.head = comment.line\n\t\t\t\tcomment.line = nil\n\t\t\t\tif comment.start_mark.line == parser.mark.line-1 {\n\t\t\t\t\tcomment.token_mark = parser.mark\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Eat a comment until a line break.\n\t\tif parser.buffer[parser.buffer_pos] == '#' {\n\t\t\tif !yaml_parser_scan_comments(parser, scan_mark) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// If it is a line break, eat it.\n\t\tif is_break(parser.buffer, parser.buffer_pos) {\n\t\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tskip_line(parser)\n\n\t\t\t// In the block context, a new line may start a simple key.\n\t\t\tif parser.flow_level == 0 {\n\t\t\t\tparser.simple_key_allowed = true\n\t\t\t}\n\t\t} else {\n\t\t\tbreak // We have found a token.\n\t\t}\n\t}\n\n\treturn true\n}\n\n// Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token.\n//\n// Scope:\n//      %YAML    1.1    # a comment \\n\n//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n//      %TAG    !yaml!  tag:yaml.org,2002:  \\n\n//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n//\nfunc yaml_parser_scan_directive(parser *yaml_parser_t, token *yaml_token_t) bool {\n\t// Eat '%'.\n\tstart_mark := parser.mark\n\tskip(parser)\n\n\t// Scan the directive name.\n\tvar name []byte\n\tif !yaml_parser_scan_directive_name(parser, start_mark, &name) {\n\t\treturn false\n\t}\n\n\t// Is it a YAML directive?\n\tif bytes.Equal(name, []byte(\"YAML\")) {\n\t\t// Scan the VERSION directive value.\n\t\tvar major, minor int8\n\t\tif !yaml_parser_scan_version_directive_value(parser, start_mark, &major, &minor) {\n\t\t\treturn false\n\t\t}\n\t\tend_mark := parser.mark\n\n\t\t// Create a VERSION-DIRECTIVE token.\n\t\t*token = yaml_token_t{\n\t\t\ttyp:        yaml_VERSION_DIRECTIVE_TOKEN,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   end_mark,\n\t\t\tmajor:      major,\n\t\t\tminor:      minor,\n\t\t}\n\n\t\t// Is it a TAG directive?\n\t} else if bytes.Equal(name, []byte(\"TAG\")) {\n\t\t// Scan the TAG directive value.\n\t\tvar handle, prefix []byte\n\t\tif !yaml_parser_scan_tag_directive_value(parser, start_mark, &handle, &prefix) {\n\t\t\treturn false\n\t\t}\n\t\tend_mark := parser.mark\n\n\t\t// Create a TAG-DIRECTIVE token.\n\t\t*token = yaml_token_t{\n\t\t\ttyp:        yaml_TAG_DIRECTIVE_TOKEN,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   end_mark,\n\t\t\tvalue:      handle,\n\t\t\tprefix:     prefix,\n\t\t}\n\n\t\t// Unknown directive.\n\t} else {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a directive\",\n\t\t\tstart_mark, \"found unknown directive name\")\n\t\treturn false\n\t}\n\n\t// Eat the rest of the line including any comments.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\n\tfor is_blank(parser.buffer, parser.buffer_pos) {\n\t\tskip(parser)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tif parser.buffer[parser.buffer_pos] == '#' {\n\t\t// [Go] Discard this inline comment for the time being.\n\t\t//if !yaml_parser_scan_line_comment(parser, start_mark) {\n\t\t//\treturn false\n\t\t//}\n\t\tfor !is_breakz(parser.buffer, parser.buffer_pos) {\n\t\t\tskip(parser)\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check if we are at the end of the line.\n\tif !is_breakz(parser.buffer, parser.buffer_pos) {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a directive\",\n\t\t\tstart_mark, \"did not find expected comment or line break\")\n\t\treturn false\n\t}\n\n\t// Eat a line break.\n\tif is_break(parser.buffer, parser.buffer_pos) {\n\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\treturn false\n\t\t}\n\t\tskip_line(parser)\n\t}\n\n\treturn true\n}\n\n// Scan the directive name.\n//\n// Scope:\n//      %YAML   1.1     # a comment \\n\n//       ^^^^\n//      %TAG    !yaml!  tag:yaml.org,2002:  \\n\n//       ^^^\n//\nfunc yaml_parser_scan_directive_name(parser *yaml_parser_t, start_mark yaml_mark_t, name *[]byte) bool {\n\t// Consume the directive name.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\n\tvar s []byte\n\tfor is_alpha(parser.buffer, parser.buffer_pos) {\n\t\ts = read(parser, s)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Check if the name is empty.\n\tif len(s) == 0 {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a directive\",\n\t\t\tstart_mark, \"could not find expected directive name\")\n\t\treturn false\n\t}\n\n\t// Check for an blank character after the name.\n\tif !is_blankz(parser.buffer, parser.buffer_pos) {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a directive\",\n\t\t\tstart_mark, \"found unexpected non-alphabetical character\")\n\t\treturn false\n\t}\n\t*name = s\n\treturn true\n}\n\n// Scan the value of VERSION-DIRECTIVE.\n//\n// Scope:\n//      %YAML   1.1     # a comment \\n\n//           ^^^^^^\nfunc yaml_parser_scan_version_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, major, minor *int8) bool {\n\t// Eat whitespaces.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tfor is_blank(parser.buffer, parser.buffer_pos) {\n\t\tskip(parser)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Consume the major version number.\n\tif !yaml_parser_scan_version_directive_number(parser, start_mark, major) {\n\t\treturn false\n\t}\n\n\t// Eat '.'.\n\tif parser.buffer[parser.buffer_pos] != '.' {\n\t\treturn yaml_parser_set_scanner_error(parser, \"while scanning a %YAML directive\",\n\t\t\tstart_mark, \"did not find expected digit or '.' character\")\n\t}\n\n\tskip(parser)\n\n\t// Consume the minor version number.\n\tif !yaml_parser_scan_version_directive_number(parser, start_mark, minor) {\n\t\treturn false\n\t}\n\treturn true\n}\n\nconst max_number_length = 2\n\n// Scan the version number of VERSION-DIRECTIVE.\n//\n// Scope:\n//      %YAML   1.1     # a comment \\n\n//              ^\n//      %YAML   1.1     # a comment \\n\n//                ^\nfunc yaml_parser_scan_version_directive_number(parser *yaml_parser_t, start_mark yaml_mark_t, number *int8) bool {\n\n\t// Repeat while the next character is digit.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tvar value, length int8\n\tfor is_digit(parser.buffer, parser.buffer_pos) {\n\t\t// Check if the number is too long.\n\t\tlength++\n\t\tif length > max_number_length {\n\t\t\treturn yaml_parser_set_scanner_error(parser, \"while scanning a %YAML directive\",\n\t\t\t\tstart_mark, \"found extremely long version number\")\n\t\t}\n\t\tvalue = value*10 + int8(as_digit(parser.buffer, parser.buffer_pos))\n\t\tskip(parser)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Check if the number was present.\n\tif length == 0 {\n\t\treturn yaml_parser_set_scanner_error(parser, \"while scanning a %YAML directive\",\n\t\t\tstart_mark, \"did not find expected version number\")\n\t}\n\t*number = value\n\treturn true\n}\n\n// Scan the value of a TAG-DIRECTIVE token.\n//\n// Scope:\n//      %TAG    !yaml!  tag:yaml.org,2002:  \\n\n//          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n//\nfunc yaml_parser_scan_tag_directive_value(parser *yaml_parser_t, start_mark yaml_mark_t, handle, prefix *[]byte) bool {\n\tvar handle_value, prefix_value []byte\n\n\t// Eat whitespaces.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\n\tfor is_blank(parser.buffer, parser.buffer_pos) {\n\t\tskip(parser)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Scan a handle.\n\tif !yaml_parser_scan_tag_handle(parser, true, start_mark, &handle_value) {\n\t\treturn false\n\t}\n\n\t// Expect a whitespace.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tif !is_blank(parser.buffer, parser.buffer_pos) {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a %TAG directive\",\n\t\t\tstart_mark, \"did not find expected whitespace\")\n\t\treturn false\n\t}\n\n\t// Eat whitespaces.\n\tfor is_blank(parser.buffer, parser.buffer_pos) {\n\t\tskip(parser)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Scan a prefix.\n\tif !yaml_parser_scan_tag_uri(parser, true, nil, start_mark, &prefix_value) {\n\t\treturn false\n\t}\n\n\t// Expect a whitespace or line break.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tif !is_blankz(parser.buffer, parser.buffer_pos) {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a %TAG directive\",\n\t\t\tstart_mark, \"did not find expected whitespace or line break\")\n\t\treturn false\n\t}\n\n\t*handle = handle_value\n\t*prefix = prefix_value\n\treturn true\n}\n\nfunc yaml_parser_scan_anchor(parser *yaml_parser_t, token *yaml_token_t, typ yaml_token_type_t) bool {\n\tvar s []byte\n\n\t// Eat the indicator character.\n\tstart_mark := parser.mark\n\tskip(parser)\n\n\t// Consume the value.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\n\tfor is_alpha(parser.buffer, parser.buffer_pos) {\n\t\ts = read(parser, s)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\tend_mark := parser.mark\n\n\t/*\n\t * Check if length of the anchor is greater than 0 and it is followed by\n\t * a whitespace character or one of the indicators:\n\t *\n\t *      '?', ':', ',', ']', '}', '%', '@', '`'.\n\t */\n\n\tif len(s) == 0 ||\n\t\t!(is_blankz(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == '?' ||\n\t\t\tparser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == ',' ||\n\t\t\tparser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '}' ||\n\t\t\tparser.buffer[parser.buffer_pos] == '%' || parser.buffer[parser.buffer_pos] == '@' ||\n\t\t\tparser.buffer[parser.buffer_pos] == '`') {\n\t\tcontext := \"while scanning an alias\"\n\t\tif typ == yaml_ANCHOR_TOKEN {\n\t\t\tcontext = \"while scanning an anchor\"\n\t\t}\n\t\tyaml_parser_set_scanner_error(parser, context, start_mark,\n\t\t\t\"did not find expected alphabetic or numeric character\")\n\t\treturn false\n\t}\n\n\t// Create a token.\n\t*token = yaml_token_t{\n\t\ttyp:        typ,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t\tvalue:      s,\n\t}\n\n\treturn true\n}\n\n/*\n * Scan a TAG token.\n */\n\nfunc yaml_parser_scan_tag(parser *yaml_parser_t, token *yaml_token_t) bool {\n\tvar handle, suffix []byte\n\n\tstart_mark := parser.mark\n\n\t// Check if the tag is in the canonical form.\n\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\treturn false\n\t}\n\n\tif parser.buffer[parser.buffer_pos+1] == '<' {\n\t\t// Keep the handle as ''\n\n\t\t// Eat '!<'\n\t\tskip(parser)\n\t\tskip(parser)\n\n\t\t// Consume the tag value.\n\t\tif !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Check for '>' and eat it.\n\t\tif parser.buffer[parser.buffer_pos] != '>' {\n\t\t\tyaml_parser_set_scanner_error(parser, \"while scanning a tag\",\n\t\t\t\tstart_mark, \"did not find the expected '>'\")\n\t\t\treturn false\n\t\t}\n\n\t\tskip(parser)\n\t} else {\n\t\t// The tag has either the '!suffix' or the '!handle!suffix' form.\n\n\t\t// First, try to scan a handle.\n\t\tif !yaml_parser_scan_tag_handle(parser, false, start_mark, &handle) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Check if it is, indeed, handle.\n\t\tif handle[0] == '!' && len(handle) > 1 && handle[len(handle)-1] == '!' {\n\t\t\t// Scan the suffix now.\n\t\t\tif !yaml_parser_scan_tag_uri(parser, false, nil, start_mark, &suffix) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\t// It wasn't a handle after all.  Scan the rest of the tag.\n\t\t\tif !yaml_parser_scan_tag_uri(parser, false, handle, start_mark, &suffix) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// Set the handle to '!'.\n\t\t\thandle = []byte{'!'}\n\n\t\t\t// A special case: the '!' tag.  Set the handle to '' and the\n\t\t\t// suffix to '!'.\n\t\t\tif len(suffix) == 0 {\n\t\t\t\thandle, suffix = suffix, handle\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check the character which ends the tag.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tif !is_blankz(parser.buffer, parser.buffer_pos) {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a tag\",\n\t\t\tstart_mark, \"did not find expected whitespace or line break\")\n\t\treturn false\n\t}\n\n\tend_mark := parser.mark\n\n\t// Create a token.\n\t*token = yaml_token_t{\n\t\ttyp:        yaml_TAG_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t\tvalue:      handle,\n\t\tsuffix:     suffix,\n\t}\n\treturn true\n}\n\n// Scan a tag handle.\nfunc yaml_parser_scan_tag_handle(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, handle *[]byte) bool {\n\t// Check the initial '!' character.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tif parser.buffer[parser.buffer_pos] != '!' {\n\t\tyaml_parser_set_scanner_tag_error(parser, directive,\n\t\t\tstart_mark, \"did not find expected '!'\")\n\t\treturn false\n\t}\n\n\tvar s []byte\n\n\t// Copy the '!' character.\n\ts = read(parser, s)\n\n\t// Copy all subsequent alphabetical and numerical characters.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tfor is_alpha(parser.buffer, parser.buffer_pos) {\n\t\ts = read(parser, s)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Check if the trailing character is '!' and copy it.\n\tif parser.buffer[parser.buffer_pos] == '!' {\n\t\ts = read(parser, s)\n\t} else {\n\t\t// It's either the '!' tag or not really a tag handle.  If it's a %TAG\n\t\t// directive, it's an error.  If it's a tag token, it must be a part of URI.\n\t\tif directive && string(s) != \"!\" {\n\t\t\tyaml_parser_set_scanner_tag_error(parser, directive,\n\t\t\t\tstart_mark, \"did not find expected '!'\")\n\t\t\treturn false\n\t\t}\n\t}\n\n\t*handle = s\n\treturn true\n}\n\n// Scan a tag.\nfunc yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {\n\t//size_t length = head ? strlen((char *)head) : 0\n\tvar s []byte\n\thasTag := len(head) > 0\n\n\t// Copy the head if needed.\n\t//\n\t// Note that we don't copy the leading '!' character.\n\tif len(head) > 1 {\n\t\ts = append(s, head[1:]...)\n\t}\n\n\t// Scan the tag.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\n\t// The set of characters that may appear in URI is as follows:\n\t//\n\t//      '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&',\n\t//      '=', '+', '$', ',', '.', '!', '~', '*', '\\'', '(', ')', '[', ']',\n\t//      '%'.\n\t// [Go] TODO Convert this into more reasonable logic.\n\tfor is_alpha(parser.buffer, parser.buffer_pos) || parser.buffer[parser.buffer_pos] == ';' ||\n\t\tparser.buffer[parser.buffer_pos] == '/' || parser.buffer[parser.buffer_pos] == '?' ||\n\t\tparser.buffer[parser.buffer_pos] == ':' || parser.buffer[parser.buffer_pos] == '@' ||\n\t\tparser.buffer[parser.buffer_pos] == '&' || parser.buffer[parser.buffer_pos] == '=' ||\n\t\tparser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '$' ||\n\t\tparser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == '.' ||\n\t\tparser.buffer[parser.buffer_pos] == '!' || parser.buffer[parser.buffer_pos] == '~' ||\n\t\tparser.buffer[parser.buffer_pos] == '*' || parser.buffer[parser.buffer_pos] == '\\'' ||\n\t\tparser.buffer[parser.buffer_pos] == '(' || parser.buffer[parser.buffer_pos] == ')' ||\n\t\tparser.buffer[parser.buffer_pos] == '[' || parser.buffer[parser.buffer_pos] == ']' ||\n\t\tparser.buffer[parser.buffer_pos] == '%' {\n\t\t// Check if it is a URI-escape sequence.\n\t\tif parser.buffer[parser.buffer_pos] == '%' {\n\t\t\tif !yaml_parser_scan_uri_escapes(parser, directive, start_mark, &s) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\ts = read(parser, s)\n\t\t}\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t\thasTag = true\n\t}\n\n\tif !hasTag {\n\t\tyaml_parser_set_scanner_tag_error(parser, directive,\n\t\t\tstart_mark, \"did not find expected tag URI\")\n\t\treturn false\n\t}\n\t*uri = s\n\treturn true\n}\n\n// Decode an URI-escape sequence corresponding to a single UTF-8 character.\nfunc yaml_parser_scan_uri_escapes(parser *yaml_parser_t, directive bool, start_mark yaml_mark_t, s *[]byte) bool {\n\n\t// Decode the required number of characters.\n\tw := 1024\n\tfor w > 0 {\n\t\t// Check for a URI-escaped octet.\n\t\tif parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {\n\t\t\treturn false\n\t\t}\n\n\t\tif !(parser.buffer[parser.buffer_pos] == '%' &&\n\t\t\tis_hex(parser.buffer, parser.buffer_pos+1) &&\n\t\t\tis_hex(parser.buffer, parser.buffer_pos+2)) {\n\t\t\treturn yaml_parser_set_scanner_tag_error(parser, directive,\n\t\t\t\tstart_mark, \"did not find URI escaped octet\")\n\t\t}\n\n\t\t// Get the octet.\n\t\toctet := byte((as_hex(parser.buffer, parser.buffer_pos+1) << 4) + as_hex(parser.buffer, parser.buffer_pos+2))\n\n\t\t// If it is the leading octet, determine the length of the UTF-8 sequence.\n\t\tif w == 1024 {\n\t\t\tw = width(octet)\n\t\t\tif w == 0 {\n\t\t\t\treturn yaml_parser_set_scanner_tag_error(parser, directive,\n\t\t\t\t\tstart_mark, \"found an incorrect leading UTF-8 octet\")\n\t\t\t}\n\t\t} else {\n\t\t\t// Check if the trailing octet is correct.\n\t\t\tif octet&0xC0 != 0x80 {\n\t\t\t\treturn yaml_parser_set_scanner_tag_error(parser, directive,\n\t\t\t\t\tstart_mark, \"found an incorrect trailing UTF-8 octet\")\n\t\t\t}\n\t\t}\n\n\t\t// Copy the octet and move the pointers.\n\t\t*s = append(*s, octet)\n\t\tskip(parser)\n\t\tskip(parser)\n\t\tskip(parser)\n\t\tw--\n\t}\n\treturn true\n}\n\n// Scan a block scalar.\nfunc yaml_parser_scan_block_scalar(parser *yaml_parser_t, token *yaml_token_t, literal bool) bool {\n\t// Eat the indicator '|' or '>'.\n\tstart_mark := parser.mark\n\tskip(parser)\n\n\t// Scan the additional block scalar indicators.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\n\t// Check for a chomping indicator.\n\tvar chomping, increment int\n\tif parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {\n\t\t// Set the chomping method and eat the indicator.\n\t\tif parser.buffer[parser.buffer_pos] == '+' {\n\t\t\tchomping = +1\n\t\t} else {\n\t\t\tchomping = -1\n\t\t}\n\t\tskip(parser)\n\n\t\t// Check for an indentation indicator.\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t\tif is_digit(parser.buffer, parser.buffer_pos) {\n\t\t\t// Check that the indentation is greater than 0.\n\t\t\tif parser.buffer[parser.buffer_pos] == '0' {\n\t\t\t\tyaml_parser_set_scanner_error(parser, \"while scanning a block scalar\",\n\t\t\t\t\tstart_mark, \"found an indentation indicator equal to 0\")\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\t// Get the indentation level and eat the indicator.\n\t\t\tincrement = as_digit(parser.buffer, parser.buffer_pos)\n\t\t\tskip(parser)\n\t\t}\n\n\t} else if is_digit(parser.buffer, parser.buffer_pos) {\n\t\t// Do the same as above, but in the opposite order.\n\n\t\tif parser.buffer[parser.buffer_pos] == '0' {\n\t\t\tyaml_parser_set_scanner_error(parser, \"while scanning a block scalar\",\n\t\t\t\tstart_mark, \"found an indentation indicator equal to 0\")\n\t\t\treturn false\n\t\t}\n\t\tincrement = as_digit(parser.buffer, parser.buffer_pos)\n\t\tskip(parser)\n\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t\tif parser.buffer[parser.buffer_pos] == '+' || parser.buffer[parser.buffer_pos] == '-' {\n\t\t\tif parser.buffer[parser.buffer_pos] == '+' {\n\t\t\t\tchomping = +1\n\t\t\t} else {\n\t\t\t\tchomping = -1\n\t\t\t}\n\t\t\tskip(parser)\n\t\t}\n\t}\n\n\t// Eat whitespaces and comments to the end of the line.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tfor is_blank(parser.buffer, parser.buffer_pos) {\n\t\tskip(parser)\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t}\n\tif parser.buffer[parser.buffer_pos] == '#' {\n\t\tif !yaml_parser_scan_line_comment(parser, start_mark) {\n\t\t\treturn false\n\t\t}\n\t\tfor !is_breakz(parser.buffer, parser.buffer_pos) {\n\t\t\tskip(parser)\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check if we are at the end of the line.\n\tif !is_breakz(parser.buffer, parser.buffer_pos) {\n\t\tyaml_parser_set_scanner_error(parser, \"while scanning a block scalar\",\n\t\t\tstart_mark, \"did not find expected comment or line break\")\n\t\treturn false\n\t}\n\n\t// Eat a line break.\n\tif is_break(parser.buffer, parser.buffer_pos) {\n\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\treturn false\n\t\t}\n\t\tskip_line(parser)\n\t}\n\n\tend_mark := parser.mark\n\n\t// Set the indentation level if it was specified.\n\tvar indent int\n\tif increment > 0 {\n\t\tif parser.indent >= 0 {\n\t\t\tindent = parser.indent + increment\n\t\t} else {\n\t\t\tindent = increment\n\t\t}\n\t}\n\n\t// Scan the leading line breaks and determine the indentation level if needed.\n\tvar s, leading_break, trailing_breaks []byte\n\tif !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {\n\t\treturn false\n\t}\n\n\t// Scan the block scalar content.\n\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\treturn false\n\t}\n\tvar leading_blank, trailing_blank bool\n\tfor parser.mark.column == indent && !is_z(parser.buffer, parser.buffer_pos) {\n\t\t// We are at the beginning of a non-empty line.\n\n\t\t// Is it a trailing whitespace?\n\t\ttrailing_blank = is_blank(parser.buffer, parser.buffer_pos)\n\n\t\t// Check if we need to fold the leading line break.\n\t\tif !literal && !leading_blank && !trailing_blank && len(leading_break) > 0 && leading_break[0] == '\\n' {\n\t\t\t// Do we need to join the lines by space?\n\t\t\tif len(trailing_breaks) == 0 {\n\t\t\t\ts = append(s, ' ')\n\t\t\t}\n\t\t} else {\n\t\t\ts = append(s, leading_break...)\n\t\t}\n\t\tleading_break = leading_break[:0]\n\n\t\t// Append the remaining line breaks.\n\t\ts = append(s, trailing_breaks...)\n\t\ttrailing_breaks = trailing_breaks[:0]\n\n\t\t// Is it a leading whitespace?\n\t\tleading_blank = is_blank(parser.buffer, parser.buffer_pos)\n\n\t\t// Consume the current line.\n\t\tfor !is_breakz(parser.buffer, parser.buffer_pos) {\n\t\t\ts = read(parser, s)\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// Consume the line break.\n\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\treturn false\n\t\t}\n\n\t\tleading_break = read_line(parser, leading_break)\n\n\t\t// Eat the following indentation spaces and line breaks.\n\t\tif !yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, start_mark, &end_mark) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// Chomp the tail.\n\tif chomping != -1 {\n\t\ts = append(s, leading_break...)\n\t}\n\tif chomping == 1 {\n\t\ts = append(s, trailing_breaks...)\n\t}\n\n\t// Create a token.\n\t*token = yaml_token_t{\n\t\ttyp:        yaml_SCALAR_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t\tvalue:      s,\n\t\tstyle:      yaml_LITERAL_SCALAR_STYLE,\n\t}\n\tif !literal {\n\t\ttoken.style = yaml_FOLDED_SCALAR_STYLE\n\t}\n\treturn true\n}\n\n// Scan indentation spaces and line breaks for a block scalar.  Determine the\n// indentation level if needed.\nfunc yaml_parser_scan_block_scalar_breaks(parser *yaml_parser_t, indent *int, breaks *[]byte, start_mark yaml_mark_t, end_mark *yaml_mark_t) bool {\n\t*end_mark = parser.mark\n\n\t// Eat the indentation spaces and line breaks.\n\tmax_indent := 0\n\tfor {\n\t\t// Eat the indentation spaces.\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\t\tfor (*indent == 0 || parser.mark.column < *indent) && is_space(parser.buffer, parser.buffer_pos) {\n\t\t\tskip(parser)\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tif parser.mark.column > max_indent {\n\t\t\tmax_indent = parser.mark.column\n\t\t}\n\n\t\t// Check for a tab character messing the indentation.\n\t\tif (*indent == 0 || parser.mark.column < *indent) && is_tab(parser.buffer, parser.buffer_pos) {\n\t\t\treturn yaml_parser_set_scanner_error(parser, \"while scanning a block scalar\",\n\t\t\t\tstart_mark, \"found a tab character where an indentation space is expected\")\n\t\t}\n\n\t\t// Have we found a non-empty line?\n\t\tif !is_break(parser.buffer, parser.buffer_pos) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Consume the line break.\n\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\treturn false\n\t\t}\n\t\t// [Go] Should really be returning breaks instead.\n\t\t*breaks = read_line(parser, *breaks)\n\t\t*end_mark = parser.mark\n\t}\n\n\t// Determine the indentation level if needed.\n\tif *indent == 0 {\n\t\t*indent = max_indent\n\t\tif *indent < parser.indent+1 {\n\t\t\t*indent = parser.indent + 1\n\t\t}\n\t\tif *indent < 1 {\n\t\t\t*indent = 1\n\t\t}\n\t}\n\treturn true\n}\n\n// Scan a quoted scalar.\nfunc yaml_parser_scan_flow_scalar(parser *yaml_parser_t, token *yaml_token_t, single bool) bool {\n\t// Eat the left quote.\n\tstart_mark := parser.mark\n\tskip(parser)\n\n\t// Consume the content of the quoted scalar.\n\tvar s, leading_break, trailing_breaks, whitespaces []byte\n\tfor {\n\t\t// Check that there are no document indicators at the beginning of the line.\n\t\tif parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {\n\t\t\treturn false\n\t\t}\n\n\t\tif parser.mark.column == 0 &&\n\t\t\t((parser.buffer[parser.buffer_pos+0] == '-' &&\n\t\t\t\tparser.buffer[parser.buffer_pos+1] == '-' &&\n\t\t\t\tparser.buffer[parser.buffer_pos+2] == '-') ||\n\t\t\t\t(parser.buffer[parser.buffer_pos+0] == '.' &&\n\t\t\t\t\tparser.buffer[parser.buffer_pos+1] == '.' &&\n\t\t\t\t\tparser.buffer[parser.buffer_pos+2] == '.')) &&\n\t\t\tis_blankz(parser.buffer, parser.buffer_pos+3) {\n\t\t\tyaml_parser_set_scanner_error(parser, \"while scanning a quoted scalar\",\n\t\t\t\tstart_mark, \"found unexpected document indicator\")\n\t\t\treturn false\n\t\t}\n\n\t\t// Check for EOF.\n\t\tif is_z(parser.buffer, parser.buffer_pos) {\n\t\t\tyaml_parser_set_scanner_error(parser, \"while scanning a quoted scalar\",\n\t\t\t\tstart_mark, \"found unexpected end of stream\")\n\t\t\treturn false\n\t\t}\n\n\t\t// Consume non-blank characters.\n\t\tleading_blanks := false\n\t\tfor !is_blankz(parser.buffer, parser.buffer_pos) {\n\t\t\tif single && parser.buffer[parser.buffer_pos] == '\\'' && parser.buffer[parser.buffer_pos+1] == '\\'' {\n\t\t\t\t// Is is an escaped single quote.\n\t\t\t\ts = append(s, '\\'')\n\t\t\t\tskip(parser)\n\t\t\t\tskip(parser)\n\n\t\t\t} else if single && parser.buffer[parser.buffer_pos] == '\\'' {\n\t\t\t\t// It is a right single quote.\n\t\t\t\tbreak\n\t\t\t} else if !single && parser.buffer[parser.buffer_pos] == '\"' {\n\t\t\t\t// It is a right double quote.\n\t\t\t\tbreak\n\n\t\t\t} else if !single && parser.buffer[parser.buffer_pos] == '\\\\' && is_break(parser.buffer, parser.buffer_pos+1) {\n\t\t\t\t// It is an escaped line break.\n\t\t\t\tif parser.unread < 3 && !yaml_parser_update_buffer(parser, 3) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tskip(parser)\n\t\t\t\tskip_line(parser)\n\t\t\t\tleading_blanks = true\n\t\t\t\tbreak\n\n\t\t\t} else if !single && parser.buffer[parser.buffer_pos] == '\\\\' {\n\t\t\t\t// It is an escape sequence.\n\t\t\t\tcode_length := 0\n\n\t\t\t\t// Check the escape character.\n\t\t\t\tswitch parser.buffer[parser.buffer_pos+1] {\n\t\t\t\tcase '0':\n\t\t\t\t\ts = append(s, 0)\n\t\t\t\tcase 'a':\n\t\t\t\t\ts = append(s, '\\x07')\n\t\t\t\tcase 'b':\n\t\t\t\t\ts = append(s, '\\x08')\n\t\t\t\tcase 't', '\\t':\n\t\t\t\t\ts = append(s, '\\x09')\n\t\t\t\tcase 'n':\n\t\t\t\t\ts = append(s, '\\x0A')\n\t\t\t\tcase 'v':\n\t\t\t\t\ts = append(s, '\\x0B')\n\t\t\t\tcase 'f':\n\t\t\t\t\ts = append(s, '\\x0C')\n\t\t\t\tcase 'r':\n\t\t\t\t\ts = append(s, '\\x0D')\n\t\t\t\tcase 'e':\n\t\t\t\t\ts = append(s, '\\x1B')\n\t\t\t\tcase ' ':\n\t\t\t\t\ts = append(s, '\\x20')\n\t\t\t\tcase '\"':\n\t\t\t\t\ts = append(s, '\"')\n\t\t\t\tcase '\\'':\n\t\t\t\t\ts = append(s, '\\'')\n\t\t\t\tcase '\\\\':\n\t\t\t\t\ts = append(s, '\\\\')\n\t\t\t\tcase 'N': // NEL (#x85)\n\t\t\t\t\ts = append(s, '\\xC2')\n\t\t\t\t\ts = append(s, '\\x85')\n\t\t\t\tcase '_': // #xA0\n\t\t\t\t\ts = append(s, '\\xC2')\n\t\t\t\t\ts = append(s, '\\xA0')\n\t\t\t\tcase 'L': // LS (#x2028)\n\t\t\t\t\ts = append(s, '\\xE2')\n\t\t\t\t\ts = append(s, '\\x80')\n\t\t\t\t\ts = append(s, '\\xA8')\n\t\t\t\tcase 'P': // PS (#x2029)\n\t\t\t\t\ts = append(s, '\\xE2')\n\t\t\t\t\ts = append(s, '\\x80')\n\t\t\t\t\ts = append(s, '\\xA9')\n\t\t\t\tcase 'x':\n\t\t\t\t\tcode_length = 2\n\t\t\t\tcase 'u':\n\t\t\t\t\tcode_length = 4\n\t\t\t\tcase 'U':\n\t\t\t\t\tcode_length = 8\n\t\t\t\tdefault:\n\t\t\t\t\tyaml_parser_set_scanner_error(parser, \"while parsing a quoted scalar\",\n\t\t\t\t\t\tstart_mark, \"found unknown escape character\")\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\tskip(parser)\n\t\t\t\tskip(parser)\n\n\t\t\t\t// Consume an arbitrary escape code.\n\t\t\t\tif code_length > 0 {\n\t\t\t\t\tvar value int\n\n\t\t\t\t\t// Scan the character value.\n\t\t\t\t\tif parser.unread < code_length && !yaml_parser_update_buffer(parser, code_length) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t\tfor k := 0; k < code_length; k++ {\n\t\t\t\t\t\tif !is_hex(parser.buffer, parser.buffer_pos+k) {\n\t\t\t\t\t\t\tyaml_parser_set_scanner_error(parser, \"while parsing a quoted scalar\",\n\t\t\t\t\t\t\t\tstart_mark, \"did not find expected hexdecimal number\")\n\t\t\t\t\t\t\treturn false\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalue = (value << 4) + as_hex(parser.buffer, parser.buffer_pos+k)\n\t\t\t\t\t}\n\n\t\t\t\t\t// Check the value and write the character.\n\t\t\t\t\tif (value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF {\n\t\t\t\t\t\tyaml_parser_set_scanner_error(parser, \"while parsing a quoted scalar\",\n\t\t\t\t\t\t\tstart_mark, \"found invalid Unicode character escape code\")\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t\tif value <= 0x7F {\n\t\t\t\t\t\ts = append(s, byte(value))\n\t\t\t\t\t} else if value <= 0x7FF {\n\t\t\t\t\t\ts = append(s, byte(0xC0+(value>>6)))\n\t\t\t\t\t\ts = append(s, byte(0x80+(value&0x3F)))\n\t\t\t\t\t} else if value <= 0xFFFF {\n\t\t\t\t\t\ts = append(s, byte(0xE0+(value>>12)))\n\t\t\t\t\t\ts = append(s, byte(0x80+((value>>6)&0x3F)))\n\t\t\t\t\t\ts = append(s, byte(0x80+(value&0x3F)))\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts = append(s, byte(0xF0+(value>>18)))\n\t\t\t\t\t\ts = append(s, byte(0x80+((value>>12)&0x3F)))\n\t\t\t\t\t\ts = append(s, byte(0x80+((value>>6)&0x3F)))\n\t\t\t\t\t\ts = append(s, byte(0x80+(value&0x3F)))\n\t\t\t\t\t}\n\n\t\t\t\t\t// Advance the pointer.\n\t\t\t\t\tfor k := 0; k < code_length; k++ {\n\t\t\t\t\t\tskip(parser)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// It is a non-escaped non-blank character.\n\t\t\t\ts = read(parser, s)\n\t\t\t}\n\t\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Check if we are at the end of the scalar.\n\t\tif single {\n\t\t\tif parser.buffer[parser.buffer_pos] == '\\'' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t} else {\n\t\t\tif parser.buffer[parser.buffer_pos] == '\"' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Consume blank characters.\n\t\tfor is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {\n\t\t\tif is_blank(parser.buffer, parser.buffer_pos) {\n\t\t\t\t// Consume a space or a tab character.\n\t\t\t\tif !leading_blanks {\n\t\t\t\t\twhitespaces = read(parser, whitespaces)\n\t\t\t\t} else {\n\t\t\t\t\tskip(parser)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\t// Check if it is a first line break.\n\t\t\t\tif !leading_blanks {\n\t\t\t\t\twhitespaces = whitespaces[:0]\n\t\t\t\t\tleading_break = read_line(parser, leading_break)\n\t\t\t\t\tleading_blanks = true\n\t\t\t\t} else {\n\t\t\t\t\ttrailing_breaks = read_line(parser, trailing_breaks)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// Join the whitespaces or fold line breaks.\n\t\tif leading_blanks {\n\t\t\t// Do we need to fold line breaks?\n\t\t\tif len(leading_break) > 0 && leading_break[0] == '\\n' {\n\t\t\t\tif len(trailing_breaks) == 0 {\n\t\t\t\t\ts = append(s, ' ')\n\t\t\t\t} else {\n\t\t\t\t\ts = append(s, trailing_breaks...)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ts = append(s, leading_break...)\n\t\t\t\ts = append(s, trailing_breaks...)\n\t\t\t}\n\t\t\ttrailing_breaks = trailing_breaks[:0]\n\t\t\tleading_break = leading_break[:0]\n\t\t} else {\n\t\t\ts = append(s, whitespaces...)\n\t\t\twhitespaces = whitespaces[:0]\n\t\t}\n\t}\n\n\t// Eat the right quote.\n\tskip(parser)\n\tend_mark := parser.mark\n\n\t// Create a token.\n\t*token = yaml_token_t{\n\t\ttyp:        yaml_SCALAR_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t\tvalue:      s,\n\t\tstyle:      yaml_SINGLE_QUOTED_SCALAR_STYLE,\n\t}\n\tif !single {\n\t\ttoken.style = yaml_DOUBLE_QUOTED_SCALAR_STYLE\n\t}\n\treturn true\n}\n\n// Scan a plain scalar.\nfunc yaml_parser_scan_plain_scalar(parser *yaml_parser_t, token *yaml_token_t) bool {\n\n\tvar s, leading_break, trailing_breaks, whitespaces []byte\n\tvar leading_blanks bool\n\tvar indent = parser.indent + 1\n\n\tstart_mark := parser.mark\n\tend_mark := parser.mark\n\n\t// Consume the content of the plain scalar.\n\tfor {\n\t\t// Check for a document indicator.\n\t\tif parser.unread < 4 && !yaml_parser_update_buffer(parser, 4) {\n\t\t\treturn false\n\t\t}\n\t\tif parser.mark.column == 0 &&\n\t\t\t((parser.buffer[parser.buffer_pos+0] == '-' &&\n\t\t\t\tparser.buffer[parser.buffer_pos+1] == '-' &&\n\t\t\t\tparser.buffer[parser.buffer_pos+2] == '-') ||\n\t\t\t\t(parser.buffer[parser.buffer_pos+0] == '.' &&\n\t\t\t\t\tparser.buffer[parser.buffer_pos+1] == '.' &&\n\t\t\t\t\tparser.buffer[parser.buffer_pos+2] == '.')) &&\n\t\t\tis_blankz(parser.buffer, parser.buffer_pos+3) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Check for a comment.\n\t\tif parser.buffer[parser.buffer_pos] == '#' {\n\t\t\tbreak\n\t\t}\n\n\t\t// Consume non-blank characters.\n\t\tfor !is_blankz(parser.buffer, parser.buffer_pos) {\n\n\t\t\t// Check for indicators that may end a plain scalar.\n\t\t\tif (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||\n\t\t\t\t(parser.flow_level > 0 &&\n\t\t\t\t\t(parser.buffer[parser.buffer_pos] == ',' ||\n\t\t\t\t\t\tparser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||\n\t\t\t\t\t\tparser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||\n\t\t\t\t\t\tparser.buffer[parser.buffer_pos] == '}')) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// Check if we need to join whitespaces and breaks.\n\t\t\tif leading_blanks || len(whitespaces) > 0 {\n\t\t\t\tif leading_blanks {\n\t\t\t\t\t// Do we need to fold line breaks?\n\t\t\t\t\tif leading_break[0] == '\\n' {\n\t\t\t\t\t\tif len(trailing_breaks) == 0 {\n\t\t\t\t\t\t\ts = append(s, ' ')\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ts = append(s, trailing_breaks...)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\ts = append(s, leading_break...)\n\t\t\t\t\t\ts = append(s, trailing_breaks...)\n\t\t\t\t\t}\n\t\t\t\t\ttrailing_breaks = trailing_breaks[:0]\n\t\t\t\t\tleading_break = leading_break[:0]\n\t\t\t\t\tleading_blanks = false\n\t\t\t\t} else {\n\t\t\t\t\ts = append(s, whitespaces...)\n\t\t\t\t\twhitespaces = whitespaces[:0]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Copy the character.\n\t\t\ts = read(parser, s)\n\n\t\t\tend_mark = parser.mark\n\t\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// Is it the end?\n\t\tif !(is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos)) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Consume blank characters.\n\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\treturn false\n\t\t}\n\n\t\tfor is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {\n\t\t\tif is_blank(parser.buffer, parser.buffer_pos) {\n\n\t\t\t\t// Check for tab characters that abuse indentation.\n\t\t\t\tif leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {\n\t\t\t\t\tyaml_parser_set_scanner_error(parser, \"while scanning a plain scalar\",\n\t\t\t\t\t\tstart_mark, \"found a tab character that violates indentation\")\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\t// Consume a space or a tab character.\n\t\t\t\tif !leading_blanks {\n\t\t\t\t\twhitespaces = read(parser, whitespaces)\n\t\t\t\t} else {\n\t\t\t\t\tskip(parser)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\t// Check if it is a first line break.\n\t\t\t\tif !leading_blanks {\n\t\t\t\t\twhitespaces = whitespaces[:0]\n\t\t\t\t\tleading_break = read_line(parser, leading_break)\n\t\t\t\t\tleading_blanks = true\n\t\t\t\t} else {\n\t\t\t\t\ttrailing_breaks = read_line(parser, trailing_breaks)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\t// Check indentation level.\n\t\tif parser.flow_level == 0 && parser.mark.column < indent {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Create a token.\n\t*token = yaml_token_t{\n\t\ttyp:        yaml_SCALAR_TOKEN,\n\t\tstart_mark: start_mark,\n\t\tend_mark:   end_mark,\n\t\tvalue:      s,\n\t\tstyle:      yaml_PLAIN_SCALAR_STYLE,\n\t}\n\n\t// Note that we change the 'simple_key_allowed' flag.\n\tif leading_blanks {\n\t\tparser.simple_key_allowed = true\n\t}\n\treturn true\n}\n\nfunc yaml_parser_scan_line_comment(parser *yaml_parser_t, token_mark yaml_mark_t) bool {\n\tif parser.newlines > 0 {\n\t\treturn true\n\t}\n\n\tvar start_mark yaml_mark_t\n\tvar text []byte\n\n\tfor peek := 0; peek < 512; peek++ {\n\t\tif parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) {\n\t\t\tbreak\n\t\t}\n\t\tif is_blank(parser.buffer, parser.buffer_pos+peek) {\n\t\t\tcontinue\n\t\t}\n\t\tif parser.buffer[parser.buffer_pos+peek] == '#' {\n\t\t\tseen := parser.mark.index+peek\n\t\t\tfor {\n\t\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tif is_breakz(parser.buffer, parser.buffer_pos) {\n\t\t\t\t\tif parser.mark.index >= seen {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\t\t\t\t\tskip_line(parser)\n\t\t\t\t} else if parser.mark.index >= seen {\n\t\t\t\t\tif len(text) == 0 {\n\t\t\t\t\t\tstart_mark = parser.mark\n\t\t\t\t\t}\n\t\t\t\t\ttext = read(parser, text)\n\t\t\t\t} else {\n\t\t\t\t\tskip(parser)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tbreak\n\t}\n\tif len(text) > 0 {\n\t\tparser.comments = append(parser.comments, yaml_comment_t{\n\t\t\ttoken_mark: token_mark,\n\t\t\tstart_mark: start_mark,\n\t\t\tline: text,\n\t\t})\n\t}\n\treturn true\n}\n\nfunc yaml_parser_scan_comments(parser *yaml_parser_t, scan_mark yaml_mark_t) bool {\n\ttoken := parser.tokens[len(parser.tokens)-1]\n\n\tif token.typ == yaml_FLOW_ENTRY_TOKEN && len(parser.tokens) > 1 {\n\t\ttoken = parser.tokens[len(parser.tokens)-2]\n\t}\n\n\tvar token_mark = token.start_mark\n\tvar start_mark yaml_mark_t\n\tvar next_indent = parser.indent\n\tif next_indent < 0 {\n\t\tnext_indent = 0\n\t}\n\n\tvar recent_empty = false\n\tvar first_empty = parser.newlines <= 1\n\n\tvar line = parser.mark.line\n\tvar column = parser.mark.column\n\n\tvar text []byte\n\n\t// The foot line is the place where a comment must start to\n\t// still be considered as a foot of the prior content.\n\t// If there's some content in the currently parsed line, then\n\t// the foot is the line below it.\n\tvar foot_line = -1\n\tif scan_mark.line > 0 {\n\t\tfoot_line = parser.mark.line-parser.newlines+1\n\t\tif parser.newlines == 0 && parser.mark.column > 1 {\n\t\t\tfoot_line++\n\t\t}\n\t}\n\n\tvar peek = 0\n\tfor ; peek < 512; peek++ {\n\t\tif parser.unread < peek+1 && !yaml_parser_update_buffer(parser, peek+1) {\n\t\t\tbreak\n\t\t}\n\t\tcolumn++\n\t\tif is_blank(parser.buffer, parser.buffer_pos+peek) {\n\t\t\tcontinue\n\t\t}\n\t\tc := parser.buffer[parser.buffer_pos+peek]\n\t\tvar close_flow = parser.flow_level > 0 && (c == ']' || c == '}')\n\t\tif close_flow || is_breakz(parser.buffer, parser.buffer_pos+peek) {\n\t\t\t// Got line break or terminator.\n\t\t\tif close_flow || !recent_empty {\n\t\t\t\tif close_flow || first_empty && (start_mark.line == foot_line && token.typ != yaml_VALUE_TOKEN || start_mark.column-1 < next_indent) {\n\t\t\t\t\t// This is the first empty line and there were no empty lines before,\n\t\t\t\t\t// so this initial part of the comment is a foot of the prior token\n\t\t\t\t\t// instead of being a head for the following one. Split it up.\n\t\t\t\t\t// Alternatively, this might also be the last comment inside a flow\n\t\t\t\t\t// scope, so it must be a footer.\n\t\t\t\t\tif len(text) > 0 {\n\t\t\t\t\t\tif start_mark.column-1 < next_indent {\n\t\t\t\t\t\t\t// If dedented it's unrelated to the prior token.\n\t\t\t\t\t\t\ttoken_mark = start_mark\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparser.comments = append(parser.comments, yaml_comment_t{\n\t\t\t\t\t\t\tscan_mark:  scan_mark,\n\t\t\t\t\t\t\ttoken_mark: token_mark,\n\t\t\t\t\t\t\tstart_mark: start_mark,\n\t\t\t\t\t\t\tend_mark:   yaml_mark_t{parser.mark.index + peek, line, column},\n\t\t\t\t\t\t\tfoot:       text,\n\t\t\t\t\t\t})\n\t\t\t\t\t\tscan_mark = yaml_mark_t{parser.mark.index + peek, line, column}\n\t\t\t\t\t\ttoken_mark = scan_mark\n\t\t\t\t\t\ttext = nil\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif len(text) > 0 && parser.buffer[parser.buffer_pos+peek] != 0 {\n\t\t\t\t\t\ttext = append(text, '\\n')\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !is_break(parser.buffer, parser.buffer_pos+peek) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tfirst_empty = false\n\t\t\trecent_empty = true\n\t\t\tcolumn = 0\n\t\t\tline++\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(text) > 0 && (close_flow || column-1 < next_indent && column != start_mark.column) {\n\t\t\t// The comment at the different indentation is a foot of the\n\t\t\t// preceding data rather than a head of the upcoming one.\n\t\t\tparser.comments = append(parser.comments, yaml_comment_t{\n\t\t\t\tscan_mark:  scan_mark,\n\t\t\t\ttoken_mark: token_mark,\n\t\t\t\tstart_mark: start_mark,\n\t\t\t\tend_mark:   yaml_mark_t{parser.mark.index + peek, line, column},\n\t\t\t\tfoot:       text,\n\t\t\t})\n\t\t\tscan_mark = yaml_mark_t{parser.mark.index + peek, line, column}\n\t\t\ttoken_mark = scan_mark\n\t\t\ttext = nil\n\t\t}\n\n\t\tif parser.buffer[parser.buffer_pos+peek] != '#' {\n\t\t\tbreak\n\t\t}\n\n\t\tif len(text) == 0 {\n\t\t\tstart_mark = yaml_mark_t{parser.mark.index + peek, line, column}\n\t\t} else {\n\t\t\ttext = append(text, '\\n')\n\t\t}\n\n\t\trecent_empty = false\n\n\t\t// Consume until after the consumed comment line.\n\t\tseen := parser.mark.index+peek\n\t\tfor {\n\t\t\tif parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif is_breakz(parser.buffer, parser.buffer_pos) {\n\t\t\t\tif parser.mark.index >= seen {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tif parser.unread < 2 && !yaml_parser_update_buffer(parser, 2) {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t\tskip_line(parser)\n\t\t\t} else if parser.mark.index >= seen {\n\t\t\t\ttext = read(parser, text)\n\t\t\t} else {\n\t\t\t\tskip(parser)\n\t\t\t}\n\t\t}\n\n\t\tpeek = 0\n\t\tcolumn = 0\n\t\tline = parser.mark.line\n\t\tnext_indent = parser.indent\n\t\tif next_indent < 0 {\n\t\t\tnext_indent = 0\n\t\t}\n\t}\n\n\tif len(text) > 0 {\n\t\tparser.comments = append(parser.comments, yaml_comment_t{\n\t\t\tscan_mark:  scan_mark,\n\t\t\ttoken_mark: start_mark,\n\t\t\tstart_mark: start_mark,\n\t\t\tend_mark:   yaml_mark_t{parser.mark.index + peek - 1, line, column},\n\t\t\thead:       text,\n\t\t})\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/sorter.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\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//     http://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\npackage yaml\n\nimport (\n\t\"reflect\"\n\t\"unicode\"\n)\n\ntype keyList []reflect.Value\n\nfunc (l keyList) Len() int      { return len(l) }\nfunc (l keyList) Swap(i, j int) { l[i], l[j] = l[j], l[i] }\nfunc (l keyList) Less(i, j int) bool {\n\ta := l[i]\n\tb := l[j]\n\tak := a.Kind()\n\tbk := b.Kind()\n\tfor (ak == reflect.Interface || ak == reflect.Ptr) && !a.IsNil() {\n\t\ta = a.Elem()\n\t\tak = a.Kind()\n\t}\n\tfor (bk == reflect.Interface || bk == reflect.Ptr) && !b.IsNil() {\n\t\tb = b.Elem()\n\t\tbk = b.Kind()\n\t}\n\taf, aok := keyFloat(a)\n\tbf, bok := keyFloat(b)\n\tif aok && bok {\n\t\tif af != bf {\n\t\t\treturn af < bf\n\t\t}\n\t\tif ak != bk {\n\t\t\treturn ak < bk\n\t\t}\n\t\treturn numLess(a, b)\n\t}\n\tif ak != reflect.String || bk != reflect.String {\n\t\treturn ak < bk\n\t}\n\tar, br := []rune(a.String()), []rune(b.String())\n\tdigits := false\n\tfor i := 0; i < len(ar) && i < len(br); i++ {\n\t\tif ar[i] == br[i] {\n\t\t\tdigits = unicode.IsDigit(ar[i])\n\t\t\tcontinue\n\t\t}\n\t\tal := unicode.IsLetter(ar[i])\n\t\tbl := unicode.IsLetter(br[i])\n\t\tif al && bl {\n\t\t\treturn ar[i] < br[i]\n\t\t}\n\t\tif al || bl {\n\t\t\tif digits {\n\t\t\t\treturn al\n\t\t\t} else {\n\t\t\t\treturn bl\n\t\t\t}\n\t\t}\n\t\tvar ai, bi int\n\t\tvar an, bn int64\n\t\tif ar[i] == '0' || br[i] == '0' {\n\t\t\tfor j := i - 1; j >= 0 && unicode.IsDigit(ar[j]); j-- {\n\t\t\t\tif ar[j] != '0' {\n\t\t\t\t\tan = 1\n\t\t\t\t\tbn = 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {\n\t\t\tan = an*10 + int64(ar[ai]-'0')\n\t\t}\n\t\tfor bi = i; bi < len(br) && unicode.IsDigit(br[bi]); bi++ {\n\t\t\tbn = bn*10 + int64(br[bi]-'0')\n\t\t}\n\t\tif an != bn {\n\t\t\treturn an < bn\n\t\t}\n\t\tif ai != bi {\n\t\t\treturn ai < bi\n\t\t}\n\t\treturn ar[i] < br[i]\n\t}\n\treturn len(ar) < len(br)\n}\n\n// keyFloat returns a float value for v if it is a number/bool\n// and whether it is a number/bool or not.\nfunc keyFloat(v reflect.Value) (f float64, ok bool) {\n\tswitch v.Kind() {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn float64(v.Int()), true\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float(), true\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn float64(v.Uint()), true\n\tcase reflect.Bool:\n\t\tif v.Bool() {\n\t\t\treturn 1, true\n\t\t}\n\t\treturn 0, true\n\t}\n\treturn 0, false\n}\n\n// numLess returns whether a < b.\n// a and b must necessarily have the same kind.\nfunc numLess(a, b reflect.Value) bool {\n\tswitch a.Kind() {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn a.Int() < b.Int()\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn a.Float() < b.Float()\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn a.Uint() < b.Uint()\n\tcase reflect.Bool:\n\t\treturn !a.Bool() && b.Bool()\n\t}\n\tpanic(\"not a number\")\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/writerc.go",
    "content": "// \n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\n// Set the writer error and return false.\nfunc yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool {\n\temitter.error = yaml_WRITER_ERROR\n\temitter.problem = problem\n\treturn false\n}\n\n// Flush the output buffer.\nfunc yaml_emitter_flush(emitter *yaml_emitter_t) bool {\n\tif emitter.write_handler == nil {\n\t\tpanic(\"write handler not set\")\n\t}\n\n\t// Check if the buffer is empty.\n\tif emitter.buffer_pos == 0 {\n\t\treturn true\n\t}\n\n\tif err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {\n\t\treturn yaml_emitter_set_writer_error(emitter, \"write error: \"+err.Error())\n\t}\n\temitter.buffer_pos = 0\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/yaml.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\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//     http://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\n// Package yaml implements YAML support for the Go language.\n//\n// Source code and other details for the project are available at GitHub:\n//\n//\thttps://github.com/go-yaml/yaml\npackage yaml\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\t\"unicode/utf8\"\n)\n\n// The Unmarshaler interface may be implemented by types to customize their\n// behavior when being unmarshaled from a YAML document.\ntype Unmarshaler interface {\n\tUnmarshalYAML(value *Node) error\n}\n\ntype obsoleteUnmarshaler interface {\n\tUnmarshalYAML(unmarshal func(interface{}) error) error\n}\n\n// The Marshaler interface may be implemented by types to customize their\n// behavior when being marshaled into a YAML document. The returned value\n// is marshaled in place of the original value implementing Marshaler.\n//\n// If an error is returned by MarshalYAML, the marshaling procedure stops\n// and returns with the provided error.\ntype Marshaler interface {\n\tMarshalYAML() (interface{}, error)\n}\n\n// Unmarshal decodes the first document found within the in byte slice\n// and assigns decoded values into the out value.\n//\n// Maps and pointers (to a struct, string, int, etc) are accepted as out\n// values. If an internal pointer within a struct is not initialized,\n// the yaml package will initialize it if necessary for unmarshalling\n// the provided data. The out parameter must not be nil.\n//\n// The type of the decoded values should be compatible with the respective\n// values in out. If one or more values cannot be decoded due to a type\n// mismatches, decoding continues partially until the end of the YAML\n// content, and a *yaml.TypeError is returned with details for all\n// missed values.\n//\n// Struct fields are only unmarshalled if they are exported (have an\n// upper case first letter), and are unmarshalled using the field name\n// lowercased as the default key. Custom keys may be defined via the\n// \"yaml\" name in the field tag: the content preceding the first comma\n// is used as the key, and the following comma-separated options are\n// used to tweak the marshalling process (see Marshal).\n// Conflicting names result in a runtime error.\n//\n// For example:\n//\n//\ttype T struct {\n//\t    F int `yaml:\"a,omitempty\"`\n//\t    B int\n//\t}\n//\tvar t T\n//\tyaml.Unmarshal([]byte(\"a: 1\\nb: 2\"), &t)\n//\n// See the documentation of Marshal for the format of tags and a list of\n// supported tag options.\nfunc Unmarshal(in []byte, out interface{}) (err error) {\n\treturn unmarshal(in, out, false)\n}\n\n// A Decoder reads and decodes YAML values from an input stream.\ntype Decoder struct {\n\tparser      *parser\n\tknownFields bool\n\torigin      bool\n}\n\n// NewDecoder returns a new decoder that reads from r.\n//\n// The decoder introduces its own buffering and may read\n// data from r beyond the YAML values requested.\nfunc NewDecoder(r io.Reader) *Decoder {\n\treturn &Decoder{\n\t\tparser: newParserFromReader(r),\n\t}\n}\n\n// KnownFields ensures that the keys in decoded mappings to\n// exist as fields in the struct being decoded into.\nfunc (dec *Decoder) KnownFields(enable bool) {\n\tdec.knownFields = enable\n}\n\n// Origin enables the recording of the line and column of the\n// decoded values in the YAML content.\nfunc (dec *Decoder) Origin(enable bool) {\n\tdec.origin = enable\n}\n\n// Decode reads the next YAML-encoded value from its input\n// and stores it in the value pointed to by v.\n//\n// See the documentation for Unmarshal for details about the\n// conversion of YAML into a Go value.\nfunc (dec *Decoder) Decode(v interface{}) (err error) {\n\td := newDecoder()\n\td.knownFields = dec.knownFields\n\td.origin = dec.origin\n\tdefer handleErr(&err)\n\tnode := dec.parser.parse()\n\tif node == nil {\n\t\treturn io.EOF\n\t}\n\tout := reflect.ValueOf(v)\n\tif out.Kind() == reflect.Ptr && !out.IsNil() {\n\t\tout = out.Elem()\n\t}\n\td.unmarshal(node, out)\n\tif len(d.terrors) > 0 {\n\t\treturn &TypeError{d.terrors}\n\t}\n\treturn nil\n}\n\n// Decode decodes the node and stores its data into the value pointed to by v.\n//\n// See the documentation for Unmarshal for details about the\n// conversion of YAML into a Go value.\nfunc (n *Node) Decode(v interface{}) (err error) {\n\td := newDecoder()\n\tdefer handleErr(&err)\n\tout := reflect.ValueOf(v)\n\tif out.Kind() == reflect.Ptr && !out.IsNil() {\n\t\tout = out.Elem()\n\t}\n\td.unmarshal(n, out)\n\tif len(d.terrors) > 0 {\n\t\treturn &TypeError{d.terrors}\n\t}\n\treturn nil\n}\n\nfunc unmarshal(in []byte, out interface{}, strict bool) (err error) {\n\tdefer handleErr(&err)\n\td := newDecoder()\n\tp := newParser(in)\n\tdefer p.destroy()\n\tnode := p.parse()\n\tif node != nil {\n\t\tv := reflect.ValueOf(out)\n\t\tif v.Kind() == reflect.Ptr && !v.IsNil() {\n\t\t\tv = v.Elem()\n\t\t}\n\t\td.unmarshal(node, v)\n\t}\n\tif len(d.terrors) > 0 {\n\t\treturn &TypeError{d.terrors}\n\t}\n\treturn nil\n}\n\n// Marshal serializes the value provided into a YAML document. The structure\n// of the generated document will reflect the structure of the value itself.\n// Maps and pointers (to struct, string, int, etc) are accepted as the in value.\n//\n// Struct fields are only marshalled if they are exported (have an upper case\n// first letter), and are marshalled using the field name lowercased as the\n// default key. Custom keys may be defined via the \"yaml\" name in the field\n// tag: the content preceding the first comma is used as the key, and the\n// following comma-separated options are used to tweak the marshalling process.\n// Conflicting names result in a runtime error.\n//\n// The field tag format accepted is:\n//\n//\t`(...) yaml:\"[<key>][,<flag1>[,<flag2>]]\" (...)`\n//\n// The following flags are currently supported:\n//\n//\tomitempty    Only include the field if it's not set to the zero\n//\t             value for the type or to empty slices or maps.\n//\t             Zero valued structs will be omitted if all their public\n//\t             fields are zero, unless they implement an IsZero\n//\t             method (see the IsZeroer interface type), in which\n//\t             case the field will be excluded if IsZero returns true.\n//\n//\tflow         Marshal using a flow style (useful for structs,\n//\t             sequences and maps).\n//\n//\tinline       Inline the field, which must be a struct or a map,\n//\t             causing all of its fields or keys to be processed as if\n//\t             they were part of the outer struct. For maps, keys must\n//\t             not conflict with the yaml keys of other struct fields.\n//\n// In addition, if the key is \"-\", the field is ignored.\n//\n// For example:\n//\n//\ttype T struct {\n//\t    F int `yaml:\"a,omitempty\"`\n//\t    B int\n//\t}\n//\tyaml.Marshal(&T{B: 2}) // Returns \"b: 2\\n\"\n//\tyaml.Marshal(&T{F: 1}} // Returns \"a: 1\\nb: 0\\n\"\nfunc Marshal(in interface{}) (out []byte, err error) {\n\tdefer handleErr(&err)\n\te := newEncoder()\n\tdefer e.destroy()\n\te.marshalDoc(\"\", reflect.ValueOf(in))\n\te.finish()\n\tout = e.out\n\treturn\n}\n\n// An Encoder writes YAML values to an output stream.\ntype Encoder struct {\n\tencoder *encoder\n}\n\n// NewEncoder returns a new encoder that writes to w.\n// The Encoder should be closed after use to flush all data\n// to w.\nfunc NewEncoder(w io.Writer) *Encoder {\n\treturn &Encoder{\n\t\tencoder: newEncoderWithWriter(w),\n\t}\n}\n\n// Encode writes the YAML encoding of v to the stream.\n// If multiple items are encoded to the stream, the\n// second and subsequent document will be preceded\n// with a \"---\" document separator, but the first will not.\n//\n// See the documentation for Marshal for details about the conversion of Go\n// values to YAML.\nfunc (e *Encoder) Encode(v interface{}) (err error) {\n\tdefer handleErr(&err)\n\te.encoder.marshalDoc(\"\", reflect.ValueOf(v))\n\treturn nil\n}\n\n// Encode encodes value v and stores its representation in n.\n//\n// See the documentation for Marshal for details about the\n// conversion of Go values into YAML.\nfunc (n *Node) Encode(v interface{}) (err error) {\n\tdefer handleErr(&err)\n\te := newEncoder()\n\tdefer e.destroy()\n\te.marshalDoc(\"\", reflect.ValueOf(v))\n\te.finish()\n\tp := newParser(e.out)\n\tp.textless = true\n\tdefer p.destroy()\n\tdoc := p.parse()\n\t*n = *doc.Content[0]\n\treturn nil\n}\n\n// SetIndent changes the used indentation used when encoding.\nfunc (e *Encoder) SetIndent(spaces int) {\n\tif spaces < 0 {\n\t\tpanic(\"yaml: cannot indent to a negative number of spaces\")\n\t}\n\te.encoder.indent = spaces\n}\n\n// Close closes the encoder by writing any remaining data.\n// It does not write a stream terminating string \"...\".\nfunc (e *Encoder) Close() (err error) {\n\tdefer handleErr(&err)\n\te.encoder.finish()\n\treturn nil\n}\n\nfunc handleErr(err *error) {\n\tif v := recover(); v != nil {\n\t\tif e, ok := v.(yamlError); ok {\n\t\t\t*err = e.err\n\t\t} else {\n\t\t\tpanic(v)\n\t\t}\n\t}\n}\n\ntype yamlError struct {\n\terr error\n}\n\nfunc fail(err error) {\n\tpanic(yamlError{err})\n}\n\nfunc failf(format string, args ...interface{}) {\n\tpanic(yamlError{fmt.Errorf(\"yaml: \"+format, args...)})\n}\n\n// A TypeError is returned by Unmarshal when one or more fields in\n// the YAML document cannot be properly decoded into the requested\n// types. When this error is returned, the value is still\n// unmarshaled partially.\ntype TypeError struct {\n\tErrors []string\n}\n\nfunc (e *TypeError) Error() string {\n\treturn fmt.Sprintf(\"yaml: unmarshal errors:\\n  %s\", strings.Join(e.Errors, \"\\n  \"))\n}\n\ntype Kind uint32\n\nconst (\n\tDocumentNode Kind = 1 << iota\n\tSequenceNode\n\tMappingNode\n\tScalarNode\n\tAliasNode\n)\n\ntype Style uint32\n\nconst (\n\tTaggedStyle Style = 1 << iota\n\tDoubleQuotedStyle\n\tSingleQuotedStyle\n\tLiteralStyle\n\tFoldedStyle\n\tFlowStyle\n)\n\n// Node represents an element in the YAML document hierarchy. While documents\n// are typically encoded and decoded into higher level types, such as structs\n// and maps, Node is an intermediate representation that allows detailed\n// control over the content being decoded or encoded.\n//\n// It's worth noting that although Node offers access into details such as\n// line numbers, colums, and comments, the content when re-encoded will not\n// have its original textual representation preserved. An effort is made to\n// render the data plesantly, and to preserve comments near the data they\n// describe, though.\n//\n// Values that make use of the Node type interact with the yaml package in the\n// same way any other type would do, by encoding and decoding yaml data\n// directly or indirectly into them.\n//\n// For example:\n//\n//\tvar person struct {\n//\t        Name    string\n//\t        Address yaml.Node\n//\t}\n//\terr := yaml.Unmarshal(data, &person)\n//\n// Or by itself:\n//\n//\tvar person Node\n//\terr := yaml.Unmarshal(data, &person)\ntype Node struct {\n\t// Kind defines whether the node is a document, a mapping, a sequence,\n\t// a scalar value, or an alias to another node. The specific data type of\n\t// scalar nodes may be obtained via the ShortTag and LongTag methods.\n\tKind Kind\n\n\t// Style allows customizing the apperance of the node in the tree.\n\tStyle Style\n\n\t// Tag holds the YAML tag defining the data type for the value.\n\t// When decoding, this field will always be set to the resolved tag,\n\t// even when it wasn't explicitly provided in the YAML content.\n\t// When encoding, if this field is unset the value type will be\n\t// implied from the node properties, and if it is set, it will only\n\t// be serialized into the representation if TaggedStyle is used or\n\t// the implicit tag diverges from the provided one.\n\tTag string\n\n\t// Value holds the unescaped and unquoted represenation of the value.\n\tValue string\n\n\t// Anchor holds the anchor name for this node, which allows aliases to point to it.\n\tAnchor string\n\n\t// Alias holds the node that this alias points to. Only valid when Kind is AliasNode.\n\tAlias *Node\n\n\t// Content holds contained nodes for documents, mappings, and sequences.\n\tContent []*Node\n\n\t// HeadComment holds any comments in the lines preceding the node and\n\t// not separated by an empty line.\n\tHeadComment string\n\n\t// LineComment holds any comments at the end of the line where the node is in.\n\tLineComment string\n\n\t// FootComment holds any comments following the node and before empty lines.\n\tFootComment string\n\n\t// Line and Column hold the node position in the decoded YAML text.\n\t// These fields are not respected when encoding the node.\n\tLine   int\n\tColumn int\n}\n\n// IsZero returns whether the node has all of its fields unset.\nfunc (n *Node) IsZero() bool {\n\treturn n.Kind == 0 && n.Style == 0 && n.Tag == \"\" && n.Value == \"\" && n.Anchor == \"\" && n.Alias == nil && n.Content == nil &&\n\t\tn.HeadComment == \"\" && n.LineComment == \"\" && n.FootComment == \"\" && n.Line == 0 && n.Column == 0\n}\n\n// LongTag returns the long form of the tag that indicates the data type for\n// the node. If the Tag field isn't explicitly defined, one will be computed\n// based on the node properties.\nfunc (n *Node) LongTag() string {\n\treturn longTag(n.ShortTag())\n}\n\n// ShortTag returns the short form of the YAML tag that indicates data type for\n// the node. If the Tag field isn't explicitly defined, one will be computed\n// based on the node properties.\nfunc (n *Node) ShortTag() string {\n\tif n.indicatedString() {\n\t\treturn strTag\n\t}\n\tif n.Tag == \"\" || n.Tag == \"!\" {\n\t\tswitch n.Kind {\n\t\tcase MappingNode:\n\t\t\treturn mapTag\n\t\tcase SequenceNode:\n\t\t\treturn seqTag\n\t\tcase AliasNode:\n\t\t\tif n.Alias != nil {\n\t\t\t\treturn n.Alias.ShortTag()\n\t\t\t}\n\t\tcase ScalarNode:\n\t\t\ttag, _ := resolve(\"\", n.Value)\n\t\t\treturn tag\n\t\tcase 0:\n\t\t\t// Special case to make the zero value convenient.\n\t\t\tif n.IsZero() {\n\t\t\t\treturn nullTag\n\t\t\t}\n\t\t}\n\t\treturn \"\"\n\t}\n\treturn shortTag(n.Tag)\n}\n\nfunc (n *Node) indicatedString() bool {\n\treturn n.Kind == ScalarNode &&\n\t\t(shortTag(n.Tag) == strTag ||\n\t\t\t(n.Tag == \"\" || n.Tag == \"!\") && n.Style&(SingleQuotedStyle|DoubleQuotedStyle|LiteralStyle|FoldedStyle) != 0)\n}\n\n// SetString is a convenience function that sets the node to a string value\n// and defines its style in a pleasant way depending on its content.\nfunc (n *Node) SetString(s string) {\n\tn.Kind = ScalarNode\n\tif utf8.ValidString(s) {\n\t\tn.Value = s\n\t\tn.Tag = strTag\n\t} else {\n\t\tn.Value = encodeBase64(s)\n\t\tn.Tag = binaryTag\n\t}\n\tif strings.Contains(n.Value, \"\\n\") {\n\t\tn.Style = LiteralStyle\n\t}\n}\n\n// --------------------------------------------------------------------------\n// Maintain a mapping of keys to structure field indexes\n\n// The code in this section was copied from mgo/bson.\n\n// structInfo holds details for the serialization of fields of\n// a given struct.\ntype structInfo struct {\n\tFieldsMap  map[string]fieldInfo\n\tFieldsList []fieldInfo\n\n\t// InlineMap is the number of the field in the struct that\n\t// contains an ,inline map, or -1 if there's none.\n\tInlineMap int\n\n\t// InlineUnmarshalers holds indexes to inlined fields that\n\t// contain unmarshaler values.\n\tInlineUnmarshalers [][]int\n}\n\ntype fieldInfo struct {\n\tKey       string\n\tNum       int\n\tOmitEmpty bool\n\tFlow      bool\n\t// Id holds the unique field identifier, so we can cheaply\n\t// check for field duplicates without maintaining an extra map.\n\tId int\n\n\t// Inline holds the field index if the field is part of an inlined struct.\n\tInline []int\n}\n\nvar structMap = make(map[reflect.Type]*structInfo)\nvar fieldMapMutex sync.RWMutex\nvar unmarshalerType reflect.Type\n\nfunc init() {\n\tvar v Unmarshaler\n\tunmarshalerType = reflect.ValueOf(&v).Elem().Type()\n}\n\nfunc getStructInfo(st reflect.Type) (*structInfo, error) {\n\tfieldMapMutex.RLock()\n\tsinfo, found := structMap[st]\n\tfieldMapMutex.RUnlock()\n\tif found {\n\t\treturn sinfo, nil\n\t}\n\n\tn := st.NumField()\n\tfieldsMap := make(map[string]fieldInfo)\n\tfieldsList := make([]fieldInfo, 0, n)\n\tinlineMap := -1\n\tinlineUnmarshalers := [][]int(nil)\n\tfor i := 0; i != n; i++ {\n\t\tfield := st.Field(i)\n\t\tif field.PkgPath != \"\" && !field.Anonymous {\n\t\t\tcontinue // Private field\n\t\t}\n\n\t\tinfo := fieldInfo{Num: i}\n\n\t\ttag := field.Tag.Get(\"yaml\")\n\t\tif tag == \"\" && strings.Index(string(field.Tag), \":\") < 0 {\n\t\t\ttag = string(field.Tag)\n\t\t}\n\t\tif tag == \"-\" {\n\t\t\tcontinue\n\t\t}\n\n\t\tinline := false\n\t\tfields := strings.Split(tag, \",\")\n\t\tif len(fields) > 1 {\n\t\t\tfor _, flag := range fields[1:] {\n\t\t\t\tswitch flag {\n\t\t\t\tcase \"omitempty\":\n\t\t\t\t\tinfo.OmitEmpty = true\n\t\t\t\tcase \"flow\":\n\t\t\t\t\tinfo.Flow = true\n\t\t\t\tcase \"inline\":\n\t\t\t\t\tinline = true\n\t\t\t\tdefault:\n\t\t\t\t\treturn nil, errors.New(fmt.Sprintf(\"unsupported flag %q in tag %q of type %s\", flag, tag, st))\n\t\t\t\t}\n\t\t\t}\n\t\t\ttag = fields[0]\n\t\t}\n\n\t\tif inline {\n\t\t\tswitch field.Type.Kind() {\n\t\t\tcase reflect.Map:\n\t\t\t\tif inlineMap >= 0 {\n\t\t\t\t\treturn nil, errors.New(\"multiple ,inline maps in struct \" + st.String())\n\t\t\t\t}\n\t\t\t\tif field.Type.Key() != reflect.TypeOf(\"\") {\n\t\t\t\t\treturn nil, errors.New(\"option ,inline needs a map with string keys in struct \" + st.String())\n\t\t\t\t}\n\t\t\t\tinlineMap = info.Num\n\t\t\tcase reflect.Struct, reflect.Ptr:\n\t\t\t\tftype := field.Type\n\t\t\t\tfor ftype.Kind() == reflect.Ptr {\n\t\t\t\t\tftype = ftype.Elem()\n\t\t\t\t}\n\t\t\t\tif ftype.Kind() != reflect.Struct {\n\t\t\t\t\treturn nil, errors.New(\"option ,inline may only be used on a struct or map field\")\n\t\t\t\t}\n\t\t\t\tif reflect.PtrTo(ftype).Implements(unmarshalerType) {\n\t\t\t\t\tinlineUnmarshalers = append(inlineUnmarshalers, []int{i})\n\t\t\t\t} else {\n\t\t\t\t\tsinfo, err := getStructInfo(ftype)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, err\n\t\t\t\t\t}\n\t\t\t\t\tfor _, index := range sinfo.InlineUnmarshalers {\n\t\t\t\t\t\tinlineUnmarshalers = append(inlineUnmarshalers, append([]int{i}, index...))\n\t\t\t\t\t}\n\t\t\t\t\tfor _, finfo := range sinfo.FieldsList {\n\t\t\t\t\t\tif _, found := fieldsMap[finfo.Key]; found {\n\t\t\t\t\t\t\tmsg := \"duplicated key '\" + finfo.Key + \"' in struct \" + st.String()\n\t\t\t\t\t\t\treturn nil, errors.New(msg)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif finfo.Inline == nil {\n\t\t\t\t\t\t\tfinfo.Inline = []int{i, finfo.Num}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfinfo.Inline = append([]int{i}, finfo.Inline...)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinfo.Id = len(fieldsList)\n\t\t\t\t\t\tfieldsMap[finfo.Key] = finfo\n\t\t\t\t\t\tfieldsList = append(fieldsList, finfo)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn nil, errors.New(\"option ,inline may only be used on a struct or map field\")\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif tag != \"\" {\n\t\t\tinfo.Key = tag\n\t\t} else {\n\t\t\tinfo.Key = strings.ToLower(field.Name)\n\t\t}\n\n\t\tif _, found = fieldsMap[info.Key]; found {\n\t\t\tmsg := \"duplicated key '\" + info.Key + \"' in struct \" + st.String()\n\t\t\treturn nil, errors.New(msg)\n\t\t}\n\n\t\tinfo.Id = len(fieldsList)\n\t\tfieldsList = append(fieldsList, info)\n\t\tfieldsMap[info.Key] = info\n\t}\n\n\tsinfo = &structInfo{\n\t\tFieldsMap:          fieldsMap,\n\t\tFieldsList:         fieldsList,\n\t\tInlineMap:          inlineMap,\n\t\tInlineUnmarshalers: inlineUnmarshalers,\n\t}\n\n\tfieldMapMutex.Lock()\n\tstructMap[st] = sinfo\n\tfieldMapMutex.Unlock()\n\treturn sinfo, nil\n}\n\n// IsZeroer is used to check whether an object is zero to\n// determine whether it should be omitted when marshaling\n// with the omitempty flag. One notable implementation\n// is time.Time.\ntype IsZeroer interface {\n\tIsZero() bool\n}\n\nfunc isZero(v reflect.Value) bool {\n\tkind := v.Kind()\n\tif z, ok := v.Interface().(IsZeroer); ok {\n\t\tif (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {\n\t\t\treturn true\n\t\t}\n\t\treturn z.IsZero()\n\t}\n\tswitch kind {\n\tcase reflect.String:\n\t\treturn len(v.String()) == 0\n\tcase reflect.Interface, reflect.Ptr:\n\t\treturn v.IsNil()\n\tcase reflect.Slice:\n\t\treturn v.Len() == 0\n\tcase reflect.Map:\n\t\treturn v.Len() == 0\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn v.Uint() == 0\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Struct:\n\t\tvt := v.Type()\n\t\tfor i := v.NumField() - 1; i >= 0; i-- {\n\t\t\tif vt.Field(i).PkgPath != \"\" {\n\t\t\t\tcontinue // Private field\n\t\t\t}\n\t\t\tif !isZero(v.Field(i)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/yamlh.go",
    "content": "//\n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// The version directive data.\ntype yaml_version_directive_t struct {\n\tmajor int8 // The major version number.\n\tminor int8 // The minor version number.\n}\n\n// The tag directive data.\ntype yaml_tag_directive_t struct {\n\thandle []byte // The tag handle.\n\tprefix []byte // The tag prefix.\n}\n\ntype yaml_encoding_t int\n\n// The stream encoding.\nconst (\n\t// Let the parser choose the encoding.\n\tyaml_ANY_ENCODING yaml_encoding_t = iota\n\n\tyaml_UTF8_ENCODING    // The default UTF-8 encoding.\n\tyaml_UTF16LE_ENCODING // The UTF-16-LE encoding with BOM.\n\tyaml_UTF16BE_ENCODING // The UTF-16-BE encoding with BOM.\n)\n\ntype yaml_break_t int\n\n// Line break types.\nconst (\n\t// Let the parser choose the break type.\n\tyaml_ANY_BREAK yaml_break_t = iota\n\n\tyaml_CR_BREAK   // Use CR for line breaks (Mac style).\n\tyaml_LN_BREAK   // Use LN for line breaks (Unix style).\n\tyaml_CRLN_BREAK // Use CR LN for line breaks (DOS style).\n)\n\ntype yaml_error_type_t int\n\n// Many bad things could happen with the parser and emitter.\nconst (\n\t// No error is produced.\n\tyaml_NO_ERROR yaml_error_type_t = iota\n\n\tyaml_MEMORY_ERROR   // Cannot allocate or reallocate a block of memory.\n\tyaml_READER_ERROR   // Cannot read or decode the input stream.\n\tyaml_SCANNER_ERROR  // Cannot scan the input stream.\n\tyaml_PARSER_ERROR   // Cannot parse the input stream.\n\tyaml_COMPOSER_ERROR // Cannot compose a YAML document.\n\tyaml_WRITER_ERROR   // Cannot write to the output stream.\n\tyaml_EMITTER_ERROR  // Cannot emit a YAML stream.\n)\n\n// The pointer position.\ntype yaml_mark_t struct {\n\tindex  int // The position index.\n\tline   int // The position line.\n\tcolumn int // The position column.\n}\n\n// Node Styles\n\ntype yaml_style_t int8\n\ntype yaml_scalar_style_t yaml_style_t\n\n// Scalar styles.\nconst (\n\t// Let the emitter choose the style.\n\tyaml_ANY_SCALAR_STYLE yaml_scalar_style_t = 0\n\n\tyaml_PLAIN_SCALAR_STYLE         yaml_scalar_style_t = 1 << iota // The plain scalar style.\n\tyaml_SINGLE_QUOTED_SCALAR_STYLE                                 // The single-quoted scalar style.\n\tyaml_DOUBLE_QUOTED_SCALAR_STYLE                                 // The double-quoted scalar style.\n\tyaml_LITERAL_SCALAR_STYLE                                       // The literal scalar style.\n\tyaml_FOLDED_SCALAR_STYLE                                        // The folded scalar style.\n)\n\ntype yaml_sequence_style_t yaml_style_t\n\n// Sequence styles.\nconst (\n\t// Let the emitter choose the style.\n\tyaml_ANY_SEQUENCE_STYLE yaml_sequence_style_t = iota\n\n\tyaml_BLOCK_SEQUENCE_STYLE // The block sequence style.\n\tyaml_FLOW_SEQUENCE_STYLE  // The flow sequence style.\n)\n\ntype yaml_mapping_style_t yaml_style_t\n\n// Mapping styles.\nconst (\n\t// Let the emitter choose the style.\n\tyaml_ANY_MAPPING_STYLE yaml_mapping_style_t = iota\n\n\tyaml_BLOCK_MAPPING_STYLE // The block mapping style.\n\tyaml_FLOW_MAPPING_STYLE  // The flow mapping style.\n)\n\n// Tokens\n\ntype yaml_token_type_t int\n\n// Token types.\nconst (\n\t// An empty token.\n\tyaml_NO_TOKEN yaml_token_type_t = iota\n\n\tyaml_STREAM_START_TOKEN // A STREAM-START token.\n\tyaml_STREAM_END_TOKEN   // A STREAM-END token.\n\n\tyaml_VERSION_DIRECTIVE_TOKEN // A VERSION-DIRECTIVE token.\n\tyaml_TAG_DIRECTIVE_TOKEN     // A TAG-DIRECTIVE token.\n\tyaml_DOCUMENT_START_TOKEN    // A DOCUMENT-START token.\n\tyaml_DOCUMENT_END_TOKEN      // A DOCUMENT-END token.\n\n\tyaml_BLOCK_SEQUENCE_START_TOKEN // A BLOCK-SEQUENCE-START token.\n\tyaml_BLOCK_MAPPING_START_TOKEN  // A BLOCK-SEQUENCE-END token.\n\tyaml_BLOCK_END_TOKEN            // A BLOCK-END token.\n\n\tyaml_FLOW_SEQUENCE_START_TOKEN // A FLOW-SEQUENCE-START token.\n\tyaml_FLOW_SEQUENCE_END_TOKEN   // A FLOW-SEQUENCE-END token.\n\tyaml_FLOW_MAPPING_START_TOKEN  // A FLOW-MAPPING-START token.\n\tyaml_FLOW_MAPPING_END_TOKEN    // A FLOW-MAPPING-END token.\n\n\tyaml_BLOCK_ENTRY_TOKEN // A BLOCK-ENTRY token.\n\tyaml_FLOW_ENTRY_TOKEN  // A FLOW-ENTRY token.\n\tyaml_KEY_TOKEN         // A KEY token.\n\tyaml_VALUE_TOKEN       // A VALUE token.\n\n\tyaml_ALIAS_TOKEN  // An ALIAS token.\n\tyaml_ANCHOR_TOKEN // An ANCHOR token.\n\tyaml_TAG_TOKEN    // A TAG token.\n\tyaml_SCALAR_TOKEN // A SCALAR token.\n)\n\nfunc (tt yaml_token_type_t) String() string {\n\tswitch tt {\n\tcase yaml_NO_TOKEN:\n\t\treturn \"yaml_NO_TOKEN\"\n\tcase yaml_STREAM_START_TOKEN:\n\t\treturn \"yaml_STREAM_START_TOKEN\"\n\tcase yaml_STREAM_END_TOKEN:\n\t\treturn \"yaml_STREAM_END_TOKEN\"\n\tcase yaml_VERSION_DIRECTIVE_TOKEN:\n\t\treturn \"yaml_VERSION_DIRECTIVE_TOKEN\"\n\tcase yaml_TAG_DIRECTIVE_TOKEN:\n\t\treturn \"yaml_TAG_DIRECTIVE_TOKEN\"\n\tcase yaml_DOCUMENT_START_TOKEN:\n\t\treturn \"yaml_DOCUMENT_START_TOKEN\"\n\tcase yaml_DOCUMENT_END_TOKEN:\n\t\treturn \"yaml_DOCUMENT_END_TOKEN\"\n\tcase yaml_BLOCK_SEQUENCE_START_TOKEN:\n\t\treturn \"yaml_BLOCK_SEQUENCE_START_TOKEN\"\n\tcase yaml_BLOCK_MAPPING_START_TOKEN:\n\t\treturn \"yaml_BLOCK_MAPPING_START_TOKEN\"\n\tcase yaml_BLOCK_END_TOKEN:\n\t\treturn \"yaml_BLOCK_END_TOKEN\"\n\tcase yaml_FLOW_SEQUENCE_START_TOKEN:\n\t\treturn \"yaml_FLOW_SEQUENCE_START_TOKEN\"\n\tcase yaml_FLOW_SEQUENCE_END_TOKEN:\n\t\treturn \"yaml_FLOW_SEQUENCE_END_TOKEN\"\n\tcase yaml_FLOW_MAPPING_START_TOKEN:\n\t\treturn \"yaml_FLOW_MAPPING_START_TOKEN\"\n\tcase yaml_FLOW_MAPPING_END_TOKEN:\n\t\treturn \"yaml_FLOW_MAPPING_END_TOKEN\"\n\tcase yaml_BLOCK_ENTRY_TOKEN:\n\t\treturn \"yaml_BLOCK_ENTRY_TOKEN\"\n\tcase yaml_FLOW_ENTRY_TOKEN:\n\t\treturn \"yaml_FLOW_ENTRY_TOKEN\"\n\tcase yaml_KEY_TOKEN:\n\t\treturn \"yaml_KEY_TOKEN\"\n\tcase yaml_VALUE_TOKEN:\n\t\treturn \"yaml_VALUE_TOKEN\"\n\tcase yaml_ALIAS_TOKEN:\n\t\treturn \"yaml_ALIAS_TOKEN\"\n\tcase yaml_ANCHOR_TOKEN:\n\t\treturn \"yaml_ANCHOR_TOKEN\"\n\tcase yaml_TAG_TOKEN:\n\t\treturn \"yaml_TAG_TOKEN\"\n\tcase yaml_SCALAR_TOKEN:\n\t\treturn \"yaml_SCALAR_TOKEN\"\n\t}\n\treturn \"<unknown token>\"\n}\n\n// The token structure.\ntype yaml_token_t struct {\n\t// The token type.\n\ttyp yaml_token_type_t\n\n\t// The start/end of the token.\n\tstart_mark, end_mark yaml_mark_t\n\n\t// The stream encoding (for yaml_STREAM_START_TOKEN).\n\tencoding yaml_encoding_t\n\n\t// The alias/anchor/scalar value or tag/tag directive handle\n\t// (for yaml_ALIAS_TOKEN, yaml_ANCHOR_TOKEN, yaml_SCALAR_TOKEN, yaml_TAG_TOKEN, yaml_TAG_DIRECTIVE_TOKEN).\n\tvalue []byte\n\n\t// The tag suffix (for yaml_TAG_TOKEN).\n\tsuffix []byte\n\n\t// The tag directive prefix (for yaml_TAG_DIRECTIVE_TOKEN).\n\tprefix []byte\n\n\t// The scalar style (for yaml_SCALAR_TOKEN).\n\tstyle yaml_scalar_style_t\n\n\t// The version directive major/minor (for yaml_VERSION_DIRECTIVE_TOKEN).\n\tmajor, minor int8\n}\n\n// Events\n\ntype yaml_event_type_t int8\n\n// Event types.\nconst (\n\t// An empty event.\n\tyaml_NO_EVENT yaml_event_type_t = iota\n\n\tyaml_STREAM_START_EVENT   // A STREAM-START event.\n\tyaml_STREAM_END_EVENT     // A STREAM-END event.\n\tyaml_DOCUMENT_START_EVENT // A DOCUMENT-START event.\n\tyaml_DOCUMENT_END_EVENT   // A DOCUMENT-END event.\n\tyaml_ALIAS_EVENT          // An ALIAS event.\n\tyaml_SCALAR_EVENT         // A SCALAR event.\n\tyaml_SEQUENCE_START_EVENT // A SEQUENCE-START event.\n\tyaml_SEQUENCE_END_EVENT   // A SEQUENCE-END event.\n\tyaml_MAPPING_START_EVENT  // A MAPPING-START event.\n\tyaml_MAPPING_END_EVENT    // A MAPPING-END event.\n\tyaml_TAIL_COMMENT_EVENT\n)\n\nvar eventStrings = []string{\n\tyaml_NO_EVENT:             \"none\",\n\tyaml_STREAM_START_EVENT:   \"stream start\",\n\tyaml_STREAM_END_EVENT:     \"stream end\",\n\tyaml_DOCUMENT_START_EVENT: \"document start\",\n\tyaml_DOCUMENT_END_EVENT:   \"document end\",\n\tyaml_ALIAS_EVENT:          \"alias\",\n\tyaml_SCALAR_EVENT:         \"scalar\",\n\tyaml_SEQUENCE_START_EVENT: \"sequence start\",\n\tyaml_SEQUENCE_END_EVENT:   \"sequence end\",\n\tyaml_MAPPING_START_EVENT:  \"mapping start\",\n\tyaml_MAPPING_END_EVENT:    \"mapping end\",\n\tyaml_TAIL_COMMENT_EVENT:   \"tail comment\",\n}\n\nfunc (e yaml_event_type_t) String() string {\n\tif e < 0 || int(e) >= len(eventStrings) {\n\t\treturn fmt.Sprintf(\"unknown event %d\", e)\n\t}\n\treturn eventStrings[e]\n}\n\n// The event structure.\ntype yaml_event_t struct {\n\n\t// The event type.\n\ttyp yaml_event_type_t\n\n\t// The start and end of the event.\n\tstart_mark, end_mark yaml_mark_t\n\n\t// The document encoding (for yaml_STREAM_START_EVENT).\n\tencoding yaml_encoding_t\n\n\t// The version directive (for yaml_DOCUMENT_START_EVENT).\n\tversion_directive *yaml_version_directive_t\n\n\t// The list of tag directives (for yaml_DOCUMENT_START_EVENT).\n\ttag_directives []yaml_tag_directive_t\n\n\t// The comments\n\thead_comment []byte\n\tline_comment []byte\n\tfoot_comment []byte\n\ttail_comment []byte\n\n\t// The anchor (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_ALIAS_EVENT).\n\tanchor []byte\n\n\t// The tag (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).\n\ttag []byte\n\n\t// The scalar value (for yaml_SCALAR_EVENT).\n\tvalue []byte\n\n\t// Is the document start/end indicator implicit, or the tag optional?\n\t// (for yaml_DOCUMENT_START_EVENT, yaml_DOCUMENT_END_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT, yaml_SCALAR_EVENT).\n\timplicit bool\n\n\t// Is the tag optional for any non-plain style? (for yaml_SCALAR_EVENT).\n\tquoted_implicit bool\n\n\t// The style (for yaml_SCALAR_EVENT, yaml_SEQUENCE_START_EVENT, yaml_MAPPING_START_EVENT).\n\tstyle yaml_style_t\n}\n\nfunc (e *yaml_event_t) scalar_style() yaml_scalar_style_t     { return yaml_scalar_style_t(e.style) }\nfunc (e *yaml_event_t) sequence_style() yaml_sequence_style_t { return yaml_sequence_style_t(e.style) }\nfunc (e *yaml_event_t) mapping_style() yaml_mapping_style_t   { return yaml_mapping_style_t(e.style) }\n\n// Nodes\n\nconst (\n\tyaml_NULL_TAG      = \"tag:yaml.org,2002:null\"      // The tag !!null with the only possible value: null.\n\tyaml_BOOL_TAG      = \"tag:yaml.org,2002:bool\"      // The tag !!bool with the values: true and false.\n\tyaml_STR_TAG       = \"tag:yaml.org,2002:str\"       // The tag !!str for string values.\n\tyaml_INT_TAG       = \"tag:yaml.org,2002:int\"       // The tag !!int for integer values.\n\tyaml_FLOAT_TAG     = \"tag:yaml.org,2002:float\"     // The tag !!float for float values.\n\tyaml_TIMESTAMP_TAG = \"tag:yaml.org,2002:timestamp\" // The tag !!timestamp for date and time values.\n\n\tyaml_SEQ_TAG = \"tag:yaml.org,2002:seq\" // The tag !!seq is used to denote sequences.\n\tyaml_MAP_TAG = \"tag:yaml.org,2002:map\" // The tag !!map is used to denote mapping.\n\n\t// Not in original libyaml.\n\tyaml_BINARY_TAG = \"tag:yaml.org,2002:binary\"\n\tyaml_MERGE_TAG  = \"tag:yaml.org,2002:merge\"\n\n\tyaml_DEFAULT_SCALAR_TAG   = yaml_STR_TAG // The default scalar tag is !!str.\n\tyaml_DEFAULT_SEQUENCE_TAG = yaml_SEQ_TAG // The default sequence tag is !!seq.\n\tyaml_DEFAULT_MAPPING_TAG  = yaml_MAP_TAG // The default mapping tag is !!map.\n)\n\ntype yaml_node_type_t int\n\n// Node types.\nconst (\n\t// An empty node.\n\tyaml_NO_NODE yaml_node_type_t = iota\n\n\tyaml_SCALAR_NODE   // A scalar node.\n\tyaml_SEQUENCE_NODE // A sequence node.\n\tyaml_MAPPING_NODE  // A mapping node.\n)\n\n// An element of a sequence node.\ntype yaml_node_item_t int\n\n// An element of a mapping node.\ntype yaml_node_pair_t struct {\n\tkey   int // The key of the element.\n\tvalue int // The value of the element.\n}\n\n// The node structure.\ntype yaml_node_t struct {\n\ttyp yaml_node_type_t // The node type.\n\ttag []byte           // The node tag.\n\n\t// The node data.\n\n\t// The scalar parameters (for yaml_SCALAR_NODE).\n\tscalar struct {\n\t\tvalue  []byte              // The scalar value.\n\t\tlength int                 // The length of the scalar value.\n\t\tstyle  yaml_scalar_style_t // The scalar style.\n\t}\n\n\t// The sequence parameters (for YAML_SEQUENCE_NODE).\n\tsequence struct {\n\t\titems_data []yaml_node_item_t    // The stack of sequence items.\n\t\tstyle      yaml_sequence_style_t // The sequence style.\n\t}\n\n\t// The mapping parameters (for yaml_MAPPING_NODE).\n\tmapping struct {\n\t\tpairs_data  []yaml_node_pair_t   // The stack of mapping pairs (key, value).\n\t\tpairs_start *yaml_node_pair_t    // The beginning of the stack.\n\t\tpairs_end   *yaml_node_pair_t    // The end of the stack.\n\t\tpairs_top   *yaml_node_pair_t    // The top of the stack.\n\t\tstyle       yaml_mapping_style_t // The mapping style.\n\t}\n\n\tstart_mark yaml_mark_t // The beginning of the node.\n\tend_mark   yaml_mark_t // The end of the node.\n\n}\n\n// The document structure.\ntype yaml_document_t struct {\n\n\t// The document nodes.\n\tnodes []yaml_node_t\n\n\t// The version directive.\n\tversion_directive *yaml_version_directive_t\n\n\t// The list of tag directives.\n\ttag_directives_data  []yaml_tag_directive_t\n\ttag_directives_start int // The beginning of the tag directives list.\n\ttag_directives_end   int // The end of the tag directives list.\n\n\tstart_implicit int // Is the document start indicator implicit?\n\tend_implicit   int // Is the document end indicator implicit?\n\n\t// The start/end of the document.\n\tstart_mark, end_mark yaml_mark_t\n}\n\n// The prototype of a read handler.\n//\n// The read handler is called when the parser needs to read more bytes from the\n// source. The handler should write not more than size bytes to the buffer.\n// The number of written bytes should be set to the size_read variable.\n//\n// [in,out]   data        A pointer to an application data specified by\n//                        yaml_parser_set_input().\n// [out]      buffer      The buffer to write the data from the source.\n// [in]       size        The size of the buffer.\n// [out]      size_read   The actual number of bytes read from the source.\n//\n// On success, the handler should return 1.  If the handler failed,\n// the returned value should be 0. On EOF, the handler should set the\n// size_read to 0 and return 1.\ntype yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error)\n\n// This structure holds information about a potential simple key.\ntype yaml_simple_key_t struct {\n\tpossible     bool        // Is a simple key possible?\n\trequired     bool        // Is a simple key required?\n\ttoken_number int         // The number of the token.\n\tmark         yaml_mark_t // The position mark.\n}\n\n// The states of the parser.\ntype yaml_parser_state_t int\n\nconst (\n\tyaml_PARSE_STREAM_START_STATE yaml_parser_state_t = iota\n\n\tyaml_PARSE_IMPLICIT_DOCUMENT_START_STATE           // Expect the beginning of an implicit document.\n\tyaml_PARSE_DOCUMENT_START_STATE                    // Expect DOCUMENT-START.\n\tyaml_PARSE_DOCUMENT_CONTENT_STATE                  // Expect the content of a document.\n\tyaml_PARSE_DOCUMENT_END_STATE                      // Expect DOCUMENT-END.\n\tyaml_PARSE_BLOCK_NODE_STATE                        // Expect a block node.\n\tyaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE // Expect a block node or indentless sequence.\n\tyaml_PARSE_FLOW_NODE_STATE                         // Expect a flow node.\n\tyaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE        // Expect the first entry of a block sequence.\n\tyaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE              // Expect an entry of a block sequence.\n\tyaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE         // Expect an entry of an indentless sequence.\n\tyaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE           // Expect the first key of a block mapping.\n\tyaml_PARSE_BLOCK_MAPPING_KEY_STATE                 // Expect a block mapping key.\n\tyaml_PARSE_BLOCK_MAPPING_VALUE_STATE               // Expect a block mapping value.\n\tyaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE         // Expect the first entry of a flow sequence.\n\tyaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE               // Expect an entry of a flow sequence.\n\tyaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE   // Expect a key of an ordered mapping.\n\tyaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE // Expect a value of an ordered mapping.\n\tyaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE   // Expect the and of an ordered mapping entry.\n\tyaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE            // Expect the first key of a flow mapping.\n\tyaml_PARSE_FLOW_MAPPING_KEY_STATE                  // Expect a key of a flow mapping.\n\tyaml_PARSE_FLOW_MAPPING_VALUE_STATE                // Expect a value of a flow mapping.\n\tyaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE          // Expect an empty value of a flow mapping.\n\tyaml_PARSE_END_STATE                               // Expect nothing.\n)\n\nfunc (ps yaml_parser_state_t) String() string {\n\tswitch ps {\n\tcase yaml_PARSE_STREAM_START_STATE:\n\t\treturn \"yaml_PARSE_STREAM_START_STATE\"\n\tcase yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE:\n\t\treturn \"yaml_PARSE_IMPLICIT_DOCUMENT_START_STATE\"\n\tcase yaml_PARSE_DOCUMENT_START_STATE:\n\t\treturn \"yaml_PARSE_DOCUMENT_START_STATE\"\n\tcase yaml_PARSE_DOCUMENT_CONTENT_STATE:\n\t\treturn \"yaml_PARSE_DOCUMENT_CONTENT_STATE\"\n\tcase yaml_PARSE_DOCUMENT_END_STATE:\n\t\treturn \"yaml_PARSE_DOCUMENT_END_STATE\"\n\tcase yaml_PARSE_BLOCK_NODE_STATE:\n\t\treturn \"yaml_PARSE_BLOCK_NODE_STATE\"\n\tcase yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE:\n\t\treturn \"yaml_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE\"\n\tcase yaml_PARSE_FLOW_NODE_STATE:\n\t\treturn \"yaml_PARSE_FLOW_NODE_STATE\"\n\tcase yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE:\n\t\treturn \"yaml_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE\"\n\tcase yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE:\n\t\treturn \"yaml_PARSE_BLOCK_SEQUENCE_ENTRY_STATE\"\n\tcase yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE:\n\t\treturn \"yaml_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE\"\n\tcase yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE:\n\t\treturn \"yaml_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE\"\n\tcase yaml_PARSE_BLOCK_MAPPING_KEY_STATE:\n\t\treturn \"yaml_PARSE_BLOCK_MAPPING_KEY_STATE\"\n\tcase yaml_PARSE_BLOCK_MAPPING_VALUE_STATE:\n\t\treturn \"yaml_PARSE_BLOCK_MAPPING_VALUE_STATE\"\n\tcase yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE:\n\t\treturn \"yaml_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE\"\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE:\n\t\treturn \"yaml_PARSE_FLOW_SEQUENCE_ENTRY_STATE\"\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE:\n\t\treturn \"yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE\"\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE:\n\t\treturn \"yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE\"\n\tcase yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE:\n\t\treturn \"yaml_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE\"\n\tcase yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE:\n\t\treturn \"yaml_PARSE_FLOW_MAPPING_FIRST_KEY_STATE\"\n\tcase yaml_PARSE_FLOW_MAPPING_KEY_STATE:\n\t\treturn \"yaml_PARSE_FLOW_MAPPING_KEY_STATE\"\n\tcase yaml_PARSE_FLOW_MAPPING_VALUE_STATE:\n\t\treturn \"yaml_PARSE_FLOW_MAPPING_VALUE_STATE\"\n\tcase yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE:\n\t\treturn \"yaml_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE\"\n\tcase yaml_PARSE_END_STATE:\n\t\treturn \"yaml_PARSE_END_STATE\"\n\t}\n\treturn \"<unknown parser state>\"\n}\n\n// This structure holds aliases data.\ntype yaml_alias_data_t struct {\n\tanchor []byte      // The anchor.\n\tindex  int         // The node id.\n\tmark   yaml_mark_t // The anchor mark.\n}\n\n// The parser structure.\n//\n// All members are internal. Manage the structure using the\n// yaml_parser_ family of functions.\ntype yaml_parser_t struct {\n\n\t// Error handling\n\n\terror yaml_error_type_t // Error type.\n\n\tproblem string // Error description.\n\n\t// The byte about which the problem occurred.\n\tproblem_offset int\n\tproblem_value  int\n\tproblem_mark   yaml_mark_t\n\n\t// The error context.\n\tcontext      string\n\tcontext_mark yaml_mark_t\n\n\t// Reader stuff\n\n\tread_handler yaml_read_handler_t // Read handler.\n\n\tinput_reader io.Reader // File input data.\n\tinput        []byte    // String input data.\n\tinput_pos    int\n\n\teof bool // EOF flag\n\n\tbuffer     []byte // The working buffer.\n\tbuffer_pos int    // The current position of the buffer.\n\n\tunread int // The number of unread characters in the buffer.\n\n\tnewlines int // The number of line breaks since last non-break/non-blank character\n\n\traw_buffer     []byte // The raw buffer.\n\traw_buffer_pos int    // The current position of the buffer.\n\n\tencoding yaml_encoding_t // The input encoding.\n\n\toffset int         // The offset of the current position (in bytes).\n\tmark   yaml_mark_t // The mark of the current position.\n\n\t// Comments\n\n\thead_comment []byte // The current head comments\n\tline_comment []byte // The current line comments\n\tfoot_comment []byte // The current foot comments\n\ttail_comment []byte // Foot comment that happens at the end of a block.\n\tstem_comment []byte // Comment in item preceding a nested structure (list inside list item, etc)\n\n\tcomments      []yaml_comment_t // The folded comments for all parsed tokens\n\tcomments_head int\n\n\t// Scanner stuff\n\n\tstream_start_produced bool // Have we started to scan the input stream?\n\tstream_end_produced   bool // Have we reached the end of the input stream?\n\n\tflow_level int // The number of unclosed '[' and '{' indicators.\n\n\ttokens          []yaml_token_t // The tokens queue.\n\ttokens_head     int            // The head of the tokens queue.\n\ttokens_parsed   int            // The number of tokens fetched from the queue.\n\ttoken_available bool           // Does the tokens queue contain a token ready for dequeueing.\n\n\tindent  int   // The current indentation level.\n\tindents []int // The indentation levels stack.\n\n\tsimple_key_allowed bool                // May a simple key occur at the current position?\n\tsimple_keys        []yaml_simple_key_t // The stack of simple keys.\n\tsimple_keys_by_tok map[int]int         // possible simple_key indexes indexed by token_number\n\n\t// Parser stuff\n\n\tstate          yaml_parser_state_t    // The current parser state.\n\tstates         []yaml_parser_state_t  // The parser states stack.\n\tmarks          []yaml_mark_t          // The stack of marks.\n\ttag_directives []yaml_tag_directive_t // The list of TAG directives.\n\n\t// Dumper stuff\n\n\taliases []yaml_alias_data_t // The alias data.\n\n\tdocument *yaml_document_t // The currently parsed document.\n}\n\ntype yaml_comment_t struct {\n\n\tscan_mark  yaml_mark_t // Position where scanning for comments started\n\ttoken_mark yaml_mark_t // Position after which tokens will be associated with this comment\n\tstart_mark yaml_mark_t // Position of '#' comment mark\n\tend_mark   yaml_mark_t // Position where comment terminated\n\n\thead []byte\n\tline []byte\n\tfoot []byte\n}\n\n// Emitter Definitions\n\n// The prototype of a write handler.\n//\n// The write handler is called when the emitter needs to flush the accumulated\n// characters to the output.  The handler should write @a size bytes of the\n// @a buffer to the output.\n//\n// @param[in,out]   data        A pointer to an application data specified by\n//                              yaml_emitter_set_output().\n// @param[in]       buffer      The buffer with bytes to be written.\n// @param[in]       size        The size of the buffer.\n//\n// @returns On success, the handler should return @c 1.  If the handler failed,\n// the returned value should be @c 0.\n//\ntype yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error\n\ntype yaml_emitter_state_t int\n\n// The emitter states.\nconst (\n\t// Expect STREAM-START.\n\tyaml_EMIT_STREAM_START_STATE yaml_emitter_state_t = iota\n\n\tyaml_EMIT_FIRST_DOCUMENT_START_STATE       // Expect the first DOCUMENT-START or STREAM-END.\n\tyaml_EMIT_DOCUMENT_START_STATE             // Expect DOCUMENT-START or STREAM-END.\n\tyaml_EMIT_DOCUMENT_CONTENT_STATE           // Expect the content of a document.\n\tyaml_EMIT_DOCUMENT_END_STATE               // Expect DOCUMENT-END.\n\tyaml_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE   // Expect the first item of a flow sequence.\n\tyaml_EMIT_FLOW_SEQUENCE_TRAIL_ITEM_STATE   // Expect the next item of a flow sequence, with the comma already written out\n\tyaml_EMIT_FLOW_SEQUENCE_ITEM_STATE         // Expect an item of a flow sequence.\n\tyaml_EMIT_FLOW_MAPPING_FIRST_KEY_STATE     // Expect the first key of a flow mapping.\n\tyaml_EMIT_FLOW_MAPPING_TRAIL_KEY_STATE     // Expect the next key of a flow mapping, with the comma already written out\n\tyaml_EMIT_FLOW_MAPPING_KEY_STATE           // Expect a key of a flow mapping.\n\tyaml_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE  // Expect a value for a simple key of a flow mapping.\n\tyaml_EMIT_FLOW_MAPPING_VALUE_STATE         // Expect a value of a flow mapping.\n\tyaml_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE  // Expect the first item of a block sequence.\n\tyaml_EMIT_BLOCK_SEQUENCE_ITEM_STATE        // Expect an item of a block sequence.\n\tyaml_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE    // Expect the first key of a block mapping.\n\tyaml_EMIT_BLOCK_MAPPING_KEY_STATE          // Expect the key of a block mapping.\n\tyaml_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE // Expect a value for a simple key of a block mapping.\n\tyaml_EMIT_BLOCK_MAPPING_VALUE_STATE        // Expect a value of a block mapping.\n\tyaml_EMIT_END_STATE                        // Expect nothing.\n)\n\n// The emitter structure.\n//\n// All members are internal.  Manage the structure using the @c yaml_emitter_\n// family of functions.\ntype yaml_emitter_t struct {\n\n\t// Error handling\n\n\terror   yaml_error_type_t // Error type.\n\tproblem string            // Error description.\n\n\t// Writer stuff\n\n\twrite_handler yaml_write_handler_t // Write handler.\n\n\toutput_buffer *[]byte   // String output data.\n\toutput_writer io.Writer // File output data.\n\n\tbuffer     []byte // The working buffer.\n\tbuffer_pos int    // The current position of the buffer.\n\n\traw_buffer     []byte // The raw buffer.\n\traw_buffer_pos int    // The current position of the buffer.\n\n\tencoding yaml_encoding_t // The stream encoding.\n\n\t// Emitter stuff\n\n\tcanonical   bool         // If the output is in the canonical style?\n\tbest_indent int          // The number of indentation spaces.\n\tbest_width  int          // The preferred width of the output lines.\n\tunicode     bool         // Allow unescaped non-ASCII characters?\n\tline_break  yaml_break_t // The preferred line break.\n\n\tstate  yaml_emitter_state_t   // The current emitter state.\n\tstates []yaml_emitter_state_t // The stack of states.\n\n\tevents      []yaml_event_t // The event queue.\n\tevents_head int            // The head of the event queue.\n\n\tindents []int // The stack of indentation levels.\n\n\ttag_directives []yaml_tag_directive_t // The list of tag directives.\n\n\tindent int // The current indentation level.\n\n\tflow_level int // The current flow level.\n\n\troot_context       bool // Is it the document root context?\n\tsequence_context   bool // Is it a sequence context?\n\tmapping_context    bool // Is it a mapping context?\n\tsimple_key_context bool // Is it a simple mapping key context?\n\n\tline       int  // The current line.\n\tcolumn     int  // The current column.\n\twhitespace bool // If the last character was a whitespace?\n\tindention  bool // If the last character was an indentation character (' ', '-', '?', ':')?\n\topen_ended bool // If an explicit document end is required?\n\n\tspace_above bool // Is there's an empty line above?\n\tfoot_indent int  // The indent used to write the foot comment above, or -1 if none.\n\n\t// Anchor analysis.\n\tanchor_data struct {\n\t\tanchor []byte // The anchor value.\n\t\talias  bool   // Is it an alias?\n\t}\n\n\t// Tag analysis.\n\ttag_data struct {\n\t\thandle []byte // The tag handle.\n\t\tsuffix []byte // The tag suffix.\n\t}\n\n\t// Scalar analysis.\n\tscalar_data struct {\n\t\tvalue                 []byte              // The scalar value.\n\t\tmultiline             bool                // Does the scalar contain line breaks?\n\t\tflow_plain_allowed    bool                // Can the scalar be expessed in the flow plain style?\n\t\tblock_plain_allowed   bool                // Can the scalar be expressed in the block plain style?\n\t\tsingle_quoted_allowed bool                // Can the scalar be expressed in the single quoted style?\n\t\tblock_allowed         bool                // Can the scalar be expressed in the literal or folded styles?\n\t\tstyle                 yaml_scalar_style_t // The output style.\n\t}\n\n\t// Comments\n\thead_comment []byte\n\tline_comment []byte\n\tfoot_comment []byte\n\ttail_comment []byte\n\n\tkey_line_comment []byte\n\n\t// Dumper stuff\n\n\topened bool // If the stream was already opened?\n\tclosed bool // If the stream was already closed?\n\n\t// The information associated with the document nodes.\n\tanchors *struct {\n\t\treferences int  // The number of references.\n\t\tanchor     int  // The anchor id.\n\t\tserialized bool // If the node has been emitted?\n\t}\n\n\tlast_anchor_id int // The last assigned anchor id.\n\n\tdocument *yaml_document_t // The currently emitted document.\n}\n"
  },
  {
    "path": "vendor/github.com/oasdiff/yaml3/yamlprivateh.go",
    "content": "// \n// Copyright (c) 2011-2019 Canonical Ltd\n// Copyright (c) 2006-2010 Kirill Simonov\n// \n// Permission is hereby granted, free of charge, to any person obtaining a copy of\n// this software and associated documentation files (the \"Software\"), to deal in\n// the Software without restriction, including without limitation the rights to\n// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n// of the Software, and to permit persons to whom the Software is furnished to do\n// so, subject to the following conditions:\n// \n// The above copyright notice and this permission notice shall be included in all\n// copies or substantial portions of the Software.\n// \n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n// SOFTWARE.\n\npackage yaml\n\nconst (\n\t// The size of the input raw buffer.\n\tinput_raw_buffer_size = 512\n\n\t// The size of the input buffer.\n\t// It should be possible to decode the whole raw buffer.\n\tinput_buffer_size = input_raw_buffer_size * 3\n\n\t// The size of the output buffer.\n\toutput_buffer_size = 128\n\n\t// The size of the output raw buffer.\n\t// It should be possible to encode the whole output buffer.\n\toutput_raw_buffer_size = (output_buffer_size*2 + 2)\n\n\t// The size of other stacks and queues.\n\tinitial_stack_size  = 16\n\tinitial_queue_size  = 16\n\tinitial_string_size = 16\n)\n\n// Check if the character at the specified position is an alphabetical\n// character, a digit, '_', or '-'.\nfunc is_alpha(b []byte, i int) bool {\n\treturn b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'Z' || b[i] >= 'a' && b[i] <= 'z' || b[i] == '_' || b[i] == '-'\n}\n\n// Check if the character at the specified position is a digit.\nfunc is_digit(b []byte, i int) bool {\n\treturn b[i] >= '0' && b[i] <= '9'\n}\n\n// Get the value of a digit.\nfunc as_digit(b []byte, i int) int {\n\treturn int(b[i]) - '0'\n}\n\n// Check if the character at the specified position is a hex-digit.\nfunc is_hex(b []byte, i int) bool {\n\treturn b[i] >= '0' && b[i] <= '9' || b[i] >= 'A' && b[i] <= 'F' || b[i] >= 'a' && b[i] <= 'f'\n}\n\n// Get the value of a hex-digit.\nfunc as_hex(b []byte, i int) int {\n\tbi := b[i]\n\tif bi >= 'A' && bi <= 'F' {\n\t\treturn int(bi) - 'A' + 10\n\t}\n\tif bi >= 'a' && bi <= 'f' {\n\t\treturn int(bi) - 'a' + 10\n\t}\n\treturn int(bi) - '0'\n}\n\n// Check if the character is ASCII.\nfunc is_ascii(b []byte, i int) bool {\n\treturn b[i] <= 0x7F\n}\n\n// Check if the character at the start of the buffer can be printed unescaped.\nfunc is_printable(b []byte, i int) bool {\n\treturn ((b[i] == 0x0A) || // . == #x0A\n\t\t(b[i] >= 0x20 && b[i] <= 0x7E) || // #x20 <= . <= #x7E\n\t\t(b[i] == 0xC2 && b[i+1] >= 0xA0) || // #0xA0 <= . <= #xD7FF\n\t\t(b[i] > 0xC2 && b[i] < 0xED) ||\n\t\t(b[i] == 0xED && b[i+1] < 0xA0) ||\n\t\t(b[i] == 0xEE) ||\n\t\t(b[i] == 0xEF && // #xE000 <= . <= #xFFFD\n\t\t\t!(b[i+1] == 0xBB && b[i+2] == 0xBF) && // && . != #xFEFF\n\t\t\t!(b[i+1] == 0xBF && (b[i+2] == 0xBE || b[i+2] == 0xBF))))\n}\n\n// Check if the character at the specified position is NUL.\nfunc is_z(b []byte, i int) bool {\n\treturn b[i] == 0x00\n}\n\n// Check if the beginning of the buffer is a BOM.\nfunc is_bom(b []byte, i int) bool {\n\treturn b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF\n}\n\n// Check if the character at the specified position is space.\nfunc is_space(b []byte, i int) bool {\n\treturn b[i] == ' '\n}\n\n// Check if the character at the specified position is tab.\nfunc is_tab(b []byte, i int) bool {\n\treturn b[i] == '\\t'\n}\n\n// Check if the character at the specified position is blank (space or tab).\nfunc is_blank(b []byte, i int) bool {\n\t//return is_space(b, i) || is_tab(b, i)\n\treturn b[i] == ' ' || b[i] == '\\t'\n}\n\n// Check if the character at the specified position is a line break.\nfunc is_break(b []byte, i int) bool {\n\treturn (b[i] == '\\r' || // CR (#xD)\n\t\tb[i] == '\\n' || // LF (#xA)\n\t\tb[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9) // PS (#x2029)\n}\n\nfunc is_crlf(b []byte, i int) bool {\n\treturn b[i] == '\\r' && b[i+1] == '\\n'\n}\n\n// Check if the character is a line break or NUL.\nfunc is_breakz(b []byte, i int) bool {\n\t//return is_break(b, i) || is_z(b, i)\n\treturn (\n\t\t// is_break:\n\t\tb[i] == '\\r' || // CR (#xD)\n\t\tb[i] == '\\n' || // LF (#xA)\n\t\tb[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)\n\t\t// is_z:\n\t\tb[i] == 0)\n}\n\n// Check if the character is a line break, space, or NUL.\nfunc is_spacez(b []byte, i int) bool {\n\t//return is_space(b, i) || is_breakz(b, i)\n\treturn (\n\t\t// is_space:\n\t\tb[i] == ' ' ||\n\t\t// is_breakz:\n\t\tb[i] == '\\r' || // CR (#xD)\n\t\tb[i] == '\\n' || // LF (#xA)\n\t\tb[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)\n\t\tb[i] == 0)\n}\n\n// Check if the character is a line break, space, tab, or NUL.\nfunc is_blankz(b []byte, i int) bool {\n\t//return is_blank(b, i) || is_breakz(b, i)\n\treturn (\n\t\t// is_blank:\n\t\tb[i] == ' ' || b[i] == '\\t' ||\n\t\t// is_breakz:\n\t\tb[i] == '\\r' || // CR (#xD)\n\t\tb[i] == '\\n' || // LF (#xA)\n\t\tb[i] == 0xC2 && b[i+1] == 0x85 || // NEL (#x85)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA8 || // LS (#x2028)\n\t\tb[i] == 0xE2 && b[i+1] == 0x80 && b[i+2] == 0xA9 || // PS (#x2029)\n\t\tb[i] == 0)\n}\n\n// Determine the width of the character.\nfunc width(b byte) int {\n\t// Don't replace these by a switch without first\n\t// confirming that it is being inlined.\n\tif b&0x80 == 0x00 {\n\t\treturn 1\n\t}\n\tif b&0xE0 == 0xC0 {\n\t\treturn 2\n\t}\n\tif b&0xF0 == 0xE0 {\n\t\treturn 3\n\t}\n\tif b&0xF8 == 0xF0 {\n\t\treturn 4\n\t}\n\treturn 0\n\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/.mailmap",
    "content": "Aaron Lehmann <aaronl@vitelus.com> <aaron.lehmann@docker.com>\nDerek McGowan <derek@mcg.dev> <derek@mcgstyle.net>\nStephen J Day <stephen.day@docker.com> <stevvooe@users.noreply.github.com>\nHaibing Zhou <zhouhaibing089@gmail.com>\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/.pullapprove.yml",
    "content": "version: 2\n\nrequirements:\n  signed_off_by:\n    required: true\n\nalways_pending:\n  title_regex: '^WIP'\n  explanation: 'Work in progress...'\n\ngroup_defaults:\n  required: 2\n  approve_by_comment:\n    enabled: true\n    approve_regex: '^LGTM'\n    reject_regex: '^Rejected'\n  reset_on_push:\n    enabled: true\n  author_approval:\n    ignored: true\n  conditions:\n    branches:\n      - master\n\ngroups:\n  go-digest:\n    teams:\n      - go-digest-maintainers\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/.travis.yml",
    "content": "language: go\ngo:\n  - 1.12.x\n  - 1.13.x\n  - master\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/CONTRIBUTING.md",
    "content": "# Contributing to Docker open source projects\n\nWant to hack on this project? Awesome! Here are instructions to get you started.\n\nThis project is a part of the [Docker](https://www.docker.com) project, and follows\nthe same rules and principles. If you're already familiar with the way\nDocker does things, you'll feel right at home.\n\nOtherwise, go read Docker's\n[contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md),\n[issue triaging](https://github.com/docker/docker/blob/master/project/ISSUE-TRIAGE.md),\n[review process](https://github.com/docker/docker/blob/master/project/REVIEWING.md) and\n[branches and tags](https://github.com/docker/docker/blob/master/project/BRANCHES-AND-TAGS.md).\n\nFor an in-depth description of our contribution process, visit the\ncontributors guide: [Understand how to contribute](https://docs.docker.com/opensource/workflow/make-a-contribution/)\n\n### Sign your work\n\nThe sign-off is a simple line at the end of the explanation for the patch. Your\nsignature certifies that you wrote the patch or otherwise have the right to pass\nit on as an open-source patch. The rules are pretty simple: if you can certify\nthe below (from [developercertificate.org](http://developercertificate.org/)):\n\n```\nDeveloper Certificate of Origin\nVersion 1.1\n\nCopyright (C) 2004, 2006 The Linux Foundation and its contributors.\n1 Letterman Drive\nSuite D4700\nSan Francisco, CA, 94129\n\nEveryone is permitted to copy and distribute verbatim copies of this\nlicense document, but changing it is not allowed.\n\n\nDeveloper's Certificate of Origin 1.1\n\nBy making a contribution to this project, I certify that:\n\n(a) The contribution was created in whole or in part by me and I\n    have the right to submit it under the open source license\n    indicated in the file; or\n\n(b) The contribution is based upon previous work that, to the best\n    of my knowledge, is covered under an appropriate open source\n    license and I have the right under that license to submit that\n    work with modifications, whether created in whole or in part\n    by me, under the same open source license (unless I am\n    permitted to submit under a different license), as indicated\n    in the file; or\n\n(c) The contribution was provided directly to me by some other\n    person who certified (a), (b) or (c) and I have not modified\n    it.\n\n(d) I understand and agree that this project and the contribution\n    are public and that a record of the contribution (including all\n    personal information I submit with it, including my sign-off) is\n    maintained indefinitely and may be redistributed consistent with\n    this project or the open source license(s) involved.\n```\n\nThen you just add a line to every git commit message:\n\n    Signed-off-by: Joe Smith <joe.smith@email.com>\n\nUse your real name (sorry, no pseudonyms or anonymous contributions.)\n\nIf you set your `user.name` and `user.email` git configs, you can sign your\ncommit automatically with `git commit -s`.\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/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 2019, 2020 OCI Contributors\n   Copyright 2016 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": "vendor/github.com/opencontainers/go-digest/LICENSE.docs",
    "content": "Attribution-ShareAlike 4.0 International\n\n=======================================================================\n\nCreative Commons Corporation (\"Creative Commons\") is not a law firm and\ndoes not provide legal services or legal advice. Distribution of\nCreative Commons public licenses does not create a lawyer-client or\nother relationship. Creative Commons makes its licenses and related\ninformation available on an \"as-is\" basis. Creative Commons gives no\nwarranties regarding its licenses, any material licensed under their\nterms and conditions, or any related information. Creative Commons\ndisclaims all liability for damages resulting from their use to the\nfullest extent possible.\n\nUsing Creative Commons Public Licenses\n\nCreative Commons public licenses provide a standard set of terms and\nconditions that creators and other rights holders may use to share\noriginal works of authorship and other material subject to copyright\nand certain other rights specified in the public license below. The\nfollowing considerations are for informational purposes only, are not\nexhaustive, and do not form part of our licenses.\n\n     Considerations for licensors: Our public licenses are\n     intended for use by those authorized to give the public\n     permission to use material in ways otherwise restricted by\n     copyright and certain other rights. Our licenses are\n     irrevocable. Licensors should read and understand the terms\n     and conditions of the license they choose before applying it.\n     Licensors should also secure all rights necessary before\n     applying our licenses so that the public can reuse the\n     material as expected. Licensors should clearly mark any\n     material not subject to the license. This includes other CC-\n     licensed material, or material used under an exception or\n     limitation to copyright. More considerations for licensors:\n\twiki.creativecommons.org/Considerations_for_licensors\n\n     Considerations for the public: By using one of our public\n     licenses, a licensor grants the public permission to use the\n     licensed material under specified terms and conditions. If\n     the licensor's permission is not necessary for any reason--for\n     example, because of any applicable exception or limitation to\n     copyright--then that use is not regulated by the license. Our\n     licenses grant only permissions under copyright and certain\n     other rights that a licensor has authority to grant. Use of\n     the licensed material may still be restricted for other\n     reasons, including because others have copyright or other\n     rights in the material. A licensor may make special requests,\n     such as asking that all changes be marked or described.\n     Although not required by our licenses, you are encouraged to\n     respect those requests where reasonable. More_considerations\n     for the public:\n\twiki.creativecommons.org/Considerations_for_licensees\n\n=======================================================================\n\nCreative Commons Attribution-ShareAlike 4.0 International Public\nLicense\n\nBy exercising the Licensed Rights (defined below), You accept and agree\nto be bound by the terms and conditions of this Creative Commons\nAttribution-ShareAlike 4.0 International Public License (\"Public\nLicense\"). To the extent this Public License may be interpreted as a\ncontract, You are granted the Licensed Rights in consideration of Your\nacceptance of these terms and conditions, and the Licensor grants You\nsuch rights in consideration of benefits the Licensor receives from\nmaking the Licensed Material available under these terms and\nconditions.\n\n\nSection 1 -- Definitions.\n\n  a. Adapted Material means material subject to Copyright and Similar\n     Rights that is derived from or based upon the Licensed Material\n     and in which the Licensed Material is translated, altered,\n     arranged, transformed, or otherwise modified in a manner requiring\n     permission under the Copyright and Similar Rights held by the\n     Licensor. For purposes of this Public License, where the Licensed\n     Material is a musical work, performance, or sound recording,\n     Adapted Material is always produced where the Licensed Material is\n     synched in timed relation with a moving image.\n\n  b. Adapter's License means the license You apply to Your Copyright\n     and Similar Rights in Your contributions to Adapted Material in\n     accordance with the terms and conditions of this Public License.\n\n  c. BY-SA Compatible License means a license listed at\n     creativecommons.org/compatiblelicenses, approved by Creative\n     Commons as essentially the equivalent of this Public License.\n\n  d. Copyright and Similar Rights means copyright and/or similar rights\n     closely related to copyright including, without limitation,\n     performance, broadcast, sound recording, and Sui Generis Database\n     Rights, without regard to how the rights are labeled or\n     categorized. For purposes of this Public License, the rights\n     specified in Section 2(b)(1)-(2) are not Copyright and Similar\n     Rights.\n\n  e. Effective Technological Measures means those measures that, in the\n     absence of proper authority, may not be circumvented under laws\n     fulfilling obligations under Article 11 of the WIPO Copyright\n     Treaty adopted on December 20, 1996, and/or similar international\n     agreements.\n\n  f. Exceptions and Limitations means fair use, fair dealing, and/or\n     any other exception or limitation to Copyright and Similar Rights\n     that applies to Your use of the Licensed Material.\n\n  g. License Elements means the license attributes listed in the name\n     of a Creative Commons Public License. The License Elements of this\n     Public License are Attribution and ShareAlike.\n\n  h. Licensed Material means the artistic or literary work, database,\n     or other material to which the Licensor applied this Public\n     License.\n\n  i. Licensed Rights means the rights granted to You subject to the\n     terms and conditions of this Public License, which are limited to\n     all Copyright and Similar Rights that apply to Your use of the\n     Licensed Material and that the Licensor has authority to license.\n\n  j. Licensor means the individual(s) or entity(ies) granting rights\n     under this Public License.\n\n  k. Share means to provide material to the public by any means or\n     process that requires permission under the Licensed Rights, such\n     as reproduction, public display, public performance, distribution,\n     dissemination, communication, or importation, and to make material\n     available to the public including in ways that members of the\n     public may access the material from a place and at a time\n     individually chosen by them.\n\n  l. Sui Generis Database Rights means rights other than copyright\n     resulting from Directive 96/9/EC of the European Parliament and of\n     the Council of 11 March 1996 on the legal protection of databases,\n     as amended and/or succeeded, as well as other essentially\n     equivalent rights anywhere in the world.\n\n  m. You means the individual or entity exercising the Licensed Rights\n     under this Public License. Your has a corresponding meaning.\n\n\nSection 2 -- Scope.\n\n  a. License grant.\n\n       1. Subject to the terms and conditions of this Public License,\n          the Licensor hereby grants You a worldwide, royalty-free,\n          non-sublicensable, non-exclusive, irrevocable license to\n          exercise the Licensed Rights in the Licensed Material to:\n\n            a. reproduce and Share the Licensed Material, in whole or\n               in part; and\n\n            b. produce, reproduce, and Share Adapted Material.\n\n       2. Exceptions and Limitations. For the avoidance of doubt, where\n          Exceptions and Limitations apply to Your use, this Public\n          License does not apply, and You do not need to comply with\n          its terms and conditions.\n\n       3. Term. The term of this Public License is specified in Section\n          6(a).\n\n       4. Media and formats; technical modifications allowed. The\n          Licensor authorizes You to exercise the Licensed Rights in\n          all media and formats whether now known or hereafter created,\n          and to make technical modifications necessary to do so. The\n          Licensor waives and/or agrees not to assert any right or\n          authority to forbid You from making technical modifications\n          necessary to exercise the Licensed Rights, including\n          technical modifications necessary to circumvent Effective\n          Technological Measures. For purposes of this Public License,\n          simply making modifications authorized by this Section 2(a)\n          (4) never produces Adapted Material.\n\n       5. Downstream recipients.\n\n            a. Offer from the Licensor -- Licensed Material. Every\n               recipient of the Licensed Material automatically\n               receives an offer from the Licensor to exercise the\n               Licensed Rights under the terms and conditions of this\n               Public License.\n\n            b. Additional offer from the Licensor -- Adapted Material.\n               Every recipient of Adapted Material from You\n               automatically receives an offer from the Licensor to\n               exercise the Licensed Rights in the Adapted Material\n               under the conditions of the Adapter's License You apply.\n\n            c. No downstream restrictions. You may not offer or impose\n               any additional or different terms or conditions on, or\n               apply any Effective Technological Measures to, the\n               Licensed Material if doing so restricts exercise of the\n               Licensed Rights by any recipient of the Licensed\n               Material.\n\n       6. No endorsement. Nothing in this Public License constitutes or\n          may be construed as permission to assert or imply that You\n          are, or that Your use of the Licensed Material is, connected\n          with, or sponsored, endorsed, or granted official status by,\n          the Licensor or others designated to receive attribution as\n          provided in Section 3(a)(1)(A)(i).\n\n  b. Other rights.\n\n       1. Moral rights, such as the right of integrity, are not\n          licensed under this Public License, nor are publicity,\n          privacy, and/or other similar personality rights; however, to\n          the extent possible, the Licensor waives and/or agrees not to\n          assert any such rights held by the Licensor to the limited\n          extent necessary to allow You to exercise the Licensed\n          Rights, but not otherwise.\n\n       2. Patent and trademark rights are not licensed under this\n          Public License.\n\n       3. To the extent possible, the Licensor waives any right to\n          collect royalties from You for the exercise of the Licensed\n          Rights, whether directly or through a collecting society\n          under any voluntary or waivable statutory or compulsory\n          licensing scheme. In all other cases the Licensor expressly\n          reserves any right to collect such royalties.\n\n\nSection 3 -- License Conditions.\n\nYour exercise of the Licensed Rights is expressly made subject to the\nfollowing conditions.\n\n  a. Attribution.\n\n       1. If You Share the Licensed Material (including in modified\n          form), You must:\n\n            a. retain the following if it is supplied by the Licensor\n               with the Licensed Material:\n\n                 i. identification of the creator(s) of the Licensed\n                    Material and any others designated to receive\n                    attribution, in any reasonable manner requested by\n                    the Licensor (including by pseudonym if\n                    designated);\n\n                ii. a copyright notice;\n\n               iii. a notice that refers to this Public License;\n\n                iv. a notice that refers to the disclaimer of\n                    warranties;\n\n                 v. a URI or hyperlink to the Licensed Material to the\n                    extent reasonably practicable;\n\n            b. indicate if You modified the Licensed Material and\n               retain an indication of any previous modifications; and\n\n            c. indicate the Licensed Material is licensed under this\n               Public License, and include the text of, or the URI or\n               hyperlink to, this Public License.\n\n       2. You may satisfy the conditions in Section 3(a)(1) in any\n          reasonable manner based on the medium, means, and context in\n          which You Share the Licensed Material. For example, it may be\n          reasonable to satisfy the conditions by providing a URI or\n          hyperlink to a resource that includes the required\n          information.\n\n       3. If requested by the Licensor, You must remove any of the\n          information required by Section 3(a)(1)(A) to the extent\n          reasonably practicable.\n\n  b. ShareAlike.\n\n     In addition to the conditions in Section 3(a), if You Share\n     Adapted Material You produce, the following conditions also apply.\n\n       1. The Adapter's License You apply must be a Creative Commons\n          license with the same License Elements, this version or\n          later, or a BY-SA Compatible License.\n\n       2. You must include the text of, or the URI or hyperlink to, the\n          Adapter's License You apply. You may satisfy this condition\n          in any reasonable manner based on the medium, means, and\n          context in which You Share Adapted Material.\n\n       3. You may not offer or impose any additional or different terms\n          or conditions on, or apply any Effective Technological\n          Measures to, Adapted Material that restrict exercise of the\n          rights granted under the Adapter's License You apply.\n\n\nSection 4 -- Sui Generis Database Rights.\n\nWhere the Licensed Rights include Sui Generis Database Rights that\napply to Your use of the Licensed Material:\n\n  a. for the avoidance of doubt, Section 2(a)(1) grants You the right\n     to extract, reuse, reproduce, and Share all or a substantial\n     portion of the contents of the database;\n\n  b. if You include all or a substantial portion of the database\n     contents in a database in which You have Sui Generis Database\n     Rights, then the database in which You have Sui Generis Database\n     Rights (but not its individual contents) is Adapted Material,\n\n     including for purposes of Section 3(b); and\n  c. You must comply with the conditions in Section 3(a) if You Share\n     all or a substantial portion of the contents of the database.\n\nFor the avoidance of doubt, this Section 4 supplements and does not\nreplace Your obligations under this Public License where the Licensed\nRights include other Copyright and Similar Rights.\n\n\nSection 5 -- Disclaimer of Warranties and Limitation of Liability.\n\n  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE\n     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS\n     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF\n     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,\n     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,\n     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR\n     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,\n     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT\n     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT\n     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.\n\n  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE\n     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,\n     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,\n     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,\n     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR\n     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN\n     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR\n     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR\n     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.\n\n  c. The disclaimer of warranties and limitation of liability provided\n     above shall be interpreted in a manner that, to the extent\n     possible, most closely approximates an absolute disclaimer and\n     waiver of all liability.\n\n\nSection 6 -- Term and Termination.\n\n  a. This Public License applies for the term of the Copyright and\n     Similar Rights licensed here. However, if You fail to comply with\n     this Public License, then Your rights under this Public License\n     terminate automatically.\n\n  b. Where Your right to use the Licensed Material has terminated under\n     Section 6(a), it reinstates:\n\n       1. automatically as of the date the violation is cured, provided\n          it is cured within 30 days of Your discovery of the\n          violation; or\n\n       2. upon express reinstatement by the Licensor.\n\n     For the avoidance of doubt, this Section 6(b) does not affect any\n     right the Licensor may have to seek remedies for Your violations\n     of this Public License.\n\n  c. For the avoidance of doubt, the Licensor may also offer the\n     Licensed Material under separate terms or conditions or stop\n     distributing the Licensed Material at any time; however, doing so\n     will not terminate this Public License.\n\n  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public\n     License.\n\n\nSection 7 -- Other Terms and Conditions.\n\n  a. The Licensor shall not be bound by any additional or different\n     terms or conditions communicated by You unless expressly agreed.\n\n  b. Any arrangements, understandings, or agreements regarding the\n     Licensed Material not stated herein are separate from and\n     independent of the terms and conditions of this Public License.\n\n\nSection 8 -- Interpretation.\n\n  a. For the avoidance of doubt, this Public License does not, and\n     shall not be interpreted to, reduce, limit, restrict, or impose\n     conditions on any use of the Licensed Material that could lawfully\n     be made without permission under this Public License.\n\n  b. To the extent possible, if any provision of this Public License is\n     deemed unenforceable, it shall be automatically reformed to the\n     minimum extent necessary to make it enforceable. If the provision\n     cannot be reformed, it shall be severed from this Public License\n     without affecting the enforceability of the remaining terms and\n     conditions.\n\n  c. No term or condition of this Public License will be waived and no\n     failure to comply consented to unless expressly agreed to by the\n     Licensor.\n\n  d. Nothing in this Public License constitutes or may be interpreted\n     as a limitation upon, or waiver of, any privileges and immunities\n     that apply to the Licensor or You, including from the legal\n     processes of any jurisdiction or authority.\n\n\n=======================================================================\n\nCreative Commons is not a party to its public licenses.\nNotwithstanding, Creative Commons may elect to apply one of its public\nlicenses to material it publishes and in those instances will be\nconsidered the \"Licensor.\" Except for the limited purpose of indicating\nthat material is shared under a Creative Commons public license or as\notherwise permitted by the Creative Commons policies published at\ncreativecommons.org/policies, Creative Commons does not authorize the\nuse of the trademark \"Creative Commons\" or any other trademark or logo\nof Creative Commons without its prior written consent including,\nwithout limitation, in connection with any unauthorized modifications\nto any of its public licenses or any other arrangements,\nunderstandings, or agreements concerning use of licensed material. For\nthe avoidance of doubt, this paragraph does not form part of the public\nlicenses.\n\nCreative Commons may be contacted at creativecommons.org.\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/MAINTAINERS",
    "content": "Derek McGowan <derek@mcgstyle.net> (@dmcgowan)\nStephen Day <stevvooe@gmail.com> (@stevvooe)\nVincent Batts <vbatts@hashbangbash.com> (@vbatts)\nAkihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> (@AkihiroSuda)\nSebastiaan van Stijn <github@gone.nl> (@thaJeztah)\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/README.md",
    "content": "# go-digest\n\n[![GoDoc](https://godoc.org/github.com/opencontainers/go-digest?status.svg)](https://godoc.org/github.com/opencontainers/go-digest) [![Go Report Card](https://goreportcard.com/badge/github.com/opencontainers/go-digest)](https://goreportcard.com/report/github.com/opencontainers/go-digest) [![Build Status](https://travis-ci.org/opencontainers/go-digest.svg?branch=master)](https://travis-ci.org/opencontainers/go-digest)\n\nCommon digest package used across the container ecosystem.\n\nPlease see the [godoc](https://godoc.org/github.com/opencontainers/go-digest) for more information.\n\n# What is a digest?\n\nA digest is just a [hash](https://en.wikipedia.org/wiki/Hash_function).\n\nThe most common use case for a digest is to create a content identifier for use in [Content Addressable Storage](https://en.wikipedia.org/wiki/Content-addressable_storage) systems:\n\n```go\nid := digest.FromBytes([]byte(\"my content\"))\n```\n\nIn the example above, the id can be used to uniquely identify the byte slice \"my content\".\nThis allows two disparate applications to agree on a verifiable identifier without having to trust one another.\n\nAn identifying digest can be verified, as follows:\n\n```go\nif id != digest.FromBytes([]byte(\"my content\")) {\n  return errors.New(\"the content has changed!\")\n}\n```\n\nA `Verifier` type can be used to handle cases where an `io.Reader` makes more sense:\n\n```go\nrd := getContent()\nverifier := id.Verifier()\nio.Copy(verifier, rd)\n\nif !verifier.Verified() {\n  return errors.New(\"the content has changed!\")\n}\n```\n\nUsing [Merkle DAGs](https://en.wikipedia.org/wiki/Merkle_tree), this can power a rich, safe, content distribution system.\n\n# Usage\n\nWhile the [godoc](https://godoc.org/github.com/opencontainers/go-digest) is considered the best resource, a few important items need to be called out when using this package.\n\n1. Make sure to import the hash implementations into your application or the package will panic.\n    You should have something like the following in the main (or other entrypoint) of your application:\n   \n    ```go\n    import (\n        _ \"crypto/sha256\"\n        _ \"crypto/sha512\"\n    )\n    ```\n    This may seem inconvenient but it allows you replace the hash \n    implementations with others, such as https://github.com/stevvooe/resumable.\n \n2. Even though `digest.Digest` may be assemblable as a string, _always_ verify your input with `digest.Parse` or use `Digest.Validate` when accepting untrusted input.\n    While there are measures to avoid common problems, this will ensure you have valid digests in the rest of your application.\n\n3. While alternative encodings of hash values (digests) are possible (for example, base64), this package deals exclusively with hex-encoded digests.\n\n# Stability\n\nThe Go API, at this stage, is considered stable, unless otherwise noted.\n\nAs always, before using a package export, read the [godoc](https://godoc.org/github.com/opencontainers/go-digest).\n\n# Contributing\n\nThis package is considered fairly complete.\nIt has been in production in thousands (millions?) of deployments and is fairly battle-hardened.\nNew additions will be met with skepticism.\nIf you think there is a missing feature, please file a bug clearly describing the problem and the alternatives you tried before submitting a PR.\n\n## Code of Conduct\n\nParticipation in the OpenContainers community is governed by [OpenContainer's Code of Conduct][code-of-conduct].\n\n## Security\n\nIf you find an issue, please follow the [security][security] protocol to report it.\n\n# Copyright and license\n\nCopyright © 2019, 2020 OCI Contributors\nCopyright © 2016 Docker, Inc.\nAll rights reserved, except as follows.\nCode is released under the [Apache 2.0 license](LICENSE).\nThis `README.md` file and the [`CONTRIBUTING.md`](CONTRIBUTING.md) file are licensed under the Creative Commons Attribution 4.0 International License under the terms and conditions set forth in the file [`LICENSE.docs`](LICENSE.docs).\nYou may obtain a duplicate copy of the same license, titled CC BY-SA 4.0, at http://creativecommons.org/licenses/by-sa/4.0/.\n\n[security]: https://github.com/opencontainers/org/blob/master/security\n[code-of-conduct]: https://github.com/opencontainers/org/blob/master/CODE_OF_CONDUCT.md\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/algorithm.go",
    "content": "// Copyright 2019, 2020 OCI Contributors\n// Copyright 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\npackage digest\n\nimport (\n\t\"crypto\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"regexp\"\n)\n\n// Algorithm identifies and implementation of a digester by an identifier.\n// Note the that this defines both the hash algorithm used and the string\n// encoding.\ntype Algorithm string\n\n// supported digest types\nconst (\n\tSHA256 Algorithm = \"sha256\" // sha256 with hex encoding (lower case only)\n\tSHA384 Algorithm = \"sha384\" // sha384 with hex encoding (lower case only)\n\tSHA512 Algorithm = \"sha512\" // sha512 with hex encoding (lower case only)\n\n\t// Canonical is the primary digest algorithm used with the distribution\n\t// project. Other digests may be used but this one is the primary storage\n\t// digest.\n\tCanonical = SHA256\n)\n\nvar (\n\t// TODO(stevvooe): Follow the pattern of the standard crypto package for\n\t// registration of digests. Effectively, we are a registerable set and\n\t// common symbol access.\n\n\t// algorithms maps values to hash.Hash implementations. Other algorithms\n\t// may be available but they cannot be calculated by the digest package.\n\talgorithms = map[Algorithm]crypto.Hash{\n\t\tSHA256: crypto.SHA256,\n\t\tSHA384: crypto.SHA384,\n\t\tSHA512: crypto.SHA512,\n\t}\n\n\t// anchoredEncodedRegexps contains anchored regular expressions for hex-encoded digests.\n\t// Note that /A-F/ disallowed.\n\tanchoredEncodedRegexps = map[Algorithm]*regexp.Regexp{\n\t\tSHA256: regexp.MustCompile(`^[a-f0-9]{64}$`),\n\t\tSHA384: regexp.MustCompile(`^[a-f0-9]{96}$`),\n\t\tSHA512: regexp.MustCompile(`^[a-f0-9]{128}$`),\n\t}\n)\n\n// Available returns true if the digest type is available for use. If this\n// returns false, Digester and Hash will return nil.\nfunc (a Algorithm) Available() bool {\n\th, ok := algorithms[a]\n\tif !ok {\n\t\treturn false\n\t}\n\n\t// check availability of the hash, as well\n\treturn h.Available()\n}\n\nfunc (a Algorithm) String() string {\n\treturn string(a)\n}\n\n// Size returns number of bytes returned by the hash.\nfunc (a Algorithm) Size() int {\n\th, ok := algorithms[a]\n\tif !ok {\n\t\treturn 0\n\t}\n\treturn h.Size()\n}\n\n// Set implemented to allow use of Algorithm as a command line flag.\nfunc (a *Algorithm) Set(value string) error {\n\tif value == \"\" {\n\t\t*a = Canonical\n\t} else {\n\t\t// just do a type conversion, support is queried with Available.\n\t\t*a = Algorithm(value)\n\t}\n\n\tif !a.Available() {\n\t\treturn ErrDigestUnsupported\n\t}\n\n\treturn nil\n}\n\n// Digester returns a new digester for the specified algorithm. If the algorithm\n// does not have a digester implementation, nil will be returned. This can be\n// checked by calling Available before calling Digester.\nfunc (a Algorithm) Digester() Digester {\n\treturn &digester{\n\t\talg:  a,\n\t\thash: a.Hash(),\n\t}\n}\n\n// Hash returns a new hash as used by the algorithm. If not available, the\n// method will panic. Check Algorithm.Available() before calling.\nfunc (a Algorithm) Hash() hash.Hash {\n\tif !a.Available() {\n\t\t// Empty algorithm string is invalid\n\t\tif a == \"\" {\n\t\t\tpanic(fmt.Sprintf(\"empty digest algorithm, validate before calling Algorithm.Hash()\"))\n\t\t}\n\n\t\t// NOTE(stevvooe): A missing hash is usually a programming error that\n\t\t// must be resolved at compile time. We don't import in the digest\n\t\t// package to allow users to choose their hash implementation (such as\n\t\t// when using stevvooe/resumable or a hardware accelerated package).\n\t\t//\n\t\t// Applications that may want to resolve the hash at runtime should\n\t\t// call Algorithm.Available before call Algorithm.Hash().\n\t\tpanic(fmt.Sprintf(\"%v not available (make sure it is imported)\", a))\n\t}\n\n\treturn algorithms[a].New()\n}\n\n// Encode encodes the raw bytes of a digest, typically from a hash.Hash, into\n// the encoded portion of the digest.\nfunc (a Algorithm) Encode(d []byte) string {\n\t// TODO(stevvooe): Currently, all algorithms use a hex encoding. When we\n\t// add support for back registration, we can modify this accordingly.\n\treturn fmt.Sprintf(\"%x\", d)\n}\n\n// FromReader returns the digest of the reader using the algorithm.\nfunc (a Algorithm) FromReader(rd io.Reader) (Digest, error) {\n\tdigester := a.Digester()\n\n\tif _, err := io.Copy(digester.Hash(), rd); err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn digester.Digest(), nil\n}\n\n// FromBytes digests the input and returns a Digest.\nfunc (a Algorithm) FromBytes(p []byte) Digest {\n\tdigester := a.Digester()\n\n\tif _, err := digester.Hash().Write(p); err != nil {\n\t\t// Writes to a Hash should never fail. None of the existing\n\t\t// hash implementations in the stdlib or hashes vendored\n\t\t// here can return errors from Write. Having a panic in this\n\t\t// condition instead of having FromBytes return an error value\n\t\t// avoids unnecessary error handling paths in all callers.\n\t\tpanic(\"write to hash function returned error: \" + err.Error())\n\t}\n\n\treturn digester.Digest()\n}\n\n// FromString digests the string input and returns a Digest.\nfunc (a Algorithm) FromString(s string) Digest {\n\treturn a.FromBytes([]byte(s))\n}\n\n// Validate validates the encoded portion string\nfunc (a Algorithm) Validate(encoded string) error {\n\tr, ok := anchoredEncodedRegexps[a]\n\tif !ok {\n\t\treturn ErrDigestUnsupported\n\t}\n\t// Digests much always be hex-encoded, ensuring that their hex portion will\n\t// always be size*2\n\tif a.Size()*2 != len(encoded) {\n\t\treturn ErrDigestInvalidLength\n\t}\n\tif r.MatchString(encoded) {\n\t\treturn nil\n\t}\n\treturn ErrDigestInvalidFormat\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/digest.go",
    "content": "// Copyright 2019, 2020 OCI Contributors\n// Copyright 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\npackage digest\n\nimport (\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// Digest allows simple protection of hex formatted digest strings, prefixed\n// by their algorithm. Strings of type Digest have some guarantee of being in\n// the correct format and it provides quick access to the components of a\n// digest string.\n//\n// The following is an example of the contents of Digest types:\n//\n// \tsha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc\n//\n// This allows to abstract the digest behind this type and work only in those\n// terms.\ntype Digest string\n\n// NewDigest returns a Digest from alg and a hash.Hash object.\nfunc NewDigest(alg Algorithm, h hash.Hash) Digest {\n\treturn NewDigestFromBytes(alg, h.Sum(nil))\n}\n\n// NewDigestFromBytes returns a new digest from the byte contents of p.\n// Typically, this can come from hash.Hash.Sum(...) or xxx.SumXXX(...)\n// functions. This is also useful for rebuilding digests from binary\n// serializations.\nfunc NewDigestFromBytes(alg Algorithm, p []byte) Digest {\n\treturn NewDigestFromEncoded(alg, alg.Encode(p))\n}\n\n// NewDigestFromHex is deprecated. Please use NewDigestFromEncoded.\nfunc NewDigestFromHex(alg, hex string) Digest {\n\treturn NewDigestFromEncoded(Algorithm(alg), hex)\n}\n\n// NewDigestFromEncoded returns a Digest from alg and the encoded digest.\nfunc NewDigestFromEncoded(alg Algorithm, encoded string) Digest {\n\treturn Digest(fmt.Sprintf(\"%s:%s\", alg, encoded))\n}\n\n// DigestRegexp matches valid digest types.\nvar DigestRegexp = regexp.MustCompile(`[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+`)\n\n// DigestRegexpAnchored matches valid digest types, anchored to the start and end of the match.\nvar DigestRegexpAnchored = regexp.MustCompile(`^` + DigestRegexp.String() + `$`)\n\nvar (\n\t// ErrDigestInvalidFormat returned when digest format invalid.\n\tErrDigestInvalidFormat = fmt.Errorf(\"invalid checksum digest format\")\n\n\t// ErrDigestInvalidLength returned when digest has invalid length.\n\tErrDigestInvalidLength = fmt.Errorf(\"invalid checksum digest length\")\n\n\t// ErrDigestUnsupported returned when the digest algorithm is unsupported.\n\tErrDigestUnsupported = fmt.Errorf(\"unsupported digest algorithm\")\n)\n\n// Parse parses s and returns the validated digest object. An error will\n// be returned if the format is invalid.\nfunc Parse(s string) (Digest, error) {\n\td := Digest(s)\n\treturn d, d.Validate()\n}\n\n// FromReader consumes the content of rd until io.EOF, returning canonical digest.\nfunc FromReader(rd io.Reader) (Digest, error) {\n\treturn Canonical.FromReader(rd)\n}\n\n// FromBytes digests the input and returns a Digest.\nfunc FromBytes(p []byte) Digest {\n\treturn Canonical.FromBytes(p)\n}\n\n// FromString digests the input and returns a Digest.\nfunc FromString(s string) Digest {\n\treturn Canonical.FromString(s)\n}\n\n// Validate checks that the contents of d is a valid digest, returning an\n// error if not.\nfunc (d Digest) Validate() error {\n\ts := string(d)\n\ti := strings.Index(s, \":\")\n\tif i <= 0 || i+1 == len(s) {\n\t\treturn ErrDigestInvalidFormat\n\t}\n\talgorithm, encoded := Algorithm(s[:i]), s[i+1:]\n\tif !algorithm.Available() {\n\t\tif !DigestRegexpAnchored.MatchString(s) {\n\t\t\treturn ErrDigestInvalidFormat\n\t\t}\n\t\treturn ErrDigestUnsupported\n\t}\n\treturn algorithm.Validate(encoded)\n}\n\n// Algorithm returns the algorithm portion of the digest. This will panic if\n// the underlying digest is not in a valid format.\nfunc (d Digest) Algorithm() Algorithm {\n\treturn Algorithm(d[:d.sepIndex()])\n}\n\n// Verifier returns a writer object that can be used to verify a stream of\n// content against the digest. If the digest is invalid, the method will panic.\nfunc (d Digest) Verifier() Verifier {\n\treturn hashVerifier{\n\t\thash:   d.Algorithm().Hash(),\n\t\tdigest: d,\n\t}\n}\n\n// Encoded returns the encoded portion of the digest. This will panic if the\n// underlying digest is not in a valid format.\nfunc (d Digest) Encoded() string {\n\treturn string(d[d.sepIndex()+1:])\n}\n\n// Hex is deprecated. Please use Digest.Encoded.\nfunc (d Digest) Hex() string {\n\treturn d.Encoded()\n}\n\nfunc (d Digest) String() string {\n\treturn string(d)\n}\n\nfunc (d Digest) sepIndex() int {\n\ti := strings.Index(string(d), \":\")\n\n\tif i < 0 {\n\t\tpanic(fmt.Sprintf(\"no ':' separator in digest %q\", d))\n\t}\n\n\treturn i\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/digester.go",
    "content": "// Copyright 2019, 2020 OCI Contributors\n// Copyright 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\npackage digest\n\nimport \"hash\"\n\n// Digester calculates the digest of written data. Writes should go directly\n// to the return value of Hash, while calling Digest will return the current\n// value of the digest.\ntype Digester interface {\n\tHash() hash.Hash // provides direct access to underlying hash instance.\n\tDigest() Digest\n}\n\n// digester provides a simple digester definition that embeds a hasher.\ntype digester struct {\n\talg  Algorithm\n\thash hash.Hash\n}\n\nfunc (d *digester) Hash() hash.Hash {\n\treturn d.hash\n}\n\nfunc (d *digester) Digest() Digest {\n\treturn NewDigest(d.alg, d.hash)\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/doc.go",
    "content": "// Copyright 2019, 2020 OCI Contributors\n// Copyright 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\n// Package digest provides a generalized type to opaquely represent message\n// digests and their operations within the registry. The Digest type is\n// designed to serve as a flexible identifier in a content-addressable system.\n// More importantly, it provides tools and wrappers to work with\n// hash.Hash-based digests with little effort.\n//\n// Basics\n//\n// The format of a digest is simply a string with two parts, dubbed the\n// \"algorithm\" and the \"digest\", separated by a colon:\n//\n// \t<algorithm>:<digest>\n//\n// An example of a sha256 digest representation follows:\n//\n// \tsha256:7173b809ca12ec5dee4506cd86be934c4596dd234ee82c0662eac04a8c2c71dc\n//\n// The \"algorithm\" portion defines both the hashing algorithm used to calculate\n// the digest and the encoding of the resulting digest, which defaults to \"hex\"\n// if not otherwise specified. Currently, all supported algorithms have their\n// digests encoded in hex strings.\n//\n// In the example above, the string \"sha256\" is the algorithm and the hex bytes\n// are the \"digest\".\n//\n// Because the Digest type is simply a string, once a valid Digest is\n// obtained, comparisons are cheap, quick and simple to express with the\n// standard equality operator.\n//\n// Verification\n//\n// The main benefit of using the Digest type is simple verification against a\n// given digest. The Verifier interface, modeled after the stdlib hash.Hash\n// interface, provides a common write sink for digest verification. After\n// writing is complete, calling the Verifier.Verified method will indicate\n// whether or not the stream of bytes matches the target digest.\n//\n// Missing Features\n//\n// In addition to the above, we intend to add the following features to this\n// package:\n//\n// 1. A Digester type that supports write sink digest calculation.\n//\n// 2. Suspend and resume of ongoing digest calculations to support efficient digest verification in the registry.\n//\npackage digest\n"
  },
  {
    "path": "vendor/github.com/opencontainers/go-digest/verifiers.go",
    "content": "// Copyright 2019, 2020 OCI Contributors\n// Copyright 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\npackage digest\n\nimport (\n\t\"hash\"\n\t\"io\"\n)\n\n// Verifier presents a general verification interface to be used with message\n// digests and other byte stream verifications. Users instantiate a Verifier\n// from one of the various methods, write the data under test to it then check\n// the result with the Verified method.\ntype Verifier interface {\n\tio.Writer\n\n\t// Verified will return true if the content written to Verifier matches\n\t// the digest.\n\tVerified() bool\n}\n\ntype hashVerifier struct {\n\tdigest Digest\n\thash   hash.Hash\n}\n\nfunc (hv hashVerifier) Write(p []byte) (n int, err error) {\n\treturn hv.hash.Write(p)\n}\n\nfunc (hv hashVerifier) Verified() bool {\n\treturn hv.digest == NewDigest(hv.digest.Algorithm(), hv.hash)\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://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 2016 The Linux Foundation.\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       http://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": "vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go",
    "content": "// Copyright 2016 The Linux Foundation\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//     http://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\npackage v1\n\nconst (\n\t// AnnotationCreated is the annotation key for the date and time on which the image was built (date-time string as defined by RFC 3339).\n\tAnnotationCreated = \"org.opencontainers.image.created\"\n\n\t// AnnotationAuthors is the annotation key for the contact details of the people or organization responsible for the image (freeform string).\n\tAnnotationAuthors = \"org.opencontainers.image.authors\"\n\n\t// AnnotationURL is the annotation key for the URL to find more information on the image.\n\tAnnotationURL = \"org.opencontainers.image.url\"\n\n\t// AnnotationDocumentation is the annotation key for the URL to get documentation on the image.\n\tAnnotationDocumentation = \"org.opencontainers.image.documentation\"\n\n\t// AnnotationSource is the annotation key for the URL to get source code for building the image.\n\tAnnotationSource = \"org.opencontainers.image.source\"\n\n\t// AnnotationVersion is the annotation key for the version of the packaged software.\n\t// The version MAY match a label or tag in the source code repository.\n\t// The version MAY be Semantic versioning-compatible.\n\tAnnotationVersion = \"org.opencontainers.image.version\"\n\n\t// AnnotationRevision is the annotation key for the source control revision identifier for the packaged software.\n\tAnnotationRevision = \"org.opencontainers.image.revision\"\n\n\t// AnnotationVendor is the annotation key for the name of the distributing entity, organization or individual.\n\tAnnotationVendor = \"org.opencontainers.image.vendor\"\n\n\t// AnnotationLicenses is the annotation key for the license(s) under which contained software is distributed as an SPDX License Expression.\n\tAnnotationLicenses = \"org.opencontainers.image.licenses\"\n\n\t// AnnotationRefName is the annotation key for the name of the reference for a target.\n\t// SHOULD only be considered valid when on descriptors on `index.json` within image layout.\n\tAnnotationRefName = \"org.opencontainers.image.ref.name\"\n\n\t// AnnotationTitle is the annotation key for the human-readable title of the image.\n\tAnnotationTitle = \"org.opencontainers.image.title\"\n\n\t// AnnotationDescription is the annotation key for the human-readable description of the software packaged in the image.\n\tAnnotationDescription = \"org.opencontainers.image.description\"\n\n\t// AnnotationBaseImageDigest is the annotation key for the digest of the image's base image.\n\tAnnotationBaseImageDigest = \"org.opencontainers.image.base.digest\"\n\n\t// AnnotationBaseImageName is the annotation key for the image reference of the image's base image.\n\tAnnotationBaseImageName = \"org.opencontainers.image.base.name\"\n)\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go",
    "content": "// Copyright 2016 The Linux Foundation\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//     http://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\npackage v1\n\nimport (\n\t\"time\"\n\n\tdigest \"github.com/opencontainers/go-digest\"\n)\n\n// ImageConfig defines the execution parameters which should be used as a base when running a container using an image.\ntype ImageConfig struct {\n\t// User defines the username or UID which the process in the container should run as.\n\tUser string `json:\"User,omitempty\"`\n\n\t// ExposedPorts a set of ports to expose from a container running this image.\n\tExposedPorts map[string]struct{} `json:\"ExposedPorts,omitempty\"`\n\n\t// Env is a list of environment variables to be used in a container.\n\tEnv []string `json:\"Env,omitempty\"`\n\n\t// Entrypoint defines a list of arguments to use as the command to execute when the container starts.\n\tEntrypoint []string `json:\"Entrypoint,omitempty\"`\n\n\t// Cmd defines the default arguments to the entrypoint of the container.\n\tCmd []string `json:\"Cmd,omitempty\"`\n\n\t// Volumes is a set of directories describing where the process is likely write data specific to a container instance.\n\tVolumes map[string]struct{} `json:\"Volumes,omitempty\"`\n\n\t// WorkingDir sets the current working directory of the entrypoint process in the container.\n\tWorkingDir string `json:\"WorkingDir,omitempty\"`\n\n\t// Labels contains arbitrary metadata for the container.\n\tLabels map[string]string `json:\"Labels,omitempty\"`\n\n\t// StopSignal contains the system call signal that will be sent to the container to exit.\n\tStopSignal string `json:\"StopSignal,omitempty\"`\n\n\t// ArgsEscaped\n\t//\n\t// Deprecated: This field is present only for legacy compatibility with\n\t// Docker and should not be used by new image builders.  It is used by Docker\n\t// for Windows images to indicate that the `Entrypoint` or `Cmd` or both,\n\t// contains only a single element array, that is a pre-escaped, and combined\n\t// into a single string `CommandLine`. If `true` the value in `Entrypoint` or\n\t// `Cmd` should be used as-is to avoid double escaping.\n\t// https://github.com/opencontainers/image-spec/pull/892\n\tArgsEscaped bool `json:\"ArgsEscaped,omitempty\"`\n}\n\n// RootFS describes a layer content addresses\ntype RootFS struct {\n\t// Type is the type of the rootfs.\n\tType string `json:\"type\"`\n\n\t// DiffIDs is an array of layer content hashes (DiffIDs), in order from bottom-most to top-most.\n\tDiffIDs []digest.Digest `json:\"diff_ids\"`\n}\n\n// History describes the history of a layer.\ntype History struct {\n\t// Created is the combined date and time at which the layer was created, formatted as defined by RFC 3339, section 5.6.\n\tCreated *time.Time `json:\"created,omitempty\"`\n\n\t// CreatedBy is the command which created the layer.\n\tCreatedBy string `json:\"created_by,omitempty\"`\n\n\t// Author is the author of the build point.\n\tAuthor string `json:\"author,omitempty\"`\n\n\t// Comment is a custom message set when creating the layer.\n\tComment string `json:\"comment,omitempty\"`\n\n\t// EmptyLayer is used to mark if the history item created a filesystem diff.\n\tEmptyLayer bool `json:\"empty_layer,omitempty\"`\n}\n\n// Image is the JSON structure which describes some basic information about the image.\n// This provides the `application/vnd.oci.image.config.v1+json` mediatype when marshalled to JSON.\ntype Image struct {\n\t// Created is the combined date and time at which the image was created, formatted as defined by RFC 3339, section 5.6.\n\tCreated *time.Time `json:\"created,omitempty\"`\n\n\t// Author defines the name and/or email address of the person or entity which created and is responsible for maintaining the image.\n\tAuthor string `json:\"author,omitempty\"`\n\n\t// Platform describes the platform which the image in the manifest runs on.\n\tPlatform\n\n\t// Config defines the execution parameters which should be used as a base when running a container using the image.\n\tConfig ImageConfig `json:\"config,omitempty\"`\n\n\t// RootFS references the layer content addresses used by the image.\n\tRootFS RootFS `json:\"rootfs\"`\n\n\t// History describes the history of each layer.\n\tHistory []History `json:\"history,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go",
    "content": "// Copyright 2016-2022 The Linux Foundation\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//     http://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\npackage v1\n\nimport digest \"github.com/opencontainers/go-digest\"\n\n// Descriptor describes the disposition of targeted content.\n// This structure provides `application/vnd.oci.descriptor.v1+json` mediatype\n// when marshalled to JSON.\ntype Descriptor struct {\n\t// MediaType is the media type of the object this schema refers to.\n\tMediaType string `json:\"mediaType\"`\n\n\t// Digest is the digest of the targeted content.\n\tDigest digest.Digest `json:\"digest\"`\n\n\t// Size specifies the size in bytes of the blob.\n\tSize int64 `json:\"size\"`\n\n\t// URLs specifies a list of URLs from which this object MAY be downloaded\n\tURLs []string `json:\"urls,omitempty\"`\n\n\t// Annotations contains arbitrary metadata relating to the targeted content.\n\tAnnotations map[string]string `json:\"annotations,omitempty\"`\n\n\t// Data is an embedding of the targeted content. This is encoded as a base64\n\t// string when marshalled to JSON (automatically, by encoding/json). If\n\t// present, Data can be used directly to avoid fetching the targeted content.\n\tData []byte `json:\"data,omitempty\"`\n\n\t// Platform describes the platform which the image in the manifest runs on.\n\t//\n\t// This should only be used when referring to a manifest.\n\tPlatform *Platform `json:\"platform,omitempty\"`\n\n\t// ArtifactType is the IANA media type of this artifact.\n\tArtifactType string `json:\"artifactType,omitempty\"`\n}\n\n// Platform describes the platform which the image in the manifest runs on.\ntype Platform struct {\n\t// Architecture field specifies the CPU architecture, for example\n\t// `amd64` or `ppc64le`.\n\tArchitecture string `json:\"architecture\"`\n\n\t// OS specifies the operating system, for example `linux` or `windows`.\n\tOS string `json:\"os\"`\n\n\t// OSVersion is an optional field specifying the operating system\n\t// version, for example on Windows `10.0.14393.1066`.\n\tOSVersion string `json:\"os.version,omitempty\"`\n\n\t// OSFeatures is an optional field specifying an array of strings,\n\t// each listing a required OS feature (for example on Windows `win32k`).\n\tOSFeatures []string `json:\"os.features,omitempty\"`\n\n\t// Variant is an optional field specifying a variant of the CPU, for\n\t// example `v7` to specify ARMv7 when architecture is `arm`.\n\tVariant string `json:\"variant,omitempty\"`\n}\n\n// DescriptorEmptyJSON is the descriptor of a blob with content of `{}`.\nvar DescriptorEmptyJSON = Descriptor{\n\tMediaType: MediaTypeEmptyJSON,\n\tDigest:    `sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a`,\n\tSize:      2,\n\tData:      []byte(`{}`),\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go",
    "content": "// Copyright 2016 The Linux Foundation\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//     http://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\npackage v1\n\nimport \"github.com/opencontainers/image-spec/specs-go\"\n\n// Index references manifests for various platforms.\n// This structure provides `application/vnd.oci.image.index.v1+json` mediatype when marshalled to JSON.\ntype Index struct {\n\tspecs.Versioned\n\n\t// MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.index.v1+json`\n\tMediaType string `json:\"mediaType,omitempty\"`\n\n\t// ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact.\n\tArtifactType string `json:\"artifactType,omitempty\"`\n\n\t// Manifests references platform specific manifests.\n\tManifests []Descriptor `json:\"manifests\"`\n\n\t// Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest.\n\tSubject *Descriptor `json:\"subject,omitempty\"`\n\n\t// Annotations contains arbitrary metadata for the image index.\n\tAnnotations map[string]string `json:\"annotations,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go",
    "content": "// Copyright 2016 The Linux Foundation\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//     http://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\npackage v1\n\nconst (\n\t// ImageLayoutFile is the file name containing ImageLayout in an OCI Image Layout\n\tImageLayoutFile = \"oci-layout\"\n\t// ImageLayoutVersion is the version of ImageLayout\n\tImageLayoutVersion = \"1.0.0\"\n\t// ImageIndexFile is the file name of the entry point for references and descriptors in an OCI Image Layout\n\tImageIndexFile = \"index.json\"\n\t// ImageBlobsDir is the directory name containing content addressable blobs in an OCI Image Layout\n\tImageBlobsDir = \"blobs\"\n)\n\n// ImageLayout is the structure in the \"oci-layout\" file, found in the root\n// of an OCI Image-layout directory.\ntype ImageLayout struct {\n\tVersion string `json:\"imageLayoutVersion\"`\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go",
    "content": "// Copyright 2016-2022 The Linux Foundation\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//     http://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\npackage v1\n\nimport \"github.com/opencontainers/image-spec/specs-go\"\n\n// Manifest provides `application/vnd.oci.image.manifest.v1+json` mediatype structure when marshalled to JSON.\ntype Manifest struct {\n\tspecs.Versioned\n\n\t// MediaType specifies the type of this document data structure e.g. `application/vnd.oci.image.manifest.v1+json`\n\tMediaType string `json:\"mediaType,omitempty\"`\n\n\t// ArtifactType specifies the IANA media type of artifact when the manifest is used for an artifact.\n\tArtifactType string `json:\"artifactType,omitempty\"`\n\n\t// Config references a configuration object for a container, by digest.\n\t// The referenced configuration object is a JSON blob that the runtime uses to set up the container.\n\tConfig Descriptor `json:\"config\"`\n\n\t// Layers is an indexed list of layers referenced by the manifest.\n\tLayers []Descriptor `json:\"layers\"`\n\n\t// Subject is an optional link from the image manifest to another manifest forming an association between the image manifest and the other manifest.\n\tSubject *Descriptor `json:\"subject,omitempty\"`\n\n\t// Annotations contains arbitrary metadata for the image manifest.\n\tAnnotations map[string]string `json:\"annotations,omitempty\"`\n}\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go",
    "content": "// Copyright 2016 The Linux Foundation\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//     http://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\npackage v1\n\nconst (\n\t// MediaTypeDescriptor specifies the media type for a content descriptor.\n\tMediaTypeDescriptor = \"application/vnd.oci.descriptor.v1+json\"\n\n\t// MediaTypeLayoutHeader specifies the media type for the oci-layout.\n\tMediaTypeLayoutHeader = \"application/vnd.oci.layout.header.v1+json\"\n\n\t// MediaTypeImageManifest specifies the media type for an image manifest.\n\tMediaTypeImageManifest = \"application/vnd.oci.image.manifest.v1+json\"\n\n\t// MediaTypeImageIndex specifies the media type for an image index.\n\tMediaTypeImageIndex = \"application/vnd.oci.image.index.v1+json\"\n\n\t// MediaTypeImageLayer is the media type used for layers referenced by the manifest.\n\tMediaTypeImageLayer = \"application/vnd.oci.image.layer.v1.tar\"\n\n\t// MediaTypeImageLayerGzip is the media type used for gzipped layers\n\t// referenced by the manifest.\n\tMediaTypeImageLayerGzip = \"application/vnd.oci.image.layer.v1.tar+gzip\"\n\n\t// MediaTypeImageLayerZstd is the media type used for zstd compressed\n\t// layers referenced by the manifest.\n\tMediaTypeImageLayerZstd = \"application/vnd.oci.image.layer.v1.tar+zstd\"\n\n\t// MediaTypeImageLayerNonDistributable is the media type for layers referenced by\n\t// the manifest but with distribution restrictions.\n\t//\n\t// Deprecated: Non-distributable layers are deprecated, and not recommended\n\t// for future use. Implementations SHOULD NOT produce new non-distributable\n\t// layers.\n\t// https://github.com/opencontainers/image-spec/pull/965\n\tMediaTypeImageLayerNonDistributable = \"application/vnd.oci.image.layer.nondistributable.v1.tar\"\n\n\t// MediaTypeImageLayerNonDistributableGzip is the media type for\n\t// gzipped layers referenced by the manifest but with distribution\n\t// restrictions.\n\t//\n\t// Deprecated: Non-distributable layers are deprecated, and not recommended\n\t// for future use. Implementations SHOULD NOT produce new non-distributable\n\t// layers.\n\t// https://github.com/opencontainers/image-spec/pull/965\n\tMediaTypeImageLayerNonDistributableGzip = \"application/vnd.oci.image.layer.nondistributable.v1.tar+gzip\"\n\n\t// MediaTypeImageLayerNonDistributableZstd is the media type for zstd\n\t// compressed layers referenced by the manifest but with distribution\n\t// restrictions.\n\t//\n\t// Deprecated: Non-distributable layers are deprecated, and not recommended\n\t// for future use. Implementations SHOULD NOT produce new non-distributable\n\t// layers.\n\t// https://github.com/opencontainers/image-spec/pull/965\n\tMediaTypeImageLayerNonDistributableZstd = \"application/vnd.oci.image.layer.nondistributable.v1.tar+zstd\"\n\n\t// MediaTypeImageConfig specifies the media type for the image configuration.\n\tMediaTypeImageConfig = \"application/vnd.oci.image.config.v1+json\"\n\n\t// MediaTypeEmptyJSON specifies the media type for an unused blob containing the value `{}`\n\tMediaTypeEmptyJSON = \"application/vnd.oci.empty.v1+json\"\n)\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/version.go",
    "content": "// Copyright 2016 The Linux Foundation\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//     http://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\npackage specs\n\nimport \"fmt\"\n\nconst (\n\t// VersionMajor is for an API incompatible changes\n\tVersionMajor = 1\n\t// VersionMinor is for functionality in a backwards-compatible manner\n\tVersionMinor = 1\n\t// VersionPatch is for backwards-compatible bug fixes\n\tVersionPatch = 0\n\n\t// VersionDev indicates development branch. Releases will be empty string.\n\tVersionDev = \"-rc.5\"\n)\n\n// Version is the specification version that the package types support.\nvar Version = fmt.Sprintf(\"%d.%d.%d%s\", VersionMajor, VersionMinor, VersionPatch, VersionDev)\n"
  },
  {
    "path": "vendor/github.com/opencontainers/image-spec/specs-go/versioned.go",
    "content": "// Copyright 2016 The Linux Foundation\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//     http://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\npackage specs\n\n// Versioned provides a struct with the manifest schemaVersion and mediaType.\n// Incoming content with unknown schema version can be decoded against this\n// struct to check the version.\ntype Versioned struct {\n\t// SchemaVersion is the image manifest schema that this image follows\n\tSchemaVersion int `json:\"schemaVersion\"`\n}\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/.gitignore",
    "content": "/.idea\n\ncoverage.out\nprofile.out\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [[1.1.5](https://github.com/PerimeterX/marshmallow/compare/v1.1.4...v1.1.5)] - 2023-07-03\n\n### Added\n\n- Support for reporting errors from `HandleJSONData` - [info](https://github.com/PerimeterX/marshmallow/issues/27).\n\n## [[1.1.4](https://github.com/PerimeterX/marshmallow/compare/v1.1.3...v1.1.4)] - 2022-11-10\n\n### Fixed\n\n- Fixed problem with nested object implementing JSONDataHandler with skipPopulateStruct - [info](https://github.com/PerimeterX/marshmallow/issues/18).\n- Fixed problem with nested object implementing JSONDataHandler with skipPopulateStruct in ModeFailOverToOriginalValue - [info](https://github.com/PerimeterX/marshmallow/issues/19).\n\n## [[1.1.3](https://github.com/PerimeterX/marshmallow/compare/v1.1.2...v1.1.3)] - 2022-08-31\n\n### Added\n\n- Support for excluding known fields from the result map - [info](https://github.com/PerimeterX/marshmallow/issues/16).\n\n## [[1.1.2](https://github.com/PerimeterX/marshmallow/compare/v1.1.1...v1.1.2)] - 2022-08-23\n\n### Added\n\n- Support capturing nested unknown fields - [info](https://github.com/PerimeterX/marshmallow/issues/15).\n\n## [[1.1.1](https://github.com/PerimeterX/marshmallow/compare/v1.1.0...v1.1.1)] - 2022-08-21\n\n### Fixed\n\n- Fix parsing bug for unknown nested fields - [info](https://github.com/PerimeterX/marshmallow/issues/12).\n\n## [[1.1.0](https://github.com/PerimeterX/marshmallow/compare/v0.0.1...v1.1.0)] - 2022-07-10\n\n### Fixed\n\n- Fixed an issue with embedded fields - [info](https://github.com/PerimeterX/marshmallow/issues/9).\n\n## [[0.0.1](https://github.com/PerimeterX/marshmallow/tree/v0.0.1)] - 2022-04-21\n\n### Added\n\n- All functionality from our internal repository, after it has been stabilized on production for several months - [info](https://www.perimeterx.com/tech-blog/2022/boosting-up-json-performance-of-unstructured-structs-in-go/).\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/CODE_OF_CONDUCT.md",
    "content": "\n# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participation in our\ncommunity a harassment-free experience for everyone, regardless of age, body\nsize, visible or invisible disability, ethnicity, sex characteristics, gender\nidentity and expression, level of experience, education, socio-economic status,\nnationality, personal appearance, race, caste, color, religion, or sexual\nidentity and orientation.\n\nWe pledge to act and interact in ways that contribute to an open, welcoming,\ndiverse, inclusive, and healthy community.\n\n## Our Standards\n\nExamples of behavior that contributes to a positive environment for our\ncommunity include:\n\n* Demonstrating empathy and kindness toward other people\n* Being respectful of differing opinions, viewpoints, and experiences\n* Giving and gracefully accepting constructive feedback\n* Accepting responsibility and apologizing to those affected by our mistakes,\n  and learning from the experience\n* Focusing on what is best not just for us as individuals, but for the overall\n  community\n\nExamples of unacceptable behavior include:\n\n* The use of sexualized language or imagery, and sexual attention or advances of\n  any kind\n* Trolling, insulting or derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or email address,\n  without their explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Enforcement Responsibilities\n\nCommunity leaders are responsible for clarifying and enforcing our standards of\nacceptable behavior and will take appropriate and fair corrective action in\nresponse to any behavior that they deem inappropriate, threatening, offensive,\nor harmful.\n\nCommunity leaders have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, and will communicate reasons for moderation\ndecisions when appropriate.\n\n## Scope\n\nThis Code of Conduct applies within all community spaces, and also applies when\nan individual is officially representing the community in public spaces.\nExamples of representing our community include using an official e-mail address,\nposting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported to the community leaders responsible for enforcement at\n[opensource-conduct@humansecurity.com](mailto:opensource-conduct@humansecurity.com).\nAll complaints will be reviewed and investigated promptly and fairly.\n\nAll community leaders are obligated to respect the privacy and security of the\nreporter of any incident.\n\n## Enforcement Guidelines\n\nCommunity leaders will follow these Community Impact Guidelines in determining\nthe consequences for any action they deem in violation of this Code of Conduct:\n\n### 1. Correction\n\n**Community Impact**: Use of inappropriate language or other behavior deemed\nunprofessional or unwelcome in the community.\n\n**Consequence**: A private, written warning from community leaders, providing\nclarity around the nature of the violation and an explanation of why the\nbehavior was inappropriate. A public apology may be requested.\n\n### 2. Warning\n\n**Community Impact**: A violation through a single incident or series of\nactions.\n\n**Consequence**: A warning with consequences for continued behavior. No\ninteraction with the people involved, including unsolicited interaction with\nthose enforcing the Code of Conduct, for a specified period of time. This\nincludes avoiding interactions in community spaces as well as external channels\nlike social media. Violating these terms may lead to a temporary or permanent\nban.\n\n### 3. Temporary Ban\n\n**Community Impact**: A serious violation of community standards, including\nsustained inappropriate behavior.\n\n**Consequence**: A temporary ban from any sort of interaction or public\ncommunication with the community for a specified period of time. No public or\nprivate interaction with the people involved, including unsolicited interaction\nwith those enforcing the Code of Conduct, is allowed during this period.\nViolating these terms may lead to a permanent ban.\n\n### 4. Permanent Ban\n\n**Community Impact**: Demonstrating a pattern of violation of community\nstandards, including sustained inappropriate behavior, harassment of an\nindividual, or aggression toward or disparagement of classes of individuals.\n\n**Consequence**: A permanent ban from any sort of public interaction within the\ncommunity.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 2.1, available at\n[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].\n\nCommunity Impact Guidelines were inspired by\n[Mozilla's code of conduct enforcement ladder][Mozilla CoC].\n\nFor answers to common questions about this code of conduct, see the FAQ at\n[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at\n[https://www.contributor-covenant.org/translations][translations].\n\n[homepage]: https://www.contributor-covenant.org\n[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html\n[Mozilla CoC]: https://github.com/mozilla/diversity\n[FAQ]: https://www.contributor-covenant.org/faq\n[translations]: https://www.contributor-covenant.org/translations\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/CONTRIBUTING.md",
    "content": "# How To Contribute\n\nWe'd love to accept your patches and contributions to this project. There are just a few guidelines you need to follow which are described in detail below.\n\n## 1. Fork this repo\n\nYou should create a fork of this project in your account and work from there. You can create a fork by clicking the fork button in GitHub.\n\n## 2. One feature, one branch\n\nWork for each new feature/issue should occur in its own branch. To create a new branch from the command line:\n```shell\ngit checkout -b my-new-feature\n```\nwhere \"my-new-feature\" describes what you're working on.\n\n## 3. Add unit tests\nIf your contribution modifies existing or adds new code please add corresponding unit tests for this.\n\n## 4. Ensure that the build passes\n\nRun\n```shell\ngo test -v\n```\nand check that there are no errors.\n\n## 5. Add documentation for new or updated functionality\n\nPlease review the [README.md](README.md) file in this project to see if they are impacted by your change and update them accordingly.\n\n## 6. Add to CHANGELOG.md\n\nAny notable changes should be recorded in the CHANGELOG.md following the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) conventions.\n\n## 7. Submit a pull request and describe the change\n\nPush your changes to your branch and open a pull request against the parent repo on GitHub. The project administrators will review your pull request and respond with feedback.\n\n# How your contribution gets merged\n\nUpon pull request submission, your code will be reviewed by the maintainers. They will confirm at least the following:\n\n- Tests run successfully (unit, coverage, style).\n- Contribution policy has been followed.\n\nA (human) reviewer will need to sign off on your pull request before it can be merged.\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2022 PerimeterX\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": "vendor/github.com/perimeterx/marshmallow/README.md",
    "content": "# Marshmallow\n\n![Marshmallow Campfire](https://raw.githubusercontent.com/PerimeterX/marshmallow/assets/campfire.png)\n\n[![CodeQL Status](https://img.shields.io/github/actions/workflow/status/perimeterx/marshmallow/codeql.yml?branch=main&logo=github&label=CodeQL)](https://github.com/PerimeterX/marshmallow/actions/workflows/codeql.yml?query=branch%3Amain++)\n[![Run Tests](https://img.shields.io/github/actions/workflow/status/perimeterx/marshmallow/go.yml?branch=main&logo=github&label=Run%20Tests)](https://github.com/PerimeterX/marshmallow/actions/workflows/go.yml?query=branch%3Amain)\n[![Dependency Review](https://img.shields.io/github/actions/workflow/status/perimeterx/marshmallow/dependency-review.yml?logo=github&label=Dependency%20Review)](https://github.com/PerimeterX/marshmallow/actions/workflows/dependency-review.yml?query=branch%3Amain)\n[![Go Report Card](https://goreportcard.com/badge/github.com/perimeterx/marshmallow)](https://goreportcard.com/report/github.com/perimeterx/marshmallow)\n![Manual Code Coverage](https://img.shields.io/badge/coverage-92.6%25-green)\n[![Go Reference](https://pkg.go.dev/badge/github.com/perimeterx/marshmallow.svg)](https://pkg.go.dev/github.com/perimeterx/marshmallow)\n[![Licence](https://img.shields.io/github/license/perimeterx/marshmallow)](LICENSE)\n[![Latest Release](https://img.shields.io/github/v/release/perimeterx/marshmallow)](https://github.com/PerimeterX/marshmallow/releases)\n![Top Languages](https://img.shields.io/github/languages/top/perimeterx/marshmallow)\n[![Issues](https://img.shields.io/github/issues-closed/perimeterx/marshmallow?color=%238250df&logo=github)](https://github.com/PerimeterX/marshmallow/issues)\n[![Pull Requests](https://img.shields.io/github/issues-pr-closed-raw/perimeterx/marshmallow?color=%238250df&label=merged%20pull%20requests&logo=github)](https://github.com/PerimeterX/marshmallow/pulls)\n[![Commits](https://img.shields.io/github/last-commit/perimeterx/marshmallow)](https://github.com/PerimeterX/marshmallow/commits/main)\n[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)\n\n<img align=\"right\" width=\"200\" alt=\"marshmallow-gopher\" src=\"https://raw.githubusercontent.com/PerimeterX/marshmallow/assets/sticker7.png\">\n\nMarshmallow package provides a simple API to perform flexible and performant JSON unmarshalling in Go.\n\nMarshmallow specializes in dealing with **unstructured struct** - when some fields are known and some aren't,\nwith zero performance overhead nor extra coding needed.\nWhile unmarshalling, marshmallow allows fully retaining the original data and access\nit via a typed struct and a dynamic map.\n\n## Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [Performance Benchmark And Alternatives](#performance-benchmark-and-alternatives)\n- [When Should I Use Marshmallow](#when-should-i-use-marshmallow)\n- [API](#api)\n\n## Install\n\n```sh\ngo get -u github.com/perimeterx/marshmallow\n```\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/perimeterx/marshmallow\"\n)\n\nfunc main() {\n\tv := struct {\n\t\tFoo string `json:\"foo\"`\n\t\tBoo []int  `json:\"boo\"`\n\t}{}\n\tresult, err := marshmallow.Unmarshal([]byte(`{\"foo\":\"bar\",\"boo\":[1,2,3],\"goo\":12.6}`), &v)\n\tfmt.Printf(\"v=%+v, result=%+v, err=%v\", v, result, err)\n\t// Output: v={Foo:bar Boo:[1 2 3]}, result=map[boo:[1 2 3] foo:bar goo:12.6], err=<nil>\n}\n```\n\n**Examples can be found [here](example_test.go)**\n\n## Performance Benchmark And Alternatives\n\nMarshmallow performs best when dealing with mixed data - when some fields are known and some are unknown.\nMore info [below](#when-should-i-use-marshmallow).\nOther solutions are available for this kind of use case, each solution is explained and documented in the link below.\nThe full benchmark test can be found\n[here](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go).\n\n|Benchmark|Iterations|Time/Iteration|Bytes Allocated|Allocations|\n|--|--|--|--|--|\n|[unmarshall twice](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L40)|228693|5164 ns/op|1640 B/op|51 allocs/op|\n|[raw map](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L66)|232236|5116 ns/op|2296 B/op|53 allocs/op|\n|[go codec](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L121)|388442|3077 ns/op|2512 B/op|37 allocs/op|\n|[marshmallow](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L16)|626168|1853 ns/op|608 B/op|18 allocs/op|\n|[marshmallow without populating struct](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L162)|678616|1751 ns/op|608 B/op|18 allocs/op|\n\n![marshmallow performance comparison](https://raw.githubusercontent.com/PerimeterX/marshmallow/e45088ca20d4ea5be4143d418d12da63a68d6dfd/performance-chart.svg)\n\n**Marshmallow provides the best performance (up to X3 faster) while not requiring any extra coding.**\nIn fact, marshmallow performs as fast as normal `json.Unmarshal` call, however, such a call causes loss of data for all\nthe fields that did not match the given struct. With marshmallow you never lose any data.\n\n|Benchmark|Iterations|Time/Iteration|Bytes Allocated|Allocations|\n|--|--|--|--|--|\n|[marshmallow](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L16)|626168|1853 ns/op|608 B/op|18 allocs/op|\n|[native library](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L143)|652106|1845 ns/op|304 B/op|11 allocs/op|\n|[marshmallow without populating struct](https://github.com/PerimeterX/marshmallow/blob/8c5bba9e6dc0033f4324eca554737089a99f6e5e/benchmark_test.go#L162)|678616|1751 ns/op|608 B/op|18 allocs/op|\n\n## When Should I Use Marshmallow\n\nMarshmallow is best suited for use cases where you are interested in all the input data, but you have predetermined\ninformation only about a subset of it. For instance, if you plan to reference two specific fields from the data, then\niterate all the data and apply some generic logic. How does it look with the native library:\n\n```go\nfunc isAllowedToDrive(data []byte) (bool, error) {\n\tresult := make(map[string]interface{})\n\terr := json.Unmarshal(data, &result)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tage, ok := result[\"age\"]\n\tif !ok {\n\t\treturn false, nil\n\t}\n\ta, ok := age.(float64)\n\tif !ok {\n\t\treturn false, nil\n\t}\n\tif a < 17 {\n\t\treturn false, nil\n\t}\n\n\thasDriversLicense, ok := result[\"has_drivers_license\"]\n\tif !ok {\n\t\treturn false, nil\n\t}\n\th, ok := hasDriversLicense.(bool)\n\tif !ok {\n\t\treturn false, nil\n\t}\n\tif !h {\n\t\treturn false, nil\n\t}\n\n\tfor key := range result {\n\t\tif strings.Contains(key, \"prior_conviction\") {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\n\treturn true, nil\n}\n```\n\nAnd with marshmallow:\n\n```go\nfunc isAllowedToDrive(data []byte) (bool, error) {\n\tv := struct {\n\t\tAge               int  `json:\"age\"`\n\t\tHasDriversLicense bool `json:\"has_drivers_license\"`\n\t}{}\n\tresult, err := marshmallow.Unmarshal(data, &v)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tif v.Age < 17 || !v.HasDriversLicense {\n\t\treturn false, nil\n\t}\n\n\tfor key := range result {\n\t\tif strings.Contains(key, \"prior_conviction\") {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\n\treturn true, nil\n}\n```\n\n## API\n\nMarshmallow exposes two main API functions -\n[Unmarshal](https://github.com/PerimeterX/marshmallow/blob/0e0218ab860be8a4b5f57f5ff239f281c250c5da/unmarshal.go#L27)\nand\n[UnmarshalFromJSONMap](https://github.com/PerimeterX/marshmallow/blob/0e0218ab860be8a4b5f57f5ff239f281c250c5da/unmarshal_from_json_map.go#L37).\nWhile unmarshalling, marshmallow supports the following optional options:\n\n* Setting the mode for handling invalid data using the [WithMode](https://github.com/PerimeterX/marshmallow/blob/0e0218ab860be8a4b5f57f5ff239f281c250c5da/options.go#L30) function.\n* Excluding known fields from the result map using the [WithExcludeKnownFieldsFromMap](https://github.com/PerimeterX/marshmallow/blob/457669ae9973895584f2636eabfc104140d3b700/options.go#L50) function. \n* Skipping struct population to boost performance using the [WithSkipPopulateStruct](https://github.com/PerimeterX/marshmallow/blob/0e0218ab860be8a4b5f57f5ff239f281c250c5da/options.go#L41) function.\n\nIn order to capture unknown nested fields, structs must implement [JSONDataErrorHandler](https://github.com/PerimeterX/marshmallow/blob/195c994aa6e3e0852601ad9cf65bcddef0dd7479/options.go#L76).\nMore info [here](https://github.com/PerimeterX/marshmallow/issues/15). \n\nMarshmallow also supports caching of refection information using \n[EnableCache](https://github.com/PerimeterX/marshmallow/blob/d3500aa5b0f330942b178b155da933c035dd3906/cache.go#L40)\nand\n[EnableCustomCache](https://github.com/PerimeterX/marshmallow/blob/d3500aa5b0f330942b178b155da933c035dd3906/cache.go#L35).\n\n## Contact and Contribute\n\nReporting issues and requesting features may be done in our [GitHub issues page](https://github.com/PerimeterX/marshmallow/issues).\nDiscussions may be conducted in our [GitHub discussions page](https://github.com/PerimeterX/marshmallow/discussions).\nFor any further questions or comments you can reach us out at [open-source@humansecurity.com](mailto:open-source@humansecurity.com).\n\nAny type of contribution is warmly welcome and appreciated ❤️\nPlease read our [contribution](CONTRIBUTING.md) guide for more info.\n\nIf you're looking for something to get started with, tou can always follow our [issues page](https://github.com/PerimeterX/marshmallow/issues) and look for\n[good first issue](https://github.com/PerimeterX/marshmallow/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) and\n[help wanted](https://github.com/PerimeterX/marshmallow/issues?q=is%3Aissue+label%3A%22help+wanted%22+is%3Aopen) labels.\n\n## Marshmallow Logo\n\nMarshmallow logo and assets by [Adva Rom](https://www.linkedin.com/in/adva-rom-7a6738127/) are licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by/4.0/\">Creative Commons Attribution 4.0 International License</a>.<br />\n\n![Marshmallow Logo](https://raw.githubusercontent.com/PerimeterX/marshmallow/assets/marshmallow.png)\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/cache.go",
    "content": "// Copyright 2022 PerimeterX. All rights reserved.\n// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage marshmallow\n\nimport (\n\t\"reflect\"\n\t\"sync\"\n)\n\n// Cache allows unmarshalling to use a cached version of refection information about types.\n// Cache interface follows the implementation of sync.Map, but you may wrap any cache implementation\n// to match it. This allows you to control max cache size, eviction policies and any other caching aspect.\ntype Cache interface {\n\t// Load returns the value stored in the map for a key, or nil if no value is present.\n\t// The ok result indicates whether value was found in the map.\n\tLoad(key interface{}) (interface{}, bool)\n\t// Store sets the value for a key.\n\tStore(key, value interface{})\n}\n\n// EnableCustomCache enables unmarshalling cache. It allows reuse of refection information about types needed\n// to perform the unmarshalling. A use of such cache can boost up unmarshalling by x1.4.\n// Check out benchmark_test.go for an example.\n//\n// EnableCustomCache is not thread safe! Do not use it while performing unmarshalling, or it will\n// cause an unsafe race condition. Typically, EnableCustomCache should be called once when the process boots.\n//\n// Caching is disabled by default. The use of this function allows enabling it and controlling the\n// behavior of the cache. Typically, the use of sync.Map should be good enough. The caching mechanism\n// stores a single map per struct type. If you plan to unmarshal a huge amount of distinct\n// struct it may get to consume a lot of resources, in which case you have the control to choose\n// the caching implementation you like and its setup.\nfunc EnableCustomCache(c Cache) {\n\tcache = c\n}\n\n// EnableCache enables unmarshalling cache with default implementation. More info at EnableCustomCache.\nfunc EnableCache() {\n\tEnableCustomCache(&sync.Map{})\n}\n\nvar cache Cache\n\nfunc cacheLookup(t reflect.Type) map[string]reflectionInfo {\n\tif cache == nil {\n\t\treturn nil\n\t}\n\tvalue, exists := cache.Load(t)\n\tif !exists {\n\t\treturn nil\n\t}\n\tresult, _ := value.(map[string]reflectionInfo)\n\treturn result\n}\n\nfunc cacheStore(t reflect.Type, fields map[string]reflectionInfo) {\n\tif cache == nil {\n\t\treturn\n\t}\n\tcache.Store(t, fields)\n}\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/doc.go",
    "content": "/*\nPackage marshmallow provides a simple API to perform flexible and performant JSON unmarshalling.\nUnlike other packages, marshmallow supports unmarshalling of some known and some unknown fields\nwith zero performance overhead nor extra coding needed. While unmarshalling,\nmarshmallow allows fully retaining the original data and access it via a typed struct and a\ndynamic map.\n\nhttps://github.com/perimeterx/marshmallow\n*/\npackage marshmallow\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/errors.go",
    "content": "// Copyright 2022 PerimeterX. All rights reserved.\n// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage marshmallow\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"github.com/mailru/easyjson/jlexer\"\n\t\"reflect\"\n\t\"strings\"\n)\n\nvar (\n\t// ErrInvalidInput indicates the input JSON is invalid\n\tErrInvalidInput = errors.New(\"invalid JSON input\")\n\n\t// ErrInvalidValue indicates the target struct has invalid type\n\tErrInvalidValue = errors.New(\"unexpected non struct value\")\n)\n\n// MultipleLexerError indicates one or more unmarshalling errors during JSON bytes decode\ntype MultipleLexerError struct {\n\tErrors []*jlexer.LexerError\n}\n\nfunc (m *MultipleLexerError) Error() string {\n\terrs := make([]string, len(m.Errors))\n\tfor i, lexerError := range m.Errors {\n\t\terrs[i] = lexerError.Error()\n\t}\n\treturn strings.Join(errs, \", \")\n}\n\n// MultipleError indicates one or more unmarshalling errors during JSON map decode\ntype MultipleError struct {\n\tErrors []error\n}\n\nfunc (m *MultipleError) Error() string {\n\terrs := make([]string, len(m.Errors))\n\tfor i, lexerError := range m.Errors {\n\t\terrs[i] = lexerError.Error()\n\t}\n\treturn strings.Join(errs, \", \")\n}\n\n// ParseError indicates a JSON map decode error\ntype ParseError struct {\n\tReason string\n\tPath   string\n}\n\nfunc (p *ParseError) Error() string {\n\treturn fmt.Sprintf(\"parse error: %s in %s\", p.Reason, p.Path)\n}\n\nfunc newUnexpectedTypeParseError(expectedType reflect.Type, path []string) *ParseError {\n\treturn &ParseError{\n\t\tReason: fmt.Sprintf(\"expected type %s\", externalTypeName(expectedType)),\n\t\tPath:   strings.Join(path, \".\"),\n\t}\n}\n\nfunc newUnsupportedTypeParseError(unsupportedType reflect.Type, path []string) *ParseError {\n\treturn &ParseError{\n\t\tReason: fmt.Sprintf(\"unsupported type %s\", externalTypeName(unsupportedType)),\n\t\tPath:   strings.Join(path, \".\"),\n\t}\n}\n\nfunc addUnexpectedTypeLexerError(lexer *jlexer.Lexer, expectedType reflect.Type) {\n\tlexer.AddNonFatalError(fmt.Errorf(\"expected type %s\", externalTypeName(expectedType)))\n}\n\nfunc addUnsupportedTypeLexerError(lexer *jlexer.Lexer, unsupportedType reflect.Type) {\n\tlexer.AddNonFatalError(fmt.Errorf(\"unsupported type %s\", externalTypeName(unsupportedType)))\n}\n\nfunc externalTypeName(t reflect.Type) string {\n\tswitch t.Kind() {\n\tcase reflect.String:\n\t\treturn \"string\"\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint,\n\t\treflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32,\n\t\treflect.Float64, reflect.Complex64, reflect.Complex128:\n\t\treturn \"number\"\n\tcase reflect.Bool:\n\t\treturn \"boolean\"\n\tcase reflect.Array, reflect.Slice:\n\t\treturn \"array\"\n\tcase reflect.Interface:\n\t\treturn \"any\"\n\tcase reflect.Map, reflect.Struct:\n\t\treturn \"object\"\n\tcase reflect.Ptr:\n\t\treturn externalTypeName(t.Elem())\n\t}\n\treturn \"invalid\"\n}\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/options.go",
    "content": "// Copyright 2022 PerimeterX. All rights reserved.\n// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage marshmallow\n\n// Mode dictates the unmarshalling mode.\n// Each mode is self documented below.\ntype Mode uint8\n\nconst (\n\t// ModeFailOnFirstError is the default mode. It makes unmarshalling terminate\n\t// immediately on any kind of error. This error will then be returned.\n\tModeFailOnFirstError Mode = iota\n\n\t// ModeAllowMultipleErrors mode makes unmarshalling keep decoding even if\n\t// errors are encountered. In case of such error, the erroneous value will be omitted from the result.\n\t// Eventually, all errors will all be returned, alongside the partial result.\n\tModeAllowMultipleErrors\n\n\t// ModeFailOverToOriginalValue mode makes unmarshalling keep decoding even if\n\t// errors are encountered. In case of such error, the original external value be placed in the\n\t// result data, even though it does not meet the schematic requirements.\n\t// Eventually, all errors will be returned, alongside the full result. Note that the result map\n\t// will contain values that do not match the struct schema.\n\tModeFailOverToOriginalValue\n)\n\n// WithMode is an UnmarshalOption function to set the unmarshalling mode.\nfunc WithMode(mode Mode) UnmarshalOption {\n\treturn func(options *unmarshalOptions) {\n\t\toptions.mode = mode\n\t}\n}\n\n// WithSkipPopulateStruct is an UnmarshalOption function to set the skipPopulateStruct option.\n// Skipping populate struct is set to false by default.\n// If you do not intend to use the struct value once unmarshalling is finished, set this\n// option to true to boost performance. This would mean the struct fields will not be set\n// with values, but rather it will only be used as the target schema when populating the result map.\nfunc WithSkipPopulateStruct(skipPopulateStruct bool) UnmarshalOption {\n\treturn func(options *unmarshalOptions) {\n\t\toptions.skipPopulateStruct = skipPopulateStruct\n\t}\n}\n\n// WithExcludeKnownFieldsFromMap is an UnmarshalOption function to set the excludeKnownFieldsFromMap option.\n// Exclude known fields flag is set to false by default.\n// When the flag is set to true, fields specified in the input struct (known fields) will be excluded from the result map\nfunc WithExcludeKnownFieldsFromMap(excludeKnownFields bool) UnmarshalOption {\n\treturn func(options *unmarshalOptions) {\n\t\toptions.excludeKnownFieldsFromMap = excludeKnownFields\n\t}\n}\n\ntype UnmarshalOption func(*unmarshalOptions)\n\ntype unmarshalOptions struct {\n\tmode                      Mode\n\tskipPopulateStruct        bool\n\texcludeKnownFieldsFromMap bool\n}\n\nfunc buildUnmarshalOptions(options []UnmarshalOption) *unmarshalOptions {\n\tresult := &unmarshalOptions{}\n\tfor _, option := range options {\n\t\toption(result)\n\t}\n\treturn result\n}\n\n// JSONDataErrorHandler allow types to handle JSON data as maps.\n// Types should implement this interface if they wish to act on the map representation of parsed JSON input.\n// This is mainly used to allow nested objects to capture unknown fields and leverage marshmallow's abilities.\n// If HandleJSONData returns an error, it will be propagated as an unmarshal error\ntype JSONDataErrorHandler interface {\n\tHandleJSONData(data map[string]interface{}) error\n}\n\n// Deprecated: use JSONDataErrorHandler instead\ntype JSONDataHandler interface {\n\tHandleJSONData(data map[string]interface{})\n}\n\nfunc asJSONDataHandler(value interface{}) (func(map[string]interface{}) error, bool) {\n\tif handler, ok := value.(JSONDataErrorHandler); ok {\n\t\treturn handler.HandleJSONData, true\n\t}\n\tif handler, ok := value.(JSONDataHandler); ok {\n\t\treturn func(m map[string]interface{}) error {\n\t\t\thandler.HandleJSONData(m)\n\t\t\treturn nil\n\t\t}, true\n\t}\n\treturn nil, false\n}\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/reflection.go",
    "content": "// Copyright 2022 PerimeterX. All rights reserved.\n// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage marshmallow\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"strings\"\n)\n\nvar unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()\n\ntype reflectionInfo struct {\n\tpath []int\n\tt    reflect.Type\n}\n\nfunc (r reflectionInfo) field(target reflect.Value) reflect.Value {\n\tcurrent := target\n\tfor _, i := range r.path {\n\t\tcurrent = current.Field(i)\n\t}\n\treturn current\n}\n\nfunc mapStructFields(target interface{}) map[string]reflectionInfo {\n\tt := reflectStructType(target)\n\tresult := cacheLookup(t)\n\tif result != nil {\n\t\treturn result\n\t}\n\tresult = make(map[string]reflectionInfo, t.NumField())\n\tmapTypeFields(t, result, nil)\n\tcacheStore(t, result)\n\treturn result\n}\n\nfunc mapTypeFields(t reflect.Type, result map[string]reflectionInfo, path []int) {\n\tnum := t.NumField()\n\tfor i := 0; i < num; i++ {\n\t\tfield := t.Field(i)\n\t\tfieldPath := append(path, i)\n\t\tif field.Anonymous && field.Type.Kind() == reflect.Struct {\n\t\t\tmapTypeFields(field.Type, result, fieldPath)\n\t\t\tcontinue\n\t\t}\n\t\tname := field.Tag.Get(\"json\")\n\t\tif name == \"\" || name == \"-\" {\n\t\t\tcontinue\n\t\t}\n\t\tif index := strings.Index(name, \",\"); index > -1 {\n\t\t\tname = name[:index]\n\t\t}\n\t\tresult[name] = reflectionInfo{\n\t\t\tpath: fieldPath,\n\t\t\tt:    field.Type,\n\t\t}\n\t}\n}\n\nfunc reflectStructValue(target interface{}) reflect.Value {\n\tv := reflect.ValueOf(target)\n\tfor v.Kind() == reflect.Ptr {\n\t\tv = v.Elem()\n\t}\n\treturn v\n}\n\nfunc reflectStructType(target interface{}) reflect.Type {\n\tt := reflect.TypeOf(target)\n\tfor t.Kind() == reflect.Ptr {\n\t\tt = t.Elem()\n\t}\n\treturn t\n}\n\nvar primitiveConverters = map[reflect.Kind]func(v interface{}) (interface{}, bool){\n\treflect.Bool: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(bool)\n\t\treturn res, ok\n\t},\n\treflect.Int: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn int(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Int8: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn int8(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Int16: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn int16(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Int32: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn int32(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Int64: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn int64(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Uint: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn uint(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Uint8: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn uint8(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Uint16: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn uint16(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Uint32: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn uint32(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Uint64: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn uint64(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Float32: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn float32(res), true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Float64: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(float64)\n\t\tif ok {\n\t\t\treturn res, true\n\t\t}\n\t\treturn v, false\n\t},\n\treflect.Interface: func(v interface{}) (interface{}, bool) {\n\t\treturn v, true\n\t},\n\treflect.String: func(v interface{}) (interface{}, bool) {\n\t\tres, ok := v.(string)\n\t\treturn res, ok\n\t},\n}\n\nfunc assignValue(field reflect.Value, value interface{}) {\n\tif value == nil {\n\t\treturn\n\t}\n\treflectValue := reflect.ValueOf(value)\n\tif reflectValue.Type().AssignableTo(field.Type()) {\n\t\tfield.Set(reflectValue)\n\t}\n}\n\nfunc isValidValue(v interface{}) bool {\n\tvalue := reflect.ValueOf(v)\n\treturn value.Kind() == reflect.Ptr && value.Elem().Kind() == reflect.Struct && !value.IsNil()\n}\n\nfunc safeReflectValue(t reflect.Type, v interface{}) reflect.Value {\n\tif v == nil {\n\t\treturn reflect.Zero(t)\n\t}\n\treturn reflect.ValueOf(v)\n}\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/unmarshal.go",
    "content": "// Copyright 2022 PerimeterX. All rights reserved.\n// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage marshmallow\n\nimport (\n\t\"encoding/json\"\n\t\"github.com/mailru/easyjson/jlexer\"\n\t\"reflect\"\n)\n\n// Unmarshal parses the JSON-encoded object in data and stores the values\n// in the struct pointed to by v and in the returned map.\n// If v is nil or not a pointer to a struct, Unmarshal returns an ErrInvalidValue.\n// If data is not a valid JSON or not a JSON object Unmarshal returns an ErrInvalidInput.\n//\n// Unmarshal follows the rules of json.Unmarshal with the following exceptions:\n// - All input fields are stored in the resulting map, including fields that do not exist in the\n// struct pointed by v.\n// - Unmarshal only operates on JSON object inputs. It will reject all other types of input\n// by returning ErrInvalidInput.\n// - Unmarshal only operates on struct values. It will reject all other types of v by\n// returning ErrInvalidValue.\n// - Unmarshal supports three types of Mode values. Each mode is self documented and affects\n// how Unmarshal behaves.\nfunc Unmarshal(data []byte, v interface{}, options ...UnmarshalOption) (map[string]interface{}, error) {\n\tif !isValidValue(v) {\n\t\treturn nil, ErrInvalidValue\n\t}\n\topts := buildUnmarshalOptions(options)\n\tuseMultipleErrors := opts.mode == ModeAllowMultipleErrors || opts.mode == ModeFailOverToOriginalValue\n\td := &decoder{options: opts, lexer: &jlexer.Lexer{Data: data, UseMultipleErrors: useMultipleErrors}}\n\tresult := make(map[string]interface{})\n\tif d.lexer.IsNull() {\n\t\td.lexer.Skip()\n\t} else if !d.lexer.IsDelim('{') {\n\t\treturn nil, ErrInvalidInput\n\t} else {\n\t\td.populateStruct(false, v, result)\n\t}\n\td.lexer.Consumed()\n\tif useMultipleErrors {\n\t\terrors := d.lexer.GetNonFatalErrors()\n\t\tif len(errors) == 0 {\n\t\t\treturn result, nil\n\t\t}\n\t\treturn result, &MultipleLexerError{Errors: errors}\n\t}\n\terr := d.lexer.Error()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\ntype decoder struct {\n\toptions *unmarshalOptions\n\tlexer   *jlexer.Lexer\n}\n\nfunc (d *decoder) populateStruct(forcePopulate bool, structInstance interface{}, result map[string]interface{}) (interface{}, bool) {\n\tdoPopulate := !d.options.skipPopulateStruct || forcePopulate\n\tvar structValue reflect.Value\n\tif doPopulate {\n\t\tstructValue = reflectStructValue(structInstance)\n\t}\n\tfields := mapStructFields(structInstance)\n\tvar clone map[string]interface{}\n\tif d.options.mode == ModeFailOverToOriginalValue {\n\t\tclone = make(map[string]interface{}, len(fields))\n\t}\n\td.lexer.Delim('{')\n\tfor !d.lexer.IsDelim('}') {\n\t\tkey := d.lexer.UnsafeFieldName(false)\n\t\td.lexer.WantColon()\n\t\trefInfo, exists := fields[key]\n\t\tif exists {\n\t\t\tvalue, isValidType := d.valueByReflectType(refInfo.t)\n\t\t\tif isValidType {\n\t\t\t\tif value != nil && doPopulate {\n\t\t\t\t\tfield := refInfo.field(structValue)\n\t\t\t\t\tassignValue(field, value)\n\t\t\t\t}\n\t\t\t\tif !d.options.excludeKnownFieldsFromMap {\n\t\t\t\t\tif result != nil {\n\t\t\t\t\t\tresult[key] = value\n\t\t\t\t\t}\n\t\t\t\t\tif clone != nil {\n\t\t\t\t\t\tclone[key] = value\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch d.options.mode {\n\t\t\t\tcase ModeFailOnFirstError:\n\t\t\t\t\treturn nil, false\n\t\t\t\tcase ModeFailOverToOriginalValue:\n\t\t\t\t\tif !forcePopulate {\n\t\t\t\t\t\tresult[key] = value\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone[key] = value\n\t\t\t\t\t\td.lexer.WantComma()\n\t\t\t\t\t\td.drainLexerMap(clone)\n\t\t\t\t\t\treturn clone, false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tvalue := d.lexer.Interface()\n\t\t\tif result != nil {\n\t\t\t\tresult[key] = value\n\t\t\t}\n\t\t\tif clone != nil {\n\t\t\t\tclone[key] = value\n\t\t\t}\n\t\t}\n\t\td.lexer.WantComma()\n\t}\n\td.lexer.Delim('}')\n\treturn structInstance, true\n}\n\nfunc (d *decoder) valueByReflectType(t reflect.Type) (interface{}, bool) {\n\tif t.Implements(unmarshalerType) {\n\t\tresult := reflect.New(t.Elem()).Interface()\n\t\td.valueFromCustomUnmarshaler(result.(json.Unmarshaler))\n\t\treturn result, true\n\t}\n\tif reflect.PtrTo(t).Implements(unmarshalerType) {\n\t\tvalue := reflect.New(t)\n\t\td.valueFromCustomUnmarshaler(value.Interface().(json.Unmarshaler))\n\t\treturn value.Elem().Interface(), true\n\t}\n\tkind := t.Kind()\n\tif converter := primitiveConverters[kind]; converter != nil {\n\t\tv := d.lexer.Interface()\n\t\tif v == nil {\n\t\t\treturn nil, true\n\t\t}\n\t\tconverted, ok := converter(v)\n\t\tif !ok {\n\t\t\taddUnexpectedTypeLexerError(d.lexer, t)\n\t\t\treturn v, false\n\t\t}\n\t\treturn converted, true\n\t}\n\tswitch kind {\n\tcase reflect.Slice:\n\t\treturn d.buildSlice(t)\n\tcase reflect.Array:\n\t\treturn d.buildArray(t)\n\tcase reflect.Map:\n\t\treturn d.buildMap(t)\n\tcase reflect.Struct:\n\t\tvalue, valid := d.buildStruct(t)\n\t\tif value == nil {\n\t\t\treturn nil, valid\n\t\t}\n\t\tif !valid {\n\t\t\treturn value, false\n\t\t}\n\t\treturn reflect.ValueOf(value).Elem().Interface(), valid\n\tcase reflect.Ptr:\n\t\tif t.Elem().Kind() == reflect.Struct {\n\t\t\treturn d.buildStruct(t.Elem())\n\t\t}\n\t\tvalue, valid := d.valueByReflectType(t.Elem())\n\t\tif value == nil {\n\t\t\treturn nil, valid\n\t\t}\n\t\tif !valid {\n\t\t\treturn value, false\n\t\t}\n\t\tresult := reflect.New(reflect.TypeOf(value))\n\t\tresult.Elem().Set(reflect.ValueOf(value))\n\t\treturn result.Interface(), valid\n\t}\n\taddUnsupportedTypeLexerError(d.lexer, t)\n\treturn nil, false\n}\n\nfunc (d *decoder) buildSlice(sliceType reflect.Type) (interface{}, bool) {\n\tif d.lexer.IsNull() {\n\t\td.lexer.Skip()\n\t\treturn nil, true\n\t}\n\tif !d.lexer.IsDelim('[') {\n\t\taddUnexpectedTypeLexerError(d.lexer, sliceType)\n\t\treturn d.lexer.Interface(), false\n\t}\n\telemType := sliceType.Elem()\n\td.lexer.Delim('[')\n\tvar sliceValue reflect.Value\n\tif !d.lexer.IsDelim(']') {\n\t\tsliceValue = reflect.MakeSlice(sliceType, 0, 4)\n\t} else {\n\t\tsliceValue = reflect.MakeSlice(sliceType, 0, 0)\n\t}\n\tfor !d.lexer.IsDelim(']') {\n\t\tcurrent, valid := d.valueByReflectType(elemType)\n\t\tif !valid {\n\t\t\tif d.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\td.drainLexerArray(nil)\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\tresult := d.cloneReflectArray(sliceValue, -1)\n\t\t\tresult = append(result, current)\n\t\t\treturn d.drainLexerArray(result), true\n\t\t}\n\t\tsliceValue = reflect.Append(sliceValue, safeReflectValue(elemType, current))\n\t\td.lexer.WantComma()\n\t}\n\td.lexer.Delim(']')\n\treturn sliceValue.Interface(), true\n}\n\nfunc (d *decoder) buildArray(arrayType reflect.Type) (interface{}, bool) {\n\tif d.lexer.IsNull() {\n\t\td.lexer.Skip()\n\t\treturn nil, true\n\t}\n\tif !d.lexer.IsDelim('[') {\n\t\taddUnexpectedTypeLexerError(d.lexer, arrayType)\n\t\treturn d.lexer.Interface(), false\n\t}\n\telemType := arrayType.Elem()\n\tarrayValue := reflect.New(arrayType).Elem()\n\td.lexer.Delim('[')\n\tfor i := 0; !d.lexer.IsDelim(']'); i++ {\n\t\tcurrent, valid := d.valueByReflectType(elemType)\n\t\tif !valid {\n\t\t\tif d.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\td.drainLexerArray(nil)\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\tresult := d.cloneReflectArray(arrayValue, i)\n\t\t\tresult = append(result, current)\n\t\t\treturn d.drainLexerArray(result), true\n\t\t}\n\t\tif current != nil {\n\t\t\tarrayValue.Index(i).Set(reflect.ValueOf(current))\n\t\t}\n\t\td.lexer.WantComma()\n\t}\n\td.lexer.Delim(']')\n\treturn arrayValue.Interface(), true\n}\n\nfunc (d *decoder) buildMap(mapType reflect.Type) (interface{}, bool) {\n\tif d.lexer.IsNull() {\n\t\td.lexer.Skip()\n\t\treturn nil, true\n\t}\n\tif !d.lexer.IsDelim('{') {\n\t\taddUnexpectedTypeLexerError(d.lexer, mapType)\n\t\treturn d.lexer.Interface(), false\n\t}\n\td.lexer.Delim('{')\n\tkeyType := mapType.Key()\n\tvalueType := mapType.Elem()\n\tmapValue := reflect.MakeMap(mapType)\n\tfor !d.lexer.IsDelim('}') {\n\t\tkey, valid := d.valueByReflectType(keyType)\n\t\tif !valid {\n\t\t\tif d.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\td.lexer.WantColon()\n\t\t\t\td.lexer.Interface()\n\t\t\t\td.lexer.WantComma()\n\t\t\t\td.drainLexerMap(make(map[string]interface{}))\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\tstrKey, _ := key.(string)\n\t\t\td.lexer.WantColon()\n\t\t\tvalue := d.lexer.Interface()\n\t\t\tresult := d.cloneReflectMap(mapValue)\n\t\t\tresult[strKey] = value\n\t\t\td.lexer.WantComma()\n\t\t\td.drainLexerMap(result)\n\t\t\treturn result, true\n\t\t}\n\t\td.lexer.WantColon()\n\t\tvalue, valid := d.valueByReflectType(valueType)\n\t\tif !valid {\n\t\t\tif d.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\td.lexer.WantComma()\n\t\t\t\td.drainLexerMap(make(map[string]interface{}))\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\tstrKey, _ := key.(string)\n\t\t\tresult := d.cloneReflectMap(mapValue)\n\t\t\tresult[strKey] = value\n\t\t\td.lexer.WantComma()\n\t\t\td.drainLexerMap(result)\n\t\t\treturn result, true\n\t\t}\n\t\tmapValue.SetMapIndex(safeReflectValue(keyType, key), safeReflectValue(valueType, value))\n\t\td.lexer.WantComma()\n\t}\n\td.lexer.Delim('}')\n\treturn mapValue.Interface(), true\n}\n\nfunc (d *decoder) buildStruct(structType reflect.Type) (interface{}, bool) {\n\tif d.lexer.IsNull() {\n\t\td.lexer.Skip()\n\t\treturn nil, true\n\t}\n\tif !d.lexer.IsDelim('{') {\n\t\taddUnexpectedTypeLexerError(d.lexer, structType)\n\t\treturn d.lexer.Interface(), false\n\t}\n\tvalue := reflect.New(structType).Interface()\n\thandler, ok := asJSONDataHandler(value)\n\tif !ok {\n\t\treturn d.populateStruct(true, value, nil)\n\t}\n\tdata := make(map[string]interface{})\n\tresult, valid := d.populateStruct(true, value, data)\n\tif !valid {\n\t\treturn result, false\n\t}\n\terr := handler(data)\n\tif err != nil {\n\t\td.lexer.AddNonFatalError(err)\n\t\treturn result, false\n\t}\n\treturn result, true\n}\n\nfunc (d *decoder) valueFromCustomUnmarshaler(unmarshaler json.Unmarshaler) {\n\tdata := d.lexer.Raw()\n\tif !d.lexer.Ok() {\n\t\treturn\n\t}\n\terr := unmarshaler.UnmarshalJSON(data)\n\tif err != nil {\n\t\td.lexer.AddNonFatalError(err)\n\t}\n}\n\nfunc (d *decoder) cloneReflectArray(value reflect.Value, length int) []interface{} {\n\tif length == -1 {\n\t\tlength = value.Len()\n\t}\n\tresult := make([]interface{}, length)\n\tfor i := 0; i < length; i++ {\n\t\tresult[i] = value.Index(i).Interface()\n\t}\n\treturn result\n}\n\nfunc (d *decoder) cloneReflectMap(mapValue reflect.Value) map[string]interface{} {\n\tl := mapValue.Len()\n\tresult := make(map[string]interface{}, l)\n\tfor _, key := range mapValue.MapKeys() {\n\t\tvalue := mapValue.MapIndex(key)\n\t\tstrKey, _ := key.Interface().(string)\n\t\tresult[strKey] = value.Interface()\n\t}\n\treturn result\n}\n\nfunc (d *decoder) drainLexerArray(target []interface{}) interface{} {\n\td.lexer.WantComma()\n\tfor !d.lexer.IsDelim(']') {\n\t\tcurrent := d.lexer.Interface()\n\t\ttarget = append(target, current)\n\t\td.lexer.WantComma()\n\t}\n\td.lexer.Delim(']')\n\treturn target\n}\n\nfunc (d *decoder) drainLexerMap(target map[string]interface{}) {\n\tfor !d.lexer.IsDelim('}') {\n\t\tkey := d.lexer.String()\n\t\td.lexer.WantColon()\n\t\tvalue := d.lexer.Interface()\n\t\ttarget[key] = value\n\t\td.lexer.WantComma()\n\t}\n\td.lexer.Delim('}')\n}\n"
  },
  {
    "path": "vendor/github.com/perimeterx/marshmallow/unmarshal_from_json_map.go",
    "content": "// Copyright 2022 PerimeterX. All rights reserved.\n// Use of this source code is governed by a MIT style\n// license that can be found in the LICENSE file.\n\npackage marshmallow\n\nimport (\n\t\"reflect\"\n)\n\n// UnmarshalerFromJSONMap is the interface implemented by types\n// that can unmarshal a JSON description of themselves.\n// In case you want to implement custom unmarshalling, json.Unmarshaler only supports\n// receiving the data as []byte. However, while unmarshalling from JSON map,\n// the data is not available as a raw []byte and converting to it will significantly\n// hurt performance. Thus, if you wish to implement a custom unmarshalling on a type\n// that is being unmarshalled from a JSON map, you need to implement\n// UnmarshalerFromJSONMap interface.\ntype UnmarshalerFromJSONMap interface {\n\tUnmarshalJSONFromMap(data interface{}) error\n}\n\n// UnmarshalFromJSONMap parses the JSON map data and stores the values\n// in the struct pointed to by v and in the returned map.\n// If v is nil or not a pointer to a struct, UnmarshalFromJSONMap returns an ErrInvalidValue.\n//\n// UnmarshalFromJSONMap follows the rules of json.Unmarshal with the following exceptions:\n// - All input fields are stored in the resulting map, including fields that do not exist in the\n// struct pointed by v.\n// - UnmarshalFromJSONMap receive a JSON map instead of raw bytes. The given input map is assumed\n// to be a JSON map, meaning it should only contain the following types: bool, string, float64,\n// []interface, and map[string]interface{}. Other types will cause decoding to return unexpected results.\n// - UnmarshalFromJSONMap only operates on struct values. It will reject all other types of v by\n// returning ErrInvalidValue.\n// - UnmarshalFromJSONMap supports three types of Mode values. Each mode is self documented and affects\n// how UnmarshalFromJSONMap behaves.\nfunc UnmarshalFromJSONMap(data map[string]interface{}, v interface{}, options ...UnmarshalOption) (map[string]interface{}, error) {\n\tif !isValidValue(v) {\n\t\treturn nil, ErrInvalidValue\n\t}\n\topts := buildUnmarshalOptions(options)\n\td := &mapDecoder{options: opts}\n\tresult := make(map[string]interface{})\n\tif data != nil {\n\t\td.populateStruct(false, nil, data, v, result)\n\t}\n\tif opts.mode == ModeAllowMultipleErrors || opts.mode == ModeFailOverToOriginalValue {\n\t\tif len(d.errs) == 0 {\n\t\t\treturn result, nil\n\t\t}\n\t\treturn result, &MultipleError{Errors: d.errs}\n\t}\n\tif d.err != nil {\n\t\treturn nil, d.err\n\t}\n\treturn result, nil\n}\n\nvar unmarshalerFromJSONMapType = reflect.TypeOf((*UnmarshalerFromJSONMap)(nil)).Elem()\n\ntype mapDecoder struct {\n\toptions *unmarshalOptions\n\terr     error\n\terrs    []error\n}\n\nfunc (m *mapDecoder) populateStruct(forcePopulate bool, path []string, data map[string]interface{}, structInstance interface{}, result map[string]interface{}) (interface{}, bool) {\n\tdoPopulate := !m.options.skipPopulateStruct || forcePopulate\n\tvar structValue reflect.Value\n\tif doPopulate {\n\t\tstructValue = reflectStructValue(structInstance)\n\t}\n\tfields := mapStructFields(structInstance)\n\tfor key, inputValue := range data {\n\t\trefInfo, exists := fields[key]\n\t\tif exists {\n\t\t\tvalue, isValidType := m.valueByReflectType(append(path, key), inputValue, refInfo.t)\n\t\t\tif isValidType {\n\t\t\t\tif value != nil && doPopulate {\n\t\t\t\t\tfield := refInfo.field(structValue)\n\t\t\t\t\tassignValue(field, value)\n\t\t\t\t}\n\t\t\t\tif !m.options.excludeKnownFieldsFromMap {\n\t\t\t\t\tif result != nil {\n\t\t\t\t\t\tresult[key] = value\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch m.options.mode {\n\t\t\t\tcase ModeFailOnFirstError:\n\t\t\t\t\treturn nil, false\n\t\t\t\tcase ModeFailOverToOriginalValue:\n\t\t\t\t\tif !forcePopulate {\n\t\t\t\t\t\tresult[key] = value\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn data, false\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif result != nil {\n\t\t\t\tresult[key] = inputValue\n\t\t\t}\n\t\t}\n\t}\n\treturn structInstance, true\n}\n\nfunc (m *mapDecoder) valueByReflectType(path []string, v interface{}, t reflect.Type) (interface{}, bool) {\n\tif t.Implements(unmarshalerFromJSONMapType) {\n\t\tresult := reflect.New(t.Elem()).Interface()\n\t\tm.valueFromCustomUnmarshaler(v, result.(UnmarshalerFromJSONMap))\n\t\treturn result, true\n\t}\n\tif reflect.PtrTo(t).Implements(unmarshalerFromJSONMapType) {\n\t\tvalue := reflect.New(t)\n\t\tm.valueFromCustomUnmarshaler(v, value.Interface().(UnmarshalerFromJSONMap))\n\t\treturn value.Elem().Interface(), true\n\t}\n\tkind := t.Kind()\n\tif converter := primitiveConverters[kind]; converter != nil {\n\t\tif v == nil {\n\t\t\treturn nil, true\n\t\t}\n\t\tconverted, ok := converter(v)\n\t\tif !ok {\n\t\t\tm.addError(newUnexpectedTypeParseError(t, path))\n\t\t\treturn v, false\n\t\t}\n\t\treturn converted, true\n\t}\n\tswitch kind {\n\tcase reflect.Slice:\n\t\treturn m.buildSlice(path, v, t)\n\tcase reflect.Array:\n\t\treturn m.buildArray(path, v, t)\n\tcase reflect.Map:\n\t\treturn m.buildMap(path, v, t)\n\tcase reflect.Struct:\n\t\tvalue, valid := m.buildStruct(path, v, t)\n\t\tif value == nil {\n\t\t\treturn nil, valid\n\t\t}\n\t\tif !valid {\n\t\t\treturn value, false\n\t\t}\n\t\treturn reflect.ValueOf(value).Elem().Interface(), valid\n\tcase reflect.Ptr:\n\t\tif t.Elem().Kind() == reflect.Struct {\n\t\t\treturn m.buildStruct(path, v, t.Elem())\n\t\t}\n\t\tvalue, valid := m.valueByReflectType(path, v, t.Elem())\n\t\tif value == nil {\n\t\t\treturn nil, valid\n\t\t}\n\t\tif !valid {\n\t\t\treturn value, false\n\t\t}\n\t\tresult := reflect.New(reflect.TypeOf(value))\n\t\tresult.Elem().Set(reflect.ValueOf(value))\n\t\treturn result.Interface(), valid\n\t}\n\tm.addError(newUnsupportedTypeParseError(t, path))\n\treturn nil, false\n}\n\nfunc (m *mapDecoder) buildSlice(path []string, v interface{}, sliceType reflect.Type) (interface{}, bool) {\n\tif v == nil {\n\t\treturn nil, true\n\t}\n\tarr, ok := v.([]interface{})\n\tif !ok {\n\t\tm.addError(newUnexpectedTypeParseError(sliceType, path))\n\t\treturn v, false\n\t}\n\telemType := sliceType.Elem()\n\tvar sliceValue reflect.Value\n\tif len(arr) > 0 {\n\t\tsliceValue = reflect.MakeSlice(sliceType, 0, 4)\n\t} else {\n\t\tsliceValue = reflect.MakeSlice(sliceType, 0, 0)\n\t}\n\tfor _, element := range arr {\n\t\tcurrent, valid := m.valueByReflectType(path, element, elemType)\n\t\tif !valid {\n\t\t\tif m.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\treturn v, true\n\t\t}\n\t\tsliceValue = reflect.Append(sliceValue, safeReflectValue(elemType, current))\n\t}\n\treturn sliceValue.Interface(), true\n}\n\nfunc (m *mapDecoder) buildArray(path []string, v interface{}, arrayType reflect.Type) (interface{}, bool) {\n\tif v == nil {\n\t\treturn nil, true\n\t}\n\tarr, ok := v.([]interface{})\n\tif !ok {\n\t\tm.addError(newUnexpectedTypeParseError(arrayType, path))\n\t\treturn v, false\n\t}\n\telemType := arrayType.Elem()\n\tarrayValue := reflect.New(arrayType).Elem()\n\tfor i, element := range arr {\n\t\tcurrent, valid := m.valueByReflectType(path, element, elemType)\n\t\tif !valid {\n\t\t\tif m.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\treturn v, true\n\t\t}\n\t\tif current != nil {\n\t\t\tarrayValue.Index(i).Set(reflect.ValueOf(current))\n\t\t}\n\t}\n\treturn arrayValue.Interface(), true\n}\n\nfunc (m *mapDecoder) buildMap(path []string, v interface{}, mapType reflect.Type) (interface{}, bool) {\n\tif v == nil {\n\t\treturn nil, true\n\t}\n\tmp, ok := v.(map[string]interface{})\n\tif !ok {\n\t\tm.addError(newUnexpectedTypeParseError(mapType, path))\n\t\treturn v, false\n\t}\n\tkeyType := mapType.Key()\n\tvalueType := mapType.Elem()\n\tmapValue := reflect.MakeMap(mapType)\n\tfor inputKey, inputValue := range mp {\n\t\tkeyPath := append(path, inputKey)\n\t\tkey, valid := m.valueByReflectType(keyPath, inputKey, keyType)\n\t\tif !valid {\n\t\t\tif m.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\treturn v, true\n\t\t}\n\t\tvalue, valid := m.valueByReflectType(keyPath, inputValue, valueType)\n\t\tif !valid {\n\t\t\tif m.options.mode != ModeFailOverToOriginalValue {\n\t\t\t\treturn nil, true\n\t\t\t}\n\t\t\treturn v, true\n\t\t}\n\t\tmapValue.SetMapIndex(safeReflectValue(keyType, key), safeReflectValue(valueType, value))\n\t}\n\treturn mapValue.Interface(), true\n}\n\nfunc (m *mapDecoder) buildStruct(path []string, v interface{}, structType reflect.Type) (interface{}, bool) {\n\tif v == nil {\n\t\treturn nil, true\n\t}\n\tmp, ok := v.(map[string]interface{})\n\tif !ok {\n\t\tm.addError(newUnexpectedTypeParseError(structType, path))\n\t\treturn v, false\n\t}\n\tvalue := reflect.New(structType).Interface()\n\thandler, ok := asJSONDataHandler(value)\n\tif !ok {\n\t\treturn m.populateStruct(true, path, mp, value, nil)\n\t}\n\tdata := make(map[string]interface{})\n\tresult, valid := m.populateStruct(true, path, mp, value, data)\n\tif !valid {\n\t\treturn result, false\n\t}\n\terr := handler(data)\n\tif err != nil {\n\t\tm.addError(err)\n\t\treturn result, false\n\t}\n\treturn result, true\n}\n\nfunc (m *mapDecoder) valueFromCustomUnmarshaler(data interface{}, unmarshaler UnmarshalerFromJSONMap) {\n\terr := unmarshaler.UnmarshalJSONFromMap(data)\n\tif err != nil {\n\t\tm.addError(err)\n\t}\n}\n\nfunc (m *mapDecoder) addError(err error) {\n\tif m.options.mode == ModeFailOnFirstError {\n\t\tm.err = err\n\t} else {\n\t\tm.errs = append(m.errs, err)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/peterbourgon/diskv/LICENSE",
    "content": "Copyright (c) 2011-2012 Peter Bourgon\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/peterbourgon/diskv/README.md",
    "content": "# What is diskv?\n\nDiskv (disk-vee) is a simple, persistent key-value store written in the Go\nlanguage. It starts with an incredibly simple API for storing arbitrary data on\na filesystem by key, and builds several layers of performance-enhancing\nabstraction on top.  The end result is a conceptually simple, but highly\nperformant, disk-backed storage system.\n\n[![Build Status][1]][2]\n\n[1]: https://drone.io/github.com/peterbourgon/diskv/status.png\n[2]: https://drone.io/github.com/peterbourgon/diskv/latest\n\n\n# Installing\n\nInstall [Go 1][3], either [from source][4] or [with a prepackaged binary][5].\nThen,\n\n```bash\n$ go get github.com/peterbourgon/diskv\n```\n\n[3]: http://golang.org\n[4]: http://golang.org/doc/install/source\n[5]: http://golang.org/doc/install\n\n\n# Usage\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/peterbourgon/diskv\"\n)\n\nfunc main() {\n\t// Simplest transform function: put all the data files into the base dir.\n\tflatTransform := func(s string) []string { return []string{} }\n\n\t// Initialize a new diskv store, rooted at \"my-data-dir\", with a 1MB cache.\n\td := diskv.New(diskv.Options{\n\t\tBasePath:     \"my-data-dir\",\n\t\tTransform:    flatTransform,\n\t\tCacheSizeMax: 1024 * 1024,\n\t})\n\n\t// Write three bytes to the key \"alpha\".\n\tkey := \"alpha\"\n\td.Write(key, []byte{'1', '2', '3'})\n\n\t// Read the value back out of the store.\n\tvalue, _ := d.Read(key)\n\tfmt.Printf(\"%v\\n\", value)\n\n\t// Erase the key+value from the store (and the disk).\n\td.Erase(key)\n}\n```\n\nMore complex examples can be found in the \"examples\" subdirectory.\n\n\n# Theory\n\n## Basic idea\n\nAt its core, diskv is a map of a key (`string`) to arbitrary data (`[]byte`).\nThe data is written to a single file on disk, with the same name as the key.\nThe key determines where that file will be stored, via a user-provided\n`TransformFunc`, which takes a key and returns a slice (`[]string`)\ncorresponding to a path list where the key file will be stored. The simplest\nTransformFunc,\n\n```go\nfunc SimpleTransform (key string) []string {\n    return []string{}\n}\n```\n\nwill place all keys in the same, base directory. The design is inspired by\n[Redis diskstore][6]; a TransformFunc which emulates the default diskstore\nbehavior is available in the content-addressable-storage example.\n\n[6]: http://groups.google.com/group/redis-db/browse_thread/thread/d444bc786689bde9?pli=1\n\n**Note** that your TransformFunc should ensure that one valid key doesn't\ntransform to a subset of another valid key. That is, it shouldn't be possible\nto construct valid keys that resolve to directory names. As a concrete example,\nif your TransformFunc splits on every 3 characters, then\n\n```go\nd.Write(\"abcabc\", val) // OK: written to <base>/abc/abc/abcabc\nd.Write(\"abc\", val)    // Error: attempted write to <base>/abc/abc, but it's a directory\n```\n\nThis will be addressed in an upcoming version of diskv.\n\nProbably the most important design principle behind diskv is that your data is\nalways flatly available on the disk. diskv will never do anything that would\nprevent you from accessing, copying, backing up, or otherwise interacting with\nyour data via common UNIX commandline tools.\n\n## Adding a cache\n\nAn in-memory caching layer is provided by combining the BasicStore\nfunctionality with a simple map structure, and keeping it up-to-date as\nappropriate. Since the map structure in Go is not threadsafe, it's combined\nwith a RWMutex to provide safe concurrent access.\n\n## Adding order\n\ndiskv is a key-value store and therefore inherently unordered. An ordering\nsystem can be injected into the store by passing something which satisfies the\ndiskv.Index interface. (A default implementation, using Google's\n[btree][7] package, is provided.) Basically, diskv keeps an ordered (by a\nuser-provided Less function) index of the keys, which can be queried.\n\n[7]: https://github.com/google/btree\n\n## Adding compression\n\nSomething which implements the diskv.Compression interface may be passed\nduring store creation, so that all Writes and Reads are filtered through\na compression/decompression pipeline. Several default implementations,\nusing stdlib compression algorithms, are provided. Note that data is cached\ncompressed; the cost of decompression is borne with each Read.\n\n## Streaming\n\ndiskv also now provides ReadStream and WriteStream methods, to allow very large\ndata to be handled efficiently.\n\n\n# Future plans\n\n * Needs plenty of robust testing: huge datasets, etc...\n * More thorough benchmarking\n * Your suggestions for use-cases I haven't thought of\n"
  },
  {
    "path": "vendor/github.com/peterbourgon/diskv/compression.go",
    "content": "package diskv\n\nimport (\n\t\"compress/flate\"\n\t\"compress/gzip\"\n\t\"compress/zlib\"\n\t\"io\"\n)\n\n// Compression is an interface that Diskv uses to implement compression of\n// data. Writer takes a destination io.Writer and returns a WriteCloser that\n// compresses all data written through it. Reader takes a source io.Reader and\n// returns a ReadCloser that decompresses all data read through it. You may\n// define these methods on your own type, or use one of the NewCompression\n// helpers.\ntype Compression interface {\n\tWriter(dst io.Writer) (io.WriteCloser, error)\n\tReader(src io.Reader) (io.ReadCloser, error)\n}\n\n// NewGzipCompression returns a Gzip-based Compression.\nfunc NewGzipCompression() Compression {\n\treturn NewGzipCompressionLevel(flate.DefaultCompression)\n}\n\n// NewGzipCompressionLevel returns a Gzip-based Compression with the given level.\nfunc NewGzipCompressionLevel(level int) Compression {\n\treturn &genericCompression{\n\t\twf: func(w io.Writer) (io.WriteCloser, error) { return gzip.NewWriterLevel(w, level) },\n\t\trf: func(r io.Reader) (io.ReadCloser, error) { return gzip.NewReader(r) },\n\t}\n}\n\n// NewZlibCompression returns a Zlib-based Compression.\nfunc NewZlibCompression() Compression {\n\treturn NewZlibCompressionLevel(flate.DefaultCompression)\n}\n\n// NewZlibCompressionLevel returns a Zlib-based Compression with the given level.\nfunc NewZlibCompressionLevel(level int) Compression {\n\treturn NewZlibCompressionLevelDict(level, nil)\n}\n\n// NewZlibCompressionLevelDict returns a Zlib-based Compression with the given\n// level, based on the given dictionary.\nfunc NewZlibCompressionLevelDict(level int, dict []byte) Compression {\n\treturn &genericCompression{\n\t\tfunc(w io.Writer) (io.WriteCloser, error) { return zlib.NewWriterLevelDict(w, level, dict) },\n\t\tfunc(r io.Reader) (io.ReadCloser, error) { return zlib.NewReaderDict(r, dict) },\n\t}\n}\n\ntype genericCompression struct {\n\twf func(w io.Writer) (io.WriteCloser, error)\n\trf func(r io.Reader) (io.ReadCloser, error)\n}\n\nfunc (g *genericCompression) Writer(dst io.Writer) (io.WriteCloser, error) {\n\treturn g.wf(dst)\n}\n\nfunc (g *genericCompression) Reader(src io.Reader) (io.ReadCloser, error) {\n\treturn g.rf(src)\n}\n"
  },
  {
    "path": "vendor/github.com/peterbourgon/diskv/diskv.go",
    "content": "// Diskv (disk-vee) is a simple, persistent, key-value store.\n// It stores all data flatly on the filesystem.\n\npackage diskv\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall\"\n)\n\nconst (\n\tdefaultBasePath             = \"diskv\"\n\tdefaultFilePerm os.FileMode = 0666\n\tdefaultPathPerm os.FileMode = 0777\n)\n\nvar (\n\tdefaultTransform   = func(s string) []string { return []string{} }\n\terrCanceled        = errors.New(\"canceled\")\n\terrEmptyKey        = errors.New(\"empty key\")\n\terrBadKey          = errors.New(\"bad key\")\n\terrImportDirectory = errors.New(\"can't import a directory\")\n)\n\n// TransformFunction transforms a key into a slice of strings, with each\n// element in the slice representing a directory in the file path where the\n// key's entry will eventually be stored.\n//\n// For example, if TransformFunc transforms \"abcdef\" to [\"ab\", \"cde\", \"f\"],\n// the final location of the data file will be <basedir>/ab/cde/f/abcdef\ntype TransformFunction func(s string) []string\n\n// Options define a set of properties that dictate Diskv behavior.\n// All values are optional.\ntype Options struct {\n\tBasePath     string\n\tTransform    TransformFunction\n\tCacheSizeMax uint64 // bytes\n\tPathPerm     os.FileMode\n\tFilePerm     os.FileMode\n\t// If TempDir is set, it will enable filesystem atomic writes by\n\t// writing temporary files to that location before being moved\n\t// to BasePath.\n\t// Note that TempDir MUST be on the same device/partition as\n\t// BasePath.\n\tTempDir string\n\n\tIndex     Index\n\tIndexLess LessFunction\n\n\tCompression Compression\n}\n\n// Diskv implements the Diskv interface. You shouldn't construct Diskv\n// structures directly; instead, use the New constructor.\ntype Diskv struct {\n\tOptions\n\tmu        sync.RWMutex\n\tcache     map[string][]byte\n\tcacheSize uint64\n}\n\n// New returns an initialized Diskv structure, ready to use.\n// If the path identified by baseDir already contains data,\n// it will be accessible, but not yet cached.\nfunc New(o Options) *Diskv {\n\tif o.BasePath == \"\" {\n\t\to.BasePath = defaultBasePath\n\t}\n\tif o.Transform == nil {\n\t\to.Transform = defaultTransform\n\t}\n\tif o.PathPerm == 0 {\n\t\to.PathPerm = defaultPathPerm\n\t}\n\tif o.FilePerm == 0 {\n\t\to.FilePerm = defaultFilePerm\n\t}\n\n\td := &Diskv{\n\t\tOptions:   o,\n\t\tcache:     map[string][]byte{},\n\t\tcacheSize: 0,\n\t}\n\n\tif d.Index != nil && d.IndexLess != nil {\n\t\td.Index.Initialize(d.IndexLess, d.Keys(nil))\n\t}\n\n\treturn d\n}\n\n// Write synchronously writes the key-value pair to disk, making it immediately\n// available for reads. Write relies on the filesystem to perform an eventual\n// sync to physical media. If you need stronger guarantees, see WriteStream.\nfunc (d *Diskv) Write(key string, val []byte) error {\n\treturn d.WriteStream(key, bytes.NewBuffer(val), false)\n}\n\n// WriteStream writes the data represented by the io.Reader to the disk, under\n// the provided key. If sync is true, WriteStream performs an explicit sync on\n// the file as soon as it's written.\n//\n// bytes.Buffer provides io.Reader semantics for basic data types.\nfunc (d *Diskv) WriteStream(key string, r io.Reader, sync bool) error {\n\tif len(key) <= 0 {\n\t\treturn errEmptyKey\n\t}\n\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\n\treturn d.writeStreamWithLock(key, r, sync)\n}\n\n// createKeyFileWithLock either creates the key file directly, or\n// creates a temporary file in TempDir if it is set.\nfunc (d *Diskv) createKeyFileWithLock(key string) (*os.File, error) {\n\tif d.TempDir != \"\" {\n\t\tif err := os.MkdirAll(d.TempDir, d.PathPerm); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"temp mkdir: %s\", err)\n\t\t}\n\t\tf, err := ioutil.TempFile(d.TempDir, \"\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"temp file: %s\", err)\n\t\t}\n\n\t\tif err := f.Chmod(d.FilePerm); err != nil {\n\t\t\tf.Close()           // error deliberately ignored\n\t\t\tos.Remove(f.Name()) // error deliberately ignored\n\t\t\treturn nil, fmt.Errorf(\"chmod: %s\", err)\n\t\t}\n\t\treturn f, nil\n\t}\n\n\tmode := os.O_WRONLY | os.O_CREATE | os.O_TRUNC // overwrite if exists\n\tf, err := os.OpenFile(d.completeFilename(key), mode, d.FilePerm)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"open file: %s\", err)\n\t}\n\treturn f, nil\n}\n\n// writeStream does no input validation checking.\nfunc (d *Diskv) writeStreamWithLock(key string, r io.Reader, sync bool) error {\n\tif err := d.ensurePathWithLock(key); err != nil {\n\t\treturn fmt.Errorf(\"ensure path: %s\", err)\n\t}\n\n\tf, err := d.createKeyFileWithLock(key)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create key file: %s\", err)\n\t}\n\n\twc := io.WriteCloser(&nopWriteCloser{f})\n\tif d.Compression != nil {\n\t\twc, err = d.Compression.Writer(f)\n\t\tif err != nil {\n\t\t\tf.Close()           // error deliberately ignored\n\t\t\tos.Remove(f.Name()) // error deliberately ignored\n\t\t\treturn fmt.Errorf(\"compression writer: %s\", err)\n\t\t}\n\t}\n\n\tif _, err := io.Copy(wc, r); err != nil {\n\t\tf.Close()           // error deliberately ignored\n\t\tos.Remove(f.Name()) // error deliberately ignored\n\t\treturn fmt.Errorf(\"i/o copy: %s\", err)\n\t}\n\n\tif err := wc.Close(); err != nil {\n\t\tf.Close()           // error deliberately ignored\n\t\tos.Remove(f.Name()) // error deliberately ignored\n\t\treturn fmt.Errorf(\"compression close: %s\", err)\n\t}\n\n\tif sync {\n\t\tif err := f.Sync(); err != nil {\n\t\t\tf.Close()           // error deliberately ignored\n\t\t\tos.Remove(f.Name()) // error deliberately ignored\n\t\t\treturn fmt.Errorf(\"file sync: %s\", err)\n\t\t}\n\t}\n\n\tif err := f.Close(); err != nil {\n\t\treturn fmt.Errorf(\"file close: %s\", err)\n\t}\n\n\tif f.Name() != d.completeFilename(key) {\n\t\tif err := os.Rename(f.Name(), d.completeFilename(key)); err != nil {\n\t\t\tos.Remove(f.Name()) // error deliberately ignored\n\t\t\treturn fmt.Errorf(\"rename: %s\", err)\n\t\t}\n\t}\n\n\tif d.Index != nil {\n\t\td.Index.Insert(key)\n\t}\n\n\td.bustCacheWithLock(key) // cache only on read\n\n\treturn nil\n}\n\n// Import imports the source file into diskv under the destination key. If the\n// destination key already exists, it's overwritten. If move is true, the\n// source file is removed after a successful import.\nfunc (d *Diskv) Import(srcFilename, dstKey string, move bool) (err error) {\n\tif dstKey == \"\" {\n\t\treturn errEmptyKey\n\t}\n\n\tif fi, err := os.Stat(srcFilename); err != nil {\n\t\treturn err\n\t} else if fi.IsDir() {\n\t\treturn errImportDirectory\n\t}\n\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\n\tif err := d.ensurePathWithLock(dstKey); err != nil {\n\t\treturn fmt.Errorf(\"ensure path: %s\", err)\n\t}\n\n\tif move {\n\t\tif err := syscall.Rename(srcFilename, d.completeFilename(dstKey)); err == nil {\n\t\t\td.bustCacheWithLock(dstKey)\n\t\t\treturn nil\n\t\t} else if err != syscall.EXDEV {\n\t\t\t// If it failed due to being on a different device, fall back to copying\n\t\t\treturn err\n\t\t}\n\t}\n\n\tf, err := os.Open(srcFilename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\terr = d.writeStreamWithLock(dstKey, f, false)\n\tif err == nil && move {\n\t\terr = os.Remove(srcFilename)\n\t}\n\treturn err\n}\n\n// Read reads the key and returns the value.\n// If the key is available in the cache, Read won't touch the disk.\n// If the key is not in the cache, Read will have the side-effect of\n// lazily caching the value.\nfunc (d *Diskv) Read(key string) ([]byte, error) {\n\trc, err := d.ReadStream(key, false)\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\tdefer rc.Close()\n\treturn ioutil.ReadAll(rc)\n}\n\n// ReadStream reads the key and returns the value (data) as an io.ReadCloser.\n// If the value is cached from a previous read, and direct is false,\n// ReadStream will use the cached value. Otherwise, it will return a handle to\n// the file on disk, and cache the data on read.\n//\n// If direct is true, ReadStream will lazily delete any cached value for the\n// key, and return a direct handle to the file on disk.\n//\n// If compression is enabled, ReadStream taps into the io.Reader stream prior\n// to decompression, and caches the compressed data.\nfunc (d *Diskv) ReadStream(key string, direct bool) (io.ReadCloser, error) {\n\td.mu.RLock()\n\tdefer d.mu.RUnlock()\n\n\tif val, ok := d.cache[key]; ok {\n\t\tif !direct {\n\t\t\tbuf := bytes.NewBuffer(val)\n\t\t\tif d.Compression != nil {\n\t\t\t\treturn d.Compression.Reader(buf)\n\t\t\t}\n\t\t\treturn ioutil.NopCloser(buf), nil\n\t\t}\n\n\t\tgo func() {\n\t\t\td.mu.Lock()\n\t\t\tdefer d.mu.Unlock()\n\t\t\td.uncacheWithLock(key, uint64(len(val)))\n\t\t}()\n\t}\n\n\treturn d.readWithRLock(key)\n}\n\n// read ignores the cache, and returns an io.ReadCloser representing the\n// decompressed data for the given key, streamed from the disk. Clients should\n// acquire a read lock on the Diskv and check the cache themselves before\n// calling read.\nfunc (d *Diskv) readWithRLock(key string) (io.ReadCloser, error) {\n\tfilename := d.completeFilename(key)\n\n\tfi, err := os.Stat(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif fi.IsDir() {\n\t\treturn nil, os.ErrNotExist\n\t}\n\n\tf, err := os.Open(filename)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar r io.Reader\n\tif d.CacheSizeMax > 0 {\n\t\tr = newSiphon(f, d, key)\n\t} else {\n\t\tr = &closingReader{f}\n\t}\n\n\tvar rc = io.ReadCloser(ioutil.NopCloser(r))\n\tif d.Compression != nil {\n\t\trc, err = d.Compression.Reader(r)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn rc, nil\n}\n\n// closingReader provides a Reader that automatically closes the\n// embedded ReadCloser when it reaches EOF\ntype closingReader struct {\n\trc io.ReadCloser\n}\n\nfunc (cr closingReader) Read(p []byte) (int, error) {\n\tn, err := cr.rc.Read(p)\n\tif err == io.EOF {\n\t\tif closeErr := cr.rc.Close(); closeErr != nil {\n\t\t\treturn n, closeErr // close must succeed for Read to succeed\n\t\t}\n\t}\n\treturn n, err\n}\n\n// siphon is like a TeeReader: it copies all data read through it to an\n// internal buffer, and moves that buffer to the cache at EOF.\ntype siphon struct {\n\tf   *os.File\n\td   *Diskv\n\tkey string\n\tbuf *bytes.Buffer\n}\n\n// newSiphon constructs a siphoning reader that represents the passed file.\n// When a successful series of reads ends in an EOF, the siphon will write\n// the buffered data to Diskv's cache under the given key.\nfunc newSiphon(f *os.File, d *Diskv, key string) io.Reader {\n\treturn &siphon{\n\t\tf:   f,\n\t\td:   d,\n\t\tkey: key,\n\t\tbuf: &bytes.Buffer{},\n\t}\n}\n\n// Read implements the io.Reader interface for siphon.\nfunc (s *siphon) Read(p []byte) (int, error) {\n\tn, err := s.f.Read(p)\n\n\tif err == nil {\n\t\treturn s.buf.Write(p[0:n]) // Write must succeed for Read to succeed\n\t}\n\n\tif err == io.EOF {\n\t\ts.d.cacheWithoutLock(s.key, s.buf.Bytes()) // cache may fail\n\t\tif closeErr := s.f.Close(); closeErr != nil {\n\t\t\treturn n, closeErr // close must succeed for Read to succeed\n\t\t}\n\t\treturn n, err\n\t}\n\n\treturn n, err\n}\n\n// Erase synchronously erases the given key from the disk and the cache.\nfunc (d *Diskv) Erase(key string) error {\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\n\td.bustCacheWithLock(key)\n\n\t// erase from index\n\tif d.Index != nil {\n\t\td.Index.Delete(key)\n\t}\n\n\t// erase from disk\n\tfilename := d.completeFilename(key)\n\tif s, err := os.Stat(filename); err == nil {\n\t\tif s.IsDir() {\n\t\t\treturn errBadKey\n\t\t}\n\t\tif err = os.Remove(filename); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// Return err as-is so caller can do os.IsNotExist(err).\n\t\treturn err\n\t}\n\n\t// clean up and return\n\td.pruneDirsWithLock(key)\n\treturn nil\n}\n\n// EraseAll will delete all of the data from the store, both in the cache and on\n// the disk. Note that EraseAll doesn't distinguish diskv-related data from non-\n// diskv-related data. Care should be taken to always specify a diskv base\n// directory that is exclusively for diskv data.\nfunc (d *Diskv) EraseAll() error {\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\td.cache = make(map[string][]byte)\n\td.cacheSize = 0\n\tif d.TempDir != \"\" {\n\t\tos.RemoveAll(d.TempDir) // errors ignored\n\t}\n\treturn os.RemoveAll(d.BasePath)\n}\n\n// Has returns true if the given key exists.\nfunc (d *Diskv) Has(key string) bool {\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\n\tif _, ok := d.cache[key]; ok {\n\t\treturn true\n\t}\n\n\tfilename := d.completeFilename(key)\n\ts, err := os.Stat(filename)\n\tif err != nil {\n\t\treturn false\n\t}\n\tif s.IsDir() {\n\t\treturn false\n\t}\n\n\treturn true\n}\n\n// Keys returns a channel that will yield every key accessible by the store,\n// in undefined order. If a cancel channel is provided, closing it will\n// terminate and close the keys channel.\nfunc (d *Diskv) Keys(cancel <-chan struct{}) <-chan string {\n\treturn d.KeysPrefix(\"\", cancel)\n}\n\n// KeysPrefix returns a channel that will yield every key accessible by the\n// store with the given prefix, in undefined order. If a cancel channel is\n// provided, closing it will terminate and close the keys channel. If the\n// provided prefix is the empty string, all keys will be yielded.\nfunc (d *Diskv) KeysPrefix(prefix string, cancel <-chan struct{}) <-chan string {\n\tvar prepath string\n\tif prefix == \"\" {\n\t\tprepath = d.BasePath\n\t} else {\n\t\tprepath = d.pathFor(prefix)\n\t}\n\tc := make(chan string)\n\tgo func() {\n\t\tfilepath.Walk(prepath, walker(c, prefix, cancel))\n\t\tclose(c)\n\t}()\n\treturn c\n}\n\n// walker returns a function which satisfies the filepath.WalkFunc interface.\n// It sends every non-directory file entry down the channel c.\nfunc walker(c chan<- string, prefix string, cancel <-chan struct{}) filepath.WalkFunc {\n\treturn func(path string, info os.FileInfo, err error) error {\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif info.IsDir() || !strings.HasPrefix(info.Name(), prefix) {\n\t\t\treturn nil // \"pass\"\n\t\t}\n\n\t\tselect {\n\t\tcase c <- info.Name():\n\t\tcase <-cancel:\n\t\t\treturn errCanceled\n\t\t}\n\n\t\treturn nil\n\t}\n}\n\n// pathFor returns the absolute path for location on the filesystem where the\n// data for the given key will be stored.\nfunc (d *Diskv) pathFor(key string) string {\n\treturn filepath.Join(d.BasePath, filepath.Join(d.Transform(key)...))\n}\n\n// ensurePathWithLock is a helper function that generates all necessary\n// directories on the filesystem for the given key.\nfunc (d *Diskv) ensurePathWithLock(key string) error {\n\treturn os.MkdirAll(d.pathFor(key), d.PathPerm)\n}\n\n// completeFilename returns the absolute path to the file for the given key.\nfunc (d *Diskv) completeFilename(key string) string {\n\treturn filepath.Join(d.pathFor(key), key)\n}\n\n// cacheWithLock attempts to cache the given key-value pair in the store's\n// cache. It can fail if the value is larger than the cache's maximum size.\nfunc (d *Diskv) cacheWithLock(key string, val []byte) error {\n\tvalueSize := uint64(len(val))\n\tif err := d.ensureCacheSpaceWithLock(valueSize); err != nil {\n\t\treturn fmt.Errorf(\"%s; not caching\", err)\n\t}\n\n\t// be very strict about memory guarantees\n\tif (d.cacheSize + valueSize) > d.CacheSizeMax {\n\t\tpanic(fmt.Sprintf(\"failed to make room for value (%d/%d)\", valueSize, d.CacheSizeMax))\n\t}\n\n\td.cache[key] = val\n\td.cacheSize += valueSize\n\treturn nil\n}\n\n// cacheWithoutLock acquires the store's (write) mutex and calls cacheWithLock.\nfunc (d *Diskv) cacheWithoutLock(key string, val []byte) error {\n\td.mu.Lock()\n\tdefer d.mu.Unlock()\n\treturn d.cacheWithLock(key, val)\n}\n\nfunc (d *Diskv) bustCacheWithLock(key string) {\n\tif val, ok := d.cache[key]; ok {\n\t\td.uncacheWithLock(key, uint64(len(val)))\n\t}\n}\n\nfunc (d *Diskv) uncacheWithLock(key string, sz uint64) {\n\td.cacheSize -= sz\n\tdelete(d.cache, key)\n}\n\n// pruneDirsWithLock deletes empty directories in the path walk leading to the\n// key k. Typically this function is called after an Erase is made.\nfunc (d *Diskv) pruneDirsWithLock(key string) error {\n\tpathlist := d.Transform(key)\n\tfor i := range pathlist {\n\t\tdir := filepath.Join(d.BasePath, filepath.Join(pathlist[:len(pathlist)-i]...))\n\n\t\t// thanks to Steven Blenkinsop for this snippet\n\t\tswitch fi, err := os.Stat(dir); true {\n\t\tcase err != nil:\n\t\t\treturn err\n\t\tcase !fi.IsDir():\n\t\t\tpanic(fmt.Sprintf(\"corrupt dirstate at %s\", dir))\n\t\t}\n\n\t\tnlinks, err := filepath.Glob(filepath.Join(dir, \"*\"))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t} else if len(nlinks) > 0 {\n\t\t\treturn nil // has subdirs -- do not prune\n\t\t}\n\t\tif err = os.Remove(dir); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// ensureCacheSpaceWithLock deletes entries from the cache in arbitrary order\n// until the cache has at least valueSize bytes available.\nfunc (d *Diskv) ensureCacheSpaceWithLock(valueSize uint64) error {\n\tif valueSize > d.CacheSizeMax {\n\t\treturn fmt.Errorf(\"value size (%d bytes) too large for cache (%d bytes)\", valueSize, d.CacheSizeMax)\n\t}\n\n\tsafe := func() bool { return (d.cacheSize + valueSize) <= d.CacheSizeMax }\n\n\tfor key, val := range d.cache {\n\t\tif safe() {\n\t\t\tbreak\n\t\t}\n\n\t\td.uncacheWithLock(key, uint64(len(val)))\n\t}\n\n\tif !safe() {\n\t\tpanic(fmt.Sprintf(\"%d bytes still won't fit in the cache! (max %d bytes)\", valueSize, d.CacheSizeMax))\n\t}\n\n\treturn nil\n}\n\n// nopWriteCloser wraps an io.Writer and provides a no-op Close method to\n// satisfy the io.WriteCloser interface.\ntype nopWriteCloser struct {\n\tio.Writer\n}\n\nfunc (wc *nopWriteCloser) Write(p []byte) (int, error) { return wc.Writer.Write(p) }\nfunc (wc *nopWriteCloser) Close() error                { return nil }\n"
  },
  {
    "path": "vendor/github.com/peterbourgon/diskv/index.go",
    "content": "package diskv\n\nimport (\n\t\"sync\"\n\n\t\"github.com/google/btree\"\n)\n\n// Index is a generic interface for things that can\n// provide an ordered list of keys.\ntype Index interface {\n\tInitialize(less LessFunction, keys <-chan string)\n\tInsert(key string)\n\tDelete(key string)\n\tKeys(from string, n int) []string\n}\n\n// LessFunction is used to initialize an Index of keys in a specific order.\ntype LessFunction func(string, string) bool\n\n// btreeString is a custom data type that satisfies the BTree Less interface,\n// making the strings it wraps sortable by the BTree package.\ntype btreeString struct {\n\ts string\n\tl LessFunction\n}\n\n// Less satisfies the BTree.Less interface using the btreeString's LessFunction.\nfunc (s btreeString) Less(i btree.Item) bool {\n\treturn s.l(s.s, i.(btreeString).s)\n}\n\n// BTreeIndex is an implementation of the Index interface using google/btree.\ntype BTreeIndex struct {\n\tsync.RWMutex\n\tLessFunction\n\t*btree.BTree\n}\n\n// Initialize populates the BTree tree with data from the keys channel,\n// according to the passed less function. It's destructive to the BTreeIndex.\nfunc (i *BTreeIndex) Initialize(less LessFunction, keys <-chan string) {\n\ti.Lock()\n\tdefer i.Unlock()\n\ti.LessFunction = less\n\ti.BTree = rebuild(less, keys)\n}\n\n// Insert inserts the given key (only) into the BTree tree.\nfunc (i *BTreeIndex) Insert(key string) {\n\ti.Lock()\n\tdefer i.Unlock()\n\tif i.BTree == nil || i.LessFunction == nil {\n\t\tpanic(\"uninitialized index\")\n\t}\n\ti.BTree.ReplaceOrInsert(btreeString{s: key, l: i.LessFunction})\n}\n\n// Delete removes the given key (only) from the BTree tree.\nfunc (i *BTreeIndex) Delete(key string) {\n\ti.Lock()\n\tdefer i.Unlock()\n\tif i.BTree == nil || i.LessFunction == nil {\n\t\tpanic(\"uninitialized index\")\n\t}\n\ti.BTree.Delete(btreeString{s: key, l: i.LessFunction})\n}\n\n// Keys yields a maximum of n keys in order. If the passed 'from' key is empty,\n// Keys will return the first n keys. If the passed 'from' key is non-empty, the\n// first key in the returned slice will be the key that immediately follows the\n// passed key, in key order.\nfunc (i *BTreeIndex) Keys(from string, n int) []string {\n\ti.RLock()\n\tdefer i.RUnlock()\n\n\tif i.BTree == nil || i.LessFunction == nil {\n\t\tpanic(\"uninitialized index\")\n\t}\n\n\tif i.BTree.Len() <= 0 {\n\t\treturn []string{}\n\t}\n\n\tbtreeFrom := btreeString{s: from, l: i.LessFunction}\n\tskipFirst := true\n\tif len(from) <= 0 || !i.BTree.Has(btreeFrom) {\n\t\t// no such key, so fabricate an always-smallest item\n\t\tbtreeFrom = btreeString{s: \"\", l: func(string, string) bool { return true }}\n\t\tskipFirst = false\n\t}\n\n\tkeys := []string{}\n\titerator := func(i btree.Item) bool {\n\t\tkeys = append(keys, i.(btreeString).s)\n\t\treturn len(keys) < n\n\t}\n\ti.BTree.AscendGreaterOrEqual(btreeFrom, iterator)\n\n\tif skipFirst && len(keys) > 0 {\n\t\tkeys = keys[1:]\n\t}\n\n\treturn keys\n}\n\n// rebuildIndex does the work of regenerating the index\n// with the given keys.\nfunc rebuild(less LessFunction, keys <-chan string) *btree.BTree {\n\ttree := btree.New(2)\n\tfor key := range keys {\n\t\ttree.ReplaceOrInsert(btreeString{s: key, l: less})\n\t}\n\treturn tree\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\n*.test\n*.prof\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/.travis.yml",
    "content": "language: go\ngo_import_path: github.com/pkg/errors\ngo:\n  - 1.11.x\n  - 1.12.x\n  - 1.13.x\n  - tip\n\nscript:\n  - make check\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/LICENSE",
    "content": "Copyright (c) 2015, Dave Cheney <dave@cheney.net>\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (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": "vendor/github.com/pkg/errors/Makefile",
    "content": "PKGS := github.com/pkg/errors\nSRCDIRS := $(shell go list -f '{{.Dir}}' $(PKGS))\nGO := go\n\ncheck: test vet gofmt misspell unconvert staticcheck ineffassign unparam\n\ntest: \n\t$(GO) test $(PKGS)\n\nvet: | test\n\t$(GO) vet $(PKGS)\n\nstaticcheck:\n\t$(GO) get honnef.co/go/tools/cmd/staticcheck\n\tstaticcheck -checks all $(PKGS)\n\nmisspell:\n\t$(GO) get github.com/client9/misspell/cmd/misspell\n\tmisspell \\\n\t\t-locale GB \\\n\t\t-error \\\n\t\t*.md *.go\n\nunconvert:\n\t$(GO) get github.com/mdempsky/unconvert\n\tunconvert -v $(PKGS)\n\nineffassign:\n\t$(GO) get github.com/gordonklaus/ineffassign\n\tfind $(SRCDIRS) -name '*.go' | xargs ineffassign\n\npedantic: check errcheck\n\nunparam:\n\t$(GO) get mvdan.cc/unparam\n\tunparam ./...\n\nerrcheck:\n\t$(GO) get github.com/kisielk/errcheck\n\terrcheck $(PKGS)\n\ngofmt:  \n\t@echo Checking code is gofmted\n\t@test -z \"$(shell gofmt -s -l -d -e $(SRCDIRS) | tee /dev/stderr)\"\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/README.md",
    "content": "# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge)\n\nPackage errors provides simple error handling primitives.\n\n`go get github.com/pkg/errors`\n\nThe traditional error handling idiom in Go is roughly akin to\n```go\nif err != nil {\n        return err\n}\n```\nwhich applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.\n\n## Adding context to an error\n\nThe errors.Wrap function returns a new error that adds context to the original error. For example\n```go\n_, err := ioutil.ReadAll(r)\nif err != nil {\n        return errors.Wrap(err, \"read failed\")\n}\n```\n## Retrieving the cause of an error\n\nUsing `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.\n```go\ntype causer interface {\n        Cause() error\n}\n```\n`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:\n```go\nswitch err := errors.Cause(err).(type) {\ncase *MyError:\n        // handle specifically\ndefault:\n        // unknown error\n}\n```\n\n[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).\n\n## Roadmap\n\nWith the upcoming [Go2 error proposals](https://go.googlesource.com/proposal/+/master/design/go2draft.md) this package is moving into maintenance mode. The roadmap for a 1.0 release is as follows:\n\n- 0.9. Remove pre Go 1.9 and Go 1.10 support, address outstanding pull requests (if possible)\n- 1.0. Final release.\n\n## Contributing\n\nBecause of the Go2 errors changes, this package is not accepting proposals for new functionality. With that said, we welcome pull requests, bug fixes and issue reports. \n\nBefore sending a PR, please discuss your change by raising an issue.\n\n## License\n\nBSD-2-Clause\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/appveyor.yml",
    "content": "version: build-{build}.{branch}\n\nclone_folder: C:\\gopath\\src\\github.com\\pkg\\errors\nshallow_clone: true # for startup speed\n\nenvironment:\n  GOPATH: C:\\gopath\n\nplatform:\n  - x64\n\n# http://www.appveyor.com/docs/installed-software\ninstall:\n  # some helpful output for debugging builds\n  - go version\n  - go env\n  # pre-installed MinGW at C:\\MinGW is 32bit only\n  # but MSYS2 at C:\\msys64 has mingw64\n  - set PATH=C:\\msys64\\mingw64\\bin;%PATH%\n  - gcc --version\n  - g++ --version\n\nbuild_script:\n  - go install -v ./...\n\ntest_script:\n  - set PATH=C:\\gopath\\bin;%PATH%\n  - go test -v ./...\n\n#artifacts:\n#  - path: '%GOPATH%\\bin\\*.exe'\ndeploy: off\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/errors.go",
    "content": "// Package errors provides simple error handling primitives.\n//\n// The traditional error handling idiom in Go is roughly akin to\n//\n//     if err != nil {\n//             return err\n//     }\n//\n// which when applied recursively up the call stack results in error reports\n// without context or debugging information. The errors package allows\n// programmers to add context to the failure path in their code in a way\n// that does not destroy the original value of the error.\n//\n// Adding context to an error\n//\n// The errors.Wrap function returns a new error that adds context to the\n// original error by recording a stack trace at the point Wrap is called,\n// together with the supplied message. For example\n//\n//     _, err := ioutil.ReadAll(r)\n//     if err != nil {\n//             return errors.Wrap(err, \"read failed\")\n//     }\n//\n// If additional control is required, the errors.WithStack and\n// errors.WithMessage functions destructure errors.Wrap into its component\n// operations: annotating an error with a stack trace and with a message,\n// respectively.\n//\n// Retrieving the cause of an error\n//\n// Using errors.Wrap constructs a stack of errors, adding context to the\n// preceding error. Depending on the nature of the error it may be necessary\n// to reverse the operation of errors.Wrap to retrieve the original error\n// for inspection. Any error value which implements this interface\n//\n//     type causer interface {\n//             Cause() error\n//     }\n//\n// can be inspected by errors.Cause. errors.Cause will recursively retrieve\n// the topmost error that does not implement causer, which is assumed to be\n// the original cause. For example:\n//\n//     switch err := errors.Cause(err).(type) {\n//     case *MyError:\n//             // handle specifically\n//     default:\n//             // unknown error\n//     }\n//\n// Although the causer interface is not exported by this package, it is\n// considered a part of its stable public interface.\n//\n// Formatted printing of errors\n//\n// All error values returned from this package implement fmt.Formatter and can\n// be formatted by the fmt package. The following verbs are supported:\n//\n//     %s    print the error. If the error has a Cause it will be\n//           printed recursively.\n//     %v    see %s\n//     %+v   extended format. Each Frame of the error's StackTrace will\n//           be printed in detail.\n//\n// Retrieving the stack trace of an error or wrapper\n//\n// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are\n// invoked. This information can be retrieved with the following interface:\n//\n//     type stackTracer interface {\n//             StackTrace() errors.StackTrace\n//     }\n//\n// The returned errors.StackTrace type is defined as\n//\n//     type StackTrace []Frame\n//\n// The Frame type represents a call site in the stack trace. Frame supports\n// the fmt.Formatter interface that can be used for printing information about\n// the stack trace of this error. For example:\n//\n//     if err, ok := err.(stackTracer); ok {\n//             for _, f := range err.StackTrace() {\n//                     fmt.Printf(\"%+s:%d\\n\", f, f)\n//             }\n//     }\n//\n// Although the stackTracer interface is not exported by this package, it is\n// considered a part of its stable public interface.\n//\n// See the documentation for Frame.Format for more details.\npackage errors\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// New returns an error with the supplied message.\n// New also records the stack trace at the point it was called.\nfunc New(message string) error {\n\treturn &fundamental{\n\t\tmsg:   message,\n\t\tstack: callers(),\n\t}\n}\n\n// Errorf formats according to a format specifier and returns the string\n// as a value that satisfies error.\n// Errorf also records the stack trace at the point it was called.\nfunc Errorf(format string, args ...interface{}) error {\n\treturn &fundamental{\n\t\tmsg:   fmt.Sprintf(format, args...),\n\t\tstack: callers(),\n\t}\n}\n\n// fundamental is an error that has a message and a stack, but no caller.\ntype fundamental struct {\n\tmsg string\n\t*stack\n}\n\nfunc (f *fundamental) Error() string { return f.msg }\n\nfunc (f *fundamental) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tif s.Flag('+') {\n\t\t\tio.WriteString(s, f.msg)\n\t\t\tf.stack.Format(s, verb)\n\t\t\treturn\n\t\t}\n\t\tfallthrough\n\tcase 's':\n\t\tio.WriteString(s, f.msg)\n\tcase 'q':\n\t\tfmt.Fprintf(s, \"%q\", f.msg)\n\t}\n}\n\n// WithStack annotates err with a stack trace at the point WithStack was called.\n// If err is nil, WithStack returns nil.\nfunc WithStack(err error) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\treturn &withStack{\n\t\terr,\n\t\tcallers(),\n\t}\n}\n\ntype withStack struct {\n\terror\n\t*stack\n}\n\nfunc (w *withStack) Cause() error { return w.error }\n\n// Unwrap provides compatibility for Go 1.13 error chains.\nfunc (w *withStack) Unwrap() error { return w.error }\n\nfunc (w *withStack) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tif s.Flag('+') {\n\t\t\tfmt.Fprintf(s, \"%+v\", w.Cause())\n\t\t\tw.stack.Format(s, verb)\n\t\t\treturn\n\t\t}\n\t\tfallthrough\n\tcase 's':\n\t\tio.WriteString(s, w.Error())\n\tcase 'q':\n\t\tfmt.Fprintf(s, \"%q\", w.Error())\n\t}\n}\n\n// Wrap returns an error annotating err with a stack trace\n// at the point Wrap is called, and the supplied message.\n// If err is nil, Wrap returns nil.\nfunc Wrap(err error, message string) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\terr = &withMessage{\n\t\tcause: err,\n\t\tmsg:   message,\n\t}\n\treturn &withStack{\n\t\terr,\n\t\tcallers(),\n\t}\n}\n\n// Wrapf returns an error annotating err with a stack trace\n// at the point Wrapf is called, and the format specifier.\n// If err is nil, Wrapf returns nil.\nfunc Wrapf(err error, format string, args ...interface{}) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\terr = &withMessage{\n\t\tcause: err,\n\t\tmsg:   fmt.Sprintf(format, args...),\n\t}\n\treturn &withStack{\n\t\terr,\n\t\tcallers(),\n\t}\n}\n\n// WithMessage annotates err with a new message.\n// If err is nil, WithMessage returns nil.\nfunc WithMessage(err error, message string) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\treturn &withMessage{\n\t\tcause: err,\n\t\tmsg:   message,\n\t}\n}\n\n// WithMessagef annotates err with the format specifier.\n// If err is nil, WithMessagef returns nil.\nfunc WithMessagef(err error, format string, args ...interface{}) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\treturn &withMessage{\n\t\tcause: err,\n\t\tmsg:   fmt.Sprintf(format, args...),\n\t}\n}\n\ntype withMessage struct {\n\tcause error\n\tmsg   string\n}\n\nfunc (w *withMessage) Error() string { return w.msg + \": \" + w.cause.Error() }\nfunc (w *withMessage) Cause() error  { return w.cause }\n\n// Unwrap provides compatibility for Go 1.13 error chains.\nfunc (w *withMessage) Unwrap() error { return w.cause }\n\nfunc (w *withMessage) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tif s.Flag('+') {\n\t\t\tfmt.Fprintf(s, \"%+v\\n\", w.Cause())\n\t\t\tio.WriteString(s, w.msg)\n\t\t\treturn\n\t\t}\n\t\tfallthrough\n\tcase 's', 'q':\n\t\tio.WriteString(s, w.Error())\n\t}\n}\n\n// Cause returns the underlying cause of the error, if possible.\n// An error value has a cause if it implements the following\n// interface:\n//\n//     type causer interface {\n//            Cause() error\n//     }\n//\n// If the error does not implement Cause, the original error will\n// be returned. If the error is nil, nil will be returned without further\n// investigation.\nfunc Cause(err error) error {\n\ttype causer interface {\n\t\tCause() error\n\t}\n\n\tfor err != nil {\n\t\tcause, ok := err.(causer)\n\t\tif !ok {\n\t\t\tbreak\n\t\t}\n\t\terr = cause.Cause()\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/go113.go",
    "content": "// +build go1.13\n\npackage errors\n\nimport (\n\tstderrors \"errors\"\n)\n\n// Is reports whether any error in err's chain matches target.\n//\n// The chain consists of err itself followed by the sequence of errors obtained by\n// repeatedly calling Unwrap.\n//\n// An error is considered to match a target if it is equal to that target or if\n// it implements a method Is(error) bool such that Is(target) returns true.\nfunc Is(err, target error) bool { return stderrors.Is(err, target) }\n\n// As finds the first error in err's chain that matches target, and if so, sets\n// target to that error value and returns true.\n//\n// The chain consists of err itself followed by the sequence of errors obtained by\n// repeatedly calling Unwrap.\n//\n// An error matches target if the error's concrete value is assignable to the value\n// pointed to by target, or if the error has a method As(interface{}) bool such that\n// As(target) returns true. In the latter case, the As method is responsible for\n// setting target.\n//\n// As will panic if target is not a non-nil pointer to either a type that implements\n// error, or to any interface type. As returns false if err is nil.\nfunc As(err error, target interface{}) bool { return stderrors.As(err, target) }\n\n// Unwrap returns the result of calling the Unwrap method on err, if err's\n// type contains an Unwrap method returning error.\n// Otherwise, Unwrap returns nil.\nfunc Unwrap(err error) error {\n\treturn stderrors.Unwrap(err)\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/errors/stack.go",
    "content": "package errors\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// Frame represents a program counter inside a stack frame.\n// For historical reasons if Frame is interpreted as a uintptr\n// its value represents the program counter + 1.\ntype Frame uintptr\n\n// pc returns the program counter for this frame;\n// multiple frames may have the same PC value.\nfunc (f Frame) pc() uintptr { return uintptr(f) - 1 }\n\n// file returns the full path to the file that contains the\n// function for this Frame's pc.\nfunc (f Frame) file() string {\n\tfn := runtime.FuncForPC(f.pc())\n\tif fn == nil {\n\t\treturn \"unknown\"\n\t}\n\tfile, _ := fn.FileLine(f.pc())\n\treturn file\n}\n\n// line returns the line number of source code of the\n// function for this Frame's pc.\nfunc (f Frame) line() int {\n\tfn := runtime.FuncForPC(f.pc())\n\tif fn == nil {\n\t\treturn 0\n\t}\n\t_, line := fn.FileLine(f.pc())\n\treturn line\n}\n\n// name returns the name of this function, if known.\nfunc (f Frame) name() string {\n\tfn := runtime.FuncForPC(f.pc())\n\tif fn == nil {\n\t\treturn \"unknown\"\n\t}\n\treturn fn.Name()\n}\n\n// Format formats the frame according to the fmt.Formatter interface.\n//\n//    %s    source file\n//    %d    source line\n//    %n    function name\n//    %v    equivalent to %s:%d\n//\n// Format accepts flags that alter the printing of some verbs, as follows:\n//\n//    %+s   function name and path of source file relative to the compile time\n//          GOPATH separated by \\n\\t (<funcname>\\n\\t<path>)\n//    %+v   equivalent to %+s:%d\nfunc (f Frame) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 's':\n\t\tswitch {\n\t\tcase s.Flag('+'):\n\t\t\tio.WriteString(s, f.name())\n\t\t\tio.WriteString(s, \"\\n\\t\")\n\t\t\tio.WriteString(s, f.file())\n\t\tdefault:\n\t\t\tio.WriteString(s, path.Base(f.file()))\n\t\t}\n\tcase 'd':\n\t\tio.WriteString(s, strconv.Itoa(f.line()))\n\tcase 'n':\n\t\tio.WriteString(s, funcname(f.name()))\n\tcase 'v':\n\t\tf.Format(s, 's')\n\t\tio.WriteString(s, \":\")\n\t\tf.Format(s, 'd')\n\t}\n}\n\n// MarshalText formats a stacktrace Frame as a text string. The output is the\n// same as that of fmt.Sprintf(\"%+v\", f), but without newlines or tabs.\nfunc (f Frame) MarshalText() ([]byte, error) {\n\tname := f.name()\n\tif name == \"unknown\" {\n\t\treturn []byte(name), nil\n\t}\n\treturn []byte(fmt.Sprintf(\"%s %s:%d\", name, f.file(), f.line())), nil\n}\n\n// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).\ntype StackTrace []Frame\n\n// Format formats the stack of Frames according to the fmt.Formatter interface.\n//\n//    %s\tlists source files for each Frame in the stack\n//    %v\tlists the source file and line number for each Frame in the stack\n//\n// Format accepts flags that alter the printing of some verbs, as follows:\n//\n//    %+v   Prints filename, function, and line number for each Frame in the stack.\nfunc (st StackTrace) Format(s fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tswitch {\n\t\tcase s.Flag('+'):\n\t\t\tfor _, f := range st {\n\t\t\t\tio.WriteString(s, \"\\n\")\n\t\t\t\tf.Format(s, verb)\n\t\t\t}\n\t\tcase s.Flag('#'):\n\t\t\tfmt.Fprintf(s, \"%#v\", []Frame(st))\n\t\tdefault:\n\t\t\tst.formatSlice(s, verb)\n\t\t}\n\tcase 's':\n\t\tst.formatSlice(s, verb)\n\t}\n}\n\n// formatSlice will format this StackTrace into the given buffer as a slice of\n// Frame, only valid when called with '%s' or '%v'.\nfunc (st StackTrace) formatSlice(s fmt.State, verb rune) {\n\tio.WriteString(s, \"[\")\n\tfor i, f := range st {\n\t\tif i > 0 {\n\t\t\tio.WriteString(s, \" \")\n\t\t}\n\t\tf.Format(s, verb)\n\t}\n\tio.WriteString(s, \"]\")\n}\n\n// stack represents a stack of program counters.\ntype stack []uintptr\n\nfunc (s *stack) Format(st fmt.State, verb rune) {\n\tswitch verb {\n\tcase 'v':\n\t\tswitch {\n\t\tcase st.Flag('+'):\n\t\t\tfor _, pc := range *s {\n\t\t\t\tf := Frame(pc)\n\t\t\t\tfmt.Fprintf(st, \"\\n%+v\", f)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (s *stack) StackTrace() StackTrace {\n\tf := make([]Frame, len(*s))\n\tfor i := 0; i < len(f); i++ {\n\t\tf[i] = Frame((*s)[i])\n\t}\n\treturn f\n}\n\nfunc callers() *stack {\n\tconst depth = 32\n\tvar pcs [depth]uintptr\n\tn := runtime.Callers(3, pcs[:])\n\tvar st stack = pcs[0:n]\n\treturn &st\n}\n\n// funcname removes the path prefix component of a function's name reported by func.Name().\nfunc funcname(name string) string {\n\ti := strings.LastIndex(name, \"/\")\n\tname = name[i+1:]\n\ti = strings.Index(name, \".\")\n\treturn name[i+1:]\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/LICENSE",
    "content": "Copyright (c) 2014, David Cheney\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/doc.go",
    "content": "// Package termios implements the low level termios(3) terminal line discipline facilities.\n//\n// For a higher level interface please use the github.com/pkg/term package.\npackage termios\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/ioctl.go",
    "content": "// +build !windows,!solaris\n\npackage termios\n\nimport \"syscall\"\n\nfunc ioctl(fd, request, argp uintptr) error {\n\tif _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, fd, request, argp, 0, 0, 0); e != 0 {\n\t\treturn e\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/ioctl_darwin.go",
    "content": "package termios\n\nconst (\n\t_IOC_PARAM_SHIFT = 13\n\t_IOC_PARAM_MASK  = (1 << _IOC_PARAM_SHIFT) - 1\n)\n\nfunc _IOC_PARM_LEN(ioctl uintptr) uintptr {\n\treturn (ioctl >> 16) & _IOC_PARAM_MASK\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/ioctl_solaris.go",
    "content": "package termios\n\nimport \"golang.org/x/sys/unix\"\n\nfunc ioctl(fd, request, argp uintptr) error {\n\treturn unix.IoctlSetInt(int(fd), uint(request), int(argp))\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/pty.go",
    "content": "// +build !windows\n\npackage termios\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"syscall\"\n)\n\nfunc open_device(path string) (uintptr, error) {\n\tfd, err := syscall.Open(path, syscall.O_NOCTTY|syscall.O_RDWR|syscall.O_CLOEXEC, 0666)\n\tif err != nil {\n\t\treturn 0, fmt.Errorf(\"unable to open %q: %v\", path, err)\n\t}\n\treturn uintptr(fd), nil\n}\n\n// Pty returns a UNIX 98 pseudoterminal device.\n// Pty returns a pair of fds representing the master and slave pair.\nfunc Pty() (*os.File, *os.File, error) {\n\tptm, err := open_pty_master()\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tsname, err := Ptsname(ptm)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\terr = grantpt(ptm)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\terr = unlockpt(ptm)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tpts, err := open_device(sname)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn os.NewFile(uintptr(ptm), \"ptm\"), os.NewFile(uintptr(pts), sname), nil\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/pty_bsd.go",
    "content": "// +build dragonfly openbsd\n\npackage termios\n\n// #include<stdlib.h>\nimport \"C\"\n\nimport \"syscall\"\n\nfunc open_pty_master() (uintptr, error) {\n\trc := C.posix_openpt(syscall.O_NOCTTY | syscall.O_RDWR)\n\tif rc < 0 {\n\t\treturn 0, syscall.Errno(rc)\n\t}\n\treturn uintptr(rc), nil\n}\n\nfunc Ptsname(fd uintptr) (string, error) {\n\tslavename := C.GoString(C.ptsname(C.int(fd)))\n\treturn slavename, nil\n}\n\nfunc grantpt(fd uintptr) error {\n\trc := C.grantpt(C.int(fd))\n\tif rc == 0 {\n\t\treturn nil\n\t}\n\treturn syscall.Errno(rc)\n}\n\nfunc unlockpt(fd uintptr) error {\n\trc := C.unlockpt(C.int(fd))\n\tif rc == 0 {\n\t\treturn nil\n\t}\n\treturn syscall.Errno(rc)\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/pty_darwin.go",
    "content": "package termios\n\nimport (\n\t\"errors\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc open_pty_master() (uintptr, error) {\n\treturn open_device(\"/dev/ptmx\")\n}\n\nfunc Ptsname(fd uintptr) (string, error) {\n\tn := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))\n\n\terr := ioctl(fd, syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tfor i, c := range n {\n\t\tif c == 0 {\n\t\t\treturn string(n[:i]), nil\n\t\t}\n\t}\n\treturn \"\", errors.New(\"TIOCPTYGNAME string not NUL-terminated\")\n}\n\nfunc grantpt(fd uintptr) error {\n\treturn ioctl(fd, syscall.TIOCPTYGRANT, 0)\n}\n\nfunc unlockpt(fd uintptr) error {\n\treturn ioctl(fd, syscall.TIOCPTYUNLK, 0)\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/pty_freebsd.go",
    "content": "package termios\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc posix_openpt(oflag int) (fd uintptr, err error) {\n\t// Copied from debian-golang-pty/pty_freebsd.go.\n\tr0, _, e1 := syscall.Syscall(syscall.SYS_POSIX_OPENPT, uintptr(oflag), 0, 0)\n\tfd = uintptr(r0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc open_pty_master() (uintptr, error) {\n\treturn posix_openpt(syscall.O_NOCTTY|syscall.O_RDWR|syscall.O_CLOEXEC)\n}\n\nfunc Ptsname(fd uintptr) (string, error) {\n\tvar n uintptr\n\terr := ioctl(fd, syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn fmt.Sprintf(\"/dev/pts/%d\", n), nil\n}\n\nfunc grantpt(fd uintptr) error {\n\tvar n uintptr\n\treturn ioctl(fd, syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))\n}\n\nfunc unlockpt(fd uintptr) error {\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/pty_linux.go",
    "content": "package termios\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc open_pty_master() (uintptr, error) {\n\treturn open_device(\"/dev/ptmx\")\n}\n\nfunc Ptsname(fd uintptr) (string, error) {\n\tvar n uintptr\n\terr := ioctl(fd, syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn fmt.Sprintf(\"/dev/pts/%d\", n), nil\n}\n\nfunc grantpt(fd uintptr) error {\n\tvar n uintptr\n\treturn ioctl(fd, syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))\n}\n\nfunc unlockpt(fd uintptr) error {\n\tvar n uintptr\n\treturn ioctl(fd, syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&n)))\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/pty_netbsd.go",
    "content": "package termios\n\nimport (\n\t\"bytes\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nfunc open_pty_master() (uintptr, error) {\n\tfd, err := unix.Open(\"/dev/ptmx\", unix.O_NOCTTY|unix.O_RDWR, 0666)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uintptr(fd), nil\n}\n\nfunc Ptsname(fd uintptr) (string, error) {\n\tptm, err := unix.IoctlGetPtmget(int(fd), unix.TIOCPTSNAME)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn string(ptm.Sn[:bytes.IndexByte(ptm.Sn[:], 0)]), nil\n}\n\nfunc grantpt(fd uintptr) error {\n\treturn unix.IoctlSetInt(int(fd), unix.TIOCGRANTPT, 0)\n}\n\nfunc unlockpt(fd uintptr) error {\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/pty_solaris.go",
    "content": "package termios\n\n// #include<stdlib.h>\nimport \"C\"\n\nimport \"syscall\"\n\nfunc open_pty_master() (uintptr, error) {\n\treturn open_device(\"/dev/ptmx\")\n}\n\nfunc Ptsname(fd uintptr) (string, error) {\n\tslavename := C.GoString(C.ptsname(C.int(fd)))\n\treturn slavename, nil\n}\n\nfunc grantpt(fd uintptr) error {\n\trc := C.grantpt(C.int(fd))\n\tif rc == 0 {\n\t\treturn nil\n\t} else {\n\t\treturn syscall.Errno(rc)\n\t}\n}\n\nfunc unlockpt(fd uintptr) error {\n\trc := C.unlockpt(C.int(fd))\n\tif rc == 0 {\n\t\treturn nil\n\t} else {\n\t\treturn syscall.Errno(rc)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/termios.go",
    "content": "// +build !windows\n\npackage termios\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\n// Tiocmget returns the state of the MODEM bits.\nfunc Tiocmget(fd uintptr, status *int) error {\n\treturn ioctl(fd, syscall.TIOCMGET, uintptr(unsafe.Pointer(status)))\n}\n\n// Tiocmset sets the state of the MODEM bits.\nfunc Tiocmset(fd uintptr, status *int) error {\n\treturn ioctl(fd, syscall.TIOCMSET, uintptr(unsafe.Pointer(status)))\n}\n\n// Tiocmbis sets the indicated modem bits.\nfunc Tiocmbis(fd uintptr, status *int) error {\n\treturn ioctl(fd, syscall.TIOCMBIS, uintptr(unsafe.Pointer(status)))\n}\n\n// Tiocmbic clears the indicated modem bits.\nfunc Tiocmbic(fd uintptr, status *int) error {\n\treturn ioctl(fd, syscall.TIOCMBIC, uintptr(unsafe.Pointer(status)))\n}\n\n// Cfmakecbreak modifies attr for cbreak mode.\nfunc Cfmakecbreak(attr *syscall.Termios) {\n\tattr.Lflag &^= syscall.ECHO | syscall.ICANON\n\tattr.Cc[syscall.VMIN] = 1\n\tattr.Cc[syscall.VTIME] = 0\n}\n\n// Cfmakeraw modifies attr for raw mode.\nfunc Cfmakeraw(attr *syscall.Termios) {\n\tattr.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON\n\tattr.Oflag &^= syscall.OPOST\n\tattr.Cflag &^= syscall.CSIZE | syscall.PARENB\n\tattr.Cflag |= syscall.CS8\n\tattr.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG\n\tattr.Cc[syscall.VMIN] = 1\n\tattr.Cc[syscall.VTIME] = 0\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/termios_bsd.go",
    "content": "// +build darwin freebsd openbsd netbsd dragonfly\n\npackage termios\n\nimport (\n\t\"syscall\"\n\t\"time\"\n\t\"unsafe\"\n)\n\nconst (\n\tFREAD  = 0x0001\n\tFWRITE = 0x0002\n\n\tIXON       = 0x00000200\n\tIXOFF      = 0x00000400\n\tIXANY      = 0x00000800\n\tCCTS_OFLOW = 0x00010000\n\tCRTS_IFLOW = 0x00020000\n\tCRTSCTS    = CCTS_OFLOW | CRTS_IFLOW\n)\n\n// Tcgetattr gets the current serial port settings.\nfunc Tcgetattr(fd uintptr, argp *syscall.Termios) error {\n\treturn ioctl(fd, syscall.TIOCGETA, uintptr(unsafe.Pointer(argp)))\n}\n\n// Tcsetattr sets the current serial port settings.\nfunc Tcsetattr(fd, opt uintptr, argp *syscall.Termios) error {\n\tswitch opt {\n\tcase TCSANOW:\n\t\topt = syscall.TIOCSETA\n\tcase TCSADRAIN:\n\t\topt = syscall.TIOCSETAW\n\tcase TCSAFLUSH:\n\t\topt = syscall.TIOCSETAF\n\tdefault:\n\t\treturn syscall.EINVAL\n\t}\n\treturn ioctl(fd, opt, uintptr(unsafe.Pointer(argp)))\n}\n\n// Tcsendbreak function transmits a continuous stream of zero-valued bits for\n// four-tenths of a second to the terminal referenced by fildes. The duration\n// parameter is ignored in this implementation.\nfunc Tcsendbreak(fd, duration uintptr) error {\n\tif err := ioctl(fd, syscall.TIOCSBRK, 0); err != nil {\n\t\treturn err\n\t}\n\ttime.Sleep(4 / 10 * time.Second)\n\treturn ioctl(fd, syscall.TIOCCBRK, 0)\n}\n\n// Tcdrain waits until all output written to the terminal referenced by fd has been transmitted to the terminal.\nfunc Tcdrain(fd uintptr) error {\n\treturn ioctl(fd, syscall.TIOCDRAIN, 0)\n}\n\n// Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of which.\nfunc Tcflush(fd, which uintptr) error {\n\tvar com int\n\tswitch which {\n\tcase syscall.TCIFLUSH:\n\t\tcom = FREAD\n\tcase syscall.TCOFLUSH:\n\t\tcom = FWRITE\n\tcase syscall.TCIOFLUSH:\n\t\tcom = FREAD | FWRITE\n\tdefault:\n\t\treturn syscall.EINVAL\n\t}\n\treturn ioctl(fd, syscall.TIOCFLUSH, uintptr(unsafe.Pointer(&com)))\n}\n\n// Cfgetispeed returns the input baud rate stored in the termios structure.\nfunc Cfgetispeed(attr *syscall.Termios) uint32 { return uint32(attr.Ispeed) }\n\n// Cfgetospeed returns the output baud rate stored in the termios structure.\nfunc Cfgetospeed(attr *syscall.Termios) uint32 { return uint32(attr.Ospeed) }\n\n// Tiocinq returns the number of bytes in the input buffer.\nfunc Tiocinq(fd uintptr, argp *int) error {\n\t*argp = 0\n\treturn nil\n}\n\n// Tiocoutq return the number of bytes in the output buffer.\nfunc Tiocoutq(fd uintptr, argp *int) error {\n\treturn ioctl(fd, syscall.TIOCOUTQ, uintptr(unsafe.Pointer(argp)))\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/termios_const.go",
    "content": "// +build !windows,!solaris\n\npackage termios\n\nconst (\n\tTCIFLUSH  = 0\n\tTCOFLUSH  = 1\n\tTCIOFLUSH = 2\n\n\tTCSANOW   = 0\n\tTCSADRAIN = 1\n\tTCSAFLUSH = 2\n)\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/termios_const_solaris.go",
    "content": "package termios\n\n// #include<termios.h>\nimport \"C\"\n\nconst (\n\tTCIFLUSH  = C.TCIFLUSH\n\tTCOFLUSH  = C.TCOFLUSH\n\tTCIOFLUSH = C.TCIOFLUSH\n\n\tTCSANOW   = C.TCSANOW\n\tTCSADRAIN = C.TCSADRAIN\n\tTCSAFLUSH = C.TCSAFLUSH\n)\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/termios_linux.go",
    "content": "package termios\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst (\n\tTCSETS  = 0x5402\n\tTCSETSW = 0x5403\n\tTCSETSF = 0x5404\n\tTCFLSH  = 0x540B\n\tTCSBRK  = 0x5409\n\tTCSBRKP = 0x5425\n\n\tIXON    = 0x00000400\n\tIXANY   = 0x00000800\n\tIXOFF   = 0x00001000\n\tCRTSCTS = 0x80000000\n)\n\n// Tcgetattr gets the current serial port settings.\nfunc Tcgetattr(fd uintptr, argp *syscall.Termios) error {\n\treturn ioctl(fd, syscall.TCGETS, uintptr(unsafe.Pointer(argp)))\n}\n\n// Tcsetattr sets the current serial port settings.\nfunc Tcsetattr(fd, action uintptr, argp *syscall.Termios) error {\n\tvar request uintptr\n\tswitch action {\n\tcase TCSANOW:\n\t\trequest = TCSETS\n\tcase TCSADRAIN:\n\t\trequest = TCSETSW\n\tcase TCSAFLUSH:\n\t\trequest = TCSETSF\n\tdefault:\n\t\treturn syscall.EINVAL\n\t}\n\treturn ioctl(fd, request, uintptr(unsafe.Pointer(argp)))\n}\n\n// Tcsendbreak transmits a continuous stream of zero-valued bits for a specific\n// duration, if the terminal is using asynchronous serial data transmission. If\n// duration is zero, it transmits zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds.\n// If duration is not zero, it sends zero-valued bits for some\n// implementation-defined length of time.\nfunc Tcsendbreak(fd, duration uintptr) error {\n\treturn ioctl(fd, TCSBRKP, duration)\n}\n\n// Tcdrain waits until all output written to the object referred to by fd has been transmitted.\nfunc Tcdrain(fd uintptr) error {\n\t// simulate drain with TCSADRAIN\n\tvar attr syscall.Termios\n\tif err := Tcgetattr(fd, &attr); err != nil {\n\t\treturn err\n\t}\n\treturn Tcsetattr(fd, TCSADRAIN, &attr)\n}\n\n// Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of selector.\nfunc Tcflush(fd, selector uintptr) error {\n\treturn ioctl(fd, TCFLSH, selector)\n}\n\n// Tiocinq returns the number of bytes in the input buffer.\nfunc Tiocinq(fd uintptr, argp *int) error {\n\treturn ioctl(fd, syscall.TIOCINQ, uintptr(unsafe.Pointer(argp)))\n}\n\n// Tiocoutq return the number of bytes in the output buffer.\nfunc Tiocoutq(fd uintptr, argp *int) error {\n\treturn ioctl(fd, syscall.TIOCOUTQ, uintptr(unsafe.Pointer(argp)))\n}\n\n// Cfgetispeed returns the input baud rate stored in the termios structure.\nfunc Cfgetispeed(attr *syscall.Termios) uint32 { return attr.Ispeed }\n\n// Cfgetospeed returns the output baud rate stored in the termios structure.\nfunc Cfgetospeed(attr *syscall.Termios) uint32 { return attr.Ospeed }\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/termios_solaris.go",
    "content": "package termios\n\n// #include <termios.h>\n// typedef struct termios termios_t;\nimport \"C\"\n\nimport (\n\t\"syscall\"\n\n\t\"golang.org/x/sys/unix\"\n\t\"unsafe\"\n)\n\nconst (\n\tTCSETS  = 0x5402\n\tTCSETSW = 0x5403\n\tTCSETSF = 0x5404\n\tTCFLSH  = 0x540B\n\tTCSBRK  = 0x5409\n\tTCSBRKP = 0x5425\n\n\tIXON    = 0x00000400\n\tIXANY   = 0x00000800\n\tIXOFF   = 0x00001000\n\tCRTSCTS = 0x80000000\n)\n\n// See /usr/include/sys/termios.h\nconst FIORDCHK = C.FIORDCHK\n\n// Tcgetattr gets the current serial port settings.\nfunc Tcgetattr(fd uintptr, argp *syscall.Termios) error {\n\ttermios, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)\n\t*argp = *(tiosToSyscall(termios))\n\treturn err\n}\n\n// Tcsetattr sets the current serial port settings.\nfunc Tcsetattr(fd, action uintptr, argp *syscall.Termios) error {\n\treturn unix.IoctlSetTermios(int(fd), uint(action), tiosToUnix(argp))\n}\n\n// Tcsendbreak transmits a continuous stream of zero-valued bits for a specific\n// duration, if the terminal is using asynchronous serial data transmission. If\n// duration is zero, it transmits zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds.\n// If duration is not zero, it sends zero-valued bits for some\n// implementation-defined length of time.\nfunc Tcsendbreak(fd, duration uintptr) error {\n\treturn ioctl(fd, TCSBRKP, duration)\n}\n\n// Tcdrain waits until all output written to the object referred to by fd has been transmitted.\nfunc Tcdrain(fd uintptr) error {\n\t// simulate drain with TCSADRAIN\n\tvar attr syscall.Termios\n\tif err := Tcgetattr(fd, &attr); err != nil {\n\t\treturn err\n\t}\n\treturn Tcsetattr(fd, TCSADRAIN, &attr)\n}\n\n// Tcflush discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of selector.\nfunc Tcflush(fd, selector uintptr) error {\n\treturn ioctl(fd, TCFLSH, selector)\n}\n\n// Tiocinq returns the number of bytes in the input buffer.\nfunc Tiocinq(fd uintptr, argp *int) (err error) {\n\t*argp, err = unix.IoctlGetInt(int(fd), FIORDCHK)\n\treturn err\n}\n\n// Tiocoutq return the number of bytes in the output buffer.\nfunc Tiocoutq(fd uintptr, argp *int) error {\n\treturn ioctl(fd, syscall.TIOCOUTQ, uintptr(unsafe.Pointer(argp)))\n}\n\n// Cfgetispeed returns the input baud rate stored in the termios structure.\nfunc Cfgetispeed(attr *syscall.Termios) uint32 {\n\tsolTermios := tiosToUnix(attr)\n\treturn uint32(C.cfgetispeed((*C.termios_t)(unsafe.Pointer(solTermios))))\n}\n\n// Cfsetispeed sets the input baud rate stored in the termios structure.\nfunc Cfsetispeed(attr *syscall.Termios, speed uintptr) error {\n\tsolTermios := tiosToUnix(attr)\n\t_, err := C.cfsetispeed((*C.termios_t)(unsafe.Pointer(solTermios)), C.speed_t(speed))\n\treturn err\n}\n\n// Cfgetospeed returns the output baud rate stored in the termios structure.\nfunc Cfgetospeed(attr *syscall.Termios) uint32 {\n\tsolTermios := tiosToUnix(attr)\n\treturn uint32(C.cfgetospeed((*C.termios_t)(unsafe.Pointer(solTermios))))\n}\n\n// Cfsetospeed sets the output baud rate stored in the termios structure.\nfunc Cfsetospeed(attr *syscall.Termios, speed uintptr) error {\n\tsolTermios := tiosToUnix(attr)\n\t_, err := C.cfsetospeed((*C.termios_t)(unsafe.Pointer(solTermios)), C.speed_t(speed))\n\treturn err\n}\n\n\n// tiosToUnix copies a syscall.Termios to a x/sys/unix.Termios.\n// This is needed since type conversions between the two fail due to\n// more recent x/sys/unix.Termios renaming the padding field.\nfunc tiosToUnix(st *syscall.Termios) *unix.Termios {\n\treturn &unix.Termios{\n\t\tIflag:  st.Iflag,\n\t\tOflag:  st.Oflag,\n\t\tCflag:  st.Cflag,\n\t\tLflag:  st.Lflag,\n\t\tCc:     st.Cc,\n\t}\n}\n\n// tiosToSyscall copies a x/sys/unix.Termios to a syscall.Termios.\nfunc tiosToSyscall(ut *unix.Termios) *syscall.Termios {\n\treturn &syscall.Termios{\n\t\tIflag:  ut.Iflag,\n\t\tOflag:  ut.Oflag,\n\t\tCflag:  ut.Cflag,\n\t\tLflag:  ut.Lflag,\n\t\tCc:     ut.Cc,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/pkg/term/termios/termios_windows.go",
    "content": "package termios\n"
  },
  {
    "path": "vendor/github.com/pmezard/go-difflib/LICENSE",
    "content": "Copyright (c) 2013, Patrick Mezard\nAll 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    Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n    The names of its contributors may not be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/pmezard/go-difflib/difflib/difflib.go",
    "content": "// Package difflib is a partial port of Python difflib module.\n//\n// It provides tools to compare sequences of strings and generate textual diffs.\n//\n// The following class and functions have been ported:\n//\n// - SequenceMatcher\n//\n// - unified_diff\n//\n// - context_diff\n//\n// Getting unified diffs was the main goal of the port. Keep in mind this code\n// is mostly suitable to output text differences in a human friendly way, there\n// are no guarantees generated diffs are consumable by patch(1).\npackage difflib\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\nfunc min(a, b int) int {\n\tif a < b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc max(a, b int) int {\n\tif a > b {\n\t\treturn a\n\t}\n\treturn b\n}\n\nfunc calculateRatio(matches, length int) float64 {\n\tif length > 0 {\n\t\treturn 2.0 * float64(matches) / float64(length)\n\t}\n\treturn 1.0\n}\n\ntype Match struct {\n\tA    int\n\tB    int\n\tSize int\n}\n\ntype OpCode struct {\n\tTag byte\n\tI1  int\n\tI2  int\n\tJ1  int\n\tJ2  int\n}\n\n// SequenceMatcher compares sequence of strings. The basic\n// algorithm predates, and is a little fancier than, an algorithm\n// published in the late 1980's by Ratcliff and Obershelp under the\n// hyperbolic name \"gestalt pattern matching\".  The basic idea is to find\n// the longest contiguous matching subsequence that contains no \"junk\"\n// elements (R-O doesn't address junk).  The same idea is then applied\n// recursively to the pieces of the sequences to the left and to the right\n// of the matching subsequence.  This does not yield minimal edit\n// sequences, but does tend to yield matches that \"look right\" to people.\n//\n// SequenceMatcher tries to compute a \"human-friendly diff\" between two\n// sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the\n// longest *contiguous* & junk-free matching subsequence.  That's what\n// catches peoples' eyes.  The Windows(tm) windiff has another interesting\n// notion, pairing up elements that appear uniquely in each sequence.\n// That, and the method here, appear to yield more intuitive difference\n// reports than does diff.  This method appears to be the least vulnerable\n// to synching up on blocks of \"junk lines\", though (like blank lines in\n// ordinary text files, or maybe \"<P>\" lines in HTML files).  That may be\n// because this is the only method of the 3 that has a *concept* of\n// \"junk\" <wink>.\n//\n// Timing:  Basic R-O is cubic time worst case and quadratic time expected\n// case.  SequenceMatcher is quadratic time for the worst case and has\n// expected-case behavior dependent in a complicated way on how many\n// elements the sequences have in common; best case time is linear.\ntype SequenceMatcher struct {\n\ta              []string\n\tb              []string\n\tb2j            map[string][]int\n\tIsJunk         func(string) bool\n\tautoJunk       bool\n\tbJunk          map[string]struct{}\n\tmatchingBlocks []Match\n\tfullBCount     map[string]int\n\tbPopular       map[string]struct{}\n\topCodes        []OpCode\n}\n\nfunc NewMatcher(a, b []string) *SequenceMatcher {\n\tm := SequenceMatcher{autoJunk: true}\n\tm.SetSeqs(a, b)\n\treturn &m\n}\n\nfunc NewMatcherWithJunk(a, b []string, autoJunk bool,\n\tisJunk func(string) bool) *SequenceMatcher {\n\n\tm := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk}\n\tm.SetSeqs(a, b)\n\treturn &m\n}\n\n// Set two sequences to be compared.\nfunc (m *SequenceMatcher) SetSeqs(a, b []string) {\n\tm.SetSeq1(a)\n\tm.SetSeq2(b)\n}\n\n// Set the first sequence to be compared. The second sequence to be compared is\n// not changed.\n//\n// SequenceMatcher computes and caches detailed information about the second\n// sequence, so if you want to compare one sequence S against many sequences,\n// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other\n// sequences.\n//\n// See also SetSeqs() and SetSeq2().\nfunc (m *SequenceMatcher) SetSeq1(a []string) {\n\tif &a == &m.a {\n\t\treturn\n\t}\n\tm.a = a\n\tm.matchingBlocks = nil\n\tm.opCodes = nil\n}\n\n// Set the second sequence to be compared. The first sequence to be compared is\n// not changed.\nfunc (m *SequenceMatcher) SetSeq2(b []string) {\n\tif &b == &m.b {\n\t\treturn\n\t}\n\tm.b = b\n\tm.matchingBlocks = nil\n\tm.opCodes = nil\n\tm.fullBCount = nil\n\tm.chainB()\n}\n\nfunc (m *SequenceMatcher) chainB() {\n\t// Populate line -> index mapping\n\tb2j := map[string][]int{}\n\tfor i, s := range m.b {\n\t\tindices := b2j[s]\n\t\tindices = append(indices, i)\n\t\tb2j[s] = indices\n\t}\n\n\t// Purge junk elements\n\tm.bJunk = map[string]struct{}{}\n\tif m.IsJunk != nil {\n\t\tjunk := m.bJunk\n\t\tfor s, _ := range b2j {\n\t\t\tif m.IsJunk(s) {\n\t\t\t\tjunk[s] = struct{}{}\n\t\t\t}\n\t\t}\n\t\tfor s, _ := range junk {\n\t\t\tdelete(b2j, s)\n\t\t}\n\t}\n\n\t// Purge remaining popular elements\n\tpopular := map[string]struct{}{}\n\tn := len(m.b)\n\tif m.autoJunk && n >= 200 {\n\t\tntest := n/100 + 1\n\t\tfor s, indices := range b2j {\n\t\t\tif len(indices) > ntest {\n\t\t\t\tpopular[s] = struct{}{}\n\t\t\t}\n\t\t}\n\t\tfor s, _ := range popular {\n\t\t\tdelete(b2j, s)\n\t\t}\n\t}\n\tm.bPopular = popular\n\tm.b2j = b2j\n}\n\nfunc (m *SequenceMatcher) isBJunk(s string) bool {\n\t_, ok := m.bJunk[s]\n\treturn ok\n}\n\n// Find longest matching block in a[alo:ahi] and b[blo:bhi].\n//\n// If IsJunk is not defined:\n//\n// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where\n//     alo <= i <= i+k <= ahi\n//     blo <= j <= j+k <= bhi\n// and for all (i',j',k') meeting those conditions,\n//     k >= k'\n//     i <= i'\n//     and if i == i', j <= j'\n//\n// In other words, of all maximal matching blocks, return one that\n// starts earliest in a, and of all those maximal matching blocks that\n// start earliest in a, return the one that starts earliest in b.\n//\n// If IsJunk is defined, first the longest matching block is\n// determined as above, but with the additional restriction that no\n// junk element appears in the block.  Then that block is extended as\n// far as possible by matching (only) junk elements on both sides.  So\n// the resulting block never matches on junk except as identical junk\n// happens to be adjacent to an \"interesting\" match.\n//\n// If no blocks match, return (alo, blo, 0).\nfunc (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {\n\t// CAUTION:  stripping common prefix or suffix would be incorrect.\n\t// E.g.,\n\t//    ab\n\t//    acab\n\t// Longest matching block is \"ab\", but if common prefix is\n\t// stripped, it's \"a\" (tied with \"b\").  UNIX(tm) diff does so\n\t// strip, so ends up claiming that ab is changed to acab by\n\t// inserting \"ca\" in the middle.  That's minimal but unintuitive:\n\t// \"it's obvious\" that someone inserted \"ac\" at the front.\n\t// Windiff ends up at the same place as diff, but by pairing up\n\t// the unique 'b's and then matching the first two 'a's.\n\tbesti, bestj, bestsize := alo, blo, 0\n\n\t// find longest junk-free match\n\t// during an iteration of the loop, j2len[j] = length of longest\n\t// junk-free match ending with a[i-1] and b[j]\n\tj2len := map[int]int{}\n\tfor i := alo; i != ahi; i++ {\n\t\t// look at all instances of a[i] in b; note that because\n\t\t// b2j has no junk keys, the loop is skipped if a[i] is junk\n\t\tnewj2len := map[int]int{}\n\t\tfor _, j := range m.b2j[m.a[i]] {\n\t\t\t// a[i] matches b[j]\n\t\t\tif j < blo {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif j >= bhi {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tk := j2len[j-1] + 1\n\t\t\tnewj2len[j] = k\n\t\t\tif k > bestsize {\n\t\t\t\tbesti, bestj, bestsize = i-k+1, j-k+1, k\n\t\t\t}\n\t\t}\n\t\tj2len = newj2len\n\t}\n\n\t// Extend the best by non-junk elements on each end.  In particular,\n\t// \"popular\" non-junk elements aren't in b2j, which greatly speeds\n\t// the inner loop above, but also means \"the best\" match so far\n\t// doesn't contain any junk *or* popular non-junk elements.\n\tfor besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&\n\t\tm.a[besti-1] == m.b[bestj-1] {\n\t\tbesti, bestj, bestsize = besti-1, bestj-1, bestsize+1\n\t}\n\tfor besti+bestsize < ahi && bestj+bestsize < bhi &&\n\t\t!m.isBJunk(m.b[bestj+bestsize]) &&\n\t\tm.a[besti+bestsize] == m.b[bestj+bestsize] {\n\t\tbestsize += 1\n\t}\n\n\t// Now that we have a wholly interesting match (albeit possibly\n\t// empty!), we may as well suck up the matching junk on each\n\t// side of it too.  Can't think of a good reason not to, and it\n\t// saves post-processing the (possibly considerable) expense of\n\t// figuring out what to do with it.  In the case of an empty\n\t// interesting match, this is clearly the right thing to do,\n\t// because no other kind of match is possible in the regions.\n\tfor besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&\n\t\tm.a[besti-1] == m.b[bestj-1] {\n\t\tbesti, bestj, bestsize = besti-1, bestj-1, bestsize+1\n\t}\n\tfor besti+bestsize < ahi && bestj+bestsize < bhi &&\n\t\tm.isBJunk(m.b[bestj+bestsize]) &&\n\t\tm.a[besti+bestsize] == m.b[bestj+bestsize] {\n\t\tbestsize += 1\n\t}\n\n\treturn Match{A: besti, B: bestj, Size: bestsize}\n}\n\n// Return list of triples describing matching subsequences.\n//\n// Each triple is of the form (i, j, n), and means that\n// a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in\n// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are\n// adjacent triples in the list, and the second is not the last triple in the\n// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe\n// adjacent equal blocks.\n//\n// The last triple is a dummy, (len(a), len(b), 0), and is the only\n// triple with n==0.\nfunc (m *SequenceMatcher) GetMatchingBlocks() []Match {\n\tif m.matchingBlocks != nil {\n\t\treturn m.matchingBlocks\n\t}\n\n\tvar matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match\n\tmatchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {\n\t\tmatch := m.findLongestMatch(alo, ahi, blo, bhi)\n\t\ti, j, k := match.A, match.B, match.Size\n\t\tif match.Size > 0 {\n\t\t\tif alo < i && blo < j {\n\t\t\t\tmatched = matchBlocks(alo, i, blo, j, matched)\n\t\t\t}\n\t\t\tmatched = append(matched, match)\n\t\t\tif i+k < ahi && j+k < bhi {\n\t\t\t\tmatched = matchBlocks(i+k, ahi, j+k, bhi, matched)\n\t\t\t}\n\t\t}\n\t\treturn matched\n\t}\n\tmatched := matchBlocks(0, len(m.a), 0, len(m.b), nil)\n\n\t// It's possible that we have adjacent equal blocks in the\n\t// matching_blocks list now.\n\tnonAdjacent := []Match{}\n\ti1, j1, k1 := 0, 0, 0\n\tfor _, b := range matched {\n\t\t// Is this block adjacent to i1, j1, k1?\n\t\ti2, j2, k2 := b.A, b.B, b.Size\n\t\tif i1+k1 == i2 && j1+k1 == j2 {\n\t\t\t// Yes, so collapse them -- this just increases the length of\n\t\t\t// the first block by the length of the second, and the first\n\t\t\t// block so lengthened remains the block to compare against.\n\t\t\tk1 += k2\n\t\t} else {\n\t\t\t// Not adjacent.  Remember the first block (k1==0 means it's\n\t\t\t// the dummy we started with), and make the second block the\n\t\t\t// new block to compare against.\n\t\t\tif k1 > 0 {\n\t\t\t\tnonAdjacent = append(nonAdjacent, Match{i1, j1, k1})\n\t\t\t}\n\t\t\ti1, j1, k1 = i2, j2, k2\n\t\t}\n\t}\n\tif k1 > 0 {\n\t\tnonAdjacent = append(nonAdjacent, Match{i1, j1, k1})\n\t}\n\n\tnonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})\n\tm.matchingBlocks = nonAdjacent\n\treturn m.matchingBlocks\n}\n\n// Return list of 5-tuples describing how to turn a into b.\n//\n// Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple\n// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the\n// tuple preceding it, and likewise for j1 == the previous j2.\n//\n// The tags are characters, with these meanings:\n//\n// 'r' (replace):  a[i1:i2] should be replaced by b[j1:j2]\n//\n// 'd' (delete):   a[i1:i2] should be deleted, j1==j2 in this case.\n//\n// 'i' (insert):   b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.\n//\n// 'e' (equal):    a[i1:i2] == b[j1:j2]\nfunc (m *SequenceMatcher) GetOpCodes() []OpCode {\n\tif m.opCodes != nil {\n\t\treturn m.opCodes\n\t}\n\ti, j := 0, 0\n\tmatching := m.GetMatchingBlocks()\n\topCodes := make([]OpCode, 0, len(matching))\n\tfor _, m := range matching {\n\t\t//  invariant:  we've pumped out correct diffs to change\n\t\t//  a[:i] into b[:j], and the next matching block is\n\t\t//  a[ai:ai+size] == b[bj:bj+size]. So we need to pump\n\t\t//  out a diff to change a[i:ai] into b[j:bj], pump out\n\t\t//  the matching block, and move (i,j) beyond the match\n\t\tai, bj, size := m.A, m.B, m.Size\n\t\ttag := byte(0)\n\t\tif i < ai && j < bj {\n\t\t\ttag = 'r'\n\t\t} else if i < ai {\n\t\t\ttag = 'd'\n\t\t} else if j < bj {\n\t\t\ttag = 'i'\n\t\t}\n\t\tif tag > 0 {\n\t\t\topCodes = append(opCodes, OpCode{tag, i, ai, j, bj})\n\t\t}\n\t\ti, j = ai+size, bj+size\n\t\t// the list of matching blocks is terminated by a\n\t\t// sentinel with size 0\n\t\tif size > 0 {\n\t\t\topCodes = append(opCodes, OpCode{'e', ai, i, bj, j})\n\t\t}\n\t}\n\tm.opCodes = opCodes\n\treturn m.opCodes\n}\n\n// Isolate change clusters by eliminating ranges with no changes.\n//\n// Return a generator of groups with up to n lines of context.\n// Each group is in the same format as returned by GetOpCodes().\nfunc (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {\n\tif n < 0 {\n\t\tn = 3\n\t}\n\tcodes := m.GetOpCodes()\n\tif len(codes) == 0 {\n\t\tcodes = []OpCode{OpCode{'e', 0, 1, 0, 1}}\n\t}\n\t// Fixup leading and trailing groups if they show no changes.\n\tif codes[0].Tag == 'e' {\n\t\tc := codes[0]\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\tcodes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}\n\t}\n\tif codes[len(codes)-1].Tag == 'e' {\n\t\tc := codes[len(codes)-1]\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\tcodes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}\n\t}\n\tnn := n + n\n\tgroups := [][]OpCode{}\n\tgroup := []OpCode{}\n\tfor _, c := range codes {\n\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\t// End the current group and start a new one whenever\n\t\t// there is a large range with no changes.\n\t\tif c.Tag == 'e' && i2-i1 > nn {\n\t\t\tgroup = append(group, OpCode{c.Tag, i1, min(i2, i1+n),\n\t\t\t\tj1, min(j2, j1+n)})\n\t\t\tgroups = append(groups, group)\n\t\t\tgroup = []OpCode{}\n\t\t\ti1, j1 = max(i1, i2-n), max(j1, j2-n)\n\t\t}\n\t\tgroup = append(group, OpCode{c.Tag, i1, i2, j1, j2})\n\t}\n\tif len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {\n\t\tgroups = append(groups, group)\n\t}\n\treturn groups\n}\n\n// Return a measure of the sequences' similarity (float in [0,1]).\n//\n// Where T is the total number of elements in both sequences, and\n// M is the number of matches, this is 2.0*M / T.\n// Note that this is 1 if the sequences are identical, and 0 if\n// they have nothing in common.\n//\n// .Ratio() is expensive to compute if you haven't already computed\n// .GetMatchingBlocks() or .GetOpCodes(), in which case you may\n// want to try .QuickRatio() or .RealQuickRation() first to get an\n// upper bound.\nfunc (m *SequenceMatcher) Ratio() float64 {\n\tmatches := 0\n\tfor _, m := range m.GetMatchingBlocks() {\n\t\tmatches += m.Size\n\t}\n\treturn calculateRatio(matches, len(m.a)+len(m.b))\n}\n\n// Return an upper bound on ratio() relatively quickly.\n//\n// This isn't defined beyond that it is an upper bound on .Ratio(), and\n// is faster to compute.\nfunc (m *SequenceMatcher) QuickRatio() float64 {\n\t// viewing a and b as multisets, set matches to the cardinality\n\t// of their intersection; this counts the number of matches\n\t// without regard to order, so is clearly an upper bound\n\tif m.fullBCount == nil {\n\t\tm.fullBCount = map[string]int{}\n\t\tfor _, s := range m.b {\n\t\t\tm.fullBCount[s] = m.fullBCount[s] + 1\n\t\t}\n\t}\n\n\t// avail[x] is the number of times x appears in 'b' less the\n\t// number of times we've seen it in 'a' so far ... kinda\n\tavail := map[string]int{}\n\tmatches := 0\n\tfor _, s := range m.a {\n\t\tn, ok := avail[s]\n\t\tif !ok {\n\t\t\tn = m.fullBCount[s]\n\t\t}\n\t\tavail[s] = n - 1\n\t\tif n > 0 {\n\t\t\tmatches += 1\n\t\t}\n\t}\n\treturn calculateRatio(matches, len(m.a)+len(m.b))\n}\n\n// Return an upper bound on ratio() very quickly.\n//\n// This isn't defined beyond that it is an upper bound on .Ratio(), and\n// is faster to compute than either .Ratio() or .QuickRatio().\nfunc (m *SequenceMatcher) RealQuickRatio() float64 {\n\tla, lb := len(m.a), len(m.b)\n\treturn calculateRatio(min(la, lb), la+lb)\n}\n\n// Convert range to the \"ed\" format\nfunc formatRangeUnified(start, stop int) string {\n\t// Per the diff spec at http://www.unix.org/single_unix_specification/\n\tbeginning := start + 1 // lines start numbering with one\n\tlength := stop - start\n\tif length == 1 {\n\t\treturn fmt.Sprintf(\"%d\", beginning)\n\t}\n\tif length == 0 {\n\t\tbeginning -= 1 // empty ranges begin at line just before the range\n\t}\n\treturn fmt.Sprintf(\"%d,%d\", beginning, length)\n}\n\n// Unified diff parameters\ntype UnifiedDiff struct {\n\tA        []string // First sequence lines\n\tFromFile string   // First file name\n\tFromDate string   // First file time\n\tB        []string // Second sequence lines\n\tToFile   string   // Second file name\n\tToDate   string   // Second file time\n\tEol      string   // Headers end of line, defaults to LF\n\tContext  int      // Number of context lines\n}\n\n// Compare two sequences of lines; generate the delta as a unified diff.\n//\n// Unified diffs are a compact way of showing line changes and a few\n// lines of context.  The number of context lines is set by 'n' which\n// defaults to three.\n//\n// By default, the diff control lines (those with ---, +++, or @@) are\n// created with a trailing newline.  This is helpful so that inputs\n// created from file.readlines() result in diffs that are suitable for\n// file.writelines() since both the inputs and outputs have trailing\n// newlines.\n//\n// For inputs that do not have trailing newlines, set the lineterm\n// argument to \"\" so that the output will be uniformly newline free.\n//\n// The unidiff format normally has a header for filenames and modification\n// times.  Any or all of these may be specified using strings for\n// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'.\n// The modification times are normally expressed in the ISO 8601 format.\nfunc WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error {\n\tbuf := bufio.NewWriter(writer)\n\tdefer buf.Flush()\n\twf := func(format string, args ...interface{}) error {\n\t\t_, err := buf.WriteString(fmt.Sprintf(format, args...))\n\t\treturn err\n\t}\n\tws := func(s string) error {\n\t\t_, err := buf.WriteString(s)\n\t\treturn err\n\t}\n\n\tif len(diff.Eol) == 0 {\n\t\tdiff.Eol = \"\\n\"\n\t}\n\n\tstarted := false\n\tm := NewMatcher(diff.A, diff.B)\n\tfor _, g := range m.GetGroupedOpCodes(diff.Context) {\n\t\tif !started {\n\t\t\tstarted = true\n\t\t\tfromDate := \"\"\n\t\t\tif len(diff.FromDate) > 0 {\n\t\t\t\tfromDate = \"\\t\" + diff.FromDate\n\t\t\t}\n\t\t\ttoDate := \"\"\n\t\t\tif len(diff.ToDate) > 0 {\n\t\t\t\ttoDate = \"\\t\" + diff.ToDate\n\t\t\t}\n\t\t\tif diff.FromFile != \"\" || diff.ToFile != \"\" {\n\t\t\t\terr := wf(\"--- %s%s%s\", diff.FromFile, fromDate, diff.Eol)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\terr = wf(\"+++ %s%s%s\", diff.ToFile, toDate, diff.Eol)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfirst, last := g[0], g[len(g)-1]\n\t\trange1 := formatRangeUnified(first.I1, last.I2)\n\t\trange2 := formatRangeUnified(first.J1, last.J2)\n\t\tif err := wf(\"@@ -%s +%s @@%s\", range1, range2, diff.Eol); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tfor _, c := range g {\n\t\t\ti1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2\n\t\t\tif c.Tag == 'e' {\n\t\t\t\tfor _, line := range diff.A[i1:i2] {\n\t\t\t\t\tif err := ws(\" \" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.Tag == 'r' || c.Tag == 'd' {\n\t\t\t\tfor _, line := range diff.A[i1:i2] {\n\t\t\t\t\tif err := ws(\"-\" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif c.Tag == 'r' || c.Tag == 'i' {\n\t\t\t\tfor _, line := range diff.B[j1:j2] {\n\t\t\t\t\tif err := ws(\"+\" + line); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// Like WriteUnifiedDiff but returns the diff a string.\nfunc GetUnifiedDiffString(diff UnifiedDiff) (string, error) {\n\tw := &bytes.Buffer{}\n\terr := WriteUnifiedDiff(w, diff)\n\treturn string(w.Bytes()), err\n}\n\n// Convert range to the \"ed\" format.\nfunc formatRangeContext(start, stop int) string {\n\t// Per the diff spec at http://www.unix.org/single_unix_specification/\n\tbeginning := start + 1 // lines start numbering with one\n\tlength := stop - start\n\tif length == 0 {\n\t\tbeginning -= 1 // empty ranges begin at line just before the range\n\t}\n\tif length <= 1 {\n\t\treturn fmt.Sprintf(\"%d\", beginning)\n\t}\n\treturn fmt.Sprintf(\"%d,%d\", beginning, beginning+length-1)\n}\n\ntype ContextDiff UnifiedDiff\n\n// Compare two sequences of lines; generate the delta as a context diff.\n//\n// Context diffs are a compact way of showing line changes and a few\n// lines of context. The number of context lines is set by diff.Context\n// which defaults to three.\n//\n// By default, the diff control lines (those with *** or ---) are\n// created with a trailing newline.\n//\n// For inputs that do not have trailing newlines, set the diff.Eol\n// argument to \"\" so that the output will be uniformly newline free.\n//\n// The context diff format normally has a header for filenames and\n// modification times.  Any or all of these may be specified using\n// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate.\n// The modification times are normally expressed in the ISO 8601 format.\n// If not specified, the strings default to blanks.\nfunc WriteContextDiff(writer io.Writer, diff ContextDiff) error {\n\tbuf := bufio.NewWriter(writer)\n\tdefer buf.Flush()\n\tvar diffErr error\n\twf := func(format string, args ...interface{}) {\n\t\t_, err := buf.WriteString(fmt.Sprintf(format, args...))\n\t\tif diffErr == nil && err != nil {\n\t\t\tdiffErr = err\n\t\t}\n\t}\n\tws := func(s string) {\n\t\t_, err := buf.WriteString(s)\n\t\tif diffErr == nil && err != nil {\n\t\t\tdiffErr = err\n\t\t}\n\t}\n\n\tif len(diff.Eol) == 0 {\n\t\tdiff.Eol = \"\\n\"\n\t}\n\n\tprefix := map[byte]string{\n\t\t'i': \"+ \",\n\t\t'd': \"- \",\n\t\t'r': \"! \",\n\t\t'e': \"  \",\n\t}\n\n\tstarted := false\n\tm := NewMatcher(diff.A, diff.B)\n\tfor _, g := range m.GetGroupedOpCodes(diff.Context) {\n\t\tif !started {\n\t\t\tstarted = true\n\t\t\tfromDate := \"\"\n\t\t\tif len(diff.FromDate) > 0 {\n\t\t\t\tfromDate = \"\\t\" + diff.FromDate\n\t\t\t}\n\t\t\ttoDate := \"\"\n\t\t\tif len(diff.ToDate) > 0 {\n\t\t\t\ttoDate = \"\\t\" + diff.ToDate\n\t\t\t}\n\t\t\tif diff.FromFile != \"\" || diff.ToFile != \"\" {\n\t\t\t\twf(\"*** %s%s%s\", diff.FromFile, fromDate, diff.Eol)\n\t\t\t\twf(\"--- %s%s%s\", diff.ToFile, toDate, diff.Eol)\n\t\t\t}\n\t\t}\n\n\t\tfirst, last := g[0], g[len(g)-1]\n\t\tws(\"***************\" + diff.Eol)\n\n\t\trange1 := formatRangeContext(first.I1, last.I2)\n\t\twf(\"*** %s ****%s\", range1, diff.Eol)\n\t\tfor _, c := range g {\n\t\t\tif c.Tag == 'r' || c.Tag == 'd' {\n\t\t\t\tfor _, cc := range g {\n\t\t\t\t\tif cc.Tag == 'i' {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfor _, line := range diff.A[cc.I1:cc.I2] {\n\t\t\t\t\t\tws(prefix[cc.Tag] + line)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\trange2 := formatRangeContext(first.J1, last.J2)\n\t\twf(\"--- %s ----%s\", range2, diff.Eol)\n\t\tfor _, c := range g {\n\t\t\tif c.Tag == 'r' || c.Tag == 'i' {\n\t\t\t\tfor _, cc := range g {\n\t\t\t\t\tif cc.Tag == 'd' {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tfor _, line := range diff.B[cc.J1:cc.J2] {\n\t\t\t\t\t\tws(prefix[cc.Tag] + line)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\treturn diffErr\n}\n\n// Like WriteContextDiff but returns the diff a string.\nfunc GetContextDiffString(diff ContextDiff) (string, error) {\n\tw := &bytes.Buffer{}\n\terr := WriteContextDiff(w, diff)\n\treturn string(w.Bytes()), err\n}\n\n// Split a string on \"\\n\" while preserving them. The output can be used\n// as input for UnifiedDiff and ContextDiff structures.\nfunc SplitLines(s string) []string {\n\tlines := strings.SplitAfter(s, \"\\n\")\n\tlines[len(lines)-1] += \"\\n\"\n\treturn lines\n}\n"
  },
  {
    "path": "vendor/github.com/rivo/uniseg/LICENSE.txt",
    "content": "MIT License\n\nCopyright (c) 2019 Oliver Kuederle\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": "vendor/github.com/rivo/uniseg/README.md",
    "content": "# Unicode Text Segmentation for Go\n\n[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/github.com/rivo/uniseg)\n[![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg)\n\nThis Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](http://unicode.org/reports/tr29/) (Unicode version 12.0.0).\n\nAt this point, only the determination of grapheme cluster boundaries is implemented.\n\n## Background\n\nIn Go, [strings are read-only slices of bytes](https://blog.golang.org/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls \"grapheme cluster\". Here are some examples:\n\n|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters|\n|-|-|-|-|\n|Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`|\n|🏳️‍🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`|\n|🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`|\n\nThis package provides a tool to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit.\n\n## Installation\n\n```bash\ngo get github.com/rivo/uniseg\n```\n\n## Basic Example\n\n```go\npackage uniseg\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/rivo/uniseg\"\n)\n\nfunc main() {\n\tgr := uniseg.NewGraphemes(\"👍🏼!\")\n\tfor gr.Next() {\n\t\tfmt.Printf(\"%x \", gr.Runes())\n\t}\n\t// Output: [1f44d 1f3fc] [21]\n}\n```\n\n## Documentation\n\nRefer to https://godoc.org/github.com/rivo/uniseg for the package's documentation.\n\n## Dependencies\n\nThis package does not depend on any packages outside the standard library.\n\n## Your Feedback\n\nAdd your issue here on GitHub. Feel free to get in touch if you have any questions.\n\n## Version\n\nVersion tags will be introduced once Golang modules are official. Consider this version 0.1.\n"
  },
  {
    "path": "vendor/github.com/rivo/uniseg/doc.go",
    "content": "/*\nPackage uniseg implements Unicode Text Segmentation according to Unicode\nStandard Annex #29 (http://unicode.org/reports/tr29/).\n\nAt this point, only the determination of grapheme cluster boundaries is\nimplemented.\n*/\npackage uniseg\n"
  },
  {
    "path": "vendor/github.com/rivo/uniseg/grapheme.go",
    "content": "package uniseg\n\nimport \"unicode/utf8\"\n\n// The states of the grapheme cluster parser.\nconst (\n\tgrAny = iota\n\tgrCR\n\tgrControlLF\n\tgrL\n\tgrLVV\n\tgrLVTT\n\tgrPrepend\n\tgrExtendedPictographic\n\tgrExtendedPictographicZWJ\n\tgrRIOdd\n\tgrRIEven\n)\n\n// The grapheme cluster parser's breaking instructions.\nconst (\n\tgrNoBoundary = iota\n\tgrBoundary\n)\n\n// The grapheme cluster parser's state transitions. Maps (state, property) to\n// (new state, breaking instruction, rule number). The breaking instruction\n// always refers to the boundary between the last and next code point.\n//\n// This map is queried as follows:\n//\n//   1. Find specific state + specific property. Stop if found.\n//   2. Find specific state + any property.\n//   3. Find any state + specific property.\n//   4. If only (2) or (3) (but not both) was found, stop.\n//   5. If both (2) and (3) were found, use state and breaking instruction from\n//      the transition with the lower rule number, prefer (3) if rule numbers\n//      are equal. Stop.\n//   6. Assume grAny and grBoundary.\nvar grTransitions = map[[2]int][3]int{\n\t// GB5\n\t{grAny, prCR}:      {grCR, grBoundary, 50},\n\t{grAny, prLF}:      {grControlLF, grBoundary, 50},\n\t{grAny, prControl}: {grControlLF, grBoundary, 50},\n\n\t// GB4\n\t{grCR, prAny}:        {grAny, grBoundary, 40},\n\t{grControlLF, prAny}: {grAny, grBoundary, 40},\n\n\t// GB3.\n\t{grCR, prLF}: {grAny, grNoBoundary, 30},\n\n\t// GB6.\n\t{grAny, prL}: {grL, grBoundary, 9990},\n\t{grL, prL}:   {grL, grNoBoundary, 60},\n\t{grL, prV}:   {grLVV, grNoBoundary, 60},\n\t{grL, prLV}:  {grLVV, grNoBoundary, 60},\n\t{grL, prLVT}: {grLVTT, grNoBoundary, 60},\n\n\t// GB7.\n\t{grAny, prLV}: {grLVV, grBoundary, 9990},\n\t{grAny, prV}:  {grLVV, grBoundary, 9990},\n\t{grLVV, prV}:  {grLVV, grNoBoundary, 70},\n\t{grLVV, prT}:  {grLVTT, grNoBoundary, 70},\n\n\t// GB8.\n\t{grAny, prLVT}: {grLVTT, grBoundary, 9990},\n\t{grAny, prT}:   {grLVTT, grBoundary, 9990},\n\t{grLVTT, prT}:  {grLVTT, grNoBoundary, 80},\n\n\t// GB9.\n\t{grAny, prExtend}: {grAny, grNoBoundary, 90},\n\t{grAny, prZWJ}:    {grAny, grNoBoundary, 90},\n\n\t// GB9a.\n\t{grAny, prSpacingMark}: {grAny, grNoBoundary, 91},\n\n\t// GB9b.\n\t{grAny, prPreprend}: {grPrepend, grBoundary, 9990},\n\t{grPrepend, prAny}:  {grAny, grNoBoundary, 92},\n\n\t// GB11.\n\t{grAny, prExtendedPictographic}:                     {grExtendedPictographic, grBoundary, 9990},\n\t{grExtendedPictographic, prExtend}:                  {grExtendedPictographic, grNoBoundary, 110},\n\t{grExtendedPictographic, prZWJ}:                     {grExtendedPictographicZWJ, grNoBoundary, 110},\n\t{grExtendedPictographicZWJ, prExtendedPictographic}: {grExtendedPictographic, grNoBoundary, 110},\n\n\t// GB12 / GB13.\n\t{grAny, prRegionalIndicator}:    {grRIOdd, grBoundary, 9990},\n\t{grRIOdd, prRegionalIndicator}:  {grRIEven, grNoBoundary, 120},\n\t{grRIEven, prRegionalIndicator}: {grRIOdd, grBoundary, 120},\n}\n\n// Graphemes implements an iterator over Unicode extended grapheme clusters,\n// specified in the Unicode Standard Annex #29. Grapheme clusters correspond to\n// \"user-perceived characters\". These characters often consist of multiple\n// code points (e.g. the \"woman kissing woman\" emoji consists of 8 code points:\n// woman + ZWJ + heavy black heart (2 code points) + ZWJ + kiss mark + ZWJ +\n// woman) and the rules described in Annex #29 must be applied to group those\n// code points into clusters perceived by the user as one character.\ntype Graphemes struct {\n\t// The code points over which this class iterates.\n\tcodePoints []rune\n\n\t// The (byte-based) indices of the code points into the original string plus\n\t// len(original string). Thus, len(indices) = len(codePoints) + 1.\n\tindices []int\n\n\t// The current grapheme cluster to be returned. These are indices into\n\t// codePoints/indices. If start == end, we either haven't started iterating\n\t// yet (0) or the iteration has already completed (1).\n\tstart, end int\n\n\t// The index of the next code point to be parsed.\n\tpos int\n\n\t// The current state of the code point parser.\n\tstate int\n}\n\n// NewGraphemes returns a new grapheme cluster iterator.\nfunc NewGraphemes(s string) *Graphemes {\n\tl := utf8.RuneCountInString(s)\n\tcodePoints := make([]rune, l)\n\tindices := make([]int, l+1)\n\ti := 0\n\tfor pos, r := range s {\n\t\tcodePoints[i] = r\n\t\tindices[i] = pos\n\t\ti++\n\t}\n\tindices[l] = len(s)\n\tg := &Graphemes{\n\t\tcodePoints: codePoints,\n\t\tindices:    indices,\n\t}\n\tg.Next() // Parse ahead.\n\treturn g\n}\n\n// Next advances the iterator by one grapheme cluster and returns false if no\n// clusters are left. This function must be called before the first cluster is\n// accessed.\nfunc (g *Graphemes) Next() bool {\n\tg.start = g.end\n\n\t// The state transition gives us a boundary instruction BEFORE the next code\n\t// point so we always need to stay ahead by one code point.\n\n\t// Parse the next code point.\n\tfor g.pos <= len(g.codePoints) {\n\t\t// GB2.\n\t\tif g.pos == len(g.codePoints) {\n\t\t\tg.end = g.pos\n\t\t\tg.pos++\n\t\t\tbreak\n\t\t}\n\n\t\t// Determine the property of the next character.\n\t\tnextProperty := property(g.codePoints[g.pos])\n\t\tg.pos++\n\n\t\t// Find the applicable transition.\n\t\tvar boundary bool\n\t\ttransition, ok := grTransitions[[2]int{g.state, nextProperty}]\n\t\tif ok {\n\t\t\t// We have a specific transition. We'll use it.\n\t\t\tg.state = transition[0]\n\t\t\tboundary = transition[1] == grBoundary\n\t\t} else {\n\t\t\t// No specific transition found. Try the less specific ones.\n\t\t\ttransAnyProp, okAnyProp := grTransitions[[2]int{g.state, prAny}]\n\t\t\ttransAnyState, okAnyState := grTransitions[[2]int{grAny, nextProperty}]\n\t\t\tif okAnyProp && okAnyState {\n\t\t\t\t// Both apply. We'll use a mix (see comments for grTransitions).\n\t\t\t\tg.state = transAnyState[0]\n\t\t\t\tboundary = transAnyState[1] == grBoundary\n\t\t\t\tif transAnyProp[2] < transAnyState[2] {\n\t\t\t\t\tg.state = transAnyProp[0]\n\t\t\t\t\tboundary = transAnyProp[1] == grBoundary\n\t\t\t\t}\n\t\t\t} else if okAnyProp {\n\t\t\t\t// We only have a specific state.\n\t\t\t\tg.state = transAnyProp[0]\n\t\t\t\tboundary = transAnyProp[1] == grBoundary\n\t\t\t\t// This branch will probably never be reached because okAnyState will\n\t\t\t\t// always be true given the current transition map. But we keep it here\n\t\t\t\t// for future modifications to the transition map where this may not be\n\t\t\t\t// true anymore.\n\t\t\t} else if okAnyState {\n\t\t\t\t// We only have a specific property.\n\t\t\t\tg.state = transAnyState[0]\n\t\t\t\tboundary = transAnyState[1] == grBoundary\n\t\t\t} else {\n\t\t\t\t// No known transition. GB999: Any x Any.\n\t\t\t\tg.state = grAny\n\t\t\t\tboundary = true\n\t\t\t}\n\t\t}\n\n\t\t// If we found a cluster boundary, let's stop here. The current cluster will\n\t\t// be the one that just ended.\n\t\tif g.pos-1 == 0 /* GB1 */ || boundary {\n\t\t\tg.end = g.pos - 1\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn g.start != g.end\n}\n\n// Runes returns a slice of runes (code points) which corresponds to the current\n// grapheme cluster. If the iterator is already past the end or Next() has not\n// yet been called, nil is returned.\nfunc (g *Graphemes) Runes() []rune {\n\tif g.start == g.end {\n\t\treturn nil\n\t}\n\treturn g.codePoints[g.start:g.end]\n}\n\n// Str returns a substring of the original string which corresponds to the\n// current grapheme cluster. If the iterator is already past the end or Next()\n// has not yet been called, an empty string is returned.\nfunc (g *Graphemes) Str() string {\n\tif g.start == g.end {\n\t\treturn \"\"\n\t}\n\treturn string(g.codePoints[g.start:g.end])\n}\n\n// Bytes returns a byte slice which corresponds to the current grapheme cluster.\n// If the iterator is already past the end or Next() has not yet been called,\n// nil is returned.\nfunc (g *Graphemes) Bytes() []byte {\n\tif g.start == g.end {\n\t\treturn nil\n\t}\n\treturn []byte(string(g.codePoints[g.start:g.end]))\n}\n\n// Positions returns the interval of the current grapheme cluster as byte\n// positions into the original string. The first returned value \"from\" indexes\n// the first byte and the second returned value \"to\" indexes the first byte that\n// is not included anymore, i.e. str[from:to] is the current grapheme cluster of\n// the original string \"str\". If Next() has not yet been called, both values are\n// 0. If the iterator is already past the end, both values are 1.\nfunc (g *Graphemes) Positions() (int, int) {\n\treturn g.indices[g.start], g.indices[g.end]\n}\n\n// Reset puts the iterator into its initial state such that the next call to\n// Next() sets it to the first grapheme cluster again.\nfunc (g *Graphemes) Reset() {\n\tg.start, g.end, g.pos, g.state = 0, 0, 0, grAny\n\tg.Next() // Parse ahead again.\n}\n\n// GraphemeClusterCount returns the number of user-perceived characters\n// (grapheme clusters) for the given string. To calculate this number, it\n// iterates through the string using the Graphemes iterator.\nfunc GraphemeClusterCount(s string) (n int) {\n\tg := NewGraphemes(s)\n\tfor g.Next() {\n\t\tn++\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/rivo/uniseg/properties.go",
    "content": "package uniseg\n\n// The unicode properties. Only the ones needed in the context of this package\n// are included.\nconst (\n\tprAny = iota\n\tprPreprend\n\tprCR\n\tprLF\n\tprControl\n\tprExtend\n\tprRegionalIndicator\n\tprSpacingMark\n\tprL\n\tprV\n\tprT\n\tprLV\n\tprLVT\n\tprZWJ\n\tprExtendedPictographic\n)\n\n// Maps code point ranges to their properties. In the context of this package,\n// any code point that is not contained may map to \"prAny\". The code point\n// ranges in this slice are numerically sorted.\n//\n// These ranges were taken from\n// http://www.unicode.org/Public/UCD/latest/ucd/auxiliary/GraphemeBreakProperty.txt\n// as well as\n// https://unicode.org/Public/emoji/latest/emoji-data.txt\n// (\"Extended_Pictographic\" only) on March 11, 2019. See\n// https://www.unicode.org/license.html for the Unicode license agreement.\nvar codePoints = [][3]int{\n\t{0x0000, 0x0009, prControl},                // Cc  [10] <control-0000>..<control-0009>\n\t{0x000A, 0x000A, prLF},                     // Cc       <control-000A>\n\t{0x000B, 0x000C, prControl},                // Cc   [2] <control-000B>..<control-000C>\n\t{0x000D, 0x000D, prCR},                     // Cc       <control-000D>\n\t{0x000E, 0x001F, prControl},                // Cc  [18] <control-000E>..<control-001F>\n\t{0x007F, 0x009F, prControl},                // Cc  [33] <control-007F>..<control-009F>\n\t{0x00A9, 0x00A9, prExtendedPictographic},   //  1.1  [1] (©️)       copyright\n\t{0x00AD, 0x00AD, prControl},                // Cf       SOFT HYPHEN\n\t{0x00AE, 0x00AE, prExtendedPictographic},   //  1.1  [1] (®️)       registered\n\t{0x0300, 0x036F, prExtend},                 // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X\n\t{0x0483, 0x0487, prExtend},                 // Mn   [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE\n\t{0x0488, 0x0489, prExtend},                 // Me   [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN\n\t{0x0591, 0x05BD, prExtend},                 // Mn  [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG\n\t{0x05BF, 0x05BF, prExtend},                 // Mn       HEBREW POINT RAFE\n\t{0x05C1, 0x05C2, prExtend},                 // Mn   [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT\n\t{0x05C4, 0x05C5, prExtend},                 // Mn   [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT\n\t{0x05C7, 0x05C7, prExtend},                 // Mn       HEBREW POINT QAMATS QATAN\n\t{0x0600, 0x0605, prPreprend},               // Cf   [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE\n\t{0x0610, 0x061A, prExtend},                 // Mn  [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA\n\t{0x061C, 0x061C, prControl},                // Cf       ARABIC LETTER MARK\n\t{0x064B, 0x065F, prExtend},                 // Mn  [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW\n\t{0x0670, 0x0670, prExtend},                 // Mn       ARABIC LETTER SUPERSCRIPT ALEF\n\t{0x06D6, 0x06DC, prExtend},                 // Mn   [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN\n\t{0x06DD, 0x06DD, prPreprend},               // Cf       ARABIC END OF AYAH\n\t{0x06DF, 0x06E4, prExtend},                 // Mn   [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA\n\t{0x06E7, 0x06E8, prExtend},                 // Mn   [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON\n\t{0x06EA, 0x06ED, prExtend},                 // Mn   [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM\n\t{0x070F, 0x070F, prPreprend},               // Cf       SYRIAC ABBREVIATION MARK\n\t{0x0711, 0x0711, prExtend},                 // Mn       SYRIAC LETTER SUPERSCRIPT ALAPH\n\t{0x0730, 0x074A, prExtend},                 // Mn  [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH\n\t{0x07A6, 0x07B0, prExtend},                 // Mn  [11] THAANA ABAFILI..THAANA SUKUN\n\t{0x07EB, 0x07F3, prExtend},                 // Mn   [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE\n\t{0x07FD, 0x07FD, prExtend},                 // Mn       NKO DANTAYALAN\n\t{0x0816, 0x0819, prExtend},                 // Mn   [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH\n\t{0x081B, 0x0823, prExtend},                 // Mn   [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A\n\t{0x0825, 0x0827, prExtend},                 // Mn   [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U\n\t{0x0829, 0x082D, prExtend},                 // Mn   [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA\n\t{0x0859, 0x085B, prExtend},                 // Mn   [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK\n\t{0x08D3, 0x08E1, prExtend},                 // Mn  [15] ARABIC SMALL LOW WAW..ARABIC SMALL HIGH SIGN SAFHA\n\t{0x08E2, 0x08E2, prPreprend},               // Cf       ARABIC DISPUTED END OF AYAH\n\t{0x08E3, 0x0902, prExtend},                 // Mn  [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA\n\t{0x0903, 0x0903, prSpacingMark},            // Mc       DEVANAGARI SIGN VISARGA\n\t{0x093A, 0x093A, prExtend},                 // Mn       DEVANAGARI VOWEL SIGN OE\n\t{0x093B, 0x093B, prSpacingMark},            // Mc       DEVANAGARI VOWEL SIGN OOE\n\t{0x093C, 0x093C, prExtend},                 // Mn       DEVANAGARI SIGN NUKTA\n\t{0x093E, 0x0940, prSpacingMark},            // Mc   [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II\n\t{0x0941, 0x0948, prExtend},                 // Mn   [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI\n\t{0x0949, 0x094C, prSpacingMark},            // Mc   [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU\n\t{0x094D, 0x094D, prExtend},                 // Mn       DEVANAGARI SIGN VIRAMA\n\t{0x094E, 0x094F, prSpacingMark},            // Mc   [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW\n\t{0x0951, 0x0957, prExtend},                 // Mn   [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE\n\t{0x0962, 0x0963, prExtend},                 // Mn   [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL\n\t{0x0981, 0x0981, prExtend},                 // Mn       BENGALI SIGN CANDRABINDU\n\t{0x0982, 0x0983, prSpacingMark},            // Mc   [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA\n\t{0x09BC, 0x09BC, prExtend},                 // Mn       BENGALI SIGN NUKTA\n\t{0x09BE, 0x09BE, prExtend},                 // Mc       BENGALI VOWEL SIGN AA\n\t{0x09BF, 0x09C0, prSpacingMark},            // Mc   [2] BENGALI VOWEL SIGN I..BENGALI VOWEL SIGN II\n\t{0x09C1, 0x09C4, prExtend},                 // Mn   [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR\n\t{0x09C7, 0x09C8, prSpacingMark},            // Mc   [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI\n\t{0x09CB, 0x09CC, prSpacingMark},            // Mc   [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU\n\t{0x09CD, 0x09CD, prExtend},                 // Mn       BENGALI SIGN VIRAMA\n\t{0x09D7, 0x09D7, prExtend},                 // Mc       BENGALI AU LENGTH MARK\n\t{0x09E2, 0x09E3, prExtend},                 // Mn   [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL\n\t{0x09FE, 0x09FE, prExtend},                 // Mn       BENGALI SANDHI MARK\n\t{0x0A01, 0x0A02, prExtend},                 // Mn   [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI\n\t{0x0A03, 0x0A03, prSpacingMark},            // Mc       GURMUKHI SIGN VISARGA\n\t{0x0A3C, 0x0A3C, prExtend},                 // Mn       GURMUKHI SIGN NUKTA\n\t{0x0A3E, 0x0A40, prSpacingMark},            // Mc   [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II\n\t{0x0A41, 0x0A42, prExtend},                 // Mn   [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU\n\t{0x0A47, 0x0A48, prExtend},                 // Mn   [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI\n\t{0x0A4B, 0x0A4D, prExtend},                 // Mn   [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA\n\t{0x0A51, 0x0A51, prExtend},                 // Mn       GURMUKHI SIGN UDAAT\n\t{0x0A70, 0x0A71, prExtend},                 // Mn   [2] GURMUKHI TIPPI..GURMUKHI ADDAK\n\t{0x0A75, 0x0A75, prExtend},                 // Mn       GURMUKHI SIGN YAKASH\n\t{0x0A81, 0x0A82, prExtend},                 // Mn   [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA\n\t{0x0A83, 0x0A83, prSpacingMark},            // Mc       GUJARATI SIGN VISARGA\n\t{0x0ABC, 0x0ABC, prExtend},                 // Mn       GUJARATI SIGN NUKTA\n\t{0x0ABE, 0x0AC0, prSpacingMark},            // Mc   [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II\n\t{0x0AC1, 0x0AC5, prExtend},                 // Mn   [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E\n\t{0x0AC7, 0x0AC8, prExtend},                 // Mn   [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI\n\t{0x0AC9, 0x0AC9, prSpacingMark},            // Mc       GUJARATI VOWEL SIGN CANDRA O\n\t{0x0ACB, 0x0ACC, prSpacingMark},            // Mc   [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU\n\t{0x0ACD, 0x0ACD, prExtend},                 // Mn       GUJARATI SIGN VIRAMA\n\t{0x0AE2, 0x0AE3, prExtend},                 // Mn   [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL\n\t{0x0AFA, 0x0AFF, prExtend},                 // Mn   [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE\n\t{0x0B01, 0x0B01, prExtend},                 // Mn       ORIYA SIGN CANDRABINDU\n\t{0x0B02, 0x0B03, prSpacingMark},            // Mc   [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA\n\t{0x0B3C, 0x0B3C, prExtend},                 // Mn       ORIYA SIGN NUKTA\n\t{0x0B3E, 0x0B3E, prExtend},                 // Mc       ORIYA VOWEL SIGN AA\n\t{0x0B3F, 0x0B3F, prExtend},                 // Mn       ORIYA VOWEL SIGN I\n\t{0x0B40, 0x0B40, prSpacingMark},            // Mc       ORIYA VOWEL SIGN II\n\t{0x0B41, 0x0B44, prExtend},                 // Mn   [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR\n\t{0x0B47, 0x0B48, prSpacingMark},            // Mc   [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI\n\t{0x0B4B, 0x0B4C, prSpacingMark},            // Mc   [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU\n\t{0x0B4D, 0x0B4D, prExtend},                 // Mn       ORIYA SIGN VIRAMA\n\t{0x0B56, 0x0B56, prExtend},                 // Mn       ORIYA AI LENGTH MARK\n\t{0x0B57, 0x0B57, prExtend},                 // Mc       ORIYA AU LENGTH MARK\n\t{0x0B62, 0x0B63, prExtend},                 // Mn   [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL\n\t{0x0B82, 0x0B82, prExtend},                 // Mn       TAMIL SIGN ANUSVARA\n\t{0x0BBE, 0x0BBE, prExtend},                 // Mc       TAMIL VOWEL SIGN AA\n\t{0x0BBF, 0x0BBF, prSpacingMark},            // Mc       TAMIL VOWEL SIGN I\n\t{0x0BC0, 0x0BC0, prExtend},                 // Mn       TAMIL VOWEL SIGN II\n\t{0x0BC1, 0x0BC2, prSpacingMark},            // Mc   [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU\n\t{0x0BC6, 0x0BC8, prSpacingMark},            // Mc   [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI\n\t{0x0BCA, 0x0BCC, prSpacingMark},            // Mc   [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU\n\t{0x0BCD, 0x0BCD, prExtend},                 // Mn       TAMIL SIGN VIRAMA\n\t{0x0BD7, 0x0BD7, prExtend},                 // Mc       TAMIL AU LENGTH MARK\n\t{0x0C00, 0x0C00, prExtend},                 // Mn       TELUGU SIGN COMBINING CANDRABINDU ABOVE\n\t{0x0C01, 0x0C03, prSpacingMark},            // Mc   [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA\n\t{0x0C04, 0x0C04, prExtend},                 // Mn       TELUGU SIGN COMBINING ANUSVARA ABOVE\n\t{0x0C3E, 0x0C40, prExtend},                 // Mn   [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II\n\t{0x0C41, 0x0C44, prSpacingMark},            // Mc   [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR\n\t{0x0C46, 0x0C48, prExtend},                 // Mn   [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI\n\t{0x0C4A, 0x0C4D, prExtend},                 // Mn   [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA\n\t{0x0C55, 0x0C56, prExtend},                 // Mn   [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK\n\t{0x0C62, 0x0C63, prExtend},                 // Mn   [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL\n\t{0x0C81, 0x0C81, prExtend},                 // Mn       KANNADA SIGN CANDRABINDU\n\t{0x0C82, 0x0C83, prSpacingMark},            // Mc   [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA\n\t{0x0CBC, 0x0CBC, prExtend},                 // Mn       KANNADA SIGN NUKTA\n\t{0x0CBE, 0x0CBE, prSpacingMark},            // Mc       KANNADA VOWEL SIGN AA\n\t{0x0CBF, 0x0CBF, prExtend},                 // Mn       KANNADA VOWEL SIGN I\n\t{0x0CC0, 0x0CC1, prSpacingMark},            // Mc   [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U\n\t{0x0CC2, 0x0CC2, prExtend},                 // Mc       KANNADA VOWEL SIGN UU\n\t{0x0CC3, 0x0CC4, prSpacingMark},            // Mc   [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR\n\t{0x0CC6, 0x0CC6, prExtend},                 // Mn       KANNADA VOWEL SIGN E\n\t{0x0CC7, 0x0CC8, prSpacingMark},            // Mc   [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI\n\t{0x0CCA, 0x0CCB, prSpacingMark},            // Mc   [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO\n\t{0x0CCC, 0x0CCD, prExtend},                 // Mn   [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA\n\t{0x0CD5, 0x0CD6, prExtend},                 // Mc   [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK\n\t{0x0CE2, 0x0CE3, prExtend},                 // Mn   [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL\n\t{0x0D00, 0x0D01, prExtend},                 // Mn   [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU\n\t{0x0D02, 0x0D03, prSpacingMark},            // Mc   [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA\n\t{0x0D3B, 0x0D3C, prExtend},                 // Mn   [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA\n\t{0x0D3E, 0x0D3E, prExtend},                 // Mc       MALAYALAM VOWEL SIGN AA\n\t{0x0D3F, 0x0D40, prSpacingMark},            // Mc   [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II\n\t{0x0D41, 0x0D44, prExtend},                 // Mn   [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR\n\t{0x0D46, 0x0D48, prSpacingMark},            // Mc   [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI\n\t{0x0D4A, 0x0D4C, prSpacingMark},            // Mc   [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU\n\t{0x0D4D, 0x0D4D, prExtend},                 // Mn       MALAYALAM SIGN VIRAMA\n\t{0x0D4E, 0x0D4E, prPreprend},               // Lo       MALAYALAM LETTER DOT REPH\n\t{0x0D57, 0x0D57, prExtend},                 // Mc       MALAYALAM AU LENGTH MARK\n\t{0x0D62, 0x0D63, prExtend},                 // Mn   [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL\n\t{0x0D82, 0x0D83, prSpacingMark},            // Mc   [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA\n\t{0x0DCA, 0x0DCA, prExtend},                 // Mn       SINHALA SIGN AL-LAKUNA\n\t{0x0DCF, 0x0DCF, prExtend},                 // Mc       SINHALA VOWEL SIGN AELA-PILLA\n\t{0x0DD0, 0x0DD1, prSpacingMark},            // Mc   [2] SINHALA VOWEL SIGN KETTI AEDA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA\n\t{0x0DD2, 0x0DD4, prExtend},                 // Mn   [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA\n\t{0x0DD6, 0x0DD6, prExtend},                 // Mn       SINHALA VOWEL SIGN DIGA PAA-PILLA\n\t{0x0DD8, 0x0DDE, prSpacingMark},            // Mc   [7] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA\n\t{0x0DDF, 0x0DDF, prExtend},                 // Mc       SINHALA VOWEL SIGN GAYANUKITTA\n\t{0x0DF2, 0x0DF3, prSpacingMark},            // Mc   [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA\n\t{0x0E31, 0x0E31, prExtend},                 // Mn       THAI CHARACTER MAI HAN-AKAT\n\t{0x0E33, 0x0E33, prSpacingMark},            // Lo       THAI CHARACTER SARA AM\n\t{0x0E34, 0x0E3A, prExtend},                 // Mn   [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU\n\t{0x0E47, 0x0E4E, prExtend},                 // Mn   [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN\n\t{0x0EB1, 0x0EB1, prExtend},                 // Mn       LAO VOWEL SIGN MAI KAN\n\t{0x0EB3, 0x0EB3, prSpacingMark},            // Lo       LAO VOWEL SIGN AM\n\t{0x0EB4, 0x0EBC, prExtend},                 // Mn   [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO\n\t{0x0EC8, 0x0ECD, prExtend},                 // Mn   [6] LAO TONE MAI EK..LAO NIGGAHITA\n\t{0x0F18, 0x0F19, prExtend},                 // Mn   [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS\n\t{0x0F35, 0x0F35, prExtend},                 // Mn       TIBETAN MARK NGAS BZUNG NYI ZLA\n\t{0x0F37, 0x0F37, prExtend},                 // Mn       TIBETAN MARK NGAS BZUNG SGOR RTAGS\n\t{0x0F39, 0x0F39, prExtend},                 // Mn       TIBETAN MARK TSA -PHRU\n\t{0x0F3E, 0x0F3F, prSpacingMark},            // Mc   [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES\n\t{0x0F71, 0x0F7E, prExtend},                 // Mn  [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO\n\t{0x0F7F, 0x0F7F, prSpacingMark},            // Mc       TIBETAN SIGN RNAM BCAD\n\t{0x0F80, 0x0F84, prExtend},                 // Mn   [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA\n\t{0x0F86, 0x0F87, prExtend},                 // Mn   [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS\n\t{0x0F8D, 0x0F97, prExtend},                 // Mn  [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA\n\t{0x0F99, 0x0FBC, prExtend},                 // Mn  [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA\n\t{0x0FC6, 0x0FC6, prExtend},                 // Mn       TIBETAN SYMBOL PADMA GDAN\n\t{0x102D, 0x1030, prExtend},                 // Mn   [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU\n\t{0x1031, 0x1031, prSpacingMark},            // Mc       MYANMAR VOWEL SIGN E\n\t{0x1032, 0x1037, prExtend},                 // Mn   [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW\n\t{0x1039, 0x103A, prExtend},                 // Mn   [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT\n\t{0x103B, 0x103C, prSpacingMark},            // Mc   [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA\n\t{0x103D, 0x103E, prExtend},                 // Mn   [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA\n\t{0x1056, 0x1057, prSpacingMark},            // Mc   [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR\n\t{0x1058, 0x1059, prExtend},                 // Mn   [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL\n\t{0x105E, 0x1060, prExtend},                 // Mn   [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA\n\t{0x1071, 0x1074, prExtend},                 // Mn   [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE\n\t{0x1082, 0x1082, prExtend},                 // Mn       MYANMAR CONSONANT SIGN SHAN MEDIAL WA\n\t{0x1084, 0x1084, prSpacingMark},            // Mc       MYANMAR VOWEL SIGN SHAN E\n\t{0x1085, 0x1086, prExtend},                 // Mn   [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y\n\t{0x108D, 0x108D, prExtend},                 // Mn       MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE\n\t{0x109D, 0x109D, prExtend},                 // Mn       MYANMAR VOWEL SIGN AITON AI\n\t{0x1100, 0x115F, prL},                      // Lo  [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER\n\t{0x1160, 0x11A7, prV},                      // Lo  [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE\n\t{0x11A8, 0x11FF, prT},                      // Lo  [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN\n\t{0x135D, 0x135F, prExtend},                 // Mn   [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK\n\t{0x1712, 0x1714, prExtend},                 // Mn   [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA\n\t{0x1732, 0x1734, prExtend},                 // Mn   [3] HANUNOO VOWEL SIGN I..HANUNOO SIGN PAMUDPOD\n\t{0x1752, 0x1753, prExtend},                 // Mn   [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U\n\t{0x1772, 0x1773, prExtend},                 // Mn   [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U\n\t{0x17B4, 0x17B5, prExtend},                 // Mn   [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA\n\t{0x17B6, 0x17B6, prSpacingMark},            // Mc       KHMER VOWEL SIGN AA\n\t{0x17B7, 0x17BD, prExtend},                 // Mn   [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA\n\t{0x17BE, 0x17C5, prSpacingMark},            // Mc   [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU\n\t{0x17C6, 0x17C6, prExtend},                 // Mn       KHMER SIGN NIKAHIT\n\t{0x17C7, 0x17C8, prSpacingMark},            // Mc   [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU\n\t{0x17C9, 0x17D3, prExtend},                 // Mn  [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT\n\t{0x17DD, 0x17DD, prExtend},                 // Mn       KHMER SIGN ATTHACAN\n\t{0x180B, 0x180D, prExtend},                 // Mn   [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE\n\t{0x180E, 0x180E, prControl},                // Cf       MONGOLIAN VOWEL SEPARATOR\n\t{0x1885, 0x1886, prExtend},                 // Mn   [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA\n\t{0x18A9, 0x18A9, prExtend},                 // Mn       MONGOLIAN LETTER ALI GALI DAGALGA\n\t{0x1920, 0x1922, prExtend},                 // Mn   [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U\n\t{0x1923, 0x1926, prSpacingMark},            // Mc   [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU\n\t{0x1927, 0x1928, prExtend},                 // Mn   [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O\n\t{0x1929, 0x192B, prSpacingMark},            // Mc   [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA\n\t{0x1930, 0x1931, prSpacingMark},            // Mc   [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA\n\t{0x1932, 0x1932, prExtend},                 // Mn       LIMBU SMALL LETTER ANUSVARA\n\t{0x1933, 0x1938, prSpacingMark},            // Mc   [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA\n\t{0x1939, 0x193B, prExtend},                 // Mn   [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I\n\t{0x1A17, 0x1A18, prExtend},                 // Mn   [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U\n\t{0x1A19, 0x1A1A, prSpacingMark},            // Mc   [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O\n\t{0x1A1B, 0x1A1B, prExtend},                 // Mn       BUGINESE VOWEL SIGN AE\n\t{0x1A55, 0x1A55, prSpacingMark},            // Mc       TAI THAM CONSONANT SIGN MEDIAL RA\n\t{0x1A56, 0x1A56, prExtend},                 // Mn       TAI THAM CONSONANT SIGN MEDIAL LA\n\t{0x1A57, 0x1A57, prSpacingMark},            // Mc       TAI THAM CONSONANT SIGN LA TANG LAI\n\t{0x1A58, 0x1A5E, prExtend},                 // Mn   [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA\n\t{0x1A60, 0x1A60, prExtend},                 // Mn       TAI THAM SIGN SAKOT\n\t{0x1A62, 0x1A62, prExtend},                 // Mn       TAI THAM VOWEL SIGN MAI SAT\n\t{0x1A65, 0x1A6C, prExtend},                 // Mn   [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW\n\t{0x1A6D, 0x1A72, prSpacingMark},            // Mc   [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI\n\t{0x1A73, 0x1A7C, prExtend},                 // Mn  [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN\n\t{0x1A7F, 0x1A7F, prExtend},                 // Mn       TAI THAM COMBINING CRYPTOGRAMMIC DOT\n\t{0x1AB0, 0x1ABD, prExtend},                 // Mn  [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW\n\t{0x1ABE, 0x1ABE, prExtend},                 // Me       COMBINING PARENTHESES OVERLAY\n\t{0x1B00, 0x1B03, prExtend},                 // Mn   [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG\n\t{0x1B04, 0x1B04, prSpacingMark},            // Mc       BALINESE SIGN BISAH\n\t{0x1B34, 0x1B34, prExtend},                 // Mn       BALINESE SIGN REREKAN\n\t{0x1B35, 0x1B35, prExtend},                 // Mc       BALINESE VOWEL SIGN TEDUNG\n\t{0x1B36, 0x1B3A, prExtend},                 // Mn   [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA\n\t{0x1B3B, 0x1B3B, prSpacingMark},            // Mc       BALINESE VOWEL SIGN RA REPA TEDUNG\n\t{0x1B3C, 0x1B3C, prExtend},                 // Mn       BALINESE VOWEL SIGN LA LENGA\n\t{0x1B3D, 0x1B41, prSpacingMark},            // Mc   [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG\n\t{0x1B42, 0x1B42, prExtend},                 // Mn       BALINESE VOWEL SIGN PEPET\n\t{0x1B43, 0x1B44, prSpacingMark},            // Mc   [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG\n\t{0x1B6B, 0x1B73, prExtend},                 // Mn   [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG\n\t{0x1B80, 0x1B81, prExtend},                 // Mn   [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR\n\t{0x1B82, 0x1B82, prSpacingMark},            // Mc       SUNDANESE SIGN PANGWISAD\n\t{0x1BA1, 0x1BA1, prSpacingMark},            // Mc       SUNDANESE CONSONANT SIGN PAMINGKAL\n\t{0x1BA2, 0x1BA5, prExtend},                 // Mn   [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU\n\t{0x1BA6, 0x1BA7, prSpacingMark},            // Mc   [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG\n\t{0x1BA8, 0x1BA9, prExtend},                 // Mn   [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG\n\t{0x1BAA, 0x1BAA, prSpacingMark},            // Mc       SUNDANESE SIGN PAMAAEH\n\t{0x1BAB, 0x1BAD, prExtend},                 // Mn   [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA\n\t{0x1BE6, 0x1BE6, prExtend},                 // Mn       BATAK SIGN TOMPI\n\t{0x1BE7, 0x1BE7, prSpacingMark},            // Mc       BATAK VOWEL SIGN E\n\t{0x1BE8, 0x1BE9, prExtend},                 // Mn   [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE\n\t{0x1BEA, 0x1BEC, prSpacingMark},            // Mc   [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O\n\t{0x1BED, 0x1BED, prExtend},                 // Mn       BATAK VOWEL SIGN KARO O\n\t{0x1BEE, 0x1BEE, prSpacingMark},            // Mc       BATAK VOWEL SIGN U\n\t{0x1BEF, 0x1BF1, prExtend},                 // Mn   [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H\n\t{0x1BF2, 0x1BF3, prSpacingMark},            // Mc   [2] BATAK PANGOLAT..BATAK PANONGONAN\n\t{0x1C24, 0x1C2B, prSpacingMark},            // Mc   [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU\n\t{0x1C2C, 0x1C33, prExtend},                 // Mn   [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T\n\t{0x1C34, 0x1C35, prSpacingMark},            // Mc   [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG\n\t{0x1C36, 0x1C37, prExtend},                 // Mn   [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA\n\t{0x1CD0, 0x1CD2, prExtend},                 // Mn   [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA\n\t{0x1CD4, 0x1CE0, prExtend},                 // Mn  [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA\n\t{0x1CE1, 0x1CE1, prSpacingMark},            // Mc       VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA\n\t{0x1CE2, 0x1CE8, prExtend},                 // Mn   [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL\n\t{0x1CED, 0x1CED, prExtend},                 // Mn       VEDIC SIGN TIRYAK\n\t{0x1CF4, 0x1CF4, prExtend},                 // Mn       VEDIC TONE CANDRA ABOVE\n\t{0x1CF7, 0x1CF7, prSpacingMark},            // Mc       VEDIC SIGN ATIKRAMA\n\t{0x1CF8, 0x1CF9, prExtend},                 // Mn   [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE\n\t{0x1DC0, 0x1DF9, prExtend},                 // Mn  [58] COMBINING DOTTED GRAVE ACCENT..COMBINING WIDE INVERTED BRIDGE BELOW\n\t{0x1DFB, 0x1DFF, prExtend},                 // Mn   [5] COMBINING DELETION MARK..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW\n\t{0x200B, 0x200B, prControl},                // Cf       ZERO WIDTH SPACE\n\t{0x200C, 0x200C, prExtend},                 // Cf       ZERO WIDTH NON-JOINER\n\t{0x200D, 0x200D, prZWJ},                    // Cf       ZERO WIDTH JOINER\n\t{0x200E, 0x200F, prControl},                // Cf   [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK\n\t{0x2028, 0x2028, prControl},                // Zl       LINE SEPARATOR\n\t{0x2029, 0x2029, prControl},                // Zp       PARAGRAPH SEPARATOR\n\t{0x202A, 0x202E, prControl},                // Cf   [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE\n\t{0x203C, 0x203C, prExtendedPictographic},   //  1.1  [1] (‼️)       double exclamation mark\n\t{0x2049, 0x2049, prExtendedPictographic},   //  3.0  [1] (⁉️)       exclamation question mark\n\t{0x2060, 0x2064, prControl},                // Cf   [5] WORD JOINER..INVISIBLE PLUS\n\t{0x2065, 0x2065, prControl},                // Cn       <reserved-2065>\n\t{0x2066, 0x206F, prControl},                // Cf  [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES\n\t{0x20D0, 0x20DC, prExtend},                 // Mn  [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE\n\t{0x20DD, 0x20E0, prExtend},                 // Me   [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH\n\t{0x20E1, 0x20E1, prExtend},                 // Mn       COMBINING LEFT RIGHT ARROW ABOVE\n\t{0x20E2, 0x20E4, prExtend},                 // Me   [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE\n\t{0x20E5, 0x20F0, prExtend},                 // Mn  [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE\n\t{0x2122, 0x2122, prExtendedPictographic},   //  1.1  [1] (™️)       trade mark\n\t{0x2139, 0x2139, prExtendedPictographic},   //  3.0  [1] (ℹ️)       information\n\t{0x2194, 0x2199, prExtendedPictographic},   //  1.1  [6] (↔️..↙️)    left-right arrow..down-left arrow\n\t{0x21A9, 0x21AA, prExtendedPictographic},   //  1.1  [2] (↩️..↪️)    right arrow curving left..left arrow curving right\n\t{0x231A, 0x231B, prExtendedPictographic},   //  1.1  [2] (⌚..⌛)    watch..hourglass done\n\t{0x2328, 0x2328, prExtendedPictographic},   //  1.1  [1] (⌨️)       keyboard\n\t{0x2388, 0x2388, prExtendedPictographic},   //  3.0  [1] (⎈)       HELM SYMBOL\n\t{0x23CF, 0x23CF, prExtendedPictographic},   //  4.0  [1] (⏏️)       eject button\n\t{0x23E9, 0x23F3, prExtendedPictographic},   //  6.0 [11] (⏩..⏳)    fast-forward button..hourglass not done\n\t{0x23F8, 0x23FA, prExtendedPictographic},   //  7.0  [3] (⏸️..⏺️)    pause button..record button\n\t{0x24C2, 0x24C2, prExtendedPictographic},   //  1.1  [1] (Ⓜ️)       circled M\n\t{0x25AA, 0x25AB, prExtendedPictographic},   //  1.1  [2] (▪️..▫️)    black small square..white small square\n\t{0x25B6, 0x25B6, prExtendedPictographic},   //  1.1  [1] (▶️)       play button\n\t{0x25C0, 0x25C0, prExtendedPictographic},   //  1.1  [1] (◀️)       reverse button\n\t{0x25FB, 0x25FE, prExtendedPictographic},   //  3.2  [4] (◻️..◾)    white medium square..black medium-small square\n\t{0x2600, 0x2605, prExtendedPictographic},   //  1.1  [6] (☀️..★)    sun..BLACK STAR\n\t{0x2607, 0x2612, prExtendedPictographic},   //  1.1 [12] (☇..☒)    LIGHTNING..BALLOT BOX WITH X\n\t{0x2614, 0x2615, prExtendedPictographic},   //  4.0  [2] (☔..☕)    umbrella with rain drops..hot beverage\n\t{0x2616, 0x2617, prExtendedPictographic},   //  3.2  [2] (☖..☗)    WHITE SHOGI PIECE..BLACK SHOGI PIECE\n\t{0x2618, 0x2618, prExtendedPictographic},   //  4.1  [1] (☘️)       shamrock\n\t{0x2619, 0x2619, prExtendedPictographic},   //  3.0  [1] (☙)       REVERSED ROTATED FLORAL HEART BULLET\n\t{0x261A, 0x266F, prExtendedPictographic},   //  1.1 [86] (☚..♯)    BLACK LEFT POINTING INDEX..MUSIC SHARP SIGN\n\t{0x2670, 0x2671, prExtendedPictographic},   //  3.0  [2] (♰..♱)    WEST SYRIAC CROSS..EAST SYRIAC CROSS\n\t{0x2672, 0x267D, prExtendedPictographic},   //  3.2 [12] (♲..♽)    UNIVERSAL RECYCLING SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL\n\t{0x267E, 0x267F, prExtendedPictographic},   //  4.1  [2] (♾️..♿)    infinity..wheelchair symbol\n\t{0x2680, 0x2685, prExtendedPictographic},   //  3.2  [6] (⚀..⚅)    DIE FACE-1..DIE FACE-6\n\t{0x2690, 0x2691, prExtendedPictographic},   //  4.0  [2] (⚐..⚑)    WHITE FLAG..BLACK FLAG\n\t{0x2692, 0x269C, prExtendedPictographic},   //  4.1 [11] (⚒️..⚜️)    hammer and pick..fleur-de-lis\n\t{0x269D, 0x269D, prExtendedPictographic},   //  5.1  [1] (⚝)       OUTLINED WHITE STAR\n\t{0x269E, 0x269F, prExtendedPictographic},   //  5.2  [2] (⚞..⚟)    THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT\n\t{0x26A0, 0x26A1, prExtendedPictographic},   //  4.0  [2] (⚠️..⚡)    warning..high voltage\n\t{0x26A2, 0x26B1, prExtendedPictographic},   //  4.1 [16] (⚢..⚱️)    DOUBLED FEMALE SIGN..funeral urn\n\t{0x26B2, 0x26B2, prExtendedPictographic},   //  5.0  [1] (⚲)       NEUTER\n\t{0x26B3, 0x26BC, prExtendedPictographic},   //  5.1 [10] (⚳..⚼)    CERES..SESQUIQUADRATE\n\t{0x26BD, 0x26BF, prExtendedPictographic},   //  5.2  [3] (⚽..⚿)    soccer ball..SQUARED KEY\n\t{0x26C0, 0x26C3, prExtendedPictographic},   //  5.1  [4] (⛀..⛃)    WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING\n\t{0x26C4, 0x26CD, prExtendedPictographic},   //  5.2 [10] (⛄..⛍)    snowman without snow..DISABLED CAR\n\t{0x26CE, 0x26CE, prExtendedPictographic},   //  6.0  [1] (⛎)       Ophiuchus\n\t{0x26CF, 0x26E1, prExtendedPictographic},   //  5.2 [19] (⛏️..⛡)    pick..RESTRICTED LEFT ENTRY-2\n\t{0x26E2, 0x26E2, prExtendedPictographic},   //  6.0  [1] (⛢)       ASTRONOMICAL SYMBOL FOR URANUS\n\t{0x26E3, 0x26E3, prExtendedPictographic},   //  5.2  [1] (⛣)       HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE\n\t{0x26E4, 0x26E7, prExtendedPictographic},   //  6.0  [4] (⛤..⛧)    PENTAGRAM..INVERTED PENTAGRAM\n\t{0x26E8, 0x26FF, prExtendedPictographic},   //  5.2 [24] (⛨..⛿)    BLACK CROSS ON SHIELD..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE\n\t{0x2700, 0x2700, prExtendedPictographic},   //  7.0  [1] (✀)       BLACK SAFETY SCISSORS\n\t{0x2701, 0x2704, prExtendedPictographic},   //  1.1  [4] (✁..✄)    UPPER BLADE SCISSORS..WHITE SCISSORS\n\t{0x2705, 0x2705, prExtendedPictographic},   //  6.0  [1] (✅)       check mark button\n\t{0x2708, 0x2709, prExtendedPictographic},   //  1.1  [2] (✈️..✉️)    airplane..envelope\n\t{0x270A, 0x270B, prExtendedPictographic},   //  6.0  [2] (✊..✋)    raised fist..raised hand\n\t{0x270C, 0x2712, prExtendedPictographic},   //  1.1  [7] (✌️..✒️)    victory hand..black nib\n\t{0x2714, 0x2714, prExtendedPictographic},   //  1.1  [1] (✔️)       check mark\n\t{0x2716, 0x2716, prExtendedPictographic},   //  1.1  [1] (✖️)       multiplication sign\n\t{0x271D, 0x271D, prExtendedPictographic},   //  1.1  [1] (✝️)       latin cross\n\t{0x2721, 0x2721, prExtendedPictographic},   //  1.1  [1] (✡️)       star of David\n\t{0x2728, 0x2728, prExtendedPictographic},   //  6.0  [1] (✨)       sparkles\n\t{0x2733, 0x2734, prExtendedPictographic},   //  1.1  [2] (✳️..✴️)    eight-spoked asterisk..eight-pointed star\n\t{0x2744, 0x2744, prExtendedPictographic},   //  1.1  [1] (❄️)       snowflake\n\t{0x2747, 0x2747, prExtendedPictographic},   //  1.1  [1] (❇️)       sparkle\n\t{0x274C, 0x274C, prExtendedPictographic},   //  6.0  [1] (❌)       cross mark\n\t{0x274E, 0x274E, prExtendedPictographic},   //  6.0  [1] (❎)       cross mark button\n\t{0x2753, 0x2755, prExtendedPictographic},   //  6.0  [3] (❓..❕)    question mark..white exclamation mark\n\t{0x2757, 0x2757, prExtendedPictographic},   //  5.2  [1] (❗)       exclamation mark\n\t{0x2763, 0x2767, prExtendedPictographic},   //  1.1  [5] (❣️..❧)    heart exclamation..ROTATED FLORAL HEART BULLET\n\t{0x2795, 0x2797, prExtendedPictographic},   //  6.0  [3] (➕..➗)    plus sign..division sign\n\t{0x27A1, 0x27A1, prExtendedPictographic},   //  1.1  [1] (➡️)       right arrow\n\t{0x27B0, 0x27B0, prExtendedPictographic},   //  6.0  [1] (➰)       curly loop\n\t{0x27BF, 0x27BF, prExtendedPictographic},   //  6.0  [1] (➿)       double curly loop\n\t{0x2934, 0x2935, prExtendedPictographic},   //  3.2  [2] (⤴️..⤵️)    right arrow curving up..right arrow curving down\n\t{0x2B05, 0x2B07, prExtendedPictographic},   //  4.0  [3] (⬅️..⬇️)    left arrow..down arrow\n\t{0x2B1B, 0x2B1C, prExtendedPictographic},   //  5.1  [2] (⬛..⬜)    black large square..white large square\n\t{0x2B50, 0x2B50, prExtendedPictographic},   //  5.1  [1] (⭐)       star\n\t{0x2B55, 0x2B55, prExtendedPictographic},   //  5.2  [1] (⭕)       hollow red circle\n\t{0x2CEF, 0x2CF1, prExtend},                 // Mn   [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS\n\t{0x2D7F, 0x2D7F, prExtend},                 // Mn       TIFINAGH CONSONANT JOINER\n\t{0x2DE0, 0x2DFF, prExtend},                 // Mn  [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS\n\t{0x302A, 0x302D, prExtend},                 // Mn   [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK\n\t{0x302E, 0x302F, prExtend},                 // Mc   [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK\n\t{0x3030, 0x3030, prExtendedPictographic},   //  1.1  [1] (〰️)       wavy dash\n\t{0x303D, 0x303D, prExtendedPictographic},   //  3.2  [1] (〽️)       part alternation mark\n\t{0x3099, 0x309A, prExtend},                 // Mn   [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK\n\t{0x3297, 0x3297, prExtendedPictographic},   //  1.1  [1] (㊗️)       Japanese “congratulations” button\n\t{0x3299, 0x3299, prExtendedPictographic},   //  1.1  [1] (㊙️)       Japanese “secret” button\n\t{0xA66F, 0xA66F, prExtend},                 // Mn       COMBINING CYRILLIC VZMET\n\t{0xA670, 0xA672, prExtend},                 // Me   [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN\n\t{0xA674, 0xA67D, prExtend},                 // Mn  [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK\n\t{0xA69E, 0xA69F, prExtend},                 // Mn   [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E\n\t{0xA6F0, 0xA6F1, prExtend},                 // Mn   [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS\n\t{0xA802, 0xA802, prExtend},                 // Mn       SYLOTI NAGRI SIGN DVISVARA\n\t{0xA806, 0xA806, prExtend},                 // Mn       SYLOTI NAGRI SIGN HASANTA\n\t{0xA80B, 0xA80B, prExtend},                 // Mn       SYLOTI NAGRI SIGN ANUSVARA\n\t{0xA823, 0xA824, prSpacingMark},            // Mc   [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I\n\t{0xA825, 0xA826, prExtend},                 // Mn   [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E\n\t{0xA827, 0xA827, prSpacingMark},            // Mc       SYLOTI NAGRI VOWEL SIGN OO\n\t{0xA880, 0xA881, prSpacingMark},            // Mc   [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA\n\t{0xA8B4, 0xA8C3, prSpacingMark},            // Mc  [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU\n\t{0xA8C4, 0xA8C5, prExtend},                 // Mn   [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU\n\t{0xA8E0, 0xA8F1, prExtend},                 // Mn  [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA\n\t{0xA8FF, 0xA8FF, prExtend},                 // Mn       DEVANAGARI VOWEL SIGN AY\n\t{0xA926, 0xA92D, prExtend},                 // Mn   [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU\n\t{0xA947, 0xA951, prExtend},                 // Mn  [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R\n\t{0xA952, 0xA953, prSpacingMark},            // Mc   [2] REJANG CONSONANT SIGN H..REJANG VIRAMA\n\t{0xA960, 0xA97C, prL},                      // Lo  [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH\n\t{0xA980, 0xA982, prExtend},                 // Mn   [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR\n\t{0xA983, 0xA983, prSpacingMark},            // Mc       JAVANESE SIGN WIGNYAN\n\t{0xA9B3, 0xA9B3, prExtend},                 // Mn       JAVANESE SIGN CECAK TELU\n\t{0xA9B4, 0xA9B5, prSpacingMark},            // Mc   [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG\n\t{0xA9B6, 0xA9B9, prExtend},                 // Mn   [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT\n\t{0xA9BA, 0xA9BB, prSpacingMark},            // Mc   [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE\n\t{0xA9BC, 0xA9BD, prExtend},                 // Mn   [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET\n\t{0xA9BE, 0xA9C0, prSpacingMark},            // Mc   [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON\n\t{0xA9E5, 0xA9E5, prExtend},                 // Mn       MYANMAR SIGN SHAN SAW\n\t{0xAA29, 0xAA2E, prExtend},                 // Mn   [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE\n\t{0xAA2F, 0xAA30, prSpacingMark},            // Mc   [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI\n\t{0xAA31, 0xAA32, prExtend},                 // Mn   [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE\n\t{0xAA33, 0xAA34, prSpacingMark},            // Mc   [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA\n\t{0xAA35, 0xAA36, prExtend},                 // Mn   [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA\n\t{0xAA43, 0xAA43, prExtend},                 // Mn       CHAM CONSONANT SIGN FINAL NG\n\t{0xAA4C, 0xAA4C, prExtend},                 // Mn       CHAM CONSONANT SIGN FINAL M\n\t{0xAA4D, 0xAA4D, prSpacingMark},            // Mc       CHAM CONSONANT SIGN FINAL H\n\t{0xAA7C, 0xAA7C, prExtend},                 // Mn       MYANMAR SIGN TAI LAING TONE-2\n\t{0xAAB0, 0xAAB0, prExtend},                 // Mn       TAI VIET MAI KANG\n\t{0xAAB2, 0xAAB4, prExtend},                 // Mn   [3] TAI VIET VOWEL I..TAI VIET VOWEL U\n\t{0xAAB7, 0xAAB8, prExtend},                 // Mn   [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA\n\t{0xAABE, 0xAABF, prExtend},                 // Mn   [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK\n\t{0xAAC1, 0xAAC1, prExtend},                 // Mn       TAI VIET TONE MAI THO\n\t{0xAAEB, 0xAAEB, prSpacingMark},            // Mc       MEETEI MAYEK VOWEL SIGN II\n\t{0xAAEC, 0xAAED, prExtend},                 // Mn   [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI\n\t{0xAAEE, 0xAAEF, prSpacingMark},            // Mc   [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU\n\t{0xAAF5, 0xAAF5, prSpacingMark},            // Mc       MEETEI MAYEK VOWEL SIGN VISARGA\n\t{0xAAF6, 0xAAF6, prExtend},                 // Mn       MEETEI MAYEK VIRAMA\n\t{0xABE3, 0xABE4, prSpacingMark},            // Mc   [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP\n\t{0xABE5, 0xABE5, prExtend},                 // Mn       MEETEI MAYEK VOWEL SIGN ANAP\n\t{0xABE6, 0xABE7, prSpacingMark},            // Mc   [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP\n\t{0xABE8, 0xABE8, prExtend},                 // Mn       MEETEI MAYEK VOWEL SIGN UNAP\n\t{0xABE9, 0xABEA, prSpacingMark},            // Mc   [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG\n\t{0xABEC, 0xABEC, prSpacingMark},            // Mc       MEETEI MAYEK LUM IYEK\n\t{0xABED, 0xABED, prExtend},                 // Mn       MEETEI MAYEK APUN IYEK\n\t{0xAC00, 0xAC00, prLV},                     // Lo       HANGUL SYLLABLE GA\n\t{0xAC01, 0xAC1B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH\n\t{0xAC1C, 0xAC1C, prLV},                     // Lo       HANGUL SYLLABLE GAE\n\t{0xAC1D, 0xAC37, prLVT},                    // Lo  [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH\n\t{0xAC38, 0xAC38, prLV},                     // Lo       HANGUL SYLLABLE GYA\n\t{0xAC39, 0xAC53, prLVT},                    // Lo  [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH\n\t{0xAC54, 0xAC54, prLV},                     // Lo       HANGUL SYLLABLE GYAE\n\t{0xAC55, 0xAC6F, prLVT},                    // Lo  [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH\n\t{0xAC70, 0xAC70, prLV},                     // Lo       HANGUL SYLLABLE GEO\n\t{0xAC71, 0xAC8B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH\n\t{0xAC8C, 0xAC8C, prLV},                     // Lo       HANGUL SYLLABLE GE\n\t{0xAC8D, 0xACA7, prLVT},                    // Lo  [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH\n\t{0xACA8, 0xACA8, prLV},                     // Lo       HANGUL SYLLABLE GYEO\n\t{0xACA9, 0xACC3, prLVT},                    // Lo  [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH\n\t{0xACC4, 0xACC4, prLV},                     // Lo       HANGUL SYLLABLE GYE\n\t{0xACC5, 0xACDF, prLVT},                    // Lo  [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH\n\t{0xACE0, 0xACE0, prLV},                     // Lo       HANGUL SYLLABLE GO\n\t{0xACE1, 0xACFB, prLVT},                    // Lo  [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH\n\t{0xACFC, 0xACFC, prLV},                     // Lo       HANGUL SYLLABLE GWA\n\t{0xACFD, 0xAD17, prLVT},                    // Lo  [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH\n\t{0xAD18, 0xAD18, prLV},                     // Lo       HANGUL SYLLABLE GWAE\n\t{0xAD19, 0xAD33, prLVT},                    // Lo  [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH\n\t{0xAD34, 0xAD34, prLV},                     // Lo       HANGUL SYLLABLE GOE\n\t{0xAD35, 0xAD4F, prLVT},                    // Lo  [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH\n\t{0xAD50, 0xAD50, prLV},                     // Lo       HANGUL SYLLABLE GYO\n\t{0xAD51, 0xAD6B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH\n\t{0xAD6C, 0xAD6C, prLV},                     // Lo       HANGUL SYLLABLE GU\n\t{0xAD6D, 0xAD87, prLVT},                    // Lo  [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH\n\t{0xAD88, 0xAD88, prLV},                     // Lo       HANGUL SYLLABLE GWEO\n\t{0xAD89, 0xADA3, prLVT},                    // Lo  [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH\n\t{0xADA4, 0xADA4, prLV},                     // Lo       HANGUL SYLLABLE GWE\n\t{0xADA5, 0xADBF, prLVT},                    // Lo  [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH\n\t{0xADC0, 0xADC0, prLV},                     // Lo       HANGUL SYLLABLE GWI\n\t{0xADC1, 0xADDB, prLVT},                    // Lo  [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH\n\t{0xADDC, 0xADDC, prLV},                     // Lo       HANGUL SYLLABLE GYU\n\t{0xADDD, 0xADF7, prLVT},                    // Lo  [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH\n\t{0xADF8, 0xADF8, prLV},                     // Lo       HANGUL SYLLABLE GEU\n\t{0xADF9, 0xAE13, prLVT},                    // Lo  [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH\n\t{0xAE14, 0xAE14, prLV},                     // Lo       HANGUL SYLLABLE GYI\n\t{0xAE15, 0xAE2F, prLVT},                    // Lo  [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH\n\t{0xAE30, 0xAE30, prLV},                     // Lo       HANGUL SYLLABLE GI\n\t{0xAE31, 0xAE4B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH\n\t{0xAE4C, 0xAE4C, prLV},                     // Lo       HANGUL SYLLABLE GGA\n\t{0xAE4D, 0xAE67, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH\n\t{0xAE68, 0xAE68, prLV},                     // Lo       HANGUL SYLLABLE GGAE\n\t{0xAE69, 0xAE83, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH\n\t{0xAE84, 0xAE84, prLV},                     // Lo       HANGUL SYLLABLE GGYA\n\t{0xAE85, 0xAE9F, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH\n\t{0xAEA0, 0xAEA0, prLV},                     // Lo       HANGUL SYLLABLE GGYAE\n\t{0xAEA1, 0xAEBB, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH\n\t{0xAEBC, 0xAEBC, prLV},                     // Lo       HANGUL SYLLABLE GGEO\n\t{0xAEBD, 0xAED7, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH\n\t{0xAED8, 0xAED8, prLV},                     // Lo       HANGUL SYLLABLE GGE\n\t{0xAED9, 0xAEF3, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH\n\t{0xAEF4, 0xAEF4, prLV},                     // Lo       HANGUL SYLLABLE GGYEO\n\t{0xAEF5, 0xAF0F, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH\n\t{0xAF10, 0xAF10, prLV},                     // Lo       HANGUL SYLLABLE GGYE\n\t{0xAF11, 0xAF2B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH\n\t{0xAF2C, 0xAF2C, prLV},                     // Lo       HANGUL SYLLABLE GGO\n\t{0xAF2D, 0xAF47, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH\n\t{0xAF48, 0xAF48, prLV},                     // Lo       HANGUL SYLLABLE GGWA\n\t{0xAF49, 0xAF63, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH\n\t{0xAF64, 0xAF64, prLV},                     // Lo       HANGUL SYLLABLE GGWAE\n\t{0xAF65, 0xAF7F, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH\n\t{0xAF80, 0xAF80, prLV},                     // Lo       HANGUL SYLLABLE GGOE\n\t{0xAF81, 0xAF9B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH\n\t{0xAF9C, 0xAF9C, prLV},                     // Lo       HANGUL SYLLABLE GGYO\n\t{0xAF9D, 0xAFB7, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH\n\t{0xAFB8, 0xAFB8, prLV},                     // Lo       HANGUL SYLLABLE GGU\n\t{0xAFB9, 0xAFD3, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH\n\t{0xAFD4, 0xAFD4, prLV},                     // Lo       HANGUL SYLLABLE GGWEO\n\t{0xAFD5, 0xAFEF, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH\n\t{0xAFF0, 0xAFF0, prLV},                     // Lo       HANGUL SYLLABLE GGWE\n\t{0xAFF1, 0xB00B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH\n\t{0xB00C, 0xB00C, prLV},                     // Lo       HANGUL SYLLABLE GGWI\n\t{0xB00D, 0xB027, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH\n\t{0xB028, 0xB028, prLV},                     // Lo       HANGUL SYLLABLE GGYU\n\t{0xB029, 0xB043, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH\n\t{0xB044, 0xB044, prLV},                     // Lo       HANGUL SYLLABLE GGEU\n\t{0xB045, 0xB05F, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH\n\t{0xB060, 0xB060, prLV},                     // Lo       HANGUL SYLLABLE GGYI\n\t{0xB061, 0xB07B, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH\n\t{0xB07C, 0xB07C, prLV},                     // Lo       HANGUL SYLLABLE GGI\n\t{0xB07D, 0xB097, prLVT},                    // Lo  [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH\n\t{0xB098, 0xB098, prLV},                     // Lo       HANGUL SYLLABLE NA\n\t{0xB099, 0xB0B3, prLVT},                    // Lo  [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH\n\t{0xB0B4, 0xB0B4, prLV},                     // Lo       HANGUL SYLLABLE NAE\n\t{0xB0B5, 0xB0CF, prLVT},                    // Lo  [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH\n\t{0xB0D0, 0xB0D0, prLV},                     // Lo       HANGUL SYLLABLE NYA\n\t{0xB0D1, 0xB0EB, prLVT},                    // Lo  [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH\n\t{0xB0EC, 0xB0EC, prLV},                     // Lo       HANGUL SYLLABLE NYAE\n\t{0xB0ED, 0xB107, prLVT},                    // Lo  [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH\n\t{0xB108, 0xB108, prLV},                     // Lo       HANGUL SYLLABLE NEO\n\t{0xB109, 0xB123, prLVT},                    // Lo  [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH\n\t{0xB124, 0xB124, prLV},                     // Lo       HANGUL SYLLABLE NE\n\t{0xB125, 0xB13F, prLVT},                    // Lo  [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH\n\t{0xB140, 0xB140, prLV},                     // Lo       HANGUL SYLLABLE NYEO\n\t{0xB141, 0xB15B, prLVT},                    // Lo  [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH\n\t{0xB15C, 0xB15C, prLV},                     // Lo       HANGUL SYLLABLE NYE\n\t{0xB15D, 0xB177, prLVT},                    // Lo  [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH\n\t{0xB178, 0xB178, prLV},                     // Lo       HANGUL SYLLABLE NO\n\t{0xB179, 0xB193, prLVT},                    // Lo  [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH\n\t{0xB194, 0xB194, prLV},                     // Lo       HANGUL SYLLABLE NWA\n\t{0xB195, 0xB1AF, prLVT},                    // Lo  [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH\n\t{0xB1B0, 0xB1B0, prLV},                     // Lo       HANGUL SYLLABLE NWAE\n\t{0xB1B1, 0xB1CB, prLVT},                    // Lo  [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH\n\t{0xB1CC, 0xB1CC, prLV},                     // Lo       HANGUL SYLLABLE NOE\n\t{0xB1CD, 0xB1E7, prLVT},                    // Lo  [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH\n\t{0xB1E8, 0xB1E8, prLV},                     // Lo       HANGUL SYLLABLE NYO\n\t{0xB1E9, 0xB203, prLVT},                    // Lo  [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH\n\t{0xB204, 0xB204, prLV},                     // Lo       HANGUL SYLLABLE NU\n\t{0xB205, 0xB21F, prLVT},                    // Lo  [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH\n\t{0xB220, 0xB220, prLV},                     // Lo       HANGUL SYLLABLE NWEO\n\t{0xB221, 0xB23B, prLVT},                    // Lo  [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH\n\t{0xB23C, 0xB23C, prLV},                     // Lo       HANGUL SYLLABLE NWE\n\t{0xB23D, 0xB257, prLVT},                    // Lo  [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH\n\t{0xB258, 0xB258, prLV},                     // Lo       HANGUL SYLLABLE NWI\n\t{0xB259, 0xB273, prLVT},                    // Lo  [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH\n\t{0xB274, 0xB274, prLV},                     // Lo       HANGUL SYLLABLE NYU\n\t{0xB275, 0xB28F, prLVT},                    // Lo  [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH\n\t{0xB290, 0xB290, prLV},                     // Lo       HANGUL SYLLABLE NEU\n\t{0xB291, 0xB2AB, prLVT},                    // Lo  [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH\n\t{0xB2AC, 0xB2AC, prLV},                     // Lo       HANGUL SYLLABLE NYI\n\t{0xB2AD, 0xB2C7, prLVT},                    // Lo  [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH\n\t{0xB2C8, 0xB2C8, prLV},                     // Lo       HANGUL SYLLABLE NI\n\t{0xB2C9, 0xB2E3, prLVT},                    // Lo  [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH\n\t{0xB2E4, 0xB2E4, prLV},                     // Lo       HANGUL SYLLABLE DA\n\t{0xB2E5, 0xB2FF, prLVT},                    // Lo  [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH\n\t{0xB300, 0xB300, prLV},                     // Lo       HANGUL SYLLABLE DAE\n\t{0xB301, 0xB31B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH\n\t{0xB31C, 0xB31C, prLV},                     // Lo       HANGUL SYLLABLE DYA\n\t{0xB31D, 0xB337, prLVT},                    // Lo  [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH\n\t{0xB338, 0xB338, prLV},                     // Lo       HANGUL SYLLABLE DYAE\n\t{0xB339, 0xB353, prLVT},                    // Lo  [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH\n\t{0xB354, 0xB354, prLV},                     // Lo       HANGUL SYLLABLE DEO\n\t{0xB355, 0xB36F, prLVT},                    // Lo  [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH\n\t{0xB370, 0xB370, prLV},                     // Lo       HANGUL SYLLABLE DE\n\t{0xB371, 0xB38B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH\n\t{0xB38C, 0xB38C, prLV},                     // Lo       HANGUL SYLLABLE DYEO\n\t{0xB38D, 0xB3A7, prLVT},                    // Lo  [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH\n\t{0xB3A8, 0xB3A8, prLV},                     // Lo       HANGUL SYLLABLE DYE\n\t{0xB3A9, 0xB3C3, prLVT},                    // Lo  [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH\n\t{0xB3C4, 0xB3C4, prLV},                     // Lo       HANGUL SYLLABLE DO\n\t{0xB3C5, 0xB3DF, prLVT},                    // Lo  [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH\n\t{0xB3E0, 0xB3E0, prLV},                     // Lo       HANGUL SYLLABLE DWA\n\t{0xB3E1, 0xB3FB, prLVT},                    // Lo  [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH\n\t{0xB3FC, 0xB3FC, prLV},                     // Lo       HANGUL SYLLABLE DWAE\n\t{0xB3FD, 0xB417, prLVT},                    // Lo  [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH\n\t{0xB418, 0xB418, prLV},                     // Lo       HANGUL SYLLABLE DOE\n\t{0xB419, 0xB433, prLVT},                    // Lo  [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH\n\t{0xB434, 0xB434, prLV},                     // Lo       HANGUL SYLLABLE DYO\n\t{0xB435, 0xB44F, prLVT},                    // Lo  [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH\n\t{0xB450, 0xB450, prLV},                     // Lo       HANGUL SYLLABLE DU\n\t{0xB451, 0xB46B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH\n\t{0xB46C, 0xB46C, prLV},                     // Lo       HANGUL SYLLABLE DWEO\n\t{0xB46D, 0xB487, prLVT},                    // Lo  [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH\n\t{0xB488, 0xB488, prLV},                     // Lo       HANGUL SYLLABLE DWE\n\t{0xB489, 0xB4A3, prLVT},                    // Lo  [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH\n\t{0xB4A4, 0xB4A4, prLV},                     // Lo       HANGUL SYLLABLE DWI\n\t{0xB4A5, 0xB4BF, prLVT},                    // Lo  [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH\n\t{0xB4C0, 0xB4C0, prLV},                     // Lo       HANGUL SYLLABLE DYU\n\t{0xB4C1, 0xB4DB, prLVT},                    // Lo  [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH\n\t{0xB4DC, 0xB4DC, prLV},                     // Lo       HANGUL SYLLABLE DEU\n\t{0xB4DD, 0xB4F7, prLVT},                    // Lo  [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH\n\t{0xB4F8, 0xB4F8, prLV},                     // Lo       HANGUL SYLLABLE DYI\n\t{0xB4F9, 0xB513, prLVT},                    // Lo  [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH\n\t{0xB514, 0xB514, prLV},                     // Lo       HANGUL SYLLABLE DI\n\t{0xB515, 0xB52F, prLVT},                    // Lo  [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH\n\t{0xB530, 0xB530, prLV},                     // Lo       HANGUL SYLLABLE DDA\n\t{0xB531, 0xB54B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH\n\t{0xB54C, 0xB54C, prLV},                     // Lo       HANGUL SYLLABLE DDAE\n\t{0xB54D, 0xB567, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH\n\t{0xB568, 0xB568, prLV},                     // Lo       HANGUL SYLLABLE DDYA\n\t{0xB569, 0xB583, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH\n\t{0xB584, 0xB584, prLV},                     // Lo       HANGUL SYLLABLE DDYAE\n\t{0xB585, 0xB59F, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH\n\t{0xB5A0, 0xB5A0, prLV},                     // Lo       HANGUL SYLLABLE DDEO\n\t{0xB5A1, 0xB5BB, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH\n\t{0xB5BC, 0xB5BC, prLV},                     // Lo       HANGUL SYLLABLE DDE\n\t{0xB5BD, 0xB5D7, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH\n\t{0xB5D8, 0xB5D8, prLV},                     // Lo       HANGUL SYLLABLE DDYEO\n\t{0xB5D9, 0xB5F3, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH\n\t{0xB5F4, 0xB5F4, prLV},                     // Lo       HANGUL SYLLABLE DDYE\n\t{0xB5F5, 0xB60F, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH\n\t{0xB610, 0xB610, prLV},                     // Lo       HANGUL SYLLABLE DDO\n\t{0xB611, 0xB62B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH\n\t{0xB62C, 0xB62C, prLV},                     // Lo       HANGUL SYLLABLE DDWA\n\t{0xB62D, 0xB647, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH\n\t{0xB648, 0xB648, prLV},                     // Lo       HANGUL SYLLABLE DDWAE\n\t{0xB649, 0xB663, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH\n\t{0xB664, 0xB664, prLV},                     // Lo       HANGUL SYLLABLE DDOE\n\t{0xB665, 0xB67F, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH\n\t{0xB680, 0xB680, prLV},                     // Lo       HANGUL SYLLABLE DDYO\n\t{0xB681, 0xB69B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH\n\t{0xB69C, 0xB69C, prLV},                     // Lo       HANGUL SYLLABLE DDU\n\t{0xB69D, 0xB6B7, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH\n\t{0xB6B8, 0xB6B8, prLV},                     // Lo       HANGUL SYLLABLE DDWEO\n\t{0xB6B9, 0xB6D3, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH\n\t{0xB6D4, 0xB6D4, prLV},                     // Lo       HANGUL SYLLABLE DDWE\n\t{0xB6D5, 0xB6EF, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH\n\t{0xB6F0, 0xB6F0, prLV},                     // Lo       HANGUL SYLLABLE DDWI\n\t{0xB6F1, 0xB70B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH\n\t{0xB70C, 0xB70C, prLV},                     // Lo       HANGUL SYLLABLE DDYU\n\t{0xB70D, 0xB727, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH\n\t{0xB728, 0xB728, prLV},                     // Lo       HANGUL SYLLABLE DDEU\n\t{0xB729, 0xB743, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH\n\t{0xB744, 0xB744, prLV},                     // Lo       HANGUL SYLLABLE DDYI\n\t{0xB745, 0xB75F, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH\n\t{0xB760, 0xB760, prLV},                     // Lo       HANGUL SYLLABLE DDI\n\t{0xB761, 0xB77B, prLVT},                    // Lo  [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH\n\t{0xB77C, 0xB77C, prLV},                     // Lo       HANGUL SYLLABLE RA\n\t{0xB77D, 0xB797, prLVT},                    // Lo  [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH\n\t{0xB798, 0xB798, prLV},                     // Lo       HANGUL SYLLABLE RAE\n\t{0xB799, 0xB7B3, prLVT},                    // Lo  [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH\n\t{0xB7B4, 0xB7B4, prLV},                     // Lo       HANGUL SYLLABLE RYA\n\t{0xB7B5, 0xB7CF, prLVT},                    // Lo  [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH\n\t{0xB7D0, 0xB7D0, prLV},                     // Lo       HANGUL SYLLABLE RYAE\n\t{0xB7D1, 0xB7EB, prLVT},                    // Lo  [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH\n\t{0xB7EC, 0xB7EC, prLV},                     // Lo       HANGUL SYLLABLE REO\n\t{0xB7ED, 0xB807, prLVT},                    // Lo  [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH\n\t{0xB808, 0xB808, prLV},                     // Lo       HANGUL SYLLABLE RE\n\t{0xB809, 0xB823, prLVT},                    // Lo  [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH\n\t{0xB824, 0xB824, prLV},                     // Lo       HANGUL SYLLABLE RYEO\n\t{0xB825, 0xB83F, prLVT},                    // Lo  [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH\n\t{0xB840, 0xB840, prLV},                     // Lo       HANGUL SYLLABLE RYE\n\t{0xB841, 0xB85B, prLVT},                    // Lo  [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH\n\t{0xB85C, 0xB85C, prLV},                     // Lo       HANGUL SYLLABLE RO\n\t{0xB85D, 0xB877, prLVT},                    // Lo  [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH\n\t{0xB878, 0xB878, prLV},                     // Lo       HANGUL SYLLABLE RWA\n\t{0xB879, 0xB893, prLVT},                    // Lo  [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH\n\t{0xB894, 0xB894, prLV},                     // Lo       HANGUL SYLLABLE RWAE\n\t{0xB895, 0xB8AF, prLVT},                    // Lo  [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH\n\t{0xB8B0, 0xB8B0, prLV},                     // Lo       HANGUL SYLLABLE ROE\n\t{0xB8B1, 0xB8CB, prLVT},                    // Lo  [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH\n\t{0xB8CC, 0xB8CC, prLV},                     // Lo       HANGUL SYLLABLE RYO\n\t{0xB8CD, 0xB8E7, prLVT},                    // Lo  [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH\n\t{0xB8E8, 0xB8E8, prLV},                     // Lo       HANGUL SYLLABLE RU\n\t{0xB8E9, 0xB903, prLVT},                    // Lo  [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH\n\t{0xB904, 0xB904, prLV},                     // Lo       HANGUL SYLLABLE RWEO\n\t{0xB905, 0xB91F, prLVT},                    // Lo  [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH\n\t{0xB920, 0xB920, prLV},                     // Lo       HANGUL SYLLABLE RWE\n\t{0xB921, 0xB93B, prLVT},                    // Lo  [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH\n\t{0xB93C, 0xB93C, prLV},                     // Lo       HANGUL SYLLABLE RWI\n\t{0xB93D, 0xB957, prLVT},                    // Lo  [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH\n\t{0xB958, 0xB958, prLV},                     // Lo       HANGUL SYLLABLE RYU\n\t{0xB959, 0xB973, prLVT},                    // Lo  [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH\n\t{0xB974, 0xB974, prLV},                     // Lo       HANGUL SYLLABLE REU\n\t{0xB975, 0xB98F, prLVT},                    // Lo  [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH\n\t{0xB990, 0xB990, prLV},                     // Lo       HANGUL SYLLABLE RYI\n\t{0xB991, 0xB9AB, prLVT},                    // Lo  [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH\n\t{0xB9AC, 0xB9AC, prLV},                     // Lo       HANGUL SYLLABLE RI\n\t{0xB9AD, 0xB9C7, prLVT},                    // Lo  [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH\n\t{0xB9C8, 0xB9C8, prLV},                     // Lo       HANGUL SYLLABLE MA\n\t{0xB9C9, 0xB9E3, prLVT},                    // Lo  [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH\n\t{0xB9E4, 0xB9E4, prLV},                     // Lo       HANGUL SYLLABLE MAE\n\t{0xB9E5, 0xB9FF, prLVT},                    // Lo  [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH\n\t{0xBA00, 0xBA00, prLV},                     // Lo       HANGUL SYLLABLE MYA\n\t{0xBA01, 0xBA1B, prLVT},                    // Lo  [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH\n\t{0xBA1C, 0xBA1C, prLV},                     // Lo       HANGUL SYLLABLE MYAE\n\t{0xBA1D, 0xBA37, prLVT},                    // Lo  [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH\n\t{0xBA38, 0xBA38, prLV},                     // Lo       HANGUL SYLLABLE MEO\n\t{0xBA39, 0xBA53, prLVT},                    // Lo  [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH\n\t{0xBA54, 0xBA54, prLV},                     // Lo       HANGUL SYLLABLE ME\n\t{0xBA55, 0xBA6F, prLVT},                    // Lo  [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH\n\t{0xBA70, 0xBA70, prLV},                     // Lo       HANGUL SYLLABLE MYEO\n\t{0xBA71, 0xBA8B, prLVT},                    // Lo  [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH\n\t{0xBA8C, 0xBA8C, prLV},                     // Lo       HANGUL SYLLABLE MYE\n\t{0xBA8D, 0xBAA7, prLVT},                    // Lo  [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH\n\t{0xBAA8, 0xBAA8, prLV},                     // Lo       HANGUL SYLLABLE MO\n\t{0xBAA9, 0xBAC3, prLVT},                    // Lo  [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH\n\t{0xBAC4, 0xBAC4, prLV},                     // Lo       HANGUL SYLLABLE MWA\n\t{0xBAC5, 0xBADF, prLVT},                    // Lo  [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH\n\t{0xBAE0, 0xBAE0, prLV},                     // Lo       HANGUL SYLLABLE MWAE\n\t{0xBAE1, 0xBAFB, prLVT},                    // Lo  [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH\n\t{0xBAFC, 0xBAFC, prLV},                     // Lo       HANGUL SYLLABLE MOE\n\t{0xBAFD, 0xBB17, prLVT},                    // Lo  [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH\n\t{0xBB18, 0xBB18, prLV},                     // Lo       HANGUL SYLLABLE MYO\n\t{0xBB19, 0xBB33, prLVT},                    // Lo  [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH\n\t{0xBB34, 0xBB34, prLV},                     // Lo       HANGUL SYLLABLE MU\n\t{0xBB35, 0xBB4F, prLVT},                    // Lo  [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH\n\t{0xBB50, 0xBB50, prLV},                     // Lo       HANGUL SYLLABLE MWEO\n\t{0xBB51, 0xBB6B, prLVT},                    // Lo  [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH\n\t{0xBB6C, 0xBB6C, prLV},                     // Lo       HANGUL SYLLABLE MWE\n\t{0xBB6D, 0xBB87, prLVT},                    // Lo  [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH\n\t{0xBB88, 0xBB88, prLV},                     // Lo       HANGUL SYLLABLE MWI\n\t{0xBB89, 0xBBA3, prLVT},                    // Lo  [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH\n\t{0xBBA4, 0xBBA4, prLV},                     // Lo       HANGUL SYLLABLE MYU\n\t{0xBBA5, 0xBBBF, prLVT},                    // Lo  [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH\n\t{0xBBC0, 0xBBC0, prLV},                     // Lo       HANGUL SYLLABLE MEU\n\t{0xBBC1, 0xBBDB, prLVT},                    // Lo  [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH\n\t{0xBBDC, 0xBBDC, prLV},                     // Lo       HANGUL SYLLABLE MYI\n\t{0xBBDD, 0xBBF7, prLVT},                    // Lo  [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH\n\t{0xBBF8, 0xBBF8, prLV},                     // Lo       HANGUL SYLLABLE MI\n\t{0xBBF9, 0xBC13, prLVT},                    // Lo  [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH\n\t{0xBC14, 0xBC14, prLV},                     // Lo       HANGUL SYLLABLE BA\n\t{0xBC15, 0xBC2F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH\n\t{0xBC30, 0xBC30, prLV},                     // Lo       HANGUL SYLLABLE BAE\n\t{0xBC31, 0xBC4B, prLVT},                    // Lo  [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH\n\t{0xBC4C, 0xBC4C, prLV},                     // Lo       HANGUL SYLLABLE BYA\n\t{0xBC4D, 0xBC67, prLVT},                    // Lo  [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH\n\t{0xBC68, 0xBC68, prLV},                     // Lo       HANGUL SYLLABLE BYAE\n\t{0xBC69, 0xBC83, prLVT},                    // Lo  [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH\n\t{0xBC84, 0xBC84, prLV},                     // Lo       HANGUL SYLLABLE BEO\n\t{0xBC85, 0xBC9F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH\n\t{0xBCA0, 0xBCA0, prLV},                     // Lo       HANGUL SYLLABLE BE\n\t{0xBCA1, 0xBCBB, prLVT},                    // Lo  [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH\n\t{0xBCBC, 0xBCBC, prLV},                     // Lo       HANGUL SYLLABLE BYEO\n\t{0xBCBD, 0xBCD7, prLVT},                    // Lo  [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH\n\t{0xBCD8, 0xBCD8, prLV},                     // Lo       HANGUL SYLLABLE BYE\n\t{0xBCD9, 0xBCF3, prLVT},                    // Lo  [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH\n\t{0xBCF4, 0xBCF4, prLV},                     // Lo       HANGUL SYLLABLE BO\n\t{0xBCF5, 0xBD0F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH\n\t{0xBD10, 0xBD10, prLV},                     // Lo       HANGUL SYLLABLE BWA\n\t{0xBD11, 0xBD2B, prLVT},                    // Lo  [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH\n\t{0xBD2C, 0xBD2C, prLV},                     // Lo       HANGUL SYLLABLE BWAE\n\t{0xBD2D, 0xBD47, prLVT},                    // Lo  [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH\n\t{0xBD48, 0xBD48, prLV},                     // Lo       HANGUL SYLLABLE BOE\n\t{0xBD49, 0xBD63, prLVT},                    // Lo  [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH\n\t{0xBD64, 0xBD64, prLV},                     // Lo       HANGUL SYLLABLE BYO\n\t{0xBD65, 0xBD7F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH\n\t{0xBD80, 0xBD80, prLV},                     // Lo       HANGUL SYLLABLE BU\n\t{0xBD81, 0xBD9B, prLVT},                    // Lo  [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH\n\t{0xBD9C, 0xBD9C, prLV},                     // Lo       HANGUL SYLLABLE BWEO\n\t{0xBD9D, 0xBDB7, prLVT},                    // Lo  [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH\n\t{0xBDB8, 0xBDB8, prLV},                     // Lo       HANGUL SYLLABLE BWE\n\t{0xBDB9, 0xBDD3, prLVT},                    // Lo  [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH\n\t{0xBDD4, 0xBDD4, prLV},                     // Lo       HANGUL SYLLABLE BWI\n\t{0xBDD5, 0xBDEF, prLVT},                    // Lo  [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH\n\t{0xBDF0, 0xBDF0, prLV},                     // Lo       HANGUL SYLLABLE BYU\n\t{0xBDF1, 0xBE0B, prLVT},                    // Lo  [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH\n\t{0xBE0C, 0xBE0C, prLV},                     // Lo       HANGUL SYLLABLE BEU\n\t{0xBE0D, 0xBE27, prLVT},                    // Lo  [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH\n\t{0xBE28, 0xBE28, prLV},                     // Lo       HANGUL SYLLABLE BYI\n\t{0xBE29, 0xBE43, prLVT},                    // Lo  [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH\n\t{0xBE44, 0xBE44, prLV},                     // Lo       HANGUL SYLLABLE BI\n\t{0xBE45, 0xBE5F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH\n\t{0xBE60, 0xBE60, prLV},                     // Lo       HANGUL SYLLABLE BBA\n\t{0xBE61, 0xBE7B, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH\n\t{0xBE7C, 0xBE7C, prLV},                     // Lo       HANGUL SYLLABLE BBAE\n\t{0xBE7D, 0xBE97, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH\n\t{0xBE98, 0xBE98, prLV},                     // Lo       HANGUL SYLLABLE BBYA\n\t{0xBE99, 0xBEB3, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH\n\t{0xBEB4, 0xBEB4, prLV},                     // Lo       HANGUL SYLLABLE BBYAE\n\t{0xBEB5, 0xBECF, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH\n\t{0xBED0, 0xBED0, prLV},                     // Lo       HANGUL SYLLABLE BBEO\n\t{0xBED1, 0xBEEB, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH\n\t{0xBEEC, 0xBEEC, prLV},                     // Lo       HANGUL SYLLABLE BBE\n\t{0xBEED, 0xBF07, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH\n\t{0xBF08, 0xBF08, prLV},                     // Lo       HANGUL SYLLABLE BBYEO\n\t{0xBF09, 0xBF23, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH\n\t{0xBF24, 0xBF24, prLV},                     // Lo       HANGUL SYLLABLE BBYE\n\t{0xBF25, 0xBF3F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH\n\t{0xBF40, 0xBF40, prLV},                     // Lo       HANGUL SYLLABLE BBO\n\t{0xBF41, 0xBF5B, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH\n\t{0xBF5C, 0xBF5C, prLV},                     // Lo       HANGUL SYLLABLE BBWA\n\t{0xBF5D, 0xBF77, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH\n\t{0xBF78, 0xBF78, prLV},                     // Lo       HANGUL SYLLABLE BBWAE\n\t{0xBF79, 0xBF93, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH\n\t{0xBF94, 0xBF94, prLV},                     // Lo       HANGUL SYLLABLE BBOE\n\t{0xBF95, 0xBFAF, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH\n\t{0xBFB0, 0xBFB0, prLV},                     // Lo       HANGUL SYLLABLE BBYO\n\t{0xBFB1, 0xBFCB, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH\n\t{0xBFCC, 0xBFCC, prLV},                     // Lo       HANGUL SYLLABLE BBU\n\t{0xBFCD, 0xBFE7, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH\n\t{0xBFE8, 0xBFE8, prLV},                     // Lo       HANGUL SYLLABLE BBWEO\n\t{0xBFE9, 0xC003, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH\n\t{0xC004, 0xC004, prLV},                     // Lo       HANGUL SYLLABLE BBWE\n\t{0xC005, 0xC01F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH\n\t{0xC020, 0xC020, prLV},                     // Lo       HANGUL SYLLABLE BBWI\n\t{0xC021, 0xC03B, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH\n\t{0xC03C, 0xC03C, prLV},                     // Lo       HANGUL SYLLABLE BBYU\n\t{0xC03D, 0xC057, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH\n\t{0xC058, 0xC058, prLV},                     // Lo       HANGUL SYLLABLE BBEU\n\t{0xC059, 0xC073, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH\n\t{0xC074, 0xC074, prLV},                     // Lo       HANGUL SYLLABLE BBYI\n\t{0xC075, 0xC08F, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH\n\t{0xC090, 0xC090, prLV},                     // Lo       HANGUL SYLLABLE BBI\n\t{0xC091, 0xC0AB, prLVT},                    // Lo  [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH\n\t{0xC0AC, 0xC0AC, prLV},                     // Lo       HANGUL SYLLABLE SA\n\t{0xC0AD, 0xC0C7, prLVT},                    // Lo  [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH\n\t{0xC0C8, 0xC0C8, prLV},                     // Lo       HANGUL SYLLABLE SAE\n\t{0xC0C9, 0xC0E3, prLVT},                    // Lo  [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH\n\t{0xC0E4, 0xC0E4, prLV},                     // Lo       HANGUL SYLLABLE SYA\n\t{0xC0E5, 0xC0FF, prLVT},                    // Lo  [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH\n\t{0xC100, 0xC100, prLV},                     // Lo       HANGUL SYLLABLE SYAE\n\t{0xC101, 0xC11B, prLVT},                    // Lo  [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH\n\t{0xC11C, 0xC11C, prLV},                     // Lo       HANGUL SYLLABLE SEO\n\t{0xC11D, 0xC137, prLVT},                    // Lo  [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH\n\t{0xC138, 0xC138, prLV},                     // Lo       HANGUL SYLLABLE SE\n\t{0xC139, 0xC153, prLVT},                    // Lo  [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH\n\t{0xC154, 0xC154, prLV},                     // Lo       HANGUL SYLLABLE SYEO\n\t{0xC155, 0xC16F, prLVT},                    // Lo  [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH\n\t{0xC170, 0xC170, prLV},                     // Lo       HANGUL SYLLABLE SYE\n\t{0xC171, 0xC18B, prLVT},                    // Lo  [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH\n\t{0xC18C, 0xC18C, prLV},                     // Lo       HANGUL SYLLABLE SO\n\t{0xC18D, 0xC1A7, prLVT},                    // Lo  [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH\n\t{0xC1A8, 0xC1A8, prLV},                     // Lo       HANGUL SYLLABLE SWA\n\t{0xC1A9, 0xC1C3, prLVT},                    // Lo  [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH\n\t{0xC1C4, 0xC1C4, prLV},                     // Lo       HANGUL SYLLABLE SWAE\n\t{0xC1C5, 0xC1DF, prLVT},                    // Lo  [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH\n\t{0xC1E0, 0xC1E0, prLV},                     // Lo       HANGUL SYLLABLE SOE\n\t{0xC1E1, 0xC1FB, prLVT},                    // Lo  [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH\n\t{0xC1FC, 0xC1FC, prLV},                     // Lo       HANGUL SYLLABLE SYO\n\t{0xC1FD, 0xC217, prLVT},                    // Lo  [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH\n\t{0xC218, 0xC218, prLV},                     // Lo       HANGUL SYLLABLE SU\n\t{0xC219, 0xC233, prLVT},                    // Lo  [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH\n\t{0xC234, 0xC234, prLV},                     // Lo       HANGUL SYLLABLE SWEO\n\t{0xC235, 0xC24F, prLVT},                    // Lo  [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH\n\t{0xC250, 0xC250, prLV},                     // Lo       HANGUL SYLLABLE SWE\n\t{0xC251, 0xC26B, prLVT},                    // Lo  [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH\n\t{0xC26C, 0xC26C, prLV},                     // Lo       HANGUL SYLLABLE SWI\n\t{0xC26D, 0xC287, prLVT},                    // Lo  [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH\n\t{0xC288, 0xC288, prLV},                     // Lo       HANGUL SYLLABLE SYU\n\t{0xC289, 0xC2A3, prLVT},                    // Lo  [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH\n\t{0xC2A4, 0xC2A4, prLV},                     // Lo       HANGUL SYLLABLE SEU\n\t{0xC2A5, 0xC2BF, prLVT},                    // Lo  [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH\n\t{0xC2C0, 0xC2C0, prLV},                     // Lo       HANGUL SYLLABLE SYI\n\t{0xC2C1, 0xC2DB, prLVT},                    // Lo  [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH\n\t{0xC2DC, 0xC2DC, prLV},                     // Lo       HANGUL SYLLABLE SI\n\t{0xC2DD, 0xC2F7, prLVT},                    // Lo  [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH\n\t{0xC2F8, 0xC2F8, prLV},                     // Lo       HANGUL SYLLABLE SSA\n\t{0xC2F9, 0xC313, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH\n\t{0xC314, 0xC314, prLV},                     // Lo       HANGUL SYLLABLE SSAE\n\t{0xC315, 0xC32F, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH\n\t{0xC330, 0xC330, prLV},                     // Lo       HANGUL SYLLABLE SSYA\n\t{0xC331, 0xC34B, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH\n\t{0xC34C, 0xC34C, prLV},                     // Lo       HANGUL SYLLABLE SSYAE\n\t{0xC34D, 0xC367, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH\n\t{0xC368, 0xC368, prLV},                     // Lo       HANGUL SYLLABLE SSEO\n\t{0xC369, 0xC383, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH\n\t{0xC384, 0xC384, prLV},                     // Lo       HANGUL SYLLABLE SSE\n\t{0xC385, 0xC39F, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH\n\t{0xC3A0, 0xC3A0, prLV},                     // Lo       HANGUL SYLLABLE SSYEO\n\t{0xC3A1, 0xC3BB, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH\n\t{0xC3BC, 0xC3BC, prLV},                     // Lo       HANGUL SYLLABLE SSYE\n\t{0xC3BD, 0xC3D7, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH\n\t{0xC3D8, 0xC3D8, prLV},                     // Lo       HANGUL SYLLABLE SSO\n\t{0xC3D9, 0xC3F3, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH\n\t{0xC3F4, 0xC3F4, prLV},                     // Lo       HANGUL SYLLABLE SSWA\n\t{0xC3F5, 0xC40F, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH\n\t{0xC410, 0xC410, prLV},                     // Lo       HANGUL SYLLABLE SSWAE\n\t{0xC411, 0xC42B, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH\n\t{0xC42C, 0xC42C, prLV},                     // Lo       HANGUL SYLLABLE SSOE\n\t{0xC42D, 0xC447, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH\n\t{0xC448, 0xC448, prLV},                     // Lo       HANGUL SYLLABLE SSYO\n\t{0xC449, 0xC463, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH\n\t{0xC464, 0xC464, prLV},                     // Lo       HANGUL SYLLABLE SSU\n\t{0xC465, 0xC47F, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH\n\t{0xC480, 0xC480, prLV},                     // Lo       HANGUL SYLLABLE SSWEO\n\t{0xC481, 0xC49B, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH\n\t{0xC49C, 0xC49C, prLV},                     // Lo       HANGUL SYLLABLE SSWE\n\t{0xC49D, 0xC4B7, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH\n\t{0xC4B8, 0xC4B8, prLV},                     // Lo       HANGUL SYLLABLE SSWI\n\t{0xC4B9, 0xC4D3, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH\n\t{0xC4D4, 0xC4D4, prLV},                     // Lo       HANGUL SYLLABLE SSYU\n\t{0xC4D5, 0xC4EF, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH\n\t{0xC4F0, 0xC4F0, prLV},                     // Lo       HANGUL SYLLABLE SSEU\n\t{0xC4F1, 0xC50B, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH\n\t{0xC50C, 0xC50C, prLV},                     // Lo       HANGUL SYLLABLE SSYI\n\t{0xC50D, 0xC527, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH\n\t{0xC528, 0xC528, prLV},                     // Lo       HANGUL SYLLABLE SSI\n\t{0xC529, 0xC543, prLVT},                    // Lo  [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH\n\t{0xC544, 0xC544, prLV},                     // Lo       HANGUL SYLLABLE A\n\t{0xC545, 0xC55F, prLVT},                    // Lo  [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH\n\t{0xC560, 0xC560, prLV},                     // Lo       HANGUL SYLLABLE AE\n\t{0xC561, 0xC57B, prLVT},                    // Lo  [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH\n\t{0xC57C, 0xC57C, prLV},                     // Lo       HANGUL SYLLABLE YA\n\t{0xC57D, 0xC597, prLVT},                    // Lo  [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH\n\t{0xC598, 0xC598, prLV},                     // Lo       HANGUL SYLLABLE YAE\n\t{0xC599, 0xC5B3, prLVT},                    // Lo  [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH\n\t{0xC5B4, 0xC5B4, prLV},                     // Lo       HANGUL SYLLABLE EO\n\t{0xC5B5, 0xC5CF, prLVT},                    // Lo  [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH\n\t{0xC5D0, 0xC5D0, prLV},                     // Lo       HANGUL SYLLABLE E\n\t{0xC5D1, 0xC5EB, prLVT},                    // Lo  [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH\n\t{0xC5EC, 0xC5EC, prLV},                     // Lo       HANGUL SYLLABLE YEO\n\t{0xC5ED, 0xC607, prLVT},                    // Lo  [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH\n\t{0xC608, 0xC608, prLV},                     // Lo       HANGUL SYLLABLE YE\n\t{0xC609, 0xC623, prLVT},                    // Lo  [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH\n\t{0xC624, 0xC624, prLV},                     // Lo       HANGUL SYLLABLE O\n\t{0xC625, 0xC63F, prLVT},                    // Lo  [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH\n\t{0xC640, 0xC640, prLV},                     // Lo       HANGUL SYLLABLE WA\n\t{0xC641, 0xC65B, prLVT},                    // Lo  [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH\n\t{0xC65C, 0xC65C, prLV},                     // Lo       HANGUL SYLLABLE WAE\n\t{0xC65D, 0xC677, prLVT},                    // Lo  [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH\n\t{0xC678, 0xC678, prLV},                     // Lo       HANGUL SYLLABLE OE\n\t{0xC679, 0xC693, prLVT},                    // Lo  [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH\n\t{0xC694, 0xC694, prLV},                     // Lo       HANGUL SYLLABLE YO\n\t{0xC695, 0xC6AF, prLVT},                    // Lo  [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH\n\t{0xC6B0, 0xC6B0, prLV},                     // Lo       HANGUL SYLLABLE U\n\t{0xC6B1, 0xC6CB, prLVT},                    // Lo  [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH\n\t{0xC6CC, 0xC6CC, prLV},                     // Lo       HANGUL SYLLABLE WEO\n\t{0xC6CD, 0xC6E7, prLVT},                    // Lo  [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH\n\t{0xC6E8, 0xC6E8, prLV},                     // Lo       HANGUL SYLLABLE WE\n\t{0xC6E9, 0xC703, prLVT},                    // Lo  [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH\n\t{0xC704, 0xC704, prLV},                     // Lo       HANGUL SYLLABLE WI\n\t{0xC705, 0xC71F, prLVT},                    // Lo  [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH\n\t{0xC720, 0xC720, prLV},                     // Lo       HANGUL SYLLABLE YU\n\t{0xC721, 0xC73B, prLVT},                    // Lo  [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH\n\t{0xC73C, 0xC73C, prLV},                     // Lo       HANGUL SYLLABLE EU\n\t{0xC73D, 0xC757, prLVT},                    // Lo  [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH\n\t{0xC758, 0xC758, prLV},                     // Lo       HANGUL SYLLABLE YI\n\t{0xC759, 0xC773, prLVT},                    // Lo  [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH\n\t{0xC774, 0xC774, prLV},                     // Lo       HANGUL SYLLABLE I\n\t{0xC775, 0xC78F, prLVT},                    // Lo  [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH\n\t{0xC790, 0xC790, prLV},                     // Lo       HANGUL SYLLABLE JA\n\t{0xC791, 0xC7AB, prLVT},                    // Lo  [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH\n\t{0xC7AC, 0xC7AC, prLV},                     // Lo       HANGUL SYLLABLE JAE\n\t{0xC7AD, 0xC7C7, prLVT},                    // Lo  [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH\n\t{0xC7C8, 0xC7C8, prLV},                     // Lo       HANGUL SYLLABLE JYA\n\t{0xC7C9, 0xC7E3, prLVT},                    // Lo  [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH\n\t{0xC7E4, 0xC7E4, prLV},                     // Lo       HANGUL SYLLABLE JYAE\n\t{0xC7E5, 0xC7FF, prLVT},                    // Lo  [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH\n\t{0xC800, 0xC800, prLV},                     // Lo       HANGUL SYLLABLE JEO\n\t{0xC801, 0xC81B, prLVT},                    // Lo  [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH\n\t{0xC81C, 0xC81C, prLV},                     // Lo       HANGUL SYLLABLE JE\n\t{0xC81D, 0xC837, prLVT},                    // Lo  [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH\n\t{0xC838, 0xC838, prLV},                     // Lo       HANGUL SYLLABLE JYEO\n\t{0xC839, 0xC853, prLVT},                    // Lo  [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH\n\t{0xC854, 0xC854, prLV},                     // Lo       HANGUL SYLLABLE JYE\n\t{0xC855, 0xC86F, prLVT},                    // Lo  [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH\n\t{0xC870, 0xC870, prLV},                     // Lo       HANGUL SYLLABLE JO\n\t{0xC871, 0xC88B, prLVT},                    // Lo  [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH\n\t{0xC88C, 0xC88C, prLV},                     // Lo       HANGUL SYLLABLE JWA\n\t{0xC88D, 0xC8A7, prLVT},                    // Lo  [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH\n\t{0xC8A8, 0xC8A8, prLV},                     // Lo       HANGUL SYLLABLE JWAE\n\t{0xC8A9, 0xC8C3, prLVT},                    // Lo  [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH\n\t{0xC8C4, 0xC8C4, prLV},                     // Lo       HANGUL SYLLABLE JOE\n\t{0xC8C5, 0xC8DF, prLVT},                    // Lo  [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH\n\t{0xC8E0, 0xC8E0, prLV},                     // Lo       HANGUL SYLLABLE JYO\n\t{0xC8E1, 0xC8FB, prLVT},                    // Lo  [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH\n\t{0xC8FC, 0xC8FC, prLV},                     // Lo       HANGUL SYLLABLE JU\n\t{0xC8FD, 0xC917, prLVT},                    // Lo  [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH\n\t{0xC918, 0xC918, prLV},                     // Lo       HANGUL SYLLABLE JWEO\n\t{0xC919, 0xC933, prLVT},                    // Lo  [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH\n\t{0xC934, 0xC934, prLV},                     // Lo       HANGUL SYLLABLE JWE\n\t{0xC935, 0xC94F, prLVT},                    // Lo  [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH\n\t{0xC950, 0xC950, prLV},                     // Lo       HANGUL SYLLABLE JWI\n\t{0xC951, 0xC96B, prLVT},                    // Lo  [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH\n\t{0xC96C, 0xC96C, prLV},                     // Lo       HANGUL SYLLABLE JYU\n\t{0xC96D, 0xC987, prLVT},                    // Lo  [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH\n\t{0xC988, 0xC988, prLV},                     // Lo       HANGUL SYLLABLE JEU\n\t{0xC989, 0xC9A3, prLVT},                    // Lo  [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH\n\t{0xC9A4, 0xC9A4, prLV},                     // Lo       HANGUL SYLLABLE JYI\n\t{0xC9A5, 0xC9BF, prLVT},                    // Lo  [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH\n\t{0xC9C0, 0xC9C0, prLV},                     // Lo       HANGUL SYLLABLE JI\n\t{0xC9C1, 0xC9DB, prLVT},                    // Lo  [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH\n\t{0xC9DC, 0xC9DC, prLV},                     // Lo       HANGUL SYLLABLE JJA\n\t{0xC9DD, 0xC9F7, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH\n\t{0xC9F8, 0xC9F8, prLV},                     // Lo       HANGUL SYLLABLE JJAE\n\t{0xC9F9, 0xCA13, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH\n\t{0xCA14, 0xCA14, prLV},                     // Lo       HANGUL SYLLABLE JJYA\n\t{0xCA15, 0xCA2F, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH\n\t{0xCA30, 0xCA30, prLV},                     // Lo       HANGUL SYLLABLE JJYAE\n\t{0xCA31, 0xCA4B, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH\n\t{0xCA4C, 0xCA4C, prLV},                     // Lo       HANGUL SYLLABLE JJEO\n\t{0xCA4D, 0xCA67, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH\n\t{0xCA68, 0xCA68, prLV},                     // Lo       HANGUL SYLLABLE JJE\n\t{0xCA69, 0xCA83, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH\n\t{0xCA84, 0xCA84, prLV},                     // Lo       HANGUL SYLLABLE JJYEO\n\t{0xCA85, 0xCA9F, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH\n\t{0xCAA0, 0xCAA0, prLV},                     // Lo       HANGUL SYLLABLE JJYE\n\t{0xCAA1, 0xCABB, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH\n\t{0xCABC, 0xCABC, prLV},                     // Lo       HANGUL SYLLABLE JJO\n\t{0xCABD, 0xCAD7, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH\n\t{0xCAD8, 0xCAD8, prLV},                     // Lo       HANGUL SYLLABLE JJWA\n\t{0xCAD9, 0xCAF3, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH\n\t{0xCAF4, 0xCAF4, prLV},                     // Lo       HANGUL SYLLABLE JJWAE\n\t{0xCAF5, 0xCB0F, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH\n\t{0xCB10, 0xCB10, prLV},                     // Lo       HANGUL SYLLABLE JJOE\n\t{0xCB11, 0xCB2B, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH\n\t{0xCB2C, 0xCB2C, prLV},                     // Lo       HANGUL SYLLABLE JJYO\n\t{0xCB2D, 0xCB47, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH\n\t{0xCB48, 0xCB48, prLV},                     // Lo       HANGUL SYLLABLE JJU\n\t{0xCB49, 0xCB63, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH\n\t{0xCB64, 0xCB64, prLV},                     // Lo       HANGUL SYLLABLE JJWEO\n\t{0xCB65, 0xCB7F, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH\n\t{0xCB80, 0xCB80, prLV},                     // Lo       HANGUL SYLLABLE JJWE\n\t{0xCB81, 0xCB9B, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH\n\t{0xCB9C, 0xCB9C, prLV},                     // Lo       HANGUL SYLLABLE JJWI\n\t{0xCB9D, 0xCBB7, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH\n\t{0xCBB8, 0xCBB8, prLV},                     // Lo       HANGUL SYLLABLE JJYU\n\t{0xCBB9, 0xCBD3, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH\n\t{0xCBD4, 0xCBD4, prLV},                     // Lo       HANGUL SYLLABLE JJEU\n\t{0xCBD5, 0xCBEF, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH\n\t{0xCBF0, 0xCBF0, prLV},                     // Lo       HANGUL SYLLABLE JJYI\n\t{0xCBF1, 0xCC0B, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH\n\t{0xCC0C, 0xCC0C, prLV},                     // Lo       HANGUL SYLLABLE JJI\n\t{0xCC0D, 0xCC27, prLVT},                    // Lo  [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH\n\t{0xCC28, 0xCC28, prLV},                     // Lo       HANGUL SYLLABLE CA\n\t{0xCC29, 0xCC43, prLVT},                    // Lo  [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH\n\t{0xCC44, 0xCC44, prLV},                     // Lo       HANGUL SYLLABLE CAE\n\t{0xCC45, 0xCC5F, prLVT},                    // Lo  [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH\n\t{0xCC60, 0xCC60, prLV},                     // Lo       HANGUL SYLLABLE CYA\n\t{0xCC61, 0xCC7B, prLVT},                    // Lo  [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH\n\t{0xCC7C, 0xCC7C, prLV},                     // Lo       HANGUL SYLLABLE CYAE\n\t{0xCC7D, 0xCC97, prLVT},                    // Lo  [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH\n\t{0xCC98, 0xCC98, prLV},                     // Lo       HANGUL SYLLABLE CEO\n\t{0xCC99, 0xCCB3, prLVT},                    // Lo  [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH\n\t{0xCCB4, 0xCCB4, prLV},                     // Lo       HANGUL SYLLABLE CE\n\t{0xCCB5, 0xCCCF, prLVT},                    // Lo  [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH\n\t{0xCCD0, 0xCCD0, prLV},                     // Lo       HANGUL SYLLABLE CYEO\n\t{0xCCD1, 0xCCEB, prLVT},                    // Lo  [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH\n\t{0xCCEC, 0xCCEC, prLV},                     // Lo       HANGUL SYLLABLE CYE\n\t{0xCCED, 0xCD07, prLVT},                    // Lo  [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH\n\t{0xCD08, 0xCD08, prLV},                     // Lo       HANGUL SYLLABLE CO\n\t{0xCD09, 0xCD23, prLVT},                    // Lo  [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH\n\t{0xCD24, 0xCD24, prLV},                     // Lo       HANGUL SYLLABLE CWA\n\t{0xCD25, 0xCD3F, prLVT},                    // Lo  [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH\n\t{0xCD40, 0xCD40, prLV},                     // Lo       HANGUL SYLLABLE CWAE\n\t{0xCD41, 0xCD5B, prLVT},                    // Lo  [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH\n\t{0xCD5C, 0xCD5C, prLV},                     // Lo       HANGUL SYLLABLE COE\n\t{0xCD5D, 0xCD77, prLVT},                    // Lo  [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH\n\t{0xCD78, 0xCD78, prLV},                     // Lo       HANGUL SYLLABLE CYO\n\t{0xCD79, 0xCD93, prLVT},                    // Lo  [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH\n\t{0xCD94, 0xCD94, prLV},                     // Lo       HANGUL SYLLABLE CU\n\t{0xCD95, 0xCDAF, prLVT},                    // Lo  [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH\n\t{0xCDB0, 0xCDB0, prLV},                     // Lo       HANGUL SYLLABLE CWEO\n\t{0xCDB1, 0xCDCB, prLVT},                    // Lo  [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH\n\t{0xCDCC, 0xCDCC, prLV},                     // Lo       HANGUL SYLLABLE CWE\n\t{0xCDCD, 0xCDE7, prLVT},                    // Lo  [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH\n\t{0xCDE8, 0xCDE8, prLV},                     // Lo       HANGUL SYLLABLE CWI\n\t{0xCDE9, 0xCE03, prLVT},                    // Lo  [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH\n\t{0xCE04, 0xCE04, prLV},                     // Lo       HANGUL SYLLABLE CYU\n\t{0xCE05, 0xCE1F, prLVT},                    // Lo  [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH\n\t{0xCE20, 0xCE20, prLV},                     // Lo       HANGUL SYLLABLE CEU\n\t{0xCE21, 0xCE3B, prLVT},                    // Lo  [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH\n\t{0xCE3C, 0xCE3C, prLV},                     // Lo       HANGUL SYLLABLE CYI\n\t{0xCE3D, 0xCE57, prLVT},                    // Lo  [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH\n\t{0xCE58, 0xCE58, prLV},                     // Lo       HANGUL SYLLABLE CI\n\t{0xCE59, 0xCE73, prLVT},                    // Lo  [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH\n\t{0xCE74, 0xCE74, prLV},                     // Lo       HANGUL SYLLABLE KA\n\t{0xCE75, 0xCE8F, prLVT},                    // Lo  [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH\n\t{0xCE90, 0xCE90, prLV},                     // Lo       HANGUL SYLLABLE KAE\n\t{0xCE91, 0xCEAB, prLVT},                    // Lo  [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH\n\t{0xCEAC, 0xCEAC, prLV},                     // Lo       HANGUL SYLLABLE KYA\n\t{0xCEAD, 0xCEC7, prLVT},                    // Lo  [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH\n\t{0xCEC8, 0xCEC8, prLV},                     // Lo       HANGUL SYLLABLE KYAE\n\t{0xCEC9, 0xCEE3, prLVT},                    // Lo  [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH\n\t{0xCEE4, 0xCEE4, prLV},                     // Lo       HANGUL SYLLABLE KEO\n\t{0xCEE5, 0xCEFF, prLVT},                    // Lo  [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH\n\t{0xCF00, 0xCF00, prLV},                     // Lo       HANGUL SYLLABLE KE\n\t{0xCF01, 0xCF1B, prLVT},                    // Lo  [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH\n\t{0xCF1C, 0xCF1C, prLV},                     // Lo       HANGUL SYLLABLE KYEO\n\t{0xCF1D, 0xCF37, prLVT},                    // Lo  [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH\n\t{0xCF38, 0xCF38, prLV},                     // Lo       HANGUL SYLLABLE KYE\n\t{0xCF39, 0xCF53, prLVT},                    // Lo  [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH\n\t{0xCF54, 0xCF54, prLV},                     // Lo       HANGUL SYLLABLE KO\n\t{0xCF55, 0xCF6F, prLVT},                    // Lo  [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH\n\t{0xCF70, 0xCF70, prLV},                     // Lo       HANGUL SYLLABLE KWA\n\t{0xCF71, 0xCF8B, prLVT},                    // Lo  [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH\n\t{0xCF8C, 0xCF8C, prLV},                     // Lo       HANGUL SYLLABLE KWAE\n\t{0xCF8D, 0xCFA7, prLVT},                    // Lo  [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH\n\t{0xCFA8, 0xCFA8, prLV},                     // Lo       HANGUL SYLLABLE KOE\n\t{0xCFA9, 0xCFC3, prLVT},                    // Lo  [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH\n\t{0xCFC4, 0xCFC4, prLV},                     // Lo       HANGUL SYLLABLE KYO\n\t{0xCFC5, 0xCFDF, prLVT},                    // Lo  [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH\n\t{0xCFE0, 0xCFE0, prLV},                     // Lo       HANGUL SYLLABLE KU\n\t{0xCFE1, 0xCFFB, prLVT},                    // Lo  [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH\n\t{0xCFFC, 0xCFFC, prLV},                     // Lo       HANGUL SYLLABLE KWEO\n\t{0xCFFD, 0xD017, prLVT},                    // Lo  [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH\n\t{0xD018, 0xD018, prLV},                     // Lo       HANGUL SYLLABLE KWE\n\t{0xD019, 0xD033, prLVT},                    // Lo  [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH\n\t{0xD034, 0xD034, prLV},                     // Lo       HANGUL SYLLABLE KWI\n\t{0xD035, 0xD04F, prLVT},                    // Lo  [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH\n\t{0xD050, 0xD050, prLV},                     // Lo       HANGUL SYLLABLE KYU\n\t{0xD051, 0xD06B, prLVT},                    // Lo  [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH\n\t{0xD06C, 0xD06C, prLV},                     // Lo       HANGUL SYLLABLE KEU\n\t{0xD06D, 0xD087, prLVT},                    // Lo  [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH\n\t{0xD088, 0xD088, prLV},                     // Lo       HANGUL SYLLABLE KYI\n\t{0xD089, 0xD0A3, prLVT},                    // Lo  [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH\n\t{0xD0A4, 0xD0A4, prLV},                     // Lo       HANGUL SYLLABLE KI\n\t{0xD0A5, 0xD0BF, prLVT},                    // Lo  [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH\n\t{0xD0C0, 0xD0C0, prLV},                     // Lo       HANGUL SYLLABLE TA\n\t{0xD0C1, 0xD0DB, prLVT},                    // Lo  [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH\n\t{0xD0DC, 0xD0DC, prLV},                     // Lo       HANGUL SYLLABLE TAE\n\t{0xD0DD, 0xD0F7, prLVT},                    // Lo  [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH\n\t{0xD0F8, 0xD0F8, prLV},                     // Lo       HANGUL SYLLABLE TYA\n\t{0xD0F9, 0xD113, prLVT},                    // Lo  [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH\n\t{0xD114, 0xD114, prLV},                     // Lo       HANGUL SYLLABLE TYAE\n\t{0xD115, 0xD12F, prLVT},                    // Lo  [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH\n\t{0xD130, 0xD130, prLV},                     // Lo       HANGUL SYLLABLE TEO\n\t{0xD131, 0xD14B, prLVT},                    // Lo  [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH\n\t{0xD14C, 0xD14C, prLV},                     // Lo       HANGUL SYLLABLE TE\n\t{0xD14D, 0xD167, prLVT},                    // Lo  [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH\n\t{0xD168, 0xD168, prLV},                     // Lo       HANGUL SYLLABLE TYEO\n\t{0xD169, 0xD183, prLVT},                    // Lo  [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH\n\t{0xD184, 0xD184, prLV},                     // Lo       HANGUL SYLLABLE TYE\n\t{0xD185, 0xD19F, prLVT},                    // Lo  [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH\n\t{0xD1A0, 0xD1A0, prLV},                     // Lo       HANGUL SYLLABLE TO\n\t{0xD1A1, 0xD1BB, prLVT},                    // Lo  [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH\n\t{0xD1BC, 0xD1BC, prLV},                     // Lo       HANGUL SYLLABLE TWA\n\t{0xD1BD, 0xD1D7, prLVT},                    // Lo  [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH\n\t{0xD1D8, 0xD1D8, prLV},                     // Lo       HANGUL SYLLABLE TWAE\n\t{0xD1D9, 0xD1F3, prLVT},                    // Lo  [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH\n\t{0xD1F4, 0xD1F4, prLV},                     // Lo       HANGUL SYLLABLE TOE\n\t{0xD1F5, 0xD20F, prLVT},                    // Lo  [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH\n\t{0xD210, 0xD210, prLV},                     // Lo       HANGUL SYLLABLE TYO\n\t{0xD211, 0xD22B, prLVT},                    // Lo  [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH\n\t{0xD22C, 0xD22C, prLV},                     // Lo       HANGUL SYLLABLE TU\n\t{0xD22D, 0xD247, prLVT},                    // Lo  [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH\n\t{0xD248, 0xD248, prLV},                     // Lo       HANGUL SYLLABLE TWEO\n\t{0xD249, 0xD263, prLVT},                    // Lo  [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH\n\t{0xD264, 0xD264, prLV},                     // Lo       HANGUL SYLLABLE TWE\n\t{0xD265, 0xD27F, prLVT},                    // Lo  [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH\n\t{0xD280, 0xD280, prLV},                     // Lo       HANGUL SYLLABLE TWI\n\t{0xD281, 0xD29B, prLVT},                    // Lo  [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH\n\t{0xD29C, 0xD29C, prLV},                     // Lo       HANGUL SYLLABLE TYU\n\t{0xD29D, 0xD2B7, prLVT},                    // Lo  [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH\n\t{0xD2B8, 0xD2B8, prLV},                     // Lo       HANGUL SYLLABLE TEU\n\t{0xD2B9, 0xD2D3, prLVT},                    // Lo  [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH\n\t{0xD2D4, 0xD2D4, prLV},                     // Lo       HANGUL SYLLABLE TYI\n\t{0xD2D5, 0xD2EF, prLVT},                    // Lo  [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH\n\t{0xD2F0, 0xD2F0, prLV},                     // Lo       HANGUL SYLLABLE TI\n\t{0xD2F1, 0xD30B, prLVT},                    // Lo  [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH\n\t{0xD30C, 0xD30C, prLV},                     // Lo       HANGUL SYLLABLE PA\n\t{0xD30D, 0xD327, prLVT},                    // Lo  [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH\n\t{0xD328, 0xD328, prLV},                     // Lo       HANGUL SYLLABLE PAE\n\t{0xD329, 0xD343, prLVT},                    // Lo  [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH\n\t{0xD344, 0xD344, prLV},                     // Lo       HANGUL SYLLABLE PYA\n\t{0xD345, 0xD35F, prLVT},                    // Lo  [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH\n\t{0xD360, 0xD360, prLV},                     // Lo       HANGUL SYLLABLE PYAE\n\t{0xD361, 0xD37B, prLVT},                    // Lo  [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH\n\t{0xD37C, 0xD37C, prLV},                     // Lo       HANGUL SYLLABLE PEO\n\t{0xD37D, 0xD397, prLVT},                    // Lo  [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH\n\t{0xD398, 0xD398, prLV},                     // Lo       HANGUL SYLLABLE PE\n\t{0xD399, 0xD3B3, prLVT},                    // Lo  [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH\n\t{0xD3B4, 0xD3B4, prLV},                     // Lo       HANGUL SYLLABLE PYEO\n\t{0xD3B5, 0xD3CF, prLVT},                    // Lo  [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH\n\t{0xD3D0, 0xD3D0, prLV},                     // Lo       HANGUL SYLLABLE PYE\n\t{0xD3D1, 0xD3EB, prLVT},                    // Lo  [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH\n\t{0xD3EC, 0xD3EC, prLV},                     // Lo       HANGUL SYLLABLE PO\n\t{0xD3ED, 0xD407, prLVT},                    // Lo  [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH\n\t{0xD408, 0xD408, prLV},                     // Lo       HANGUL SYLLABLE PWA\n\t{0xD409, 0xD423, prLVT},                    // Lo  [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH\n\t{0xD424, 0xD424, prLV},                     // Lo       HANGUL SYLLABLE PWAE\n\t{0xD425, 0xD43F, prLVT},                    // Lo  [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH\n\t{0xD440, 0xD440, prLV},                     // Lo       HANGUL SYLLABLE POE\n\t{0xD441, 0xD45B, prLVT},                    // Lo  [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH\n\t{0xD45C, 0xD45C, prLV},                     // Lo       HANGUL SYLLABLE PYO\n\t{0xD45D, 0xD477, prLVT},                    // Lo  [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH\n\t{0xD478, 0xD478, prLV},                     // Lo       HANGUL SYLLABLE PU\n\t{0xD479, 0xD493, prLVT},                    // Lo  [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH\n\t{0xD494, 0xD494, prLV},                     // Lo       HANGUL SYLLABLE PWEO\n\t{0xD495, 0xD4AF, prLVT},                    // Lo  [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH\n\t{0xD4B0, 0xD4B0, prLV},                     // Lo       HANGUL SYLLABLE PWE\n\t{0xD4B1, 0xD4CB, prLVT},                    // Lo  [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH\n\t{0xD4CC, 0xD4CC, prLV},                     // Lo       HANGUL SYLLABLE PWI\n\t{0xD4CD, 0xD4E7, prLVT},                    // Lo  [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH\n\t{0xD4E8, 0xD4E8, prLV},                     // Lo       HANGUL SYLLABLE PYU\n\t{0xD4E9, 0xD503, prLVT},                    // Lo  [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH\n\t{0xD504, 0xD504, prLV},                     // Lo       HANGUL SYLLABLE PEU\n\t{0xD505, 0xD51F, prLVT},                    // Lo  [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH\n\t{0xD520, 0xD520, prLV},                     // Lo       HANGUL SYLLABLE PYI\n\t{0xD521, 0xD53B, prLVT},                    // Lo  [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH\n\t{0xD53C, 0xD53C, prLV},                     // Lo       HANGUL SYLLABLE PI\n\t{0xD53D, 0xD557, prLVT},                    // Lo  [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH\n\t{0xD558, 0xD558, prLV},                     // Lo       HANGUL SYLLABLE HA\n\t{0xD559, 0xD573, prLVT},                    // Lo  [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH\n\t{0xD574, 0xD574, prLV},                     // Lo       HANGUL SYLLABLE HAE\n\t{0xD575, 0xD58F, prLVT},                    // Lo  [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH\n\t{0xD590, 0xD590, prLV},                     // Lo       HANGUL SYLLABLE HYA\n\t{0xD591, 0xD5AB, prLVT},                    // Lo  [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH\n\t{0xD5AC, 0xD5AC, prLV},                     // Lo       HANGUL SYLLABLE HYAE\n\t{0xD5AD, 0xD5C7, prLVT},                    // Lo  [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH\n\t{0xD5C8, 0xD5C8, prLV},                     // Lo       HANGUL SYLLABLE HEO\n\t{0xD5C9, 0xD5E3, prLVT},                    // Lo  [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH\n\t{0xD5E4, 0xD5E4, prLV},                     // Lo       HANGUL SYLLABLE HE\n\t{0xD5E5, 0xD5FF, prLVT},                    // Lo  [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH\n\t{0xD600, 0xD600, prLV},                     // Lo       HANGUL SYLLABLE HYEO\n\t{0xD601, 0xD61B, prLVT},                    // Lo  [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH\n\t{0xD61C, 0xD61C, prLV},                     // Lo       HANGUL SYLLABLE HYE\n\t{0xD61D, 0xD637, prLVT},                    // Lo  [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH\n\t{0xD638, 0xD638, prLV},                     // Lo       HANGUL SYLLABLE HO\n\t{0xD639, 0xD653, prLVT},                    // Lo  [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH\n\t{0xD654, 0xD654, prLV},                     // Lo       HANGUL SYLLABLE HWA\n\t{0xD655, 0xD66F, prLVT},                    // Lo  [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH\n\t{0xD670, 0xD670, prLV},                     // Lo       HANGUL SYLLABLE HWAE\n\t{0xD671, 0xD68B, prLVT},                    // Lo  [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH\n\t{0xD68C, 0xD68C, prLV},                     // Lo       HANGUL SYLLABLE HOE\n\t{0xD68D, 0xD6A7, prLVT},                    // Lo  [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH\n\t{0xD6A8, 0xD6A8, prLV},                     // Lo       HANGUL SYLLABLE HYO\n\t{0xD6A9, 0xD6C3, prLVT},                    // Lo  [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH\n\t{0xD6C4, 0xD6C4, prLV},                     // Lo       HANGUL SYLLABLE HU\n\t{0xD6C5, 0xD6DF, prLVT},                    // Lo  [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH\n\t{0xD6E0, 0xD6E0, prLV},                     // Lo       HANGUL SYLLABLE HWEO\n\t{0xD6E1, 0xD6FB, prLVT},                    // Lo  [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH\n\t{0xD6FC, 0xD6FC, prLV},                     // Lo       HANGUL SYLLABLE HWE\n\t{0xD6FD, 0xD717, prLVT},                    // Lo  [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH\n\t{0xD718, 0xD718, prLV},                     // Lo       HANGUL SYLLABLE HWI\n\t{0xD719, 0xD733, prLVT},                    // Lo  [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH\n\t{0xD734, 0xD734, prLV},                     // Lo       HANGUL SYLLABLE HYU\n\t{0xD735, 0xD74F, prLVT},                    // Lo  [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH\n\t{0xD750, 0xD750, prLV},                     // Lo       HANGUL SYLLABLE HEU\n\t{0xD751, 0xD76B, prLVT},                    // Lo  [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH\n\t{0xD76C, 0xD76C, prLV},                     // Lo       HANGUL SYLLABLE HYI\n\t{0xD76D, 0xD787, prLVT},                    // Lo  [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH\n\t{0xD788, 0xD788, prLV},                     // Lo       HANGUL SYLLABLE HI\n\t{0xD789, 0xD7A3, prLVT},                    // Lo  [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH\n\t{0xD7B0, 0xD7C6, prV},                      // Lo  [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E\n\t{0xD7CB, 0xD7FB, prT},                      // Lo  [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH\n\t{0xFB1E, 0xFB1E, prExtend},                 // Mn       HEBREW POINT JUDEO-SPANISH VARIKA\n\t{0xFE00, 0xFE0F, prExtend},                 // Mn  [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16\n\t{0xFE20, 0xFE2F, prExtend},                 // Mn  [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF\n\t{0xFEFF, 0xFEFF, prControl},                // Cf       ZERO WIDTH NO-BREAK SPACE\n\t{0xFF9E, 0xFF9F, prExtend},                 // Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK\n\t{0xFFF0, 0xFFF8, prControl},                // Cn   [9] <reserved-FFF0>..<reserved-FFF8>\n\t{0xFFF9, 0xFFFB, prControl},                // Cf   [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR\n\t{0x101FD, 0x101FD, prExtend},               // Mn       PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE\n\t{0x102E0, 0x102E0, prExtend},               // Mn       COPTIC EPACT THOUSANDS MARK\n\t{0x10376, 0x1037A, prExtend},               // Mn   [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII\n\t{0x10A01, 0x10A03, prExtend},               // Mn   [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R\n\t{0x10A05, 0x10A06, prExtend},               // Mn   [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O\n\t{0x10A0C, 0x10A0F, prExtend},               // Mn   [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA\n\t{0x10A38, 0x10A3A, prExtend},               // Mn   [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW\n\t{0x10A3F, 0x10A3F, prExtend},               // Mn       KHAROSHTHI VIRAMA\n\t{0x10AE5, 0x10AE6, prExtend},               // Mn   [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW\n\t{0x10D24, 0x10D27, prExtend},               // Mn   [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI\n\t{0x10F46, 0x10F50, prExtend},               // Mn  [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW\n\t{0x11000, 0x11000, prSpacingMark},          // Mc       BRAHMI SIGN CANDRABINDU\n\t{0x11001, 0x11001, prExtend},               // Mn       BRAHMI SIGN ANUSVARA\n\t{0x11002, 0x11002, prSpacingMark},          // Mc       BRAHMI SIGN VISARGA\n\t{0x11038, 0x11046, prExtend},               // Mn  [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA\n\t{0x1107F, 0x11081, prExtend},               // Mn   [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA\n\t{0x11082, 0x11082, prSpacingMark},          // Mc       KAITHI SIGN VISARGA\n\t{0x110B0, 0x110B2, prSpacingMark},          // Mc   [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II\n\t{0x110B3, 0x110B6, prExtend},               // Mn   [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI\n\t{0x110B7, 0x110B8, prSpacingMark},          // Mc   [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU\n\t{0x110B9, 0x110BA, prExtend},               // Mn   [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA\n\t{0x110BD, 0x110BD, prPreprend},             // Cf       KAITHI NUMBER SIGN\n\t{0x110CD, 0x110CD, prPreprend},             // Cf       KAITHI NUMBER SIGN ABOVE\n\t{0x11100, 0x11102, prExtend},               // Mn   [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA\n\t{0x11127, 0x1112B, prExtend},               // Mn   [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU\n\t{0x1112C, 0x1112C, prSpacingMark},          // Mc       CHAKMA VOWEL SIGN E\n\t{0x1112D, 0x11134, prExtend},               // Mn   [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA\n\t{0x11145, 0x11146, prSpacingMark},          // Mc   [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI\n\t{0x11173, 0x11173, prExtend},               // Mn       MAHAJANI SIGN NUKTA\n\t{0x11180, 0x11181, prExtend},               // Mn   [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA\n\t{0x11182, 0x11182, prSpacingMark},          // Mc       SHARADA SIGN VISARGA\n\t{0x111B3, 0x111B5, prSpacingMark},          // Mc   [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II\n\t{0x111B6, 0x111BE, prExtend},               // Mn   [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O\n\t{0x111BF, 0x111C0, prSpacingMark},          // Mc   [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA\n\t{0x111C2, 0x111C3, prPreprend},             // Lo   [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA\n\t{0x111C9, 0x111CC, prExtend},               // Mn   [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK\n\t{0x1122C, 0x1122E, prSpacingMark},          // Mc   [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II\n\t{0x1122F, 0x11231, prExtend},               // Mn   [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI\n\t{0x11232, 0x11233, prSpacingMark},          // Mc   [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU\n\t{0x11234, 0x11234, prExtend},               // Mn       KHOJKI SIGN ANUSVARA\n\t{0x11235, 0x11235, prSpacingMark},          // Mc       KHOJKI SIGN VIRAMA\n\t{0x11236, 0x11237, prExtend},               // Mn   [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA\n\t{0x1123E, 0x1123E, prExtend},               // Mn       KHOJKI SIGN SUKUN\n\t{0x112DF, 0x112DF, prExtend},               // Mn       KHUDAWADI SIGN ANUSVARA\n\t{0x112E0, 0x112E2, prSpacingMark},          // Mc   [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II\n\t{0x112E3, 0x112EA, prExtend},               // Mn   [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA\n\t{0x11300, 0x11301, prExtend},               // Mn   [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU\n\t{0x11302, 0x11303, prSpacingMark},          // Mc   [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA\n\t{0x1133B, 0x1133C, prExtend},               // Mn   [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA\n\t{0x1133E, 0x1133E, prExtend},               // Mc       GRANTHA VOWEL SIGN AA\n\t{0x1133F, 0x1133F, prSpacingMark},          // Mc       GRANTHA VOWEL SIGN I\n\t{0x11340, 0x11340, prExtend},               // Mn       GRANTHA VOWEL SIGN II\n\t{0x11341, 0x11344, prSpacingMark},          // Mc   [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR\n\t{0x11347, 0x11348, prSpacingMark},          // Mc   [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI\n\t{0x1134B, 0x1134D, prSpacingMark},          // Mc   [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA\n\t{0x11357, 0x11357, prExtend},               // Mc       GRANTHA AU LENGTH MARK\n\t{0x11362, 0x11363, prSpacingMark},          // Mc   [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL\n\t{0x11366, 0x1136C, prExtend},               // Mn   [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX\n\t{0x11370, 0x11374, prExtend},               // Mn   [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA\n\t{0x11435, 0x11437, prSpacingMark},          // Mc   [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II\n\t{0x11438, 0x1143F, prExtend},               // Mn   [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI\n\t{0x11440, 0x11441, prSpacingMark},          // Mc   [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU\n\t{0x11442, 0x11444, prExtend},               // Mn   [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA\n\t{0x11445, 0x11445, prSpacingMark},          // Mc       NEWA SIGN VISARGA\n\t{0x11446, 0x11446, prExtend},               // Mn       NEWA SIGN NUKTA\n\t{0x1145E, 0x1145E, prExtend},               // Mn       NEWA SANDHI MARK\n\t{0x114B0, 0x114B0, prExtend},               // Mc       TIRHUTA VOWEL SIGN AA\n\t{0x114B1, 0x114B2, prSpacingMark},          // Mc   [2] TIRHUTA VOWEL SIGN I..TIRHUTA VOWEL SIGN II\n\t{0x114B3, 0x114B8, prExtend},               // Mn   [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL\n\t{0x114B9, 0x114B9, prSpacingMark},          // Mc       TIRHUTA VOWEL SIGN E\n\t{0x114BA, 0x114BA, prExtend},               // Mn       TIRHUTA VOWEL SIGN SHORT E\n\t{0x114BB, 0x114BC, prSpacingMark},          // Mc   [2] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN O\n\t{0x114BD, 0x114BD, prExtend},               // Mc       TIRHUTA VOWEL SIGN SHORT O\n\t{0x114BE, 0x114BE, prSpacingMark},          // Mc       TIRHUTA VOWEL SIGN AU\n\t{0x114BF, 0x114C0, prExtend},               // Mn   [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA\n\t{0x114C1, 0x114C1, prSpacingMark},          // Mc       TIRHUTA SIGN VISARGA\n\t{0x114C2, 0x114C3, prExtend},               // Mn   [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA\n\t{0x115AF, 0x115AF, prExtend},               // Mc       SIDDHAM VOWEL SIGN AA\n\t{0x115B0, 0x115B1, prSpacingMark},          // Mc   [2] SIDDHAM VOWEL SIGN I..SIDDHAM VOWEL SIGN II\n\t{0x115B2, 0x115B5, prExtend},               // Mn   [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR\n\t{0x115B8, 0x115BB, prSpacingMark},          // Mc   [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU\n\t{0x115BC, 0x115BD, prExtend},               // Mn   [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA\n\t{0x115BE, 0x115BE, prSpacingMark},          // Mc       SIDDHAM SIGN VISARGA\n\t{0x115BF, 0x115C0, prExtend},               // Mn   [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA\n\t{0x115DC, 0x115DD, prExtend},               // Mn   [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU\n\t{0x11630, 0x11632, prSpacingMark},          // Mc   [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II\n\t{0x11633, 0x1163A, prExtend},               // Mn   [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI\n\t{0x1163B, 0x1163C, prSpacingMark},          // Mc   [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU\n\t{0x1163D, 0x1163D, prExtend},               // Mn       MODI SIGN ANUSVARA\n\t{0x1163E, 0x1163E, prSpacingMark},          // Mc       MODI SIGN VISARGA\n\t{0x1163F, 0x11640, prExtend},               // Mn   [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA\n\t{0x116AB, 0x116AB, prExtend},               // Mn       TAKRI SIGN ANUSVARA\n\t{0x116AC, 0x116AC, prSpacingMark},          // Mc       TAKRI SIGN VISARGA\n\t{0x116AD, 0x116AD, prExtend},               // Mn       TAKRI VOWEL SIGN AA\n\t{0x116AE, 0x116AF, prSpacingMark},          // Mc   [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II\n\t{0x116B0, 0x116B5, prExtend},               // Mn   [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU\n\t{0x116B6, 0x116B6, prSpacingMark},          // Mc       TAKRI SIGN VIRAMA\n\t{0x116B7, 0x116B7, prExtend},               // Mn       TAKRI SIGN NUKTA\n\t{0x1171D, 0x1171F, prExtend},               // Mn   [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA\n\t{0x11720, 0x11721, prSpacingMark},          // Mc   [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA\n\t{0x11722, 0x11725, prExtend},               // Mn   [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU\n\t{0x11726, 0x11726, prSpacingMark},          // Mc       AHOM VOWEL SIGN E\n\t{0x11727, 0x1172B, prExtend},               // Mn   [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER\n\t{0x1182C, 0x1182E, prSpacingMark},          // Mc   [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II\n\t{0x1182F, 0x11837, prExtend},               // Mn   [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA\n\t{0x11838, 0x11838, prSpacingMark},          // Mc       DOGRA SIGN VISARGA\n\t{0x11839, 0x1183A, prExtend},               // Mn   [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA\n\t{0x119D1, 0x119D3, prSpacingMark},          // Mc   [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II\n\t{0x119D4, 0x119D7, prExtend},               // Mn   [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR\n\t{0x119DA, 0x119DB, prExtend},               // Mn   [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI\n\t{0x119DC, 0x119DF, prSpacingMark},          // Mc   [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA\n\t{0x119E0, 0x119E0, prExtend},               // Mn       NANDINAGARI SIGN VIRAMA\n\t{0x119E4, 0x119E4, prSpacingMark},          // Mc       NANDINAGARI VOWEL SIGN PRISHTHAMATRA E\n\t{0x11A01, 0x11A0A, prExtend},               // Mn  [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK\n\t{0x11A33, 0x11A38, prExtend},               // Mn   [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA\n\t{0x11A39, 0x11A39, prSpacingMark},          // Mc       ZANABAZAR SQUARE SIGN VISARGA\n\t{0x11A3A, 0x11A3A, prPreprend},             // Lo       ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA\n\t{0x11A3B, 0x11A3E, prExtend},               // Mn   [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA\n\t{0x11A47, 0x11A47, prExtend},               // Mn       ZANABAZAR SQUARE SUBJOINER\n\t{0x11A51, 0x11A56, prExtend},               // Mn   [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE\n\t{0x11A57, 0x11A58, prSpacingMark},          // Mc   [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU\n\t{0x11A59, 0x11A5B, prExtend},               // Mn   [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK\n\t{0x11A84, 0x11A89, prPreprend},             // Lo   [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA\n\t{0x11A8A, 0x11A96, prExtend},               // Mn  [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA\n\t{0x11A97, 0x11A97, prSpacingMark},          // Mc       SOYOMBO SIGN VISARGA\n\t{0x11A98, 0x11A99, prExtend},               // Mn   [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER\n\t{0x11C2F, 0x11C2F, prSpacingMark},          // Mc       BHAIKSUKI VOWEL SIGN AA\n\t{0x11C30, 0x11C36, prExtend},               // Mn   [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L\n\t{0x11C38, 0x11C3D, prExtend},               // Mn   [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA\n\t{0x11C3E, 0x11C3E, prSpacingMark},          // Mc       BHAIKSUKI SIGN VISARGA\n\t{0x11C3F, 0x11C3F, prExtend},               // Mn       BHAIKSUKI SIGN VIRAMA\n\t{0x11C92, 0x11CA7, prExtend},               // Mn  [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA\n\t{0x11CA9, 0x11CA9, prSpacingMark},          // Mc       MARCHEN SUBJOINED LETTER YA\n\t{0x11CAA, 0x11CB0, prExtend},               // Mn   [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA\n\t{0x11CB1, 0x11CB1, prSpacingMark},          // Mc       MARCHEN VOWEL SIGN I\n\t{0x11CB2, 0x11CB3, prExtend},               // Mn   [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E\n\t{0x11CB4, 0x11CB4, prSpacingMark},          // Mc       MARCHEN VOWEL SIGN O\n\t{0x11CB5, 0x11CB6, prExtend},               // Mn   [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU\n\t{0x11D31, 0x11D36, prExtend},               // Mn   [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R\n\t{0x11D3A, 0x11D3A, prExtend},               // Mn       MASARAM GONDI VOWEL SIGN E\n\t{0x11D3C, 0x11D3D, prExtend},               // Mn   [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O\n\t{0x11D3F, 0x11D45, prExtend},               // Mn   [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA\n\t{0x11D46, 0x11D46, prPreprend},             // Lo       MASARAM GONDI REPHA\n\t{0x11D47, 0x11D47, prExtend},               // Mn       MASARAM GONDI RA-KARA\n\t{0x11D8A, 0x11D8E, prSpacingMark},          // Mc   [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU\n\t{0x11D90, 0x11D91, prExtend},               // Mn   [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI\n\t{0x11D93, 0x11D94, prSpacingMark},          // Mc   [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU\n\t{0x11D95, 0x11D95, prExtend},               // Mn       GUNJALA GONDI SIGN ANUSVARA\n\t{0x11D96, 0x11D96, prSpacingMark},          // Mc       GUNJALA GONDI SIGN VISARGA\n\t{0x11D97, 0x11D97, prExtend},               // Mn       GUNJALA GONDI VIRAMA\n\t{0x11EF3, 0x11EF4, prExtend},               // Mn   [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U\n\t{0x11EF5, 0x11EF6, prSpacingMark},          // Mc   [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O\n\t{0x13430, 0x13438, prControl},              // Cf   [9] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END SEGMENT\n\t{0x16AF0, 0x16AF4, prExtend},               // Mn   [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE\n\t{0x16B30, 0x16B36, prExtend},               // Mn   [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM\n\t{0x16F4F, 0x16F4F, prExtend},               // Mn       MIAO SIGN CONSONANT MODIFIER BAR\n\t{0x16F51, 0x16F87, prSpacingMark},          // Mc  [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI\n\t{0x16F8F, 0x16F92, prExtend},               // Mn   [4] MIAO TONE RIGHT..MIAO TONE BELOW\n\t{0x1BC9D, 0x1BC9E, prExtend},               // Mn   [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK\n\t{0x1BCA0, 0x1BCA3, prControl},              // Cf   [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP\n\t{0x1D165, 0x1D165, prExtend},               // Mc       MUSICAL SYMBOL COMBINING STEM\n\t{0x1D166, 0x1D166, prSpacingMark},          // Mc       MUSICAL SYMBOL COMBINING SPRECHGESANG STEM\n\t{0x1D167, 0x1D169, prExtend},               // Mn   [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3\n\t{0x1D16D, 0x1D16D, prSpacingMark},          // Mc       MUSICAL SYMBOL COMBINING AUGMENTATION DOT\n\t{0x1D16E, 0x1D172, prExtend},               // Mc   [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5\n\t{0x1D173, 0x1D17A, prControl},              // Cf   [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE\n\t{0x1D17B, 0x1D182, prExtend},               // Mn   [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE\n\t{0x1D185, 0x1D18B, prExtend},               // Mn   [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE\n\t{0x1D1AA, 0x1D1AD, prExtend},               // Mn   [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO\n\t{0x1D242, 0x1D244, prExtend},               // Mn   [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME\n\t{0x1DA00, 0x1DA36, prExtend},               // Mn  [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN\n\t{0x1DA3B, 0x1DA6C, prExtend},               // Mn  [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT\n\t{0x1DA75, 0x1DA75, prExtend},               // Mn       SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS\n\t{0x1DA84, 0x1DA84, prExtend},               // Mn       SIGNWRITING LOCATION HEAD NECK\n\t{0x1DA9B, 0x1DA9F, prExtend},               // Mn   [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6\n\t{0x1DAA1, 0x1DAAF, prExtend},               // Mn  [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16\n\t{0x1E000, 0x1E006, prExtend},               // Mn   [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE\n\t{0x1E008, 0x1E018, prExtend},               // Mn  [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU\n\t{0x1E01B, 0x1E021, prExtend},               // Mn   [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI\n\t{0x1E023, 0x1E024, prExtend},               // Mn   [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS\n\t{0x1E026, 0x1E02A, prExtend},               // Mn   [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA\n\t{0x1E130, 0x1E136, prExtend},               // Mn   [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D\n\t{0x1E2EC, 0x1E2EF, prExtend},               // Mn   [4] WANCHO TONE TUP..WANCHO TONE KOINI\n\t{0x1E8D0, 0x1E8D6, prExtend},               // Mn   [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS\n\t{0x1E944, 0x1E94A, prExtend},               // Mn   [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA\n\t{0x1F000, 0x1F02B, prExtendedPictographic}, //  5.1 [44] (🀀..🀫)    MAHJONG TILE EAST WIND..MAHJONG TILE BACK\n\t{0x1F02C, 0x1F02F, prExtendedPictographic}, //   NA  [4] (🀬..🀯)    <reserved-1F02C>..<reserved-1F02F>\n\t{0x1F030, 0x1F093, prExtendedPictographic}, //  5.1[100] (🀰..🂓)    DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06\n\t{0x1F094, 0x1F09F, prExtendedPictographic}, //   NA [12] (🂔..🂟)    <reserved-1F094>..<reserved-1F09F>\n\t{0x1F0A0, 0x1F0AE, prExtendedPictographic}, //  6.0 [15] (🂠..🂮)    PLAYING CARD BACK..PLAYING CARD KING OF SPADES\n\t{0x1F0AF, 0x1F0B0, prExtendedPictographic}, //   NA  [2] (🂯..🂰)    <reserved-1F0AF>..<reserved-1F0B0>\n\t{0x1F0B1, 0x1F0BE, prExtendedPictographic}, //  6.0 [14] (🂱..🂾)    PLAYING CARD ACE OF HEARTS..PLAYING CARD KING OF HEARTS\n\t{0x1F0BF, 0x1F0BF, prExtendedPictographic}, //  7.0  [1] (🂿)       PLAYING CARD RED JOKER\n\t{0x1F0C0, 0x1F0C0, prExtendedPictographic}, //   NA  [1] (🃀)       <reserved-1F0C0>\n\t{0x1F0C1, 0x1F0CF, prExtendedPictographic}, //  6.0 [15] (🃁..🃏)    PLAYING CARD ACE OF DIAMONDS..joker\n\t{0x1F0D0, 0x1F0D0, prExtendedPictographic}, //   NA  [1] (🃐)       <reserved-1F0D0>\n\t{0x1F0D1, 0x1F0DF, prExtendedPictographic}, //  6.0 [15] (🃑..🃟)    PLAYING CARD ACE OF CLUBS..PLAYING CARD WHITE JOKER\n\t{0x1F0E0, 0x1F0F5, prExtendedPictographic}, //  7.0 [22] (🃠..🃵)    PLAYING CARD FOOL..PLAYING CARD TRUMP-21\n\t{0x1F0F6, 0x1F0FF, prExtendedPictographic}, //   NA [10] (🃶..🃿)    <reserved-1F0F6>..<reserved-1F0FF>\n\t{0x1F10D, 0x1F10F, prExtendedPictographic}, //   NA  [3] (🄍..🄏)    <reserved-1F10D>..<reserved-1F10F>\n\t{0x1F12F, 0x1F12F, prExtendedPictographic}, // 11.0  [1] (🄯)       COPYLEFT SYMBOL\n\t{0x1F16C, 0x1F16C, prExtendedPictographic}, // 12.0  [1] (🅬)       RAISED MR SIGN\n\t{0x1F16D, 0x1F16F, prExtendedPictographic}, //   NA  [3] (🅭..🅯)    <reserved-1F16D>..<reserved-1F16F>\n\t{0x1F170, 0x1F171, prExtendedPictographic}, //  6.0  [2] (🅰️..🅱️)    A button (blood type)..B button (blood type)\n\t{0x1F17E, 0x1F17E, prExtendedPictographic}, //  6.0  [1] (🅾️)       O button (blood type)\n\t{0x1F17F, 0x1F17F, prExtendedPictographic}, //  5.2  [1] (🅿️)       P button\n\t{0x1F18E, 0x1F18E, prExtendedPictographic}, //  6.0  [1] (🆎)       AB button (blood type)\n\t{0x1F191, 0x1F19A, prExtendedPictographic}, //  6.0 [10] (🆑..🆚)    CL button..VS button\n\t{0x1F1AD, 0x1F1E5, prExtendedPictographic}, //   NA [57] (🆭..🇥)    <reserved-1F1AD>..<reserved-1F1E5>\n\t{0x1F1E6, 0x1F1FF, prRegionalIndicator},    // So  [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z\n\t{0x1F201, 0x1F202, prExtendedPictographic}, //  6.0  [2] (🈁..🈂️)    Japanese “here” button..Japanese “service charge” button\n\t{0x1F203, 0x1F20F, prExtendedPictographic}, //   NA [13] (🈃..🈏)    <reserved-1F203>..<reserved-1F20F>\n\t{0x1F21A, 0x1F21A, prExtendedPictographic}, //  5.2  [1] (🈚)       Japanese “free of charge” button\n\t{0x1F22F, 0x1F22F, prExtendedPictographic}, //  5.2  [1] (🈯)       Japanese “reserved” button\n\t{0x1F232, 0x1F23A, prExtendedPictographic}, //  6.0  [9] (🈲..🈺)    Japanese “prohibited” button..Japanese “open for business” button\n\t{0x1F23C, 0x1F23F, prExtendedPictographic}, //   NA  [4] (🈼..🈿)    <reserved-1F23C>..<reserved-1F23F>\n\t{0x1F249, 0x1F24F, prExtendedPictographic}, //   NA  [7] (🉉..🉏)    <reserved-1F249>..<reserved-1F24F>\n\t{0x1F250, 0x1F251, prExtendedPictographic}, //  6.0  [2] (🉐..🉑)    Japanese “bargain” button..Japanese “acceptable” button\n\t{0x1F252, 0x1F25F, prExtendedPictographic}, //   NA [14] (🉒..🉟)    <reserved-1F252>..<reserved-1F25F>\n\t{0x1F260, 0x1F265, prExtendedPictographic}, // 10.0  [6] (🉠..🉥)    ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI\n\t{0x1F266, 0x1F2FF, prExtendedPictographic}, //   NA[154] (🉦..🋿)    <reserved-1F266>..<reserved-1F2FF>\n\t{0x1F300, 0x1F320, prExtendedPictographic}, //  6.0 [33] (🌀..🌠)    cyclone..shooting star\n\t{0x1F321, 0x1F32C, prExtendedPictographic}, //  7.0 [12] (🌡️..🌬️)    thermometer..wind face\n\t{0x1F32D, 0x1F32F, prExtendedPictographic}, //  8.0  [3] (🌭..🌯)    hot dog..burrito\n\t{0x1F330, 0x1F335, prExtendedPictographic}, //  6.0  [6] (🌰..🌵)    chestnut..cactus\n\t{0x1F336, 0x1F336, prExtendedPictographic}, //  7.0  [1] (🌶️)       hot pepper\n\t{0x1F337, 0x1F37C, prExtendedPictographic}, //  6.0 [70] (🌷..🍼)    tulip..baby bottle\n\t{0x1F37D, 0x1F37D, prExtendedPictographic}, //  7.0  [1] (🍽️)       fork and knife with plate\n\t{0x1F37E, 0x1F37F, prExtendedPictographic}, //  8.0  [2] (🍾..🍿)    bottle with popping cork..popcorn\n\t{0x1F380, 0x1F393, prExtendedPictographic}, //  6.0 [20] (🎀..🎓)    ribbon..graduation cap\n\t{0x1F394, 0x1F39F, prExtendedPictographic}, //  7.0 [12] (🎔..🎟️)    HEART WITH TIP ON THE LEFT..admission tickets\n\t{0x1F3A0, 0x1F3C4, prExtendedPictographic}, //  6.0 [37] (🎠..🏄)    carousel horse..person surfing\n\t{0x1F3C5, 0x1F3C5, prExtendedPictographic}, //  7.0  [1] (🏅)       sports medal\n\t{0x1F3C6, 0x1F3CA, prExtendedPictographic}, //  6.0  [5] (🏆..🏊)    trophy..person swimming\n\t{0x1F3CB, 0x1F3CE, prExtendedPictographic}, //  7.0  [4] (🏋️..🏎️)    person lifting weights..racing car\n\t{0x1F3CF, 0x1F3D3, prExtendedPictographic}, //  8.0  [5] (🏏..🏓)    cricket game..ping pong\n\t{0x1F3D4, 0x1F3DF, prExtendedPictographic}, //  7.0 [12] (🏔️..🏟️)    snow-capped mountain..stadium\n\t{0x1F3E0, 0x1F3F0, prExtendedPictographic}, //  6.0 [17] (🏠..🏰)    house..castle\n\t{0x1F3F1, 0x1F3F7, prExtendedPictographic}, //  7.0  [7] (🏱..🏷️)    WHITE PENNANT..label\n\t{0x1F3F8, 0x1F3FA, prExtendedPictographic}, //  8.0  [3] (🏸..🏺)    badminton..amphora\n\t{0x1F3FB, 0x1F3FF, prExtend},               // Sk   [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6\n\t{0x1F400, 0x1F43E, prExtendedPictographic}, //  6.0 [63] (🐀..🐾)    rat..paw prints\n\t{0x1F43F, 0x1F43F, prExtendedPictographic}, //  7.0  [1] (🐿️)       chipmunk\n\t{0x1F440, 0x1F440, prExtendedPictographic}, //  6.0  [1] (👀)       eyes\n\t{0x1F441, 0x1F441, prExtendedPictographic}, //  7.0  [1] (👁️)       eye\n\t{0x1F442, 0x1F4F7, prExtendedPictographic}, //  6.0[182] (👂..📷)    ear..camera\n\t{0x1F4F8, 0x1F4F8, prExtendedPictographic}, //  7.0  [1] (📸)       camera with flash\n\t{0x1F4F9, 0x1F4FC, prExtendedPictographic}, //  6.0  [4] (📹..📼)    video camera..videocassette\n\t{0x1F4FD, 0x1F4FE, prExtendedPictographic}, //  7.0  [2] (📽️..📾)    film projector..PORTABLE STEREO\n\t{0x1F4FF, 0x1F4FF, prExtendedPictographic}, //  8.0  [1] (📿)       prayer beads\n\t{0x1F500, 0x1F53D, prExtendedPictographic}, //  6.0 [62] (🔀..🔽)    shuffle tracks button..downwards button\n\t{0x1F546, 0x1F54A, prExtendedPictographic}, //  7.0  [5] (🕆..🕊️)    WHITE LATIN CROSS..dove\n\t{0x1F54B, 0x1F54F, prExtendedPictographic}, //  8.0  [5] (🕋..🕏)    kaaba..BOWL OF HYGIEIA\n\t{0x1F550, 0x1F567, prExtendedPictographic}, //  6.0 [24] (🕐..🕧)    one o’clock..twelve-thirty\n\t{0x1F568, 0x1F579, prExtendedPictographic}, //  7.0 [18] (🕨..🕹️)    RIGHT SPEAKER..joystick\n\t{0x1F57A, 0x1F57A, prExtendedPictographic}, //  9.0  [1] (🕺)       man dancing\n\t{0x1F57B, 0x1F5A3, prExtendedPictographic}, //  7.0 [41] (🕻..🖣)    LEFT HAND TELEPHONE RECEIVER..BLACK DOWN POINTING BACKHAND INDEX\n\t{0x1F5A4, 0x1F5A4, prExtendedPictographic}, //  9.0  [1] (🖤)       black heart\n\t{0x1F5A5, 0x1F5FA, prExtendedPictographic}, //  7.0 [86] (🖥️..🗺️)    desktop computer..world map\n\t{0x1F5FB, 0x1F5FF, prExtendedPictographic}, //  6.0  [5] (🗻..🗿)    mount fuji..moai\n\t{0x1F600, 0x1F600, prExtendedPictographic}, //  6.1  [1] (😀)       grinning face\n\t{0x1F601, 0x1F610, prExtendedPictographic}, //  6.0 [16] (😁..😐)    beaming face with smiling eyes..neutral face\n\t{0x1F611, 0x1F611, prExtendedPictographic}, //  6.1  [1] (😑)       expressionless face\n\t{0x1F612, 0x1F614, prExtendedPictographic}, //  6.0  [3] (😒..😔)    unamused face..pensive face\n\t{0x1F615, 0x1F615, prExtendedPictographic}, //  6.1  [1] (😕)       confused face\n\t{0x1F616, 0x1F616, prExtendedPictographic}, //  6.0  [1] (😖)       confounded face\n\t{0x1F617, 0x1F617, prExtendedPictographic}, //  6.1  [1] (😗)       kissing face\n\t{0x1F618, 0x1F618, prExtendedPictographic}, //  6.0  [1] (😘)       face blowing a kiss\n\t{0x1F619, 0x1F619, prExtendedPictographic}, //  6.1  [1] (😙)       kissing face with smiling eyes\n\t{0x1F61A, 0x1F61A, prExtendedPictographic}, //  6.0  [1] (😚)       kissing face with closed eyes\n\t{0x1F61B, 0x1F61B, prExtendedPictographic}, //  6.1  [1] (😛)       face with tongue\n\t{0x1F61C, 0x1F61E, prExtendedPictographic}, //  6.0  [3] (😜..😞)    winking face with tongue..disappointed face\n\t{0x1F61F, 0x1F61F, prExtendedPictographic}, //  6.1  [1] (😟)       worried face\n\t{0x1F620, 0x1F625, prExtendedPictographic}, //  6.0  [6] (😠..😥)    angry face..sad but relieved face\n\t{0x1F626, 0x1F627, prExtendedPictographic}, //  6.1  [2] (😦..😧)    frowning face with open mouth..anguished face\n\t{0x1F628, 0x1F62B, prExtendedPictographic}, //  6.0  [4] (😨..😫)    fearful face..tired face\n\t{0x1F62C, 0x1F62C, prExtendedPictographic}, //  6.1  [1] (😬)       grimacing face\n\t{0x1F62D, 0x1F62D, prExtendedPictographic}, //  6.0  [1] (😭)       loudly crying face\n\t{0x1F62E, 0x1F62F, prExtendedPictographic}, //  6.1  [2] (😮..😯)    face with open mouth..hushed face\n\t{0x1F630, 0x1F633, prExtendedPictographic}, //  6.0  [4] (😰..😳)    anxious face with sweat..flushed face\n\t{0x1F634, 0x1F634, prExtendedPictographic}, //  6.1  [1] (😴)       sleeping face\n\t{0x1F635, 0x1F640, prExtendedPictographic}, //  6.0 [12] (😵..🙀)    dizzy face..weary cat\n\t{0x1F641, 0x1F642, prExtendedPictographic}, //  7.0  [2] (🙁..🙂)    slightly frowning face..slightly smiling face\n\t{0x1F643, 0x1F644, prExtendedPictographic}, //  8.0  [2] (🙃..🙄)    upside-down face..face with rolling eyes\n\t{0x1F645, 0x1F64F, prExtendedPictographic}, //  6.0 [11] (🙅..🙏)    person gesturing NO..folded hands\n\t{0x1F680, 0x1F6C5, prExtendedPictographic}, //  6.0 [70] (🚀..🛅)    rocket..left luggage\n\t{0x1F6C6, 0x1F6CF, prExtendedPictographic}, //  7.0 [10] (🛆..🛏️)    TRIANGLE WITH ROUNDED CORNERS..bed\n\t{0x1F6D0, 0x1F6D0, prExtendedPictographic}, //  8.0  [1] (🛐)       place of worship\n\t{0x1F6D1, 0x1F6D2, prExtendedPictographic}, //  9.0  [2] (🛑..🛒)    stop sign..shopping cart\n\t{0x1F6D3, 0x1F6D4, prExtendedPictographic}, // 10.0  [2] (🛓..🛔)    STUPA..PAGODA\n\t{0x1F6D5, 0x1F6D5, prExtendedPictographic}, // 12.0  [1] (🛕)       hindu temple\n\t{0x1F6D6, 0x1F6DF, prExtendedPictographic}, //   NA [10] (🛖..🛟)    <reserved-1F6D6>..<reserved-1F6DF>\n\t{0x1F6E0, 0x1F6EC, prExtendedPictographic}, //  7.0 [13] (🛠️..🛬)    hammer and wrench..airplane arrival\n\t{0x1F6ED, 0x1F6EF, prExtendedPictographic}, //   NA  [3] (🛭..🛯)    <reserved-1F6ED>..<reserved-1F6EF>\n\t{0x1F6F0, 0x1F6F3, prExtendedPictographic}, //  7.0  [4] (🛰️..🛳️)    satellite..passenger ship\n\t{0x1F6F4, 0x1F6F6, prExtendedPictographic}, //  9.0  [3] (🛴..🛶)    kick scooter..canoe\n\t{0x1F6F7, 0x1F6F8, prExtendedPictographic}, // 10.0  [2] (🛷..🛸)    sled..flying saucer\n\t{0x1F6F9, 0x1F6F9, prExtendedPictographic}, // 11.0  [1] (🛹)       skateboard\n\t{0x1F6FA, 0x1F6FA, prExtendedPictographic}, // 12.0  [1] (🛺)       auto rickshaw\n\t{0x1F6FB, 0x1F6FF, prExtendedPictographic}, //   NA  [5] (🛻..🛿)    <reserved-1F6FB>..<reserved-1F6FF>\n\t{0x1F774, 0x1F77F, prExtendedPictographic}, //   NA [12] (🝴..🝿)    <reserved-1F774>..<reserved-1F77F>\n\t{0x1F7D5, 0x1F7D8, prExtendedPictographic}, // 11.0  [4] (🟕..🟘)    CIRCLED TRIANGLE..NEGATIVE CIRCLED SQUARE\n\t{0x1F7D9, 0x1F7DF, prExtendedPictographic}, //   NA  [7] (🟙..🟟)    <reserved-1F7D9>..<reserved-1F7DF>\n\t{0x1F7E0, 0x1F7EB, prExtendedPictographic}, // 12.0 [12] (🟠..🟫)    orange circle..brown square\n\t{0x1F7EC, 0x1F7FF, prExtendedPictographic}, //   NA [20] (🟬..🟿)    <reserved-1F7EC>..<reserved-1F7FF>\n\t{0x1F80C, 0x1F80F, prExtendedPictographic}, //   NA  [4] (🠌..🠏)    <reserved-1F80C>..<reserved-1F80F>\n\t{0x1F848, 0x1F84F, prExtendedPictographic}, //   NA  [8] (🡈..🡏)    <reserved-1F848>..<reserved-1F84F>\n\t{0x1F85A, 0x1F85F, prExtendedPictographic}, //   NA  [6] (🡚..🡟)    <reserved-1F85A>..<reserved-1F85F>\n\t{0x1F888, 0x1F88F, prExtendedPictographic}, //   NA  [8] (🢈..🢏)    <reserved-1F888>..<reserved-1F88F>\n\t{0x1F8AE, 0x1F8FF, prExtendedPictographic}, //   NA [82] (🢮..🣿)    <reserved-1F8AE>..<reserved-1F8FF>\n\t{0x1F90C, 0x1F90C, prExtendedPictographic}, //   NA  [1] (🤌)       <reserved-1F90C>\n\t{0x1F90D, 0x1F90F, prExtendedPictographic}, // 12.0  [3] (🤍..🤏)    white heart..pinching hand\n\t{0x1F910, 0x1F918, prExtendedPictographic}, //  8.0  [9] (🤐..🤘)    zipper-mouth face..sign of the horns\n\t{0x1F919, 0x1F91E, prExtendedPictographic}, //  9.0  [6] (🤙..🤞)    call me hand..crossed fingers\n\t{0x1F91F, 0x1F91F, prExtendedPictographic}, // 10.0  [1] (🤟)       love-you gesture\n\t{0x1F920, 0x1F927, prExtendedPictographic}, //  9.0  [8] (🤠..🤧)    cowboy hat face..sneezing face\n\t{0x1F928, 0x1F92F, prExtendedPictographic}, // 10.0  [8] (🤨..🤯)    face with raised eyebrow..exploding head\n\t{0x1F930, 0x1F930, prExtendedPictographic}, //  9.0  [1] (🤰)       pregnant woman\n\t{0x1F931, 0x1F932, prExtendedPictographic}, // 10.0  [2] (🤱..🤲)    breast-feeding..palms up together\n\t{0x1F933, 0x1F93A, prExtendedPictographic}, //  9.0  [8] (🤳..🤺)    selfie..person fencing\n\t{0x1F93C, 0x1F93E, prExtendedPictographic}, //  9.0  [3] (🤼..🤾)    people wrestling..person playing handball\n\t{0x1F93F, 0x1F93F, prExtendedPictographic}, // 12.0  [1] (🤿)       diving mask\n\t{0x1F940, 0x1F945, prExtendedPictographic}, //  9.0  [6] (🥀..🥅)    wilted flower..goal net\n\t{0x1F947, 0x1F94B, prExtendedPictographic}, //  9.0  [5] (🥇..🥋)    1st place medal..martial arts uniform\n\t{0x1F94C, 0x1F94C, prExtendedPictographic}, // 10.0  [1] (🥌)       curling stone\n\t{0x1F94D, 0x1F94F, prExtendedPictographic}, // 11.0  [3] (🥍..🥏)    lacrosse..flying disc\n\t{0x1F950, 0x1F95E, prExtendedPictographic}, //  9.0 [15] (🥐..🥞)    croissant..pancakes\n\t{0x1F95F, 0x1F96B, prExtendedPictographic}, // 10.0 [13] (🥟..🥫)    dumpling..canned food\n\t{0x1F96C, 0x1F970, prExtendedPictographic}, // 11.0  [5] (🥬..🥰)    leafy green..smiling face with hearts\n\t{0x1F971, 0x1F971, prExtendedPictographic}, // 12.0  [1] (🥱)       yawning face\n\t{0x1F972, 0x1F972, prExtendedPictographic}, //   NA  [1] (🥲)       <reserved-1F972>\n\t{0x1F973, 0x1F976, prExtendedPictographic}, // 11.0  [4] (🥳..🥶)    partying face..cold face\n\t{0x1F977, 0x1F979, prExtendedPictographic}, //   NA  [3] (🥷..🥹)    <reserved-1F977>..<reserved-1F979>\n\t{0x1F97A, 0x1F97A, prExtendedPictographic}, // 11.0  [1] (🥺)       pleading face\n\t{0x1F97B, 0x1F97B, prExtendedPictographic}, // 12.0  [1] (🥻)       sari\n\t{0x1F97C, 0x1F97F, prExtendedPictographic}, // 11.0  [4] (🥼..🥿)    lab coat..flat shoe\n\t{0x1F980, 0x1F984, prExtendedPictographic}, //  8.0  [5] (🦀..🦄)    crab..unicorn\n\t{0x1F985, 0x1F991, prExtendedPictographic}, //  9.0 [13] (🦅..🦑)    eagle..squid\n\t{0x1F992, 0x1F997, prExtendedPictographic}, // 10.0  [6] (🦒..🦗)    giraffe..cricket\n\t{0x1F998, 0x1F9A2, prExtendedPictographic}, // 11.0 [11] (🦘..🦢)    kangaroo..swan\n\t{0x1F9A3, 0x1F9A4, prExtendedPictographic}, //   NA  [2] (🦣..🦤)    <reserved-1F9A3>..<reserved-1F9A4>\n\t{0x1F9A5, 0x1F9AA, prExtendedPictographic}, // 12.0  [6] (🦥..🦪)    sloth..oyster\n\t{0x1F9AB, 0x1F9AD, prExtendedPictographic}, //   NA  [3] (🦫..🦭)    <reserved-1F9AB>..<reserved-1F9AD>\n\t{0x1F9AE, 0x1F9AF, prExtendedPictographic}, // 12.0  [2] (🦮..🦯)    guide dog..probing cane\n\t{0x1F9B0, 0x1F9B9, prExtendedPictographic}, // 11.0 [10] (🦰..🦹)    red hair..supervillain\n\t{0x1F9BA, 0x1F9BF, prExtendedPictographic}, // 12.0  [6] (🦺..🦿)    safety vest..mechanical leg\n\t{0x1F9C0, 0x1F9C0, prExtendedPictographic}, //  8.0  [1] (🧀)       cheese wedge\n\t{0x1F9C1, 0x1F9C2, prExtendedPictographic}, // 11.0  [2] (🧁..🧂)    cupcake..salt\n\t{0x1F9C3, 0x1F9CA, prExtendedPictographic}, // 12.0  [8] (🧃..🧊)    beverage box..ice cube\n\t{0x1F9CB, 0x1F9CC, prExtendedPictographic}, //   NA  [2] (🧋..🧌)    <reserved-1F9CB>..<reserved-1F9CC>\n\t{0x1F9CD, 0x1F9CF, prExtendedPictographic}, // 12.0  [3] (🧍..🧏)    person standing..deaf person\n\t{0x1F9D0, 0x1F9E6, prExtendedPictographic}, // 10.0 [23] (🧐..🧦)    face with monocle..socks\n\t{0x1F9E7, 0x1F9FF, prExtendedPictographic}, // 11.0 [25] (🧧..🧿)    red envelope..nazar amulet\n\t{0x1FA00, 0x1FA53, prExtendedPictographic}, // 12.0 [84] (🨀..🩓)    NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP\n\t{0x1FA54, 0x1FA5F, prExtendedPictographic}, //   NA [12] (🩔..🩟)    <reserved-1FA54>..<reserved-1FA5F>\n\t{0x1FA60, 0x1FA6D, prExtendedPictographic}, // 11.0 [14] (🩠..🩭)    XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER\n\t{0x1FA6E, 0x1FA6F, prExtendedPictographic}, //   NA  [2] (🩮..🩯)    <reserved-1FA6E>..<reserved-1FA6F>\n\t{0x1FA70, 0x1FA73, prExtendedPictographic}, // 12.0  [4] (🩰..🩳)    ballet shoes..shorts\n\t{0x1FA74, 0x1FA77, prExtendedPictographic}, //   NA  [4] (🩴..🩷)    <reserved-1FA74>..<reserved-1FA77>\n\t{0x1FA78, 0x1FA7A, prExtendedPictographic}, // 12.0  [3] (🩸..🩺)    drop of blood..stethoscope\n\t{0x1FA7B, 0x1FA7F, prExtendedPictographic}, //   NA  [5] (🩻..🩿)    <reserved-1FA7B>..<reserved-1FA7F>\n\t{0x1FA80, 0x1FA82, prExtendedPictographic}, // 12.0  [3] (🪀..🪂)    yo-yo..parachute\n\t{0x1FA83, 0x1FA8F, prExtendedPictographic}, //   NA [13] (🪃..🪏)    <reserved-1FA83>..<reserved-1FA8F>\n\t{0x1FA90, 0x1FA95, prExtendedPictographic}, // 12.0  [6] (🪐..🪕)    ringed planet..banjo\n\t{0x1FA96, 0x1FFFD, prExtendedPictographic}, //   NA[1384] (🪖..🿽)   <reserved-1FA96>..<reserved-1FFFD>\n\t{0xE0000, 0xE0000, prControl},              // Cn       <reserved-E0000>\n\t{0xE0001, 0xE0001, prControl},              // Cf       LANGUAGE TAG\n\t{0xE0002, 0xE001F, prControl},              // Cn  [30] <reserved-E0002>..<reserved-E001F>\n\t{0xE0020, 0xE007F, prExtend},               // Cf  [96] TAG SPACE..CANCEL TAG\n\t{0xE0080, 0xE00FF, prControl},              // Cn [128] <reserved-E0080>..<reserved-E00FF>\n\t{0xE0100, 0xE01EF, prExtend},               // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256\n\t{0xE01F0, 0xE0FFF, prControl},              // Cn [3600] <reserved-E01F0>..<reserved-E0FFF>\n}\n\n// property returns the Unicode property value (see constants above) of the\n// given code point.\nfunc property(r rune) int {\n\t// Run a binary search.\n\tfrom := 0\n\tto := len(codePoints)\n\tfor to > from {\n\t\tmiddle := (from + to) / 2\n\t\tcpRange := codePoints[middle]\n\t\tif int(r) < cpRange[0] {\n\t\t\tto = middle\n\t\t\tcontinue\n\t\t}\n\t\tif int(r) > cpRange[1] {\n\t\t\tfrom = middle + 1\n\t\t\tcontinue\n\t\t}\n\t\treturn cpRange[2]\n\t}\n\treturn prAny\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/.gitignore",
    "content": "*.out\n*.swp\n*.8\n*.6\n_obj\n_test*\nmarkdown\ntags\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/.travis.yml",
    "content": "sudo: false\nlanguage: go\ngo:\n  - \"1.10.x\"\n  - \"1.11.x\"\n  - tip\nmatrix:\n  fast_finish: true\n  allow_failures:\n    - go: tip\ninstall:\n  - # Do nothing. This is needed to prevent default install action \"go get -t -v ./...\" from happening here (we want it to happen inside script step).\nscript:\n  - go get -t -v ./...\n  - diff -u <(echo -n) <(gofmt -d -s .)\n  - go tool vet .\n  - go test -v ./...\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/LICENSE.txt",
    "content": "Blackfriday is distributed under the Simplified BSD License:\n\n> Copyright © 2011 Russ Ross\n> All rights reserved.\n>\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>\n> 1.  Redistributions of source code must retain the above copyright\n>     notice, this list of conditions and the following disclaimer.\n>\n> 2.  Redistributions in binary form must reproduce the above\n>     copyright notice, this list of conditions and the following\n>     disclaimer in the documentation and/or other materials provided with\n>     the distribution.\n>\n> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n> \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n> POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/README.md",
    "content": "Blackfriday\n[![Build Status][BuildV2SVG]][BuildV2URL]\n[![PkgGoDev][PkgGoDevV2SVG]][PkgGoDevV2URL]\n===========\n\nBlackfriday is a [Markdown][1] processor implemented in [Go][2]. It\nis paranoid about its input (so you can safely feed it user-supplied\ndata), it is fast, it supports common extensions (tables, smart\npunctuation substitutions, etc.), and it is safe for all utf-8\n(unicode) input.\n\nHTML output is currently supported, along with Smartypants\nextensions.\n\nIt started as a translation from C of [Sundown][3].\n\n\nInstallation\n------------\n\nBlackfriday is compatible with modern Go releases in module mode.\nWith Go installed:\n\n    go get github.com/russross/blackfriday/v2\n\nwill resolve and add the package to the current development module,\nthen build and install it. Alternatively, you can achieve the same\nif you import it in a package:\n\n    import \"github.com/russross/blackfriday/v2\"\n\nand `go get` without parameters.\n\nLegacy GOPATH mode is unsupported.\n\n\nVersions\n--------\n\nCurrently maintained and recommended version of Blackfriday is `v2`. It's being\ndeveloped on its own branch: https://github.com/russross/blackfriday/tree/v2 and the\ndocumentation is available at\nhttps://pkg.go.dev/github.com/russross/blackfriday/v2.\n\nIt is `go get`-able in module mode at `github.com/russross/blackfriday/v2`.\n\nVersion 2 offers a number of improvements over v1:\n\n* Cleaned up API\n* A separate call to [`Parse`][4], which produces an abstract syntax tree for\n  the document\n* Latest bug fixes\n* Flexibility to easily add your own rendering extensions\n\nPotential drawbacks:\n\n* Our benchmarks show v2 to be slightly slower than v1. Currently in the\n  ballpark of around 15%.\n* API breakage. If you can't afford modifying your code to adhere to the new API\n  and don't care too much about the new features, v2 is probably not for you.\n* Several bug fixes are trailing behind and still need to be forward-ported to\n  v2. See issue [#348](https://github.com/russross/blackfriday/issues/348) for\n  tracking.\n\nIf you are still interested in the legacy `v1`, you can import it from\n`github.com/russross/blackfriday`. Documentation for the legacy v1 can be found\nhere: https://pkg.go.dev/github.com/russross/blackfriday.\n\n\nUsage\n-----\n\nFor the most sensible markdown processing, it is as simple as getting your input\ninto a byte slice and calling:\n\n```go\noutput := blackfriday.Run(input)\n```\n\nYour input will be parsed and the output rendered with a set of most popular\nextensions enabled. If you want the most basic feature set, corresponding with\nthe bare Markdown specification, use:\n\n```go\noutput := blackfriday.Run(input, blackfriday.WithNoExtensions())\n```\n\n### Sanitize untrusted content\n\nBlackfriday itself does nothing to protect against malicious content. If you are\ndealing with user-supplied markdown, we recommend running Blackfriday's output\nthrough HTML sanitizer such as [Bluemonday][5].\n\nHere's an example of simple usage of Blackfriday together with Bluemonday:\n\n```go\nimport (\n    \"github.com/microcosm-cc/bluemonday\"\n    \"github.com/russross/blackfriday/v2\"\n)\n\n// ...\nunsafe := blackfriday.Run(input)\nhtml := bluemonday.UGCPolicy().SanitizeBytes(unsafe)\n```\n\n### Custom options\n\nIf you want to customize the set of options, use `blackfriday.WithExtensions`,\n`blackfriday.WithRenderer` and `blackfriday.WithRefOverride`.\n\n### `blackfriday-tool`\n\nYou can also check out `blackfriday-tool` for a more complete example\nof how to use it. Download and install it using:\n\n    go get github.com/russross/blackfriday-tool\n\nThis is a simple command-line tool that allows you to process a\nmarkdown file using a standalone program.  You can also browse the\nsource directly on github if you are just looking for some example\ncode:\n\n* <https://github.com/russross/blackfriday-tool>\n\nNote that if you have not already done so, installing\n`blackfriday-tool` will be sufficient to download and install\nblackfriday in addition to the tool itself. The tool binary will be\ninstalled in `$GOPATH/bin`.  This is a statically-linked binary that\ncan be copied to wherever you need it without worrying about\ndependencies and library versions.\n\n### Sanitized anchor names\n\nBlackfriday includes an algorithm for creating sanitized anchor names\ncorresponding to a given input text. This algorithm is used to create\nanchors for headings when `AutoHeadingIDs` extension is enabled. The\nalgorithm has a specification, so that other packages can create\ncompatible anchor names and links to those anchors.\n\nThe specification is located at https://pkg.go.dev/github.com/russross/blackfriday/v2#hdr-Sanitized_Anchor_Names.\n\n[`SanitizedAnchorName`](https://pkg.go.dev/github.com/russross/blackfriday/v2#SanitizedAnchorName) exposes this functionality, and can be used to\ncreate compatible links to the anchor names generated by blackfriday.\nThis algorithm is also implemented in a small standalone package at\n[`github.com/shurcooL/sanitized_anchor_name`](https://pkg.go.dev/github.com/shurcooL/sanitized_anchor_name). It can be useful for clients\nthat want a small package and don't need full functionality of blackfriday.\n\n\nFeatures\n--------\n\nAll features of Sundown are supported, including:\n\n*   **Compatibility**. The Markdown v1.0.3 test suite passes with\n    the `--tidy` option.  Without `--tidy`, the differences are\n    mostly in whitespace and entity escaping, where blackfriday is\n    more consistent and cleaner.\n\n*   **Common extensions**, including table support, fenced code\n    blocks, autolinks, strikethroughs, non-strict emphasis, etc.\n\n*   **Safety**. Blackfriday is paranoid when parsing, making it safe\n    to feed untrusted user input without fear of bad things\n    happening. The test suite stress tests this and there are no\n    known inputs that make it crash.  If you find one, please let me\n    know and send me the input that does it.\n\n    NOTE: \"safety\" in this context means *runtime safety only*. In order to\n    protect yourself against JavaScript injection in untrusted content, see\n    [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).\n\n*   **Fast processing**. It is fast enough to render on-demand in\n    most web applications without having to cache the output.\n\n*   **Thread safety**. You can run multiple parsers in different\n    goroutines without ill effect. There is no dependence on global\n    shared state.\n\n*   **Minimal dependencies**. Blackfriday only depends on standard\n    library packages in Go. The source code is pretty\n    self-contained, so it is easy to add to any project, including\n    Google App Engine projects.\n\n*   **Standards compliant**. Output successfully validates using the\n    W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.\n\n\nExtensions\n----------\n\nIn addition to the standard markdown syntax, this package\nimplements the following extensions:\n\n*   **Intra-word emphasis supression**. The `_` character is\n    commonly used inside words when discussing code, so having\n    markdown interpret it as an emphasis command is usually the\n    wrong thing. Blackfriday lets you treat all emphasis markers as\n    normal characters when they occur inside a word.\n\n*   **Tables**. Tables can be created by drawing them in the input\n    using a simple syntax:\n\n    ```\n    Name    | Age\n    --------|------\n    Bob     | 27\n    Alice   | 23\n    ```\n\n*   **Fenced code blocks**. In addition to the normal 4-space\n    indentation to mark code blocks, you can explicitly mark them\n    and supply a language (to make syntax highlighting simple). Just\n    mark it like this:\n\n        ```go\n        func getTrue() bool {\n            return true\n        }\n        ```\n\n    You can use 3 or more backticks to mark the beginning of the\n    block, and the same number to mark the end of the block.\n\n    To preserve classes of fenced code blocks while using the bluemonday\n    HTML sanitizer, use the following policy:\n\n    ```go\n    p := bluemonday.UGCPolicy()\n    p.AllowAttrs(\"class\").Matching(regexp.MustCompile(\"^language-[a-zA-Z0-9]+$\")).OnElements(\"code\")\n    html := p.SanitizeBytes(unsafe)\n    ```\n\n*   **Definition lists**. A simple definition list is made of a single-line\n    term followed by a colon and the definition for that term.\n\n        Cat\n        : Fluffy animal everyone likes\n\n        Internet\n        : Vector of transmission for pictures of cats\n\n    Terms must be separated from the previous definition by a blank line.\n\n*   **Footnotes**. A marker in the text that will become a superscript number;\n    a footnote definition that will be placed in a list of footnotes at the\n    end of the document. A footnote looks like this:\n\n        This is a footnote.[^1]\n\n        [^1]: the footnote text.\n\n*   **Autolinking**. Blackfriday can find URLs that have not been\n    explicitly marked as links and turn them into links.\n\n*   **Strikethrough**. Use two tildes (`~~`) to mark text that\n    should be crossed out.\n\n*   **Hard line breaks**. With this extension enabled newlines in the input\n    translate into line breaks in the output. This extension is off by default.\n\n*   **Smart quotes**. Smartypants-style punctuation substitution is\n    supported, turning normal double- and single-quote marks into\n    curly quotes, etc.\n\n*   **LaTeX-style dash parsing** is an additional option, where `--`\n    is translated into `&ndash;`, and `---` is translated into\n    `&mdash;`. This differs from most smartypants processors, which\n    turn a single hyphen into an ndash and a double hyphen into an\n    mdash.\n\n*   **Smart fractions**, where anything that looks like a fraction\n    is translated into suitable HTML (instead of just a few special\n    cases like most smartypant processors). For example, `4/5`\n    becomes `<sup>4</sup>&frasl;<sub>5</sub>`, which renders as\n    <sup>4</sup>&frasl;<sub>5</sub>.\n\n\nOther renderers\n---------------\n\nBlackfriday is structured to allow alternative rendering engines. Here\nare a few of note:\n\n*   [github_flavored_markdown](https://pkg.go.dev/github.com/shurcooL/github_flavored_markdown):\n    provides a GitHub Flavored Markdown renderer with fenced code block\n    highlighting, clickable heading anchor links.\n\n    It's not customizable, and its goal is to produce HTML output\n    equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode),\n    except the rendering is performed locally.\n\n*   [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,\n    but for markdown.\n\n*   [LaTeX output](https://gitlab.com/ambrevar/blackfriday-latex):\n    renders output as LaTeX.\n\n*   [bfchroma](https://github.com/Depado/bfchroma/): provides convenience\n    integration with the [Chroma](https://github.com/alecthomas/chroma) code\n    highlighting library. bfchroma is only compatible with v2 of Blackfriday and\n    provides a drop-in renderer ready to use with Blackfriday, as well as\n    options and means for further customization.\n\n*   [Blackfriday-Confluence](https://github.com/kentaro-m/blackfriday-confluence): provides a [Confluence Wiki Markup](https://confluence.atlassian.com/doc/confluence-wiki-markup-251003035.html) renderer.\n\n*   [Blackfriday-Slack](https://github.com/karriereat/blackfriday-slack): converts markdown to slack message style\n\n\nTODO\n----\n\n*   More unit testing\n*   Improve Unicode support. It does not understand all Unicode\n    rules (about what constitutes a letter, a punctuation symbol,\n    etc.), so it may fail to detect word boundaries correctly in\n    some instances. It is safe on all UTF-8 input.\n\n\nLicense\n-------\n\n[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt)\n\n\n   [1]: https://daringfireball.net/projects/markdown/ \"Markdown\"\n   [2]: https://golang.org/ \"Go Language\"\n   [3]: https://github.com/vmg/sundown \"Sundown\"\n   [4]: https://pkg.go.dev/github.com/russross/blackfriday/v2#Parse \"Parse func\"\n   [5]: https://github.com/microcosm-cc/bluemonday \"Bluemonday\"\n\n   [BuildV2SVG]: https://travis-ci.org/russross/blackfriday.svg?branch=v2\n   [BuildV2URL]: https://travis-ci.org/russross/blackfriday\n   [PkgGoDevV2SVG]: https://pkg.go.dev/badge/github.com/russross/blackfriday/v2\n   [PkgGoDevV2URL]: https://pkg.go.dev/github.com/russross/blackfriday/v2\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/block.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n// Functions to parse block-level elements.\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"html\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode\"\n)\n\nconst (\n\tcharEntity = \"&(?:#x[a-f0-9]{1,8}|#[0-9]{1,8}|[a-z][a-z0-9]{1,31});\"\n\tescapable  = \"[!\\\"#$%&'()*+,./:;<=>?@[\\\\\\\\\\\\]^_`{|}~-]\"\n)\n\nvar (\n\treBackslashOrAmp      = regexp.MustCompile(\"[\\\\&]\")\n\treEntityOrEscapedChar = regexp.MustCompile(\"(?i)\\\\\\\\\" + escapable + \"|\" + charEntity)\n)\n\n// Parse block-level data.\n// Note: this function and many that it calls assume that\n// the input buffer ends with a newline.\nfunc (p *Markdown) block(data []byte) {\n\t// this is called recursively: enforce a maximum depth\n\tif p.nesting >= p.maxNesting {\n\t\treturn\n\t}\n\tp.nesting++\n\n\t// parse out one block-level construct at a time\n\tfor len(data) > 0 {\n\t\t// prefixed heading:\n\t\t//\n\t\t// # Heading 1\n\t\t// ## Heading 2\n\t\t// ...\n\t\t// ###### Heading 6\n\t\tif p.isPrefixHeading(data) {\n\t\t\tdata = data[p.prefixHeading(data):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// block of preformatted HTML:\n\t\t//\n\t\t// <div>\n\t\t//     ...\n\t\t// </div>\n\t\tif data[0] == '<' {\n\t\t\tif i := p.html(data, true); i > 0 {\n\t\t\t\tdata = data[i:]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// title block\n\t\t//\n\t\t// % stuff\n\t\t// % more stuff\n\t\t// % even more stuff\n\t\tif p.extensions&Titleblock != 0 {\n\t\t\tif data[0] == '%' {\n\t\t\t\tif i := p.titleBlock(data, true); i > 0 {\n\t\t\t\t\tdata = data[i:]\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// blank lines.  note: returns the # of bytes to skip\n\t\tif i := p.isEmpty(data); i > 0 {\n\t\t\tdata = data[i:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// indented code block:\n\t\t//\n\t\t//     func max(a, b int) int {\n\t\t//         if a > b {\n\t\t//             return a\n\t\t//         }\n\t\t//         return b\n\t\t//      }\n\t\tif p.codePrefix(data) > 0 {\n\t\t\tdata = data[p.code(data):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// fenced code block:\n\t\t//\n\t\t// ``` go\n\t\t// func fact(n int) int {\n\t\t//     if n <= 1 {\n\t\t//         return n\n\t\t//     }\n\t\t//     return n * fact(n-1)\n\t\t// }\n\t\t// ```\n\t\tif p.extensions&FencedCode != 0 {\n\t\t\tif i := p.fencedCodeBlock(data, true); i > 0 {\n\t\t\t\tdata = data[i:]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// horizontal rule:\n\t\t//\n\t\t// ------\n\t\t// or\n\t\t// ******\n\t\t// or\n\t\t// ______\n\t\tif p.isHRule(data) {\n\t\t\tp.addBlock(HorizontalRule, nil)\n\t\t\tvar i int\n\t\t\tfor i = 0; i < len(data) && data[i] != '\\n'; i++ {\n\t\t\t}\n\t\t\tdata = data[i:]\n\t\t\tcontinue\n\t\t}\n\n\t\t// block quote:\n\t\t//\n\t\t// > A big quote I found somewhere\n\t\t// > on the web\n\t\tif p.quotePrefix(data) > 0 {\n\t\t\tdata = data[p.quote(data):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// table:\n\t\t//\n\t\t// Name  | Age | Phone\n\t\t// ------|-----|---------\n\t\t// Bob   | 31  | 555-1234\n\t\t// Alice | 27  | 555-4321\n\t\tif p.extensions&Tables != 0 {\n\t\t\tif i := p.table(data); i > 0 {\n\t\t\t\tdata = data[i:]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// an itemized/unordered list:\n\t\t//\n\t\t// * Item 1\n\t\t// * Item 2\n\t\t//\n\t\t// also works with + or -\n\t\tif p.uliPrefix(data) > 0 {\n\t\t\tdata = data[p.list(data, 0):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// a numbered/ordered list:\n\t\t//\n\t\t// 1. Item 1\n\t\t// 2. Item 2\n\t\tif p.oliPrefix(data) > 0 {\n\t\t\tdata = data[p.list(data, ListTypeOrdered):]\n\t\t\tcontinue\n\t\t}\n\n\t\t// definition lists:\n\t\t//\n\t\t// Term 1\n\t\t// :   Definition a\n\t\t// :   Definition b\n\t\t//\n\t\t// Term 2\n\t\t// :   Definition c\n\t\tif p.extensions&DefinitionLists != 0 {\n\t\t\tif p.dliPrefix(data) > 0 {\n\t\t\t\tdata = data[p.list(data, ListTypeDefinition):]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// anything else must look like a normal paragraph\n\t\t// note: this finds underlined headings, too\n\t\tdata = data[p.paragraph(data):]\n\t}\n\n\tp.nesting--\n}\n\nfunc (p *Markdown) addBlock(typ NodeType, content []byte) *Node {\n\tp.closeUnmatchedBlocks()\n\tcontainer := p.addChild(typ, 0)\n\tcontainer.content = content\n\treturn container\n}\n\nfunc (p *Markdown) isPrefixHeading(data []byte) bool {\n\tif data[0] != '#' {\n\t\treturn false\n\t}\n\n\tif p.extensions&SpaceHeadings != 0 {\n\t\tlevel := 0\n\t\tfor level < 6 && level < len(data) && data[level] == '#' {\n\t\t\tlevel++\n\t\t}\n\t\tif level == len(data) || data[level] != ' ' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (p *Markdown) prefixHeading(data []byte) int {\n\tlevel := 0\n\tfor level < 6 && level < len(data) && data[level] == '#' {\n\t\tlevel++\n\t}\n\ti := skipChar(data, level, ' ')\n\tend := skipUntilChar(data, i, '\\n')\n\tskip := end\n\tid := \"\"\n\tif p.extensions&HeadingIDs != 0 {\n\t\tj, k := 0, 0\n\t\t// find start/end of heading id\n\t\tfor j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ {\n\t\t}\n\t\tfor k = j + 1; k < end && data[k] != '}'; k++ {\n\t\t}\n\t\t// extract heading id iff found\n\t\tif j < end && k < end {\n\t\t\tid = string(data[j+2 : k])\n\t\t\tend = j\n\t\t\tskip = k + 1\n\t\t\tfor end > 0 && data[end-1] == ' ' {\n\t\t\t\tend--\n\t\t\t}\n\t\t}\n\t}\n\tfor end > 0 && data[end-1] == '#' {\n\t\tif isBackslashEscaped(data, end-1) {\n\t\t\tbreak\n\t\t}\n\t\tend--\n\t}\n\tfor end > 0 && data[end-1] == ' ' {\n\t\tend--\n\t}\n\tif end > i {\n\t\tif id == \"\" && p.extensions&AutoHeadingIDs != 0 {\n\t\t\tid = SanitizedAnchorName(string(data[i:end]))\n\t\t}\n\t\tblock := p.addBlock(Heading, data[i:end])\n\t\tblock.HeadingID = id\n\t\tblock.Level = level\n\t}\n\treturn skip\n}\n\nfunc (p *Markdown) isUnderlinedHeading(data []byte) int {\n\t// test of level 1 heading\n\tif data[0] == '=' {\n\t\ti := skipChar(data, 1, '=')\n\t\ti = skipChar(data, i, ' ')\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\treturn 1\n\t\t}\n\t\treturn 0\n\t}\n\n\t// test of level 2 heading\n\tif data[0] == '-' {\n\t\ti := skipChar(data, 1, '-')\n\t\ti = skipChar(data, i, ' ')\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\treturn 2\n\t\t}\n\t\treturn 0\n\t}\n\n\treturn 0\n}\n\nfunc (p *Markdown) titleBlock(data []byte, doRender bool) int {\n\tif data[0] != '%' {\n\t\treturn 0\n\t}\n\tsplitData := bytes.Split(data, []byte(\"\\n\"))\n\tvar i int\n\tfor idx, b := range splitData {\n\t\tif !bytes.HasPrefix(b, []byte(\"%\")) {\n\t\t\ti = idx // - 1\n\t\t\tbreak\n\t\t}\n\t}\n\n\tdata = bytes.Join(splitData[0:i], []byte(\"\\n\"))\n\tconsumed := len(data)\n\tdata = bytes.TrimPrefix(data, []byte(\"% \"))\n\tdata = bytes.Replace(data, []byte(\"\\n% \"), []byte(\"\\n\"), -1)\n\tblock := p.addBlock(Heading, data)\n\tblock.Level = 1\n\tblock.IsTitleblock = true\n\n\treturn consumed\n}\n\nfunc (p *Markdown) html(data []byte, doRender bool) int {\n\tvar i, j int\n\n\t// identify the opening tag\n\tif data[0] != '<' {\n\t\treturn 0\n\t}\n\tcurtag, tagfound := p.htmlFindTag(data[1:])\n\n\t// handle special cases\n\tif !tagfound {\n\t\t// check for an HTML comment\n\t\tif size := p.htmlComment(data, doRender); size > 0 {\n\t\t\treturn size\n\t\t}\n\n\t\t// check for an <hr> tag\n\t\tif size := p.htmlHr(data, doRender); size > 0 {\n\t\t\treturn size\n\t\t}\n\n\t\t// no special case recognized\n\t\treturn 0\n\t}\n\n\t// look for an unindented matching closing tag\n\t// followed by a blank line\n\tfound := false\n\t/*\n\t\tclosetag := []byte(\"\\n</\" + curtag + \">\")\n\t\tj = len(curtag) + 1\n\t\tfor !found {\n\t\t\t// scan for a closing tag at the beginning of a line\n\t\t\tif skip := bytes.Index(data[j:], closetag); skip >= 0 {\n\t\t\t\tj += skip + len(closetag)\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// see if it is the only thing on the line\n\t\t\tif skip := p.isEmpty(data[j:]); skip > 0 {\n\t\t\t\t// see if it is followed by a blank line/eof\n\t\t\t\tj += skip\n\t\t\t\tif j >= len(data) {\n\t\t\t\t\tfound = true\n\t\t\t\t\ti = j\n\t\t\t\t} else {\n\t\t\t\t\tif skip := p.isEmpty(data[j:]); skip > 0 {\n\t\t\t\t\t\tj += skip\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t\ti = j\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t*/\n\n\t// if not found, try a second pass looking for indented match\n\t// but not if tag is \"ins\" or \"del\" (following original Markdown.pl)\n\tif !found && curtag != \"ins\" && curtag != \"del\" {\n\t\ti = 1\n\t\tfor i < len(data) {\n\t\t\ti++\n\t\t\tfor i < len(data) && !(data[i-1] == '<' && data[i] == '/') {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\tif i+2+len(curtag) >= len(data) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tj = p.htmlFindEnd(curtag, data[i-1:])\n\n\t\t\tif j > 0 {\n\t\t\t\ti += j - 1\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif !found {\n\t\treturn 0\n\t}\n\n\t// the end of the block has been found\n\tif doRender {\n\t\t// trim newlines\n\t\tend := i\n\t\tfor end > 0 && data[end-1] == '\\n' {\n\t\t\tend--\n\t\t}\n\t\tfinalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))\n\t}\n\n\treturn i\n}\n\nfunc finalizeHTMLBlock(block *Node) {\n\tblock.Literal = block.content\n\tblock.content = nil\n}\n\n// HTML comment, lax form\nfunc (p *Markdown) htmlComment(data []byte, doRender bool) int {\n\ti := p.inlineHTMLComment(data)\n\t// needs to end with a blank line\n\tif j := p.isEmpty(data[i:]); j > 0 {\n\t\tsize := i + j\n\t\tif doRender {\n\t\t\t// trim trailing newlines\n\t\t\tend := size\n\t\t\tfor end > 0 && data[end-1] == '\\n' {\n\t\t\t\tend--\n\t\t\t}\n\t\t\tblock := p.addBlock(HTMLBlock, data[:end])\n\t\t\tfinalizeHTMLBlock(block)\n\t\t}\n\t\treturn size\n\t}\n\treturn 0\n}\n\n// HR, which is the only self-closing block tag considered\nfunc (p *Markdown) htmlHr(data []byte, doRender bool) int {\n\tif len(data) < 4 {\n\t\treturn 0\n\t}\n\tif data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') {\n\t\treturn 0\n\t}\n\tif data[3] != ' ' && data[3] != '/' && data[3] != '>' {\n\t\t// not an <hr> tag after all; at least not a valid one\n\t\treturn 0\n\t}\n\ti := 3\n\tfor i < len(data) && data[i] != '>' && data[i] != '\\n' {\n\t\ti++\n\t}\n\tif i < len(data) && data[i] == '>' {\n\t\ti++\n\t\tif j := p.isEmpty(data[i:]); j > 0 {\n\t\t\tsize := i + j\n\t\t\tif doRender {\n\t\t\t\t// trim newlines\n\t\t\t\tend := size\n\t\t\t\tfor end > 0 && data[end-1] == '\\n' {\n\t\t\t\t\tend--\n\t\t\t\t}\n\t\t\t\tfinalizeHTMLBlock(p.addBlock(HTMLBlock, data[:end]))\n\t\t\t}\n\t\t\treturn size\n\t\t}\n\t}\n\treturn 0\n}\n\nfunc (p *Markdown) htmlFindTag(data []byte) (string, bool) {\n\ti := 0\n\tfor i < len(data) && isalnum(data[i]) {\n\t\ti++\n\t}\n\tkey := string(data[:i])\n\tif _, ok := blockTags[key]; ok {\n\t\treturn key, true\n\t}\n\treturn \"\", false\n}\n\nfunc (p *Markdown) htmlFindEnd(tag string, data []byte) int {\n\t// assume data[0] == '<' && data[1] == '/' already tested\n\tif tag == \"hr\" {\n\t\treturn 2\n\t}\n\t// check if tag is a match\n\tclosetag := []byte(\"</\" + tag + \">\")\n\tif !bytes.HasPrefix(data, closetag) {\n\t\treturn 0\n\t}\n\ti := len(closetag)\n\n\t// check that the rest of the line is blank\n\tskip := 0\n\tif skip = p.isEmpty(data[i:]); skip == 0 {\n\t\treturn 0\n\t}\n\ti += skip\n\tskip = 0\n\n\tif i >= len(data) {\n\t\treturn i\n\t}\n\n\tif p.extensions&LaxHTMLBlocks != 0 {\n\t\treturn i\n\t}\n\tif skip = p.isEmpty(data[i:]); skip == 0 {\n\t\t// following line must be blank\n\t\treturn 0\n\t}\n\n\treturn i + skip\n}\n\nfunc (*Markdown) isEmpty(data []byte) int {\n\t// it is okay to call isEmpty on an empty buffer\n\tif len(data) == 0 {\n\t\treturn 0\n\t}\n\n\tvar i int\n\tfor i = 0; i < len(data) && data[i] != '\\n'; i++ {\n\t\tif data[i] != ' ' && data[i] != '\\t' {\n\t\t\treturn 0\n\t\t}\n\t}\n\tif i < len(data) && data[i] == '\\n' {\n\t\ti++\n\t}\n\treturn i\n}\n\nfunc (*Markdown) isHRule(data []byte) bool {\n\ti := 0\n\n\t// skip up to three spaces\n\tfor i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// look at the hrule char\n\tif data[i] != '*' && data[i] != '-' && data[i] != '_' {\n\t\treturn false\n\t}\n\tc := data[i]\n\n\t// the whole line must be the char or whitespace\n\tn := 0\n\tfor i < len(data) && data[i] != '\\n' {\n\t\tswitch {\n\t\tcase data[i] == c:\n\t\t\tn++\n\t\tcase data[i] != ' ':\n\t\t\treturn false\n\t\t}\n\t\ti++\n\t}\n\n\treturn n >= 3\n}\n\n// isFenceLine checks if there's a fence line (e.g., ``` or ``` go) at the beginning of data,\n// and returns the end index if so, or 0 otherwise. It also returns the marker found.\n// If info is not nil, it gets set to the syntax specified in the fence line.\nfunc isFenceLine(data []byte, info *string, oldmarker string) (end int, marker string) {\n\ti, size := 0, 0\n\n\t// skip up to three spaces\n\tfor i < len(data) && i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// check for the marker characters: ~ or `\n\tif i >= len(data) {\n\t\treturn 0, \"\"\n\t}\n\tif data[i] != '~' && data[i] != '`' {\n\t\treturn 0, \"\"\n\t}\n\n\tc := data[i]\n\n\t// the whole line must be the same char or whitespace\n\tfor i < len(data) && data[i] == c {\n\t\tsize++\n\t\ti++\n\t}\n\n\t// the marker char must occur at least 3 times\n\tif size < 3 {\n\t\treturn 0, \"\"\n\t}\n\tmarker = string(data[i-size : i])\n\n\t// if this is the end marker, it must match the beginning marker\n\tif oldmarker != \"\" && marker != oldmarker {\n\t\treturn 0, \"\"\n\t}\n\n\t// TODO(shurcooL): It's probably a good idea to simplify the 2 code paths here\n\t// into one, always get the info string, and discard it if the caller doesn't care.\n\tif info != nil {\n\t\tinfoLength := 0\n\t\ti = skipChar(data, i, ' ')\n\n\t\tif i >= len(data) {\n\t\t\tif i == len(data) {\n\t\t\t\treturn i, marker\n\t\t\t}\n\t\t\treturn 0, \"\"\n\t\t}\n\n\t\tinfoStart := i\n\n\t\tif data[i] == '{' {\n\t\t\ti++\n\t\t\tinfoStart++\n\n\t\t\tfor i < len(data) && data[i] != '}' && data[i] != '\\n' {\n\t\t\t\tinfoLength++\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\tif i >= len(data) || data[i] != '}' {\n\t\t\t\treturn 0, \"\"\n\t\t\t}\n\n\t\t\t// strip all whitespace at the beginning and the end\n\t\t\t// of the {} block\n\t\t\tfor infoLength > 0 && isspace(data[infoStart]) {\n\t\t\t\tinfoStart++\n\t\t\t\tinfoLength--\n\t\t\t}\n\n\t\t\tfor infoLength > 0 && isspace(data[infoStart+infoLength-1]) {\n\t\t\t\tinfoLength--\n\t\t\t}\n\t\t\ti++\n\t\t\ti = skipChar(data, i, ' ')\n\t\t} else {\n\t\t\tfor i < len(data) && !isverticalspace(data[i]) {\n\t\t\t\tinfoLength++\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\n\t\t*info = strings.TrimSpace(string(data[infoStart : infoStart+infoLength]))\n\t}\n\n\tif i == len(data) {\n\t\treturn i, marker\n\t}\n\tif i > len(data) || data[i] != '\\n' {\n\t\treturn 0, \"\"\n\t}\n\treturn i + 1, marker // Take newline into account.\n}\n\n// fencedCodeBlock returns the end index if data contains a fenced code block at the beginning,\n// or 0 otherwise. It writes to out if doRender is true, otherwise it has no side effects.\n// If doRender is true, a final newline is mandatory to recognize the fenced code block.\nfunc (p *Markdown) fencedCodeBlock(data []byte, doRender bool) int {\n\tvar info string\n\tbeg, marker := isFenceLine(data, &info, \"\")\n\tif beg == 0 || beg >= len(data) {\n\t\treturn 0\n\t}\n\tfenceLength := beg - 1\n\n\tvar work bytes.Buffer\n\twork.Write([]byte(info))\n\twork.WriteByte('\\n')\n\n\tfor {\n\t\t// safe to assume beg < len(data)\n\n\t\t// check for the end of the code block\n\t\tfenceEnd, _ := isFenceLine(data[beg:], nil, marker)\n\t\tif fenceEnd != 0 {\n\t\t\tbeg += fenceEnd\n\t\t\tbreak\n\t\t}\n\n\t\t// copy the current line\n\t\tend := skipUntilChar(data, beg, '\\n') + 1\n\n\t\t// did we reach the end of the buffer without a closing marker?\n\t\tif end >= len(data) {\n\t\t\treturn 0\n\t\t}\n\n\t\t// verbatim copy to the working buffer\n\t\tif doRender {\n\t\t\twork.Write(data[beg:end])\n\t\t}\n\t\tbeg = end\n\t}\n\n\tif doRender {\n\t\tblock := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer\n\t\tblock.IsFenced = true\n\t\tblock.FenceLength = fenceLength\n\t\tfinalizeCodeBlock(block)\n\t}\n\n\treturn beg\n}\n\nfunc unescapeChar(str []byte) []byte {\n\tif str[0] == '\\\\' {\n\t\treturn []byte{str[1]}\n\t}\n\treturn []byte(html.UnescapeString(string(str)))\n}\n\nfunc unescapeString(str []byte) []byte {\n\tif reBackslashOrAmp.Match(str) {\n\t\treturn reEntityOrEscapedChar.ReplaceAllFunc(str, unescapeChar)\n\t}\n\treturn str\n}\n\nfunc finalizeCodeBlock(block *Node) {\n\tif block.IsFenced {\n\t\tnewlinePos := bytes.IndexByte(block.content, '\\n')\n\t\tfirstLine := block.content[:newlinePos]\n\t\trest := block.content[newlinePos+1:]\n\t\tblock.Info = unescapeString(bytes.Trim(firstLine, \"\\n\"))\n\t\tblock.Literal = rest\n\t} else {\n\t\tblock.Literal = block.content\n\t}\n\tblock.content = nil\n}\n\nfunc (p *Markdown) table(data []byte) int {\n\ttable := p.addBlock(Table, nil)\n\ti, columns := p.tableHeader(data)\n\tif i == 0 {\n\t\tp.tip = table.Parent\n\t\ttable.Unlink()\n\t\treturn 0\n\t}\n\n\tp.addBlock(TableBody, nil)\n\n\tfor i < len(data) {\n\t\tpipes, rowStart := 0, i\n\t\tfor ; i < len(data) && data[i] != '\\n'; i++ {\n\t\t\tif data[i] == '|' {\n\t\t\t\tpipes++\n\t\t\t}\n\t\t}\n\n\t\tif pipes == 0 {\n\t\t\ti = rowStart\n\t\t\tbreak\n\t\t}\n\n\t\t// include the newline in data sent to tableRow\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\ti++\n\t\t}\n\t\tp.tableRow(data[rowStart:i], columns, false)\n\t}\n\n\treturn i\n}\n\n// check if the specified position is preceded by an odd number of backslashes\nfunc isBackslashEscaped(data []byte, i int) bool {\n\tbackslashes := 0\n\tfor i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\\\' {\n\t\tbackslashes++\n\t}\n\treturn backslashes&1 == 1\n}\n\nfunc (p *Markdown) tableHeader(data []byte) (size int, columns []CellAlignFlags) {\n\ti := 0\n\tcolCount := 1\n\tfor i = 0; i < len(data) && data[i] != '\\n'; i++ {\n\t\tif data[i] == '|' && !isBackslashEscaped(data, i) {\n\t\t\tcolCount++\n\t\t}\n\t}\n\n\t// doesn't look like a table header\n\tif colCount == 1 {\n\t\treturn\n\t}\n\n\t// include the newline in the data sent to tableRow\n\tj := i\n\tif j < len(data) && data[j] == '\\n' {\n\t\tj++\n\t}\n\theader := data[:j]\n\n\t// column count ignores pipes at beginning or end of line\n\tif data[0] == '|' {\n\t\tcolCount--\n\t}\n\tif i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) {\n\t\tcolCount--\n\t}\n\n\tcolumns = make([]CellAlignFlags, colCount)\n\n\t// move on to the header underline\n\ti++\n\tif i >= len(data) {\n\t\treturn\n\t}\n\n\tif data[i] == '|' && !isBackslashEscaped(data, i) {\n\t\ti++\n\t}\n\ti = skipChar(data, i, ' ')\n\n\t// each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3\n\t// and trailing | optional on last column\n\tcol := 0\n\tfor i < len(data) && data[i] != '\\n' {\n\t\tdashes := 0\n\n\t\tif data[i] == ':' {\n\t\t\ti++\n\t\t\tcolumns[col] |= TableAlignmentLeft\n\t\t\tdashes++\n\t\t}\n\t\tfor i < len(data) && data[i] == '-' {\n\t\t\ti++\n\t\t\tdashes++\n\t\t}\n\t\tif i < len(data) && data[i] == ':' {\n\t\t\ti++\n\t\t\tcolumns[col] |= TableAlignmentRight\n\t\t\tdashes++\n\t\t}\n\t\tfor i < len(data) && data[i] == ' ' {\n\t\t\ti++\n\t\t}\n\t\tif i == len(data) {\n\t\t\treturn\n\t\t}\n\t\t// end of column test is messy\n\t\tswitch {\n\t\tcase dashes < 3:\n\t\t\t// not a valid column\n\t\t\treturn\n\n\t\tcase data[i] == '|' && !isBackslashEscaped(data, i):\n\t\t\t// marker found, now skip past trailing whitespace\n\t\t\tcol++\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] == ' ' {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t\t// trailing junk found after last column\n\t\t\tif col >= colCount && i < len(data) && data[i] != '\\n' {\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:\n\t\t\t// something else found where marker was required\n\t\t\treturn\n\n\t\tcase data[i] == '\\n':\n\t\t\t// marker is optional for the last column\n\t\t\tcol++\n\n\t\tdefault:\n\t\t\t// trailing junk found after last column\n\t\t\treturn\n\t\t}\n\t}\n\tif col != colCount {\n\t\treturn\n\t}\n\n\tp.addBlock(TableHead, nil)\n\tp.tableRow(header, columns, true)\n\tsize = i\n\tif size < len(data) && data[size] == '\\n' {\n\t\tsize++\n\t}\n\treturn\n}\n\nfunc (p *Markdown) tableRow(data []byte, columns []CellAlignFlags, header bool) {\n\tp.addBlock(TableRow, nil)\n\ti, col := 0, 0\n\n\tif data[i] == '|' && !isBackslashEscaped(data, i) {\n\t\ti++\n\t}\n\n\tfor col = 0; col < len(columns) && i < len(data); col++ {\n\t\tfor i < len(data) && data[i] == ' ' {\n\t\t\ti++\n\t\t}\n\n\t\tcellStart := i\n\n\t\tfor i < len(data) && (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\tcellEnd := i\n\n\t\t// skip the end-of-cell marker, possibly taking us past end of buffer\n\t\ti++\n\n\t\tfor cellEnd > cellStart && cellEnd-1 < len(data) && data[cellEnd-1] == ' ' {\n\t\t\tcellEnd--\n\t\t}\n\n\t\tcell := p.addBlock(TableCell, data[cellStart:cellEnd])\n\t\tcell.IsHeader = header\n\t\tcell.Align = columns[col]\n\t}\n\n\t// pad it out with empty columns to get the right number\n\tfor ; col < len(columns); col++ {\n\t\tcell := p.addBlock(TableCell, nil)\n\t\tcell.IsHeader = header\n\t\tcell.Align = columns[col]\n\t}\n\n\t// silently ignore rows with too many cells\n}\n\n// returns blockquote prefix length\nfunc (p *Markdown) quotePrefix(data []byte) int {\n\ti := 0\n\tfor i < 3 && i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\tif i < len(data) && data[i] == '>' {\n\t\tif i+1 < len(data) && data[i+1] == ' ' {\n\t\t\treturn i + 2\n\t\t}\n\t\treturn i + 1\n\t}\n\treturn 0\n}\n\n// blockquote ends with at least one blank line\n// followed by something without a blockquote prefix\nfunc (p *Markdown) terminateBlockquote(data []byte, beg, end int) bool {\n\tif p.isEmpty(data[beg:]) <= 0 {\n\t\treturn false\n\t}\n\tif end >= len(data) {\n\t\treturn true\n\t}\n\treturn p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0\n}\n\n// parse a blockquote fragment\nfunc (p *Markdown) quote(data []byte) int {\n\tblock := p.addBlock(BlockQuote, nil)\n\tvar raw bytes.Buffer\n\tbeg, end := 0, 0\n\tfor beg < len(data) {\n\t\tend = beg\n\t\t// Step over whole lines, collecting them. While doing that, check for\n\t\t// fenced code and if one's found, incorporate it altogether,\n\t\t// irregardless of any contents inside it\n\t\tfor end < len(data) && data[end] != '\\n' {\n\t\t\tif p.extensions&FencedCode != 0 {\n\t\t\t\tif i := p.fencedCodeBlock(data[end:], false); i > 0 {\n\t\t\t\t\t// -1 to compensate for the extra end++ after the loop:\n\t\t\t\t\tend += i - 1\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tend++\n\t\t}\n\t\tif end < len(data) && data[end] == '\\n' {\n\t\t\tend++\n\t\t}\n\t\tif pre := p.quotePrefix(data[beg:]); pre > 0 {\n\t\t\t// skip the prefix\n\t\t\tbeg += pre\n\t\t} else if p.terminateBlockquote(data, beg, end) {\n\t\t\tbreak\n\t\t}\n\t\t// this line is part of the blockquote\n\t\traw.Write(data[beg:end])\n\t\tbeg = end\n\t}\n\tp.block(raw.Bytes())\n\tp.finalize(block)\n\treturn end\n}\n\n// returns prefix length for block code\nfunc (p *Markdown) codePrefix(data []byte) int {\n\tif len(data) >= 1 && data[0] == '\\t' {\n\t\treturn 1\n\t}\n\tif len(data) >= 4 && data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' {\n\t\treturn 4\n\t}\n\treturn 0\n}\n\nfunc (p *Markdown) code(data []byte) int {\n\tvar work bytes.Buffer\n\n\ti := 0\n\tfor i < len(data) {\n\t\tbeg := i\n\t\tfor i < len(data) && data[i] != '\\n' {\n\t\t\ti++\n\t\t}\n\t\tif i < len(data) && data[i] == '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\tblankline := p.isEmpty(data[beg:i]) > 0\n\t\tif pre := p.codePrefix(data[beg:i]); pre > 0 {\n\t\t\tbeg += pre\n\t\t} else if !blankline {\n\t\t\t// non-empty, non-prefixed line breaks the pre\n\t\t\ti = beg\n\t\t\tbreak\n\t\t}\n\n\t\t// verbatim copy to the working buffer\n\t\tif blankline {\n\t\t\twork.WriteByte('\\n')\n\t\t} else {\n\t\t\twork.Write(data[beg:i])\n\t\t}\n\t}\n\n\t// trim all the \\n off the end of work\n\tworkbytes := work.Bytes()\n\teol := len(workbytes)\n\tfor eol > 0 && workbytes[eol-1] == '\\n' {\n\t\teol--\n\t}\n\tif eol != len(workbytes) {\n\t\twork.Truncate(eol)\n\t}\n\n\twork.WriteByte('\\n')\n\n\tblock := p.addBlock(CodeBlock, work.Bytes()) // TODO: get rid of temp buffer\n\tblock.IsFenced = false\n\tfinalizeCodeBlock(block)\n\n\treturn i\n}\n\n// returns unordered list item prefix\nfunc (p *Markdown) uliPrefix(data []byte) int {\n\ti := 0\n\t// start with up to 3 spaces\n\tfor i < len(data) && i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\tif i >= len(data)-1 {\n\t\treturn 0\n\t}\n\t// need one of {'*', '+', '-'} followed by a space or a tab\n\tif (data[i] != '*' && data[i] != '+' && data[i] != '-') ||\n\t\t(data[i+1] != ' ' && data[i+1] != '\\t') {\n\t\treturn 0\n\t}\n\treturn i + 2\n}\n\n// returns ordered list item prefix\nfunc (p *Markdown) oliPrefix(data []byte) int {\n\ti := 0\n\n\t// start with up to 3 spaces\n\tfor i < 3 && i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// count the digits\n\tstart := i\n\tfor i < len(data) && data[i] >= '0' && data[i] <= '9' {\n\t\ti++\n\t}\n\tif start == i || i >= len(data)-1 {\n\t\treturn 0\n\t}\n\n\t// we need >= 1 digits followed by a dot and a space or a tab\n\tif data[i] != '.' || !(data[i+1] == ' ' || data[i+1] == '\\t') {\n\t\treturn 0\n\t}\n\treturn i + 2\n}\n\n// returns definition list item prefix\nfunc (p *Markdown) dliPrefix(data []byte) int {\n\tif len(data) < 2 {\n\t\treturn 0\n\t}\n\ti := 0\n\t// need a ':' followed by a space or a tab\n\tif data[i] != ':' || !(data[i+1] == ' ' || data[i+1] == '\\t') {\n\t\treturn 0\n\t}\n\tfor i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\treturn i + 2\n}\n\n// parse ordered or unordered list block\nfunc (p *Markdown) list(data []byte, flags ListType) int {\n\ti := 0\n\tflags |= ListItemBeginningOfList\n\tblock := p.addBlock(List, nil)\n\tblock.ListFlags = flags\n\tblock.Tight = true\n\n\tfor i < len(data) {\n\t\tskip := p.listItem(data[i:], &flags)\n\t\tif flags&ListItemContainsBlock != 0 {\n\t\t\tblock.ListData.Tight = false\n\t\t}\n\t\ti += skip\n\t\tif skip == 0 || flags&ListItemEndOfList != 0 {\n\t\t\tbreak\n\t\t}\n\t\tflags &= ^ListItemBeginningOfList\n\t}\n\n\tabove := block.Parent\n\tfinalizeList(block)\n\tp.tip = above\n\treturn i\n}\n\n// Returns true if the list item is not the same type as its parent list\nfunc (p *Markdown) listTypeChanged(data []byte, flags *ListType) bool {\n\tif p.dliPrefix(data) > 0 && *flags&ListTypeDefinition == 0 {\n\t\treturn true\n\t} else if p.oliPrefix(data) > 0 && *flags&ListTypeOrdered == 0 {\n\t\treturn true\n\t} else if p.uliPrefix(data) > 0 && (*flags&ListTypeOrdered != 0 || *flags&ListTypeDefinition != 0) {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Returns true if block ends with a blank line, descending if needed\n// into lists and sublists.\nfunc endsWithBlankLine(block *Node) bool {\n\t// TODO: figure this out. Always false now.\n\tfor block != nil {\n\t\t//if block.lastLineBlank {\n\t\t//return true\n\t\t//}\n\t\tt := block.Type\n\t\tif t == List || t == Item {\n\t\t\tblock = block.LastChild\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn false\n}\n\nfunc finalizeList(block *Node) {\n\tblock.open = false\n\titem := block.FirstChild\n\tfor item != nil {\n\t\t// check for non-final list item ending with blank line:\n\t\tif endsWithBlankLine(item) && item.Next != nil {\n\t\t\tblock.ListData.Tight = false\n\t\t\tbreak\n\t\t}\n\t\t// recurse into children of list item, to see if there are spaces\n\t\t// between any of them:\n\t\tsubItem := item.FirstChild\n\t\tfor subItem != nil {\n\t\t\tif endsWithBlankLine(subItem) && (item.Next != nil || subItem.Next != nil) {\n\t\t\t\tblock.ListData.Tight = false\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsubItem = subItem.Next\n\t\t}\n\t\titem = item.Next\n\t}\n}\n\n// Parse a single list item.\n// Assumes initial prefix is already removed if this is a sublist.\nfunc (p *Markdown) listItem(data []byte, flags *ListType) int {\n\t// keep track of the indentation of the first line\n\titemIndent := 0\n\tif data[0] == '\\t' {\n\t\titemIndent += 4\n\t} else {\n\t\tfor itemIndent < 3 && data[itemIndent] == ' ' {\n\t\t\titemIndent++\n\t\t}\n\t}\n\n\tvar bulletChar byte = '*'\n\ti := p.uliPrefix(data)\n\tif i == 0 {\n\t\ti = p.oliPrefix(data)\n\t} else {\n\t\tbulletChar = data[i-2]\n\t}\n\tif i == 0 {\n\t\ti = p.dliPrefix(data)\n\t\t// reset definition term flag\n\t\tif i > 0 {\n\t\t\t*flags &= ^ListTypeTerm\n\t\t}\n\t}\n\tif i == 0 {\n\t\t// if in definition list, set term flag and continue\n\t\tif *flags&ListTypeDefinition != 0 {\n\t\t\t*flags |= ListTypeTerm\n\t\t} else {\n\t\t\treturn 0\n\t\t}\n\t}\n\n\t// skip leading whitespace on first line\n\tfor i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\n\t// find the end of the line\n\tline := i\n\tfor i > 0 && i < len(data) && data[i-1] != '\\n' {\n\t\ti++\n\t}\n\n\t// get working buffer\n\tvar raw bytes.Buffer\n\n\t// put the first line into the working buffer\n\traw.Write(data[line:i])\n\tline = i\n\n\t// process the following lines\n\tcontainsBlankLine := false\n\tsublist := 0\n\tcodeBlockMarker := \"\"\n\ngatherlines:\n\tfor line < len(data) {\n\t\ti++\n\n\t\t// find the end of this line\n\t\tfor i < len(data) && data[i-1] != '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\t// if it is an empty line, guess that it is part of this item\n\t\t// and move on to the next line\n\t\tif p.isEmpty(data[line:i]) > 0 {\n\t\t\tcontainsBlankLine = true\n\t\t\tline = i\n\t\t\tcontinue\n\t\t}\n\n\t\t// calculate the indentation\n\t\tindent := 0\n\t\tindentIndex := 0\n\t\tif data[line] == '\\t' {\n\t\t\tindentIndex++\n\t\t\tindent += 4\n\t\t} else {\n\t\t\tfor indent < 4 && line+indent < i && data[line+indent] == ' ' {\n\t\t\t\tindent++\n\t\t\t\tindentIndex++\n\t\t\t}\n\t\t}\n\n\t\tchunk := data[line+indentIndex : i]\n\n\t\tif p.extensions&FencedCode != 0 {\n\t\t\t// determine if in or out of codeblock\n\t\t\t// if in codeblock, ignore normal list processing\n\t\t\t_, marker := isFenceLine(chunk, nil, codeBlockMarker)\n\t\t\tif marker != \"\" {\n\t\t\t\tif codeBlockMarker == \"\" {\n\t\t\t\t\t// start of codeblock\n\t\t\t\t\tcodeBlockMarker = marker\n\t\t\t\t} else {\n\t\t\t\t\t// end of codeblock.\n\t\t\t\t\tcodeBlockMarker = \"\"\n\t\t\t\t}\n\t\t\t}\n\t\t\t// we are in a codeblock, write line, and continue\n\t\t\tif codeBlockMarker != \"\" || marker != \"\" {\n\t\t\t\traw.Write(data[line+indentIndex : i])\n\t\t\t\tline = i\n\t\t\t\tcontinue gatherlines\n\t\t\t}\n\t\t}\n\n\t\t// evaluate how this line fits in\n\t\tswitch {\n\t\t// is this a nested list item?\n\t\tcase (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) ||\n\t\t\tp.oliPrefix(chunk) > 0 ||\n\t\t\tp.dliPrefix(chunk) > 0:\n\n\t\t\t// to be a nested list, it must be indented more\n\t\t\t// if not, it is either a different kind of list\n\t\t\t// or the next item in the same list\n\t\t\tif indent <= itemIndent {\n\t\t\t\tif p.listTypeChanged(chunk, flags) {\n\t\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t\t} else if containsBlankLine {\n\t\t\t\t\t*flags |= ListItemContainsBlock\n\t\t\t\t}\n\n\t\t\t\tbreak gatherlines\n\t\t\t}\n\n\t\t\tif containsBlankLine {\n\t\t\t\t*flags |= ListItemContainsBlock\n\t\t\t}\n\n\t\t\t// is this the first item in the nested list?\n\t\t\tif sublist == 0 {\n\t\t\t\tsublist = raw.Len()\n\t\t\t}\n\n\t\t// is this a nested prefix heading?\n\t\tcase p.isPrefixHeading(chunk):\n\t\t\t// if the heading is not indented, it is not nested in the list\n\t\t\t// and thus ends the list\n\t\t\tif containsBlankLine && indent < 4 {\n\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t\tbreak gatherlines\n\t\t\t}\n\t\t\t*flags |= ListItemContainsBlock\n\n\t\t// anything following an empty line is only part\n\t\t// of this item if it is indented 4 spaces\n\t\t// (regardless of the indentation of the beginning of the item)\n\t\tcase containsBlankLine && indent < 4:\n\t\t\tif *flags&ListTypeDefinition != 0 && i < len(data)-1 {\n\t\t\t\t// is the next item still a part of this list?\n\t\t\t\tnext := i\n\t\t\t\tfor next < len(data) && data[next] != '\\n' {\n\t\t\t\t\tnext++\n\t\t\t\t}\n\t\t\t\tfor next < len(data)-1 && data[next] == '\\n' {\n\t\t\t\t\tnext++\n\t\t\t\t}\n\t\t\t\tif i < len(data)-1 && data[i] != ':' && data[next] != ':' {\n\t\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t*flags |= ListItemEndOfList\n\t\t\t}\n\t\t\tbreak gatherlines\n\n\t\t// a blank line means this should be parsed as a block\n\t\tcase containsBlankLine:\n\t\t\traw.WriteByte('\\n')\n\t\t\t*flags |= ListItemContainsBlock\n\t\t}\n\n\t\t// if this line was preceded by one or more blanks,\n\t\t// re-introduce the blank into the buffer\n\t\tif containsBlankLine {\n\t\t\tcontainsBlankLine = false\n\t\t\traw.WriteByte('\\n')\n\t\t}\n\n\t\t// add the line into the working buffer without prefix\n\t\traw.Write(data[line+indentIndex : i])\n\n\t\tline = i\n\t}\n\n\trawBytes := raw.Bytes()\n\n\tblock := p.addBlock(Item, nil)\n\tblock.ListFlags = *flags\n\tblock.Tight = false\n\tblock.BulletChar = bulletChar\n\tblock.Delimiter = '.' // Only '.' is possible in Markdown, but ')' will also be possible in CommonMark\n\n\t// render the contents of the list item\n\tif *flags&ListItemContainsBlock != 0 && *flags&ListTypeTerm == 0 {\n\t\t// intermediate render of block item, except for definition term\n\t\tif sublist > 0 {\n\t\t\tp.block(rawBytes[:sublist])\n\t\t\tp.block(rawBytes[sublist:])\n\t\t} else {\n\t\t\tp.block(rawBytes)\n\t\t}\n\t} else {\n\t\t// intermediate render of inline item\n\t\tif sublist > 0 {\n\t\t\tchild := p.addChild(Paragraph, 0)\n\t\t\tchild.content = rawBytes[:sublist]\n\t\t\tp.block(rawBytes[sublist:])\n\t\t} else {\n\t\t\tchild := p.addChild(Paragraph, 0)\n\t\t\tchild.content = rawBytes\n\t\t}\n\t}\n\treturn line\n}\n\n// render a single paragraph that has already been parsed out\nfunc (p *Markdown) renderParagraph(data []byte) {\n\tif len(data) == 0 {\n\t\treturn\n\t}\n\n\t// trim leading spaces\n\tbeg := 0\n\tfor data[beg] == ' ' {\n\t\tbeg++\n\t}\n\n\tend := len(data)\n\t// trim trailing newline\n\tif data[len(data)-1] == '\\n' {\n\t\tend--\n\t}\n\n\t// trim trailing spaces\n\tfor end > beg && data[end-1] == ' ' {\n\t\tend--\n\t}\n\n\tp.addBlock(Paragraph, data[beg:end])\n}\n\nfunc (p *Markdown) paragraph(data []byte) int {\n\t// prev: index of 1st char of previous line\n\t// line: index of 1st char of current line\n\t// i: index of cursor/end of current line\n\tvar prev, line, i int\n\ttabSize := TabSizeDefault\n\tif p.extensions&TabSizeEight != 0 {\n\t\ttabSize = TabSizeDouble\n\t}\n\t// keep going until we find something to mark the end of the paragraph\n\tfor i < len(data) {\n\t\t// mark the beginning of the current line\n\t\tprev = line\n\t\tcurrent := data[i:]\n\t\tline = i\n\n\t\t// did we find a reference or a footnote? If so, end a paragraph\n\t\t// preceding it and report that we have consumed up to the end of that\n\t\t// reference:\n\t\tif refEnd := isReference(p, current, tabSize); refEnd > 0 {\n\t\t\tp.renderParagraph(data[:i])\n\t\t\treturn i + refEnd\n\t\t}\n\n\t\t// did we find a blank line marking the end of the paragraph?\n\t\tif n := p.isEmpty(current); n > 0 {\n\t\t\t// did this blank line followed by a definition list item?\n\t\t\tif p.extensions&DefinitionLists != 0 {\n\t\t\t\tif i < len(data)-1 && data[i+1] == ':' {\n\t\t\t\t\treturn p.list(data[prev:], ListTypeDefinition)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.renderParagraph(data[:i])\n\t\t\treturn i + n\n\t\t}\n\n\t\t// an underline under some text marks a heading, so our paragraph ended on prev line\n\t\tif i > 0 {\n\t\t\tif level := p.isUnderlinedHeading(current); level > 0 {\n\t\t\t\t// render the paragraph\n\t\t\t\tp.renderParagraph(data[:prev])\n\n\t\t\t\t// ignore leading and trailing whitespace\n\t\t\t\teol := i - 1\n\t\t\t\tfor prev < eol && data[prev] == ' ' {\n\t\t\t\t\tprev++\n\t\t\t\t}\n\t\t\t\tfor eol > prev && data[eol-1] == ' ' {\n\t\t\t\t\teol--\n\t\t\t\t}\n\n\t\t\t\tid := \"\"\n\t\t\t\tif p.extensions&AutoHeadingIDs != 0 {\n\t\t\t\t\tid = SanitizedAnchorName(string(data[prev:eol]))\n\t\t\t\t}\n\n\t\t\t\tblock := p.addBlock(Heading, data[prev:eol])\n\t\t\t\tblock.Level = level\n\t\t\t\tblock.HeadingID = id\n\n\t\t\t\t// find the end of the underline\n\t\t\t\tfor i < len(data) && data[i] != '\\n' {\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// if the next line starts a block of HTML, then the paragraph ends here\n\t\tif p.extensions&LaxHTMLBlocks != 0 {\n\t\t\tif data[i] == '<' && p.html(current, false) > 0 {\n\t\t\t\t// rewind to before the HTML block\n\t\t\t\tp.renderParagraph(data[:i])\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// if there's a prefixed heading or a horizontal rule after this, paragraph is over\n\t\tif p.isPrefixHeading(current) || p.isHRule(current) {\n\t\t\tp.renderParagraph(data[:i])\n\t\t\treturn i\n\t\t}\n\n\t\t// if there's a fenced code block, paragraph is over\n\t\tif p.extensions&FencedCode != 0 {\n\t\t\tif p.fencedCodeBlock(current, false) > 0 {\n\t\t\t\tp.renderParagraph(data[:i])\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// if there's a definition list item, prev line is a definition term\n\t\tif p.extensions&DefinitionLists != 0 {\n\t\t\tif p.dliPrefix(current) != 0 {\n\t\t\t\tret := p.list(data[prev:], ListTypeDefinition)\n\t\t\t\treturn ret\n\t\t\t}\n\t\t}\n\n\t\t// if there's a list after this, paragraph is over\n\t\tif p.extensions&NoEmptyLineBeforeBlock != 0 {\n\t\t\tif p.uliPrefix(current) != 0 ||\n\t\t\t\tp.oliPrefix(current) != 0 ||\n\t\t\t\tp.quotePrefix(current) != 0 ||\n\t\t\t\tp.codePrefix(current) != 0 {\n\t\t\t\tp.renderParagraph(data[:i])\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\n\t\t// otherwise, scan to the beginning of the next line\n\t\tnl := bytes.IndexByte(data[i:], '\\n')\n\t\tif nl >= 0 {\n\t\t\ti += nl + 1\n\t\t} else {\n\t\t\ti += len(data[i:])\n\t\t}\n\t}\n\n\tp.renderParagraph(data[:i])\n\treturn i\n}\n\nfunc skipChar(data []byte, start int, char byte) int {\n\ti := start\n\tfor i < len(data) && data[i] == char {\n\t\ti++\n\t}\n\treturn i\n}\n\nfunc skipUntilChar(text []byte, start int, char byte) int {\n\ti := start\n\tfor i < len(text) && text[i] != char {\n\t\ti++\n\t}\n\treturn i\n}\n\n// SanitizedAnchorName returns a sanitized anchor name for the given text.\n//\n// It implements the algorithm specified in the package comment.\nfunc SanitizedAnchorName(text string) string {\n\tvar anchorName []rune\n\tfutureDash := false\n\tfor _, r := range text {\n\t\tswitch {\n\t\tcase unicode.IsLetter(r) || unicode.IsNumber(r):\n\t\t\tif futureDash && len(anchorName) > 0 {\n\t\t\t\tanchorName = append(anchorName, '-')\n\t\t\t}\n\t\t\tfutureDash = false\n\t\t\tanchorName = append(anchorName, unicode.ToLower(r))\n\t\tdefault:\n\t\t\tfutureDash = true\n\t\t}\n\t}\n\treturn string(anchorName)\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/doc.go",
    "content": "// Package blackfriday is a markdown processor.\n//\n// It translates plain text with simple formatting rules into an AST, which can\n// then be further processed to HTML (provided by Blackfriday itself) or other\n// formats (provided by the community).\n//\n// The simplest way to invoke Blackfriday is to call the Run function. It will\n// take a text input and produce a text output in HTML (or other format).\n//\n// A slightly more sophisticated way to use Blackfriday is to create a Markdown\n// processor and to call Parse, which returns a syntax tree for the input\n// document. You can leverage Blackfriday's parsing for content extraction from\n// markdown documents. You can assign a custom renderer and set various options\n// to the Markdown processor.\n//\n// If you're interested in calling Blackfriday from command line, see\n// https://github.com/russross/blackfriday-tool.\n//\n// Sanitized Anchor Names\n//\n// Blackfriday includes an algorithm for creating sanitized anchor names\n// corresponding to a given input text. This algorithm is used to create\n// anchors for headings when AutoHeadingIDs extension is enabled. The\n// algorithm is specified below, so that other packages can create\n// compatible anchor names and links to those anchors.\n//\n// The algorithm iterates over the input text, interpreted as UTF-8,\n// one Unicode code point (rune) at a time. All runes that are letters (category L)\n// or numbers (category N) are considered valid characters. They are mapped to\n// lower case, and included in the output. All other runes are considered\n// invalid characters. Invalid characters that precede the first valid character,\n// as well as invalid character that follow the last valid character\n// are dropped completely. All other sequences of invalid characters\n// between two valid characters are replaced with a single dash character '-'.\n//\n// SanitizedAnchorName exposes this functionality, and can be used to\n// create compatible links to the anchor names generated by blackfriday.\n// This algorithm is also implemented in a small standalone package at\n// github.com/shurcooL/sanitized_anchor_name. It can be useful for clients\n// that want a small package and don't need full functionality of blackfriday.\npackage blackfriday\n\n// NOTE: Keep Sanitized Anchor Name algorithm in sync with package\n//       github.com/shurcooL/sanitized_anchor_name.\n//       Otherwise, users of sanitized_anchor_name will get anchor names\n//       that are incompatible with those generated by blackfriday.\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/entities.go",
    "content": "package blackfriday\n\n// Extracted from https://html.spec.whatwg.org/multipage/entities.json\nvar entities = map[string]bool{\n\t\"&AElig\":                            true,\n\t\"&AElig;\":                           true,\n\t\"&AMP\":                              true,\n\t\"&AMP;\":                             true,\n\t\"&Aacute\":                           true,\n\t\"&Aacute;\":                          true,\n\t\"&Abreve;\":                          true,\n\t\"&Acirc\":                            true,\n\t\"&Acirc;\":                           true,\n\t\"&Acy;\":                             true,\n\t\"&Afr;\":                             true,\n\t\"&Agrave\":                           true,\n\t\"&Agrave;\":                          true,\n\t\"&Alpha;\":                           true,\n\t\"&Amacr;\":                           true,\n\t\"&And;\":                             true,\n\t\"&Aogon;\":                           true,\n\t\"&Aopf;\":                            true,\n\t\"&ApplyFunction;\":                   true,\n\t\"&Aring\":                            true,\n\t\"&Aring;\":                           true,\n\t\"&Ascr;\":                            true,\n\t\"&Assign;\":                          true,\n\t\"&Atilde\":                           true,\n\t\"&Atilde;\":                          true,\n\t\"&Auml\":                             true,\n\t\"&Auml;\":                            true,\n\t\"&Backslash;\":                       true,\n\t\"&Barv;\":                            true,\n\t\"&Barwed;\":                          true,\n\t\"&Bcy;\":                             true,\n\t\"&Because;\":                         true,\n\t\"&Bernoullis;\":                      true,\n\t\"&Beta;\":                            true,\n\t\"&Bfr;\":                             true,\n\t\"&Bopf;\":                            true,\n\t\"&Breve;\":                           true,\n\t\"&Bscr;\":                            true,\n\t\"&Bumpeq;\":                          true,\n\t\"&CHcy;\":                            true,\n\t\"&COPY\":                             true,\n\t\"&COPY;\":                            true,\n\t\"&Cacute;\":                          true,\n\t\"&Cap;\":                             true,\n\t\"&CapitalDifferentialD;\":            true,\n\t\"&Cayleys;\":                         true,\n\t\"&Ccaron;\":                          true,\n\t\"&Ccedil\":                           true,\n\t\"&Ccedil;\":                          true,\n\t\"&Ccirc;\":                           true,\n\t\"&Cconint;\":                         true,\n\t\"&Cdot;\":                            true,\n\t\"&Cedilla;\":                         true,\n\t\"&CenterDot;\":                       true,\n\t\"&Cfr;\":                             true,\n\t\"&Chi;\":                             true,\n\t\"&CircleDot;\":                       true,\n\t\"&CircleMinus;\":                     true,\n\t\"&CirclePlus;\":                      true,\n\t\"&CircleTimes;\":                     true,\n\t\"&ClockwiseContourIntegral;\":        true,\n\t\"&CloseCurlyDoubleQuote;\":           true,\n\t\"&CloseCurlyQuote;\":                 true,\n\t\"&Colon;\":                           true,\n\t\"&Colone;\":                          true,\n\t\"&Congruent;\":                       true,\n\t\"&Conint;\":                          true,\n\t\"&ContourIntegral;\":                 true,\n\t\"&Copf;\":                            true,\n\t\"&Coproduct;\":                       true,\n\t\"&CounterClockwiseContourIntegral;\": true,\n\t\"&Cross;\":                           true,\n\t\"&Cscr;\":                            true,\n\t\"&Cup;\":                             true,\n\t\"&CupCap;\":                          true,\n\t\"&DD;\":                              true,\n\t\"&DDotrahd;\":                        true,\n\t\"&DJcy;\":                            true,\n\t\"&DScy;\":                            true,\n\t\"&DZcy;\":                            true,\n\t\"&Dagger;\":                          true,\n\t\"&Darr;\":                            true,\n\t\"&Dashv;\":                           true,\n\t\"&Dcaron;\":                          true,\n\t\"&Dcy;\":                             true,\n\t\"&Del;\":                             true,\n\t\"&Delta;\":                           true,\n\t\"&Dfr;\":                             true,\n\t\"&DiacriticalAcute;\":                true,\n\t\"&DiacriticalDot;\":                  true,\n\t\"&DiacriticalDoubleAcute;\":          true,\n\t\"&DiacriticalGrave;\":                true,\n\t\"&DiacriticalTilde;\":                true,\n\t\"&Diamond;\":                         true,\n\t\"&DifferentialD;\":                   true,\n\t\"&Dopf;\":                            true,\n\t\"&Dot;\":                             true,\n\t\"&DotDot;\":                          true,\n\t\"&DotEqual;\":                        true,\n\t\"&DoubleContourIntegral;\":           true,\n\t\"&DoubleDot;\":                       true,\n\t\"&DoubleDownArrow;\":                 true,\n\t\"&DoubleLeftArrow;\":                 true,\n\t\"&DoubleLeftRightArrow;\":            true,\n\t\"&DoubleLeftTee;\":                   true,\n\t\"&DoubleLongLeftArrow;\":             true,\n\t\"&DoubleLongLeftRightArrow;\":        true,\n\t\"&DoubleLongRightArrow;\":            true,\n\t\"&DoubleRightArrow;\":                true,\n\t\"&DoubleRightTee;\":                  true,\n\t\"&DoubleUpArrow;\":                   true,\n\t\"&DoubleUpDownArrow;\":               true,\n\t\"&DoubleVerticalBar;\":               true,\n\t\"&DownArrow;\":                       true,\n\t\"&DownArrowBar;\":                    true,\n\t\"&DownArrowUpArrow;\":                true,\n\t\"&DownBreve;\":                       true,\n\t\"&DownLeftRightVector;\":             true,\n\t\"&DownLeftTeeVector;\":               true,\n\t\"&DownLeftVector;\":                  true,\n\t\"&DownLeftVectorBar;\":               true,\n\t\"&DownRightTeeVector;\":              true,\n\t\"&DownRightVector;\":                 true,\n\t\"&DownRightVectorBar;\":              true,\n\t\"&DownTee;\":                         true,\n\t\"&DownTeeArrow;\":                    true,\n\t\"&Downarrow;\":                       true,\n\t\"&Dscr;\":                            true,\n\t\"&Dstrok;\":                          true,\n\t\"&ENG;\":                             true,\n\t\"&ETH\":                              true,\n\t\"&ETH;\":                             true,\n\t\"&Eacute\":                           true,\n\t\"&Eacute;\":                          true,\n\t\"&Ecaron;\":                          true,\n\t\"&Ecirc\":                            true,\n\t\"&Ecirc;\":                           true,\n\t\"&Ecy;\":                             true,\n\t\"&Edot;\":                            true,\n\t\"&Efr;\":                             true,\n\t\"&Egrave\":                           true,\n\t\"&Egrave;\":                          true,\n\t\"&Element;\":                         true,\n\t\"&Emacr;\":                           true,\n\t\"&EmptySmallSquare;\":                true,\n\t\"&EmptyVerySmallSquare;\":            true,\n\t\"&Eogon;\":                           true,\n\t\"&Eopf;\":                            true,\n\t\"&Epsilon;\":                         true,\n\t\"&Equal;\":                           true,\n\t\"&EqualTilde;\":                      true,\n\t\"&Equilibrium;\":                     true,\n\t\"&Escr;\":                            true,\n\t\"&Esim;\":                            true,\n\t\"&Eta;\":                             true,\n\t\"&Euml\":                             true,\n\t\"&Euml;\":                            true,\n\t\"&Exists;\":                          true,\n\t\"&ExponentialE;\":                    true,\n\t\"&Fcy;\":                             true,\n\t\"&Ffr;\":                             true,\n\t\"&FilledSmallSquare;\":               true,\n\t\"&FilledVerySmallSquare;\":           true,\n\t\"&Fopf;\":                            true,\n\t\"&ForAll;\":                          true,\n\t\"&Fouriertrf;\":                      true,\n\t\"&Fscr;\":                            true,\n\t\"&GJcy;\":                            true,\n\t\"&GT\":                               true,\n\t\"&GT;\":                              true,\n\t\"&Gamma;\":                           true,\n\t\"&Gammad;\":                          true,\n\t\"&Gbreve;\":                          true,\n\t\"&Gcedil;\":                          true,\n\t\"&Gcirc;\":                           true,\n\t\"&Gcy;\":                             true,\n\t\"&Gdot;\":                            true,\n\t\"&Gfr;\":                             true,\n\t\"&Gg;\":                              true,\n\t\"&Gopf;\":                            true,\n\t\"&GreaterEqual;\":                    true,\n\t\"&GreaterEqualLess;\":                true,\n\t\"&GreaterFullEqual;\":                true,\n\t\"&GreaterGreater;\":                  true,\n\t\"&GreaterLess;\":                     true,\n\t\"&GreaterSlantEqual;\":               true,\n\t\"&GreaterTilde;\":                    true,\n\t\"&Gscr;\":                            true,\n\t\"&Gt;\":                              true,\n\t\"&HARDcy;\":                          true,\n\t\"&Hacek;\":                           true,\n\t\"&Hat;\":                             true,\n\t\"&Hcirc;\":                           true,\n\t\"&Hfr;\":                             true,\n\t\"&HilbertSpace;\":                    true,\n\t\"&Hopf;\":                            true,\n\t\"&HorizontalLine;\":                  true,\n\t\"&Hscr;\":                            true,\n\t\"&Hstrok;\":                          true,\n\t\"&HumpDownHump;\":                    true,\n\t\"&HumpEqual;\":                       true,\n\t\"&IEcy;\":                            true,\n\t\"&IJlig;\":                           true,\n\t\"&IOcy;\":                            true,\n\t\"&Iacute\":                           true,\n\t\"&Iacute;\":                          true,\n\t\"&Icirc\":                            true,\n\t\"&Icirc;\":                           true,\n\t\"&Icy;\":                             true,\n\t\"&Idot;\":                            true,\n\t\"&Ifr;\":                             true,\n\t\"&Igrave\":                           true,\n\t\"&Igrave;\":                          true,\n\t\"&Im;\":                              true,\n\t\"&Imacr;\":                           true,\n\t\"&ImaginaryI;\":                      true,\n\t\"&Implies;\":                         true,\n\t\"&Int;\":                             true,\n\t\"&Integral;\":                        true,\n\t\"&Intersection;\":                    true,\n\t\"&InvisibleComma;\":                  true,\n\t\"&InvisibleTimes;\":                  true,\n\t\"&Iogon;\":                           true,\n\t\"&Iopf;\":                            true,\n\t\"&Iota;\":                            true,\n\t\"&Iscr;\":                            true,\n\t\"&Itilde;\":                          true,\n\t\"&Iukcy;\":                           true,\n\t\"&Iuml\":                             true,\n\t\"&Iuml;\":                            true,\n\t\"&Jcirc;\":                           true,\n\t\"&Jcy;\":                             true,\n\t\"&Jfr;\":                             true,\n\t\"&Jopf;\":                            true,\n\t\"&Jscr;\":                            true,\n\t\"&Jsercy;\":                          true,\n\t\"&Jukcy;\":                           true,\n\t\"&KHcy;\":                            true,\n\t\"&KJcy;\":                            true,\n\t\"&Kappa;\":                           true,\n\t\"&Kcedil;\":                          true,\n\t\"&Kcy;\":                             true,\n\t\"&Kfr;\":                             true,\n\t\"&Kopf;\":                            true,\n\t\"&Kscr;\":                            true,\n\t\"&LJcy;\":                            true,\n\t\"&LT\":                               true,\n\t\"&LT;\":                              true,\n\t\"&Lacute;\":                          true,\n\t\"&Lambda;\":                          true,\n\t\"&Lang;\":                            true,\n\t\"&Laplacetrf;\":                      true,\n\t\"&Larr;\":                            true,\n\t\"&Lcaron;\":                          true,\n\t\"&Lcedil;\":                          true,\n\t\"&Lcy;\":                             true,\n\t\"&LeftAngleBracket;\":                true,\n\t\"&LeftArrow;\":                       true,\n\t\"&LeftArrowBar;\":                    true,\n\t\"&LeftArrowRightArrow;\":             true,\n\t\"&LeftCeiling;\":                     true,\n\t\"&LeftDoubleBracket;\":               true,\n\t\"&LeftDownTeeVector;\":               true,\n\t\"&LeftDownVector;\":                  true,\n\t\"&LeftDownVectorBar;\":               true,\n\t\"&LeftFloor;\":                       true,\n\t\"&LeftRightArrow;\":                  true,\n\t\"&LeftRightVector;\":                 true,\n\t\"&LeftTee;\":                         true,\n\t\"&LeftTeeArrow;\":                    true,\n\t\"&LeftTeeVector;\":                   true,\n\t\"&LeftTriangle;\":                    true,\n\t\"&LeftTriangleBar;\":                 true,\n\t\"&LeftTriangleEqual;\":               true,\n\t\"&LeftUpDownVector;\":                true,\n\t\"&LeftUpTeeVector;\":                 true,\n\t\"&LeftUpVector;\":                    true,\n\t\"&LeftUpVectorBar;\":                 true,\n\t\"&LeftVector;\":                      true,\n\t\"&LeftVectorBar;\":                   true,\n\t\"&Leftarrow;\":                       true,\n\t\"&Leftrightarrow;\":                  true,\n\t\"&LessEqualGreater;\":                true,\n\t\"&LessFullEqual;\":                   true,\n\t\"&LessGreater;\":                     true,\n\t\"&LessLess;\":                        true,\n\t\"&LessSlantEqual;\":                  true,\n\t\"&LessTilde;\":                       true,\n\t\"&Lfr;\":                             true,\n\t\"&Ll;\":                              true,\n\t\"&Lleftarrow;\":                      true,\n\t\"&Lmidot;\":                          true,\n\t\"&LongLeftArrow;\":                   true,\n\t\"&LongLeftRightArrow;\":              true,\n\t\"&LongRightArrow;\":                  true,\n\t\"&Longleftarrow;\":                   true,\n\t\"&Longleftrightarrow;\":              true,\n\t\"&Longrightarrow;\":                  true,\n\t\"&Lopf;\":                            true,\n\t\"&LowerLeftArrow;\":                  true,\n\t\"&LowerRightArrow;\":                 true,\n\t\"&Lscr;\":                            true,\n\t\"&Lsh;\":                             true,\n\t\"&Lstrok;\":                          true,\n\t\"&Lt;\":                              true,\n\t\"&Map;\":                             true,\n\t\"&Mcy;\":                             true,\n\t\"&MediumSpace;\":                     true,\n\t\"&Mellintrf;\":                       true,\n\t\"&Mfr;\":                             true,\n\t\"&MinusPlus;\":                       true,\n\t\"&Mopf;\":                            true,\n\t\"&Mscr;\":                            true,\n\t\"&Mu;\":                              true,\n\t\"&NJcy;\":                            true,\n\t\"&Nacute;\":                          true,\n\t\"&Ncaron;\":                          true,\n\t\"&Ncedil;\":                          true,\n\t\"&Ncy;\":                             true,\n\t\"&NegativeMediumSpace;\":             true,\n\t\"&NegativeThickSpace;\":              true,\n\t\"&NegativeThinSpace;\":               true,\n\t\"&NegativeVeryThinSpace;\":           true,\n\t\"&NestedGreaterGreater;\":            true,\n\t\"&NestedLessLess;\":                  true,\n\t\"&NewLine;\":                         true,\n\t\"&Nfr;\":                             true,\n\t\"&NoBreak;\":                         true,\n\t\"&NonBreakingSpace;\":                true,\n\t\"&Nopf;\":                            true,\n\t\"&Not;\":                             true,\n\t\"&NotCongruent;\":                    true,\n\t\"&NotCupCap;\":                       true,\n\t\"&NotDoubleVerticalBar;\":            true,\n\t\"&NotElement;\":                      true,\n\t\"&NotEqual;\":                        true,\n\t\"&NotEqualTilde;\":                   true,\n\t\"&NotExists;\":                       true,\n\t\"&NotGreater;\":                      true,\n\t\"&NotGreaterEqual;\":                 true,\n\t\"&NotGreaterFullEqual;\":             true,\n\t\"&NotGreaterGreater;\":               true,\n\t\"&NotGreaterLess;\":                  true,\n\t\"&NotGreaterSlantEqual;\":            true,\n\t\"&NotGreaterTilde;\":                 true,\n\t\"&NotHumpDownHump;\":                 true,\n\t\"&NotHumpEqual;\":                    true,\n\t\"&NotLeftTriangle;\":                 true,\n\t\"&NotLeftTriangleBar;\":              true,\n\t\"&NotLeftTriangleEqual;\":            true,\n\t\"&NotLess;\":                         true,\n\t\"&NotLessEqual;\":                    true,\n\t\"&NotLessGreater;\":                  true,\n\t\"&NotLessLess;\":                     true,\n\t\"&NotLessSlantEqual;\":               true,\n\t\"&NotLessTilde;\":                    true,\n\t\"&NotNestedGreaterGreater;\":         true,\n\t\"&NotNestedLessLess;\":               true,\n\t\"&NotPrecedes;\":                     true,\n\t\"&NotPrecedesEqual;\":                true,\n\t\"&NotPrecedesSlantEqual;\":           true,\n\t\"&NotReverseElement;\":               true,\n\t\"&NotRightTriangle;\":                true,\n\t\"&NotRightTriangleBar;\":             true,\n\t\"&NotRightTriangleEqual;\":           true,\n\t\"&NotSquareSubset;\":                 true,\n\t\"&NotSquareSubsetEqual;\":            true,\n\t\"&NotSquareSuperset;\":               true,\n\t\"&NotSquareSupersetEqual;\":          true,\n\t\"&NotSubset;\":                       true,\n\t\"&NotSubsetEqual;\":                  true,\n\t\"&NotSucceeds;\":                     true,\n\t\"&NotSucceedsEqual;\":                true,\n\t\"&NotSucceedsSlantEqual;\":           true,\n\t\"&NotSucceedsTilde;\":                true,\n\t\"&NotSuperset;\":                     true,\n\t\"&NotSupersetEqual;\":                true,\n\t\"&NotTilde;\":                        true,\n\t\"&NotTildeEqual;\":                   true,\n\t\"&NotTildeFullEqual;\":               true,\n\t\"&NotTildeTilde;\":                   true,\n\t\"&NotVerticalBar;\":                  true,\n\t\"&Nscr;\":                            true,\n\t\"&Ntilde\":                           true,\n\t\"&Ntilde;\":                          true,\n\t\"&Nu;\":                              true,\n\t\"&OElig;\":                           true,\n\t\"&Oacute\":                           true,\n\t\"&Oacute;\":                          true,\n\t\"&Ocirc\":                            true,\n\t\"&Ocirc;\":                           true,\n\t\"&Ocy;\":                             true,\n\t\"&Odblac;\":                          true,\n\t\"&Ofr;\":                             true,\n\t\"&Ograve\":                           true,\n\t\"&Ograve;\":                          true,\n\t\"&Omacr;\":                           true,\n\t\"&Omega;\":                           true,\n\t\"&Omicron;\":                         true,\n\t\"&Oopf;\":                            true,\n\t\"&OpenCurlyDoubleQuote;\":            true,\n\t\"&OpenCurlyQuote;\":                  true,\n\t\"&Or;\":                              true,\n\t\"&Oscr;\":                            true,\n\t\"&Oslash\":                           true,\n\t\"&Oslash;\":                          true,\n\t\"&Otilde\":                           true,\n\t\"&Otilde;\":                          true,\n\t\"&Otimes;\":                          true,\n\t\"&Ouml\":                             true,\n\t\"&Ouml;\":                            true,\n\t\"&OverBar;\":                         true,\n\t\"&OverBrace;\":                       true,\n\t\"&OverBracket;\":                     true,\n\t\"&OverParenthesis;\":                 true,\n\t\"&PartialD;\":                        true,\n\t\"&Pcy;\":                             true,\n\t\"&Pfr;\":                             true,\n\t\"&Phi;\":                             true,\n\t\"&Pi;\":                              true,\n\t\"&PlusMinus;\":                       true,\n\t\"&Poincareplane;\":                   true,\n\t\"&Popf;\":                            true,\n\t\"&Pr;\":                              true,\n\t\"&Precedes;\":                        true,\n\t\"&PrecedesEqual;\":                   true,\n\t\"&PrecedesSlantEqual;\":              true,\n\t\"&PrecedesTilde;\":                   true,\n\t\"&Prime;\":                           true,\n\t\"&Product;\":                         true,\n\t\"&Proportion;\":                      true,\n\t\"&Proportional;\":                    true,\n\t\"&Pscr;\":                            true,\n\t\"&Psi;\":                             true,\n\t\"&QUOT\":                             true,\n\t\"&QUOT;\":                            true,\n\t\"&Qfr;\":                             true,\n\t\"&Qopf;\":                            true,\n\t\"&Qscr;\":                            true,\n\t\"&RBarr;\":                           true,\n\t\"&REG\":                              true,\n\t\"&REG;\":                             true,\n\t\"&Racute;\":                          true,\n\t\"&Rang;\":                            true,\n\t\"&Rarr;\":                            true,\n\t\"&Rarrtl;\":                          true,\n\t\"&Rcaron;\":                          true,\n\t\"&Rcedil;\":                          true,\n\t\"&Rcy;\":                             true,\n\t\"&Re;\":                              true,\n\t\"&ReverseElement;\":                  true,\n\t\"&ReverseEquilibrium;\":              true,\n\t\"&ReverseUpEquilibrium;\":            true,\n\t\"&Rfr;\":                             true,\n\t\"&Rho;\":                             true,\n\t\"&RightAngleBracket;\":               true,\n\t\"&RightArrow;\":                      true,\n\t\"&RightArrowBar;\":                   true,\n\t\"&RightArrowLeftArrow;\":             true,\n\t\"&RightCeiling;\":                    true,\n\t\"&RightDoubleBracket;\":              true,\n\t\"&RightDownTeeVector;\":              true,\n\t\"&RightDownVector;\":                 true,\n\t\"&RightDownVectorBar;\":              true,\n\t\"&RightFloor;\":                      true,\n\t\"&RightTee;\":                        true,\n\t\"&RightTeeArrow;\":                   true,\n\t\"&RightTeeVector;\":                  true,\n\t\"&RightTriangle;\":                   true,\n\t\"&RightTriangleBar;\":                true,\n\t\"&RightTriangleEqual;\":              true,\n\t\"&RightUpDownVector;\":               true,\n\t\"&RightUpTeeVector;\":                true,\n\t\"&RightUpVector;\":                   true,\n\t\"&RightUpVectorBar;\":                true,\n\t\"&RightVector;\":                     true,\n\t\"&RightVectorBar;\":                  true,\n\t\"&Rightarrow;\":                      true,\n\t\"&Ropf;\":                            true,\n\t\"&RoundImplies;\":                    true,\n\t\"&Rrightarrow;\":                     true,\n\t\"&Rscr;\":                            true,\n\t\"&Rsh;\":                             true,\n\t\"&RuleDelayed;\":                     true,\n\t\"&SHCHcy;\":                          true,\n\t\"&SHcy;\":                            true,\n\t\"&SOFTcy;\":                          true,\n\t\"&Sacute;\":                          true,\n\t\"&Sc;\":                              true,\n\t\"&Scaron;\":                          true,\n\t\"&Scedil;\":                          true,\n\t\"&Scirc;\":                           true,\n\t\"&Scy;\":                             true,\n\t\"&Sfr;\":                             true,\n\t\"&ShortDownArrow;\":                  true,\n\t\"&ShortLeftArrow;\":                  true,\n\t\"&ShortRightArrow;\":                 true,\n\t\"&ShortUpArrow;\":                    true,\n\t\"&Sigma;\":                           true,\n\t\"&SmallCircle;\":                     true,\n\t\"&Sopf;\":                            true,\n\t\"&Sqrt;\":                            true,\n\t\"&Square;\":                          true,\n\t\"&SquareIntersection;\":              true,\n\t\"&SquareSubset;\":                    true,\n\t\"&SquareSubsetEqual;\":               true,\n\t\"&SquareSuperset;\":                  true,\n\t\"&SquareSupersetEqual;\":             true,\n\t\"&SquareUnion;\":                     true,\n\t\"&Sscr;\":                            true,\n\t\"&Star;\":                            true,\n\t\"&Sub;\":                             true,\n\t\"&Subset;\":                          true,\n\t\"&SubsetEqual;\":                     true,\n\t\"&Succeeds;\":                        true,\n\t\"&SucceedsEqual;\":                   true,\n\t\"&SucceedsSlantEqual;\":              true,\n\t\"&SucceedsTilde;\":                   true,\n\t\"&SuchThat;\":                        true,\n\t\"&Sum;\":                             true,\n\t\"&Sup;\":                             true,\n\t\"&Superset;\":                        true,\n\t\"&SupersetEqual;\":                   true,\n\t\"&Supset;\":                          true,\n\t\"&THORN\":                            true,\n\t\"&THORN;\":                           true,\n\t\"&TRADE;\":                           true,\n\t\"&TSHcy;\":                           true,\n\t\"&TScy;\":                            true,\n\t\"&Tab;\":                             true,\n\t\"&Tau;\":                             true,\n\t\"&Tcaron;\":                          true,\n\t\"&Tcedil;\":                          true,\n\t\"&Tcy;\":                             true,\n\t\"&Tfr;\":                             true,\n\t\"&Therefore;\":                       true,\n\t\"&Theta;\":                           true,\n\t\"&ThickSpace;\":                      true,\n\t\"&ThinSpace;\":                       true,\n\t\"&Tilde;\":                           true,\n\t\"&TildeEqual;\":                      true,\n\t\"&TildeFullEqual;\":                  true,\n\t\"&TildeTilde;\":                      true,\n\t\"&Topf;\":                            true,\n\t\"&TripleDot;\":                       true,\n\t\"&Tscr;\":                            true,\n\t\"&Tstrok;\":                          true,\n\t\"&Uacute\":                           true,\n\t\"&Uacute;\":                          true,\n\t\"&Uarr;\":                            true,\n\t\"&Uarrocir;\":                        true,\n\t\"&Ubrcy;\":                           true,\n\t\"&Ubreve;\":                          true,\n\t\"&Ucirc\":                            true,\n\t\"&Ucirc;\":                           true,\n\t\"&Ucy;\":                             true,\n\t\"&Udblac;\":                          true,\n\t\"&Ufr;\":                             true,\n\t\"&Ugrave\":                           true,\n\t\"&Ugrave;\":                          true,\n\t\"&Umacr;\":                           true,\n\t\"&UnderBar;\":                        true,\n\t\"&UnderBrace;\":                      true,\n\t\"&UnderBracket;\":                    true,\n\t\"&UnderParenthesis;\":                true,\n\t\"&Union;\":                           true,\n\t\"&UnionPlus;\":                       true,\n\t\"&Uogon;\":                           true,\n\t\"&Uopf;\":                            true,\n\t\"&UpArrow;\":                         true,\n\t\"&UpArrowBar;\":                      true,\n\t\"&UpArrowDownArrow;\":                true,\n\t\"&UpDownArrow;\":                     true,\n\t\"&UpEquilibrium;\":                   true,\n\t\"&UpTee;\":                           true,\n\t\"&UpTeeArrow;\":                      true,\n\t\"&Uparrow;\":                         true,\n\t\"&Updownarrow;\":                     true,\n\t\"&UpperLeftArrow;\":                  true,\n\t\"&UpperRightArrow;\":                 true,\n\t\"&Upsi;\":                            true,\n\t\"&Upsilon;\":                         true,\n\t\"&Uring;\":                           true,\n\t\"&Uscr;\":                            true,\n\t\"&Utilde;\":                          true,\n\t\"&Uuml\":                             true,\n\t\"&Uuml;\":                            true,\n\t\"&VDash;\":                           true,\n\t\"&Vbar;\":                            true,\n\t\"&Vcy;\":                             true,\n\t\"&Vdash;\":                           true,\n\t\"&Vdashl;\":                          true,\n\t\"&Vee;\":                             true,\n\t\"&Verbar;\":                          true,\n\t\"&Vert;\":                            true,\n\t\"&VerticalBar;\":                     true,\n\t\"&VerticalLine;\":                    true,\n\t\"&VerticalSeparator;\":               true,\n\t\"&VerticalTilde;\":                   true,\n\t\"&VeryThinSpace;\":                   true,\n\t\"&Vfr;\":                             true,\n\t\"&Vopf;\":                            true,\n\t\"&Vscr;\":                            true,\n\t\"&Vvdash;\":                          true,\n\t\"&Wcirc;\":                           true,\n\t\"&Wedge;\":                           true,\n\t\"&Wfr;\":                             true,\n\t\"&Wopf;\":                            true,\n\t\"&Wscr;\":                            true,\n\t\"&Xfr;\":                             true,\n\t\"&Xi;\":                              true,\n\t\"&Xopf;\":                            true,\n\t\"&Xscr;\":                            true,\n\t\"&YAcy;\":                            true,\n\t\"&YIcy;\":                            true,\n\t\"&YUcy;\":                            true,\n\t\"&Yacute\":                           true,\n\t\"&Yacute;\":                          true,\n\t\"&Ycirc;\":                           true,\n\t\"&Ycy;\":                             true,\n\t\"&Yfr;\":                             true,\n\t\"&Yopf;\":                            true,\n\t\"&Yscr;\":                            true,\n\t\"&Yuml;\":                            true,\n\t\"&ZHcy;\":                            true,\n\t\"&Zacute;\":                          true,\n\t\"&Zcaron;\":                          true,\n\t\"&Zcy;\":                             true,\n\t\"&Zdot;\":                            true,\n\t\"&ZeroWidthSpace;\":                  true,\n\t\"&Zeta;\":                            true,\n\t\"&Zfr;\":                             true,\n\t\"&Zopf;\":                            true,\n\t\"&Zscr;\":                            true,\n\t\"&aacute\":                           true,\n\t\"&aacute;\":                          true,\n\t\"&abreve;\":                          true,\n\t\"&ac;\":                              true,\n\t\"&acE;\":                             true,\n\t\"&acd;\":                             true,\n\t\"&acirc\":                            true,\n\t\"&acirc;\":                           true,\n\t\"&acute\":                            true,\n\t\"&acute;\":                           true,\n\t\"&acy;\":                             true,\n\t\"&aelig\":                            true,\n\t\"&aelig;\":                           true,\n\t\"&af;\":                              true,\n\t\"&afr;\":                             true,\n\t\"&agrave\":                           true,\n\t\"&agrave;\":                          true,\n\t\"&alefsym;\":                         true,\n\t\"&aleph;\":                           true,\n\t\"&alpha;\":                           true,\n\t\"&amacr;\":                           true,\n\t\"&amalg;\":                           true,\n\t\"&amp\":                              true,\n\t\"&amp;\":                             true,\n\t\"&and;\":                             true,\n\t\"&andand;\":                          true,\n\t\"&andd;\":                            true,\n\t\"&andslope;\":                        true,\n\t\"&andv;\":                            true,\n\t\"&ang;\":                             true,\n\t\"&ange;\":                            true,\n\t\"&angle;\":                           true,\n\t\"&angmsd;\":                          true,\n\t\"&angmsdaa;\":                        true,\n\t\"&angmsdab;\":                        true,\n\t\"&angmsdac;\":                        true,\n\t\"&angmsdad;\":                        true,\n\t\"&angmsdae;\":                        true,\n\t\"&angmsdaf;\":                        true,\n\t\"&angmsdag;\":                        true,\n\t\"&angmsdah;\":                        true,\n\t\"&angrt;\":                           true,\n\t\"&angrtvb;\":                         true,\n\t\"&angrtvbd;\":                        true,\n\t\"&angsph;\":                          true,\n\t\"&angst;\":                           true,\n\t\"&angzarr;\":                         true,\n\t\"&aogon;\":                           true,\n\t\"&aopf;\":                            true,\n\t\"&ap;\":                              true,\n\t\"&apE;\":                             true,\n\t\"&apacir;\":                          true,\n\t\"&ape;\":                             true,\n\t\"&apid;\":                            true,\n\t\"&apos;\":                            true,\n\t\"&approx;\":                          true,\n\t\"&approxeq;\":                        true,\n\t\"&aring\":                            true,\n\t\"&aring;\":                           true,\n\t\"&ascr;\":                            true,\n\t\"&ast;\":                             true,\n\t\"&asymp;\":                           true,\n\t\"&asympeq;\":                         true,\n\t\"&atilde\":                           true,\n\t\"&atilde;\":                          true,\n\t\"&auml\":                             true,\n\t\"&auml;\":                            true,\n\t\"&awconint;\":                        true,\n\t\"&awint;\":                           true,\n\t\"&bNot;\":                            true,\n\t\"&backcong;\":                        true,\n\t\"&backepsilon;\":                     true,\n\t\"&backprime;\":                       true,\n\t\"&backsim;\":                         true,\n\t\"&backsimeq;\":                       true,\n\t\"&barvee;\":                          true,\n\t\"&barwed;\":                          true,\n\t\"&barwedge;\":                        true,\n\t\"&bbrk;\":                            true,\n\t\"&bbrktbrk;\":                        true,\n\t\"&bcong;\":                           true,\n\t\"&bcy;\":                             true,\n\t\"&bdquo;\":                           true,\n\t\"&becaus;\":                          true,\n\t\"&because;\":                         true,\n\t\"&bemptyv;\":                         true,\n\t\"&bepsi;\":                           true,\n\t\"&bernou;\":                          true,\n\t\"&beta;\":                            true,\n\t\"&beth;\":                            true,\n\t\"&between;\":                         true,\n\t\"&bfr;\":                             true,\n\t\"&bigcap;\":                          true,\n\t\"&bigcirc;\":                         true,\n\t\"&bigcup;\":                          true,\n\t\"&bigodot;\":                         true,\n\t\"&bigoplus;\":                        true,\n\t\"&bigotimes;\":                       true,\n\t\"&bigsqcup;\":                        true,\n\t\"&bigstar;\":                         true,\n\t\"&bigtriangledown;\":                 true,\n\t\"&bigtriangleup;\":                   true,\n\t\"&biguplus;\":                        true,\n\t\"&bigvee;\":                          true,\n\t\"&bigwedge;\":                        true,\n\t\"&bkarow;\":                          true,\n\t\"&blacklozenge;\":                    true,\n\t\"&blacksquare;\":                     true,\n\t\"&blacktriangle;\":                   true,\n\t\"&blacktriangledown;\":               true,\n\t\"&blacktriangleleft;\":               true,\n\t\"&blacktriangleright;\":              true,\n\t\"&blank;\":                           true,\n\t\"&blk12;\":                           true,\n\t\"&blk14;\":                           true,\n\t\"&blk34;\":                           true,\n\t\"&block;\":                           true,\n\t\"&bne;\":                             true,\n\t\"&bnequiv;\":                         true,\n\t\"&bnot;\":                            true,\n\t\"&bopf;\":                            true,\n\t\"&bot;\":                             true,\n\t\"&bottom;\":                          true,\n\t\"&bowtie;\":                          true,\n\t\"&boxDL;\":                           true,\n\t\"&boxDR;\":                           true,\n\t\"&boxDl;\":                           true,\n\t\"&boxDr;\":                           true,\n\t\"&boxH;\":                            true,\n\t\"&boxHD;\":                           true,\n\t\"&boxHU;\":                           true,\n\t\"&boxHd;\":                           true,\n\t\"&boxHu;\":                           true,\n\t\"&boxUL;\":                           true,\n\t\"&boxUR;\":                           true,\n\t\"&boxUl;\":                           true,\n\t\"&boxUr;\":                           true,\n\t\"&boxV;\":                            true,\n\t\"&boxVH;\":                           true,\n\t\"&boxVL;\":                           true,\n\t\"&boxVR;\":                           true,\n\t\"&boxVh;\":                           true,\n\t\"&boxVl;\":                           true,\n\t\"&boxVr;\":                           true,\n\t\"&boxbox;\":                          true,\n\t\"&boxdL;\":                           true,\n\t\"&boxdR;\":                           true,\n\t\"&boxdl;\":                           true,\n\t\"&boxdr;\":                           true,\n\t\"&boxh;\":                            true,\n\t\"&boxhD;\":                           true,\n\t\"&boxhU;\":                           true,\n\t\"&boxhd;\":                           true,\n\t\"&boxhu;\":                           true,\n\t\"&boxminus;\":                        true,\n\t\"&boxplus;\":                         true,\n\t\"&boxtimes;\":                        true,\n\t\"&boxuL;\":                           true,\n\t\"&boxuR;\":                           true,\n\t\"&boxul;\":                           true,\n\t\"&boxur;\":                           true,\n\t\"&boxv;\":                            true,\n\t\"&boxvH;\":                           true,\n\t\"&boxvL;\":                           true,\n\t\"&boxvR;\":                           true,\n\t\"&boxvh;\":                           true,\n\t\"&boxvl;\":                           true,\n\t\"&boxvr;\":                           true,\n\t\"&bprime;\":                          true,\n\t\"&breve;\":                           true,\n\t\"&brvbar\":                           true,\n\t\"&brvbar;\":                          true,\n\t\"&bscr;\":                            true,\n\t\"&bsemi;\":                           true,\n\t\"&bsim;\":                            true,\n\t\"&bsime;\":                           true,\n\t\"&bsol;\":                            true,\n\t\"&bsolb;\":                           true,\n\t\"&bsolhsub;\":                        true,\n\t\"&bull;\":                            true,\n\t\"&bullet;\":                          true,\n\t\"&bump;\":                            true,\n\t\"&bumpE;\":                           true,\n\t\"&bumpe;\":                           true,\n\t\"&bumpeq;\":                          true,\n\t\"&cacute;\":                          true,\n\t\"&cap;\":                             true,\n\t\"&capand;\":                          true,\n\t\"&capbrcup;\":                        true,\n\t\"&capcap;\":                          true,\n\t\"&capcup;\":                          true,\n\t\"&capdot;\":                          true,\n\t\"&caps;\":                            true,\n\t\"&caret;\":                           true,\n\t\"&caron;\":                           true,\n\t\"&ccaps;\":                           true,\n\t\"&ccaron;\":                          true,\n\t\"&ccedil\":                           true,\n\t\"&ccedil;\":                          true,\n\t\"&ccirc;\":                           true,\n\t\"&ccups;\":                           true,\n\t\"&ccupssm;\":                         true,\n\t\"&cdot;\":                            true,\n\t\"&cedil\":                            true,\n\t\"&cedil;\":                           true,\n\t\"&cemptyv;\":                         true,\n\t\"&cent\":                             true,\n\t\"&cent;\":                            true,\n\t\"&centerdot;\":                       true,\n\t\"&cfr;\":                             true,\n\t\"&chcy;\":                            true,\n\t\"&check;\":                           true,\n\t\"&checkmark;\":                       true,\n\t\"&chi;\":                             true,\n\t\"&cir;\":                             true,\n\t\"&cirE;\":                            true,\n\t\"&circ;\":                            true,\n\t\"&circeq;\":                          true,\n\t\"&circlearrowleft;\":                 true,\n\t\"&circlearrowright;\":                true,\n\t\"&circledR;\":                        true,\n\t\"&circledS;\":                        true,\n\t\"&circledast;\":                      true,\n\t\"&circledcirc;\":                     true,\n\t\"&circleddash;\":                     true,\n\t\"&cire;\":                            true,\n\t\"&cirfnint;\":                        true,\n\t\"&cirmid;\":                          true,\n\t\"&cirscir;\":                         true,\n\t\"&clubs;\":                           true,\n\t\"&clubsuit;\":                        true,\n\t\"&colon;\":                           true,\n\t\"&colone;\":                          true,\n\t\"&coloneq;\":                         true,\n\t\"&comma;\":                           true,\n\t\"&commat;\":                          true,\n\t\"&comp;\":                            true,\n\t\"&compfn;\":                          true,\n\t\"&complement;\":                      true,\n\t\"&complexes;\":                       true,\n\t\"&cong;\":                            true,\n\t\"&congdot;\":                         true,\n\t\"&conint;\":                          true,\n\t\"&copf;\":                            true,\n\t\"&coprod;\":                          true,\n\t\"&copy\":                             true,\n\t\"&copy;\":                            true,\n\t\"&copysr;\":                          true,\n\t\"&crarr;\":                           true,\n\t\"&cross;\":                           true,\n\t\"&cscr;\":                            true,\n\t\"&csub;\":                            true,\n\t\"&csube;\":                           true,\n\t\"&csup;\":                            true,\n\t\"&csupe;\":                           true,\n\t\"&ctdot;\":                           true,\n\t\"&cudarrl;\":                         true,\n\t\"&cudarrr;\":                         true,\n\t\"&cuepr;\":                           true,\n\t\"&cuesc;\":                           true,\n\t\"&cularr;\":                          true,\n\t\"&cularrp;\":                         true,\n\t\"&cup;\":                             true,\n\t\"&cupbrcap;\":                        true,\n\t\"&cupcap;\":                          true,\n\t\"&cupcup;\":                          true,\n\t\"&cupdot;\":                          true,\n\t\"&cupor;\":                           true,\n\t\"&cups;\":                            true,\n\t\"&curarr;\":                          true,\n\t\"&curarrm;\":                         true,\n\t\"&curlyeqprec;\":                     true,\n\t\"&curlyeqsucc;\":                     true,\n\t\"&curlyvee;\":                        true,\n\t\"&curlywedge;\":                      true,\n\t\"&curren\":                           true,\n\t\"&curren;\":                          true,\n\t\"&curvearrowleft;\":                  true,\n\t\"&curvearrowright;\":                 true,\n\t\"&cuvee;\":                           true,\n\t\"&cuwed;\":                           true,\n\t\"&cwconint;\":                        true,\n\t\"&cwint;\":                           true,\n\t\"&cylcty;\":                          true,\n\t\"&dArr;\":                            true,\n\t\"&dHar;\":                            true,\n\t\"&dagger;\":                          true,\n\t\"&daleth;\":                          true,\n\t\"&darr;\":                            true,\n\t\"&dash;\":                            true,\n\t\"&dashv;\":                           true,\n\t\"&dbkarow;\":                         true,\n\t\"&dblac;\":                           true,\n\t\"&dcaron;\":                          true,\n\t\"&dcy;\":                             true,\n\t\"&dd;\":                              true,\n\t\"&ddagger;\":                         true,\n\t\"&ddarr;\":                           true,\n\t\"&ddotseq;\":                         true,\n\t\"&deg\":                              true,\n\t\"&deg;\":                             true,\n\t\"&delta;\":                           true,\n\t\"&demptyv;\":                         true,\n\t\"&dfisht;\":                          true,\n\t\"&dfr;\":                             true,\n\t\"&dharl;\":                           true,\n\t\"&dharr;\":                           true,\n\t\"&diam;\":                            true,\n\t\"&diamond;\":                         true,\n\t\"&diamondsuit;\":                     true,\n\t\"&diams;\":                           true,\n\t\"&die;\":                             true,\n\t\"&digamma;\":                         true,\n\t\"&disin;\":                           true,\n\t\"&div;\":                             true,\n\t\"&divide\":                           true,\n\t\"&divide;\":                          true,\n\t\"&divideontimes;\":                   true,\n\t\"&divonx;\":                          true,\n\t\"&djcy;\":                            true,\n\t\"&dlcorn;\":                          true,\n\t\"&dlcrop;\":                          true,\n\t\"&dollar;\":                          true,\n\t\"&dopf;\":                            true,\n\t\"&dot;\":                             true,\n\t\"&doteq;\":                           true,\n\t\"&doteqdot;\":                        true,\n\t\"&dotminus;\":                        true,\n\t\"&dotplus;\":                         true,\n\t\"&dotsquare;\":                       true,\n\t\"&doublebarwedge;\":                  true,\n\t\"&downarrow;\":                       true,\n\t\"&downdownarrows;\":                  true,\n\t\"&downharpoonleft;\":                 true,\n\t\"&downharpoonright;\":                true,\n\t\"&drbkarow;\":                        true,\n\t\"&drcorn;\":                          true,\n\t\"&drcrop;\":                          true,\n\t\"&dscr;\":                            true,\n\t\"&dscy;\":                            true,\n\t\"&dsol;\":                            true,\n\t\"&dstrok;\":                          true,\n\t\"&dtdot;\":                           true,\n\t\"&dtri;\":                            true,\n\t\"&dtrif;\":                           true,\n\t\"&duarr;\":                           true,\n\t\"&duhar;\":                           true,\n\t\"&dwangle;\":                         true,\n\t\"&dzcy;\":                            true,\n\t\"&dzigrarr;\":                        true,\n\t\"&eDDot;\":                           true,\n\t\"&eDot;\":                            true,\n\t\"&eacute\":                           true,\n\t\"&eacute;\":                          true,\n\t\"&easter;\":                          true,\n\t\"&ecaron;\":                          true,\n\t\"&ecir;\":                            true,\n\t\"&ecirc\":                            true,\n\t\"&ecirc;\":                           true,\n\t\"&ecolon;\":                          true,\n\t\"&ecy;\":                             true,\n\t\"&edot;\":                            true,\n\t\"&ee;\":                              true,\n\t\"&efDot;\":                           true,\n\t\"&efr;\":                             true,\n\t\"&eg;\":                              true,\n\t\"&egrave\":                           true,\n\t\"&egrave;\":                          true,\n\t\"&egs;\":                             true,\n\t\"&egsdot;\":                          true,\n\t\"&el;\":                              true,\n\t\"&elinters;\":                        true,\n\t\"&ell;\":                             true,\n\t\"&els;\":                             true,\n\t\"&elsdot;\":                          true,\n\t\"&emacr;\":                           true,\n\t\"&empty;\":                           true,\n\t\"&emptyset;\":                        true,\n\t\"&emptyv;\":                          true,\n\t\"&emsp13;\":                          true,\n\t\"&emsp14;\":                          true,\n\t\"&emsp;\":                            true,\n\t\"&eng;\":                             true,\n\t\"&ensp;\":                            true,\n\t\"&eogon;\":                           true,\n\t\"&eopf;\":                            true,\n\t\"&epar;\":                            true,\n\t\"&eparsl;\":                          true,\n\t\"&eplus;\":                           true,\n\t\"&epsi;\":                            true,\n\t\"&epsilon;\":                         true,\n\t\"&epsiv;\":                           true,\n\t\"&eqcirc;\":                          true,\n\t\"&eqcolon;\":                         true,\n\t\"&eqsim;\":                           true,\n\t\"&eqslantgtr;\":                      true,\n\t\"&eqslantless;\":                     true,\n\t\"&equals;\":                          true,\n\t\"&equest;\":                          true,\n\t\"&equiv;\":                           true,\n\t\"&equivDD;\":                         true,\n\t\"&eqvparsl;\":                        true,\n\t\"&erDot;\":                           true,\n\t\"&erarr;\":                           true,\n\t\"&escr;\":                            true,\n\t\"&esdot;\":                           true,\n\t\"&esim;\":                            true,\n\t\"&eta;\":                             true,\n\t\"&eth\":                              true,\n\t\"&eth;\":                             true,\n\t\"&euml\":                             true,\n\t\"&euml;\":                            true,\n\t\"&euro;\":                            true,\n\t\"&excl;\":                            true,\n\t\"&exist;\":                           true,\n\t\"&expectation;\":                     true,\n\t\"&exponentiale;\":                    true,\n\t\"&fallingdotseq;\":                   true,\n\t\"&fcy;\":                             true,\n\t\"&female;\":                          true,\n\t\"&ffilig;\":                          true,\n\t\"&fflig;\":                           true,\n\t\"&ffllig;\":                          true,\n\t\"&ffr;\":                             true,\n\t\"&filig;\":                           true,\n\t\"&fjlig;\":                           true,\n\t\"&flat;\":                            true,\n\t\"&fllig;\":                           true,\n\t\"&fltns;\":                           true,\n\t\"&fnof;\":                            true,\n\t\"&fopf;\":                            true,\n\t\"&forall;\":                          true,\n\t\"&fork;\":                            true,\n\t\"&forkv;\":                           true,\n\t\"&fpartint;\":                        true,\n\t\"&frac12\":                           true,\n\t\"&frac12;\":                          true,\n\t\"&frac13;\":                          true,\n\t\"&frac14\":                           true,\n\t\"&frac14;\":                          true,\n\t\"&frac15;\":                          true,\n\t\"&frac16;\":                          true,\n\t\"&frac18;\":                          true,\n\t\"&frac23;\":                          true,\n\t\"&frac25;\":                          true,\n\t\"&frac34\":                           true,\n\t\"&frac34;\":                          true,\n\t\"&frac35;\":                          true,\n\t\"&frac38;\":                          true,\n\t\"&frac45;\":                          true,\n\t\"&frac56;\":                          true,\n\t\"&frac58;\":                          true,\n\t\"&frac78;\":                          true,\n\t\"&frasl;\":                           true,\n\t\"&frown;\":                           true,\n\t\"&fscr;\":                            true,\n\t\"&gE;\":                              true,\n\t\"&gEl;\":                             true,\n\t\"&gacute;\":                          true,\n\t\"&gamma;\":                           true,\n\t\"&gammad;\":                          true,\n\t\"&gap;\":                             true,\n\t\"&gbreve;\":                          true,\n\t\"&gcirc;\":                           true,\n\t\"&gcy;\":                             true,\n\t\"&gdot;\":                            true,\n\t\"&ge;\":                              true,\n\t\"&gel;\":                             true,\n\t\"&geq;\":                             true,\n\t\"&geqq;\":                            true,\n\t\"&geqslant;\":                        true,\n\t\"&ges;\":                             true,\n\t\"&gescc;\":                           true,\n\t\"&gesdot;\":                          true,\n\t\"&gesdoto;\":                         true,\n\t\"&gesdotol;\":                        true,\n\t\"&gesl;\":                            true,\n\t\"&gesles;\":                          true,\n\t\"&gfr;\":                             true,\n\t\"&gg;\":                              true,\n\t\"&ggg;\":                             true,\n\t\"&gimel;\":                           true,\n\t\"&gjcy;\":                            true,\n\t\"&gl;\":                              true,\n\t\"&glE;\":                             true,\n\t\"&gla;\":                             true,\n\t\"&glj;\":                             true,\n\t\"&gnE;\":                             true,\n\t\"&gnap;\":                            true,\n\t\"&gnapprox;\":                        true,\n\t\"&gne;\":                             true,\n\t\"&gneq;\":                            true,\n\t\"&gneqq;\":                           true,\n\t\"&gnsim;\":                           true,\n\t\"&gopf;\":                            true,\n\t\"&grave;\":                           true,\n\t\"&gscr;\":                            true,\n\t\"&gsim;\":                            true,\n\t\"&gsime;\":                           true,\n\t\"&gsiml;\":                           true,\n\t\"&gt\":                               true,\n\t\"&gt;\":                              true,\n\t\"&gtcc;\":                            true,\n\t\"&gtcir;\":                           true,\n\t\"&gtdot;\":                           true,\n\t\"&gtlPar;\":                          true,\n\t\"&gtquest;\":                         true,\n\t\"&gtrapprox;\":                       true,\n\t\"&gtrarr;\":                          true,\n\t\"&gtrdot;\":                          true,\n\t\"&gtreqless;\":                       true,\n\t\"&gtreqqless;\":                      true,\n\t\"&gtrless;\":                         true,\n\t\"&gtrsim;\":                          true,\n\t\"&gvertneqq;\":                       true,\n\t\"&gvnE;\":                            true,\n\t\"&hArr;\":                            true,\n\t\"&hairsp;\":                          true,\n\t\"&half;\":                            true,\n\t\"&hamilt;\":                          true,\n\t\"&hardcy;\":                          true,\n\t\"&harr;\":                            true,\n\t\"&harrcir;\":                         true,\n\t\"&harrw;\":                           true,\n\t\"&hbar;\":                            true,\n\t\"&hcirc;\":                           true,\n\t\"&hearts;\":                          true,\n\t\"&heartsuit;\":                       true,\n\t\"&hellip;\":                          true,\n\t\"&hercon;\":                          true,\n\t\"&hfr;\":                             true,\n\t\"&hksearow;\":                        true,\n\t\"&hkswarow;\":                        true,\n\t\"&hoarr;\":                           true,\n\t\"&homtht;\":                          true,\n\t\"&hookleftarrow;\":                   true,\n\t\"&hookrightarrow;\":                  true,\n\t\"&hopf;\":                            true,\n\t\"&horbar;\":                          true,\n\t\"&hscr;\":                            true,\n\t\"&hslash;\":                          true,\n\t\"&hstrok;\":                          true,\n\t\"&hybull;\":                          true,\n\t\"&hyphen;\":                          true,\n\t\"&iacute\":                           true,\n\t\"&iacute;\":                          true,\n\t\"&ic;\":                              true,\n\t\"&icirc\":                            true,\n\t\"&icirc;\":                           true,\n\t\"&icy;\":                             true,\n\t\"&iecy;\":                            true,\n\t\"&iexcl\":                            true,\n\t\"&iexcl;\":                           true,\n\t\"&iff;\":                             true,\n\t\"&ifr;\":                             true,\n\t\"&igrave\":                           true,\n\t\"&igrave;\":                          true,\n\t\"&ii;\":                              true,\n\t\"&iiiint;\":                          true,\n\t\"&iiint;\":                           true,\n\t\"&iinfin;\":                          true,\n\t\"&iiota;\":                           true,\n\t\"&ijlig;\":                           true,\n\t\"&imacr;\":                           true,\n\t\"&image;\":                           true,\n\t\"&imagline;\":                        true,\n\t\"&imagpart;\":                        true,\n\t\"&imath;\":                           true,\n\t\"&imof;\":                            true,\n\t\"&imped;\":                           true,\n\t\"&in;\":                              true,\n\t\"&incare;\":                          true,\n\t\"&infin;\":                           true,\n\t\"&infintie;\":                        true,\n\t\"&inodot;\":                          true,\n\t\"&int;\":                             true,\n\t\"&intcal;\":                          true,\n\t\"&integers;\":                        true,\n\t\"&intercal;\":                        true,\n\t\"&intlarhk;\":                        true,\n\t\"&intprod;\":                         true,\n\t\"&iocy;\":                            true,\n\t\"&iogon;\":                           true,\n\t\"&iopf;\":                            true,\n\t\"&iota;\":                            true,\n\t\"&iprod;\":                           true,\n\t\"&iquest\":                           true,\n\t\"&iquest;\":                          true,\n\t\"&iscr;\":                            true,\n\t\"&isin;\":                            true,\n\t\"&isinE;\":                           true,\n\t\"&isindot;\":                         true,\n\t\"&isins;\":                           true,\n\t\"&isinsv;\":                          true,\n\t\"&isinv;\":                           true,\n\t\"&it;\":                              true,\n\t\"&itilde;\":                          true,\n\t\"&iukcy;\":                           true,\n\t\"&iuml\":                             true,\n\t\"&iuml;\":                            true,\n\t\"&jcirc;\":                           true,\n\t\"&jcy;\":                             true,\n\t\"&jfr;\":                             true,\n\t\"&jmath;\":                           true,\n\t\"&jopf;\":                            true,\n\t\"&jscr;\":                            true,\n\t\"&jsercy;\":                          true,\n\t\"&jukcy;\":                           true,\n\t\"&kappa;\":                           true,\n\t\"&kappav;\":                          true,\n\t\"&kcedil;\":                          true,\n\t\"&kcy;\":                             true,\n\t\"&kfr;\":                             true,\n\t\"&kgreen;\":                          true,\n\t\"&khcy;\":                            true,\n\t\"&kjcy;\":                            true,\n\t\"&kopf;\":                            true,\n\t\"&kscr;\":                            true,\n\t\"&lAarr;\":                           true,\n\t\"&lArr;\":                            true,\n\t\"&lAtail;\":                          true,\n\t\"&lBarr;\":                           true,\n\t\"&lE;\":                              true,\n\t\"&lEg;\":                             true,\n\t\"&lHar;\":                            true,\n\t\"&lacute;\":                          true,\n\t\"&laemptyv;\":                        true,\n\t\"&lagran;\":                          true,\n\t\"&lambda;\":                          true,\n\t\"&lang;\":                            true,\n\t\"&langd;\":                           true,\n\t\"&langle;\":                          true,\n\t\"&lap;\":                             true,\n\t\"&laquo\":                            true,\n\t\"&laquo;\":                           true,\n\t\"&larr;\":                            true,\n\t\"&larrb;\":                           true,\n\t\"&larrbfs;\":                         true,\n\t\"&larrfs;\":                          true,\n\t\"&larrhk;\":                          true,\n\t\"&larrlp;\":                          true,\n\t\"&larrpl;\":                          true,\n\t\"&larrsim;\":                         true,\n\t\"&larrtl;\":                          true,\n\t\"&lat;\":                             true,\n\t\"&latail;\":                          true,\n\t\"&late;\":                            true,\n\t\"&lates;\":                           true,\n\t\"&lbarr;\":                           true,\n\t\"&lbbrk;\":                           true,\n\t\"&lbrace;\":                          true,\n\t\"&lbrack;\":                          true,\n\t\"&lbrke;\":                           true,\n\t\"&lbrksld;\":                         true,\n\t\"&lbrkslu;\":                         true,\n\t\"&lcaron;\":                          true,\n\t\"&lcedil;\":                          true,\n\t\"&lceil;\":                           true,\n\t\"&lcub;\":                            true,\n\t\"&lcy;\":                             true,\n\t\"&ldca;\":                            true,\n\t\"&ldquo;\":                           true,\n\t\"&ldquor;\":                          true,\n\t\"&ldrdhar;\":                         true,\n\t\"&ldrushar;\":                        true,\n\t\"&ldsh;\":                            true,\n\t\"&le;\":                              true,\n\t\"&leftarrow;\":                       true,\n\t\"&leftarrowtail;\":                   true,\n\t\"&leftharpoondown;\":                 true,\n\t\"&leftharpoonup;\":                   true,\n\t\"&leftleftarrows;\":                  true,\n\t\"&leftrightarrow;\":                  true,\n\t\"&leftrightarrows;\":                 true,\n\t\"&leftrightharpoons;\":               true,\n\t\"&leftrightsquigarrow;\":             true,\n\t\"&leftthreetimes;\":                  true,\n\t\"&leg;\":                             true,\n\t\"&leq;\":                             true,\n\t\"&leqq;\":                            true,\n\t\"&leqslant;\":                        true,\n\t\"&les;\":                             true,\n\t\"&lescc;\":                           true,\n\t\"&lesdot;\":                          true,\n\t\"&lesdoto;\":                         true,\n\t\"&lesdotor;\":                        true,\n\t\"&lesg;\":                            true,\n\t\"&lesges;\":                          true,\n\t\"&lessapprox;\":                      true,\n\t\"&lessdot;\":                         true,\n\t\"&lesseqgtr;\":                       true,\n\t\"&lesseqqgtr;\":                      true,\n\t\"&lessgtr;\":                         true,\n\t\"&lesssim;\":                         true,\n\t\"&lfisht;\":                          true,\n\t\"&lfloor;\":                          true,\n\t\"&lfr;\":                             true,\n\t\"&lg;\":                              true,\n\t\"&lgE;\":                             true,\n\t\"&lhard;\":                           true,\n\t\"&lharu;\":                           true,\n\t\"&lharul;\":                          true,\n\t\"&lhblk;\":                           true,\n\t\"&ljcy;\":                            true,\n\t\"&ll;\":                              true,\n\t\"&llarr;\":                           true,\n\t\"&llcorner;\":                        true,\n\t\"&llhard;\":                          true,\n\t\"&lltri;\":                           true,\n\t\"&lmidot;\":                          true,\n\t\"&lmoust;\":                          true,\n\t\"&lmoustache;\":                      true,\n\t\"&lnE;\":                             true,\n\t\"&lnap;\":                            true,\n\t\"&lnapprox;\":                        true,\n\t\"&lne;\":                             true,\n\t\"&lneq;\":                            true,\n\t\"&lneqq;\":                           true,\n\t\"&lnsim;\":                           true,\n\t\"&loang;\":                           true,\n\t\"&loarr;\":                           true,\n\t\"&lobrk;\":                           true,\n\t\"&longleftarrow;\":                   true,\n\t\"&longleftrightarrow;\":              true,\n\t\"&longmapsto;\":                      true,\n\t\"&longrightarrow;\":                  true,\n\t\"&looparrowleft;\":                   true,\n\t\"&looparrowright;\":                  true,\n\t\"&lopar;\":                           true,\n\t\"&lopf;\":                            true,\n\t\"&loplus;\":                          true,\n\t\"&lotimes;\":                         true,\n\t\"&lowast;\":                          true,\n\t\"&lowbar;\":                          true,\n\t\"&loz;\":                             true,\n\t\"&lozenge;\":                         true,\n\t\"&lozf;\":                            true,\n\t\"&lpar;\":                            true,\n\t\"&lparlt;\":                          true,\n\t\"&lrarr;\":                           true,\n\t\"&lrcorner;\":                        true,\n\t\"&lrhar;\":                           true,\n\t\"&lrhard;\":                          true,\n\t\"&lrm;\":                             true,\n\t\"&lrtri;\":                           true,\n\t\"&lsaquo;\":                          true,\n\t\"&lscr;\":                            true,\n\t\"&lsh;\":                             true,\n\t\"&lsim;\":                            true,\n\t\"&lsime;\":                           true,\n\t\"&lsimg;\":                           true,\n\t\"&lsqb;\":                            true,\n\t\"&lsquo;\":                           true,\n\t\"&lsquor;\":                          true,\n\t\"&lstrok;\":                          true,\n\t\"&lt\":                               true,\n\t\"&lt;\":                              true,\n\t\"&ltcc;\":                            true,\n\t\"&ltcir;\":                           true,\n\t\"&ltdot;\":                           true,\n\t\"&lthree;\":                          true,\n\t\"&ltimes;\":                          true,\n\t\"&ltlarr;\":                          true,\n\t\"&ltquest;\":                         true,\n\t\"&ltrPar;\":                          true,\n\t\"&ltri;\":                            true,\n\t\"&ltrie;\":                           true,\n\t\"&ltrif;\":                           true,\n\t\"&lurdshar;\":                        true,\n\t\"&luruhar;\":                         true,\n\t\"&lvertneqq;\":                       true,\n\t\"&lvnE;\":                            true,\n\t\"&mDDot;\":                           true,\n\t\"&macr\":                             true,\n\t\"&macr;\":                            true,\n\t\"&male;\":                            true,\n\t\"&malt;\":                            true,\n\t\"&maltese;\":                         true,\n\t\"&map;\":                             true,\n\t\"&mapsto;\":                          true,\n\t\"&mapstodown;\":                      true,\n\t\"&mapstoleft;\":                      true,\n\t\"&mapstoup;\":                        true,\n\t\"&marker;\":                          true,\n\t\"&mcomma;\":                          true,\n\t\"&mcy;\":                             true,\n\t\"&mdash;\":                           true,\n\t\"&measuredangle;\":                   true,\n\t\"&mfr;\":                             true,\n\t\"&mho;\":                             true,\n\t\"&micro\":                            true,\n\t\"&micro;\":                           true,\n\t\"&mid;\":                             true,\n\t\"&midast;\":                          true,\n\t\"&midcir;\":                          true,\n\t\"&middot\":                           true,\n\t\"&middot;\":                          true,\n\t\"&minus;\":                           true,\n\t\"&minusb;\":                          true,\n\t\"&minusd;\":                          true,\n\t\"&minusdu;\":                         true,\n\t\"&mlcp;\":                            true,\n\t\"&mldr;\":                            true,\n\t\"&mnplus;\":                          true,\n\t\"&models;\":                          true,\n\t\"&mopf;\":                            true,\n\t\"&mp;\":                              true,\n\t\"&mscr;\":                            true,\n\t\"&mstpos;\":                          true,\n\t\"&mu;\":                              true,\n\t\"&multimap;\":                        true,\n\t\"&mumap;\":                           true,\n\t\"&nGg;\":                             true,\n\t\"&nGt;\":                             true,\n\t\"&nGtv;\":                            true,\n\t\"&nLeftarrow;\":                      true,\n\t\"&nLeftrightarrow;\":                 true,\n\t\"&nLl;\":                             true,\n\t\"&nLt;\":                             true,\n\t\"&nLtv;\":                            true,\n\t\"&nRightarrow;\":                     true,\n\t\"&nVDash;\":                          true,\n\t\"&nVdash;\":                          true,\n\t\"&nabla;\":                           true,\n\t\"&nacute;\":                          true,\n\t\"&nang;\":                            true,\n\t\"&nap;\":                             true,\n\t\"&napE;\":                            true,\n\t\"&napid;\":                           true,\n\t\"&napos;\":                           true,\n\t\"&napprox;\":                         true,\n\t\"&natur;\":                           true,\n\t\"&natural;\":                         true,\n\t\"&naturals;\":                        true,\n\t\"&nbsp\":                             true,\n\t\"&nbsp;\":                            true,\n\t\"&nbump;\":                           true,\n\t\"&nbumpe;\":                          true,\n\t\"&ncap;\":                            true,\n\t\"&ncaron;\":                          true,\n\t\"&ncedil;\":                          true,\n\t\"&ncong;\":                           true,\n\t\"&ncongdot;\":                        true,\n\t\"&ncup;\":                            true,\n\t\"&ncy;\":                             true,\n\t\"&ndash;\":                           true,\n\t\"&ne;\":                              true,\n\t\"&neArr;\":                           true,\n\t\"&nearhk;\":                          true,\n\t\"&nearr;\":                           true,\n\t\"&nearrow;\":                         true,\n\t\"&nedot;\":                           true,\n\t\"&nequiv;\":                          true,\n\t\"&nesear;\":                          true,\n\t\"&nesim;\":                           true,\n\t\"&nexist;\":                          true,\n\t\"&nexists;\":                         true,\n\t\"&nfr;\":                             true,\n\t\"&ngE;\":                             true,\n\t\"&nge;\":                             true,\n\t\"&ngeq;\":                            true,\n\t\"&ngeqq;\":                           true,\n\t\"&ngeqslant;\":                       true,\n\t\"&nges;\":                            true,\n\t\"&ngsim;\":                           true,\n\t\"&ngt;\":                             true,\n\t\"&ngtr;\":                            true,\n\t\"&nhArr;\":                           true,\n\t\"&nharr;\":                           true,\n\t\"&nhpar;\":                           true,\n\t\"&ni;\":                              true,\n\t\"&nis;\":                             true,\n\t\"&nisd;\":                            true,\n\t\"&niv;\":                             true,\n\t\"&njcy;\":                            true,\n\t\"&nlArr;\":                           true,\n\t\"&nlE;\":                             true,\n\t\"&nlarr;\":                           true,\n\t\"&nldr;\":                            true,\n\t\"&nle;\":                             true,\n\t\"&nleftarrow;\":                      true,\n\t\"&nleftrightarrow;\":                 true,\n\t\"&nleq;\":                            true,\n\t\"&nleqq;\":                           true,\n\t\"&nleqslant;\":                       true,\n\t\"&nles;\":                            true,\n\t\"&nless;\":                           true,\n\t\"&nlsim;\":                           true,\n\t\"&nlt;\":                             true,\n\t\"&nltri;\":                           true,\n\t\"&nltrie;\":                          true,\n\t\"&nmid;\":                            true,\n\t\"&nopf;\":                            true,\n\t\"&not\":                              true,\n\t\"&not;\":                             true,\n\t\"&notin;\":                           true,\n\t\"&notinE;\":                          true,\n\t\"&notindot;\":                        true,\n\t\"&notinva;\":                         true,\n\t\"&notinvb;\":                         true,\n\t\"&notinvc;\":                         true,\n\t\"&notni;\":                           true,\n\t\"&notniva;\":                         true,\n\t\"&notnivb;\":                         true,\n\t\"&notnivc;\":                         true,\n\t\"&npar;\":                            true,\n\t\"&nparallel;\":                       true,\n\t\"&nparsl;\":                          true,\n\t\"&npart;\":                           true,\n\t\"&npolint;\":                         true,\n\t\"&npr;\":                             true,\n\t\"&nprcue;\":                          true,\n\t\"&npre;\":                            true,\n\t\"&nprec;\":                           true,\n\t\"&npreceq;\":                         true,\n\t\"&nrArr;\":                           true,\n\t\"&nrarr;\":                           true,\n\t\"&nrarrc;\":                          true,\n\t\"&nrarrw;\":                          true,\n\t\"&nrightarrow;\":                     true,\n\t\"&nrtri;\":                           true,\n\t\"&nrtrie;\":                          true,\n\t\"&nsc;\":                             true,\n\t\"&nsccue;\":                          true,\n\t\"&nsce;\":                            true,\n\t\"&nscr;\":                            true,\n\t\"&nshortmid;\":                       true,\n\t\"&nshortparallel;\":                  true,\n\t\"&nsim;\":                            true,\n\t\"&nsime;\":                           true,\n\t\"&nsimeq;\":                          true,\n\t\"&nsmid;\":                           true,\n\t\"&nspar;\":                           true,\n\t\"&nsqsube;\":                         true,\n\t\"&nsqsupe;\":                         true,\n\t\"&nsub;\":                            true,\n\t\"&nsubE;\":                           true,\n\t\"&nsube;\":                           true,\n\t\"&nsubset;\":                         true,\n\t\"&nsubseteq;\":                       true,\n\t\"&nsubseteqq;\":                      true,\n\t\"&nsucc;\":                           true,\n\t\"&nsucceq;\":                         true,\n\t\"&nsup;\":                            true,\n\t\"&nsupE;\":                           true,\n\t\"&nsupe;\":                           true,\n\t\"&nsupset;\":                         true,\n\t\"&nsupseteq;\":                       true,\n\t\"&nsupseteqq;\":                      true,\n\t\"&ntgl;\":                            true,\n\t\"&ntilde\":                           true,\n\t\"&ntilde;\":                          true,\n\t\"&ntlg;\":                            true,\n\t\"&ntriangleleft;\":                   true,\n\t\"&ntrianglelefteq;\":                 true,\n\t\"&ntriangleright;\":                  true,\n\t\"&ntrianglerighteq;\":                true,\n\t\"&nu;\":                              true,\n\t\"&num;\":                             true,\n\t\"&numero;\":                          true,\n\t\"&numsp;\":                           true,\n\t\"&nvDash;\":                          true,\n\t\"&nvHarr;\":                          true,\n\t\"&nvap;\":                            true,\n\t\"&nvdash;\":                          true,\n\t\"&nvge;\":                            true,\n\t\"&nvgt;\":                            true,\n\t\"&nvinfin;\":                         true,\n\t\"&nvlArr;\":                          true,\n\t\"&nvle;\":                            true,\n\t\"&nvlt;\":                            true,\n\t\"&nvltrie;\":                         true,\n\t\"&nvrArr;\":                          true,\n\t\"&nvrtrie;\":                         true,\n\t\"&nvsim;\":                           true,\n\t\"&nwArr;\":                           true,\n\t\"&nwarhk;\":                          true,\n\t\"&nwarr;\":                           true,\n\t\"&nwarrow;\":                         true,\n\t\"&nwnear;\":                          true,\n\t\"&oS;\":                              true,\n\t\"&oacute\":                           true,\n\t\"&oacute;\":                          true,\n\t\"&oast;\":                            true,\n\t\"&ocir;\":                            true,\n\t\"&ocirc\":                            true,\n\t\"&ocirc;\":                           true,\n\t\"&ocy;\":                             true,\n\t\"&odash;\":                           true,\n\t\"&odblac;\":                          true,\n\t\"&odiv;\":                            true,\n\t\"&odot;\":                            true,\n\t\"&odsold;\":                          true,\n\t\"&oelig;\":                           true,\n\t\"&ofcir;\":                           true,\n\t\"&ofr;\":                             true,\n\t\"&ogon;\":                            true,\n\t\"&ograve\":                           true,\n\t\"&ograve;\":                          true,\n\t\"&ogt;\":                             true,\n\t\"&ohbar;\":                           true,\n\t\"&ohm;\":                             true,\n\t\"&oint;\":                            true,\n\t\"&olarr;\":                           true,\n\t\"&olcir;\":                           true,\n\t\"&olcross;\":                         true,\n\t\"&oline;\":                           true,\n\t\"&olt;\":                             true,\n\t\"&omacr;\":                           true,\n\t\"&omega;\":                           true,\n\t\"&omicron;\":                         true,\n\t\"&omid;\":                            true,\n\t\"&ominus;\":                          true,\n\t\"&oopf;\":                            true,\n\t\"&opar;\":                            true,\n\t\"&operp;\":                           true,\n\t\"&oplus;\":                           true,\n\t\"&or;\":                              true,\n\t\"&orarr;\":                           true,\n\t\"&ord;\":                             true,\n\t\"&order;\":                           true,\n\t\"&orderof;\":                         true,\n\t\"&ordf\":                             true,\n\t\"&ordf;\":                            true,\n\t\"&ordm\":                             true,\n\t\"&ordm;\":                            true,\n\t\"&origof;\":                          true,\n\t\"&oror;\":                            true,\n\t\"&orslope;\":                         true,\n\t\"&orv;\":                             true,\n\t\"&oscr;\":                            true,\n\t\"&oslash\":                           true,\n\t\"&oslash;\":                          true,\n\t\"&osol;\":                            true,\n\t\"&otilde\":                           true,\n\t\"&otilde;\":                          true,\n\t\"&otimes;\":                          true,\n\t\"&otimesas;\":                        true,\n\t\"&ouml\":                             true,\n\t\"&ouml;\":                            true,\n\t\"&ovbar;\":                           true,\n\t\"&par;\":                             true,\n\t\"&para\":                             true,\n\t\"&para;\":                            true,\n\t\"&parallel;\":                        true,\n\t\"&parsim;\":                          true,\n\t\"&parsl;\":                           true,\n\t\"&part;\":                            true,\n\t\"&pcy;\":                             true,\n\t\"&percnt;\":                          true,\n\t\"&period;\":                          true,\n\t\"&permil;\":                          true,\n\t\"&perp;\":                            true,\n\t\"&pertenk;\":                         true,\n\t\"&pfr;\":                             true,\n\t\"&phi;\":                             true,\n\t\"&phiv;\":                            true,\n\t\"&phmmat;\":                          true,\n\t\"&phone;\":                           true,\n\t\"&pi;\":                              true,\n\t\"&pitchfork;\":                       true,\n\t\"&piv;\":                             true,\n\t\"&planck;\":                          true,\n\t\"&planckh;\":                         true,\n\t\"&plankv;\":                          true,\n\t\"&plus;\":                            true,\n\t\"&plusacir;\":                        true,\n\t\"&plusb;\":                           true,\n\t\"&pluscir;\":                         true,\n\t\"&plusdo;\":                          true,\n\t\"&plusdu;\":                          true,\n\t\"&pluse;\":                           true,\n\t\"&plusmn\":                           true,\n\t\"&plusmn;\":                          true,\n\t\"&plussim;\":                         true,\n\t\"&plustwo;\":                         true,\n\t\"&pm;\":                              true,\n\t\"&pointint;\":                        true,\n\t\"&popf;\":                            true,\n\t\"&pound\":                            true,\n\t\"&pound;\":                           true,\n\t\"&pr;\":                              true,\n\t\"&prE;\":                             true,\n\t\"&prap;\":                            true,\n\t\"&prcue;\":                           true,\n\t\"&pre;\":                             true,\n\t\"&prec;\":                            true,\n\t\"&precapprox;\":                      true,\n\t\"&preccurlyeq;\":                     true,\n\t\"&preceq;\":                          true,\n\t\"&precnapprox;\":                     true,\n\t\"&precneqq;\":                        true,\n\t\"&precnsim;\":                        true,\n\t\"&precsim;\":                         true,\n\t\"&prime;\":                           true,\n\t\"&primes;\":                          true,\n\t\"&prnE;\":                            true,\n\t\"&prnap;\":                           true,\n\t\"&prnsim;\":                          true,\n\t\"&prod;\":                            true,\n\t\"&profalar;\":                        true,\n\t\"&profline;\":                        true,\n\t\"&profsurf;\":                        true,\n\t\"&prop;\":                            true,\n\t\"&propto;\":                          true,\n\t\"&prsim;\":                           true,\n\t\"&prurel;\":                          true,\n\t\"&pscr;\":                            true,\n\t\"&psi;\":                             true,\n\t\"&puncsp;\":                          true,\n\t\"&qfr;\":                             true,\n\t\"&qint;\":                            true,\n\t\"&qopf;\":                            true,\n\t\"&qprime;\":                          true,\n\t\"&qscr;\":                            true,\n\t\"&quaternions;\":                     true,\n\t\"&quatint;\":                         true,\n\t\"&quest;\":                           true,\n\t\"&questeq;\":                         true,\n\t\"&quot\":                             true,\n\t\"&quot;\":                            true,\n\t\"&rAarr;\":                           true,\n\t\"&rArr;\":                            true,\n\t\"&rAtail;\":                          true,\n\t\"&rBarr;\":                           true,\n\t\"&rHar;\":                            true,\n\t\"&race;\":                            true,\n\t\"&racute;\":                          true,\n\t\"&radic;\":                           true,\n\t\"&raemptyv;\":                        true,\n\t\"&rang;\":                            true,\n\t\"&rangd;\":                           true,\n\t\"&range;\":                           true,\n\t\"&rangle;\":                          true,\n\t\"&raquo\":                            true,\n\t\"&raquo;\":                           true,\n\t\"&rarr;\":                            true,\n\t\"&rarrap;\":                          true,\n\t\"&rarrb;\":                           true,\n\t\"&rarrbfs;\":                         true,\n\t\"&rarrc;\":                           true,\n\t\"&rarrfs;\":                          true,\n\t\"&rarrhk;\":                          true,\n\t\"&rarrlp;\":                          true,\n\t\"&rarrpl;\":                          true,\n\t\"&rarrsim;\":                         true,\n\t\"&rarrtl;\":                          true,\n\t\"&rarrw;\":                           true,\n\t\"&ratail;\":                          true,\n\t\"&ratio;\":                           true,\n\t\"&rationals;\":                       true,\n\t\"&rbarr;\":                           true,\n\t\"&rbbrk;\":                           true,\n\t\"&rbrace;\":                          true,\n\t\"&rbrack;\":                          true,\n\t\"&rbrke;\":                           true,\n\t\"&rbrksld;\":                         true,\n\t\"&rbrkslu;\":                         true,\n\t\"&rcaron;\":                          true,\n\t\"&rcedil;\":                          true,\n\t\"&rceil;\":                           true,\n\t\"&rcub;\":                            true,\n\t\"&rcy;\":                             true,\n\t\"&rdca;\":                            true,\n\t\"&rdldhar;\":                         true,\n\t\"&rdquo;\":                           true,\n\t\"&rdquor;\":                          true,\n\t\"&rdsh;\":                            true,\n\t\"&real;\":                            true,\n\t\"&realine;\":                         true,\n\t\"&realpart;\":                        true,\n\t\"&reals;\":                           true,\n\t\"&rect;\":                            true,\n\t\"&reg\":                              true,\n\t\"&reg;\":                             true,\n\t\"&rfisht;\":                          true,\n\t\"&rfloor;\":                          true,\n\t\"&rfr;\":                             true,\n\t\"&rhard;\":                           true,\n\t\"&rharu;\":                           true,\n\t\"&rharul;\":                          true,\n\t\"&rho;\":                             true,\n\t\"&rhov;\":                            true,\n\t\"&rightarrow;\":                      true,\n\t\"&rightarrowtail;\":                  true,\n\t\"&rightharpoondown;\":                true,\n\t\"&rightharpoonup;\":                  true,\n\t\"&rightleftarrows;\":                 true,\n\t\"&rightleftharpoons;\":               true,\n\t\"&rightrightarrows;\":                true,\n\t\"&rightsquigarrow;\":                 true,\n\t\"&rightthreetimes;\":                 true,\n\t\"&ring;\":                            true,\n\t\"&risingdotseq;\":                    true,\n\t\"&rlarr;\":                           true,\n\t\"&rlhar;\":                           true,\n\t\"&rlm;\":                             true,\n\t\"&rmoust;\":                          true,\n\t\"&rmoustache;\":                      true,\n\t\"&rnmid;\":                           true,\n\t\"&roang;\":                           true,\n\t\"&roarr;\":                           true,\n\t\"&robrk;\":                           true,\n\t\"&ropar;\":                           true,\n\t\"&ropf;\":                            true,\n\t\"&roplus;\":                          true,\n\t\"&rotimes;\":                         true,\n\t\"&rpar;\":                            true,\n\t\"&rpargt;\":                          true,\n\t\"&rppolint;\":                        true,\n\t\"&rrarr;\":                           true,\n\t\"&rsaquo;\":                          true,\n\t\"&rscr;\":                            true,\n\t\"&rsh;\":                             true,\n\t\"&rsqb;\":                            true,\n\t\"&rsquo;\":                           true,\n\t\"&rsquor;\":                          true,\n\t\"&rthree;\":                          true,\n\t\"&rtimes;\":                          true,\n\t\"&rtri;\":                            true,\n\t\"&rtrie;\":                           true,\n\t\"&rtrif;\":                           true,\n\t\"&rtriltri;\":                        true,\n\t\"&ruluhar;\":                         true,\n\t\"&rx;\":                              true,\n\t\"&sacute;\":                          true,\n\t\"&sbquo;\":                           true,\n\t\"&sc;\":                              true,\n\t\"&scE;\":                             true,\n\t\"&scap;\":                            true,\n\t\"&scaron;\":                          true,\n\t\"&sccue;\":                           true,\n\t\"&sce;\":                             true,\n\t\"&scedil;\":                          true,\n\t\"&scirc;\":                           true,\n\t\"&scnE;\":                            true,\n\t\"&scnap;\":                           true,\n\t\"&scnsim;\":                          true,\n\t\"&scpolint;\":                        true,\n\t\"&scsim;\":                           true,\n\t\"&scy;\":                             true,\n\t\"&sdot;\":                            true,\n\t\"&sdotb;\":                           true,\n\t\"&sdote;\":                           true,\n\t\"&seArr;\":                           true,\n\t\"&searhk;\":                          true,\n\t\"&searr;\":                           true,\n\t\"&searrow;\":                         true,\n\t\"&sect\":                             true,\n\t\"&sect;\":                            true,\n\t\"&semi;\":                            true,\n\t\"&seswar;\":                          true,\n\t\"&setminus;\":                        true,\n\t\"&setmn;\":                           true,\n\t\"&sext;\":                            true,\n\t\"&sfr;\":                             true,\n\t\"&sfrown;\":                          true,\n\t\"&sharp;\":                           true,\n\t\"&shchcy;\":                          true,\n\t\"&shcy;\":                            true,\n\t\"&shortmid;\":                        true,\n\t\"&shortparallel;\":                   true,\n\t\"&shy\":                              true,\n\t\"&shy;\":                             true,\n\t\"&sigma;\":                           true,\n\t\"&sigmaf;\":                          true,\n\t\"&sigmav;\":                          true,\n\t\"&sim;\":                             true,\n\t\"&simdot;\":                          true,\n\t\"&sime;\":                            true,\n\t\"&simeq;\":                           true,\n\t\"&simg;\":                            true,\n\t\"&simgE;\":                           true,\n\t\"&siml;\":                            true,\n\t\"&simlE;\":                           true,\n\t\"&simne;\":                           true,\n\t\"&simplus;\":                         true,\n\t\"&simrarr;\":                         true,\n\t\"&slarr;\":                           true,\n\t\"&smallsetminus;\":                   true,\n\t\"&smashp;\":                          true,\n\t\"&smeparsl;\":                        true,\n\t\"&smid;\":                            true,\n\t\"&smile;\":                           true,\n\t\"&smt;\":                             true,\n\t\"&smte;\":                            true,\n\t\"&smtes;\":                           true,\n\t\"&softcy;\":                          true,\n\t\"&sol;\":                             true,\n\t\"&solb;\":                            true,\n\t\"&solbar;\":                          true,\n\t\"&sopf;\":                            true,\n\t\"&spades;\":                          true,\n\t\"&spadesuit;\":                       true,\n\t\"&spar;\":                            true,\n\t\"&sqcap;\":                           true,\n\t\"&sqcaps;\":                          true,\n\t\"&sqcup;\":                           true,\n\t\"&sqcups;\":                          true,\n\t\"&sqsub;\":                           true,\n\t\"&sqsube;\":                          true,\n\t\"&sqsubset;\":                        true,\n\t\"&sqsubseteq;\":                      true,\n\t\"&sqsup;\":                           true,\n\t\"&sqsupe;\":                          true,\n\t\"&sqsupset;\":                        true,\n\t\"&sqsupseteq;\":                      true,\n\t\"&squ;\":                             true,\n\t\"&square;\":                          true,\n\t\"&squarf;\":                          true,\n\t\"&squf;\":                            true,\n\t\"&srarr;\":                           true,\n\t\"&sscr;\":                            true,\n\t\"&ssetmn;\":                          true,\n\t\"&ssmile;\":                          true,\n\t\"&sstarf;\":                          true,\n\t\"&star;\":                            true,\n\t\"&starf;\":                           true,\n\t\"&straightepsilon;\":                 true,\n\t\"&straightphi;\":                     true,\n\t\"&strns;\":                           true,\n\t\"&sub;\":                             true,\n\t\"&subE;\":                            true,\n\t\"&subdot;\":                          true,\n\t\"&sube;\":                            true,\n\t\"&subedot;\":                         true,\n\t\"&submult;\":                         true,\n\t\"&subnE;\":                           true,\n\t\"&subne;\":                           true,\n\t\"&subplus;\":                         true,\n\t\"&subrarr;\":                         true,\n\t\"&subset;\":                          true,\n\t\"&subseteq;\":                        true,\n\t\"&subseteqq;\":                       true,\n\t\"&subsetneq;\":                       true,\n\t\"&subsetneqq;\":                      true,\n\t\"&subsim;\":                          true,\n\t\"&subsub;\":                          true,\n\t\"&subsup;\":                          true,\n\t\"&succ;\":                            true,\n\t\"&succapprox;\":                      true,\n\t\"&succcurlyeq;\":                     true,\n\t\"&succeq;\":                          true,\n\t\"&succnapprox;\":                     true,\n\t\"&succneqq;\":                        true,\n\t\"&succnsim;\":                        true,\n\t\"&succsim;\":                         true,\n\t\"&sum;\":                             true,\n\t\"&sung;\":                            true,\n\t\"&sup1\":                             true,\n\t\"&sup1;\":                            true,\n\t\"&sup2\":                             true,\n\t\"&sup2;\":                            true,\n\t\"&sup3\":                             true,\n\t\"&sup3;\":                            true,\n\t\"&sup;\":                             true,\n\t\"&supE;\":                            true,\n\t\"&supdot;\":                          true,\n\t\"&supdsub;\":                         true,\n\t\"&supe;\":                            true,\n\t\"&supedot;\":                         true,\n\t\"&suphsol;\":                         true,\n\t\"&suphsub;\":                         true,\n\t\"&suplarr;\":                         true,\n\t\"&supmult;\":                         true,\n\t\"&supnE;\":                           true,\n\t\"&supne;\":                           true,\n\t\"&supplus;\":                         true,\n\t\"&supset;\":                          true,\n\t\"&supseteq;\":                        true,\n\t\"&supseteqq;\":                       true,\n\t\"&supsetneq;\":                       true,\n\t\"&supsetneqq;\":                      true,\n\t\"&supsim;\":                          true,\n\t\"&supsub;\":                          true,\n\t\"&supsup;\":                          true,\n\t\"&swArr;\":                           true,\n\t\"&swarhk;\":                          true,\n\t\"&swarr;\":                           true,\n\t\"&swarrow;\":                         true,\n\t\"&swnwar;\":                          true,\n\t\"&szlig\":                            true,\n\t\"&szlig;\":                           true,\n\t\"&target;\":                          true,\n\t\"&tau;\":                             true,\n\t\"&tbrk;\":                            true,\n\t\"&tcaron;\":                          true,\n\t\"&tcedil;\":                          true,\n\t\"&tcy;\":                             true,\n\t\"&tdot;\":                            true,\n\t\"&telrec;\":                          true,\n\t\"&tfr;\":                             true,\n\t\"&there4;\":                          true,\n\t\"&therefore;\":                       true,\n\t\"&theta;\":                           true,\n\t\"&thetasym;\":                        true,\n\t\"&thetav;\":                          true,\n\t\"&thickapprox;\":                     true,\n\t\"&thicksim;\":                        true,\n\t\"&thinsp;\":                          true,\n\t\"&thkap;\":                           true,\n\t\"&thksim;\":                          true,\n\t\"&thorn\":                            true,\n\t\"&thorn;\":                           true,\n\t\"&tilde;\":                           true,\n\t\"&times\":                            true,\n\t\"&times;\":                           true,\n\t\"&timesb;\":                          true,\n\t\"&timesbar;\":                        true,\n\t\"&timesd;\":                          true,\n\t\"&tint;\":                            true,\n\t\"&toea;\":                            true,\n\t\"&top;\":                             true,\n\t\"&topbot;\":                          true,\n\t\"&topcir;\":                          true,\n\t\"&topf;\":                            true,\n\t\"&topfork;\":                         true,\n\t\"&tosa;\":                            true,\n\t\"&tprime;\":                          true,\n\t\"&trade;\":                           true,\n\t\"&triangle;\":                        true,\n\t\"&triangledown;\":                    true,\n\t\"&triangleleft;\":                    true,\n\t\"&trianglelefteq;\":                  true,\n\t\"&triangleq;\":                       true,\n\t\"&triangleright;\":                   true,\n\t\"&trianglerighteq;\":                 true,\n\t\"&tridot;\":                          true,\n\t\"&trie;\":                            true,\n\t\"&triminus;\":                        true,\n\t\"&triplus;\":                         true,\n\t\"&trisb;\":                           true,\n\t\"&tritime;\":                         true,\n\t\"&trpezium;\":                        true,\n\t\"&tscr;\":                            true,\n\t\"&tscy;\":                            true,\n\t\"&tshcy;\":                           true,\n\t\"&tstrok;\":                          true,\n\t\"&twixt;\":                           true,\n\t\"&twoheadleftarrow;\":                true,\n\t\"&twoheadrightarrow;\":               true,\n\t\"&uArr;\":                            true,\n\t\"&uHar;\":                            true,\n\t\"&uacute\":                           true,\n\t\"&uacute;\":                          true,\n\t\"&uarr;\":                            true,\n\t\"&ubrcy;\":                           true,\n\t\"&ubreve;\":                          true,\n\t\"&ucirc\":                            true,\n\t\"&ucirc;\":                           true,\n\t\"&ucy;\":                             true,\n\t\"&udarr;\":                           true,\n\t\"&udblac;\":                          true,\n\t\"&udhar;\":                           true,\n\t\"&ufisht;\":                          true,\n\t\"&ufr;\":                             true,\n\t\"&ugrave\":                           true,\n\t\"&ugrave;\":                          true,\n\t\"&uharl;\":                           true,\n\t\"&uharr;\":                           true,\n\t\"&uhblk;\":                           true,\n\t\"&ulcorn;\":                          true,\n\t\"&ulcorner;\":                        true,\n\t\"&ulcrop;\":                          true,\n\t\"&ultri;\":                           true,\n\t\"&umacr;\":                           true,\n\t\"&uml\":                              true,\n\t\"&uml;\":                             true,\n\t\"&uogon;\":                           true,\n\t\"&uopf;\":                            true,\n\t\"&uparrow;\":                         true,\n\t\"&updownarrow;\":                     true,\n\t\"&upharpoonleft;\":                   true,\n\t\"&upharpoonright;\":                  true,\n\t\"&uplus;\":                           true,\n\t\"&upsi;\":                            true,\n\t\"&upsih;\":                           true,\n\t\"&upsilon;\":                         true,\n\t\"&upuparrows;\":                      true,\n\t\"&urcorn;\":                          true,\n\t\"&urcorner;\":                        true,\n\t\"&urcrop;\":                          true,\n\t\"&uring;\":                           true,\n\t\"&urtri;\":                           true,\n\t\"&uscr;\":                            true,\n\t\"&utdot;\":                           true,\n\t\"&utilde;\":                          true,\n\t\"&utri;\":                            true,\n\t\"&utrif;\":                           true,\n\t\"&uuarr;\":                           true,\n\t\"&uuml\":                             true,\n\t\"&uuml;\":                            true,\n\t\"&uwangle;\":                         true,\n\t\"&vArr;\":                            true,\n\t\"&vBar;\":                            true,\n\t\"&vBarv;\":                           true,\n\t\"&vDash;\":                           true,\n\t\"&vangrt;\":                          true,\n\t\"&varepsilon;\":                      true,\n\t\"&varkappa;\":                        true,\n\t\"&varnothing;\":                      true,\n\t\"&varphi;\":                          true,\n\t\"&varpi;\":                           true,\n\t\"&varpropto;\":                       true,\n\t\"&varr;\":                            true,\n\t\"&varrho;\":                          true,\n\t\"&varsigma;\":                        true,\n\t\"&varsubsetneq;\":                    true,\n\t\"&varsubsetneqq;\":                   true,\n\t\"&varsupsetneq;\":                    true,\n\t\"&varsupsetneqq;\":                   true,\n\t\"&vartheta;\":                        true,\n\t\"&vartriangleleft;\":                 true,\n\t\"&vartriangleright;\":                true,\n\t\"&vcy;\":                             true,\n\t\"&vdash;\":                           true,\n\t\"&vee;\":                             true,\n\t\"&veebar;\":                          true,\n\t\"&veeeq;\":                           true,\n\t\"&vellip;\":                          true,\n\t\"&verbar;\":                          true,\n\t\"&vert;\":                            true,\n\t\"&vfr;\":                             true,\n\t\"&vltri;\":                           true,\n\t\"&vnsub;\":                           true,\n\t\"&vnsup;\":                           true,\n\t\"&vopf;\":                            true,\n\t\"&vprop;\":                           true,\n\t\"&vrtri;\":                           true,\n\t\"&vscr;\":                            true,\n\t\"&vsubnE;\":                          true,\n\t\"&vsubne;\":                          true,\n\t\"&vsupnE;\":                          true,\n\t\"&vsupne;\":                          true,\n\t\"&vzigzag;\":                         true,\n\t\"&wcirc;\":                           true,\n\t\"&wedbar;\":                          true,\n\t\"&wedge;\":                           true,\n\t\"&wedgeq;\":                          true,\n\t\"&weierp;\":                          true,\n\t\"&wfr;\":                             true,\n\t\"&wopf;\":                            true,\n\t\"&wp;\":                              true,\n\t\"&wr;\":                              true,\n\t\"&wreath;\":                          true,\n\t\"&wscr;\":                            true,\n\t\"&xcap;\":                            true,\n\t\"&xcirc;\":                           true,\n\t\"&xcup;\":                            true,\n\t\"&xdtri;\":                           true,\n\t\"&xfr;\":                             true,\n\t\"&xhArr;\":                           true,\n\t\"&xharr;\":                           true,\n\t\"&xi;\":                              true,\n\t\"&xlArr;\":                           true,\n\t\"&xlarr;\":                           true,\n\t\"&xmap;\":                            true,\n\t\"&xnis;\":                            true,\n\t\"&xodot;\":                           true,\n\t\"&xopf;\":                            true,\n\t\"&xoplus;\":                          true,\n\t\"&xotime;\":                          true,\n\t\"&xrArr;\":                           true,\n\t\"&xrarr;\":                           true,\n\t\"&xscr;\":                            true,\n\t\"&xsqcup;\":                          true,\n\t\"&xuplus;\":                          true,\n\t\"&xutri;\":                           true,\n\t\"&xvee;\":                            true,\n\t\"&xwedge;\":                          true,\n\t\"&yacute\":                           true,\n\t\"&yacute;\":                          true,\n\t\"&yacy;\":                            true,\n\t\"&ycirc;\":                           true,\n\t\"&ycy;\":                             true,\n\t\"&yen\":                              true,\n\t\"&yen;\":                             true,\n\t\"&yfr;\":                             true,\n\t\"&yicy;\":                            true,\n\t\"&yopf;\":                            true,\n\t\"&yscr;\":                            true,\n\t\"&yucy;\":                            true,\n\t\"&yuml\":                             true,\n\t\"&yuml;\":                            true,\n\t\"&zacute;\":                          true,\n\t\"&zcaron;\":                          true,\n\t\"&zcy;\":                             true,\n\t\"&zdot;\":                            true,\n\t\"&zeetrf;\":                          true,\n\t\"&zeta;\":                            true,\n\t\"&zfr;\":                             true,\n\t\"&zhcy;\":                            true,\n\t\"&zigrarr;\":                         true,\n\t\"&zopf;\":                            true,\n\t\"&zscr;\":                            true,\n\t\"&zwj;\":                             true,\n\t\"&zwnj;\":                            true,\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/esc.go",
    "content": "package blackfriday\n\nimport (\n\t\"html\"\n\t\"io\"\n)\n\nvar htmlEscaper = [256][]byte{\n\t'&': []byte(\"&amp;\"),\n\t'<': []byte(\"&lt;\"),\n\t'>': []byte(\"&gt;\"),\n\t'\"': []byte(\"&quot;\"),\n}\n\nfunc escapeHTML(w io.Writer, s []byte) {\n\tescapeEntities(w, s, false)\n}\n\nfunc escapeAllHTML(w io.Writer, s []byte) {\n\tescapeEntities(w, s, true)\n}\n\nfunc escapeEntities(w io.Writer, s []byte, escapeValidEntities bool) {\n\tvar start, end int\n\tfor end < len(s) {\n\t\tescSeq := htmlEscaper[s[end]]\n\t\tif escSeq != nil {\n\t\t\tisEntity, entityEnd := nodeIsEntity(s, end)\n\t\t\tif isEntity && !escapeValidEntities {\n\t\t\t\tw.Write(s[start : entityEnd+1])\n\t\t\t\tstart = entityEnd + 1\n\t\t\t} else {\n\t\t\t\tw.Write(s[start:end])\n\t\t\t\tw.Write(escSeq)\n\t\t\t\tstart = end + 1\n\t\t\t}\n\t\t}\n\t\tend++\n\t}\n\tif start < len(s) && end <= len(s) {\n\t\tw.Write(s[start:end])\n\t}\n}\n\nfunc nodeIsEntity(s []byte, end int) (isEntity bool, endEntityPos int) {\n\tisEntity = false\n\tendEntityPos = end + 1\n\n\tif s[end] == '&' {\n\t\tfor endEntityPos < len(s) {\n\t\t\tif s[endEntityPos] == ';' {\n\t\t\t\tif entities[string(s[end:endEntityPos+1])] {\n\t\t\t\t\tisEntity = true\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !isalnum(s[endEntityPos]) && s[endEntityPos] != '&' && s[endEntityPos] != '#' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tendEntityPos++\n\t\t}\n\t}\n\n\treturn isEntity, endEntityPos\n}\n\nfunc escLink(w io.Writer, text []byte) {\n\tunesc := html.UnescapeString(string(text))\n\tescapeHTML(w, []byte(unesc))\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/html.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n//\n// HTML rendering backend\n//\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"regexp\"\n\t\"strings\"\n)\n\n// HTMLFlags control optional behavior of HTML renderer.\ntype HTMLFlags int\n\n// HTML renderer configuration options.\nconst (\n\tHTMLFlagsNone           HTMLFlags = 0\n\tSkipHTML                HTMLFlags = 1 << iota // Skip preformatted HTML blocks\n\tSkipImages                                    // Skip embedded images\n\tSkipLinks                                     // Skip all links\n\tSafelink                                      // Only link to trusted protocols\n\tNofollowLinks                                 // Only link with rel=\"nofollow\"\n\tNoreferrerLinks                               // Only link with rel=\"noreferrer\"\n\tNoopenerLinks                                 // Only link with rel=\"noopener\"\n\tHrefTargetBlank                               // Add a blank target\n\tCompletePage                                  // Generate a complete HTML page\n\tUseXHTML                                      // Generate XHTML output instead of HTML\n\tFootnoteReturnLinks                           // Generate a link at the end of a footnote to return to the source\n\tSmartypants                                   // Enable smart punctuation substitutions\n\tSmartypantsFractions                          // Enable smart fractions (with Smartypants)\n\tSmartypantsDashes                             // Enable smart dashes (with Smartypants)\n\tSmartypantsLatexDashes                        // Enable LaTeX-style dashes (with Smartypants)\n\tSmartypantsAngledQuotes                       // Enable angled double quotes (with Smartypants) for double quotes rendering\n\tSmartypantsQuotesNBSP                         // Enable « French guillemets » (with Smartypants)\n\tTOC                                           // Generate a table of contents\n)\n\nvar (\n\thtmlTagRe = regexp.MustCompile(\"(?i)^\" + htmlTag)\n)\n\nconst (\n\thtmlTag = \"(?:\" + openTag + \"|\" + closeTag + \"|\" + htmlComment + \"|\" +\n\t\tprocessingInstruction + \"|\" + declaration + \"|\" + cdata + \")\"\n\tcloseTag              = \"</\" + tagName + \"\\\\s*[>]\"\n\topenTag               = \"<\" + tagName + attribute + \"*\" + \"\\\\s*/?>\"\n\tattribute             = \"(?:\" + \"\\\\s+\" + attributeName + attributeValueSpec + \"?)\"\n\tattributeValue        = \"(?:\" + unquotedValue + \"|\" + singleQuotedValue + \"|\" + doubleQuotedValue + \")\"\n\tattributeValueSpec    = \"(?:\" + \"\\\\s*=\" + \"\\\\s*\" + attributeValue + \")\"\n\tattributeName         = \"[a-zA-Z_:][a-zA-Z0-9:._-]*\"\n\tcdata                 = \"<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>\"\n\tdeclaration           = \"<![A-Z]+\" + \"\\\\s+[^>]*>\"\n\tdoubleQuotedValue     = \"\\\"[^\\\"]*\\\"\"\n\thtmlComment           = \"<!---->|<!--(?:-?[^>-])(?:-?[^-])*-->\"\n\tprocessingInstruction = \"[<][?].*?[?][>]\"\n\tsingleQuotedValue     = \"'[^']*'\"\n\ttagName               = \"[A-Za-z][A-Za-z0-9-]*\"\n\tunquotedValue         = \"[^\\\"'=<>`\\\\x00-\\\\x20]+\"\n)\n\n// HTMLRendererParameters is a collection of supplementary parameters tweaking\n// the behavior of various parts of HTML renderer.\ntype HTMLRendererParameters struct {\n\t// Prepend this text to each relative URL.\n\tAbsolutePrefix string\n\t// Add this text to each footnote anchor, to ensure uniqueness.\n\tFootnoteAnchorPrefix string\n\t// Show this text inside the <a> tag for a footnote return link, if the\n\t// HTML_FOOTNOTE_RETURN_LINKS flag is enabled. If blank, the string\n\t// <sup>[return]</sup> is used.\n\tFootnoteReturnLinkContents string\n\t// If set, add this text to the front of each Heading ID, to ensure\n\t// uniqueness.\n\tHeadingIDPrefix string\n\t// If set, add this text to the back of each Heading ID, to ensure uniqueness.\n\tHeadingIDSuffix string\n\t// Increase heading levels: if the offset is 1, <h1> becomes <h2> etc.\n\t// Negative offset is also valid.\n\t// Resulting levels are clipped between 1 and 6.\n\tHeadingLevelOffset int\n\n\tTitle string // Document title (used if CompletePage is set)\n\tCSS   string // Optional CSS file URL (used if CompletePage is set)\n\tIcon  string // Optional icon file URL (used if CompletePage is set)\n\n\tFlags HTMLFlags // Flags allow customizing this renderer's behavior\n}\n\n// HTMLRenderer is a type that implements the Renderer interface for HTML output.\n//\n// Do not create this directly, instead use the NewHTMLRenderer function.\ntype HTMLRenderer struct {\n\tHTMLRendererParameters\n\n\tcloseTag string // how to end singleton tags: either \" />\" or \">\"\n\n\t// Track heading IDs to prevent ID collision in a single generation.\n\theadingIDs map[string]int\n\n\tlastOutputLen int\n\tdisableTags   int\n\n\tsr *SPRenderer\n}\n\nconst (\n\txhtmlClose = \" />\"\n\thtmlClose  = \">\"\n)\n\n// NewHTMLRenderer creates and configures an HTMLRenderer object, which\n// satisfies the Renderer interface.\nfunc NewHTMLRenderer(params HTMLRendererParameters) *HTMLRenderer {\n\t// configure the rendering engine\n\tcloseTag := htmlClose\n\tif params.Flags&UseXHTML != 0 {\n\t\tcloseTag = xhtmlClose\n\t}\n\n\tif params.FootnoteReturnLinkContents == \"\" {\n\t\t// U+FE0E is VARIATION SELECTOR-15.\n\t\t// It suppresses automatic emoji presentation of the preceding\n\t\t// U+21A9 LEFTWARDS ARROW WITH HOOK on iOS and iPadOS.\n\t\tparams.FootnoteReturnLinkContents = \"<span aria-label='Return'>↩\\ufe0e</span>\"\n\t}\n\n\treturn &HTMLRenderer{\n\t\tHTMLRendererParameters: params,\n\n\t\tcloseTag:   closeTag,\n\t\theadingIDs: make(map[string]int),\n\n\t\tsr: NewSmartypantsRenderer(params.Flags),\n\t}\n}\n\nfunc isHTMLTag(tag []byte, tagname string) bool {\n\tfound, _ := findHTMLTagPos(tag, tagname)\n\treturn found\n}\n\n// Look for a character, but ignore it when it's in any kind of quotes, it\n// might be JavaScript\nfunc skipUntilCharIgnoreQuotes(html []byte, start int, char byte) int {\n\tinSingleQuote := false\n\tinDoubleQuote := false\n\tinGraveQuote := false\n\ti := start\n\tfor i < len(html) {\n\t\tswitch {\n\t\tcase html[i] == char && !inSingleQuote && !inDoubleQuote && !inGraveQuote:\n\t\t\treturn i\n\t\tcase html[i] == '\\'':\n\t\t\tinSingleQuote = !inSingleQuote\n\t\tcase html[i] == '\"':\n\t\t\tinDoubleQuote = !inDoubleQuote\n\t\tcase html[i] == '`':\n\t\t\tinGraveQuote = !inGraveQuote\n\t\t}\n\t\ti++\n\t}\n\treturn start\n}\n\nfunc findHTMLTagPos(tag []byte, tagname string) (bool, int) {\n\ti := 0\n\tif i < len(tag) && tag[0] != '<' {\n\t\treturn false, -1\n\t}\n\ti++\n\ti = skipSpace(tag, i)\n\n\tif i < len(tag) && tag[i] == '/' {\n\t\ti++\n\t}\n\n\ti = skipSpace(tag, i)\n\tj := 0\n\tfor ; i < len(tag); i, j = i+1, j+1 {\n\t\tif j >= len(tagname) {\n\t\t\tbreak\n\t\t}\n\n\t\tif strings.ToLower(string(tag[i]))[0] != tagname[j] {\n\t\t\treturn false, -1\n\t\t}\n\t}\n\n\tif i == len(tag) {\n\t\treturn false, -1\n\t}\n\n\trightAngle := skipUntilCharIgnoreQuotes(tag, i, '>')\n\tif rightAngle >= i {\n\t\treturn true, rightAngle\n\t}\n\n\treturn false, -1\n}\n\nfunc skipSpace(tag []byte, i int) int {\n\tfor i < len(tag) && isspace(tag[i]) {\n\t\ti++\n\t}\n\treturn i\n}\n\nfunc isRelativeLink(link []byte) (yes bool) {\n\t// a tag begin with '#'\n\tif link[0] == '#' {\n\t\treturn true\n\t}\n\n\t// link begin with '/' but not '//', the second maybe a protocol relative link\n\tif len(link) >= 2 && link[0] == '/' && link[1] != '/' {\n\t\treturn true\n\t}\n\n\t// only the root '/'\n\tif len(link) == 1 && link[0] == '/' {\n\t\treturn true\n\t}\n\n\t// current directory : begin with \"./\"\n\tif bytes.HasPrefix(link, []byte(\"./\")) {\n\t\treturn true\n\t}\n\n\t// parent directory : begin with \"../\"\n\tif bytes.HasPrefix(link, []byte(\"../\")) {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\nfunc (r *HTMLRenderer) ensureUniqueHeadingID(id string) string {\n\tfor count, found := r.headingIDs[id]; found; count, found = r.headingIDs[id] {\n\t\ttmp := fmt.Sprintf(\"%s-%d\", id, count+1)\n\n\t\tif _, tmpFound := r.headingIDs[tmp]; !tmpFound {\n\t\t\tr.headingIDs[id] = count + 1\n\t\t\tid = tmp\n\t\t} else {\n\t\t\tid = id + \"-1\"\n\t\t}\n\t}\n\n\tif _, found := r.headingIDs[id]; !found {\n\t\tr.headingIDs[id] = 0\n\t}\n\n\treturn id\n}\n\nfunc (r *HTMLRenderer) addAbsPrefix(link []byte) []byte {\n\tif r.AbsolutePrefix != \"\" && isRelativeLink(link) && link[0] != '.' {\n\t\tnewDest := r.AbsolutePrefix\n\t\tif link[0] != '/' {\n\t\t\tnewDest += \"/\"\n\t\t}\n\t\tnewDest += string(link)\n\t\treturn []byte(newDest)\n\t}\n\treturn link\n}\n\nfunc appendLinkAttrs(attrs []string, flags HTMLFlags, link []byte) []string {\n\tif isRelativeLink(link) {\n\t\treturn attrs\n\t}\n\tval := []string{}\n\tif flags&NofollowLinks != 0 {\n\t\tval = append(val, \"nofollow\")\n\t}\n\tif flags&NoreferrerLinks != 0 {\n\t\tval = append(val, \"noreferrer\")\n\t}\n\tif flags&NoopenerLinks != 0 {\n\t\tval = append(val, \"noopener\")\n\t}\n\tif flags&HrefTargetBlank != 0 {\n\t\tattrs = append(attrs, \"target=\\\"_blank\\\"\")\n\t}\n\tif len(val) == 0 {\n\t\treturn attrs\n\t}\n\tattr := fmt.Sprintf(\"rel=%q\", strings.Join(val, \" \"))\n\treturn append(attrs, attr)\n}\n\nfunc isMailto(link []byte) bool {\n\treturn bytes.HasPrefix(link, []byte(\"mailto:\"))\n}\n\nfunc needSkipLink(flags HTMLFlags, dest []byte) bool {\n\tif flags&SkipLinks != 0 {\n\t\treturn true\n\t}\n\treturn flags&Safelink != 0 && !isSafeLink(dest) && !isMailto(dest)\n}\n\nfunc isSmartypantable(node *Node) bool {\n\tpt := node.Parent.Type\n\treturn pt != Link && pt != CodeBlock && pt != Code\n}\n\nfunc appendLanguageAttr(attrs []string, info []byte) []string {\n\tif len(info) == 0 {\n\t\treturn attrs\n\t}\n\tendOfLang := bytes.IndexAny(info, \"\\t \")\n\tif endOfLang < 0 {\n\t\tendOfLang = len(info)\n\t}\n\treturn append(attrs, fmt.Sprintf(\"class=\\\"language-%s\\\"\", info[:endOfLang]))\n}\n\nfunc (r *HTMLRenderer) tag(w io.Writer, name []byte, attrs []string) {\n\tw.Write(name)\n\tif len(attrs) > 0 {\n\t\tw.Write(spaceBytes)\n\t\tw.Write([]byte(strings.Join(attrs, \" \")))\n\t}\n\tw.Write(gtBytes)\n\tr.lastOutputLen = 1\n}\n\nfunc footnoteRef(prefix string, node *Node) []byte {\n\turlFrag := prefix + string(slugify(node.Destination))\n\tanchor := fmt.Sprintf(`<a href=\"#fn:%s\">%d</a>`, urlFrag, node.NoteID)\n\treturn []byte(fmt.Sprintf(`<sup class=\"footnote-ref\" id=\"fnref:%s\">%s</sup>`, urlFrag, anchor))\n}\n\nfunc footnoteItem(prefix string, slug []byte) []byte {\n\treturn []byte(fmt.Sprintf(`<li id=\"fn:%s%s\">`, prefix, slug))\n}\n\nfunc footnoteReturnLink(prefix, returnLink string, slug []byte) []byte {\n\tconst format = ` <a class=\"footnote-return\" href=\"#fnref:%s%s\">%s</a>`\n\treturn []byte(fmt.Sprintf(format, prefix, slug, returnLink))\n}\n\nfunc itemOpenCR(node *Node) bool {\n\tif node.Prev == nil {\n\t\treturn false\n\t}\n\tld := node.Parent.ListData\n\treturn !ld.Tight && ld.ListFlags&ListTypeDefinition == 0\n}\n\nfunc skipParagraphTags(node *Node) bool {\n\tgrandparent := node.Parent.Parent\n\tif grandparent == nil || grandparent.Type != List {\n\t\treturn false\n\t}\n\ttightOrTerm := grandparent.Tight || node.Parent.ListFlags&ListTypeTerm != 0\n\treturn grandparent.Type == List && tightOrTerm\n}\n\nfunc cellAlignment(align CellAlignFlags) string {\n\tswitch align {\n\tcase TableAlignmentLeft:\n\t\treturn \"left\"\n\tcase TableAlignmentRight:\n\t\treturn \"right\"\n\tcase TableAlignmentCenter:\n\t\treturn \"center\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\nfunc (r *HTMLRenderer) out(w io.Writer, text []byte) {\n\tif r.disableTags > 0 {\n\t\tw.Write(htmlTagRe.ReplaceAll(text, []byte{}))\n\t} else {\n\t\tw.Write(text)\n\t}\n\tr.lastOutputLen = len(text)\n}\n\nfunc (r *HTMLRenderer) cr(w io.Writer) {\n\tif r.lastOutputLen > 0 {\n\t\tr.out(w, nlBytes)\n\t}\n}\n\nvar (\n\tnlBytes    = []byte{'\\n'}\n\tgtBytes    = []byte{'>'}\n\tspaceBytes = []byte{' '}\n)\n\nvar (\n\tbrTag              = []byte(\"<br>\")\n\tbrXHTMLTag         = []byte(\"<br />\")\n\temTag              = []byte(\"<em>\")\n\temCloseTag         = []byte(\"</em>\")\n\tstrongTag          = []byte(\"<strong>\")\n\tstrongCloseTag     = []byte(\"</strong>\")\n\tdelTag             = []byte(\"<del>\")\n\tdelCloseTag        = []byte(\"</del>\")\n\tttTag              = []byte(\"<tt>\")\n\tttCloseTag         = []byte(\"</tt>\")\n\taTag               = []byte(\"<a\")\n\taCloseTag          = []byte(\"</a>\")\n\tpreTag             = []byte(\"<pre>\")\n\tpreCloseTag        = []byte(\"</pre>\")\n\tcodeTag            = []byte(\"<code>\")\n\tcodeCloseTag       = []byte(\"</code>\")\n\tpTag               = []byte(\"<p>\")\n\tpCloseTag          = []byte(\"</p>\")\n\tblockquoteTag      = []byte(\"<blockquote>\")\n\tblockquoteCloseTag = []byte(\"</blockquote>\")\n\thrTag              = []byte(\"<hr>\")\n\thrXHTMLTag         = []byte(\"<hr />\")\n\tulTag              = []byte(\"<ul>\")\n\tulCloseTag         = []byte(\"</ul>\")\n\tolTag              = []byte(\"<ol>\")\n\tolCloseTag         = []byte(\"</ol>\")\n\tdlTag              = []byte(\"<dl>\")\n\tdlCloseTag         = []byte(\"</dl>\")\n\tliTag              = []byte(\"<li>\")\n\tliCloseTag         = []byte(\"</li>\")\n\tddTag              = []byte(\"<dd>\")\n\tddCloseTag         = []byte(\"</dd>\")\n\tdtTag              = []byte(\"<dt>\")\n\tdtCloseTag         = []byte(\"</dt>\")\n\ttableTag           = []byte(\"<table>\")\n\ttableCloseTag      = []byte(\"</table>\")\n\ttdTag              = []byte(\"<td\")\n\ttdCloseTag         = []byte(\"</td>\")\n\tthTag              = []byte(\"<th\")\n\tthCloseTag         = []byte(\"</th>\")\n\ttheadTag           = []byte(\"<thead>\")\n\ttheadCloseTag      = []byte(\"</thead>\")\n\ttbodyTag           = []byte(\"<tbody>\")\n\ttbodyCloseTag      = []byte(\"</tbody>\")\n\ttrTag              = []byte(\"<tr>\")\n\ttrCloseTag         = []byte(\"</tr>\")\n\th1Tag              = []byte(\"<h1\")\n\th1CloseTag         = []byte(\"</h1>\")\n\th2Tag              = []byte(\"<h2\")\n\th2CloseTag         = []byte(\"</h2>\")\n\th3Tag              = []byte(\"<h3\")\n\th3CloseTag         = []byte(\"</h3>\")\n\th4Tag              = []byte(\"<h4\")\n\th4CloseTag         = []byte(\"</h4>\")\n\th5Tag              = []byte(\"<h5\")\n\th5CloseTag         = []byte(\"</h5>\")\n\th6Tag              = []byte(\"<h6\")\n\th6CloseTag         = []byte(\"</h6>\")\n\n\tfootnotesDivBytes      = []byte(\"\\n<div class=\\\"footnotes\\\">\\n\\n\")\n\tfootnotesCloseDivBytes = []byte(\"\\n</div>\\n\")\n)\n\nfunc headingTagsFromLevel(level int) ([]byte, []byte) {\n\tif level <= 1 {\n\t\treturn h1Tag, h1CloseTag\n\t}\n\tswitch level {\n\tcase 2:\n\t\treturn h2Tag, h2CloseTag\n\tcase 3:\n\t\treturn h3Tag, h3CloseTag\n\tcase 4:\n\t\treturn h4Tag, h4CloseTag\n\tcase 5:\n\t\treturn h5Tag, h5CloseTag\n\t}\n\treturn h6Tag, h6CloseTag\n}\n\nfunc (r *HTMLRenderer) outHRTag(w io.Writer) {\n\tif r.Flags&UseXHTML == 0 {\n\t\tr.out(w, hrTag)\n\t} else {\n\t\tr.out(w, hrXHTMLTag)\n\t}\n}\n\n// RenderNode is a default renderer of a single node of a syntax tree. For\n// block nodes it will be called twice: first time with entering=true, second\n// time with entering=false, so that it could know when it's working on an open\n// tag and when on close. It writes the result to w.\n//\n// The return value is a way to tell the calling walker to adjust its walk\n// pattern: e.g. it can terminate the traversal by returning Terminate. Or it\n// can ask the walker to skip a subtree of this node by returning SkipChildren.\n// The typical behavior is to return GoToNext, which asks for the usual\n// traversal to the next node.\nfunc (r *HTMLRenderer) RenderNode(w io.Writer, node *Node, entering bool) WalkStatus {\n\tattrs := []string{}\n\tswitch node.Type {\n\tcase Text:\n\t\tif r.Flags&Smartypants != 0 {\n\t\t\tvar tmp bytes.Buffer\n\t\t\tescapeHTML(&tmp, node.Literal)\n\t\t\tr.sr.Process(w, tmp.Bytes())\n\t\t} else {\n\t\t\tif node.Parent.Type == Link {\n\t\t\t\tescLink(w, node.Literal)\n\t\t\t} else {\n\t\t\t\tescapeHTML(w, node.Literal)\n\t\t\t}\n\t\t}\n\tcase Softbreak:\n\t\tr.cr(w)\n\t\t// TODO: make it configurable via out(renderer.softbreak)\n\tcase Hardbreak:\n\t\tif r.Flags&UseXHTML == 0 {\n\t\t\tr.out(w, brTag)\n\t\t} else {\n\t\t\tr.out(w, brXHTMLTag)\n\t\t}\n\t\tr.cr(w)\n\tcase Emph:\n\t\tif entering {\n\t\t\tr.out(w, emTag)\n\t\t} else {\n\t\t\tr.out(w, emCloseTag)\n\t\t}\n\tcase Strong:\n\t\tif entering {\n\t\t\tr.out(w, strongTag)\n\t\t} else {\n\t\t\tr.out(w, strongCloseTag)\n\t\t}\n\tcase Del:\n\t\tif entering {\n\t\t\tr.out(w, delTag)\n\t\t} else {\n\t\t\tr.out(w, delCloseTag)\n\t\t}\n\tcase HTMLSpan:\n\t\tif r.Flags&SkipHTML != 0 {\n\t\t\tbreak\n\t\t}\n\t\tr.out(w, node.Literal)\n\tcase Link:\n\t\t// mark it but don't link it if it is not a safe link: no smartypants\n\t\tdest := node.LinkData.Destination\n\t\tif needSkipLink(r.Flags, dest) {\n\t\t\tif entering {\n\t\t\t\tr.out(w, ttTag)\n\t\t\t} else {\n\t\t\t\tr.out(w, ttCloseTag)\n\t\t\t}\n\t\t} else {\n\t\t\tif entering {\n\t\t\t\tdest = r.addAbsPrefix(dest)\n\t\t\t\tvar hrefBuf bytes.Buffer\n\t\t\t\threfBuf.WriteString(\"href=\\\"\")\n\t\t\t\tescLink(&hrefBuf, dest)\n\t\t\t\threfBuf.WriteByte('\"')\n\t\t\t\tattrs = append(attrs, hrefBuf.String())\n\t\t\t\tif node.NoteID != 0 {\n\t\t\t\t\tr.out(w, footnoteRef(r.FootnoteAnchorPrefix, node))\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tattrs = appendLinkAttrs(attrs, r.Flags, dest)\n\t\t\t\tif len(node.LinkData.Title) > 0 {\n\t\t\t\t\tvar titleBuff bytes.Buffer\n\t\t\t\t\ttitleBuff.WriteString(\"title=\\\"\")\n\t\t\t\t\tescapeHTML(&titleBuff, node.LinkData.Title)\n\t\t\t\t\ttitleBuff.WriteByte('\"')\n\t\t\t\t\tattrs = append(attrs, titleBuff.String())\n\t\t\t\t}\n\t\t\t\tr.tag(w, aTag, attrs)\n\t\t\t} else {\n\t\t\t\tif node.NoteID != 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tr.out(w, aCloseTag)\n\t\t\t}\n\t\t}\n\tcase Image:\n\t\tif r.Flags&SkipImages != 0 {\n\t\t\treturn SkipChildren\n\t\t}\n\t\tif entering {\n\t\t\tdest := node.LinkData.Destination\n\t\t\tdest = r.addAbsPrefix(dest)\n\t\t\tif r.disableTags == 0 {\n\t\t\t\t//if options.safe && potentiallyUnsafe(dest) {\n\t\t\t\t//out(w, `<img src=\"\" alt=\"`)\n\t\t\t\t//} else {\n\t\t\t\tr.out(w, []byte(`<img src=\"`))\n\t\t\t\tescLink(w, dest)\n\t\t\t\tr.out(w, []byte(`\" alt=\"`))\n\t\t\t\t//}\n\t\t\t}\n\t\t\tr.disableTags++\n\t\t} else {\n\t\t\tr.disableTags--\n\t\t\tif r.disableTags == 0 {\n\t\t\t\tif node.LinkData.Title != nil {\n\t\t\t\t\tr.out(w, []byte(`\" title=\"`))\n\t\t\t\t\tescapeHTML(w, node.LinkData.Title)\n\t\t\t\t}\n\t\t\t\tr.out(w, []byte(`\" />`))\n\t\t\t}\n\t\t}\n\tcase Code:\n\t\tr.out(w, codeTag)\n\t\tescapeAllHTML(w, node.Literal)\n\t\tr.out(w, codeCloseTag)\n\tcase Document:\n\t\tbreak\n\tcase Paragraph:\n\t\tif skipParagraphTags(node) {\n\t\t\tbreak\n\t\t}\n\t\tif entering {\n\t\t\t// TODO: untangle this clusterfuck about when the newlines need\n\t\t\t// to be added and when not.\n\t\t\tif node.Prev != nil {\n\t\t\t\tswitch node.Prev.Type {\n\t\t\t\tcase HTMLBlock, List, Paragraph, Heading, CodeBlock, BlockQuote, HorizontalRule:\n\t\t\t\t\tr.cr(w)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif node.Parent.Type == BlockQuote && node.Prev == nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.out(w, pTag)\n\t\t} else {\n\t\t\tr.out(w, pCloseTag)\n\t\t\tif !(node.Parent.Type == Item && node.Next == nil) {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t}\n\tcase BlockQuote:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, blockquoteTag)\n\t\t} else {\n\t\t\tr.out(w, blockquoteCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase HTMLBlock:\n\t\tif r.Flags&SkipHTML != 0 {\n\t\t\tbreak\n\t\t}\n\t\tr.cr(w)\n\t\tr.out(w, node.Literal)\n\t\tr.cr(w)\n\tcase Heading:\n\t\theadingLevel := r.HTMLRendererParameters.HeadingLevelOffset + node.Level\n\t\topenTag, closeTag := headingTagsFromLevel(headingLevel)\n\t\tif entering {\n\t\t\tif node.IsTitleblock {\n\t\t\t\tattrs = append(attrs, `class=\"title\"`)\n\t\t\t}\n\t\t\tif node.HeadingID != \"\" {\n\t\t\t\tid := r.ensureUniqueHeadingID(node.HeadingID)\n\t\t\t\tif r.HeadingIDPrefix != \"\" {\n\t\t\t\t\tid = r.HeadingIDPrefix + id\n\t\t\t\t}\n\t\t\t\tif r.HeadingIDSuffix != \"\" {\n\t\t\t\t\tid = id + r.HeadingIDSuffix\n\t\t\t\t}\n\t\t\t\tattrs = append(attrs, fmt.Sprintf(`id=\"%s\"`, id))\n\t\t\t}\n\t\t\tr.cr(w)\n\t\t\tr.tag(w, openTag, attrs)\n\t\t} else {\n\t\t\tr.out(w, closeTag)\n\t\t\tif !(node.Parent.Type == Item && node.Next == nil) {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t}\n\tcase HorizontalRule:\n\t\tr.cr(w)\n\t\tr.outHRTag(w)\n\t\tr.cr(w)\n\tcase List:\n\t\topenTag := ulTag\n\t\tcloseTag := ulCloseTag\n\t\tif node.ListFlags&ListTypeOrdered != 0 {\n\t\t\topenTag = olTag\n\t\t\tcloseTag = olCloseTag\n\t\t}\n\t\tif node.ListFlags&ListTypeDefinition != 0 {\n\t\t\topenTag = dlTag\n\t\t\tcloseTag = dlCloseTag\n\t\t}\n\t\tif entering {\n\t\t\tif node.IsFootnotesList {\n\t\t\t\tr.out(w, footnotesDivBytes)\n\t\t\t\tr.outHRTag(w)\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.cr(w)\n\t\t\tif node.Parent.Type == Item && node.Parent.Parent.Tight {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.tag(w, openTag[:len(openTag)-1], attrs)\n\t\t\tr.cr(w)\n\t\t} else {\n\t\t\tr.out(w, closeTag)\n\t\t\t//cr(w)\n\t\t\t//if node.parent.Type != Item {\n\t\t\t//\tcr(w)\n\t\t\t//}\n\t\t\tif node.Parent.Type == Item && node.Next != nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tif node.Parent.Type == Document || node.Parent.Type == BlockQuote {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tif node.IsFootnotesList {\n\t\t\t\tr.out(w, footnotesCloseDivBytes)\n\t\t\t}\n\t\t}\n\tcase Item:\n\t\topenTag := liTag\n\t\tcloseTag := liCloseTag\n\t\tif node.ListFlags&ListTypeDefinition != 0 {\n\t\t\topenTag = ddTag\n\t\t\tcloseTag = ddCloseTag\n\t\t}\n\t\tif node.ListFlags&ListTypeTerm != 0 {\n\t\t\topenTag = dtTag\n\t\t\tcloseTag = dtCloseTag\n\t\t}\n\t\tif entering {\n\t\t\tif itemOpenCR(node) {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tif node.ListData.RefLink != nil {\n\t\t\t\tslug := slugify(node.ListData.RefLink)\n\t\t\t\tr.out(w, footnoteItem(r.FootnoteAnchorPrefix, slug))\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tr.out(w, openTag)\n\t\t} else {\n\t\t\tif node.ListData.RefLink != nil {\n\t\t\t\tslug := slugify(node.ListData.RefLink)\n\t\t\t\tif r.Flags&FootnoteReturnLinks != 0 {\n\t\t\t\t\tr.out(w, footnoteReturnLink(r.FootnoteAnchorPrefix, r.FootnoteReturnLinkContents, slug))\n\t\t\t\t}\n\t\t\t}\n\t\t\tr.out(w, closeTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase CodeBlock:\n\t\tattrs = appendLanguageAttr(attrs, node.Info)\n\t\tr.cr(w)\n\t\tr.out(w, preTag)\n\t\tr.tag(w, codeTag[:len(codeTag)-1], attrs)\n\t\tescapeAllHTML(w, node.Literal)\n\t\tr.out(w, codeCloseTag)\n\t\tr.out(w, preCloseTag)\n\t\tif node.Parent.Type != Item {\n\t\t\tr.cr(w)\n\t\t}\n\tcase Table:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, tableTag)\n\t\t} else {\n\t\t\tr.out(w, tableCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableCell:\n\t\topenTag := tdTag\n\t\tcloseTag := tdCloseTag\n\t\tif node.IsHeader {\n\t\t\topenTag = thTag\n\t\t\tcloseTag = thCloseTag\n\t\t}\n\t\tif entering {\n\t\t\talign := cellAlignment(node.Align)\n\t\t\tif align != \"\" {\n\t\t\t\tattrs = append(attrs, fmt.Sprintf(`align=\"%s\"`, align))\n\t\t\t}\n\t\t\tif node.Prev == nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t\tr.tag(w, openTag, attrs)\n\t\t} else {\n\t\t\tr.out(w, closeTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableHead:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, theadTag)\n\t\t} else {\n\t\t\tr.out(w, theadCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableBody:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, tbodyTag)\n\t\t\t// XXX: this is to adhere to a rather silly test. Should fix test.\n\t\t\tif node.FirstChild == nil {\n\t\t\t\tr.cr(w)\n\t\t\t}\n\t\t} else {\n\t\t\tr.out(w, tbodyCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tcase TableRow:\n\t\tif entering {\n\t\t\tr.cr(w)\n\t\t\tr.out(w, trTag)\n\t\t} else {\n\t\t\tr.out(w, trCloseTag)\n\t\t\tr.cr(w)\n\t\t}\n\tdefault:\n\t\tpanic(\"Unknown node type \" + node.Type.String())\n\t}\n\treturn GoToNext\n}\n\n// RenderHeader writes HTML document preamble and TOC if requested.\nfunc (r *HTMLRenderer) RenderHeader(w io.Writer, ast *Node) {\n\tr.writeDocumentHeader(w)\n\tif r.Flags&TOC != 0 {\n\t\tr.writeTOC(w, ast)\n\t}\n}\n\n// RenderFooter writes HTML document footer.\nfunc (r *HTMLRenderer) RenderFooter(w io.Writer, ast *Node) {\n\tif r.Flags&CompletePage == 0 {\n\t\treturn\n\t}\n\tio.WriteString(w, \"\\n</body>\\n</html>\\n\")\n}\n\nfunc (r *HTMLRenderer) writeDocumentHeader(w io.Writer) {\n\tif r.Flags&CompletePage == 0 {\n\t\treturn\n\t}\n\tending := \"\"\n\tif r.Flags&UseXHTML != 0 {\n\t\tio.WriteString(w, \"<!DOCTYPE html PUBLIC \\\"-//W3C//DTD XHTML 1.0 Transitional//EN\\\" \")\n\t\tio.WriteString(w, \"\\\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\\\">\\n\")\n\t\tio.WriteString(w, \"<html xmlns=\\\"http://www.w3.org/1999/xhtml\\\">\\n\")\n\t\tending = \" /\"\n\t} else {\n\t\tio.WriteString(w, \"<!DOCTYPE html>\\n\")\n\t\tio.WriteString(w, \"<html>\\n\")\n\t}\n\tio.WriteString(w, \"<head>\\n\")\n\tio.WriteString(w, \"  <title>\")\n\tif r.Flags&Smartypants != 0 {\n\t\tr.sr.Process(w, []byte(r.Title))\n\t} else {\n\t\tescapeHTML(w, []byte(r.Title))\n\t}\n\tio.WriteString(w, \"</title>\\n\")\n\tio.WriteString(w, \"  <meta name=\\\"GENERATOR\\\" content=\\\"Blackfriday Markdown Processor v\")\n\tio.WriteString(w, Version)\n\tio.WriteString(w, \"\\\"\")\n\tio.WriteString(w, ending)\n\tio.WriteString(w, \">\\n\")\n\tio.WriteString(w, \"  <meta charset=\\\"utf-8\\\"\")\n\tio.WriteString(w, ending)\n\tio.WriteString(w, \">\\n\")\n\tif r.CSS != \"\" {\n\t\tio.WriteString(w, \"  <link rel=\\\"stylesheet\\\" type=\\\"text/css\\\" href=\\\"\")\n\t\tescapeHTML(w, []byte(r.CSS))\n\t\tio.WriteString(w, \"\\\"\")\n\t\tio.WriteString(w, ending)\n\t\tio.WriteString(w, \">\\n\")\n\t}\n\tif r.Icon != \"\" {\n\t\tio.WriteString(w, \"  <link rel=\\\"icon\\\" type=\\\"image/x-icon\\\" href=\\\"\")\n\t\tescapeHTML(w, []byte(r.Icon))\n\t\tio.WriteString(w, \"\\\"\")\n\t\tio.WriteString(w, ending)\n\t\tio.WriteString(w, \">\\n\")\n\t}\n\tio.WriteString(w, \"</head>\\n\")\n\tio.WriteString(w, \"<body>\\n\\n\")\n}\n\nfunc (r *HTMLRenderer) writeTOC(w io.Writer, ast *Node) {\n\tbuf := bytes.Buffer{}\n\n\tinHeading := false\n\ttocLevel := 0\n\theadingCount := 0\n\n\tast.Walk(func(node *Node, entering bool) WalkStatus {\n\t\tif node.Type == Heading && !node.HeadingData.IsTitleblock {\n\t\t\tinHeading = entering\n\t\t\tif entering {\n\t\t\t\tnode.HeadingID = fmt.Sprintf(\"toc_%d\", headingCount)\n\t\t\t\tif node.Level == tocLevel {\n\t\t\t\t\tbuf.WriteString(\"</li>\\n\\n<li>\")\n\t\t\t\t} else if node.Level < tocLevel {\n\t\t\t\t\tfor node.Level < tocLevel {\n\t\t\t\t\t\ttocLevel--\n\t\t\t\t\t\tbuf.WriteString(\"</li>\\n</ul>\")\n\t\t\t\t\t}\n\t\t\t\t\tbuf.WriteString(\"</li>\\n\\n<li>\")\n\t\t\t\t} else {\n\t\t\t\t\tfor node.Level > tocLevel {\n\t\t\t\t\t\ttocLevel++\n\t\t\t\t\t\tbuf.WriteString(\"\\n<ul>\\n<li>\")\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfmt.Fprintf(&buf, `<a href=\"#toc_%d\">`, headingCount)\n\t\t\t\theadingCount++\n\t\t\t} else {\n\t\t\t\tbuf.WriteString(\"</a>\")\n\t\t\t}\n\t\t\treturn GoToNext\n\t\t}\n\n\t\tif inHeading {\n\t\t\treturn r.RenderNode(&buf, node, entering)\n\t\t}\n\n\t\treturn GoToNext\n\t})\n\n\tfor ; tocLevel > 0; tocLevel-- {\n\t\tbuf.WriteString(\"</li>\\n</ul>\")\n\t}\n\n\tif buf.Len() > 0 {\n\t\tio.WriteString(w, \"<nav>\\n\")\n\t\tw.Write(buf.Bytes())\n\t\tio.WriteString(w, \"\\n\\n</nav>\\n\")\n\t}\n\tr.lastOutputLen = buf.Len()\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/inline.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n// Functions to parse inline elements.\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"regexp\"\n\t\"strconv\"\n)\n\nvar (\n\turlRe    = `((https?|ftp):\\/\\/|\\/)[-A-Za-z0-9+&@#\\/%?=~_|!:,.;\\(\\)]+`\n\tanchorRe = regexp.MustCompile(`^(<a\\shref=\"` + urlRe + `\"(\\stitle=\"[^\"<>]+\")?\\s?>` + urlRe + `<\\/a>)`)\n\n\t// https://www.w3.org/TR/html5/syntax.html#character-references\n\t// highest unicode code point in 17 planes (2^20): 1,114,112d =\n\t// 7 dec digits or 6 hex digits\n\t// named entity references can be 2-31 characters with stuff like &lt;\n\t// at one end and &CounterClockwiseContourIntegral; at the other. There\n\t// are also sometimes numbers at the end, although this isn't inherent\n\t// in the specification; there are never numbers anywhere else in\n\t// current character references, though; see &frac34; and &blk12;, etc.\n\t// https://www.w3.org/TR/html5/syntax.html#named-character-references\n\t//\n\t// entity := \"&\" (named group | number ref) \";\"\n\t// named group := [a-zA-Z]{2,31}[0-9]{0,2}\n\t// number ref := \"#\" (dec ref | hex ref)\n\t// dec ref := [0-9]{1,7}\n\t// hex ref := (\"x\" | \"X\") [0-9a-fA-F]{1,6}\n\thtmlEntityRe = regexp.MustCompile(`&([a-zA-Z]{2,31}[0-9]{0,2}|#([0-9]{1,7}|[xX][0-9a-fA-F]{1,6}));`)\n)\n\n// Functions to parse text within a block\n// Each function returns the number of chars taken care of\n// data is the complete block being rendered\n// offset is the number of valid chars before the current cursor\n\nfunc (p *Markdown) inline(currBlock *Node, data []byte) {\n\t// handlers might call us recursively: enforce a maximum depth\n\tif p.nesting >= p.maxNesting || len(data) == 0 {\n\t\treturn\n\t}\n\tp.nesting++\n\tbeg, end := 0, 0\n\tfor end < len(data) {\n\t\thandler := p.inlineCallback[data[end]]\n\t\tif handler != nil {\n\t\t\tif consumed, node := handler(p, data, end); consumed == 0 {\n\t\t\t\t// No action from the callback.\n\t\t\t\tend++\n\t\t\t} else {\n\t\t\t\t// Copy inactive chars into the output.\n\t\t\t\tcurrBlock.AppendChild(text(data[beg:end]))\n\t\t\t\tif node != nil {\n\t\t\t\t\tcurrBlock.AppendChild(node)\n\t\t\t\t}\n\t\t\t\t// Skip past whatever the callback used.\n\t\t\t\tbeg = end + consumed\n\t\t\t\tend = beg\n\t\t\t}\n\t\t} else {\n\t\t\tend++\n\t\t}\n\t}\n\tif beg < len(data) {\n\t\tif data[end-1] == '\\n' {\n\t\t\tend--\n\t\t}\n\t\tcurrBlock.AppendChild(text(data[beg:end]))\n\t}\n\tp.nesting--\n}\n\n// single and double emphasis parsing\nfunc emphasis(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\tc := data[0]\n\n\tif len(data) > 2 && data[1] != c {\n\t\t// whitespace cannot follow an opening emphasis;\n\t\t// strikethrough only takes two characters '~~'\n\t\tif c == '~' || isspace(data[1]) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tret, node := helperEmphasis(p, data[1:], c)\n\t\tif ret == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn ret + 1, node\n\t}\n\n\tif len(data) > 3 && data[1] == c && data[2] != c {\n\t\tif isspace(data[2]) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tret, node := helperDoubleEmphasis(p, data[2:], c)\n\t\tif ret == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn ret + 2, node\n\t}\n\n\tif len(data) > 4 && data[1] == c && data[2] == c && data[3] != c {\n\t\tif c == '~' || isspace(data[3]) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tret, node := helperTripleEmphasis(p, data, 3, c)\n\t\tif ret == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn ret + 3, node\n\t}\n\n\treturn 0, nil\n}\n\nfunc codeSpan(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\n\tnb := 0\n\n\t// count the number of backticks in the delimiter\n\tfor nb < len(data) && data[nb] == '`' {\n\t\tnb++\n\t}\n\n\t// find the next delimiter\n\ti, end := 0, 0\n\tfor end = nb; end < len(data) && i < nb; end++ {\n\t\tif data[end] == '`' {\n\t\t\ti++\n\t\t} else {\n\t\t\ti = 0\n\t\t}\n\t}\n\n\t// no matching delimiter?\n\tif i < nb && end >= len(data) {\n\t\treturn 0, nil\n\t}\n\n\t// trim outside whitespace\n\tfBegin := nb\n\tfor fBegin < end && data[fBegin] == ' ' {\n\t\tfBegin++\n\t}\n\n\tfEnd := end - nb\n\tfor fEnd > fBegin && data[fEnd-1] == ' ' {\n\t\tfEnd--\n\t}\n\n\t// render the code span\n\tif fBegin != fEnd {\n\t\tcode := NewNode(Code)\n\t\tcode.Literal = data[fBegin:fEnd]\n\t\treturn end, code\n\t}\n\n\treturn end, nil\n}\n\n// newline preceded by two spaces becomes <br>\nfunc maybeLineBreak(p *Markdown, data []byte, offset int) (int, *Node) {\n\torigOffset := offset\n\tfor offset < len(data) && data[offset] == ' ' {\n\t\toffset++\n\t}\n\n\tif offset < len(data) && data[offset] == '\\n' {\n\t\tif offset-origOffset >= 2 {\n\t\t\treturn offset - origOffset + 1, NewNode(Hardbreak)\n\t\t}\n\t\treturn offset - origOffset, nil\n\t}\n\treturn 0, nil\n}\n\n// newline without two spaces works when HardLineBreak is enabled\nfunc lineBreak(p *Markdown, data []byte, offset int) (int, *Node) {\n\tif p.extensions&HardLineBreak != 0 {\n\t\treturn 1, NewNode(Hardbreak)\n\t}\n\treturn 0, nil\n}\n\ntype linkType int\n\nconst (\n\tlinkNormal linkType = iota\n\tlinkImg\n\tlinkDeferredFootnote\n\tlinkInlineFootnote\n)\n\nfunc isReferenceStyleLink(data []byte, pos int, t linkType) bool {\n\tif t == linkDeferredFootnote {\n\t\treturn false\n\t}\n\treturn pos < len(data)-1 && data[pos] == '[' && data[pos+1] != '^'\n}\n\nfunc maybeImage(p *Markdown, data []byte, offset int) (int, *Node) {\n\tif offset < len(data)-1 && data[offset+1] == '[' {\n\t\treturn link(p, data, offset)\n\t}\n\treturn 0, nil\n}\n\nfunc maybeInlineFootnote(p *Markdown, data []byte, offset int) (int, *Node) {\n\tif offset < len(data)-1 && data[offset+1] == '[' {\n\t\treturn link(p, data, offset)\n\t}\n\treturn 0, nil\n}\n\n// '[': parse a link or an image or a footnote\nfunc link(p *Markdown, data []byte, offset int) (int, *Node) {\n\t// no links allowed inside regular links, footnote, and deferred footnotes\n\tif p.insideLink && (offset > 0 && data[offset-1] == '[' || len(data)-1 > offset && data[offset+1] == '^') {\n\t\treturn 0, nil\n\t}\n\n\tvar t linkType\n\tswitch {\n\t// special case: ![^text] == deferred footnote (that follows something with\n\t// an exclamation point)\n\tcase p.extensions&Footnotes != 0 && len(data)-1 > offset && data[offset+1] == '^':\n\t\tt = linkDeferredFootnote\n\t// ![alt] == image\n\tcase offset >= 0 && data[offset] == '!':\n\t\tt = linkImg\n\t\toffset++\n\t// ^[text] == inline footnote\n\t// [^refId] == deferred footnote\n\tcase p.extensions&Footnotes != 0:\n\t\tif offset >= 0 && data[offset] == '^' {\n\t\t\tt = linkInlineFootnote\n\t\t\toffset++\n\t\t} else if len(data)-1 > offset && data[offset+1] == '^' {\n\t\t\tt = linkDeferredFootnote\n\t\t}\n\t// [text] == regular link\n\tdefault:\n\t\tt = linkNormal\n\t}\n\n\tdata = data[offset:]\n\n\tvar (\n\t\ti                       = 1\n\t\tnoteID                  int\n\t\ttitle, link, altContent []byte\n\t\ttextHasNl               = false\n\t)\n\n\tif t == linkDeferredFootnote {\n\t\ti++\n\t}\n\n\t// look for the matching closing bracket\n\tfor level := 1; level > 0 && i < len(data); i++ {\n\t\tswitch {\n\t\tcase data[i] == '\\n':\n\t\t\ttextHasNl = true\n\n\t\tcase isBackslashEscaped(data, i):\n\t\t\tcontinue\n\n\t\tcase data[i] == '[':\n\t\t\tlevel++\n\n\t\tcase data[i] == ']':\n\t\t\tlevel--\n\t\t\tif level <= 0 {\n\t\t\t\ti-- // compensate for extra i++ in for loop\n\t\t\t}\n\t\t}\n\t}\n\n\tif i >= len(data) {\n\t\treturn 0, nil\n\t}\n\n\ttxtE := i\n\ti++\n\tvar footnoteNode *Node\n\n\t// skip any amount of whitespace or newline\n\t// (this is much more lax than original markdown syntax)\n\tfor i < len(data) && isspace(data[i]) {\n\t\ti++\n\t}\n\n\t// inline style link\n\tswitch {\n\tcase i < len(data) && data[i] == '(':\n\t\t// skip initial whitespace\n\t\ti++\n\n\t\tfor i < len(data) && isspace(data[i]) {\n\t\t\ti++\n\t\t}\n\n\t\tlinkB := i\n\n\t\t// look for link end: ' \" )\n\tfindlinkend:\n\t\tfor i < len(data) {\n\t\t\tswitch {\n\t\t\tcase data[i] == '\\\\':\n\t\t\t\ti += 2\n\n\t\t\tcase data[i] == ')' || data[i] == '\\'' || data[i] == '\"':\n\t\t\t\tbreak findlinkend\n\n\t\t\tdefault:\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\n\t\tif i >= len(data) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tlinkE := i\n\n\t\t// look for title end if present\n\t\ttitleB, titleE := 0, 0\n\t\tif data[i] == '\\'' || data[i] == '\"' {\n\t\t\ti++\n\t\t\ttitleB = i\n\n\t\tfindtitleend:\n\t\t\tfor i < len(data) {\n\t\t\t\tswitch {\n\t\t\t\tcase data[i] == '\\\\':\n\t\t\t\t\ti += 2\n\n\t\t\t\tcase data[i] == ')':\n\t\t\t\t\tbreak findtitleend\n\n\t\t\t\tdefault:\n\t\t\t\t\ti++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif i >= len(data) {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\n\t\t\t// skip whitespace after title\n\t\t\ttitleE = i - 1\n\t\t\tfor titleE > titleB && isspace(data[titleE]) {\n\t\t\t\ttitleE--\n\t\t\t}\n\n\t\t\t// check for closing quote presence\n\t\t\tif data[titleE] != '\\'' && data[titleE] != '\"' {\n\t\t\t\ttitleB, titleE = 0, 0\n\t\t\t\tlinkE = i\n\t\t\t}\n\t\t}\n\n\t\t// remove whitespace at the end of the link\n\t\tfor linkE > linkB && isspace(data[linkE-1]) {\n\t\t\tlinkE--\n\t\t}\n\n\t\t// remove optional angle brackets around the link\n\t\tif data[linkB] == '<' {\n\t\t\tlinkB++\n\t\t}\n\t\tif data[linkE-1] == '>' {\n\t\t\tlinkE--\n\t\t}\n\n\t\t// build escaped link and title\n\t\tif linkE > linkB {\n\t\t\tlink = data[linkB:linkE]\n\t\t}\n\n\t\tif titleE > titleB {\n\t\t\ttitle = data[titleB:titleE]\n\t\t}\n\n\t\ti++\n\n\t// reference style link\n\tcase isReferenceStyleLink(data, i, t):\n\t\tvar id []byte\n\t\taltContentConsidered := false\n\n\t\t// look for the id\n\t\ti++\n\t\tlinkB := i\n\t\tfor i < len(data) && data[i] != ']' {\n\t\t\ti++\n\t\t}\n\t\tif i >= len(data) {\n\t\t\treturn 0, nil\n\t\t}\n\t\tlinkE := i\n\n\t\t// find the reference\n\t\tif linkB == linkE {\n\t\t\tif textHasNl {\n\t\t\t\tvar b bytes.Buffer\n\n\t\t\t\tfor j := 1; j < txtE; j++ {\n\t\t\t\t\tswitch {\n\t\t\t\t\tcase data[j] != '\\n':\n\t\t\t\t\t\tb.WriteByte(data[j])\n\t\t\t\t\tcase data[j-1] != ' ':\n\t\t\t\t\t\tb.WriteByte(' ')\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tid = b.Bytes()\n\t\t\t} else {\n\t\t\t\tid = data[1:txtE]\n\t\t\t\taltContentConsidered = true\n\t\t\t}\n\t\t} else {\n\t\t\tid = data[linkB:linkE]\n\t\t}\n\n\t\t// find the reference with matching id\n\t\tlr, ok := p.getRef(string(id))\n\t\tif !ok {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\t// keep link and title from reference\n\t\tlink = lr.link\n\t\ttitle = lr.title\n\t\tif altContentConsidered {\n\t\t\taltContent = lr.text\n\t\t}\n\t\ti++\n\n\t// shortcut reference style link or reference or inline footnote\n\tdefault:\n\t\tvar id []byte\n\n\t\t// craft the id\n\t\tif textHasNl {\n\t\t\tvar b bytes.Buffer\n\n\t\t\tfor j := 1; j < txtE; j++ {\n\t\t\t\tswitch {\n\t\t\t\tcase data[j] != '\\n':\n\t\t\t\t\tb.WriteByte(data[j])\n\t\t\t\tcase data[j-1] != ' ':\n\t\t\t\t\tb.WriteByte(' ')\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tid = b.Bytes()\n\t\t} else {\n\t\t\tif t == linkDeferredFootnote {\n\t\t\t\tid = data[2:txtE] // get rid of the ^\n\t\t\t} else {\n\t\t\t\tid = data[1:txtE]\n\t\t\t}\n\t\t}\n\n\t\tfootnoteNode = NewNode(Item)\n\t\tif t == linkInlineFootnote {\n\t\t\t// create a new reference\n\t\t\tnoteID = len(p.notes) + 1\n\n\t\t\tvar fragment []byte\n\t\t\tif len(id) > 0 {\n\t\t\t\tif len(id) < 16 {\n\t\t\t\t\tfragment = make([]byte, len(id))\n\t\t\t\t} else {\n\t\t\t\t\tfragment = make([]byte, 16)\n\t\t\t\t}\n\t\t\t\tcopy(fragment, slugify(id))\n\t\t\t} else {\n\t\t\t\tfragment = append([]byte(\"footnote-\"), []byte(strconv.Itoa(noteID))...)\n\t\t\t}\n\n\t\t\tref := &reference{\n\t\t\t\tnoteID:   noteID,\n\t\t\t\thasBlock: false,\n\t\t\t\tlink:     fragment,\n\t\t\t\ttitle:    id,\n\t\t\t\tfootnote: footnoteNode,\n\t\t\t}\n\n\t\t\tp.notes = append(p.notes, ref)\n\n\t\t\tlink = ref.link\n\t\t\ttitle = ref.title\n\t\t} else {\n\t\t\t// find the reference with matching id\n\t\t\tlr, ok := p.getRef(string(id))\n\t\t\tif !ok {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\n\t\t\tif t == linkDeferredFootnote {\n\t\t\t\tlr.noteID = len(p.notes) + 1\n\t\t\t\tlr.footnote = footnoteNode\n\t\t\t\tp.notes = append(p.notes, lr)\n\t\t\t}\n\n\t\t\t// keep link and title from reference\n\t\t\tlink = lr.link\n\t\t\t// if inline footnote, title == footnote contents\n\t\t\ttitle = lr.title\n\t\t\tnoteID = lr.noteID\n\t\t}\n\n\t\t// rewind the whitespace\n\t\ti = txtE + 1\n\t}\n\n\tvar uLink []byte\n\tif t == linkNormal || t == linkImg {\n\t\tif len(link) > 0 {\n\t\t\tvar uLinkBuf bytes.Buffer\n\t\t\tunescapeText(&uLinkBuf, link)\n\t\t\tuLink = uLinkBuf.Bytes()\n\t\t}\n\n\t\t// links need something to click on and somewhere to go\n\t\tif len(uLink) == 0 || (t == linkNormal && txtE <= 1) {\n\t\t\treturn 0, nil\n\t\t}\n\t}\n\n\t// call the relevant rendering function\n\tvar linkNode *Node\n\tswitch t {\n\tcase linkNormal:\n\t\tlinkNode = NewNode(Link)\n\t\tlinkNode.Destination = normalizeURI(uLink)\n\t\tlinkNode.Title = title\n\t\tif len(altContent) > 0 {\n\t\t\tlinkNode.AppendChild(text(altContent))\n\t\t} else {\n\t\t\t// links cannot contain other links, so turn off link parsing\n\t\t\t// temporarily and recurse\n\t\t\tinsideLink := p.insideLink\n\t\t\tp.insideLink = true\n\t\t\tp.inline(linkNode, data[1:txtE])\n\t\t\tp.insideLink = insideLink\n\t\t}\n\n\tcase linkImg:\n\t\tlinkNode = NewNode(Image)\n\t\tlinkNode.Destination = uLink\n\t\tlinkNode.Title = title\n\t\tlinkNode.AppendChild(text(data[1:txtE]))\n\t\ti++\n\n\tcase linkInlineFootnote, linkDeferredFootnote:\n\t\tlinkNode = NewNode(Link)\n\t\tlinkNode.Destination = link\n\t\tlinkNode.Title = title\n\t\tlinkNode.NoteID = noteID\n\t\tlinkNode.Footnote = footnoteNode\n\t\tif t == linkInlineFootnote {\n\t\t\ti++\n\t\t}\n\n\tdefault:\n\t\treturn 0, nil\n\t}\n\n\treturn i, linkNode\n}\n\nfunc (p *Markdown) inlineHTMLComment(data []byte) int {\n\tif len(data) < 5 {\n\t\treturn 0\n\t}\n\tif data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' {\n\t\treturn 0\n\t}\n\ti := 5\n\t// scan for an end-of-comment marker, across lines if necessary\n\tfor i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') {\n\t\ti++\n\t}\n\t// no end-of-comment marker\n\tif i >= len(data) {\n\t\treturn 0\n\t}\n\treturn i + 1\n}\n\nfunc stripMailto(link []byte) []byte {\n\tif bytes.HasPrefix(link, []byte(\"mailto://\")) {\n\t\treturn link[9:]\n\t} else if bytes.HasPrefix(link, []byte(\"mailto:\")) {\n\t\treturn link[7:]\n\t} else {\n\t\treturn link\n\t}\n}\n\n// autolinkType specifies a kind of autolink that gets detected.\ntype autolinkType int\n\n// These are the possible flag values for the autolink renderer.\nconst (\n\tnotAutolink autolinkType = iota\n\tnormalAutolink\n\temailAutolink\n)\n\n// '<' when tags or autolinks are allowed\nfunc leftAngle(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\taltype, end := tagLength(data)\n\tif size := p.inlineHTMLComment(data); size > 0 {\n\t\tend = size\n\t}\n\tif end > 2 {\n\t\tif altype != notAutolink {\n\t\t\tvar uLink bytes.Buffer\n\t\t\tunescapeText(&uLink, data[1:end+1-2])\n\t\t\tif uLink.Len() > 0 {\n\t\t\t\tlink := uLink.Bytes()\n\t\t\t\tnode := NewNode(Link)\n\t\t\t\tnode.Destination = link\n\t\t\t\tif altype == emailAutolink {\n\t\t\t\t\tnode.Destination = append([]byte(\"mailto:\"), link...)\n\t\t\t\t}\n\t\t\t\tnode.AppendChild(text(stripMailto(link)))\n\t\t\t\treturn end, node\n\t\t\t}\n\t\t} else {\n\t\t\thtmlTag := NewNode(HTMLSpan)\n\t\t\thtmlTag.Literal = data[:end]\n\t\t\treturn end, htmlTag\n\t\t}\n\t}\n\n\treturn end, nil\n}\n\n// '\\\\' backslash escape\nvar escapeChars = []byte(\"\\\\`*_{}[]()#+-.!:|&<>~\")\n\nfunc escape(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\n\tif len(data) > 1 {\n\t\tif p.extensions&BackslashLineBreak != 0 && data[1] == '\\n' {\n\t\t\treturn 2, NewNode(Hardbreak)\n\t\t}\n\t\tif bytes.IndexByte(escapeChars, data[1]) < 0 {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\treturn 2, text(data[1:2])\n\t}\n\n\treturn 2, nil\n}\n\nfunc unescapeText(ob *bytes.Buffer, src []byte) {\n\ti := 0\n\tfor i < len(src) {\n\t\torg := i\n\t\tfor i < len(src) && src[i] != '\\\\' {\n\t\t\ti++\n\t\t}\n\n\t\tif i > org {\n\t\t\tob.Write(src[org:i])\n\t\t}\n\n\t\tif i+1 >= len(src) {\n\t\t\tbreak\n\t\t}\n\n\t\tob.WriteByte(src[i+1])\n\t\ti += 2\n\t}\n}\n\n// '&' escaped when it doesn't belong to an entity\n// valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;\nfunc entity(p *Markdown, data []byte, offset int) (int, *Node) {\n\tdata = data[offset:]\n\n\tend := 1\n\n\tif end < len(data) && data[end] == '#' {\n\t\tend++\n\t}\n\n\tfor end < len(data) && isalnum(data[end]) {\n\t\tend++\n\t}\n\n\tif end < len(data) && data[end] == ';' {\n\t\tend++ // real entity\n\t} else {\n\t\treturn 0, nil // lone '&'\n\t}\n\n\tent := data[:end]\n\t// undo &amp; escaping or it will be converted to &amp;amp; by another\n\t// escaper in the renderer\n\tif bytes.Equal(ent, []byte(\"&amp;\")) {\n\t\tent = []byte{'&'}\n\t}\n\n\treturn end, text(ent)\n}\n\nfunc linkEndsWithEntity(data []byte, linkEnd int) bool {\n\tentityRanges := htmlEntityRe.FindAllIndex(data[:linkEnd], -1)\n\treturn entityRanges != nil && entityRanges[len(entityRanges)-1][1] == linkEnd\n}\n\n// hasPrefixCaseInsensitive is a custom implementation of\n//     strings.HasPrefix(strings.ToLower(s), prefix)\n// we rolled our own because ToLower pulls in a huge machinery of lowercasing\n// anything from Unicode and that's very slow. Since this func will only be\n// used on ASCII protocol prefixes, we can take shortcuts.\nfunc hasPrefixCaseInsensitive(s, prefix []byte) bool {\n\tif len(s) < len(prefix) {\n\t\treturn false\n\t}\n\tdelta := byte('a' - 'A')\n\tfor i, b := range prefix {\n\t\tif b != s[i] && b != s[i]+delta {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nvar protocolPrefixes = [][]byte{\n\t[]byte(\"http://\"),\n\t[]byte(\"https://\"),\n\t[]byte(\"ftp://\"),\n\t[]byte(\"file://\"),\n\t[]byte(\"mailto:\"),\n}\n\nconst shortestPrefix = 6 // len(\"ftp://\"), the shortest of the above\n\nfunc maybeAutoLink(p *Markdown, data []byte, offset int) (int, *Node) {\n\t// quick check to rule out most false hits\n\tif p.insideLink || len(data) < offset+shortestPrefix {\n\t\treturn 0, nil\n\t}\n\tfor _, prefix := range protocolPrefixes {\n\t\tendOfHead := offset + 8 // 8 is the len() of the longest prefix\n\t\tif endOfHead > len(data) {\n\t\t\tendOfHead = len(data)\n\t\t}\n\t\tif hasPrefixCaseInsensitive(data[offset:endOfHead], prefix) {\n\t\t\treturn autoLink(p, data, offset)\n\t\t}\n\t}\n\treturn 0, nil\n}\n\nfunc autoLink(p *Markdown, data []byte, offset int) (int, *Node) {\n\t// Now a more expensive check to see if we're not inside an anchor element\n\tanchorStart := offset\n\toffsetFromAnchor := 0\n\tfor anchorStart > 0 && data[anchorStart] != '<' {\n\t\tanchorStart--\n\t\toffsetFromAnchor++\n\t}\n\n\tanchorStr := anchorRe.Find(data[anchorStart:])\n\tif anchorStr != nil {\n\t\tanchorClose := NewNode(HTMLSpan)\n\t\tanchorClose.Literal = anchorStr[offsetFromAnchor:]\n\t\treturn len(anchorStr) - offsetFromAnchor, anchorClose\n\t}\n\n\t// scan backward for a word boundary\n\trewind := 0\n\tfor offset-rewind > 0 && rewind <= 7 && isletter(data[offset-rewind-1]) {\n\t\trewind++\n\t}\n\tif rewind > 6 { // longest supported protocol is \"mailto\" which has 6 letters\n\t\treturn 0, nil\n\t}\n\n\torigData := data\n\tdata = data[offset-rewind:]\n\n\tif !isSafeLink(data) {\n\t\treturn 0, nil\n\t}\n\n\tlinkEnd := 0\n\tfor linkEnd < len(data) && !isEndOfLink(data[linkEnd]) {\n\t\tlinkEnd++\n\t}\n\n\t// Skip punctuation at the end of the link\n\tif (data[linkEnd-1] == '.' || data[linkEnd-1] == ',') && data[linkEnd-2] != '\\\\' {\n\t\tlinkEnd--\n\t}\n\n\t// But don't skip semicolon if it's a part of escaped entity:\n\tif data[linkEnd-1] == ';' && data[linkEnd-2] != '\\\\' && !linkEndsWithEntity(data, linkEnd) {\n\t\tlinkEnd--\n\t}\n\n\t// See if the link finishes with a punctuation sign that can be closed.\n\tvar copen byte\n\tswitch data[linkEnd-1] {\n\tcase '\"':\n\t\tcopen = '\"'\n\tcase '\\'':\n\t\tcopen = '\\''\n\tcase ')':\n\t\tcopen = '('\n\tcase ']':\n\t\tcopen = '['\n\tcase '}':\n\t\tcopen = '{'\n\tdefault:\n\t\tcopen = 0\n\t}\n\n\tif copen != 0 {\n\t\tbufEnd := offset - rewind + linkEnd - 2\n\n\t\topenDelim := 1\n\n\t\t/* Try to close the final punctuation sign in this same line;\n\t\t * if we managed to close it outside of the URL, that means that it's\n\t\t * not part of the URL. If it closes inside the URL, that means it\n\t\t * is part of the URL.\n\t\t *\n\t\t * Examples:\n\t\t *\n\t\t *      foo http://www.pokemon.com/Pikachu_(Electric) bar\n\t\t *              => http://www.pokemon.com/Pikachu_(Electric)\n\t\t *\n\t\t *      foo (http://www.pokemon.com/Pikachu_(Electric)) bar\n\t\t *              => http://www.pokemon.com/Pikachu_(Electric)\n\t\t *\n\t\t *      foo http://www.pokemon.com/Pikachu_(Electric)) bar\n\t\t *              => http://www.pokemon.com/Pikachu_(Electric))\n\t\t *\n\t\t *      (foo http://www.pokemon.com/Pikachu_(Electric)) bar\n\t\t *              => foo http://www.pokemon.com/Pikachu_(Electric)\n\t\t */\n\n\t\tfor bufEnd >= 0 && origData[bufEnd] != '\\n' && openDelim != 0 {\n\t\t\tif origData[bufEnd] == data[linkEnd-1] {\n\t\t\t\topenDelim++\n\t\t\t}\n\n\t\t\tif origData[bufEnd] == copen {\n\t\t\t\topenDelim--\n\t\t\t}\n\n\t\t\tbufEnd--\n\t\t}\n\n\t\tif openDelim == 0 {\n\t\t\tlinkEnd--\n\t\t}\n\t}\n\n\tvar uLink bytes.Buffer\n\tunescapeText(&uLink, data[:linkEnd])\n\n\tif uLink.Len() > 0 {\n\t\tnode := NewNode(Link)\n\t\tnode.Destination = uLink.Bytes()\n\t\tnode.AppendChild(text(uLink.Bytes()))\n\t\treturn linkEnd, node\n\t}\n\n\treturn linkEnd, nil\n}\n\nfunc isEndOfLink(char byte) bool {\n\treturn isspace(char) || char == '<'\n}\n\nvar validUris = [][]byte{[]byte(\"http://\"), []byte(\"https://\"), []byte(\"ftp://\"), []byte(\"mailto://\")}\nvar validPaths = [][]byte{[]byte(\"/\"), []byte(\"./\"), []byte(\"../\")}\n\nfunc isSafeLink(link []byte) bool {\n\tfor _, path := range validPaths {\n\t\tif len(link) >= len(path) && bytes.Equal(link[:len(path)], path) {\n\t\t\tif len(link) == len(path) {\n\t\t\t\treturn true\n\t\t\t} else if isalnum(link[len(path)]) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\n\tfor _, prefix := range validUris {\n\t\t// TODO: handle unicode here\n\t\t// case-insensitive prefix test\n\t\tif len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isalnum(link[len(prefix)]) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\n// return the length of the given tag, or 0 is it's not valid\nfunc tagLength(data []byte) (autolink autolinkType, end int) {\n\tvar i, j int\n\n\t// a valid tag can't be shorter than 3 chars\n\tif len(data) < 3 {\n\t\treturn notAutolink, 0\n\t}\n\n\t// begins with a '<' optionally followed by '/', followed by letter or number\n\tif data[0] != '<' {\n\t\treturn notAutolink, 0\n\t}\n\tif data[1] == '/' {\n\t\ti = 2\n\t} else {\n\t\ti = 1\n\t}\n\n\tif !isalnum(data[i]) {\n\t\treturn notAutolink, 0\n\t}\n\n\t// scheme test\n\tautolink = notAutolink\n\n\t// try to find the beginning of an URI\n\tfor i < len(data) && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-') {\n\t\ti++\n\t}\n\n\tif i > 1 && i < len(data) && data[i] == '@' {\n\t\tif j = isMailtoAutoLink(data[i:]); j != 0 {\n\t\t\treturn emailAutolink, i + j\n\t\t}\n\t}\n\n\tif i > 2 && i < len(data) && data[i] == ':' {\n\t\tautolink = normalAutolink\n\t\ti++\n\t}\n\n\t// complete autolink test: no whitespace or ' or \"\n\tswitch {\n\tcase i >= len(data):\n\t\tautolink = notAutolink\n\tcase autolink != notAutolink:\n\t\tj = i\n\n\t\tfor i < len(data) {\n\t\t\tif data[i] == '\\\\' {\n\t\t\t\ti += 2\n\t\t\t} else if data[i] == '>' || data[i] == '\\'' || data[i] == '\"' || isspace(data[i]) {\n\t\t\t\tbreak\n\t\t\t} else {\n\t\t\t\ti++\n\t\t\t}\n\n\t\t}\n\n\t\tif i >= len(data) {\n\t\t\treturn autolink, 0\n\t\t}\n\t\tif i > j && data[i] == '>' {\n\t\t\treturn autolink, i + 1\n\t\t}\n\n\t\t// one of the forbidden chars has been found\n\t\tautolink = notAutolink\n\t}\n\ti += bytes.IndexByte(data[i:], '>')\n\tif i < 0 {\n\t\treturn autolink, 0\n\t}\n\treturn autolink, i + 1\n}\n\n// look for the address part of a mail autolink and '>'\n// this is less strict than the original markdown e-mail address matching\nfunc isMailtoAutoLink(data []byte) int {\n\tnb := 0\n\n\t// address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@'\n\tfor i := 0; i < len(data); i++ {\n\t\tif isalnum(data[i]) {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch data[i] {\n\t\tcase '@':\n\t\t\tnb++\n\n\t\tcase '-', '.', '_':\n\t\t\tbreak\n\n\t\tcase '>':\n\t\t\tif nb == 1 {\n\t\t\t\treturn i + 1\n\t\t\t}\n\t\t\treturn 0\n\t\tdefault:\n\t\t\treturn 0\n\t\t}\n\t}\n\n\treturn 0\n}\n\n// look for the next emph char, skipping other constructs\nfunc helperFindEmphChar(data []byte, c byte) int {\n\ti := 0\n\n\tfor i < len(data) {\n\t\tfor i < len(data) && data[i] != c && data[i] != '`' && data[i] != '[' {\n\t\t\ti++\n\t\t}\n\t\tif i >= len(data) {\n\t\t\treturn 0\n\t\t}\n\t\t// do not count escaped chars\n\t\tif i != 0 && data[i-1] == '\\\\' {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\tif data[i] == c {\n\t\t\treturn i\n\t\t}\n\n\t\tif data[i] == '`' {\n\t\t\t// skip a code span\n\t\t\ttmpI := 0\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] != '`' {\n\t\t\t\tif tmpI == 0 && data[i] == c {\n\t\t\t\t\ttmpI = i\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i >= len(data) {\n\t\t\t\treturn tmpI\n\t\t\t}\n\t\t\ti++\n\t\t} else if data[i] == '[' {\n\t\t\t// skip a link\n\t\t\ttmpI := 0\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] != ']' {\n\t\t\t\tif tmpI == 0 && data[i] == c {\n\t\t\t\t\ttmpI = i\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\ti++\n\t\t\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\n') {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i >= len(data) {\n\t\t\t\treturn tmpI\n\t\t\t}\n\t\t\tif data[i] != '[' && data[i] != '(' { // not a link\n\t\t\t\tif tmpI > 0 {\n\t\t\t\t\treturn tmpI\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcc := data[i]\n\t\t\ti++\n\t\t\tfor i < len(data) && data[i] != cc {\n\t\t\t\tif tmpI == 0 && data[i] == c {\n\t\t\t\t\treturn i\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t}\n\t\t\tif i >= len(data) {\n\t\t\t\treturn tmpI\n\t\t\t}\n\t\t\ti++\n\t\t}\n\t}\n\treturn 0\n}\n\nfunc helperEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {\n\ti := 0\n\n\t// skip one symbol if coming from emph3\n\tif len(data) > 1 && data[0] == c && data[1] == c {\n\t\ti = 1\n\t}\n\n\tfor i < len(data) {\n\t\tlength := helperFindEmphChar(data[i:], c)\n\t\tif length == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\t\ti += length\n\t\tif i >= len(data) {\n\t\t\treturn 0, nil\n\t\t}\n\n\t\tif i+1 < len(data) && data[i+1] == c {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\tif data[i] == c && !isspace(data[i-1]) {\n\n\t\t\tif p.extensions&NoIntraEmphasis != 0 {\n\t\t\t\tif !(i+1 == len(data) || isspace(data[i+1]) || ispunct(data[i+1])) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\temph := NewNode(Emph)\n\t\t\tp.inline(emph, data[:i])\n\t\t\treturn i + 1, emph\n\t\t}\n\t}\n\n\treturn 0, nil\n}\n\nfunc helperDoubleEmphasis(p *Markdown, data []byte, c byte) (int, *Node) {\n\ti := 0\n\n\tfor i < len(data) {\n\t\tlength := helperFindEmphChar(data[i:], c)\n\t\tif length == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\t\ti += length\n\n\t\tif i+1 < len(data) && data[i] == c && data[i+1] == c && i > 0 && !isspace(data[i-1]) {\n\t\t\tnodeType := Strong\n\t\t\tif c == '~' {\n\t\t\t\tnodeType = Del\n\t\t\t}\n\t\t\tnode := NewNode(nodeType)\n\t\t\tp.inline(node, data[:i])\n\t\t\treturn i + 2, node\n\t\t}\n\t\ti++\n\t}\n\treturn 0, nil\n}\n\nfunc helperTripleEmphasis(p *Markdown, data []byte, offset int, c byte) (int, *Node) {\n\ti := 0\n\torigData := data\n\tdata = data[offset:]\n\n\tfor i < len(data) {\n\t\tlength := helperFindEmphChar(data[i:], c)\n\t\tif length == 0 {\n\t\t\treturn 0, nil\n\t\t}\n\t\ti += length\n\n\t\t// skip whitespace preceded symbols\n\t\tif data[i] != c || isspace(data[i-1]) {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch {\n\t\tcase i+2 < len(data) && data[i+1] == c && data[i+2] == c:\n\t\t\t// triple symbol found\n\t\t\tstrong := NewNode(Strong)\n\t\t\tem := NewNode(Emph)\n\t\t\tstrong.AppendChild(em)\n\t\t\tp.inline(em, data[:i])\n\t\t\treturn i + 3, strong\n\t\tcase (i+1 < len(data) && data[i+1] == c):\n\t\t\t// double symbol found, hand over to emph1\n\t\t\tlength, node := helperEmphasis(p, origData[offset-2:], c)\n\t\t\tif length == 0 {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\t\t\treturn length - 2, node\n\t\tdefault:\n\t\t\t// single symbol found, hand over to emph2\n\t\t\tlength, node := helperDoubleEmphasis(p, origData[offset-1:], c)\n\t\t\tif length == 0 {\n\t\t\t\treturn 0, nil\n\t\t\t}\n\t\t\treturn length - 1, node\n\t\t}\n\t}\n\treturn 0, nil\n}\n\nfunc text(s []byte) *Node {\n\tnode := NewNode(Text)\n\tnode.Literal = s\n\treturn node\n}\n\nfunc normalizeURI(s []byte) []byte {\n\treturn s // TODO: implement\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/markdown.go",
    "content": "// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n//\n// Markdown parsing and processing\n//\n\n// Version string of the package. Appears in the rendered document when\n// CompletePage flag is on.\nconst Version = \"2.0\"\n\n// Extensions is a bitwise or'ed collection of enabled Blackfriday's\n// extensions.\ntype Extensions int\n\n// These are the supported markdown parsing extensions.\n// OR these values together to select multiple extensions.\nconst (\n\tNoExtensions           Extensions = 0\n\tNoIntraEmphasis        Extensions = 1 << iota // Ignore emphasis markers inside words\n\tTables                                        // Render tables\n\tFencedCode                                    // Render fenced code blocks\n\tAutolink                                      // Detect embedded URLs that are not explicitly marked\n\tStrikethrough                                 // Strikethrough text using ~~test~~\n\tLaxHTMLBlocks                                 // Loosen up HTML block parsing rules\n\tSpaceHeadings                                 // Be strict about prefix heading rules\n\tHardLineBreak                                 // Translate newlines into line breaks\n\tTabSizeEight                                  // Expand tabs to eight spaces instead of four\n\tFootnotes                                     // Pandoc-style footnotes\n\tNoEmptyLineBeforeBlock                        // No need to insert an empty line to start a (code, quote, ordered list, unordered list) block\n\tHeadingIDs                                    // specify heading IDs  with {#id}\n\tTitleblock                                    // Titleblock ala pandoc\n\tAutoHeadingIDs                                // Create the heading ID from the text\n\tBackslashLineBreak                            // Translate trailing backslashes into line breaks\n\tDefinitionLists                               // Render definition lists\n\n\tCommonHTMLFlags HTMLFlags = UseXHTML | Smartypants |\n\t\tSmartypantsFractions | SmartypantsDashes | SmartypantsLatexDashes\n\n\tCommonExtensions Extensions = NoIntraEmphasis | Tables | FencedCode |\n\t\tAutolink | Strikethrough | SpaceHeadings | HeadingIDs |\n\t\tBackslashLineBreak | DefinitionLists\n)\n\n// ListType contains bitwise or'ed flags for list and list item objects.\ntype ListType int\n\n// These are the possible flag values for the ListItem renderer.\n// Multiple flag values may be ORed together.\n// These are mostly of interest if you are writing a new output format.\nconst (\n\tListTypeOrdered ListType = 1 << iota\n\tListTypeDefinition\n\tListTypeTerm\n\n\tListItemContainsBlock\n\tListItemBeginningOfList // TODO: figure out if this is of any use now\n\tListItemEndOfList\n)\n\n// CellAlignFlags holds a type of alignment in a table cell.\ntype CellAlignFlags int\n\n// These are the possible flag values for the table cell renderer.\n// Only a single one of these values will be used; they are not ORed together.\n// These are mostly of interest if you are writing a new output format.\nconst (\n\tTableAlignmentLeft CellAlignFlags = 1 << iota\n\tTableAlignmentRight\n\tTableAlignmentCenter = (TableAlignmentLeft | TableAlignmentRight)\n)\n\n// The size of a tab stop.\nconst (\n\tTabSizeDefault = 4\n\tTabSizeDouble  = 8\n)\n\n// blockTags is a set of tags that are recognized as HTML block tags.\n// Any of these can be included in markdown text without special escaping.\nvar blockTags = map[string]struct{}{\n\t\"blockquote\": {},\n\t\"del\":        {},\n\t\"div\":        {},\n\t\"dl\":         {},\n\t\"fieldset\":   {},\n\t\"form\":       {},\n\t\"h1\":         {},\n\t\"h2\":         {},\n\t\"h3\":         {},\n\t\"h4\":         {},\n\t\"h5\":         {},\n\t\"h6\":         {},\n\t\"iframe\":     {},\n\t\"ins\":        {},\n\t\"math\":       {},\n\t\"noscript\":   {},\n\t\"ol\":         {},\n\t\"pre\":        {},\n\t\"p\":          {},\n\t\"script\":     {},\n\t\"style\":      {},\n\t\"table\":      {},\n\t\"ul\":         {},\n\n\t// HTML5\n\t\"address\":    {},\n\t\"article\":    {},\n\t\"aside\":      {},\n\t\"canvas\":     {},\n\t\"figcaption\": {},\n\t\"figure\":     {},\n\t\"footer\":     {},\n\t\"header\":     {},\n\t\"hgroup\":     {},\n\t\"main\":       {},\n\t\"nav\":        {},\n\t\"output\":     {},\n\t\"progress\":   {},\n\t\"section\":    {},\n\t\"video\":      {},\n}\n\n// Renderer is the rendering interface. This is mostly of interest if you are\n// implementing a new rendering format.\n//\n// Only an HTML implementation is provided in this repository, see the README\n// for external implementations.\ntype Renderer interface {\n\t// RenderNode is the main rendering method. It will be called once for\n\t// every leaf node and twice for every non-leaf node (first with\n\t// entering=true, then with entering=false). The method should write its\n\t// rendition of the node to the supplied writer w.\n\tRenderNode(w io.Writer, node *Node, entering bool) WalkStatus\n\n\t// RenderHeader is a method that allows the renderer to produce some\n\t// content preceding the main body of the output document. The header is\n\t// understood in the broad sense here. For example, the default HTML\n\t// renderer will write not only the HTML document preamble, but also the\n\t// table of contents if it was requested.\n\t//\n\t// The method will be passed an entire document tree, in case a particular\n\t// implementation needs to inspect it to produce output.\n\t//\n\t// The output should be written to the supplied writer w. If your\n\t// implementation has no header to write, supply an empty implementation.\n\tRenderHeader(w io.Writer, ast *Node)\n\n\t// RenderFooter is a symmetric counterpart of RenderHeader.\n\tRenderFooter(w io.Writer, ast *Node)\n}\n\n// Callback functions for inline parsing. One such function is defined\n// for each character that triggers a response when parsing inline data.\ntype inlineParser func(p *Markdown, data []byte, offset int) (int, *Node)\n\n// Markdown is a type that holds extensions and the runtime state used by\n// Parse, and the renderer. You can not use it directly, construct it with New.\ntype Markdown struct {\n\trenderer          Renderer\n\treferenceOverride ReferenceOverrideFunc\n\trefs              map[string]*reference\n\tinlineCallback    [256]inlineParser\n\textensions        Extensions\n\tnesting           int\n\tmaxNesting        int\n\tinsideLink        bool\n\n\t// Footnotes need to be ordered as well as available to quickly check for\n\t// presence. If a ref is also a footnote, it's stored both in refs and here\n\t// in notes. Slice is nil if footnotes not enabled.\n\tnotes []*reference\n\n\tdoc                  *Node\n\ttip                  *Node // = doc\n\toldTip               *Node\n\tlastMatchedContainer *Node // = doc\n\tallClosed            bool\n}\n\nfunc (p *Markdown) getRef(refid string) (ref *reference, found bool) {\n\tif p.referenceOverride != nil {\n\t\tr, overridden := p.referenceOverride(refid)\n\t\tif overridden {\n\t\t\tif r == nil {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\treturn &reference{\n\t\t\t\tlink:     []byte(r.Link),\n\t\t\t\ttitle:    []byte(r.Title),\n\t\t\t\tnoteID:   0,\n\t\t\t\thasBlock: false,\n\t\t\t\ttext:     []byte(r.Text)}, true\n\t\t}\n\t}\n\t// refs are case insensitive\n\tref, found = p.refs[strings.ToLower(refid)]\n\treturn ref, found\n}\n\nfunc (p *Markdown) finalize(block *Node) {\n\tabove := block.Parent\n\tblock.open = false\n\tp.tip = above\n}\n\nfunc (p *Markdown) addChild(node NodeType, offset uint32) *Node {\n\treturn p.addExistingChild(NewNode(node), offset)\n}\n\nfunc (p *Markdown) addExistingChild(node *Node, offset uint32) *Node {\n\tfor !p.tip.canContain(node.Type) {\n\t\tp.finalize(p.tip)\n\t}\n\tp.tip.AppendChild(node)\n\tp.tip = node\n\treturn node\n}\n\nfunc (p *Markdown) closeUnmatchedBlocks() {\n\tif !p.allClosed {\n\t\tfor p.oldTip != p.lastMatchedContainer {\n\t\t\tparent := p.oldTip.Parent\n\t\t\tp.finalize(p.oldTip)\n\t\t\tp.oldTip = parent\n\t\t}\n\t\tp.allClosed = true\n\t}\n}\n\n//\n//\n// Public interface\n//\n//\n\n// Reference represents the details of a link.\n// See the documentation in Options for more details on use-case.\ntype Reference struct {\n\t// Link is usually the URL the reference points to.\n\tLink string\n\t// Title is the alternate text describing the link in more detail.\n\tTitle string\n\t// Text is the optional text to override the ref with if the syntax used was\n\t// [refid][]\n\tText string\n}\n\n// ReferenceOverrideFunc is expected to be called with a reference string and\n// return either a valid Reference type that the reference string maps to or\n// nil. If overridden is false, the default reference logic will be executed.\n// See the documentation in Options for more details on use-case.\ntype ReferenceOverrideFunc func(reference string) (ref *Reference, overridden bool)\n\n// New constructs a Markdown processor. You can use the same With* functions as\n// for Run() to customize parser's behavior and the renderer.\nfunc New(opts ...Option) *Markdown {\n\tvar p Markdown\n\tfor _, opt := range opts {\n\t\topt(&p)\n\t}\n\tp.refs = make(map[string]*reference)\n\tp.maxNesting = 16\n\tp.insideLink = false\n\tdocNode := NewNode(Document)\n\tp.doc = docNode\n\tp.tip = docNode\n\tp.oldTip = docNode\n\tp.lastMatchedContainer = docNode\n\tp.allClosed = true\n\t// register inline parsers\n\tp.inlineCallback[' '] = maybeLineBreak\n\tp.inlineCallback['*'] = emphasis\n\tp.inlineCallback['_'] = emphasis\n\tif p.extensions&Strikethrough != 0 {\n\t\tp.inlineCallback['~'] = emphasis\n\t}\n\tp.inlineCallback['`'] = codeSpan\n\tp.inlineCallback['\\n'] = lineBreak\n\tp.inlineCallback['['] = link\n\tp.inlineCallback['<'] = leftAngle\n\tp.inlineCallback['\\\\'] = escape\n\tp.inlineCallback['&'] = entity\n\tp.inlineCallback['!'] = maybeImage\n\tp.inlineCallback['^'] = maybeInlineFootnote\n\tif p.extensions&Autolink != 0 {\n\t\tp.inlineCallback['h'] = maybeAutoLink\n\t\tp.inlineCallback['m'] = maybeAutoLink\n\t\tp.inlineCallback['f'] = maybeAutoLink\n\t\tp.inlineCallback['H'] = maybeAutoLink\n\t\tp.inlineCallback['M'] = maybeAutoLink\n\t\tp.inlineCallback['F'] = maybeAutoLink\n\t}\n\tif p.extensions&Footnotes != 0 {\n\t\tp.notes = make([]*reference, 0)\n\t}\n\treturn &p\n}\n\n// Option customizes the Markdown processor's default behavior.\ntype Option func(*Markdown)\n\n// WithRenderer allows you to override the default renderer.\nfunc WithRenderer(r Renderer) Option {\n\treturn func(p *Markdown) {\n\t\tp.renderer = r\n\t}\n}\n\n// WithExtensions allows you to pick some of the many extensions provided by\n// Blackfriday. You can bitwise OR them.\nfunc WithExtensions(e Extensions) Option {\n\treturn func(p *Markdown) {\n\t\tp.extensions = e\n\t}\n}\n\n// WithNoExtensions turns off all extensions and custom behavior.\nfunc WithNoExtensions() Option {\n\treturn func(p *Markdown) {\n\t\tp.extensions = NoExtensions\n\t\tp.renderer = NewHTMLRenderer(HTMLRendererParameters{\n\t\t\tFlags: HTMLFlagsNone,\n\t\t})\n\t}\n}\n\n// WithRefOverride sets an optional function callback that is called every\n// time a reference is resolved.\n//\n// In Markdown, the link reference syntax can be made to resolve a link to\n// a reference instead of an inline URL, in one of the following ways:\n//\n//  * [link text][refid]\n//  * [refid][]\n//\n// Usually, the refid is defined at the bottom of the Markdown document. If\n// this override function is provided, the refid is passed to the override\n// function first, before consulting the defined refids at the bottom. If\n// the override function indicates an override did not occur, the refids at\n// the bottom will be used to fill in the link details.\nfunc WithRefOverride(o ReferenceOverrideFunc) Option {\n\treturn func(p *Markdown) {\n\t\tp.referenceOverride = o\n\t}\n}\n\n// Run is the main entry point to Blackfriday. It parses and renders a\n// block of markdown-encoded text.\n//\n// The simplest invocation of Run takes one argument, input:\n//     output := Run(input)\n// This will parse the input with CommonExtensions enabled and render it with\n// the default HTMLRenderer (with CommonHTMLFlags).\n//\n// Variadic arguments opts can customize the default behavior. Since Markdown\n// type does not contain exported fields, you can not use it directly. Instead,\n// use the With* functions. For example, this will call the most basic\n// functionality, with no extensions:\n//     output := Run(input, WithNoExtensions())\n//\n// You can use any number of With* arguments, even contradicting ones. They\n// will be applied in order of appearance and the latter will override the\n// former:\n//     output := Run(input, WithNoExtensions(), WithExtensions(exts),\n//         WithRenderer(yourRenderer))\nfunc Run(input []byte, opts ...Option) []byte {\n\tr := NewHTMLRenderer(HTMLRendererParameters{\n\t\tFlags: CommonHTMLFlags,\n\t})\n\toptList := []Option{WithRenderer(r), WithExtensions(CommonExtensions)}\n\toptList = append(optList, opts...)\n\tparser := New(optList...)\n\tast := parser.Parse(input)\n\tvar buf bytes.Buffer\n\tparser.renderer.RenderHeader(&buf, ast)\n\tast.Walk(func(node *Node, entering bool) WalkStatus {\n\t\treturn parser.renderer.RenderNode(&buf, node, entering)\n\t})\n\tparser.renderer.RenderFooter(&buf, ast)\n\treturn buf.Bytes()\n}\n\n// Parse is an entry point to the parsing part of Blackfriday. It takes an\n// input markdown document and produces a syntax tree for its contents. This\n// tree can then be rendered with a default or custom renderer, or\n// analyzed/transformed by the caller to whatever non-standard needs they have.\n// The return value is the root node of the syntax tree.\nfunc (p *Markdown) Parse(input []byte) *Node {\n\tp.block(input)\n\t// Walk the tree and finish up some of unfinished blocks\n\tfor p.tip != nil {\n\t\tp.finalize(p.tip)\n\t}\n\t// Walk the tree again and process inline markdown in each block\n\tp.doc.Walk(func(node *Node, entering bool) WalkStatus {\n\t\tif node.Type == Paragraph || node.Type == Heading || node.Type == TableCell {\n\t\t\tp.inline(node, node.content)\n\t\t\tnode.content = nil\n\t\t}\n\t\treturn GoToNext\n\t})\n\tp.parseRefsToAST()\n\treturn p.doc\n}\n\nfunc (p *Markdown) parseRefsToAST() {\n\tif p.extensions&Footnotes == 0 || len(p.notes) == 0 {\n\t\treturn\n\t}\n\tp.tip = p.doc\n\tblock := p.addBlock(List, nil)\n\tblock.IsFootnotesList = true\n\tblock.ListFlags = ListTypeOrdered\n\tflags := ListItemBeginningOfList\n\t// Note: this loop is intentionally explicit, not range-form. This is\n\t// because the body of the loop will append nested footnotes to p.notes and\n\t// we need to process those late additions. Range form would only walk over\n\t// the fixed initial set.\n\tfor i := 0; i < len(p.notes); i++ {\n\t\tref := p.notes[i]\n\t\tp.addExistingChild(ref.footnote, 0)\n\t\tblock := ref.footnote\n\t\tblock.ListFlags = flags | ListTypeOrdered\n\t\tblock.RefLink = ref.link\n\t\tif ref.hasBlock {\n\t\t\tflags |= ListItemContainsBlock\n\t\t\tp.block(ref.title)\n\t\t} else {\n\t\t\tp.inline(block, ref.title)\n\t\t}\n\t\tflags &^= ListItemBeginningOfList | ListItemContainsBlock\n\t}\n\tabove := block.Parent\n\tfinalizeList(block)\n\tp.tip = above\n\tblock.Walk(func(node *Node, entering bool) WalkStatus {\n\t\tif node.Type == Paragraph || node.Type == Heading {\n\t\t\tp.inline(node, node.content)\n\t\t\tnode.content = nil\n\t\t}\n\t\treturn GoToNext\n\t})\n}\n\n//\n// Link references\n//\n// This section implements support for references that (usually) appear\n// as footnotes in a document, and can be referenced anywhere in the document.\n// The basic format is:\n//\n//    [1]: http://www.google.com/ \"Google\"\n//    [2]: http://www.github.com/ \"Github\"\n//\n// Anywhere in the document, the reference can be linked by referring to its\n// label, i.e., 1 and 2 in this example, as in:\n//\n//    This library is hosted on [Github][2], a git hosting site.\n//\n// Actual footnotes as specified in Pandoc and supported by some other Markdown\n// libraries such as php-markdown are also taken care of. They look like this:\n//\n//    This sentence needs a bit of further explanation.[^note]\n//\n//    [^note]: This is the explanation.\n//\n// Footnotes should be placed at the end of the document in an ordered list.\n// Finally, there are inline footnotes such as:\n//\n//    Inline footnotes^[Also supported.] provide a quick inline explanation,\n//    but are rendered at the bottom of the document.\n//\n\n// reference holds all information necessary for a reference-style links or\n// footnotes.\n//\n// Consider this markdown with reference-style links:\n//\n//     [link][ref]\n//\n//     [ref]: /url/ \"tooltip title\"\n//\n// It will be ultimately converted to this HTML:\n//\n//     <p><a href=\\\"/url/\\\" title=\\\"title\\\">link</a></p>\n//\n// And a reference structure will be populated as follows:\n//\n//     p.refs[\"ref\"] = &reference{\n//         link: \"/url/\",\n//         title: \"tooltip title\",\n//     }\n//\n// Alternatively, reference can contain information about a footnote. Consider\n// this markdown:\n//\n//     Text needing a footnote.[^a]\n//\n//     [^a]: This is the note\n//\n// A reference structure will be populated as follows:\n//\n//     p.refs[\"a\"] = &reference{\n//         link: \"a\",\n//         title: \"This is the note\",\n//         noteID: <some positive int>,\n//     }\n//\n// TODO: As you can see, it begs for splitting into two dedicated structures\n// for refs and for footnotes.\ntype reference struct {\n\tlink     []byte\n\ttitle    []byte\n\tnoteID   int // 0 if not a footnote ref\n\thasBlock bool\n\tfootnote *Node // a link to the Item node within a list of footnotes\n\n\ttext []byte // only gets populated by refOverride feature with Reference.Text\n}\n\nfunc (r *reference) String() string {\n\treturn fmt.Sprintf(\"{link: %q, title: %q, text: %q, noteID: %d, hasBlock: %v}\",\n\t\tr.link, r.title, r.text, r.noteID, r.hasBlock)\n}\n\n// Check whether or not data starts with a reference link.\n// If so, it is parsed and stored in the list of references\n// (in the render struct).\n// Returns the number of bytes to skip to move past it,\n// or zero if the first line is not a reference.\nfunc isReference(p *Markdown, data []byte, tabSize int) int {\n\t// up to 3 optional leading spaces\n\tif len(data) < 4 {\n\t\treturn 0\n\t}\n\ti := 0\n\tfor i < 3 && data[i] == ' ' {\n\t\ti++\n\t}\n\n\tnoteID := 0\n\n\t// id part: anything but a newline between brackets\n\tif data[i] != '[' {\n\t\treturn 0\n\t}\n\ti++\n\tif p.extensions&Footnotes != 0 {\n\t\tif i < len(data) && data[i] == '^' {\n\t\t\t// we can set it to anything here because the proper noteIds will\n\t\t\t// be assigned later during the second pass. It just has to be != 0\n\t\t\tnoteID = 1\n\t\t\ti++\n\t\t}\n\t}\n\tidOffset := i\n\tfor i < len(data) && data[i] != '\\n' && data[i] != '\\r' && data[i] != ']' {\n\t\ti++\n\t}\n\tif i >= len(data) || data[i] != ']' {\n\t\treturn 0\n\t}\n\tidEnd := i\n\t// footnotes can have empty ID, like this: [^], but a reference can not be\n\t// empty like this: []. Break early if it's not a footnote and there's no ID\n\tif noteID == 0 && idOffset == idEnd {\n\t\treturn 0\n\t}\n\t// spacer: colon (space | tab)* newline? (space | tab)*\n\ti++\n\tif i >= len(data) || data[i] != ':' {\n\t\treturn 0\n\t}\n\ti++\n\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\ti++\n\t}\n\tif i < len(data) && (data[i] == '\\n' || data[i] == '\\r') {\n\t\ti++\n\t\tif i < len(data) && data[i] == '\\n' && data[i-1] == '\\r' {\n\t\t\ti++\n\t\t}\n\t}\n\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\ti++\n\t}\n\tif i >= len(data) {\n\t\treturn 0\n\t}\n\n\tvar (\n\t\tlinkOffset, linkEnd   int\n\t\ttitleOffset, titleEnd int\n\t\tlineEnd               int\n\t\traw                   []byte\n\t\thasBlock              bool\n\t)\n\n\tif p.extensions&Footnotes != 0 && noteID != 0 {\n\t\tlinkOffset, linkEnd, raw, hasBlock = scanFootnote(p, data, i, tabSize)\n\t\tlineEnd = linkEnd\n\t} else {\n\t\tlinkOffset, linkEnd, titleOffset, titleEnd, lineEnd = scanLinkRef(p, data, i)\n\t}\n\tif lineEnd == 0 {\n\t\treturn 0\n\t}\n\n\t// a valid ref has been found\n\n\tref := &reference{\n\t\tnoteID:   noteID,\n\t\thasBlock: hasBlock,\n\t}\n\n\tif noteID > 0 {\n\t\t// reusing the link field for the id since footnotes don't have links\n\t\tref.link = data[idOffset:idEnd]\n\t\t// if footnote, it's not really a title, it's the contained text\n\t\tref.title = raw\n\t} else {\n\t\tref.link = data[linkOffset:linkEnd]\n\t\tref.title = data[titleOffset:titleEnd]\n\t}\n\n\t// id matches are case-insensitive\n\tid := string(bytes.ToLower(data[idOffset:idEnd]))\n\n\tp.refs[id] = ref\n\n\treturn lineEnd\n}\n\nfunc scanLinkRef(p *Markdown, data []byte, i int) (linkOffset, linkEnd, titleOffset, titleEnd, lineEnd int) {\n\t// link: whitespace-free sequence, optionally between angle brackets\n\tif data[i] == '<' {\n\t\ti++\n\t}\n\tlinkOffset = i\n\tfor i < len(data) && data[i] != ' ' && data[i] != '\\t' && data[i] != '\\n' && data[i] != '\\r' {\n\t\ti++\n\t}\n\tlinkEnd = i\n\tif data[linkOffset] == '<' && data[linkEnd-1] == '>' {\n\t\tlinkOffset++\n\t\tlinkEnd--\n\t}\n\n\t// optional spacer: (space | tab)* (newline | '\\'' | '\"' | '(' )\n\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\ti++\n\t}\n\tif i < len(data) && data[i] != '\\n' && data[i] != '\\r' && data[i] != '\\'' && data[i] != '\"' && data[i] != '(' {\n\t\treturn\n\t}\n\n\t// compute end-of-line\n\tif i >= len(data) || data[i] == '\\r' || data[i] == '\\n' {\n\t\tlineEnd = i\n\t}\n\tif i+1 < len(data) && data[i] == '\\r' && data[i+1] == '\\n' {\n\t\tlineEnd++\n\t}\n\n\t// optional (space|tab)* spacer after a newline\n\tif lineEnd > 0 {\n\t\ti = lineEnd + 1\n\t\tfor i < len(data) && (data[i] == ' ' || data[i] == '\\t') {\n\t\t\ti++\n\t\t}\n\t}\n\n\t// optional title: any non-newline sequence enclosed in '\"() alone on its line\n\tif i+1 < len(data) && (data[i] == '\\'' || data[i] == '\"' || data[i] == '(') {\n\t\ti++\n\t\ttitleOffset = i\n\n\t\t// look for EOL\n\t\tfor i < len(data) && data[i] != '\\n' && data[i] != '\\r' {\n\t\t\ti++\n\t\t}\n\t\tif i+1 < len(data) && data[i] == '\\n' && data[i+1] == '\\r' {\n\t\t\ttitleEnd = i + 1\n\t\t} else {\n\t\t\ttitleEnd = i\n\t\t}\n\n\t\t// step back\n\t\ti--\n\t\tfor i > titleOffset && (data[i] == ' ' || data[i] == '\\t') {\n\t\t\ti--\n\t\t}\n\t\tif i > titleOffset && (data[i] == '\\'' || data[i] == '\"' || data[i] == ')') {\n\t\t\tlineEnd = titleEnd\n\t\t\ttitleEnd = i\n\t\t}\n\t}\n\n\treturn\n}\n\n// The first bit of this logic is the same as Parser.listItem, but the rest\n// is much simpler. This function simply finds the entire block and shifts it\n// over by one tab if it is indeed a block (just returns the line if it's not).\n// blockEnd is the end of the section in the input buffer, and contents is the\n// extracted text that was shifted over one tab. It will need to be rendered at\n// the end of the document.\nfunc scanFootnote(p *Markdown, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte, hasBlock bool) {\n\tif i == 0 || len(data) == 0 {\n\t\treturn\n\t}\n\n\t// skip leading whitespace on first line\n\tfor i < len(data) && data[i] == ' ' {\n\t\ti++\n\t}\n\n\tblockStart = i\n\n\t// find the end of the line\n\tblockEnd = i\n\tfor i < len(data) && data[i-1] != '\\n' {\n\t\ti++\n\t}\n\n\t// get working buffer\n\tvar raw bytes.Buffer\n\n\t// put the first line into the working buffer\n\traw.Write(data[blockEnd:i])\n\tblockEnd = i\n\n\t// process the following lines\n\tcontainsBlankLine := false\n\ngatherLines:\n\tfor blockEnd < len(data) {\n\t\ti++\n\n\t\t// find the end of this line\n\t\tfor i < len(data) && data[i-1] != '\\n' {\n\t\t\ti++\n\t\t}\n\n\t\t// if it is an empty line, guess that it is part of this item\n\t\t// and move on to the next line\n\t\tif p.isEmpty(data[blockEnd:i]) > 0 {\n\t\t\tcontainsBlankLine = true\n\t\t\tblockEnd = i\n\t\t\tcontinue\n\t\t}\n\n\t\tn := 0\n\t\tif n = isIndented(data[blockEnd:i], indentSize); n == 0 {\n\t\t\t// this is the end of the block.\n\t\t\t// we don't want to include this last line in the index.\n\t\t\tbreak gatherLines\n\t\t}\n\n\t\t// if there were blank lines before this one, insert a new one now\n\t\tif containsBlankLine {\n\t\t\traw.WriteByte('\\n')\n\t\t\tcontainsBlankLine = false\n\t\t}\n\n\t\t// get rid of that first tab, write to buffer\n\t\traw.Write(data[blockEnd+n : i])\n\t\thasBlock = true\n\n\t\tblockEnd = i\n\t}\n\n\tif data[blockEnd-1] != '\\n' {\n\t\traw.WriteByte('\\n')\n\t}\n\n\tcontents = raw.Bytes()\n\n\treturn\n}\n\n//\n//\n// Miscellaneous helper functions\n//\n//\n\n// Test if a character is a punctuation symbol.\n// Taken from a private function in regexp in the stdlib.\nfunc ispunct(c byte) bool {\n\tfor _, r := range []byte(\"!\\\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~\") {\n\t\tif c == r {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// Test if a character is a whitespace character.\nfunc isspace(c byte) bool {\n\treturn ishorizontalspace(c) || isverticalspace(c)\n}\n\n// Test if a character is a horizontal whitespace character.\nfunc ishorizontalspace(c byte) bool {\n\treturn c == ' ' || c == '\\t'\n}\n\n// Test if a character is a vertical character.\nfunc isverticalspace(c byte) bool {\n\treturn c == '\\n' || c == '\\r' || c == '\\f' || c == '\\v'\n}\n\n// Test if a character is letter.\nfunc isletter(c byte) bool {\n\treturn (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')\n}\n\n// Test if a character is a letter or a digit.\n// TODO: check when this is looking for ASCII alnum and when it should use unicode\nfunc isalnum(c byte) bool {\n\treturn (c >= '0' && c <= '9') || isletter(c)\n}\n\n// Replace tab characters with spaces, aligning to the next TAB_SIZE column.\n// always ends output with a newline\nfunc expandTabs(out *bytes.Buffer, line []byte, tabSize int) {\n\t// first, check for common cases: no tabs, or only tabs at beginning of line\n\ti, prefix := 0, 0\n\tslowcase := false\n\tfor i = 0; i < len(line); i++ {\n\t\tif line[i] == '\\t' {\n\t\t\tif prefix == i {\n\t\t\t\tprefix++\n\t\t\t} else {\n\t\t\t\tslowcase = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// no need to decode runes if all tabs are at the beginning of the line\n\tif !slowcase {\n\t\tfor i = 0; i < prefix*tabSize; i++ {\n\t\t\tout.WriteByte(' ')\n\t\t}\n\t\tout.Write(line[prefix:])\n\t\treturn\n\t}\n\n\t// the slow case: we need to count runes to figure out how\n\t// many spaces to insert for each tab\n\tcolumn := 0\n\ti = 0\n\tfor i < len(line) {\n\t\tstart := i\n\t\tfor i < len(line) && line[i] != '\\t' {\n\t\t\t_, size := utf8.DecodeRune(line[i:])\n\t\t\ti += size\n\t\t\tcolumn++\n\t\t}\n\n\t\tif i > start {\n\t\t\tout.Write(line[start:i])\n\t\t}\n\n\t\tif i >= len(line) {\n\t\t\tbreak\n\t\t}\n\n\t\tfor {\n\t\t\tout.WriteByte(' ')\n\t\t\tcolumn++\n\t\t\tif column%tabSize == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\ti++\n\t}\n}\n\n// Find if a line counts as indented or not.\n// Returns number of characters the indent is (0 = not indented).\nfunc isIndented(data []byte, indentSize int) int {\n\tif len(data) == 0 {\n\t\treturn 0\n\t}\n\tif data[0] == '\\t' {\n\t\treturn 1\n\t}\n\tif len(data) < indentSize {\n\t\treturn 0\n\t}\n\tfor i := 0; i < indentSize; i++ {\n\t\tif data[i] != ' ' {\n\t\t\treturn 0\n\t\t}\n\t}\n\treturn indentSize\n}\n\n// Create a url-safe slug for fragments\nfunc slugify(in []byte) []byte {\n\tif len(in) == 0 {\n\t\treturn in\n\t}\n\tout := make([]byte, 0, len(in))\n\tsym := false\n\n\tfor _, ch := range in {\n\t\tif isalnum(ch) {\n\t\t\tsym = false\n\t\t\tout = append(out, ch)\n\t\t} else if sym {\n\t\t\tcontinue\n\t\t} else {\n\t\t\tout = append(out, '-')\n\t\t\tsym = true\n\t\t}\n\t}\n\tvar a, b int\n\tvar ch byte\n\tfor a, ch = range out {\n\t\tif ch != '-' {\n\t\t\tbreak\n\t\t}\n\t}\n\tfor b = len(out) - 1; b > 0; b-- {\n\t\tif out[b] != '-' {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn out[a : b+1]\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/node.go",
    "content": "package blackfriday\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n)\n\n// NodeType specifies a type of a single node of a syntax tree. Usually one\n// node (and its type) corresponds to a single markdown feature, e.g. emphasis\n// or code block.\ntype NodeType int\n\n// Constants for identifying different types of nodes. See NodeType.\nconst (\n\tDocument NodeType = iota\n\tBlockQuote\n\tList\n\tItem\n\tParagraph\n\tHeading\n\tHorizontalRule\n\tEmph\n\tStrong\n\tDel\n\tLink\n\tImage\n\tText\n\tHTMLBlock\n\tCodeBlock\n\tSoftbreak\n\tHardbreak\n\tCode\n\tHTMLSpan\n\tTable\n\tTableCell\n\tTableHead\n\tTableBody\n\tTableRow\n)\n\nvar nodeTypeNames = []string{\n\tDocument:       \"Document\",\n\tBlockQuote:     \"BlockQuote\",\n\tList:           \"List\",\n\tItem:           \"Item\",\n\tParagraph:      \"Paragraph\",\n\tHeading:        \"Heading\",\n\tHorizontalRule: \"HorizontalRule\",\n\tEmph:           \"Emph\",\n\tStrong:         \"Strong\",\n\tDel:            \"Del\",\n\tLink:           \"Link\",\n\tImage:          \"Image\",\n\tText:           \"Text\",\n\tHTMLBlock:      \"HTMLBlock\",\n\tCodeBlock:      \"CodeBlock\",\n\tSoftbreak:      \"Softbreak\",\n\tHardbreak:      \"Hardbreak\",\n\tCode:           \"Code\",\n\tHTMLSpan:       \"HTMLSpan\",\n\tTable:          \"Table\",\n\tTableCell:      \"TableCell\",\n\tTableHead:      \"TableHead\",\n\tTableBody:      \"TableBody\",\n\tTableRow:       \"TableRow\",\n}\n\nfunc (t NodeType) String() string {\n\treturn nodeTypeNames[t]\n}\n\n// ListData contains fields relevant to a List and Item node type.\ntype ListData struct {\n\tListFlags       ListType\n\tTight           bool   // Skip <p>s around list item data if true\n\tBulletChar      byte   // '*', '+' or '-' in bullet lists\n\tDelimiter       byte   // '.' or ')' after the number in ordered lists\n\tRefLink         []byte // If not nil, turns this list item into a footnote item and triggers different rendering\n\tIsFootnotesList bool   // This is a list of footnotes\n}\n\n// LinkData contains fields relevant to a Link node type.\ntype LinkData struct {\n\tDestination []byte // Destination is what goes into a href\n\tTitle       []byte // Title is the tooltip thing that goes in a title attribute\n\tNoteID      int    // NoteID contains a serial number of a footnote, zero if it's not a footnote\n\tFootnote    *Node  // If it's a footnote, this is a direct link to the footnote Node. Otherwise nil.\n}\n\n// CodeBlockData contains fields relevant to a CodeBlock node type.\ntype CodeBlockData struct {\n\tIsFenced    bool   // Specifies whether it's a fenced code block or an indented one\n\tInfo        []byte // This holds the info string\n\tFenceChar   byte\n\tFenceLength int\n\tFenceOffset int\n}\n\n// TableCellData contains fields relevant to a TableCell node type.\ntype TableCellData struct {\n\tIsHeader bool           // This tells if it's under the header row\n\tAlign    CellAlignFlags // This holds the value for align attribute\n}\n\n// HeadingData contains fields relevant to a Heading node type.\ntype HeadingData struct {\n\tLevel        int    // This holds the heading level number\n\tHeadingID    string // This might hold heading ID, if present\n\tIsTitleblock bool   // Specifies whether it's a title block\n}\n\n// Node is a single element in the abstract syntax tree of the parsed document.\n// It holds connections to the structurally neighboring nodes and, for certain\n// types of nodes, additional information that might be needed when rendering.\ntype Node struct {\n\tType       NodeType // Determines the type of the node\n\tParent     *Node    // Points to the parent\n\tFirstChild *Node    // Points to the first child, if any\n\tLastChild  *Node    // Points to the last child, if any\n\tPrev       *Node    // Previous sibling; nil if it's the first child\n\tNext       *Node    // Next sibling; nil if it's the last child\n\n\tLiteral []byte // Text contents of the leaf nodes\n\n\tHeadingData   // Populated if Type is Heading\n\tListData      // Populated if Type is List\n\tCodeBlockData // Populated if Type is CodeBlock\n\tLinkData      // Populated if Type is Link\n\tTableCellData // Populated if Type is TableCell\n\n\tcontent []byte // Markdown content of the block nodes\n\topen    bool   // Specifies an open block node that has not been finished to process yet\n}\n\n// NewNode allocates a node of a specified type.\nfunc NewNode(typ NodeType) *Node {\n\treturn &Node{\n\t\tType: typ,\n\t\topen: true,\n\t}\n}\n\nfunc (n *Node) String() string {\n\tellipsis := \"\"\n\tsnippet := n.Literal\n\tif len(snippet) > 16 {\n\t\tsnippet = snippet[:16]\n\t\tellipsis = \"...\"\n\t}\n\treturn fmt.Sprintf(\"%s: '%s%s'\", n.Type, snippet, ellipsis)\n}\n\n// Unlink removes node 'n' from the tree.\n// It panics if the node is nil.\nfunc (n *Node) Unlink() {\n\tif n.Prev != nil {\n\t\tn.Prev.Next = n.Next\n\t} else if n.Parent != nil {\n\t\tn.Parent.FirstChild = n.Next\n\t}\n\tif n.Next != nil {\n\t\tn.Next.Prev = n.Prev\n\t} else if n.Parent != nil {\n\t\tn.Parent.LastChild = n.Prev\n\t}\n\tn.Parent = nil\n\tn.Next = nil\n\tn.Prev = nil\n}\n\n// AppendChild adds a node 'child' as a child of 'n'.\n// It panics if either node is nil.\nfunc (n *Node) AppendChild(child *Node) {\n\tchild.Unlink()\n\tchild.Parent = n\n\tif n.LastChild != nil {\n\t\tn.LastChild.Next = child\n\t\tchild.Prev = n.LastChild\n\t\tn.LastChild = child\n\t} else {\n\t\tn.FirstChild = child\n\t\tn.LastChild = child\n\t}\n}\n\n// InsertBefore inserts 'sibling' immediately before 'n'.\n// It panics if either node is nil.\nfunc (n *Node) InsertBefore(sibling *Node) {\n\tsibling.Unlink()\n\tsibling.Prev = n.Prev\n\tif sibling.Prev != nil {\n\t\tsibling.Prev.Next = sibling\n\t}\n\tsibling.Next = n\n\tn.Prev = sibling\n\tsibling.Parent = n.Parent\n\tif sibling.Prev == nil {\n\t\tsibling.Parent.FirstChild = sibling\n\t}\n}\n\n// IsContainer returns true if 'n' can contain children.\nfunc (n *Node) IsContainer() bool {\n\tswitch n.Type {\n\tcase Document:\n\t\tfallthrough\n\tcase BlockQuote:\n\t\tfallthrough\n\tcase List:\n\t\tfallthrough\n\tcase Item:\n\t\tfallthrough\n\tcase Paragraph:\n\t\tfallthrough\n\tcase Heading:\n\t\tfallthrough\n\tcase Emph:\n\t\tfallthrough\n\tcase Strong:\n\t\tfallthrough\n\tcase Del:\n\t\tfallthrough\n\tcase Link:\n\t\tfallthrough\n\tcase Image:\n\t\tfallthrough\n\tcase Table:\n\t\tfallthrough\n\tcase TableHead:\n\t\tfallthrough\n\tcase TableBody:\n\t\tfallthrough\n\tcase TableRow:\n\t\tfallthrough\n\tcase TableCell:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// IsLeaf returns true if 'n' is a leaf node.\nfunc (n *Node) IsLeaf() bool {\n\treturn !n.IsContainer()\n}\n\nfunc (n *Node) canContain(t NodeType) bool {\n\tif n.Type == List {\n\t\treturn t == Item\n\t}\n\tif n.Type == Document || n.Type == BlockQuote || n.Type == Item {\n\t\treturn t != Item\n\t}\n\tif n.Type == Table {\n\t\treturn t == TableHead || t == TableBody\n\t}\n\tif n.Type == TableHead || n.Type == TableBody {\n\t\treturn t == TableRow\n\t}\n\tif n.Type == TableRow {\n\t\treturn t == TableCell\n\t}\n\treturn false\n}\n\n// WalkStatus allows NodeVisitor to have some control over the tree traversal.\n// It is returned from NodeVisitor and different values allow Node.Walk to\n// decide which node to go to next.\ntype WalkStatus int\n\nconst (\n\t// GoToNext is the default traversal of every node.\n\tGoToNext WalkStatus = iota\n\t// SkipChildren tells walker to skip all children of current node.\n\tSkipChildren\n\t// Terminate tells walker to terminate the traversal.\n\tTerminate\n)\n\n// NodeVisitor is a callback to be called when traversing the syntax tree.\n// Called twice for every node: once with entering=true when the branch is\n// first visited, then with entering=false after all the children are done.\ntype NodeVisitor func(node *Node, entering bool) WalkStatus\n\n// Walk is a convenience method that instantiates a walker and starts a\n// traversal of subtree rooted at n.\nfunc (n *Node) Walk(visitor NodeVisitor) {\n\tw := newNodeWalker(n)\n\tfor w.current != nil {\n\t\tstatus := visitor(w.current, w.entering)\n\t\tswitch status {\n\t\tcase GoToNext:\n\t\t\tw.next()\n\t\tcase SkipChildren:\n\t\t\tw.entering = false\n\t\t\tw.next()\n\t\tcase Terminate:\n\t\t\treturn\n\t\t}\n\t}\n}\n\ntype nodeWalker struct {\n\tcurrent  *Node\n\troot     *Node\n\tentering bool\n}\n\nfunc newNodeWalker(root *Node) *nodeWalker {\n\treturn &nodeWalker{\n\t\tcurrent:  root,\n\t\troot:     root,\n\t\tentering: true,\n\t}\n}\n\nfunc (nw *nodeWalker) next() {\n\tif (!nw.current.IsContainer() || !nw.entering) && nw.current == nw.root {\n\t\tnw.current = nil\n\t\treturn\n\t}\n\tif nw.entering && nw.current.IsContainer() {\n\t\tif nw.current.FirstChild != nil {\n\t\t\tnw.current = nw.current.FirstChild\n\t\t\tnw.entering = true\n\t\t} else {\n\t\t\tnw.entering = false\n\t\t}\n\t} else if nw.current.Next == nil {\n\t\tnw.current = nw.current.Parent\n\t\tnw.entering = false\n\t} else {\n\t\tnw.current = nw.current.Next\n\t\tnw.entering = true\n\t}\n}\n\nfunc dump(ast *Node) {\n\tfmt.Println(dumpString(ast))\n}\n\nfunc dumpR(ast *Node, depth int) string {\n\tif ast == nil {\n\t\treturn \"\"\n\t}\n\tindent := bytes.Repeat([]byte(\"\\t\"), depth)\n\tcontent := ast.Literal\n\tif content == nil {\n\t\tcontent = ast.content\n\t}\n\tresult := fmt.Sprintf(\"%s%s(%q)\\n\", indent, ast.Type, content)\n\tfor n := ast.FirstChild; n != nil; n = n.Next {\n\t\tresult += dumpR(n, depth+1)\n\t}\n\treturn result\n}\n\nfunc dumpString(ast *Node) string {\n\treturn dumpR(ast, 0)\n}\n"
  },
  {
    "path": "vendor/github.com/russross/blackfriday/v2/smartypants.go",
    "content": "//\n// Blackfriday Markdown Processor\n// Available at http://github.com/russross/blackfriday\n//\n// Copyright © 2011 Russ Ross <russ@russross.com>.\n// Distributed under the Simplified BSD License.\n// See README.md for details.\n//\n\n//\n//\n// SmartyPants rendering\n//\n//\n\npackage blackfriday\n\nimport (\n\t\"bytes\"\n\t\"io\"\n)\n\n// SPRenderer is a struct containing state of a Smartypants renderer.\ntype SPRenderer struct {\n\tinSingleQuote bool\n\tinDoubleQuote bool\n\tcallbacks     [256]smartCallback\n}\n\nfunc wordBoundary(c byte) bool {\n\treturn c == 0 || isspace(c) || ispunct(c)\n}\n\nfunc tolower(c byte) byte {\n\tif c >= 'A' && c <= 'Z' {\n\t\treturn c - 'A' + 'a'\n\t}\n\treturn c\n}\n\nfunc isdigit(c byte) bool {\n\treturn c >= '0' && c <= '9'\n}\n\nfunc smartQuoteHelper(out *bytes.Buffer, previousChar byte, nextChar byte, quote byte, isOpen *bool, addNBSP bool) bool {\n\t// edge of the buffer is likely to be a tag that we don't get to see,\n\t// so we treat it like text sometimes\n\n\t// enumerate all sixteen possibilities for (previousChar, nextChar)\n\t// each can be one of {0, space, punct, other}\n\tswitch {\n\tcase previousChar == 0 && nextChar == 0:\n\t\t// context is not any help here, so toggle\n\t\t*isOpen = !*isOpen\n\tcase isspace(previousChar) && nextChar == 0:\n\t\t// [ \"] might be [ \"<code>foo...]\n\t\t*isOpen = true\n\tcase ispunct(previousChar) && nextChar == 0:\n\t\t// [!\"] hmm... could be [Run!\"] or [(\"<code>...]\n\t\t*isOpen = false\n\tcase /* isnormal(previousChar) && */ nextChar == 0:\n\t\t// [a\"] is probably a close\n\t\t*isOpen = false\n\tcase previousChar == 0 && isspace(nextChar):\n\t\t// [\" ] might be [...foo</code>\" ]\n\t\t*isOpen = false\n\tcase isspace(previousChar) && isspace(nextChar):\n\t\t// [ \" ] context is not any help here, so toggle\n\t\t*isOpen = !*isOpen\n\tcase ispunct(previousChar) && isspace(nextChar):\n\t\t// [!\" ] is probably a close\n\t\t*isOpen = false\n\tcase /* isnormal(previousChar) && */ isspace(nextChar):\n\t\t// [a\" ] this is one of the easy cases\n\t\t*isOpen = false\n\tcase previousChar == 0 && ispunct(nextChar):\n\t\t// [\"!] hmm... could be [\"$1.95] or [</code>\"!...]\n\t\t*isOpen = false\n\tcase isspace(previousChar) && ispunct(nextChar):\n\t\t// [ \"!] looks more like [ \"$1.95]\n\t\t*isOpen = true\n\tcase ispunct(previousChar) && ispunct(nextChar):\n\t\t// [!\"!] context is not any help here, so toggle\n\t\t*isOpen = !*isOpen\n\tcase /* isnormal(previousChar) && */ ispunct(nextChar):\n\t\t// [a\"!] is probably a close\n\t\t*isOpen = false\n\tcase previousChar == 0 /* && isnormal(nextChar) */ :\n\t\t// [\"a] is probably an open\n\t\t*isOpen = true\n\tcase isspace(previousChar) /* && isnormal(nextChar) */ :\n\t\t// [ \"a] this is one of the easy cases\n\t\t*isOpen = true\n\tcase ispunct(previousChar) /* && isnormal(nextChar) */ :\n\t\t// [!\"a] is probably an open\n\t\t*isOpen = true\n\tdefault:\n\t\t// [a'b] maybe a contraction?\n\t\t*isOpen = false\n\t}\n\n\t// Note that with the limited lookahead, this non-breaking\n\t// space will also be appended to single double quotes.\n\tif addNBSP && !*isOpen {\n\t\tout.WriteString(\"&nbsp;\")\n\t}\n\n\tout.WriteByte('&')\n\tif *isOpen {\n\t\tout.WriteByte('l')\n\t} else {\n\t\tout.WriteByte('r')\n\t}\n\tout.WriteByte(quote)\n\tout.WriteString(\"quo;\")\n\n\tif addNBSP && *isOpen {\n\t\tout.WriteString(\"&nbsp;\")\n\t}\n\n\treturn true\n}\n\nfunc (r *SPRenderer) smartSingleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 2 {\n\t\tt1 := tolower(text[1])\n\n\t\tif t1 == '\\'' {\n\t\t\tnextChar := byte(0)\n\t\t\tif len(text) >= 3 {\n\t\t\t\tnextChar = text[2]\n\t\t\t}\n\t\t\tif smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t}\n\n\t\tif (t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') && (len(text) < 3 || wordBoundary(text[2])) {\n\t\t\tout.WriteString(\"&rsquo;\")\n\t\t\treturn 0\n\t\t}\n\n\t\tif len(text) >= 3 {\n\t\t\tt2 := tolower(text[2])\n\n\t\t\tif ((t1 == 'r' && t2 == 'e') || (t1 == 'l' && t2 == 'l') || (t1 == 'v' && t2 == 'e')) &&\n\t\t\t\t(len(text) < 4 || wordBoundary(text[3])) {\n\t\t\t\tout.WriteString(\"&rsquo;\")\n\t\t\t\treturn 0\n\t\t\t}\n\t\t}\n\t}\n\n\tnextChar := byte(0)\n\tif len(text) > 1 {\n\t\tnextChar = text[1]\n\t}\n\tif smartQuoteHelper(out, previousChar, nextChar, 's', &r.inSingleQuote, false) {\n\t\treturn 0\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartParens(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 3 {\n\t\tt1 := tolower(text[1])\n\t\tt2 := tolower(text[2])\n\n\t\tif t1 == 'c' && t2 == ')' {\n\t\t\tout.WriteString(\"&copy;\")\n\t\t\treturn 2\n\t\t}\n\n\t\tif t1 == 'r' && t2 == ')' {\n\t\t\tout.WriteString(\"&reg;\")\n\t\t\treturn 2\n\t\t}\n\n\t\tif len(text) >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')' {\n\t\t\tout.WriteString(\"&trade;\")\n\t\t\treturn 3\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDash(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 2 {\n\t\tif text[1] == '-' {\n\t\t\tout.WriteString(\"&mdash;\")\n\t\t\treturn 1\n\t\t}\n\n\t\tif wordBoundary(previousChar) && wordBoundary(text[1]) {\n\t\t\tout.WriteString(\"&ndash;\")\n\t\t\treturn 0\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDashLatex(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 3 && text[1] == '-' && text[2] == '-' {\n\t\tout.WriteString(\"&mdash;\")\n\t\treturn 2\n\t}\n\tif len(text) >= 2 && text[1] == '-' {\n\t\tout.WriteString(\"&ndash;\")\n\t\treturn 1\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartAmpVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte, addNBSP bool) int {\n\tif bytes.HasPrefix(text, []byte(\"&quot;\")) {\n\t\tnextChar := byte(0)\n\t\tif len(text) >= 7 {\n\t\t\tnextChar = text[6]\n\t\t}\n\t\tif smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, addNBSP) {\n\t\t\treturn 5\n\t\t}\n\t}\n\n\tif bytes.HasPrefix(text, []byte(\"&#0;\")) {\n\t\treturn 3\n\t}\n\n\tout.WriteByte('&')\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartAmp(angledQuotes, addNBSP bool) func(*bytes.Buffer, byte, []byte) int {\n\tvar quote byte = 'd'\n\tif angledQuotes {\n\t\tquote = 'a'\n\t}\n\n\treturn func(out *bytes.Buffer, previousChar byte, text []byte) int {\n\t\treturn r.smartAmpVariant(out, previousChar, text, quote, addNBSP)\n\t}\n}\n\nfunc (r *SPRenderer) smartPeriod(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 3 && text[1] == '.' && text[2] == '.' {\n\t\tout.WriteString(\"&hellip;\")\n\t\treturn 2\n\t}\n\n\tif len(text) >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.' {\n\t\tout.WriteString(\"&hellip;\")\n\t\treturn 4\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartBacktick(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif len(text) >= 2 && text[1] == '`' {\n\t\tnextChar := byte(0)\n\t\tif len(text) >= 3 {\n\t\t\tnextChar = text[2]\n\t\t}\n\t\tif smartQuoteHelper(out, previousChar, nextChar, 'd', &r.inDoubleQuote, false) {\n\t\t\treturn 1\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartNumberGeneric(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {\n\t\t// is it of the form digits/digits(word boundary)?, i.e., \\d+/\\d+\\b\n\t\t// note: check for regular slash (/) or fraction slash (⁄, 0x2044, or 0xe2 81 84 in utf-8)\n\t\t//       and avoid changing dates like 1/23/2005 into fractions.\n\t\tnumEnd := 0\n\t\tfor len(text) > numEnd && isdigit(text[numEnd]) {\n\t\t\tnumEnd++\n\t\t}\n\t\tif numEnd == 0 {\n\t\t\tout.WriteByte(text[0])\n\t\t\treturn 0\n\t\t}\n\t\tdenStart := numEnd + 1\n\t\tif len(text) > numEnd+3 && text[numEnd] == 0xe2 && text[numEnd+1] == 0x81 && text[numEnd+2] == 0x84 {\n\t\t\tdenStart = numEnd + 3\n\t\t} else if len(text) < numEnd+2 || text[numEnd] != '/' {\n\t\t\tout.WriteByte(text[0])\n\t\t\treturn 0\n\t\t}\n\t\tdenEnd := denStart\n\t\tfor len(text) > denEnd && isdigit(text[denEnd]) {\n\t\t\tdenEnd++\n\t\t}\n\t\tif denEnd == denStart {\n\t\t\tout.WriteByte(text[0])\n\t\t\treturn 0\n\t\t}\n\t\tif len(text) == denEnd || wordBoundary(text[denEnd]) && text[denEnd] != '/' {\n\t\t\tout.WriteString(\"<sup>\")\n\t\t\tout.Write(text[:numEnd])\n\t\t\tout.WriteString(\"</sup>&frasl;<sub>\")\n\t\t\tout.Write(text[denStart:denEnd])\n\t\t\tout.WriteString(\"</sub>\")\n\t\t\treturn denEnd - 1\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartNumber(out *bytes.Buffer, previousChar byte, text []byte) int {\n\tif wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {\n\t\tif text[0] == '1' && text[1] == '/' && text[2] == '2' {\n\t\t\tif len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' {\n\t\t\t\tout.WriteString(\"&frac12;\")\n\t\t\t\treturn 2\n\t\t\t}\n\t\t}\n\n\t\tif text[0] == '1' && text[1] == '/' && text[2] == '4' {\n\t\t\tif len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h') {\n\t\t\t\tout.WriteString(\"&frac14;\")\n\t\t\t\treturn 2\n\t\t\t}\n\t\t}\n\n\t\tif text[0] == '3' && text[1] == '/' && text[2] == '4' {\n\t\t\tif len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's') {\n\t\t\t\tout.WriteString(\"&frac34;\")\n\t\t\t\treturn 2\n\t\t\t}\n\t\t}\n\t}\n\n\tout.WriteByte(text[0])\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDoubleQuoteVariant(out *bytes.Buffer, previousChar byte, text []byte, quote byte) int {\n\tnextChar := byte(0)\n\tif len(text) > 1 {\n\t\tnextChar = text[1]\n\t}\n\tif !smartQuoteHelper(out, previousChar, nextChar, quote, &r.inDoubleQuote, false) {\n\t\tout.WriteString(\"&quot;\")\n\t}\n\n\treturn 0\n}\n\nfunc (r *SPRenderer) smartDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {\n\treturn r.smartDoubleQuoteVariant(out, previousChar, text, 'd')\n}\n\nfunc (r *SPRenderer) smartAngledDoubleQuote(out *bytes.Buffer, previousChar byte, text []byte) int {\n\treturn r.smartDoubleQuoteVariant(out, previousChar, text, 'a')\n}\n\nfunc (r *SPRenderer) smartLeftAngle(out *bytes.Buffer, previousChar byte, text []byte) int {\n\ti := 0\n\n\tfor i < len(text) && text[i] != '>' {\n\t\ti++\n\t}\n\n\tout.Write(text[:i+1])\n\treturn i\n}\n\ntype smartCallback func(out *bytes.Buffer, previousChar byte, text []byte) int\n\n// NewSmartypantsRenderer constructs a Smartypants renderer object.\nfunc NewSmartypantsRenderer(flags HTMLFlags) *SPRenderer {\n\tvar (\n\t\tr SPRenderer\n\n\t\tsmartAmpAngled      = r.smartAmp(true, false)\n\t\tsmartAmpAngledNBSP  = r.smartAmp(true, true)\n\t\tsmartAmpRegular     = r.smartAmp(false, false)\n\t\tsmartAmpRegularNBSP = r.smartAmp(false, true)\n\n\t\taddNBSP = flags&SmartypantsQuotesNBSP != 0\n\t)\n\n\tif flags&SmartypantsAngledQuotes == 0 {\n\t\tr.callbacks['\"'] = r.smartDoubleQuote\n\t\tif !addNBSP {\n\t\t\tr.callbacks['&'] = smartAmpRegular\n\t\t} else {\n\t\t\tr.callbacks['&'] = smartAmpRegularNBSP\n\t\t}\n\t} else {\n\t\tr.callbacks['\"'] = r.smartAngledDoubleQuote\n\t\tif !addNBSP {\n\t\t\tr.callbacks['&'] = smartAmpAngled\n\t\t} else {\n\t\t\tr.callbacks['&'] = smartAmpAngledNBSP\n\t\t}\n\t}\n\tr.callbacks['\\''] = r.smartSingleQuote\n\tr.callbacks['('] = r.smartParens\n\tif flags&SmartypantsDashes != 0 {\n\t\tif flags&SmartypantsLatexDashes == 0 {\n\t\t\tr.callbacks['-'] = r.smartDash\n\t\t} else {\n\t\t\tr.callbacks['-'] = r.smartDashLatex\n\t\t}\n\t}\n\tr.callbacks['.'] = r.smartPeriod\n\tif flags&SmartypantsFractions == 0 {\n\t\tr.callbacks['1'] = r.smartNumber\n\t\tr.callbacks['3'] = r.smartNumber\n\t} else {\n\t\tfor ch := '1'; ch <= '9'; ch++ {\n\t\t\tr.callbacks[ch] = r.smartNumberGeneric\n\t\t}\n\t}\n\tr.callbacks['<'] = r.smartLeftAngle\n\tr.callbacks['`'] = r.smartBacktick\n\treturn &r\n}\n\n// Process is the entry point of the Smartypants renderer.\nfunc (r *SPRenderer) Process(w io.Writer, text []byte) {\n\tmark := 0\n\tfor i := 0; i < len(text); i++ {\n\t\tif action := r.callbacks[text[i]]; action != nil {\n\t\t\tif i > mark {\n\t\t\t\tw.Write(text[mark:i])\n\t\t\t}\n\t\t\tpreviousChar := byte(0)\n\t\t\tif i > 0 {\n\t\t\t\tpreviousChar = text[i-1]\n\t\t\t}\n\t\t\tvar tmp bytes.Buffer\n\t\t\ti += action(&tmp, previousChar, text[i:])\n\t\t\tw.Write(tmp.Bytes())\n\t\t\tmark = i + 1\n\t\t}\n\t}\n\tif mark < len(text) {\n\t\tw.Write(text[mark:])\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/2022.go",
    "content": "package chardet\n\nimport (\n\t\"bytes\"\n)\n\ntype recognizer2022 struct {\n\tcharset string\n\tescapes [][]byte\n}\n\nfunc (r *recognizer2022) Match(input *recognizerInput) (output recognizerOutput) {\n\treturn recognizerOutput{\n\t\tCharset:    r.charset,\n\t\tConfidence: r.matchConfidence(input.input),\n\t}\n}\n\nfunc (r *recognizer2022) matchConfidence(input []byte) int {\n\tvar hits, misses, shifts int\ninput:\n\tfor i := 0; i < len(input); i++ {\n\t\tc := input[i]\n\t\tif c == 0x1B {\n\t\t\tfor _, esc := range r.escapes {\n\t\t\t\tif bytes.HasPrefix(input[i+1:], esc) {\n\t\t\t\t\thits++\n\t\t\t\t\ti += len(esc)\n\t\t\t\t\tcontinue input\n\t\t\t\t}\n\t\t\t}\n\t\t\tmisses++\n\t\t} else if c == 0x0E || c == 0x0F {\n\t\t\tshifts++\n\t\t}\n\t}\n\tif hits == 0 {\n\t\treturn 0\n\t}\n\tquality := (100*hits - 100*misses) / (hits + misses)\n\tif hits+shifts < 5 {\n\t\tquality -= (5 - (hits + shifts)) * 10\n\t}\n\tif quality < 0 {\n\t\tquality = 0\n\t}\n\treturn quality\n}\n\nvar escapeSequences_2022JP = [][]byte{\n\t{0x24, 0x28, 0x43}, // KS X 1001:1992\n\t{0x24, 0x28, 0x44}, // JIS X 212-1990\n\t{0x24, 0x40},       // JIS C 6226-1978\n\t{0x24, 0x41},       // GB 2312-80\n\t{0x24, 0x42},       // JIS X 208-1983\n\t{0x26, 0x40},       // JIS X 208 1990, 1997\n\t{0x28, 0x42},       // ASCII\n\t{0x28, 0x48},       // JIS-Roman\n\t{0x28, 0x49},       // Half-width katakana\n\t{0x28, 0x4a},       // JIS-Roman\n\t{0x2e, 0x41},       // ISO 8859-1\n\t{0x2e, 0x46},       // ISO 8859-7\n}\n\nvar escapeSequences_2022KR = [][]byte{\n\t{0x24, 0x29, 0x43},\n}\n\nvar escapeSequences_2022CN = [][]byte{\n\t{0x24, 0x29, 0x41}, // GB 2312-80\n\t{0x24, 0x29, 0x47}, // CNS 11643-1992 Plane 1\n\t{0x24, 0x2A, 0x48}, // CNS 11643-1992 Plane 2\n\t{0x24, 0x29, 0x45}, // ISO-IR-165\n\t{0x24, 0x2B, 0x49}, // CNS 11643-1992 Plane 3\n\t{0x24, 0x2B, 0x4A}, // CNS 11643-1992 Plane 4\n\t{0x24, 0x2B, 0x4B}, // CNS 11643-1992 Plane 5\n\t{0x24, 0x2B, 0x4C}, // CNS 11643-1992 Plane 6\n\t{0x24, 0x2B, 0x4D}, // CNS 11643-1992 Plane 7\n\t{0x4e},             // SS2\n\t{0x4f},             // SS3\n}\n\nfunc newRecognizer_2022JP() *recognizer2022 {\n\treturn &recognizer2022{\n\t\t\"ISO-2022-JP\",\n\t\tescapeSequences_2022JP,\n\t}\n}\n\nfunc newRecognizer_2022KR() *recognizer2022 {\n\treturn &recognizer2022{\n\t\t\"ISO-2022-KR\",\n\t\tescapeSequences_2022KR,\n\t}\n}\n\nfunc newRecognizer_2022CN() *recognizer2022 {\n\treturn &recognizer2022{\n\t\t\"ISO-2022-CN\",\n\t\tescapeSequences_2022CN,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/AUTHORS",
    "content": "Sheng Yu (yusheng dot sjtu at gmail dot com)\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/LICENSE",
    "content": "Copyright (c) 2012 chardet Authors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, 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\nPartial of the Software is derived from ICU project. See icu-license.html for\nlicense of the derivative portions.\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/README.md",
    "content": "# chardet\n\nchardet is library to automatically detect\n[charset](http://en.wikipedia.org/wiki/Character_encoding) of texts for [Go\nprogramming language](http://golang.org/). It's based on the algorithm and data\nin [ICU](http://icu-project.org/)'s implementation.\n\n## Documentation and Usage\n\nSee [pkgdoc](https://pkg.go.dev/github.com/saintfish/chardet)\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/detector.go",
    "content": "// Package chardet ports character set detection from ICU.\npackage chardet\n\nimport (\n\t\"errors\"\n\t\"sort\"\n)\n\n// Result contains all the information that charset detector gives.\ntype Result struct {\n\t// IANA name of the detected charset.\n\tCharset string\n\t// IANA name of the detected language. It may be empty for some charsets.\n\tLanguage string\n\t// Confidence of the Result. Scale from 1 to 100. The bigger, the more confident.\n\tConfidence int\n}\n\n// Detector implements charset detection.\ntype Detector struct {\n\trecognizers []recognizer\n\tstripTag    bool\n}\n\n// List of charset recognizers\nvar recognizers = []recognizer{\n\tnewRecognizer_utf8(),\n\tnewRecognizer_utf16be(),\n\tnewRecognizer_utf16le(),\n\tnewRecognizer_utf32be(),\n\tnewRecognizer_utf32le(),\n\tnewRecognizer_8859_1_en(),\n\tnewRecognizer_8859_1_da(),\n\tnewRecognizer_8859_1_de(),\n\tnewRecognizer_8859_1_es(),\n\tnewRecognizer_8859_1_fr(),\n\tnewRecognizer_8859_1_it(),\n\tnewRecognizer_8859_1_nl(),\n\tnewRecognizer_8859_1_no(),\n\tnewRecognizer_8859_1_pt(),\n\tnewRecognizer_8859_1_sv(),\n\tnewRecognizer_8859_2_cs(),\n\tnewRecognizer_8859_2_hu(),\n\tnewRecognizer_8859_2_pl(),\n\tnewRecognizer_8859_2_ro(),\n\tnewRecognizer_8859_5_ru(),\n\tnewRecognizer_8859_6_ar(),\n\tnewRecognizer_8859_7_el(),\n\tnewRecognizer_8859_8_I_he(),\n\tnewRecognizer_8859_8_he(),\n\tnewRecognizer_windows_1251(),\n\tnewRecognizer_windows_1256(),\n\tnewRecognizer_KOI8_R(),\n\tnewRecognizer_8859_9_tr(),\n\n\tnewRecognizer_sjis(),\n\tnewRecognizer_gb_18030(),\n\tnewRecognizer_euc_jp(),\n\tnewRecognizer_euc_kr(),\n\tnewRecognizer_big5(),\n\n\tnewRecognizer_2022JP(),\n\tnewRecognizer_2022KR(),\n\tnewRecognizer_2022CN(),\n\n\tnewRecognizer_IBM424_he_rtl(),\n\tnewRecognizer_IBM424_he_ltr(),\n\tnewRecognizer_IBM420_ar_rtl(),\n\tnewRecognizer_IBM420_ar_ltr(),\n}\n\n// NewTextDetector creates a Detector for plain text.\nfunc NewTextDetector() *Detector {\n\treturn &Detector{recognizers, false}\n}\n\n// NewHtmlDetector creates a Detector for Html.\nfunc NewHtmlDetector() *Detector {\n\treturn &Detector{recognizers, true}\n}\n\nvar (\n\tNotDetectedError = errors.New(\"Charset not detected.\")\n)\n\n// DetectBest returns the Result with highest Confidence.\nfunc (d *Detector) DetectBest(b []byte) (r *Result, err error) {\n\tvar all []Result\n\tif all, err = d.DetectAll(b); err == nil {\n\t\tr = &all[0]\n\t}\n\treturn\n}\n\n// DetectAll returns all Results which have non-zero Confidence. The Results are sorted by Confidence in descending order.\nfunc (d *Detector) DetectAll(b []byte) ([]Result, error) {\n\tinput := newRecognizerInput(b, d.stripTag)\n\toutputChan := make(chan recognizerOutput)\n\tfor _, r := range d.recognizers {\n\t\tgo matchHelper(r, input, outputChan)\n\t}\n\toutputs := make([]recognizerOutput, 0, len(d.recognizers))\n\tfor i := 0; i < len(d.recognizers); i++ {\n\t\to := <-outputChan\n\t\tif o.Confidence > 0 {\n\t\t\toutputs = append(outputs, o)\n\t\t}\n\t}\n\tif len(outputs) == 0 {\n\t\treturn nil, NotDetectedError\n\t}\n\n\tsort.Sort(recognizerOutputs(outputs))\n\tdedupOutputs := make([]Result, 0, len(outputs))\n\tfoundCharsets := make(map[string]struct{}, len(outputs))\n\tfor _, o := range outputs {\n\t\tif _, found := foundCharsets[o.Charset]; !found {\n\t\t\tdedupOutputs = append(dedupOutputs, Result(o))\n\t\t\tfoundCharsets[o.Charset] = struct{}{}\n\t\t}\n\t}\n\tif len(dedupOutputs) == 0 {\n\t\treturn nil, NotDetectedError\n\t}\n\treturn dedupOutputs, nil\n}\n\nfunc matchHelper(r recognizer, input *recognizerInput, outputChan chan<- recognizerOutput) {\n\toutputChan <- r.Match(input)\n}\n\ntype recognizerOutputs []recognizerOutput\n\nfunc (r recognizerOutputs) Len() int           { return len(r) }\nfunc (r recognizerOutputs) Less(i, j int) bool { return r[i].Confidence > r[j].Confidence }\nfunc (r recognizerOutputs) Swap(i, j int)      { r[i], r[j] = r[j], r[i] }\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/icu-license.html",
    "content": "<html>\n\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\"></meta>\n<title>ICU License - ICU 1.8.1 and later</title>\n</head>\n\n<body BGCOLOR=\"#ffffff\">\n<h2>ICU License - ICU 1.8.1 and later</h2>\n\n<p>COPYRIGHT AND PERMISSION NOTICE</p>\n\n<p>\nCopyright (c) 1995-2012 International Business Machines Corporation and others\n</p>\n<p>\nAll rights reserved.\n</p>\n<p>\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, and/or sell\ncopies of the Software, and to permit persons\nto whom the Software is furnished to do so, provided that the above\ncopyright notice(s) and this permission notice appear in all copies\nof the Software and that both the above copyright notice(s) and this\npermission notice appear in supporting documentation.\n</p>\n<p>\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, \nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\nPARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL\nTHE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM,\nOR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER\nRESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,\nNEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE\nUSE OR PERFORMANCE OF THIS SOFTWARE.\n</p>\n<p>\nExcept as contained in this notice, the name of a copyright holder shall not be\nused in advertising or otherwise to promote the sale, use or other dealings in\nthis Software without prior written authorization of the copyright holder.\n</p>\n\n<hr>\n<p><small>\nAll trademarks and registered trademarks mentioned herein are the property of their respective owners.\n</small></p>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/multi_byte.go",
    "content": "package chardet\n\nimport (\n\t\"errors\"\n\t\"math\"\n)\n\ntype recognizerMultiByte struct {\n\tcharset     string\n\tlanguage    string\n\tdecoder     charDecoder\n\tcommonChars []uint16\n}\n\ntype charDecoder interface {\n\tDecodeOneChar([]byte) (c uint16, remain []byte, err error)\n}\n\nfunc (r *recognizerMultiByte) Match(input *recognizerInput) (output recognizerOutput) {\n\treturn recognizerOutput{\n\t\tCharset:    r.charset,\n\t\tLanguage:   r.language,\n\t\tConfidence: r.matchConfidence(input),\n\t}\n}\n\nfunc (r *recognizerMultiByte) matchConfidence(input *recognizerInput) int {\n\traw := input.raw\n\tvar c uint16\n\tvar err error\n\tvar totalCharCount, badCharCount, singleByteCharCount, doubleByteCharCount, commonCharCount int\n\tfor c, raw, err = r.decoder.DecodeOneChar(raw); len(raw) > 0; c, raw, err = r.decoder.DecodeOneChar(raw) {\n\t\ttotalCharCount++\n\t\tif err != nil {\n\t\t\tbadCharCount++\n\t\t} else if c <= 0xFF {\n\t\t\tsingleByteCharCount++\n\t\t} else {\n\t\t\tdoubleByteCharCount++\n\t\t\tif r.commonChars != nil && binarySearch(r.commonChars, c) {\n\t\t\t\tcommonCharCount++\n\t\t\t}\n\t\t}\n\t\tif badCharCount >= 2 && badCharCount*5 >= doubleByteCharCount {\n\t\t\treturn 0\n\t\t}\n\t}\n\n\tif doubleByteCharCount <= 10 && badCharCount == 0 {\n\t\tif doubleByteCharCount == 0 && totalCharCount < 10 {\n\t\t\treturn 0\n\t\t} else {\n\t\t\treturn 10\n\t\t}\n\t}\n\n\tif doubleByteCharCount < 20*badCharCount {\n\t\treturn 0\n\t}\n\tif r.commonChars == nil {\n\t\tconfidence := 30 + doubleByteCharCount - 20*badCharCount\n\t\tif confidence > 100 {\n\t\t\tconfidence = 100\n\t\t}\n\t\treturn confidence\n\t}\n\tmaxVal := math.Log(float64(doubleByteCharCount) / 4)\n\tscaleFactor := 90 / maxVal\n\tconfidence := int(math.Log(float64(commonCharCount)+1)*scaleFactor + 10)\n\tif confidence > 100 {\n\t\tconfidence = 100\n\t}\n\tif confidence < 0 {\n\t\tconfidence = 0\n\t}\n\treturn confidence\n}\n\nfunc binarySearch(l []uint16, c uint16) bool {\n\tstart := 0\n\tend := len(l) - 1\n\tfor start <= end {\n\t\tmid := (start + end) / 2\n\t\tif c == l[mid] {\n\t\t\treturn true\n\t\t} else if c < l[mid] {\n\t\t\tend = mid - 1\n\t\t} else {\n\t\t\tstart = mid + 1\n\t\t}\n\t}\n\treturn false\n}\n\nvar eobError = errors.New(\"End of input buffer\")\nvar badCharError = errors.New(\"Decode a bad char\")\n\ntype charDecoder_sjis struct {\n}\n\nfunc (charDecoder_sjis) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) {\n\tif len(input) == 0 {\n\t\treturn 0, nil, eobError\n\t}\n\tfirst := input[0]\n\tc = uint16(first)\n\tremain = input[1:]\n\tif first <= 0x7F || (first > 0xA0 && first <= 0xDF) {\n\t\treturn\n\t}\n\tif len(remain) == 0 {\n\t\treturn c, remain, badCharError\n\t}\n\tsecond := remain[0]\n\tremain = remain[1:]\n\tc = c<<8 | uint16(second)\n\tif (second >= 0x40 && second <= 0x7F) || (second >= 0x80 && second <= 0xFE) {\n\t} else {\n\t\terr = badCharError\n\t}\n\treturn\n}\n\nvar commonChars_sjis = []uint16{\n\t0x8140, 0x8141, 0x8142, 0x8145, 0x815b, 0x8169, 0x816a, 0x8175, 0x8176, 0x82a0,\n\t0x82a2, 0x82a4, 0x82a9, 0x82aa, 0x82ab, 0x82ad, 0x82af, 0x82b1, 0x82b3, 0x82b5,\n\t0x82b7, 0x82bd, 0x82be, 0x82c1, 0x82c4, 0x82c5, 0x82c6, 0x82c8, 0x82c9, 0x82cc,\n\t0x82cd, 0x82dc, 0x82e0, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82f0, 0x82f1, 0x8341,\n\t0x8343, 0x834e, 0x834f, 0x8358, 0x835e, 0x8362, 0x8367, 0x8375, 0x8376, 0x8389,\n\t0x838a, 0x838b, 0x838d, 0x8393, 0x8e96, 0x93fa, 0x95aa,\n}\n\nfunc newRecognizer_sjis() *recognizerMultiByte {\n\treturn &recognizerMultiByte{\n\t\t\"Shift_JIS\",\n\t\t\"ja\",\n\t\tcharDecoder_sjis{},\n\t\tcommonChars_sjis,\n\t}\n}\n\ntype charDecoder_euc struct {\n}\n\nfunc (charDecoder_euc) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) {\n\tif len(input) == 0 {\n\t\treturn 0, nil, eobError\n\t}\n\tfirst := input[0]\n\tremain = input[1:]\n\tc = uint16(first)\n\tif first <= 0x8D {\n\t\treturn uint16(first), remain, nil\n\t}\n\tif len(remain) == 0 {\n\t\treturn 0, nil, eobError\n\t}\n\tsecond := remain[0]\n\tremain = remain[1:]\n\tc = c<<8 | uint16(second)\n\tif first >= 0xA1 && first <= 0xFE {\n\t\tif second < 0xA1 {\n\t\t\terr = badCharError\n\t\t}\n\t\treturn\n\t}\n\tif first == 0x8E {\n\t\tif second < 0xA1 {\n\t\t\terr = badCharError\n\t\t}\n\t\treturn\n\t}\n\tif first == 0x8F {\n\t\tif len(remain) == 0 {\n\t\t\treturn 0, nil, eobError\n\t\t}\n\t\tthird := remain[0]\n\t\tremain = remain[1:]\n\t\tc = c<<0 | uint16(third)\n\t\tif third < 0xa1 {\n\t\t\terr = badCharError\n\t\t}\n\t}\n\treturn\n}\n\nvar commonChars_euc_jp = []uint16{\n\t0xa1a1, 0xa1a2, 0xa1a3, 0xa1a6, 0xa1bc, 0xa1ca, 0xa1cb, 0xa1d6, 0xa1d7, 0xa4a2,\n\t0xa4a4, 0xa4a6, 0xa4a8, 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4af, 0xa4b1, 0xa4b3,\n\t0xa4b5, 0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd, 0xa4bf, 0xa4c0, 0xa4c1, 0xa4c3, 0xa4c4,\n\t0xa4c6, 0xa4c7, 0xa4c8, 0xa4c9, 0xa4ca, 0xa4cb, 0xa4ce, 0xa4cf, 0xa4d0, 0xa4de,\n\t0xa4df, 0xa4e1, 0xa4e2, 0xa4e4, 0xa4e8, 0xa4e9, 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ef,\n\t0xa4f2, 0xa4f3, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a6, 0xa5a7, 0xa5aa, 0xa5ad, 0xa5af,\n\t0xa5b0, 0xa5b3, 0xa5b5, 0xa5b7, 0xa5b8, 0xa5b9, 0xa5bf, 0xa5c3, 0xa5c6, 0xa5c7,\n\t0xa5c8, 0xa5c9, 0xa5cb, 0xa5d0, 0xa5d5, 0xa5d6, 0xa5d7, 0xa5de, 0xa5e0, 0xa5e1,\n\t0xa5e5, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5f3, 0xb8a9, 0xb9d4, 0xbaee,\n\t0xbbc8, 0xbef0, 0xbfb7, 0xc4ea, 0xc6fc, 0xc7bd, 0xcab8, 0xcaf3, 0xcbdc, 0xcdd1,\n}\n\nvar commonChars_euc_kr = []uint16{\n\t0xb0a1, 0xb0b3, 0xb0c5, 0xb0cd, 0xb0d4, 0xb0e6, 0xb0ed, 0xb0f8, 0xb0fa, 0xb0fc,\n\t0xb1b8, 0xb1b9, 0xb1c7, 0xb1d7, 0xb1e2, 0xb3aa, 0xb3bb, 0xb4c2, 0xb4cf, 0xb4d9,\n\t0xb4eb, 0xb5a5, 0xb5b5, 0xb5bf, 0xb5c7, 0xb5e9, 0xb6f3, 0xb7af, 0xb7c2, 0xb7ce,\n\t0xb8a6, 0xb8ae, 0xb8b6, 0xb8b8, 0xb8bb, 0xb8e9, 0xb9ab, 0xb9ae, 0xb9cc, 0xb9ce,\n\t0xb9fd, 0xbab8, 0xbace, 0xbad0, 0xbaf1, 0xbbe7, 0xbbf3, 0xbbfd, 0xbcad, 0xbcba,\n\t0xbcd2, 0xbcf6, 0xbdba, 0xbdc0, 0xbdc3, 0xbdc5, 0xbec6, 0xbec8, 0xbedf, 0xbeee,\n\t0xbef8, 0xbefa, 0xbfa1, 0xbfa9, 0xbfc0, 0xbfe4, 0xbfeb, 0xbfec, 0xbff8, 0xc0a7,\n\t0xc0af, 0xc0b8, 0xc0ba, 0xc0bb, 0xc0bd, 0xc0c7, 0xc0cc, 0xc0ce, 0xc0cf, 0xc0d6,\n\t0xc0da, 0xc0e5, 0xc0fb, 0xc0fc, 0xc1a4, 0xc1a6, 0xc1b6, 0xc1d6, 0xc1df, 0xc1f6,\n\t0xc1f8, 0xc4a1, 0xc5cd, 0xc6ae, 0xc7cf, 0xc7d1, 0xc7d2, 0xc7d8, 0xc7e5, 0xc8ad,\n}\n\nfunc newRecognizer_euc_jp() *recognizerMultiByte {\n\treturn &recognizerMultiByte{\n\t\t\"EUC-JP\",\n\t\t\"ja\",\n\t\tcharDecoder_euc{},\n\t\tcommonChars_euc_jp,\n\t}\n}\n\nfunc newRecognizer_euc_kr() *recognizerMultiByte {\n\treturn &recognizerMultiByte{\n\t\t\"EUC-KR\",\n\t\t\"ko\",\n\t\tcharDecoder_euc{},\n\t\tcommonChars_euc_kr,\n\t}\n}\n\ntype charDecoder_big5 struct {\n}\n\nfunc (charDecoder_big5) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) {\n\tif len(input) == 0 {\n\t\treturn 0, nil, eobError\n\t}\n\tfirst := input[0]\n\tremain = input[1:]\n\tc = uint16(first)\n\tif first <= 0x7F || first == 0xFF {\n\t\treturn\n\t}\n\tif len(remain) == 0 {\n\t\treturn c, nil, eobError\n\t}\n\tsecond := remain[0]\n\tremain = remain[1:]\n\tc = c<<8 | uint16(second)\n\tif second < 0x40 || second == 0x7F || second == 0xFF {\n\t\terr = badCharError\n\t}\n\treturn\n}\n\nvar commonChars_big5 = []uint16{\n\t0xa140, 0xa141, 0xa142, 0xa143, 0xa147, 0xa149, 0xa175, 0xa176, 0xa440, 0xa446,\n\t0xa447, 0xa448, 0xa451, 0xa454, 0xa457, 0xa464, 0xa46a, 0xa46c, 0xa477, 0xa4a3,\n\t0xa4a4, 0xa4a7, 0xa4c1, 0xa4ce, 0xa4d1, 0xa4df, 0xa4e8, 0xa4fd, 0xa540, 0xa548,\n\t0xa558, 0xa569, 0xa5cd, 0xa5e7, 0xa657, 0xa661, 0xa662, 0xa668, 0xa670, 0xa6a8,\n\t0xa6b3, 0xa6b9, 0xa6d3, 0xa6db, 0xa6e6, 0xa6f2, 0xa740, 0xa751, 0xa759, 0xa7da,\n\t0xa8a3, 0xa8a5, 0xa8ad, 0xa8d1, 0xa8d3, 0xa8e4, 0xa8fc, 0xa9c0, 0xa9d2, 0xa9f3,\n\t0xaa6b, 0xaaba, 0xaabe, 0xaacc, 0xaafc, 0xac47, 0xac4f, 0xacb0, 0xacd2, 0xad59,\n\t0xaec9, 0xafe0, 0xb0ea, 0xb16f, 0xb2b3, 0xb2c4, 0xb36f, 0xb44c, 0xb44e, 0xb54c,\n\t0xb5a5, 0xb5bd, 0xb5d0, 0xb5d8, 0xb671, 0xb7ed, 0xb867, 0xb944, 0xbad8, 0xbb44,\n\t0xbba1, 0xbdd1, 0xc2c4, 0xc3b9, 0xc440, 0xc45f,\n}\n\nfunc newRecognizer_big5() *recognizerMultiByte {\n\treturn &recognizerMultiByte{\n\t\t\"Big5\",\n\t\t\"zh\",\n\t\tcharDecoder_big5{},\n\t\tcommonChars_big5,\n\t}\n}\n\ntype charDecoder_gb_18030 struct {\n}\n\nfunc (charDecoder_gb_18030) DecodeOneChar(input []byte) (c uint16, remain []byte, err error) {\n\tif len(input) == 0 {\n\t\treturn 0, nil, eobError\n\t}\n\tfirst := input[0]\n\tremain = input[1:]\n\tc = uint16(first)\n\tif first <= 0x80 {\n\t\treturn\n\t}\n\tif len(remain) == 0 {\n\t\treturn 0, nil, eobError\n\t}\n\tsecond := remain[0]\n\tremain = remain[1:]\n\tc = c<<8 | uint16(second)\n\tif first >= 0x81 && first <= 0xFE {\n\t\tif (second >= 0x40 && second <= 0x7E) || (second >= 0x80 && second <= 0xFE) {\n\t\t\treturn\n\t\t}\n\n\t\tif second >= 0x30 && second <= 0x39 {\n\t\t\tif len(remain) == 0 {\n\t\t\t\treturn 0, nil, eobError\n\t\t\t}\n\t\t\tthird := remain[0]\n\t\t\tremain = remain[1:]\n\t\t\tif third >= 0x81 && third <= 0xFE {\n\t\t\t\tif len(remain) == 0 {\n\t\t\t\t\treturn 0, nil, eobError\n\t\t\t\t}\n\t\t\t\tfourth := remain[0]\n\t\t\t\tremain = remain[1:]\n\t\t\t\tif fourth >= 0x30 && fourth <= 0x39 {\n\t\t\t\t\tc = c<<16 | uint16(third)<<8 | uint16(fourth)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\terr = badCharError\n\t}\n\treturn\n}\n\nvar commonChars_gb_18030 = []uint16{\n\t0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1b0, 0xa1b1, 0xa1f1, 0xa1f3, 0xa3a1, 0xa3ac,\n\t0xa3ba, 0xb1a8, 0xb1b8, 0xb1be, 0xb2bb, 0xb3c9, 0xb3f6, 0xb4f3, 0xb5bd, 0xb5c4,\n\t0xb5e3, 0xb6af, 0xb6d4, 0xb6e0, 0xb7a2, 0xb7a8, 0xb7bd, 0xb7d6, 0xb7dd, 0xb8b4,\n\t0xb8df, 0xb8f6, 0xb9ab, 0xb9c9, 0xb9d8, 0xb9fa, 0xb9fd, 0xbacd, 0xbba7, 0xbbd6,\n\t0xbbe1, 0xbbfa, 0xbcbc, 0xbcdb, 0xbcfe, 0xbdcc, 0xbecd, 0xbedd, 0xbfb4, 0xbfc6,\n\t0xbfc9, 0xc0b4, 0xc0ed, 0xc1cb, 0xc2db, 0xc3c7, 0xc4dc, 0xc4ea, 0xc5cc, 0xc6f7,\n\t0xc7f8, 0xc8ab, 0xc8cb, 0xc8d5, 0xc8e7, 0xc9cf, 0xc9fa, 0xcab1, 0xcab5, 0xcac7,\n\t0xcad0, 0xcad6, 0xcaf5, 0xcafd, 0xccec, 0xcdf8, 0xceaa, 0xcec4, 0xced2, 0xcee5,\n\t0xcfb5, 0xcfc2, 0xcfd6, 0xd0c2, 0xd0c5, 0xd0d0, 0xd0d4, 0xd1a7, 0xd2aa, 0xd2b2,\n\t0xd2b5, 0xd2bb, 0xd2d4, 0xd3c3, 0xd3d0, 0xd3fd, 0xd4c2, 0xd4da, 0xd5e2, 0xd6d0,\n}\n\nfunc newRecognizer_gb_18030() *recognizerMultiByte {\n\treturn &recognizerMultiByte{\n\t\t\"GB-18030\",\n\t\t\"zh\",\n\t\tcharDecoder_gb_18030{},\n\t\tcommonChars_gb_18030,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/recognizer.go",
    "content": "package chardet\n\ntype recognizer interface {\n\tMatch(*recognizerInput) recognizerOutput\n}\n\ntype recognizerOutput Result\n\ntype recognizerInput struct {\n\traw         []byte\n\tinput       []byte\n\ttagStripped bool\n\tbyteStats   []int\n\thasC1Bytes  bool\n}\n\nfunc newRecognizerInput(raw []byte, stripTag bool) *recognizerInput {\n\tinput, stripped := mayStripInput(raw, stripTag)\n\tbyteStats := computeByteStats(input)\n\treturn &recognizerInput{\n\t\traw:         raw,\n\t\tinput:       input,\n\t\ttagStripped: stripped,\n\t\tbyteStats:   byteStats,\n\t\thasC1Bytes:  computeHasC1Bytes(byteStats),\n\t}\n}\n\nfunc mayStripInput(raw []byte, stripTag bool) (out []byte, stripped bool) {\n\tconst inputBufferSize = 8192\n\tout = make([]byte, 0, inputBufferSize)\n\tvar badTags, openTags int32\n\tvar inMarkup bool = false\n\tstripped = false\n\tif stripTag {\n\t\tstripped = true\n\t\tfor _, c := range raw {\n\t\t\tif c == '<' {\n\t\t\t\tif inMarkup {\n\t\t\t\t\tbadTags += 1\n\t\t\t\t}\n\t\t\t\tinMarkup = true\n\t\t\t\topenTags += 1\n\t\t\t}\n\t\t\tif !inMarkup {\n\t\t\t\tout = append(out, c)\n\t\t\t\tif len(out) >= inputBufferSize {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif c == '>' {\n\t\t\t\tinMarkup = false\n\t\t\t}\n\t\t}\n\t}\n\tif openTags < 5 || openTags/5 < badTags || (len(out) < 100 && len(raw) > 600) {\n\t\tlimit := len(raw)\n\t\tif limit > inputBufferSize {\n\t\t\tlimit = inputBufferSize\n\t\t}\n\t\tout = make([]byte, limit)\n\t\tcopy(out, raw[:limit])\n\t\tstripped = false\n\t}\n\treturn\n}\n\nfunc computeByteStats(input []byte) []int {\n\tr := make([]int, 256)\n\tfor _, c := range input {\n\t\tr[c] += 1\n\t}\n\treturn r\n}\n\nfunc computeHasC1Bytes(byteStats []int) bool {\n\tfor _, count := range byteStats[0x80 : 0x9F+1] {\n\t\tif count > 0 {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/single_byte.go",
    "content": "package chardet\n\n// Recognizer for single byte charset family\ntype recognizerSingleByte struct {\n\tcharset          string\n\thasC1ByteCharset string\n\tlanguage         string\n\tcharMap          *[256]byte\n\tngram            *[64]uint32\n}\n\nfunc (r *recognizerSingleByte) Match(input *recognizerInput) recognizerOutput {\n\tvar charset string = r.charset\n\tif input.hasC1Bytes && len(r.hasC1ByteCharset) > 0 {\n\t\tcharset = r.hasC1ByteCharset\n\t}\n\treturn recognizerOutput{\n\t\tCharset:    charset,\n\t\tLanguage:   r.language,\n\t\tConfidence: r.parseNgram(input.input),\n\t}\n}\n\ntype ngramState struct {\n\tngram                uint32\n\tignoreSpace          bool\n\tngramCount, ngramHit uint32\n\ttable                *[64]uint32\n}\n\nfunc newNgramState(table *[64]uint32) *ngramState {\n\treturn &ngramState{\n\t\tngram:       0,\n\t\tignoreSpace: false,\n\t\tngramCount:  0,\n\t\tngramHit:    0,\n\t\ttable:       table,\n\t}\n}\n\nfunc (s *ngramState) AddByte(b byte) {\n\tconst ngramMask = 0xFFFFFF\n\tif !(b == 0x20 && s.ignoreSpace) {\n\t\ts.ngram = ((s.ngram << 8) | uint32(b)) & ngramMask\n\t\ts.ignoreSpace = (s.ngram == 0x20)\n\t\ts.ngramCount++\n\t\tif s.lookup() {\n\t\t\ts.ngramHit++\n\t\t}\n\t}\n\ts.ignoreSpace = (b == 0x20)\n}\n\nfunc (s *ngramState) HitRate() float32 {\n\tif s.ngramCount == 0 {\n\t\treturn 0\n\t}\n\treturn float32(s.ngramHit) / float32(s.ngramCount)\n}\n\nfunc (s *ngramState) lookup() bool {\n\tvar index int\n\tif s.table[index+32] <= s.ngram {\n\t\tindex += 32\n\t}\n\tif s.table[index+16] <= s.ngram {\n\t\tindex += 16\n\t}\n\tif s.table[index+8] <= s.ngram {\n\t\tindex += 8\n\t}\n\tif s.table[index+4] <= s.ngram {\n\t\tindex += 4\n\t}\n\tif s.table[index+2] <= s.ngram {\n\t\tindex += 2\n\t}\n\tif s.table[index+1] <= s.ngram {\n\t\tindex += 1\n\t}\n\tif s.table[index] > s.ngram {\n\t\tindex -= 1\n\t}\n\tif index < 0 || s.table[index] != s.ngram {\n\t\treturn false\n\t}\n\treturn true\n}\n\nfunc (r *recognizerSingleByte) parseNgram(input []byte) int {\n\tstate := newNgramState(r.ngram)\n\tfor _, inChar := range input {\n\t\tc := r.charMap[inChar]\n\t\tif c != 0 {\n\t\t\tstate.AddByte(c)\n\t\t}\n\t}\n\tstate.AddByte(0x20)\n\trate := state.HitRate()\n\tif rate > 0.33 {\n\t\treturn 98\n\t}\n\treturn int(rate * 300)\n}\n\nvar charMap_8859_1 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20,\n\t0x20, 0x20, 0xBA, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,\n}\n\nvar ngrams_8859_1_en = [64]uint32{\n\t0x206120, 0x20616E, 0x206265, 0x20636F, 0x20666F, 0x206861, 0x206865, 0x20696E, 0x206D61, 0x206F66, 0x207072, 0x207265, 0x207361, 0x207374, 0x207468, 0x20746F,\n\t0x207768, 0x616964, 0x616C20, 0x616E20, 0x616E64, 0x617320, 0x617420, 0x617465, 0x617469, 0x642061, 0x642074, 0x652061, 0x652073, 0x652074, 0x656420, 0x656E74,\n\t0x657220, 0x657320, 0x666F72, 0x686174, 0x686520, 0x686572, 0x696420, 0x696E20, 0x696E67, 0x696F6E, 0x697320, 0x6E2061, 0x6E2074, 0x6E6420, 0x6E6720, 0x6E7420,\n\t0x6F6620, 0x6F6E20, 0x6F7220, 0x726520, 0x727320, 0x732061, 0x732074, 0x736169, 0x737420, 0x742074, 0x746572, 0x746861, 0x746865, 0x74696F, 0x746F20, 0x747320,\n}\n\nvar ngrams_8859_1_da = [64]uint32{\n\t0x206166, 0x206174, 0x206465, 0x20656E, 0x206572, 0x20666F, 0x206861, 0x206920, 0x206D65, 0x206F67, 0x2070E5, 0x207369, 0x207374, 0x207469, 0x207669, 0x616620,\n\t0x616E20, 0x616E64, 0x617220, 0x617420, 0x646520, 0x64656E, 0x646572, 0x646574, 0x652073, 0x656420, 0x656465, 0x656E20, 0x656E64, 0x657220, 0x657265, 0x657320,\n\t0x657420, 0x666F72, 0x676520, 0x67656E, 0x676572, 0x696765, 0x696C20, 0x696E67, 0x6B6520, 0x6B6B65, 0x6C6572, 0x6C6967, 0x6C6C65, 0x6D6564, 0x6E6465, 0x6E6520,\n\t0x6E6720, 0x6E6765, 0x6F6720, 0x6F6D20, 0x6F7220, 0x70E520, 0x722064, 0x722065, 0x722073, 0x726520, 0x737465, 0x742073, 0x746520, 0x746572, 0x74696C, 0x766572,\n}\n\nvar ngrams_8859_1_de = [64]uint32{\n\t0x20616E, 0x206175, 0x206265, 0x206461, 0x206465, 0x206469, 0x206569, 0x206765, 0x206861, 0x20696E, 0x206D69, 0x207363, 0x207365, 0x20756E, 0x207665, 0x20766F,\n\t0x207765, 0x207A75, 0x626572, 0x636820, 0x636865, 0x636874, 0x646173, 0x64656E, 0x646572, 0x646965, 0x652064, 0x652073, 0x65696E, 0x656974, 0x656E20, 0x657220,\n\t0x657320, 0x67656E, 0x68656E, 0x687420, 0x696368, 0x696520, 0x696E20, 0x696E65, 0x697420, 0x6C6963, 0x6C6C65, 0x6E2061, 0x6E2064, 0x6E2073, 0x6E6420, 0x6E6465,\n\t0x6E6520, 0x6E6720, 0x6E6765, 0x6E7465, 0x722064, 0x726465, 0x726569, 0x736368, 0x737465, 0x742064, 0x746520, 0x74656E, 0x746572, 0x756E64, 0x756E67, 0x766572,\n}\n\nvar ngrams_8859_1_es = [64]uint32{\n\t0x206120, 0x206361, 0x20636F, 0x206465, 0x20656C, 0x20656E, 0x206573, 0x20696E, 0x206C61, 0x206C6F, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207265, 0x207365,\n\t0x20756E, 0x207920, 0x612063, 0x612064, 0x612065, 0x61206C, 0x612070, 0x616369, 0x61646F, 0x616C20, 0x617220, 0x617320, 0x6369F3, 0x636F6E, 0x646520, 0x64656C,\n\t0x646F20, 0x652064, 0x652065, 0x65206C, 0x656C20, 0x656E20, 0x656E74, 0x657320, 0x657374, 0x69656E, 0x69F36E, 0x6C6120, 0x6C6F73, 0x6E2065, 0x6E7465, 0x6F2064,\n\t0x6F2065, 0x6F6E20, 0x6F7220, 0x6F7320, 0x706172, 0x717565, 0x726120, 0x726573, 0x732064, 0x732065, 0x732070, 0x736520, 0x746520, 0x746F20, 0x756520, 0xF36E20,\n}\n\nvar ngrams_8859_1_fr = [64]uint32{\n\t0x206175, 0x20636F, 0x206461, 0x206465, 0x206475, 0x20656E, 0x206574, 0x206C61, 0x206C65, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207365, 0x20736F, 0x20756E,\n\t0x20E020, 0x616E74, 0x617469, 0x636520, 0x636F6E, 0x646520, 0x646573, 0x647520, 0x652061, 0x652063, 0x652064, 0x652065, 0x65206C, 0x652070, 0x652073, 0x656E20,\n\t0x656E74, 0x657220, 0x657320, 0x657420, 0x657572, 0x696F6E, 0x697320, 0x697420, 0x6C6120, 0x6C6520, 0x6C6573, 0x6D656E, 0x6E2064, 0x6E6520, 0x6E7320, 0x6E7420,\n\t0x6F6E20, 0x6F6E74, 0x6F7572, 0x717565, 0x72206C, 0x726520, 0x732061, 0x732064, 0x732065, 0x73206C, 0x732070, 0x742064, 0x746520, 0x74696F, 0x756520, 0x757220,\n}\n\nvar ngrams_8859_1_it = [64]uint32{\n\t0x20616C, 0x206368, 0x20636F, 0x206465, 0x206469, 0x206520, 0x20696C, 0x20696E, 0x206C61, 0x207065, 0x207072, 0x20756E, 0x612063, 0x612064, 0x612070, 0x612073,\n\t0x61746F, 0x636865, 0x636F6E, 0x64656C, 0x646920, 0x652061, 0x652063, 0x652064, 0x652069, 0x65206C, 0x652070, 0x652073, 0x656C20, 0x656C6C, 0x656E74, 0x657220,\n\t0x686520, 0x692061, 0x692063, 0x692064, 0x692073, 0x696120, 0x696C20, 0x696E20, 0x696F6E, 0x6C6120, 0x6C6520, 0x6C6920, 0x6C6C61, 0x6E6520, 0x6E6920, 0x6E6F20,\n\t0x6E7465, 0x6F2061, 0x6F2064, 0x6F2069, 0x6F2073, 0x6F6E20, 0x6F6E65, 0x706572, 0x726120, 0x726520, 0x736920, 0x746120, 0x746520, 0x746920, 0x746F20, 0x7A696F,\n}\n\nvar ngrams_8859_1_nl = [64]uint32{\n\t0x20616C, 0x206265, 0x206461, 0x206465, 0x206469, 0x206565, 0x20656E, 0x206765, 0x206865, 0x20696E, 0x206D61, 0x206D65, 0x206F70, 0x207465, 0x207661, 0x207665,\n\t0x20766F, 0x207765, 0x207A69, 0x61616E, 0x616172, 0x616E20, 0x616E64, 0x617220, 0x617420, 0x636874, 0x646520, 0x64656E, 0x646572, 0x652062, 0x652076, 0x65656E,\n\t0x656572, 0x656E20, 0x657220, 0x657273, 0x657420, 0x67656E, 0x686574, 0x696520, 0x696E20, 0x696E67, 0x697320, 0x6E2062, 0x6E2064, 0x6E2065, 0x6E2068, 0x6E206F,\n\t0x6E2076, 0x6E6465, 0x6E6720, 0x6F6E64, 0x6F6F72, 0x6F7020, 0x6F7220, 0x736368, 0x737465, 0x742064, 0x746520, 0x74656E, 0x746572, 0x76616E, 0x766572, 0x766F6F,\n}\n\nvar ngrams_8859_1_no = [64]uint32{\n\t0x206174, 0x206176, 0x206465, 0x20656E, 0x206572, 0x20666F, 0x206861, 0x206920, 0x206D65, 0x206F67, 0x2070E5, 0x207365, 0x20736B, 0x20736F, 0x207374, 0x207469,\n\t0x207669, 0x20E520, 0x616E64, 0x617220, 0x617420, 0x646520, 0x64656E, 0x646574, 0x652073, 0x656420, 0x656E20, 0x656E65, 0x657220, 0x657265, 0x657420, 0x657474,\n\t0x666F72, 0x67656E, 0x696B6B, 0x696C20, 0x696E67, 0x6B6520, 0x6B6B65, 0x6C6520, 0x6C6C65, 0x6D6564, 0x6D656E, 0x6E2073, 0x6E6520, 0x6E6720, 0x6E6765, 0x6E6E65,\n\t0x6F6720, 0x6F6D20, 0x6F7220, 0x70E520, 0x722073, 0x726520, 0x736F6D, 0x737465, 0x742073, 0x746520, 0x74656E, 0x746572, 0x74696C, 0x747420, 0x747465, 0x766572,\n}\n\nvar ngrams_8859_1_pt = [64]uint32{\n\t0x206120, 0x20636F, 0x206461, 0x206465, 0x20646F, 0x206520, 0x206573, 0x206D61, 0x206E6F, 0x206F20, 0x207061, 0x20706F, 0x207072, 0x207175, 0x207265, 0x207365,\n\t0x20756D, 0x612061, 0x612063, 0x612064, 0x612070, 0x616465, 0x61646F, 0x616C20, 0x617220, 0x617261, 0x617320, 0x636F6D, 0x636F6E, 0x646120, 0x646520, 0x646F20,\n\t0x646F73, 0x652061, 0x652064, 0x656D20, 0x656E74, 0x657320, 0x657374, 0x696120, 0x696361, 0x6D656E, 0x6E7465, 0x6E746F, 0x6F2061, 0x6F2063, 0x6F2064, 0x6F2065,\n\t0x6F2070, 0x6F7320, 0x706172, 0x717565, 0x726120, 0x726573, 0x732061, 0x732064, 0x732065, 0x732070, 0x737461, 0x746520, 0x746F20, 0x756520, 0xE36F20, 0xE7E36F,\n}\n\nvar ngrams_8859_1_sv = [64]uint32{\n\t0x206174, 0x206176, 0x206465, 0x20656E, 0x2066F6, 0x206861, 0x206920, 0x20696E, 0x206B6F, 0x206D65, 0x206F63, 0x2070E5, 0x20736B, 0x20736F, 0x207374, 0x207469,\n\t0x207661, 0x207669, 0x20E472, 0x616465, 0x616E20, 0x616E64, 0x617220, 0x617474, 0x636820, 0x646520, 0x64656E, 0x646572, 0x646574, 0x656420, 0x656E20, 0x657220,\n\t0x657420, 0x66F672, 0x67656E, 0x696C6C, 0x696E67, 0x6B6120, 0x6C6C20, 0x6D6564, 0x6E2073, 0x6E6120, 0x6E6465, 0x6E6720, 0x6E6765, 0x6E696E, 0x6F6368, 0x6F6D20,\n\t0x6F6E20, 0x70E520, 0x722061, 0x722073, 0x726120, 0x736B61, 0x736F6D, 0x742073, 0x746120, 0x746520, 0x746572, 0x74696C, 0x747420, 0x766172, 0xE47220, 0xF67220,\n}\n\nfunc newRecognizer_8859_1(language string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:          \"ISO-8859-1\",\n\t\thasC1ByteCharset: \"windows-1252\",\n\t\tlanguage:         language,\n\t\tcharMap:          &charMap_8859_1,\n\t\tngram:            ngram,\n\t}\n}\n\nfunc newRecognizer_8859_1_en() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"en\", &ngrams_8859_1_en)\n}\nfunc newRecognizer_8859_1_da() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"da\", &ngrams_8859_1_da)\n}\nfunc newRecognizer_8859_1_de() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"de\", &ngrams_8859_1_de)\n}\nfunc newRecognizer_8859_1_es() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"es\", &ngrams_8859_1_es)\n}\nfunc newRecognizer_8859_1_fr() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"fr\", &ngrams_8859_1_fr)\n}\nfunc newRecognizer_8859_1_it() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"it\", &ngrams_8859_1_it)\n}\nfunc newRecognizer_8859_1_nl() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"nl\", &ngrams_8859_1_nl)\n}\nfunc newRecognizer_8859_1_no() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"no\", &ngrams_8859_1_no)\n}\nfunc newRecognizer_8859_1_pt() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"pt\", &ngrams_8859_1_pt)\n}\nfunc newRecognizer_8859_1_sv() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"sv\", &ngrams_8859_1_sv)\n}\n\nvar charMap_8859_2 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0xB1, 0x20, 0xB3, 0x20, 0xB5, 0xB6, 0x20,\n\t0x20, 0xB9, 0xBA, 0xBB, 0xBC, 0x20, 0xBE, 0xBF,\n\t0x20, 0xB1, 0x20, 0xB3, 0x20, 0xB5, 0xB6, 0xB7,\n\t0x20, 0xB9, 0xBA, 0xBB, 0xBC, 0x20, 0xBE, 0xBF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x20,\n}\n\nvar ngrams_8859_2_cs = [64]uint32{\n\t0x206120, 0x206279, 0x20646F, 0x206A65, 0x206E61, 0x206E65, 0x206F20, 0x206F64, 0x20706F, 0x207072, 0x2070F8, 0x20726F, 0x207365, 0x20736F, 0x207374, 0x20746F,\n\t0x207620, 0x207679, 0x207A61, 0x612070, 0x636520, 0x636820, 0x652070, 0x652073, 0x652076, 0x656D20, 0x656EED, 0x686F20, 0x686F64, 0x697374, 0x6A6520, 0x6B7465,\n\t0x6C6520, 0x6C6920, 0x6E6120, 0x6EE920, 0x6EEC20, 0x6EED20, 0x6F2070, 0x6F646E, 0x6F6A69, 0x6F7374, 0x6F7520, 0x6F7661, 0x706F64, 0x706F6A, 0x70726F, 0x70F865,\n\t0x736520, 0x736F75, 0x737461, 0x737469, 0x73746E, 0x746572, 0x746EED, 0x746F20, 0x752070, 0xBE6520, 0xE16EED, 0xE9686F, 0xED2070, 0xED2073, 0xED6D20, 0xF86564,\n}\n\nvar ngrams_8859_2_hu = [64]uint32{\n\t0x206120, 0x20617A, 0x206265, 0x206567, 0x20656C, 0x206665, 0x206861, 0x20686F, 0x206973, 0x206B65, 0x206B69, 0x206BF6, 0x206C65, 0x206D61, 0x206D65, 0x206D69,\n\t0x206E65, 0x20737A, 0x207465, 0x20E973, 0x612061, 0x61206B, 0x61206D, 0x612073, 0x616B20, 0x616E20, 0x617A20, 0x62616E, 0x62656E, 0x656779, 0x656B20, 0x656C20,\n\t0x656C65, 0x656D20, 0x656E20, 0x657265, 0x657420, 0x657465, 0x657474, 0x677920, 0x686F67, 0x696E74, 0x697320, 0x6B2061, 0x6BF67A, 0x6D6567, 0x6D696E, 0x6E2061,\n\t0x6E616B, 0x6E656B, 0x6E656D, 0x6E7420, 0x6F6779, 0x732061, 0x737A65, 0x737A74, 0x737AE1, 0x73E967, 0x742061, 0x747420, 0x74E173, 0x7A6572, 0xE16E20, 0xE97320,\n}\n\nvar ngrams_8859_2_pl = [64]uint32{\n\t0x20637A, 0x20646F, 0x206920, 0x206A65, 0x206B6F, 0x206D61, 0x206D69, 0x206E61, 0x206E69, 0x206F64, 0x20706F, 0x207072, 0x207369, 0x207720, 0x207769, 0x207779,\n\t0x207A20, 0x207A61, 0x612070, 0x612077, 0x616E69, 0x636820, 0x637A65, 0x637A79, 0x646F20, 0x647A69, 0x652070, 0x652073, 0x652077, 0x65207A, 0x65676F, 0x656A20,\n\t0x656D20, 0x656E69, 0x676F20, 0x696120, 0x696520, 0x69656A, 0x6B6120, 0x6B6920, 0x6B6965, 0x6D6965, 0x6E6120, 0x6E6961, 0x6E6965, 0x6F2070, 0x6F7761, 0x6F7769,\n\t0x706F6C, 0x707261, 0x70726F, 0x70727A, 0x727A65, 0x727A79, 0x7369EA, 0x736B69, 0x737461, 0x776965, 0x796368, 0x796D20, 0x7A6520, 0x7A6965, 0x7A7920, 0xF37720,\n}\n\nvar ngrams_8859_2_ro = [64]uint32{\n\t0x206120, 0x206163, 0x206361, 0x206365, 0x20636F, 0x206375, 0x206465, 0x206469, 0x206C61, 0x206D61, 0x207065, 0x207072, 0x207365, 0x2073E3, 0x20756E, 0x20BA69,\n\t0x20EE6E, 0x612063, 0x612064, 0x617265, 0x617420, 0x617465, 0x617520, 0x636172, 0x636F6E, 0x637520, 0x63E320, 0x646520, 0x652061, 0x652063, 0x652064, 0x652070,\n\t0x652073, 0x656120, 0x656920, 0x656C65, 0x656E74, 0x657374, 0x692061, 0x692063, 0x692064, 0x692070, 0x696520, 0x696920, 0x696E20, 0x6C6120, 0x6C6520, 0x6C6F72,\n\t0x6C7569, 0x6E6520, 0x6E7472, 0x6F7220, 0x70656E, 0x726520, 0x726561, 0x727520, 0x73E320, 0x746520, 0x747275, 0x74E320, 0x756920, 0x756C20, 0xBA6920, 0xEE6E20,\n}\n\nfunc newRecognizer_8859_2(language string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:          \"ISO-8859-2\",\n\t\thasC1ByteCharset: \"windows-1250\",\n\t\tlanguage:         language,\n\t\tcharMap:          &charMap_8859_2,\n\t\tngram:            ngram,\n\t}\n}\n\nfunc newRecognizer_8859_2_cs() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"cs\", &ngrams_8859_2_cs)\n}\nfunc newRecognizer_8859_2_hu() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"hu\", &ngrams_8859_2_hu)\n}\nfunc newRecognizer_8859_2_pl() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"pl\", &ngrams_8859_2_pl)\n}\nfunc newRecognizer_8859_2_ro() *recognizerSingleByte {\n\treturn newRecognizer_8859_1(\"ro\", &ngrams_8859_2_ro)\n}\n\nvar charMap_8859_5 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x20, 0xFE, 0xFF,\n\t0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,\n\t0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,\n\t0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0x20, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x20, 0xFE, 0xFF,\n}\n\nvar ngrams_8859_5_ru = [64]uint32{\n\t0x20D220, 0x20D2DE, 0x20D4DE, 0x20D7D0, 0x20D820, 0x20DAD0, 0x20DADE, 0x20DDD0, 0x20DDD5, 0x20DED1, 0x20DFDE, 0x20DFE0, 0x20E0D0, 0x20E1DE, 0x20E1E2, 0x20E2DE,\n\t0x20E7E2, 0x20EDE2, 0xD0DDD8, 0xD0E2EC, 0xD3DE20, 0xD5DBEC, 0xD5DDD8, 0xD5E1E2, 0xD5E220, 0xD820DF, 0xD8D520, 0xD8D820, 0xD8EF20, 0xDBD5DD, 0xDBD820, 0xDBECDD,\n\t0xDDD020, 0xDDD520, 0xDDD8D5, 0xDDD8EF, 0xDDDE20, 0xDDDED2, 0xDE20D2, 0xDE20DF, 0xDE20E1, 0xDED220, 0xDED2D0, 0xDED3DE, 0xDED920, 0xDEDBEC, 0xDEDC20, 0xDEE1E2,\n\t0xDFDEDB, 0xDFE0D5, 0xDFE0D8, 0xDFE0DE, 0xE0D0D2, 0xE0D5D4, 0xE1E2D0, 0xE1E2D2, 0xE1E2D8, 0xE1EF20, 0xE2D5DB, 0xE2DE20, 0xE2DEE0, 0xE2EC20, 0xE7E2DE, 0xEBE520,\n}\n\nfunc newRecognizer_8859_5(language string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:  \"ISO-8859-5\",\n\t\tlanguage: language,\n\t\tcharMap:  &charMap_8859_5,\n\t\tngram:    ngram,\n\t}\n}\n\nfunc newRecognizer_8859_5_ru() *recognizerSingleByte {\n\treturn newRecognizer_8859_5(\"ru\", &ngrams_8859_5_ru)\n}\n\nvar charMap_8859_6 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,\n\t0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,\n\t0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,\n\t0xD8, 0xD9, 0xDA, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n}\n\nvar ngrams_8859_6_ar = [64]uint32{\n\t0x20C7E4, 0x20C7E6, 0x20C8C7, 0x20D9E4, 0x20E1EA, 0x20E4E4, 0x20E5E6, 0x20E8C7, 0xC720C7, 0xC7C120, 0xC7CA20, 0xC7D120, 0xC7E420, 0xC7E4C3, 0xC7E4C7, 0xC7E4C8,\n\t0xC7E4CA, 0xC7E4CC, 0xC7E4CD, 0xC7E4CF, 0xC7E4D3, 0xC7E4D9, 0xC7E4E2, 0xC7E4E5, 0xC7E4E8, 0xC7E4EA, 0xC7E520, 0xC7E620, 0xC7E6CA, 0xC820C7, 0xC920C7, 0xC920E1,\n\t0xC920E4, 0xC920E5, 0xC920E8, 0xCA20C7, 0xCF20C7, 0xCFC920, 0xD120C7, 0xD1C920, 0xD320C7, 0xD920C7, 0xD9E4E9, 0xE1EA20, 0xE420C7, 0xE4C920, 0xE4E920, 0xE4EA20,\n\t0xE520C7, 0xE5C720, 0xE5C920, 0xE5E620, 0xE620C7, 0xE720C7, 0xE7C720, 0xE8C7E4, 0xE8E620, 0xE920C7, 0xEA20C7, 0xEA20E5, 0xEA20E8, 0xEAC920, 0xEAD120, 0xEAE620,\n}\n\nfunc newRecognizer_8859_6(language string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:  \"ISO-8859-6\",\n\t\tlanguage: language,\n\t\tcharMap:  &charMap_8859_6,\n\t\tngram:    ngram,\n\t}\n}\n\nfunc newRecognizer_8859_6_ar() *recognizerSingleByte {\n\treturn newRecognizer_8859_6(\"ar\", &ngrams_8859_6_ar)\n}\n\nvar charMap_8859_7 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0xA1, 0xA2, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xDC, 0x20,\n\t0xDD, 0xDE, 0xDF, 0x20, 0xFC, 0x20, 0xFD, 0xFE,\n\t0xC0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0x20, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xDC, 0xDD, 0xDE, 0xDF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0x20,\n}\n\nvar ngrams_8859_7_el = [64]uint32{\n\t0x20E1ED, 0x20E1F0, 0x20E3E9, 0x20E4E9, 0x20E5F0, 0x20E720, 0x20EAE1, 0x20ECE5, 0x20EDE1, 0x20EF20, 0x20F0E1, 0x20F0EF, 0x20F0F1, 0x20F3F4, 0x20F3F5, 0x20F4E7,\n\t0x20F4EF, 0xDFE120, 0xE120E1, 0xE120F4, 0xE1E920, 0xE1ED20, 0xE1F0FC, 0xE1F220, 0xE3E9E1, 0xE5E920, 0xE5F220, 0xE720F4, 0xE7ED20, 0xE7F220, 0xE920F4, 0xE9E120,\n\t0xE9EADE, 0xE9F220, 0xEAE1E9, 0xEAE1F4, 0xECE520, 0xED20E1, 0xED20E5, 0xED20F0, 0xEDE120, 0xEFF220, 0xEFF520, 0xF0EFF5, 0xF0F1EF, 0xF0FC20, 0xF220E1, 0xF220E5,\n\t0xF220EA, 0xF220F0, 0xF220F4, 0xF3E520, 0xF3E720, 0xF3F4EF, 0xF4E120, 0xF4E1E9, 0xF4E7ED, 0xF4E7F2, 0xF4E9EA, 0xF4EF20, 0xF4EFF5, 0xF4F9ED, 0xF9ED20, 0xFEED20,\n}\n\nfunc newRecognizer_8859_7(language string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:          \"ISO-8859-7\",\n\t\thasC1ByteCharset: \"windows-1253\",\n\t\tlanguage:         language,\n\t\tcharMap:          &charMap_8859_7,\n\t\tngram:            ngram,\n\t}\n}\n\nfunc newRecognizer_8859_7_el() *recognizerSingleByte {\n\treturn newRecognizer_8859_7(\"el\", &ngrams_8859_7_el)\n}\n\nvar charMap_8859_8 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,\n\t0xF8, 0xF9, 0xFA, 0x20, 0x20, 0x20, 0x20, 0x20,\n}\n\nvar ngrams_8859_8_I_he = [64]uint32{\n\t0x20E0E5, 0x20E0E7, 0x20E0E9, 0x20E0FA, 0x20E1E9, 0x20E1EE, 0x20E4E0, 0x20E4E5, 0x20E4E9, 0x20E4EE, 0x20E4F2, 0x20E4F9, 0x20E4FA, 0x20ECE0, 0x20ECE4, 0x20EEE0,\n\t0x20F2EC, 0x20F9EC, 0xE0FA20, 0xE420E0, 0xE420E1, 0xE420E4, 0xE420EC, 0xE420EE, 0xE420F9, 0xE4E5E0, 0xE5E020, 0xE5ED20, 0xE5EF20, 0xE5F820, 0xE5FA20, 0xE920E4,\n\t0xE9E420, 0xE9E5FA, 0xE9E9ED, 0xE9ED20, 0xE9EF20, 0xE9F820, 0xE9FA20, 0xEC20E0, 0xEC20E4, 0xECE020, 0xECE420, 0xED20E0, 0xED20E1, 0xED20E4, 0xED20EC, 0xED20EE,\n\t0xED20F9, 0xEEE420, 0xEF20E4, 0xF0E420, 0xF0E920, 0xF0E9ED, 0xF2EC20, 0xF820E4, 0xF8E9ED, 0xF9EC20, 0xFA20E0, 0xFA20E1, 0xFA20E4, 0xFA20EC, 0xFA20EE, 0xFA20F9,\n}\n\nvar ngrams_8859_8_he = [64]uint32{\n\t0x20E0E5, 0x20E0EC, 0x20E4E9, 0x20E4EC, 0x20E4EE, 0x20E4F0, 0x20E9F0, 0x20ECF2, 0x20ECF9, 0x20EDE5, 0x20EDE9, 0x20EFE5, 0x20EFE9, 0x20F8E5, 0x20F8E9, 0x20FAE0,\n\t0x20FAE5, 0x20FAE9, 0xE020E4, 0xE020EC, 0xE020ED, 0xE020FA, 0xE0E420, 0xE0E5E4, 0xE0EC20, 0xE0EE20, 0xE120E4, 0xE120ED, 0xE120FA, 0xE420E4, 0xE420E9, 0xE420EC,\n\t0xE420ED, 0xE420EF, 0xE420F8, 0xE420FA, 0xE4EC20, 0xE5E020, 0xE5E420, 0xE7E020, 0xE9E020, 0xE9E120, 0xE9E420, 0xEC20E4, 0xEC20ED, 0xEC20FA, 0xECF220, 0xECF920,\n\t0xEDE9E9, 0xEDE9F0, 0xEDE9F8, 0xEE20E4, 0xEE20ED, 0xEE20FA, 0xEEE120, 0xEEE420, 0xF2E420, 0xF920E4, 0xF920ED, 0xF920FA, 0xF9E420, 0xFAE020, 0xFAE420, 0xFAE5E9,\n}\n\nfunc newRecognizer_8859_8(language string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:          \"ISO-8859-8\",\n\t\thasC1ByteCharset: \"windows-1255\",\n\t\tlanguage:         language,\n\t\tcharMap:          &charMap_8859_8,\n\t\tngram:            ngram,\n\t}\n}\n\nfunc newRecognizer_8859_8_I_he() *recognizerSingleByte {\n\tr := newRecognizer_8859_8(\"he\", &ngrams_8859_8_I_he)\n\tr.charset = \"ISO-8859-8-I\"\n\treturn r\n}\n\nfunc newRecognizer_8859_8_he() *recognizerSingleByte {\n\treturn newRecognizer_8859_8(\"he\", &ngrams_8859_8_he)\n}\n\nvar charMap_8859_9 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20,\n\t0x20, 0x20, 0xBA, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0x69, 0xFE, 0xDF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0x20,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,\n}\n\nvar ngrams_8859_9_tr = [64]uint32{\n\t0x206261, 0x206269, 0x206275, 0x206461, 0x206465, 0x206765, 0x206861, 0x20696C, 0x206B61, 0x206B6F, 0x206D61, 0x206F6C, 0x207361, 0x207461, 0x207665, 0x207961,\n\t0x612062, 0x616B20, 0x616C61, 0x616D61, 0x616E20, 0x616EFD, 0x617220, 0x617261, 0x6172FD, 0x6173FD, 0x617961, 0x626972, 0x646120, 0x646520, 0x646920, 0x652062,\n\t0x65206B, 0x656469, 0x656E20, 0x657220, 0x657269, 0x657369, 0x696C65, 0x696E20, 0x696E69, 0x697220, 0x6C616E, 0x6C6172, 0x6C6520, 0x6C6572, 0x6E2061, 0x6E2062,\n\t0x6E206B, 0x6E6461, 0x6E6465, 0x6E6520, 0x6E6920, 0x6E696E, 0x6EFD20, 0x72696E, 0x72FD6E, 0x766520, 0x796120, 0x796F72, 0xFD6E20, 0xFD6E64, 0xFD6EFD, 0xFDF0FD,\n}\n\nfunc newRecognizer_8859_9(language string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:          \"ISO-8859-9\",\n\t\thasC1ByteCharset: \"windows-1254\",\n\t\tlanguage:         language,\n\t\tcharMap:          &charMap_8859_9,\n\t\tngram:            ngram,\n\t}\n}\n\nfunc newRecognizer_8859_9_tr() *recognizerSingleByte {\n\treturn newRecognizer_8859_9(\"tr\", &ngrams_8859_9_tr)\n}\n\nvar charMap_windows_1256 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x81, 0x20, 0x83, 0x20, 0x20, 0x20, 0x20,\n\t0x88, 0x20, 0x8A, 0x20, 0x9C, 0x8D, 0x8E, 0x8F,\n\t0x90, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x98, 0x20, 0x9A, 0x20, 0x9C, 0x20, 0x20, 0x9F,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0xAA, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0xB5, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,\n\t0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,\n\t0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0x20,\n\t0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0x20, 0x20, 0x20, 0x20, 0xF4, 0x20, 0x20, 0x20,\n\t0x20, 0xF9, 0x20, 0xFB, 0xFC, 0x20, 0x20, 0xFF,\n}\n\nvar ngrams_windows_1256 = [64]uint32{\n\t0x20C7E1, 0x20C7E4, 0x20C8C7, 0x20DAE1, 0x20DDED, 0x20E1E1, 0x20E3E4, 0x20E6C7, 0xC720C7, 0xC7C120, 0xC7CA20, 0xC7D120, 0xC7E120, 0xC7E1C3, 0xC7E1C7, 0xC7E1C8,\n\t0xC7E1CA, 0xC7E1CC, 0xC7E1CD, 0xC7E1CF, 0xC7E1D3, 0xC7E1DA, 0xC7E1DE, 0xC7E1E3, 0xC7E1E6, 0xC7E1ED, 0xC7E320, 0xC7E420, 0xC7E4CA, 0xC820C7, 0xC920C7, 0xC920DD,\n\t0xC920E1, 0xC920E3, 0xC920E6, 0xCA20C7, 0xCF20C7, 0xCFC920, 0xD120C7, 0xD1C920, 0xD320C7, 0xDA20C7, 0xDAE1EC, 0xDDED20, 0xE120C7, 0xE1C920, 0xE1EC20, 0xE1ED20,\n\t0xE320C7, 0xE3C720, 0xE3C920, 0xE3E420, 0xE420C7, 0xE520C7, 0xE5C720, 0xE6C7E1, 0xE6E420, 0xEC20C7, 0xED20C7, 0xED20E3, 0xED20E6, 0xEDC920, 0xEDD120, 0xEDE420,\n}\n\nfunc newRecognizer_windows_1256() *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:  \"windows-1256\",\n\t\tlanguage: \"ar\",\n\t\tcharMap:  &charMap_windows_1256,\n\t\tngram:    &ngrams_windows_1256,\n\t}\n}\n\nvar charMap_windows_1251 = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x90, 0x83, 0x20, 0x83, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x9A, 0x20, 0x9C, 0x9D, 0x9E, 0x9F,\n\t0x90, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x9A, 0x20, 0x9C, 0x9D, 0x9E, 0x9F,\n\t0x20, 0xA2, 0xA2, 0xBC, 0x20, 0xB4, 0x20, 0x20,\n\t0xB8, 0x20, 0xBA, 0x20, 0x20, 0x20, 0x20, 0xBF,\n\t0x20, 0x20, 0xB3, 0xB3, 0xB4, 0xB5, 0x20, 0x20,\n\t0xB8, 0x20, 0xBA, 0x20, 0xBC, 0xBE, 0xBE, 0xBF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,\n\t0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,\n\t0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,\n\t0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,\n\t0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,\n}\n\nvar ngrams_windows_1251 = [64]uint32{\n\t0x20E220, 0x20E2EE, 0x20E4EE, 0x20E7E0, 0x20E820, 0x20EAE0, 0x20EAEE, 0x20EDE0, 0x20EDE5, 0x20EEE1, 0x20EFEE, 0x20EFF0, 0x20F0E0, 0x20F1EE, 0x20F1F2, 0x20F2EE,\n\t0x20F7F2, 0x20FDF2, 0xE0EDE8, 0xE0F2FC, 0xE3EE20, 0xE5EBFC, 0xE5EDE8, 0xE5F1F2, 0xE5F220, 0xE820EF, 0xE8E520, 0xE8E820, 0xE8FF20, 0xEBE5ED, 0xEBE820, 0xEBFCED,\n\t0xEDE020, 0xEDE520, 0xEDE8E5, 0xEDE8FF, 0xEDEE20, 0xEDEEE2, 0xEE20E2, 0xEE20EF, 0xEE20F1, 0xEEE220, 0xEEE2E0, 0xEEE3EE, 0xEEE920, 0xEEEBFC, 0xEEEC20, 0xEEF1F2,\n\t0xEFEEEB, 0xEFF0E5, 0xEFF0E8, 0xEFF0EE, 0xF0E0E2, 0xF0E5E4, 0xF1F2E0, 0xF1F2E2, 0xF1F2E8, 0xF1FF20, 0xF2E5EB, 0xF2EE20, 0xF2EEF0, 0xF2FC20, 0xF7F2EE, 0xFBF520,\n}\n\nfunc newRecognizer_windows_1251() *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:  \"windows-1251\",\n\t\tlanguage: \"ar\",\n\t\tcharMap:  &charMap_windows_1251,\n\t\tngram:    &ngrams_windows_1251,\n\t}\n}\n\nvar charMap_KOI8_R = [256]byte{\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,\n\t0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,\n\t0x78, 0x79, 0x7A, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0xA3, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0xA3, 0x20, 0x20, 0x20, 0x20,\n\t0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,\n\t0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,\n\t0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,\n\t0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,\n\t0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,\n\t0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,\n\t0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,\n\t0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,\n\t0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,\n}\n\nvar ngrams_KOI8_R = [64]uint32{\n\t0x20C4CF, 0x20C920, 0x20CBC1, 0x20CBCF, 0x20CEC1, 0x20CEC5, 0x20CFC2, 0x20D0CF, 0x20D0D2, 0x20D2C1, 0x20D3CF, 0x20D3D4, 0x20D4CF, 0x20D720, 0x20D7CF, 0x20DAC1,\n\t0x20DCD4, 0x20DED4, 0xC1CEC9, 0xC1D4D8, 0xC5CCD8, 0xC5CEC9, 0xC5D3D4, 0xC5D420, 0xC7CF20, 0xC920D0, 0xC9C520, 0xC9C920, 0xC9D120, 0xCCC5CE, 0xCCC920, 0xCCD8CE,\n\t0xCEC120, 0xCEC520, 0xCEC9C5, 0xCEC9D1, 0xCECF20, 0xCECFD7, 0xCF20D0, 0xCF20D3, 0xCF20D7, 0xCFC7CF, 0xCFCA20, 0xCFCCD8, 0xCFCD20, 0xCFD3D4, 0xCFD720, 0xCFD7C1,\n\t0xD0CFCC, 0xD0D2C5, 0xD0D2C9, 0xD0D2CF, 0xD2C1D7, 0xD2C5C4, 0xD3D120, 0xD3D4C1, 0xD3D4C9, 0xD3D4D7, 0xD4C5CC, 0xD4CF20, 0xD4CFD2, 0xD4D820, 0xD9C820, 0xDED4CF,\n}\n\nfunc newRecognizer_KOI8_R() *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:  \"KOI8-R\",\n\t\tlanguage: \"ru\",\n\t\tcharMap:  &charMap_KOI8_R,\n\t\tngram:    &ngrams_KOI8_R,\n\t}\n}\n\nvar charMap_IBM424_he = [256]byte{\n\t/*        -0    -1    -2    -3    -4    -5    -6    -7    -8    -9    -A    -B    -C    -D    -E    -F   */\n\t/* 0- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 1- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 2- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 3- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 4- */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 5- */ 0x40, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 6- */ 0x40, 0x40, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 7- */ 0x40, 0x71, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x40, 0x40,\n\t/* 8- */ 0x40, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 9- */ 0x40, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* A- */ 0xA0, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* B- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* C- */ 0x40, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* D- */ 0x40, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* E- */ 0x40, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* F- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n}\n\nvar ngrams_IBM424_he_rtl = [64]uint32{\n\t0x404146, 0x404148, 0x404151, 0x404171, 0x404251, 0x404256, 0x404541, 0x404546, 0x404551, 0x404556, 0x404562, 0x404569, 0x404571, 0x405441, 0x405445, 0x405641,\n\t0x406254, 0x406954, 0x417140, 0x454041, 0x454042, 0x454045, 0x454054, 0x454056, 0x454069, 0x454641, 0x464140, 0x465540, 0x465740, 0x466840, 0x467140, 0x514045,\n\t0x514540, 0x514671, 0x515155, 0x515540, 0x515740, 0x516840, 0x517140, 0x544041, 0x544045, 0x544140, 0x544540, 0x554041, 0x554042, 0x554045, 0x554054, 0x554056,\n\t0x554069, 0x564540, 0x574045, 0x584540, 0x585140, 0x585155, 0x625440, 0x684045, 0x685155, 0x695440, 0x714041, 0x714042, 0x714045, 0x714054, 0x714056, 0x714069,\n}\n\nvar ngrams_IBM424_he_ltr = [64]uint32{\n\t0x404146, 0x404154, 0x404551, 0x404554, 0x404556, 0x404558, 0x405158, 0x405462, 0x405469, 0x405546, 0x405551, 0x405746, 0x405751, 0x406846, 0x406851, 0x407141,\n\t0x407146, 0x407151, 0x414045, 0x414054, 0x414055, 0x414071, 0x414540, 0x414645, 0x415440, 0x415640, 0x424045, 0x424055, 0x424071, 0x454045, 0x454051, 0x454054,\n\t0x454055, 0x454057, 0x454068, 0x454071, 0x455440, 0x464140, 0x464540, 0x484140, 0x514140, 0x514240, 0x514540, 0x544045, 0x544055, 0x544071, 0x546240, 0x546940,\n\t0x555151, 0x555158, 0x555168, 0x564045, 0x564055, 0x564071, 0x564240, 0x564540, 0x624540, 0x694045, 0x694055, 0x694071, 0x694540, 0x714140, 0x714540, 0x714651,\n}\n\nfunc newRecognizer_IBM424_he(charset string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:  charset,\n\t\tlanguage: \"he\",\n\t\tcharMap:  &charMap_IBM424_he,\n\t\tngram:    ngram,\n\t}\n}\n\nfunc newRecognizer_IBM424_he_rtl() *recognizerSingleByte {\n\treturn newRecognizer_IBM424_he(\"IBM424_rtl\", &ngrams_IBM424_he_rtl)\n}\n\nfunc newRecognizer_IBM424_he_ltr() *recognizerSingleByte {\n\treturn newRecognizer_IBM424_he(\"IBM424_ltr\", &ngrams_IBM424_he_ltr)\n}\n\nvar charMap_IBM420_ar = [256]byte{\n\t/*        -0    -1    -2    -3    -4    -5    -6    -7    -8    -9    -A    -B    -C    -D    -E    -F   */\n\t/* 0- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 1- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 2- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 3- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 4- */ 0x40, 0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 5- */ 0x40, 0x51, 0x52, 0x40, 0x40, 0x55, 0x56, 0x57, 0x58, 0x59, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 6- */ 0x40, 0x40, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 7- */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,\n\t/* 8- */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,\n\t/* 9- */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,\n\t/* A- */ 0xA0, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,\n\t/* B- */ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0x40, 0x40, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,\n\t/* C- */ 0x40, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x40, 0xCB, 0x40, 0xCD, 0x40, 0xCF,\n\t/* D- */ 0x40, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,\n\t/* E- */ 0x40, 0x40, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xEA, 0xEB, 0x40, 0xED, 0xEE, 0xEF,\n\t/* F- */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xFB, 0xFC, 0xFD, 0xFE, 0x40,\n}\n\nvar ngrams_IBM420_ar_rtl = [64]uint32{\n\t0x4056B1, 0x4056BD, 0x405856, 0x409AB1, 0x40ABDC, 0x40B1B1, 0x40BBBD, 0x40CF56, 0x564056, 0x564640, 0x566340, 0x567540, 0x56B140, 0x56B149, 0x56B156, 0x56B158,\n\t0x56B163, 0x56B167, 0x56B169, 0x56B173, 0x56B178, 0x56B19A, 0x56B1AD, 0x56B1BB, 0x56B1CF, 0x56B1DC, 0x56BB40, 0x56BD40, 0x56BD63, 0x584056, 0x624056, 0x6240AB,\n\t0x6240B1, 0x6240BB, 0x6240CF, 0x634056, 0x734056, 0x736240, 0x754056, 0x756240, 0x784056, 0x9A4056, 0x9AB1DA, 0xABDC40, 0xB14056, 0xB16240, 0xB1DA40, 0xB1DC40,\n\t0xBB4056, 0xBB5640, 0xBB6240, 0xBBBD40, 0xBD4056, 0xBF4056, 0xBF5640, 0xCF56B1, 0xCFBD40, 0xDA4056, 0xDC4056, 0xDC40BB, 0xDC40CF, 0xDC6240, 0xDC7540, 0xDCBD40,\n}\n\nvar ngrams_IBM420_ar_ltr = [64]uint32{\n\t0x404656, 0x4056BB, 0x4056BF, 0x406273, 0x406275, 0x4062B1, 0x4062BB, 0x4062DC, 0x406356, 0x407556, 0x4075DC, 0x40B156, 0x40BB56, 0x40BD56, 0x40BDBB, 0x40BDCF,\n\t0x40BDDC, 0x40DAB1, 0x40DCAB, 0x40DCB1, 0x49B156, 0x564056, 0x564058, 0x564062, 0x564063, 0x564073, 0x564075, 0x564078, 0x56409A, 0x5640B1, 0x5640BB, 0x5640BD,\n\t0x5640BF, 0x5640DA, 0x5640DC, 0x565840, 0x56B156, 0x56CF40, 0x58B156, 0x63B156, 0x63BD56, 0x67B156, 0x69B156, 0x73B156, 0x78B156, 0x9AB156, 0xAB4062, 0xADB156,\n\t0xB14062, 0xB15640, 0xB156CF, 0xB19A40, 0xB1B140, 0xBB4062, 0xBB40DC, 0xBBB156, 0xBD5640, 0xBDBB40, 0xCF4062, 0xCF40DC, 0xCFB156, 0xDAB19A, 0xDCAB40, 0xDCB156,\n}\n\nfunc newRecognizer_IBM420_ar(charset string, ngram *[64]uint32) *recognizerSingleByte {\n\treturn &recognizerSingleByte{\n\t\tcharset:  charset,\n\t\tlanguage: \"ar\",\n\t\tcharMap:  &charMap_IBM420_ar,\n\t\tngram:    ngram,\n\t}\n}\n\nfunc newRecognizer_IBM420_ar_rtl() *recognizerSingleByte {\n\treturn newRecognizer_IBM420_ar(\"IBM420_rtl\", &ngrams_IBM420_ar_rtl)\n}\n\nfunc newRecognizer_IBM420_ar_ltr() *recognizerSingleByte {\n\treturn newRecognizer_IBM420_ar(\"IBM420_ltr\", &ngrams_IBM420_ar_ltr)\n}\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/unicode.go",
    "content": "package chardet\n\nimport (\n\t\"bytes\"\n)\n\nvar (\n\tutf16beBom = []byte{0xFE, 0xFF}\n\tutf16leBom = []byte{0xFF, 0xFE}\n\tutf32beBom = []byte{0x00, 0x00, 0xFE, 0xFF}\n\tutf32leBom = []byte{0xFF, 0xFE, 0x00, 0x00}\n)\n\ntype recognizerUtf16be struct {\n}\n\nfunc newRecognizer_utf16be() *recognizerUtf16be {\n\treturn &recognizerUtf16be{}\n}\n\nfunc (*recognizerUtf16be) Match(input *recognizerInput) (output recognizerOutput) {\n\toutput = recognizerOutput{\n\t\tCharset: \"UTF-16BE\",\n\t}\n\tif bytes.HasPrefix(input.raw, utf16beBom) {\n\t\toutput.Confidence = 100\n\t}\n\treturn\n}\n\ntype recognizerUtf16le struct {\n}\n\nfunc newRecognizer_utf16le() *recognizerUtf16le {\n\treturn &recognizerUtf16le{}\n}\n\nfunc (*recognizerUtf16le) Match(input *recognizerInput) (output recognizerOutput) {\n\toutput = recognizerOutput{\n\t\tCharset: \"UTF-16LE\",\n\t}\n\tif bytes.HasPrefix(input.raw, utf16leBom) && !bytes.HasPrefix(input.raw, utf32leBom) {\n\t\toutput.Confidence = 100\n\t}\n\treturn\n}\n\ntype recognizerUtf32 struct {\n\tname       string\n\tbom        []byte\n\tdecodeChar func(input []byte) uint32\n}\n\nfunc decodeUtf32be(input []byte) uint32 {\n\treturn uint32(input[0])<<24 | uint32(input[1])<<16 | uint32(input[2])<<8 | uint32(input[3])\n}\n\nfunc decodeUtf32le(input []byte) uint32 {\n\treturn uint32(input[3])<<24 | uint32(input[2])<<16 | uint32(input[1])<<8 | uint32(input[0])\n}\n\nfunc newRecognizer_utf32be() *recognizerUtf32 {\n\treturn &recognizerUtf32{\n\t\t\"UTF-32BE\",\n\t\tutf32beBom,\n\t\tdecodeUtf32be,\n\t}\n}\n\nfunc newRecognizer_utf32le() *recognizerUtf32 {\n\treturn &recognizerUtf32{\n\t\t\"UTF-32LE\",\n\t\tutf32leBom,\n\t\tdecodeUtf32le,\n\t}\n}\n\nfunc (r *recognizerUtf32) Match(input *recognizerInput) (output recognizerOutput) {\n\toutput = recognizerOutput{\n\t\tCharset: r.name,\n\t}\n\thasBom := bytes.HasPrefix(input.raw, r.bom)\n\tvar numValid, numInvalid uint32\n\tfor b := input.raw; len(b) >= 4; b = b[4:] {\n\t\tif c := r.decodeChar(b); c >= 0x10FFFF || (c >= 0xD800 && c <= 0xDFFF) {\n\t\t\tnumInvalid++\n\t\t} else {\n\t\t\tnumValid++\n\t\t}\n\t}\n\tif hasBom && numInvalid == 0 {\n\t\toutput.Confidence = 100\n\t} else if hasBom && numValid > numInvalid*10 {\n\t\toutput.Confidence = 80\n\t} else if numValid > 3 && numInvalid == 0 {\n\t\toutput.Confidence = 100\n\t} else if numValid > 0 && numInvalid == 0 {\n\t\toutput.Confidence = 80\n\t} else if numValid > numInvalid*10 {\n\t\toutput.Confidence = 25\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/saintfish/chardet/utf8.go",
    "content": "package chardet\n\nimport (\n\t\"bytes\"\n)\n\nvar utf8Bom = []byte{0xEF, 0xBB, 0xBF}\n\ntype recognizerUtf8 struct {\n}\n\nfunc newRecognizer_utf8() *recognizerUtf8 {\n\treturn &recognizerUtf8{}\n}\n\nfunc (*recognizerUtf8) Match(input *recognizerInput) (output recognizerOutput) {\n\toutput = recognizerOutput{\n\t\tCharset: \"UTF-8\",\n\t}\n\thasBom := bytes.HasPrefix(input.raw, utf8Bom)\n\tinputLen := len(input.raw)\n\tvar numValid, numInvalid uint32\n\tvar trailBytes uint8\n\tfor i := 0; i < inputLen; i++ {\n\t\tc := input.raw[i]\n\t\tif c&0x80 == 0 {\n\t\t\tcontinue\n\t\t}\n\t\tif c&0xE0 == 0xC0 {\n\t\t\ttrailBytes = 1\n\t\t} else if c&0xF0 == 0xE0 {\n\t\t\ttrailBytes = 2\n\t\t} else if c&0xF8 == 0xF0 {\n\t\t\ttrailBytes = 3\n\t\t} else {\n\t\t\tnumInvalid++\n\t\t\tif numInvalid > 5 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ttrailBytes = 0\n\t\t}\n\n\t\tfor i++; i < inputLen; i++ {\n\t\t\tc = input.raw[i]\n\t\t\tif c&0xC0 != 0x80 {\n\t\t\t\tnumInvalid++\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif trailBytes--; trailBytes == 0 {\n\t\t\t\tnumValid++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif hasBom && numInvalid == 0 {\n\t\toutput.Confidence = 100\n\t} else if hasBom && numValid > numInvalid*10 {\n\t\toutput.Confidence = 80\n\t} else if numValid > 3 && numInvalid == 0 {\n\t\toutput.Confidence = 100\n\t} else if numValid > 0 && numInvalid == 0 {\n\t\toutput.Confidence = 80\n\t} else if numValid == 0 && numInvalid == 0 {\n\t\t// Plain ASCII\n\t\toutput.Confidence = 10\n\t} else if numValid > numInvalid*10 {\n\t\toutput.Confidence = 25\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/.gitignore",
    "content": ".DS_Store\n\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/LICENSE",
    "content": "Copyright 2015 Alan Shreve\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/README.md",
    "content": "# go-update: Build self-updating Go programs [![godoc reference](https://godoc.org/github.com/docker-slim/go-update?status.png)](https://godoc.org/github.com/docker-slim/go-update)\n\n## Note\n\nThe forked version will fix a few minor bugs and add a few new features (using updates for installs when the executables are't there yet or updating with a file path instead of a reader interface)\n\n## Original Package Info\n\nPackage update provides functionality to implement secure, self-updating Go programs (or other single-file targets)\nA program can update itself by replacing its executable file with a new version.\n\nIt provides the flexibility to implement different updating user experiences\nlike auto-updating, or manual user-initiated updates. It also boasts\nadvanced features like binary patching and code signing verification.\n\nExample of updating from a URL:\n\n```go\nimport (\n    \"fmt\"\n    \"net/http\"\n\n    \"github.com/docker-slim/go-update\"\n)\n\nfunc doUpdate(url string) error {\n    resp, err := http.Get(url)\n    if err != nil {\n        return err\n    }\n    defer resp.Body.Close()\n    err := update.Apply(resp.Body, update.Options{})\n    if err != nil {\n        // error handling\n    }\n    return err\n}\n```\n\n### Features\n\n- Cross platform support (Windows too!)\n- Binary patch application\n- Checksum verification\n- Code signing verification\n- Support for updating arbitrary files\n\n### API Compatibility Promises\nThe master branch of `go-update` is *not* guaranteed to have a stable API over time. For any production application, you should vendor\nyour dependency on `go-update` with a tool like git submodules, [gb](http://getgb.io/) or [govendor](https://github.com/kardianos/govendor).\n\nThe `go-update` package makes the following promises about API compatibility:\n1. A list of all API-breaking changes will be documented in this README.\n1. `go-update` will strive for as few API-breaking changes as possible.\n\n### License\nApache\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/apply.go",
    "content": "package update\n\nimport (\n\t\"bytes\"\n\t\"crypto\"\n\t\"crypto/x509\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\n\t\"github.com/slimtoolkit/go-update/internal/osext\"\n)\n\nvar (\n\topenFile = os.OpenFile\n)\n\n// Apply performs an update of the current executable (or opts.TargetFile, if set) with the contents of the given io.Reader.\n//\n// Apply performs the following actions to ensure a safe cross-platform update:\n//\n// 1. If configured, applies the contents of the update io.Reader as a binary patch.\n//\n// 2. If configured, computes the checksum of the new executable and verifies it matches.\n//\n// 3. If configured, verifies the signature with a public key.\n//\n// 4. Creates a new file, /path/to/.target.new with the TargetMode with the contents of the updated file\n//\n// 5. Renames /path/to/target to /path/to/.target.old\n//\n// 6. Renames /path/to/.target.new to /path/to/target\n//\n// 7. If the final rename is successful, deletes /path/to/.target.old, returns no error. On Windows,\n// the removal of /path/to/target.old always fails, so instead Apply hides the old file instead.\n//\n// 8. If the final rename fails, attempts to roll back by renaming /path/to/.target.old\n// back to /path/to/target.\n//\n// If the roll back operation fails, the file system is left in an inconsistent state (betweet steps 5 and 6) where\n// there is no new executable file and the old executable file could not be be moved to its original location. In this\n// case you should notify the user of the bad news and ask them to recover manually. Applications can determine whether\n// the rollback failed by calling RollbackError, see the documentation on that function for additional detail.\nfunc Apply(update io.Reader, opts Options) error {\n\t// validate\n\tverify := false\n\tswitch {\n\tcase opts.Signature != nil && opts.PublicKey != nil:\n\t\t// okay\n\t\tverify = true\n\tcase opts.Signature != nil:\n\t\treturn errors.New(\"no public key to verify signature with\")\n\tcase opts.PublicKey != nil:\n\t\treturn errors.New(\"No signature to verify with\")\n\t}\n\n\t// set defaults\n\tif opts.Hash == 0 {\n\t\topts.Hash = crypto.SHA256\n\t}\n\tif opts.Verifier == nil {\n\t\topts.Verifier = NewECDSAVerifier()\n\t}\n\tif opts.TargetMode == 0 {\n\t\topts.TargetMode = 0755\n\t}\n\n\t// get target path\n\tvar err error\n\topts.TargetPath, err = opts.getPath()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ttargetExists := false\n\tif _, err := os.Stat(opts.TargetPath); err == nil {\n\t\ttargetExists = true\n\t}\n\n\tvar newBytes []byte\n\tif opts.Patcher != nil {\n\t\tif newBytes, err = opts.applyPatch(update); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\t// no patch to apply, go on through\n\t\tif newBytes, err = ioutil.ReadAll(update); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// verify checksum if requested\n\tif opts.Checksum != nil {\n\t\tif err = opts.verifyChecksum(newBytes); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif verify {\n\t\tif err = opts.verifySignature(newBytes); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// get the directory the executable exists in\n\tupdateDir := filepath.Dir(opts.TargetPath)\n\tfilename := filepath.Base(opts.TargetPath)\n\n\t// Copy the contents of newbinary to a new executable file\n\tnewPath := filepath.Join(updateDir, fmt.Sprintf(\".%s.new\", filename))\n\tfp, err := openFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, opts.TargetMode)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer fp.Close()\n\n\t_, err = io.Copy(fp, bytes.NewReader(newBytes))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// if we don't call fp.Close(), windows won't let us move the new executable\n\t// because the file will still be \"in use\"\n\tfp.Close()\n\n\t// this is where we'll move the executable to so that we can swap in the updated replacement\n\toldPath := opts.OldSavePath\n\tremoveOld := opts.OldSavePath == \"\"\n\tif removeOld {\n\t\toldPath = filepath.Join(updateDir, fmt.Sprintf(\".%s.old\", filename))\n\t}\n\n\t// delete any existing old exec file - this is necessary on Windows for two reasons:\n\t// 1. after a successful update, Windows can't remove the .old file because the process is still running\n\t// 2. windows rename operations fail if the destination file already exists\n\t_ = os.Remove(oldPath)\n\n\tif targetExists {\n\t\t// move the existing executable to a new file in the same directory\n\t\terr = os.Rename(opts.TargetPath, oldPath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// move the new exectuable in to become the new program\n\terr = os.Rename(newPath, opts.TargetPath)\n\n\tif err != nil {\n\t\t// move unsuccessful\n\t\t//\n\t\t// The filesystem is now in a bad state. We have successfully\n\t\t// moved the existing binary to a new location, but we couldn't move the new\n\t\t// binary to take its place. That means there is no file where the current executable binary\n\t\t// used to be!\n\t\t// Try to rollback by restoring the old binary to its original path.\n\t\tif targetExists {\n\t\t\trerr := os.Rename(oldPath, opts.TargetPath)\n\t\t\tif rerr != nil {\n\t\t\t\treturn &rollbackErr{err, rerr}\n\t\t\t}\n\t\t}\n\n\t\treturn err\n\t}\n\n\t// move successful, remove the old binary if needed\n\tif removeOld {\n\t\terrRemove := os.Remove(oldPath)\n\n\t\t// windows has trouble with removing old binaries, so hide it instead\n\t\tif errRemove != nil {\n\t\t\t_ = hideFile(oldPath)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// RollbackError takes an error value returned by Apply and returns the error, if any,\n// that occurred when attempting to roll back from a failed update. Applications should\n// always call this function on any non-nil errors returned by Apply.\n//\n// If no rollback was needed or if the rollback was successful, RollbackError returns nil,\n// otherwise it returns the error encountered when trying to roll back.\nfunc RollbackError(err error) error {\n\tif err == nil {\n\t\treturn nil\n\t}\n\tif rerr, ok := err.(*rollbackErr); ok {\n\t\treturn rerr.rollbackErr\n\t}\n\treturn nil\n}\n\ntype rollbackErr struct {\n\terror             // original error\n\trollbackErr error // error encountered while rolling back\n}\n\ntype Options struct {\n\t// TargetPath defines the path to the file to update.\n\t// The emptry string means 'the executable file of the running program'.\n\tTargetPath string\n\n\t// Create TargetPath replacement with this file mode. If zero, defaults to 0755.\n\tTargetMode os.FileMode\n\n\t// Checksum of the new binary to verify against. If nil, no checksum or signature verification is done.\n\tChecksum []byte\n\n\t// Public key to use for signature verification. If nil, no signature verification is done.\n\tPublicKey crypto.PublicKey\n\n\t// Signature to verify the updated file. If nil, no signature verification is done.\n\tSignature []byte\n\n\t// Pluggable signature verification algorithm. If nil, ECDSA is used.\n\tVerifier Verifier\n\n\t// Use this hash function to generate the checksum. If not set, SHA256 is used.\n\tHash crypto.Hash\n\n\t// If nil, treat the update as a complete replacement for the contents of the file at TargetPath.\n\t// If non-nil, treat the update contents as a patch and use this object to apply the patch.\n\tPatcher Patcher\n\n\t// Store the old executable file at this path after a successful update.\n\t// The empty string means the old executable file will be removed after the update.\n\tOldSavePath string\n}\n\n// CheckPermissions determines whether the process has the correct permissions to\n// perform the requested update. If the update can proceed, it returns nil, otherwise\n// it returns the error that would occur if an update were attempted.\nfunc (o *Options) CheckPermissions() error {\n\t// get the directory the file exists in\n\tpath, err := o.getPath()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfileDir := filepath.Dir(path)\n\tfileName := filepath.Base(path)\n\n\t// attempt to open a file in the file's directory\n\tnewPath := filepath.Join(fileDir, fmt.Sprintf(\".%s.new\", fileName))\n\tfp, err := openFile(newPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, o.TargetMode)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfp.Close()\n\n\t_ = os.Remove(newPath)\n\treturn nil\n}\n\n// SetPublicKeyPEM is a convenience method to set the PublicKey property\n// used for checking a completed update's signature by parsing a\n// Public Key formatted as PEM data.\nfunc (o *Options) SetPublicKeyPEM(pembytes []byte) error {\n\tblock, _ := pem.Decode(pembytes)\n\tif block == nil {\n\t\treturn errors.New(\"couldn't parse PEM data\")\n\t}\n\n\tpub, err := x509.ParsePKIXPublicKey(block.Bytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\to.PublicKey = pub\n\treturn nil\n}\n\nfunc (o *Options) getPath() (string, error) {\n\tif o.TargetPath == \"\" {\n\t\treturn osext.Executable()\n\t} else {\n\t\treturn o.TargetPath, nil\n\t}\n}\n\nfunc (o *Options) applyPatch(patch io.Reader) ([]byte, error) {\n\t// open the file to patch\n\told, err := os.Open(o.TargetPath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer old.Close()\n\n\t// apply the patch\n\tvar applied bytes.Buffer\n\tif err = o.Patcher.Patch(old, &applied, patch); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn applied.Bytes(), nil\n}\n\nfunc (o *Options) verifyChecksum(updated []byte) error {\n\tchecksum, err := checksumFor(o.Hash, updated)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !bytes.Equal(o.Checksum, checksum) {\n\t\treturn fmt.Errorf(\"Updated file has wrong checksum. Expected: %x, got: %x\", o.Checksum, checksum)\n\t}\n\treturn nil\n}\n\nfunc (o *Options) verifySignature(updated []byte) error {\n\tchecksum, err := checksumFor(o.Hash, updated)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn o.Verifier.VerifySignature(checksum, o.Signature, o.Hash, o.PublicKey)\n}\n\nfunc checksumFor(h crypto.Hash, payload []byte) ([]byte, error) {\n\tif !h.Available() {\n\t\treturn nil, errors.New(\"requested hash function not available\")\n\t}\n\thash := h.New()\n\thash.Write(payload) // guaranteed not to error\n\treturn hash.Sum([]byte{}), nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/doc.go",
    "content": "/*\nPackage update provides functionality to implement secure, self-updating Go programs (or other single-file targets).\n\nFor complete updating solutions please see Equinox (https://equinox.io) and go-tuf (https://github.com/flynn/go-tuf).\n\nBasic Example\n\nThis example shows how to update a program remotely from a URL.\n\n\timport (\n\t\t\"fmt\"\n\t\t\"net/http\"\n\n\t\t\"github.com/docker-slim/go-update\"\n\t)\n\n\tfunc doUpdate(url string) error {\n\t\t// request the new file\n\t\tresp, err := http.Get(url)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer resp.Body.Close()\n\t\terr := update.Apply(resp.Body, update.Options{})\n\t\tif err != nil {\n\t\t\tif rerr := update.RollbackError(err); rerr != nil {\n\t\t\t\tfmt.Println(\"Failed to rollback from bad update: %v\", rerr)\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n\n\nBinary Patching\n\nGo binaries can often be large. It can be advantageous to only ship a binary patch to a client\ninstead of the complete program text of a new version.\n\nThis example shows how to update a program with a bsdiff binary patch. Other patch formats\nmay be applied by implementing the Patcher interface.\n\n\timport (\n\t\t\"encoding/hex\"\n\t\t\"io\"\n\n\t\t\"github.com/docker-slim/go-update\"\n\t)\n\n\tfunc updateWithPatch(patch io.Reader) error {\n\t\terr := update.Apply(patch, update.Options{\n\t\t\tPatcher: update.NewBSDiffPatcher()\n\t\t})\n\t\tif err != nil {\n\t\t\t// error handling\n\t\t}\n\t\treturn err\n\t}\n\nChecksum Verification\n\nUpdating executable code on a computer can be a dangerous operation unless you\ntake the appropriate steps to guarantee the authenticity of the new code. While\nchecksum verification is important, it should always be combined with signature\nverification (next section) to guarantee that the code came from a trusted party.\n\ngo-update validates SHA256 checksums by default, but this is pluggable via the Hash\nproperty on the Options struct.\n\nThis example shows how to guarantee that the newly-updated binary is verified to\nhave an appropriate checksum (that was otherwise retrived via a secure channel)\nspecified as a hex string.\n\n\timport (\n\t\t\"crypto\"\n\t\t_ \"crypto/sha256\"\n\t\t\"encoding/hex\"\n\t\t\"io\"\n\n\t\t\"github.com/docker-slim/go-update\"\n\t)\n\n\tfunc updateWithChecksum(binary io.Reader, hexChecksum string) error {\n\t\tchecksum, err := hex.DecodeString(hexChecksum)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = update.Apply(binary, update.Options{\n\t\t\tHash: crypto.SHA256, \t// this is the default, you don't need to specify it\n\t\t\tChecksum: checksum,\n\t\t})\n\t\tif err != nil {\n\t\t\t// error handling\n\t\t}\n\t\treturn err\n\t}\n\nCryptographic Signature Verification\n\nCryptographic verification of new code from an update is an extremely important way to guarantee the\nsecurity and integrity of your updates.\n\nVerification is performed by validating the signature of a hash of the new file. This\nmeans nothing changes if you apply your update with a patch.\n\nThis example shows how to add signature verification to your updates. To make all of this work\nan application distributor must first create a public/private key pair and embed the public key\ninto their application. When they issue a new release, the issuer must sign the new executable file\nwith the private key and distribute the signature along with the update.\n\n\timport (\n\t\t\"crypto\"\n\t\t_ \"crypto/sha256\"\n\t\t\"encoding/hex\"\n\t\t\"io\"\n\n\t\t\"github.com/docker-slim/go-update\"\n\t)\n\n\tvar publicKey = []byte(`\n\t-----BEGIN PUBLIC KEY-----\n\tMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEtrVmBxQvheRArXjg2vG1xIprWGuCyESx\n\tMMY8pjmjepSy2kuz+nl9aFLqmr+rDNdYvEBqQaZrYMc6k29gjvoQnQ==\n\t-----END PUBLIC KEY-----\n\t`)\n\n\tfunc verifiedUpdate(binary io.Reader, hexChecksum, hexSignature string) {\n\t\tchecksum, err := hex.DecodeString(hexChecksum)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tsignature, err := hex.DecodeString(hexSignature)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\topts := update.Options{\n\t\t\tChecksum: checksum,\n\t\t\tSignature: signature,\n\t\t\tHash: crypto.SHA256, \t                 // this is the default, you don't need to specify it\n\t\t\tVerifier: update.NewECDSAVerifier(),   // this is the default, you don't need to specify it\n\t\t}\n\t\terr = opts.SetPublicKeyPEM(publicKey)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\terr = update.Apply(binary, opts)\n\t\tif err != nil {\n\t\t\t// error handling\n\t\t}\n\t\treturn err\n\t}\n\n\nBuilding Single-File Go Binaries\n\nIn order to update a Go application with go-update, you must distributed it as a single executable.\nThis is often easy, but some applications require static assets (like HTML and CSS asset files or TLS certificates).\nIn order to update applications like these, you'll want to make sure to embed those asset files into\nthe distributed binary with a tool like go-bindata (my favorite): https://github.com/jteeuwen/go-bindata\n\nNon-Goals\n\nMechanisms and protocols for determining whether an update should be applied and, if so, which one are\nout of scope for this package. Please consult go-tuf (https://github.com/flynn/go-tuf) or Equinox (https://equinox.io)\nfor more complete solutions.\n\ngo-update only works for self-updating applications that are distributed as a single binary, i.e.\napplications that do not have additional assets or dependency files.\nUpdating application that are distributed as mutliple on-disk files is out of scope, although this\nmay change in future versions of this library.\n\n*/\npackage update\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/hide_noop.go",
    "content": "// +build !windows\n\npackage update\n\nfunc hideFile(path string) error {\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/hide_windows.go",
    "content": "package update\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nfunc hideFile(path string) error {\n\tkernel32 := syscall.NewLazyDLL(\"kernel32.dll\")\n\tsetFileAttributes := kernel32.NewProc(\"SetFileAttributesW\")\n\n\tr1, _, err := setFileAttributes.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), 2)\n\n\tif r1 == 0 {\n\t\treturn err\n\t} else {\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/License",
    "content": "Copyright 2012 Keith Rarick\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/Readme.md",
    "content": "# binarydist\n\nPackage binarydist implements binary diff and patch as described on\n<http://www.daemonology.net/bsdiff/>. It reads and writes files\ncompatible with the tools there.\n\nDocumentation at <http://go.pkgdoc.org/github.com/kr/binarydist>.\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/bzip2.go",
    "content": "package binarydist\n\nimport (\n\t\"io\"\n\t\"os/exec\"\n)\n\ntype bzip2Writer struct {\n\tc *exec.Cmd\n\tw io.WriteCloser\n}\n\nfunc (w bzip2Writer) Write(b []byte) (int, error) {\n\treturn w.w.Write(b)\n}\n\nfunc (w bzip2Writer) Close() error {\n\tif err := w.w.Close(); err != nil {\n\t\treturn err\n\t}\n\treturn w.c.Wait()\n}\n\n// Package compress/bzip2 implements only decompression,\n// so we'll fake it by running bzip2 in another process.\nfunc newBzip2Writer(w io.Writer) (wc io.WriteCloser, err error) {\n\tvar bw bzip2Writer\n\tbw.c = exec.Command(\"bzip2\", \"-c\")\n\tbw.c.Stdout = w\n\n\tif bw.w, err = bw.c.StdinPipe(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = bw.c.Start(); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn bw, nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/diff.go",
    "content": "package binarydist\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"io\"\n\t\"io/ioutil\"\n)\n\nfunc swap(a []int, i, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc split(I, V []int, start, length, h int) {\n\tvar i, j, k, x, jj, kk int\n\n\tif length < 16 {\n\t\tfor k = start; k < start+length; k += j {\n\t\t\tj = 1\n\t\t\tx = V[I[k]+h]\n\t\t\tfor i = 1; k+i < start+length; i++ {\n\t\t\t\tif V[I[k+i]+h] < x {\n\t\t\t\t\tx = V[I[k+i]+h]\n\t\t\t\t\tj = 0\n\t\t\t\t}\n\t\t\t\tif V[I[k+i]+h] == x {\n\t\t\t\t\tswap(I, k+i, k+j)\n\t\t\t\t\tj++\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor i = 0; i < j; i++ {\n\t\t\t\tV[I[k+i]] = k + j - 1\n\t\t\t}\n\t\t\tif j == 1 {\n\t\t\t\tI[k] = -1\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\n\tx = V[I[start+length/2]+h]\n\tjj = 0\n\tkk = 0\n\tfor i = start; i < start+length; i++ {\n\t\tif V[I[i]+h] < x {\n\t\t\tjj++\n\t\t}\n\t\tif V[I[i]+h] == x {\n\t\t\tkk++\n\t\t}\n\t}\n\tjj += start\n\tkk += jj\n\n\ti = start\n\tj = 0\n\tk = 0\n\tfor i < jj {\n\t\tif V[I[i]+h] < x {\n\t\t\ti++\n\t\t} else if V[I[i]+h] == x {\n\t\t\tswap(I, i, jj+j)\n\t\t\tj++\n\t\t} else {\n\t\t\tswap(I, i, kk+k)\n\t\t\tk++\n\t\t}\n\t}\n\n\tfor jj+j < kk {\n\t\tif V[I[jj+j]+h] == x {\n\t\t\tj++\n\t\t} else {\n\t\t\tswap(I, jj+j, kk+k)\n\t\t\tk++\n\t\t}\n\t}\n\n\tif jj > start {\n\t\tsplit(I, V, start, jj-start, h)\n\t}\n\n\tfor i = 0; i < kk-jj; i++ {\n\t\tV[I[jj+i]] = kk - 1\n\t}\n\tif jj == kk-1 {\n\t\tI[jj] = -1\n\t}\n\n\tif start+length > kk {\n\t\tsplit(I, V, kk, start+length-kk, h)\n\t}\n}\n\nfunc qsufsort(obuf []byte) []int {\n\tvar buckets [256]int\n\tvar i, h int\n\tI := make([]int, len(obuf)+1)\n\tV := make([]int, len(obuf)+1)\n\n\tfor _, c := range obuf {\n\t\tbuckets[c]++\n\t}\n\tfor i = 1; i < 256; i++ {\n\t\tbuckets[i] += buckets[i-1]\n\t}\n\tcopy(buckets[1:], buckets[:])\n\tbuckets[0] = 0\n\n\tfor i, c := range obuf {\n\t\tbuckets[c]++\n\t\tI[buckets[c]] = i\n\t}\n\n\tI[0] = len(obuf)\n\tfor i, c := range obuf {\n\t\tV[i] = buckets[c]\n\t}\n\n\tV[len(obuf)] = 0\n\tfor i = 1; i < 256; i++ {\n\t\tif buckets[i] == buckets[i-1]+1 {\n\t\t\tI[buckets[i]] = -1\n\t\t}\n\t}\n\tI[0] = -1\n\n\tfor h = 1; I[0] != -(len(obuf) + 1); h += h {\n\t\tvar n int\n\t\tfor i = 0; i < len(obuf)+1; {\n\t\t\tif I[i] < 0 {\n\t\t\t\tn -= I[i]\n\t\t\t\ti -= I[i]\n\t\t\t} else {\n\t\t\t\tif n != 0 {\n\t\t\t\t\tI[i-n] = -n\n\t\t\t\t}\n\t\t\t\tn = V[I[i]] + 1 - i\n\t\t\t\tsplit(I, V, i, n, h)\n\t\t\t\ti += n\n\t\t\t\tn = 0\n\t\t\t}\n\t\t}\n\t\tif n != 0 {\n\t\t\tI[i-n] = -n\n\t\t}\n\t}\n\n\tfor i = 0; i < len(obuf)+1; i++ {\n\t\tI[V[i]] = i\n\t}\n\treturn I\n}\n\nfunc matchlen(a, b []byte) (i int) {\n\tfor i < len(a) && i < len(b) && a[i] == b[i] {\n\t\ti++\n\t}\n\treturn i\n}\n\nfunc search(I []int, obuf, nbuf []byte, st, en int) (pos, n int) {\n\tif en-st < 2 {\n\t\tx := matchlen(obuf[I[st]:], nbuf)\n\t\ty := matchlen(obuf[I[en]:], nbuf)\n\n\t\tif x > y {\n\t\t\treturn I[st], x\n\t\t} else {\n\t\t\treturn I[en], y\n\t\t}\n\t}\n\n\tx := st + (en-st)/2\n\tif bytes.Compare(obuf[I[x]:], nbuf) < 0 {\n\t\treturn search(I, obuf, nbuf, x, en)\n\t} else {\n\t\treturn search(I, obuf, nbuf, st, x)\n\t}\n\tpanic(\"unreached\")\n}\n\n// Diff computes the difference between old and new, according to the bsdiff\n// algorithm, and writes the result to patch.\nfunc Diff(old, new io.Reader, patch io.Writer) error {\n\tobuf, err := ioutil.ReadAll(old)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnbuf, err := ioutil.ReadAll(new)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpbuf, err := diffBytes(obuf, nbuf)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = patch.Write(pbuf)\n\treturn err\n}\n\nfunc diffBytes(obuf, nbuf []byte) ([]byte, error) {\n\tvar patch seekBuffer\n\terr := diff(obuf, nbuf, &patch)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn patch.buf, nil\n}\n\nfunc diff(obuf, nbuf []byte, patch io.WriteSeeker) error {\n\tvar lenf int\n\tI := qsufsort(obuf)\n\tdb := make([]byte, len(nbuf))\n\teb := make([]byte, len(nbuf))\n\tvar dblen, eblen int\n\n\tvar hdr header\n\thdr.Magic = magic\n\thdr.NewSize = int64(len(nbuf))\n\terr := binary.Write(patch, signMagLittleEndian{}, &hdr)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Compute the differences, writing ctrl as we go\n\tpfbz2, err := newBzip2Writer(patch)\n\tif err != nil {\n\t\treturn err\n\t}\n\tvar scan, pos, length int\n\tvar lastscan, lastpos, lastoffset int\n\tfor scan < len(nbuf) {\n\t\tvar oldscore int\n\t\tscan += length\n\t\tfor scsc := scan; scan < len(nbuf); scan++ {\n\t\t\tpos, length = search(I, obuf, nbuf[scan:], 0, len(obuf))\n\n\t\t\tfor ; scsc < scan+length; scsc++ {\n\t\t\t\tif scsc+lastoffset < len(obuf) &&\n\t\t\t\t\tobuf[scsc+lastoffset] == nbuf[scsc] {\n\t\t\t\t\toldscore++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (length == oldscore && length != 0) || length > oldscore+8 {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\tif scan+lastoffset < len(obuf) && obuf[scan+lastoffset] == nbuf[scan] {\n\t\t\t\toldscore--\n\t\t\t}\n\t\t}\n\n\t\tif length != oldscore || scan == len(nbuf) {\n\t\t\tvar s, Sf int\n\t\t\tlenf = 0\n\t\t\tfor i := 0; lastscan+i < scan && lastpos+i < len(obuf); {\n\t\t\t\tif obuf[lastpos+i] == nbuf[lastscan+i] {\n\t\t\t\t\ts++\n\t\t\t\t}\n\t\t\t\ti++\n\t\t\t\tif s*2-i > Sf*2-lenf {\n\t\t\t\t\tSf = s\n\t\t\t\t\tlenf = i\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlenb := 0\n\t\t\tif scan < len(nbuf) {\n\t\t\t\tvar s, Sb int\n\t\t\t\tfor i := 1; (scan >= lastscan+i) && (pos >= i); i++ {\n\t\t\t\t\tif obuf[pos-i] == nbuf[scan-i] {\n\t\t\t\t\t\ts++\n\t\t\t\t\t}\n\t\t\t\t\tif s*2-i > Sb*2-lenb {\n\t\t\t\t\t\tSb = s\n\t\t\t\t\t\tlenb = i\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif lastscan+lenf > scan-lenb {\n\t\t\t\toverlap := (lastscan + lenf) - (scan - lenb)\n\t\t\t\ts := 0\n\t\t\t\tSs := 0\n\t\t\t\tlens := 0\n\t\t\t\tfor i := 0; i < overlap; i++ {\n\t\t\t\t\tif nbuf[lastscan+lenf-overlap+i] == obuf[lastpos+lenf-overlap+i] {\n\t\t\t\t\t\ts++\n\t\t\t\t\t}\n\t\t\t\t\tif nbuf[scan-lenb+i] == obuf[pos-lenb+i] {\n\t\t\t\t\t\ts--\n\t\t\t\t\t}\n\t\t\t\t\tif s > Ss {\n\t\t\t\t\t\tSs = s\n\t\t\t\t\t\tlens = i + 1\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlenf += lens - overlap\n\t\t\t\tlenb -= lens\n\t\t\t}\n\n\t\t\tfor i := 0; i < lenf; i++ {\n\t\t\t\tdb[dblen+i] = nbuf[lastscan+i] - obuf[lastpos+i]\n\t\t\t}\n\t\t\tfor i := 0; i < (scan-lenb)-(lastscan+lenf); i++ {\n\t\t\t\teb[eblen+i] = nbuf[lastscan+lenf+i]\n\t\t\t}\n\n\t\t\tdblen += lenf\n\t\t\teblen += (scan - lenb) - (lastscan + lenf)\n\n\t\t\terr = binary.Write(pfbz2, signMagLittleEndian{}, int64(lenf))\n\t\t\tif err != nil {\n\t\t\t\tpfbz2.Close()\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tval := (scan - lenb) - (lastscan + lenf)\n\t\t\terr = binary.Write(pfbz2, signMagLittleEndian{}, int64(val))\n\t\t\tif err != nil {\n\t\t\t\tpfbz2.Close()\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tval = (pos - lenb) - (lastpos + lenf)\n\t\t\terr = binary.Write(pfbz2, signMagLittleEndian{}, int64(val))\n\t\t\tif err != nil {\n\t\t\t\tpfbz2.Close()\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tlastscan = scan - lenb\n\t\t\tlastpos = pos - lenb\n\t\t\tlastoffset = pos - scan\n\t\t}\n\t}\n\terr = pfbz2.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Compute size of compressed ctrl data\n\tl64, err := patch.Seek(0, 1)\n\tif err != nil {\n\t\treturn err\n\t}\n\thdr.CtrlLen = int64(l64 - 32)\n\n\t// Write compressed diff data\n\tpfbz2, err = newBzip2Writer(patch)\n\tif err != nil {\n\t\treturn err\n\t}\n\tn, err := pfbz2.Write(db[:dblen])\n\tif err != nil {\n\t\tpfbz2.Close()\n\t\treturn err\n\t}\n\tif n != dblen {\n\t\tpfbz2.Close()\n\t\treturn io.ErrShortWrite\n\t}\n\terr = pfbz2.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Compute size of compressed diff data\n\tn64, err := patch.Seek(0, 1)\n\tif err != nil {\n\t\treturn err\n\t}\n\thdr.DiffLen = n64 - l64\n\n\t// Write compressed extra data\n\tpfbz2, err = newBzip2Writer(patch)\n\tif err != nil {\n\t\treturn err\n\t}\n\tn, err = pfbz2.Write(eb[:eblen])\n\tif err != nil {\n\t\tpfbz2.Close()\n\t\treturn err\n\t}\n\tif n != eblen {\n\t\tpfbz2.Close()\n\t\treturn io.ErrShortWrite\n\t}\n\terr = pfbz2.Close()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Seek to the beginning, write the header, and close the file\n\t_, err = patch.Seek(0, 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\terr = binary.Write(patch, signMagLittleEndian{}, &hdr)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/doc.go",
    "content": "// Package binarydist implements binary diff and patch as described on\n// http://www.daemonology.net/bsdiff/. It reads and writes files\n// compatible with the tools there.\npackage binarydist\n\nvar magic = [8]byte{'B', 'S', 'D', 'I', 'F', 'F', '4', '0'}\n\n// File format:\n//   0       8    \"BSDIFF40\"\n//   8       8    X\n//   16      8    Y\n//   24      8    sizeof(newfile)\n//   32      X    bzip2(control block)\n//   32+X    Y    bzip2(diff block)\n//   32+X+Y  ???  bzip2(extra block)\n// with control block a set of triples (x,y,z) meaning \"add x bytes\n// from oldfile to x bytes from the diff block; copy y bytes from the\n// extra block; seek forwards in oldfile by z bytes\".\ntype header struct {\n\tMagic   [8]byte\n\tCtrlLen int64\n\tDiffLen int64\n\tNewSize int64\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/encoding.go",
    "content": "package binarydist\n\n// SignMagLittleEndian is the numeric encoding used by the bsdiff tools.\n// It implements binary.ByteOrder using a sign-magnitude format\n// and little-endian byte order. Only methods Uint64 and String\n// have been written; the rest panic.\ntype signMagLittleEndian struct{}\n\nfunc (signMagLittleEndian) Uint16(b []byte) uint16 { panic(\"unimplemented\") }\n\nfunc (signMagLittleEndian) PutUint16(b []byte, v uint16) { panic(\"unimplemented\") }\n\nfunc (signMagLittleEndian) Uint32(b []byte) uint32 { panic(\"unimplemented\") }\n\nfunc (signMagLittleEndian) PutUint32(b []byte, v uint32) { panic(\"unimplemented\") }\n\nfunc (signMagLittleEndian) Uint64(b []byte) uint64 {\n\ty := int64(b[0]) |\n\t\tint64(b[1])<<8 |\n\t\tint64(b[2])<<16 |\n\t\tint64(b[3])<<24 |\n\t\tint64(b[4])<<32 |\n\t\tint64(b[5])<<40 |\n\t\tint64(b[6])<<48 |\n\t\tint64(b[7]&0x7f)<<56\n\n\tif b[7]&0x80 != 0 {\n\t\ty = -y\n\t}\n\treturn uint64(y)\n}\n\nfunc (signMagLittleEndian) PutUint64(b []byte, v uint64) {\n\tx := int64(v)\n\tneg := x < 0\n\tif neg {\n\t\tx = -x\n\t}\n\n\tb[0] = byte(x)\n\tb[1] = byte(x >> 8)\n\tb[2] = byte(x >> 16)\n\tb[3] = byte(x >> 24)\n\tb[4] = byte(x >> 32)\n\tb[5] = byte(x >> 40)\n\tb[6] = byte(x >> 48)\n\tb[7] = byte(x >> 56)\n\tif neg {\n\t\tb[7] |= 0x80\n\t}\n}\n\nfunc (signMagLittleEndian) String() string { return \"signMagLittleEndian\" }\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/patch.go",
    "content": "package binarydist\n\nimport (\n\t\"bytes\"\n\t\"compress/bzip2\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"io\"\n\t\"io/ioutil\"\n)\n\nvar ErrCorrupt = errors.New(\"corrupt patch\")\n\n// Patch applies patch to old, according to the bspatch algorithm,\n// and writes the result to new.\nfunc Patch(old io.Reader, new io.Writer, patch io.Reader) error {\n\tvar hdr header\n\terr := binary.Read(patch, signMagLittleEndian{}, &hdr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif hdr.Magic != magic {\n\t\treturn ErrCorrupt\n\t}\n\tif hdr.CtrlLen < 0 || hdr.DiffLen < 0 || hdr.NewSize < 0 {\n\t\treturn ErrCorrupt\n\t}\n\n\tctrlbuf := make([]byte, hdr.CtrlLen)\n\t_, err = io.ReadFull(patch, ctrlbuf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tcpfbz2 := bzip2.NewReader(bytes.NewReader(ctrlbuf))\n\n\tdiffbuf := make([]byte, hdr.DiffLen)\n\t_, err = io.ReadFull(patch, diffbuf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdpfbz2 := bzip2.NewReader(bytes.NewReader(diffbuf))\n\n\t// The entire rest of the file is the extra block.\n\tepfbz2 := bzip2.NewReader(patch)\n\n\tobuf, err := ioutil.ReadAll(old)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tnbuf := make([]byte, hdr.NewSize)\n\n\tvar oldpos, newpos int64\n\tfor newpos < hdr.NewSize {\n\t\tvar ctrl struct{ Add, Copy, Seek int64 }\n\t\terr = binary.Read(cpfbz2, signMagLittleEndian{}, &ctrl)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Sanity-check\n\t\tif newpos+ctrl.Add > hdr.NewSize {\n\t\t\treturn ErrCorrupt\n\t\t}\n\n\t\t// Read diff string\n\t\t_, err = io.ReadFull(dpfbz2, nbuf[newpos:newpos+ctrl.Add])\n\t\tif err != nil {\n\t\t\treturn ErrCorrupt\n\t\t}\n\n\t\t// Add old data to diff string\n\t\tfor i := int64(0); i < ctrl.Add; i++ {\n\t\t\tif oldpos+i >= 0 && oldpos+i < int64(len(obuf)) {\n\t\t\t\tnbuf[newpos+i] += obuf[oldpos+i]\n\t\t\t}\n\t\t}\n\n\t\t// Adjust pointers\n\t\tnewpos += ctrl.Add\n\t\toldpos += ctrl.Add\n\n\t\t// Sanity-check\n\t\tif newpos+ctrl.Copy > hdr.NewSize {\n\t\t\treturn ErrCorrupt\n\t\t}\n\n\t\t// Read extra string\n\t\t_, err = io.ReadFull(epfbz2, nbuf[newpos:newpos+ctrl.Copy])\n\t\tif err != nil {\n\t\t\treturn ErrCorrupt\n\t\t}\n\n\t\t// Adjust pointers\n\t\tnewpos += ctrl.Copy\n\t\toldpos += ctrl.Seek\n\t}\n\n\t// Write the new file\n\tfor len(nbuf) > 0 {\n\t\tn, err := new.Write(nbuf)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tnbuf = nbuf[n:]\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/binarydist/seek.go",
    "content": "package binarydist\n\nimport (\n\t\"errors\"\n)\n\ntype seekBuffer struct {\n\tbuf []byte\n\tpos int\n}\n\nfunc (b *seekBuffer) Write(p []byte) (n int, err error) {\n\tn = copy(b.buf[b.pos:], p)\n\tif n == len(p) {\n\t\tb.pos += n\n\t\treturn n, nil\n\t}\n\tb.buf = append(b.buf, p[n:]...)\n\tb.pos += len(p)\n\treturn len(p), nil\n}\n\nfunc (b *seekBuffer) Seek(offset int64, whence int) (ret int64, err error) {\n\tvar abs int64\n\tswitch whence {\n\tcase 0:\n\t\tabs = offset\n\tcase 1:\n\t\tabs = int64(b.pos) + offset\n\tcase 2:\n\t\tabs = int64(len(b.buf)) + offset\n\tdefault:\n\t\treturn 0, errors.New(\"binarydist: invalid whence\")\n\t}\n\tif abs < 0 {\n\t\treturn 0, errors.New(\"binarydist: negative position\")\n\t}\n\tif abs >= 1<<31 {\n\t\treturn 0, errors.New(\"binarydist: position out of range\")\n\t}\n\tb.pos = int(abs)\n\treturn abs, nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/osext/LICENSE",
    "content": "Copyright (c) 2012 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/slimtoolkit/go-update/internal/osext/README.md",
    "content": "### Extensions to the \"os\" package.\n\n## Find the current Executable and ExecutableFolder.\n\nThere is sometimes utility in finding the current executable file\nthat is running. This can be used for upgrading the current executable\nor finding resources located relative to the executable file. Both\nworking directory and the os.Args[0] value are arbitrary and cannot\nbe relied on; os.Args[0] can be \"faked\".\n\nMulti-platform and supports:\n * Linux\n * OS X\n * Windows\n * Plan 9\n * BSDs.\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/osext/osext.go",
    "content": "// Copyright 2012 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// Extensions to the standard \"os\" package.\npackage osext\n\nimport \"path/filepath\"\n\n// Executable returns an absolute path that can be used to\n// re-invoke the current program.\n// It may not be valid after the current program exits.\nfunc Executable() (string, error) {\n\tp, err := executable()\n\treturn filepath.Clean(p), err\n}\n\n// Returns same path as Executable, returns just the folder\n// path. Excludes the executable name and any trailing slash.\nfunc ExecutableFolder() (string, error) {\n\tp, err := Executable()\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\treturn filepath.Dir(p), nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/osext/osext_plan9.go",
    "content": "// Copyright 2012 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 osext\n\nimport (\n\t\"os\"\n\t\"strconv\"\n\t\"syscall\"\n)\n\nfunc executable() (string, error) {\n\tf, err := os.Open(\"/proc/\" + strconv.Itoa(os.Getpid()) + \"/text\")\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer f.Close()\n\treturn syscall.Fd2path(int(f.Fd()))\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/osext/osext_procfs.go",
    "content": "// Copyright 2012 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// +build linux netbsd openbsd solaris dragonfly\n\npackage osext\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strings\"\n)\n\nfunc executable() (string, error) {\n\tswitch runtime.GOOS {\n\tcase \"linux\":\n\t\tconst deletedTag = \" (deleted)\"\n\t\texecpath, err := os.Readlink(\"/proc/self/exe\")\n\t\tif err != nil {\n\t\t\treturn execpath, err\n\t\t}\n\t\texecpath = strings.TrimSuffix(execpath, deletedTag)\n\t\texecpath = strings.TrimPrefix(execpath, deletedTag)\n\t\treturn execpath, nil\n\tcase \"netbsd\":\n\t\treturn os.Readlink(\"/proc/curproc/exe\")\n\tcase \"openbsd\", \"dragonfly\":\n\t\treturn os.Readlink(\"/proc/curproc/file\")\n\tcase \"solaris\":\n\t\treturn os.Readlink(fmt.Sprintf(\"/proc/%d/path/a.out\", os.Getpid()))\n\t}\n\treturn \"\", errors.New(\"ExecPath not implemented for \" + runtime.GOOS)\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/osext/osext_sysctl.go",
    "content": "// Copyright 2012 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// +build darwin freebsd\n\npackage osext\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nvar initCwd, initCwdErr = os.Getwd()\n\nfunc executable() (string, error) {\n\tvar mib [4]int32\n\tswitch runtime.GOOS {\n\tcase \"freebsd\":\n\t\tmib = [4]int32{1 /* CTL_KERN */, 14 /* KERN_PROC */, 12 /* KERN_PROC_PATHNAME */, -1}\n\tcase \"darwin\":\n\t\tmib = [4]int32{1 /* CTL_KERN */, 38 /* KERN_PROCARGS */, int32(os.Getpid()), -1}\n\t}\n\n\tn := uintptr(0)\n\t// Get length.\n\t_, _, errNum := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)\n\tif errNum != 0 {\n\t\treturn \"\", errNum\n\t}\n\tif n == 0 { // This shouldn't happen.\n\t\treturn \"\", nil\n\t}\n\tbuf := make([]byte, n)\n\t_, _, errNum = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)\n\tif errNum != 0 {\n\t\treturn \"\", errNum\n\t}\n\tif n == 0 { // This shouldn't happen.\n\t\treturn \"\", nil\n\t}\n\tfor i, v := range buf {\n\t\tif v == 0 {\n\t\t\tbuf = buf[:i]\n\t\t\tbreak\n\t\t}\n\t}\n\tvar err error\n\texecPath := string(buf)\n\t// execPath will not be empty due to above checks.\n\t// Try to get the absolute path if the execPath is not rooted.\n\tif execPath[0] != '/' {\n\t\texecPath, err = getAbs(execPath)\n\t\tif err != nil {\n\t\t\treturn execPath, err\n\t\t}\n\t}\n\t// For darwin KERN_PROCARGS may return the path to a symlink rather than the\n\t// actual executable.\n\tif runtime.GOOS == \"darwin\" {\n\t\tif execPath, err = filepath.EvalSymlinks(execPath); err != nil {\n\t\t\treturn execPath, err\n\t\t}\n\t}\n\treturn execPath, nil\n}\n\nfunc getAbs(execPath string) (string, error) {\n\tif initCwdErr != nil {\n\t\treturn execPath, initCwdErr\n\t}\n\t// The execPath may begin with a \"../\" or a \"./\" so clean it first.\n\t// Join the two paths, trailing and starting slashes undetermined, so use\n\t// the generic Join function.\n\treturn filepath.Join(initCwd, filepath.Clean(execPath)), nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/internal/osext/osext_windows.go",
    "content": "// Copyright 2012 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 osext\n\nimport (\n\t\"syscall\"\n\t\"unicode/utf16\"\n\t\"unsafe\"\n)\n\nvar (\n\tkernel                = syscall.MustLoadDLL(\"kernel32.dll\")\n\tgetModuleFileNameProc = kernel.MustFindProc(\"GetModuleFileNameW\")\n)\n\n// GetModuleFileName() with hModule = NULL\nfunc executable() (exePath string, err error) {\n\treturn getModuleFileName()\n}\n\nfunc getModuleFileName() (string, error) {\n\tvar n uint32\n\tb := make([]uint16, syscall.MAX_PATH)\n\tsize := uint32(len(b))\n\n\tr0, _, e1 := getModuleFileNameProc.Call(0, uintptr(unsafe.Pointer(&b[0])), uintptr(size))\n\tn = uint32(r0)\n\tif n == 0 {\n\t\treturn \"\", e1\n\t}\n\treturn string(utf16.Decode(b[0:n])), nil\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/patcher.go",
    "content": "package update\n\nimport (\n\t\"io\"\n\n\t\"github.com/slimtoolkit/go-update/internal/binarydist\"\n)\n\n// Patcher defines an interface for applying binary patches to an old item to get an updated item.\ntype Patcher interface {\n\tPatch(old io.Reader, new io.Writer, patch io.Reader) error\n}\n\ntype patchFn func(io.Reader, io.Writer, io.Reader) error\n\nfunc (fn patchFn) Patch(old io.Reader, new io.Writer, patch io.Reader) error {\n\treturn fn(old, new, patch)\n}\n\n// NewBSDifferPatcher returns a new Patcher that applies binary patches using\n// the bsdiff algorithm. See http://www.daemonology.net/bsdiff/\nfunc NewBSDiffPatcher() Patcher {\n\treturn patchFn(binarydist.Patch)\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/go-update/verifier.go",
    "content": "package update\n\nimport (\n\t\"crypto\"\n\t\"crypto/dsa\"\n\t\"crypto/ecdsa\"\n\t\"crypto/rsa\"\n\t\"encoding/asn1\"\n\t\"errors\"\n\t\"math/big\"\n)\n\n// Verifier defines an interface for verfiying an update's signature with a public key.\ntype Verifier interface {\n\tVerifySignature(checksum, signature []byte, h crypto.Hash, publicKey crypto.PublicKey) error\n}\n\ntype verifyFn func([]byte, []byte, crypto.Hash, crypto.PublicKey) error\n\nfunc (fn verifyFn) VerifySignature(checksum []byte, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {\n\treturn fn(checksum, signature, hash, publicKey)\n}\n\n// NewRSAVerifier returns a Verifier that uses the RSA algorithm to verify updates.\nfunc NewRSAVerifier() Verifier {\n\treturn verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {\n\t\tkey, ok := publicKey.(*rsa.PublicKey)\n\t\tif !ok {\n\t\t\treturn errors.New(\"not a valid RSA public key\")\n\t\t}\n\t\treturn rsa.VerifyPKCS1v15(key, hash, checksum, signature)\n\t})\n}\n\ntype rsDER struct {\n\tR *big.Int\n\tS *big.Int\n}\n\n// NewECDSAVerifier returns a Verifier that uses the ECDSA algorithm to verify updates.\nfunc NewECDSAVerifier() Verifier {\n\treturn verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {\n\t\tkey, ok := publicKey.(*ecdsa.PublicKey)\n\t\tif !ok {\n\t\t\treturn errors.New(\"not a valid ECDSA public key\")\n\t\t}\n\t\tvar rs rsDER\n\t\tif _, err := asn1.Unmarshal(signature, &rs); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !ecdsa.Verify(key, checksum, rs.R, rs.S) {\n\t\t\treturn errors.New(\"failed to verify ecsda signature\")\n\t\t}\n\t\treturn nil\n\t})\n}\n\n// NewDSAVerifier returns a Verifier that uses the DSA algorithm to verify updates.\nfunc NewDSAVerifier() Verifier {\n\treturn verifyFn(func(checksum, signature []byte, hash crypto.Hash, publicKey crypto.PublicKey) error {\n\t\tkey, ok := publicKey.(*dsa.PublicKey)\n\t\tif !ok {\n\t\t\treturn errors.New(\"not a valid DSA public key\")\n\t\t}\n\t\tvar rs rsDER\n\t\tif _, err := asn1.Unmarshal(signature, &rs); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif !dsa.Verify(key, checksum, rs.R, rs.S) {\n\t\t\treturn errors.New(\"failed to verify ecsda signature\")\n\t\t}\n\t\treturn nil\n\t})\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/.travis.yml",
    "content": "language: go\nsudo: false\ninstall:\n  - go get ./...\ngo:\n  - 1.4\n  - tip\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/LICENSE",
    "content": "MIT License\n===========\n\nCopyright (c) 2015, Greg Osuri\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/Makefile",
    "content": "test:\n\t@go test -race .\n\nexamples:\n\t@go run -race ./example\n\n.PHONY: test examples\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/README.md",
    "content": "# uilive [![GoDoc](https://godoc.org/github.com/gosuri/uilive?status.svg)](https://godoc.org/github.com/gosuri/uilive) [![Build Status](https://travis-ci.org/gosuri/uilive.svg?branch=master)](https://travis-ci.org/gosuri/uilive)\n\nuilive is a go library for updating terminal output in realtime. It provides a buffered [io.Writer](https://golang.org/pkg/io/#Writer) that is flushed at a timed interval. uilive powers [uiprogress](https://github.com/gosuri/uiprogress).\n\n## Usage Example\n\nCalling `uilive.New()` will create a new writer. To start rendering, simply call `writer.Start()` and update the ui by writing to the `writer`. Full source for the below example is in [example/main.go](example/main.go).\n\n```go\nwriter := uilive.New()\n// start listening for updates and render\nwriter.Start()\n\nfor i := 0; i <= 100; i++ {\n  fmt.Fprintf(writer, \"Downloading.. (%d/%d) GB\\n\", i, 100)\n  time.Sleep(time.Millisecond * 5)\n}\n\nfmt.Fprintln(writer, \"Finished: Downloaded 100GB\")\nwriter.Stop() // flush and stop rendering\n```\n\nThe above will render\n\n![example](doc/example.gif)\n\n## Installation\n\n```sh\n$ go get -v github.com/gosuri/uilive\n```\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/doc.go",
    "content": "// Package uilive provides a writer that live updates the terminal. It provides a buffered io.Writer that is flushed at a timed interval.\npackage uilive\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/terminal_size.go",
    "content": "package uilive\n\nimport (\n\t\"os\"\n\t\"runtime\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\ntype windowSize struct {\n\trows    uint16\n\tcols    uint16\n\txPixels uint16\n\tyPixels uint16\n}\n\nvar out *os.File\nvar err error\nvar sz windowSize\n\nfunc getTermSize() (int, int) {\n\tif runtime.GOOS == \"openbsd\" {\n\t\tout, err = os.OpenFile(\"/dev/tty\", os.O_RDWR, 0)\n\t\tif err != nil {\n\t\t\tos.Exit(1)\n\t\t}\n\n\t} else {\n\t\tout, err = os.OpenFile(\"/dev/tty\", os.O_WRONLY, 0)\n\t\tif err != nil {\n\t\t\tos.Exit(1)\n\t\t}\n\t}\n\t_, _, _ = syscall.Syscall(syscall.SYS_IOCTL,\n\t\tout.Fd(), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&sz)))\n\treturn int(sz.cols), int(sz.rows)\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/writer.go",
    "content": "package uilive\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n)\n\n// ESC is the ASCII code for escape character\nconst ESC = 27\n\n// RefreshInterval is the default refresh interval to update the ui\nvar RefreshInterval = time.Millisecond\n\nvar overFlowHandled bool\n\nvar termWidth int\n\n// Out is the default output writer for the Writer\nvar Out = os.Stdout\n\n// ErrClosedPipe is the error returned when trying to writer is not listening\nvar ErrClosedPipe = errors.New(\"uilive: read/write on closed pipe\")\n\n// FdWriter is a writer with a file descriptor.\ntype FdWriter interface {\n\tio.Writer\n\tFd() uintptr\n}\n\n// Writer is a buffered the writer that updates the terminal. The contents of writer will be flushed on a timed interval or when Flush is called.\ntype Writer struct {\n\t// Out is the writer to write to\n\tOut io.Writer\n\n\t// RefreshInterval is the time the UI sould refresh\n\tRefreshInterval time.Duration\n\n\tticker *time.Ticker\n\ttdone  chan bool\n\n\tbuf       bytes.Buffer\n\tmtx       *sync.Mutex\n\tlineCount int\n}\n\ntype bypass struct {\n\twriter *Writer\n}\n\ntype newline struct {\n\twriter *Writer\n}\n\n// New returns a new Writer with defaults\nfunc New() *Writer {\n\ttermWidth, _ = getTermSize()\n\tif termWidth != 0 {\n\t\toverFlowHandled = true\n\t}\n\n\treturn &Writer{\n\t\tOut:             Out,\n\t\tRefreshInterval: RefreshInterval,\n\n\t\tmtx: &sync.Mutex{},\n\t}\n}\n\n// Flush writes to the out and resets the buffer. It should be called after the last call to Write to ensure that any data buffered in the Writer is written to output.\n// Any incomplete escape sequence at the end is considered complete for formatting purposes.\n// An error is returned if the contents of the buffer cannot be written to the underlying output stream\nfunc (w *Writer) Flush() error {\n\tw.mtx.Lock()\n\tdefer w.mtx.Unlock()\n\n\t// do nothing if buffer is empty\n\tif len(w.buf.Bytes()) == 0 {\n\t\treturn nil\n\t}\n\tw.clearLines()\n\n\tlines := 0\n\tvar currentLine bytes.Buffer\n\tfor _, b := range w.buf.Bytes() {\n\t\tif b == '\\n' {\n\t\t\tlines++\n\t\t\tcurrentLine.Reset()\n\t\t} else {\n\t\t\tcurrentLine.Write([]byte{b})\n\t\t\tif overFlowHandled && currentLine.Len() > termWidth {\n\t\t\t\tlines++\n\t\t\t\tcurrentLine.Reset()\n\t\t\t}\n\t\t}\n\t}\n\tw.lineCount = lines\n\t_, err := w.Out.Write(w.buf.Bytes())\n\tw.buf.Reset()\n\treturn err\n}\n\n// Start starts the listener in a non-blocking manner\nfunc (w *Writer) Start() {\n\tif w.ticker == nil {\n\t\tw.ticker = time.NewTicker(w.RefreshInterval)\n\t\tw.tdone = make(chan bool, 1)\n\t}\n\n\tgo w.Listen()\n}\n\n// Stop stops the listener that updates the terminal\nfunc (w *Writer) Stop() {\n\tw.Flush()\n\tclose(w.tdone)\n}\n\n// Listen listens for updates to the writer's buffer and flushes to the out provided. It blocks the runtime.\nfunc (w *Writer) Listen() {\n\tfor {\n\t\tselect {\n\t\tcase <-w.ticker.C:\n\t\t\tif w.ticker != nil {\n\t\t\t\tw.Flush()\n\t\t\t}\n\t\tcase <-w.tdone:\n\t\t\tw.mtx.Lock()\n\t\t\tw.ticker.Stop()\n\t\t\tw.ticker = nil\n\t\t\tw.mtx.Unlock()\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// Write save the contents of buf to the writer b. The only errors returned are ones encountered while writing to the underlying buffer.\nfunc (w *Writer) Write(buf []byte) (n int, err error) {\n\tw.mtx.Lock()\n\tdefer w.mtx.Unlock()\n\treturn w.buf.Write(buf)\n}\n\n// Bypass creates an io.Writer which allows non-buffered output to be written to the underlying output\nfunc (w *Writer) Bypass() io.Writer {\n\treturn &bypass{writer: w}\n}\n\nfunc (b *bypass) Write(p []byte) (int, error) {\n\tb.writer.mtx.Lock()\n\tdefer b.writer.mtx.Unlock()\n\n\tb.writer.clearLines()\n\tb.writer.lineCount = 0\n\treturn b.writer.Out.Write(p)\n}\n\n// Newline creates an io.Writer which allows buffered output to be written to the underlying output. This enable writing\n// to multiple lines at once.\nfunc (w *Writer) Newline() io.Writer {\n\treturn &newline{writer: w}\n}\n\nfunc (n *newline) Write(p []byte) (int, error) {\n\tn.writer.mtx.Lock()\n\tdefer n.writer.mtx.Unlock()\n\treturn n.writer.buf.Write(p)\n}"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/writer_posix.go",
    "content": "// +build !windows\n\npackage uilive\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// clear the line and move the cursor up\nvar clear = fmt.Sprintf(\"%c[%dA%c[2K\", ESC, 1, ESC)\n\nfunc (w *Writer) clearLines() {\n\t_, _ = fmt.Fprint(w.Out, strings.Repeat(clear, w.lineCount))\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uilive/writer_windows.go",
    "content": "// +build windows\n\npackage uilive\n\nimport (\n\t\"fmt\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nvar kernel32 = syscall.NewLazyDLL(\"kernel32.dll\")\n\nvar (\n\tprocGetConsoleScreenBufferInfo = kernel32.NewProc(\"GetConsoleScreenBufferInfo\")\n\tprocSetConsoleCursorPosition   = kernel32.NewProc(\"SetConsoleCursorPosition\")\n\tprocFillConsoleOutputCharacter = kernel32.NewProc(\"FillConsoleOutputCharacterW\")\n\tprocFillConsoleOutputAttribute = kernel32.NewProc(\"FillConsoleOutputAttribute\")\n)\n\n// clear the line and move the cursor up\nvar clear = fmt.Sprintf(\"%c[%dA%c[2K\", ESC, 1, ESC)\n\ntype short int16\ntype dword uint32\ntype word uint16\n\ntype coord struct {\n\tx short\n\ty short\n}\n\ntype smallRect struct {\n\tleft   short\n\ttop    short\n\tright  short\n\tbottom short\n}\n\ntype consoleScreenBufferInfo struct {\n\tsize              coord\n\tcursorPosition    coord\n\tattributes        word\n\twindow            smallRect\n\tmaximumWindowSize coord\n}\n\nfunc (w *Writer) clearLines() {\n\tf, ok := w.Out.(FdWriter)\n\tif ok && !isatty.IsTerminal(f.Fd()) {\n\t\tok = false\n\t}\n\tif !ok {\n\t\t_, _ = fmt.Fprint(w.Out, strings.Repeat(clear, w.lineCount))\n\t\treturn\n\t}\n\tfd := f.Fd()\n\tvar csbi consoleScreenBufferInfo\n\tprocGetConsoleScreenBufferInfo.Call(fd, uintptr(unsafe.Pointer(&csbi)))\n\n\tfor i := 0; i < w.lineCount; i++ {\n\t\t// move the cursor up\n\t\tcsbi.cursorPosition.y--\n\t\tprocSetConsoleCursorPosition.Call(fd, uintptr(*(*int32)(unsafe.Pointer(&csbi.cursorPosition))))\n\t\t// clear the line\n\t\tcursor := coord{\n\t\t\tx: csbi.window.left,\n\t\t\ty: csbi.window.top + csbi.cursorPosition.y,\n\t\t}\n\t\tvar count, w dword\n\t\tcount = dword(csbi.size.x)\n\t\tprocFillConsoleOutputCharacter.Call(fd, uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&w)))\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/.gitignore",
    "content": ".DS_Store\n/bin/\n/_gopath/\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/.travis.yml",
    "content": "language: go\nsudo: false\ninstall:\n  - go get ./...\ngo:\n  - 1.4\n  - tip\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/LICENSE",
    "content": "MIT License\n===========\n\nCopyright (c) 2015, Greg Osuri\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/Makefile",
    "content": "test:\n\t@go test -race .\n\t@go test -race ./util/strutil\n\nexamples:\n\tgo run -race example/full/full.go\n\tgo run -race example/incr/incr.go\n\tgo run -race example/multi/multi.go\n\tgo run -race example/simple/simple.go\n\n.PHONY: test examples\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/README.md",
    "content": "# uiprogress [![GoDoc](https://godoc.org/github.com/docker-slim/uiprogress?status.svg)](https://godoc.org/github.com/docker-slim/uiprogress) [![Build Status](https://travis-ci.org/docker-slim/uiprogress.svg?branch=master)](https://travis-ci.org/docker-slim/uiprogress)\n\n## Note\n\nFixing the os.Exit problem in its dependency and a few other things...\n\nEnhancements:\n* No default progress bar\n\n## Original Package Info\n\nA Go library to render progress bars in terminal applications. It provides a set of flexible features with a customizable API.\n\n![example](doc/example_full.gif)\n\nProgress bars improve readability for terminal applications with long outputs by providing a concise feedback loop.\n\n### Features\n\n* __Multiple Bars__: uiprogress can render multiple progress bars that can be tracked concurrently\n* __Dynamic Addition__:  Add additional progress bars any time, even after the progress tracking has started\n* __Prepend and Append Functions__: Append or prepend completion percent and time elapsed to the progress bars\n* __Custom Decorator Functions__: Add custom functions around the bar along with helper functions\n\n### Usage\n\nTo start listening for progress bars, call `uiprogress.Start()` and add a progress bar using `uiprogress.AddBar(total int)`. Update the progress using `bar.Incr()` or `bar.Set(n int)`. Full source code for the below example is available at [example/simple/simple.go](example/simple/simple.go) \n\n```go\nuiprogress.Start()            // start rendering\nbar := uiprogress.AddBar(100) // Add a new bar\n\n// optionally, append and prepend completion and elapsed time\nbar.AppendCompleted()\nbar.PrependElapsed()\n\nfor bar.Incr() {\n  time.Sleep(time.Millisecond * 20)\n}\n```\n\nThis will render the below in the terminal\n\n![example](doc/example_simple.gif)\n\n#### Using Custom Decorators\n\nYou can also add a custom decorator function in addition to default `bar.AppendCompleted()` and `bar.PrependElapsed()` decorators. The below example tracks the current step for an application deploy progress. Source code for the below example is available at [example/full/full.go](example/full/full.go) \n\n```go\nvar steps = []string{\"downloading source\", \"installing deps\", \"compiling\", \"packaging\", \"seeding database\", \"deploying\", \"staring servers\"}\nbar := uiprogress.AddBar(len(steps))\n\n// prepend the current step to the bar\nbar.PrependFunc(func(b *uiprogress.Bar) string {\n  return \"app: \" + steps[b.Current()-1]\n})\n\nfor bar.Incr() {\n  time.Sleep(time.Millisecond * 10)\n}\n```\n\n#### Rendering Multiple bars\n\nYou can add multiple bars using `uiprogress.AddBar(n)`. The below example demonstrates updating multiple bars concurrently and adding a new bar later in the pipeline. Source for this example is available at [example/multi/multi.go](example/multi/multi.go) \n\n```go\nwaitTime := time.Millisecond * 100\nuiprogress.Start()\n\n// start the progress bars in go routines\nvar wg sync.WaitGroup\n\nbar1 := uiprogress.AddBar(20).AppendCompleted().PrependElapsed()\nwg.Add(1)\ngo func() {\n  defer wg.Done()\n  for bar1.Incr() {\n    time.Sleep(waitTime)\n  }\n}()\n\nbar2 := uiprogress.AddBar(40).AppendCompleted().PrependElapsed()\nwg.Add(1)\ngo func() {\n  defer wg.Done()\n  for bar2.Incr() {\n    time.Sleep(waitTime)\n  }\n}()\n\ntime.Sleep(time.Second)\nbar3 := uiprogress.AddBar(20).PrependElapsed().AppendCompleted()\nwg.Add(1)\ngo func() {\n  defer wg.Done()\n  for i := 1; i <= bar3.Total; i++ {\n    bar3.Set(i)\n    time.Sleep(waitTime)\n  }\n}()\n\n// wait for all the go routines to finish\nwg.Wait()\n```\n\nThis will produce\n\n![example](doc/example_multi.gif)\n\n#### `Incr` counter\n\n[Bar.Incr()](https://godoc.org/github.com/docker-slim/uiprogress#Bar.Incr) is an atomic counter and can be used as a general tracker, making it ideal for tracking progress of work fanned out to a lots of go routines. The source code for the below example is available at [example/incr/incr.go](example/incr/incr.go)\n\n```go\nruntime.GOMAXPROCS(runtime.NumCPU()) // use all available cpu cores\n\n// create a new bar and prepend the task progress to the bar and fanout into 1k go routines\ncount := 1000\nbar := uiprogress.AddBar(count).AppendCompleted().PrependElapsed()\nbar.PrependFunc(func(b *uiprogress.Bar) string {\n  return fmt.Sprintf(\"Task (%d/%d)\", b.Current(), count)\n})\n\nuiprogress.Start()\nvar wg sync.WaitGroup\n\n// fanout into go routines\nfor i := 0; i < count; i++ {\n  wg.Add(1)\n  go func() {\n    defer wg.Done()\n    time.Sleep(time.Millisecond * time.Duration(rand.Intn(500)))\n    bar.Incr()\n  }()\n}\ntime.Sleep(time.Second) // wait for a second for all the go routines to finish\nwg.Wait()\nuiprogress.Stop()\n```\n\n### Installation\n\n```sh\n$ go get -v github.com/docker-slim/uiprogress\n```\n### Todos\n\n- [ ] Resize bars and decorators by auto detecting window's dimensions\n- [ ] Handle more progress bars than vertical screen allows\n\n### License\n\nuiprogress is released under the MIT License. See [LICENSE](https://github.com/docker-slim/uiprogress/blob/master/LICENSE).\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/bar.go",
    "content": "package uiprogress\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/uiprogress/util/strutil\"\n)\n\nvar (\n\t// Fill is the default character representing completed progress\n\tFill byte = '='\n\n\t// Head is the default character that moves when progress is updated\n\tHead byte = '>'\n\n\t// Empty is the default character that represents the empty progress\n\tEmpty byte = '-'\n\n\t// LeftEnd is the default character in the left most part of the progress indicator\n\tLeftEnd byte = '['\n\n\t// RightEnd is the default character in the right most part of the progress indicator\n\tRightEnd byte = ']'\n\n\t// Width is the default width of the progress bar\n\tWidth = 70\n\n\t// ErrMaxCurrentReached is error when trying to set current value that exceeds the total value\n\tErrMaxCurrentReached = errors.New(\"errors: current value is greater total value\")\n)\n\n// Bar represents a progress bar\ntype Bar struct {\n\t// Total of the total  for the progress bar\n\tTotal int\n\n\t// LeftEnd is character in the left most part of the progress indicator. Defaults to '['\n\tLeftEnd byte\n\n\t// RightEnd is character in the right most part of the progress indicator. Defaults to ']'\n\tRightEnd byte\n\n\t// Fill is the character representing completed progress. Defaults to '='\n\tFill byte\n\n\t// Head is the character that moves when progress is updated.  Defaults to '>'\n\tHead byte\n\n\t// Empty is the character that represents the empty progress. Default is '-'\n\tEmpty byte\n\n\t// TimeStated is time progress began\n\tTimeStarted time.Time\n\n\t// Width is the width of the progress bar\n\tWidth int\n\n\t// timeElased is the time elapsed for the progress\n\ttimeElapsed time.Duration\n\tcurrent     int\n\n\tmtx *sync.RWMutex\n\n\tappendFuncs  []DecoratorFunc\n\tprependFuncs []DecoratorFunc\n}\n\n// DecoratorFunc is a function that can be prepended and appended to the progress bar\ntype DecoratorFunc func(b *Bar) string\n\n// NewBar returns a new progress bar\nfunc NewBar(total int) *Bar {\n\treturn &Bar{\n\t\tTotal:    total,\n\t\tWidth:    Width,\n\t\tLeftEnd:  LeftEnd,\n\t\tRightEnd: RightEnd,\n\t\tHead:     Head,\n\t\tFill:     Fill,\n\t\tEmpty:    Empty,\n\n\t\tmtx: &sync.RWMutex{},\n\t}\n}\n\n// Set the current count of the bar. It returns ErrMaxCurrentReached when trying n exceeds the total value. This is atomic operation and concurancy safe.\nfunc (b *Bar) Set(n int) error {\n\tb.mtx.Lock()\n\tdefer b.mtx.Unlock()\n\n\tif n > b.Total {\n\t\treturn ErrMaxCurrentReached\n\t}\n\tb.current = n\n\treturn nil\n}\n\n// Incr increments the current value by 1, time elapsed to current time and returns true. It returns false if the cursor has reached or exceeds total value.\nfunc (b *Bar) Incr() bool {\n\tb.mtx.Lock()\n\tdefer b.mtx.Unlock()\n\n\tn := b.current + 1\n\tif n > b.Total {\n\t\treturn false\n\t}\n\tvar t time.Time\n\tif b.TimeStarted == t {\n\t\tb.TimeStarted = time.Now()\n\t}\n\tb.timeElapsed = time.Since(b.TimeStarted)\n\tb.current = n\n\treturn true\n}\n\n// Current returns the current progress of the bar\nfunc (b *Bar) Current() int {\n\tb.mtx.RLock()\n\tdefer b.mtx.RUnlock()\n\treturn b.current\n}\n\n// AppendFunc runs the decorator function and renders the output on the right of the progress bar\nfunc (b *Bar) AppendFunc(f DecoratorFunc) *Bar {\n\tb.mtx.Lock()\n\tdefer b.mtx.Unlock()\n\tb.appendFuncs = append(b.appendFuncs, f)\n\treturn b\n}\n\n// AppendCompleted appends the completion percent to the progress bar\nfunc (b *Bar) AppendCompleted() *Bar {\n\tb.AppendFunc(func(b *Bar) string {\n\t\treturn b.CompletedPercentString()\n\t})\n\treturn b\n}\n\n// AppendElapsed appends the time elapsed the be progress bar\nfunc (b *Bar) AppendElapsed() *Bar {\n\tb.AppendFunc(func(b *Bar) string {\n\t\treturn strutil.PadLeft(b.TimeElapsedString(), 5, ' ')\n\t})\n\treturn b\n}\n\n// PrependFunc runs decorator function and render the output left the progress bar\nfunc (b *Bar) PrependFunc(f DecoratorFunc) *Bar {\n\tb.mtx.Lock()\n\tdefer b.mtx.Unlock()\n\tb.prependFuncs = append(b.prependFuncs, f)\n\treturn b\n}\n\n// PrependCompleted prepends the precent completed to the progress bar\nfunc (b *Bar) PrependCompleted() *Bar {\n\tb.PrependFunc(func(b *Bar) string {\n\t\treturn b.CompletedPercentString()\n\t})\n\treturn b\n}\n\n// PrependElapsed prepends the time elapsed to the begining of the bar\nfunc (b *Bar) PrependElapsed() *Bar {\n\tb.PrependFunc(func(b *Bar) string {\n\t\treturn strutil.PadLeft(b.TimeElapsedString(), 5, ' ')\n\t})\n\treturn b\n}\n\n// Bytes returns the byte presentation of the progress bar\nfunc (b *Bar) Bytes() []byte {\n\tcompletedWidth := int(float64(b.Width) * (b.CompletedPercent() / 100.00))\n\n\t// add fill and empty bits\n\tvar buf bytes.Buffer\n\tfor i := 0; i < completedWidth; i++ {\n\t\tbuf.WriteByte(b.Fill)\n\t}\n\tfor i := 0; i < b.Width-completedWidth; i++ {\n\t\tbuf.WriteByte(b.Empty)\n\t}\n\n\t// set head bit\n\tpb := buf.Bytes()\n\tif completedWidth > 0 && completedWidth < b.Width {\n\t\tpb[completedWidth-1] = b.Head\n\t}\n\n\t// set left and right ends bits\n\tpb[0], pb[len(pb)-1] = b.LeftEnd, b.RightEnd\n\n\t// render append functions to the right of the bar\n\tfor _, f := range b.appendFuncs {\n\t\tpb = append(pb, ' ')\n\t\tpb = append(pb, []byte(f(b))...)\n\t}\n\n\t// render prepend functions to the left of the bar\n\tfor _, f := range b.prependFuncs {\n\t\targs := []byte(f(b))\n\t\targs = append(args, ' ')\n\t\tpb = append(args, pb...)\n\t}\n\treturn pb\n}\n\n// String returns the string representation of the bar\nfunc (b *Bar) String() string {\n\treturn string(b.Bytes())\n}\n\n// CompletedPercent return the percent completed\nfunc (b *Bar) CompletedPercent() float64 {\n\treturn (float64(b.Current()) / float64(b.Total)) * 100.00\n}\n\n// CompletedPercentString returns the formatted string representation of the completed percent\nfunc (b *Bar) CompletedPercentString() string {\n\treturn fmt.Sprintf(\"%3.f%%\", b.CompletedPercent())\n}\n\n// TimeElapsed returns the time elapsed\nfunc (b *Bar) TimeElapsed() time.Duration {\n\tb.mtx.RLock()\n\tdefer b.mtx.RUnlock()\n\treturn b.timeElapsed\n}\n\n// TimeElapsedString returns the formatted string represenation of the time elapsed\nfunc (b *Bar) TimeElapsedString() string {\n\treturn strutil.PrettyTime(b.TimeElapsed())\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/doc.go",
    "content": "// Package uiprogress is a library to render progress bars in terminal applications\npackage uiprogress\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/progress.go",
    "content": "package uiprogress\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/slimtoolkit/uilive\"\n)\n\n// Out is the default writer to render progress bars to\nvar Out = os.Stdout\n\n// RefreshInterval in the default time duration to wait for refreshing the output\nvar RefreshInterval = time.Millisecond * 10\n\n// defaultProgress is the default progress <- removing\n//var defaultProgress = New()\n\n// Progress represents the container that renders progress bars\ntype Progress struct {\n\t// Out is the writer to render progress bars to\n\tOut io.Writer\n\n\t// Width is the width of the progress bars\n\tWidth int\n\n\t// Bars is the collection of progress bars\n\tBars []*Bar\n\n\t// RefreshInterval in the time duration to wait for refreshing the output\n\tRefreshInterval time.Duration\n\n\tlw     *uilive.Writer\n\tticker *time.Ticker\n\ttdone  chan bool\n\tmtx    *sync.RWMutex\n}\n\n// New returns a new progress bar with defaults\nfunc New() *Progress {\n\tlw := uilive.New()\n\tif lw == nil {\n\t\treturn nil\n\t}\n\t\n\tlw.Out = Out\n\n\treturn &Progress{\n\t\tWidth:           Width,\n\t\tOut:             Out,\n\t\tBars:            make([]*Bar, 0),\n\t\tRefreshInterval: RefreshInterval,\n\n\t\ttdone: make(chan bool),\n\t\tlw:    uilive.New(),\n\t\tmtx:   &sync.RWMutex{},\n\t}\n}\n\n//removing...\n// AddBar creates a new progress bar and adds it to the default progress container\n//func AddBar(total int) *Bar {\n//\treturn defaultProgress.AddBar(total)\n//}\n\n//removing...\n// Start starts the rendering the progress of progress bars using the DefaultProgress. It listens for updates using `bar.Set(n)` and new bars when added using `AddBar`\n//func Start() {\n//\tdefaultProgress.Start()\n//}\n\n//removing...\n// Stop stops listening\n//func Stop() {\n//\tdefaultProgress.Stop()\n//}\n\n//removing...\n// Listen listens for updates and renders the progress bars\n//func Listen() {\n//\tdefaultProgress.Listen()\n//}\n\nfunc (p *Progress) SetOut(o io.Writer) {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tp.Out = o\n\tp.lw.Out = o\n}\n\nfunc (p *Progress) SetRefreshInterval(interval time.Duration) {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\tp.RefreshInterval = interval\n}\n\n// AddBar creates a new progress bar and adds to the container\nfunc (p *Progress) AddBar(total int) *Bar {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tbar := NewBar(total)\n\tbar.Width = p.Width\n\tp.Bars = append(p.Bars, bar)\n\treturn bar\n}\n\n// Listen listens for updates and renders the progress bars\nfunc (p *Progress) Listen() {\n\tfor {\n\n\t\tp.mtx.Lock()\n\t\tinterval := p.RefreshInterval\n\t\tp.mtx.Unlock()\n\n\t\tselect {\n\t\tcase <-time.After(interval):\n\t\t\tp.print()\n\t\tcase <-p.tdone:\n\t\t\tp.print()\n\t\t\tclose(p.tdone)\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (p *Progress) print() {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\tfor _, bar := range p.Bars {\n\t\tfmt.Fprintln(p.lw, bar.String())\n\t}\n\tp.lw.Flush()\n}\n\n// Start starts the rendering the progress of progress bars. It listens for updates using `bar.Set(n)` and new bars when added using `AddBar`\nfunc (p *Progress) Start() {\n\tgo p.Listen()\n}\n\n// Stop stops listening\nfunc (p *Progress) Stop() {\n\tp.tdone <- true\n\t<-p.tdone\n}\n\n// Bypass returns a writer which allows non-buffered data to be written to the underlying output\nfunc (p *Progress) Bypass() io.Writer {\n\treturn p.lw.Bypass()\n}\n"
  },
  {
    "path": "vendor/github.com/slimtoolkit/uiprogress/util/strutil/strutil.go",
    "content": "// Package strutil provides various utilities for manipulating strings\npackage strutil\n\nimport (\n\t\"bytes\"\n\t\"time\"\n)\n\n// PadRight returns a new string of a specified length in which the end of the current string is padded with spaces or with a specified Unicode character.\nfunc PadRight(str string, length int, pad byte) string {\n\tif len(str) >= length {\n\t\treturn str\n\t}\n\tbuf := bytes.NewBufferString(str)\n\tfor i := 0; i < length-len(str); i++ {\n\t\tbuf.WriteByte(pad)\n\t}\n\treturn buf.String()\n}\n\n// PadLeft returns a new string of a specified length in which the beginning of the current string is padded with spaces or with a specified Unicode character.\nfunc PadLeft(str string, length int, pad byte) string {\n\tif len(str) >= length {\n\t\treturn str\n\t}\n\tvar buf bytes.Buffer\n\tfor i := 0; i < length-len(str); i++ {\n\t\tbuf.WriteByte(pad)\n\t}\n\tbuf.WriteString(str)\n\treturn buf.String()\n}\n\n// Resize resizes the string with the given length. It ellipses with '...' when the string's length exceeds\n// the desired length or pads spaces to the right of the string when length is smaller than desired\nfunc Resize(s string, length uint) string {\n\tn := int(length)\n\tif len(s) == n {\n\t\treturn s\n\t}\n\t// Pads only when length of the string smaller than len needed\n\ts = PadRight(s, n, ' ')\n\tif len(s) > n {\n\t\tb := []byte(s)\n\t\tvar buf bytes.Buffer\n\t\tfor i := 0; i < n-3; i++ {\n\t\t\tbuf.WriteByte(b[i])\n\t\t}\n\t\tbuf.WriteString(\"...\")\n\t\ts = buf.String()\n\t}\n\treturn s\n}\n\n// PrettyTime returns the string representation of the duration. It rounds the time duration to a second and returns a \"---\" when duration is 0\nfunc PrettyTime(t time.Duration) string {\n\tif t == 0 {\n\t\treturn \"---\"\n\t}\n\treturn (t - (t % time.Second)).String()\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/.gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n# Vim files https://github.com/github/gitignore/blob/master/Global/Vim.gitignore\n# swap\n[._]*.s[a-w][a-z]\n[._]s[a-w][a-z]\n# session\nSession.vim\n# temporary\n.netrwhist\n*~\n# auto-generated tag files\ntags\n\n*.exe\ncobra.test\nbin\n\n.idea/\n*.iml\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/.golangci.yml",
    "content": "# Copyright 2013-2023 The Cobra Authors\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#      http://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\nrun:\n  deadline: 5m\n\nlinters:\n  disable-all: true\n  enable:\n    #- bodyclose\n    - deadcode\n    #- depguard\n    #- dogsled\n    #- dupl\n    - errcheck\n    #- exhaustive\n    #- funlen\n    - gas\n    #- gochecknoinits\n    - goconst\n    #- gocritic\n    #- gocyclo\n    #- gofmt\n    - goimports\n    - golint\n    #- gomnd\n    #- goprintffuncname\n    #- gosec\n    #- gosimple\n    - govet\n    - ineffassign\n    - interfacer\n    #- lll\n    - maligned\n    - megacheck\n    #- misspell\n    #- nakedret\n    #- noctx\n    #- nolintlint\n    #- rowserrcheck\n    #- scopelint\n    #- staticcheck\n    - structcheck\n    #- stylecheck\n    #- typecheck\n    - unconvert\n    #- unparam\n    #- unused\n    - varcheck\n    #- whitespace\n  fast: false\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/.mailmap",
    "content": "Steve Francia <steve.francia@gmail.com>\nBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>\nFabiano Franz <ffranz@redhat.com>                   <contact@fabianofranz.com>\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/CONDUCT.md",
    "content": "## Cobra User Contract\n\n### Versioning\nCobra will follow a steady release cadence. Non breaking changes will be released as minor versions quarterly. Patch bug releases are at the discretion of the maintainers. Users can expect security patch fixes to be released within relatively short order of a CVE becoming known. For more information on security patch fixes see the CVE section below. Releases will follow [Semantic Versioning](https://semver.org/). Users tracking the Master branch should expect unpredictable breaking changes as the project continues to move forward. For stability, it is highly recommended to use a release.\n\n### Backward Compatibility\nWe will maintain two major releases in a moving window. The N-1 release will only receive bug fixes and security updates and will be dropped once N+1 is released.\n\n### Deprecation\nDeprecation of Go versions or dependent packages will only occur in major releases. To reduce the change of this taking users by surprise, any large deprecation will be preceded by an announcement in the [#cobra slack channel](https://gophers.slack.com/archives/CD3LP1199) and an Issue on Github.\n\n### CVE\nMaintainers will make every effort to release security patches in the case of a medium to high severity CVE directly impacting the library. The speed in which these patches reach a release is up to the discretion of the maintainers. A low severity CVE may be a lower priority than a high severity one.\n\n### Communication\nCobra maintainers will use GitHub issues and the [#cobra slack channel](https://gophers.slack.com/archives/CD3LP1199) as the primary means of communication with the community. This is to foster open communication with all users and contributors.\n\n### Breaking Changes\nBreaking changes are generally allowed in the master branch, as this is the branch used to develop the next release of Cobra.\n\nThere may be times, however, when master is closed for breaking changes. This is likely to happen as we near the release of a new version.\n\nBreaking changes are not allowed in release branches, as these represent minor versions that have already been released. These version have consumers who expect the APIs, behaviors, etc, to remain stable during the lifetime of the patch stream for the minor release.\n\nExamples of breaking changes include:\n- Removing or renaming exported constant, variable, type, or function.\n- Updating the version of critical libraries such as `spf13/pflag`, `spf13/viper` etc...\n  - Some version updates may be acceptable for picking up bug fixes, but maintainers must exercise caution when reviewing.\n\nThere may, at times, need to be exceptions where breaking changes are allowed in release branches. These are at the discretion of the project's maintainers, and must be carefully considered before merging.\n\n### CI Testing\nMaintainers will ensure the Cobra test suite utilizes the current supported versions of Golang.\n\n### Disclaimer\nChanges to this document and the contents therein are at the discretion of the maintainers.\nNone of the contents of this document are legally binding in any way to the maintainers or the users.\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/CONTRIBUTING.md",
    "content": "# Contributing to Cobra\n\nThank you so much for contributing to Cobra. We appreciate your time and help.\nHere are some guidelines to help you get started.\n\n## Code of Conduct\n\nBe kind and respectful to the members of the community. Take time to educate\nothers who are seeking help. Harassment of any kind will not be tolerated.\n\n## Questions\n\nIf you have questions regarding Cobra, feel free to ask it in the community\n[#cobra Slack channel][cobra-slack]\n\n## Filing a bug or feature\n\n1. Before filing an issue, please check the existing issues to see if a\n   similar one was already opened. If there is one already opened, feel free\n   to comment on it.\n1. If you believe you've found a bug, please provide detailed steps of\n   reproduction, the version of Cobra and anything else you believe will be\n   useful to help troubleshoot it (e.g. OS environment, environment variables,\n   etc...). Also state the current behavior vs. the expected behavior.\n1. If you'd like to see a feature or an enhancement please open an issue with\n   a clear title and description of what the feature is and why it would be\n   beneficial to the project and its users.\n\n## Submitting changes\n\n1. CLA: Upon submitting a Pull Request (PR), contributors will be prompted to\n   sign a CLA. Please sign the CLA :slightly_smiling_face:\n1. Tests: If you are submitting code, please ensure you have adequate tests\n   for the feature. Tests can be run via `go test ./...` or `make test`.\n1. Since this is golang project, ensure the new code is properly formatted to\n   ensure code consistency. Run `make all`.\n\n### Quick steps to contribute\n\n1. Fork the project.\n1. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)\n1. Create your feature branch (`git checkout -b my-new-feature`)\n1. Make changes and run tests (`make test`)\n1. Add them to staging (`git add .`)\n1. Commit your changes (`git commit -m 'Add some feature'`)\n1. Push to the branch (`git push origin my-new-feature`)\n1. Create new pull request\n\n<!-- Links -->\n[cobra-slack]: https://gophers.slack.com/archives/CD3LP1199\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/LICENSE.txt",
    "content": "                                Apache License\n                           Version 2.0, January 2004\n                        http://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"
  },
  {
    "path": "vendor/github.com/spf13/cobra/MAINTAINERS",
    "content": "maintainers:\n- spf13\n- johnSchnake\n- jpmcb\n- marckhouzam\ninactive:\n- anthonyfok\n- bep\n- bogem\n- broady\n- eparis\n- jharshman\n- wfernandes\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/Makefile",
    "content": "BIN=\"./bin\"\nSRC=$(shell find . -name \"*.go\")\n\nifeq (, $(shell which golangci-lint))\n$(warning \"could not find golangci-lint in $(PATH), run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh\")\nendif\n\n.PHONY: fmt lint test install_deps clean\n\ndefault: all\n\nall: fmt test\n\nfmt:\n\t$(info ******************** checking formatting ********************)\n\t@test -z $(shell gofmt -l $(SRC)) || (gofmt -d $(SRC); exit 1)\n\nlint:\n\t$(info ******************** running lint tools ********************)\n\tgolangci-lint run -v\n\ntest: install_deps\n\t$(info ******************** running tests ********************)\n\tgo test -v ./...\n\nrichtest: install_deps\n\t$(info ******************** running tests with kyoh86/richgo ********************)\n\trichgo test -v ./...\n\ninstall_deps:\n\t$(info ******************** downloading dependencies ********************)\n\tgo get -v ./...\n\nclean:\n\trm -rf $(BIN)\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/README.md",
    "content": "![cobra logo](assets/CobraMain.png)\n\nCobra is a library for creating powerful modern CLI applications.\n\nCobra is used in many Go projects such as [Kubernetes](https://kubernetes.io/),\n[Hugo](https://gohugo.io), and [GitHub CLI](https://github.com/cli/cli) to\nname a few. [This list](./projects_using_cobra.md) contains a more extensive list of projects using Cobra.\n\n[![](https://img.shields.io/github/actions/workflow/status/spf13/cobra/test.yml?branch=main&longCache=true&label=Test&logo=github%20actions&logoColor=fff)](https://github.com/spf13/cobra/actions?query=workflow%3ATest)\n[![Go Reference](https://pkg.go.dev/badge/github.com/spf13/cobra.svg)](https://pkg.go.dev/github.com/spf13/cobra)\n[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/cobra)](https://goreportcard.com/report/github.com/spf13/cobra)\n[![Slack](https://img.shields.io/badge/Slack-cobra-brightgreen)](https://gophers.slack.com/archives/CD3LP1199)\n\n# Overview\n\nCobra is a library providing a simple interface to create powerful modern CLI\ninterfaces similar to git & go tools.\n\nCobra provides:\n* Easy subcommand-based CLIs: `app server`, `app fetch`, etc.\n* Fully POSIX-compliant flags (including short & long versions)\n* Nested subcommands\n* Global, local and cascading flags\n* Intelligent suggestions (`app srver`... did you mean `app server`?)\n* Automatic help generation for commands and flags\n* Grouping help for subcommands\n* Automatic help flag recognition of `-h`, `--help`, etc.\n* Automatically generated shell autocomplete for your application (bash, zsh, fish, powershell)\n* Automatically generated man pages for your application\n* Command aliases so you can change things without breaking them\n* The flexibility to define your own help, usage, etc.\n* Optional seamless integration with [viper](https://github.com/spf13/viper) for 12-factor apps\n\n# Concepts\n\nCobra is built on a structure of commands, arguments & flags.\n\n**Commands** represent actions, **Args** are things and **Flags** are modifiers for those actions.\n\nThe best applications read like sentences when used, and as a result, users\nintuitively know how to interact with them.\n\nThe pattern to follow is\n`APPNAME VERB NOUN --ADJECTIVE`\n    or\n`APPNAME COMMAND ARG --FLAG`.\n\nA few good real world examples may better illustrate this point.\n\nIn the following example, 'server' is a command, and 'port' is a flag:\n\n    hugo server --port=1313\n\nIn this command we are telling Git to clone the url bare.\n\n    git clone URL --bare\n\n## Commands\n\nCommand is the central point of the application. Each interaction that\nthe application supports will be contained in a Command. A command can\nhave children commands and optionally run an action.\n\nIn the example above, 'server' is the command.\n\n[More about cobra.Command](https://pkg.go.dev/github.com/spf13/cobra#Command)\n\n## Flags\n\nA flag is a way to modify the behavior of a command. Cobra supports\nfully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).\nA Cobra command can define flags that persist through to children commands\nand flags that are only available to that command.\n\nIn the example above, 'port' is the flag.\n\nFlag functionality is provided by the [pflag\nlibrary](https://github.com/spf13/pflag), a fork of the flag standard library\nwhich maintains the same interface while adding POSIX compliance.\n\n# Installing\nUsing Cobra is easy. First, use `go get` to install the latest version\nof the library.     \n\n```\ngo get -u github.com/spf13/cobra@latest\n```\n\nNext, include Cobra in your application:\n\n```go\nimport \"github.com/spf13/cobra\"\n```\n\n# Usage\n`cobra-cli` is a command line program to generate cobra applications and command files.\nIt will bootstrap your application scaffolding to rapidly\ndevelop a Cobra-based application. It is the easiest way to incorporate Cobra into your application.\n\nIt can be installed by running:\n\n```\ngo install github.com/spf13/cobra-cli@latest\n```\n\nFor complete details on using the Cobra-CLI generator, please read [The Cobra Generator README](https://github.com/spf13/cobra-cli/blob/main/README.md)\n\nFor complete details on using the Cobra library, please read the [The Cobra User Guide](user_guide.md).\n\n# License\n\nCobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/active_help.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n)\n\nconst (\n\tactiveHelpMarker = \"_activeHelp_ \"\n\t// The below values should not be changed: programs will be using them explicitly\n\t// in their user documentation, and users will be using them explicitly.\n\tactiveHelpEnvVarSuffix  = \"_ACTIVE_HELP\"\n\tactiveHelpGlobalEnvVar  = \"COBRA_ACTIVE_HELP\"\n\tactiveHelpGlobalDisable = \"0\"\n)\n\n// AppendActiveHelp adds the specified string to the specified array to be used as ActiveHelp.\n// Such strings will be processed by the completion script and will be shown as ActiveHelp\n// to the user.\n// The array parameter should be the array that will contain the completions.\n// This function can be called multiple times before and/or after completions are added to\n// the array.  Each time this function is called with the same array, the new\n// ActiveHelp line will be shown below the previous ones when completion is triggered.\nfunc AppendActiveHelp(compArray []string, activeHelpStr string) []string {\n\treturn append(compArray, fmt.Sprintf(\"%s%s\", activeHelpMarker, activeHelpStr))\n}\n\n// GetActiveHelpConfig returns the value of the ActiveHelp environment variable\n// <PROGRAM>_ACTIVE_HELP where <PROGRAM> is the name of the root command in upper\n// case, with all - replaced by _.\n// It will always return \"0\" if the global environment variable COBRA_ACTIVE_HELP\n// is set to \"0\".\nfunc GetActiveHelpConfig(cmd *Command) string {\n\tactiveHelpCfg := os.Getenv(activeHelpGlobalEnvVar)\n\tif activeHelpCfg != activeHelpGlobalDisable {\n\t\tactiveHelpCfg = os.Getenv(activeHelpEnvVar(cmd.Root().Name()))\n\t}\n\treturn activeHelpCfg\n}\n\n// activeHelpEnvVar returns the name of the program-specific ActiveHelp environment\n// variable.  It has the format <PROGRAM>_ACTIVE_HELP where <PROGRAM> is the name of the\n// root command in upper case, with all - replaced by _.\nfunc activeHelpEnvVar(name string) string {\n\t// This format should not be changed: users will be using it explicitly.\n\tactiveHelpEnvVar := strings.ToUpper(fmt.Sprintf(\"%s%s\", name, activeHelpEnvVarSuffix))\n\treturn strings.ReplaceAll(activeHelpEnvVar, \"-\", \"_\")\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/active_help.md",
    "content": "# Active Help\n\nActive Help is a framework provided by Cobra which allows a program to define messages (hints, warnings, etc) that will be printed during program usage.  It aims to make it easier for your users to learn how to use your program.  If configured by the program, Active Help is printed when the user triggers shell completion.\n\nFor example, \n```\nbash-5.1$ helm repo add [tab]\nYou must choose a name for the repo you are adding.\n\nbash-5.1$ bin/helm package [tab]\nPlease specify the path to the chart to package\n\nbash-5.1$ bin/helm package [tab][tab]\nbin/    internal/    scripts/    pkg/     testdata/\n```\n\n**Hint**: A good place to use Active Help messages is when the normal completion system does not provide any suggestions. In such cases, Active Help nicely supplements the normal shell completions to guide the user in knowing what is expected by the program.\n## Supported shells\n\nActive Help is currently only supported for the following shells:\n- Bash (using [bash completion V2](shell_completions.md#bash-completion-v2) only). Note that bash 4.4 or higher is required for the prompt to appear when an Active Help message is printed.\n- Zsh\n\n## Adding Active Help messages\n\nAs Active Help uses the shell completion system, the implementation of Active Help messages is done by enhancing custom dynamic completions.  If you are not familiar with dynamic completions, please refer to [Shell Completions](shell_completions.md).\n\nAdding Active Help is done through the use of the `cobra.AppendActiveHelp(...)` function, where the program repeatedly adds Active Help messages to the list of completions.  Keep reading for details.\n\n### Active Help for nouns\n\nAdding Active Help when completing a noun is done within the `ValidArgsFunction(...)` of a command.  Please notice the use of `cobra.AppendActiveHelp(...)` in the following example:\n\n```go\ncmd := &cobra.Command{\n\tUse:   \"add [NAME] [URL]\",\n\tShort: \"add a chart repository\",\n\tArgs:  require.ExactArgs(2),\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\treturn addRepo(args)\n\t},\n\tValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\tvar comps []string\n\t\tif len(args) == 0 {\n\t\t\tcomps = cobra.AppendActiveHelp(comps, \"You must choose a name for the repo you are adding\")\n\t\t} else if len(args) == 1 {\n\t\t\tcomps = cobra.AppendActiveHelp(comps, \"You must specify the URL for the repo you are adding\")\n\t\t} else {\n\t\t\tcomps = cobra.AppendActiveHelp(comps, \"This command does not take any more arguments\")\n\t\t}\n\t\treturn comps, cobra.ShellCompDirectiveNoFileComp\n\t},\n}\n```\nThe example above defines the completions (none, in this specific example) as well as the Active Help messages for the `helm repo add` command.  It yields the following behavior:\n```\nbash-5.1$ helm repo add [tab]\nYou must choose a name for the repo you are adding\n\nbash-5.1$ helm repo add grafana [tab]\nYou must specify the URL for the repo you are adding\n\nbash-5.1$ helm repo add grafana https://grafana.github.io/helm-charts [tab]\nThis command does not take any more arguments\n```\n**Hint**: As can be seen in the above example, a good place to use Active Help messages is when the normal completion system does not provide any suggestions. In such cases, Active Help nicely supplements the normal shell completions.\n\n### Active Help for flags\n\nProviding Active Help for flags is done in the same fashion as for nouns, but using the completion function registered for the flag.  For example:\n```go\n_ = cmd.RegisterFlagCompletionFunc(\"version\", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\tif len(args) != 2 {\n\t\t\treturn cobra.AppendActiveHelp(nil, \"You must first specify the chart to install before the --version flag can be completed\"), cobra.ShellCompDirectiveNoFileComp\n\t\t}\n\t\treturn compVersionFlag(args[1], toComplete)\n\t})\n```\nThe example above prints an Active Help message when not enough information was given by the user to complete the `--version` flag.\n```\nbash-5.1$ bin/helm install myrelease --version 2.0.[tab]\nYou must first specify the chart to install before the --version flag can be completed\n\nbash-5.1$ bin/helm install myrelease bitnami/solr --version 2.0.[tab][tab]\n2.0.1  2.0.2  2.0.3\n```\n\n## User control of Active Help\n\nYou may want to allow your users to disable Active Help or choose between different levels of Active Help.  It is entirely up to the program to define the type of configurability of Active Help that it wants to offer, if any.\nAllowing to configure Active Help is entirely optional; you can use Active Help in your program without doing anything about Active Help configuration.\n\nThe way to configure Active Help is to use the program's Active Help environment\nvariable.  That variable is named `<PROGRAM>_ACTIVE_HELP` where `<PROGRAM>` is the name of your \nprogram in uppercase with any `-` replaced by an `_`.  The variable should be set by the user to whatever\nActive Help configuration values are supported by the program.\n\nFor example, say `helm` has chosen to support three levels for Active Help: `on`, `off`, `local`.  Then a user\nwould set the desired behavior to `local` by doing `export HELM_ACTIVE_HELP=local` in their shell.\n\nFor simplicity, when in `cmd.ValidArgsFunction(...)` or a flag's completion function, the program should read the\nActive Help configuration using the `cobra.GetActiveHelpConfig(cmd)` function and select what Active Help messages\nshould or should not be added (instead of reading the environment variable directly).\n\nFor example:\n```go\nValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\tactiveHelpLevel := cobra.GetActiveHelpConfig(cmd)\n\n\tvar comps []string\n\tif len(args) == 0 {\n\t\tif activeHelpLevel != \"off\"  {\n\t\t\tcomps = cobra.AppendActiveHelp(comps, \"You must choose a name for the repo you are adding\")\n\t\t}\n\t} else if len(args) == 1 {\n\t\tif activeHelpLevel != \"off\" {\n\t\t\tcomps = cobra.AppendActiveHelp(comps, \"You must specify the URL for the repo you are adding\")\n\t\t}\n\t} else {\n\t\tif activeHelpLevel == \"local\" {\n\t\t\tcomps = cobra.AppendActiveHelp(comps, \"This command does not take any more arguments\")\n\t\t}\n\t}\n\treturn comps, cobra.ShellCompDirectiveNoFileComp\n},\n```\n**Note 1**: If the `<PROGRAM>_ACTIVE_HELP` environment variable is set to the string \"0\", Cobra will automatically disable all Active Help output (even if some output was specified by the program using the `cobra.AppendActiveHelp(...)` function).  Using \"0\" can simplify your code in situations where you want to blindly disable Active Help without having to call `cobra.GetActiveHelpConfig(cmd)` explicitly.\n\n**Note 2**: If a user wants to disable Active Help for every single program based on Cobra, she can set the environment variable `COBRA_ACTIVE_HELP` to \"0\".  In this case `cobra.GetActiveHelpConfig(cmd)` will return \"0\" no matter what the variable `<PROGRAM>_ACTIVE_HELP` is set to.\n\n**Note 3**: If the user does not set `<PROGRAM>_ACTIVE_HELP` or `COBRA_ACTIVE_HELP` (which will be a common case), the default value for the Active Help configuration returned by `cobra.GetActiveHelpConfig(cmd)` will be the empty string. \n## Active Help with Cobra's default completion command\n\nCobra provides a default `completion` command for programs that wish to use it.\nWhen using the default `completion` command, Active Help is configurable in the same\nfashion as described above using environment variables.  You may wish to document this in more\ndetails for your users.\n\n## Debugging Active Help\n\nDebugging your Active Help code is done in the same way as debugging your dynamic completion code, which is with Cobra's hidden `__complete` command.  Please refer to [debugging shell completion](shell_completions.md#debugging) for details.\n\nWhen debugging with the `__complete` command, if you want to specify different Active Help configurations, you should use the active help environment variable.  That variable is named `<PROGRAM>_ACTIVE_HELP` where any `-` is replaced by an `_`.  For example, we can test deactivating some Active Help as shown below:\n```\n$ HELM_ACTIVE_HELP=1 bin/helm __complete install wordpress bitnami/h<ENTER>\nbitnami/haproxy\nbitnami/harbor\n_activeHelp_ WARNING: cannot re-use a name that is still in use\n:0\nCompletion ended with directive: ShellCompDirectiveDefault\n\n$ HELM_ACTIVE_HELP=0 bin/helm __complete install wordpress bitnami/h<ENTER>\nbitnami/haproxy\nbitnami/harbor\n:0\nCompletion ended with directive: ShellCompDirectiveDefault\n```\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/args.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype PositionalArgs func(cmd *Command, args []string) error\n\n// legacyArgs validation has the following behaviour:\n// - root commands with no subcommands can take arbitrary arguments\n// - root commands with subcommands will do subcommand validity checking\n// - subcommands will always accept arbitrary arguments\nfunc legacyArgs(cmd *Command, args []string) error {\n\t// no subcommand, always take args\n\tif !cmd.HasSubCommands() {\n\t\treturn nil\n\t}\n\n\t// root command with subcommands, do subcommand checking.\n\tif !cmd.HasParent() && len(args) > 0 {\n\t\treturn fmt.Errorf(\"unknown command %q for %q%s\", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))\n\t}\n\treturn nil\n}\n\n// NoArgs returns an error if any args are included.\nfunc NoArgs(cmd *Command, args []string) error {\n\tif len(args) > 0 {\n\t\treturn fmt.Errorf(\"unknown command %q for %q\", args[0], cmd.CommandPath())\n\t}\n\treturn nil\n}\n\n// OnlyValidArgs returns an error if there are any positional args that are not in\n// the `ValidArgs` field of `Command`\nfunc OnlyValidArgs(cmd *Command, args []string) error {\n\tif len(cmd.ValidArgs) > 0 {\n\t\t// Remove any description that may be included in ValidArgs.\n\t\t// A description is following a tab character.\n\t\tvar validArgs []string\n\t\tfor _, v := range cmd.ValidArgs {\n\t\t\tvalidArgs = append(validArgs, strings.Split(v, \"\\t\")[0])\n\t\t}\n\t\tfor _, v := range args {\n\t\t\tif !stringInSlice(v, validArgs) {\n\t\t\t\treturn fmt.Errorf(\"invalid argument %q for %q%s\", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// ArbitraryArgs never returns an error.\nfunc ArbitraryArgs(cmd *Command, args []string) error {\n\treturn nil\n}\n\n// MinimumNArgs returns an error if there is not at least N args.\nfunc MinimumNArgs(n int) PositionalArgs {\n\treturn func(cmd *Command, args []string) error {\n\t\tif len(args) < n {\n\t\t\treturn fmt.Errorf(\"requires at least %d arg(s), only received %d\", n, len(args))\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// MaximumNArgs returns an error if there are more than N args.\nfunc MaximumNArgs(n int) PositionalArgs {\n\treturn func(cmd *Command, args []string) error {\n\t\tif len(args) > n {\n\t\t\treturn fmt.Errorf(\"accepts at most %d arg(s), received %d\", n, len(args))\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// ExactArgs returns an error if there are not exactly n args.\nfunc ExactArgs(n int) PositionalArgs {\n\treturn func(cmd *Command, args []string) error {\n\t\tif len(args) != n {\n\t\t\treturn fmt.Errorf(\"accepts %d arg(s), received %d\", n, len(args))\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// RangeArgs returns an error if the number of args is not within the expected range.\nfunc RangeArgs(min int, max int) PositionalArgs {\n\treturn func(cmd *Command, args []string) error {\n\t\tif len(args) < min || len(args) > max {\n\t\t\treturn fmt.Errorf(\"accepts between %d and %d arg(s), received %d\", min, max, len(args))\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// MatchAll allows combining several PositionalArgs to work in concert.\nfunc MatchAll(pargs ...PositionalArgs) PositionalArgs {\n\treturn func(cmd *Command, args []string) error {\n\t\tfor _, parg := range pargs {\n\t\t\tif err := parg(cmd, args); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// ExactValidArgs returns an error if there are not exactly N positional args OR\n// there are any positional args that are not in the `ValidArgs` field of `Command`\n//\n// Deprecated: use MatchAll(ExactArgs(n), OnlyValidArgs) instead\nfunc ExactValidArgs(n int) PositionalArgs {\n\treturn MatchAll(ExactArgs(n), OnlyValidArgs)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/bash_completions.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/spf13/pflag\"\n)\n\n// Annotations for Bash completion.\nconst (\n\tBashCompFilenameExt     = \"cobra_annotation_bash_completion_filename_extensions\"\n\tBashCompCustom          = \"cobra_annotation_bash_completion_custom\"\n\tBashCompOneRequiredFlag = \"cobra_annotation_bash_completion_one_required_flag\"\n\tBashCompSubdirsInDir    = \"cobra_annotation_bash_completion_subdirs_in_dir\"\n)\n\nfunc writePreamble(buf io.StringWriter, name string) {\n\tWriteStringAndCheck(buf, fmt.Sprintf(\"# bash completion for %-36s -*- shell-script -*-\\n\", name))\n\tWriteStringAndCheck(buf, fmt.Sprintf(`\n__%[1]s_debug()\n{\n    if [[ -n ${BASH_COMP_DEBUG_FILE:-} ]]; then\n        echo \"$*\" >> \"${BASH_COMP_DEBUG_FILE}\"\n    fi\n}\n\n# Homebrew on Macs have version 1.3 of bash-completion which doesn't include\n# _init_completion. This is a very minimal version of that function.\n__%[1]s_init_completion()\n{\n    COMPREPLY=()\n    _get_comp_words_by_ref \"$@\" cur prev words cword\n}\n\n__%[1]s_index_of_word()\n{\n    local w word=$1\n    shift\n    index=0\n    for w in \"$@\"; do\n        [[ $w = \"$word\" ]] && return\n        index=$((index+1))\n    done\n    index=-1\n}\n\n__%[1]s_contains_word()\n{\n    local w word=$1; shift\n    for w in \"$@\"; do\n        [[ $w = \"$word\" ]] && return\n    done\n    return 1\n}\n\n__%[1]s_handle_go_custom_completion()\n{\n    __%[1]s_debug \"${FUNCNAME[0]}: cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}\"\n\n    local shellCompDirectiveError=%[3]d\n    local shellCompDirectiveNoSpace=%[4]d\n    local shellCompDirectiveNoFileComp=%[5]d\n    local shellCompDirectiveFilterFileExt=%[6]d\n    local shellCompDirectiveFilterDirs=%[7]d\n\n    local out requestComp lastParam lastChar comp directive args\n\n    # Prepare the command to request completions for the program.\n    # Calling ${words[0]} instead of directly %[1]s allows to handle aliases\n    args=(\"${words[@]:1}\")\n    # Disable ActiveHelp which is not supported for bash completion v1\n    requestComp=\"%[8]s=0 ${words[0]} %[2]s ${args[*]}\"\n\n    lastParam=${words[$((${#words[@]}-1))]}\n    lastChar=${lastParam:$((${#lastParam}-1)):1}\n    __%[1]s_debug \"${FUNCNAME[0]}: lastParam ${lastParam}, lastChar ${lastChar}\"\n\n    if [ -z \"${cur}\" ] && [ \"${lastChar}\" != \"=\" ]; then\n        # If the last parameter is complete (there is a space following it)\n        # We add an extra empty parameter so we can indicate this to the go method.\n        __%[1]s_debug \"${FUNCNAME[0]}: Adding extra empty parameter\"\n        requestComp=\"${requestComp} \\\"\\\"\"\n    fi\n\n    __%[1]s_debug \"${FUNCNAME[0]}: calling ${requestComp}\"\n    # Use eval to handle any environment variables and such\n    out=$(eval \"${requestComp}\" 2>/dev/null)\n\n    # Extract the directive integer at the very end of the output following a colon (:)\n    directive=${out##*:}\n    # Remove the directive\n    out=${out%%:*}\n    if [ \"${directive}\" = \"${out}\" ]; then\n        # There is not directive specified\n        directive=0\n    fi\n    __%[1]s_debug \"${FUNCNAME[0]}: the completion directive is: ${directive}\"\n    __%[1]s_debug \"${FUNCNAME[0]}: the completions are: ${out}\"\n\n    if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then\n        # Error code.  No completion.\n        __%[1]s_debug \"${FUNCNAME[0]}: received error from custom completion go code\"\n        return\n    else\n        if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then\n            if [[ $(type -t compopt) = \"builtin\" ]]; then\n                __%[1]s_debug \"${FUNCNAME[0]}: activating no space\"\n                compopt -o nospace\n            fi\n        fi\n        if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then\n            if [[ $(type -t compopt) = \"builtin\" ]]; then\n                __%[1]s_debug \"${FUNCNAME[0]}: activating no file completion\"\n                compopt +o default\n            fi\n        fi\n    fi\n\n    if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then\n        # File extension filtering\n        local fullFilter filter filteringCmd\n        # Do not use quotes around the $out variable or else newline\n        # characters will be kept.\n        for filter in ${out}; do\n            fullFilter+=\"$filter|\"\n        done\n\n        filteringCmd=\"_filedir $fullFilter\"\n        __%[1]s_debug \"File filtering command: $filteringCmd\"\n        $filteringCmd\n    elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then\n        # File completion for directories only\n        local subdir\n        # Use printf to strip any trailing newline\n        subdir=$(printf \"%%s\" \"${out}\")\n        if [ -n \"$subdir\" ]; then\n            __%[1]s_debug \"Listing directories in $subdir\"\n            __%[1]s_handle_subdirs_in_dir_flag \"$subdir\"\n        else\n            __%[1]s_debug \"Listing directories in .\"\n            _filedir -d\n        fi\n    else\n        while IFS='' read -r comp; do\n            COMPREPLY+=(\"$comp\")\n        done < <(compgen -W \"${out}\" -- \"$cur\")\n    fi\n}\n\n__%[1]s_handle_reply()\n{\n    __%[1]s_debug \"${FUNCNAME[0]}\"\n    local comp\n    case $cur in\n        -*)\n            if [[ $(type -t compopt) = \"builtin\" ]]; then\n                compopt -o nospace\n            fi\n            local allflags\n            if [ ${#must_have_one_flag[@]} -ne 0 ]; then\n                allflags=(\"${must_have_one_flag[@]}\")\n            else\n                allflags=(\"${flags[*]} ${two_word_flags[*]}\")\n            fi\n            while IFS='' read -r comp; do\n                COMPREPLY+=(\"$comp\")\n            done < <(compgen -W \"${allflags[*]}\" -- \"$cur\")\n            if [[ $(type -t compopt) = \"builtin\" ]]; then\n                [[ \"${COMPREPLY[0]}\" == *= ]] || compopt +o nospace\n            fi\n\n            # complete after --flag=abc\n            if [[ $cur == *=* ]]; then\n                if [[ $(type -t compopt) = \"builtin\" ]]; then\n                    compopt +o nospace\n                fi\n\n                local index flag\n                flag=\"${cur%%=*}\"\n                __%[1]s_index_of_word \"${flag}\" \"${flags_with_completion[@]}\"\n                COMPREPLY=()\n                if [[ ${index} -ge 0 ]]; then\n                    PREFIX=\"\"\n                    cur=\"${cur#*=}\"\n                    ${flags_completion[${index}]}\n                    if [ -n \"${ZSH_VERSION:-}\" ]; then\n                        # zsh completion needs --flag= prefix\n                        eval \"COMPREPLY=( \\\"\\${COMPREPLY[@]/#/${flag}=}\\\" )\"\n                    fi\n                fi\n            fi\n\n            if [[ -z \"${flag_parsing_disabled}\" ]]; then\n                # If flag parsing is enabled, we have completed the flags and can return.\n                # If flag parsing is disabled, we may not know all (or any) of the flags, so we fallthrough\n                # to possibly call handle_go_custom_completion.\n                return 0;\n            fi\n            ;;\n    esac\n\n    # check if we are handling a flag with special work handling\n    local index\n    __%[1]s_index_of_word \"${prev}\" \"${flags_with_completion[@]}\"\n    if [[ ${index} -ge 0 ]]; then\n        ${flags_completion[${index}]}\n        return\n    fi\n\n    # we are parsing a flag and don't have a special handler, no completion\n    if [[ ${cur} != \"${words[cword]}\" ]]; then\n        return\n    fi\n\n    local completions\n    completions=(\"${commands[@]}\")\n    if [[ ${#must_have_one_noun[@]} -ne 0 ]]; then\n        completions+=(\"${must_have_one_noun[@]}\")\n    elif [[ -n \"${has_completion_function}\" ]]; then\n        # if a go completion function is provided, defer to that function\n        __%[1]s_handle_go_custom_completion\n    fi\n    if [[ ${#must_have_one_flag[@]} -ne 0 ]]; then\n        completions+=(\"${must_have_one_flag[@]}\")\n    fi\n    while IFS='' read -r comp; do\n        COMPREPLY+=(\"$comp\")\n    done < <(compgen -W \"${completions[*]}\" -- \"$cur\")\n\n    if [[ ${#COMPREPLY[@]} -eq 0 && ${#noun_aliases[@]} -gt 0 && ${#must_have_one_noun[@]} -ne 0 ]]; then\n        while IFS='' read -r comp; do\n            COMPREPLY+=(\"$comp\")\n        done < <(compgen -W \"${noun_aliases[*]}\" -- \"$cur\")\n    fi\n\n    if [[ ${#COMPREPLY[@]} -eq 0 ]]; then\n        if declare -F __%[1]s_custom_func >/dev/null; then\n            # try command name qualified custom func\n            __%[1]s_custom_func\n        else\n            # otherwise fall back to unqualified for compatibility\n            declare -F __custom_func >/dev/null && __custom_func\n        fi\n    fi\n\n    # available in bash-completion >= 2, not always present on macOS\n    if declare -F __ltrim_colon_completions >/dev/null; then\n        __ltrim_colon_completions \"$cur\"\n    fi\n\n    # If there is only 1 completion and it is a flag with an = it will be completed\n    # but we don't want a space after the =\n    if [[ \"${#COMPREPLY[@]}\" -eq \"1\" ]] && [[ $(type -t compopt) = \"builtin\" ]] && [[ \"${COMPREPLY[0]}\" == --*= ]]; then\n       compopt -o nospace\n    fi\n}\n\n# The arguments should be in the form \"ext1|ext2|extn\"\n__%[1]s_handle_filename_extension_flag()\n{\n    local ext=\"$1\"\n    _filedir \"@(${ext})\"\n}\n\n__%[1]s_handle_subdirs_in_dir_flag()\n{\n    local dir=\"$1\"\n    pushd \"${dir}\" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return\n}\n\n__%[1]s_handle_flag()\n{\n    __%[1]s_debug \"${FUNCNAME[0]}: c is $c words[c] is ${words[c]}\"\n\n    # if a command required a flag, and we found it, unset must_have_one_flag()\n    local flagname=${words[c]}\n    local flagvalue=\"\"\n    # if the word contained an =\n    if [[ ${words[c]} == *\"=\"* ]]; then\n        flagvalue=${flagname#*=} # take in as flagvalue after the =\n        flagname=${flagname%%=*} # strip everything after the =\n        flagname=\"${flagname}=\" # but put the = back\n    fi\n    __%[1]s_debug \"${FUNCNAME[0]}: looking for ${flagname}\"\n    if __%[1]s_contains_word \"${flagname}\" \"${must_have_one_flag[@]}\"; then\n        must_have_one_flag=()\n    fi\n\n    # if you set a flag which only applies to this command, don't show subcommands\n    if __%[1]s_contains_word \"${flagname}\" \"${local_nonpersistent_flags[@]}\"; then\n      commands=()\n    fi\n\n    # keep flag value with flagname as flaghash\n    # flaghash variable is an associative array which is only supported in bash > 3.\n    if [[ -z \"${BASH_VERSION:-}\" || \"${BASH_VERSINFO[0]:-}\" -gt 3 ]]; then\n        if [ -n \"${flagvalue}\" ] ; then\n            flaghash[${flagname}]=${flagvalue}\n        elif [ -n \"${words[ $((c+1)) ]}\" ] ; then\n            flaghash[${flagname}]=${words[ $((c+1)) ]}\n        else\n            flaghash[${flagname}]=\"true\" # pad \"true\" for bool flag\n        fi\n    fi\n\n    # skip the argument to a two word flag\n    if [[ ${words[c]} != *\"=\"* ]] && __%[1]s_contains_word \"${words[c]}\" \"${two_word_flags[@]}\"; then\n        __%[1]s_debug \"${FUNCNAME[0]}: found a flag ${words[c]}, skip the next argument\"\n        c=$((c+1))\n        # if we are looking for a flags value, don't show commands\n        if [[ $c -eq $cword ]]; then\n            commands=()\n        fi\n    fi\n\n    c=$((c+1))\n\n}\n\n__%[1]s_handle_noun()\n{\n    __%[1]s_debug \"${FUNCNAME[0]}: c is $c words[c] is ${words[c]}\"\n\n    if __%[1]s_contains_word \"${words[c]}\" \"${must_have_one_noun[@]}\"; then\n        must_have_one_noun=()\n    elif __%[1]s_contains_word \"${words[c]}\" \"${noun_aliases[@]}\"; then\n        must_have_one_noun=()\n    fi\n\n    nouns+=(\"${words[c]}\")\n    c=$((c+1))\n}\n\n__%[1]s_handle_command()\n{\n    __%[1]s_debug \"${FUNCNAME[0]}: c is $c words[c] is ${words[c]}\"\n\n    local next_command\n    if [[ -n ${last_command} ]]; then\n        next_command=\"_${last_command}_${words[c]//:/__}\"\n    else\n        if [[ $c -eq 0 ]]; then\n            next_command=\"_%[1]s_root_command\"\n        else\n            next_command=\"_${words[c]//:/__}\"\n        fi\n    fi\n    c=$((c+1))\n    __%[1]s_debug \"${FUNCNAME[0]}: looking for ${next_command}\"\n    declare -F \"$next_command\" >/dev/null && $next_command\n}\n\n__%[1]s_handle_word()\n{\n    if [[ $c -ge $cword ]]; then\n        __%[1]s_handle_reply\n        return\n    fi\n    __%[1]s_debug \"${FUNCNAME[0]}: c is $c words[c] is ${words[c]}\"\n    if [[ \"${words[c]}\" == -* ]]; then\n        __%[1]s_handle_flag\n    elif __%[1]s_contains_word \"${words[c]}\" \"${commands[@]}\"; then\n        __%[1]s_handle_command\n    elif [[ $c -eq 0 ]]; then\n        __%[1]s_handle_command\n    elif __%[1]s_contains_word \"${words[c]}\" \"${command_aliases[@]}\"; then\n        # aliashash variable is an associative array which is only supported in bash > 3.\n        if [[ -z \"${BASH_VERSION:-}\" || \"${BASH_VERSINFO[0]:-}\" -gt 3 ]]; then\n            words[c]=${aliashash[${words[c]}]}\n            __%[1]s_handle_command\n        else\n            __%[1]s_handle_noun\n        fi\n    else\n        __%[1]s_handle_noun\n    fi\n    __%[1]s_handle_word\n}\n\n`, name, ShellCompNoDescRequestCmd,\n\t\tShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,\n\t\tShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name)))\n}\n\nfunc writePostscript(buf io.StringWriter, name string) {\n\tname = strings.ReplaceAll(name, \":\", \"__\")\n\tWriteStringAndCheck(buf, fmt.Sprintf(\"__start_%s()\\n\", name))\n\tWriteStringAndCheck(buf, fmt.Sprintf(`{\n    local cur prev words cword split\n    declare -A flaghash 2>/dev/null || :\n    declare -A aliashash 2>/dev/null || :\n    if declare -F _init_completion >/dev/null 2>&1; then\n        _init_completion -s || return\n    else\n        __%[1]s_init_completion -n \"=\" || return\n    fi\n\n    local c=0\n    local flag_parsing_disabled=\n    local flags=()\n    local two_word_flags=()\n    local local_nonpersistent_flags=()\n    local flags_with_completion=()\n    local flags_completion=()\n    local commands=(\"%[1]s\")\n    local command_aliases=()\n    local must_have_one_flag=()\n    local must_have_one_noun=()\n    local has_completion_function=\"\"\n    local last_command=\"\"\n    local nouns=()\n    local noun_aliases=()\n\n    __%[1]s_handle_word\n}\n\n`, name))\n\tWriteStringAndCheck(buf, fmt.Sprintf(`if [[ $(type -t compopt) = \"builtin\" ]]; then\n    complete -o default -F __start_%s %s\nelse\n    complete -o default -o nospace -F __start_%s %s\nfi\n\n`, name, name, name, name))\n\tWriteStringAndCheck(buf, \"# ex: ts=4 sw=4 et filetype=sh\\n\")\n}\n\nfunc writeCommands(buf io.StringWriter, cmd *Command) {\n\tWriteStringAndCheck(buf, \"    commands=()\\n\")\n\tfor _, c := range cmd.Commands() {\n\t\tif !c.IsAvailableCommand() && c != cmd.helpCommand {\n\t\t\tcontinue\n\t\t}\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    commands+=(%q)\\n\", c.Name()))\n\t\twriteCmdAliases(buf, c)\n\t}\n\tWriteStringAndCheck(buf, \"\\n\")\n}\n\nfunc writeFlagHandler(buf io.StringWriter, name string, annotations map[string][]string, cmd *Command) {\n\tfor key, value := range annotations {\n\t\tswitch key {\n\t\tcase BashCompFilenameExt:\n\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    flags_with_completion+=(%q)\\n\", name))\n\n\t\t\tvar ext string\n\t\t\tif len(value) > 0 {\n\t\t\t\text = fmt.Sprintf(\"__%s_handle_filename_extension_flag \", cmd.Root().Name()) + strings.Join(value, \"|\")\n\t\t\t} else {\n\t\t\t\text = \"_filedir\"\n\t\t\t}\n\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    flags_completion+=(%q)\\n\", ext))\n\t\tcase BashCompCustom:\n\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    flags_with_completion+=(%q)\\n\", name))\n\n\t\t\tif len(value) > 0 {\n\t\t\t\thandlers := strings.Join(value, \"; \")\n\t\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    flags_completion+=(%q)\\n\", handlers))\n\t\t\t} else {\n\t\t\t\tWriteStringAndCheck(buf, \"    flags_completion+=(:)\\n\")\n\t\t\t}\n\t\tcase BashCompSubdirsInDir:\n\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    flags_with_completion+=(%q)\\n\", name))\n\n\t\t\tvar ext string\n\t\t\tif len(value) == 1 {\n\t\t\t\text = fmt.Sprintf(\"__%s_handle_subdirs_in_dir_flag \", cmd.Root().Name()) + value[0]\n\t\t\t} else {\n\t\t\t\text = \"_filedir -d\"\n\t\t\t}\n\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    flags_completion+=(%q)\\n\", ext))\n\t\t}\n\t}\n}\n\nconst cbn = \"\\\")\\n\"\n\nfunc writeShortFlag(buf io.StringWriter, flag *pflag.Flag, cmd *Command) {\n\tname := flag.Shorthand\n\tformat := \"    \"\n\tif len(flag.NoOptDefVal) == 0 {\n\t\tformat += \"two_word_\"\n\t}\n\tformat += \"flags+=(\\\"-%s\" + cbn\n\tWriteStringAndCheck(buf, fmt.Sprintf(format, name))\n\twriteFlagHandler(buf, \"-\"+name, flag.Annotations, cmd)\n}\n\nfunc writeFlag(buf io.StringWriter, flag *pflag.Flag, cmd *Command) {\n\tname := flag.Name\n\tformat := \"    flags+=(\\\"--%s\"\n\tif len(flag.NoOptDefVal) == 0 {\n\t\tformat += \"=\"\n\t}\n\tformat += cbn\n\tWriteStringAndCheck(buf, fmt.Sprintf(format, name))\n\tif len(flag.NoOptDefVal) == 0 {\n\t\tformat = \"    two_word_flags+=(\\\"--%s\" + cbn\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(format, name))\n\t}\n\twriteFlagHandler(buf, \"--\"+name, flag.Annotations, cmd)\n}\n\nfunc writeLocalNonPersistentFlag(buf io.StringWriter, flag *pflag.Flag) {\n\tname := flag.Name\n\tformat := \"    local_nonpersistent_flags+=(\\\"--%[1]s\" + cbn\n\tif len(flag.NoOptDefVal) == 0 {\n\t\tformat += \"    local_nonpersistent_flags+=(\\\"--%[1]s=\" + cbn\n\t}\n\tWriteStringAndCheck(buf, fmt.Sprintf(format, name))\n\tif len(flag.Shorthand) > 0 {\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    local_nonpersistent_flags+=(\\\"-%s\\\")\\n\", flag.Shorthand))\n\t}\n}\n\n// prepareCustomAnnotationsForFlags setup annotations for go completions for registered flags\nfunc prepareCustomAnnotationsForFlags(cmd *Command) {\n\tflagCompletionMutex.RLock()\n\tdefer flagCompletionMutex.RUnlock()\n\tfor flag := range flagCompletionFunctions {\n\t\t// Make sure the completion script calls the __*_go_custom_completion function for\n\t\t// every registered flag.  We need to do this here (and not when the flag was registered\n\t\t// for completion) so that we can know the root command name for the prefix\n\t\t// of __<prefix>_go_custom_completion\n\t\tif flag.Annotations == nil {\n\t\t\tflag.Annotations = map[string][]string{}\n\t\t}\n\t\tflag.Annotations[BashCompCustom] = []string{fmt.Sprintf(\"__%[1]s_handle_go_custom_completion\", cmd.Root().Name())}\n\t}\n}\n\nfunc writeFlags(buf io.StringWriter, cmd *Command) {\n\tprepareCustomAnnotationsForFlags(cmd)\n\tWriteStringAndCheck(buf, `    flags=()\n    two_word_flags=()\n    local_nonpersistent_flags=()\n    flags_with_completion=()\n    flags_completion=()\n\n`)\n\n\tif cmd.DisableFlagParsing {\n\t\tWriteStringAndCheck(buf, \"    flag_parsing_disabled=1\\n\")\n\t}\n\n\tlocalNonPersistentFlags := cmd.LocalNonPersistentFlags()\n\tcmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {\n\t\tif nonCompletableFlag(flag) {\n\t\t\treturn\n\t\t}\n\t\twriteFlag(buf, flag, cmd)\n\t\tif len(flag.Shorthand) > 0 {\n\t\t\twriteShortFlag(buf, flag, cmd)\n\t\t}\n\t\t// localNonPersistentFlags are used to stop the completion of subcommands when one is set\n\t\t// if TraverseChildren is true we should allow to complete subcommands\n\t\tif localNonPersistentFlags.Lookup(flag.Name) != nil && !cmd.Root().TraverseChildren {\n\t\t\twriteLocalNonPersistentFlag(buf, flag)\n\t\t}\n\t})\n\tcmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {\n\t\tif nonCompletableFlag(flag) {\n\t\t\treturn\n\t\t}\n\t\twriteFlag(buf, flag, cmd)\n\t\tif len(flag.Shorthand) > 0 {\n\t\t\twriteShortFlag(buf, flag, cmd)\n\t\t}\n\t})\n\n\tWriteStringAndCheck(buf, \"\\n\")\n}\n\nfunc writeRequiredFlag(buf io.StringWriter, cmd *Command) {\n\tWriteStringAndCheck(buf, \"    must_have_one_flag=()\\n\")\n\tflags := cmd.NonInheritedFlags()\n\tflags.VisitAll(func(flag *pflag.Flag) {\n\t\tif nonCompletableFlag(flag) {\n\t\t\treturn\n\t\t}\n\t\tfor key := range flag.Annotations {\n\t\t\tswitch key {\n\t\t\tcase BashCompOneRequiredFlag:\n\t\t\t\tformat := \"    must_have_one_flag+=(\\\"--%s\"\n\t\t\t\tif flag.Value.Type() != \"bool\" {\n\t\t\t\t\tformat += \"=\"\n\t\t\t\t}\n\t\t\t\tformat += cbn\n\t\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(format, flag.Name))\n\n\t\t\t\tif len(flag.Shorthand) > 0 {\n\t\t\t\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    must_have_one_flag+=(\\\"-%s\"+cbn, flag.Shorthand))\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc writeRequiredNouns(buf io.StringWriter, cmd *Command) {\n\tWriteStringAndCheck(buf, \"    must_have_one_noun=()\\n\")\n\tsort.Strings(cmd.ValidArgs)\n\tfor _, value := range cmd.ValidArgs {\n\t\t// Remove any description that may be included following a tab character.\n\t\t// Descriptions are not supported by bash completion.\n\t\tvalue = strings.Split(value, \"\\t\")[0]\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    must_have_one_noun+=(%q)\\n\", value))\n\t}\n\tif cmd.ValidArgsFunction != nil {\n\t\tWriteStringAndCheck(buf, \"    has_completion_function=1\\n\")\n\t}\n}\n\nfunc writeCmdAliases(buf io.StringWriter, cmd *Command) {\n\tif len(cmd.Aliases) == 0 {\n\t\treturn\n\t}\n\n\tsort.Strings(cmd.Aliases)\n\n\tWriteStringAndCheck(buf, fmt.Sprint(`    if [[ -z \"${BASH_VERSION:-}\" || \"${BASH_VERSINFO[0]:-}\" -gt 3 ]]; then`, \"\\n\"))\n\tfor _, value := range cmd.Aliases {\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"        command_aliases+=(%q)\\n\", value))\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"        aliashash[%q]=%q\\n\", value, cmd.Name()))\n\t}\n\tWriteStringAndCheck(buf, `    fi`)\n\tWriteStringAndCheck(buf, \"\\n\")\n}\nfunc writeArgAliases(buf io.StringWriter, cmd *Command) {\n\tWriteStringAndCheck(buf, \"    noun_aliases=()\\n\")\n\tsort.Strings(cmd.ArgAliases)\n\tfor _, value := range cmd.ArgAliases {\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"    noun_aliases+=(%q)\\n\", value))\n\t}\n}\n\nfunc gen(buf io.StringWriter, cmd *Command) {\n\tfor _, c := range cmd.Commands() {\n\t\tif !c.IsAvailableCommand() && c != cmd.helpCommand {\n\t\t\tcontinue\n\t\t}\n\t\tgen(buf, c)\n\t}\n\tcommandName := cmd.CommandPath()\n\tcommandName = strings.ReplaceAll(commandName, \" \", \"_\")\n\tcommandName = strings.ReplaceAll(commandName, \":\", \"__\")\n\n\tif cmd.Root() == cmd {\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"_%s_root_command()\\n{\\n\", commandName))\n\t} else {\n\t\tWriteStringAndCheck(buf, fmt.Sprintf(\"_%s()\\n{\\n\", commandName))\n\t}\n\n\tWriteStringAndCheck(buf, fmt.Sprintf(\"    last_command=%q\\n\", commandName))\n\tWriteStringAndCheck(buf, \"\\n\")\n\tWriteStringAndCheck(buf, \"    command_aliases=()\\n\")\n\tWriteStringAndCheck(buf, \"\\n\")\n\n\twriteCommands(buf, cmd)\n\twriteFlags(buf, cmd)\n\twriteRequiredFlag(buf, cmd)\n\twriteRequiredNouns(buf, cmd)\n\twriteArgAliases(buf, cmd)\n\tWriteStringAndCheck(buf, \"}\\n\\n\")\n}\n\n// GenBashCompletion generates bash completion file and writes to the passed writer.\nfunc (c *Command) GenBashCompletion(w io.Writer) error {\n\tbuf := new(bytes.Buffer)\n\twritePreamble(buf, c.Name())\n\tif len(c.BashCompletionFunction) > 0 {\n\t\tbuf.WriteString(c.BashCompletionFunction + \"\\n\")\n\t}\n\tgen(buf, c)\n\twritePostscript(buf, c.Name())\n\n\t_, err := buf.WriteTo(w)\n\treturn err\n}\n\nfunc nonCompletableFlag(flag *pflag.Flag) bool {\n\treturn flag.Hidden || len(flag.Deprecated) > 0\n}\n\n// GenBashCompletionFile generates bash completion file.\nfunc (c *Command) GenBashCompletionFile(filename string) error {\n\toutFile, err := os.Create(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer outFile.Close()\n\n\treturn c.GenBashCompletion(outFile)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/bash_completions.md",
    "content": "# Generating Bash Completions For Your cobra.Command\n\nPlease refer to [Shell Completions](shell_completions.md) for details.\n\n## Bash legacy dynamic completions\n\nFor backward compatibility, Cobra still supports its legacy dynamic completion solution (described below).  Unlike the `ValidArgsFunction` solution, the legacy solution will only work for Bash shell-completion and not for other shells. This legacy solution can be used along-side `ValidArgsFunction` and `RegisterFlagCompletionFunc()`, as long as both solutions are not used for the same command.  This provides a path to gradually migrate from the legacy solution to the new solution.\n\n**Note**: Cobra's default `completion` command uses bash completion V2.  If you are currently using Cobra's legacy dynamic completion solution, you should not use the default `completion` command but continue using your own.\n\nThe legacy solution allows you to inject bash functions into the bash completion script.  Those bash functions are responsible for providing the completion choices for your own completions.\n\nSome code that works in kubernetes:\n\n```bash\nconst (\n        bash_completion_func = `__kubectl_parse_get()\n{\n    local kubectl_output out\n    if kubectl_output=$(kubectl get --no-headers \"$1\" 2>/dev/null); then\n        out=($(echo \"${kubectl_output}\" | awk '{print $1}'))\n        COMPREPLY=( $( compgen -W \"${out[*]}\" -- \"$cur\" ) )\n    fi\n}\n\n__kubectl_get_resource()\n{\n    if [[ ${#nouns[@]} -eq 0 ]]; then\n        return 1\n    fi\n    __kubectl_parse_get ${nouns[${#nouns[@]} -1]}\n    if [[ $? -eq 0 ]]; then\n        return 0\n    fi\n}\n\n__kubectl_custom_func() {\n    case ${last_command} in\n        kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop)\n            __kubectl_get_resource\n            return\n            ;;\n        *)\n            ;;\n    esac\n}\n`)\n```\n\nAnd then I set that in my command definition:\n\n```go\ncmds := &cobra.Command{\n\tUse:   \"kubectl\",\n\tShort: \"kubectl controls the Kubernetes cluster manager\",\n\tLong: `kubectl controls the Kubernetes cluster manager.\n\nFind more information at https://github.com/GoogleCloudPlatform/kubernetes.`,\n\tRun: runHelp,\n\tBashCompletionFunction: bash_completion_func,\n}\n```\n\nThe `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__kubectl_custom_func()` (`__<command-use>_custom_func()`) to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__kubectl_customc_func()` will run because the cobra.Command only understood \"kubectl\" and \"get.\" `__kubectl_custom_func()` will see that the cobra.Command is \"kubectl_get\" and will thus call another helper `__kubectl_get_resource()`.  `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`.  So it will call `__kubectl_parse_get pod`.  `__kubectl_parse_get` will actually call out to kubernetes and get any pods.  It will then set `COMPREPLY` to valid pods!\n\nSimilarly, for flags:\n\n```go\n\tannotation := make(map[string][]string)\n\tannotation[cobra.BashCompCustom] = []string{\"__kubectl_get_namespaces\"}\n\n\tflag := &pflag.Flag{\n\t\tName:        \"namespace\",\n\t\tUsage:       usage,\n\t\tAnnotations: annotation,\n\t}\n\tcmd.Flags().AddFlag(flag)\n```\n\nIn addition add the `__kubectl_get_namespaces` implementation in the `BashCompletionFunction`\nvalue, e.g.:\n\n```bash\n__kubectl_get_namespaces()\n{\n    local template\n    template=\"{{ range .items  }}{{ .metadata.name }} {{ end }}\"\n    local kubectl_out\n    if kubectl_out=$(kubectl get -o template --template=\"${template}\" namespace 2>/dev/null); then\n        COMPREPLY=( $( compgen -W \"${kubectl_out}[*]\" -- \"$cur\" ) )\n    fi\n}\n```\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/bash_completionsV2.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\nfunc (c *Command) genBashCompletion(w io.Writer, includeDesc bool) error {\n\tbuf := new(bytes.Buffer)\n\tgenBashComp(buf, c.Name(), includeDesc)\n\t_, err := buf.WriteTo(w)\n\treturn err\n}\n\nfunc genBashComp(buf io.StringWriter, name string, includeDesc bool) {\n\tcompCmd := ShellCompRequestCmd\n\tif !includeDesc {\n\t\tcompCmd = ShellCompNoDescRequestCmd\n\t}\n\n\tWriteStringAndCheck(buf, fmt.Sprintf(`# bash completion V2 for %-36[1]s -*- shell-script -*-\n\n__%[1]s_debug()\n{\n    if [[ -n ${BASH_COMP_DEBUG_FILE-} ]]; then\n        echo \"$*\" >> \"${BASH_COMP_DEBUG_FILE}\"\n    fi\n}\n\n# Macs have bash3 for which the bash-completion package doesn't include\n# _init_completion. This is a minimal version of that function.\n__%[1]s_init_completion()\n{\n    COMPREPLY=()\n    _get_comp_words_by_ref \"$@\" cur prev words cword\n}\n\n# This function calls the %[1]s program to obtain the completion\n# results and the directive.  It fills the 'out' and 'directive' vars.\n__%[1]s_get_completion_results() {\n    local requestComp lastParam lastChar args\n\n    # Prepare the command to request completions for the program.\n    # Calling ${words[0]} instead of directly %[1]s allows to handle aliases\n    args=(\"${words[@]:1}\")\n    requestComp=\"${words[0]} %[2]s ${args[*]}\"\n\n    lastParam=${words[$((${#words[@]}-1))]}\n    lastChar=${lastParam:$((${#lastParam}-1)):1}\n    __%[1]s_debug \"lastParam ${lastParam}, lastChar ${lastChar}\"\n\n    if [[ -z ${cur} && ${lastChar} != = ]]; then\n        # If the last parameter is complete (there is a space following it)\n        # We add an extra empty parameter so we can indicate this to the go method.\n        __%[1]s_debug \"Adding extra empty parameter\"\n        requestComp=\"${requestComp} ''\"\n    fi\n\n    # When completing a flag with an = (e.g., %[1]s -n=<TAB>)\n    # bash focuses on the part after the =, so we need to remove\n    # the flag part from $cur\n    if [[ ${cur} == -*=* ]]; then\n        cur=\"${cur#*=}\"\n    fi\n\n    __%[1]s_debug \"Calling ${requestComp}\"\n    # Use eval to handle any environment variables and such\n    out=$(eval \"${requestComp}\" 2>/dev/null)\n\n    # Extract the directive integer at the very end of the output following a colon (:)\n    directive=${out##*:}\n    # Remove the directive\n    out=${out%%:*}\n    if [[ ${directive} == \"${out}\" ]]; then\n        # There is not directive specified\n        directive=0\n    fi\n    __%[1]s_debug \"The completion directive is: ${directive}\"\n    __%[1]s_debug \"The completions are: ${out}\"\n}\n\n__%[1]s_process_completion_results() {\n    local shellCompDirectiveError=%[3]d\n    local shellCompDirectiveNoSpace=%[4]d\n    local shellCompDirectiveNoFileComp=%[5]d\n    local shellCompDirectiveFilterFileExt=%[6]d\n    local shellCompDirectiveFilterDirs=%[7]d\n    local shellCompDirectiveKeepOrder=%[8]d\n\n    if (((directive & shellCompDirectiveError) != 0)); then\n        # Error code.  No completion.\n        __%[1]s_debug \"Received error from custom completion go code\"\n        return\n    else\n        if (((directive & shellCompDirectiveNoSpace) != 0)); then\n            if [[ $(type -t compopt) == builtin ]]; then\n                __%[1]s_debug \"Activating no space\"\n                compopt -o nospace\n            else\n                __%[1]s_debug \"No space directive not supported in this version of bash\"\n            fi\n        fi\n        if (((directive & shellCompDirectiveKeepOrder) != 0)); then\n            if [[ $(type -t compopt) == builtin ]]; then\n                # no sort isn't supported for bash less than < 4.4\n                if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then\n                    __%[1]s_debug \"No sort directive not supported in this version of bash\"\n                else\n                    __%[1]s_debug \"Activating keep order\"\n                    compopt -o nosort\n                fi\n            else\n                __%[1]s_debug \"No sort directive not supported in this version of bash\"\n            fi\n        fi\n        if (((directive & shellCompDirectiveNoFileComp) != 0)); then\n            if [[ $(type -t compopt) == builtin ]]; then\n                __%[1]s_debug \"Activating no file completion\"\n                compopt +o default\n            else\n                __%[1]s_debug \"No file completion directive not supported in this version of bash\"\n            fi\n        fi\n    fi\n\n    # Separate activeHelp from normal completions\n    local completions=()\n    local activeHelp=()\n    __%[1]s_extract_activeHelp\n\n    if (((directive & shellCompDirectiveFilterFileExt) != 0)); then\n        # File extension filtering\n        local fullFilter filter filteringCmd\n\n        # Do not use quotes around the $completions variable or else newline\n        # characters will be kept.\n        for filter in ${completions[*]}; do\n            fullFilter+=\"$filter|\"\n        done\n\n        filteringCmd=\"_filedir $fullFilter\"\n        __%[1]s_debug \"File filtering command: $filteringCmd\"\n        $filteringCmd\n    elif (((directive & shellCompDirectiveFilterDirs) != 0)); then\n        # File completion for directories only\n\n        local subdir\n        subdir=${completions[0]}\n        if [[ -n $subdir ]]; then\n            __%[1]s_debug \"Listing directories in $subdir\"\n            pushd \"$subdir\" >/dev/null 2>&1 && _filedir -d && popd >/dev/null 2>&1 || return\n        else\n            __%[1]s_debug \"Listing directories in .\"\n            _filedir -d\n        fi\n    else\n        __%[1]s_handle_completion_types\n    fi\n\n    __%[1]s_handle_special_char \"$cur\" :\n    __%[1]s_handle_special_char \"$cur\" =\n\n    # Print the activeHelp statements before we finish\n    if ((${#activeHelp[*]} != 0)); then\n        printf \"\\n\";\n        printf \"%%s\\n\" \"${activeHelp[@]}\"\n        printf \"\\n\"\n\n        # The prompt format is only available from bash 4.4.\n        # We test if it is available before using it.\n        if (x=${PS1@P}) 2> /dev/null; then\n            printf \"%%s\" \"${PS1@P}${COMP_LINE[@]}\"\n        else\n            # Can't print the prompt.  Just print the\n            # text the user had typed, it is workable enough.\n            printf \"%%s\" \"${COMP_LINE[@]}\"\n        fi\n    fi\n}\n\n# Separate activeHelp lines from real completions.\n# Fills the $activeHelp and $completions arrays.\n__%[1]s_extract_activeHelp() {\n    local activeHelpMarker=\"%[9]s\"\n    local endIndex=${#activeHelpMarker}\n\n    while IFS='' read -r comp; do\n        if [[ ${comp:0:endIndex} == $activeHelpMarker ]]; then\n            comp=${comp:endIndex}\n            __%[1]s_debug \"ActiveHelp found: $comp\"\n            if [[ -n $comp ]]; then\n                activeHelp+=(\"$comp\")\n            fi\n        else\n            # Not an activeHelp line but a normal completion\n            completions+=(\"$comp\")\n        fi\n    done <<<\"${out}\"\n}\n\n__%[1]s_handle_completion_types() {\n    __%[1]s_debug \"__%[1]s_handle_completion_types: COMP_TYPE is $COMP_TYPE\"\n\n    case $COMP_TYPE in\n    37|42)\n        # Type: menu-complete/menu-complete-backward and insert-completions\n        # If the user requested inserting one completion at a time, or all\n        # completions at once on the command-line we must remove the descriptions.\n        # https://github.com/spf13/cobra/issues/1508\n        local tab=$'\\t' comp\n        while IFS='' read -r comp; do\n            [[ -z $comp ]] && continue\n            # Strip any description\n            comp=${comp%%%%$tab*}\n            # Only consider the completions that match\n            if [[ $comp == \"$cur\"* ]]; then\n                COMPREPLY+=(\"$comp\")\n            fi\n        done < <(printf \"%%s\\n\" \"${completions[@]}\")\n        ;;\n\n    *)\n        # Type: complete (normal completion)\n        __%[1]s_handle_standard_completion_case\n        ;;\n    esac\n}\n\n__%[1]s_handle_standard_completion_case() {\n    local tab=$'\\t' comp\n\n    # Short circuit to optimize if we don't have descriptions\n    if [[ \"${completions[*]}\" != *$tab* ]]; then\n        IFS=$'\\n' read -ra COMPREPLY -d '' < <(compgen -W \"${completions[*]}\" -- \"$cur\")\n        return 0\n    fi\n\n    local longest=0\n    local compline\n    # Look for the longest completion so that we can format things nicely\n    while IFS='' read -r compline; do\n        [[ -z $compline ]] && continue\n        # Strip any description before checking the length\n        comp=${compline%%%%$tab*}\n        # Only consider the completions that match\n        [[ $comp == \"$cur\"* ]] || continue\n        COMPREPLY+=(\"$compline\")\n        if ((${#comp}>longest)); then\n            longest=${#comp}\n        fi\n    done < <(printf \"%%s\\n\" \"${completions[@]}\")\n\n    # If there is a single completion left, remove the description text\n    if ((${#COMPREPLY[*]} == 1)); then\n        __%[1]s_debug \"COMPREPLY[0]: ${COMPREPLY[0]}\"\n        comp=\"${COMPREPLY[0]%%%%$tab*}\"\n        __%[1]s_debug \"Removed description from single completion, which is now: ${comp}\"\n        COMPREPLY[0]=$comp\n    else # Format the descriptions\n        __%[1]s_format_comp_descriptions $longest\n    fi\n}\n\n__%[1]s_handle_special_char()\n{\n    local comp=\"$1\"\n    local char=$2\n    if [[ \"$comp\" == *${char}* && \"$COMP_WORDBREAKS\" == *${char}* ]]; then\n        local word=${comp%%\"${comp##*${char}}\"}\n        local idx=${#COMPREPLY[*]}\n        while ((--idx >= 0)); do\n            COMPREPLY[idx]=${COMPREPLY[idx]#\"$word\"}\n        done\n    fi\n}\n\n__%[1]s_format_comp_descriptions()\n{\n    local tab=$'\\t'\n    local comp desc maxdesclength\n    local longest=$1\n\n    local i ci\n    for ci in ${!COMPREPLY[*]}; do\n        comp=${COMPREPLY[ci]}\n        # Properly format the description string which follows a tab character if there is one\n        if [[ \"$comp\" == *$tab* ]]; then\n            __%[1]s_debug \"Original comp: $comp\"\n            desc=${comp#*$tab}\n            comp=${comp%%%%$tab*}\n\n            # $COLUMNS stores the current shell width.\n            # Remove an extra 4 because we add 2 spaces and 2 parentheses.\n            maxdesclength=$(( COLUMNS - longest - 4 ))\n\n            # Make sure we can fit a description of at least 8 characters\n            # if we are to align the descriptions.\n            if ((maxdesclength > 8)); then\n                # Add the proper number of spaces to align the descriptions\n                for ((i = ${#comp} ; i < longest ; i++)); do\n                    comp+=\" \"\n                done\n            else\n                # Don't pad the descriptions so we can fit more text after the completion\n                maxdesclength=$(( COLUMNS - ${#comp} - 4 ))\n            fi\n\n            # If there is enough space for any description text,\n            # truncate the descriptions that are too long for the shell width\n            if ((maxdesclength > 0)); then\n                if ((${#desc} > maxdesclength)); then\n                    desc=${desc:0:$(( maxdesclength - 1 ))}\n                    desc+=\"…\"\n                fi\n                comp+=\"  ($desc)\"\n            fi\n            COMPREPLY[ci]=$comp\n            __%[1]s_debug \"Final comp: $comp\"\n        fi\n    done\n}\n\n__start_%[1]s()\n{\n    local cur prev words cword split\n\n    COMPREPLY=()\n\n    # Call _init_completion from the bash-completion package\n    # to prepare the arguments properly\n    if declare -F _init_completion >/dev/null 2>&1; then\n        _init_completion -n =: || return\n    else\n        __%[1]s_init_completion -n =: || return\n    fi\n\n    __%[1]s_debug\n    __%[1]s_debug \"========= starting completion logic ==========\"\n    __%[1]s_debug \"cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword\"\n\n    # The user could have moved the cursor backwards on the command-line.\n    # We need to trigger completion from the $cword location, so we need\n    # to truncate the command-line ($words) up to the $cword location.\n    words=(\"${words[@]:0:$cword+1}\")\n    __%[1]s_debug \"Truncated words[*]: ${words[*]},\"\n\n    local out directive\n    __%[1]s_get_completion_results\n    __%[1]s_process_completion_results\n}\n\nif [[ $(type -t compopt) = \"builtin\" ]]; then\n    complete -o default -F __start_%[1]s %[1]s\nelse\n    complete -o default -o nospace -F __start_%[1]s %[1]s\nfi\n\n# ex: ts=4 sw=4 et filetype=sh\n`, name, compCmd,\n\t\tShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,\n\t\tShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,\n\t\tactiveHelpMarker))\n}\n\n// GenBashCompletionFileV2 generates Bash completion version 2.\nfunc (c *Command) GenBashCompletionFileV2(filename string, includeDesc bool) error {\n\toutFile, err := os.Create(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer outFile.Close()\n\n\treturn c.GenBashCompletionV2(outFile, includeDesc)\n}\n\n// GenBashCompletionV2 generates Bash completion file version 2\n// and writes it to the passed writer.\nfunc (c *Command) GenBashCompletionV2(w io.Writer, includeDesc bool) error {\n\treturn c.genBashCompletion(w, includeDesc)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/cobra.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\n// Commands similar to git, go tools and other modern CLI tools\n// inspired by go, go-Commander, gh and subcommand\n\npackage cobra\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"text/template\"\n\t\"time\"\n\t\"unicode\"\n)\n\nvar templateFuncs = template.FuncMap{\n\t\"trim\":                    strings.TrimSpace,\n\t\"trimRightSpace\":          trimRightSpace,\n\t\"trimTrailingWhitespaces\": trimRightSpace,\n\t\"appendIfNotPresent\":      appendIfNotPresent,\n\t\"rpad\":                    rpad,\n\t\"gt\":                      Gt,\n\t\"eq\":                      Eq,\n}\n\nvar initializers []func()\nvar finalizers []func()\n\nconst (\n\tdefaultPrefixMatching  = false\n\tdefaultCommandSorting  = true\n\tdefaultCaseInsensitive = false\n)\n\n// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing\n// to automatically enable in CLI tools.\n// Set this to true to enable it.\nvar EnablePrefixMatching = defaultPrefixMatching\n\n// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.\n// To disable sorting, set it to false.\nvar EnableCommandSorting = defaultCommandSorting\n\n// EnableCaseInsensitive allows case-insensitive commands names. (case sensitive by default)\nvar EnableCaseInsensitive = defaultCaseInsensitive\n\n// MousetrapHelpText enables an information splash screen on Windows\n// if the CLI is started from explorer.exe.\n// To disable the mousetrap, just set this variable to blank string (\"\").\n// Works only on Microsoft Windows.\nvar MousetrapHelpText = `This is a command line tool.\n\nYou need to open cmd.exe and run it from there.\n`\n\n// MousetrapDisplayDuration controls how long the MousetrapHelpText message is displayed on Windows\n// if the CLI is started from explorer.exe. Set to 0 to wait for the return key to be pressed.\n// To disable the mousetrap, just set MousetrapHelpText to blank string (\"\").\n// Works only on Microsoft Windows.\nvar MousetrapDisplayDuration = 5 * time.Second\n\n// AddTemplateFunc adds a template function that's available to Usage and Help\n// template generation.\nfunc AddTemplateFunc(name string, tmplFunc interface{}) {\n\ttemplateFuncs[name] = tmplFunc\n}\n\n// AddTemplateFuncs adds multiple template functions that are available to Usage and\n// Help template generation.\nfunc AddTemplateFuncs(tmplFuncs template.FuncMap) {\n\tfor k, v := range tmplFuncs {\n\t\ttemplateFuncs[k] = v\n\t}\n}\n\n// OnInitialize sets the passed functions to be run when each command's\n// Execute method is called.\nfunc OnInitialize(y ...func()) {\n\tinitializers = append(initializers, y...)\n}\n\n// OnFinalize sets the passed functions to be run when each command's\n// Execute method is terminated.\nfunc OnFinalize(y ...func()) {\n\tfinalizers = append(finalizers, y...)\n}\n\n// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.\n\n// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,\n// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as\n// ints and then compared.\nfunc Gt(a interface{}, b interface{}) bool {\n\tvar left, right int64\n\tav := reflect.ValueOf(a)\n\n\tswitch av.Kind() {\n\tcase reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:\n\t\tleft = int64(av.Len())\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tleft = av.Int()\n\tcase reflect.String:\n\t\tleft, _ = strconv.ParseInt(av.String(), 10, 64)\n\t}\n\n\tbv := reflect.ValueOf(b)\n\n\tswitch bv.Kind() {\n\tcase reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:\n\t\tright = int64(bv.Len())\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tright = bv.Int()\n\tcase reflect.String:\n\t\tright, _ = strconv.ParseInt(bv.String(), 10, 64)\n\t}\n\n\treturn left > right\n}\n\n// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.\n\n// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.\nfunc Eq(a interface{}, b interface{}) bool {\n\tav := reflect.ValueOf(a)\n\tbv := reflect.ValueOf(b)\n\n\tswitch av.Kind() {\n\tcase reflect.Array, reflect.Chan, reflect.Map, reflect.Slice:\n\t\tpanic(\"Eq called on unsupported type\")\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn av.Int() == bv.Int()\n\tcase reflect.String:\n\t\treturn av.String() == bv.String()\n\t}\n\treturn false\n}\n\nfunc trimRightSpace(s string) string {\n\treturn strings.TrimRightFunc(s, unicode.IsSpace)\n}\n\n// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.\n\n// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.\nfunc appendIfNotPresent(s, stringToAppend string) string {\n\tif strings.Contains(s, stringToAppend) {\n\t\treturn s\n\t}\n\treturn s + \" \" + stringToAppend\n}\n\n// rpad adds padding to the right of a string.\nfunc rpad(s string, padding int) string {\n\tformattedString := fmt.Sprintf(\"%%-%ds\", padding)\n\treturn fmt.Sprintf(formattedString, s)\n}\n\n// tmpl executes the given template text on data, writing the result to w.\nfunc tmpl(w io.Writer, text string, data interface{}) error {\n\tt := template.New(\"top\")\n\tt.Funcs(templateFuncs)\n\ttemplate.Must(t.Parse(text))\n\treturn t.Execute(w, data)\n}\n\n// ld compares two strings and returns the levenshtein distance between them.\nfunc ld(s, t string, ignoreCase bool) int {\n\tif ignoreCase {\n\t\ts = strings.ToLower(s)\n\t\tt = strings.ToLower(t)\n\t}\n\td := make([][]int, len(s)+1)\n\tfor i := range d {\n\t\td[i] = make([]int, len(t)+1)\n\t}\n\tfor i := range d {\n\t\td[i][0] = i\n\t}\n\tfor j := range d[0] {\n\t\td[0][j] = j\n\t}\n\tfor j := 1; j <= len(t); j++ {\n\t\tfor i := 1; i <= len(s); i++ {\n\t\t\tif s[i-1] == t[j-1] {\n\t\t\t\td[i][j] = d[i-1][j-1]\n\t\t\t} else {\n\t\t\t\tmin := d[i-1][j]\n\t\t\t\tif d[i][j-1] < min {\n\t\t\t\t\tmin = d[i][j-1]\n\t\t\t\t}\n\t\t\t\tif d[i-1][j-1] < min {\n\t\t\t\t\tmin = d[i-1][j-1]\n\t\t\t\t}\n\t\t\t\td[i][j] = min + 1\n\t\t\t}\n\t\t}\n\n\t}\n\treturn d[len(s)][len(t)]\n}\n\nfunc stringInSlice(a string, list []string) bool {\n\tfor _, b := range list {\n\t\tif b == a {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// CheckErr prints the msg with the prefix 'Error:' and exits with error code 1. If the msg is nil, it does nothing.\nfunc CheckErr(msg interface{}) {\n\tif msg != nil {\n\t\tfmt.Fprintln(os.Stderr, \"Error:\", msg)\n\t\tos.Exit(1)\n\t}\n}\n\n// WriteStringAndCheck writes a string into a buffer, and checks if the error is not nil.\nfunc WriteStringAndCheck(b io.StringWriter, s string) {\n\t_, err := b.WriteString(s)\n\tCheckErr(err)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/command.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\n// Package cobra is a commander providing a simple interface to create powerful modern CLI interfaces.\n// In addition to providing an interface, Cobra simultaneously provides a controller to organize your application code.\npackage cobra\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"sort\"\n\t\"strings\"\n\n\tflag \"github.com/spf13/pflag\"\n)\n\nconst FlagSetByCobraAnnotation = \"cobra_annotation_flag_set_by_cobra\"\n\n// FParseErrWhitelist configures Flag parse errors to be ignored\ntype FParseErrWhitelist flag.ParseErrorsWhitelist\n\n// Group Structure to manage groups for commands\ntype Group struct {\n\tID    string\n\tTitle string\n}\n\n// Command is just that, a command for your application.\n// E.g.  'go run ...' - 'run' is the command. Cobra requires\n// you to define the usage and description as part of your command\n// definition to ensure usability.\ntype Command struct {\n\t// Use is the one-line usage message.\n\t// Recommended syntax is as follows:\n\t//   [ ] identifies an optional argument. Arguments that are not enclosed in brackets are required.\n\t//   ... indicates that you can specify multiple values for the previous argument.\n\t//   |   indicates mutually exclusive information. You can use the argument to the left of the separator or the\n\t//       argument to the right of the separator. You cannot use both arguments in a single use of the command.\n\t//   { } delimits a set of mutually exclusive arguments when one of the arguments is required. If the arguments are\n\t//       optional, they are enclosed in brackets ([ ]).\n\t// Example: add [-F file | -D dir]... [-f format] profile\n\tUse string\n\n\t// Aliases is an array of aliases that can be used instead of the first word in Use.\n\tAliases []string\n\n\t// SuggestFor is an array of command names for which this command will be suggested -\n\t// similar to aliases but only suggests.\n\tSuggestFor []string\n\n\t// Short is the short description shown in the 'help' output.\n\tShort string\n\n\t// The group id under which this subcommand is grouped in the 'help' output of its parent.\n\tGroupID string\n\n\t// Long is the long message shown in the 'help <this-command>' output.\n\tLong string\n\n\t// Example is examples of how to use the command.\n\tExample string\n\n\t// ValidArgs is list of all valid non-flag arguments that are accepted in shell completions\n\tValidArgs []string\n\t// ValidArgsFunction is an optional function that provides valid non-flag arguments for shell completion.\n\t// It is a dynamic version of using ValidArgs.\n\t// Only one of ValidArgs and ValidArgsFunction can be used for a command.\n\tValidArgsFunction func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)\n\n\t// Expected arguments\n\tArgs PositionalArgs\n\n\t// ArgAliases is List of aliases for ValidArgs.\n\t// These are not suggested to the user in the shell completion,\n\t// but accepted if entered manually.\n\tArgAliases []string\n\n\t// BashCompletionFunction is custom bash functions used by the legacy bash autocompletion generator.\n\t// For portability with other shells, it is recommended to instead use ValidArgsFunction\n\tBashCompletionFunction string\n\n\t// Deprecated defines, if this command is deprecated and should print this string when used.\n\tDeprecated string\n\n\t// Annotations are key/value pairs that can be used by applications to identify or\n\t// group commands.\n\tAnnotations map[string]string\n\n\t// Version defines the version for this command. If this value is non-empty and the command does not\n\t// define a \"version\" flag, a \"version\" boolean flag will be added to the command and, if specified,\n\t// will print content of the \"Version\" variable. A shorthand \"v\" flag will also be added if the\n\t// command does not define one.\n\tVersion string\n\n\t// The *Run functions are executed in the following order:\n\t//   * PersistentPreRun()\n\t//   * PreRun()\n\t//   * Run()\n\t//   * PostRun()\n\t//   * PersistentPostRun()\n\t// All functions get the same args, the arguments after the command name.\n\t//\n\t// PersistentPreRun: children of this command will inherit and execute.\n\tPersistentPreRun func(cmd *Command, args []string)\n\t// PersistentPreRunE: PersistentPreRun but returns an error.\n\tPersistentPreRunE func(cmd *Command, args []string) error\n\t// PreRun: children of this command will not inherit.\n\tPreRun func(cmd *Command, args []string)\n\t// PreRunE: PreRun but returns an error.\n\tPreRunE func(cmd *Command, args []string) error\n\t// Run: Typically the actual work function. Most commands will only implement this.\n\tRun func(cmd *Command, args []string)\n\t// RunE: Run but returns an error.\n\tRunE func(cmd *Command, args []string) error\n\t// PostRun: run after the Run command.\n\tPostRun func(cmd *Command, args []string)\n\t// PostRunE: PostRun but returns an error.\n\tPostRunE func(cmd *Command, args []string) error\n\t// PersistentPostRun: children of this command will inherit and execute after PostRun.\n\tPersistentPostRun func(cmd *Command, args []string)\n\t// PersistentPostRunE: PersistentPostRun but returns an error.\n\tPersistentPostRunE func(cmd *Command, args []string) error\n\n\t// groups for subcommands\n\tcommandgroups []*Group\n\n\t// args is actual args parsed from flags.\n\targs []string\n\t// flagErrorBuf contains all error messages from pflag.\n\tflagErrorBuf *bytes.Buffer\n\t// flags is full set of flags.\n\tflags *flag.FlagSet\n\t// pflags contains persistent flags.\n\tpflags *flag.FlagSet\n\t// lflags contains local flags.\n\tlflags *flag.FlagSet\n\t// iflags contains inherited flags.\n\tiflags *flag.FlagSet\n\t// parentsPflags is all persistent flags of cmd's parents.\n\tparentsPflags *flag.FlagSet\n\t// globNormFunc is the global normalization function\n\t// that we can use on every pflag set and children commands\n\tglobNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName\n\n\t// usageFunc is usage func defined by user.\n\tusageFunc func(*Command) error\n\t// usageTemplate is usage template defined by user.\n\tusageTemplate string\n\t// flagErrorFunc is func defined by user and it's called when the parsing of\n\t// flags returns an error.\n\tflagErrorFunc func(*Command, error) error\n\t// helpTemplate is help template defined by user.\n\thelpTemplate string\n\t// helpFunc is help func defined by user.\n\thelpFunc func(*Command, []string)\n\t// helpCommand is command with usage 'help'. If it's not defined by user,\n\t// cobra uses default help command.\n\thelpCommand *Command\n\t// helpCommandGroupID is the group id for the helpCommand\n\thelpCommandGroupID string\n\n\t// completionCommandGroupID is the group id for the completion command\n\tcompletionCommandGroupID string\n\n\t// versionTemplate is the version template defined by user.\n\tversionTemplate string\n\n\t// inReader is a reader defined by the user that replaces stdin\n\tinReader io.Reader\n\t// outWriter is a writer defined by the user that replaces stdout\n\toutWriter io.Writer\n\t// errWriter is a writer defined by the user that replaces stderr\n\terrWriter io.Writer\n\n\t// FParseErrWhitelist flag parse errors to be ignored\n\tFParseErrWhitelist FParseErrWhitelist\n\n\t// CompletionOptions is a set of options to control the handling of shell completion\n\tCompletionOptions CompletionOptions\n\n\t// commandsAreSorted defines, if command slice are sorted or not.\n\tcommandsAreSorted bool\n\t// commandCalledAs is the name or alias value used to call this command.\n\tcommandCalledAs struct {\n\t\tname   string\n\t\tcalled bool\n\t}\n\n\tctx context.Context\n\n\t// commands is the list of commands supported by this program.\n\tcommands []*Command\n\t// parent is a parent command for this command.\n\tparent *Command\n\t// Max lengths of commands' string lengths for use in padding.\n\tcommandsMaxUseLen         int\n\tcommandsMaxCommandPathLen int\n\tcommandsMaxNameLen        int\n\n\t// TraverseChildren parses flags on all parents before executing child command.\n\tTraverseChildren bool\n\n\t// Hidden defines, if this command is hidden and should NOT show up in the list of available commands.\n\tHidden bool\n\n\t// SilenceErrors is an option to quiet errors down stream.\n\tSilenceErrors bool\n\n\t// SilenceUsage is an option to silence usage when an error occurs.\n\tSilenceUsage bool\n\n\t// DisableFlagParsing disables the flag parsing.\n\t// If this is true all flags will be passed to the command as arguments.\n\tDisableFlagParsing bool\n\n\t// DisableAutoGenTag defines, if gen tag (\"Auto generated by spf13/cobra...\")\n\t// will be printed by generating docs for this command.\n\tDisableAutoGenTag bool\n\n\t// DisableFlagsInUseLine will disable the addition of [flags] to the usage\n\t// line of a command when printing help or generating docs\n\tDisableFlagsInUseLine bool\n\n\t// DisableSuggestions disables the suggestions based on Levenshtein distance\n\t// that go along with 'unknown command' messages.\n\tDisableSuggestions bool\n\n\t// SuggestionsMinimumDistance defines minimum levenshtein distance to display suggestions.\n\t// Must be > 0.\n\tSuggestionsMinimumDistance int\n}\n\n// Context returns underlying command context. If command was executed\n// with ExecuteContext or the context was set with SetContext, the\n// previously set context will be returned. Otherwise, nil is returned.\n//\n// Notice that a call to Execute and ExecuteC will replace a nil context of\n// a command with a context.Background, so a background context will be\n// returned by Context after one of these functions has been called.\nfunc (c *Command) Context() context.Context {\n\treturn c.ctx\n}\n\n// SetContext sets context for the command. This context will be overwritten by\n// Command.ExecuteContext or Command.ExecuteContextC.\nfunc (c *Command) SetContext(ctx context.Context) {\n\tc.ctx = ctx\n}\n\n// SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden\n// particularly useful when testing.\nfunc (c *Command) SetArgs(a []string) {\n\tc.args = a\n}\n\n// SetOutput sets the destination for usage and error messages.\n// If output is nil, os.Stderr is used.\n// Deprecated: Use SetOut and/or SetErr instead\nfunc (c *Command) SetOutput(output io.Writer) {\n\tc.outWriter = output\n\tc.errWriter = output\n}\n\n// SetOut sets the destination for usage messages.\n// If newOut is nil, os.Stdout is used.\nfunc (c *Command) SetOut(newOut io.Writer) {\n\tc.outWriter = newOut\n}\n\n// SetErr sets the destination for error messages.\n// If newErr is nil, os.Stderr is used.\nfunc (c *Command) SetErr(newErr io.Writer) {\n\tc.errWriter = newErr\n}\n\n// SetIn sets the source for input data\n// If newIn is nil, os.Stdin is used.\nfunc (c *Command) SetIn(newIn io.Reader) {\n\tc.inReader = newIn\n}\n\n// SetUsageFunc sets usage function. Usage can be defined by application.\nfunc (c *Command) SetUsageFunc(f func(*Command) error) {\n\tc.usageFunc = f\n}\n\n// SetUsageTemplate sets usage template. Can be defined by Application.\nfunc (c *Command) SetUsageTemplate(s string) {\n\tc.usageTemplate = s\n}\n\n// SetFlagErrorFunc sets a function to generate an error when flag parsing\n// fails.\nfunc (c *Command) SetFlagErrorFunc(f func(*Command, error) error) {\n\tc.flagErrorFunc = f\n}\n\n// SetHelpFunc sets help function. Can be defined by Application.\nfunc (c *Command) SetHelpFunc(f func(*Command, []string)) {\n\tc.helpFunc = f\n}\n\n// SetHelpCommand sets help command.\nfunc (c *Command) SetHelpCommand(cmd *Command) {\n\tc.helpCommand = cmd\n}\n\n// SetHelpCommandGroupID sets the group id of the help command.\nfunc (c *Command) SetHelpCommandGroupID(groupID string) {\n\tif c.helpCommand != nil {\n\t\tc.helpCommand.GroupID = groupID\n\t}\n\t// helpCommandGroupID is used if no helpCommand is defined by the user\n\tc.helpCommandGroupID = groupID\n}\n\n// SetCompletionCommandGroupID sets the group id of the completion command.\nfunc (c *Command) SetCompletionCommandGroupID(groupID string) {\n\t// completionCommandGroupID is used if no completion command is defined by the user\n\tc.Root().completionCommandGroupID = groupID\n}\n\n// SetHelpTemplate sets help template to be used. Application can use it to set custom template.\nfunc (c *Command) SetHelpTemplate(s string) {\n\tc.helpTemplate = s\n}\n\n// SetVersionTemplate sets version template to be used. Application can use it to set custom template.\nfunc (c *Command) SetVersionTemplate(s string) {\n\tc.versionTemplate = s\n}\n\n// SetGlobalNormalizationFunc sets a normalization function to all flag sets and also to child commands.\n// The user should not have a cyclic dependency on commands.\nfunc (c *Command) SetGlobalNormalizationFunc(n func(f *flag.FlagSet, name string) flag.NormalizedName) {\n\tc.Flags().SetNormalizeFunc(n)\n\tc.PersistentFlags().SetNormalizeFunc(n)\n\tc.globNormFunc = n\n\n\tfor _, command := range c.commands {\n\t\tcommand.SetGlobalNormalizationFunc(n)\n\t}\n}\n\n// OutOrStdout returns output to stdout.\nfunc (c *Command) OutOrStdout() io.Writer {\n\treturn c.getOut(os.Stdout)\n}\n\n// OutOrStderr returns output to stderr\nfunc (c *Command) OutOrStderr() io.Writer {\n\treturn c.getOut(os.Stderr)\n}\n\n// ErrOrStderr returns output to stderr\nfunc (c *Command) ErrOrStderr() io.Writer {\n\treturn c.getErr(os.Stderr)\n}\n\n// InOrStdin returns input to stdin\nfunc (c *Command) InOrStdin() io.Reader {\n\treturn c.getIn(os.Stdin)\n}\n\nfunc (c *Command) getOut(def io.Writer) io.Writer {\n\tif c.outWriter != nil {\n\t\treturn c.outWriter\n\t}\n\tif c.HasParent() {\n\t\treturn c.parent.getOut(def)\n\t}\n\treturn def\n}\n\nfunc (c *Command) getErr(def io.Writer) io.Writer {\n\tif c.errWriter != nil {\n\t\treturn c.errWriter\n\t}\n\tif c.HasParent() {\n\t\treturn c.parent.getErr(def)\n\t}\n\treturn def\n}\n\nfunc (c *Command) getIn(def io.Reader) io.Reader {\n\tif c.inReader != nil {\n\t\treturn c.inReader\n\t}\n\tif c.HasParent() {\n\t\treturn c.parent.getIn(def)\n\t}\n\treturn def\n}\n\n// UsageFunc returns either the function set by SetUsageFunc for this command\n// or a parent, or it returns a default usage function.\nfunc (c *Command) UsageFunc() (f func(*Command) error) {\n\tif c.usageFunc != nil {\n\t\treturn c.usageFunc\n\t}\n\tif c.HasParent() {\n\t\treturn c.Parent().UsageFunc()\n\t}\n\treturn func(c *Command) error {\n\t\tc.mergePersistentFlags()\n\t\terr := tmpl(c.OutOrStderr(), c.UsageTemplate(), c)\n\t\tif err != nil {\n\t\t\tc.PrintErrln(err)\n\t\t}\n\t\treturn err\n\t}\n}\n\n// Usage puts out the usage for the command.\n// Used when a user provides invalid input.\n// Can be defined by user by overriding UsageFunc.\nfunc (c *Command) Usage() error {\n\treturn c.UsageFunc()(c)\n}\n\n// HelpFunc returns either the function set by SetHelpFunc for this command\n// or a parent, or it returns a function with default help behavior.\nfunc (c *Command) HelpFunc() func(*Command, []string) {\n\tif c.helpFunc != nil {\n\t\treturn c.helpFunc\n\t}\n\tif c.HasParent() {\n\t\treturn c.Parent().HelpFunc()\n\t}\n\treturn func(c *Command, a []string) {\n\t\tc.mergePersistentFlags()\n\t\t// The help should be sent to stdout\n\t\t// See https://github.com/spf13/cobra/issues/1002\n\t\terr := tmpl(c.OutOrStdout(), c.HelpTemplate(), c)\n\t\tif err != nil {\n\t\t\tc.PrintErrln(err)\n\t\t}\n\t}\n}\n\n// Help puts out the help for the command.\n// Used when a user calls help [command].\n// Can be defined by user by overriding HelpFunc.\nfunc (c *Command) Help() error {\n\tc.HelpFunc()(c, []string{})\n\treturn nil\n}\n\n// UsageString returns usage string.\nfunc (c *Command) UsageString() string {\n\t// Storing normal writers\n\ttmpOutput := c.outWriter\n\ttmpErr := c.errWriter\n\n\tbb := new(bytes.Buffer)\n\tc.outWriter = bb\n\tc.errWriter = bb\n\n\tCheckErr(c.Usage())\n\n\t// Setting things back to normal\n\tc.outWriter = tmpOutput\n\tc.errWriter = tmpErr\n\n\treturn bb.String()\n}\n\n// FlagErrorFunc returns either the function set by SetFlagErrorFunc for this\n// command or a parent, or it returns a function which returns the original\n// error.\nfunc (c *Command) FlagErrorFunc() (f func(*Command, error) error) {\n\tif c.flagErrorFunc != nil {\n\t\treturn c.flagErrorFunc\n\t}\n\n\tif c.HasParent() {\n\t\treturn c.parent.FlagErrorFunc()\n\t}\n\treturn func(c *Command, err error) error {\n\t\treturn err\n\t}\n}\n\nvar minUsagePadding = 25\n\n// UsagePadding return padding for the usage.\nfunc (c *Command) UsagePadding() int {\n\tif c.parent == nil || minUsagePadding > c.parent.commandsMaxUseLen {\n\t\treturn minUsagePadding\n\t}\n\treturn c.parent.commandsMaxUseLen\n}\n\nvar minCommandPathPadding = 11\n\n// CommandPathPadding return padding for the command path.\nfunc (c *Command) CommandPathPadding() int {\n\tif c.parent == nil || minCommandPathPadding > c.parent.commandsMaxCommandPathLen {\n\t\treturn minCommandPathPadding\n\t}\n\treturn c.parent.commandsMaxCommandPathLen\n}\n\nvar minNamePadding = 11\n\n// NamePadding returns padding for the name.\nfunc (c *Command) NamePadding() int {\n\tif c.parent == nil || minNamePadding > c.parent.commandsMaxNameLen {\n\t\treturn minNamePadding\n\t}\n\treturn c.parent.commandsMaxNameLen\n}\n\n// UsageTemplate returns usage template for the command.\nfunc (c *Command) UsageTemplate() string {\n\tif c.usageTemplate != \"\" {\n\t\treturn c.usageTemplate\n\t}\n\n\tif c.HasParent() {\n\t\treturn c.parent.UsageTemplate()\n\t}\n\treturn `Usage:{{if .Runnable}}\n  {{.UseLine}}{{end}}{{if .HasAvailableSubCommands}}\n  {{.CommandPath}} [command]{{end}}{{if gt (len .Aliases) 0}}\n\nAliases:\n  {{.NameAndAliases}}{{end}}{{if .HasExample}}\n\nExamples:\n{{.Example}}{{end}}{{if .HasAvailableSubCommands}}{{$cmds := .Commands}}{{if eq (len .Groups) 0}}\n\nAvailable Commands:{{range $cmds}}{{if (or .IsAvailableCommand (eq .Name \"help\"))}}\n  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{else}}{{range $group := .Groups}}\n\n{{.Title}}{{range $cmds}}{{if (and (eq .GroupID $group.ID) (or .IsAvailableCommand (eq .Name \"help\")))}}\n  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if not .AllChildCommandsHaveGroup}}\n\nAdditional Commands:{{range $cmds}}{{if (and (eq .GroupID \"\") (or .IsAvailableCommand (eq .Name \"help\")))}}\n  {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}}\n\nFlags:\n{{.LocalFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}}\n\nGlobal Flags:\n{{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}}\n\nAdditional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}\n  {{rpad .CommandPath .CommandPathPadding}} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableSubCommands}}\n\nUse \"{{.CommandPath}} [command] --help\" for more information about a command.{{end}}\n`\n}\n\n// HelpTemplate return help template for the command.\nfunc (c *Command) HelpTemplate() string {\n\tif c.helpTemplate != \"\" {\n\t\treturn c.helpTemplate\n\t}\n\n\tif c.HasParent() {\n\t\treturn c.parent.HelpTemplate()\n\t}\n\treturn `{{with (or .Long .Short)}}{{. | trimTrailingWhitespaces}}\n\n{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}`\n}\n\n// VersionTemplate return version template for the command.\nfunc (c *Command) VersionTemplate() string {\n\tif c.versionTemplate != \"\" {\n\t\treturn c.versionTemplate\n\t}\n\n\tif c.HasParent() {\n\t\treturn c.parent.VersionTemplate()\n\t}\n\treturn `{{with .Name}}{{printf \"%s \" .}}{{end}}{{printf \"version %s\" .Version}}\n`\n}\n\nfunc hasNoOptDefVal(name string, fs *flag.FlagSet) bool {\n\tflag := fs.Lookup(name)\n\tif flag == nil {\n\t\treturn false\n\t}\n\treturn flag.NoOptDefVal != \"\"\n}\n\nfunc shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {\n\tif len(name) == 0 {\n\t\treturn false\n\t}\n\n\tflag := fs.ShorthandLookup(name[:1])\n\tif flag == nil {\n\t\treturn false\n\t}\n\treturn flag.NoOptDefVal != \"\"\n}\n\nfunc stripFlags(args []string, c *Command) []string {\n\tif len(args) == 0 {\n\t\treturn args\n\t}\n\tc.mergePersistentFlags()\n\n\tcommands := []string{}\n\tflags := c.Flags()\n\nLoop:\n\tfor len(args) > 0 {\n\t\ts := args[0]\n\t\targs = args[1:]\n\t\tswitch {\n\t\tcase s == \"--\":\n\t\t\t// \"--\" terminates the flags\n\t\t\tbreak Loop\n\t\tcase strings.HasPrefix(s, \"--\") && !strings.Contains(s, \"=\") && !hasNoOptDefVal(s[2:], flags):\n\t\t\t// If '--flag arg' then\n\t\t\t// delete arg from args.\n\t\t\tfallthrough // (do the same as below)\n\t\tcase strings.HasPrefix(s, \"-\") && !strings.Contains(s, \"=\") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):\n\t\t\t// If '-f arg' then\n\t\t\t// delete 'arg' from args or break the loop if len(args) <= 1.\n\t\t\tif len(args) <= 1 {\n\t\t\t\tbreak Loop\n\t\t\t} else {\n\t\t\t\targs = args[1:]\n\t\t\t\tcontinue\n\t\t\t}\n\t\tcase s != \"\" && !strings.HasPrefix(s, \"-\"):\n\t\t\tcommands = append(commands, s)\n\t\t}\n\t}\n\n\treturn commands\n}\n\n// argsMinusFirstX removes only the first x from args.  Otherwise, commands that look like\n// openshift admin policy add-role-to-user admin my-user, lose the admin argument (arg[4]).\n// Special care needs to be taken not to remove a flag value.\nfunc (c *Command) argsMinusFirstX(args []string, x string) []string {\n\tif len(args) == 0 {\n\t\treturn args\n\t}\n\tc.mergePersistentFlags()\n\tflags := c.Flags()\n\nLoop:\n\tfor pos := 0; pos < len(args); pos++ {\n\t\ts := args[pos]\n\t\tswitch {\n\t\tcase s == \"--\":\n\t\t\t// -- means we have reached the end of the parseable args. Break out of the loop now.\n\t\t\tbreak Loop\n\t\tcase strings.HasPrefix(s, \"--\") && !strings.Contains(s, \"=\") && !hasNoOptDefVal(s[2:], flags):\n\t\t\tfallthrough\n\t\tcase strings.HasPrefix(s, \"-\") && !strings.Contains(s, \"=\") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags):\n\t\t\t// This is a flag without a default value, and an equal sign is not used. Increment pos in order to skip\n\t\t\t// over the next arg, because that is the value of this flag.\n\t\t\tpos++\n\t\t\tcontinue\n\t\tcase !strings.HasPrefix(s, \"-\"):\n\t\t\t// This is not a flag or a flag value. Check to see if it matches what we're looking for, and if so,\n\t\t\t// return the args, excluding the one at this position.\n\t\t\tif s == x {\n\t\t\t\tret := []string{}\n\t\t\t\tret = append(ret, args[:pos]...)\n\t\t\t\tret = append(ret, args[pos+1:]...)\n\t\t\t\treturn ret\n\t\t\t}\n\t\t}\n\t}\n\treturn args\n}\n\nfunc isFlagArg(arg string) bool {\n\treturn ((len(arg) >= 3 && arg[0:2] == \"--\") ||\n\t\t(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))\n}\n\n// Find the target command given the args and command tree\n// Meant to be run on the highest node. Only searches down.\nfunc (c *Command) Find(args []string) (*Command, []string, error) {\n\tvar innerfind func(*Command, []string) (*Command, []string)\n\n\tinnerfind = func(c *Command, innerArgs []string) (*Command, []string) {\n\t\targsWOflags := stripFlags(innerArgs, c)\n\t\tif len(argsWOflags) == 0 {\n\t\t\treturn c, innerArgs\n\t\t}\n\t\tnextSubCmd := argsWOflags[0]\n\n\t\tcmd := c.findNext(nextSubCmd)\n\t\tif cmd != nil {\n\t\t\treturn innerfind(cmd, c.argsMinusFirstX(innerArgs, nextSubCmd))\n\t\t}\n\t\treturn c, innerArgs\n\t}\n\n\tcommandFound, a := innerfind(c, args)\n\tif commandFound.Args == nil {\n\t\treturn commandFound, a, legacyArgs(commandFound, stripFlags(a, commandFound))\n\t}\n\treturn commandFound, a, nil\n}\n\nfunc (c *Command) findSuggestions(arg string) string {\n\tif c.DisableSuggestions {\n\t\treturn \"\"\n\t}\n\tif c.SuggestionsMinimumDistance <= 0 {\n\t\tc.SuggestionsMinimumDistance = 2\n\t}\n\tsuggestionsString := \"\"\n\tif suggestions := c.SuggestionsFor(arg); len(suggestions) > 0 {\n\t\tsuggestionsString += \"\\n\\nDid you mean this?\\n\"\n\t\tfor _, s := range suggestions {\n\t\t\tsuggestionsString += fmt.Sprintf(\"\\t%v\\n\", s)\n\t\t}\n\t}\n\treturn suggestionsString\n}\n\nfunc (c *Command) findNext(next string) *Command {\n\tmatches := make([]*Command, 0)\n\tfor _, cmd := range c.commands {\n\t\tif commandNameMatches(cmd.Name(), next) || cmd.HasAlias(next) {\n\t\t\tcmd.commandCalledAs.name = next\n\t\t\treturn cmd\n\t\t}\n\t\tif EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {\n\t\t\tmatches = append(matches, cmd)\n\t\t}\n\t}\n\n\tif len(matches) == 1 {\n\t\treturn matches[0]\n\t}\n\n\treturn nil\n}\n\n// Traverse the command tree to find the command, and parse args for\n// each parent.\nfunc (c *Command) Traverse(args []string) (*Command, []string, error) {\n\tflags := []string{}\n\tinFlag := false\n\n\tfor i, arg := range args {\n\t\tswitch {\n\t\t// A long flag with a space separated value\n\t\tcase strings.HasPrefix(arg, \"--\") && !strings.Contains(arg, \"=\"):\n\t\t\t// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'\n\t\t\tinFlag = !hasNoOptDefVal(arg[2:], c.Flags())\n\t\t\tflags = append(flags, arg)\n\t\t\tcontinue\n\t\t// A short flag with a space separated value\n\t\tcase strings.HasPrefix(arg, \"-\") && !strings.Contains(arg, \"=\") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):\n\t\t\tinFlag = true\n\t\t\tflags = append(flags, arg)\n\t\t\tcontinue\n\t\t// The value for a flag\n\t\tcase inFlag:\n\t\t\tinFlag = false\n\t\t\tflags = append(flags, arg)\n\t\t\tcontinue\n\t\t// A flag without a value, or with an `=` separated value\n\t\tcase isFlagArg(arg):\n\t\t\tflags = append(flags, arg)\n\t\t\tcontinue\n\t\t}\n\n\t\tcmd := c.findNext(arg)\n\t\tif cmd == nil {\n\t\t\treturn c, args, nil\n\t\t}\n\n\t\tif err := c.ParseFlags(flags); err != nil {\n\t\t\treturn nil, args, err\n\t\t}\n\t\treturn cmd.Traverse(args[i+1:])\n\t}\n\treturn c, args, nil\n}\n\n// SuggestionsFor provides suggestions for the typedName.\nfunc (c *Command) SuggestionsFor(typedName string) []string {\n\tsuggestions := []string{}\n\tfor _, cmd := range c.commands {\n\t\tif cmd.IsAvailableCommand() {\n\t\t\tlevenshteinDistance := ld(typedName, cmd.Name(), true)\n\t\t\tsuggestByLevenshtein := levenshteinDistance <= c.SuggestionsMinimumDistance\n\t\t\tsuggestByPrefix := strings.HasPrefix(strings.ToLower(cmd.Name()), strings.ToLower(typedName))\n\t\t\tif suggestByLevenshtein || suggestByPrefix {\n\t\t\t\tsuggestions = append(suggestions, cmd.Name())\n\t\t\t}\n\t\t\tfor _, explicitSuggestion := range cmd.SuggestFor {\n\t\t\t\tif strings.EqualFold(typedName, explicitSuggestion) {\n\t\t\t\t\tsuggestions = append(suggestions, cmd.Name())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn suggestions\n}\n\n// VisitParents visits all parents of the command and invokes fn on each parent.\nfunc (c *Command) VisitParents(fn func(*Command)) {\n\tif c.HasParent() {\n\t\tfn(c.Parent())\n\t\tc.Parent().VisitParents(fn)\n\t}\n}\n\n// Root finds root command.\nfunc (c *Command) Root() *Command {\n\tif c.HasParent() {\n\t\treturn c.Parent().Root()\n\t}\n\treturn c\n}\n\n// ArgsLenAtDash will return the length of c.Flags().Args at the moment\n// when a -- was found during args parsing.\nfunc (c *Command) ArgsLenAtDash() int {\n\treturn c.Flags().ArgsLenAtDash()\n}\n\nfunc (c *Command) execute(a []string) (err error) {\n\tif c == nil {\n\t\treturn fmt.Errorf(\"Called Execute() on a nil Command\")\n\t}\n\n\tif len(c.Deprecated) > 0 {\n\t\tc.Printf(\"Command %q is deprecated, %s\\n\", c.Name(), c.Deprecated)\n\t}\n\n\t// initialize help and version flag at the last point possible to allow for user\n\t// overriding\n\tc.InitDefaultHelpFlag()\n\tc.InitDefaultVersionFlag()\n\n\terr = c.ParseFlags(a)\n\tif err != nil {\n\t\treturn c.FlagErrorFunc()(c, err)\n\t}\n\n\t// If help is called, regardless of other flags, return we want help.\n\t// Also say we need help if the command isn't runnable.\n\thelpVal, err := c.Flags().GetBool(\"help\")\n\tif err != nil {\n\t\t// should be impossible to get here as we always declare a help\n\t\t// flag in InitDefaultHelpFlag()\n\t\tc.Println(\"\\\"help\\\" flag declared as non-bool. Please correct your code\")\n\t\treturn err\n\t}\n\n\tif helpVal {\n\t\treturn flag.ErrHelp\n\t}\n\n\t// for back-compat, only add version flag behavior if version is defined\n\tif c.Version != \"\" {\n\t\tversionVal, err := c.Flags().GetBool(\"version\")\n\t\tif err != nil {\n\t\t\tc.Println(\"\\\"version\\\" flag declared as non-bool. Please correct your code\")\n\t\t\treturn err\n\t\t}\n\t\tif versionVal {\n\t\t\terr := tmpl(c.OutOrStdout(), c.VersionTemplate(), c)\n\t\t\tif err != nil {\n\t\t\t\tc.Println(err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif !c.Runnable() {\n\t\treturn flag.ErrHelp\n\t}\n\n\tc.preRun()\n\n\tdefer c.postRun()\n\n\targWoFlags := c.Flags().Args()\n\tif c.DisableFlagParsing {\n\t\targWoFlags = a\n\t}\n\n\tif err := c.ValidateArgs(argWoFlags); err != nil {\n\t\treturn err\n\t}\n\n\tfor p := c; p != nil; p = p.Parent() {\n\t\tif p.PersistentPreRunE != nil {\n\t\t\tif err := p.PersistentPreRunE(c, argWoFlags); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tbreak\n\t\t} else if p.PersistentPreRun != nil {\n\t\t\tp.PersistentPreRun(c, argWoFlags)\n\t\t\tbreak\n\t\t}\n\t}\n\tif c.PreRunE != nil {\n\t\tif err := c.PreRunE(c, argWoFlags); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if c.PreRun != nil {\n\t\tc.PreRun(c, argWoFlags)\n\t}\n\n\tif err := c.ValidateRequiredFlags(); err != nil {\n\t\treturn err\n\t}\n\tif err := c.ValidateFlagGroups(); err != nil {\n\t\treturn err\n\t}\n\n\tif c.RunE != nil {\n\t\tif err := c.RunE(c, argWoFlags); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tc.Run(c, argWoFlags)\n\t}\n\tif c.PostRunE != nil {\n\t\tif err := c.PostRunE(c, argWoFlags); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if c.PostRun != nil {\n\t\tc.PostRun(c, argWoFlags)\n\t}\n\tfor p := c; p != nil; p = p.Parent() {\n\t\tif p.PersistentPostRunE != nil {\n\t\t\tif err := p.PersistentPostRunE(c, argWoFlags); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tbreak\n\t\t} else if p.PersistentPostRun != nil {\n\t\t\tp.PersistentPostRun(c, argWoFlags)\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (c *Command) preRun() {\n\tfor _, x := range initializers {\n\t\tx()\n\t}\n}\n\nfunc (c *Command) postRun() {\n\tfor _, x := range finalizers {\n\t\tx()\n\t}\n}\n\n// ExecuteContext is the same as Execute(), but sets the ctx on the command.\n// Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs\n// functions.\nfunc (c *Command) ExecuteContext(ctx context.Context) error {\n\tc.ctx = ctx\n\treturn c.Execute()\n}\n\n// Execute uses the args (os.Args[1:] by default)\n// and run through the command tree finding appropriate matches\n// for commands and then corresponding flags.\nfunc (c *Command) Execute() error {\n\t_, err := c.ExecuteC()\n\treturn err\n}\n\n// ExecuteContextC is the same as ExecuteC(), but sets the ctx on the command.\n// Retrieve ctx by calling cmd.Context() inside your *Run lifecycle or ValidArgs\n// functions.\nfunc (c *Command) ExecuteContextC(ctx context.Context) (*Command, error) {\n\tc.ctx = ctx\n\treturn c.ExecuteC()\n}\n\n// ExecuteC executes the command.\nfunc (c *Command) ExecuteC() (cmd *Command, err error) {\n\tif c.ctx == nil {\n\t\tc.ctx = context.Background()\n\t}\n\n\t// Regardless of what command execute is called on, run on Root only\n\tif c.HasParent() {\n\t\treturn c.Root().ExecuteC()\n\t}\n\n\t// windows hook\n\tif preExecHookFn != nil {\n\t\tpreExecHookFn(c)\n\t}\n\n\t// initialize help at the last point to allow for user overriding\n\tc.InitDefaultHelpCmd()\n\t// initialize completion at the last point to allow for user overriding\n\tc.InitDefaultCompletionCmd()\n\n\t// Now that all commands have been created, let's make sure all groups\n\t// are properly created also\n\tc.checkCommandGroups()\n\n\targs := c.args\n\n\t// Workaround FAIL with \"go test -v\" or \"cobra.test -test.v\", see #155\n\tif c.args == nil && filepath.Base(os.Args[0]) != \"cobra.test\" {\n\t\targs = os.Args[1:]\n\t}\n\n\t// initialize the hidden command to be used for shell completion\n\tc.initCompleteCmd(args)\n\n\tvar flags []string\n\tif c.TraverseChildren {\n\t\tcmd, flags, err = c.Traverse(args)\n\t} else {\n\t\tcmd, flags, err = c.Find(args)\n\t}\n\tif err != nil {\n\t\t// If found parse to a subcommand and then failed, talk about the subcommand\n\t\tif cmd != nil {\n\t\t\tc = cmd\n\t\t}\n\t\tif !c.SilenceErrors {\n\t\t\tc.PrintErrln(\"Error:\", err.Error())\n\t\t\tc.PrintErrf(\"Run '%v --help' for usage.\\n\", c.CommandPath())\n\t\t}\n\t\treturn c, err\n\t}\n\n\tcmd.commandCalledAs.called = true\n\tif cmd.commandCalledAs.name == \"\" {\n\t\tcmd.commandCalledAs.name = cmd.Name()\n\t}\n\n\t// We have to pass global context to children command\n\t// if context is present on the parent command.\n\tif cmd.ctx == nil {\n\t\tcmd.ctx = c.ctx\n\t}\n\n\terr = cmd.execute(flags)\n\tif err != nil {\n\t\t// Always show help if requested, even if SilenceErrors is in\n\t\t// effect\n\t\tif errors.Is(err, flag.ErrHelp) {\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn cmd, nil\n\t\t}\n\n\t\t// If root command has SilenceErrors flagged,\n\t\t// all subcommands should respect it\n\t\tif !cmd.SilenceErrors && !c.SilenceErrors {\n\t\t\tc.PrintErrln(\"Error:\", err.Error())\n\t\t}\n\n\t\t// If root command has SilenceUsage flagged,\n\t\t// all subcommands should respect it\n\t\tif !cmd.SilenceUsage && !c.SilenceUsage {\n\t\t\tc.Println(cmd.UsageString())\n\t\t}\n\t}\n\treturn cmd, err\n}\n\nfunc (c *Command) ValidateArgs(args []string) error {\n\tif c.Args == nil {\n\t\treturn ArbitraryArgs(c, args)\n\t}\n\treturn c.Args(c, args)\n}\n\n// ValidateRequiredFlags validates all required flags are present and returns an error otherwise\nfunc (c *Command) ValidateRequiredFlags() error {\n\tif c.DisableFlagParsing {\n\t\treturn nil\n\t}\n\n\tflags := c.Flags()\n\tmissingFlagNames := []string{}\n\tflags.VisitAll(func(pflag *flag.Flag) {\n\t\trequiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]\n\t\tif !found {\n\t\t\treturn\n\t\t}\n\t\tif (requiredAnnotation[0] == \"true\") && !pflag.Changed {\n\t\t\tmissingFlagNames = append(missingFlagNames, pflag.Name)\n\t\t}\n\t})\n\n\tif len(missingFlagNames) > 0 {\n\t\treturn fmt.Errorf(`required flag(s) \"%s\" not set`, strings.Join(missingFlagNames, `\", \"`))\n\t}\n\treturn nil\n}\n\n// checkCommandGroups checks if a command has been added to a group that does not exists.\n// If so, we panic because it indicates a coding error that should be corrected.\nfunc (c *Command) checkCommandGroups() {\n\tfor _, sub := range c.commands {\n\t\t// if Group is not defined let the developer know right away\n\t\tif sub.GroupID != \"\" && !c.ContainsGroup(sub.GroupID) {\n\t\t\tpanic(fmt.Sprintf(\"group id '%s' is not defined for subcommand '%s'\", sub.GroupID, sub.CommandPath()))\n\t\t}\n\n\t\tsub.checkCommandGroups()\n\t}\n}\n\n// InitDefaultHelpFlag adds default help flag to c.\n// It is called automatically by executing the c or by calling help and usage.\n// If c already has help flag, it will do nothing.\nfunc (c *Command) InitDefaultHelpFlag() {\n\tc.mergePersistentFlags()\n\tif c.Flags().Lookup(\"help\") == nil {\n\t\tusage := \"help for \"\n\t\tif c.Name() == \"\" {\n\t\t\tusage += \"this command\"\n\t\t} else {\n\t\t\tusage += c.Name()\n\t\t}\n\t\tc.Flags().BoolP(\"help\", \"h\", false, usage)\n\t\t_ = c.Flags().SetAnnotation(\"help\", FlagSetByCobraAnnotation, []string{\"true\"})\n\t}\n}\n\n// InitDefaultVersionFlag adds default version flag to c.\n// It is called automatically by executing the c.\n// If c already has a version flag, it will do nothing.\n// If c.Version is empty, it will do nothing.\nfunc (c *Command) InitDefaultVersionFlag() {\n\tif c.Version == \"\" {\n\t\treturn\n\t}\n\n\tc.mergePersistentFlags()\n\tif c.Flags().Lookup(\"version\") == nil {\n\t\tusage := \"version for \"\n\t\tif c.Name() == \"\" {\n\t\t\tusage += \"this command\"\n\t\t} else {\n\t\t\tusage += c.Name()\n\t\t}\n\t\tif c.Flags().ShorthandLookup(\"v\") == nil {\n\t\t\tc.Flags().BoolP(\"version\", \"v\", false, usage)\n\t\t} else {\n\t\t\tc.Flags().Bool(\"version\", false, usage)\n\t\t}\n\t\t_ = c.Flags().SetAnnotation(\"version\", FlagSetByCobraAnnotation, []string{\"true\"})\n\t}\n}\n\n// InitDefaultHelpCmd adds default help command to c.\n// It is called automatically by executing the c or by calling help and usage.\n// If c already has help command or c has no subcommands, it will do nothing.\nfunc (c *Command) InitDefaultHelpCmd() {\n\tif !c.HasSubCommands() {\n\t\treturn\n\t}\n\n\tif c.helpCommand == nil {\n\t\tc.helpCommand = &Command{\n\t\t\tUse:   \"help [command]\",\n\t\t\tShort: \"Help about any command\",\n\t\t\tLong: `Help provides help for any command in the application.\nSimply type ` + c.Name() + ` help [path to command] for full details.`,\n\t\t\tValidArgsFunction: func(c *Command, args []string, toComplete string) ([]string, ShellCompDirective) {\n\t\t\t\tvar completions []string\n\t\t\t\tcmd, _, e := c.Root().Find(args)\n\t\t\t\tif e != nil {\n\t\t\t\t\treturn nil, ShellCompDirectiveNoFileComp\n\t\t\t\t}\n\t\t\t\tif cmd == nil {\n\t\t\t\t\t// Root help command.\n\t\t\t\t\tcmd = c.Root()\n\t\t\t\t}\n\t\t\t\tfor _, subCmd := range cmd.Commands() {\n\t\t\t\t\tif subCmd.IsAvailableCommand() || subCmd == cmd.helpCommand {\n\t\t\t\t\t\tif strings.HasPrefix(subCmd.Name(), toComplete) {\n\t\t\t\t\t\t\tcompletions = append(completions, fmt.Sprintf(\"%s\\t%s\", subCmd.Name(), subCmd.Short))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn completions, ShellCompDirectiveNoFileComp\n\t\t\t},\n\t\t\tRun: func(c *Command, args []string) {\n\t\t\t\tcmd, _, e := c.Root().Find(args)\n\t\t\t\tif cmd == nil || e != nil {\n\t\t\t\t\tc.Printf(\"Unknown help topic %#q\\n\", args)\n\t\t\t\t\tCheckErr(c.Root().Usage())\n\t\t\t\t} else {\n\t\t\t\t\tcmd.InitDefaultHelpFlag()    // make possible 'help' flag to be shown\n\t\t\t\t\tcmd.InitDefaultVersionFlag() // make possible 'version' flag to be shown\n\t\t\t\t\tCheckErr(cmd.Help())\n\t\t\t\t}\n\t\t\t},\n\t\t\tGroupID: c.helpCommandGroupID,\n\t\t}\n\t}\n\tc.RemoveCommand(c.helpCommand)\n\tc.AddCommand(c.helpCommand)\n}\n\n// ResetCommands delete parent, subcommand and help command from c.\nfunc (c *Command) ResetCommands() {\n\tc.parent = nil\n\tc.commands = nil\n\tc.helpCommand = nil\n\tc.parentsPflags = nil\n}\n\n// Sorts commands by their names.\ntype commandSorterByName []*Command\n\nfunc (c commandSorterByName) Len() int           { return len(c) }\nfunc (c commandSorterByName) Swap(i, j int)      { c[i], c[j] = c[j], c[i] }\nfunc (c commandSorterByName) Less(i, j int) bool { return c[i].Name() < c[j].Name() }\n\n// Commands returns a sorted slice of child commands.\nfunc (c *Command) Commands() []*Command {\n\t// do not sort commands if it already sorted or sorting was disabled\n\tif EnableCommandSorting && !c.commandsAreSorted {\n\t\tsort.Sort(commandSorterByName(c.commands))\n\t\tc.commandsAreSorted = true\n\t}\n\treturn c.commands\n}\n\n// AddCommand adds one or more commands to this parent command.\nfunc (c *Command) AddCommand(cmds ...*Command) {\n\tfor i, x := range cmds {\n\t\tif cmds[i] == c {\n\t\t\tpanic(\"Command can't be a child of itself\")\n\t\t}\n\t\tcmds[i].parent = c\n\t\t// update max lengths\n\t\tusageLen := len(x.Use)\n\t\tif usageLen > c.commandsMaxUseLen {\n\t\t\tc.commandsMaxUseLen = usageLen\n\t\t}\n\t\tcommandPathLen := len(x.CommandPath())\n\t\tif commandPathLen > c.commandsMaxCommandPathLen {\n\t\t\tc.commandsMaxCommandPathLen = commandPathLen\n\t\t}\n\t\tnameLen := len(x.Name())\n\t\tif nameLen > c.commandsMaxNameLen {\n\t\t\tc.commandsMaxNameLen = nameLen\n\t\t}\n\t\t// If global normalization function exists, update all children\n\t\tif c.globNormFunc != nil {\n\t\t\tx.SetGlobalNormalizationFunc(c.globNormFunc)\n\t\t}\n\t\tc.commands = append(c.commands, x)\n\t\tc.commandsAreSorted = false\n\t}\n}\n\n// Groups returns a slice of child command groups.\nfunc (c *Command) Groups() []*Group {\n\treturn c.commandgroups\n}\n\n// AllChildCommandsHaveGroup returns if all subcommands are assigned to a group\nfunc (c *Command) AllChildCommandsHaveGroup() bool {\n\tfor _, sub := range c.commands {\n\t\tif (sub.IsAvailableCommand() || sub == c.helpCommand) && sub.GroupID == \"\" {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// ContainsGroup return if groupID exists in the list of command groups.\nfunc (c *Command) ContainsGroup(groupID string) bool {\n\tfor _, x := range c.commandgroups {\n\t\tif x.ID == groupID {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// AddGroup adds one or more command groups to this parent command.\nfunc (c *Command) AddGroup(groups ...*Group) {\n\tc.commandgroups = append(c.commandgroups, groups...)\n}\n\n// RemoveCommand removes one or more commands from a parent command.\nfunc (c *Command) RemoveCommand(cmds ...*Command) {\n\tcommands := []*Command{}\nmain:\n\tfor _, command := range c.commands {\n\t\tfor _, cmd := range cmds {\n\t\t\tif command == cmd {\n\t\t\t\tcommand.parent = nil\n\t\t\t\tcontinue main\n\t\t\t}\n\t\t}\n\t\tcommands = append(commands, command)\n\t}\n\tc.commands = commands\n\t// recompute all lengths\n\tc.commandsMaxUseLen = 0\n\tc.commandsMaxCommandPathLen = 0\n\tc.commandsMaxNameLen = 0\n\tfor _, command := range c.commands {\n\t\tusageLen := len(command.Use)\n\t\tif usageLen > c.commandsMaxUseLen {\n\t\t\tc.commandsMaxUseLen = usageLen\n\t\t}\n\t\tcommandPathLen := len(command.CommandPath())\n\t\tif commandPathLen > c.commandsMaxCommandPathLen {\n\t\t\tc.commandsMaxCommandPathLen = commandPathLen\n\t\t}\n\t\tnameLen := len(command.Name())\n\t\tif nameLen > c.commandsMaxNameLen {\n\t\t\tc.commandsMaxNameLen = nameLen\n\t\t}\n\t}\n}\n\n// Print is a convenience method to Print to the defined output, fallback to Stderr if not set.\nfunc (c *Command) Print(i ...interface{}) {\n\tfmt.Fprint(c.OutOrStderr(), i...)\n}\n\n// Println is a convenience method to Println to the defined output, fallback to Stderr if not set.\nfunc (c *Command) Println(i ...interface{}) {\n\tc.Print(fmt.Sprintln(i...))\n}\n\n// Printf is a convenience method to Printf to the defined output, fallback to Stderr if not set.\nfunc (c *Command) Printf(format string, i ...interface{}) {\n\tc.Print(fmt.Sprintf(format, i...))\n}\n\n// PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set.\nfunc (c *Command) PrintErr(i ...interface{}) {\n\tfmt.Fprint(c.ErrOrStderr(), i...)\n}\n\n// PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set.\nfunc (c *Command) PrintErrln(i ...interface{}) {\n\tc.PrintErr(fmt.Sprintln(i...))\n}\n\n// PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set.\nfunc (c *Command) PrintErrf(format string, i ...interface{}) {\n\tc.PrintErr(fmt.Sprintf(format, i...))\n}\n\n// CommandPath returns the full path to this command.\nfunc (c *Command) CommandPath() string {\n\tif c.HasParent() {\n\t\treturn c.Parent().CommandPath() + \" \" + c.Name()\n\t}\n\treturn c.Name()\n}\n\n// UseLine puts out the full usage for a given command (including parents).\nfunc (c *Command) UseLine() string {\n\tvar useline string\n\tif c.HasParent() {\n\t\tuseline = c.parent.CommandPath() + \" \" + c.Use\n\t} else {\n\t\tuseline = c.Use\n\t}\n\tif c.DisableFlagsInUseLine {\n\t\treturn useline\n\t}\n\tif c.HasAvailableFlags() && !strings.Contains(useline, \"[flags]\") {\n\t\tuseline += \" [flags]\"\n\t}\n\treturn useline\n}\n\n// DebugFlags used to determine which flags have been assigned to which commands\n// and which persist.\nfunc (c *Command) DebugFlags() {\n\tc.Println(\"DebugFlags called on\", c.Name())\n\tvar debugflags func(*Command)\n\n\tdebugflags = func(x *Command) {\n\t\tif x.HasFlags() || x.HasPersistentFlags() {\n\t\t\tc.Println(x.Name())\n\t\t}\n\t\tif x.HasFlags() {\n\t\t\tx.flags.VisitAll(func(f *flag.Flag) {\n\t\t\t\tif x.HasPersistentFlags() && x.persistentFlag(f.Name) != nil {\n\t\t\t\t\tc.Println(\"  -\"+f.Shorthand+\",\", \"--\"+f.Name, \"[\"+f.DefValue+\"]\", \"\", f.Value, \"  [LP]\")\n\t\t\t\t} else {\n\t\t\t\t\tc.Println(\"  -\"+f.Shorthand+\",\", \"--\"+f.Name, \"[\"+f.DefValue+\"]\", \"\", f.Value, \"  [L]\")\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tif x.HasPersistentFlags() {\n\t\t\tx.pflags.VisitAll(func(f *flag.Flag) {\n\t\t\t\tif x.HasFlags() {\n\t\t\t\t\tif x.flags.Lookup(f.Name) == nil {\n\t\t\t\t\t\tc.Println(\"  -\"+f.Shorthand+\",\", \"--\"+f.Name, \"[\"+f.DefValue+\"]\", \"\", f.Value, \"  [P]\")\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tc.Println(\"  -\"+f.Shorthand+\",\", \"--\"+f.Name, \"[\"+f.DefValue+\"]\", \"\", f.Value, \"  [P]\")\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\tc.Println(x.flagErrorBuf)\n\t\tif x.HasSubCommands() {\n\t\t\tfor _, y := range x.commands {\n\t\t\t\tdebugflags(y)\n\t\t\t}\n\t\t}\n\t}\n\n\tdebugflags(c)\n}\n\n// Name returns the command's name: the first word in the use line.\nfunc (c *Command) Name() string {\n\tname := c.Use\n\ti := strings.Index(name, \" \")\n\tif i >= 0 {\n\t\tname = name[:i]\n\t}\n\treturn name\n}\n\n// HasAlias determines if a given string is an alias of the command.\nfunc (c *Command) HasAlias(s string) bool {\n\tfor _, a := range c.Aliases {\n\t\tif commandNameMatches(a, s) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// CalledAs returns the command name or alias that was used to invoke\n// this command or an empty string if the command has not been called.\nfunc (c *Command) CalledAs() string {\n\tif c.commandCalledAs.called {\n\t\treturn c.commandCalledAs.name\n\t}\n\treturn \"\"\n}\n\n// hasNameOrAliasPrefix returns true if the Name or any of aliases start\n// with prefix\nfunc (c *Command) hasNameOrAliasPrefix(prefix string) bool {\n\tif strings.HasPrefix(c.Name(), prefix) {\n\t\tc.commandCalledAs.name = c.Name()\n\t\treturn true\n\t}\n\tfor _, alias := range c.Aliases {\n\t\tif strings.HasPrefix(alias, prefix) {\n\t\t\tc.commandCalledAs.name = alias\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// NameAndAliases returns a list of the command name and all aliases\nfunc (c *Command) NameAndAliases() string {\n\treturn strings.Join(append([]string{c.Name()}, c.Aliases...), \", \")\n}\n\n// HasExample determines if the command has example.\nfunc (c *Command) HasExample() bool {\n\treturn len(c.Example) > 0\n}\n\n// Runnable determines if the command is itself runnable.\nfunc (c *Command) Runnable() bool {\n\treturn c.Run != nil || c.RunE != nil\n}\n\n// HasSubCommands determines if the command has children commands.\nfunc (c *Command) HasSubCommands() bool {\n\treturn len(c.commands) > 0\n}\n\n// IsAvailableCommand determines if a command is available as a non-help command\n// (this includes all non deprecated/hidden commands).\nfunc (c *Command) IsAvailableCommand() bool {\n\tif len(c.Deprecated) != 0 || c.Hidden {\n\t\treturn false\n\t}\n\n\tif c.HasParent() && c.Parent().helpCommand == c {\n\t\treturn false\n\t}\n\n\tif c.Runnable() || c.HasAvailableSubCommands() {\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n// IsAdditionalHelpTopicCommand determines if a command is an additional\n// help topic command; additional help topic command is determined by the\n// fact that it is NOT runnable/hidden/deprecated, and has no sub commands that\n// are runnable/hidden/deprecated.\n// Concrete example: https://github.com/spf13/cobra/issues/393#issuecomment-282741924.\nfunc (c *Command) IsAdditionalHelpTopicCommand() bool {\n\t// if a command is runnable, deprecated, or hidden it is not a 'help' command\n\tif c.Runnable() || len(c.Deprecated) != 0 || c.Hidden {\n\t\treturn false\n\t}\n\n\t// if any non-help sub commands are found, the command is not a 'help' command\n\tfor _, sub := range c.commands {\n\t\tif !sub.IsAdditionalHelpTopicCommand() {\n\t\t\treturn false\n\t\t}\n\t}\n\n\t// the command either has no sub commands, or no non-help sub commands\n\treturn true\n}\n\n// HasHelpSubCommands determines if a command has any available 'help' sub commands\n// that need to be shown in the usage/help default template under 'additional help\n// topics'.\nfunc (c *Command) HasHelpSubCommands() bool {\n\t// return true on the first found available 'help' sub command\n\tfor _, sub := range c.commands {\n\t\tif sub.IsAdditionalHelpTopicCommand() {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// the command either has no sub commands, or no available 'help' sub commands\n\treturn false\n}\n\n// HasAvailableSubCommands determines if a command has available sub commands that\n// need to be shown in the usage/help default template under 'available commands'.\nfunc (c *Command) HasAvailableSubCommands() bool {\n\t// return true on the first found available (non deprecated/help/hidden)\n\t// sub command\n\tfor _, sub := range c.commands {\n\t\tif sub.IsAvailableCommand() {\n\t\t\treturn true\n\t\t}\n\t}\n\n\t// the command either has no sub commands, or no available (non deprecated/help/hidden)\n\t// sub commands\n\treturn false\n}\n\n// HasParent determines if the command is a child command.\nfunc (c *Command) HasParent() bool {\n\treturn c.parent != nil\n}\n\n// GlobalNormalizationFunc returns the global normalization function or nil if it doesn't exist.\nfunc (c *Command) GlobalNormalizationFunc() func(f *flag.FlagSet, name string) flag.NormalizedName {\n\treturn c.globNormFunc\n}\n\n// Flags returns the complete FlagSet that applies\n// to this command (local and persistent declared here and by all parents).\nfunc (c *Command) Flags() *flag.FlagSet {\n\tif c.flags == nil {\n\t\tc.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\t\tif c.flagErrorBuf == nil {\n\t\t\tc.flagErrorBuf = new(bytes.Buffer)\n\t\t}\n\t\tc.flags.SetOutput(c.flagErrorBuf)\n\t}\n\n\treturn c.flags\n}\n\n// LocalNonPersistentFlags are flags specific to this command which will NOT persist to subcommands.\nfunc (c *Command) LocalNonPersistentFlags() *flag.FlagSet {\n\tpersistentFlags := c.PersistentFlags()\n\n\tout := flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\tc.LocalFlags().VisitAll(func(f *flag.Flag) {\n\t\tif persistentFlags.Lookup(f.Name) == nil {\n\t\t\tout.AddFlag(f)\n\t\t}\n\t})\n\treturn out\n}\n\n// LocalFlags returns the local FlagSet specifically set in the current command.\nfunc (c *Command) LocalFlags() *flag.FlagSet {\n\tc.mergePersistentFlags()\n\n\tif c.lflags == nil {\n\t\tc.lflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\t\tif c.flagErrorBuf == nil {\n\t\t\tc.flagErrorBuf = new(bytes.Buffer)\n\t\t}\n\t\tc.lflags.SetOutput(c.flagErrorBuf)\n\t}\n\tc.lflags.SortFlags = c.Flags().SortFlags\n\tif c.globNormFunc != nil {\n\t\tc.lflags.SetNormalizeFunc(c.globNormFunc)\n\t}\n\n\taddToLocal := func(f *flag.Flag) {\n\t\t// Add the flag if it is not a parent PFlag, or it shadows a parent PFlag\n\t\tif c.lflags.Lookup(f.Name) == nil && f != c.parentsPflags.Lookup(f.Name) {\n\t\t\tc.lflags.AddFlag(f)\n\t\t}\n\t}\n\tc.Flags().VisitAll(addToLocal)\n\tc.PersistentFlags().VisitAll(addToLocal)\n\treturn c.lflags\n}\n\n// InheritedFlags returns all flags which were inherited from parent commands.\nfunc (c *Command) InheritedFlags() *flag.FlagSet {\n\tc.mergePersistentFlags()\n\n\tif c.iflags == nil {\n\t\tc.iflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\t\tif c.flagErrorBuf == nil {\n\t\t\tc.flagErrorBuf = new(bytes.Buffer)\n\t\t}\n\t\tc.iflags.SetOutput(c.flagErrorBuf)\n\t}\n\n\tlocal := c.LocalFlags()\n\tif c.globNormFunc != nil {\n\t\tc.iflags.SetNormalizeFunc(c.globNormFunc)\n\t}\n\n\tc.parentsPflags.VisitAll(func(f *flag.Flag) {\n\t\tif c.iflags.Lookup(f.Name) == nil && local.Lookup(f.Name) == nil {\n\t\t\tc.iflags.AddFlag(f)\n\t\t}\n\t})\n\treturn c.iflags\n}\n\n// NonInheritedFlags returns all flags which were not inherited from parent commands.\nfunc (c *Command) NonInheritedFlags() *flag.FlagSet {\n\treturn c.LocalFlags()\n}\n\n// PersistentFlags returns the persistent FlagSet specifically set in the current command.\nfunc (c *Command) PersistentFlags() *flag.FlagSet {\n\tif c.pflags == nil {\n\t\tc.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\t\tif c.flagErrorBuf == nil {\n\t\t\tc.flagErrorBuf = new(bytes.Buffer)\n\t\t}\n\t\tc.pflags.SetOutput(c.flagErrorBuf)\n\t}\n\treturn c.pflags\n}\n\n// ResetFlags deletes all flags from command.\nfunc (c *Command) ResetFlags() {\n\tc.flagErrorBuf = new(bytes.Buffer)\n\tc.flagErrorBuf.Reset()\n\tc.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\tc.flags.SetOutput(c.flagErrorBuf)\n\tc.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\tc.pflags.SetOutput(c.flagErrorBuf)\n\n\tc.lflags = nil\n\tc.iflags = nil\n\tc.parentsPflags = nil\n}\n\n// HasFlags checks if the command contains any flags (local plus persistent from the entire structure).\nfunc (c *Command) HasFlags() bool {\n\treturn c.Flags().HasFlags()\n}\n\n// HasPersistentFlags checks if the command contains persistent flags.\nfunc (c *Command) HasPersistentFlags() bool {\n\treturn c.PersistentFlags().HasFlags()\n}\n\n// HasLocalFlags checks if the command has flags specifically declared locally.\nfunc (c *Command) HasLocalFlags() bool {\n\treturn c.LocalFlags().HasFlags()\n}\n\n// HasInheritedFlags checks if the command has flags inherited from its parent command.\nfunc (c *Command) HasInheritedFlags() bool {\n\treturn c.InheritedFlags().HasFlags()\n}\n\n// HasAvailableFlags checks if the command contains any flags (local plus persistent from the entire\n// structure) which are not hidden or deprecated.\nfunc (c *Command) HasAvailableFlags() bool {\n\treturn c.Flags().HasAvailableFlags()\n}\n\n// HasAvailablePersistentFlags checks if the command contains persistent flags which are not hidden or deprecated.\nfunc (c *Command) HasAvailablePersistentFlags() bool {\n\treturn c.PersistentFlags().HasAvailableFlags()\n}\n\n// HasAvailableLocalFlags checks if the command has flags specifically declared locally which are not hidden\n// or deprecated.\nfunc (c *Command) HasAvailableLocalFlags() bool {\n\treturn c.LocalFlags().HasAvailableFlags()\n}\n\n// HasAvailableInheritedFlags checks if the command has flags inherited from its parent command which are\n// not hidden or deprecated.\nfunc (c *Command) HasAvailableInheritedFlags() bool {\n\treturn c.InheritedFlags().HasAvailableFlags()\n}\n\n// Flag climbs up the command tree looking for matching flag.\nfunc (c *Command) Flag(name string) (flag *flag.Flag) {\n\tflag = c.Flags().Lookup(name)\n\n\tif flag == nil {\n\t\tflag = c.persistentFlag(name)\n\t}\n\n\treturn\n}\n\n// Recursively find matching persistent flag.\nfunc (c *Command) persistentFlag(name string) (flag *flag.Flag) {\n\tif c.HasPersistentFlags() {\n\t\tflag = c.PersistentFlags().Lookup(name)\n\t}\n\n\tif flag == nil {\n\t\tc.updateParentsPflags()\n\t\tflag = c.parentsPflags.Lookup(name)\n\t}\n\treturn\n}\n\n// ParseFlags parses persistent flag tree and local flags.\nfunc (c *Command) ParseFlags(args []string) error {\n\tif c.DisableFlagParsing {\n\t\treturn nil\n\t}\n\n\tif c.flagErrorBuf == nil {\n\t\tc.flagErrorBuf = new(bytes.Buffer)\n\t}\n\tbeforeErrorBufLen := c.flagErrorBuf.Len()\n\tc.mergePersistentFlags()\n\n\t// do it here after merging all flags and just before parse\n\tc.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist)\n\n\terr := c.Flags().Parse(args)\n\t// Print warnings if they occurred (e.g. deprecated flag messages).\n\tif c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil {\n\t\tc.Print(c.flagErrorBuf.String())\n\t}\n\n\treturn err\n}\n\n// Parent returns a commands parent command.\nfunc (c *Command) Parent() *Command {\n\treturn c.parent\n}\n\n// mergePersistentFlags merges c.PersistentFlags() to c.Flags()\n// and adds missing persistent flags of all parents.\nfunc (c *Command) mergePersistentFlags() {\n\tc.updateParentsPflags()\n\tc.Flags().AddFlagSet(c.PersistentFlags())\n\tc.Flags().AddFlagSet(c.parentsPflags)\n}\n\n// updateParentsPflags updates c.parentsPflags by adding\n// new persistent flags of all parents.\n// If c.parentsPflags == nil, it makes new.\nfunc (c *Command) updateParentsPflags() {\n\tif c.parentsPflags == nil {\n\t\tc.parentsPflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)\n\t\tc.parentsPflags.SetOutput(c.flagErrorBuf)\n\t\tc.parentsPflags.SortFlags = false\n\t}\n\n\tif c.globNormFunc != nil {\n\t\tc.parentsPflags.SetNormalizeFunc(c.globNormFunc)\n\t}\n\n\tc.Root().PersistentFlags().AddFlagSet(flag.CommandLine)\n\n\tc.VisitParents(func(parent *Command) {\n\t\tc.parentsPflags.AddFlagSet(parent.PersistentFlags())\n\t})\n}\n\n// commandNameMatches checks if two command names are equal\n// taking into account case sensitivity according to\n// EnableCaseInsensitive global configuration.\nfunc commandNameMatches(s string, t string) bool {\n\tif EnableCaseInsensitive {\n\t\treturn strings.EqualFold(s, t)\n\t}\n\n\treturn s == t\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/command_notwin.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\n//go:build !windows\n// +build !windows\n\npackage cobra\n\nvar preExecHookFn func(*Command)\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/command_win.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\n//go:build windows\n// +build windows\n\npackage cobra\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/inconshreveable/mousetrap\"\n)\n\nvar preExecHookFn = preExecHook\n\nfunc preExecHook(c *Command) {\n\tif MousetrapHelpText != \"\" && mousetrap.StartedByExplorer() {\n\t\tc.Print(MousetrapHelpText)\n\t\tif MousetrapDisplayDuration > 0 {\n\t\t\ttime.Sleep(MousetrapDisplayDuration)\n\t\t} else {\n\t\t\tc.Println(\"Press return to continue...\")\n\t\t\tfmt.Scanln()\n\t\t}\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/completions.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/spf13/pflag\"\n)\n\nconst (\n\t// ShellCompRequestCmd is the name of the hidden command that is used to request\n\t// completion results from the program.  It is used by the shell completion scripts.\n\tShellCompRequestCmd = \"__complete\"\n\t// ShellCompNoDescRequestCmd is the name of the hidden command that is used to request\n\t// completion results without their description.  It is used by the shell completion scripts.\n\tShellCompNoDescRequestCmd = \"__completeNoDesc\"\n)\n\n// Global map of flag completion functions. Make sure to use flagCompletionMutex before you try to read and write from it.\nvar flagCompletionFunctions = map[*pflag.Flag]func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective){}\n\n// lock for reading and writing from flagCompletionFunctions\nvar flagCompletionMutex = &sync.RWMutex{}\n\n// ShellCompDirective is a bit map representing the different behaviors the shell\n// can be instructed to have once completions have been provided.\ntype ShellCompDirective int\n\ntype flagCompError struct {\n\tsubCommand string\n\tflagName   string\n}\n\nfunc (e *flagCompError) Error() string {\n\treturn \"Subcommand '\" + e.subCommand + \"' does not support flag '\" + e.flagName + \"'\"\n}\n\nconst (\n\t// ShellCompDirectiveError indicates an error occurred and completions should be ignored.\n\tShellCompDirectiveError ShellCompDirective = 1 << iota\n\n\t// ShellCompDirectiveNoSpace indicates that the shell should not add a space\n\t// after the completion even if there is a single completion provided.\n\tShellCompDirectiveNoSpace\n\n\t// ShellCompDirectiveNoFileComp indicates that the shell should not provide\n\t// file completion even when no completion is provided.\n\tShellCompDirectiveNoFileComp\n\n\t// ShellCompDirectiveFilterFileExt indicates that the provided completions\n\t// should be used as file extension filters.\n\t// For flags, using Command.MarkFlagFilename() and Command.MarkPersistentFlagFilename()\n\t// is a shortcut to using this directive explicitly.  The BashCompFilenameExt\n\t// annotation can also be used to obtain the same behavior for flags.\n\tShellCompDirectiveFilterFileExt\n\n\t// ShellCompDirectiveFilterDirs indicates that only directory names should\n\t// be provided in file completion.  To request directory names within another\n\t// directory, the returned completions should specify the directory within\n\t// which to search.  The BashCompSubdirsInDir annotation can be used to\n\t// obtain the same behavior but only for flags.\n\tShellCompDirectiveFilterDirs\n\n\t// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order\n\t// in which the completions are provided\n\tShellCompDirectiveKeepOrder\n\n\t// ===========================================================================\n\n\t// All directives using iota should be above this one.\n\t// For internal use.\n\tshellCompDirectiveMaxValue\n\n\t// ShellCompDirectiveDefault indicates to let the shell perform its default\n\t// behavior after completions have been provided.\n\t// This one must be last to avoid messing up the iota count.\n\tShellCompDirectiveDefault ShellCompDirective = 0\n)\n\nconst (\n\t// Constants for the completion command\n\tcompCmdName              = \"completion\"\n\tcompCmdNoDescFlagName    = \"no-descriptions\"\n\tcompCmdNoDescFlagDesc    = \"disable completion descriptions\"\n\tcompCmdNoDescFlagDefault = false\n)\n\n// CompletionOptions are the options to control shell completion\ntype CompletionOptions struct {\n\t// DisableDefaultCmd prevents Cobra from creating a default 'completion' command\n\tDisableDefaultCmd bool\n\t// DisableNoDescFlag prevents Cobra from creating the '--no-descriptions' flag\n\t// for shells that support completion descriptions\n\tDisableNoDescFlag bool\n\t// DisableDescriptions turns off all completion descriptions for shells\n\t// that support them\n\tDisableDescriptions bool\n\t// HiddenDefaultCmd makes the default 'completion' command hidden\n\tHiddenDefaultCmd bool\n}\n\n// NoFileCompletions can be used to disable file completion for commands that should\n// not trigger file completions.\nfunc NoFileCompletions(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) {\n\treturn nil, ShellCompDirectiveNoFileComp\n}\n\n// FixedCompletions can be used to create a completion function which always\n// returns the same results.\nfunc FixedCompletions(choices []string, directive ShellCompDirective) func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) {\n\treturn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) {\n\t\treturn choices, directive\n\t}\n}\n\n// RegisterFlagCompletionFunc should be called to register a function to provide completion for a flag.\nfunc (c *Command) RegisterFlagCompletionFunc(flagName string, f func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)) error {\n\tflag := c.Flag(flagName)\n\tif flag == nil {\n\t\treturn fmt.Errorf(\"RegisterFlagCompletionFunc: flag '%s' does not exist\", flagName)\n\t}\n\tflagCompletionMutex.Lock()\n\tdefer flagCompletionMutex.Unlock()\n\n\tif _, exists := flagCompletionFunctions[flag]; exists {\n\t\treturn fmt.Errorf(\"RegisterFlagCompletionFunc: flag '%s' already registered\", flagName)\n\t}\n\tflagCompletionFunctions[flag] = f\n\treturn nil\n}\n\n// Returns a string listing the different directive enabled in the specified parameter\nfunc (d ShellCompDirective) string() string {\n\tvar directives []string\n\tif d&ShellCompDirectiveError != 0 {\n\t\tdirectives = append(directives, \"ShellCompDirectiveError\")\n\t}\n\tif d&ShellCompDirectiveNoSpace != 0 {\n\t\tdirectives = append(directives, \"ShellCompDirectiveNoSpace\")\n\t}\n\tif d&ShellCompDirectiveNoFileComp != 0 {\n\t\tdirectives = append(directives, \"ShellCompDirectiveNoFileComp\")\n\t}\n\tif d&ShellCompDirectiveFilterFileExt != 0 {\n\t\tdirectives = append(directives, \"ShellCompDirectiveFilterFileExt\")\n\t}\n\tif d&ShellCompDirectiveFilterDirs != 0 {\n\t\tdirectives = append(directives, \"ShellCompDirectiveFilterDirs\")\n\t}\n\tif d&ShellCompDirectiveKeepOrder != 0 {\n\t\tdirectives = append(directives, \"ShellCompDirectiveKeepOrder\")\n\t}\n\tif len(directives) == 0 {\n\t\tdirectives = append(directives, \"ShellCompDirectiveDefault\")\n\t}\n\n\tif d >= shellCompDirectiveMaxValue {\n\t\treturn fmt.Sprintf(\"ERROR: unexpected ShellCompDirective value: %d\", d)\n\t}\n\treturn strings.Join(directives, \", \")\n}\n\n// initCompleteCmd adds a special hidden command that can be used to request custom completions.\nfunc (c *Command) initCompleteCmd(args []string) {\n\tcompleteCmd := &Command{\n\t\tUse:                   fmt.Sprintf(\"%s [command-line]\", ShellCompRequestCmd),\n\t\tAliases:               []string{ShellCompNoDescRequestCmd},\n\t\tDisableFlagsInUseLine: true,\n\t\tHidden:                true,\n\t\tDisableFlagParsing:    true,\n\t\tArgs:                  MinimumNArgs(1),\n\t\tShort:                 \"Request shell completion choices for the specified command-line\",\n\t\tLong: fmt.Sprintf(\"%[2]s is a special command that is used by the shell completion logic\\n%[1]s\",\n\t\t\t\"to request completion choices for the specified command-line.\", ShellCompRequestCmd),\n\t\tRun: func(cmd *Command, args []string) {\n\t\t\tfinalCmd, completions, directive, err := cmd.getCompletions(args)\n\t\t\tif err != nil {\n\t\t\t\tCompErrorln(err.Error())\n\t\t\t\t// Keep going for multiple reasons:\n\t\t\t\t// 1- There could be some valid completions even though there was an error\n\t\t\t\t// 2- Even without completions, we need to print the directive\n\t\t\t}\n\n\t\t\tnoDescriptions := (cmd.CalledAs() == ShellCompNoDescRequestCmd)\n\t\t\tfor _, comp := range completions {\n\t\t\t\tif GetActiveHelpConfig(finalCmd) == activeHelpGlobalDisable {\n\t\t\t\t\t// Remove all activeHelp entries in this case\n\t\t\t\t\tif strings.HasPrefix(comp, activeHelpMarker) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif noDescriptions {\n\t\t\t\t\t// Remove any description that may be included following a tab character.\n\t\t\t\t\tcomp = strings.Split(comp, \"\\t\")[0]\n\t\t\t\t}\n\n\t\t\t\t// Make sure we only write the first line to the output.\n\t\t\t\t// This is needed if a description contains a linebreak.\n\t\t\t\t// Otherwise the shell scripts will interpret the other lines as new flags\n\t\t\t\t// and could therefore provide a wrong completion.\n\t\t\t\tcomp = strings.Split(comp, \"\\n\")[0]\n\n\t\t\t\t// Finally trim the completion.  This is especially important to get rid\n\t\t\t\t// of a trailing tab when there are no description following it.\n\t\t\t\t// For example, a sub-command without a description should not be completed\n\t\t\t\t// with a tab at the end (or else zsh will show a -- following it\n\t\t\t\t// although there is no description).\n\t\t\t\tcomp = strings.TrimSpace(comp)\n\n\t\t\t\t// Print each possible completion to stdout for the completion script to consume.\n\t\t\t\tfmt.Fprintln(finalCmd.OutOrStdout(), comp)\n\t\t\t}\n\n\t\t\t// As the last printout, print the completion directive for the completion script to parse.\n\t\t\t// The directive integer must be that last character following a single colon (:).\n\t\t\t// The completion script expects :<directive>\n\t\t\tfmt.Fprintf(finalCmd.OutOrStdout(), \":%d\\n\", directive)\n\n\t\t\t// Print some helpful info to stderr for the user to understand.\n\t\t\t// Output from stderr must be ignored by the completion script.\n\t\t\tfmt.Fprintf(finalCmd.ErrOrStderr(), \"Completion ended with directive: %s\\n\", directive.string())\n\t\t},\n\t}\n\tc.AddCommand(completeCmd)\n\tsubCmd, _, err := c.Find(args)\n\tif err != nil || subCmd.Name() != ShellCompRequestCmd {\n\t\t// Only create this special command if it is actually being called.\n\t\t// This reduces possible side-effects of creating such a command;\n\t\t// for example, having this command would cause problems to a\n\t\t// cobra program that only consists of the root command, since this\n\t\t// command would cause the root command to suddenly have a subcommand.\n\t\tc.RemoveCommand(completeCmd)\n\t}\n}\n\nfunc (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDirective, error) {\n\t// The last argument, which is not completely typed by the user,\n\t// should not be part of the list of arguments\n\ttoComplete := args[len(args)-1]\n\ttrimmedArgs := args[:len(args)-1]\n\n\tvar finalCmd *Command\n\tvar finalArgs []string\n\tvar err error\n\t// Find the real command for which completion must be performed\n\t// check if we need to traverse here to parse local flags on parent commands\n\tif c.Root().TraverseChildren {\n\t\tfinalCmd, finalArgs, err = c.Root().Traverse(trimmedArgs)\n\t} else {\n\t\t// For Root commands that don't specify any value for their Args fields, when we call\n\t\t// Find(), if those Root commands don't have any sub-commands, they will accept arguments.\n\t\t// However, because we have added the __complete sub-command in the current code path, the\n\t\t// call to Find() -> legacyArgs() will return an error if there are any arguments.\n\t\t// To avoid this, we first remove the __complete command to get back to having no sub-commands.\n\t\trootCmd := c.Root()\n\t\tif len(rootCmd.Commands()) == 1 {\n\t\t\trootCmd.RemoveCommand(c)\n\t\t}\n\n\t\tfinalCmd, finalArgs, err = rootCmd.Find(trimmedArgs)\n\t}\n\tif err != nil {\n\t\t// Unable to find the real command. E.g., <program> someInvalidCmd <TAB>\n\t\treturn c, []string{}, ShellCompDirectiveDefault, fmt.Errorf(\"Unable to find a command for arguments: %v\", trimmedArgs)\n\t}\n\tfinalCmd.ctx = c.ctx\n\n\t// These flags are normally added when `execute()` is called on `finalCmd`,\n\t// however, when doing completion, we don't call `finalCmd.execute()`.\n\t// Let's add the --help and --version flag ourselves.\n\tfinalCmd.InitDefaultHelpFlag()\n\tfinalCmd.InitDefaultVersionFlag()\n\n\t// Check if we are doing flag value completion before parsing the flags.\n\t// This is important because if we are completing a flag value, we need to also\n\t// remove the flag name argument from the list of finalArgs or else the parsing\n\t// could fail due to an invalid value (incomplete) for the flag.\n\tflag, finalArgs, toComplete, flagErr := checkIfFlagCompletion(finalCmd, finalArgs, toComplete)\n\n\t// Check if interspersed is false or -- was set on a previous arg.\n\t// This works by counting the arguments. Normally -- is not counted as arg but\n\t// if -- was already set or interspersed is false and there is already one arg then\n\t// the extra added -- is counted as arg.\n\tflagCompletion := true\n\t_ = finalCmd.ParseFlags(append(finalArgs, \"--\"))\n\tnewArgCount := finalCmd.Flags().NArg()\n\n\t// Parse the flags early so we can check if required flags are set\n\tif err = finalCmd.ParseFlags(finalArgs); err != nil {\n\t\treturn finalCmd, []string{}, ShellCompDirectiveDefault, fmt.Errorf(\"Error while parsing flags from args %v: %s\", finalArgs, err.Error())\n\t}\n\n\trealArgCount := finalCmd.Flags().NArg()\n\tif newArgCount > realArgCount {\n\t\t// don't do flag completion (see above)\n\t\tflagCompletion = false\n\t}\n\t// Error while attempting to parse flags\n\tif flagErr != nil {\n\t\t// If error type is flagCompError and we don't want flagCompletion we should ignore the error\n\t\tif _, ok := flagErr.(*flagCompError); !(ok && !flagCompletion) {\n\t\t\treturn finalCmd, []string{}, ShellCompDirectiveDefault, flagErr\n\t\t}\n\t}\n\n\t// Look for the --help or --version flags.  If they are present,\n\t// there should be no further completions.\n\tif helpOrVersionFlagPresent(finalCmd) {\n\t\treturn finalCmd, []string{}, ShellCompDirectiveNoFileComp, nil\n\t}\n\n\t// We only remove the flags from the arguments if DisableFlagParsing is not set.\n\t// This is important for commands which have requested to do their own flag completion.\n\tif !finalCmd.DisableFlagParsing {\n\t\tfinalArgs = finalCmd.Flags().Args()\n\t}\n\n\tif flag != nil && flagCompletion {\n\t\t// Check if we are completing a flag value subject to annotations\n\t\tif validExts, present := flag.Annotations[BashCompFilenameExt]; present {\n\t\t\tif len(validExts) != 0 {\n\t\t\t\t// File completion filtered by extensions\n\t\t\t\treturn finalCmd, validExts, ShellCompDirectiveFilterFileExt, nil\n\t\t\t}\n\n\t\t\t// The annotation requests simple file completion.  There is no reason to do\n\t\t\t// that since it is the default behavior anyway.  Let's ignore this annotation\n\t\t\t// in case the program also registered a completion function for this flag.\n\t\t\t// Even though it is a mistake on the program's side, let's be nice when we can.\n\t\t}\n\n\t\tif subDir, present := flag.Annotations[BashCompSubdirsInDir]; present {\n\t\t\tif len(subDir) == 1 {\n\t\t\t\t// Directory completion from within a directory\n\t\t\t\treturn finalCmd, subDir, ShellCompDirectiveFilterDirs, nil\n\t\t\t}\n\t\t\t// Directory completion\n\t\t\treturn finalCmd, []string{}, ShellCompDirectiveFilterDirs, nil\n\t\t}\n\t}\n\n\tvar completions []string\n\tvar directive ShellCompDirective\n\n\t// Enforce flag groups before doing flag completions\n\tfinalCmd.enforceFlagGroupsForCompletion()\n\n\t// Note that we want to perform flagname completion even if finalCmd.DisableFlagParsing==true;\n\t// doing this allows for completion of persistent flag names even for commands that disable flag parsing.\n\t//\n\t// When doing completion of a flag name, as soon as an argument starts with\n\t// a '-' we know it is a flag.  We cannot use isFlagArg() here as it requires\n\t// the flag name to be complete\n\tif flag == nil && len(toComplete) > 0 && toComplete[0] == '-' && !strings.Contains(toComplete, \"=\") && flagCompletion {\n\t\t// First check for required flags\n\t\tcompletions = completeRequireFlags(finalCmd, toComplete)\n\n\t\t// If we have not found any required flags, only then can we show regular flags\n\t\tif len(completions) == 0 {\n\t\t\tdoCompleteFlags := func(flag *pflag.Flag) {\n\t\t\t\tif !flag.Changed ||\n\t\t\t\t\tstrings.Contains(flag.Value.Type(), \"Slice\") ||\n\t\t\t\t\tstrings.Contains(flag.Value.Type(), \"Array\") {\n\t\t\t\t\t// If the flag is not already present, or if it can be specified multiple times (Array or Slice)\n\t\t\t\t\t// we suggest it as a completion\n\t\t\t\t\tcompletions = append(completions, getFlagNameCompletions(flag, toComplete)...)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// We cannot use finalCmd.Flags() because we may not have called ParsedFlags() for commands\n\t\t\t// that have set DisableFlagParsing; it is ParseFlags() that merges the inherited and\n\t\t\t// non-inherited flags.\n\t\t\tfinalCmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {\n\t\t\t\tdoCompleteFlags(flag)\n\t\t\t})\n\t\t\tfinalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {\n\t\t\t\tdoCompleteFlags(flag)\n\t\t\t})\n\t\t}\n\n\t\tdirective = ShellCompDirectiveNoFileComp\n\t\tif len(completions) == 1 && strings.HasSuffix(completions[0], \"=\") {\n\t\t\t// If there is a single completion, the shell usually adds a space\n\t\t\t// after the completion.  We don't want that if the flag ends with an =\n\t\t\tdirective = ShellCompDirectiveNoSpace\n\t\t}\n\n\t\tif !finalCmd.DisableFlagParsing {\n\t\t\t// If DisableFlagParsing==false, we have completed the flags as known by Cobra;\n\t\t\t// we can return what we found.\n\t\t\t// If DisableFlagParsing==true, Cobra may not be aware of all flags, so we\n\t\t\t// let the logic continue to see if ValidArgsFunction needs to be called.\n\t\t\treturn finalCmd, completions, directive, nil\n\t\t}\n\t} else {\n\t\tdirective = ShellCompDirectiveDefault\n\t\tif flag == nil {\n\t\t\tfoundLocalNonPersistentFlag := false\n\t\t\t// If TraverseChildren is true on the root command we don't check for\n\t\t\t// local flags because we can use a local flag on a parent command\n\t\t\tif !finalCmd.Root().TraverseChildren {\n\t\t\t\t// Check if there are any local, non-persistent flags on the command-line\n\t\t\t\tlocalNonPersistentFlags := finalCmd.LocalNonPersistentFlags()\n\t\t\t\tfinalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {\n\t\t\t\t\tif localNonPersistentFlags.Lookup(flag.Name) != nil && flag.Changed {\n\t\t\t\t\t\tfoundLocalNonPersistentFlag = true\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Complete subcommand names, including the help command\n\t\t\tif len(finalArgs) == 0 && !foundLocalNonPersistentFlag {\n\t\t\t\t// We only complete sub-commands if:\n\t\t\t\t// - there are no arguments on the command-line and\n\t\t\t\t// - there are no local, non-persistent flags on the command-line or TraverseChildren is true\n\t\t\t\tfor _, subCmd := range finalCmd.Commands() {\n\t\t\t\t\tif subCmd.IsAvailableCommand() || subCmd == finalCmd.helpCommand {\n\t\t\t\t\t\tif strings.HasPrefix(subCmd.Name(), toComplete) {\n\t\t\t\t\t\t\tcompletions = append(completions, fmt.Sprintf(\"%s\\t%s\", subCmd.Name(), subCmd.Short))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdirective = ShellCompDirectiveNoFileComp\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Complete required flags even without the '-' prefix\n\t\t\tcompletions = append(completions, completeRequireFlags(finalCmd, toComplete)...)\n\n\t\t\t// Always complete ValidArgs, even if we are completing a subcommand name.\n\t\t\t// This is for commands that have both subcommands and ValidArgs.\n\t\t\tif len(finalCmd.ValidArgs) > 0 {\n\t\t\t\tif len(finalArgs) == 0 {\n\t\t\t\t\t// ValidArgs are only for the first argument\n\t\t\t\t\tfor _, validArg := range finalCmd.ValidArgs {\n\t\t\t\t\t\tif strings.HasPrefix(validArg, toComplete) {\n\t\t\t\t\t\t\tcompletions = append(completions, validArg)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdirective = ShellCompDirectiveNoFileComp\n\n\t\t\t\t\t// If no completions were found within commands or ValidArgs,\n\t\t\t\t\t// see if there are any ArgAliases that should be completed.\n\t\t\t\t\tif len(completions) == 0 {\n\t\t\t\t\t\tfor _, argAlias := range finalCmd.ArgAliases {\n\t\t\t\t\t\t\tif strings.HasPrefix(argAlias, toComplete) {\n\t\t\t\t\t\t\t\tcompletions = append(completions, argAlias)\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\n\t\t\t\t// If there are ValidArgs specified (even if they don't match), we stop completion.\n\t\t\t\t// Only one of ValidArgs or ValidArgsFunction can be used for a single command.\n\t\t\t\treturn finalCmd, completions, directive, nil\n\t\t\t}\n\n\t\t\t// Let the logic continue so as to add any ValidArgsFunction completions,\n\t\t\t// even if we already found sub-commands.\n\t\t\t// This is for commands that have subcommands but also specify a ValidArgsFunction.\n\t\t}\n\t}\n\n\t// Find the completion function for the flag or command\n\tvar completionFn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)\n\tif flag != nil && flagCompletion {\n\t\tflagCompletionMutex.RLock()\n\t\tcompletionFn = flagCompletionFunctions[flag]\n\t\tflagCompletionMutex.RUnlock()\n\t} else {\n\t\tcompletionFn = finalCmd.ValidArgsFunction\n\t}\n\tif completionFn != nil {\n\t\t// Go custom completion defined for this flag or command.\n\t\t// Call the registered completion function to get the completions.\n\t\tvar comps []string\n\t\tcomps, directive = completionFn(finalCmd, finalArgs, toComplete)\n\t\tcompletions = append(completions, comps...)\n\t}\n\n\treturn finalCmd, completions, directive, nil\n}\n\nfunc helpOrVersionFlagPresent(cmd *Command) bool {\n\tif versionFlag := cmd.Flags().Lookup(\"version\"); versionFlag != nil &&\n\t\tlen(versionFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && versionFlag.Changed {\n\t\treturn true\n\t}\n\tif helpFlag := cmd.Flags().Lookup(\"help\"); helpFlag != nil &&\n\t\tlen(helpFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && helpFlag.Changed {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc getFlagNameCompletions(flag *pflag.Flag, toComplete string) []string {\n\tif nonCompletableFlag(flag) {\n\t\treturn []string{}\n\t}\n\n\tvar completions []string\n\tflagName := \"--\" + flag.Name\n\tif strings.HasPrefix(flagName, toComplete) {\n\t\t// Flag without the =\n\t\tcompletions = append(completions, fmt.Sprintf(\"%s\\t%s\", flagName, flag.Usage))\n\n\t\t// Why suggest both long forms: --flag and --flag= ?\n\t\t// This forces the user to *always* have to type either an = or a space after the flag name.\n\t\t// Let's be nice and avoid making users have to do that.\n\t\t// Since boolean flags and shortname flags don't show the = form, let's go that route and never show it.\n\t\t// The = form will still work, we just won't suggest it.\n\t\t// This also makes the list of suggested flags shorter as we avoid all the = forms.\n\t\t//\n\t\t// if len(flag.NoOptDefVal) == 0 {\n\t\t// \t// Flag requires a value, so it can be suffixed with =\n\t\t// \tflagName += \"=\"\n\t\t// \tcompletions = append(completions, fmt.Sprintf(\"%s\\t%s\", flagName, flag.Usage))\n\t\t// }\n\t}\n\n\tflagName = \"-\" + flag.Shorthand\n\tif len(flag.Shorthand) > 0 && strings.HasPrefix(flagName, toComplete) {\n\t\tcompletions = append(completions, fmt.Sprintf(\"%s\\t%s\", flagName, flag.Usage))\n\t}\n\n\treturn completions\n}\n\nfunc completeRequireFlags(finalCmd *Command, toComplete string) []string {\n\tvar completions []string\n\n\tdoCompleteRequiredFlags := func(flag *pflag.Flag) {\n\t\tif _, present := flag.Annotations[BashCompOneRequiredFlag]; present {\n\t\t\tif !flag.Changed {\n\t\t\t\t// If the flag is not already present, we suggest it as a completion\n\t\t\t\tcompletions = append(completions, getFlagNameCompletions(flag, toComplete)...)\n\t\t\t}\n\t\t}\n\t}\n\n\t// We cannot use finalCmd.Flags() because we may not have called ParsedFlags() for commands\n\t// that have set DisableFlagParsing; it is ParseFlags() that merges the inherited and\n\t// non-inherited flags.\n\tfinalCmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {\n\t\tdoCompleteRequiredFlags(flag)\n\t})\n\tfinalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {\n\t\tdoCompleteRequiredFlags(flag)\n\t})\n\n\treturn completions\n}\n\nfunc checkIfFlagCompletion(finalCmd *Command, args []string, lastArg string) (*pflag.Flag, []string, string, error) {\n\tif finalCmd.DisableFlagParsing {\n\t\t// We only do flag completion if we are allowed to parse flags\n\t\t// This is important for commands which have requested to do their own flag completion.\n\t\treturn nil, args, lastArg, nil\n\t}\n\n\tvar flagName string\n\ttrimmedArgs := args\n\tflagWithEqual := false\n\torgLastArg := lastArg\n\n\t// When doing completion of a flag name, as soon as an argument starts with\n\t// a '-' we know it is a flag.  We cannot use isFlagArg() here as that function\n\t// requires the flag name to be complete\n\tif len(lastArg) > 0 && lastArg[0] == '-' {\n\t\tif index := strings.Index(lastArg, \"=\"); index >= 0 {\n\t\t\t// Flag with an =\n\t\t\tif strings.HasPrefix(lastArg[:index], \"--\") {\n\t\t\t\t// Flag has full name\n\t\t\t\tflagName = lastArg[2:index]\n\t\t\t} else {\n\t\t\t\t// Flag is shorthand\n\t\t\t\t// We have to get the last shorthand flag name\n\t\t\t\t// e.g. `-asd` => d to provide the correct completion\n\t\t\t\t// https://github.com/spf13/cobra/issues/1257\n\t\t\t\tflagName = lastArg[index-1 : index]\n\t\t\t}\n\t\t\tlastArg = lastArg[index+1:]\n\t\t\tflagWithEqual = true\n\t\t} else {\n\t\t\t// Normal flag completion\n\t\t\treturn nil, args, lastArg, nil\n\t\t}\n\t}\n\n\tif len(flagName) == 0 {\n\t\tif len(args) > 0 {\n\t\t\tprevArg := args[len(args)-1]\n\t\t\tif isFlagArg(prevArg) {\n\t\t\t\t// Only consider the case where the flag does not contain an =.\n\t\t\t\t// If the flag contains an = it means it has already been fully processed,\n\t\t\t\t// so we don't need to deal with it here.\n\t\t\t\tif index := strings.Index(prevArg, \"=\"); index < 0 {\n\t\t\t\t\tif strings.HasPrefix(prevArg, \"--\") {\n\t\t\t\t\t\t// Flag has full name\n\t\t\t\t\t\tflagName = prevArg[2:]\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Flag is shorthand\n\t\t\t\t\t\t// We have to get the last shorthand flag name\n\t\t\t\t\t\t// e.g. `-asd` => d to provide the correct completion\n\t\t\t\t\t\t// https://github.com/spf13/cobra/issues/1257\n\t\t\t\t\t\tflagName = prevArg[len(prevArg)-1:]\n\t\t\t\t\t}\n\t\t\t\t\t// Remove the uncompleted flag or else there could be an error created\n\t\t\t\t\t// for an invalid value for that flag\n\t\t\t\t\ttrimmedArgs = args[:len(args)-1]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(flagName) == 0 {\n\t\t// Not doing flag completion\n\t\treturn nil, trimmedArgs, lastArg, nil\n\t}\n\n\tflag := findFlag(finalCmd, flagName)\n\tif flag == nil {\n\t\t// Flag not supported by this command, the interspersed option might be set so return the original args\n\t\treturn nil, args, orgLastArg, &flagCompError{subCommand: finalCmd.Name(), flagName: flagName}\n\t}\n\n\tif !flagWithEqual {\n\t\tif len(flag.NoOptDefVal) != 0 {\n\t\t\t// We had assumed dealing with a two-word flag but the flag is a boolean flag.\n\t\t\t// In that case, there is no value following it, so we are not really doing flag completion.\n\t\t\t// Reset everything to do noun completion.\n\t\t\ttrimmedArgs = args\n\t\t\tflag = nil\n\t\t}\n\t}\n\n\treturn flag, trimmedArgs, lastArg, nil\n}\n\n// InitDefaultCompletionCmd adds a default 'completion' command to c.\n// This function will do nothing if any of the following is true:\n// 1- the feature has been explicitly disabled by the program,\n// 2- c has no subcommands (to avoid creating one),\n// 3- c already has a 'completion' command provided by the program.\nfunc (c *Command) InitDefaultCompletionCmd() {\n\tif c.CompletionOptions.DisableDefaultCmd || !c.HasSubCommands() {\n\t\treturn\n\t}\n\n\tfor _, cmd := range c.commands {\n\t\tif cmd.Name() == compCmdName || cmd.HasAlias(compCmdName) {\n\t\t\t// A completion command is already available\n\t\t\treturn\n\t\t}\n\t}\n\n\thaveNoDescFlag := !c.CompletionOptions.DisableNoDescFlag && !c.CompletionOptions.DisableDescriptions\n\n\tcompletionCmd := &Command{\n\t\tUse:   compCmdName,\n\t\tShort: \"Generate the autocompletion script for the specified shell\",\n\t\tLong: fmt.Sprintf(`Generate the autocompletion script for %[1]s for the specified shell.\nSee each sub-command's help for details on how to use the generated script.\n`, c.Root().Name()),\n\t\tArgs:              NoArgs,\n\t\tValidArgsFunction: NoFileCompletions,\n\t\tHidden:            c.CompletionOptions.HiddenDefaultCmd,\n\t\tGroupID:           c.completionCommandGroupID,\n\t}\n\tc.AddCommand(completionCmd)\n\n\tout := c.OutOrStdout()\n\tnoDesc := c.CompletionOptions.DisableDescriptions\n\tshortDesc := \"Generate the autocompletion script for %s\"\n\tbash := &Command{\n\t\tUse:   \"bash\",\n\t\tShort: fmt.Sprintf(shortDesc, \"bash\"),\n\t\tLong: fmt.Sprintf(`Generate the autocompletion script for the bash shell.\n\nThis script depends on the 'bash-completion' package.\nIf it is not installed already, you can install it via your OS's package manager.\n\nTo load completions in your current shell session:\n\n\tsource <(%[1]s completion bash)\n\nTo load completions for every new session, execute once:\n\n#### Linux:\n\n\t%[1]s completion bash > /etc/bash_completion.d/%[1]s\n\n#### macOS:\n\n\t%[1]s completion bash > $(brew --prefix)/etc/bash_completion.d/%[1]s\n\nYou will need to start a new shell for this setup to take effect.\n`, c.Root().Name()),\n\t\tArgs:                  NoArgs,\n\t\tDisableFlagsInUseLine: true,\n\t\tValidArgsFunction:     NoFileCompletions,\n\t\tRunE: func(cmd *Command, args []string) error {\n\t\t\treturn cmd.Root().GenBashCompletionV2(out, !noDesc)\n\t\t},\n\t}\n\tif haveNoDescFlag {\n\t\tbash.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)\n\t}\n\n\tzsh := &Command{\n\t\tUse:   \"zsh\",\n\t\tShort: fmt.Sprintf(shortDesc, \"zsh\"),\n\t\tLong: fmt.Sprintf(`Generate the autocompletion script for the zsh shell.\n\nIf shell completion is not already enabled in your environment you will need\nto enable it.  You can execute the following once:\n\n\techo \"autoload -U compinit; compinit\" >> ~/.zshrc\n\nTo load completions in your current shell session:\n\n\tsource <(%[1]s completion zsh)\n\nTo load completions for every new session, execute once:\n\n#### Linux:\n\n\t%[1]s completion zsh > \"${fpath[1]}/_%[1]s\"\n\n#### macOS:\n\n\t%[1]s completion zsh > $(brew --prefix)/share/zsh/site-functions/_%[1]s\n\nYou will need to start a new shell for this setup to take effect.\n`, c.Root().Name()),\n\t\tArgs:              NoArgs,\n\t\tValidArgsFunction: NoFileCompletions,\n\t\tRunE: func(cmd *Command, args []string) error {\n\t\t\tif noDesc {\n\t\t\t\treturn cmd.Root().GenZshCompletionNoDesc(out)\n\t\t\t}\n\t\t\treturn cmd.Root().GenZshCompletion(out)\n\t\t},\n\t}\n\tif haveNoDescFlag {\n\t\tzsh.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)\n\t}\n\n\tfish := &Command{\n\t\tUse:   \"fish\",\n\t\tShort: fmt.Sprintf(shortDesc, \"fish\"),\n\t\tLong: fmt.Sprintf(`Generate the autocompletion script for the fish shell.\n\nTo load completions in your current shell session:\n\n\t%[1]s completion fish | source\n\nTo load completions for every new session, execute once:\n\n\t%[1]s completion fish > ~/.config/fish/completions/%[1]s.fish\n\nYou will need to start a new shell for this setup to take effect.\n`, c.Root().Name()),\n\t\tArgs:              NoArgs,\n\t\tValidArgsFunction: NoFileCompletions,\n\t\tRunE: func(cmd *Command, args []string) error {\n\t\t\treturn cmd.Root().GenFishCompletion(out, !noDesc)\n\t\t},\n\t}\n\tif haveNoDescFlag {\n\t\tfish.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)\n\t}\n\n\tpowershell := &Command{\n\t\tUse:   \"powershell\",\n\t\tShort: fmt.Sprintf(shortDesc, \"powershell\"),\n\t\tLong: fmt.Sprintf(`Generate the autocompletion script for powershell.\n\nTo load completions in your current shell session:\n\n\t%[1]s completion powershell | Out-String | Invoke-Expression\n\nTo load completions for every new session, add the output of the above command\nto your powershell profile.\n`, c.Root().Name()),\n\t\tArgs:              NoArgs,\n\t\tValidArgsFunction: NoFileCompletions,\n\t\tRunE: func(cmd *Command, args []string) error {\n\t\t\tif noDesc {\n\t\t\t\treturn cmd.Root().GenPowerShellCompletion(out)\n\t\t\t}\n\t\t\treturn cmd.Root().GenPowerShellCompletionWithDesc(out)\n\n\t\t},\n\t}\n\tif haveNoDescFlag {\n\t\tpowershell.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)\n\t}\n\n\tcompletionCmd.AddCommand(bash, zsh, fish, powershell)\n}\n\nfunc findFlag(cmd *Command, name string) *pflag.Flag {\n\tflagSet := cmd.Flags()\n\tif len(name) == 1 {\n\t\t// First convert the short flag into a long flag\n\t\t// as the cmd.Flag() search only accepts long flags\n\t\tif short := flagSet.ShorthandLookup(name); short != nil {\n\t\t\tname = short.Name\n\t\t} else {\n\t\t\tset := cmd.InheritedFlags()\n\t\t\tif short = set.ShorthandLookup(name); short != nil {\n\t\t\t\tname = short.Name\n\t\t\t} else {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\treturn cmd.Flag(name)\n}\n\n// CompDebug prints the specified string to the same file as where the\n// completion script prints its logs.\n// Note that completion printouts should never be on stdout as they would\n// be wrongly interpreted as actual completion choices by the completion script.\nfunc CompDebug(msg string, printToStdErr bool) {\n\tmsg = fmt.Sprintf(\"[Debug] %s\", msg)\n\n\t// Such logs are only printed when the user has set the environment\n\t// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.\n\tif path := os.Getenv(\"BASH_COMP_DEBUG_FILE\"); path != \"\" {\n\t\tf, err := os.OpenFile(path,\n\t\t\tos.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)\n\t\tif err == nil {\n\t\t\tdefer f.Close()\n\t\t\tWriteStringAndCheck(f, msg)\n\t\t}\n\t}\n\n\tif printToStdErr {\n\t\t// Must print to stderr for this not to be read by the completion script.\n\t\tfmt.Fprint(os.Stderr, msg)\n\t}\n}\n\n// CompDebugln prints the specified string with a newline at the end\n// to the same file as where the completion script prints its logs.\n// Such logs are only printed when the user has set the environment\n// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.\nfunc CompDebugln(msg string, printToStdErr bool) {\n\tCompDebug(fmt.Sprintf(\"%s\\n\", msg), printToStdErr)\n}\n\n// CompError prints the specified completion message to stderr.\nfunc CompError(msg string) {\n\tmsg = fmt.Sprintf(\"[Error] %s\", msg)\n\tCompDebug(msg, true)\n}\n\n// CompErrorln prints the specified completion message to stderr with a newline at the end.\nfunc CompErrorln(msg string) {\n\tCompError(fmt.Sprintf(\"%s\\n\", msg))\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/fish_completions.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc genFishComp(buf io.StringWriter, name string, includeDesc bool) {\n\t// Variables should not contain a '-' or ':' character\n\tnameForVar := name\n\tnameForVar = strings.ReplaceAll(nameForVar, \"-\", \"_\")\n\tnameForVar = strings.ReplaceAll(nameForVar, \":\", \"_\")\n\n\tcompCmd := ShellCompRequestCmd\n\tif !includeDesc {\n\t\tcompCmd = ShellCompNoDescRequestCmd\n\t}\n\tWriteStringAndCheck(buf, fmt.Sprintf(\"# fish completion for %-36s -*- shell-script -*-\\n\", name))\n\tWriteStringAndCheck(buf, fmt.Sprintf(`\nfunction __%[1]s_debug\n    set -l file \"$BASH_COMP_DEBUG_FILE\"\n    if test -n \"$file\"\n        echo \"$argv\" >> $file\n    end\nend\n\nfunction __%[1]s_perform_completion\n    __%[1]s_debug \"Starting __%[1]s_perform_completion\"\n\n    # Extract all args except the last one\n    set -l args (commandline -opc)\n    # Extract the last arg and escape it in case it is a space\n    set -l lastArg (string escape -- (commandline -ct))\n\n    __%[1]s_debug \"args: $args\"\n    __%[1]s_debug \"last arg: $lastArg\"\n\n    # Disable ActiveHelp which is not supported for fish shell\n    set -l requestComp \"%[10]s=0 $args[1] %[3]s $args[2..-1] $lastArg\"\n\n    __%[1]s_debug \"Calling $requestComp\"\n    set -l results (eval $requestComp 2> /dev/null)\n\n    # Some programs may output extra empty lines after the directive.\n    # Let's ignore them or else it will break completion.\n    # Ref: https://github.com/spf13/cobra/issues/1279\n    for line in $results[-1..1]\n        if test (string trim -- $line) = \"\"\n            # Found an empty line, remove it\n            set results $results[1..-2]\n        else\n            # Found non-empty line, we have our proper output\n            break\n        end\n    end\n\n    set -l comps $results[1..-2]\n    set -l directiveLine $results[-1]\n\n    # For Fish, when completing a flag with an = (e.g., <program> -n=<TAB>)\n    # completions must be prefixed with the flag\n    set -l flagPrefix (string match -r -- '-.*=' \"$lastArg\")\n\n    __%[1]s_debug \"Comps: $comps\"\n    __%[1]s_debug \"DirectiveLine: $directiveLine\"\n    __%[1]s_debug \"flagPrefix: $flagPrefix\"\n\n    for comp in $comps\n        printf \"%%s%%s\\n\" \"$flagPrefix\" \"$comp\"\n    end\n\n    printf \"%%s\\n\" \"$directiveLine\"\nend\n\n# this function limits calls to __%[1]s_perform_completion, by caching the result behind $__%[1]s_perform_completion_once_result\nfunction __%[1]s_perform_completion_once\n    __%[1]s_debug \"Starting __%[1]s_perform_completion_once\"\n\n    if test -n \"$__%[1]s_perform_completion_once_result\"\n        __%[1]s_debug \"Seems like a valid result already exists, skipping __%[1]s_perform_completion\"\n        return 0\n    end\n\n    set --global __%[1]s_perform_completion_once_result (__%[1]s_perform_completion)\n    if test -z \"$__%[1]s_perform_completion_once_result\"\n        __%[1]s_debug \"No completions, probably due to a failure\"\n        return 1\n    end\n\n    __%[1]s_debug \"Performed completions and set __%[1]s_perform_completion_once_result\"\n    return 0\nend\n\n# this function is used to clear the $__%[1]s_perform_completion_once_result variable after completions are run\nfunction __%[1]s_clear_perform_completion_once_result\n    __%[1]s_debug \"\"\n    __%[1]s_debug \"========= clearing previously set __%[1]s_perform_completion_once_result variable ==========\"\n    set --erase __%[1]s_perform_completion_once_result\n    __%[1]s_debug \"Succesfully erased the variable __%[1]s_perform_completion_once_result\"\nend\n\nfunction __%[1]s_requires_order_preservation\n    __%[1]s_debug \"\"\n    __%[1]s_debug \"========= checking if order preservation is required ==========\"\n\n    __%[1]s_perform_completion_once\n    if test -z \"$__%[1]s_perform_completion_once_result\"\n        __%[1]s_debug \"Error determining if order preservation is required\"\n        return 1\n    end\n\n    set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1])\n    __%[1]s_debug \"Directive is: $directive\"\n\n    set -l shellCompDirectiveKeepOrder %[9]d\n    set -l keeporder (math (math --scale 0 $directive / $shellCompDirectiveKeepOrder) %% 2)\n    __%[1]s_debug \"Keeporder is: $keeporder\"\n\n    if test $keeporder -ne 0\n        __%[1]s_debug \"This does require order preservation\"\n        return 0\n    end\n\n    __%[1]s_debug \"This doesn't require order preservation\"\n    return 1\nend\n\n\n# This function does two things:\n# - Obtain the completions and store them in the global __%[1]s_comp_results\n# - Return false if file completion should be performed\nfunction __%[1]s_prepare_completions\n    __%[1]s_debug \"\"\n    __%[1]s_debug \"========= starting completion logic ==========\"\n\n    # Start fresh\n    set --erase __%[1]s_comp_results\n\n    __%[1]s_perform_completion_once\n    __%[1]s_debug \"Completion results: $__%[1]s_perform_completion_once_result\"\n\n    if test -z \"$__%[1]s_perform_completion_once_result\"\n        __%[1]s_debug \"No completion, probably due to a failure\"\n        # Might as well do file completion, in case it helps\n        return 1\n    end\n\n    set -l directive (string sub --start 2 $__%[1]s_perform_completion_once_result[-1])\n    set --global __%[1]s_comp_results $__%[1]s_perform_completion_once_result[1..-2]\n\n    __%[1]s_debug \"Completions are: $__%[1]s_comp_results\"\n    __%[1]s_debug \"Directive is: $directive\"\n\n    set -l shellCompDirectiveError %[4]d\n    set -l shellCompDirectiveNoSpace %[5]d\n    set -l shellCompDirectiveNoFileComp %[6]d\n    set -l shellCompDirectiveFilterFileExt %[7]d\n    set -l shellCompDirectiveFilterDirs %[8]d\n\n    if test -z \"$directive\"\n        set directive 0\n    end\n\n    set -l compErr (math (math --scale 0 $directive / $shellCompDirectiveError) %% 2)\n    if test $compErr -eq 1\n        __%[1]s_debug \"Received error directive: aborting.\"\n        # Might as well do file completion, in case it helps\n        return 1\n    end\n\n    set -l filefilter (math (math --scale 0 $directive / $shellCompDirectiveFilterFileExt) %% 2)\n    set -l dirfilter (math (math --scale 0 $directive / $shellCompDirectiveFilterDirs) %% 2)\n    if test $filefilter -eq 1; or test $dirfilter -eq 1\n        __%[1]s_debug \"File extension filtering or directory filtering not supported\"\n        # Do full file completion instead\n        return 1\n    end\n\n    set -l nospace (math (math --scale 0 $directive / $shellCompDirectiveNoSpace) %% 2)\n    set -l nofiles (math (math --scale 0 $directive / $shellCompDirectiveNoFileComp) %% 2)\n\n    __%[1]s_debug \"nospace: $nospace, nofiles: $nofiles\"\n\n    # If we want to prevent a space, or if file completion is NOT disabled,\n    # we need to count the number of valid completions.\n    # To do so, we will filter on prefix as the completions we have received\n    # may not already be filtered so as to allow fish to match on different\n    # criteria than the prefix.\n    if test $nospace -ne 0; or test $nofiles -eq 0\n        set -l prefix (commandline -t | string escape --style=regex)\n        __%[1]s_debug \"prefix: $prefix\"\n\n        set -l completions (string match -r -- \"^$prefix.*\" $__%[1]s_comp_results)\n        set --global __%[1]s_comp_results $completions\n        __%[1]s_debug \"Filtered completions are: $__%[1]s_comp_results\"\n\n        # Important not to quote the variable for count to work\n        set -l numComps (count $__%[1]s_comp_results)\n        __%[1]s_debug \"numComps: $numComps\"\n\n        if test $numComps -eq 1; and test $nospace -ne 0\n            # We must first split on \\t to get rid of the descriptions to be\n            # able to check what the actual completion will be.\n            # We don't need descriptions anyway since there is only a single\n            # real completion which the shell will expand immediately.\n            set -l split (string split --max 1 \\t $__%[1]s_comp_results[1])\n\n            # Fish won't add a space if the completion ends with any\n            # of the following characters: @=/:.,\n            set -l lastChar (string sub -s -1 -- $split)\n            if not string match -r -q \"[@=/:.,]\" -- \"$lastChar\"\n                # In other cases, to support the \"nospace\" directive we trick the shell\n                # by outputting an extra, longer completion.\n                __%[1]s_debug \"Adding second completion to perform nospace directive\"\n                set --global __%[1]s_comp_results $split[1] $split[1].\n                __%[1]s_debug \"Completions are now: $__%[1]s_comp_results\"\n            end\n        end\n\n        if test $numComps -eq 0; and test $nofiles -eq 0\n            # To be consistent with bash and zsh, we only trigger file\n            # completion when there are no other completions\n            __%[1]s_debug \"Requesting file completion\"\n            return 1\n        end\n    end\n\n    return 0\nend\n\n# Since Fish completions are only loaded once the user triggers them, we trigger them ourselves\n# so we can properly delete any completions provided by another script.\n# Only do this if the program can be found, or else fish may print some errors; besides,\n# the existing completions will only be loaded if the program can be found.\nif type -q \"%[2]s\"\n    # The space after the program name is essential to trigger completion for the program\n    # and not completion of the program name itself.\n    # Also, we use '> /dev/null 2>&1' since '&>' is not supported in older versions of fish.\n    complete --do-complete \"%[2]s \" > /dev/null 2>&1\nend\n\n# Remove any pre-existing completions for the program since we will be handling all of them.\ncomplete -c %[2]s -e\n\n# this will get called after the two calls below and clear the $__%[1]s_perform_completion_once_result global\ncomplete -c %[2]s -n '__%[1]s_clear_perform_completion_once_result'\n# The call to __%[1]s_prepare_completions will setup __%[1]s_comp_results\n# which provides the program's completion choices.\n# If this doesn't require order preservation, we don't use the -k flag\ncomplete -c %[2]s -n 'not __%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'\n# otherwise we use the -k flag\ncomplete -k -c %[2]s -n '__%[1]s_requires_order_preservation && __%[1]s_prepare_completions' -f -a '$__%[1]s_comp_results'\n`, nameForVar, name, compCmd,\n\t\tShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,\n\t\tShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))\n}\n\n// GenFishCompletion generates fish completion file and writes to the passed writer.\nfunc (c *Command) GenFishCompletion(w io.Writer, includeDesc bool) error {\n\tbuf := new(bytes.Buffer)\n\tgenFishComp(buf, c.Name(), includeDesc)\n\t_, err := buf.WriteTo(w)\n\treturn err\n}\n\n// GenFishCompletionFile generates fish completion file.\nfunc (c *Command) GenFishCompletionFile(filename string, includeDesc bool) error {\n\toutFile, err := os.Create(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer outFile.Close()\n\n\treturn c.GenFishCompletion(outFile, includeDesc)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/fish_completions.md",
    "content": "## Generating Fish Completions For Your cobra.Command\n\nPlease refer to [Shell Completions](shell_completions.md) for details.\n\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/flag_groups.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\tflag \"github.com/spf13/pflag\"\n)\n\nconst (\n\trequiredAsGroup   = \"cobra_annotation_required_if_others_set\"\n\tmutuallyExclusive = \"cobra_annotation_mutually_exclusive\"\n)\n\n// MarkFlagsRequiredTogether marks the given flags with annotations so that Cobra errors\n// if the command is invoked with a subset (but not all) of the given flags.\nfunc (c *Command) MarkFlagsRequiredTogether(flagNames ...string) {\n\tc.mergePersistentFlags()\n\tfor _, v := range flagNames {\n\t\tf := c.Flags().Lookup(v)\n\t\tif f == nil {\n\t\t\tpanic(fmt.Sprintf(\"Failed to find flag %q and mark it as being required in a flag group\", v))\n\t\t}\n\t\tif err := c.Flags().SetAnnotation(v, requiredAsGroup, append(f.Annotations[requiredAsGroup], strings.Join(flagNames, \" \"))); err != nil {\n\t\t\t// Only errs if the flag isn't found.\n\t\t\tpanic(err)\n\t\t}\n\t}\n}\n\n// MarkFlagsMutuallyExclusive marks the given flags with annotations so that Cobra errors\n// if the command is invoked with more than one flag from the given set of flags.\nfunc (c *Command) MarkFlagsMutuallyExclusive(flagNames ...string) {\n\tc.mergePersistentFlags()\n\tfor _, v := range flagNames {\n\t\tf := c.Flags().Lookup(v)\n\t\tif f == nil {\n\t\t\tpanic(fmt.Sprintf(\"Failed to find flag %q and mark it as being in a mutually exclusive flag group\", v))\n\t\t}\n\t\t// Each time this is called is a single new entry; this allows it to be a member of multiple groups if needed.\n\t\tif err := c.Flags().SetAnnotation(v, mutuallyExclusive, append(f.Annotations[mutuallyExclusive], strings.Join(flagNames, \" \"))); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n}\n\n// ValidateFlagGroups validates the mutuallyExclusive/requiredAsGroup logic and returns the\n// first error encountered.\nfunc (c *Command) ValidateFlagGroups() error {\n\tif c.DisableFlagParsing {\n\t\treturn nil\n\t}\n\n\tflags := c.Flags()\n\n\t// groupStatus format is the list of flags as a unique ID,\n\t// then a map of each flag name and whether it is set or not.\n\tgroupStatus := map[string]map[string]bool{}\n\tmutuallyExclusiveGroupStatus := map[string]map[string]bool{}\n\tflags.VisitAll(func(pflag *flag.Flag) {\n\t\tprocessFlagForGroupAnnotation(flags, pflag, requiredAsGroup, groupStatus)\n\t\tprocessFlagForGroupAnnotation(flags, pflag, mutuallyExclusive, mutuallyExclusiveGroupStatus)\n\t})\n\n\tif err := validateRequiredFlagGroups(groupStatus); err != nil {\n\t\treturn err\n\t}\n\tif err := validateExclusiveFlagGroups(mutuallyExclusiveGroupStatus); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc hasAllFlags(fs *flag.FlagSet, flagnames ...string) bool {\n\tfor _, fname := range flagnames {\n\t\tf := fs.Lookup(fname)\n\t\tif f == nil {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc processFlagForGroupAnnotation(flags *flag.FlagSet, pflag *flag.Flag, annotation string, groupStatus map[string]map[string]bool) {\n\tgroupInfo, found := pflag.Annotations[annotation]\n\tif found {\n\t\tfor _, group := range groupInfo {\n\t\t\tif groupStatus[group] == nil {\n\t\t\t\tflagnames := strings.Split(group, \" \")\n\n\t\t\t\t// Only consider this flag group at all if all the flags are defined.\n\t\t\t\tif !hasAllFlags(flags, flagnames...) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tgroupStatus[group] = map[string]bool{}\n\t\t\t\tfor _, name := range flagnames {\n\t\t\t\t\tgroupStatus[group][name] = false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tgroupStatus[group][pflag.Name] = pflag.Changed\n\t\t}\n\t}\n}\n\nfunc validateRequiredFlagGroups(data map[string]map[string]bool) error {\n\tkeys := sortedKeys(data)\n\tfor _, flagList := range keys {\n\t\tflagnameAndStatus := data[flagList]\n\n\t\tunset := []string{}\n\t\tfor flagname, isSet := range flagnameAndStatus {\n\t\t\tif !isSet {\n\t\t\t\tunset = append(unset, flagname)\n\t\t\t}\n\t\t}\n\t\tif len(unset) == len(flagnameAndStatus) || len(unset) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Sort values, so they can be tested/scripted against consistently.\n\t\tsort.Strings(unset)\n\t\treturn fmt.Errorf(\"if any flags in the group [%v] are set they must all be set; missing %v\", flagList, unset)\n\t}\n\n\treturn nil\n}\n\nfunc validateExclusiveFlagGroups(data map[string]map[string]bool) error {\n\tkeys := sortedKeys(data)\n\tfor _, flagList := range keys {\n\t\tflagnameAndStatus := data[flagList]\n\t\tvar set []string\n\t\tfor flagname, isSet := range flagnameAndStatus {\n\t\t\tif isSet {\n\t\t\t\tset = append(set, flagname)\n\t\t\t}\n\t\t}\n\t\tif len(set) == 0 || len(set) == 1 {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Sort values, so they can be tested/scripted against consistently.\n\t\tsort.Strings(set)\n\t\treturn fmt.Errorf(\"if any flags in the group [%v] are set none of the others can be; %v were all set\", flagList, set)\n\t}\n\treturn nil\n}\n\nfunc sortedKeys(m map[string]map[string]bool) []string {\n\tkeys := make([]string, len(m))\n\ti := 0\n\tfor k := range m {\n\t\tkeys[i] = k\n\t\ti++\n\t}\n\tsort.Strings(keys)\n\treturn keys\n}\n\n// enforceFlagGroupsForCompletion will do the following:\n// - when a flag in a group is present, other flags in the group will be marked required\n// - when a flag in a mutually exclusive group is present, other flags in the group will be marked as hidden\n// This allows the standard completion logic to behave appropriately for flag groups\nfunc (c *Command) enforceFlagGroupsForCompletion() {\n\tif c.DisableFlagParsing {\n\t\treturn\n\t}\n\n\tflags := c.Flags()\n\tgroupStatus := map[string]map[string]bool{}\n\tmutuallyExclusiveGroupStatus := map[string]map[string]bool{}\n\tc.Flags().VisitAll(func(pflag *flag.Flag) {\n\t\tprocessFlagForGroupAnnotation(flags, pflag, requiredAsGroup, groupStatus)\n\t\tprocessFlagForGroupAnnotation(flags, pflag, mutuallyExclusive, mutuallyExclusiveGroupStatus)\n\t})\n\n\t// If a flag that is part of a group is present, we make all the other flags\n\t// of that group required so that the shell completion suggests them automatically\n\tfor flagList, flagnameAndStatus := range groupStatus {\n\t\tfor _, isSet := range flagnameAndStatus {\n\t\t\tif isSet {\n\t\t\t\t// One of the flags of the group is set, mark the other ones as required\n\t\t\t\tfor _, fName := range strings.Split(flagList, \" \") {\n\t\t\t\t\t_ = c.MarkFlagRequired(fName)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If a flag that is mutually exclusive to others is present, we hide the other\n\t// flags of that group so the shell completion does not suggest them\n\tfor flagList, flagnameAndStatus := range mutuallyExclusiveGroupStatus {\n\t\tfor flagName, isSet := range flagnameAndStatus {\n\t\t\tif isSet {\n\t\t\t\t// One of the flags of the mutually exclusive group is set, mark the other ones as hidden\n\t\t\t\t// Don't mark the flag that is already set as hidden because it may be an\n\t\t\t\t// array or slice flag and therefore must continue being suggested\n\t\t\t\tfor _, fName := range strings.Split(flagList, \" \") {\n\t\t\t\t\tif fName != flagName {\n\t\t\t\t\t\tflag := c.Flags().Lookup(fName)\n\t\t\t\t\t\tflag.Hidden = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/powershell_completions.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\n// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but\n// can be downloaded separately for windows 7 or 8.1).\n\npackage cobra\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n)\n\nfunc genPowerShellComp(buf io.StringWriter, name string, includeDesc bool) {\n\t// Variables should not contain a '-' or ':' character\n\tnameForVar := name\n\tnameForVar = strings.Replace(nameForVar, \"-\", \"_\", -1)\n\tnameForVar = strings.Replace(nameForVar, \":\", \"_\", -1)\n\n\tcompCmd := ShellCompRequestCmd\n\tif !includeDesc {\n\t\tcompCmd = ShellCompNoDescRequestCmd\n\t}\n\tWriteStringAndCheck(buf, fmt.Sprintf(`# powershell completion for %-36[1]s -*- shell-script -*-\n\nfunction __%[1]s_debug {\n    if ($env:BASH_COMP_DEBUG_FILE) {\n        \"$args\" | Out-File -Append -FilePath \"$env:BASH_COMP_DEBUG_FILE\"\n    }\n}\n\nfilter __%[1]s_escapeStringWithSpecialChars {\n`+\"    $_ -replace '\\\\s|#|@|\\\\$|;|,|''|\\\\{|\\\\}|\\\\(|\\\\)|\\\"|`|\\\\||<|>|&','`$&'\"+`\n}\n\n[scriptblock]$__%[2]sCompleterBlock = {\n    param(\n            $WordToComplete,\n            $CommandAst,\n            $CursorPosition\n        )\n\n    # Get the current command line and convert into a string\n    $Command = $CommandAst.CommandElements\n    $Command = \"$Command\"\n\n    __%[1]s_debug \"\"\n    __%[1]s_debug \"========= starting completion logic ==========\"\n    __%[1]s_debug \"WordToComplete: $WordToComplete Command: $Command CursorPosition: $CursorPosition\"\n\n    # The user could have moved the cursor backwards on the command-line.\n    # We need to trigger completion from the $CursorPosition location, so we need\n    # to truncate the command-line ($Command) up to the $CursorPosition location.\n    # Make sure the $Command is longer then the $CursorPosition before we truncate.\n    # This happens because the $Command does not include the last space.\n    if ($Command.Length -gt $CursorPosition) {\n        $Command=$Command.Substring(0,$CursorPosition)\n    }\n    __%[1]s_debug \"Truncated command: $Command\"\n\n    $ShellCompDirectiveError=%[4]d\n    $ShellCompDirectiveNoSpace=%[5]d\n    $ShellCompDirectiveNoFileComp=%[6]d\n    $ShellCompDirectiveFilterFileExt=%[7]d\n    $ShellCompDirectiveFilterDirs=%[8]d\n    $ShellCompDirectiveKeepOrder=%[9]d\n\n    # Prepare the command to request completions for the program.\n    # Split the command at the first space to separate the program and arguments.\n    $Program,$Arguments = $Command.Split(\" \",2)\n\n    $RequestComp=\"$Program %[3]s $Arguments\"\n    __%[1]s_debug \"RequestComp: $RequestComp\"\n\n    # we cannot use $WordToComplete because it\n    # has the wrong values if the cursor was moved\n    # so use the last argument\n    if ($WordToComplete -ne \"\" ) {\n        $WordToComplete = $Arguments.Split(\" \")[-1]\n    }\n    __%[1]s_debug \"New WordToComplete: $WordToComplete\"\n\n\n    # Check for flag with equal sign\n    $IsEqualFlag = ($WordToComplete -Like \"--*=*\" )\n    if ( $IsEqualFlag ) {\n        __%[1]s_debug \"Completing equal sign flag\"\n        # Remove the flag part\n        $Flag,$WordToComplete = $WordToComplete.Split(\"=\",2)\n    }\n\n    if ( $WordToComplete -eq \"\" -And ( -Not $IsEqualFlag )) {\n        # If the last parameter is complete (there is a space following it)\n        # We add an extra empty parameter so we can indicate this to the go method.\n        __%[1]s_debug \"Adding extra empty parameter\"\n        # PowerShell 7.2+ changed the way how the arguments are passed to executables,\n        # so for pre-7.2 or when Legacy argument passing is enabled we need to use\n`+\"        # `\\\"`\\\" to pass an empty argument, a \\\"\\\" or '' does not work!!!\"+`\n        if ($PSVersionTable.PsVersion -lt [version]'7.2.0' -or\n            ($PSVersionTable.PsVersion -lt [version]'7.3.0' -and -not [ExperimentalFeature]::IsEnabled(\"PSNativeCommandArgumentPassing\")) -or\n            (($PSVersionTable.PsVersion -ge [version]'7.3.0' -or [ExperimentalFeature]::IsEnabled(\"PSNativeCommandArgumentPassing\")) -and\n              $PSNativeCommandArgumentPassing -eq 'Legacy')) {\n`+\"             $RequestComp=\\\"$RequestComp\\\" + ' `\\\"`\\\"'\"+`\n        } else {\n             $RequestComp=\"$RequestComp\" + ' \"\"'\n        }\n    }\n\n    __%[1]s_debug \"Calling $RequestComp\"\n    # First disable ActiveHelp which is not supported for Powershell\n    $env:%[10]s=0\n\n    #call the command store the output in $out and redirect stderr and stdout to null\n    # $Out is an array contains each line per element\n    Invoke-Expression -OutVariable out \"$RequestComp\" 2>&1 | Out-Null\n\n    # get directive from last line\n    [int]$Directive = $Out[-1].TrimStart(':')\n    if ($Directive -eq \"\") {\n        # There is no directive specified\n        $Directive = 0\n    }\n    __%[1]s_debug \"The completion directive is: $Directive\"\n\n    # remove directive (last element) from out\n    $Out = $Out | Where-Object { $_ -ne $Out[-1] }\n    __%[1]s_debug \"The completions are: $Out\"\n\n    if (($Directive -band $ShellCompDirectiveError) -ne 0 ) {\n        # Error code.  No completion.\n        __%[1]s_debug \"Received error from custom completion go code\"\n        return\n    }\n\n    $Longest = 0\n    [Array]$Values = $Out | ForEach-Object {\n        #Split the output in name and description\n`+\"        $Name, $Description = $_.Split(\\\"`t\\\",2)\"+`\n        __%[1]s_debug \"Name: $Name Description: $Description\"\n\n        # Look for the longest completion so that we can format things nicely\n        if ($Longest -lt $Name.Length) {\n            $Longest = $Name.Length\n        }\n\n        # Set the description to a one space string if there is none set.\n        # This is needed because the CompletionResult does not accept an empty string as argument\n        if (-Not $Description) {\n            $Description = \" \"\n        }\n        @{Name=\"$Name\";Description=\"$Description\"}\n    }\n\n\n    $Space = \" \"\n    if (($Directive -band $ShellCompDirectiveNoSpace) -ne 0 ) {\n        # remove the space here\n        __%[1]s_debug \"ShellCompDirectiveNoSpace is called\"\n        $Space = \"\"\n    }\n\n    if ((($Directive -band $ShellCompDirectiveFilterFileExt) -ne 0 ) -or\n       (($Directive -band $ShellCompDirectiveFilterDirs) -ne 0 ))  {\n        __%[1]s_debug \"ShellCompDirectiveFilterFileExt ShellCompDirectiveFilterDirs are not supported\"\n\n        # return here to prevent the completion of the extensions\n        return\n    }\n\n    $Values = $Values | Where-Object {\n        # filter the result\n        $_.Name -like \"$WordToComplete*\"\n\n        # Join the flag back if we have an equal sign flag\n        if ( $IsEqualFlag ) {\n            __%[1]s_debug \"Join the equal sign flag back to the completion value\"\n            $_.Name = $Flag + \"=\" + $_.Name\n        }\n    }\n\n    # we sort the values in ascending order by name if keep order isn't passed\n    if (($Directive -band $ShellCompDirectiveKeepOrder) -eq 0 ) {\n        $Values = $Values | Sort-Object -Property Name\n    }\n\n    if (($Directive -band $ShellCompDirectiveNoFileComp) -ne 0 ) {\n        __%[1]s_debug \"ShellCompDirectiveNoFileComp is called\"\n\n        if ($Values.Length -eq 0) {\n            # Just print an empty string here so the\n            # shell does not start to complete paths.\n            # We cannot use CompletionResult here because\n            # it does not accept an empty string as argument.\n            \"\"\n            return\n        }\n    }\n\n    # Get the current mode\n    $Mode = (Get-PSReadLineKeyHandler | Where-Object {$_.Key -eq \"Tab\" }).Function\n    __%[1]s_debug \"Mode: $Mode\"\n\n    $Values | ForEach-Object {\n\n        # store temporary because switch will overwrite $_\n        $comp = $_\n\n        # PowerShell supports three different completion modes\n        # - TabCompleteNext (default windows style - on each key press the next option is displayed)\n        # - Complete (works like bash)\n        # - MenuComplete (works like zsh)\n        # You set the mode with Set-PSReadLineKeyHandler -Key Tab -Function <mode>\n\n        # CompletionResult Arguments:\n        # 1) CompletionText text to be used as the auto completion result\n        # 2) ListItemText   text to be displayed in the suggestion list\n        # 3) ResultType     type of completion result\n        # 4) ToolTip        text for the tooltip with details about the object\n\n        switch ($Mode) {\n\n            # bash like\n            \"Complete\" {\n\n                if ($Values.Length -eq 1) {\n                    __%[1]s_debug \"Only one completion left\"\n\n                    # insert space after value\n                    [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, \"$($comp.Name)\", 'ParameterValue', \"$($comp.Description)\")\n\n                } else {\n                    # Add the proper number of spaces to align the descriptions\n                    while($comp.Name.Length -lt $Longest) {\n                        $comp.Name = $comp.Name + \" \"\n                    }\n\n                    # Check for empty description and only add parentheses if needed\n                    if ($($comp.Description) -eq \" \" ) {\n                        $Description = \"\"\n                    } else {\n                        $Description = \"  ($($comp.Description))\"\n                    }\n\n                    [System.Management.Automation.CompletionResult]::new(\"$($comp.Name)$Description\", \"$($comp.Name)$Description\", 'ParameterValue', \"$($comp.Description)\")\n                }\n             }\n\n            # zsh like\n            \"MenuComplete\" {\n                # insert space after value\n                # MenuComplete will automatically show the ToolTip of\n                # the highlighted value at the bottom of the suggestions.\n                [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars) + $Space, \"$($comp.Name)\", 'ParameterValue', \"$($comp.Description)\")\n            }\n\n            # TabCompleteNext and in case we get something unknown\n            Default {\n                # Like MenuComplete but we don't want to add a space here because\n                # the user need to press space anyway to get the completion.\n                # Description will not be shown because that's not possible with TabCompleteNext\n                [System.Management.Automation.CompletionResult]::new($($comp.Name | __%[1]s_escapeStringWithSpecialChars), \"$($comp.Name)\", 'ParameterValue', \"$($comp.Description)\")\n            }\n        }\n\n    }\n}\n\nRegister-ArgumentCompleter -CommandName '%[1]s' -ScriptBlock $__%[2]sCompleterBlock\n`, name, nameForVar, compCmd,\n\t\tShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,\n\t\tShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder, activeHelpEnvVar(name)))\n}\n\nfunc (c *Command) genPowerShellCompletion(w io.Writer, includeDesc bool) error {\n\tbuf := new(bytes.Buffer)\n\tgenPowerShellComp(buf, c.Name(), includeDesc)\n\t_, err := buf.WriteTo(w)\n\treturn err\n}\n\nfunc (c *Command) genPowerShellCompletionFile(filename string, includeDesc bool) error {\n\toutFile, err := os.Create(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer outFile.Close()\n\n\treturn c.genPowerShellCompletion(outFile, includeDesc)\n}\n\n// GenPowerShellCompletionFile generates powershell completion file without descriptions.\nfunc (c *Command) GenPowerShellCompletionFile(filename string) error {\n\treturn c.genPowerShellCompletionFile(filename, false)\n}\n\n// GenPowerShellCompletion generates powershell completion file without descriptions\n// and writes it to the passed writer.\nfunc (c *Command) GenPowerShellCompletion(w io.Writer) error {\n\treturn c.genPowerShellCompletion(w, false)\n}\n\n// GenPowerShellCompletionFileWithDesc generates powershell completion file with descriptions.\nfunc (c *Command) GenPowerShellCompletionFileWithDesc(filename string) error {\n\treturn c.genPowerShellCompletionFile(filename, true)\n}\n\n// GenPowerShellCompletionWithDesc generates powershell completion file with descriptions\n// and writes it to the passed writer.\nfunc (c *Command) GenPowerShellCompletionWithDesc(w io.Writer) error {\n\treturn c.genPowerShellCompletion(w, true)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/powershell_completions.md",
    "content": "# Generating PowerShell Completions For Your Own cobra.Command\n\nPlease refer to [Shell Completions](shell_completions.md#powershell-completions) for details.\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/projects_using_cobra.md",
    "content": "## Projects using Cobra\n\n- [Allero](https://github.com/allero-io/allero)\n- [Arewefastyet](https://benchmark.vitess.io)\n- [Arduino CLI](https://github.com/arduino/arduino-cli)\n- [Bleve](https://blevesearch.com/)\n- [Cilium](https://cilium.io/)\n- [CloudQuery](https://github.com/cloudquery/cloudquery)\n- [CockroachDB](https://www.cockroachlabs.com/)\n- [Constellation](https://github.com/edgelesssys/constellation)\n- [Cosmos SDK](https://github.com/cosmos/cosmos-sdk)\n- [Datree](https://github.com/datreeio/datree)\n- [Delve](https://github.com/derekparker/delve)\n- [Docker (distribution)](https://github.com/docker/distribution)\n- [Etcd](https://etcd.io/)\n- [Gardener](https://github.com/gardener/gardenctl)\n- [Giant Swarm's gsctl](https://github.com/giantswarm/gsctl)\n- [Git Bump](https://github.com/erdaltsksn/git-bump)\n- [GitHub CLI](https://github.com/cli/cli)\n- [GitHub Labeler](https://github.com/erdaltsksn/gh-label)\n- [Golangci-lint](https://golangci-lint.run)\n- [GopherJS](https://github.com/gopherjs/gopherjs)\n- [GoReleaser](https://goreleaser.com)\n- [Helm](https://helm.sh)\n- [Hugo](https://gohugo.io)\n- [Infracost](https://github.com/infracost/infracost)\n- [Istio](https://istio.io)\n- [Kool](https://github.com/kool-dev/kool)\n- [Kubernetes](https://kubernetes.io/)\n- [Kubescape](https://github.com/kubescape/kubescape)\n- [KubeVirt](https://github.com/kubevirt/kubevirt)\n- [Linkerd](https://linkerd.io/)\n- [Mattermost-server](https://github.com/mattermost/mattermost-server)\n- [Mercure](https://mercure.rocks/)\n- [Meroxa CLI](https://github.com/meroxa/cli)\n- [Metal Stack CLI](https://github.com/metal-stack/metalctl)\n- [Moby (former Docker)](https://github.com/moby/moby)\n- [Moldy](https://github.com/Moldy-Community/moldy)\n- [Multi-gitter](https://github.com/lindell/multi-gitter)\n- [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)\n- [nFPM](https://nfpm.goreleaser.com)\n- [Okteto](https://github.com/okteto/okteto)\n- [OpenShift](https://www.openshift.com/)\n- [Ory Hydra](https://github.com/ory/hydra)\n- [Ory Kratos](https://github.com/ory/kratos)\n- [Pixie](https://github.com/pixie-io/pixie)\n- [Polygon Edge](https://github.com/0xPolygon/polygon-edge)\n- [Pouch](https://github.com/alibaba/pouch)\n- [ProjectAtomic (enterprise)](https://www.projectatomic.io/)\n- [Prototool](https://github.com/uber/prototool)\n- [Pulumi](https://www.pulumi.com)\n- [QRcp](https://github.com/claudiodangelis/qrcp)\n- [Random](https://github.com/erdaltsksn/random)\n- [Rclone](https://rclone.org/)\n- [Scaleway CLI](https://github.com/scaleway/scaleway-cli)\n- [Sia](https://github.com/SiaFoundation/siad)\n- [Skaffold](https://skaffold.dev/)\n- [Tendermint](https://github.com/tendermint/tendermint)\n- [Twitch CLI](https://github.com/twitchdev/twitch-cli)\n- [UpCloud CLI (`upctl`)](https://github.com/UpCloudLtd/upcloud-cli)\n- [Vitess](https://vitess.io)\n- VMware's [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) & [Tanzu Framework](https://github.com/vmware-tanzu/tanzu-framework)\n- [Werf](https://werf.io/)\n- [ZITADEL](https://github.com/zitadel/zitadel)\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/shell_completions.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"github.com/spf13/pflag\"\n)\n\n// MarkFlagRequired instructs the various shell completion implementations to\n// prioritize the named flag when performing completion,\n// and causes your command to report an error if invoked without the flag.\nfunc (c *Command) MarkFlagRequired(name string) error {\n\treturn MarkFlagRequired(c.Flags(), name)\n}\n\n// MarkPersistentFlagRequired instructs the various shell completion implementations to\n// prioritize the named persistent flag when performing completion,\n// and causes your command to report an error if invoked without the flag.\nfunc (c *Command) MarkPersistentFlagRequired(name string) error {\n\treturn MarkFlagRequired(c.PersistentFlags(), name)\n}\n\n// MarkFlagRequired instructs the various shell completion implementations to\n// prioritize the named flag when performing completion,\n// and causes your command to report an error if invoked without the flag.\nfunc MarkFlagRequired(flags *pflag.FlagSet, name string) error {\n\treturn flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{\"true\"})\n}\n\n// MarkFlagFilename instructs the various shell completion implementations to\n// limit completions for the named flag to the specified file extensions.\nfunc (c *Command) MarkFlagFilename(name string, extensions ...string) error {\n\treturn MarkFlagFilename(c.Flags(), name, extensions...)\n}\n\n// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.\n// The bash completion script will call the bash function f for the flag.\n//\n// This will only work for bash completion.\n// It is recommended to instead use c.RegisterFlagCompletionFunc(...) which allows\n// to register a Go function which will work across all shells.\nfunc (c *Command) MarkFlagCustom(name string, f string) error {\n\treturn MarkFlagCustom(c.Flags(), name, f)\n}\n\n// MarkPersistentFlagFilename instructs the various shell completion\n// implementations to limit completions for the named persistent flag to the\n// specified file extensions.\nfunc (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {\n\treturn MarkFlagFilename(c.PersistentFlags(), name, extensions...)\n}\n\n// MarkFlagFilename instructs the various shell completion implementations to\n// limit completions for the named flag to the specified file extensions.\nfunc MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error {\n\treturn flags.SetAnnotation(name, BashCompFilenameExt, extensions)\n}\n\n// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.\n// The bash completion script will call the bash function f for the flag.\n//\n// This will only work for bash completion.\n// It is recommended to instead use c.RegisterFlagCompletionFunc(...) which allows\n// to register a Go function which will work across all shells.\nfunc MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error {\n\treturn flags.SetAnnotation(name, BashCompCustom, []string{f})\n}\n\n// MarkFlagDirname instructs the various shell completion implementations to\n// limit completions for the named flag to directory names.\nfunc (c *Command) MarkFlagDirname(name string) error {\n\treturn MarkFlagDirname(c.Flags(), name)\n}\n\n// MarkPersistentFlagDirname instructs the various shell completion\n// implementations to limit completions for the named persistent flag to\n// directory names.\nfunc (c *Command) MarkPersistentFlagDirname(name string) error {\n\treturn MarkFlagDirname(c.PersistentFlags(), name)\n}\n\n// MarkFlagDirname instructs the various shell completion implementations to\n// limit completions for the named flag to directory names.\nfunc MarkFlagDirname(flags *pflag.FlagSet, name string) error {\n\treturn flags.SetAnnotation(name, BashCompSubdirsInDir, []string{})\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/shell_completions.md",
    "content": "# Generating shell completions\n\nCobra can generate shell completions for multiple shells.\nThe currently supported shells are:\n- Bash\n- Zsh\n- fish\n- PowerShell\n\nCobra will automatically provide your program with a fully functional `completion` command,\nsimilarly to how it provides the `help` command.\n\n## Creating your own completion command\n\nIf you do not wish to use the default `completion` command, you can choose to\nprovide your own, which will take precedence over the default one. (This also provides\nbackwards-compatibility with programs that already have their own `completion` command.)\n\nIf you are using the `cobra-cli` generator,\nwhich can be found at [spf13/cobra-cli](https://github.com/spf13/cobra-cli),\nyou can create a completion command by running\n\n```bash\ncobra-cli add completion\n```\nand then modifying the generated `cmd/completion.go` file to look something like this\n(writing the shell script to stdout allows the most flexible use):\n\n```go\nvar completionCmd = &cobra.Command{\n\tUse:   \"completion [bash|zsh|fish|powershell]\",\n\tShort: \"Generate completion script\",\n\tLong: fmt.Sprintf(`To load completions:\n\nBash:\n\n  $ source <(%[1]s completion bash)\n\n  # To load completions for each session, execute once:\n  # Linux:\n  $ %[1]s completion bash > /etc/bash_completion.d/%[1]s\n  # macOS:\n  $ %[1]s completion bash > $(brew --prefix)/etc/bash_completion.d/%[1]s\n\nZsh:\n\n  # If shell completion is not already enabled in your environment,\n  # you will need to enable it.  You can execute the following once:\n\n  $ echo \"autoload -U compinit; compinit\" >> ~/.zshrc\n\n  # To load completions for each session, execute once:\n  $ %[1]s completion zsh > \"${fpath[1]}/_%[1]s\"\n\n  # You will need to start a new shell for this setup to take effect.\n\nfish:\n\n  $ %[1]s completion fish | source\n\n  # To load completions for each session, execute once:\n  $ %[1]s completion fish > ~/.config/fish/completions/%[1]s.fish\n\nPowerShell:\n\n  PS> %[1]s completion powershell | Out-String | Invoke-Expression\n\n  # To load completions for every new session, run:\n  PS> %[1]s completion powershell > %[1]s.ps1\n  # and source this file from your PowerShell profile.\n`,cmd.Root().Name()),\n\tDisableFlagsInUseLine: true,\n\tValidArgs:             []string{\"bash\", \"zsh\", \"fish\", \"powershell\"},\n\tArgs:                  cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tswitch args[0] {\n\t\tcase \"bash\":\n\t\t\tcmd.Root().GenBashCompletion(os.Stdout)\n\t\tcase \"zsh\":\n\t\t\tcmd.Root().GenZshCompletion(os.Stdout)\n\t\tcase \"fish\":\n\t\t\tcmd.Root().GenFishCompletion(os.Stdout, true)\n\t\tcase \"powershell\":\n\t\t\tcmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)\n\t\t}\n\t},\n}\n```\n\n**Note:** The cobra generator may include messages printed to stdout, for example, if the config file is loaded; this will break the auto-completion script so must be removed.\n\n## Adapting the default completion command\n\nCobra provides a few options for the default `completion` command.  To configure such options you must set\nthe `CompletionOptions` field on the *root* command.\n\nTo tell Cobra *not* to provide the default `completion` command:\n```\nrootCmd.CompletionOptions.DisableDefaultCmd = true\n```\n\nTo tell Cobra to mark the default `completion` command as *hidden*:\n```\nrootCmd.CompletionOptions.HiddenDefaultCmd = true\n```\n\nTo tell Cobra *not* to provide the user with the `--no-descriptions` flag to the completion sub-commands:\n```\nrootCmd.CompletionOptions.DisableNoDescFlag = true\n```\n\nTo tell Cobra to completely disable descriptions for completions:\n```\nrootCmd.CompletionOptions.DisableDescriptions = true\n```\n\n# Customizing completions\n\nThe generated completion scripts will automatically handle completing commands and flags.  However, you can make your completions much more powerful by providing information to complete your program's nouns and flag values.\n\n## Completion of nouns\n\n### Static completion of nouns\n\nCobra allows you to provide a pre-defined list of completion choices for your nouns using the `ValidArgs` field.\nFor example, if you want `kubectl get [tab][tab]` to show a list of valid \"nouns\" you have to set them.\nSome simplified code from `kubectl get` looks like:\n\n```go\nvalidArgs = []string{ \"pod\", \"node\", \"service\", \"replicationcontroller\" }\n\ncmd := &cobra.Command{\n\tUse:     \"get [(-o|--output=)json|yaml|template|...] (RESOURCE [NAME] | RESOURCE/NAME ...)\",\n\tShort:   \"Display one or many resources\",\n\tLong:    get_long,\n\tExample: get_example,\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tcobra.CheckErr(RunGet(f, out, cmd, args))\n\t},\n\tValidArgs: validArgs,\n}\n```\n\nNotice we put the `ValidArgs` field on the `get` sub-command. Doing so will give results like:\n\n```bash\n$ kubectl get [tab][tab]\nnode   pod   replicationcontroller   service\n```\n\n#### Aliases for nouns\n\nIf your nouns have aliases, you can define them alongside `ValidArgs` using `ArgAliases`:\n\n```go\nargAliases = []string { \"pods\", \"nodes\", \"services\", \"svc\", \"replicationcontrollers\", \"rc\" }\n\ncmd := &cobra.Command{\n    ...\n\tValidArgs:  validArgs,\n\tArgAliases: argAliases\n}\n```\n\nThe aliases are shown to the user on tab completion only if no completions were found within sub-commands or `ValidArgs`.\n\n### Dynamic completion of nouns\n\nIn some cases it is not possible to provide a list of completions in advance.  Instead, the list of completions must be determined at execution-time. In a similar fashion as for static completions, you can use the `ValidArgsFunction` field to provide a Go function that Cobra will execute when it needs the list of completion choices for the nouns of a command.  Note that either `ValidArgs` or `ValidArgsFunction` can be used for a single cobra command, but not both.\nSimplified code from `helm status` looks like:\n\n```go\ncmd := &cobra.Command{\n\tUse:   \"status RELEASE_NAME\",\n\tShort: \"Display the status of the named release\",\n\tLong:  status_long,\n\tRunE: func(cmd *cobra.Command, args []string) {\n\t\tRunGet(args[0])\n\t},\n\tValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\t\tif len(args) != 0 {\n\t\t\treturn nil, cobra.ShellCompDirectiveNoFileComp\n\t\t}\n\t\treturn getReleasesFromCluster(toComplete), cobra.ShellCompDirectiveNoFileComp\n\t},\n}\n```\nWhere `getReleasesFromCluster()` is a Go function that obtains the list of current Helm releases running on the Kubernetes cluster.\nNotice we put the `ValidArgsFunction` on the `status` sub-command. Let's assume the Helm releases on the cluster are: `harbor`, `notary`, `rook` and `thanos` then this dynamic completion will give results like:\n\n```bash\n$ helm status [tab][tab]\nharbor notary rook thanos\n```\nYou may have noticed the use of `cobra.ShellCompDirective`.  These directives are bit fields allowing to control some shell completion behaviors for your particular completion.  You can combine them with the bit-or operator such as `cobra.ShellCompDirectiveNoSpace | cobra.ShellCompDirectiveNoFileComp`\n```go\n// Indicates that the shell will perform its default behavior after completions\n// have been provided (this implies none of the other directives).\nShellCompDirectiveDefault\n\n// Indicates an error occurred and completions should be ignored.\nShellCompDirectiveError\n\n// Indicates that the shell should not add a space after the completion,\n// even if there is a single completion provided.\nShellCompDirectiveNoSpace\n\n// Indicates that the shell should not provide file completion even when\n// no completion is provided.\nShellCompDirectiveNoFileComp\n\n// Indicates that the returned completions should be used as file extension filters.\n// For example, to complete only files of the form *.json or *.yaml:\n//    return []string{\"yaml\", \"json\"}, ShellCompDirectiveFilterFileExt\n// For flags, using MarkFlagFilename() and MarkPersistentFlagFilename()\n// is a shortcut to using this directive explicitly.\n//\nShellCompDirectiveFilterFileExt\n\n// Indicates that only directory names should be provided in file completion.\n// For example:\n//    return nil, ShellCompDirectiveFilterDirs\n// For flags, using MarkFlagDirname() is a shortcut to using this directive explicitly.\n//\n// To request directory names within another directory, the returned completions\n// should specify a single directory name within which to search. For example,\n// to complete directories within \"themes/\":\n//    return []string{\"themes\"}, ShellCompDirectiveFilterDirs\n//\nShellCompDirectiveFilterDirs\n\n// ShellCompDirectiveKeepOrder indicates that the shell should preserve the order\n// in which the completions are provided\nShellCompDirectiveKeepOrder\n```\n\n***Note***: When using the `ValidArgsFunction`, Cobra will call your registered function after having parsed all flags and arguments provided in the command-line.  You therefore don't need to do this parsing yourself.  For example, when a user calls `helm status --namespace my-rook-ns [tab][tab]`, Cobra will call your registered `ValidArgsFunction` after having parsed the `--namespace` flag, as it would have done when calling the `RunE` function.\n\n#### Debugging\n\nCobra achieves dynamic completion through the use of a hidden command called by the completion script.  To debug your Go completion code, you can call this hidden command directly:\n```bash\n$ helm __complete status har<ENTER>\nharbor\n:4\nCompletion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr\n```\n***Important:*** If the noun to complete is empty (when the user has not yet typed any letters of that noun), you must pass an empty parameter to the `__complete` command:\n```bash\n$ helm __complete status \"\"<ENTER>\nharbor\nnotary\nrook\nthanos\n:4\nCompletion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr\n```\nCalling the `__complete` command directly allows you to run the Go debugger to troubleshoot your code.  You can also add printouts to your code; Cobra provides the following functions to use for printouts in Go completion code:\n```go\n// Prints to the completion script debug file (if BASH_COMP_DEBUG_FILE\n// is set to a file path) and optionally prints to stderr.\ncobra.CompDebug(msg string, printToStdErr bool) {\ncobra.CompDebugln(msg string, printToStdErr bool)\n\n// Prints to the completion script debug file (if BASH_COMP_DEBUG_FILE\n// is set to a file path) and to stderr.\ncobra.CompError(msg string)\ncobra.CompErrorln(msg string)\n```\n***Important:*** You should **not** leave traces that print directly to stdout in your completion code as they will be interpreted as completion choices by the completion script.  Instead, use the cobra-provided debugging traces functions mentioned above.\n\n## Completions for flags\n\n### Mark flags as required\n\nMost of the time completions will only show sub-commands. But if a flag is required to make a sub-command work, you probably want it to show up when the user types [tab][tab].  You can mark a flag as 'Required' like so:\n\n```go\ncmd.MarkFlagRequired(\"pod\")\ncmd.MarkFlagRequired(\"container\")\n```\n\nand you'll get something like\n\n```bash\n$ kubectl exec [tab][tab]\n-c            --container=  -p            --pod=\n```\n\n### Specify dynamic flag completion\n\nAs for nouns, Cobra provides a way of defining dynamic completion of flags.  To provide a Go function that Cobra will execute when it needs the list of completion choices for a flag, you must register the function using the `command.RegisterFlagCompletionFunc()` function.\n\n```go\nflagName := \"output\"\ncmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\treturn []string{\"json\", \"table\", \"yaml\"}, cobra.ShellCompDirectiveDefault\n})\n```\nNotice that calling `RegisterFlagCompletionFunc()` is done through the `command` with which the flag is associated.  In our example this dynamic completion will give results like so:\n\n```bash\n$ helm status --output [tab][tab]\njson table yaml\n```\n\n#### Debugging\n\nYou can also easily debug your Go completion code for flags:\n```bash\n$ helm __complete status --output \"\"\njson\ntable\nyaml\n:4\nCompletion ended with directive: ShellCompDirectiveNoFileComp # This is on stderr\n```\n***Important:*** You should **not** leave traces that print to stdout in your completion code as they will be interpreted as completion choices by the completion script.  Instead, use the cobra-provided debugging traces functions mentioned further above.\n\n### Specify valid filename extensions for flags that take a filename\n\nTo limit completions of flag values to file names with certain extensions you can either use the different `MarkFlagFilename()` functions or a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterFileExt`, like so:\n```go\nflagName := \"output\"\ncmd.MarkFlagFilename(flagName, \"yaml\", \"json\")\n```\nor\n```go\nflagName := \"output\"\ncmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\treturn []string{\"yaml\", \"json\"}, ShellCompDirectiveFilterFileExt})\n```\n\n### Limit flag completions to directory names\n\nTo limit completions of flag values to directory names you can either use the `MarkFlagDirname()` functions or a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterDirs`, like so:\n```go\nflagName := \"output\"\ncmd.MarkFlagDirname(flagName)\n```\nor\n```go\nflagName := \"output\"\ncmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\treturn nil, cobra.ShellCompDirectiveFilterDirs\n})\n```\nTo limit completions of flag values to directory names *within another directory* you can use a combination of `RegisterFlagCompletionFunc()` and `ShellCompDirectiveFilterDirs` like so:\n```go\nflagName := \"output\"\ncmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\treturn []string{\"themes\"}, cobra.ShellCompDirectiveFilterDirs\n})\n```\n### Descriptions for completions\n\nCobra provides support for completion descriptions.  Such descriptions are supported for each shell\n(however, for bash, it is only available in the [completion V2 version](#bash-completion-v2)).\nFor commands and flags, Cobra will provide the descriptions automatically, based on usage information.\nFor example, using zsh:\n```\n$ helm s[tab]\nsearch  -- search for a keyword in charts\nshow    -- show information of a chart\nstatus  -- displays the status of the named release\n```\nwhile using fish:\n```\n$ helm s[tab]\nsearch  (search for a keyword in charts)  show  (show information of a chart)  status  (displays the status of the named release)\n```\n\nCobra allows you to add descriptions to your own completions.  Simply add the description text after each completion, following a `\\t` separator.  This technique applies to completions returned by `ValidArgs`, `ValidArgsFunction` and `RegisterFlagCompletionFunc()`.  For example:\n```go\nValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {\n\treturn []string{\"harbor\\tAn image registry\", \"thanos\\tLong-term metrics\"}, cobra.ShellCompDirectiveNoFileComp\n}}\n```\nor\n```go\nValidArgs: []string{\"bash\\tCompletions for bash\", \"zsh\\tCompletions for zsh\"}\n```\n\nIf you don't want to show descriptions in the completions, you can add `--no-descriptions` to the default `completion` command to disable them, like:\n\n```bash\n$ source <(helm completion bash)\n$ helm completion [tab][tab]\nbash        (generate autocompletion script for bash)        powershell  (generate autocompletion script for powershell)\nfish        (generate autocompletion script for fish)        zsh         (generate autocompletion script for zsh)\n\n$ source <(helm completion bash --no-descriptions)\n$ helm completion [tab][tab]\nbash        fish        powershell  zsh\n```\n## Bash completions\n\n### Dependencies\n\nThe bash completion script generated by Cobra requires the `bash_completion` package. You should update the help text of your completion command to show how to install the `bash_completion` package ([Kubectl docs](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion))\n\n### Aliases\n\nYou can also configure `bash` aliases for your program and they will also support completions.\n\n```bash\nalias aliasname=origcommand\ncomplete -o default -F __start_origcommand aliasname\n\n# and now when you run `aliasname` completion will make\n# suggestions as it did for `origcommand`.\n\n$ aliasname <tab><tab>\ncompletion     firstcommand   secondcommand\n```\n### Bash legacy dynamic completions\n\nFor backward compatibility, Cobra still supports its bash legacy dynamic completion solution.\nPlease refer to [Bash Completions](bash_completions.md) for details.\n\n### Bash completion V2\n\nCobra provides two versions for bash completion.  The original bash completion (which started it all!) can be used by calling\n`GenBashCompletion()` or `GenBashCompletionFile()`.\n\nA new V2 bash completion version is also available.  This version can be used by calling `GenBashCompletionV2()` or\n`GenBashCompletionFileV2()`.  The V2 version does **not** support the legacy dynamic completion\n(see [Bash Completions](bash_completions.md)) but instead works only with the Go dynamic completion\nsolution described in this document.\nUnless your program already uses the legacy dynamic completion solution, it is recommended that you use the bash\ncompletion V2 solution which provides the following extra features:\n- Supports completion descriptions (like the other shells)\n- Small completion script of less than 300 lines (v1 generates scripts of thousands of lines; `kubectl` for example has a bash v1 completion script of over 13K lines)\n- Streamlined user experience thanks to a completion behavior aligned with the other shells \n\n`Bash` completion V2 supports descriptions for completions. When calling `GenBashCompletionV2()` or `GenBashCompletionFileV2()`\nyou must provide these functions with a parameter indicating if the completions should be annotated with a description; Cobra\nwill provide the description automatically based on usage information.  You can choose to make this option configurable by\nyour users.\n\n```\n# With descriptions\n$ helm s[tab][tab]\nsearch  (search for a keyword in charts)           status  (display the status of the named release)\nshow    (show information of a chart)\n\n# Without descriptions\n$ helm s[tab][tab]\nsearch  show  status\n```\n**Note**: Cobra's default `completion` command uses bash completion V2.  If for some reason you need to use bash completion V1, you will need to implement your own `completion` command. \n## Zsh completions\n\nCobra supports native zsh completion generated from the root `cobra.Command`.\nThe generated completion script should be put somewhere in your `$fpath` and be named\n`_<yourProgram>`.  You will need to start a new shell for the completions to become available.\n\nZsh supports descriptions for completions. Cobra will provide the description automatically,\nbased on usage information. Cobra provides a way to completely disable such descriptions by\nusing `GenZshCompletionNoDesc()` or `GenZshCompletionFileNoDesc()`. You can choose to make\nthis a configurable option to your users.\n```\n# With descriptions\n$ helm s[tab]\nsearch  -- search for a keyword in charts\nshow    -- show information of a chart\nstatus  -- displays the status of the named release\n\n# Without descriptions\n$ helm s[tab]\nsearch  show  status\n```\n*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`.\n\n### Limitations\n\n* Custom completions implemented in Bash scripting (legacy) are not supported and will be ignored for `zsh` (including the use of the `BashCompCustom` flag annotation).\n  * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).\n* The function `MarkFlagCustom()` is not supported and will be ignored for `zsh`.\n  * You should instead use `RegisterFlagCompletionFunc()`.\n\n### Zsh completions standardization\n\nCobra 1.1 standardized its zsh completion support to align it with its other shell completions.  Although the API was kept backward-compatible, some small changes in behavior were introduced.\nPlease refer to [Zsh Completions](zsh_completions.md) for details.\n\n## fish completions\n\nCobra supports native fish completions generated from the root `cobra.Command`.  You can use the `command.GenFishCompletion()` or `command.GenFishCompletionFile()` functions. You must provide these functions with a parameter indicating if the completions should be annotated with a description; Cobra will provide the description automatically based on usage information.  You can choose to make this option configurable by your users.\n```\n# With descriptions\n$ helm s[tab]\nsearch  (search for a keyword in charts)  show  (show information of a chart)  status  (displays the status of the named release)\n\n# Without descriptions\n$ helm s[tab]\nsearch  show  status\n```\n*Note*: Because of backward-compatibility requirements, we were forced to have a different API to disable completion descriptions between `zsh` and `fish`.\n\n### Limitations\n\n* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `fish` (including the use of the `BashCompCustom` flag annotation).\n  * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).\n* The function `MarkFlagCustom()` is not supported and will be ignored for `fish`.\n  * You should instead use `RegisterFlagCompletionFunc()`.\n* The following flag completion annotations are not supported and will be ignored for `fish`:\n  * `BashCompFilenameExt` (filtering by file extension)\n  * `BashCompSubdirsInDir` (filtering by directory)\n* The functions corresponding to the above annotations are consequently not supported and will be ignored for `fish`:\n  * `MarkFlagFilename()` and `MarkPersistentFlagFilename()` (filtering by file extension)\n  * `MarkFlagDirname()` and `MarkPersistentFlagDirname()` (filtering by directory)\n* Similarly, the following completion directives are not supported and will be ignored for `fish`:\n  * `ShellCompDirectiveFilterFileExt` (filtering by file extension)\n  * `ShellCompDirectiveFilterDirs` (filtering by directory)\n\n## PowerShell completions\n\nCobra supports native PowerShell completions generated from the root `cobra.Command`. You can use the `command.GenPowerShellCompletion()` or `command.GenPowerShellCompletionFile()` functions. To include descriptions use `command.GenPowerShellCompletionWithDesc()` and `command.GenPowerShellCompletionFileWithDesc()`. Cobra will provide the description automatically based on usage information. You can choose to make this option configurable by your users.\n\nThe script is designed to support all three PowerShell completion modes:\n\n* TabCompleteNext (default windows style - on each key press the next option is displayed)\n* Complete (works like bash)\n* MenuComplete (works like zsh)\n\nYou set the mode with `Set-PSReadLineKeyHandler -Key Tab -Function <mode>`. Descriptions are only displayed when using the `Complete` or `MenuComplete` mode.\n\nUsers need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles.\n\n```\n# With descriptions and Mode 'Complete'\n$ helm s[tab]\nsearch  (search for a keyword in charts)  show  (show information of a chart)  status  (displays the status of the named release)\n\n# With descriptions and Mode 'MenuComplete' The description of the current selected value will be displayed below the suggestions.\n$ helm s[tab]\nsearch    show     status  \n\nsearch for a keyword in charts\n\n# Without descriptions\n$ helm s[tab]\nsearch  show  status\n```\n### Aliases\n\nYou can also configure `powershell` aliases for your program and they will also support completions.\n\n```\n$ sal aliasname origcommand\n$ Register-ArgumentCompleter -CommandName 'aliasname' -ScriptBlock $__origcommandCompleterBlock\n\n# and now when you run `aliasname` completion will make\n# suggestions as it did for `origcommand`.\n\n$ aliasname <tab>\ncompletion     firstcommand   secondcommand\n```\nThe name of the completer block variable is of the form `$__<programName>CompleterBlock` where every `-` and `:` in the program name have been replaced with `_`, to respect powershell naming syntax.\n\n### Limitations\n\n* Custom completions implemented in bash scripting (legacy) are not supported and will be ignored for `powershell` (including the use of the `BashCompCustom` flag annotation).\n  * You should instead use `ValidArgsFunction` and `RegisterFlagCompletionFunc()` which are portable to the different shells (`bash`, `zsh`, `fish`, `powershell`).\n* The function `MarkFlagCustom()` is not supported and will be ignored for `powershell`.\n  * You should instead use `RegisterFlagCompletionFunc()`.\n* The following flag completion annotations are not supported and will be ignored for `powershell`:\n  * `BashCompFilenameExt` (filtering by file extension)\n  * `BashCompSubdirsInDir` (filtering by directory)\n* The functions corresponding to the above annotations are consequently not supported and will be ignored for `powershell`:\n  * `MarkFlagFilename()` and `MarkPersistentFlagFilename()` (filtering by file extension)\n  * `MarkFlagDirname()` and `MarkPersistentFlagDirname()` (filtering by directory)\n* Similarly, the following completion directives are not supported and will be ignored for `powershell`:\n  * `ShellCompDirectiveFilterFileExt` (filtering by file extension)\n  * `ShellCompDirectiveFilterDirs` (filtering by directory)\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/user_guide.md",
    "content": "# User Guide\n\nWhile you are welcome to provide your own organization, typically a Cobra-based\napplication will follow the following organizational structure:\n\n```\n  ▾ appName/\n    ▾ cmd/\n        add.go\n        your.go\n        commands.go\n        here.go\n      main.go\n```\n\nIn a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra.\n\n```go\npackage main\n\nimport (\n  \"{pathToYourApp}/cmd\"\n)\n\nfunc main() {\n  cmd.Execute()\n}\n```\n\n## Using the Cobra Generator\n\nCobra-CLI is its own program that will create your application and add any\ncommands you want. It's the easiest way to incorporate Cobra into your application.\n\nFor complete details on using the Cobra generator, please refer to [The Cobra-CLI Generator README](https://github.com/spf13/cobra-cli/blob/main/README.md)\n\n## Using the Cobra Library\n\nTo manually implement Cobra you need to create a bare main.go file and a rootCmd file.\nYou will optionally provide additional commands as you see fit.\n\n### Create rootCmd\n\nCobra doesn't require any special constructors. Simply create your commands.\n\nIdeally you place this in app/cmd/root.go:\n\n```go\nvar rootCmd = &cobra.Command{\n  Use:   \"hugo\",\n  Short: \"Hugo is a very fast static site generator\",\n  Long: `A Fast and Flexible Static Site Generator built with\n                love by spf13 and friends in Go.\n                Complete documentation is available at https://gohugo.io/documentation/`,\n  Run: func(cmd *cobra.Command, args []string) {\n    // Do Stuff Here\n  },\n}\n\nfunc Execute() {\n  if err := rootCmd.Execute(); err != nil {\n    fmt.Fprintln(os.Stderr, err)\n    os.Exit(1)\n  }\n}\n```\n\nYou will additionally define flags and handle configuration in your init() function.\n\nFor example cmd/root.go:\n\n```go\npackage cmd\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/viper\"\n)\n\nvar (\n\t// Used for flags.\n\tcfgFile     string\n\tuserLicense string\n\n\trootCmd = &cobra.Command{\n\t\tUse:   \"cobra-cli\",\n\t\tShort: \"A generator for Cobra based Applications\",\n\t\tLong: `Cobra is a CLI library for Go that empowers applications.\nThis application is a tool to generate the needed files\nto quickly create a Cobra application.`,\n\t}\n)\n\n// Execute executes the root command.\nfunc Execute() error {\n\treturn rootCmd.Execute()\n}\n\nfunc init() {\n\tcobra.OnInitialize(initConfig)\n\n\trootCmd.PersistentFlags().StringVar(&cfgFile, \"config\", \"\", \"config file (default is $HOME/.cobra.yaml)\")\n\trootCmd.PersistentFlags().StringP(\"author\", \"a\", \"YOUR NAME\", \"author name for copyright attribution\")\n\trootCmd.PersistentFlags().StringVarP(&userLicense, \"license\", \"l\", \"\", \"name of license for the project\")\n\trootCmd.PersistentFlags().Bool(\"viper\", true, \"use Viper for configuration\")\n\tviper.BindPFlag(\"author\", rootCmd.PersistentFlags().Lookup(\"author\"))\n\tviper.BindPFlag(\"useViper\", rootCmd.PersistentFlags().Lookup(\"viper\"))\n\tviper.SetDefault(\"author\", \"NAME HERE <EMAIL ADDRESS>\")\n\tviper.SetDefault(\"license\", \"apache\")\n\n\trootCmd.AddCommand(addCmd)\n\trootCmd.AddCommand(initCmd)\n}\n\nfunc initConfig() {\n\tif cfgFile != \"\" {\n\t\t// Use config file from the flag.\n\t\tviper.SetConfigFile(cfgFile)\n\t} else {\n\t\t// Find home directory.\n\t\thome, err := os.UserHomeDir()\n\t\tcobra.CheckErr(err)\n\n\t\t// Search config in home directory with name \".cobra\" (without extension).\n\t\tviper.AddConfigPath(home)\n\t\tviper.SetConfigType(\"yaml\")\n\t\tviper.SetConfigName(\".cobra\")\n\t}\n\n\tviper.AutomaticEnv()\n\n\tif err := viper.ReadInConfig(); err == nil {\n\t\tfmt.Println(\"Using config file:\", viper.ConfigFileUsed())\n\t}\n}\n```\n\n### Create your main.go\n\nWith the root command you need to have your main function execute it.\nExecute should be run on the root for clarity, though it can be called on any command.\n\nIn a Cobra app, typically the main.go file is very bare. It serves one purpose: to initialize Cobra.\n\n```go\npackage main\n\nimport (\n  \"{pathToYourApp}/cmd\"\n)\n\nfunc main() {\n  cmd.Execute()\n}\n```\n\n### Create additional commands\n\nAdditional commands can be defined and typically are each given their own file\ninside of the cmd/ directory.\n\nIf you wanted to create a version command you would create cmd/version.go and\npopulate it with the following:\n\n```go\npackage cmd\n\nimport (\n  \"fmt\"\n\n  \"github.com/spf13/cobra\"\n)\n\nfunc init() {\n  rootCmd.AddCommand(versionCmd)\n}\n\nvar versionCmd = &cobra.Command{\n  Use:   \"version\",\n  Short: \"Print the version number of Hugo\",\n  Long:  `All software has versions. This is Hugo's`,\n  Run: func(cmd *cobra.Command, args []string) {\n    fmt.Println(\"Hugo Static Site Generator v0.9 -- HEAD\")\n  },\n}\n```\n\n### Organizing subcommands\n\nA command may have subcommands which in turn may have other subcommands. This is achieved by using\n`AddCommand`. In some cases, especially in larger applications, each subcommand may be defined in\nits own go package.\n\nThe suggested approach is for the parent command to use `AddCommand` to add its most immediate\nsubcommands. For example, consider the following directory structure:\n\n```text\n├── cmd\n│   ├── root.go\n│   └── sub1\n│       ├── sub1.go\n│       └── sub2\n│           ├── leafA.go\n│           ├── leafB.go\n│           └── sub2.go\n└── main.go\n```\n\nIn this case:\n\n* The `init` function of `root.go` adds the command defined in `sub1.go` to the root command.\n* The `init` function of `sub1.go` adds the command defined in `sub2.go` to the sub1 command.\n* The `init` function of `sub2.go` adds the commands defined in `leafA.go` and `leafB.go` to the\n  sub2 command.\n\nThis approach ensures the subcommands are always included at compile time while avoiding cyclic\nreferences.\n\n### Returning and handling errors\n\nIf you wish to return an error to the caller of a command, `RunE` can be used.\n\n```go\npackage cmd\n\nimport (\n  \"fmt\"\n\n  \"github.com/spf13/cobra\"\n)\n\nfunc init() {\n  rootCmd.AddCommand(tryCmd)\n}\n\nvar tryCmd = &cobra.Command{\n  Use:   \"try\",\n  Short: \"Try and possibly fail at something\",\n  RunE: func(cmd *cobra.Command, args []string) error {\n    if err := someFunc(); err != nil {\n\treturn err\n    }\n    return nil\n  },\n}\n```\n\nThe error can then be caught at the execute function call.\n\n## Working with Flags\n\nFlags provide modifiers to control how the action command operates.\n\n### Assign flags to a command\n\nSince the flags are defined and used in different locations, we need to\ndefine a variable outside with the correct scope to assign the flag to\nwork with.\n\n```go\nvar Verbose bool\nvar Source string\n```\n\nThere are two different approaches to assign a flag.\n\n### Persistent Flags\n\nA flag can be 'persistent', meaning that this flag will be available to the\ncommand it's assigned to as well as every command under that command. For\nglobal flags, assign a flag as a persistent flag on the root.\n\n```go\nrootCmd.PersistentFlags().BoolVarP(&Verbose, \"verbose\", \"v\", false, \"verbose output\")\n```\n\n### Local Flags\n\nA flag can also be assigned locally, which will only apply to that specific command.\n\n```go\nlocalCmd.Flags().StringVarP(&Source, \"source\", \"s\", \"\", \"Source directory to read from\")\n```\n\n### Local Flag on Parent Commands\n\nBy default, Cobra only parses local flags on the target command, and any local flags on\nparent commands are ignored. By enabling `Command.TraverseChildren`, Cobra will\nparse local flags on each command before executing the target command.\n\n```go\ncommand := cobra.Command{\n  Use: \"print [OPTIONS] [COMMANDS]\",\n  TraverseChildren: true,\n}\n```\n\n### Bind Flags with Config\n\nYou can also bind your flags with [viper](https://github.com/spf13/viper):\n```go\nvar author string\n\nfunc init() {\n  rootCmd.PersistentFlags().StringVar(&author, \"author\", \"YOUR NAME\", \"Author name for copyright attribution\")\n  viper.BindPFlag(\"author\", rootCmd.PersistentFlags().Lookup(\"author\"))\n}\n```\n\nIn this example, the persistent flag `author` is bound with `viper`.\n**Note**: the variable `author` will not be set to the value from config,\nwhen the `--author` flag is provided by user.\n\nMore in [viper documentation](https://github.com/spf13/viper#working-with-flags).\n\n### Required flags\n\nFlags are optional by default. If instead you wish your command to report an error\nwhen a flag has not been set, mark it as required:\n```go\nrootCmd.Flags().StringVarP(&Region, \"region\", \"r\", \"\", \"AWS region (required)\")\nrootCmd.MarkFlagRequired(\"region\")\n```\n\nOr, for persistent flags:\n```go\nrootCmd.PersistentFlags().StringVarP(&Region, \"region\", \"r\", \"\", \"AWS region (required)\")\nrootCmd.MarkPersistentFlagRequired(\"region\")\n```\n\n### Flag Groups\n\nIf you have different flags that must be provided together (e.g. if they provide the `--username` flag they MUST provide the `--password` flag as well) then\nCobra can enforce that requirement:\n```go\nrootCmd.Flags().StringVarP(&u, \"username\", \"u\", \"\", \"Username (required if password is set)\")\nrootCmd.Flags().StringVarP(&pw, \"password\", \"p\", \"\", \"Password (required if username is set)\")\nrootCmd.MarkFlagsRequiredTogether(\"username\", \"password\")\n```\n\nYou can also prevent different flags from being provided together if they represent mutually\nexclusive options such as specifying an output format as either `--json` or `--yaml` but never both:\n```go\nrootCmd.Flags().BoolVar(&ofJson, \"json\", false, \"Output in JSON\")\nrootCmd.Flags().BoolVar(&ofYaml, \"yaml\", false, \"Output in YAML\")\nrootCmd.MarkFlagsMutuallyExclusive(\"json\", \"yaml\")\n```\n\nIn both of these cases:\n  - both local and persistent flags can be used\n    - **NOTE:** the group is only enforced on commands where every flag is defined\n  - a flag may appear in multiple groups\n  - a group may contain any number of flags\n\n## Positional and Custom Arguments\n\nValidation of positional arguments can be specified using the `Args` field of `Command`.\nThe following validators are built in:\n\n- Number of arguments:\n  - `NoArgs` - report an error if there are any positional args.\n  - `ArbitraryArgs` - accept any number of args.\n  - `MinimumNArgs(int)` - report an error if less than N positional args are provided.\n  - `MaximumNArgs(int)` - report an error if more than N positional args are provided.\n  - `ExactArgs(int)` - report an error if there are not exactly N positional args.\n  - `RangeArgs(min, max)` - report an error if the number of args is not between `min` and `max`.\n- Content of the arguments:\n  - `OnlyValidArgs` - report an error if there are any positional args not specified in the `ValidArgs` field of `Command`, which can optionally be set to a list of valid values for positional args.\n\nIf `Args` is undefined or `nil`, it defaults to `ArbitraryArgs`.\n\nMoreover, `MatchAll(pargs ...PositionalArgs)` enables combining existing checks with arbitrary other checks.\nFor instance, if you want to report an error if there are not exactly N positional args OR if there are any positional\nargs that are not in the `ValidArgs` field of `Command`, you can call `MatchAll` on `ExactArgs` and `OnlyValidArgs`, as\nshown below:\n\n```go\nvar cmd = &cobra.Command{\n  Short: \"hello\",\n  Args: cobra.MatchAll(cobra.ExactArgs(2), cobra.OnlyValidArgs),\n  Run: func(cmd *cobra.Command, args []string) {\n    fmt.Println(\"Hello, World!\")\n  },\n}\n```\n\nIt is possible to set any custom validator that satisfies `func(cmd *cobra.Command, args []string) error`.\nFor example:\n\n```go\nvar cmd = &cobra.Command{\n  Short: \"hello\",\n  Args: func(cmd *cobra.Command, args []string) error {\n    // Optionally run one of the validators provided by cobra\n    if err := cobra.MinimumNArgs(1)(cmd, args); err != nil {\n        return err\n    }\n    // Run the custom validation logic\n    if myapp.IsValidColor(args[0]) {\n      return nil\n    }\n    return fmt.Errorf(\"invalid color specified: %s\", args[0])\n  },\n  Run: func(cmd *cobra.Command, args []string) {\n    fmt.Println(\"Hello, World!\")\n  },\n}\n```\n\n## Example\n\nIn the example below, we have defined three commands. Two are at the top level\nand one (cmdTimes) is a child of one of the top commands. In this case the root\nis not executable, meaning that a subcommand is required. This is accomplished\nby not providing a 'Run' for the 'rootCmd'.\n\nWe have only defined one flag for a single command.\n\nMore documentation about flags is available at https://github.com/spf13/pflag\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"strings\"\n\n  \"github.com/spf13/cobra\"\n)\n\nfunc main() {\n  var echoTimes int\n\n  var cmdPrint = &cobra.Command{\n    Use:   \"print [string to print]\",\n    Short: \"Print anything to the screen\",\n    Long: `print is for printing anything back to the screen.\nFor many years people have printed back to the screen.`,\n    Args: cobra.MinimumNArgs(1),\n    Run: func(cmd *cobra.Command, args []string) {\n      fmt.Println(\"Print: \" + strings.Join(args, \" \"))\n    },\n  }\n\n  var cmdEcho = &cobra.Command{\n    Use:   \"echo [string to echo]\",\n    Short: \"Echo anything to the screen\",\n    Long: `echo is for echoing anything back.\nEcho works a lot like print, except it has a child command.`,\n    Args: cobra.MinimumNArgs(1),\n    Run: func(cmd *cobra.Command, args []string) {\n      fmt.Println(\"Echo: \" + strings.Join(args, \" \"))\n    },\n  }\n\n  var cmdTimes = &cobra.Command{\n    Use:   \"times [string to echo]\",\n    Short: \"Echo anything to the screen more times\",\n    Long: `echo things multiple times back to the user by providing\na count and a string.`,\n    Args: cobra.MinimumNArgs(1),\n    Run: func(cmd *cobra.Command, args []string) {\n      for i := 0; i < echoTimes; i++ {\n        fmt.Println(\"Echo: \" + strings.Join(args, \" \"))\n      }\n    },\n  }\n\n  cmdTimes.Flags().IntVarP(&echoTimes, \"times\", \"t\", 1, \"times to echo the input\")\n\n  var rootCmd = &cobra.Command{Use: \"app\"}\n  rootCmd.AddCommand(cmdPrint, cmdEcho)\n  cmdEcho.AddCommand(cmdTimes)\n  rootCmd.Execute()\n}\n```\n\nFor a more complete example of a larger application, please checkout [Hugo](https://gohugo.io/).\n\n## Help Command\n\nCobra automatically adds a help command to your application when you have subcommands.\nThis will be called when a user runs 'app help'. Additionally, help will also\nsupport all other commands as input. Say, for instance, you have a command called\n'create' without any additional configuration; Cobra will work when 'app help\ncreate' is called.  Every command will automatically have the '--help' flag added.\n\n### Example\n\nThe following output is automatically generated by Cobra. Nothing beyond the\ncommand and flag definitions are needed.\n\n    $ cobra-cli help\n\n    Cobra is a CLI library for Go that empowers applications.\n    This application is a tool to generate the needed files\n    to quickly create a Cobra application.\n\n    Usage:\n      cobra-cli [command]\n\n    Available Commands:\n      add         Add a command to a Cobra Application\n      completion  Generate the autocompletion script for the specified shell\n      help        Help about any command\n      init        Initialize a Cobra Application\n\n    Flags:\n      -a, --author string    author name for copyright attribution (default \"YOUR NAME\")\n          --config string    config file (default is $HOME/.cobra.yaml)\n      -h, --help             help for cobra-cli\n      -l, --license string   name of license for the project\n          --viper            use Viper for configuration\n\n    Use \"cobra-cli [command] --help\" for more information about a command.\n\n\nHelp is just a command like any other. There is no special logic or behavior\naround it. In fact, you can provide your own if you want.\n\n### Grouping commands in help\n\nCobra supports grouping of available commands in the help output.  To group commands, each group must be explicitly\ndefined using `AddGroup()` on the parent command.  Then a subcommand can be added to a group using the `GroupID` element\nof that subcommand. The groups will appear in the help output in the same order as they are defined using different\ncalls to `AddGroup()`.  If you use the generated `help` or `completion` commands, you can set their group ids using\n`SetHelpCommandGroupId()` and `SetCompletionCommandGroupId()` on the root command, respectively.\n\n### Defining your own help\n\nYou can provide your own Help command or your own template for the default command to use\nwith the following functions:\n\n```go\ncmd.SetHelpCommand(cmd *Command)\ncmd.SetHelpFunc(f func(*Command, []string))\ncmd.SetHelpTemplate(s string)\n```\n\nThe latter two will also apply to any children commands.\n\n## Usage Message\n\nWhen the user provides an invalid flag or invalid command, Cobra responds by\nshowing the user the 'usage'.\n\n### Example\nYou may recognize this from the help above. That's because the default help\nembeds the usage as part of its output.\n\n    $ cobra-cli --invalid\n    Error: unknown flag: --invalid\n    Usage:\n      cobra-cli [command]\n\n    Available Commands:\n      add         Add a command to a Cobra Application\n      completion  Generate the autocompletion script for the specified shell\n      help        Help about any command\n      init        Initialize a Cobra Application\n\n    Flags:\n      -a, --author string    author name for copyright attribution (default \"YOUR NAME\")\n          --config string    config file (default is $HOME/.cobra.yaml)\n      -h, --help             help for cobra-cli\n      -l, --license string   name of license for the project\n          --viper            use Viper for configuration\n\n    Use \"cobra [command] --help\" for more information about a command.\n\n### Defining your own usage\nYou can provide your own usage function or template for Cobra to use.\nLike help, the function and template are overridable through public methods:\n\n```go\ncmd.SetUsageFunc(f func(*Command) error)\ncmd.SetUsageTemplate(s string)\n```\n\n## Version Flag\n\nCobra adds a top-level '--version' flag if the Version field is set on the root command.\nRunning an application with the '--version' flag will print the version to stdout using\nthe version template. The template can be customized using the\n`cmd.SetVersionTemplate(s string)` function.\n\n## PreRun and PostRun Hooks\n\nIt is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`.  The `Persistent*Run` functions will be inherited by children if they do not declare their own.  These functions are run in the following order:\n\n- `PersistentPreRun`\n- `PreRun`\n- `Run`\n- `PostRun`\n- `PersistentPostRun`\n\nAn example of two commands which use all of these features is below.  When the subcommand is executed, it will run the root command's `PersistentPreRun` but not the root command's `PersistentPostRun`:\n\n```go\npackage main\n\nimport (\n  \"fmt\"\n\n  \"github.com/spf13/cobra\"\n)\n\nfunc main() {\n\n  var rootCmd = &cobra.Command{\n    Use:   \"root [sub]\",\n    Short: \"My root command\",\n    PersistentPreRun: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside rootCmd PersistentPreRun with args: %v\\n\", args)\n    },\n    PreRun: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside rootCmd PreRun with args: %v\\n\", args)\n    },\n    Run: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside rootCmd Run with args: %v\\n\", args)\n    },\n    PostRun: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside rootCmd PostRun with args: %v\\n\", args)\n    },\n    PersistentPostRun: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside rootCmd PersistentPostRun with args: %v\\n\", args)\n    },\n  }\n\n  var subCmd = &cobra.Command{\n    Use:   \"sub [no options!]\",\n    Short: \"My subcommand\",\n    PreRun: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside subCmd PreRun with args: %v\\n\", args)\n    },\n    Run: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside subCmd Run with args: %v\\n\", args)\n    },\n    PostRun: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside subCmd PostRun with args: %v\\n\", args)\n    },\n    PersistentPostRun: func(cmd *cobra.Command, args []string) {\n      fmt.Printf(\"Inside subCmd PersistentPostRun with args: %v\\n\", args)\n    },\n  }\n\n  rootCmd.AddCommand(subCmd)\n\n  rootCmd.SetArgs([]string{\"\"})\n  rootCmd.Execute()\n  fmt.Println()\n  rootCmd.SetArgs([]string{\"sub\", \"arg1\", \"arg2\"})\n  rootCmd.Execute()\n}\n```\n\nOutput:\n```\nInside rootCmd PersistentPreRun with args: []\nInside rootCmd PreRun with args: []\nInside rootCmd Run with args: []\nInside rootCmd PostRun with args: []\nInside rootCmd PersistentPostRun with args: []\n\nInside rootCmd PersistentPreRun with args: [arg1 arg2]\nInside subCmd PreRun with args: [arg1 arg2]\nInside subCmd Run with args: [arg1 arg2]\nInside subCmd PostRun with args: [arg1 arg2]\nInside subCmd PersistentPostRun with args: [arg1 arg2]\n```\n\n## Suggestions when \"unknown command\" happens\n\nCobra will print automatic suggestions when \"unknown command\" errors happen. This allows Cobra to behave similarly to the `git` command when a typo happens. For example:\n\n```\n$ hugo srever\nError: unknown command \"srever\" for \"hugo\"\n\nDid you mean this?\n        server\n\nRun 'hugo --help' for usage.\n```\n\nSuggestions are automatically generated based on existing subcommands and use an implementation of [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion.\n\nIf you need to disable suggestions or tweak the string distance in your command, use:\n\n```go\ncommand.DisableSuggestions = true\n```\n\nor\n\n```go\ncommand.SuggestionsMinimumDistance = 1\n```\n\nYou can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but make sense in your set of commands but for which\nyou don't want aliases. Example:\n\n```\n$ kubectl remove\nError: unknown command \"remove\" for \"kubectl\"\n\nDid you mean this?\n        delete\n\nRun 'kubectl help' for usage.\n```\n\n## Generating documentation for your command\n\nCobra can generate documentation based on subcommands, flags, etc. Read more about it in the [docs generation documentation](doc/README.md).\n\n## Generating shell completions\n\nCobra can generate a shell-completion file for the following shells: bash, zsh, fish, PowerShell. If you add more information to your commands, these completions can be amazingly powerful and flexible.  Read more about it in [Shell Completions](shell_completions.md).\n\n## Providing Active Help\n\nCobra makes use of the shell-completion system to define a framework allowing you to provide Active Help to your users.  Active Help are messages (hints, warnings, etc) printed as the program is being used.  Read more about it in [Active Help](active_help.md).\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/zsh_completions.go",
    "content": "// Copyright 2013-2023 The Cobra Authors\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//      http://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\npackage cobra\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\n// GenZshCompletionFile generates zsh completion file including descriptions.\nfunc (c *Command) GenZshCompletionFile(filename string) error {\n\treturn c.genZshCompletionFile(filename, true)\n}\n\n// GenZshCompletion generates zsh completion file including descriptions\n// and writes it to the passed writer.\nfunc (c *Command) GenZshCompletion(w io.Writer) error {\n\treturn c.genZshCompletion(w, true)\n}\n\n// GenZshCompletionFileNoDesc generates zsh completion file without descriptions.\nfunc (c *Command) GenZshCompletionFileNoDesc(filename string) error {\n\treturn c.genZshCompletionFile(filename, false)\n}\n\n// GenZshCompletionNoDesc generates zsh completion file without descriptions\n// and writes it to the passed writer.\nfunc (c *Command) GenZshCompletionNoDesc(w io.Writer) error {\n\treturn c.genZshCompletion(w, false)\n}\n\n// MarkZshCompPositionalArgumentFile only worked for zsh and its behavior was\n// not consistent with Bash completion. It has therefore been disabled.\n// Instead, when no other completion is specified, file completion is done by\n// default for every argument. One can disable file completion on a per-argument\n// basis by using ValidArgsFunction and ShellCompDirectiveNoFileComp.\n// To achieve file extension filtering, one can use ValidArgsFunction and\n// ShellCompDirectiveFilterFileExt.\n//\n// Deprecated\nfunc (c *Command) MarkZshCompPositionalArgumentFile(argPosition int, patterns ...string) error {\n\treturn nil\n}\n\n// MarkZshCompPositionalArgumentWords only worked for zsh. It has therefore\n// been disabled.\n// To achieve the same behavior across all shells, one can use\n// ValidArgs (for the first argument only) or ValidArgsFunction for\n// any argument (can include the first one also).\n//\n// Deprecated\nfunc (c *Command) MarkZshCompPositionalArgumentWords(argPosition int, words ...string) error {\n\treturn nil\n}\n\nfunc (c *Command) genZshCompletionFile(filename string, includeDesc bool) error {\n\toutFile, err := os.Create(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer outFile.Close()\n\n\treturn c.genZshCompletion(outFile, includeDesc)\n}\n\nfunc (c *Command) genZshCompletion(w io.Writer, includeDesc bool) error {\n\tbuf := new(bytes.Buffer)\n\tgenZshComp(buf, c.Name(), includeDesc)\n\t_, err := buf.WriteTo(w)\n\treturn err\n}\n\nfunc genZshComp(buf io.StringWriter, name string, includeDesc bool) {\n\tcompCmd := ShellCompRequestCmd\n\tif !includeDesc {\n\t\tcompCmd = ShellCompNoDescRequestCmd\n\t}\n\tWriteStringAndCheck(buf, fmt.Sprintf(`#compdef %[1]s\ncompdef _%[1]s %[1]s\n\n# zsh completion for %-36[1]s -*- shell-script -*-\n\n__%[1]s_debug()\n{\n    local file=\"$BASH_COMP_DEBUG_FILE\"\n    if [[ -n ${file} ]]; then\n        echo \"$*\" >> \"${file}\"\n    fi\n}\n\n_%[1]s()\n{\n    local shellCompDirectiveError=%[3]d\n    local shellCompDirectiveNoSpace=%[4]d\n    local shellCompDirectiveNoFileComp=%[5]d\n    local shellCompDirectiveFilterFileExt=%[6]d\n    local shellCompDirectiveFilterDirs=%[7]d\n    local shellCompDirectiveKeepOrder=%[8]d\n\n    local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder\n    local -a completions\n\n    __%[1]s_debug \"\\n========= starting completion logic ==========\"\n    __%[1]s_debug \"CURRENT: ${CURRENT}, words[*]: ${words[*]}\"\n\n    # The user could have moved the cursor backwards on the command-line.\n    # We need to trigger completion from the $CURRENT location, so we need\n    # to truncate the command-line ($words) up to the $CURRENT location.\n    # (We cannot use $CURSOR as its value does not work when a command is an alias.)\n    words=(\"${=words[1,CURRENT]}\")\n    __%[1]s_debug \"Truncated words[*]: ${words[*]},\"\n\n    lastParam=${words[-1]}\n    lastChar=${lastParam[-1]}\n    __%[1]s_debug \"lastParam: ${lastParam}, lastChar: ${lastChar}\"\n\n    # For zsh, when completing a flag with an = (e.g., %[1]s -n=<TAB>)\n    # completions must be prefixed with the flag\n    setopt local_options BASH_REMATCH\n    if [[ \"${lastParam}\" =~ '-.*=' ]]; then\n        # We are dealing with a flag with an =\n        flagPrefix=\"-P ${BASH_REMATCH}\"\n    fi\n\n    # Prepare the command to obtain completions\n    requestComp=\"${words[1]} %[2]s ${words[2,-1]}\"\n    if [ \"${lastChar}\" = \"\" ]; then\n        # If the last parameter is complete (there is a space following it)\n        # We add an extra empty parameter so we can indicate this to the go completion code.\n        __%[1]s_debug \"Adding extra empty parameter\"\n        requestComp=\"${requestComp} \\\"\\\"\"\n    fi\n\n    __%[1]s_debug \"About to call: eval ${requestComp}\"\n\n    # Use eval to handle any environment variables and such\n    out=$(eval ${requestComp} 2>/dev/null)\n    __%[1]s_debug \"completion output: ${out}\"\n\n    # Extract the directive integer following a : from the last line\n    local lastLine\n    while IFS='\\n' read -r line; do\n        lastLine=${line}\n    done < <(printf \"%%s\\n\" \"${out[@]}\")\n    __%[1]s_debug \"last line: ${lastLine}\"\n\n    if [ \"${lastLine[1]}\" = : ]; then\n        directive=${lastLine[2,-1]}\n        # Remove the directive including the : and the newline\n        local suffix\n        (( suffix=${#lastLine}+2))\n        out=${out[1,-$suffix]}\n    else\n        # There is no directive specified.  Leave $out as is.\n        __%[1]s_debug \"No directive found.  Setting do default\"\n        directive=0\n    fi\n\n    __%[1]s_debug \"directive: ${directive}\"\n    __%[1]s_debug \"completions: ${out}\"\n    __%[1]s_debug \"flagPrefix: ${flagPrefix}\"\n\n    if [ $((directive & shellCompDirectiveError)) -ne 0 ]; then\n        __%[1]s_debug \"Completion received error. Ignoring completions.\"\n        return\n    fi\n\n    local activeHelpMarker=\"%[9]s\"\n    local endIndex=${#activeHelpMarker}\n    local startIndex=$((${#activeHelpMarker}+1))\n    local hasActiveHelp=0\n    while IFS='\\n' read -r comp; do\n        # Check if this is an activeHelp statement (i.e., prefixed with $activeHelpMarker)\n        if [ \"${comp[1,$endIndex]}\" = \"$activeHelpMarker\" ];then\n            __%[1]s_debug \"ActiveHelp found: $comp\"\n            comp=\"${comp[$startIndex,-1]}\"\n            if [ -n \"$comp\" ]; then\n                compadd -x \"${comp}\"\n                __%[1]s_debug \"ActiveHelp will need delimiter\"\n                hasActiveHelp=1\n            fi\n\n            continue\n        fi\n\n        if [ -n \"$comp\" ]; then\n            # If requested, completions are returned with a description.\n            # The description is preceded by a TAB character.\n            # For zsh's _describe, we need to use a : instead of a TAB.\n            # We first need to escape any : as part of the completion itself.\n            comp=${comp//:/\\\\:}\n\n            local tab=\"$(printf '\\t')\"\n            comp=${comp//$tab/:}\n\n            __%[1]s_debug \"Adding completion: ${comp}\"\n            completions+=${comp}\n            lastComp=$comp\n        fi\n    done < <(printf \"%%s\\n\" \"${out[@]}\")\n\n    # Add a delimiter after the activeHelp statements, but only if:\n    # - there are completions following the activeHelp statements, or\n    # - file completion will be performed (so there will be choices after the activeHelp)\n    if [ $hasActiveHelp -eq 1 ]; then\n        if [ ${#completions} -ne 0 ] || [ $((directive & shellCompDirectiveNoFileComp)) -eq 0 ]; then\n            __%[1]s_debug \"Adding activeHelp delimiter\"\n            compadd -x \"--\"\n            hasActiveHelp=0\n        fi\n    fi\n\n    if [ $((directive & shellCompDirectiveNoSpace)) -ne 0 ]; then\n        __%[1]s_debug \"Activating nospace.\"\n        noSpace=\"-S ''\"\n    fi\n\n    if [ $((directive & shellCompDirectiveKeepOrder)) -ne 0 ]; then\n        __%[1]s_debug \"Activating keep order.\"\n        keepOrder=\"-V\"\n    fi\n\n    if [ $((directive & shellCompDirectiveFilterFileExt)) -ne 0 ]; then\n        # File extension filtering\n        local filteringCmd\n        filteringCmd='_files'\n        for filter in ${completions[@]}; do\n            if [ ${filter[1]} != '*' ]; then\n                # zsh requires a glob pattern to do file filtering\n                filter=\"\\*.$filter\"\n            fi\n            filteringCmd+=\" -g $filter\"\n        done\n        filteringCmd+=\" ${flagPrefix}\"\n\n        __%[1]s_debug \"File filtering command: $filteringCmd\"\n        _arguments '*:filename:'\"$filteringCmd\"\n    elif [ $((directive & shellCompDirectiveFilterDirs)) -ne 0 ]; then\n        # File completion for directories only\n        local subdir\n        subdir=\"${completions[1]}\"\n        if [ -n \"$subdir\" ]; then\n            __%[1]s_debug \"Listing directories in $subdir\"\n            pushd \"${subdir}\" >/dev/null 2>&1\n        else\n            __%[1]s_debug \"Listing directories in .\"\n        fi\n\n        local result\n        _arguments '*:dirname:_files -/'\" ${flagPrefix}\"\n        result=$?\n        if [ -n \"$subdir\" ]; then\n            popd >/dev/null 2>&1\n        fi\n        return $result\n    else\n        __%[1]s_debug \"Calling _describe\"\n        if eval _describe $keepOrder \"completions\" completions $flagPrefix $noSpace; then\n            __%[1]s_debug \"_describe found some completions\"\n\n            # Return the success of having called _describe\n            return 0\n        else\n            __%[1]s_debug \"_describe did not find completions.\"\n            __%[1]s_debug \"Checking if we should do file completion.\"\n            if [ $((directive & shellCompDirectiveNoFileComp)) -ne 0 ]; then\n                __%[1]s_debug \"deactivating file completion\"\n\n                # We must return an error code here to let zsh know that there were no\n                # completions found by _describe; this is what will trigger other\n                # matching algorithms to attempt to find completions.\n                # For example zsh can match letters in the middle of words.\n                return 1\n            else\n                # Perform file completion\n                __%[1]s_debug \"Activating file completion\"\n\n                # We must return the result of this command, so it must be the\n                # last command, or else we must store its result to return it.\n                _arguments '*:filename:_files'\" ${flagPrefix}\"\n            fi\n        fi\n    fi\n}\n\n# don't run the completion function when being source-ed or eval-ed\nif [ \"$funcstack[1]\" = \"_%[1]s\" ]; then\n    _%[1]s\nfi\n`, name, compCmd,\n\t\tShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,\n\t\tShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder,\n\t\tactiveHelpMarker))\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/cobra/zsh_completions.md",
    "content": "## Generating Zsh Completion For Your cobra.Command\n\nPlease refer to [Shell Completions](shell_completions.md) for details.\n\n## Zsh completions standardization\n\nCobra 1.1 standardized its zsh completion support to align it with its other shell completions.  Although the API was kept backwards-compatible, some small changes in behavior were introduced.\n\n### Deprecation summary\n\nSee further below for more details on these deprecations.\n\n* `cmd.MarkZshCompPositionalArgumentFile(pos, []string{})` is no longer needed.  It is therefore **deprecated** and silently ignored.\n* `cmd.MarkZshCompPositionalArgumentFile(pos, glob[])` is **deprecated** and silently ignored.\n  * Instead use `ValidArgsFunction` with `ShellCompDirectiveFilterFileExt`.\n* `cmd.MarkZshCompPositionalArgumentWords()` is **deprecated** and silently ignored.\n  * Instead use `ValidArgsFunction`.\n\n### Behavioral changes\n\n**Noun completion**\n|Old behavior|New behavior|\n|---|---|\n|No file completion by default (opposite of bash)|File completion by default; use `ValidArgsFunction` with `ShellCompDirectiveNoFileComp` to turn off file completion on a per-argument basis|\n|Completion of flag names without the `-` prefix having been typed|Flag names are only completed if the user has typed the first `-`|\n`cmd.MarkZshCompPositionalArgumentFile(pos, []string{})` used to turn on file completion on a per-argument position basis|File completion for all arguments by default; `cmd.MarkZshCompPositionalArgumentFile()` is **deprecated** and silently ignored|\n|`cmd.MarkZshCompPositionalArgumentFile(pos, glob[])` used to turn on file completion **with glob filtering** on a per-argument position basis (zsh-specific)|`cmd.MarkZshCompPositionalArgumentFile()` is **deprecated** and silently ignored; use `ValidArgsFunction` with `ShellCompDirectiveFilterFileExt` for file **extension** filtering (not full glob filtering)|\n|`cmd.MarkZshCompPositionalArgumentWords(pos, words[])` used to provide completion choices on a per-argument position basis (zsh-specific)|`cmd.MarkZshCompPositionalArgumentWords()` is **deprecated** and silently ignored; use `ValidArgsFunction` to achieve the same behavior|\n\n**Flag-value completion**\n\n|Old behavior|New behavior|\n|---|---|\n|No file completion by default (opposite of bash)|File completion by default; use `RegisterFlagCompletionFunc()` with `ShellCompDirectiveNoFileComp` to turn off file completion|\n|`cmd.MarkFlagFilename(flag, []string{})` and similar used to turn on file completion|File completion by default; `cmd.MarkFlagFilename(flag, []string{})` no longer needed in this context and silently ignored|\n|`cmd.MarkFlagFilename(flag, glob[])`  used to turn on file completion **with glob filtering** (syntax of `[]string{\"*.yaml\", \"*.yml\"}` incompatible with bash)|Will continue to work, however, support for bash syntax is added and should be used instead so as to work for all shells (`[]string{\"yaml\", \"yml\"}`)|\n|`cmd.MarkFlagDirname(flag)` only completes directories (zsh-specific)|Has been added for all shells|\n|Completion of a flag name does not repeat, unless flag is of type `*Array` or `*Slice` (not supported by bash)|Retained for `zsh` and added to `fish`|\n|Completion of a flag name does not provide the `=` form (unlike bash)|Retained for `zsh` and added to `fish`|\n\n**Improvements**\n\n* Custom completion support (`ValidArgsFunction` and `RegisterFlagCompletionFunc()`)\n* File completion by default if no other completions found\n* Handling of required flags\n* File extension filtering no longer mutually exclusive with bash usage\n* Completion of directory names *within* another directory\n* Support for `=` form of flags\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/.gitignore",
    "content": ".idea/*\n\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/.travis.yml",
    "content": "sudo: false\n\nlanguage: go\n\ngo:\n  - 1.9.x\n  - 1.10.x\n  - 1.11.x\n  - tip\n\nmatrix:\n  allow_failures:\n    - go: tip\n\ninstall:\n  - go get golang.org/x/lint/golint\n  - export PATH=$GOPATH/bin:$PATH\n  - go install ./...\n\nscript:\n  - verify/all.sh -v\n  - go test ./...\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/LICENSE",
    "content": "Copyright (c) 2012 Alex Ogier. All rights reserved.\nCopyright (c) 2012 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   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * 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": "vendor/github.com/spf13/pflag/README.md",
    "content": "[![Build Status](https://travis-ci.org/spf13/pflag.svg?branch=master)](https://travis-ci.org/spf13/pflag)\n[![Go Report Card](https://goreportcard.com/badge/github.com/spf13/pflag)](https://goreportcard.com/report/github.com/spf13/pflag)\n[![GoDoc](https://godoc.org/github.com/spf13/pflag?status.svg)](https://godoc.org/github.com/spf13/pflag)\n\n## Description\n\npflag is a drop-in replacement for Go's flag package, implementing\nPOSIX/GNU-style --flags.\n\npflag is compatible with the [GNU extensions to the POSIX recommendations\nfor command-line options][1]. For a more precise description, see the\n\"Command-line flag syntax\" section below.\n\n[1]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html\n\npflag is available under the same style of BSD license as the Go language,\nwhich can be found in the LICENSE file.\n\n## Installation\n\npflag is available using the standard `go get` command.\n\nInstall by running:\n\n    go get github.com/spf13/pflag\n\nRun tests by running:\n\n    go test github.com/spf13/pflag\n\n## Usage\n\npflag is a drop-in replacement of Go's native flag package. If you import\npflag under the name \"flag\" then all code should continue to function\nwith no changes.\n\n``` go\nimport flag \"github.com/spf13/pflag\"\n```\n\nThere is one exception to this: if you directly instantiate the Flag struct\nthere is one more field \"Shorthand\" that you will need to set.\nMost code never instantiates this struct directly, and instead uses\nfunctions such as String(), BoolVar(), and Var(), and is therefore\nunaffected.\n\nDefine flags using flag.String(), Bool(), Int(), etc.\n\nThis declares an integer flag, -flagname, stored in the pointer ip, with type *int.\n\n``` go\nvar ip *int = flag.Int(\"flagname\", 1234, \"help message for flagname\")\n```\n\nIf you like, you can bind the flag to a variable using the Var() functions.\n\n``` go\nvar flagvar int\nfunc init() {\n    flag.IntVar(&flagvar, \"flagname\", 1234, \"help message for flagname\")\n}\n```\n\nOr you can create custom flags that satisfy the Value interface (with\npointer receivers) and couple them to flag parsing by\n\n``` go\nflag.Var(&flagVal, \"name\", \"help message for flagname\")\n```\n\nFor such flags, the default value is just the initial value of the variable.\n\nAfter all flags are defined, call\n\n``` go\nflag.Parse()\n```\n\nto parse the command line into the defined flags.\n\nFlags may then be used directly. If you're using the flags themselves,\nthey are all pointers; if you bind to variables, they're values.\n\n``` go\nfmt.Println(\"ip has value \", *ip)\nfmt.Println(\"flagvar has value \", flagvar)\n```\n\nThere are helper functions available to get the value stored in a Flag if you have a FlagSet but find\nit difficult to keep up with all of the pointers in your code.\nIf you have a pflag.FlagSet with a flag called 'flagname' of type int you\ncan use GetInt() to get the int value. But notice that 'flagname' must exist\nand it must be an int. GetString(\"flagname\") will fail.\n\n``` go\ni, err := flagset.GetInt(\"flagname\")\n```\n\nAfter parsing, the arguments after the flag are available as the\nslice flag.Args() or individually as flag.Arg(i).\nThe arguments are indexed from 0 through flag.NArg()-1.\n\nThe pflag package also defines some new functions that are not in flag,\nthat give one-letter shorthands for flags. You can use these by appending\n'P' to the name of any function that defines a flag.\n\n``` go\nvar ip = flag.IntP(\"flagname\", \"f\", 1234, \"help message\")\nvar flagvar bool\nfunc init() {\n\tflag.BoolVarP(&flagvar, \"boolname\", \"b\", true, \"help message\")\n}\nflag.VarP(&flagVal, \"varname\", \"v\", \"help message\")\n```\n\nShorthand letters can be used with single dashes on the command line.\nBoolean shorthand flags can be combined with other shorthand flags.\n\nThe default set of command-line flags is controlled by\ntop-level functions.  The FlagSet type allows one to define\nindependent sets of flags, such as to implement subcommands\nin a command-line interface. The methods of FlagSet are\nanalogous to the top-level functions for the command-line\nflag set.\n\n## Setting no option default values for flags\n\nAfter you create a flag it is possible to set the pflag.NoOptDefVal for\nthe given flag. Doing this changes the meaning of the flag slightly. If\na flag has a NoOptDefVal and the flag is set on the command line without\nan option the flag will be set to the NoOptDefVal. For example given:\n\n``` go\nvar ip = flag.IntP(\"flagname\", \"f\", 1234, \"help message\")\nflag.Lookup(\"flagname\").NoOptDefVal = \"4321\"\n```\n\nWould result in something like\n\n| Parsed Arguments | Resulting Value |\n| -------------    | -------------   |\n| --flagname=1357  | ip=1357         |\n| --flagname       | ip=4321         |\n| [nothing]        | ip=1234         |\n\n## Command line flag syntax\n\n```\n--flag    // boolean flags, or flags with no option default values\n--flag x  // only on flags without a default value\n--flag=x\n```\n\nUnlike the flag package, a single dash before an option means something\ndifferent than a double dash. Single dashes signify a series of shorthand\nletters for flags. All but the last shorthand letter must be boolean flags\nor a flag with a default value\n\n```\n// boolean or flags where the 'no option default value' is set\n-f\n-f=true\n-abc\nbut\n-b true is INVALID\n\n// non-boolean and flags without a 'no option default value'\n-n 1234\n-n=1234\n-n1234\n\n// mixed\n-abcs \"hello\"\n-absd=\"hello\"\n-abcs1234\n```\n\nFlag parsing stops after the terminator \"--\". Unlike the flag package,\nflags can be interspersed with arguments anywhere on the command line\nbefore this terminator.\n\nInteger flags accept 1234, 0664, 0x1234 and may be negative.\nBoolean flags (in their long form) accept 1, 0, t, f, true, false,\nTRUE, FALSE, True, False.\nDuration flags accept any input valid for time.ParseDuration.\n\n## Mutating or \"Normalizing\" Flag names\n\nIt is possible to set a custom flag name 'normalization function.' It allows flag names to be mutated both when created in the code and when used on the command line to some 'normalized' form. The 'normalized' form is used for comparison. Two examples of using the custom normalization func follow.\n\n**Example #1**: You want -, _, and . in flags to compare the same. aka --my-flag == --my_flag == --my.flag\n\n``` go\nfunc wordSepNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {\n\tfrom := []string{\"-\", \"_\"}\n\tto := \".\"\n\tfor _, sep := range from {\n\t\tname = strings.Replace(name, sep, to, -1)\n\t}\n\treturn pflag.NormalizedName(name)\n}\n\nmyFlagSet.SetNormalizeFunc(wordSepNormalizeFunc)\n```\n\n**Example #2**: You want to alias two flags. aka --old-flag-name == --new-flag-name\n\n``` go\nfunc aliasNormalizeFunc(f *pflag.FlagSet, name string) pflag.NormalizedName {\n\tswitch name {\n\tcase \"old-flag-name\":\n\t\tname = \"new-flag-name\"\n\t\tbreak\n\t}\n\treturn pflag.NormalizedName(name)\n}\n\nmyFlagSet.SetNormalizeFunc(aliasNormalizeFunc)\n```\n\n## Deprecating a flag or its shorthand\nIt is possible to deprecate a flag, or just its shorthand. Deprecating a flag/shorthand hides it from help text and prints a usage message when the deprecated flag/shorthand is used.\n\n**Example #1**: You want to deprecate a flag named \"badflag\" as well as inform the users what flag they should use instead.\n```go\n// deprecate a flag by specifying its name and a usage message\nflags.MarkDeprecated(\"badflag\", \"please use --good-flag instead\")\n```\nThis hides \"badflag\" from help text, and prints `Flag --badflag has been deprecated, please use --good-flag instead` when \"badflag\" is used.\n\n**Example #2**: You want to keep a flag name \"noshorthandflag\" but deprecate its shortname \"n\".\n```go\n// deprecate a flag shorthand by specifying its flag name and a usage message\nflags.MarkShorthandDeprecated(\"noshorthandflag\", \"please use --noshorthandflag only\")\n```\nThis hides the shortname \"n\" from help text, and prints `Flag shorthand -n has been deprecated, please use --noshorthandflag only` when the shorthand \"n\" is used.\n\nNote that usage message is essential here, and it should not be empty.\n\n## Hidden flags\nIt is possible to mark a flag as hidden, meaning it will still function as normal, however will not show up in usage/help text.\n\n**Example**: You have a flag named \"secretFlag\" that you need for internal use only and don't want it showing up in help text, or for its usage text to be available.\n```go\n// hide a flag by specifying its name\nflags.MarkHidden(\"secretFlag\")\n```\n\n## Disable sorting of flags\n`pflag` allows you to disable sorting of flags for help and usage message.\n\n**Example**:\n```go\nflags.BoolP(\"verbose\", \"v\", false, \"verbose output\")\nflags.String(\"coolflag\", \"yeaah\", \"it's really cool flag\")\nflags.Int(\"usefulflag\", 777, \"sometimes it's very useful\")\nflags.SortFlags = false\nflags.PrintDefaults()\n```\n**Output**:\n```\n  -v, --verbose           verbose output\n      --coolflag string   it's really cool flag (default \"yeaah\")\n      --usefulflag int    sometimes it's very useful (default 777)\n```\n\n\n## Supporting Go flags when using pflag\nIn order to support flags defined using Go's `flag` package, they must be added to the `pflag` flagset. This is usually necessary\nto support flags defined by third-party dependencies (e.g. `golang/glog`).\n\n**Example**: You want to add the Go flags to the `CommandLine` flagset\n```go\nimport (\n\tgoflag \"flag\"\n\tflag \"github.com/spf13/pflag\"\n)\n\nvar ip *int = flag.Int(\"flagname\", 1234, \"help message for flagname\")\n\nfunc main() {\n\tflag.CommandLine.AddGoFlagSet(goflag.CommandLine)\n\tflag.Parse()\n}\n```\n\n## More info\n\nYou can see the full reference documentation of the pflag package\n[at godoc.org][3], or through go's standard documentation system by\nrunning `godoc -http=:6060` and browsing to\n[http://localhost:6060/pkg/github.com/spf13/pflag][2] after\ninstallation.\n\n[2]: http://localhost:6060/pkg/github.com/spf13/pflag\n[3]: http://godoc.org/github.com/spf13/pflag\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/bool.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// optional interface to indicate boolean flags that can be\n// supplied without \"=value\" text\ntype boolFlag interface {\n\tValue\n\tIsBoolFlag() bool\n}\n\n// -- bool Value\ntype boolValue bool\n\nfunc newBoolValue(val bool, p *bool) *boolValue {\n\t*p = val\n\treturn (*boolValue)(p)\n}\n\nfunc (b *boolValue) Set(s string) error {\n\tv, err := strconv.ParseBool(s)\n\t*b = boolValue(v)\n\treturn err\n}\n\nfunc (b *boolValue) Type() string {\n\treturn \"bool\"\n}\n\nfunc (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }\n\nfunc (b *boolValue) IsBoolFlag() bool { return true }\n\nfunc boolConv(sval string) (interface{}, error) {\n\treturn strconv.ParseBool(sval)\n}\n\n// GetBool return the bool value of a flag with the given name\nfunc (f *FlagSet) GetBool(name string) (bool, error) {\n\tval, err := f.getFlagType(name, \"bool\", boolConv)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn val.(bool), nil\n}\n\n// BoolVar defines a bool flag with specified name, default value, and usage string.\n// The argument p points to a bool variable in which to store the value of the flag.\nfunc (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {\n\tf.BoolVarP(p, name, \"\", value, usage)\n}\n\n// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BoolVarP(p *bool, name, shorthand string, value bool, usage string) {\n\tflag := f.VarPF(newBoolValue(value, p), name, shorthand, usage)\n\tflag.NoOptDefVal = \"true\"\n}\n\n// BoolVar defines a bool flag with specified name, default value, and usage string.\n// The argument p points to a bool variable in which to store the value of the flag.\nfunc BoolVar(p *bool, name string, value bool, usage string) {\n\tBoolVarP(p, name, \"\", value, usage)\n}\n\n// BoolVarP is like BoolVar, but accepts a shorthand letter that can be used after a single dash.\nfunc BoolVarP(p *bool, name, shorthand string, value bool, usage string) {\n\tflag := CommandLine.VarPF(newBoolValue(value, p), name, shorthand, usage)\n\tflag.NoOptDefVal = \"true\"\n}\n\n// Bool defines a bool flag with specified name, default value, and usage string.\n// The return value is the address of a bool variable that stores the value of the flag.\nfunc (f *FlagSet) Bool(name string, value bool, usage string) *bool {\n\treturn f.BoolP(name, \"\", value, usage)\n}\n\n// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BoolP(name, shorthand string, value bool, usage string) *bool {\n\tp := new(bool)\n\tf.BoolVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Bool defines a bool flag with specified name, default value, and usage string.\n// The return value is the address of a bool variable that stores the value of the flag.\nfunc Bool(name string, value bool, usage string) *bool {\n\treturn BoolP(name, \"\", value, usage)\n}\n\n// BoolP is like Bool, but accepts a shorthand letter that can be used after a single dash.\nfunc BoolP(name, shorthand string, value bool, usage string) *bool {\n\tb := CommandLine.BoolP(name, shorthand, value, usage)\n\treturn b\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/bool_slice.go",
    "content": "package pflag\n\nimport (\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- boolSlice Value\ntype boolSliceValue struct {\n\tvalue   *[]bool\n\tchanged bool\n}\n\nfunc newBoolSliceValue(val []bool, p *[]bool) *boolSliceValue {\n\tbsv := new(boolSliceValue)\n\tbsv.value = p\n\t*bsv.value = val\n\treturn bsv\n}\n\n// Set converts, and assigns, the comma-separated boolean argument string representation as the []bool value of this flag.\n// If Set is called on a flag that already has a []bool assigned, the newly converted values will be appended.\nfunc (s *boolSliceValue) Set(val string) error {\n\n\t// remove all quote characters\n\trmQuote := strings.NewReplacer(`\"`, \"\", `'`, \"\", \"`\", \"\")\n\n\t// read flag arguments with CSV parser\n\tboolStrSlice, err := readAsCSV(rmQuote.Replace(val))\n\tif err != nil && err != io.EOF {\n\t\treturn err\n\t}\n\n\t// parse boolean values into slice\n\tout := make([]bool, 0, len(boolStrSlice))\n\tfor _, boolStr := range boolStrSlice {\n\t\tb, err := strconv.ParseBool(strings.TrimSpace(boolStr))\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tout = append(out, b)\n\t}\n\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\n\ts.changed = true\n\n\treturn nil\n}\n\n// Type returns a string that uniquely represents this flag's type.\nfunc (s *boolSliceValue) Type() string {\n\treturn \"boolSlice\"\n}\n\n// String defines a \"native\" format for this boolean slice flag value.\nfunc (s *boolSliceValue) String() string {\n\n\tboolStrSlice := make([]string, len(*s.value))\n\tfor i, b := range *s.value {\n\t\tboolStrSlice[i] = strconv.FormatBool(b)\n\t}\n\n\tout, _ := writeAsCSV(boolStrSlice)\n\n\treturn \"[\" + out + \"]\"\n}\n\nfunc (s *boolSliceValue) fromString(val string) (bool, error) {\n\treturn strconv.ParseBool(val)\n}\n\nfunc (s *boolSliceValue) toString(val bool) string {\n\treturn strconv.FormatBool(val)\n}\n\nfunc (s *boolSliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *boolSliceValue) Replace(val []string) error {\n\tout := make([]bool, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *boolSliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc boolSliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []bool{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]bool, len(ss))\n\tfor i, t := range ss {\n\t\tvar err error\n\t\tout[i], err = strconv.ParseBool(t)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn out, nil\n}\n\n// GetBoolSlice returns the []bool value of a flag with the given name.\nfunc (f *FlagSet) GetBoolSlice(name string) ([]bool, error) {\n\tval, err := f.getFlagType(name, \"boolSlice\", boolSliceConv)\n\tif err != nil {\n\t\treturn []bool{}, err\n\t}\n\treturn val.([]bool), nil\n}\n\n// BoolSliceVar defines a boolSlice flag with specified name, default value, and usage string.\n// The argument p points to a []bool variable in which to store the value of the flag.\nfunc (f *FlagSet) BoolSliceVar(p *[]bool, name string, value []bool, usage string) {\n\tf.VarP(newBoolSliceValue(value, p), name, \"\", usage)\n}\n\n// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {\n\tf.VarP(newBoolSliceValue(value, p), name, shorthand, usage)\n}\n\n// BoolSliceVar defines a []bool flag with specified name, default value, and usage string.\n// The argument p points to a []bool variable in which to store the value of the flag.\nfunc BoolSliceVar(p *[]bool, name string, value []bool, usage string) {\n\tCommandLine.VarP(newBoolSliceValue(value, p), name, \"\", usage)\n}\n\n// BoolSliceVarP is like BoolSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc BoolSliceVarP(p *[]bool, name, shorthand string, value []bool, usage string) {\n\tCommandLine.VarP(newBoolSliceValue(value, p), name, shorthand, usage)\n}\n\n// BoolSlice defines a []bool flag with specified name, default value, and usage string.\n// The return value is the address of a []bool variable that stores the value of the flag.\nfunc (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool {\n\tp := []bool{}\n\tf.BoolSliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {\n\tp := []bool{}\n\tf.BoolSliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// BoolSlice defines a []bool flag with specified name, default value, and usage string.\n// The return value is the address of a []bool variable that stores the value of the flag.\nfunc BoolSlice(name string, value []bool, usage string) *[]bool {\n\treturn CommandLine.BoolSliceP(name, \"\", value, usage)\n}\n\n// BoolSliceP is like BoolSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc BoolSliceP(name, shorthand string, value []bool, usage string) *[]bool {\n\treturn CommandLine.BoolSliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/bytes.go",
    "content": "package pflag\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded\ntype bytesHexValue []byte\n\n// String implements pflag.Value.String.\nfunc (bytesHex bytesHexValue) String() string {\n\treturn fmt.Sprintf(\"%X\", []byte(bytesHex))\n}\n\n// Set implements pflag.Value.Set.\nfunc (bytesHex *bytesHexValue) Set(value string) error {\n\tbin, err := hex.DecodeString(strings.TrimSpace(value))\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*bytesHex = bin\n\n\treturn nil\n}\n\n// Type implements pflag.Value.Type.\nfunc (*bytesHexValue) Type() string {\n\treturn \"bytesHex\"\n}\n\nfunc newBytesHexValue(val []byte, p *[]byte) *bytesHexValue {\n\t*p = val\n\treturn (*bytesHexValue)(p)\n}\n\nfunc bytesHexConv(sval string) (interface{}, error) {\n\n\tbin, err := hex.DecodeString(sval)\n\n\tif err == nil {\n\t\treturn bin, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"invalid string being converted to Bytes: %s %s\", sval, err)\n}\n\n// GetBytesHex return the []byte value of a flag with the given name\nfunc (f *FlagSet) GetBytesHex(name string) ([]byte, error) {\n\tval, err := f.getFlagType(name, \"bytesHex\", bytesHexConv)\n\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\n\treturn val.([]byte), nil\n}\n\n// BytesHexVar defines an []byte flag with specified name, default value, and usage string.\n// The argument p points to an []byte variable in which to store the value of the flag.\nfunc (f *FlagSet) BytesHexVar(p *[]byte, name string, value []byte, usage string) {\n\tf.VarP(newBytesHexValue(value, p), name, \"\", usage)\n}\n\n// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {\n\tf.VarP(newBytesHexValue(value, p), name, shorthand, usage)\n}\n\n// BytesHexVar defines an []byte flag with specified name, default value, and usage string.\n// The argument p points to an []byte variable in which to store the value of the flag.\nfunc BytesHexVar(p *[]byte, name string, value []byte, usage string) {\n\tCommandLine.VarP(newBytesHexValue(value, p), name, \"\", usage)\n}\n\n// BytesHexVarP is like BytesHexVar, but accepts a shorthand letter that can be used after a single dash.\nfunc BytesHexVarP(p *[]byte, name, shorthand string, value []byte, usage string) {\n\tCommandLine.VarP(newBytesHexValue(value, p), name, shorthand, usage)\n}\n\n// BytesHex defines an []byte flag with specified name, default value, and usage string.\n// The return value is the address of an []byte variable that stores the value of the flag.\nfunc (f *FlagSet) BytesHex(name string, value []byte, usage string) *[]byte {\n\tp := new([]byte)\n\tf.BytesHexVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {\n\tp := new([]byte)\n\tf.BytesHexVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// BytesHex defines an []byte flag with specified name, default value, and usage string.\n// The return value is the address of an []byte variable that stores the value of the flag.\nfunc BytesHex(name string, value []byte, usage string) *[]byte {\n\treturn CommandLine.BytesHexP(name, \"\", value, usage)\n}\n\n// BytesHexP is like BytesHex, but accepts a shorthand letter that can be used after a single dash.\nfunc BytesHexP(name, shorthand string, value []byte, usage string) *[]byte {\n\treturn CommandLine.BytesHexP(name, shorthand, value, usage)\n}\n\n// BytesBase64 adapts []byte for use as a flag. Value of flag is Base64 encoded\ntype bytesBase64Value []byte\n\n// String implements pflag.Value.String.\nfunc (bytesBase64 bytesBase64Value) String() string {\n\treturn base64.StdEncoding.EncodeToString([]byte(bytesBase64))\n}\n\n// Set implements pflag.Value.Set.\nfunc (bytesBase64 *bytesBase64Value) Set(value string) error {\n\tbin, err := base64.StdEncoding.DecodeString(strings.TrimSpace(value))\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t*bytesBase64 = bin\n\n\treturn nil\n}\n\n// Type implements pflag.Value.Type.\nfunc (*bytesBase64Value) Type() string {\n\treturn \"bytesBase64\"\n}\n\nfunc newBytesBase64Value(val []byte, p *[]byte) *bytesBase64Value {\n\t*p = val\n\treturn (*bytesBase64Value)(p)\n}\n\nfunc bytesBase64ValueConv(sval string) (interface{}, error) {\n\n\tbin, err := base64.StdEncoding.DecodeString(sval)\n\tif err == nil {\n\t\treturn bin, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"invalid string being converted to Bytes: %s %s\", sval, err)\n}\n\n// GetBytesBase64 return the []byte value of a flag with the given name\nfunc (f *FlagSet) GetBytesBase64(name string) ([]byte, error) {\n\tval, err := f.getFlagType(name, \"bytesBase64\", bytesBase64ValueConv)\n\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\n\treturn val.([]byte), nil\n}\n\n// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.\n// The argument p points to an []byte variable in which to store the value of the flag.\nfunc (f *FlagSet) BytesBase64Var(p *[]byte, name string, value []byte, usage string) {\n\tf.VarP(newBytesBase64Value(value, p), name, \"\", usage)\n}\n\n// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {\n\tf.VarP(newBytesBase64Value(value, p), name, shorthand, usage)\n}\n\n// BytesBase64Var defines an []byte flag with specified name, default value, and usage string.\n// The argument p points to an []byte variable in which to store the value of the flag.\nfunc BytesBase64Var(p *[]byte, name string, value []byte, usage string) {\n\tCommandLine.VarP(newBytesBase64Value(value, p), name, \"\", usage)\n}\n\n// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) {\n\tCommandLine.VarP(newBytesBase64Value(value, p), name, shorthand, usage)\n}\n\n// BytesBase64 defines an []byte flag with specified name, default value, and usage string.\n// The return value is the address of an []byte variable that stores the value of the flag.\nfunc (f *FlagSet) BytesBase64(name string, value []byte, usage string) *[]byte {\n\tp := new([]byte)\n\tf.BytesBase64VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {\n\tp := new([]byte)\n\tf.BytesBase64VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// BytesBase64 defines an []byte flag with specified name, default value, and usage string.\n// The return value is the address of an []byte variable that stores the value of the flag.\nfunc BytesBase64(name string, value []byte, usage string) *[]byte {\n\treturn CommandLine.BytesBase64P(name, \"\", value, usage)\n}\n\n// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash.\nfunc BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte {\n\treturn CommandLine.BytesBase64P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/count.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- count Value\ntype countValue int\n\nfunc newCountValue(val int, p *int) *countValue {\n\t*p = val\n\treturn (*countValue)(p)\n}\n\nfunc (i *countValue) Set(s string) error {\n\t// \"+1\" means that no specific value was passed, so increment\n\tif s == \"+1\" {\n\t\t*i = countValue(*i + 1)\n\t\treturn nil\n\t}\n\tv, err := strconv.ParseInt(s, 0, 0)\n\t*i = countValue(v)\n\treturn err\n}\n\nfunc (i *countValue) Type() string {\n\treturn \"count\"\n}\n\nfunc (i *countValue) String() string { return strconv.Itoa(int(*i)) }\n\nfunc countConv(sval string) (interface{}, error) {\n\ti, err := strconv.Atoi(sval)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn i, nil\n}\n\n// GetCount return the int value of a flag with the given name\nfunc (f *FlagSet) GetCount(name string) (int, error) {\n\tval, err := f.getFlagType(name, \"count\", countConv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(int), nil\n}\n\n// CountVar defines a count flag with specified name, default value, and usage string.\n// The argument p points to an int variable in which to store the value of the flag.\n// A count flag will add 1 to its value every time it is found on the command line\nfunc (f *FlagSet) CountVar(p *int, name string, usage string) {\n\tf.CountVarP(p, name, \"\", usage)\n}\n\n// CountVarP is like CountVar only take a shorthand for the flag name.\nfunc (f *FlagSet) CountVarP(p *int, name, shorthand string, usage string) {\n\tflag := f.VarPF(newCountValue(0, p), name, shorthand, usage)\n\tflag.NoOptDefVal = \"+1\"\n}\n\n// CountVar like CountVar only the flag is placed on the CommandLine instead of a given flag set\nfunc CountVar(p *int, name string, usage string) {\n\tCommandLine.CountVar(p, name, usage)\n}\n\n// CountVarP is like CountVar only take a shorthand for the flag name.\nfunc CountVarP(p *int, name, shorthand string, usage string) {\n\tCommandLine.CountVarP(p, name, shorthand, usage)\n}\n\n// Count defines a count flag with specified name, default value, and usage string.\n// The return value is the address of an int variable that stores the value of the flag.\n// A count flag will add 1 to its value every time it is found on the command line\nfunc (f *FlagSet) Count(name string, usage string) *int {\n\tp := new(int)\n\tf.CountVarP(p, name, \"\", usage)\n\treturn p\n}\n\n// CountP is like Count only takes a shorthand for the flag name.\nfunc (f *FlagSet) CountP(name, shorthand string, usage string) *int {\n\tp := new(int)\n\tf.CountVarP(p, name, shorthand, usage)\n\treturn p\n}\n\n// Count defines a count flag with specified name, default value, and usage string.\n// The return value is the address of an int variable that stores the value of the flag.\n// A count flag will add 1 to its value evey time it is found on the command line\nfunc Count(name string, usage string) *int {\n\treturn CommandLine.CountP(name, \"\", usage)\n}\n\n// CountP is like Count only takes a shorthand for the flag name.\nfunc CountP(name, shorthand string, usage string) *int {\n\treturn CommandLine.CountP(name, shorthand, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/duration.go",
    "content": "package pflag\n\nimport (\n\t\"time\"\n)\n\n// -- time.Duration Value\ntype durationValue time.Duration\n\nfunc newDurationValue(val time.Duration, p *time.Duration) *durationValue {\n\t*p = val\n\treturn (*durationValue)(p)\n}\n\nfunc (d *durationValue) Set(s string) error {\n\tv, err := time.ParseDuration(s)\n\t*d = durationValue(v)\n\treturn err\n}\n\nfunc (d *durationValue) Type() string {\n\treturn \"duration\"\n}\n\nfunc (d *durationValue) String() string { return (*time.Duration)(d).String() }\n\nfunc durationConv(sval string) (interface{}, error) {\n\treturn time.ParseDuration(sval)\n}\n\n// GetDuration return the duration value of a flag with the given name\nfunc (f *FlagSet) GetDuration(name string) (time.Duration, error) {\n\tval, err := f.getFlagType(name, \"duration\", durationConv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(time.Duration), nil\n}\n\n// DurationVar defines a time.Duration flag with specified name, default value, and usage string.\n// The argument p points to a time.Duration variable in which to store the value of the flag.\nfunc (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {\n\tf.VarP(newDurationValue(value, p), name, \"\", usage)\n}\n\n// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {\n\tf.VarP(newDurationValue(value, p), name, shorthand, usage)\n}\n\n// DurationVar defines a time.Duration flag with specified name, default value, and usage string.\n// The argument p points to a time.Duration variable in which to store the value of the flag.\nfunc DurationVar(p *time.Duration, name string, value time.Duration, usage string) {\n\tCommandLine.VarP(newDurationValue(value, p), name, \"\", usage)\n}\n\n// DurationVarP is like DurationVar, but accepts a shorthand letter that can be used after a single dash.\nfunc DurationVarP(p *time.Duration, name, shorthand string, value time.Duration, usage string) {\n\tCommandLine.VarP(newDurationValue(value, p), name, shorthand, usage)\n}\n\n// Duration defines a time.Duration flag with specified name, default value, and usage string.\n// The return value is the address of a time.Duration variable that stores the value of the flag.\nfunc (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {\n\tp := new(time.Duration)\n\tf.DurationVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {\n\tp := new(time.Duration)\n\tf.DurationVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Duration defines a time.Duration flag with specified name, default value, and usage string.\n// The return value is the address of a time.Duration variable that stores the value of the flag.\nfunc Duration(name string, value time.Duration, usage string) *time.Duration {\n\treturn CommandLine.DurationP(name, \"\", value, usage)\n}\n\n// DurationP is like Duration, but accepts a shorthand letter that can be used after a single dash.\nfunc DurationP(name, shorthand string, value time.Duration, usage string) *time.Duration {\n\treturn CommandLine.DurationP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/duration_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n)\n\n// -- durationSlice Value\ntype durationSliceValue struct {\n\tvalue   *[]time.Duration\n\tchanged bool\n}\n\nfunc newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSliceValue {\n\tdsv := new(durationSliceValue)\n\tdsv.value = p\n\t*dsv.value = val\n\treturn dsv\n}\n\nfunc (s *durationSliceValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make([]time.Duration, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = time.ParseDuration(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *durationSliceValue) Type() string {\n\treturn \"durationSlice\"\n}\n\nfunc (s *durationSliceValue) String() string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = fmt.Sprintf(\"%s\", d)\n\t}\n\treturn \"[\" + strings.Join(out, \",\") + \"]\"\n}\n\nfunc (s *durationSliceValue) fromString(val string) (time.Duration, error) {\n\treturn time.ParseDuration(val)\n}\n\nfunc (s *durationSliceValue) toString(val time.Duration) string {\n\treturn fmt.Sprintf(\"%s\", val)\n}\n\nfunc (s *durationSliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *durationSliceValue) Replace(val []string) error {\n\tout := make([]time.Duration, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *durationSliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc durationSliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []time.Duration{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]time.Duration, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = time.ParseDuration(d)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t}\n\treturn out, nil\n}\n\n// GetDurationSlice returns the []time.Duration value of a flag with the given name\nfunc (f *FlagSet) GetDurationSlice(name string) ([]time.Duration, error) {\n\tval, err := f.getFlagType(name, \"durationSlice\", durationSliceConv)\n\tif err != nil {\n\t\treturn []time.Duration{}, err\n\t}\n\treturn val.([]time.Duration), nil\n}\n\n// DurationSliceVar defines a durationSlice flag with specified name, default value, and usage string.\n// The argument p points to a []time.Duration variable in which to store the value of the flag.\nfunc (f *FlagSet) DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {\n\tf.VarP(newDurationSliceValue(value, p), name, \"\", usage)\n}\n\n// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {\n\tf.VarP(newDurationSliceValue(value, p), name, shorthand, usage)\n}\n\n// DurationSliceVar defines a duration[] flag with specified name, default value, and usage string.\n// The argument p points to a duration[] variable in which to store the value of the flag.\nfunc DurationSliceVar(p *[]time.Duration, name string, value []time.Duration, usage string) {\n\tCommandLine.VarP(newDurationSliceValue(value, p), name, \"\", usage)\n}\n\n// DurationSliceVarP is like DurationSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc DurationSliceVarP(p *[]time.Duration, name, shorthand string, value []time.Duration, usage string) {\n\tCommandLine.VarP(newDurationSliceValue(value, p), name, shorthand, usage)\n}\n\n// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.\n// The return value is the address of a []time.Duration variable that stores the value of the flag.\nfunc (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {\n\tp := []time.Duration{}\n\tf.DurationSliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {\n\tp := []time.Duration{}\n\tf.DurationSliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string.\n// The return value is the address of a []time.Duration variable that stores the value of the flag.\nfunc DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration {\n\treturn CommandLine.DurationSliceP(name, \"\", value, usage)\n}\n\n// DurationSliceP is like DurationSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc DurationSliceP(name, shorthand string, value []time.Duration, usage string) *[]time.Duration {\n\treturn CommandLine.DurationSliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/flag.go",
    "content": "// Copyright 2009 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/*\nPackage pflag is a drop-in replacement for Go's flag package, implementing\nPOSIX/GNU-style --flags.\n\npflag is compatible with the GNU extensions to the POSIX recommendations\nfor command-line options. See\nhttp://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html\n\nUsage:\n\npflag is a drop-in replacement of Go's native flag package. If you import\npflag under the name \"flag\" then all code should continue to function\nwith no changes.\n\n\timport flag \"github.com/spf13/pflag\"\n\nThere is one exception to this: if you directly instantiate the Flag struct\nthere is one more field \"Shorthand\" that you will need to set.\nMost code never instantiates this struct directly, and instead uses\nfunctions such as String(), BoolVar(), and Var(), and is therefore\nunaffected.\n\nDefine flags using flag.String(), Bool(), Int(), etc.\n\nThis declares an integer flag, -flagname, stored in the pointer ip, with type *int.\n\tvar ip = flag.Int(\"flagname\", 1234, \"help message for flagname\")\nIf you like, you can bind the flag to a variable using the Var() functions.\n\tvar flagvar int\n\tfunc init() {\n\t\tflag.IntVar(&flagvar, \"flagname\", 1234, \"help message for flagname\")\n\t}\nOr you can create custom flags that satisfy the Value interface (with\npointer receivers) and couple them to flag parsing by\n\tflag.Var(&flagVal, \"name\", \"help message for flagname\")\nFor such flags, the default value is just the initial value of the variable.\n\nAfter all flags are defined, call\n\tflag.Parse()\nto parse the command line into the defined flags.\n\nFlags may then be used directly. If you're using the flags themselves,\nthey are all pointers; if you bind to variables, they're values.\n\tfmt.Println(\"ip has value \", *ip)\n\tfmt.Println(\"flagvar has value \", flagvar)\n\nAfter parsing, the arguments after the flag are available as the\nslice flag.Args() or individually as flag.Arg(i).\nThe arguments are indexed from 0 through flag.NArg()-1.\n\nThe pflag package also defines some new functions that are not in flag,\nthat give one-letter shorthands for flags. You can use these by appending\n'P' to the name of any function that defines a flag.\n\tvar ip = flag.IntP(\"flagname\", \"f\", 1234, \"help message\")\n\tvar flagvar bool\n\tfunc init() {\n\t\tflag.BoolVarP(&flagvar, \"boolname\", \"b\", true, \"help message\")\n\t}\n\tflag.VarP(&flagval, \"varname\", \"v\", \"help message\")\nShorthand letters can be used with single dashes on the command line.\nBoolean shorthand flags can be combined with other shorthand flags.\n\nCommand line flag syntax:\n\t--flag    // boolean flags only\n\t--flag=x\n\nUnlike the flag package, a single dash before an option means something\ndifferent than a double dash. Single dashes signify a series of shorthand\nletters for flags. All but the last shorthand letter must be boolean flags.\n\t// boolean flags\n\t-f\n\t-abc\n\t// non-boolean flags\n\t-n 1234\n\t-Ifile\n\t// mixed\n\t-abcs \"hello\"\n\t-abcn1234\n\nFlag parsing stops after the terminator \"--\". Unlike the flag package,\nflags can be interspersed with arguments anywhere on the command line\nbefore this terminator.\n\nInteger flags accept 1234, 0664, 0x1234 and may be negative.\nBoolean flags (in their long form) accept 1, 0, t, f, true, false,\nTRUE, FALSE, True, False.\nDuration flags accept any input valid for time.ParseDuration.\n\nThe default set of command-line flags is controlled by\ntop-level functions.  The FlagSet type allows one to define\nindependent sets of flags, such as to implement subcommands\nin a command-line interface. The methods of FlagSet are\nanalogous to the top-level functions for the command-line\nflag set.\n*/\npackage pflag\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\tgoflag \"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"sort\"\n\t\"strings\"\n)\n\n// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.\nvar ErrHelp = errors.New(\"pflag: help requested\")\n\n// ErrorHandling defines how to handle flag parsing errors.\ntype ErrorHandling int\n\nconst (\n\t// ContinueOnError will return an err from Parse() if an error is found\n\tContinueOnError ErrorHandling = iota\n\t// ExitOnError will call os.Exit(2) if an error is found when parsing\n\tExitOnError\n\t// PanicOnError will panic() if an error is found when parsing flags\n\tPanicOnError\n)\n\n// ParseErrorsWhitelist defines the parsing errors that can be ignored\ntype ParseErrorsWhitelist struct {\n\t// UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags\n\tUnknownFlags bool\n}\n\n// NormalizedName is a flag name that has been normalized according to rules\n// for the FlagSet (e.g. making '-' and '_' equivalent).\ntype NormalizedName string\n\n// A FlagSet represents a set of defined flags.\ntype FlagSet struct {\n\t// Usage is the function called when an error occurs while parsing flags.\n\t// The field is a function (not a method) that may be changed to point to\n\t// a custom error handler.\n\tUsage func()\n\n\t// SortFlags is used to indicate, if user wants to have sorted flags in\n\t// help/usage messages.\n\tSortFlags bool\n\n\t// ParseErrorsWhitelist is used to configure a whitelist of errors\n\tParseErrorsWhitelist ParseErrorsWhitelist\n\n\tname              string\n\tparsed            bool\n\tactual            map[NormalizedName]*Flag\n\torderedActual     []*Flag\n\tsortedActual      []*Flag\n\tformal            map[NormalizedName]*Flag\n\torderedFormal     []*Flag\n\tsortedFormal      []*Flag\n\tshorthands        map[byte]*Flag\n\targs              []string // arguments after flags\n\targsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --\n\terrorHandling     ErrorHandling\n\toutput            io.Writer // nil means stderr; use out() accessor\n\tinterspersed      bool      // allow interspersed option/non-option args\n\tnormalizeNameFunc func(f *FlagSet, name string) NormalizedName\n\n\taddedGoFlagSets []*goflag.FlagSet\n}\n\n// A Flag represents the state of a flag.\ntype Flag struct {\n\tName                string              // name as it appears on command line\n\tShorthand           string              // one-letter abbreviated flag\n\tUsage               string              // help message\n\tValue               Value               // value as set\n\tDefValue            string              // default value (as text); for usage message\n\tChanged             bool                // If the user set the value (or if left to default)\n\tNoOptDefVal         string              // default value (as text); if the flag is on the command line without any options\n\tDeprecated          string              // If this flag is deprecated, this string is the new or now thing to use\n\tHidden              bool                // used by cobra.Command to allow flags to be hidden from help/usage text\n\tShorthandDeprecated string              // If the shorthand of this flag is deprecated, this string is the new or now thing to use\n\tAnnotations         map[string][]string // used by cobra.Command bash autocomple code\n}\n\n// Value is the interface to the dynamic value stored in a flag.\n// (The default value is represented as a string.)\ntype Value interface {\n\tString() string\n\tSet(string) error\n\tType() string\n}\n\n// SliceValue is a secondary interface to all flags which hold a list\n// of values.  This allows full control over the value of list flags,\n// and avoids complicated marshalling and unmarshalling to csv.\ntype SliceValue interface {\n\t// Append adds the specified value to the end of the flag value list.\n\tAppend(string) error\n\t// Replace will fully overwrite any data currently in the flag value list.\n\tReplace([]string) error\n\t// GetSlice returns the flag value list as an array of strings.\n\tGetSlice() []string\n}\n\n// sortFlags returns the flags as a slice in lexicographical sorted order.\nfunc sortFlags(flags map[NormalizedName]*Flag) []*Flag {\n\tlist := make(sort.StringSlice, len(flags))\n\ti := 0\n\tfor k := range flags {\n\t\tlist[i] = string(k)\n\t\ti++\n\t}\n\tlist.Sort()\n\tresult := make([]*Flag, len(list))\n\tfor i, name := range list {\n\t\tresult[i] = flags[NormalizedName(name)]\n\t}\n\treturn result\n}\n\n// SetNormalizeFunc allows you to add a function which can translate flag names.\n// Flags added to the FlagSet will be translated and then when anything tries to\n// look up the flag that will also be translated. So it would be possible to create\n// a flag named \"getURL\" and have it translated to \"geturl\".  A user could then pass\n// \"--getUrl\" which may also be translated to \"geturl\" and everything will work.\nfunc (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {\n\tf.normalizeNameFunc = n\n\tf.sortedFormal = f.sortedFormal[:0]\n\tfor fname, flag := range f.formal {\n\t\tnname := f.normalizeFlagName(flag.Name)\n\t\tif fname == nname {\n\t\t\tcontinue\n\t\t}\n\t\tflag.Name = string(nname)\n\t\tdelete(f.formal, fname)\n\t\tf.formal[nname] = flag\n\t\tif _, set := f.actual[fname]; set {\n\t\t\tdelete(f.actual, fname)\n\t\t\tf.actual[nname] = flag\n\t\t}\n\t}\n}\n\n// GetNormalizeFunc returns the previously set NormalizeFunc of a function which\n// does no translation, if not set previously.\nfunc (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {\n\tif f.normalizeNameFunc != nil {\n\t\treturn f.normalizeNameFunc\n\t}\n\treturn func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }\n}\n\nfunc (f *FlagSet) normalizeFlagName(name string) NormalizedName {\n\tn := f.GetNormalizeFunc()\n\treturn n(f, name)\n}\n\nfunc (f *FlagSet) out() io.Writer {\n\tif f.output == nil {\n\t\treturn os.Stderr\n\t}\n\treturn f.output\n}\n\n// SetOutput sets the destination for usage and error messages.\n// If output is nil, os.Stderr is used.\nfunc (f *FlagSet) SetOutput(output io.Writer) {\n\tf.output = output\n}\n\n// VisitAll visits the flags in lexicographical order or\n// in primordial order if f.SortFlags is false, calling fn for each.\n// It visits all flags, even those not set.\nfunc (f *FlagSet) VisitAll(fn func(*Flag)) {\n\tif len(f.formal) == 0 {\n\t\treturn\n\t}\n\n\tvar flags []*Flag\n\tif f.SortFlags {\n\t\tif len(f.formal) != len(f.sortedFormal) {\n\t\t\tf.sortedFormal = sortFlags(f.formal)\n\t\t}\n\t\tflags = f.sortedFormal\n\t} else {\n\t\tflags = f.orderedFormal\n\t}\n\n\tfor _, flag := range flags {\n\t\tfn(flag)\n\t}\n}\n\n// HasFlags returns a bool to indicate if the FlagSet has any flags defined.\nfunc (f *FlagSet) HasFlags() bool {\n\treturn len(f.formal) > 0\n}\n\n// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags\n// that are not hidden.\nfunc (f *FlagSet) HasAvailableFlags() bool {\n\tfor _, flag := range f.formal {\n\t\tif !flag.Hidden {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// VisitAll visits the command-line flags in lexicographical order or\n// in primordial order if f.SortFlags is false, calling fn for each.\n// It visits all flags, even those not set.\nfunc VisitAll(fn func(*Flag)) {\n\tCommandLine.VisitAll(fn)\n}\n\n// Visit visits the flags in lexicographical order or\n// in primordial order if f.SortFlags is false, calling fn for each.\n// It visits only those flags that have been set.\nfunc (f *FlagSet) Visit(fn func(*Flag)) {\n\tif len(f.actual) == 0 {\n\t\treturn\n\t}\n\n\tvar flags []*Flag\n\tif f.SortFlags {\n\t\tif len(f.actual) != len(f.sortedActual) {\n\t\t\tf.sortedActual = sortFlags(f.actual)\n\t\t}\n\t\tflags = f.sortedActual\n\t} else {\n\t\tflags = f.orderedActual\n\t}\n\n\tfor _, flag := range flags {\n\t\tfn(flag)\n\t}\n}\n\n// Visit visits the command-line flags in lexicographical order or\n// in primordial order if f.SortFlags is false, calling fn for each.\n// It visits only those flags that have been set.\nfunc Visit(fn func(*Flag)) {\n\tCommandLine.Visit(fn)\n}\n\n// Lookup returns the Flag structure of the named flag, returning nil if none exists.\nfunc (f *FlagSet) Lookup(name string) *Flag {\n\treturn f.lookup(f.normalizeFlagName(name))\n}\n\n// ShorthandLookup returns the Flag structure of the short handed flag,\n// returning nil if none exists.\n// It panics, if len(name) > 1.\nfunc (f *FlagSet) ShorthandLookup(name string) *Flag {\n\tif name == \"\" {\n\t\treturn nil\n\t}\n\tif len(name) > 1 {\n\t\tmsg := fmt.Sprintf(\"can not look up shorthand which is more than one ASCII character: %q\", name)\n\t\tfmt.Fprintf(f.out(), msg)\n\t\tpanic(msg)\n\t}\n\tc := name[0]\n\treturn f.shorthands[c]\n}\n\n// lookup returns the Flag structure of the named flag, returning nil if none exists.\nfunc (f *FlagSet) lookup(name NormalizedName) *Flag {\n\treturn f.formal[name]\n}\n\n// func to return a given type for a given flag name\nfunc (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {\n\tflag := f.Lookup(name)\n\tif flag == nil {\n\t\terr := fmt.Errorf(\"flag accessed but not defined: %s\", name)\n\t\treturn nil, err\n\t}\n\n\tif flag.Value.Type() != ftype {\n\t\terr := fmt.Errorf(\"trying to get %s value of flag of type %s\", ftype, flag.Value.Type())\n\t\treturn nil, err\n\t}\n\n\tsval := flag.Value.String()\n\tresult, err := convFunc(sval)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn result, nil\n}\n\n// ArgsLenAtDash will return the length of f.Args at the moment when a -- was\n// found during arg parsing. This allows your program to know which args were\n// before the -- and which came after.\nfunc (f *FlagSet) ArgsLenAtDash() int {\n\treturn f.argsLenAtDash\n}\n\n// MarkDeprecated indicated that a flag is deprecated in your program. It will\n// continue to function but will not show up in help or usage messages. Using\n// this flag will also print the given usageMessage.\nfunc (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {\n\tflag := f.Lookup(name)\n\tif flag == nil {\n\t\treturn fmt.Errorf(\"flag %q does not exist\", name)\n\t}\n\tif usageMessage == \"\" {\n\t\treturn fmt.Errorf(\"deprecated message for flag %q must be set\", name)\n\t}\n\tflag.Deprecated = usageMessage\n\tflag.Hidden = true\n\treturn nil\n}\n\n// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your\n// program. It will continue to function but will not show up in help or usage\n// messages. Using this flag will also print the given usageMessage.\nfunc (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {\n\tflag := f.Lookup(name)\n\tif flag == nil {\n\t\treturn fmt.Errorf(\"flag %q does not exist\", name)\n\t}\n\tif usageMessage == \"\" {\n\t\treturn fmt.Errorf(\"deprecated message for flag %q must be set\", name)\n\t}\n\tflag.ShorthandDeprecated = usageMessage\n\treturn nil\n}\n\n// MarkHidden sets a flag to 'hidden' in your program. It will continue to\n// function but will not show up in help or usage messages.\nfunc (f *FlagSet) MarkHidden(name string) error {\n\tflag := f.Lookup(name)\n\tif flag == nil {\n\t\treturn fmt.Errorf(\"flag %q does not exist\", name)\n\t}\n\tflag.Hidden = true\n\treturn nil\n}\n\n// Lookup returns the Flag structure of the named command-line flag,\n// returning nil if none exists.\nfunc Lookup(name string) *Flag {\n\treturn CommandLine.Lookup(name)\n}\n\n// ShorthandLookup returns the Flag structure of the short handed flag,\n// returning nil if none exists.\nfunc ShorthandLookup(name string) *Flag {\n\treturn CommandLine.ShorthandLookup(name)\n}\n\n// Set sets the value of the named flag.\nfunc (f *FlagSet) Set(name, value string) error {\n\tnormalName := f.normalizeFlagName(name)\n\tflag, ok := f.formal[normalName]\n\tif !ok {\n\t\treturn fmt.Errorf(\"no such flag -%v\", name)\n\t}\n\n\terr := flag.Value.Set(value)\n\tif err != nil {\n\t\tvar flagName string\n\t\tif flag.Shorthand != \"\" && flag.ShorthandDeprecated == \"\" {\n\t\t\tflagName = fmt.Sprintf(\"-%s, --%s\", flag.Shorthand, flag.Name)\n\t\t} else {\n\t\t\tflagName = fmt.Sprintf(\"--%s\", flag.Name)\n\t\t}\n\t\treturn fmt.Errorf(\"invalid argument %q for %q flag: %v\", value, flagName, err)\n\t}\n\n\tif !flag.Changed {\n\t\tif f.actual == nil {\n\t\t\tf.actual = make(map[NormalizedName]*Flag)\n\t\t}\n\t\tf.actual[normalName] = flag\n\t\tf.orderedActual = append(f.orderedActual, flag)\n\n\t\tflag.Changed = true\n\t}\n\n\tif flag.Deprecated != \"\" {\n\t\tfmt.Fprintf(f.out(), \"Flag --%s has been deprecated, %s\\n\", flag.Name, flag.Deprecated)\n\t}\n\treturn nil\n}\n\n// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.\n// This is sometimes used by spf13/cobra programs which want to generate additional\n// bash completion information.\nfunc (f *FlagSet) SetAnnotation(name, key string, values []string) error {\n\tnormalName := f.normalizeFlagName(name)\n\tflag, ok := f.formal[normalName]\n\tif !ok {\n\t\treturn fmt.Errorf(\"no such flag -%v\", name)\n\t}\n\tif flag.Annotations == nil {\n\t\tflag.Annotations = map[string][]string{}\n\t}\n\tflag.Annotations[key] = values\n\treturn nil\n}\n\n// Changed returns true if the flag was explicitly set during Parse() and false\n// otherwise\nfunc (f *FlagSet) Changed(name string) bool {\n\tflag := f.Lookup(name)\n\t// If a flag doesn't exist, it wasn't changed....\n\tif flag == nil {\n\t\treturn false\n\t}\n\treturn flag.Changed\n}\n\n// Set sets the value of the named command-line flag.\nfunc Set(name, value string) error {\n\treturn CommandLine.Set(name, value)\n}\n\n// PrintDefaults prints, to standard error unless configured\n// otherwise, the default values of all defined flags in the set.\nfunc (f *FlagSet) PrintDefaults() {\n\tusages := f.FlagUsages()\n\tfmt.Fprint(f.out(), usages)\n}\n\n// defaultIsZeroValue returns true if the default value for this flag represents\n// a zero value.\nfunc (f *Flag) defaultIsZeroValue() bool {\n\tswitch f.Value.(type) {\n\tcase boolFlag:\n\t\treturn f.DefValue == \"false\"\n\tcase *durationValue:\n\t\t// Beginning in Go 1.7, duration zero values are \"0s\"\n\t\treturn f.DefValue == \"0\" || f.DefValue == \"0s\"\n\tcase *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:\n\t\treturn f.DefValue == \"0\"\n\tcase *stringValue:\n\t\treturn f.DefValue == \"\"\n\tcase *ipValue, *ipMaskValue, *ipNetValue:\n\t\treturn f.DefValue == \"<nil>\"\n\tcase *intSliceValue, *stringSliceValue, *stringArrayValue:\n\t\treturn f.DefValue == \"[]\"\n\tdefault:\n\t\tswitch f.Value.String() {\n\t\tcase \"false\":\n\t\t\treturn true\n\t\tcase \"<nil>\":\n\t\t\treturn true\n\t\tcase \"\":\n\t\t\treturn true\n\t\tcase \"0\":\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n}\n\n// UnquoteUsage extracts a back-quoted name from the usage\n// string for a flag and returns it and the un-quoted usage.\n// Given \"a `name` to show\" it returns (\"name\", \"a name to show\").\n// If there are no back quotes, the name is an educated guess of the\n// type of the flag's value, or the empty string if the flag is boolean.\nfunc UnquoteUsage(flag *Flag) (name string, usage string) {\n\t// Look for a back-quoted name, but avoid the strings package.\n\tusage = flag.Usage\n\tfor i := 0; i < len(usage); i++ {\n\t\tif usage[i] == '`' {\n\t\t\tfor j := i + 1; j < len(usage); j++ {\n\t\t\t\tif usage[j] == '`' {\n\t\t\t\t\tname = usage[i+1 : j]\n\t\t\t\t\tusage = usage[:i] + name + usage[j+1:]\n\t\t\t\t\treturn name, usage\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak // Only one back quote; use type name.\n\t\t}\n\t}\n\n\tname = flag.Value.Type()\n\tswitch name {\n\tcase \"bool\":\n\t\tname = \"\"\n\tcase \"float64\":\n\t\tname = \"float\"\n\tcase \"int64\":\n\t\tname = \"int\"\n\tcase \"uint64\":\n\t\tname = \"uint\"\n\tcase \"stringSlice\":\n\t\tname = \"strings\"\n\tcase \"intSlice\":\n\t\tname = \"ints\"\n\tcase \"uintSlice\":\n\t\tname = \"uints\"\n\tcase \"boolSlice\":\n\t\tname = \"bools\"\n\t}\n\n\treturn\n}\n\n// Splits the string `s` on whitespace into an initial substring up to\n// `i` runes in length and the remainder. Will go `slop` over `i` if\n// that encompasses the entire string (which allows the caller to\n// avoid short orphan words on the final line).\nfunc wrapN(i, slop int, s string) (string, string) {\n\tif i+slop > len(s) {\n\t\treturn s, \"\"\n\t}\n\n\tw := strings.LastIndexAny(s[:i], \" \\t\\n\")\n\tif w <= 0 {\n\t\treturn s, \"\"\n\t}\n\tnlPos := strings.LastIndex(s[:i], \"\\n\")\n\tif nlPos > 0 && nlPos < w {\n\t\treturn s[:nlPos], s[nlPos+1:]\n\t}\n\treturn s[:w], s[w+1:]\n}\n\n// Wraps the string `s` to a maximum width `w` with leading indent\n// `i`. The first line is not indented (this is assumed to be done by\n// caller). Pass `w` == 0 to do no wrapping\nfunc wrap(i, w int, s string) string {\n\tif w == 0 {\n\t\treturn strings.Replace(s, \"\\n\", \"\\n\"+strings.Repeat(\" \", i), -1)\n\t}\n\n\t// space between indent i and end of line width w into which\n\t// we should wrap the text.\n\twrap := w - i\n\n\tvar r, l string\n\n\t// Not enough space for sensible wrapping. Wrap as a block on\n\t// the next line instead.\n\tif wrap < 24 {\n\t\ti = 16\n\t\twrap = w - i\n\t\tr += \"\\n\" + strings.Repeat(\" \", i)\n\t}\n\t// If still not enough space then don't even try to wrap.\n\tif wrap < 24 {\n\t\treturn strings.Replace(s, \"\\n\", r, -1)\n\t}\n\n\t// Try to avoid short orphan words on the final line, by\n\t// allowing wrapN to go a bit over if that would fit in the\n\t// remainder of the line.\n\tslop := 5\n\twrap = wrap - slop\n\n\t// Handle first line, which is indented by the caller (or the\n\t// special case above)\n\tl, s = wrapN(wrap, slop, s)\n\tr = r + strings.Replace(l, \"\\n\", \"\\n\"+strings.Repeat(\" \", i), -1)\n\n\t// Now wrap the rest\n\tfor s != \"\" {\n\t\tvar t string\n\n\t\tt, s = wrapN(wrap, slop, s)\n\t\tr = r + \"\\n\" + strings.Repeat(\" \", i) + strings.Replace(t, \"\\n\", \"\\n\"+strings.Repeat(\" \", i), -1)\n\t}\n\n\treturn r\n\n}\n\n// FlagUsagesWrapped returns a string containing the usage information\n// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no\n// wrapping)\nfunc (f *FlagSet) FlagUsagesWrapped(cols int) string {\n\tbuf := new(bytes.Buffer)\n\n\tlines := make([]string, 0, len(f.formal))\n\n\tmaxlen := 0\n\tf.VisitAll(func(flag *Flag) {\n\t\tif flag.Hidden {\n\t\t\treturn\n\t\t}\n\n\t\tline := \"\"\n\t\tif flag.Shorthand != \"\" && flag.ShorthandDeprecated == \"\" {\n\t\t\tline = fmt.Sprintf(\"  -%s, --%s\", flag.Shorthand, flag.Name)\n\t\t} else {\n\t\t\tline = fmt.Sprintf(\"      --%s\", flag.Name)\n\t\t}\n\n\t\tvarname, usage := UnquoteUsage(flag)\n\t\tif varname != \"\" {\n\t\t\tline += \" \" + varname\n\t\t}\n\t\tif flag.NoOptDefVal != \"\" {\n\t\t\tswitch flag.Value.Type() {\n\t\t\tcase \"string\":\n\t\t\t\tline += fmt.Sprintf(\"[=\\\"%s\\\"]\", flag.NoOptDefVal)\n\t\t\tcase \"bool\":\n\t\t\t\tif flag.NoOptDefVal != \"true\" {\n\t\t\t\t\tline += fmt.Sprintf(\"[=%s]\", flag.NoOptDefVal)\n\t\t\t\t}\n\t\t\tcase \"count\":\n\t\t\t\tif flag.NoOptDefVal != \"+1\" {\n\t\t\t\t\tline += fmt.Sprintf(\"[=%s]\", flag.NoOptDefVal)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tline += fmt.Sprintf(\"[=%s]\", flag.NoOptDefVal)\n\t\t\t}\n\t\t}\n\n\t\t// This special character will be replaced with spacing once the\n\t\t// correct alignment is calculated\n\t\tline += \"\\x00\"\n\t\tif len(line) > maxlen {\n\t\t\tmaxlen = len(line)\n\t\t}\n\n\t\tline += usage\n\t\tif !flag.defaultIsZeroValue() {\n\t\t\tif flag.Value.Type() == \"string\" {\n\t\t\t\tline += fmt.Sprintf(\" (default %q)\", flag.DefValue)\n\t\t\t} else {\n\t\t\t\tline += fmt.Sprintf(\" (default %s)\", flag.DefValue)\n\t\t\t}\n\t\t}\n\t\tif len(flag.Deprecated) != 0 {\n\t\t\tline += fmt.Sprintf(\" (DEPRECATED: %s)\", flag.Deprecated)\n\t\t}\n\n\t\tlines = append(lines, line)\n\t})\n\n\tfor _, line := range lines {\n\t\tsidx := strings.Index(line, \"\\x00\")\n\t\tspacing := strings.Repeat(\" \", maxlen-sidx)\n\t\t// maxlen + 2 comes from + 1 for the \\x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx\n\t\tfmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))\n\t}\n\n\treturn buf.String()\n}\n\n// FlagUsages returns a string containing the usage information for all flags in\n// the FlagSet\nfunc (f *FlagSet) FlagUsages() string {\n\treturn f.FlagUsagesWrapped(0)\n}\n\n// PrintDefaults prints to standard error the default values of all defined command-line flags.\nfunc PrintDefaults() {\n\tCommandLine.PrintDefaults()\n}\n\n// defaultUsage is the default function to print a usage message.\nfunc defaultUsage(f *FlagSet) {\n\tfmt.Fprintf(f.out(), \"Usage of %s:\\n\", f.name)\n\tf.PrintDefaults()\n}\n\n// NOTE: Usage is not just defaultUsage(CommandLine)\n// because it serves (via godoc flag Usage) as the example\n// for how to write your own usage function.\n\n// Usage prints to standard error a usage message documenting all defined command-line flags.\n// The function is a variable that may be changed to point to a custom function.\n// By default it prints a simple header and calls PrintDefaults; for details about the\n// format of the output and how to control it, see the documentation for PrintDefaults.\nvar Usage = func() {\n\tfmt.Fprintf(os.Stderr, \"Usage of %s:\\n\", os.Args[0])\n\tPrintDefaults()\n}\n\n// NFlag returns the number of flags that have been set.\nfunc (f *FlagSet) NFlag() int { return len(f.actual) }\n\n// NFlag returns the number of command-line flags that have been set.\nfunc NFlag() int { return len(CommandLine.actual) }\n\n// Arg returns the i'th argument.  Arg(0) is the first remaining argument\n// after flags have been processed.\nfunc (f *FlagSet) Arg(i int) string {\n\tif i < 0 || i >= len(f.args) {\n\t\treturn \"\"\n\t}\n\treturn f.args[i]\n}\n\n// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument\n// after flags have been processed.\nfunc Arg(i int) string {\n\treturn CommandLine.Arg(i)\n}\n\n// NArg is the number of arguments remaining after flags have been processed.\nfunc (f *FlagSet) NArg() int { return len(f.args) }\n\n// NArg is the number of arguments remaining after flags have been processed.\nfunc NArg() int { return len(CommandLine.args) }\n\n// Args returns the non-flag arguments.\nfunc (f *FlagSet) Args() []string { return f.args }\n\n// Args returns the non-flag command-line arguments.\nfunc Args() []string { return CommandLine.args }\n\n// Var defines a flag with the specified name and usage string. The type and\n// value of the flag are represented by the first argument, of type Value, which\n// typically holds a user-defined implementation of Value. For instance, the\n// caller could create a flag that turns a comma-separated string into a slice\n// of strings by giving the slice the methods of Value; in particular, Set would\n// decompose the comma-separated string into the slice.\nfunc (f *FlagSet) Var(value Value, name string, usage string) {\n\tf.VarP(value, name, \"\", usage)\n}\n\n// VarPF is like VarP, but returns the flag created\nfunc (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {\n\t// Remember the default value as a string; it won't change.\n\tflag := &Flag{\n\t\tName:      name,\n\t\tShorthand: shorthand,\n\t\tUsage:     usage,\n\t\tValue:     value,\n\t\tDefValue:  value.String(),\n\t}\n\tf.AddFlag(flag)\n\treturn flag\n}\n\n// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) VarP(value Value, name, shorthand, usage string) {\n\tf.VarPF(value, name, shorthand, usage)\n}\n\n// AddFlag will add the flag to the FlagSet\nfunc (f *FlagSet) AddFlag(flag *Flag) {\n\tnormalizedFlagName := f.normalizeFlagName(flag.Name)\n\n\t_, alreadyThere := f.formal[normalizedFlagName]\n\tif alreadyThere {\n\t\tmsg := fmt.Sprintf(\"%s flag redefined: %s\", f.name, flag.Name)\n\t\tfmt.Fprintln(f.out(), msg)\n\t\tpanic(msg) // Happens only if flags are declared with identical names\n\t}\n\tif f.formal == nil {\n\t\tf.formal = make(map[NormalizedName]*Flag)\n\t}\n\n\tflag.Name = string(normalizedFlagName)\n\tf.formal[normalizedFlagName] = flag\n\tf.orderedFormal = append(f.orderedFormal, flag)\n\n\tif flag.Shorthand == \"\" {\n\t\treturn\n\t}\n\tif len(flag.Shorthand) > 1 {\n\t\tmsg := fmt.Sprintf(\"%q shorthand is more than one ASCII character\", flag.Shorthand)\n\t\tfmt.Fprintf(f.out(), msg)\n\t\tpanic(msg)\n\t}\n\tif f.shorthands == nil {\n\t\tf.shorthands = make(map[byte]*Flag)\n\t}\n\tc := flag.Shorthand[0]\n\tused, alreadyThere := f.shorthands[c]\n\tif alreadyThere {\n\t\tmsg := fmt.Sprintf(\"unable to redefine %q shorthand in %q flagset: it's already used for %q flag\", c, f.name, used.Name)\n\t\tfmt.Fprintf(f.out(), msg)\n\t\tpanic(msg)\n\t}\n\tf.shorthands[c] = flag\n}\n\n// AddFlagSet adds one FlagSet to another. If a flag is already present in f\n// the flag from newSet will be ignored.\nfunc (f *FlagSet) AddFlagSet(newSet *FlagSet) {\n\tif newSet == nil {\n\t\treturn\n\t}\n\tnewSet.VisitAll(func(flag *Flag) {\n\t\tif f.Lookup(flag.Name) == nil {\n\t\t\tf.AddFlag(flag)\n\t\t}\n\t})\n}\n\n// Var defines a flag with the specified name and usage string. The type and\n// value of the flag are represented by the first argument, of type Value, which\n// typically holds a user-defined implementation of Value. For instance, the\n// caller could create a flag that turns a comma-separated string into a slice\n// of strings by giving the slice the methods of Value; in particular, Set would\n// decompose the comma-separated string into the slice.\nfunc Var(value Value, name string, usage string) {\n\tCommandLine.VarP(value, name, \"\", usage)\n}\n\n// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.\nfunc VarP(value Value, name, shorthand, usage string) {\n\tCommandLine.VarP(value, name, shorthand, usage)\n}\n\n// failf prints to standard error a formatted error and usage message and\n// returns the error.\nfunc (f *FlagSet) failf(format string, a ...interface{}) error {\n\terr := fmt.Errorf(format, a...)\n\tif f.errorHandling != ContinueOnError {\n\t\tfmt.Fprintln(f.out(), err)\n\t\tf.usage()\n\t}\n\treturn err\n}\n\n// usage calls the Usage method for the flag set, or the usage function if\n// the flag set is CommandLine.\nfunc (f *FlagSet) usage() {\n\tif f == CommandLine {\n\t\tUsage()\n\t} else if f.Usage == nil {\n\t\tdefaultUsage(f)\n\t} else {\n\t\tf.Usage()\n\t}\n}\n\n//--unknown (args will be empty)\n//--unknown --next-flag ... (args will be --next-flag ...)\n//--unknown arg ... (args will be arg ...)\nfunc stripUnknownFlagValue(args []string) []string {\n\tif len(args) == 0 {\n\t\t//--unknown\n\t\treturn args\n\t}\n\n\tfirst := args[0]\n\tif len(first) > 0 && first[0] == '-' {\n\t\t//--unknown --next-flag ...\n\t\treturn args\n\t}\n\n\t//--unknown arg ... (args will be arg ...)\n\tif len(args) > 1 {\n\t\treturn args[1:]\n\t}\n\treturn nil\n}\n\nfunc (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {\n\ta = args\n\tname := s[2:]\n\tif len(name) == 0 || name[0] == '-' || name[0] == '=' {\n\t\terr = f.failf(\"bad flag syntax: %s\", s)\n\t\treturn\n\t}\n\n\tsplit := strings.SplitN(name, \"=\", 2)\n\tname = split[0]\n\tflag, exists := f.formal[f.normalizeFlagName(name)]\n\n\tif !exists {\n\t\tswitch {\n\t\tcase name == \"help\":\n\t\t\tf.usage()\n\t\t\treturn a, ErrHelp\n\t\tcase f.ParseErrorsWhitelist.UnknownFlags:\n\t\t\t// --unknown=unknownval arg ...\n\t\t\t// we do not want to lose arg in this case\n\t\t\tif len(split) >= 2 {\n\t\t\t\treturn a, nil\n\t\t\t}\n\n\t\t\treturn stripUnknownFlagValue(a), nil\n\t\tdefault:\n\t\t\terr = f.failf(\"unknown flag: --%s\", name)\n\t\t\treturn\n\t\t}\n\t}\n\n\tvar value string\n\tif len(split) == 2 {\n\t\t// '--flag=arg'\n\t\tvalue = split[1]\n\t} else if flag.NoOptDefVal != \"\" {\n\t\t// '--flag' (arg was optional)\n\t\tvalue = flag.NoOptDefVal\n\t} else if len(a) > 0 {\n\t\t// '--flag arg'\n\t\tvalue = a[0]\n\t\ta = a[1:]\n\t} else {\n\t\t// '--flag' (arg was required)\n\t\terr = f.failf(\"flag needs an argument: %s\", s)\n\t\treturn\n\t}\n\n\terr = fn(flag, value)\n\tif err != nil {\n\t\tf.failf(err.Error())\n\t}\n\treturn\n}\n\nfunc (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {\n\toutArgs = args\n\n\tif strings.HasPrefix(shorthands, \"test.\") {\n\t\treturn\n\t}\n\n\toutShorts = shorthands[1:]\n\tc := shorthands[0]\n\n\tflag, exists := f.shorthands[c]\n\tif !exists {\n\t\tswitch {\n\t\tcase c == 'h':\n\t\t\tf.usage()\n\t\t\terr = ErrHelp\n\t\t\treturn\n\t\tcase f.ParseErrorsWhitelist.UnknownFlags:\n\t\t\t// '-f=arg arg ...'\n\t\t\t// we do not want to lose arg in this case\n\t\t\tif len(shorthands) > 2 && shorthands[1] == '=' {\n\t\t\t\toutShorts = \"\"\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\toutArgs = stripUnknownFlagValue(outArgs)\n\t\t\treturn\n\t\tdefault:\n\t\t\terr = f.failf(\"unknown shorthand flag: %q in -%s\", c, shorthands)\n\t\t\treturn\n\t\t}\n\t}\n\n\tvar value string\n\tif len(shorthands) > 2 && shorthands[1] == '=' {\n\t\t// '-f=arg'\n\t\tvalue = shorthands[2:]\n\t\toutShorts = \"\"\n\t} else if flag.NoOptDefVal != \"\" {\n\t\t// '-f' (arg was optional)\n\t\tvalue = flag.NoOptDefVal\n\t} else if len(shorthands) > 1 {\n\t\t// '-farg'\n\t\tvalue = shorthands[1:]\n\t\toutShorts = \"\"\n\t} else if len(args) > 0 {\n\t\t// '-f arg'\n\t\tvalue = args[0]\n\t\toutArgs = args[1:]\n\t} else {\n\t\t// '-f' (arg was required)\n\t\terr = f.failf(\"flag needs an argument: %q in -%s\", c, shorthands)\n\t\treturn\n\t}\n\n\tif flag.ShorthandDeprecated != \"\" {\n\t\tfmt.Fprintf(f.out(), \"Flag shorthand -%s has been deprecated, %s\\n\", flag.Shorthand, flag.ShorthandDeprecated)\n\t}\n\n\terr = fn(flag, value)\n\tif err != nil {\n\t\tf.failf(err.Error())\n\t}\n\treturn\n}\n\nfunc (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {\n\ta = args\n\tshorthands := s[1:]\n\n\t// \"shorthands\" can be a series of shorthand letters of flags (e.g. \"-vvv\").\n\tfor len(shorthands) > 0 {\n\t\tshorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {\n\tfor len(args) > 0 {\n\t\ts := args[0]\n\t\targs = args[1:]\n\t\tif len(s) == 0 || s[0] != '-' || len(s) == 1 {\n\t\t\tif !f.interspersed {\n\t\t\t\tf.args = append(f.args, s)\n\t\t\t\tf.args = append(f.args, args...)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tf.args = append(f.args, s)\n\t\t\tcontinue\n\t\t}\n\n\t\tif s[1] == '-' {\n\t\t\tif len(s) == 2 { // \"--\" terminates the flags\n\t\t\t\tf.argsLenAtDash = len(f.args)\n\t\t\t\tf.args = append(f.args, args...)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\targs, err = f.parseLongArg(s, args, fn)\n\t\t} else {\n\t\t\targs, err = f.parseShortArg(s, args, fn)\n\t\t}\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\treturn\n}\n\n// Parse parses flag definitions from the argument list, which should not\n// include the command name.  Must be called after all flags in the FlagSet\n// are defined and before flags are accessed by the program.\n// The return value will be ErrHelp if -help was set but not defined.\nfunc (f *FlagSet) Parse(arguments []string) error {\n\tif f.addedGoFlagSets != nil {\n\t\tfor _, goFlagSet := range f.addedGoFlagSets {\n\t\t\tgoFlagSet.Parse(nil)\n\t\t}\n\t}\n\tf.parsed = true\n\n\tif len(arguments) < 0 {\n\t\treturn nil\n\t}\n\n\tf.args = make([]string, 0, len(arguments))\n\n\tset := func(flag *Flag, value string) error {\n\t\treturn f.Set(flag.Name, value)\n\t}\n\n\terr := f.parseArgs(arguments, set)\n\tif err != nil {\n\t\tswitch f.errorHandling {\n\t\tcase ContinueOnError:\n\t\t\treturn err\n\t\tcase ExitOnError:\n\t\t\tfmt.Println(err)\n\t\t\tos.Exit(2)\n\t\tcase PanicOnError:\n\t\t\tpanic(err)\n\t\t}\n\t}\n\treturn nil\n}\n\ntype parseFunc func(flag *Flag, value string) error\n\n// ParseAll parses flag definitions from the argument list, which should not\n// include the command name. The arguments for fn are flag and value. Must be\n// called after all flags in the FlagSet are defined and before flags are\n// accessed by the program. The return value will be ErrHelp if -help was set\n// but not defined.\nfunc (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {\n\tf.parsed = true\n\tf.args = make([]string, 0, len(arguments))\n\n\terr := f.parseArgs(arguments, fn)\n\tif err != nil {\n\t\tswitch f.errorHandling {\n\t\tcase ContinueOnError:\n\t\t\treturn err\n\t\tcase ExitOnError:\n\t\t\tos.Exit(2)\n\t\tcase PanicOnError:\n\t\t\tpanic(err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// Parsed reports whether f.Parse has been called.\nfunc (f *FlagSet) Parsed() bool {\n\treturn f.parsed\n}\n\n// Parse parses the command-line flags from os.Args[1:].  Must be called\n// after all flags are defined and before flags are accessed by the program.\nfunc Parse() {\n\t// Ignore errors; CommandLine is set for ExitOnError.\n\tCommandLine.Parse(os.Args[1:])\n}\n\n// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.\n// The arguments for fn are flag and value. Must be called after all flags are\n// defined and before flags are accessed by the program.\nfunc ParseAll(fn func(flag *Flag, value string) error) {\n\t// Ignore errors; CommandLine is set for ExitOnError.\n\tCommandLine.ParseAll(os.Args[1:], fn)\n}\n\n// SetInterspersed sets whether to support interspersed option/non-option arguments.\nfunc SetInterspersed(interspersed bool) {\n\tCommandLine.SetInterspersed(interspersed)\n}\n\n// Parsed returns true if the command-line flags have been parsed.\nfunc Parsed() bool {\n\treturn CommandLine.Parsed()\n}\n\n// CommandLine is the default set of command-line flags, parsed from os.Args.\nvar CommandLine = NewFlagSet(os.Args[0], ExitOnError)\n\n// NewFlagSet returns a new, empty flag set with the specified name,\n// error handling property and SortFlags set to true.\nfunc NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {\n\tf := &FlagSet{\n\t\tname:          name,\n\t\terrorHandling: errorHandling,\n\t\targsLenAtDash: -1,\n\t\tinterspersed:  true,\n\t\tSortFlags:     true,\n\t}\n\treturn f\n}\n\n// SetInterspersed sets whether to support interspersed option/non-option arguments.\nfunc (f *FlagSet) SetInterspersed(interspersed bool) {\n\tf.interspersed = interspersed\n}\n\n// Init sets the name and error handling property for a flag set.\n// By default, the zero FlagSet uses an empty name and the\n// ContinueOnError error handling policy.\nfunc (f *FlagSet) Init(name string, errorHandling ErrorHandling) {\n\tf.name = name\n\tf.errorHandling = errorHandling\n\tf.argsLenAtDash = -1\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/float32.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- float32 Value\ntype float32Value float32\n\nfunc newFloat32Value(val float32, p *float32) *float32Value {\n\t*p = val\n\treturn (*float32Value)(p)\n}\n\nfunc (f *float32Value) Set(s string) error {\n\tv, err := strconv.ParseFloat(s, 32)\n\t*f = float32Value(v)\n\treturn err\n}\n\nfunc (f *float32Value) Type() string {\n\treturn \"float32\"\n}\n\nfunc (f *float32Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 32) }\n\nfunc float32Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseFloat(sval, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn float32(v), nil\n}\n\n// GetFloat32 return the float32 value of a flag with the given name\nfunc (f *FlagSet) GetFloat32(name string) (float32, error) {\n\tval, err := f.getFlagType(name, \"float32\", float32Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(float32), nil\n}\n\n// Float32Var defines a float32 flag with specified name, default value, and usage string.\n// The argument p points to a float32 variable in which to store the value of the flag.\nfunc (f *FlagSet) Float32Var(p *float32, name string, value float32, usage string) {\n\tf.VarP(newFloat32Value(value, p), name, \"\", usage)\n}\n\n// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float32VarP(p *float32, name, shorthand string, value float32, usage string) {\n\tf.VarP(newFloat32Value(value, p), name, shorthand, usage)\n}\n\n// Float32Var defines a float32 flag with specified name, default value, and usage string.\n// The argument p points to a float32 variable in which to store the value of the flag.\nfunc Float32Var(p *float32, name string, value float32, usage string) {\n\tCommandLine.VarP(newFloat32Value(value, p), name, \"\", usage)\n}\n\n// Float32VarP is like Float32Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Float32VarP(p *float32, name, shorthand string, value float32, usage string) {\n\tCommandLine.VarP(newFloat32Value(value, p), name, shorthand, usage)\n}\n\n// Float32 defines a float32 flag with specified name, default value, and usage string.\n// The return value is the address of a float32 variable that stores the value of the flag.\nfunc (f *FlagSet) Float32(name string, value float32, usage string) *float32 {\n\tp := new(float32)\n\tf.Float32VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float32P(name, shorthand string, value float32, usage string) *float32 {\n\tp := new(float32)\n\tf.Float32VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Float32 defines a float32 flag with specified name, default value, and usage string.\n// The return value is the address of a float32 variable that stores the value of the flag.\nfunc Float32(name string, value float32, usage string) *float32 {\n\treturn CommandLine.Float32P(name, \"\", value, usage)\n}\n\n// Float32P is like Float32, but accepts a shorthand letter that can be used after a single dash.\nfunc Float32P(name, shorthand string, value float32, usage string) *float32 {\n\treturn CommandLine.Float32P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/float32_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- float32Slice Value\ntype float32SliceValue struct {\n\tvalue   *[]float32\n\tchanged bool\n}\n\nfunc newFloat32SliceValue(val []float32, p *[]float32) *float32SliceValue {\n\tisv := new(float32SliceValue)\n\tisv.value = p\n\t*isv.value = val\n\treturn isv\n}\n\nfunc (s *float32SliceValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make([]float32, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tvar temp64 float64\n\t\ttemp64, err = strconv.ParseFloat(d, 32)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tout[i] = float32(temp64)\n\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *float32SliceValue) Type() string {\n\treturn \"float32Slice\"\n}\n\nfunc (s *float32SliceValue) String() string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = fmt.Sprintf(\"%f\", d)\n\t}\n\treturn \"[\" + strings.Join(out, \",\") + \"]\"\n}\n\nfunc (s *float32SliceValue) fromString(val string) (float32, error) {\n\tt64, err := strconv.ParseFloat(val, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn float32(t64), nil\n}\n\nfunc (s *float32SliceValue) toString(val float32) string {\n\treturn fmt.Sprintf(\"%f\", val)\n}\n\nfunc (s *float32SliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *float32SliceValue) Replace(val []string) error {\n\tout := make([]float32, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *float32SliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc float32SliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []float32{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]float32, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tvar temp64 float64\n\t\ttemp64, err = strconv.ParseFloat(d, 32)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tout[i] = float32(temp64)\n\n\t}\n\treturn out, nil\n}\n\n// GetFloat32Slice return the []float32 value of a flag with the given name\nfunc (f *FlagSet) GetFloat32Slice(name string) ([]float32, error) {\n\tval, err := f.getFlagType(name, \"float32Slice\", float32SliceConv)\n\tif err != nil {\n\t\treturn []float32{}, err\n\t}\n\treturn val.([]float32), nil\n}\n\n// Float32SliceVar defines a float32Slice flag with specified name, default value, and usage string.\n// The argument p points to a []float32 variable in which to store the value of the flag.\nfunc (f *FlagSet) Float32SliceVar(p *[]float32, name string, value []float32, usage string) {\n\tf.VarP(newFloat32SliceValue(value, p), name, \"\", usage)\n}\n\n// Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) {\n\tf.VarP(newFloat32SliceValue(value, p), name, shorthand, usage)\n}\n\n// Float32SliceVar defines a float32[] flag with specified name, default value, and usage string.\n// The argument p points to a float32[] variable in which to store the value of the flag.\nfunc Float32SliceVar(p *[]float32, name string, value []float32, usage string) {\n\tCommandLine.VarP(newFloat32SliceValue(value, p), name, \"\", usage)\n}\n\n// Float32SliceVarP is like Float32SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc Float32SliceVarP(p *[]float32, name, shorthand string, value []float32, usage string) {\n\tCommandLine.VarP(newFloat32SliceValue(value, p), name, shorthand, usage)\n}\n\n// Float32Slice defines a []float32 flag with specified name, default value, and usage string.\n// The return value is the address of a []float32 variable that stores the value of the flag.\nfunc (f *FlagSet) Float32Slice(name string, value []float32, usage string) *[]float32 {\n\tp := []float32{}\n\tf.Float32SliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 {\n\tp := []float32{}\n\tf.Float32SliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// Float32Slice defines a []float32 flag with specified name, default value, and usage string.\n// The return value is the address of a []float32 variable that stores the value of the flag.\nfunc Float32Slice(name string, value []float32, usage string) *[]float32 {\n\treturn CommandLine.Float32SliceP(name, \"\", value, usage)\n}\n\n// Float32SliceP is like Float32Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc Float32SliceP(name, shorthand string, value []float32, usage string) *[]float32 {\n\treturn CommandLine.Float32SliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/float64.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- float64 Value\ntype float64Value float64\n\nfunc newFloat64Value(val float64, p *float64) *float64Value {\n\t*p = val\n\treturn (*float64Value)(p)\n}\n\nfunc (f *float64Value) Set(s string) error {\n\tv, err := strconv.ParseFloat(s, 64)\n\t*f = float64Value(v)\n\treturn err\n}\n\nfunc (f *float64Value) Type() string {\n\treturn \"float64\"\n}\n\nfunc (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }\n\nfunc float64Conv(sval string) (interface{}, error) {\n\treturn strconv.ParseFloat(sval, 64)\n}\n\n// GetFloat64 return the float64 value of a flag with the given name\nfunc (f *FlagSet) GetFloat64(name string) (float64, error) {\n\tval, err := f.getFlagType(name, \"float64\", float64Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(float64), nil\n}\n\n// Float64Var defines a float64 flag with specified name, default value, and usage string.\n// The argument p points to a float64 variable in which to store the value of the flag.\nfunc (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {\n\tf.VarP(newFloat64Value(value, p), name, \"\", usage)\n}\n\n// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float64VarP(p *float64, name, shorthand string, value float64, usage string) {\n\tf.VarP(newFloat64Value(value, p), name, shorthand, usage)\n}\n\n// Float64Var defines a float64 flag with specified name, default value, and usage string.\n// The argument p points to a float64 variable in which to store the value of the flag.\nfunc Float64Var(p *float64, name string, value float64, usage string) {\n\tCommandLine.VarP(newFloat64Value(value, p), name, \"\", usage)\n}\n\n// Float64VarP is like Float64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Float64VarP(p *float64, name, shorthand string, value float64, usage string) {\n\tCommandLine.VarP(newFloat64Value(value, p), name, shorthand, usage)\n}\n\n// Float64 defines a float64 flag with specified name, default value, and usage string.\n// The return value is the address of a float64 variable that stores the value of the flag.\nfunc (f *FlagSet) Float64(name string, value float64, usage string) *float64 {\n\tp := new(float64)\n\tf.Float64VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float64P(name, shorthand string, value float64, usage string) *float64 {\n\tp := new(float64)\n\tf.Float64VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Float64 defines a float64 flag with specified name, default value, and usage string.\n// The return value is the address of a float64 variable that stores the value of the flag.\nfunc Float64(name string, value float64, usage string) *float64 {\n\treturn CommandLine.Float64P(name, \"\", value, usage)\n}\n\n// Float64P is like Float64, but accepts a shorthand letter that can be used after a single dash.\nfunc Float64P(name, shorthand string, value float64, usage string) *float64 {\n\treturn CommandLine.Float64P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/float64_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- float64Slice Value\ntype float64SliceValue struct {\n\tvalue   *[]float64\n\tchanged bool\n}\n\nfunc newFloat64SliceValue(val []float64, p *[]float64) *float64SliceValue {\n\tisv := new(float64SliceValue)\n\tisv.value = p\n\t*isv.value = val\n\treturn isv\n}\n\nfunc (s *float64SliceValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make([]float64, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = strconv.ParseFloat(d, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *float64SliceValue) Type() string {\n\treturn \"float64Slice\"\n}\n\nfunc (s *float64SliceValue) String() string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = fmt.Sprintf(\"%f\", d)\n\t}\n\treturn \"[\" + strings.Join(out, \",\") + \"]\"\n}\n\nfunc (s *float64SliceValue) fromString(val string) (float64, error) {\n\treturn strconv.ParseFloat(val, 64)\n}\n\nfunc (s *float64SliceValue) toString(val float64) string {\n\treturn fmt.Sprintf(\"%f\", val)\n}\n\nfunc (s *float64SliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *float64SliceValue) Replace(val []string) error {\n\tout := make([]float64, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *float64SliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc float64SliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []float64{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]float64, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = strconv.ParseFloat(d, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t}\n\treturn out, nil\n}\n\n// GetFloat64Slice return the []float64 value of a flag with the given name\nfunc (f *FlagSet) GetFloat64Slice(name string) ([]float64, error) {\n\tval, err := f.getFlagType(name, \"float64Slice\", float64SliceConv)\n\tif err != nil {\n\t\treturn []float64{}, err\n\t}\n\treturn val.([]float64), nil\n}\n\n// Float64SliceVar defines a float64Slice flag with specified name, default value, and usage string.\n// The argument p points to a []float64 variable in which to store the value of the flag.\nfunc (f *FlagSet) Float64SliceVar(p *[]float64, name string, value []float64, usage string) {\n\tf.VarP(newFloat64SliceValue(value, p), name, \"\", usage)\n}\n\n// Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) {\n\tf.VarP(newFloat64SliceValue(value, p), name, shorthand, usage)\n}\n\n// Float64SliceVar defines a float64[] flag with specified name, default value, and usage string.\n// The argument p points to a float64[] variable in which to store the value of the flag.\nfunc Float64SliceVar(p *[]float64, name string, value []float64, usage string) {\n\tCommandLine.VarP(newFloat64SliceValue(value, p), name, \"\", usage)\n}\n\n// Float64SliceVarP is like Float64SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc Float64SliceVarP(p *[]float64, name, shorthand string, value []float64, usage string) {\n\tCommandLine.VarP(newFloat64SliceValue(value, p), name, shorthand, usage)\n}\n\n// Float64Slice defines a []float64 flag with specified name, default value, and usage string.\n// The return value is the address of a []float64 variable that stores the value of the flag.\nfunc (f *FlagSet) Float64Slice(name string, value []float64, usage string) *[]float64 {\n\tp := []float64{}\n\tf.Float64SliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 {\n\tp := []float64{}\n\tf.Float64SliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// Float64Slice defines a []float64 flag with specified name, default value, and usage string.\n// The return value is the address of a []float64 variable that stores the value of the flag.\nfunc Float64Slice(name string, value []float64, usage string) *[]float64 {\n\treturn CommandLine.Float64SliceP(name, \"\", value, usage)\n}\n\n// Float64SliceP is like Float64Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc Float64SliceP(name, shorthand string, value []float64, usage string) *[]float64 {\n\treturn CommandLine.Float64SliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/golangflag.go",
    "content": "// Copyright 2009 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 pflag\n\nimport (\n\tgoflag \"flag\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// flagValueWrapper implements pflag.Value around a flag.Value.  The main\n// difference here is the addition of the Type method that returns a string\n// name of the type.  As this is generally unknown, we approximate that with\n// reflection.\ntype flagValueWrapper struct {\n\tinner    goflag.Value\n\tflagType string\n}\n\n// We are just copying the boolFlag interface out of goflag as that is what\n// they use to decide if a flag should get \"true\" when no arg is given.\ntype goBoolFlag interface {\n\tgoflag.Value\n\tIsBoolFlag() bool\n}\n\nfunc wrapFlagValue(v goflag.Value) Value {\n\t// If the flag.Value happens to also be a pflag.Value, just use it directly.\n\tif pv, ok := v.(Value); ok {\n\t\treturn pv\n\t}\n\n\tpv := &flagValueWrapper{\n\t\tinner: v,\n\t}\n\n\tt := reflect.TypeOf(v)\n\tif t.Kind() == reflect.Interface || t.Kind() == reflect.Ptr {\n\t\tt = t.Elem()\n\t}\n\n\tpv.flagType = strings.TrimSuffix(t.Name(), \"Value\")\n\treturn pv\n}\n\nfunc (v *flagValueWrapper) String() string {\n\treturn v.inner.String()\n}\n\nfunc (v *flagValueWrapper) Set(s string) error {\n\treturn v.inner.Set(s)\n}\n\nfunc (v *flagValueWrapper) Type() string {\n\treturn v.flagType\n}\n\n// PFlagFromGoFlag will return a *pflag.Flag given a *flag.Flag\n// If the *flag.Flag.Name was a single character (ex: `v`) it will be accessiblei\n// with both `-v` and `--v` in flags. If the golang flag was more than a single\n// character (ex: `verbose`) it will only be accessible via `--verbose`\nfunc PFlagFromGoFlag(goflag *goflag.Flag) *Flag {\n\t// Remember the default value as a string; it won't change.\n\tflag := &Flag{\n\t\tName:  goflag.Name,\n\t\tUsage: goflag.Usage,\n\t\tValue: wrapFlagValue(goflag.Value),\n\t\t// Looks like golang flags don't set DefValue correctly  :-(\n\t\t//DefValue: goflag.DefValue,\n\t\tDefValue: goflag.Value.String(),\n\t}\n\t// Ex: if the golang flag was -v, allow both -v and --v to work\n\tif len(flag.Name) == 1 {\n\t\tflag.Shorthand = flag.Name\n\t}\n\tif fv, ok := goflag.Value.(goBoolFlag); ok && fv.IsBoolFlag() {\n\t\tflag.NoOptDefVal = \"true\"\n\t}\n\treturn flag\n}\n\n// AddGoFlag will add the given *flag.Flag to the pflag.FlagSet\nfunc (f *FlagSet) AddGoFlag(goflag *goflag.Flag) {\n\tif f.Lookup(goflag.Name) != nil {\n\t\treturn\n\t}\n\tnewflag := PFlagFromGoFlag(goflag)\n\tf.AddFlag(newflag)\n}\n\n// AddGoFlagSet will add the given *flag.FlagSet to the pflag.FlagSet\nfunc (f *FlagSet) AddGoFlagSet(newSet *goflag.FlagSet) {\n\tif newSet == nil {\n\t\treturn\n\t}\n\tnewSet.VisitAll(func(goflag *goflag.Flag) {\n\t\tf.AddGoFlag(goflag)\n\t})\n\tif f.addedGoFlagSets == nil {\n\t\tf.addedGoFlagSets = make([]*goflag.FlagSet, 0)\n\t}\n\tf.addedGoFlagSets = append(f.addedGoFlagSets, newSet)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- int Value\ntype intValue int\n\nfunc newIntValue(val int, p *int) *intValue {\n\t*p = val\n\treturn (*intValue)(p)\n}\n\nfunc (i *intValue) Set(s string) error {\n\tv, err := strconv.ParseInt(s, 0, 64)\n\t*i = intValue(v)\n\treturn err\n}\n\nfunc (i *intValue) Type() string {\n\treturn \"int\"\n}\n\nfunc (i *intValue) String() string { return strconv.Itoa(int(*i)) }\n\nfunc intConv(sval string) (interface{}, error) {\n\treturn strconv.Atoi(sval)\n}\n\n// GetInt return the int value of a flag with the given name\nfunc (f *FlagSet) GetInt(name string) (int, error) {\n\tval, err := f.getFlagType(name, \"int\", intConv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(int), nil\n}\n\n// IntVar defines an int flag with specified name, default value, and usage string.\n// The argument p points to an int variable in which to store the value of the flag.\nfunc (f *FlagSet) IntVar(p *int, name string, value int, usage string) {\n\tf.VarP(newIntValue(value, p), name, \"\", usage)\n}\n\n// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IntVarP(p *int, name, shorthand string, value int, usage string) {\n\tf.VarP(newIntValue(value, p), name, shorthand, usage)\n}\n\n// IntVar defines an int flag with specified name, default value, and usage string.\n// The argument p points to an int variable in which to store the value of the flag.\nfunc IntVar(p *int, name string, value int, usage string) {\n\tCommandLine.VarP(newIntValue(value, p), name, \"\", usage)\n}\n\n// IntVarP is like IntVar, but accepts a shorthand letter that can be used after a single dash.\nfunc IntVarP(p *int, name, shorthand string, value int, usage string) {\n\tCommandLine.VarP(newIntValue(value, p), name, shorthand, usage)\n}\n\n// Int defines an int flag with specified name, default value, and usage string.\n// The return value is the address of an int variable that stores the value of the flag.\nfunc (f *FlagSet) Int(name string, value int, usage string) *int {\n\tp := new(int)\n\tf.IntVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IntP(name, shorthand string, value int, usage string) *int {\n\tp := new(int)\n\tf.IntVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Int defines an int flag with specified name, default value, and usage string.\n// The return value is the address of an int variable that stores the value of the flag.\nfunc Int(name string, value int, usage string) *int {\n\treturn CommandLine.IntP(name, \"\", value, usage)\n}\n\n// IntP is like Int, but accepts a shorthand letter that can be used after a single dash.\nfunc IntP(name, shorthand string, value int, usage string) *int {\n\treturn CommandLine.IntP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int16.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- int16 Value\ntype int16Value int16\n\nfunc newInt16Value(val int16, p *int16) *int16Value {\n\t*p = val\n\treturn (*int16Value)(p)\n}\n\nfunc (i *int16Value) Set(s string) error {\n\tv, err := strconv.ParseInt(s, 0, 16)\n\t*i = int16Value(v)\n\treturn err\n}\n\nfunc (i *int16Value) Type() string {\n\treturn \"int16\"\n}\n\nfunc (i *int16Value) String() string { return strconv.FormatInt(int64(*i), 10) }\n\nfunc int16Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseInt(sval, 0, 16)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn int16(v), nil\n}\n\n// GetInt16 returns the int16 value of a flag with the given name\nfunc (f *FlagSet) GetInt16(name string) (int16, error) {\n\tval, err := f.getFlagType(name, \"int16\", int16Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(int16), nil\n}\n\n// Int16Var defines an int16 flag with specified name, default value, and usage string.\n// The argument p points to an int16 variable in which to store the value of the flag.\nfunc (f *FlagSet) Int16Var(p *int16, name string, value int16, usage string) {\n\tf.VarP(newInt16Value(value, p), name, \"\", usage)\n}\n\n// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int16VarP(p *int16, name, shorthand string, value int16, usage string) {\n\tf.VarP(newInt16Value(value, p), name, shorthand, usage)\n}\n\n// Int16Var defines an int16 flag with specified name, default value, and usage string.\n// The argument p points to an int16 variable in which to store the value of the flag.\nfunc Int16Var(p *int16, name string, value int16, usage string) {\n\tCommandLine.VarP(newInt16Value(value, p), name, \"\", usage)\n}\n\n// Int16VarP is like Int16Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Int16VarP(p *int16, name, shorthand string, value int16, usage string) {\n\tCommandLine.VarP(newInt16Value(value, p), name, shorthand, usage)\n}\n\n// Int16 defines an int16 flag with specified name, default value, and usage string.\n// The return value is the address of an int16 variable that stores the value of the flag.\nfunc (f *FlagSet) Int16(name string, value int16, usage string) *int16 {\n\tp := new(int16)\n\tf.Int16VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int16P(name, shorthand string, value int16, usage string) *int16 {\n\tp := new(int16)\n\tf.Int16VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Int16 defines an int16 flag with specified name, default value, and usage string.\n// The return value is the address of an int16 variable that stores the value of the flag.\nfunc Int16(name string, value int16, usage string) *int16 {\n\treturn CommandLine.Int16P(name, \"\", value, usage)\n}\n\n// Int16P is like Int16, but accepts a shorthand letter that can be used after a single dash.\nfunc Int16P(name, shorthand string, value int16, usage string) *int16 {\n\treturn CommandLine.Int16P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int32.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- int32 Value\ntype int32Value int32\n\nfunc newInt32Value(val int32, p *int32) *int32Value {\n\t*p = val\n\treturn (*int32Value)(p)\n}\n\nfunc (i *int32Value) Set(s string) error {\n\tv, err := strconv.ParseInt(s, 0, 32)\n\t*i = int32Value(v)\n\treturn err\n}\n\nfunc (i *int32Value) Type() string {\n\treturn \"int32\"\n}\n\nfunc (i *int32Value) String() string { return strconv.FormatInt(int64(*i), 10) }\n\nfunc int32Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseInt(sval, 0, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn int32(v), nil\n}\n\n// GetInt32 return the int32 value of a flag with the given name\nfunc (f *FlagSet) GetInt32(name string) (int32, error) {\n\tval, err := f.getFlagType(name, \"int32\", int32Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(int32), nil\n}\n\n// Int32Var defines an int32 flag with specified name, default value, and usage string.\n// The argument p points to an int32 variable in which to store the value of the flag.\nfunc (f *FlagSet) Int32Var(p *int32, name string, value int32, usage string) {\n\tf.VarP(newInt32Value(value, p), name, \"\", usage)\n}\n\n// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int32VarP(p *int32, name, shorthand string, value int32, usage string) {\n\tf.VarP(newInt32Value(value, p), name, shorthand, usage)\n}\n\n// Int32Var defines an int32 flag with specified name, default value, and usage string.\n// The argument p points to an int32 variable in which to store the value of the flag.\nfunc Int32Var(p *int32, name string, value int32, usage string) {\n\tCommandLine.VarP(newInt32Value(value, p), name, \"\", usage)\n}\n\n// Int32VarP is like Int32Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Int32VarP(p *int32, name, shorthand string, value int32, usage string) {\n\tCommandLine.VarP(newInt32Value(value, p), name, shorthand, usage)\n}\n\n// Int32 defines an int32 flag with specified name, default value, and usage string.\n// The return value is the address of an int32 variable that stores the value of the flag.\nfunc (f *FlagSet) Int32(name string, value int32, usage string) *int32 {\n\tp := new(int32)\n\tf.Int32VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int32P(name, shorthand string, value int32, usage string) *int32 {\n\tp := new(int32)\n\tf.Int32VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Int32 defines an int32 flag with specified name, default value, and usage string.\n// The return value is the address of an int32 variable that stores the value of the flag.\nfunc Int32(name string, value int32, usage string) *int32 {\n\treturn CommandLine.Int32P(name, \"\", value, usage)\n}\n\n// Int32P is like Int32, but accepts a shorthand letter that can be used after a single dash.\nfunc Int32P(name, shorthand string, value int32, usage string) *int32 {\n\treturn CommandLine.Int32P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int32_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- int32Slice Value\ntype int32SliceValue struct {\n\tvalue   *[]int32\n\tchanged bool\n}\n\nfunc newInt32SliceValue(val []int32, p *[]int32) *int32SliceValue {\n\tisv := new(int32SliceValue)\n\tisv.value = p\n\t*isv.value = val\n\treturn isv\n}\n\nfunc (s *int32SliceValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make([]int32, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tvar temp64 int64\n\t\ttemp64, err = strconv.ParseInt(d, 0, 32)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tout[i] = int32(temp64)\n\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *int32SliceValue) Type() string {\n\treturn \"int32Slice\"\n}\n\nfunc (s *int32SliceValue) String() string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = fmt.Sprintf(\"%d\", d)\n\t}\n\treturn \"[\" + strings.Join(out, \",\") + \"]\"\n}\n\nfunc (s *int32SliceValue) fromString(val string) (int32, error) {\n\tt64, err := strconv.ParseInt(val, 0, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn int32(t64), nil\n}\n\nfunc (s *int32SliceValue) toString(val int32) string {\n\treturn fmt.Sprintf(\"%d\", val)\n}\n\nfunc (s *int32SliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *int32SliceValue) Replace(val []string) error {\n\tout := make([]int32, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *int32SliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc int32SliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []int32{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]int32, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tvar temp64 int64\n\t\ttemp64, err = strconv.ParseInt(d, 0, 32)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tout[i] = int32(temp64)\n\n\t}\n\treturn out, nil\n}\n\n// GetInt32Slice return the []int32 value of a flag with the given name\nfunc (f *FlagSet) GetInt32Slice(name string) ([]int32, error) {\n\tval, err := f.getFlagType(name, \"int32Slice\", int32SliceConv)\n\tif err != nil {\n\t\treturn []int32{}, err\n\t}\n\treturn val.([]int32), nil\n}\n\n// Int32SliceVar defines a int32Slice flag with specified name, default value, and usage string.\n// The argument p points to a []int32 variable in which to store the value of the flag.\nfunc (f *FlagSet) Int32SliceVar(p *[]int32, name string, value []int32, usage string) {\n\tf.VarP(newInt32SliceValue(value, p), name, \"\", usage)\n}\n\n// Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) {\n\tf.VarP(newInt32SliceValue(value, p), name, shorthand, usage)\n}\n\n// Int32SliceVar defines a int32[] flag with specified name, default value, and usage string.\n// The argument p points to a int32[] variable in which to store the value of the flag.\nfunc Int32SliceVar(p *[]int32, name string, value []int32, usage string) {\n\tCommandLine.VarP(newInt32SliceValue(value, p), name, \"\", usage)\n}\n\n// Int32SliceVarP is like Int32SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc Int32SliceVarP(p *[]int32, name, shorthand string, value []int32, usage string) {\n\tCommandLine.VarP(newInt32SliceValue(value, p), name, shorthand, usage)\n}\n\n// Int32Slice defines a []int32 flag with specified name, default value, and usage string.\n// The return value is the address of a []int32 variable that stores the value of the flag.\nfunc (f *FlagSet) Int32Slice(name string, value []int32, usage string) *[]int32 {\n\tp := []int32{}\n\tf.Int32SliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 {\n\tp := []int32{}\n\tf.Int32SliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// Int32Slice defines a []int32 flag with specified name, default value, and usage string.\n// The return value is the address of a []int32 variable that stores the value of the flag.\nfunc Int32Slice(name string, value []int32, usage string) *[]int32 {\n\treturn CommandLine.Int32SliceP(name, \"\", value, usage)\n}\n\n// Int32SliceP is like Int32Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc Int32SliceP(name, shorthand string, value []int32, usage string) *[]int32 {\n\treturn CommandLine.Int32SliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int64.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- int64 Value\ntype int64Value int64\n\nfunc newInt64Value(val int64, p *int64) *int64Value {\n\t*p = val\n\treturn (*int64Value)(p)\n}\n\nfunc (i *int64Value) Set(s string) error {\n\tv, err := strconv.ParseInt(s, 0, 64)\n\t*i = int64Value(v)\n\treturn err\n}\n\nfunc (i *int64Value) Type() string {\n\treturn \"int64\"\n}\n\nfunc (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }\n\nfunc int64Conv(sval string) (interface{}, error) {\n\treturn strconv.ParseInt(sval, 0, 64)\n}\n\n// GetInt64 return the int64 value of a flag with the given name\nfunc (f *FlagSet) GetInt64(name string) (int64, error) {\n\tval, err := f.getFlagType(name, \"int64\", int64Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(int64), nil\n}\n\n// Int64Var defines an int64 flag with specified name, default value, and usage string.\n// The argument p points to an int64 variable in which to store the value of the flag.\nfunc (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {\n\tf.VarP(newInt64Value(value, p), name, \"\", usage)\n}\n\n// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int64VarP(p *int64, name, shorthand string, value int64, usage string) {\n\tf.VarP(newInt64Value(value, p), name, shorthand, usage)\n}\n\n// Int64Var defines an int64 flag with specified name, default value, and usage string.\n// The argument p points to an int64 variable in which to store the value of the flag.\nfunc Int64Var(p *int64, name string, value int64, usage string) {\n\tCommandLine.VarP(newInt64Value(value, p), name, \"\", usage)\n}\n\n// Int64VarP is like Int64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Int64VarP(p *int64, name, shorthand string, value int64, usage string) {\n\tCommandLine.VarP(newInt64Value(value, p), name, shorthand, usage)\n}\n\n// Int64 defines an int64 flag with specified name, default value, and usage string.\n// The return value is the address of an int64 variable that stores the value of the flag.\nfunc (f *FlagSet) Int64(name string, value int64, usage string) *int64 {\n\tp := new(int64)\n\tf.Int64VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int64P(name, shorthand string, value int64, usage string) *int64 {\n\tp := new(int64)\n\tf.Int64VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Int64 defines an int64 flag with specified name, default value, and usage string.\n// The return value is the address of an int64 variable that stores the value of the flag.\nfunc Int64(name string, value int64, usage string) *int64 {\n\treturn CommandLine.Int64P(name, \"\", value, usage)\n}\n\n// Int64P is like Int64, but accepts a shorthand letter that can be used after a single dash.\nfunc Int64P(name, shorthand string, value int64, usage string) *int64 {\n\treturn CommandLine.Int64P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int64_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- int64Slice Value\ntype int64SliceValue struct {\n\tvalue   *[]int64\n\tchanged bool\n}\n\nfunc newInt64SliceValue(val []int64, p *[]int64) *int64SliceValue {\n\tisv := new(int64SliceValue)\n\tisv.value = p\n\t*isv.value = val\n\treturn isv\n}\n\nfunc (s *int64SliceValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make([]int64, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = strconv.ParseInt(d, 0, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *int64SliceValue) Type() string {\n\treturn \"int64Slice\"\n}\n\nfunc (s *int64SliceValue) String() string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = fmt.Sprintf(\"%d\", d)\n\t}\n\treturn \"[\" + strings.Join(out, \",\") + \"]\"\n}\n\nfunc (s *int64SliceValue) fromString(val string) (int64, error) {\n\treturn strconv.ParseInt(val, 0, 64)\n}\n\nfunc (s *int64SliceValue) toString(val int64) string {\n\treturn fmt.Sprintf(\"%d\", val)\n}\n\nfunc (s *int64SliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *int64SliceValue) Replace(val []string) error {\n\tout := make([]int64, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *int64SliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc int64SliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []int64{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]int64, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = strconv.ParseInt(d, 0, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t}\n\treturn out, nil\n}\n\n// GetInt64Slice return the []int64 value of a flag with the given name\nfunc (f *FlagSet) GetInt64Slice(name string) ([]int64, error) {\n\tval, err := f.getFlagType(name, \"int64Slice\", int64SliceConv)\n\tif err != nil {\n\t\treturn []int64{}, err\n\t}\n\treturn val.([]int64), nil\n}\n\n// Int64SliceVar defines a int64Slice flag with specified name, default value, and usage string.\n// The argument p points to a []int64 variable in which to store the value of the flag.\nfunc (f *FlagSet) Int64SliceVar(p *[]int64, name string, value []int64, usage string) {\n\tf.VarP(newInt64SliceValue(value, p), name, \"\", usage)\n}\n\n// Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) {\n\tf.VarP(newInt64SliceValue(value, p), name, shorthand, usage)\n}\n\n// Int64SliceVar defines a int64[] flag with specified name, default value, and usage string.\n// The argument p points to a int64[] variable in which to store the value of the flag.\nfunc Int64SliceVar(p *[]int64, name string, value []int64, usage string) {\n\tCommandLine.VarP(newInt64SliceValue(value, p), name, \"\", usage)\n}\n\n// Int64SliceVarP is like Int64SliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc Int64SliceVarP(p *[]int64, name, shorthand string, value []int64, usage string) {\n\tCommandLine.VarP(newInt64SliceValue(value, p), name, shorthand, usage)\n}\n\n// Int64Slice defines a []int64 flag with specified name, default value, and usage string.\n// The return value is the address of a []int64 variable that stores the value of the flag.\nfunc (f *FlagSet) Int64Slice(name string, value []int64, usage string) *[]int64 {\n\tp := []int64{}\n\tf.Int64SliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 {\n\tp := []int64{}\n\tf.Int64SliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// Int64Slice defines a []int64 flag with specified name, default value, and usage string.\n// The return value is the address of a []int64 variable that stores the value of the flag.\nfunc Int64Slice(name string, value []int64, usage string) *[]int64 {\n\treturn CommandLine.Int64SliceP(name, \"\", value, usage)\n}\n\n// Int64SliceP is like Int64Slice, but accepts a shorthand letter that can be used after a single dash.\nfunc Int64SliceP(name, shorthand string, value []int64, usage string) *[]int64 {\n\treturn CommandLine.Int64SliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int8.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- int8 Value\ntype int8Value int8\n\nfunc newInt8Value(val int8, p *int8) *int8Value {\n\t*p = val\n\treturn (*int8Value)(p)\n}\n\nfunc (i *int8Value) Set(s string) error {\n\tv, err := strconv.ParseInt(s, 0, 8)\n\t*i = int8Value(v)\n\treturn err\n}\n\nfunc (i *int8Value) Type() string {\n\treturn \"int8\"\n}\n\nfunc (i *int8Value) String() string { return strconv.FormatInt(int64(*i), 10) }\n\nfunc int8Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseInt(sval, 0, 8)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn int8(v), nil\n}\n\n// GetInt8 return the int8 value of a flag with the given name\nfunc (f *FlagSet) GetInt8(name string) (int8, error) {\n\tval, err := f.getFlagType(name, \"int8\", int8Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(int8), nil\n}\n\n// Int8Var defines an int8 flag with specified name, default value, and usage string.\n// The argument p points to an int8 variable in which to store the value of the flag.\nfunc (f *FlagSet) Int8Var(p *int8, name string, value int8, usage string) {\n\tf.VarP(newInt8Value(value, p), name, \"\", usage)\n}\n\n// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int8VarP(p *int8, name, shorthand string, value int8, usage string) {\n\tf.VarP(newInt8Value(value, p), name, shorthand, usage)\n}\n\n// Int8Var defines an int8 flag with specified name, default value, and usage string.\n// The argument p points to an int8 variable in which to store the value of the flag.\nfunc Int8Var(p *int8, name string, value int8, usage string) {\n\tCommandLine.VarP(newInt8Value(value, p), name, \"\", usage)\n}\n\n// Int8VarP is like Int8Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Int8VarP(p *int8, name, shorthand string, value int8, usage string) {\n\tCommandLine.VarP(newInt8Value(value, p), name, shorthand, usage)\n}\n\n// Int8 defines an int8 flag with specified name, default value, and usage string.\n// The return value is the address of an int8 variable that stores the value of the flag.\nfunc (f *FlagSet) Int8(name string, value int8, usage string) *int8 {\n\tp := new(int8)\n\tf.Int8VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Int8P(name, shorthand string, value int8, usage string) *int8 {\n\tp := new(int8)\n\tf.Int8VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Int8 defines an int8 flag with specified name, default value, and usage string.\n// The return value is the address of an int8 variable that stores the value of the flag.\nfunc Int8(name string, value int8, usage string) *int8 {\n\treturn CommandLine.Int8P(name, \"\", value, usage)\n}\n\n// Int8P is like Int8, but accepts a shorthand letter that can be used after a single dash.\nfunc Int8P(name, shorthand string, value int8, usage string) *int8 {\n\treturn CommandLine.Int8P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/int_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- intSlice Value\ntype intSliceValue struct {\n\tvalue   *[]int\n\tchanged bool\n}\n\nfunc newIntSliceValue(val []int, p *[]int) *intSliceValue {\n\tisv := new(intSliceValue)\n\tisv.value = p\n\t*isv.value = val\n\treturn isv\n}\n\nfunc (s *intSliceValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make([]int, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = strconv.Atoi(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *intSliceValue) Type() string {\n\treturn \"intSlice\"\n}\n\nfunc (s *intSliceValue) String() string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = fmt.Sprintf(\"%d\", d)\n\t}\n\treturn \"[\" + strings.Join(out, \",\") + \"]\"\n}\n\nfunc (s *intSliceValue) Append(val string) error {\n\ti, err := strconv.Atoi(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *intSliceValue) Replace(val []string) error {\n\tout := make([]int, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = strconv.Atoi(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *intSliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = strconv.Itoa(d)\n\t}\n\treturn out\n}\n\nfunc intSliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []int{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]int, len(ss))\n\tfor i, d := range ss {\n\t\tvar err error\n\t\tout[i], err = strconv.Atoi(d)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t}\n\treturn out, nil\n}\n\n// GetIntSlice return the []int value of a flag with the given name\nfunc (f *FlagSet) GetIntSlice(name string) ([]int, error) {\n\tval, err := f.getFlagType(name, \"intSlice\", intSliceConv)\n\tif err != nil {\n\t\treturn []int{}, err\n\t}\n\treturn val.([]int), nil\n}\n\n// IntSliceVar defines a intSlice flag with specified name, default value, and usage string.\n// The argument p points to a []int variable in which to store the value of the flag.\nfunc (f *FlagSet) IntSliceVar(p *[]int, name string, value []int, usage string) {\n\tf.VarP(newIntSliceValue(value, p), name, \"\", usage)\n}\n\n// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {\n\tf.VarP(newIntSliceValue(value, p), name, shorthand, usage)\n}\n\n// IntSliceVar defines a int[] flag with specified name, default value, and usage string.\n// The argument p points to a int[] variable in which to store the value of the flag.\nfunc IntSliceVar(p *[]int, name string, value []int, usage string) {\n\tCommandLine.VarP(newIntSliceValue(value, p), name, \"\", usage)\n}\n\n// IntSliceVarP is like IntSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc IntSliceVarP(p *[]int, name, shorthand string, value []int, usage string) {\n\tCommandLine.VarP(newIntSliceValue(value, p), name, shorthand, usage)\n}\n\n// IntSlice defines a []int flag with specified name, default value, and usage string.\n// The return value is the address of a []int variable that stores the value of the flag.\nfunc (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int {\n\tp := []int{}\n\tf.IntSliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IntSliceP(name, shorthand string, value []int, usage string) *[]int {\n\tp := []int{}\n\tf.IntSliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// IntSlice defines a []int flag with specified name, default value, and usage string.\n// The return value is the address of a []int variable that stores the value of the flag.\nfunc IntSlice(name string, value []int, usage string) *[]int {\n\treturn CommandLine.IntSliceP(name, \"\", value, usage)\n}\n\n// IntSliceP is like IntSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc IntSliceP(name, shorthand string, value []int, usage string) *[]int {\n\treturn CommandLine.IntSliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/ip.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n)\n\n// -- net.IP value\ntype ipValue net.IP\n\nfunc newIPValue(val net.IP, p *net.IP) *ipValue {\n\t*p = val\n\treturn (*ipValue)(p)\n}\n\nfunc (i *ipValue) String() string { return net.IP(*i).String() }\nfunc (i *ipValue) Set(s string) error {\n\tip := net.ParseIP(strings.TrimSpace(s))\n\tif ip == nil {\n\t\treturn fmt.Errorf(\"failed to parse IP: %q\", s)\n\t}\n\t*i = ipValue(ip)\n\treturn nil\n}\n\nfunc (i *ipValue) Type() string {\n\treturn \"ip\"\n}\n\nfunc ipConv(sval string) (interface{}, error) {\n\tip := net.ParseIP(sval)\n\tif ip != nil {\n\t\treturn ip, nil\n\t}\n\treturn nil, fmt.Errorf(\"invalid string being converted to IP address: %s\", sval)\n}\n\n// GetIP return the net.IP value of a flag with the given name\nfunc (f *FlagSet) GetIP(name string) (net.IP, error) {\n\tval, err := f.getFlagType(name, \"ip\", ipConv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn val.(net.IP), nil\n}\n\n// IPVar defines an net.IP flag with specified name, default value, and usage string.\n// The argument p points to an net.IP variable in which to store the value of the flag.\nfunc (f *FlagSet) IPVar(p *net.IP, name string, value net.IP, usage string) {\n\tf.VarP(newIPValue(value, p), name, \"\", usage)\n}\n\n// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {\n\tf.VarP(newIPValue(value, p), name, shorthand, usage)\n}\n\n// IPVar defines an net.IP flag with specified name, default value, and usage string.\n// The argument p points to an net.IP variable in which to store the value of the flag.\nfunc IPVar(p *net.IP, name string, value net.IP, usage string) {\n\tCommandLine.VarP(newIPValue(value, p), name, \"\", usage)\n}\n\n// IPVarP is like IPVar, but accepts a shorthand letter that can be used after a single dash.\nfunc IPVarP(p *net.IP, name, shorthand string, value net.IP, usage string) {\n\tCommandLine.VarP(newIPValue(value, p), name, shorthand, usage)\n}\n\n// IP defines an net.IP flag with specified name, default value, and usage string.\n// The return value is the address of an net.IP variable that stores the value of the flag.\nfunc (f *FlagSet) IP(name string, value net.IP, usage string) *net.IP {\n\tp := new(net.IP)\n\tf.IPVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPP(name, shorthand string, value net.IP, usage string) *net.IP {\n\tp := new(net.IP)\n\tf.IPVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// IP defines an net.IP flag with specified name, default value, and usage string.\n// The return value is the address of an net.IP variable that stores the value of the flag.\nfunc IP(name string, value net.IP, usage string) *net.IP {\n\treturn CommandLine.IPP(name, \"\", value, usage)\n}\n\n// IPP is like IP, but accepts a shorthand letter that can be used after a single dash.\nfunc IPP(name, shorthand string, value net.IP, usage string) *net.IP {\n\treturn CommandLine.IPP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/ip_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"strings\"\n)\n\n// -- ipSlice Value\ntype ipSliceValue struct {\n\tvalue   *[]net.IP\n\tchanged bool\n}\n\nfunc newIPSliceValue(val []net.IP, p *[]net.IP) *ipSliceValue {\n\tipsv := new(ipSliceValue)\n\tipsv.value = p\n\t*ipsv.value = val\n\treturn ipsv\n}\n\n// Set converts, and assigns, the comma-separated IP argument string representation as the []net.IP value of this flag.\n// If Set is called on a flag that already has a []net.IP assigned, the newly converted values will be appended.\nfunc (s *ipSliceValue) Set(val string) error {\n\n\t// remove all quote characters\n\trmQuote := strings.NewReplacer(`\"`, \"\", `'`, \"\", \"`\", \"\")\n\n\t// read flag arguments with CSV parser\n\tipStrSlice, err := readAsCSV(rmQuote.Replace(val))\n\tif err != nil && err != io.EOF {\n\t\treturn err\n\t}\n\n\t// parse ip values into slice\n\tout := make([]net.IP, 0, len(ipStrSlice))\n\tfor _, ipStr := range ipStrSlice {\n\t\tip := net.ParseIP(strings.TrimSpace(ipStr))\n\t\tif ip == nil {\n\t\t\treturn fmt.Errorf(\"invalid string being converted to IP address: %s\", ipStr)\n\t\t}\n\t\tout = append(out, ip)\n\t}\n\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\n\ts.changed = true\n\n\treturn nil\n}\n\n// Type returns a string that uniquely represents this flag's type.\nfunc (s *ipSliceValue) Type() string {\n\treturn \"ipSlice\"\n}\n\n// String defines a \"native\" format for this net.IP slice flag value.\nfunc (s *ipSliceValue) String() string {\n\n\tipStrSlice := make([]string, len(*s.value))\n\tfor i, ip := range *s.value {\n\t\tipStrSlice[i] = ip.String()\n\t}\n\n\tout, _ := writeAsCSV(ipStrSlice)\n\n\treturn \"[\" + out + \"]\"\n}\n\nfunc (s *ipSliceValue) fromString(val string) (net.IP, error) {\n\treturn net.ParseIP(strings.TrimSpace(val)), nil\n}\n\nfunc (s *ipSliceValue) toString(val net.IP) string {\n\treturn val.String()\n}\n\nfunc (s *ipSliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *ipSliceValue) Replace(val []string) error {\n\tout := make([]net.IP, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *ipSliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc ipSliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []net.IP{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]net.IP, len(ss))\n\tfor i, sval := range ss {\n\t\tip := net.ParseIP(strings.TrimSpace(sval))\n\t\tif ip == nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid string being converted to IP address: %s\", sval)\n\t\t}\n\t\tout[i] = ip\n\t}\n\treturn out, nil\n}\n\n// GetIPSlice returns the []net.IP value of a flag with the given name\nfunc (f *FlagSet) GetIPSlice(name string) ([]net.IP, error) {\n\tval, err := f.getFlagType(name, \"ipSlice\", ipSliceConv)\n\tif err != nil {\n\t\treturn []net.IP{}, err\n\t}\n\treturn val.([]net.IP), nil\n}\n\n// IPSliceVar defines a ipSlice flag with specified name, default value, and usage string.\n// The argument p points to a []net.IP variable in which to store the value of the flag.\nfunc (f *FlagSet) IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {\n\tf.VarP(newIPSliceValue(value, p), name, \"\", usage)\n}\n\n// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {\n\tf.VarP(newIPSliceValue(value, p), name, shorthand, usage)\n}\n\n// IPSliceVar defines a []net.IP flag with specified name, default value, and usage string.\n// The argument p points to a []net.IP variable in which to store the value of the flag.\nfunc IPSliceVar(p *[]net.IP, name string, value []net.IP, usage string) {\n\tCommandLine.VarP(newIPSliceValue(value, p), name, \"\", usage)\n}\n\n// IPSliceVarP is like IPSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc IPSliceVarP(p *[]net.IP, name, shorthand string, value []net.IP, usage string) {\n\tCommandLine.VarP(newIPSliceValue(value, p), name, shorthand, usage)\n}\n\n// IPSlice defines a []net.IP flag with specified name, default value, and usage string.\n// The return value is the address of a []net.IP variable that stores the value of that flag.\nfunc (f *FlagSet) IPSlice(name string, value []net.IP, usage string) *[]net.IP {\n\tp := []net.IP{}\n\tf.IPSliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {\n\tp := []net.IP{}\n\tf.IPSliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// IPSlice defines a []net.IP flag with specified name, default value, and usage string.\n// The return value is the address of a []net.IP variable that stores the value of the flag.\nfunc IPSlice(name string, value []net.IP, usage string) *[]net.IP {\n\treturn CommandLine.IPSliceP(name, \"\", value, usage)\n}\n\n// IPSliceP is like IPSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc IPSliceP(name, shorthand string, value []net.IP, usage string) *[]net.IP {\n\treturn CommandLine.IPSliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/ipmask.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strconv\"\n)\n\n// -- net.IPMask value\ntype ipMaskValue net.IPMask\n\nfunc newIPMaskValue(val net.IPMask, p *net.IPMask) *ipMaskValue {\n\t*p = val\n\treturn (*ipMaskValue)(p)\n}\n\nfunc (i *ipMaskValue) String() string { return net.IPMask(*i).String() }\nfunc (i *ipMaskValue) Set(s string) error {\n\tip := ParseIPv4Mask(s)\n\tif ip == nil {\n\t\treturn fmt.Errorf(\"failed to parse IP mask: %q\", s)\n\t}\n\t*i = ipMaskValue(ip)\n\treturn nil\n}\n\nfunc (i *ipMaskValue) Type() string {\n\treturn \"ipMask\"\n}\n\n// ParseIPv4Mask written in IP form (e.g. 255.255.255.0).\n// This function should really belong to the net package.\nfunc ParseIPv4Mask(s string) net.IPMask {\n\tmask := net.ParseIP(s)\n\tif mask == nil {\n\t\tif len(s) != 8 {\n\t\t\treturn nil\n\t\t}\n\t\t// net.IPMask.String() actually outputs things like ffffff00\n\t\t// so write a horrible parser for that as well  :-(\n\t\tm := []int{}\n\t\tfor i := 0; i < 4; i++ {\n\t\t\tb := \"0x\" + s[2*i:2*i+2]\n\t\t\td, err := strconv.ParseInt(b, 0, 0)\n\t\t\tif err != nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tm = append(m, int(d))\n\t\t}\n\t\ts := fmt.Sprintf(\"%d.%d.%d.%d\", m[0], m[1], m[2], m[3])\n\t\tmask = net.ParseIP(s)\n\t\tif mask == nil {\n\t\t\treturn nil\n\t\t}\n\t}\n\treturn net.IPv4Mask(mask[12], mask[13], mask[14], mask[15])\n}\n\nfunc parseIPv4Mask(sval string) (interface{}, error) {\n\tmask := ParseIPv4Mask(sval)\n\tif mask == nil {\n\t\treturn nil, fmt.Errorf(\"unable to parse %s as net.IPMask\", sval)\n\t}\n\treturn mask, nil\n}\n\n// GetIPv4Mask return the net.IPv4Mask value of a flag with the given name\nfunc (f *FlagSet) GetIPv4Mask(name string) (net.IPMask, error) {\n\tval, err := f.getFlagType(name, \"ipMask\", parseIPv4Mask)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn val.(net.IPMask), nil\n}\n\n// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.\n// The argument p points to an net.IPMask variable in which to store the value of the flag.\nfunc (f *FlagSet) IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {\n\tf.VarP(newIPMaskValue(value, p), name, \"\", usage)\n}\n\n// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {\n\tf.VarP(newIPMaskValue(value, p), name, shorthand, usage)\n}\n\n// IPMaskVar defines an net.IPMask flag with specified name, default value, and usage string.\n// The argument p points to an net.IPMask variable in which to store the value of the flag.\nfunc IPMaskVar(p *net.IPMask, name string, value net.IPMask, usage string) {\n\tCommandLine.VarP(newIPMaskValue(value, p), name, \"\", usage)\n}\n\n// IPMaskVarP is like IPMaskVar, but accepts a shorthand letter that can be used after a single dash.\nfunc IPMaskVarP(p *net.IPMask, name, shorthand string, value net.IPMask, usage string) {\n\tCommandLine.VarP(newIPMaskValue(value, p), name, shorthand, usage)\n}\n\n// IPMask defines an net.IPMask flag with specified name, default value, and usage string.\n// The return value is the address of an net.IPMask variable that stores the value of the flag.\nfunc (f *FlagSet) IPMask(name string, value net.IPMask, usage string) *net.IPMask {\n\tp := new(net.IPMask)\n\tf.IPMaskVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// IPMaskP is like IPMask, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {\n\tp := new(net.IPMask)\n\tf.IPMaskVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// IPMask defines an net.IPMask flag with specified name, default value, and usage string.\n// The return value is the address of an net.IPMask variable that stores the value of the flag.\nfunc IPMask(name string, value net.IPMask, usage string) *net.IPMask {\n\treturn CommandLine.IPMaskP(name, \"\", value, usage)\n}\n\n// IPMaskP is like IP, but accepts a shorthand letter that can be used after a single dash.\nfunc IPMaskP(name, shorthand string, value net.IPMask, usage string) *net.IPMask {\n\treturn CommandLine.IPMaskP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/ipnet.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"net\"\n\t\"strings\"\n)\n\n// IPNet adapts net.IPNet for use as a flag.\ntype ipNetValue net.IPNet\n\nfunc (ipnet ipNetValue) String() string {\n\tn := net.IPNet(ipnet)\n\treturn n.String()\n}\n\nfunc (ipnet *ipNetValue) Set(value string) error {\n\t_, n, err := net.ParseCIDR(strings.TrimSpace(value))\n\tif err != nil {\n\t\treturn err\n\t}\n\t*ipnet = ipNetValue(*n)\n\treturn nil\n}\n\nfunc (*ipNetValue) Type() string {\n\treturn \"ipNet\"\n}\n\nfunc newIPNetValue(val net.IPNet, p *net.IPNet) *ipNetValue {\n\t*p = val\n\treturn (*ipNetValue)(p)\n}\n\nfunc ipNetConv(sval string) (interface{}, error) {\n\t_, n, err := net.ParseCIDR(strings.TrimSpace(sval))\n\tif err == nil {\n\t\treturn *n, nil\n\t}\n\treturn nil, fmt.Errorf(\"invalid string being converted to IPNet: %s\", sval)\n}\n\n// GetIPNet return the net.IPNet value of a flag with the given name\nfunc (f *FlagSet) GetIPNet(name string) (net.IPNet, error) {\n\tval, err := f.getFlagType(name, \"ipNet\", ipNetConv)\n\tif err != nil {\n\t\treturn net.IPNet{}, err\n\t}\n\treturn val.(net.IPNet), nil\n}\n\n// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.\n// The argument p points to an net.IPNet variable in which to store the value of the flag.\nfunc (f *FlagSet) IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {\n\tf.VarP(newIPNetValue(value, p), name, \"\", usage)\n}\n\n// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {\n\tf.VarP(newIPNetValue(value, p), name, shorthand, usage)\n}\n\n// IPNetVar defines an net.IPNet flag with specified name, default value, and usage string.\n// The argument p points to an net.IPNet variable in which to store the value of the flag.\nfunc IPNetVar(p *net.IPNet, name string, value net.IPNet, usage string) {\n\tCommandLine.VarP(newIPNetValue(value, p), name, \"\", usage)\n}\n\n// IPNetVarP is like IPNetVar, but accepts a shorthand letter that can be used after a single dash.\nfunc IPNetVarP(p *net.IPNet, name, shorthand string, value net.IPNet, usage string) {\n\tCommandLine.VarP(newIPNetValue(value, p), name, shorthand, usage)\n}\n\n// IPNet defines an net.IPNet flag with specified name, default value, and usage string.\n// The return value is the address of an net.IPNet variable that stores the value of the flag.\nfunc (f *FlagSet) IPNet(name string, value net.IPNet, usage string) *net.IPNet {\n\tp := new(net.IPNet)\n\tf.IPNetVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {\n\tp := new(net.IPNet)\n\tf.IPNetVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// IPNet defines an net.IPNet flag with specified name, default value, and usage string.\n// The return value is the address of an net.IPNet variable that stores the value of the flag.\nfunc IPNet(name string, value net.IPNet, usage string) *net.IPNet {\n\treturn CommandLine.IPNetP(name, \"\", value, usage)\n}\n\n// IPNetP is like IPNet, but accepts a shorthand letter that can be used after a single dash.\nfunc IPNetP(name, shorthand string, value net.IPNet, usage string) *net.IPNet {\n\treturn CommandLine.IPNetP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/string.go",
    "content": "package pflag\n\n// -- string Value\ntype stringValue string\n\nfunc newStringValue(val string, p *string) *stringValue {\n\t*p = val\n\treturn (*stringValue)(p)\n}\n\nfunc (s *stringValue) Set(val string) error {\n\t*s = stringValue(val)\n\treturn nil\n}\nfunc (s *stringValue) Type() string {\n\treturn \"string\"\n}\n\nfunc (s *stringValue) String() string { return string(*s) }\n\nfunc stringConv(sval string) (interface{}, error) {\n\treturn sval, nil\n}\n\n// GetString return the string value of a flag with the given name\nfunc (f *FlagSet) GetString(name string) (string, error) {\n\tval, err := f.getFlagType(name, \"string\", stringConv)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn val.(string), nil\n}\n\n// StringVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a string variable in which to store the value of the flag.\nfunc (f *FlagSet) StringVar(p *string, name string, value string, usage string) {\n\tf.VarP(newStringValue(value, p), name, \"\", usage)\n}\n\n// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringVarP(p *string, name, shorthand string, value string, usage string) {\n\tf.VarP(newStringValue(value, p), name, shorthand, usage)\n}\n\n// StringVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a string variable in which to store the value of the flag.\nfunc StringVar(p *string, name string, value string, usage string) {\n\tCommandLine.VarP(newStringValue(value, p), name, \"\", usage)\n}\n\n// StringVarP is like StringVar, but accepts a shorthand letter that can be used after a single dash.\nfunc StringVarP(p *string, name, shorthand string, value string, usage string) {\n\tCommandLine.VarP(newStringValue(value, p), name, shorthand, usage)\n}\n\n// String defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a string variable that stores the value of the flag.\nfunc (f *FlagSet) String(name string, value string, usage string) *string {\n\tp := new(string)\n\tf.StringVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// StringP is like String, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringP(name, shorthand string, value string, usage string) *string {\n\tp := new(string)\n\tf.StringVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// String defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a string variable that stores the value of the flag.\nfunc String(name string, value string, usage string) *string {\n\treturn CommandLine.StringP(name, \"\", value, usage)\n}\n\n// StringP is like String, but accepts a shorthand letter that can be used after a single dash.\nfunc StringP(name, shorthand string, value string, usage string) *string {\n\treturn CommandLine.StringP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/string_array.go",
    "content": "package pflag\n\n// -- stringArray Value\ntype stringArrayValue struct {\n\tvalue   *[]string\n\tchanged bool\n}\n\nfunc newStringArrayValue(val []string, p *[]string) *stringArrayValue {\n\tssv := new(stringArrayValue)\n\tssv.value = p\n\t*ssv.value = val\n\treturn ssv\n}\n\nfunc (s *stringArrayValue) Set(val string) error {\n\tif !s.changed {\n\t\t*s.value = []string{val}\n\t\ts.changed = true\n\t} else {\n\t\t*s.value = append(*s.value, val)\n\t}\n\treturn nil\n}\n\nfunc (s *stringArrayValue) Append(val string) error {\n\t*s.value = append(*s.value, val)\n\treturn nil\n}\n\nfunc (s *stringArrayValue) Replace(val []string) error {\n\tout := make([]string, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i] = d\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *stringArrayValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = d\n\t}\n\treturn out\n}\n\nfunc (s *stringArrayValue) Type() string {\n\treturn \"stringArray\"\n}\n\nfunc (s *stringArrayValue) String() string {\n\tstr, _ := writeAsCSV(*s.value)\n\treturn \"[\" + str + \"]\"\n}\n\nfunc stringArrayConv(sval string) (interface{}, error) {\n\tsval = sval[1 : len(sval)-1]\n\t// An empty string would cause a array with one (empty) string\n\tif len(sval) == 0 {\n\t\treturn []string{}, nil\n\t}\n\treturn readAsCSV(sval)\n}\n\n// GetStringArray return the []string value of a flag with the given name\nfunc (f *FlagSet) GetStringArray(name string) ([]string, error) {\n\tval, err := f.getFlagType(name, \"stringArray\", stringArrayConv)\n\tif err != nil {\n\t\treturn []string{}, err\n\t}\n\treturn val.([]string), nil\n}\n\n// StringArrayVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a []string variable in which to store the values of the multiple flags.\n// The value of each argument will not try to be separated by comma. Use a StringSlice for that.\nfunc (f *FlagSet) StringArrayVar(p *[]string, name string, value []string, usage string) {\n\tf.VarP(newStringArrayValue(value, p), name, \"\", usage)\n}\n\n// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {\n\tf.VarP(newStringArrayValue(value, p), name, shorthand, usage)\n}\n\n// StringArrayVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a []string variable in which to store the value of the flag.\n// The value of each argument will not try to be separated by comma. Use a StringSlice for that.\nfunc StringArrayVar(p *[]string, name string, value []string, usage string) {\n\tCommandLine.VarP(newStringArrayValue(value, p), name, \"\", usage)\n}\n\n// StringArrayVarP is like StringArrayVar, but accepts a shorthand letter that can be used after a single dash.\nfunc StringArrayVarP(p *[]string, name, shorthand string, value []string, usage string) {\n\tCommandLine.VarP(newStringArrayValue(value, p), name, shorthand, usage)\n}\n\n// StringArray defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a []string variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma. Use a StringSlice for that.\nfunc (f *FlagSet) StringArray(name string, value []string, usage string) *[]string {\n\tp := []string{}\n\tf.StringArrayVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringArrayP(name, shorthand string, value []string, usage string) *[]string {\n\tp := []string{}\n\tf.StringArrayVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// StringArray defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a []string variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma. Use a StringSlice for that.\nfunc StringArray(name string, value []string, usage string) *[]string {\n\treturn CommandLine.StringArrayP(name, \"\", value, usage)\n}\n\n// StringArrayP is like StringArray, but accepts a shorthand letter that can be used after a single dash.\nfunc StringArrayP(name, shorthand string, value []string, usage string) *[]string {\n\treturn CommandLine.StringArrayP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/string_slice.go",
    "content": "package pflag\n\nimport (\n\t\"bytes\"\n\t\"encoding/csv\"\n\t\"strings\"\n)\n\n// -- stringSlice Value\ntype stringSliceValue struct {\n\tvalue   *[]string\n\tchanged bool\n}\n\nfunc newStringSliceValue(val []string, p *[]string) *stringSliceValue {\n\tssv := new(stringSliceValue)\n\tssv.value = p\n\t*ssv.value = val\n\treturn ssv\n}\n\nfunc readAsCSV(val string) ([]string, error) {\n\tif val == \"\" {\n\t\treturn []string{}, nil\n\t}\n\tstringReader := strings.NewReader(val)\n\tcsvReader := csv.NewReader(stringReader)\n\treturn csvReader.Read()\n}\n\nfunc writeAsCSV(vals []string) (string, error) {\n\tb := &bytes.Buffer{}\n\tw := csv.NewWriter(b)\n\terr := w.Write(vals)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tw.Flush()\n\treturn strings.TrimSuffix(b.String(), \"\\n\"), nil\n}\n\nfunc (s *stringSliceValue) Set(val string) error {\n\tv, err := readAsCSV(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif !s.changed {\n\t\t*s.value = v\n\t} else {\n\t\t*s.value = append(*s.value, v...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *stringSliceValue) Type() string {\n\treturn \"stringSlice\"\n}\n\nfunc (s *stringSliceValue) String() string {\n\tstr, _ := writeAsCSV(*s.value)\n\treturn \"[\" + str + \"]\"\n}\n\nfunc (s *stringSliceValue) Append(val string) error {\n\t*s.value = append(*s.value, val)\n\treturn nil\n}\n\nfunc (s *stringSliceValue) Replace(val []string) error {\n\t*s.value = val\n\treturn nil\n}\n\nfunc (s *stringSliceValue) GetSlice() []string {\n\treturn *s.value\n}\n\nfunc stringSliceConv(sval string) (interface{}, error) {\n\tsval = sval[1 : len(sval)-1]\n\t// An empty string would cause a slice with one (empty) string\n\tif len(sval) == 0 {\n\t\treturn []string{}, nil\n\t}\n\treturn readAsCSV(sval)\n}\n\n// GetStringSlice return the []string value of a flag with the given name\nfunc (f *FlagSet) GetStringSlice(name string) ([]string, error) {\n\tval, err := f.getFlagType(name, \"stringSlice\", stringSliceConv)\n\tif err != nil {\n\t\treturn []string{}, err\n\t}\n\treturn val.([]string), nil\n}\n\n// StringSliceVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a []string variable in which to store the value of the flag.\n// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.\n// For example:\n//   --ss=\"v1,v2\" --ss=\"v3\"\n// will result in\n//   []string{\"v1\", \"v2\", \"v3\"}\nfunc (f *FlagSet) StringSliceVar(p *[]string, name string, value []string, usage string) {\n\tf.VarP(newStringSliceValue(value, p), name, \"\", usage)\n}\n\n// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {\n\tf.VarP(newStringSliceValue(value, p), name, shorthand, usage)\n}\n\n// StringSliceVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a []string variable in which to store the value of the flag.\n// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.\n// For example:\n//   --ss=\"v1,v2\" --ss=\"v3\"\n// will result in\n//   []string{\"v1\", \"v2\", \"v3\"}\nfunc StringSliceVar(p *[]string, name string, value []string, usage string) {\n\tCommandLine.VarP(newStringSliceValue(value, p), name, \"\", usage)\n}\n\n// StringSliceVarP is like StringSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc StringSliceVarP(p *[]string, name, shorthand string, value []string, usage string) {\n\tCommandLine.VarP(newStringSliceValue(value, p), name, shorthand, usage)\n}\n\n// StringSlice defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a []string variable that stores the value of the flag.\n// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.\n// For example:\n//   --ss=\"v1,v2\" --ss=\"v3\"\n// will result in\n//   []string{\"v1\", \"v2\", \"v3\"}\nfunc (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string {\n\tp := []string{}\n\tf.StringSliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringSliceP(name, shorthand string, value []string, usage string) *[]string {\n\tp := []string{}\n\tf.StringSliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// StringSlice defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a []string variable that stores the value of the flag.\n// Compared to StringArray flags, StringSlice flags take comma-separated value as arguments and split them accordingly.\n// For example:\n//   --ss=\"v1,v2\" --ss=\"v3\"\n// will result in\n//   []string{\"v1\", \"v2\", \"v3\"}\nfunc StringSlice(name string, value []string, usage string) *[]string {\n\treturn CommandLine.StringSliceP(name, \"\", value, usage)\n}\n\n// StringSliceP is like StringSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc StringSliceP(name, shorthand string, value []string, usage string) *[]string {\n\treturn CommandLine.StringSliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/string_to_int.go",
    "content": "package pflag\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- stringToInt Value\ntype stringToIntValue struct {\n\tvalue   *map[string]int\n\tchanged bool\n}\n\nfunc newStringToIntValue(val map[string]int, p *map[string]int) *stringToIntValue {\n\tssv := new(stringToIntValue)\n\tssv.value = p\n\t*ssv.value = val\n\treturn ssv\n}\n\n// Format: a=1,b=2\nfunc (s *stringToIntValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make(map[string]int, len(ss))\n\tfor _, pair := range ss {\n\t\tkv := strings.SplitN(pair, \"=\", 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn fmt.Errorf(\"%s must be formatted as key=value\", pair)\n\t\t}\n\t\tvar err error\n\t\tout[kv[0]], err = strconv.Atoi(kv[1])\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\tfor k, v := range out {\n\t\t\t(*s.value)[k] = v\n\t\t}\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *stringToIntValue) Type() string {\n\treturn \"stringToInt\"\n}\n\nfunc (s *stringToIntValue) String() string {\n\tvar buf bytes.Buffer\n\ti := 0\n\tfor k, v := range *s.value {\n\t\tif i > 0 {\n\t\t\tbuf.WriteRune(',')\n\t\t}\n\t\tbuf.WriteString(k)\n\t\tbuf.WriteRune('=')\n\t\tbuf.WriteString(strconv.Itoa(v))\n\t\ti++\n\t}\n\treturn \"[\" + buf.String() + \"]\"\n}\n\nfunc stringToIntConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// An empty string would cause an empty map\n\tif len(val) == 0 {\n\t\treturn map[string]int{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make(map[string]int, len(ss))\n\tfor _, pair := range ss {\n\t\tkv := strings.SplitN(pair, \"=\", 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"%s must be formatted as key=value\", pair)\n\t\t}\n\t\tvar err error\n\t\tout[kv[0]], err = strconv.Atoi(kv[1])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn out, nil\n}\n\n// GetStringToInt return the map[string]int value of a flag with the given name\nfunc (f *FlagSet) GetStringToInt(name string) (map[string]int, error) {\n\tval, err := f.getFlagType(name, \"stringToInt\", stringToIntConv)\n\tif err != nil {\n\t\treturn map[string]int{}, err\n\t}\n\treturn val.(map[string]int), nil\n}\n\n// StringToIntVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a map[string]int variable in which to store the values of the multiple flags.\n// The value of each argument will not try to be separated by comma\nfunc (f *FlagSet) StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) {\n\tf.VarP(newStringToIntValue(value, p), name, \"\", usage)\n}\n\n// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) {\n\tf.VarP(newStringToIntValue(value, p), name, shorthand, usage)\n}\n\n// StringToIntVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a map[string]int variable in which to store the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) {\n\tCommandLine.VarP(newStringToIntValue(value, p), name, \"\", usage)\n}\n\n// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash.\nfunc StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) {\n\tCommandLine.VarP(newStringToIntValue(value, p), name, shorthand, usage)\n}\n\n// StringToInt defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a map[string]int variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc (f *FlagSet) StringToInt(name string, value map[string]int, usage string) *map[string]int {\n\tp := map[string]int{}\n\tf.StringToIntVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int {\n\tp := map[string]int{}\n\tf.StringToIntVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// StringToInt defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a map[string]int variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc StringToInt(name string, value map[string]int, usage string) *map[string]int {\n\treturn CommandLine.StringToIntP(name, \"\", value, usage)\n}\n\n// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash.\nfunc StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int {\n\treturn CommandLine.StringToIntP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/string_to_int64.go",
    "content": "package pflag\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- stringToInt64 Value\ntype stringToInt64Value struct {\n\tvalue   *map[string]int64\n\tchanged bool\n}\n\nfunc newStringToInt64Value(val map[string]int64, p *map[string]int64) *stringToInt64Value {\n\tssv := new(stringToInt64Value)\n\tssv.value = p\n\t*ssv.value = val\n\treturn ssv\n}\n\n// Format: a=1,b=2\nfunc (s *stringToInt64Value) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make(map[string]int64, len(ss))\n\tfor _, pair := range ss {\n\t\tkv := strings.SplitN(pair, \"=\", 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn fmt.Errorf(\"%s must be formatted as key=value\", pair)\n\t\t}\n\t\tvar err error\n\t\tout[kv[0]], err = strconv.ParseInt(kv[1], 10, 64)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\tfor k, v := range out {\n\t\t\t(*s.value)[k] = v\n\t\t}\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *stringToInt64Value) Type() string {\n\treturn \"stringToInt64\"\n}\n\nfunc (s *stringToInt64Value) String() string {\n\tvar buf bytes.Buffer\n\ti := 0\n\tfor k, v := range *s.value {\n\t\tif i > 0 {\n\t\t\tbuf.WriteRune(',')\n\t\t}\n\t\tbuf.WriteString(k)\n\t\tbuf.WriteRune('=')\n\t\tbuf.WriteString(strconv.FormatInt(v, 10))\n\t\ti++\n\t}\n\treturn \"[\" + buf.String() + \"]\"\n}\n\nfunc stringToInt64Conv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// An empty string would cause an empty map\n\tif len(val) == 0 {\n\t\treturn map[string]int64{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make(map[string]int64, len(ss))\n\tfor _, pair := range ss {\n\t\tkv := strings.SplitN(pair, \"=\", 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"%s must be formatted as key=value\", pair)\n\t\t}\n\t\tvar err error\n\t\tout[kv[0]], err = strconv.ParseInt(kv[1], 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn out, nil\n}\n\n// GetStringToInt64 return the map[string]int64 value of a flag with the given name\nfunc (f *FlagSet) GetStringToInt64(name string) (map[string]int64, error) {\n\tval, err := f.getFlagType(name, \"stringToInt64\", stringToInt64Conv)\n\tif err != nil {\n\t\treturn map[string]int64{}, err\n\t}\n\treturn val.(map[string]int64), nil\n}\n\n// StringToInt64Var defines a string flag with specified name, default value, and usage string.\n// The argument p point64s to a map[string]int64 variable in which to store the values of the multiple flags.\n// The value of each argument will not try to be separated by comma\nfunc (f *FlagSet) StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) {\n\tf.VarP(newStringToInt64Value(value, p), name, \"\", usage)\n}\n\n// StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) {\n\tf.VarP(newStringToInt64Value(value, p), name, shorthand, usage)\n}\n\n// StringToInt64Var defines a string flag with specified name, default value, and usage string.\n// The argument p point64s to a map[string]int64 variable in which to store the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc StringToInt64Var(p *map[string]int64, name string, value map[string]int64, usage string) {\n\tCommandLine.VarP(newStringToInt64Value(value, p), name, \"\", usage)\n}\n\n// StringToInt64VarP is like StringToInt64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc StringToInt64VarP(p *map[string]int64, name, shorthand string, value map[string]int64, usage string) {\n\tCommandLine.VarP(newStringToInt64Value(value, p), name, shorthand, usage)\n}\n\n// StringToInt64 defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a map[string]int64 variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc (f *FlagSet) StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 {\n\tp := map[string]int64{}\n\tf.StringToInt64VarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 {\n\tp := map[string]int64{}\n\tf.StringToInt64VarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// StringToInt64 defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a map[string]int64 variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc StringToInt64(name string, value map[string]int64, usage string) *map[string]int64 {\n\treturn CommandLine.StringToInt64P(name, \"\", value, usage)\n}\n\n// StringToInt64P is like StringToInt64, but accepts a shorthand letter that can be used after a single dash.\nfunc StringToInt64P(name, shorthand string, value map[string]int64, usage string) *map[string]int64 {\n\treturn CommandLine.StringToInt64P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/string_to_string.go",
    "content": "package pflag\n\nimport (\n\t\"bytes\"\n\t\"encoding/csv\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// -- stringToString Value\ntype stringToStringValue struct {\n\tvalue   *map[string]string\n\tchanged bool\n}\n\nfunc newStringToStringValue(val map[string]string, p *map[string]string) *stringToStringValue {\n\tssv := new(stringToStringValue)\n\tssv.value = p\n\t*ssv.value = val\n\treturn ssv\n}\n\n// Format: a=1,b=2\nfunc (s *stringToStringValue) Set(val string) error {\n\tvar ss []string\n\tn := strings.Count(val, \"=\")\n\tswitch n {\n\tcase 0:\n\t\treturn fmt.Errorf(\"%s must be formatted as key=value\", val)\n\tcase 1:\n\t\tss = append(ss, strings.Trim(val, `\"`))\n\tdefault:\n\t\tr := csv.NewReader(strings.NewReader(val))\n\t\tvar err error\n\t\tss, err = r.Read()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tout := make(map[string]string, len(ss))\n\tfor _, pair := range ss {\n\t\tkv := strings.SplitN(pair, \"=\", 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn fmt.Errorf(\"%s must be formatted as key=value\", pair)\n\t\t}\n\t\tout[kv[0]] = kv[1]\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\tfor k, v := range out {\n\t\t\t(*s.value)[k] = v\n\t\t}\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *stringToStringValue) Type() string {\n\treturn \"stringToString\"\n}\n\nfunc (s *stringToStringValue) String() string {\n\trecords := make([]string, 0, len(*s.value)>>1)\n\tfor k, v := range *s.value {\n\t\trecords = append(records, k+\"=\"+v)\n\t}\n\n\tvar buf bytes.Buffer\n\tw := csv.NewWriter(&buf)\n\tif err := w.Write(records); err != nil {\n\t\tpanic(err)\n\t}\n\tw.Flush()\n\treturn \"[\" + strings.TrimSpace(buf.String()) + \"]\"\n}\n\nfunc stringToStringConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// An empty string would cause an empty map\n\tif len(val) == 0 {\n\t\treturn map[string]string{}, nil\n\t}\n\tr := csv.NewReader(strings.NewReader(val))\n\tss, err := r.Read()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout := make(map[string]string, len(ss))\n\tfor _, pair := range ss {\n\t\tkv := strings.SplitN(pair, \"=\", 2)\n\t\tif len(kv) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"%s must be formatted as key=value\", pair)\n\t\t}\n\t\tout[kv[0]] = kv[1]\n\t}\n\treturn out, nil\n}\n\n// GetStringToString return the map[string]string value of a flag with the given name\nfunc (f *FlagSet) GetStringToString(name string) (map[string]string, error) {\n\tval, err := f.getFlagType(name, \"stringToString\", stringToStringConv)\n\tif err != nil {\n\t\treturn map[string]string{}, err\n\t}\n\treturn val.(map[string]string), nil\n}\n\n// StringToStringVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a map[string]string variable in which to store the values of the multiple flags.\n// The value of each argument will not try to be separated by comma\nfunc (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) {\n\tf.VarP(newStringToStringValue(value, p), name, \"\", usage)\n}\n\n// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) {\n\tf.VarP(newStringToStringValue(value, p), name, shorthand, usage)\n}\n\n// StringToStringVar defines a string flag with specified name, default value, and usage string.\n// The argument p points to a map[string]string variable in which to store the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) {\n\tCommandLine.VarP(newStringToStringValue(value, p), name, \"\", usage)\n}\n\n// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash.\nfunc StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) {\n\tCommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage)\n}\n\n// StringToString defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a map[string]string variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc (f *FlagSet) StringToString(name string, value map[string]string, usage string) *map[string]string {\n\tp := map[string]string{}\n\tf.StringToStringVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string {\n\tp := map[string]string{}\n\tf.StringToStringVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// StringToString defines a string flag with specified name, default value, and usage string.\n// The return value is the address of a map[string]string variable that stores the value of the flag.\n// The value of each argument will not try to be separated by comma\nfunc StringToString(name string, value map[string]string, usage string) *map[string]string {\n\treturn CommandLine.StringToStringP(name, \"\", value, usage)\n}\n\n// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash.\nfunc StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string {\n\treturn CommandLine.StringToStringP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/uint.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- uint Value\ntype uintValue uint\n\nfunc newUintValue(val uint, p *uint) *uintValue {\n\t*p = val\n\treturn (*uintValue)(p)\n}\n\nfunc (i *uintValue) Set(s string) error {\n\tv, err := strconv.ParseUint(s, 0, 64)\n\t*i = uintValue(v)\n\treturn err\n}\n\nfunc (i *uintValue) Type() string {\n\treturn \"uint\"\n}\n\nfunc (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }\n\nfunc uintConv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseUint(sval, 0, 0)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint(v), nil\n}\n\n// GetUint return the uint value of a flag with the given name\nfunc (f *FlagSet) GetUint(name string) (uint, error) {\n\tval, err := f.getFlagType(name, \"uint\", uintConv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(uint), nil\n}\n\n// UintVar defines a uint flag with specified name, default value, and usage string.\n// The argument p points to a uint variable in which to store the value of the flag.\nfunc (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {\n\tf.VarP(newUintValue(value, p), name, \"\", usage)\n}\n\n// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) UintVarP(p *uint, name, shorthand string, value uint, usage string) {\n\tf.VarP(newUintValue(value, p), name, shorthand, usage)\n}\n\n// UintVar defines a uint flag with specified name, default value, and usage string.\n// The argument p points to a uint  variable in which to store the value of the flag.\nfunc UintVar(p *uint, name string, value uint, usage string) {\n\tCommandLine.VarP(newUintValue(value, p), name, \"\", usage)\n}\n\n// UintVarP is like UintVar, but accepts a shorthand letter that can be used after a single dash.\nfunc UintVarP(p *uint, name, shorthand string, value uint, usage string) {\n\tCommandLine.VarP(newUintValue(value, p), name, shorthand, usage)\n}\n\n// Uint defines a uint flag with specified name, default value, and usage string.\n// The return value is the address of a uint  variable that stores the value of the flag.\nfunc (f *FlagSet) Uint(name string, value uint, usage string) *uint {\n\tp := new(uint)\n\tf.UintVarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) UintP(name, shorthand string, value uint, usage string) *uint {\n\tp := new(uint)\n\tf.UintVarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Uint defines a uint flag with specified name, default value, and usage string.\n// The return value is the address of a uint  variable that stores the value of the flag.\nfunc Uint(name string, value uint, usage string) *uint {\n\treturn CommandLine.UintP(name, \"\", value, usage)\n}\n\n// UintP is like Uint, but accepts a shorthand letter that can be used after a single dash.\nfunc UintP(name, shorthand string, value uint, usage string) *uint {\n\treturn CommandLine.UintP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/uint16.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- uint16 value\ntype uint16Value uint16\n\nfunc newUint16Value(val uint16, p *uint16) *uint16Value {\n\t*p = val\n\treturn (*uint16Value)(p)\n}\n\nfunc (i *uint16Value) Set(s string) error {\n\tv, err := strconv.ParseUint(s, 0, 16)\n\t*i = uint16Value(v)\n\treturn err\n}\n\nfunc (i *uint16Value) Type() string {\n\treturn \"uint16\"\n}\n\nfunc (i *uint16Value) String() string { return strconv.FormatUint(uint64(*i), 10) }\n\nfunc uint16Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseUint(sval, 0, 16)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint16(v), nil\n}\n\n// GetUint16 return the uint16 value of a flag with the given name\nfunc (f *FlagSet) GetUint16(name string) (uint16, error) {\n\tval, err := f.getFlagType(name, \"uint16\", uint16Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(uint16), nil\n}\n\n// Uint16Var defines a uint flag with specified name, default value, and usage string.\n// The argument p points to a uint variable in which to store the value of the flag.\nfunc (f *FlagSet) Uint16Var(p *uint16, name string, value uint16, usage string) {\n\tf.VarP(newUint16Value(value, p), name, \"\", usage)\n}\n\n// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {\n\tf.VarP(newUint16Value(value, p), name, shorthand, usage)\n}\n\n// Uint16Var defines a uint flag with specified name, default value, and usage string.\n// The argument p points to a uint  variable in which to store the value of the flag.\nfunc Uint16Var(p *uint16, name string, value uint16, usage string) {\n\tCommandLine.VarP(newUint16Value(value, p), name, \"\", usage)\n}\n\n// Uint16VarP is like Uint16Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint16VarP(p *uint16, name, shorthand string, value uint16, usage string) {\n\tCommandLine.VarP(newUint16Value(value, p), name, shorthand, usage)\n}\n\n// Uint16 defines a uint flag with specified name, default value, and usage string.\n// The return value is the address of a uint  variable that stores the value of the flag.\nfunc (f *FlagSet) Uint16(name string, value uint16, usage string) *uint16 {\n\tp := new(uint16)\n\tf.Uint16VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint16P(name, shorthand string, value uint16, usage string) *uint16 {\n\tp := new(uint16)\n\tf.Uint16VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Uint16 defines a uint flag with specified name, default value, and usage string.\n// The return value is the address of a uint  variable that stores the value of the flag.\nfunc Uint16(name string, value uint16, usage string) *uint16 {\n\treturn CommandLine.Uint16P(name, \"\", value, usage)\n}\n\n// Uint16P is like Uint16, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint16P(name, shorthand string, value uint16, usage string) *uint16 {\n\treturn CommandLine.Uint16P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/uint32.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- uint32 value\ntype uint32Value uint32\n\nfunc newUint32Value(val uint32, p *uint32) *uint32Value {\n\t*p = val\n\treturn (*uint32Value)(p)\n}\n\nfunc (i *uint32Value) Set(s string) error {\n\tv, err := strconv.ParseUint(s, 0, 32)\n\t*i = uint32Value(v)\n\treturn err\n}\n\nfunc (i *uint32Value) Type() string {\n\treturn \"uint32\"\n}\n\nfunc (i *uint32Value) String() string { return strconv.FormatUint(uint64(*i), 10) }\n\nfunc uint32Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseUint(sval, 0, 32)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint32(v), nil\n}\n\n// GetUint32 return the uint32 value of a flag with the given name\nfunc (f *FlagSet) GetUint32(name string) (uint32, error) {\n\tval, err := f.getFlagType(name, \"uint32\", uint32Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(uint32), nil\n}\n\n// Uint32Var defines a uint32 flag with specified name, default value, and usage string.\n// The argument p points to a uint32 variable in which to store the value of the flag.\nfunc (f *FlagSet) Uint32Var(p *uint32, name string, value uint32, usage string) {\n\tf.VarP(newUint32Value(value, p), name, \"\", usage)\n}\n\n// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {\n\tf.VarP(newUint32Value(value, p), name, shorthand, usage)\n}\n\n// Uint32Var defines a uint32 flag with specified name, default value, and usage string.\n// The argument p points to a uint32  variable in which to store the value of the flag.\nfunc Uint32Var(p *uint32, name string, value uint32, usage string) {\n\tCommandLine.VarP(newUint32Value(value, p), name, \"\", usage)\n}\n\n// Uint32VarP is like Uint32Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint32VarP(p *uint32, name, shorthand string, value uint32, usage string) {\n\tCommandLine.VarP(newUint32Value(value, p), name, shorthand, usage)\n}\n\n// Uint32 defines a uint32 flag with specified name, default value, and usage string.\n// The return value is the address of a uint32  variable that stores the value of the flag.\nfunc (f *FlagSet) Uint32(name string, value uint32, usage string) *uint32 {\n\tp := new(uint32)\n\tf.Uint32VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint32P(name, shorthand string, value uint32, usage string) *uint32 {\n\tp := new(uint32)\n\tf.Uint32VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Uint32 defines a uint32 flag with specified name, default value, and usage string.\n// The return value is the address of a uint32  variable that stores the value of the flag.\nfunc Uint32(name string, value uint32, usage string) *uint32 {\n\treturn CommandLine.Uint32P(name, \"\", value, usage)\n}\n\n// Uint32P is like Uint32, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint32P(name, shorthand string, value uint32, usage string) *uint32 {\n\treturn CommandLine.Uint32P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/uint64.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- uint64 Value\ntype uint64Value uint64\n\nfunc newUint64Value(val uint64, p *uint64) *uint64Value {\n\t*p = val\n\treturn (*uint64Value)(p)\n}\n\nfunc (i *uint64Value) Set(s string) error {\n\tv, err := strconv.ParseUint(s, 0, 64)\n\t*i = uint64Value(v)\n\treturn err\n}\n\nfunc (i *uint64Value) Type() string {\n\treturn \"uint64\"\n}\n\nfunc (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }\n\nfunc uint64Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseUint(sval, 0, 64)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint64(v), nil\n}\n\n// GetUint64 return the uint64 value of a flag with the given name\nfunc (f *FlagSet) GetUint64(name string) (uint64, error) {\n\tval, err := f.getFlagType(name, \"uint64\", uint64Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(uint64), nil\n}\n\n// Uint64Var defines a uint64 flag with specified name, default value, and usage string.\n// The argument p points to a uint64 variable in which to store the value of the flag.\nfunc (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {\n\tf.VarP(newUint64Value(value, p), name, \"\", usage)\n}\n\n// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {\n\tf.VarP(newUint64Value(value, p), name, shorthand, usage)\n}\n\n// Uint64Var defines a uint64 flag with specified name, default value, and usage string.\n// The argument p points to a uint64 variable in which to store the value of the flag.\nfunc Uint64Var(p *uint64, name string, value uint64, usage string) {\n\tCommandLine.VarP(newUint64Value(value, p), name, \"\", usage)\n}\n\n// Uint64VarP is like Uint64Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint64VarP(p *uint64, name, shorthand string, value uint64, usage string) {\n\tCommandLine.VarP(newUint64Value(value, p), name, shorthand, usage)\n}\n\n// Uint64 defines a uint64 flag with specified name, default value, and usage string.\n// The return value is the address of a uint64 variable that stores the value of the flag.\nfunc (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {\n\tp := new(uint64)\n\tf.Uint64VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint64P(name, shorthand string, value uint64, usage string) *uint64 {\n\tp := new(uint64)\n\tf.Uint64VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Uint64 defines a uint64 flag with specified name, default value, and usage string.\n// The return value is the address of a uint64 variable that stores the value of the flag.\nfunc Uint64(name string, value uint64, usage string) *uint64 {\n\treturn CommandLine.Uint64P(name, \"\", value, usage)\n}\n\n// Uint64P is like Uint64, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint64P(name, shorthand string, value uint64, usage string) *uint64 {\n\treturn CommandLine.Uint64P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/uint8.go",
    "content": "package pflag\n\nimport \"strconv\"\n\n// -- uint8 Value\ntype uint8Value uint8\n\nfunc newUint8Value(val uint8, p *uint8) *uint8Value {\n\t*p = val\n\treturn (*uint8Value)(p)\n}\n\nfunc (i *uint8Value) Set(s string) error {\n\tv, err := strconv.ParseUint(s, 0, 8)\n\t*i = uint8Value(v)\n\treturn err\n}\n\nfunc (i *uint8Value) Type() string {\n\treturn \"uint8\"\n}\n\nfunc (i *uint8Value) String() string { return strconv.FormatUint(uint64(*i), 10) }\n\nfunc uint8Conv(sval string) (interface{}, error) {\n\tv, err := strconv.ParseUint(sval, 0, 8)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint8(v), nil\n}\n\n// GetUint8 return the uint8 value of a flag with the given name\nfunc (f *FlagSet) GetUint8(name string) (uint8, error) {\n\tval, err := f.getFlagType(name, \"uint8\", uint8Conv)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn val.(uint8), nil\n}\n\n// Uint8Var defines a uint8 flag with specified name, default value, and usage string.\n// The argument p points to a uint8 variable in which to store the value of the flag.\nfunc (f *FlagSet) Uint8Var(p *uint8, name string, value uint8, usage string) {\n\tf.VarP(newUint8Value(value, p), name, \"\", usage)\n}\n\n// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {\n\tf.VarP(newUint8Value(value, p), name, shorthand, usage)\n}\n\n// Uint8Var defines a uint8 flag with specified name, default value, and usage string.\n// The argument p points to a uint8 variable in which to store the value of the flag.\nfunc Uint8Var(p *uint8, name string, value uint8, usage string) {\n\tCommandLine.VarP(newUint8Value(value, p), name, \"\", usage)\n}\n\n// Uint8VarP is like Uint8Var, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint8VarP(p *uint8, name, shorthand string, value uint8, usage string) {\n\tCommandLine.VarP(newUint8Value(value, p), name, shorthand, usage)\n}\n\n// Uint8 defines a uint8 flag with specified name, default value, and usage string.\n// The return value is the address of a uint8 variable that stores the value of the flag.\nfunc (f *FlagSet) Uint8(name string, value uint8, usage string) *uint8 {\n\tp := new(uint8)\n\tf.Uint8VarP(p, name, \"\", value, usage)\n\treturn p\n}\n\n// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) Uint8P(name, shorthand string, value uint8, usage string) *uint8 {\n\tp := new(uint8)\n\tf.Uint8VarP(p, name, shorthand, value, usage)\n\treturn p\n}\n\n// Uint8 defines a uint8 flag with specified name, default value, and usage string.\n// The return value is the address of a uint8 variable that stores the value of the flag.\nfunc Uint8(name string, value uint8, usage string) *uint8 {\n\treturn CommandLine.Uint8P(name, \"\", value, usage)\n}\n\n// Uint8P is like Uint8, but accepts a shorthand letter that can be used after a single dash.\nfunc Uint8P(name, shorthand string, value uint8, usage string) *uint8 {\n\treturn CommandLine.Uint8P(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/spf13/pflag/uint_slice.go",
    "content": "package pflag\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// -- uintSlice Value\ntype uintSliceValue struct {\n\tvalue   *[]uint\n\tchanged bool\n}\n\nfunc newUintSliceValue(val []uint, p *[]uint) *uintSliceValue {\n\tuisv := new(uintSliceValue)\n\tuisv.value = p\n\t*uisv.value = val\n\treturn uisv\n}\n\nfunc (s *uintSliceValue) Set(val string) error {\n\tss := strings.Split(val, \",\")\n\tout := make([]uint, len(ss))\n\tfor i, d := range ss {\n\t\tu, err := strconv.ParseUint(d, 10, 0)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tout[i] = uint(u)\n\t}\n\tif !s.changed {\n\t\t*s.value = out\n\t} else {\n\t\t*s.value = append(*s.value, out...)\n\t}\n\ts.changed = true\n\treturn nil\n}\n\nfunc (s *uintSliceValue) Type() string {\n\treturn \"uintSlice\"\n}\n\nfunc (s *uintSliceValue) String() string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = fmt.Sprintf(\"%d\", d)\n\t}\n\treturn \"[\" + strings.Join(out, \",\") + \"]\"\n}\n\nfunc (s *uintSliceValue) fromString(val string) (uint, error) {\n\tt, err := strconv.ParseUint(val, 10, 0)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn uint(t), nil\n}\n\nfunc (s *uintSliceValue) toString(val uint) string {\n\treturn fmt.Sprintf(\"%d\", val)\n}\n\nfunc (s *uintSliceValue) Append(val string) error {\n\ti, err := s.fromString(val)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*s.value = append(*s.value, i)\n\treturn nil\n}\n\nfunc (s *uintSliceValue) Replace(val []string) error {\n\tout := make([]uint, len(val))\n\tfor i, d := range val {\n\t\tvar err error\n\t\tout[i], err = s.fromString(d)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\t*s.value = out\n\treturn nil\n}\n\nfunc (s *uintSliceValue) GetSlice() []string {\n\tout := make([]string, len(*s.value))\n\tfor i, d := range *s.value {\n\t\tout[i] = s.toString(d)\n\t}\n\treturn out\n}\n\nfunc uintSliceConv(val string) (interface{}, error) {\n\tval = strings.Trim(val, \"[]\")\n\t// Empty string would cause a slice with one (empty) entry\n\tif len(val) == 0 {\n\t\treturn []uint{}, nil\n\t}\n\tss := strings.Split(val, \",\")\n\tout := make([]uint, len(ss))\n\tfor i, d := range ss {\n\t\tu, err := strconv.ParseUint(d, 10, 0)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tout[i] = uint(u)\n\t}\n\treturn out, nil\n}\n\n// GetUintSlice returns the []uint value of a flag with the given name.\nfunc (f *FlagSet) GetUintSlice(name string) ([]uint, error) {\n\tval, err := f.getFlagType(name, \"uintSlice\", uintSliceConv)\n\tif err != nil {\n\t\treturn []uint{}, err\n\t}\n\treturn val.([]uint), nil\n}\n\n// UintSliceVar defines a uintSlice flag with specified name, default value, and usage string.\n// The argument p points to a []uint variable in which to store the value of the flag.\nfunc (f *FlagSet) UintSliceVar(p *[]uint, name string, value []uint, usage string) {\n\tf.VarP(newUintSliceValue(value, p), name, \"\", usage)\n}\n\n// UintSliceVarP is like UintSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {\n\tf.VarP(newUintSliceValue(value, p), name, shorthand, usage)\n}\n\n// UintSliceVar defines a uint[] flag with specified name, default value, and usage string.\n// The argument p points to a uint[] variable in which to store the value of the flag.\nfunc UintSliceVar(p *[]uint, name string, value []uint, usage string) {\n\tCommandLine.VarP(newUintSliceValue(value, p), name, \"\", usage)\n}\n\n// UintSliceVarP is like the UintSliceVar, but accepts a shorthand letter that can be used after a single dash.\nfunc UintSliceVarP(p *[]uint, name, shorthand string, value []uint, usage string) {\n\tCommandLine.VarP(newUintSliceValue(value, p), name, shorthand, usage)\n}\n\n// UintSlice defines a []uint flag with specified name, default value, and usage string.\n// The return value is the address of a []uint variable that stores the value of the flag.\nfunc (f *FlagSet) UintSlice(name string, value []uint, usage string) *[]uint {\n\tp := []uint{}\n\tf.UintSliceVarP(&p, name, \"\", value, usage)\n\treturn &p\n}\n\n// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc (f *FlagSet) UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {\n\tp := []uint{}\n\tf.UintSliceVarP(&p, name, shorthand, value, usage)\n\treturn &p\n}\n\n// UintSlice defines a []uint flag with specified name, default value, and usage string.\n// The return value is the address of a []uint variable that stores the value of the flag.\nfunc UintSlice(name string, value []uint, usage string) *[]uint {\n\treturn CommandLine.UintSliceP(name, \"\", value, usage)\n}\n\n// UintSliceP is like UintSlice, but accepts a shorthand letter that can be used after a single dash.\nfunc UintSliceP(name, shorthand string, value []uint, usage string) *[]uint {\n\treturn CommandLine.UintSliceP(name, shorthand, value, usage)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/LICENSE",
    "content": "MIT License\n\nCopyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors.\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": "vendor/github.com/stretchr/testify/assert/assertion_compare.go",
    "content": "package assert\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"time\"\n)\n\ntype CompareType int\n\nconst (\n\tcompareLess CompareType = iota - 1\n\tcompareEqual\n\tcompareGreater\n)\n\nvar (\n\tintType   = reflect.TypeOf(int(1))\n\tint8Type  = reflect.TypeOf(int8(1))\n\tint16Type = reflect.TypeOf(int16(1))\n\tint32Type = reflect.TypeOf(int32(1))\n\tint64Type = reflect.TypeOf(int64(1))\n\n\tuintType   = reflect.TypeOf(uint(1))\n\tuint8Type  = reflect.TypeOf(uint8(1))\n\tuint16Type = reflect.TypeOf(uint16(1))\n\tuint32Type = reflect.TypeOf(uint32(1))\n\tuint64Type = reflect.TypeOf(uint64(1))\n\n\tuintptrType = reflect.TypeOf(uintptr(1))\n\n\tfloat32Type = reflect.TypeOf(float32(1))\n\tfloat64Type = reflect.TypeOf(float64(1))\n\n\tstringType = reflect.TypeOf(\"\")\n\n\ttimeType  = reflect.TypeOf(time.Time{})\n\tbytesType = reflect.TypeOf([]byte{})\n)\n\nfunc compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) {\n\tobj1Value := reflect.ValueOf(obj1)\n\tobj2Value := reflect.ValueOf(obj2)\n\n\t// throughout this switch we try and avoid calling .Convert() if possible,\n\t// as this has a pretty big performance impact\n\tswitch kind {\n\tcase reflect.Int:\n\t\t{\n\t\t\tintobj1, ok := obj1.(int)\n\t\t\tif !ok {\n\t\t\t\tintobj1 = obj1Value.Convert(intType).Interface().(int)\n\t\t\t}\n\t\t\tintobj2, ok := obj2.(int)\n\t\t\tif !ok {\n\t\t\t\tintobj2 = obj2Value.Convert(intType).Interface().(int)\n\t\t\t}\n\t\t\tif intobj1 > intobj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif intobj1 == intobj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif intobj1 < intobj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int8:\n\t\t{\n\t\t\tint8obj1, ok := obj1.(int8)\n\t\t\tif !ok {\n\t\t\t\tint8obj1 = obj1Value.Convert(int8Type).Interface().(int8)\n\t\t\t}\n\t\t\tint8obj2, ok := obj2.(int8)\n\t\t\tif !ok {\n\t\t\t\tint8obj2 = obj2Value.Convert(int8Type).Interface().(int8)\n\t\t\t}\n\t\t\tif int8obj1 > int8obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int8obj1 == int8obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int8obj1 < int8obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int16:\n\t\t{\n\t\t\tint16obj1, ok := obj1.(int16)\n\t\t\tif !ok {\n\t\t\t\tint16obj1 = obj1Value.Convert(int16Type).Interface().(int16)\n\t\t\t}\n\t\t\tint16obj2, ok := obj2.(int16)\n\t\t\tif !ok {\n\t\t\t\tint16obj2 = obj2Value.Convert(int16Type).Interface().(int16)\n\t\t\t}\n\t\t\tif int16obj1 > int16obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int16obj1 == int16obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int16obj1 < int16obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int32:\n\t\t{\n\t\t\tint32obj1, ok := obj1.(int32)\n\t\t\tif !ok {\n\t\t\t\tint32obj1 = obj1Value.Convert(int32Type).Interface().(int32)\n\t\t\t}\n\t\t\tint32obj2, ok := obj2.(int32)\n\t\t\tif !ok {\n\t\t\t\tint32obj2 = obj2Value.Convert(int32Type).Interface().(int32)\n\t\t\t}\n\t\t\tif int32obj1 > int32obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int32obj1 == int32obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int32obj1 < int32obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Int64:\n\t\t{\n\t\t\tint64obj1, ok := obj1.(int64)\n\t\t\tif !ok {\n\t\t\t\tint64obj1 = obj1Value.Convert(int64Type).Interface().(int64)\n\t\t\t}\n\t\t\tint64obj2, ok := obj2.(int64)\n\t\t\tif !ok {\n\t\t\t\tint64obj2 = obj2Value.Convert(int64Type).Interface().(int64)\n\t\t\t}\n\t\t\tif int64obj1 > int64obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif int64obj1 == int64obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif int64obj1 < int64obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint:\n\t\t{\n\t\t\tuintobj1, ok := obj1.(uint)\n\t\t\tif !ok {\n\t\t\t\tuintobj1 = obj1Value.Convert(uintType).Interface().(uint)\n\t\t\t}\n\t\t\tuintobj2, ok := obj2.(uint)\n\t\t\tif !ok {\n\t\t\t\tuintobj2 = obj2Value.Convert(uintType).Interface().(uint)\n\t\t\t}\n\t\t\tif uintobj1 > uintobj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uintobj1 == uintobj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uintobj1 < uintobj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint8:\n\t\t{\n\t\t\tuint8obj1, ok := obj1.(uint8)\n\t\t\tif !ok {\n\t\t\t\tuint8obj1 = obj1Value.Convert(uint8Type).Interface().(uint8)\n\t\t\t}\n\t\t\tuint8obj2, ok := obj2.(uint8)\n\t\t\tif !ok {\n\t\t\t\tuint8obj2 = obj2Value.Convert(uint8Type).Interface().(uint8)\n\t\t\t}\n\t\t\tif uint8obj1 > uint8obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint8obj1 == uint8obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint8obj1 < uint8obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint16:\n\t\t{\n\t\t\tuint16obj1, ok := obj1.(uint16)\n\t\t\tif !ok {\n\t\t\t\tuint16obj1 = obj1Value.Convert(uint16Type).Interface().(uint16)\n\t\t\t}\n\t\t\tuint16obj2, ok := obj2.(uint16)\n\t\t\tif !ok {\n\t\t\t\tuint16obj2 = obj2Value.Convert(uint16Type).Interface().(uint16)\n\t\t\t}\n\t\t\tif uint16obj1 > uint16obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint16obj1 == uint16obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint16obj1 < uint16obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint32:\n\t\t{\n\t\t\tuint32obj1, ok := obj1.(uint32)\n\t\t\tif !ok {\n\t\t\t\tuint32obj1 = obj1Value.Convert(uint32Type).Interface().(uint32)\n\t\t\t}\n\t\t\tuint32obj2, ok := obj2.(uint32)\n\t\t\tif !ok {\n\t\t\t\tuint32obj2 = obj2Value.Convert(uint32Type).Interface().(uint32)\n\t\t\t}\n\t\t\tif uint32obj1 > uint32obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint32obj1 == uint32obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint32obj1 < uint32obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Uint64:\n\t\t{\n\t\t\tuint64obj1, ok := obj1.(uint64)\n\t\t\tif !ok {\n\t\t\t\tuint64obj1 = obj1Value.Convert(uint64Type).Interface().(uint64)\n\t\t\t}\n\t\t\tuint64obj2, ok := obj2.(uint64)\n\t\t\tif !ok {\n\t\t\t\tuint64obj2 = obj2Value.Convert(uint64Type).Interface().(uint64)\n\t\t\t}\n\t\t\tif uint64obj1 > uint64obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uint64obj1 == uint64obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uint64obj1 < uint64obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Float32:\n\t\t{\n\t\t\tfloat32obj1, ok := obj1.(float32)\n\t\t\tif !ok {\n\t\t\t\tfloat32obj1 = obj1Value.Convert(float32Type).Interface().(float32)\n\t\t\t}\n\t\t\tfloat32obj2, ok := obj2.(float32)\n\t\t\tif !ok {\n\t\t\t\tfloat32obj2 = obj2Value.Convert(float32Type).Interface().(float32)\n\t\t\t}\n\t\t\tif float32obj1 > float32obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif float32obj1 == float32obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif float32obj1 < float32obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.Float64:\n\t\t{\n\t\t\tfloat64obj1, ok := obj1.(float64)\n\t\t\tif !ok {\n\t\t\t\tfloat64obj1 = obj1Value.Convert(float64Type).Interface().(float64)\n\t\t\t}\n\t\t\tfloat64obj2, ok := obj2.(float64)\n\t\t\tif !ok {\n\t\t\t\tfloat64obj2 = obj2Value.Convert(float64Type).Interface().(float64)\n\t\t\t}\n\t\t\tif float64obj1 > float64obj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif float64obj1 == float64obj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif float64obj1 < float64obj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\tcase reflect.String:\n\t\t{\n\t\t\tstringobj1, ok := obj1.(string)\n\t\t\tif !ok {\n\t\t\t\tstringobj1 = obj1Value.Convert(stringType).Interface().(string)\n\t\t\t}\n\t\t\tstringobj2, ok := obj2.(string)\n\t\t\tif !ok {\n\t\t\t\tstringobj2 = obj2Value.Convert(stringType).Interface().(string)\n\t\t\t}\n\t\t\tif stringobj1 > stringobj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif stringobj1 == stringobj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif stringobj1 < stringobj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\t// Check for known struct types we can check for compare results.\n\tcase reflect.Struct:\n\t\t{\n\t\t\t// All structs enter here. We're not interested in most types.\n\t\t\tif !obj1Value.CanConvert(timeType) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// time.Time can be compared!\n\t\t\ttimeObj1, ok := obj1.(time.Time)\n\t\t\tif !ok {\n\t\t\t\ttimeObj1 = obj1Value.Convert(timeType).Interface().(time.Time)\n\t\t\t}\n\n\t\t\ttimeObj2, ok := obj2.(time.Time)\n\t\t\tif !ok {\n\t\t\t\ttimeObj2 = obj2Value.Convert(timeType).Interface().(time.Time)\n\t\t\t}\n\n\t\t\treturn compare(timeObj1.UnixNano(), timeObj2.UnixNano(), reflect.Int64)\n\t\t}\n\tcase reflect.Slice:\n\t\t{\n\t\t\t// We only care about the []byte type.\n\t\t\tif !obj1Value.CanConvert(bytesType) {\n\t\t\t\tbreak\n\t\t\t}\n\n\t\t\t// []byte can be compared!\n\t\t\tbytesObj1, ok := obj1.([]byte)\n\t\t\tif !ok {\n\t\t\t\tbytesObj1 = obj1Value.Convert(bytesType).Interface().([]byte)\n\n\t\t\t}\n\t\t\tbytesObj2, ok := obj2.([]byte)\n\t\t\tif !ok {\n\t\t\t\tbytesObj2 = obj2Value.Convert(bytesType).Interface().([]byte)\n\t\t\t}\n\n\t\t\treturn CompareType(bytes.Compare(bytesObj1, bytesObj2)), true\n\t\t}\n\tcase reflect.Uintptr:\n\t\t{\n\t\t\tuintptrObj1, ok := obj1.(uintptr)\n\t\t\tif !ok {\n\t\t\t\tuintptrObj1 = obj1Value.Convert(uintptrType).Interface().(uintptr)\n\t\t\t}\n\t\t\tuintptrObj2, ok := obj2.(uintptr)\n\t\t\tif !ok {\n\t\t\t\tuintptrObj2 = obj2Value.Convert(uintptrType).Interface().(uintptr)\n\t\t\t}\n\t\t\tif uintptrObj1 > uintptrObj2 {\n\t\t\t\treturn compareGreater, true\n\t\t\t}\n\t\t\tif uintptrObj1 == uintptrObj2 {\n\t\t\t\treturn compareEqual, true\n\t\t\t}\n\t\t\tif uintptrObj1 < uintptrObj2 {\n\t\t\t\treturn compareLess, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn compareEqual, false\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\tassert.Greater(t, 2, 1)\n//\tassert.Greater(t, float64(2), float64(1))\n//\tassert.Greater(t, \"b\", \"a\")\nfunc Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn compareTwoValues(t, e1, e2, []CompareType{compareGreater}, \"\\\"%v\\\" is not greater than \\\"%v\\\"\", msgAndArgs...)\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\tassert.GreaterOrEqual(t, 2, 1)\n//\tassert.GreaterOrEqual(t, 2, 2)\n//\tassert.GreaterOrEqual(t, \"b\", \"a\")\n//\tassert.GreaterOrEqual(t, \"b\", \"b\")\nfunc GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn compareTwoValues(t, e1, e2, []CompareType{compareGreater, compareEqual}, \"\\\"%v\\\" is not greater than or equal to \\\"%v\\\"\", msgAndArgs...)\n}\n\n// Less asserts that the first element is less than the second\n//\n//\tassert.Less(t, 1, 2)\n//\tassert.Less(t, float64(1), float64(2))\n//\tassert.Less(t, \"a\", \"b\")\nfunc Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn compareTwoValues(t, e1, e2, []CompareType{compareLess}, \"\\\"%v\\\" is not less than \\\"%v\\\"\", msgAndArgs...)\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\tassert.LessOrEqual(t, 1, 2)\n//\tassert.LessOrEqual(t, 2, 2)\n//\tassert.LessOrEqual(t, \"a\", \"b\")\n//\tassert.LessOrEqual(t, \"b\", \"b\")\nfunc LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, \"\\\"%v\\\" is not less than or equal to \\\"%v\\\"\", msgAndArgs...)\n}\n\n// Positive asserts that the specified element is positive\n//\n//\tassert.Positive(t, 1)\n//\tassert.Positive(t, 1.23)\nfunc Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tzero := reflect.Zero(reflect.TypeOf(e))\n\treturn compareTwoValues(t, e, zero.Interface(), []CompareType{compareGreater}, \"\\\"%v\\\" is not positive\", msgAndArgs...)\n}\n\n// Negative asserts that the specified element is negative\n//\n//\tassert.Negative(t, -1)\n//\tassert.Negative(t, -1.23)\nfunc Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tzero := reflect.Zero(reflect.TypeOf(e))\n\treturn compareTwoValues(t, e, zero.Interface(), []CompareType{compareLess}, \"\\\"%v\\\" is not negative\", msgAndArgs...)\n}\n\nfunc compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\te1Kind := reflect.ValueOf(e1).Kind()\n\te2Kind := reflect.ValueOf(e2).Kind()\n\tif e1Kind != e2Kind {\n\t\treturn Fail(t, \"Elements should be the same type\", msgAndArgs...)\n\t}\n\n\tcompareResult, isComparable := compare(e1, e2, e1Kind)\n\tif !isComparable {\n\t\treturn Fail(t, fmt.Sprintf(\"Can not compare type \\\"%s\\\"\", reflect.TypeOf(e1)), msgAndArgs...)\n\t}\n\n\tif !containsValue(allowedComparesResults, compareResult) {\n\t\treturn Fail(t, fmt.Sprintf(failMessage, e1, e2), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\nfunc containsValue(values []CompareType, value CompareType) bool {\n\tfor _, v := range values {\n\t\tif v == value {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_format.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage assert\n\nimport (\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Condition(t, comp, append([]interface{}{msg}, args...)...)\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\tassert.Containsf(t, \"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\tassert.Containsf(t, [\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\tassert.Containsf(t, {\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Contains(t, s, contains, append([]interface{}{msg}, args...)...)\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn DirExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)\n}\n\n// Emptyf asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tassert.Emptyf(t, obj, \"error message %s\", \"formatted\")\nfunc Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Empty(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\tassert.Equalf(t, 123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Equal(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.EqualErrorf(t, err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualExportedValues(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\tassert.EqualValuesf(t, uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.Errorf(t, err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedErrorf, err)\n//\t  }\nfunc Errorf(t TestingT, err error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Error(t, err, append([]interface{}{msg}, args...)...)\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorAs(t, err, target, append([]interface{}{msg}, args...)...)\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.ErrorContainsf(t, err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorContains(t, theError, contains, append([]interface{}{msg}, args...)...)\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorIs(t, err, target, append([]interface{}{msg}, args...)...)\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\tassert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\tassert.EventuallyWithTf(t, func(c *assert.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EventuallyWithT(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\tassert.Exactlyf(t, int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Failf reports a failure through\nfunc Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, failureMessage, append([]interface{}{msg}, args...)...)\n}\n\n// FailNowf fails test\nfunc FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\tassert.Falsef(t, myBool, \"error message %s\", \"formatted\")\nfunc Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn False(t, value, append([]interface{}{msg}, args...)...)\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FileExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\tassert.Greaterf(t, 2, 1, \"error message %s\", \"formatted\")\n//\tassert.Greaterf(t, float64(2), float64(1), \"error message %s\", \"formatted\")\n//\tassert.Greaterf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\nfunc Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Greater(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\tassert.GreaterOrEqualf(t, 2, 1, \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn GreaterOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\tassert.HTTPBodyContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\tassert.HTTPBodyNotContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\tassert.HTTPErrorf(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\tassert.HTTPRedirectf(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\tassert.HTTPStatusCodef(t, myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPStatusCode(t, handler, method, url, values, statuscode, append([]interface{}{msg}, args...)...)\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\tassert.HTTPSuccessf(t, myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\tassert.Implementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\tassert.InDeltaf(t, math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\tassert.IsDecreasingf(t, []int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\tassert.IsDecreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsDecreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsDecreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\tassert.IsIncreasingf(t, []int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\tassert.IsIncreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsIncreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsIncreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\tassert.IsNonDecreasingf(t, []int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsNonDecreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsNonDecreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonDecreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\tassert.IsNonIncreasingf(t, []int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsNonIncreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsNonIncreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonIncreasing(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// IsTypef asserts that the specified objects are of the same type.\nfunc IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\tassert.JSONEqf(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\tassert.Lenf(t, mySlice, 3, \"error message %s\", \"formatted\")\nfunc Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Len(t, object, length, append([]interface{}{msg}, args...)...)\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\tassert.Lessf(t, 1, 2, \"error message %s\", \"formatted\")\n//\tassert.Lessf(t, float64(1), float64(2), \"error message %s\", \"formatted\")\n//\tassert.Lessf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\nfunc Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Less(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\tassert.LessOrEqualf(t, 1, 2, \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...)\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\tassert.Negativef(t, -1, \"error message %s\", \"formatted\")\n//\tassert.Negativef(t, -1.23, \"error message %s\", \"formatted\")\nfunc Negativef(t TestingT, e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Negative(t, e, append([]interface{}{msg}, args...)...)\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\tassert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Never(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...)\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\tassert.Nilf(t, err, \"error message %s\", \"formatted\")\nfunc Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Nil(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoDirExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.NoErrorf(t, err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoError(t, err, append([]interface{}{msg}, args...)...)\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoFileExists(t, path, append([]interface{}{msg}, args...)...)\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\tassert.NotContainsf(t, \"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\tassert.NotContainsf(t, [\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\tassert.NotContainsf(t, {\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotContains(t, s, contains, append([]interface{}{msg}, args...)...)\n}\n\n// NotEmptyf asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif assert.NotEmptyf(t, obj, \"error message %s\", \"formatted\") {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEmpty(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\tassert.NotEqualf(t, obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\tassert.NotEqualValuesf(t, obj1, obj2, \"error message %s\", \"formatted\")\nfunc NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// NotErrorIsf asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorIs(t, err, target, append([]interface{}{msg}, args...)...)\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\tassert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotImplements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\tassert.NotNilf(t, err, \"error message %s\", \"formatted\")\nfunc NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotNil(t, object, append([]interface{}{msg}, args...)...)\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\tassert.NotPanicsf(t, func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotPanics(t, f, append([]interface{}{msg}, args...)...)\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\tassert.NotRegexpf(t, regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\tassert.NotRegexpf(t, \"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\tassert.NotSamef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSame(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// NotSubsetf asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\tassert.NotSubsetf(t, [1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\tassert.NotSubsetf(t, {\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\nfunc NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotZero(t, i, append([]interface{}{msg}, args...)...)\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\tassert.Panicsf(t, func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Panics(t, f, append([]interface{}{msg}, args...)...)\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\tassert.PanicsWithErrorf(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithError(t, errString, f, append([]interface{}{msg}, args...)...)\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\tassert.PanicsWithValuef(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\tassert.Positivef(t, 1, \"error message %s\", \"formatted\")\n//\tassert.Positivef(t, 1.23, \"error message %s\", \"formatted\")\nfunc Positivef(t TestingT, e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Positive(t, e, append([]interface{}{msg}, args...)...)\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\tassert.Regexpf(t, regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\tassert.Regexpf(t, \"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Regexp(t, rx, str, append([]interface{}{msg}, args...)...)\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\tassert.Samef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Same(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Subsetf asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\tassert.Subsetf(t, [1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\tassert.Subsetf(t, {\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\nfunc Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Subset(t, list, subset, append([]interface{}{msg}, args...)...)\n}\n\n// Truef asserts that the specified value is true.\n//\n//\tassert.Truef(t, myBool, \"error message %s\", \"formatted\")\nfunc Truef(t TestingT, value bool, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn True(t, value, append([]interface{}{msg}, args...)...)\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\tassert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\tassert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...)\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn YAMLEq(t, expected, actual, append([]interface{}{msg}, args...)...)\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Zero(t, i, append([]interface{}{msg}, args...)...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl",
    "content": "{{.CommentFormat}}\nfunc {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {\n\tif h, ok := t.(tHelper); ok { h.Helper() }\n\treturn {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_forward.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage assert\n\nimport (\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Condition uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Condition(a.t, comp, msgAndArgs...)\n}\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Conditionf(a.t, comp, msg, args...)\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Contains(\"Hello World\", \"World\")\n//\ta.Contains([\"Hello\", \"World\"], \"World\")\n//\ta.Contains({\"Hello\": \"World\"}, \"Hello\")\nfunc (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Contains(a.t, s, contains, msgAndArgs...)\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Containsf(\"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf([\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf({\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Containsf(a.t, s, contains, msg, args...)\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn DirExists(a.t, path, msgAndArgs...)\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn DirExistsf(a.t, path, msg, args...)\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])\nfunc (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ElementsMatch(a.t, listA, listB, msgAndArgs...)\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ElementsMatchf(a.t, listA, listB, msg, args...)\n}\n\n// Empty asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\ta.Empty(obj)\nfunc (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Empty(a.t, object, msgAndArgs...)\n}\n\n// Emptyf asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\ta.Emptyf(obj, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Emptyf(a.t, object, msg, args...)\n}\n\n// Equal asserts that two objects are equal.\n//\n//\ta.Equal(123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Equal(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualError(err,  expectedErrorString)\nfunc (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualError(a.t, theError, errString, msgAndArgs...)\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualErrorf(err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualErrorf(a.t, theError, errString, msg, args...)\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValues(S{1, 2}, S{1, 3}) => true\n//\t a.EqualExportedValues(S{1, 2}, S{2, 3}) => false\nfunc (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualExportedValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValuesf(S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t a.EqualExportedValuesf(S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualExportedValuesf(a.t, expected, actual, msg, args...)\n}\n\n// EqualValues asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\ta.EqualValues(uint32(123), int32(123))\nfunc (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\ta.EqualValuesf(uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\ta.Equalf(123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Equalf(a.t, expected, actual, msg, args...)\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.Error(err) {\n//\t\t   assert.Equal(t, expectedError, err)\n//\t  }\nfunc (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Error(a.t, err, msgAndArgs...)\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorAs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorAsf(a.t, err, target, msg, args...)\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContains(err,  expectedErrorSubString)\nfunc (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorContains(a.t, theError, contains, msgAndArgs...)\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContainsf(err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorContainsf(a.t, theError, contains, msg, args...)\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn ErrorIsf(a.t, err, target, msg, args...)\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.Errorf(err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedErrorf, err)\n//\t  }\nfunc (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Errorf(a.t, err, msg, args...)\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Eventually(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithT(func(c *assert.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithTf(func(c *assert.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn EventuallyWithTf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Eventuallyf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\ta.Exactly(int32(123), int64(123))\nfunc (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Exactly(a.t, expected, actual, msgAndArgs...)\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\ta.Exactlyf(int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Exactlyf(a.t, expected, actual, msg, args...)\n}\n\n// Fail reports a failure through\nfunc (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNow fails test\nfunc (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FailNow(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNowf fails test\nfunc (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FailNowf(a.t, failureMessage, msg, args...)\n}\n\n// Failf reports a failure through\nfunc (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Failf(a.t, failureMessage, msg, args...)\n}\n\n// False asserts that the specified value is false.\n//\n//\ta.False(myBool)\nfunc (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn False(a.t, value, msgAndArgs...)\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\ta.Falsef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Falsef(a.t, value, msg, args...)\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FileExists(a.t, path, msgAndArgs...)\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn FileExistsf(a.t, path, msg, args...)\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\ta.Greater(2, 1)\n//\ta.Greater(float64(2), float64(1))\n//\ta.Greater(\"b\", \"a\")\nfunc (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Greater(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqual(2, 1)\n//\ta.GreaterOrEqual(2, 2)\n//\ta.GreaterOrEqual(\"b\", \"a\")\n//\ta.GreaterOrEqual(\"b\", \"b\")\nfunc (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn GreaterOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqualf(2, 1, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"a\", \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn GreaterOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\ta.Greaterf(2, 1, \"error message %s\", \"formatted\")\n//\ta.Greaterf(float64(2), float64(1), \"error message %s\", \"formatted\")\n//\ta.Greaterf(\"b\", \"a\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Greaterf(a.t, e1, e2, msg, args...)\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPError(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPError(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPErrorf(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPErrorf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirect(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirectf(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPRedirectf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCode(myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPStatusCode(a.t, handler, method, url, values, statuscode, msgAndArgs...)\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCodef(myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPStatusCodef(a.t, handler, method, url, values, statuscode, msg, args...)\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccess(myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccessf(myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn HTTPSuccessf(a.t, handler, method, url, values, msg, args...)\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\ta.Implements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Implements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\ta.Implementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Implementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\ta.InDelta(math.Pi, 22/7.0, 0.01)\nfunc (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDelta(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaSlicef(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\ta.InDeltaf(math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InDeltaf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn InEpsilonf(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\ta.IsDecreasing([]int{2, 1, 0})\n//\ta.IsDecreasing([]float{2, 1})\n//\ta.IsDecreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\ta.IsDecreasingf([]int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsDecreasingf(a.t, object, msg, args...)\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\ta.IsIncreasing([]int{1, 2, 3})\n//\ta.IsIncreasing([]float{1, 2})\n//\ta.IsIncreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\ta.IsIncreasingf([]int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsIncreasingf(a.t, object, msg, args...)\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasing([]int{1, 1, 2})\n//\ta.IsNonDecreasing([]float{1, 2})\n//\ta.IsNonDecreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasingf([]int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonDecreasingf(a.t, object, msg, args...)\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasing([]int{2, 1, 1})\n//\ta.IsNonIncreasing([]float{2, 1})\n//\ta.IsNonIncreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasingf([]int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsNonIncreasingf(a.t, object, msg, args...)\n}\n\n// IsType asserts that the specified objects are of the same type.\nfunc (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsType(a.t, expectedType, object, msgAndArgs...)\n}\n\n// IsTypef asserts that the specified objects are of the same type.\nfunc (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn IsTypef(a.t, expectedType, object, msg, args...)\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEq(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn JSONEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEqf(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn JSONEqf(a.t, expected, actual, msg, args...)\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\ta.Len(mySlice, 3)\nfunc (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Len(a.t, object, length, msgAndArgs...)\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\ta.Lenf(mySlice, 3, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Lenf(a.t, object, length, msg, args...)\n}\n\n// Less asserts that the first element is less than the second\n//\n//\ta.Less(1, 2)\n//\ta.Less(float64(1), float64(2))\n//\ta.Less(\"a\", \"b\")\nfunc (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Less(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqual(1, 2)\n//\ta.LessOrEqual(2, 2)\n//\ta.LessOrEqual(\"a\", \"b\")\n//\ta.LessOrEqual(\"b\", \"b\")\nfunc (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn LessOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqualf(1, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"a\", \"b\", \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn LessOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\ta.Lessf(1, 2, \"error message %s\", \"formatted\")\n//\ta.Lessf(float64(1), float64(2), \"error message %s\", \"formatted\")\n//\ta.Lessf(\"a\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Lessf(a.t, e1, e2, msg, args...)\n}\n\n// Negative asserts that the specified element is negative\n//\n//\ta.Negative(-1)\n//\ta.Negative(-1.23)\nfunc (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Negative(a.t, e, msgAndArgs...)\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\ta.Negativef(-1, \"error message %s\", \"formatted\")\n//\ta.Negativef(-1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Negativef(a.t, e, msg, args...)\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Never(func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Never(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Neverf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\ta.Nil(err)\nfunc (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Nil(a.t, object, msgAndArgs...)\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\ta.Nilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Nilf(a.t, object, msg, args...)\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoDirExists(a.t, path, msgAndArgs...)\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoDirExistsf(a.t, path, msg, args...)\n}\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoError(err) {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoError(a.t, err, msgAndArgs...)\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoErrorf(err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoErrorf(a.t, err, msg, args...)\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoFileExists(a.t, path, msgAndArgs...)\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NoFileExistsf(a.t, path, msg, args...)\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContains(\"Hello World\", \"Earth\")\n//\ta.NotContains([\"Hello\", \"World\"], \"Earth\")\n//\ta.NotContains({\"Hello\": \"World\"}, \"Earth\")\nfunc (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotContains(a.t, s, contains, msgAndArgs...)\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContainsf(\"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf([\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf({\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotContainsf(a.t, s, contains, msg, args...)\n}\n\n// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif a.NotEmpty(obj) {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEmpty(a.t, object, msgAndArgs...)\n}\n\n// NotEmptyf asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif a.NotEmptyf(obj, \"error message %s\", \"formatted\") {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEmptyf(a.t, object, msg, args...)\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\ta.NotEqual(obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqual(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValues(obj1, obj2)\nfunc (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValuesf(obj1, obj2, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\ta.NotEqualf(obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotEqualf(a.t, expected, actual, msg, args...)\n}\n\n// NotErrorIs asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// NotErrorIsf asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotErrorIsf(a.t, err, target, msg, args...)\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotImplements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotImplementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\ta.NotNil(err)\nfunc (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotNil(a.t, object, msgAndArgs...)\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\ta.NotNilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotNilf(a.t, object, msg, args...)\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanics(func(){ RemainCalm() })\nfunc (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotPanics(a.t, f, msgAndArgs...)\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanicsf(func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotPanicsf(a.t, f, msg, args...)\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexp(regexp.MustCompile(\"starts\"), \"it's starting\")\n//\ta.NotRegexp(\"^start\", \"it's not starting\")\nfunc (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotRegexp(a.t, rx, str, msgAndArgs...)\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexpf(regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.NotRegexpf(\"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotRegexpf(a.t, rx, str, msg, args...)\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\ta.NotSame(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSame(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\ta.NotSamef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSamef(a.t, expected, actual, msg, args...)\n}\n\n// NotSubset asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\ta.NotSubset([1, 3, 4], [1, 2])\n//\ta.NotSubset({\"x\": 1, \"y\": 2}, {\"z\": 3})\nfunc (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSubset(a.t, list, subset, msgAndArgs...)\n}\n\n// NotSubsetf asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\ta.NotSubsetf([1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\ta.NotSubsetf({\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotSubsetf(a.t, list, subset, msg, args...)\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotZero(a.t, i, msgAndArgs...)\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn NotZerof(a.t, i, msg, args...)\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panics(func(){ GoCrazy() })\nfunc (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Panics(a.t, f, msgAndArgs...)\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithError(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithError(a.t, errString, f, msgAndArgs...)\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithErrorf(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithErrorf(a.t, errString, f, msg, args...)\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValue(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithValue(a.t, expected, f, msgAndArgs...)\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValuef(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn PanicsWithValuef(a.t, expected, f, msg, args...)\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panicsf(func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Panicsf(a.t, f, msg, args...)\n}\n\n// Positive asserts that the specified element is positive\n//\n//\ta.Positive(1)\n//\ta.Positive(1.23)\nfunc (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Positive(a.t, e, msgAndArgs...)\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\ta.Positivef(1, \"error message %s\", \"formatted\")\n//\ta.Positivef(1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Positivef(a.t, e, msg, args...)\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\ta.Regexp(regexp.MustCompile(\"start\"), \"it's starting\")\n//\ta.Regexp(\"start...$\", \"it's not starting\")\nfunc (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Regexp(a.t, rx, str, msgAndArgs...)\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\ta.Regexpf(regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.Regexpf(\"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Regexpf(a.t, rx, str, msg, args...)\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\ta.Same(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Same(a.t, expected, actual, msgAndArgs...)\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\ta.Samef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Samef(a.t, expected, actual, msg, args...)\n}\n\n// Subset asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\ta.Subset([1, 2, 3], [1, 2])\n//\ta.Subset({\"x\": 1, \"y\": 2}, {\"x\": 1})\nfunc (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Subset(a.t, list, subset, msgAndArgs...)\n}\n\n// Subsetf asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\ta.Subsetf([1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\ta.Subsetf({\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Subsetf(a.t, list, subset, msg, args...)\n}\n\n// True asserts that the specified value is true.\n//\n//\ta.True(myBool)\nfunc (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn True(a.t, value, msgAndArgs...)\n}\n\n// Truef asserts that the specified value is true.\n//\n//\ta.Truef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Truef(a.t, value, msg, args...)\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDuration(time.Now(), time.Now(), 10*time.Second)\nfunc (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinDuration(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDurationf(time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinDurationf(a.t, expected, actual, delta, msg, args...)\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinRange(a.t, actual, start, end, msgAndArgs...)\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn WithinRangef(a.t, actual, start, end, msg, args...)\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn YAMLEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn YAMLEqf(a.t, expected, actual, msg, args...)\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Zero(a.t, i, msgAndArgs...)\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Zerof(a.t, i, msg, args...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl",
    "content": "{{.CommentWithoutT \"a\"}}\nfunc (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {\n\tif h, ok := a.t.(tHelper); ok { h.Helper() }\n\treturn {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertion_order.go",
    "content": "package assert\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\n// isOrdered checks that collection contains orderable elements.\nfunc isOrdered(t TestingT, object interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool {\n\tobjKind := reflect.TypeOf(object).Kind()\n\tif objKind != reflect.Slice && objKind != reflect.Array {\n\t\treturn false\n\t}\n\n\tobjValue := reflect.ValueOf(object)\n\tobjLen := objValue.Len()\n\n\tif objLen <= 1 {\n\t\treturn true\n\t}\n\n\tvalue := objValue.Index(0)\n\tvalueInterface := value.Interface()\n\tfirstValueKind := value.Kind()\n\n\tfor i := 1; i < objLen; i++ {\n\t\tprevValue := value\n\t\tprevValueInterface := valueInterface\n\n\t\tvalue = objValue.Index(i)\n\t\tvalueInterface = value.Interface()\n\n\t\tcompareResult, isComparable := compare(prevValueInterface, valueInterface, firstValueKind)\n\n\t\tif !isComparable {\n\t\t\treturn Fail(t, fmt.Sprintf(\"Can not compare type \\\"%s\\\" and \\\"%s\\\"\", reflect.TypeOf(value), reflect.TypeOf(prevValue)), msgAndArgs...)\n\t\t}\n\n\t\tif !containsValue(allowedComparesResults, compareResult) {\n\t\t\treturn Fail(t, fmt.Sprintf(failMessage, prevValue, value), msgAndArgs...)\n\t\t}\n\t}\n\n\treturn true\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\tassert.IsIncreasing(t, []int{1, 2, 3})\n//\tassert.IsIncreasing(t, []float{1, 2})\n//\tassert.IsIncreasing(t, []string{\"a\", \"b\"})\nfunc IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []CompareType{compareLess}, \"\\\"%v\\\" is not less than \\\"%v\\\"\", msgAndArgs...)\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\tassert.IsNonIncreasing(t, []int{2, 1, 1})\n//\tassert.IsNonIncreasing(t, []float{2, 1})\n//\tassert.IsNonIncreasing(t, []string{\"b\", \"a\"})\nfunc IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []CompareType{compareEqual, compareGreater}, \"\\\"%v\\\" is not greater than or equal to \\\"%v\\\"\", msgAndArgs...)\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\tassert.IsDecreasing(t, []int{2, 1, 0})\n//\tassert.IsDecreasing(t, []float{2, 1})\n//\tassert.IsDecreasing(t, []string{\"b\", \"a\"})\nfunc IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []CompareType{compareGreater}, \"\\\"%v\\\" is not greater than \\\"%v\\\"\", msgAndArgs...)\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\tassert.IsNonDecreasing(t, []int{1, 1, 2})\n//\tassert.IsNonDecreasing(t, []float{1, 2})\n//\tassert.IsNonDecreasing(t, []string{\"a\", \"b\"})\nfunc IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\treturn isOrdered(t, object, []CompareType{compareLess, compareEqual}, \"\\\"%v\\\" is not less than or equal to \\\"%v\\\"\", msgAndArgs...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/assertions.go",
    "content": "package assert\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"os\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"github.com/davecgh/go-spew/spew\"\n\t\"github.com/pmezard/go-difflib/difflib\"\n\t\"gopkg.in/yaml.v3\"\n)\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl\"\n\n// TestingT is an interface wrapper around *testing.T\ntype TestingT interface {\n\tErrorf(format string, args ...interface{})\n}\n\n// ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful\n// for table driven tests.\ntype ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool\n\n// ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful\n// for table driven tests.\ntype ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool\n\n// BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful\n// for table driven tests.\ntype BoolAssertionFunc func(TestingT, bool, ...interface{}) bool\n\n// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful\n// for table driven tests.\ntype ErrorAssertionFunc func(TestingT, error, ...interface{}) bool\n\n// Comparison is a custom function that returns true on success and false on failure\ntype Comparison func() (success bool)\n\n/*\n\tHelper functions\n*/\n\n// ObjectsAreEqual determines if two objects are considered equal.\n//\n// This function does no assertion of any kind.\nfunc ObjectsAreEqual(expected, actual interface{}) bool {\n\tif expected == nil || actual == nil {\n\t\treturn expected == actual\n\t}\n\n\texp, ok := expected.([]byte)\n\tif !ok {\n\t\treturn reflect.DeepEqual(expected, actual)\n\t}\n\n\tact, ok := actual.([]byte)\n\tif !ok {\n\t\treturn false\n\t}\n\tif exp == nil || act == nil {\n\t\treturn exp == nil && act == nil\n\t}\n\treturn bytes.Equal(exp, act)\n}\n\n// copyExportedFields iterates downward through nested data structures and creates a copy\n// that only contains the exported struct fields.\nfunc copyExportedFields(expected interface{}) interface{} {\n\tif isNil(expected) {\n\t\treturn expected\n\t}\n\n\texpectedType := reflect.TypeOf(expected)\n\texpectedKind := expectedType.Kind()\n\texpectedValue := reflect.ValueOf(expected)\n\n\tswitch expectedKind {\n\tcase reflect.Struct:\n\t\tresult := reflect.New(expectedType).Elem()\n\t\tfor i := 0; i < expectedType.NumField(); i++ {\n\t\t\tfield := expectedType.Field(i)\n\t\t\tisExported := field.IsExported()\n\t\t\tif isExported {\n\t\t\t\tfieldValue := expectedValue.Field(i)\n\t\t\t\tif isNil(fieldValue) || isNil(fieldValue.Interface()) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tnewValue := copyExportedFields(fieldValue.Interface())\n\t\t\t\tresult.Field(i).Set(reflect.ValueOf(newValue))\n\t\t\t}\n\t\t}\n\t\treturn result.Interface()\n\n\tcase reflect.Ptr:\n\t\tresult := reflect.New(expectedType.Elem())\n\t\tunexportedRemoved := copyExportedFields(expectedValue.Elem().Interface())\n\t\tresult.Elem().Set(reflect.ValueOf(unexportedRemoved))\n\t\treturn result.Interface()\n\n\tcase reflect.Array, reflect.Slice:\n\t\tvar result reflect.Value\n\t\tif expectedKind == reflect.Array {\n\t\t\tresult = reflect.New(reflect.ArrayOf(expectedValue.Len(), expectedType.Elem())).Elem()\n\t\t} else {\n\t\t\tresult = reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len())\n\t\t}\n\t\tfor i := 0; i < expectedValue.Len(); i++ {\n\t\t\tindex := expectedValue.Index(i)\n\t\t\tif isNil(index) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tunexportedRemoved := copyExportedFields(index.Interface())\n\t\t\tresult.Index(i).Set(reflect.ValueOf(unexportedRemoved))\n\t\t}\n\t\treturn result.Interface()\n\n\tcase reflect.Map:\n\t\tresult := reflect.MakeMap(expectedType)\n\t\tfor _, k := range expectedValue.MapKeys() {\n\t\t\tindex := expectedValue.MapIndex(k)\n\t\t\tunexportedRemoved := copyExportedFields(index.Interface())\n\t\t\tresult.SetMapIndex(k, reflect.ValueOf(unexportedRemoved))\n\t\t}\n\t\treturn result.Interface()\n\n\tdefault:\n\t\treturn expected\n\t}\n}\n\n// ObjectsExportedFieldsAreEqual determines if the exported (public) fields of two objects are\n// considered equal. This comparison of only exported fields is applied recursively to nested data\n// structures.\n//\n// This function does no assertion of any kind.\n//\n// Deprecated: Use [EqualExportedValues] instead.\nfunc ObjectsExportedFieldsAreEqual(expected, actual interface{}) bool {\n\texpectedCleaned := copyExportedFields(expected)\n\tactualCleaned := copyExportedFields(actual)\n\treturn ObjectsAreEqualValues(expectedCleaned, actualCleaned)\n}\n\n// ObjectsAreEqualValues gets whether two objects are equal, or if their\n// values are equal.\nfunc ObjectsAreEqualValues(expected, actual interface{}) bool {\n\tif ObjectsAreEqual(expected, actual) {\n\t\treturn true\n\t}\n\n\texpectedValue := reflect.ValueOf(expected)\n\tactualValue := reflect.ValueOf(actual)\n\tif !expectedValue.IsValid() || !actualValue.IsValid() {\n\t\treturn false\n\t}\n\n\texpectedType := expectedValue.Type()\n\tactualType := actualValue.Type()\n\tif !expectedType.ConvertibleTo(actualType) {\n\t\treturn false\n\t}\n\n\tif !isNumericType(expectedType) || !isNumericType(actualType) {\n\t\t// Attempt comparison after type conversion\n\t\treturn reflect.DeepEqual(\n\t\t\texpectedValue.Convert(actualType).Interface(), actual,\n\t\t)\n\t}\n\n\t// If BOTH values are numeric, there are chances of false positives due\n\t// to overflow or underflow. So, we need to make sure to always convert\n\t// the smaller type to a larger type before comparing.\n\tif expectedType.Size() >= actualType.Size() {\n\t\treturn actualValue.Convert(expectedType).Interface() == expected\n\t}\n\n\treturn expectedValue.Convert(actualType).Interface() == actual\n}\n\n// isNumericType returns true if the type is one of:\n// int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64,\n// float32, float64, complex64, complex128\nfunc isNumericType(t reflect.Type) bool {\n\treturn t.Kind() >= reflect.Int && t.Kind() <= reflect.Complex128\n}\n\n/* CallerInfo is necessary because the assert functions use the testing object\ninternally, causing it to print the file:line of the assert method, rather than where\nthe problem actually occurred in calling code.*/\n\n// CallerInfo returns an array of strings containing the file and line number\n// of each stack frame leading from the current test to the assert call that\n// failed.\nfunc CallerInfo() []string {\n\n\tvar pc uintptr\n\tvar ok bool\n\tvar file string\n\tvar line int\n\tvar name string\n\n\tcallers := []string{}\n\tfor i := 0; ; i++ {\n\t\tpc, file, line, ok = runtime.Caller(i)\n\t\tif !ok {\n\t\t\t// The breaks below failed to terminate the loop, and we ran off the\n\t\t\t// end of the call stack.\n\t\t\tbreak\n\t\t}\n\n\t\t// This is a huge edge case, but it will panic if this is the case, see #180\n\t\tif file == \"<autogenerated>\" {\n\t\t\tbreak\n\t\t}\n\n\t\tf := runtime.FuncForPC(pc)\n\t\tif f == nil {\n\t\t\tbreak\n\t\t}\n\t\tname = f.Name()\n\n\t\t// testing.tRunner is the standard library function that calls\n\t\t// tests. Subtests are called directly by tRunner, without going through\n\t\t// the Test/Benchmark/Example function that contains the t.Run calls, so\n\t\t// with subtests we should break when we hit tRunner, without adding it\n\t\t// to the list of callers.\n\t\tif name == \"testing.tRunner\" {\n\t\t\tbreak\n\t\t}\n\n\t\tparts := strings.Split(file, \"/\")\n\t\tif len(parts) > 1 {\n\t\t\tfilename := parts[len(parts)-1]\n\t\t\tdir := parts[len(parts)-2]\n\t\t\tif (dir != \"assert\" && dir != \"mock\" && dir != \"require\") || filename == \"mock_test.go\" {\n\t\t\t\tcallers = append(callers, fmt.Sprintf(\"%s:%d\", file, line))\n\t\t\t}\n\t\t}\n\n\t\t// Drop the package\n\t\tsegments := strings.Split(name, \".\")\n\t\tname = segments[len(segments)-1]\n\t\tif isTest(name, \"Test\") ||\n\t\t\tisTest(name, \"Benchmark\") ||\n\t\t\tisTest(name, \"Example\") {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn callers\n}\n\n// Stolen from the `go test` tool.\n// isTest tells whether name looks like a test (or benchmark, according to prefix).\n// It is a Test (say) if there is a character after Test that is not a lower-case letter.\n// We don't want TesticularCancer.\nfunc isTest(name, prefix string) bool {\n\tif !strings.HasPrefix(name, prefix) {\n\t\treturn false\n\t}\n\tif len(name) == len(prefix) { // \"Test\" is ok\n\t\treturn true\n\t}\n\tr, _ := utf8.DecodeRuneInString(name[len(prefix):])\n\treturn !unicode.IsLower(r)\n}\n\nfunc messageFromMsgAndArgs(msgAndArgs ...interface{}) string {\n\tif len(msgAndArgs) == 0 || msgAndArgs == nil {\n\t\treturn \"\"\n\t}\n\tif len(msgAndArgs) == 1 {\n\t\tmsg := msgAndArgs[0]\n\t\tif msgAsStr, ok := msg.(string); ok {\n\t\t\treturn msgAsStr\n\t\t}\n\t\treturn fmt.Sprintf(\"%+v\", msg)\n\t}\n\tif len(msgAndArgs) > 1 {\n\t\treturn fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)\n\t}\n\treturn \"\"\n}\n\n// Aligns the provided message so that all lines after the first line start at the same location as the first line.\n// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab).\n// The longestLabelLen parameter specifies the length of the longest label in the output (required because this is the\n// basis on which the alignment occurs).\nfunc indentMessageLines(message string, longestLabelLen int) string {\n\toutBuf := new(bytes.Buffer)\n\n\tfor i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ {\n\t\t// no need to align first line because it starts at the correct location (after the label)\n\t\tif i != 0 {\n\t\t\t// append alignLen+1 spaces to align with \"{{longestLabel}}:\" before adding tab\n\t\t\toutBuf.WriteString(\"\\n\\t\" + strings.Repeat(\" \", longestLabelLen+1) + \"\\t\")\n\t\t}\n\t\toutBuf.WriteString(scanner.Text())\n\t}\n\n\treturn outBuf.String()\n}\n\ntype failNower interface {\n\tFailNow()\n}\n\n// FailNow fails test\nfunc FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFail(t, failureMessage, msgAndArgs...)\n\n\t// We cannot extend TestingT with FailNow() and\n\t// maintain backwards compatibility, so we fallback\n\t// to panicking when FailNow is not available in\n\t// TestingT.\n\t// See issue #263\n\n\tif t, ok := t.(failNower); ok {\n\t\tt.FailNow()\n\t} else {\n\t\tpanic(\"test failed and t is missing `FailNow()`\")\n\t}\n\treturn false\n}\n\n// Fail reports a failure through\nfunc Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcontent := []labeledContent{\n\t\t{\"Error Trace\", strings.Join(CallerInfo(), \"\\n\\t\\t\\t\")},\n\t\t{\"Error\", failureMessage},\n\t}\n\n\t// Add test name if the Go version supports it\n\tif n, ok := t.(interface {\n\t\tName() string\n\t}); ok {\n\t\tcontent = append(content, labeledContent{\"Test\", n.Name()})\n\t}\n\n\tmessage := messageFromMsgAndArgs(msgAndArgs...)\n\tif len(message) > 0 {\n\t\tcontent = append(content, labeledContent{\"Messages\", message})\n\t}\n\n\tt.Errorf(\"\\n%s\", \"\"+labeledOutput(content...))\n\n\treturn false\n}\n\ntype labeledContent struct {\n\tlabel   string\n\tcontent string\n}\n\n// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:\n//\n//\t\\t{{label}}:{{align_spaces}}\\t{{content}}\\n\n//\n// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The \"\\t{{label}}:\" is for the label.\n// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this\n// alignment is achieved, \"\\t{{content}}\\n\" is added for the output.\n//\n// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line.\nfunc labeledOutput(content ...labeledContent) string {\n\tlongestLabel := 0\n\tfor _, v := range content {\n\t\tif len(v.label) > longestLabel {\n\t\t\tlongestLabel = len(v.label)\n\t\t}\n\t}\n\tvar output string\n\tfor _, v := range content {\n\t\toutput += \"\\t\" + v.label + \":\" + strings.Repeat(\" \", longestLabel-len(v.label)) + \"\\t\" + indentMessageLines(v.content, longestLabel) + \"\\n\"\n\t}\n\treturn output\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\tassert.Implements(t, (*MyInterface)(nil), new(MyObject))\nfunc Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinterfaceType := reflect.TypeOf(interfaceObject).Elem()\n\n\tif object == nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Cannot check if nil implements %v\", interfaceType), msgAndArgs...)\n\t}\n\tif !reflect.TypeOf(object).Implements(interfaceType) {\n\t\treturn Fail(t, fmt.Sprintf(\"%T must implement %v\", object, interfaceType), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\tassert.NotImplements(t, (*MyInterface)(nil), new(MyObject))\nfunc NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinterfaceType := reflect.TypeOf(interfaceObject).Elem()\n\n\tif object == nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Cannot check if nil does not implement %v\", interfaceType), msgAndArgs...)\n\t}\n\tif reflect.TypeOf(object).Implements(interfaceType) {\n\t\treturn Fail(t, fmt.Sprintf(\"%T implements %v\", object, interfaceType), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// IsType asserts that the specified objects are of the same type.\nfunc IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {\n\t\treturn Fail(t, fmt.Sprintf(\"Object expected to be of type %v, but was %v\", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// Equal asserts that two objects are equal.\n//\n//\tassert.Equal(t, 123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif err := validateEqualArgs(expected, actual); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Invalid operation: %#v == %#v (%s)\",\n\t\t\texpected, actual, err), msgAndArgs...)\n\t}\n\n\tif !ObjectsAreEqual(expected, actual) {\n\t\tdiff := diff(expected, actual)\n\t\texpected, actual = formatUnequalValues(expected, actual)\n\t\treturn Fail(t, fmt.Sprintf(\"Not equal: \\n\"+\n\t\t\t\"expected: %s\\n\"+\n\t\t\t\"actual  : %s%s\", expected, actual, diff), msgAndArgs...)\n\t}\n\n\treturn true\n\n}\n\n// validateEqualArgs checks whether provided arguments can be safely used in the\n// Equal/NotEqual functions.\nfunc validateEqualArgs(expected, actual interface{}) error {\n\tif expected == nil && actual == nil {\n\t\treturn nil\n\t}\n\n\tif isFunction(expected) || isFunction(actual) {\n\t\treturn errors.New(\"cannot take func type as argument\")\n\t}\n\treturn nil\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\tassert.Same(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif !samePointers(expected, actual) {\n\t\treturn Fail(t, fmt.Sprintf(\"Not same: \\n\"+\n\t\t\t\"expected: %p %#v\\n\"+\n\t\t\t\"actual  : %p %#v\", expected, expected, actual, actual), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\tassert.NotSame(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif samePointers(expected, actual) {\n\t\treturn Fail(t, fmt.Sprintf(\n\t\t\t\"Expected and actual point to the same object: %p %#v\",\n\t\t\texpected, expected), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// samePointers compares two generic interface objects and returns whether\n// they point to the same object\nfunc samePointers(first, second interface{}) bool {\n\tfirstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second)\n\tif firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr {\n\t\treturn false\n\t}\n\n\tfirstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second)\n\tif firstType != secondType {\n\t\treturn false\n\t}\n\n\t// compare pointer addresses\n\treturn first == second\n}\n\n// formatUnequalValues takes two values of arbitrary types and returns string\n// representations appropriate to be presented to the user.\n//\n// If the values are not of like type, the returned strings will be prefixed\n// with the type name, and the value will be enclosed in parentheses similar\n// to a type conversion in the Go grammar.\nfunc formatUnequalValues(expected, actual interface{}) (e string, a string) {\n\tif reflect.TypeOf(expected) != reflect.TypeOf(actual) {\n\t\treturn fmt.Sprintf(\"%T(%s)\", expected, truncatingFormat(expected)),\n\t\t\tfmt.Sprintf(\"%T(%s)\", actual, truncatingFormat(actual))\n\t}\n\tswitch expected.(type) {\n\tcase time.Duration:\n\t\treturn fmt.Sprintf(\"%v\", expected), fmt.Sprintf(\"%v\", actual)\n\t}\n\treturn truncatingFormat(expected), truncatingFormat(actual)\n}\n\n// truncatingFormat formats the data and truncates it if it's too long.\n//\n// This helps keep formatted error messages lines from exceeding the\n// bufio.MaxScanTokenSize max line length that the go testing framework imposes.\nfunc truncatingFormat(data interface{}) string {\n\tvalue := fmt.Sprintf(\"%#v\", data)\n\tmax := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed.\n\tif len(value) > max {\n\t\tvalue = value[0:max] + \"<... truncated>\"\n\t}\n\treturn value\n}\n\n// EqualValues asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\tassert.EqualValues(t, uint32(123), int32(123))\nfunc EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif !ObjectsAreEqualValues(expected, actual) {\n\t\tdiff := diff(expected, actual)\n\t\texpected, actual = formatUnequalValues(expected, actual)\n\t\treturn Fail(t, fmt.Sprintf(\"Not equal: \\n\"+\n\t\t\t\"expected: %s\\n\"+\n\t\t\t\"actual  : %s%s\", expected, actual, diff), msgAndArgs...)\n\t}\n\n\treturn true\n\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true\n//\t assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false\nfunc EqualExportedValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\taType := reflect.TypeOf(expected)\n\tbType := reflect.TypeOf(actual)\n\n\tif aType != bType {\n\t\treturn Fail(t, fmt.Sprintf(\"Types expected to match exactly\\n\\t%v != %v\", aType, bType), msgAndArgs...)\n\t}\n\n\tif aType.Kind() == reflect.Ptr {\n\t\taType = aType.Elem()\n\t}\n\tif bType.Kind() == reflect.Ptr {\n\t\tbType = bType.Elem()\n\t}\n\n\tif aType.Kind() != reflect.Struct {\n\t\treturn Fail(t, fmt.Sprintf(\"Types expected to both be struct or pointer to struct \\n\\t%v != %v\", aType.Kind(), reflect.Struct), msgAndArgs...)\n\t}\n\n\tif bType.Kind() != reflect.Struct {\n\t\treturn Fail(t, fmt.Sprintf(\"Types expected to both be struct or pointer to struct \\n\\t%v != %v\", bType.Kind(), reflect.Struct), msgAndArgs...)\n\t}\n\n\texpected = copyExportedFields(expected)\n\tactual = copyExportedFields(actual)\n\n\tif !ObjectsAreEqualValues(expected, actual) {\n\t\tdiff := diff(expected, actual)\n\t\texpected, actual = formatUnequalValues(expected, actual)\n\t\treturn Fail(t, fmt.Sprintf(\"Not equal (comparing only exported fields): \\n\"+\n\t\t\t\"expected: %s\\n\"+\n\t\t\t\"actual  : %s%s\", expected, actual, diff), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\tassert.Exactly(t, int32(123), int64(123))\nfunc Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\taType := reflect.TypeOf(expected)\n\tbType := reflect.TypeOf(actual)\n\n\tif aType != bType {\n\t\treturn Fail(t, fmt.Sprintf(\"Types expected to match exactly\\n\\t%v != %v\", aType, bType), msgAndArgs...)\n\t}\n\n\treturn Equal(t, expected, actual, msgAndArgs...)\n\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\tassert.NotNil(t, err)\nfunc NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tif !isNil(object) {\n\t\treturn true\n\t}\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, \"Expected value not to be nil.\", msgAndArgs...)\n}\n\n// isNil checks if a specified object is nil or not, without Failing.\nfunc isNil(object interface{}) bool {\n\tif object == nil {\n\t\treturn true\n\t}\n\n\tvalue := reflect.ValueOf(object)\n\tswitch value.Kind() {\n\tcase\n\t\treflect.Chan, reflect.Func,\n\t\treflect.Interface, reflect.Map,\n\t\treflect.Ptr, reflect.Slice, reflect.UnsafePointer:\n\n\t\treturn value.IsNil()\n\t}\n\n\treturn false\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\tassert.Nil(t, err)\nfunc Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tif isNil(object) {\n\t\treturn true\n\t}\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\treturn Fail(t, fmt.Sprintf(\"Expected nil, but got: %#v\", object), msgAndArgs...)\n}\n\n// isEmpty gets whether the specified object is considered empty or not.\nfunc isEmpty(object interface{}) bool {\n\n\t// get nil case out of the way\n\tif object == nil {\n\t\treturn true\n\t}\n\n\tobjValue := reflect.ValueOf(object)\n\n\tswitch objValue.Kind() {\n\t// collection types are empty when they have no element\n\tcase reflect.Chan, reflect.Map, reflect.Slice:\n\t\treturn objValue.Len() == 0\n\t// pointers are empty if nil or if the value they point to is empty\n\tcase reflect.Ptr:\n\t\tif objValue.IsNil() {\n\t\t\treturn true\n\t\t}\n\t\tderef := objValue.Elem().Interface()\n\t\treturn isEmpty(deref)\n\t// for all other types, compare against the zero value\n\t// array types are empty when they match their zero-initialized state\n\tdefault:\n\t\tzero := reflect.Zero(objValue.Type())\n\t\treturn reflect.DeepEqual(object, zero.Interface())\n\t}\n}\n\n// Empty asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tassert.Empty(t, obj)\nfunc Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tpass := isEmpty(object)\n\tif !pass {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\tFail(t, fmt.Sprintf(\"Should be empty, but was %v\", object), msgAndArgs...)\n\t}\n\n\treturn pass\n\n}\n\n// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif assert.NotEmpty(t, obj) {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {\n\tpass := !isEmpty(object)\n\tif !pass {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\tFail(t, fmt.Sprintf(\"Should NOT be empty, but was %v\", object), msgAndArgs...)\n\t}\n\n\treturn pass\n\n}\n\n// getLen tries to get the length of an object.\n// It returns (0, false) if impossible.\nfunc getLen(x interface{}) (length int, ok bool) {\n\tv := reflect.ValueOf(x)\n\tdefer func() {\n\t\tok = recover() == nil\n\t}()\n\treturn v.Len(), true\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\tassert.Len(t, mySlice, 3)\nfunc Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tl, ok := getLen(object)\n\tif !ok {\n\t\treturn Fail(t, fmt.Sprintf(\"\\\"%v\\\" could not be applied builtin len()\", object), msgAndArgs...)\n\t}\n\n\tif l != length {\n\t\treturn Fail(t, fmt.Sprintf(\"\\\"%v\\\" should have %d item(s), but has %d\", object, length, l), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// True asserts that the specified value is true.\n//\n//\tassert.True(t, myBool)\nfunc True(t TestingT, value bool, msgAndArgs ...interface{}) bool {\n\tif !value {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, \"Should be true\", msgAndArgs...)\n\t}\n\n\treturn true\n\n}\n\n// False asserts that the specified value is false.\n//\n//\tassert.False(t, myBool)\nfunc False(t TestingT, value bool, msgAndArgs ...interface{}) bool {\n\tif value {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, \"Should be false\", msgAndArgs...)\n\t}\n\n\treturn true\n\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\tassert.NotEqual(t, obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif err := validateEqualArgs(expected, actual); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Invalid operation: %#v != %#v (%s)\",\n\t\t\texpected, actual, err), msgAndArgs...)\n\t}\n\n\tif ObjectsAreEqual(expected, actual) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should not be: %#v\\n\", actual), msgAndArgs...)\n\t}\n\n\treturn true\n\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\tassert.NotEqualValues(t, obj1, obj2)\nfunc NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif ObjectsAreEqualValues(expected, actual) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should not be: %#v\\n\", actual), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// containsElement try loop over the list check if the list includes the element.\n// return (false, false) if impossible.\n// return (true, false) if element was not found.\n// return (true, true) if element was found.\nfunc containsElement(list interface{}, element interface{}) (ok, found bool) {\n\n\tlistValue := reflect.ValueOf(list)\n\tlistType := reflect.TypeOf(list)\n\tif listType == nil {\n\t\treturn false, false\n\t}\n\tlistKind := listType.Kind()\n\tdefer func() {\n\t\tif e := recover(); e != nil {\n\t\t\tok = false\n\t\t\tfound = false\n\t\t}\n\t}()\n\n\tif listKind == reflect.String {\n\t\telementValue := reflect.ValueOf(element)\n\t\treturn true, strings.Contains(listValue.String(), elementValue.String())\n\t}\n\n\tif listKind == reflect.Map {\n\t\tmapKeys := listValue.MapKeys()\n\t\tfor i := 0; i < len(mapKeys); i++ {\n\t\t\tif ObjectsAreEqual(mapKeys[i].Interface(), element) {\n\t\t\t\treturn true, true\n\t\t\t}\n\t\t}\n\t\treturn true, false\n\t}\n\n\tfor i := 0; i < listValue.Len(); i++ {\n\t\tif ObjectsAreEqual(listValue.Index(i).Interface(), element) {\n\t\t\treturn true, true\n\t\t}\n\t}\n\treturn true, false\n\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\tassert.Contains(t, \"Hello World\", \"World\")\n//\tassert.Contains(t, [\"Hello\", \"World\"], \"World\")\n//\tassert.Contains(t, {\"Hello\": \"World\"}, \"Hello\")\nfunc Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tok, found := containsElement(s, contains)\n\tif !ok {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v could not be applied builtin len()\", s), msgAndArgs...)\n\t}\n\tif !found {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", s, contains), msgAndArgs...)\n\t}\n\n\treturn true\n\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\tassert.NotContains(t, \"Hello World\", \"Earth\")\n//\tassert.NotContains(t, [\"Hello\", \"World\"], \"Earth\")\n//\tassert.NotContains(t, {\"Hello\": \"World\"}, \"Earth\")\nfunc NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tok, found := containsElement(s, contains)\n\tif !ok {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v could not be applied builtin len()\", s), msgAndArgs...)\n\t}\n\tif found {\n\t\treturn Fail(t, fmt.Sprintf(\"%#v should not contain %#v\", s, contains), msgAndArgs...)\n\t}\n\n\treturn true\n\n}\n\n// Subset asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\tassert.Subset(t, [1, 2, 3], [1, 2])\n//\tassert.Subset(t, {\"x\": 1, \"y\": 2}, {\"x\": 1})\nfunc Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif subset == nil {\n\t\treturn true // we consider nil to be equal to the nil set\n\t}\n\n\tlistKind := reflect.TypeOf(list).Kind()\n\tif listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", list, listKind), msgAndArgs...)\n\t}\n\n\tsubsetKind := reflect.TypeOf(subset).Kind()\n\tif subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", subset, subsetKind), msgAndArgs...)\n\t}\n\n\tif subsetKind == reflect.Map && listKind == reflect.Map {\n\t\tsubsetMap := reflect.ValueOf(subset)\n\t\tactualMap := reflect.ValueOf(list)\n\n\t\tfor _, k := range subsetMap.MapKeys() {\n\t\t\tev := subsetMap.MapIndex(k)\n\t\t\tav := actualMap.MapIndex(k)\n\n\t\t\tif !av.IsValid() {\n\t\t\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", list, subset), msgAndArgs...)\n\t\t\t}\n\t\t\tif !ObjectsAreEqual(ev.Interface(), av.Interface()) {\n\t\t\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", list, subset), msgAndArgs...)\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t}\n\n\tsubsetList := reflect.ValueOf(subset)\n\tfor i := 0; i < subsetList.Len(); i++ {\n\t\telement := subsetList.Index(i).Interface()\n\t\tok, found := containsElement(list, element)\n\t\tif !ok {\n\t\t\treturn Fail(t, fmt.Sprintf(\"%#v could not be applied builtin len()\", list), msgAndArgs...)\n\t\t}\n\t\tif !found {\n\t\t\treturn Fail(t, fmt.Sprintf(\"%#v does not contain %#v\", list, element), msgAndArgs...)\n\t\t}\n\t}\n\n\treturn true\n}\n\n// NotSubset asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\tassert.NotSubset(t, [1, 3, 4], [1, 2])\n//\tassert.NotSubset(t, {\"x\": 1, \"y\": 2}, {\"z\": 3})\nfunc NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif subset == nil {\n\t\treturn Fail(t, \"nil is the empty set which is a subset of every set\", msgAndArgs...)\n\t}\n\n\tlistKind := reflect.TypeOf(list).Kind()\n\tif listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", list, listKind), msgAndArgs...)\n\t}\n\n\tsubsetKind := reflect.TypeOf(subset).Kind()\n\tif subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s\", subset, subsetKind), msgAndArgs...)\n\t}\n\n\tif subsetKind == reflect.Map && listKind == reflect.Map {\n\t\tsubsetMap := reflect.ValueOf(subset)\n\t\tactualMap := reflect.ValueOf(list)\n\n\t\tfor _, k := range subsetMap.MapKeys() {\n\t\t\tev := subsetMap.MapIndex(k)\n\t\t\tav := actualMap.MapIndex(k)\n\n\t\t\tif !av.IsValid() {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif !ObjectsAreEqual(ev.Interface(), av.Interface()) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\n\t\treturn Fail(t, fmt.Sprintf(\"%q is a subset of %q\", subset, list), msgAndArgs...)\n\t}\n\n\tsubsetList := reflect.ValueOf(subset)\n\tfor i := 0; i < subsetList.Len(); i++ {\n\t\telement := subsetList.Index(i).Interface()\n\t\tok, found := containsElement(list, element)\n\t\tif !ok {\n\t\t\treturn Fail(t, fmt.Sprintf(\"\\\"%s\\\" could not be applied builtin len()\", list), msgAndArgs...)\n\t\t}\n\t\tif !found {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn Fail(t, fmt.Sprintf(\"%q is a subset of %q\", subset, list), msgAndArgs...)\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])\nfunc ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif isEmpty(listA) && isEmpty(listB) {\n\t\treturn true\n\t}\n\n\tif !isList(t, listA, msgAndArgs...) || !isList(t, listB, msgAndArgs...) {\n\t\treturn false\n\t}\n\n\textraA, extraB := diffLists(listA, listB)\n\n\tif len(extraA) == 0 && len(extraB) == 0 {\n\t\treturn true\n\t}\n\n\treturn Fail(t, formatListDiff(listA, listB, extraA, extraB), msgAndArgs...)\n}\n\n// isList checks that the provided value is array or slice.\nfunc isList(t TestingT, list interface{}, msgAndArgs ...interface{}) (ok bool) {\n\tkind := reflect.TypeOf(list).Kind()\n\tif kind != reflect.Array && kind != reflect.Slice {\n\t\treturn Fail(t, fmt.Sprintf(\"%q has an unsupported type %s, expecting array or slice\", list, kind),\n\t\t\tmsgAndArgs...)\n\t}\n\treturn true\n}\n\n// diffLists diffs two arrays/slices and returns slices of elements that are only in A and only in B.\n// If some element is present multiple times, each instance is counted separately (e.g. if something is 2x in A and\n// 5x in B, it will be 0x in extraA and 3x in extraB). The order of items in both lists is ignored.\nfunc diffLists(listA, listB interface{}) (extraA, extraB []interface{}) {\n\taValue := reflect.ValueOf(listA)\n\tbValue := reflect.ValueOf(listB)\n\n\taLen := aValue.Len()\n\tbLen := bValue.Len()\n\n\t// Mark indexes in bValue that we already used\n\tvisited := make([]bool, bLen)\n\tfor i := 0; i < aLen; i++ {\n\t\telement := aValue.Index(i).Interface()\n\t\tfound := false\n\t\tfor j := 0; j < bLen; j++ {\n\t\t\tif visited[j] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif ObjectsAreEqual(bValue.Index(j).Interface(), element) {\n\t\t\t\tvisited[j] = true\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\textraA = append(extraA, element)\n\t\t}\n\t}\n\n\tfor j := 0; j < bLen; j++ {\n\t\tif visited[j] {\n\t\t\tcontinue\n\t\t}\n\t\textraB = append(extraB, bValue.Index(j).Interface())\n\t}\n\n\treturn\n}\n\nfunc formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) string {\n\tvar msg bytes.Buffer\n\n\tmsg.WriteString(\"elements differ\")\n\tif len(extraA) > 0 {\n\t\tmsg.WriteString(\"\\n\\nextra elements in list A:\\n\")\n\t\tmsg.WriteString(spewConfig.Sdump(extraA))\n\t}\n\tif len(extraB) > 0 {\n\t\tmsg.WriteString(\"\\n\\nextra elements in list B:\\n\")\n\t\tmsg.WriteString(spewConfig.Sdump(extraB))\n\t}\n\tmsg.WriteString(\"\\n\\nlistA:\\n\")\n\tmsg.WriteString(spewConfig.Sdump(listA))\n\tmsg.WriteString(\"\\n\\nlistB:\\n\")\n\tmsg.WriteString(spewConfig.Sdump(listB))\n\n\treturn msg.String()\n}\n\n// Condition uses a Comparison to assert a complex condition.\nfunc Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tresult := comp()\n\tif !result {\n\t\tFail(t, \"Condition failed!\", msgAndArgs...)\n\t}\n\treturn result\n}\n\n// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics\n// methods, and represents a simple func that takes no arguments, and returns nothing.\ntype PanicTestFunc func()\n\n// didPanic returns true if the function passed to it panics. Otherwise, it returns false.\nfunc didPanic(f PanicTestFunc) (didPanic bool, message interface{}, stack string) {\n\tdidPanic = true\n\n\tdefer func() {\n\t\tmessage = recover()\n\t\tif didPanic {\n\t\t\tstack = string(debug.Stack())\n\t\t}\n\t}()\n\n\t// call the target function\n\tf()\n\tdidPanic = false\n\n\treturn\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\tassert.Panics(t, func(){ GoCrazy() })\nfunc Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic\\n\\tPanic value:\\t%#v\", f, panicValue), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\tassert.PanicsWithValue(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tfuncDidPanic, panicValue, panickedStack := didPanic(f)\n\tif !funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic\\n\\tPanic value:\\t%#v\", f, panicValue), msgAndArgs...)\n\t}\n\tif panicValue != expected {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic with value:\\t%#v\\n\\tPanic value:\\t%#v\\n\\tPanic stack:\\t%s\", f, expected, panicValue, panickedStack), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\tassert.PanicsWithError(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tfuncDidPanic, panicValue, panickedStack := didPanic(f)\n\tif !funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic\\n\\tPanic value:\\t%#v\", f, panicValue), msgAndArgs...)\n\t}\n\tpanicErr, ok := panicValue.(error)\n\tif !ok || panicErr.Error() != errString {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should panic with error message:\\t%#v\\n\\tPanic value:\\t%#v\\n\\tPanic stack:\\t%s\", f, errString, panicValue, panickedStack), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\tassert.NotPanics(t, func(){ RemainCalm() })\nfunc NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic {\n\t\treturn Fail(t, fmt.Sprintf(\"func %#v should not panic\\n\\tPanic value:\\t%v\\n\\tPanic stack:\\t%s\", f, panicValue, panickedStack), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\tassert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)\nfunc WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tdt := expected.Sub(actual)\n\tif dt < -delta || dt > delta {\n\t\treturn Fail(t, fmt.Sprintf(\"Max difference between %v and %v allowed is %v, but difference was %v\", expected, actual, delta, dt), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\tassert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc WithinRange(t TestingT, actual, start, end time.Time, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif end.Before(start) {\n\t\treturn Fail(t, \"Start should be before end\", msgAndArgs...)\n\t}\n\n\tif actual.Before(start) {\n\t\treturn Fail(t, fmt.Sprintf(\"Time %v expected to be in time range %v to %v, but is before the range\", actual, start, end), msgAndArgs...)\n\t} else if actual.After(end) {\n\t\treturn Fail(t, fmt.Sprintf(\"Time %v expected to be in time range %v to %v, but is after the range\", actual, start, end), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\nfunc toFloat(x interface{}) (float64, bool) {\n\tvar xf float64\n\txok := true\n\n\tswitch xn := x.(type) {\n\tcase uint:\n\t\txf = float64(xn)\n\tcase uint8:\n\t\txf = float64(xn)\n\tcase uint16:\n\t\txf = float64(xn)\n\tcase uint32:\n\t\txf = float64(xn)\n\tcase uint64:\n\t\txf = float64(xn)\n\tcase int:\n\t\txf = float64(xn)\n\tcase int8:\n\t\txf = float64(xn)\n\tcase int16:\n\t\txf = float64(xn)\n\tcase int32:\n\t\txf = float64(xn)\n\tcase int64:\n\t\txf = float64(xn)\n\tcase float32:\n\t\txf = float64(xn)\n\tcase float64:\n\t\txf = xn\n\tcase time.Duration:\n\t\txf = float64(xn)\n\tdefault:\n\t\txok = false\n\t}\n\n\treturn xf, xok\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\tassert.InDelta(t, math.Pi, 22/7.0, 0.01)\nfunc InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\taf, aok := toFloat(expected)\n\tbf, bok := toFloat(actual)\n\n\tif !aok || !bok {\n\t\treturn Fail(t, \"Parameters must be numerical\", msgAndArgs...)\n\t}\n\n\tif math.IsNaN(af) && math.IsNaN(bf) {\n\t\treturn true\n\t}\n\n\tif math.IsNaN(af) {\n\t\treturn Fail(t, \"Expected must not be NaN\", msgAndArgs...)\n\t}\n\n\tif math.IsNaN(bf) {\n\t\treturn Fail(t, fmt.Sprintf(\"Expected %v with delta %v, but was NaN\", expected, delta), msgAndArgs...)\n\t}\n\n\tdt := af - bf\n\tif dt < -delta || dt > delta {\n\t\treturn Fail(t, fmt.Sprintf(\"Max difference between %v and %v allowed is %v, but difference was %v\", expected, actual, delta, dt), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif expected == nil || actual == nil ||\n\t\treflect.TypeOf(actual).Kind() != reflect.Slice ||\n\t\treflect.TypeOf(expected).Kind() != reflect.Slice {\n\t\treturn Fail(t, \"Parameters must be slice\", msgAndArgs...)\n\t}\n\n\tactualSlice := reflect.ValueOf(actual)\n\texpectedSlice := reflect.ValueOf(expected)\n\n\tfor i := 0; i < actualSlice.Len(); i++ {\n\t\tresult := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...)\n\t\tif !result {\n\t\t\treturn result\n\t\t}\n\t}\n\n\treturn true\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif expected == nil || actual == nil ||\n\t\treflect.TypeOf(actual).Kind() != reflect.Map ||\n\t\treflect.TypeOf(expected).Kind() != reflect.Map {\n\t\treturn Fail(t, \"Arguments must be maps\", msgAndArgs...)\n\t}\n\n\texpectedMap := reflect.ValueOf(expected)\n\tactualMap := reflect.ValueOf(actual)\n\n\tif expectedMap.Len() != actualMap.Len() {\n\t\treturn Fail(t, \"Arguments must have the same number of keys\", msgAndArgs...)\n\t}\n\n\tfor _, k := range expectedMap.MapKeys() {\n\t\tev := expectedMap.MapIndex(k)\n\t\tav := actualMap.MapIndex(k)\n\n\t\tif !ev.IsValid() {\n\t\t\treturn Fail(t, fmt.Sprintf(\"missing key %q in expected map\", k), msgAndArgs...)\n\t\t}\n\n\t\tif !av.IsValid() {\n\t\t\treturn Fail(t, fmt.Sprintf(\"missing key %q in actual map\", k), msgAndArgs...)\n\t\t}\n\n\t\tif !InDelta(\n\t\t\tt,\n\t\t\tev.Interface(),\n\t\t\tav.Interface(),\n\t\t\tdelta,\n\t\t\tmsgAndArgs...,\n\t\t) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc calcRelativeError(expected, actual interface{}) (float64, error) {\n\taf, aok := toFloat(expected)\n\tbf, bok := toFloat(actual)\n\tif !aok || !bok {\n\t\treturn 0, fmt.Errorf(\"Parameters must be numerical\")\n\t}\n\tif math.IsNaN(af) && math.IsNaN(bf) {\n\t\treturn 0, nil\n\t}\n\tif math.IsNaN(af) {\n\t\treturn 0, errors.New(\"expected value must not be NaN\")\n\t}\n\tif af == 0 {\n\t\treturn 0, fmt.Errorf(\"expected value must have a value other than zero to calculate the relative error\")\n\t}\n\tif math.IsNaN(bf) {\n\t\treturn 0, errors.New(\"actual value must not be NaN\")\n\t}\n\n\treturn math.Abs(af-bf) / math.Abs(af), nil\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif math.IsNaN(epsilon) {\n\t\treturn Fail(t, \"epsilon must not be NaN\", msgAndArgs...)\n\t}\n\tactualEpsilon, err := calcRelativeError(expected, actual)\n\tif err != nil {\n\t\treturn Fail(t, err.Error(), msgAndArgs...)\n\t}\n\tif actualEpsilon > epsilon {\n\t\treturn Fail(t, fmt.Sprintf(\"Relative error is too high: %#v (expected)\\n\"+\n\t\t\t\"        < %#v (actual)\", epsilon, actualEpsilon), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tif expected == nil || actual == nil {\n\t\treturn Fail(t, \"Parameters must be slice\", msgAndArgs...)\n\t}\n\n\texpectedSlice := reflect.ValueOf(expected)\n\tactualSlice := reflect.ValueOf(actual)\n\n\tif expectedSlice.Type().Kind() != reflect.Slice {\n\t\treturn Fail(t, \"Expected value must be slice\", msgAndArgs...)\n\t}\n\n\texpectedLen := expectedSlice.Len()\n\tif !IsType(t, expected, actual) || !Len(t, actual, expectedLen) {\n\t\treturn false\n\t}\n\n\tfor i := 0; i < expectedLen; i++ {\n\t\tif !InEpsilon(t, expectedSlice.Index(i).Interface(), actualSlice.Index(i).Interface(), epsilon, \"at index %d\", i) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n/*\n\tErrors\n*/\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.NoError(t, err) {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {\n\tif err != nil {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, fmt.Sprintf(\"Received unexpected error:\\n%+v\", err), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.Error(t, err) {\n//\t\t   assert.Equal(t, expectedError, err)\n//\t  }\nfunc Error(t TestingT, err error, msgAndArgs ...interface{}) bool {\n\tif err == nil {\n\t\tif h, ok := t.(tHelper); ok {\n\t\t\th.Helper()\n\t\t}\n\t\treturn Fail(t, \"An error is expected but got nil.\", msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.EqualError(t, err,  expectedErrorString)\nfunc EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif !Error(t, theError, msgAndArgs...) {\n\t\treturn false\n\t}\n\texpected := errString\n\tactual := theError.Error()\n\t// don't need to use deep equals here, we know they are both strings\n\tif expected != actual {\n\t\treturn Fail(t, fmt.Sprintf(\"Error message not equal:\\n\"+\n\t\t\t\"expected: %q\\n\"+\n\t\t\t\"actual  : %q\", expected, actual), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.ErrorContains(t, err,  expectedErrorSubString)\nfunc ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif !Error(t, theError, msgAndArgs...) {\n\t\treturn false\n\t}\n\n\tactual := theError.Error()\n\tif !strings.Contains(actual, contains) {\n\t\treturn Fail(t, fmt.Sprintf(\"Error %#v does not contain %#v\", actual, contains), msgAndArgs...)\n\t}\n\n\treturn true\n}\n\n// matchRegexp return true if a specified regexp matches a string.\nfunc matchRegexp(rx interface{}, str interface{}) bool {\n\n\tvar r *regexp.Regexp\n\tif rr, ok := rx.(*regexp.Regexp); ok {\n\t\tr = rr\n\t} else {\n\t\tr = regexp.MustCompile(fmt.Sprint(rx))\n\t}\n\n\treturn (r.FindStringIndex(fmt.Sprint(str)) != nil)\n\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\tassert.Regexp(t, regexp.MustCompile(\"start\"), \"it's starting\")\n//\tassert.Regexp(t, \"start...$\", \"it's not starting\")\nfunc Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tmatch := matchRegexp(rx, str)\n\n\tif !match {\n\t\tFail(t, fmt.Sprintf(\"Expect \\\"%v\\\" to match \\\"%v\\\"\", str, rx), msgAndArgs...)\n\t}\n\n\treturn match\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\tassert.NotRegexp(t, regexp.MustCompile(\"starts\"), \"it's starting\")\n//\tassert.NotRegexp(t, \"^start\", \"it's not starting\")\nfunc NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tmatch := matchRegexp(rx, str)\n\n\tif match {\n\t\tFail(t, fmt.Sprintf(\"Expect \\\"%v\\\" to NOT match \\\"%v\\\"\", str, rx), msgAndArgs...)\n\t}\n\n\treturn !match\n\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should be zero, but was %v\", i), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {\n\t\treturn Fail(t, fmt.Sprintf(\"Should not be zero, but was %v\", i), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn Fail(t, fmt.Sprintf(\"unable to find file %q\", path), msgAndArgs...)\n\t\t}\n\t\treturn Fail(t, fmt.Sprintf(\"error when running os.Lstat(%q): %s\", path, err), msgAndArgs...)\n\t}\n\tif info.IsDir() {\n\t\treturn Fail(t, fmt.Sprintf(\"%q is a directory\", path), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\treturn true\n\t}\n\tif info.IsDir() {\n\t\treturn true\n\t}\n\treturn Fail(t, fmt.Sprintf(\"file %q exists\", path), msgAndArgs...)\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn Fail(t, fmt.Sprintf(\"unable to find file %q\", path), msgAndArgs...)\n\t\t}\n\t\treturn Fail(t, fmt.Sprintf(\"error when running os.Lstat(%q): %s\", path, err), msgAndArgs...)\n\t}\n\tif !info.IsDir() {\n\t\treturn Fail(t, fmt.Sprintf(\"%q is a file\", path), msgAndArgs...)\n\t}\n\treturn true\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tinfo, err := os.Lstat(path)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn true\n\t\t}\n\t\treturn true\n\t}\n\tif !info.IsDir() {\n\t\treturn true\n\t}\n\treturn Fail(t, fmt.Sprintf(\"directory %q exists\", path), msgAndArgs...)\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\tassert.JSONEq(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tvar expectedJSONAsInterface, actualJSONAsInterface interface{}\n\n\tif err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Expected value ('%s') is not valid json.\\nJSON parsing error: '%s'\", expected, err.Error()), msgAndArgs...)\n\t}\n\n\tif err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Input ('%s') needs to be valid json.\\nJSON parsing error: '%s'\", actual, err.Error()), msgAndArgs...)\n\t}\n\n\treturn Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...)\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tvar expectedYAMLAsInterface, actualYAMLAsInterface interface{}\n\n\tif err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Expected value ('%s') is not valid yaml.\\nYAML parsing error: '%s'\", expected, err.Error()), msgAndArgs...)\n\t}\n\n\tif err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil {\n\t\treturn Fail(t, fmt.Sprintf(\"Input ('%s') needs to be valid yaml.\\nYAML error: '%s'\", actual, err.Error()), msgAndArgs...)\n\t}\n\n\treturn Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...)\n}\n\nfunc typeAndKind(v interface{}) (reflect.Type, reflect.Kind) {\n\tt := reflect.TypeOf(v)\n\tk := t.Kind()\n\n\tif k == reflect.Ptr {\n\t\tt = t.Elem()\n\t\tk = t.Kind()\n\t}\n\treturn t, k\n}\n\n// diff returns a diff of both values as long as both are of the same type and\n// are a struct, map, slice, array or string. Otherwise it returns an empty string.\nfunc diff(expected interface{}, actual interface{}) string {\n\tif expected == nil || actual == nil {\n\t\treturn \"\"\n\t}\n\n\tet, ek := typeAndKind(expected)\n\tat, _ := typeAndKind(actual)\n\n\tif et != at {\n\t\treturn \"\"\n\t}\n\n\tif ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {\n\t\treturn \"\"\n\t}\n\n\tvar e, a string\n\n\tswitch et {\n\tcase reflect.TypeOf(\"\"):\n\t\te = reflect.ValueOf(expected).String()\n\t\ta = reflect.ValueOf(actual).String()\n\tcase reflect.TypeOf(time.Time{}):\n\t\te = spewConfigStringerEnabled.Sdump(expected)\n\t\ta = spewConfigStringerEnabled.Sdump(actual)\n\tdefault:\n\t\te = spewConfig.Sdump(expected)\n\t\ta = spewConfig.Sdump(actual)\n\t}\n\n\tdiff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{\n\t\tA:        difflib.SplitLines(e),\n\t\tB:        difflib.SplitLines(a),\n\t\tFromFile: \"Expected\",\n\t\tFromDate: \"\",\n\t\tToFile:   \"Actual\",\n\t\tToDate:   \"\",\n\t\tContext:  1,\n\t})\n\n\treturn \"\\n\\nDiff:\\n\" + diff\n}\n\nfunc isFunction(arg interface{}) bool {\n\tif arg == nil {\n\t\treturn false\n\t}\n\treturn reflect.TypeOf(arg).Kind() == reflect.Func\n}\n\nvar spewConfig = spew.ConfigState{\n\tIndent:                  \" \",\n\tDisablePointerAddresses: true,\n\tDisableCapacities:       true,\n\tSortKeys:                true,\n\tDisableMethods:          true,\n\tMaxDepth:                10,\n}\n\nvar spewConfigStringerEnabled = spew.ConfigState{\n\tIndent:                  \" \",\n\tDisablePointerAddresses: true,\n\tDisableCapacities:       true,\n\tSortKeys:                true,\n\tMaxDepth:                10,\n}\n\ntype tHelper interface {\n\tHelper()\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\tassert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tch := make(chan bool, 1)\n\n\ttimer := time.NewTimer(waitFor)\n\tdefer timer.Stop()\n\n\tticker := time.NewTicker(tick)\n\tdefer ticker.Stop()\n\n\tfor tick := ticker.C; ; {\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\treturn Fail(t, \"Condition never satisfied\", msgAndArgs...)\n\t\tcase <-tick:\n\t\t\ttick = nil\n\t\t\tgo func() { ch <- condition() }()\n\t\tcase v := <-ch:\n\t\t\tif v {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\ttick = ticker.C\n\t\t}\n\t}\n}\n\n// CollectT implements the TestingT interface and collects all errors.\ntype CollectT struct {\n\terrors []error\n}\n\n// Errorf collects the error.\nfunc (c *CollectT) Errorf(format string, args ...interface{}) {\n\tc.errors = append(c.errors, fmt.Errorf(format, args...))\n}\n\n// FailNow panics.\nfunc (*CollectT) FailNow() {\n\tpanic(\"Assertion failed\")\n}\n\n// Deprecated: That was a method for internal usage that should not have been published. Now just panics.\nfunc (*CollectT) Reset() {\n\tpanic(\"Reset() is deprecated\")\n}\n\n// Deprecated: That was a method for internal usage that should not have been published. Now just panics.\nfunc (*CollectT) Copy(TestingT) {\n\tpanic(\"Copy() is deprecated\")\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\tassert.EventuallyWithT(t, func(c *assert.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithT(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tvar lastFinishedTickErrs []error\n\tch := make(chan []error, 1)\n\n\ttimer := time.NewTimer(waitFor)\n\tdefer timer.Stop()\n\n\tticker := time.NewTicker(tick)\n\tdefer ticker.Stop()\n\n\tfor tick := ticker.C; ; {\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\tfor _, err := range lastFinishedTickErrs {\n\t\t\t\tt.Errorf(\"%v\", err)\n\t\t\t}\n\t\t\treturn Fail(t, \"Condition never satisfied\", msgAndArgs...)\n\t\tcase <-tick:\n\t\t\ttick = nil\n\t\t\tgo func() {\n\t\t\t\tcollect := new(CollectT)\n\t\t\t\tdefer func() {\n\t\t\t\t\tch <- collect.errors\n\t\t\t\t}()\n\t\t\t\tcondition(collect)\n\t\t\t}()\n\t\tcase errs := <-ch:\n\t\t\tif len(errs) == 0 {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Keep the errors from the last ended condition, so that they can be copied to t if timeout is reached.\n\t\t\tlastFinishedTickErrs = errs\n\t\t\ttick = ticker.C\n\t\t}\n\t}\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\tassert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\n\tch := make(chan bool, 1)\n\n\ttimer := time.NewTimer(waitFor)\n\tdefer timer.Stop()\n\n\tticker := time.NewTicker(tick)\n\tdefer ticker.Stop()\n\n\tfor tick := ticker.C; ; {\n\t\tselect {\n\t\tcase <-timer.C:\n\t\t\treturn true\n\t\tcase <-tick:\n\t\t\ttick = nil\n\t\t\tgo func() { ch <- condition() }()\n\t\tcase v := <-ch:\n\t\t\tif v {\n\t\t\t\treturn Fail(t, \"Condition satisfied\", msgAndArgs...)\n\t\t\t}\n\t\t\ttick = ticker.C\n\t\t}\n\t}\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif errors.Is(err, target) {\n\t\treturn true\n\t}\n\n\tvar expectedText string\n\tif target != nil {\n\t\texpectedText = target.Error()\n\t}\n\n\tchain := buildErrorChainString(err)\n\n\treturn Fail(t, fmt.Sprintf(\"Target error should be in err chain:\\n\"+\n\t\t\"expected: %q\\n\"+\n\t\t\"in chain: %s\", expectedText, chain,\n\t), msgAndArgs...)\n}\n\n// NotErrorIs asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif !errors.Is(err, target) {\n\t\treturn true\n\t}\n\n\tvar expectedText string\n\tif target != nil {\n\t\texpectedText = target.Error()\n\t}\n\n\tchain := buildErrorChainString(err)\n\n\treturn Fail(t, fmt.Sprintf(\"Target error should not be in err chain:\\n\"+\n\t\t\"found: %q\\n\"+\n\t\t\"in chain: %s\", expectedText, chain,\n\t), msgAndArgs...)\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif errors.As(err, target) {\n\t\treturn true\n\t}\n\n\tchain := buildErrorChainString(err)\n\n\treturn Fail(t, fmt.Sprintf(\"Should be in error chain:\\n\"+\n\t\t\"expected: %q\\n\"+\n\t\t\"in chain: %s\", target, chain,\n\t), msgAndArgs...)\n}\n\nfunc buildErrorChainString(err error) string {\n\tif err == nil {\n\t\treturn \"\"\n\t}\n\n\te := errors.Unwrap(err)\n\tchain := fmt.Sprintf(\"%q\", err.Error())\n\tfor e != nil {\n\t\tchain += fmt.Sprintf(\"\\n\\t%q\", e.Error())\n\t\te = errors.Unwrap(e)\n\t}\n\treturn chain\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/doc.go",
    "content": "// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system.\n//\n// # Example Usage\n//\n// The following is a complete example using assert in a standard test function:\n//\n//\timport (\n//\t  \"testing\"\n//\t  \"github.com/stretchr/testify/assert\"\n//\t)\n//\n//\tfunc TestSomething(t *testing.T) {\n//\n//\t  var a string = \"Hello\"\n//\t  var b string = \"Hello\"\n//\n//\t  assert.Equal(t, a, b, \"The two words should be the same.\")\n//\n//\t}\n//\n// if you assert many times, use the format below:\n//\n//\timport (\n//\t  \"testing\"\n//\t  \"github.com/stretchr/testify/assert\"\n//\t)\n//\n//\tfunc TestSomething(t *testing.T) {\n//\t  assert := assert.New(t)\n//\n//\t  var a string = \"Hello\"\n//\t  var b string = \"Hello\"\n//\n//\t  assert.Equal(a, b, \"The two words should be the same.\")\n//\t}\n//\n// # Assertions\n//\n// Assertions allow you to easily write test code, and are global funcs in the `assert` package.\n// All assertion functions take, as the first argument, the `*testing.T` object provided by the\n// testing framework. This allows the assertion funcs to write the failings and other details to\n// the correct place.\n//\n// Every assertion function also takes an optional string message as the final argument,\n// allowing custom error messages to be appended to the message the assertion method outputs.\npackage assert\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/errors.go",
    "content": "package assert\n\nimport (\n\t\"errors\"\n)\n\n// AnError is an error instance useful for testing.  If the code does not care\n// about error specifics, and only needs to return the error for example, this\n// error should be used to make the test code more readable.\nvar AnError = errors.New(\"assert.AnError general error for testing\")\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/forward_assertions.go",
    "content": "package assert\n\n// Assertions provides assertion methods around the\n// TestingT interface.\ntype Assertions struct {\n\tt TestingT\n}\n\n// New makes a new Assertions object for the specified TestingT.\nfunc New(t TestingT) *Assertions {\n\treturn &Assertions{\n\t\tt: t,\n\t}\n}\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs\"\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/assert/http_assertions.go",
    "content": "package assert\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n// httpCode is a helper that returns HTTP code of the response. It returns -1 and\n// an error if building a new request fails.\nfunc httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {\n\tw := httptest.NewRecorder()\n\treq, err := http.NewRequest(method, url, http.NoBody)\n\tif err != nil {\n\t\treturn -1, err\n\t}\n\treq.URL.RawQuery = values.Encode()\n\thandler(w, req)\n\treturn w.Code, nil\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\tassert.HTTPSuccess(t, myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tisSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent\n\tif !isSuccessCode {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP success status code for %q but received %d\", url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn isSuccessCode\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\tassert.HTTPRedirect(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tisRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect\n\tif !isRedirectCode {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP redirect status code for %q but received %d\", url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn isRedirectCode\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\tassert.HTTPError(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tisErrorCode := code >= http.StatusBadRequest\n\tif !isErrorCode {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP error status code for %q but received %d\", url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn isErrorCode\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\tassert.HTTPStatusCode(t, myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tcode, err := httpCode(handler, method, url, values)\n\tif err != nil {\n\t\tFail(t, fmt.Sprintf(\"Failed to build test request, got error: %s\", err), msgAndArgs...)\n\t}\n\n\tsuccessful := code == statuscode\n\tif !successful {\n\t\tFail(t, fmt.Sprintf(\"Expected HTTP status code %d for %q but received %d\", statuscode, url+\"?\"+values.Encode(), code), msgAndArgs...)\n\t}\n\n\treturn successful\n}\n\n// HTTPBody is a helper that returns HTTP body of the response. It returns\n// empty string if building a new request fails.\nfunc HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string {\n\tw := httptest.NewRecorder()\n\tif len(values) > 0 {\n\t\turl += \"?\" + values.Encode()\n\t}\n\treq, err := http.NewRequest(method, url, http.NoBody)\n\tif err != nil {\n\t\treturn \"\"\n\t}\n\thandler(w, req)\n\treturn w.Body.String()\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\tassert.HTTPBodyContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tbody := HTTPBody(handler, method, url, values)\n\n\tcontains := strings.Contains(body, fmt.Sprint(str))\n\tif !contains {\n\t\tFail(t, fmt.Sprintf(\"Expected response body for \\\"%s\\\" to contain \\\"%s\\\" but found \\\"%s\\\"\", url+\"?\"+values.Encode(), str, body), msgAndArgs...)\n\t}\n\n\treturn contains\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\tassert.HTTPBodyNotContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tbody := HTTPBody(handler, method, url, values)\n\n\tcontains := strings.Contains(body, fmt.Sprint(str))\n\tif contains {\n\t\tFail(t, fmt.Sprintf(\"Expected response body for \\\"%s\\\" to NOT contain \\\"%s\\\" but found \\\"%s\\\"\", url+\"?\"+values.Encode(), str, body), msgAndArgs...)\n\t}\n\n\treturn !contains\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/doc.go",
    "content": "// Package require implements the same assertions as the `assert` package but\n// stops test execution when a test fails.\n//\n// # Example Usage\n//\n// The following is a complete example using require in a standard test function:\n//\n//\timport (\n//\t  \"testing\"\n//\t  \"github.com/stretchr/testify/require\"\n//\t)\n//\n//\tfunc TestSomething(t *testing.T) {\n//\n//\t  var a string = \"Hello\"\n//\t  var b string = \"Hello\"\n//\n//\t  require.Equal(t, a, b, \"The two words should be the same.\")\n//\n//\t}\n//\n// # Assertions\n//\n// The `require` package have same global functions as in the `assert` package,\n// but instead of returning a boolean result they call `t.FailNow()`.\n//\n// Every assertion function also takes an optional string message as the final argument,\n// allowing custom error messages to be appended to the message the assertion method outputs.\npackage require\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/forward_requirements.go",
    "content": "package require\n\n// Assertions provides assertion methods around the\n// TestingT interface.\ntype Assertions struct {\n\tt TestingT\n}\n\n// New makes a new Assertions object for the specified TestingT.\nfunc New(t TestingT) *Assertions {\n\treturn &Assertions{\n\t\tt: t,\n\t}\n}\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require_forward.go.tmpl -include-format-funcs\"\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage require\n\nimport (\n\tassert \"github.com/stretchr/testify/assert\"\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Condition uses a Comparison to assert a complex condition.\nfunc Condition(t TestingT, comp assert.Comparison, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Condition(t, comp, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc Conditionf(t TestingT, comp assert.Comparison, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Conditionf(t, comp, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\tassert.Contains(t, \"Hello World\", \"World\")\n//\tassert.Contains(t, [\"Hello\", \"World\"], \"World\")\n//\tassert.Contains(t, {\"Hello\": \"World\"}, \"Hello\")\nfunc Contains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Contains(t, s, contains, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\tassert.Containsf(t, \"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\tassert.Containsf(t, [\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\tassert.Containsf(t, {\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Containsf(t, s, contains, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.DirExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc DirExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.DirExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])\nfunc ElementsMatch(t TestingT, listA interface{}, listB interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ElementsMatch(t, listA, listB, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ElementsMatchf(t, listA, listB, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Empty asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tassert.Empty(t, obj)\nfunc Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Empty(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Emptyf asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tassert.Emptyf(t, obj, \"error message %s\", \"formatted\")\nfunc Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Emptyf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Equal asserts that two objects are equal.\n//\n//\tassert.Equal(t, 123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Equal(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.EqualError(t, err,  expectedErrorString)\nfunc EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualError(t, theError, errString, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.EqualErrorf(t, err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualErrorf(t, theError, errString, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t assert.EqualExportedValues(t, S{1, 2}, S{1, 3}) => true\n//\t assert.EqualExportedValues(t, S{1, 2}, S{2, 3}) => false\nfunc EqualExportedValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualExportedValues(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t assert.EqualExportedValuesf(t, S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t assert.EqualExportedValuesf(t, S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc EqualExportedValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualExportedValuesf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualValues asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\tassert.EqualValues(t, uint32(123), int32(123))\nfunc EqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualValues(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\tassert.EqualValuesf(t, uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EqualValuesf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\tassert.Equalf(t, 123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Equalf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.Error(t, err) {\n//\t\t   assert.Equal(t, expectedError, err)\n//\t  }\nfunc Error(t TestingT, err error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Error(t, err, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorAs(t, err, target, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorAsf(t, err, target, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.ErrorContains(t, err,  expectedErrorSubString)\nfunc ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorContains(t, theError, contains, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\tassert.ErrorContainsf(t, err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc ErrorContainsf(t TestingT, theError error, contains string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorContainsf(t, theError, contains, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorIs(t, err, target, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc ErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.ErrorIsf(t, err, target, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.Errorf(t, err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedErrorf, err)\n//\t  }\nfunc Errorf(t TestingT, err error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Errorf(t, err, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\tassert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Eventually(t, condition, waitFor, tick, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\tassert.EventuallyWithT(t, func(c *assert.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithT(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EventuallyWithT(t, condition, waitFor, tick, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\tassert.EventuallyWithTf(t, func(c *assert.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc EventuallyWithTf(t TestingT, condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.EventuallyWithTf(t, condition, waitFor, tick, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\tassert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Eventuallyf(t, condition, waitFor, tick, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\tassert.Exactly(t, int32(123), int64(123))\nfunc Exactly(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Exactly(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\tassert.Exactlyf(t, int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Exactlyf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Fail reports a failure through\nfunc Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Fail(t, failureMessage, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FailNow fails test\nfunc FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FailNow(t, failureMessage, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FailNowf fails test\nfunc FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FailNowf(t, failureMessage, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Failf reports a failure through\nfunc Failf(t TestingT, failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Failf(t, failureMessage, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// False asserts that the specified value is false.\n//\n//\tassert.False(t, myBool)\nfunc False(t TestingT, value bool, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.False(t, value, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\tassert.Falsef(t, myBool, \"error message %s\", \"formatted\")\nfunc Falsef(t TestingT, value bool, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Falsef(t, value, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FileExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc FileExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.FileExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\tassert.Greater(t, 2, 1)\n//\tassert.Greater(t, float64(2), float64(1))\n//\tassert.Greater(t, \"b\", \"a\")\nfunc Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Greater(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\tassert.GreaterOrEqual(t, 2, 1)\n//\tassert.GreaterOrEqual(t, 2, 2)\n//\tassert.GreaterOrEqual(t, \"b\", \"a\")\n//\tassert.GreaterOrEqual(t, \"b\", \"b\")\nfunc GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.GreaterOrEqual(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\tassert.GreaterOrEqualf(t, 2, 1, \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\n//\tassert.GreaterOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.GreaterOrEqualf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\tassert.Greaterf(t, 2, 1, \"error message %s\", \"formatted\")\n//\tassert.Greaterf(t, float64(2), float64(1), \"error message %s\", \"formatted\")\n//\tassert.Greaterf(t, \"b\", \"a\", \"error message %s\", \"formatted\")\nfunc Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Greaterf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\tassert.HTTPBodyContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyContains(t, handler, method, url, values, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\tassert.HTTPBodyContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyContainsf(t, handler, method, url, values, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\tassert.HTTPBodyNotContains(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyNotContains(t, handler, method, url, values, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\tassert.HTTPBodyNotContainsf(t, myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPBodyNotContainsf(t, handler, method, url, values, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\tassert.HTTPError(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPError(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPError(t, handler, method, url, values, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\tassert.HTTPErrorf(t, myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPErrorf(t, handler, method, url, values, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\tassert.HTTPRedirect(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirect(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPRedirect(t, handler, method, url, values, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\tassert.HTTPRedirectf(t, myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPRedirectf(t, handler, method, url, values, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\tassert.HTTPStatusCode(t, myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCode(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPStatusCode(t, handler, method, url, values, statuscode, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\tassert.HTTPStatusCodef(t, myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPStatusCodef(t, handler, method, url, values, statuscode, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\tassert.HTTPSuccess(t, myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccess(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPSuccess(t, handler, method, url, values, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\tassert.HTTPSuccessf(t, myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.HTTPSuccessf(t, handler, method, url, values, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\tassert.Implements(t, (*MyInterface)(nil), new(MyObject))\nfunc Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Implements(t, interfaceObject, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\tassert.Implementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Implementsf(t, interfaceObject, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\tassert.InDelta(t, math.Pi, 22/7.0, 0.01)\nfunc InDelta(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDelta(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValues(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaMapValues(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaMapValuesf(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc InDeltaSlice(t TestingT, expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaSlice(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaSlicef(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\tassert.InDeltaf(t, math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InDeltaf(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilon(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilon(t, expected, actual, epsilon, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlice(t TestingT, expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilonSlice(t, expected, actual, epsilon, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilonSlicef(t, expected, actual, epsilon, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.InEpsilonf(t, expected, actual, epsilon, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\tassert.IsDecreasing(t, []int{2, 1, 0})\n//\tassert.IsDecreasing(t, []float{2, 1})\n//\tassert.IsDecreasing(t, []string{\"b\", \"a\"})\nfunc IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsDecreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\tassert.IsDecreasingf(t, []int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\tassert.IsDecreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsDecreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsDecreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\tassert.IsIncreasing(t, []int{1, 2, 3})\n//\tassert.IsIncreasing(t, []float{1, 2})\n//\tassert.IsIncreasing(t, []string{\"a\", \"b\"})\nfunc IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsIncreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\tassert.IsIncreasingf(t, []int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\tassert.IsIncreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsIncreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsIncreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\tassert.IsNonDecreasing(t, []int{1, 1, 2})\n//\tassert.IsNonDecreasing(t, []float{1, 2})\n//\tassert.IsNonDecreasing(t, []string{\"a\", \"b\"})\nfunc IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonDecreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\tassert.IsNonDecreasingf(t, []int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsNonDecreasingf(t, []float{1, 2}, \"error message %s\", \"formatted\")\n//\tassert.IsNonDecreasingf(t, []string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc IsNonDecreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonDecreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\tassert.IsNonIncreasing(t, []int{2, 1, 1})\n//\tassert.IsNonIncreasing(t, []float{2, 1})\n//\tassert.IsNonIncreasing(t, []string{\"b\", \"a\"})\nfunc IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonIncreasing(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\tassert.IsNonIncreasingf(t, []int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsNonIncreasingf(t, []float{2, 1}, \"error message %s\", \"formatted\")\n//\tassert.IsNonIncreasingf(t, []string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc IsNonIncreasingf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsNonIncreasingf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsType asserts that the specified objects are of the same type.\nfunc IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsType(t, expectedType, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// IsTypef asserts that the specified objects are of the same type.\nfunc IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.IsTypef(t, expectedType, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\tassert.JSONEq(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.JSONEq(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\tassert.JSONEqf(t, `{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.JSONEqf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\tassert.Len(t, mySlice, 3)\nfunc Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Len(t, object, length, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\tassert.Lenf(t, mySlice, 3, \"error message %s\", \"formatted\")\nfunc Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Lenf(t, object, length, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Less asserts that the first element is less than the second\n//\n//\tassert.Less(t, 1, 2)\n//\tassert.Less(t, float64(1), float64(2))\n//\tassert.Less(t, \"a\", \"b\")\nfunc Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Less(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\tassert.LessOrEqual(t, 1, 2)\n//\tassert.LessOrEqual(t, 2, 2)\n//\tassert.LessOrEqual(t, \"a\", \"b\")\n//\tassert.LessOrEqual(t, \"b\", \"b\")\nfunc LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.LessOrEqual(t, e1, e2, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\tassert.LessOrEqualf(t, 1, 2, \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, 2, 2, \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\n//\tassert.LessOrEqualf(t, \"b\", \"b\", \"error message %s\", \"formatted\")\nfunc LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.LessOrEqualf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\tassert.Lessf(t, 1, 2, \"error message %s\", \"formatted\")\n//\tassert.Lessf(t, float64(1), float64(2), \"error message %s\", \"formatted\")\n//\tassert.Lessf(t, \"a\", \"b\", \"error message %s\", \"formatted\")\nfunc Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Lessf(t, e1, e2, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Negative asserts that the specified element is negative\n//\n//\tassert.Negative(t, -1)\n//\tassert.Negative(t, -1.23)\nfunc Negative(t TestingT, e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Negative(t, e, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\tassert.Negativef(t, -1, \"error message %s\", \"formatted\")\n//\tassert.Negativef(t, -1.23, \"error message %s\", \"formatted\")\nfunc Negativef(t TestingT, e interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Negativef(t, e, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\tassert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Never(t, condition, waitFor, tick, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\tassert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Neverf(t, condition, waitFor, tick, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\tassert.Nil(t, err)\nfunc Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Nil(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\tassert.Nilf(t, err, \"error message %s\", \"formatted\")\nfunc Nilf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Nilf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoDirExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoDirExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.NoError(t, err) {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoError(t TestingT, err error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoError(t, err, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if assert.NoErrorf(t, err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc NoErrorf(t TestingT, err error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoErrorf(t, err, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoFileExists(t, path, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NoFileExistsf(t, path, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\tassert.NotContains(t, \"Hello World\", \"Earth\")\n//\tassert.NotContains(t, [\"Hello\", \"World\"], \"Earth\")\n//\tassert.NotContains(t, {\"Hello\": \"World\"}, \"Earth\")\nfunc NotContains(t TestingT, s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotContains(t, s, contains, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\tassert.NotContainsf(t, \"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\tassert.NotContainsf(t, [\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\tassert.NotContainsf(t, {\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotContainsf(t, s, contains, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif assert.NotEmpty(t, obj) {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEmpty(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEmptyf asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif assert.NotEmptyf(t, obj, \"error message %s\", \"formatted\") {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEmptyf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\tassert.NotEqual(t, obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqual(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqual(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\tassert.NotEqualValues(t, obj1, obj2)\nfunc NotEqualValues(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqualValues(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\tassert.NotEqualValuesf(t, obj1, obj2, \"error message %s\", \"formatted\")\nfunc NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqualValuesf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\tassert.NotEqualf(t, obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotEqualf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotErrorIs asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIs(t TestingT, err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotErrorIs(t, err, target, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotErrorIsf asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc NotErrorIsf(t TestingT, err error, target error, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotErrorIsf(t, err, target, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\tassert.NotImplements(t, (*MyInterface)(nil), new(MyObject))\nfunc NotImplements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotImplements(t, interfaceObject, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\tassert.NotImplementsf(t, (*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc NotImplementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotImplementsf(t, interfaceObject, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\tassert.NotNil(t, err)\nfunc NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotNil(t, object, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\tassert.NotNilf(t, err, \"error message %s\", \"formatted\")\nfunc NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotNilf(t, object, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\tassert.NotPanics(t, func(){ RemainCalm() })\nfunc NotPanics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotPanics(t, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\tassert.NotPanicsf(t, func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc NotPanicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotPanicsf(t, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\tassert.NotRegexp(t, regexp.MustCompile(\"starts\"), \"it's starting\")\n//\tassert.NotRegexp(t, \"^start\", \"it's not starting\")\nfunc NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotRegexp(t, rx, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\tassert.NotRegexpf(t, regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\tassert.NotRegexpf(t, \"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotRegexpf(t, rx, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\tassert.NotSame(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSame(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSame(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\tassert.NotSamef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSamef(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSubset asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\tassert.NotSubset(t, [1, 3, 4], [1, 2])\n//\tassert.NotSubset(t, {\"x\": 1, \"y\": 2}, {\"z\": 3})\nfunc NotSubset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSubset(t, list, subset, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotSubsetf asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\tassert.NotSubsetf(t, [1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\tassert.NotSubsetf(t, {\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\nfunc NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotSubsetf(t, list, subset, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotZero(t, i, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.NotZerof(t, i, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\tassert.Panics(t, func(){ GoCrazy() })\nfunc Panics(t TestingT, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Panics(t, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\tassert.PanicsWithError(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithError(t TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithError(t, errString, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\tassert.PanicsWithErrorf(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithErrorf(t TestingT, errString string, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithErrorf(t, errString, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\tassert.PanicsWithValue(t, \"crazy error\", func(){ GoCrazy() })\nfunc PanicsWithValue(t TestingT, expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithValue(t, expected, f, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\tassert.PanicsWithValuef(t, \"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc PanicsWithValuef(t TestingT, expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.PanicsWithValuef(t, expected, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\tassert.Panicsf(t, func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc Panicsf(t TestingT, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Panicsf(t, f, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Positive asserts that the specified element is positive\n//\n//\tassert.Positive(t, 1)\n//\tassert.Positive(t, 1.23)\nfunc Positive(t TestingT, e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Positive(t, e, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\tassert.Positivef(t, 1, \"error message %s\", \"formatted\")\n//\tassert.Positivef(t, 1.23, \"error message %s\", \"formatted\")\nfunc Positivef(t TestingT, e interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Positivef(t, e, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\tassert.Regexp(t, regexp.MustCompile(\"start\"), \"it's starting\")\n//\tassert.Regexp(t, \"start...$\", \"it's not starting\")\nfunc Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Regexp(t, rx, str, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\tassert.Regexpf(t, regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\tassert.Regexpf(t, \"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Regexpf(t, rx, str, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\tassert.Same(t, ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Same(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Same(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\tassert.Samef(t, ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Samef(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Subset asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\tassert.Subset(t, [1, 2, 3], [1, 2])\n//\tassert.Subset(t, {\"x\": 1, \"y\": 2}, {\"x\": 1})\nfunc Subset(t TestingT, list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Subset(t, list, subset, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Subsetf asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\tassert.Subsetf(t, [1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\tassert.Subsetf(t, {\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\nfunc Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Subsetf(t, list, subset, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// True asserts that the specified value is true.\n//\n//\tassert.True(t, myBool)\nfunc True(t TestingT, value bool, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.True(t, value, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Truef asserts that the specified value is true.\n//\n//\tassert.Truef(t, myBool, \"error message %s\", \"formatted\")\nfunc Truef(t TestingT, value bool, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Truef(t, value, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\tassert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)\nfunc WithinDuration(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinDuration(t, expected, actual, delta, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\tassert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinDurationf(t, expected, actual, delta, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\tassert.WithinRange(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc WithinRange(t TestingT, actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinRange(t, actual, start, end, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\tassert.WithinRangef(t, time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.WithinRangef(t, actual, start, end, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.YAMLEq(t, expected, actual, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.YAMLEqf(t, expected, actual, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Zero(t, i, msgAndArgs...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc Zerof(t TestingT, i interface{}, msg string, args ...interface{}) {\n\tif h, ok := t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tif assert.Zerof(t, i, msg, args...) {\n\t\treturn\n\t}\n\tt.FailNow()\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require.go.tmpl",
    "content": "{{.Comment}}\nfunc {{.DocInfo.Name}}(t TestingT, {{.Params}}) {\n\tif h, ok := t.(tHelper); ok { h.Helper() }\n\tif assert.{{.DocInfo.Name}}(t, {{.ForwardedParams}}) { return }\n\tt.FailNow()\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require_forward.go",
    "content": "// Code generated with github.com/stretchr/testify/_codegen; DO NOT EDIT.\n\npackage require\n\nimport (\n\tassert \"github.com/stretchr/testify/assert\"\n\thttp \"net/http\"\n\turl \"net/url\"\n\ttime \"time\"\n)\n\n// Condition uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Condition(comp assert.Comparison, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tCondition(a.t, comp, msgAndArgs...)\n}\n\n// Conditionf uses a Comparison to assert a complex condition.\nfunc (a *Assertions) Conditionf(comp assert.Comparison, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tConditionf(a.t, comp, msg, args...)\n}\n\n// Contains asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Contains(\"Hello World\", \"World\")\n//\ta.Contains([\"Hello\", \"World\"], \"World\")\n//\ta.Contains({\"Hello\": \"World\"}, \"Hello\")\nfunc (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tContains(a.t, s, contains, msgAndArgs...)\n}\n\n// Containsf asserts that the specified string, list(array, slice...) or map contains the\n// specified substring or element.\n//\n//\ta.Containsf(\"Hello World\", \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf([\"Hello\", \"World\"], \"World\", \"error message %s\", \"formatted\")\n//\ta.Containsf({\"Hello\": \"World\"}, \"Hello\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tContainsf(a.t, s, contains, msg, args...)\n}\n\n// DirExists checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tDirExists(a.t, path, msgAndArgs...)\n}\n\n// DirExistsf checks whether a directory exists in the given path. It also fails\n// if the path is a file rather a directory or there is an error checking whether it exists.\nfunc (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tDirExistsf(a.t, path, msg, args...)\n}\n\n// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])\nfunc (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tElementsMatch(a.t, listA, listB, msgAndArgs...)\n}\n\n// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified\n// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements,\n// the number of appearances of each of them in both lists should match.\n//\n// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], \"error message %s\", \"formatted\")\nfunc (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tElementsMatchf(a.t, listA, listB, msg, args...)\n}\n\n// Empty asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\ta.Empty(obj)\nfunc (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEmpty(a.t, object, msgAndArgs...)\n}\n\n// Emptyf asserts that the specified object is empty.  I.e. nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\ta.Emptyf(obj, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEmptyf(a.t, object, msg, args...)\n}\n\n// Equal asserts that two objects are equal.\n//\n//\ta.Equal(123, 123)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqual(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualError asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualError(err,  expectedErrorString)\nfunc (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualError(a.t, theError, errString, msgAndArgs...)\n}\n\n// EqualErrorf asserts that a function returned an error (i.e. not `nil`)\n// and that it is equal to the provided error.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.EqualErrorf(err,  expectedErrorString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualErrorf(a.t, theError, errString, msg, args...)\n}\n\n// EqualExportedValues asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValues(S{1, 2}, S{1, 3}) => true\n//\t a.EqualExportedValues(S{1, 2}, S{2, 3}) => false\nfunc (a *Assertions) EqualExportedValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualExportedValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualExportedValuesf asserts that the types of two objects are equal and their public\n// fields are also equal. This is useful for comparing structs that have private fields\n// that could potentially differ.\n//\n//\t type S struct {\n//\t\tExported     \tint\n//\t\tnotExported   \tint\n//\t }\n//\t a.EqualExportedValuesf(S{1, 2}, S{1, 3}, \"error message %s\", \"formatted\") => true\n//\t a.EqualExportedValuesf(S{1, 2}, S{2, 3}, \"error message %s\", \"formatted\") => false\nfunc (a *Assertions) EqualExportedValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualExportedValuesf(a.t, expected, actual, msg, args...)\n}\n\n// EqualValues asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\ta.EqualValues(uint32(123), int32(123))\nfunc (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// EqualValuesf asserts that two objects are equal or convertible to the same types\n// and equal.\n//\n//\ta.EqualValuesf(uint32(123), int32(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// Equalf asserts that two objects are equal.\n//\n//\ta.Equalf(123, 123, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses). Function equality\n// cannot be determined and will always fail.\nfunc (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEqualf(a.t, expected, actual, msg, args...)\n}\n\n// Error asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.Error(err) {\n//\t\t   assert.Equal(t, expectedError, err)\n//\t  }\nfunc (a *Assertions) Error(err error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tError(a.t, err, msgAndArgs...)\n}\n\n// ErrorAs asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAs(err error, target interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorAs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorAsf asserts that at least one of the errors in err's chain matches target, and if so, sets target to that error value.\n// This is a wrapper for errors.As.\nfunc (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorAsf(a.t, err, target, msg, args...)\n}\n\n// ErrorContains asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContains(err,  expectedErrorSubString)\nfunc (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorContains(a.t, theError, contains, msgAndArgs...)\n}\n\n// ErrorContainsf asserts that a function returned an error (i.e. not `nil`)\n// and that the error contains the specified substring.\n//\n//\tactualObj, err := SomeFunction()\n//\ta.ErrorContainsf(err,  expectedErrorSubString, \"error message %s\", \"formatted\")\nfunc (a *Assertions) ErrorContainsf(theError error, contains string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorContainsf(a.t, theError, contains, msg, args...)\n}\n\n// ErrorIs asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIs(err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// ErrorIsf asserts that at least one of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) ErrorIsf(err error, target error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorIsf(a.t, err, target, msg, args...)\n}\n\n// Errorf asserts that a function returned an error (i.e. not `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.Errorf(err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedErrorf, err)\n//\t  }\nfunc (a *Assertions) Errorf(err error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tErrorf(a.t, err, msg, args...)\n}\n\n// Eventually asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventually(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithT asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithT(func(c *assert.CollectT) {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithT(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventuallyWithT(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// EventuallyWithTf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick. In contrast to Eventually,\n// it supplies a CollectT to the condition function, so that the condition\n// function can use the CollectT to call other assertions.\n// The condition is considered \"met\" if no errors are raised in a tick.\n// The supplied CollectT collects all errors from one tick (if there are any).\n// If the condition is not met before waitFor, the collected errors of\n// the last tick are copied to t.\n//\n//\texternalValue := false\n//\tgo func() {\n//\t\ttime.Sleep(8*time.Second)\n//\t\texternalValue = true\n//\t}()\n//\ta.EventuallyWithTf(func(c *assert.CollectT, \"error message %s\", \"formatted\") {\n//\t\t// add assertions as needed; any assertion failure will fail the current tick\n//\t\tassert.True(c, externalValue, \"expected 'externalValue' to be true\")\n//\t}, 1*time.Second, 10*time.Second, \"external state has not changed to 'true'; still false\")\nfunc (a *Assertions) EventuallyWithTf(condition func(collect *assert.CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventuallyWithTf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Eventuallyf asserts that given condition will be met in waitFor time,\n// periodically checking target function each tick.\n//\n//\ta.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tEventuallyf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Exactly asserts that two objects are equal in value and type.\n//\n//\ta.Exactly(int32(123), int64(123))\nfunc (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tExactly(a.t, expected, actual, msgAndArgs...)\n}\n\n// Exactlyf asserts that two objects are equal in value and type.\n//\n//\ta.Exactlyf(int32(123), int64(123), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tExactlyf(a.t, expected, actual, msg, args...)\n}\n\n// Fail reports a failure through\nfunc (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFail(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNow fails test\nfunc (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFailNow(a.t, failureMessage, msgAndArgs...)\n}\n\n// FailNowf fails test\nfunc (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFailNowf(a.t, failureMessage, msg, args...)\n}\n\n// Failf reports a failure through\nfunc (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFailf(a.t, failureMessage, msg, args...)\n}\n\n// False asserts that the specified value is false.\n//\n//\ta.False(myBool)\nfunc (a *Assertions) False(value bool, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFalse(a.t, value, msgAndArgs...)\n}\n\n// Falsef asserts that the specified value is false.\n//\n//\ta.Falsef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Falsef(value bool, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFalsef(a.t, value, msg, args...)\n}\n\n// FileExists checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFileExists(a.t, path, msgAndArgs...)\n}\n\n// FileExistsf checks whether a file exists in the given path. It also fails if\n// the path points to a directory or there is an error when trying to check the file.\nfunc (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tFileExistsf(a.t, path, msg, args...)\n}\n\n// Greater asserts that the first element is greater than the second\n//\n//\ta.Greater(2, 1)\n//\ta.Greater(float64(2), float64(1))\n//\ta.Greater(\"b\", \"a\")\nfunc (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreater(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqual asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqual(2, 1)\n//\ta.GreaterOrEqual(2, 2)\n//\ta.GreaterOrEqual(\"b\", \"a\")\n//\ta.GreaterOrEqual(\"b\", \"b\")\nfunc (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreaterOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// GreaterOrEqualf asserts that the first element is greater than or equal to the second\n//\n//\ta.GreaterOrEqualf(2, 1, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"a\", \"error message %s\", \"formatted\")\n//\ta.GreaterOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreaterOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Greaterf asserts that the first element is greater than the second\n//\n//\ta.Greaterf(2, 1, \"error message %s\", \"formatted\")\n//\ta.Greaterf(float64(2), float64(1), \"error message %s\", \"formatted\")\n//\ta.Greaterf(\"b\", \"a\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tGreaterf(a.t, e1, e2, msg, args...)\n}\n\n// HTTPBodyContains asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyContainsf asserts that a specified handler returns a\n// body that contains a string.\n//\n//\ta.HTTPBodyContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPBodyNotContains asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContains(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)\n}\n\n// HTTPBodyNotContainsf asserts that a specified handler returns a\n// body that does not contain a string.\n//\n//\ta.HTTPBodyNotContainsf(myHandler, \"GET\", \"www.google.com\", nil, \"I'm Feeling Lucky\", \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)\n}\n\n// HTTPError asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPError(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPError(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPErrorf asserts that a specified handler returns an error status code.\n//\n//\ta.HTTPErrorf(myHandler, \"POST\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPErrorf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPRedirect asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirect(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPRedirectf asserts that a specified handler returns a redirect status code.\n//\n//\ta.HTTPRedirectf(myHandler, \"GET\", \"/a/b/c\", url.Values{\"a\": []string{\"b\", \"c\"}}\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPRedirectf(a.t, handler, method, url, values, msg, args...)\n}\n\n// HTTPStatusCode asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCode(myHandler, \"GET\", \"/notImplemented\", nil, 501)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPStatusCode(a.t, handler, method, url, values, statuscode, msgAndArgs...)\n}\n\n// HTTPStatusCodef asserts that a specified handler returns a specified status code.\n//\n//\ta.HTTPStatusCodef(myHandler, \"GET\", \"/notImplemented\", nil, 501, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPStatusCodef(a.t, handler, method, url, values, statuscode, msg, args...)\n}\n\n// HTTPSuccess asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccess(myHandler, \"POST\", \"http://www.google.com\", nil)\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)\n}\n\n// HTTPSuccessf asserts that a specified handler returns a success status code.\n//\n//\ta.HTTPSuccessf(myHandler, \"POST\", \"http://www.google.com\", nil, \"error message %s\", \"formatted\")\n//\n// Returns whether the assertion was successful (true) or not (false).\nfunc (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tHTTPSuccessf(a.t, handler, method, url, values, msg, args...)\n}\n\n// Implements asserts that an object is implemented by the specified interface.\n//\n//\ta.Implements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tImplements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// Implementsf asserts that an object is implemented by the specified interface.\n//\n//\ta.Implementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tImplementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// InDelta asserts that the two numerals are within delta of each other.\n//\n//\ta.InDelta(math.Pi, 22/7.0, 0.01)\nfunc (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDelta(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.\nfunc (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaSlice is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// InDeltaSlicef is the same as InDelta, except it compares two slices.\nfunc (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaSlicef(a.t, expected, actual, delta, msg, args...)\n}\n\n// InDeltaf asserts that the two numerals are within delta of each other.\n//\n//\ta.InDeltaf(math.Pi, 22/7.0, 0.01, \"error message %s\", \"formatted\")\nfunc (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInDeltaf(a.t, expected, actual, delta, msg, args...)\n}\n\n// InEpsilon asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)\n}\n\n// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.\nfunc (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// InEpsilonf asserts that expected and actual have a relative error less than epsilon\nfunc (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tInEpsilonf(a.t, expected, actual, epsilon, msg, args...)\n}\n\n// IsDecreasing asserts that the collection is decreasing\n//\n//\ta.IsDecreasing([]int{2, 1, 0})\n//\ta.IsDecreasing([]float{2, 1})\n//\ta.IsDecreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsDecreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsDecreasingf asserts that the collection is decreasing\n//\n//\ta.IsDecreasingf([]int{2, 1, 0}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsDecreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsDecreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsDecreasingf(a.t, object, msg, args...)\n}\n\n// IsIncreasing asserts that the collection is increasing\n//\n//\ta.IsIncreasing([]int{1, 2, 3})\n//\ta.IsIncreasing([]float{1, 2})\n//\ta.IsIncreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsIncreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsIncreasingf asserts that the collection is increasing\n//\n//\ta.IsIncreasingf([]int{1, 2, 3}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsIncreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsIncreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsIncreasingf(a.t, object, msg, args...)\n}\n\n// IsNonDecreasing asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasing([]int{1, 1, 2})\n//\ta.IsNonDecreasing([]float{1, 2})\n//\ta.IsNonDecreasing([]string{\"a\", \"b\"})\nfunc (a *Assertions) IsNonDecreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonDecreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonDecreasingf asserts that the collection is not decreasing\n//\n//\ta.IsNonDecreasingf([]int{1, 1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]float{1, 2}, \"error message %s\", \"formatted\")\n//\ta.IsNonDecreasingf([]string{\"a\", \"b\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonDecreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonDecreasingf(a.t, object, msg, args...)\n}\n\n// IsNonIncreasing asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasing([]int{2, 1, 1})\n//\ta.IsNonIncreasing([]float{2, 1})\n//\ta.IsNonIncreasing([]string{\"b\", \"a\"})\nfunc (a *Assertions) IsNonIncreasing(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonIncreasing(a.t, object, msgAndArgs...)\n}\n\n// IsNonIncreasingf asserts that the collection is not increasing\n//\n//\ta.IsNonIncreasingf([]int{2, 1, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]float{2, 1}, \"error message %s\", \"formatted\")\n//\ta.IsNonIncreasingf([]string{\"b\", \"a\"}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) IsNonIncreasingf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsNonIncreasingf(a.t, object, msg, args...)\n}\n\n// IsType asserts that the specified objects are of the same type.\nfunc (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsType(a.t, expectedType, object, msgAndArgs...)\n}\n\n// IsTypef asserts that the specified objects are of the same type.\nfunc (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tIsTypef(a.t, expectedType, object, msg, args...)\n}\n\n// JSONEq asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEq(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`)\nfunc (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tJSONEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// JSONEqf asserts that two JSON strings are equivalent.\n//\n//\ta.JSONEqf(`{\"hello\": \"world\", \"foo\": \"bar\"}`, `{\"foo\": \"bar\", \"hello\": \"world\"}`, \"error message %s\", \"formatted\")\nfunc (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tJSONEqf(a.t, expected, actual, msg, args...)\n}\n\n// Len asserts that the specified object has specific length.\n// Len also fails if the object has a type that len() not accept.\n//\n//\ta.Len(mySlice, 3)\nfunc (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLen(a.t, object, length, msgAndArgs...)\n}\n\n// Lenf asserts that the specified object has specific length.\n// Lenf also fails if the object has a type that len() not accept.\n//\n//\ta.Lenf(mySlice, 3, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLenf(a.t, object, length, msg, args...)\n}\n\n// Less asserts that the first element is less than the second\n//\n//\ta.Less(1, 2)\n//\ta.Less(float64(1), float64(2))\n//\ta.Less(\"a\", \"b\")\nfunc (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLess(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqual asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqual(1, 2)\n//\ta.LessOrEqual(2, 2)\n//\ta.LessOrEqual(\"a\", \"b\")\n//\ta.LessOrEqual(\"b\", \"b\")\nfunc (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLessOrEqual(a.t, e1, e2, msgAndArgs...)\n}\n\n// LessOrEqualf asserts that the first element is less than or equal to the second\n//\n//\ta.LessOrEqualf(1, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(2, 2, \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"a\", \"b\", \"error message %s\", \"formatted\")\n//\ta.LessOrEqualf(\"b\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLessOrEqualf(a.t, e1, e2, msg, args...)\n}\n\n// Lessf asserts that the first element is less than the second\n//\n//\ta.Lessf(1, 2, \"error message %s\", \"formatted\")\n//\ta.Lessf(float64(1), float64(2), \"error message %s\", \"formatted\")\n//\ta.Lessf(\"a\", \"b\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tLessf(a.t, e1, e2, msg, args...)\n}\n\n// Negative asserts that the specified element is negative\n//\n//\ta.Negative(-1)\n//\ta.Negative(-1.23)\nfunc (a *Assertions) Negative(e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNegative(a.t, e, msgAndArgs...)\n}\n\n// Negativef asserts that the specified element is negative\n//\n//\ta.Negativef(-1, \"error message %s\", \"formatted\")\n//\ta.Negativef(-1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Negativef(e interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNegativef(a.t, e, msg, args...)\n}\n\n// Never asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Never(func() bool { return false; }, time.Second, 10*time.Millisecond)\nfunc (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNever(a.t, condition, waitFor, tick, msgAndArgs...)\n}\n\n// Neverf asserts that the given condition doesn't satisfy in waitFor time,\n// periodically checking the target function each tick.\n//\n//\ta.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNeverf(a.t, condition, waitFor, tick, msg, args...)\n}\n\n// Nil asserts that the specified object is nil.\n//\n//\ta.Nil(err)\nfunc (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNil(a.t, object, msgAndArgs...)\n}\n\n// Nilf asserts that the specified object is nil.\n//\n//\ta.Nilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNilf(a.t, object, msg, args...)\n}\n\n// NoDirExists checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoDirExists(a.t, path, msgAndArgs...)\n}\n\n// NoDirExistsf checks whether a directory does not exist in the given path.\n// It fails if the path points to an existing _directory_ only.\nfunc (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoDirExistsf(a.t, path, msg, args...)\n}\n\n// NoError asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoError(err) {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoError(err error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoError(a.t, err, msgAndArgs...)\n}\n\n// NoErrorf asserts that a function returned no error (i.e. `nil`).\n//\n//\t  actualObj, err := SomeFunction()\n//\t  if a.NoErrorf(err, \"error message %s\", \"formatted\") {\n//\t\t   assert.Equal(t, expectedObj, actualObj)\n//\t  }\nfunc (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoErrorf(a.t, err, msg, args...)\n}\n\n// NoFileExists checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoFileExists(a.t, path, msgAndArgs...)\n}\n\n// NoFileExistsf checks whether a file does not exist in a given path. It fails\n// if the path points to an existing _file_ only.\nfunc (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNoFileExistsf(a.t, path, msg, args...)\n}\n\n// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContains(\"Hello World\", \"Earth\")\n//\ta.NotContains([\"Hello\", \"World\"], \"Earth\")\n//\ta.NotContains({\"Hello\": \"World\"}, \"Earth\")\nfunc (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotContains(a.t, s, contains, msgAndArgs...)\n}\n\n// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the\n// specified substring or element.\n//\n//\ta.NotContainsf(\"Hello World\", \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf([\"Hello\", \"World\"], \"Earth\", \"error message %s\", \"formatted\")\n//\ta.NotContainsf({\"Hello\": \"World\"}, \"Earth\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotContainsf(a.t, s, contains, msg, args...)\n}\n\n// NotEmpty asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif a.NotEmpty(obj) {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEmpty(a.t, object, msgAndArgs...)\n}\n\n// NotEmptyf asserts that the specified object is NOT empty.  I.e. not nil, \"\", false, 0 or either\n// a slice or a channel with len == 0.\n//\n//\tif a.NotEmptyf(obj, \"error message %s\", \"formatted\") {\n//\t  assert.Equal(t, \"two\", obj[1])\n//\t}\nfunc (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEmptyf(a.t, object, msg, args...)\n}\n\n// NotEqual asserts that the specified values are NOT equal.\n//\n//\ta.NotEqual(obj1, obj2)\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqual(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValues asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValues(obj1, obj2)\nfunc (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqualValues(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotEqualValuesf asserts that two objects are not equal even when converted to the same type\n//\n//\ta.NotEqualValuesf(obj1, obj2, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqualValuesf(a.t, expected, actual, msg, args...)\n}\n\n// NotEqualf asserts that the specified values are NOT equal.\n//\n//\ta.NotEqualf(obj1, obj2, \"error message %s\", \"formatted\")\n//\n// Pointer variable equality is determined based on the equality of the\n// referenced values (as opposed to the memory addresses).\nfunc (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotEqualf(a.t, expected, actual, msg, args...)\n}\n\n// NotErrorIs asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIs(err error, target error, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotErrorIs(a.t, err, target, msgAndArgs...)\n}\n\n// NotErrorIsf asserts that at none of the errors in err's chain matches target.\n// This is a wrapper for errors.Is.\nfunc (a *Assertions) NotErrorIsf(err error, target error, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotErrorIsf(a.t, err, target, msg, args...)\n}\n\n// NotImplements asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplements((*MyInterface)(nil), new(MyObject))\nfunc (a *Assertions) NotImplements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotImplements(a.t, interfaceObject, object, msgAndArgs...)\n}\n\n// NotImplementsf asserts that an object does not implement the specified interface.\n//\n//\ta.NotImplementsf((*MyInterface)(nil), new(MyObject), \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotImplementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotImplementsf(a.t, interfaceObject, object, msg, args...)\n}\n\n// NotNil asserts that the specified object is not nil.\n//\n//\ta.NotNil(err)\nfunc (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotNil(a.t, object, msgAndArgs...)\n}\n\n// NotNilf asserts that the specified object is not nil.\n//\n//\ta.NotNilf(err, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotNilf(a.t, object, msg, args...)\n}\n\n// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanics(func(){ RemainCalm() })\nfunc (a *Assertions) NotPanics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotPanics(a.t, f, msgAndArgs...)\n}\n\n// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic.\n//\n//\ta.NotPanicsf(func(){ RemainCalm() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotPanicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotPanicsf(a.t, f, msg, args...)\n}\n\n// NotRegexp asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexp(regexp.MustCompile(\"starts\"), \"it's starting\")\n//\ta.NotRegexp(\"^start\", \"it's not starting\")\nfunc (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotRegexp(a.t, rx, str, msgAndArgs...)\n}\n\n// NotRegexpf asserts that a specified regexp does not match a string.\n//\n//\ta.NotRegexpf(regexp.MustCompile(\"starts\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.NotRegexpf(\"^start\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotRegexpf(a.t, rx, str, msg, args...)\n}\n\n// NotSame asserts that two pointers do not reference the same object.\n//\n//\ta.NotSame(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSame(a.t, expected, actual, msgAndArgs...)\n}\n\n// NotSamef asserts that two pointers do not reference the same object.\n//\n//\ta.NotSamef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSamef(a.t, expected, actual, msg, args...)\n}\n\n// NotSubset asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\ta.NotSubset([1, 3, 4], [1, 2])\n//\ta.NotSubset({\"x\": 1, \"y\": 2}, {\"z\": 3})\nfunc (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSubset(a.t, list, subset, msgAndArgs...)\n}\n\n// NotSubsetf asserts that the specified list(array, slice...) or map does NOT\n// contain all elements given in the specified subset list(array, slice...) or\n// map.\n//\n//\ta.NotSubsetf([1, 3, 4], [1, 2], \"error message %s\", \"formatted\")\n//\ta.NotSubsetf({\"x\": 1, \"y\": 2}, {\"z\": 3}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotSubsetf(a.t, list, subset, msg, args...)\n}\n\n// NotZero asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotZero(a.t, i, msgAndArgs...)\n}\n\n// NotZerof asserts that i is not the zero value for its type.\nfunc (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tNotZerof(a.t, i, msg, args...)\n}\n\n// Panics asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panics(func(){ GoCrazy() })\nfunc (a *Assertions) Panics(f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanics(a.t, f, msgAndArgs...)\n}\n\n// PanicsWithError asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithError(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithError(errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithError(a.t, errString, f, msgAndArgs...)\n}\n\n// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc\n// panics, and that the recovered panic value is an error that satisfies the\n// EqualError comparison.\n//\n//\ta.PanicsWithErrorf(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithErrorf(errString string, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithErrorf(a.t, errString, f, msg, args...)\n}\n\n// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValue(\"crazy error\", func(){ GoCrazy() })\nfunc (a *Assertions) PanicsWithValue(expected interface{}, f assert.PanicTestFunc, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithValue(a.t, expected, f, msgAndArgs...)\n}\n\n// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that\n// the recovered panic value equals the expected panic value.\n//\n//\ta.PanicsWithValuef(\"crazy error\", func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) PanicsWithValuef(expected interface{}, f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsWithValuef(a.t, expected, f, msg, args...)\n}\n\n// Panicsf asserts that the code inside the specified PanicTestFunc panics.\n//\n//\ta.Panicsf(func(){ GoCrazy() }, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Panicsf(f assert.PanicTestFunc, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPanicsf(a.t, f, msg, args...)\n}\n\n// Positive asserts that the specified element is positive\n//\n//\ta.Positive(1)\n//\ta.Positive(1.23)\nfunc (a *Assertions) Positive(e interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPositive(a.t, e, msgAndArgs...)\n}\n\n// Positivef asserts that the specified element is positive\n//\n//\ta.Positivef(1, \"error message %s\", \"formatted\")\n//\ta.Positivef(1.23, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Positivef(e interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tPositivef(a.t, e, msg, args...)\n}\n\n// Regexp asserts that a specified regexp matches a string.\n//\n//\ta.Regexp(regexp.MustCompile(\"start\"), \"it's starting\")\n//\ta.Regexp(\"start...$\", \"it's not starting\")\nfunc (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tRegexp(a.t, rx, str, msgAndArgs...)\n}\n\n// Regexpf asserts that a specified regexp matches a string.\n//\n//\ta.Regexpf(regexp.MustCompile(\"start\"), \"it's starting\", \"error message %s\", \"formatted\")\n//\ta.Regexpf(\"start...$\", \"it's not starting\", \"error message %s\", \"formatted\")\nfunc (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tRegexpf(a.t, rx, str, msg, args...)\n}\n\n// Same asserts that two pointers reference the same object.\n//\n//\ta.Same(ptr1, ptr2)\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSame(a.t, expected, actual, msgAndArgs...)\n}\n\n// Samef asserts that two pointers reference the same object.\n//\n//\ta.Samef(ptr1, ptr2, \"error message %s\", \"formatted\")\n//\n// Both arguments must be pointer variables. Pointer variable sameness is\n// determined based on the equality of both type and value.\nfunc (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSamef(a.t, expected, actual, msg, args...)\n}\n\n// Subset asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\ta.Subset([1, 2, 3], [1, 2])\n//\ta.Subset({\"x\": 1, \"y\": 2}, {\"x\": 1})\nfunc (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSubset(a.t, list, subset, msgAndArgs...)\n}\n\n// Subsetf asserts that the specified list(array, slice...) or map contains all\n// elements given in the specified subset list(array, slice...) or map.\n//\n//\ta.Subsetf([1, 2, 3], [1, 2], \"error message %s\", \"formatted\")\n//\ta.Subsetf({\"x\": 1, \"y\": 2}, {\"x\": 1}, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tSubsetf(a.t, list, subset, msg, args...)\n}\n\n// True asserts that the specified value is true.\n//\n//\ta.True(myBool)\nfunc (a *Assertions) True(value bool, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tTrue(a.t, value, msgAndArgs...)\n}\n\n// Truef asserts that the specified value is true.\n//\n//\ta.Truef(myBool, \"error message %s\", \"formatted\")\nfunc (a *Assertions) Truef(value bool, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tTruef(a.t, value, msg, args...)\n}\n\n// WithinDuration asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDuration(time.Now(), time.Now(), 10*time.Second)\nfunc (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinDuration(a.t, expected, actual, delta, msgAndArgs...)\n}\n\n// WithinDurationf asserts that the two times are within duration delta of each other.\n//\n//\ta.WithinDurationf(time.Now(), time.Now(), 10*time.Second, \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinDurationf(a.t, expected, actual, delta, msg, args...)\n}\n\n// WithinRange asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRange(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second))\nfunc (a *Assertions) WithinRange(actual time.Time, start time.Time, end time.Time, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinRange(a.t, actual, start, end, msgAndArgs...)\n}\n\n// WithinRangef asserts that a time is within a time range (inclusive).\n//\n//\ta.WithinRangef(time.Now(), time.Now().Add(-time.Second), time.Now().Add(time.Second), \"error message %s\", \"formatted\")\nfunc (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Time, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tWithinRangef(a.t, actual, start, end, msg, args...)\n}\n\n// YAMLEq asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tYAMLEq(a.t, expected, actual, msgAndArgs...)\n}\n\n// YAMLEqf asserts that two YAML strings are equivalent.\nfunc (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tYAMLEqf(a.t, expected, actual, msg, args...)\n}\n\n// Zero asserts that i is the zero value for its type.\nfunc (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tZero(a.t, i, msgAndArgs...)\n}\n\n// Zerof asserts that i is the zero value for its type.\nfunc (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) {\n\tif h, ok := a.t.(tHelper); ok {\n\t\th.Helper()\n\t}\n\tZerof(a.t, i, msg, args...)\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/require_forward.go.tmpl",
    "content": "{{.CommentWithoutT \"a\"}}\nfunc (a *Assertions) {{.DocInfo.Name}}({{.Params}}) {\n\tif h, ok := a.t.(tHelper); ok { h.Helper() }\n\t{{.DocInfo.Name}}(a.t, {{.ForwardedParams}})\n}\n"
  },
  {
    "path": "vendor/github.com/stretchr/testify/require/requirements.go",
    "content": "package require\n\n// TestingT is an interface wrapper around *testing.T\ntype TestingT interface {\n\tErrorf(format string, args ...interface{})\n\tFailNow()\n}\n\ntype tHelper interface {\n\tHelper()\n}\n\n// ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful\n// for table driven tests.\ntype ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{})\n\n// ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful\n// for table driven tests.\ntype ValueAssertionFunc func(TestingT, interface{}, ...interface{})\n\n// BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful\n// for table driven tests.\ntype BoolAssertionFunc func(TestingT, bool, ...interface{})\n\n// ErrorAssertionFunc is a common function prototype when validating an error value.  Can be useful\n// for table driven tests.\ntype ErrorAssertionFunc func(TestingT, error, ...interface{})\n\n//go:generate sh -c \"cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=require -template=require.go.tmpl -include-format-funcs\"\n"
  },
  {
    "path": "vendor/github.com/syndtr/gocapability/LICENSE",
    "content": "Copyright 2013 Suryandaru Triandana <syndtr@gmail.com>\nAll 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    * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n    * Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\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\nHOLDER 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": "vendor/github.com/syndtr/gocapability/capability/capability.go",
    "content": "// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>\n// All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// Package capability provides utilities for manipulating POSIX capabilities.\npackage capability\n\ntype Capabilities interface {\n\t// Get check whether a capability present in the given\n\t// capabilities set. The 'which' value should be one of EFFECTIVE,\n\t// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.\n\tGet(which CapType, what Cap) bool\n\n\t// Empty check whether all capability bits of the given capabilities\n\t// set are zero. The 'which' value should be one of EFFECTIVE,\n\t// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.\n\tEmpty(which CapType) bool\n\n\t// Full check whether all capability bits of the given capabilities\n\t// set are one. The 'which' value should be one of EFFECTIVE,\n\t// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.\n\tFull(which CapType) bool\n\n\t// Set sets capabilities of the given capabilities sets. The\n\t// 'which' value should be one or combination (OR'ed) of EFFECTIVE,\n\t// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.\n\tSet(which CapType, caps ...Cap)\n\n\t// Unset unsets capabilities of the given capabilities sets. The\n\t// 'which' value should be one or combination (OR'ed) of EFFECTIVE,\n\t// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.\n\tUnset(which CapType, caps ...Cap)\n\n\t// Fill sets all bits of the given capabilities kind to one. The\n\t// 'kind' value should be one or combination (OR'ed) of CAPS,\n\t// BOUNDS or AMBS.\n\tFill(kind CapType)\n\n\t// Clear sets all bits of the given capabilities kind to zero. The\n\t// 'kind' value should be one or combination (OR'ed) of CAPS,\n\t// BOUNDS or AMBS.\n\tClear(kind CapType)\n\n\t// String return current capabilities state of the given capabilities\n\t// set as string. The 'which' value should be one of EFFECTIVE,\n\t// PERMITTED, INHERITABLE BOUNDING or AMBIENT\n\tStringCap(which CapType) string\n\n\t// String return current capabilities state as string.\n\tString() string\n\n\t// Load load actual capabilities value. This will overwrite all\n\t// outstanding changes.\n\tLoad() error\n\n\t// Apply apply the capabilities settings, so all changes will take\n\t// effect.\n\tApply(kind CapType) error\n}\n\n// NewPid initializes a new Capabilities object for given pid when\n// it is nonzero, or for the current process if pid is 0.\n//\n// Deprecated: Replace with NewPid2.  For example, replace:\n//\n//    c, err := NewPid(0)\n//    if err != nil {\n//      return err\n//    }\n//\n// with:\n//\n//    c, err := NewPid2(0)\n//    if err != nil {\n//      return err\n//    }\n//    err = c.Load()\n//    if err != nil {\n//      return err\n//    }\nfunc NewPid(pid int) (Capabilities, error) {\n\tc, err := newPid(pid)\n\tif err != nil {\n\t\treturn c, err\n\t}\n\terr = c.Load()\n\treturn c, err\n}\n\n// NewPid2 initializes a new Capabilities object for given pid when\n// it is nonzero, or for the current process if pid is 0.  This\n// does not load the process's current capabilities; to do that you\n// must call Load explicitly.\nfunc NewPid2(pid int) (Capabilities, error) {\n\treturn newPid(pid)\n}\n\n// NewFile initializes a new Capabilities object for given file path.\n//\n// Deprecated: Replace with NewFile2.  For example, replace:\n//\n//    c, err := NewFile(path)\n//    if err != nil {\n//      return err\n//    }\n//\n// with:\n//\n//    c, err := NewFile2(path)\n//    if err != nil {\n//      return err\n//    }\n//    err = c.Load()\n//    if err != nil {\n//      return err\n//    }\nfunc NewFile(path string) (Capabilities, error) {\n\tc, err := newFile(path)\n\tif err != nil {\n\t\treturn c, err\n\t}\n\terr = c.Load()\n\treturn c, err\n}\n\n// NewFile2 creates a new initialized Capabilities object for given\n// file path.  This does not load the process's current capabilities;\n// to do that you must call Load explicitly.\nfunc NewFile2(path string) (Capabilities, error) {\n\treturn newFile(path)\n}\n"
  },
  {
    "path": "vendor/github.com/syndtr/gocapability/capability/capability_linux.go",
    "content": "// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>\n// All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\npackage capability\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"syscall\"\n)\n\nvar errUnknownVers = errors.New(\"unknown capability version\")\n\nconst (\n\tlinuxCapVer1 = 0x19980330\n\tlinuxCapVer2 = 0x20071026\n\tlinuxCapVer3 = 0x20080522\n)\n\nvar (\n\tcapVers    uint32\n\tcapLastCap Cap\n)\n\nfunc init() {\n\tvar hdr capHeader\n\tcapget(&hdr, nil)\n\tcapVers = hdr.version\n\n\tif initLastCap() == nil {\n\t\tCAP_LAST_CAP = capLastCap\n\t\tif capLastCap > 31 {\n\t\t\tcapUpperMask = (uint32(1) << (uint(capLastCap) - 31)) - 1\n\t\t} else {\n\t\t\tcapUpperMask = 0\n\t\t}\n\t}\n}\n\nfunc initLastCap() error {\n\tif capLastCap != 0 {\n\t\treturn nil\n\t}\n\n\tf, err := os.Open(\"/proc/sys/kernel/cap_last_cap\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer f.Close()\n\n\tvar b []byte = make([]byte, 11)\n\t_, err = f.Read(b)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Sscanf(string(b), \"%d\", &capLastCap)\n\n\treturn nil\n}\n\nfunc mkStringCap(c Capabilities, which CapType) (ret string) {\n\tfor i, first := Cap(0), true; i <= CAP_LAST_CAP; i++ {\n\t\tif !c.Get(which, i) {\n\t\t\tcontinue\n\t\t}\n\t\tif first {\n\t\t\tfirst = false\n\t\t} else {\n\t\t\tret += \", \"\n\t\t}\n\t\tret += i.String()\n\t}\n\treturn\n}\n\nfunc mkString(c Capabilities, max CapType) (ret string) {\n\tret = \"{\"\n\tfor i := CapType(1); i <= max; i <<= 1 {\n\t\tret += \" \" + i.String() + \"=\\\"\"\n\t\tif c.Empty(i) {\n\t\t\tret += \"empty\"\n\t\t} else if c.Full(i) {\n\t\t\tret += \"full\"\n\t\t} else {\n\t\t\tret += c.StringCap(i)\n\t\t}\n\t\tret += \"\\\"\"\n\t}\n\tret += \" }\"\n\treturn\n}\n\nfunc newPid(pid int) (c Capabilities, err error) {\n\tswitch capVers {\n\tcase linuxCapVer1:\n\t\tp := new(capsV1)\n\t\tp.hdr.version = capVers\n\t\tp.hdr.pid = int32(pid)\n\t\tc = p\n\tcase linuxCapVer2, linuxCapVer3:\n\t\tp := new(capsV3)\n\t\tp.hdr.version = capVers\n\t\tp.hdr.pid = int32(pid)\n\t\tc = p\n\tdefault:\n\t\terr = errUnknownVers\n\t\treturn\n\t}\n\treturn\n}\n\ntype capsV1 struct {\n\thdr  capHeader\n\tdata capData\n}\n\nfunc (c *capsV1) Get(which CapType, what Cap) bool {\n\tif what > 32 {\n\t\treturn false\n\t}\n\n\tswitch which {\n\tcase EFFECTIVE:\n\t\treturn (1<<uint(what))&c.data.effective != 0\n\tcase PERMITTED:\n\t\treturn (1<<uint(what))&c.data.permitted != 0\n\tcase INHERITABLE:\n\t\treturn (1<<uint(what))&c.data.inheritable != 0\n\t}\n\n\treturn false\n}\n\nfunc (c *capsV1) getData(which CapType) (ret uint32) {\n\tswitch which {\n\tcase EFFECTIVE:\n\t\tret = c.data.effective\n\tcase PERMITTED:\n\t\tret = c.data.permitted\n\tcase INHERITABLE:\n\t\tret = c.data.inheritable\n\t}\n\treturn\n}\n\nfunc (c *capsV1) Empty(which CapType) bool {\n\treturn c.getData(which) == 0\n}\n\nfunc (c *capsV1) Full(which CapType) bool {\n\treturn (c.getData(which) & 0x7fffffff) == 0x7fffffff\n}\n\nfunc (c *capsV1) Set(which CapType, caps ...Cap) {\n\tfor _, what := range caps {\n\t\tif what > 32 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif which&EFFECTIVE != 0 {\n\t\t\tc.data.effective |= 1 << uint(what)\n\t\t}\n\t\tif which&PERMITTED != 0 {\n\t\t\tc.data.permitted |= 1 << uint(what)\n\t\t}\n\t\tif which&INHERITABLE != 0 {\n\t\t\tc.data.inheritable |= 1 << uint(what)\n\t\t}\n\t}\n}\n\nfunc (c *capsV1) Unset(which CapType, caps ...Cap) {\n\tfor _, what := range caps {\n\t\tif what > 32 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif which&EFFECTIVE != 0 {\n\t\t\tc.data.effective &= ^(1 << uint(what))\n\t\t}\n\t\tif which&PERMITTED != 0 {\n\t\t\tc.data.permitted &= ^(1 << uint(what))\n\t\t}\n\t\tif which&INHERITABLE != 0 {\n\t\t\tc.data.inheritable &= ^(1 << uint(what))\n\t\t}\n\t}\n}\n\nfunc (c *capsV1) Fill(kind CapType) {\n\tif kind&CAPS == CAPS {\n\t\tc.data.effective = 0x7fffffff\n\t\tc.data.permitted = 0x7fffffff\n\t\tc.data.inheritable = 0\n\t}\n}\n\nfunc (c *capsV1) Clear(kind CapType) {\n\tif kind&CAPS == CAPS {\n\t\tc.data.effective = 0\n\t\tc.data.permitted = 0\n\t\tc.data.inheritable = 0\n\t}\n}\n\nfunc (c *capsV1) StringCap(which CapType) (ret string) {\n\treturn mkStringCap(c, which)\n}\n\nfunc (c *capsV1) String() (ret string) {\n\treturn mkString(c, BOUNDING)\n}\n\nfunc (c *capsV1) Load() (err error) {\n\treturn capget(&c.hdr, &c.data)\n}\n\nfunc (c *capsV1) Apply(kind CapType) error {\n\tif kind&CAPS == CAPS {\n\t\treturn capset(&c.hdr, &c.data)\n\t}\n\treturn nil\n}\n\ntype capsV3 struct {\n\thdr     capHeader\n\tdata    [2]capData\n\tbounds  [2]uint32\n\tambient [2]uint32\n}\n\nfunc (c *capsV3) Get(which CapType, what Cap) bool {\n\tvar i uint\n\tif what > 31 {\n\t\ti = uint(what) >> 5\n\t\twhat %= 32\n\t}\n\n\tswitch which {\n\tcase EFFECTIVE:\n\t\treturn (1<<uint(what))&c.data[i].effective != 0\n\tcase PERMITTED:\n\t\treturn (1<<uint(what))&c.data[i].permitted != 0\n\tcase INHERITABLE:\n\t\treturn (1<<uint(what))&c.data[i].inheritable != 0\n\tcase BOUNDING:\n\t\treturn (1<<uint(what))&c.bounds[i] != 0\n\tcase AMBIENT:\n\t\treturn (1<<uint(what))&c.ambient[i] != 0\n\t}\n\n\treturn false\n}\n\nfunc (c *capsV3) getData(which CapType, dest []uint32) {\n\tswitch which {\n\tcase EFFECTIVE:\n\t\tdest[0] = c.data[0].effective\n\t\tdest[1] = c.data[1].effective\n\tcase PERMITTED:\n\t\tdest[0] = c.data[0].permitted\n\t\tdest[1] = c.data[1].permitted\n\tcase INHERITABLE:\n\t\tdest[0] = c.data[0].inheritable\n\t\tdest[1] = c.data[1].inheritable\n\tcase BOUNDING:\n\t\tdest[0] = c.bounds[0]\n\t\tdest[1] = c.bounds[1]\n\tcase AMBIENT:\n\t\tdest[0] = c.ambient[0]\n\t\tdest[1] = c.ambient[1]\n\t}\n}\n\nfunc (c *capsV3) Empty(which CapType) bool {\n\tvar data [2]uint32\n\tc.getData(which, data[:])\n\treturn data[0] == 0 && data[1] == 0\n}\n\nfunc (c *capsV3) Full(which CapType) bool {\n\tvar data [2]uint32\n\tc.getData(which, data[:])\n\tif (data[0] & 0xffffffff) != 0xffffffff {\n\t\treturn false\n\t}\n\treturn (data[1] & capUpperMask) == capUpperMask\n}\n\nfunc (c *capsV3) Set(which CapType, caps ...Cap) {\n\tfor _, what := range caps {\n\t\tvar i uint\n\t\tif what > 31 {\n\t\t\ti = uint(what) >> 5\n\t\t\twhat %= 32\n\t\t}\n\n\t\tif which&EFFECTIVE != 0 {\n\t\t\tc.data[i].effective |= 1 << uint(what)\n\t\t}\n\t\tif which&PERMITTED != 0 {\n\t\t\tc.data[i].permitted |= 1 << uint(what)\n\t\t}\n\t\tif which&INHERITABLE != 0 {\n\t\t\tc.data[i].inheritable |= 1 << uint(what)\n\t\t}\n\t\tif which&BOUNDING != 0 {\n\t\t\tc.bounds[i] |= 1 << uint(what)\n\t\t}\n\t\tif which&AMBIENT != 0 {\n\t\t\tc.ambient[i] |= 1 << uint(what)\n\t\t}\n\t}\n}\n\nfunc (c *capsV3) Unset(which CapType, caps ...Cap) {\n\tfor _, what := range caps {\n\t\tvar i uint\n\t\tif what > 31 {\n\t\t\ti = uint(what) >> 5\n\t\t\twhat %= 32\n\t\t}\n\n\t\tif which&EFFECTIVE != 0 {\n\t\t\tc.data[i].effective &= ^(1 << uint(what))\n\t\t}\n\t\tif which&PERMITTED != 0 {\n\t\t\tc.data[i].permitted &= ^(1 << uint(what))\n\t\t}\n\t\tif which&INHERITABLE != 0 {\n\t\t\tc.data[i].inheritable &= ^(1 << uint(what))\n\t\t}\n\t\tif which&BOUNDING != 0 {\n\t\t\tc.bounds[i] &= ^(1 << uint(what))\n\t\t}\n\t\tif which&AMBIENT != 0 {\n\t\t\tc.ambient[i] &= ^(1 << uint(what))\n\t\t}\n\t}\n}\n\nfunc (c *capsV3) Fill(kind CapType) {\n\tif kind&CAPS == CAPS {\n\t\tc.data[0].effective = 0xffffffff\n\t\tc.data[0].permitted = 0xffffffff\n\t\tc.data[0].inheritable = 0\n\t\tc.data[1].effective = 0xffffffff\n\t\tc.data[1].permitted = 0xffffffff\n\t\tc.data[1].inheritable = 0\n\t}\n\n\tif kind&BOUNDS == BOUNDS {\n\t\tc.bounds[0] = 0xffffffff\n\t\tc.bounds[1] = 0xffffffff\n\t}\n\tif kind&AMBS == AMBS {\n\t\tc.ambient[0] = 0xffffffff\n\t\tc.ambient[1] = 0xffffffff\n\t}\n}\n\nfunc (c *capsV3) Clear(kind CapType) {\n\tif kind&CAPS == CAPS {\n\t\tc.data[0].effective = 0\n\t\tc.data[0].permitted = 0\n\t\tc.data[0].inheritable = 0\n\t\tc.data[1].effective = 0\n\t\tc.data[1].permitted = 0\n\t\tc.data[1].inheritable = 0\n\t}\n\n\tif kind&BOUNDS == BOUNDS {\n\t\tc.bounds[0] = 0\n\t\tc.bounds[1] = 0\n\t}\n\tif kind&AMBS == AMBS {\n\t\tc.ambient[0] = 0\n\t\tc.ambient[1] = 0\n\t}\n}\n\nfunc (c *capsV3) StringCap(which CapType) (ret string) {\n\treturn mkStringCap(c, which)\n}\n\nfunc (c *capsV3) String() (ret string) {\n\treturn mkString(c, BOUNDING)\n}\n\nfunc (c *capsV3) Load() (err error) {\n\terr = capget(&c.hdr, &c.data[0])\n\tif err != nil {\n\t\treturn\n\t}\n\n\tvar status_path string\n\n\tif c.hdr.pid == 0 {\n\t\tstatus_path = fmt.Sprintf(\"/proc/self/status\")\n\t} else {\n\t\tstatus_path = fmt.Sprintf(\"/proc/%d/status\", c.hdr.pid)\n\t}\n\n\tf, err := os.Open(status_path)\n\tif err != nil {\n\t\treturn\n\t}\n\tb := bufio.NewReader(f)\n\tfor {\n\t\tline, e := b.ReadString('\\n')\n\t\tif e != nil {\n\t\t\tif e != io.EOF {\n\t\t\t\terr = e\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif strings.HasPrefix(line, \"CapB\") {\n\t\t\tfmt.Sscanf(line[4:], \"nd:  %08x%08x\", &c.bounds[1], &c.bounds[0])\n\t\t\tcontinue\n\t\t}\n\t\tif strings.HasPrefix(line, \"CapA\") {\n\t\t\tfmt.Sscanf(line[4:], \"mb:  %08x%08x\", &c.ambient[1], &c.ambient[0])\n\t\t\tcontinue\n\t\t}\n\t}\n\tf.Close()\n\n\treturn\n}\n\nfunc (c *capsV3) Apply(kind CapType) (err error) {\n\tif kind&BOUNDS == BOUNDS {\n\t\tvar data [2]capData\n\t\terr = capget(&c.hdr, &data[0])\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t\tif (1<<uint(CAP_SETPCAP))&data[0].effective != 0 {\n\t\t\tfor i := Cap(0); i <= CAP_LAST_CAP; i++ {\n\t\t\t\tif c.Get(BOUNDING, i) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\terr = prctl(syscall.PR_CAPBSET_DROP, uintptr(i), 0, 0, 0)\n\t\t\t\tif err != nil {\n\t\t\t\t\t// Ignore EINVAL since the capability may not be supported in this system.\n\t\t\t\t\tif errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {\n\t\t\t\t\t\terr = nil\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif kind&CAPS == CAPS {\n\t\terr = capset(&c.hdr, &c.data[0])\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif kind&AMBS == AMBS {\n\t\tfor i := Cap(0); i <= CAP_LAST_CAP; i++ {\n\t\t\taction := pr_CAP_AMBIENT_LOWER\n\t\t\tif c.Get(AMBIENT, i) {\n\t\t\t\taction = pr_CAP_AMBIENT_RAISE\n\t\t\t}\n\t\t\terr := prctl(pr_CAP_AMBIENT, action, uintptr(i), 0, 0)\n\t\t\t// Ignore EINVAL as not supported on kernels before 4.3\n\t\t\tif errno, ok := err.(syscall.Errno); ok && errno == syscall.EINVAL {\n\t\t\t\terr = nil\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc newFile(path string) (c Capabilities, err error) {\n\tc = &capsFile{path: path}\n\treturn\n}\n\ntype capsFile struct {\n\tpath string\n\tdata vfscapData\n}\n\nfunc (c *capsFile) Get(which CapType, what Cap) bool {\n\tvar i uint\n\tif what > 31 {\n\t\tif c.data.version == 1 {\n\t\t\treturn false\n\t\t}\n\t\ti = uint(what) >> 5\n\t\twhat %= 32\n\t}\n\n\tswitch which {\n\tcase EFFECTIVE:\n\t\treturn (1<<uint(what))&c.data.effective[i] != 0\n\tcase PERMITTED:\n\t\treturn (1<<uint(what))&c.data.data[i].permitted != 0\n\tcase INHERITABLE:\n\t\treturn (1<<uint(what))&c.data.data[i].inheritable != 0\n\t}\n\n\treturn false\n}\n\nfunc (c *capsFile) getData(which CapType, dest []uint32) {\n\tswitch which {\n\tcase EFFECTIVE:\n\t\tdest[0] = c.data.effective[0]\n\t\tdest[1] = c.data.effective[1]\n\tcase PERMITTED:\n\t\tdest[0] = c.data.data[0].permitted\n\t\tdest[1] = c.data.data[1].permitted\n\tcase INHERITABLE:\n\t\tdest[0] = c.data.data[0].inheritable\n\t\tdest[1] = c.data.data[1].inheritable\n\t}\n}\n\nfunc (c *capsFile) Empty(which CapType) bool {\n\tvar data [2]uint32\n\tc.getData(which, data[:])\n\treturn data[0] == 0 && data[1] == 0\n}\n\nfunc (c *capsFile) Full(which CapType) bool {\n\tvar data [2]uint32\n\tc.getData(which, data[:])\n\tif c.data.version == 0 {\n\t\treturn (data[0] & 0x7fffffff) == 0x7fffffff\n\t}\n\tif (data[0] & 0xffffffff) != 0xffffffff {\n\t\treturn false\n\t}\n\treturn (data[1] & capUpperMask) == capUpperMask\n}\n\nfunc (c *capsFile) Set(which CapType, caps ...Cap) {\n\tfor _, what := range caps {\n\t\tvar i uint\n\t\tif what > 31 {\n\t\t\tif c.data.version == 1 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ti = uint(what) >> 5\n\t\t\twhat %= 32\n\t\t}\n\n\t\tif which&EFFECTIVE != 0 {\n\t\t\tc.data.effective[i] |= 1 << uint(what)\n\t\t}\n\t\tif which&PERMITTED != 0 {\n\t\t\tc.data.data[i].permitted |= 1 << uint(what)\n\t\t}\n\t\tif which&INHERITABLE != 0 {\n\t\t\tc.data.data[i].inheritable |= 1 << uint(what)\n\t\t}\n\t}\n}\n\nfunc (c *capsFile) Unset(which CapType, caps ...Cap) {\n\tfor _, what := range caps {\n\t\tvar i uint\n\t\tif what > 31 {\n\t\t\tif c.data.version == 1 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ti = uint(what) >> 5\n\t\t\twhat %= 32\n\t\t}\n\n\t\tif which&EFFECTIVE != 0 {\n\t\t\tc.data.effective[i] &= ^(1 << uint(what))\n\t\t}\n\t\tif which&PERMITTED != 0 {\n\t\t\tc.data.data[i].permitted &= ^(1 << uint(what))\n\t\t}\n\t\tif which&INHERITABLE != 0 {\n\t\t\tc.data.data[i].inheritable &= ^(1 << uint(what))\n\t\t}\n\t}\n}\n\nfunc (c *capsFile) Fill(kind CapType) {\n\tif kind&CAPS == CAPS {\n\t\tc.data.effective[0] = 0xffffffff\n\t\tc.data.data[0].permitted = 0xffffffff\n\t\tc.data.data[0].inheritable = 0\n\t\tif c.data.version == 2 {\n\t\t\tc.data.effective[1] = 0xffffffff\n\t\t\tc.data.data[1].permitted = 0xffffffff\n\t\t\tc.data.data[1].inheritable = 0\n\t\t}\n\t}\n}\n\nfunc (c *capsFile) Clear(kind CapType) {\n\tif kind&CAPS == CAPS {\n\t\tc.data.effective[0] = 0\n\t\tc.data.data[0].permitted = 0\n\t\tc.data.data[0].inheritable = 0\n\t\tif c.data.version == 2 {\n\t\t\tc.data.effective[1] = 0\n\t\t\tc.data.data[1].permitted = 0\n\t\t\tc.data.data[1].inheritable = 0\n\t\t}\n\t}\n}\n\nfunc (c *capsFile) StringCap(which CapType) (ret string) {\n\treturn mkStringCap(c, which)\n}\n\nfunc (c *capsFile) String() (ret string) {\n\treturn mkString(c, INHERITABLE)\n}\n\nfunc (c *capsFile) Load() (err error) {\n\treturn getVfsCap(c.path, &c.data)\n}\n\nfunc (c *capsFile) Apply(kind CapType) (err error) {\n\tif kind&CAPS == CAPS {\n\t\treturn setVfsCap(c.path, &c.data)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/syndtr/gocapability/capability/capability_noop.go",
    "content": "// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>\n// All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\n// +build !linux\n\npackage capability\n\nimport \"errors\"\n\nfunc newPid(pid int) (Capabilities, error) {\n\treturn nil, errors.New(\"not supported\")\n}\n\nfunc newFile(path string) (Capabilities, error) {\n\treturn nil, errors.New(\"not supported\")\n}\n"
  },
  {
    "path": "vendor/github.com/syndtr/gocapability/capability/enum.go",
    "content": "// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>\n// All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\npackage capability\n\ntype CapType uint\n\nfunc (c CapType) String() string {\n\tswitch c {\n\tcase EFFECTIVE:\n\t\treturn \"effective\"\n\tcase PERMITTED:\n\t\treturn \"permitted\"\n\tcase INHERITABLE:\n\t\treturn \"inheritable\"\n\tcase BOUNDING:\n\t\treturn \"bounding\"\n\tcase CAPS:\n\t\treturn \"caps\"\n\tcase AMBIENT:\n\t\treturn \"ambient\"\n\t}\n\treturn \"unknown\"\n}\n\nconst (\n\tEFFECTIVE CapType = 1 << iota\n\tPERMITTED\n\tINHERITABLE\n\tBOUNDING\n\tAMBIENT\n\n\tCAPS   = EFFECTIVE | PERMITTED | INHERITABLE\n\tBOUNDS = BOUNDING\n\tAMBS   = AMBIENT\n)\n\n//go:generate go run enumgen/gen.go\ntype Cap int\n\n// POSIX-draft defined capabilities and Linux extensions.\n//\n// Defined in https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h\nconst (\n\t// In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this\n\t// overrides the restriction of changing file ownership and group\n\t// ownership.\n\tCAP_CHOWN = Cap(0)\n\n\t// Override all DAC access, including ACL execute access if\n\t// [_POSIX_ACL] is defined. Excluding DAC access covered by\n\t// CAP_LINUX_IMMUTABLE.\n\tCAP_DAC_OVERRIDE = Cap(1)\n\n\t// Overrides all DAC restrictions regarding read and search on files\n\t// and directories, including ACL restrictions if [_POSIX_ACL] is\n\t// defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE.\n\tCAP_DAC_READ_SEARCH = Cap(2)\n\n\t// Overrides all restrictions about allowed operations on files, where\n\t// file owner ID must be equal to the user ID, except where CAP_FSETID\n\t// is applicable. It doesn't override MAC and DAC restrictions.\n\tCAP_FOWNER = Cap(3)\n\n\t// Overrides the following restrictions that the effective user ID\n\t// shall match the file owner ID when setting the S_ISUID and S_ISGID\n\t// bits on that file; that the effective group ID (or one of the\n\t// supplementary group IDs) shall match the file owner ID when setting\n\t// the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are\n\t// cleared on successful return from chown(2) (not implemented).\n\tCAP_FSETID = Cap(4)\n\n\t// Overrides the restriction that the real or effective user ID of a\n\t// process sending a signal must match the real or effective user ID\n\t// of the process receiving the signal.\n\tCAP_KILL = Cap(5)\n\n\t// Allows setgid(2) manipulation\n\t// Allows setgroups(2)\n\t// Allows forged gids on socket credentials passing.\n\tCAP_SETGID = Cap(6)\n\n\t// Allows set*uid(2) manipulation (including fsuid).\n\t// Allows forged pids on socket credentials passing.\n\tCAP_SETUID = Cap(7)\n\n\t// Linux-specific capabilities\n\n\t// Without VFS support for capabilities:\n\t//   Transfer any capability in your permitted set to any pid,\n\t//   remove any capability in your permitted set from any pid\n\t// With VFS support for capabilities (neither of above, but)\n\t//   Add any capability from current's capability bounding set\n\t//     to the current process' inheritable set\n\t//   Allow taking bits out of capability bounding set\n\t//   Allow modification of the securebits for a process\n\tCAP_SETPCAP = Cap(8)\n\n\t// Allow modification of S_IMMUTABLE and S_APPEND file attributes\n\tCAP_LINUX_IMMUTABLE = Cap(9)\n\n\t// Allows binding to TCP/UDP sockets below 1024\n\t// Allows binding to ATM VCIs below 32\n\tCAP_NET_BIND_SERVICE = Cap(10)\n\n\t// Allow broadcasting, listen to multicast\n\tCAP_NET_BROADCAST = Cap(11)\n\n\t// Allow interface configuration\n\t// Allow administration of IP firewall, masquerading and accounting\n\t// Allow setting debug option on sockets\n\t// Allow modification of routing tables\n\t// Allow setting arbitrary process / process group ownership on\n\t// sockets\n\t// Allow binding to any address for transparent proxying (also via NET_RAW)\n\t// Allow setting TOS (type of service)\n\t// Allow setting promiscuous mode\n\t// Allow clearing driver statistics\n\t// Allow multicasting\n\t// Allow read/write of device-specific registers\n\t// Allow activation of ATM control sockets\n\tCAP_NET_ADMIN = Cap(12)\n\n\t// Allow use of RAW sockets\n\t// Allow use of PACKET sockets\n\t// Allow binding to any address for transparent proxying (also via NET_ADMIN)\n\tCAP_NET_RAW = Cap(13)\n\n\t// Allow locking of shared memory segments\n\t// Allow mlock and mlockall (which doesn't really have anything to do\n\t// with IPC)\n\tCAP_IPC_LOCK = Cap(14)\n\n\t// Override IPC ownership checks\n\tCAP_IPC_OWNER = Cap(15)\n\n\t// Insert and remove kernel modules - modify kernel without limit\n\tCAP_SYS_MODULE = Cap(16)\n\n\t// Allow ioperm/iopl access\n\t// Allow sending USB messages to any device via /proc/bus/usb\n\tCAP_SYS_RAWIO = Cap(17)\n\n\t// Allow use of chroot()\n\tCAP_SYS_CHROOT = Cap(18)\n\n\t// Allow ptrace() of any process\n\tCAP_SYS_PTRACE = Cap(19)\n\n\t// Allow configuration of process accounting\n\tCAP_SYS_PACCT = Cap(20)\n\n\t// Allow configuration of the secure attention key\n\t// Allow administration of the random device\n\t// Allow examination and configuration of disk quotas\n\t// Allow setting the domainname\n\t// Allow setting the hostname\n\t// Allow calling bdflush()\n\t// Allow mount() and umount(), setting up new smb connection\n\t// Allow some autofs root ioctls\n\t// Allow nfsservctl\n\t// Allow VM86_REQUEST_IRQ\n\t// Allow to read/write pci config on alpha\n\t// Allow irix_prctl on mips (setstacksize)\n\t// Allow flushing all cache on m68k (sys_cacheflush)\n\t// Allow removing semaphores\n\t// Used instead of CAP_CHOWN to \"chown\" IPC message queues, semaphores\n\t// and shared memory\n\t// Allow locking/unlocking of shared memory segment\n\t// Allow turning swap on/off\n\t// Allow forged pids on socket credentials passing\n\t// Allow setting readahead and flushing buffers on block devices\n\t// Allow setting geometry in floppy driver\n\t// Allow turning DMA on/off in xd driver\n\t// Allow administration of md devices (mostly the above, but some\n\t// extra ioctls)\n\t// Allow tuning the ide driver\n\t// Allow access to the nvram device\n\t// Allow administration of apm_bios, serial and bttv (TV) device\n\t// Allow manufacturer commands in isdn CAPI support driver\n\t// Allow reading non-standardized portions of pci configuration space\n\t// Allow DDI debug ioctl on sbpcd driver\n\t// Allow setting up serial ports\n\t// Allow sending raw qic-117 commands\n\t// Allow enabling/disabling tagged queuing on SCSI controllers and sending\n\t// arbitrary SCSI commands\n\t// Allow setting encryption key on loopback filesystem\n\t// Allow setting zone reclaim policy\n\t// Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility\n\tCAP_SYS_ADMIN = Cap(21)\n\n\t// Allow use of reboot()\n\tCAP_SYS_BOOT = Cap(22)\n\n\t// Allow raising priority and setting priority on other (different\n\t// UID) processes\n\t// Allow use of FIFO and round-robin (realtime) scheduling on own\n\t// processes and setting the scheduling algorithm used by another\n\t// process.\n\t// Allow setting cpu affinity on other processes\n\tCAP_SYS_NICE = Cap(23)\n\n\t// Override resource limits. Set resource limits.\n\t// Override quota limits.\n\t// Override reserved space on ext2 filesystem\n\t// Modify data journaling mode on ext3 filesystem (uses journaling\n\t// resources)\n\t// NOTE: ext2 honors fsuid when checking for resource overrides, so\n\t// you can override using fsuid too\n\t// Override size restrictions on IPC message queues\n\t// Allow more than 64hz interrupts from the real-time clock\n\t// Override max number of consoles on console allocation\n\t// Override max number of keymaps\n\t// Control memory reclaim behavior\n\tCAP_SYS_RESOURCE = Cap(24)\n\n\t// Allow manipulation of system clock\n\t// Allow irix_stime on mips\n\t// Allow setting the real-time clock\n\tCAP_SYS_TIME = Cap(25)\n\n\t// Allow configuration of tty devices\n\t// Allow vhangup() of tty\n\tCAP_SYS_TTY_CONFIG = Cap(26)\n\n\t// Allow the privileged aspects of mknod()\n\tCAP_MKNOD = Cap(27)\n\n\t// Allow taking of leases on files\n\tCAP_LEASE = Cap(28)\n\n\tCAP_AUDIT_WRITE   = Cap(29)\n\tCAP_AUDIT_CONTROL = Cap(30)\n\tCAP_SETFCAP       = Cap(31)\n\n\t// Override MAC access.\n\t// The base kernel enforces no MAC policy.\n\t// An LSM may enforce a MAC policy, and if it does and it chooses\n\t// to implement capability based overrides of that policy, this is\n\t// the capability it should use to do so.\n\tCAP_MAC_OVERRIDE = Cap(32)\n\n\t// Allow MAC configuration or state changes.\n\t// The base kernel requires no MAC configuration.\n\t// An LSM may enforce a MAC policy, and if it does and it chooses\n\t// to implement capability based checks on modifications to that\n\t// policy or the data required to maintain it, this is the\n\t// capability it should use to do so.\n\tCAP_MAC_ADMIN = Cap(33)\n\n\t// Allow configuring the kernel's syslog (printk behaviour)\n\tCAP_SYSLOG = Cap(34)\n\n\t// Allow triggering something that will wake the system\n\tCAP_WAKE_ALARM = Cap(35)\n\n\t// Allow preventing system suspends\n\tCAP_BLOCK_SUSPEND = Cap(36)\n\n\t// Allow reading the audit log via multicast netlink socket\n\tCAP_AUDIT_READ = Cap(37)\n\n\t// Allow system performance and observability privileged operations\n\t// using perf_events, i915_perf and other kernel subsystems\n\tCAP_PERFMON = Cap(38)\n\n\t// CAP_BPF allows the following BPF operations:\n\t// - Creating all types of BPF maps\n\t// - Advanced verifier features\n\t//   - Indirect variable access\n\t//   - Bounded loops\n\t//   - BPF to BPF function calls\n\t//   - Scalar precision tracking\n\t//   - Larger complexity limits\n\t//   - Dead code elimination\n\t//   - And potentially other features\n\t// - Loading BPF Type Format (BTF) data\n\t// - Retrieve xlated and JITed code of BPF programs\n\t// - Use bpf_spin_lock() helper\n\t//\n\t// CAP_PERFMON relaxes the verifier checks further:\n\t// - BPF progs can use of pointer-to-integer conversions\n\t// - speculation attack hardening measures are bypassed\n\t// - bpf_probe_read to read arbitrary kernel memory is allowed\n\t// - bpf_trace_printk to print kernel memory is allowed\n\t//\n\t// CAP_SYS_ADMIN is required to use bpf_probe_write_user.\n\t//\n\t// CAP_SYS_ADMIN is required to iterate system wide loaded\n\t// programs, maps, links, BTFs and convert their IDs to file descriptors.\n\t//\n\t// CAP_PERFMON and CAP_BPF are required to load tracing programs.\n\t// CAP_NET_ADMIN and CAP_BPF are required to load networking programs.\n\tCAP_BPF = Cap(39)\n\n\t// Allow checkpoint/restore related operations.\n\t// Introduced in kernel 5.9\n\tCAP_CHECKPOINT_RESTORE = Cap(40)\n)\n\nvar (\n\t// Highest valid capability of the running kernel.\n\tCAP_LAST_CAP = Cap(63)\n\n\tcapUpperMask = ^uint32(0)\n)\n"
  },
  {
    "path": "vendor/github.com/syndtr/gocapability/capability/enum_gen.go",
    "content": "// generated file; DO NOT EDIT - use go generate in directory with source\n\npackage capability\n\nfunc (c Cap) String() string {\n\tswitch c {\n\tcase CAP_CHOWN:\n\t\treturn \"chown\"\n\tcase CAP_DAC_OVERRIDE:\n\t\treturn \"dac_override\"\n\tcase CAP_DAC_READ_SEARCH:\n\t\treturn \"dac_read_search\"\n\tcase CAP_FOWNER:\n\t\treturn \"fowner\"\n\tcase CAP_FSETID:\n\t\treturn \"fsetid\"\n\tcase CAP_KILL:\n\t\treturn \"kill\"\n\tcase CAP_SETGID:\n\t\treturn \"setgid\"\n\tcase CAP_SETUID:\n\t\treturn \"setuid\"\n\tcase CAP_SETPCAP:\n\t\treturn \"setpcap\"\n\tcase CAP_LINUX_IMMUTABLE:\n\t\treturn \"linux_immutable\"\n\tcase CAP_NET_BIND_SERVICE:\n\t\treturn \"net_bind_service\"\n\tcase CAP_NET_BROADCAST:\n\t\treturn \"net_broadcast\"\n\tcase CAP_NET_ADMIN:\n\t\treturn \"net_admin\"\n\tcase CAP_NET_RAW:\n\t\treturn \"net_raw\"\n\tcase CAP_IPC_LOCK:\n\t\treturn \"ipc_lock\"\n\tcase CAP_IPC_OWNER:\n\t\treturn \"ipc_owner\"\n\tcase CAP_SYS_MODULE:\n\t\treturn \"sys_module\"\n\tcase CAP_SYS_RAWIO:\n\t\treturn \"sys_rawio\"\n\tcase CAP_SYS_CHROOT:\n\t\treturn \"sys_chroot\"\n\tcase CAP_SYS_PTRACE:\n\t\treturn \"sys_ptrace\"\n\tcase CAP_SYS_PACCT:\n\t\treturn \"sys_pacct\"\n\tcase CAP_SYS_ADMIN:\n\t\treturn \"sys_admin\"\n\tcase CAP_SYS_BOOT:\n\t\treturn \"sys_boot\"\n\tcase CAP_SYS_NICE:\n\t\treturn \"sys_nice\"\n\tcase CAP_SYS_RESOURCE:\n\t\treturn \"sys_resource\"\n\tcase CAP_SYS_TIME:\n\t\treturn \"sys_time\"\n\tcase CAP_SYS_TTY_CONFIG:\n\t\treturn \"sys_tty_config\"\n\tcase CAP_MKNOD:\n\t\treturn \"mknod\"\n\tcase CAP_LEASE:\n\t\treturn \"lease\"\n\tcase CAP_AUDIT_WRITE:\n\t\treturn \"audit_write\"\n\tcase CAP_AUDIT_CONTROL:\n\t\treturn \"audit_control\"\n\tcase CAP_SETFCAP:\n\t\treturn \"setfcap\"\n\tcase CAP_MAC_OVERRIDE:\n\t\treturn \"mac_override\"\n\tcase CAP_MAC_ADMIN:\n\t\treturn \"mac_admin\"\n\tcase CAP_SYSLOG:\n\t\treturn \"syslog\"\n\tcase CAP_WAKE_ALARM:\n\t\treturn \"wake_alarm\"\n\tcase CAP_BLOCK_SUSPEND:\n\t\treturn \"block_suspend\"\n\tcase CAP_AUDIT_READ:\n\t\treturn \"audit_read\"\n\tcase CAP_PERFMON:\n\t\treturn \"perfmon\"\n\tcase CAP_BPF:\n\t\treturn \"bpf\"\n\tcase CAP_CHECKPOINT_RESTORE:\n\t\treturn \"checkpoint_restore\"\n\t}\n\treturn \"unknown\"\n}\n\n// List returns list of all supported capabilities\nfunc List() []Cap {\n\treturn []Cap{\n\t\tCAP_CHOWN,\n\t\tCAP_DAC_OVERRIDE,\n\t\tCAP_DAC_READ_SEARCH,\n\t\tCAP_FOWNER,\n\t\tCAP_FSETID,\n\t\tCAP_KILL,\n\t\tCAP_SETGID,\n\t\tCAP_SETUID,\n\t\tCAP_SETPCAP,\n\t\tCAP_LINUX_IMMUTABLE,\n\t\tCAP_NET_BIND_SERVICE,\n\t\tCAP_NET_BROADCAST,\n\t\tCAP_NET_ADMIN,\n\t\tCAP_NET_RAW,\n\t\tCAP_IPC_LOCK,\n\t\tCAP_IPC_OWNER,\n\t\tCAP_SYS_MODULE,\n\t\tCAP_SYS_RAWIO,\n\t\tCAP_SYS_CHROOT,\n\t\tCAP_SYS_PTRACE,\n\t\tCAP_SYS_PACCT,\n\t\tCAP_SYS_ADMIN,\n\t\tCAP_SYS_BOOT,\n\t\tCAP_SYS_NICE,\n\t\tCAP_SYS_RESOURCE,\n\t\tCAP_SYS_TIME,\n\t\tCAP_SYS_TTY_CONFIG,\n\t\tCAP_MKNOD,\n\t\tCAP_LEASE,\n\t\tCAP_AUDIT_WRITE,\n\t\tCAP_AUDIT_CONTROL,\n\t\tCAP_SETFCAP,\n\t\tCAP_MAC_OVERRIDE,\n\t\tCAP_MAC_ADMIN,\n\t\tCAP_SYSLOG,\n\t\tCAP_WAKE_ALARM,\n\t\tCAP_BLOCK_SUSPEND,\n\t\tCAP_AUDIT_READ,\n\t\tCAP_PERFMON,\n\t\tCAP_BPF,\n\t\tCAP_CHECKPOINT_RESTORE,\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/syndtr/gocapability/capability/syscall_linux.go",
    "content": "// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>\n// All rights reserved.\n//\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\npackage capability\n\nimport (\n\t\"syscall\"\n\t\"unsafe\"\n)\n\ntype capHeader struct {\n\tversion uint32\n\tpid     int32\n}\n\ntype capData struct {\n\teffective   uint32\n\tpermitted   uint32\n\tinheritable uint32\n}\n\nfunc capget(hdr *capHeader, data *capData) (err error) {\n\t_, _, e1 := syscall.Syscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nfunc capset(hdr *capHeader, data *capData) (err error) {\n\t_, _, e1 := syscall.Syscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\n// not yet in syscall\nconst (\n\tpr_CAP_AMBIENT           = 47\n\tpr_CAP_AMBIENT_IS_SET    = uintptr(1)\n\tpr_CAP_AMBIENT_RAISE     = uintptr(2)\n\tpr_CAP_AMBIENT_LOWER     = uintptr(3)\n\tpr_CAP_AMBIENT_CLEAR_ALL = uintptr(4)\n)\n\nfunc prctl(option int, arg2, arg3, arg4, arg5 uintptr) (err error) {\n\t_, _, e1 := syscall.Syscall6(syscall.SYS_PRCTL, uintptr(option), arg2, arg3, arg4, arg5, 0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n\nconst (\n\tvfsXattrName = \"security.capability\"\n\n\tvfsCapVerMask = 0xff000000\n\tvfsCapVer1    = 0x01000000\n\tvfsCapVer2    = 0x02000000\n\n\tvfsCapFlagMask      = ^vfsCapVerMask\n\tvfsCapFlageffective = 0x000001\n\n\tvfscapDataSizeV1 = 4 * (1 + 2*1)\n\tvfscapDataSizeV2 = 4 * (1 + 2*2)\n)\n\ntype vfscapData struct {\n\tmagic uint32\n\tdata  [2]struct {\n\t\tpermitted   uint32\n\t\tinheritable uint32\n\t}\n\teffective [2]uint32\n\tversion   int8\n}\n\nvar (\n\t_vfsXattrName *byte\n)\n\nfunc init() {\n\t_vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName)\n}\n\nfunc getVfsCap(path string, dest *vfscapData) (err error) {\n\tvar _p0 *byte\n\t_p0, err = syscall.BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tr0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0)\n\tif e1 != 0 {\n\t\tif e1 == syscall.ENODATA {\n\t\t\tdest.version = 2\n\t\t\treturn\n\t\t}\n\t\terr = e1\n\t}\n\tswitch dest.magic & vfsCapVerMask {\n\tcase vfsCapVer1:\n\t\tdest.version = 1\n\t\tif r0 != vfscapDataSizeV1 {\n\t\t\treturn syscall.EINVAL\n\t\t}\n\t\tdest.data[1].permitted = 0\n\t\tdest.data[1].inheritable = 0\n\tcase vfsCapVer2:\n\t\tdest.version = 2\n\t\tif r0 != vfscapDataSizeV2 {\n\t\t\treturn syscall.EINVAL\n\t\t}\n\tdefault:\n\t\treturn syscall.EINVAL\n\t}\n\tif dest.magic&vfsCapFlageffective != 0 {\n\t\tdest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable\n\t\tdest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable\n\t} else {\n\t\tdest.effective[0] = 0\n\t\tdest.effective[1] = 0\n\t}\n\treturn\n}\n\nfunc setVfsCap(path string, data *vfscapData) (err error) {\n\tvar _p0 *byte\n\t_p0, err = syscall.BytePtrFromString(path)\n\tif err != nil {\n\t\treturn\n\t}\n\tvar size uintptr\n\tif data.version == 1 {\n\t\tdata.magic = vfsCapVer1\n\t\tsize = vfscapDataSizeV1\n\t} else if data.version == 2 {\n\t\tdata.magic = vfsCapVer2\n\t\tif data.effective[0] != 0 || data.effective[1] != 0 {\n\t\t\tdata.magic |= vfsCapFlageffective\n\t\t}\n\t\tsize = vfscapDataSizeV2\n\t} else {\n\t\treturn syscall.EINVAL\n\t}\n\t_, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0)\n\tif e1 != 0 {\n\t\terr = e1\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/.gitignore",
    "content": "*.cgo?.*\n*.o\n*.so\n*.sublime-*\n*.zip\n.DS_Store\n.idea/\n.tags*\n_cgo_*\n_gofuzz/crashers/\n_gofuzz/suppressions/\n_obj\n_test\ncoverage.txt\nrobots.txt-check/robots.txt-check\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/.golangci.yml",
    "content": "linters:\n  enable:\n    - goconst\n    - gofmt\n    - gosec\n    - maligned\n    - prealloc\n    - staticcheck\n  disable:\n    - deadcode\n    - structcheck\n    - varcheck\n\nlinters-settings:\n  gofmt:\n    simplify: true\n  govet:\n    check-shadowing: true\n  maligned:\n    suggest-new: true\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/.travis.yml",
    "content": "cache:\n  go: true\n  directories:\n  - $HOME/.cache\n  - $HOME/bin\n  - $HOME/gopath/pkg/mod\nlanguage: go\ngo:\n- 1.11\n- 1.12\n- 1.13\n- 1.14\n- 1.x\n- master\ninstall: true\nscript: GO111MODULE=on go test -race\n\nmatrix:\n  include:\n  - go: 1.x\n    env: task=coverage\n    script: GO111MODULE=on go test -race -covermode=atomic -coverprofile=coverage.txt\n    after_success: bash <(curl -s https://codecov.io/bash)\n  - go: 1.x\n    env: task=bench\n    script: GO111MODULE=on ./script/bench\n  - go: 1.x\n    install: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $HOME/bin v1.19.1\n    env: task=clean\n    script: GO111MODULE=on ./script/clean\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/LICENSE",
    "content": "The MIT License\n\nCopyright (c) 2010 Sergey Shepelev <temotor@gmail.com>\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/README.rst",
    "content": "What\n====\n\nThis is a robots.txt exclusion protocol implementation for Go language (golang).\n\n\nBuild\n=====\n\nTo build and run tests run `go test` in source directory.\n\n\nContribute\n==========\n\nWarm welcome.\n\n* If desired, add your name in README.rst, section Who.\n* Run `script/test && script/clean && echo ok`\n* You can ignore linter warnings, but everything else must pass.\n* Send your change as pull request or just a regular patch to current maintainer (see section Who).\n\nThank you.\n\n\nUsage\n=====\n\nAs usual, no special installation is required, just\n\n    import \"github.com/temoto/robotstxt\"\n\nrun `go get` and you're ready.\n\n1. Parse\n^^^^^^^^\n\nFirst of all, you need to parse robots.txt data. You can do it with\nfunctions `FromBytes(body []byte) (*RobotsData, error)` or same for `string`::\n\n    robots, err := robotstxt.FromBytes([]byte(\"User-agent: *\\nDisallow:\"))\n    robots, err := robotstxt.FromString(\"User-agent: *\\nDisallow:\")\n\nAs of 2012-10-03, `FromBytes` is the most efficient method, everything else\nis a wrapper for this core function.\n\nThere are few convenient constructors for various purposes:\n\n* `FromResponse(*http.Response) (*RobotsData, error)` to init robots data\nfrom HTTP response. It *does not* call `response.Body.Close()`::\n\n    robots, err := robotstxt.FromResponse(resp)\n    resp.Body.Close()\n    if err != nil {\n        log.Println(\"Error parsing robots.txt:\", err.Error())\n    }\n\n* `FromStatusAndBytes(statusCode int, body []byte) (*RobotsData, error)` or\n`FromStatusAndString` if you prefer to read bytes (string) yourself.\nPassing status code applies following logic in line with Google's interpretation\nof robots.txt files:\n\n    * status 2xx  -> parse body with `FromBytes` and apply rules listed there.\n    * status 4xx  -> allow all (even 401/403, as recommended by Google).\n    * other (5xx) -> disallow all, consider this a temporary unavailability.\n\n2. Query\n^^^^^^^^\n\nParsing robots.txt content builds a kind of logic database, which you can\nquery with `(r *RobotsData) TestAgent(url, agent string) (bool)`.\n\nExplicit passing of agent is useful if you want to query for different agents. For\nsingle agent users there is an efficient option: `RobotsData.FindGroup(userAgent string)`\nreturns a structure with `.Test(path string)` method and `.CrawlDelay time.Duration`.\n\nSimple query with explicit user agent. Each call will scan all rules.\n\n::\n\n    allow := robots.TestAgent(\"/\", \"FooBot\")\n\nOr query several paths against same user agent for performance.\n\n::\n\n    group := robots.FindGroup(\"BarBot\")\n    group.Test(\"/\")\n    group.Test(\"/download.mp3\")\n    group.Test(\"/news/article-2012-1\")\n\n\nWho\n===\n\nHonorable contributors (in undefined order):\n\n    * Ilya Grigorik (igrigorik)\n    * Martin Angers (PuerkitoBio)\n    * Micha Gorelick (mynameisfiber)\n\nInitial commit and other: Sergey Shepelev temotor@gmail.com\n\n\nFlair\n=====\n\n.. image:: https://travis-ci.org/temoto/robotstxt.svg?branch=master\n    :target: https://travis-ci.org/temoto/robotstxt\n\n.. image:: https://codecov.io/gh/temoto/robotstxt/branch/master/graph/badge.svg\n    :target: https://codecov.io/gh/temoto/robotstxt\n\n.. image:: https://goreportcard.com/badge/github.com/temoto/robotstxt\n    :target: https://goreportcard.com/report/github.com/temoto/robotstxt\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/codecov.yml",
    "content": "codecov:\n  token: 6bf9c7eb-69ff-4b74-8464-e2fb452d0f04\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/fuzz.go",
    "content": "// +build gofuzz\n\npackage robotstxt\n\nimport \"testing/quick\"\n\nfunc Fuzz(data []byte) int {\n\tr, err := FromBytes(data)\n\tif err != nil {\n\t\tif r != nil {\n\t\t\tpanic(\"r != nil on error\")\n\t\t}\n\t\treturn 0\n\t}\n\n\t// FindGroup must never return nil\n\tf1 := func(agent string) bool { return r.FindGroup(agent) != nil }\n\tif err := quick.Check(f1, nil); err != nil {\n\t\tpanic(err)\n\t}\n\n\t// just check TestAgent doesn't panic\n\tf2 := func(path, agent string) bool { r.TestAgent(path, agent); return true }\n\tif err := quick.Check(f2, nil); err != nil {\n\t\tpanic(err)\n\t}\n\n\treturn 1\n}\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/parser.go",
    "content": "package robotstxt\n\n// Comments explaining the logic are taken from either the google's spec:\n// https://developers.google.com/webmasters/control-crawl-index/docs/robots_txt\n//\n// or the Wikipedia's entry on robots.txt:\n// http://en.wikipedia.org/wiki/Robots.txt\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype lineType uint\n\nconst (\n\tlIgnore lineType = iota\n\tlUnknown\n\tlUserAgent\n\tlAllow\n\tlDisallow\n\tlCrawlDelay\n\tlSitemap\n\tlHost\n)\n\ntype parser struct {\n\ttokens []string\n\tpos    int\n}\n\ntype lineInfo struct {\n\tt  lineType       // Type of line key\n\tk  string         // String representation of the type of key\n\tvs string         // String value of the key\n\tvf float64        // Float value of the key\n\tvr *regexp.Regexp // Regexp value of the key\n}\n\nfunc newParser(tokens []string) *parser {\n\treturn &parser{tokens: tokens}\n}\n\nfunc parseGroupMap(groups map[string]*Group, agents []string, fun func(*Group)) {\n\tvar g *Group\n\tfor _, a := range agents {\n\t\tif g = groups[a]; g == nil {\n\t\t\tg = new(Group)\n\t\t\tgroups[a] = g\n\t\t}\n\t\tfun(g)\n\t}\n}\n\nfunc (p *parser) parseAll() (groups map[string]*Group, host string, sitemaps []string, errs []error) {\n\tgroups = make(map[string]*Group, 16)\n\tagents := make([]string, 0, 4)\n\tisEmptyGroup := true\n\n\t// Reset internal fields, tokens are assigned at creation time, never change\n\tp.pos = 0\n\n\tfor {\n\t\tif li, err := p.parseLine(); err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\terrs = append(errs, err)\n\t\t} else {\n\t\t\tswitch li.t {\n\t\t\tcase lUserAgent:\n\t\t\t\t// Two successive user-agent lines are part of the same group.\n\t\t\t\tif !isEmptyGroup {\n\t\t\t\t\t// End previous group\n\t\t\t\t\tagents = make([]string, 0, 4)\n\t\t\t\t}\n\t\t\t\tif len(agents) == 0 {\n\t\t\t\t\tisEmptyGroup = true\n\t\t\t\t}\n\t\t\t\tagents = append(agents, li.vs)\n\n\t\t\tcase lDisallow:\n\t\t\t\t// Error if no current group\n\t\t\t\tif len(agents) == 0 {\n\t\t\t\t\terrs = append(errs, fmt.Errorf(\"Disallow before User-agent at token #%d.\", p.pos))\n\t\t\t\t} else {\n\t\t\t\t\tisEmptyGroup = false\n\t\t\t\t\tvar r *rule\n\t\t\t\t\tif li.vr != nil {\n\t\t\t\t\t\tr = &rule{\"\", false, li.vr}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tr = &rule{li.vs, false, nil}\n\t\t\t\t\t}\n\t\t\t\t\tparseGroupMap(groups, agents, func(g *Group) { g.rules = append(g.rules, r) })\n\t\t\t\t}\n\n\t\t\tcase lAllow:\n\t\t\t\t// Error if no current group\n\t\t\t\tif len(agents) == 0 {\n\t\t\t\t\terrs = append(errs, fmt.Errorf(\"Allow before User-agent at token #%d.\", p.pos))\n\t\t\t\t} else {\n\t\t\t\t\tisEmptyGroup = false\n\t\t\t\t\tvar r *rule\n\t\t\t\t\tif li.vr != nil {\n\t\t\t\t\t\tr = &rule{\"\", true, li.vr}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tr = &rule{li.vs, true, nil}\n\t\t\t\t\t}\n\t\t\t\t\tparseGroupMap(groups, agents, func(g *Group) { g.rules = append(g.rules, r) })\n\t\t\t\t}\n\n\t\t\tcase lHost:\n\t\t\t\thost = li.vs\n\n\t\t\tcase lSitemap:\n\t\t\t\tsitemaps = append(sitemaps, li.vs)\n\n\t\t\tcase lCrawlDelay:\n\t\t\t\tif len(agents) == 0 {\n\t\t\t\t\terrs = append(errs, fmt.Errorf(\"Crawl-delay before User-agent at token #%d.\", p.pos))\n\t\t\t\t} else {\n\t\t\t\t\tisEmptyGroup = false\n\t\t\t\t\tdelay := time.Duration(li.vf * float64(time.Second))\n\t\t\t\t\tparseGroupMap(groups, agents, func(g *Group) { g.CrawlDelay = delay })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc (p *parser) parseLine() (li *lineInfo, err error) {\n\tt1, ok1 := p.popToken()\n\tif !ok1 {\n\t\t// proper EOF\n\t\treturn nil, io.EOF\n\t}\n\n\tt2, ok2 := p.peekToken()\n\tif !ok2 {\n\t\t// EOF, no value associated with the token, so ignore token and return\n\t\treturn nil, io.EOF\n\t}\n\n\t// Helper closure for all string-based tokens, common behaviour:\n\t// - Consume t2 token\n\t// - If empty, return unknown line info\n\t// - Otherwise return the specified line info\n\treturnStringVal := func(t lineType) (*lineInfo, error) {\n\t\tp.popToken()\n\t\tif t2 != \"\" {\n\t\t\treturn &lineInfo{t: t, k: t1, vs: t2}, nil\n\t\t}\n\t\treturn &lineInfo{t: lIgnore}, nil\n\t}\n\n\t// Helper closure for all path tokens (allow/disallow), common behaviour:\n\t// - Consume t2 token\n\t// - If empty, return unknown line info\n\t// - Otherwise, normalize the path (add leading \"/\" if missing, remove trailing \"*\")\n\t// - Detect if wildcards are present, if so, compile into a regexp\n\t// - Return the specified line info\n\treturnPathVal := func(t lineType) (*lineInfo, error) {\n\t\tp.popToken()\n\t\tif t2 != \"\" {\n\t\t\tif !strings.HasPrefix(t2, \"*\") && !strings.HasPrefix(t2, \"/\") {\n\t\t\t\tt2 = \"/\" + t2\n\t\t\t}\n\t\t\tt2 = strings.TrimRightFunc(t2, isAsterisk)\n\t\t\t// From google's spec:\n\t\t\t// Google, Bing, Yahoo, and Ask support a limited form of\n\t\t\t// \"wildcards\" for path values. These are:\n\t\t\t//   * designates 0 or more instances of any valid character\n\t\t\t//   $ designates the end of the URL\n\t\t\tif strings.ContainsAny(t2, \"*$\") {\n\t\t\t\t// Must compile a regexp, this is a pattern.\n\t\t\t\t// Escape string before compile.\n\t\t\t\tt2 = regexp.QuoteMeta(t2)\n\t\t\t\tt2 = strings.Replace(t2, `\\*`, `.*`, -1)\n\t\t\t\tt2 = strings.Replace(t2, `\\$`, `$`, -1)\n\t\t\t\tif r, e := regexp.Compile(t2); e != nil {\n\t\t\t\t\treturn nil, e\n\t\t\t\t} else {\n\t\t\t\t\treturn &lineInfo{t: t, k: t1, vr: r}, nil\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Simple string path\n\t\t\t\treturn &lineInfo{t: t, k: t1, vs: t2}, nil\n\t\t\t}\n\t\t}\n\t\treturn &lineInfo{t: lIgnore}, nil\n\t}\n\n\tswitch strings.ToLower(t1) {\n\tcase tokEOL:\n\t\t// Don't consume t2 and continue parsing\n\t\treturn &lineInfo{t: lIgnore}, nil\n\n\tcase \"user-agent\", \"useragent\":\n\t\t// From google's spec:\n\t\t// Handling of <field> elements with simple errors / typos (eg \"useragent\"\n\t\t// instead of \"user-agent\") is undefined and may be interpreted as correct\n\t\t// directives by some user-agents.\n\t\t// The user-agent is non-case-sensitive.\n\t\tt2 = strings.ToLower(t2)\n\t\treturn returnStringVal(lUserAgent)\n\n\tcase \"disallow\":\n\t\t// From google's spec:\n\t\t// When no path is specified, the directive is ignored (so an empty Disallow\n\t\t// CAN be an allow, since allow is the default. The actual result depends\n\t\t// on the other rules in the group).\n\t\treturn returnPathVal(lDisallow)\n\n\tcase \"allow\":\n\t\t// From google's spec:\n\t\t// When no path is specified, the directive is ignored.\n\t\treturn returnPathVal(lAllow)\n\n\tcase \"host\":\n\t\t// Host directive to specify main site mirror\n\t\t// Read more: https://help.yandex.com/webmaster/controlling-robot/robots-txt.xml#host\n\t\treturn returnStringVal(lHost)\n\n\tcase \"sitemap\":\n\t\t// Non-group field, applies to the host as a whole, not to a specific user-agent\n\t\treturn returnStringVal(lSitemap)\n\n\tcase \"crawl-delay\", \"crawldelay\":\n\t\t// From http://en.wikipedia.org/wiki/Robots_exclusion_standard#Nonstandard_extensions\n\t\t// Several major crawlers support a Crawl-delay parameter, set to the\n\t\t// number of seconds to wait between successive requests to the same server.\n\t\tp.popToken()\n\t\tif cd, e := strconv.ParseFloat(t2, 64); e != nil {\n\t\t\treturn nil, e\n\t\t} else if cd < 0 || math.IsInf(cd, 0) || math.IsNaN(cd) {\n\t\t\treturn nil, fmt.Errorf(\"Crawl-delay invalid value '%s'\", t2)\n\t\t} else {\n\t\t\treturn &lineInfo{t: lCrawlDelay, k: t1, vf: cd}, nil\n\t\t}\n\t}\n\n\t// Consume t2 token\n\tp.popToken()\n\treturn &lineInfo{t: lUnknown, k: t1}, nil\n}\n\nfunc (p *parser) popToken() (tok string, ok bool) {\n\ttok, ok = p.peekToken()\n\tif !ok {\n\t\treturn\n\t}\n\tp.pos++\n\treturn tok, true\n}\n\nfunc (p *parser) peekToken() (tok string, ok bool) {\n\tif p.pos >= len(p.tokens) {\n\t\treturn \"\", false\n\t}\n\treturn p.tokens[p.pos], true\n}\n\nfunc isAsterisk(r rune) bool {\n\treturn r == '*'\n}\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/robotstxt.go",
    "content": "// Package robotstxt implements the robots.txt Exclusion Protocol\n// as specified in http://www.robotstxt.org/wc/robots.html\n// with various extensions.\npackage robotstxt\n\n// Comments explaining the logic are taken from either the Google's spec:\n// https://developers.google.com/webmasters/control-crawl-index/docs/robots_txt\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io/ioutil\"\n\t\"net/http\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype RobotsData struct {\n\t// private\n\tgroups      map[string]*Group\n\tallowAll    bool\n\tdisallowAll bool\n\tHost        string\n\tSitemaps    []string\n}\n\ntype Group struct {\n\trules      []*rule\n\tAgent      string\n\tCrawlDelay time.Duration\n}\n\ntype rule struct {\n\tpath    string\n\tallow   bool\n\tpattern *regexp.Regexp\n}\n\ntype ParseError struct {\n\tErrs []error\n}\n\nfunc newParseError(errs []error) *ParseError {\n\treturn &ParseError{errs}\n}\n\nfunc (e ParseError) Error() string {\n\tvar b bytes.Buffer\n\n\tb.WriteString(\"Parse error(s): \" + \"\\n\")\n\tfor _, er := range e.Errs {\n\t\tb.WriteString(er.Error() + \"\\n\")\n\t}\n\treturn b.String()\n}\n\nvar allowAll = &RobotsData{allowAll: true}\nvar disallowAll = &RobotsData{disallowAll: true}\nvar emptyGroup = &Group{}\n\nfunc FromStatusAndBytes(statusCode int, body []byte) (*RobotsData, error) {\n\tswitch {\n\tcase statusCode >= 200 && statusCode < 300:\n\t\treturn FromBytes(body)\n\n\t// From https://developers.google.com/webmasters/control-crawl-index/docs/robots_txt\n\t//\n\t// Google treats all 4xx errors in the same way and assumes that no valid\n\t// robots.txt file exists. It is assumed that there are no restrictions.\n\t// This is a \"full allow\" for crawling. Note: this includes 401\n\t// \"Unauthorized\" and 403 \"Forbidden\" HTTP result codes.\n\tcase statusCode >= 400 && statusCode < 500:\n\t\treturn allowAll, nil\n\n\t// From Google's spec:\n\t// Server errors (5xx) are seen as temporary errors that result in a \"full\n\t// disallow\" of crawling.\n\tcase statusCode >= 500 && statusCode < 600:\n\t\treturn disallowAll, nil\n\t}\n\n\treturn nil, errors.New(\"Unexpected status: \" + strconv.Itoa(statusCode))\n}\n\nfunc FromStatusAndString(statusCode int, body string) (*RobotsData, error) {\n\treturn FromStatusAndBytes(statusCode, []byte(body))\n}\n\nfunc FromResponse(res *http.Response) (*RobotsData, error) {\n\tif res == nil {\n\t\t// Edge case, if res is nil, return nil data\n\t\treturn nil, nil\n\t}\n\tbuf, e := ioutil.ReadAll(res.Body)\n\tif e != nil {\n\t\treturn nil, e\n\t}\n\treturn FromStatusAndBytes(res.StatusCode, buf)\n}\n\nfunc FromBytes(body []byte) (r *RobotsData, err error) {\n\tvar errs []error\n\n\t// special case (probably not worth optimization?)\n\ttrimmed := bytes.TrimSpace(body)\n\tif len(trimmed) == 0 {\n\t\treturn allowAll, nil\n\t}\n\n\tsc := newByteScanner(\"bytes\", true)\n\t//sc.Quiet = !print_errors\n\tsc.feed(body, true)\n\ttokens := sc.scanAll()\n\n\t// special case worth optimization\n\tif len(tokens) == 0 {\n\t\treturn allowAll, nil\n\t}\n\n\tr = &RobotsData{}\n\tparser := newParser(tokens)\n\tr.groups, r.Host, r.Sitemaps, errs = parser.parseAll()\n\tif len(errs) > 0 {\n\t\treturn nil, newParseError(errs)\n\t}\n\n\treturn r, nil\n}\n\nfunc FromString(body string) (r *RobotsData, err error) {\n\treturn FromBytes([]byte(body))\n}\n\nfunc (r *RobotsData) TestAgent(path, agent string) bool {\n\tif r.allowAll {\n\t\treturn true\n\t}\n\tif r.disallowAll {\n\t\treturn false\n\t}\n\n\t// Find a group of rules that applies to this agent\n\t// From Google's spec:\n\t// The user-agent is non-case-sensitive.\n\tg := r.FindGroup(agent)\n\treturn g.Test(path)\n}\n\n// FindGroup searches block of declarations for specified user-agent.\n// From Google's spec:\n// Only one group of group-member records is valid for a particular crawler.\n// The crawler must determine the correct group of records by finding the group\n// with the most specific user-agent that still matches. All other groups of\n// records are ignored by the crawler. The user-agent is non-case-sensitive.\n// The order of the groups within the robots.txt file is irrelevant.\nfunc (r *RobotsData) FindGroup(agent string) (ret *Group) {\n\tvar prefixLen int\n\n\tagent = strings.ToLower(agent)\n\tif ret = r.groups[\"*\"]; ret != nil {\n\t\t// Weakest match possible\n\t\tprefixLen = 1\n\t}\n\tfor a, g := range r.groups {\n\t\tif a != \"*\" && strings.HasPrefix(agent, a) {\n\t\t\tif l := len(a); l > prefixLen {\n\t\t\t\tprefixLen = l\n\t\t\t\tret = g\n\t\t\t}\n\t\t}\n\t}\n\n\tif ret == nil {\n\t\treturn emptyGroup\n\t}\n\treturn\n}\n\nfunc (g *Group) Test(path string) bool {\n\tif r := g.findRule(path); r != nil {\n\t\treturn r.allow\n\t}\n\n\t// From Google's spec:\n\t// By default, there are no restrictions for crawling for the designated crawlers.\n\treturn true\n}\n\n// From Google's spec:\n// The path value is used as a basis to determine whether or not a rule applies\n// to a specific URL on a site. With the exception of wildcards, the path is\n// used to match the beginning of a URL (and any valid URLs that start with the\n// same path).\n//\n// At a group-member level, in particular for allow and disallow directives,\n// the most specific rule based on the length of the [path] entry will trump\n// the less specific (shorter) rule. The order of precedence for rules with\n// wildcards is undefined.\nfunc (g *Group) findRule(path string) (ret *rule) {\n\tvar prefixLen int\n\n\tfor _, r := range g.rules {\n\t\tif r.pattern != nil {\n\t\t\tif r.pattern.MatchString(path) {\n\t\t\t\t// Consider this a match equal to the length of the pattern.\n\t\t\t\t// From Google's spec:\n\t\t\t\t// The order of precedence for rules with wildcards is undefined.\n\t\t\t\tif l := len(r.pattern.String()); l > prefixLen {\n\t\t\t\t\tprefixLen = l\n\t\t\t\t\tret = r\n\t\t\t\t}\n\t\t\t}\n\t\t} else if r.path == \"/\" && prefixLen == 0 {\n\t\t\t// Weakest match possible\n\t\t\tprefixLen = 1\n\t\t\tret = r\n\t\t} else if strings.HasPrefix(path, r.path) {\n\t\t\tif l := len(r.path); l > prefixLen {\n\t\t\t\tprefixLen = l\n\t\t\t\tret = r\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/temoto/robotstxt/scanner.go",
    "content": "package robotstxt\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"go/token\"\n\t\"os\"\n\t\"sync\"\n\t\"unicode/utf8\"\n)\n\ntype byteScanner struct {\n\tpos           token.Position\n\tbuf           []byte\n\tErrorCount    int\n\tch            rune\n\tQuiet         bool\n\tkeyTokenFound bool\n\tlastChunk     bool\n}\n\nconst tokEOL = \"\\n\"\n\nvar WhitespaceChars = []rune{' ', '\\t', '\\v'}\nvar tokBuffers = sync.Pool{New: func() interface{} { return bytes.NewBuffer(make([]byte, 32)) }}\n\nfunc newByteScanner(srcname string, quiet bool) *byteScanner {\n\treturn &byteScanner{\n\t\tQuiet: quiet,\n\t\tch:    -1,\n\t\tpos:   token.Position{Filename: srcname},\n\t}\n}\n\nfunc (s *byteScanner) feed(input []byte, end bool) {\n\ts.buf = input\n\ts.pos.Offset = 0\n\ts.pos.Line = 1\n\ts.pos.Column = 1\n\ts.lastChunk = end\n\n\t// Read first char into look-ahead buffer `s.ch`.\n\tif !s.nextChar() {\n\t\treturn\n\t}\n\n\t// Skip UTF-8 byte order mark\n\tif s.ch == 65279 {\n\t\ts.nextChar()\n\t\ts.pos.Column = 1\n\t}\n}\n\nfunc (s *byteScanner) GetPosition() token.Position {\n\treturn s.pos\n}\n\nfunc (s *byteScanner) scan() string {\n\t// Note Offset > len, not >=, so we can scan last character.\n\tif s.lastChunk && s.pos.Offset > len(s.buf) {\n\t\treturn \"\"\n\t}\n\n\ts.skipSpace()\n\n\tif s.ch == -1 {\n\t\treturn \"\"\n\t}\n\n\t// EOL\n\tif s.isEol() {\n\t\ts.keyTokenFound = false\n\t\t// skip subsequent newline chars\n\t\tfor s.ch != -1 && s.isEol() {\n\t\t\ts.nextChar()\n\t\t}\n\t\t// emit newline as separate token\n\t\treturn tokEOL\n\t}\n\n\t// skip comments\n\tif s.ch == '#' {\n\t\ts.keyTokenFound = false\n\t\ts.skipUntilEol()\n\t\tif s.ch == -1 {\n\t\t\treturn \"\"\n\t\t}\n\t\t// emit newline as separate token\n\t\treturn tokEOL\n\t}\n\n\t// else we found something\n\ttok := tokBuffers.Get().(*bytes.Buffer)\n\tdefer tokBuffers.Put(tok)\n\ttok.Reset()\n\ttok.WriteRune(s.ch)\n\ts.nextChar()\n\tfor s.ch != -1 && !s.isSpace() && !s.isEol() {\n\t\t// Do not consider \":\" to be a token separator if a first key token\n\t\t// has already been found on this line (avoid cutting an absolute URL\n\t\t// after the \"http:\")\n\t\tif s.ch == ':' && !s.keyTokenFound {\n\t\t\ts.nextChar()\n\t\t\ts.keyTokenFound = true\n\t\t\tbreak\n\t\t}\n\n\t\ttok.WriteRune(s.ch)\n\t\ts.nextChar()\n\t}\n\treturn tok.String()\n}\n\nfunc (s *byteScanner) scanAll() []string {\n\tresults := make([]string, 0, 64) // random guess of average tokens length\n\tfor {\n\t\ttoken := s.scan()\n\t\tif token != \"\" {\n\t\t\tresults = append(results, token)\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn results\n}\n\nfunc (s *byteScanner) error(pos token.Position, msg string) {\n\ts.ErrorCount++\n\tif !s.Quiet {\n\t\tfmt.Fprintf(os.Stderr, \"robotstxt from %s: %s\\n\", pos.String(), msg)\n\t}\n}\n\nfunc (s *byteScanner) isEol() bool {\n\treturn s.ch == '\\n' || s.ch == '\\r'\n}\n\nfunc (s *byteScanner) isSpace() bool {\n\tfor _, r := range WhitespaceChars {\n\t\tif s.ch == r {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (s *byteScanner) skipSpace() {\n\tfor s.ch != -1 && s.isSpace() {\n\t\ts.nextChar()\n\t}\n}\n\nfunc (s *byteScanner) skipUntilEol() {\n\tfor s.ch != -1 && !s.isEol() {\n\t\ts.nextChar()\n\t}\n\t// skip subsequent newline chars\n\tfor s.ch != -1 && s.isEol() {\n\t\ts.nextChar()\n\t}\n}\n\n// Reads next Unicode char.\nfunc (s *byteScanner) nextChar() bool {\n\tif s.pos.Offset >= len(s.buf) {\n\t\ts.ch = -1\n\t\treturn false\n\t}\n\ts.pos.Column++\n\tif s.ch == '\\n' {\n\t\ts.pos.Line++\n\t\ts.pos.Column = 1\n\t}\n\tr, w := rune(s.buf[s.pos.Offset]), 1\n\tif r >= 0x80 {\n\t\tr, w = utf8.DecodeRune(s.buf[s.pos.Offset:])\n\t\tif r == utf8.RuneError && w == 1 {\n\t\t\ts.error(s.pos, \"illegal UTF-8 encoding\")\n\t\t}\n\t}\n\ts.pos.Column++\n\ts.pos.Offset += w\n\ts.ch = r\n\treturn true\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/.gitignore",
    "content": "# .gitignore\n\nTODO.html\nREADME.html\n\nlzma/writer.txt\nlzma/reader.txt\n\ncmd/gxz/gxz\ncmd/xb/xb\n\n# test executables\n*.test\n\n# profile files\n*.out\n\n# vim swap file\n.*.swp\n\n# executables on windows\n*.exe\n\n# default compression test file\nenwik8*\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/LICENSE",
    "content": "Copyright (c) 2014-2020  Ulrich Kunitz\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* My name, Ulrich Kunitz, may not be used to endorse or promote products\n  derived from this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (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": "vendor/github.com/ulikunitz/xz/README.md",
    "content": "# Package xz\n\nThis Go language package supports the reading and writing of xz\ncompressed streams. It includes also a gxz command for compressing and\ndecompressing data. The package is completely written in Go and doesn't\nhave any dependency on any C code.\n\nThe package is currently under development. There might be bugs and APIs\nare not considered stable. At this time the package cannot compete with\nthe xz tool regarding compression speed and size. The algorithms there\nhave been developed over a long time and are highly optimized. However\nthere are a number of improvements planned and I'm very optimistic about\nparallel compression and decompression. Stay tuned!\n\n## Using the API\n\nThe following example program shows how to use the API.\n\n```go\npackage main\n\nimport (\n    \"bytes\"\n    \"io\"\n    \"log\"\n    \"os\"\n\n    \"github.com/ulikunitz/xz\"\n)\n\nfunc main() {\n    const text = \"The quick brown fox jumps over the lazy dog.\\n\"\n    var buf bytes.Buffer\n    // compress text\n    w, err := xz.NewWriter(&buf)\n    if err != nil {\n        log.Fatalf(\"xz.NewWriter error %s\", err)\n    }\n    if _, err := io.WriteString(w, text); err != nil {\n        log.Fatalf(\"WriteString error %s\", err)\n    }\n    if err := w.Close(); err != nil {\n        log.Fatalf(\"w.Close error %s\", err)\n    }\n    // decompress buffer and write output to stdout\n    r, err := xz.NewReader(&buf)\n    if err != nil {\n        log.Fatalf(\"NewReader error %s\", err)\n    }\n    if _, err = io.Copy(os.Stdout, r); err != nil {\n        log.Fatalf(\"io.Copy error %s\", err)\n    }\n}\n```\n\n## Using the gxz compression tool\n\nThe package includes a gxz command line utility for compression and\ndecompression.\n\nUse following command for installation:\n\n    $ go get github.com/ulikunitz/xz/cmd/gxz\n\nTo test it call the following command.\n\n    $ gxz bigfile\n\nAfter some time a much smaller file bigfile.xz will replace bigfile.\nTo decompress it use the following command.\n\n    $ gxz -d bigfile.xz\n\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/TODO.md",
    "content": "# TODO list\n\n## Release v0.5.x\n\n1. Support check flag in gxz command.\n\n## Release v0.6\n\n1. Review encoder and check for lzma improvements under xz.\n2. Fix binary tree matcher.\n3. Compare compression ratio with xz tool using comparable parameters\n   and optimize parameters\n4. Do some optimizations\n    - rename operation action and make it a simple type of size 8\n    - make maxMatches, wordSize parameters\n    - stop searching after a certain length is found (parameter sweetLen)\n\n## Release v0.7\n\n1. Optimize code\n2. Do statistical analysis to get linear presets.\n3. Test sync.Pool compatability for xz and lzma Writer and Reader\n3. Fuzz optimized code.\n\n## Release v0.8\n\n1. Support parallel go routines for writing and reading xz files.\n2. Support a ReaderAt interface for xz files with small block sizes.\n3. Improve compatibility between gxz and xz\n4. Provide manual page for gxz\n\n## Release v0.9\n\n1. Improve documentation\n2. Fuzz again\n\n## Release v1.0\n\n1. Full functioning gxz\n2. Add godoc URL to README.md (godoc.org)\n3. Resolve all issues.\n4. Define release candidates.\n5. Public announcement.\n\n## Package lzma\n\n### Release v0.6\n\n- Rewrite Encoder into a simple greedy one-op-at-a-time encoder\n  including\n    + simple scan at the dictionary head for the same byte\n    + use the killer byte (requiring matches to get longer, the first\n      test should be the byte that would make the match longer)\n\n\n## Optimizations\n\n- There may be a lot of false sharing in lzma.State; check whether this\n  can be improved by reorganizing the internal structure of it.\n- Check whether batching encoding and decoding improves speed.\n\n### DAG optimizations\n\n- Use full buffer to create minimal bit-length above range encoder.\n- Might be too slow (see v0.4)\n\n### Different match finders\n\n- hashes with 2, 3 characters additional to 4 characters\n- binary trees with 2-7 characters (uint64 as key, use uint32 as\n  pointers into a an array)\n- rb-trees with 2-7 characters (uint64 as key, use uint32 as pointers\n  into an array with bit-steeling for the colors)\n\n## Release Procedure\n\n- execute goch -l for all packages; probably with lower param like 0.5.\n- check orthography with gospell\n- Write release notes in doc/relnotes.\n- Update README.md\n- xb copyright . in xz directory to ensure all new files have Copyright\n  header\n- VERSION=<version> go generate github.com/ulikunitz/xz/... to update\n  version files\n- Execute test for Linux/amd64, Linux/x86 and Windows/amd64.\n- Update TODO.md - write short log entry\n- git checkout master && git merge dev\n- git tag -a <version>\n- git push\n\n## Log\n\n### 2020-02-24\n\nRelease v0.5.7 supports the check-ID None and fixes\n[issue #27](https://github.com/ulikunitz/xz/issues/27).\n\n### 2019-02-20\n\nRelease v0.5.6 supports the go.mod file.\n\n### 2018-10-28\n\nRelease v0.5.5 fixes issues #19 observing ErrLimit outputs.\n\n### 2017-06-05\n\nRelease v0.5.4 fixes issues #15 of another problem with the padding size\ncheck for the xz block header. I removed the check completely.\n\n### 2017-02-15\n\nRelease v0.5.3 fixes issue #12 regarding the decompression of an empty\nXZ stream. Many thanks to Tomasz Kłak, who reported the issue.\n\n### 2016-12-02\n\nRelease v0.5.2 became necessary to allow the decoding of xz files with\n4-byte padding in the block header. Many thanks to Greg, who reported\nthe issue.\n\n### 2016-07-23\n\nRelease v0.5.1 became necessary to fix problems with 32-bit platforms.\nMany thanks to Bruno Brigas, who reported the issue.\n\n### 2016-07-04\n\nRelease v0.5 provides improvements to the compressor and provides support for\nthe decompression of xz files with multiple xz streams.\n\n### 2016-01-31\n\nAnother compression rate increase by checking the byte at length of the\nbest match first, before checking the whole prefix. This makes the\ncompressor even faster. We have now a large time budget to beat the\ncompression ratio of the xz tool. For enwik8 we have now over 40 seconds\nto reduce the compressed file size for another 7 MiB.\n\n### 2016-01-30\n\nI simplified the encoder. Speed and compression rate increased\ndramatically. A high compression rate affects also the decompression\nspeed. The approach with the buffer and optimizing for operation\ncompression rate has not been successful. Going for the maximum length\nappears to be the best approach.\n\n### 2016-01-28\n\nThe release v0.4 is ready. It provides a working xz implementation,\nwhich is rather slow, but works and is interoperable with the xz tool.\nIt is an important milestone.\n\n### 2016-01-10\n\nI have the first working implementation of an xz reader and writer. I'm\nhappy about reaching this milestone.\n\n### 2015-12-02\n\nI'm now ready to implement xz because, I have a working LZMA2\nimplementation. I decided today that v0.4 will use the slow encoder\nusing the operations buffer to be able to go back, if I intend to do so.\n\n### 2015-10-21\n\nI have restarted the work on the library. While trying to implement\nLZMA2, I discovered that I need to resimplify the encoder and decoder\nfunctions. The option approach is too complicated. Using a limited byte\nwriter and not caring for written bytes at all and not to try to handle\nuncompressed data simplifies the LZMA encoder and decoder much.\nProcessing uncompressed data and handling limits is a feature of the\nLZMA2 format not of LZMA.\n\nI learned an interesting method from the LZO format. If the last copy is\ntoo far away they are moving the head one 2 bytes and not 1 byte to\nreduce processing times.\n\n### 2015-08-26\n\nI have now reimplemented the lzma package. The code is reasonably fast,\nbut can still be optimized. The next step is to implement LZMA2 and then\nxz.\n\n### 2015-07-05\n\nCreated release v0.3. The version is the foundation for a full xz\nimplementation that is the target of v0.4.\n\n### 2015-06-11\n\nThe gflag package has been developed because I couldn't use flag and\npflag for a fully compatible support of gzip's and lzma's options. It\nseems to work now quite nicely.\n\n### 2015-06-05\n\nThe overflow issue was interesting to research, however Henry S. Warren\nJr. Hacker's Delight book was very helpful as usual and had the issue\nexplained perfectly. Fefe's information on his website was based on the\nC FAQ and quite bad, because it didn't address the issue of -MININT ==\nMININT.\n\n### 2015-06-04\n\nIt has been a productive day. I improved the interface of lzma.Reader\nand lzma.Writer and fixed the error handling.\n\n### 2015-06-01\n\nBy computing the bit length of the LZMA operations I was able to\nimprove the greedy algorithm implementation. By using an 8 MByte buffer\nthe compression rate was not as good as for xz but already better then\ngzip default.\n\nCompression is currently slow, but this is something we will be able to\nimprove over time.\n\n### 2015-05-26\n\nChecked the license of ogier/pflag. The binary lzmago binary should\ninclude the license terms for the pflag library.\n\nI added the endorsement clause as used by Google for the Go sources the\nLICENSE file.\n\n### 2015-05-22\n\nThe package lzb contains now the basic implementation for creating or\nreading LZMA byte streams. It allows the support for the implementation\nof the DAG-shortest-path algorithm for the compression function.\n\n### 2015-04-23\n\nCompleted yesterday the lzbase classes. I'm a little bit concerned that\nusing the components may require too much code, but on the other hand\nthere is a lot of flexibility.\n\n### 2015-04-22\n\nImplemented Reader and Writer during the Bayern game against Porto. The\nsecond half gave me enough time.\n\n### 2015-04-21\n\nWhile showering today morning I discovered that the design for OpEncoder\nand OpDecoder doesn't work, because encoding/decoding might depend on\nthe current status of the dictionary. This is not exactly the right way\nto start the day.\n\nTherefore we need to keep the Reader and Writer design. This time around\nwe simplify it by ignoring size limits. These can be added by wrappers\naround the Reader and Writer interfaces. The Parameters type isn't\nneeded anymore.\n\nHowever I will implement a ReaderState and WriterState type to use\nstatic typing to ensure the right State object is combined with the\nright lzbase.Reader and lzbase.Writer.\n\nAs a start I have implemented ReaderState and WriterState to ensure\nthat the state for reading is only used by readers and WriterState only\nused by Writers.\n\n### 2015-04-20\n\nToday I implemented the OpDecoder and tested OpEncoder and OpDecoder.\n\n### 2015-04-08\n\nCame up with a new simplified design for lzbase. I implemented already\nthe type State that replaces OpCodec.\n\n### 2015-04-06\n\nThe new lzma package is now fully usable and lzmago is using it now. The\nold lzma package has been completely removed.\n\n### 2015-04-05\n\nImplemented lzma.Reader and tested it.\n\n### 2015-04-04\n\nImplemented baseReader by adapting code form lzma.Reader.\n\n### 2015-04-03\n\nThe opCodec has been copied yesterday to lzma2. opCodec has a high\nnumber of dependencies on other files in lzma2. Therefore I had to copy\nalmost all files from lzma.\n\n### 2015-03-31\n\nRemoved only a TODO item.\n\nHowever in Francesco Campoy's presentation \"Go for Javaneros\n(Javaïstes?)\" is the the idea that using an embedded field E, all the\nmethods of E will be defined on T. If E is an interface T satisfies E.\n\nhttps://talks.golang.org/2014/go4java.slide#51\n\nI have never used this, but it seems to be a cool idea.\n\n### 2015-03-30\n\nFinished the type writerDict and wrote a simple test.\n\n### 2015-03-25\n\nI started to implement the writerDict.\n\n### 2015-03-24\n\nAfter thinking long about the LZMA2 code and several false starts, I\nhave now a plan to create a self-sufficient lzma2 package that supports\nthe classic LZMA format as well as LZMA2. The core idea is to support a\nbaseReader and baseWriter type that support the basic LZMA stream\nwithout any headers. Both types must support the reuse of dictionaries\nand the opCodec.\n\n### 2015-01-10\n\n1. Implemented simple lzmago tool\n2. Tested tool against large 4.4G file\n    - compression worked correctly; tested decompression with lzma\n    - decompression hits a full buffer condition\n3. Fixed a bug in the compressor and wrote a test for it\n4. Executed full cycle for 4.4 GB file; performance can be improved ;-)\n\n### 2015-01-11\n\n- Release v0.2 because of the working LZMA encoder and decoder\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/bits.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 xz\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\n// putUint32LE puts the little-endian representation of x into the first\n// four bytes of p.\nfunc putUint32LE(p []byte, x uint32) {\n\tp[0] = byte(x)\n\tp[1] = byte(x >> 8)\n\tp[2] = byte(x >> 16)\n\tp[3] = byte(x >> 24)\n}\n\n// putUint64LE puts the little-endian representation of x into the first\n// eight bytes of p.\nfunc putUint64LE(p []byte, x uint64) {\n\tp[0] = byte(x)\n\tp[1] = byte(x >> 8)\n\tp[2] = byte(x >> 16)\n\tp[3] = byte(x >> 24)\n\tp[4] = byte(x >> 32)\n\tp[5] = byte(x >> 40)\n\tp[6] = byte(x >> 48)\n\tp[7] = byte(x >> 56)\n}\n\n// uint32LE converts a little endian representation to an uint32 value.\nfunc uint32LE(p []byte) uint32 {\n\treturn uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 |\n\t\tuint32(p[3])<<24\n}\n\n// putUvarint puts a uvarint representation of x into the byte slice.\nfunc putUvarint(p []byte, x uint64) int {\n\ti := 0\n\tfor x >= 0x80 {\n\t\tp[i] = byte(x) | 0x80\n\t\tx >>= 7\n\t\ti++\n\t}\n\tp[i] = byte(x)\n\treturn i + 1\n}\n\n// errOverflow indicates an overflow of the 64-bit unsigned integer.\nvar errOverflowU64 = errors.New(\"xz: uvarint overflows 64-bit unsigned integer\")\n\n// readUvarint reads a uvarint from the given byte reader.\nfunc readUvarint(r io.ByteReader) (x uint64, n int, err error) {\n\tvar s uint\n\ti := 0\n\tfor {\n\t\tb, err := r.ReadByte()\n\t\tif err != nil {\n\t\t\treturn x, i, err\n\t\t}\n\t\ti++\n\t\tif b < 0x80 {\n\t\t\tif i > 10 || i == 10 && b > 1 {\n\t\t\t\treturn x, i, errOverflowU64\n\t\t\t}\n\t\t\treturn x | uint64(b)<<s, i, nil\n\t\t}\n\t\tx |= uint64(b&0x7f) << s\n\t\ts += 7\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/crc.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 xz\n\nimport (\n\t\"hash\"\n\t\"hash/crc32\"\n\t\"hash/crc64\"\n)\n\n// crc32Hash implements the hash.Hash32 interface with Sum returning the\n// crc32 value in little-endian encoding.\ntype crc32Hash struct {\n\thash.Hash32\n}\n\n// Sum returns the crc32 value as little endian.\nfunc (h crc32Hash) Sum(b []byte) []byte {\n\tp := make([]byte, 4)\n\tputUint32LE(p, h.Hash32.Sum32())\n\tb = append(b, p...)\n\treturn b\n}\n\n// newCRC32 returns a CRC-32 hash that returns the 64-bit value in\n// little-endian encoding using the IEEE polynomial.\nfunc newCRC32() hash.Hash {\n\treturn crc32Hash{Hash32: crc32.NewIEEE()}\n}\n\n// crc64Hash implements the Hash64 interface with Sum returning the\n// CRC-64 value in little-endian encoding.\ntype crc64Hash struct {\n\thash.Hash64\n}\n\n// Sum returns the CRC-64 value in little-endian encoding.\nfunc (h crc64Hash) Sum(b []byte) []byte {\n\tp := make([]byte, 8)\n\tputUint64LE(p, h.Hash64.Sum64())\n\tb = append(b, p...)\n\treturn b\n}\n\n// crc64Table is used to create a CRC-64 hash.\nvar crc64Table = crc64.MakeTable(crc64.ECMA)\n\n// newCRC64 returns a CRC-64 hash that returns the 64-bit value in\n// little-endian encoding using the ECMA polynomial.\nfunc newCRC64() hash.Hash {\n\treturn crc64Hash{Hash64: crc64.New(crc64Table)}\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/format.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 xz\n\nimport (\n\t\"bytes\"\n\t\"crypto/sha256\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"hash/crc32\"\n\t\"io\"\n\n\t\"github.com/ulikunitz/xz/lzma\"\n)\n\n// allZeros checks whether a given byte slice has only zeros.\nfunc allZeros(p []byte) bool {\n\tfor _, c := range p {\n\t\tif c != 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// padLen returns the length of the padding required for the given\n// argument.\nfunc padLen(n int64) int {\n\tk := int(n % 4)\n\tif k > 0 {\n\t\tk = 4 - k\n\t}\n\treturn k\n}\n\n/*** Header ***/\n\n// headerMagic stores the magic bytes for the header\nvar headerMagic = []byte{0xfd, '7', 'z', 'X', 'Z', 0x00}\n\n// HeaderLen provides the length of the xz file header.\nconst HeaderLen = 12\n\n// Constants for the checksum methods supported by xz.\nconst (\n\tNone   byte = 0x0\n\tCRC32       = 0x1\n\tCRC64       = 0x4\n\tSHA256      = 0xa\n)\n\n// errInvalidFlags indicates that flags are invalid.\nvar errInvalidFlags = errors.New(\"xz: invalid flags\")\n\n// verifyFlags returns the error errInvalidFlags if the value is\n// invalid.\nfunc verifyFlags(flags byte) error {\n\tswitch flags {\n\tcase None, CRC32, CRC64, SHA256:\n\t\treturn nil\n\tdefault:\n\t\treturn errInvalidFlags\n\t}\n}\n\n// flagstrings maps flag values to strings.\nvar flagstrings = map[byte]string{\n\tNone:   \"None\",\n\tCRC32:  \"CRC-32\",\n\tCRC64:  \"CRC-64\",\n\tSHA256: \"SHA-256\",\n}\n\n// flagString returns the string representation for the given flags.\nfunc flagString(flags byte) string {\n\ts, ok := flagstrings[flags]\n\tif !ok {\n\t\treturn \"invalid\"\n\t}\n\treturn s\n}\n\n// newHashFunc returns a function that creates hash instances for the\n// hash method encoded in flags.\nfunc newHashFunc(flags byte) (newHash func() hash.Hash, err error) {\n\tswitch flags {\n\tcase None:\n\t\tnewHash = newNoneHash\n\tcase CRC32:\n\t\tnewHash = newCRC32\n\tcase CRC64:\n\t\tnewHash = newCRC64\n\tcase SHA256:\n\t\tnewHash = sha256.New\n\tdefault:\n\t\terr = errInvalidFlags\n\t}\n\treturn\n}\n\n// header provides the actual content of the xz file header: the flags.\ntype header struct {\n\tflags byte\n}\n\n// Errors returned by readHeader.\nvar errHeaderMagic = errors.New(\"xz: invalid header magic bytes\")\n\n// ValidHeader checks whether data is a correct xz file header. The\n// length of data must be HeaderLen.\nfunc ValidHeader(data []byte) bool {\n\tvar h header\n\terr := h.UnmarshalBinary(data)\n\treturn err == nil\n}\n\n// String returns a string representation of the flags.\nfunc (h header) String() string {\n\treturn flagString(h.flags)\n}\n\n// UnmarshalBinary reads header from the provided data slice.\nfunc (h *header) UnmarshalBinary(data []byte) error {\n\t// header length\n\tif len(data) != HeaderLen {\n\t\treturn errors.New(\"xz: wrong file header length\")\n\t}\n\n\t// magic header\n\tif !bytes.Equal(headerMagic, data[:6]) {\n\t\treturn errHeaderMagic\n\t}\n\n\t// checksum\n\tcrc := crc32.NewIEEE()\n\tcrc.Write(data[6:8])\n\tif uint32LE(data[8:]) != crc.Sum32() {\n\t\treturn errors.New(\"xz: invalid checksum for file header\")\n\t}\n\n\t// stream flags\n\tif data[6] != 0 {\n\t\treturn errInvalidFlags\n\t}\n\tflags := data[7]\n\tif err := verifyFlags(flags); err != nil {\n\t\treturn err\n\t}\n\n\th.flags = flags\n\treturn nil\n}\n\n// MarshalBinary generates the xz file header.\nfunc (h *header) MarshalBinary() (data []byte, err error) {\n\tif err = verifyFlags(h.flags); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdata = make([]byte, 12)\n\tcopy(data, headerMagic)\n\tdata[7] = h.flags\n\n\tcrc := crc32.NewIEEE()\n\tcrc.Write(data[6:8])\n\tputUint32LE(data[8:], crc.Sum32())\n\n\treturn data, nil\n}\n\n/*** Footer ***/\n\n// footerLen defines the length of the footer.\nconst footerLen = 12\n\n// footerMagic contains the footer magic bytes.\nvar footerMagic = []byte{'Y', 'Z'}\n\n// footer represents the content of the xz file footer.\ntype footer struct {\n\tindexSize int64\n\tflags     byte\n}\n\n// String prints a string representation of the footer structure.\nfunc (f footer) String() string {\n\treturn fmt.Sprintf(\"%s index size %d\", flagString(f.flags), f.indexSize)\n}\n\n// Minimum and maximum for the size of the index (backward size).\nconst (\n\tminIndexSize = 4\n\tmaxIndexSize = (1 << 32) * 4\n)\n\n// MarshalBinary converts footer values into an xz file footer. Note\n// that the footer value is checked for correctness.\nfunc (f *footer) MarshalBinary() (data []byte, err error) {\n\tif err = verifyFlags(f.flags); err != nil {\n\t\treturn nil, err\n\t}\n\tif !(minIndexSize <= f.indexSize && f.indexSize <= maxIndexSize) {\n\t\treturn nil, errors.New(\"xz: index size out of range\")\n\t}\n\tif f.indexSize%4 != 0 {\n\t\treturn nil, errors.New(\n\t\t\t\"xz: index size not aligned to four bytes\")\n\t}\n\n\tdata = make([]byte, footerLen)\n\n\t// backward size (index size)\n\ts := (f.indexSize / 4) - 1\n\tputUint32LE(data[4:], uint32(s))\n\t// flags\n\tdata[9] = f.flags\n\t// footer magic\n\tcopy(data[10:], footerMagic)\n\n\t// CRC-32\n\tcrc := crc32.NewIEEE()\n\tcrc.Write(data[4:10])\n\tputUint32LE(data, crc.Sum32())\n\n\treturn data, nil\n}\n\n// UnmarshalBinary sets the footer value by unmarshalling an xz file\n// footer.\nfunc (f *footer) UnmarshalBinary(data []byte) error {\n\tif len(data) != footerLen {\n\t\treturn errors.New(\"xz: wrong footer length\")\n\t}\n\n\t// magic bytes\n\tif !bytes.Equal(data[10:], footerMagic) {\n\t\treturn errors.New(\"xz: footer magic invalid\")\n\t}\n\n\t// CRC-32\n\tcrc := crc32.NewIEEE()\n\tcrc.Write(data[4:10])\n\tif uint32LE(data) != crc.Sum32() {\n\t\treturn errors.New(\"xz: footer checksum error\")\n\t}\n\n\tvar g footer\n\t// backward size (index size)\n\tg.indexSize = (int64(uint32LE(data[4:])) + 1) * 4\n\n\t// flags\n\tif data[8] != 0 {\n\t\treturn errInvalidFlags\n\t}\n\tg.flags = data[9]\n\tif err := verifyFlags(g.flags); err != nil {\n\t\treturn err\n\t}\n\n\t*f = g\n\treturn nil\n}\n\n/*** Block Header ***/\n\n// blockHeader represents the content of an xz block header.\ntype blockHeader struct {\n\tcompressedSize   int64\n\tuncompressedSize int64\n\tfilters          []filter\n}\n\n// String converts the block header into a string.\nfunc (h blockHeader) String() string {\n\tvar buf bytes.Buffer\n\tfirst := true\n\tif h.compressedSize >= 0 {\n\t\tfmt.Fprintf(&buf, \"compressed size %d\", h.compressedSize)\n\t\tfirst = false\n\t}\n\tif h.uncompressedSize >= 0 {\n\t\tif !first {\n\t\t\tbuf.WriteString(\" \")\n\t\t}\n\t\tfmt.Fprintf(&buf, \"uncompressed size %d\", h.uncompressedSize)\n\t\tfirst = false\n\t}\n\tfor _, f := range h.filters {\n\t\tif !first {\n\t\t\tbuf.WriteString(\" \")\n\t\t}\n\t\tfmt.Fprintf(&buf, \"filter %s\", f)\n\t\tfirst = false\n\t}\n\treturn buf.String()\n}\n\n// Masks for the block flags.\nconst (\n\tfilterCountMask         = 0x03\n\tcompressedSizePresent   = 0x40\n\tuncompressedSizePresent = 0x80\n\treservedBlockFlags      = 0x3C\n)\n\n// errIndexIndicator signals that an index indicator (0x00) has been found\n// instead of an expected block header indicator.\nvar errIndexIndicator = errors.New(\"xz: found index indicator\")\n\n// readBlockHeader reads the block header.\nfunc readBlockHeader(r io.Reader) (h *blockHeader, n int, err error) {\n\tvar buf bytes.Buffer\n\tbuf.Grow(20)\n\n\t// block header size\n\tz, err := io.CopyN(&buf, r, 1)\n\tn = int(z)\n\tif err != nil {\n\t\treturn nil, n, err\n\t}\n\ts := buf.Bytes()[0]\n\tif s == 0 {\n\t\treturn nil, n, errIndexIndicator\n\t}\n\n\t// read complete header\n\theaderLen := (int(s) + 1) * 4\n\tbuf.Grow(headerLen - 1)\n\tz, err = io.CopyN(&buf, r, int64(headerLen-1))\n\tn += int(z)\n\tif err != nil {\n\t\treturn nil, n, err\n\t}\n\n\t// unmarshal block header\n\th = new(blockHeader)\n\tif err = h.UnmarshalBinary(buf.Bytes()); err != nil {\n\t\treturn nil, n, err\n\t}\n\n\treturn h, n, nil\n}\n\n// readSizeInBlockHeader reads the uncompressed or compressed size\n// fields in the block header. The present value informs the function\n// whether the respective field is actually present in the header.\nfunc readSizeInBlockHeader(r io.ByteReader, present bool) (n int64, err error) {\n\tif !present {\n\t\treturn -1, nil\n\t}\n\tx, _, err := readUvarint(r)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif x >= 1<<63 {\n\t\treturn 0, errors.New(\"xz: size overflow in block header\")\n\t}\n\treturn int64(x), nil\n}\n\n// UnmarshalBinary unmarshals the block header.\nfunc (h *blockHeader) UnmarshalBinary(data []byte) error {\n\t// Check header length\n\ts := data[0]\n\tif data[0] == 0 {\n\t\treturn errIndexIndicator\n\t}\n\theaderLen := (int(s) + 1) * 4\n\tif len(data) != headerLen {\n\t\treturn fmt.Errorf(\"xz: data length %d; want %d\", len(data),\n\t\t\theaderLen)\n\t}\n\tn := headerLen - 4\n\n\t// Check CRC-32\n\tcrc := crc32.NewIEEE()\n\tcrc.Write(data[:n])\n\tif crc.Sum32() != uint32LE(data[n:]) {\n\t\treturn errors.New(\"xz: checksum error for block header\")\n\t}\n\n\t// Block header flags\n\tflags := data[1]\n\tif flags&reservedBlockFlags != 0 {\n\t\treturn errors.New(\"xz: reserved block header flags set\")\n\t}\n\n\tr := bytes.NewReader(data[2:n])\n\n\t// Compressed size\n\tvar err error\n\th.compressedSize, err = readSizeInBlockHeader(\n\t\tr, flags&compressedSizePresent != 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Uncompressed size\n\th.uncompressedSize, err = readSizeInBlockHeader(\n\t\tr, flags&uncompressedSizePresent != 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\th.filters, err = readFilters(r, int(flags&filterCountMask)+1)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Check padding\n\t// Since headerLen is a multiple of 4 we don't need to check\n\t// alignment.\n\tk := r.Len()\n\t// The standard spec says that the padding should have not more\n\t// than 3 bytes. However we found paddings of 4 or 5 in the\n\t// wild. See https://github.com/ulikunitz/xz/pull/11 and\n\t// https://github.com/ulikunitz/xz/issues/15\n\t//\n\t// The only reasonable approach seems to be to ignore the\n\t// padding size. We still check that all padding bytes are zero.\n\tif !allZeros(data[n-k : n]) {\n\t\treturn errPadding\n\t}\n\treturn nil\n}\n\n// MarshalBinary marshals the binary header.\nfunc (h *blockHeader) MarshalBinary() (data []byte, err error) {\n\tif !(minFilters <= len(h.filters) && len(h.filters) <= maxFilters) {\n\t\treturn nil, errors.New(\"xz: filter count wrong\")\n\t}\n\tfor i, f := range h.filters {\n\t\tif i < len(h.filters)-1 {\n\t\t\tif f.id() == lzmaFilterID {\n\t\t\t\treturn nil, errors.New(\n\t\t\t\t\t\"xz: LZMA2 filter is not the last\")\n\t\t\t}\n\t\t} else {\n\t\t\t// last filter\n\t\t\tif f.id() != lzmaFilterID {\n\t\t\t\treturn nil, errors.New(\"xz: \" +\n\t\t\t\t\t\"last filter must be the LZMA2 filter\")\n\t\t\t}\n\t\t}\n\t}\n\n\tvar buf bytes.Buffer\n\t// header size must set at the end\n\tbuf.WriteByte(0)\n\n\t// flags\n\tflags := byte(len(h.filters) - 1)\n\tif h.compressedSize >= 0 {\n\t\tflags |= compressedSizePresent\n\t}\n\tif h.uncompressedSize >= 0 {\n\t\tflags |= uncompressedSizePresent\n\t}\n\tbuf.WriteByte(flags)\n\n\tp := make([]byte, 10)\n\tif h.compressedSize >= 0 {\n\t\tk := putUvarint(p, uint64(h.compressedSize))\n\t\tbuf.Write(p[:k])\n\t}\n\tif h.uncompressedSize >= 0 {\n\t\tk := putUvarint(p, uint64(h.uncompressedSize))\n\t\tbuf.Write(p[:k])\n\t}\n\n\tfor _, f := range h.filters {\n\t\tfp, err := f.MarshalBinary()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbuf.Write(fp)\n\t}\n\n\t// padding\n\tfor i := padLen(int64(buf.Len())); i > 0; i-- {\n\t\tbuf.WriteByte(0)\n\t}\n\n\t// crc place holder\n\tbuf.Write(p[:4])\n\n\tdata = buf.Bytes()\n\tif len(data)%4 != 0 {\n\t\tpanic(\"data length not aligned\")\n\t}\n\ts := len(data)/4 - 1\n\tif !(1 < s && s <= 255) {\n\t\tpanic(\"wrong block header size\")\n\t}\n\tdata[0] = byte(s)\n\n\tcrc := crc32.NewIEEE()\n\tcrc.Write(data[:len(data)-4])\n\tputUint32LE(data[len(data)-4:], crc.Sum32())\n\n\treturn data, nil\n}\n\n// Constants used for marshalling and unmarshalling filters in the xz\n// block header.\nconst (\n\tminFilters    = 1\n\tmaxFilters    = 4\n\tminReservedID = 1 << 62\n)\n\n// filter represents a filter in the block header.\ntype filter interface {\n\tid() uint64\n\tUnmarshalBinary(data []byte) error\n\tMarshalBinary() (data []byte, err error)\n\treader(r io.Reader, c *ReaderConfig) (fr io.Reader, err error)\n\twriteCloser(w io.WriteCloser, c *WriterConfig) (fw io.WriteCloser, err error)\n\t// filter must be last filter\n\tlast() bool\n}\n\n// readFilter reads a block filter from the block header. At this point\n// in time only the LZMA2 filter is supported.\nfunc readFilter(r io.Reader) (f filter, err error) {\n\tbr := lzma.ByteReader(r)\n\n\t// index\n\tid, _, err := readUvarint(br)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar data []byte\n\tswitch id {\n\tcase lzmaFilterID:\n\t\tdata = make([]byte, lzmaFilterLen)\n\t\tdata[0] = lzmaFilterID\n\t\tif _, err = io.ReadFull(r, data[1:]); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tf = new(lzmaFilter)\n\tdefault:\n\t\tif id >= minReservedID {\n\t\t\treturn nil, errors.New(\n\t\t\t\t\"xz: reserved filter id in block stream header\")\n\t\t}\n\t\treturn nil, errors.New(\"xz: invalid filter id\")\n\t}\n\tif err = f.UnmarshalBinary(data); err != nil {\n\t\treturn nil, err\n\t}\n\treturn f, err\n}\n\n// readFilters reads count filters. At this point in time only the count\n// 1 is supported.\nfunc readFilters(r io.Reader, count int) (filters []filter, err error) {\n\tif count != 1 {\n\t\treturn nil, errors.New(\"xz: unsupported filter count\")\n\t}\n\tf, err := readFilter(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn []filter{f}, err\n}\n\n// writeFilters writes the filters.\nfunc writeFilters(w io.Writer, filters []filter) (n int, err error) {\n\tfor _, f := range filters {\n\t\tp, err := f.MarshalBinary()\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tk, err := w.Write(p)\n\t\tn += k\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t}\n\treturn n, nil\n}\n\n/*** Index ***/\n\n// record describes a block in the xz file index.\ntype record struct {\n\tunpaddedSize     int64\n\tuncompressedSize int64\n}\n\n// readRecord reads an index record.\nfunc readRecord(r io.ByteReader) (rec record, n int, err error) {\n\tu, k, err := readUvarint(r)\n\tn += k\n\tif err != nil {\n\t\treturn rec, n, err\n\t}\n\trec.unpaddedSize = int64(u)\n\tif rec.unpaddedSize < 0 {\n\t\treturn rec, n, errors.New(\"xz: unpadded size negative\")\n\t}\n\n\tu, k, err = readUvarint(r)\n\tn += k\n\tif err != nil {\n\t\treturn rec, n, err\n\t}\n\trec.uncompressedSize = int64(u)\n\tif rec.uncompressedSize < 0 {\n\t\treturn rec, n, errors.New(\"xz: uncompressed size negative\")\n\t}\n\n\treturn rec, n, nil\n}\n\n// MarshalBinary converts an index record in its binary encoding.\nfunc (rec *record) MarshalBinary() (data []byte, err error) {\n\t// maximum length of a uvarint is 10\n\tp := make([]byte, 20)\n\tn := putUvarint(p, uint64(rec.unpaddedSize))\n\tn += putUvarint(p[n:], uint64(rec.uncompressedSize))\n\treturn p[:n], nil\n}\n\n// writeIndex writes the index, a sequence of records.\nfunc writeIndex(w io.Writer, index []record) (n int64, err error) {\n\tcrc := crc32.NewIEEE()\n\tmw := io.MultiWriter(w, crc)\n\n\t// index indicator\n\tk, err := mw.Write([]byte{0})\n\tn += int64(k)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\n\t// number of records\n\tp := make([]byte, 10)\n\tk = putUvarint(p, uint64(len(index)))\n\tk, err = mw.Write(p[:k])\n\tn += int64(k)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\n\t// list of records\n\tfor _, rec := range index {\n\t\tp, err := rec.MarshalBinary()\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tk, err = mw.Write(p)\n\t\tn += int64(k)\n\t\tif err != nil {\n\t\t\treturn n, err\n\t\t}\n\t}\n\n\t// index padding\n\tk, err = mw.Write(make([]byte, padLen(int64(n))))\n\tn += int64(k)\n\tif err != nil {\n\t\treturn n, err\n\t}\n\n\t// crc32 checksum\n\tputUint32LE(p, crc.Sum32())\n\tk, err = w.Write(p[:4])\n\tn += int64(k)\n\n\treturn n, err\n}\n\n// readIndexBody reads the index from the reader. It assumes that the\n// index indicator has already been read.\nfunc readIndexBody(r io.Reader) (records []record, n int64, err error) {\n\tcrc := crc32.NewIEEE()\n\t// index indicator\n\tcrc.Write([]byte{0})\n\n\tbr := lzma.ByteReader(io.TeeReader(r, crc))\n\n\t// number of records\n\tu, k, err := readUvarint(br)\n\tn += int64(k)\n\tif err != nil {\n\t\treturn nil, n, err\n\t}\n\trecLen := int(u)\n\tif recLen < 0 || uint64(recLen) != u {\n\t\treturn nil, n, errors.New(\"xz: record number overflow\")\n\t}\n\n\t// list of records\n\trecords = make([]record, recLen)\n\tfor i := range records {\n\t\trecords[i], k, err = readRecord(br)\n\t\tn += int64(k)\n\t\tif err != nil {\n\t\t\treturn nil, n, err\n\t\t}\n\t}\n\n\tp := make([]byte, padLen(int64(n+1)), 4)\n\tk, err = io.ReadFull(br.(io.Reader), p)\n\tn += int64(k)\n\tif err != nil {\n\t\treturn nil, n, err\n\t}\n\tif !allZeros(p) {\n\t\treturn nil, n, errors.New(\"xz: non-zero byte in index padding\")\n\t}\n\n\t// crc32\n\ts := crc.Sum32()\n\tp = p[:4]\n\tk, err = io.ReadFull(br.(io.Reader), p)\n\tn += int64(k)\n\tif err != nil {\n\t\treturn records, n, err\n\t}\n\tif uint32LE(p) != s {\n\t\treturn nil, n, errors.New(\"xz: wrong checksum for index\")\n\t}\n\n\treturn records, n, nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/internal/hash/cyclic_poly.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 hash\n\n// CyclicPoly provides a cyclic polynomial rolling hash.\ntype CyclicPoly struct {\n\th uint64\n\tp []uint64\n\ti int\n}\n\n// ror rotates the unsigned 64-bit integer to right. The argument s must be\n// less than 64.\nfunc ror(x uint64, s uint) uint64 {\n\treturn (x >> s) | (x << (64 - s))\n}\n\n// NewCyclicPoly creates a new instance of the CyclicPoly structure. The\n// argument n gives the number of bytes for which a hash will be executed.\n// This number must be positive; the method panics if this isn't the case.\nfunc NewCyclicPoly(n int) *CyclicPoly {\n\tif n < 1 {\n\t\tpanic(\"argument n must be positive\")\n\t}\n\treturn &CyclicPoly{p: make([]uint64, 0, n)}\n}\n\n// Len returns the length of the byte sequence for which a hash is generated.\nfunc (r *CyclicPoly) Len() int {\n\treturn cap(r.p)\n}\n\n// RollByte hashes the next byte and returns a hash value. The complete becomes\n// available after at least Len() bytes have been hashed.\nfunc (r *CyclicPoly) RollByte(x byte) uint64 {\n\ty := hash[x]\n\tif len(r.p) < cap(r.p) {\n\t\tr.h = ror(r.h, 1) ^ y\n\t\tr.p = append(r.p, y)\n\t} else {\n\t\tr.h ^= ror(r.p[r.i], uint(cap(r.p)-1))\n\t\tr.h = ror(r.h, 1) ^ y\n\t\tr.p[r.i] = y\n\t\tr.i = (r.i + 1) % cap(r.p)\n\t}\n\treturn r.h\n}\n\n// Stores the hash for the individual bytes.\nvar hash = [256]uint64{\n\t0x2e4fc3f904065142, 0xc790984cfbc99527,\n\t0x879f95eb8c62f187, 0x3b61be86b5021ef2,\n\t0x65a896a04196f0a5, 0xc5b307b80470b59e,\n\t0xd3bff376a70df14b, 0xc332f04f0b3f1701,\n\t0x753b5f0e9abf3e0d, 0xb41538fdfe66ef53,\n\t0x1906a10c2c1c0208, 0xfb0c712a03421c0d,\n\t0x38be311a65c9552b, 0xfee7ee4ca6445c7e,\n\t0x71aadeded184f21e, 0xd73426fccda23b2d,\n\t0x29773fb5fb9600b5, 0xce410261cd32981a,\n\t0xfe2848b3c62dbc2d, 0x459eaaff6e43e11c,\n\t0xc13e35fc9c73a887, 0xf30ed5c201e76dbc,\n\t0xa5f10b3910482cea, 0x2945d59be02dfaad,\n\t0x06ee334ff70571b5, 0xbabf9d8070f44380,\n\t0xee3e2e9912ffd27c, 0x2a7118d1ea6b8ea7,\n\t0x26183cb9f7b1664c, 0xea71dac7da068f21,\n\t0xea92eca5bd1d0bb7, 0x415595862defcd75,\n\t0x248a386023c60648, 0x9cf021ab284b3c8a,\n\t0xfc9372df02870f6c, 0x2b92d693eeb3b3fc,\n\t0x73e799d139dc6975, 0x7b15ae312486363c,\n\t0xb70e5454a2239c80, 0x208e3fb31d3b2263,\n\t0x01f563cabb930f44, 0x2ac4533d2a3240d8,\n\t0x84231ed1064f6f7c, 0xa9f020977c2a6d19,\n\t0x213c227271c20122, 0x09fe8a9a0a03d07a,\n\t0x4236dc75bcaf910c, 0x460a8b2bead8f17e,\n\t0xd9b27be1aa07055f, 0xd202d5dc4b11c33e,\n\t0x70adb010543bea12, 0xcdae938f7ea6f579,\n\t0x3f3d870208672f4d, 0x8e6ccbce9d349536,\n\t0xe4c0871a389095ae, 0xf5f2a49152bca080,\n\t0x9a43f9b97269934e, 0xc17b3753cb6f475c,\n\t0xd56d941e8e206bd4, 0xac0a4f3e525eda00,\n\t0xa06d5a011912a550, 0x5537ed19537ad1df,\n\t0xa32fe713d611449d, 0x2a1d05b47c3b579f,\n\t0x991d02dbd30a2a52, 0x39e91e7e28f93eb0,\n\t0x40d06adb3e92c9ac, 0x9b9d3afde1c77c97,\n\t0x9a3f3f41c02c616f, 0x22ecd4ba00f60c44,\n\t0x0b63d5d801708420, 0x8f227ca8f37ffaec,\n\t0x0256278670887c24, 0x107e14877dbf540b,\n\t0x32c19f2786ac1c05, 0x1df5b12bb4bc9c61,\n\t0xc0cac129d0d4c4e2, 0x9fdb52ee9800b001,\n\t0x31f601d5d31c48c4, 0x72ff3c0928bcaec7,\n\t0xd99264421147eb03, 0x535a2d6d38aefcfe,\n\t0x6ba8b4454a916237, 0xfa39366eaae4719c,\n\t0x10f00fd7bbb24b6f, 0x5bd23185c76c84d4,\n\t0xb22c3d7e1b00d33f, 0x3efc20aa6bc830a8,\n\t0xd61c2503fe639144, 0x30ce625441eb92d3,\n\t0xe5d34cf359e93100, 0xa8e5aa13f2b9f7a5,\n\t0x5c2b8d851ca254a6, 0x68fb6c5e8b0d5fdf,\n\t0xc7ea4872c96b83ae, 0x6dd5d376f4392382,\n\t0x1be88681aaa9792f, 0xfef465ee1b6c10d9,\n\t0x1f98b65ed43fcb2e, 0x4d1ca11eb6e9a9c9,\n\t0x7808e902b3857d0b, 0x171c9c4ea4607972,\n\t0x58d66274850146df, 0x42b311c10d3981d1,\n\t0x647fa8c621c41a4c, 0xf472771c66ddfedc,\n\t0x338d27e3f847b46b, 0x6402ce3da97545ce,\n\t0x5162db616fc38638, 0x9c83be97bc22a50e,\n\t0x2d3d7478a78d5e72, 0xe621a9b938fd5397,\n\t0x9454614eb0f81c45, 0x395fb6e742ed39b6,\n\t0x77dd9179d06037bf, 0xc478d0fee4d2656d,\n\t0x35d9d6cb772007af, 0x83a56e92c883f0f6,\n\t0x27937453250c00a1, 0x27bd6ebc3a46a97d,\n\t0x9f543bf784342d51, 0xd158f38c48b0ed52,\n\t0x8dd8537c045f66b4, 0x846a57230226f6d5,\n\t0x6b13939e0c4e7cdf, 0xfca25425d8176758,\n\t0x92e5fc6cd52788e6, 0x9992e13d7a739170,\n\t0x518246f7a199e8ea, 0xf104c2a71b9979c7,\n\t0x86b3ffaabea4768f, 0x6388061cf3e351ad,\n\t0x09d9b5295de5bbb5, 0x38bf1638c2599e92,\n\t0x1d759846499e148d, 0x4c0ff015e5f96ef4,\n\t0xa41a94cfa270f565, 0x42d76f9cb2326c0b,\n\t0x0cf385dd3c9c23ba, 0x0508a6c7508d6e7a,\n\t0x337523aabbe6cf8d, 0x646bb14001d42b12,\n\t0xc178729d138adc74, 0xf900ef4491f24086,\n\t0xee1a90d334bb5ac4, 0x9755c92247301a50,\n\t0xb999bf7c4ff1b610, 0x6aeeb2f3b21e8fc9,\n\t0x0fa8084cf91ac6ff, 0x10d226cf136e6189,\n\t0xd302057a07d4fb21, 0x5f03800e20a0fcc3,\n\t0x80118d4ae46bd210, 0x58ab61a522843733,\n\t0x51edd575c5432a4b, 0x94ee6ff67f9197f7,\n\t0x765669e0e5e8157b, 0xa5347830737132f0,\n\t0x3ba485a69f01510c, 0x0b247d7b957a01c3,\n\t0x1b3d63449fd807dc, 0x0fdc4721c30ad743,\n\t0x8b535ed3829b2b14, 0xee41d0cad65d232c,\n\t0xe6a99ed97a6a982f, 0x65ac6194c202003d,\n\t0x692accf3a70573eb, 0xcc3c02c3e200d5af,\n\t0x0d419e8b325914a3, 0x320f160f42c25e40,\n\t0x00710d647a51fe7a, 0x3c947692330aed60,\n\t0x9288aa280d355a7a, 0xa1806a9b791d1696,\n\t0x5d60e38496763da1, 0x6c69e22e613fd0f4,\n\t0x977fc2a5aadffb17, 0xfb7bd063fc5a94ba,\n\t0x460c17992cbaece1, 0xf7822c5444d3297f,\n\t0x344a9790c69b74aa, 0xb80a42e6cae09dce,\n\t0x1b1361eaf2b1e757, 0xd84c1e758e236f01,\n\t0x88e0b7be347627cc, 0x45246009b7a99490,\n\t0x8011c6dd3fe50472, 0xc341d682bffb99d7,\n\t0x2511be93808e2d15, 0xd5bc13d7fd739840,\n\t0x2a3cd030679ae1ec, 0x8ad9898a4b9ee157,\n\t0x3245fef0a8eaf521, 0x3d6d8dbbb427d2b0,\n\t0x1ed146d8968b3981, 0x0c6a28bf7d45f3fc,\n\t0x4a1fd3dbcee3c561, 0x4210ff6a476bf67e,\n\t0xa559cce0d9199aac, 0xde39d47ef3723380,\n\t0xe5b69d848ce42e35, 0xefa24296f8e79f52,\n\t0x70190b59db9a5afc, 0x26f166cdb211e7bf,\n\t0x4deaf2df3c6b8ef5, 0xf171dbdd670f1017,\n\t0xb9059b05e9420d90, 0x2f0da855c9388754,\n\t0x611d5e9ab77949cc, 0x2912038ac01163f4,\n\t0x0231df50402b2fba, 0x45660fc4f3245f58,\n\t0xb91cc97c7c8dac50, 0xb72d2aafe4953427,\n\t0xfa6463f87e813d6b, 0x4515f7ee95d5c6a2,\n\t0x1310e1c1a48d21c3, 0xad48a7810cdd8544,\n\t0x4d5bdfefd5c9e631, 0xa43ed43f1fdcb7de,\n\t0xe70cfc8fe1ee9626, 0xef4711b0d8dda442,\n\t0xb80dd9bd4dab6c93, 0xa23be08d31ba4d93,\n\t0x9b37db9d0335a39c, 0x494b6f870f5cfebc,\n\t0x6d1b3c1149dda943, 0x372c943a518c1093,\n\t0xad27af45e77c09c4, 0x3b6f92b646044604,\n\t0xac2917909f5fcf4f, 0x2069a60e977e5557,\n\t0x353a469e71014de5, 0x24be356281f55c15,\n\t0x2b6d710ba8e9adea, 0x404ad1751c749c29,\n\t0xed7311bf23d7f185, 0xba4f6976b4acc43e,\n\t0x32d7198d2bc39000, 0xee667019014d6e01,\n\t0x494ef3e128d14c83, 0x1f95a152baecd6be,\n\t0x201648dff1f483a5, 0x68c28550c8384af6,\n\t0x5fc834a6824a7f48, 0x7cd06cb7365eaf28,\n\t0xd82bbd95e9b30909, 0x234f0d1694c53f6d,\n\t0xd2fb7f4a96d83f4a, 0xff0d5da83acac05e,\n\t0xf8f6b97f5585080a, 0x74236084be57b95b,\n\t0xa25e40c03bbc36ad, 0x6b6e5c14ce88465b,\n\t0x4378ffe93e1528c5, 0x94ca92a17118e2d2,\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/internal/hash/doc.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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/*\nPackage hash provides rolling hashes.\n\nRolling hashes have to be used for maintaining the positions of n-byte\nsequences in the dictionary buffer.\n\nThe package provides currently the Rabin-Karp rolling hash and a Cyclic\nPolynomial hash. Both support the Hashes method to be used with an interface.\n*/\npackage hash\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/internal/hash/rabin_karp.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 hash\n\n// A is the default constant for Robin-Karp rolling hash. This is a random\n// prime.\nconst A = 0x97b548add41d5da1\n\n// RabinKarp supports the computation of a rolling hash.\ntype RabinKarp struct {\n\tA uint64\n\t// a^n\n\taOldest uint64\n\th       uint64\n\tp       []byte\n\ti       int\n}\n\n// NewRabinKarp creates a new RabinKarp value. The argument n defines the\n// length of the byte sequence to be hashed. The default constant will will be\n// used.\nfunc NewRabinKarp(n int) *RabinKarp {\n\treturn NewRabinKarpConst(n, A)\n}\n\n// NewRabinKarpConst creates a new RabinKarp value. The argument n defines the\n// length of the byte sequence to be hashed. The argument a provides the\n// constant used to compute the hash.\nfunc NewRabinKarpConst(n int, a uint64) *RabinKarp {\n\tif n <= 0 {\n\t\tpanic(\"number of bytes n must be positive\")\n\t}\n\taOldest := uint64(1)\n\t// There are faster methods. For the small n required by the LZMA\n\t// compressor O(n) is sufficient.\n\tfor i := 0; i < n; i++ {\n\t\taOldest *= a\n\t}\n\treturn &RabinKarp{\n\t\tA: a, aOldest: aOldest,\n\t\tp: make([]byte, 0, n),\n\t}\n}\n\n// Len returns the length of the byte sequence.\nfunc (r *RabinKarp) Len() int {\n\treturn cap(r.p)\n}\n\n// RollByte computes the hash after x has been added.\nfunc (r *RabinKarp) RollByte(x byte) uint64 {\n\tif len(r.p) < cap(r.p) {\n\t\tr.h += uint64(x)\n\t\tr.h *= r.A\n\t\tr.p = append(r.p, x)\n\t} else {\n\t\tr.h -= uint64(r.p[r.i]) * r.aOldest\n\t\tr.h += uint64(x)\n\t\tr.h *= r.A\n\t\tr.p[r.i] = x\n\t\tr.i = (r.i + 1) % cap(r.p)\n\t}\n\treturn r.h\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/internal/hash/roller.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 hash\n\n// Roller provides an interface for rolling hashes. The hash value will become\n// valid after hash has been called Len times.\ntype Roller interface {\n\tLen() int\n\tRollByte(x byte) uint64\n}\n\n// Hashes computes all hash values for the array p. Note that the state of the\n// roller is changed.\nfunc Hashes(r Roller, p []byte) []uint64 {\n\tn := r.Len()\n\tif len(p) < n {\n\t\treturn nil\n\t}\n\th := make([]uint64, len(p)-n+1)\n\tfor i := 0; i < n-1; i++ {\n\t\tr.RollByte(p[i])\n\t}\n\tfor i := range h {\n\t\th[i] = r.RollByte(p[i+n-1])\n\t}\n\treturn h\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/internal/xlog/xlog.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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// Package xlog provides a simple logging package that allows to disable\n// certain message categories. It defines a type, Logger, with multiple\n// methods for formatting output. The package has also a predefined\n// 'standard' Logger accessible through helper function Print[f|ln],\n// Fatal[f|ln], Panic[f|ln], Warn[f|ln], Print[f|ln] and Debug[f|ln]\n// that are easier to use then creating a Logger manually. That logger\n// writes to standard error and prints the date and time of each logged\n// message, which can be configured using the function SetFlags.\n//\n// The Fatal functions call os.Exit(1) after the message is output\n// unless not suppressed by the flags. The Panic functions call panic\n// after the writing the log message unless suppressed.\npackage xlog\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"runtime\"\n\t\"sync\"\n\t\"time\"\n)\n\n// The flags define what information is prefixed to each log entry\n// generated by the Logger. The Lno* versions allow the suppression of\n// specific output. The bits are or'ed together to control what will be\n// printed. There is no control over the order of the items printed and\n// the format. The full format is:\n//\n//   2009-01-23 01:23:23.123123 /a/b/c/d.go:23: message\n//\nconst (\n\tLdate         = 1 << iota // the date: 2009-01-23\n\tLtime                     // the time: 01:23:23\n\tLmicroseconds             // microsecond resolution: 01:23:23.123123\n\tLlongfile                 // full file name and line number: /a/b/c/d.go:23\n\tLshortfile                // final file name element and line number: d.go:23\n\tLnopanic                  // suppresses output from Panic[f|ln] but not the panic call\n\tLnofatal                  // suppresses output from Fatal[f|ln] but not the exit\n\tLnowarn                   // suppresses output from Warn[f|ln]\n\tLnoprint                  // suppresses output from Print[f|ln]\n\tLnodebug                  // suppresses output from Debug[f|ln]\n\t// initial values for the standard logger\n\tLstdflags = Ldate | Ltime | Lnodebug\n)\n\n// A Logger represents an active logging object that generates lines of\n// output to an io.Writer. Each logging operation if not suppressed\n// makes a single call to the Writer's Write method. A Logger can be\n// used simultaneously from multiple goroutines; it guarantees to\n// serialize access to the Writer.\ntype Logger struct {\n\tmu sync.Mutex // ensures atomic writes; and protects the following\n\t// fields\n\tprefix string    // prefix to write at beginning of each line\n\tflag   int       // properties\n\tout    io.Writer // destination for output\n\tbuf    []byte    // for accumulating text to write\n}\n\n// New creates a new Logger. The out argument sets the destination to\n// which the log output will be written. The prefix appears at the\n// beginning of each log line. The flag argument defines the logging\n// properties.\nfunc New(out io.Writer, prefix string, flag int) *Logger {\n\treturn &Logger{out: out, prefix: prefix, flag: flag}\n}\n\n// std is the standard logger used by the package scope functions.\nvar std = New(os.Stderr, \"\", Lstdflags)\n\n// itoa converts the integer to ASCII. A negative widths will avoid\n// zero-padding. The function supports only non-negative integers.\nfunc itoa(buf *[]byte, i int, wid int) {\n\tvar u = uint(i)\n\tif u == 0 && wid <= 1 {\n\t\t*buf = append(*buf, '0')\n\t\treturn\n\t}\n\tvar b [32]byte\n\tbp := len(b)\n\tfor ; u > 0 || wid > 0; u /= 10 {\n\t\tbp--\n\t\twid--\n\t\tb[bp] = byte(u%10) + '0'\n\t}\n\t*buf = append(*buf, b[bp:]...)\n}\n\n// formatHeader puts the header into the buf field of the buffer.\nfunc (l *Logger) formatHeader(t time.Time, file string, line int) {\n\tl.buf = append(l.buf, l.prefix...)\n\tif l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {\n\t\tif l.flag&Ldate != 0 {\n\t\t\tyear, month, day := t.Date()\n\t\t\titoa(&l.buf, year, 4)\n\t\t\tl.buf = append(l.buf, '-')\n\t\t\titoa(&l.buf, int(month), 2)\n\t\t\tl.buf = append(l.buf, '-')\n\t\t\titoa(&l.buf, day, 2)\n\t\t\tl.buf = append(l.buf, ' ')\n\t\t}\n\t\tif l.flag&(Ltime|Lmicroseconds) != 0 {\n\t\t\thour, min, sec := t.Clock()\n\t\t\titoa(&l.buf, hour, 2)\n\t\t\tl.buf = append(l.buf, ':')\n\t\t\titoa(&l.buf, min, 2)\n\t\t\tl.buf = append(l.buf, ':')\n\t\t\titoa(&l.buf, sec, 2)\n\t\t\tif l.flag&Lmicroseconds != 0 {\n\t\t\t\tl.buf = append(l.buf, '.')\n\t\t\t\titoa(&l.buf, t.Nanosecond()/1e3, 6)\n\t\t\t}\n\t\t\tl.buf = append(l.buf, ' ')\n\t\t}\n\t}\n\tif l.flag&(Lshortfile|Llongfile) != 0 {\n\t\tif l.flag&Lshortfile != 0 {\n\t\t\tshort := file\n\t\t\tfor i := len(file) - 1; i > 0; i-- {\n\t\t\t\tif file[i] == '/' {\n\t\t\t\t\tshort = file[i+1:]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tfile = short\n\t\t}\n\t\tl.buf = append(l.buf, file...)\n\t\tl.buf = append(l.buf, ':')\n\t\titoa(&l.buf, line, -1)\n\t\tl.buf = append(l.buf, \": \"...)\n\t}\n}\n\nfunc (l *Logger) output(calldepth int, now time.Time, s string) error {\n\tvar file string\n\tvar line int\n\tif l.flag&(Lshortfile|Llongfile) != 0 {\n\t\tl.mu.Unlock()\n\t\tvar ok bool\n\t\t_, file, line, ok = runtime.Caller(calldepth)\n\t\tif !ok {\n\t\t\tfile = \"???\"\n\t\t\tline = 0\n\t\t}\n\t\tl.mu.Lock()\n\t}\n\tl.buf = l.buf[:0]\n\tl.formatHeader(now, file, line)\n\tl.buf = append(l.buf, s...)\n\tif len(s) == 0 || s[len(s)-1] != '\\n' {\n\t\tl.buf = append(l.buf, '\\n')\n\t}\n\t_, err := l.out.Write(l.buf)\n\treturn err\n}\n\n// Output writes the string s with the header controlled by the flags to\n// the l.out writer. A newline will be appended if s doesn't end in a\n// newline. Calldepth is used to recover the PC, although all current\n// calls of Output use the call depth 2. Access to the function is serialized.\nfunc (l *Logger) Output(calldepth, noflag int, v ...interface{}) error {\n\tnow := time.Now()\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif l.flag&noflag != 0 {\n\t\treturn nil\n\t}\n\ts := fmt.Sprint(v...)\n\treturn l.output(calldepth+1, now, s)\n}\n\n// Outputf works like output but formats the output like Printf.\nfunc (l *Logger) Outputf(calldepth int, noflag int, format string, v ...interface{}) error {\n\tnow := time.Now()\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif l.flag&noflag != 0 {\n\t\treturn nil\n\t}\n\ts := fmt.Sprintf(format, v...)\n\treturn l.output(calldepth+1, now, s)\n}\n\n// Outputln works like output but formats the output like Println.\nfunc (l *Logger) Outputln(calldepth int, noflag int, v ...interface{}) error {\n\tnow := time.Now()\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tif l.flag&noflag != 0 {\n\t\treturn nil\n\t}\n\ts := fmt.Sprintln(v...)\n\treturn l.output(calldepth+1, now, s)\n}\n\n// Panic prints the message like Print and calls panic. The printing\n// might be suppressed by the flag Lnopanic.\nfunc (l *Logger) Panic(v ...interface{}) {\n\tl.Output(2, Lnopanic, v...)\n\ts := fmt.Sprint(v...)\n\tpanic(s)\n}\n\n// Panic prints the message like Print and calls panic. The printing\n// might be suppressed by the flag Lnopanic.\nfunc Panic(v ...interface{}) {\n\tstd.Output(2, Lnopanic, v...)\n\ts := fmt.Sprint(v...)\n\tpanic(s)\n}\n\n// Panicf prints the message like Printf and calls panic. The printing\n// might be suppressed by the flag Lnopanic.\nfunc (l *Logger) Panicf(format string, v ...interface{}) {\n\tl.Outputf(2, Lnopanic, format, v...)\n\ts := fmt.Sprintf(format, v...)\n\tpanic(s)\n}\n\n// Panicf prints the message like Printf and calls panic. The printing\n// might be suppressed by the flag Lnopanic.\nfunc Panicf(format string, v ...interface{}) {\n\tstd.Outputf(2, Lnopanic, format, v...)\n\ts := fmt.Sprintf(format, v...)\n\tpanic(s)\n}\n\n// Panicln prints the message like Println and calls panic. The printing\n// might be suppressed by the flag Lnopanic.\nfunc (l *Logger) Panicln(v ...interface{}) {\n\tl.Outputln(2, Lnopanic, v...)\n\ts := fmt.Sprintln(v...)\n\tpanic(s)\n}\n\n// Panicln prints the message like Println and calls panic. The printing\n// might be suppressed by the flag Lnopanic.\nfunc Panicln(v ...interface{}) {\n\tstd.Outputln(2, Lnopanic, v...)\n\ts := fmt.Sprintln(v...)\n\tpanic(s)\n}\n\n// Fatal prints the message like Print and calls os.Exit(1). The\n// printing might be suppressed by the flag Lnofatal.\nfunc (l *Logger) Fatal(v ...interface{}) {\n\tl.Output(2, Lnofatal, v...)\n\tos.Exit(1)\n}\n\n// Fatal prints the message like Print and calls os.Exit(1). The\n// printing might be suppressed by the flag Lnofatal.\nfunc Fatal(v ...interface{}) {\n\tstd.Output(2, Lnofatal, v...)\n\tos.Exit(1)\n}\n\n// Fatalf prints the message like Printf and calls os.Exit(1). The\n// printing might be suppressed by the flag Lnofatal.\nfunc (l *Logger) Fatalf(format string, v ...interface{}) {\n\tl.Outputf(2, Lnofatal, format, v...)\n\tos.Exit(1)\n}\n\n// Fatalf prints the message like Printf and calls os.Exit(1). The\n// printing might be suppressed by the flag Lnofatal.\nfunc Fatalf(format string, v ...interface{}) {\n\tstd.Outputf(2, Lnofatal, format, v...)\n\tos.Exit(1)\n}\n\n// Fatalln prints the message like Println and calls os.Exit(1). The\n// printing might be suppressed by the flag Lnofatal.\nfunc (l *Logger) Fatalln(format string, v ...interface{}) {\n\tl.Outputln(2, Lnofatal, v...)\n\tos.Exit(1)\n}\n\n// Fatalln prints the message like Println and calls os.Exit(1). The\n// printing might be suppressed by the flag Lnofatal.\nfunc Fatalln(format string, v ...interface{}) {\n\tstd.Outputln(2, Lnofatal, v...)\n\tos.Exit(1)\n}\n\n// Warn prints the message like Print. The printing might be suppressed\n// by the flag Lnowarn.\nfunc (l *Logger) Warn(v ...interface{}) {\n\tl.Output(2, Lnowarn, v...)\n}\n\n// Warn prints the message like Print. The printing might be suppressed\n// by the flag Lnowarn.\nfunc Warn(v ...interface{}) {\n\tstd.Output(2, Lnowarn, v...)\n}\n\n// Warnf prints the message like Printf. The printing might be suppressed\n// by the flag Lnowarn.\nfunc (l *Logger) Warnf(format string, v ...interface{}) {\n\tl.Outputf(2, Lnowarn, format, v...)\n}\n\n// Warnf prints the message like Printf. The printing might be suppressed\n// by the flag Lnowarn.\nfunc Warnf(format string, v ...interface{}) {\n\tstd.Outputf(2, Lnowarn, format, v...)\n}\n\n// Warnln prints the message like Println. The printing might be suppressed\n// by the flag Lnowarn.\nfunc (l *Logger) Warnln(v ...interface{}) {\n\tl.Outputln(2, Lnowarn, v...)\n}\n\n// Warnln prints the message like Println. The printing might be suppressed\n// by the flag Lnowarn.\nfunc Warnln(v ...interface{}) {\n\tstd.Outputln(2, Lnowarn, v...)\n}\n\n// Print prints the message like fmt.Print. The printing might be suppressed\n// by the flag Lnoprint.\nfunc (l *Logger) Print(v ...interface{}) {\n\tl.Output(2, Lnoprint, v...)\n}\n\n// Print prints the message like fmt.Print. The printing might be suppressed\n// by the flag Lnoprint.\nfunc Print(v ...interface{}) {\n\tstd.Output(2, Lnoprint, v...)\n}\n\n// Printf prints the message like fmt.Printf. The printing might be suppressed\n// by the flag Lnoprint.\nfunc (l *Logger) Printf(format string, v ...interface{}) {\n\tl.Outputf(2, Lnoprint, format, v...)\n}\n\n// Printf prints the message like fmt.Printf. The printing might be suppressed\n// by the flag Lnoprint.\nfunc Printf(format string, v ...interface{}) {\n\tstd.Outputf(2, Lnoprint, format, v...)\n}\n\n// Println prints the message like fmt.Println. The printing might be\n// suppressed by the flag Lnoprint.\nfunc (l *Logger) Println(v ...interface{}) {\n\tl.Outputln(2, Lnoprint, v...)\n}\n\n// Println prints the message like fmt.Println. The printing might be\n// suppressed by the flag Lnoprint.\nfunc Println(v ...interface{}) {\n\tstd.Outputln(2, Lnoprint, v...)\n}\n\n// Debug prints the message like Print. The printing might be suppressed\n// by the flag Lnodebug.\nfunc (l *Logger) Debug(v ...interface{}) {\n\tl.Output(2, Lnodebug, v...)\n}\n\n// Debug prints the message like Print. The printing might be suppressed\n// by the flag Lnodebug.\nfunc Debug(v ...interface{}) {\n\tstd.Output(2, Lnodebug, v...)\n}\n\n// Debugf prints the message like Printf. The printing might be suppressed\n// by the flag Lnodebug.\nfunc (l *Logger) Debugf(format string, v ...interface{}) {\n\tl.Outputf(2, Lnodebug, format, v...)\n}\n\n// Debugf prints the message like Printf. The printing might be suppressed\n// by the flag Lnodebug.\nfunc Debugf(format string, v ...interface{}) {\n\tstd.Outputf(2, Lnodebug, format, v...)\n}\n\n// Debugln prints the message like Println. The printing might be suppressed\n// by the flag Lnodebug.\nfunc (l *Logger) Debugln(v ...interface{}) {\n\tl.Outputln(2, Lnodebug, v...)\n}\n\n// Debugln prints the message like Println. The printing might be suppressed\n// by the flag Lnodebug.\nfunc Debugln(v ...interface{}) {\n\tstd.Outputln(2, Lnodebug, v...)\n}\n\n// Flags returns the current flags used by the logger.\nfunc (l *Logger) Flags() int {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\treturn l.flag\n}\n\n// Flags returns the current flags used by the standard logger.\nfunc Flags() int {\n\treturn std.Flags()\n}\n\n// SetFlags sets the flags of the logger.\nfunc (l *Logger) SetFlags(flag int) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tl.flag = flag\n}\n\n// SetFlags sets the flags for the standard logger.\nfunc SetFlags(flag int) {\n\tstd.SetFlags(flag)\n}\n\n// Prefix returns the prefix used by the logger.\nfunc (l *Logger) Prefix() string {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\treturn l.prefix\n}\n\n// Prefix returns the prefix used by the standard logger of the package.\nfunc Prefix() string {\n\treturn std.Prefix()\n}\n\n// SetPrefix sets the prefix for the logger.\nfunc (l *Logger) SetPrefix(prefix string) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tl.prefix = prefix\n}\n\n// SetPrefix sets the prefix of the standard logger of the package.\nfunc SetPrefix(prefix string) {\n\tstd.SetPrefix(prefix)\n}\n\n// SetOutput sets the output of the logger.\nfunc (l *Logger) SetOutput(w io.Writer) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tl.out = w\n}\n\n// SetOutput sets the output for the standard logger of the package.\nfunc SetOutput(w io.Writer) {\n\tstd.SetOutput(w)\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/bintree.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"unicode\"\n)\n\n// node represents a node in the binary tree.\ntype node struct {\n\t// x is the search value\n\tx uint32\n\t// p parent node\n\tp uint32\n\t// l left child\n\tl uint32\n\t// r right child\n\tr uint32\n}\n\n// wordLen is the number of bytes represented by the v field of a node.\nconst wordLen = 4\n\n// binTree supports the identification of the next operation based on a\n// binary tree.\n//\n// Nodes will be identified by their index into the ring buffer.\ntype binTree struct {\n\tdict *encoderDict\n\t// ring buffer of nodes\n\tnode []node\n\t// absolute offset of the entry for the next node. Position 4\n\t// byte larger.\n\thoff int64\n\t// front position in the node ring buffer\n\tfront uint32\n\t// index of the root node\n\troot uint32\n\t// current x value\n\tx uint32\n\t// preallocated array\n\tdata []byte\n}\n\n// null represents the nonexistent index. We can't use zero because it\n// would always exist or we would need to decrease the index for each\n// reference.\nconst null uint32 = 1<<32 - 1\n\n// newBinTree initializes the binTree structure. The capacity defines\n// the size of the buffer and defines the maximum distance for which\n// matches will be found.\nfunc newBinTree(capacity int) (t *binTree, err error) {\n\tif capacity < 1 {\n\t\treturn nil, errors.New(\n\t\t\t\"newBinTree: capacity must be larger than zero\")\n\t}\n\tif int64(capacity) >= int64(null) {\n\t\treturn nil, errors.New(\n\t\t\t\"newBinTree: capacity must less 2^{32}-1\")\n\t}\n\tt = &binTree{\n\t\tnode: make([]node, capacity),\n\t\thoff: -int64(wordLen),\n\t\troot: null,\n\t\tdata: make([]byte, maxMatchLen),\n\t}\n\treturn t, nil\n}\n\nfunc (t *binTree) SetDict(d *encoderDict) { t.dict = d }\n\n// WriteByte writes a single byte into the binary tree.\nfunc (t *binTree) WriteByte(c byte) error {\n\tt.x = (t.x << 8) | uint32(c)\n\tt.hoff++\n\tif t.hoff < 0 {\n\t\treturn nil\n\t}\n\tv := t.front\n\tif int64(v) < t.hoff {\n\t\t// We are overwriting old nodes stored in the tree.\n\t\tt.remove(v)\n\t}\n\tt.node[v].x = t.x\n\tt.add(v)\n\tt.front++\n\tif int64(t.front) >= int64(len(t.node)) {\n\t\tt.front = 0\n\t}\n\treturn nil\n}\n\n// Writes writes a sequence of bytes into the binTree structure.\nfunc (t *binTree) Write(p []byte) (n int, err error) {\n\tfor _, c := range p {\n\t\tt.WriteByte(c)\n\t}\n\treturn len(p), nil\n}\n\n// add puts the node v into the tree. The node must not be part of the\n// tree before.\nfunc (t *binTree) add(v uint32) {\n\tvn := &t.node[v]\n\t// Set left and right to null indices.\n\tvn.l, vn.r = null, null\n\t// If the binary tree is empty make v the root.\n\tif t.root == null {\n\t\tt.root = v\n\t\tvn.p = null\n\t\treturn\n\t}\n\tx := vn.x\n\tp := t.root\n\t// Search for the right leave link and add the new node.\n\tfor {\n\t\tpn := &t.node[p]\n\t\tif x <= pn.x {\n\t\t\tif pn.l == null {\n\t\t\t\tpn.l = v\n\t\t\t\tvn.p = p\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp = pn.l\n\t\t} else {\n\t\t\tif pn.r == null {\n\t\t\t\tpn.r = v\n\t\t\t\tvn.p = p\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp = pn.r\n\t\t}\n\t}\n}\n\n// parent returns the parent node index of v and the pointer to v value\n// in the parent.\nfunc (t *binTree) parent(v uint32) (p uint32, ptr *uint32) {\n\tif t.root == v {\n\t\treturn null, &t.root\n\t}\n\tp = t.node[v].p\n\tif t.node[p].l == v {\n\t\tptr = &t.node[p].l\n\t} else {\n\t\tptr = &t.node[p].r\n\t}\n\treturn\n}\n\n// Remove node v.\nfunc (t *binTree) remove(v uint32) {\n\tvn := &t.node[v]\n\tp, ptr := t.parent(v)\n\tl, r := vn.l, vn.r\n\tif l == null {\n\t\t// Move the right child up.\n\t\t*ptr = r\n\t\tif r != null {\n\t\t\tt.node[r].p = p\n\t\t}\n\t\treturn\n\t}\n\tif r == null {\n\t\t// Move the left child up.\n\t\t*ptr = l\n\t\tt.node[l].p = p\n\t\treturn\n\t}\n\n\t// Search the in-order predecessor u.\n\tun := &t.node[l]\n\tur := un.r\n\tif ur == null {\n\t\t// In order predecessor is l. Move it up.\n\t\tun.r = r\n\t\tt.node[r].p = l\n\t\tun.p = p\n\t\t*ptr = l\n\t\treturn\n\t}\n\tvar u uint32\n\tfor {\n\t\t// Look for the max value in the tree where l is root.\n\t\tu = ur\n\t\tur = t.node[u].r\n\t\tif ur == null {\n\t\t\tbreak\n\t\t}\n\t}\n\t// replace u with ul\n\tun = &t.node[u]\n\tul := un.l\n\tup := un.p\n\tt.node[up].r = ul\n\tif ul != null {\n\t\tt.node[ul].p = up\n\t}\n\n\t// replace v by u\n\tun.l, un.r = l, r\n\tt.node[l].p = u\n\tt.node[r].p = u\n\t*ptr = u\n\tun.p = p\n}\n\n// search looks for the node that have the value x or for the nodes that\n// brace it. The node highest in the tree with the value x will be\n// returned. All other nodes with the same value live in left subtree of\n// the returned node.\nfunc (t *binTree) search(v uint32, x uint32) (a, b uint32) {\n\ta, b = null, null\n\tif v == null {\n\t\treturn\n\t}\n\tfor {\n\t\tvn := &t.node[v]\n\t\tif x <= vn.x {\n\t\t\tif x == vn.x {\n\t\t\t\treturn v, v\n\t\t\t}\n\t\t\tb = v\n\t\t\tif vn.l == null {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tv = vn.l\n\t\t} else {\n\t\t\ta = v\n\t\t\tif vn.r == null {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tv = vn.r\n\t\t}\n\t}\n}\n\n// max returns the node with maximum value in the subtree with v as\n// root.\nfunc (t *binTree) max(v uint32) uint32 {\n\tif v == null {\n\t\treturn null\n\t}\n\tfor {\n\t\tr := t.node[v].r\n\t\tif r == null {\n\t\t\treturn v\n\t\t}\n\t\tv = r\n\t}\n}\n\n// min returns the node with the minimum value in the subtree with v as\n// root.\nfunc (t *binTree) min(v uint32) uint32 {\n\tif v == null {\n\t\treturn null\n\t}\n\tfor {\n\t\tl := t.node[v].l\n\t\tif l == null {\n\t\t\treturn v\n\t\t}\n\t\tv = l\n\t}\n}\n\n// pred returns the in-order predecessor of node v.\nfunc (t *binTree) pred(v uint32) uint32 {\n\tif v == null {\n\t\treturn null\n\t}\n\tu := t.max(t.node[v].l)\n\tif u != null {\n\t\treturn u\n\t}\n\tfor {\n\t\tp := t.node[v].p\n\t\tif p == null {\n\t\t\treturn null\n\t\t}\n\t\tif t.node[p].r == v {\n\t\t\treturn p\n\t\t}\n\t\tv = p\n\t}\n}\n\n// succ returns the in-order successor of node v.\nfunc (t *binTree) succ(v uint32) uint32 {\n\tif v == null {\n\t\treturn null\n\t}\n\tu := t.min(t.node[v].r)\n\tif u != null {\n\t\treturn u\n\t}\n\tfor {\n\t\tp := t.node[v].p\n\t\tif p == null {\n\t\t\treturn null\n\t\t}\n\t\tif t.node[p].l == v {\n\t\t\treturn p\n\t\t}\n\t\tv = p\n\t}\n}\n\n// xval converts the first four bytes of a into an 32-bit unsigned\n// integer in big-endian order.\nfunc xval(a []byte) uint32 {\n\tvar x uint32\n\tswitch len(a) {\n\tdefault:\n\t\tx |= uint32(a[3])\n\t\tfallthrough\n\tcase 3:\n\t\tx |= uint32(a[2]) << 8\n\t\tfallthrough\n\tcase 2:\n\t\tx |= uint32(a[1]) << 16\n\t\tfallthrough\n\tcase 1:\n\t\tx |= uint32(a[0]) << 24\n\tcase 0:\n\t}\n\treturn x\n}\n\n// dumpX converts value x into a four-letter string.\nfunc dumpX(x uint32) string {\n\ta := make([]byte, 4)\n\tfor i := 0; i < 4; i++ {\n\t\tc := byte(x >> uint((3-i)*8))\n\t\tif unicode.IsGraphic(rune(c)) {\n\t\t\ta[i] = c\n\t\t} else {\n\t\t\ta[i] = '.'\n\t\t}\n\t}\n\treturn string(a)\n}\n\n// dumpNode writes a representation of the node v into the io.Writer.\nfunc (t *binTree) dumpNode(w io.Writer, v uint32, indent int) {\n\tif v == null {\n\t\treturn\n\t}\n\n\tvn := &t.node[v]\n\n\tt.dumpNode(w, vn.r, indent+2)\n\n\tfor i := 0; i < indent; i++ {\n\t\tfmt.Fprint(w, \" \")\n\t}\n\tif vn.p == null {\n\t\tfmt.Fprintf(w, \"node %d %q parent null\\n\", v, dumpX(vn.x))\n\t} else {\n\t\tfmt.Fprintf(w, \"node %d %q parent %d\\n\", v, dumpX(vn.x), vn.p)\n\t}\n\n\tt.dumpNode(w, vn.l, indent+2)\n}\n\n// dump prints a representation of the binary tree into the writer.\nfunc (t *binTree) dump(w io.Writer) error {\n\tbw := bufio.NewWriter(w)\n\tt.dumpNode(bw, t.root, 0)\n\treturn bw.Flush()\n}\n\nfunc (t *binTree) distance(v uint32) int {\n\tdist := int(t.front) - int(v)\n\tif dist <= 0 {\n\t\tdist += len(t.node)\n\t}\n\treturn dist\n}\n\ntype matchParams struct {\n\trep [4]uint32\n\t// length when match will be accepted\n\tnAccept int\n\t// nodes to check\n\tcheck int\n\t// finish if length get shorter\n\tstopShorter bool\n}\n\nfunc (t *binTree) match(m match, distIter func() (int, bool), p matchParams,\n) (r match, checked int, accepted bool) {\n\tbuf := &t.dict.buf\n\tfor {\n\t\tif checked >= p.check {\n\t\t\treturn m, checked, true\n\t\t}\n\t\tdist, ok := distIter()\n\t\tif !ok {\n\t\t\treturn m, checked, false\n\t\t}\n\t\tchecked++\n\t\tif m.n > 0 {\n\t\t\ti := buf.rear - dist + m.n - 1\n\t\t\tif i < 0 {\n\t\t\t\ti += len(buf.data)\n\t\t\t} else if i >= len(buf.data) {\n\t\t\t\ti -= len(buf.data)\n\t\t\t}\n\t\t\tif buf.data[i] != t.data[m.n-1] {\n\t\t\t\tif p.stopShorter {\n\t\t\t\t\treturn m, checked, false\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tn := buf.matchLen(dist, t.data)\n\t\tswitch n {\n\t\tcase 0:\n\t\t\tif p.stopShorter {\n\t\t\t\treturn m, checked, false\n\t\t\t}\n\t\t\tcontinue\n\t\tcase 1:\n\t\t\tif uint32(dist-minDistance) != p.rep[0] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif n < m.n || (n == m.n && int64(dist) >= m.distance) {\n\t\t\tcontinue\n\t\t}\n\t\tm = match{int64(dist), n}\n\t\tif n >= p.nAccept {\n\t\t\treturn m, checked, true\n\t\t}\n\t}\n}\n\nfunc (t *binTree) NextOp(rep [4]uint32) operation {\n\t// retrieve maxMatchLen data\n\tn, _ := t.dict.buf.Peek(t.data[:maxMatchLen])\n\tif n == 0 {\n\t\tpanic(\"no data in buffer\")\n\t}\n\tt.data = t.data[:n]\n\n\tvar (\n\t\tm                  match\n\t\tx, u, v            uint32\n\t\titerPred, iterSucc func() (int, bool)\n\t)\n\tp := matchParams{\n\t\trep:     rep,\n\t\tnAccept: maxMatchLen,\n\t\tcheck:   32,\n\t}\n\ti := 4\n\titerSmall := func() (dist int, ok bool) {\n\t\ti--\n\t\tif i <= 0 {\n\t\t\treturn 0, false\n\t\t}\n\t\treturn i, true\n\t}\n\tm, checked, accepted := t.match(m, iterSmall, p)\n\tif accepted {\n\t\tgoto end\n\t}\n\tp.check -= checked\n\tx = xval(t.data)\n\tu, v = t.search(t.root, x)\n\tif u == v && len(t.data) == 4 {\n\t\titer := func() (dist int, ok bool) {\n\t\t\tif u == null {\n\t\t\t\treturn 0, false\n\t\t\t}\n\t\t\tdist = t.distance(u)\n\t\t\tu, v = t.search(t.node[u].l, x)\n\t\t\tif u != v {\n\t\t\t\tu = null\n\t\t\t}\n\t\t\treturn dist, true\n\t\t}\n\t\tm, _, _ = t.match(m, iter, p)\n\t\tgoto end\n\t}\n\tp.stopShorter = true\n\titerSucc = func() (dist int, ok bool) {\n\t\tif v == null {\n\t\t\treturn 0, false\n\t\t}\n\t\tdist = t.distance(v)\n\t\tv = t.succ(v)\n\t\treturn dist, true\n\t}\n\tm, checked, accepted = t.match(m, iterSucc, p)\n\tif accepted {\n\t\tgoto end\n\t}\n\tp.check -= checked\n\titerPred = func() (dist int, ok bool) {\n\t\tif u == null {\n\t\t\treturn 0, false\n\t\t}\n\t\tdist = t.distance(u)\n\t\tu = t.pred(u)\n\t\treturn dist, true\n\t}\n\tm, _, _ = t.match(m, iterPred, p)\nend:\n\tif m.n == 0 {\n\t\treturn lit{t.data[0]}\n\t}\n\treturn m\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/bitops.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\n/* Naming conventions follows the CodeReviewComments in the Go Wiki. */\n\n// ntz32Const is used by the functions NTZ and NLZ.\nconst ntz32Const = 0x04d7651f\n\n// ntz32Table is a helper table for de Bruijn algorithm by Danny Dubé.\n// See Henry S. Warren, Jr. \"Hacker's Delight\" section 5-1 figure 5-26.\nvar ntz32Table = [32]int8{\n\t0, 1, 2, 24, 3, 19, 6, 25,\n\t22, 4, 20, 10, 16, 7, 12, 26,\n\t31, 23, 18, 5, 21, 9, 15, 11,\n\t30, 17, 8, 14, 29, 13, 28, 27,\n}\n\n// ntz32 computes the number of trailing zeros for an unsigned 32-bit integer.\nfunc ntz32(x uint32) int {\n\tif x == 0 {\n\t\treturn 32\n\t}\n\tx = (x & -x) * ntz32Const\n\treturn int(ntz32Table[x>>27])\n}\n\n// nlz32 computes the number of leading zeros for an unsigned 32-bit integer.\nfunc nlz32(x uint32) int {\n\t// Smear left most bit to the right\n\tx |= x >> 1\n\tx |= x >> 2\n\tx |= x >> 4\n\tx |= x >> 8\n\tx |= x >> 16\n\t// Use ntz mechanism to calculate nlz.\n\tx++\n\tif x == 0 {\n\t\treturn 0\n\t}\n\tx *= ntz32Const\n\treturn 32 - int(ntz32Table[x>>27])\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/breader.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\n// breader provides the ReadByte function for a Reader. It doesn't read\n// more data from the reader than absolutely necessary.\ntype breader struct {\n\tio.Reader\n\t// helper slice to save allocations\n\tp []byte\n}\n\n// ByteReader converts an io.Reader into an io.ByteReader.\nfunc ByteReader(r io.Reader) io.ByteReader {\n\tbr, ok := r.(io.ByteReader)\n\tif !ok {\n\t\treturn &breader{r, make([]byte, 1)}\n\t}\n\treturn br\n}\n\n// ReadByte read byte function.\nfunc (r *breader) ReadByte() (c byte, err error) {\n\tn, err := r.Reader.Read(r.p)\n\tif n < 1 {\n\t\tif err == nil {\n\t\t\terr = errors.New(\"breader.ReadByte: no data\")\n\t\t}\n\t\treturn 0, err\n\t}\n\treturn r.p[0], nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/buffer.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n)\n\n// buffer provides a circular buffer of bytes. If the front index equals\n// the rear index the buffer is empty. As a consequence front cannot be\n// equal rear for a full buffer. So a full buffer has a length that is\n// one byte less the the length of the data slice.\ntype buffer struct {\n\tdata  []byte\n\tfront int\n\trear  int\n}\n\n// newBuffer creates a buffer with the given size.\nfunc newBuffer(size int) *buffer {\n\treturn &buffer{data: make([]byte, size+1)}\n}\n\n// Cap returns the capacity of the buffer.\nfunc (b *buffer) Cap() int {\n\treturn len(b.data) - 1\n}\n\n// Resets the buffer. The front and rear index are set to zero.\nfunc (b *buffer) Reset() {\n\tb.front = 0\n\tb.rear = 0\n}\n\n// Buffered returns the number of bytes buffered.\nfunc (b *buffer) Buffered() int {\n\tdelta := b.front - b.rear\n\tif delta < 0 {\n\t\tdelta += len(b.data)\n\t}\n\treturn delta\n}\n\n// Available returns the number of bytes available for writing.\nfunc (b *buffer) Available() int {\n\tdelta := b.rear - 1 - b.front\n\tif delta < 0 {\n\t\tdelta += len(b.data)\n\t}\n\treturn delta\n}\n\n// addIndex adds a non-negative integer to the index i and returns the\n// resulting index. The function takes care of wrapping the index as\n// well as potential overflow situations.\nfunc (b *buffer) addIndex(i int, n int) int {\n\t// subtraction of len(b.data) prevents overflow\n\ti += n - len(b.data)\n\tif i < 0 {\n\t\ti += len(b.data)\n\t}\n\treturn i\n}\n\n// Read reads bytes from the buffer into p and returns the number of\n// bytes read. The function never returns an error but might return less\n// data than requested.\nfunc (b *buffer) Read(p []byte) (n int, err error) {\n\tn, err = b.Peek(p)\n\tb.rear = b.addIndex(b.rear, n)\n\treturn n, err\n}\n\n// Peek reads bytes from the buffer into p without changing the buffer.\n// Peek will never return an error but might return less data than\n// requested.\nfunc (b *buffer) Peek(p []byte) (n int, err error) {\n\tm := b.Buffered()\n\tn = len(p)\n\tif m < n {\n\t\tn = m\n\t\tp = p[:n]\n\t}\n\tk := copy(p, b.data[b.rear:])\n\tif k < n {\n\t\tcopy(p[k:], b.data)\n\t}\n\treturn n, nil\n}\n\n// Discard skips the n next bytes to read from the buffer, returning the\n// bytes discarded.\n//\n// If Discards skips fewer than n bytes, it returns an error.\nfunc (b *buffer) Discard(n int) (discarded int, err error) {\n\tif n < 0 {\n\t\treturn 0, errors.New(\"buffer.Discard: negative argument\")\n\t}\n\tm := b.Buffered()\n\tif m < n {\n\t\tn = m\n\t\terr = errors.New(\n\t\t\t\"buffer.Discard: discarded less bytes then requested\")\n\t}\n\tb.rear = b.addIndex(b.rear, n)\n\treturn n, err\n}\n\n// ErrNoSpace indicates that there is insufficient space for the Write\n// operation.\nvar ErrNoSpace = errors.New(\"insufficient space\")\n\n// Write puts data into the  buffer. If less bytes are written than\n// requested ErrNoSpace is returned.\nfunc (b *buffer) Write(p []byte) (n int, err error) {\n\tm := b.Available()\n\tn = len(p)\n\tif m < n {\n\t\tn = m\n\t\tp = p[:m]\n\t\terr = ErrNoSpace\n\t}\n\tk := copy(b.data[b.front:], p)\n\tif k < n {\n\t\tcopy(b.data, p[k:])\n\t}\n\tb.front = b.addIndex(b.front, n)\n\treturn n, err\n}\n\n// WriteByte writes a single byte into the buffer. The error ErrNoSpace\n// is returned if no single byte is available in the buffer for writing.\nfunc (b *buffer) WriteByte(c byte) error {\n\tif b.Available() < 1 {\n\t\treturn ErrNoSpace\n\t}\n\tb.data[b.front] = c\n\tb.front = b.addIndex(b.front, 1)\n\treturn nil\n}\n\n// prefixLen returns the length of the common prefix of a and b.\nfunc prefixLen(a, b []byte) int {\n\tif len(a) > len(b) {\n\t\ta, b = b, a\n\t}\n\tfor i, c := range a {\n\t\tif b[i] != c {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn len(a)\n}\n\n// matchLen returns the length of the common prefix for the given\n// distance from the rear and the byte slice p.\nfunc (b *buffer) matchLen(distance int, p []byte) int {\n\tvar n int\n\ti := b.rear - distance\n\tif i < 0 {\n\t\tif n = prefixLen(p, b.data[len(b.data)+i:]); n < -i {\n\t\t\treturn n\n\t\t}\n\t\tp = p[n:]\n\t\ti = 0\n\t}\n\tn += prefixLen(p, b.data[i:])\n\treturn n\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/bytewriter.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\n// ErrLimit indicates that the limit of the LimitedByteWriter has been\n// reached.\nvar ErrLimit = errors.New(\"limit reached\")\n\n// LimitedByteWriter provides a byte writer that can be written until a\n// limit is reached. The field N provides the number of remaining\n// bytes.\ntype LimitedByteWriter struct {\n\tBW io.ByteWriter\n\tN  int64\n}\n\n// WriteByte writes a single byte to the limited byte writer. It returns\n// ErrLimit if the limit has been reached. If the byte is successfully\n// written the field N of the LimitedByteWriter will be decremented by\n// one.\nfunc (l *LimitedByteWriter) WriteByte(c byte) error {\n\tif l.N <= 0 {\n\t\treturn ErrLimit\n\t}\n\tif err := l.BW.WriteByte(c); err != nil {\n\t\treturn err\n\t}\n\tl.N--\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/decoder.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// decoder decodes a raw LZMA stream without any header.\ntype decoder struct {\n\t// dictionary; the rear pointer of the buffer will be used for\n\t// reading the data.\n\tDict *decoderDict\n\t// decoder state\n\tState *state\n\t// range decoder\n\trd *rangeDecoder\n\t// start stores the head value of the dictionary for the LZMA\n\t// stream\n\tstart int64\n\t// size of uncompressed data\n\tsize int64\n\t// end-of-stream encountered\n\teos bool\n\t// EOS marker found\n\teosMarker bool\n}\n\n// newDecoder creates a new decoder instance. The parameter size provides\n// the expected byte size of the decompressed data. If the size is\n// unknown use a negative value. In that case the decoder will look for\n// a terminating end-of-stream marker.\nfunc newDecoder(br io.ByteReader, state *state, dict *decoderDict, size int64) (d *decoder, err error) {\n\trd, err := newRangeDecoder(br)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\td = &decoder{\n\t\tState: state,\n\t\tDict:  dict,\n\t\trd:    rd,\n\t\tsize:  size,\n\t\tstart: dict.pos(),\n\t}\n\treturn d, nil\n}\n\n// Reopen restarts the decoder with a new byte reader and a new size. Reopen\n// resets the Decompressed counter to zero.\nfunc (d *decoder) Reopen(br io.ByteReader, size int64) error {\n\tvar err error\n\tif d.rd, err = newRangeDecoder(br); err != nil {\n\t\treturn err\n\t}\n\td.start = d.Dict.pos()\n\td.size = size\n\td.eos = false\n\treturn nil\n}\n\n// decodeLiteral decodes a single literal from the LZMA stream.\nfunc (d *decoder) decodeLiteral() (op operation, err error) {\n\tlitState := d.State.litState(d.Dict.byteAt(1), d.Dict.head)\n\tmatch := d.Dict.byteAt(int(d.State.rep[0]) + 1)\n\ts, err := d.State.litCodec.Decode(d.rd, d.State.state, match, litState)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn lit{s}, nil\n}\n\n// errEOS indicates that an EOS marker has been found.\nvar errEOS = errors.New(\"EOS marker found\")\n\n// readOp decodes the next operation from the compressed stream. It\n// returns the operation. If an explicit end of stream marker is\n// identified the eos error is returned.\nfunc (d *decoder) readOp() (op operation, err error) {\n\t// Value of the end of stream (EOS) marker\n\tconst eosDist = 1<<32 - 1\n\n\tstate, state2, posState := d.State.states(d.Dict.head)\n\n\tb, err := d.State.isMatch[state2].Decode(d.rd)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif b == 0 {\n\t\t// literal\n\t\top, err := d.decodeLiteral()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\td.State.updateStateLiteral()\n\t\treturn op, nil\n\t}\n\tb, err = d.State.isRep[state].Decode(d.rd)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif b == 0 {\n\t\t// simple match\n\t\td.State.rep[3], d.State.rep[2], d.State.rep[1] =\n\t\t\td.State.rep[2], d.State.rep[1], d.State.rep[0]\n\n\t\td.State.updateStateMatch()\n\t\t// The length decoder returns the length offset.\n\t\tn, err := d.State.lenCodec.Decode(d.rd, posState)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// The dist decoder returns the distance offset. The actual\n\t\t// distance is 1 higher.\n\t\td.State.rep[0], err = d.State.distCodec.Decode(d.rd, n)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif d.State.rep[0] == eosDist {\n\t\t\td.eosMarker = true\n\t\t\treturn nil, errEOS\n\t\t}\n\t\top = match{n: int(n) + minMatchLen,\n\t\t\tdistance: int64(d.State.rep[0]) + minDistance}\n\t\treturn op, nil\n\t}\n\tb, err = d.State.isRepG0[state].Decode(d.rd)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdist := d.State.rep[0]\n\tif b == 0 {\n\t\t// rep match 0\n\t\tb, err = d.State.isRepG0Long[state2].Decode(d.rd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif b == 0 {\n\t\t\td.State.updateStateShortRep()\n\t\t\top = match{n: 1, distance: int64(dist) + minDistance}\n\t\t\treturn op, nil\n\t\t}\n\t} else {\n\t\tb, err = d.State.isRepG1[state].Decode(d.rd)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif b == 0 {\n\t\t\tdist = d.State.rep[1]\n\t\t} else {\n\t\t\tb, err = d.State.isRepG2[state].Decode(d.rd)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif b == 0 {\n\t\t\t\tdist = d.State.rep[2]\n\t\t\t} else {\n\t\t\t\tdist = d.State.rep[3]\n\t\t\t\td.State.rep[3] = d.State.rep[2]\n\t\t\t}\n\t\t\td.State.rep[2] = d.State.rep[1]\n\t\t}\n\t\td.State.rep[1] = d.State.rep[0]\n\t\td.State.rep[0] = dist\n\t}\n\tn, err := d.State.repLenCodec.Decode(d.rd, posState)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\td.State.updateStateRep()\n\top = match{n: int(n) + minMatchLen, distance: int64(dist) + minDistance}\n\treturn op, nil\n}\n\n// apply takes the operation and transforms the decoder dictionary accordingly.\nfunc (d *decoder) apply(op operation) error {\n\tvar err error\n\tswitch x := op.(type) {\n\tcase match:\n\t\terr = d.Dict.writeMatch(x.distance, x.n)\n\tcase lit:\n\t\terr = d.Dict.WriteByte(x.b)\n\tdefault:\n\t\tpanic(\"op is neither a match nor a literal\")\n\t}\n\treturn err\n}\n\n// decompress fills the dictionary unless no space for new data is\n// available. If the end of the LZMA stream has been reached io.EOF will\n// be returned.\nfunc (d *decoder) decompress() error {\n\tif d.eos {\n\t\treturn io.EOF\n\t}\n\tfor d.Dict.Available() >= maxMatchLen {\n\t\top, err := d.readOp()\n\t\tswitch err {\n\t\tcase nil:\n\t\t\tbreak\n\t\tcase errEOS:\n\t\t\td.eos = true\n\t\t\tif !d.rd.possiblyAtEnd() {\n\t\t\t\treturn errDataAfterEOS\n\t\t\t}\n\t\t\tif d.size >= 0 && d.size != d.Decompressed() {\n\t\t\t\treturn errSize\n\t\t\t}\n\t\t\treturn io.EOF\n\t\tcase io.EOF:\n\t\t\td.eos = true\n\t\t\treturn io.ErrUnexpectedEOF\n\t\tdefault:\n\t\t\treturn err\n\t\t}\n\t\tif err = d.apply(op); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif d.size >= 0 && d.Decompressed() >= d.size {\n\t\t\td.eos = true\n\t\t\tif d.Decompressed() > d.size {\n\t\t\t\treturn errSize\n\t\t\t}\n\t\t\tif !d.rd.possiblyAtEnd() {\n\t\t\t\tswitch _, err = d.readOp(); err {\n\t\t\t\tcase nil:\n\t\t\t\t\treturn errSize\n\t\t\t\tcase io.EOF:\n\t\t\t\t\treturn io.ErrUnexpectedEOF\n\t\t\t\tcase errEOS:\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn io.EOF\n\t\t}\n\t}\n\treturn nil\n}\n\n// Errors that may be returned while decoding data.\nvar (\n\terrDataAfterEOS = errors.New(\"lzma: data after end of stream marker\")\n\terrSize         = errors.New(\"lzma: wrong uncompressed data size\")\n)\n\n// Read reads data from the buffer. If no more data is available io.EOF is\n// returned.\nfunc (d *decoder) Read(p []byte) (n int, err error) {\n\tvar k int\n\tfor {\n\t\t// Read of decoder dict never returns an error.\n\t\tk, err = d.Dict.Read(p[n:])\n\t\tif err != nil {\n\t\t\tpanic(fmt.Errorf(\"dictionary read error %s\", err))\n\t\t}\n\t\tif k == 0 && d.eos {\n\t\t\treturn n, io.EOF\n\t\t}\n\t\tn += k\n\t\tif n >= len(p) {\n\t\t\treturn n, nil\n\t\t}\n\t\tif err = d.decompress(); err != nil && err != io.EOF {\n\t\t\treturn n, err\n\t\t}\n\t}\n}\n\n// Decompressed returns the number of bytes decompressed by the decoder.\nfunc (d *decoder) Decompressed() int64 {\n\treturn d.Dict.pos() - d.start\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/decoderdict.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// decoderDict provides the dictionary for the decoder. The whole\n// dictionary is used as reader buffer.\ntype decoderDict struct {\n\tbuf  buffer\n\thead int64\n}\n\n// newDecoderDict creates a new decoder dictionary. The whole dictionary\n// will be used as reader buffer.\nfunc newDecoderDict(dictCap int) (d *decoderDict, err error) {\n\t// lower limit supports easy test cases\n\tif !(1 <= dictCap && int64(dictCap) <= MaxDictCap) {\n\t\treturn nil, errors.New(\"lzma: dictCap out of range\")\n\t}\n\td = &decoderDict{buf: *newBuffer(dictCap)}\n\treturn d, nil\n}\n\n// Reset clears the dictionary. The read buffer is not changed, so the\n// buffered data can still be read.\nfunc (d *decoderDict) Reset() {\n\td.head = 0\n}\n\n// WriteByte writes a single byte into the dictionary. It is used to\n// write literals into the dictionary.\nfunc (d *decoderDict) WriteByte(c byte) error {\n\tif err := d.buf.WriteByte(c); err != nil {\n\t\treturn err\n\t}\n\td.head++\n\treturn nil\n}\n\n// pos returns the position of the dictionary head.\nfunc (d *decoderDict) pos() int64 { return d.head }\n\n// dictLen returns the actual length of the dictionary.\nfunc (d *decoderDict) dictLen() int {\n\tcapacity := d.buf.Cap()\n\tif d.head >= int64(capacity) {\n\t\treturn capacity\n\t}\n\treturn int(d.head)\n}\n\n// byteAt returns a byte stored in the dictionary. If the distance is\n// non-positive or exceeds the current length of the dictionary the zero\n// byte is returned.\nfunc (d *decoderDict) byteAt(dist int) byte {\n\tif !(0 < dist && dist <= d.dictLen()) {\n\t\treturn 0\n\t}\n\ti := d.buf.front - dist\n\tif i < 0 {\n\t\ti += len(d.buf.data)\n\t}\n\treturn d.buf.data[i]\n}\n\n// writeMatch writes the match at the top of the dictionary. The given\n// distance must point in the current dictionary and the length must not\n// exceed the maximum length 273 supported in LZMA.\n//\n// The error value ErrNoSpace indicates that no space is available in\n// the dictionary for writing. You need to read from the dictionary\n// first.\nfunc (d *decoderDict) writeMatch(dist int64, length int) error {\n\tif !(0 < dist && dist <= int64(d.dictLen())) {\n\t\treturn errors.New(\"writeMatch: distance out of range\")\n\t}\n\tif !(0 < length && length <= maxMatchLen) {\n\t\treturn errors.New(\"writeMatch: length out of range\")\n\t}\n\tif length > d.buf.Available() {\n\t\treturn ErrNoSpace\n\t}\n\td.head += int64(length)\n\n\ti := d.buf.front - int(dist)\n\tif i < 0 {\n\t\ti += len(d.buf.data)\n\t}\n\tfor length > 0 {\n\t\tvar p []byte\n\t\tif i >= d.buf.front {\n\t\t\tp = d.buf.data[i:]\n\t\t\ti = 0\n\t\t} else {\n\t\t\tp = d.buf.data[i:d.buf.front]\n\t\t\ti = d.buf.front\n\t\t}\n\t\tif len(p) > length {\n\t\t\tp = p[:length]\n\t\t}\n\t\tif _, err := d.buf.Write(p); err != nil {\n\t\t\tpanic(fmt.Errorf(\"d.buf.Write returned error %s\", err))\n\t\t}\n\t\tlength -= len(p)\n\t}\n\treturn nil\n}\n\n// Write writes the given bytes into the dictionary and advances the\n// head.\nfunc (d *decoderDict) Write(p []byte) (n int, err error) {\n\tn, err = d.buf.Write(p)\n\td.head += int64(n)\n\treturn n, err\n}\n\n// Available returns the number of available bytes for writing into the\n// decoder dictionary.\nfunc (d *decoderDict) Available() int { return d.buf.Available() }\n\n// Read reads data from the buffer contained in the decoder dictionary.\nfunc (d *decoderDict) Read(p []byte) (n int, err error) { return d.buf.Read(p) }\n\n// Buffered returns the number of bytes currently buffered in the\n// decoder dictionary.\nfunc (d *decoderDict) buffered() int { return d.buf.Buffered() }\n\n// Peek gets data from the buffer without advancing the rear index.\nfunc (d *decoderDict) peek(p []byte) (n int, err error) { return d.buf.Peek(p) }\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/directcodec.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport \"fmt\"\n\n// directCodec allows the encoding and decoding of values with a fixed number\n// of bits. The number of bits must be in the range [1,32].\ntype directCodec byte\n\n// makeDirectCodec creates a directCodec. The function panics if the number of\n// bits is not in the range [1,32].\nfunc makeDirectCodec(bits int) directCodec {\n\tif !(1 <= bits && bits <= 32) {\n\t\tpanic(fmt.Errorf(\"bits=%d out of range\", bits))\n\t}\n\treturn directCodec(bits)\n}\n\n// Bits returns the number of bits supported by this codec.\nfunc (dc directCodec) Bits() int {\n\treturn int(dc)\n}\n\n// Encode uses the range encoder to encode a value with the fixed number of\n// bits. The most-significant bit is encoded first.\nfunc (dc directCodec) Encode(e *rangeEncoder, v uint32) error {\n\tfor i := int(dc) - 1; i >= 0; i-- {\n\t\tif err := e.DirectEncodeBit(v >> uint(i)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Decode uses the range decoder to decode a value with the given number of\n// given bits. The most-significant bit is decoded first.\nfunc (dc directCodec) Decode(d *rangeDecoder) (v uint32, err error) {\n\tfor i := int(dc) - 1; i >= 0; i-- {\n\t\tx, err := d.DirectDecodeBit()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv = (v << 1) | x\n\t}\n\treturn v, nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/distcodec.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\n// Constants used by the distance codec.\nconst (\n\t// minimum supported distance\n\tminDistance = 1\n\t// maximum supported distance, value is used for the eos marker.\n\tmaxDistance = 1 << 32\n\t// number of the supported len states\n\tlenStates = 4\n\t// start for the position models\n\tstartPosModel = 4\n\t// first index with align bits support\n\tendPosModel = 14\n\t// bits for the position slots\n\tposSlotBits = 6\n\t// number of align bits\n\talignBits = 4\n\t// maximum position slot\n\tmaxPosSlot = 63\n)\n\n// distCodec provides encoding and decoding of distance values.\ntype distCodec struct {\n\tposSlotCodecs [lenStates]treeCodec\n\tposModel      [endPosModel - startPosModel]treeReverseCodec\n\talignCodec    treeReverseCodec\n}\n\n// deepcopy initializes dc as deep copy of the source.\nfunc (dc *distCodec) deepcopy(src *distCodec) {\n\tif dc == src {\n\t\treturn\n\t}\n\tfor i := range dc.posSlotCodecs {\n\t\tdc.posSlotCodecs[i].deepcopy(&src.posSlotCodecs[i])\n\t}\n\tfor i := range dc.posModel {\n\t\tdc.posModel[i].deepcopy(&src.posModel[i])\n\t}\n\tdc.alignCodec.deepcopy(&src.alignCodec)\n}\n\n// distBits returns the number of bits required to encode dist.\nfunc distBits(dist uint32) int {\n\tif dist < startPosModel {\n\t\treturn 6\n\t}\n\t// slot s > 3, dist d\n\t// s = 2(bits(d)-1) + bit(d, bits(d)-2)\n\t// s>>1 = bits(d)-1\n\t// bits(d) = 32-nlz32(d)\n\t// s>>1=31-nlz32(d)\n\t// n = 5 + (s>>1) = 36 - nlz32(d)\n\treturn 36 - nlz32(dist)\n}\n\n// newDistCodec creates a new distance codec.\nfunc (dc *distCodec) init() {\n\tfor i := range dc.posSlotCodecs {\n\t\tdc.posSlotCodecs[i] = makeTreeCodec(posSlotBits)\n\t}\n\tfor i := range dc.posModel {\n\t\tposSlot := startPosModel + i\n\t\tbits := (posSlot >> 1) - 1\n\t\tdc.posModel[i] = makeTreeReverseCodec(bits)\n\t}\n\tdc.alignCodec = makeTreeReverseCodec(alignBits)\n}\n\n// lenState converts the value l to a supported lenState value.\nfunc lenState(l uint32) uint32 {\n\tif l >= lenStates {\n\t\tl = lenStates - 1\n\t}\n\treturn l\n}\n\n// Encode encodes the distance using the parameter l. Dist can have values from\n// the full range of uint32 values. To get the distance offset the actual match\n// distance has to be decreased by 1. A distance offset of 0xffffffff (eos)\n// indicates the end of the stream.\nfunc (dc *distCodec) Encode(e *rangeEncoder, dist uint32, l uint32) (err error) {\n\t// Compute the posSlot using nlz32\n\tvar posSlot uint32\n\tvar bits uint32\n\tif dist < startPosModel {\n\t\tposSlot = dist\n\t} else {\n\t\tbits = uint32(30 - nlz32(dist))\n\t\tposSlot = startPosModel - 2 + (bits << 1)\n\t\tposSlot += (dist >> uint(bits)) & 1\n\t}\n\n\tif err = dc.posSlotCodecs[lenState(l)].Encode(e, posSlot); err != nil {\n\t\treturn\n\t}\n\n\tswitch {\n\tcase posSlot < startPosModel:\n\t\treturn nil\n\tcase posSlot < endPosModel:\n\t\ttc := &dc.posModel[posSlot-startPosModel]\n\t\treturn tc.Encode(dist, e)\n\t}\n\tdic := directCodec(bits - alignBits)\n\tif err = dic.Encode(e, dist>>alignBits); err != nil {\n\t\treturn\n\t}\n\treturn dc.alignCodec.Encode(dist, e)\n}\n\n// Decode decodes the distance offset using the parameter l. The dist value\n// 0xffffffff (eos) indicates the end of the stream. Add one to the distance\n// offset to get the actual match distance.\nfunc (dc *distCodec) Decode(d *rangeDecoder, l uint32) (dist uint32, err error) {\n\tposSlot, err := dc.posSlotCodecs[lenState(l)].Decode(d)\n\tif err != nil {\n\t\treturn\n\t}\n\n\t// posSlot equals distance\n\tif posSlot < startPosModel {\n\t\treturn posSlot, nil\n\t}\n\n\t// posSlot uses the individual models\n\tbits := (posSlot >> 1) - 1\n\tdist = (2 | (posSlot & 1)) << bits\n\tvar u uint32\n\tif posSlot < endPosModel {\n\t\ttc := &dc.posModel[posSlot-startPosModel]\n\t\tif u, err = tc.Decode(d); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tdist += u\n\t\treturn dist, nil\n\t}\n\n\t// posSlots use direct encoding and a single model for the four align\n\t// bits.\n\tdic := directCodec(bits - alignBits)\n\tif u, err = dic.Decode(d); err != nil {\n\t\treturn 0, err\n\t}\n\tdist += u << alignBits\n\tif u, err = dc.alignCodec.Decode(d); err != nil {\n\t\treturn 0, err\n\t}\n\tdist += u\n\treturn dist, nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/encoder.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// opLenMargin provides the upper limit of the number of bytes required\n// to encode a single operation.\nconst opLenMargin = 16\n\n// compressFlags control the compression process.\ntype compressFlags uint32\n\n// Values for compressFlags.\nconst (\n\t// all data should be compressed, even if compression is not\n\t// optimal.\n\tall compressFlags = 1 << iota\n)\n\n// encoderFlags provide the flags for an encoder.\ntype encoderFlags uint32\n\n// Flags for the encoder.\nconst (\n\t// eosMarker requests an EOS marker to be written.\n\teosMarker encoderFlags = 1 << iota\n)\n\n// Encoder compresses data buffered in the encoder dictionary and writes\n// it into a byte writer.\ntype encoder struct {\n\tdict  *encoderDict\n\tstate *state\n\tre    *rangeEncoder\n\tstart int64\n\t// generate eos marker\n\tmarker bool\n\tlimit  bool\n\tmargin int\n}\n\n// newEncoder creates a new encoder. If the byte writer must be\n// limited use LimitedByteWriter provided by this package. The flags\n// argument supports the eosMarker flag, controlling whether a\n// terminating end-of-stream marker must be written.\nfunc newEncoder(bw io.ByteWriter, state *state, dict *encoderDict,\n\tflags encoderFlags) (e *encoder, err error) {\n\n\tre, err := newRangeEncoder(bw)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\te = &encoder{\n\t\tdict:   dict,\n\t\tstate:  state,\n\t\tre:     re,\n\t\tmarker: flags&eosMarker != 0,\n\t\tstart:  dict.Pos(),\n\t\tmargin: opLenMargin,\n\t}\n\tif e.marker {\n\t\te.margin += 5\n\t}\n\treturn e, nil\n}\n\n// Write writes the bytes from p into the dictionary. If not enough\n// space is available the data in the dictionary buffer will be\n// compressed to make additional space available. If the limit of the\n// underlying writer has been reached ErrLimit will be returned.\nfunc (e *encoder) Write(p []byte) (n int, err error) {\n\tfor {\n\t\tk, err := e.dict.Write(p[n:])\n\t\tn += k\n\t\tif err == ErrNoSpace {\n\t\t\tif err = e.compress(0); err != nil {\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\treturn n, err\n\t}\n}\n\n// Reopen reopens the encoder with a new byte writer.\nfunc (e *encoder) Reopen(bw io.ByteWriter) error {\n\tvar err error\n\tif e.re, err = newRangeEncoder(bw); err != nil {\n\t\treturn err\n\t}\n\te.start = e.dict.Pos()\n\te.limit = false\n\treturn nil\n}\n\n// writeLiteral writes a literal into the LZMA stream\nfunc (e *encoder) writeLiteral(l lit) error {\n\tvar err error\n\tstate, state2, _ := e.state.states(e.dict.Pos())\n\tif err = e.state.isMatch[state2].Encode(e.re, 0); err != nil {\n\t\treturn err\n\t}\n\tlitState := e.state.litState(e.dict.ByteAt(1), e.dict.Pos())\n\tmatch := e.dict.ByteAt(int(e.state.rep[0]) + 1)\n\terr = e.state.litCodec.Encode(e.re, l.b, state, match, litState)\n\tif err != nil {\n\t\treturn err\n\t}\n\te.state.updateStateLiteral()\n\treturn nil\n}\n\n// iverson implements the Iverson operator as proposed by Donald Knuth in his\n// book Concrete Mathematics.\nfunc iverson(ok bool) uint32 {\n\tif ok {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\n// writeMatch writes a repetition operation into the operation stream\nfunc (e *encoder) writeMatch(m match) error {\n\tvar err error\n\tif !(minDistance <= m.distance && m.distance <= maxDistance) {\n\t\tpanic(fmt.Errorf(\"match distance %d out of range\", m.distance))\n\t}\n\tdist := uint32(m.distance - minDistance)\n\tif !(minMatchLen <= m.n && m.n <= maxMatchLen) &&\n\t\t!(dist == e.state.rep[0] && m.n == 1) {\n\t\tpanic(fmt.Errorf(\n\t\t\t\"match length %d out of range; dist %d rep[0] %d\",\n\t\t\tm.n, dist, e.state.rep[0]))\n\t}\n\tstate, state2, posState := e.state.states(e.dict.Pos())\n\tif err = e.state.isMatch[state2].Encode(e.re, 1); err != nil {\n\t\treturn err\n\t}\n\tg := 0\n\tfor ; g < 4; g++ {\n\t\tif e.state.rep[g] == dist {\n\t\t\tbreak\n\t\t}\n\t}\n\tb := iverson(g < 4)\n\tif err = e.state.isRep[state].Encode(e.re, b); err != nil {\n\t\treturn err\n\t}\n\tn := uint32(m.n - minMatchLen)\n\tif b == 0 {\n\t\t// simple match\n\t\te.state.rep[3], e.state.rep[2], e.state.rep[1], e.state.rep[0] =\n\t\t\te.state.rep[2], e.state.rep[1], e.state.rep[0], dist\n\t\te.state.updateStateMatch()\n\t\tif err = e.state.lenCodec.Encode(e.re, n, posState); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn e.state.distCodec.Encode(e.re, dist, n)\n\t}\n\tb = iverson(g != 0)\n\tif err = e.state.isRepG0[state].Encode(e.re, b); err != nil {\n\t\treturn err\n\t}\n\tif b == 0 {\n\t\t// g == 0\n\t\tb = iverson(m.n != 1)\n\t\tif err = e.state.isRepG0Long[state2].Encode(e.re, b); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif b == 0 {\n\t\t\te.state.updateStateShortRep()\n\t\t\treturn nil\n\t\t}\n\t} else {\n\t\t// g in {1,2,3}\n\t\tb = iverson(g != 1)\n\t\tif err = e.state.isRepG1[state].Encode(e.re, b); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif b == 1 {\n\t\t\t// g in {2,3}\n\t\t\tb = iverson(g != 2)\n\t\t\terr = e.state.isRepG2[state].Encode(e.re, b)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif b == 1 {\n\t\t\t\te.state.rep[3] = e.state.rep[2]\n\t\t\t}\n\t\t\te.state.rep[2] = e.state.rep[1]\n\t\t}\n\t\te.state.rep[1] = e.state.rep[0]\n\t\te.state.rep[0] = dist\n\t}\n\te.state.updateStateRep()\n\treturn e.state.repLenCodec.Encode(e.re, n, posState)\n}\n\n// writeOp writes a single operation to the range encoder. The function\n// checks whether there is enough space available to close the LZMA\n// stream.\nfunc (e *encoder) writeOp(op operation) error {\n\tif e.re.Available() < int64(e.margin) {\n\t\treturn ErrLimit\n\t}\n\tswitch x := op.(type) {\n\tcase lit:\n\t\treturn e.writeLiteral(x)\n\tcase match:\n\t\treturn e.writeMatch(x)\n\tdefault:\n\t\tpanic(\"unexpected operation\")\n\t}\n}\n\n// compress compressed data from the dictionary buffer. If the flag all\n// is set, all data in the dictionary buffer will be compressed. The\n// function returns ErrLimit if the underlying writer has reached its\n// limit.\nfunc (e *encoder) compress(flags compressFlags) error {\n\tn := 0\n\tif flags&all == 0 {\n\t\tn = maxMatchLen - 1\n\t}\n\td := e.dict\n\tm := d.m\n\tfor d.Buffered() > n {\n\t\top := m.NextOp(e.state.rep)\n\t\tif err := e.writeOp(op); err != nil {\n\t\t\treturn err\n\t\t}\n\t\td.Discard(op.Len())\n\t}\n\treturn nil\n}\n\n// eosMatch is a pseudo operation that indicates the end of the stream.\nvar eosMatch = match{distance: maxDistance, n: minMatchLen}\n\n// Close terminates the LZMA stream. If requested the end-of-stream\n// marker will be written. If the byte writer limit has been or will be\n// reached during compression of the remaining data in the buffer the\n// LZMA stream will be closed and data will remain in the buffer.\nfunc (e *encoder) Close() error {\n\terr := e.compress(all)\n\tif err != nil && err != ErrLimit {\n\t\treturn err\n\t}\n\tif e.marker {\n\t\tif err := e.writeMatch(eosMatch); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\terr = e.re.Close()\n\treturn err\n}\n\n// Compressed returns the number bytes of the input data that been\n// compressed.\nfunc (e *encoder) Compressed() int64 {\n\treturn e.dict.Pos() - e.start\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/encoderdict.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n// matcher is an interface that supports the identification of the next\n// operation.\ntype matcher interface {\n\tio.Writer\n\tSetDict(d *encoderDict)\n\tNextOp(rep [4]uint32) operation\n}\n\n// encoderDict provides the dictionary of the encoder. It includes an\n// addtional buffer atop of the actual dictionary.\ntype encoderDict struct {\n\tbuf      buffer\n\tm        matcher\n\thead     int64\n\tcapacity int\n\t// preallocated array\n\tdata [maxMatchLen]byte\n}\n\n// newEncoderDict creates the encoder dictionary. The argument bufSize\n// defines the size of the additional buffer.\nfunc newEncoderDict(dictCap, bufSize int, m matcher) (d *encoderDict, err error) {\n\tif !(1 <= dictCap && int64(dictCap) <= MaxDictCap) {\n\t\treturn nil, errors.New(\n\t\t\t\"lzma: dictionary capacity out of range\")\n\t}\n\tif bufSize < 1 {\n\t\treturn nil, errors.New(\n\t\t\t\"lzma: buffer size must be larger than zero\")\n\t}\n\td = &encoderDict{\n\t\tbuf:      *newBuffer(dictCap + bufSize),\n\t\tcapacity: dictCap,\n\t\tm:        m,\n\t}\n\tm.SetDict(d)\n\treturn d, nil\n}\n\n// Discard discards n bytes. Note that n must not be larger than\n// MaxMatchLen.\nfunc (d *encoderDict) Discard(n int) {\n\tp := d.data[:n]\n\tk, _ := d.buf.Read(p)\n\tif k < n {\n\t\tpanic(fmt.Errorf(\"lzma: can't discard %d bytes\", n))\n\t}\n\td.head += int64(n)\n\td.m.Write(p)\n}\n\n// Len returns the data available in the encoder dictionary.\nfunc (d *encoderDict) Len() int {\n\tn := d.buf.Available()\n\tif int64(n) > d.head {\n\t\treturn int(d.head)\n\t}\n\treturn n\n}\n\n// DictLen returns the actual length of data in the dictionary.\nfunc (d *encoderDict) DictLen() int {\n\tif d.head < int64(d.capacity) {\n\t\treturn int(d.head)\n\t}\n\treturn d.capacity\n}\n\n// Available returns the number of bytes that can be written by a\n// following Write call.\nfunc (d *encoderDict) Available() int {\n\treturn d.buf.Available() - d.DictLen()\n}\n\n// Write writes data into the dictionary buffer. Note that the position\n// of the dictionary head will not be moved. If there is not enough\n// space in the buffer ErrNoSpace will be returned.\nfunc (d *encoderDict) Write(p []byte) (n int, err error) {\n\tm := d.Available()\n\tif len(p) > m {\n\t\tp = p[:m]\n\t\terr = ErrNoSpace\n\t}\n\tvar e error\n\tif n, e = d.buf.Write(p); e != nil {\n\t\terr = e\n\t}\n\treturn n, err\n}\n\n// Pos returns the position of the head.\nfunc (d *encoderDict) Pos() int64 { return d.head }\n\n// ByteAt returns the byte at the given distance.\nfunc (d *encoderDict) ByteAt(distance int) byte {\n\tif !(0 < distance && distance <= d.Len()) {\n\t\treturn 0\n\t}\n\ti := d.buf.rear - distance\n\tif i < 0 {\n\t\ti += len(d.buf.data)\n\t}\n\treturn d.buf.data[i]\n}\n\n// CopyN copies the last n bytes from the dictionary into the provided\n// writer. This is used for copying uncompressed data into an\n// uncompressed segment.\nfunc (d *encoderDict) CopyN(w io.Writer, n int) (written int, err error) {\n\tif n <= 0 {\n\t\treturn 0, nil\n\t}\n\tm := d.Len()\n\tif n > m {\n\t\tn = m\n\t\terr = ErrNoSpace\n\t}\n\ti := d.buf.rear - n\n\tvar e error\n\tif i < 0 {\n\t\ti += len(d.buf.data)\n\t\tif written, e = w.Write(d.buf.data[i:]); e != nil {\n\t\t\treturn written, e\n\t\t}\n\t\ti = 0\n\t}\n\tvar k int\n\tk, e = w.Write(d.buf.data[i:d.buf.rear])\n\twritten += k\n\tif e != nil {\n\t\terr = e\n\t}\n\treturn written, err\n}\n\n// Buffered returns the number of bytes in the buffer.\nfunc (d *encoderDict) Buffered() int { return d.buf.Buffered() }\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/hashtable.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/ulikunitz/xz/internal/hash\"\n)\n\n/* For compression we need to find byte sequences that match the byte\n * sequence at the dictionary head. A hash table is a simple method to\n * provide this capability.\n */\n\n// maxMatches limits the number of matches requested from the Matches\n// function. This controls the speed of the overall encoding.\nconst maxMatches = 16\n\n// shortDists defines the number of short distances supported by the\n// implementation.\nconst shortDists = 8\n\n// The minimum is somehow arbitrary but the maximum is limited by the\n// memory requirements of the hash table.\nconst (\n\tminTableExponent = 9\n\tmaxTableExponent = 20\n)\n\n// newRoller contains the function used to create an instance of the\n// hash.Roller.\nvar newRoller = func(n int) hash.Roller { return hash.NewCyclicPoly(n) }\n\n// hashTable stores the hash table including the rolling hash method.\n//\n// We implement chained hashing into a circular buffer. Each entry in\n// the circular buffer stores the delta distance to the next position with a\n// word that has the same hash value.\ntype hashTable struct {\n\tdict *encoderDict\n\t// actual hash table\n\tt []int64\n\t// circular list data with the offset to the next word\n\tdata  []uint32\n\tfront int\n\t// mask for computing the index for the hash table\n\tmask uint64\n\t// hash offset; initial value is -int64(wordLen)\n\thoff int64\n\t// length of the hashed word\n\twordLen int\n\t// hash roller for computing the hash values for the Write\n\t// method\n\twr hash.Roller\n\t// hash roller for computing arbitrary hashes\n\thr hash.Roller\n\t// preallocated slices\n\tp         [maxMatches]int64\n\tdistances [maxMatches + shortDists]int\n}\n\n// hashTableExponent derives the hash table exponent from the dictionary\n// capacity.\nfunc hashTableExponent(n uint32) int {\n\te := 30 - nlz32(n)\n\tswitch {\n\tcase e < minTableExponent:\n\t\te = minTableExponent\n\tcase e > maxTableExponent:\n\t\te = maxTableExponent\n\t}\n\treturn e\n}\n\n// newHashTable creates a new hash table for words of length wordLen\nfunc newHashTable(capacity int, wordLen int) (t *hashTable, err error) {\n\tif !(0 < capacity) {\n\t\treturn nil, errors.New(\n\t\t\t\"newHashTable: capacity must not be negative\")\n\t}\n\texp := hashTableExponent(uint32(capacity))\n\tif !(1 <= wordLen && wordLen <= 4) {\n\t\treturn nil, errors.New(\"newHashTable: \" +\n\t\t\t\"argument wordLen out of range\")\n\t}\n\tn := 1 << uint(exp)\n\tif n <= 0 {\n\t\tpanic(\"newHashTable: exponent is too large\")\n\t}\n\tt = &hashTable{\n\t\tt:       make([]int64, n),\n\t\tdata:    make([]uint32, capacity),\n\t\tmask:    (uint64(1) << uint(exp)) - 1,\n\t\thoff:    -int64(wordLen),\n\t\twordLen: wordLen,\n\t\twr:      newRoller(wordLen),\n\t\thr:      newRoller(wordLen),\n\t}\n\treturn t, nil\n}\n\nfunc (t *hashTable) SetDict(d *encoderDict) { t.dict = d }\n\n// buffered returns the number of bytes that are currently hashed.\nfunc (t *hashTable) buffered() int {\n\tn := t.hoff + 1\n\tswitch {\n\tcase n <= 0:\n\t\treturn 0\n\tcase n >= int64(len(t.data)):\n\t\treturn len(t.data)\n\t}\n\treturn int(n)\n}\n\n// addIndex adds n to an index ensuring that is stays inside the\n// circular buffer for the hash chain.\nfunc (t *hashTable) addIndex(i, n int) int {\n\ti += n - len(t.data)\n\tif i < 0 {\n\t\ti += len(t.data)\n\t}\n\treturn i\n}\n\n// putDelta puts the delta instance at the current front of the circular\n// chain buffer.\nfunc (t *hashTable) putDelta(delta uint32) {\n\tt.data[t.front] = delta\n\tt.front = t.addIndex(t.front, 1)\n}\n\n// putEntry puts a new entry into the hash table. If there is already a\n// value stored it is moved into the circular chain buffer.\nfunc (t *hashTable) putEntry(h uint64, pos int64) {\n\tif pos < 0 {\n\t\treturn\n\t}\n\ti := h & t.mask\n\told := t.t[i] - 1\n\tt.t[i] = pos + 1\n\tvar delta int64\n\tif old >= 0 {\n\t\tdelta = pos - old\n\t\tif delta > 1<<32-1 || delta > int64(t.buffered()) {\n\t\t\tdelta = 0\n\t\t}\n\t}\n\tt.putDelta(uint32(delta))\n}\n\n// WriteByte converts a single byte into a hash and puts them into the hash\n// table.\nfunc (t *hashTable) WriteByte(b byte) error {\n\th := t.wr.RollByte(b)\n\tt.hoff++\n\tt.putEntry(h, t.hoff)\n\treturn nil\n}\n\n// Write converts the bytes provided into hash tables and stores the\n// abbreviated offsets into the hash table. The method will never return an\n// error.\nfunc (t *hashTable) Write(p []byte) (n int, err error) {\n\tfor _, b := range p {\n\t\t// WriteByte doesn't generate an error.\n\t\tt.WriteByte(b)\n\t}\n\treturn len(p), nil\n}\n\n// getMatches the matches for a specific hash. The functions returns the\n// number of positions found.\n//\n// TODO: Make a getDistances because that we are actually interested in.\nfunc (t *hashTable) getMatches(h uint64, positions []int64) (n int) {\n\tif t.hoff < 0 || len(positions) == 0 {\n\t\treturn 0\n\t}\n\tbuffered := t.buffered()\n\ttailPos := t.hoff + 1 - int64(buffered)\n\trear := t.front - buffered\n\tif rear >= 0 {\n\t\trear -= len(t.data)\n\t}\n\t// get the slot for the hash\n\tpos := t.t[h&t.mask] - 1\n\tdelta := pos - tailPos\n\tfor {\n\t\tif delta < 0 {\n\t\t\treturn n\n\t\t}\n\t\tpositions[n] = tailPos + delta\n\t\tn++\n\t\tif n >= len(positions) {\n\t\t\treturn n\n\t\t}\n\t\ti := rear + int(delta)\n\t\tif i < 0 {\n\t\t\ti += len(t.data)\n\t\t}\n\t\tu := t.data[i]\n\t\tif u == 0 {\n\t\t\treturn n\n\t\t}\n\t\tdelta -= int64(u)\n\t}\n}\n\n// hash computes the rolling hash for the word stored in p. For correct\n// results its length must be equal to t.wordLen.\nfunc (t *hashTable) hash(p []byte) uint64 {\n\tvar h uint64\n\tfor _, b := range p {\n\t\th = t.hr.RollByte(b)\n\t}\n\treturn h\n}\n\n// Matches fills the positions slice with potential matches. The\n// functions returns the number of positions filled into positions. The\n// byte slice p must have word length of the hash table.\nfunc (t *hashTable) Matches(p []byte, positions []int64) int {\n\tif len(p) != t.wordLen {\n\t\tpanic(fmt.Errorf(\n\t\t\t\"byte slice must have length %d\", t.wordLen))\n\t}\n\th := t.hash(p)\n\treturn t.getMatches(h, positions)\n}\n\n// NextOp identifies the next operation using the hash table.\n//\n// TODO: Use all repetitions to find matches.\nfunc (t *hashTable) NextOp(rep [4]uint32) operation {\n\t// get positions\n\tdata := t.dict.data[:maxMatchLen]\n\tn, _ := t.dict.buf.Peek(data)\n\tdata = data[:n]\n\tvar p []int64\n\tif n < t.wordLen {\n\t\tp = t.p[:0]\n\t} else {\n\t\tp = t.p[:maxMatches]\n\t\tn = t.Matches(data[:t.wordLen], p)\n\t\tp = p[:n]\n\t}\n\n\t// convert positions in potential distances\n\thead := t.dict.head\n\tdists := append(t.distances[:0], 1, 2, 3, 4, 5, 6, 7, 8)\n\tfor _, pos := range p {\n\t\tdis := int(head - pos)\n\t\tif dis > shortDists {\n\t\t\tdists = append(dists, dis)\n\t\t}\n\t}\n\n\t// check distances\n\tvar m match\n\tdictLen := t.dict.DictLen()\n\tfor _, dist := range dists {\n\t\tif dist > dictLen {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Here comes a trick. We are only interested in matches\n\t\t// that are longer than the matches we have been found\n\t\t// before. So before we test the whole byte sequence at\n\t\t// the given distance, we test the first byte that would\n\t\t// make the match longer. If it doesn't match the byte\n\t\t// to match, we don't to care any longer.\n\t\ti := t.dict.buf.rear - dist + m.n\n\t\tif i < 0 {\n\t\t\ti += len(t.dict.buf.data)\n\t\t}\n\t\tif t.dict.buf.data[i] != data[m.n] {\n\t\t\t// We can't get a longer match. Jump to the next\n\t\t\t// distance.\n\t\t\tcontinue\n\t\t}\n\n\t\tn := t.dict.buf.matchLen(dist, data)\n\t\tswitch n {\n\t\tcase 0:\n\t\t\tcontinue\n\t\tcase 1:\n\t\t\tif uint32(dist-minDistance) != rep[0] {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif n > m.n {\n\t\t\tm = match{int64(dist), n}\n\t\t\tif n == len(data) {\n\t\t\t\t// No better match will be found.\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tif m.n == 0 {\n\t\treturn lit{data[0]}\n\t}\n\treturn m\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/header.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// uint32LE reads an uint32 integer from a byte slice\nfunc uint32LE(b []byte) uint32 {\n\tx := uint32(b[3]) << 24\n\tx |= uint32(b[2]) << 16\n\tx |= uint32(b[1]) << 8\n\tx |= uint32(b[0])\n\treturn x\n}\n\n// uint64LE converts the uint64 value stored as little endian to an uint64\n// value.\nfunc uint64LE(b []byte) uint64 {\n\tx := uint64(b[7]) << 56\n\tx |= uint64(b[6]) << 48\n\tx |= uint64(b[5]) << 40\n\tx |= uint64(b[4]) << 32\n\tx |= uint64(b[3]) << 24\n\tx |= uint64(b[2]) << 16\n\tx |= uint64(b[1]) << 8\n\tx |= uint64(b[0])\n\treturn x\n}\n\n// putUint32LE puts an uint32 integer into a byte slice that must have at least\n// a length of 4 bytes.\nfunc putUint32LE(b []byte, x uint32) {\n\tb[0] = byte(x)\n\tb[1] = byte(x >> 8)\n\tb[2] = byte(x >> 16)\n\tb[3] = byte(x >> 24)\n}\n\n// putUint64LE puts the uint64 value into the byte slice as little endian\n// value. The byte slice b must have at least place for 8 bytes.\nfunc putUint64LE(b []byte, x uint64) {\n\tb[0] = byte(x)\n\tb[1] = byte(x >> 8)\n\tb[2] = byte(x >> 16)\n\tb[3] = byte(x >> 24)\n\tb[4] = byte(x >> 32)\n\tb[5] = byte(x >> 40)\n\tb[6] = byte(x >> 48)\n\tb[7] = byte(x >> 56)\n}\n\n// noHeaderSize defines the value of the length field in the LZMA header.\nconst noHeaderSize uint64 = 1<<64 - 1\n\n// HeaderLen provides the length of the LZMA file header.\nconst HeaderLen = 13\n\n// header represents the header of an LZMA file.\ntype header struct {\n\tproperties Properties\n\tdictCap    int\n\t// uncompressed size; negative value if no size is given\n\tsize int64\n}\n\n// marshalBinary marshals the header.\nfunc (h *header) marshalBinary() (data []byte, err error) {\n\tif err = h.properties.verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tif !(0 <= h.dictCap && int64(h.dictCap) <= MaxDictCap) {\n\t\treturn nil, fmt.Errorf(\"lzma: DictCap %d out of range\",\n\t\t\th.dictCap)\n\t}\n\n\tdata = make([]byte, 13)\n\n\t// property byte\n\tdata[0] = h.properties.Code()\n\n\t// dictionary capacity\n\tputUint32LE(data[1:5], uint32(h.dictCap))\n\n\t// uncompressed size\n\tvar s uint64\n\tif h.size > 0 {\n\t\ts = uint64(h.size)\n\t} else {\n\t\ts = noHeaderSize\n\t}\n\tputUint64LE(data[5:], s)\n\n\treturn data, nil\n}\n\n// unmarshalBinary unmarshals the header.\nfunc (h *header) unmarshalBinary(data []byte) error {\n\tif len(data) != HeaderLen {\n\t\treturn errors.New(\"lzma.unmarshalBinary: data has wrong length\")\n\t}\n\n\t// properties\n\tvar err error\n\tif h.properties, err = PropertiesForCode(data[0]); err != nil {\n\t\treturn err\n\t}\n\n\t// dictionary capacity\n\th.dictCap = int(uint32LE(data[1:]))\n\tif h.dictCap < 0 {\n\t\treturn errors.New(\n\t\t\t\"LZMA header: dictionary capacity exceeds maximum \" +\n\t\t\t\t\"integer\")\n\t}\n\n\t// uncompressed size\n\ts := uint64LE(data[5:])\n\tif s == noHeaderSize {\n\t\th.size = -1\n\t} else {\n\t\th.size = int64(s)\n\t\tif h.size < 0 {\n\t\t\treturn errors.New(\n\t\t\t\t\"LZMA header: uncompressed size \" +\n\t\t\t\t\t\"out of int64 range\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// validDictCap checks whether the dictionary capacity is correct. This\n// is used to weed out wrong file headers.\nfunc validDictCap(dictcap int) bool {\n\tif int64(dictcap) == MaxDictCap {\n\t\treturn true\n\t}\n\tfor n := uint(10); n < 32; n++ {\n\t\tif dictcap == 1<<n {\n\t\t\treturn true\n\t\t}\n\t\tif dictcap == 1<<n+1<<(n-1) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// ValidHeader checks for a valid LZMA file header. It allows only\n// dictionary sizes of 2^n or 2^n+2^(n-1) with n >= 10 or 2^32-1. If\n// there is an explicit size it must not exceed 256 GiB. The length of\n// the data argument must be HeaderLen.\nfunc ValidHeader(data []byte) bool {\n\tvar h header\n\tif err := h.unmarshalBinary(data); err != nil {\n\t\treturn false\n\t}\n\tif !validDictCap(h.dictCap) {\n\t\treturn false\n\t}\n\treturn h.size < 0 || h.size <= 1<<38\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/header2.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\nconst (\n\t// maximum size of compressed data in a chunk\n\tmaxCompressed = 1 << 16\n\t// maximum size of uncompressed data in a chunk\n\tmaxUncompressed = 1 << 21\n)\n\n// chunkType represents the type of an LZMA2 chunk. Note that this\n// value is an internal representation and no actual encoding of a LZMA2\n// chunk header.\ntype chunkType byte\n\n// Possible values for the chunk type.\nconst (\n\t// end of stream\n\tcEOS chunkType = iota\n\t// uncompressed; reset dictionary\n\tcUD\n\t// uncompressed; no reset of dictionary\n\tcU\n\t// LZMA compressed; no reset\n\tcL\n\t// LZMA compressed; reset state\n\tcLR\n\t// LZMA compressed; reset state; new property value\n\tcLRN\n\t// LZMA compressed; reset state; new property value; reset dictionary\n\tcLRND\n)\n\n// chunkTypeStrings provide a string representation for the chunk types.\nvar chunkTypeStrings = [...]string{\n\tcEOS:  \"EOS\",\n\tcU:    \"U\",\n\tcUD:   \"UD\",\n\tcL:    \"L\",\n\tcLR:   \"LR\",\n\tcLRN:  \"LRN\",\n\tcLRND: \"LRND\",\n}\n\n// String returns a string representation of the chunk type.\nfunc (c chunkType) String() string {\n\tif !(cEOS <= c && c <= cLRND) {\n\t\treturn \"unknown\"\n\t}\n\treturn chunkTypeStrings[c]\n}\n\n// Actual encodings for the chunk types in the value. Note that the high\n// uncompressed size bits are stored in the header byte additionally.\nconst (\n\thEOS  = 0\n\thUD   = 1\n\thU    = 2\n\thL    = 1 << 7\n\thLR   = 1<<7 | 1<<5\n\thLRN  = 1<<7 | 1<<6\n\thLRND = 1<<7 | 1<<6 | 1<<5\n)\n\n// errHeaderByte indicates an unsupported value for the chunk header\n// byte. These bytes starts the variable-length chunk header.\nvar errHeaderByte = errors.New(\"lzma: unsupported chunk header byte\")\n\n// headerChunkType converts the header byte into a chunk type. It\n// ignores the uncompressed size bits in the chunk header byte.\nfunc headerChunkType(h byte) (c chunkType, err error) {\n\tif h&hL == 0 {\n\t\t// no compression\n\t\tswitch h {\n\t\tcase hEOS:\n\t\t\tc = cEOS\n\t\tcase hUD:\n\t\t\tc = cUD\n\t\tcase hU:\n\t\t\tc = cU\n\t\tdefault:\n\t\t\treturn 0, errHeaderByte\n\t\t}\n\t\treturn\n\t}\n\tswitch h & hLRND {\n\tcase hL:\n\t\tc = cL\n\tcase hLR:\n\t\tc = cLR\n\tcase hLRN:\n\t\tc = cLRN\n\tcase hLRND:\n\t\tc = cLRND\n\tdefault:\n\t\treturn 0, errHeaderByte\n\t}\n\treturn\n}\n\n// uncompressedHeaderLen provides the length of an uncompressed header\nconst uncompressedHeaderLen = 3\n\n// headerLen returns the length of the LZMA2 header for a given chunk\n// type.\nfunc headerLen(c chunkType) int {\n\tswitch c {\n\tcase cEOS:\n\t\treturn 1\n\tcase cU, cUD:\n\t\treturn uncompressedHeaderLen\n\tcase cL, cLR:\n\t\treturn 5\n\tcase cLRN, cLRND:\n\t\treturn 6\n\t}\n\tpanic(fmt.Errorf(\"unsupported chunk type %d\", c))\n}\n\n// chunkHeader represents the contents of a chunk header.\ntype chunkHeader struct {\n\tctype        chunkType\n\tuncompressed uint32\n\tcompressed   uint16\n\tprops        Properties\n}\n\n// String returns a string representation of the chunk header.\nfunc (h *chunkHeader) String() string {\n\treturn fmt.Sprintf(\"%s %d %d %s\", h.ctype, h.uncompressed,\n\t\th.compressed, &h.props)\n}\n\n// UnmarshalBinary reads the content of the chunk header from the data\n// slice. The slice must have the correct length.\nfunc (h *chunkHeader) UnmarshalBinary(data []byte) error {\n\tif len(data) == 0 {\n\t\treturn errors.New(\"no data\")\n\t}\n\tc, err := headerChunkType(data[0])\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tn := headerLen(c)\n\tif len(data) < n {\n\t\treturn errors.New(\"incomplete data\")\n\t}\n\tif len(data) > n {\n\t\treturn errors.New(\"invalid data length\")\n\t}\n\n\t*h = chunkHeader{ctype: c}\n\tif c == cEOS {\n\t\treturn nil\n\t}\n\n\th.uncompressed = uint32(uint16BE(data[1:3]))\n\tif c <= cU {\n\t\treturn nil\n\t}\n\th.uncompressed |= uint32(data[0]&^hLRND) << 16\n\n\th.compressed = uint16BE(data[3:5])\n\tif c <= cLR {\n\t\treturn nil\n\t}\n\n\th.props, err = PropertiesForCode(data[5])\n\treturn err\n}\n\n// MarshalBinary encodes the chunk header value. The function checks\n// whether the content of the chunk header is correct.\nfunc (h *chunkHeader) MarshalBinary() (data []byte, err error) {\n\tif h.ctype > cLRND {\n\t\treturn nil, errors.New(\"invalid chunk type\")\n\t}\n\tif err = h.props.verify(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tdata = make([]byte, headerLen(h.ctype))\n\n\tswitch h.ctype {\n\tcase cEOS:\n\t\treturn data, nil\n\tcase cUD:\n\t\tdata[0] = hUD\n\tcase cU:\n\t\tdata[0] = hU\n\tcase cL:\n\t\tdata[0] = hL\n\tcase cLR:\n\t\tdata[0] = hLR\n\tcase cLRN:\n\t\tdata[0] = hLRN\n\tcase cLRND:\n\t\tdata[0] = hLRND\n\t}\n\n\tputUint16BE(data[1:3], uint16(h.uncompressed))\n\tif h.ctype <= cU {\n\t\treturn data, nil\n\t}\n\tdata[0] |= byte(h.uncompressed>>16) &^ hLRND\n\n\tputUint16BE(data[3:5], h.compressed)\n\tif h.ctype <= cLR {\n\t\treturn data, nil\n\t}\n\n\tdata[5] = h.props.Code()\n\treturn data, nil\n}\n\n// readChunkHeader reads the chunk header from the IO reader.\nfunc readChunkHeader(r io.Reader) (h *chunkHeader, err error) {\n\tp := make([]byte, 1, 6)\n\tif _, err = io.ReadFull(r, p); err != nil {\n\t\treturn\n\t}\n\tc, err := headerChunkType(p[0])\n\tif err != nil {\n\t\treturn\n\t}\n\tp = p[:headerLen(c)]\n\tif _, err = io.ReadFull(r, p[1:]); err != nil {\n\t\treturn\n\t}\n\th = new(chunkHeader)\n\tif err = h.UnmarshalBinary(p); err != nil {\n\t\treturn nil, err\n\t}\n\treturn h, nil\n}\n\n// uint16BE converts a big-endian uint16 representation to an uint16\n// value.\nfunc uint16BE(p []byte) uint16 {\n\treturn uint16(p[0])<<8 | uint16(p[1])\n}\n\n// putUint16BE puts the big-endian uint16 presentation into the given\n// slice.\nfunc putUint16BE(p []byte, x uint16) {\n\tp[0] = byte(x >> 8)\n\tp[1] = byte(x)\n}\n\n// chunkState is used to manage the state of the chunks\ntype chunkState byte\n\n// start and stop define the initial and terminating state of the chunk\n// state\nconst (\n\tstart chunkState = 'S'\n\tstop             = 'T'\n)\n\n// errors for the chunk state handling\nvar (\n\terrChunkType = errors.New(\"lzma: unexpected chunk type\")\n\terrState     = errors.New(\"lzma: wrong chunk state\")\n)\n\n// next transitions state based on chunk type input\nfunc (c *chunkState) next(ctype chunkType) error {\n\tswitch *c {\n\t// start state\n\tcase 'S':\n\t\tswitch ctype {\n\t\tcase cEOS:\n\t\t\t*c = 'T'\n\t\tcase cUD:\n\t\t\t*c = 'R'\n\t\tcase cLRND:\n\t\t\t*c = 'L'\n\t\tdefault:\n\t\t\treturn errChunkType\n\t\t}\n\t// normal LZMA mode\n\tcase 'L':\n\t\tswitch ctype {\n\t\tcase cEOS:\n\t\t\t*c = 'T'\n\t\tcase cUD:\n\t\t\t*c = 'R'\n\t\tcase cU:\n\t\t\t*c = 'U'\n\t\tcase cL, cLR, cLRN, cLRND:\n\t\t\tbreak\n\t\tdefault:\n\t\t\treturn errChunkType\n\t\t}\n\t// reset required\n\tcase 'R':\n\t\tswitch ctype {\n\t\tcase cEOS:\n\t\t\t*c = 'T'\n\t\tcase cUD, cU:\n\t\t\tbreak\n\t\tcase cLRN, cLRND:\n\t\t\t*c = 'L'\n\t\tdefault:\n\t\t\treturn errChunkType\n\t\t}\n\t// uncompressed\n\tcase 'U':\n\t\tswitch ctype {\n\t\tcase cEOS:\n\t\t\t*c = 'T'\n\t\tcase cUD:\n\t\t\t*c = 'R'\n\t\tcase cU:\n\t\t\tbreak\n\t\tcase cL, cLR, cLRN, cLRND:\n\t\t\t*c = 'L'\n\t\tdefault:\n\t\t\treturn errChunkType\n\t\t}\n\t// terminal state\n\tcase 'T':\n\t\treturn errChunkType\n\tdefault:\n\t\treturn errState\n\t}\n\treturn nil\n}\n\n// defaultChunkType returns the default chunk type for each chunk state.\nfunc (c chunkState) defaultChunkType() chunkType {\n\tswitch c {\n\tcase 'S':\n\t\treturn cLRND\n\tcase 'L', 'U':\n\t\treturn cL\n\tcase 'R':\n\t\treturn cLRN\n\tdefault:\n\t\t// no error\n\t\treturn cEOS\n\t}\n}\n\n// maxDictCap defines the maximum dictionary capacity supported by the\n// LZMA2 dictionary capacity encoding.\nconst maxDictCap = 1<<32 - 1\n\n// maxDictCapCode defines the maximum dictionary capacity code.\nconst maxDictCapCode = 40\n\n// The function decodes the dictionary capacity byte, but doesn't change\n// for the correct range of the given byte.\nfunc decodeDictCap(c byte) int64 {\n\treturn (2 | int64(c)&1) << (11 + (c>>1)&0x1f)\n}\n\n// DecodeDictCap decodes the encoded dictionary capacity. The function\n// returns an error if the code is out of range.\nfunc DecodeDictCap(c byte) (n int64, err error) {\n\tif c >= maxDictCapCode {\n\t\tif c == maxDictCapCode {\n\t\t\treturn maxDictCap, nil\n\t\t}\n\t\treturn 0, errors.New(\"lzma: invalid dictionary size code\")\n\t}\n\treturn decodeDictCap(c), nil\n}\n\n// EncodeDictCap encodes a dictionary capacity. The function returns the\n// code for the capacity that is greater or equal n. If n exceeds the\n// maximum support dictionary capacity, the maximum value is returned.\nfunc EncodeDictCap(n int64) byte {\n\ta, b := byte(0), byte(40)\n\tfor a < b {\n\t\tc := a + (b-a)>>1\n\t\tm := decodeDictCap(c)\n\t\tif n <= m {\n\t\t\tif n == m {\n\t\t\t\treturn c\n\t\t\t}\n\t\t\tb = c\n\t\t} else {\n\t\t\ta = c + 1\n\t\t}\n\t}\n\treturn a\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/lengthcodec.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport \"errors\"\n\n// maxPosBits defines the number of bits of the position value that are used to\n// to compute the posState value. The value is used to select the tree codec\n// for length encoding and decoding.\nconst maxPosBits = 4\n\n// minMatchLen and maxMatchLen give the minimum and maximum values for\n// encoding and decoding length values. minMatchLen is also used as base\n// for the encoded length values.\nconst (\n\tminMatchLen = 2\n\tmaxMatchLen = minMatchLen + 16 + 256 - 1\n)\n\n// lengthCodec support the encoding of the length value.\ntype lengthCodec struct {\n\tchoice [2]prob\n\tlow    [1 << maxPosBits]treeCodec\n\tmid    [1 << maxPosBits]treeCodec\n\thigh   treeCodec\n}\n\n// deepcopy initializes the lc value as deep copy of the source value.\nfunc (lc *lengthCodec) deepcopy(src *lengthCodec) {\n\tif lc == src {\n\t\treturn\n\t}\n\tlc.choice = src.choice\n\tfor i := range lc.low {\n\t\tlc.low[i].deepcopy(&src.low[i])\n\t}\n\tfor i := range lc.mid {\n\t\tlc.mid[i].deepcopy(&src.mid[i])\n\t}\n\tlc.high.deepcopy(&src.high)\n}\n\n// init initializes a new length codec.\nfunc (lc *lengthCodec) init() {\n\tfor i := range lc.choice {\n\t\tlc.choice[i] = probInit\n\t}\n\tfor i := range lc.low {\n\t\tlc.low[i] = makeTreeCodec(3)\n\t}\n\tfor i := range lc.mid {\n\t\tlc.mid[i] = makeTreeCodec(3)\n\t}\n\tlc.high = makeTreeCodec(8)\n}\n\n// lBits gives the number of bits used for the encoding of the l value\n// provided to the range encoder.\nfunc lBits(l uint32) int {\n\tswitch {\n\tcase l < 8:\n\t\treturn 4\n\tcase l < 16:\n\t\treturn 5\n\tdefault:\n\t\treturn 10\n\t}\n}\n\n// Encode encodes the length offset. The length offset l can be compute by\n// subtracting minMatchLen (2) from the actual length.\n//\n//   l = length - minMatchLen\n//\nfunc (lc *lengthCodec) Encode(e *rangeEncoder, l uint32, posState uint32,\n) (err error) {\n\tif l > maxMatchLen-minMatchLen {\n\t\treturn errors.New(\"lengthCodec.Encode: l out of range\")\n\t}\n\tif l < 8 {\n\t\tif err = lc.choice[0].Encode(e, 0); err != nil {\n\t\t\treturn\n\t\t}\n\t\treturn lc.low[posState].Encode(e, l)\n\t}\n\tif err = lc.choice[0].Encode(e, 1); err != nil {\n\t\treturn\n\t}\n\tif l < 16 {\n\t\tif err = lc.choice[1].Encode(e, 0); err != nil {\n\t\t\treturn\n\t\t}\n\t\treturn lc.mid[posState].Encode(e, l-8)\n\t}\n\tif err = lc.choice[1].Encode(e, 1); err != nil {\n\t\treturn\n\t}\n\tif err = lc.high.Encode(e, l-16); err != nil {\n\t\treturn\n\t}\n\treturn nil\n}\n\n// Decode reads the length offset. Add minMatchLen to compute the actual length\n// to the length offset l.\nfunc (lc *lengthCodec) Decode(d *rangeDecoder, posState uint32,\n) (l uint32, err error) {\n\tvar b uint32\n\tif b, err = lc.choice[0].Decode(d); err != nil {\n\t\treturn\n\t}\n\tif b == 0 {\n\t\tl, err = lc.low[posState].Decode(d)\n\t\treturn\n\t}\n\tif b, err = lc.choice[1].Decode(d); err != nil {\n\t\treturn\n\t}\n\tif b == 0 {\n\t\tl, err = lc.mid[posState].Decode(d)\n\t\tl += 8\n\t\treturn\n\t}\n\tl, err = lc.high.Decode(d)\n\tl += 16\n\treturn\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/literalcodec.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\n// literalCodec supports the encoding of literal. It provides 768 probability\n// values per literal state. The upper 512 probabilities are used with the\n// context of a match bit.\ntype literalCodec struct {\n\tprobs []prob\n}\n\n// deepcopy initializes literal codec c as a deep copy of the source.\nfunc (c *literalCodec) deepcopy(src *literalCodec) {\n\tif c == src {\n\t\treturn\n\t}\n\tc.probs = make([]prob, len(src.probs))\n\tcopy(c.probs, src.probs)\n}\n\n// init initializes the literal codec.\nfunc (c *literalCodec) init(lc, lp int) {\n\tswitch {\n\tcase !(minLC <= lc && lc <= maxLC):\n\t\tpanic(\"lc out of range\")\n\tcase !(minLP <= lp && lp <= maxLP):\n\t\tpanic(\"lp out of range\")\n\t}\n\tc.probs = make([]prob, 0x300<<uint(lc+lp))\n\tfor i := range c.probs {\n\t\tc.probs[i] = probInit\n\t}\n}\n\n// Encode encodes the byte s using a range encoder as well as the current LZMA\n// encoder state, a match byte and the literal state.\nfunc (c *literalCodec) Encode(e *rangeEncoder, s byte,\n\tstate uint32, match byte, litState uint32,\n) (err error) {\n\tk := litState * 0x300\n\tprobs := c.probs[k : k+0x300]\n\tsymbol := uint32(1)\n\tr := uint32(s)\n\tif state >= 7 {\n\t\tm := uint32(match)\n\t\tfor {\n\t\t\tmatchBit := (m >> 7) & 1\n\t\t\tm <<= 1\n\t\t\tbit := (r >> 7) & 1\n\t\t\tr <<= 1\n\t\t\ti := ((1 + matchBit) << 8) | symbol\n\t\t\tif err = probs[i].Encode(e, bit); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsymbol = (symbol << 1) | bit\n\t\t\tif matchBit != bit {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif symbol >= 0x100 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tfor symbol < 0x100 {\n\t\tbit := (r >> 7) & 1\n\t\tr <<= 1\n\t\tif err = probs[symbol].Encode(e, bit); err != nil {\n\t\t\treturn\n\t\t}\n\t\tsymbol = (symbol << 1) | bit\n\t}\n\treturn nil\n}\n\n// Decode decodes a literal byte using the range decoder as well as the LZMA\n// state, a match byte, and the literal state.\nfunc (c *literalCodec) Decode(d *rangeDecoder,\n\tstate uint32, match byte, litState uint32,\n) (s byte, err error) {\n\tk := litState * 0x300\n\tprobs := c.probs[k : k+0x300]\n\tsymbol := uint32(1)\n\tif state >= 7 {\n\t\tm := uint32(match)\n\t\tfor {\n\t\t\tmatchBit := (m >> 7) & 1\n\t\t\tm <<= 1\n\t\t\ti := ((1 + matchBit) << 8) | symbol\n\t\t\tbit, err := d.DecodeBit(&probs[i])\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tsymbol = (symbol << 1) | bit\n\t\t\tif matchBit != bit {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif symbol >= 0x100 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\tfor symbol < 0x100 {\n\t\tbit, err := d.DecodeBit(&probs[symbol])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tsymbol = (symbol << 1) | bit\n\t}\n\ts = byte(symbol - 0x100)\n\treturn s, nil\n}\n\n// minLC and maxLC define the range for LC values.\nconst (\n\tminLC = 0\n\tmaxLC = 8\n)\n\n// minLC and maxLC define the range for LP values.\nconst (\n\tminLP = 0\n\tmaxLP = 4\n)\n\n// minState and maxState define a range for the state values stored in\n// the State values.\nconst (\n\tminState = 0\n\tmaxState = 11\n)\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/matchalgorithm.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport \"errors\"\n\n// MatchAlgorithm identifies an algorithm to find matches in the\n// dictionary.\ntype MatchAlgorithm byte\n\n// Supported matcher algorithms.\nconst (\n\tHashTable4 MatchAlgorithm = iota\n\tBinaryTree\n)\n\n// maStrings are used by the String method.\nvar maStrings = map[MatchAlgorithm]string{\n\tHashTable4: \"HashTable4\",\n\tBinaryTree: \"BinaryTree\",\n}\n\n// String returns a string representation of the Matcher.\nfunc (a MatchAlgorithm) String() string {\n\tif s, ok := maStrings[a]; ok {\n\t\treturn s\n\t}\n\treturn \"unknown\"\n}\n\nvar errUnsupportedMatchAlgorithm = errors.New(\n\t\"lzma: unsupported match algorithm value\")\n\n// verify checks whether the matcher value is supported.\nfunc (a MatchAlgorithm) verify() error {\n\tif _, ok := maStrings[a]; !ok {\n\t\treturn errUnsupportedMatchAlgorithm\n\t}\n\treturn nil\n}\n\nfunc (a MatchAlgorithm) new(dictCap int) (m matcher, err error) {\n\tswitch a {\n\tcase HashTable4:\n\t\treturn newHashTable(dictCap, 4)\n\tcase BinaryTree:\n\t\treturn newBinTree(dictCap)\n\t}\n\treturn nil, errUnsupportedMatchAlgorithm\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/operation.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"unicode\"\n)\n\n// operation represents an operation on the dictionary during encoding or\n// decoding.\ntype operation interface {\n\tLen() int\n}\n\n// rep represents a repetition at the given distance and the given length\ntype match struct {\n\t// supports all possible distance values, including the eos marker\n\tdistance int64\n\t// length\n\tn int\n}\n\n// verify checks whether the match is valid. If that is not the case an\n// error is returned.\nfunc (m match) verify() error {\n\tif !(minDistance <= m.distance && m.distance <= maxDistance) {\n\t\treturn errors.New(\"distance out of range\")\n\t}\n\tif !(1 <= m.n && m.n <= maxMatchLen) {\n\t\treturn errors.New(\"length out of range\")\n\t}\n\treturn nil\n}\n\n// l return the l-value for the match, which is the difference of length\n// n and 2.\nfunc (m match) l() uint32 {\n\treturn uint32(m.n - minMatchLen)\n}\n\n// dist returns the dist value for the match, which is one less of the\n// distance stored in the match.\nfunc (m match) dist() uint32 {\n\treturn uint32(m.distance - minDistance)\n}\n\n// Len returns the number of bytes matched.\nfunc (m match) Len() int {\n\treturn m.n\n}\n\n// String returns a string representation for the repetition.\nfunc (m match) String() string {\n\treturn fmt.Sprintf(\"M{%d,%d}\", m.distance, m.n)\n}\n\n// lit represents a single byte literal.\ntype lit struct {\n\tb byte\n}\n\n// Len returns 1 for the single byte literal.\nfunc (l lit) Len() int {\n\treturn 1\n}\n\n// String returns a string representation for the literal.\nfunc (l lit) String() string {\n\tvar c byte\n\tif unicode.IsPrint(rune(l.b)) {\n\t\tc = l.b\n\t} else {\n\t\tc = '.'\n\t}\n\treturn fmt.Sprintf(\"L{%c/%02x}\", c, l.b)\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/prob.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\n// movebits defines the number of bits used for the updates of probability\n// values.\nconst movebits = 5\n\n// probbits defines the number of bits of a probability value.\nconst probbits = 11\n\n// probInit defines 0.5 as initial value for prob values.\nconst probInit prob = 1 << (probbits - 1)\n\n// Type prob represents probabilities. The type can also be used to encode and\n// decode single bits.\ntype prob uint16\n\n// Dec decreases the probability. The decrease is proportional to the\n// probability value.\nfunc (p *prob) dec() {\n\t*p -= *p >> movebits\n}\n\n// Inc increases the probability. The Increase is proportional to the\n// difference of 1 and the probability value.\nfunc (p *prob) inc() {\n\t*p += ((1 << probbits) - *p) >> movebits\n}\n\n// Computes the new bound for a given range using the probability value.\nfunc (p prob) bound(r uint32) uint32 {\n\treturn (r >> probbits) * uint32(p)\n}\n\n// Bits returns 1. One is the number of bits that can be encoded or decoded\n// with a single prob value.\nfunc (p prob) Bits() int {\n\treturn 1\n}\n\n// Encode encodes the least-significant bit of v. Note that the p value will be\n// changed.\nfunc (p *prob) Encode(e *rangeEncoder, v uint32) error {\n\treturn e.EncodeBit(v, p)\n}\n\n// Decode decodes a single bit. Note that the p value will change.\nfunc (p *prob) Decode(d *rangeDecoder) (v uint32, err error) {\n\treturn d.DecodeBit(p)\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/properties.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// maximum and minimum values for the LZMA properties.\nconst (\n\tminPB = 0\n\tmaxPB = 4\n)\n\n// maxPropertyCode is the possible maximum of a properties code byte.\nconst maxPropertyCode = (maxPB+1)*(maxLP+1)*(maxLC+1) - 1\n\n// Properties contains the parameters LC, LP and PB. The parameter LC\n// defines the number of literal context bits; parameter LP the number\n// of literal position bits and PB the number of position bits.\ntype Properties struct {\n\tLC int\n\tLP int\n\tPB int\n}\n\n// String returns the properties in a string representation.\nfunc (p *Properties) String() string {\n\treturn fmt.Sprintf(\"LC %d LP %d PB %d\", p.LC, p.LP, p.PB)\n}\n\n// PropertiesForCode converts a properties code byte into a Properties value.\nfunc PropertiesForCode(code byte) (p Properties, err error) {\n\tif code > maxPropertyCode {\n\t\treturn p, errors.New(\"lzma: invalid properties code\")\n\t}\n\tp.LC = int(code % 9)\n\tcode /= 9\n\tp.LP = int(code % 5)\n\tcode /= 5\n\tp.PB = int(code % 5)\n\treturn p, err\n}\n\n// verify checks the properties for correctness.\nfunc (p *Properties) verify() error {\n\tif p == nil {\n\t\treturn errors.New(\"lzma: properties are nil\")\n\t}\n\tif !(minLC <= p.LC && p.LC <= maxLC) {\n\t\treturn errors.New(\"lzma: lc out of range\")\n\t}\n\tif !(minLP <= p.LP && p.LP <= maxLP) {\n\t\treturn errors.New(\"lzma: lp out of range\")\n\t}\n\tif !(minPB <= p.PB && p.PB <= maxPB) {\n\t\treturn errors.New(\"lzma: pb out of range\")\n\t}\n\treturn nil\n}\n\n// Code converts the properties to a byte. The function assumes that\n// the properties components are all in range.\nfunc (p Properties) Code() byte {\n\treturn byte((p.PB*5+p.LP)*9 + p.LC)\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/rangecodec.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\n// rangeEncoder implements range encoding of single bits. The low value can\n// overflow therefore we need uint64. The cache value is used to handle\n// overflows.\ntype rangeEncoder struct {\n\tlbw      *LimitedByteWriter\n\tnrange   uint32\n\tlow      uint64\n\tcacheLen int64\n\tcache    byte\n}\n\n// maxInt64 provides the  maximal value of the int64 type\nconst maxInt64 = 1<<63 - 1\n\n// newRangeEncoder creates a new range encoder.\nfunc newRangeEncoder(bw io.ByteWriter) (re *rangeEncoder, err error) {\n\tlbw, ok := bw.(*LimitedByteWriter)\n\tif !ok {\n\t\tlbw = &LimitedByteWriter{BW: bw, N: maxInt64}\n\t}\n\treturn &rangeEncoder{\n\t\tlbw:      lbw,\n\t\tnrange:   0xffffffff,\n\t\tcacheLen: 1}, nil\n}\n\n// Available returns the number of bytes that still can be written. The\n// method takes the bytes that will be currently written by Close into\n// account.\nfunc (e *rangeEncoder) Available() int64 {\n\treturn e.lbw.N - (e.cacheLen + 4)\n}\n\n// writeByte writes a single byte to the underlying writer. An error is\n// returned if the limit is reached. The written byte will be counted if\n// the underlying writer doesn't return an error.\nfunc (e *rangeEncoder) writeByte(c byte) error {\n\tif e.Available() < 1 {\n\t\treturn ErrLimit\n\t}\n\treturn e.lbw.WriteByte(c)\n}\n\n// DirectEncodeBit encodes the least-significant bit of b with probability 1/2.\nfunc (e *rangeEncoder) DirectEncodeBit(b uint32) error {\n\te.nrange >>= 1\n\te.low += uint64(e.nrange) & (0 - (uint64(b) & 1))\n\n\t// normalize\n\tconst top = 1 << 24\n\tif e.nrange >= top {\n\t\treturn nil\n\t}\n\te.nrange <<= 8\n\treturn e.shiftLow()\n}\n\n// EncodeBit encodes the least significant bit of b. The p value will be\n// updated by the function depending on the bit encoded.\nfunc (e *rangeEncoder) EncodeBit(b uint32, p *prob) error {\n\tbound := p.bound(e.nrange)\n\tif b&1 == 0 {\n\t\te.nrange = bound\n\t\tp.inc()\n\t} else {\n\t\te.low += uint64(bound)\n\t\te.nrange -= bound\n\t\tp.dec()\n\t}\n\n\t// normalize\n\tconst top = 1 << 24\n\tif e.nrange >= top {\n\t\treturn nil\n\t}\n\te.nrange <<= 8\n\treturn e.shiftLow()\n}\n\n// Close writes a complete copy of the low value.\nfunc (e *rangeEncoder) Close() error {\n\tfor i := 0; i < 5; i++ {\n\t\tif err := e.shiftLow(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// shiftLow shifts the low value for 8 bit. The shifted byte is written into\n// the byte writer. The cache value is used to handle overflows.\nfunc (e *rangeEncoder) shiftLow() error {\n\tif uint32(e.low) < 0xff000000 || (e.low>>32) != 0 {\n\t\ttmp := e.cache\n\t\tfor {\n\t\t\terr := e.writeByte(tmp + byte(e.low>>32))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\ttmp = 0xff\n\t\t\te.cacheLen--\n\t\t\tif e.cacheLen <= 0 {\n\t\t\t\tif e.cacheLen < 0 {\n\t\t\t\t\tpanic(\"negative cacheLen\")\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\te.cache = byte(uint32(e.low) >> 24)\n\t}\n\te.cacheLen++\n\te.low = uint64(uint32(e.low) << 8)\n\treturn nil\n}\n\n// rangeDecoder decodes single bits of the range encoding stream.\ntype rangeDecoder struct {\n\tbr     io.ByteReader\n\tnrange uint32\n\tcode   uint32\n}\n\n// init initializes the range decoder, by reading from the byte reader.\nfunc (d *rangeDecoder) init() error {\n\td.nrange = 0xffffffff\n\td.code = 0\n\n\tb, err := d.br.ReadByte()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif b != 0 {\n\t\treturn errors.New(\"newRangeDecoder: first byte not zero\")\n\t}\n\n\tfor i := 0; i < 4; i++ {\n\t\tif err = d.updateCode(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif d.code >= d.nrange {\n\t\treturn errors.New(\"newRangeDecoder: d.code >= d.nrange\")\n\t}\n\n\treturn nil\n}\n\n// newRangeDecoder initializes a range decoder. It reads five bytes from the\n// reader and therefore may return an error.\nfunc newRangeDecoder(br io.ByteReader) (d *rangeDecoder, err error) {\n\td = &rangeDecoder{br: br, nrange: 0xffffffff}\n\n\tb, err := d.br.ReadByte()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif b != 0 {\n\t\treturn nil, errors.New(\"newRangeDecoder: first byte not zero\")\n\t}\n\n\tfor i := 0; i < 4; i++ {\n\t\tif err = d.updateCode(); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tif d.code >= d.nrange {\n\t\treturn nil, errors.New(\"newRangeDecoder: d.code >= d.nrange\")\n\t}\n\n\treturn d, nil\n}\n\n// possiblyAtEnd checks whether the decoder may be at the end of the stream.\nfunc (d *rangeDecoder) possiblyAtEnd() bool {\n\treturn d.code == 0\n}\n\n// DirectDecodeBit decodes a bit with probability 1/2. The return value b will\n// contain the bit at the least-significant position. All other bits will be\n// zero.\nfunc (d *rangeDecoder) DirectDecodeBit() (b uint32, err error) {\n\td.nrange >>= 1\n\td.code -= d.nrange\n\tt := 0 - (d.code >> 31)\n\td.code += d.nrange & t\n\tb = (t + 1) & 1\n\n\t// d.code will stay less then d.nrange\n\n\t// normalize\n\t// assume d.code < d.nrange\n\tconst top = 1 << 24\n\tif d.nrange >= top {\n\t\treturn b, nil\n\t}\n\td.nrange <<= 8\n\t// d.code < d.nrange will be maintained\n\treturn b, d.updateCode()\n}\n\n// decodeBit decodes a single bit. The bit will be returned at the\n// least-significant position. All other bits will be zero. The probability\n// value will be updated.\nfunc (d *rangeDecoder) DecodeBit(p *prob) (b uint32, err error) {\n\tbound := p.bound(d.nrange)\n\tif d.code < bound {\n\t\td.nrange = bound\n\t\tp.inc()\n\t\tb = 0\n\t} else {\n\t\td.code -= bound\n\t\td.nrange -= bound\n\t\tp.dec()\n\t\tb = 1\n\t}\n\t// normalize\n\t// assume d.code < d.nrange\n\tconst top = 1 << 24\n\tif d.nrange >= top {\n\t\treturn b, nil\n\t}\n\td.nrange <<= 8\n\t// d.code < d.nrange will be maintained\n\treturn b, d.updateCode()\n}\n\n// updateCode reads a new byte into the code.\nfunc (d *rangeDecoder) updateCode() error {\n\tb, err := d.br.ReadByte()\n\tif err != nil {\n\t\treturn err\n\t}\n\td.code = (d.code << 8) | uint32(b)\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/reader.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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// Package lzma supports the decoding and encoding of LZMA streams.\n// Reader and Writer support the classic LZMA format. Reader2 and\n// Writer2 support the decoding and encoding of LZMA2 streams.\n//\n// The package is written completely in Go and doesn't rely on any external\n// library.\npackage lzma\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\n// ReaderConfig stores the parameters for the reader of the classic LZMA\n// format.\ntype ReaderConfig struct {\n\tDictCap int\n}\n\n// fill converts the zero values of the configuration to the default values.\nfunc (c *ReaderConfig) fill() {\n\tif c.DictCap == 0 {\n\t\tc.DictCap = 8 * 1024 * 1024\n\t}\n}\n\n// Verify checks the reader configuration for errors. Zero values will\n// be replaced by default values.\nfunc (c *ReaderConfig) Verify() error {\n\tc.fill()\n\tif !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) {\n\t\treturn errors.New(\"lzma: dictionary capacity is out of range\")\n\t}\n\treturn nil\n}\n\n// Reader provides a reader for LZMA files or streams.\ntype Reader struct {\n\tlzma io.Reader\n\th    header\n\td    *decoder\n}\n\n// NewReader creates a new reader for an LZMA stream using the classic\n// format. NewReader reads and checks the header of the LZMA stream.\nfunc NewReader(lzma io.Reader) (r *Reader, err error) {\n\treturn ReaderConfig{}.NewReader(lzma)\n}\n\n// NewReader creates a new reader for an LZMA stream in the classic\n// format. The function reads and verifies the the header of the LZMA\n// stream.\nfunc (c ReaderConfig) NewReader(lzma io.Reader) (r *Reader, err error) {\n\tif err = c.Verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tdata := make([]byte, HeaderLen)\n\tif _, err := io.ReadFull(lzma, data); err != nil {\n\t\tif err == io.EOF {\n\t\t\treturn nil, errors.New(\"lzma: unexpected EOF\")\n\t\t}\n\t\treturn nil, err\n\t}\n\tr = &Reader{lzma: lzma}\n\tif err = r.h.unmarshalBinary(data); err != nil {\n\t\treturn nil, err\n\t}\n\tif r.h.dictCap < MinDictCap {\n\t\treturn nil, errors.New(\"lzma: dictionary capacity too small\")\n\t}\n\tdictCap := r.h.dictCap\n\tif c.DictCap > dictCap {\n\t\tdictCap = c.DictCap\n\t}\n\n\tstate := newState(r.h.properties)\n\tdict, err := newDecoderDict(dictCap)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tr.d, err = newDecoder(ByteReader(lzma), state, dict, r.h.size)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n\n// EOSMarker indicates that an EOS marker has been encountered.\nfunc (r *Reader) EOSMarker() bool {\n\treturn r.d.eosMarker\n}\n\n// Read returns uncompressed data.\nfunc (r *Reader) Read(p []byte) (n int, err error) {\n\treturn r.d.Read(p)\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/reader2.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"errors\"\n\t\"io\"\n\n\t\"github.com/ulikunitz/xz/internal/xlog\"\n)\n\n// Reader2Config stores the parameters for the LZMA2 reader.\n// format.\ntype Reader2Config struct {\n\tDictCap int\n}\n\n// fill converts the zero values of the configuration to the default values.\nfunc (c *Reader2Config) fill() {\n\tif c.DictCap == 0 {\n\t\tc.DictCap = 8 * 1024 * 1024\n\t}\n}\n\n// Verify checks the reader configuration for errors. Zero configuration values\n// will be replaced by default values.\nfunc (c *Reader2Config) Verify() error {\n\tc.fill()\n\tif !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) {\n\t\treturn errors.New(\"lzma: dictionary capacity is out of range\")\n\t}\n\treturn nil\n}\n\n// Reader2 supports the reading of LZMA2 chunk sequences. Note that the\n// first chunk should have a dictionary reset and the first compressed\n// chunk a properties reset. The chunk sequence may not be terminated by\n// an end-of-stream chunk.\ntype Reader2 struct {\n\tr   io.Reader\n\terr error\n\n\tdict        *decoderDict\n\tur          *uncompressedReader\n\tdecoder     *decoder\n\tchunkReader io.Reader\n\n\tcstate chunkState\n\tctype  chunkType\n}\n\n// NewReader2 creates a reader for an LZMA2 chunk sequence.\nfunc NewReader2(lzma2 io.Reader) (r *Reader2, err error) {\n\treturn Reader2Config{}.NewReader2(lzma2)\n}\n\n// NewReader2 creates an LZMA2 reader using the given configuration.\nfunc (c Reader2Config) NewReader2(lzma2 io.Reader) (r *Reader2, err error) {\n\tif err = c.Verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tr = &Reader2{r: lzma2, cstate: start}\n\tr.dict, err = newDecoderDict(c.DictCap)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif err = r.startChunk(); err != nil {\n\t\tr.err = err\n\t}\n\treturn r, nil\n}\n\n// uncompressed tests whether the chunk type specifies an uncompressed\n// chunk.\nfunc uncompressed(ctype chunkType) bool {\n\treturn ctype == cU || ctype == cUD\n}\n\n// startChunk parses a new chunk.\nfunc (r *Reader2) startChunk() error {\n\tr.chunkReader = nil\n\theader, err := readChunkHeader(r.r)\n\tif err != nil {\n\t\tif err == io.EOF {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t}\n\t\treturn err\n\t}\n\txlog.Debugf(\"chunk header %v\", header)\n\tif err = r.cstate.next(header.ctype); err != nil {\n\t\treturn err\n\t}\n\tif r.cstate == stop {\n\t\treturn io.EOF\n\t}\n\tif header.ctype == cUD || header.ctype == cLRND {\n\t\tr.dict.Reset()\n\t}\n\tsize := int64(header.uncompressed) + 1\n\tif uncompressed(header.ctype) {\n\t\tif r.ur != nil {\n\t\t\tr.ur.Reopen(r.r, size)\n\t\t} else {\n\t\t\tr.ur = newUncompressedReader(r.r, r.dict, size)\n\t\t}\n\t\tr.chunkReader = r.ur\n\t\treturn nil\n\t}\n\tbr := ByteReader(io.LimitReader(r.r, int64(header.compressed)+1))\n\tif r.decoder == nil {\n\t\tstate := newState(header.props)\n\t\tr.decoder, err = newDecoder(br, state, r.dict, size)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tr.chunkReader = r.decoder\n\t\treturn nil\n\t}\n\tswitch header.ctype {\n\tcase cLR:\n\t\tr.decoder.State.Reset()\n\tcase cLRN, cLRND:\n\t\tr.decoder.State = newState(header.props)\n\t}\n\terr = r.decoder.Reopen(br, size)\n\tif err != nil {\n\t\treturn err\n\t}\n\tr.chunkReader = r.decoder\n\treturn nil\n}\n\n// Read reads data from the LZMA2 chunk sequence.\nfunc (r *Reader2) Read(p []byte) (n int, err error) {\n\tif r.err != nil {\n\t\treturn 0, r.err\n\t}\n\tfor n < len(p) {\n\t\tvar k int\n\t\tk, err = r.chunkReader.Read(p[n:])\n\t\tn += k\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\terr = r.startChunk()\n\t\t\t\tif err == nil {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tr.err = err\n\t\t\treturn n, err\n\t\t}\n\t\tif k == 0 {\n\t\t\tr.err = errors.New(\"lzma: Reader2 doesn't get data\")\n\t\t\treturn n, r.err\n\t\t}\n\t}\n\treturn n, nil\n}\n\n// EOS returns whether the LZMA2 stream has been terminated by an\n// end-of-stream chunk.\nfunc (r *Reader2) EOS() bool {\n\treturn r.cstate == stop\n}\n\n// uncompressedReader is used to read uncompressed chunks.\ntype uncompressedReader struct {\n\tlr   io.LimitedReader\n\tDict *decoderDict\n\teof  bool\n\terr  error\n}\n\n// newUncompressedReader initializes a new uncompressedReader.\nfunc newUncompressedReader(r io.Reader, dict *decoderDict, size int64) *uncompressedReader {\n\tur := &uncompressedReader{\n\t\tlr:   io.LimitedReader{R: r, N: size},\n\t\tDict: dict,\n\t}\n\treturn ur\n}\n\n// Reopen reinitializes an uncompressed reader.\nfunc (ur *uncompressedReader) Reopen(r io.Reader, size int64) {\n\tur.err = nil\n\tur.eof = false\n\tur.lr = io.LimitedReader{R: r, N: size}\n}\n\n// fill reads uncompressed data into the dictionary.\nfunc (ur *uncompressedReader) fill() error {\n\tif !ur.eof {\n\t\tn, err := io.CopyN(ur.Dict, &ur.lr, int64(ur.Dict.Available()))\n\t\tif err != io.EOF {\n\t\t\treturn err\n\t\t}\n\t\tur.eof = true\n\t\tif n > 0 {\n\t\t\treturn nil\n\t\t}\n\t}\n\tif ur.lr.N != 0 {\n\t\treturn io.ErrUnexpectedEOF\n\t}\n\treturn io.EOF\n}\n\n// Read reads uncompressed data from the limited reader.\nfunc (ur *uncompressedReader) Read(p []byte) (n int, err error) {\n\tif ur.err != nil {\n\t\treturn 0, ur.err\n\t}\n\tfor {\n\t\tvar k int\n\t\tk, err = ur.Dict.Read(p[n:])\n\t\tn += k\n\t\tif n >= len(p) {\n\t\t\treturn n, nil\n\t\t}\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\terr = ur.fill()\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\tur.err = err\n\treturn n, err\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/state.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\n// states defines the overall state count\nconst states = 12\n\n// State maintains the full state of the operation encoding or decoding\n// process.\ntype state struct {\n\trep         [4]uint32\n\tisMatch     [states << maxPosBits]prob\n\tisRepG0Long [states << maxPosBits]prob\n\tisRep       [states]prob\n\tisRepG0     [states]prob\n\tisRepG1     [states]prob\n\tisRepG2     [states]prob\n\tlitCodec    literalCodec\n\tlenCodec    lengthCodec\n\trepLenCodec lengthCodec\n\tdistCodec   distCodec\n\tstate       uint32\n\tposBitMask  uint32\n\tProperties  Properties\n}\n\n// initProbSlice initializes a slice of probabilities.\nfunc initProbSlice(p []prob) {\n\tfor i := range p {\n\t\tp[i] = probInit\n\t}\n}\n\n// Reset sets all state information to the original values.\nfunc (s *state) Reset() {\n\tp := s.Properties\n\t*s = state{\n\t\tProperties: p,\n\t\t// dict:       s.dict,\n\t\tposBitMask: (uint32(1) << uint(p.PB)) - 1,\n\t}\n\tinitProbSlice(s.isMatch[:])\n\tinitProbSlice(s.isRep[:])\n\tinitProbSlice(s.isRepG0[:])\n\tinitProbSlice(s.isRepG1[:])\n\tinitProbSlice(s.isRepG2[:])\n\tinitProbSlice(s.isRepG0Long[:])\n\ts.litCodec.init(p.LC, p.LP)\n\ts.lenCodec.init()\n\ts.repLenCodec.init()\n\ts.distCodec.init()\n}\n\n// initState initializes the state.\nfunc initState(s *state, p Properties) {\n\t*s = state{Properties: p}\n\ts.Reset()\n}\n\n// newState creates a new state from the give Properties.\nfunc newState(p Properties) *state {\n\ts := &state{Properties: p}\n\ts.Reset()\n\treturn s\n}\n\n// deepcopy initializes s as a deep copy of the source.\nfunc (s *state) deepcopy(src *state) {\n\tif s == src {\n\t\treturn\n\t}\n\ts.rep = src.rep\n\ts.isMatch = src.isMatch\n\ts.isRepG0Long = src.isRepG0Long\n\ts.isRep = src.isRep\n\ts.isRepG0 = src.isRepG0\n\ts.isRepG1 = src.isRepG1\n\ts.isRepG2 = src.isRepG2\n\ts.litCodec.deepcopy(&src.litCodec)\n\ts.lenCodec.deepcopy(&src.lenCodec)\n\ts.repLenCodec.deepcopy(&src.repLenCodec)\n\ts.distCodec.deepcopy(&src.distCodec)\n\ts.state = src.state\n\ts.posBitMask = src.posBitMask\n\ts.Properties = src.Properties\n}\n\n// cloneState creates a new clone of the give state.\nfunc cloneState(src *state) *state {\n\ts := new(state)\n\ts.deepcopy(src)\n\treturn s\n}\n\n// updateStateLiteral updates the state for a literal.\nfunc (s *state) updateStateLiteral() {\n\tswitch {\n\tcase s.state < 4:\n\t\ts.state = 0\n\t\treturn\n\tcase s.state < 10:\n\t\ts.state -= 3\n\t\treturn\n\t}\n\ts.state -= 6\n}\n\n// updateStateMatch updates the state for a match.\nfunc (s *state) updateStateMatch() {\n\tif s.state < 7 {\n\t\ts.state = 7\n\t} else {\n\t\ts.state = 10\n\t}\n}\n\n// updateStateRep updates the state for a repetition.\nfunc (s *state) updateStateRep() {\n\tif s.state < 7 {\n\t\ts.state = 8\n\t} else {\n\t\ts.state = 11\n\t}\n}\n\n// updateStateShortRep updates the state for a short repetition.\nfunc (s *state) updateStateShortRep() {\n\tif s.state < 7 {\n\t\ts.state = 9\n\t} else {\n\t\ts.state = 11\n\t}\n}\n\n// states computes the states of the operation codec.\nfunc (s *state) states(dictHead int64) (state1, state2, posState uint32) {\n\tstate1 = s.state\n\tposState = uint32(dictHead) & s.posBitMask\n\tstate2 = (s.state << maxPosBits) | posState\n\treturn\n}\n\n// litState computes the literal state.\nfunc (s *state) litState(prev byte, dictHead int64) uint32 {\n\tlp, lc := uint(s.Properties.LP), uint(s.Properties.LC)\n\tlitState := ((uint32(dictHead) & ((1 << lp) - 1)) << lc) |\n\t\t(uint32(prev) >> (8 - lc))\n\treturn litState\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/treecodecs.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\n// treeCodec encodes or decodes values with a fixed bit size. It is using a\n// tree of probability value. The root of the tree is the most-significant bit.\ntype treeCodec struct {\n\tprobTree\n}\n\n// makeTreeCodec makes a tree codec. The bits value must be inside the range\n// [1,32].\nfunc makeTreeCodec(bits int) treeCodec {\n\treturn treeCodec{makeProbTree(bits)}\n}\n\n// deepcopy initializes tc as a deep copy of the source.\nfunc (tc *treeCodec) deepcopy(src *treeCodec) {\n\ttc.probTree.deepcopy(&src.probTree)\n}\n\n// Encode uses the range encoder to encode a fixed-bit-size value.\nfunc (tc *treeCodec) Encode(e *rangeEncoder, v uint32) (err error) {\n\tm := uint32(1)\n\tfor i := int(tc.bits) - 1; i >= 0; i-- {\n\t\tb := (v >> uint(i)) & 1\n\t\tif err := e.EncodeBit(b, &tc.probs[m]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tm = (m << 1) | b\n\t}\n\treturn nil\n}\n\n// Decodes uses the range decoder to decode a fixed-bit-size value. Errors may\n// be caused by the range decoder.\nfunc (tc *treeCodec) Decode(d *rangeDecoder) (v uint32, err error) {\n\tm := uint32(1)\n\tfor j := 0; j < int(tc.bits); j++ {\n\t\tb, err := d.DecodeBit(&tc.probs[m])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tm = (m << 1) | b\n\t}\n\treturn m - (1 << uint(tc.bits)), nil\n}\n\n// treeReverseCodec is another tree codec, where the least-significant bit is\n// the start of the probability tree.\ntype treeReverseCodec struct {\n\tprobTree\n}\n\n// deepcopy initializes the treeReverseCodec as a deep copy of the\n// source.\nfunc (tc *treeReverseCodec) deepcopy(src *treeReverseCodec) {\n\ttc.probTree.deepcopy(&src.probTree)\n}\n\n// makeTreeReverseCodec creates treeReverseCodec value. The bits argument must\n// be in the range [1,32].\nfunc makeTreeReverseCodec(bits int) treeReverseCodec {\n\treturn treeReverseCodec{makeProbTree(bits)}\n}\n\n// Encode uses range encoder to encode a fixed-bit-size value. The range\n// encoder may cause errors.\nfunc (tc *treeReverseCodec) Encode(v uint32, e *rangeEncoder) (err error) {\n\tm := uint32(1)\n\tfor i := uint(0); i < uint(tc.bits); i++ {\n\t\tb := (v >> i) & 1\n\t\tif err := e.EncodeBit(b, &tc.probs[m]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tm = (m << 1) | b\n\t}\n\treturn nil\n}\n\n// Decodes uses the range decoder to decode a fixed-bit-size value. Errors\n// returned by the range decoder will be returned.\nfunc (tc *treeReverseCodec) Decode(d *rangeDecoder) (v uint32, err error) {\n\tm := uint32(1)\n\tfor j := uint(0); j < uint(tc.bits); j++ {\n\t\tb, err := d.DecodeBit(&tc.probs[m])\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tm = (m << 1) | b\n\t\tv |= b << j\n\t}\n\treturn v, nil\n}\n\n// probTree stores enough probability values to be used by the treeEncode and\n// treeDecode methods of the range coder types.\ntype probTree struct {\n\tprobs []prob\n\tbits  byte\n}\n\n// deepcopy initializes the probTree value as a deep copy of the source.\nfunc (t *probTree) deepcopy(src *probTree) {\n\tif t == src {\n\t\treturn\n\t}\n\tt.probs = make([]prob, len(src.probs))\n\tcopy(t.probs, src.probs)\n\tt.bits = src.bits\n}\n\n// makeProbTree initializes a probTree structure.\nfunc makeProbTree(bits int) probTree {\n\tif !(1 <= bits && bits <= 32) {\n\t\tpanic(\"bits outside of range [1,32]\")\n\t}\n\tt := probTree{\n\t\tbits:  byte(bits),\n\t\tprobs: make([]prob, 1<<uint(bits)),\n\t}\n\tfor i := range t.probs {\n\t\tt.probs[i] = probInit\n\t}\n\treturn t\n}\n\n// Bits provides the number of bits for the values to de- or encode.\nfunc (t *probTree) Bits() int {\n\treturn int(t.bits)\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/writer.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"io\"\n)\n\n// MinDictCap and MaxDictCap provide the range of supported dictionary\n// capacities.\nconst (\n\tMinDictCap = 1 << 12\n\tMaxDictCap = 1<<32 - 1\n)\n\n// WriterConfig defines the configuration parameter for a writer.\ntype WriterConfig struct {\n\t// Properties for the encoding. If the it is nil the value\n\t// {LC: 3, LP: 0, PB: 2} will be chosen.\n\tProperties *Properties\n\t// The capacity of the dictionary. If DictCap is zero, the value\n\t// 8 MiB will be chosen.\n\tDictCap int\n\t// Size of the lookahead buffer; value 0 indicates default size\n\t// 4096\n\tBufSize int\n\t// Match algorithm\n\tMatcher MatchAlgorithm\n\t// SizeInHeader indicates that the header will contain an\n\t// explicit size.\n\tSizeInHeader bool\n\t// Size of the data to be encoded. A positive value will imply\n\t// than an explicit size will be set in the header.\n\tSize int64\n\t// EOSMarker requests whether the EOSMarker needs to be written.\n\t// If no explicit size is been given the EOSMarker will be\n\t// set automatically.\n\tEOSMarker bool\n}\n\n// fill converts zero-value fields to their explicit default values.\nfunc (c *WriterConfig) fill() {\n\tif c.Properties == nil {\n\t\tc.Properties = &Properties{LC: 3, LP: 0, PB: 2}\n\t}\n\tif c.DictCap == 0 {\n\t\tc.DictCap = 8 * 1024 * 1024\n\t}\n\tif c.BufSize == 0 {\n\t\tc.BufSize = 4096\n\t}\n\tif c.Size > 0 {\n\t\tc.SizeInHeader = true\n\t}\n\tif !c.SizeInHeader {\n\t\tc.EOSMarker = true\n\t}\n}\n\n// Verify checks WriterConfig for errors. Verify will replace zero\n// values with default values.\nfunc (c *WriterConfig) Verify() error {\n\tc.fill()\n\tvar err error\n\tif c == nil {\n\t\treturn errors.New(\"lzma: WriterConfig is nil\")\n\t}\n\tif c.Properties == nil {\n\t\treturn errors.New(\"lzma: WriterConfig has no Properties set\")\n\t}\n\tif err = c.Properties.verify(); err != nil {\n\t\treturn err\n\t}\n\tif !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) {\n\t\treturn errors.New(\"lzma: dictionary capacity is out of range\")\n\t}\n\tif !(maxMatchLen <= c.BufSize) {\n\t\treturn errors.New(\"lzma: lookahead buffer size too small\")\n\t}\n\tif c.SizeInHeader {\n\t\tif c.Size < 0 {\n\t\t\treturn errors.New(\"lzma: negative size not supported\")\n\t\t}\n\t} else if !c.EOSMarker {\n\t\treturn errors.New(\"lzma: EOS marker is required\")\n\t}\n\tif err = c.Matcher.verify(); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// header returns the header structure for this configuration.\nfunc (c *WriterConfig) header() header {\n\th := header{\n\t\tproperties: *c.Properties,\n\t\tdictCap:    c.DictCap,\n\t\tsize:       -1,\n\t}\n\tif c.SizeInHeader {\n\t\th.size = c.Size\n\t}\n\treturn h\n}\n\n// Writer writes an LZMA stream in the classic format.\ntype Writer struct {\n\th   header\n\tbw  io.ByteWriter\n\tbuf *bufio.Writer\n\te   *encoder\n}\n\n// NewWriter creates a new LZMA writer for the classic format. The\n// method will write the header to the underlying stream.\nfunc (c WriterConfig) NewWriter(lzma io.Writer) (w *Writer, err error) {\n\tif err = c.Verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tw = &Writer{h: c.header()}\n\n\tvar ok bool\n\tw.bw, ok = lzma.(io.ByteWriter)\n\tif !ok {\n\t\tw.buf = bufio.NewWriter(lzma)\n\t\tw.bw = w.buf\n\t}\n\tstate := newState(w.h.properties)\n\tm, err := c.Matcher.new(w.h.dictCap)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdict, err := newEncoderDict(w.h.dictCap, c.BufSize, m)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tvar flags encoderFlags\n\tif c.EOSMarker {\n\t\tflags = eosMarker\n\t}\n\tif w.e, err = newEncoder(w.bw, state, dict, flags); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err = w.writeHeader(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn w, nil\n}\n\n// NewWriter creates a new LZMA writer using the classic format. The\n// function writes the header to the underlying stream.\nfunc NewWriter(lzma io.Writer) (w *Writer, err error) {\n\treturn WriterConfig{}.NewWriter(lzma)\n}\n\n// writeHeader writes the LZMA header into the stream.\nfunc (w *Writer) writeHeader() error {\n\tdata, err := w.h.marshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\t_, err = w.bw.(io.Writer).Write(data)\n\treturn err\n}\n\n// Write puts data into the Writer.\nfunc (w *Writer) Write(p []byte) (n int, err error) {\n\tif w.h.size >= 0 {\n\t\tm := w.h.size\n\t\tm -= w.e.Compressed() + int64(w.e.dict.Buffered())\n\t\tif m < 0 {\n\t\t\tm = 0\n\t\t}\n\t\tif m < int64(len(p)) {\n\t\t\tp = p[:m]\n\t\t\terr = ErrNoSpace\n\t\t}\n\t}\n\tvar werr error\n\tif n, werr = w.e.Write(p); werr != nil {\n\t\terr = werr\n\t}\n\treturn n, err\n}\n\n// Close closes the writer stream. It ensures that all data from the\n// buffer will be compressed and the LZMA stream will be finished.\nfunc (w *Writer) Close() error {\n\tif w.h.size >= 0 {\n\t\tn := w.e.Compressed() + int64(w.e.dict.Buffered())\n\t\tif n != w.h.size {\n\t\t\treturn errSize\n\t\t}\n\t}\n\terr := w.e.Close()\n\tif w.buf != nil {\n\t\tferr := w.buf.Flush()\n\t\tif err == nil {\n\t\t\terr = ferr\n\t\t}\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzma/writer2.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 lzma\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n)\n\n// Writer2Config is used to create a Writer2 using parameters.\ntype Writer2Config struct {\n\t// The properties for the encoding. If the it is nil the value\n\t// {LC: 3, LP: 0, PB: 2} will be chosen.\n\tProperties *Properties\n\t// The capacity of the dictionary. If DictCap is zero, the value\n\t// 8 MiB will be chosen.\n\tDictCap int\n\t// Size of the lookahead buffer; value 0 indicates default size\n\t// 4096\n\tBufSize int\n\t// Match algorithm\n\tMatcher MatchAlgorithm\n}\n\n// fill replaces zero values with default values.\nfunc (c *Writer2Config) fill() {\n\tif c.Properties == nil {\n\t\tc.Properties = &Properties{LC: 3, LP: 0, PB: 2}\n\t}\n\tif c.DictCap == 0 {\n\t\tc.DictCap = 8 * 1024 * 1024\n\t}\n\tif c.BufSize == 0 {\n\t\tc.BufSize = 4096\n\t}\n}\n\n// Verify checks the Writer2Config for correctness. Zero values will be\n// replaced by default values.\nfunc (c *Writer2Config) Verify() error {\n\tc.fill()\n\tvar err error\n\tif c == nil {\n\t\treturn errors.New(\"lzma: WriterConfig is nil\")\n\t}\n\tif c.Properties == nil {\n\t\treturn errors.New(\"lzma: WriterConfig has no Properties set\")\n\t}\n\tif err = c.Properties.verify(); err != nil {\n\t\treturn err\n\t}\n\tif !(MinDictCap <= c.DictCap && int64(c.DictCap) <= MaxDictCap) {\n\t\treturn errors.New(\"lzma: dictionary capacity is out of range\")\n\t}\n\tif !(maxMatchLen <= c.BufSize) {\n\t\treturn errors.New(\"lzma: lookahead buffer size too small\")\n\t}\n\tif c.Properties.LC+c.Properties.LP > 4 {\n\t\treturn errors.New(\"lzma: sum of lc and lp exceeds 4\")\n\t}\n\tif err = c.Matcher.verify(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Writer2 supports the creation of an LZMA2 stream. But note that\n// written data is buffered, so call Flush or Close to write data to the\n// underlying writer. The Close method writes the end-of-stream marker\n// to the stream. So you may be able to concatenate the output of two\n// writers as long the output of the first writer has only been flushed\n// but not closed.\n//\n// Any change to the fields Properties, DictCap must be done before the\n// first call to Write, Flush or Close.\ntype Writer2 struct {\n\tw io.Writer\n\n\tstart   *state\n\tencoder *encoder\n\n\tcstate chunkState\n\tctype  chunkType\n\n\tbuf bytes.Buffer\n\tlbw LimitedByteWriter\n}\n\n// NewWriter2 creates an LZMA2 chunk sequence writer with the default\n// parameters and options.\nfunc NewWriter2(lzma2 io.Writer) (w *Writer2, err error) {\n\treturn Writer2Config{}.NewWriter2(lzma2)\n}\n\n// NewWriter2 creates a new LZMA2 writer using the given configuration.\nfunc (c Writer2Config) NewWriter2(lzma2 io.Writer) (w *Writer2, err error) {\n\tif err = c.Verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tw = &Writer2{\n\t\tw:      lzma2,\n\t\tstart:  newState(*c.Properties),\n\t\tcstate: start,\n\t\tctype:  start.defaultChunkType(),\n\t}\n\tw.buf.Grow(maxCompressed)\n\tw.lbw = LimitedByteWriter{BW: &w.buf, N: maxCompressed}\n\tm, err := c.Matcher.new(c.DictCap)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\td, err := newEncoderDict(c.DictCap, c.BufSize, m)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tw.encoder, err = newEncoder(&w.lbw, cloneState(w.start), d, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn w, nil\n}\n\n// written returns the number of bytes written to the current chunk\nfunc (w *Writer2) written() int {\n\tif w.encoder == nil {\n\t\treturn 0\n\t}\n\treturn int(w.encoder.Compressed()) + w.encoder.dict.Buffered()\n}\n\n// errClosed indicates that the writer is closed.\nvar errClosed = errors.New(\"lzma: writer closed\")\n\n// Writes data to LZMA2 stream. Note that written data will be buffered.\n// Use Flush or Close to ensure that data is written to the underlying\n// writer.\nfunc (w *Writer2) Write(p []byte) (n int, err error) {\n\tif w.cstate == stop {\n\t\treturn 0, errClosed\n\t}\n\tfor n < len(p) {\n\t\tm := maxUncompressed - w.written()\n\t\tif m <= 0 {\n\t\t\tpanic(\"lzma: maxUncompressed reached\")\n\t\t}\n\t\tvar q []byte\n\t\tif n+m < len(p) {\n\t\t\tq = p[n : n+m]\n\t\t} else {\n\t\t\tq = p[n:]\n\t\t}\n\t\tk, err := w.encoder.Write(q)\n\t\tn += k\n\t\tif err != nil && err != ErrLimit {\n\t\t\treturn n, err\n\t\t}\n\t\tif err == ErrLimit || k == m {\n\t\t\tif err = w.flushChunk(); err != nil {\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t}\n\treturn n, nil\n}\n\n// writeUncompressedChunk writes an uncompressed chunk to the LZMA2\n// stream.\nfunc (w *Writer2) writeUncompressedChunk() error {\n\tu := w.encoder.Compressed()\n\tif u <= 0 {\n\t\treturn errors.New(\"lzma: can't write empty uncompressed chunk\")\n\t}\n\tif u > maxUncompressed {\n\t\tpanic(\"overrun of uncompressed data limit\")\n\t}\n\tswitch w.ctype {\n\tcase cLRND:\n\t\tw.ctype = cUD\n\tdefault:\n\t\tw.ctype = cU\n\t}\n\tw.encoder.state = w.start\n\n\theader := chunkHeader{\n\t\tctype:        w.ctype,\n\t\tuncompressed: uint32(u - 1),\n\t}\n\thdata, err := header.MarshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err = w.w.Write(hdata); err != nil {\n\t\treturn err\n\t}\n\t_, err = w.encoder.dict.CopyN(w.w, int(u))\n\treturn err\n}\n\n// writeCompressedChunk writes a compressed chunk to the underlying\n// writer.\nfunc (w *Writer2) writeCompressedChunk() error {\n\tif w.ctype == cU || w.ctype == cUD {\n\t\tpanic(\"chunk type uncompressed\")\n\t}\n\n\tu := w.encoder.Compressed()\n\tif u <= 0 {\n\t\treturn errors.New(\"writeCompressedChunk: empty chunk\")\n\t}\n\tif u > maxUncompressed {\n\t\tpanic(\"overrun of uncompressed data limit\")\n\t}\n\tc := w.buf.Len()\n\tif c <= 0 {\n\t\tpanic(\"no compressed data\")\n\t}\n\tif c > maxCompressed {\n\t\tpanic(\"overrun of compressed data limit\")\n\t}\n\theader := chunkHeader{\n\t\tctype:        w.ctype,\n\t\tuncompressed: uint32(u - 1),\n\t\tcompressed:   uint16(c - 1),\n\t\tprops:        w.encoder.state.Properties,\n\t}\n\thdata, err := header.MarshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err = w.w.Write(hdata); err != nil {\n\t\treturn err\n\t}\n\t_, err = io.Copy(w.w, &w.buf)\n\treturn err\n}\n\n// writes a single chunk to the underlying writer.\nfunc (w *Writer2) writeChunk() error {\n\tu := int(uncompressedHeaderLen + w.encoder.Compressed())\n\tc := headerLen(w.ctype) + w.buf.Len()\n\tif u < c {\n\t\treturn w.writeUncompressedChunk()\n\t}\n\treturn w.writeCompressedChunk()\n}\n\n// flushChunk terminates the current chunk. The encoder will be reset\n// to support the next chunk.\nfunc (w *Writer2) flushChunk() error {\n\tif w.written() == 0 {\n\t\treturn nil\n\t}\n\tvar err error\n\tif err = w.encoder.Close(); err != nil {\n\t\treturn err\n\t}\n\tif err = w.writeChunk(); err != nil {\n\t\treturn err\n\t}\n\tw.buf.Reset()\n\tw.lbw.N = maxCompressed\n\tif err = w.encoder.Reopen(&w.lbw); err != nil {\n\t\treturn err\n\t}\n\tif err = w.cstate.next(w.ctype); err != nil {\n\t\treturn err\n\t}\n\tw.ctype = w.cstate.defaultChunkType()\n\tw.start = cloneState(w.encoder.state)\n\treturn nil\n}\n\n// Flush writes all buffered data out to the underlying stream. This\n// could result in multiple chunks to be created.\nfunc (w *Writer2) Flush() error {\n\tif w.cstate == stop {\n\t\treturn errClosed\n\t}\n\tfor w.written() > 0 {\n\t\tif err := w.flushChunk(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// Close terminates the LZMA2 stream with an EOS chunk.\nfunc (w *Writer2) Close() error {\n\tif w.cstate == stop {\n\t\treturn errClosed\n\t}\n\tif err := w.Flush(); err != nil {\n\t\treturn nil\n\t}\n\t// write zero byte EOS chunk\n\t_, err := w.w.Write([]byte{0})\n\tif err != nil {\n\t\treturn err\n\t}\n\tw.cstate = stop\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/lzmafilter.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 xz\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/ulikunitz/xz/lzma\"\n)\n\n// LZMA filter constants.\nconst (\n\tlzmaFilterID  = 0x21\n\tlzmaFilterLen = 3\n)\n\n// lzmaFilter declares the LZMA2 filter information stored in an xz\n// block header.\ntype lzmaFilter struct {\n\tdictCap int64\n}\n\n// String returns a representation of the LZMA filter.\nfunc (f lzmaFilter) String() string {\n\treturn fmt.Sprintf(\"LZMA dict cap %#x\", f.dictCap)\n}\n\n// id returns the ID for the LZMA2 filter.\nfunc (f lzmaFilter) id() uint64 { return lzmaFilterID }\n\n// MarshalBinary converts the lzmaFilter in its encoded representation.\nfunc (f lzmaFilter) MarshalBinary() (data []byte, err error) {\n\tc := lzma.EncodeDictCap(f.dictCap)\n\treturn []byte{lzmaFilterID, 1, c}, nil\n}\n\n// UnmarshalBinary unmarshals the given data representation of the LZMA2\n// filter.\nfunc (f *lzmaFilter) UnmarshalBinary(data []byte) error {\n\tif len(data) != lzmaFilterLen {\n\t\treturn errors.New(\"xz: data for LZMA2 filter has wrong length\")\n\t}\n\tif data[0] != lzmaFilterID {\n\t\treturn errors.New(\"xz: wrong LZMA2 filter id\")\n\t}\n\tif data[1] != 1 {\n\t\treturn errors.New(\"xz: wrong LZMA2 filter size\")\n\t}\n\tdc, err := lzma.DecodeDictCap(data[2])\n\tif err != nil {\n\t\treturn errors.New(\"xz: wrong LZMA2 dictionary size property\")\n\t}\n\n\tf.dictCap = dc\n\treturn nil\n}\n\n// reader creates a new reader for the LZMA2 filter.\nfunc (f lzmaFilter) reader(r io.Reader, c *ReaderConfig) (fr io.Reader,\n\terr error) {\n\n\tconfig := new(lzma.Reader2Config)\n\tif c != nil {\n\t\tconfig.DictCap = c.DictCap\n\t}\n\tdc := int(f.dictCap)\n\tif dc < 1 {\n\t\treturn nil, errors.New(\"xz: LZMA2 filter parameter \" +\n\t\t\t\"dictionary capacity overflow\")\n\t}\n\tif dc > config.DictCap {\n\t\tconfig.DictCap = dc\n\t}\n\n\tfr, err = config.NewReader2(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn fr, nil\n}\n\n// writeCloser creates a io.WriteCloser for the LZMA2 filter.\nfunc (f lzmaFilter) writeCloser(w io.WriteCloser, c *WriterConfig,\n) (fw io.WriteCloser, err error) {\n\tconfig := new(lzma.Writer2Config)\n\tif c != nil {\n\t\t*config = lzma.Writer2Config{\n\t\t\tProperties: c.Properties,\n\t\t\tDictCap:    c.DictCap,\n\t\t\tBufSize:    c.BufSize,\n\t\t\tMatcher:    c.Matcher,\n\t\t}\n\t}\n\n\tdc := int(f.dictCap)\n\tif dc < 1 {\n\t\treturn nil, errors.New(\"xz: LZMA2 filter parameter \" +\n\t\t\t\"dictionary capacity overflow\")\n\t}\n\tif dc > config.DictCap {\n\t\tconfig.DictCap = dc\n\t}\n\n\tfw, err = config.NewWriter2(w)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn fw, nil\n}\n\n// last returns true, because an LZMA2 filter must be the last filter in\n// the filter list.\nfunc (f lzmaFilter) last() bool { return true }\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/make-docs",
    "content": "#!/bin/sh\n\nset -x\npandoc -t html5 -f markdown -s --css=doc/md.css -o README.html README.md\npandoc -t html5 -f markdown -s --css=doc/md.css -o TODO.html TODO.md\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/none-check.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 xz\n\nimport \"hash\"\n\ntype noneHash struct{}\n\nfunc (h noneHash) Write(p []byte) (n int, err error) { return len(p), nil }\n\nfunc (h noneHash) Sum(b []byte) []byte { return b }\n\nfunc (h noneHash) Reset() {}\n\nfunc (h noneHash) Size() int { return 0 }\n\nfunc (h noneHash) BlockSize() int { return 0 }\n\nfunc newNoneHash() hash.Hash {\n\treturn &noneHash{}\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/reader.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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// Package xz supports the compression and decompression of xz files. It\n// supports version 1.0.4 of the specification without the non-LZMA2\n// filters. See http://tukaani.org/xz/xz-file-format-1.0.4.txt\npackage xz\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"hash\"\n\t\"io\"\n\n\t\"github.com/ulikunitz/xz/internal/xlog\"\n\t\"github.com/ulikunitz/xz/lzma\"\n)\n\n// ReaderConfig defines the parameters for the xz reader. The\n// SingleStream parameter requests the reader to assume that the\n// underlying stream contains only a single stream.\ntype ReaderConfig struct {\n\tDictCap      int\n\tSingleStream bool\n}\n\n// fill replaces all zero values with their default values.\nfunc (c *ReaderConfig) fill() {\n\tif c.DictCap == 0 {\n\t\tc.DictCap = 8 * 1024 * 1024\n\t}\n}\n\n// Verify checks the reader parameters for Validity. Zero values will be\n// replaced by default values.\nfunc (c *ReaderConfig) Verify() error {\n\tif c == nil {\n\t\treturn errors.New(\"xz: reader parameters are nil\")\n\t}\n\tlc := lzma.Reader2Config{DictCap: c.DictCap}\n\tif err := lc.Verify(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Reader supports the reading of one or multiple xz streams.\ntype Reader struct {\n\tReaderConfig\n\n\txz io.Reader\n\tsr *streamReader\n}\n\n// streamReader decodes a single xz stream\ntype streamReader struct {\n\tReaderConfig\n\n\txz      io.Reader\n\tbr      *blockReader\n\tnewHash func() hash.Hash\n\th       header\n\tindex   []record\n}\n\n// NewReader creates a new xz reader using the default parameters.\n// The function reads and checks the header of the first XZ stream. The\n// reader will process multiple streams including padding.\nfunc NewReader(xz io.Reader) (r *Reader, err error) {\n\treturn ReaderConfig{}.NewReader(xz)\n}\n\n// NewReader creates an xz stream reader. The created reader will be\n// able to process multiple streams and padding unless a SingleStream\n// has been set in the reader configuration c.\nfunc (c ReaderConfig) NewReader(xz io.Reader) (r *Reader, err error) {\n\tif err = c.Verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tr = &Reader{\n\t\tReaderConfig: c,\n\t\txz:           xz,\n\t}\n\tif r.sr, err = c.newStreamReader(xz); err != nil {\n\t\tif err == io.EOF {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t}\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n\nvar errUnexpectedData = errors.New(\"xz: unexpected data after stream\")\n\n// Read reads uncompressed data from the stream.\nfunc (r *Reader) Read(p []byte) (n int, err error) {\n\tfor n < len(p) {\n\t\tif r.sr == nil {\n\t\t\tif r.SingleStream {\n\t\t\t\tdata := make([]byte, 1)\n\t\t\t\t_, err = io.ReadFull(r.xz, data)\n\t\t\t\tif err != io.EOF {\n\t\t\t\t\treturn n, errUnexpectedData\n\t\t\t\t}\n\t\t\t\treturn n, io.EOF\n\t\t\t}\n\t\t\tfor {\n\t\t\t\tr.sr, err = r.ReaderConfig.newStreamReader(r.xz)\n\t\t\t\tif err != errPadding {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t\tk, err := r.sr.Read(p[n:])\n\t\tn += k\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tr.sr = nil\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn n, err\n\t\t}\n\t}\n\treturn n, nil\n}\n\nvar errPadding = errors.New(\"xz: padding (4 zero bytes) encountered\")\n\n// newStreamReader creates a new xz stream reader using the given configuration\n// parameters. NewReader reads and checks the header of the xz stream.\nfunc (c ReaderConfig) newStreamReader(xz io.Reader) (r *streamReader, err error) {\n\tif err = c.Verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tdata := make([]byte, HeaderLen)\n\tif _, err := io.ReadFull(xz, data[:4]); err != nil {\n\t\treturn nil, err\n\t}\n\tif bytes.Equal(data[:4], []byte{0, 0, 0, 0}) {\n\t\treturn nil, errPadding\n\t}\n\tif _, err = io.ReadFull(xz, data[4:]); err != nil {\n\t\tif err == io.EOF {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t}\n\t\treturn nil, err\n\t}\n\tr = &streamReader{\n\t\tReaderConfig: c,\n\t\txz:           xz,\n\t\tindex:        make([]record, 0, 4),\n\t}\n\tif err = r.h.UnmarshalBinary(data); err != nil {\n\t\treturn nil, err\n\t}\n\txlog.Debugf(\"xz header %s\", r.h)\n\tif r.newHash, err = newHashFunc(r.h.flags); err != nil {\n\t\treturn nil, err\n\t}\n\treturn r, nil\n}\n\n// errIndex indicates an error with the xz file index.\nvar errIndex = errors.New(\"xz: error in xz file index\")\n\n// readTail reads the index body and the xz footer.\nfunc (r *streamReader) readTail() error {\n\tindex, n, err := readIndexBody(r.xz)\n\tif err != nil {\n\t\tif err == io.EOF {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t}\n\t\treturn err\n\t}\n\tif len(index) != len(r.index) {\n\t\treturn fmt.Errorf(\"xz: index length is %d; want %d\",\n\t\t\tlen(index), len(r.index))\n\t}\n\tfor i, rec := range r.index {\n\t\tif rec != index[i] {\n\t\t\treturn fmt.Errorf(\"xz: record %d is %v; want %v\",\n\t\t\t\ti, rec, index[i])\n\t\t}\n\t}\n\n\tp := make([]byte, footerLen)\n\tif _, err = io.ReadFull(r.xz, p); err != nil {\n\t\tif err == io.EOF {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t}\n\t\treturn err\n\t}\n\tvar f footer\n\tif err = f.UnmarshalBinary(p); err != nil {\n\t\treturn err\n\t}\n\txlog.Debugf(\"xz footer %s\", f)\n\tif f.flags != r.h.flags {\n\t\treturn errors.New(\"xz: footer flags incorrect\")\n\t}\n\tif f.indexSize != int64(n)+1 {\n\t\treturn errors.New(\"xz: index size in footer wrong\")\n\t}\n\treturn nil\n}\n\n// Read reads actual data from the xz stream.\nfunc (r *streamReader) Read(p []byte) (n int, err error) {\n\tfor n < len(p) {\n\t\tif r.br == nil {\n\t\t\tbh, hlen, err := readBlockHeader(r.xz)\n\t\t\tif err != nil {\n\t\t\t\tif err == errIndexIndicator {\n\t\t\t\t\tif err = r.readTail(); err != nil {\n\t\t\t\t\t\treturn n, err\n\t\t\t\t\t}\n\t\t\t\t\treturn n, io.EOF\n\t\t\t\t}\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t\txlog.Debugf(\"block %v\", *bh)\n\t\t\tr.br, err = r.ReaderConfig.newBlockReader(r.xz, bh,\n\t\t\t\thlen, r.newHash())\n\t\t\tif err != nil {\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t\tk, err := r.br.Read(p[n:])\n\t\tn += k\n\t\tif err != nil {\n\t\t\tif err == io.EOF {\n\t\t\t\tr.index = append(r.index, r.br.record())\n\t\t\t\tr.br = nil\n\t\t\t} else {\n\t\t\t\treturn n, err\n\t\t\t}\n\t\t}\n\t}\n\treturn n, nil\n}\n\n// countingReader is a reader that counts the bytes read.\ntype countingReader struct {\n\tr io.Reader\n\tn int64\n}\n\n// Read reads data from the wrapped reader and adds it to the n field.\nfunc (lr *countingReader) Read(p []byte) (n int, err error) {\n\tn, err = lr.r.Read(p)\n\tlr.n += int64(n)\n\treturn n, err\n}\n\n// blockReader supports the reading of a block.\ntype blockReader struct {\n\tlxz       countingReader\n\theader    *blockHeader\n\theaderLen int\n\tn         int64\n\thash      hash.Hash\n\tr         io.Reader\n\terr       error\n}\n\n// newBlockReader creates a new block reader.\nfunc (c *ReaderConfig) newBlockReader(xz io.Reader, h *blockHeader,\n\thlen int, hash hash.Hash) (br *blockReader, err error) {\n\n\tbr = &blockReader{\n\t\tlxz:       countingReader{r: xz},\n\t\theader:    h,\n\t\theaderLen: hlen,\n\t\thash:      hash,\n\t}\n\n\tfr, err := c.newFilterReader(&br.lxz, h.filters)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif br.hash.Size() != 0 {\n\t\tbr.r = io.TeeReader(fr, br.hash)\n\t} else {\n\t\tbr.r = fr\n\t}\n\n\treturn br, nil\n}\n\n// uncompressedSize returns the uncompressed size of the block.\nfunc (br *blockReader) uncompressedSize() int64 {\n\treturn br.n\n}\n\n// compressedSize returns the compressed size of the block.\nfunc (br *blockReader) compressedSize() int64 {\n\treturn br.lxz.n\n}\n\n// unpaddedSize computes the unpadded size for the block.\nfunc (br *blockReader) unpaddedSize() int64 {\n\tn := int64(br.headerLen)\n\tn += br.compressedSize()\n\tn += int64(br.hash.Size())\n\treturn n\n}\n\n// record returns the index record for the current block.\nfunc (br *blockReader) record() record {\n\treturn record{br.unpaddedSize(), br.uncompressedSize()}\n}\n\n// errBlockSize indicates that the size of the block in the block header\n// is wrong.\nvar errBlockSize = errors.New(\"xz: wrong uncompressed size for block\")\n\n// Read reads data from the block.\nfunc (br *blockReader) Read(p []byte) (n int, err error) {\n\tn, err = br.r.Read(p)\n\tbr.n += int64(n)\n\n\tu := br.header.uncompressedSize\n\tif u >= 0 && br.uncompressedSize() > u {\n\t\treturn n, errors.New(\"xz: wrong uncompressed size for block\")\n\t}\n\tc := br.header.compressedSize\n\tif c >= 0 && br.compressedSize() > c {\n\t\treturn n, errors.New(\"xz: wrong compressed size for block\")\n\t}\n\tif err != io.EOF {\n\t\treturn n, err\n\t}\n\tif br.uncompressedSize() < u || br.compressedSize() < c {\n\t\treturn n, io.ErrUnexpectedEOF\n\t}\n\n\ts := br.hash.Size()\n\tk := padLen(br.lxz.n)\n\tq := make([]byte, k+s, k+2*s)\n\tif _, err = io.ReadFull(br.lxz.r, q); err != nil {\n\t\tif err == io.EOF {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t}\n\t\treturn n, err\n\t}\n\tif !allZeros(q[:k]) {\n\t\treturn n, errors.New(\"xz: non-zero block padding\")\n\t}\n\tcheckSum := q[k:]\n\tcomputedSum := br.hash.Sum(checkSum[s:])\n\tif !bytes.Equal(checkSum, computedSum) {\n\t\treturn n, errors.New(\"xz: checksum error for block\")\n\t}\n\treturn n, io.EOF\n}\n\nfunc (c *ReaderConfig) newFilterReader(r io.Reader, f []filter) (fr io.Reader,\n\terr error) {\n\n\tif err = verifyFilters(f); err != nil {\n\t\treturn nil, err\n\t}\n\n\tfr = r\n\tfor i := len(f) - 1; i >= 0; i-- {\n\t\tfr, err = f[i].reader(fr, c)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn fr, nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulikunitz/xz/writer.go",
    "content": "// Copyright 2014-2019 Ulrich Kunitz. 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 xz\n\nimport (\n\t\"errors\"\n\t\"hash\"\n\t\"io\"\n\n\t\"github.com/ulikunitz/xz/lzma\"\n)\n\n// WriterConfig describe the parameters for an xz writer.\ntype WriterConfig struct {\n\tProperties *lzma.Properties\n\tDictCap    int\n\tBufSize    int\n\tBlockSize  int64\n\t// checksum method: CRC32, CRC64 or SHA256 (default: CRC64)\n\tCheckSum byte\n\t// Forces NoChecksum (default: false)\n\tNoCheckSum bool\n\t// match algorithm\n\tMatcher lzma.MatchAlgorithm\n}\n\n// fill replaces zero values with default values.\nfunc (c *WriterConfig) fill() {\n\tif c.Properties == nil {\n\t\tc.Properties = &lzma.Properties{LC: 3, LP: 0, PB: 2}\n\t}\n\tif c.DictCap == 0 {\n\t\tc.DictCap = 8 * 1024 * 1024\n\t}\n\tif c.BufSize == 0 {\n\t\tc.BufSize = 4096\n\t}\n\tif c.BlockSize == 0 {\n\t\tc.BlockSize = maxInt64\n\t}\n\tif c.CheckSum == 0 {\n\t\tc.CheckSum = CRC64\n\t}\n\tif c.NoCheckSum {\n\t\tc.CheckSum = None\n\t}\n}\n\n// Verify checks the configuration for errors. Zero values will be\n// replaced by default values.\nfunc (c *WriterConfig) Verify() error {\n\tif c == nil {\n\t\treturn errors.New(\"xz: writer configuration is nil\")\n\t}\n\tc.fill()\n\tlc := lzma.Writer2Config{\n\t\tProperties: c.Properties,\n\t\tDictCap:    c.DictCap,\n\t\tBufSize:    c.BufSize,\n\t\tMatcher:    c.Matcher,\n\t}\n\tif err := lc.Verify(); err != nil {\n\t\treturn err\n\t}\n\tif c.BlockSize <= 0 {\n\t\treturn errors.New(\"xz: block size out of range\")\n\t}\n\tif err := verifyFlags(c.CheckSum); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// filters creates the filter list for the given parameters.\nfunc (c *WriterConfig) filters() []filter {\n\treturn []filter{&lzmaFilter{int64(c.DictCap)}}\n}\n\n// maxInt64 defines the maximum 64-bit signed integer.\nconst maxInt64 = 1<<63 - 1\n\n// verifyFilters checks the filter list for the length and the right\n// sequence of filters.\nfunc verifyFilters(f []filter) error {\n\tif len(f) == 0 {\n\t\treturn errors.New(\"xz: no filters\")\n\t}\n\tif len(f) > 4 {\n\t\treturn errors.New(\"xz: more than four filters\")\n\t}\n\tfor _, g := range f[:len(f)-1] {\n\t\tif g.last() {\n\t\t\treturn errors.New(\"xz: last filter is not last\")\n\t\t}\n\t}\n\tif !f[len(f)-1].last() {\n\t\treturn errors.New(\"xz: wrong last filter\")\n\t}\n\treturn nil\n}\n\n// newFilterWriteCloser converts a filter list into a WriteCloser that\n// can be used by a blockWriter.\nfunc (c *WriterConfig) newFilterWriteCloser(w io.Writer, f []filter) (fw io.WriteCloser, err error) {\n\tif err = verifyFilters(f); err != nil {\n\t\treturn nil, err\n\t}\n\tfw = nopWriteCloser(w)\n\tfor i := len(f) - 1; i >= 0; i-- {\n\t\tfw, err = f[i].writeCloser(fw, c)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn fw, nil\n}\n\n// nopWCloser implements a WriteCloser with a Close method not doing\n// anything.\ntype nopWCloser struct {\n\tio.Writer\n}\n\n// Close returns nil and doesn't do anything else.\nfunc (c nopWCloser) Close() error {\n\treturn nil\n}\n\n// nopWriteCloser converts the Writer into a WriteCloser with a Close\n// function that does nothing beside returning nil.\nfunc nopWriteCloser(w io.Writer) io.WriteCloser {\n\treturn nopWCloser{w}\n}\n\n// Writer compresses data written to it. It is an io.WriteCloser.\ntype Writer struct {\n\tWriterConfig\n\n\txz      io.Writer\n\tbw      *blockWriter\n\tnewHash func() hash.Hash\n\th       header\n\tindex   []record\n\tclosed  bool\n}\n\n// newBlockWriter creates a new block writer writes the header out.\nfunc (w *Writer) newBlockWriter() error {\n\tvar err error\n\tw.bw, err = w.WriterConfig.newBlockWriter(w.xz, w.newHash())\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err = w.bw.writeHeader(w.xz); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// closeBlockWriter closes a block writer and records the sizes in the\n// index.\nfunc (w *Writer) closeBlockWriter() error {\n\tvar err error\n\tif err = w.bw.Close(); err != nil {\n\t\treturn err\n\t}\n\tw.index = append(w.index, w.bw.record())\n\treturn nil\n}\n\n// NewWriter creates a new xz writer using default parameters.\nfunc NewWriter(xz io.Writer) (w *Writer, err error) {\n\treturn WriterConfig{}.NewWriter(xz)\n}\n\n// NewWriter creates a new Writer using the given configuration parameters.\nfunc (c WriterConfig) NewWriter(xz io.Writer) (w *Writer, err error) {\n\tif err = c.Verify(); err != nil {\n\t\treturn nil, err\n\t}\n\tw = &Writer{\n\t\tWriterConfig: c,\n\t\txz:           xz,\n\t\th:            header{c.CheckSum},\n\t\tindex:        make([]record, 0, 4),\n\t}\n\tif w.newHash, err = newHashFunc(c.CheckSum); err != nil {\n\t\treturn nil, err\n\t}\n\tdata, err := w.h.MarshalBinary()\n\tif _, err = xz.Write(data); err != nil {\n\t\treturn nil, err\n\t}\n\tif err = w.newBlockWriter(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn w, nil\n\n}\n\n// Write compresses the uncompressed data provided.\nfunc (w *Writer) Write(p []byte) (n int, err error) {\n\tif w.closed {\n\t\treturn 0, errClosed\n\t}\n\tfor {\n\t\tk, err := w.bw.Write(p[n:])\n\t\tn += k\n\t\tif err != errNoSpace {\n\t\t\treturn n, err\n\t\t}\n\t\tif err = w.closeBlockWriter(); err != nil {\n\t\t\treturn n, err\n\t\t}\n\t\tif err = w.newBlockWriter(); err != nil {\n\t\t\treturn n, err\n\t\t}\n\t}\n}\n\n// Close closes the writer and adds the footer to the Writer. Close\n// doesn't close the underlying writer.\nfunc (w *Writer) Close() error {\n\tif w.closed {\n\t\treturn errClosed\n\t}\n\tw.closed = true\n\tvar err error\n\tif err = w.closeBlockWriter(); err != nil {\n\t\treturn err\n\t}\n\n\tf := footer{flags: w.h.flags}\n\tif f.indexSize, err = writeIndex(w.xz, w.index); err != nil {\n\t\treturn err\n\t}\n\tdata, err := f.MarshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err = w.xz.Write(data); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// countingWriter is a writer that counts all data written to it.\ntype countingWriter struct {\n\tw io.Writer\n\tn int64\n}\n\n// Write writes data to the countingWriter.\nfunc (cw *countingWriter) Write(p []byte) (n int, err error) {\n\tn, err = cw.w.Write(p)\n\tcw.n += int64(n)\n\tif err == nil && cw.n < 0 {\n\t\treturn n, errors.New(\"xz: counter overflow\")\n\t}\n\treturn\n}\n\n// blockWriter is writes a single block.\ntype blockWriter struct {\n\tcxz countingWriter\n\t// mw combines io.WriteCloser w and the hash.\n\tmw        io.Writer\n\tw         io.WriteCloser\n\tn         int64\n\tblockSize int64\n\tclosed    bool\n\theaderLen int\n\n\tfilters []filter\n\thash    hash.Hash\n}\n\n// newBlockWriter creates a new block writer.\nfunc (c *WriterConfig) newBlockWriter(xz io.Writer, hash hash.Hash) (bw *blockWriter, err error) {\n\tbw = &blockWriter{\n\t\tcxz:       countingWriter{w: xz},\n\t\tblockSize: c.BlockSize,\n\t\tfilters:   c.filters(),\n\t\thash:      hash,\n\t}\n\tbw.w, err = c.newFilterWriteCloser(&bw.cxz, bw.filters)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif bw.hash.Size() != 0 {\n\t\tbw.mw = io.MultiWriter(bw.w, bw.hash)\n\t} else {\n\t\tbw.mw = bw.w\n\t}\n\treturn bw, nil\n}\n\n// writeHeader writes the header. If the function is called after Close\n// the commpressedSize and uncompressedSize fields will be filled.\nfunc (bw *blockWriter) writeHeader(w io.Writer) error {\n\th := blockHeader{\n\t\tcompressedSize:   -1,\n\t\tuncompressedSize: -1,\n\t\tfilters:          bw.filters,\n\t}\n\tif bw.closed {\n\t\th.compressedSize = bw.compressedSize()\n\t\th.uncompressedSize = bw.uncompressedSize()\n\t}\n\tdata, err := h.MarshalBinary()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, err = w.Write(data); err != nil {\n\t\treturn err\n\t}\n\tbw.headerLen = len(data)\n\treturn nil\n}\n\n// compressed size returns the amount of data written to the underlying\n// stream.\nfunc (bw *blockWriter) compressedSize() int64 {\n\treturn bw.cxz.n\n}\n\n// uncompressedSize returns the number of data written to the\n// blockWriter\nfunc (bw *blockWriter) uncompressedSize() int64 {\n\treturn bw.n\n}\n\n// unpaddedSize returns the sum of the header length, the uncompressed\n// size of the block and the hash size.\nfunc (bw *blockWriter) unpaddedSize() int64 {\n\tif bw.headerLen <= 0 {\n\t\tpanic(\"xz: block header not written\")\n\t}\n\tn := int64(bw.headerLen)\n\tn += bw.compressedSize()\n\tn += int64(bw.hash.Size())\n\treturn n\n}\n\n// record returns the record for the current stream. Call Close before\n// calling this method.\nfunc (bw *blockWriter) record() record {\n\treturn record{bw.unpaddedSize(), bw.uncompressedSize()}\n}\n\nvar errClosed = errors.New(\"xz: writer already closed\")\n\nvar errNoSpace = errors.New(\"xz: no space\")\n\n// Write writes uncompressed data to the block writer.\nfunc (bw *blockWriter) Write(p []byte) (n int, err error) {\n\tif bw.closed {\n\t\treturn 0, errClosed\n\t}\n\n\tt := bw.blockSize - bw.n\n\tif int64(len(p)) > t {\n\t\terr = errNoSpace\n\t\tp = p[:t]\n\t}\n\n\tvar werr error\n\tn, werr = bw.mw.Write(p)\n\tbw.n += int64(n)\n\tif werr != nil {\n\t\treturn n, werr\n\t}\n\treturn n, err\n}\n\n// Close closes the writer.\nfunc (bw *blockWriter) Close() error {\n\tif bw.closed {\n\t\treturn errClosed\n\t}\n\tbw.closed = true\n\tif err := bw.w.Close(); err != nil {\n\t\treturn err\n\t}\n\ts := bw.hash.Size()\n\tk := padLen(bw.cxz.n)\n\tp := make([]byte, k+s)\n\tbw.hash.Sum(p[k:k])\n\tif _, err := bw.cxz.w.Write(p); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/ulyssessouza/godotenv/.gitignore",
    "content": ".DS_Store\n"
  },
  {
    "path": "vendor/github.com/ulyssessouza/godotenv/LICENCE",
    "content": "Copyright (c) 2013 John Barton\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n"
  },
  {
    "path": "vendor/github.com/ulyssessouza/godotenv/README.md",
    "content": "# GoDotEnv ![CI](https://github.com/joho/godotenv/workflows/CI/badge.svg) [![Go Report Card](https://goreportcard.com/badge/github.com/joho/godotenv)](https://goreportcard.com/report/github.com/joho/godotenv)\n\nA Go (golang) port of the Ruby dotenv project (which loads env vars from a .env file)\n\nFrom the original Library:\n\n> Storing configuration in the environment is one of the tenets of a twelve-factor app. Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables.\n>\n> But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. Dotenv load variables from a .env file into ENV when the environment is bootstrapped.\n\nIt can be used as a library (for loading in env for your own daemons etc) or as a bin command.\n\nThere is test coverage and CI for both linuxish and windows environments, but I make no guarantees about the bin version working on windows.\n\n## Installation\n\nAs a library\n\n```shell\ngo get github.com/joho/godotenv\n```\n\nor if you want to use it as a bin command\n```shell\ngo get github.com/joho/godotenv/cmd/godotenv\n```\n\n## Usage\n\nAdd your application configuration to your `.env` file in the root of your project:\n\n```shell\nS3_BUCKET=YOURS3BUCKET\nSECRET_KEY=YOURSECRETKEYGOESHERE\n```\n\nThen in your Go app you can do something like\n\n```go\npackage main\n\nimport (\n    \"github.com/joho/godotenv\"\n    \"log\"\n    \"os\"\n)\n\nfunc main() {\n  err := godotenv.Load()\n  if err != nil {\n    log.Fatal(\"Error loading .env file\")\n  }\n\n  s3Bucket := os.Getenv(\"S3_BUCKET\")\n  secretKey := os.Getenv(\"SECRET_KEY\")\n\n  // now do something with s3 or whatever\n}\n```\n\nIf you're even lazier than that, you can just take advantage of the autoload package which will read in `.env` on import\n\n```go\nimport _ \"github.com/joho/godotenv/autoload\"\n```\n\nWhile `.env` in the project root is the default, you don't have to be constrained, both examples below are 100% legit\n\n```go\n_ = godotenv.Load(\"somerandomfile\")\n_ = godotenv.Load(\"filenumberone.env\", \"filenumbertwo.env\")\n```\n\nIf you want to be really fancy with your env file you can do comments and exports (below is a valid env file)\n\n```shell\n# I am a comment and that is OK\nSOME_VAR=someval\nFOO=BAR # comments at line end are OK too\nexport BAR=BAZ\n```\n\nOr finally you can do YAML(ish) style\n\n```yaml\nFOO: bar\nBAR: baz\n```\n\nas a final aside, if you don't want godotenv munging your env you can just get a map back instead\n\n```go\nvar myEnv map[string]string\nmyEnv, err := godotenv.Read()\n\ns3Bucket := myEnv[\"S3_BUCKET\"]\n```\n\n... or from an `io.Reader` instead of a local file\n\n```go\nreader := getRemoteFile()\nmyEnv, err := godotenv.Parse(reader)\n```\n\n... or from a `string` if you so desire\n\n```go\ncontent := getRemoteFileContent()\nmyEnv, err := godotenv.Unmarshal(content)\n```\n\n### Precedence & Conventions\n\nExisting envs take precedence of envs that are loaded later.\n\nThe [convention](https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use)\nfor managing multiple environments (i.e. development, test, production)\nis to create an env named `{YOURAPP}_ENV` and load envs in this order:\n\n```go\nenv := os.Getenv(\"FOO_ENV\")\nif \"\" == env {\n  env = \"development\"\n}\n\ngodotenv.Load(\".env.\" + env + \".local\")\nif \"test\" != env {\n  godotenv.Load(\".env.local\")\n}\ngodotenv.Load(\".env.\" + env)\ngodotenv.Load() // The Original .env\n```\n\nIf you need to, you can also use `godotenv.Overload()` to defy this convention\nand overwrite existing envs instead of only supplanting them. Use with caution.\n\n### Command Mode\n\nAssuming you've installed the command as above and you've got `$GOPATH/bin` in your `$PATH`\n\n```\ngodotenv -f /some/path/to/.env some_command with some args\n```\n\nIf you don't specify `-f` it will fall back on the default of loading `.env` in `PWD`\n\n### Writing Env Files\n\nGodotenv can also write a map representing the environment to a correctly-formatted and escaped file\n\n```go\nenv, err := godotenv.Unmarshal(\"KEY=value\")\nerr := godotenv.Write(env, \"./.env\")\n```\n\n... or to a string\n\n```go\nenv, err := godotenv.Unmarshal(\"KEY=value\")\ncontent, err := godotenv.Marshal(env)\n```\n\n## Contributing\n\nContributions are most welcome! The parser itself is pretty stupidly naive and I wouldn't be surprised if it breaks with edge cases.\n\n*code changes without tests will not be accepted*\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Added some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n## Releases\n\nReleases should follow [Semver](http://semver.org/) though the first couple of releases are `v1` and `v1.1`.\n\nUse [annotated tags for all releases](https://github.com/joho/godotenv/issues/30). Example `git tag -a v1.2.1`\n\n## CI\n\nLinux: [![Build Status](https://travis-ci.org/joho/godotenv.svg?branch=master)](https://travis-ci.org/joho/godotenv) Windows: [![Build status](https://ci.appveyor.com/api/projects/status/9v40vnfvvgde64u4)](https://ci.appveyor.com/project/joho/godotenv)\n\n## Who?\n\nThe original library [dotenv](https://github.com/bkeepers/dotenv) was written by [Brandon Keepers](http://opensoul.org/), and this port was done by [John Barton](https://johnbarton.co/) based off the tests/fixtures in the original library.\n"
  },
  {
    "path": "vendor/github.com/ulyssessouza/godotenv/godotenv.go",
    "content": "// Package godotenv is a go port of the ruby dotenv library (https://github.com/bkeepers/dotenv)\n//\n// Examples/readme can be found on the github page at https://github.com/joho/godotenv\n//\n// The TL;DR is that you make a .env file that looks something like\n//\n// \t\tSOME_ENV_VAR=somevalue\n//\n// and then in your go code you can call\n//\n// \t\tgodotenv.Load()\n//\n// and all the env vars declared in .env will be available through os.Getenv(\"SOME_ENV_VAR\")\npackage godotenv\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nconst doubleQuoteSpecialChars = \"\\\\\\n\\r\\\"!$`\"\n\n// LoadWithLookupFn will read your env file(s), lookup the inherited variables with `lookupFn`\n//\n// and load them into ENV for this process.\n//\n// Call this function as close as possible to the start of your program (ideally in main)\n//\n// If you call Load without any args it will default to loading .env in the current path\n//\n// You can otherwise tell it which files to load (there can be more than one) like\n//\n//\t\tgodotenv.Load(\"fileone\", \"filetwo\")\n//\n// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults\nfunc LoadWithLookupFn(lookupFn func(string) (string, bool), filenames ...string) (err error) {\n\tfilenames = filenamesOrDefault(filenames)\n\n\tfor _, filename := range filenames {\n\t\terr = loadFile(filename, false, lookupFn)\n\t\tif err != nil {\n\t\t\treturn // return early on a spazout\n\t\t}\n\t}\n\treturn\n}\n\n// Load will read your env file(s) and load them into ENV for this process.\n//\n// Call this function as close as possible to the start of your program (ideally in main)\n//\n// If you call Load without any args it will default to loading .env in the current path\n//\n// You can otherwise tell it which files to load (there can be more than one) like\n//\n//\t\tgodotenv.Load(\"fileone\", \"filetwo\")\n//\n// It's important to note that it WILL NOT OVERRIDE an env variable that already exists - consider the .env file to set dev vars or sensible defaults\nfunc Load(filenames ...string) (err error) {\n\treturn LoadWithLookupFn(func(string) (string, bool){\n\t\treturn \"\", true\n\t}, filenames...)\n}\n\n// Overload will read your env file(s) and load them into ENV for this process.\n//\n// Call this function as close as possible to the start of your program (ideally in main)\n//\n// If you call Overload without any args it will default to loading .env in the current path\n//\n// You can otherwise tell it which files to load (there can be more than one) like\n//\n//\t\tgodotenv.Overload(\"fileone\", \"filetwo\")\n//\n// It's important to note this WILL OVERRIDE an env variable that already exists - consider the .env file to forcefilly set all vars.\nfunc Overload(filenames ...string) (err error) {\n\tfilenames = filenamesOrDefault(filenames)\n\n\tfor _, filename := range filenames {\n\t\terr = loadFile(filename, true, func(string) (string, bool) {\n\t\t\treturn \"\", true\n\t\t})\n\t\tif err != nil {\n\t\t\treturn // return early on a spazout\n\t\t}\n\t}\n\treturn\n}\n\n// Read all env (with same file loading semantics as Load) but return values as\n// a map rather than automatically writing values into env\nfunc Read(filenames ...string) (envMap map[string]string, err error) {\n\tfilenames = filenamesOrDefault(filenames)\n\tenvMap = make(map[string]string)\n\n\tfor _, filename := range filenames {\n\t\tindividualEnvMap, individualErr := readFile(filename, noLookupFn)\n\n\t\tif individualErr != nil {\n\t\t\terr = individualErr\n\t\t\treturn // return early on a spazout\n\t\t}\n\n\t\tfor key, value := range individualEnvMap {\n\t\t\tenvMap[key] = value\n\t\t}\n\t}\n\n\treturn\n}\n\n// ReadWithLookup all env (with same file loading semantics as Load) but return values as\n// a map rather than automatically writing values into env\nfunc ReadWithLookup(lookupFn func(string)(string, bool), filenames ...string) (envMap map[string]string, err error) {\n\tfilenames = filenamesOrDefault(filenames)\n\tenvMap = make(map[string]string)\n\n\tfor _, filename := range filenames {\n\t\tindividualEnvMap, individualErr := readFile(filename, lookupFn)\n\n\t\tif individualErr != nil {\n\t\t\terr = individualErr\n\t\t\treturn // return early on a spazout\n\t\t}\n\n\t\tfor key, value := range individualEnvMap {\n\t\t\tenvMap[key] = value\n\t\t}\n\t}\n\n\treturn\n}\n\n// ParseWithLookup reads an env file from io.Reader resolving variables with lookupFn, returning a map of keys and values.\nfunc ParseWithLookup(r io.Reader, lookupFn func(string)(string, bool)) (map[string]string, error) {\n\tenvMap := make(map[string]string)\n\n\tvar lines []string\n\tscanner := bufio.NewScanner(r)\n\tfor scanner.Scan() {\n\t\tlines = append(lines, scanner.Text())\n\t}\n\n\tif err := scanner.Err(); err != nil {\n\t\treturn envMap, err\n\t}\n\n\tfor _, fullLine := range lines {\n\t\tif !isIgnoredLine(fullLine) {\n\t\t\tvar key, value string\n\t\t\tkey, value, err := parseLine(fullLine, envMap, lookupFn)\n\t\t\tif err != nil {\n\t\t\t\treturn envMap, err\n\t\t\t}\n\t\t\tif key == \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tenvMap[key] = value\n\t\t}\n\t}\n\treturn envMap, nil\n}\n\n// Parse reads an env file from io.Reader, returning a map of keys and values.\nfunc Parse(r io.Reader) (map[string]string, error) {\n\treturn ParseWithLookup(r, noLookupFn)\n}\n\n//Unmarshal reads an env file from a string, returning a map of keys and values.\nfunc Unmarshal(str string) (envMap map[string]string, err error) {\n\treturn Parse(strings.NewReader(str))\n}\n\n// Exec loads env vars from the specified filenames (empty map falls back to default)\n// then executes the cmd specified.\n//\n// Simply hooks up os.Stdin/err/out to the command and calls Run()\n//\n// If you want more fine grained control over your command it's recommended\n// that you use `Load()` or `Read()` and the `os/exec` package yourself.\nfunc Exec(filenames []string, cmd string, cmdArgs []string) error {\n\tLoad(filenames...)\n\n\tcommand := exec.Command(cmd, cmdArgs...)\n\tcommand.Stdin = os.Stdin\n\tcommand.Stdout = os.Stdout\n\tcommand.Stderr = os.Stderr\n\treturn command.Run()\n}\n\n// Write serializes the given environment and writes it to a file\nfunc Write(envMap map[string]string, filename string) error {\n\tcontent, err := Marshal(envMap)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfile, err := os.Create(filename)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n\t_, err = file.WriteString(content + \"\\n\")\n\tif err != nil {\n\t\treturn err\n\t}\n\tfile.Sync()\n\treturn err\n}\n\n// Marshal outputs the given environment as a dotenv-formatted environment file.\n// Each line is in the format: KEY=\"VALUE\" where VALUE is backslash-escaped.\nfunc Marshal(envMap map[string]string) (string, error) {\n\tlines := make([]string, 0, len(envMap))\n\tfor k, v := range envMap {\n\t\tif d, err := strconv.Atoi(v); err == nil {\n\t\t\tlines = append(lines, fmt.Sprintf(`%s=%d`, k, d))\n\t\t} else {\n\t\t\tlines = append(lines, fmt.Sprintf(`%s=\"%s\"`, k, doubleQuoteEscape(v)))\n\t\t}\n\t}\n\tsort.Strings(lines)\n\treturn strings.Join(lines, \"\\n\"), nil\n}\n\nfunc filenamesOrDefault(filenames []string) []string {\n\tif len(filenames) == 0 {\n\t\treturn []string{\".env\"}\n\t}\n\treturn filenames\n}\n\nfunc loadFile(filename string, overload bool, lookupFn func(string)(string, bool)) error {\n\tenvMap, err := readFile(filename, lookupFn)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcurrentEnv := map[string]bool{}\n\trawEnv := os.Environ()\n\tfor _, rawEnvLine := range rawEnv {\n\t\tkey := strings.Split(rawEnvLine, \"=\")[0]\n\t\tcurrentEnv[key] = true\n\t}\n\n\tfor key, value := range envMap {\n\t\tif !currentEnv[key] || overload {\n\t\t\tos.Setenv(key, value)\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc readFile(filename string, lookupFn func(string)(string, bool)) (envMap map[string]string, err error) {\n\tfile, err := os.Open(filename)\n\tif err != nil {\n\t\treturn\n\t}\n\tdefer file.Close()\n\n\treturn ParseWithLookup(file, lookupFn)\n}\n\nvar exportRegex = regexp.MustCompile(`^\\s*(?:export\\s+)?(.*?)\\s*$`)\n\nfunc parseLine(line string, envMap map[string]string, lookupFn func(string)(string, bool)) (key string, value string, err error) {\n\tif len(line) == 0 {\n\t\terr = errors.New(\"zero length string\")\n\t\treturn\n\t}\n\n\t// ditch the comments (but keep quoted hashes)\n\tif strings.Contains(line, \"#\") {\n\t\tsegmentsBetweenHashes := strings.Split(line, \"#\")\n\t\tquotesAreOpen := false\n\t\tvar segmentsToKeep []string\n\t\tfor _, segment := range segmentsBetweenHashes {\n\t\t\tif strings.Count(segment, \"\\\"\") == 1 || strings.Count(segment, \"'\") == 1 {\n\t\t\t\tif quotesAreOpen {\n\t\t\t\t\tquotesAreOpen = false\n\t\t\t\t\tsegmentsToKeep = append(segmentsToKeep, segment)\n\t\t\t\t} else {\n\t\t\t\t\tquotesAreOpen = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif len(segmentsToKeep) == 0 || quotesAreOpen {\n\t\t\t\tsegmentsToKeep = append(segmentsToKeep, segment)\n\t\t\t}\n\t\t}\n\n\t\tline = strings.Join(segmentsToKeep, \"#\")\n\t}\n\n\tfirstEquals := strings.Index(line, \"=\")\n\tfirstColon := strings.Index(line, \":\")\n\tsplitString := strings.SplitN(line, \"=\", 2)\n\tif firstColon != -1 && (firstColon < firstEquals || firstEquals == -1) {\n\t\t//this is a yaml-style line\n\t\tsplitString = strings.SplitN(line, \":\", 2)\n\t}\n\n\t// Parse the key\n\tkey = strings.TrimSpace(strings.TrimPrefix(splitString[0], \"export \"))\n\tkey = exportRegex.ReplaceAllString(key, \"$1\")\n\tif err = validateVariableName(key); err != nil {\n\t\treturn\n\t}\n\n\t// Environment inherited variable\n\tif firstEquals < 0 && firstColon < 0 {\n\t\tvalue = \"\"\n\t\tv, ok := lookupFn(strings.TrimSpace(key))\n\t\tif ok {\n\t\t\tvalue = v\n\t\t}\n\t\treturn\n\t}\n\n\tif len(splitString) != 2 {\n\t\terr = errors.New(\"Can't separate key from value\")\n\t\treturn\n\t}\n\n\t// Parse the value\n\tvalue = parseValue(splitString[1], envMap)\n\treturn\n}\n\nfunc validateVariableName(key string) error {\n\tkey = strings.TrimSpace(strings.TrimPrefix(key, \"export \"))\n\tif !variableNameRegex.MatchString(key) {\n\t\treturn fmt.Errorf(\"invalid variable name %q\", key)\n\t}\n\treturn nil\n}\n\nvar (\n\tsingleQuotesRegex  = regexp.MustCompile(`\\A'(.*)'\\z`)\n\tdoubleQuotesRegex  = regexp.MustCompile(`\\A\"(.*)\"\\z`)\n\tescapeRegex        = regexp.MustCompile(`\\\\.`)\n\tunescapeCharsRegex = regexp.MustCompile(`\\\\([^$])`)\n\tvariableNameRegex  = regexp.MustCompile(`^[_\\\\.a-zA-Z0-9]+$`)\n\n\tnoLookupFn = func(string)(string, bool) {return \"\", true}\n)\n\nfunc parseValue(value string, envMap map[string]string) string {\n\n\t// trim\n\tvalue = strings.Trim(value, \" \")\n\n\t// check if we've got quoted values or possible escapes\n\tif len(value) > 1 {\n\t\tsingleQuotes := singleQuotesRegex.FindStringSubmatch(value)\n\n\t\tdoubleQuotes := doubleQuotesRegex.FindStringSubmatch(value)\n\n\t\tif singleQuotes != nil || doubleQuotes != nil {\n\t\t\t// pull the quotes off the edges\n\t\t\tvalue = value[1 : len(value)-1]\n\t\t}\n\n\t\tif doubleQuotes != nil {\n\t\t\t// expand newlines\n\t\t\tvalue = escapeRegex.ReplaceAllStringFunc(value, func(match string) string {\n\t\t\t\tc := strings.TrimPrefix(match, `\\`)\n\t\t\t\tswitch c {\n\t\t\t\tcase \"n\":\n\t\t\t\t\treturn \"\\n\"\n\t\t\t\tcase \"r\":\n\t\t\t\t\treturn \"\\r\"\n\t\t\t\tdefault:\n\t\t\t\t\treturn match\n\t\t\t\t}\n\t\t\t})\n\t\t\t// unescape characters\n\t\t\tvalue = unescapeCharsRegex.ReplaceAllString(value, \"$1\")\n\t\t}\n\n\t\tif singleQuotes == nil {\n\t\t\tvalue = expandVariables(value, envMap)\n\t\t}\n\t}\n\n\treturn value\n}\n\nvar expandVarRegex = regexp.MustCompile(`(\\\\)?(\\$)(\\()?\\{?([A-Z0-9_]+)?\\}?`)\n\nfunc expandVariables(v string, m map[string]string) string {\n\treturn expandVarRegex.ReplaceAllStringFunc(v, func(s string) string {\n\t\tsubmatch := expandVarRegex.FindStringSubmatch(s)\n\n\t\tif submatch == nil {\n\t\t\treturn s\n\t\t}\n\t\tif submatch[1] == \"\\\\\" || submatch[2] == \"(\" {\n\t\t\treturn submatch[0][1:]\n\t\t} else if submatch[4] != \"\" {\n\t\t\treturn m[submatch[4]]\n\t\t}\n\t\treturn s\n\t})\n}\n\nfunc isIgnoredLine(line string) bool {\n\ttrimmedLine := strings.TrimSpace(line)\n\treturn len(trimmedLine) == 0 || strings.HasPrefix(trimmedLine, \"#\")\n}\n\nfunc doubleQuoteEscape(line string) string {\n\tfor _, c := range doubleQuoteSpecialChars {\n\t\ttoReplace := \"\\\\\" + string(c)\n\t\tif c == '\\n' {\n\t\t\ttoReplace = `\\n`\n\t\t}\n\t\tif c == '\\r' {\n\t\t\ttoReplace = `\\r`\n\t\t}\n\t\tline = strings.Replace(line, string(c), toReplace, -1)\n\t}\n\treturn line\n}\n"
  },
  {
    "path": "vendor/github.com/ulyssessouza/godotenv/renovate.json",
    "content": "{\n  \"extends\": [\n    \"config:base\"\n  ]\n}\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/LICENSE",
    "content": "Copyright (c) 2015 Vincent Batts, Raleigh, NC, USA\n\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation\nand/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors\nmay be used to endorse or promote products derived from this software without\nspecific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (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": "vendor/github.com/vbatts/tar-split/archive/tar/common.go",
    "content": "// Copyright 2009 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// Package tar implements access to tar archives.\n//\n// Tape archives (tar) are a file format for storing a sequence of files that\n// can be read and written in a streaming manner.\n// This package aims to cover most variations of the format,\n// including those produced by GNU and BSD tar tools.\npackage tar\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"os\"\n\t\"path\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// BUG: Use of the Uid and Gid fields in Header could overflow on 32-bit\n// architectures. If a large value is encountered when decoding, the result\n// stored in Header will be the truncated version.\n\nvar (\n\tErrHeader          = errors.New(\"archive/tar: invalid tar header\")\n\tErrWriteTooLong    = errors.New(\"archive/tar: write too long\")\n\tErrFieldTooLong    = errors.New(\"archive/tar: header field too long\")\n\tErrWriteAfterClose = errors.New(\"archive/tar: write after close\")\n\terrMissData        = errors.New(\"archive/tar: sparse file references non-existent data\")\n\terrUnrefData       = errors.New(\"archive/tar: sparse file contains unreferenced data\")\n\terrWriteHole       = errors.New(\"archive/tar: write non-NUL byte in sparse hole\")\n)\n\ntype headerError []string\n\nfunc (he headerError) Error() string {\n\tconst prefix = \"archive/tar: cannot encode header\"\n\tvar ss []string\n\tfor _, s := range he {\n\t\tif s != \"\" {\n\t\t\tss = append(ss, s)\n\t\t}\n\t}\n\tif len(ss) == 0 {\n\t\treturn prefix\n\t}\n\treturn fmt.Sprintf(\"%s: %v\", prefix, strings.Join(ss, \"; and \"))\n}\n\n// Type flags for Header.Typeflag.\nconst (\n\t// Type '0' indicates a regular file.\n\tTypeReg  = '0'\n\tTypeRegA = '\\x00' // Deprecated: Use TypeReg instead.\n\n\t// Type '1' to '6' are header-only flags and may not have a data body.\n\tTypeLink    = '1' // Hard link\n\tTypeSymlink = '2' // Symbolic link\n\tTypeChar    = '3' // Character device node\n\tTypeBlock   = '4' // Block device node\n\tTypeDir     = '5' // Directory\n\tTypeFifo    = '6' // FIFO node\n\n\t// Type '7' is reserved.\n\tTypeCont = '7'\n\n\t// Type 'x' is used by the PAX format to store key-value records that\n\t// are only relevant to the next file.\n\t// This package transparently handles these types.\n\tTypeXHeader = 'x'\n\n\t// Type 'g' is used by the PAX format to store key-value records that\n\t// are relevant to all subsequent files.\n\t// This package only supports parsing and composing such headers,\n\t// but does not currently support persisting the global state across files.\n\tTypeXGlobalHeader = 'g'\n\n\t// Type 'S' indicates a sparse file in the GNU format.\n\tTypeGNUSparse = 'S'\n\n\t// Types 'L' and 'K' are used by the GNU format for a meta file\n\t// used to store the path or link name for the next file.\n\t// This package transparently handles these types.\n\tTypeGNULongName = 'L'\n\tTypeGNULongLink = 'K'\n)\n\n// Keywords for PAX extended header records.\nconst (\n\tpaxNone     = \"\" // Indicates that no PAX key is suitable\n\tpaxPath     = \"path\"\n\tpaxLinkpath = \"linkpath\"\n\tpaxSize     = \"size\"\n\tpaxUid      = \"uid\"\n\tpaxGid      = \"gid\"\n\tpaxUname    = \"uname\"\n\tpaxGname    = \"gname\"\n\tpaxMtime    = \"mtime\"\n\tpaxAtime    = \"atime\"\n\tpaxCtime    = \"ctime\"   // Removed from later revision of PAX spec, but was valid\n\tpaxCharset  = \"charset\" // Currently unused\n\tpaxComment  = \"comment\" // Currently unused\n\n\tpaxSchilyXattr = \"SCHILY.xattr.\"\n\n\t// Keywords for GNU sparse files in a PAX extended header.\n\tpaxGNUSparse          = \"GNU.sparse.\"\n\tpaxGNUSparseNumBlocks = \"GNU.sparse.numblocks\"\n\tpaxGNUSparseOffset    = \"GNU.sparse.offset\"\n\tpaxGNUSparseNumBytes  = \"GNU.sparse.numbytes\"\n\tpaxGNUSparseMap       = \"GNU.sparse.map\"\n\tpaxGNUSparseName      = \"GNU.sparse.name\"\n\tpaxGNUSparseMajor     = \"GNU.sparse.major\"\n\tpaxGNUSparseMinor     = \"GNU.sparse.minor\"\n\tpaxGNUSparseSize      = \"GNU.sparse.size\"\n\tpaxGNUSparseRealSize  = \"GNU.sparse.realsize\"\n)\n\n// basicKeys is a set of the PAX keys for which we have built-in support.\n// This does not contain \"charset\" or \"comment\", which are both PAX-specific,\n// so adding them as first-class features of Header is unlikely.\n// Users can use the PAXRecords field to set it themselves.\nvar basicKeys = map[string]bool{\n\tpaxPath: true, paxLinkpath: true, paxSize: true, paxUid: true, paxGid: true,\n\tpaxUname: true, paxGname: true, paxMtime: true, paxAtime: true, paxCtime: true,\n}\n\n// A Header represents a single header in a tar archive.\n// Some fields may not be populated.\n//\n// For forward compatibility, users that retrieve a Header from Reader.Next,\n// mutate it in some ways, and then pass it back to Writer.WriteHeader\n// should do so by creating a new Header and copying the fields\n// that they are interested in preserving.\ntype Header struct {\n\t// Typeflag is the type of header entry.\n\t// The zero value is automatically promoted to either TypeReg or TypeDir\n\t// depending on the presence of a trailing slash in Name.\n\tTypeflag byte\n\n\tName     string // Name of file entry\n\tLinkname string // Target name of link (valid for TypeLink or TypeSymlink)\n\n\tSize  int64  // Logical file size in bytes\n\tMode  int64  // Permission and mode bits\n\tUid   int    // User ID of owner\n\tGid   int    // Group ID of owner\n\tUname string // User name of owner\n\tGname string // Group name of owner\n\n\t// If the Format is unspecified, then Writer.WriteHeader rounds ModTime\n\t// to the nearest second and ignores the AccessTime and ChangeTime fields.\n\t//\n\t// To use AccessTime or ChangeTime, specify the Format as PAX or GNU.\n\t// To use sub-second resolution, specify the Format as PAX.\n\tModTime    time.Time // Modification time\n\tAccessTime time.Time // Access time (requires either PAX or GNU support)\n\tChangeTime time.Time // Change time (requires either PAX or GNU support)\n\n\tDevmajor int64 // Major device number (valid for TypeChar or TypeBlock)\n\tDevminor int64 // Minor device number (valid for TypeChar or TypeBlock)\n\n\t// Xattrs stores extended attributes as PAX records under the\n\t// \"SCHILY.xattr.\" namespace.\n\t//\n\t// The following are semantically equivalent:\n\t//  h.Xattrs[key] = value\n\t//  h.PAXRecords[\"SCHILY.xattr.\"+key] = value\n\t//\n\t// When Writer.WriteHeader is called, the contents of Xattrs will take\n\t// precedence over those in PAXRecords.\n\t//\n\t// Deprecated: Use PAXRecords instead.\n\tXattrs map[string]string\n\n\t// PAXRecords is a map of PAX extended header records.\n\t//\n\t// User-defined records should have keys of the following form:\n\t//\tVENDOR.keyword\n\t// Where VENDOR is some namespace in all uppercase, and keyword may\n\t// not contain the '=' character (e.g., \"GOLANG.pkg.version\").\n\t// The key and value should be non-empty UTF-8 strings.\n\t//\n\t// When Writer.WriteHeader is called, PAX records derived from the\n\t// other fields in Header take precedence over PAXRecords.\n\tPAXRecords map[string]string\n\n\t// Format specifies the format of the tar header.\n\t//\n\t// This is set by Reader.Next as a best-effort guess at the format.\n\t// Since the Reader liberally reads some non-compliant files,\n\t// it is possible for this to be FormatUnknown.\n\t//\n\t// If the format is unspecified when Writer.WriteHeader is called,\n\t// then it uses the first format (in the order of USTAR, PAX, GNU)\n\t// capable of encoding this Header (see Format).\n\tFormat Format\n}\n\n// sparseEntry represents a Length-sized fragment at Offset in the file.\ntype sparseEntry struct{ Offset, Length int64 }\n\nfunc (s sparseEntry) endOffset() int64 { return s.Offset + s.Length }\n\n// A sparse file can be represented as either a sparseDatas or a sparseHoles.\n// As long as the total size is known, they are equivalent and one can be\n// converted to the other form and back. The various tar formats with sparse\n// file support represent sparse files in the sparseDatas form. That is, they\n// specify the fragments in the file that has data, and treat everything else as\n// having zero bytes. As such, the encoding and decoding logic in this package\n// deals with sparseDatas.\n//\n// However, the external API uses sparseHoles instead of sparseDatas because the\n// zero value of sparseHoles logically represents a normal file (i.e., there are\n// no holes in it). On the other hand, the zero value of sparseDatas implies\n// that the file has no data in it, which is rather odd.\n//\n// As an example, if the underlying raw file contains the 10-byte data:\n//\tvar compactFile = \"abcdefgh\"\n//\n// And the sparse map has the following entries:\n//\tvar spd sparseDatas = []sparseEntry{\n//\t\t{Offset: 2,  Length: 5},  // Data fragment for 2..6\n//\t\t{Offset: 18, Length: 3},  // Data fragment for 18..20\n//\t}\n//\tvar sph sparseHoles = []sparseEntry{\n//\t\t{Offset: 0,  Length: 2},  // Hole fragment for 0..1\n//\t\t{Offset: 7,  Length: 11}, // Hole fragment for 7..17\n//\t\t{Offset: 21, Length: 4},  // Hole fragment for 21..24\n//\t}\n//\n// Then the content of the resulting sparse file with a Header.Size of 25 is:\n//\tvar sparseFile = \"\\x00\"*2 + \"abcde\" + \"\\x00\"*11 + \"fgh\" + \"\\x00\"*4\ntype (\n\tsparseDatas []sparseEntry\n\tsparseHoles []sparseEntry\n)\n\n// validateSparseEntries reports whether sp is a valid sparse map.\n// It does not matter whether sp represents data fragments or hole fragments.\nfunc validateSparseEntries(sp []sparseEntry, size int64) bool {\n\t// Validate all sparse entries. These are the same checks as performed by\n\t// the BSD tar utility.\n\tif size < 0 {\n\t\treturn false\n\t}\n\tvar pre sparseEntry\n\tfor _, cur := range sp {\n\t\tswitch {\n\t\tcase cur.Offset < 0 || cur.Length < 0:\n\t\t\treturn false // Negative values are never okay\n\t\tcase cur.Offset > math.MaxInt64-cur.Length:\n\t\t\treturn false // Integer overflow with large length\n\t\tcase cur.endOffset() > size:\n\t\t\treturn false // Region extends beyond the actual size\n\t\tcase pre.endOffset() > cur.Offset:\n\t\t\treturn false // Regions cannot overlap and must be in order\n\t\t}\n\t\tpre = cur\n\t}\n\treturn true\n}\n\n// alignSparseEntries mutates src and returns dst where each fragment's\n// starting offset is aligned up to the nearest block edge, and each\n// ending offset is aligned down to the nearest block edge.\n//\n// Even though the Go tar Reader and the BSD tar utility can handle entries\n// with arbitrary offsets and lengths, the GNU tar utility can only handle\n// offsets and lengths that are multiples of blockSize.\nfunc alignSparseEntries(src []sparseEntry, size int64) []sparseEntry {\n\tdst := src[:0]\n\tfor _, s := range src {\n\t\tpos, end := s.Offset, s.endOffset()\n\t\tpos += blockPadding(+pos) // Round-up to nearest blockSize\n\t\tif end != size {\n\t\t\tend -= blockPadding(-end) // Round-down to nearest blockSize\n\t\t}\n\t\tif pos < end {\n\t\t\tdst = append(dst, sparseEntry{Offset: pos, Length: end - pos})\n\t\t}\n\t}\n\treturn dst\n}\n\n// invertSparseEntries converts a sparse map from one form to the other.\n// If the input is sparseHoles, then it will output sparseDatas and vice-versa.\n// The input must have been already validated.\n//\n// This function mutates src and returns a normalized map where:\n//\t* adjacent fragments are coalesced together\n//\t* only the last fragment may be empty\n//\t* the endOffset of the last fragment is the total size\nfunc invertSparseEntries(src []sparseEntry, size int64) []sparseEntry {\n\tdst := src[:0]\n\tvar pre sparseEntry\n\tfor _, cur := range src {\n\t\tif cur.Length == 0 {\n\t\t\tcontinue // Skip empty fragments\n\t\t}\n\t\tpre.Length = cur.Offset - pre.Offset\n\t\tif pre.Length > 0 {\n\t\t\tdst = append(dst, pre) // Only add non-empty fragments\n\t\t}\n\t\tpre.Offset = cur.endOffset()\n\t}\n\tpre.Length = size - pre.Offset // Possibly the only empty fragment\n\treturn append(dst, pre)\n}\n\n// fileState tracks the number of logical (includes sparse holes) and physical\n// (actual in tar archive) bytes remaining for the current file.\n//\n// Invariant: LogicalRemaining >= PhysicalRemaining\ntype fileState interface {\n\tLogicalRemaining() int64\n\tPhysicalRemaining() int64\n}\n\n// allowedFormats determines which formats can be used.\n// The value returned is the logical OR of multiple possible formats.\n// If the value is FormatUnknown, then the input Header cannot be encoded\n// and an error is returned explaining why.\n//\n// As a by-product of checking the fields, this function returns paxHdrs, which\n// contain all fields that could not be directly encoded.\n// A value receiver ensures that this method does not mutate the source Header.\nfunc (h Header) allowedFormats() (format Format, paxHdrs map[string]string, err error) {\n\tformat = FormatUSTAR | FormatPAX | FormatGNU\n\tpaxHdrs = make(map[string]string)\n\n\tvar whyNoUSTAR, whyNoPAX, whyNoGNU string\n\tvar preferPAX bool // Prefer PAX over USTAR\n\tverifyString := func(s string, size int, name, paxKey string) {\n\t\t// NUL-terminator is optional for path and linkpath.\n\t\t// Technically, it is required for uname and gname,\n\t\t// but neither GNU nor BSD tar checks for it.\n\t\ttooLong := len(s) > size\n\t\tallowLongGNU := paxKey == paxPath || paxKey == paxLinkpath\n\t\tif hasNUL(s) || (tooLong && !allowLongGNU) {\n\t\t\twhyNoGNU = fmt.Sprintf(\"GNU cannot encode %s=%q\", name, s)\n\t\t\tformat.mustNotBe(FormatGNU)\n\t\t}\n\t\tif !isASCII(s) || tooLong {\n\t\t\tcanSplitUSTAR := paxKey == paxPath\n\t\t\tif _, _, ok := splitUSTARPath(s); !canSplitUSTAR || !ok {\n\t\t\t\twhyNoUSTAR = fmt.Sprintf(\"USTAR cannot encode %s=%q\", name, s)\n\t\t\t\tformat.mustNotBe(FormatUSTAR)\n\t\t\t}\n\t\t\tif paxKey == paxNone {\n\t\t\t\twhyNoPAX = fmt.Sprintf(\"PAX cannot encode %s=%q\", name, s)\n\t\t\t\tformat.mustNotBe(FormatPAX)\n\t\t\t} else {\n\t\t\t\tpaxHdrs[paxKey] = s\n\t\t\t}\n\t\t}\n\t\tif v, ok := h.PAXRecords[paxKey]; ok && v == s {\n\t\t\tpaxHdrs[paxKey] = v\n\t\t}\n\t}\n\tverifyNumeric := func(n int64, size int, name, paxKey string) {\n\t\tif !fitsInBase256(size, n) {\n\t\t\twhyNoGNU = fmt.Sprintf(\"GNU cannot encode %s=%d\", name, n)\n\t\t\tformat.mustNotBe(FormatGNU)\n\t\t}\n\t\tif !fitsInOctal(size, n) {\n\t\t\twhyNoUSTAR = fmt.Sprintf(\"USTAR cannot encode %s=%d\", name, n)\n\t\t\tformat.mustNotBe(FormatUSTAR)\n\t\t\tif paxKey == paxNone {\n\t\t\t\twhyNoPAX = fmt.Sprintf(\"PAX cannot encode %s=%d\", name, n)\n\t\t\t\tformat.mustNotBe(FormatPAX)\n\t\t\t} else {\n\t\t\t\tpaxHdrs[paxKey] = strconv.FormatInt(n, 10)\n\t\t\t}\n\t\t}\n\t\tif v, ok := h.PAXRecords[paxKey]; ok && v == strconv.FormatInt(n, 10) {\n\t\t\tpaxHdrs[paxKey] = v\n\t\t}\n\t}\n\tverifyTime := func(ts time.Time, size int, name, paxKey string) {\n\t\tif ts.IsZero() {\n\t\t\treturn // Always okay\n\t\t}\n\t\tif !fitsInBase256(size, ts.Unix()) {\n\t\t\twhyNoGNU = fmt.Sprintf(\"GNU cannot encode %s=%v\", name, ts)\n\t\t\tformat.mustNotBe(FormatGNU)\n\t\t}\n\t\tisMtime := paxKey == paxMtime\n\t\tfitsOctal := fitsInOctal(size, ts.Unix())\n\t\tif (isMtime && !fitsOctal) || !isMtime {\n\t\t\twhyNoUSTAR = fmt.Sprintf(\"USTAR cannot encode %s=%v\", name, ts)\n\t\t\tformat.mustNotBe(FormatUSTAR)\n\t\t}\n\t\tneedsNano := ts.Nanosecond() != 0\n\t\tif !isMtime || !fitsOctal || needsNano {\n\t\t\tpreferPAX = true // USTAR may truncate sub-second measurements\n\t\t\tif paxKey == paxNone {\n\t\t\t\twhyNoPAX = fmt.Sprintf(\"PAX cannot encode %s=%v\", name, ts)\n\t\t\t\tformat.mustNotBe(FormatPAX)\n\t\t\t} else {\n\t\t\t\tpaxHdrs[paxKey] = formatPAXTime(ts)\n\t\t\t}\n\t\t}\n\t\tif v, ok := h.PAXRecords[paxKey]; ok && v == formatPAXTime(ts) {\n\t\t\tpaxHdrs[paxKey] = v\n\t\t}\n\t}\n\n\t// Check basic fields.\n\tvar blk block\n\tv7 := blk.V7()\n\tustar := blk.USTAR()\n\tgnu := blk.GNU()\n\tverifyString(h.Name, len(v7.Name()), \"Name\", paxPath)\n\tverifyString(h.Linkname, len(v7.LinkName()), \"Linkname\", paxLinkpath)\n\tverifyString(h.Uname, len(ustar.UserName()), \"Uname\", paxUname)\n\tverifyString(h.Gname, len(ustar.GroupName()), \"Gname\", paxGname)\n\tverifyNumeric(h.Mode, len(v7.Mode()), \"Mode\", paxNone)\n\tverifyNumeric(int64(h.Uid), len(v7.UID()), \"Uid\", paxUid)\n\tverifyNumeric(int64(h.Gid), len(v7.GID()), \"Gid\", paxGid)\n\tverifyNumeric(h.Size, len(v7.Size()), \"Size\", paxSize)\n\tverifyNumeric(h.Devmajor, len(ustar.DevMajor()), \"Devmajor\", paxNone)\n\tverifyNumeric(h.Devminor, len(ustar.DevMinor()), \"Devminor\", paxNone)\n\tverifyTime(h.ModTime, len(v7.ModTime()), \"ModTime\", paxMtime)\n\tverifyTime(h.AccessTime, len(gnu.AccessTime()), \"AccessTime\", paxAtime)\n\tverifyTime(h.ChangeTime, len(gnu.ChangeTime()), \"ChangeTime\", paxCtime)\n\n\t// Check for header-only types.\n\tvar whyOnlyPAX, whyOnlyGNU string\n\tswitch h.Typeflag {\n\tcase TypeReg, TypeChar, TypeBlock, TypeFifo, TypeGNUSparse:\n\t\t// Exclude TypeLink and TypeSymlink, since they may reference directories.\n\t\tif strings.HasSuffix(h.Name, \"/\") {\n\t\t\treturn FormatUnknown, nil, headerError{\"filename may not have trailing slash\"}\n\t\t}\n\tcase TypeXHeader, TypeGNULongName, TypeGNULongLink:\n\t\treturn FormatUnknown, nil, headerError{\"cannot manually encode TypeXHeader, TypeGNULongName, or TypeGNULongLink headers\"}\n\tcase TypeXGlobalHeader:\n\t\th2 := Header{Name: h.Name, Typeflag: h.Typeflag, Xattrs: h.Xattrs, PAXRecords: h.PAXRecords, Format: h.Format}\n\t\tif !reflect.DeepEqual(h, h2) {\n\t\t\treturn FormatUnknown, nil, headerError{\"only PAXRecords should be set for TypeXGlobalHeader\"}\n\t\t}\n\t\twhyOnlyPAX = \"only PAX supports TypeXGlobalHeader\"\n\t\tformat.mayOnlyBe(FormatPAX)\n\t}\n\tif !isHeaderOnlyType(h.Typeflag) && h.Size < 0 {\n\t\treturn FormatUnknown, nil, headerError{\"negative size on header-only type\"}\n\t}\n\n\t// Check PAX records.\n\tif len(h.Xattrs) > 0 {\n\t\tfor k, v := range h.Xattrs {\n\t\t\tpaxHdrs[paxSchilyXattr+k] = v\n\t\t}\n\t\twhyOnlyPAX = \"only PAX supports Xattrs\"\n\t\tformat.mayOnlyBe(FormatPAX)\n\t}\n\tif len(h.PAXRecords) > 0 {\n\t\tfor k, v := range h.PAXRecords {\n\t\t\tswitch _, exists := paxHdrs[k]; {\n\t\t\tcase exists:\n\t\t\t\tcontinue // Do not overwrite existing records\n\t\t\tcase h.Typeflag == TypeXGlobalHeader:\n\t\t\t\tpaxHdrs[k] = v // Copy all records\n\t\t\tcase !basicKeys[k] && !strings.HasPrefix(k, paxGNUSparse):\n\t\t\t\tpaxHdrs[k] = v // Ignore local records that may conflict\n\t\t\t}\n\t\t}\n\t\twhyOnlyPAX = \"only PAX supports PAXRecords\"\n\t\tformat.mayOnlyBe(FormatPAX)\n\t}\n\tfor k, v := range paxHdrs {\n\t\tif !validPAXRecord(k, v) {\n\t\t\treturn FormatUnknown, nil, headerError{fmt.Sprintf(\"invalid PAX record: %q\", k+\" = \"+v)}\n\t\t}\n\t}\n\n\t// TODO(dsnet): Re-enable this when adding sparse support.\n\t// See https://golang.org/issue/22735\n\t/*\n\t\t// Check sparse files.\n\t\tif len(h.SparseHoles) > 0 || h.Typeflag == TypeGNUSparse {\n\t\t\tif isHeaderOnlyType(h.Typeflag) {\n\t\t\t\treturn FormatUnknown, nil, headerError{\"header-only type cannot be sparse\"}\n\t\t\t}\n\t\t\tif !validateSparseEntries(h.SparseHoles, h.Size) {\n\t\t\t\treturn FormatUnknown, nil, headerError{\"invalid sparse holes\"}\n\t\t\t}\n\t\t\tif h.Typeflag == TypeGNUSparse {\n\t\t\t\twhyOnlyGNU = \"only GNU supports TypeGNUSparse\"\n\t\t\t\tformat.mayOnlyBe(FormatGNU)\n\t\t\t} else {\n\t\t\t\twhyNoGNU = \"GNU supports sparse files only with TypeGNUSparse\"\n\t\t\t\tformat.mustNotBe(FormatGNU)\n\t\t\t}\n\t\t\twhyNoUSTAR = \"USTAR does not support sparse files\"\n\t\t\tformat.mustNotBe(FormatUSTAR)\n\t\t}\n\t*/\n\n\t// Check desired format.\n\tif wantFormat := h.Format; wantFormat != FormatUnknown {\n\t\tif wantFormat.has(FormatPAX) && !preferPAX {\n\t\t\twantFormat.mayBe(FormatUSTAR) // PAX implies USTAR allowed too\n\t\t}\n\t\tformat.mayOnlyBe(wantFormat) // Set union of formats allowed and format wanted\n\t}\n\tif format == FormatUnknown {\n\t\tswitch h.Format {\n\t\tcase FormatUSTAR:\n\t\t\terr = headerError{\"Format specifies USTAR\", whyNoUSTAR, whyOnlyPAX, whyOnlyGNU}\n\t\tcase FormatPAX:\n\t\t\terr = headerError{\"Format specifies PAX\", whyNoPAX, whyOnlyGNU}\n\t\tcase FormatGNU:\n\t\t\terr = headerError{\"Format specifies GNU\", whyNoGNU, whyOnlyPAX}\n\t\tdefault:\n\t\t\terr = headerError{whyNoUSTAR, whyNoPAX, whyNoGNU, whyOnlyPAX, whyOnlyGNU}\n\t\t}\n\t}\n\treturn format, paxHdrs, err\n}\n\n// FileInfo returns an os.FileInfo for the Header.\nfunc (h *Header) FileInfo() os.FileInfo {\n\treturn headerFileInfo{h}\n}\n\n// headerFileInfo implements os.FileInfo.\ntype headerFileInfo struct {\n\th *Header\n}\n\nfunc (fi headerFileInfo) Size() int64        { return fi.h.Size }\nfunc (fi headerFileInfo) IsDir() bool        { return fi.Mode().IsDir() }\nfunc (fi headerFileInfo) ModTime() time.Time { return fi.h.ModTime }\nfunc (fi headerFileInfo) Sys() interface{}   { return fi.h }\n\n// Name returns the base name of the file.\nfunc (fi headerFileInfo) Name() string {\n\tif fi.IsDir() {\n\t\treturn path.Base(path.Clean(fi.h.Name))\n\t}\n\treturn path.Base(fi.h.Name)\n}\n\n// Mode returns the permission and mode bits for the headerFileInfo.\nfunc (fi headerFileInfo) Mode() (mode os.FileMode) {\n\t// Set file permission bits.\n\tmode = os.FileMode(fi.h.Mode).Perm()\n\n\t// Set setuid, setgid and sticky bits.\n\tif fi.h.Mode&c_ISUID != 0 {\n\t\tmode |= os.ModeSetuid\n\t}\n\tif fi.h.Mode&c_ISGID != 0 {\n\t\tmode |= os.ModeSetgid\n\t}\n\tif fi.h.Mode&c_ISVTX != 0 {\n\t\tmode |= os.ModeSticky\n\t}\n\n\t// Set file mode bits; clear perm, setuid, setgid, and sticky bits.\n\tswitch m := os.FileMode(fi.h.Mode) &^ 07777; m {\n\tcase c_ISDIR:\n\t\tmode |= os.ModeDir\n\tcase c_ISFIFO:\n\t\tmode |= os.ModeNamedPipe\n\tcase c_ISLNK:\n\t\tmode |= os.ModeSymlink\n\tcase c_ISBLK:\n\t\tmode |= os.ModeDevice\n\tcase c_ISCHR:\n\t\tmode |= os.ModeDevice\n\t\tmode |= os.ModeCharDevice\n\tcase c_ISSOCK:\n\t\tmode |= os.ModeSocket\n\t}\n\n\tswitch fi.h.Typeflag {\n\tcase TypeSymlink:\n\t\tmode |= os.ModeSymlink\n\tcase TypeChar:\n\t\tmode |= os.ModeDevice\n\t\tmode |= os.ModeCharDevice\n\tcase TypeBlock:\n\t\tmode |= os.ModeDevice\n\tcase TypeDir:\n\t\tmode |= os.ModeDir\n\tcase TypeFifo:\n\t\tmode |= os.ModeNamedPipe\n\t}\n\n\treturn mode\n}\n\n// sysStat, if non-nil, populates h from system-dependent fields of fi.\nvar sysStat func(fi os.FileInfo, h *Header) error\n\nconst (\n\t// Mode constants from the USTAR spec:\n\t// See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06\n\tc_ISUID = 04000 // Set uid\n\tc_ISGID = 02000 // Set gid\n\tc_ISVTX = 01000 // Save text (sticky bit)\n\n\t// Common Unix mode constants; these are not defined in any common tar standard.\n\t// Header.FileInfo understands these, but FileInfoHeader will never produce these.\n\tc_ISDIR  = 040000  // Directory\n\tc_ISFIFO = 010000  // FIFO\n\tc_ISREG  = 0100000 // Regular file\n\tc_ISLNK  = 0120000 // Symbolic link\n\tc_ISBLK  = 060000  // Block special file\n\tc_ISCHR  = 020000  // Character special file\n\tc_ISSOCK = 0140000 // Socket\n)\n\n// FileInfoHeader creates a partially-populated Header from fi.\n// If fi describes a symlink, FileInfoHeader records link as the link target.\n// If fi describes a directory, a slash is appended to the name.\n//\n// Since os.FileInfo's Name method only returns the base name of\n// the file it describes, it may be necessary to modify Header.Name\n// to provide the full path name of the file.\nfunc FileInfoHeader(fi os.FileInfo, link string) (*Header, error) {\n\tif fi == nil {\n\t\treturn nil, errors.New(\"archive/tar: FileInfo is nil\")\n\t}\n\tfm := fi.Mode()\n\th := &Header{\n\t\tName:    fi.Name(),\n\t\tModTime: fi.ModTime(),\n\t\tMode:    int64(fm.Perm()), // or'd with c_IS* constants later\n\t}\n\tswitch {\n\tcase fm.IsRegular():\n\t\th.Typeflag = TypeReg\n\t\th.Size = fi.Size()\n\tcase fi.IsDir():\n\t\th.Typeflag = TypeDir\n\t\th.Name += \"/\"\n\tcase fm&os.ModeSymlink != 0:\n\t\th.Typeflag = TypeSymlink\n\t\th.Linkname = link\n\tcase fm&os.ModeDevice != 0:\n\t\tif fm&os.ModeCharDevice != 0 {\n\t\t\th.Typeflag = TypeChar\n\t\t} else {\n\t\t\th.Typeflag = TypeBlock\n\t\t}\n\tcase fm&os.ModeNamedPipe != 0:\n\t\th.Typeflag = TypeFifo\n\tcase fm&os.ModeSocket != 0:\n\t\treturn nil, fmt.Errorf(\"archive/tar: sockets not supported\")\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"archive/tar: unknown file mode %v\", fm)\n\t}\n\tif fm&os.ModeSetuid != 0 {\n\t\th.Mode |= c_ISUID\n\t}\n\tif fm&os.ModeSetgid != 0 {\n\t\th.Mode |= c_ISGID\n\t}\n\tif fm&os.ModeSticky != 0 {\n\t\th.Mode |= c_ISVTX\n\t}\n\t// If possible, populate additional fields from OS-specific\n\t// FileInfo fields.\n\tif sys, ok := fi.Sys().(*Header); ok {\n\t\t// This FileInfo came from a Header (not the OS). Use the\n\t\t// original Header to populate all remaining fields.\n\t\th.Uid = sys.Uid\n\t\th.Gid = sys.Gid\n\t\th.Uname = sys.Uname\n\t\th.Gname = sys.Gname\n\t\th.AccessTime = sys.AccessTime\n\t\th.ChangeTime = sys.ChangeTime\n\t\tif sys.Xattrs != nil {\n\t\t\th.Xattrs = make(map[string]string)\n\t\t\tfor k, v := range sys.Xattrs {\n\t\t\t\th.Xattrs[k] = v\n\t\t\t}\n\t\t}\n\t\tif sys.Typeflag == TypeLink {\n\t\t\t// hard link\n\t\t\th.Typeflag = TypeLink\n\t\t\th.Size = 0\n\t\t\th.Linkname = sys.Linkname\n\t\t}\n\t\tif sys.PAXRecords != nil {\n\t\t\th.PAXRecords = make(map[string]string)\n\t\t\tfor k, v := range sys.PAXRecords {\n\t\t\t\th.PAXRecords[k] = v\n\t\t\t}\n\t\t}\n\t}\n\tif sysStat != nil {\n\t\treturn h, sysStat(fi, h)\n\t}\n\treturn h, nil\n}\n\n// isHeaderOnlyType checks if the given type flag is of the type that has no\n// data section even if a size is specified.\nfunc isHeaderOnlyType(flag byte) bool {\n\tswitch flag {\n\tcase TypeLink, TypeSymlink, TypeChar, TypeBlock, TypeDir, TypeFifo:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc min(a, b int64) int64 {\n\tif a < b {\n\t\treturn a\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/archive/tar/format.go",
    "content": "// Copyright 2016 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 tar\n\nimport \"strings\"\n\n// Format represents the tar archive format.\n//\n// The original tar format was introduced in Unix V7.\n// Since then, there have been multiple competing formats attempting to\n// standardize or extend the V7 format to overcome its limitations.\n// The most common formats are the USTAR, PAX, and GNU formats,\n// each with their own advantages and limitations.\n//\n// The following table captures the capabilities of each format:\n//\n//\t                  |  USTAR |       PAX |       GNU\n//\t------------------+--------+-----------+----------\n//\tName              |   256B | unlimited | unlimited\n//\tLinkname          |   100B | unlimited | unlimited\n//\tSize              | uint33 | unlimited |    uint89\n//\tMode              | uint21 |    uint21 |    uint57\n//\tUid/Gid           | uint21 | unlimited |    uint57\n//\tUname/Gname       |    32B | unlimited |       32B\n//\tModTime           | uint33 | unlimited |     int89\n//\tAccessTime        |    n/a | unlimited |     int89\n//\tChangeTime        |    n/a | unlimited |     int89\n//\tDevmajor/Devminor | uint21 |    uint21 |    uint57\n//\t------------------+--------+-----------+----------\n//\tstring encoding   |  ASCII |     UTF-8 |    binary\n//\tsub-second times  |     no |       yes |        no\n//\tsparse files      |     no |       yes |       yes\n//\n// The table's upper portion shows the Header fields, where each format reports\n// the maximum number of bytes allowed for each string field and\n// the integer type used to store each numeric field\n// (where timestamps are stored as the number of seconds since the Unix epoch).\n//\n// The table's lower portion shows specialized features of each format,\n// such as supported string encodings, support for sub-second timestamps,\n// or support for sparse files.\n//\n// The Writer currently provides no support for sparse files.\ntype Format int\n\n// Constants to identify various tar formats.\nconst (\n\t// Deliberately hide the meaning of constants from public API.\n\t_ Format = (1 << iota) / 4 // Sequence of 0, 0, 1, 2, 4, 8, etc...\n\n\t// FormatUnknown indicates that the format is unknown.\n\tFormatUnknown\n\n\t// The format of the original Unix V7 tar tool prior to standardization.\n\tformatV7\n\n\t// FormatUSTAR represents the USTAR header format defined in POSIX.1-1988.\n\t//\n\t// While this format is compatible with most tar readers,\n\t// the format has several limitations making it unsuitable for some usages.\n\t// Most notably, it cannot support sparse files, files larger than 8GiB,\n\t// filenames larger than 256 characters, and non-ASCII filenames.\n\t//\n\t// Reference:\n\t//\thttp://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html#tag_20_92_13_06\n\tFormatUSTAR\n\n\t// FormatPAX represents the PAX header format defined in POSIX.1-2001.\n\t//\n\t// PAX extends USTAR by writing a special file with Typeflag TypeXHeader\n\t// preceding the original header. This file contains a set of key-value\n\t// records, which are used to overcome USTAR's shortcomings, in addition to\n\t// providing the ability to have sub-second resolution for timestamps.\n\t//\n\t// Some newer formats add their own extensions to PAX by defining their\n\t// own keys and assigning certain semantic meaning to the associated values.\n\t// For example, sparse file support in PAX is implemented using keys\n\t// defined by the GNU manual (e.g., \"GNU.sparse.map\").\n\t//\n\t// Reference:\n\t//\thttp://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html\n\tFormatPAX\n\n\t// FormatGNU represents the GNU header format.\n\t//\n\t// The GNU header format is older than the USTAR and PAX standards and\n\t// is not compatible with them. The GNU format supports\n\t// arbitrary file sizes, filenames of arbitrary encoding and length,\n\t// sparse files, and other features.\n\t//\n\t// It is recommended that PAX be chosen over GNU unless the target\n\t// application can only parse GNU formatted archives.\n\t//\n\t// Reference:\n\t//\thttps://www.gnu.org/software/tar/manual/html_node/Standard.html\n\tFormatGNU\n\n\t// Schily's tar format, which is incompatible with USTAR.\n\t// This does not cover STAR extensions to the PAX format; these fall under\n\t// the PAX format.\n\tformatSTAR\n\n\tformatMax\n)\n\nfunc (f Format) has(f2 Format) bool   { return f&f2 != 0 }\nfunc (f *Format) mayBe(f2 Format)     { *f |= f2 }\nfunc (f *Format) mayOnlyBe(f2 Format) { *f &= f2 }\nfunc (f *Format) mustNotBe(f2 Format) { *f &^= f2 }\n\nvar formatNames = map[Format]string{\n\tformatV7: \"V7\", FormatUSTAR: \"USTAR\", FormatPAX: \"PAX\", FormatGNU: \"GNU\", formatSTAR: \"STAR\",\n}\n\nfunc (f Format) String() string {\n\tvar ss []string\n\tfor f2 := Format(1); f2 < formatMax; f2 <<= 1 {\n\t\tif f.has(f2) {\n\t\t\tss = append(ss, formatNames[f2])\n\t\t}\n\t}\n\tswitch len(ss) {\n\tcase 0:\n\t\treturn \"<unknown>\"\n\tcase 1:\n\t\treturn ss[0]\n\tdefault:\n\t\treturn \"(\" + strings.Join(ss, \" | \") + \")\"\n\t}\n}\n\n// Magics used to identify various formats.\nconst (\n\tmagicGNU, versionGNU     = \"ustar \", \" \\x00\"\n\tmagicUSTAR, versionUSTAR = \"ustar\\x00\", \"00\"\n\ttrailerSTAR              = \"tar\\x00\"\n)\n\n// Size constants from various tar specifications.\nconst (\n\tblockSize  = 512 // Size of each block in a tar stream\n\tnameSize   = 100 // Max length of the name field in USTAR format\n\tprefixSize = 155 // Max length of the prefix field in USTAR format\n)\n\n// blockPadding computes the number of bytes needed to pad offset up to the\n// nearest block edge where 0 <= n < blockSize.\nfunc blockPadding(offset int64) (n int64) {\n\treturn -offset & (blockSize - 1)\n}\n\nvar zeroBlock block\n\ntype block [blockSize]byte\n\n// Convert block to any number of formats.\nfunc (b *block) V7() *headerV7       { return (*headerV7)(b) }\nfunc (b *block) GNU() *headerGNU     { return (*headerGNU)(b) }\nfunc (b *block) STAR() *headerSTAR   { return (*headerSTAR)(b) }\nfunc (b *block) USTAR() *headerUSTAR { return (*headerUSTAR)(b) }\nfunc (b *block) Sparse() sparseArray { return (sparseArray)(b[:]) }\n\n// GetFormat checks that the block is a valid tar header based on the checksum.\n// It then attempts to guess the specific format based on magic values.\n// If the checksum fails, then FormatUnknown is returned.\nfunc (b *block) GetFormat() Format {\n\t// Verify checksum.\n\tvar p parser\n\tvalue := p.parseOctal(b.V7().Chksum())\n\tchksum1, chksum2 := b.ComputeChecksum()\n\tif p.err != nil || (value != chksum1 && value != chksum2) {\n\t\treturn FormatUnknown\n\t}\n\n\t// Guess the magic values.\n\tmagic := string(b.USTAR().Magic())\n\tversion := string(b.USTAR().Version())\n\ttrailer := string(b.STAR().Trailer())\n\tswitch {\n\tcase magic == magicUSTAR && trailer == trailerSTAR:\n\t\treturn formatSTAR\n\tcase magic == magicUSTAR:\n\t\treturn FormatUSTAR | FormatPAX\n\tcase magic == magicGNU && version == versionGNU:\n\t\treturn FormatGNU\n\tdefault:\n\t\treturn formatV7\n\t}\n}\n\n// SetFormat writes the magic values necessary for specified format\n// and then updates the checksum accordingly.\nfunc (b *block) SetFormat(format Format) {\n\t// Set the magic values.\n\tswitch {\n\tcase format.has(formatV7):\n\t\t// Do nothing.\n\tcase format.has(FormatGNU):\n\t\tcopy(b.GNU().Magic(), magicGNU)\n\t\tcopy(b.GNU().Version(), versionGNU)\n\tcase format.has(formatSTAR):\n\t\tcopy(b.STAR().Magic(), magicUSTAR)\n\t\tcopy(b.STAR().Version(), versionUSTAR)\n\t\tcopy(b.STAR().Trailer(), trailerSTAR)\n\tcase format.has(FormatUSTAR | FormatPAX):\n\t\tcopy(b.USTAR().Magic(), magicUSTAR)\n\t\tcopy(b.USTAR().Version(), versionUSTAR)\n\tdefault:\n\t\tpanic(\"invalid format\")\n\t}\n\n\t// Update checksum.\n\t// This field is special in that it is terminated by a NULL then space.\n\tvar f formatter\n\tfield := b.V7().Chksum()\n\tchksum, _ := b.ComputeChecksum() // Possible values are 256..128776\n\tf.formatOctal(field[:7], chksum) // Never fails since 128776 < 262143\n\tfield[7] = ' '\n}\n\n// ComputeChecksum computes the checksum for the header block.\n// POSIX specifies a sum of the unsigned byte values, but the Sun tar used\n// signed byte values.\n// We compute and return both.\nfunc (b *block) ComputeChecksum() (unsigned, signed int64) {\n\tfor i, c := range b {\n\t\tif 148 <= i && i < 156 {\n\t\t\tc = ' ' // Treat the checksum field itself as all spaces.\n\t\t}\n\t\tunsigned += int64(c)\n\t\tsigned += int64(int8(c))\n\t}\n\treturn unsigned, signed\n}\n\n// Reset clears the block with all zeros.\nfunc (b *block) Reset() {\n\t*b = block{}\n}\n\ntype headerV7 [blockSize]byte\n\nfunc (h *headerV7) Name() []byte     { return h[000:][:100] }\nfunc (h *headerV7) Mode() []byte     { return h[100:][:8] }\nfunc (h *headerV7) UID() []byte      { return h[108:][:8] }\nfunc (h *headerV7) GID() []byte      { return h[116:][:8] }\nfunc (h *headerV7) Size() []byte     { return h[124:][:12] }\nfunc (h *headerV7) ModTime() []byte  { return h[136:][:12] }\nfunc (h *headerV7) Chksum() []byte   { return h[148:][:8] }\nfunc (h *headerV7) TypeFlag() []byte { return h[156:][:1] }\nfunc (h *headerV7) LinkName() []byte { return h[157:][:100] }\n\ntype headerGNU [blockSize]byte\n\nfunc (h *headerGNU) V7() *headerV7       { return (*headerV7)(h) }\nfunc (h *headerGNU) Magic() []byte       { return h[257:][:6] }\nfunc (h *headerGNU) Version() []byte     { return h[263:][:2] }\nfunc (h *headerGNU) UserName() []byte    { return h[265:][:32] }\nfunc (h *headerGNU) GroupName() []byte   { return h[297:][:32] }\nfunc (h *headerGNU) DevMajor() []byte    { return h[329:][:8] }\nfunc (h *headerGNU) DevMinor() []byte    { return h[337:][:8] }\nfunc (h *headerGNU) AccessTime() []byte  { return h[345:][:12] }\nfunc (h *headerGNU) ChangeTime() []byte  { return h[357:][:12] }\nfunc (h *headerGNU) Sparse() sparseArray { return (sparseArray)(h[386:][:24*4+1]) }\nfunc (h *headerGNU) RealSize() []byte    { return h[483:][:12] }\n\ntype headerSTAR [blockSize]byte\n\nfunc (h *headerSTAR) V7() *headerV7      { return (*headerV7)(h) }\nfunc (h *headerSTAR) Magic() []byte      { return h[257:][:6] }\nfunc (h *headerSTAR) Version() []byte    { return h[263:][:2] }\nfunc (h *headerSTAR) UserName() []byte   { return h[265:][:32] }\nfunc (h *headerSTAR) GroupName() []byte  { return h[297:][:32] }\nfunc (h *headerSTAR) DevMajor() []byte   { return h[329:][:8] }\nfunc (h *headerSTAR) DevMinor() []byte   { return h[337:][:8] }\nfunc (h *headerSTAR) Prefix() []byte     { return h[345:][:131] }\nfunc (h *headerSTAR) AccessTime() []byte { return h[476:][:12] }\nfunc (h *headerSTAR) ChangeTime() []byte { return h[488:][:12] }\nfunc (h *headerSTAR) Trailer() []byte    { return h[508:][:4] }\n\ntype headerUSTAR [blockSize]byte\n\nfunc (h *headerUSTAR) V7() *headerV7     { return (*headerV7)(h) }\nfunc (h *headerUSTAR) Magic() []byte     { return h[257:][:6] }\nfunc (h *headerUSTAR) Version() []byte   { return h[263:][:2] }\nfunc (h *headerUSTAR) UserName() []byte  { return h[265:][:32] }\nfunc (h *headerUSTAR) GroupName() []byte { return h[297:][:32] }\nfunc (h *headerUSTAR) DevMajor() []byte  { return h[329:][:8] }\nfunc (h *headerUSTAR) DevMinor() []byte  { return h[337:][:8] }\nfunc (h *headerUSTAR) Prefix() []byte    { return h[345:][:155] }\n\ntype sparseArray []byte\n\nfunc (s sparseArray) Entry(i int) sparseElem { return (sparseElem)(s[i*24:]) }\nfunc (s sparseArray) IsExtended() []byte     { return s[24*s.MaxEntries():][:1] }\nfunc (s sparseArray) MaxEntries() int        { return len(s) / 24 }\n\ntype sparseElem []byte\n\nfunc (s sparseElem) Offset() []byte { return s[00:][:12] }\nfunc (s sparseElem) Length() []byte { return s[12:][:12] }\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/archive/tar/reader.go",
    "content": "// Copyright 2009 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 tar\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Reader provides sequential access to the contents of a tar archive.\n// Reader.Next advances to the next file in the archive (including the first),\n// and then Reader can be treated as an io.Reader to access the file's data.\ntype Reader struct {\n\tr    io.Reader\n\tpad  int64      // Amount of padding (ignored) after current file entry\n\tcurr fileReader // Reader for current file entry\n\tblk  block      // Buffer to use as temporary local storage\n\n\t// err is a persistent error.\n\t// It is only the responsibility of every exported method of Reader to\n\t// ensure that this error is sticky.\n\terr error\n\n\tRawAccounting bool          // Whether to enable the access needed to reassemble the tar from raw bytes. Some performance/memory hit for this.\n\trawBytes      *bytes.Buffer // last raw bits\n}\n\ntype fileReader interface {\n\tio.Reader\n\tfileState\n\n\tWriteTo(io.Writer) (int64, error)\n}\n\n// RawBytes accesses the raw bytes of the archive, apart from the file payload itself.\n// This includes the header and padding.\n//\n// # This call resets the current rawbytes buffer\n//\n// Only when RawAccounting is enabled, otherwise this returns nil\nfunc (tr *Reader) RawBytes() []byte {\n\tif !tr.RawAccounting {\n\t\treturn nil\n\t}\n\tif tr.rawBytes == nil {\n\t\ttr.rawBytes = bytes.NewBuffer(nil)\n\t}\n\tdefer tr.rawBytes.Reset() // if we've read them, then flush them.\n\n\treturn tr.rawBytes.Bytes()\n\n}\n\n// NewReader creates a new Reader reading from r.\nfunc NewReader(r io.Reader) *Reader {\n\treturn &Reader{r: r, curr: &regFileReader{r, 0}}\n}\n\n// Next advances to the next entry in the tar archive.\n// The Header.Size determines how many bytes can be read for the next file.\n// Any remaining data in the current file is automatically discarded.\n//\n// io.EOF is returned at the end of the input.\nfunc (tr *Reader) Next() (*Header, error) {\n\tif tr.err != nil {\n\t\treturn nil, tr.err\n\t}\n\thdr, err := tr.next()\n\ttr.err = err\n\treturn hdr, err\n}\n\nfunc (tr *Reader) next() (*Header, error) {\n\tvar paxHdrs map[string]string\n\tvar gnuLongName, gnuLongLink string\n\n\tif tr.RawAccounting {\n\t\tif tr.rawBytes == nil {\n\t\t\ttr.rawBytes = bytes.NewBuffer(nil)\n\t\t} else {\n\t\t\ttr.rawBytes.Reset()\n\t\t}\n\t}\n\n\t// Externally, Next iterates through the tar archive as if it is a series of\n\t// files. Internally, the tar format often uses fake \"files\" to add meta\n\t// data that describes the next file. These meta data \"files\" should not\n\t// normally be visible to the outside. As such, this loop iterates through\n\t// one or more \"header files\" until it finds a \"normal file\".\n\tformat := FormatUSTAR | FormatPAX | FormatGNU\n\tfor {\n\t\t// Discard the remainder of the file and any padding.\n\t\tif err := discard(tr, tr.curr.PhysicalRemaining()); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tn, err := tryReadFull(tr.r, tr.blk[:tr.pad])\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif tr.RawAccounting {\n\t\t\ttr.rawBytes.Write(tr.blk[:n])\n\t\t}\n\t\ttr.pad = 0\n\n\t\thdr, rawHdr, err := tr.readHeader()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := tr.handleRegularFile(hdr); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tformat.mayOnlyBe(hdr.Format)\n\n\t\t// Check for PAX/GNU special headers and files.\n\t\tswitch hdr.Typeflag {\n\t\tcase TypeXHeader, TypeXGlobalHeader:\n\t\t\tformat.mayOnlyBe(FormatPAX)\n\t\t\tpaxHdrs, err = parsePAX(tr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif hdr.Typeflag == TypeXGlobalHeader {\n\t\t\t\tif err = mergePAX(hdr, paxHdrs); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn &Header{\n\t\t\t\t\tName:       hdr.Name,\n\t\t\t\t\tTypeflag:   hdr.Typeflag,\n\t\t\t\t\tXattrs:     hdr.Xattrs,\n\t\t\t\t\tPAXRecords: hdr.PAXRecords,\n\t\t\t\t\tFormat:     format,\n\t\t\t\t}, nil\n\t\t\t}\n\t\t\tcontinue // This is a meta header affecting the next header\n\t\tcase TypeGNULongName, TypeGNULongLink:\n\t\t\tformat.mayOnlyBe(FormatGNU)\n\t\t\trealname, err := ioutil.ReadAll(tr)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tif tr.RawAccounting {\n\t\t\t\ttr.rawBytes.Write(realname)\n\t\t\t}\n\n\t\t\tvar p parser\n\t\t\tswitch hdr.Typeflag {\n\t\t\tcase TypeGNULongName:\n\t\t\t\tgnuLongName = p.parseString(realname)\n\t\t\tcase TypeGNULongLink:\n\t\t\t\tgnuLongLink = p.parseString(realname)\n\t\t\t}\n\t\t\tcontinue // This is a meta header affecting the next header\n\t\tdefault:\n\t\t\t// The old GNU sparse format is handled here since it is technically\n\t\t\t// just a regular file with additional attributes.\n\n\t\t\tif err := mergePAX(hdr, paxHdrs); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif gnuLongName != \"\" {\n\t\t\t\thdr.Name = gnuLongName\n\t\t\t}\n\t\t\tif gnuLongLink != \"\" {\n\t\t\t\thdr.Linkname = gnuLongLink\n\t\t\t}\n\t\t\tif hdr.Typeflag == TypeRegA {\n\t\t\t\tif strings.HasSuffix(hdr.Name, \"/\") {\n\t\t\t\t\thdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories\n\t\t\t\t} else {\n\t\t\t\t\thdr.Typeflag = TypeReg\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// The extended headers may have updated the size.\n\t\t\t// Thus, setup the regFileReader again after merging PAX headers.\n\t\t\tif err := tr.handleRegularFile(hdr); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Sparse formats rely on being able to read from the logical data\n\t\t\t// section; there must be a preceding call to handleRegularFile.\n\t\t\tif err := tr.handleSparseFile(hdr, rawHdr); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\t// Set the final guess at the format.\n\t\t\tif format.has(FormatUSTAR) && format.has(FormatPAX) {\n\t\t\t\tformat.mayOnlyBe(FormatUSTAR)\n\t\t\t}\n\t\t\thdr.Format = format\n\t\t\treturn hdr, nil // This is a file, so stop\n\t\t}\n\t}\n}\n\n// handleRegularFile sets up the current file reader and padding such that it\n// can only read the following logical data section. It will properly handle\n// special headers that contain no data section.\nfunc (tr *Reader) handleRegularFile(hdr *Header) error {\n\tnb := hdr.Size\n\tif isHeaderOnlyType(hdr.Typeflag) {\n\t\tnb = 0\n\t}\n\tif nb < 0 {\n\t\treturn ErrHeader\n\t}\n\n\ttr.pad = blockPadding(nb)\n\ttr.curr = &regFileReader{r: tr.r, nb: nb}\n\treturn nil\n}\n\n// handleSparseFile checks if the current file is a sparse format of any type\n// and sets the curr reader appropriately.\nfunc (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {\n\tvar spd sparseDatas\n\tvar err error\n\tif hdr.Typeflag == TypeGNUSparse {\n\t\tspd, err = tr.readOldGNUSparseMap(hdr, rawHdr)\n\t} else {\n\t\tspd, err = tr.readGNUSparsePAXHeaders(hdr)\n\t}\n\n\t// If sp is non-nil, then this is a sparse file.\n\t// Note that it is possible for len(sp) == 0.\n\tif err == nil && spd != nil {\n\t\tif isHeaderOnlyType(hdr.Typeflag) || !validateSparseEntries(spd, hdr.Size) {\n\t\t\treturn ErrHeader\n\t\t}\n\t\tsph := invertSparseEntries(spd, hdr.Size)\n\t\ttr.curr = &sparseFileReader{tr.curr, sph, 0}\n\t}\n\treturn err\n}\n\n// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.\n// If they are found, then this function reads the sparse map and returns it.\n// This assumes that 0.0 headers have already been converted to 0.1 headers\n// by the PAX header parsing logic.\nfunc (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {\n\t// Identify the version of GNU headers.\n\tvar is1x0 bool\n\tmajor, minor := hdr.PAXRecords[paxGNUSparseMajor], hdr.PAXRecords[paxGNUSparseMinor]\n\tswitch {\n\tcase major == \"0\" && (minor == \"0\" || minor == \"1\"):\n\t\tis1x0 = false\n\tcase major == \"1\" && minor == \"0\":\n\t\tis1x0 = true\n\tcase major != \"\" || minor != \"\":\n\t\treturn nil, nil // Unknown GNU sparse PAX version\n\tcase hdr.PAXRecords[paxGNUSparseMap] != \"\":\n\t\tis1x0 = false // 0.0 and 0.1 did not have explicit version records, so guess\n\tdefault:\n\t\treturn nil, nil // Not a PAX format GNU sparse file.\n\t}\n\thdr.Format.mayOnlyBe(FormatPAX)\n\n\t// Update hdr from GNU sparse PAX headers.\n\tif name := hdr.PAXRecords[paxGNUSparseName]; name != \"\" {\n\t\thdr.Name = name\n\t}\n\tsize := hdr.PAXRecords[paxGNUSparseSize]\n\tif size == \"\" {\n\t\tsize = hdr.PAXRecords[paxGNUSparseRealSize]\n\t}\n\tif size != \"\" {\n\t\tn, err := strconv.ParseInt(size, 10, 64)\n\t\tif err != nil {\n\t\t\treturn nil, ErrHeader\n\t\t}\n\t\thdr.Size = n\n\t}\n\n\t// Read the sparse map according to the appropriate format.\n\tif is1x0 {\n\t\treturn readGNUSparseMap1x0(tr.curr)\n\t}\n\treturn readGNUSparseMap0x1(hdr.PAXRecords)\n}\n\n// mergePAX merges paxHdrs into hdr for all relevant fields of Header.\nfunc mergePAX(hdr *Header, paxHdrs map[string]string) (err error) {\n\tfor k, v := range paxHdrs {\n\t\tif v == \"\" {\n\t\t\tcontinue // Keep the original USTAR value\n\t\t}\n\t\tvar id64 int64\n\t\tswitch k {\n\t\tcase paxPath:\n\t\t\thdr.Name = v\n\t\tcase paxLinkpath:\n\t\t\thdr.Linkname = v\n\t\tcase paxUname:\n\t\t\thdr.Uname = v\n\t\tcase paxGname:\n\t\t\thdr.Gname = v\n\t\tcase paxUid:\n\t\t\tid64, err = strconv.ParseInt(v, 10, 64)\n\t\t\thdr.Uid = int(id64) // Integer overflow possible\n\t\tcase paxGid:\n\t\t\tid64, err = strconv.ParseInt(v, 10, 64)\n\t\t\thdr.Gid = int(id64) // Integer overflow possible\n\t\tcase paxAtime:\n\t\t\thdr.AccessTime, err = parsePAXTime(v)\n\t\tcase paxMtime:\n\t\t\thdr.ModTime, err = parsePAXTime(v)\n\t\tcase paxCtime:\n\t\t\thdr.ChangeTime, err = parsePAXTime(v)\n\t\tcase paxSize:\n\t\t\thdr.Size, err = strconv.ParseInt(v, 10, 64)\n\t\tdefault:\n\t\t\tif strings.HasPrefix(k, paxSchilyXattr) {\n\t\t\t\tif hdr.Xattrs == nil {\n\t\t\t\t\thdr.Xattrs = make(map[string]string)\n\t\t\t\t}\n\t\t\t\thdr.Xattrs[k[len(paxSchilyXattr):]] = v\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\treturn ErrHeader\n\t\t}\n\t}\n\thdr.PAXRecords = paxHdrs\n\treturn nil\n}\n\n// parsePAX parses PAX headers.\n// If an extended header (type 'x') is invalid, ErrHeader is returned\nfunc parsePAX(r io.Reader) (map[string]string, error) {\n\tbuf, err := ioutil.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// leaving this function for io.Reader makes it more testable\n\tif tr, ok := r.(*Reader); ok && tr.RawAccounting {\n\t\tif _, err = tr.rawBytes.Write(buf); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tsbuf := string(buf)\n\n\t// For GNU PAX sparse format 0.0 support.\n\t// This function transforms the sparse format 0.0 headers into format 0.1\n\t// headers since 0.0 headers were not PAX compliant.\n\tvar sparseMap []string\n\n\tpaxHdrs := make(map[string]string)\n\tfor len(sbuf) > 0 {\n\t\tkey, value, residual, err := parsePAXRecord(sbuf)\n\t\tif err != nil {\n\t\t\treturn nil, ErrHeader\n\t\t}\n\t\tsbuf = residual\n\n\t\tswitch key {\n\t\tcase paxGNUSparseOffset, paxGNUSparseNumBytes:\n\t\t\t// Validate sparse header order and value.\n\t\t\tif (len(sparseMap)%2 == 0 && key != paxGNUSparseOffset) ||\n\t\t\t\t(len(sparseMap)%2 == 1 && key != paxGNUSparseNumBytes) ||\n\t\t\t\tstrings.Contains(value, \",\") {\n\t\t\t\treturn nil, ErrHeader\n\t\t\t}\n\t\t\tsparseMap = append(sparseMap, value)\n\t\tdefault:\n\t\t\tpaxHdrs[key] = value\n\t\t}\n\t}\n\tif len(sparseMap) > 0 {\n\t\tpaxHdrs[paxGNUSparseMap] = strings.Join(sparseMap, \",\")\n\t}\n\treturn paxHdrs, nil\n}\n\n// readHeader reads the next block header and assumes that the underlying reader\n// is already aligned to a block boundary. It returns the raw block of the\n// header in case further processing is required.\n//\n// The err will be set to io.EOF only when one of the following occurs:\n//   - Exactly 0 bytes are read and EOF is hit.\n//   - Exactly 1 block of zeros is read and EOF is hit.\n//   - At least 2 blocks of zeros are read.\nfunc (tr *Reader) readHeader() (*Header, *block, error) {\n\t// Two blocks of zero bytes marks the end of the archive.\n\tn, err := io.ReadFull(tr.r, tr.blk[:])\n\tif tr.RawAccounting && (err == nil || err == io.EOF) {\n\t\ttr.rawBytes.Write(tr.blk[:n])\n\t}\n\tif err != nil {\n\t\treturn nil, nil, err // EOF is okay here; exactly 0 bytes read\n\t}\n\n\tif bytes.Equal(tr.blk[:], zeroBlock[:]) {\n\t\tn, err = io.ReadFull(tr.r, tr.blk[:])\n\t\tif tr.RawAccounting && (err == nil || err == io.EOF) {\n\t\t\ttr.rawBytes.Write(tr.blk[:n])\n\t\t}\n\t\tif err != nil {\n\t\t\treturn nil, nil, err // EOF is okay here; exactly 1 block of zeros read\n\t\t}\n\t\tif bytes.Equal(tr.blk[:], zeroBlock[:]) {\n\t\t\treturn nil, nil, io.EOF // normal EOF; exactly 2 block of zeros read\n\t\t}\n\t\treturn nil, nil, ErrHeader // Zero block and then non-zero block\n\t}\n\n\t// Verify the header matches a known format.\n\tformat := tr.blk.GetFormat()\n\tif format == FormatUnknown {\n\t\treturn nil, nil, ErrHeader\n\t}\n\n\tvar p parser\n\thdr := new(Header)\n\n\t// Unpack the V7 header.\n\tv7 := tr.blk.V7()\n\thdr.Typeflag = v7.TypeFlag()[0]\n\thdr.Name = p.parseString(v7.Name())\n\thdr.Linkname = p.parseString(v7.LinkName())\n\thdr.Size = p.parseNumeric(v7.Size())\n\thdr.Mode = p.parseNumeric(v7.Mode())\n\thdr.Uid = int(p.parseNumeric(v7.UID()))\n\thdr.Gid = int(p.parseNumeric(v7.GID()))\n\thdr.ModTime = time.Unix(p.parseNumeric(v7.ModTime()), 0)\n\n\t// Unpack format specific fields.\n\tif format > formatV7 {\n\t\tustar := tr.blk.USTAR()\n\t\thdr.Uname = p.parseString(ustar.UserName())\n\t\thdr.Gname = p.parseString(ustar.GroupName())\n\t\thdr.Devmajor = p.parseNumeric(ustar.DevMajor())\n\t\thdr.Devminor = p.parseNumeric(ustar.DevMinor())\n\n\t\tvar prefix string\n\t\tswitch {\n\t\tcase format.has(FormatUSTAR | FormatPAX):\n\t\t\thdr.Format = format\n\t\t\tustar := tr.blk.USTAR()\n\t\t\tprefix = p.parseString(ustar.Prefix())\n\n\t\t\t// For Format detection, check if block is properly formatted since\n\t\t\t// the parser is more liberal than what USTAR actually permits.\n\t\t\tnotASCII := func(r rune) bool { return r >= 0x80 }\n\t\t\tif bytes.IndexFunc(tr.blk[:], notASCII) >= 0 {\n\t\t\t\thdr.Format = FormatUnknown // Non-ASCII characters in block.\n\t\t\t}\n\t\t\tnul := func(b []byte) bool { return int(b[len(b)-1]) == 0 }\n\t\t\tif !(nul(v7.Size()) && nul(v7.Mode()) && nul(v7.UID()) && nul(v7.GID()) &&\n\t\t\t\tnul(v7.ModTime()) && nul(ustar.DevMajor()) && nul(ustar.DevMinor())) {\n\t\t\t\thdr.Format = FormatUnknown // Numeric fields must end in NUL\n\t\t\t}\n\t\tcase format.has(formatSTAR):\n\t\t\tstar := tr.blk.STAR()\n\t\t\tprefix = p.parseString(star.Prefix())\n\t\t\thdr.AccessTime = time.Unix(p.parseNumeric(star.AccessTime()), 0)\n\t\t\thdr.ChangeTime = time.Unix(p.parseNumeric(star.ChangeTime()), 0)\n\t\tcase format.has(FormatGNU):\n\t\t\thdr.Format = format\n\t\t\tvar p2 parser\n\t\t\tgnu := tr.blk.GNU()\n\t\t\tif b := gnu.AccessTime(); b[0] != 0 {\n\t\t\t\thdr.AccessTime = time.Unix(p2.parseNumeric(b), 0)\n\t\t\t}\n\t\t\tif b := gnu.ChangeTime(); b[0] != 0 {\n\t\t\t\thdr.ChangeTime = time.Unix(p2.parseNumeric(b), 0)\n\t\t\t}\n\n\t\t\t// Prior to Go1.8, the Writer had a bug where it would output\n\t\t\t// an invalid tar file in certain rare situations because the logic\n\t\t\t// incorrectly believed that the old GNU format had a prefix field.\n\t\t\t// This is wrong and leads to an output file that mangles the\n\t\t\t// atime and ctime fields, which are often left unused.\n\t\t\t//\n\t\t\t// In order to continue reading tar files created by former, buggy\n\t\t\t// versions of Go, we skeptically parse the atime and ctime fields.\n\t\t\t// If we are unable to parse them and the prefix field looks like\n\t\t\t// an ASCII string, then we fallback on the pre-Go1.8 behavior\n\t\t\t// of treating these fields as the USTAR prefix field.\n\t\t\t//\n\t\t\t// Note that this will not use the fallback logic for all possible\n\t\t\t// files generated by a pre-Go1.8 toolchain. If the generated file\n\t\t\t// happened to have a prefix field that parses as valid\n\t\t\t// atime and ctime fields (e.g., when they are valid octal strings),\n\t\t\t// then it is impossible to distinguish between an valid GNU file\n\t\t\t// and an invalid pre-Go1.8 file.\n\t\t\t//\n\t\t\t// See https://golang.org/issues/12594\n\t\t\t// See https://golang.org/issues/21005\n\t\t\tif p2.err != nil {\n\t\t\t\thdr.AccessTime, hdr.ChangeTime = time.Time{}, time.Time{}\n\t\t\t\tustar := tr.blk.USTAR()\n\t\t\t\tif s := p.parseString(ustar.Prefix()); isASCII(s) {\n\t\t\t\t\tprefix = s\n\t\t\t\t}\n\t\t\t\thdr.Format = FormatUnknown // Buggy file is not GNU\n\t\t\t}\n\t\t}\n\t\tif len(prefix) > 0 {\n\t\t\thdr.Name = prefix + \"/\" + hdr.Name\n\t\t}\n\t}\n\treturn hdr, &tr.blk, p.err\n}\n\n// readOldGNUSparseMap reads the sparse map from the old GNU sparse format.\n// The sparse map is stored in the tar header if it's small enough.\n// If it's larger than four entries, then one or more extension headers are used\n// to store the rest of the sparse map.\n//\n// The Header.Size does not reflect the size of any extended headers used.\n// Thus, this function will read from the raw io.Reader to fetch extra headers.\n// This method mutates blk in the process.\nfunc (tr *Reader) readOldGNUSparseMap(hdr *Header, blk *block) (sparseDatas, error) {\n\t// Make sure that the input format is GNU.\n\t// Unfortunately, the STAR format also has a sparse header format that uses\n\t// the same type flag but has a completely different layout.\n\tif blk.GetFormat() != FormatGNU {\n\t\treturn nil, ErrHeader\n\t}\n\thdr.Format.mayOnlyBe(FormatGNU)\n\n\tvar p parser\n\thdr.Size = p.parseNumeric(blk.GNU().RealSize())\n\tif p.err != nil {\n\t\treturn nil, p.err\n\t}\n\ts := blk.GNU().Sparse()\n\tspd := make(sparseDatas, 0, s.MaxEntries())\n\tfor {\n\t\tfor i := 0; i < s.MaxEntries(); i++ {\n\t\t\t// This termination condition is identical to GNU and BSD tar.\n\t\t\tif s.Entry(i).Offset()[0] == 0x00 {\n\t\t\t\tbreak // Don't return, need to process extended headers (even if empty)\n\t\t\t}\n\t\t\toffset := p.parseNumeric(s.Entry(i).Offset())\n\t\t\tlength := p.parseNumeric(s.Entry(i).Length())\n\t\t\tif p.err != nil {\n\t\t\t\treturn nil, p.err\n\t\t\t}\n\t\t\tspd = append(spd, sparseEntry{Offset: offset, Length: length})\n\t\t}\n\n\t\tif s.IsExtended()[0] > 0 {\n\t\t\t// There are more entries. Read an extension header and parse its entries.\n\t\t\tif _, err := mustReadFull(tr.r, blk[:]); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif tr.RawAccounting {\n\t\t\t\ttr.rawBytes.Write(blk[:])\n\t\t\t}\n\t\t\ts = blk.Sparse()\n\t\t\tcontinue\n\t\t}\n\t\treturn spd, nil // Done\n\t}\n}\n\n// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format\n// version 1.0. The format of the sparse map consists of a series of\n// newline-terminated numeric fields. The first field is the number of entries\n// and is always present. Following this are the entries, consisting of two\n// fields (offset, length). This function must stop reading at the end\n// boundary of the block containing the last newline.\n//\n// Note that the GNU manual says that numeric values should be encoded in octal\n// format. However, the GNU tar utility itself outputs these values in decimal.\n// As such, this library treats values as being encoded in decimal.\nfunc readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {\n\tvar (\n\t\tcntNewline int64\n\t\tbuf        bytes.Buffer\n\t\tblk        block\n\t)\n\n\t// feedTokens copies data in blocks from r into buf until there are\n\t// at least cnt newlines in buf. It will not read more blocks than needed.\n\tfeedTokens := func(n int64) error {\n\t\tfor cntNewline < n {\n\t\t\tif _, err := mustReadFull(r, blk[:]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tbuf.Write(blk[:])\n\t\t\tfor _, c := range blk {\n\t\t\t\tif c == '\\n' {\n\t\t\t\t\tcntNewline++\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\n\t// nextToken gets the next token delimited by a newline. This assumes that\n\t// at least one newline exists in the buffer.\n\tnextToken := func() string {\n\t\tcntNewline--\n\t\ttok, _ := buf.ReadString('\\n')\n\t\treturn strings.TrimRight(tok, \"\\n\")\n\t}\n\n\t// Parse for the number of entries.\n\t// Use integer overflow resistant math to check this.\n\tif err := feedTokens(1); err != nil {\n\t\treturn nil, err\n\t}\n\tnumEntries, err := strconv.ParseInt(nextToken(), 10, 0) // Intentionally parse as native int\n\tif err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {\n\t\treturn nil, ErrHeader\n\t}\n\n\t// Parse for all member entries.\n\t// numEntries is trusted after this since a potential attacker must have\n\t// committed resources proportional to what this library used.\n\tif err := feedTokens(2 * numEntries); err != nil {\n\t\treturn nil, err\n\t}\n\tspd := make(sparseDatas, 0, numEntries)\n\tfor i := int64(0); i < numEntries; i++ {\n\t\toffset, err1 := strconv.ParseInt(nextToken(), 10, 64)\n\t\tlength, err2 := strconv.ParseInt(nextToken(), 10, 64)\n\t\tif err1 != nil || err2 != nil {\n\t\t\treturn nil, ErrHeader\n\t\t}\n\t\tspd = append(spd, sparseEntry{Offset: offset, Length: length})\n\t}\n\treturn spd, nil\n}\n\n// readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format\n// version 0.1. The sparse map is stored in the PAX headers.\nfunc readGNUSparseMap0x1(paxHdrs map[string]string) (sparseDatas, error) {\n\t// Get number of entries.\n\t// Use integer overflow resistant math to check this.\n\tnumEntriesStr := paxHdrs[paxGNUSparseNumBlocks]\n\tnumEntries, err := strconv.ParseInt(numEntriesStr, 10, 0) // Intentionally parse as native int\n\tif err != nil || numEntries < 0 || int(2*numEntries) < int(numEntries) {\n\t\treturn nil, ErrHeader\n\t}\n\n\t// There should be two numbers in sparseMap for each entry.\n\tsparseMap := strings.Split(paxHdrs[paxGNUSparseMap], \",\")\n\tif len(sparseMap) == 1 && sparseMap[0] == \"\" {\n\t\tsparseMap = sparseMap[:0]\n\t}\n\tif int64(len(sparseMap)) != 2*numEntries {\n\t\treturn nil, ErrHeader\n\t}\n\n\t// Loop through the entries in the sparse map.\n\t// numEntries is trusted now.\n\tspd := make(sparseDatas, 0, numEntries)\n\tfor len(sparseMap) >= 2 {\n\t\toffset, err1 := strconv.ParseInt(sparseMap[0], 10, 64)\n\t\tlength, err2 := strconv.ParseInt(sparseMap[1], 10, 64)\n\t\tif err1 != nil || err2 != nil {\n\t\t\treturn nil, ErrHeader\n\t\t}\n\t\tspd = append(spd, sparseEntry{Offset: offset, Length: length})\n\t\tsparseMap = sparseMap[2:]\n\t}\n\treturn spd, nil\n}\n\n// Read reads from the current file in the tar archive.\n// It returns (0, io.EOF) when it reaches the end of that file,\n// until Next is called to advance to the next file.\n//\n// If the current file is sparse, then the regions marked as a hole\n// are read back as NUL-bytes.\n//\n// Calling Read on special types like TypeLink, TypeSymlink, TypeChar,\n// TypeBlock, TypeDir, and TypeFifo returns (0, io.EOF) regardless of what\n// the Header.Size claims.\nfunc (tr *Reader) Read(b []byte) (int, error) {\n\tif tr.err != nil {\n\t\treturn 0, tr.err\n\t}\n\tn, err := tr.curr.Read(b)\n\tif err != nil && err != io.EOF {\n\t\ttr.err = err\n\t}\n\treturn n, err\n}\n\n// writeTo writes the content of the current file to w.\n// The bytes written matches the number of remaining bytes in the current file.\n//\n// If the current file is sparse and w is an io.WriteSeeker,\n// then writeTo uses Seek to skip past holes defined in Header.SparseHoles,\n// assuming that skipped regions are filled with NULs.\n// This always writes the last byte to ensure w is the right size.\n//\n// TODO(dsnet): Re-export this when adding sparse file support.\n// See https://golang.org/issue/22735\nfunc (tr *Reader) writeTo(w io.Writer) (int64, error) {\n\tif tr.err != nil {\n\t\treturn 0, tr.err\n\t}\n\tn, err := tr.curr.WriteTo(w)\n\tif err != nil {\n\t\ttr.err = err\n\t}\n\treturn n, err\n}\n\n// regFileReader is a fileReader for reading data from a regular file entry.\ntype regFileReader struct {\n\tr  io.Reader // Underlying Reader\n\tnb int64     // Number of remaining bytes to read\n}\n\nfunc (fr *regFileReader) Read(b []byte) (n int, err error) {\n\tif int64(len(b)) > fr.nb {\n\t\tb = b[:fr.nb]\n\t}\n\tif len(b) > 0 {\n\t\tn, err = fr.r.Read(b)\n\t\tfr.nb -= int64(n)\n\t}\n\tswitch {\n\tcase err == io.EOF && fr.nb > 0:\n\t\treturn n, io.ErrUnexpectedEOF\n\tcase err == nil && fr.nb == 0:\n\t\treturn n, io.EOF\n\tdefault:\n\t\treturn n, err\n\t}\n}\n\nfunc (fr *regFileReader) WriteTo(w io.Writer) (int64, error) {\n\treturn io.Copy(w, struct{ io.Reader }{fr})\n}\n\nfunc (fr regFileReader) LogicalRemaining() int64 {\n\treturn fr.nb\n}\n\nfunc (fr regFileReader) PhysicalRemaining() int64 {\n\treturn fr.nb\n}\n\n// sparseFileReader is a fileReader for reading data from a sparse file entry.\ntype sparseFileReader struct {\n\tfr  fileReader  // Underlying fileReader\n\tsp  sparseHoles // Normalized list of sparse holes\n\tpos int64       // Current position in sparse file\n}\n\nfunc (sr *sparseFileReader) Read(b []byte) (n int, err error) {\n\tfinished := int64(len(b)) >= sr.LogicalRemaining()\n\tif finished {\n\t\tb = b[:sr.LogicalRemaining()]\n\t}\n\n\tb0 := b\n\tendPos := sr.pos + int64(len(b))\n\tfor endPos > sr.pos && err == nil {\n\t\tvar nf int // Bytes read in fragment\n\t\tholeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()\n\t\tif sr.pos < holeStart { // In a data fragment\n\t\t\tbf := b[:min(int64(len(b)), holeStart-sr.pos)]\n\t\t\tnf, err = tryReadFull(sr.fr, bf)\n\t\t} else { // In a hole fragment\n\t\t\tbf := b[:min(int64(len(b)), holeEnd-sr.pos)]\n\t\t\tnf, err = tryReadFull(zeroReader{}, bf)\n\t\t}\n\t\tb = b[nf:]\n\t\tsr.pos += int64(nf)\n\t\tif sr.pos >= holeEnd && len(sr.sp) > 1 {\n\t\t\tsr.sp = sr.sp[1:] // Ensure last fragment always remains\n\t\t}\n\t}\n\n\tn = len(b0) - len(b)\n\tswitch {\n\tcase err == io.EOF:\n\t\treturn n, errMissData // Less data in dense file than sparse file\n\tcase err != nil:\n\t\treturn n, err\n\tcase sr.LogicalRemaining() == 0 && sr.PhysicalRemaining() > 0:\n\t\treturn n, errUnrefData // More data in dense file than sparse file\n\tcase finished:\n\t\treturn n, io.EOF\n\tdefault:\n\t\treturn n, nil\n\t}\n}\n\nfunc (sr *sparseFileReader) WriteTo(w io.Writer) (n int64, err error) {\n\tws, ok := w.(io.WriteSeeker)\n\tif ok {\n\t\tif _, err := ws.Seek(0, io.SeekCurrent); err != nil {\n\t\t\tok = false // Not all io.Seeker can really seek\n\t\t}\n\t}\n\tif !ok {\n\t\treturn io.Copy(w, struct{ io.Reader }{sr})\n\t}\n\n\tvar writeLastByte bool\n\tpos0 := sr.pos\n\tfor sr.LogicalRemaining() > 0 && !writeLastByte && err == nil {\n\t\tvar nf int64 // Size of fragment\n\t\tholeStart, holeEnd := sr.sp[0].Offset, sr.sp[0].endOffset()\n\t\tif sr.pos < holeStart { // In a data fragment\n\t\t\tnf = holeStart - sr.pos\n\t\t\tnf, err = io.CopyN(ws, sr.fr, nf)\n\t\t} else { // In a hole fragment\n\t\t\tnf = holeEnd - sr.pos\n\t\t\tif sr.PhysicalRemaining() == 0 {\n\t\t\t\twriteLastByte = true\n\t\t\t\tnf--\n\t\t\t}\n\t\t\t_, err = ws.Seek(nf, io.SeekCurrent)\n\t\t}\n\t\tsr.pos += nf\n\t\tif sr.pos >= holeEnd && len(sr.sp) > 1 {\n\t\t\tsr.sp = sr.sp[1:] // Ensure last fragment always remains\n\t\t}\n\t}\n\n\t// If the last fragment is a hole, then seek to 1-byte before EOF, and\n\t// write a single byte to ensure the file is the right size.\n\tif writeLastByte && err == nil {\n\t\t_, err = ws.Write([]byte{0})\n\t\tsr.pos++\n\t}\n\n\tn = sr.pos - pos0\n\tswitch {\n\tcase err == io.EOF:\n\t\treturn n, errMissData // Less data in dense file than sparse file\n\tcase err != nil:\n\t\treturn n, err\n\tcase sr.LogicalRemaining() == 0 && sr.PhysicalRemaining() > 0:\n\t\treturn n, errUnrefData // More data in dense file than sparse file\n\tdefault:\n\t\treturn n, nil\n\t}\n}\n\nfunc (sr sparseFileReader) LogicalRemaining() int64 {\n\treturn sr.sp[len(sr.sp)-1].endOffset() - sr.pos\n}\nfunc (sr sparseFileReader) PhysicalRemaining() int64 {\n\treturn sr.fr.PhysicalRemaining()\n}\n\ntype zeroReader struct{}\n\nfunc (zeroReader) Read(b []byte) (int, error) {\n\tfor i := range b {\n\t\tb[i] = 0\n\t}\n\treturn len(b), nil\n}\n\n// mustReadFull is like io.ReadFull except it returns\n// io.ErrUnexpectedEOF when io.EOF is hit before len(b) bytes are read.\nfunc mustReadFull(r io.Reader, b []byte) (int, error) {\n\tn, err := tryReadFull(r, b)\n\tif err == io.EOF {\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\treturn n, err\n}\n\n// tryReadFull is like io.ReadFull except it returns\n// io.EOF when it is hit before len(b) bytes are read.\nfunc tryReadFull(r io.Reader, b []byte) (n int, err error) {\n\tfor len(b) > n && err == nil {\n\t\tvar nn int\n\t\tnn, err = r.Read(b[n:])\n\t\tn += nn\n\t}\n\tif len(b) == n && err == io.EOF {\n\t\terr = nil\n\t}\n\treturn n, err\n}\n\n// discard skips n bytes in r, reporting an error if unable to do so.\nfunc discard(tr *Reader, n int64) error {\n\tvar seekSkipped, copySkipped int64\n\tvar err error\n\tr := tr.r\n\tif tr.RawAccounting {\n\n\t\tcopySkipped, err = io.CopyN(tr.rawBytes, tr.r, n)\n\t\tgoto out\n\t}\n\n\t// If possible, Seek to the last byte before the end of the data section.\n\t// Do this because Seek is often lazy about reporting errors; this will mask\n\t// the fact that the stream may be truncated. We can rely on the\n\t// io.CopyN done shortly afterwards to trigger any IO errors.\n\tif sr, ok := r.(io.Seeker); ok && n > 1 {\n\t\t// Not all io.Seeker can actually Seek. For example, os.Stdin implements\n\t\t// io.Seeker, but calling Seek always returns an error and performs\n\t\t// no action. Thus, we try an innocent seek to the current position\n\t\t// to see if Seek is really supported.\n\t\tpos1, err := sr.Seek(0, io.SeekCurrent)\n\t\tif pos1 >= 0 && err == nil {\n\t\t\t// Seek seems supported, so perform the real Seek.\n\t\t\tpos2, err := sr.Seek(n-1, io.SeekCurrent)\n\t\t\tif pos2 < 0 || err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tseekSkipped = pos2 - pos1\n\t\t}\n\t}\n\n\tcopySkipped, err = io.CopyN(ioutil.Discard, r, n-seekSkipped)\nout:\n\tif err == io.EOF && seekSkipped+copySkipped < n {\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\treturn err\n}\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/archive/tar/stat_actime1.go",
    "content": "// Copyright 2012 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// +build linux dragonfly openbsd solaris\n\npackage tar\n\nimport (\n\t\"syscall\"\n\t\"time\"\n)\n\nfunc statAtime(st *syscall.Stat_t) time.Time {\n\treturn time.Unix(st.Atim.Unix())\n}\n\nfunc statCtime(st *syscall.Stat_t) time.Time {\n\treturn time.Unix(st.Ctim.Unix())\n}\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/archive/tar/stat_actime2.go",
    "content": "// Copyright 2012 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// +build darwin freebsd netbsd\n\npackage tar\n\nimport (\n\t\"syscall\"\n\t\"time\"\n)\n\nfunc statAtime(st *syscall.Stat_t) time.Time {\n\treturn time.Unix(st.Atimespec.Unix())\n}\n\nfunc statCtime(st *syscall.Stat_t) time.Time {\n\treturn time.Unix(st.Ctimespec.Unix())\n}\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/archive/tar/stat_unix.go",
    "content": "// Copyright 2012 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// +build linux darwin dragonfly freebsd openbsd netbsd solaris\n\npackage tar\n\nimport (\n\t\"os\"\n\t\"os/user\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"sync\"\n\t\"syscall\"\n)\n\nfunc init() {\n\tsysStat = statUnix\n}\n\n// userMap and groupMap caches UID and GID lookups for performance reasons.\n// The downside is that renaming uname or gname by the OS never takes effect.\nvar userMap, groupMap sync.Map // map[int]string\n\nfunc statUnix(fi os.FileInfo, h *Header) error {\n\tsys, ok := fi.Sys().(*syscall.Stat_t)\n\tif !ok {\n\t\treturn nil\n\t}\n\th.Uid = int(sys.Uid)\n\th.Gid = int(sys.Gid)\n\n\t// Best effort at populating Uname and Gname.\n\t// The os/user functions may fail for any number of reasons\n\t// (not implemented on that platform, cgo not enabled, etc).\n\tif u, ok := userMap.Load(h.Uid); ok {\n\t\th.Uname = u.(string)\n\t} else if u, err := user.LookupId(strconv.Itoa(h.Uid)); err == nil {\n\t\th.Uname = u.Username\n\t\tuserMap.Store(h.Uid, h.Uname)\n\t}\n\tif g, ok := groupMap.Load(h.Gid); ok {\n\t\th.Gname = g.(string)\n\t} else if g, err := user.LookupGroupId(strconv.Itoa(h.Gid)); err == nil {\n\t\th.Gname = g.Name\n\t\tgroupMap.Store(h.Gid, h.Gname)\n\t}\n\n\th.AccessTime = statAtime(sys)\n\th.ChangeTime = statCtime(sys)\n\n\t// Best effort at populating Devmajor and Devminor.\n\tif h.Typeflag == TypeChar || h.Typeflag == TypeBlock {\n\t\tdev := uint64(sys.Rdev) // May be int32 or uint32\n\t\tswitch runtime.GOOS {\n\t\tcase \"linux\":\n\t\t\t// Copied from golang.org/x/sys/unix/dev_linux.go.\n\t\t\tmajor := uint32((dev & 0x00000000000fff00) >> 8)\n\t\t\tmajor |= uint32((dev & 0xfffff00000000000) >> 32)\n\t\t\tminor := uint32((dev & 0x00000000000000ff) >> 0)\n\t\t\tminor |= uint32((dev & 0x00000ffffff00000) >> 12)\n\t\t\th.Devmajor, h.Devminor = int64(major), int64(minor)\n\t\tcase \"darwin\":\n\t\t\t// Copied from golang.org/x/sys/unix/dev_darwin.go.\n\t\t\tmajor := uint32((dev >> 24) & 0xff)\n\t\t\tminor := uint32(dev & 0xffffff)\n\t\t\th.Devmajor, h.Devminor = int64(major), int64(minor)\n\t\tcase \"dragonfly\":\n\t\t\t// Copied from golang.org/x/sys/unix/dev_dragonfly.go.\n\t\t\tmajor := uint32((dev >> 8) & 0xff)\n\t\t\tminor := uint32(dev & 0xffff00ff)\n\t\t\th.Devmajor, h.Devminor = int64(major), int64(minor)\n\t\tcase \"freebsd\":\n\t\t\t// Copied from golang.org/x/sys/unix/dev_freebsd.go.\n\t\t\tmajor := uint32((dev >> 8) & 0xff)\n\t\t\tminor := uint32(dev & 0xffff00ff)\n\t\t\th.Devmajor, h.Devminor = int64(major), int64(minor)\n\t\tcase \"netbsd\":\n\t\t\t// Copied from golang.org/x/sys/unix/dev_netbsd.go.\n\t\t\tmajor := uint32((dev & 0x000fff00) >> 8)\n\t\t\tminor := uint32((dev & 0x000000ff) >> 0)\n\t\t\tminor |= uint32((dev & 0xfff00000) >> 12)\n\t\t\th.Devmajor, h.Devminor = int64(major), int64(minor)\n\t\tcase \"openbsd\":\n\t\t\t// Copied from golang.org/x/sys/unix/dev_openbsd.go.\n\t\t\tmajor := uint32((dev & 0x0000ff00) >> 8)\n\t\t\tminor := uint32((dev & 0x000000ff) >> 0)\n\t\t\tminor |= uint32((dev & 0xffff0000) >> 8)\n\t\t\th.Devmajor, h.Devminor = int64(major), int64(minor)\n\t\tdefault:\n\t\t\t// TODO: Implement solaris (see https://golang.org/issue/8106)\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/archive/tar/strconv.go",
    "content": "// Copyright 2016 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 tar\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// hasNUL reports whether the NUL character exists within s.\nfunc hasNUL(s string) bool {\n\treturn strings.IndexByte(s, 0) >= 0\n}\n\n// isASCII reports whether the input is an ASCII C-style string.\nfunc isASCII(s string) bool {\n\tfor _, c := range s {\n\t\tif c >= 0x80 || c == 0x00 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// toASCII converts the input to an ASCII C-style string.\n// This a best effort conversion, so invalid characters are dropped.\nfunc toASCII(s string) string {\n\tif isASCII(s) {\n\t\treturn s\n\t}\n\tb := make([]byte, 0, len(s))\n\tfor _, c := range s {\n\t\tif c < 0x80 && c != 0x00 {\n\t\t\tb = append(b, byte(c))\n\t\t}\n\t}\n\treturn string(b)\n}\n\ntype parser struct {\n\terr error // Last error seen\n}\n\ntype formatter struct {\n\terr error // Last error seen\n}\n\n// parseString parses bytes as a NUL-terminated C-style string.\n// If a NUL byte is not found then the whole slice is returned as a string.\nfunc (*parser) parseString(b []byte) string {\n\tif i := bytes.IndexByte(b, 0); i >= 0 {\n\t\treturn string(b[:i])\n\t}\n\treturn string(b)\n}\n\n// formatString copies s into b, NUL-terminating if possible.\nfunc (f *formatter) formatString(b []byte, s string) {\n\tif len(s) > len(b) {\n\t\tf.err = ErrFieldTooLong\n\t}\n\tcopy(b, s)\n\tif len(s) < len(b) {\n\t\tb[len(s)] = 0\n\t}\n\n\t// Some buggy readers treat regular files with a trailing slash\n\t// in the V7 path field as a directory even though the full path\n\t// recorded elsewhere (e.g., via PAX record) contains no trailing slash.\n\tif len(s) > len(b) && b[len(b)-1] == '/' {\n\t\tn := len(strings.TrimRight(s[:len(b)], \"/\"))\n\t\tb[n] = 0 // Replace trailing slash with NUL terminator\n\t}\n}\n\n// fitsInBase256 reports whether x can be encoded into n bytes using base-256\n// encoding. Unlike octal encoding, base-256 encoding does not require that the\n// string ends with a NUL character. Thus, all n bytes are available for output.\n//\n// If operating in binary mode, this assumes strict GNU binary mode; which means\n// that the first byte can only be either 0x80 or 0xff. Thus, the first byte is\n// equivalent to the sign bit in two's complement form.\nfunc fitsInBase256(n int, x int64) bool {\n\tbinBits := uint(n-1) * 8\n\treturn n >= 9 || (x >= -1<<binBits && x < 1<<binBits)\n}\n\n// parseNumeric parses the input as being encoded in either base-256 or octal.\n// This function may return negative numbers.\n// If parsing fails or an integer overflow occurs, err will be set.\nfunc (p *parser) parseNumeric(b []byte) int64 {\n\t// Check for base-256 (binary) format first.\n\t// If the first bit is set, then all following bits constitute a two's\n\t// complement encoded number in big-endian byte order.\n\tif len(b) > 0 && b[0]&0x80 != 0 {\n\t\t// Handling negative numbers relies on the following identity:\n\t\t//\t-a-1 == ^a\n\t\t//\n\t\t// If the number is negative, we use an inversion mask to invert the\n\t\t// data bytes and treat the value as an unsigned number.\n\t\tvar inv byte // 0x00 if positive or zero, 0xff if negative\n\t\tif b[0]&0x40 != 0 {\n\t\t\tinv = 0xff\n\t\t}\n\n\t\tvar x uint64\n\t\tfor i, c := range b {\n\t\t\tc ^= inv // Inverts c only if inv is 0xff, otherwise does nothing\n\t\t\tif i == 0 {\n\t\t\t\tc &= 0x7f // Ignore signal bit in first byte\n\t\t\t}\n\t\t\tif (x >> 56) > 0 {\n\t\t\t\tp.err = ErrHeader // Integer overflow\n\t\t\t\treturn 0\n\t\t\t}\n\t\t\tx = x<<8 | uint64(c)\n\t\t}\n\t\tif (x >> 63) > 0 {\n\t\t\tp.err = ErrHeader // Integer overflow\n\t\t\treturn 0\n\t\t}\n\t\tif inv == 0xff {\n\t\t\treturn ^int64(x)\n\t\t}\n\t\treturn int64(x)\n\t}\n\n\t// Normal case is base-8 (octal) format.\n\treturn p.parseOctal(b)\n}\n\n// formatNumeric encodes x into b using base-8 (octal) encoding if possible.\n// Otherwise it will attempt to use base-256 (binary) encoding.\nfunc (f *formatter) formatNumeric(b []byte, x int64) {\n\tif fitsInOctal(len(b), x) {\n\t\tf.formatOctal(b, x)\n\t\treturn\n\t}\n\n\tif fitsInBase256(len(b), x) {\n\t\tfor i := len(b) - 1; i >= 0; i-- {\n\t\t\tb[i] = byte(x)\n\t\t\tx >>= 8\n\t\t}\n\t\tb[0] |= 0x80 // Highest bit indicates binary format\n\t\treturn\n\t}\n\n\tf.formatOctal(b, 0) // Last resort, just write zero\n\tf.err = ErrFieldTooLong\n}\n\nfunc (p *parser) parseOctal(b []byte) int64 {\n\t// Because unused fields are filled with NULs, we need\n\t// to skip leading NULs. Fields may also be padded with\n\t// spaces or NULs.\n\t// So we remove leading and trailing NULs and spaces to\n\t// be sure.\n\tb = bytes.Trim(b, \" \\x00\")\n\n\tif len(b) == 0 {\n\t\treturn 0\n\t}\n\tx, perr := strconv.ParseUint(p.parseString(b), 8, 64)\n\tif perr != nil {\n\t\tp.err = ErrHeader\n\t}\n\treturn int64(x)\n}\n\nfunc (f *formatter) formatOctal(b []byte, x int64) {\n\tif !fitsInOctal(len(b), x) {\n\t\tx = 0 // Last resort, just write zero\n\t\tf.err = ErrFieldTooLong\n\t}\n\n\ts := strconv.FormatInt(x, 8)\n\t// Add leading zeros, but leave room for a NUL.\n\tif n := len(b) - len(s) - 1; n > 0 {\n\t\ts = strings.Repeat(\"0\", n) + s\n\t}\n\tf.formatString(b, s)\n}\n\n// fitsInOctal reports whether the integer x fits in a field n-bytes long\n// using octal encoding with the appropriate NUL terminator.\nfunc fitsInOctal(n int, x int64) bool {\n\toctBits := uint(n-1) * 3\n\treturn x >= 0 && (n >= 22 || x < 1<<octBits)\n}\n\n// parsePAXTime takes a string of the form %d.%d as described in the PAX\n// specification. Note that this implementation allows for negative timestamps,\n// which is allowed for by the PAX specification, but not always portable.\nfunc parsePAXTime(s string) (time.Time, error) {\n\tconst maxNanoSecondDigits = 9\n\n\t// Split string into seconds and sub-seconds parts.\n\tss, sn := s, \"\"\n\tif pos := strings.IndexByte(s, '.'); pos >= 0 {\n\t\tss, sn = s[:pos], s[pos+1:]\n\t}\n\n\t// Parse the seconds.\n\tsecs, err := strconv.ParseInt(ss, 10, 64)\n\tif err != nil {\n\t\treturn time.Time{}, ErrHeader\n\t}\n\tif len(sn) == 0 {\n\t\treturn time.Unix(secs, 0), nil // No sub-second values\n\t}\n\n\t// Parse the nanoseconds.\n\tif strings.Trim(sn, \"0123456789\") != \"\" {\n\t\treturn time.Time{}, ErrHeader\n\t}\n\tif len(sn) < maxNanoSecondDigits {\n\t\tsn += strings.Repeat(\"0\", maxNanoSecondDigits-len(sn)) // Right pad\n\t} else {\n\t\tsn = sn[:maxNanoSecondDigits] // Right truncate\n\t}\n\tnsecs, _ := strconv.ParseInt(sn, 10, 64) // Must succeed\n\tif len(ss) > 0 && ss[0] == '-' {\n\t\treturn time.Unix(secs, -1*nsecs), nil // Negative correction\n\t}\n\treturn time.Unix(secs, nsecs), nil\n}\n\n// formatPAXTime converts ts into a time of the form %d.%d as described in the\n// PAX specification. This function is capable of negative timestamps.\nfunc formatPAXTime(ts time.Time) (s string) {\n\tsecs, nsecs := ts.Unix(), ts.Nanosecond()\n\tif nsecs == 0 {\n\t\treturn strconv.FormatInt(secs, 10)\n\t}\n\n\t// If seconds is negative, then perform correction.\n\tsign := \"\"\n\tif secs < 0 {\n\t\tsign = \"-\"             // Remember sign\n\t\tsecs = -(secs + 1)     // Add a second to secs\n\t\tnsecs = -(nsecs - 1E9) // Take that second away from nsecs\n\t}\n\treturn strings.TrimRight(fmt.Sprintf(\"%s%d.%09d\", sign, secs, nsecs), \"0\")\n}\n\n// parsePAXRecord parses the input PAX record string into a key-value pair.\n// If parsing is successful, it will slice off the currently read record and\n// return the remainder as r.\nfunc parsePAXRecord(s string) (k, v, r string, err error) {\n\t// The size field ends at the first space.\n\tsp := strings.IndexByte(s, ' ')\n\tif sp == -1 {\n\t\treturn \"\", \"\", s, ErrHeader\n\t}\n\n\t// Parse the first token as a decimal integer.\n\tn, perr := strconv.ParseInt(s[:sp], 10, 0) // Intentionally parse as native int\n\tif perr != nil || n < 5 || int64(len(s)) < n {\n\t\treturn \"\", \"\", s, ErrHeader\n\t}\n\n\t// Extract everything between the space and the final newline.\n\trec, nl, rem := s[sp+1:n-1], s[n-1:n], s[n:]\n\tif nl != \"\\n\" {\n\t\treturn \"\", \"\", s, ErrHeader\n\t}\n\n\t// The first equals separates the key from the value.\n\teq := strings.IndexByte(rec, '=')\n\tif eq == -1 {\n\t\treturn \"\", \"\", s, ErrHeader\n\t}\n\tk, v = rec[:eq], rec[eq+1:]\n\n\tif !validPAXRecord(k, v) {\n\t\treturn \"\", \"\", s, ErrHeader\n\t}\n\treturn k, v, rem, nil\n}\n\n// formatPAXRecord formats a single PAX record, prefixing it with the\n// appropriate length.\nfunc formatPAXRecord(k, v string) (string, error) {\n\tif !validPAXRecord(k, v) {\n\t\treturn \"\", ErrHeader\n\t}\n\n\tconst padding = 3 // Extra padding for ' ', '=', and '\\n'\n\tsize := len(k) + len(v) + padding\n\tsize += len(strconv.Itoa(size))\n\trecord := strconv.Itoa(size) + \" \" + k + \"=\" + v + \"\\n\"\n\n\t// Final adjustment if adding size field increased the record size.\n\tif len(record) != size {\n\t\tsize = len(record)\n\t\trecord = strconv.Itoa(size) + \" \" + k + \"=\" + v + \"\\n\"\n\t}\n\treturn record, nil\n}\n\n// validPAXRecord reports whether the key-value pair is valid where each\n// record is formatted as:\n//\t\"%d %s=%s\\n\" % (size, key, value)\n//\n// Keys and values should be UTF-8, but the number of bad writers out there\n// forces us to be a more liberal.\n// Thus, we only reject all keys with NUL, and only reject NULs in values\n// for the PAX version of the USTAR string fields.\n// The key must not contain an '=' character.\nfunc validPAXRecord(k, v string) bool {\n\tif k == \"\" || strings.IndexByte(k, '=') >= 0 {\n\t\treturn false\n\t}\n\tswitch k {\n\tcase paxPath, paxLinkpath, paxUname, paxGname:\n\t\treturn !hasNUL(v)\n\tdefault:\n\t\treturn !hasNUL(k)\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/vbatts/tar-split/archive/tar/writer.go",
    "content": "// Copyright 2009 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 tar\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"path\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n)\n\n// Writer provides sequential writing of a tar archive.\n// Write.WriteHeader begins a new file with the provided Header,\n// and then Writer can be treated as an io.Writer to supply that file's data.\ntype Writer struct {\n\tw    io.Writer\n\tpad  int64      // Amount of padding to write after current file entry\n\tcurr fileWriter // Writer for current file entry\n\thdr  Header     // Shallow copy of Header that is safe for mutations\n\tblk  block      // Buffer to use as temporary local storage\n\n\t// err is a persistent error.\n\t// It is only the responsibility of every exported method of Writer to\n\t// ensure that this error is sticky.\n\terr error\n}\n\n// NewWriter creates a new Writer writing to w.\nfunc NewWriter(w io.Writer) *Writer {\n\treturn &Writer{w: w, curr: &regFileWriter{w, 0}}\n}\n\ntype fileWriter interface {\n\tio.Writer\n\tfileState\n\n\tReadFrom(io.Reader) (int64, error)\n}\n\n// Flush finishes writing the current file's block padding.\n// The current file must be fully written before Flush can be called.\n//\n// This is unnecessary as the next call to WriteHeader or Close\n// will implicitly flush out the file's padding.\nfunc (tw *Writer) Flush() error {\n\tif tw.err != nil {\n\t\treturn tw.err\n\t}\n\tif nb := tw.curr.LogicalRemaining(); nb > 0 {\n\t\treturn fmt.Errorf(\"archive/tar: missed writing %d bytes\", nb)\n\t}\n\tif _, tw.err = tw.w.Write(zeroBlock[:tw.pad]); tw.err != nil {\n\t\treturn tw.err\n\t}\n\ttw.pad = 0\n\treturn nil\n}\n\n// WriteHeader writes hdr and prepares to accept the file's contents.\n// The Header.Size determines how many bytes can be written for the next file.\n// If the current file is not fully written, then this returns an error.\n// This implicitly flushes any padding necessary before writing the header.\nfunc (tw *Writer) WriteHeader(hdr *Header) error {\n\tif err := tw.Flush(); err != nil {\n\t\treturn err\n\t}\n\ttw.hdr = *hdr // Shallow copy of Header\n\n\t// Avoid usage of the legacy TypeRegA flag, and automatically promote\n\t// it to use TypeReg or TypeDir.\n\tif tw.hdr.Typeflag == TypeRegA {\n\t\tif strings.HasSuffix(tw.hdr.Name, \"/\") {\n\t\t\ttw.hdr.Typeflag = TypeDir\n\t\t} else {\n\t\t\ttw.hdr.Typeflag = TypeReg\n\t\t}\n\t}\n\n\t// Round ModTime and ignore AccessTime and ChangeTime unless\n\t// the format is explicitly chosen.\n\t// This ensures nominal usage of WriteHeader (without specifying the format)\n\t// does not always result in the PAX format being chosen, which\n\t// causes a 1KiB increase to every header.\n\tif tw.hdr.Format == FormatUnknown {\n\t\ttw.hdr.ModTime = tw.hdr.ModTime.Round(time.Second)\n\t\ttw.hdr.AccessTime = time.Time{}\n\t\ttw.hdr.ChangeTime = time.Time{}\n\t}\n\n\tallowedFormats, paxHdrs, err := tw.hdr.allowedFormats()\n\tswitch {\n\tcase allowedFormats.has(FormatUSTAR):\n\t\ttw.err = tw.writeUSTARHeader(&tw.hdr)\n\t\treturn tw.err\n\tcase allowedFormats.has(FormatPAX):\n\t\ttw.err = tw.writePAXHeader(&tw.hdr, paxHdrs)\n\t\treturn tw.err\n\tcase allowedFormats.has(FormatGNU):\n\t\ttw.err = tw.writeGNUHeader(&tw.hdr)\n\t\treturn tw.err\n\tdefault:\n\t\treturn err // Non-fatal error\n\t}\n}\n\nfunc (tw *Writer) writeUSTARHeader(hdr *Header) error {\n\t// Check if we can use USTAR prefix/suffix splitting.\n\tvar namePrefix string\n\tif prefix, suffix, ok := splitUSTARPath(hdr.Name); ok {\n\t\tnamePrefix, hdr.Name = prefix, suffix\n\t}\n\n\t// Pack the main header.\n\tvar f formatter\n\tblk := tw.templateV7Plus(hdr, f.formatString, f.formatOctal)\n\tf.formatString(blk.USTAR().Prefix(), namePrefix)\n\tblk.SetFormat(FormatUSTAR)\n\tif f.err != nil {\n\t\treturn f.err // Should never happen since header is validated\n\t}\n\treturn tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag)\n}\n\nfunc (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {\n\trealName, realSize := hdr.Name, hdr.Size\n\n\t// TODO(dsnet): Re-enable this when adding sparse support.\n\t// See https://golang.org/issue/22735\n\t/*\n\t\t// Handle sparse files.\n\t\tvar spd sparseDatas\n\t\tvar spb []byte\n\t\tif len(hdr.SparseHoles) > 0 {\n\t\t\tsph := append([]sparseEntry{}, hdr.SparseHoles...) // Copy sparse map\n\t\t\tsph = alignSparseEntries(sph, hdr.Size)\n\t\t\tspd = invertSparseEntries(sph, hdr.Size)\n\n\t\t\t// Format the sparse map.\n\t\t\thdr.Size = 0 // Replace with encoded size\n\t\t\tspb = append(strconv.AppendInt(spb, int64(len(spd)), 10), '\\n')\n\t\t\tfor _, s := range spd {\n\t\t\t\thdr.Size += s.Length\n\t\t\t\tspb = append(strconv.AppendInt(spb, s.Offset, 10), '\\n')\n\t\t\t\tspb = append(strconv.AppendInt(spb, s.Length, 10), '\\n')\n\t\t\t}\n\t\t\tpad := blockPadding(int64(len(spb)))\n\t\t\tspb = append(spb, zeroBlock[:pad]...)\n\t\t\thdr.Size += int64(len(spb)) // Accounts for encoded sparse map\n\n\t\t\t// Add and modify appropriate PAX records.\n\t\t\tdir, file := path.Split(realName)\n\t\t\thdr.Name = path.Join(dir, \"GNUSparseFile.0\", file)\n\t\t\tpaxHdrs[paxGNUSparseMajor] = \"1\"\n\t\t\tpaxHdrs[paxGNUSparseMinor] = \"0\"\n\t\t\tpaxHdrs[paxGNUSparseName] = realName\n\t\t\tpaxHdrs[paxGNUSparseRealSize] = strconv.FormatInt(realSize, 10)\n\t\t\tpaxHdrs[paxSize] = strconv.FormatInt(hdr.Size, 10)\n\t\t\tdelete(paxHdrs, paxPath) // Recorded by paxGNUSparseName\n\t\t}\n\t*/\n\t_ = realSize\n\n\t// Write PAX records to the output.\n\tisGlobal := hdr.Typeflag == TypeXGlobalHeader\n\tif len(paxHdrs) > 0 || isGlobal {\n\t\t// Sort keys for deterministic ordering.\n\t\tvar keys []string\n\t\tfor k := range paxHdrs {\n\t\t\tkeys = append(keys, k)\n\t\t}\n\t\tsort.Strings(keys)\n\n\t\t// Write each record to a buffer.\n\t\tvar buf strings.Builder\n\t\tfor _, k := range keys {\n\t\t\trec, err := formatPAXRecord(k, paxHdrs[k])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tbuf.WriteString(rec)\n\t\t}\n\n\t\t// Write the extended header file.\n\t\tvar name string\n\t\tvar flag byte\n\t\tif isGlobal {\n\t\t\tname = realName\n\t\t\tif name == \"\" {\n\t\t\t\tname = \"GlobalHead.0.0\"\n\t\t\t}\n\t\t\tflag = TypeXGlobalHeader\n\t\t} else {\n\t\t\tdir, file := path.Split(realName)\n\t\t\tname = path.Join(dir, \"PaxHeaders.0\", file)\n\t\t\tflag = TypeXHeader\n\t\t}\n\t\tdata := buf.String()\n\t\tif err := tw.writeRawFile(name, data, flag, FormatPAX); err != nil || isGlobal {\n\t\t\treturn err // Global headers return here\n\t\t}\n\t}\n\n\t// Pack the main header.\n\tvar f formatter // Ignore errors since they are expected\n\tfmtStr := func(b []byte, s string) { f.formatString(b, toASCII(s)) }\n\tblk := tw.templateV7Plus(hdr, fmtStr, f.formatOctal)\n\tblk.SetFormat(FormatPAX)\n\tif err := tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag); err != nil {\n\t\treturn err\n\t}\n\n\t// TODO(dsnet): Re-enable this when adding sparse support.\n\t// See https://golang.org/issue/22735\n\t/*\n\t\t// Write the sparse map and setup the sparse writer if necessary.\n\t\tif len(spd) > 0 {\n\t\t\t// Use tw.curr since the sparse map is accounted for in hdr.Size.\n\t\t\tif _, err := tw.curr.Write(spb); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\ttw.curr = &sparseFileWriter{tw.curr, spd, 0}\n\t\t}\n\t*/\n\treturn nil\n}\n\nfunc (tw *Writer) writeGNUHeader(hdr *Header) error {\n\t// Use long-link files if Name or Linkname exceeds the field size.\n\tconst longName = \"././@LongLink\"\n\tif len(hdr.Name) > nameSize {\n\t\tdata := hdr.Name + \"\\x00\"\n\t\tif err := tw.writeRawFile(longName, data, TypeGNULongName, FormatGNU); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif len(hdr.Linkname) > nameSize {\n\t\tdata := hdr.Linkname + \"\\x00\"\n\t\tif err := tw.writeRawFile(longName, data, TypeGNULongLink, FormatGNU); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Pack the main header.\n\tvar f formatter // Ignore errors since they are expected\n\tvar spd sparseDatas\n\tvar spb []byte\n\tblk := tw.templateV7Plus(hdr, f.formatString, f.formatNumeric)\n\tif !hdr.AccessTime.IsZero() {\n\t\tf.formatNumeric(blk.GNU().AccessTime(), hdr.AccessTime.Unix())\n\t}\n\tif !hdr.ChangeTime.IsZero() {\n\t\tf.formatNumeric(blk.GNU().ChangeTime(), hdr.ChangeTime.Unix())\n\t}\n\t// TODO(dsnet): Re-enable this when adding sparse support.\n\t// See https://golang.org/issue/22735\n\t/*\n\t\tif hdr.Typeflag == TypeGNUSparse {\n\t\t\tsph := append([]sparseEntry{}, hdr.SparseHoles...) // Copy sparse map\n\t\t\tsph = alignSparseEntries(sph, hdr.Size)\n\t\t\tspd = invertSparseEntries(sph, hdr.Size)\n\n\t\t\t// Format the sparse map.\n\t\t\tformatSPD := func(sp sparseDatas, sa sparseArray) sparseDatas {\n\t\t\t\tfor i := 0; len(sp) > 0 && i < sa.MaxEntries(); i++ {\n\t\t\t\t\tf.formatNumeric(sa.Entry(i).Offset(), sp[0].Offset)\n\t\t\t\t\tf.formatNumeric(sa.Entry(i).Length(), sp[0].Length)\n\t\t\t\t\tsp = sp[1:]\n\t\t\t\t}\n\t\t\t\tif len(sp) > 0 {\n\t\t\t\t\tsa.IsExtended()[0] = 1\n\t\t\t\t}\n\t\t\t\treturn sp\n\t\t\t}\n\t\t\tsp2 := formatSPD(spd, blk.GNU().Sparse())\n\t\t\tfor len(sp2) > 0 {\n\t\t\t\tvar spHdr block\n\t\t\t\tsp2 = formatSPD(sp2, spHdr.Sparse())\n\t\t\t\tspb = append(spb, spHdr[:]...)\n\t\t\t}\n\n\t\t\t// Update size fields in the header block.\n\t\t\trealSize := hdr.Size\n\t\t\thdr.Size = 0 // Encoded size; does not account for encoded sparse map\n\t\t\tfor _, s := range spd {\n\t\t\t\thdr.Size += s.Length\n\t\t\t}\n\t\t\tcopy(blk.V7().Size(), zeroBlock[:]) // Reset field\n\t\t\tf.formatNumeric(blk.V7().Size(), hdr.Size)\n\t\t\tf.formatNumeric(blk.GNU().RealSize(), realSize)\n\t\t}\n\t*/\n\tblk.SetFormat(FormatGNU)\n\tif err := tw.writeRawHeader(blk, hdr.Size, hdr.Typeflag); err != nil {\n\t\treturn err\n\t}\n\n\t// Write the extended sparse map and setup the sparse writer if necessary.\n\tif len(spd) > 0 {\n\t\t// Use tw.w since the sparse map is not accounted for in hdr.Size.\n\t\tif _, err := tw.w.Write(spb); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ttw.curr = &sparseFileWriter{tw.curr, spd, 0}\n\t}\n\treturn nil\n}\n\ntype (\n\tstringFormatter func([]byte, string)\n\tnumberFormatter func([]byte, int64)\n)\n\n// templateV7Plus fills out the V7 fields of a block using values from hdr.\n// It also fills out fields (uname, gname, devmajor, devminor) that are\n// shared in the USTAR, PAX, and GNU formats using the provided formatters.\n//\n// The block returned is only valid until the next call to\n// templateV7Plus or writeRawFile.\nfunc (tw *Writer) templateV7Plus(hdr *Header, fmtStr stringFormatter, fmtNum numberFormatter) *block {\n\ttw.blk.Reset()\n\n\tmodTime := hdr.ModTime\n\tif modTime.IsZero() {\n\t\tmodTime = time.Unix(0, 0)\n\t}\n\n\tv7 := tw.blk.V7()\n\tv7.TypeFlag()[0] = hdr.Typeflag\n\tfmtStr(v7.Name(), hdr.Name)\n\tfmtStr(v7.LinkName(), hdr.Linkname)\n\tfmtNum(v7.Mode(), hdr.Mode)\n\tfmtNum(v7.UID(), int64(hdr.Uid))\n\tfmtNum(v7.GID(), int64(hdr.Gid))\n\tfmtNum(v7.Size(), hdr.Size)\n\tfmtNum(v7.ModTime(), modTime.Unix())\n\n\tustar := tw.blk.USTAR()\n\tfmtStr(ustar.UserName(), hdr.Uname)\n\tfmtStr(ustar.GroupName(), hdr.Gname)\n\tfmtNum(ustar.DevMajor(), hdr.Devmajor)\n\tfmtNum(ustar.DevMinor(), hdr.Devminor)\n\n\treturn &tw.blk\n}\n\n// writeRawFile writes a minimal file with the given name and flag type.\n// It uses format to encode the header format and will write data as the body.\n// It uses default values for all of the other fields (as BSD and GNU tar does).\nfunc (tw *Writer) writeRawFile(name, data string, flag byte, format Format) error {\n\ttw.blk.Reset()\n\n\t// Best effort for the filename.\n\tname = toASCII(name)\n\tif len(name) > nameSize {\n\t\tname = name[:nameSize]\n\t}\n\tname = strings.TrimRight(name, \"/\")\n\n\tvar f formatter\n\tv7 := tw.blk.V7()\n\tv7.TypeFlag()[0] = flag\n\tf.formatString(v7.Name(), name)\n\tf.formatOctal(v7.Mode(), 0)\n\tf.formatOctal(v7.UID(), 0)\n\tf.formatOctal(v7.GID(), 0)\n\tf.formatOctal(v7.Size(), int64(len(data))) // Must be < 8GiB\n\tf.formatOctal(v7.ModTime(), 0)\n\ttw.blk.SetFormat(format)\n\tif f.err != nil {\n\t\treturn f.err // Only occurs if size condition is violated\n\t}\n\n\t// Write the header and data.\n\tif err := tw.writeRawHeader(&tw.blk, int64(len(data)), flag); err != nil {\n\t\treturn err\n\t}\n\t_, err := io.WriteString(tw, data)\n\treturn err\n}\n\n// writeRawHeader writes the value of blk, regardless of its value.\n// It sets up the Writer such that it can accept a file of the given size.\n// If the flag is a special header-only flag, then the size is treated as zero.\nfunc (tw *Writer) writeRawHeader(blk *block, size int64, flag byte) error {\n\tif err := tw.Flush(); err != nil {\n\t\treturn err\n\t}\n\tif _, err := tw.w.Write(blk[:]); err != nil {\n\t\treturn err\n\t}\n\tif isHeaderOnlyType(flag) {\n\t\tsize = 0\n\t}\n\ttw.curr = &regFileWriter{tw.w, size}\n\ttw.pad = blockPadding(size)\n\treturn nil\n}\n\n// splitUSTARPath splits a path according to USTAR prefix and suffix rules.\n// If the path is not splittable, then it will return (\"\", \"\", false).\nfunc splitUSTARPath(name string) (prefix, suffix string, ok bool) {\n\tlength := len(name)\n\tif length <= nameSize || !isASCII(name) {\n\t\treturn \"\", \"\", false\n\t} else if length > prefixSize+1 {\n\t\tlength = prefixSize + 1\n\t} else if name[length-1] == '/' {\n\t\tlength--\n\t}\n\n\ti := strings.LastIndex(name[:length], \"/\")\n\tnlen := len(name) - i - 1 // nlen is length of suffix\n\tplen := i                 // plen is length of prefix\n\tif i <= 0 || nlen > nameSize || nlen == 0 || plen > prefixSize {\n\t\treturn \"\", \"\", false\n\t}\n\treturn name[:i], name[i+1:], true\n}\n\n// Write writes to the current file in the tar archive.\n// Write returns the error ErrWriteTooLong if more than\n// Header.Size bytes are written after WriteHeader.\n//\n// Calling Write on special types like TypeLink, TypeSymlink, TypeChar,\n// TypeBlock, TypeDir, and TypeFifo returns (0, ErrWriteTooLong) regardless\n// of what the Header.Size claims.\nfunc (tw *Writer) Write(b []byte) (int, error) {\n\tif tw.err != nil {\n\t\treturn 0, tw.err\n\t}\n\tn, err := tw.curr.Write(b)\n\tif err != nil && err != ErrWriteTooLong {\n\t\ttw.err = err\n\t}\n\treturn n, err\n}\n\n// readFrom populates the content of the current file by reading from r.\n// The bytes read must match the number of remaining bytes in the current file.\n//\n// If the current file is sparse and r is an io.ReadSeeker,\n// then readFrom uses Seek to skip past holes defined in Header.SparseHoles,\n// assuming that skipped regions are all NULs.\n// This always reads the last byte to ensure r is the right size.\n//\n// TODO(dsnet): Re-export this when adding sparse file support.\n// See https://golang.org/issue/22735\nfunc (tw *Writer) readFrom(r io.Reader) (int64, error) {\n\tif tw.err != nil {\n\t\treturn 0, tw.err\n\t}\n\tn, err := tw.curr.ReadFrom(r)\n\tif err != nil && err != ErrWriteTooLong {\n\t\ttw.err = err\n\t}\n\treturn n, err\n}\n\n// Close closes the tar archive by flushing the padding, and writing the footer.\n// If the current file (from a prior call to WriteHeader) is not fully written,\n// then this returns an error.\nfunc (tw *Writer) Close() error {\n\tif tw.err == ErrWriteAfterClose {\n\t\treturn nil\n\t}\n\tif tw.err != nil {\n\t\treturn tw.err\n\t}\n\n\t// Trailer: two zero blocks.\n\terr := tw.Flush()\n\tfor i := 0; i < 2 && err == nil; i++ {\n\t\t_, err = tw.w.Write(zeroBlock[:])\n\t}\n\n\t// Ensure all future actions are invalid.\n\ttw.err = ErrWriteAfterClose\n\treturn err // Report IO errors\n}\n\n// regFileWriter is a fileWriter for writing data to a regular file entry.\ntype regFileWriter struct {\n\tw  io.Writer // Underlying Writer\n\tnb int64     // Number of remaining bytes to write\n}\n\nfunc (fw *regFileWriter) Write(b []byte) (n int, err error) {\n\toverwrite := int64(len(b)) > fw.nb\n\tif overwrite {\n\t\tb = b[:fw.nb]\n\t}\n\tif len(b) > 0 {\n\t\tn, err = fw.w.Write(b)\n\t\tfw.nb -= int64(n)\n\t}\n\tswitch {\n\tcase err != nil:\n\t\treturn n, err\n\tcase overwrite:\n\t\treturn n, ErrWriteTooLong\n\tdefault:\n\t\treturn n, nil\n\t}\n}\n\nfunc (fw *regFileWriter) ReadFrom(r io.Reader) (int64, error) {\n\treturn io.Copy(struct{ io.Writer }{fw}, r)\n}\n\nfunc (fw regFileWriter) LogicalRemaining() int64 {\n\treturn fw.nb\n}\nfunc (fw regFileWriter) PhysicalRemaining() int64 {\n\treturn fw.nb\n}\n\n// sparseFileWriter is a fileWriter for writing data to a sparse file entry.\ntype sparseFileWriter struct {\n\tfw  fileWriter  // Underlying fileWriter\n\tsp  sparseDatas // Normalized list of data fragments\n\tpos int64       // Current position in sparse file\n}\n\nfunc (sw *sparseFileWriter) Write(b []byte) (n int, err error) {\n\toverwrite := int64(len(b)) > sw.LogicalRemaining()\n\tif overwrite {\n\t\tb = b[:sw.LogicalRemaining()]\n\t}\n\n\tb0 := b\n\tendPos := sw.pos + int64(len(b))\n\tfor endPos > sw.pos && err == nil {\n\t\tvar nf int // Bytes written in fragment\n\t\tdataStart, dataEnd := sw.sp[0].Offset, sw.sp[0].endOffset()\n\t\tif sw.pos < dataStart { // In a hole fragment\n\t\t\tbf := b[:min(int64(len(b)), dataStart-sw.pos)]\n\t\t\tnf, err = zeroWriter{}.Write(bf)\n\t\t} else { // In a data fragment\n\t\t\tbf := b[:min(int64(len(b)), dataEnd-sw.pos)]\n\t\t\tnf, err = sw.fw.Write(bf)\n\t\t}\n\t\tb = b[nf:]\n\t\tsw.pos += int64(nf)\n\t\tif sw.pos >= dataEnd && len(sw.sp) > 1 {\n\t\t\tsw.sp = sw.sp[1:] // Ensure last fragment always remains\n\t\t}\n\t}\n\n\tn = len(b0) - len(b)\n\tswitch {\n\tcase err == ErrWriteTooLong:\n\t\treturn n, errMissData // Not possible; implies bug in validation logic\n\tcase err != nil:\n\t\treturn n, err\n\tcase sw.LogicalRemaining() == 0 && sw.PhysicalRemaining() > 0:\n\t\treturn n, errUnrefData // Not possible; implies bug in validation logic\n\tcase overwrite:\n\t\treturn n, ErrWriteTooLong\n\tdefault:\n\t\treturn n, nil\n\t}\n}\n\nfunc (sw *sparseFileWriter) ReadFrom(r io.Reader) (n int64, err error) {\n\trs, ok := r.(io.ReadSeeker)\n\tif ok {\n\t\tif _, err := rs.Seek(0, io.SeekCurrent); err != nil {\n\t\t\tok = false // Not all io.Seeker can really seek\n\t\t}\n\t}\n\tif !ok {\n\t\treturn io.Copy(struct{ io.Writer }{sw}, r)\n\t}\n\n\tvar readLastByte bool\n\tpos0 := sw.pos\n\tfor sw.LogicalRemaining() > 0 && !readLastByte && err == nil {\n\t\tvar nf int64 // Size of fragment\n\t\tdataStart, dataEnd := sw.sp[0].Offset, sw.sp[0].endOffset()\n\t\tif sw.pos < dataStart { // In a hole fragment\n\t\t\tnf = dataStart - sw.pos\n\t\t\tif sw.PhysicalRemaining() == 0 {\n\t\t\t\treadLastByte = true\n\t\t\t\tnf--\n\t\t\t}\n\t\t\t_, err = rs.Seek(nf, io.SeekCurrent)\n\t\t} else { // In a data fragment\n\t\t\tnf = dataEnd - sw.pos\n\t\t\tnf, err = io.CopyN(sw.fw, rs, nf)\n\t\t}\n\t\tsw.pos += nf\n\t\tif sw.pos >= dataEnd && len(sw.sp) > 1 {\n\t\t\tsw.sp = sw.sp[1:] // Ensure last fragment always remains\n\t\t}\n\t}\n\n\t// If the last fragment is a hole, then seek to 1-byte before EOF, and\n\t// read a single byte to ensure the file is the right size.\n\tif readLastByte && err == nil {\n\t\t_, err = mustReadFull(rs, []byte{0})\n\t\tsw.pos++\n\t}\n\n\tn = sw.pos - pos0\n\tswitch {\n\tcase err == io.EOF:\n\t\treturn n, io.ErrUnexpectedEOF\n\tcase err == ErrWriteTooLong:\n\t\treturn n, errMissData // Not possible; implies bug in validation logic\n\tcase err != nil:\n\t\treturn n, err\n\tcase sw.LogicalRemaining() == 0 && sw.PhysicalRemaining() > 0:\n\t\treturn n, errUnrefData // Not possible; implies bug in validation logic\n\tdefault:\n\t\treturn n, ensureEOF(rs)\n\t}\n}\n\nfunc (sw sparseFileWriter) LogicalRemaining() int64 {\n\treturn sw.sp[len(sw.sp)-1].endOffset() - sw.pos\n}\nfunc (sw sparseFileWriter) PhysicalRemaining() int64 {\n\treturn sw.fw.PhysicalRemaining()\n}\n\n// zeroWriter may only be written with NULs, otherwise it returns errWriteHole.\ntype zeroWriter struct{}\n\nfunc (zeroWriter) Write(b []byte) (int, error) {\n\tfor i, c := range b {\n\t\tif c != 0 {\n\t\t\treturn i, errWriteHole\n\t\t}\n\t}\n\treturn len(b), nil\n}\n\n// ensureEOF checks whether r is at EOF, reporting ErrWriteTooLong if not so.\nfunc ensureEOF(r io.Reader) error {\n\tn, err := tryReadFull(r, []byte{0})\n\tswitch {\n\tcase n > 0:\n\t\treturn ErrWriteTooLong\n\tcase err == io.EOF:\n\t\treturn nil\n\tdefault:\n\t\treturn err\n\t}\n}\n"
  },
  {
    "path": "vendor/github.com/xlab/treeprint/LICENSE",
    "content": "The MIT License (MIT)\nCopyright © 2016 Maxim Kupriianov <max@kc.vc>\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\nall copies 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\nTHE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/xlab/treeprint/README.md",
    "content": "treeprint [![GoDoc](https://godoc.org/github.com/xlab/treeprint?status.svg)](https://godoc.org/github.com/xlab/treeprint) ![test coverage](https://img.shields.io/badge/coverage-68.6%25-green.svg)\n=========\n\nPackage `treeprint` provides a simple ASCII tree composing tool.\n\n<a href=\"https://upload.wikimedia.org/wikipedia/commons/5/58/ENC_SYSTEME_FIGURE.jpeg\"><img alt=\"SYSTEME FIGURE\" src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/5/58/ENC_SYSTEME_FIGURE.jpeg/896px-ENC_SYSTEME_FIGURE.jpeg\" align=\"left\" width=\"300\"></a>\n\nIf you are familiar with the [tree](http://mama.indstate.edu/users/ice/tree/) utility that is a recursive directory listing command that produces a depth indented listing of files, then you have the idea of what it would look like.\n\nOn my system the command yields the following\n\n```\n $ tree\n.\n├── LICENSE\n├── README.md\n├── treeprint.go\n└── treeprint_test.go\n\n0 directories, 4 files\n```\n\nand I'd like to have the same format for my Go data structures when I print them.\n\n## Installation\n\n```\n$ go get github.com/xlab/treeprint\n```\n\n## Concept of work\n\nThe general idea is that you initialise a new tree with `treeprint.New()` and then add nodes and\nbranches into it. Use `AddNode()` when you want add a node on the same level as the target or\nuse `AddBranch()` when you want to go a level deeper. So `tree.AddBranch().AddNode().AddNode()` would\ncreate a new level with two distinct nodes on it. So `tree.AddNode().AddNode()` is a flat thing and\n`tree.AddBranch().AddBranch().AddBranch()` is a high thing. Use `String()` or `Bytes()` on a branch\nto render a subtree, or use it on the root to print the whole tree.\n\nThe utility will yield Unicode-friendly trees. The output is predictable and there is no platform-dependent exceptions, so if you have issues with displaying the tree in the console, all platform-related transformations can be done after the tree has been rendered: [an example](https://github.com/xlab/treeprint/issues/2#issuecomment-324944141) for Asian locales.\n\n## Use cases\n\n### When you want to render a complex data structure:\n\n```go\nfunc main() {\n    // to add a custom root name use `treeprint.NewWithRoot()` instead\n    tree := treeprint.New()\n\n    // create a new branch in the root\n    one := tree.AddBranch(\"one\")\n\n    // add some nodes\n    one.AddNode(\"subnode1\").AddNode(\"subnode2\")\n\n    // create a new sub-branch\n    one.AddBranch(\"two\").\n        AddNode(\"subnode1\").AddNode(\"subnode2\"). // add some nodes\n        AddBranch(\"three\"). // add a new sub-branch\n        AddNode(\"subnode1\").AddNode(\"subnode2\") // add some nodes too\n\n    // add one more node that should surround the inner branch\n    one.AddNode(\"subnode3\")\n\n    // add a new node to the root\n    tree.AddNode(\"outernode\")\n\n    fmt.Println(tree.String())\n}\n```\n\nWill give you:\n\n```\n.\n├── one\n│   ├── subnode1\n│   ├── subnode2\n│   ├── two\n│   │   ├── subnode1\n│   │   ├── subnode2\n│   │   └── three\n│   │       ├── subnode1\n│   │       └── subnode2\n│   └── subnode3\n└── outernode\n```\n\n### Another case, when you have to make a tree where any leaf may have some meta-data (as `tree` is capable of it):\n\n```go\nfunc main {\n    // to add a custom root name use `treeprint.NewWithRoot()` instead\n    tree := treeprint.New()\n\n    tree.AddNode(\"Dockerfile\")\n    tree.AddNode(\"Makefile\")\n    tree.AddNode(\"aws.sh\")\n    tree.AddMetaBranch(\" 204\", \"bin\").\n        AddNode(\"dbmaker\").AddNode(\"someserver\").AddNode(\"testtool\")\n    tree.AddMetaBranch(\" 374\", \"deploy\").\n        AddNode(\"Makefile\").AddNode(\"bootstrap.sh\")\n    tree.AddMetaNode(\"122K\", \"testtool.a\")\n\n    fmt.Println(tree.String())\n}\n```\n\nOutput:\n\n```\n.\n├── Dockerfile\n├── Makefile\n├── aws.sh\n├── [ 204]  bin\n│   ├── dbmaker\n│   ├── someserver\n│   └── testtool\n├── [ 374]  deploy\n│   ├── Makefile\n│   └── bootstrap.sh\n└── [122K]  testtool.a\n```\n\n### Iterating over the tree nodes\n\n```go\ntree := New()\n\none := tree.AddBranch(\"one\")\none.AddNode(\"one-subnode1\").AddNode(\"one-subnode2\")\none.AddBranch(\"two\").AddNode(\"two-subnode1\").AddNode(\"two-subnode2\").\n    AddBranch(\"three\").AddNode(\"three-subnode1\").AddNode(\"three-subnode2\")\ntree.AddNode(\"outernode\")\n\n// if you need to iterate over the whole tree\n// call `VisitAll` from your top root node.\ntree.VisitAll(func(item *node) {\n    if len(item.Nodes) > 0 {\n        // branch nodes\n        fmt.Println(item.Value) // will output one, two, three\n    } else {\n        // leaf nodes\n        fmt.Println(item.Value) // will output one-*, two-*, three-* and outernode\n    }\n})\n\n```\nYay! So it works.\n\n## License\nMIT\n"
  },
  {
    "path": "vendor/github.com/xlab/treeprint/helpers.go",
    "content": "package treeprint\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n)\n\nfunc isEmpty(v *reflect.Value) bool {\n\tswitch v.Kind() {\n\tcase reflect.Array, reflect.Map, reflect.Slice, reflect.String:\n\t\treturn v.Len() == 0\n\tcase reflect.Bool:\n\t\treturn !v.Bool()\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\treturn v.Int() == 0\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:\n\t\treturn v.Uint() == 0\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn v.Float() == 0\n\tcase reflect.Interface, reflect.Ptr:\n\t\treturn v.IsNil()\n\t}\n\treturn false\n}\n\nfunc tagSpec(tag string) (name string, omit bool) {\n\tparts := strings.Split(tag, \",\")\n\tif len(parts) < 2 {\n\t\treturn tag, false\n\t}\n\tif parts[1] == \"omitempty\" {\n\t\treturn parts[0], true\n\t}\n\treturn parts[0], false\n}\n\nfunc filterTags(tag reflect.StructTag) string {\n\ttags := strings.Split(string(tag), \" \")\n\tfiltered := make([]string, 0, len(tags))\n\tfor i := range tags {\n\t\tif strings.HasPrefix(tags[i], \"tree:\") {\n\t\t\tcontinue\n\t\t}\n\t\tfiltered = append(filtered, tags[i])\n\t}\n\treturn strings.Join(filtered, \" \")\n}\n"
  },
  {
    "path": "vendor/github.com/xlab/treeprint/struct.go",
    "content": "package treeprint\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"strings\"\n)\n\ntype StructTreeOption int\n\nconst (\n\tStructNameTree StructTreeOption = iota\n\tStructValueTree\n\tStructTagTree\n\tStructTypeTree\n\tStructTypeSizeTree\n)\n\nfunc FromStruct(v interface{}, opt ...StructTreeOption) (Tree, error) {\n\tvar treeOpt StructTreeOption\n\tif len(opt) > 0 {\n\t\ttreeOpt = opt[0]\n\t}\n\tswitch treeOpt {\n\tcase StructNameTree:\n\t\ttree := New()\n\t\terr := nameTree(tree, v)\n\t\treturn tree, err\n\tcase StructValueTree:\n\t\ttree := New()\n\t\terr := valueTree(tree, v)\n\t\treturn tree, err\n\tcase StructTagTree:\n\t\ttree := New()\n\t\terr := tagTree(tree, v)\n\t\treturn tree, err\n\tcase StructTypeTree:\n\t\ttree := New()\n\t\terr := typeTree(tree, v)\n\t\treturn tree, err\n\tcase StructTypeSizeTree:\n\t\ttree := New()\n\t\terr := typeSizeTree(tree, v)\n\t\treturn tree, err\n\tdefault:\n\t\terr := fmt.Errorf(\"treeprint: invalid StructTreeOption %v\", treeOpt)\n\t\treturn nil, err\n\t}\n}\n\ntype FmtFunc func(name string, v interface{}) (string, bool)\n\nfunc FromStructWithMeta(v interface{}, fmtFunc FmtFunc) (Tree, error) {\n\tif fmtFunc == nil {\n\t\ttree := New()\n\t\terr := nameTree(tree, v)\n\t\treturn tree, err\n\t}\n\ttree := New()\n\terr := metaTree(tree, v, fmtFunc)\n\treturn tree, err\n}\n\nfunc Repr(v interface{}) string {\n\ttree := New()\n\tvType := reflect.TypeOf(v)\n\tvValue := reflect.ValueOf(v)\n\t_, val, isStruct := getValue(vType, &vValue)\n\tif !isStruct {\n\t\treturn fmt.Sprintf(\"%+v\", val.Interface())\n\t}\n\terr := valueTree(tree, val.Interface())\n\tif err != nil {\n\t\treturn err.Error()\n\t}\n\treturn tree.String()\n}\n\nfunc nameTree(tree Tree, v interface{}) error {\n\ttyp, val, err := checkType(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfields := typ.NumField()\n\tfor i := 0; i < fields; i++ {\n\t\tfield := typ.Field(i)\n\t\tfieldValue := val.Field(i)\n\t\tname, skip, omit := getMeta(field.Name, field.Tag)\n\t\tif skip || omit && isEmpty(&fieldValue) {\n\t\t\tcontinue\n\t\t}\n\t\ttyp, val, isStruct := getValue(field.Type, &fieldValue)\n\t\tif !isStruct {\n\t\t\ttree.AddNode(name)\n\t\t\tcontinue\n\t\t} else if subNum := typ.NumField(); subNum == 0 {\n\t\t\ttree.AddNode(name)\n\t\t\tcontinue\n\t\t}\n\t\tbranch := tree.AddBranch(name)\n\t\tif err := nameTree(branch, val.Interface()); err != nil {\n\t\t\terr := fmt.Errorf(\"%v on struct branch %s\", err, name)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc getMeta(fieldName string, tag reflect.StructTag) (name string, skip, omit bool) {\n\tif tagStr := tag.Get(\"tree\"); len(tagStr) > 0 {\n\t\tname, omit = tagSpec(tagStr)\n\t}\n\tif name == \"-\" {\n\t\treturn fieldName, true, omit\n\t}\n\tif len(name) == 0 {\n\t\tname = fieldName\n\t} else if trimmed := strings.TrimSpace(name); len(trimmed) == 0 {\n\t\tname = fieldName\n\t}\n\treturn\n}\n\nfunc valueTree(tree Tree, v interface{}) error {\n\ttyp, val, err := checkType(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfields := typ.NumField()\n\tfor i := 0; i < fields; i++ {\n\t\tfield := typ.Field(i)\n\t\tfieldValue := val.Field(i)\n\t\tname, skip, omit := getMeta(field.Name, field.Tag)\n\t\tif skip || omit && isEmpty(&fieldValue) {\n\t\t\tcontinue\n\t\t}\n\t\ttyp, val, isStruct := getValue(field.Type, &fieldValue)\n\t\tif !isStruct {\n\t\t\ttree.AddMetaNode(val.Interface(), name)\n\t\t\tcontinue\n\t\t} else if subNum := typ.NumField(); subNum == 0 {\n\t\t\ttree.AddMetaNode(val.Interface(), name)\n\t\t\tcontinue\n\t\t}\n\t\tbranch := tree.AddBranch(name)\n\t\tif err := valueTree(branch, val.Interface()); err != nil {\n\t\t\terr := fmt.Errorf(\"%v on struct branch %s\", err, name)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc tagTree(tree Tree, v interface{}) error {\n\ttyp, val, err := checkType(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfields := typ.NumField()\n\tfor i := 0; i < fields; i++ {\n\t\tfield := typ.Field(i)\n\t\tfieldValue := val.Field(i)\n\t\tname, skip, omit := getMeta(field.Name, field.Tag)\n\t\tif skip || omit && isEmpty(&fieldValue) {\n\t\t\tcontinue\n\t\t}\n\t\tfilteredTag := filterTags(field.Tag)\n\t\ttyp, val, isStruct := getValue(field.Type, &fieldValue)\n\t\tif !isStruct {\n\t\t\ttree.AddMetaNode(filteredTag, name)\n\t\t\tcontinue\n\t\t} else if subNum := typ.NumField(); subNum == 0 {\n\t\t\ttree.AddMetaNode(filteredTag, name)\n\t\t\tcontinue\n\t\t}\n\t\tbranch := tree.AddMetaBranch(filteredTag, name)\n\t\tif err := tagTree(branch, val.Interface()); err != nil {\n\t\t\terr := fmt.Errorf(\"%v on struct branch %s\", err, name)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc typeTree(tree Tree, v interface{}) error {\n\ttyp, val, err := checkType(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfields := typ.NumField()\n\tfor i := 0; i < fields; i++ {\n\t\tfield := typ.Field(i)\n\t\tfieldValue := val.Field(i)\n\t\tname, skip, omit := getMeta(field.Name, field.Tag)\n\t\tif skip || omit && isEmpty(&fieldValue) {\n\t\t\tcontinue\n\t\t}\n\t\ttyp, val, isStruct := getValue(field.Type, &fieldValue)\n\t\ttypename := fmt.Sprintf(\"%T\", val.Interface())\n\t\tif !isStruct {\n\t\t\ttree.AddMetaNode(typename, name)\n\t\t\tcontinue\n\t\t} else if subNum := typ.NumField(); subNum == 0 {\n\t\t\ttree.AddMetaNode(typename, name)\n\t\t\tcontinue\n\t\t}\n\t\tbranch := tree.AddMetaBranch(typename, name)\n\t\tif err := typeTree(branch, val.Interface()); err != nil {\n\t\t\terr := fmt.Errorf(\"%v on struct branch %s\", err, name)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc typeSizeTree(tree Tree, v interface{}) error {\n\ttyp, val, err := checkType(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfields := typ.NumField()\n\tfor i := 0; i < fields; i++ {\n\t\tfield := typ.Field(i)\n\t\tfieldValue := val.Field(i)\n\t\tname, skip, omit := getMeta(field.Name, field.Tag)\n\t\tif skip || omit && isEmpty(&fieldValue) {\n\t\t\tcontinue\n\t\t}\n\t\ttyp, val, isStruct := getValue(field.Type, &fieldValue)\n\t\ttypesize := typ.Size()\n\t\tif !isStruct {\n\t\t\ttree.AddMetaNode(typesize, name)\n\t\t\tcontinue\n\t\t} else if subNum := typ.NumField(); subNum == 0 {\n\t\t\ttree.AddMetaNode(typesize, name)\n\t\t\tcontinue\n\t\t}\n\t\tbranch := tree.AddMetaBranch(typesize, name)\n\t\tif err := typeSizeTree(branch, val.Interface()); err != nil {\n\t\t\terr := fmt.Errorf(\"%v on struct branch %s\", err, name)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc metaTree(tree Tree, v interface{}, fmtFunc FmtFunc) error {\n\ttyp, val, err := checkType(v)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfields := typ.NumField()\n\tfor i := 0; i < fields; i++ {\n\t\tfield := typ.Field(i)\n\t\tfieldValue := val.Field(i)\n\t\tname, skip, omit := getMeta(field.Name, field.Tag)\n\t\tif skip || omit && isEmpty(&fieldValue) {\n\t\t\tcontinue\n\t\t}\n\t\ttyp, val, isStruct := getValue(field.Type, &fieldValue)\n\t\tformatted, show := fmtFunc(name, val.Interface())\n\t\tif !isStruct {\n\t\t\tif show {\n\t\t\t\ttree.AddMetaNode(formatted, name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttree.AddNode(name)\n\t\t\tcontinue\n\t\t} else if subNum := typ.NumField(); subNum == 0 {\n\t\t\tif show {\n\t\t\t\ttree.AddMetaNode(formatted, name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\ttree.AddNode(name)\n\t\t\tcontinue\n\t\t}\n\t\tvar branch Tree\n\t\tif show {\n\t\t\tbranch = tree.AddMetaBranch(formatted, name)\n\t\t} else {\n\t\t\tbranch = tree.AddBranch(name)\n\t\t}\n\t\tif err := metaTree(branch, val.Interface(), fmtFunc); err != nil {\n\t\t\terr := fmt.Errorf(\"%v on struct branch %s\", err, name)\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc getValue(typ reflect.Type, val *reflect.Value) (reflect.Type, *reflect.Value, bool) {\n\tswitch typ.Kind() {\n\tcase reflect.Ptr:\n\t\ttyp = typ.Elem()\n\t\tif typ.Kind() == reflect.Struct {\n\t\t\telem := val.Elem()\n\t\t\treturn typ, &elem, true\n\t\t}\n\tcase reflect.Struct:\n\t\treturn typ, val, true\n\t}\n\treturn typ, val, false\n}\n\nfunc checkType(v interface{}) (reflect.Type, *reflect.Value, error) {\n\ttyp := reflect.TypeOf(v)\n\tval := reflect.ValueOf(v)\n\tswitch typ.Kind() {\n\tcase reflect.Ptr:\n\t\ttyp = typ.Elem()\n\t\tif typ.Kind() != reflect.Struct {\n\t\t\terr := fmt.Errorf(\"treeprint: %T is not a struct we could work with\", v)\n\t\t\treturn nil, nil, err\n\t\t}\n\t\tval = val.Elem()\n\tcase reflect.Struct:\n\tdefault:\n\t\terr := fmt.Errorf(\"treeprint: %T is not a struct we could work with\", v)\n\t\treturn nil, nil, err\n\t}\n\treturn typ, &val, nil\n}\n"
  },
  {
    "path": "vendor/github.com/xlab/treeprint/treeprint.go",
    "content": "// Package treeprint provides a simple ASCII tree composing tool.\npackage treeprint\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// Value defines any value\ntype Value interface{}\n\n// MetaValue defines any meta value\ntype MetaValue interface{}\n\n// NodeVisitor function type for iterating over nodes\ntype NodeVisitor func(item *node)\n\n// Tree represents a tree structure with leaf-nodes and branch-nodes.\ntype Tree interface {\n\t// AddNode adds a new node to a branch.\n\tAddNode(v Value) Tree\n\t// AddMetaNode adds a new node with meta value provided to a branch.\n\tAddMetaNode(meta MetaValue, v Value) Tree\n\t// AddBranch adds a new branch node (a level deeper).\n\tAddBranch(v Value) Tree\n\t// AddMetaBranch adds a new branch node (a level deeper) with meta value provided.\n\tAddMetaBranch(meta MetaValue, v Value) Tree\n\t// Branch converts a leaf-node to a branch-node,\n\t// applying this on a branch-node does no effect.\n\tBranch() Tree\n\t// FindByMeta finds a node whose meta value matches the provided one by reflect.DeepEqual,\n\t// returns nil if not found.\n\tFindByMeta(meta MetaValue) Tree\n\t// FindByValue finds a node whose value matches the provided one by reflect.DeepEqual,\n\t// returns nil if not found.\n\tFindByValue(value Value) Tree\n\t//  returns the last node of a tree\n\tFindLastNode() Tree\n\t// String renders the tree or subtree as a string.\n\tString() string\n\t// Bytes renders the tree or subtree as byteslice.\n\tBytes() []byte\n\n\tSetValue(value Value)\n\tSetMetaValue(meta MetaValue)\n\n\t// VisitAll iterates over the tree, branches and nodes.\n\t// If need to iterate over the whole tree, use the root node.\n\t// Note this method uses a breadth-first approach.\n\tVisitAll(fn NodeVisitor)\n}\n\ntype node struct {\n\tRoot  *node\n\tMeta  MetaValue\n\tValue Value\n\tNodes []*node\n}\n\nfunc (n *node) FindLastNode() Tree {\n\tns := n.Nodes\n\tif len(ns) == 0 {\n\t\treturn nil\n\t}\n\treturn ns[len(ns)-1]\n}\n\nfunc (n *node) AddNode(v Value) Tree {\n\tn.Nodes = append(n.Nodes, &node{\n\t\tRoot:  n,\n\t\tValue: v,\n\t})\n\treturn n\n}\n\nfunc (n *node) AddMetaNode(meta MetaValue, v Value) Tree {\n\tn.Nodes = append(n.Nodes, &node{\n\t\tRoot:  n,\n\t\tMeta:  meta,\n\t\tValue: v,\n\t})\n\treturn n\n}\n\nfunc (n *node) AddBranch(v Value) Tree {\n\tbranch := &node{\n\t\tRoot:  n,\n\t\tValue: v,\n\t}\n\tn.Nodes = append(n.Nodes, branch)\n\treturn branch\n}\n\nfunc (n *node) AddMetaBranch(meta MetaValue, v Value) Tree {\n\tbranch := &node{\n\t\tRoot:  n,\n\t\tMeta:  meta,\n\t\tValue: v,\n\t}\n\tn.Nodes = append(n.Nodes, branch)\n\treturn branch\n}\n\nfunc (n *node) Branch() Tree {\n\tn.Root = nil\n\treturn n\n}\n\nfunc (n *node) FindByMeta(meta MetaValue) Tree {\n\tfor _, node := range n.Nodes {\n\t\tif reflect.DeepEqual(node.Meta, meta) {\n\t\t\treturn node\n\t\t}\n\t\tif v := node.FindByMeta(meta); v != nil {\n\t\t\treturn v\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (n *node) FindByValue(value Value) Tree {\n\tfor _, node := range n.Nodes {\n\t\tif reflect.DeepEqual(node.Value, value) {\n\t\t\treturn node\n\t\t}\n\t\tif v := node.FindByMeta(value); v != nil {\n\t\t\treturn v\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (n *node) Bytes() []byte {\n\tbuf := new(bytes.Buffer)\n\tlevel := 0\n\tvar levelsEnded []int\n\tif n.Root == nil {\n\t\tif n.Meta != nil {\n\t\t\tbuf.WriteString(fmt.Sprintf(\"[%v]  %v\", n.Meta, n.Value))\n\t\t} else {\n\t\t\tbuf.WriteString(fmt.Sprintf(\"%v\", n.Value))\n\t\t}\n\t\tbuf.WriteByte('\\n')\n\t} else {\n\t\tedge := EdgeTypeMid\n\t\tif len(n.Nodes) == 0 {\n\t\t\tedge = EdgeTypeEnd\n\t\t\tlevelsEnded = append(levelsEnded, level)\n\t\t}\n\t\tprintValues(buf, 0, levelsEnded, edge, n)\n\t}\n\tif len(n.Nodes) > 0 {\n\t\tprintNodes(buf, level, levelsEnded, n.Nodes)\n\t}\n\treturn buf.Bytes()\n}\n\nfunc (n *node) String() string {\n\treturn string(n.Bytes())\n}\n\nfunc (n *node) SetValue(value Value) {\n\tn.Value = value\n}\n\nfunc (n *node) SetMetaValue(meta MetaValue) {\n\tn.Meta = meta\n}\n\nfunc (n *node) VisitAll(fn NodeVisitor) {\n\tfor _, node := range n.Nodes {\n\t\tfn(node)\n\n\t\tif len(node.Nodes) > 0 {\n\t\t\tnode.VisitAll(fn)\n\t\t\tcontinue\n\t\t}\n\t}\n}\n\nfunc printNodes(wr io.Writer,\n\tlevel int, levelsEnded []int, nodes []*node) {\n\n\tfor i, node := range nodes {\n\t\tedge := EdgeTypeMid\n\t\tif i == len(nodes)-1 {\n\t\t\tlevelsEnded = append(levelsEnded, level)\n\t\t\tedge = EdgeTypeEnd\n\t\t}\n\t\tprintValues(wr, level, levelsEnded, edge, node)\n\t\tif len(node.Nodes) > 0 {\n\t\t\tprintNodes(wr, level+1, levelsEnded, node.Nodes)\n\t\t}\n\t}\n}\n\nfunc printValues(wr io.Writer,\n\tlevel int, levelsEnded []int, edge EdgeType, node *node) {\n\n\tfor i := 0; i < level; i++ {\n\t\tif isEnded(levelsEnded, i) {\n\t\t\tfmt.Fprint(wr, strings.Repeat(\" \", IndentSize+1))\n\t\t\tcontinue\n\t\t}\n\t\tfmt.Fprintf(wr, \"%s%s\", EdgeTypeLink, strings.Repeat(\" \", IndentSize))\n\t}\n\n\tval := renderValue(level, node)\n\tmeta := node.Meta\n\n\tif meta != nil {\n\t\tfmt.Fprintf(wr, \"%s [%v]  %v\\n\", edge, meta, val)\n\t\treturn\n\t}\n\tfmt.Fprintf(wr, \"%s %v\\n\", edge, val)\n}\n\nfunc isEnded(levelsEnded []int, level int) bool {\n\tfor _, l := range levelsEnded {\n\t\tif l == level {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc renderValue(level int, node *node) Value {\n\tlines := strings.Split(fmt.Sprintf(\"%v\", node.Value), \"\\n\")\n\n\t// If value does not contain multiple lines, return itself.\n\tif len(lines) < 2 {\n\t\treturn node.Value\n\t}\n\n\t// If value contains multiple lines,\n\t// generate a padding and prefix each line with it.\n\tpad := padding(level, node)\n\n\tfor i := 1; i < len(lines); i++ {\n\t\tlines[i] = fmt.Sprintf(\"%s%s\", pad, lines[i])\n\t}\n\n\treturn strings.Join(lines, \"\\n\")\n}\n\n// padding returns a padding for the multiline values with correctly placed link edges.\n// It is generated by traversing the tree upwards (from leaf to the root of the tree)\n// and, on each level, checking if the node the last one of its siblings.\n// If a node is the last one, the padding on that level should be empty (there's nothing to link to below it).\n// If a node is not the last one, the padding on that level should be the link edge so the sibling below is correctly connected.\nfunc padding(level int, node *node) string {\n\tlinks := make([]string, level+1)\n\n\tfor node.Root != nil {\n\t\tif isLast(node) {\n\t\t\tlinks[level] = strings.Repeat(\" \", IndentSize+1)\n\t\t} else {\n\t\t\tlinks[level] = fmt.Sprintf(\"%s%s\", EdgeTypeLink, strings.Repeat(\" \", IndentSize))\n\t\t}\n\t\tlevel--\n\t\tnode = node.Root\n\t}\n\n\treturn strings.Join(links, \"\")\n}\n\n// isLast checks if the node is the last one in the slice of its parent children\nfunc isLast(n *node) bool {\n\treturn n == n.Root.FindLastNode()\n}\n\ntype EdgeType string\n\nvar (\n\tEdgeTypeLink EdgeType = \"│\"\n\tEdgeTypeMid  EdgeType = \"├──\"\n\tEdgeTypeEnd  EdgeType = \"└──\"\n)\n\n// IndentSize is the number of spaces per tree level.\nvar IndentSize = 3\n\n// New Generates new tree\nfunc New() Tree {\n\treturn &node{Value: \".\"}\n}\n\n// NewWithRoot Generates new tree with the given root value\nfunc NewWithRoot(root Value) Tree {\n\treturn &node{Value: root}\n}\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/.travis.yml",
    "content": "language: go\ngo:\n    - 1.11\n    - 1.12\n    - 1.13\n    - 1.14.x\n    - master\nscript:\n    - cd tests && make\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/LICENSE",
    "content": "Copyright (C) 2016 Felipe da Cunha Gonçalves\nAll Rights Reserved.\n\nMIT LICENSE\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject 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, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/README.md",
    "content": "[![Build Status](https://travis-ci.org/xrash/smetrics.svg?branch=master)](http://travis-ci.org/xrash/smetrics)\n\n# smetrics\n\n`smetrics` is \"string metrics\".\n\nPackage smetrics provides a bunch of algorithms for calculating the distance between strings.\n\nThere are implementations for calculating the popular Levenshtein distance (aka Edit Distance or Wagner-Fischer), as well as the Jaro distance, the Jaro-Winkler distance, and more.\n\n# How to import\n\n```go\nimport \"github.com/xrash/smetrics\"\n```\n\n# Documentation\n\nGo to [https://pkg.go.dev/github.com/xrash/smetrics](https://pkg.go.dev/github.com/xrash/smetrics) for complete documentation.\n\n# Example\n\n```go\npackage main\n\nimport (\n\t\"github.com/xrash/smetrics\"\n)\n\nfunc main() {\n\tsmetrics.WagnerFischer(\"POTATO\", \"POTATTO\", 1, 1, 2)\n\tsmetrics.WagnerFischer(\"MOUSE\", \"HOUSE\", 2, 2, 4)\n\n\tsmetrics.Ukkonen(\"POTATO\", \"POTATTO\", 1, 1, 2)\n\tsmetrics.Ukkonen(\"MOUSE\", \"HOUSE\", 2, 2, 4)\n\n\tsmetrics.Jaro(\"AL\", \"AL\")\n\tsmetrics.Jaro(\"MARTHA\", \"MARHTA\")\n\n\tsmetrics.JaroWinkler(\"AL\", \"AL\", 0.7, 4)\n\tsmetrics.JaroWinkler(\"MARTHA\", \"MARHTA\", 0.7, 4)\n\n\tsmetrics.Soundex(\"Euler\")\n\tsmetrics.Soundex(\"Ellery\")\n\n\tsmetrics.Hamming(\"aaa\", \"aaa\")\n\tsmetrics.Hamming(\"aaa\", \"aab\")\n}\n```\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/doc.go",
    "content": "/*\nPackage smetrics provides a bunch of algorithms for calculating\nthe distance between strings.\n\nThere are implementations for calculating the popular Levenshtein\ndistance (aka Edit Distance or Wagner-Fischer), as well as the Jaro\ndistance, the Jaro-Winkler distance, and more.\n\nFor the Levenshtein distance, you can use the functions WagnerFischer()\nand Ukkonen(). Read the documentation on these functions.\n\nFor the Jaro and Jaro-Winkler algorithms, check the functions\nJaro() and JaroWinkler(). Read the documentation on these functions.\n\nFor the Soundex algorithm, check the function Soundex().\n\nFor the Hamming distance algorithm, check the function Hamming().\n*/\npackage smetrics\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/hamming.go",
    "content": "package smetrics\n\nimport (\n\t\"fmt\"\n)\n\n// The Hamming distance is the minimum number of substitutions required to change string A into string B. Both strings must have the same size. If the strings have different sizes, the function returns an error.\nfunc Hamming(a, b string) (int, error) {\n\tal := len(a)\n\tbl := len(b)\n\n\tif al != bl {\n\t\treturn -1, fmt.Errorf(\"strings are not equal (len(a)=%d, len(b)=%d)\", al, bl)\n\t}\n\n\tvar difference = 0\n\n\tfor i := range a {\n\t\tif a[i] != b[i] {\n\t\t\tdifference = difference + 1\n\t\t}\n\t}\n\n\treturn difference, nil\n}\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/jaro-winkler.go",
    "content": "package smetrics\n\nimport (\n\t\"math\"\n)\n\n// The Jaro-Winkler distance. The result is 1 for equal strings, and 0 for completely different strings. It is commonly used on Record Linkage stuff, thus it tries to be accurate for common typos when writing real names such as  person names and street names.\n// Jaro-Winkler is a modification of the Jaro algorithm. It works by first running Jaro, then boosting the score of exact matches at the beginning of the strings. Because of that, it introduces two more parameters: the boostThreshold and the prefixSize. These are commonly set to 0.7 and 4, respectively.\nfunc JaroWinkler(a, b string, boostThreshold float64, prefixSize int) float64 {\n\tj := Jaro(a, b)\n\n\tif j <= boostThreshold {\n\t\treturn j\n\t}\n\n\tprefixSize = int(math.Min(float64(len(a)), math.Min(float64(prefixSize), float64(len(b)))))\n\n\tvar prefixMatch float64\n\tfor i := 0; i < prefixSize; i++ {\n\t\tif a[i] == b[i] {\n\t\t\tprefixMatch++\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn j + 0.1*prefixMatch*(1.0-j)\n}\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/jaro.go",
    "content": "package smetrics\n\nimport (\n\t\"math\"\n)\n\n// The Jaro distance. The result is 1 for equal strings, and 0 for completely different strings.\nfunc Jaro(a, b string) float64 {\n\t// If both strings are zero-length, they are completely equal,\n\t// therefore return 1.\n\tif len(a) == 0 && len(b) == 0 {\n\t\treturn 1\n\t}\n\n\t// If one string is zero-length, strings are completely different,\n\t// therefore return 0.\n\tif len(a) == 0 || len(b) == 0 {\n\t\treturn 0\n\t}\n\n\t// Define the necessary variables for the algorithm.\n\tla := float64(len(a))\n\tlb := float64(len(b))\n\tmatchRange := int(math.Max(0, math.Floor(math.Max(la, lb)/2.0)-1))\n\tmatchesA := make([]bool, len(a))\n\tmatchesB := make([]bool, len(b))\n\tvar matches float64 = 0\n\n\t// Step 1: Matches\n\t// Loop through each character of the first string,\n\t// looking for a matching character in the second string.\n\tfor i := 0; i < len(a); i++ {\n\t\tstart := int(math.Max(0, float64(i-matchRange)))\n\t\tend := int(math.Min(lb-1, float64(i+matchRange)))\n\n\t\tfor j := start; j <= end; j++ {\n\t\t\tif matchesB[j] {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif a[i] == b[j] {\n\t\t\t\tmatchesA[i] = true\n\t\t\t\tmatchesB[j] = true\n\t\t\t\tmatches++\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// If there are no matches, strings are completely different,\n\t// therefore return 0.\n\tif matches == 0 {\n\t\treturn 0\n\t}\n\n\t// Step 2: Transpositions\n\t// Loop through the matches' arrays, looking for\n\t// unaligned matches. Count the number of unaligned matches.\n\tunaligned := 0\n\tj := 0\n\tfor i := 0; i < len(a); i++ {\n\t\tif !matchesA[i] {\n\t\t\tcontinue\n\t\t}\n\n\t\tfor !matchesB[j] {\n\t\t\tj++\n\t\t}\n\n\t\tif a[i] != b[j] {\n\t\t\tunaligned++\n\t\t}\n\n\t\tj++\n\t}\n\n\t// The number of unaligned matches divided by two, is the number of _transpositions_.\n\ttranspositions := math.Floor(float64(unaligned / 2))\n\n\t// Jaro distance is the average between these three numbers:\n\t// 1. matches / length of string A\n\t// 2. matches / length of string B\n\t// 3. (matches - transpositions/matches)\n\t// So, all that divided by three is the final result.\n\treturn ((matches / la) + (matches / lb) + ((matches - transpositions) / matches)) / 3.0\n}\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/soundex.go",
    "content": "package smetrics\n\nimport (\n\t\"strings\"\n)\n\n// The Soundex encoding. It is a phonetic algorithm that considers how the words sound in English. Soundex maps a string to a 4-byte code consisting of the first letter of the original string and three numbers. Strings that sound similar should map to the same code.\nfunc Soundex(s string) string {\n\tb := strings.Builder{}\n\tb.Grow(4)\n\n\tp := s[0]\n\tif p <= 'z' && p >= 'a' {\n\t\tp -= 32 // convert to uppercase\n\t}\n\tb.WriteByte(p)\n\n\tn := 0\n\tfor i := 1; i < len(s); i++ {\n\t\tc := s[i]\n\n\t\tif c <= 'z' && c >= 'a' {\n\t\t\tc -= 32 // convert to uppercase\n\t\t} else if c < 'A' || c > 'Z' {\n\t\t\tcontinue\n\t\t}\n\n\t\tif c == p {\n\t\t\tcontinue\n\t\t}\n\n\t\tp = c\n\n\t\tswitch c {\n\t\tcase 'B', 'P', 'F', 'V':\n\t\t\tc = '1'\n\t\tcase 'C', 'S', 'K', 'G', 'J', 'Q', 'X', 'Z':\n\t\t\tc = '2'\n\t\tcase 'D', 'T':\n\t\t\tc = '3'\n\t\tcase 'L':\n\t\t\tc = '4'\n\t\tcase 'M', 'N':\n\t\t\tc = '5'\n\t\tcase 'R':\n\t\t\tc = '6'\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\n\t\tb.WriteByte(c)\n\t\tn++\n\t\tif n == 3 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfor i := n; i < 3; i++ {\n\t\tb.WriteByte('0')\n\t}\n\n\treturn b.String()\n}\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/ukkonen.go",
    "content": "package smetrics\n\nimport (\n\t\"math\"\n)\n\n// The Ukkonen algorithm for calculating the Levenshtein distance. The algorithm is described in http://www.cs.helsinki.fi/u/ukkonen/InfCont85.PDF, or in docs/InfCont85.PDF. It runs on O(t . min(m, n)) where t is the actual distance between strings a and b. It needs O(min(t, m, n)) space. This function might be preferred over WagnerFischer() for *very* similar strings. But test it out yourself.\n// The first two parameters are the two strings to be compared. The last three parameters are the insertion cost, the deletion cost and the substitution cost. These are normally defined as 1, 1 and 2 respectively.\nfunc Ukkonen(a, b string, icost, dcost, scost int) int {\n\tvar lowerCost int\n\n\tif icost < dcost && icost < scost {\n\t\tlowerCost = icost\n\t} else if dcost < scost {\n\t\tlowerCost = dcost\n\t} else {\n\t\tlowerCost = scost\n\t}\n\n\tinfinite := math.MaxInt32 / 2\n\n\tvar r []int\n\tvar k, kprime, p, t int\n\tvar ins, del, sub int\n\n\tif len(a) > len(b) {\n\t\tt = (len(a) - len(b) + 1) * lowerCost\n\t} else {\n\t\tt = (len(b) - len(a) + 1) * lowerCost\n\t}\n\n\tfor {\n\t\tif (t / lowerCost) < (len(b) - len(a)) {\n\t\t\tcontinue\n\t\t}\n\n\t\t// This is the right damn thing since the original Ukkonen\n\t\t// paper minimizes the expression result only, but the uncommented version\n\t\t// doesn't need to deal with floats so it's faster.\n\t\t// p = int(math.Floor(0.5*((float64(t)/float64(lowerCost)) - float64(len(b) - len(a)))))\n\t\tp = ((t / lowerCost) - (len(b) - len(a))) / 2\n\n\t\tk = -p\n\t\tkprime = k\n\n\t\trowlength := (len(b) - len(a)) + (2 * p)\n\n\t\tr = make([]int, rowlength+2)\n\n\t\tfor i := 0; i < rowlength+2; i++ {\n\t\t\tr[i] = infinite\n\t\t}\n\n\t\tfor i := 0; i <= len(a); i++ {\n\t\t\tfor j := 0; j <= rowlength; j++ {\n\t\t\t\tif i == j+k && i == 0 {\n\t\t\t\t\tr[j] = 0\n\t\t\t\t} else {\n\t\t\t\t\tif j-1 < 0 {\n\t\t\t\t\t\tins = infinite\n\t\t\t\t\t} else {\n\t\t\t\t\t\tins = r[j-1] + icost\n\t\t\t\t\t}\n\n\t\t\t\t\tdel = r[j+1] + dcost\n\t\t\t\t\tsub = r[j] + scost\n\n\t\t\t\t\tif i-1 < 0 || i-1 >= len(a) || j+k-1 >= len(b) || j+k-1 < 0 {\n\t\t\t\t\t\tsub = infinite\n\t\t\t\t\t} else if a[i-1] == b[j+k-1] {\n\t\t\t\t\t\tsub = r[j]\n\t\t\t\t\t}\n\n\t\t\t\t\tif ins < del && ins < sub {\n\t\t\t\t\t\tr[j] = ins\n\t\t\t\t\t} else if del < sub {\n\t\t\t\t\t\tr[j] = del\n\t\t\t\t\t} else {\n\t\t\t\t\t\tr[j] = sub\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tk++\n\t\t}\n\n\t\tif r[(len(b)-len(a))+(2*p)+kprime] <= t {\n\t\t\tbreak\n\t\t} else {\n\t\t\tt *= 2\n\t\t}\n\t}\n\n\treturn r[(len(b)-len(a))+(2*p)+kprime]\n}\n"
  },
  {
    "path": "vendor/github.com/xrash/smetrics/wagner-fischer.go",
    "content": "package smetrics\n\n// The Wagner-Fischer algorithm for calculating the Levenshtein distance.\n// The first two parameters are the two strings to be compared. The last three parameters are the insertion cost, the deletion cost and the substitution cost. These are normally defined as 1, 1 and 2 respectively.\nfunc WagnerFischer(a, b string, icost, dcost, scost int) int {\n\n\t// Allocate both rows.\n\trow1 := make([]int, len(b)+1)\n\trow2 := make([]int, len(b)+1)\n\tvar tmp []int\n\n\t// Initialize the first row.\n\tfor i := 1; i <= len(b); i++ {\n\t\trow1[i] = i * icost\n\t}\n\n\t// For each row...\n\tfor i := 1; i <= len(a); i++ {\n\t\trow2[0] = i * dcost\n\n\t\t// For each column...\n\t\tfor j := 1; j <= len(b); j++ {\n\t\t\tif a[i-1] == b[j-1] {\n\t\t\t\trow2[j] = row1[j-1]\n\t\t\t} else {\n\t\t\t\tins := row2[j-1] + icost\n\t\t\t\tdel := row1[j] + dcost\n\t\t\t\tsub := row1[j-1] + scost\n\n\t\t\t\tif ins < del && ins < sub {\n\t\t\t\t\trow2[j] = ins\n\t\t\t\t} else if del < sub {\n\t\t\t\t\trow2[j] = del\n\t\t\t\t} else {\n\t\t\t\t\trow2[j] = sub\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Swap the rows at the end of each row.\n\t\ttmp = row1\n\t\trow1 = row2\n\t\trow2 = tmp\n\t}\n\n\t// Because we swapped the rows, the final result is in row1 instead of row2.\n\treturn row1[len(row1)-1]\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n)\n\n// DefaultClient is the default Client and is used by Get, Head, Post and PostForm.\n// Please be careful of intitialization order - for example, if you change\n// the global propagator, the DefaultClient might still be using the old one.\nvar DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)}\n\n// Get is a convenient replacement for http.Get that adds a span around the request.\nfunc Get(ctx context.Context, targetURL string) (resp *http.Response, err error) {\n\treq, err := http.NewRequestWithContext(ctx, \"GET\", targetURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn DefaultClient.Do(req)\n}\n\n// Head is a convenient replacement for http.Head that adds a span around the request.\nfunc Head(ctx context.Context, targetURL string) (resp *http.Response, err error) {\n\treq, err := http.NewRequestWithContext(ctx, \"HEAD\", targetURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn DefaultClient.Do(req)\n}\n\n// Post is a convenient replacement for http.Post that adds a span around the request.\nfunc Post(ctx context.Context, targetURL, contentType string, body io.Reader) (resp *http.Response, err error) {\n\treq, err := http.NewRequestWithContext(ctx, \"POST\", targetURL, body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Content-Type\", contentType)\n\treturn DefaultClient.Do(req)\n}\n\n// PostForm is a convenient replacement for http.PostForm that adds a span around the request.\nfunc PostForm(ctx context.Context, targetURL string, data url.Values) (resp *http.Response, err error) {\n\treturn Post(ctx, targetURL, \"application/x-www-form-urlencoded\", strings.NewReader(data.Encode()))\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\nimport (\n\t\"net/http\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Attribute keys that can be added to a span.\nconst (\n\tReadBytesKey  = attribute.Key(\"http.read_bytes\")  // if anything was read from the request body, the total number of bytes read\n\tReadErrorKey  = attribute.Key(\"http.read_error\")  // If an error occurred while reading a request, the string of the error (io.EOF is not recorded)\n\tWroteBytesKey = attribute.Key(\"http.wrote_bytes\") // if anything was written to the response writer, the total number of bytes written\n\tWriteErrorKey = attribute.Key(\"http.write_error\") // if an error occurred while writing a reply, the string of the error (io.EOF is not recorded)\n)\n\n// Server HTTP metrics.\nconst (\n\tRequestCount          = \"http.server.request_count\"           // Incoming request count total\n\tRequestContentLength  = \"http.server.request_content_length\"  // Incoming request bytes total\n\tResponseContentLength = \"http.server.response_content_length\" // Incoming response bytes total\n\tServerLatency         = \"http.server.duration\"                // Incoming end to end duration, microseconds\n)\n\n// Filter is a predicate used to determine whether a given http.request should\n// be traced. A Filter must return true if the request should be traced.\ntype Filter func(*http.Request) bool\n\nfunc newTracer(tp trace.TracerProvider) trace.Tracer {\n\treturn tp.Tracer(instrumentationName, trace.WithInstrumentationVersion(Version()))\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/config.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nconst (\n\tinstrumentationName = \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n)\n\n// config represents the configuration options available for the http.Handler\n// and http.Transport types.\ntype config struct {\n\tServerName        string\n\tTracer            trace.Tracer\n\tMeter             metric.Meter\n\tPropagators       propagation.TextMapPropagator\n\tSpanStartOptions  []trace.SpanStartOption\n\tPublicEndpoint    bool\n\tPublicEndpointFn  func(*http.Request) bool\n\tReadEvent         bool\n\tWriteEvent        bool\n\tFilters           []Filter\n\tSpanNameFormatter func(string, *http.Request) string\n\tClientTrace       func(context.Context) *httptrace.ClientTrace\n\n\tTracerProvider trace.TracerProvider\n\tMeterProvider  metric.MeterProvider\n}\n\n// Option interface used for setting optional config properties.\ntype Option interface {\n\tapply(*config)\n}\n\ntype optionFunc func(*config)\n\nfunc (o optionFunc) apply(c *config) {\n\to(c)\n}\n\n// newConfig creates a new config struct and applies opts to it.\nfunc newConfig(opts ...Option) *config {\n\tc := &config{\n\t\tPropagators:   otel.GetTextMapPropagator(),\n\t\tMeterProvider: otel.GetMeterProvider(),\n\t}\n\tfor _, opt := range opts {\n\t\topt.apply(c)\n\t}\n\n\t// Tracer is only initialized if manually specified. Otherwise, can be passed with the tracing context.\n\tif c.TracerProvider != nil {\n\t\tc.Tracer = newTracer(c.TracerProvider)\n\t}\n\n\tc.Meter = c.MeterProvider.Meter(\n\t\tinstrumentationName,\n\t\tmetric.WithInstrumentationVersion(Version()),\n\t)\n\n\treturn c\n}\n\n// WithTracerProvider specifies a tracer provider to use for creating a tracer.\n// If none is specified, the global provider is used.\nfunc WithTracerProvider(provider trace.TracerProvider) Option {\n\treturn optionFunc(func(cfg *config) {\n\t\tif provider != nil {\n\t\t\tcfg.TracerProvider = provider\n\t\t}\n\t})\n}\n\n// WithMeterProvider specifies a meter provider to use for creating a meter.\n// If none is specified, the global provider is used.\nfunc WithMeterProvider(provider metric.MeterProvider) Option {\n\treturn optionFunc(func(cfg *config) {\n\t\tif provider != nil {\n\t\t\tcfg.MeterProvider = provider\n\t\t}\n\t})\n}\n\n// WithPublicEndpoint configures the Handler to link the span with an incoming\n// span context. If this option is not provided, then the association is a child\n// association instead of a link.\nfunc WithPublicEndpoint() Option {\n\treturn optionFunc(func(c *config) {\n\t\tc.PublicEndpoint = true\n\t})\n}\n\n// WithPublicEndpointFn runs with every request, and allows conditionnally\n// configuring the Handler to link the span with an incoming span context. If\n// this option is not provided or returns false, then the association is a\n// child association instead of a link.\n// Note: WithPublicEndpoint takes precedence over WithPublicEndpointFn.\nfunc WithPublicEndpointFn(fn func(*http.Request) bool) Option {\n\treturn optionFunc(func(c *config) {\n\t\tc.PublicEndpointFn = fn\n\t})\n}\n\n// WithPropagators configures specific propagators. If this\n// option isn't specified, then the global TextMapPropagator is used.\nfunc WithPropagators(ps propagation.TextMapPropagator) Option {\n\treturn optionFunc(func(c *config) {\n\t\tif ps != nil {\n\t\t\tc.Propagators = ps\n\t\t}\n\t})\n}\n\n// WithSpanOptions configures an additional set of\n// trace.SpanOptions, which are applied to each new span.\nfunc WithSpanOptions(opts ...trace.SpanStartOption) Option {\n\treturn optionFunc(func(c *config) {\n\t\tc.SpanStartOptions = append(c.SpanStartOptions, opts...)\n\t})\n}\n\n// WithFilter adds a filter to the list of filters used by the handler.\n// If any filter indicates to exclude a request then the request will not be\n// traced. All filters must allow a request to be traced for a Span to be created.\n// If no filters are provided then all requests are traced.\n// Filters will be invoked for each processed request, it is advised to make them\n// simple and fast.\nfunc WithFilter(f Filter) Option {\n\treturn optionFunc(func(c *config) {\n\t\tc.Filters = append(c.Filters, f)\n\t})\n}\n\ntype event int\n\n// Different types of events that can be recorded, see WithMessageEvents.\nconst (\n\tReadEvents event = iota\n\tWriteEvents\n)\n\n// WithMessageEvents configures the Handler to record the specified events\n// (span.AddEvent) on spans. By default only summary attributes are added at the\n// end of the request.\n//\n// Valid events are:\n//   - ReadEvents: Record the number of bytes read after every http.Request.Body.Read\n//     using the ReadBytesKey\n//   - WriteEvents: Record the number of bytes written after every http.ResponeWriter.Write\n//     using the WriteBytesKey\nfunc WithMessageEvents(events ...event) Option {\n\treturn optionFunc(func(c *config) {\n\t\tfor _, e := range events {\n\t\t\tswitch e {\n\t\t\tcase ReadEvents:\n\t\t\t\tc.ReadEvent = true\n\t\t\tcase WriteEvents:\n\t\t\t\tc.WriteEvent = true\n\t\t\t}\n\t\t}\n\t})\n}\n\n// WithSpanNameFormatter takes a function that will be called on every\n// request and the returned string will become the Span Name.\nfunc WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option {\n\treturn optionFunc(func(c *config) {\n\t\tc.SpanNameFormatter = f\n\t})\n}\n\n// WithClientTrace takes a function that returns client trace instance that will be\n// applied to the requests sent through the otelhttp Transport.\nfunc WithClientTrace(f func(context.Context) *httptrace.ClientTrace) Option {\n\treturn optionFunc(func(c *config) {\n\t\tc.ClientTrace = f\n\t})\n}\n\n// WithServerName returns an Option that sets the name of the (virtual) server\n// handling requests.\nfunc WithServerName(server string) Option {\n\treturn optionFunc(func(c *config) {\n\t\tc.ServerName = server\n\t})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n// Package otelhttp provides an http.Handler and functions that are intended\n// to be used to add tracing by wrapping existing handlers (with Handler) and\n// routes WithRouteTag.\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\nimport (\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/felixge/httpsnoop\"\n\n\t\"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil\"\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// middleware is an http middleware which wraps the next handler in a span.\ntype middleware struct {\n\toperation string\n\tserver    string\n\n\ttracer            trace.Tracer\n\tmeter             metric.Meter\n\tpropagators       propagation.TextMapPropagator\n\tspanStartOptions  []trace.SpanStartOption\n\treadEvent         bool\n\twriteEvent        bool\n\tfilters           []Filter\n\tspanNameFormatter func(string, *http.Request) string\n\tcounters          map[string]metric.Int64Counter\n\tvalueRecorders    map[string]metric.Float64Histogram\n\tpublicEndpoint    bool\n\tpublicEndpointFn  func(*http.Request) bool\n}\n\nfunc defaultHandlerFormatter(operation string, _ *http.Request) string {\n\treturn operation\n}\n\n// NewHandler wraps the passed handler in a span named after the operation and\n// enriches it with metrics.\nfunc NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler {\n\treturn NewMiddleware(operation, opts...)(handler)\n}\n\n// NewMiddleware returns a tracing and metrics instrumentation middleware.\n// The handler returned by the middleware wraps a handler\n// in a span named after the operation and enriches it with metrics.\nfunc NewMiddleware(operation string, opts ...Option) func(http.Handler) http.Handler {\n\th := middleware{\n\t\toperation: operation,\n\t}\n\n\tdefaultOpts := []Option{\n\t\tWithSpanOptions(trace.WithSpanKind(trace.SpanKindServer)),\n\t\tWithSpanNameFormatter(defaultHandlerFormatter),\n\t}\n\n\tc := newConfig(append(defaultOpts, opts...)...)\n\th.configure(c)\n\th.createMeasures()\n\n\treturn func(next http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\th.serveHTTP(w, r, next)\n\t\t})\n\t}\n}\n\nfunc (h *middleware) configure(c *config) {\n\th.tracer = c.Tracer\n\th.meter = c.Meter\n\th.propagators = c.Propagators\n\th.spanStartOptions = c.SpanStartOptions\n\th.readEvent = c.ReadEvent\n\th.writeEvent = c.WriteEvent\n\th.filters = c.Filters\n\th.spanNameFormatter = c.SpanNameFormatter\n\th.publicEndpoint = c.PublicEndpoint\n\th.publicEndpointFn = c.PublicEndpointFn\n\th.server = c.ServerName\n}\n\nfunc handleErr(err error) {\n\tif err != nil {\n\t\totel.Handle(err)\n\t}\n}\n\nfunc (h *middleware) createMeasures() {\n\th.counters = make(map[string]metric.Int64Counter)\n\th.valueRecorders = make(map[string]metric.Float64Histogram)\n\n\trequestBytesCounter, err := h.meter.Int64Counter(RequestContentLength)\n\thandleErr(err)\n\n\tresponseBytesCounter, err := h.meter.Int64Counter(ResponseContentLength)\n\thandleErr(err)\n\n\tserverLatencyMeasure, err := h.meter.Float64Histogram(ServerLatency)\n\thandleErr(err)\n\n\th.counters[RequestContentLength] = requestBytesCounter\n\th.counters[ResponseContentLength] = responseBytesCounter\n\th.valueRecorders[ServerLatency] = serverLatencyMeasure\n}\n\n// serveHTTP sets up tracing and calls the given next http.Handler with the span\n// context injected into the request context.\nfunc (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http.Handler) {\n\trequestStartTime := time.Now()\n\tfor _, f := range h.filters {\n\t\tif !f(r) {\n\t\t\t// Simply pass through to the handler if a filter rejects the request\n\t\t\tnext.ServeHTTP(w, r)\n\t\t\treturn\n\t\t}\n\t}\n\n\tctx := h.propagators.Extract(r.Context(), propagation.HeaderCarrier(r.Header))\n\topts := []trace.SpanStartOption{\n\t\ttrace.WithAttributes(semconvutil.HTTPServerRequest(h.server, r)...),\n\t}\n\tif h.server != \"\" {\n\t\thostAttr := semconv.NetHostName(h.server)\n\t\topts = append(opts, trace.WithAttributes(hostAttr))\n\t}\n\topts = append(opts, h.spanStartOptions...)\n\tif h.publicEndpoint || (h.publicEndpointFn != nil && h.publicEndpointFn(r.WithContext(ctx))) {\n\t\topts = append(opts, trace.WithNewRoot())\n\t\t// Linking incoming span context if any for public endpoint.\n\t\tif s := trace.SpanContextFromContext(ctx); s.IsValid() && s.IsRemote() {\n\t\t\topts = append(opts, trace.WithLinks(trace.Link{SpanContext: s}))\n\t\t}\n\t}\n\n\ttracer := h.tracer\n\n\tif tracer == nil {\n\t\tif span := trace.SpanFromContext(r.Context()); span.SpanContext().IsValid() {\n\t\t\ttracer = newTracer(span.TracerProvider())\n\t\t} else {\n\t\t\ttracer = newTracer(otel.GetTracerProvider())\n\t\t}\n\t}\n\n\tctx, span := tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...)\n\tdefer span.End()\n\n\treadRecordFunc := func(int64) {}\n\tif h.readEvent {\n\t\treadRecordFunc = func(n int64) {\n\t\t\tspan.AddEvent(\"read\", trace.WithAttributes(ReadBytesKey.Int64(n)))\n\t\t}\n\t}\n\n\tvar bw bodyWrapper\n\t// if request body is nil or NoBody, we don't want to mutate the body as it\n\t// will affect the identity of it in an unforeseeable way because we assert\n\t// ReadCloser fulfills a certain interface and it is indeed nil or NoBody.\n\tif r.Body != nil && r.Body != http.NoBody {\n\t\tbw.ReadCloser = r.Body\n\t\tbw.record = readRecordFunc\n\t\tr.Body = &bw\n\t}\n\n\twriteRecordFunc := func(int64) {}\n\tif h.writeEvent {\n\t\twriteRecordFunc = func(n int64) {\n\t\t\tspan.AddEvent(\"write\", trace.WithAttributes(WroteBytesKey.Int64(n)))\n\t\t}\n\t}\n\n\trww := &respWriterWrapper{\n\t\tResponseWriter: w,\n\t\trecord:         writeRecordFunc,\n\t\tctx:            ctx,\n\t\tprops:          h.propagators,\n\t\tstatusCode:     http.StatusOK, // default status code in case the Handler doesn't write anything\n\t}\n\n\t// Wrap w to use our ResponseWriter methods while also exposing\n\t// other interfaces that w may implement (http.CloseNotifier,\n\t// http.Flusher, http.Hijacker, http.Pusher, io.ReaderFrom).\n\n\tw = httpsnoop.Wrap(w, httpsnoop.Hooks{\n\t\tHeader: func(httpsnoop.HeaderFunc) httpsnoop.HeaderFunc {\n\t\t\treturn rww.Header\n\t\t},\n\t\tWrite: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc {\n\t\t\treturn rww.Write\n\t\t},\n\t\tWriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc {\n\t\t\treturn rww.WriteHeader\n\t\t},\n\t})\n\n\tlabeler := &Labeler{}\n\tctx = injectLabeler(ctx, labeler)\n\n\tnext.ServeHTTP(w, r.WithContext(ctx))\n\n\tsetAfterServeAttributes(span, bw.read, rww.written, rww.statusCode, bw.err, rww.err)\n\n\t// Add metrics\n\tattributes := append(labeler.Get(), semconvutil.HTTPServerRequestMetrics(h.server, r)...)\n\tif rww.statusCode > 0 {\n\t\tattributes = append(attributes, semconv.HTTPStatusCode(rww.statusCode))\n\t}\n\to := metric.WithAttributes(attributes...)\n\th.counters[RequestContentLength].Add(ctx, bw.read, o)\n\th.counters[ResponseContentLength].Add(ctx, rww.written, o)\n\n\t// Use floating point division here for higher precision (instead of Millisecond method).\n\telapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond)\n\n\th.valueRecorders[ServerLatency].Record(ctx, elapsedTime, o)\n}\n\nfunc setAfterServeAttributes(span trace.Span, read, wrote int64, statusCode int, rerr, werr error) {\n\tattributes := []attribute.KeyValue{}\n\n\t// TODO: Consider adding an event after each read and write, possibly as an\n\t// option (defaulting to off), so as to not create needlessly verbose spans.\n\tif read > 0 {\n\t\tattributes = append(attributes, ReadBytesKey.Int64(read))\n\t}\n\tif rerr != nil && rerr != io.EOF {\n\t\tattributes = append(attributes, ReadErrorKey.String(rerr.Error()))\n\t}\n\tif wrote > 0 {\n\t\tattributes = append(attributes, WroteBytesKey.Int64(wrote))\n\t}\n\tif statusCode > 0 {\n\t\tattributes = append(attributes, semconv.HTTPStatusCode(statusCode))\n\t}\n\tspan.SetStatus(semconvutil.HTTPServerStatus(statusCode))\n\n\tif werr != nil && werr != io.EOF {\n\t\tattributes = append(attributes, WriteErrorKey.String(werr.Error()))\n\t}\n\tspan.SetAttributes(attributes...)\n}\n\n// WithRouteTag annotates spans and metrics with the provided route name\n// with HTTP route attribute.\nfunc WithRouteTag(route string, h http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tattr := semconv.HTTPRouteKey.String(route)\n\n\t\tspan := trace.SpanFromContext(r.Context())\n\t\tspan.SetAttributes(attr)\n\n\t\tlabeler, _ := LabelerFromContext(r.Context())\n\t\tlabeler.Add(attr)\n\n\t\th.ServeHTTP(w, r)\n\t})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/gen.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage semconvutil // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil\"\n\n// Generate semconvutil package:\n//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/httpconv_test.go.tmpl \"--data={}\" --out=httpconv_test.go\n//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/httpconv.go.tmpl \"--data={}\" --out=httpconv.go\n//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/netconv_test.go.tmpl \"--data={}\" --out=netconv_test.go\n//go:generate gotmpl --body=../../../../../../internal/shared/semconvutil/netconv.go.tmpl \"--data={}\" --out=netconv.go\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/httpconv.go",
    "content": "// Code created by gotmpl. DO NOT MODIFY.\n// source: internal/shared/semconvutil/httpconv.go.tmpl\n\n// Copyright The OpenTelemetry Authors\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//     http://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\npackage semconvutil // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil\"\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n)\n\n// HTTPClientResponse returns trace attributes for an HTTP response received by a\n// client from a server. It will return the following attributes if the related\n// values are defined in resp: \"http.status.code\",\n// \"http.response_content_length\".\n//\n// This does not add all OpenTelemetry required attributes for an HTTP event,\n// it assumes ClientRequest was used to create the span with a complete set of\n// attributes. If a complete set of attributes can be generated using the\n// request contained in resp. For example:\n//\n//\tappend(HTTPClientResponse(resp), ClientRequest(resp.Request)...)\nfunc HTTPClientResponse(resp *http.Response) []attribute.KeyValue {\n\treturn hc.ClientResponse(resp)\n}\n\n// HTTPClientRequest returns trace attributes for an HTTP request made by a client.\n// The following attributes are always returned: \"http.url\", \"http.flavor\",\n// \"http.method\", \"net.peer.name\". The following attributes are returned if the\n// related values are defined in req: \"net.peer.port\", \"http.user_agent\",\n// \"http.request_content_length\", \"enduser.id\".\nfunc HTTPClientRequest(req *http.Request) []attribute.KeyValue {\n\treturn hc.ClientRequest(req)\n}\n\n// HTTPClientStatus returns a span status code and message for an HTTP status code\n// value received by a client.\nfunc HTTPClientStatus(code int) (codes.Code, string) {\n\treturn hc.ClientStatus(code)\n}\n\n// HTTPServerRequest returns trace attributes for an HTTP request received by a\n// server.\n//\n// The server must be the primary server name if it is known. For example this\n// would be the ServerName directive\n// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache\n// server, and the server_name directive\n// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an\n// nginx server. More generically, the primary server name would be the host\n// header value that matches the default virtual host of an HTTP server. It\n// should include the host identifier and if a port is used to route to the\n// server that port identifier should be included as an appropriate port\n// suffix.\n//\n// If the primary server name is not known, server should be an empty string.\n// The req Host will be used to determine the server instead.\n//\n// The following attributes are always returned: \"http.method\", \"http.scheme\",\n// \"http.flavor\", \"http.target\", \"net.host.name\". The following attributes are\n// returned if they related values are defined in req: \"net.host.port\",\n// \"net.sock.peer.addr\", \"net.sock.peer.port\", \"http.user_agent\", \"enduser.id\",\n// \"http.client_ip\".\nfunc HTTPServerRequest(server string, req *http.Request) []attribute.KeyValue {\n\treturn hc.ServerRequest(server, req)\n}\n\n// HTTPServerRequestMetrics returns metric attributes for an HTTP request received by a\n// server.\n//\n// The server must be the primary server name if it is known. For example this\n// would be the ServerName directive\n// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache\n// server, and the server_name directive\n// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an\n// nginx server. More generically, the primary server name would be the host\n// header value that matches the default virtual host of an HTTP server. It\n// should include the host identifier and if a port is used to route to the\n// server that port identifier should be included as an appropriate port\n// suffix.\n//\n// If the primary server name is not known, server should be an empty string.\n// The req Host will be used to determine the server instead.\n//\n// The following attributes are always returned: \"http.method\", \"http.scheme\",\n// \"http.flavor\", \"net.host.name\". The following attributes are\n// returned if they related values are defined in req: \"net.host.port\".\nfunc HTTPServerRequestMetrics(server string, req *http.Request) []attribute.KeyValue {\n\treturn hc.ServerRequestMetrics(server, req)\n}\n\n// HTTPServerStatus returns a span status code and message for an HTTP status code\n// value returned by a server. Status codes in the 400-499 range are not\n// returned as errors.\nfunc HTTPServerStatus(code int) (codes.Code, string) {\n\treturn hc.ServerStatus(code)\n}\n\n// HTTPRequestHeader returns the contents of h as attributes.\n//\n// Instrumentation should require an explicit configuration of which headers to\n// captured and then prune what they pass here. Including all headers can be a\n// security risk - explicit configuration helps avoid leaking sensitive\n// information.\n//\n// The User-Agent header is already captured in the http.user_agent attribute\n// from ClientRequest and ServerRequest. Instrumentation may provide an option\n// to capture that header here even though it is not recommended. Otherwise,\n// instrumentation should filter that out of what is passed.\nfunc HTTPRequestHeader(h http.Header) []attribute.KeyValue {\n\treturn hc.RequestHeader(h)\n}\n\n// HTTPResponseHeader returns the contents of h as attributes.\n//\n// Instrumentation should require an explicit configuration of which headers to\n// captured and then prune what they pass here. Including all headers can be a\n// security risk - explicit configuration helps avoid leaking sensitive\n// information.\n//\n// The User-Agent header is already captured in the http.user_agent attribute\n// from ClientRequest and ServerRequest. Instrumentation may provide an option\n// to capture that header here even though it is not recommended. Otherwise,\n// instrumentation should filter that out of what is passed.\nfunc HTTPResponseHeader(h http.Header) []attribute.KeyValue {\n\treturn hc.ResponseHeader(h)\n}\n\n// httpConv are the HTTP semantic convention attributes defined for a version\n// of the OpenTelemetry specification.\ntype httpConv struct {\n\tNetConv *netConv\n\n\tEnduserIDKey                 attribute.Key\n\tHTTPClientIPKey              attribute.Key\n\tHTTPFlavorKey                attribute.Key\n\tHTTPMethodKey                attribute.Key\n\tHTTPRequestContentLengthKey  attribute.Key\n\tHTTPResponseContentLengthKey attribute.Key\n\tHTTPRouteKey                 attribute.Key\n\tHTTPSchemeHTTP               attribute.KeyValue\n\tHTTPSchemeHTTPS              attribute.KeyValue\n\tHTTPStatusCodeKey            attribute.Key\n\tHTTPTargetKey                attribute.Key\n\tHTTPURLKey                   attribute.Key\n\tHTTPUserAgentKey             attribute.Key\n}\n\nvar hc = &httpConv{\n\tNetConv: nc,\n\n\tEnduserIDKey:                 semconv.EnduserIDKey,\n\tHTTPClientIPKey:              semconv.HTTPClientIPKey,\n\tHTTPFlavorKey:                semconv.HTTPFlavorKey,\n\tHTTPMethodKey:                semconv.HTTPMethodKey,\n\tHTTPRequestContentLengthKey:  semconv.HTTPRequestContentLengthKey,\n\tHTTPResponseContentLengthKey: semconv.HTTPResponseContentLengthKey,\n\tHTTPRouteKey:                 semconv.HTTPRouteKey,\n\tHTTPSchemeHTTP:               semconv.HTTPSchemeHTTP,\n\tHTTPSchemeHTTPS:              semconv.HTTPSchemeHTTPS,\n\tHTTPStatusCodeKey:            semconv.HTTPStatusCodeKey,\n\tHTTPTargetKey:                semconv.HTTPTargetKey,\n\tHTTPURLKey:                   semconv.HTTPURLKey,\n\tHTTPUserAgentKey:             semconv.HTTPUserAgentKey,\n}\n\n// ClientResponse returns attributes for an HTTP response received by a client\n// from a server. The following attributes are returned if the related values\n// are defined in resp: \"http.status.code\", \"http.response_content_length\".\n//\n// This does not add all OpenTelemetry required attributes for an HTTP event,\n// it assumes ClientRequest was used to create the span with a complete set of\n// attributes. If a complete set of attributes can be generated using the\n// request contained in resp. For example:\n//\n//\tappend(ClientResponse(resp), ClientRequest(resp.Request)...)\nfunc (c *httpConv) ClientResponse(resp *http.Response) []attribute.KeyValue {\n\tvar n int\n\tif resp.StatusCode > 0 {\n\t\tn++\n\t}\n\tif resp.ContentLength > 0 {\n\t\tn++\n\t}\n\n\tattrs := make([]attribute.KeyValue, 0, n)\n\tif resp.StatusCode > 0 {\n\t\tattrs = append(attrs, c.HTTPStatusCodeKey.Int(resp.StatusCode))\n\t}\n\tif resp.ContentLength > 0 {\n\t\tattrs = append(attrs, c.HTTPResponseContentLengthKey.Int(int(resp.ContentLength)))\n\t}\n\treturn attrs\n}\n\n// ClientRequest returns attributes for an HTTP request made by a client. The\n// following attributes are always returned: \"http.url\", \"http.flavor\",\n// \"http.method\", \"net.peer.name\". The following attributes are returned if the\n// related values are defined in req: \"net.peer.port\", \"http.user_agent\",\n// \"http.request_content_length\", \"enduser.id\".\nfunc (c *httpConv) ClientRequest(req *http.Request) []attribute.KeyValue {\n\tn := 3 // URL, peer name, proto, and method.\n\tvar h string\n\tif req.URL != nil {\n\t\th = req.URL.Host\n\t}\n\tpeer, p := firstHostPort(h, req.Header.Get(\"Host\"))\n\tport := requiredHTTPPort(req.URL != nil && req.URL.Scheme == \"https\", p)\n\tif port > 0 {\n\t\tn++\n\t}\n\tuseragent := req.UserAgent()\n\tif useragent != \"\" {\n\t\tn++\n\t}\n\tif req.ContentLength > 0 {\n\t\tn++\n\t}\n\tuserID, _, hasUserID := req.BasicAuth()\n\tif hasUserID {\n\t\tn++\n\t}\n\tattrs := make([]attribute.KeyValue, 0, n)\n\n\tattrs = append(attrs, c.method(req.Method))\n\tattrs = append(attrs, c.flavor(req.Proto))\n\n\tvar u string\n\tif req.URL != nil {\n\t\t// Remove any username/password info that may be in the URL.\n\t\tuserinfo := req.URL.User\n\t\treq.URL.User = nil\n\t\tu = req.URL.String()\n\t\t// Restore any username/password info that was removed.\n\t\treq.URL.User = userinfo\n\t}\n\tattrs = append(attrs, c.HTTPURLKey.String(u))\n\n\tattrs = append(attrs, c.NetConv.PeerName(peer))\n\tif port > 0 {\n\t\tattrs = append(attrs, c.NetConv.PeerPort(port))\n\t}\n\n\tif useragent != \"\" {\n\t\tattrs = append(attrs, c.HTTPUserAgentKey.String(useragent))\n\t}\n\n\tif l := req.ContentLength; l > 0 {\n\t\tattrs = append(attrs, c.HTTPRequestContentLengthKey.Int64(l))\n\t}\n\n\tif hasUserID {\n\t\tattrs = append(attrs, c.EnduserIDKey.String(userID))\n\t}\n\n\treturn attrs\n}\n\n// ServerRequest returns attributes for an HTTP request received by a server.\n//\n// The server must be the primary server name if it is known. For example this\n// would be the ServerName directive\n// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache\n// server, and the server_name directive\n// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an\n// nginx server. More generically, the primary server name would be the host\n// header value that matches the default virtual host of an HTTP server. It\n// should include the host identifier and if a port is used to route to the\n// server that port identifier should be included as an appropriate port\n// suffix.\n//\n// If the primary server name is not known, server should be an empty string.\n// The req Host will be used to determine the server instead.\n//\n// The following attributes are always returned: \"http.method\", \"http.scheme\",\n// \"http.flavor\", \"http.target\", \"net.host.name\". The following attributes are\n// returned if they related values are defined in req: \"net.host.port\",\n// \"net.sock.peer.addr\", \"net.sock.peer.port\", \"http.user_agent\", \"enduser.id\",\n// \"http.client_ip\".\nfunc (c *httpConv) ServerRequest(server string, req *http.Request) []attribute.KeyValue {\n\t// TODO: This currently does not add the specification required\n\t// `http.target` attribute. It has too high of a cardinality to safely be\n\t// added. An alternate should be added, or this comment removed, when it is\n\t// addressed by the specification. If it is ultimately decided to continue\n\t// not including the attribute, the HTTPTargetKey field of the httpConv\n\t// should be removed as well.\n\n\tn := 4 // Method, scheme, proto, and host name.\n\tvar host string\n\tvar p int\n\tif server == \"\" {\n\t\thost, p = splitHostPort(req.Host)\n\t} else {\n\t\t// Prioritize the primary server name.\n\t\thost, p = splitHostPort(server)\n\t\tif p < 0 {\n\t\t\t_, p = splitHostPort(req.Host)\n\t\t}\n\t}\n\thostPort := requiredHTTPPort(req.TLS != nil, p)\n\tif hostPort > 0 {\n\t\tn++\n\t}\n\tpeer, peerPort := splitHostPort(req.RemoteAddr)\n\tif peer != \"\" {\n\t\tn++\n\t\tif peerPort > 0 {\n\t\t\tn++\n\t\t}\n\t}\n\tuseragent := req.UserAgent()\n\tif useragent != \"\" {\n\t\tn++\n\t}\n\tuserID, _, hasUserID := req.BasicAuth()\n\tif hasUserID {\n\t\tn++\n\t}\n\tclientIP := serverClientIP(req.Header.Get(\"X-Forwarded-For\"))\n\tif clientIP != \"\" {\n\t\tn++\n\t}\n\tattrs := make([]attribute.KeyValue, 0, n)\n\n\tattrs = append(attrs, c.method(req.Method))\n\tattrs = append(attrs, c.scheme(req.TLS != nil))\n\tattrs = append(attrs, c.flavor(req.Proto))\n\tattrs = append(attrs, c.NetConv.HostName(host))\n\n\tif hostPort > 0 {\n\t\tattrs = append(attrs, c.NetConv.HostPort(hostPort))\n\t}\n\n\tif peer != \"\" {\n\t\t// The Go HTTP server sets RemoteAddr to \"IP:port\", this will not be a\n\t\t// file-path that would be interpreted with a sock family.\n\t\tattrs = append(attrs, c.NetConv.SockPeerAddr(peer))\n\t\tif peerPort > 0 {\n\t\t\tattrs = append(attrs, c.NetConv.SockPeerPort(peerPort))\n\t\t}\n\t}\n\n\tif useragent != \"\" {\n\t\tattrs = append(attrs, c.HTTPUserAgentKey.String(useragent))\n\t}\n\n\tif hasUserID {\n\t\tattrs = append(attrs, c.EnduserIDKey.String(userID))\n\t}\n\n\tif clientIP != \"\" {\n\t\tattrs = append(attrs, c.HTTPClientIPKey.String(clientIP))\n\t}\n\n\treturn attrs\n}\n\n// ServerRequestMetrics returns metric attributes for an HTTP request received\n// by a server.\n//\n// The server must be the primary server name if it is known. For example this\n// would be the ServerName directive\n// (https://httpd.apache.org/docs/2.4/mod/core.html#servername) for an Apache\n// server, and the server_name directive\n// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name) for an\n// nginx server. More generically, the primary server name would be the host\n// header value that matches the default virtual host of an HTTP server. It\n// should include the host identifier and if a port is used to route to the\n// server that port identifier should be included as an appropriate port\n// suffix.\n//\n// If the primary server name is not known, server should be an empty string.\n// The req Host will be used to determine the server instead.\n//\n// The following attributes are always returned: \"http.method\", \"http.scheme\",\n// \"http.flavor\", \"net.host.name\". The following attributes are\n// returned if they related values are defined in req: \"net.host.port\".\nfunc (c *httpConv) ServerRequestMetrics(server string, req *http.Request) []attribute.KeyValue {\n\t// TODO: This currently does not add the specification required\n\t// `http.target` attribute. It has too high of a cardinality to safely be\n\t// added. An alternate should be added, or this comment removed, when it is\n\t// addressed by the specification. If it is ultimately decided to continue\n\t// not including the attribute, the HTTPTargetKey field of the httpConv\n\t// should be removed as well.\n\n\tn := 4 // Method, scheme, proto, and host name.\n\tvar host string\n\tvar p int\n\tif server == \"\" {\n\t\thost, p = splitHostPort(req.Host)\n\t} else {\n\t\t// Prioritize the primary server name.\n\t\thost, p = splitHostPort(server)\n\t\tif p < 0 {\n\t\t\t_, p = splitHostPort(req.Host)\n\t\t}\n\t}\n\thostPort := requiredHTTPPort(req.TLS != nil, p)\n\tif hostPort > 0 {\n\t\tn++\n\t}\n\tattrs := make([]attribute.KeyValue, 0, n)\n\n\tattrs = append(attrs, c.methodMetric(req.Method))\n\tattrs = append(attrs, c.scheme(req.TLS != nil))\n\tattrs = append(attrs, c.flavor(req.Proto))\n\tattrs = append(attrs, c.NetConv.HostName(host))\n\n\tif hostPort > 0 {\n\t\tattrs = append(attrs, c.NetConv.HostPort(hostPort))\n\t}\n\n\treturn attrs\n}\n\nfunc (c *httpConv) method(method string) attribute.KeyValue {\n\tif method == \"\" {\n\t\treturn c.HTTPMethodKey.String(http.MethodGet)\n\t}\n\treturn c.HTTPMethodKey.String(method)\n}\n\nfunc (c *httpConv) methodMetric(method string) attribute.KeyValue {\n\tmethod = strings.ToUpper(method)\n\tswitch method {\n\tcase http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace:\n\tdefault:\n\t\tmethod = \"_OTHER\"\n\t}\n\treturn c.HTTPMethodKey.String(method)\n}\n\nfunc (c *httpConv) scheme(https bool) attribute.KeyValue { // nolint:revive\n\tif https {\n\t\treturn c.HTTPSchemeHTTPS\n\t}\n\treturn c.HTTPSchemeHTTP\n}\n\nfunc (c *httpConv) flavor(proto string) attribute.KeyValue {\n\tswitch proto {\n\tcase \"HTTP/1.0\":\n\t\treturn c.HTTPFlavorKey.String(\"1.0\")\n\tcase \"HTTP/1.1\":\n\t\treturn c.HTTPFlavorKey.String(\"1.1\")\n\tcase \"HTTP/2\":\n\t\treturn c.HTTPFlavorKey.String(\"2.0\")\n\tcase \"HTTP/3\":\n\t\treturn c.HTTPFlavorKey.String(\"3.0\")\n\tdefault:\n\t\treturn c.HTTPFlavorKey.String(proto)\n\t}\n}\n\nfunc serverClientIP(xForwardedFor string) string {\n\tif idx := strings.Index(xForwardedFor, \",\"); idx >= 0 {\n\t\txForwardedFor = xForwardedFor[:idx]\n\t}\n\treturn xForwardedFor\n}\n\nfunc requiredHTTPPort(https bool, port int) int { // nolint:revive\n\tif https {\n\t\tif port > 0 && port != 443 {\n\t\t\treturn port\n\t\t}\n\t} else {\n\t\tif port > 0 && port != 80 {\n\t\t\treturn port\n\t\t}\n\t}\n\treturn -1\n}\n\n// Return the request host and port from the first non-empty source.\nfunc firstHostPort(source ...string) (host string, port int) {\n\tfor _, hostport := range source {\n\t\thost, port = splitHostPort(hostport)\n\t\tif host != \"\" || port > 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn\n}\n\n// RequestHeader returns the contents of h as OpenTelemetry attributes.\nfunc (c *httpConv) RequestHeader(h http.Header) []attribute.KeyValue {\n\treturn c.header(\"http.request.header\", h)\n}\n\n// ResponseHeader returns the contents of h as OpenTelemetry attributes.\nfunc (c *httpConv) ResponseHeader(h http.Header) []attribute.KeyValue {\n\treturn c.header(\"http.response.header\", h)\n}\n\nfunc (c *httpConv) header(prefix string, h http.Header) []attribute.KeyValue {\n\tkey := func(k string) attribute.Key {\n\t\tk = strings.ToLower(k)\n\t\tk = strings.ReplaceAll(k, \"-\", \"_\")\n\t\tk = fmt.Sprintf(\"%s.%s\", prefix, k)\n\t\treturn attribute.Key(k)\n\t}\n\n\tattrs := make([]attribute.KeyValue, 0, len(h))\n\tfor k, v := range h {\n\t\tattrs = append(attrs, key(k).StringSlice(v))\n\t}\n\treturn attrs\n}\n\n// ClientStatus returns a span status code and message for an HTTP status code\n// value received by a client.\nfunc (c *httpConv) ClientStatus(code int) (codes.Code, string) {\n\tif code < 100 || code >= 600 {\n\t\treturn codes.Error, fmt.Sprintf(\"Invalid HTTP status code %d\", code)\n\t}\n\tif code >= 400 {\n\t\treturn codes.Error, \"\"\n\t}\n\treturn codes.Unset, \"\"\n}\n\n// ServerStatus returns a span status code and message for an HTTP status code\n// value returned by a server. Status codes in the 400-499 range are not\n// returned as errors.\nfunc (c *httpConv) ServerStatus(code int) (codes.Code, string) {\n\tif code < 100 || code >= 600 {\n\t\treturn codes.Error, fmt.Sprintf(\"Invalid HTTP status code %d\", code)\n\t}\n\tif code >= 500 {\n\t\treturn codes.Error, \"\"\n\t}\n\treturn codes.Unset, \"\"\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go",
    "content": "// Code created by gotmpl. DO NOT MODIFY.\n// source: internal/shared/semconvutil/netconv.go.tmpl\n\n// Copyright The OpenTelemetry Authors\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//     http://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\npackage semconvutil // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil\"\n\nimport (\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\tsemconv \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n)\n\n// NetTransport returns a trace attribute describing the transport protocol of the\n// passed network. See the net.Dial for information about acceptable network\n// values.\nfunc NetTransport(network string) attribute.KeyValue {\n\treturn nc.Transport(network)\n}\n\n// NetClient returns trace attributes for a client network connection to address.\n// See net.Dial for information about acceptable address values, address should\n// be the same as the one used to create conn. If conn is nil, only network\n// peer attributes will be returned that describe address. Otherwise, the\n// socket level information about conn will also be included.\nfunc NetClient(address string, conn net.Conn) []attribute.KeyValue {\n\treturn nc.Client(address, conn)\n}\n\n// NetServer returns trace attributes for a network listener listening at address.\n// See net.Listen for information about acceptable address values, address\n// should be the same as the one used to create ln. If ln is nil, only network\n// host attributes will be returned that describe address. Otherwise, the\n// socket level information about ln will also be included.\nfunc NetServer(address string, ln net.Listener) []attribute.KeyValue {\n\treturn nc.Server(address, ln)\n}\n\n// netConv are the network semantic convention attributes defined for a version\n// of the OpenTelemetry specification.\ntype netConv struct {\n\tNetHostNameKey     attribute.Key\n\tNetHostPortKey     attribute.Key\n\tNetPeerNameKey     attribute.Key\n\tNetPeerPortKey     attribute.Key\n\tNetSockFamilyKey   attribute.Key\n\tNetSockPeerAddrKey attribute.Key\n\tNetSockPeerPortKey attribute.Key\n\tNetSockHostAddrKey attribute.Key\n\tNetSockHostPortKey attribute.Key\n\tNetTransportOther  attribute.KeyValue\n\tNetTransportTCP    attribute.KeyValue\n\tNetTransportUDP    attribute.KeyValue\n\tNetTransportInProc attribute.KeyValue\n}\n\nvar nc = &netConv{\n\tNetHostNameKey:     semconv.NetHostNameKey,\n\tNetHostPortKey:     semconv.NetHostPortKey,\n\tNetPeerNameKey:     semconv.NetPeerNameKey,\n\tNetPeerPortKey:     semconv.NetPeerPortKey,\n\tNetSockFamilyKey:   semconv.NetSockFamilyKey,\n\tNetSockPeerAddrKey: semconv.NetSockPeerAddrKey,\n\tNetSockPeerPortKey: semconv.NetSockPeerPortKey,\n\tNetSockHostAddrKey: semconv.NetSockHostAddrKey,\n\tNetSockHostPortKey: semconv.NetSockHostPortKey,\n\tNetTransportOther:  semconv.NetTransportOther,\n\tNetTransportTCP:    semconv.NetTransportTCP,\n\tNetTransportUDP:    semconv.NetTransportUDP,\n\tNetTransportInProc: semconv.NetTransportInProc,\n}\n\nfunc (c *netConv) Transport(network string) attribute.KeyValue {\n\tswitch network {\n\tcase \"tcp\", \"tcp4\", \"tcp6\":\n\t\treturn c.NetTransportTCP\n\tcase \"udp\", \"udp4\", \"udp6\":\n\t\treturn c.NetTransportUDP\n\tcase \"unix\", \"unixgram\", \"unixpacket\":\n\t\treturn c.NetTransportInProc\n\tdefault:\n\t\t// \"ip:*\", \"ip4:*\", and \"ip6:*\" all are considered other.\n\t\treturn c.NetTransportOther\n\t}\n}\n\n// Host returns attributes for a network host address.\nfunc (c *netConv) Host(address string) []attribute.KeyValue {\n\th, p := splitHostPort(address)\n\tvar n int\n\tif h != \"\" {\n\t\tn++\n\t\tif p > 0 {\n\t\t\tn++\n\t\t}\n\t}\n\n\tif n == 0 {\n\t\treturn nil\n\t}\n\n\tattrs := make([]attribute.KeyValue, 0, n)\n\tattrs = append(attrs, c.HostName(h))\n\tif p > 0 {\n\t\tattrs = append(attrs, c.HostPort(int(p)))\n\t}\n\treturn attrs\n}\n\n// Server returns attributes for a network listener listening at address. See\n// net.Listen for information about acceptable address values, address should\n// be the same as the one used to create ln. If ln is nil, only network host\n// attributes will be returned that describe address. Otherwise, the socket\n// level information about ln will also be included.\nfunc (c *netConv) Server(address string, ln net.Listener) []attribute.KeyValue {\n\tif ln == nil {\n\t\treturn c.Host(address)\n\t}\n\n\tlAddr := ln.Addr()\n\tif lAddr == nil {\n\t\treturn c.Host(address)\n\t}\n\n\thostName, hostPort := splitHostPort(address)\n\tsockHostAddr, sockHostPort := splitHostPort(lAddr.String())\n\tnetwork := lAddr.Network()\n\tsockFamily := family(network, sockHostAddr)\n\n\tn := nonZeroStr(hostName, network, sockHostAddr, sockFamily)\n\tn += positiveInt(hostPort, sockHostPort)\n\tattr := make([]attribute.KeyValue, 0, n)\n\tif hostName != \"\" {\n\t\tattr = append(attr, c.HostName(hostName))\n\t\tif hostPort > 0 {\n\t\t\t// Only if net.host.name is set should net.host.port be.\n\t\t\tattr = append(attr, c.HostPort(hostPort))\n\t\t}\n\t}\n\tif network != \"\" {\n\t\tattr = append(attr, c.Transport(network))\n\t}\n\tif sockFamily != \"\" {\n\t\tattr = append(attr, c.NetSockFamilyKey.String(sockFamily))\n\t}\n\tif sockHostAddr != \"\" {\n\t\tattr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))\n\t\tif sockHostPort > 0 {\n\t\t\t// Only if net.sock.host.addr is set should net.sock.host.port be.\n\t\t\tattr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))\n\t\t}\n\t}\n\treturn attr\n}\n\nfunc (c *netConv) HostName(name string) attribute.KeyValue {\n\treturn c.NetHostNameKey.String(name)\n}\n\nfunc (c *netConv) HostPort(port int) attribute.KeyValue {\n\treturn c.NetHostPortKey.Int(port)\n}\n\n// Client returns attributes for a client network connection to address. See\n// net.Dial for information about acceptable address values, address should be\n// the same as the one used to create conn. If conn is nil, only network peer\n// attributes will be returned that describe address. Otherwise, the socket\n// level information about conn will also be included.\nfunc (c *netConv) Client(address string, conn net.Conn) []attribute.KeyValue {\n\tif conn == nil {\n\t\treturn c.Peer(address)\n\t}\n\n\tlAddr, rAddr := conn.LocalAddr(), conn.RemoteAddr()\n\n\tvar network string\n\tswitch {\n\tcase lAddr != nil:\n\t\tnetwork = lAddr.Network()\n\tcase rAddr != nil:\n\t\tnetwork = rAddr.Network()\n\tdefault:\n\t\treturn c.Peer(address)\n\t}\n\n\tpeerName, peerPort := splitHostPort(address)\n\tvar (\n\t\tsockFamily   string\n\t\tsockPeerAddr string\n\t\tsockPeerPort int\n\t\tsockHostAddr string\n\t\tsockHostPort int\n\t)\n\n\tif lAddr != nil {\n\t\tsockHostAddr, sockHostPort = splitHostPort(lAddr.String())\n\t}\n\n\tif rAddr != nil {\n\t\tsockPeerAddr, sockPeerPort = splitHostPort(rAddr.String())\n\t}\n\n\tswitch {\n\tcase sockHostAddr != \"\":\n\t\tsockFamily = family(network, sockHostAddr)\n\tcase sockPeerAddr != \"\":\n\t\tsockFamily = family(network, sockPeerAddr)\n\t}\n\n\tn := nonZeroStr(peerName, network, sockPeerAddr, sockHostAddr, sockFamily)\n\tn += positiveInt(peerPort, sockPeerPort, sockHostPort)\n\tattr := make([]attribute.KeyValue, 0, n)\n\tif peerName != \"\" {\n\t\tattr = append(attr, c.PeerName(peerName))\n\t\tif peerPort > 0 {\n\t\t\t// Only if net.peer.name is set should net.peer.port be.\n\t\t\tattr = append(attr, c.PeerPort(peerPort))\n\t\t}\n\t}\n\tif network != \"\" {\n\t\tattr = append(attr, c.Transport(network))\n\t}\n\tif sockFamily != \"\" {\n\t\tattr = append(attr, c.NetSockFamilyKey.String(sockFamily))\n\t}\n\tif sockPeerAddr != \"\" {\n\t\tattr = append(attr, c.NetSockPeerAddrKey.String(sockPeerAddr))\n\t\tif sockPeerPort > 0 {\n\t\t\t// Only if net.sock.peer.addr is set should net.sock.peer.port be.\n\t\t\tattr = append(attr, c.NetSockPeerPortKey.Int(sockPeerPort))\n\t\t}\n\t}\n\tif sockHostAddr != \"\" {\n\t\tattr = append(attr, c.NetSockHostAddrKey.String(sockHostAddr))\n\t\tif sockHostPort > 0 {\n\t\t\t// Only if net.sock.host.addr is set should net.sock.host.port be.\n\t\t\tattr = append(attr, c.NetSockHostPortKey.Int(sockHostPort))\n\t\t}\n\t}\n\treturn attr\n}\n\nfunc family(network, address string) string {\n\tswitch network {\n\tcase \"unix\", \"unixgram\", \"unixpacket\":\n\t\treturn \"unix\"\n\tdefault:\n\t\tif ip := net.ParseIP(address); ip != nil {\n\t\t\tif ip.To4() == nil {\n\t\t\t\treturn \"inet6\"\n\t\t\t}\n\t\t\treturn \"inet\"\n\t\t}\n\t}\n\treturn \"\"\n}\n\nfunc nonZeroStr(strs ...string) int {\n\tvar n int\n\tfor _, str := range strs {\n\t\tif str != \"\" {\n\t\t\tn++\n\t\t}\n\t}\n\treturn n\n}\n\nfunc positiveInt(ints ...int) int {\n\tvar n int\n\tfor _, i := range ints {\n\t\tif i > 0 {\n\t\t\tn++\n\t\t}\n\t}\n\treturn n\n}\n\n// Peer returns attributes for a network peer address.\nfunc (c *netConv) Peer(address string) []attribute.KeyValue {\n\th, p := splitHostPort(address)\n\tvar n int\n\tif h != \"\" {\n\t\tn++\n\t\tif p > 0 {\n\t\t\tn++\n\t\t}\n\t}\n\n\tif n == 0 {\n\t\treturn nil\n\t}\n\n\tattrs := make([]attribute.KeyValue, 0, n)\n\tattrs = append(attrs, c.PeerName(h))\n\tif p > 0 {\n\t\tattrs = append(attrs, c.PeerPort(int(p)))\n\t}\n\treturn attrs\n}\n\nfunc (c *netConv) PeerName(name string) attribute.KeyValue {\n\treturn c.NetPeerNameKey.String(name)\n}\n\nfunc (c *netConv) PeerPort(port int) attribute.KeyValue {\n\treturn c.NetPeerPortKey.Int(port)\n}\n\nfunc (c *netConv) SockPeerAddr(addr string) attribute.KeyValue {\n\treturn c.NetSockPeerAddrKey.String(addr)\n}\n\nfunc (c *netConv) SockPeerPort(port int) attribute.KeyValue {\n\treturn c.NetSockPeerPortKey.Int(port)\n}\n\n// splitHostPort splits a network address hostport of the form \"host\",\n// \"host%zone\", \"[host]\", \"[host%zone], \"host:port\", \"host%zone:port\",\n// \"[host]:port\", \"[host%zone]:port\", or \":port\" into host or host%zone and\n// port.\n//\n// An empty host is returned if it is not provided or unparsable. A negative\n// port is returned if it is not provided or unparsable.\nfunc splitHostPort(hostport string) (host string, port int) {\n\tport = -1\n\n\tif strings.HasPrefix(hostport, \"[\") {\n\t\taddrEnd := strings.LastIndex(hostport, \"]\")\n\t\tif addrEnd < 0 {\n\t\t\t// Invalid hostport.\n\t\t\treturn\n\t\t}\n\t\tif i := strings.LastIndex(hostport[addrEnd:], \":\"); i < 0 {\n\t\t\thost = hostport[1:addrEnd]\n\t\t\treturn\n\t\t}\n\t} else {\n\t\tif i := strings.LastIndex(hostport, \":\"); i < 0 {\n\t\t\thost = hostport\n\t\t\treturn\n\t\t}\n\t}\n\n\thost, pStr, err := net.SplitHostPort(hostport)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tp, err := strconv.ParseUint(pStr, 10, 16)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn host, int(p)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/labeler.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// Labeler is used to allow instrumented HTTP handlers to add custom attributes to\n// the metrics recorded by the net/http instrumentation.\ntype Labeler struct {\n\tmu         sync.Mutex\n\tattributes []attribute.KeyValue\n}\n\n// Add attributes to a Labeler.\nfunc (l *Labeler) Add(ls ...attribute.KeyValue) {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tl.attributes = append(l.attributes, ls...)\n}\n\n// Get returns a copy of the attributes added to the Labeler.\nfunc (l *Labeler) Get() []attribute.KeyValue {\n\tl.mu.Lock()\n\tdefer l.mu.Unlock()\n\tret := make([]attribute.KeyValue, len(l.attributes))\n\tcopy(ret, l.attributes)\n\treturn ret\n}\n\ntype labelerContextKeyType int\n\nconst lablelerContextKey labelerContextKeyType = 0\n\nfunc injectLabeler(ctx context.Context, l *Labeler) context.Context {\n\treturn context.WithValue(ctx, lablelerContextKey, l)\n}\n\n// LabelerFromContext retrieves a Labeler instance from the provided context if\n// one is available.  If no Labeler was found in the provided context a new, empty\n// Labeler is returned and the second return value is false.  In this case it is\n// safe to use the Labeler but any attributes added to it will not be used.\nfunc LabelerFromContext(ctx context.Context) (*Labeler, bool) {\n\tl, ok := ctx.Value(lablelerContextKey).(*Labeler)\n\tif !ok {\n\t\tl = &Labeler{}\n\t}\n\treturn l, ok\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\n\t\"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil\"\n\t\"go.opentelemetry.io/otel\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Transport implements the http.RoundTripper interface and wraps\n// outbound HTTP(S) requests with a span.\ntype Transport struct {\n\trt http.RoundTripper\n\n\ttracer            trace.Tracer\n\tpropagators       propagation.TextMapPropagator\n\tspanStartOptions  []trace.SpanStartOption\n\tfilters           []Filter\n\tspanNameFormatter func(string, *http.Request) string\n\tclientTrace       func(context.Context) *httptrace.ClientTrace\n}\n\nvar _ http.RoundTripper = &Transport{}\n\n// NewTransport wraps the provided http.RoundTripper with one that\n// starts a span and injects the span context into the outbound request headers.\n//\n// If the provided http.RoundTripper is nil, http.DefaultTransport will be used\n// as the base http.RoundTripper.\nfunc NewTransport(base http.RoundTripper, opts ...Option) *Transport {\n\tif base == nil {\n\t\tbase = http.DefaultTransport\n\t}\n\n\tt := Transport{\n\t\trt: base,\n\t}\n\n\tdefaultOpts := []Option{\n\t\tWithSpanOptions(trace.WithSpanKind(trace.SpanKindClient)),\n\t\tWithSpanNameFormatter(defaultTransportFormatter),\n\t}\n\n\tc := newConfig(append(defaultOpts, opts...)...)\n\tt.applyConfig(c)\n\n\treturn &t\n}\n\nfunc (t *Transport) applyConfig(c *config) {\n\tt.tracer = c.Tracer\n\tt.propagators = c.Propagators\n\tt.spanStartOptions = c.SpanStartOptions\n\tt.filters = c.Filters\n\tt.spanNameFormatter = c.SpanNameFormatter\n\tt.clientTrace = c.ClientTrace\n}\n\nfunc defaultTransportFormatter(_ string, r *http.Request) string {\n\treturn \"HTTP \" + r.Method\n}\n\n// RoundTrip creates a Span and propagates its context via the provided request's headers\n// before handing the request to the configured base RoundTripper. The created span will\n// end when the response body is closed or when a read from the body returns io.EOF.\nfunc (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {\n\tfor _, f := range t.filters {\n\t\tif !f(r) {\n\t\t\t// Simply pass through to the base RoundTripper if a filter rejects the request\n\t\t\treturn t.rt.RoundTrip(r)\n\t\t}\n\t}\n\n\ttracer := t.tracer\n\n\tif tracer == nil {\n\t\tif span := trace.SpanFromContext(r.Context()); span.SpanContext().IsValid() {\n\t\t\ttracer = newTracer(span.TracerProvider())\n\t\t} else {\n\t\t\ttracer = newTracer(otel.GetTracerProvider())\n\t\t}\n\t}\n\n\topts := append([]trace.SpanStartOption{}, t.spanStartOptions...) // start with the configured options\n\n\tctx, span := tracer.Start(r.Context(), t.spanNameFormatter(\"\", r), opts...)\n\n\tif t.clientTrace != nil {\n\t\tctx = httptrace.WithClientTrace(ctx, t.clientTrace(ctx))\n\t}\n\n\tr = r.Clone(ctx) // According to RoundTripper spec, we shouldn't modify the origin request.\n\tspan.SetAttributes(semconvutil.HTTPClientRequest(r)...)\n\tt.propagators.Inject(ctx, propagation.HeaderCarrier(r.Header))\n\n\tres, err := t.rt.RoundTrip(r)\n\tif err != nil {\n\t\tspan.RecordError(err)\n\t\tspan.SetStatus(codes.Error, err.Error())\n\t\tspan.End()\n\t\treturn res, err\n\t}\n\n\tspan.SetAttributes(semconvutil.HTTPClientResponse(res)...)\n\tspan.SetStatus(semconvutil.HTTPClientStatus(res.StatusCode))\n\tres.Body = newWrappedBody(span, res.Body)\n\n\treturn res, err\n}\n\n// newWrappedBody returns a new and appropriately scoped *wrappedBody as an\n// io.ReadCloser. If the passed body implements io.Writer, the returned value\n// will implement io.ReadWriteCloser.\nfunc newWrappedBody(span trace.Span, body io.ReadCloser) io.ReadCloser {\n\t// The successful protocol switch responses will have a body that\n\t// implement an io.ReadWriteCloser. Ensure this interface type continues\n\t// to be satisfied if that is the case.\n\tif _, ok := body.(io.ReadWriteCloser); ok {\n\t\treturn &wrappedBody{span: span, body: body}\n\t}\n\n\t// Remove the implementation of the io.ReadWriteCloser and only implement\n\t// the io.ReadCloser.\n\treturn struct{ io.ReadCloser }{&wrappedBody{span: span, body: body}}\n}\n\n// wrappedBody is the response body type returned by the transport\n// instrumentation to complete a span. Errors encountered when using the\n// response body are recorded in span tracking the response.\n//\n// The span tracking the response is ended when this body is closed.\n//\n// If the response body implements the io.Writer interface (i.e. for\n// successful protocol switches), the wrapped body also will.\ntype wrappedBody struct {\n\tspan trace.Span\n\tbody io.ReadCloser\n}\n\nvar _ io.ReadWriteCloser = &wrappedBody{}\n\nfunc (wb *wrappedBody) Write(p []byte) (int, error) {\n\t// This will not panic given the guard in newWrappedBody.\n\tn, err := wb.body.(io.Writer).Write(p)\n\tif err != nil {\n\t\twb.span.RecordError(err)\n\t\twb.span.SetStatus(codes.Error, err.Error())\n\t}\n\treturn n, err\n}\n\nfunc (wb *wrappedBody) Read(b []byte) (int, error) {\n\tn, err := wb.body.Read(b)\n\n\tswitch err {\n\tcase nil:\n\t\t// nothing to do here but fall through to the return\n\tcase io.EOF:\n\t\twb.span.End()\n\tdefault:\n\t\twb.span.RecordError(err)\n\t\twb.span.SetStatus(codes.Error, err.Error())\n\t}\n\treturn n, err\n}\n\nfunc (wb *wrappedBody) Close() error {\n\twb.span.End()\n\tif wb.body != nil {\n\t\treturn wb.body.Close()\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\n// Version is the current release version of the otelhttp instrumentation.\nfunc Version() string {\n\treturn \"0.45.0\"\n\t// This string is updated by the pre_release.sh script during release\n}\n\n// SemVersion is the semantic version to be supplied to tracer/meter creation.\n//\n// Deprecated: Use [Version] instead.\nfunc SemVersion() string {\n\treturn Version()\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/wrap.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otelhttp // import \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\"\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"net/http\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n)\n\nvar _ io.ReadCloser = &bodyWrapper{}\n\n// bodyWrapper wraps a http.Request.Body (an io.ReadCloser) to track the number\n// of bytes read and the last error.\ntype bodyWrapper struct {\n\tio.ReadCloser\n\trecord func(n int64) // must not be nil\n\n\tread int64\n\terr  error\n}\n\nfunc (w *bodyWrapper) Read(b []byte) (int, error) {\n\tn, err := w.ReadCloser.Read(b)\n\tn1 := int64(n)\n\tw.read += n1\n\tw.err = err\n\tw.record(n1)\n\treturn n, err\n}\n\nfunc (w *bodyWrapper) Close() error {\n\treturn w.ReadCloser.Close()\n}\n\nvar _ http.ResponseWriter = &respWriterWrapper{}\n\n// respWriterWrapper wraps a http.ResponseWriter in order to track the number of\n// bytes written, the last error, and to catch the first written statusCode.\n// TODO: The wrapped http.ResponseWriter doesn't implement any of the optional\n// types (http.Hijacker, http.Pusher, http.CloseNotifier, http.Flusher, etc)\n// that may be useful when using it in real life situations.\ntype respWriterWrapper struct {\n\thttp.ResponseWriter\n\trecord func(n int64) // must not be nil\n\n\t// used to inject the header\n\tctx context.Context\n\n\tprops propagation.TextMapPropagator\n\n\twritten     int64\n\tstatusCode  int\n\terr         error\n\twroteHeader bool\n}\n\nfunc (w *respWriterWrapper) Header() http.Header {\n\treturn w.ResponseWriter.Header()\n}\n\nfunc (w *respWriterWrapper) Write(p []byte) (int, error) {\n\tif !w.wroteHeader {\n\t\tw.WriteHeader(http.StatusOK)\n\t}\n\tn, err := w.ResponseWriter.Write(p)\n\tn1 := int64(n)\n\tw.record(n1)\n\tw.written += n1\n\tw.err = err\n\treturn n, err\n}\n\n// WriteHeader persists initial statusCode for span attribution.\n// All calls to WriteHeader will be propagated to the underlying ResponseWriter\n// and will persist the statusCode from the first call.\n// Blocking consecutive calls to WriteHeader alters expected behavior and will\n// remove warning logs from net/http where developers will notice incorrect handler implementations.\nfunc (w *respWriterWrapper) WriteHeader(statusCode int) {\n\tif !w.wroteHeader {\n\t\tw.wroteHeader = true\n\t\tw.statusCode = statusCode\n\t}\n\tw.ResponseWriter.WriteHeader(statusCode)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.codespellignore",
    "content": "ot\nfo\nte\ncollison\nconsequentially\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.codespellrc",
    "content": "# https://github.com/codespell-project/codespell\n[codespell]\nbuiltin = clear,rare,informal\ncheck-filenames =\ncheck-hidden =\nignore-words = .codespellignore\ninteractive = 1\nskip = .git,go.mod,go.sum,semconv,venv,.tools\nuri-ignore-words-list = *\nwrite =\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.gitattributes",
    "content": "* text=auto eol=lf\n*.{cmd,[cC][mM][dD]} text eol=crlf\n*.{bat,[bB][aA][tT]} text eol=crlf\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.gitignore",
    "content": ".DS_Store\nThumbs.db\n\n.tools/\nvenv/\n.idea/\n.vscode/\n*.iml\n*.so\ncoverage.*\ngo.work\ngo.work.sum\n\ngen/\n\n/example/dice/dice\n/example/fib/fib\n/example/fib/traces.txt\n/example/jaeger/jaeger\n/example/namedtracer/namedtracer\n/example/opencensus/opencensus\n/example/passthrough/passthrough\n/example/prometheus/prometheus\n/example/zipkin/zipkin\n/example/otel-collector/otel-collector\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.gitmodules",
    "content": "[submodule \"opentelemetry-proto\"]\n\tpath = exporters/otlp/internal/opentelemetry-proto\n\turl = https://github.com/open-telemetry/opentelemetry-proto\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.golangci.yml",
    "content": "# See https://github.com/golangci/golangci-lint#config-file\nrun:\n  issues-exit-code: 1 #Default\n  tests: true #Default\n\nlinters:\n  # Disable everything by default so upgrades to not include new \"default\n  # enabled\" linters.\n  disable-all: true\n  # Specifically enable linters we want to use.\n  enable:\n    - depguard\n    - errcheck\n    - godot\n    - gofmt\n    - goimports\n    - gosimple\n    - govet\n    - ineffassign\n    - misspell\n    - revive\n    - staticcheck\n    - typecheck\n    - unused\n\nissues:\n  # Maximum issues count per one linter.\n  # Set to 0 to disable.\n  # Default: 50\n  # Setting to unlimited so the linter only is run once to debug all issues.\n  max-issues-per-linter: 0\n  # Maximum count of issues with the same text.\n  # Set to 0 to disable.\n  # Default: 3\n  # Setting to unlimited so the linter only is run once to debug all issues.\n  max-same-issues: 0\n  # Excluding configuration per-path, per-linter, per-text and per-source.\n  exclude-rules:\n    # TODO: Having appropriate comments for exported objects helps development,\n    # even for objects in internal packages. Appropriate comments for all\n    # exported objects should be added and this exclusion removed.\n    - path: '.*internal/.*'\n      text: \"exported (method|function|type|const) (.+) should have comment or be unexported\"\n      linters:\n        - revive\n    # Yes, they are, but it's okay in a test.\n    - path: _test\\.go\n      text: \"exported func.*returns unexported type.*which can be annoying to use\"\n      linters:\n        - revive\n    # Example test functions should be treated like main.\n    - path: example.*_test\\.go\n      text: \"calls to (.+) only in main[(][)] or init[(][)] functions\"\n      linters:\n        - revive\n  include:\n    # revive exported should have comment or be unexported.\n    - EXC0012\n    # revive package comment should be of the form ...\n    - EXC0013\n\nlinters-settings:\n  depguard:\n    rules:\n      non-tests:\n        files:\n          - \"!$test\"\n          - \"!**/*test/*.go\"\n          - \"!**/internal/matchers/*.go\"\n        deny:\n          - pkg: \"testing\"\n          - pkg: \"github.com/stretchr/testify\"\n          - pkg: \"crypto/md5\"\n          - pkg: \"crypto/sha1\"\n          - pkg: \"crypto/**/pkix\"\n      otlp-internal:\n        files:\n          - \"!**/exporters/otlp/internal/**/*.go\"\n        deny:\n          - pkg: \"go.opentelemetry.io/otel/exporters/otlp/internal\"\n            desc: Do not use cross-module internal packages.\n      otlptrace-internal:\n        files:\n          - \"!**/exporters/otlp/otlptrace/*.go\"\n          - \"!**/exporters/otlp/otlptrace/internal/**.go\"\n        deny:\n          - pkg: \"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal\"\n            desc: Do not use cross-module internal packages.\n      otlpmetric-internal:\n        files:\n          - \"!**/exporters/otlp/otlpmetric/internal/*.go\"\n          - \"!**/exporters/otlp/otlpmetric/internal/**/*.go\"\n        deny:\n          - pkg: \"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal\"\n            desc: Do not use cross-module internal packages.\n      otel-internal:\n        files:\n          - \"**/sdk/*.go\"\n          - \"**/sdk/**/*.go\"\n          - \"**/exporters/*.go\"\n          - \"**/exporters/**/*.go\"\n          - \"**/schema/*.go\"\n          - \"**/schema/**/*.go\"\n          - \"**/metric/*.go\"\n          - \"**/metric/**/*.go\"\n          - \"**/bridge/*.go\"\n          - \"**/bridge/**/*.go\"\n          - \"**/example/*.go\"\n          - \"**/example/**/*.go\"\n          - \"**/trace/*.go\"\n          - \"**/trace/**/*.go\"\n        deny:\n          - pkg: \"go.opentelemetry.io/otel/internal$\"\n            desc: Do not use cross-module internal packages.\n          - pkg: \"go.opentelemetry.io/otel/internal/attribute\"\n            desc: Do not use cross-module internal packages.\n          - pkg: \"go.opentelemetry.io/otel/internal/internaltest\"\n            desc: Do not use cross-module internal packages.\n          - pkg: \"go.opentelemetry.io/otel/internal/matchers\"\n            desc: Do not use cross-module internal packages.\n  godot:\n    exclude:\n      # Exclude links.\n      - '^ *\\[[^]]+\\]:'\n      # Exclude sentence fragments for lists.\n      - '^[ ]*[-•]'\n      # Exclude sentences prefixing a list.\n      - ':$'\n  goimports:\n    local-prefixes: go.opentelemetry.io\n  misspell:\n    locale: US\n    ignore-words:\n      - cancelled\n  revive:\n    # Sets the default failure confidence.\n    # This means that linting errors with less than 0.8 confidence will be ignored.\n    # Default: 0.8\n    confidence: 0.01\n    rules:\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#blank-imports\n      - name: blank-imports\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr\n      - name: bool-literal-in-expr\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#constant-logical-expr\n      - name: constant-logical-expr\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument\n      # TODO (#3372) re-enable linter when it is compatible. https://github.com/golangci/golangci-lint/issues/3280\n      - name: context-as-argument\n        disabled: true\n        arguments:\n          allowTypesBefore: \"*testing.T\"\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-keys-type\n      - name: context-keys-type\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#deep-exit\n      - name: deep-exit\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#defer\n      - name: defer\n        disabled: false\n        arguments:\n          - [\"call-chain\", \"loop\"]\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#dot-imports\n      - name: dot-imports\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports\n      - name: duplicated-imports\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return\n      - name: early-return\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block\n      - name: empty-block\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines\n      - name: empty-lines\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-naming\n      - name: error-naming\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-return\n      - name: error-return\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-strings\n      - name: error-strings\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#errorf\n      - name: errorf\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#exported\n      - name: exported\n        disabled: false\n        arguments:\n          - \"sayRepetitiveInsteadOfStutters\"\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#flag-parameter\n      - name: flag-parameter\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#identical-branches\n      - name: identical-branches\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#if-return\n      - name: if-return\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#increment-decrement\n      - name: increment-decrement\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow\n      - name: indent-error-flow\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-shadowing\n      - name: import-shadowing\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments\n      - name: package-comments\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range\n      - name: range\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-in-closure\n      - name: range-val-in-closure\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-address\n      - name: range-val-address\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redefines-builtin-id\n      - name: redefines-builtin-id\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-format\n      - name: string-format\n        disabled: false\n        arguments:\n          - - panic\n            - '/^[^\\n]*$/'\n            - must not contain line breaks\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#struct-tag\n      - name: struct-tag\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#superfluous-else\n      - name: superfluous-else\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-equal\n      - name: time-equal\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-naming\n      - name: var-naming\n        disabled: false\n        arguments:\n          - [\"ID\"] # AllowList\n          - [\"Otel\", \"Aws\", \"Gcp\"] # DenyList\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-declaration\n      - name: var-declaration\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unconditional-recursion\n      - name: unconditional-recursion\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-return\n      - name: unexported-return\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error\n      - name: unhandled-error\n        disabled: false\n        arguments:\n          - \"fmt.Fprint\"\n          - \"fmt.Fprintf\"\n          - \"fmt.Fprintln\"\n          - \"fmt.Print\"\n          - \"fmt.Printf\"\n          - \"fmt.Println\"\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unnecessary-stmt\n      - name: unnecessary-stmt\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break\n      - name: useless-break\n        disabled: false\n      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#waitgroup-by-value\n      - name: waitgroup-by-value\n        disabled: false\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.lycheeignore",
    "content": "http://localhost\nhttp://jaeger-collector\nhttps://github.com/open-telemetry/opentelemetry-go/milestone/\nhttps://github.com/open-telemetry/opentelemetry-go/projects\nfile:///home/runner/work/opentelemetry-go/opentelemetry-go/libraries\nfile:///home/runner/work/opentelemetry-go/opentelemetry-go/manual\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/.markdownlint.yaml",
    "content": "# Default state for all rules\ndefault: true\n\n# ul-style\nMD004: false\n\n# hard-tabs\nMD010: false\n\n# line-length\nMD013: false\n\n# no-duplicate-header\nMD024:\n  siblings_only: true\n\n#single-title\nMD025: false\n\n# ol-prefix\nMD029:\n  style: ordered\n\n# no-inline-html\nMD033: false\n\n# fenced-code-language\nMD040: false\n\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/CHANGELOG.md",
    "content": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).\n\nThis project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [Unreleased]\n\n## [1.19.0/0.42.0/0.0.7] 2023-09-28\n\nThis release contains the first stable release of the OpenTelemetry Go [metric SDK].\nOur project stability guarantees now apply to the `go.opentelemetry.io/otel/sdk/metric` package.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- Add the \"Roll the dice\" getting started application example in `go.opentelemetry.io/otel/example/dice`. (#4539)\n- The `WithWriter` and `WithPrettyPrint` options to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to set a custom `io.Writer`, and allow displaying the output in human-readable JSON. (#4507)\n\n### Changed\n\n- Allow '/' characters in metric instrument names. (#4501)\n- The exporter in `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` does not prettify its output by default anymore. (#4507)\n- Upgrade `gopkg.io/yaml` from `v2` to `v3` in `go.opentelemetry.io/otel/schema`. (#4535)\n\n### Fixed\n\n- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the Prometheus metric on every `Collect` if we know the scope is invalid. (#4499)\n\n### Removed\n\n- Remove `\"go.opentelemetry.io/otel/bridge/opencensus\".NewMetricExporter`, which is replaced by `NewMetricProducer`. (#4566)\n\n## [1.19.0-rc.1/0.42.0-rc.1] 2023-09-14\n\nThis is a release candidate for the v1.19.0/v0.42.0 release.\nThat release is expected to include the `v1` release of the OpenTelemetry Go metric SDK and will provide stability guarantees of that SDK.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Changed\n\n- Allow '/' characters in metric instrument names. (#4501)\n\n### Fixed\n\n- In `go.opentelemetry.op/otel/exporters/prometheus`, don't try to create the prometheus metric on every `Collect` if we know the scope is invalid. (#4499)\n\n## [1.18.0/0.41.0/0.0.6] 2023-09-12\n\nThis release drops the compatibility guarantee of [Go 1.19].\n\n### Added\n\n- Add `WithProducer` option in `go.opentelemetry.op/otel/exporters/prometheus` to restore the ability to register producers on the prometheus exporter's manual reader. (#4473)\n- Add `IgnoreValue` option in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest` to allow ignoring values when comparing metrics. (#4447)\n\n### Changed\n\n- Use a `TestingT` interface instead of `*testing.T` struct in `go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#4483)\n\n### Deprecated\n\n- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` was deprecated in `v0.35.0` (#3541).\n  The deprecation notice format for the function has been corrected to trigger Go documentation and build tooling. (#4470)\n\n### Removed\n\n- Removed the deprecated `go.opentelemetry.io/otel/exporters/jaeger` package. (#4467)\n- Removed the deprecated `go.opentelemetry.io/otel/example/jaeger` package. (#4467)\n- Removed the deprecated `go.opentelemetry.io/otel/sdk/metric/aggregation` package. (#4468)\n- Removed the deprecated internal packages in `go.opentelemetry.io/otel/exporters/otlp` and its sub-packages. (#4469)\n- Dropped guaranteed support for versions of Go less than 1.20. (#4481)\n\n## [1.17.0/0.40.0/0.0.5] 2023-08-28\n\n### Added\n\n- Export the `ManualReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244)\n- Export the `PeriodicReader` struct in `go.opentelemetry.io/otel/sdk/metric`. (#4244)\n- Add support for exponential histogram aggregations.\n  A histogram can be configured as an exponential histogram using a view with `\"go.opentelemetry.io/otel/sdk/metric\".ExponentialHistogram` as the aggregation. (#4245)\n- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4272)\n- Export the `Exporter` struct in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4272)\n- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` environment variable. (#4287)\n- Add `WithoutCounterSuffixes` option in `go.opentelemetry.io/otel/exporters/prometheus` to disable addition of `_total` suffixes. (#4306)\n- Add info and debug logging to the metric SDK in `go.opentelemetry.io/otel/sdk/metric`. (#4315)\n- The `go.opentelemetry.io/otel/semconv/v1.21.0` package.\n  The package contains semantic conventions from the `v1.21.0` version of the OpenTelemetry Semantic Conventions. (#4362)\n- Accept 201 to 299 HTTP status as success in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4365)\n- Document the `Temporality` and `Aggregation` methods of the `\"go.opentelemetry.io/otel/sdk/metric\".Exporter\"` need to be concurrent safe. (#4381)\n- Expand the set of units supported by the Prometheus exporter, and don't add unit suffixes if they are already present in `go.opentelemetry.op/otel/exporters/prometheus` (#4374)\n- Move the `Aggregation` interface and its implementations from `go.opentelemetry.io/otel/sdk/metric/aggregation` to `go.opentelemetry.io/otel/sdk/metric`. (#4435)\n- The exporters in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` now support the `OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION` environment variable. (#4437)\n- Add the `NewAllowKeysFilter` and `NewDenyKeysFilter` functions to `go.opentelemetry.io/otel/attribute` to allow convenient creation of allow-keys and deny-keys filters. (#4444)\n- Support Go 1.21. (#4463)\n\n### Changed\n\n- Starting from `v1.21.0` of semantic conventions, `go.opentelemetry.io/otel/semconv/{version}/httpconv` and `go.opentelemetry.io/otel/semconv/{version}/netconv` packages will no longer be published. (#4145)\n- Log duplicate instrument conflict at a warning level instead of info in `go.opentelemetry.io/otel/sdk/metric`. (#4202)\n- Return an error on the creation of new instruments in `go.opentelemetry.io/otel/sdk/metric` if their name doesn't pass regexp validation. (#4210)\n- `NewManualReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*ManualReader` instead of `Reader`. (#4244)\n- `NewPeriodicReader` in `go.opentelemetry.io/otel/sdk/metric` returns `*PeriodicReader` instead of `Reader`. (#4244)\n- Count the Collect time in the `PeriodicReader` timeout in `go.opentelemetry.io/otel/sdk/metric`. (#4221)\n- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` returns `*Exporter` instead of `\"go.opentelemetry.io/otel/sdk/metric\".Exporter`. (#4272)\n- The function `New` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` returns `*Exporter` instead of `\"go.opentelemetry.io/otel/sdk/metric\".Exporter`. (#4272)\n- If an attribute set is omitted from an async callback, the previous value will no longer be exported in `go.opentelemetry.io/otel/sdk/metric`. (#4290)\n- If an attribute set is observed multiple times in an async callback in `go.opentelemetry.io/otel/sdk/metric`, the values will be summed instead of the last observation winning. (#4289)\n- Allow the explicit bucket histogram aggregation to be used for the up-down counter, observable counter, observable up-down counter, and observable gauge in the `go.opentelemetry.io/otel/sdk/metric` package. (#4332)\n- Restrict `Meter`s in `go.opentelemetry.io/otel/sdk/metric` to only register and collect instruments it created. (#4333)\n- `PeriodicReader.Shutdown` and `PeriodicReader.ForceFlush` in `go.opentelemetry.io/otel/sdk/metric` now apply the periodic reader's timeout to the operation if the user provided context does not contain a deadline. (#4356, #4377)\n- Upgrade all use of `go.opentelemetry.io/otel/semconv` to use `v1.21.0`. (#4408)\n- Increase instrument name maximum length from 63 to 255 characters in `go.opentelemetry.io/otel/sdk/metric`. (#4434)\n- Add `go.opentelemetry.op/otel/sdk/metric.WithProducer` as an `Option` for `\"go.opentelemetry.io/otel/sdk/metric\".NewManualReader` and `\"go.opentelemetry.io/otel/sdk/metric\".NewPeriodicReader`. (#4346)\n\n### Removed\n\n- Remove `Reader.RegisterProducer` in `go.opentelemetry.io/otel/metric`.\n  Use the added `WithProducer` option instead. (#4346)\n- Remove `Reader.ForceFlush` in `go.opentelemetry.io/otel/metric`.\n  Notice that `PeriodicReader.ForceFlush` is still available. (#4375)\n\n### Fixed\n\n- Correctly format log messages from the `go.opentelemetry.io/otel/exporters/zipkin` exporter. (#4143)\n- Log an error for calls to `NewView` in `go.opentelemetry.io/otel/sdk/metric` that have empty criteria. (#4307)\n- Fix `\"go.opentelemetry.io/otel/sdk/resource\".WithHostID()` to not set an empty `host.id`. (#4317)\n- Use the instrument identifying fields to cache aggregators and determine duplicate instrument registrations in `go.opentelemetry.io/otel/sdk/metric`. (#4337)\n- Detect duplicate instruments for case-insensitive names in `go.opentelemetry.io/otel/sdk/metric`. (#4338)\n- The `ManualReader` will not panic if `AggregationSelector` returns `nil` in `go.opentelemetry.io/otel/sdk/metric`. (#4350)\n- If a `Reader`'s `AggregationSelector` returns `nil` or `DefaultAggregation` the pipeline will use the default aggregation. (#4350)\n- Log a suggested view that fixes instrument conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4349)\n- Fix possible panic, deadlock and race condition in batch span processor in `go.opentelemetry.io/otel/sdk/trace`. (#4353)\n- Improve context cancellation handling in batch span processor's `ForceFlush` in  `go.opentelemetry.io/otel/sdk/trace`. (#4369)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` using gotmpl. (#4397, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4404, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` using gotmpl. (#4407, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4400, #3846)\n- Decouple `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp/internal` from `go.opentelemetry.io/otel/exporters/otlp/internal` and `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` using gotmpl. (#4401, #3846)\n- Do not block the metric SDK when OTLP metric exports are blocked in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#3925, #4395)\n- Do not append `_total` if the counter already has that suffix for the Prometheus exproter in `go.opentelemetry.io/otel/exporter/prometheus`. (#4373)\n- Fix resource detection data race in `go.opentelemetry.io/otel/sdk/resource`. (#4409)\n- Use the first-seen instrument name during instrument name conflicts in `go.opentelemetry.io/otel/sdk/metric`. (#4428)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/exporters/jaeger` package is deprecated.\n  OpenTelemetry dropped support for Jaeger exporter in July 2023.\n  Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`\n  or `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` instead. (#4423)\n- The `go.opentelemetry.io/otel/example/jaeger` package is deprecated. (#4423)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/oconf` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/otest` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/internal/transform` package is deprecated. (#4420)\n- The `go.opentelemetry.io/otel/exporters/otlp/internal` package is deprecated. (#4421)\n- The `go.opentelemetry.io/otel/exporters/otlp/internal/envconfig` package is deprecated. (#4421)\n- The `go.opentelemetry.io/otel/exporters/otlp/internal/retry` package is deprecated. (#4421)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/envconfig` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlptracetest` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry` package is deprecated. (#4425)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregation` package is deprecated.\n  Use the aggregation types added to `go.opentelemetry.io/otel/sdk/metric` instead. (#4435)\n\n## [1.16.0/0.39.0] 2023-05-18\n\nThis release contains the first stable release of the OpenTelemetry Go [metric API].\nOur project stability guarantees now apply to the `go.opentelemetry.io/otel/metric` package.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- The `go.opentelemetry.io/otel/semconv/v1.19.0` package.\n  The package contains semantic conventions from the `v1.19.0` version of the OpenTelemetry specification. (#3848)\n- The `go.opentelemetry.io/otel/semconv/v1.20.0` package.\n  The package contains semantic conventions from the `v1.20.0` version of the OpenTelemetry specification. (#4078)\n- The Exponential Histogram data types in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#4165)\n- OTLP metrics exporter now supports the Exponential Histogram Data Type. (#4222)\n- Fix serialization of `time.Time` zero values in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` packages. (#4271)\n\n### Changed\n\n- Use `strings.Cut()` instead of `string.SplitN()` for better readability and memory use. (#4049)\n- `MeterProvider` returns noop meters once it has been shutdown. (#4154)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/instrument` package is removed.\n  Use `go.opentelemetry.io/otel/metric` instead. (#4055)\n\n### Fixed\n\n- Fix build for BSD based systems in `go.opentelemetry.io/otel/sdk/resource`. (#4077)\n\n## [1.16.0-rc.1/0.39.0-rc.1] 2023-05-03\n\nThis is a release candidate for the v1.16.0/v0.39.0 release.\nThat release is expected to include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#4039)\n  - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`.\n  - Use `GetMeterProivder` for a global `metric.MeterProvider`.\n  - Use `SetMeterProivder` to set the global `metric.MeterProvider`.\n\n### Changed\n\n- Move the `go.opentelemetry.io/otel/metric` module to the `stable-v1` module set.\n  This stages the metric API to be released as a stable module. (#4038)\n\n### Removed\n\n- The `go.opentelemetry.io/otel/metric/global` package is removed.\n  Use `go.opentelemetry.io/otel` instead. (#4039)\n\n## [1.15.1/0.38.1] 2023-05-02\n\n### Fixed\n\n- Remove unused imports from `sdk/resource/host_id_bsd.go` which caused build failures. (#4040, #4041)\n\n## [1.15.0/0.38.0] 2023-04-27\n\n### Added\n\n- The `go.opentelemetry.io/otel/metric/embedded` package. (#3916)\n- The `Version` function to `go.opentelemetry.io/otel/sdk` to return the SDK version. (#3949)\n- Add a `WithNamespace` option to `go.opentelemetry.io/otel/exporters/prometheus` to allow users to prefix metrics with a namespace. (#3970)\n- The following configuration types were added to `go.opentelemetry.io/otel/metric/instrument` to be used in the configuration of measurement methods. (#3971)\n  - The `AddConfig` used to hold configuration for addition measurements\n    - `NewAddConfig` used to create a new `AddConfig`\n    - `AddOption` used to configure an `AddConfig`\n  - The `RecordConfig` used to hold configuration for recorded measurements\n    - `NewRecordConfig` used to create a new `RecordConfig`\n    - `RecordOption` used to configure a `RecordConfig`\n  - The `ObserveConfig` used to hold configuration for observed measurements\n    - `NewObserveConfig` used to create a new `ObserveConfig`\n    - `ObserveOption` used to configure an `ObserveConfig`\n- `WithAttributeSet` and `WithAttributes` are added to `go.opentelemetry.io/otel/metric/instrument`.\n  They return an option used during a measurement that defines the attribute Set associated with the measurement. (#3971)\n- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` to return the OTLP metrics client version. (#3956)\n- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlptrace` to return the OTLP trace client version. (#3956)\n\n### Changed\n\n- The `Extrema` in `go.opentelemetry.io/otel/sdk/metric/metricdata` is redefined with a generic argument of `[N int64 | float64]`. (#3870)\n- Update all exported interfaces from `go.opentelemetry.io/otel/metric` to embed their corresponding interface from `go.opentelemetry.io/otel/metric/embedded`.\n  This adds an implementation requirement to set the interface default behavior for unimplemented methods. (#3916)\n- Move No-Op implementation from `go.opentelemetry.io/otel/metric` into its own package `go.opentelemetry.io/otel/metric/noop`. (#3941)\n  - `metric.NewNoopMeterProvider` is replaced with `noop.NewMeterProvider`\n- Add all the methods from `\"go.opentelemetry.io/otel/trace\".SpanContext` to `bridgeSpanContext` by embedding `otel.SpanContext` in `bridgeSpanContext`. (#3966)\n- Wrap `UploadMetrics` error in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/` to improve error message when encountering generic grpc errors. (#3974)\n- The measurement methods for all instruments in `go.opentelemetry.io/otel/metric/instrument` accept an option instead of the variadic `\"go.opentelemetry.io/otel/attribute\".KeyValue`. (#3971)\n  - The `Int64Counter.Add` method now accepts `...AddOption`\n  - The `Float64Counter.Add` method now accepts `...AddOption`\n  - The `Int64UpDownCounter.Add` method now accepts `...AddOption`\n  - The `Float64UpDownCounter.Add` method now accepts `...AddOption`\n  - The `Int64Histogram.Record` method now accepts `...RecordOption`\n  - The `Float64Histogram.Record` method now accepts `...RecordOption`\n  - The `Int64Observer.Observe` method now accepts `...ObserveOption`\n  - The `Float64Observer.Observe` method now accepts `...ObserveOption`\n- The `Observer` methods in `go.opentelemetry.io/otel/metric` accept an option instead of the variadic `\"go.opentelemetry.io/otel/attribute\".KeyValue`. (#3971)\n  - The `Observer.ObserveInt64` method now accepts `...ObserveOption`\n  - The `Observer.ObserveFloat64` method now accepts `...ObserveOption`\n- Move global metric back to `go.opentelemetry.io/otel/metric/global` from `go.opentelemetry.io/otel`. (#3986)\n\n### Fixed\n\n- `TracerProvider` allows calling `Tracer()` while it's shutting down.\n  It used to deadlock. (#3924)\n- Use the SDK version for the Telemetry SDK resource detector in `go.opentelemetry.io/otel/sdk/resource`. (#3949)\n- Fix a data race in `SpanProcessor` returned by `NewSimpleSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#3951)\n- Automatically figure out the default aggregation with `aggregation.Default`. (#3967)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/metric/instrument` package is deprecated.\n  Use the equivalent types added to `go.opentelemetry.io/otel/metric` instead. (#4018)\n\n## [1.15.0-rc.2/0.38.0-rc.2] 2023-03-23\n\nThis is a release candidate for the v1.15.0/v0.38.0 release.\nThat release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\n### Added\n\n- The `WithHostID` option to `go.opentelemetry.io/otel/sdk/resource`. (#3812)\n- The `WithoutTimestamps` option to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to sets all timestamps to zero. (#3828)\n- The new `Exemplar` type is added to `go.opentelemetry.io/otel/sdk/metric/metricdata`.\n  Both the `DataPoint` and `HistogramDataPoint` types from that package have a new field of `Exemplars` containing the sampled exemplars for their timeseries. (#3849)\n- Configuration for each metric instrument in `go.opentelemetry.io/otel/sdk/metric/instrument`. (#3895)\n- The internal logging introduces a warning level verbosity equal to `V(1)`. (#3900)\n- Added a log message warning about usage of `SimpleSpanProcessor` in production environments. (#3854)\n\n### Changed\n\n- Optimize memory allocation when creation a new `Set` using `NewSet` or `NewSetWithFiltered` in `go.opentelemetry.io/otel/attribute`. (#3832)\n- Optimize memory allocation when creation new metric instruments in `go.opentelemetry.io/otel/sdk/metric`. (#3832)\n- Avoid creating new objects on all calls to `WithDeferredSetup` and `SkipContextSetup` in OpenTracing bridge. (#3833)\n- The `New` and `Detect` functions from `go.opentelemetry.io/otel/sdk/resource` return errors that wrap underlying errors instead of just containing the underlying error strings. (#3844)\n- Both the `Histogram` and `HistogramDataPoint` are redefined with a generic argument of `[N int64 | float64]` in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#3849)\n- The metric `Export` interface from `go.opentelemetry.io/otel/sdk/metric` accepts a `*ResourceMetrics` instead of `ResourceMetrics`. (#3853)\n- Rename `Asynchronous` to `Observable` in `go.opentelemetry.io/otel/metric/instrument`. (#3892)\n- Rename `Int64ObserverOption` to `Int64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)\n- Rename `Float64ObserverOption` to `Float64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895)\n- The internal logging changes the verbosity level of info to `V(4)`, the verbosity level of debug to `V(8)`. (#3900)\n\n### Fixed\n\n- `TracerProvider` consistently doesn't allow to register a `SpanProcessor` after shutdown. (#3845)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/global` package is removed. (#3829)\n- The unneeded `Synchronous` interface in `go.opentelemetry.io/otel/metric/instrument` was removed. (#3892)\n- The `Float64ObserverConfig` and `NewFloat64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`.\n  Use the added `float64` instrument configuration instead. (#3895)\n- The `Int64ObserverConfig` and `NewInt64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`.\n  Use the added `int64` instrument configuration instead. (#3895)\n- The `NewNoopMeter` function in `go.opentelemetry.io/otel/metric`, use `NewMeterProvider().Meter(\"\")` instead. (#3893)\n\n## [1.15.0-rc.1/0.38.0-rc.1] 2023-03-01\n\nThis is a release candidate for the v1.15.0/v0.38.0 release.\nThat release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API.\nSee our [versioning policy](VERSIONING.md) for more information about these stability guarantees.\n\nThis release drops the compatibility guarantee of [Go 1.18].\n\n### Added\n\n- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#3818)\n  - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`.\n  - Use `GetMeterProivder` for a global `metric.MeterProvider`.\n  - Use `SetMeterProivder` to set the global `metric.MeterProvider`.\n\n### Changed\n\n- Dropped compatibility testing for [Go 1.18].\n  The project no longer guarantees support for this version of Go. (#3813)\n\n### Fixed\n\n- Handle empty environment variable as it they were not set. (#3764)\n- Clarify the `httpconv` and `netconv` packages in `go.opentelemetry.io/otel/semconv/*` provide tracing semantic conventions. (#3823)\n- Fix race conditions in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic. (#3899)\n- Fix sending nil `scopeInfo` to metrics channel in `go.opentelemetry.io/otel/exporters/metric/prometheus` that could cause a panic in `github.com/prometheus/client_golang/prometheus`. (#3899)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/metric/global` package is deprecated.\n  Use `go.opentelemetry.io/otel` instead. (#3818)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/unit` package is removed. (#3814)\n\n## [1.14.0/0.37.0/0.0.4] 2023-02-27\n\nThis release is the last to support [Go 1.18].\nThe next release will require at least [Go 1.19].\n\n### Added\n\n- The `event` type semantic conventions are added to `go.opentelemetry.io/otel/semconv/v1.17.0`. (#3697)\n- Support [Go 1.20]. (#3693)\n- The `go.opentelemetry.io/otel/semconv/v1.18.0` package.\n  The package contains semantic conventions from the `v1.18.0` version of the OpenTelemetry specification. (#3719)\n  - The following `const` renames from `go.opentelemetry.io/otel/semconv/v1.17.0` are included:\n    - `OtelScopeNameKey` -> `OTelScopeNameKey`\n    - `OtelScopeVersionKey` -> `OTelScopeVersionKey`\n    - `OtelLibraryNameKey` -> `OTelLibraryNameKey`\n    - `OtelLibraryVersionKey` -> `OTelLibraryVersionKey`\n    - `OtelStatusCodeKey` -> `OTelStatusCodeKey`\n    - `OtelStatusDescriptionKey` -> `OTelStatusDescriptionKey`\n    - `OtelStatusCodeOk` -> `OTelStatusCodeOk`\n    - `OtelStatusCodeError` -> `OTelStatusCodeError`\n  - The following `func` renames from `go.opentelemetry.io/otel/semconv/v1.17.0` are included:\n    - `OtelScopeName` -> `OTelScopeName`\n    - `OtelScopeVersion` -> `OTelScopeVersion`\n    - `OtelLibraryName` -> `OTelLibraryName`\n    - `OtelLibraryVersion` -> `OTelLibraryVersion`\n    - `OtelStatusDescription` -> `OTelStatusDescription`\n- A `IsSampled` method is added to the `SpanContext` implementation in `go.opentelemetry.io/otel/bridge/opentracing` to expose the span sampled state.\n  See the [README](./bridge/opentracing/README.md) for more information. (#3570)\n- The `WithInstrumentationAttributes` option to `go.opentelemetry.io/otel/metric`. (#3738)\n- The `WithInstrumentationAttributes` option to `go.opentelemetry.io/otel/trace`. (#3739)\n- The following environment variables are supported by the periodic `Reader` in `go.opentelemetry.io/otel/sdk/metric`. (#3763)\n  - `OTEL_METRIC_EXPORT_INTERVAL` sets the time between collections and exports.\n  - `OTEL_METRIC_EXPORT_TIMEOUT` sets the timeout an export is attempted.\n\n### Changed\n\n- Fall-back to `TextMapCarrier` when it's not `HttpHeader`s in `go.opentelemetry.io/otel/bridge/opentracing`. (#3679)\n- The `Collect` method of the `\"go.opentelemetry.io/otel/sdk/metric\".Reader` interface is updated to accept the `metricdata.ResourceMetrics` value the collection will be made into.\n  This change is made to enable memory reuse by SDK users. (#3732)\n- The `WithUnit` option in `go.opentelemetry.io/otel/sdk/metric/instrument` is updated to accept a `string` for the unit value. (#3776)\n\n### Fixed\n\n- Ensure `go.opentelemetry.io/otel` does not use generics. (#3723, #3725)\n- Multi-reader `MeterProvider`s now export metrics for all readers, instead of just the first reader. (#3720, #3724)\n- Remove use of deprecated `\"math/rand\".Seed` in `go.opentelemetry.io/otel/example/prometheus`. (#3733)\n- Do not silently drop unknown schema data with `Parse` in  `go.opentelemetry.io/otel/schema/v1.1`. (#3743)\n- Data race issue in OTLP exporter retry mechanism. (#3755, #3756)\n- Wrapping empty errors when exporting in `go.opentelemetry.io/otel/sdk/metric`. (#3698, #3772)\n- Incorrect \"all\" and \"resource\" definition for schema files in `go.opentelemetry.io/otel/schema/v1.1`. (#3777)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/metric/unit` package is deprecated.\n  Use the equivalent unit string instead. (#3776)\n  - Use `\"1\"` instead of `unit.Dimensionless`\n  - Use `\"By\"` instead of `unit.Bytes`\n  - Use `\"ms\"` instead of `unit.Milliseconds`\n\n## [1.13.0/0.36.0] 2023-02-07\n\n### Added\n\n- Attribute `KeyValue` creations functions to `go.opentelemetry.io/otel/semconv/v1.17.0` for all non-enum semantic conventions.\n  These functions ensure semantic convention type correctness. (#3675)\n\n### Fixed\n\n- Removed the `http.target` attribute from being added by `ServerRequest` in the following packages. (#3687)\n  - `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.14.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.15.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.16.0/httpconv`\n  - `go.opentelemetry.io/otel/semconv/v1.17.0/httpconv`\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/asyncfloat64` package is removed. (#3631)\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/asyncint64` package is removed. (#3631)\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/syncfloat64` package is removed. (#3631)\n- The deprecated `go.opentelemetry.io/otel/metric/instrument/syncint64` package is removed. (#3631)\n\n## [1.12.0/0.35.0] 2023-01-28\n\n### Added\n\n- The `WithInt64Callback` option to `go.opentelemetry.io/otel/metric/instrument`.\n  This options is used to configure `int64` Observer callbacks during their creation. (#3507)\n- The `WithFloat64Callback` option to `go.opentelemetry.io/otel/metric/instrument`.\n  This options is used to configure `float64` Observer callbacks during their creation. (#3507)\n- The `Producer` interface and `Reader.RegisterProducer(Producer)` to `go.opentelemetry.io/otel/sdk/metric`.\n  These additions are used to enable external metric Producers. (#3524)\n- The `Callback` function type to `go.opentelemetry.io/otel/metric`.\n  This new named function type is registered with a `Meter`. (#3564)\n- The `go.opentelemetry.io/otel/semconv/v1.13.0` package.\n  The package contains semantic conventions from the `v1.13.0` version of the OpenTelemetry specification. (#3499)\n  - The `EndUserAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientRequest` and `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPAttributesFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is merged into `ClientResponse` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPClientAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPServerAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `HTTPServerMetricAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `NetAttributesFromHTTPRequest` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `Transport` in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` and `ClientRequest` or `ServerRequest` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `SpanStatusFromHTTPStatusCode` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is replaced by `ClientStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `SpanStatusFromHTTPStatusCodeAndSpanKind` function in `go.opentelemetry.io/otel/semconv/v1.12.0` is split into `ClientStatus` and `ServerStatus` in `go.opentelemetry.io/otel/semconv/v1.13.0/httpconv`.\n  - The `Client` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Conn`.\n  - The `Server` function is included in `go.opentelemetry.io/otel/semconv/v1.13.0/netconv` to generate attributes for a `net.Listener`.\n- The `go.opentelemetry.io/otel/semconv/v1.14.0` package.\n  The package contains semantic conventions from the `v1.14.0` version of the OpenTelemetry specification. (#3566)\n- The `go.opentelemetry.io/otel/semconv/v1.15.0` package.\n  The package contains semantic conventions from the `v1.15.0` version of the OpenTelemetry specification. (#3578)\n- The `go.opentelemetry.io/otel/semconv/v1.16.0` package.\n  The package contains semantic conventions from the `v1.16.0` version of the OpenTelemetry specification. (#3579)\n- Metric instruments to `go.opentelemetry.io/otel/metric/instrument`.\n  These instruments are use as replacements of the deprecated `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586)\n  - `Float64ObservableCounter` replaces the `asyncfloat64.Counter`\n  - `Float64ObservableUpDownCounter` replaces the `asyncfloat64.UpDownCounter`\n  - `Float64ObservableGauge` replaces the `asyncfloat64.Gauge`\n  - `Int64ObservableCounter` replaces the `asyncint64.Counter`\n  - `Int64ObservableUpDownCounter` replaces the `asyncint64.UpDownCounter`\n  - `Int64ObservableGauge` replaces the `asyncint64.Gauge`\n  - `Float64Counter` replaces the `syncfloat64.Counter`\n  - `Float64UpDownCounter` replaces the `syncfloat64.UpDownCounter`\n  - `Float64Histogram` replaces the `syncfloat64.Histogram`\n  - `Int64Counter` replaces the `syncint64.Counter`\n  - `Int64UpDownCounter` replaces the `syncint64.UpDownCounter`\n  - `Int64Histogram` replaces the `syncint64.Histogram`\n- `NewTracerProvider` to `go.opentelemetry.io/otel/bridge/opentracing`.\n  This is used to create `WrapperTracer` instances from a `TracerProvider`. (#3116)\n- The `Extrema` type to `go.opentelemetry.io/otel/sdk/metric/metricdata`.\n  This type is used to represent min/max values and still be able to distinguish unset and zero values. (#3487)\n- The `go.opentelemetry.io/otel/semconv/v1.17.0` package.\n  The package contains semantic conventions from the `v1.17.0` version of the OpenTelemetry specification. (#3599)\n\n### Changed\n\n- Jaeger and Zipkin exporter use `github.com/go-logr/logr` as the logging interface, and add the `WithLogr` option. (#3497, #3500)\n- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and configuration based on the instrument type. (#3507)\n  - Use the added `Int64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncint64`.\n  - Use the added `Float64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncfloat64`.\n  - Use the added `Int64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncint64`.\n  - Use the added `Float64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncfloat64`.\n- Return a `Registration` from the `RegisterCallback` method of a `Meter` in the `go.opentelemetry.io/otel/metric` package.\n  This `Registration` can be used to unregister callbacks. (#3522)\n- Global error handler uses an atomic value instead of a mutex. (#3543)\n- Add `NewMetricProducer` to `go.opentelemetry.io/otel/bridge/opencensus`, which can be used to pass OpenCensus metrics to an OpenTelemetry Reader. (#3541)\n- Global logger uses an atomic value instead of a mutex. (#3545)\n- The `Shutdown` method of the `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` releases all computational resources when called the first time. (#3551)\n- The `Sampler` returned from `TraceIDRatioBased` `go.opentelemetry.io/otel/sdk/trace` now uses the rightmost bits for sampling decisions.\n  This fixes random sampling when using ID generators like `xray.IDGenerator` and increasing parity with other language implementations. (#3557)\n- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in errors identifying their signal name.\n  Existing users of the exporters attempting to identify specific errors will need to use `errors.Unwrap()` to get the underlying error. (#3516)\n- Exporters from `go.opentelemetry.io/otel/exporters/otlp` will print the final retryable error message when attempts to retry time out. (#3514)\n- The instrument kind names in `go.opentelemetry.io/otel/sdk/metric` are updated to match the API. (#3562)\n  - `InstrumentKindSyncCounter` is renamed to `InstrumentKindCounter`\n  - `InstrumentKindSyncUpDownCounter` is renamed to `InstrumentKindUpDownCounter`\n  - `InstrumentKindSyncHistogram` is renamed to `InstrumentKindHistogram`\n  - `InstrumentKindAsyncCounter` is renamed to `InstrumentKindObservableCounter`\n  - `InstrumentKindAsyncUpDownCounter` is renamed to `InstrumentKindObservableUpDownCounter`\n  - `InstrumentKindAsyncGauge` is renamed to `InstrumentKindObservableGauge`\n- The `RegisterCallback` method of the `Meter` in `go.opentelemetry.io/otel/metric` changed.\n  - The named `Callback` replaces the inline function parameter. (#3564)\n  - `Callback` is required to return an error. (#3576)\n  - `Callback` accepts the added `Observer` parameter added.\n    This new parameter is used by `Callback` implementations to observe values for asynchronous instruments instead of calling the `Observe` method of the instrument directly. (#3584)\n  - The slice of `instrument.Asynchronous` is now passed as a variadic argument. (#3587)\n- The exporter from `go.opentelemetry.io/otel/exporters/zipkin` is updated to use the `v1.16.0` version of semantic conventions.\n  This means it no longer uses the removed `net.peer.ip` or `http.host` attributes to determine the remote endpoint.\n  Instead it uses the `net.sock.peer` attributes. (#3581)\n- The `Min` and `Max` fields of the `HistogramDataPoint` in `go.opentelemetry.io/otel/sdk/metric/metricdata` are now defined with the added `Extrema` type instead of a `*float64`. (#3487)\n\n### Fixed\n\n- Asynchronous instruments that use sum aggregators and attribute filters correctly add values from equivalent attribute sets that have been filtered. (#3439, #3549)\n- The `RegisterCallback` method of the `Meter` from `go.opentelemetry.io/otel/sdk/metric` only registers a callback for instruments created by that meter.\n  Trying to register a callback with instruments from a different meter will result in an error being returned. (#3584)\n\n### Deprecated\n\n- The `NewMetricExporter` in `go.opentelemetry.io/otel/bridge/opencensus` is deprecated.\n  Use `NewMetricProducer` instead. (#3541)\n- The `go.opentelemetry.io/otel/metric/instrument/asyncfloat64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `go.opentelemetry.io/otel/metric/instrument/asyncint64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `go.opentelemetry.io/otel/metric/instrument/syncfloat64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `go.opentelemetry.io/otel/metric/instrument/syncint64` package is deprecated.\n  Use the instruments from `go.opentelemetry.io/otel/metric/instrument` instead. (#3575)\n- The `NewWrappedTracerProvider` in `go.opentelemetry.io/otel/bridge/opentracing` is now deprecated.\n  Use `NewTracerProvider` instead. (#3116)\n\n### Removed\n\n- The deprecated `go.opentelemetry.io/otel/sdk/metric/view` package is removed. (#3520)\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncint64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Int64ObservableCounter`\n  - The `UpDownCounter` method is replaced by `Meter.Int64ObservableUpDownCounter`\n  - The `Gauge` method is replaced by `Meter.Int64ObservableGauge`\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/asyncfloat64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Float64ObservableCounter`\n  - The `UpDownCounter` method is replaced by `Meter.Float64ObservableUpDownCounter`\n  - The `Gauge` method is replaced by `Meter.Float64ObservableGauge`\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncint64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Int64Counter`\n  - The `UpDownCounter` method is replaced by `Meter.Int64UpDownCounter`\n  - The `Histogram` method is replaced by `Meter.Int64Histogram`\n- The `InstrumentProvider` from `go.opentelemetry.io/otel/sdk/metric/syncfloat64` is removed.\n  Use the new creation methods of the `Meter` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3530)\n  - The `Counter` method is replaced by `Meter.Float64Counter`\n  - The `UpDownCounter` method is replaced by `Meter.Float64UpDownCounter`\n  - The `Histogram` method is replaced by `Meter.Float64Histogram`\n\n## [1.11.2/0.34.0] 2022-12-05\n\n### Added\n\n- The `WithView` `Option` is added to the `go.opentelemetry.io/otel/sdk/metric` package.\n   This option is used to configure the view(s) a `MeterProvider` will use for all `Reader`s that are registered with it. (#3387)\n- Add Instrumentation Scope and Version as info metric and label in Prometheus exporter.\n  This can be disabled using the `WithoutScopeInfo()` option added to that package.(#3273, #3357)\n- OTLP exporters now recognize: (#3363)\n  - `OTEL_EXPORTER_OTLP_INSECURE`\n  - `OTEL_EXPORTER_OTLP_TRACES_INSECURE`\n  - `OTEL_EXPORTER_OTLP_METRICS_INSECURE`\n  - `OTEL_EXPORTER_OTLP_CLIENT_KEY`\n  - `OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY`\n  - `OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY`\n  - `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE`\n- The `View` type and related `NewView` function to create a view according to the OpenTelemetry specification are added to `go.opentelemetry.io/otel/sdk/metric`.\n  These additions are replacements for the `View` type and `New` function from `go.opentelemetry.io/otel/sdk/metric/view`. (#3459)\n- The `Instrument` and `InstrumentKind` type are added to `go.opentelemetry.io/otel/sdk/metric`.\n  These additions are replacements for the `Instrument` and `InstrumentKind` types from `go.opentelemetry.io/otel/sdk/metric/view`. (#3459)\n- The `Stream` type is added to `go.opentelemetry.io/otel/sdk/metric` to define a metric data stream a view will produce. (#3459)\n- The `AssertHasAttributes` allows instrument authors to test that datapoints returned have appropriate attributes. (#3487)\n\n### Changed\n\n- The `\"go.opentelemetry.io/otel/sdk/metric\".WithReader` option no longer accepts views to associate with the `Reader`.\n   Instead, views are now registered directly with the `MeterProvider` via the new `WithView` option.\n   The views registered with the `MeterProvider` apply to all `Reader`s. (#3387)\n- The `Temporality(view.InstrumentKind) metricdata.Temporality` and `Aggregation(view.InstrumentKind) aggregation.Aggregation` methods are added to the `\"go.opentelemetry.io/otel/sdk/metric\".Exporter` interface. (#3260)\n- The `Temporality(view.InstrumentKind) metricdata.Temporality` and `Aggregation(view.InstrumentKind) aggregation.Aggregation` methods are added to the `\"go.opentelemetry.io/otel/exporters/otlp/otlpmetric\".Client` interface. (#3260)\n- The `WithTemporalitySelector` and `WithAggregationSelector` `ReaderOption`s have been changed to `ManualReaderOption`s in the `go.opentelemetry.io/otel/sdk/metric` package. (#3260)\n- The periodic reader in the `go.opentelemetry.io/otel/sdk/metric` package now uses the temporality and aggregation selectors from its configured exporter instead of accepting them as options. (#3260)\n\n### Fixed\n\n- The `go.opentelemetry.io/otel/exporters/prometheus` exporter fixes duplicated `_total` suffixes. (#3369)\n- Remove comparable requirement for `Reader`s. (#3387)\n- Cumulative metrics from the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) are defined as monotonic sums, instead of non-monotonic. (#3389)\n- Asynchronous counters (`Counter` and `UpDownCounter`) from the metric SDK now produce delta sums when configured with delta temporality. (#3398)\n- Exported `Status` codes in the `go.opentelemetry.io/otel/exporters/zipkin` exporter are now exported as all upper case values. (#3340)\n- `Aggregation`s from `go.opentelemetry.io/otel/sdk/metric` with no data are not exported. (#3394, #3436)\n- Re-enabled Attribute Filters in the Metric SDK. (#3396)\n- Asynchronous callbacks are only called if they are registered with at least one instrument that does not use drop aggragation. (#3408)\n- Do not report empty partial-success responses in the `go.opentelemetry.io/otel/exporters/otlp` exporters. (#3438, #3432)\n- Handle partial success responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` exporters. (#3162, #3440)\n- Prevent duplicate Prometheus description, unit, and type. (#3469)\n- Prevents panic when using incorrect `attribute.Value.As[Type]Slice()`. (#3489)\n\n### Removed\n\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.Client` interface is removed. (#3486)\n- The `go.opentelemetry.io/otel/exporters/otlp/otlpmetric.New` function is removed. Use the `otlpmetric[http|grpc].New` directly. (#3486)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/sdk/metric/view` package is deprecated.\n  Use `Instrument`, `InstrumentKind`, `View`, and `NewView` in `go.opentelemetry.io/otel/sdk/metric` instead. (#3476)\n\n## [1.11.1/0.33.0] 2022-10-19\n\n### Added\n\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` registers with a Prometheus registerer on creation.\n   By default, it will register with the default Prometheus registerer.\n   A non-default registerer can be used by passing the `WithRegisterer` option. (#3239)\n- Added the `WithAggregationSelector` option to the `go.opentelemetry.io/otel/exporters/prometheus` package to change the default `AggregationSelector` used. (#3341)\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` converts the `Resource` associated with metric exports into a `target_info` metric. (#3285)\n\n### Changed\n\n- The `\"go.opentelemetry.io/otel/exporters/prometheus\".New` function is updated to return an error.\n   It will return an error if the exporter fails to register with Prometheus. (#3239)\n\n### Fixed\n\n- The URL-encoded values from the `OTEL_RESOURCE_ATTRIBUTES` environment variable are decoded. (#2963)\n- The `baggage.NewMember` function decodes the `value` parameter instead of directly using it.\n   This fixes the implementation to be compliant with the W3C specification. (#3226)\n- Slice attributes of the `attribute` package are now comparable based on their value, not instance. (#3108 #3252)\n- The `Shutdown` and `ForceFlush` methods of the `\"go.opentelemetry.io/otel/sdk/trace\".TraceProvider` no longer return an error when no processor is registered. (#3268)\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` cumulatively sums histogram buckets. (#3281)\n- The sum of each histogram data point is now uniquely exported by the `go.opentelemetry.io/otel/exporters/otlpmetric` exporters. (#3284, #3293)\n- Recorded values for asynchronous counters (`Counter` and `UpDownCounter`) are interpreted as exact, not incremental, sum values by the metric SDK. (#3350, #3278)\n- `UpDownCounters` are now correctly output as Prometheus gauges in the `go.opentelemetry.io/otel/exporters/prometheus` exporter. (#3358)\n- The Prometheus exporter in `go.opentelemetry.io/otel/exporters/prometheus` no longer describes the metrics it will send to Prometheus on startup.\n   Instead the exporter is defined as an \"unchecked\" collector for Prometheus.\n   This fixes the `reader is not registered` warning currently emitted on startup. (#3291 #3342)\n- The `go.opentelemetry.io/otel/exporters/prometheus` exporter now correctly adds `_total` suffixes to counter metrics. (#3360)\n- The `go.opentelemetry.io/otel/exporters/prometheus` exporter now adds a unit suffix to metric names.\n   This can be disabled using the `WithoutUnits()` option added to that package. (#3352)\n\n## [1.11.0/0.32.3] 2022-10-12\n\n### Added\n\n- Add default User-Agent header to OTLP exporter requests (`go.opentelemetry.io/otel/exporters/otlptrace/otlptracegrpc` and `go.opentelemetry.io/otel/exporters/otlptrace/otlptracehttp`). (#3261)\n\n### Changed\n\n- `span.SetStatus` has been updated such that calls that lower the status are now no-ops. (#3214)\n- Upgrade `golang.org/x/sys/unix` from `v0.0.0-20210423185535-09eb48e85fd7` to `v0.0.0-20220919091848-fb04ddd9f9c8`.\n  This addresses [GO-2022-0493](https://pkg.go.dev/vuln/GO-2022-0493). (#3235)\n\n## [0.32.2] Metric SDK (Alpha) - 2022-10-11\n\n### Added\n\n- Added an example of using metric views to customize instruments. (#3177)\n- Add default User-Agent header to OTLP exporter requests (`go.opentelemetry.io/otel/exporters/otlpmetric/otlpmetricgrpc` and `go.opentelemetry.io/otel/exporters/otlpmetric/otlpmetrichttp`). (#3261)\n\n### Changed\n\n- Flush pending measurements with the `PeriodicReader` in the `go.opentelemetry.io/otel/sdk/metric` when `ForceFlush` or `Shutdown` are called. (#3220)\n- Update histogram default bounds to match the requirements of the latest specification. (#3222)\n- Encode the HTTP status code in the OpenTracing bridge (`go.opentelemetry.io/otel/bridge/opentracing`) as an integer.  (#3265)\n\n### Fixed\n\n- Use default view if instrument does not match any registered view of a reader. (#3224, #3237)\n- Return the same instrument every time a user makes the exact same instrument creation call. (#3229, #3251)\n- Return the existing instrument when a view transforms a creation call to match an existing instrument. (#3240, #3251)\n- Log a warning when a conflicting instrument (e.g. description, unit, data-type) is created instead of returning an error. (#3251)\n- The OpenCensus bridge no longer sends empty batches of metrics. (#3263)\n\n## [0.32.1] Metric SDK (Alpha) - 2022-09-22\n\n### Changed\n\n- The Prometheus exporter sanitizes OpenTelemetry instrument names when exporting.\n   Invalid characters are replaced with `_`. (#3212)\n\n### Added\n\n- The metric portion of the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) has been reintroduced. (#3192)\n- The OpenCensus bridge example (`go.opentelemetry.io/otel/example/opencensus`) has been reintroduced. (#3206)\n\n### Fixed\n\n- Updated go.mods to point to valid versions of the sdk. (#3216)\n- Set the `MeterProvider` resource on all exported metric data. (#3218)\n\n## [0.32.0] Revised Metric SDK (Alpha) - 2022-09-18\n\n### Changed\n\n- The metric SDK in `go.opentelemetry.io/otel/sdk/metric` is completely refactored to comply with the OpenTelemetry specification.\n  Please see the package documentation for how the new SDK is initialized and configured. (#3175)\n- Update the minimum supported go version to go1.18. Removes support for go1.17 (#3179)\n\n### Removed\n\n- The metric portion of the OpenCensus bridge (`go.opentelemetry.io/otel/bridge/opencensus`) has been removed.\n  A new bridge compliant with the revised metric SDK will be added back in a future release. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/histogram` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator/sum` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/aggregator` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/controller/basic` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/controller/controllertest` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/controller/time` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/export/aggregation` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/export` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/metrictest` package is removed.\n  A replacement package that supports the new metric SDK will be added back in a future release. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/number` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/processor/basic` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/processor/processortest` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/processor/reducer` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/registry` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/sdkapi` package is removed, see the new metric SDK. (#3175)\n- The `go.opentelemetry.io/otel/sdk/metric/selector/simple` package is removed, see the new metric SDK. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".ErrUninitializedInstrument` variable was removed. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".ErrBadInstrument` variable was removed. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".Accumulator` type was removed, see the `MeterProvider`in the new metric SDK. (#3175)\n- The `\"go.opentelemetry.io/otel/sdk/metric\".NewAccumulator` function was removed, see `NewMeterProvider`in the new metric SDK. (#3175)\n- The deprecated `\"go.opentelemetry.io/otel/sdk/metric\".AtomicFieldOffsets` function was removed. (#3175)\n\n## [1.10.0] - 2022-09-09\n\n### Added\n\n- Support Go 1.19. (#3077)\n  Include compatibility testing and document support. (#3077)\n- Support the OTLP ExportTracePartialSuccess response; these are passed to the registered error handler. (#3106)\n- Upgrade go.opentelemetry.io/proto/otlp from v0.18.0 to v0.19.0 (#3107)\n\n### Changed\n\n- Fix misidentification of OpenTelemetry `SpanKind` in OpenTracing bridge (`go.opentelemetry.io/otel/bridge/opentracing`).  (#3096)\n- Attempting to start a span with a nil `context` will no longer cause a panic. (#3110)\n- All exporters will be shutdown even if one reports an error (#3091)\n- Ensure valid UTF-8 when truncating over-length attribute values. (#3156)\n\n## [1.9.0/0.0.3] - 2022-08-01\n\n### Added\n\n- Add support for Schema Files format 1.1.x (metric \"split\" transform) with the new `go.opentelemetry.io/otel/schema/v1.1` package. (#2999)\n- Add the `go.opentelemetry.io/otel/semconv/v1.11.0` package.\n  The package contains semantic conventions from the `v1.11.0` version of the OpenTelemetry specification. (#3009)\n- Add the `go.opentelemetry.io/otel/semconv/v1.12.0` package.\n  The package contains semantic conventions from the `v1.12.0` version of the OpenTelemetry specification. (#3010)\n- Add the `http.method` attribute to HTTP server metric from all `go.opentelemetry.io/otel/semconv/*` packages. (#3018)\n\n### Fixed\n\n- Invalid warning for context setup being deferred in `go.opentelemetry.io/otel/bridge/opentracing` package. (#3029)\n\n## [1.8.0/0.31.0] - 2022-07-08\n\n### Added\n\n- Add support for `opentracing.TextMap` format in the `Inject` and `Extract` methods\nof the `\"go.opentelemetry.io/otel/bridge/opentracing\".BridgeTracer` type. (#2911)\n\n### Changed\n\n- The `crosslink` make target has been updated to use the `go.opentelemetry.io/build-tools/crosslink` package. (#2886)\n- In the `go.opentelemetry.io/otel/sdk/instrumentation` package rename `Library` to `Scope` and alias `Library` as `Scope` (#2976)\n- Move metric no-op implementation form `nonrecording` to `metric` package. (#2866)\n\n### Removed\n\n- Support for go1.16. Support is now only for go1.17 and go1.18 (#2917)\n\n### Deprecated\n\n- The `Library` struct in the `go.opentelemetry.io/otel/sdk/instrumentation` package is deprecated.\n  Use the equivalent `Scope` struct instead. (#2977)\n- The `ReadOnlySpan.InstrumentationLibrary` method from the `go.opentelemetry.io/otel/sdk/trace` package is deprecated.\n  Use the equivalent `ReadOnlySpan.InstrumentationScope` method instead. (#2977)\n\n## [1.7.0/0.30.0] - 2022-04-28\n\n### Added\n\n- Add the `go.opentelemetry.io/otel/semconv/v1.8.0` package.\n  The package contains semantic conventions from the `v1.8.0` version of the OpenTelemetry specification. (#2763)\n- Add the `go.opentelemetry.io/otel/semconv/v1.9.0` package.\n  The package contains semantic conventions from the `v1.9.0` version of the OpenTelemetry specification. (#2792)\n- Add the `go.opentelemetry.io/otel/semconv/v1.10.0` package.\n  The package contains semantic conventions from the `v1.10.0` version of the OpenTelemetry specification. (#2842)\n- Added an in-memory exporter to metrictest to aid testing with a full SDK. (#2776)\n\n### Fixed\n\n- Globally delegated instruments are unwrapped before delegating asynchronous callbacks. (#2784)\n- Remove import of `testing` package in non-tests builds of the `go.opentelemetry.io/otel` package. (#2786)\n\n### Changed\n\n- The `WithLabelEncoder` option from the `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` package is renamed to `WithAttributeEncoder`. (#2790)\n- The `LabelFilterSelector` interface from `go.opentelemetry.io/otel/sdk/metric/processor/reducer` is renamed to `AttributeFilterSelector`.\n  The method included in the renamed interface also changed from `LabelFilterFor` to `AttributeFilterFor`. (#2790)\n- The `Metadata.Labels` method from the `go.opentelemetry.io/otel/sdk/metric/export` package is renamed to `Metadata.Attributes`.\n  Consequentially, the `Record` type from the same package also has had the embedded method renamed. (#2790)\n\n### Deprecated\n\n- The `Iterator.Label` method in the `go.opentelemetry.io/otel/attribute` package is deprecated.\n  Use the equivalent `Iterator.Attribute` method instead. (#2790)\n- The `Iterator.IndexedLabel` method in the `go.opentelemetry.io/otel/attribute` package is deprecated.\n  Use the equivalent `Iterator.IndexedAttribute` method instead. (#2790)\n- The `MergeIterator.Label` method in the `go.opentelemetry.io/otel/attribute` package is deprecated.\n  Use the equivalent `MergeIterator.Attribute` method instead. (#2790)\n\n### Removed\n\n- Removed the `Batch` type from the `go.opentelemetry.io/otel/sdk/metric/metrictest` package. (#2864)\n- Removed the `Measurement` type from the `go.opentelemetry.io/otel/sdk/metric/metrictest` package. (#2864)\n\n## [0.29.0] - 2022-04-11\n\n### Added\n\n- The metrics global package was added back into several test files. (#2764)\n- The `Meter` function is added back to the `go.opentelemetry.io/otel/metric/global` package.\n  This function is a convenience function equivalent to calling `global.MeterProvider().Meter(...)`. (#2750)\n\n### Removed\n\n- Removed module the `go.opentelemetry.io/otel/sdk/export/metric`.\n  Use the `go.opentelemetry.io/otel/sdk/metric` module instead. (#2720)\n\n### Changed\n\n- Don't panic anymore when setting a global MeterProvider to itself. (#2749)\n- Upgrade `go.opentelemetry.io/proto/otlp` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` from `v0.12.1` to `v0.15.0`.\n  This replaces the use of the now deprecated `InstrumentationLibrary` and `InstrumentationLibraryMetrics` types and fields in the proto library with the equivalent `InstrumentationScope` and `ScopeMetrics`. (#2748)\n\n## [1.6.3] - 2022-04-07\n\n### Fixed\n\n- Allow non-comparable global `MeterProvider`, `TracerProvider`, and `TextMapPropagator` types to be set. (#2772, #2773)\n\n## [1.6.2] - 2022-04-06\n\n### Changed\n\n- Don't panic anymore when setting a global TracerProvider or TextMapPropagator to itself. (#2749)\n- Upgrade `go.opentelemetry.io/proto/otlp` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace` from `v0.12.1` to `v0.15.0`.\n  This replaces the use of the now deprecated `InstrumentationLibrary` and `InstrumentationLibrarySpans` types and fields in the proto library with the equivalent `InstrumentationScope` and `ScopeSpans`. (#2748)\n\n## [1.6.1] - 2022-03-28\n\n### Fixed\n\n- The `go.opentelemetry.io/otel/schema/*` packages now use the correct schema URL for their `SchemaURL` constant.\n  Instead of using `\"https://opentelemetry.io/schemas/v<version>\"` they now use the correct URL without a `v` prefix, `\"https://opentelemetry.io/schemas/<version>\"`. (#2743, #2744)\n\n### Security\n\n- Upgrade `go.opentelemetry.io/proto/otlp` from `v0.12.0` to `v0.12.1`.\n  This includes an indirect upgrade of `github.com/grpc-ecosystem/grpc-gateway` which resolves [a vulnerability](https://nvd.nist.gov/vuln/detail/CVE-2019-11254) from `gopkg.in/yaml.v2` in version `v2.2.3`. (#2724, #2728)\n\n## [1.6.0/0.28.0] - 2022-03-23\n\n### ⚠️ Notice ⚠️\n\nThis update is a breaking change of the unstable Metrics API.\nCode instrumented with the `go.opentelemetry.io/otel/metric` will need to be modified.\n\n### Added\n\n- Add metrics exponential histogram support.\n  New mapping functions have been made available in `sdk/metric/aggregator/exponential/mapping` for other OpenTelemetry projects to take dependencies on. (#2502)\n- Add Go 1.18 to our compatibility tests. (#2679)\n- Allow configuring the Sampler with the `OTEL_TRACES_SAMPLER` and `OTEL_TRACES_SAMPLER_ARG` environment variables. (#2305, #2517)\n- Add the `metric/global` for obtaining and setting the global `MeterProvider`. (#2660)\n\n### Changed\n\n- The metrics API has been significantly changed to match the revised OpenTelemetry specification.\n  High-level changes include:\n\n  - Synchronous and asynchronous instruments are now handled by independent `InstrumentProvider`s.\n    These `InstrumentProvider`s are managed with a `Meter`.\n  - Synchronous and asynchronous instruments are grouped into their own packages based on value types.\n  - Asynchronous callbacks can now be registered with a `Meter`.\n\n  Be sure to check out the metric module documentation for more information on how to use the revised API. (#2587, #2660)\n\n### Fixed\n\n- Fallback to general attribute limits when span specific ones are not set in the environment. (#2675, #2677)\n\n## [1.5.0] - 2022-03-16\n\n### Added\n\n- Log the Exporters configuration in the TracerProviders message. (#2578)\n- Added support to configure the span limits with environment variables.\n  The following environment variables are supported. (#2606, #2637)\n  - `OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT`\n  - `OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT`\n  - `OTEL_SPAN_EVENT_COUNT_LIMIT`\n  - `OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT`\n  - `OTEL_SPAN_LINK_COUNT_LIMIT`\n  - `OTEL_LINK_ATTRIBUTE_COUNT_LIMIT`\n\n  If the provided environment variables are invalid (negative), the default values would be used.\n- Rename the `gc` runtime name to `go` (#2560)\n- Add resource container ID detection. (#2418)\n- Add span attribute value length limit.\n  The new `AttributeValueLengthLimit` field is added to the `\"go.opentelemetry.io/otel/sdk/trace\".SpanLimits` type to configure this limit for a `TracerProvider`.\n  The default limit for this resource is \"unlimited\". (#2637)\n- Add the `WithRawSpanLimits` option to `go.opentelemetry.io/otel/sdk/trace`.\n  This option replaces the `WithSpanLimits` option.\n  Zero or negative values will not be changed to the default value like `WithSpanLimits` does.\n  Setting a limit to zero will effectively disable the related resource it limits and setting to a negative value will mean that resource is unlimited.\n  Consequentially, limits should be constructed using `NewSpanLimits` and updated accordingly. (#2637)\n\n### Changed\n\n- Drop oldest tracestate `Member` when capacity is reached. (#2592)\n- Add event and link drop counts to the exported data from the `oltptrace` exporter. (#2601)\n- Unify path cleaning functionally in the `otlpmetric` and `otlptrace` configuration. (#2639)\n- Change the debug message from the `sdk/trace.BatchSpanProcessor` to reflect the count is cumulative. (#2640)\n- Introduce new internal `envconfig` package for OTLP exporters. (#2608)\n- If `http.Request.Host` is empty, fall back to use `URL.Host` when populating `http.host` in the `semconv` packages. (#2661)\n\n### Fixed\n\n- Remove the OTLP trace exporter limit of SpanEvents when exporting. (#2616)\n- Default to port `4318` instead of `4317` for the `otlpmetrichttp` and `otlptracehttp` client. (#2614, #2625)\n- Unlimited span limits are now supported (negative values). (#2636, #2637)\n\n### Deprecated\n\n- Deprecated `\"go.opentelemetry.io/otel/sdk/trace\".WithSpanLimits`.\n  Use `WithRawSpanLimits` instead.\n  That option allows setting unlimited and zero limits, this option does not.\n  This option will be kept until the next major version incremented release. (#2637)\n\n## [1.4.1] - 2022-02-16\n\n### Fixed\n\n- Fix race condition in reading the dropped spans number for the `BatchSpanProcessor`. (#2615)\n\n## [1.4.0] - 2022-02-11\n\n### Added\n\n- Use `OTEL_EXPORTER_ZIPKIN_ENDPOINT` environment variable to specify zipkin collector endpoint. (#2490)\n- Log the configuration of `TracerProvider`s, and `Tracer`s for debugging.\n  To enable use a logger with Verbosity (V level) `>=1`. (#2500)\n- Added support to configure the batch span-processor with environment variables.\n  The following environment variables are used. (#2515)\n  - `OTEL_BSP_SCHEDULE_DELAY`\n  - `OTEL_BSP_EXPORT_TIMEOUT`\n  - `OTEL_BSP_MAX_QUEUE_SIZE`.\n  - `OTEL_BSP_MAX_EXPORT_BATCH_SIZE`\n\n### Changed\n\n- Zipkin exporter exports `Resource` attributes in the `Tags` field. (#2589)\n\n### Deprecated\n\n- Deprecate module the `go.opentelemetry.io/otel/sdk/export/metric`.\n  Use the `go.opentelemetry.io/otel/sdk/metric` module instead. (#2382)\n- Deprecate `\"go.opentelemetry.io/otel/sdk/metric\".AtomicFieldOffsets`. (#2445)\n\n### Fixed\n\n- Fixed the instrument kind for noop async instruments to correctly report an implementation. (#2461)\n- Fix UDP packets overflowing with Jaeger payloads. (#2489, #2512)\n- Change the `otlpmetric.Client` interface's `UploadMetrics` method to accept a single `ResourceMetrics` instead of a slice of them. (#2491)\n- Specify explicit buckets in Prometheus example, fixing issue where example only has `+inf` bucket. (#2419, #2493)\n- W3C baggage will now decode urlescaped values. (#2529)\n- Baggage members are now only validated once, when calling `NewMember` and not also when adding it to the baggage itself. (#2522)\n- The order attributes are dropped from spans in the `go.opentelemetry.io/otel/sdk/trace` package when capacity is reached is fixed to be in compliance with the OpenTelemetry specification.\n  Instead of dropping the least-recently-used attribute, the last added attribute is dropped.\n  This drop order still only applies to attributes with unique keys not already contained in the span.\n  If an attribute is added with a key already contained in the span, that attribute is updated to the new value being added. (#2576)\n\n### Removed\n\n- Updated `go.opentelemetry.io/proto/otlp` from `v0.11.0` to `v0.12.0`. This version removes a number of deprecated methods. (#2546)\n  - [`Metric.GetIntGauge()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntGauge)\n  - [`Metric.GetIntHistogram()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntHistogram)\n  - [`Metric.GetIntSum()`](https://pkg.go.dev/go.opentelemetry.io/proto/otlp@v0.11.0/metrics/v1#Metric.GetIntSum)\n\n## [1.3.0] - 2021-12-10\n\n### ⚠️ Notice ⚠️\n\nWe have updated the project minimum supported Go version to 1.16\n\n### Added\n\n- Added an internal Logger.\n  This can be used by the SDK and API to provide users with feedback of the internal state.\n  To enable verbose logs configure the logger which will print V(1) logs. For debugging information configure to print V(5) logs. (#2343)\n- Add the `WithRetry` `Option` and the `RetryConfig` type to the `go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp` package to specify retry behavior consistently. (#2425)\n- Add `SpanStatusFromHTTPStatusCodeAndSpanKind` to all `semconv` packages to return a span status code similar to `SpanStatusFromHTTPStatusCode`, but exclude `4XX` HTTP errors as span errors if the span is of server kind. (#2296)\n\n### Changed\n\n- The `\"go.opentelemetry.io/otel/exporter/otel/otlptrace/otlptracegrpc\".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2329)\n- The `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc\".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2425)\n- The `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetricgrpc\".RetrySettings` type is renamed to `RetryConfig`. (#2425)\n- The `go.opentelemetry.io/otel/exporter/otel/*` gRPC exporters now default to using the host's root CA set if none are provided by the user and `WithInsecure` is not specified. (#2432)\n- Change `resource.Default` to be evaluated the first time it is called, rather than on import. This allows the caller the option to update `OTEL_RESOURCE_ATTRIBUTES` first, such as with `os.Setenv`. (#2371)\n\n### Fixed\n\n- The `go.opentelemetry.io/otel/exporter/otel/*` exporters are updated to handle per-signal and universal endpoints according to the OpenTelemetry specification.\n  Any per-signal endpoint set via an `OTEL_EXPORTER_OTLP_<signal>_ENDPOINT` environment variable is now used without modification of the path.\n  When `OTEL_EXPORTER_OTLP_ENDPOINT` is set, if it contains a path, that path is used as a base path which per-signal paths are appended to. (#2433)\n- Basic metric controller updated to use sync.Map to avoid blocking calls (#2381)\n- The `go.opentelemetry.io/otel/exporter/jaeger` correctly sets the `otel.status_code` value to be a string of `ERROR` or `OK` instead of an integer code. (#2439, #2440)\n\n### Deprecated\n\n- Deprecated the `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp\".WithMaxAttempts` `Option`, use the new `WithRetry` `Option` instead. (#2425)\n- Deprecated the `\"go.opentelemetry.io/otel/exporter/otel/otlpmetric/otlpmetrichttp\".WithBackoff` `Option`, use the new `WithRetry` `Option` instead. (#2425)\n\n### Removed\n\n- Remove the metric Processor's ability to convert cumulative to delta aggregation temporality. (#2350)\n- Remove the metric Bound Instruments interface and implementations. (#2399)\n- Remove the metric MinMaxSumCount kind aggregation and the corresponding OTLP export path. (#2423)\n- Metric SDK removes the \"exact\" aggregator for histogram instruments, as it performed a non-standard aggregation for OTLP export (creating repeated Gauge points) and worked its way into a number of confusing examples. (#2348)\n\n## [1.2.0] - 2021-11-12\n\n### Changed\n\n- Metric SDK `export.ExportKind`, `export.ExportKindSelector` types have been renamed to `aggregation.Temporality` and `aggregation.TemporalitySelector` respectively to keep in line with current specification and protocol along with built-in selectors (e.g., `aggregation.CumulativeTemporalitySelector`, ...). (#2274)\n- The Metric `Exporter` interface now requires a `TemporalitySelector` method instead of an `ExportKindSelector`. (#2274)\n- Metrics API cleanup. The `metric/sdkapi` package has been created to relocate the API-to-SDK interface:\n  - The following interface types simply moved from `metric` to `metric/sdkapi`: `Descriptor`, `MeterImpl`, `InstrumentImpl`, `SyncImpl`, `BoundSyncImpl`, `AsyncImpl`, `AsyncRunner`, `AsyncSingleRunner`, and `AsyncBatchRunner`\n  - The following struct types moved and are replaced with type aliases, since they are exposed to the user: `Observation`, `Measurement`.\n  - The No-op implementations of sync and async instruments are no longer exported, new functions `sdkapi.NewNoopAsyncInstrument()` and `sdkapi.NewNoopSyncInstrument()` are provided instead. (#2271)\n- Update the SDK `BatchSpanProcessor` to export all queued spans when `ForceFlush` is called. (#2080, #2335)\n\n### Added\n\n- Add the `\"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc\".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002)\n- Added a new `schema` module to help parse Schema Files in OTEP 0152 format. (#2267)\n- Added a new `MapCarrier` to the `go.opentelemetry.io/otel/propagation` package to hold propagated cross-cutting concerns as a `map[string]string` held in memory. (#2334)\n\n## [1.1.0] - 2021-10-27\n\n### Added\n\n- Add the `\"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\".WithGRPCConn` option so the exporter can reuse an existing gRPC connection. (#2002)\n- Add the `go.opentelemetry.io/otel/semconv/v1.7.0` package.\n  The package contains semantic conventions from the `v1.7.0` version of the OpenTelemetry specification. (#2320)\n- Add the `go.opentelemetry.io/otel/semconv/v1.6.1` package.\n  The package contains semantic conventions from the `v1.6.1` version of the OpenTelemetry specification. (#2321)\n- Add the `go.opentelemetry.io/otel/semconv/v1.5.0` package.\n  The package contains semantic conventions from the `v1.5.0` version of the OpenTelemetry specification. (#2322)\n  - When upgrading from the `semconv/v1.4.0` package note the following name changes:\n    - `K8SReplicasetUIDKey` -> `K8SReplicaSetUIDKey`\n    - `K8SReplicasetNameKey` -> `K8SReplicaSetNameKey`\n    - `K8SStatefulsetUIDKey` -> `K8SStatefulSetUIDKey`\n    - `k8SStatefulsetNameKey` -> `K8SStatefulSetNameKey`\n    - `K8SDaemonsetUIDKey` -> `K8SDaemonSetUIDKey`\n    - `K8SDaemonsetNameKey` -> `K8SDaemonSetNameKey`\n\n### Changed\n\n- Links added to a span will be dropped by the SDK if they contain an invalid span context (#2275).\n\n### Fixed\n\n- The `\"go.opentelemetry.io/otel/semconv/v1.4.0\".HTTPServerAttributesFromHTTPRequest` now correctly only sets the HTTP client IP attribute even if the connection was routed with proxies and there are multiple addresses in the `X-Forwarded-For` header. (#2282, #2284)\n- The `\"go.opentelemetry.io/otel/semconv/v1.4.0\".NetAttributesFromHTTPRequest` function correctly handles IPv6 addresses as IP addresses and sets the correct net peer IP instead of the net peer hostname attribute. (#2283, #2285)\n- The simple span processor shutdown method deterministically returns the exporter error status if it simultaneously finishes when the deadline is reached. (#2290, #2289)\n\n## [1.0.1] - 2021-10-01\n\n### Fixed\n\n- json stdout exporter no longer crashes due to concurrency bug. (#2265)\n\n## [Metrics 0.24.0] - 2021-10-01\n\n### Changed\n\n- NoopMeterProvider is now private and NewNoopMeterProvider must be used to obtain a noopMeterProvider. (#2237)\n- The Metric SDK `Export()` function takes a new two-level reader interface for iterating over results one instrumentation library at a time. (#2197)\n  - The former `\"go.opentelemetry.io/otel/sdk/export/metric\".CheckpointSet` is renamed `Reader`.\n  - The new interface is named `\"go.opentelemetry.io/otel/sdk/export/metric\".InstrumentationLibraryReader`.\n\n## [1.0.0] - 2021-09-20\n\nThis is the first stable release for the project.\nThis release includes an API and SDK for the tracing signal that will comply with the stability guarantees defined by the projects [versioning policy](./VERSIONING.md).\n\n### Added\n\n- OTLP trace exporter now sets the `SchemaURL` field in the exported telemetry if the Tracer has `WithSchemaURL` option. (#2242)\n\n### Fixed\n\n- Slice-valued attributes can correctly be used as map keys. (#2223)\n\n### Removed\n\n- Removed the `\"go.opentelemetry.io/otel/exporters/zipkin\".WithSDKOptions` function. (#2248)\n- Removed the deprecated package `go.opentelemetry.io/otel/oteltest`. (#2234)\n- Removed the deprecated package `go.opentelemetry.io/otel/bridge/opencensus/utils`. (#2233)\n- Removed deprecated functions, types, and methods from `go.opentelemetry.io/otel/attribute` package.\n  Use the typed functions and methods added to the package instead. (#2235)\n  - The `Key.Array` method is removed.\n  - The `Array` function is removed.\n  - The `Any` function is removed.\n  - The `ArrayValue` function is removed.\n  - The `AsArray` function is removed.\n\n## [1.0.0-RC3] - 2021-09-02\n\n### Added\n\n- Added `ErrorHandlerFunc` to use a function as an `\"go.opentelemetry.io/otel\".ErrorHandler`. (#2149)\n- Added `\"go.opentelemetry.io/otel/trace\".WithStackTrace` option to add a stack trace when using `span.RecordError` or when panic is handled in `span.End`. (#2163)\n- Added typed slice attribute types and functionality to the `go.opentelemetry.io/otel/attribute` package to replace the existing array type and functions. (#2162)\n  - `BoolSlice`, `IntSlice`, `Int64Slice`, `Float64Slice`, and `StringSlice` replace the use of the `Array` function in the package.\n- Added the `go.opentelemetry.io/otel/example/fib` example package.\n  Included is an example application that computes Fibonacci numbers. (#2203)\n\n### Changed\n\n- Metric instruments have been renamed to match the (feature-frozen) metric API specification:\n  - ValueRecorder becomes Histogram\n  - ValueObserver becomes Gauge\n  - SumObserver becomes CounterObserver\n  - UpDownSumObserver becomes UpDownCounterObserver\n  The API exported from this project is still considered experimental. (#2202)\n- Metric SDK/API implementation type `InstrumentKind` moves into `sdkapi` sub-package. (#2091)\n- The Metrics SDK export record no longer contains a Resource pointer, the SDK `\"go.opentelemetry.io/otel/sdk/trace/export/metric\".Exporter.Export()` function for push-based exporters now takes a single Resource argument, pull-based exporters use `\"go.opentelemetry.io/otel/sdk/metric/controller/basic\".Controller.Resource()`. (#2120)\n- The JSON output of the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` is harmonized now such that the output is \"plain\" JSON objects after each other of the form `{ ... } { ... } { ... }`. Earlier the JSON objects describing a span were wrapped in a slice for each `Exporter.ExportSpans` call, like `[ { ... } ][ { ... } { ... } ]`. Outputting JSON object directly after each other is consistent with JSON loggers, and a bit easier to parse and read. (#2196)\n- Update the `NewTracerConfig`, `NewSpanStartConfig`, `NewSpanEndConfig`, and `NewEventConfig` function in the `go.opentelemetry.io/otel/trace` package to return their respective configurations as structs instead of pointers to the struct. (#2212)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/bridge/opencensus/utils` package is deprecated.\n  All functionality from this package now exists in the `go.opentelemetry.io/otel/bridge/opencensus` package.\n  The functions from that package should be used instead. (#2166)\n- The `\"go.opentelemetry.io/otel/attribute\".Array` function and the related `ARRAY` value type is deprecated.\n  Use the typed `*Slice` functions and types added to the package instead. (#2162)\n- The `\"go.opentelemetry.io/otel/attribute\".Any` function is deprecated.\n  Use the typed functions instead. (#2181)\n- The `go.opentelemetry.io/otel/oteltest` package is deprecated.\n  The `\"go.opentelemetry.io/otel/sdk/trace/tracetest\".SpanRecorder` can be registered with the default SDK (`go.opentelemetry.io/otel/sdk/trace`) as a `SpanProcessor` and used as a replacement for this deprecated package. (#2188)\n\n### Removed\n\n- Removed metrics test package `go.opentelemetry.io/otel/sdk/export/metric/metrictest`. (#2105)\n\n### Fixed\n\n- The `fromEnv` detector no longer throws an error when `OTEL_RESOURCE_ATTRIBUTES` environment variable is not set or empty. (#2138)\n- Setting the global `ErrorHandler` with `\"go.opentelemetry.io/otel\".SetErrorHandler` multiple times is now supported. (#2160, #2140)\n- The `\"go.opentelemetry.io/otel/attribute\".Any` function now supports `int32` values. (#2169)\n- Multiple calls to `\"go.opentelemetry.io/otel/sdk/metric/controller/basic\".WithResource()` are handled correctly, and when no resources are provided `\"go.opentelemetry.io/otel/sdk/resource\".Default()` is used. (#2120)\n- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly omit timestamps. (#2195)\n- Fixed typos in resources.go. (#2201)\n\n## [1.0.0-RC2] - 2021-07-26\n\n### Added\n\n- Added `WithOSDescription` resource configuration option to set OS (Operating System) description resource attribute (`os.description`). (#1840)\n- Added `WithOS` resource configuration option to set all OS (Operating System) resource attributes at once. (#1840)\n- Added the `WithRetry` option to the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package.\n  This option is a replacement for the removed `WithMaxAttempts` and `WithBackoff` options. (#2095)\n- Added API `LinkFromContext` to return Link which encapsulates SpanContext from provided context and also encapsulates attributes. (#2115)\n- Added a new `Link` type under the SDK `otel/sdk/trace` package that counts the number of attributes that were dropped for surpassing the `AttributePerLinkCountLimit` configured in the Span's `SpanLimits`.\n  This new type replaces the equal-named API `Link` type found in the `otel/trace` package for most usages within the SDK.\n  For example, instances of this type are now returned by the `Links()` function of `ReadOnlySpan`s provided in places like the `OnEnd` function of `SpanProcessor` implementations. (#2118)\n- Added the `SpanRecorder` type to the `go.opentelemetry.io/otel/skd/trace/tracetest` package.\n  This type can be used with the default SDK as a `SpanProcessor` during testing. (#2132)\n\n### Changed\n\n- The `SpanModels` function is now exported from the `go.opentelemetry.io/otel/exporters/zipkin` package to convert OpenTelemetry spans into Zipkin model spans. (#2027)\n- Rename the `\"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\".RetrySettings` to `RetryConfig`. (#2095)\n\n### Deprecated\n\n- The `TextMapCarrier` and `TextMapPropagator` from the `go.opentelemetry.io/otel/oteltest` package and their associated creation functions (`TextMapCarrier`, `NewTextMapPropagator`) are deprecated. (#2114)\n- The `Harness` type from the `go.opentelemetry.io/otel/oteltest` package and its associated creation function, `NewHarness` are deprecated and will be removed in the next release. (#2123)\n- The `TraceStateFromKeyValues` function from the `go.opentelemetry.io/otel/oteltest` package is deprecated.\n  Use the `trace.ParseTraceState` function instead. (#2122)\n\n### Removed\n\n- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/jaeger`. (#2020)\n- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/zipkin`. (#2020)\n- Removed the `\"go.opentelemetry.io/otel/sdk/resource\".WithBuiltinDetectors` function.\n  The explicit `With*` options for every built-in detector should be used instead. (#2026 #2097)\n- Removed the `WithMaxAttempts` and `WithBackoff` options from the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package.\n  The retry logic of the package has been updated to match the `otlptracegrpc` package and accordingly a `WithRetry` option is added that should be used instead. (#2095)\n- Removed `DroppedAttributeCount` field from `otel/trace.Link` struct. (#2118)\n\n### Fixed\n\n- When using WithNewRoot, don't use the parent context for making sampling decisions. (#2032)\n- `oteltest.Tracer` now creates a valid `SpanContext` when using `WithNewRoot`. (#2073)\n- OS type detector now sets the correct `dragonflybsd` value for DragonFly BSD. (#2092)\n- The OTel span status is correctly transformed into the OTLP status in the `go.opentelemetry.io/otel/exporters/otlp/otlptrace` package.\n  This fix will by default set the status to `Unset` if it is not explicitly set to `Ok` or `Error`. (#2099 #2102)\n- The `Inject` method for the `\"go.opentelemetry.io/otel/propagation\".TraceContext` type no longer injects empty `tracestate` values. (#2108)\n- Use `6831` as default Jaeger agent port instead of `6832`. (#2131)\n\n## [Experimental Metrics v0.22.0] - 2021-07-19\n\n### Added\n\n- Adds HTTP support for OTLP metrics exporter. (#2022)\n\n### Removed\n\n- Removed the deprecated package `go.opentelemetry.io/otel/exporters/metric/prometheus`. (#2020)\n\n## [1.0.0-RC1] / 0.21.0 - 2021-06-18\n\nWith this release we are introducing a split in module versions.  The tracing API and SDK are entering the `v1.0.0` Release Candidate phase with `v1.0.0-RC1`\nwhile the experimental metrics API and SDK continue with `v0.x` releases at `v0.21.0`.  Modules at major version 1 or greater will not depend on modules\nwith major version 0.\n\n### Added\n\n- Adds `otlpgrpc.WithRetry`option for configuring the retry policy for transient errors on the otlp/gRPC exporter. (#1832)\n  - The following status codes are defined as transient errors:\n      | gRPC Status Code | Description |\n      | ---------------- | ----------- |\n      | 1  | Cancelled |\n      | 4  | Deadline Exceeded |\n      | 8  | Resource Exhausted |\n      | 10 | Aborted |\n      | 10 | Out of Range |\n      | 14 | Unavailable |\n      | 15 | Data Loss |\n- Added `Status` type to the `go.opentelemetry.io/otel/sdk/trace` package to represent the status of a span. (#1874)\n- Added `SpanStub` type and its associated functions to the `go.opentelemetry.io/otel/sdk/trace/tracetest` package.\n  This type can be used as a testing replacement for the `SpanSnapshot` that was removed from the `go.opentelemetry.io/otel/sdk/trace` package. (#1873)\n- Adds support for scheme in `OTEL_EXPORTER_OTLP_ENDPOINT` according to the spec. (#1886)\n- Adds `trace.WithSchemaURL` option for configuring the tracer with a Schema URL. (#1889)\n- Added an example of using OpenTelemetry Go as a trace context forwarder. (#1912)\n- `ParseTraceState` is added to the `go.opentelemetry.io/otel/trace` package.\n  It can be used to decode a `TraceState` from a `tracestate` header string value. (#1937)\n- Added `Len` method to the `TraceState` type in the `go.opentelemetry.io/otel/trace` package.\n  This method returns the number of list-members the `TraceState` holds. (#1937)\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace` that defines a trace exporter that uses a `otlptrace.Client` to send data.\n  Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` implementing a gRPC `otlptrace.Client` and offers convenience functions, `NewExportPipeline` and `InstallNewPipeline`, to setup and install a `otlptrace.Exporter` in tracing .(#1922)\n- Added `Baggage`, `Member`, and `Property` types to the `go.opentelemetry.io/otel/baggage` package along with their related functions. (#1967)\n- Added `ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext` functions to the `go.opentelemetry.io/otel/baggage` package.\n  These functions replace the `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions from that package and directly work with the new `Baggage` type. (#1967)\n- The `OTEL_SERVICE_NAME` environment variable is the preferred source for `service.name`, used by the environment resource detector if a service name is present both there and in `OTEL_RESOURCE_ATTRIBUTES`. (#1969)\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` implementing an HTTP `otlptrace.Client` and offers convenience functions, `NewExportPipeline` and `InstallNewPipeline`, to setup and install a `otlptrace.Exporter` in tracing. (#1963)\n- Changes `go.opentelemetry.io/otel/sdk/resource.NewWithAttributes` to require a schema URL. The old function is still available as `resource.NewSchemaless`. This is a breaking change. (#1938)\n- Several builtin resource detectors now correctly populate the schema URL. (#1938)\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` that defines a metrics exporter that uses a `otlpmetric.Client` to send data.\n- Creates package `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` implementing a gRPC `otlpmetric.Client` and offers convenience functions, `New` and `NewUnstarted`, to create an `otlpmetric.Exporter`.(#1991)\n- Added `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter. (#2005)\n- Added `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` exporter. (#2005)\n- Added a `TracerProvider()` method to the `\"go.opentelemetry.io/otel/trace\".Span` interface. This can be used to obtain a `TracerProvider` from a given span that utilizes the same trace processing pipeline.  (#2009)\n\n### Changed\n\n- Make `NewSplitDriver` from `go.opentelemetry.io/otel/exporters/otlp` take variadic arguments instead of a `SplitConfig` item.\n  `NewSplitDriver` now automatically implements an internal `noopDriver` for `SplitConfig` fields that are not initialized. (#1798)\n- `resource.New()` now creates a Resource without builtin detectors. Previous behavior is now achieved by using `WithBuiltinDetectors` Option. (#1810)\n- Move the `Event` type from the `go.opentelemetry.io/otel` package to the `go.opentelemetry.io/otel/sdk/trace` package. (#1846)\n- CI builds validate against last two versions of Go, dropping 1.14 and adding 1.16. (#1865)\n- BatchSpanProcessor now report export failures when calling `ForceFlush()` method. (#1860)\n- `Set.Encoded(Encoder)` no longer caches the result of an encoding. (#1855)\n- Renamed `CloudZoneKey` to `CloudAvailabilityZoneKey` in Resource semantic conventions according to spec. (#1871)\n- The `StatusCode` and `StatusMessage` methods of the `ReadOnlySpan` interface and the `Span` produced by the `go.opentelemetry.io/otel/sdk/trace` package have been replaced with a single `Status` method.\n  This method returns the status of a span using the new `Status` type. (#1874)\n- Updated `ExportSpans` method of the`SpanExporter` interface type to accept `ReadOnlySpan`s instead of the removed `SpanSnapshot`.\n  This brings the export interface into compliance with the specification in that it now accepts an explicitly immutable type instead of just an implied one. (#1873)\n- Unembed `SpanContext` in `Link`. (#1877)\n- Generate Semantic conventions from the specification YAML. (#1891)\n- Spans created by the global `Tracer` obtained from `go.opentelemetry.io/otel`, prior to a functioning `TracerProvider` being set, now propagate the span context from their parent if one exists. (#1901)\n- The `\"go.opentelemetry.io/otel\".Tracer` function now accepts tracer options. (#1902)\n- Move the `go.opentelemetry.io/otel/unit` package to `go.opentelemetry.io/otel/metric/unit`. (#1903)\n- Changed `go.opentelemetry.io/otel/trace.TracerConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config.) (#1921)\n- Changed `go.opentelemetry.io/otel/trace.SpanConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921)\n- Changed `span.End()` now only accepts Options that are allowed at `End()`. (#1921)\n- Changed `go.opentelemetry.io/otel/metric.InstrumentConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921)\n- Changed `go.opentelemetry.io/otel/metric.MeterConfig` to conform to the [Contributing guidelines](CONTRIBUTING.md#config). (#1921)\n- Refactored option types according to the contribution style guide. (#1882)\n- Move the `go.opentelemetry.io/otel/trace.TraceStateFromKeyValues` function to the `go.opentelemetry.io/otel/oteltest` package.\n  This function is preserved for testing purposes where it may be useful to create a `TraceState` from `attribute.KeyValue`s, but it is not intended for production use.\n  The new `ParseTraceState` function should be used to create a `TraceState`. (#1931)\n- Updated `MarshalJSON` method of the `go.opentelemetry.io/otel/trace.TraceState` type to marshal the type into the string representation of the `TraceState`. (#1931)\n- The `TraceState.Delete` method from the `go.opentelemetry.io/otel/trace` package no longer returns an error in addition to a `TraceState`. (#1931)\n- Updated `Get` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a `string` instead of an `attribute.Key` type. (#1931)\n- Updated `Insert` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a pair of `string`s instead of an `attribute.KeyValue` type. (#1931)\n- Updated `Delete` method of the `TraceState` type from the `go.opentelemetry.io/otel/trace` package to accept a `string` instead of an `attribute.Key` type. (#1931)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/stdout` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/metric/prometheus` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1985)\n- Renamed `NewExporter` to `New` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985)\n- Renamed `NewUnstartedExporter` to `NewUnstarted` in the `go.opentelemetry.io/otel/exporters/otlp` package. (#1985)\n- The `go.opentelemetry.io/otel/semconv` package has been moved to `go.opentelemetry.io/otel/semconv/v1.4.0` to allow for multiple [telemetry schema](https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md) versions to be used concurrently. (#1987)\n- Metrics test helpers in `go.opentelemetry.io/otel/oteltest` have been moved to `go.opentelemetry.io/otel/metric/metrictest`. (#1988)\n\n### Deprecated\n\n- The `go.opentelemetry.io/otel/exporters/metric/prometheus` is deprecated, use `go.opentelemetry.io/otel/exporters/prometheus` instead. (#1993)\n- The `go.opentelemetry.io/otel/exporters/trace/jaeger` is deprecated, use `go.opentelemetry.io/otel/exporters/jaeger` instead. (#1993)\n- The `go.opentelemetry.io/otel/exporters/trace/zipkin` is deprecated, use `go.opentelemetry.io/otel/exporters/zipkin` instead. (#1993)\n\n### Removed\n\n- Removed `resource.WithoutBuiltin()`. Use `resource.New()`. (#1810)\n- Unexported types `resource.FromEnv`, `resource.Host`, and `resource.TelemetrySDK`, Use the corresponding `With*()` to use individually. (#1810)\n- Removed the `Tracer` and `IsRecording` method from the `ReadOnlySpan` in the `go.opentelemetry.io/otel/sdk/trace`.\n  The `Tracer` method is not a required to be included in this interface and given the mutable nature of the tracer that is associated with a span, this method is not appropriate.\n  The `IsRecording` method returns if the span is recording or not.\n  A read-only span value does not need to know if updates to it will be recorded or not.\n  By definition, it cannot be updated so there is no point in communicating if an update is recorded. (#1873)\n- Removed the `SpanSnapshot` type from the `go.opentelemetry.io/otel/sdk/trace` package.\n  The use of this type has been replaced with the use of the explicitly immutable `ReadOnlySpan` type.\n  When a concrete representation of a read-only span is needed for testing, the newly added `SpanStub` in the `go.opentelemetry.io/otel/sdk/trace/tracetest` package should be used. (#1873)\n- Removed the `Tracer` method from the `Span` interface in the `go.opentelemetry.io/otel/trace` package.\n  Using the same tracer that created a span introduces the error where an instrumentation library's `Tracer` is used by other code instead of their own.\n  The `\"go.opentelemetry.io/otel\".Tracer` function or a `TracerProvider` should be used to acquire a library specific `Tracer` instead. (#1900)\n  - The `TracerProvider()` method on the `Span` interface may also be used to obtain a `TracerProvider` using the same trace processing pipeline. (#2009)\n- The `http.url` attribute generated by `HTTPClientAttributesFromHTTPRequest` will no longer include username or password information. (#1919)\n- Removed `IsEmpty` method of the `TraceState` type in the `go.opentelemetry.io/otel/trace` package in favor of using the added `TraceState.Len` method. (#1931)\n- Removed `Set`, `Value`, `ContextWithValue`, `ContextWithoutValue`, and `ContextWithEmpty` functions in the `go.opentelemetry.io/otel/baggage` package.\n  Handling of baggage is now done using the added `Baggage` type and related context functions (`ContextWithBaggage`, `ContextWithoutBaggage`, and `FromContext`) in that package. (#1967)\n- The `InstallNewPipeline` and `NewExportPipeline` creation functions in all the exporters (prometheus, otlp, stdout, jaeger, and zipkin) have been removed.\n  These functions were deemed premature attempts to provide convenience that did not achieve this aim. (#1985)\n- The `go.opentelemetry.io/otel/exporters/otlp` exporter has been removed.  Use `go.opentelemetry.io/otel/exporters/otlp/otlptrace` instead. (#1990)\n- The `go.opentelemetry.io/otel/exporters/stdout` exporter has been removed.  Use `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` or `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` instead. (#2005)\n\n### Fixed\n\n- Only report errors from the `\"go.opentelemetry.io/otel/sdk/resource\".Environment` function when they are not `nil`. (#1850, #1851)\n- The `Shutdown` method of the simple `SpanProcessor` in the `go.opentelemetry.io/otel/sdk/trace` package now honors the context deadline or cancellation. (#1616, #1856)\n- BatchSpanProcessor now drops span batches that failed to be exported. (#1860)\n- Use `http://localhost:14268/api/traces` as default Jaeger collector endpoint instead of `http://localhost:14250`. (#1898)\n- Allow trailing and leading whitespace in the parsing of a `tracestate` header. (#1931)\n- Add logic to determine if the channel is closed to fix Jaeger exporter test panic with close closed channel. (#1870, #1973)\n- Avoid transport security when OTLP endpoint is a Unix socket. (#2001)\n\n### Security\n\n## [0.20.0] - 2021-04-23\n\n### Added\n\n- The OTLP exporter now has two new convenience functions, `NewExportPipeline` and `InstallNewPipeline`, setup and install the exporter in tracing and metrics pipelines. (#1373)\n- Adds semantic conventions for exceptions. (#1492)\n- Added Jaeger Environment variables: `OTEL_EXPORTER_JAEGER_AGENT_HOST`, `OTEL_EXPORTER_JAEGER_AGENT_PORT`\n  These environment variables can be used to override Jaeger agent hostname and port (#1752)\n- Option `ExportTimeout` was added to batch span processor. (#1755)\n- `trace.TraceFlags` is now a defined type over `byte` and `WithSampled(bool) TraceFlags` and `IsSampled() bool` methods have been added to it. (#1770)\n- The `Event` and `Link` struct types from the `go.opentelemetry.io/otel` package now include a `DroppedAttributeCount` field to record the number of attributes that were not recorded due to configured limits being reached. (#1771)\n- The Jaeger exporter now reports dropped attributes for a Span event in the exported log. (#1771)\n- Adds test to check BatchSpanProcessor ignores `OnEnd` and `ForceFlush` post `Shutdown`. (#1772)\n- Extract resource attributes from the `OTEL_RESOURCE_ATTRIBUTES` environment variable and merge them with the `resource.Default` resource as well as resources provided to the `TracerProvider` and metric `Controller`. (#1785)\n- Added `WithOSType` resource configuration option to set OS (Operating System) type resource attribute (`os.type`). (#1788)\n- Added `WithProcess*` resource configuration options to set Process resource attributes. (#1788)\n  - `process.pid`\n  - `process.executable.name`\n  - `process.executable.path`\n  - `process.command_args`\n  - `process.owner`\n  - `process.runtime.name`\n  - `process.runtime.version`\n  - `process.runtime.description`\n- Adds `k8s.node.name` and `k8s.node.uid` attribute keys to the `semconv` package. (#1789)\n- Added support for configuring OTLP/HTTP and OTLP/gRPC Endpoints, TLS Certificates, Headers, Compression and Timeout via Environment Variables. (#1758, #1769 and #1811)\n  - `OTEL_EXPORTER_OTLP_ENDPOINT`\n  - `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`\n  - `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`\n  - `OTEL_EXPORTER_OTLP_HEADERS`\n  - `OTEL_EXPORTER_OTLP_TRACES_HEADERS`\n  - `OTEL_EXPORTER_OTLP_METRICS_HEADERS`\n  - `OTEL_EXPORTER_OTLP_COMPRESSION`\n  - `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION`\n  - `OTEL_EXPORTER_OTLP_METRICS_COMPRESSION`\n  - `OTEL_EXPORTER_OTLP_TIMEOUT`\n  - `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`\n  - `OTEL_EXPORTER_OTLP_METRICS_TIMEOUT`\n  - `OTEL_EXPORTER_OTLP_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE`\n  - `OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE`\n- Adds `otlpgrpc.WithTimeout` option for configuring timeout to the otlp/gRPC exporter. (#1821)\n- Adds `jaeger.WithMaxPacketSize` option for configuring maximum UDP packet size used when connecting to the Jaeger agent. (#1853)\n\n### Fixed\n\n- The `Span.IsRecording` implementation from `go.opentelemetry.io/otel/sdk/trace` always returns false when not being sampled. (#1750)\n- The Jaeger exporter now correctly sets tags for the Span status code and message.\n  This means it uses the correct tag keys (`\"otel.status_code\"`, `\"otel.status_description\"`) and does not set the status message as a tag unless it is set on the span. (#1761)\n- The Jaeger exporter now correctly records Span event's names using the `\"event\"` key for a tag.\n  Additionally, this tag is overridden, as specified in the OTel specification, if the event contains an attribute with that key. (#1768)\n- Zipkin Exporter: Ensure mapping between OTel and Zipkin span data complies with the specification. (#1688)\n- Fixed typo for default service name in Jaeger Exporter. (#1797)\n- Fix flaky OTLP for the reconnnection of the client connection. (#1527, #1814)\n- Fix Jaeger exporter dropping of span batches that exceed the UDP packet size limit.\n  Instead, the exporter now splits the batch into smaller sendable batches. (#1828)\n\n### Changed\n\n- Span `RecordError` now records an `exception` event to comply with the semantic convention specification. (#1492)\n- Jaeger exporter was updated to use thrift v0.14.1. (#1712)\n- Migrate from using internally built and maintained version of the OTLP to the one hosted at `go.opentelemetry.io/proto/otlp`. (#1713)\n- Migrate from using `github.com/gogo/protobuf` to `google.golang.org/protobuf` to match `go.opentelemetry.io/proto/otlp`. (#1713)\n- The storage of a local or remote Span in a `context.Context` using its SpanContext is unified to store just the current Span.\n  The Span's SpanContext can now self-identify as being remote or not.\n  This means that `\"go.opentelemetry.io/otel/trace\".ContextWithRemoteSpanContext` will now overwrite any existing current Span, not just existing remote Spans, and make it the current Span in a `context.Context`. (#1731)\n- Improve OTLP/gRPC exporter connection errors. (#1737)\n- Information about a parent span context in a `\"go.opentelemetry.io/otel/export/trace\".SpanSnapshot` is unified in a new `Parent` field.\n  The existing `ParentSpanID` and `HasRemoteParent` fields are removed in favor of this. (#1748)\n- The `ParentContext` field of the `\"go.opentelemetry.io/otel/sdk/trace\".SamplingParameters` is updated to hold a `context.Context` containing the parent span.\n  This changes it to make `SamplingParameters` conform with the OpenTelemetry specification. (#1749)\n- Updated Jaeger Environment Variables: `JAEGER_ENDPOINT`, `JAEGER_USER`, `JAEGER_PASSWORD`\n  to `OTEL_EXPORTER_JAEGER_ENDPOINT`, `OTEL_EXPORTER_JAEGER_USER`, `OTEL_EXPORTER_JAEGER_PASSWORD` in compliance with OTel specification. (#1752)\n- Modify `BatchSpanProcessor.ForceFlush` to abort after timeout/cancellation. (#1757)\n- The `DroppedAttributeCount` field of the `Span` in the `go.opentelemetry.io/otel` package now only represents the number of attributes dropped for the span itself.\n  It no longer is a conglomerate of itself, events, and link attributes that have been dropped. (#1771)\n- Make `ExportSpans` in Jaeger Exporter honor context deadline. (#1773)\n- Modify Zipkin Exporter default service name, use default resource's serviceName instead of empty. (#1777)\n- The `go.opentelemetry.io/otel/sdk/export/trace` package is merged into the `go.opentelemetry.io/otel/sdk/trace` package. (#1778)\n- The prometheus.InstallNewPipeline example is moved from comment to example test (#1796)\n- The convenience functions for the stdout exporter have been updated to return the `TracerProvider` implementation and enable the shutdown of the exporter. (#1800)\n- Replace the flush function returned from the Jaeger exporter's convenience creation functions (`InstallNewPipeline` and `NewExportPipeline`) with the `TracerProvider` implementation they create.\n  This enables the caller to shutdown and flush using the related `TracerProvider` methods. (#1822)\n- Updated the Jaeger exporter to have a default endpoint, `http://localhost:14250`, for the collector. (#1824)\n- Changed the function `WithCollectorEndpoint` in the Jaeger exporter to no longer accept an endpoint as an argument.\n  The endpoint can be passed with the `CollectorEndpointOption` using the `WithEndpoint` function or by setting the `OTEL_EXPORTER_JAEGER_ENDPOINT` environment variable value appropriately. (#1824)\n- The Jaeger exporter no longer batches exported spans itself, instead it relies on the SDK's `BatchSpanProcessor` for this functionality. (#1830)\n- The Jaeger exporter creation functions (`NewRawExporter`, `NewExportPipeline`, and `InstallNewPipeline`) no longer accept the removed `Option` type as a variadic argument. (#1830)\n\n### Removed\n\n- Removed Jaeger Environment variables: `JAEGER_SERVICE_NAME`, `JAEGER_DISABLED`, `JAEGER_TAGS`\n  These environment variables will no longer be used to override values of the Jaeger exporter (#1752)\n- No longer set the links for a `Span` in `go.opentelemetry.io/otel/sdk/trace` that is configured to be a new root.\n  This is unspecified behavior that the OpenTelemetry community plans to standardize in the future.\n  To prevent backwards incompatible changes when it is specified, these links are removed. (#1726)\n- Setting error status while recording error with Span from oteltest package. (#1729)\n- The concept of a remote and local Span stored in a context is unified to just the current Span.\n  Because of this `\"go.opentelemetry.io/otel/trace\".RemoteSpanContextFromContext` is removed as it is no longer needed.\n  Instead, `\"go.opentelemetry.io/otel/trace\".SpanContextFromContex` can be used to return the current Span.\n  If needed, that Span's `SpanContext.IsRemote()` can then be used to determine if it is remote or not. (#1731)\n- The `HasRemoteParent` field of the `\"go.opentelemetry.io/otel/sdk/trace\".SamplingParameters` is removed.\n  This field is redundant to the information returned from the `Remote` method of the `SpanContext` held in the `ParentContext` field. (#1749)\n- The `trace.FlagsDebug` and `trace.FlagsDeferred` constants have been removed and will be localized to the B3 propagator. (#1770)\n- Remove `Process` configuration, `WithProcessFromEnv` and `ProcessFromEnv`, and type from the Jaeger exporter package.\n  The information that could be configured in the `Process` struct should be configured in a `Resource` instead. (#1776, #1804)\n- Remove the `WithDisabled` option from the Jaeger exporter.\n  To disable the exporter unregister it from the `TracerProvider` or use a no-operation `TracerProvider`. (#1806)\n- Removed the functions `CollectorEndpointFromEnv` and `WithCollectorEndpointOptionFromEnv` from the Jaeger exporter.\n  These functions for retrieving specific environment variable values are redundant of other internal functions and\n  are not intended for end user use. (#1824)\n- Removed the Jaeger exporter `WithSDKOptions` `Option`.\n  This option was used to set SDK options for the exporter creation convenience functions.\n  These functions are provided as a way to easily setup or install the exporter with what are deemed reasonable SDK settings for common use cases.\n  If the SDK needs to be configured differently, the `NewRawExporter` function and direct setup of the SDK with the desired settings should be used. (#1825)\n- The `WithBufferMaxCount` and `WithBatchMaxCount` `Option`s from the Jaeger exporter are removed.\n  The exporter no longer batches exports, instead relying on the SDK's `BatchSpanProcessor` for this functionality. (#1830)\n- The Jaeger exporter `Option` type is removed.\n  The type is no longer used by the exporter to configure anything.\n  All the previous configurations these options provided were duplicates of SDK configuration.\n  They have been removed in favor of using the SDK configuration and focuses the exporter configuration to be only about the endpoints it will send telemetry to. (#1830)\n\n## [0.19.0] - 2021-03-18\n\n### Added\n\n- Added `Marshaler` config option to `otlphttp` to enable otlp over json or protobufs. (#1586)\n- A `ForceFlush` method to the `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` to flush all registered `SpanProcessor`s. (#1608)\n- Added `WithSampler` and `WithSpanLimits` to tracer provider. (#1633, #1702)\n- `\"go.opentelemetry.io/otel/trace\".SpanContext` now has a `remote` property, and `IsRemote()` predicate, that is true when the `SpanContext` has been extracted from remote context data. (#1701)\n- A `Valid` method to the `\"go.opentelemetry.io/otel/attribute\".KeyValue` type. (#1703)\n\n### Changed\n\n- `trace.SpanContext` is now immutable and has no exported fields. (#1573)\n  - `trace.NewSpanContext()` can be used in conjunction with the `trace.SpanContextConfig` struct to initialize a new `SpanContext` where all values are known.\n- Update the `ForceFlush` method signature to the `\"go.opentelemetry.io/otel/sdk/trace\".SpanProcessor` to accept a `context.Context` and return an error. (#1608)\n- Update the `Shutdown` method to the `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` return an error on shutdown failure. (#1608)\n- The SimpleSpanProcessor will now shut down the enclosed `SpanExporter` and gracefully ignore subsequent calls to `OnEnd` after `Shutdown` is called. (#1612)\n- `\"go.opentelemetry.io/sdk/metric/controller.basic\".WithPusher` is replaced with `WithExporter` to provide consistent naming across project. (#1656)\n- Added non-empty string check for trace `Attribute` keys. (#1659)\n- Add `description` to SpanStatus only when `StatusCode` is set to error. (#1662)\n- Jaeger exporter falls back to `resource.Default`'s `service.name` if the exported Span does not have one. (#1673)\n- Jaeger exporter populates Jaeger's Span Process from Resource. (#1673)\n- Renamed the `LabelSet` method of `\"go.opentelemetry.io/otel/sdk/resource\".Resource` to `Set`. (#1692)\n- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/jaeger` package. (#1693)\n- Changed `WithSDK` to `WithSDKOptions` to accept variadic arguments of `TracerProviderOption` type in `go.opentelemetry.io/otel/exporters/trace/zipkin` package. (#1693)\n\n### Removed\n\n- Removed `serviceName` parameter from Zipkin exporter and uses resource instead. (#1549)\n- Removed `WithConfig` from tracer provider to avoid overriding configuration. (#1633)\n- Removed the exported `SimpleSpanProcessor` and `BatchSpanProcessor` structs.\n   These are now returned as a SpanProcessor interface from their respective constructors. (#1638)\n- Removed `WithRecord()` from `trace.SpanOption` when creating a span. (#1660)\n- Removed setting status to `Error` while recording an error as a span event in `RecordError`. (#1663)\n- Removed `jaeger.WithProcess` configuration option. (#1673)\n- Removed `ApplyConfig` method from `\"go.opentelemetry.io/otel/sdk/trace\".TracerProvider` and the now unneeded `Config` struct. (#1693)\n\n### Fixed\n\n- Jaeger Exporter: Ensure mapping between OTEL and Jaeger span data complies with the specification. (#1626)\n- `SamplingResult.TraceState` is correctly propagated to a newly created span's `SpanContext`. (#1655)\n- The `otel-collector` example now correctly flushes metric events prior to shutting down the exporter. (#1678)\n- Do not set span status message in `SpanStatusFromHTTPStatusCode` if it can be inferred from `http.status_code`. (#1681)\n- Synchronization issues in global trace delegate implementation. (#1686)\n- Reduced excess memory usage by global `TracerProvider`. (#1687)\n\n## [0.18.0] - 2021-03-03\n\n### Added\n\n- Added `resource.Default()` for use with meter and tracer providers. (#1507)\n- `AttributePerEventCountLimit` and `AttributePerLinkCountLimit` for `SpanLimits`. (#1535)\n- Added `Keys()` method to `propagation.TextMapCarrier` and `propagation.HeaderCarrier` to adapt `http.Header` to this interface. (#1544)\n- Added `code` attributes to `go.opentelemetry.io/otel/semconv` package. (#1558)\n- Compatibility testing suite in the CI system for the following systems. (#1567)\n   | OS      | Go Version | Architecture |\n   | ------- | ---------- | ------------ |\n   | Ubuntu  | 1.15       | amd64        |\n   | Ubuntu  | 1.14       | amd64        |\n   | Ubuntu  | 1.15       | 386          |\n   | Ubuntu  | 1.14       | 386          |\n   | MacOS   | 1.15       | amd64        |\n   | MacOS   | 1.14       | amd64        |\n   | Windows | 1.15       | amd64        |\n   | Windows | 1.14       | amd64        |\n   | Windows | 1.15       | 386          |\n   | Windows | 1.14       | 386          |\n\n### Changed\n\n- Replaced interface `oteltest.SpanRecorder` with its existing implementation\n  `StandardSpanRecorder`. (#1542)\n- Default span limit values to 128. (#1535)\n- Rename `MaxEventsPerSpan`, `MaxAttributesPerSpan` and `MaxLinksPerSpan` to `EventCountLimit`, `AttributeCountLimit` and `LinkCountLimit`, and move these fields into `SpanLimits`. (#1535)\n- Renamed the `otel/label` package to `otel/attribute`. (#1541)\n- Vendor the Jaeger exporter's dependency on Apache Thrift. (#1551)\n- Parallelize the CI linting and testing. (#1567)\n- Stagger timestamps in exact aggregator tests. (#1569)\n- Changed all examples to use `WithBatchTimeout(5 * time.Second)` rather than `WithBatchTimeout(5)`. (#1621)\n- Prevent end-users from implementing some interfaces (#1575)\n\n  ```\n      \"otel/exporters/otlp/otlphttp\".Option\n      \"otel/exporters/stdout\".Option\n      \"otel/oteltest\".Option\n      \"otel/trace\".TracerOption\n      \"otel/trace\".SpanOption\n      \"otel/trace\".EventOption\n      \"otel/trace\".LifeCycleOption\n      \"otel/trace\".InstrumentationOption\n      \"otel/sdk/resource\".Option\n      \"otel/sdk/trace\".ParentBasedSamplerOption\n      \"otel/sdk/trace\".ReadOnlySpan\n      \"otel/sdk/trace\".ReadWriteSpan\n  ```\n\n### Removed\n\n- Removed attempt to resample spans upon changing the span name with `span.SetName()`. (#1545)\n- The `test-benchmark` is no longer a dependency of the `precommit` make target. (#1567)\n- Removed the `test-386` make target.\n   This was replaced with a full compatibility testing suite (i.e. multi OS/arch) in the CI system. (#1567)\n\n### Fixed\n\n- The sequential timing check of timestamps in the stdout exporter are now setup explicitly to be sequential (#1571). (#1572)\n- Windows build of Jaeger tests now compiles with OS specific functions (#1576). (#1577)\n- The sequential timing check of timestamps of go.opentelemetry.io/otel/sdk/metric/aggregator/lastvalue are now setup explicitly to be sequential (#1578). (#1579)\n- Validate tracestate header keys with vendors according to the W3C TraceContext specification (#1475). (#1581)\n- The OTLP exporter includes related labels for translations of a GaugeArray (#1563). (#1570)\n\n## [0.17.0] - 2021-02-12\n\n### Changed\n\n- Rename project default branch from `master` to `main`. (#1505)\n- Reverse order in which `Resource` attributes are merged, per change in spec. (#1501)\n- Add tooling to maintain \"replace\" directives in go.mod files automatically. (#1528)\n- Create new modules: otel/metric, otel/trace, otel/oteltest, otel/sdk/export/metric, otel/sdk/metric (#1528)\n- Move metric-related public global APIs from otel to otel/metric/global. (#1528)\n\n## Fixed\n\n- Fixed otlpgrpc reconnection issue.\n- The example code in the README.md of `go.opentelemetry.io/otel/exporters/otlp` is moved to a compiled example test and used the new `WithAddress` instead of `WithEndpoint`. (#1513)\n- The otel-collector example now uses the default OTLP receiver port of the collector.\n\n## [0.16.0] - 2021-01-13\n\n### Added\n\n- Add the `ReadOnlySpan` and `ReadWriteSpan` interfaces to provide better control for accessing span data. (#1360)\n- `NewGRPCDriver` function returns a `ProtocolDriver` that maintains a single gRPC connection to the collector. (#1369)\n- Added documentation about the project's versioning policy. (#1388)\n- Added `NewSplitDriver` for OTLP exporter that allows sending traces and metrics to different endpoints. (#1418)\n- Added codeql workflow to GitHub Actions (#1428)\n- Added Gosec workflow to GitHub Actions (#1429)\n- Add new HTTP driver for OTLP exporter in `exporters/otlp/otlphttp`. Currently it only supports the binary protobuf payloads. (#1420)\n- Add an OpenCensus exporter bridge. (#1444)\n\n### Changed\n\n- Rename `internal/testing` to `internal/internaltest`. (#1449)\n- Rename `export.SpanData` to `export.SpanSnapshot` and use it only for exporting spans. (#1360)\n- Store the parent's full `SpanContext` rather than just its span ID in the `span` struct. (#1360)\n- Improve span duration accuracy. (#1360)\n- Migrated CI/CD from CircleCI to GitHub Actions (#1382)\n- Remove duplicate checkout from GitHub Actions workflow (#1407)\n- Metric `array` aggregator renamed `exact` to match its `aggregation.Kind` (#1412)\n- Metric `exact` aggregator includes per-point timestamps (#1412)\n- Metric stdout exporter uses MinMaxSumCount aggregator for ValueRecorder instruments (#1412)\n- `NewExporter` from `exporters/otlp` now takes a `ProtocolDriver` as a parameter. (#1369)\n- Many OTLP Exporter options became gRPC ProtocolDriver options. (#1369)\n- Unify endpoint API that related to OTel exporter. (#1401)\n- Optimize metric histogram aggregator to re-use its slice of buckets. (#1435)\n- Metric aggregator Count() and histogram Bucket.Counts are consistently `uint64`. (1430)\n- Histogram aggregator accepts functional options, uses default boundaries if none given. (#1434)\n- `SamplingResult` now passed a `Tracestate` from the parent `SpanContext` (#1432)\n- Moved gRPC driver for OTLP exporter to `exporters/otlp/otlpgrpc`. (#1420)\n- The `TraceContext` propagator now correctly propagates `TraceState` through the `SpanContext`. (#1447)\n- Metric Push and Pull Controller components are combined into a single \"basic\" Controller:\n  - `WithExporter()` and `Start()` to configure Push behavior\n  - `Start()` is optional; use `Collect()` and `ForEach()` for Pull behavior\n  - `Start()` and `Stop()` accept Context. (#1378)\n- The `Event` type is moved from the `otel/sdk/export/trace` package to the `otel/trace` API package. (#1452)\n\n### Removed\n\n- Remove `errUninitializedSpan` as its only usage is now obsolete. (#1360)\n- Remove Metric export functionality related to quantiles and summary data points: this is not specified (#1412)\n- Remove DDSketch metric aggregator; our intention is to re-introduce this as an option of the histogram aggregator after [new OTLP histogram data types](https://github.com/open-telemetry/opentelemetry-proto/pull/226) are released (#1412)\n\n### Fixed\n\n- `BatchSpanProcessor.Shutdown()` will now shutdown underlying `export.SpanExporter`. (#1443)\n\n## [0.15.0] - 2020-12-10\n\n### Added\n\n- The `WithIDGenerator` `TracerProviderOption` is added to the `go.opentelemetry.io/otel/trace` package to configure an `IDGenerator` for the `TracerProvider`. (#1363)\n\n### Changed\n\n- The Zipkin exporter now uses the Span status code to determine. (#1328)\n- `NewExporter` and `Start` functions in `go.opentelemetry.io/otel/exporters/otlp` now receive `context.Context` as a first parameter. (#1357)\n- Move the OpenCensus example into `example` directory. (#1359)\n- Moved the SDK's `internal.IDGenerator` interface in to the `sdk/trace` package to enable support for externally-defined ID generators. (#1363)\n- Bump `github.com/google/go-cmp` from 0.5.3 to 0.5.4 (#1374)\n- Bump `github.com/golangci/golangci-lint` in `/internal/tools` (#1375)\n\n### Fixed\n\n- Metric SDK `SumObserver` and `UpDownSumObserver` instruments correctness fixes. (#1381)\n\n## [0.14.0] - 2020-11-19\n\n### Added\n\n- An `EventOption` and the related `NewEventConfig` function are added to the `go.opentelemetry.io/otel` package to configure Span events. (#1254)\n- A `TextMapPropagator` and associated `TextMapCarrier` are added to the `go.opentelemetry.io/otel/oteltest` package to test `TextMap` type propagators and their use. (#1259)\n- `SpanContextFromContext` returns `SpanContext` from context. (#1255)\n- `TraceState` has been added to `SpanContext`. (#1340)\n- `DeploymentEnvironmentKey` added to `go.opentelemetry.io/otel/semconv` package. (#1323)\n- Add an OpenCensus to OpenTelemetry tracing bridge. (#1305)\n- Add a parent context argument to `SpanProcessor.OnStart` to follow the specification. (#1333)\n- Add missing tests for `sdk/trace/attributes_map.go`. (#1337)\n\n### Changed\n\n- Move the `go.opentelemetry.io/otel/api/trace` package into `go.opentelemetry.io/otel/trace` with the following changes. (#1229) (#1307)\n  - `ID` has been renamed to `TraceID`.\n  - `IDFromHex` has been renamed to `TraceIDFromHex`.\n  - `EmptySpanContext` is removed.\n- Move the `go.opentelemetry.io/otel/api/trace/tracetest` package into `go.opentelemetry.io/otel/oteltest`. (#1229)\n- OTLP Exporter updates:\n  - supports OTLP v0.6.0 (#1230, #1354)\n  - supports configurable aggregation temporality (default: Cumulative, optional: Stateless). (#1296)\n- The Sampler is now called on local child spans. (#1233)\n- The `Kind` type from the `go.opentelemetry.io/otel/api/metric` package was renamed to `InstrumentKind` to more specifically describe what it is and avoid semantic ambiguity. (#1240)\n- The `MetricKind` method of the `Descriptor` type in the `go.opentelemetry.io/otel/api/metric` package was renamed to `Descriptor.InstrumentKind`.\n   This matches the returned type and fixes misuse of the term metric. (#1240)\n- Move test harness from the `go.opentelemetry.io/otel/api/apitest` package into `go.opentelemetry.io/otel/oteltest`. (#1241)\n- Move the `go.opentelemetry.io/otel/api/metric/metrictest` package into `go.opentelemetry.io/oteltest` as part of #964. (#1252)\n- Move the `go.opentelemetry.io/otel/api/metric` package into `go.opentelemetry.io/otel/metric` as part of #1303. (#1321)\n- Move the `go.opentelemetry.io/otel/api/metric/registry` package into `go.opentelemetry.io/otel/metric/registry` as a part of #1303. (#1316)\n- Move the `Number` type (together with related functions) from `go.opentelemetry.io/otel/api/metric` package into `go.opentelemetry.io/otel/metric/number` as a part of #1303. (#1316)\n- The function signature of the Span `AddEvent` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required name and a variable number of `EventOption`s. (#1254)\n- The function signature of the Span `RecordError` method in `go.opentelemetry.io/otel` is updated to no longer take an unused context and instead take a required error value and a variable number of `EventOption`s. (#1254)\n- Move the `go.opentelemetry.io/otel/api/global` package to `go.opentelemetry.io/otel`. (#1262) (#1330)\n- Move the `Version` function from `go.opentelemetry.io/otel/sdk` to `go.opentelemetry.io/otel`. (#1330)\n- Rename correlation context header from `\"otcorrelations\"` to `\"baggage\"` to match the OpenTelemetry specification. (#1267)\n- Fix `Code.UnmarshalJSON` to work with valid JSON only. (#1276)\n- The `resource.New()` method changes signature to support builtin attributes and functional options, including `telemetry.sdk.*` and\n  `host.name` semantic conventions; the former method is renamed `resource.NewWithAttributes`. (#1235)\n- The Prometheus exporter now exports non-monotonic counters (i.e. `UpDownCounter`s) as gauges. (#1210)\n- Correct the `Span.End` method documentation in the `otel` API to state updates are not allowed on a span after it has ended. (#1310)\n- Updated span collection limits for attribute, event and link counts to 1000 (#1318)\n- Renamed `semconv.HTTPUrlKey` to `semconv.HTTPURLKey`. (#1338)\n\n### Removed\n\n- The `ErrInvalidHexID`, `ErrInvalidTraceIDLength`, `ErrInvalidSpanIDLength`, `ErrInvalidSpanIDLength`, or `ErrNilSpanID` from the `go.opentelemetry.io/otel` package are unexported now. (#1243)\n- The `AddEventWithTimestamp` method on the `Span` interface in `go.opentelemetry.io/otel` is removed due to its redundancy.\n   It is replaced by using the `AddEvent` method with a `WithTimestamp` option. (#1254)\n- The `MockSpan` and `MockTracer` types are removed from `go.opentelemetry.io/otel/oteltest`.\n   `Tracer` and `Span` from the same module should be used in their place instead. (#1306)\n- `WorkerCount` option is removed from `go.opentelemetry.io/otel/exporters/otlp`. (#1350)\n- Remove the following labels types: INT32, UINT32, UINT64 and FLOAT32. (#1314)\n\n### Fixed\n\n- Rename `MergeItererator` to `MergeIterator` in the `go.opentelemetry.io/otel/label` package. (#1244)\n- The `go.opentelemetry.io/otel/api/global` packages global TextMapPropagator now delegates functionality to a globally set delegate for all previously returned propagators. (#1258)\n- Fix condition in `label.Any`. (#1299)\n- Fix global `TracerProvider` to pass options to its configured provider. (#1329)\n- Fix missing handler for `ExactKind` aggregator in OTLP metrics transformer (#1309)\n\n## [0.13.0] - 2020-10-08\n\n### Added\n\n- OTLP Metric exporter supports Histogram aggregation. (#1209)\n- The `Code` struct from the `go.opentelemetry.io/otel/codes` package now supports JSON marshaling and unmarshaling as well as implements the `Stringer` interface. (#1214)\n- A Baggage API to implement the OpenTelemetry specification. (#1217)\n- Add Shutdown method to sdk/trace/provider, shutdown processors in the order they were registered. (#1227)\n\n### Changed\n\n- Set default propagator to no-op propagator. (#1184)\n- The `HTTPSupplier`, `HTTPExtractor`, `HTTPInjector`, and `HTTPPropagator` from the `go.opentelemetry.io/otel/api/propagation` package were replaced with unified `TextMapCarrier` and `TextMapPropagator` in the `go.opentelemetry.io/otel/propagation` package. (#1212) (#1325)\n- The `New` function from the `go.opentelemetry.io/otel/api/propagation` package was replaced with `NewCompositeTextMapPropagator` in the `go.opentelemetry.io/otel` package. (#1212)\n- The status codes of the `go.opentelemetry.io/otel/codes` package have been updated to match the latest OpenTelemetry specification.\n   They now are `Unset`, `Error`, and `Ok`.\n   They no longer track the gRPC codes. (#1214)\n- The `StatusCode` field of the `SpanData` struct in the `go.opentelemetry.io/otel/sdk/export/trace` package now uses the codes package from this package instead of the gRPC project. (#1214)\n- Move the `go.opentelemetry.io/otel/api/baggage` package into `go.opentelemetry.io/otel/baggage`. (#1217) (#1325)\n- A `Shutdown` method of `SpanProcessor` and all its implementations receives a context and returns an error. (#1264)\n\n### Fixed\n\n- Copies of data from arrays and slices passed to `go.opentelemetry.io/otel/label.ArrayValue()` are now used in the returned `Value` instead of using the mutable data itself. (#1226)\n\n### Removed\n\n- The `ExtractHTTP` and `InjectHTTP` functions from the `go.opentelemetry.io/otel/api/propagation` package were removed. (#1212)\n- The `Propagators` interface from the `go.opentelemetry.io/otel/api/propagation` package was removed to conform to the OpenTelemetry specification.\n   The explicit `TextMapPropagator` type can be used in its place as this is the `Propagator` type the specification defines. (#1212)\n- The `SetAttribute` method of the `Span` from the `go.opentelemetry.io/otel/api/trace` package was removed given its redundancy with the `SetAttributes` method. (#1216)\n- The internal implementation of Baggage storage is removed in favor of using the new Baggage API functionality. (#1217)\n- Remove duplicate hostname key `HostHostNameKey` in Resource semantic conventions. (#1219)\n- Nested array/slice support has been removed. (#1226)\n\n## [0.12.0] - 2020-09-24\n\n### Added\n\n- A `SpanConfigure` function in `go.opentelemetry.io/otel/api/trace` to create a new `SpanConfig` from `SpanOption`s. (#1108)\n- In the `go.opentelemetry.io/otel/api/trace` package, `NewTracerConfig` was added to construct new `TracerConfig`s.\n   This addition was made to conform with our project option conventions. (#1155)\n- Instrumentation library information was added to the Zipkin exporter. (#1119)\n- The `SpanProcessor` interface now has a `ForceFlush()` method. (#1166)\n- More semantic conventions for k8s as resource attributes. (#1167)\n\n### Changed\n\n- Add reconnecting udp connection type to Jaeger exporter.\n   This change adds a new optional implementation of the udp conn interface used to detect changes to an agent's host dns record.\n   It then adopts the new destination address to ensure the exporter doesn't get stuck. This change was ported from jaegertracing/jaeger-client-go#520. (#1063)\n- Replace `StartOption` and `EndOption` in `go.opentelemetry.io/otel/api/trace` with `SpanOption`.\n   This change is matched by replacing the `StartConfig` and `EndConfig` with a unified `SpanConfig`. (#1108)\n- Replace the `LinkedTo` span option in `go.opentelemetry.io/otel/api/trace` with `WithLinks`.\n   This is be more consistent with our other option patterns, i.e. passing the item to be configured directly instead of its component parts, and provides a cleaner function signature. (#1108)\n- The `go.opentelemetry.io/otel/api/trace` `TracerOption` was changed to an interface to conform to project option conventions. (#1109)\n- Move the `B3` and `TraceContext` from within the `go.opentelemetry.io/otel/api/trace` package to their own `go.opentelemetry.io/otel/propagators` package.\n    This removal of the propagators is reflective of the OpenTelemetry specification for these propagators as well as cleans up the `go.opentelemetry.io/otel/api/trace` API. (#1118)\n- Rename Jaeger tags used for instrumentation library information to reflect changes in OpenTelemetry specification. (#1119)\n- Rename `ProbabilitySampler` to `TraceIDRatioBased` and change semantics to ignore parent span sampling status. (#1115)\n- Move `tools` package under `internal`. (#1141)\n- Move `go.opentelemetry.io/otel/api/correlation` package to `go.opentelemetry.io/otel/api/baggage`. (#1142)\n   The `correlation.CorrelationContext` propagator has been renamed `baggage.Baggage`.  Other exported functions and types are unchanged.\n- Rename `ParentOrElse` sampler to `ParentBased` and allow setting samplers depending on parent span. (#1153)\n- In the `go.opentelemetry.io/otel/api/trace` package, `SpanConfigure` was renamed to `NewSpanConfig`. (#1155)\n- Change `dependabot.yml` to add a `Skip Changelog` label to dependabot-sourced PRs. (#1161)\n- The [configuration style guide](https://github.com/open-telemetry/opentelemetry-go/blob/master/CONTRIBUTING.md#config) has been updated to\n   recommend the use of `newConfig()` instead of `configure()`. (#1163)\n- The `otlp.Config` type has been unexported and changed to `otlp.config`, along with its initializer. (#1163)\n- Ensure exported interface types include parameter names and update the\n   Style Guide to reflect this styling rule. (#1172)\n- Don't consider unset environment variable for resource detection to be an error. (#1170)\n- Rename `go.opentelemetry.io/otel/api/metric.ConfigureInstrument` to `NewInstrumentConfig` and\n  `go.opentelemetry.io/otel/api/metric.ConfigureMeter` to `NewMeterConfig`.\n- ValueObserver instruments use LastValue aggregator by default. (#1165)\n- OTLP Metric exporter supports LastValue aggregation. (#1165)\n- Move the `go.opentelemetry.io/otel/api/unit` package to `go.opentelemetry.io/otel/unit`. (#1185)\n- Rename `Provider` to `MeterProvider` in the `go.opentelemetry.io/otel/api/metric` package. (#1190)\n- Rename `NoopProvider` to `NoopMeterProvider` in the `go.opentelemetry.io/otel/api/metric` package. (#1190)\n- Rename `NewProvider` to `NewMeterProvider` in the `go.opentelemetry.io/otel/api/metric/metrictest` package. (#1190)\n- Rename `Provider` to `MeterProvider` in the `go.opentelemetry.io/otel/api/metric/registry` package. (#1190)\n- Rename `NewProvider` to `NewMeterProvider` in the `go.opentelemetry.io/otel/api/metri/registryc` package. (#1190)\n- Rename `Provider` to `TracerProvider` in the `go.opentelemetry.io/otel/api/trace` package. (#1190)\n- Rename `NoopProvider` to `NoopTracerProvider` in the `go.opentelemetry.io/otel/api/trace` package. (#1190)\n- Rename `Provider` to `TracerProvider` in the `go.opentelemetry.io/otel/api/trace/tracetest` package. (#1190)\n- Rename `NewProvider` to `NewTracerProvider` in the `go.opentelemetry.io/otel/api/trace/tracetest` package. (#1190)\n- Rename `WrapperProvider` to `WrapperTracerProvider` in the `go.opentelemetry.io/otel/bridge/opentracing` package. (#1190)\n- Rename `NewWrapperProvider` to `NewWrapperTracerProvider` in the `go.opentelemetry.io/otel/bridge/opentracing` package. (#1190)\n- Rename `Provider` method of the pull controller to `MeterProvider` in the `go.opentelemetry.io/otel/sdk/metric/controller/pull` package. (#1190)\n- Rename `Provider` method of the push controller to `MeterProvider` in the `go.opentelemetry.io/otel/sdk/metric/controller/push` package. (#1190)\n- Rename `ProviderOptions` to `TracerProviderConfig` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Rename `ProviderOption` to `TracerProviderOption` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Rename `Provider` to `TracerProvider` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Rename `NewProvider` to `NewTracerProvider` in the `go.opentelemetry.io/otel/sdk/trace` package. (#1190)\n- Renamed `SamplingDecision` values to comply with OpenTelemetry specification change. (#1192)\n- Renamed Zipkin attribute names from `ot.status_code & ot.status_description` to `otel.status_code & otel.status_description`. (#1201)\n- The default SDK now invokes registered `SpanProcessor`s in the order they were registered with the `TracerProvider`. (#1195)\n- Add test of spans being processed by the `SpanProcessor`s in the order they were registered. (#1203)\n\n### Removed\n\n- Remove the B3 propagator from `go.opentelemetry.io/otel/propagators`. It is now located in the\n   `go.opentelemetry.io/contrib/propagators/` module. (#1191)\n- Remove the semantic convention for HTTP status text, `HTTPStatusTextKey` from package `go.opentelemetry.io/otel/semconv`. (#1194)\n\n### Fixed\n\n- Zipkin example no longer mentions `ParentSampler`, corrected to `ParentBased`. (#1171)\n- Fix missing shutdown processor in otel-collector example. (#1186)\n- Fix missing shutdown processor in basic and namedtracer examples. (#1197)\n\n## [0.11.0] - 2020-08-24\n\n### Added\n\n- Support for exporting array-valued attributes via OTLP. (#992)\n- `Noop` and `InMemory` `SpanBatcher` implementations to help with testing integrations. (#994)\n- Support for filtering metric label sets. (#1047)\n- A dimensionality-reducing metric Processor. (#1057)\n- Integration tests for more OTel Collector Attribute types. (#1062)\n- A new `WithSpanProcessor` `ProviderOption` is added to the `go.opentelemetry.io/otel/sdk/trace` package to create a `Provider` and automatically register the `SpanProcessor`. (#1078)\n\n### Changed\n\n- Rename `sdk/metric/processor/test` to `sdk/metric/processor/processortest`. (#1049)\n- Rename `sdk/metric/controller/test` to `sdk/metric/controller/controllertest`. (#1049)\n- Rename `api/testharness` to `api/apitest`. (#1049)\n- Rename `api/trace/testtrace` to `api/trace/tracetest`. (#1049)\n- Change Metric Processor to merge multiple observations. (#1024)\n- The `go.opentelemetry.io/otel/bridge/opentracing` bridge package has been made into its own module.\n   This removes the package dependencies of this bridge from the rest of the OpenTelemetry based project. (#1038)\n- Renamed `go.opentelemetry.io/otel/api/standard` package to `go.opentelemetry.io/otel/semconv` to avoid the ambiguous and generic name `standard` and better describe the package as containing OpenTelemetry semantic conventions. (#1016)\n- The environment variable used for resource detection has been changed from `OTEL_RESOURCE_LABELS` to `OTEL_RESOURCE_ATTRIBUTES` (#1042)\n- Replace `WithSyncer` with `WithBatcher` in examples. (#1044)\n- Replace the `google.golang.org/grpc/codes` dependency in the API with an equivalent `go.opentelemetry.io/otel/codes` package. (#1046)\n- Merge the `go.opentelemetry.io/otel/api/label` and `go.opentelemetry.io/otel/api/kv` into the new `go.opentelemetry.io/otel/label` package. (#1060)\n- Unify Callback Function Naming.\n   Rename `*Callback` with `*Func`. (#1061)\n- CI builds validate against last two versions of Go, dropping 1.13 and adding 1.15. (#1064)\n- The `go.opentelemetry.io/otel/sdk/export/trace` interfaces `SpanSyncer` and `SpanBatcher` have been replaced with a specification compliant `Exporter` interface.\n   This interface still supports the export of `SpanData`, but only as a slice.\n   Implementation are also required now to return any error from `ExportSpans` if one occurs as well as implement a `Shutdown` method for exporter clean-up. (#1078)\n- The `go.opentelemetry.io/otel/sdk/trace` `NewBatchSpanProcessor` function no longer returns an error.\n   If a `nil` exporter is passed as an argument to this function, instead of it returning an error, it now returns a `BatchSpanProcessor` that handles the export of `SpanData` by not taking any action. (#1078)\n- The `go.opentelemetry.io/otel/sdk/trace` `NewProvider` function to create a `Provider` no longer returns an error, instead only a `*Provider`.\n   This change is related to `NewBatchSpanProcessor` not returning an error which was the only error this function would return. (#1078)\n\n### Removed\n\n- Duplicate, unused API sampler interface. (#999)\n   Use the [`Sampler` interface](https://github.com/open-telemetry/opentelemetry-go/blob/v0.11.0/sdk/trace/sampling.go) provided by the SDK instead.\n- The `grpctrace` instrumentation was moved to the `go.opentelemetry.io/contrib` repository and out of this repository.\n   This move includes moving the `grpc` example to the `go.opentelemetry.io/contrib` as well. (#1027)\n- The `WithSpan` method of the `Tracer` interface.\n   The functionality this method provided was limited compared to what a user can provide themselves.\n   It was removed with the understanding that if there is sufficient user need it can be added back based on actual user usage. (#1043)\n- The `RegisterSpanProcessor` and `UnregisterSpanProcessor` functions.\n   These were holdovers from an approach prior to the TracerProvider design. They were not used anymore. (#1077)\n- The `oterror` package. (#1026)\n- The `othttp` and `httptrace` instrumentations were moved to `go.opentelemetry.io/contrib`. (#1032)\n\n### Fixed\n\n- The `semconv.HTTPServerMetricAttributesFromHTTPRequest()` function no longer generates the high-cardinality `http.request.content.length` label. (#1031)\n- Correct instrumentation version tag in Jaeger exporter. (#1037)\n- The SDK span will now set an error event if the `End` method is called during a panic (i.e. it was deferred). (#1043)\n- Move internally generated protobuf code from the `go.opentelemetry.io/otel` to the OTLP exporter to reduce dependency overhead. (#1050)\n- The `otel-collector` example referenced outdated collector processors. (#1006)\n\n## [0.10.0] - 2020-07-29\n\nThis release migrates the default OpenTelemetry SDK into its own Go module, decoupling the SDK from the API and reducing dependencies for instrumentation packages.\n\n### Added\n\n- The Zipkin exporter now has `NewExportPipeline` and `InstallNewPipeline` constructor functions to match the common pattern.\n    These function build a new exporter with default SDK options and register the exporter with the `global` package respectively. (#944)\n- Add propagator option for gRPC instrumentation. (#986)\n- The `testtrace` package now tracks the `trace.SpanKind` for each span. (#987)\n\n### Changed\n\n- Replace the `RegisterGlobal` `Option` in the Jaeger exporter with an `InstallNewPipeline` constructor function.\n   This matches the other exporter constructor patterns and will register a new exporter after building it with default configuration. (#944)\n- The trace (`go.opentelemetry.io/otel/exporters/trace/stdout`) and metric (`go.opentelemetry.io/otel/exporters/metric/stdout`) `stdout` exporters are now merged into a single exporter at `go.opentelemetry.io/otel/exporters/stdout`.\n   This new exporter was made into its own Go module to follow the pattern of all exporters and decouple it from the `go.opentelemetry.io/otel` module. (#956, #963)\n- Move the `go.opentelemetry.io/otel/exporters/test` test package to `go.opentelemetry.io/otel/sdk/export/metric/metrictest`. (#962)\n- The `go.opentelemetry.io/otel/api/kv/value` package was merged into the parent `go.opentelemetry.io/otel/api/kv` package. (#968)\n  - `value.Bool` was replaced with `kv.BoolValue`.\n  - `value.Int64` was replaced with `kv.Int64Value`.\n  - `value.Uint64` was replaced with `kv.Uint64Value`.\n  - `value.Float64` was replaced with `kv.Float64Value`.\n  - `value.Int32` was replaced with `kv.Int32Value`.\n  - `value.Uint32` was replaced with `kv.Uint32Value`.\n  - `value.Float32` was replaced with `kv.Float32Value`.\n  - `value.String` was replaced with `kv.StringValue`.\n  - `value.Int` was replaced with `kv.IntValue`.\n  - `value.Uint` was replaced with `kv.UintValue`.\n  - `value.Array` was replaced with `kv.ArrayValue`.\n- Rename `Infer` to `Any` in the `go.opentelemetry.io/otel/api/kv` package. (#972)\n- Change `othttp` to use the `httpsnoop` package to wrap the `ResponseWriter` so that optional interfaces (`http.Hijacker`, `http.Flusher`, etc.) that are implemented by the original `ResponseWriter`are also implemented by the wrapped `ResponseWriter`. (#979)\n- Rename `go.opentelemetry.io/otel/sdk/metric/aggregator/test` package to `go.opentelemetry.io/otel/sdk/metric/aggregator/aggregatortest`. (#980)\n- Make the SDK into its own Go module called `go.opentelemetry.io/otel/sdk`. (#985)\n- Changed the default trace `Sampler` from `AlwaysOn` to `ParentOrElse(AlwaysOn)`. (#989)\n\n### Removed\n\n- The `IndexedAttribute` function from the `go.opentelemetry.io/otel/api/label` package was removed in favor of `IndexedLabel` which it was synonymous with. (#970)\n\n### Fixed\n\n- Bump github.com/golangci/golangci-lint from 1.28.3 to 1.29.0 in /tools. (#953)\n- Bump github.com/google/go-cmp from 0.5.0 to 0.5.1. (#957)\n- Use `global.Handle` for span export errors in the OTLP exporter. (#946)\n- Correct Go language formatting in the README documentation. (#961)\n- Remove default SDK dependencies from the `go.opentelemetry.io/otel/api` package. (#977)\n- Remove default SDK dependencies from the `go.opentelemetry.io/otel/instrumentation` package. (#983)\n- Move documented examples for `go.opentelemetry.io/otel/instrumentation/grpctrace` interceptors into Go example tests. (#984)\n\n## [0.9.0] - 2020-07-20\n\n### Added\n\n- A new Resource Detector interface is included to allow resources to be automatically detected and included. (#939)\n- A Detector to automatically detect resources from an environment variable. (#939)\n- Github action to generate protobuf Go bindings locally in `internal/opentelemetry-proto-gen`. (#938)\n- OTLP .proto files from `open-telemetry/opentelemetry-proto` imported as a git submodule under `internal/opentelemetry-proto`.\n   References to `github.com/open-telemetry/opentelemetry-proto` changed to `go.opentelemetry.io/otel/internal/opentelemetry-proto-gen`. (#942)\n\n### Changed\n\n- Non-nil value `struct`s for key-value pairs will be marshalled using JSON rather than `Sprintf`. (#948)\n\n### Removed\n\n- Removed dependency on `github.com/open-telemetry/opentelemetry-collector`. (#943)\n\n## [0.8.0] - 2020-07-09\n\n### Added\n\n- The `B3Encoding` type to represent the B3 encoding(s) the B3 propagator can inject.\n   A value for HTTP supported encodings (Multiple Header: `MultipleHeader`, Single Header: `SingleHeader`) are included. (#882)\n- The `FlagsDeferred` trace flag to indicate if the trace sampling decision has been deferred. (#882)\n- The `FlagsDebug` trace flag to indicate if the trace is a debug trace. (#882)\n- Add `peer.service` semantic attribute. (#898)\n- Add database-specific semantic attributes. (#899)\n- Add semantic convention for `faas.coldstart` and `container.id`. (#909)\n- Add http content size semantic conventions. (#905)\n- Include `http.request_content_length` in HTTP request basic attributes. (#905)\n- Add semantic conventions for operating system process resource attribute keys. (#919)\n- The Jaeger exporter now has a `WithBatchMaxCount` option to specify the maximum number of spans sent in a batch. (#931)\n\n### Changed\n\n- Update `CONTRIBUTING.md` to ask for updates to `CHANGELOG.md` with each pull request. (#879)\n- Use lowercase header names for B3 Multiple Headers. (#881)\n- The B3 propagator `SingleHeader` field has been replaced with `InjectEncoding`.\n   This new field can be set to combinations of the `B3Encoding` bitmasks and will inject trace information in these encodings.\n   If no encoding is set, the propagator will default to `MultipleHeader` encoding. (#882)\n- The B3 propagator now extracts from either HTTP encoding of B3 (Single Header or Multiple Header) based on what is contained in the header.\n   Preference is given to Single Header encoding with Multiple Header being the fallback if Single Header is not found or is invalid.\n   This behavior change is made to dynamically support all correctly encoded traces received instead of having to guess the expected encoding prior to receiving. (#882)\n- Extend semantic conventions for RPC. (#900)\n- To match constant naming conventions in the `api/standard` package, the `FaaS*` key names are appended with a suffix of `Key`. (#920)\n  - `\"api/standard\".FaaSName` -> `FaaSNameKey`\n  - `\"api/standard\".FaaSID` -> `FaaSIDKey`\n  - `\"api/standard\".FaaSVersion` -> `FaaSVersionKey`\n  - `\"api/standard\".FaaSInstance` -> `FaaSInstanceKey`\n\n### Removed\n\n- The `FlagsUnused` trace flag is removed.\n   The purpose of this flag was to act as the inverse of `FlagsSampled`, the inverse of `FlagsSampled` is used instead. (#882)\n- The B3 header constants (`B3SingleHeader`, `B3DebugFlagHeader`, `B3TraceIDHeader`, `B3SpanIDHeader`, `B3SampledHeader`, `B3ParentSpanIDHeader`) are removed.\n   If B3 header keys are needed [the authoritative OpenZipkin package constants](https://pkg.go.dev/github.com/openzipkin/zipkin-go@v0.2.2/propagation/b3?tab=doc#pkg-constants) should be used instead. (#882)\n\n### Fixed\n\n- The B3 Single Header name is now correctly `b3` instead of the previous `X-B3`. (#881)\n- The B3 propagator now correctly supports sampling only values (`b3: 0`, `b3: 1`, or `b3: d`) for a Single B3 Header. (#882)\n- The B3 propagator now propagates the debug flag.\n   This removes the behavior of changing the debug flag into a set sampling bit.\n   Instead, this now follow the B3 specification and omits the `X-B3-Sampling` header. (#882)\n- The B3 propagator now tracks \"unset\" sampling state (meaning \"defer the decision\") and does not set the `X-B3-Sampling` header when injecting. (#882)\n- Bump github.com/itchyny/gojq from 0.10.3 to 0.10.4 in /tools. (#883)\n- Bump github.com/opentracing/opentracing-go from v1.1.1-0.20190913142402-a7454ce5950e to v1.2.0. (#885)\n- The tracing time conversion for OTLP spans is now correctly set to `UnixNano`. (#896)\n- Ensure span status is not set to `Unknown` when no HTTP status code is provided as it is assumed to be `200 OK`. (#908)\n- Ensure `httptrace.clientTracer` closes `http.headers` span. (#912)\n- Prometheus exporter will not apply stale updates or forget inactive metrics. (#903)\n- Add test for api.standard `HTTPClientAttributesFromHTTPRequest`. (#905)\n- Bump github.com/golangci/golangci-lint from 1.27.0 to 1.28.1 in /tools. (#901, #913)\n- Update otel-colector example to use the v0.5.0 collector. (#915)\n- The `grpctrace` instrumentation uses a span name conforming to the OpenTelemetry semantic conventions (does not contain a leading slash (`/`)). (#922)\n- The `grpctrace` instrumentation includes an `rpc.method` attribute now set to the gRPC method name. (#900, #922)\n- The `grpctrace` instrumentation `rpc.service` attribute now contains the package name if one exists.\n   This is in accordance with OpenTelemetry semantic conventions. (#922)\n- Correlation Context extractor will no longer insert an empty map into the returned context when no valid values are extracted. (#923)\n- Bump google.golang.org/api from 0.28.0 to 0.29.0 in /exporters/trace/jaeger. (#925)\n- Bump github.com/itchyny/gojq from 0.10.4 to 0.11.0 in /tools. (#926)\n- Bump github.com/golangci/golangci-lint from 1.28.1 to 1.28.2 in /tools. (#930)\n\n## [0.7.0] - 2020-06-26\n\nThis release implements the v0.5.0 version of the OpenTelemetry specification.\n\n### Added\n\n- The othttp instrumentation now includes default metrics. (#861)\n- This CHANGELOG file to track all changes in the project going forward.\n- Support for array type attributes. (#798)\n- Apply transitive dependabot go.mod dependency updates as part of a new automatic Github workflow. (#844)\n- Timestamps are now passed to exporters for each export. (#835)\n- Add new `Accumulation` type to metric SDK to transport telemetry from `Accumulator`s to `Processor`s.\n   This replaces the prior `Record` `struct` use for this purpose. (#835)\n- New dependabot integration to automate package upgrades. (#814)\n- `Meter` and `Tracer` implementations accept instrumentation version version as an optional argument.\n   This instrumentation version is passed on to exporters. (#811) (#805) (#802)\n- The OTLP exporter includes the instrumentation version in telemetry it exports. (#811)\n- Environment variables for Jaeger exporter are supported. (#796)\n- New `aggregation.Kind` in the export metric API. (#808)\n- New example that uses OTLP and the collector. (#790)\n- Handle errors in the span `SetName` during span initialization. (#791)\n- Default service config to enable retries for retry-able failed requests in the OTLP exporter and an option to override this default. (#777)\n- New `go.opentelemetry.io/otel/api/oterror` package to uniformly support error handling and definitions for the project. (#778)\n- New `global` default implementation of the `go.opentelemetry.io/otel/api/oterror.Handler` interface to be used to handle errors prior to an user defined `Handler`.\n   There is also functionality for the user to register their `Handler` as well as a convenience function `Handle` to handle an error with this global `Handler`(#778)\n- Options to specify propagators for httptrace and grpctrace instrumentation. (#784)\n- The required `application/json` header for the Zipkin exporter is included in all exports. (#774)\n- Integrate HTTP semantics helpers from the contrib repository into the `api/standard` package. #769\n\n### Changed\n\n- Rename `Integrator` to `Processor` in the metric SDK. (#863)\n- Rename `AggregationSelector` to `AggregatorSelector`. (#859)\n- Rename `SynchronizedCopy` to `SynchronizedMove`. (#858)\n- Rename `simple` integrator to `basic` integrator. (#857)\n- Merge otlp collector examples. (#841)\n- Change the metric SDK to support cumulative, delta, and pass-through exporters directly.\n   With these changes, cumulative and delta specific exporters are able to request the correct kind of aggregation from the SDK. (#840)\n- The `Aggregator.Checkpoint` API is renamed to `SynchronizedCopy` and adds an argument, a different `Aggregator` into which the copy is stored. (#812)\n- The `export.Aggregator` contract is that `Update()` and `SynchronizedCopy()` are synchronized with each other.\n   All the aggregation interfaces (`Sum`, `LastValue`, ...) are not meant to be synchronized, as the caller is expected to synchronize aggregators at a higher level after the `Accumulator`.\n   Some of the `Aggregators` used unnecessary locking and that has been cleaned up. (#812)\n- Use of `metric.Number` was replaced by `int64` now that we use `sync.Mutex` in the `MinMaxSumCount` and `Histogram` `Aggregators`. (#812)\n- Replace `AlwaysParentSample` with `ParentSample(fallback)` to match the OpenTelemetry v0.5.0 specification. (#810)\n- Rename `sdk/export/metric/aggregator` to `sdk/export/metric/aggregation`. #808\n- Send configured headers with every request in the OTLP exporter, instead of just on connection creation. (#806)\n- Update error handling for any one off error handlers, replacing, instead, with the `global.Handle` function. (#791)\n- Rename `plugin` directory to `instrumentation` to match the OpenTelemetry specification. (#779)\n- Makes the argument order to Histogram and DDSketch `New()` consistent. (#781)\n\n### Removed\n\n- `Uint64NumberKind` and related functions from the API. (#864)\n- Context arguments from `Aggregator.Checkpoint` and `Integrator.Process` as they were unused. (#803)\n- `SpanID` is no longer included in parameters for sampling decision to match the OpenTelemetry specification. (#775)\n\n### Fixed\n\n- Upgrade OTLP exporter to opentelemetry-proto matching the opentelemetry-collector v0.4.0 release. (#866)\n- Allow changes to `go.sum` and `go.mod` when running dependabot tidy-up. (#871)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1. (#824)\n- Bump github.com/prometheus/client_golang from 1.7.0 to 1.7.1 in /exporters/metric/prometheus. (#867)\n- Bump google.golang.org/grpc from 1.29.1 to 1.30.0 in /exporters/trace/jaeger. (#853)\n- Bump google.golang.org/grpc from 1.29.1 to 1.30.0 in /exporters/trace/zipkin. (#854)\n- Bumps github.com/golang/protobuf from 1.3.2 to 1.4.2 (#848)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/otlp (#817)\n- Bump github.com/golangci/golangci-lint from 1.25.1 to 1.27.0 in /tools (#828)\n- Bump github.com/prometheus/client_golang from 1.5.0 to 1.7.0 in /exporters/metric/prometheus (#838)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/trace/jaeger (#829)\n- Bump github.com/benbjohnson/clock from 1.0.0 to 1.0.3 (#815)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/trace/zipkin (#823)\n- Bump github.com/itchyny/gojq from 0.10.1 to 0.10.3 in /tools (#830)\n- Bump github.com/stretchr/testify from 1.4.0 to 1.6.1 in /exporters/metric/prometheus (#822)\n- Bump google.golang.org/grpc from 1.27.1 to 1.29.1 in /exporters/trace/zipkin (#820)\n- Bump google.golang.org/grpc from 1.27.1 to 1.29.1 in /exporters/trace/jaeger (#831)\n- Bump github.com/google/go-cmp from 0.4.0 to 0.5.0 (#836)\n- Bump github.com/google/go-cmp from 0.4.0 to 0.5.0 in /exporters/trace/jaeger (#837)\n- Bump github.com/google/go-cmp from 0.4.0 to 0.5.0 in /exporters/otlp (#839)\n- Bump google.golang.org/api from 0.20.0 to 0.28.0 in /exporters/trace/jaeger (#843)\n- Set span status from HTTP status code in the othttp instrumentation. (#832)\n- Fixed typo in push controller comment. (#834)\n- The `Aggregator` testing has been updated and cleaned. (#812)\n- `metric.Number(0)` expressions are replaced by `0` where possible. (#812)\n- Fixed `global` `handler_test.go` test failure. #804\n- Fixed `BatchSpanProcessor.Shutdown` to wait until all spans are processed. (#766)\n- Fixed OTLP example's accidental early close of exporter. (#807)\n- Ensure zipkin exporter reads and closes response body. (#788)\n- Update instrumentation to use `api/standard` keys instead of custom keys. (#782)\n- Clean up tools and RELEASING documentation. (#762)\n\n## [0.6.0] - 2020-05-21\n\n### Added\n\n- Support for `Resource`s in the prometheus exporter. (#757)\n- New pull controller. (#751)\n- New `UpDownSumObserver` instrument. (#750)\n- OpenTelemetry collector demo. (#711)\n- New `SumObserver` instrument. (#747)\n- New `UpDownCounter` instrument. (#745)\n- New timeout `Option` and configuration function `WithTimeout` to the push controller. (#742)\n- New `api/standards` package to implement semantic conventions and standard key-value generation. (#731)\n\n### Changed\n\n- Rename `Register*` functions in the metric API to `New*` for all `Observer` instruments. (#761)\n- Use `[]float64` for histogram boundaries, not `[]metric.Number`. (#758)\n- Change OTLP example to use exporter as a trace `Syncer` instead of as an unneeded `Batcher`. (#756)\n- Replace `WithResourceAttributes()` with `WithResource()` in the trace SDK. (#754)\n- The prometheus exporter now uses the new pull controller. (#751)\n- Rename `ScheduleDelayMillis` to `BatchTimeout` in the trace `BatchSpanProcessor`.(#752)\n- Support use of synchronous instruments in asynchronous callbacks (#725)\n- Move `Resource` from the `Export` method parameter into the metric export `Record`. (#739)\n- Rename `Observer` instrument to `ValueObserver`. (#734)\n- The push controller now has a method (`Provider()`) to return a `metric.Provider` instead of the old `Meter` method that acted as a `metric.Provider`. (#738)\n- Replace `Measure` instrument by `ValueRecorder` instrument. (#732)\n- Rename correlation context header from `\"Correlation-Context\"` to `\"otcorrelations\"` to match the OpenTelemetry specification. (#727)\n\n### Fixed\n\n- Ensure gRPC `ClientStream` override methods do not panic in grpctrace package. (#755)\n- Disable parts of `BatchSpanProcessor` test until a fix is found. (#743)\n- Fix `string` case in `kv` `Infer` function. (#746)\n- Fix panic in grpctrace client interceptors. (#740)\n- Refactor the `api/metrics` push controller and add `CheckpointSet` synchronization. (#737)\n- Rewrite span batch process queue batching logic. (#719)\n- Remove the push controller named Meter map. (#738)\n- Fix Histogram aggregator initial state (fix #735). (#736)\n- Ensure golang alpine image is running `golang-1.14` for examples. (#733)\n- Added test for grpctrace `UnaryInterceptorClient`. (#695)\n- Rearrange `api/metric` code layout. (#724)\n\n## [0.5.0] - 2020-05-13\n\n### Added\n\n- Batch `Observer` callback support. (#717)\n- Alias `api` types to root package of project. (#696)\n- Create basic `othttp.Transport` for simple client instrumentation. (#678)\n- `SetAttribute(string, interface{})` to the trace API. (#674)\n- Jaeger exporter option that allows user to specify custom http client. (#671)\n- `Stringer` and `Infer` methods to `key`s. (#662)\n\n### Changed\n\n- Rename `NewKey` in the `kv` package to just `Key`. (#721)\n- Move `core` and `key` to `kv` package. (#720)\n- Make the metric API `Meter` a `struct` so the abstract `MeterImpl` can be passed and simplify implementation. (#709)\n- Rename SDK `Batcher` to `Integrator` to match draft OpenTelemetry SDK specification. (#710)\n- Rename SDK `Ungrouped` integrator to `simple.Integrator` to match draft OpenTelemetry SDK specification. (#710)\n- Rename SDK `SDK` `struct` to `Accumulator` to match draft OpenTelemetry SDK specification. (#710)\n- Move `Number` from `core` to `api/metric` package. (#706)\n- Move `SpanContext` from `core` to `trace` package. (#692)\n- Change traceparent header from `Traceparent` to `traceparent` to implement the W3C specification. (#681)\n\n### Fixed\n\n- Update tooling to run generators in all submodules. (#705)\n- gRPC interceptor regexp to match methods without a service name. (#683)\n- Use a `const` for padding 64-bit B3 trace IDs. (#701)\n- Update `mockZipkin` listen address from `:0` to `127.0.0.1:0`. (#700)\n- Left-pad 64-bit B3 trace IDs with zero. (#698)\n- Propagate at least the first W3C tracestate header. (#694)\n- Remove internal `StateLocker` implementation. (#688)\n- Increase instance size CI system uses. (#690)\n- Add a `key` benchmark and use reflection in `key.Infer()`. (#679)\n- Fix internal `global` test by using `global.Meter` with `RecordBatch()`. (#680)\n- Reimplement histogram using mutex instead of `StateLocker`. (#669)\n- Switch `MinMaxSumCount` to a mutex lock implementation instead of `StateLocker`. (#667)\n- Update documentation to not include any references to `WithKeys`. (#672)\n- Correct misspelling. (#668)\n- Fix clobbering of the span context if extraction fails. (#656)\n- Bump `golangci-lint` and work around the corrupting bug. (#666) (#670)\n\n## [0.4.3] - 2020-04-24\n\n### Added\n\n- `Dockerfile` and `docker-compose.yml` to run example code. (#635)\n- New `grpctrace` package that provides gRPC client and server interceptors for both unary and stream connections. (#621)\n- New `api/label` package, providing common label set implementation. (#651)\n- Support for JSON marshaling of `Resources`. (#654)\n- `TraceID` and `SpanID` implementations for `Stringer` interface. (#642)\n- `RemoteAddrKey` in the othttp plugin to include the HTTP client address in top-level spans. (#627)\n- `WithSpanFormatter` option to the othttp plugin. (#617)\n- Updated README to include section for compatible libraries and include reference to the contrib repository. (#612)\n- The prometheus exporter now supports exporting histograms. (#601)\n- A `String` method to the `Resource` to return a hashable identifier for a now unique resource. (#613)\n- An `Iter` method to the `Resource` to return an array `AttributeIterator`. (#613)\n- An `Equal` method to the `Resource` test the equivalence of resources. (#613)\n- An iterable structure (`AttributeIterator`) for `Resource` attributes.\n\n### Changed\n\n- zipkin export's `NewExporter` now requires a `serviceName` argument to ensure this needed values is provided. (#644)\n- Pass `Resources` through the metrics export pipeline. (#659)\n\n### Removed\n\n- `WithKeys` option from the metric API. (#639)\n\n### Fixed\n\n- Use the `label.Set.Equivalent` value instead of an encoding in the batcher. (#658)\n- Correct typo `trace.Exporter` to `trace.SpanSyncer` in comments. (#653)\n- Use type names for return values in jaeger exporter. (#648)\n- Increase the visibility of the `api/key` package by updating comments and fixing usages locally. (#650)\n- `Checkpoint` only after `Update`; Keep records in the `sync.Map` longer. (#647)\n- Do not cache `reflect.ValueOf()` in metric Labels. (#649)\n- Batch metrics exported from the OTLP exporter based on `Resource` and labels. (#626)\n- Add error wrapping to the prometheus exporter. (#631)\n- Update the OTLP exporter batching of traces to use a unique `string` representation of an associated `Resource` as the batching key. (#623)\n- Update OTLP `SpanData` transform to only include the `ParentSpanID` if one exists. (#614)\n- Update `Resource` internal representation to uniquely and reliably identify resources. (#613)\n- Check return value from `CheckpointSet.ForEach` in prometheus exporter. (#622)\n- Ensure spans created by httptrace client tracer reflect operation structure. (#618)\n- Create a new recorder rather than reuse when multiple observations in same epoch for asynchronous instruments. #610\n- The default port the OTLP exporter uses to connect to the OpenTelemetry collector is updated to match the one the collector listens on by default. (#611)\n\n## [0.4.2] - 2020-03-31\n\n### Fixed\n\n- Fix `pre_release.sh` to update version in `sdk/opentelemetry.go`. (#607)\n- Fix time conversion from internal to OTLP in OTLP exporter. (#606)\n\n## [0.4.1] - 2020-03-31\n\n### Fixed\n\n- Update `tag.sh` to create signed tags. (#604)\n\n## [0.4.0] - 2020-03-30\n\n### Added\n\n- New API package `api/metric/registry` that exposes a `MeterImpl` wrapper for use by SDKs to generate unique instruments. (#580)\n- Script to verify examples after a new release. (#579)\n\n### Removed\n\n- The dogstatsd exporter due to lack of support.\n   This additionally removes support for statsd. (#591)\n- `LabelSet` from the metric API.\n   This is replaced by a `[]core.KeyValue` slice. (#595)\n- `Labels` from the metric API's `Meter` interface. (#595)\n\n### Changed\n\n- The metric `export.Labels` became an interface which the SDK implements and the `export` package provides a simple, immutable implementation of this interface intended for testing purposes. (#574)\n- Renamed `internal/metric.Meter` to `MeterImpl`. (#580)\n- Renamed `api/global/internal.obsImpl` to `asyncImpl`. (#580)\n\n### Fixed\n\n- Corrected missing return in mock span. (#582)\n- Update License header for all source files to match CNCF guidelines and include a test to ensure it is present. (#586) (#596)\n- Update to v0.3.0 of the OTLP in the OTLP exporter. (#588)\n- Update pre-release script to be compatible between GNU and BSD based systems. (#592)\n- Add a `RecordBatch` benchmark. (#594)\n- Moved span transforms of the OTLP exporter to the internal package. (#593)\n- Build both go-1.13 and go-1.14 in circleci to test for all supported versions of Go. (#569)\n- Removed unneeded allocation on empty labels in OLTP exporter. (#597)\n- Update `BatchedSpanProcessor` to process the queue until no data but respect max batch size. (#599)\n- Update project documentation godoc.org links to pkg.go.dev. (#602)\n\n## [0.3.0] - 2020-03-21\n\nThis is a first official beta release, which provides almost fully complete metrics, tracing, and context propagation functionality.\nThere is still a possibility of breaking changes.\n\n### Added\n\n- Add `Observer` metric instrument. (#474)\n- Add global `Propagators` functionality to enable deferred initialization for propagators registered before the first Meter SDK is installed. (#494)\n- Simplified export setup pipeline for the jaeger exporter to match other exporters. (#459)\n- The zipkin trace exporter. (#495)\n- The OTLP exporter to export metric and trace telemetry to the OpenTelemetry collector. (#497) (#544) (#545)\n- Add `StatusMessage` field to the trace `Span`. (#524)\n- Context propagation in OpenTracing bridge in terms of OpenTelemetry context propagation. (#525)\n- The `Resource` type was added to the SDK. (#528)\n- The global API now supports a `Tracer` and `Meter` function as shortcuts to getting a global `*Provider` and calling these methods directly. (#538)\n- The metric API now defines a generic `MeterImpl` interface to support general purpose `Meter` construction.\n   Additionally, `SyncImpl` and `AsyncImpl` are added to support general purpose instrument construction. (#560)\n- A metric `Kind` is added to represent the `MeasureKind`, `ObserverKind`, and `CounterKind`. (#560)\n- Scripts to better automate the release process. (#576)\n\n### Changed\n\n- Default to to use `AlwaysSampler` instead of `ProbabilitySampler` to match OpenTelemetry specification. (#506)\n- Renamed `AlwaysSampleSampler` to `AlwaysOnSampler` in the trace API. (#511)\n- Renamed `NeverSampleSampler` to `AlwaysOffSampler` in the trace API. (#511)\n- The `Status` field of the `Span` was changed to `StatusCode` to disambiguate with the added `StatusMessage`. (#524)\n- Updated the trace `Sampler` interface conform to the OpenTelemetry specification. (#531)\n- Rename metric API `Options` to `Config`. (#541)\n- Rename metric `Counter` aggregator to be `Sum`. (#541)\n- Unify metric options into `Option` from instrument specific options. (#541)\n- The trace API's `TraceProvider` now support `Resource`s. (#545)\n- Correct error in zipkin module name. (#548)\n- The jaeger trace exporter now supports `Resource`s. (#551)\n- Metric SDK now supports `Resource`s.\n   The `WithResource` option was added to configure a `Resource` on creation and the `Resource` method was added to the metric `Descriptor` to return the associated `Resource`. (#552)\n- Replace `ErrNoLastValue` and `ErrEmptyDataSet` by `ErrNoData` in the metric SDK. (#557)\n- The stdout trace exporter now supports `Resource`s. (#558)\n- The metric `Descriptor` is now included at the API instead of the SDK. (#560)\n- Replace `Ordered` with an iterator in `export.Labels`. (#567)\n\n### Removed\n\n- The vendor specific Stackdriver. It is now hosted on 3rd party vendor infrastructure. (#452)\n- The `Unregister` method for metric observers as it is not in the OpenTelemetry specification. (#560)\n- `GetDescriptor` from the metric SDK. (#575)\n- The `Gauge` instrument from the metric API. (#537)\n\n### Fixed\n\n- Make histogram aggregator checkpoint consistent. (#438)\n- Update README with import instructions and how to build and test. (#505)\n- The default label encoding was updated to be unique. (#508)\n- Use `NewRoot` in the othttp plugin for public endpoints. (#513)\n- Fix data race in `BatchedSpanProcessor`. (#518)\n- Skip test-386 for Mac OS 10.15.x (Catalina and upwards). #521\n- Use a variable-size array to represent ordered labels in maps. (#523)\n- Update the OTLP protobuf and update changed import path. (#532)\n- Use `StateLocker` implementation in `MinMaxSumCount`. (#546)\n- Eliminate goroutine leak in histogram stress test. (#547)\n- Update OTLP exporter with latest protobuf. (#550)\n- Add filters to the othttp plugin. (#556)\n- Provide an implementation of the `Header*` filters that do not depend on Go 1.14. (#565)\n- Encode labels once during checkpoint.\n   The checkpoint function is executed in a single thread so we can do the encoding lazily before passing the encoded version of labels to the exporter.\n   This is a cheap and quick way to avoid encoding the labels on every collection interval. (#572)\n- Run coverage over all packages in `COVERAGE_MOD_DIR`. (#573)\n\n## [0.2.3] - 2020-03-04\n\n### Added\n\n- `RecordError` method on `Span`s in the trace API to Simplify adding error events to spans. (#473)\n- Configurable push frequency for exporters setup pipeline. (#504)\n\n### Changed\n\n- Rename the `exporter` directory to `exporters`.\n   The `go.opentelemetry.io/otel/exporter/trace/jaeger` package was mistakenly released with a `v1.0.0` tag instead of `v0.1.0`.\n   This resulted in all subsequent releases not becoming the default latest.\n   A consequence of this was that all `go get`s pulled in the incompatible `v0.1.0` release of that package when pulling in more recent packages from other otel packages.\n   Renaming the `exporter` directory to `exporters` fixes this issue by renaming the package and therefore clearing any existing dependency tags.\n   Consequentially, this action also renames *all* exporter packages. (#502)\n\n### Removed\n\n- The `CorrelationContextHeader` constant in the `correlation` package is no longer exported. (#503)\n\n## [0.2.2] - 2020-02-27\n\n### Added\n\n- `HTTPSupplier` interface in the propagation API to specify methods to retrieve and store a single value for a key to be associated with a carrier. (#467)\n- `HTTPExtractor` interface in the propagation API to extract information from an `HTTPSupplier` into a context. (#467)\n- `HTTPInjector` interface in the propagation API to inject information into an `HTTPSupplier.` (#467)\n- `Config` and configuring `Option` to the propagator API. (#467)\n- `Propagators` interface in the propagation API to contain the set of injectors and extractors for all supported carrier formats. (#467)\n- `HTTPPropagator` interface in the propagation API to inject and extract from an `HTTPSupplier.` (#467)\n- `WithInjectors` and `WithExtractors` functions to the propagator API to configure injectors and extractors to use. (#467)\n- `ExtractHTTP` and `InjectHTTP` functions to apply configured HTTP extractors and injectors to a passed context. (#467)\n- Histogram aggregator. (#433)\n- `DefaultPropagator` function and have it return `trace.TraceContext` as the default context propagator. (#456)\n- `AlwaysParentSample` sampler to the trace API. (#455)\n- `WithNewRoot` option function to the trace API to specify the created span should be considered a root span. (#451)\n\n### Changed\n\n- Renamed `WithMap` to `ContextWithMap` in the correlation package. (#481)\n- Renamed `FromContext` to `MapFromContext` in the correlation package. (#481)\n- Move correlation context propagation to correlation package. (#479)\n- Do not default to putting remote span context into links. (#480)\n- `Tracer.WithSpan` updated to accept `StartOptions`. (#472)\n- Renamed `MetricKind` to `Kind` to not stutter in the type usage. (#432)\n- Renamed the `export` package to `metric` to match directory structure. (#432)\n- Rename the `api/distributedcontext` package to `api/correlation`. (#444)\n- Rename the `api/propagators` package to `api/propagation`. (#444)\n- Move the propagators from the `propagators` package into the `trace` API package. (#444)\n- Update `Float64Gauge`, `Int64Gauge`, `Float64Counter`, `Int64Counter`, `Float64Measure`, and `Int64Measure` metric methods to use value receivers instead of pointers. (#462)\n- Moved all dependencies of tools package to a tools directory. (#466)\n\n### Removed\n\n- Binary propagators. (#467)\n- NOOP propagator. (#467)\n\n### Fixed\n\n- Upgraded `github.com/golangci/golangci-lint` from `v1.21.0` to `v1.23.6` in `tools/`. (#492)\n- Fix a possible nil-dereference crash (#478)\n- Correct comments for `InstallNewPipeline` in the stdout exporter. (#483)\n- Correct comments for `InstallNewPipeline` in the dogstatsd exporter. (#484)\n- Correct comments for `InstallNewPipeline` in the prometheus exporter. (#482)\n- Initialize `onError` based on `Config` in prometheus exporter. (#486)\n- Correct module name in prometheus exporter README. (#475)\n- Removed tracer name prefix from span names. (#430)\n- Fix `aggregator_test.go` import package comment. (#431)\n- Improved detail in stdout exporter. (#436)\n- Fix a dependency issue (generate target should depend on stringer, not lint target) in Makefile. (#442)\n- Reorders the Makefile targets within `precommit` target so we generate files and build the code before doing linting, so we can get much nicer errors about syntax errors from the compiler. (#442)\n- Reword function documentation in gRPC plugin. (#446)\n- Send the `span.kind` tag to Jaeger from the jaeger exporter. (#441)\n- Fix `metadataSupplier` in the jaeger exporter to overwrite the header if existing instead of appending to it. (#441)\n- Upgraded to Go 1.13 in CI. (#465)\n- Correct opentelemetry.io URL in trace SDK documentation. (#464)\n- Refactored reference counting logic in SDK determination of stale records. (#468)\n- Add call to `runtime.Gosched` in instrument `acquireHandle` logic to not block the collector. (#469)\n\n## [0.2.1.1] - 2020-01-13\n\n### Fixed\n\n- Use stateful batcher on Prometheus exporter fixing regression introduced in #395. (#428)\n\n## [0.2.1] - 2020-01-08\n\n### Added\n\n- Global meter forwarding implementation.\n   This enables deferred initialization for metric instruments registered before the first Meter SDK is installed. (#392)\n- Global trace forwarding implementation.\n   This enables deferred initialization for tracers registered before the first Trace SDK is installed. (#406)\n- Standardize export pipeline creation in all exporters. (#395)\n- A testing, organization, and comments for 64-bit field alignment. (#418)\n- Script to tag all modules in the project. (#414)\n\n### Changed\n\n- Renamed `propagation` package to `propagators`. (#362)\n- Renamed `B3Propagator` propagator to `B3`. (#362)\n- Renamed `TextFormatPropagator` propagator to `TextFormat`. (#362)\n- Renamed `BinaryPropagator` propagator to `Binary`. (#362)\n- Renamed `BinaryFormatPropagator` propagator to `BinaryFormat`. (#362)\n- Renamed `NoopTextFormatPropagator` propagator to `NoopTextFormat`. (#362)\n- Renamed `TraceContextPropagator` propagator to `TraceContext`. (#362)\n- Renamed `SpanOption` to `StartOption` in the trace API. (#369)\n- Renamed `StartOptions` to `StartConfig` in the trace API. (#369)\n- Renamed `EndOptions` to `EndConfig` in the trace API. (#369)\n- `Number` now has a pointer receiver for its methods. (#375)\n- Renamed `CurrentSpan` to `SpanFromContext` in the trace API. (#379)\n- Renamed `SetCurrentSpan` to `ContextWithSpan` in the trace API. (#379)\n- Renamed `Message` in Event to `Name` in the trace API. (#389)\n- Prometheus exporter no longer aggregates metrics, instead it only exports them. (#385)\n- Renamed `HandleImpl` to `BoundInstrumentImpl` in the metric API. (#400)\n- Renamed `Float64CounterHandle` to `Float64CounterBoundInstrument` in the metric API. (#400)\n- Renamed `Int64CounterHandle` to `Int64CounterBoundInstrument` in the metric API. (#400)\n- Renamed `Float64GaugeHandle` to `Float64GaugeBoundInstrument` in the metric API. (#400)\n- Renamed `Int64GaugeHandle` to `Int64GaugeBoundInstrument` in the metric API. (#400)\n- Renamed `Float64MeasureHandle` to `Float64MeasureBoundInstrument` in the metric API. (#400)\n- Renamed `Int64MeasureHandle` to `Int64MeasureBoundInstrument` in the metric API. (#400)\n- Renamed `Release` method for bound instruments in the metric API to `Unbind`. (#400)\n- Renamed `AcquireHandle` method for bound instruments in the metric API to `Bind`. (#400)\n- Renamed the `File` option in the stdout exporter to `Writer`. (#404)\n- Renamed all `Options` to `Config` for all metric exports where this wasn't already the case.\n\n### Fixed\n\n- Aggregator import path corrected. (#421)\n- Correct links in README. (#368)\n- The README was updated to match latest code changes in its examples. (#374)\n- Don't capitalize error statements. (#375)\n- Fix ignored errors. (#375)\n- Fix ambiguous variable naming. (#375)\n- Removed unnecessary type casting. (#375)\n- Use named parameters. (#375)\n- Updated release schedule. (#378)\n- Correct http-stackdriver example module name. (#394)\n- Removed the `http.request` span in `httptrace` package. (#397)\n- Add comments in the metrics SDK (#399)\n- Initialize checkpoint when creating ddsketch aggregator to prevent panic when merging into a empty one. (#402) (#403)\n- Add documentation of compatible exporters in the README. (#405)\n- Typo fix. (#408)\n- Simplify span check logic in SDK tracer implementation. (#419)\n\n## [0.2.0] - 2019-12-03\n\n### Added\n\n- Unary gRPC tracing example. (#351)\n- Prometheus exporter. (#334)\n- Dogstatsd metrics exporter. (#326)\n\n### Changed\n\n- Rename `MaxSumCount` aggregation to `MinMaxSumCount` and add the `Min` interface for this aggregation. (#352)\n- Rename `GetMeter` to `Meter`. (#357)\n- Rename `HTTPTraceContextPropagator` to `TraceContextPropagator`. (#355)\n- Rename `HTTPB3Propagator` to `B3Propagator`. (#355)\n- Rename `HTTPTraceContextPropagator` to `TraceContextPropagator`. (#355)\n- Move `/global` package to `/api/global`. (#356)\n- Rename `GetTracer` to `Tracer`. (#347)\n\n### Removed\n\n- `SetAttribute` from the `Span` interface in the trace API. (#361)\n- `AddLink` from the `Span` interface in the trace API. (#349)\n- `Link` from the `Span` interface in the trace API. (#349)\n\n### Fixed\n\n- Exclude example directories from coverage report. (#365)\n- Lint make target now implements automatic fixes with `golangci-lint` before a second run to report the remaining issues. (#360)\n- Drop `GO111MODULE` environment variable in Makefile as Go 1.13 is the project specified minimum version and this is environment variable is not needed for that version of Go. (#359)\n- Run the race checker for all test. (#354)\n- Redundant commands in the Makefile are removed. (#354)\n- Split the `generate` and `lint` targets of the Makefile. (#354)\n- Renames `circle-ci` target to more generic `ci` in Makefile. (#354)\n- Add example Prometheus binary to gitignore. (#358)\n- Support negative numbers with the `MaxSumCount`. (#335)\n- Resolve race conditions in `push_test.go` identified in #339. (#340)\n- Use `/usr/bin/env bash` as a shebang in scripts rather than `/bin/bash`. (#336)\n- Trace benchmark now tests both `AlwaysSample` and `NeverSample`.\n   Previously it was testing `AlwaysSample` twice. (#325)\n- Trace benchmark now uses a `[]byte` for `TraceID` to fix failing test. (#325)\n- Added a trace benchmark to test variadic functions in `setAttribute` vs `setAttributes` (#325)\n- The `defaultkeys` batcher was only using the encoded label set as its map key while building a checkpoint.\n   This allowed distinct label sets through, but any metrics sharing a label set could be overwritten or merged incorrectly.\n   This was corrected. (#333)\n\n## [0.1.2] - 2019-11-18\n\n### Fixed\n\n- Optimized the `simplelru` map for attributes to reduce the number of allocations. (#328)\n- Removed unnecessary unslicing of parameters that are already a slice. (#324)\n\n## [0.1.1] - 2019-11-18\n\nThis release contains a Metrics SDK with stdout exporter and supports basic aggregations such as counter, gauges, array, maxsumcount, and ddsketch.\n\n### Added\n\n- Metrics stdout export pipeline. (#265)\n- Array aggregation for raw measure metrics. (#282)\n- The core.Value now have a `MarshalJSON` method. (#281)\n\n### Removed\n\n- `WithService`, `WithResources`, and `WithComponent` methods of tracers. (#314)\n- Prefix slash in `Tracer.Start()` for the Jaeger example. (#292)\n\n### Changed\n\n- Allocation in LabelSet construction to reduce GC overhead. (#318)\n- `trace.WithAttributes` to append values instead of replacing (#315)\n- Use a formula for tolerance in sampling tests. (#298)\n- Move export types into trace and metric-specific sub-directories. (#289)\n- `SpanKind` back to being based on an `int` type. (#288)\n\n### Fixed\n\n- URL to OpenTelemetry website in README. (#323)\n- Name of othttp default tracer. (#321)\n- `ExportSpans` for the stackdriver exporter now handles `nil` context. (#294)\n- CI modules cache to correctly restore/save from/to the cache. (#316)\n- Fix metric SDK race condition between `LoadOrStore` and the assignment `rec.recorder = i.meter.exporter.AggregatorFor(rec)`. (#293)\n- README now reflects the new code structure introduced with these changes. (#291)\n- Make the basic example work. (#279)\n\n## [0.1.0] - 2019-11-04\n\nThis is the first release of open-telemetry go library.\nIt contains api and sdk for trace and meter.\n\n### Added\n\n- Initial OpenTelemetry trace and metric API prototypes.\n- Initial OpenTelemetry trace, metric, and export SDK packages.\n- A wireframe bridge to support compatibility with OpenTracing.\n- Example code for a basic, http-stackdriver, http, jaeger, and named tracer setup.\n- Exporters for Jaeger, Stackdriver, and stdout.\n- Propagators for binary, B3, and trace-context protocols.\n- Project information and guidelines in the form of a README and CONTRIBUTING.\n- Tools to build the project and a Makefile to automate the process.\n- Apache-2.0 license.\n- CircleCI build CI manifest files.\n- CODEOWNERS file to track owners of this project.\n\n[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.19.0...HEAD\n[1.19.0/0.42.0/0.0.7]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0\n[1.19.0-rc.1/0.42.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0-rc.1\n[1.18.0/0.41.0/0.0.6]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.18.0\n[1.17.0/0.40.0/0.0.5]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.17.0\n[1.16.0/0.39.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0\n[1.16.0-rc.1/0.39.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.16.0-rc.1\n[1.15.1/0.38.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.1\n[1.15.0/0.38.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0\n[1.15.0-rc.2/0.38.0-rc.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.2\n[1.15.0-rc.1/0.38.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.1\n[1.14.0/0.37.0/0.0.4]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.14.0\n[1.13.0/0.36.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.13.0\n[1.12.0/0.35.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.12.0\n[1.11.2/0.34.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.2\n[1.11.1/0.33.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.1\n[1.11.0/0.32.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.11.0\n[0.32.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.2\n[0.32.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.1\n[0.32.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/sdk/metric/v0.32.0\n[1.10.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.10.0\n[1.9.0/0.0.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.9.0\n[1.8.0/0.31.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.8.0\n[1.7.0/0.30.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.7.0\n[0.29.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.29.0\n[1.6.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.3\n[1.6.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.2\n[1.6.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.1\n[1.6.0/0.28.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.6.0\n[1.5.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.5.0\n[1.4.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.1\n[1.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.4.0\n[1.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.3.0\n[1.2.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.2.0\n[1.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.1.0\n[1.0.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.1\n[Metrics 0.24.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.24.0\n[1.0.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0\n[1.0.0-RC3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC3\n[1.0.0-RC2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC2\n[Experimental Metrics v0.22.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.22.0\n[1.0.0-RC1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC1\n[0.20.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.20.0\n[0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.19.0\n[0.18.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.18.0\n[0.17.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.17.0\n[0.16.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.16.0\n[0.15.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.15.0\n[0.14.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.14.0\n[0.13.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.13.0\n[0.12.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.12.0\n[0.11.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.11.0\n[0.10.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.10.0\n[0.9.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.9.0\n[0.8.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.8.0\n[0.7.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.7.0\n[0.6.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.6.0\n[0.5.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.5.0\n[0.4.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.3\n[0.4.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.2\n[0.4.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.1\n[0.4.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.4.0\n[0.3.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.3.0\n[0.2.3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.3\n[0.2.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.2\n[0.2.1.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.1.1\n[0.2.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.1\n[0.2.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.2.0\n[0.1.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.2\n[0.1.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.1\n[0.1.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.1.0\n\n[Go 1.20]: https://go.dev/doc/go1.20\n[Go 1.19]: https://go.dev/doc/go1.19\n[Go 1.18]: https://go.dev/doc/go1.18\n[Go 1.19]: https://go.dev/doc/go1.19\n\n[metric API]:https://pkg.go.dev/go.opentelemetry.io/otel/metric\n[metric SDK]:https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/CODEOWNERS",
    "content": "#####################################################\n#\n# List of approvers for this repository\n#\n#####################################################\n#\n# Learn about membership in OpenTelemetry community:\n#  https://github.com/open-telemetry/community/blob/main/community-membership.md\n#\n#\n# Learn about CODEOWNERS file format:\n#  https://help.github.com/en/articles/about-code-owners\n#\n\n* @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu\n\nCODEOWNERS @MrAlias @MadVikingGod @pellared"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/CONTRIBUTING.md",
    "content": "# Contributing to opentelemetry-go\n\nThe Go special interest group (SIG) meets regularly. See the\nOpenTelemetry\n[community](https://github.com/open-telemetry/community#golang-sdk)\nrepo for information on this and other language SIGs.\n\nSee the [public meeting\nnotes](https://docs.google.com/document/d/1E5e7Ld0NuU1iVvf-42tOBpu2VBBLYnh73GJuITGJTTU/edit)\nfor a summary description of past meetings. To request edit access,\njoin the meeting or get in touch on\n[Slack](https://cloud-native.slack.com/archives/C01NPAXACKT).\n\n## Development\n\nYou can view and edit the source code by cloning this repository:\n\n```sh\ngit clone https://github.com/open-telemetry/opentelemetry-go.git\n```\n\nRun `make test` to run the tests instead of `go test`.\n\nThere are some generated files checked into the repo. To make sure\nthat the generated files are up-to-date, run `make` (or `make\nprecommit` - the `precommit` target is the default).\n\nThe `precommit` target also fixes the formatting of the code and\nchecks the status of the go module files.\n\nAdditionally, there is a `codespell` target that checks for common\ntypos in the code. It is not run by default, but you can run it\nmanually with `make codespell`. It will set up a virtual environment\nin `venv` and install `codespell` there.\n\nIf after running `make precommit` the output of `git status` contains\n`nothing to commit, working tree clean` then it means that everything\nis up-to-date and properly formatted.\n\n## Pull Requests\n\n### How to Send Pull Requests\n\nEveryone is welcome to contribute code to `opentelemetry-go` via\nGitHub pull requests (PRs).\n\nTo create a new PR, fork the project in GitHub and clone the upstream\nrepo:\n\n```sh\ngo get -d go.opentelemetry.io/otel\n```\n\n(This may print some warning about \"build constraints exclude all Go\nfiles\", just ignore it.)\n\nThis will put the project in `${GOPATH}/src/go.opentelemetry.io/otel`. You\ncan alternatively use `git` directly with:\n\n```sh\ngit clone https://github.com/open-telemetry/opentelemetry-go\n```\n\n(Note that `git clone` is *not* using the `go.opentelemetry.io/otel` name -\nthat name is a kind of a redirector to GitHub that `go get` can\nunderstand, but `git` does not.)\n\nThis would put the project in the `opentelemetry-go` directory in\ncurrent working directory.\n\nEnter the newly created directory and add your fork as a new remote:\n\n```sh\ngit remote add <YOUR_FORK> git@github.com:<YOUR_GITHUB_USERNAME>/opentelemetry-go\n```\n\nCheck out a new branch, make modifications, run linters and tests, update\n`CHANGELOG.md`, and push the branch to your fork:\n\n```sh\ngit checkout -b <YOUR_BRANCH_NAME>\n# edit files\n# update changelog\nmake precommit\ngit add -p\ngit commit\ngit push <YOUR_FORK> <YOUR_BRANCH_NAME>\n```\n\nOpen a pull request against the main `opentelemetry-go` repo. Be sure to add the pull\nrequest ID to the entry you added to `CHANGELOG.md`.\n\n### How to Receive Comments\n\n* If the PR is not ready for review, please put `[WIP]` in the title,\n  tag it as `work-in-progress`, or mark it as\n  [`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).\n* Make sure CLA is signed and CI is clear.\n\n### How to Get PRs Merged\n\nA PR is considered **ready to merge** when:\n\n* It has received two qualified approvals[^1].\n\n  This is not enforced through automation, but needs to be validated by the\n  maintainer merging.\n  * The qualified approvals need to be from [Approver]s/[Maintainer]s\n    affiliated with different companies. Two qualified approvals from\n    [Approver]s or [Maintainer]s affiliated with the same company counts as a\n    single qualified approval.\n  * PRs introducing changes that have already been discussed and consensus\n    reached only need one qualified approval. The discussion and resolution\n    needs to be linked to the PR.\n  * Trivial changes[^2] only need one qualified approval.\n\n* All feedback has been addressed.\n  * All PR comments and suggestions are resolved.\n  * All GitHub Pull Request reviews with a status of \"Request changes\" have\n    been addressed. Another review by the objecting reviewer with a different\n    status can be submitted to clear the original review, or the review can be\n    dismissed by a [Maintainer] when the issues from the original review have\n    been addressed.\n  * Any comments or reviews that cannot be resolved between the PR author and\n    reviewers can be submitted to the community [Approver]s and [Maintainer]s\n    during the weekly SIG meeting. If consensus is reached among the\n    [Approver]s and [Maintainer]s during the SIG meeting the objections to the\n    PR may be dismissed or resolved or the PR closed by a [Maintainer].\n  * Any substantive changes to the PR require existing Approval reviews be\n    cleared unless the approver explicitly states that their approval persists\n    across changes. This includes changes resulting from other feedback.\n    [Approver]s and [Maintainer]s can help in clearing reviews and they should\n    be consulted if there are any questions.\n\n* The PR branch is up to date with the base branch it is merging into.\n  * To ensure this does not block the PR, it should be configured to allow\n    maintainers to update it.\n\n* It has been open for review for at least one working day. This gives people\n  reasonable time to review.\n  * Trivial changes[^2] do not have to wait for one day and may be merged with\n    a single [Maintainer]'s approval.\n\n* All required GitHub workflows have succeeded.\n* Urgent fix can take exception as long as it has been actively communicated\n  among [Maintainer]s.\n\nAny [Maintainer] can merge the PR once the above criteria have been met.\n\n[^1]: A qualified approval is a GitHub Pull Request review with \"Approve\"\n  status from an OpenTelemetry Go [Approver] or [Maintainer].\n[^2]: Trivial changes include: typo corrections, cosmetic non-substantive\n  changes, documentation corrections or updates, dependency updates, etc.\n\n## Design Choices\n\nAs with other OpenTelemetry clients, opentelemetry-go follows the\n[OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel).\n\nIt's especially valuable to read through the [library\nguidelines](https://opentelemetry.io/docs/specs/otel/library-guidelines).\n\n### Focus on Capabilities, Not Structure Compliance\n\nOpenTelemetry is an evolving specification, one where the desires and\nuse cases are clear, but the method to satisfy those uses cases are\nnot.\n\nAs such, Contributions should provide functionality and behavior that\nconforms to the specification, but the interface and structure is\nflexible.\n\nIt is preferable to have contributions follow the idioms of the\nlanguage rather than conform to specific API names or argument\npatterns in the spec.\n\nFor a deeper discussion, see\n[this](https://github.com/open-telemetry/opentelemetry-specification/issues/165).\n\n## Documentation\n\nEach (non-internal, non-test) package must be documented using\n[Go Doc Comments](https://go.dev/doc/comment),\npreferably in a `doc.go` file.\n\nPrefer using [Examples](https://pkg.go.dev/testing#hdr-Examples)\ninstead of putting code snippets in Go doc comments.\nIn some cases, you can even create [Testable Examples](https://go.dev/blog/examples).\n\nYou can install and run a \"local Go Doc site\" in the following way:\n\n  ```sh\n  go install golang.org/x/pkgsite/cmd/pkgsite@latest\n  pkgsite\n  ```\n\n[`go.opentelemetry.io/otel/metric`](https://pkg.go.dev/go.opentelemetry.io/otel/metric)\nis an example of a very well-documented package.\n\n## Style Guide\n\nOne of the primary goals of this project is that it is actually used by\ndevelopers. With this goal in mind the project strives to build\nuser-friendly and idiomatic Go code adhering to the Go community's best\npractices.\n\nFor a non-comprehensive but foundational overview of these best practices\nthe [Effective Go](https://golang.org/doc/effective_go.html) documentation\nis an excellent starting place.\n\nAs a convenience for developers building this project the `make precommit`\nwill format, lint, validate, and in some cases fix the changes you plan to\nsubmit. This check will need to pass for your changes to be able to be\nmerged.\n\nIn addition to idiomatic Go, the project has adopted certain standards for\nimplementations of common patterns. These standards should be followed as a\ndefault, and if they are not followed documentation needs to be included as\nto the reasons why.\n\n### Configuration\n\nWhen creating an instantiation function for a complex `type T struct`, it is\nuseful to allow variable number of options to be applied. However, the strong\ntype system of Go restricts the function design options. There are a few ways\nto solve this problem, but we have landed on the following design.\n\n#### `config`\n\nConfiguration should be held in a `struct` named `config`, or prefixed with\nspecific type name this Configuration applies to if there are multiple\n`config` in the package. This type must contain configuration options.\n\n```go\n// config contains configuration options for a thing.\ntype config struct {\n\t// options ...\n}\n```\n\nIn general the `config` type will not need to be used externally to the\npackage and should be unexported. If, however, it is expected that the user\nwill likely want to build custom options for the configuration, the `config`\nshould be exported. Please, include in the documentation for the `config`\nhow the user can extend the configuration.\n\nIt is important that internal `config` are not shared across package boundaries.\nMeaning a `config` from one package should not be directly used by another. The\none exception is the API packages.  The configs from the base API, eg.\n`go.opentelemetry.io/otel/trace.TracerConfig` and\n`go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed\nby the SDK therefore it is expected that these are exported.\n\nWhen a config is exported we want to maintain forward and backward\ncompatibility, to achieve this no fields should be exported but should\ninstead be accessed by methods.\n\nOptionally, it is common to include a `newConfig` function (with the same\nnaming scheme). This function wraps any defaults setting and looping over\nall options to create a configured `config`.\n\n```go\n// newConfig returns an appropriately configured config.\nfunc newConfig(options ...Option) config {\n\t// Set default values for config.\n\tconfig := config{/* […] */}\n\tfor _, option := range options {\n\t\tconfig = option.apply(config)\n\t}\n\t// Perform any validation here.\n\treturn config\n}\n```\n\nIf validation of the `config` options is also performed this can return an\nerror as well that is expected to be handled by the instantiation function\nor propagated to the user.\n\nGiven the design goal of not having the user need to work with the `config`,\nthe `newConfig` function should also be unexported.\n\n#### `Option`\n\nTo set the value of the options a `config` contains, a corresponding\n`Option` interface type should be used.\n\n```go\ntype Option interface {\n\tapply(config) config\n}\n```\n\nHaving `apply` unexported makes sure that it will not be used externally.\nMoreover, the interface becomes sealed so the user cannot easily implement\nthe interface on its own.\n\nThe `apply` method should return a modified version of the passed config.\nThis approach, instead of passing a pointer, is used to prevent the config from being allocated to the heap.\n\nThe name of the interface should be prefixed in the same way the\ncorresponding `config` is (if at all).\n\n#### Options\n\nAll user configurable options for a `config` must have a related unexported\nimplementation of the `Option` interface and an exported configuration\nfunction that wraps this implementation.\n\nThe wrapping function name should be prefixed with `With*` (or in the\nspecial case of a boolean options `Without*`) and should have the following\nfunction signature.\n\n```go\nfunc With*(…) Option { … }\n```\n\n##### `bool` Options\n\n```go\ntype defaultFalseOption bool\n\nfunc (o defaultFalseOption) apply(c config) config {\n\tc.Bool = bool(o)\n    return c\n}\n\n// WithOption sets a T to have an option included.\nfunc WithOption() Option {\n\treturn defaultFalseOption(true)\n}\n```\n\n```go\ntype defaultTrueOption bool\n\nfunc (o defaultTrueOption) apply(c config) config {\n\tc.Bool = bool(o)\n    return c\n}\n\n// WithoutOption sets a T to have Bool option excluded.\nfunc WithoutOption() Option {\n\treturn defaultTrueOption(false)\n}\n```\n\n##### Declared Type Options\n\n```go\ntype myTypeOption struct {\n\tMyType MyType\n}\n\nfunc (o myTypeOption) apply(c config) config {\n\tc.MyType = o.MyType\n    return c\n}\n\n// WithMyType sets T to have include MyType.\nfunc WithMyType(t MyType) Option {\n\treturn myTypeOption{t}\n}\n```\n\n##### Functional Options\n\n```go\ntype optionFunc func(config) config\n\nfunc (fn optionFunc) apply(c config) config {\n\treturn fn(c)\n}\n\n// WithMyType sets t as MyType.\nfunc WithMyType(t MyType) Option {\n\treturn optionFunc(func(c config) config {\n\t\tc.MyType = t\n        return c\n\t})\n}\n```\n\n#### Instantiation\n\nUsing this configuration pattern to configure instantiation with a `NewT`\nfunction.\n\n```go\nfunc NewT(options ...Option) T {…}\n```\n\nAny required parameters can be declared before the variadic `options`.\n\n#### Dealing with Overlap\n\nSometimes there are multiple complex `struct` that share common\nconfiguration and also have distinct configuration. To avoid repeated\nportions of `config`s, a common `config` can be used with the union of\noptions being handled with the `Option` interface.\n\nFor example.\n\n```go\n// config holds options for all animals.\ntype config struct {\n\tWeight      float64\n\tColor       string\n\tMaxAltitude float64\n}\n\n// DogOption apply Dog specific options.\ntype DogOption interface {\n\tapplyDog(config) config\n}\n\n// BirdOption apply Bird specific options.\ntype BirdOption interface {\n\tapplyBird(config) config\n}\n\n// Option apply options for all animals.\ntype Option interface {\n\tBirdOption\n\tDogOption\n}\n\ntype weightOption float64\n\nfunc (o weightOption) applyDog(c config) config {\n\tc.Weight = float64(o)\n\treturn c\n}\n\nfunc (o weightOption) applyBird(c config) config {\n\tc.Weight = float64(o)\n\treturn c\n}\n\nfunc WithWeight(w float64) Option { return weightOption(w) }\n\ntype furColorOption string\n\nfunc (o furColorOption) applyDog(c config) config {\n\tc.Color = string(o)\n\treturn c\n}\n\nfunc WithFurColor(c string) DogOption { return furColorOption(c) }\n\ntype maxAltitudeOption float64\n\nfunc (o maxAltitudeOption) applyBird(c config) config {\n\tc.MaxAltitude = float64(o)\n\treturn c\n}\n\nfunc WithMaxAltitude(a float64) BirdOption { return maxAltitudeOption(a) }\n\nfunc NewDog(name string, o ...DogOption) Dog    {…}\nfunc NewBird(name string, o ...BirdOption) Bird {…}\n```\n\n### Interfaces\n\nTo allow other developers to better comprehend the code, it is important\nto ensure it is sufficiently documented. One simple measure that contributes\nto this aim is self-documenting by naming method parameters. Therefore,\nwhere appropriate, methods of every exported interface type should have\ntheir parameters appropriately named.\n\n#### Interface Stability\n\nAll exported stable interfaces that include the following warning in their\ndocumentation are allowed to be extended with additional methods.\n\n> Warning: methods may be added to this interface in minor releases.\n\nThese interfaces are defined by the OpenTelemetry specification and will be\nupdated as the specification evolves.\n\nOtherwise, stable interfaces MUST NOT be modified.\n\n#### How to Change Specification Interfaces\n\nWhen an API change must be made, we will update the SDK with the new method one\nrelease before the API change. This will allow the SDK one version before the\nAPI change to work seamlessly with the new API.\n\nIf an incompatible version of the SDK is used with the new API the application\nwill fail to compile.\n\n#### How Not to Change Specification Interfaces\n\nWe have explored using a v2 of the API to change interfaces and found that there\nwas no way to introduce a v2 and have it work seamlessly with the v1 of the API.\nProblems happened with libraries that upgraded to v2 when an application did not,\nand would not produce any telemetry.\n\nMore detail of the approaches considered and their limitations can be found in\nthe [Use a V2 API to evolve interfaces](https://github.com/open-telemetry/opentelemetry-go/issues/3920)\nissue.\n\n#### How to Change Other Interfaces\n\nIf new functionality is needed for an interface that cannot be changed it MUST\nbe added by including an additional interface. That added interface can be a\nsimple interface for the specific functionality that you want to add or it can\nbe a super-set of the original interface. For example, if you wanted to a\n`Close` method to the `Exporter` interface:\n\n```go\ntype Exporter interface {\n\tExport()\n}\n```\n\nA new interface, `Closer`, can be added:\n\n```go\ntype Closer interface {\n\tClose()\n}\n```\n\nCode that is passed the `Exporter` interface can now check to see if the passed\nvalue also satisfies the new interface. E.g.\n\n```go\nfunc caller(e Exporter) {\n\t/* ... */\n\tif c, ok := e.(Closer); ok {\n\t\tc.Close()\n\t}\n\t/* ... */\n}\n```\n\nAlternatively, a new type that is the super-set of an `Exporter` can be created.\n\n```go\ntype ClosingExporter struct {\n\tExporter\n\tClose()\n}\n```\n\nThis new type can be used similar to the simple interface above in that a\npassed `Exporter` type can be asserted to satisfy the `ClosingExporter` type\nand the `Close` method called.\n\nThis super-set approach can be useful if there is explicit behavior that needs\nto be coupled with the original type and passed as a unified type to a new\nfunction, but, because of this coupling, it also limits the applicability of\nthe added functionality. If there exist other interfaces where this\nfunctionality should be added, each one will need their own super-set\ninterfaces and will duplicate the pattern. For this reason, the simple targeted\ninterface that defines the specific functionality should be preferred.\n\n### Testing\n\nThe tests should never leak goroutines.\n\nUse the term `ConcurrentSafe` in the test name when it aims to verify the\nabsence of race conditions.\n\n### Internal packages\n\nThe use of internal packages should be scoped to a single module. A sub-module\nshould never import from a parent internal package. This creates a coupling\nbetween the two modules where a user can upgrade the parent without the child\nand if the internal package API has changed it will fail to upgrade[^3].\n\nThere are two known exceptions to this rule:\n\n- `go.opentelemetry.io/otel/internal/global`\n  - This package manages global state for all of opentelemetry-go. It needs to\n  be a single package in order to ensure the uniqueness of the global state.\n- `go.opentelemetry.io/otel/internal/baggage`\n  - This package provides values in a `context.Context` that need to be\n  recognized by `go.opentelemetry.io/otel/baggage` and\n  `go.opentelemetry.io/otel/bridge/opentracing` but remain private.\n\nIf you have duplicate code in multiple modules, make that code into a Go\ntemplate stored in `go.opentelemetry.io/otel/internal/shared` and use [gotmpl]\nto render the templates in the desired locations. See [#4404] for an example of\nthis.\n\n[^3]: https://github.com/open-telemetry/opentelemetry-go/issues/3548\n\n## Approvers and Maintainers\n\n### Approvers\n\n- [Evan Torrie](https://github.com/evantorrie), Verizon Media\n- [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics\n- [David Ashpole](https://github.com/dashpole), Google\n- [Chester Cheung](https://github.com/hanyuancheung), Tencent\n- [Damien Mathieu](https://github.com/dmathieu), Elastic\n- [Anthony Mirabella](https://github.com/Aneurysm9), AWS\n\n### Maintainers\n\n- [Aaron Clawson](https://github.com/MadVikingGod), LightStep\n- [Robert Pająk](https://github.com/pellared), Splunk\n- [Tyler Yahn](https://github.com/MrAlias), Splunk\n\n### Emeritus\n\n- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep\n- [Josh MacDonald](https://github.com/jmacd), LightStep\n\n### Become an Approver or a Maintainer\n\nSee the [community membership document in OpenTelemetry community\nrepo](https://github.com/open-telemetry/community/blob/main/community-membership.md).\n\n[Approver]: #approvers\n[Maintainer]: #maintainers\n[gotmpl]: https://pkg.go.dev/go.opentelemetry.io/build-tools/gotmpl\n[#4404]: https://github.com/open-telemetry/opentelemetry-go/pull/4404\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/go.opentelemetry.io/otel/Makefile",
    "content": "# Copyright The OpenTelemetry Authors\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#     http://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\nTOOLS_MOD_DIR := ./internal/tools\n\nALL_DOCS := $(shell find . -name '*.md' -type f | sort)\nALL_GO_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \\; | sort)\nOTEL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(ALL_GO_MOD_DIRS))\nALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \\; | grep -E -v '^./example|^$(TOOLS_MOD_DIR)' | sort)\n\nGO = go\nTIMEOUT = 60\n\n.DEFAULT_GOAL := precommit\n\n.PHONY: precommit ci\nprecommit: generate dependabot-generate license-check misspell go-mod-tidy golangci-lint-fix test-default\nci: generate dependabot-check license-check lint vanity-import-check build test-default check-clean-work-tree test-coverage\n\n# Tools\n\nTOOLS = $(CURDIR)/.tools\n\n$(TOOLS):\n\t@mkdir -p $@\n$(TOOLS)/%: | $(TOOLS)\n\tcd $(TOOLS_MOD_DIR) && \\\n\t$(GO) build -o $@ $(PACKAGE)\n\nMULTIMOD = $(TOOLS)/multimod\n$(TOOLS)/multimod: PACKAGE=go.opentelemetry.io/build-tools/multimod\n\nSEMCONVGEN = $(TOOLS)/semconvgen\n$(TOOLS)/semconvgen: PACKAGE=go.opentelemetry.io/build-tools/semconvgen\n\nCROSSLINK = $(TOOLS)/crosslink\n$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/build-tools/crosslink\n\nSEMCONVKIT = $(TOOLS)/semconvkit\n$(TOOLS)/semconvkit: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconvkit\n\nDBOTCONF = $(TOOLS)/dbotconf\n$(TOOLS)/dbotconf: PACKAGE=go.opentelemetry.io/build-tools/dbotconf\n\nGOLANGCI_LINT = $(TOOLS)/golangci-lint\n$(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint\n\nMISSPELL = $(TOOLS)/misspell\n$(TOOLS)/misspell: PACKAGE=github.com/client9/misspell/cmd/misspell\n\nGOCOVMERGE = $(TOOLS)/gocovmerge\n$(TOOLS)/gocovmerge: PACKAGE=github.com/wadey/gocovmerge\n\nSTRINGER = $(TOOLS)/stringer\n$(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer\n\nPORTO = $(TOOLS)/porto\n$(TOOLS)/porto: PACKAGE=github.com/jcchavezs/porto/cmd/porto\n\nGOJQ = $(TOOLS)/gojq\n$(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq\n\nGOTMPL = $(TOOLS)/gotmpl\n$(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl\n\nGORELEASE = $(TOOLS)/gorelease\n$(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease\n\n.PHONY: tools\ntools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE)\n\n# Virtualized python tools via docker\n\n# The directory where the virtual environment is created.\nVENVDIR := venv\n\n# The directory where the python tools are installed.\nPYTOOLS := $(VENVDIR)/bin\n\n# The pip executable in the virtual environment.\nPIP := $(PYTOOLS)/pip\n\n# The directory in the docker image where the current directory is mounted.\nWORKDIR := /workdir\n\n# The python image to use for the virtual environment.\nPYTHONIMAGE := python:3.11.3-slim-bullseye\n\n# Run the python image with the current directory mounted.\nDOCKERPY := docker run --rm -v \"$(CURDIR):$(WORKDIR)\" -w $(WORKDIR) $(PYTHONIMAGE)\n\n# Create a virtual environment for Python tools.\n$(PYTOOLS):\n# The `--upgrade` flag is needed to ensure that the virtual environment is\n# created with the latest pip version.\n\t@$(DOCKERPY) bash -c \"python3 -m venv $(VENVDIR) && $(PIP) install --upgrade pip\"\n\n# Install python packages into the virtual environment.\n$(PYTOOLS)/%: | $(PYTOOLS)\n\t@$(DOCKERPY) $(PIP) install -r requirements.txt\n\nCODESPELL = $(PYTOOLS)/codespell\n$(CODESPELL): PACKAGE=codespell\n\n# Generate\n\n.PHONY: generate\ngenerate: go-generate vanity-import-fix\n\n.PHONY: go-generate\ngo-generate: $(OTEL_GO_MOD_DIRS:%=go-generate/%)\ngo-generate/%: DIR=$*\ngo-generate/%: | $(STRINGER) $(GOTMPL)\n\t@echo \"$(GO) generate $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& PATH=\"$(TOOLS):$${PATH}\" $(GO) generate ./...\n\n.PHONY: vanity-import-fix\nvanity-import-fix: | $(PORTO)\n\t@$(PORTO) --include-internal -w .\n\n# Generate go.work file for local development.\n.PHONY: go-work\ngo-work: | $(CROSSLINK)\n\t$(CROSSLINK) work --root=$(shell pwd)\n\n# Build\n\n.PHONY: build\n\nbuild: $(OTEL_GO_MOD_DIRS:%=build/%) $(OTEL_GO_MOD_DIRS:%=build-tests/%)\nbuild/%: DIR=$*\nbuild/%:\n\t@echo \"$(GO) build $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) build ./...\n\nbuild-tests/%: DIR=$*\nbuild-tests/%:\n\t@echo \"$(GO) build tests $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) list ./... \\\n\t\t| grep -v third_party \\\n\t\t| xargs $(GO) test -vet=off -run xxxxxMatchNothingxxxxx >/dev/null\n\n# Tests\n\nTEST_TARGETS := test-default test-bench test-short test-verbose test-race\n.PHONY: $(TEST_TARGETS) test\ntest-default test-race: ARGS=-race\ntest-bench:   ARGS=-run=xxxxxMatchNothingxxxxx -test.benchtime=1ms -bench=.\ntest-short:   ARGS=-short\ntest-verbose: ARGS=-v -race\n$(TEST_TARGETS): test\ntest: $(OTEL_GO_MOD_DIRS:%=test/%)\ntest/%: DIR=$*\ntest/%:\n\t@echo \"$(GO) test -timeout $(TIMEOUT)s $(ARGS) $(DIR)/...\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) list ./... \\\n\t\t| grep -v third_party \\\n\t\t| xargs $(GO) test -timeout $(TIMEOUT)s $(ARGS)\n\nCOVERAGE_MODE    = atomic\nCOVERAGE_PROFILE = coverage.out\n.PHONY: test-coverage\ntest-coverage: | $(GOCOVMERGE)\n\t@set -e; \\\n\tprintf \"\" > coverage.txt; \\\n\tfor dir in $(ALL_COVERAGE_MOD_DIRS); do \\\n\t  echo \"$(GO) test -coverpkg=go.opentelemetry.io/otel/... -covermode=$(COVERAGE_MODE) -coverprofile=\"$(COVERAGE_PROFILE)\" $${dir}/...\"; \\\n\t  (cd \"$${dir}\" && \\\n\t    $(GO) list ./... \\\n\t    | grep -v third_party \\\n\t    | grep -v 'semconv/v.*' \\\n\t    | xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile=\"$(COVERAGE_PROFILE)\" && \\\n\t  $(GO) tool cover -html=coverage.out -o coverage.html); \\\n\tdone; \\\n\t$(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt\n\n.PHONY: golangci-lint golangci-lint-fix\ngolangci-lint-fix: ARGS=--fix\ngolangci-lint-fix: golangci-lint\ngolangci-lint: $(OTEL_GO_MOD_DIRS:%=golangci-lint/%)\ngolangci-lint/%: DIR=$*\ngolangci-lint/%: | $(GOLANGCI_LINT)\n\t@echo 'golangci-lint $(if $(ARGS),$(ARGS) ,)$(DIR)' \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GOLANGCI_LINT) run --allow-serial-runners $(ARGS)\n\n.PHONY: crosslink\ncrosslink: | $(CROSSLINK)\n\t@echo \"Updating intra-repository dependencies in all go modules\" \\\n\t\t&& $(CROSSLINK) --root=$(shell pwd) --prune\n\n.PHONY: go-mod-tidy\ngo-mod-tidy: $(ALL_GO_MOD_DIRS:%=go-mod-tidy/%)\ngo-mod-tidy/%: DIR=$*\ngo-mod-tidy/%: | crosslink\n\t@echo \"$(GO) mod tidy in $(DIR)\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GO) mod tidy -compat=1.20\n\n.PHONY: lint-modules\nlint-modules: go-mod-tidy\n\n.PHONY: lint\nlint: misspell lint-modules golangci-lint\n\n.PHONY: vanity-import-check\nvanity-import-check: | $(PORTO)\n\t@$(PORTO) --include-internal -l . || ( echo \"(run: make vanity-import-fix)\"; exit 1 )\n\n.PHONY: misspell\nmisspell: | $(MISSPELL)\n\t@$(MISSPELL) -w $(ALL_DOCS)\n\n.PHONY: codespell\ncodespell: | $(CODESPELL)\n\t@$(DOCKERPY) $(CODESPELL)\n\n.PHONY: license-check\nlicense-check:\n\t@licRes=$$(for f in $$(find . -type f \\( -iname '*.go' -o -iname '*.sh' \\) ! -path '**/third_party/*' ! -path './.git/*' ) ; do \\\n\t           awk '/Copyright The OpenTelemetry Authors|generated|GENERATED/ && NR<=4 { found=1; next } END { if (!found) print FILENAME }' $$f; \\\n\t   done); \\\n\t   if [ -n \"$${licRes}\" ]; then \\\n\t           echo \"license header checking failed:\"; echo \"$${licRes}\"; \\\n\t           exit 1; \\\n\t   fi\n\nDEPENDABOT_CONFIG = .github/dependabot.yml\n.PHONY: dependabot-check\ndependabot-check: | $(DBOTCONF)\n\t@$(DBOTCONF) verify $(DEPENDABOT_CONFIG) || ( echo \"(run: make dependabot-generate)\"; exit 1 )\n\n.PHONY: dependabot-generate\ndependabot-generate: | $(DBOTCONF)\n\t@$(DBOTCONF) generate > $(DEPENDABOT_CONFIG)\n\n.PHONY: check-clean-work-tree\ncheck-clean-work-tree:\n\t@if ! git diff --quiet; then \\\n\t  echo; \\\n\t  echo 'Working tree is not clean, did you forget to run \"make precommit\"?'; \\\n\t  echo; \\\n\t  git status; \\\n\t  exit 1; \\\n\tfi\n\nSEMCONVPKG ?= \"semconv/\"\n.PHONY: semconv-generate\nsemconv-generate: | $(SEMCONVGEN) $(SEMCONVKIT)\n\t[ \"$(TAG)\" ] || ( echo \"TAG unset: missing opentelemetry semantic-conventions tag\"; exit 1 )\n\t[ \"$(OTEL_SEMCONV_REPO)\" ] || ( echo \"OTEL_SEMCONV_REPO unset: missing path to opentelemetry semantic-conventions repo\"; exit 1 )\n\t$(SEMCONVGEN) -i \"$(OTEL_SEMCONV_REPO)/model/.\" --only=span -p conventionType=trace -f trace.go -t \"$(SEMCONVPKG)/template.j2\" -s \"$(TAG)\"\n\t$(SEMCONVGEN) -i \"$(OTEL_SEMCONV_REPO)/model/.\" --only=attribute_group -p conventionType=trace -f attribute_group.go -t \"$(SEMCONVPKG)/template.j2\" -s \"$(TAG)\"\n\t$(SEMCONVGEN) -i \"$(OTEL_SEMCONV_REPO)/model/.\" --only=event -p conventionType=event -f event.go -t \"$(SEMCONVPKG)/template.j2\" -s \"$(TAG)\"\n\t$(SEMCONVGEN) -i \"$(OTEL_SEMCONV_REPO)/model/.\" --only=resource -p conventionType=resource -f resource.go -t \"$(SEMCONVPKG)/template.j2\" -s \"$(TAG)\"\n\t$(SEMCONVKIT) -output \"$(SEMCONVPKG)/$(TAG)\" -tag \"$(TAG)\"\n\n.PHONY: gorelease\ngorelease: $(OTEL_GO_MOD_DIRS:%=gorelease/%)\ngorelease/%: DIR=$*\ngorelease/%:| $(GORELEASE)\n\t@echo \"gorelease in $(DIR):\" \\\n\t\t&& cd $(DIR) \\\n\t\t&& $(GORELEASE) \\\n\t\t|| echo \"\"\n\n.PHONY: prerelease\nprerelease: | $(MULTIMOD)\n\t@[ \"${MODSET}\" ] || ( echo \">> env var MODSET is not set\"; exit 1 )\n\t$(MULTIMOD) verify && $(MULTIMOD) prerelease -m ${MODSET}\n\nCOMMIT ?= \"HEAD\"\n.PHONY: add-tags\nadd-tags: | $(MULTIMOD)\n\t@[ \"${MODSET}\" ] || ( echo \">> env var MODSET is not set\"; exit 1 )\n\t$(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/README.md",
    "content": "# OpenTelemetry-Go\n\n[![CI](https://github.com/open-telemetry/opentelemetry-go/workflows/ci/badge.svg)](https://github.com/open-telemetry/opentelemetry-go/actions?query=workflow%3Aci+branch%3Amain)\n[![codecov.io](https://codecov.io/gh/open-telemetry/opentelemetry-go/coverage.svg?branch=main)](https://app.codecov.io/gh/open-telemetry/opentelemetry-go?branch=main)\n[![PkgGoDev](https://pkg.go.dev/badge/go.opentelemetry.io/otel)](https://pkg.go.dev/go.opentelemetry.io/otel)\n[![Go Report Card](https://goreportcard.com/badge/go.opentelemetry.io/otel)](https://goreportcard.com/report/go.opentelemetry.io/otel)\n[![Slack](https://img.shields.io/badge/slack-@cncf/otel--go-brightgreen.svg?logo=slack)](https://cloud-native.slack.com/archives/C01NPAXACKT)\n\nOpenTelemetry-Go is the [Go](https://golang.org/) implementation of [OpenTelemetry](https://opentelemetry.io/).\nIt provides a set of APIs to directly measure performance and behavior of your software and send this data to observability platforms.\n\n## Project Status\n\n| Signal  | Status     | Project               |\n|---------|------------|-----------------------|\n| Traces  | Stable     | N/A                   |\n| Metrics | Mixed [1]  | [Go: Metric SDK (GA)] |\n| Logs    | Frozen [2] | N/A                   |\n\n[Go: Metric SDK (GA)]: https://github.com/orgs/open-telemetry/projects/34\n\n- [1]: [Metrics API](https://pkg.go.dev/go.opentelemetry.io/otel/metric) is Stable. [Metrics SDK](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) is Beta.\n- [2]: The Logs signal development is halted for this project while we stabilize the Metrics SDK.\n   No Logs Pull Requests are currently being accepted.\n\nProgress and status specific to this repository is tracked in our\n[project boards](https://github.com/open-telemetry/opentelemetry-go/projects)\nand\n[milestones](https://github.com/open-telemetry/opentelemetry-go/milestones).\n\nProject versioning information and stability guarantees can be found in the\n[versioning documentation](VERSIONING.md).\n\n### Compatibility\n\nOpenTelemetry-Go ensures compatibility with the current supported versions of\nthe [Go language](https://golang.org/doc/devel/release#policy):\n\n> Each major Go release is supported until there are two newer major releases.\n> For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was supported until the Go 1.8 release.\n\nFor versions of Go that are no longer supported upstream, opentelemetry-go will\nstop ensuring compatibility with these versions in the following manner:\n\n- A minor release of opentelemetry-go will be made to add support for the new\n  supported release of Go.\n- The following minor release of opentelemetry-go will remove compatibility\n  testing for the oldest (now archived upstream) version of Go. This, and\n  future, releases of opentelemetry-go may include features only supported by\n  the currently supported versions of Go.\n\nCurrently, this project supports the following environments.\n\n| OS      | Go Version | Architecture |\n|---------|------------|--------------|\n| Ubuntu  | 1.21       | amd64        |\n| Ubuntu  | 1.20       | amd64        |\n| Ubuntu  | 1.21       | 386          |\n| Ubuntu  | 1.20       | 386          |\n| MacOS   | 1.21       | amd64        |\n| MacOS   | 1.20       | amd64        |\n| Windows | 1.21       | amd64        |\n| Windows | 1.20       | amd64        |\n| Windows | 1.21       | 386          |\n| Windows | 1.20       | 386          |\n\nWhile this project should work for other systems, no compatibility guarantees\nare made for those systems currently.\n\n## Getting Started\n\nYou can find a getting started guide on [opentelemetry.io](https://opentelemetry.io/docs/go/getting-started/).\n\nOpenTelemetry's goal is to provide a single set of APIs to capture distributed\ntraces and metrics from your application and send them to an observability\nplatform. This project allows you to do just that for applications written in\nGo. There are two steps to this process: instrument your application, and\nconfigure an exporter.\n\n### Instrumentation\n\nTo start capturing distributed traces and metric events from your application\nit first needs to be instrumented. The easiest way to do this is by using an\ninstrumentation library for your code. Be sure to check out [the officially\nsupported instrumentation\nlibraries](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation).\n\nIf you need to extend the telemetry an instrumentation library provides or want\nto build your own instrumentation for your application directly you will need\nto use the\n[Go otel](https://pkg.go.dev/go.opentelemetry.io/otel)\npackage. The included [examples](./example/) are a good way to see some\npractical uses of this process.\n\n### Export\n\nNow that your application is instrumented to collect telemetry, it needs an\nexport pipeline to send that telemetry to an observability platform.\n\nAll officially supported exporters for the OpenTelemetry project are contained in the [exporters directory](./exporters).\n\n| Exporter                              | Metrics | Traces |\n|---------------------------------------|:-------:|:------:|\n| [OTLP](./exporters/otlp/)             |    ✓    |   ✓    |\n| [Prometheus](./exporters/prometheus/) |    ✓    |        |\n| [stdout](./exporters/stdout/)         |    ✓    |   ✓    |\n| [Zipkin](./exporters/zipkin/)         |         |   ✓    |\n\n## Contributing\n\nSee the [contributing documentation](CONTRIBUTING.md).\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/RELEASING.md",
    "content": "# Release Process\n\n## Semantic Convention Generation\n\nNew versions of the [OpenTelemetry Semantic Conventions] mean new versions of the `semconv` package need to be generated.\nThe `semconv-generate` make target is used for this.\n\n1. Checkout a local copy of the [OpenTelemetry Semantic Conventions] to the desired release tag.\n2. Pull the latest `otel/semconvgen` image: `docker pull otel/semconvgen:latest`\n3. Run the `make semconv-generate ...` target from this repository.\n\nFor example,\n\n```sh\nexport TAG=\"v1.21.0\" # Change to the release version you are generating.\nexport OTEL_SEMCONV_REPO=\"/absolute/path/to/opentelemetry/semantic-conventions\"\ndocker pull otel/semconvgen:latest\nmake semconv-generate # Uses the exported TAG and OTEL_SEMCONV_REPO.\n```\n\nThis should create a new sub-package of [`semconv`](./semconv).\nEnsure things look correct before submitting a pull request to include the addition.\n\n## Breaking changes validation\n\nYou can run `make gorelease` that runs [gorelease](https://pkg.go.dev/golang.org/x/exp/cmd/gorelease) to ensure that there are no unwanted changes done in the public API.\n\nYou can check/report problems with `gorelease` [here](https://golang.org/issues/26420).\n\n## Pre-Release\n\nFirst, decide which module sets will be released and update their versions\nin `versions.yaml`.  Commit this change to a new branch.\n\nUpdate go.mod for submodules to depend on the new release which will happen in the next step.\n\n1. Run the `prerelease` make target. It creates a branch\n    `prerelease_<module set>_<new tag>` that will contain all release changes.\n\n    ```\n    make prerelease MODSET=<module set>\n    ```\n\n2. Verify the changes.\n\n    ```\n    git diff ...prerelease_<module set>_<new tag>\n    ```\n\n    This should have changed the version for all modules to be `<new tag>`.\n    If these changes look correct, merge them into your pre-release branch:\n\n    ```go\n    git merge prerelease_<module set>_<new tag>\n    ```\n\n3. Update the [Changelog](./CHANGELOG.md).\n   - Make sure all relevant changes for this release are included and are in language that non-contributors to the project can understand.\n       To verify this, you can look directly at the commits since the `<last tag>`.\n\n       ```\n       git --no-pager log --pretty=oneline \"<last tag>..HEAD\"\n       ```\n\n   - Move all the `Unreleased` changes into a new section following the title scheme (`[<new tag>] - <date of release>`).\n   - Update all the appropriate links at the bottom.\n\n4. Push the changes to upstream and create a Pull Request on GitHub.\n    Be sure to include the curated changes from the [Changelog](./CHANGELOG.md) in the description.\n\n## Tag\n\nOnce the Pull Request with all the version changes has been approved and merged it is time to tag the merged commit.\n\n***IMPORTANT***: It is critical you use the same tag that you used in the Pre-Release step!\nFailure to do so will leave things in a broken state. As long as you do not\nchange `versions.yaml` between pre-release and this step, things should be fine.\n\n***IMPORTANT***: [There is currently no way to remove an incorrectly tagged version of a Go module](https://github.com/golang/go/issues/34189).\nIt is critical you make sure the version you push upstream is correct.\n[Failure to do so will lead to minor emergencies and tough to work around](https://github.com/open-telemetry/opentelemetry-go/issues/331).\n\n1. For each module set that will be released, run the `add-tags` make target\n    using the `<commit-hash>` of the commit on the main branch for the merged Pull Request.\n\n    ```\n    make add-tags MODSET=<module set> COMMIT=<commit hash>\n    ```\n\n    It should only be necessary to provide an explicit `COMMIT` value if the\n    current `HEAD` of your working directory is not the correct commit.\n\n2. Push tags to the upstream remote (not your fork: `github.com/open-telemetry/opentelemetry-go.git`).\n    Make sure you push all sub-modules as well.\n\n    ```\n    git push upstream <new tag>\n    git push upstream <submodules-path/new tag>\n    ...\n    ```\n\n## Release\n\nFinally create a Release for the new `<new tag>` on GitHub.\nThe release body should include all the release notes from the Changelog for this release.\n\n## Verify Examples\n\nAfter releasing verify that examples build outside of the repository.\n\n```\n./verify_examples.sh\n```\n\nThe script copies examples into a different directory removes any `replace` declarations in `go.mod` and builds them.\nThis ensures they build with the published release, not the local copy.\n\n## Post-Release\n\n### Contrib Repository\n\nOnce verified be sure to [make a release for the `contrib` repository](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/RELEASING.md) that uses this release.\n\n### Website Documentation\n\nUpdate the [Go instrumentation documentation] in the OpenTelemetry website under [content/en/docs/instrumentation/go].\nImportantly, bump any package versions referenced to be the latest one you just released and ensure all code examples still compile and are accurate.\n\n[OpenTelemetry Semantic Conventions]: https://github.com/open-telemetry/semantic-conventions\n[Go instrumentation documentation]: https://opentelemetry.io/docs/instrumentation/go/\n[content/en/docs/instrumentation/go]: https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/instrumentation/go\n\n### Demo Repository\n\nBump the dependencies in the following Go services:\n\n- [`accountingservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/accountingservice)\n- [`checkoutservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/checkoutservice)\n- [`productcatalogservice`](https://github.com/open-telemetry/opentelemetry-demo/tree/main/src/productcatalogservice)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/VERSIONING.md",
    "content": "# Versioning\n\nThis document describes the versioning policy for this repository. This policy\nis designed so the following goals can be achieved.\n\n**Users are provided a codebase of value that is stable and secure.**\n\n## Policy\n\n* Versioning of this project will be idiomatic of a Go project using [Go\n  modules](https://github.com/golang/go/wiki/Modules).\n  * [Semantic import\n    versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)\n    will be used.\n    * Versions will comply with [semver\n      2.0](https://semver.org/spec/v2.0.0.html) with the following exceptions.\n      * New methods may be added to exported API interfaces. All exported\n        interfaces that fall within this exception will include the following\n        paragraph in their public documentation.\n\n        > Warning: methods may be added to this interface in minor releases.\n\n    * If a module is version `v2` or higher, the major version of the module\n      must be included as a `/vN` at the end of the module paths used in\n      `go.mod` files (e.g., `module go.opentelemetry.io/otel/v2`, `require\n      go.opentelemetry.io/otel/v2 v2.0.1`) and in the package import path\n      (e.g., `import \"go.opentelemetry.io/otel/v2/trace\"`). This includes the\n      paths used in `go get` commands (e.g., `go get\n      go.opentelemetry.io/otel/v2@v2.0.1`.  Note there is both a `/v2` and a\n      `@v2.0.1` in that example. One way to think about it is that the module\n      name now includes the `/v2`, so include `/v2` whenever you are using the\n      module name).\n    * If a module is version `v0` or `v1`, do not include the major version in\n      either the module path or the import path.\n  * Modules will be used to encapsulate signals and components.\n    * Experimental modules still under active development will be versioned at\n      `v0` to imply the stability guarantee defined by\n      [semver](https://semver.org/spec/v2.0.0.html#spec-item-4).\n\n      > Major version zero (0.y.z) is for initial development. Anything MAY\n      > change at any time. The public API SHOULD NOT be considered stable.\n\n    * Mature modules for which we guarantee a stable public API will be versioned\n      with a major version greater than `v0`.\n      * The decision to make a module stable will be made on a case-by-case\n        basis by the maintainers of this project.\n    * Experimental modules will start their versioning at `v0.0.0` and will\n      increment their minor version when backwards incompatible changes are\n      released and increment their patch version when backwards compatible\n      changes are released.\n    * All stable modules that use the same major version number will use the\n      same entire version number.\n      * Stable modules may be released with an incremented minor or patch\n        version even though that module has not been changed, but rather so\n        that it will remain at the same version as other stable modules that\n        did undergo change.\n      * When an experimental module becomes stable a new stable module version\n        will be released and will include this now stable module. The new\n        stable module version will be an increment of the minor version number\n        and will be applied to all existing stable modules as well as the newly\n        stable module being released.\n* Versioning of the associated [contrib\n  repository](https://github.com/open-telemetry/opentelemetry-go-contrib) of\n  this project will be idiomatic of a Go project using [Go\n  modules](https://github.com/golang/go/wiki/Modules).\n  * [Semantic import\n    versioning](https://github.com/golang/go/wiki/Modules#semantic-import-versioning)\n    will be used.\n    * Versions will comply with [semver 2.0](https://semver.org/spec/v2.0.0.html).\n    * If a module is version `v2` or higher, the\n      major version of the module must be included as a `/vN` at the end of the\n      module paths used in `go.mod` files (e.g., `module\n      go.opentelemetry.io/contrib/instrumentation/host/v2`, `require\n      go.opentelemetry.io/contrib/instrumentation/host/v2 v2.0.1`) and in the\n      package import path (e.g., `import\n      \"go.opentelemetry.io/contrib/instrumentation/host/v2\"`). This includes\n      the paths used in `go get` commands (e.g., `go get\n      go.opentelemetry.io/contrib/instrumentation/host/v2@v2.0.1`.  Note there\n      is both a `/v2` and a `@v2.0.1` in that example. One way to think about\n      it is that the module name now includes the `/v2`, so include `/v2`\n      whenever you are using the module name).\n    * If a module is version `v0` or `v1`, do not include the major version\n      in either the module path or the import path.\n  * In addition to public APIs, telemetry produced by stable instrumentation\n    will remain stable and backwards compatible. This is to avoid breaking\n    alerts and dashboard.\n  * Modules will be used to encapsulate instrumentation, detectors, exporters,\n    propagators, and any other independent sets of related components.\n    * Experimental modules still under active development will be versioned at\n      `v0` to imply the stability guarantee defined by\n      [semver](https://semver.org/spec/v2.0.0.html#spec-item-4).\n\n      > Major version zero (0.y.z) is for initial development. Anything MAY\n      > change at any time. The public API SHOULD NOT be considered stable.\n\n    * Mature modules for which we guarantee a stable public API and telemetry will\n      be versioned with a major version greater than `v0`.\n    * Experimental modules will start their versioning at `v0.0.0` and will\n      increment their minor version when backwards incompatible changes are\n      released and increment their patch version when backwards compatible\n      changes are released.\n    * Stable contrib modules cannot depend on experimental modules from this\n      project.\n    * All stable contrib modules of the same major version with this project\n      will use the same entire version as this project.\n      * Stable modules may be released with an incremented minor or patch\n        version even though that module's code has not been changed. Instead\n        the only change that will have been included is to have updated that\n        modules dependency on this project's stable APIs.\n      * When an experimental module in contrib becomes stable a new stable\n        module version will be released and will include this now stable\n        module. The new stable module version will be an increment of the minor\n        version number and will be applied to all existing stable contrib\n        modules, this project's modules, and the newly stable module being\n        released.\n  * Contrib modules will be kept up to date with this project's releases.\n    * Due to the dependency contrib modules will implicitly have on this\n      project's modules the release of stable contrib modules to match the\n      released version number will be staggered after this project's release.\n      There is no explicit time guarantee for how long after this projects\n      release the contrib release will be. Effort should be made to keep them\n      as close in time as possible.\n    * No additional stable release in this project can be made until the\n      contrib repository has a matching stable release.\n    * No release can be made in the contrib repository after this project's\n      stable release except for a stable release of the contrib repository.\n* GitHub releases will be made for all releases.\n* Go modules will be made available at Go package mirrors.\n\n## Example Versioning Lifecycle\n\nTo better understand the implementation of the above policy the following\nexample is provided. This project is simplified to include only the following\nmodules and their versions:\n\n* `otel`: `v0.14.0`\n* `otel/trace`: `v0.14.0`\n* `otel/metric`: `v0.14.0`\n* `otel/baggage`: `v0.14.0`\n* `otel/sdk/trace`: `v0.14.0`\n* `otel/sdk/metric`: `v0.14.0`\n\nThese modules have been developed to a point where the `otel/trace`,\n`otel/baggage`, and `otel/sdk/trace` modules have reached a point that they\nshould be considered for a stable release. The `otel/metric` and\n`otel/sdk/metric` are still under active development and the `otel` module\ndepends on both `otel/trace` and `otel/metric`.\n\nThe `otel` package is refactored to remove its dependencies on `otel/metric` so\nit can be released as stable as well. With that done the following release\ncandidates are made:\n\n* `otel`: `v1.0.0-RC1`\n* `otel/trace`: `v1.0.0-RC1`\n* `otel/baggage`: `v1.0.0-RC1`\n* `otel/sdk/trace`: `v1.0.0-RC1`\n\nThe `otel/metric` and `otel/sdk/metric` modules remain at `v0.14.0`.\n\nA few minor issues are discovered in the `otel/trace` package. These issues are\nresolved with some minor, but backwards incompatible, changes and are released\nas a second release candidate:\n\n* `otel`: `v1.0.0-RC2`\n* `otel/trace`: `v1.0.0-RC2`\n* `otel/baggage`: `v1.0.0-RC2`\n* `otel/sdk/trace`: `v1.0.0-RC2`\n\nNotice that all module version numbers are incremented to adhere to our\nversioning policy.\n\nAfter these release candidates have been evaluated to satisfaction, they are\nreleased as version `v1.0.0`.\n\n* `otel`: `v1.0.0`\n* `otel/trace`: `v1.0.0`\n* `otel/baggage`: `v1.0.0`\n* `otel/sdk/trace`: `v1.0.0`\n\nSince both the `go` utility and the Go module system support [the semantic\nversioning definition of\nprecedence](https://semver.org/spec/v2.0.0.html#spec-item-11), this release\nwill correctly be interpreted as the successor to the previous release\ncandidates.\n\nActive development of this project continues. The `otel/metric` module now has\nbackwards incompatible changes to its API that need to be released and the\n`otel/baggage` module has a minor bug fix that needs to be released. The\nfollowing release is made:\n\n* `otel`: `v1.0.1`\n* `otel/trace`: `v1.0.1`\n* `otel/metric`: `v0.15.0`\n* `otel/baggage`: `v1.0.1`\n* `otel/sdk/trace`: `v1.0.1`\n* `otel/sdk/metric`: `v0.15.0`\n\nNotice that, again, all stable module versions are incremented in unison and\nthe `otel/sdk/metric` package, which depends on the `otel/metric` package, also\nbumped its version. This bump of the `otel/sdk/metric` package makes sense\ngiven their coupling, though it is not explicitly required by our versioning\npolicy.\n\nAs we progress, the `otel/metric` and `otel/sdk/metric` packages have reached a\npoint where they should be evaluated for stability. The `otel` module is\nreintegrated with the `otel/metric` package and the following release is made:\n\n* `otel`: `v1.1.0-RC1`\n* `otel/trace`: `v1.1.0-RC1`\n* `otel/metric`: `v1.1.0-RC1`\n* `otel/baggage`: `v1.1.0-RC1`\n* `otel/sdk/trace`: `v1.1.0-RC1`\n* `otel/sdk/metric`: `v1.1.0-RC1`\n\nAll the modules are evaluated and determined to a viable stable release. They\nare then released as version `v1.1.0` (the minor version is incremented to\nindicate the addition of new signal).\n\n* `otel`: `v1.1.0`\n* `otel/trace`: `v1.1.0`\n* `otel/metric`: `v1.1.0`\n* `otel/baggage`: `v1.1.0`\n* `otel/sdk/trace`: `v1.1.0`\n* `otel/sdk/metric`: `v1.1.0`\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n// Package attribute provides key and value attributes.\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/encoder.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"bytes\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\ntype (\n\t// Encoder is a mechanism for serializing an attribute set into a specific\n\t// string representation that supports caching, to avoid repeated\n\t// serialization. An example could be an exporter encoding the attribute\n\t// set into a wire representation.\n\tEncoder interface {\n\t\t// Encode returns the serialized encoding of the attribute set using\n\t\t// its Iterator. This result may be cached by a attribute.Set.\n\t\tEncode(iterator Iterator) string\n\n\t\t// ID returns a value that is unique for each class of attribute\n\t\t// encoder. Attribute encoders allocate these using `NewEncoderID`.\n\t\tID() EncoderID\n\t}\n\n\t// EncoderID is used to identify distinct Encoder\n\t// implementations, for caching encoded results.\n\tEncoderID struct {\n\t\tvalue uint64\n\t}\n\n\t// defaultAttrEncoder uses a sync.Pool of buffers to reduce the number of\n\t// allocations used in encoding attributes. This implementation encodes a\n\t// comma-separated list of key=value, with '/'-escaping of '=', ',', and\n\t// '\\'.\n\tdefaultAttrEncoder struct {\n\t\t// pool is a pool of attribute set builders. The buffers in this pool\n\t\t// grow to a size that most attribute encodings will not allocate new\n\t\t// memory.\n\t\tpool sync.Pool // *bytes.Buffer\n\t}\n)\n\n// escapeChar is used to ensure uniqueness of the attribute encoding where\n// keys or values contain either '=' or ','.  Since there is no parser needed\n// for this encoding and its only requirement is to be unique, this choice is\n// arbitrary.  Users will see these in some exporters (e.g., stdout), so the\n// backslash ('\\') is used as a conventional choice.\nconst escapeChar = '\\\\'\n\nvar (\n\t_ Encoder = &defaultAttrEncoder{}\n\n\t// encoderIDCounter is for generating IDs for other attribute encoders.\n\tencoderIDCounter uint64\n\n\tdefaultEncoderOnce     sync.Once\n\tdefaultEncoderID       = NewEncoderID()\n\tdefaultEncoderInstance *defaultAttrEncoder\n)\n\n// NewEncoderID returns a unique attribute encoder ID. It should be called\n// once per each type of attribute encoder. Preferably in init() or in var\n// definition.\nfunc NewEncoderID() EncoderID {\n\treturn EncoderID{value: atomic.AddUint64(&encoderIDCounter, 1)}\n}\n\n// DefaultEncoder returns an attribute encoder that encodes attributes in such\n// a way that each escaped attribute's key is followed by an equal sign and\n// then by an escaped attribute's value. All key-value pairs are separated by\n// a comma.\n//\n// Escaping is done by prepending a backslash before either a backslash, equal\n// sign or a comma.\nfunc DefaultEncoder() Encoder {\n\tdefaultEncoderOnce.Do(func() {\n\t\tdefaultEncoderInstance = &defaultAttrEncoder{\n\t\t\tpool: sync.Pool{\n\t\t\t\tNew: func() interface{} {\n\t\t\t\t\treturn &bytes.Buffer{}\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t})\n\treturn defaultEncoderInstance\n}\n\n// Encode is a part of an implementation of the AttributeEncoder interface.\nfunc (d *defaultAttrEncoder) Encode(iter Iterator) string {\n\tbuf := d.pool.Get().(*bytes.Buffer)\n\tdefer d.pool.Put(buf)\n\tbuf.Reset()\n\n\tfor iter.Next() {\n\t\ti, keyValue := iter.IndexedAttribute()\n\t\tif i > 0 {\n\t\t\t_, _ = buf.WriteRune(',')\n\t\t}\n\t\tcopyAndEscape(buf, string(keyValue.Key))\n\n\t\t_, _ = buf.WriteRune('=')\n\n\t\tif keyValue.Value.Type() == STRING {\n\t\t\tcopyAndEscape(buf, keyValue.Value.AsString())\n\t\t} else {\n\t\t\t_, _ = buf.WriteString(keyValue.Value.Emit())\n\t\t}\n\t}\n\treturn buf.String()\n}\n\n// ID is a part of an implementation of the AttributeEncoder interface.\nfunc (*defaultAttrEncoder) ID() EncoderID {\n\treturn defaultEncoderID\n}\n\n// copyAndEscape escapes `=`, `,` and its own escape character (`\\`),\n// making the default encoding unique.\nfunc copyAndEscape(buf *bytes.Buffer, val string) {\n\tfor _, ch := range val {\n\t\tswitch ch {\n\t\tcase '=', ',', escapeChar:\n\t\t\t_, _ = buf.WriteRune(escapeChar)\n\t\t}\n\t\t_, _ = buf.WriteRune(ch)\n\t}\n}\n\n// Valid returns true if this encoder ID was allocated by\n// `NewEncoderID`.  Invalid encoder IDs will not be cached.\nfunc (id EncoderID) Valid() bool {\n\treturn id.value != 0\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/filter.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\n// Filter supports removing certain attributes from attribute sets. When\n// the filter returns true, the attribute will be kept in the filtered\n// attribute set. When the filter returns false, the attribute is excluded\n// from the filtered attribute set, and the attribute instead appears in\n// the removed list of excluded attributes.\ntype Filter func(KeyValue) bool\n\n// NewAllowKeysFilter returns a Filter that only allows attributes with one of\n// the provided keys.\n//\n// If keys is empty a deny-all filter is returned.\nfunc NewAllowKeysFilter(keys ...Key) Filter {\n\tif len(keys) <= 0 {\n\t\treturn func(kv KeyValue) bool { return false }\n\t}\n\n\tallowed := make(map[Key]struct{})\n\tfor _, k := range keys {\n\t\tallowed[k] = struct{}{}\n\t}\n\treturn func(kv KeyValue) bool {\n\t\t_, ok := allowed[kv.Key]\n\t\treturn ok\n\t}\n}\n\n// NewDenyKeysFilter returns a Filter that only allows attributes\n// that do not have one of the provided keys.\n//\n// If keys is empty an allow-all filter is returned.\nfunc NewDenyKeysFilter(keys ...Key) Filter {\n\tif len(keys) <= 0 {\n\t\treturn func(kv KeyValue) bool { return true }\n\t}\n\n\tforbid := make(map[Key]struct{})\n\tfor _, k := range keys {\n\t\tforbid[k] = struct{}{}\n\t}\n\treturn func(kv KeyValue) bool {\n\t\t_, ok := forbid[kv.Key]\n\t\treturn !ok\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/iterator.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\n// Iterator allows iterating over the set of attributes in order, sorted by\n// key.\ntype Iterator struct {\n\tstorage *Set\n\tidx     int\n}\n\n// MergeIterator supports iterating over two sets of attributes while\n// eliminating duplicate values from the combined set. The first iterator\n// value takes precedence.\ntype MergeIterator struct {\n\tone     oneIterator\n\ttwo     oneIterator\n\tcurrent KeyValue\n}\n\ntype oneIterator struct {\n\titer Iterator\n\tdone bool\n\tattr KeyValue\n}\n\n// Next moves the iterator to the next position. Returns false if there are no\n// more attributes.\nfunc (i *Iterator) Next() bool {\n\ti.idx++\n\treturn i.idx < i.Len()\n}\n\n// Label returns current KeyValue. Must be called only after Next returns\n// true.\n//\n// Deprecated: Use Attribute instead.\nfunc (i *Iterator) Label() KeyValue {\n\treturn i.Attribute()\n}\n\n// Attribute returns the current KeyValue of the Iterator. It must be called\n// only after Next returns true.\nfunc (i *Iterator) Attribute() KeyValue {\n\tkv, _ := i.storage.Get(i.idx)\n\treturn kv\n}\n\n// IndexedLabel returns current index and attribute. Must be called only\n// after Next returns true.\n//\n// Deprecated: Use IndexedAttribute instead.\nfunc (i *Iterator) IndexedLabel() (int, KeyValue) {\n\treturn i.idx, i.Attribute()\n}\n\n// IndexedAttribute returns current index and attribute. Must be called only\n// after Next returns true.\nfunc (i *Iterator) IndexedAttribute() (int, KeyValue) {\n\treturn i.idx, i.Attribute()\n}\n\n// Len returns a number of attributes in the iterated set.\nfunc (i *Iterator) Len() int {\n\treturn i.storage.Len()\n}\n\n// ToSlice is a convenience function that creates a slice of attributes from\n// the passed iterator. The iterator is set up to start from the beginning\n// before creating the slice.\nfunc (i *Iterator) ToSlice() []KeyValue {\n\tl := i.Len()\n\tif l == 0 {\n\t\treturn nil\n\t}\n\ti.idx = -1\n\tslice := make([]KeyValue, 0, l)\n\tfor i.Next() {\n\t\tslice = append(slice, i.Attribute())\n\t}\n\treturn slice\n}\n\n// NewMergeIterator returns a MergeIterator for merging two attribute sets.\n// Duplicates are resolved by taking the value from the first set.\nfunc NewMergeIterator(s1, s2 *Set) MergeIterator {\n\tmi := MergeIterator{\n\t\tone: makeOne(s1.Iter()),\n\t\ttwo: makeOne(s2.Iter()),\n\t}\n\treturn mi\n}\n\nfunc makeOne(iter Iterator) oneIterator {\n\toi := oneIterator{\n\t\titer: iter,\n\t}\n\toi.advance()\n\treturn oi\n}\n\nfunc (oi *oneIterator) advance() {\n\tif oi.done = !oi.iter.Next(); !oi.done {\n\t\toi.attr = oi.iter.Attribute()\n\t}\n}\n\n// Next returns true if there is another attribute available.\nfunc (m *MergeIterator) Next() bool {\n\tif m.one.done && m.two.done {\n\t\treturn false\n\t}\n\tif m.one.done {\n\t\tm.current = m.two.attr\n\t\tm.two.advance()\n\t\treturn true\n\t}\n\tif m.two.done {\n\t\tm.current = m.one.attr\n\t\tm.one.advance()\n\t\treturn true\n\t}\n\tif m.one.attr.Key == m.two.attr.Key {\n\t\tm.current = m.one.attr // first iterator attribute value wins\n\t\tm.one.advance()\n\t\tm.two.advance()\n\t\treturn true\n\t}\n\tif m.one.attr.Key < m.two.attr.Key {\n\t\tm.current = m.one.attr\n\t\tm.one.advance()\n\t\treturn true\n\t}\n\tm.current = m.two.attr\n\tm.two.advance()\n\treturn true\n}\n\n// Label returns the current value after Next() returns true.\n//\n// Deprecated: Use Attribute instead.\nfunc (m *MergeIterator) Label() KeyValue {\n\treturn m.current\n}\n\n// Attribute returns the current value after Next() returns true.\nfunc (m *MergeIterator) Attribute() KeyValue {\n\treturn m.current\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/key.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\n// Key represents the key part in key-value pairs. It's a string. The\n// allowed character set in the key depends on the use of the key.\ntype Key string\n\n// Bool creates a KeyValue instance with a BOOL Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Bool(name, value).\nfunc (k Key) Bool(v bool) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: BoolValue(v),\n\t}\n}\n\n// BoolSlice creates a KeyValue instance with a BOOLSLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- BoolSlice(name, value).\nfunc (k Key) BoolSlice(v []bool) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: BoolSliceValue(v),\n\t}\n}\n\n// Int creates a KeyValue instance with an INT64 Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Int(name, value).\nfunc (k Key) Int(v int) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: IntValue(v),\n\t}\n}\n\n// IntSlice creates a KeyValue instance with an INT64SLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- IntSlice(name, value).\nfunc (k Key) IntSlice(v []int) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: IntSliceValue(v),\n\t}\n}\n\n// Int64 creates a KeyValue instance with an INT64 Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Int64(name, value).\nfunc (k Key) Int64(v int64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Int64Value(v),\n\t}\n}\n\n// Int64Slice creates a KeyValue instance with an INT64SLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Int64Slice(name, value).\nfunc (k Key) Int64Slice(v []int64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Int64SliceValue(v),\n\t}\n}\n\n// Float64 creates a KeyValue instance with a FLOAT64 Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Float64(name, value).\nfunc (k Key) Float64(v float64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Float64Value(v),\n\t}\n}\n\n// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- Float64(name, value).\nfunc (k Key) Float64Slice(v []float64) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: Float64SliceValue(v),\n\t}\n}\n\n// String creates a KeyValue instance with a STRING Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- String(name, value).\nfunc (k Key) String(v string) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: StringValue(v),\n\t}\n}\n\n// StringSlice creates a KeyValue instance with a STRINGSLICE Value.\n//\n// If creating both a key and value at the same time, use the provided\n// convenience function instead -- StringSlice(name, value).\nfunc (k Key) StringSlice(v []string) KeyValue {\n\treturn KeyValue{\n\t\tKey:   k,\n\t\tValue: StringSliceValue(v),\n\t}\n}\n\n// Defined returns true for non-empty keys.\nfunc (k Key) Defined() bool {\n\treturn len(k) != 0\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/kv.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"fmt\"\n)\n\n// KeyValue holds a key and value pair.\ntype KeyValue struct {\n\tKey   Key\n\tValue Value\n}\n\n// Valid returns if kv is a valid OpenTelemetry attribute.\nfunc (kv KeyValue) Valid() bool {\n\treturn kv.Key.Defined() && kv.Value.Type() != INVALID\n}\n\n// Bool creates a KeyValue with a BOOL Value type.\nfunc Bool(k string, v bool) KeyValue {\n\treturn Key(k).Bool(v)\n}\n\n// BoolSlice creates a KeyValue with a BOOLSLICE Value type.\nfunc BoolSlice(k string, v []bool) KeyValue {\n\treturn Key(k).BoolSlice(v)\n}\n\n// Int creates a KeyValue with an INT64 Value type.\nfunc Int(k string, v int) KeyValue {\n\treturn Key(k).Int(v)\n}\n\n// IntSlice creates a KeyValue with an INT64SLICE Value type.\nfunc IntSlice(k string, v []int) KeyValue {\n\treturn Key(k).IntSlice(v)\n}\n\n// Int64 creates a KeyValue with an INT64 Value type.\nfunc Int64(k string, v int64) KeyValue {\n\treturn Key(k).Int64(v)\n}\n\n// Int64Slice creates a KeyValue with an INT64SLICE Value type.\nfunc Int64Slice(k string, v []int64) KeyValue {\n\treturn Key(k).Int64Slice(v)\n}\n\n// Float64 creates a KeyValue with a FLOAT64 Value type.\nfunc Float64(k string, v float64) KeyValue {\n\treturn Key(k).Float64(v)\n}\n\n// Float64Slice creates a KeyValue with a FLOAT64SLICE Value type.\nfunc Float64Slice(k string, v []float64) KeyValue {\n\treturn Key(k).Float64Slice(v)\n}\n\n// String creates a KeyValue with a STRING Value type.\nfunc String(k, v string) KeyValue {\n\treturn Key(k).String(v)\n}\n\n// StringSlice creates a KeyValue with a STRINGSLICE Value type.\nfunc StringSlice(k string, v []string) KeyValue {\n\treturn Key(k).StringSlice(v)\n}\n\n// Stringer creates a new key-value pair with a passed name and a string\n// value generated by the passed Stringer interface.\nfunc Stringer(k string, v fmt.Stringer) KeyValue {\n\treturn Key(k).String(v.String())\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/set.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"encoding/json\"\n\t\"reflect\"\n\t\"sort\"\n\t\"sync\"\n)\n\ntype (\n\t// Set is the representation for a distinct attribute set. It manages an\n\t// immutable set of attributes, with an internal cache for storing\n\t// attribute encodings.\n\t//\n\t// This type supports the Equivalent method of comparison using values of\n\t// type Distinct.\n\tSet struct {\n\t\tequivalent Distinct\n\t}\n\n\t// Distinct wraps a variable-size array of KeyValue, constructed with keys\n\t// in sorted order. This can be used as a map key or for equality checking\n\t// between Sets.\n\tDistinct struct {\n\t\tiface interface{}\n\t}\n\n\t// Sortable implements sort.Interface, used for sorting KeyValue. This is\n\t// an exported type to support a memory optimization. A pointer to one of\n\t// these is needed for the call to sort.Stable(), which the caller may\n\t// provide in order to avoid an allocation. See NewSetWithSortable().\n\tSortable []KeyValue\n)\n\nvar (\n\t// keyValueType is used in computeDistinctReflect.\n\tkeyValueType = reflect.TypeOf(KeyValue{})\n\n\t// emptySet is returned for empty attribute sets.\n\temptySet = &Set{\n\t\tequivalent: Distinct{\n\t\t\tiface: [0]KeyValue{},\n\t\t},\n\t}\n\n\t// sortables is a pool of Sortables used to create Sets with a user does\n\t// not provide one.\n\tsortables = sync.Pool{\n\t\tNew: func() interface{} { return new(Sortable) },\n\t}\n)\n\n// EmptySet returns a reference to a Set with no elements.\n//\n// This is a convenience provided for optimized calling utility.\nfunc EmptySet() *Set {\n\treturn emptySet\n}\n\n// reflectValue abbreviates reflect.ValueOf(d).\nfunc (d Distinct) reflectValue() reflect.Value {\n\treturn reflect.ValueOf(d.iface)\n}\n\n// Valid returns true if this value refers to a valid Set.\nfunc (d Distinct) Valid() bool {\n\treturn d.iface != nil\n}\n\n// Len returns the number of attributes in this set.\nfunc (l *Set) Len() int {\n\tif l == nil || !l.equivalent.Valid() {\n\t\treturn 0\n\t}\n\treturn l.equivalent.reflectValue().Len()\n}\n\n// Get returns the KeyValue at ordered position idx in this set.\nfunc (l *Set) Get(idx int) (KeyValue, bool) {\n\tif l == nil || !l.equivalent.Valid() {\n\t\treturn KeyValue{}, false\n\t}\n\tvalue := l.equivalent.reflectValue()\n\n\tif idx >= 0 && idx < value.Len() {\n\t\t// Note: The Go compiler successfully avoids an allocation for\n\t\t// the interface{} conversion here:\n\t\treturn value.Index(idx).Interface().(KeyValue), true\n\t}\n\n\treturn KeyValue{}, false\n}\n\n// Value returns the value of a specified key in this set.\nfunc (l *Set) Value(k Key) (Value, bool) {\n\tif l == nil || !l.equivalent.Valid() {\n\t\treturn Value{}, false\n\t}\n\trValue := l.equivalent.reflectValue()\n\tvlen := rValue.Len()\n\n\tidx := sort.Search(vlen, func(idx int) bool {\n\t\treturn rValue.Index(idx).Interface().(KeyValue).Key >= k\n\t})\n\tif idx >= vlen {\n\t\treturn Value{}, false\n\t}\n\tkeyValue := rValue.Index(idx).Interface().(KeyValue)\n\tif k == keyValue.Key {\n\t\treturn keyValue.Value, true\n\t}\n\treturn Value{}, false\n}\n\n// HasValue tests whether a key is defined in this set.\nfunc (l *Set) HasValue(k Key) bool {\n\tif l == nil {\n\t\treturn false\n\t}\n\t_, ok := l.Value(k)\n\treturn ok\n}\n\n// Iter returns an iterator for visiting the attributes in this set.\nfunc (l *Set) Iter() Iterator {\n\treturn Iterator{\n\t\tstorage: l,\n\t\tidx:     -1,\n\t}\n}\n\n// ToSlice returns the set of attributes belonging to this set, sorted, where\n// keys appear no more than once.\nfunc (l *Set) ToSlice() []KeyValue {\n\titer := l.Iter()\n\treturn iter.ToSlice()\n}\n\n// Equivalent returns a value that may be used as a map key. The Distinct type\n// guarantees that the result will equal the equivalent. Distinct value of any\n// attribute set with the same elements as this, where sets are made unique by\n// choosing the last value in the input for any given key.\nfunc (l *Set) Equivalent() Distinct {\n\tif l == nil || !l.equivalent.Valid() {\n\t\treturn emptySet.equivalent\n\t}\n\treturn l.equivalent\n}\n\n// Equals returns true if the argument set is equivalent to this set.\nfunc (l *Set) Equals(o *Set) bool {\n\treturn l.Equivalent() == o.Equivalent()\n}\n\n// Encoded returns the encoded form of this set, according to encoder.\nfunc (l *Set) Encoded(encoder Encoder) string {\n\tif l == nil || encoder == nil {\n\t\treturn \"\"\n\t}\n\n\treturn encoder.Encode(l.Iter())\n}\n\nfunc empty() Set {\n\treturn Set{\n\t\tequivalent: emptySet.equivalent,\n\t}\n}\n\n// NewSet returns a new Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\n//\n// Except for empty sets, this method adds an additional allocation compared\n// with calls that include a Sortable.\nfunc NewSet(kvs ...KeyValue) Set {\n\t// Check for empty set.\n\tif len(kvs) == 0 {\n\t\treturn empty()\n\t}\n\tsrt := sortables.Get().(*Sortable)\n\ts, _ := NewSetWithSortableFiltered(kvs, srt, nil)\n\tsortables.Put(srt)\n\treturn s\n}\n\n// NewSetWithSortable returns a new Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\n//\n// This call includes a Sortable option as a memory optimization.\nfunc NewSetWithSortable(kvs []KeyValue, tmp *Sortable) Set {\n\t// Check for empty set.\n\tif len(kvs) == 0 {\n\t\treturn empty()\n\t}\n\ts, _ := NewSetWithSortableFiltered(kvs, tmp, nil)\n\treturn s\n}\n\n// NewSetWithFiltered returns a new Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\n//\n// This call includes a Filter to include/exclude attribute keys from the\n// return value. Excluded keys are returned as a slice of attribute values.\nfunc NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) {\n\t// Check for empty set.\n\tif len(kvs) == 0 {\n\t\treturn empty(), nil\n\t}\n\tsrt := sortables.Get().(*Sortable)\n\ts, filtered := NewSetWithSortableFiltered(kvs, srt, filter)\n\tsortables.Put(srt)\n\treturn s, filtered\n}\n\n// NewSetWithSortableFiltered returns a new Set.\n//\n// Duplicate keys are eliminated by taking the last value.  This\n// re-orders the input slice so that unique last-values are contiguous\n// at the end of the slice.\n//\n// This ensures the following:\n//\n// - Last-value-wins semantics\n// - Caller sees the reordering, but doesn't lose values\n// - Repeated call preserve last-value wins.\n//\n// Note that methods are defined on Set, although this returns Set. Callers\n// can avoid memory allocations by:\n//\n// - allocating a Sortable for use as a temporary in this method\n// - allocating a Set for storing the return value of this constructor.\n//\n// The result maintains a cache of encoded attributes, by attribute.EncoderID.\n// This value should not be copied after its first use.\n//\n// The second []KeyValue return value is a list of attributes that were\n// excluded by the Filter (if non-nil).\nfunc NewSetWithSortableFiltered(kvs []KeyValue, tmp *Sortable, filter Filter) (Set, []KeyValue) {\n\t// Check for empty set.\n\tif len(kvs) == 0 {\n\t\treturn empty(), nil\n\t}\n\n\t*tmp = kvs\n\n\t// Stable sort so the following de-duplication can implement\n\t// last-value-wins semantics.\n\tsort.Stable(tmp)\n\n\t*tmp = nil\n\n\tposition := len(kvs) - 1\n\toffset := position - 1\n\n\t// The requirements stated above require that the stable\n\t// result be placed in the end of the input slice, while\n\t// overwritten values are swapped to the beginning.\n\t//\n\t// De-duplicate with last-value-wins semantics.  Preserve\n\t// duplicate values at the beginning of the input slice.\n\tfor ; offset >= 0; offset-- {\n\t\tif kvs[offset].Key == kvs[position].Key {\n\t\t\tcontinue\n\t\t}\n\t\tposition--\n\t\tkvs[offset], kvs[position] = kvs[position], kvs[offset]\n\t}\n\tif filter != nil {\n\t\treturn filterSet(kvs[position:], filter)\n\t}\n\treturn Set{\n\t\tequivalent: computeDistinct(kvs[position:]),\n\t}, nil\n}\n\n// filterSet reorders kvs so that included keys are contiguous at the end of\n// the slice, while excluded keys precede the included keys.\nfunc filterSet(kvs []KeyValue, filter Filter) (Set, []KeyValue) {\n\tvar excluded []KeyValue\n\n\t// Move attributes that do not match the filter so they're adjacent before\n\t// calling computeDistinct().\n\tdistinctPosition := len(kvs)\n\n\t// Swap indistinct keys forward and distinct keys toward the\n\t// end of the slice.\n\toffset := len(kvs) - 1\n\tfor ; offset >= 0; offset-- {\n\t\tif filter(kvs[offset]) {\n\t\t\tdistinctPosition--\n\t\t\tkvs[offset], kvs[distinctPosition] = kvs[distinctPosition], kvs[offset]\n\t\t\tcontinue\n\t\t}\n\t}\n\texcluded = kvs[:distinctPosition]\n\n\treturn Set{\n\t\tequivalent: computeDistinct(kvs[distinctPosition:]),\n\t}, excluded\n}\n\n// Filter returns a filtered copy of this Set. See the documentation for\n// NewSetWithSortableFiltered for more details.\nfunc (l *Set) Filter(re Filter) (Set, []KeyValue) {\n\tif re == nil {\n\t\treturn Set{\n\t\t\tequivalent: l.equivalent,\n\t\t}, nil\n\t}\n\n\t// Note: This could be refactored to avoid the temporary slice\n\t// allocation, if it proves to be expensive.\n\treturn filterSet(l.ToSlice(), re)\n}\n\n// computeDistinct returns a Distinct using either the fixed- or\n// reflect-oriented code path, depending on the size of the input. The input\n// slice is assumed to already be sorted and de-duplicated.\nfunc computeDistinct(kvs []KeyValue) Distinct {\n\tiface := computeDistinctFixed(kvs)\n\tif iface == nil {\n\t\tiface = computeDistinctReflect(kvs)\n\t}\n\treturn Distinct{\n\t\tiface: iface,\n\t}\n}\n\n// computeDistinctFixed computes a Distinct for small slices. It returns nil\n// if the input is too large for this code path.\nfunc computeDistinctFixed(kvs []KeyValue) interface{} {\n\tswitch len(kvs) {\n\tcase 1:\n\t\tptr := new([1]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 2:\n\t\tptr := new([2]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 3:\n\t\tptr := new([3]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 4:\n\t\tptr := new([4]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 5:\n\t\tptr := new([5]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 6:\n\t\tptr := new([6]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 7:\n\t\tptr := new([7]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 8:\n\t\tptr := new([8]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 9:\n\t\tptr := new([9]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tcase 10:\n\t\tptr := new([10]KeyValue)\n\t\tcopy((*ptr)[:], kvs)\n\t\treturn *ptr\n\tdefault:\n\t\treturn nil\n\t}\n}\n\n// computeDistinctReflect computes a Distinct using reflection, works for any\n// size input.\nfunc computeDistinctReflect(kvs []KeyValue) interface{} {\n\tat := reflect.New(reflect.ArrayOf(len(kvs), keyValueType)).Elem()\n\tfor i, keyValue := range kvs {\n\t\t*(at.Index(i).Addr().Interface().(*KeyValue)) = keyValue\n\t}\n\treturn at.Interface()\n}\n\n// MarshalJSON returns the JSON encoding of the Set.\nfunc (l *Set) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(l.equivalent.iface)\n}\n\n// MarshalLog is the marshaling function used by the logging system to represent this exporter.\nfunc (l Set) MarshalLog() interface{} {\n\tkvs := make(map[string]string)\n\tfor _, kv := range l.ToSlice() {\n\t\tkvs[string(kv.Key)] = kv.Value.Emit()\n\t}\n\treturn kvs\n}\n\n// Len implements sort.Interface.\nfunc (l *Sortable) Len() int {\n\treturn len(*l)\n}\n\n// Swap implements sort.Interface.\nfunc (l *Sortable) Swap(i, j int) {\n\t(*l)[i], (*l)[j] = (*l)[j], (*l)[i]\n}\n\n// Less implements sort.Interface.\nfunc (l *Sortable) Less(i, j int) bool {\n\treturn (*l)[i].Key < (*l)[j].Key\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/type_string.go",
    "content": "// Code generated by \"stringer -type=Type\"; DO NOT EDIT.\n\npackage attribute\n\nimport \"strconv\"\n\nfunc _() {\n\t// An \"invalid array index\" compiler error signifies that the constant values have changed.\n\t// Re-run the stringer command to generate them again.\n\tvar x [1]struct{}\n\t_ = x[INVALID-0]\n\t_ = x[BOOL-1]\n\t_ = x[INT64-2]\n\t_ = x[FLOAT64-3]\n\t_ = x[STRING-4]\n\t_ = x[BOOLSLICE-5]\n\t_ = x[INT64SLICE-6]\n\t_ = x[FLOAT64SLICE-7]\n\t_ = x[STRINGSLICE-8]\n}\n\nconst _Type_name = \"INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE\"\n\nvar _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71}\n\nfunc (i Type) String() string {\n\tif i < 0 || i >= Type(len(_Type_index)-1) {\n\t\treturn \"Type(\" + strconv.FormatInt(int64(i), 10) + \")\"\n\t}\n\treturn _Type_name[_Type_index[i]:_Type_index[i+1]]\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/attribute/value.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage attribute // import \"go.opentelemetry.io/otel/attribute\"\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"strconv\"\n\n\t\"go.opentelemetry.io/otel/internal\"\n\t\"go.opentelemetry.io/otel/internal/attribute\"\n)\n\n//go:generate stringer -type=Type\n\n// Type describes the type of the data Value holds.\ntype Type int // nolint: revive  // redefines builtin Type.\n\n// Value represents the value part in key-value pairs.\ntype Value struct {\n\tvtype    Type\n\tnumeric  uint64\n\tstringly string\n\tslice    interface{}\n}\n\nconst (\n\t// INVALID is used for a Value with no value set.\n\tINVALID Type = iota\n\t// BOOL is a boolean Type Value.\n\tBOOL\n\t// INT64 is a 64-bit signed integral Type Value.\n\tINT64\n\t// FLOAT64 is a 64-bit floating point Type Value.\n\tFLOAT64\n\t// STRING is a string Type Value.\n\tSTRING\n\t// BOOLSLICE is a slice of booleans Type Value.\n\tBOOLSLICE\n\t// INT64SLICE is a slice of 64-bit signed integral numbers Type Value.\n\tINT64SLICE\n\t// FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value.\n\tFLOAT64SLICE\n\t// STRINGSLICE is a slice of strings Type Value.\n\tSTRINGSLICE\n)\n\n// BoolValue creates a BOOL Value.\nfunc BoolValue(v bool) Value {\n\treturn Value{\n\t\tvtype:   BOOL,\n\t\tnumeric: internal.BoolToRaw(v),\n\t}\n}\n\n// BoolSliceValue creates a BOOLSLICE Value.\nfunc BoolSliceValue(v []bool) Value {\n\treturn Value{vtype: BOOLSLICE, slice: attribute.BoolSliceValue(v)}\n}\n\n// IntValue creates an INT64 Value.\nfunc IntValue(v int) Value {\n\treturn Int64Value(int64(v))\n}\n\n// IntSliceValue creates an INTSLICE Value.\nfunc IntSliceValue(v []int) Value {\n\tvar int64Val int64\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(int64Val)))\n\tfor i, val := range v {\n\t\tcp.Elem().Index(i).SetInt(int64(val))\n\t}\n\treturn Value{\n\t\tvtype: INT64SLICE,\n\t\tslice: cp.Elem().Interface(),\n\t}\n}\n\n// Int64Value creates an INT64 Value.\nfunc Int64Value(v int64) Value {\n\treturn Value{\n\t\tvtype:   INT64,\n\t\tnumeric: internal.Int64ToRaw(v),\n\t}\n}\n\n// Int64SliceValue creates an INT64SLICE Value.\nfunc Int64SliceValue(v []int64) Value {\n\treturn Value{vtype: INT64SLICE, slice: attribute.Int64SliceValue(v)}\n}\n\n// Float64Value creates a FLOAT64 Value.\nfunc Float64Value(v float64) Value {\n\treturn Value{\n\t\tvtype:   FLOAT64,\n\t\tnumeric: internal.Float64ToRaw(v),\n\t}\n}\n\n// Float64SliceValue creates a FLOAT64SLICE Value.\nfunc Float64SliceValue(v []float64) Value {\n\treturn Value{vtype: FLOAT64SLICE, slice: attribute.Float64SliceValue(v)}\n}\n\n// StringValue creates a STRING Value.\nfunc StringValue(v string) Value {\n\treturn Value{\n\t\tvtype:    STRING,\n\t\tstringly: v,\n\t}\n}\n\n// StringSliceValue creates a STRINGSLICE Value.\nfunc StringSliceValue(v []string) Value {\n\treturn Value{vtype: STRINGSLICE, slice: attribute.StringSliceValue(v)}\n}\n\n// Type returns a type of the Value.\nfunc (v Value) Type() Type {\n\treturn v.vtype\n}\n\n// AsBool returns the bool value. Make sure that the Value's type is\n// BOOL.\nfunc (v Value) AsBool() bool {\n\treturn internal.RawToBool(v.numeric)\n}\n\n// AsBoolSlice returns the []bool value. Make sure that the Value's type is\n// BOOLSLICE.\nfunc (v Value) AsBoolSlice() []bool {\n\tif v.vtype != BOOLSLICE {\n\t\treturn nil\n\t}\n\treturn v.asBoolSlice()\n}\n\nfunc (v Value) asBoolSlice() []bool {\n\treturn attribute.AsBoolSlice(v.slice)\n}\n\n// AsInt64 returns the int64 value. Make sure that the Value's type is\n// INT64.\nfunc (v Value) AsInt64() int64 {\n\treturn internal.RawToInt64(v.numeric)\n}\n\n// AsInt64Slice returns the []int64 value. Make sure that the Value's type is\n// INT64SLICE.\nfunc (v Value) AsInt64Slice() []int64 {\n\tif v.vtype != INT64SLICE {\n\t\treturn nil\n\t}\n\treturn v.asInt64Slice()\n}\n\nfunc (v Value) asInt64Slice() []int64 {\n\treturn attribute.AsInt64Slice(v.slice)\n}\n\n// AsFloat64 returns the float64 value. Make sure that the Value's\n// type is FLOAT64.\nfunc (v Value) AsFloat64() float64 {\n\treturn internal.RawToFloat64(v.numeric)\n}\n\n// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is\n// FLOAT64SLICE.\nfunc (v Value) AsFloat64Slice() []float64 {\n\tif v.vtype != FLOAT64SLICE {\n\t\treturn nil\n\t}\n\treturn v.asFloat64Slice()\n}\n\nfunc (v Value) asFloat64Slice() []float64 {\n\treturn attribute.AsFloat64Slice(v.slice)\n}\n\n// AsString returns the string value. Make sure that the Value's type\n// is STRING.\nfunc (v Value) AsString() string {\n\treturn v.stringly\n}\n\n// AsStringSlice returns the []string value. Make sure that the Value's type is\n// STRINGSLICE.\nfunc (v Value) AsStringSlice() []string {\n\tif v.vtype != STRINGSLICE {\n\t\treturn nil\n\t}\n\treturn v.asStringSlice()\n}\n\nfunc (v Value) asStringSlice() []string {\n\treturn attribute.AsStringSlice(v.slice)\n}\n\ntype unknownValueType struct{}\n\n// AsInterface returns Value's data as interface{}.\nfunc (v Value) AsInterface() interface{} {\n\tswitch v.Type() {\n\tcase BOOL:\n\t\treturn v.AsBool()\n\tcase BOOLSLICE:\n\t\treturn v.asBoolSlice()\n\tcase INT64:\n\t\treturn v.AsInt64()\n\tcase INT64SLICE:\n\t\treturn v.asInt64Slice()\n\tcase FLOAT64:\n\t\treturn v.AsFloat64()\n\tcase FLOAT64SLICE:\n\t\treturn v.asFloat64Slice()\n\tcase STRING:\n\t\treturn v.stringly\n\tcase STRINGSLICE:\n\t\treturn v.asStringSlice()\n\t}\n\treturn unknownValueType{}\n}\n\n// Emit returns a string representation of Value's data.\nfunc (v Value) Emit() string {\n\tswitch v.Type() {\n\tcase BOOLSLICE:\n\t\treturn fmt.Sprint(v.asBoolSlice())\n\tcase BOOL:\n\t\treturn strconv.FormatBool(v.AsBool())\n\tcase INT64SLICE:\n\t\treturn fmt.Sprint(v.asInt64Slice())\n\tcase INT64:\n\t\treturn strconv.FormatInt(v.AsInt64(), 10)\n\tcase FLOAT64SLICE:\n\t\treturn fmt.Sprint(v.asFloat64Slice())\n\tcase FLOAT64:\n\t\treturn fmt.Sprint(v.AsFloat64())\n\tcase STRINGSLICE:\n\t\treturn fmt.Sprint(v.asStringSlice())\n\tcase STRING:\n\t\treturn v.stringly\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\n// MarshalJSON returns the JSON encoding of the Value.\nfunc (v Value) MarshalJSON() ([]byte, error) {\n\tvar jsonVal struct {\n\t\tType  string\n\t\tValue interface{}\n\t}\n\tjsonVal.Type = v.Type().String()\n\tjsonVal.Value = v.AsInterface()\n\treturn json.Marshal(jsonVal)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/baggage/baggage.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage baggage // import \"go.opentelemetry.io/otel/baggage\"\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"go.opentelemetry.io/otel/internal/baggage\"\n)\n\nconst (\n\tmaxMembers               = 180\n\tmaxBytesPerMembers       = 4096\n\tmaxBytesPerBaggageString = 8192\n\n\tlistDelimiter     = \",\"\n\tkeyValueDelimiter = \"=\"\n\tpropertyDelimiter = \";\"\n\n\tkeyDef      = `([\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2E\\x30-\\x39\\x41-\\x5a\\x5e-\\x7a\\x7c\\x7e]+)`\n\tvalueDef    = `([\\x21\\x23-\\x2b\\x2d-\\x3a\\x3c-\\x5B\\x5D-\\x7e]*)`\n\tkeyValueDef = `\\s*` + keyDef + `\\s*` + keyValueDelimiter + `\\s*` + valueDef + `\\s*`\n)\n\nvar (\n\tkeyRe      = regexp.MustCompile(`^` + keyDef + `$`)\n\tvalueRe    = regexp.MustCompile(`^` + valueDef + `$`)\n\tpropertyRe = regexp.MustCompile(`^(?:\\s*` + keyDef + `\\s*|` + keyValueDef + `)$`)\n)\n\nvar (\n\terrInvalidKey      = errors.New(\"invalid key\")\n\terrInvalidValue    = errors.New(\"invalid value\")\n\terrInvalidProperty = errors.New(\"invalid baggage list-member property\")\n\terrInvalidMember   = errors.New(\"invalid baggage list-member\")\n\terrMemberNumber    = errors.New(\"too many list-members in baggage-string\")\n\terrMemberBytes     = errors.New(\"list-member too large\")\n\terrBaggageBytes    = errors.New(\"baggage-string too large\")\n)\n\n// Property is an additional metadata entry for a baggage list-member.\ntype Property struct {\n\tkey, value string\n\n\t// hasValue indicates if a zero-value value means the property does not\n\t// have a value or if it was the zero-value.\n\thasValue bool\n}\n\n// NewKeyProperty returns a new Property for key.\n//\n// If key is invalid, an error will be returned.\nfunc NewKeyProperty(key string) (Property, error) {\n\tif !keyRe.MatchString(key) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\n\tp := Property{key: key}\n\treturn p, nil\n}\n\n// NewKeyValueProperty returns a new Property for key with value.\n//\n// If key or value are invalid, an error will be returned.\nfunc NewKeyValueProperty(key, value string) (Property, error) {\n\tif !keyRe.MatchString(key) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\tif !valueRe.MatchString(value) {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\n\tp := Property{\n\t\tkey:      key,\n\t\tvalue:    value,\n\t\thasValue: true,\n\t}\n\treturn p, nil\n}\n\nfunc newInvalidProperty() Property {\n\treturn Property{}\n}\n\n// parseProperty attempts to decode a Property from the passed string. It\n// returns an error if the input is invalid according to the W3C Baggage\n// specification.\nfunc parseProperty(property string) (Property, error) {\n\tif property == \"\" {\n\t\treturn newInvalidProperty(), nil\n\t}\n\n\tmatch := propertyRe.FindStringSubmatch(property)\n\tif len(match) != 4 {\n\t\treturn newInvalidProperty(), fmt.Errorf(\"%w: %q\", errInvalidProperty, property)\n\t}\n\n\tvar p Property\n\tif match[1] != \"\" {\n\t\tp.key = match[1]\n\t} else {\n\t\tp.key = match[2]\n\t\tp.value = match[3]\n\t\tp.hasValue = true\n\t}\n\n\treturn p, nil\n}\n\n// validate ensures p conforms to the W3C Baggage specification, returning an\n// error otherwise.\nfunc (p Property) validate() error {\n\terrFunc := func(err error) error {\n\t\treturn fmt.Errorf(\"invalid property: %w\", err)\n\t}\n\n\tif !keyRe.MatchString(p.key) {\n\t\treturn errFunc(fmt.Errorf(\"%w: %q\", errInvalidKey, p.key))\n\t}\n\tif p.hasValue && !valueRe.MatchString(p.value) {\n\t\treturn errFunc(fmt.Errorf(\"%w: %q\", errInvalidValue, p.value))\n\t}\n\tif !p.hasValue && p.value != \"\" {\n\t\treturn errFunc(errors.New(\"inconsistent value\"))\n\t}\n\treturn nil\n}\n\n// Key returns the Property key.\nfunc (p Property) Key() string {\n\treturn p.key\n}\n\n// Value returns the Property value. Additionally, a boolean value is returned\n// indicating if the returned value is the empty if the Property has a value\n// that is empty or if the value is not set.\nfunc (p Property) Value() (string, bool) {\n\treturn p.value, p.hasValue\n}\n\n// String encodes Property into a string compliant with the W3C Baggage\n// specification.\nfunc (p Property) String() string {\n\tif p.hasValue {\n\t\treturn fmt.Sprintf(\"%s%s%v\", p.key, keyValueDelimiter, p.value)\n\t}\n\treturn p.key\n}\n\ntype properties []Property\n\nfunc fromInternalProperties(iProps []baggage.Property) properties {\n\tif len(iProps) == 0 {\n\t\treturn nil\n\t}\n\n\tprops := make(properties, len(iProps))\n\tfor i, p := range iProps {\n\t\tprops[i] = Property{\n\t\t\tkey:      p.Key,\n\t\t\tvalue:    p.Value,\n\t\t\thasValue: p.HasValue,\n\t\t}\n\t}\n\treturn props\n}\n\nfunc (p properties) asInternal() []baggage.Property {\n\tif len(p) == 0 {\n\t\treturn nil\n\t}\n\n\tiProps := make([]baggage.Property, len(p))\n\tfor i, prop := range p {\n\t\tiProps[i] = baggage.Property{\n\t\t\tKey:      prop.key,\n\t\t\tValue:    prop.value,\n\t\t\tHasValue: prop.hasValue,\n\t\t}\n\t}\n\treturn iProps\n}\n\nfunc (p properties) Copy() properties {\n\tif len(p) == 0 {\n\t\treturn nil\n\t}\n\n\tprops := make(properties, len(p))\n\tcopy(props, p)\n\treturn props\n}\n\n// validate ensures each Property in p conforms to the W3C Baggage\n// specification, returning an error otherwise.\nfunc (p properties) validate() error {\n\tfor _, prop := range p {\n\t\tif err := prop.validate(); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// String encodes properties into a string compliant with the W3C Baggage\n// specification.\nfunc (p properties) String() string {\n\tprops := make([]string, len(p))\n\tfor i, prop := range p {\n\t\tprops[i] = prop.String()\n\t}\n\treturn strings.Join(props, propertyDelimiter)\n}\n\n// Member is a list-member of a baggage-string as defined by the W3C Baggage\n// specification.\ntype Member struct {\n\tkey, value string\n\tproperties properties\n\n\t// hasData indicates whether the created property contains data or not.\n\t// Properties that do not contain data are invalid with no other check\n\t// required.\n\thasData bool\n}\n\n// NewMember returns a new Member from the passed arguments. The key will be\n// used directly while the value will be url decoded after validation. An error\n// is returned if the created Member would be invalid according to the W3C\n// Baggage specification.\nfunc NewMember(key, value string, props ...Property) (Member, error) {\n\tm := Member{\n\t\tkey:        key,\n\t\tvalue:      value,\n\t\tproperties: properties(props).Copy(),\n\t\thasData:    true,\n\t}\n\tif err := m.validate(); err != nil {\n\t\treturn newInvalidMember(), err\n\t}\n\tdecodedValue, err := url.QueryUnescape(value)\n\tif err != nil {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\tm.value = decodedValue\n\treturn m, nil\n}\n\nfunc newInvalidMember() Member {\n\treturn Member{}\n}\n\n// parseMember attempts to decode a Member from the passed string. It returns\n// an error if the input is invalid according to the W3C Baggage\n// specification.\nfunc parseMember(member string) (Member, error) {\n\tif n := len(member); n > maxBytesPerMembers {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %d\", errMemberBytes, n)\n\t}\n\n\tvar (\n\t\tkey, value string\n\t\tprops      properties\n\t)\n\n\tkeyValue, properties, found := strings.Cut(member, propertyDelimiter)\n\tif found {\n\t\t// Parse the member properties.\n\t\tfor _, pStr := range strings.Split(properties, propertyDelimiter) {\n\t\t\tp, err := parseProperty(pStr)\n\t\t\tif err != nil {\n\t\t\t\treturn newInvalidMember(), err\n\t\t\t}\n\t\t\tprops = append(props, p)\n\t\t}\n\t}\n\t// Parse the member key/value pair.\n\n\t// Take into account a value can contain equal signs (=).\n\tk, v, found := strings.Cut(keyValue, keyValueDelimiter)\n\tif !found {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidMember, member)\n\t}\n\t// \"Leading and trailing whitespaces are allowed but MUST be trimmed\n\t// when converting the header into a data structure.\"\n\tkey = strings.TrimSpace(k)\n\tvar err error\n\tvalue, err = url.QueryUnescape(strings.TrimSpace(v))\n\tif err != nil {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", err, value)\n\t}\n\tif !keyRe.MatchString(key) {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidKey, key)\n\t}\n\tif !valueRe.MatchString(value) {\n\t\treturn newInvalidMember(), fmt.Errorf(\"%w: %q\", errInvalidValue, value)\n\t}\n\n\treturn Member{key: key, value: value, properties: props, hasData: true}, nil\n}\n\n// validate ensures m conforms to the W3C Baggage specification.\n// A key is just an ASCII string, but a value must be URL encoded UTF-8,\n// returning an error otherwise.\nfunc (m Member) validate() error {\n\tif !m.hasData {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidMember, m)\n\t}\n\n\tif !keyRe.MatchString(m.key) {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidKey, m.key)\n\t}\n\tif !valueRe.MatchString(m.value) {\n\t\treturn fmt.Errorf(\"%w: %q\", errInvalidValue, m.value)\n\t}\n\treturn m.properties.validate()\n}\n\n// Key returns the Member key.\nfunc (m Member) Key() string { return m.key }\n\n// Value returns the Member value.\nfunc (m Member) Value() string { return m.value }\n\n// Properties returns a copy of the Member properties.\nfunc (m Member) Properties() []Property { return m.properties.Copy() }\n\n// String encodes Member into a string compliant with the W3C Baggage\n// specification.\nfunc (m Member) String() string {\n\t// A key is just an ASCII string, but a value is URL encoded UTF-8.\n\ts := fmt.Sprintf(\"%s%s%s\", m.key, keyValueDelimiter, url.QueryEscape(m.value))\n\tif len(m.properties) > 0 {\n\t\ts = fmt.Sprintf(\"%s%s%s\", s, propertyDelimiter, m.properties.String())\n\t}\n\treturn s\n}\n\n// Baggage is a list of baggage members representing the baggage-string as\n// defined by the W3C Baggage specification.\ntype Baggage struct { //nolint:golint\n\tlist baggage.List\n}\n\n// New returns a new valid Baggage. It returns an error if it results in a\n// Baggage exceeding limits set in that specification.\n//\n// It expects all the provided members to have already been validated.\nfunc New(members ...Member) (Baggage, error) {\n\tif len(members) == 0 {\n\t\treturn Baggage{}, nil\n\t}\n\n\tb := make(baggage.List)\n\tfor _, m := range members {\n\t\tif !m.hasData {\n\t\t\treturn Baggage{}, errInvalidMember\n\t\t}\n\n\t\t// OpenTelemetry resolves duplicates by last-one-wins.\n\t\tb[m.key] = baggage.Item{\n\t\t\tValue:      m.value,\n\t\t\tProperties: m.properties.asInternal(),\n\t\t}\n\t}\n\n\t// Check member numbers after deduplication.\n\tif len(b) > maxMembers {\n\t\treturn Baggage{}, errMemberNumber\n\t}\n\n\tbag := Baggage{b}\n\tif n := len(bag.String()); n > maxBytesPerBaggageString {\n\t\treturn Baggage{}, fmt.Errorf(\"%w: %d\", errBaggageBytes, n)\n\t}\n\n\treturn bag, nil\n}\n\n// Parse attempts to decode a baggage-string from the passed string. It\n// returns an error if the input is invalid according to the W3C Baggage\n// specification.\n//\n// If there are duplicate list-members contained in baggage, the last one\n// defined (reading left-to-right) will be the only one kept. This diverges\n// from the W3C Baggage specification which allows duplicate list-members, but\n// conforms to the OpenTelemetry Baggage specification.\nfunc Parse(bStr string) (Baggage, error) {\n\tif bStr == \"\" {\n\t\treturn Baggage{}, nil\n\t}\n\n\tif n := len(bStr); n > maxBytesPerBaggageString {\n\t\treturn Baggage{}, fmt.Errorf(\"%w: %d\", errBaggageBytes, n)\n\t}\n\n\tb := make(baggage.List)\n\tfor _, memberStr := range strings.Split(bStr, listDelimiter) {\n\t\tm, err := parseMember(memberStr)\n\t\tif err != nil {\n\t\t\treturn Baggage{}, err\n\t\t}\n\t\t// OpenTelemetry resolves duplicates by last-one-wins.\n\t\tb[m.key] = baggage.Item{\n\t\t\tValue:      m.value,\n\t\t\tProperties: m.properties.asInternal(),\n\t\t}\n\t}\n\n\t// OpenTelemetry does not allow for duplicate list-members, but the W3C\n\t// specification does. Now that we have deduplicated, ensure the baggage\n\t// does not exceed list-member limits.\n\tif len(b) > maxMembers {\n\t\treturn Baggage{}, errMemberNumber\n\t}\n\n\treturn Baggage{b}, nil\n}\n\n// Member returns the baggage list-member identified by key.\n//\n// If there is no list-member matching the passed key the returned Member will\n// be a zero-value Member.\n// The returned member is not validated, as we assume the validation happened\n// when it was added to the Baggage.\nfunc (b Baggage) Member(key string) Member {\n\tv, ok := b.list[key]\n\tif !ok {\n\t\t// We do not need to worry about distinguishing between the situation\n\t\t// where a zero-valued Member is included in the Baggage because a\n\t\t// zero-valued Member is invalid according to the W3C Baggage\n\t\t// specification (it has an empty key).\n\t\treturn newInvalidMember()\n\t}\n\n\treturn Member{\n\t\tkey:        key,\n\t\tvalue:      v.Value,\n\t\tproperties: fromInternalProperties(v.Properties),\n\t\thasData:    true,\n\t}\n}\n\n// Members returns all the baggage list-members.\n// The order of the returned list-members does not have significance.\n//\n// The returned members are not validated, as we assume the validation happened\n// when they were added to the Baggage.\nfunc (b Baggage) Members() []Member {\n\tif len(b.list) == 0 {\n\t\treturn nil\n\t}\n\n\tmembers := make([]Member, 0, len(b.list))\n\tfor k, v := range b.list {\n\t\tmembers = append(members, Member{\n\t\t\tkey:        k,\n\t\t\tvalue:      v.Value,\n\t\t\tproperties: fromInternalProperties(v.Properties),\n\t\t\thasData:    true,\n\t\t})\n\t}\n\treturn members\n}\n\n// SetMember returns a copy the Baggage with the member included. If the\n// baggage contains a Member with the same key the existing Member is\n// replaced.\n//\n// If member is invalid according to the W3C Baggage specification, an error\n// is returned with the original Baggage.\nfunc (b Baggage) SetMember(member Member) (Baggage, error) {\n\tif !member.hasData {\n\t\treturn b, errInvalidMember\n\t}\n\n\tn := len(b.list)\n\tif _, ok := b.list[member.key]; !ok {\n\t\tn++\n\t}\n\tlist := make(baggage.List, n)\n\n\tfor k, v := range b.list {\n\t\t// Do not copy if we are just going to overwrite.\n\t\tif k == member.key {\n\t\t\tcontinue\n\t\t}\n\t\tlist[k] = v\n\t}\n\n\tlist[member.key] = baggage.Item{\n\t\tValue:      member.value,\n\t\tProperties: member.properties.asInternal(),\n\t}\n\n\treturn Baggage{list: list}, nil\n}\n\n// DeleteMember returns a copy of the Baggage with the list-member identified\n// by key removed.\nfunc (b Baggage) DeleteMember(key string) Baggage {\n\tn := len(b.list)\n\tif _, ok := b.list[key]; ok {\n\t\tn--\n\t}\n\tlist := make(baggage.List, n)\n\n\tfor k, v := range b.list {\n\t\tif k == key {\n\t\t\tcontinue\n\t\t}\n\t\tlist[k] = v\n\t}\n\n\treturn Baggage{list: list}\n}\n\n// Len returns the number of list-members in the Baggage.\nfunc (b Baggage) Len() int {\n\treturn len(b.list)\n}\n\n// String encodes Baggage into a string compliant with the W3C Baggage\n// specification. The returned string will be invalid if the Baggage contains\n// any invalid list-members.\nfunc (b Baggage) String() string {\n\tmembers := make([]string, 0, len(b.list))\n\tfor k, v := range b.list {\n\t\tmembers = append(members, Member{\n\t\t\tkey:        k,\n\t\t\tvalue:      v.Value,\n\t\t\tproperties: fromInternalProperties(v.Properties),\n\t\t}.String())\n\t}\n\treturn strings.Join(members, listDelimiter)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/baggage/context.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage baggage // import \"go.opentelemetry.io/otel/baggage\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/internal/baggage\"\n)\n\n// ContextWithBaggage returns a copy of parent with baggage.\nfunc ContextWithBaggage(parent context.Context, b Baggage) context.Context {\n\t// Delegate so any hooks for the OpenTracing bridge are handled.\n\treturn baggage.ContextWithList(parent, b.list)\n}\n\n// ContextWithoutBaggage returns a copy of parent with no baggage.\nfunc ContextWithoutBaggage(parent context.Context) context.Context {\n\t// Delegate so any hooks for the OpenTracing bridge are handled.\n\treturn baggage.ContextWithList(parent, nil)\n}\n\n// FromContext returns the baggage contained in ctx.\nfunc FromContext(ctx context.Context) Baggage {\n\t// Delegate so any hooks for the OpenTracing bridge are handled.\n\treturn Baggage{list: baggage.ListFromContext(ctx)}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/baggage/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage baggage provides functionality for storing and retrieving\nbaggage items in Go context. For propagating the baggage, see the\ngo.opentelemetry.io/otel/propagation package.\n*/\npackage baggage // import \"go.opentelemetry.io/otel/baggage\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/codes/codes.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage codes // import \"go.opentelemetry.io/otel/codes\"\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n)\n\nconst (\n\t// Unset is the default status code.\n\tUnset Code = 0\n\n\t// Error indicates the operation contains an error.\n\t//\n\t// NOTE: The error code in OTLP is 2.\n\t// The value of this enum is only relevant to the internals\n\t// of the Go SDK.\n\tError Code = 1\n\n\t// Ok indicates operation has been validated by an Application developers\n\t// or Operator to have completed successfully, or contain no error.\n\t//\n\t// NOTE: The Ok code in OTLP is 1.\n\t// The value of this enum is only relevant to the internals\n\t// of the Go SDK.\n\tOk Code = 2\n\n\tmaxCode = 3\n)\n\n// Code is an 32-bit representation of a status state.\ntype Code uint32\n\nvar codeToStr = map[Code]string{\n\tUnset: \"Unset\",\n\tError: \"Error\",\n\tOk:    \"Ok\",\n}\n\nvar strToCode = map[string]Code{\n\t`\"Unset\"`: Unset,\n\t`\"Error\"`: Error,\n\t`\"Ok\"`:    Ok,\n}\n\n// String returns the Code as a string.\nfunc (c Code) String() string {\n\treturn codeToStr[c]\n}\n\n// UnmarshalJSON unmarshals b into the Code.\n//\n// This is based on the functionality in the gRPC codes package:\n// https://github.com/grpc/grpc-go/blob/bb64fee312b46ebee26be43364a7a966033521b1/codes/codes.go#L218-L244\nfunc (c *Code) UnmarshalJSON(b []byte) error {\n\t// From json.Unmarshaler: By convention, to approximate the behavior of\n\t// Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte(\"null\")) as\n\t// a no-op.\n\tif string(b) == \"null\" {\n\t\treturn nil\n\t}\n\tif c == nil {\n\t\treturn fmt.Errorf(\"nil receiver passed to UnmarshalJSON\")\n\t}\n\n\tvar x interface{}\n\tif err := json.Unmarshal(b, &x); err != nil {\n\t\treturn err\n\t}\n\tswitch x.(type) {\n\tcase string:\n\t\tif jc, ok := strToCode[string(b)]; ok {\n\t\t\t*c = jc\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"invalid code: %q\", string(b))\n\tcase float64:\n\t\tif ci, err := strconv.ParseUint(string(b), 10, 32); err == nil {\n\t\t\tif ci >= maxCode {\n\t\t\t\treturn fmt.Errorf(\"invalid code: %q\", ci)\n\t\t\t}\n\n\t\t\t*c = Code(ci)\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"invalid code: %q\", string(b))\n\tdefault:\n\t\treturn fmt.Errorf(\"invalid code: %q\", string(b))\n\t}\n}\n\n// MarshalJSON returns c as the JSON encoding of c.\nfunc (c *Code) MarshalJSON() ([]byte, error) {\n\tif c == nil {\n\t\treturn []byte(\"null\"), nil\n\t}\n\tstr, ok := codeToStr[*c]\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid code: %d\", *c)\n\t}\n\treturn []byte(fmt.Sprintf(\"%q\", str)), nil\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/codes/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage codes defines the canonical error codes used by OpenTelemetry.\n\nIt conforms to [the OpenTelemetry\nspecification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/trace/api.md#set-status).\n*/\npackage codes // import \"go.opentelemetry.io/otel/codes\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage otel provides global access to the OpenTelemetry API. The subpackages of\nthe otel package provide an implementation of the OpenTelemetry API.\n\nThe provided API is used to instrument code and measure data about that code's\nperformance and operation. The measured data, by default, is not processed or\ntransmitted anywhere. An implementation of the OpenTelemetry SDK, like the\ndefault SDK implementation (go.opentelemetry.io/otel/sdk), and associated\nexporters are used to process and transport this data.\n\nTo read the getting started guide, see https://opentelemetry.io/docs/go/getting-started/.\n\nTo read more about tracing, see go.opentelemetry.io/otel/trace.\n\nTo read more about metrics, see go.opentelemetry.io/otel/metric.\n\nTo read more about propagation, see go.opentelemetry.io/otel/propagation and\ngo.opentelemetry.io/otel/baggage.\n*/\npackage otel // import \"go.opentelemetry.io/otel\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/error_handler.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otel // import \"go.opentelemetry.io/otel\"\n\n// ErrorHandler handles irremediable events.\ntype ErrorHandler interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Handle handles any error deemed irremediable by an OpenTelemetry\n\t// component.\n\tHandle(error)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\n// ErrorHandlerFunc is a convenience adapter to allow the use of a function\n// as an ErrorHandler.\ntype ErrorHandlerFunc func(error)\n\nvar _ ErrorHandler = ErrorHandlerFunc(nil)\n\n// Handle handles the irremediable error by calling the ErrorHandlerFunc itself.\nfunc (f ErrorHandlerFunc) Handle(err error) {\n\tf(err)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/get_main_pkgs.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright The OpenTelemetry Authors\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#     http://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\nset -euo pipefail\n\ntop_dir='.'\nif [[ $# -gt 0 ]]; then\n    top_dir=\"${1}\"\nfi\n\np=$(pwd)\nmod_dirs=()\n\n# Note `mapfile` does not exist in older bash versions:\n# https://stackoverflow.com/questions/41475261/need-alternative-to-readarray-mapfile-for-script-on-older-version-of-bash\n\nwhile IFS= read -r line; do\n    mod_dirs+=(\"$line\")\ndone < <(find \"${top_dir}\" -type f -name 'go.mod' -exec dirname {} \\; | sort)\n\nfor mod_dir in \"${mod_dirs[@]}\"; do\n    cd \"${mod_dir}\"\n\n    while IFS= read -r line; do\n        echo \".${line#${p}}\"\n    done < <(go list --find -f '{{.Name}}|{{.Dir}}' ./... | grep '^main|' | cut -f 2- -d '|')\n    cd \"${p}\"\ndone\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/handler.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n)\n\nvar (\n\t// Compile-time check global.ErrDelegator implements ErrorHandler.\n\t_ ErrorHandler = (*global.ErrDelegator)(nil)\n\t// Compile-time check global.ErrLogger implements ErrorHandler.\n\t_ ErrorHandler = (*global.ErrLogger)(nil)\n)\n\n// GetErrorHandler returns the global ErrorHandler instance.\n//\n// The default ErrorHandler instance returned will log all errors to STDERR\n// until an override ErrorHandler is set with SetErrorHandler. All\n// ErrorHandler returned prior to this will automatically forward errors to\n// the set instance instead of logging.\n//\n// Subsequent calls to SetErrorHandler after the first will not forward errors\n// to the new ErrorHandler for prior returned instances.\nfunc GetErrorHandler() ErrorHandler { return global.GetErrorHandler() }\n\n// SetErrorHandler sets the global ErrorHandler to h.\n//\n// The first time this is called all ErrorHandler previously returned from\n// GetErrorHandler will send errors to h instead of the default logging\n// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not\n// delegate errors to h.\nfunc SetErrorHandler(h ErrorHandler) { global.SetErrorHandler(h) }\n\n// Handle is a convenience function for ErrorHandler().Handle(err).\nfunc Handle(err error) { global.Handle(err) }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/attribute/attribute.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage attribute provide several helper functions for some commonly used\nlogic of processing attributes.\n*/\npackage attribute // import \"go.opentelemetry.io/otel/internal/attribute\"\n\nimport (\n\t\"reflect\"\n)\n\n// BoolSliceValue converts a bool slice into an array with same elements as slice.\nfunc BoolSliceValue(v []bool) interface{} {\n\tvar zero bool\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))\n\tcopy(cp.Elem().Slice(0, len(v)).Interface().([]bool), v)\n\treturn cp.Elem().Interface()\n}\n\n// Int64SliceValue converts an int64 slice into an array with same elements as slice.\nfunc Int64SliceValue(v []int64) interface{} {\n\tvar zero int64\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))\n\tcopy(cp.Elem().Slice(0, len(v)).Interface().([]int64), v)\n\treturn cp.Elem().Interface()\n}\n\n// Float64SliceValue converts a float64 slice into an array with same elements as slice.\nfunc Float64SliceValue(v []float64) interface{} {\n\tvar zero float64\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))\n\tcopy(cp.Elem().Slice(0, len(v)).Interface().([]float64), v)\n\treturn cp.Elem().Interface()\n}\n\n// StringSliceValue converts a string slice into an array with same elements as slice.\nfunc StringSliceValue(v []string) interface{} {\n\tvar zero string\n\tcp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(zero)))\n\tcopy(cp.Elem().Slice(0, len(v)).Interface().([]string), v)\n\treturn cp.Elem().Interface()\n}\n\n// AsBoolSlice converts a bool array into a slice into with same elements as array.\nfunc AsBoolSlice(v interface{}) []bool {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tvar zero bool\n\tcorrectLen := rv.Len()\n\tcorrectType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))\n\tcpy := reflect.New(correctType)\n\t_ = reflect.Copy(cpy.Elem(), rv)\n\treturn cpy.Elem().Slice(0, correctLen).Interface().([]bool)\n}\n\n// AsInt64Slice converts an int64 array into a slice into with same elements as array.\nfunc AsInt64Slice(v interface{}) []int64 {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tvar zero int64\n\tcorrectLen := rv.Len()\n\tcorrectType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))\n\tcpy := reflect.New(correctType)\n\t_ = reflect.Copy(cpy.Elem(), rv)\n\treturn cpy.Elem().Slice(0, correctLen).Interface().([]int64)\n}\n\n// AsFloat64Slice converts a float64 array into a slice into with same elements as array.\nfunc AsFloat64Slice(v interface{}) []float64 {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tvar zero float64\n\tcorrectLen := rv.Len()\n\tcorrectType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))\n\tcpy := reflect.New(correctType)\n\t_ = reflect.Copy(cpy.Elem(), rv)\n\treturn cpy.Elem().Slice(0, correctLen).Interface().([]float64)\n}\n\n// AsStringSlice converts a string array into a slice into with same elements as array.\nfunc AsStringSlice(v interface{}) []string {\n\trv := reflect.ValueOf(v)\n\tif rv.Type().Kind() != reflect.Array {\n\t\treturn nil\n\t}\n\tvar zero string\n\tcorrectLen := rv.Len()\n\tcorrectType := reflect.ArrayOf(correctLen, reflect.TypeOf(zero))\n\tcpy := reflect.New(correctType)\n\t_ = reflect.Copy(cpy.Elem(), rv)\n\treturn cpy.Elem().Slice(0, correctLen).Interface().([]string)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/baggage/baggage.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage baggage provides base types and functionality to store and retrieve\nbaggage in Go context. This package exists because the OpenTracing bridge to\nOpenTelemetry needs to synchronize state whenever baggage for a context is\nmodified and that context contains an OpenTracing span. If it were not for\nthis need this package would not need to exist and the\n`go.opentelemetry.io/otel/baggage` package would be the singular place where\nW3C baggage is handled.\n*/\npackage baggage // import \"go.opentelemetry.io/otel/internal/baggage\"\n\n// List is the collection of baggage members. The W3C allows for duplicates,\n// but OpenTelemetry does not, therefore, this is represented as a map.\ntype List map[string]Item\n\n// Item is the value and metadata properties part of a list-member.\ntype Item struct {\n\tValue      string\n\tProperties []Property\n}\n\n// Property is a metadata entry for a list-member.\ntype Property struct {\n\tKey, Value string\n\n\t// HasValue indicates if a zero-value value means the property does not\n\t// have a value or if it was the zero-value.\n\tHasValue bool\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/baggage/context.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage baggage // import \"go.opentelemetry.io/otel/internal/baggage\"\n\nimport \"context\"\n\ntype baggageContextKeyType int\n\nconst baggageKey baggageContextKeyType = iota\n\n// SetHookFunc is a callback called when storing baggage in the context.\ntype SetHookFunc func(context.Context, List) context.Context\n\n// GetHookFunc is a callback called when getting baggage from the context.\ntype GetHookFunc func(context.Context, List) List\n\ntype baggageState struct {\n\tlist List\n\n\tsetHook SetHookFunc\n\tgetHook GetHookFunc\n}\n\n// ContextWithSetHook returns a copy of parent with hook configured to be\n// invoked every time ContextWithBaggage is called.\n//\n// Passing nil SetHookFunc creates a context with no set hook to call.\nfunc ContextWithSetHook(parent context.Context, hook SetHookFunc) context.Context {\n\tvar s baggageState\n\tif v, ok := parent.Value(baggageKey).(baggageState); ok {\n\t\ts = v\n\t}\n\n\ts.setHook = hook\n\treturn context.WithValue(parent, baggageKey, s)\n}\n\n// ContextWithGetHook returns a copy of parent with hook configured to be\n// invoked every time FromContext is called.\n//\n// Passing nil GetHookFunc creates a context with no get hook to call.\nfunc ContextWithGetHook(parent context.Context, hook GetHookFunc) context.Context {\n\tvar s baggageState\n\tif v, ok := parent.Value(baggageKey).(baggageState); ok {\n\t\ts = v\n\t}\n\n\ts.getHook = hook\n\treturn context.WithValue(parent, baggageKey, s)\n}\n\n// ContextWithList returns a copy of parent with baggage. Passing nil list\n// returns a context without any baggage.\nfunc ContextWithList(parent context.Context, list List) context.Context {\n\tvar s baggageState\n\tif v, ok := parent.Value(baggageKey).(baggageState); ok {\n\t\ts = v\n\t}\n\n\ts.list = list\n\tctx := context.WithValue(parent, baggageKey, s)\n\tif s.setHook != nil {\n\t\tctx = s.setHook(ctx, list)\n\t}\n\n\treturn ctx\n}\n\n// ListFromContext returns the baggage contained in ctx.\nfunc ListFromContext(ctx context.Context) List {\n\tswitch v := ctx.Value(baggageKey).(type) {\n\tcase baggageState:\n\t\tif v.getHook != nil {\n\t\t\treturn v.getHook(ctx, v.list)\n\t\t}\n\t\treturn v.list\n\tdefault:\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/gen.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage internal // import \"go.opentelemetry.io/otel/internal\"\n\n//go:generate gotmpl --body=./shared/matchers/expectation.go.tmpl \"--data={}\" --out=matchers/expectation.go\n//go:generate gotmpl --body=./shared/matchers/expecter.go.tmpl \"--data={}\" --out=matchers/expecter.go\n//go:generate gotmpl --body=./shared/matchers/temporal_matcher.go.tmpl \"--data={}\" --out=matchers/temporal_matcher.go\n\n//go:generate gotmpl --body=./shared/internaltest/alignment.go.tmpl \"--data={}\" --out=internaltest/alignment.go\n//go:generate gotmpl --body=./shared/internaltest/env.go.tmpl \"--data={}\" --out=internaltest/env.go\n//go:generate gotmpl --body=./shared/internaltest/env_test.go.tmpl \"--data={}\" --out=internaltest/env_test.go\n//go:generate gotmpl --body=./shared/internaltest/errors.go.tmpl \"--data={}\" --out=internaltest/errors.go\n//go:generate gotmpl --body=./shared/internaltest/harness.go.tmpl \"--data={\\\"matchersImportPath\\\": \\\"go.opentelemetry.io/otel/internal/matchers\\\"}\" --out=internaltest/harness.go\n//go:generate gotmpl --body=./shared/internaltest/text_map_carrier.go.tmpl \"--data={}\" --out=internaltest/text_map_carrier.go\n//go:generate gotmpl --body=./shared/internaltest/text_map_carrier_test.go.tmpl \"--data={}\" --out=internaltest/text_map_carrier_test.go\n//go:generate gotmpl --body=./shared/internaltest/text_map_propagator.go.tmpl \"--data={}\" --out=internaltest/text_map_propagator.go\n//go:generate gotmpl --body=./shared/internaltest/text_map_propagator_test.go.tmpl \"--data={}\" --out=internaltest/text_map_propagator_test.go\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/handler.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"sync/atomic\"\n)\n\nvar (\n\t// GlobalErrorHandler provides an ErrorHandler that can be used\n\t// throughout an OpenTelemetry instrumented project. When a user\n\t// specified ErrorHandler is registered (`SetErrorHandler`) all calls to\n\t// `Handle` and will be delegated to the registered ErrorHandler.\n\tGlobalErrorHandler = defaultErrorHandler()\n\n\t// Compile-time check that delegator implements ErrorHandler.\n\t_ ErrorHandler = (*ErrDelegator)(nil)\n\t// Compile-time check that errLogger implements ErrorHandler.\n\t_ ErrorHandler = (*ErrLogger)(nil)\n)\n\n// ErrorHandler handles irremediable events.\ntype ErrorHandler interface {\n\t// Handle handles any error deemed irremediable by an OpenTelemetry\n\t// component.\n\tHandle(error)\n}\n\ntype ErrDelegator struct {\n\tdelegate atomic.Pointer[ErrorHandler]\n}\n\nfunc (d *ErrDelegator) Handle(err error) {\n\td.getDelegate().Handle(err)\n}\n\nfunc (d *ErrDelegator) getDelegate() ErrorHandler {\n\treturn *d.delegate.Load()\n}\n\n// setDelegate sets the ErrorHandler delegate.\nfunc (d *ErrDelegator) setDelegate(eh ErrorHandler) {\n\td.delegate.Store(&eh)\n}\n\nfunc defaultErrorHandler() *ErrDelegator {\n\td := &ErrDelegator{}\n\td.setDelegate(&ErrLogger{l: log.New(os.Stderr, \"\", log.LstdFlags)})\n\treturn d\n}\n\n// ErrLogger logs errors if no delegate is set, otherwise they are delegated.\ntype ErrLogger struct {\n\tl *log.Logger\n}\n\n// Handle logs err if no delegate is set, otherwise it is delegated.\nfunc (h *ErrLogger) Handle(err error) {\n\th.l.Print(err)\n}\n\n// GetErrorHandler returns the global ErrorHandler instance.\n//\n// The default ErrorHandler instance returned will log all errors to STDERR\n// until an override ErrorHandler is set with SetErrorHandler. All\n// ErrorHandler returned prior to this will automatically forward errors to\n// the set instance instead of logging.\n//\n// Subsequent calls to SetErrorHandler after the first will not forward errors\n// to the new ErrorHandler for prior returned instances.\nfunc GetErrorHandler() ErrorHandler {\n\treturn GlobalErrorHandler\n}\n\n// SetErrorHandler sets the global ErrorHandler to h.\n//\n// The first time this is called all ErrorHandler previously returned from\n// GetErrorHandler will send errors to h instead of the default logging\n// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not\n// delegate errors to h.\nfunc SetErrorHandler(h ErrorHandler) {\n\tGlobalErrorHandler.setDelegate(h)\n}\n\n// Handle is a convenience function for ErrorHandler().Handle(err).\nfunc Handle(err error) {\n\tGetErrorHandler().Handle(err)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/instruments.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"context\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// unwrapper unwraps to return the underlying instrument implementation.\ntype unwrapper interface {\n\tUnwrap() metric.Observable\n}\n\ntype afCounter struct {\n\tembedded.Float64ObservableCounter\n\tmetric.Float64Observable\n\n\tname string\n\topts []metric.Float64ObservableCounterOption\n\n\tdelegate atomic.Value //metric.Float64ObservableCounter\n}\n\nvar _ unwrapper = (*afCounter)(nil)\nvar _ metric.Float64ObservableCounter = (*afCounter)(nil)\n\nfunc (i *afCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64ObservableCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *afCounter) Unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64ObservableCounter)\n\t}\n\treturn nil\n}\n\ntype afUpDownCounter struct {\n\tembedded.Float64ObservableUpDownCounter\n\tmetric.Float64Observable\n\n\tname string\n\topts []metric.Float64ObservableUpDownCounterOption\n\n\tdelegate atomic.Value //metric.Float64ObservableUpDownCounter\n}\n\nvar _ unwrapper = (*afUpDownCounter)(nil)\nvar _ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil)\n\nfunc (i *afUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *afUpDownCounter) Unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64ObservableUpDownCounter)\n\t}\n\treturn nil\n}\n\ntype afGauge struct {\n\tembedded.Float64ObservableGauge\n\tmetric.Float64Observable\n\n\tname string\n\topts []metric.Float64ObservableGaugeOption\n\n\tdelegate atomic.Value //metric.Float64ObservableGauge\n}\n\nvar _ unwrapper = (*afGauge)(nil)\nvar _ metric.Float64ObservableGauge = (*afGauge)(nil)\n\nfunc (i *afGauge) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64ObservableGauge(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *afGauge) Unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Float64ObservableGauge)\n\t}\n\treturn nil\n}\n\ntype aiCounter struct {\n\tembedded.Int64ObservableCounter\n\tmetric.Int64Observable\n\n\tname string\n\topts []metric.Int64ObservableCounterOption\n\n\tdelegate atomic.Value //metric.Int64ObservableCounter\n}\n\nvar _ unwrapper = (*aiCounter)(nil)\nvar _ metric.Int64ObservableCounter = (*aiCounter)(nil)\n\nfunc (i *aiCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64ObservableCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *aiCounter) Unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64ObservableCounter)\n\t}\n\treturn nil\n}\n\ntype aiUpDownCounter struct {\n\tembedded.Int64ObservableUpDownCounter\n\tmetric.Int64Observable\n\n\tname string\n\topts []metric.Int64ObservableUpDownCounterOption\n\n\tdelegate atomic.Value //metric.Int64ObservableUpDownCounter\n}\n\nvar _ unwrapper = (*aiUpDownCounter)(nil)\nvar _ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil)\n\nfunc (i *aiUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *aiUpDownCounter) Unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64ObservableUpDownCounter)\n\t}\n\treturn nil\n}\n\ntype aiGauge struct {\n\tembedded.Int64ObservableGauge\n\tmetric.Int64Observable\n\n\tname string\n\topts []metric.Int64ObservableGaugeOption\n\n\tdelegate atomic.Value //metric.Int64ObservableGauge\n}\n\nvar _ unwrapper = (*aiGauge)(nil)\nvar _ metric.Int64ObservableGauge = (*aiGauge)(nil)\n\nfunc (i *aiGauge) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64ObservableGauge(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *aiGauge) Unwrap() metric.Observable {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\treturn ctr.(metric.Int64ObservableGauge)\n\t}\n\treturn nil\n}\n\n// Sync Instruments.\ntype sfCounter struct {\n\tembedded.Float64Counter\n\n\tname string\n\topts []metric.Float64CounterOption\n\n\tdelegate atomic.Value //metric.Float64Counter\n}\n\nvar _ metric.Float64Counter = (*sfCounter)(nil)\n\nfunc (i *sfCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64Counter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *sfCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Float64Counter).Add(ctx, incr, opts...)\n\t}\n}\n\ntype sfUpDownCounter struct {\n\tembedded.Float64UpDownCounter\n\n\tname string\n\topts []metric.Float64UpDownCounterOption\n\n\tdelegate atomic.Value //metric.Float64UpDownCounter\n}\n\nvar _ metric.Float64UpDownCounter = (*sfUpDownCounter)(nil)\n\nfunc (i *sfUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64UpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *sfUpDownCounter) Add(ctx context.Context, incr float64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Float64UpDownCounter).Add(ctx, incr, opts...)\n\t}\n}\n\ntype sfHistogram struct {\n\tembedded.Float64Histogram\n\n\tname string\n\topts []metric.Float64HistogramOption\n\n\tdelegate atomic.Value //metric.Float64Histogram\n}\n\nvar _ metric.Float64Histogram = (*sfHistogram)(nil)\n\nfunc (i *sfHistogram) setDelegate(m metric.Meter) {\n\tctr, err := m.Float64Histogram(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *sfHistogram) Record(ctx context.Context, x float64, opts ...metric.RecordOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Float64Histogram).Record(ctx, x, opts...)\n\t}\n}\n\ntype siCounter struct {\n\tembedded.Int64Counter\n\n\tname string\n\topts []metric.Int64CounterOption\n\n\tdelegate atomic.Value //metric.Int64Counter\n}\n\nvar _ metric.Int64Counter = (*siCounter)(nil)\n\nfunc (i *siCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64Counter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *siCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Int64Counter).Add(ctx, x, opts...)\n\t}\n}\n\ntype siUpDownCounter struct {\n\tembedded.Int64UpDownCounter\n\n\tname string\n\topts []metric.Int64UpDownCounterOption\n\n\tdelegate atomic.Value //metric.Int64UpDownCounter\n}\n\nvar _ metric.Int64UpDownCounter = (*siUpDownCounter)(nil)\n\nfunc (i *siUpDownCounter) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64UpDownCounter(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *siUpDownCounter) Add(ctx context.Context, x int64, opts ...metric.AddOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Int64UpDownCounter).Add(ctx, x, opts...)\n\t}\n}\n\ntype siHistogram struct {\n\tembedded.Int64Histogram\n\n\tname string\n\topts []metric.Int64HistogramOption\n\n\tdelegate atomic.Value //metric.Int64Histogram\n}\n\nvar _ metric.Int64Histogram = (*siHistogram)(nil)\n\nfunc (i *siHistogram) setDelegate(m metric.Meter) {\n\tctr, err := m.Int64Histogram(i.name, i.opts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t\treturn\n\t}\n\ti.delegate.Store(ctr)\n}\n\nfunc (i *siHistogram) Record(ctx context.Context, x int64, opts ...metric.RecordOption) {\n\tif ctr := i.delegate.Load(); ctr != nil {\n\t\tctr.(metric.Int64Histogram).Record(ctx, x, opts...)\n\t}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"sync/atomic\"\n\n\t\"github.com/go-logr/logr\"\n\t\"github.com/go-logr/stdr\"\n)\n\n// globalLogger is the logging interface used within the otel api and sdk provide details of the internals.\n//\n// The default logger uses stdr which is backed by the standard `log.Logger`\n// interface. This logger will only show messages at the Error Level.\nvar globalLogger atomic.Pointer[logr.Logger]\n\nfunc init() {\n\tSetLogger(stdr.New(log.New(os.Stderr, \"\", log.LstdFlags|log.Lshortfile)))\n}\n\n// SetLogger overrides the globalLogger with l.\n//\n// To see Warn messages use a logger with `l.V(1).Enabled() == true`\n// To see Info messages use a logger with `l.V(4).Enabled() == true`\n// To see Debug messages use a logger with `l.V(8).Enabled() == true`.\nfunc SetLogger(l logr.Logger) {\n\tglobalLogger.Store(&l)\n}\n\nfunc getLogger() logr.Logger {\n\treturn *globalLogger.Load()\n}\n\n// Info prints messages about the general state of the API or SDK.\n// This should usually be less than 5 messages a minute.\nfunc Info(msg string, keysAndValues ...interface{}) {\n\tgetLogger().V(4).Info(msg, keysAndValues...)\n}\n\n// Error prints messages about exceptional states of the API or SDK.\nfunc Error(err error, msg string, keysAndValues ...interface{}) {\n\tgetLogger().Error(err, msg, keysAndValues...)\n}\n\n// Debug prints messages about all internal changes in the API or SDK.\nfunc Debug(msg string, keysAndValues ...interface{}) {\n\tgetLogger().V(8).Info(msg, keysAndValues...)\n}\n\n// Warn prints messages about warnings in the API or SDK.\n// Not an error but is likely more important than an informational event.\nfunc Warn(msg string, keysAndValues ...interface{}) {\n\tgetLogger().V(1).Info(msg, keysAndValues...)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/meter.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"container/list\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// meterProvider is a placeholder for a configured SDK MeterProvider.\n//\n// All MeterProvider functionality is forwarded to a delegate once\n// configured.\ntype meterProvider struct {\n\tembedded.MeterProvider\n\n\tmtx    sync.Mutex\n\tmeters map[il]*meter\n\n\tdelegate metric.MeterProvider\n}\n\n// setDelegate configures p to delegate all MeterProvider functionality to\n// provider.\n//\n// All Meters provided prior to this function call are switched out to be\n// Meters provided by provider. All instruments and callbacks are recreated and\n// delegated.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (p *meterProvider) setDelegate(provider metric.MeterProvider) {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tp.delegate = provider\n\n\tif len(p.meters) == 0 {\n\t\treturn\n\t}\n\n\tfor _, meter := range p.meters {\n\t\tmeter.setDelegate(provider)\n\t}\n\n\tp.meters = nil\n}\n\n// Meter implements MeterProvider.\nfunc (p *meterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tif p.delegate != nil {\n\t\treturn p.delegate.Meter(name, opts...)\n\t}\n\n\t// At this moment it is guaranteed that no sdk is installed, save the meter in the meters map.\n\n\tc := metric.NewMeterConfig(opts...)\n\tkey := il{\n\t\tname:    name,\n\t\tversion: c.InstrumentationVersion(),\n\t}\n\n\tif p.meters == nil {\n\t\tp.meters = make(map[il]*meter)\n\t}\n\n\tif val, ok := p.meters[key]; ok {\n\t\treturn val\n\t}\n\n\tt := &meter{name: name, opts: opts}\n\tp.meters[key] = t\n\treturn t\n}\n\n// meter is a placeholder for a metric.Meter.\n//\n// All Meter functionality is forwarded to a delegate once configured.\n// Otherwise, all functionality is forwarded to a NoopMeter.\ntype meter struct {\n\tembedded.Meter\n\n\tname string\n\topts []metric.MeterOption\n\n\tmtx         sync.Mutex\n\tinstruments []delegatedInstrument\n\n\tregistry list.List\n\n\tdelegate atomic.Value // metric.Meter\n}\n\ntype delegatedInstrument interface {\n\tsetDelegate(metric.Meter)\n}\n\n// setDelegate configures m to delegate all Meter functionality to Meters\n// created by provider.\n//\n// All subsequent calls to the Meter methods will be passed to the delegate.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (m *meter) setDelegate(provider metric.MeterProvider) {\n\tmeter := provider.Meter(m.name, m.opts...)\n\tm.delegate.Store(meter)\n\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\tfor _, inst := range m.instruments {\n\t\tinst.setDelegate(meter)\n\t}\n\n\tfor e := m.registry.Front(); e != nil; e = e.Next() {\n\t\tr := e.Value.(*registration)\n\t\tr.setDelegate(meter)\n\t\tm.registry.Remove(e)\n\t}\n\n\tm.instruments = nil\n\tm.registry.Init()\n}\n\nfunc (m *meter) Int64Counter(name string, options ...metric.Int64CounterOption) (metric.Int64Counter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Int64Counter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &siCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Int64UpDownCounter(name string, options ...metric.Int64UpDownCounterOption) (metric.Int64UpDownCounter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Int64UpDownCounter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &siUpDownCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Int64Histogram(name string, options ...metric.Int64HistogramOption) (metric.Int64Histogram, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Int64Histogram(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &siHistogram{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Int64ObservableCounter(name string, options ...metric.Int64ObservableCounterOption) (metric.Int64ObservableCounter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Int64ObservableCounter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &aiCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Int64ObservableUpDownCounter(name string, options ...metric.Int64ObservableUpDownCounterOption) (metric.Int64ObservableUpDownCounter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Int64ObservableUpDownCounter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &aiUpDownCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Int64ObservableGauge(name string, options ...metric.Int64ObservableGaugeOption) (metric.Int64ObservableGauge, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Int64ObservableGauge(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &aiGauge{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Float64Counter(name string, options ...metric.Float64CounterOption) (metric.Float64Counter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Float64Counter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &sfCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Float64UpDownCounter(name string, options ...metric.Float64UpDownCounterOption) (metric.Float64UpDownCounter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Float64UpDownCounter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &sfUpDownCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Float64Histogram(name string, options ...metric.Float64HistogramOption) (metric.Float64Histogram, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Float64Histogram(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &sfHistogram{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Float64ObservableCounter(name string, options ...metric.Float64ObservableCounterOption) (metric.Float64ObservableCounter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Float64ObservableCounter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &afCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Float64ObservableUpDownCounter(name string, options ...metric.Float64ObservableUpDownCounterOption) (metric.Float64ObservableUpDownCounter, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Float64ObservableUpDownCounter(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &afUpDownCounter{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\nfunc (m *meter) Float64ObservableGauge(name string, options ...metric.Float64ObservableGaugeOption) (metric.Float64ObservableGauge, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\treturn del.Float64ObservableGauge(name, options...)\n\t}\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\ti := &afGauge{name: name, opts: options}\n\tm.instruments = append(m.instruments, i)\n\treturn i, nil\n}\n\n// RegisterCallback captures the function that will be called during Collect.\nfunc (m *meter) RegisterCallback(f metric.Callback, insts ...metric.Observable) (metric.Registration, error) {\n\tif del, ok := m.delegate.Load().(metric.Meter); ok {\n\t\tinsts = unwrapInstruments(insts)\n\t\treturn del.RegisterCallback(f, insts...)\n\t}\n\n\tm.mtx.Lock()\n\tdefer m.mtx.Unlock()\n\n\treg := &registration{instruments: insts, function: f}\n\te := m.registry.PushBack(reg)\n\treg.unreg = func() error {\n\t\tm.mtx.Lock()\n\t\t_ = m.registry.Remove(e)\n\t\tm.mtx.Unlock()\n\t\treturn nil\n\t}\n\treturn reg, nil\n}\n\ntype wrapped interface {\n\tunwrap() metric.Observable\n}\n\nfunc unwrapInstruments(instruments []metric.Observable) []metric.Observable {\n\tout := make([]metric.Observable, 0, len(instruments))\n\n\tfor _, inst := range instruments {\n\t\tif in, ok := inst.(wrapped); ok {\n\t\t\tout = append(out, in.unwrap())\n\t\t} else {\n\t\t\tout = append(out, inst)\n\t\t}\n\t}\n\n\treturn out\n}\n\ntype registration struct {\n\tembedded.Registration\n\n\tinstruments []metric.Observable\n\tfunction    metric.Callback\n\n\tunreg   func() error\n\tunregMu sync.Mutex\n}\n\nfunc (c *registration) setDelegate(m metric.Meter) {\n\tinsts := unwrapInstruments(c.instruments)\n\n\tc.unregMu.Lock()\n\tdefer c.unregMu.Unlock()\n\n\tif c.unreg == nil {\n\t\t// Unregister already called.\n\t\treturn\n\t}\n\n\treg, err := m.RegisterCallback(c.function, insts...)\n\tif err != nil {\n\t\tGetErrorHandler().Handle(err)\n\t}\n\n\tc.unreg = reg.Unregister\n}\n\nfunc (c *registration) Unregister() error {\n\tc.unregMu.Lock()\n\tdefer c.unregMu.Unlock()\n\tif c.unreg == nil {\n\t\t// Unregister already called.\n\t\treturn nil\n\t}\n\n\tvar err error\n\terr, c.unreg = c.unreg(), nil\n\treturn err\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/propagator.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"context\"\n\t\"sync\"\n\n\t\"go.opentelemetry.io/otel/propagation\"\n)\n\n// textMapPropagator is a default TextMapPropagator that delegates calls to a\n// registered delegate if one is set, otherwise it defaults to delegating the\n// calls to a the default no-op propagation.TextMapPropagator.\ntype textMapPropagator struct {\n\tmtx      sync.Mutex\n\tonce     sync.Once\n\tdelegate propagation.TextMapPropagator\n\tnoop     propagation.TextMapPropagator\n}\n\n// Compile-time guarantee that textMapPropagator implements the\n// propagation.TextMapPropagator interface.\nvar _ propagation.TextMapPropagator = (*textMapPropagator)(nil)\n\nfunc newTextMapPropagator() *textMapPropagator {\n\treturn &textMapPropagator{\n\t\tnoop: propagation.NewCompositeTextMapPropagator(),\n\t}\n}\n\n// SetDelegate sets a delegate propagation.TextMapPropagator that all calls are\n// forwarded to. Delegation can only be performed once, all subsequent calls\n// perform no delegation.\nfunc (p *textMapPropagator) SetDelegate(delegate propagation.TextMapPropagator) {\n\tif delegate == nil {\n\t\treturn\n\t}\n\n\tp.mtx.Lock()\n\tp.once.Do(func() { p.delegate = delegate })\n\tp.mtx.Unlock()\n}\n\n// effectiveDelegate returns the current delegate of p if one is set,\n// otherwise the default noop TextMapPropagator is returned. This method\n// can be called concurrently.\nfunc (p *textMapPropagator) effectiveDelegate() propagation.TextMapPropagator {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\tif p.delegate != nil {\n\t\treturn p.delegate\n\t}\n\treturn p.noop\n}\n\n// Inject set cross-cutting concerns from the Context into the carrier.\nfunc (p *textMapPropagator) Inject(ctx context.Context, carrier propagation.TextMapCarrier) {\n\tp.effectiveDelegate().Inject(ctx, carrier)\n}\n\n// Extract reads cross-cutting concerns from the carrier into a Context.\nfunc (p *textMapPropagator) Extract(ctx context.Context, carrier propagation.TextMapCarrier) context.Context {\n\treturn p.effectiveDelegate().Extract(ctx, carrier)\n}\n\n// Fields returns the keys whose values are set with Inject.\nfunc (p *textMapPropagator) Fields() []string {\n\treturn p.effectiveDelegate().Fields()\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/state.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\nimport (\n\t\"errors\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel/metric\"\n\t\"go.opentelemetry.io/otel/propagation\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\ntype (\n\ttracerProviderHolder struct {\n\t\ttp trace.TracerProvider\n\t}\n\n\tpropagatorsHolder struct {\n\t\ttm propagation.TextMapPropagator\n\t}\n\n\tmeterProviderHolder struct {\n\t\tmp metric.MeterProvider\n\t}\n)\n\nvar (\n\tglobalTracer        = defaultTracerValue()\n\tglobalPropagators   = defaultPropagatorsValue()\n\tglobalMeterProvider = defaultMeterProvider()\n\n\tdelegateTraceOnce             sync.Once\n\tdelegateTextMapPropagatorOnce sync.Once\n\tdelegateMeterOnce             sync.Once\n)\n\n// TracerProvider is the internal implementation for global.TracerProvider.\nfunc TracerProvider() trace.TracerProvider {\n\treturn globalTracer.Load().(tracerProviderHolder).tp\n}\n\n// SetTracerProvider is the internal implementation for global.SetTracerProvider.\nfunc SetTracerProvider(tp trace.TracerProvider) {\n\tcurrent := TracerProvider()\n\n\tif _, cOk := current.(*tracerProvider); cOk {\n\t\tif _, tpOk := tp.(*tracerProvider); tpOk && current == tp {\n\t\t\t// Do not assign the default delegating TracerProvider to delegate\n\t\t\t// to itself.\n\t\t\tError(\n\t\t\t\terrors.New(\"no delegate configured in tracer provider\"),\n\t\t\t\t\"Setting tracer provider to it's current value. No delegate will be configured\",\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t}\n\n\tdelegateTraceOnce.Do(func() {\n\t\tif def, ok := current.(*tracerProvider); ok {\n\t\t\tdef.setDelegate(tp)\n\t\t}\n\t})\n\tglobalTracer.Store(tracerProviderHolder{tp: tp})\n}\n\n// TextMapPropagator is the internal implementation for global.TextMapPropagator.\nfunc TextMapPropagator() propagation.TextMapPropagator {\n\treturn globalPropagators.Load().(propagatorsHolder).tm\n}\n\n// SetTextMapPropagator is the internal implementation for global.SetTextMapPropagator.\nfunc SetTextMapPropagator(p propagation.TextMapPropagator) {\n\tcurrent := TextMapPropagator()\n\n\tif _, cOk := current.(*textMapPropagator); cOk {\n\t\tif _, pOk := p.(*textMapPropagator); pOk && current == p {\n\t\t\t// Do not assign the default delegating TextMapPropagator to\n\t\t\t// delegate to itself.\n\t\t\tError(\n\t\t\t\terrors.New(\"no delegate configured in text map propagator\"),\n\t\t\t\t\"Setting text map propagator to it's current value. No delegate will be configured\",\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// For the textMapPropagator already returned by TextMapPropagator\n\t// delegate to p.\n\tdelegateTextMapPropagatorOnce.Do(func() {\n\t\tif def, ok := current.(*textMapPropagator); ok {\n\t\t\tdef.SetDelegate(p)\n\t\t}\n\t})\n\t// Return p when subsequent calls to TextMapPropagator are made.\n\tglobalPropagators.Store(propagatorsHolder{tm: p})\n}\n\n// MeterProvider is the internal implementation for global.MeterProvider.\nfunc MeterProvider() metric.MeterProvider {\n\treturn globalMeterProvider.Load().(meterProviderHolder).mp\n}\n\n// SetMeterProvider is the internal implementation for global.SetMeterProvider.\nfunc SetMeterProvider(mp metric.MeterProvider) {\n\tcurrent := MeterProvider()\n\tif _, cOk := current.(*meterProvider); cOk {\n\t\tif _, mpOk := mp.(*meterProvider); mpOk && current == mp {\n\t\t\t// Do not assign the default delegating MeterProvider to delegate\n\t\t\t// to itself.\n\t\t\tError(\n\t\t\t\terrors.New(\"no delegate configured in meter provider\"),\n\t\t\t\t\"Setting meter provider to it's current value. No delegate will be configured\",\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t}\n\n\tdelegateMeterOnce.Do(func() {\n\t\tif def, ok := current.(*meterProvider); ok {\n\t\t\tdef.setDelegate(mp)\n\t\t}\n\t})\n\tglobalMeterProvider.Store(meterProviderHolder{mp: mp})\n}\n\nfunc defaultTracerValue() *atomic.Value {\n\tv := &atomic.Value{}\n\tv.Store(tracerProviderHolder{tp: &tracerProvider{}})\n\treturn v\n}\n\nfunc defaultPropagatorsValue() *atomic.Value {\n\tv := &atomic.Value{}\n\tv.Store(propagatorsHolder{tm: newTextMapPropagator()})\n\treturn v\n}\n\nfunc defaultMeterProvider() *atomic.Value {\n\tv := &atomic.Value{}\n\tv.Store(meterProviderHolder{mp: &meterProvider{}})\n\treturn v\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/global/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage global // import \"go.opentelemetry.io/otel/internal/global\"\n\n/*\nThis file contains the forwarding implementation of the TracerProvider used as\nthe default global instance. Prior to initialization of an SDK, Tracers\nreturned by the global TracerProvider will provide no-op functionality. This\nmeans that all Span created prior to initialization are no-op Spans.\n\nOnce an SDK has been initialized, all provided no-op Tracers are swapped for\nTracers provided by the SDK defined TracerProvider. However, any Span started\nprior to this initialization does not change its behavior. Meaning, the Span\nremains a no-op Span.\n\nThe implementation to track and swap Tracers locks all new Tracer creation\nuntil the swap is complete. This assumes that this operation is not\nperformance-critical. If that assumption is incorrect, be sure to configure an\nSDK prior to any Tracer creation.\n*/\n\nimport (\n\t\"context\"\n\t\"sync\"\n\t\"sync/atomic\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// tracerProvider is a placeholder for a configured SDK TracerProvider.\n//\n// All TracerProvider functionality is forwarded to a delegate once\n// configured.\ntype tracerProvider struct {\n\tmtx      sync.Mutex\n\ttracers  map[il]*tracer\n\tdelegate trace.TracerProvider\n}\n\n// Compile-time guarantee that tracerProvider implements the TracerProvider\n// interface.\nvar _ trace.TracerProvider = &tracerProvider{}\n\n// setDelegate configures p to delegate all TracerProvider functionality to\n// provider.\n//\n// All Tracers provided prior to this function call are switched out to be\n// Tracers provided by provider.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (p *tracerProvider) setDelegate(provider trace.TracerProvider) {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tp.delegate = provider\n\n\tif len(p.tracers) == 0 {\n\t\treturn\n\t}\n\n\tfor _, t := range p.tracers {\n\t\tt.setDelegate(provider)\n\t}\n\n\tp.tracers = nil\n}\n\n// Tracer implements TracerProvider.\nfunc (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer {\n\tp.mtx.Lock()\n\tdefer p.mtx.Unlock()\n\n\tif p.delegate != nil {\n\t\treturn p.delegate.Tracer(name, opts...)\n\t}\n\n\t// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.\n\n\tc := trace.NewTracerConfig(opts...)\n\tkey := il{\n\t\tname:    name,\n\t\tversion: c.InstrumentationVersion(),\n\t}\n\n\tif p.tracers == nil {\n\t\tp.tracers = make(map[il]*tracer)\n\t}\n\n\tif val, ok := p.tracers[key]; ok {\n\t\treturn val\n\t}\n\n\tt := &tracer{name: name, opts: opts, provider: p}\n\tp.tracers[key] = t\n\treturn t\n}\n\ntype il struct {\n\tname    string\n\tversion string\n}\n\n// tracer is a placeholder for a trace.Tracer.\n//\n// All Tracer functionality is forwarded to a delegate once configured.\n// Otherwise, all functionality is forwarded to a NoopTracer.\ntype tracer struct {\n\tname     string\n\topts     []trace.TracerOption\n\tprovider *tracerProvider\n\n\tdelegate atomic.Value\n}\n\n// Compile-time guarantee that tracer implements the trace.Tracer interface.\nvar _ trace.Tracer = &tracer{}\n\n// setDelegate configures t to delegate all Tracer functionality to Tracers\n// created by provider.\n//\n// All subsequent calls to the Tracer methods will be passed to the delegate.\n//\n// It is guaranteed by the caller that this happens only once.\nfunc (t *tracer) setDelegate(provider trace.TracerProvider) {\n\tt.delegate.Store(provider.Tracer(t.name, t.opts...))\n}\n\n// Start implements trace.Tracer by forwarding the call to t.delegate if\n// set, otherwise it forwards the call to a NoopTracer.\nfunc (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {\n\tdelegate := t.delegate.Load()\n\tif delegate != nil {\n\t\treturn delegate.(trace.Tracer).Start(ctx, name, opts...)\n\t}\n\n\ts := nonRecordingSpan{sc: trace.SpanContextFromContext(ctx), tracer: t}\n\tctx = trace.ContextWithSpan(ctx, s)\n\treturn ctx, s\n}\n\n// nonRecordingSpan is a minimal implementation of a Span that wraps a\n// SpanContext. It performs no operations other than to return the wrapped\n// SpanContext.\ntype nonRecordingSpan struct {\n\tsc     trace.SpanContext\n\ttracer *tracer\n}\n\nvar _ trace.Span = nonRecordingSpan{}\n\n// SpanContext returns the wrapped SpanContext.\nfunc (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }\n\n// IsRecording always returns false.\nfunc (nonRecordingSpan) IsRecording() bool { return false }\n\n// SetStatus does nothing.\nfunc (nonRecordingSpan) SetStatus(codes.Code, string) {}\n\n// SetError does nothing.\nfunc (nonRecordingSpan) SetError(bool) {}\n\n// SetAttributes does nothing.\nfunc (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}\n\n// End does nothing.\nfunc (nonRecordingSpan) End(...trace.SpanEndOption) {}\n\n// RecordError does nothing.\nfunc (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}\n\n// AddEvent does nothing.\nfunc (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}\n\n// SetName does nothing.\nfunc (nonRecordingSpan) SetName(string) {}\n\nfunc (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal/rawhelpers.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage internal // import \"go.opentelemetry.io/otel/internal\"\n\nimport (\n\t\"math\"\n\t\"unsafe\"\n)\n\nfunc BoolToRaw(b bool) uint64 { // nolint:revive  // b is not a control flag.\n\tif b {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nfunc RawToBool(r uint64) bool {\n\treturn r != 0\n}\n\nfunc Int64ToRaw(i int64) uint64 {\n\treturn uint64(i)\n}\n\nfunc RawToInt64(r uint64) int64 {\n\treturn int64(r)\n}\n\nfunc Float64ToRaw(f float64) uint64 {\n\treturn math.Float64bits(f)\n}\n\nfunc RawToFloat64(r uint64) float64 {\n\treturn math.Float64frombits(r)\n}\n\nfunc RawPtrToFloat64Ptr(r *uint64) *float64 {\n\treturn (*float64)(unsafe.Pointer(r))\n}\n\nfunc RawPtrToInt64Ptr(r *uint64) *int64 {\n\treturn (*int64)(unsafe.Pointer(r))\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/internal_logging.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"github.com/go-logr/logr\"\n\n\t\"go.opentelemetry.io/otel/internal/global\"\n)\n\n// SetLogger configures the logger used internally to opentelemetry.\nfunc SetLogger(logger logr.Logger) {\n\tglobal.SetLogger(logger)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/go.opentelemetry.io/otel/metric/asyncfloat64.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Float64Observable describes a set of instruments used asynchronously to\n// record float64 measurements once per collection cycle. Observations of\n// these instruments are only made within a callback.\n//\n// Warning: Methods may be added to this interface in minor releases.\ntype Float64Observable interface {\n\tObservable\n\n\tfloat64Observable()\n}\n\n// Float64ObservableCounter is an instrument used to asynchronously record\n// increasing float64 measurements once per collection cycle. Observations are\n// only made within a callback for this instrument. The value observed is\n// assumed the to be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for\n// unimplemented methods.\ntype Float64ObservableCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64ObservableCounter\n\n\tFloat64Observable\n}\n\n// Float64ObservableCounterConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Float64ObservableCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Float64Callback\n}\n\n// NewFloat64ObservableCounterConfig returns a new\n// [Float64ObservableCounterConfig] with all opts applied.\nfunc NewFloat64ObservableCounterConfig(opts ...Float64ObservableCounterOption) Float64ObservableCounterConfig {\n\tvar config Float64ObservableCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64ObservableCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64ObservableCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64ObservableCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Float64ObservableCounterConfig) Callbacks() []Float64Callback {\n\treturn c.callbacks\n}\n\n// Float64ObservableCounterOption applies options to a\n// [Float64ObservableCounterConfig]. See [Float64ObservableOption] and\n// [InstrumentOption] for other options that can be used as a\n// Float64ObservableCounterOption.\ntype Float64ObservableCounterOption interface {\n\tapplyFloat64ObservableCounter(Float64ObservableCounterConfig) Float64ObservableCounterConfig\n}\n\n// Float64ObservableUpDownCounter is an instrument used to asynchronously\n// record float64 measurements once per collection cycle. Observations are only\n// made within a callback for this instrument. The value observed is assumed\n// the to be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64ObservableUpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64ObservableUpDownCounter\n\n\tFloat64Observable\n}\n\n// Float64ObservableUpDownCounterConfig contains options for asynchronous\n// counter instruments that record int64 values.\ntype Float64ObservableUpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Float64Callback\n}\n\n// NewFloat64ObservableUpDownCounterConfig returns a new\n// [Float64ObservableUpDownCounterConfig] with all opts applied.\nfunc NewFloat64ObservableUpDownCounterConfig(opts ...Float64ObservableUpDownCounterOption) Float64ObservableUpDownCounterConfig {\n\tvar config Float64ObservableUpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64ObservableUpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64ObservableUpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64ObservableUpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Float64ObservableUpDownCounterConfig) Callbacks() []Float64Callback {\n\treturn c.callbacks\n}\n\n// Float64ObservableUpDownCounterOption applies options to a\n// [Float64ObservableUpDownCounterConfig]. See [Float64ObservableOption] and\n// [InstrumentOption] for other options that can be used as a\n// Float64ObservableUpDownCounterOption.\ntype Float64ObservableUpDownCounterOption interface {\n\tapplyFloat64ObservableUpDownCounter(Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig\n}\n\n// Float64ObservableGauge is an instrument used to asynchronously record\n// instantaneous float64 measurements once per collection cycle. Observations\n// are only made within a callback for this instrument.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64ObservableGauge interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64ObservableGauge\n\n\tFloat64Observable\n}\n\n// Float64ObservableGaugeConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Float64ObservableGaugeConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Float64Callback\n}\n\n// NewFloat64ObservableGaugeConfig returns a new [Float64ObservableGaugeConfig]\n// with all opts applied.\nfunc NewFloat64ObservableGaugeConfig(opts ...Float64ObservableGaugeOption) Float64ObservableGaugeConfig {\n\tvar config Float64ObservableGaugeConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64ObservableGauge(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64ObservableGaugeConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64ObservableGaugeConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Float64ObservableGaugeConfig) Callbacks() []Float64Callback {\n\treturn c.callbacks\n}\n\n// Float64ObservableGaugeOption applies options to a\n// [Float64ObservableGaugeConfig]. See [Float64ObservableOption] and\n// [InstrumentOption] for other options that can be used as a\n// Float64ObservableGaugeOption.\ntype Float64ObservableGaugeOption interface {\n\tapplyFloat64ObservableGauge(Float64ObservableGaugeConfig) Float64ObservableGaugeConfig\n}\n\n// Float64Observer is a recorder of float64 measurements.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64Observer interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64Observer\n\n\t// Observe records the float64 value.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tObserve(value float64, options ...ObserveOption)\n}\n\n// Float64Callback is a function registered with a Meter that makes\n// observations for a Float64Observerable instrument it is registered with.\n// Calls to the Float64Observer record measurement values for the\n// Float64Observable.\n//\n// The function needs to complete in a finite amount of time and the deadline\n// of the passed context is expected to be honored.\n//\n// The function needs to make unique observations across all registered\n// Float64Callbacks. Meaning, it should not report measurements with the same\n// attributes as another Float64Callbacks also registered for the same\n// instrument.\n//\n// The function needs to be concurrent safe.\ntype Float64Callback func(context.Context, Float64Observer) error\n\n// Float64ObservableOption applies options to float64 Observer instruments.\ntype Float64ObservableOption interface {\n\tFloat64ObservableCounterOption\n\tFloat64ObservableUpDownCounterOption\n\tFloat64ObservableGaugeOption\n}\n\ntype float64CallbackOpt struct {\n\tcback Float64Callback\n}\n\nfunc (o float64CallbackOpt) applyFloat64ObservableCounter(cfg Float64ObservableCounterConfig) Float64ObservableCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o float64CallbackOpt) applyFloat64ObservableUpDownCounter(cfg Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o float64CallbackOpt) applyFloat64ObservableGauge(cfg Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\n// WithFloat64Callback adds callback to be called for an instrument.\nfunc WithFloat64Callback(callback Float64Callback) Float64ObservableOption {\n\treturn float64CallbackOpt{callback}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/asyncint64.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Int64Observable describes a set of instruments used asynchronously to record\n// int64 measurements once per collection cycle. Observations of these\n// instruments are only made within a callback.\n//\n// Warning: Methods may be added to this interface in minor releases.\ntype Int64Observable interface {\n\tObservable\n\n\tint64Observable()\n}\n\n// Int64ObservableCounter is an instrument used to asynchronously record\n// increasing int64 measurements once per collection cycle. Observations are\n// only made within a callback for this instrument. The value observed is\n// assumed the to be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64ObservableCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64ObservableCounter\n\n\tInt64Observable\n}\n\n// Int64ObservableCounterConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Int64ObservableCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Int64Callback\n}\n\n// NewInt64ObservableCounterConfig returns a new [Int64ObservableCounterConfig]\n// with all opts applied.\nfunc NewInt64ObservableCounterConfig(opts ...Int64ObservableCounterOption) Int64ObservableCounterConfig {\n\tvar config Int64ObservableCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64ObservableCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64ObservableCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64ObservableCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Int64ObservableCounterConfig) Callbacks() []Int64Callback {\n\treturn c.callbacks\n}\n\n// Int64ObservableCounterOption applies options to a\n// [Int64ObservableCounterConfig]. See [Int64ObservableOption] and\n// [InstrumentOption] for other options that can be used as an\n// Int64ObservableCounterOption.\ntype Int64ObservableCounterOption interface {\n\tapplyInt64ObservableCounter(Int64ObservableCounterConfig) Int64ObservableCounterConfig\n}\n\n// Int64ObservableUpDownCounter is an instrument used to asynchronously record\n// int64 measurements once per collection cycle. Observations are only made\n// within a callback for this instrument. The value observed is assumed the to\n// be the cumulative sum of the count.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64ObservableUpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64ObservableUpDownCounter\n\n\tInt64Observable\n}\n\n// Int64ObservableUpDownCounterConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Int64ObservableUpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Int64Callback\n}\n\n// NewInt64ObservableUpDownCounterConfig returns a new\n// [Int64ObservableUpDownCounterConfig] with all opts applied.\nfunc NewInt64ObservableUpDownCounterConfig(opts ...Int64ObservableUpDownCounterOption) Int64ObservableUpDownCounterConfig {\n\tvar config Int64ObservableUpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64ObservableUpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64ObservableUpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64ObservableUpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Int64ObservableUpDownCounterConfig) Callbacks() []Int64Callback {\n\treturn c.callbacks\n}\n\n// Int64ObservableUpDownCounterOption applies options to a\n// [Int64ObservableUpDownCounterConfig]. See [Int64ObservableOption] and\n// [InstrumentOption] for other options that can be used as an\n// Int64ObservableUpDownCounterOption.\ntype Int64ObservableUpDownCounterOption interface {\n\tapplyInt64ObservableUpDownCounter(Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig\n}\n\n// Int64ObservableGauge is an instrument used to asynchronously record\n// instantaneous int64 measurements once per collection cycle. Observations are\n// only made within a callback for this instrument.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64ObservableGauge interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64ObservableGauge\n\n\tInt64Observable\n}\n\n// Int64ObservableGaugeConfig contains options for asynchronous counter\n// instruments that record int64 values.\ntype Int64ObservableGaugeConfig struct {\n\tdescription string\n\tunit        string\n\tcallbacks   []Int64Callback\n}\n\n// NewInt64ObservableGaugeConfig returns a new [Int64ObservableGaugeConfig]\n// with all opts applied.\nfunc NewInt64ObservableGaugeConfig(opts ...Int64ObservableGaugeOption) Int64ObservableGaugeConfig {\n\tvar config Int64ObservableGaugeConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64ObservableGauge(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64ObservableGaugeConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64ObservableGaugeConfig) Unit() string {\n\treturn c.unit\n}\n\n// Callbacks returns the configured callbacks.\nfunc (c Int64ObservableGaugeConfig) Callbacks() []Int64Callback {\n\treturn c.callbacks\n}\n\n// Int64ObservableGaugeOption applies options to a\n// [Int64ObservableGaugeConfig]. See [Int64ObservableOption] and\n// [InstrumentOption] for other options that can be used as an\n// Int64ObservableGaugeOption.\ntype Int64ObservableGaugeOption interface {\n\tapplyInt64ObservableGauge(Int64ObservableGaugeConfig) Int64ObservableGaugeConfig\n}\n\n// Int64Observer is a recorder of int64 measurements.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64Observer interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64Observer\n\n\t// Observe records the int64 value.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tObserve(value int64, options ...ObserveOption)\n}\n\n// Int64Callback is a function registered with a Meter that makes observations\n// for an Int64Observerable instrument it is registered with. Calls to the\n// Int64Observer record measurement values for the Int64Observable.\n//\n// The function needs to complete in a finite amount of time and the deadline\n// of the passed context is expected to be honored.\n//\n// The function needs to make unique observations across all registered\n// Int64Callbacks. Meaning, it should not report measurements with the same\n// attributes as another Int64Callbacks also registered for the same\n// instrument.\n//\n// The function needs to be concurrent safe.\ntype Int64Callback func(context.Context, Int64Observer) error\n\n// Int64ObservableOption applies options to int64 Observer instruments.\ntype Int64ObservableOption interface {\n\tInt64ObservableCounterOption\n\tInt64ObservableUpDownCounterOption\n\tInt64ObservableGaugeOption\n}\n\ntype int64CallbackOpt struct {\n\tcback Int64Callback\n}\n\nfunc (o int64CallbackOpt) applyInt64ObservableCounter(cfg Int64ObservableCounterConfig) Int64ObservableCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o int64CallbackOpt) applyInt64ObservableUpDownCounter(cfg Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\nfunc (o int64CallbackOpt) applyInt64ObservableGauge(cfg Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {\n\tcfg.callbacks = append(cfg.callbacks, o.cback)\n\treturn cfg\n}\n\n// WithInt64Callback adds callback to be called for an instrument.\nfunc WithInt64Callback(callback Int64Callback) Int64ObservableOption {\n\treturn int64CallbackOpt{callback}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/config.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// MeterConfig contains options for Meters.\ntype MeterConfig struct {\n\tinstrumentationVersion string\n\tschemaURL              string\n\tattrs                  attribute.Set\n\n\t// Ensure forward compatibility by explicitly making this not comparable.\n\tnoCmp [0]func() //nolint: unused  // This is indeed used.\n}\n\n// InstrumentationVersion returns the version of the library providing\n// instrumentation.\nfunc (cfg MeterConfig) InstrumentationVersion() string {\n\treturn cfg.instrumentationVersion\n}\n\n// InstrumentationAttributes returns the attributes associated with the library\n// providing instrumentation.\nfunc (cfg MeterConfig) InstrumentationAttributes() attribute.Set {\n\treturn cfg.attrs\n}\n\n// SchemaURL is the schema_url of the library providing instrumentation.\nfunc (cfg MeterConfig) SchemaURL() string {\n\treturn cfg.schemaURL\n}\n\n// MeterOption is an interface for applying Meter options.\ntype MeterOption interface {\n\t// applyMeter is used to set a MeterOption value of a MeterConfig.\n\tapplyMeter(MeterConfig) MeterConfig\n}\n\n// NewMeterConfig creates a new MeterConfig and applies\n// all the given options.\nfunc NewMeterConfig(opts ...MeterOption) MeterConfig {\n\tvar config MeterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyMeter(config)\n\t}\n\treturn config\n}\n\ntype meterOptionFunc func(MeterConfig) MeterConfig\n\nfunc (fn meterOptionFunc) applyMeter(cfg MeterConfig) MeterConfig {\n\treturn fn(cfg)\n}\n\n// WithInstrumentationVersion sets the instrumentation version.\nfunc WithInstrumentationVersion(version string) MeterOption {\n\treturn meterOptionFunc(func(config MeterConfig) MeterConfig {\n\t\tconfig.instrumentationVersion = version\n\t\treturn config\n\t})\n}\n\n// WithInstrumentationAttributes sets the instrumentation attributes.\n//\n// The passed attributes will be de-duplicated.\nfunc WithInstrumentationAttributes(attr ...attribute.KeyValue) MeterOption {\n\treturn meterOptionFunc(func(config MeterConfig) MeterConfig {\n\t\tconfig.attrs = attribute.NewSet(attr...)\n\t\treturn config\n\t})\n}\n\n// WithSchemaURL sets the schema URL.\nfunc WithSchemaURL(schemaURL string) MeterOption {\n\treturn meterOptionFunc(func(config MeterConfig) MeterConfig {\n\t\tconfig.schemaURL = schemaURL\n\t\treturn config\n\t})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage metric provides the OpenTelemetry API used to measure metrics about\nsource code operation.\n\nThis API is separate from its implementation so the instrumentation built from\nit is reusable. See [go.opentelemetry.io/otel/sdk/metric] for the official\nOpenTelemetry implementation of this API.\n\nAll measurements made with this package are made via instruments. These\ninstruments are created by a [Meter] which itself is created by a\n[MeterProvider]. Applications need to accept a [MeterProvider] implementation\nas a starting point when instrumenting. This can be done directly, or by using\nthe OpenTelemetry global MeterProvider via [GetMeterProvider]. Using an\nappropriately named [Meter] from the accepted [MeterProvider], instrumentation\ncan then be built from the [Meter]'s instruments.\n\n# Instruments\n\nEach instrument is designed to make measurements of a particular type. Broadly,\nall instruments fall into two overlapping logical categories: asynchronous or\nsynchronous, and int64 or float64.\n\nAll synchronous instruments ([Int64Counter], [Int64UpDownCounter],\n[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and\n[Float64Histogram]) are used to measure the operation and performance of source\ncode during the source code execution. These instruments only make measurements\nwhen the source code they instrument is run.\n\nAll asynchronous instruments ([Int64ObservableCounter],\n[Int64ObservableUpDownCounter], [Int64ObservableGauge],\n[Float64ObservableCounter], [Float64ObservableUpDownCounter], and\n[Float64ObservableGauge]) are used to measure metrics outside of the execution\nof source code. They are said to make \"observations\" via a callback function\ncalled once every measurement collection cycle.\n\nEach instrument is also grouped by the value type it measures. Either int64 or\nfloat64. The value being measured will dictate which instrument in these\ncategories to use.\n\nOutside of these two broad categories, instruments are described by the\nfunction they are designed to serve. All Counters ([Int64Counter],\n[Float64Counter], [Int64ObservableCounter], and [Float64ObservableCounter]) are\ndesigned to measure values that never decrease in value, but instead only\nincrementally increase in value. UpDownCounters ([Int64UpDownCounter],\n[Float64UpDownCounter], [Int64ObservableUpDownCounter], and\n[Float64ObservableUpDownCounter]) on the other hand, are designed to measure\nvalues that can increase and decrease. When more information needs to be\nconveyed about all the synchronous measurements made during a collection cycle,\na Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally,\nwhen just the most recent measurement needs to be conveyed about an\nasynchronous measurement, a Gauge ([Int64ObservableGauge] and\n[Float64ObservableGauge]) should be used.\n\nSee the [OpenTelemetry documentation] for more information about instruments\nand their intended use.\n\n# Measurements\n\nMeasurements are made by recording values and information about the values with\nan instrument. How these measurements are recorded depends on the instrument.\n\nMeasurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter],\n[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and\n[Float64Histogram]) are recorded using the instrument methods directly. All\ncounter instruments have an Add method that is used to measure an increment\nvalue, and all histogram instruments have a Record method to measure a data\npoint.\n\nAsynchronous instruments ([Int64ObservableCounter],\n[Int64ObservableUpDownCounter], [Int64ObservableGauge],\n[Float64ObservableCounter], [Float64ObservableUpDownCounter], and\n[Float64ObservableGauge]) record measurements within a callback function. The\ncallback is registered with the Meter which ensures the callback is called once\nper collection cycle. A callback can be registered two ways: during the\ninstrument's creation using an option, or later using the RegisterCallback\nmethod of the [Meter] that created the instrument.\n\nIf the following criteria are met, an option ([WithInt64Callback] or\n[WithFloat64Callback]) can be used during the asynchronous instrument's\ncreation to register a callback ([Int64Callback] or [Float64Callback],\nrespectively):\n\n  - The measurement process is known when the instrument is created\n  - Only that instrument will make a measurement within the callback\n  - The callback never needs to be unregistered\n\nIf the criteria are not met, use the RegisterCallback method of the [Meter] that\ncreated the instrument to register a [Callback].\n\n# API Implementations\n\nThis package does not conform to the standard Go versioning policy, all of its\ninterfaces may have methods added to them without a package major version bump.\nThis non-standard API evolution could surprise an uninformed implementation\nauthor. They could unknowingly build their implementation in a way that would\nresult in a runtime panic for their users that update to the new API.\n\nThe API is designed to help inform an instrumentation author about this\nnon-standard API evolution. It requires them to choose a default behavior for\nunimplemented interface methods. There are three behavior choices they can\nmake:\n\n  - Compilation failure\n  - Panic\n  - Default to another implementation\n\nAll interfaces in this API embed a corresponding interface from\n[go.opentelemetry.io/otel/metric/embedded]. If an author wants the default\nbehavior of their implementations to be a compilation failure, signaling to\ntheir users they need to update to the latest version of that implementation,\nthey need to embed the corresponding interface from\n[go.opentelemetry.io/otel/metric/embedded] in their implementation. For\nexample,\n\n\timport \"go.opentelemetry.io/otel/metric/embedded\"\n\n\ttype MeterProvider struct {\n\t\tembedded.MeterProvider\n\t\t// ...\n\t}\n\nIf an author wants the default behavior of their implementations to a panic,\nthey need to embed the API interface directly.\n\n\timport \"go.opentelemetry.io/otel/metric\"\n\n\ttype MeterProvider struct {\n\t\tmetric.MeterProvider\n\t\t// ...\n\t}\n\nThis is not a recommended behavior as it could lead to publishing packages that\ncontain runtime panics when users update other package that use newer versions\nof [go.opentelemetry.io/otel/metric].\n\nFinally, an author can embed another implementation in theirs. The embedded\nimplementation will be used for methods not defined by the author. For example,\nan author who want to default to silently dropping the call can use\n[go.opentelemetry.io/otel/metric/noop]:\n\n\timport \"go.opentelemetry.io/otel/metric/noop\"\n\n\ttype MeterProvider struct {\n\t\tnoop.MeterProvider\n\t\t// ...\n\t}\n\nIt is strongly recommended that authors only embed\n[go.opentelemetry.io/otel/metric/noop] if they choose this default behavior.\nThat implementation is the only one OpenTelemetry authors can guarantee will\nfully implement all the API interfaces when a user updates their API.\n\n[OpenTelemetry documentation]: https://opentelemetry.io/docs/concepts/signals/metrics/\n[GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider\n*/\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/embedded/embedded.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n// Package embedded provides interfaces embedded within the [OpenTelemetry\n// metric API].\n//\n// Implementers of the [OpenTelemetry metric API] can embed the relevant type\n// from this package into their implementation directly. Doing so will result\n// in a compilation error for users when the [OpenTelemetry metric API] is\n// extended (which is something that can happen without a major version bump of\n// the API package).\n//\n// [OpenTelemetry metric API]: https://pkg.go.dev/go.opentelemetry.io/otel/metric\npackage embedded // import \"go.opentelemetry.io/otel/metric/embedded\"\n\n// MeterProvider is embedded in\n// [go.opentelemetry.io/otel/metric.MeterProvider].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.MeterProvider] if you want users to\n// experience a compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.MeterProvider]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype MeterProvider interface{ meterProvider() }\n\n// Meter is embedded in [go.opentelemetry.io/otel/metric.Meter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Meter] if you want users to experience a\n// compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Meter] interface\n// is extended (which is something that can happen without a major version bump\n// of the API package).\ntype Meter interface{ meter() }\n\n// Float64Observer is embedded in\n// [go.opentelemetry.io/otel/metric.Float64Observer].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64Observer] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64Observer] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Float64Observer interface{ float64Observer() }\n\n// Int64Observer is embedded in\n// [go.opentelemetry.io/otel/metric.Int64Observer].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64Observer] if you want users\n// to experience a compilation error, signaling they need to update to your\n// latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64Observer] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64Observer interface{ int64Observer() }\n\n// Observer is embedded in [go.opentelemetry.io/otel/metric.Observer].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Observer] if you want users to experience a\n// compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Observer]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Observer interface{ observer() }\n\n// Registration is embedded in [go.opentelemetry.io/otel/metric.Registration].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Registration] if you want users to\n// experience a compilation error, signaling they need to update to your latest\n// implementation, when the [go.opentelemetry.io/otel/metric.Registration]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Registration interface{ registration() }\n\n// Float64Counter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64Counter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64Counter] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64Counter] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Float64Counter interface{ float64Counter() }\n\n// Float64Histogram is embedded in\n// [go.opentelemetry.io/otel/metric.Float64Histogram].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64Histogram] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64Histogram] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Float64Histogram interface{ float64Histogram() }\n\n// Float64ObservableCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64ObservableCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64ObservableCounter] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64ObservableCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Float64ObservableCounter interface{ float64ObservableCounter() }\n\n// Float64ObservableGauge is embedded in\n// [go.opentelemetry.io/otel/metric.Float64ObservableGauge].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64ObservableGauge] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64ObservableGauge]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Float64ObservableGauge interface{ float64ObservableGauge() }\n\n// Float64ObservableUpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter]\n// if you want users to experience a compilation error, signaling they need to\n// update to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64ObservableUpDownCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Float64ObservableUpDownCounter interface{ float64ObservableUpDownCounter() }\n\n// Float64UpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Float64UpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Float64UpDownCounter] interface\n// is extended (which is something that can happen without a major version bump\n// of the API package).\ntype Float64UpDownCounter interface{ float64UpDownCounter() }\n\n// Int64Counter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64Counter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64Counter] if you want users\n// to experience a compilation error, signaling they need to update to your\n// latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64Counter] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64Counter interface{ int64Counter() }\n\n// Int64Histogram is embedded in\n// [go.opentelemetry.io/otel/metric.Int64Histogram].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64Histogram] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64Histogram] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64Histogram interface{ int64Histogram() }\n\n// Int64ObservableCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64ObservableCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64ObservableCounter] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64ObservableCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Int64ObservableCounter interface{ int64ObservableCounter() }\n\n// Int64ObservableGauge is embedded in\n// [go.opentelemetry.io/otel/metric.Int64ObservableGauge].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] if you\n// want users to experience a compilation error, signaling they need to update\n// to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64ObservableGauge] interface\n// is extended (which is something that can happen without a major version bump\n// of the API package).\ntype Int64ObservableGauge interface{ int64ObservableGauge() }\n\n// Int64ObservableUpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter] if\n// you want users to experience a compilation error, signaling they need to\n// update to your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64ObservableUpDownCounter]\n// interface is extended (which is something that can happen without a major\n// version bump of the API package).\ntype Int64ObservableUpDownCounter interface{ int64ObservableUpDownCounter() }\n\n// Int64UpDownCounter is embedded in\n// [go.opentelemetry.io/otel/metric.Int64UpDownCounter].\n//\n// Embed this interface in your implementation of the\n// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] if you want\n// users to experience a compilation error, signaling they need to update to\n// your latest implementation, when the\n// [go.opentelemetry.io/otel/metric.Int64UpDownCounter] interface is\n// extended (which is something that can happen without a major version bump of\n// the API package).\ntype Int64UpDownCounter interface{ int64UpDownCounter() }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/instrument.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// Observable is used as a grouping mechanism for all instruments that are\n// updated within a Callback.\ntype Observable interface {\n\tobservable()\n}\n\n// InstrumentOption applies options to all instruments.\ntype InstrumentOption interface {\n\tInt64CounterOption\n\tInt64UpDownCounterOption\n\tInt64HistogramOption\n\tInt64ObservableCounterOption\n\tInt64ObservableUpDownCounterOption\n\tInt64ObservableGaugeOption\n\n\tFloat64CounterOption\n\tFloat64UpDownCounterOption\n\tFloat64HistogramOption\n\tFloat64ObservableCounterOption\n\tFloat64ObservableUpDownCounterOption\n\tFloat64ObservableGaugeOption\n}\n\ntype descOpt string\n\nfunc (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {\n\tc.description = string(o)\n\treturn c\n}\n\nfunc (o descOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {\n\tc.description = string(o)\n\treturn c\n}\n\n// WithDescription sets the instrument description.\nfunc WithDescription(desc string) InstrumentOption { return descOpt(desc) }\n\ntype unitOpt string\n\nfunc (o unitOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\nfunc (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {\n\tc.unit = string(o)\n\treturn c\n}\n\n// WithUnit sets the instrument unit.\n//\n// The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code.\nfunc WithUnit(u string) InstrumentOption { return unitOpt(u) }\n\n// AddOption applies options to an addition measurement. See\n// [MeasurementOption] for other options that can be used as an AddOption.\ntype AddOption interface {\n\tapplyAdd(AddConfig) AddConfig\n}\n\n// AddConfig contains options for an addition measurement.\ntype AddConfig struct {\n\tattrs attribute.Set\n}\n\n// NewAddConfig returns a new [AddConfig] with all opts applied.\nfunc NewAddConfig(opts []AddOption) AddConfig {\n\tconfig := AddConfig{attrs: *attribute.EmptySet()}\n\tfor _, o := range opts {\n\t\tconfig = o.applyAdd(config)\n\t}\n\treturn config\n}\n\n// Attributes returns the configured attribute set.\nfunc (c AddConfig) Attributes() attribute.Set {\n\treturn c.attrs\n}\n\n// RecordOption applies options to an addition measurement. See\n// [MeasurementOption] for other options that can be used as a RecordOption.\ntype RecordOption interface {\n\tapplyRecord(RecordConfig) RecordConfig\n}\n\n// RecordConfig contains options for a recorded measurement.\ntype RecordConfig struct {\n\tattrs attribute.Set\n}\n\n// NewRecordConfig returns a new [RecordConfig] with all opts applied.\nfunc NewRecordConfig(opts []RecordOption) RecordConfig {\n\tconfig := RecordConfig{attrs: *attribute.EmptySet()}\n\tfor _, o := range opts {\n\t\tconfig = o.applyRecord(config)\n\t}\n\treturn config\n}\n\n// Attributes returns the configured attribute set.\nfunc (c RecordConfig) Attributes() attribute.Set {\n\treturn c.attrs\n}\n\n// ObserveOption applies options to an addition measurement. See\n// [MeasurementOption] for other options that can be used as a ObserveOption.\ntype ObserveOption interface {\n\tapplyObserve(ObserveConfig) ObserveConfig\n}\n\n// ObserveConfig contains options for an observed measurement.\ntype ObserveConfig struct {\n\tattrs attribute.Set\n}\n\n// NewObserveConfig returns a new [ObserveConfig] with all opts applied.\nfunc NewObserveConfig(opts []ObserveOption) ObserveConfig {\n\tconfig := ObserveConfig{attrs: *attribute.EmptySet()}\n\tfor _, o := range opts {\n\t\tconfig = o.applyObserve(config)\n\t}\n\treturn config\n}\n\n// Attributes returns the configured attribute set.\nfunc (c ObserveConfig) Attributes() attribute.Set {\n\treturn c.attrs\n}\n\n// MeasurementOption applies options to all instrument measurement.\ntype MeasurementOption interface {\n\tAddOption\n\tRecordOption\n\tObserveOption\n}\n\ntype attrOpt struct {\n\tset attribute.Set\n}\n\n// mergeSets returns the union of keys between a and b. Any duplicate keys will\n// use the value associated with b.\nfunc mergeSets(a, b attribute.Set) attribute.Set {\n\t// NewMergeIterator uses the first value for any duplicates.\n\titer := attribute.NewMergeIterator(&b, &a)\n\tmerged := make([]attribute.KeyValue, 0, a.Len()+b.Len())\n\tfor iter.Next() {\n\t\tmerged = append(merged, iter.Attribute())\n\t}\n\treturn attribute.NewSet(merged...)\n}\n\nfunc (o attrOpt) applyAdd(c AddConfig) AddConfig {\n\tswitch {\n\tcase o.set.Len() == 0:\n\tcase c.attrs.Len() == 0:\n\t\tc.attrs = o.set\n\tdefault:\n\t\tc.attrs = mergeSets(c.attrs, o.set)\n\t}\n\treturn c\n}\n\nfunc (o attrOpt) applyRecord(c RecordConfig) RecordConfig {\n\tswitch {\n\tcase o.set.Len() == 0:\n\tcase c.attrs.Len() == 0:\n\t\tc.attrs = o.set\n\tdefault:\n\t\tc.attrs = mergeSets(c.attrs, o.set)\n\t}\n\treturn c\n}\n\nfunc (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig {\n\tswitch {\n\tcase o.set.Len() == 0:\n\tcase c.attrs.Len() == 0:\n\t\tc.attrs = o.set\n\tdefault:\n\t\tc.attrs = mergeSets(c.attrs, o.set)\n\t}\n\treturn c\n}\n\n// WithAttributeSet sets the attribute Set associated with a measurement is\n// made with.\n//\n// If multiple WithAttributeSet or WithAttributes options are passed the\n// attributes will be merged together in the order they are passed. Attributes\n// with duplicate keys will use the last value passed.\nfunc WithAttributeSet(attributes attribute.Set) MeasurementOption {\n\treturn attrOpt{set: attributes}\n}\n\n// WithAttributes converts attributes into an attribute Set and sets the Set to\n// be associated with a measurement. This is shorthand for:\n//\n//\tcp := make([]attribute.KeyValue, len(attributes))\n//\tcopy(cp, attributes)\n//\tWithAttributes(attribute.NewSet(cp...))\n//\n// [attribute.NewSet] may modify the passed attributes so this will make a copy\n// of attributes before creating a set in order to ensure this function is\n// concurrent safe. This makes this option function less optimized in\n// comparison to [WithAttributeSet]. Therefore, [WithAttributeSet] should be\n// preferred for performance sensitive code.\n//\n// See [WithAttributeSet] for information about how multiple WithAttributes are\n// merged.\nfunc WithAttributes(attributes ...attribute.KeyValue) MeasurementOption {\n\tcp := make([]attribute.KeyValue, len(attributes))\n\tcopy(cp, attributes)\n\treturn attrOpt{set: attribute.NewSet(cp...)}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/meter.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// MeterProvider provides access to named Meter instances, for instrumenting\n// an application or package.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype MeterProvider interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.MeterProvider\n\n\t// Meter returns a new Meter with the provided name and configuration.\n\t//\n\t// A Meter should be scoped at most to a single package. The name needs to\n\t// be unique so it does not collide with other names used by\n\t// an application, nor other applications. To achieve this, the import path\n\t// of the instrumentation package is recommended to be used as name.\n\t//\n\t// If the name is empty, then an implementation defined default name will\n\t// be used instead.\n\tMeter(name string, opts ...MeterOption) Meter\n}\n\n// Meter provides access to instrument instances for recording metrics.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Meter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Meter\n\n\t// Int64Counter returns a new Int64Counter instrument identified by name\n\t// and configured with options. The instrument is used to synchronously\n\t// record increasing int64 measurements during a computational operation.\n\tInt64Counter(name string, options ...Int64CounterOption) (Int64Counter, error)\n\t// Int64UpDownCounter returns a new Int64UpDownCounter instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to synchronously record int64 measurements during a computational\n\t// operation.\n\tInt64UpDownCounter(name string, options ...Int64UpDownCounterOption) (Int64UpDownCounter, error)\n\t// Int64Histogram returns a new Int64Histogram instrument identified by\n\t// name and configured with options. The instrument is used to\n\t// synchronously record the distribution of int64 measurements during a\n\t// computational operation.\n\tInt64Histogram(name string, options ...Int64HistogramOption) (Int64Histogram, error)\n\t// Int64ObservableCounter returns a new Int64ObservableCounter identified\n\t// by name and configured with options. The instrument is used to\n\t// asynchronously record increasing int64 measurements once per a\n\t// measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithInt64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\tInt64ObservableCounter(name string, options ...Int64ObservableCounterOption) (Int64ObservableCounter, error)\n\t// Int64ObservableUpDownCounter returns a new Int64ObservableUpDownCounter\n\t// instrument identified by name and configured with options. The\n\t// instrument is used to asynchronously record int64 measurements once per\n\t// a measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithInt64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\tInt64ObservableUpDownCounter(name string, options ...Int64ObservableUpDownCounterOption) (Int64ObservableUpDownCounter, error)\n\t// Int64ObservableGauge returns a new Int64ObservableGauge instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to asynchronously record instantaneous int64 measurements once per a\n\t// measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithInt64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\tInt64ObservableGauge(name string, options ...Int64ObservableGaugeOption) (Int64ObservableGauge, error)\n\n\t// Float64Counter returns a new Float64Counter instrument identified by\n\t// name and configured with options. The instrument is used to\n\t// synchronously record increasing float64 measurements during a\n\t// computational operation.\n\tFloat64Counter(name string, options ...Float64CounterOption) (Float64Counter, error)\n\t// Float64UpDownCounter returns a new Float64UpDownCounter instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to synchronously record float64 measurements during a computational\n\t// operation.\n\tFloat64UpDownCounter(name string, options ...Float64UpDownCounterOption) (Float64UpDownCounter, error)\n\t// Float64Histogram returns a new Float64Histogram instrument identified by\n\t// name and configured with options. The instrument is used to\n\t// synchronously record the distribution of float64 measurements during a\n\t// computational operation.\n\tFloat64Histogram(name string, options ...Float64HistogramOption) (Float64Histogram, error)\n\t// Float64ObservableCounter returns a new Float64ObservableCounter\n\t// instrument identified by name and configured with options. The\n\t// instrument is used to asynchronously record increasing float64\n\t// measurements once per a measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithFloat64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\tFloat64ObservableCounter(name string, options ...Float64ObservableCounterOption) (Float64ObservableCounter, error)\n\t// Float64ObservableUpDownCounter returns a new\n\t// Float64ObservableUpDownCounter instrument identified by name and\n\t// configured with options. The instrument is used to asynchronously record\n\t// float64 measurements once per a measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithFloat64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\tFloat64ObservableUpDownCounter(name string, options ...Float64ObservableUpDownCounterOption) (Float64ObservableUpDownCounter, error)\n\t// Float64ObservableGauge returns a new Float64ObservableGauge instrument\n\t// identified by name and configured with options. The instrument is used\n\t// to asynchronously record instantaneous float64 measurements once per a\n\t// measurement collection cycle.\n\t//\n\t// Measurements for the returned instrument are made via a callback. Use\n\t// the WithFloat64Callback option to register the callback here, or use the\n\t// RegisterCallback method of this Meter to register one later. See the\n\t// Measurements section of the package documentation for more information.\n\tFloat64ObservableGauge(name string, options ...Float64ObservableGaugeOption) (Float64ObservableGauge, error)\n\n\t// RegisterCallback registers f to be called during the collection of a\n\t// measurement cycle.\n\t//\n\t// If Unregister of the returned Registration is called, f needs to be\n\t// unregistered and not called during collection.\n\t//\n\t// The instruments f is registered with are the only instruments that f may\n\t// observe values for.\n\t//\n\t// If no instruments are passed, f should not be registered nor called\n\t// during collection.\n\t//\n\t// The function f needs to be concurrent safe.\n\tRegisterCallback(f Callback, instruments ...Observable) (Registration, error)\n}\n\n// Callback is a function registered with a Meter that makes observations for\n// the set of instruments it is registered with. The Observer parameter is used\n// to record measurement observations for these instruments.\n//\n// The function needs to complete in a finite amount of time and the deadline\n// of the passed context is expected to be honored.\n//\n// The function needs to make unique observations across all registered\n// Callbacks. Meaning, it should not report measurements for an instrument with\n// the same attributes as another Callback will report.\n//\n// The function needs to be concurrent safe.\ntype Callback func(context.Context, Observer) error\n\n// Observer records measurements for multiple instruments in a Callback.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Observer interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Observer\n\n\t// ObserveFloat64 records the float64 value for obsrv.\n\tObserveFloat64(obsrv Float64Observable, value float64, opts ...ObserveOption)\n\t// ObserveInt64 records the int64 value for obsrv.\n\tObserveInt64(obsrv Int64Observable, value int64, opts ...ObserveOption)\n}\n\n// Registration is an token representing the unique registration of a callback\n// for a set of instruments with a Meter.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Registration interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Registration\n\n\t// Unregister removes the callback registration from a Meter.\n\t//\n\t// This method needs to be idempotent and concurrent safe.\n\tUnregister() error\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/syncfloat64.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Float64Counter is an instrument that records increasing float64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64Counter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64Counter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr float64, options ...AddOption)\n}\n\n// Float64CounterConfig contains options for synchronous counter instruments that\n// record int64 values.\ntype Float64CounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewFloat64CounterConfig returns a new [Float64CounterConfig] with all opts\n// applied.\nfunc NewFloat64CounterConfig(opts ...Float64CounterOption) Float64CounterConfig {\n\tvar config Float64CounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64Counter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64CounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64CounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Float64CounterOption applies options to a [Float64CounterConfig]. See\n// [InstrumentOption] for other options that can be used as a\n// Float64CounterOption.\ntype Float64CounterOption interface {\n\tapplyFloat64Counter(Float64CounterConfig) Float64CounterConfig\n}\n\n// Float64UpDownCounter is an instrument that records increasing or decreasing\n// float64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64UpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64UpDownCounter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr float64, options ...AddOption)\n}\n\n// Float64UpDownCounterConfig contains options for synchronous counter\n// instruments that record int64 values.\ntype Float64UpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewFloat64UpDownCounterConfig returns a new [Float64UpDownCounterConfig]\n// with all opts applied.\nfunc NewFloat64UpDownCounterConfig(opts ...Float64UpDownCounterOption) Float64UpDownCounterConfig {\n\tvar config Float64UpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64UpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64UpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64UpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Float64UpDownCounterOption applies options to a\n// [Float64UpDownCounterConfig]. See [InstrumentOption] for other options that\n// can be used as a Float64UpDownCounterOption.\ntype Float64UpDownCounterOption interface {\n\tapplyFloat64UpDownCounter(Float64UpDownCounterConfig) Float64UpDownCounterConfig\n}\n\n// Float64Histogram is an instrument that records a distribution of float64\n// values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Float64Histogram interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Float64Histogram\n\n\t// Record adds an additional value to the distribution.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tRecord(ctx context.Context, incr float64, options ...RecordOption)\n}\n\n// Float64HistogramConfig contains options for synchronous counter instruments\n// that record int64 values.\ntype Float64HistogramConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewFloat64HistogramConfig returns a new [Float64HistogramConfig] with all\n// opts applied.\nfunc NewFloat64HistogramConfig(opts ...Float64HistogramOption) Float64HistogramConfig {\n\tvar config Float64HistogramConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyFloat64Histogram(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Float64HistogramConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Float64HistogramConfig) Unit() string {\n\treturn c.unit\n}\n\n// Float64HistogramOption applies options to a [Float64HistogramConfig]. See\n// [InstrumentOption] for other options that can be used as a\n// Float64HistogramOption.\ntype Float64HistogramOption interface {\n\tapplyFloat64Histogram(Float64HistogramConfig) Float64HistogramConfig\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric/syncint64.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage metric // import \"go.opentelemetry.io/otel/metric\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/metric/embedded\"\n)\n\n// Int64Counter is an instrument that records increasing int64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64Counter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64Counter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr int64, options ...AddOption)\n}\n\n// Int64CounterConfig contains options for synchronous counter instruments that\n// record int64 values.\ntype Int64CounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewInt64CounterConfig returns a new [Int64CounterConfig] with all opts\n// applied.\nfunc NewInt64CounterConfig(opts ...Int64CounterOption) Int64CounterConfig {\n\tvar config Int64CounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64Counter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64CounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64CounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Int64CounterOption applies options to a [Int64CounterConfig]. See\n// [InstrumentOption] for other options that can be used as an\n// Int64CounterOption.\ntype Int64CounterOption interface {\n\tapplyInt64Counter(Int64CounterConfig) Int64CounterConfig\n}\n\n// Int64UpDownCounter is an instrument that records increasing or decreasing\n// int64 values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64UpDownCounter interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64UpDownCounter\n\n\t// Add records a change to the counter.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tAdd(ctx context.Context, incr int64, options ...AddOption)\n}\n\n// Int64UpDownCounterConfig contains options for synchronous counter\n// instruments that record int64 values.\ntype Int64UpDownCounterConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewInt64UpDownCounterConfig returns a new [Int64UpDownCounterConfig] with\n// all opts applied.\nfunc NewInt64UpDownCounterConfig(opts ...Int64UpDownCounterOption) Int64UpDownCounterConfig {\n\tvar config Int64UpDownCounterConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64UpDownCounter(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64UpDownCounterConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64UpDownCounterConfig) Unit() string {\n\treturn c.unit\n}\n\n// Int64UpDownCounterOption applies options to a [Int64UpDownCounterConfig].\n// See [InstrumentOption] for other options that can be used as an\n// Int64UpDownCounterOption.\ntype Int64UpDownCounterOption interface {\n\tapplyInt64UpDownCounter(Int64UpDownCounterConfig) Int64UpDownCounterConfig\n}\n\n// Int64Histogram is an instrument that records a distribution of int64\n// values.\n//\n// Warning: Methods may be added to this interface in minor releases. See\n// package documentation on API implementation for information on how to set\n// default behavior for unimplemented methods.\ntype Int64Histogram interface {\n\t// Users of the interface can ignore this. This embedded type is only used\n\t// by implementations of this interface. See the \"API Implementations\"\n\t// section of the package documentation for more information.\n\tembedded.Int64Histogram\n\n\t// Record adds an additional value to the distribution.\n\t//\n\t// Use the WithAttributeSet (or, if performance is not a concern,\n\t// the WithAttributes) option to include measurement attributes.\n\tRecord(ctx context.Context, incr int64, options ...RecordOption)\n}\n\n// Int64HistogramConfig contains options for synchronous counter instruments\n// that record int64 values.\ntype Int64HistogramConfig struct {\n\tdescription string\n\tunit        string\n}\n\n// NewInt64HistogramConfig returns a new [Int64HistogramConfig] with all opts\n// applied.\nfunc NewInt64HistogramConfig(opts ...Int64HistogramOption) Int64HistogramConfig {\n\tvar config Int64HistogramConfig\n\tfor _, o := range opts {\n\t\tconfig = o.applyInt64Histogram(config)\n\t}\n\treturn config\n}\n\n// Description returns the configured description.\nfunc (c Int64HistogramConfig) Description() string {\n\treturn c.description\n}\n\n// Unit returns the configured unit.\nfunc (c Int64HistogramConfig) Unit() string {\n\treturn c.unit\n}\n\n// Int64HistogramOption applies options to a [Int64HistogramConfig]. See\n// [InstrumentOption] for other options that can be used as an\n// Int64HistogramOption.\ntype Int64HistogramOption interface {\n\tapplyInt64Histogram(Int64HistogramConfig) Int64HistogramConfig\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/metric.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/metric\"\n)\n\n// Meter returns a Meter from the global MeterProvider. The name must be the\n// name of the library providing instrumentation. This name may be the same as\n// the instrumented code only if that code provides built-in instrumentation.\n// If the name is empty, then a implementation defined default name will be\n// used instead.\n//\n// If this is called before a global MeterProvider is registered the returned\n// Meter will be a No-op implementation of a Meter. When a global MeterProvider\n// is registered for the first time, the returned Meter, and all the\n// instruments it has created or will create, are recreated automatically from\n// the new MeterProvider.\n//\n// This is short for GetMeterProvider().Meter(name).\nfunc Meter(name string, opts ...metric.MeterOption) metric.Meter {\n\treturn GetMeterProvider().Meter(name, opts...)\n}\n\n// GetMeterProvider returns the registered global meter provider.\n//\n// If no global GetMeterProvider has been registered, a No-op GetMeterProvider\n// implementation is returned. When a global GetMeterProvider is registered for\n// the first time, the returned GetMeterProvider, and all the Meters it has\n// created or will create, are recreated automatically from the new\n// GetMeterProvider.\nfunc GetMeterProvider() metric.MeterProvider {\n\treturn global.MeterProvider()\n}\n\n// SetMeterProvider registers mp as the global MeterProvider.\nfunc SetMeterProvider(mp metric.MeterProvider) {\n\tglobal.SetMeterProvider(mp)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/baggage.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/baggage\"\n)\n\nconst baggageHeader = \"baggage\"\n\n// Baggage is a propagator that supports the W3C Baggage format.\n//\n// This propagates user-defined baggage associated with a trace. The complete\n// specification is defined at https://www.w3.org/TR/baggage/.\ntype Baggage struct{}\n\nvar _ TextMapPropagator = Baggage{}\n\n// Inject sets baggage key-values from ctx into the carrier.\nfunc (b Baggage) Inject(ctx context.Context, carrier TextMapCarrier) {\n\tbStr := baggage.FromContext(ctx).String()\n\tif bStr != \"\" {\n\t\tcarrier.Set(baggageHeader, bStr)\n\t}\n}\n\n// Extract returns a copy of parent with the baggage from the carrier added.\nfunc (b Baggage) Extract(parent context.Context, carrier TextMapCarrier) context.Context {\n\tbStr := carrier.Get(baggageHeader)\n\tif bStr == \"\" {\n\t\treturn parent\n\t}\n\n\tbag, err := baggage.Parse(bStr)\n\tif err != nil {\n\t\treturn parent\n\t}\n\treturn baggage.ContextWithBaggage(parent, bag)\n}\n\n// Fields returns the keys who's values are set with Inject.\nfunc (b Baggage) Fields() []string {\n\treturn []string{baggageHeader}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage propagation contains OpenTelemetry context propagators.\n\nOpenTelemetry propagators are used to extract and inject context data from and\ninto messages exchanged by applications. The propagator supported by this\npackage is the W3C Trace Context encoding\n(https://www.w3.org/TR/trace-context/), and W3C Baggage\n(https://www.w3.org/TR/baggage/).\n*/\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/propagation.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n\nimport (\n\t\"context\"\n\t\"net/http\"\n)\n\n// TextMapCarrier is the storage medium used by a TextMapPropagator.\ntype TextMapCarrier interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Get returns the value associated with the passed key.\n\tGet(key string) string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Set stores the key-value pair.\n\tSet(key string, value string)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Keys lists the keys stored in this carrier.\n\tKeys() []string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\n// MapCarrier is a TextMapCarrier that uses a map held in memory as a storage\n// medium for propagated key-value pairs.\ntype MapCarrier map[string]string\n\n// Compile time check that MapCarrier implements the TextMapCarrier.\nvar _ TextMapCarrier = MapCarrier{}\n\n// Get returns the value associated with the passed key.\nfunc (c MapCarrier) Get(key string) string {\n\treturn c[key]\n}\n\n// Set stores the key-value pair.\nfunc (c MapCarrier) Set(key, value string) {\n\tc[key] = value\n}\n\n// Keys lists the keys stored in this carrier.\nfunc (c MapCarrier) Keys() []string {\n\tkeys := make([]string, 0, len(c))\n\tfor k := range c {\n\t\tkeys = append(keys, k)\n\t}\n\treturn keys\n}\n\n// HeaderCarrier adapts http.Header to satisfy the TextMapCarrier interface.\ntype HeaderCarrier http.Header\n\n// Get returns the value associated with the passed key.\nfunc (hc HeaderCarrier) Get(key string) string {\n\treturn http.Header(hc).Get(key)\n}\n\n// Set stores the key-value pair.\nfunc (hc HeaderCarrier) Set(key string, value string) {\n\thttp.Header(hc).Set(key, value)\n}\n\n// Keys lists the keys stored in this carrier.\nfunc (hc HeaderCarrier) Keys() []string {\n\tkeys := make([]string, 0, len(hc))\n\tfor k := range hc {\n\t\tkeys = append(keys, k)\n\t}\n\treturn keys\n}\n\n// TextMapPropagator propagates cross-cutting concerns as key-value text\n// pairs within a carrier that travels in-band across process boundaries.\ntype TextMapPropagator interface {\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Inject set cross-cutting concerns from the Context into the carrier.\n\tInject(ctx context.Context, carrier TextMapCarrier)\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Extract reads cross-cutting concerns from the carrier into a Context.\n\tExtract(ctx context.Context, carrier TextMapCarrier) context.Context\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n\n\t// Fields returns the keys whose values are set with Inject.\n\tFields() []string\n\t// DO NOT CHANGE: any modification will not be backwards compatible and\n\t// must never be done outside of a new major release.\n}\n\ntype compositeTextMapPropagator []TextMapPropagator\n\nfunc (p compositeTextMapPropagator) Inject(ctx context.Context, carrier TextMapCarrier) {\n\tfor _, i := range p {\n\t\ti.Inject(ctx, carrier)\n\t}\n}\n\nfunc (p compositeTextMapPropagator) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {\n\tfor _, i := range p {\n\t\tctx = i.Extract(ctx, carrier)\n\t}\n\treturn ctx\n}\n\nfunc (p compositeTextMapPropagator) Fields() []string {\n\tunique := make(map[string]struct{})\n\tfor _, i := range p {\n\t\tfor _, k := range i.Fields() {\n\t\t\tunique[k] = struct{}{}\n\t\t}\n\t}\n\n\tfields := make([]string, 0, len(unique))\n\tfor k := range unique {\n\t\tfields = append(fields, k)\n\t}\n\treturn fields\n}\n\n// NewCompositeTextMapPropagator returns a unified TextMapPropagator from the\n// group of passed TextMapPropagator. This allows different cross-cutting\n// concerns to be propagates in a unified manner.\n//\n// The returned TextMapPropagator will inject and extract cross-cutting\n// concerns in the order the TextMapPropagators were provided. Additionally,\n// the Fields method will return a de-duplicated slice of the keys that are\n// set with the Inject method.\nfunc NewCompositeTextMapPropagator(p ...TextMapPropagator) TextMapPropagator {\n\treturn compositeTextMapPropagator(p)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation/trace_context.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage propagation // import \"go.opentelemetry.io/otel/propagation\"\n\nimport (\n\t\"context\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"regexp\"\n\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\nconst (\n\tsupportedVersion  = 0\n\tmaxVersion        = 254\n\ttraceparentHeader = \"traceparent\"\n\ttracestateHeader  = \"tracestate\"\n)\n\n// TraceContext is a propagator that supports the W3C Trace Context format\n// (https://www.w3.org/TR/trace-context/)\n//\n// This propagator will propagate the traceparent and tracestate headers to\n// guarantee traces are not broken. It is up to the users of this propagator\n// to choose if they want to participate in a trace by modifying the\n// traceparent header and relevant parts of the tracestate header containing\n// their proprietary information.\ntype TraceContext struct{}\n\nvar _ TextMapPropagator = TraceContext{}\nvar traceCtxRegExp = regexp.MustCompile(\"^(?P<version>[0-9a-f]{2})-(?P<traceID>[a-f0-9]{32})-(?P<spanID>[a-f0-9]{16})-(?P<traceFlags>[a-f0-9]{2})(?:-.*)?$\")\n\n// Inject set tracecontext from the Context into the carrier.\nfunc (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {\n\tsc := trace.SpanContextFromContext(ctx)\n\tif !sc.IsValid() {\n\t\treturn\n\t}\n\n\tif ts := sc.TraceState().String(); ts != \"\" {\n\t\tcarrier.Set(tracestateHeader, ts)\n\t}\n\n\t// Clear all flags other than the trace-context supported sampling bit.\n\tflags := sc.TraceFlags() & trace.FlagsSampled\n\n\th := fmt.Sprintf(\"%.2x-%s-%s-%s\",\n\t\tsupportedVersion,\n\t\tsc.TraceID(),\n\t\tsc.SpanID(),\n\t\tflags)\n\tcarrier.Set(traceparentHeader, h)\n}\n\n// Extract reads tracecontext from the carrier into a returned Context.\n//\n// The returned Context will be a copy of ctx and contain the extracted\n// tracecontext as the remote SpanContext. If the extracted tracecontext is\n// invalid, the passed ctx will be returned directly instead.\nfunc (tc TraceContext) Extract(ctx context.Context, carrier TextMapCarrier) context.Context {\n\tsc := tc.extract(carrier)\n\tif !sc.IsValid() {\n\t\treturn ctx\n\t}\n\treturn trace.ContextWithRemoteSpanContext(ctx, sc)\n}\n\nfunc (tc TraceContext) extract(carrier TextMapCarrier) trace.SpanContext {\n\th := carrier.Get(traceparentHeader)\n\tif h == \"\" {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tmatches := traceCtxRegExp.FindStringSubmatch(h)\n\n\tif len(matches) == 0 {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tif len(matches) < 5 { // four subgroups plus the overall match\n\t\treturn trace.SpanContext{}\n\t}\n\n\tif len(matches[1]) != 2 {\n\t\treturn trace.SpanContext{}\n\t}\n\tver, err := hex.DecodeString(matches[1])\n\tif err != nil {\n\t\treturn trace.SpanContext{}\n\t}\n\tversion := int(ver[0])\n\tif version > maxVersion {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tif version == 0 && len(matches) != 5 { // four subgroups plus the overall match\n\t\treturn trace.SpanContext{}\n\t}\n\n\tif len(matches[2]) != 32 {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tvar scc trace.SpanContextConfig\n\n\tscc.TraceID, err = trace.TraceIDFromHex(matches[2][:32])\n\tif err != nil {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tif len(matches[3]) != 16 {\n\t\treturn trace.SpanContext{}\n\t}\n\tscc.SpanID, err = trace.SpanIDFromHex(matches[3])\n\tif err != nil {\n\t\treturn trace.SpanContext{}\n\t}\n\n\tif len(matches[4]) != 2 {\n\t\treturn trace.SpanContext{}\n\t}\n\topts, err := hex.DecodeString(matches[4])\n\tif err != nil || len(opts) < 1 || (version == 0 && opts[0] > 2) {\n\t\treturn trace.SpanContext{}\n\t}\n\t// Clear all flags other than the trace-context supported sampling bit.\n\tscc.TraceFlags = trace.TraceFlags(opts[0]) & trace.FlagsSampled\n\n\t// Ignore the error returned here. Failure to parse tracestate MUST NOT\n\t// affect the parsing of traceparent according to the W3C tracecontext\n\t// specification.\n\tscc.TraceState, _ = trace.ParseTraceState(carrier.Get(tracestateHeader))\n\tscc.Remote = true\n\n\tsc := trace.NewSpanContext(scc)\n\tif !sc.IsValid() {\n\t\treturn trace.SpanContext{}\n\t}\n\n\treturn sc\n}\n\n// Fields returns the keys who's values are set with Inject.\nfunc (tc TraceContext) Fields() []string {\n\treturn []string{traceparentHeader, tracestateHeader}\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/propagation.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/propagation\"\n)\n\n// GetTextMapPropagator returns the global TextMapPropagator. If none has been\n// set, a No-Op TextMapPropagator is returned.\nfunc GetTextMapPropagator() propagation.TextMapPropagator {\n\treturn global.TextMapPropagator()\n}\n\n// SetTextMapPropagator sets propagator as the global TextMapPropagator.\nfunc SetTextMapPropagator(propagator propagation.TextMapPropagator) {\n\tglobal.SetTextMapPropagator(propagator)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/requirements.txt",
    "content": "codespell==2.2.5\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.17.0/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n// Package semconv implements OpenTelemetry semantic conventions.\n//\n// OpenTelemetry semantic conventions are agreed standardized naming\n// patterns for OpenTelemetry things. This package represents the conventions\n// as of the v1.17.0 version of the OpenTelemetry specification.\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.17.0/event.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n// Code generated from semantic convention specification. DO NOT EDIT.\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// This semantic convention defines the attributes used to represent a feature\n// flag evaluation as an event.\nconst (\n\t// FeatureFlagKeyKey is the attribute Key conforming to the\n\t// \"feature_flag.key\" semantic conventions. It represents the unique\n\t// identifier of the feature flag.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'logo-color'\n\tFeatureFlagKeyKey = attribute.Key(\"feature_flag.key\")\n\n\t// FeatureFlagProviderNameKey is the attribute Key conforming to the\n\t// \"feature_flag.provider_name\" semantic conventions. It represents the\n\t// name of the service provider that performs the flag evaluation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: stable\n\t// Examples: 'Flag Manager'\n\tFeatureFlagProviderNameKey = attribute.Key(\"feature_flag.provider_name\")\n\n\t// FeatureFlagVariantKey is the attribute Key conforming to the\n\t// \"feature_flag.variant\" semantic conventions. It represents the sHOULD be\n\t// a semantic identifier for a value. If one is unavailable, a stringified\n\t// version of the value can be used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: stable\n\t// Examples: 'red', 'true', 'on'\n\t// Note: A semantic identifier, commonly referred to as a variant, provides\n\t// a means\n\t// for referring to a value without including the value itself. This can\n\t// provide additional context for understanding the meaning behind a value.\n\t// For example, the variant `red` maybe be used for the value `#c05543`.\n\t//\n\t// A stringified version of the value can be used in situations where a\n\t// semantic identifier is unavailable. String representation of the value\n\t// should be determined by the implementer.\n\tFeatureFlagVariantKey = attribute.Key(\"feature_flag.variant\")\n)\n\n// FeatureFlagKey returns an attribute KeyValue conforming to the\n// \"feature_flag.key\" semantic conventions. It represents the unique identifier\n// of the feature flag.\nfunc FeatureFlagKey(val string) attribute.KeyValue {\n\treturn FeatureFlagKeyKey.String(val)\n}\n\n// FeatureFlagProviderName returns an attribute KeyValue conforming to the\n// \"feature_flag.provider_name\" semantic conventions. It represents the name of\n// the service provider that performs the flag evaluation.\nfunc FeatureFlagProviderName(val string) attribute.KeyValue {\n\treturn FeatureFlagProviderNameKey.String(val)\n}\n\n// FeatureFlagVariant returns an attribute KeyValue conforming to the\n// \"feature_flag.variant\" semantic conventions. It represents the sHOULD be a\n// semantic identifier for a value. If one is unavailable, a stringified\n// version of the value can be used.\nfunc FeatureFlagVariant(val string) attribute.KeyValue {\n\treturn FeatureFlagVariantKey.String(val)\n}\n\n// RPC received/sent message.\nconst (\n\t// MessageTypeKey is the attribute Key conforming to the \"message.type\"\n\t// semantic conventions. It represents the whether this is a received or\n\t// sent message.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessageTypeKey = attribute.Key(\"message.type\")\n\n\t// MessageIDKey is the attribute Key conforming to the \"message.id\"\n\t// semantic conventions. It represents the mUST be calculated as two\n\t// different counters starting from `1` one for sent messages and one for\n\t// received message.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Note: This way we guarantee that the values will be consistent between\n\t// different implementations.\n\tMessageIDKey = attribute.Key(\"message.id\")\n\n\t// MessageCompressedSizeKey is the attribute Key conforming to the\n\t// \"message.compressed_size\" semantic conventions. It represents the\n\t// compressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessageCompressedSizeKey = attribute.Key(\"message.compressed_size\")\n\n\t// MessageUncompressedSizeKey is the attribute Key conforming to the\n\t// \"message.uncompressed_size\" semantic conventions. It represents the\n\t// uncompressed size of the message in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessageUncompressedSizeKey = attribute.Key(\"message.uncompressed_size\")\n)\n\nvar (\n\t// sent\n\tMessageTypeSent = MessageTypeKey.String(\"SENT\")\n\t// received\n\tMessageTypeReceived = MessageTypeKey.String(\"RECEIVED\")\n)\n\n// MessageID returns an attribute KeyValue conforming to the \"message.id\"\n// semantic conventions. It represents the mUST be calculated as two different\n// counters starting from `1` one for sent messages and one for received\n// message.\nfunc MessageID(val int) attribute.KeyValue {\n\treturn MessageIDKey.Int(val)\n}\n\n// MessageCompressedSize returns an attribute KeyValue conforming to the\n// \"message.compressed_size\" semantic conventions. It represents the compressed\n// size of the message in bytes.\nfunc MessageCompressedSize(val int) attribute.KeyValue {\n\treturn MessageCompressedSizeKey.Int(val)\n}\n\n// MessageUncompressedSize returns an attribute KeyValue conforming to the\n// \"message.uncompressed_size\" semantic conventions. It represents the\n// uncompressed size of the message in bytes.\nfunc MessageUncompressedSize(val int) attribute.KeyValue {\n\treturn MessageUncompressedSizeKey.Int(val)\n}\n\n// The attributes used to report a single exception associated with a span.\nconst (\n\t// ExceptionEscapedKey is the attribute Key conforming to the\n\t// \"exception.escaped\" semantic conventions. It represents the sHOULD be\n\t// set to true if the exception event is recorded at a point where it is\n\t// known that the exception is escaping the scope of the span.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Note: An exception is considered to have escaped (or left) the scope of\n\t// a span,\n\t// if that span is ended while the exception is still logically \"in\n\t// flight\".\n\t// This may be actually \"in flight\" in some languages (e.g. if the\n\t// exception\n\t// is passed to a Context manager's `__exit__` method in Python) but will\n\t// usually be caught at the point of recording the exception in most\n\t// languages.\n\t//\n\t// It is usually not possible to determine at the point where an exception\n\t// is thrown\n\t// whether it will escape the scope of a span.\n\t// However, it is trivial to know that an exception\n\t// will escape, if one checks for an active exception just before ending\n\t// the span,\n\t// as done in the [example above](#recording-an-exception).\n\t//\n\t// It follows that an exception may still escape the scope of the span\n\t// even if the `exception.escaped` attribute was not set or set to false,\n\t// since the event might have been recorded at a time where it was not\n\t// clear whether the exception will escape.\n\tExceptionEscapedKey = attribute.Key(\"exception.escaped\")\n)\n\n// ExceptionEscaped returns an attribute KeyValue conforming to the\n// \"exception.escaped\" semantic conventions. It represents the sHOULD be set to\n// true if the exception event is recorded at a point where it is known that\n// the exception is escaping the scope of the span.\nfunc ExceptionEscaped(val bool) attribute.KeyValue {\n\treturn ExceptionEscapedKey.Bool(val)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.17.0/exception.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n\nconst (\n\t// ExceptionEventName is the name of the Span event representing an exception.\n\tExceptionEventName = \"exception\"\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.17.0/http.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n\n// HTTP scheme attributes.\nvar (\n\tHTTPSchemeHTTP  = HTTPSchemeKey.String(\"http\")\n\tHTTPSchemeHTTPS = HTTPSchemeKey.String(\"https\")\n)\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.17.0/resource.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n// Code generated from semantic convention specification. DO NOT EDIT.\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// The web browser in which the application represented by the resource is\n// running. The `browser.*` attributes MUST be used only for resources that\n// represent applications running in a web browser (regardless of whether\n// running on a mobile or desktop device).\nconst (\n\t// BrowserBrandsKey is the attribute Key conforming to the \"browser.brands\"\n\t// semantic conventions. It represents the array of brand name and version\n\t// separated by a space\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: ' Not A;Brand 99', 'Chromium 99', 'Chrome 99'\n\t// Note: This value is intended to be taken from the [UA client hints\n\t// API](https://wicg.github.io/ua-client-hints/#interface)\n\t// (`navigator.userAgentData.brands`).\n\tBrowserBrandsKey = attribute.Key(\"browser.brands\")\n\n\t// BrowserPlatformKey is the attribute Key conforming to the\n\t// \"browser.platform\" semantic conventions. It represents the platform on\n\t// which the browser is running\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Windows', 'macOS', 'Android'\n\t// Note: This value is intended to be taken from the [UA client hints\n\t// API](https://wicg.github.io/ua-client-hints/#interface)\n\t// (`navigator.userAgentData.platform`). If unavailable, the legacy\n\t// `navigator.platform` API SHOULD NOT be used instead and this attribute\n\t// SHOULD be left unset in order for the values to be consistent.\n\t// The list of possible values is defined in the [W3C User-Agent Client\n\t// Hints\n\t// specification](https://wicg.github.io/ua-client-hints/#sec-ch-ua-platform).\n\t// Note that some (but not all) of these values can overlap with values in\n\t// the [`os.type` and `os.name` attributes](./os.md). However, for\n\t// consistency, the values in the `browser.platform` attribute should\n\t// capture the exact value that the user agent provides.\n\tBrowserPlatformKey = attribute.Key(\"browser.platform\")\n\n\t// BrowserMobileKey is the attribute Key conforming to the \"browser.mobile\"\n\t// semantic conventions. It represents a boolean that is true if the\n\t// browser is running on a mobile device\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Note: This value is intended to be taken from the [UA client hints\n\t// API](https://wicg.github.io/ua-client-hints/#interface)\n\t// (`navigator.userAgentData.mobile`). If unavailable, this attribute\n\t// SHOULD be left unset.\n\tBrowserMobileKey = attribute.Key(\"browser.mobile\")\n\n\t// BrowserUserAgentKey is the attribute Key conforming to the\n\t// \"browser.user_agent\" semantic conventions. It represents the full\n\t// user-agent string provided by the browser\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)\n\t// AppleWebKit/537.36 (KHTML, '\n\t//  'like Gecko) Chrome/95.0.4638.54 Safari/537.36'\n\t// Note: The user-agent value SHOULD be provided only from browsers that do\n\t// not have a mechanism to retrieve brands and platform individually from\n\t// the User-Agent Client Hints API. To retrieve the value, the legacy\n\t// `navigator.userAgent` API can be used.\n\tBrowserUserAgentKey = attribute.Key(\"browser.user_agent\")\n\n\t// BrowserLanguageKey is the attribute Key conforming to the\n\t// \"browser.language\" semantic conventions. It represents the preferred\n\t// language of the user using the browser\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'en', 'en-US', 'fr', 'fr-FR'\n\t// Note: This value is intended to be taken from the Navigator API\n\t// `navigator.language`.\n\tBrowserLanguageKey = attribute.Key(\"browser.language\")\n)\n\n// BrowserBrands returns an attribute KeyValue conforming to the\n// \"browser.brands\" semantic conventions. It represents the array of brand name\n// and version separated by a space\nfunc BrowserBrands(val ...string) attribute.KeyValue {\n\treturn BrowserBrandsKey.StringSlice(val)\n}\n\n// BrowserPlatform returns an attribute KeyValue conforming to the\n// \"browser.platform\" semantic conventions. It represents the platform on which\n// the browser is running\nfunc BrowserPlatform(val string) attribute.KeyValue {\n\treturn BrowserPlatformKey.String(val)\n}\n\n// BrowserMobile returns an attribute KeyValue conforming to the\n// \"browser.mobile\" semantic conventions. It represents a boolean that is true\n// if the browser is running on a mobile device\nfunc BrowserMobile(val bool) attribute.KeyValue {\n\treturn BrowserMobileKey.Bool(val)\n}\n\n// BrowserUserAgent returns an attribute KeyValue conforming to the\n// \"browser.user_agent\" semantic conventions. It represents the full user-agent\n// string provided by the browser\nfunc BrowserUserAgent(val string) attribute.KeyValue {\n\treturn BrowserUserAgentKey.String(val)\n}\n\n// BrowserLanguage returns an attribute KeyValue conforming to the\n// \"browser.language\" semantic conventions. It represents the preferred\n// language of the user using the browser\nfunc BrowserLanguage(val string) attribute.KeyValue {\n\treturn BrowserLanguageKey.String(val)\n}\n\n// A cloud environment (e.g. GCP, Azure, AWS)\nconst (\n\t// CloudProviderKey is the attribute Key conforming to the \"cloud.provider\"\n\t// semantic conventions. It represents the name of the cloud provider.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tCloudProviderKey = attribute.Key(\"cloud.provider\")\n\n\t// CloudAccountIDKey is the attribute Key conforming to the\n\t// \"cloud.account.id\" semantic conventions. It represents the cloud account\n\t// ID the resource is assigned to.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '111111111111', 'opentelemetry'\n\tCloudAccountIDKey = attribute.Key(\"cloud.account.id\")\n\n\t// CloudRegionKey is the attribute Key conforming to the \"cloud.region\"\n\t// semantic conventions. It represents the geographical region the resource\n\t// is running.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'us-central1', 'us-east-1'\n\t// Note: Refer to your provider's docs to see the available regions, for\n\t// example [Alibaba Cloud\n\t// regions](https://www.alibabacloud.com/help/doc-detail/40654.htm), [AWS\n\t// regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/),\n\t// [Azure\n\t// regions](https://azure.microsoft.com/en-us/global-infrastructure/geographies/),\n\t// [Google Cloud regions](https://cloud.google.com/about/locations), or\n\t// [Tencent Cloud\n\t// regions](https://intl.cloud.tencent.com/document/product/213/6091).\n\tCloudRegionKey = attribute.Key(\"cloud.region\")\n\n\t// CloudAvailabilityZoneKey is the attribute Key conforming to the\n\t// \"cloud.availability_zone\" semantic conventions. It represents the cloud\n\t// regions often have multiple, isolated locations known as zones to\n\t// increase availability. Availability zone represents the zone where the\n\t// resource is running.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'us-east-1c'\n\t// Note: Availability zones are called \"zones\" on Alibaba Cloud and Google\n\t// Cloud.\n\tCloudAvailabilityZoneKey = attribute.Key(\"cloud.availability_zone\")\n\n\t// CloudPlatformKey is the attribute Key conforming to the \"cloud.platform\"\n\t// semantic conventions. It represents the cloud platform in use.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Note: The prefix of the service SHOULD match the one specified in\n\t// `cloud.provider`.\n\tCloudPlatformKey = attribute.Key(\"cloud.platform\")\n)\n\nvar (\n\t// Alibaba Cloud\n\tCloudProviderAlibabaCloud = CloudProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\tCloudProviderAWS = CloudProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\tCloudProviderAzure = CloudProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\tCloudProviderGCP = CloudProviderKey.String(\"gcp\")\n\t// IBM Cloud\n\tCloudProviderIbmCloud = CloudProviderKey.String(\"ibm_cloud\")\n\t// Tencent Cloud\n\tCloudProviderTencentCloud = CloudProviderKey.String(\"tencent_cloud\")\n)\n\nvar (\n\t// Alibaba Cloud Elastic Compute Service\n\tCloudPlatformAlibabaCloudECS = CloudPlatformKey.String(\"alibaba_cloud_ecs\")\n\t// Alibaba Cloud Function Compute\n\tCloudPlatformAlibabaCloudFc = CloudPlatformKey.String(\"alibaba_cloud_fc\")\n\t// Red Hat OpenShift on Alibaba Cloud\n\tCloudPlatformAlibabaCloudOpenshift = CloudPlatformKey.String(\"alibaba_cloud_openshift\")\n\t// AWS Elastic Compute Cloud\n\tCloudPlatformAWSEC2 = CloudPlatformKey.String(\"aws_ec2\")\n\t// AWS Elastic Container Service\n\tCloudPlatformAWSECS = CloudPlatformKey.String(\"aws_ecs\")\n\t// AWS Elastic Kubernetes Service\n\tCloudPlatformAWSEKS = CloudPlatformKey.String(\"aws_eks\")\n\t// AWS Lambda\n\tCloudPlatformAWSLambda = CloudPlatformKey.String(\"aws_lambda\")\n\t// AWS Elastic Beanstalk\n\tCloudPlatformAWSElasticBeanstalk = CloudPlatformKey.String(\"aws_elastic_beanstalk\")\n\t// AWS App Runner\n\tCloudPlatformAWSAppRunner = CloudPlatformKey.String(\"aws_app_runner\")\n\t// Red Hat OpenShift on AWS (ROSA)\n\tCloudPlatformAWSOpenshift = CloudPlatformKey.String(\"aws_openshift\")\n\t// Azure Virtual Machines\n\tCloudPlatformAzureVM = CloudPlatformKey.String(\"azure_vm\")\n\t// Azure Container Instances\n\tCloudPlatformAzureContainerInstances = CloudPlatformKey.String(\"azure_container_instances\")\n\t// Azure Kubernetes Service\n\tCloudPlatformAzureAKS = CloudPlatformKey.String(\"azure_aks\")\n\t// Azure Functions\n\tCloudPlatformAzureFunctions = CloudPlatformKey.String(\"azure_functions\")\n\t// Azure App Service\n\tCloudPlatformAzureAppService = CloudPlatformKey.String(\"azure_app_service\")\n\t// Azure Red Hat OpenShift\n\tCloudPlatformAzureOpenshift = CloudPlatformKey.String(\"azure_openshift\")\n\t// Google Cloud Compute Engine (GCE)\n\tCloudPlatformGCPComputeEngine = CloudPlatformKey.String(\"gcp_compute_engine\")\n\t// Google Cloud Run\n\tCloudPlatformGCPCloudRun = CloudPlatformKey.String(\"gcp_cloud_run\")\n\t// Google Cloud Kubernetes Engine (GKE)\n\tCloudPlatformGCPKubernetesEngine = CloudPlatformKey.String(\"gcp_kubernetes_engine\")\n\t// Google Cloud Functions (GCF)\n\tCloudPlatformGCPCloudFunctions = CloudPlatformKey.String(\"gcp_cloud_functions\")\n\t// Google Cloud App Engine (GAE)\n\tCloudPlatformGCPAppEngine = CloudPlatformKey.String(\"gcp_app_engine\")\n\t// Red Hat OpenShift on Google Cloud\n\tCloudPlatformGoogleCloudOpenshift = CloudPlatformKey.String(\"google_cloud_openshift\")\n\t// Red Hat OpenShift on IBM Cloud\n\tCloudPlatformIbmCloudOpenshift = CloudPlatformKey.String(\"ibm_cloud_openshift\")\n\t// Tencent Cloud Cloud Virtual Machine (CVM)\n\tCloudPlatformTencentCloudCvm = CloudPlatformKey.String(\"tencent_cloud_cvm\")\n\t// Tencent Cloud Elastic Kubernetes Service (EKS)\n\tCloudPlatformTencentCloudEKS = CloudPlatformKey.String(\"tencent_cloud_eks\")\n\t// Tencent Cloud Serverless Cloud Function (SCF)\n\tCloudPlatformTencentCloudScf = CloudPlatformKey.String(\"tencent_cloud_scf\")\n)\n\n// CloudAccountID returns an attribute KeyValue conforming to the\n// \"cloud.account.id\" semantic conventions. It represents the cloud account ID\n// the resource is assigned to.\nfunc CloudAccountID(val string) attribute.KeyValue {\n\treturn CloudAccountIDKey.String(val)\n}\n\n// CloudRegion returns an attribute KeyValue conforming to the\n// \"cloud.region\" semantic conventions. It represents the geographical region\n// the resource is running.\nfunc CloudRegion(val string) attribute.KeyValue {\n\treturn CloudRegionKey.String(val)\n}\n\n// CloudAvailabilityZone returns an attribute KeyValue conforming to the\n// \"cloud.availability_zone\" semantic conventions. It represents the cloud\n// regions often have multiple, isolated locations known as zones to increase\n// availability. Availability zone represents the zone where the resource is\n// running.\nfunc CloudAvailabilityZone(val string) attribute.KeyValue {\n\treturn CloudAvailabilityZoneKey.String(val)\n}\n\n// Resources used by AWS Elastic Container Service (ECS).\nconst (\n\t// AWSECSContainerARNKey is the attribute Key conforming to the\n\t// \"aws.ecs.container.arn\" semantic conventions. It represents the Amazon\n\t// Resource Name (ARN) of an [ECS container\n\t// instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples:\n\t// 'arn:aws:ecs:us-west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'\n\tAWSECSContainerARNKey = attribute.Key(\"aws.ecs.container.arn\")\n\n\t// AWSECSClusterARNKey is the attribute Key conforming to the\n\t// \"aws.ecs.cluster.arn\" semantic conventions. It represents the ARN of an\n\t// [ECS\n\t// cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'\n\tAWSECSClusterARNKey = attribute.Key(\"aws.ecs.cluster.arn\")\n\n\t// AWSECSLaunchtypeKey is the attribute Key conforming to the\n\t// \"aws.ecs.launchtype\" semantic conventions. It represents the [launch\n\t// type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html)\n\t// for an ECS task.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tAWSECSLaunchtypeKey = attribute.Key(\"aws.ecs.launchtype\")\n\n\t// AWSECSTaskARNKey is the attribute Key conforming to the\n\t// \"aws.ecs.task.arn\" semantic conventions. It represents the ARN of an\n\t// [ECS task\n\t// definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples:\n\t// 'arn:aws:ecs:us-west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'\n\tAWSECSTaskARNKey = attribute.Key(\"aws.ecs.task.arn\")\n\n\t// AWSECSTaskFamilyKey is the attribute Key conforming to the\n\t// \"aws.ecs.task.family\" semantic conventions. It represents the task\n\t// definition family this task definition is a member of.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry-family'\n\tAWSECSTaskFamilyKey = attribute.Key(\"aws.ecs.task.family\")\n\n\t// AWSECSTaskRevisionKey is the attribute Key conforming to the\n\t// \"aws.ecs.task.revision\" semantic conventions. It represents the revision\n\t// for this task definition.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '8', '26'\n\tAWSECSTaskRevisionKey = attribute.Key(\"aws.ecs.task.revision\")\n)\n\nvar (\n\t// ec2\n\tAWSECSLaunchtypeEC2 = AWSECSLaunchtypeKey.String(\"ec2\")\n\t// fargate\n\tAWSECSLaunchtypeFargate = AWSECSLaunchtypeKey.String(\"fargate\")\n)\n\n// AWSECSContainerARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.container.arn\" semantic conventions. It represents the Amazon\n// Resource Name (ARN) of an [ECS container\n// instance](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ECS_instances.html).\nfunc AWSECSContainerARN(val string) attribute.KeyValue {\n\treturn AWSECSContainerARNKey.String(val)\n}\n\n// AWSECSClusterARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.cluster.arn\" semantic conventions. It represents the ARN of an [ECS\n// cluster](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/clusters.html).\nfunc AWSECSClusterARN(val string) attribute.KeyValue {\n\treturn AWSECSClusterARNKey.String(val)\n}\n\n// AWSECSTaskARN returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.arn\" semantic conventions. It represents the ARN of an [ECS\n// task\n// definition](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definitions.html).\nfunc AWSECSTaskARN(val string) attribute.KeyValue {\n\treturn AWSECSTaskARNKey.String(val)\n}\n\n// AWSECSTaskFamily returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.family\" semantic conventions. It represents the task\n// definition family this task definition is a member of.\nfunc AWSECSTaskFamily(val string) attribute.KeyValue {\n\treturn AWSECSTaskFamilyKey.String(val)\n}\n\n// AWSECSTaskRevision returns an attribute KeyValue conforming to the\n// \"aws.ecs.task.revision\" semantic conventions. It represents the revision for\n// this task definition.\nfunc AWSECSTaskRevision(val string) attribute.KeyValue {\n\treturn AWSECSTaskRevisionKey.String(val)\n}\n\n// Resources used by AWS Elastic Kubernetes Service (EKS).\nconst (\n\t// AWSEKSClusterARNKey is the attribute Key conforming to the\n\t// \"aws.eks.cluster.arn\" semantic conventions. It represents the ARN of an\n\t// EKS cluster.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'\n\tAWSEKSClusterARNKey = attribute.Key(\"aws.eks.cluster.arn\")\n)\n\n// AWSEKSClusterARN returns an attribute KeyValue conforming to the\n// \"aws.eks.cluster.arn\" semantic conventions. It represents the ARN of an EKS\n// cluster.\nfunc AWSEKSClusterARN(val string) attribute.KeyValue {\n\treturn AWSEKSClusterARNKey.String(val)\n}\n\n// Resources specific to Amazon Web Services.\nconst (\n\t// AWSLogGroupNamesKey is the attribute Key conforming to the\n\t// \"aws.log.group.names\" semantic conventions. It represents the name(s) of\n\t// the AWS log group(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '/aws/lambda/my-function', 'opentelemetry-service'\n\t// Note: Multiple log groups must be supported for cases like\n\t// multi-container applications, where a single application has sidecar\n\t// containers, and each write to their own log group.\n\tAWSLogGroupNamesKey = attribute.Key(\"aws.log.group.names\")\n\n\t// AWSLogGroupARNsKey is the attribute Key conforming to the\n\t// \"aws.log.group.arns\" semantic conventions. It represents the Amazon\n\t// Resource Name(s) (ARN) of the AWS log group(s).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples:\n\t// 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'\n\t// Note: See the [log group ARN format\n\t// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format).\n\tAWSLogGroupARNsKey = attribute.Key(\"aws.log.group.arns\")\n\n\t// AWSLogStreamNamesKey is the attribute Key conforming to the\n\t// \"aws.log.stream.names\" semantic conventions. It represents the name(s)\n\t// of the AWS log stream(s) an application is writing to.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'\n\tAWSLogStreamNamesKey = attribute.Key(\"aws.log.stream.names\")\n\n\t// AWSLogStreamARNsKey is the attribute Key conforming to the\n\t// \"aws.log.stream.arns\" semantic conventions. It represents the ARN(s) of\n\t// the AWS log stream(s).\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples:\n\t// 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'\n\t// Note: See the [log stream ARN format\n\t// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-access-control-overview-cwl.html#CWL_ARN_Format).\n\t// One log group can contain several log streams, so these ARNs necessarily\n\t// identify both a log group and a log stream.\n\tAWSLogStreamARNsKey = attribute.Key(\"aws.log.stream.arns\")\n)\n\n// AWSLogGroupNames returns an attribute KeyValue conforming to the\n// \"aws.log.group.names\" semantic conventions. It represents the name(s) of the\n// AWS log group(s) an application is writing to.\nfunc AWSLogGroupNames(val ...string) attribute.KeyValue {\n\treturn AWSLogGroupNamesKey.StringSlice(val)\n}\n\n// AWSLogGroupARNs returns an attribute KeyValue conforming to the\n// \"aws.log.group.arns\" semantic conventions. It represents the Amazon Resource\n// Name(s) (ARN) of the AWS log group(s).\nfunc AWSLogGroupARNs(val ...string) attribute.KeyValue {\n\treturn AWSLogGroupARNsKey.StringSlice(val)\n}\n\n// AWSLogStreamNames returns an attribute KeyValue conforming to the\n// \"aws.log.stream.names\" semantic conventions. It represents the name(s) of\n// the AWS log stream(s) an application is writing to.\nfunc AWSLogStreamNames(val ...string) attribute.KeyValue {\n\treturn AWSLogStreamNamesKey.StringSlice(val)\n}\n\n// AWSLogStreamARNs returns an attribute KeyValue conforming to the\n// \"aws.log.stream.arns\" semantic conventions. It represents the ARN(s) of the\n// AWS log stream(s).\nfunc AWSLogStreamARNs(val ...string) attribute.KeyValue {\n\treturn AWSLogStreamARNsKey.StringSlice(val)\n}\n\n// A container instance.\nconst (\n\t// ContainerNameKey is the attribute Key conforming to the \"container.name\"\n\t// semantic conventions. It represents the container name used by container\n\t// runtime.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry-autoconf'\n\tContainerNameKey = attribute.Key(\"container.name\")\n\n\t// ContainerIDKey is the attribute Key conforming to the \"container.id\"\n\t// semantic conventions. It represents the container ID. Usually a UUID, as\n\t// for example used to [identify Docker\n\t// containers](https://docs.docker.com/engine/reference/run/#container-identification).\n\t// The UUID might be abbreviated.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'a3bf90e006b2'\n\tContainerIDKey = attribute.Key(\"container.id\")\n\n\t// ContainerRuntimeKey is the attribute Key conforming to the\n\t// \"container.runtime\" semantic conventions. It represents the container\n\t// runtime managing this container.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'docker', 'containerd', 'rkt'\n\tContainerRuntimeKey = attribute.Key(\"container.runtime\")\n\n\t// ContainerImageNameKey is the attribute Key conforming to the\n\t// \"container.image.name\" semantic conventions. It represents the name of\n\t// the image the container was built on.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'gcr.io/opentelemetry/operator'\n\tContainerImageNameKey = attribute.Key(\"container.image.name\")\n\n\t// ContainerImageTagKey is the attribute Key conforming to the\n\t// \"container.image.tag\" semantic conventions. It represents the container\n\t// image tag.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '0.1'\n\tContainerImageTagKey = attribute.Key(\"container.image.tag\")\n)\n\n// ContainerName returns an attribute KeyValue conforming to the\n// \"container.name\" semantic conventions. It represents the container name used\n// by container runtime.\nfunc ContainerName(val string) attribute.KeyValue {\n\treturn ContainerNameKey.String(val)\n}\n\n// ContainerID returns an attribute KeyValue conforming to the\n// \"container.id\" semantic conventions. It represents the container ID. Usually\n// a UUID, as for example used to [identify Docker\n// containers](https://docs.docker.com/engine/reference/run/#container-identification).\n// The UUID might be abbreviated.\nfunc ContainerID(val string) attribute.KeyValue {\n\treturn ContainerIDKey.String(val)\n}\n\n// ContainerRuntime returns an attribute KeyValue conforming to the\n// \"container.runtime\" semantic conventions. It represents the container\n// runtime managing this container.\nfunc ContainerRuntime(val string) attribute.KeyValue {\n\treturn ContainerRuntimeKey.String(val)\n}\n\n// ContainerImageName returns an attribute KeyValue conforming to the\n// \"container.image.name\" semantic conventions. It represents the name of the\n// image the container was built on.\nfunc ContainerImageName(val string) attribute.KeyValue {\n\treturn ContainerImageNameKey.String(val)\n}\n\n// ContainerImageTag returns an attribute KeyValue conforming to the\n// \"container.image.tag\" semantic conventions. It represents the container\n// image tag.\nfunc ContainerImageTag(val string) attribute.KeyValue {\n\treturn ContainerImageTagKey.String(val)\n}\n\n// The software deployment.\nconst (\n\t// DeploymentEnvironmentKey is the attribute Key conforming to the\n\t// \"deployment.environment\" semantic conventions. It represents the name of\n\t// the [deployment\n\t// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka\n\t// deployment tier).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'staging', 'production'\n\tDeploymentEnvironmentKey = attribute.Key(\"deployment.environment\")\n)\n\n// DeploymentEnvironment returns an attribute KeyValue conforming to the\n// \"deployment.environment\" semantic conventions. It represents the name of the\n// [deployment\n// environment](https://en.wikipedia.org/wiki/Deployment_environment) (aka\n// deployment tier).\nfunc DeploymentEnvironment(val string) attribute.KeyValue {\n\treturn DeploymentEnvironmentKey.String(val)\n}\n\n// The device on which the process represented by this resource is running.\nconst (\n\t// DeviceIDKey is the attribute Key conforming to the \"device.id\" semantic\n\t// conventions. It represents a unique identifier representing the device\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092'\n\t// Note: The device identifier MUST only be defined using the values\n\t// outlined below. This value is not an advertising identifier and MUST NOT\n\t// be used as such. On iOS (Swift or Objective-C), this value MUST be equal\n\t// to the [vendor\n\t// identifier](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor).\n\t// On Android (Java or Kotlin), this value MUST be equal to the Firebase\n\t// Installation ID or a globally unique UUID which is persisted across\n\t// sessions in your application. More information can be found\n\t// [here](https://developer.android.com/training/articles/user-data-ids) on\n\t// best practices and exact implementation details. Caution should be taken\n\t// when storing personal data or anything which can identify a user. GDPR\n\t// and data protection laws may apply, ensure you do your own due\n\t// diligence.\n\tDeviceIDKey = attribute.Key(\"device.id\")\n\n\t// DeviceModelIdentifierKey is the attribute Key conforming to the\n\t// \"device.model.identifier\" semantic conventions. It represents the model\n\t// identifier for the device\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'iPhone3,4', 'SM-G920F'\n\t// Note: It's recommended this value represents a machine readable version\n\t// of the model identifier rather than the market or consumer-friendly name\n\t// of the device.\n\tDeviceModelIdentifierKey = attribute.Key(\"device.model.identifier\")\n\n\t// DeviceModelNameKey is the attribute Key conforming to the\n\t// \"device.model.name\" semantic conventions. It represents the marketing\n\t// name for the device model\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6'\n\t// Note: It's recommended this value represents a human readable version of\n\t// the device model rather than a machine readable alternative.\n\tDeviceModelNameKey = attribute.Key(\"device.model.name\")\n\n\t// DeviceManufacturerKey is the attribute Key conforming to the\n\t// \"device.manufacturer\" semantic conventions. It represents the name of\n\t// the device manufacturer\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Apple', 'Samsung'\n\t// Note: The Android OS provides this field via\n\t// [Build](https://developer.android.com/reference/android/os/Build#MANUFACTURER).\n\t// iOS apps SHOULD hardcode the value `Apple`.\n\tDeviceManufacturerKey = attribute.Key(\"device.manufacturer\")\n)\n\n// DeviceID returns an attribute KeyValue conforming to the \"device.id\"\n// semantic conventions. It represents a unique identifier representing the\n// device\nfunc DeviceID(val string) attribute.KeyValue {\n\treturn DeviceIDKey.String(val)\n}\n\n// DeviceModelIdentifier returns an attribute KeyValue conforming to the\n// \"device.model.identifier\" semantic conventions. It represents the model\n// identifier for the device\nfunc DeviceModelIdentifier(val string) attribute.KeyValue {\n\treturn DeviceModelIdentifierKey.String(val)\n}\n\n// DeviceModelName returns an attribute KeyValue conforming to the\n// \"device.model.name\" semantic conventions. It represents the marketing name\n// for the device model\nfunc DeviceModelName(val string) attribute.KeyValue {\n\treturn DeviceModelNameKey.String(val)\n}\n\n// DeviceManufacturer returns an attribute KeyValue conforming to the\n// \"device.manufacturer\" semantic conventions. It represents the name of the\n// device manufacturer\nfunc DeviceManufacturer(val string) attribute.KeyValue {\n\treturn DeviceManufacturerKey.String(val)\n}\n\n// A serverless instance.\nconst (\n\t// FaaSNameKey is the attribute Key conforming to the \"faas.name\" semantic\n\t// conventions. It represents the name of the single function that this\n\t// runtime instance executes.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'my-function', 'myazurefunctionapp/some-function-name'\n\t// Note: This is the name of the function as configured/deployed on the\n\t// FaaS\n\t// platform and is usually different from the name of the callback\n\t// function (which may be stored in the\n\t// [`code.namespace`/`code.function`](../../trace/semantic_conventions/span-general.md#source-code-attributes)\n\t// span attributes).\n\t//\n\t// For some cloud providers, the above definition is ambiguous. The\n\t// following\n\t// definition of function name MUST be used for this attribute\n\t// (and consequently the span name) for the listed cloud\n\t// providers/products:\n\t//\n\t// * **Azure:**  The full name `<FUNCAPP>/<FUNC>`, i.e., function app name\n\t//   followed by a forward slash followed by the function name (this form\n\t//   can also be seen in the resource JSON for the function).\n\t//   This means that a span attribute MUST be used, as an Azure function\n\t//   app can host multiple functions that would usually share\n\t//   a TracerProvider (see also the `faas.id` attribute).\n\tFaaSNameKey = attribute.Key(\"faas.name\")\n\n\t// FaaSIDKey is the attribute Key conforming to the \"faas.id\" semantic\n\t// conventions. It represents the unique ID of the single function that\n\t// this runtime instance executes.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function'\n\t// Note: On some cloud providers, it may not be possible to determine the\n\t// full ID at startup,\n\t// so consider setting `faas.id` as a span attribute instead.\n\t//\n\t// The exact value to use for `faas.id` depends on the cloud provider:\n\t//\n\t// * **AWS Lambda:** The function\n\t// [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html).\n\t//   Take care not to use the \"invoked ARN\" directly but replace any\n\t//   [alias\n\t// suffix](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html)\n\t//   with the resolved function version, as the same runtime instance may\n\t// be invokable with\n\t//   multiple different aliases.\n\t// * **GCP:** The [URI of the\n\t// resource](https://cloud.google.com/iam/docs/full-resource-names)\n\t// * **Azure:** The [Fully Qualified Resource\n\t// ID](https://docs.microsoft.com/en-us/rest/api/resources/resources/get-by-id)\n\t// of the invoked function,\n\t//   *not* the function app, having the form\n\t// `/subscriptions/<SUBSCIPTION_GUID>/resourceGroups/<RG>/providers/Microsoft.Web/sites/<FUNCAPP>/functions/<FUNC>`.\n\t//   This means that a span attribute MUST be used, as an Azure function\n\t// app can host multiple functions that would usually share\n\t//   a TracerProvider.\n\tFaaSIDKey = attribute.Key(\"faas.id\")\n\n\t// FaaSVersionKey is the attribute Key conforming to the \"faas.version\"\n\t// semantic conventions. It represents the immutable version of the\n\t// function being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '26', 'pinkfroid-00002'\n\t// Note: Depending on the cloud provider and platform, use:\n\t//\n\t// * **AWS Lambda:** The [function\n\t// version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html)\n\t//   (an integer represented as a decimal string).\n\t// * **Google Cloud Run:** The\n\t// [revision](https://cloud.google.com/run/docs/managing/revisions)\n\t//   (i.e., the function name plus the revision suffix).\n\t// * **Google Cloud Functions:** The value of the\n\t//   [`K_REVISION` environment\n\t// variable](https://cloud.google.com/functions/docs/env-var#runtime_environment_variables_set_automatically).\n\t// * **Azure Functions:** Not applicable. Do not set this attribute.\n\tFaaSVersionKey = attribute.Key(\"faas.version\")\n\n\t// FaaSInstanceKey is the attribute Key conforming to the \"faas.instance\"\n\t// semantic conventions. It represents the execution environment ID as a\n\t// string, that will be potentially reused for other invocations to the\n\t// same function/function version.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de'\n\t// Note: * **AWS Lambda:** Use the (full) log stream name.\n\tFaaSInstanceKey = attribute.Key(\"faas.instance\")\n\n\t// FaaSMaxMemoryKey is the attribute Key conforming to the\n\t// \"faas.max_memory\" semantic conventions. It represents the amount of\n\t// memory available to the serverless function in MiB.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 128\n\t// Note: It's recommended to set this attribute since e.g. too little\n\t// memory can easily stop a Java AWS Lambda function from working\n\t// correctly. On AWS Lambda, the environment variable\n\t// `AWS_LAMBDA_FUNCTION_MEMORY_SIZE` provides this information.\n\tFaaSMaxMemoryKey = attribute.Key(\"faas.max_memory\")\n)\n\n// FaaSName returns an attribute KeyValue conforming to the \"faas.name\"\n// semantic conventions. It represents the name of the single function that\n// this runtime instance executes.\nfunc FaaSName(val string) attribute.KeyValue {\n\treturn FaaSNameKey.String(val)\n}\n\n// FaaSID returns an attribute KeyValue conforming to the \"faas.id\" semantic\n// conventions. It represents the unique ID of the single function that this\n// runtime instance executes.\nfunc FaaSID(val string) attribute.KeyValue {\n\treturn FaaSIDKey.String(val)\n}\n\n// FaaSVersion returns an attribute KeyValue conforming to the\n// \"faas.version\" semantic conventions. It represents the immutable version of\n// the function being executed.\nfunc FaaSVersion(val string) attribute.KeyValue {\n\treturn FaaSVersionKey.String(val)\n}\n\n// FaaSInstance returns an attribute KeyValue conforming to the\n// \"faas.instance\" semantic conventions. It represents the execution\n// environment ID as a string, that will be potentially reused for other\n// invocations to the same function/function version.\nfunc FaaSInstance(val string) attribute.KeyValue {\n\treturn FaaSInstanceKey.String(val)\n}\n\n// FaaSMaxMemory returns an attribute KeyValue conforming to the\n// \"faas.max_memory\" semantic conventions. It represents the amount of memory\n// available to the serverless function in MiB.\nfunc FaaSMaxMemory(val int) attribute.KeyValue {\n\treturn FaaSMaxMemoryKey.Int(val)\n}\n\n// A host is defined as a general computing instance.\nconst (\n\t// HostIDKey is the attribute Key conforming to the \"host.id\" semantic\n\t// conventions. It represents the unique host ID. For Cloud, this must be\n\t// the instance_id assigned by the cloud provider. For non-containerized\n\t// Linux systems, the `machine-id` located in `/etc/machine-id` or\n\t// `/var/lib/dbus/machine-id` may be used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'fdbf79e8af94cb7f9e8df36789187052'\n\tHostIDKey = attribute.Key(\"host.id\")\n\n\t// HostNameKey is the attribute Key conforming to the \"host.name\" semantic\n\t// conventions. It represents the name of the host. On Unix systems, it may\n\t// contain what the hostname command returns, or the fully qualified\n\t// hostname, or another name specified by the user.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry-test'\n\tHostNameKey = attribute.Key(\"host.name\")\n\n\t// HostTypeKey is the attribute Key conforming to the \"host.type\" semantic\n\t// conventions. It represents the type of host. For Cloud, this must be the\n\t// machine type.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'n1-standard-1'\n\tHostTypeKey = attribute.Key(\"host.type\")\n\n\t// HostArchKey is the attribute Key conforming to the \"host.arch\" semantic\n\t// conventions. It represents the CPU architecture the host system is\n\t// running on.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tHostArchKey = attribute.Key(\"host.arch\")\n\n\t// HostImageNameKey is the attribute Key conforming to the\n\t// \"host.image.name\" semantic conventions. It represents the name of the VM\n\t// image or OS install the host was instantiated from.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'\n\tHostImageNameKey = attribute.Key(\"host.image.name\")\n\n\t// HostImageIDKey is the attribute Key conforming to the \"host.image.id\"\n\t// semantic conventions. It represents the vM image ID. For Cloud, this\n\t// value is from the provider.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'ami-07b06b442921831e5'\n\tHostImageIDKey = attribute.Key(\"host.image.id\")\n\n\t// HostImageVersionKey is the attribute Key conforming to the\n\t// \"host.image.version\" semantic conventions. It represents the version\n\t// string of the VM image as defined in [Version\n\t// Attributes](README.md#version-attributes).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '0.1'\n\tHostImageVersionKey = attribute.Key(\"host.image.version\")\n)\n\nvar (\n\t// AMD64\n\tHostArchAMD64 = HostArchKey.String(\"amd64\")\n\t// ARM32\n\tHostArchARM32 = HostArchKey.String(\"arm32\")\n\t// ARM64\n\tHostArchARM64 = HostArchKey.String(\"arm64\")\n\t// Itanium\n\tHostArchIA64 = HostArchKey.String(\"ia64\")\n\t// 32-bit PowerPC\n\tHostArchPPC32 = HostArchKey.String(\"ppc32\")\n\t// 64-bit PowerPC\n\tHostArchPPC64 = HostArchKey.String(\"ppc64\")\n\t// IBM z/Architecture\n\tHostArchS390x = HostArchKey.String(\"s390x\")\n\t// 32-bit x86\n\tHostArchX86 = HostArchKey.String(\"x86\")\n)\n\n// HostID returns an attribute KeyValue conforming to the \"host.id\" semantic\n// conventions. It represents the unique host ID. For Cloud, this must be the\n// instance_id assigned by the cloud provider. For non-containerized Linux\n// systems, the `machine-id` located in `/etc/machine-id` or\n// `/var/lib/dbus/machine-id` may be used.\nfunc HostID(val string) attribute.KeyValue {\n\treturn HostIDKey.String(val)\n}\n\n// HostName returns an attribute KeyValue conforming to the \"host.name\"\n// semantic conventions. It represents the name of the host. On Unix systems,\n// it may contain what the hostname command returns, or the fully qualified\n// hostname, or another name specified by the user.\nfunc HostName(val string) attribute.KeyValue {\n\treturn HostNameKey.String(val)\n}\n\n// HostType returns an attribute KeyValue conforming to the \"host.type\"\n// semantic conventions. It represents the type of host. For Cloud, this must\n// be the machine type.\nfunc HostType(val string) attribute.KeyValue {\n\treturn HostTypeKey.String(val)\n}\n\n// HostImageName returns an attribute KeyValue conforming to the\n// \"host.image.name\" semantic conventions. It represents the name of the VM\n// image or OS install the host was instantiated from.\nfunc HostImageName(val string) attribute.KeyValue {\n\treturn HostImageNameKey.String(val)\n}\n\n// HostImageID returns an attribute KeyValue conforming to the\n// \"host.image.id\" semantic conventions. It represents the vM image ID. For\n// Cloud, this value is from the provider.\nfunc HostImageID(val string) attribute.KeyValue {\n\treturn HostImageIDKey.String(val)\n}\n\n// HostImageVersion returns an attribute KeyValue conforming to the\n// \"host.image.version\" semantic conventions. It represents the version string\n// of the VM image as defined in [Version\n// Attributes](README.md#version-attributes).\nfunc HostImageVersion(val string) attribute.KeyValue {\n\treturn HostImageVersionKey.String(val)\n}\n\n// A Kubernetes Cluster.\nconst (\n\t// K8SClusterNameKey is the attribute Key conforming to the\n\t// \"k8s.cluster.name\" semantic conventions. It represents the name of the\n\t// cluster.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry-cluster'\n\tK8SClusterNameKey = attribute.Key(\"k8s.cluster.name\")\n)\n\n// K8SClusterName returns an attribute KeyValue conforming to the\n// \"k8s.cluster.name\" semantic conventions. It represents the name of the\n// cluster.\nfunc K8SClusterName(val string) attribute.KeyValue {\n\treturn K8SClusterNameKey.String(val)\n}\n\n// A Kubernetes Node object.\nconst (\n\t// K8SNodeNameKey is the attribute Key conforming to the \"k8s.node.name\"\n\t// semantic conventions. It represents the name of the Node.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'node-1'\n\tK8SNodeNameKey = attribute.Key(\"k8s.node.name\")\n\n\t// K8SNodeUIDKey is the attribute Key conforming to the \"k8s.node.uid\"\n\t// semantic conventions. It represents the UID of the Node.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'\n\tK8SNodeUIDKey = attribute.Key(\"k8s.node.uid\")\n)\n\n// K8SNodeName returns an attribute KeyValue conforming to the\n// \"k8s.node.name\" semantic conventions. It represents the name of the Node.\nfunc K8SNodeName(val string) attribute.KeyValue {\n\treturn K8SNodeNameKey.String(val)\n}\n\n// K8SNodeUID returns an attribute KeyValue conforming to the \"k8s.node.uid\"\n// semantic conventions. It represents the UID of the Node.\nfunc K8SNodeUID(val string) attribute.KeyValue {\n\treturn K8SNodeUIDKey.String(val)\n}\n\n// A Kubernetes Namespace.\nconst (\n\t// K8SNamespaceNameKey is the attribute Key conforming to the\n\t// \"k8s.namespace.name\" semantic conventions. It represents the name of the\n\t// namespace that the pod is running in.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'default'\n\tK8SNamespaceNameKey = attribute.Key(\"k8s.namespace.name\")\n)\n\n// K8SNamespaceName returns an attribute KeyValue conforming to the\n// \"k8s.namespace.name\" semantic conventions. It represents the name of the\n// namespace that the pod is running in.\nfunc K8SNamespaceName(val string) attribute.KeyValue {\n\treturn K8SNamespaceNameKey.String(val)\n}\n\n// A Kubernetes Pod object.\nconst (\n\t// K8SPodUIDKey is the attribute Key conforming to the \"k8s.pod.uid\"\n\t// semantic conventions. It represents the UID of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SPodUIDKey = attribute.Key(\"k8s.pod.uid\")\n\n\t// K8SPodNameKey is the attribute Key conforming to the \"k8s.pod.name\"\n\t// semantic conventions. It represents the name of the Pod.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry-pod-autoconf'\n\tK8SPodNameKey = attribute.Key(\"k8s.pod.name\")\n)\n\n// K8SPodUID returns an attribute KeyValue conforming to the \"k8s.pod.uid\"\n// semantic conventions. It represents the UID of the Pod.\nfunc K8SPodUID(val string) attribute.KeyValue {\n\treturn K8SPodUIDKey.String(val)\n}\n\n// K8SPodName returns an attribute KeyValue conforming to the \"k8s.pod.name\"\n// semantic conventions. It represents the name of the Pod.\nfunc K8SPodName(val string) attribute.KeyValue {\n\treturn K8SPodNameKey.String(val)\n}\n\n// A container in a\n// [PodTemplate](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates).\nconst (\n\t// K8SContainerNameKey is the attribute Key conforming to the\n\t// \"k8s.container.name\" semantic conventions. It represents the name of the\n\t// Container from Pod specification, must be unique within a Pod. Container\n\t// runtime usually uses different globally unique name (`container.name`).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'redis'\n\tK8SContainerNameKey = attribute.Key(\"k8s.container.name\")\n\n\t// K8SContainerRestartCountKey is the attribute Key conforming to the\n\t// \"k8s.container.restart_count\" semantic conventions. It represents the\n\t// number of times the container was restarted. This attribute can be used\n\t// to identify a particular container (running or stopped) within a\n\t// container spec.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 0, 2\n\tK8SContainerRestartCountKey = attribute.Key(\"k8s.container.restart_count\")\n)\n\n// K8SContainerName returns an attribute KeyValue conforming to the\n// \"k8s.container.name\" semantic conventions. It represents the name of the\n// Container from Pod specification, must be unique within a Pod. Container\n// runtime usually uses different globally unique name (`container.name`).\nfunc K8SContainerName(val string) attribute.KeyValue {\n\treturn K8SContainerNameKey.String(val)\n}\n\n// K8SContainerRestartCount returns an attribute KeyValue conforming to the\n// \"k8s.container.restart_count\" semantic conventions. It represents the number\n// of times the container was restarted. This attribute can be used to identify\n// a particular container (running or stopped) within a container spec.\nfunc K8SContainerRestartCount(val int) attribute.KeyValue {\n\treturn K8SContainerRestartCountKey.Int(val)\n}\n\n// A Kubernetes ReplicaSet object.\nconst (\n\t// K8SReplicaSetUIDKey is the attribute Key conforming to the\n\t// \"k8s.replicaset.uid\" semantic conventions. It represents the UID of the\n\t// ReplicaSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SReplicaSetUIDKey = attribute.Key(\"k8s.replicaset.uid\")\n\n\t// K8SReplicaSetNameKey is the attribute Key conforming to the\n\t// \"k8s.replicaset.name\" semantic conventions. It represents the name of\n\t// the ReplicaSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SReplicaSetNameKey = attribute.Key(\"k8s.replicaset.name\")\n)\n\n// K8SReplicaSetUID returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.uid\" semantic conventions. It represents the UID of the\n// ReplicaSet.\nfunc K8SReplicaSetUID(val string) attribute.KeyValue {\n\treturn K8SReplicaSetUIDKey.String(val)\n}\n\n// K8SReplicaSetName returns an attribute KeyValue conforming to the\n// \"k8s.replicaset.name\" semantic conventions. It represents the name of the\n// ReplicaSet.\nfunc K8SReplicaSetName(val string) attribute.KeyValue {\n\treturn K8SReplicaSetNameKey.String(val)\n}\n\n// A Kubernetes Deployment object.\nconst (\n\t// K8SDeploymentUIDKey is the attribute Key conforming to the\n\t// \"k8s.deployment.uid\" semantic conventions. It represents the UID of the\n\t// Deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SDeploymentUIDKey = attribute.Key(\"k8s.deployment.uid\")\n\n\t// K8SDeploymentNameKey is the attribute Key conforming to the\n\t// \"k8s.deployment.name\" semantic conventions. It represents the name of\n\t// the Deployment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SDeploymentNameKey = attribute.Key(\"k8s.deployment.name\")\n)\n\n// K8SDeploymentUID returns an attribute KeyValue conforming to the\n// \"k8s.deployment.uid\" semantic conventions. It represents the UID of the\n// Deployment.\nfunc K8SDeploymentUID(val string) attribute.KeyValue {\n\treturn K8SDeploymentUIDKey.String(val)\n}\n\n// K8SDeploymentName returns an attribute KeyValue conforming to the\n// \"k8s.deployment.name\" semantic conventions. It represents the name of the\n// Deployment.\nfunc K8SDeploymentName(val string) attribute.KeyValue {\n\treturn K8SDeploymentNameKey.String(val)\n}\n\n// A Kubernetes StatefulSet object.\nconst (\n\t// K8SStatefulSetUIDKey is the attribute Key conforming to the\n\t// \"k8s.statefulset.uid\" semantic conventions. It represents the UID of the\n\t// StatefulSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SStatefulSetUIDKey = attribute.Key(\"k8s.statefulset.uid\")\n\n\t// K8SStatefulSetNameKey is the attribute Key conforming to the\n\t// \"k8s.statefulset.name\" semantic conventions. It represents the name of\n\t// the StatefulSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SStatefulSetNameKey = attribute.Key(\"k8s.statefulset.name\")\n)\n\n// K8SStatefulSetUID returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.uid\" semantic conventions. It represents the UID of the\n// StatefulSet.\nfunc K8SStatefulSetUID(val string) attribute.KeyValue {\n\treturn K8SStatefulSetUIDKey.String(val)\n}\n\n// K8SStatefulSetName returns an attribute KeyValue conforming to the\n// \"k8s.statefulset.name\" semantic conventions. It represents the name of the\n// StatefulSet.\nfunc K8SStatefulSetName(val string) attribute.KeyValue {\n\treturn K8SStatefulSetNameKey.String(val)\n}\n\n// A Kubernetes DaemonSet object.\nconst (\n\t// K8SDaemonSetUIDKey is the attribute Key conforming to the\n\t// \"k8s.daemonset.uid\" semantic conventions. It represents the UID of the\n\t// DaemonSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SDaemonSetUIDKey = attribute.Key(\"k8s.daemonset.uid\")\n\n\t// K8SDaemonSetNameKey is the attribute Key conforming to the\n\t// \"k8s.daemonset.name\" semantic conventions. It represents the name of the\n\t// DaemonSet.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SDaemonSetNameKey = attribute.Key(\"k8s.daemonset.name\")\n)\n\n// K8SDaemonSetUID returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.uid\" semantic conventions. It represents the UID of the\n// DaemonSet.\nfunc K8SDaemonSetUID(val string) attribute.KeyValue {\n\treturn K8SDaemonSetUIDKey.String(val)\n}\n\n// K8SDaemonSetName returns an attribute KeyValue conforming to the\n// \"k8s.daemonset.name\" semantic conventions. It represents the name of the\n// DaemonSet.\nfunc K8SDaemonSetName(val string) attribute.KeyValue {\n\treturn K8SDaemonSetNameKey.String(val)\n}\n\n// A Kubernetes Job object.\nconst (\n\t// K8SJobUIDKey is the attribute Key conforming to the \"k8s.job.uid\"\n\t// semantic conventions. It represents the UID of the Job.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SJobUIDKey = attribute.Key(\"k8s.job.uid\")\n\n\t// K8SJobNameKey is the attribute Key conforming to the \"k8s.job.name\"\n\t// semantic conventions. It represents the name of the Job.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SJobNameKey = attribute.Key(\"k8s.job.name\")\n)\n\n// K8SJobUID returns an attribute KeyValue conforming to the \"k8s.job.uid\"\n// semantic conventions. It represents the UID of the Job.\nfunc K8SJobUID(val string) attribute.KeyValue {\n\treturn K8SJobUIDKey.String(val)\n}\n\n// K8SJobName returns an attribute KeyValue conforming to the \"k8s.job.name\"\n// semantic conventions. It represents the name of the Job.\nfunc K8SJobName(val string) attribute.KeyValue {\n\treturn K8SJobNameKey.String(val)\n}\n\n// A Kubernetes CronJob object.\nconst (\n\t// K8SCronJobUIDKey is the attribute Key conforming to the\n\t// \"k8s.cronjob.uid\" semantic conventions. It represents the UID of the\n\t// CronJob.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'\n\tK8SCronJobUIDKey = attribute.Key(\"k8s.cronjob.uid\")\n\n\t// K8SCronJobNameKey is the attribute Key conforming to the\n\t// \"k8s.cronjob.name\" semantic conventions. It represents the name of the\n\t// CronJob.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tK8SCronJobNameKey = attribute.Key(\"k8s.cronjob.name\")\n)\n\n// K8SCronJobUID returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.uid\" semantic conventions. It represents the UID of the\n// CronJob.\nfunc K8SCronJobUID(val string) attribute.KeyValue {\n\treturn K8SCronJobUIDKey.String(val)\n}\n\n// K8SCronJobName returns an attribute KeyValue conforming to the\n// \"k8s.cronjob.name\" semantic conventions. It represents the name of the\n// CronJob.\nfunc K8SCronJobName(val string) attribute.KeyValue {\n\treturn K8SCronJobNameKey.String(val)\n}\n\n// The operating system (OS) on which the process represented by this resource\n// is running.\nconst (\n\t// OSTypeKey is the attribute Key conforming to the \"os.type\" semantic\n\t// conventions. It represents the operating system type.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\tOSTypeKey = attribute.Key(\"os.type\")\n\n\t// OSDescriptionKey is the attribute Key conforming to the \"os.description\"\n\t// semantic conventions. It represents the human readable (not intended to\n\t// be parsed) OS version information, like e.g. reported by `ver` or\n\t// `lsb_release -a` commands.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1\n\t// LTS'\n\tOSDescriptionKey = attribute.Key(\"os.description\")\n\n\t// OSNameKey is the attribute Key conforming to the \"os.name\" semantic\n\t// conventions. It represents the human readable operating system name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'iOS', 'Android', 'Ubuntu'\n\tOSNameKey = attribute.Key(\"os.name\")\n\n\t// OSVersionKey is the attribute Key conforming to the \"os.version\"\n\t// semantic conventions. It represents the version string of the operating\n\t// system as defined in [Version\n\t// Attributes](../../resource/semantic_conventions/README.md#version-attributes).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '14.2.1', '18.04.1'\n\tOSVersionKey = attribute.Key(\"os.version\")\n)\n\nvar (\n\t// Microsoft Windows\n\tOSTypeWindows = OSTypeKey.String(\"windows\")\n\t// Linux\n\tOSTypeLinux = OSTypeKey.String(\"linux\")\n\t// Apple Darwin\n\tOSTypeDarwin = OSTypeKey.String(\"darwin\")\n\t// FreeBSD\n\tOSTypeFreeBSD = OSTypeKey.String(\"freebsd\")\n\t// NetBSD\n\tOSTypeNetBSD = OSTypeKey.String(\"netbsd\")\n\t// OpenBSD\n\tOSTypeOpenBSD = OSTypeKey.String(\"openbsd\")\n\t// DragonFly BSD\n\tOSTypeDragonflyBSD = OSTypeKey.String(\"dragonflybsd\")\n\t// HP-UX (Hewlett Packard Unix)\n\tOSTypeHPUX = OSTypeKey.String(\"hpux\")\n\t// AIX (Advanced Interactive eXecutive)\n\tOSTypeAIX = OSTypeKey.String(\"aix\")\n\t// SunOS, Oracle Solaris\n\tOSTypeSolaris = OSTypeKey.String(\"solaris\")\n\t// IBM z/OS\n\tOSTypeZOS = OSTypeKey.String(\"z_os\")\n)\n\n// OSDescription returns an attribute KeyValue conforming to the\n// \"os.description\" semantic conventions. It represents the human readable (not\n// intended to be parsed) OS version information, like e.g. reported by `ver`\n// or `lsb_release -a` commands.\nfunc OSDescription(val string) attribute.KeyValue {\n\treturn OSDescriptionKey.String(val)\n}\n\n// OSName returns an attribute KeyValue conforming to the \"os.name\" semantic\n// conventions. It represents the human readable operating system name.\nfunc OSName(val string) attribute.KeyValue {\n\treturn OSNameKey.String(val)\n}\n\n// OSVersion returns an attribute KeyValue conforming to the \"os.version\"\n// semantic conventions. It represents the version string of the operating\n// system as defined in [Version\n// Attributes](../../resource/semantic_conventions/README.md#version-attributes).\nfunc OSVersion(val string) attribute.KeyValue {\n\treturn OSVersionKey.String(val)\n}\n\n// An operating system process.\nconst (\n\t// ProcessPIDKey is the attribute Key conforming to the \"process.pid\"\n\t// semantic conventions. It represents the process identifier (PID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 1234\n\tProcessPIDKey = attribute.Key(\"process.pid\")\n\n\t// ProcessParentPIDKey is the attribute Key conforming to the\n\t// \"process.parent_pid\" semantic conventions. It represents the parent\n\t// Process identifier (PID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 111\n\tProcessParentPIDKey = attribute.Key(\"process.parent_pid\")\n\n\t// ProcessExecutableNameKey is the attribute Key conforming to the\n\t// \"process.executable.name\" semantic conventions. It represents the name\n\t// of the process executable. On Linux based systems, can be set to the\n\t// `Name` in `proc/[pid]/status`. On Windows, can be set to the base name\n\t// of `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (See alternative attributes\n\t// below.)\n\t// Stability: stable\n\t// Examples: 'otelcol'\n\tProcessExecutableNameKey = attribute.Key(\"process.executable.name\")\n\n\t// ProcessExecutablePathKey is the attribute Key conforming to the\n\t// \"process.executable.path\" semantic conventions. It represents the full\n\t// path to the process executable. On Linux based systems, can be set to\n\t// the target of `proc/[pid]/exe`. On Windows, can be set to the result of\n\t// `GetProcessImageFileNameW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (See alternative attributes\n\t// below.)\n\t// Stability: stable\n\t// Examples: '/usr/bin/cmd/otelcol'\n\tProcessExecutablePathKey = attribute.Key(\"process.executable.path\")\n\n\t// ProcessCommandKey is the attribute Key conforming to the\n\t// \"process.command\" semantic conventions. It represents the command used\n\t// to launch the process (i.e. the command name). On Linux based systems,\n\t// can be set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can\n\t// be set to the first parameter extracted from `GetCommandLineW`.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (See alternative attributes\n\t// below.)\n\t// Stability: stable\n\t// Examples: 'cmd/otelcol'\n\tProcessCommandKey = attribute.Key(\"process.command\")\n\n\t// ProcessCommandLineKey is the attribute Key conforming to the\n\t// \"process.command_line\" semantic conventions. It represents the full\n\t// command used to launch the process as a single string representing the\n\t// full command. On Windows, can be set to the result of `GetCommandLineW`.\n\t// Do not set this if you have to assemble it just for monitoring; use\n\t// `process.command_args` instead.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (See alternative attributes\n\t// below.)\n\t// Stability: stable\n\t// Examples: 'C:\\\\cmd\\\\otecol --config=\"my directory\\\\config.yaml\"'\n\tProcessCommandLineKey = attribute.Key(\"process.command_line\")\n\n\t// ProcessCommandArgsKey is the attribute Key conforming to the\n\t// \"process.command_args\" semantic conventions. It represents the all the\n\t// command arguments (including the command/executable itself) as received\n\t// by the process. On Linux-based systems (and some other Unixoid systems\n\t// supporting procfs), can be set according to the list of null-delimited\n\t// strings extracted from `proc/[pid]/cmdline`. For libc-based executables,\n\t// this would be the full argv vector passed to `main`.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: ConditionallyRequired (See alternative attributes\n\t// below.)\n\t// Stability: stable\n\t// Examples: 'cmd/otecol', '--config=config.yaml'\n\tProcessCommandArgsKey = attribute.Key(\"process.command_args\")\n\n\t// ProcessOwnerKey is the attribute Key conforming to the \"process.owner\"\n\t// semantic conventions. It represents the username of the user that owns\n\t// the process.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'root'\n\tProcessOwnerKey = attribute.Key(\"process.owner\")\n)\n\n// ProcessPID returns an attribute KeyValue conforming to the \"process.pid\"\n// semantic conventions. It represents the process identifier (PID).\nfunc ProcessPID(val int) attribute.KeyValue {\n\treturn ProcessPIDKey.Int(val)\n}\n\n// ProcessParentPID returns an attribute KeyValue conforming to the\n// \"process.parent_pid\" semantic conventions. It represents the parent Process\n// identifier (PID).\nfunc ProcessParentPID(val int) attribute.KeyValue {\n\treturn ProcessParentPIDKey.Int(val)\n}\n\n// ProcessExecutableName returns an attribute KeyValue conforming to the\n// \"process.executable.name\" semantic conventions. It represents the name of\n// the process executable. On Linux based systems, can be set to the `Name` in\n// `proc/[pid]/status`. On Windows, can be set to the base name of\n// `GetProcessImageFileNameW`.\nfunc ProcessExecutableName(val string) attribute.KeyValue {\n\treturn ProcessExecutableNameKey.String(val)\n}\n\n// ProcessExecutablePath returns an attribute KeyValue conforming to the\n// \"process.executable.path\" semantic conventions. It represents the full path\n// to the process executable. On Linux based systems, can be set to the target\n// of `proc/[pid]/exe`. On Windows, can be set to the result of\n// `GetProcessImageFileNameW`.\nfunc ProcessExecutablePath(val string) attribute.KeyValue {\n\treturn ProcessExecutablePathKey.String(val)\n}\n\n// ProcessCommand returns an attribute KeyValue conforming to the\n// \"process.command\" semantic conventions. It represents the command used to\n// launch the process (i.e. the command name). On Linux based systems, can be\n// set to the zeroth string in `proc/[pid]/cmdline`. On Windows, can be set to\n// the first parameter extracted from `GetCommandLineW`.\nfunc ProcessCommand(val string) attribute.KeyValue {\n\treturn ProcessCommandKey.String(val)\n}\n\n// ProcessCommandLine returns an attribute KeyValue conforming to the\n// \"process.command_line\" semantic conventions. It represents the full command\n// used to launch the process as a single string representing the full command.\n// On Windows, can be set to the result of `GetCommandLineW`. Do not set this\n// if you have to assemble it just for monitoring; use `process.command_args`\n// instead.\nfunc ProcessCommandLine(val string) attribute.KeyValue {\n\treturn ProcessCommandLineKey.String(val)\n}\n\n// ProcessCommandArgs returns an attribute KeyValue conforming to the\n// \"process.command_args\" semantic conventions. It represents the all the\n// command arguments (including the command/executable itself) as received by\n// the process. On Linux-based systems (and some other Unixoid systems\n// supporting procfs), can be set according to the list of null-delimited\n// strings extracted from `proc/[pid]/cmdline`. For libc-based executables,\n// this would be the full argv vector passed to `main`.\nfunc ProcessCommandArgs(val ...string) attribute.KeyValue {\n\treturn ProcessCommandArgsKey.StringSlice(val)\n}\n\n// ProcessOwner returns an attribute KeyValue conforming to the\n// \"process.owner\" semantic conventions. It represents the username of the user\n// that owns the process.\nfunc ProcessOwner(val string) attribute.KeyValue {\n\treturn ProcessOwnerKey.String(val)\n}\n\n// The single (language) runtime instance which is monitored.\nconst (\n\t// ProcessRuntimeNameKey is the attribute Key conforming to the\n\t// \"process.runtime.name\" semantic conventions. It represents the name of\n\t// the runtime of this process. For compiled native binaries, this SHOULD\n\t// be the name of the compiler.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'OpenJDK Runtime Environment'\n\tProcessRuntimeNameKey = attribute.Key(\"process.runtime.name\")\n\n\t// ProcessRuntimeVersionKey is the attribute Key conforming to the\n\t// \"process.runtime.version\" semantic conventions. It represents the\n\t// version of the runtime of this process, as returned by the runtime\n\t// without modification.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '14.0.2'\n\tProcessRuntimeVersionKey = attribute.Key(\"process.runtime.version\")\n\n\t// ProcessRuntimeDescriptionKey is the attribute Key conforming to the\n\t// \"process.runtime.description\" semantic conventions. It represents an\n\t// additional description about the runtime of the process, for example a\n\t// specific vendor customization of the runtime environment.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0'\n\tProcessRuntimeDescriptionKey = attribute.Key(\"process.runtime.description\")\n)\n\n// ProcessRuntimeName returns an attribute KeyValue conforming to the\n// \"process.runtime.name\" semantic conventions. It represents the name of the\n// runtime of this process. For compiled native binaries, this SHOULD be the\n// name of the compiler.\nfunc ProcessRuntimeName(val string) attribute.KeyValue {\n\treturn ProcessRuntimeNameKey.String(val)\n}\n\n// ProcessRuntimeVersion returns an attribute KeyValue conforming to the\n// \"process.runtime.version\" semantic conventions. It represents the version of\n// the runtime of this process, as returned by the runtime without\n// modification.\nfunc ProcessRuntimeVersion(val string) attribute.KeyValue {\n\treturn ProcessRuntimeVersionKey.String(val)\n}\n\n// ProcessRuntimeDescription returns an attribute KeyValue conforming to the\n// \"process.runtime.description\" semantic conventions. It represents an\n// additional description about the runtime of the process, for example a\n// specific vendor customization of the runtime environment.\nfunc ProcessRuntimeDescription(val string) attribute.KeyValue {\n\treturn ProcessRuntimeDescriptionKey.String(val)\n}\n\n// A service instance.\nconst (\n\t// ServiceNameKey is the attribute Key conforming to the \"service.name\"\n\t// semantic conventions. It represents the logical name of the service.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'shoppingcart'\n\t// Note: MUST be the same for all instances of horizontally scaled\n\t// services. If the value was not specified, SDKs MUST fallback to\n\t// `unknown_service:` concatenated with\n\t// [`process.executable.name`](process.md#process), e.g.\n\t// `unknown_service:bash`. If `process.executable.name` is not available,\n\t// the value MUST be set to `unknown_service`.\n\tServiceNameKey = attribute.Key(\"service.name\")\n\n\t// ServiceNamespaceKey is the attribute Key conforming to the\n\t// \"service.namespace\" semantic conventions. It represents a namespace for\n\t// `service.name`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Shop'\n\t// Note: A string value having a meaning that helps to distinguish a group\n\t// of services, for example the team name that owns a group of services.\n\t// `service.name` is expected to be unique within the same namespace. If\n\t// `service.namespace` is not specified in the Resource then `service.name`\n\t// is expected to be unique for all services that have no explicit\n\t// namespace defined (so the empty/unspecified namespace is simply one more\n\t// valid namespace). Zero-length namespace string is assumed equal to\n\t// unspecified namespace.\n\tServiceNamespaceKey = attribute.Key(\"service.namespace\")\n\n\t// ServiceInstanceIDKey is the attribute Key conforming to the\n\t// \"service.instance.id\" semantic conventions. It represents the string ID\n\t// of the service instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '627cc493-f310-47de-96bd-71410b7dec09'\n\t// Note: MUST be unique for each instance of the same\n\t// `service.namespace,service.name` pair (in other words\n\t// `service.namespace,service.name,service.instance.id` triplet MUST be\n\t// globally unique). The ID helps to distinguish instances of the same\n\t// service that exist at the same time (e.g. instances of a horizontally\n\t// scaled service). It is preferable for the ID to be persistent and stay\n\t// the same for the lifetime of the service instance, however it is\n\t// acceptable that the ID is ephemeral and changes during important\n\t// lifetime events for the service (e.g. service restarts). If the service\n\t// has no inherent unique ID that can be used as the value of this\n\t// attribute it is recommended to generate a random Version 1 or Version 4\n\t// RFC 4122 UUID (services aiming for reproducible UUIDs may also use\n\t// Version 5, see RFC 4122 for more recommendations).\n\tServiceInstanceIDKey = attribute.Key(\"service.instance.id\")\n\n\t// ServiceVersionKey is the attribute Key conforming to the\n\t// \"service.version\" semantic conventions. It represents the version string\n\t// of the service API or implementation.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '2.0.0'\n\tServiceVersionKey = attribute.Key(\"service.version\")\n)\n\n// ServiceName returns an attribute KeyValue conforming to the\n// \"service.name\" semantic conventions. It represents the logical name of the\n// service.\nfunc ServiceName(val string) attribute.KeyValue {\n\treturn ServiceNameKey.String(val)\n}\n\n// ServiceNamespace returns an attribute KeyValue conforming to the\n// \"service.namespace\" semantic conventions. It represents a namespace for\n// `service.name`.\nfunc ServiceNamespace(val string) attribute.KeyValue {\n\treturn ServiceNamespaceKey.String(val)\n}\n\n// ServiceInstanceID returns an attribute KeyValue conforming to the\n// \"service.instance.id\" semantic conventions. It represents the string ID of\n// the service instance.\nfunc ServiceInstanceID(val string) attribute.KeyValue {\n\treturn ServiceInstanceIDKey.String(val)\n}\n\n// ServiceVersion returns an attribute KeyValue conforming to the\n// \"service.version\" semantic conventions. It represents the version string of\n// the service API or implementation.\nfunc ServiceVersion(val string) attribute.KeyValue {\n\treturn ServiceVersionKey.String(val)\n}\n\n// The telemetry SDK used to capture data recorded by the instrumentation\n// libraries.\nconst (\n\t// TelemetrySDKNameKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.name\" semantic conventions. It represents the name of the\n\t// telemetry SDK as defined above.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'opentelemetry'\n\tTelemetrySDKNameKey = attribute.Key(\"telemetry.sdk.name\")\n\n\t// TelemetrySDKLanguageKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.language\" semantic conventions. It represents the\n\t// language of the telemetry SDK.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tTelemetrySDKLanguageKey = attribute.Key(\"telemetry.sdk.language\")\n\n\t// TelemetrySDKVersionKey is the attribute Key conforming to the\n\t// \"telemetry.sdk.version\" semantic conventions. It represents the version\n\t// string of the telemetry SDK.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '1.2.3'\n\tTelemetrySDKVersionKey = attribute.Key(\"telemetry.sdk.version\")\n\n\t// TelemetryAutoVersionKey is the attribute Key conforming to the\n\t// \"telemetry.auto.version\" semantic conventions. It represents the version\n\t// string of the auto instrumentation agent, if used.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '1.2.3'\n\tTelemetryAutoVersionKey = attribute.Key(\"telemetry.auto.version\")\n)\n\nvar (\n\t// cpp\n\tTelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String(\"cpp\")\n\t// dotnet\n\tTelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String(\"dotnet\")\n\t// erlang\n\tTelemetrySDKLanguageErlang = TelemetrySDKLanguageKey.String(\"erlang\")\n\t// go\n\tTelemetrySDKLanguageGo = TelemetrySDKLanguageKey.String(\"go\")\n\t// java\n\tTelemetrySDKLanguageJava = TelemetrySDKLanguageKey.String(\"java\")\n\t// nodejs\n\tTelemetrySDKLanguageNodejs = TelemetrySDKLanguageKey.String(\"nodejs\")\n\t// php\n\tTelemetrySDKLanguagePHP = TelemetrySDKLanguageKey.String(\"php\")\n\t// python\n\tTelemetrySDKLanguagePython = TelemetrySDKLanguageKey.String(\"python\")\n\t// ruby\n\tTelemetrySDKLanguageRuby = TelemetrySDKLanguageKey.String(\"ruby\")\n\t// webjs\n\tTelemetrySDKLanguageWebjs = TelemetrySDKLanguageKey.String(\"webjs\")\n\t// swift\n\tTelemetrySDKLanguageSwift = TelemetrySDKLanguageKey.String(\"swift\")\n)\n\n// TelemetrySDKName returns an attribute KeyValue conforming to the\n// \"telemetry.sdk.name\" semantic conventions. It represents the name of the\n// telemetry SDK as defined above.\nfunc TelemetrySDKName(val string) attribute.KeyValue {\n\treturn TelemetrySDKNameKey.String(val)\n}\n\n// TelemetrySDKVersion returns an attribute KeyValue conforming to the\n// \"telemetry.sdk.version\" semantic conventions. It represents the version\n// string of the telemetry SDK.\nfunc TelemetrySDKVersion(val string) attribute.KeyValue {\n\treturn TelemetrySDKVersionKey.String(val)\n}\n\n// TelemetryAutoVersion returns an attribute KeyValue conforming to the\n// \"telemetry.auto.version\" semantic conventions. It represents the version\n// string of the auto instrumentation agent, if used.\nfunc TelemetryAutoVersion(val string) attribute.KeyValue {\n\treturn TelemetryAutoVersionKey.String(val)\n}\n\n// Resource describing the packaged software running the application code. Web\n// engines are typically executed using process.runtime.\nconst (\n\t// WebEngineNameKey is the attribute Key conforming to the \"webengine.name\"\n\t// semantic conventions. It represents the name of the web engine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'WildFly'\n\tWebEngineNameKey = attribute.Key(\"webengine.name\")\n\n\t// WebEngineVersionKey is the attribute Key conforming to the\n\t// \"webengine.version\" semantic conventions. It represents the version of\n\t// the web engine.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '21.0.0'\n\tWebEngineVersionKey = attribute.Key(\"webengine.version\")\n\n\t// WebEngineDescriptionKey is the attribute Key conforming to the\n\t// \"webengine.description\" semantic conventions. It represents the\n\t// additional description of the web engine (e.g. detailed version and\n\t// edition information).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) -\n\t// 2.2.2.Final'\n\tWebEngineDescriptionKey = attribute.Key(\"webengine.description\")\n)\n\n// WebEngineName returns an attribute KeyValue conforming to the\n// \"webengine.name\" semantic conventions. It represents the name of the web\n// engine.\nfunc WebEngineName(val string) attribute.KeyValue {\n\treturn WebEngineNameKey.String(val)\n}\n\n// WebEngineVersion returns an attribute KeyValue conforming to the\n// \"webengine.version\" semantic conventions. It represents the version of the\n// web engine.\nfunc WebEngineVersion(val string) attribute.KeyValue {\n\treturn WebEngineVersionKey.String(val)\n}\n\n// WebEngineDescription returns an attribute KeyValue conforming to the\n// \"webengine.description\" semantic conventions. It represents the additional\n// description of the web engine (e.g. detailed version and edition\n// information).\nfunc WebEngineDescription(val string) attribute.KeyValue {\n\treturn WebEngineDescriptionKey.String(val)\n}\n\n// Attributes used by non-OTLP exporters to represent OpenTelemetry Scope's\n// concepts.\nconst (\n\t// OtelScopeNameKey is the attribute Key conforming to the\n\t// \"otel.scope.name\" semantic conventions. It represents the name of the\n\t// instrumentation scope - (`InstrumentationScope.Name` in OTLP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'io.opentelemetry.contrib.mongodb'\n\tOtelScopeNameKey = attribute.Key(\"otel.scope.name\")\n\n\t// OtelScopeVersionKey is the attribute Key conforming to the\n\t// \"otel.scope.version\" semantic conventions. It represents the version of\n\t// the instrumentation scope - (`InstrumentationScope.Version` in OTLP).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '1.0.0'\n\tOtelScopeVersionKey = attribute.Key(\"otel.scope.version\")\n)\n\n// OtelScopeName returns an attribute KeyValue conforming to the\n// \"otel.scope.name\" semantic conventions. It represents the name of the\n// instrumentation scope - (`InstrumentationScope.Name` in OTLP).\nfunc OtelScopeName(val string) attribute.KeyValue {\n\treturn OtelScopeNameKey.String(val)\n}\n\n// OtelScopeVersion returns an attribute KeyValue conforming to the\n// \"otel.scope.version\" semantic conventions. It represents the version of the\n// instrumentation scope - (`InstrumentationScope.Version` in OTLP).\nfunc OtelScopeVersion(val string) attribute.KeyValue {\n\treturn OtelScopeVersionKey.String(val)\n}\n\n// Span attributes used by non-OTLP exporters to represent OpenTelemetry\n// Scope's concepts.\nconst (\n\t// OtelLibraryNameKey is the attribute Key conforming to the\n\t// \"otel.library.name\" semantic conventions. It represents the deprecated,\n\t// use the `otel.scope.name` attribute.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: deprecated\n\t// Examples: 'io.opentelemetry.contrib.mongodb'\n\tOtelLibraryNameKey = attribute.Key(\"otel.library.name\")\n\n\t// OtelLibraryVersionKey is the attribute Key conforming to the\n\t// \"otel.library.version\" semantic conventions. It represents the\n\t// deprecated, use the `otel.scope.version` attribute.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: deprecated\n\t// Examples: '1.0.0'\n\tOtelLibraryVersionKey = attribute.Key(\"otel.library.version\")\n)\n\n// OtelLibraryName returns an attribute KeyValue conforming to the\n// \"otel.library.name\" semantic conventions. It represents the deprecated, use\n// the `otel.scope.name` attribute.\nfunc OtelLibraryName(val string) attribute.KeyValue {\n\treturn OtelLibraryNameKey.String(val)\n}\n\n// OtelLibraryVersion returns an attribute KeyValue conforming to the\n// \"otel.library.version\" semantic conventions. It represents the deprecated,\n// use the `otel.scope.version` attribute.\nfunc OtelLibraryVersion(val string) attribute.KeyValue {\n\treturn OtelLibraryVersionKey.String(val)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.17.0/schema.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n\n// SchemaURL is the schema URL that matches the version of the semantic conventions\n// that this package defines. Semconv packages starting from v1.4.0 must declare\n// non-empty schema URL in the form https://opentelemetry.io/schemas/<version>\nconst SchemaURL = \"https://opentelemetry.io/schemas/1.17.0\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/semconv/v1.17.0/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n// Code generated from semantic convention specification. DO NOT EDIT.\n\npackage semconv // import \"go.opentelemetry.io/otel/semconv/v1.17.0\"\n\nimport \"go.opentelemetry.io/otel/attribute\"\n\n// The shared attributes used to report a single exception associated with a\n// span or log.\nconst (\n\t// ExceptionTypeKey is the attribute Key conforming to the \"exception.type\"\n\t// semantic conventions. It represents the type of the exception (its\n\t// fully-qualified class name, if applicable). The dynamic type of the\n\t// exception should be preferred over the static type in languages that\n\t// support it.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'java.net.ConnectException', 'OSError'\n\tExceptionTypeKey = attribute.Key(\"exception.type\")\n\n\t// ExceptionMessageKey is the attribute Key conforming to the\n\t// \"exception.message\" semantic conventions. It represents the exception\n\t// message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Division by zero', \"Can't convert 'int' object to str\n\t// implicitly\"\n\tExceptionMessageKey = attribute.Key(\"exception.message\")\n\n\t// ExceptionStacktraceKey is the attribute Key conforming to the\n\t// \"exception.stacktrace\" semantic conventions. It represents a stacktrace\n\t// as a string in the natural representation for the language runtime. The\n\t// representation is to be determined and documented by each language SIG.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Exception in thread \"main\" java.lang.RuntimeException: Test\n\t// exception\\\\n at '\n\t//  'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\\\n at '\n\t//  'com.example.GenerateTrace.methodA(GenerateTrace.java:9)\\\\n at '\n\t//  'com.example.GenerateTrace.main(GenerateTrace.java:5)'\n\tExceptionStacktraceKey = attribute.Key(\"exception.stacktrace\")\n)\n\n// ExceptionType returns an attribute KeyValue conforming to the\n// \"exception.type\" semantic conventions. It represents the type of the\n// exception (its fully-qualified class name, if applicable). The dynamic type\n// of the exception should be preferred over the static type in languages that\n// support it.\nfunc ExceptionType(val string) attribute.KeyValue {\n\treturn ExceptionTypeKey.String(val)\n}\n\n// ExceptionMessage returns an attribute KeyValue conforming to the\n// \"exception.message\" semantic conventions. It represents the exception\n// message.\nfunc ExceptionMessage(val string) attribute.KeyValue {\n\treturn ExceptionMessageKey.String(val)\n}\n\n// ExceptionStacktrace returns an attribute KeyValue conforming to the\n// \"exception.stacktrace\" semantic conventions. It represents a stacktrace as a\n// string in the natural representation for the language runtime. The\n// representation is to be determined and documented by each language SIG.\nfunc ExceptionStacktrace(val string) attribute.KeyValue {\n\treturn ExceptionStacktraceKey.String(val)\n}\n\n// Attributes for Events represented using Log Records.\nconst (\n\t// EventNameKey is the attribute Key conforming to the \"event.name\"\n\t// semantic conventions. It represents the name identifies the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'click', 'exception'\n\tEventNameKey = attribute.Key(\"event.name\")\n\n\t// EventDomainKey is the attribute Key conforming to the \"event.domain\"\n\t// semantic conventions. It represents the domain identifies the business\n\t// context for the events.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Note: Events across different domains may have same `event.name`, yet be\n\t// unrelated events.\n\tEventDomainKey = attribute.Key(\"event.domain\")\n)\n\nvar (\n\t// Events from browser apps\n\tEventDomainBrowser = EventDomainKey.String(\"browser\")\n\t// Events from mobile apps\n\tEventDomainDevice = EventDomainKey.String(\"device\")\n\t// Events from Kubernetes\n\tEventDomainK8S = EventDomainKey.String(\"k8s\")\n)\n\n// EventName returns an attribute KeyValue conforming to the \"event.name\"\n// semantic conventions. It represents the name identifies the event.\nfunc EventName(val string) attribute.KeyValue {\n\treturn EventNameKey.String(val)\n}\n\n// Span attributes used by AWS Lambda (in addition to general `faas`\n// attributes).\nconst (\n\t// AWSLambdaInvokedARNKey is the attribute Key conforming to the\n\t// \"aws.lambda.invoked_arn\" semantic conventions. It represents the full\n\t// invoked ARN as provided on the `Context` passed to the function\n\t// (`Lambda-Runtime-Invoked-Function-ARN` header on the\n\t// `/runtime/invocation/next` applicable).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'arn:aws:lambda:us-east-1:123456:function:myfunction:myalias'\n\t// Note: This may be different from `faas.id` if an alias is involved.\n\tAWSLambdaInvokedARNKey = attribute.Key(\"aws.lambda.invoked_arn\")\n)\n\n// AWSLambdaInvokedARN returns an attribute KeyValue conforming to the\n// \"aws.lambda.invoked_arn\" semantic conventions. It represents the full\n// invoked ARN as provided on the `Context` passed to the function\n// (`Lambda-Runtime-Invoked-Function-ARN` header on the\n// `/runtime/invocation/next` applicable).\nfunc AWSLambdaInvokedARN(val string) attribute.KeyValue {\n\treturn AWSLambdaInvokedARNKey.String(val)\n}\n\n// Attributes for CloudEvents. CloudEvents is a specification on how to define\n// event data in a standard way. These attributes can be attached to spans when\n// performing operations with CloudEvents, regardless of the protocol being\n// used.\nconst (\n\t// CloudeventsEventIDKey is the attribute Key conforming to the\n\t// \"cloudevents.event_id\" semantic conventions. It represents the\n\t// [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id)\n\t// uniquely identifies the event.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: '123e4567-e89b-12d3-a456-426614174000', '0001'\n\tCloudeventsEventIDKey = attribute.Key(\"cloudevents.event_id\")\n\n\t// CloudeventsEventSourceKey is the attribute Key conforming to the\n\t// \"cloudevents.event_source\" semantic conventions. It represents the\n\t// [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1)\n\t// identifies the context in which an event happened.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'https://github.com/cloudevents',\n\t// '/cloudevents/spec/pull/123', 'my-service'\n\tCloudeventsEventSourceKey = attribute.Key(\"cloudevents.event_source\")\n\n\t// CloudeventsEventSpecVersionKey is the attribute Key conforming to the\n\t// \"cloudevents.event_spec_version\" semantic conventions. It represents the\n\t// [version of the CloudEvents\n\t// specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion)\n\t// which the event uses.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '1.0'\n\tCloudeventsEventSpecVersionKey = attribute.Key(\"cloudevents.event_spec_version\")\n\n\t// CloudeventsEventTypeKey is the attribute Key conforming to the\n\t// \"cloudevents.event_type\" semantic conventions. It represents the\n\t// [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type)\n\t// contains a value describing the type of event related to the originating\n\t// occurrence.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'com.github.pull_request.opened',\n\t// 'com.example.object.deleted.v2'\n\tCloudeventsEventTypeKey = attribute.Key(\"cloudevents.event_type\")\n\n\t// CloudeventsEventSubjectKey is the attribute Key conforming to the\n\t// \"cloudevents.event_subject\" semantic conventions. It represents the\n\t// [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject)\n\t// of the event in the context of the event producer (identified by\n\t// source).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'mynewfile.jpg'\n\tCloudeventsEventSubjectKey = attribute.Key(\"cloudevents.event_subject\")\n)\n\n// CloudeventsEventID returns an attribute KeyValue conforming to the\n// \"cloudevents.event_id\" semantic conventions. It represents the\n// [event_id](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#id)\n// uniquely identifies the event.\nfunc CloudeventsEventID(val string) attribute.KeyValue {\n\treturn CloudeventsEventIDKey.String(val)\n}\n\n// CloudeventsEventSource returns an attribute KeyValue conforming to the\n// \"cloudevents.event_source\" semantic conventions. It represents the\n// [source](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#source-1)\n// identifies the context in which an event happened.\nfunc CloudeventsEventSource(val string) attribute.KeyValue {\n\treturn CloudeventsEventSourceKey.String(val)\n}\n\n// CloudeventsEventSpecVersion returns an attribute KeyValue conforming to\n// the \"cloudevents.event_spec_version\" semantic conventions. It represents the\n// [version of the CloudEvents\n// specification](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#specversion)\n// which the event uses.\nfunc CloudeventsEventSpecVersion(val string) attribute.KeyValue {\n\treturn CloudeventsEventSpecVersionKey.String(val)\n}\n\n// CloudeventsEventType returns an attribute KeyValue conforming to the\n// \"cloudevents.event_type\" semantic conventions. It represents the\n// [event_type](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#type)\n// contains a value describing the type of event related to the originating\n// occurrence.\nfunc CloudeventsEventType(val string) attribute.KeyValue {\n\treturn CloudeventsEventTypeKey.String(val)\n}\n\n// CloudeventsEventSubject returns an attribute KeyValue conforming to the\n// \"cloudevents.event_subject\" semantic conventions. It represents the\n// [subject](https://github.com/cloudevents/spec/blob/v1.0.2/cloudevents/spec.md#subject)\n// of the event in the context of the event producer (identified by source).\nfunc CloudeventsEventSubject(val string) attribute.KeyValue {\n\treturn CloudeventsEventSubjectKey.String(val)\n}\n\n// Semantic conventions for the OpenTracing Shim\nconst (\n\t// OpentracingRefTypeKey is the attribute Key conforming to the\n\t// \"opentracing.ref_type\" semantic conventions. It represents the\n\t// parent-child Reference type\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Note: The causal relationship between a child Span and a parent Span.\n\tOpentracingRefTypeKey = attribute.Key(\"opentracing.ref_type\")\n)\n\nvar (\n\t// The parent Span depends on the child Span in some capacity\n\tOpentracingRefTypeChildOf = OpentracingRefTypeKey.String(\"child_of\")\n\t// The parent Span does not depend in any way on the result of the child Span\n\tOpentracingRefTypeFollowsFrom = OpentracingRefTypeKey.String(\"follows_from\")\n)\n\n// The attributes used to perform database client calls.\nconst (\n\t// DBSystemKey is the attribute Key conforming to the \"db.system\" semantic\n\t// conventions. It represents an identifier for the database management\n\t// system (DBMS) product being used. See below for a list of well-known\n\t// identifiers.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\tDBSystemKey = attribute.Key(\"db.system\")\n\n\t// DBConnectionStringKey is the attribute Key conforming to the\n\t// \"db.connection_string\" semantic conventions. It represents the\n\t// connection string used to connect to the database. It is recommended to\n\t// remove embedded credentials.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Server=(localdb)\\\\v11.0;Integrated Security=true;'\n\tDBConnectionStringKey = attribute.Key(\"db.connection_string\")\n\n\t// DBUserKey is the attribute Key conforming to the \"db.user\" semantic\n\t// conventions. It represents the username for accessing the database.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'readonly_user', 'reporting_user'\n\tDBUserKey = attribute.Key(\"db.user\")\n\n\t// DBJDBCDriverClassnameKey is the attribute Key conforming to the\n\t// \"db.jdbc.driver_classname\" semantic conventions. It represents the\n\t// fully-qualified class name of the [Java Database Connectivity\n\t// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/)\n\t// driver used to connect.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'org.postgresql.Driver',\n\t// 'com.microsoft.sqlserver.jdbc.SQLServerDriver'\n\tDBJDBCDriverClassnameKey = attribute.Key(\"db.jdbc.driver_classname\")\n\n\t// DBNameKey is the attribute Key conforming to the \"db.name\" semantic\n\t// conventions. It represents the this attribute is used to report the name\n\t// of the database being accessed. For commands that switch the database,\n\t// this should be set to the target database (even if the command fails).\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (If applicable.)\n\t// Stability: stable\n\t// Examples: 'customers', 'main'\n\t// Note: In some SQL databases, the database name to be used is called\n\t// \"schema name\". In case there are multiple layers that could be\n\t// considered for database name (e.g. Oracle instance name and schema\n\t// name), the database name to be used is the more specific layer (e.g.\n\t// Oracle schema name).\n\tDBNameKey = attribute.Key(\"db.name\")\n\n\t// DBStatementKey is the attribute Key conforming to the \"db.statement\"\n\t// semantic conventions. It represents the database statement being\n\t// executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (If applicable and not\n\t// explicitly disabled via instrumentation configuration.)\n\t// Stability: stable\n\t// Examples: 'SELECT * FROM wuser_table', 'SET mykey \"WuValue\"'\n\t// Note: The value may be sanitized to exclude sensitive information.\n\tDBStatementKey = attribute.Key(\"db.statement\")\n\n\t// DBOperationKey is the attribute Key conforming to the \"db.operation\"\n\t// semantic conventions. It represents the name of the operation being\n\t// executed, e.g. the [MongoDB command\n\t// name](https://docs.mongodb.com/manual/reference/command/#database-operations)\n\t// such as `findAndModify`, or the SQL keyword.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (If `db.statement` is not\n\t// applicable.)\n\t// Stability: stable\n\t// Examples: 'findAndModify', 'HMSET', 'SELECT'\n\t// Note: When setting this to an SQL keyword, it is not recommended to\n\t// attempt any client-side parsing of `db.statement` just to get this\n\t// property, but it should be set if the operation name is provided by the\n\t// library being instrumented. If the SQL statement has an ambiguous\n\t// operation, or performs more than one operation, this value may be\n\t// omitted.\n\tDBOperationKey = attribute.Key(\"db.operation\")\n)\n\nvar (\n\t// Some other SQL database. Fallback only. See notes\n\tDBSystemOtherSQL = DBSystemKey.String(\"other_sql\")\n\t// Microsoft SQL Server\n\tDBSystemMSSQL = DBSystemKey.String(\"mssql\")\n\t// MySQL\n\tDBSystemMySQL = DBSystemKey.String(\"mysql\")\n\t// Oracle Database\n\tDBSystemOracle = DBSystemKey.String(\"oracle\")\n\t// IBM DB2\n\tDBSystemDB2 = DBSystemKey.String(\"db2\")\n\t// PostgreSQL\n\tDBSystemPostgreSQL = DBSystemKey.String(\"postgresql\")\n\t// Amazon Redshift\n\tDBSystemRedshift = DBSystemKey.String(\"redshift\")\n\t// Apache Hive\n\tDBSystemHive = DBSystemKey.String(\"hive\")\n\t// Cloudscape\n\tDBSystemCloudscape = DBSystemKey.String(\"cloudscape\")\n\t// HyperSQL DataBase\n\tDBSystemHSQLDB = DBSystemKey.String(\"hsqldb\")\n\t// Progress Database\n\tDBSystemProgress = DBSystemKey.String(\"progress\")\n\t// SAP MaxDB\n\tDBSystemMaxDB = DBSystemKey.String(\"maxdb\")\n\t// SAP HANA\n\tDBSystemHanaDB = DBSystemKey.String(\"hanadb\")\n\t// Ingres\n\tDBSystemIngres = DBSystemKey.String(\"ingres\")\n\t// FirstSQL\n\tDBSystemFirstSQL = DBSystemKey.String(\"firstsql\")\n\t// EnterpriseDB\n\tDBSystemEDB = DBSystemKey.String(\"edb\")\n\t// InterSystems Caché\n\tDBSystemCache = DBSystemKey.String(\"cache\")\n\t// Adabas (Adaptable Database System)\n\tDBSystemAdabas = DBSystemKey.String(\"adabas\")\n\t// Firebird\n\tDBSystemFirebird = DBSystemKey.String(\"firebird\")\n\t// Apache Derby\n\tDBSystemDerby = DBSystemKey.String(\"derby\")\n\t// FileMaker\n\tDBSystemFilemaker = DBSystemKey.String(\"filemaker\")\n\t// Informix\n\tDBSystemInformix = DBSystemKey.String(\"informix\")\n\t// InstantDB\n\tDBSystemInstantDB = DBSystemKey.String(\"instantdb\")\n\t// InterBase\n\tDBSystemInterbase = DBSystemKey.String(\"interbase\")\n\t// MariaDB\n\tDBSystemMariaDB = DBSystemKey.String(\"mariadb\")\n\t// Netezza\n\tDBSystemNetezza = DBSystemKey.String(\"netezza\")\n\t// Pervasive PSQL\n\tDBSystemPervasive = DBSystemKey.String(\"pervasive\")\n\t// PointBase\n\tDBSystemPointbase = DBSystemKey.String(\"pointbase\")\n\t// SQLite\n\tDBSystemSqlite = DBSystemKey.String(\"sqlite\")\n\t// Sybase\n\tDBSystemSybase = DBSystemKey.String(\"sybase\")\n\t// Teradata\n\tDBSystemTeradata = DBSystemKey.String(\"teradata\")\n\t// Vertica\n\tDBSystemVertica = DBSystemKey.String(\"vertica\")\n\t// H2\n\tDBSystemH2 = DBSystemKey.String(\"h2\")\n\t// ColdFusion IMQ\n\tDBSystemColdfusion = DBSystemKey.String(\"coldfusion\")\n\t// Apache Cassandra\n\tDBSystemCassandra = DBSystemKey.String(\"cassandra\")\n\t// Apache HBase\n\tDBSystemHBase = DBSystemKey.String(\"hbase\")\n\t// MongoDB\n\tDBSystemMongoDB = DBSystemKey.String(\"mongodb\")\n\t// Redis\n\tDBSystemRedis = DBSystemKey.String(\"redis\")\n\t// Couchbase\n\tDBSystemCouchbase = DBSystemKey.String(\"couchbase\")\n\t// CouchDB\n\tDBSystemCouchDB = DBSystemKey.String(\"couchdb\")\n\t// Microsoft Azure Cosmos DB\n\tDBSystemCosmosDB = DBSystemKey.String(\"cosmosdb\")\n\t// Amazon DynamoDB\n\tDBSystemDynamoDB = DBSystemKey.String(\"dynamodb\")\n\t// Neo4j\n\tDBSystemNeo4j = DBSystemKey.String(\"neo4j\")\n\t// Apache Geode\n\tDBSystemGeode = DBSystemKey.String(\"geode\")\n\t// Elasticsearch\n\tDBSystemElasticsearch = DBSystemKey.String(\"elasticsearch\")\n\t// Memcached\n\tDBSystemMemcached = DBSystemKey.String(\"memcached\")\n\t// CockroachDB\n\tDBSystemCockroachdb = DBSystemKey.String(\"cockroachdb\")\n\t// OpenSearch\n\tDBSystemOpensearch = DBSystemKey.String(\"opensearch\")\n\t// ClickHouse\n\tDBSystemClickhouse = DBSystemKey.String(\"clickhouse\")\n)\n\n// DBConnectionString returns an attribute KeyValue conforming to the\n// \"db.connection_string\" semantic conventions. It represents the connection\n// string used to connect to the database. It is recommended to remove embedded\n// credentials.\nfunc DBConnectionString(val string) attribute.KeyValue {\n\treturn DBConnectionStringKey.String(val)\n}\n\n// DBUser returns an attribute KeyValue conforming to the \"db.user\" semantic\n// conventions. It represents the username for accessing the database.\nfunc DBUser(val string) attribute.KeyValue {\n\treturn DBUserKey.String(val)\n}\n\n// DBJDBCDriverClassname returns an attribute KeyValue conforming to the\n// \"db.jdbc.driver_classname\" semantic conventions. It represents the\n// fully-qualified class name of the [Java Database Connectivity\n// (JDBC)](https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) driver\n// used to connect.\nfunc DBJDBCDriverClassname(val string) attribute.KeyValue {\n\treturn DBJDBCDriverClassnameKey.String(val)\n}\n\n// DBName returns an attribute KeyValue conforming to the \"db.name\" semantic\n// conventions. It represents the this attribute is used to report the name of\n// the database being accessed. For commands that switch the database, this\n// should be set to the target database (even if the command fails).\nfunc DBName(val string) attribute.KeyValue {\n\treturn DBNameKey.String(val)\n}\n\n// DBStatement returns an attribute KeyValue conforming to the\n// \"db.statement\" semantic conventions. It represents the database statement\n// being executed.\nfunc DBStatement(val string) attribute.KeyValue {\n\treturn DBStatementKey.String(val)\n}\n\n// DBOperation returns an attribute KeyValue conforming to the\n// \"db.operation\" semantic conventions. It represents the name of the operation\n// being executed, e.g. the [MongoDB command\n// name](https://docs.mongodb.com/manual/reference/command/#database-operations)\n// such as `findAndModify`, or the SQL keyword.\nfunc DBOperation(val string) attribute.KeyValue {\n\treturn DBOperationKey.String(val)\n}\n\n// Connection-level attributes for Microsoft SQL Server\nconst (\n\t// DBMSSQLInstanceNameKey is the attribute Key conforming to the\n\t// \"db.mssql.instance_name\" semantic conventions. It represents the\n\t// Microsoft SQL Server [instance\n\t// name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15)\n\t// connecting to. This name is used to determine the port of a named\n\t// instance.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'MSSQLSERVER'\n\t// Note: If setting a `db.mssql.instance_name`, `net.peer.port` is no\n\t// longer required (but still recommended if non-standard).\n\tDBMSSQLInstanceNameKey = attribute.Key(\"db.mssql.instance_name\")\n)\n\n// DBMSSQLInstanceName returns an attribute KeyValue conforming to the\n// \"db.mssql.instance_name\" semantic conventions. It represents the Microsoft\n// SQL Server [instance\n// name](https://docs.microsoft.com/en-us/sql/connect/jdbc/building-the-connection-url?view=sql-server-ver15)\n// connecting to. This name is used to determine the port of a named instance.\nfunc DBMSSQLInstanceName(val string) attribute.KeyValue {\n\treturn DBMSSQLInstanceNameKey.String(val)\n}\n\n// Call-level attributes for Cassandra\nconst (\n\t// DBCassandraPageSizeKey is the attribute Key conforming to the\n\t// \"db.cassandra.page_size\" semantic conventions. It represents the fetch\n\t// size used for paging, i.e. how many rows will be returned at once.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 5000\n\tDBCassandraPageSizeKey = attribute.Key(\"db.cassandra.page_size\")\n\n\t// DBCassandraConsistencyLevelKey is the attribute Key conforming to the\n\t// \"db.cassandra.consistency_level\" semantic conventions. It represents the\n\t// consistency level of the query. Based on consistency values from\n\t// [CQL](https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/dml/dmlConfigConsistency.html).\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tDBCassandraConsistencyLevelKey = attribute.Key(\"db.cassandra.consistency_level\")\n\n\t// DBCassandraTableKey is the attribute Key conforming to the\n\t// \"db.cassandra.table\" semantic conventions. It represents the name of the\n\t// primary table that the operation is acting upon, including the keyspace\n\t// name (if applicable).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: stable\n\t// Examples: 'mytable'\n\t// Note: This mirrors the db.sql.table attribute but references cassandra\n\t// rather than sql. It is not recommended to attempt any client-side\n\t// parsing of `db.statement` just to get this property, but it should be\n\t// set if it is provided by the library being instrumented. If the\n\t// operation is acting upon an anonymous table, or more than one table,\n\t// this value MUST NOT be set.\n\tDBCassandraTableKey = attribute.Key(\"db.cassandra.table\")\n\n\t// DBCassandraIdempotenceKey is the attribute Key conforming to the\n\t// \"db.cassandra.idempotence\" semantic conventions. It represents the\n\t// whether or not the query is idempotent.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tDBCassandraIdempotenceKey = attribute.Key(\"db.cassandra.idempotence\")\n\n\t// DBCassandraSpeculativeExecutionCountKey is the attribute Key conforming\n\t// to the \"db.cassandra.speculative_execution_count\" semantic conventions.\n\t// It represents the number of times a query was speculatively executed.\n\t// Not set or `0` if the query was not executed speculatively.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 0, 2\n\tDBCassandraSpeculativeExecutionCountKey = attribute.Key(\"db.cassandra.speculative_execution_count\")\n\n\t// DBCassandraCoordinatorIDKey is the attribute Key conforming to the\n\t// \"db.cassandra.coordinator.id\" semantic conventions. It represents the ID\n\t// of the coordinating node for a query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af'\n\tDBCassandraCoordinatorIDKey = attribute.Key(\"db.cassandra.coordinator.id\")\n\n\t// DBCassandraCoordinatorDCKey is the attribute Key conforming to the\n\t// \"db.cassandra.coordinator.dc\" semantic conventions. It represents the\n\t// data center of the coordinating node for a query.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'us-west-2'\n\tDBCassandraCoordinatorDCKey = attribute.Key(\"db.cassandra.coordinator.dc\")\n)\n\nvar (\n\t// all\n\tDBCassandraConsistencyLevelAll = DBCassandraConsistencyLevelKey.String(\"all\")\n\t// each_quorum\n\tDBCassandraConsistencyLevelEachQuorum = DBCassandraConsistencyLevelKey.String(\"each_quorum\")\n\t// quorum\n\tDBCassandraConsistencyLevelQuorum = DBCassandraConsistencyLevelKey.String(\"quorum\")\n\t// local_quorum\n\tDBCassandraConsistencyLevelLocalQuorum = DBCassandraConsistencyLevelKey.String(\"local_quorum\")\n\t// one\n\tDBCassandraConsistencyLevelOne = DBCassandraConsistencyLevelKey.String(\"one\")\n\t// two\n\tDBCassandraConsistencyLevelTwo = DBCassandraConsistencyLevelKey.String(\"two\")\n\t// three\n\tDBCassandraConsistencyLevelThree = DBCassandraConsistencyLevelKey.String(\"three\")\n\t// local_one\n\tDBCassandraConsistencyLevelLocalOne = DBCassandraConsistencyLevelKey.String(\"local_one\")\n\t// any\n\tDBCassandraConsistencyLevelAny = DBCassandraConsistencyLevelKey.String(\"any\")\n\t// serial\n\tDBCassandraConsistencyLevelSerial = DBCassandraConsistencyLevelKey.String(\"serial\")\n\t// local_serial\n\tDBCassandraConsistencyLevelLocalSerial = DBCassandraConsistencyLevelKey.String(\"local_serial\")\n)\n\n// DBCassandraPageSize returns an attribute KeyValue conforming to the\n// \"db.cassandra.page_size\" semantic conventions. It represents the fetch size\n// used for paging, i.e. how many rows will be returned at once.\nfunc DBCassandraPageSize(val int) attribute.KeyValue {\n\treturn DBCassandraPageSizeKey.Int(val)\n}\n\n// DBCassandraTable returns an attribute KeyValue conforming to the\n// \"db.cassandra.table\" semantic conventions. It represents the name of the\n// primary table that the operation is acting upon, including the keyspace name\n// (if applicable).\nfunc DBCassandraTable(val string) attribute.KeyValue {\n\treturn DBCassandraTableKey.String(val)\n}\n\n// DBCassandraIdempotence returns an attribute KeyValue conforming to the\n// \"db.cassandra.idempotence\" semantic conventions. It represents the whether\n// or not the query is idempotent.\nfunc DBCassandraIdempotence(val bool) attribute.KeyValue {\n\treturn DBCassandraIdempotenceKey.Bool(val)\n}\n\n// DBCassandraSpeculativeExecutionCount returns an attribute KeyValue\n// conforming to the \"db.cassandra.speculative_execution_count\" semantic\n// conventions. It represents the number of times a query was speculatively\n// executed. Not set or `0` if the query was not executed speculatively.\nfunc DBCassandraSpeculativeExecutionCount(val int) attribute.KeyValue {\n\treturn DBCassandraSpeculativeExecutionCountKey.Int(val)\n}\n\n// DBCassandraCoordinatorID returns an attribute KeyValue conforming to the\n// \"db.cassandra.coordinator.id\" semantic conventions. It represents the ID of\n// the coordinating node for a query.\nfunc DBCassandraCoordinatorID(val string) attribute.KeyValue {\n\treturn DBCassandraCoordinatorIDKey.String(val)\n}\n\n// DBCassandraCoordinatorDC returns an attribute KeyValue conforming to the\n// \"db.cassandra.coordinator.dc\" semantic conventions. It represents the data\n// center of the coordinating node for a query.\nfunc DBCassandraCoordinatorDC(val string) attribute.KeyValue {\n\treturn DBCassandraCoordinatorDCKey.String(val)\n}\n\n// Call-level attributes for Redis\nconst (\n\t// DBRedisDBIndexKey is the attribute Key conforming to the\n\t// \"db.redis.database_index\" semantic conventions. It represents the index\n\t// of the database being accessed as used in the [`SELECT`\n\t// command](https://redis.io/commands/select), provided as an integer. To\n\t// be used instead of the generic `db.name` attribute.\n\t//\n\t// Type: int\n\t// RequirementLevel: ConditionallyRequired (If other than the default\n\t// database (`0`).)\n\t// Stability: stable\n\t// Examples: 0, 1, 15\n\tDBRedisDBIndexKey = attribute.Key(\"db.redis.database_index\")\n)\n\n// DBRedisDBIndex returns an attribute KeyValue conforming to the\n// \"db.redis.database_index\" semantic conventions. It represents the index of\n// the database being accessed as used in the [`SELECT`\n// command](https://redis.io/commands/select), provided as an integer. To be\n// used instead of the generic `db.name` attribute.\nfunc DBRedisDBIndex(val int) attribute.KeyValue {\n\treturn DBRedisDBIndexKey.Int(val)\n}\n\n// Call-level attributes for MongoDB\nconst (\n\t// DBMongoDBCollectionKey is the attribute Key conforming to the\n\t// \"db.mongodb.collection\" semantic conventions. It represents the\n\t// collection being accessed within the database stated in `db.name`.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'customers', 'products'\n\tDBMongoDBCollectionKey = attribute.Key(\"db.mongodb.collection\")\n)\n\n// DBMongoDBCollection returns an attribute KeyValue conforming to the\n// \"db.mongodb.collection\" semantic conventions. It represents the collection\n// being accessed within the database stated in `db.name`.\nfunc DBMongoDBCollection(val string) attribute.KeyValue {\n\treturn DBMongoDBCollectionKey.String(val)\n}\n\n// Call-level attributes for SQL databases\nconst (\n\t// DBSQLTableKey is the attribute Key conforming to the \"db.sql.table\"\n\t// semantic conventions. It represents the name of the primary table that\n\t// the operation is acting upon, including the database name (if\n\t// applicable).\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: stable\n\t// Examples: 'public.users', 'customers'\n\t// Note: It is not recommended to attempt any client-side parsing of\n\t// `db.statement` just to get this property, but it should be set if it is\n\t// provided by the library being instrumented. If the operation is acting\n\t// upon an anonymous table, or more than one table, this value MUST NOT be\n\t// set.\n\tDBSQLTableKey = attribute.Key(\"db.sql.table\")\n)\n\n// DBSQLTable returns an attribute KeyValue conforming to the \"db.sql.table\"\n// semantic conventions. It represents the name of the primary table that the\n// operation is acting upon, including the database name (if applicable).\nfunc DBSQLTable(val string) attribute.KeyValue {\n\treturn DBSQLTableKey.String(val)\n}\n\n// Span attributes used by non-OTLP exporters to represent OpenTelemetry Span's\n// concepts.\nconst (\n\t// OtelStatusCodeKey is the attribute Key conforming to the\n\t// \"otel.status_code\" semantic conventions. It represents the name of the\n\t// code, either \"OK\" or \"ERROR\". MUST NOT be set if the status code is\n\t// UNSET.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tOtelStatusCodeKey = attribute.Key(\"otel.status_code\")\n\n\t// OtelStatusDescriptionKey is the attribute Key conforming to the\n\t// \"otel.status_description\" semantic conventions. It represents the\n\t// description of the Status if it has a value, otherwise not set.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'resource not found'\n\tOtelStatusDescriptionKey = attribute.Key(\"otel.status_description\")\n)\n\nvar (\n\t// The operation has been validated by an Application developer or Operator to have completed successfully\n\tOtelStatusCodeOk = OtelStatusCodeKey.String(\"OK\")\n\t// The operation contains an error\n\tOtelStatusCodeError = OtelStatusCodeKey.String(\"ERROR\")\n)\n\n// OtelStatusDescription returns an attribute KeyValue conforming to the\n// \"otel.status_description\" semantic conventions. It represents the\n// description of the Status if it has a value, otherwise not set.\nfunc OtelStatusDescription(val string) attribute.KeyValue {\n\treturn OtelStatusDescriptionKey.String(val)\n}\n\n// This semantic convention describes an instance of a function that runs\n// without provisioning or managing of servers (also known as serverless\n// functions or Function as a Service (FaaS)) with spans.\nconst (\n\t// FaaSTriggerKey is the attribute Key conforming to the \"faas.trigger\"\n\t// semantic conventions. It represents the type of the trigger which caused\n\t// this function execution.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Note: For the server/consumer span on the incoming side,\n\t// `faas.trigger` MUST be set.\n\t//\n\t// Clients invoking FaaS instances usually cannot set `faas.trigger`,\n\t// since they would typically need to look in the payload to determine\n\t// the event type. If clients set it, it should be the same as the\n\t// trigger that corresponding incoming would have (i.e., this has\n\t// nothing to do with the underlying transport used to make the API\n\t// call to invoke the lambda, which is often HTTP).\n\tFaaSTriggerKey = attribute.Key(\"faas.trigger\")\n\n\t// FaaSExecutionKey is the attribute Key conforming to the \"faas.execution\"\n\t// semantic conventions. It represents the execution ID of the current\n\t// function execution.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28'\n\tFaaSExecutionKey = attribute.Key(\"faas.execution\")\n)\n\nvar (\n\t// A response to some data source operation such as a database or filesystem read/write\n\tFaaSTriggerDatasource = FaaSTriggerKey.String(\"datasource\")\n\t// To provide an answer to an inbound HTTP request\n\tFaaSTriggerHTTP = FaaSTriggerKey.String(\"http\")\n\t// A function is set to be executed when messages are sent to a messaging system\n\tFaaSTriggerPubsub = FaaSTriggerKey.String(\"pubsub\")\n\t// A function is scheduled to be executed regularly\n\tFaaSTriggerTimer = FaaSTriggerKey.String(\"timer\")\n\t// If none of the others apply\n\tFaaSTriggerOther = FaaSTriggerKey.String(\"other\")\n)\n\n// FaaSExecution returns an attribute KeyValue conforming to the\n// \"faas.execution\" semantic conventions. It represents the execution ID of the\n// current function execution.\nfunc FaaSExecution(val string) attribute.KeyValue {\n\treturn FaaSExecutionKey.String(val)\n}\n\n// Semantic Convention for FaaS triggered as a response to some data source\n// operation such as a database or filesystem read/write.\nconst (\n\t// FaaSDocumentCollectionKey is the attribute Key conforming to the\n\t// \"faas.document.collection\" semantic conventions. It represents the name\n\t// of the source on which the triggering operation was performed. For\n\t// example, in Cloud Storage or S3 corresponds to the bucket name, and in\n\t// Cosmos DB to the database name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'myBucketName', 'myDBName'\n\tFaaSDocumentCollectionKey = attribute.Key(\"faas.document.collection\")\n\n\t// FaaSDocumentOperationKey is the attribute Key conforming to the\n\t// \"faas.document.operation\" semantic conventions. It represents the\n\t// describes the type of the operation that was performed on the data.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\tFaaSDocumentOperationKey = attribute.Key(\"faas.document.operation\")\n\n\t// FaaSDocumentTimeKey is the attribute Key conforming to the\n\t// \"faas.document.time\" semantic conventions. It represents a string\n\t// containing the time when the data was accessed in the [ISO\n\t// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format\n\t// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '2020-01-23T13:47:06Z'\n\tFaaSDocumentTimeKey = attribute.Key(\"faas.document.time\")\n\n\t// FaaSDocumentNameKey is the attribute Key conforming to the\n\t// \"faas.document.name\" semantic conventions. It represents the document\n\t// name/table subjected to the operation. For example, in Cloud Storage or\n\t// S3 is the name of the file, and in Cosmos DB the table name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'myFile.txt', 'myTableName'\n\tFaaSDocumentNameKey = attribute.Key(\"faas.document.name\")\n)\n\nvar (\n\t// When a new object is created\n\tFaaSDocumentOperationInsert = FaaSDocumentOperationKey.String(\"insert\")\n\t// When an object is modified\n\tFaaSDocumentOperationEdit = FaaSDocumentOperationKey.String(\"edit\")\n\t// When an object is deleted\n\tFaaSDocumentOperationDelete = FaaSDocumentOperationKey.String(\"delete\")\n)\n\n// FaaSDocumentCollection returns an attribute KeyValue conforming to the\n// \"faas.document.collection\" semantic conventions. It represents the name of\n// the source on which the triggering operation was performed. For example, in\n// Cloud Storage or S3 corresponds to the bucket name, and in Cosmos DB to the\n// database name.\nfunc FaaSDocumentCollection(val string) attribute.KeyValue {\n\treturn FaaSDocumentCollectionKey.String(val)\n}\n\n// FaaSDocumentTime returns an attribute KeyValue conforming to the\n// \"faas.document.time\" semantic conventions. It represents a string containing\n// the time when the data was accessed in the [ISO\n// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format\n// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).\nfunc FaaSDocumentTime(val string) attribute.KeyValue {\n\treturn FaaSDocumentTimeKey.String(val)\n}\n\n// FaaSDocumentName returns an attribute KeyValue conforming to the\n// \"faas.document.name\" semantic conventions. It represents the document\n// name/table subjected to the operation. For example, in Cloud Storage or S3\n// is the name of the file, and in Cosmos DB the table name.\nfunc FaaSDocumentName(val string) attribute.KeyValue {\n\treturn FaaSDocumentNameKey.String(val)\n}\n\n// Semantic Convention for FaaS scheduled to be executed regularly.\nconst (\n\t// FaaSTimeKey is the attribute Key conforming to the \"faas.time\" semantic\n\t// conventions. It represents a string containing the function invocation\n\t// time in the [ISO\n\t// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format\n\t// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '2020-01-23T13:47:06Z'\n\tFaaSTimeKey = attribute.Key(\"faas.time\")\n\n\t// FaaSCronKey is the attribute Key conforming to the \"faas.cron\" semantic\n\t// conventions. It represents a string containing the schedule period as\n\t// [Cron\n\t// Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '0/5 * * * ? *'\n\tFaaSCronKey = attribute.Key(\"faas.cron\")\n)\n\n// FaaSTime returns an attribute KeyValue conforming to the \"faas.time\"\n// semantic conventions. It represents a string containing the function\n// invocation time in the [ISO\n// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format\n// expressed in [UTC](https://www.w3.org/TR/NOTE-datetime).\nfunc FaaSTime(val string) attribute.KeyValue {\n\treturn FaaSTimeKey.String(val)\n}\n\n// FaaSCron returns an attribute KeyValue conforming to the \"faas.cron\"\n// semantic conventions. It represents a string containing the schedule period\n// as [Cron\n// Expression](https://docs.oracle.com/cd/E12058_01/doc/doc.1014/e12030/cron_expressions.htm).\nfunc FaaSCron(val string) attribute.KeyValue {\n\treturn FaaSCronKey.String(val)\n}\n\n// Contains additional attributes for incoming FaaS spans.\nconst (\n\t// FaaSColdstartKey is the attribute Key conforming to the \"faas.coldstart\"\n\t// semantic conventions. It represents a boolean that is true if the\n\t// serverless function is executed for the first time (aka cold-start).\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tFaaSColdstartKey = attribute.Key(\"faas.coldstart\")\n)\n\n// FaaSColdstart returns an attribute KeyValue conforming to the\n// \"faas.coldstart\" semantic conventions. It represents a boolean that is true\n// if the serverless function is executed for the first time (aka cold-start).\nfunc FaaSColdstart(val bool) attribute.KeyValue {\n\treturn FaaSColdstartKey.Bool(val)\n}\n\n// Contains additional attributes for outgoing FaaS spans.\nconst (\n\t// FaaSInvokedNameKey is the attribute Key conforming to the\n\t// \"faas.invoked_name\" semantic conventions. It represents the name of the\n\t// invoked function.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'my-function'\n\t// Note: SHOULD be equal to the `faas.name` resource attribute of the\n\t// invoked function.\n\tFaaSInvokedNameKey = attribute.Key(\"faas.invoked_name\")\n\n\t// FaaSInvokedProviderKey is the attribute Key conforming to the\n\t// \"faas.invoked_provider\" semantic conventions. It represents the cloud\n\t// provider of the invoked function.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Note: SHOULD be equal to the `cloud.provider` resource attribute of the\n\t// invoked function.\n\tFaaSInvokedProviderKey = attribute.Key(\"faas.invoked_provider\")\n\n\t// FaaSInvokedRegionKey is the attribute Key conforming to the\n\t// \"faas.invoked_region\" semantic conventions. It represents the cloud\n\t// region of the invoked function.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (For some cloud providers, like\n\t// AWS or GCP, the region in which a function is hosted is essential to\n\t// uniquely identify the function and also part of its endpoint. Since it's\n\t// part of the endpoint being called, the region is always known to\n\t// clients. In these cases, `faas.invoked_region` MUST be set accordingly.\n\t// If the region is unknown to the client or not required for identifying\n\t// the invoked function, setting `faas.invoked_region` is optional.)\n\t// Stability: stable\n\t// Examples: 'eu-central-1'\n\t// Note: SHOULD be equal to the `cloud.region` resource attribute of the\n\t// invoked function.\n\tFaaSInvokedRegionKey = attribute.Key(\"faas.invoked_region\")\n)\n\nvar (\n\t// Alibaba Cloud\n\tFaaSInvokedProviderAlibabaCloud = FaaSInvokedProviderKey.String(\"alibaba_cloud\")\n\t// Amazon Web Services\n\tFaaSInvokedProviderAWS = FaaSInvokedProviderKey.String(\"aws\")\n\t// Microsoft Azure\n\tFaaSInvokedProviderAzure = FaaSInvokedProviderKey.String(\"azure\")\n\t// Google Cloud Platform\n\tFaaSInvokedProviderGCP = FaaSInvokedProviderKey.String(\"gcp\")\n\t// Tencent Cloud\n\tFaaSInvokedProviderTencentCloud = FaaSInvokedProviderKey.String(\"tencent_cloud\")\n)\n\n// FaaSInvokedName returns an attribute KeyValue conforming to the\n// \"faas.invoked_name\" semantic conventions. It represents the name of the\n// invoked function.\nfunc FaaSInvokedName(val string) attribute.KeyValue {\n\treturn FaaSInvokedNameKey.String(val)\n}\n\n// FaaSInvokedRegion returns an attribute KeyValue conforming to the\n// \"faas.invoked_region\" semantic conventions. It represents the cloud region\n// of the invoked function.\nfunc FaaSInvokedRegion(val string) attribute.KeyValue {\n\treturn FaaSInvokedRegionKey.String(val)\n}\n\n// These attributes may be used for any network related operation.\nconst (\n\t// NetTransportKey is the attribute Key conforming to the \"net.transport\"\n\t// semantic conventions. It represents the transport protocol used. See\n\t// note below.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tNetTransportKey = attribute.Key(\"net.transport\")\n\n\t// NetAppProtocolNameKey is the attribute Key conforming to the\n\t// \"net.app.protocol.name\" semantic conventions. It represents the\n\t// application layer protocol used. The value SHOULD be normalized to\n\t// lowercase.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'amqp', 'http', 'mqtt'\n\tNetAppProtocolNameKey = attribute.Key(\"net.app.protocol.name\")\n\n\t// NetAppProtocolVersionKey is the attribute Key conforming to the\n\t// \"net.app.protocol.version\" semantic conventions. It represents the\n\t// version of the application layer protocol used. See note below.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '3.1.1'\n\t// Note: `net.app.protocol.version` refers to the version of the protocol\n\t// used and might be different from the protocol client's version. If the\n\t// HTTP client used has a version of `0.27.2`, but sends HTTP version\n\t// `1.1`, this attribute should be set to `1.1`.\n\tNetAppProtocolVersionKey = attribute.Key(\"net.app.protocol.version\")\n\n\t// NetSockPeerNameKey is the attribute Key conforming to the\n\t// \"net.sock.peer.name\" semantic conventions. It represents the remote\n\t// socket peer name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended (If available and different from\n\t// `net.peer.name` and if `net.sock.peer.addr` is set.)\n\t// Stability: stable\n\t// Examples: 'proxy.example.com'\n\tNetSockPeerNameKey = attribute.Key(\"net.sock.peer.name\")\n\n\t// NetSockPeerAddrKey is the attribute Key conforming to the\n\t// \"net.sock.peer.addr\" semantic conventions. It represents the remote\n\t// socket peer address: IPv4 or IPv6 for internet protocols, path for local\n\t// communication,\n\t// [etc](https://man7.org/linux/man-pages/man7/address_families.7.html).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '127.0.0.1', '/tmp/mysql.sock'\n\tNetSockPeerAddrKey = attribute.Key(\"net.sock.peer.addr\")\n\n\t// NetSockPeerPortKey is the attribute Key conforming to the\n\t// \"net.sock.peer.port\" semantic conventions. It represents the remote\n\t// socket peer port.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended (If defined for the address family and if\n\t// different than `net.peer.port` and if `net.sock.peer.addr` is set.)\n\t// Stability: stable\n\t// Examples: 16456\n\tNetSockPeerPortKey = attribute.Key(\"net.sock.peer.port\")\n\n\t// NetSockFamilyKey is the attribute Key conforming to the\n\t// \"net.sock.family\" semantic conventions. It represents the protocol\n\t// [address\n\t// family](https://man7.org/linux/man-pages/man7/address_families.7.html)\n\t// which is used for communication.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: ConditionallyRequired (If different than `inet` and if\n\t// any of `net.sock.peer.addr` or `net.sock.host.addr` are set. Consumers\n\t// of telemetry SHOULD accept both IPv4 and IPv6 formats for the address in\n\t// `net.sock.peer.addr` if `net.sock.family` is not set. This is to support\n\t// instrumentations that follow previous versions of this document.)\n\t// Stability: stable\n\t// Examples: 'inet6', 'bluetooth'\n\tNetSockFamilyKey = attribute.Key(\"net.sock.family\")\n\n\t// NetPeerNameKey is the attribute Key conforming to the \"net.peer.name\"\n\t// semantic conventions. It represents the logical remote hostname, see\n\t// note below.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'example.com'\n\t// Note: `net.peer.name` SHOULD NOT be set if capturing it would require an\n\t// extra DNS lookup.\n\tNetPeerNameKey = attribute.Key(\"net.peer.name\")\n\n\t// NetPeerPortKey is the attribute Key conforming to the \"net.peer.port\"\n\t// semantic conventions. It represents the logical remote port number\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 80, 8080, 443\n\tNetPeerPortKey = attribute.Key(\"net.peer.port\")\n\n\t// NetHostNameKey is the attribute Key conforming to the \"net.host.name\"\n\t// semantic conventions. It represents the logical local hostname or\n\t// similar, see note below.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'localhost'\n\tNetHostNameKey = attribute.Key(\"net.host.name\")\n\n\t// NetHostPortKey is the attribute Key conforming to the \"net.host.port\"\n\t// semantic conventions. It represents the logical local port number,\n\t// preferably the one that the peer used to connect\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 8080\n\tNetHostPortKey = attribute.Key(\"net.host.port\")\n\n\t// NetSockHostAddrKey is the attribute Key conforming to the\n\t// \"net.sock.host.addr\" semantic conventions. It represents the local\n\t// socket address. Useful in case of a multi-IP host.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '192.168.0.1'\n\tNetSockHostAddrKey = attribute.Key(\"net.sock.host.addr\")\n\n\t// NetSockHostPortKey is the attribute Key conforming to the\n\t// \"net.sock.host.port\" semantic conventions. It represents the local\n\t// socket port number.\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended (If defined for the address family and if\n\t// different than `net.host.port` and if `net.sock.host.addr` is set.)\n\t// Stability: stable\n\t// Examples: 35555\n\tNetSockHostPortKey = attribute.Key(\"net.sock.host.port\")\n\n\t// NetHostConnectionTypeKey is the attribute Key conforming to the\n\t// \"net.host.connection.type\" semantic conventions. It represents the\n\t// internet connection type currently being used by the host.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'wifi'\n\tNetHostConnectionTypeKey = attribute.Key(\"net.host.connection.type\")\n\n\t// NetHostConnectionSubtypeKey is the attribute Key conforming to the\n\t// \"net.host.connection.subtype\" semantic conventions. It represents the\n\t// this describes more details regarding the connection.type. It may be the\n\t// type of cell technology connection, but it could be used for describing\n\t// details about a wifi connection.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'LTE'\n\tNetHostConnectionSubtypeKey = attribute.Key(\"net.host.connection.subtype\")\n\n\t// NetHostCarrierNameKey is the attribute Key conforming to the\n\t// \"net.host.carrier.name\" semantic conventions. It represents the name of\n\t// the mobile carrier.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'sprint'\n\tNetHostCarrierNameKey = attribute.Key(\"net.host.carrier.name\")\n\n\t// NetHostCarrierMccKey is the attribute Key conforming to the\n\t// \"net.host.carrier.mcc\" semantic conventions. It represents the mobile\n\t// carrier country code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '310'\n\tNetHostCarrierMccKey = attribute.Key(\"net.host.carrier.mcc\")\n\n\t// NetHostCarrierMncKey is the attribute Key conforming to the\n\t// \"net.host.carrier.mnc\" semantic conventions. It represents the mobile\n\t// carrier network code.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '001'\n\tNetHostCarrierMncKey = attribute.Key(\"net.host.carrier.mnc\")\n\n\t// NetHostCarrierIccKey is the attribute Key conforming to the\n\t// \"net.host.carrier.icc\" semantic conventions. It represents the ISO\n\t// 3166-1 alpha-2 2-character country code associated with the mobile\n\t// carrier network.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'DE'\n\tNetHostCarrierIccKey = attribute.Key(\"net.host.carrier.icc\")\n)\n\nvar (\n\t// ip_tcp\n\tNetTransportTCP = NetTransportKey.String(\"ip_tcp\")\n\t// ip_udp\n\tNetTransportUDP = NetTransportKey.String(\"ip_udp\")\n\t// Named or anonymous pipe. See note below\n\tNetTransportPipe = NetTransportKey.String(\"pipe\")\n\t// In-process communication\n\tNetTransportInProc = NetTransportKey.String(\"inproc\")\n\t// Something else (non IP-based)\n\tNetTransportOther = NetTransportKey.String(\"other\")\n)\n\nvar (\n\t// IPv4 address\n\tNetSockFamilyInet = NetSockFamilyKey.String(\"inet\")\n\t// IPv6 address\n\tNetSockFamilyInet6 = NetSockFamilyKey.String(\"inet6\")\n\t// Unix domain socket path\n\tNetSockFamilyUnix = NetSockFamilyKey.String(\"unix\")\n)\n\nvar (\n\t// wifi\n\tNetHostConnectionTypeWifi = NetHostConnectionTypeKey.String(\"wifi\")\n\t// wired\n\tNetHostConnectionTypeWired = NetHostConnectionTypeKey.String(\"wired\")\n\t// cell\n\tNetHostConnectionTypeCell = NetHostConnectionTypeKey.String(\"cell\")\n\t// unavailable\n\tNetHostConnectionTypeUnavailable = NetHostConnectionTypeKey.String(\"unavailable\")\n\t// unknown\n\tNetHostConnectionTypeUnknown = NetHostConnectionTypeKey.String(\"unknown\")\n)\n\nvar (\n\t// GPRS\n\tNetHostConnectionSubtypeGprs = NetHostConnectionSubtypeKey.String(\"gprs\")\n\t// EDGE\n\tNetHostConnectionSubtypeEdge = NetHostConnectionSubtypeKey.String(\"edge\")\n\t// UMTS\n\tNetHostConnectionSubtypeUmts = NetHostConnectionSubtypeKey.String(\"umts\")\n\t// CDMA\n\tNetHostConnectionSubtypeCdma = NetHostConnectionSubtypeKey.String(\"cdma\")\n\t// EVDO Rel. 0\n\tNetHostConnectionSubtypeEvdo0 = NetHostConnectionSubtypeKey.String(\"evdo_0\")\n\t// EVDO Rev. A\n\tNetHostConnectionSubtypeEvdoA = NetHostConnectionSubtypeKey.String(\"evdo_a\")\n\t// CDMA2000 1XRTT\n\tNetHostConnectionSubtypeCdma20001xrtt = NetHostConnectionSubtypeKey.String(\"cdma2000_1xrtt\")\n\t// HSDPA\n\tNetHostConnectionSubtypeHsdpa = NetHostConnectionSubtypeKey.String(\"hsdpa\")\n\t// HSUPA\n\tNetHostConnectionSubtypeHsupa = NetHostConnectionSubtypeKey.String(\"hsupa\")\n\t// HSPA\n\tNetHostConnectionSubtypeHspa = NetHostConnectionSubtypeKey.String(\"hspa\")\n\t// IDEN\n\tNetHostConnectionSubtypeIden = NetHostConnectionSubtypeKey.String(\"iden\")\n\t// EVDO Rev. B\n\tNetHostConnectionSubtypeEvdoB = NetHostConnectionSubtypeKey.String(\"evdo_b\")\n\t// LTE\n\tNetHostConnectionSubtypeLte = NetHostConnectionSubtypeKey.String(\"lte\")\n\t// EHRPD\n\tNetHostConnectionSubtypeEhrpd = NetHostConnectionSubtypeKey.String(\"ehrpd\")\n\t// HSPAP\n\tNetHostConnectionSubtypeHspap = NetHostConnectionSubtypeKey.String(\"hspap\")\n\t// GSM\n\tNetHostConnectionSubtypeGsm = NetHostConnectionSubtypeKey.String(\"gsm\")\n\t// TD-SCDMA\n\tNetHostConnectionSubtypeTdScdma = NetHostConnectionSubtypeKey.String(\"td_scdma\")\n\t// IWLAN\n\tNetHostConnectionSubtypeIwlan = NetHostConnectionSubtypeKey.String(\"iwlan\")\n\t// 5G NR (New Radio)\n\tNetHostConnectionSubtypeNr = NetHostConnectionSubtypeKey.String(\"nr\")\n\t// 5G NRNSA (New Radio Non-Standalone)\n\tNetHostConnectionSubtypeNrnsa = NetHostConnectionSubtypeKey.String(\"nrnsa\")\n\t// LTE CA\n\tNetHostConnectionSubtypeLteCa = NetHostConnectionSubtypeKey.String(\"lte_ca\")\n)\n\n// NetAppProtocolName returns an attribute KeyValue conforming to the\n// \"net.app.protocol.name\" semantic conventions. It represents the application\n// layer protocol used. The value SHOULD be normalized to lowercase.\nfunc NetAppProtocolName(val string) attribute.KeyValue {\n\treturn NetAppProtocolNameKey.String(val)\n}\n\n// NetAppProtocolVersion returns an attribute KeyValue conforming to the\n// \"net.app.protocol.version\" semantic conventions. It represents the version\n// of the application layer protocol used. See note below.\nfunc NetAppProtocolVersion(val string) attribute.KeyValue {\n\treturn NetAppProtocolVersionKey.String(val)\n}\n\n// NetSockPeerName returns an attribute KeyValue conforming to the\n// \"net.sock.peer.name\" semantic conventions. It represents the remote socket\n// peer name.\nfunc NetSockPeerName(val string) attribute.KeyValue {\n\treturn NetSockPeerNameKey.String(val)\n}\n\n// NetSockPeerAddr returns an attribute KeyValue conforming to the\n// \"net.sock.peer.addr\" semantic conventions. It represents the remote socket\n// peer address: IPv4 or IPv6 for internet protocols, path for local\n// communication,\n// [etc](https://man7.org/linux/man-pages/man7/address_families.7.html).\nfunc NetSockPeerAddr(val string) attribute.KeyValue {\n\treturn NetSockPeerAddrKey.String(val)\n}\n\n// NetSockPeerPort returns an attribute KeyValue conforming to the\n// \"net.sock.peer.port\" semantic conventions. It represents the remote socket\n// peer port.\nfunc NetSockPeerPort(val int) attribute.KeyValue {\n\treturn NetSockPeerPortKey.Int(val)\n}\n\n// NetPeerName returns an attribute KeyValue conforming to the\n// \"net.peer.name\" semantic conventions. It represents the logical remote\n// hostname, see note below.\nfunc NetPeerName(val string) attribute.KeyValue {\n\treturn NetPeerNameKey.String(val)\n}\n\n// NetPeerPort returns an attribute KeyValue conforming to the\n// \"net.peer.port\" semantic conventions. It represents the logical remote port\n// number\nfunc NetPeerPort(val int) attribute.KeyValue {\n\treturn NetPeerPortKey.Int(val)\n}\n\n// NetHostName returns an attribute KeyValue conforming to the\n// \"net.host.name\" semantic conventions. It represents the logical local\n// hostname or similar, see note below.\nfunc NetHostName(val string) attribute.KeyValue {\n\treturn NetHostNameKey.String(val)\n}\n\n// NetHostPort returns an attribute KeyValue conforming to the\n// \"net.host.port\" semantic conventions. It represents the logical local port\n// number, preferably the one that the peer used to connect\nfunc NetHostPort(val int) attribute.KeyValue {\n\treturn NetHostPortKey.Int(val)\n}\n\n// NetSockHostAddr returns an attribute KeyValue conforming to the\n// \"net.sock.host.addr\" semantic conventions. It represents the local socket\n// address. Useful in case of a multi-IP host.\nfunc NetSockHostAddr(val string) attribute.KeyValue {\n\treturn NetSockHostAddrKey.String(val)\n}\n\n// NetSockHostPort returns an attribute KeyValue conforming to the\n// \"net.sock.host.port\" semantic conventions. It represents the local socket\n// port number.\nfunc NetSockHostPort(val int) attribute.KeyValue {\n\treturn NetSockHostPortKey.Int(val)\n}\n\n// NetHostCarrierName returns an attribute KeyValue conforming to the\n// \"net.host.carrier.name\" semantic conventions. It represents the name of the\n// mobile carrier.\nfunc NetHostCarrierName(val string) attribute.KeyValue {\n\treturn NetHostCarrierNameKey.String(val)\n}\n\n// NetHostCarrierMcc returns an attribute KeyValue conforming to the\n// \"net.host.carrier.mcc\" semantic conventions. It represents the mobile\n// carrier country code.\nfunc NetHostCarrierMcc(val string) attribute.KeyValue {\n\treturn NetHostCarrierMccKey.String(val)\n}\n\n// NetHostCarrierMnc returns an attribute KeyValue conforming to the\n// \"net.host.carrier.mnc\" semantic conventions. It represents the mobile\n// carrier network code.\nfunc NetHostCarrierMnc(val string) attribute.KeyValue {\n\treturn NetHostCarrierMncKey.String(val)\n}\n\n// NetHostCarrierIcc returns an attribute KeyValue conforming to the\n// \"net.host.carrier.icc\" semantic conventions. It represents the ISO 3166-1\n// alpha-2 2-character country code associated with the mobile carrier network.\nfunc NetHostCarrierIcc(val string) attribute.KeyValue {\n\treturn NetHostCarrierIccKey.String(val)\n}\n\n// Operations that access some remote service.\nconst (\n\t// PeerServiceKey is the attribute Key conforming to the \"peer.service\"\n\t// semantic conventions. It represents the\n\t// [`service.name`](../../resource/semantic_conventions/README.md#service)\n\t// of the remote service. SHOULD be equal to the actual `service.name`\n\t// resource attribute of the remote service if any.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'AuthTokenCache'\n\tPeerServiceKey = attribute.Key(\"peer.service\")\n)\n\n// PeerService returns an attribute KeyValue conforming to the\n// \"peer.service\" semantic conventions. It represents the\n// [`service.name`](../../resource/semantic_conventions/README.md#service) of\n// the remote service. SHOULD be equal to the actual `service.name` resource\n// attribute of the remote service if any.\nfunc PeerService(val string) attribute.KeyValue {\n\treturn PeerServiceKey.String(val)\n}\n\n// These attributes may be used for any operation with an authenticated and/or\n// authorized enduser.\nconst (\n\t// EnduserIDKey is the attribute Key conforming to the \"enduser.id\"\n\t// semantic conventions. It represents the username or client_id extracted\n\t// from the access token or\n\t// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header\n\t// in the inbound request from outside the system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'username'\n\tEnduserIDKey = attribute.Key(\"enduser.id\")\n\n\t// EnduserRoleKey is the attribute Key conforming to the \"enduser.role\"\n\t// semantic conventions. It represents the actual/assumed role the client\n\t// is making the request under extracted from token or application security\n\t// context.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'admin'\n\tEnduserRoleKey = attribute.Key(\"enduser.role\")\n\n\t// EnduserScopeKey is the attribute Key conforming to the \"enduser.scope\"\n\t// semantic conventions. It represents the scopes or granted authorities\n\t// the client currently possesses extracted from token or application\n\t// security context. The value would come from the scope associated with an\n\t// [OAuth 2.0 Access\n\t// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute\n\t// value in a [SAML 2.0\n\t// Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'read:message, write:files'\n\tEnduserScopeKey = attribute.Key(\"enduser.scope\")\n)\n\n// EnduserID returns an attribute KeyValue conforming to the \"enduser.id\"\n// semantic conventions. It represents the username or client_id extracted from\n// the access token or\n// [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in\n// the inbound request from outside the system.\nfunc EnduserID(val string) attribute.KeyValue {\n\treturn EnduserIDKey.String(val)\n}\n\n// EnduserRole returns an attribute KeyValue conforming to the\n// \"enduser.role\" semantic conventions. It represents the actual/assumed role\n// the client is making the request under extracted from token or application\n// security context.\nfunc EnduserRole(val string) attribute.KeyValue {\n\treturn EnduserRoleKey.String(val)\n}\n\n// EnduserScope returns an attribute KeyValue conforming to the\n// \"enduser.scope\" semantic conventions. It represents the scopes or granted\n// authorities the client currently possesses extracted from token or\n// application security context. The value would come from the scope associated\n// with an [OAuth 2.0 Access\n// Token](https://tools.ietf.org/html/rfc6749#section-3.3) or an attribute\n// value in a [SAML 2.0\n// Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).\nfunc EnduserScope(val string) attribute.KeyValue {\n\treturn EnduserScopeKey.String(val)\n}\n\n// These attributes may be used for any operation to store information about a\n// thread that started a span.\nconst (\n\t// ThreadIDKey is the attribute Key conforming to the \"thread.id\" semantic\n\t// conventions. It represents the current \"managed\" thread ID (as opposed\n\t// to OS thread ID).\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 42\n\tThreadIDKey = attribute.Key(\"thread.id\")\n\n\t// ThreadNameKey is the attribute Key conforming to the \"thread.name\"\n\t// semantic conventions. It represents the current thread name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'main'\n\tThreadNameKey = attribute.Key(\"thread.name\")\n)\n\n// ThreadID returns an attribute KeyValue conforming to the \"thread.id\"\n// semantic conventions. It represents the current \"managed\" thread ID (as\n// opposed to OS thread ID).\nfunc ThreadID(val int) attribute.KeyValue {\n\treturn ThreadIDKey.Int(val)\n}\n\n// ThreadName returns an attribute KeyValue conforming to the \"thread.name\"\n// semantic conventions. It represents the current thread name.\nfunc ThreadName(val string) attribute.KeyValue {\n\treturn ThreadNameKey.String(val)\n}\n\n// These attributes allow to report this unit of code and therefore to provide\n// more context about the span.\nconst (\n\t// CodeFunctionKey is the attribute Key conforming to the \"code.function\"\n\t// semantic conventions. It represents the method or function name, or\n\t// equivalent (usually rightmost part of the code unit's name).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'serveRequest'\n\tCodeFunctionKey = attribute.Key(\"code.function\")\n\n\t// CodeNamespaceKey is the attribute Key conforming to the \"code.namespace\"\n\t// semantic conventions. It represents the \"namespace\" within which\n\t// `code.function` is defined. Usually the qualified class or module name,\n\t// such that `code.namespace` + some separator + `code.function` form a\n\t// unique identifier for the code unit.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'com.example.MyHTTPService'\n\tCodeNamespaceKey = attribute.Key(\"code.namespace\")\n\n\t// CodeFilepathKey is the attribute Key conforming to the \"code.filepath\"\n\t// semantic conventions. It represents the source code file name that\n\t// identifies the code unit as uniquely as possible (preferably an absolute\n\t// file path).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '/usr/local/MyApplication/content_root/app/index.php'\n\tCodeFilepathKey = attribute.Key(\"code.filepath\")\n\n\t// CodeLineNumberKey is the attribute Key conforming to the \"code.lineno\"\n\t// semantic conventions. It represents the line number in `code.filepath`\n\t// best representing the operation. It SHOULD point within the code unit\n\t// named in `code.function`.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 42\n\tCodeLineNumberKey = attribute.Key(\"code.lineno\")\n\n\t// CodeColumnKey is the attribute Key conforming to the \"code.column\"\n\t// semantic conventions. It represents the column number in `code.filepath`\n\t// best representing the operation. It SHOULD point within the code unit\n\t// named in `code.function`.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 16\n\tCodeColumnKey = attribute.Key(\"code.column\")\n)\n\n// CodeFunction returns an attribute KeyValue conforming to the\n// \"code.function\" semantic conventions. It represents the method or function\n// name, or equivalent (usually rightmost part of the code unit's name).\nfunc CodeFunction(val string) attribute.KeyValue {\n\treturn CodeFunctionKey.String(val)\n}\n\n// CodeNamespace returns an attribute KeyValue conforming to the\n// \"code.namespace\" semantic conventions. It represents the \"namespace\" within\n// which `code.function` is defined. Usually the qualified class or module\n// name, such that `code.namespace` + some separator + `code.function` form a\n// unique identifier for the code unit.\nfunc CodeNamespace(val string) attribute.KeyValue {\n\treturn CodeNamespaceKey.String(val)\n}\n\n// CodeFilepath returns an attribute KeyValue conforming to the\n// \"code.filepath\" semantic conventions. It represents the source code file\n// name that identifies the code unit as uniquely as possible (preferably an\n// absolute file path).\nfunc CodeFilepath(val string) attribute.KeyValue {\n\treturn CodeFilepathKey.String(val)\n}\n\n// CodeLineNumber returns an attribute KeyValue conforming to the \"code.lineno\"\n// semantic conventions. It represents the line number in `code.filepath` best\n// representing the operation. It SHOULD point within the code unit named in\n// `code.function`.\nfunc CodeLineNumber(val int) attribute.KeyValue {\n\treturn CodeLineNumberKey.Int(val)\n}\n\n// CodeColumn returns an attribute KeyValue conforming to the \"code.column\"\n// semantic conventions. It represents the column number in `code.filepath`\n// best representing the operation. It SHOULD point within the code unit named\n// in `code.function`.\nfunc CodeColumn(val int) attribute.KeyValue {\n\treturn CodeColumnKey.Int(val)\n}\n\n// Semantic conventions for HTTP client and server Spans.\nconst (\n\t// HTTPMethodKey is the attribute Key conforming to the \"http.method\"\n\t// semantic conventions. It represents the hTTP request method.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'GET', 'POST', 'HEAD'\n\tHTTPMethodKey = attribute.Key(\"http.method\")\n\n\t// HTTPStatusCodeKey is the attribute Key conforming to the\n\t// \"http.status_code\" semantic conventions. It represents the [HTTP\n\t// response status code](https://tools.ietf.org/html/rfc7231#section-6).\n\t//\n\t// Type: int\n\t// RequirementLevel: ConditionallyRequired (If and only if one was\n\t// received/sent.)\n\t// Stability: stable\n\t// Examples: 200\n\tHTTPStatusCodeKey = attribute.Key(\"http.status_code\")\n\n\t// HTTPFlavorKey is the attribute Key conforming to the \"http.flavor\"\n\t// semantic conventions. It represents the kind of HTTP protocol used.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Note: If `net.transport` is not specified, it can be assumed to be\n\t// `IP.TCP` except if `http.flavor` is `QUIC`, in which case `IP.UDP` is\n\t// assumed.\n\tHTTPFlavorKey = attribute.Key(\"http.flavor\")\n\n\t// HTTPUserAgentKey is the attribute Key conforming to the\n\t// \"http.user_agent\" semantic conventions. It represents the value of the\n\t// [HTTP\n\t// User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent)\n\t// header sent by the client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'CERN-LineMode/2.15 libwww/2.17b3'\n\tHTTPUserAgentKey = attribute.Key(\"http.user_agent\")\n\n\t// HTTPRequestContentLengthKey is the attribute Key conforming to the\n\t// \"http.request_content_length\" semantic conventions. It represents the\n\t// size of the request payload body in bytes. This is the number of bytes\n\t// transferred excluding headers and is often, but not always, present as\n\t// the\n\t// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)\n\t// header. For requests using transport encoding, this should be the\n\t// compressed size.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 3495\n\tHTTPRequestContentLengthKey = attribute.Key(\"http.request_content_length\")\n\n\t// HTTPResponseContentLengthKey is the attribute Key conforming to the\n\t// \"http.response_content_length\" semantic conventions. It represents the\n\t// size of the response payload body in bytes. This is the number of bytes\n\t// transferred excluding headers and is often, but not always, present as\n\t// the\n\t// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)\n\t// header. For requests using transport encoding, this should be the\n\t// compressed size.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 3495\n\tHTTPResponseContentLengthKey = attribute.Key(\"http.response_content_length\")\n)\n\nvar (\n\t// HTTP/1.0\n\tHTTPFlavorHTTP10 = HTTPFlavorKey.String(\"1.0\")\n\t// HTTP/1.1\n\tHTTPFlavorHTTP11 = HTTPFlavorKey.String(\"1.1\")\n\t// HTTP/2\n\tHTTPFlavorHTTP20 = HTTPFlavorKey.String(\"2.0\")\n\t// HTTP/3\n\tHTTPFlavorHTTP30 = HTTPFlavorKey.String(\"3.0\")\n\t// SPDY protocol\n\tHTTPFlavorSPDY = HTTPFlavorKey.String(\"SPDY\")\n\t// QUIC protocol\n\tHTTPFlavorQUIC = HTTPFlavorKey.String(\"QUIC\")\n)\n\n// HTTPMethod returns an attribute KeyValue conforming to the \"http.method\"\n// semantic conventions. It represents the hTTP request method.\nfunc HTTPMethod(val string) attribute.KeyValue {\n\treturn HTTPMethodKey.String(val)\n}\n\n// HTTPStatusCode returns an attribute KeyValue conforming to the\n// \"http.status_code\" semantic conventions. It represents the [HTTP response\n// status code](https://tools.ietf.org/html/rfc7231#section-6).\nfunc HTTPStatusCode(val int) attribute.KeyValue {\n\treturn HTTPStatusCodeKey.Int(val)\n}\n\n// HTTPUserAgent returns an attribute KeyValue conforming to the\n// \"http.user_agent\" semantic conventions. It represents the value of the [HTTP\n// User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent)\n// header sent by the client.\nfunc HTTPUserAgent(val string) attribute.KeyValue {\n\treturn HTTPUserAgentKey.String(val)\n}\n\n// HTTPRequestContentLength returns an attribute KeyValue conforming to the\n// \"http.request_content_length\" semantic conventions. It represents the size\n// of the request payload body in bytes. This is the number of bytes\n// transferred excluding headers and is often, but not always, present as the\n// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)\n// header. For requests using transport encoding, this should be the compressed\n// size.\nfunc HTTPRequestContentLength(val int) attribute.KeyValue {\n\treturn HTTPRequestContentLengthKey.Int(val)\n}\n\n// HTTPResponseContentLength returns an attribute KeyValue conforming to the\n// \"http.response_content_length\" semantic conventions. It represents the size\n// of the response payload body in bytes. This is the number of bytes\n// transferred excluding headers and is often, but not always, present as the\n// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)\n// header. For requests using transport encoding, this should be the compressed\n// size.\nfunc HTTPResponseContentLength(val int) attribute.KeyValue {\n\treturn HTTPResponseContentLengthKey.Int(val)\n}\n\n// Semantic Convention for HTTP Client\nconst (\n\t// HTTPURLKey is the attribute Key conforming to the \"http.url\" semantic\n\t// conventions. It represents the full HTTP request URL in the form\n\t// `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is\n\t// not transmitted over HTTP, but if it is known, it should be included\n\t// nevertheless.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv'\n\t// Note: `http.url` MUST NOT contain credentials passed via URL in form of\n\t// `https://username:password@www.example.com/`. In such case the\n\t// attribute's value should be `https://www.example.com/`.\n\tHTTPURLKey = attribute.Key(\"http.url\")\n\n\t// HTTPResendCountKey is the attribute Key conforming to the\n\t// \"http.resend_count\" semantic conventions. It represents the ordinal\n\t// number of request resending attempt (for any reason, including\n\t// redirects).\n\t//\n\t// Type: int\n\t// RequirementLevel: Recommended (if and only if request was retried.)\n\t// Stability: stable\n\t// Examples: 3\n\t// Note: The resend count SHOULD be updated each time an HTTP request gets\n\t// resent by the client, regardless of what was the cause of the resending\n\t// (e.g. redirection, authorization failure, 503 Server Unavailable,\n\t// network issues, or any other).\n\tHTTPResendCountKey = attribute.Key(\"http.resend_count\")\n)\n\n// HTTPURL returns an attribute KeyValue conforming to the \"http.url\"\n// semantic conventions. It represents the full HTTP request URL in the form\n// `scheme://host[:port]/path?query[#fragment]`. Usually the fragment is not\n// transmitted over HTTP, but if it is known, it should be included\n// nevertheless.\nfunc HTTPURL(val string) attribute.KeyValue {\n\treturn HTTPURLKey.String(val)\n}\n\n// HTTPResendCount returns an attribute KeyValue conforming to the\n// \"http.resend_count\" semantic conventions. It represents the ordinal number\n// of request resending attempt (for any reason, including redirects).\nfunc HTTPResendCount(val int) attribute.KeyValue {\n\treturn HTTPResendCountKey.Int(val)\n}\n\n// Semantic Convention for HTTP Server\nconst (\n\t// HTTPSchemeKey is the attribute Key conforming to the \"http.scheme\"\n\t// semantic conventions. It represents the URI scheme identifying the used\n\t// protocol.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'http', 'https'\n\tHTTPSchemeKey = attribute.Key(\"http.scheme\")\n\n\t// HTTPTargetKey is the attribute Key conforming to the \"http.target\"\n\t// semantic conventions. It represents the full request target as passed in\n\t// a HTTP request line or equivalent.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: '/path/12314/?q=ddds'\n\tHTTPTargetKey = attribute.Key(\"http.target\")\n\n\t// HTTPRouteKey is the attribute Key conforming to the \"http.route\"\n\t// semantic conventions. It represents the matched route (path template in\n\t// the format used by the respective server framework). See note below\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (If and only if it's available)\n\t// Stability: stable\n\t// Examples: '/users/:userID?', '{controller}/{action}/{id?}'\n\t// Note: 'http.route' MUST NOT be populated when this is not supported by\n\t// the HTTP server framework as the route attribute should have\n\t// low-cardinality and the URI path can NOT substitute it.\n\tHTTPRouteKey = attribute.Key(\"http.route\")\n\n\t// HTTPClientIPKey is the attribute Key conforming to the \"http.client_ip\"\n\t// semantic conventions. It represents the IP address of the original\n\t// client behind all proxies, if known (e.g. from\n\t// [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)).\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '83.164.160.102'\n\t// Note: This is not necessarily the same as `net.sock.peer.addr`, which\n\t// would\n\t// identify the network-level peer, which may be a proxy.\n\t//\n\t// This attribute should be set when a source of information different\n\t// from the one used for `net.sock.peer.addr`, is available even if that\n\t// other\n\t// source just confirms the same value as `net.sock.peer.addr`.\n\t// Rationale: For `net.sock.peer.addr`, one typically does not know if it\n\t// comes from a proxy, reverse proxy, or the actual client. Setting\n\t// `http.client_ip` when it's the same as `net.sock.peer.addr` means that\n\t// one is at least somewhat confident that the address is not that of\n\t// the closest proxy.\n\tHTTPClientIPKey = attribute.Key(\"http.client_ip\")\n)\n\n// HTTPScheme returns an attribute KeyValue conforming to the \"http.scheme\"\n// semantic conventions. It represents the URI scheme identifying the used\n// protocol.\nfunc HTTPScheme(val string) attribute.KeyValue {\n\treturn HTTPSchemeKey.String(val)\n}\n\n// HTTPTarget returns an attribute KeyValue conforming to the \"http.target\"\n// semantic conventions. It represents the full request target as passed in a\n// HTTP request line or equivalent.\nfunc HTTPTarget(val string) attribute.KeyValue {\n\treturn HTTPTargetKey.String(val)\n}\n\n// HTTPRoute returns an attribute KeyValue conforming to the \"http.route\"\n// semantic conventions. It represents the matched route (path template in the\n// format used by the respective server framework). See note below\nfunc HTTPRoute(val string) attribute.KeyValue {\n\treturn HTTPRouteKey.String(val)\n}\n\n// HTTPClientIP returns an attribute KeyValue conforming to the\n// \"http.client_ip\" semantic conventions. It represents the IP address of the\n// original client behind all proxies, if known (e.g. from\n// [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)).\nfunc HTTPClientIP(val string) attribute.KeyValue {\n\treturn HTTPClientIPKey.String(val)\n}\n\n// Attributes that exist for multiple DynamoDB request types.\nconst (\n\t// AWSDynamoDBTableNamesKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.table_names\" semantic conventions. It represents the keys\n\t// in the `RequestItems` object field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Users', 'Cats'\n\tAWSDynamoDBTableNamesKey = attribute.Key(\"aws.dynamodb.table_names\")\n\n\t// AWSDynamoDBConsumedCapacityKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.consumed_capacity\" semantic conventions. It represents the\n\t// JSON-serialized value of each item in the `ConsumedCapacity` response\n\t// field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '{ \"CapacityUnits\": number, \"GlobalSecondaryIndexes\": {\n\t// \"string\" : { \"CapacityUnits\": number, \"ReadCapacityUnits\": number,\n\t// \"WriteCapacityUnits\": number } }, \"LocalSecondaryIndexes\": { \"string\" :\n\t// { \"CapacityUnits\": number, \"ReadCapacityUnits\": number,\n\t// \"WriteCapacityUnits\": number } }, \"ReadCapacityUnits\": number, \"Table\":\n\t// { \"CapacityUnits\": number, \"ReadCapacityUnits\": number,\n\t// \"WriteCapacityUnits\": number }, \"TableName\": \"string\",\n\t// \"WriteCapacityUnits\": number }'\n\tAWSDynamoDBConsumedCapacityKey = attribute.Key(\"aws.dynamodb.consumed_capacity\")\n\n\t// AWSDynamoDBItemCollectionMetricsKey is the attribute Key conforming to\n\t// the \"aws.dynamodb.item_collection_metrics\" semantic conventions. It\n\t// represents the JSON-serialized value of the `ItemCollectionMetrics`\n\t// response field.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '{ \"string\" : [ { \"ItemCollectionKey\": { \"string\" : { \"B\":\n\t// blob, \"BOOL\": boolean, \"BS\": [ blob ], \"L\": [ \"AttributeValue\" ], \"M\": {\n\t// \"string\" : \"AttributeValue\" }, \"N\": \"string\", \"NS\": [ \"string\" ],\n\t// \"NULL\": boolean, \"S\": \"string\", \"SS\": [ \"string\" ] } },\n\t// \"SizeEstimateRangeGB\": [ number ] } ] }'\n\tAWSDynamoDBItemCollectionMetricsKey = attribute.Key(\"aws.dynamodb.item_collection_metrics\")\n\n\t// AWSDynamoDBProvisionedReadCapacityKey is the attribute Key conforming to\n\t// the \"aws.dynamodb.provisioned_read_capacity\" semantic conventions. It\n\t// represents the value of the `ProvisionedThroughput.ReadCapacityUnits`\n\t// request parameter.\n\t//\n\t// Type: double\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedReadCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_read_capacity\")\n\n\t// AWSDynamoDBProvisionedWriteCapacityKey is the attribute Key conforming\n\t// to the \"aws.dynamodb.provisioned_write_capacity\" semantic conventions.\n\t// It represents the value of the\n\t// `ProvisionedThroughput.WriteCapacityUnits` request parameter.\n\t//\n\t// Type: double\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 1.0, 2.0\n\tAWSDynamoDBProvisionedWriteCapacityKey = attribute.Key(\"aws.dynamodb.provisioned_write_capacity\")\n\n\t// AWSDynamoDBConsistentReadKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.consistent_read\" semantic conventions. It represents the\n\t// value of the `ConsistentRead` request parameter.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tAWSDynamoDBConsistentReadKey = attribute.Key(\"aws.dynamodb.consistent_read\")\n\n\t// AWSDynamoDBProjectionKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.projection\" semantic conventions. It represents the value\n\t// of the `ProjectionExpression` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Title', 'Title, Price, Color', 'Title, Description,\n\t// RelatedItems, ProductReviews'\n\tAWSDynamoDBProjectionKey = attribute.Key(\"aws.dynamodb.projection\")\n\n\t// AWSDynamoDBLimitKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.limit\" semantic conventions. It represents the value of\n\t// the `Limit` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 10\n\tAWSDynamoDBLimitKey = attribute.Key(\"aws.dynamodb.limit\")\n\n\t// AWSDynamoDBAttributesToGetKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.attributes_to_get\" semantic conventions. It represents the\n\t// value of the `AttributesToGet` request parameter.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'lives', 'id'\n\tAWSDynamoDBAttributesToGetKey = attribute.Key(\"aws.dynamodb.attributes_to_get\")\n\n\t// AWSDynamoDBIndexNameKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.index_name\" semantic conventions. It represents the value\n\t// of the `IndexName` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'name_to_group'\n\tAWSDynamoDBIndexNameKey = attribute.Key(\"aws.dynamodb.index_name\")\n\n\t// AWSDynamoDBSelectKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.select\" semantic conventions. It represents the value of\n\t// the `Select` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'ALL_ATTRIBUTES', 'COUNT'\n\tAWSDynamoDBSelectKey = attribute.Key(\"aws.dynamodb.select\")\n)\n\n// AWSDynamoDBTableNames returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.table_names\" semantic conventions. It represents the keys in\n// the `RequestItems` object field.\nfunc AWSDynamoDBTableNames(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBTableNamesKey.StringSlice(val)\n}\n\n// AWSDynamoDBConsumedCapacity returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.consumed_capacity\" semantic conventions. It represents the\n// JSON-serialized value of each item in the `ConsumedCapacity` response field.\nfunc AWSDynamoDBConsumedCapacity(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBConsumedCapacityKey.StringSlice(val)\n}\n\n// AWSDynamoDBItemCollectionMetrics returns an attribute KeyValue conforming\n// to the \"aws.dynamodb.item_collection_metrics\" semantic conventions. It\n// represents the JSON-serialized value of the `ItemCollectionMetrics` response\n// field.\nfunc AWSDynamoDBItemCollectionMetrics(val string) attribute.KeyValue {\n\treturn AWSDynamoDBItemCollectionMetricsKey.String(val)\n}\n\n// AWSDynamoDBProvisionedReadCapacity returns an attribute KeyValue\n// conforming to the \"aws.dynamodb.provisioned_read_capacity\" semantic\n// conventions. It represents the value of the\n// `ProvisionedThroughput.ReadCapacityUnits` request parameter.\nfunc AWSDynamoDBProvisionedReadCapacity(val float64) attribute.KeyValue {\n\treturn AWSDynamoDBProvisionedReadCapacityKey.Float64(val)\n}\n\n// AWSDynamoDBProvisionedWriteCapacity returns an attribute KeyValue\n// conforming to the \"aws.dynamodb.provisioned_write_capacity\" semantic\n// conventions. It represents the value of the\n// `ProvisionedThroughput.WriteCapacityUnits` request parameter.\nfunc AWSDynamoDBProvisionedWriteCapacity(val float64) attribute.KeyValue {\n\treturn AWSDynamoDBProvisionedWriteCapacityKey.Float64(val)\n}\n\n// AWSDynamoDBConsistentRead returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.consistent_read\" semantic conventions. It represents the value\n// of the `ConsistentRead` request parameter.\nfunc AWSDynamoDBConsistentRead(val bool) attribute.KeyValue {\n\treturn AWSDynamoDBConsistentReadKey.Bool(val)\n}\n\n// AWSDynamoDBProjection returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.projection\" semantic conventions. It represents the value of\n// the `ProjectionExpression` request parameter.\nfunc AWSDynamoDBProjection(val string) attribute.KeyValue {\n\treturn AWSDynamoDBProjectionKey.String(val)\n}\n\n// AWSDynamoDBLimit returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.limit\" semantic conventions. It represents the value of the\n// `Limit` request parameter.\nfunc AWSDynamoDBLimit(val int) attribute.KeyValue {\n\treturn AWSDynamoDBLimitKey.Int(val)\n}\n\n// AWSDynamoDBAttributesToGet returns an attribute KeyValue conforming to\n// the \"aws.dynamodb.attributes_to_get\" semantic conventions. It represents the\n// value of the `AttributesToGet` request parameter.\nfunc AWSDynamoDBAttributesToGet(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBAttributesToGetKey.StringSlice(val)\n}\n\n// AWSDynamoDBIndexName returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.index_name\" semantic conventions. It represents the value of\n// the `IndexName` request parameter.\nfunc AWSDynamoDBIndexName(val string) attribute.KeyValue {\n\treturn AWSDynamoDBIndexNameKey.String(val)\n}\n\n// AWSDynamoDBSelect returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.select\" semantic conventions. It represents the value of the\n// `Select` request parameter.\nfunc AWSDynamoDBSelect(val string) attribute.KeyValue {\n\treturn AWSDynamoDBSelectKey.String(val)\n}\n\n// DynamoDB.CreateTable\nconst (\n\t// AWSDynamoDBGlobalSecondaryIndexesKey is the attribute Key conforming to\n\t// the \"aws.dynamodb.global_secondary_indexes\" semantic conventions. It\n\t// represents the JSON-serialized value of each item of the\n\t// `GlobalSecondaryIndexes` request field\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '{ \"IndexName\": \"string\", \"KeySchema\": [ { \"AttributeName\":\n\t// \"string\", \"KeyType\": \"string\" } ], \"Projection\": { \"NonKeyAttributes\": [\n\t// \"string\" ], \"ProjectionType\": \"string\" }, \"ProvisionedThroughput\": {\n\t// \"ReadCapacityUnits\": number, \"WriteCapacityUnits\": number } }'\n\tAWSDynamoDBGlobalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.global_secondary_indexes\")\n\n\t// AWSDynamoDBLocalSecondaryIndexesKey is the attribute Key conforming to\n\t// the \"aws.dynamodb.local_secondary_indexes\" semantic conventions. It\n\t// represents the JSON-serialized value of each item of the\n\t// `LocalSecondaryIndexes` request field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '{ \"IndexARN\": \"string\", \"IndexName\": \"string\",\n\t// \"IndexSizeBytes\": number, \"ItemCount\": number, \"KeySchema\": [ {\n\t// \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": {\n\t// \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" } }'\n\tAWSDynamoDBLocalSecondaryIndexesKey = attribute.Key(\"aws.dynamodb.local_secondary_indexes\")\n)\n\n// AWSDynamoDBGlobalSecondaryIndexes returns an attribute KeyValue\n// conforming to the \"aws.dynamodb.global_secondary_indexes\" semantic\n// conventions. It represents the JSON-serialized value of each item of the\n// `GlobalSecondaryIndexes` request field\nfunc AWSDynamoDBGlobalSecondaryIndexes(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBGlobalSecondaryIndexesKey.StringSlice(val)\n}\n\n// AWSDynamoDBLocalSecondaryIndexes returns an attribute KeyValue conforming\n// to the \"aws.dynamodb.local_secondary_indexes\" semantic conventions. It\n// represents the JSON-serialized value of each item of the\n// `LocalSecondaryIndexes` request field.\nfunc AWSDynamoDBLocalSecondaryIndexes(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBLocalSecondaryIndexesKey.StringSlice(val)\n}\n\n// DynamoDB.ListTables\nconst (\n\t// AWSDynamoDBExclusiveStartTableKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.exclusive_start_table\" semantic conventions. It represents\n\t// the value of the `ExclusiveStartTableName` request parameter.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Users', 'CatsTable'\n\tAWSDynamoDBExclusiveStartTableKey = attribute.Key(\"aws.dynamodb.exclusive_start_table\")\n\n\t// AWSDynamoDBTableCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.table_count\" semantic conventions. It represents the the\n\t// number of items in the `TableNames` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 20\n\tAWSDynamoDBTableCountKey = attribute.Key(\"aws.dynamodb.table_count\")\n)\n\n// AWSDynamoDBExclusiveStartTable returns an attribute KeyValue conforming\n// to the \"aws.dynamodb.exclusive_start_table\" semantic conventions. It\n// represents the value of the `ExclusiveStartTableName` request parameter.\nfunc AWSDynamoDBExclusiveStartTable(val string) attribute.KeyValue {\n\treturn AWSDynamoDBExclusiveStartTableKey.String(val)\n}\n\n// AWSDynamoDBTableCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.table_count\" semantic conventions. It represents the the\n// number of items in the `TableNames` response parameter.\nfunc AWSDynamoDBTableCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBTableCountKey.Int(val)\n}\n\n// DynamoDB.Query\nconst (\n\t// AWSDynamoDBScanForwardKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.scan_forward\" semantic conventions. It represents the\n\t// value of the `ScanIndexForward` request parameter.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tAWSDynamoDBScanForwardKey = attribute.Key(\"aws.dynamodb.scan_forward\")\n)\n\n// AWSDynamoDBScanForward returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.scan_forward\" semantic conventions. It represents the value of\n// the `ScanIndexForward` request parameter.\nfunc AWSDynamoDBScanForward(val bool) attribute.KeyValue {\n\treturn AWSDynamoDBScanForwardKey.Bool(val)\n}\n\n// DynamoDB.Scan\nconst (\n\t// AWSDynamoDBSegmentKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.segment\" semantic conventions. It represents the value of\n\t// the `Segment` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 10\n\tAWSDynamoDBSegmentKey = attribute.Key(\"aws.dynamodb.segment\")\n\n\t// AWSDynamoDBTotalSegmentsKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.total_segments\" semantic conventions. It represents the\n\t// value of the `TotalSegments` request parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 100\n\tAWSDynamoDBTotalSegmentsKey = attribute.Key(\"aws.dynamodb.total_segments\")\n\n\t// AWSDynamoDBCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.count\" semantic conventions. It represents the value of\n\t// the `Count` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 10\n\tAWSDynamoDBCountKey = attribute.Key(\"aws.dynamodb.count\")\n\n\t// AWSDynamoDBScannedCountKey is the attribute Key conforming to the\n\t// \"aws.dynamodb.scanned_count\" semantic conventions. It represents the\n\t// value of the `ScannedCount` response parameter.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 50\n\tAWSDynamoDBScannedCountKey = attribute.Key(\"aws.dynamodb.scanned_count\")\n)\n\n// AWSDynamoDBSegment returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.segment\" semantic conventions. It represents the value of the\n// `Segment` request parameter.\nfunc AWSDynamoDBSegment(val int) attribute.KeyValue {\n\treturn AWSDynamoDBSegmentKey.Int(val)\n}\n\n// AWSDynamoDBTotalSegments returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.total_segments\" semantic conventions. It represents the value\n// of the `TotalSegments` request parameter.\nfunc AWSDynamoDBTotalSegments(val int) attribute.KeyValue {\n\treturn AWSDynamoDBTotalSegmentsKey.Int(val)\n}\n\n// AWSDynamoDBCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.count\" semantic conventions. It represents the value of the\n// `Count` response parameter.\nfunc AWSDynamoDBCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBCountKey.Int(val)\n}\n\n// AWSDynamoDBScannedCount returns an attribute KeyValue conforming to the\n// \"aws.dynamodb.scanned_count\" semantic conventions. It represents the value\n// of the `ScannedCount` response parameter.\nfunc AWSDynamoDBScannedCount(val int) attribute.KeyValue {\n\treturn AWSDynamoDBScannedCountKey.Int(val)\n}\n\n// DynamoDB.UpdateTable\nconst (\n\t// AWSDynamoDBAttributeDefinitionsKey is the attribute Key conforming to\n\t// the \"aws.dynamodb.attribute_definitions\" semantic conventions. It\n\t// represents the JSON-serialized value of each item in the\n\t// `AttributeDefinitions` request field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '{ \"AttributeName\": \"string\", \"AttributeType\": \"string\" }'\n\tAWSDynamoDBAttributeDefinitionsKey = attribute.Key(\"aws.dynamodb.attribute_definitions\")\n\n\t// AWSDynamoDBGlobalSecondaryIndexUpdatesKey is the attribute Key\n\t// conforming to the \"aws.dynamodb.global_secondary_index_updates\" semantic\n\t// conventions. It represents the JSON-serialized value of each item in the\n\t// the `GlobalSecondaryIndexUpdates` request field.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '{ \"Create\": { \"IndexName\": \"string\", \"KeySchema\": [ {\n\t// \"AttributeName\": \"string\", \"KeyType\": \"string\" } ], \"Projection\": {\n\t// \"NonKeyAttributes\": [ \"string\" ], \"ProjectionType\": \"string\" },\n\t// \"ProvisionedThroughput\": { \"ReadCapacityUnits\": number,\n\t// \"WriteCapacityUnits\": number } }'\n\tAWSDynamoDBGlobalSecondaryIndexUpdatesKey = attribute.Key(\"aws.dynamodb.global_secondary_index_updates\")\n)\n\n// AWSDynamoDBAttributeDefinitions returns an attribute KeyValue conforming\n// to the \"aws.dynamodb.attribute_definitions\" semantic conventions. It\n// represents the JSON-serialized value of each item in the\n// `AttributeDefinitions` request field.\nfunc AWSDynamoDBAttributeDefinitions(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBAttributeDefinitionsKey.StringSlice(val)\n}\n\n// AWSDynamoDBGlobalSecondaryIndexUpdates returns an attribute KeyValue\n// conforming to the \"aws.dynamodb.global_secondary_index_updates\" semantic\n// conventions. It represents the JSON-serialized value of each item in the the\n// `GlobalSecondaryIndexUpdates` request field.\nfunc AWSDynamoDBGlobalSecondaryIndexUpdates(val ...string) attribute.KeyValue {\n\treturn AWSDynamoDBGlobalSecondaryIndexUpdatesKey.StringSlice(val)\n}\n\n// Semantic conventions to apply when instrumenting the GraphQL implementation.\n// They map GraphQL operations to attributes on a Span.\nconst (\n\t// GraphqlOperationNameKey is the attribute Key conforming to the\n\t// \"graphql.operation.name\" semantic conventions. It represents the name of\n\t// the operation being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'findBookByID'\n\tGraphqlOperationNameKey = attribute.Key(\"graphql.operation.name\")\n\n\t// GraphqlOperationTypeKey is the attribute Key conforming to the\n\t// \"graphql.operation.type\" semantic conventions. It represents the type of\n\t// the operation being executed.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'query', 'mutation', 'subscription'\n\tGraphqlOperationTypeKey = attribute.Key(\"graphql.operation.type\")\n\n\t// GraphqlDocumentKey is the attribute Key conforming to the\n\t// \"graphql.document\" semantic conventions. It represents the GraphQL\n\t// document being executed.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'query findBookByID { bookByID(id: ?) { name } }'\n\t// Note: The value may be sanitized to exclude sensitive information.\n\tGraphqlDocumentKey = attribute.Key(\"graphql.document\")\n)\n\nvar (\n\t// GraphQL query\n\tGraphqlOperationTypeQuery = GraphqlOperationTypeKey.String(\"query\")\n\t// GraphQL mutation\n\tGraphqlOperationTypeMutation = GraphqlOperationTypeKey.String(\"mutation\")\n\t// GraphQL subscription\n\tGraphqlOperationTypeSubscription = GraphqlOperationTypeKey.String(\"subscription\")\n)\n\n// GraphqlOperationName returns an attribute KeyValue conforming to the\n// \"graphql.operation.name\" semantic conventions. It represents the name of the\n// operation being executed.\nfunc GraphqlOperationName(val string) attribute.KeyValue {\n\treturn GraphqlOperationNameKey.String(val)\n}\n\n// GraphqlDocument returns an attribute KeyValue conforming to the\n// \"graphql.document\" semantic conventions. It represents the GraphQL document\n// being executed.\nfunc GraphqlDocument(val string) attribute.KeyValue {\n\treturn GraphqlDocumentKey.String(val)\n}\n\n// Semantic convention describing per-message attributes populated on messaging\n// spans or links.\nconst (\n\t// MessagingMessageIDKey is the attribute Key conforming to the\n\t// \"messaging.message.id\" semantic conventions. It represents a value used\n\t// by the messaging system as an identifier for the message, represented as\n\t// a string.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '452a7c7c7c7048c2f887f61572b18fc2'\n\tMessagingMessageIDKey = attribute.Key(\"messaging.message.id\")\n\n\t// MessagingMessageConversationIDKey is the attribute Key conforming to the\n\t// \"messaging.message.conversation_id\" semantic conventions. It represents\n\t// the [conversation ID](#conversations) identifying the conversation to\n\t// which the message belongs, represented as a string. Sometimes called\n\t// \"Correlation ID\".\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'MyConversationID'\n\tMessagingMessageConversationIDKey = attribute.Key(\"messaging.message.conversation_id\")\n\n\t// MessagingMessagePayloadSizeBytesKey is the attribute Key conforming to\n\t// the \"messaging.message.payload_size_bytes\" semantic conventions. It\n\t// represents the (uncompressed) size of the message payload in bytes. Also\n\t// use this attribute if it is unknown whether the compressed or\n\t// uncompressed payload size is reported.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 2738\n\tMessagingMessagePayloadSizeBytesKey = attribute.Key(\"messaging.message.payload_size_bytes\")\n\n\t// MessagingMessagePayloadCompressedSizeBytesKey is the attribute Key\n\t// conforming to the \"messaging.message.payload_compressed_size_bytes\"\n\t// semantic conventions. It represents the compressed size of the message\n\t// payload in bytes.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 2048\n\tMessagingMessagePayloadCompressedSizeBytesKey = attribute.Key(\"messaging.message.payload_compressed_size_bytes\")\n)\n\n// MessagingMessageID returns an attribute KeyValue conforming to the\n// \"messaging.message.id\" semantic conventions. It represents a value used by\n// the messaging system as an identifier for the message, represented as a\n// string.\nfunc MessagingMessageID(val string) attribute.KeyValue {\n\treturn MessagingMessageIDKey.String(val)\n}\n\n// MessagingMessageConversationID returns an attribute KeyValue conforming\n// to the \"messaging.message.conversation_id\" semantic conventions. It\n// represents the [conversation ID](#conversations) identifying the\n// conversation to which the message belongs, represented as a string.\n// Sometimes called \"Correlation ID\".\nfunc MessagingMessageConversationID(val string) attribute.KeyValue {\n\treturn MessagingMessageConversationIDKey.String(val)\n}\n\n// MessagingMessagePayloadSizeBytes returns an attribute KeyValue conforming\n// to the \"messaging.message.payload_size_bytes\" semantic conventions. It\n// represents the (uncompressed) size of the message payload in bytes. Also use\n// this attribute if it is unknown whether the compressed or uncompressed\n// payload size is reported.\nfunc MessagingMessagePayloadSizeBytes(val int) attribute.KeyValue {\n\treturn MessagingMessagePayloadSizeBytesKey.Int(val)\n}\n\n// MessagingMessagePayloadCompressedSizeBytes returns an attribute KeyValue\n// conforming to the \"messaging.message.payload_compressed_size_bytes\" semantic\n// conventions. It represents the compressed size of the message payload in\n// bytes.\nfunc MessagingMessagePayloadCompressedSizeBytes(val int) attribute.KeyValue {\n\treturn MessagingMessagePayloadCompressedSizeBytesKey.Int(val)\n}\n\n// Semantic convention for attributes that describe messaging destination on\n// broker\nconst (\n\t// MessagingDestinationNameKey is the attribute Key conforming to the\n\t// \"messaging.destination.name\" semantic conventions. It represents the\n\t// message destination name\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'MyQueue', 'MyTopic'\n\t// Note: Destination name SHOULD uniquely identify a specific queue, topic\n\t// or other entity within the broker. If\n\t// the broker does not have such notion, the destination name SHOULD\n\t// uniquely identify the broker.\n\tMessagingDestinationNameKey = attribute.Key(\"messaging.destination.name\")\n\n\t// MessagingDestinationKindKey is the attribute Key conforming to the\n\t// \"messaging.destination.kind\" semantic conventions. It represents the\n\t// kind of message destination\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingDestinationKindKey = attribute.Key(\"messaging.destination.kind\")\n\n\t// MessagingDestinationTemplateKey is the attribute Key conforming to the\n\t// \"messaging.destination.template\" semantic conventions. It represents the\n\t// low cardinality representation of the messaging destination name\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '/customers/{customerID}'\n\t// Note: Destination names could be constructed from templates. An example\n\t// would be a destination name involving a user name or product id.\n\t// Although the destination name in this case is of high cardinality, the\n\t// underlying template is of low cardinality and can be effectively used\n\t// for grouping and aggregation.\n\tMessagingDestinationTemplateKey = attribute.Key(\"messaging.destination.template\")\n\n\t// MessagingDestinationTemporaryKey is the attribute Key conforming to the\n\t// \"messaging.destination.temporary\" semantic conventions. It represents a\n\t// boolean that is true if the message destination is temporary and might\n\t// not exist anymore after messages are processed.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingDestinationTemporaryKey = attribute.Key(\"messaging.destination.temporary\")\n\n\t// MessagingDestinationAnonymousKey is the attribute Key conforming to the\n\t// \"messaging.destination.anonymous\" semantic conventions. It represents a\n\t// boolean that is true if the message destination is anonymous (could be\n\t// unnamed or have auto-generated name).\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingDestinationAnonymousKey = attribute.Key(\"messaging.destination.anonymous\")\n)\n\nvar (\n\t// A message sent to a queue\n\tMessagingDestinationKindQueue = MessagingDestinationKindKey.String(\"queue\")\n\t// A message sent to a topic\n\tMessagingDestinationKindTopic = MessagingDestinationKindKey.String(\"topic\")\n)\n\n// MessagingDestinationName returns an attribute KeyValue conforming to the\n// \"messaging.destination.name\" semantic conventions. It represents the message\n// destination name\nfunc MessagingDestinationName(val string) attribute.KeyValue {\n\treturn MessagingDestinationNameKey.String(val)\n}\n\n// MessagingDestinationTemplate returns an attribute KeyValue conforming to\n// the \"messaging.destination.template\" semantic conventions. It represents the\n// low cardinality representation of the messaging destination name\nfunc MessagingDestinationTemplate(val string) attribute.KeyValue {\n\treturn MessagingDestinationTemplateKey.String(val)\n}\n\n// MessagingDestinationTemporary returns an attribute KeyValue conforming to\n// the \"messaging.destination.temporary\" semantic conventions. It represents a\n// boolean that is true if the message destination is temporary and might not\n// exist anymore after messages are processed.\nfunc MessagingDestinationTemporary(val bool) attribute.KeyValue {\n\treturn MessagingDestinationTemporaryKey.Bool(val)\n}\n\n// MessagingDestinationAnonymous returns an attribute KeyValue conforming to\n// the \"messaging.destination.anonymous\" semantic conventions. It represents a\n// boolean that is true if the message destination is anonymous (could be\n// unnamed or have auto-generated name).\nfunc MessagingDestinationAnonymous(val bool) attribute.KeyValue {\n\treturn MessagingDestinationAnonymousKey.Bool(val)\n}\n\n// Semantic convention for attributes that describe messaging source on broker\nconst (\n\t// MessagingSourceNameKey is the attribute Key conforming to the\n\t// \"messaging.source.name\" semantic conventions. It represents the message\n\t// source name\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'MyQueue', 'MyTopic'\n\t// Note: Source name SHOULD uniquely identify a specific queue, topic, or\n\t// other entity within the broker. If\n\t// the broker does not have such notion, the source name SHOULD uniquely\n\t// identify the broker.\n\tMessagingSourceNameKey = attribute.Key(\"messaging.source.name\")\n\n\t// MessagingSourceKindKey is the attribute Key conforming to the\n\t// \"messaging.source.kind\" semantic conventions. It represents the kind of\n\t// message source\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingSourceKindKey = attribute.Key(\"messaging.source.kind\")\n\n\t// MessagingSourceTemplateKey is the attribute Key conforming to the\n\t// \"messaging.source.template\" semantic conventions. It represents the low\n\t// cardinality representation of the messaging source name\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '/customers/{customerID}'\n\t// Note: Source names could be constructed from templates. An example would\n\t// be a source name involving a user name or product id. Although the\n\t// source name in this case is of high cardinality, the underlying template\n\t// is of low cardinality and can be effectively used for grouping and\n\t// aggregation.\n\tMessagingSourceTemplateKey = attribute.Key(\"messaging.source.template\")\n\n\t// MessagingSourceTemporaryKey is the attribute Key conforming to the\n\t// \"messaging.source.temporary\" semantic conventions. It represents a\n\t// boolean that is true if the message source is temporary and might not\n\t// exist anymore after messages are processed.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingSourceTemporaryKey = attribute.Key(\"messaging.source.temporary\")\n\n\t// MessagingSourceAnonymousKey is the attribute Key conforming to the\n\t// \"messaging.source.anonymous\" semantic conventions. It represents a\n\t// boolean that is true if the message source is anonymous (could be\n\t// unnamed or have auto-generated name).\n\t//\n\t// Type: boolean\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingSourceAnonymousKey = attribute.Key(\"messaging.source.anonymous\")\n)\n\nvar (\n\t// A message received from a queue\n\tMessagingSourceKindQueue = MessagingSourceKindKey.String(\"queue\")\n\t// A message received from a topic\n\tMessagingSourceKindTopic = MessagingSourceKindKey.String(\"topic\")\n)\n\n// MessagingSourceName returns an attribute KeyValue conforming to the\n// \"messaging.source.name\" semantic conventions. It represents the message\n// source name\nfunc MessagingSourceName(val string) attribute.KeyValue {\n\treturn MessagingSourceNameKey.String(val)\n}\n\n// MessagingSourceTemplate returns an attribute KeyValue conforming to the\n// \"messaging.source.template\" semantic conventions. It represents the low\n// cardinality representation of the messaging source name\nfunc MessagingSourceTemplate(val string) attribute.KeyValue {\n\treturn MessagingSourceTemplateKey.String(val)\n}\n\n// MessagingSourceTemporary returns an attribute KeyValue conforming to the\n// \"messaging.source.temporary\" semantic conventions. It represents a boolean\n// that is true if the message source is temporary and might not exist anymore\n// after messages are processed.\nfunc MessagingSourceTemporary(val bool) attribute.KeyValue {\n\treturn MessagingSourceTemporaryKey.Bool(val)\n}\n\n// MessagingSourceAnonymous returns an attribute KeyValue conforming to the\n// \"messaging.source.anonymous\" semantic conventions. It represents a boolean\n// that is true if the message source is anonymous (could be unnamed or have\n// auto-generated name).\nfunc MessagingSourceAnonymous(val bool) attribute.KeyValue {\n\treturn MessagingSourceAnonymousKey.Bool(val)\n}\n\n// General attributes used in messaging systems.\nconst (\n\t// MessagingSystemKey is the attribute Key conforming to the\n\t// \"messaging.system\" semantic conventions. It represents a string\n\t// identifying the messaging system.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'kafka', 'rabbitmq', 'rocketmq', 'activemq', 'AmazonSQS'\n\tMessagingSystemKey = attribute.Key(\"messaging.system\")\n\n\t// MessagingOperationKey is the attribute Key conforming to the\n\t// \"messaging.operation\" semantic conventions. It represents a string\n\t// identifying the kind of messaging operation as defined in the [Operation\n\t// names](#operation-names) section above.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Note: If a custom value is used, it MUST be of low cardinality.\n\tMessagingOperationKey = attribute.Key(\"messaging.operation\")\n\n\t// MessagingBatchMessageCountKey is the attribute Key conforming to the\n\t// \"messaging.batch.message_count\" semantic conventions. It represents the\n\t// number of messages sent, received, or processed in the scope of the\n\t// batching operation.\n\t//\n\t// Type: int\n\t// RequirementLevel: ConditionallyRequired (If the span describes an\n\t// operation on a batch of messages.)\n\t// Stability: stable\n\t// Examples: 0, 1, 2\n\t// Note: Instrumentations SHOULD NOT set `messaging.batch.message_count` on\n\t// spans that operate with a single message. When a messaging client\n\t// library supports both batch and single-message API for the same\n\t// operation, instrumentations SHOULD use `messaging.batch.message_count`\n\t// for batching APIs and SHOULD NOT use it for single-message APIs.\n\tMessagingBatchMessageCountKey = attribute.Key(\"messaging.batch.message_count\")\n)\n\nvar (\n\t// publish\n\tMessagingOperationPublish = MessagingOperationKey.String(\"publish\")\n\t// receive\n\tMessagingOperationReceive = MessagingOperationKey.String(\"receive\")\n\t// process\n\tMessagingOperationProcess = MessagingOperationKey.String(\"process\")\n)\n\n// MessagingSystem returns an attribute KeyValue conforming to the\n// \"messaging.system\" semantic conventions. It represents a string identifying\n// the messaging system.\nfunc MessagingSystem(val string) attribute.KeyValue {\n\treturn MessagingSystemKey.String(val)\n}\n\n// MessagingBatchMessageCount returns an attribute KeyValue conforming to\n// the \"messaging.batch.message_count\" semantic conventions. It represents the\n// number of messages sent, received, or processed in the scope of the batching\n// operation.\nfunc MessagingBatchMessageCount(val int) attribute.KeyValue {\n\treturn MessagingBatchMessageCountKey.Int(val)\n}\n\n// Semantic convention for a consumer of messages received from a messaging\n// system\nconst (\n\t// MessagingConsumerIDKey is the attribute Key conforming to the\n\t// \"messaging.consumer.id\" semantic conventions. It represents the\n\t// identifier for the consumer receiving a message. For Kafka, set it to\n\t// `{messaging.kafka.consumer.group} - {messaging.kafka.client_id}`, if\n\t// both are present, or only `messaging.kafka.consumer.group`. For brokers,\n\t// such as RabbitMQ and Artemis, set it to the `client_id` of the client\n\t// consuming the message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'mygroup - client-6'\n\tMessagingConsumerIDKey = attribute.Key(\"messaging.consumer.id\")\n)\n\n// MessagingConsumerID returns an attribute KeyValue conforming to the\n// \"messaging.consumer.id\" semantic conventions. It represents the identifier\n// for the consumer receiving a message. For Kafka, set it to\n// `{messaging.kafka.consumer.group} - {messaging.kafka.client_id}`, if both\n// are present, or only `messaging.kafka.consumer.group`. For brokers, such as\n// RabbitMQ and Artemis, set it to the `client_id` of the client consuming the\n// message.\nfunc MessagingConsumerID(val string) attribute.KeyValue {\n\treturn MessagingConsumerIDKey.String(val)\n}\n\n// Attributes for RabbitMQ\nconst (\n\t// MessagingRabbitmqDestinationRoutingKeyKey is the attribute Key\n\t// conforming to the \"messaging.rabbitmq.destination.routing_key\" semantic\n\t// conventions. It represents the rabbitMQ message routing key.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (If not empty.)\n\t// Stability: stable\n\t// Examples: 'myKey'\n\tMessagingRabbitmqDestinationRoutingKeyKey = attribute.Key(\"messaging.rabbitmq.destination.routing_key\")\n)\n\n// MessagingRabbitmqDestinationRoutingKey returns an attribute KeyValue\n// conforming to the \"messaging.rabbitmq.destination.routing_key\" semantic\n// conventions. It represents the rabbitMQ message routing key.\nfunc MessagingRabbitmqDestinationRoutingKey(val string) attribute.KeyValue {\n\treturn MessagingRabbitmqDestinationRoutingKeyKey.String(val)\n}\n\n// Attributes for Apache Kafka\nconst (\n\t// MessagingKafkaMessageKeyKey is the attribute Key conforming to the\n\t// \"messaging.kafka.message.key\" semantic conventions. It represents the\n\t// message keys in Kafka are used for grouping alike messages to ensure\n\t// they're processed on the same partition. They differ from\n\t// `messaging.message.id` in that they're not unique. If the key is `null`,\n\t// the attribute MUST NOT be set.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'myKey'\n\t// Note: If the key type is not string, it's string representation has to\n\t// be supplied for the attribute. If the key has no unambiguous, canonical\n\t// string form, don't include its value.\n\tMessagingKafkaMessageKeyKey = attribute.Key(\"messaging.kafka.message.key\")\n\n\t// MessagingKafkaConsumerGroupKey is the attribute Key conforming to the\n\t// \"messaging.kafka.consumer.group\" semantic conventions. It represents the\n\t// name of the Kafka Consumer Group that is handling the message. Only\n\t// applies to consumers, not producers.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'my-group'\n\tMessagingKafkaConsumerGroupKey = attribute.Key(\"messaging.kafka.consumer.group\")\n\n\t// MessagingKafkaClientIDKey is the attribute Key conforming to the\n\t// \"messaging.kafka.client_id\" semantic conventions. It represents the\n\t// client ID for the Consumer or Producer that is handling the message.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'client-5'\n\tMessagingKafkaClientIDKey = attribute.Key(\"messaging.kafka.client_id\")\n\n\t// MessagingKafkaDestinationPartitionKey is the attribute Key conforming to\n\t// the \"messaging.kafka.destination.partition\" semantic conventions. It\n\t// represents the partition the message is sent to.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 2\n\tMessagingKafkaDestinationPartitionKey = attribute.Key(\"messaging.kafka.destination.partition\")\n\n\t// MessagingKafkaSourcePartitionKey is the attribute Key conforming to the\n\t// \"messaging.kafka.source.partition\" semantic conventions. It represents\n\t// the partition the message is received from.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 2\n\tMessagingKafkaSourcePartitionKey = attribute.Key(\"messaging.kafka.source.partition\")\n\n\t// MessagingKafkaMessageOffsetKey is the attribute Key conforming to the\n\t// \"messaging.kafka.message.offset\" semantic conventions. It represents the\n\t// offset of a record in the corresponding Kafka partition.\n\t//\n\t// Type: int\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 42\n\tMessagingKafkaMessageOffsetKey = attribute.Key(\"messaging.kafka.message.offset\")\n\n\t// MessagingKafkaMessageTombstoneKey is the attribute Key conforming to the\n\t// \"messaging.kafka.message.tombstone\" semantic conventions. It represents\n\t// a boolean that is true if the message is a tombstone.\n\t//\n\t// Type: boolean\n\t// RequirementLevel: ConditionallyRequired (If value is `true`. When\n\t// missing, the value is assumed to be `false`.)\n\t// Stability: stable\n\tMessagingKafkaMessageTombstoneKey = attribute.Key(\"messaging.kafka.message.tombstone\")\n)\n\n// MessagingKafkaMessageKey returns an attribute KeyValue conforming to the\n// \"messaging.kafka.message.key\" semantic conventions. It represents the\n// message keys in Kafka are used for grouping alike messages to ensure they're\n// processed on the same partition. They differ from `messaging.message.id` in\n// that they're not unique. If the key is `null`, the attribute MUST NOT be\n// set.\nfunc MessagingKafkaMessageKey(val string) attribute.KeyValue {\n\treturn MessagingKafkaMessageKeyKey.String(val)\n}\n\n// MessagingKafkaConsumerGroup returns an attribute KeyValue conforming to\n// the \"messaging.kafka.consumer.group\" semantic conventions. It represents the\n// name of the Kafka Consumer Group that is handling the message. Only applies\n// to consumers, not producers.\nfunc MessagingKafkaConsumerGroup(val string) attribute.KeyValue {\n\treturn MessagingKafkaConsumerGroupKey.String(val)\n}\n\n// MessagingKafkaClientID returns an attribute KeyValue conforming to the\n// \"messaging.kafka.client_id\" semantic conventions. It represents the client\n// ID for the Consumer or Producer that is handling the message.\nfunc MessagingKafkaClientID(val string) attribute.KeyValue {\n\treturn MessagingKafkaClientIDKey.String(val)\n}\n\n// MessagingKafkaDestinationPartition returns an attribute KeyValue\n// conforming to the \"messaging.kafka.destination.partition\" semantic\n// conventions. It represents the partition the message is sent to.\nfunc MessagingKafkaDestinationPartition(val int) attribute.KeyValue {\n\treturn MessagingKafkaDestinationPartitionKey.Int(val)\n}\n\n// MessagingKafkaSourcePartition returns an attribute KeyValue conforming to\n// the \"messaging.kafka.source.partition\" semantic conventions. It represents\n// the partition the message is received from.\nfunc MessagingKafkaSourcePartition(val int) attribute.KeyValue {\n\treturn MessagingKafkaSourcePartitionKey.Int(val)\n}\n\n// MessagingKafkaMessageOffset returns an attribute KeyValue conforming to\n// the \"messaging.kafka.message.offset\" semantic conventions. It represents the\n// offset of a record in the corresponding Kafka partition.\nfunc MessagingKafkaMessageOffset(val int) attribute.KeyValue {\n\treturn MessagingKafkaMessageOffsetKey.Int(val)\n}\n\n// MessagingKafkaMessageTombstone returns an attribute KeyValue conforming\n// to the \"messaging.kafka.message.tombstone\" semantic conventions. It\n// represents a boolean that is true if the message is a tombstone.\nfunc MessagingKafkaMessageTombstone(val bool) attribute.KeyValue {\n\treturn MessagingKafkaMessageTombstoneKey.Bool(val)\n}\n\n// Attributes for Apache RocketMQ\nconst (\n\t// MessagingRocketmqNamespaceKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.namespace\" semantic conventions. It represents the\n\t// namespace of RocketMQ resources, resources in different namespaces are\n\t// individual.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'myNamespace'\n\tMessagingRocketmqNamespaceKey = attribute.Key(\"messaging.rocketmq.namespace\")\n\n\t// MessagingRocketmqClientGroupKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.client_group\" semantic conventions. It represents\n\t// the name of the RocketMQ producer/consumer group that is handling the\n\t// message. The client type is identified by the SpanKind.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'myConsumerGroup'\n\tMessagingRocketmqClientGroupKey = attribute.Key(\"messaging.rocketmq.client_group\")\n\n\t// MessagingRocketmqClientIDKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.client_id\" semantic conventions. It represents the\n\t// unique identifier for each client.\n\t//\n\t// Type: string\n\t// RequirementLevel: Required\n\t// Stability: stable\n\t// Examples: 'myhost@8742@s8083jm'\n\tMessagingRocketmqClientIDKey = attribute.Key(\"messaging.rocketmq.client_id\")\n\n\t// MessagingRocketmqMessageDeliveryTimestampKey is the attribute Key\n\t// conforming to the \"messaging.rocketmq.message.delivery_timestamp\"\n\t// semantic conventions. It represents the timestamp in milliseconds that\n\t// the delay message is expected to be delivered to consumer.\n\t//\n\t// Type: int\n\t// RequirementLevel: ConditionallyRequired (If the message type is delay\n\t// and delay time level is not specified.)\n\t// Stability: stable\n\t// Examples: 1665987217045\n\tMessagingRocketmqMessageDeliveryTimestampKey = attribute.Key(\"messaging.rocketmq.message.delivery_timestamp\")\n\n\t// MessagingRocketmqMessageDelayTimeLevelKey is the attribute Key\n\t// conforming to the \"messaging.rocketmq.message.delay_time_level\" semantic\n\t// conventions. It represents the delay time level for delay message, which\n\t// determines the message delay time.\n\t//\n\t// Type: int\n\t// RequirementLevel: ConditionallyRequired (If the message type is delay\n\t// and delivery timestamp is not specified.)\n\t// Stability: stable\n\t// Examples: 3\n\tMessagingRocketmqMessageDelayTimeLevelKey = attribute.Key(\"messaging.rocketmq.message.delay_time_level\")\n\n\t// MessagingRocketmqMessageGroupKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.group\" semantic conventions. It represents\n\t// the it is essential for FIFO message. Messages that belong to the same\n\t// message group are always processed one by one within the same consumer\n\t// group.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (If the message type is FIFO.)\n\t// Stability: stable\n\t// Examples: 'myMessageGroup'\n\tMessagingRocketmqMessageGroupKey = attribute.Key(\"messaging.rocketmq.message.group\")\n\n\t// MessagingRocketmqMessageTypeKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.type\" semantic conventions. It represents\n\t// the type of message.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingRocketmqMessageTypeKey = attribute.Key(\"messaging.rocketmq.message.type\")\n\n\t// MessagingRocketmqMessageTagKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.tag\" semantic conventions. It represents the\n\t// secondary classifier of message besides topic.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'tagA'\n\tMessagingRocketmqMessageTagKey = attribute.Key(\"messaging.rocketmq.message.tag\")\n\n\t// MessagingRocketmqMessageKeysKey is the attribute Key conforming to the\n\t// \"messaging.rocketmq.message.keys\" semantic conventions. It represents\n\t// the key(s) of message, another way to mark message besides message id.\n\t//\n\t// Type: string[]\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'keyA', 'keyB'\n\tMessagingRocketmqMessageKeysKey = attribute.Key(\"messaging.rocketmq.message.keys\")\n\n\t// MessagingRocketmqConsumptionModelKey is the attribute Key conforming to\n\t// the \"messaging.rocketmq.consumption_model\" semantic conventions. It\n\t// represents the model of message consumption. This only applies to\n\t// consumer spans.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\tMessagingRocketmqConsumptionModelKey = attribute.Key(\"messaging.rocketmq.consumption_model\")\n)\n\nvar (\n\t// Normal message\n\tMessagingRocketmqMessageTypeNormal = MessagingRocketmqMessageTypeKey.String(\"normal\")\n\t// FIFO message\n\tMessagingRocketmqMessageTypeFifo = MessagingRocketmqMessageTypeKey.String(\"fifo\")\n\t// Delay message\n\tMessagingRocketmqMessageTypeDelay = MessagingRocketmqMessageTypeKey.String(\"delay\")\n\t// Transaction message\n\tMessagingRocketmqMessageTypeTransaction = MessagingRocketmqMessageTypeKey.String(\"transaction\")\n)\n\nvar (\n\t// Clustering consumption model\n\tMessagingRocketmqConsumptionModelClustering = MessagingRocketmqConsumptionModelKey.String(\"clustering\")\n\t// Broadcasting consumption model\n\tMessagingRocketmqConsumptionModelBroadcasting = MessagingRocketmqConsumptionModelKey.String(\"broadcasting\")\n)\n\n// MessagingRocketmqNamespace returns an attribute KeyValue conforming to\n// the \"messaging.rocketmq.namespace\" semantic conventions. It represents the\n// namespace of RocketMQ resources, resources in different namespaces are\n// individual.\nfunc MessagingRocketmqNamespace(val string) attribute.KeyValue {\n\treturn MessagingRocketmqNamespaceKey.String(val)\n}\n\n// MessagingRocketmqClientGroup returns an attribute KeyValue conforming to\n// the \"messaging.rocketmq.client_group\" semantic conventions. It represents\n// the name of the RocketMQ producer/consumer group that is handling the\n// message. The client type is identified by the SpanKind.\nfunc MessagingRocketmqClientGroup(val string) attribute.KeyValue {\n\treturn MessagingRocketmqClientGroupKey.String(val)\n}\n\n// MessagingRocketmqClientID returns an attribute KeyValue conforming to the\n// \"messaging.rocketmq.client_id\" semantic conventions. It represents the\n// unique identifier for each client.\nfunc MessagingRocketmqClientID(val string) attribute.KeyValue {\n\treturn MessagingRocketmqClientIDKey.String(val)\n}\n\n// MessagingRocketmqMessageDeliveryTimestamp returns an attribute KeyValue\n// conforming to the \"messaging.rocketmq.message.delivery_timestamp\" semantic\n// conventions. It represents the timestamp in milliseconds that the delay\n// message is expected to be delivered to consumer.\nfunc MessagingRocketmqMessageDeliveryTimestamp(val int) attribute.KeyValue {\n\treturn MessagingRocketmqMessageDeliveryTimestampKey.Int(val)\n}\n\n// MessagingRocketmqMessageDelayTimeLevel returns an attribute KeyValue\n// conforming to the \"messaging.rocketmq.message.delay_time_level\" semantic\n// conventions. It represents the delay time level for delay message, which\n// determines the message delay time.\nfunc MessagingRocketmqMessageDelayTimeLevel(val int) attribute.KeyValue {\n\treturn MessagingRocketmqMessageDelayTimeLevelKey.Int(val)\n}\n\n// MessagingRocketmqMessageGroup returns an attribute KeyValue conforming to\n// the \"messaging.rocketmq.message.group\" semantic conventions. It represents\n// the it is essential for FIFO message. Messages that belong to the same\n// message group are always processed one by one within the same consumer\n// group.\nfunc MessagingRocketmqMessageGroup(val string) attribute.KeyValue {\n\treturn MessagingRocketmqMessageGroupKey.String(val)\n}\n\n// MessagingRocketmqMessageTag returns an attribute KeyValue conforming to\n// the \"messaging.rocketmq.message.tag\" semantic conventions. It represents the\n// secondary classifier of message besides topic.\nfunc MessagingRocketmqMessageTag(val string) attribute.KeyValue {\n\treturn MessagingRocketmqMessageTagKey.String(val)\n}\n\n// MessagingRocketmqMessageKeys returns an attribute KeyValue conforming to\n// the \"messaging.rocketmq.message.keys\" semantic conventions. It represents\n// the key(s) of message, another way to mark message besides message id.\nfunc MessagingRocketmqMessageKeys(val ...string) attribute.KeyValue {\n\treturn MessagingRocketmqMessageKeysKey.StringSlice(val)\n}\n\n// Semantic conventions for remote procedure calls.\nconst (\n\t// RPCSystemKey is the attribute Key conforming to the \"rpc.system\"\n\t// semantic conventions. It represents a string identifying the remoting\n\t// system. See below for a list of well-known identifiers.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\tRPCSystemKey = attribute.Key(\"rpc.system\")\n\n\t// RPCServiceKey is the attribute Key conforming to the \"rpc.service\"\n\t// semantic conventions. It represents the full (logical) name of the\n\t// service being called, including its package name, if applicable.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: stable\n\t// Examples: 'myservice.EchoService'\n\t// Note: This is the logical name of the service from the RPC interface\n\t// perspective, which can be different from the name of any implementing\n\t// class. The `code.namespace` attribute may be used to store the latter\n\t// (despite the attribute name, it may include a class name; e.g., class\n\t// with method actually executing the call on the server side, RPC client\n\t// stub class on the client side).\n\tRPCServiceKey = attribute.Key(\"rpc.service\")\n\n\t// RPCMethodKey is the attribute Key conforming to the \"rpc.method\"\n\t// semantic conventions. It represents the name of the (logical) method\n\t// being called, must be equal to the $method part in the span name.\n\t//\n\t// Type: string\n\t// RequirementLevel: Recommended\n\t// Stability: stable\n\t// Examples: 'exampleMethod'\n\t// Note: This is the logical name of the method from the RPC interface\n\t// perspective, which can be different from the name of any implementing\n\t// method/function. The `code.function` attribute may be used to store the\n\t// latter (e.g., method actually executing the call on the server side, RPC\n\t// client stub method on the client side).\n\tRPCMethodKey = attribute.Key(\"rpc.method\")\n)\n\nvar (\n\t// gRPC\n\tRPCSystemGRPC = RPCSystemKey.String(\"grpc\")\n\t// Java RMI\n\tRPCSystemJavaRmi = RPCSystemKey.String(\"java_rmi\")\n\t// .NET WCF\n\tRPCSystemDotnetWcf = RPCSystemKey.String(\"dotnet_wcf\")\n\t// Apache Dubbo\n\tRPCSystemApacheDubbo = RPCSystemKey.String(\"apache_dubbo\")\n)\n\n// RPCService returns an attribute KeyValue conforming to the \"rpc.service\"\n// semantic conventions. It represents the full (logical) name of the service\n// being called, including its package name, if applicable.\nfunc RPCService(val string) attribute.KeyValue {\n\treturn RPCServiceKey.String(val)\n}\n\n// RPCMethod returns an attribute KeyValue conforming to the \"rpc.method\"\n// semantic conventions. It represents the name of the (logical) method being\n// called, must be equal to the $method part in the span name.\nfunc RPCMethod(val string) attribute.KeyValue {\n\treturn RPCMethodKey.String(val)\n}\n\n// Tech-specific attributes for gRPC.\nconst (\n\t// RPCGRPCStatusCodeKey is the attribute Key conforming to the\n\t// \"rpc.grpc.status_code\" semantic conventions. It represents the [numeric\n\t// status\n\t// code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of\n\t// the gRPC request.\n\t//\n\t// Type: Enum\n\t// RequirementLevel: Required\n\t// Stability: stable\n\tRPCGRPCStatusCodeKey = attribute.Key(\"rpc.grpc.status_code\")\n)\n\nvar (\n\t// OK\n\tRPCGRPCStatusCodeOk = RPCGRPCStatusCodeKey.Int(0)\n\t// CANCELLED\n\tRPCGRPCStatusCodeCancelled = RPCGRPCStatusCodeKey.Int(1)\n\t// UNKNOWN\n\tRPCGRPCStatusCodeUnknown = RPCGRPCStatusCodeKey.Int(2)\n\t// INVALID_ARGUMENT\n\tRPCGRPCStatusCodeInvalidArgument = RPCGRPCStatusCodeKey.Int(3)\n\t// DEADLINE_EXCEEDED\n\tRPCGRPCStatusCodeDeadlineExceeded = RPCGRPCStatusCodeKey.Int(4)\n\t// NOT_FOUND\n\tRPCGRPCStatusCodeNotFound = RPCGRPCStatusCodeKey.Int(5)\n\t// ALREADY_EXISTS\n\tRPCGRPCStatusCodeAlreadyExists = RPCGRPCStatusCodeKey.Int(6)\n\t// PERMISSION_DENIED\n\tRPCGRPCStatusCodePermissionDenied = RPCGRPCStatusCodeKey.Int(7)\n\t// RESOURCE_EXHAUSTED\n\tRPCGRPCStatusCodeResourceExhausted = RPCGRPCStatusCodeKey.Int(8)\n\t// FAILED_PRECONDITION\n\tRPCGRPCStatusCodeFailedPrecondition = RPCGRPCStatusCodeKey.Int(9)\n\t// ABORTED\n\tRPCGRPCStatusCodeAborted = RPCGRPCStatusCodeKey.Int(10)\n\t// OUT_OF_RANGE\n\tRPCGRPCStatusCodeOutOfRange = RPCGRPCStatusCodeKey.Int(11)\n\t// UNIMPLEMENTED\n\tRPCGRPCStatusCodeUnimplemented = RPCGRPCStatusCodeKey.Int(12)\n\t// INTERNAL\n\tRPCGRPCStatusCodeInternal = RPCGRPCStatusCodeKey.Int(13)\n\t// UNAVAILABLE\n\tRPCGRPCStatusCodeUnavailable = RPCGRPCStatusCodeKey.Int(14)\n\t// DATA_LOSS\n\tRPCGRPCStatusCodeDataLoss = RPCGRPCStatusCodeKey.Int(15)\n\t// UNAUTHENTICATED\n\tRPCGRPCStatusCodeUnauthenticated = RPCGRPCStatusCodeKey.Int(16)\n)\n\n// Tech-specific attributes for [JSON RPC](https://www.jsonrpc.org/).\nconst (\n\t// RPCJsonrpcVersionKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.version\" semantic conventions. It represents the protocol\n\t// version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0\n\t// does not specify this, the value can be omitted.\n\t//\n\t// Type: string\n\t// RequirementLevel: ConditionallyRequired (If other than the default\n\t// version (`1.0`))\n\t// Stability: stable\n\t// Examples: '2.0', '1.0'\n\tRPCJsonrpcVersionKey = attribute.Key(\"rpc.jsonrpc.version\")\n\n\t// RPCJsonrpcRequestIDKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.request_id\" semantic conventions. It represents the `id`\n\t// property of request or response. Since protocol allows id to be int,\n\t// string, `null` or missing (for notifications), value is expected to be\n\t// cast to string for simplicity. Use empty string in case of `null` value.\n\t// Omit entirely if this is a notification.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: '10', 'request-7', ''\n\tRPCJsonrpcRequestIDKey = attribute.Key(\"rpc.jsonrpc.request_id\")\n\n\t// RPCJsonrpcErrorCodeKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.error_code\" semantic conventions. It represents the\n\t// `error.code` property of response if it is an error response.\n\t//\n\t// Type: int\n\t// RequirementLevel: ConditionallyRequired (If response is not successful.)\n\t// Stability: stable\n\t// Examples: -32700, 100\n\tRPCJsonrpcErrorCodeKey = attribute.Key(\"rpc.jsonrpc.error_code\")\n\n\t// RPCJsonrpcErrorMessageKey is the attribute Key conforming to the\n\t// \"rpc.jsonrpc.error_message\" semantic conventions. It represents the\n\t// `error.message` property of response if it is an error response.\n\t//\n\t// Type: string\n\t// RequirementLevel: Optional\n\t// Stability: stable\n\t// Examples: 'Parse error', 'User already exists'\n\tRPCJsonrpcErrorMessageKey = attribute.Key(\"rpc.jsonrpc.error_message\")\n)\n\n// RPCJsonrpcVersion returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.version\" semantic conventions. It represents the protocol\n// version as in `jsonrpc` property of request/response. Since JSON-RPC 1.0\n// does not specify this, the value can be omitted.\nfunc RPCJsonrpcVersion(val string) attribute.KeyValue {\n\treturn RPCJsonrpcVersionKey.String(val)\n}\n\n// RPCJsonrpcRequestID returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.request_id\" semantic conventions. It represents the `id`\n// property of request or response. Since protocol allows id to be int, string,\n// `null` or missing (for notifications), value is expected to be cast to\n// string for simplicity. Use empty string in case of `null` value. Omit\n// entirely if this is a notification.\nfunc RPCJsonrpcRequestID(val string) attribute.KeyValue {\n\treturn RPCJsonrpcRequestIDKey.String(val)\n}\n\n// RPCJsonrpcErrorCode returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.error_code\" semantic conventions. It represents the\n// `error.code` property of response if it is an error response.\nfunc RPCJsonrpcErrorCode(val int) attribute.KeyValue {\n\treturn RPCJsonrpcErrorCodeKey.Int(val)\n}\n\n// RPCJsonrpcErrorMessage returns an attribute KeyValue conforming to the\n// \"rpc.jsonrpc.error_message\" semantic conventions. It represents the\n// `error.message` property of response if it is an error response.\nfunc RPCJsonrpcErrorMessage(val string) attribute.KeyValue {\n\treturn RPCJsonrpcErrorMessageKey.String(val)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://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   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\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       http://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": "vendor/go.opentelemetry.io/otel/trace/config.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"time\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n)\n\n// TracerConfig is a group of options for a Tracer.\ntype TracerConfig struct {\n\tinstrumentationVersion string\n\t// Schema URL of the telemetry emitted by the Tracer.\n\tschemaURL string\n\tattrs     attribute.Set\n}\n\n// InstrumentationVersion returns the version of the library providing instrumentation.\nfunc (t *TracerConfig) InstrumentationVersion() string {\n\treturn t.instrumentationVersion\n}\n\n// InstrumentationAttributes returns the attributes associated with the library\n// providing instrumentation.\nfunc (t *TracerConfig) InstrumentationAttributes() attribute.Set {\n\treturn t.attrs\n}\n\n// SchemaURL returns the Schema URL of the telemetry emitted by the Tracer.\nfunc (t *TracerConfig) SchemaURL() string {\n\treturn t.schemaURL\n}\n\n// NewTracerConfig applies all the options to a returned TracerConfig.\nfunc NewTracerConfig(options ...TracerOption) TracerConfig {\n\tvar config TracerConfig\n\tfor _, option := range options {\n\t\tconfig = option.apply(config)\n\t}\n\treturn config\n}\n\n// TracerOption applies an option to a TracerConfig.\ntype TracerOption interface {\n\tapply(TracerConfig) TracerConfig\n}\n\ntype tracerOptionFunc func(TracerConfig) TracerConfig\n\nfunc (fn tracerOptionFunc) apply(cfg TracerConfig) TracerConfig {\n\treturn fn(cfg)\n}\n\n// SpanConfig is a group of options for a Span.\ntype SpanConfig struct {\n\tattributes []attribute.KeyValue\n\ttimestamp  time.Time\n\tlinks      []Link\n\tnewRoot    bool\n\tspanKind   SpanKind\n\tstackTrace bool\n}\n\n// Attributes describe the associated qualities of a Span.\nfunc (cfg *SpanConfig) Attributes() []attribute.KeyValue {\n\treturn cfg.attributes\n}\n\n// Timestamp is a time in a Span life-cycle.\nfunc (cfg *SpanConfig) Timestamp() time.Time {\n\treturn cfg.timestamp\n}\n\n// StackTrace checks whether stack trace capturing is enabled.\nfunc (cfg *SpanConfig) StackTrace() bool {\n\treturn cfg.stackTrace\n}\n\n// Links are the associations a Span has with other Spans.\nfunc (cfg *SpanConfig) Links() []Link {\n\treturn cfg.links\n}\n\n// NewRoot identifies a Span as the root Span for a new trace. This is\n// commonly used when an existing trace crosses trust boundaries and the\n// remote parent span context should be ignored for security.\nfunc (cfg *SpanConfig) NewRoot() bool {\n\treturn cfg.newRoot\n}\n\n// SpanKind is the role a Span has in a trace.\nfunc (cfg *SpanConfig) SpanKind() SpanKind {\n\treturn cfg.spanKind\n}\n\n// NewSpanStartConfig applies all the options to a returned SpanConfig.\n// No validation is performed on the returned SpanConfig (e.g. no uniqueness\n// checking or bounding of data), it is left to the SDK to perform this\n// action.\nfunc NewSpanStartConfig(options ...SpanStartOption) SpanConfig {\n\tvar c SpanConfig\n\tfor _, option := range options {\n\t\tc = option.applySpanStart(c)\n\t}\n\treturn c\n}\n\n// NewSpanEndConfig applies all the options to a returned SpanConfig.\n// No validation is performed on the returned SpanConfig (e.g. no uniqueness\n// checking or bounding of data), it is left to the SDK to perform this\n// action.\nfunc NewSpanEndConfig(options ...SpanEndOption) SpanConfig {\n\tvar c SpanConfig\n\tfor _, option := range options {\n\t\tc = option.applySpanEnd(c)\n\t}\n\treturn c\n}\n\n// SpanStartOption applies an option to a SpanConfig. These options are applicable\n// only when the span is created.\ntype SpanStartOption interface {\n\tapplySpanStart(SpanConfig) SpanConfig\n}\n\ntype spanOptionFunc func(SpanConfig) SpanConfig\n\nfunc (fn spanOptionFunc) applySpanStart(cfg SpanConfig) SpanConfig {\n\treturn fn(cfg)\n}\n\n// SpanEndOption applies an option to a SpanConfig. These options are\n// applicable only when the span is ended.\ntype SpanEndOption interface {\n\tapplySpanEnd(SpanConfig) SpanConfig\n}\n\n// EventConfig is a group of options for an Event.\ntype EventConfig struct {\n\tattributes []attribute.KeyValue\n\ttimestamp  time.Time\n\tstackTrace bool\n}\n\n// Attributes describe the associated qualities of an Event.\nfunc (cfg *EventConfig) Attributes() []attribute.KeyValue {\n\treturn cfg.attributes\n}\n\n// Timestamp is a time in an Event life-cycle.\nfunc (cfg *EventConfig) Timestamp() time.Time {\n\treturn cfg.timestamp\n}\n\n// StackTrace checks whether stack trace capturing is enabled.\nfunc (cfg *EventConfig) StackTrace() bool {\n\treturn cfg.stackTrace\n}\n\n// NewEventConfig applies all the EventOptions to a returned EventConfig. If no\n// timestamp option is passed, the returned EventConfig will have a Timestamp\n// set to the call time, otherwise no validation is performed on the returned\n// EventConfig.\nfunc NewEventConfig(options ...EventOption) EventConfig {\n\tvar c EventConfig\n\tfor _, option := range options {\n\t\tc = option.applyEvent(c)\n\t}\n\tif c.timestamp.IsZero() {\n\t\tc.timestamp = time.Now()\n\t}\n\treturn c\n}\n\n// EventOption applies span event options to an EventConfig.\ntype EventOption interface {\n\tapplyEvent(EventConfig) EventConfig\n}\n\n// SpanOption are options that can be used at both the beginning and end of a span.\ntype SpanOption interface {\n\tSpanStartOption\n\tSpanEndOption\n}\n\n// SpanStartEventOption are options that can be used at the start of a span, or with an event.\ntype SpanStartEventOption interface {\n\tSpanStartOption\n\tEventOption\n}\n\n// SpanEndEventOption are options that can be used at the end of a span, or with an event.\ntype SpanEndEventOption interface {\n\tSpanEndOption\n\tEventOption\n}\n\ntype attributeOption []attribute.KeyValue\n\nfunc (o attributeOption) applySpan(c SpanConfig) SpanConfig {\n\tc.attributes = append(c.attributes, []attribute.KeyValue(o)...)\n\treturn c\n}\nfunc (o attributeOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }\nfunc (o attributeOption) applyEvent(c EventConfig) EventConfig {\n\tc.attributes = append(c.attributes, []attribute.KeyValue(o)...)\n\treturn c\n}\n\nvar _ SpanStartEventOption = attributeOption{}\n\n// WithAttributes adds the attributes related to a span life-cycle event.\n// These attributes are used to describe the work a Span represents when this\n// option is provided to a Span's start or end events. Otherwise, these\n// attributes provide additional information about the event being recorded\n// (e.g. error, state change, processing progress, system event).\n//\n// If multiple of these options are passed the attributes of each successive\n// option will extend the attributes instead of overwriting. There is no\n// guarantee of uniqueness in the resulting attributes.\nfunc WithAttributes(attributes ...attribute.KeyValue) SpanStartEventOption {\n\treturn attributeOption(attributes)\n}\n\n// SpanEventOption are options that can be used with an event or a span.\ntype SpanEventOption interface {\n\tSpanOption\n\tEventOption\n}\n\ntype timestampOption time.Time\n\nfunc (o timestampOption) applySpan(c SpanConfig) SpanConfig {\n\tc.timestamp = time.Time(o)\n\treturn c\n}\nfunc (o timestampOption) applySpanStart(c SpanConfig) SpanConfig { return o.applySpan(c) }\nfunc (o timestampOption) applySpanEnd(c SpanConfig) SpanConfig   { return o.applySpan(c) }\nfunc (o timestampOption) applyEvent(c EventConfig) EventConfig {\n\tc.timestamp = time.Time(o)\n\treturn c\n}\n\nvar _ SpanEventOption = timestampOption{}\n\n// WithTimestamp sets the time of a Span or Event life-cycle moment (e.g.\n// started, stopped, errored).\nfunc WithTimestamp(t time.Time) SpanEventOption {\n\treturn timestampOption(t)\n}\n\ntype stackTraceOption bool\n\nfunc (o stackTraceOption) applyEvent(c EventConfig) EventConfig {\n\tc.stackTrace = bool(o)\n\treturn c\n}\nfunc (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {\n\tc.stackTrace = bool(o)\n\treturn c\n}\nfunc (o stackTraceOption) applySpanEnd(c SpanConfig) SpanConfig { return o.applySpan(c) }\n\n// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false).\nfunc WithStackTrace(b bool) SpanEndEventOption {\n\treturn stackTraceOption(b)\n}\n\n// WithLinks adds links to a Span. The links are added to the existing Span\n// links, i.e. this does not overwrite. Links with invalid span context are ignored.\nfunc WithLinks(links ...Link) SpanStartOption {\n\treturn spanOptionFunc(func(cfg SpanConfig) SpanConfig {\n\t\tcfg.links = append(cfg.links, links...)\n\t\treturn cfg\n\t})\n}\n\n// WithNewRoot specifies that the Span should be treated as a root Span. Any\n// existing parent span context will be ignored when defining the Span's trace\n// identifiers.\nfunc WithNewRoot() SpanStartOption {\n\treturn spanOptionFunc(func(cfg SpanConfig) SpanConfig {\n\t\tcfg.newRoot = true\n\t\treturn cfg\n\t})\n}\n\n// WithSpanKind sets the SpanKind of a Span.\nfunc WithSpanKind(kind SpanKind) SpanStartOption {\n\treturn spanOptionFunc(func(cfg SpanConfig) SpanConfig {\n\t\tcfg.spanKind = kind\n\t\treturn cfg\n\t})\n}\n\n// WithInstrumentationVersion sets the instrumentation version.\nfunc WithInstrumentationVersion(version string) TracerOption {\n\treturn tracerOptionFunc(func(cfg TracerConfig) TracerConfig {\n\t\tcfg.instrumentationVersion = version\n\t\treturn cfg\n\t})\n}\n\n// WithInstrumentationAttributes sets the instrumentation attributes.\n//\n// The passed attributes will be de-duplicated.\nfunc WithInstrumentationAttributes(attr ...attribute.KeyValue) TracerOption {\n\treturn tracerOptionFunc(func(config TracerConfig) TracerConfig {\n\t\tconfig.attrs = attribute.NewSet(attr...)\n\t\treturn config\n\t})\n}\n\n// WithSchemaURL sets the schema URL for the Tracer.\nfunc WithSchemaURL(schemaURL string) TracerOption {\n\treturn tracerOptionFunc(func(cfg TracerConfig) TracerConfig {\n\t\tcfg.schemaURL = schemaURL\n\t\treturn cfg\n\t})\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/context.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport \"context\"\n\ntype traceContextKeyType int\n\nconst currentSpanKey traceContextKeyType = iota\n\n// ContextWithSpan returns a copy of parent with span set as the current Span.\nfunc ContextWithSpan(parent context.Context, span Span) context.Context {\n\treturn context.WithValue(parent, currentSpanKey, span)\n}\n\n// ContextWithSpanContext returns a copy of parent with sc as the current\n// Span. The Span implementation that wraps sc is non-recording and performs\n// no operations other than to return sc as the SpanContext from the\n// SpanContext method.\nfunc ContextWithSpanContext(parent context.Context, sc SpanContext) context.Context {\n\treturn ContextWithSpan(parent, nonRecordingSpan{sc: sc})\n}\n\n// ContextWithRemoteSpanContext returns a copy of parent with rsc set explicly\n// as a remote SpanContext and as the current Span. The Span implementation\n// that wraps rsc is non-recording and performs no operations other than to\n// return rsc as the SpanContext from the SpanContext method.\nfunc ContextWithRemoteSpanContext(parent context.Context, rsc SpanContext) context.Context {\n\treturn ContextWithSpanContext(parent, rsc.WithRemote(true))\n}\n\n// SpanFromContext returns the current Span from ctx.\n//\n// If no Span is currently set in ctx an implementation of a Span that\n// performs no operations is returned.\nfunc SpanFromContext(ctx context.Context) Span {\n\tif ctx == nil {\n\t\treturn noopSpan{}\n\t}\n\tif span, ok := ctx.Value(currentSpanKey).(Span); ok {\n\t\treturn span\n\t}\n\treturn noopSpan{}\n}\n\n// SpanContextFromContext returns the current Span's SpanContext.\nfunc SpanContextFromContext(ctx context.Context) SpanContext {\n\treturn SpanFromContext(ctx).SpanContext()\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/doc.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\n/*\nPackage trace provides an implementation of the tracing part of the\nOpenTelemetry API.\n\nTo participate in distributed traces a Span needs to be created for the\noperation being performed as part of a traced workflow. In its simplest form:\n\n\tvar tracer trace.Tracer\n\n\tfunc init() {\n\t\ttracer = otel.Tracer(\"instrumentation/package/name\")\n\t}\n\n\tfunc operation(ctx context.Context) {\n\t\tvar span trace.Span\n\t\tctx, span = tracer.Start(ctx, \"operation\")\n\t\tdefer span.End()\n\t\t// ...\n\t}\n\nA Tracer is unique to the instrumentation and is used to create Spans.\nInstrumentation should be designed to accept a TracerProvider from which it\ncan create its own unique Tracer. Alternatively, the registered global\nTracerProvider from the go.opentelemetry.io/otel package can be used as\na default.\n\n\tconst (\n\t\tname    = \"instrumentation/package/name\"\n\t\tversion = \"0.1.0\"\n\t)\n\n\ttype Instrumentation struct {\n\t\ttracer trace.Tracer\n\t}\n\n\tfunc NewInstrumentation(tp trace.TracerProvider) *Instrumentation {\n\t\tif tp == nil {\n\t\t\ttp = otel.TracerProvider()\n\t\t}\n\t\treturn &Instrumentation{\n\t\t\ttracer: tp.Tracer(name, trace.WithInstrumentationVersion(version)),\n\t\t}\n\t}\n\n\tfunc operation(ctx context.Context, inst *Instrumentation) {\n\t\tvar span trace.Span\n\t\tctx, span = inst.tracer.Start(ctx, \"operation\")\n\t\tdefer span.End()\n\t\t// ...\n\t}\n*/\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/nonrecording.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\n// nonRecordingSpan is a minimal implementation of a Span that wraps a\n// SpanContext. It performs no operations other than to return the wrapped\n// SpanContext.\ntype nonRecordingSpan struct {\n\tnoopSpan\n\n\tsc SpanContext\n}\n\n// SpanContext returns the wrapped SpanContext.\nfunc (s nonRecordingSpan) SpanContext() SpanContext { return s.sc }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/noop.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"context\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n)\n\n// NewNoopTracerProvider returns an implementation of TracerProvider that\n// performs no operations. The Tracer and Spans created from the returned\n// TracerProvider also perform no operations.\nfunc NewNoopTracerProvider() TracerProvider {\n\treturn noopTracerProvider{}\n}\n\ntype noopTracerProvider struct{}\n\nvar _ TracerProvider = noopTracerProvider{}\n\n// Tracer returns noop implementation of Tracer.\nfunc (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer {\n\treturn noopTracer{}\n}\n\n// noopTracer is an implementation of Tracer that performs no operations.\ntype noopTracer struct{}\n\nvar _ Tracer = noopTracer{}\n\n// Start carries forward a non-recording Span, if one is present in the context, otherwise it\n// creates a no-op Span.\nfunc (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption) (context.Context, Span) {\n\tspan := SpanFromContext(ctx)\n\tif _, ok := span.(nonRecordingSpan); !ok {\n\t\t// span is likely already a noopSpan, but let's be sure\n\t\tspan = noopSpan{}\n\t}\n\treturn ContextWithSpan(ctx, span), span\n}\n\n// noopSpan is an implementation of Span that performs no operations.\ntype noopSpan struct{}\n\nvar _ Span = noopSpan{}\n\n// SpanContext returns an empty span context.\nfunc (noopSpan) SpanContext() SpanContext { return SpanContext{} }\n\n// IsRecording always returns false.\nfunc (noopSpan) IsRecording() bool { return false }\n\n// SetStatus does nothing.\nfunc (noopSpan) SetStatus(codes.Code, string) {}\n\n// SetError does nothing.\nfunc (noopSpan) SetError(bool) {}\n\n// SetAttributes does nothing.\nfunc (noopSpan) SetAttributes(...attribute.KeyValue) {}\n\n// End does nothing.\nfunc (noopSpan) End(...SpanEndOption) {}\n\n// RecordError does nothing.\nfunc (noopSpan) RecordError(error, ...EventOption) {}\n\n// AddEvent does nothing.\nfunc (noopSpan) AddEvent(string, ...EventOption) {}\n\n// SetName does nothing.\nfunc (noopSpan) SetName(string) {}\n\n// TracerProvider returns a no-op TracerProvider.\nfunc (noopSpan) TracerProvider() TracerProvider { return noopTracerProvider{} }\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\n\t\"go.opentelemetry.io/otel/attribute\"\n\t\"go.opentelemetry.io/otel/codes\"\n)\n\nconst (\n\t// FlagsSampled is a bitmask with the sampled bit set. A SpanContext\n\t// with the sampling bit set means the span is sampled.\n\tFlagsSampled = TraceFlags(0x01)\n\n\terrInvalidHexID errorConst = \"trace-id and span-id can only contain [0-9a-f] characters, all lowercase\"\n\n\terrInvalidTraceIDLength errorConst = \"hex encoded trace-id must have length equals to 32\"\n\terrNilTraceID           errorConst = \"trace-id can't be all zero\"\n\n\terrInvalidSpanIDLength errorConst = \"hex encoded span-id must have length equals to 16\"\n\terrNilSpanID           errorConst = \"span-id can't be all zero\"\n)\n\ntype errorConst string\n\nfunc (e errorConst) Error() string {\n\treturn string(e)\n}\n\n// TraceID is a unique identity of a trace.\n// nolint:revive // revive complains about stutter of `trace.TraceID`.\ntype TraceID [16]byte\n\nvar nilTraceID TraceID\nvar _ json.Marshaler = nilTraceID\n\n// IsValid checks whether the trace TraceID is valid. A valid trace ID does\n// not consist of zeros only.\nfunc (t TraceID) IsValid() bool {\n\treturn !bytes.Equal(t[:], nilTraceID[:])\n}\n\n// MarshalJSON implements a custom marshal function to encode TraceID\n// as a hex string.\nfunc (t TraceID) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(t.String())\n}\n\n// String returns the hex string representation form of a TraceID.\nfunc (t TraceID) String() string {\n\treturn hex.EncodeToString(t[:])\n}\n\n// SpanID is a unique identity of a span in a trace.\ntype SpanID [8]byte\n\nvar nilSpanID SpanID\nvar _ json.Marshaler = nilSpanID\n\n// IsValid checks whether the SpanID is valid. A valid SpanID does not consist\n// of zeros only.\nfunc (s SpanID) IsValid() bool {\n\treturn !bytes.Equal(s[:], nilSpanID[:])\n}\n\n// MarshalJSON implements a custom marshal function to encode SpanID\n// as a hex string.\nfunc (s SpanID) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(s.String())\n}\n\n// String returns the hex string representation form of a SpanID.\nfunc (s SpanID) String() string {\n\treturn hex.EncodeToString(s[:])\n}\n\n// TraceIDFromHex returns a TraceID from a hex string if it is compliant with\n// the W3C trace-context specification.  See more at\n// https://www.w3.org/TR/trace-context/#trace-id\n// nolint:revive // revive complains about stutter of `trace.TraceIDFromHex`.\nfunc TraceIDFromHex(h string) (TraceID, error) {\n\tt := TraceID{}\n\tif len(h) != 32 {\n\t\treturn t, errInvalidTraceIDLength\n\t}\n\n\tif err := decodeHex(h, t[:]); err != nil {\n\t\treturn t, err\n\t}\n\n\tif !t.IsValid() {\n\t\treturn t, errNilTraceID\n\t}\n\treturn t, nil\n}\n\n// SpanIDFromHex returns a SpanID from a hex string if it is compliant\n// with the w3c trace-context specification.\n// See more at https://www.w3.org/TR/trace-context/#parent-id\nfunc SpanIDFromHex(h string) (SpanID, error) {\n\ts := SpanID{}\n\tif len(h) != 16 {\n\t\treturn s, errInvalidSpanIDLength\n\t}\n\n\tif err := decodeHex(h, s[:]); err != nil {\n\t\treturn s, err\n\t}\n\n\tif !s.IsValid() {\n\t\treturn s, errNilSpanID\n\t}\n\treturn s, nil\n}\n\nfunc decodeHex(h string, b []byte) error {\n\tfor _, r := range h {\n\t\tswitch {\n\t\tcase 'a' <= r && r <= 'f':\n\t\t\tcontinue\n\t\tcase '0' <= r && r <= '9':\n\t\t\tcontinue\n\t\tdefault:\n\t\t\treturn errInvalidHexID\n\t\t}\n\t}\n\n\tdecoded, err := hex.DecodeString(h)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcopy(b, decoded)\n\treturn nil\n}\n\n// TraceFlags contains flags that can be set on a SpanContext.\ntype TraceFlags byte //nolint:revive // revive complains about stutter of `trace.TraceFlags`.\n\n// IsSampled returns if the sampling bit is set in the TraceFlags.\nfunc (tf TraceFlags) IsSampled() bool {\n\treturn tf&FlagsSampled == FlagsSampled\n}\n\n// WithSampled sets the sampling bit in a new copy of the TraceFlags.\nfunc (tf TraceFlags) WithSampled(sampled bool) TraceFlags { // nolint:revive  // sampled is not a control flag.\n\tif sampled {\n\t\treturn tf | FlagsSampled\n\t}\n\n\treturn tf &^ FlagsSampled\n}\n\n// MarshalJSON implements a custom marshal function to encode TraceFlags\n// as a hex string.\nfunc (tf TraceFlags) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(tf.String())\n}\n\n// String returns the hex string representation form of TraceFlags.\nfunc (tf TraceFlags) String() string {\n\treturn hex.EncodeToString([]byte{byte(tf)}[:])\n}\n\n// SpanContextConfig contains mutable fields usable for constructing\n// an immutable SpanContext.\ntype SpanContextConfig struct {\n\tTraceID    TraceID\n\tSpanID     SpanID\n\tTraceFlags TraceFlags\n\tTraceState TraceState\n\tRemote     bool\n}\n\n// NewSpanContext constructs a SpanContext using values from the provided\n// SpanContextConfig.\nfunc NewSpanContext(config SpanContextConfig) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    config.TraceID,\n\t\tspanID:     config.SpanID,\n\t\ttraceFlags: config.TraceFlags,\n\t\ttraceState: config.TraceState,\n\t\tremote:     config.Remote,\n\t}\n}\n\n// SpanContext contains identifying trace information about a Span.\ntype SpanContext struct {\n\ttraceID    TraceID\n\tspanID     SpanID\n\ttraceFlags TraceFlags\n\ttraceState TraceState\n\tremote     bool\n}\n\nvar _ json.Marshaler = SpanContext{}\n\n// IsValid returns if the SpanContext is valid. A valid span context has a\n// valid TraceID and SpanID.\nfunc (sc SpanContext) IsValid() bool {\n\treturn sc.HasTraceID() && sc.HasSpanID()\n}\n\n// IsRemote indicates whether the SpanContext represents a remotely-created Span.\nfunc (sc SpanContext) IsRemote() bool {\n\treturn sc.remote\n}\n\n// WithRemote returns a copy of sc with the Remote property set to remote.\nfunc (sc SpanContext) WithRemote(remote bool) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     remote,\n\t}\n}\n\n// TraceID returns the TraceID from the SpanContext.\nfunc (sc SpanContext) TraceID() TraceID {\n\treturn sc.traceID\n}\n\n// HasTraceID checks if the SpanContext has a valid TraceID.\nfunc (sc SpanContext) HasTraceID() bool {\n\treturn sc.traceID.IsValid()\n}\n\n// WithTraceID returns a new SpanContext with the TraceID replaced.\nfunc (sc SpanContext) WithTraceID(traceID TraceID) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// SpanID returns the SpanID from the SpanContext.\nfunc (sc SpanContext) SpanID() SpanID {\n\treturn sc.spanID\n}\n\n// HasSpanID checks if the SpanContext has a valid SpanID.\nfunc (sc SpanContext) HasSpanID() bool {\n\treturn sc.spanID.IsValid()\n}\n\n// WithSpanID returns a new SpanContext with the SpanID replaced.\nfunc (sc SpanContext) WithSpanID(spanID SpanID) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// TraceFlags returns the flags from the SpanContext.\nfunc (sc SpanContext) TraceFlags() TraceFlags {\n\treturn sc.traceFlags\n}\n\n// IsSampled returns if the sampling bit is set in the SpanContext's TraceFlags.\nfunc (sc SpanContext) IsSampled() bool {\n\treturn sc.traceFlags.IsSampled()\n}\n\n// WithTraceFlags returns a new SpanContext with the TraceFlags replaced.\nfunc (sc SpanContext) WithTraceFlags(flags TraceFlags) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: flags,\n\t\ttraceState: sc.traceState,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// TraceState returns the TraceState from the SpanContext.\nfunc (sc SpanContext) TraceState() TraceState {\n\treturn sc.traceState\n}\n\n// WithTraceState returns a new SpanContext with the TraceState replaced.\nfunc (sc SpanContext) WithTraceState(state TraceState) SpanContext {\n\treturn SpanContext{\n\t\ttraceID:    sc.traceID,\n\t\tspanID:     sc.spanID,\n\t\ttraceFlags: sc.traceFlags,\n\t\ttraceState: state,\n\t\tremote:     sc.remote,\n\t}\n}\n\n// Equal is a predicate that determines whether two SpanContext values are equal.\nfunc (sc SpanContext) Equal(other SpanContext) bool {\n\treturn sc.traceID == other.traceID &&\n\t\tsc.spanID == other.spanID &&\n\t\tsc.traceFlags == other.traceFlags &&\n\t\tsc.traceState.String() == other.traceState.String() &&\n\t\tsc.remote == other.remote\n}\n\n// MarshalJSON implements a custom marshal function to encode a SpanContext.\nfunc (sc SpanContext) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(SpanContextConfig{\n\t\tTraceID:    sc.traceID,\n\t\tSpanID:     sc.spanID,\n\t\tTraceFlags: sc.traceFlags,\n\t\tTraceState: sc.traceState,\n\t\tRemote:     sc.remote,\n\t})\n}\n\n// Span is the individual component of a trace. It represents a single named\n// and timed operation of a workflow that is traced. A Tracer is used to\n// create a Span and it is then up to the operation the Span represents to\n// properly end the Span when the operation itself ends.\n//\n// Warning: methods may be added to this interface in minor releases.\ntype Span interface {\n\t// End completes the Span. The Span is considered complete and ready to be\n\t// delivered through the rest of the telemetry pipeline after this method\n\t// is called. Therefore, updates to the Span are not allowed after this\n\t// method has been called.\n\tEnd(options ...SpanEndOption)\n\n\t// AddEvent adds an event with the provided name and options.\n\tAddEvent(name string, options ...EventOption)\n\n\t// IsRecording returns the recording state of the Span. It will return\n\t// true if the Span is active and events can be recorded.\n\tIsRecording() bool\n\n\t// RecordError will record err as an exception span event for this span. An\n\t// additional call to SetStatus is required if the Status of the Span should\n\t// be set to Error, as this method does not change the Span status. If this\n\t// span is not being recorded or err is nil then this method does nothing.\n\tRecordError(err error, options ...EventOption)\n\n\t// SpanContext returns the SpanContext of the Span. The returned SpanContext\n\t// is usable even after the End method has been called for the Span.\n\tSpanContext() SpanContext\n\n\t// SetStatus sets the status of the Span in the form of a code and a\n\t// description, provided the status hasn't already been set to a higher\n\t// value before (OK > Error > Unset). The description is only included in a\n\t// status when the code is for an error.\n\tSetStatus(code codes.Code, description string)\n\n\t// SetName sets the Span name.\n\tSetName(name string)\n\n\t// SetAttributes sets kv as attributes of the Span. If a key from kv\n\t// already exists for an attribute of the Span it will be overwritten with\n\t// the value contained in kv.\n\tSetAttributes(kv ...attribute.KeyValue)\n\n\t// TracerProvider returns a TracerProvider that can be used to generate\n\t// additional Spans on the same telemetry pipeline as the current Span.\n\tTracerProvider() TracerProvider\n}\n\n// Link is the relationship between two Spans. The relationship can be within\n// the same Trace or across different Traces.\n//\n// For example, a Link is used in the following situations:\n//\n//  1. Batch Processing: A batch of operations may contain operations\n//     associated with one or more traces/spans. Since there can only be one\n//     parent SpanContext, a Link is used to keep reference to the\n//     SpanContext of all operations in the batch.\n//  2. Public Endpoint: A SpanContext for an in incoming client request on a\n//     public endpoint should be considered untrusted. In such a case, a new\n//     trace with its own identity and sampling decision needs to be created,\n//     but this new trace needs to be related to the original trace in some\n//     form. A Link is used to keep reference to the original SpanContext and\n//     track the relationship.\ntype Link struct {\n\t// SpanContext of the linked Span.\n\tSpanContext SpanContext\n\n\t// Attributes describe the aspects of the link.\n\tAttributes []attribute.KeyValue\n}\n\n// LinkFromContext returns a link encapsulating the SpanContext in the provided ctx.\nfunc LinkFromContext(ctx context.Context, attrs ...attribute.KeyValue) Link {\n\treturn Link{\n\t\tSpanContext: SpanContextFromContext(ctx),\n\t\tAttributes:  attrs,\n\t}\n}\n\n// SpanKind is the role a Span plays in a Trace.\ntype SpanKind int\n\n// As a convenience, these match the proto definition, see\n// https://github.com/open-telemetry/opentelemetry-proto/blob/30d237e1ff3ab7aa50e0922b5bebdd93505090af/opentelemetry/proto/trace/v1/trace.proto#L101-L129\n//\n// The unspecified value is not a valid `SpanKind`. Use `ValidateSpanKind()`\n// to coerce a span kind to a valid value.\nconst (\n\t// SpanKindUnspecified is an unspecified SpanKind and is not a valid\n\t// SpanKind. SpanKindUnspecified should be replaced with SpanKindInternal\n\t// if it is received.\n\tSpanKindUnspecified SpanKind = 0\n\t// SpanKindInternal is a SpanKind for a Span that represents an internal\n\t// operation within an application.\n\tSpanKindInternal SpanKind = 1\n\t// SpanKindServer is a SpanKind for a Span that represents the operation\n\t// of handling a request from a client.\n\tSpanKindServer SpanKind = 2\n\t// SpanKindClient is a SpanKind for a Span that represents the operation\n\t// of client making a request to a server.\n\tSpanKindClient SpanKind = 3\n\t// SpanKindProducer is a SpanKind for a Span that represents the operation\n\t// of a producer sending a message to a message broker. Unlike\n\t// SpanKindClient and SpanKindServer, there is often no direct\n\t// relationship between this kind of Span and a SpanKindConsumer kind. A\n\t// SpanKindProducer Span will end once the message is accepted by the\n\t// message broker which might not overlap with the processing of that\n\t// message.\n\tSpanKindProducer SpanKind = 4\n\t// SpanKindConsumer is a SpanKind for a Span that represents the operation\n\t// of a consumer receiving a message from a message broker. Like\n\t// SpanKindProducer Spans, there is often no direct relationship between\n\t// this Span and the Span that produced the message.\n\tSpanKindConsumer SpanKind = 5\n)\n\n// ValidateSpanKind returns a valid span kind value.  This will coerce\n// invalid values into the default value, SpanKindInternal.\nfunc ValidateSpanKind(spanKind SpanKind) SpanKind {\n\tswitch spanKind {\n\tcase SpanKindInternal,\n\t\tSpanKindServer,\n\t\tSpanKindClient,\n\t\tSpanKindProducer,\n\t\tSpanKindConsumer:\n\t\t// valid\n\t\treturn spanKind\n\tdefault:\n\t\treturn SpanKindInternal\n\t}\n}\n\n// String returns the specified name of the SpanKind in lower-case.\nfunc (sk SpanKind) String() string {\n\tswitch sk {\n\tcase SpanKindInternal:\n\t\treturn \"internal\"\n\tcase SpanKindServer:\n\t\treturn \"server\"\n\tcase SpanKindClient:\n\t\treturn \"client\"\n\tcase SpanKindProducer:\n\t\treturn \"producer\"\n\tcase SpanKindConsumer:\n\t\treturn \"consumer\"\n\tdefault:\n\t\treturn \"unspecified\"\n\t}\n}\n\n// Tracer is the creator of Spans.\n//\n// Warning: methods may be added to this interface in minor releases.\ntype Tracer interface {\n\t// Start creates a span and a context.Context containing the newly-created span.\n\t//\n\t// If the context.Context provided in `ctx` contains a Span then the newly-created\n\t// Span will be a child of that span, otherwise it will be a root span. This behavior\n\t// can be overridden by providing `WithNewRoot()` as a SpanOption, causing the\n\t// newly-created Span to be a root span even if `ctx` contains a Span.\n\t//\n\t// When creating a Span it is recommended to provide all known span attributes using\n\t// the `WithAttributes()` SpanOption as samplers will only have access to the\n\t// attributes provided when a Span is created.\n\t//\n\t// Any Span that is created MUST also be ended. This is the responsibility of the user.\n\t// Implementations of this API may leak memory or other resources if Spans are not ended.\n\tStart(ctx context.Context, spanName string, opts ...SpanStartOption) (context.Context, Span)\n}\n\n// TracerProvider provides Tracers that are used by instrumentation code to\n// trace computational workflows.\n//\n// A TracerProvider is the collection destination of all Spans from Tracers it\n// provides, it represents a unique telemetry collection pipeline. How that\n// pipeline is defined, meaning how those Spans are collected, processed, and\n// where they are exported, depends on its implementation. Instrumentation\n// authors do not need to define this implementation, rather just use the\n// provided Tracers to instrument code.\n//\n// Commonly, instrumentation code will accept a TracerProvider implementation\n// at runtime from its users or it can simply use the globally registered one\n// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider).\n//\n// Warning: methods may be added to this interface in minor releases.\ntype TracerProvider interface {\n\t// Tracer returns a unique Tracer scoped to be used by instrumentation code\n\t// to trace computational workflows. The scope and identity of that\n\t// instrumentation code is uniquely defined by the name and options passed.\n\t//\n\t// The passed name needs to uniquely identify instrumentation code.\n\t// Therefore, it is recommended that name is the Go package name of the\n\t// library providing instrumentation (note: not the code being\n\t// instrumented). Instrumentation libraries can have multiple versions,\n\t// therefore, the WithInstrumentationVersion option should be used to\n\t// distinguish these different codebases. Additionally, instrumentation\n\t// libraries may sometimes use traces to communicate different domains of\n\t// workflow data (i.e. using spans to communicate workflow events only). If\n\t// this is the case, the WithScopeAttributes option should be used to\n\t// uniquely identify Tracers that handle the different domains of workflow\n\t// data.\n\t//\n\t// If the same name and options are passed multiple times, the same Tracer\n\t// will be returned (it is up to the implementation if this will be the\n\t// same underlying instance of that Tracer or not). It is not necessary to\n\t// call this multiple times with the same name and options to get an\n\t// up-to-date Tracer. All implementations will ensure any TracerProvider\n\t// configuration changes are propagated to all provided Tracers.\n\t//\n\t// If name is empty, then an implementation defined default name will be\n\t// used instead.\n\t//\n\t// This method is safe to call concurrently.\n\tTracer(name string, options ...TracerOption) Tracer\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace/tracestate.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage trace // import \"go.opentelemetry.io/otel/trace\"\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n)\n\nconst (\n\tmaxListMembers = 32\n\n\tlistDelimiter = \",\"\n\n\t// based on the W3C Trace Context specification, see\n\t// https://www.w3.org/TR/trace-context-1/#tracestate-header\n\tnoTenantKeyFormat   = `[a-z][_0-9a-z\\-\\*\\/]{0,255}`\n\twithTenantKeyFormat = `[a-z0-9][_0-9a-z\\-\\*\\/]{0,240}@[a-z][_0-9a-z\\-\\*\\/]{0,13}`\n\tvalueFormat         = `[\\x20-\\x2b\\x2d-\\x3c\\x3e-\\x7e]{0,255}[\\x21-\\x2b\\x2d-\\x3c\\x3e-\\x7e]`\n\n\terrInvalidKey    errorConst = \"invalid tracestate key\"\n\terrInvalidValue  errorConst = \"invalid tracestate value\"\n\terrInvalidMember errorConst = \"invalid tracestate list-member\"\n\terrMemberNumber  errorConst = \"too many list-members in tracestate\"\n\terrDuplicate     errorConst = \"duplicate list-member in tracestate\"\n)\n\nvar (\n\tkeyRe    = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`)\n\tvalueRe  = regexp.MustCompile(`^(` + valueFormat + `)$`)\n\tmemberRe = regexp.MustCompile(`^\\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\\s*$`)\n)\n\ntype member struct {\n\tKey   string\n\tValue string\n}\n\nfunc newMember(key, value string) (member, error) {\n\tif !keyRe.MatchString(key) {\n\t\treturn member{}, fmt.Errorf(\"%w: %s\", errInvalidKey, key)\n\t}\n\tif !valueRe.MatchString(value) {\n\t\treturn member{}, fmt.Errorf(\"%w: %s\", errInvalidValue, value)\n\t}\n\treturn member{Key: key, Value: value}, nil\n}\n\nfunc parseMember(m string) (member, error) {\n\tmatches := memberRe.FindStringSubmatch(m)\n\tif len(matches) != 5 {\n\t\treturn member{}, fmt.Errorf(\"%w: %s\", errInvalidMember, m)\n\t}\n\n\treturn member{\n\t\tKey:   matches[1],\n\t\tValue: matches[4],\n\t}, nil\n}\n\n// String encodes member into a string compliant with the W3C Trace Context\n// specification.\nfunc (m member) String() string {\n\treturn fmt.Sprintf(\"%s=%s\", m.Key, m.Value)\n}\n\n// TraceState provides additional vendor-specific trace identification\n// information across different distributed tracing systems. It represents an\n// immutable list consisting of key/value pairs, each pair is referred to as a\n// list-member.\n//\n// TraceState conforms to the W3C Trace Context specification\n// (https://www.w3.org/TR/trace-context-1). All operations that create or copy\n// a TraceState do so by validating all input and will only produce TraceState\n// that conform to the specification. Specifically, this means that all\n// list-member's key/value pairs are valid, no duplicate list-members exist,\n// and the maximum number of list-members (32) is not exceeded.\ntype TraceState struct { //nolint:revive // revive complains about stutter of `trace.TraceState`\n\t// list is the members in order.\n\tlist []member\n}\n\nvar _ json.Marshaler = TraceState{}\n\n// ParseTraceState attempts to decode a TraceState from the passed\n// string. It returns an error if the input is invalid according to the W3C\n// Trace Context specification.\nfunc ParseTraceState(tracestate string) (TraceState, error) {\n\tif tracestate == \"\" {\n\t\treturn TraceState{}, nil\n\t}\n\n\twrapErr := func(err error) error {\n\t\treturn fmt.Errorf(\"failed to parse tracestate: %w\", err)\n\t}\n\n\tvar members []member\n\tfound := make(map[string]struct{})\n\tfor _, memberStr := range strings.Split(tracestate, listDelimiter) {\n\t\tif len(memberStr) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tm, err := parseMember(memberStr)\n\t\tif err != nil {\n\t\t\treturn TraceState{}, wrapErr(err)\n\t\t}\n\n\t\tif _, ok := found[m.Key]; ok {\n\t\t\treturn TraceState{}, wrapErr(errDuplicate)\n\t\t}\n\t\tfound[m.Key] = struct{}{}\n\n\t\tmembers = append(members, m)\n\t\tif n := len(members); n > maxListMembers {\n\t\t\treturn TraceState{}, wrapErr(errMemberNumber)\n\t\t}\n\t}\n\n\treturn TraceState{list: members}, nil\n}\n\n// MarshalJSON marshals the TraceState into JSON.\nfunc (ts TraceState) MarshalJSON() ([]byte, error) {\n\treturn json.Marshal(ts.String())\n}\n\n// String encodes the TraceState into a string compliant with the W3C\n// Trace Context specification. The returned string will be invalid if the\n// TraceState contains any invalid members.\nfunc (ts TraceState) String() string {\n\tmembers := make([]string, len(ts.list))\n\tfor i, m := range ts.list {\n\t\tmembers[i] = m.String()\n\t}\n\treturn strings.Join(members, listDelimiter)\n}\n\n// Get returns the value paired with key from the corresponding TraceState\n// list-member if it exists, otherwise an empty string is returned.\nfunc (ts TraceState) Get(key string) string {\n\tfor _, member := range ts.list {\n\t\tif member.Key == key {\n\t\t\treturn member.Value\n\t\t}\n\t}\n\n\treturn \"\"\n}\n\n// Insert adds a new list-member defined by the key/value pair to the\n// TraceState. If a list-member already exists for the given key, that\n// list-member's value is updated. The new or updated list-member is always\n// moved to the beginning of the TraceState as specified by the W3C Trace\n// Context specification.\n//\n// If key or value are invalid according to the W3C Trace Context\n// specification an error is returned with the original TraceState.\n//\n// If adding a new list-member means the TraceState would have more members\n// then is allowed, the new list-member will be inserted and the right-most\n// list-member will be dropped in the returned TraceState.\nfunc (ts TraceState) Insert(key, value string) (TraceState, error) {\n\tm, err := newMember(key, value)\n\tif err != nil {\n\t\treturn ts, err\n\t}\n\n\tcTS := ts.Delete(key)\n\tif cTS.Len()+1 <= maxListMembers {\n\t\tcTS.list = append(cTS.list, member{})\n\t}\n\t// When the number of members exceeds capacity, drop the \"right-most\".\n\tcopy(cTS.list[1:], cTS.list)\n\tcTS.list[0] = m\n\n\treturn cTS, nil\n}\n\n// Delete returns a copy of the TraceState with the list-member identified by\n// key removed.\nfunc (ts TraceState) Delete(key string) TraceState {\n\tmembers := make([]member, ts.Len())\n\tcopy(members, ts.list)\n\tfor i, member := range ts.list {\n\t\tif member.Key == key {\n\t\t\tmembers = append(members[:i], members[i+1:]...)\n\t\t\t// TraceState should contain no duplicate members.\n\t\t\tbreak\n\t\t}\n\t}\n\treturn TraceState{list: members}\n}\n\n// Len returns the number of list-members in the TraceState.\nfunc (ts TraceState) Len() int {\n\treturn len(ts.list)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/trace.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otel // import \"go.opentelemetry.io/otel\"\n\nimport (\n\t\"go.opentelemetry.io/otel/internal/global\"\n\t\"go.opentelemetry.io/otel/trace\"\n)\n\n// Tracer creates a named tracer that implements Tracer interface.\n// If the name is an empty string then provider uses default name.\n//\n// This is short for GetTracerProvider().Tracer(name, opts...)\nfunc Tracer(name string, opts ...trace.TracerOption) trace.Tracer {\n\treturn GetTracerProvider().Tracer(name, opts...)\n}\n\n// GetTracerProvider returns the registered global trace provider.\n// If none is registered then an instance of NoopTracerProvider is returned.\n//\n// Use the trace provider to create a named tracer. E.g.\n//\n//\ttracer := otel.GetTracerProvider().Tracer(\"example.com/foo\")\n//\n// or\n//\n//\ttracer := otel.Tracer(\"example.com/foo\")\nfunc GetTracerProvider() trace.TracerProvider {\n\treturn global.TracerProvider()\n}\n\n// SetTracerProvider registers `tp` as the global trace provider.\nfunc SetTracerProvider(tp trace.TracerProvider) {\n\tglobal.SetTracerProvider(tp)\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/verify_examples.sh",
    "content": "#!/bin/bash\n\n# Copyright The OpenTelemetry Authors\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#     http://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\nset -euo pipefail\n\ncd $(dirname $0)\nTOOLS_DIR=$(pwd)/.tools\n\nif [ -z \"${GOPATH}\" ] ; then\n\tprintf \"GOPATH is not defined.\\n\"\n\texit -1\nfi\n\nif [ ! -d \"${GOPATH}\" ] ; then\n\tprintf \"GOPATH ${GOPATH} is invalid \\n\"\n\texit -1\nfi\n\n# Pre-requisites\nif ! git diff --quiet; then \\\n\tgit status\n\tprintf \"\\n\\nError: working tree is not clean\\n\"\n\texit -1\nfi\n\nif [ \"$(git tag --contains $(git log -1 --pretty=format:\"%H\"))\" = \"\" ] ; then\n\tprintf \"$(git log -1)\"\n\tprintf \"\\n\\nError: HEAD is not pointing to a tagged version\"\nfi\n\nmake ${TOOLS_DIR}/gojq\n\nDIR_TMP=\"${GOPATH}/src/oteltmp/\"\nrm -rf $DIR_TMP\nmkdir -p $DIR_TMP\n\nprintf \"Copy examples to ${DIR_TMP}\\n\"\ncp -a ./example ${DIR_TMP}\n\n# Update go.mod files\nprintf \"Update go.mod: rename module and remove replace\\n\"\n\nPACKAGE_DIRS=$(find . -mindepth 2 -type f -name 'go.mod' -exec dirname {} \\; | egrep 'example' | sed 's/^\\.\\///' | sort)\n\nfor dir in $PACKAGE_DIRS; do\n\tprintf \"  Update go.mod for $dir\\n\"\n\t(cd \"${DIR_TMP}/${dir}\" && \\\n\t # replaces is (\"mod1\" \"mod2\" …)\n\t replaces=($(go mod edit -json | ${TOOLS_DIR}/gojq '.Replace[].Old.Path')) && \\\n\t # strip double quotes\n\t replaces=(\"${replaces[@]%\\\"}\") && \\\n\t replaces=(\"${replaces[@]#\\\"}\") && \\\n\t # make an array (-dropreplace=mod1 -dropreplace=mod2 …)\n\t dropreplaces=(\"${replaces[@]/#/-dropreplace=}\") && \\\n\t go mod edit -module \"oteltmp/${dir}\" \"${dropreplaces[@]}\" && \\\n\t go mod tidy)\ndone\nprintf \"Update done:\\n\\n\"\n\n# Build directories that contain main package. These directories are different than\n# directories that contain go.mod files.\nprintf \"Build examples:\\n\"\nEXAMPLES=$(./get_main_pkgs.sh ./example)\nfor ex in $EXAMPLES; do\n\tprintf \"  Build $ex in ${DIR_TMP}/${ex}\\n\"\n\t(cd \"${DIR_TMP}/${ex}\" && \\\n\t go build .)\ndone\n\n# Cleanup\nprintf \"Remove copied files.\\n\"\nrm -rf $DIR_TMP\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/version.go",
    "content": "// Copyright The OpenTelemetry Authors\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//     http://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\npackage otel // import \"go.opentelemetry.io/otel\"\n\n// Version is the current release version of OpenTelemetry in use.\nfunc Version() string {\n\treturn \"1.19.0\"\n}\n"
  },
  {
    "path": "vendor/go.opentelemetry.io/otel/versions.yaml",
    "content": "# Copyright The OpenTelemetry Authors\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#     http://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\nmodule-sets:\n  stable-v1:\n    version: v1.19.0\n    modules:\n      - go.opentelemetry.io/otel\n      - go.opentelemetry.io/otel/bridge/opentracing\n      - go.opentelemetry.io/otel/bridge/opentracing/test\n      - go.opentelemetry.io/otel/example/dice\n      - go.opentelemetry.io/otel/example/fib\n      - go.opentelemetry.io/otel/example/namedtracer\n      - go.opentelemetry.io/otel/example/otel-collector\n      - go.opentelemetry.io/otel/example/passthrough\n      - go.opentelemetry.io/otel/example/zipkin\n      - go.opentelemetry.io/otel/exporters/otlp/otlptrace\n      - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc\n      - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp\n      - go.opentelemetry.io/otel/exporters/stdout/stdouttrace\n      - go.opentelemetry.io/otel/exporters/zipkin\n      - go.opentelemetry.io/otel/metric\n      - go.opentelemetry.io/otel/sdk\n      - go.opentelemetry.io/otel/sdk/metric\n      - go.opentelemetry.io/otel/trace\n  experimental-metrics:\n    version: v0.42.0\n    modules:\n      - go.opentelemetry.io/otel/bridge/opencensus\n      - go.opentelemetry.io/otel/bridge/opencensus/test\n      - go.opentelemetry.io/otel/example/opencensus\n      - go.opentelemetry.io/otel/example/prometheus\n      - go.opentelemetry.io/otel/example/view\n      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric\n      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc\n      - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp\n      - go.opentelemetry.io/otel/exporters/prometheus\n      - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric\n  experimental-schema:\n    version: v0.0.7\n    modules:\n      - go.opentelemetry.io/otel/schema\nexcluded-modules:\n  - go.opentelemetry.io/otel/internal/tools\n"
  },
  {
    "path": "vendor/go.starlark.net/LICENSE",
    "content": "Copyright (c) 2017 The Bazel 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\n1. Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n\n2. 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\n   distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived\n   from this 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\nHOLDER 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": "vendor/go.starlark.net/internal/compile/compile.go",
    "content": "// Package compile defines the Starlark bytecode compiler.\n// It is an internal package of the Starlark interpreter and is not directly accessible to clients.\n//\n// The compiler generates byte code with optional uint32 operands for a\n// virtual machine with the following components:\n//   - a program counter, which is an index into the byte code array.\n//   - an operand stack, whose maximum size is computed for each function by the compiler.\n//   - an stack of active iterators.\n//   - an array of local variables.\n//     The number of local variables and their indices are computed by the resolver.\n//     Locals (possibly including parameters) that are shared with nested functions\n//     are 'cells': their locals array slot will contain a value of type 'cell',\n//     an indirect value in a box that is explicitly read/updated by instructions.\n//   - an array of free variables, for nested functions.\n//     Free variables are a subset of the ancestors' cell variables.\n//     As with locals and cells, these are computed by the resolver.\n//   - an array of global variables, shared among all functions in the same module.\n//     All elements are initially nil.\n//   - two maps of predeclared and universal identifiers.\n//\n// Each function has a line number table that maps each program counter\n// offset to a source position, including the column number.\n//\n// Operands, logically uint32s, are encoded using little-endian 7-bit\n// varints, the top bit indicating that more bytes follow.\n//\npackage compile // import \"go.starlark.net/internal/compile\"\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"sync\"\n\n\t\"go.starlark.net/resolve\"\n\t\"go.starlark.net/syntax\"\n)\n\n// Disassemble causes the assembly code for each function\n// to be printed to stderr as it is generated.\nvar Disassemble = false\n\nconst debug = false // make code generation verbose, for debugging the compiler\n\n// Increment this to force recompilation of saved bytecode files.\nconst Version = 10\n\ntype Opcode uint8\n\n// \"x DUP x x\" is a \"stack picture\" that describes the state of the\n// stack before and after execution of the instruction.\n//\n// OP<index> indicates an immediate operand that is an index into the\n// specified table: locals, names, freevars, constants.\nconst (\n\tNOP Opcode = iota // - NOP -\n\n\t// stack operations\n\tDUP  //   x DUP x x\n\tDUP2 // x y DUP2 x y x y\n\tPOP  //   x POP -\n\tEXCH // x y EXCH y x\n\n\t// binary comparisons\n\t// (order must match Token)\n\tLT\n\tGT\n\tGE\n\tLE\n\tEQL\n\tNEQ\n\n\t// binary arithmetic\n\t// (order must match Token)\n\tPLUS\n\tMINUS\n\tSTAR\n\tSLASH\n\tSLASHSLASH\n\tPERCENT\n\tAMP\n\tPIPE\n\tCIRCUMFLEX\n\tLTLT\n\tGTGT\n\n\tIN\n\n\t// unary operators\n\tUPLUS  // x UPLUS x\n\tUMINUS // x UMINUS -x\n\tTILDE  // x TILDE ~x\n\n\tNONE      // - NONE None\n\tTRUE      // - TRUE True\n\tFALSE     // - FALSE False\n\tMANDATORY // - MANDATORY Mandatory\t     [sentinel value for required kwonly args]\n\n\tITERPUSH    //       iterable ITERPUSH    -  [pushes the iterator stack]\n\tITERPOP     //              - ITERPOP     -    [pops the iterator stack]\n\tNOT         //          value NOT         bool\n\tRETURN      //          value RETURN      -\n\tSETINDEX    //        a i new SETINDEX    -\n\tINDEX       //            a i INDEX       elem\n\tSETDICT     // dict key value SETDICT     -\n\tSETDICTUNIQ // dict key value SETDICTUNIQ -\n\tAPPEND      //      list elem APPEND      -\n\tSLICE       //   x lo hi step SLICE       slice\n\tINPLACE_ADD //            x y INPLACE_ADD z      where z is x+y or x.extend(y)\n\tMAKEDICT    //              - MAKEDICT    dict\n\tSETCELL     //     value cell SETCELL     -\n\tCELL        //           cell CELL        value\n\n\t// --- opcodes with an argument must go below this line ---\n\n\t// control flow\n\tJMP     //            - JMP<addr>     -\n\tCJMP    //         cond CJMP<addr>    -\n\tITERJMP //            - ITERJMP<addr> elem   (and fall through) [acts on topmost iterator]\n\t//       or:          - ITERJMP<addr> -      (and jump)\n\n\tCONSTANT    //                 - CONSTANT<constant>  value\n\tMAKETUPLE   //         x1 ... xn MAKETUPLE<n>        tuple\n\tMAKELIST    //         x1 ... xn MAKELIST<n>         list\n\tMAKEFUNC    // defaults+freevars MAKEFUNC<func>      fn\n\tLOAD        //   from1 ... fromN module LOAD<n>      v1 ... vN\n\tSETLOCAL    //             value SETLOCAL<local>     -\n\tSETGLOBAL   //             value SETGLOBAL<global>   -\n\tLOCAL       //                 - LOCAL<local>        value\n\tFREE        //                 - FREE<freevar>       cell\n\tGLOBAL      //                 - GLOBAL<global>      value\n\tPREDECLARED //                 - PREDECLARED<name>   value\n\tUNIVERSAL   //                 - UNIVERSAL<name>     value\n\tATTR        //                 x ATTR<name>          y           y = x.name\n\tSETFIELD    //               x y SETFIELD<name>      -           x.name = y\n\tUNPACK      //          iterable UNPACK<n>           vn ... v1\n\n\t// n>>8 is #positional args and n&0xff is #named args (pairs).\n\tCALL        // fn positional named                CALL<n>        result\n\tCALL_VAR    // fn positional named *args          CALL_VAR<n>    result\n\tCALL_KW     // fn positional named       **kwargs CALL_KW<n>     result\n\tCALL_VAR_KW // fn positional named *args **kwargs CALL_VAR_KW<n> result\n\n\tOpcodeArgMin = JMP\n\tOpcodeMax    = CALL_VAR_KW\n)\n\n// TODO(adonovan): add dynamic checks for missing opcodes in the tables below.\n\nvar opcodeNames = [...]string{\n\tAMP:         \"amp\",\n\tAPPEND:      \"append\",\n\tATTR:        \"attr\",\n\tCALL:        \"call\",\n\tCALL_KW:     \"call_kw \",\n\tCALL_VAR:    \"call_var\",\n\tCALL_VAR_KW: \"call_var_kw\",\n\tCELL:        \"cell\",\n\tCIRCUMFLEX:  \"circumflex\",\n\tCJMP:        \"cjmp\",\n\tCONSTANT:    \"constant\",\n\tDUP2:        \"dup2\",\n\tDUP:         \"dup\",\n\tEQL:         \"eql\",\n\tEXCH:        \"exch\",\n\tFALSE:       \"false\",\n\tFREE:        \"free\",\n\tGE:          \"ge\",\n\tGLOBAL:      \"global\",\n\tGT:          \"gt\",\n\tGTGT:        \"gtgt\",\n\tIN:          \"in\",\n\tINDEX:       \"index\",\n\tINPLACE_ADD: \"inplace_add\",\n\tITERJMP:     \"iterjmp\",\n\tITERPOP:     \"iterpop\",\n\tITERPUSH:    \"iterpush\",\n\tJMP:         \"jmp\",\n\tLE:          \"le\",\n\tLOAD:        \"load\",\n\tLOCAL:       \"local\",\n\tLT:          \"lt\",\n\tLTLT:        \"ltlt\",\n\tMAKEDICT:    \"makedict\",\n\tMAKEFUNC:    \"makefunc\",\n\tMAKELIST:    \"makelist\",\n\tMAKETUPLE:   \"maketuple\",\n\tMANDATORY:   \"mandatory\",\n\tMINUS:       \"minus\",\n\tNEQ:         \"neq\",\n\tNONE:        \"none\",\n\tNOP:         \"nop\",\n\tNOT:         \"not\",\n\tPERCENT:     \"percent\",\n\tPIPE:        \"pipe\",\n\tPLUS:        \"plus\",\n\tPOP:         \"pop\",\n\tPREDECLARED: \"predeclared\",\n\tRETURN:      \"return\",\n\tSETCELL:     \"setcell\",\n\tSETDICT:     \"setdict\",\n\tSETDICTUNIQ: \"setdictuniq\",\n\tSETFIELD:    \"setfield\",\n\tSETGLOBAL:   \"setglobal\",\n\tSETINDEX:    \"setindex\",\n\tSETLOCAL:    \"setlocal\",\n\tSLASH:       \"slash\",\n\tSLASHSLASH:  \"slashslash\",\n\tSLICE:       \"slice\",\n\tSTAR:        \"star\",\n\tTILDE:       \"tilde\",\n\tTRUE:        \"true\",\n\tUMINUS:      \"uminus\",\n\tUNIVERSAL:   \"universal\",\n\tUNPACK:      \"unpack\",\n\tUPLUS:       \"uplus\",\n}\n\nconst variableStackEffect = 0x7f\n\n// stackEffect records the effect on the size of the operand stack of\n// each kind of instruction. For some instructions this requires computation.\nvar stackEffect = [...]int8{\n\tAMP:         -1,\n\tAPPEND:      -2,\n\tATTR:        0,\n\tCALL:        variableStackEffect,\n\tCALL_KW:     variableStackEffect,\n\tCALL_VAR:    variableStackEffect,\n\tCALL_VAR_KW: variableStackEffect,\n\tCELL:        0,\n\tCIRCUMFLEX:  -1,\n\tCJMP:        -1,\n\tCONSTANT:    +1,\n\tDUP2:        +2,\n\tDUP:         +1,\n\tEQL:         -1,\n\tFALSE:       +1,\n\tFREE:        +1,\n\tGE:          -1,\n\tGLOBAL:      +1,\n\tGT:          -1,\n\tGTGT:        -1,\n\tIN:          -1,\n\tINDEX:       -1,\n\tINPLACE_ADD: -1,\n\tITERJMP:     variableStackEffect,\n\tITERPOP:     0,\n\tITERPUSH:    -1,\n\tJMP:         0,\n\tLE:          -1,\n\tLOAD:        -1,\n\tLOCAL:       +1,\n\tLT:          -1,\n\tLTLT:        -1,\n\tMAKEDICT:    +1,\n\tMAKEFUNC:    0,\n\tMAKELIST:    variableStackEffect,\n\tMAKETUPLE:   variableStackEffect,\n\tMANDATORY:   +1,\n\tMINUS:       -1,\n\tNEQ:         -1,\n\tNONE:        +1,\n\tNOP:         0,\n\tNOT:         0,\n\tPERCENT:     -1,\n\tPIPE:        -1,\n\tPLUS:        -1,\n\tPOP:         -1,\n\tPREDECLARED: +1,\n\tRETURN:      -1,\n\tSETCELL:     -2,\n\tSETDICT:     -3,\n\tSETDICTUNIQ: -3,\n\tSETFIELD:    -2,\n\tSETGLOBAL:   -1,\n\tSETINDEX:    -3,\n\tSETLOCAL:    -1,\n\tSLASH:       -1,\n\tSLASHSLASH:  -1,\n\tSLICE:       -3,\n\tSTAR:        -1,\n\tTRUE:        +1,\n\tUMINUS:      0,\n\tUNIVERSAL:   +1,\n\tUNPACK:      variableStackEffect,\n\tUPLUS:       0,\n}\n\nfunc (op Opcode) String() string {\n\tif op < OpcodeMax {\n\t\tif name := opcodeNames[op]; name != \"\" {\n\t\t\treturn name\n\t\t}\n\t}\n\treturn fmt.Sprintf(\"illegal op (%d)\", op)\n}\n\n// A Program is a Starlark file in executable form.\n//\n// Programs are serialized by the Program.Encode method,\n// which must be updated whenever this declaration is changed.\ntype Program struct {\n\tLoads     []Binding     // name (really, string) and position of each load stmt\n\tNames     []string      // names of attributes and predeclared variables\n\tConstants []interface{} // = string | int64 | float64 | *big.Int\n\tFunctions []*Funcode\n\tGlobals   []Binding // for error messages and tracing\n\tToplevel  *Funcode  // module initialization function\n}\n\n// A Funcode is the code of a compiled Starlark function.\n//\n// Funcodes are serialized by the encoder.function method,\n// which must be updated whenever this declaration is changed.\ntype Funcode struct {\n\tProg                  *Program\n\tPos                   syntax.Position // position of def or lambda token\n\tName                  string          // name of this function\n\tDoc                   string          // docstring of this function\n\tCode                  []byte          // the byte code\n\tpclinetab             []uint16        // mapping from pc to linenum\n\tLocals                []Binding       // locals, parameters first\n\tCells                 []int           // indices of Locals that require cells\n\tFreevars              []Binding       // for tracing\n\tMaxStack              int\n\tNumParams             int\n\tNumKwonlyParams       int\n\tHasVarargs, HasKwargs bool\n\n\t// -- transient state --\n\n\tlntOnce sync.Once\n\tlnt     []pclinecol // decoded line number table\n}\n\ntype pclinecol struct {\n\tpc        uint32\n\tline, col int32\n}\n\n// A Binding is the name and position of a binding identifier.\ntype Binding struct {\n\tName string\n\tPos  syntax.Position\n}\n\n// A pcomp holds the compiler state for a Program.\ntype pcomp struct {\n\tprog *Program // what we're building\n\n\tnames     map[string]uint32\n\tconstants map[interface{}]uint32\n\tfunctions map[*Funcode]uint32\n}\n\n// An fcomp holds the compiler state for a Funcode.\ntype fcomp struct {\n\tfn *Funcode // what we're building\n\n\tpcomp *pcomp\n\tpos   syntax.Position // current position of generated code\n\tloops []loop\n\tblock *block\n}\n\ntype loop struct {\n\tbreak_, continue_ *block\n}\n\ntype block struct {\n\tinsns []insn\n\n\t// If the last insn is a RETURN, jmp and cjmp are nil.\n\t// If the last insn is a CJMP or ITERJMP,\n\t//  cjmp and jmp are the \"true\" and \"false\" successors.\n\t// Otherwise, jmp is the sole successor.\n\tjmp, cjmp *block\n\n\tinitialstack int // for stack depth computation\n\n\t// Used during encoding\n\tindex int // -1 => not encoded yet\n\taddr  uint32\n}\n\ntype insn struct {\n\top        Opcode\n\targ       uint32\n\tline, col int32\n}\n\n// Position returns the source position for program counter pc.\nfunc (fn *Funcode) Position(pc uint32) syntax.Position {\n\tfn.lntOnce.Do(fn.decodeLNT)\n\n\t// Binary search to find last LNT entry not greater than pc.\n\t// To avoid dynamic dispatch, this is a specialization of\n\t// sort.Search using this predicate:\n\t//   !(i < len(fn.lnt)-1 && fn.lnt[i+1].pc <= pc)\n\tn := len(fn.lnt)\n\ti, j := 0, n\n\tfor i < j {\n\t\th := int(uint(i+j) >> 1)\n\t\tif !(h >= n-1 || fn.lnt[h+1].pc > pc) {\n\t\t\ti = h + 1\n\t\t} else {\n\t\t\tj = h\n\t\t}\n\t}\n\n\tvar line, col int32\n\tif i < n {\n\t\tline = fn.lnt[i].line\n\t\tcol = fn.lnt[i].col\n\t}\n\n\tpos := fn.Pos // copy the (annoyingly inaccessible) filename\n\tpos.Col = col\n\tpos.Line = line\n\treturn pos\n}\n\n// decodeLNT decodes the line number table and populates fn.lnt.\n// It is called at most once.\nfunc (fn *Funcode) decodeLNT() {\n\t// Conceptually the table contains rows of the form\n\t// (pc uint32, line int32, col int32), sorted by pc.\n\t// We use a delta encoding, since the differences\n\t// between successive pc, line, and column values\n\t// are typically small and positive (though line and\n\t// especially column differences may be negative).\n\t// The delta encoding starts from\n\t// {pc: 0, line: fn.Pos.Line, col: fn.Pos.Col}.\n\t//\n\t// Each entry is packed into one or more 16-bit values:\n\t//    Δpc        uint4\n\t//    Δline      int5\n\t//    Δcol       int6\n\t//    incomplete uint1\n\t// The top 4 bits are the unsigned delta pc.\n\t// The next 5 bits are the signed line number delta.\n\t// The next 6 bits are the signed column number delta.\n\t// The bottom bit indicates that more rows follow because\n\t// one of the deltas was maxed out.\n\t// These field widths were chosen from a sample of real programs,\n\t// and allow >97% of rows to be encoded in a single uint16.\n\n\tfn.lnt = make([]pclinecol, 0, len(fn.pclinetab)) // a minor overapproximation\n\tentry := pclinecol{\n\t\tpc:   0,\n\t\tline: fn.Pos.Line,\n\t\tcol:  fn.Pos.Col,\n\t}\n\tfor _, x := range fn.pclinetab {\n\t\tentry.pc += uint32(x) >> 12\n\t\tentry.line += int32((int16(x) << 4) >> (16 - 5)) // sign extend Δline\n\t\tentry.col += int32((int16(x) << 9) >> (16 - 6))  // sign extend Δcol\n\t\tif (x & 1) == 0 {\n\t\t\tfn.lnt = append(fn.lnt, entry)\n\t\t}\n\t}\n}\n\n// bindings converts resolve.Bindings to compiled form.\nfunc bindings(bindings []*resolve.Binding) []Binding {\n\tres := make([]Binding, len(bindings))\n\tfor i, bind := range bindings {\n\t\tres[i].Name = bind.First.Name\n\t\tres[i].Pos = bind.First.NamePos\n\t}\n\treturn res\n}\n\n// Expr compiles an expression to a program whose toplevel function evaluates it.\nfunc Expr(expr syntax.Expr, name string, locals []*resolve.Binding) *Program {\n\tpos := syntax.Start(expr)\n\tstmts := []syntax.Stmt{&syntax.ReturnStmt{Result: expr}}\n\treturn File(stmts, pos, name, locals, nil)\n}\n\n// File compiles the statements of a file into a program.\nfunc File(stmts []syntax.Stmt, pos syntax.Position, name string, locals, globals []*resolve.Binding) *Program {\n\tpcomp := &pcomp{\n\t\tprog: &Program{\n\t\t\tGlobals: bindings(globals),\n\t\t},\n\t\tnames:     make(map[string]uint32),\n\t\tconstants: make(map[interface{}]uint32),\n\t\tfunctions: make(map[*Funcode]uint32),\n\t}\n\tpcomp.prog.Toplevel = pcomp.function(name, pos, stmts, locals, nil)\n\n\treturn pcomp.prog\n}\n\nfunc (pcomp *pcomp) function(name string, pos syntax.Position, stmts []syntax.Stmt, locals, freevars []*resolve.Binding) *Funcode {\n\tfcomp := &fcomp{\n\t\tpcomp: pcomp,\n\t\tpos:   pos,\n\t\tfn: &Funcode{\n\t\t\tProg:     pcomp.prog,\n\t\t\tPos:      pos,\n\t\t\tName:     name,\n\t\t\tDoc:      docStringFromBody(stmts),\n\t\t\tLocals:   bindings(locals),\n\t\t\tFreevars: bindings(freevars),\n\t\t},\n\t}\n\n\t// Record indices of locals that require cells.\n\tfor i, local := range locals {\n\t\tif local.Scope == resolve.Cell {\n\t\t\tfcomp.fn.Cells = append(fcomp.fn.Cells, i)\n\t\t}\n\t}\n\n\tif debug {\n\t\tfmt.Fprintf(os.Stderr, \"start function(%s @ %s)\\n\", name, pos)\n\t}\n\n\t// Convert AST to a CFG of instructions.\n\tentry := fcomp.newBlock()\n\tfcomp.block = entry\n\tfcomp.stmts(stmts)\n\tif fcomp.block != nil {\n\t\tfcomp.emit(NONE)\n\t\tfcomp.emit(RETURN)\n\t}\n\n\tvar oops bool // something bad happened\n\n\tsetinitialstack := func(b *block, depth int) {\n\t\tif b.initialstack == -1 {\n\t\t\tb.initialstack = depth\n\t\t} else if b.initialstack != depth {\n\t\t\tfmt.Fprintf(os.Stderr, \"%d: setinitialstack: depth mismatch: %d vs %d\\n\",\n\t\t\t\tb.index, b.initialstack, depth)\n\t\t\toops = true\n\t\t}\n\t}\n\n\t// Linearize the CFG:\n\t// compute order, address, and initial\n\t// stack depth of each reachable block.\n\tvar pc uint32\n\tvar blocks []*block\n\tvar maxstack int\n\tvar visit func(b *block)\n\tvisit = func(b *block) {\n\t\tif b.index >= 0 {\n\t\t\treturn // already visited\n\t\t}\n\t\tb.index = len(blocks)\n\t\tb.addr = pc\n\t\tblocks = append(blocks, b)\n\n\t\tstack := b.initialstack\n\t\tif debug {\n\t\t\tfmt.Fprintf(os.Stderr, \"%s block %d: (stack = %d)\\n\", name, b.index, stack)\n\t\t}\n\t\tvar cjmpAddr *uint32\n\t\tvar isiterjmp int\n\t\tfor i, insn := range b.insns {\n\t\t\tpc++\n\n\t\t\t// Compute size of argument.\n\t\t\tif insn.op >= OpcodeArgMin {\n\t\t\t\tswitch insn.op {\n\t\t\t\tcase ITERJMP:\n\t\t\t\t\tisiterjmp = 1\n\t\t\t\t\tfallthrough\n\t\t\t\tcase CJMP:\n\t\t\t\t\tcjmpAddr = &b.insns[i].arg\n\t\t\t\t\tpc += 4\n\t\t\t\tdefault:\n\t\t\t\t\tpc += uint32(argLen(insn.arg))\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Compute effect on stack.\n\t\t\tse := insn.stackeffect()\n\t\t\tif debug {\n\t\t\t\tfmt.Fprintln(os.Stderr, \"\\t\", insn.op, stack, stack+se)\n\t\t\t}\n\t\t\tstack += se\n\t\t\tif stack < 0 {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"After pc=%d: stack underflow\\n\", pc)\n\t\t\t\toops = true\n\t\t\t}\n\t\t\tif stack+isiterjmp > maxstack {\n\t\t\t\tmaxstack = stack + isiterjmp\n\t\t\t}\n\t\t}\n\n\t\tif debug {\n\t\t\tfmt.Fprintf(os.Stderr, \"successors of block %d (start=%d):\\n\",\n\t\t\t\tb.addr, b.index)\n\t\t\tif b.jmp != nil {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"jmp to %d\\n\", b.jmp.index)\n\t\t\t}\n\t\t\tif b.cjmp != nil {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"cjmp to %d\\n\", b.cjmp.index)\n\t\t\t}\n\t\t}\n\n\t\t// Place the jmp block next.\n\t\tif b.jmp != nil {\n\t\t\t// jump threading (empty cycles are impossible)\n\t\t\tfor b.jmp.insns == nil {\n\t\t\t\tb.jmp = b.jmp.jmp\n\t\t\t}\n\n\t\t\tsetinitialstack(b.jmp, stack+isiterjmp)\n\t\t\tif b.jmp.index < 0 {\n\t\t\t\t// Successor is not yet visited:\n\t\t\t\t// place it next and fall through.\n\t\t\t\tvisit(b.jmp)\n\t\t\t} else {\n\t\t\t\t// Successor already visited;\n\t\t\t\t// explicit backward jump required.\n\t\t\t\tpc += 5\n\t\t\t}\n\t\t}\n\n\t\t// Then the cjmp block.\n\t\tif b.cjmp != nil {\n\t\t\t// jump threading (empty cycles are impossible)\n\t\t\tfor b.cjmp.insns == nil {\n\t\t\t\tb.cjmp = b.cjmp.jmp\n\t\t\t}\n\n\t\t\tsetinitialstack(b.cjmp, stack)\n\t\t\tvisit(b.cjmp)\n\n\t\t\t// Patch the CJMP/ITERJMP, if present.\n\t\t\tif cjmpAddr != nil {\n\t\t\t\t*cjmpAddr = b.cjmp.addr\n\t\t\t}\n\t\t}\n\t}\n\tsetinitialstack(entry, 0)\n\tvisit(entry)\n\n\tfn := fcomp.fn\n\tfn.MaxStack = maxstack\n\n\t// Emit bytecode (and position table).\n\tif Disassemble {\n\t\tfmt.Fprintf(os.Stderr, \"Function %s: (%d blocks, %d bytes)\\n\", name, len(blocks), pc)\n\t}\n\tfcomp.generate(blocks, pc)\n\n\tif debug {\n\t\tfmt.Fprintf(os.Stderr, \"code=%d maxstack=%d\\n\", fn.Code, fn.MaxStack)\n\t}\n\n\t// Don't panic until we've completed printing of the function.\n\tif oops {\n\t\tpanic(\"internal error\")\n\t}\n\n\tif debug {\n\t\tfmt.Fprintf(os.Stderr, \"end function(%s @ %s)\\n\", name, pos)\n\t}\n\n\treturn fn\n}\n\nfunc docStringFromBody(body []syntax.Stmt) string {\n\tif len(body) == 0 {\n\t\treturn \"\"\n\t}\n\texpr, ok := body[0].(*syntax.ExprStmt)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\tlit, ok := expr.X.(*syntax.Literal)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\tif lit.Token != syntax.STRING {\n\t\treturn \"\"\n\t}\n\treturn lit.Value.(string)\n}\n\nfunc (insn *insn) stackeffect() int {\n\tse := int(stackEffect[insn.op])\n\tif se == variableStackEffect {\n\t\targ := int(insn.arg)\n\t\tswitch insn.op {\n\t\tcase CALL, CALL_KW, CALL_VAR, CALL_VAR_KW:\n\t\t\tse = -int(2*(insn.arg&0xff) + insn.arg>>8)\n\t\t\tif insn.op != CALL {\n\t\t\t\tse--\n\t\t\t}\n\t\t\tif insn.op == CALL_VAR_KW {\n\t\t\t\tse--\n\t\t\t}\n\t\tcase ITERJMP:\n\t\t\t// Stack effect differs by successor:\n\t\t\t// +1 for jmp/false/ok\n\t\t\t//  0 for cjmp/true/exhausted\n\t\t\t// Handled specially in caller.\n\t\t\tse = 0\n\t\tcase MAKELIST, MAKETUPLE:\n\t\t\tse = 1 - arg\n\t\tcase UNPACK:\n\t\t\tse = arg - 1\n\t\tdefault:\n\t\t\tpanic(insn.op)\n\t\t}\n\t}\n\treturn se\n}\n\n// generate emits the linear instruction stream from the CFG,\n// and builds the PC-to-line number table.\nfunc (fcomp *fcomp) generate(blocks []*block, codelen uint32) {\n\tcode := make([]byte, 0, codelen)\n\tvar pclinetab []uint16\n\tprev := pclinecol{\n\t\tpc:   0,\n\t\tline: fcomp.fn.Pos.Line,\n\t\tcol:  fcomp.fn.Pos.Col,\n\t}\n\n\tfor _, b := range blocks {\n\t\tif Disassemble {\n\t\t\tfmt.Fprintf(os.Stderr, \"%d:\\n\", b.index)\n\t\t}\n\t\tpc := b.addr\n\t\tfor _, insn := range b.insns {\n\t\t\tif insn.line != 0 {\n\t\t\t\t// Instruction has a source position.  Delta-encode it.\n\t\t\t\t// See Funcode.Position for the encoding.\n\t\t\t\tfor {\n\t\t\t\t\tvar incomplete uint16\n\n\t\t\t\t\t// Δpc, uint4\n\t\t\t\t\tdeltapc := pc - prev.pc\n\t\t\t\t\tif deltapc > 0x0f {\n\t\t\t\t\t\tdeltapc = 0x0f\n\t\t\t\t\t\tincomplete = 1\n\t\t\t\t\t}\n\t\t\t\t\tprev.pc += deltapc\n\n\t\t\t\t\t// Δline, int5\n\t\t\t\t\tdeltaline, ok := clip(insn.line-prev.line, -0x10, 0x0f)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tincomplete = 1\n\t\t\t\t\t}\n\t\t\t\t\tprev.line += deltaline\n\n\t\t\t\t\t// Δcol, int6\n\t\t\t\t\tdeltacol, ok := clip(insn.col-prev.col, -0x20, 0x1f)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tincomplete = 1\n\t\t\t\t\t}\n\t\t\t\t\tprev.col += deltacol\n\n\t\t\t\t\tentry := uint16(deltapc<<12) | uint16(deltaline&0x1f)<<7 | uint16(deltacol&0x3f)<<1 | incomplete\n\t\t\t\t\tpclinetab = append(pclinetab, entry)\n\t\t\t\t\tif incomplete == 0 {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif Disassemble {\n\t\t\t\t\tfmt.Fprintf(os.Stderr, \"\\t\\t\\t\\t\\t; %s:%d:%d\\n\",\n\t\t\t\t\t\tfilepath.Base(fcomp.fn.Pos.Filename()), insn.line, insn.col)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif Disassemble {\n\t\t\t\tPrintOp(fcomp.fn, pc, insn.op, insn.arg)\n\t\t\t}\n\t\t\tcode = append(code, byte(insn.op))\n\t\t\tpc++\n\t\t\tif insn.op >= OpcodeArgMin {\n\t\t\t\tif insn.op == CJMP || insn.op == ITERJMP {\n\t\t\t\t\tcode = addUint32(code, insn.arg, 4) // pad arg to 4 bytes\n\t\t\t\t} else {\n\t\t\t\t\tcode = addUint32(code, insn.arg, 0)\n\t\t\t\t}\n\t\t\t\tpc = uint32(len(code))\n\t\t\t}\n\t\t}\n\n\t\tif b.jmp != nil && b.jmp.index != b.index+1 {\n\t\t\taddr := b.jmp.addr\n\t\t\tif Disassemble {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"\\t%d\\tjmp\\t\\t%d\\t; block %d\\n\",\n\t\t\t\t\tpc, addr, b.jmp.index)\n\t\t\t}\n\t\t\tcode = append(code, byte(JMP))\n\t\t\tcode = addUint32(code, addr, 4)\n\t\t}\n\t}\n\tif len(code) != int(codelen) {\n\t\tpanic(\"internal error: wrong code length\")\n\t}\n\n\tfcomp.fn.pclinetab = pclinetab\n\tfcomp.fn.Code = code\n}\n\n// clip returns the value nearest x in the range [min...max],\n// and whether it equals x.\nfunc clip(x, min, max int32) (int32, bool) {\n\tif x > max {\n\t\treturn max, false\n\t} else if x < min {\n\t\treturn min, false\n\t} else {\n\t\treturn x, true\n\t}\n}\n\n// addUint32 encodes x as 7-bit little-endian varint.\n// TODO(adonovan): opt: steal top two bits of opcode\n// to encode the number of complete bytes that follow.\nfunc addUint32(code []byte, x uint32, min int) []byte {\n\tend := len(code) + min\n\tfor x >= 0x80 {\n\t\tcode = append(code, byte(x)|0x80)\n\t\tx >>= 7\n\t}\n\tcode = append(code, byte(x))\n\t// Pad the operand with NOPs to exactly min bytes.\n\tfor len(code) < end {\n\t\tcode = append(code, byte(NOP))\n\t}\n\treturn code\n}\n\nfunc argLen(x uint32) int {\n\tn := 0\n\tfor x >= 0x80 {\n\t\tn++\n\t\tx >>= 7\n\t}\n\treturn n + 1\n}\n\n// PrintOp prints an instruction.\n// It is provided for debugging.\nfunc PrintOp(fn *Funcode, pc uint32, op Opcode, arg uint32) {\n\tif op < OpcodeArgMin {\n\t\tfmt.Fprintf(os.Stderr, \"\\t%d\\t%s\\n\", pc, op)\n\t\treturn\n\t}\n\n\tvar comment string\n\tswitch op {\n\tcase CONSTANT:\n\t\tswitch x := fn.Prog.Constants[arg].(type) {\n\t\tcase string:\n\t\t\tcomment = strconv.Quote(x)\n\t\tdefault:\n\t\t\tcomment = fmt.Sprint(x)\n\t\t}\n\tcase MAKEFUNC:\n\t\tcomment = fn.Prog.Functions[arg].Name\n\tcase SETLOCAL, LOCAL:\n\t\tcomment = fn.Locals[arg].Name\n\tcase SETGLOBAL, GLOBAL:\n\t\tcomment = fn.Prog.Globals[arg].Name\n\tcase ATTR, SETFIELD, PREDECLARED, UNIVERSAL:\n\t\tcomment = fn.Prog.Names[arg]\n\tcase FREE:\n\t\tcomment = fn.Freevars[arg].Name\n\tcase CALL, CALL_VAR, CALL_KW, CALL_VAR_KW:\n\t\tcomment = fmt.Sprintf(\"%d pos, %d named\", arg>>8, arg&0xff)\n\tdefault:\n\t\t// JMP, CJMP, ITERJMP, MAKETUPLE, MAKELIST, LOAD, UNPACK:\n\t\t// arg is just a number\n\t}\n\tvar buf bytes.Buffer\n\tfmt.Fprintf(&buf, \"\\t%d\\t%-10s\\t%d\", pc, op, arg)\n\tif comment != \"\" {\n\t\tfmt.Fprint(&buf, \"\\t; \", comment)\n\t}\n\tfmt.Fprintln(&buf)\n\tos.Stderr.Write(buf.Bytes())\n}\n\n// newBlock returns a new block.\nfunc (fcomp) newBlock() *block {\n\treturn &block{index: -1, initialstack: -1}\n}\n\n// emit emits an instruction to the current block.\nfunc (fcomp *fcomp) emit(op Opcode) {\n\tif op >= OpcodeArgMin {\n\t\tpanic(\"missing arg: \" + op.String())\n\t}\n\tinsn := insn{op: op, line: fcomp.pos.Line, col: fcomp.pos.Col}\n\tfcomp.block.insns = append(fcomp.block.insns, insn)\n\tfcomp.pos.Line = 0\n\tfcomp.pos.Col = 0\n}\n\n// emit1 emits an instruction with an immediate operand.\nfunc (fcomp *fcomp) emit1(op Opcode, arg uint32) {\n\tif op < OpcodeArgMin {\n\t\tpanic(\"unwanted arg: \" + op.String())\n\t}\n\tinsn := insn{op: op, arg: arg, line: fcomp.pos.Line, col: fcomp.pos.Col}\n\tfcomp.block.insns = append(fcomp.block.insns, insn)\n\tfcomp.pos.Line = 0\n\tfcomp.pos.Col = 0\n}\n\n// jump emits a jump to the specified block.\n// On return, the current block is unset.\nfunc (fcomp *fcomp) jump(b *block) {\n\tif b == fcomp.block {\n\t\tpanic(\"self-jump\") // unreachable: Starlark has no arbitrary looping constructs\n\t}\n\tfcomp.block.jmp = b\n\tfcomp.block = nil\n}\n\n// condjump emits a conditional jump (CJMP or ITERJMP)\n// to the specified true/false blocks.\n// (For ITERJMP, the cases are jmp/f/ok and cjmp/t/exhausted.)\n// On return, the current block is unset.\nfunc (fcomp *fcomp) condjump(op Opcode, t, f *block) {\n\tif !(op == CJMP || op == ITERJMP) {\n\t\tpanic(\"not a conditional jump: \" + op.String())\n\t}\n\tfcomp.emit1(op, 0) // fill in address later\n\tfcomp.block.cjmp = t\n\tfcomp.jump(f)\n}\n\n// nameIndex returns the index of the specified name\n// within the name pool, adding it if necessary.\nfunc (pcomp *pcomp) nameIndex(name string) uint32 {\n\tindex, ok := pcomp.names[name]\n\tif !ok {\n\t\tindex = uint32(len(pcomp.prog.Names))\n\t\tpcomp.names[name] = index\n\t\tpcomp.prog.Names = append(pcomp.prog.Names, name)\n\t}\n\treturn index\n}\n\n// constantIndex returns the index of the specified constant\n// within the constant pool, adding it if necessary.\nfunc (pcomp *pcomp) constantIndex(v interface{}) uint32 {\n\tindex, ok := pcomp.constants[v]\n\tif !ok {\n\t\tindex = uint32(len(pcomp.prog.Constants))\n\t\tpcomp.constants[v] = index\n\t\tpcomp.prog.Constants = append(pcomp.prog.Constants, v)\n\t}\n\treturn index\n}\n\n// functionIndex returns the index of the specified function\n// AST the nestedfun pool, adding it if necessary.\nfunc (pcomp *pcomp) functionIndex(fn *Funcode) uint32 {\n\tindex, ok := pcomp.functions[fn]\n\tif !ok {\n\t\tindex = uint32(len(pcomp.prog.Functions))\n\t\tpcomp.functions[fn] = index\n\t\tpcomp.prog.Functions = append(pcomp.prog.Functions, fn)\n\t}\n\treturn index\n}\n\n// string emits code to push the specified string.\nfunc (fcomp *fcomp) string(s string) {\n\tfcomp.emit1(CONSTANT, fcomp.pcomp.constantIndex(s))\n}\n\n// setPos sets the current source position.\n// It should be called prior to any operation that can fail dynamically.\n// All positions are assumed to belong to the same file.\nfunc (fcomp *fcomp) setPos(pos syntax.Position) {\n\tfcomp.pos = pos\n}\n\n// set emits code to store the top-of-stack value\n// to the specified local, cell, or global variable.\nfunc (fcomp *fcomp) set(id *syntax.Ident) {\n\tbind := id.Binding.(*resolve.Binding)\n\tswitch bind.Scope {\n\tcase resolve.Local:\n\t\tfcomp.emit1(SETLOCAL, uint32(bind.Index))\n\tcase resolve.Cell:\n\t\t// TODO(adonovan): opt: make a single op for LOCAL<n>, SETCELL.\n\t\tfcomp.emit1(LOCAL, uint32(bind.Index))\n\t\tfcomp.emit(SETCELL)\n\tcase resolve.Global:\n\t\tfcomp.emit1(SETGLOBAL, uint32(bind.Index))\n\tdefault:\n\t\tlog.Panicf(\"%s: set(%s): not global/local/cell (%d)\", id.NamePos, id.Name, bind.Scope)\n\t}\n}\n\n// lookup emits code to push the value of the specified variable.\nfunc (fcomp *fcomp) lookup(id *syntax.Ident) {\n\tbind := id.Binding.(*resolve.Binding)\n\tif bind.Scope != resolve.Universal { // (universal lookup can't fail)\n\t\tfcomp.setPos(id.NamePos)\n\t}\n\tswitch bind.Scope {\n\tcase resolve.Local:\n\t\tfcomp.emit1(LOCAL, uint32(bind.Index))\n\tcase resolve.Free:\n\t\t// TODO(adonovan): opt: make a single op for FREE<n>, CELL.\n\t\tfcomp.emit1(FREE, uint32(bind.Index))\n\t\tfcomp.emit(CELL)\n\tcase resolve.Cell:\n\t\t// TODO(adonovan): opt: make a single op for LOCAL<n>, CELL.\n\t\tfcomp.emit1(LOCAL, uint32(bind.Index))\n\t\tfcomp.emit(CELL)\n\tcase resolve.Global:\n\t\tfcomp.emit1(GLOBAL, uint32(bind.Index))\n\tcase resolve.Predeclared:\n\t\tfcomp.emit1(PREDECLARED, fcomp.pcomp.nameIndex(id.Name))\n\tcase resolve.Universal:\n\t\tfcomp.emit1(UNIVERSAL, fcomp.pcomp.nameIndex(id.Name))\n\tdefault:\n\t\tlog.Panicf(\"%s: compiler.lookup(%s): scope = %d\", id.NamePos, id.Name, bind.Scope)\n\t}\n}\n\nfunc (fcomp *fcomp) stmts(stmts []syntax.Stmt) {\n\tfor _, stmt := range stmts {\n\t\tfcomp.stmt(stmt)\n\t}\n}\n\nfunc (fcomp *fcomp) stmt(stmt syntax.Stmt) {\n\tswitch stmt := stmt.(type) {\n\tcase *syntax.ExprStmt:\n\t\tif _, ok := stmt.X.(*syntax.Literal); ok {\n\t\t\t// Opt: don't compile doc comments only to pop them.\n\t\t\treturn\n\t\t}\n\t\tfcomp.expr(stmt.X)\n\t\tfcomp.emit(POP)\n\n\tcase *syntax.BranchStmt:\n\t\t// Resolver invariant: break/continue appear only within loops.\n\t\tswitch stmt.Token {\n\t\tcase syntax.PASS:\n\t\t\t// no-op\n\t\tcase syntax.BREAK:\n\t\t\tb := fcomp.loops[len(fcomp.loops)-1].break_\n\t\t\tfcomp.jump(b)\n\t\t\tfcomp.block = fcomp.newBlock() // dead code\n\t\tcase syntax.CONTINUE:\n\t\t\tb := fcomp.loops[len(fcomp.loops)-1].continue_\n\t\t\tfcomp.jump(b)\n\t\t\tfcomp.block = fcomp.newBlock() // dead code\n\t\t}\n\n\tcase *syntax.IfStmt:\n\t\t// Keep consistent with CondExpr.\n\t\tt := fcomp.newBlock()\n\t\tf := fcomp.newBlock()\n\t\tdone := fcomp.newBlock()\n\n\t\tfcomp.ifelse(stmt.Cond, t, f)\n\n\t\tfcomp.block = t\n\t\tfcomp.stmts(stmt.True)\n\t\tfcomp.jump(done)\n\n\t\tfcomp.block = f\n\t\tfcomp.stmts(stmt.False)\n\t\tfcomp.jump(done)\n\n\t\tfcomp.block = done\n\n\tcase *syntax.AssignStmt:\n\t\tswitch stmt.Op {\n\t\tcase syntax.EQ:\n\t\t\t// simple assignment: x = y\n\t\t\tfcomp.expr(stmt.RHS)\n\t\t\tfcomp.assign(stmt.OpPos, stmt.LHS)\n\n\t\tcase syntax.PLUS_EQ,\n\t\t\tsyntax.MINUS_EQ,\n\t\t\tsyntax.STAR_EQ,\n\t\t\tsyntax.SLASH_EQ,\n\t\t\tsyntax.SLASHSLASH_EQ,\n\t\t\tsyntax.PERCENT_EQ,\n\t\t\tsyntax.AMP_EQ,\n\t\t\tsyntax.PIPE_EQ,\n\t\t\tsyntax.CIRCUMFLEX_EQ,\n\t\t\tsyntax.LTLT_EQ,\n\t\t\tsyntax.GTGT_EQ:\n\t\t\t// augmented assignment: x += y\n\n\t\t\tvar set func()\n\n\t\t\t// Evaluate \"address\" of x exactly once to avoid duplicate side-effects.\n\t\t\tswitch lhs := unparen(stmt.LHS).(type) {\n\t\t\tcase *syntax.Ident:\n\t\t\t\t// x = ...\n\t\t\t\tfcomp.lookup(lhs)\n\t\t\t\tset = func() {\n\t\t\t\t\tfcomp.set(lhs)\n\t\t\t\t}\n\n\t\t\tcase *syntax.IndexExpr:\n\t\t\t\t// x[y] = ...\n\t\t\t\tfcomp.expr(lhs.X)\n\t\t\t\tfcomp.expr(lhs.Y)\n\t\t\t\tfcomp.emit(DUP2)\n\t\t\t\tfcomp.setPos(lhs.Lbrack)\n\t\t\t\tfcomp.emit(INDEX)\n\t\t\t\tset = func() {\n\t\t\t\t\tfcomp.setPos(lhs.Lbrack)\n\t\t\t\t\tfcomp.emit(SETINDEX)\n\t\t\t\t}\n\n\t\t\tcase *syntax.DotExpr:\n\t\t\t\t// x.f = ...\n\t\t\t\tfcomp.expr(lhs.X)\n\t\t\t\tfcomp.emit(DUP)\n\t\t\t\tname := fcomp.pcomp.nameIndex(lhs.Name.Name)\n\t\t\t\tfcomp.setPos(lhs.Dot)\n\t\t\t\tfcomp.emit1(ATTR, name)\n\t\t\t\tset = func() {\n\t\t\t\t\tfcomp.setPos(lhs.Dot)\n\t\t\t\t\tfcomp.emit1(SETFIELD, name)\n\t\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tpanic(lhs)\n\t\t\t}\n\n\t\t\tfcomp.expr(stmt.RHS)\n\n\t\t\tif stmt.Op == syntax.PLUS_EQ {\n\t\t\t\t// Allow the runtime to optimize list += iterable.\n\t\t\t\tfcomp.setPos(stmt.OpPos)\n\t\t\t\tfcomp.emit(INPLACE_ADD)\n\t\t\t} else {\n\t\t\t\tfcomp.binop(stmt.OpPos, stmt.Op-syntax.PLUS_EQ+syntax.PLUS)\n\t\t\t}\n\t\t\tset()\n\t\t}\n\n\tcase *syntax.DefStmt:\n\t\tfcomp.function(stmt.Function.(*resolve.Function))\n\t\tfcomp.set(stmt.Name)\n\n\tcase *syntax.ForStmt:\n\t\t// Keep consistent with ForClause.\n\t\thead := fcomp.newBlock()\n\t\tbody := fcomp.newBlock()\n\t\ttail := fcomp.newBlock()\n\n\t\tfcomp.expr(stmt.X)\n\t\tfcomp.setPos(stmt.For)\n\t\tfcomp.emit(ITERPUSH)\n\t\tfcomp.jump(head)\n\n\t\tfcomp.block = head\n\t\tfcomp.condjump(ITERJMP, tail, body)\n\n\t\tfcomp.block = body\n\t\tfcomp.assign(stmt.For, stmt.Vars)\n\t\tfcomp.loops = append(fcomp.loops, loop{break_: tail, continue_: head})\n\t\tfcomp.stmts(stmt.Body)\n\t\tfcomp.loops = fcomp.loops[:len(fcomp.loops)-1]\n\t\tfcomp.jump(head)\n\n\t\tfcomp.block = tail\n\t\tfcomp.emit(ITERPOP)\n\n\tcase *syntax.WhileStmt:\n\t\thead := fcomp.newBlock()\n\t\tbody := fcomp.newBlock()\n\t\tdone := fcomp.newBlock()\n\n\t\tfcomp.jump(head)\n\t\tfcomp.block = head\n\t\tfcomp.ifelse(stmt.Cond, body, done)\n\n\t\tfcomp.block = body\n\t\tfcomp.loops = append(fcomp.loops, loop{break_: done, continue_: head})\n\t\tfcomp.stmts(stmt.Body)\n\t\tfcomp.loops = fcomp.loops[:len(fcomp.loops)-1]\n\t\tfcomp.jump(head)\n\n\t\tfcomp.block = done\n\n\tcase *syntax.ReturnStmt:\n\t\tif stmt.Result != nil {\n\t\t\tfcomp.expr(stmt.Result)\n\t\t} else {\n\t\t\tfcomp.emit(NONE)\n\t\t}\n\t\tfcomp.emit(RETURN)\n\t\tfcomp.block = fcomp.newBlock() // dead code\n\n\tcase *syntax.LoadStmt:\n\t\tfor i := range stmt.From {\n\t\t\tfcomp.string(stmt.From[i].Name)\n\t\t}\n\t\tmodule := stmt.Module.Value.(string)\n\t\tfcomp.pcomp.prog.Loads = append(fcomp.pcomp.prog.Loads, Binding{\n\t\t\tName: module,\n\t\t\tPos:  stmt.Module.TokenPos,\n\t\t})\n\t\tfcomp.string(module)\n\t\tfcomp.setPos(stmt.Load)\n\t\tfcomp.emit1(LOAD, uint32(len(stmt.From)))\n\t\tfor i := range stmt.To {\n\t\t\tfcomp.set(stmt.To[len(stmt.To)-1-i])\n\t\t}\n\n\tdefault:\n\t\tstart, _ := stmt.Span()\n\t\tlog.Panicf(\"%s: exec: unexpected statement %T\", start, stmt)\n\t}\n}\n\n// assign implements lhs = rhs for arbitrary expressions lhs.\n// RHS is on top of stack, consumed.\nfunc (fcomp *fcomp) assign(pos syntax.Position, lhs syntax.Expr) {\n\tswitch lhs := lhs.(type) {\n\tcase *syntax.ParenExpr:\n\t\t// (lhs) = rhs\n\t\tfcomp.assign(pos, lhs.X)\n\n\tcase *syntax.Ident:\n\t\t// x = rhs\n\t\tfcomp.set(lhs)\n\n\tcase *syntax.TupleExpr:\n\t\t// x, y = rhs\n\t\tfcomp.assignSequence(pos, lhs.List)\n\n\tcase *syntax.ListExpr:\n\t\t// [x, y] = rhs\n\t\tfcomp.assignSequence(pos, lhs.List)\n\n\tcase *syntax.IndexExpr:\n\t\t// x[y] = rhs\n\t\tfcomp.expr(lhs.X)\n\t\tfcomp.emit(EXCH)\n\t\tfcomp.expr(lhs.Y)\n\t\tfcomp.emit(EXCH)\n\t\tfcomp.setPos(lhs.Lbrack)\n\t\tfcomp.emit(SETINDEX)\n\n\tcase *syntax.DotExpr:\n\t\t// x.f = rhs\n\t\tfcomp.expr(lhs.X)\n\t\tfcomp.emit(EXCH)\n\t\tfcomp.setPos(lhs.Dot)\n\t\tfcomp.emit1(SETFIELD, fcomp.pcomp.nameIndex(lhs.Name.Name))\n\n\tdefault:\n\t\tpanic(lhs)\n\t}\n}\n\nfunc (fcomp *fcomp) assignSequence(pos syntax.Position, lhs []syntax.Expr) {\n\tfcomp.setPos(pos)\n\tfcomp.emit1(UNPACK, uint32(len(lhs)))\n\tfor i := range lhs {\n\t\tfcomp.assign(pos, lhs[i])\n\t}\n}\n\nfunc (fcomp *fcomp) expr(e syntax.Expr) {\n\tswitch e := e.(type) {\n\tcase *syntax.ParenExpr:\n\t\tfcomp.expr(e.X)\n\n\tcase *syntax.Ident:\n\t\tfcomp.lookup(e)\n\n\tcase *syntax.Literal:\n\t\t// e.Value is int64, float64, *bigInt, or string.\n\t\tfcomp.emit1(CONSTANT, fcomp.pcomp.constantIndex(e.Value))\n\n\tcase *syntax.ListExpr:\n\t\tfor _, x := range e.List {\n\t\t\tfcomp.expr(x)\n\t\t}\n\t\tfcomp.emit1(MAKELIST, uint32(len(e.List)))\n\n\tcase *syntax.CondExpr:\n\t\t// Keep consistent with IfStmt.\n\t\tt := fcomp.newBlock()\n\t\tf := fcomp.newBlock()\n\t\tdone := fcomp.newBlock()\n\n\t\tfcomp.ifelse(e.Cond, t, f)\n\n\t\tfcomp.block = t\n\t\tfcomp.expr(e.True)\n\t\tfcomp.jump(done)\n\n\t\tfcomp.block = f\n\t\tfcomp.expr(e.False)\n\t\tfcomp.jump(done)\n\n\t\tfcomp.block = done\n\n\tcase *syntax.IndexExpr:\n\t\tfcomp.expr(e.X)\n\t\tfcomp.expr(e.Y)\n\t\tfcomp.setPos(e.Lbrack)\n\t\tfcomp.emit(INDEX)\n\n\tcase *syntax.SliceExpr:\n\t\tfcomp.setPos(e.Lbrack)\n\t\tfcomp.expr(e.X)\n\t\tif e.Lo != nil {\n\t\t\tfcomp.expr(e.Lo)\n\t\t} else {\n\t\t\tfcomp.emit(NONE)\n\t\t}\n\t\tif e.Hi != nil {\n\t\t\tfcomp.expr(e.Hi)\n\t\t} else {\n\t\t\tfcomp.emit(NONE)\n\t\t}\n\t\tif e.Step != nil {\n\t\t\tfcomp.expr(e.Step)\n\t\t} else {\n\t\t\tfcomp.emit(NONE)\n\t\t}\n\t\tfcomp.emit(SLICE)\n\n\tcase *syntax.Comprehension:\n\t\tif e.Curly {\n\t\t\tfcomp.emit(MAKEDICT)\n\t\t} else {\n\t\t\tfcomp.emit1(MAKELIST, 0)\n\t\t}\n\t\tfcomp.comprehension(e, 0)\n\n\tcase *syntax.TupleExpr:\n\t\tfcomp.tuple(e.List)\n\n\tcase *syntax.DictExpr:\n\t\tfcomp.emit(MAKEDICT)\n\t\tfor _, entry := range e.List {\n\t\t\tentry := entry.(*syntax.DictEntry)\n\t\t\tfcomp.emit(DUP)\n\t\t\tfcomp.expr(entry.Key)\n\t\t\tfcomp.expr(entry.Value)\n\t\t\tfcomp.setPos(entry.Colon)\n\t\t\tfcomp.emit(SETDICTUNIQ)\n\t\t}\n\n\tcase *syntax.UnaryExpr:\n\t\tfcomp.expr(e.X)\n\t\tfcomp.setPos(e.OpPos)\n\t\tswitch e.Op {\n\t\tcase syntax.MINUS:\n\t\t\tfcomp.emit(UMINUS)\n\t\tcase syntax.PLUS:\n\t\t\tfcomp.emit(UPLUS)\n\t\tcase syntax.NOT:\n\t\t\tfcomp.emit(NOT)\n\t\tcase syntax.TILDE:\n\t\t\tfcomp.emit(TILDE)\n\t\tdefault:\n\t\t\tlog.Panicf(\"%s: unexpected unary op: %s\", e.OpPos, e.Op)\n\t\t}\n\n\tcase *syntax.BinaryExpr:\n\t\tswitch e.Op {\n\t\t// short-circuit operators\n\t\t// TODO(adonovan): use ifelse to simplify conditions.\n\t\tcase syntax.OR:\n\t\t\t// x or y  =>  if x then x else y\n\t\t\tdone := fcomp.newBlock()\n\t\t\ty := fcomp.newBlock()\n\n\t\t\tfcomp.expr(e.X)\n\t\t\tfcomp.emit(DUP)\n\t\t\tfcomp.condjump(CJMP, done, y)\n\n\t\t\tfcomp.block = y\n\t\t\tfcomp.emit(POP) // discard X\n\t\t\tfcomp.expr(e.Y)\n\t\t\tfcomp.jump(done)\n\n\t\t\tfcomp.block = done\n\n\t\tcase syntax.AND:\n\t\t\t// x and y  =>  if x then y else x\n\t\t\tdone := fcomp.newBlock()\n\t\t\ty := fcomp.newBlock()\n\n\t\t\tfcomp.expr(e.X)\n\t\t\tfcomp.emit(DUP)\n\t\t\tfcomp.condjump(CJMP, y, done)\n\n\t\t\tfcomp.block = y\n\t\t\tfcomp.emit(POP) // discard X\n\t\t\tfcomp.expr(e.Y)\n\t\t\tfcomp.jump(done)\n\n\t\t\tfcomp.block = done\n\n\t\tcase syntax.PLUS:\n\t\t\tfcomp.plus(e)\n\n\t\tdefault:\n\t\t\t// all other strict binary operator (includes comparisons)\n\t\t\tfcomp.expr(e.X)\n\t\t\tfcomp.expr(e.Y)\n\t\t\tfcomp.binop(e.OpPos, e.Op)\n\t\t}\n\n\tcase *syntax.DotExpr:\n\t\tfcomp.expr(e.X)\n\t\tfcomp.setPos(e.Dot)\n\t\tfcomp.emit1(ATTR, fcomp.pcomp.nameIndex(e.Name.Name))\n\n\tcase *syntax.CallExpr:\n\t\tfcomp.call(e)\n\n\tcase *syntax.LambdaExpr:\n\t\tfcomp.function(e.Function.(*resolve.Function))\n\n\tdefault:\n\t\tstart, _ := e.Span()\n\t\tlog.Panicf(\"%s: unexpected expr %T\", start, e)\n\t}\n}\n\ntype summand struct {\n\tx       syntax.Expr\n\tplusPos syntax.Position\n}\n\n// plus emits optimized code for ((a+b)+...)+z that avoids naive\n// quadratic behavior for strings, tuples, and lists,\n// and folds together adjacent literals of the same type.\nfunc (fcomp *fcomp) plus(e *syntax.BinaryExpr) {\n\t// Gather all the right operands of the left tree of plusses.\n\t// A tree (((a+b)+c)+d) becomes args=[a +b +c +d].\n\targs := make([]summand, 0, 2) // common case: 2 operands\n\tfor plus := e; ; {\n\t\targs = append(args, summand{unparen(plus.Y), plus.OpPos})\n\t\tleft := unparen(plus.X)\n\t\tx, ok := left.(*syntax.BinaryExpr)\n\t\tif !ok || x.Op != syntax.PLUS {\n\t\t\targs = append(args, summand{x: left})\n\t\t\tbreak\n\t\t}\n\t\tplus = x\n\t}\n\t// Reverse args to syntactic order.\n\tfor i, n := 0, len(args)/2; i < n; i++ {\n\t\tj := len(args) - 1 - i\n\t\targs[i], args[j] = args[j], args[i]\n\t}\n\n\t// Fold sums of adjacent literals of the same type: \"\"+\"\", []+[], ()+().\n\tout := args[:0] // compact in situ\n\tfor i := 0; i < len(args); {\n\t\tj := i + 1\n\t\tif code := addable(args[i].x); code != 0 {\n\t\t\tfor j < len(args) && addable(args[j].x) == code {\n\t\t\t\tj++\n\t\t\t}\n\t\t\tif j > i+1 {\n\t\t\t\targs[i].x = add(code, args[i:j])\n\t\t\t}\n\t\t}\n\t\tout = append(out, args[i])\n\t\ti = j\n\t}\n\targs = out\n\n\t// Emit code for an n-ary sum (n > 0).\n\tfcomp.expr(args[0].x)\n\tfor _, summand := range args[1:] {\n\t\tfcomp.expr(summand.x)\n\t\tfcomp.setPos(summand.plusPos)\n\t\tfcomp.emit(PLUS)\n\t}\n\n\t// If len(args) > 2, use of an accumulator instead of a chain of\n\t// PLUS operations may be more efficient.\n\t// However, no gain was measured on a workload analogous to Bazel loading;\n\t// TODO(adonovan): opt: re-evaluate on a Bazel analysis-like workload.\n\t//\n\t// We cannot use a single n-ary SUM operation\n\t//    a b c SUM<3>\n\t// because we need to report a distinct error for each\n\t// individual '+' operation, so three additional operations are\n\t// needed:\n\t//\n\t//   ACCSTART => create buffer and append to it\n\t//   ACCUM    => append to buffer\n\t//   ACCEND   => get contents of buffer\n\t//\n\t// For string, list, and tuple values, the interpreter can\n\t// optimize these operations by using a mutable buffer.\n\t// For all other types, ACCSTART and ACCEND would behave like\n\t// the identity function and ACCUM behaves like PLUS.\n\t// ACCUM must correctly support user-defined operations\n\t// such as list+foo.\n\t//\n\t// fcomp.emit(ACCSTART)\n\t// for _, summand := range args[1:] {\n\t// \tfcomp.expr(summand.x)\n\t// \tfcomp.setPos(summand.plusPos)\n\t// \tfcomp.emit(ACCUM)\n\t// }\n\t// fcomp.emit(ACCEND)\n}\n\n// addable reports whether e is a statically addable\n// expression: a [s]tring, [l]ist, or [t]uple.\nfunc addable(e syntax.Expr) rune {\n\tswitch e := e.(type) {\n\tcase *syntax.Literal:\n\t\t// TODO(adonovan): opt: support INT/FLOAT/BIGINT constant folding.\n\t\tswitch e.Token {\n\t\tcase syntax.STRING:\n\t\t\treturn 's'\n\t\t}\n\tcase *syntax.ListExpr:\n\t\treturn 'l'\n\tcase *syntax.TupleExpr:\n\t\treturn 't'\n\t}\n\treturn 0\n}\n\n// add returns an expression denoting the sum of args,\n// which are all addable values of the type indicated by code.\n// The resulting syntax is degenerate, lacking position, etc.\nfunc add(code rune, args []summand) syntax.Expr {\n\tswitch code {\n\tcase 's':\n\t\tvar buf bytes.Buffer\n\t\tfor _, arg := range args {\n\t\t\tbuf.WriteString(arg.x.(*syntax.Literal).Value.(string))\n\t\t}\n\t\treturn &syntax.Literal{Token: syntax.STRING, Value: buf.String()}\n\tcase 'l':\n\t\tvar elems []syntax.Expr\n\t\tfor _, arg := range args {\n\t\t\telems = append(elems, arg.x.(*syntax.ListExpr).List...)\n\t\t}\n\t\treturn &syntax.ListExpr{List: elems}\n\tcase 't':\n\t\tvar elems []syntax.Expr\n\t\tfor _, arg := range args {\n\t\t\telems = append(elems, arg.x.(*syntax.TupleExpr).List...)\n\t\t}\n\t\treturn &syntax.TupleExpr{List: elems}\n\t}\n\tpanic(code)\n}\n\nfunc unparen(e syntax.Expr) syntax.Expr {\n\tif p, ok := e.(*syntax.ParenExpr); ok {\n\t\treturn unparen(p.X)\n\t}\n\treturn e\n}\n\nfunc (fcomp *fcomp) binop(pos syntax.Position, op syntax.Token) {\n\t// TODO(adonovan): simplify by assuming syntax and compiler constants align.\n\tfcomp.setPos(pos)\n\tswitch op {\n\t// arithmetic\n\tcase syntax.PLUS:\n\t\tfcomp.emit(PLUS)\n\tcase syntax.MINUS:\n\t\tfcomp.emit(MINUS)\n\tcase syntax.STAR:\n\t\tfcomp.emit(STAR)\n\tcase syntax.SLASH:\n\t\tfcomp.emit(SLASH)\n\tcase syntax.SLASHSLASH:\n\t\tfcomp.emit(SLASHSLASH)\n\tcase syntax.PERCENT:\n\t\tfcomp.emit(PERCENT)\n\tcase syntax.AMP:\n\t\tfcomp.emit(AMP)\n\tcase syntax.PIPE:\n\t\tfcomp.emit(PIPE)\n\tcase syntax.CIRCUMFLEX:\n\t\tfcomp.emit(CIRCUMFLEX)\n\tcase syntax.LTLT:\n\t\tfcomp.emit(LTLT)\n\tcase syntax.GTGT:\n\t\tfcomp.emit(GTGT)\n\tcase syntax.IN:\n\t\tfcomp.emit(IN)\n\tcase syntax.NOT_IN:\n\t\tfcomp.emit(IN)\n\t\tfcomp.emit(NOT)\n\n\t\t// comparisons\n\tcase syntax.EQL,\n\t\tsyntax.NEQ,\n\t\tsyntax.GT,\n\t\tsyntax.LT,\n\t\tsyntax.LE,\n\t\tsyntax.GE:\n\t\tfcomp.emit(Opcode(op-syntax.EQL) + EQL)\n\n\tdefault:\n\t\tlog.Panicf(\"%s: unexpected binary op: %s\", pos, op)\n\t}\n}\n\nfunc (fcomp *fcomp) call(call *syntax.CallExpr) {\n\t// TODO(adonovan): opt: Use optimized path for calling methods\n\t// of built-ins: x.f(...) to avoid materializing a closure.\n\t// if dot, ok := call.Fcomp.(*syntax.DotExpr); ok {\n\t// \tfcomp.expr(dot.X)\n\t// \tfcomp.args(call)\n\t// \tfcomp.emit1(CALL_ATTR, fcomp.name(dot.Name.Name))\n\t// \treturn\n\t// }\n\n\t// usual case\n\tfcomp.expr(call.Fn)\n\top, arg := fcomp.args(call)\n\tfcomp.setPos(call.Lparen)\n\tfcomp.emit1(op, arg)\n}\n\n// args emits code to push a tuple of positional arguments\n// and a tuple of named arguments containing alternating keys and values.\n// Either or both tuples may be empty (TODO(adonovan): optimize).\nfunc (fcomp *fcomp) args(call *syntax.CallExpr) (op Opcode, arg uint32) {\n\tvar callmode int\n\t// Compute the number of each kind of parameter.\n\tvar p, n int // number of  positional, named arguments\n\tvar varargs, kwargs syntax.Expr\n\tfor _, arg := range call.Args {\n\t\tif binary, ok := arg.(*syntax.BinaryExpr); ok && binary.Op == syntax.EQ {\n\n\t\t\t// named argument (name, value)\n\t\t\tfcomp.string(binary.X.(*syntax.Ident).Name)\n\t\t\tfcomp.expr(binary.Y)\n\t\t\tn++\n\t\t\tcontinue\n\t\t}\n\t\tif unary, ok := arg.(*syntax.UnaryExpr); ok {\n\t\t\tif unary.Op == syntax.STAR {\n\t\t\t\tcallmode |= 1\n\t\t\t\tvarargs = unary.X\n\t\t\t\tcontinue\n\t\t\t} else if unary.Op == syntax.STARSTAR {\n\t\t\t\tcallmode |= 2\n\t\t\t\tkwargs = unary.X\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// positional argument\n\t\tfcomp.expr(arg)\n\t\tp++\n\t}\n\n\t// Python2 and Python3 both permit named arguments\n\t// to appear both before and after a *args argument:\n\t//   f(1, 2, x=3, *[4], y=5, **dict(z=6))\n\t//\n\t// They also differ in their evaluation order:\n\t//  Python2: 1 2 3 5 4 6 (*args and **kwargs evaluated last)\n\t//  Python3: 1 2 4 3 5 6 (positional args evaluated before named args)\n\t// Starlark-in-Java historically used a third order:\n\t//  Lexical: 1 2 3 4 5 6 (all args evaluated left-to-right)\n\t//\n\t// After discussion in github.com/bazelbuild/starlark#13, the\n\t// spec now requires Starlark to statically reject named\n\t// arguments after *args (e.g. y=5), and to use Python2-style\n\t// evaluation order. This is both easy to implement and\n\t// consistent with lexical order:\n\t//\n\t//   f(1, 2, x=3, *[4], **dict(z=6)) # 1 2 3 4 6\n\n\t// *args\n\tif varargs != nil {\n\t\tfcomp.expr(varargs)\n\t}\n\n\t// **kwargs\n\tif kwargs != nil {\n\t\tfcomp.expr(kwargs)\n\t}\n\n\t// TODO(adonovan): avoid this with a more flexible encoding.\n\tif p >= 256 || n >= 256 {\n\t\t// resolve already checked this; should be unreachable\n\t\tpanic(\"too many arguments in call\")\n\t}\n\n\treturn CALL + Opcode(callmode), uint32(p<<8 | n)\n}\n\nfunc (fcomp *fcomp) tuple(elems []syntax.Expr) {\n\tfor _, elem := range elems {\n\t\tfcomp.expr(elem)\n\t}\n\tfcomp.emit1(MAKETUPLE, uint32(len(elems)))\n}\n\nfunc (fcomp *fcomp) comprehension(comp *syntax.Comprehension, clauseIndex int) {\n\tif clauseIndex == len(comp.Clauses) {\n\t\tfcomp.emit(DUP) // accumulator\n\t\tif comp.Curly {\n\t\t\t// dict: {k:v for ...}\n\t\t\t// Parser ensures that body is of form k:v.\n\t\t\t// Python-style set comprehensions {body for vars in x}\n\t\t\t// are not supported.\n\t\t\tentry := comp.Body.(*syntax.DictEntry)\n\t\t\tfcomp.expr(entry.Key)\n\t\t\tfcomp.expr(entry.Value)\n\t\t\tfcomp.setPos(entry.Colon)\n\t\t\tfcomp.emit(SETDICT)\n\t\t} else {\n\t\t\t// list: [body for vars in x]\n\t\t\tfcomp.expr(comp.Body)\n\t\t\tfcomp.emit(APPEND)\n\t\t}\n\t\treturn\n\t}\n\n\tclause := comp.Clauses[clauseIndex]\n\tswitch clause := clause.(type) {\n\tcase *syntax.IfClause:\n\t\tt := fcomp.newBlock()\n\t\tdone := fcomp.newBlock()\n\t\tfcomp.ifelse(clause.Cond, t, done)\n\n\t\tfcomp.block = t\n\t\tfcomp.comprehension(comp, clauseIndex+1)\n\t\tfcomp.jump(done)\n\n\t\tfcomp.block = done\n\t\treturn\n\n\tcase *syntax.ForClause:\n\t\t// Keep consistent with ForStmt.\n\t\thead := fcomp.newBlock()\n\t\tbody := fcomp.newBlock()\n\t\ttail := fcomp.newBlock()\n\n\t\tfcomp.expr(clause.X)\n\t\tfcomp.setPos(clause.For)\n\t\tfcomp.emit(ITERPUSH)\n\t\tfcomp.jump(head)\n\n\t\tfcomp.block = head\n\t\tfcomp.condjump(ITERJMP, tail, body)\n\n\t\tfcomp.block = body\n\t\tfcomp.assign(clause.For, clause.Vars)\n\t\tfcomp.comprehension(comp, clauseIndex+1)\n\t\tfcomp.jump(head)\n\n\t\tfcomp.block = tail\n\t\tfcomp.emit(ITERPOP)\n\t\treturn\n\t}\n\n\tstart, _ := clause.Span()\n\tlog.Panicf(\"%s: unexpected comprehension clause %T\", start, clause)\n}\n\nfunc (fcomp *fcomp) function(f *resolve.Function) {\n\t// Evaluation of the defaults may fail, so record the position.\n\tfcomp.setPos(f.Pos)\n\n\t// To reduce allocation, we emit a combined tuple\n\t// for the defaults and the freevars.\n\t// The function knows where to split it at run time.\n\n\t// Generate tuple of parameter defaults. For:\n\t//  def f(p1, p2=dp2, p3=dp3, *, k1, k2=dk2, k3, **kwargs)\n\t// the tuple is:\n\t//  (dp2, dp3, MANDATORY, dk2, MANDATORY).\n\tndefaults := 0\n\tseenStar := false\n\tfor _, param := range f.Params {\n\t\tswitch param := param.(type) {\n\t\tcase *syntax.BinaryExpr:\n\t\t\tfcomp.expr(param.Y)\n\t\t\tndefaults++\n\t\tcase *syntax.UnaryExpr:\n\t\t\tseenStar = true // * or *args (also **kwargs)\n\t\tcase *syntax.Ident:\n\t\t\tif seenStar {\n\t\t\t\tfcomp.emit(MANDATORY)\n\t\t\t\tndefaults++\n\t\t\t}\n\t\t}\n\t}\n\n\t// Capture the cells of the function's\n\t// free variables from the lexical environment.\n\tfor _, freevar := range f.FreeVars {\n\t\t// Don't call fcomp.lookup because we want\n\t\t// the cell itself, not its content.\n\t\tswitch freevar.Scope {\n\t\tcase resolve.Free:\n\t\t\tfcomp.emit1(FREE, uint32(freevar.Index))\n\t\tcase resolve.Cell:\n\t\t\tfcomp.emit1(LOCAL, uint32(freevar.Index))\n\t\t}\n\t}\n\n\tfcomp.emit1(MAKETUPLE, uint32(ndefaults+len(f.FreeVars)))\n\n\tfuncode := fcomp.pcomp.function(f.Name, f.Pos, f.Body, f.Locals, f.FreeVars)\n\n\tif debug {\n\t\t// TODO(adonovan): do compilations sequentially not as a tree,\n\t\t// to make the log easier to read.\n\t\t// Simplify by identifying Toplevel and functionIndex 0.\n\t\tfmt.Fprintf(os.Stderr, \"resuming %s @ %s\\n\", fcomp.fn.Name, fcomp.pos)\n\t}\n\n\t// def f(a, *, b=1) has only 2 parameters.\n\tnumParams := len(f.Params)\n\tif f.NumKwonlyParams > 0 && !f.HasVarargs {\n\t\tnumParams--\n\t}\n\n\tfuncode.NumParams = numParams\n\tfuncode.NumKwonlyParams = f.NumKwonlyParams\n\tfuncode.HasVarargs = f.HasVarargs\n\tfuncode.HasKwargs = f.HasKwargs\n\tfcomp.emit1(MAKEFUNC, fcomp.pcomp.functionIndex(funcode))\n}\n\n// ifelse emits a Boolean control flow decision.\n// On return, the current block is unset.\nfunc (fcomp *fcomp) ifelse(cond syntax.Expr, t, f *block) {\n\tswitch cond := cond.(type) {\n\tcase *syntax.UnaryExpr:\n\t\tif cond.Op == syntax.NOT {\n\t\t\t// if not x then goto t else goto f\n\t\t\t//    =>\n\t\t\t// if x then goto f else goto t\n\t\t\tfcomp.ifelse(cond.X, f, t)\n\t\t\treturn\n\t\t}\n\n\tcase *syntax.BinaryExpr:\n\t\tswitch cond.Op {\n\t\tcase syntax.AND:\n\t\t\t// if x and y then goto t else goto f\n\t\t\t//    =>\n\t\t\t// if x then ifelse(y, t, f) else goto f\n\t\t\tfcomp.expr(cond.X)\n\t\t\ty := fcomp.newBlock()\n\t\t\tfcomp.condjump(CJMP, y, f)\n\n\t\t\tfcomp.block = y\n\t\t\tfcomp.ifelse(cond.Y, t, f)\n\t\t\treturn\n\n\t\tcase syntax.OR:\n\t\t\t// if x or y then goto t else goto f\n\t\t\t//    =>\n\t\t\t// if x then goto t else ifelse(y, t, f)\n\t\t\tfcomp.expr(cond.X)\n\t\t\ty := fcomp.newBlock()\n\t\t\tfcomp.condjump(CJMP, t, y)\n\n\t\t\tfcomp.block = y\n\t\t\tfcomp.ifelse(cond.Y, t, f)\n\t\t\treturn\n\t\tcase syntax.NOT_IN:\n\t\t\t// if x not in y then goto t else goto f\n\t\t\t//    =>\n\t\t\t// if x in y then goto f else goto t\n\t\t\tcopy := *cond\n\t\t\tcopy.Op = syntax.IN\n\t\t\tfcomp.expr(&copy)\n\t\t\tfcomp.condjump(CJMP, f, t)\n\t\t\treturn\n\t\t}\n\t}\n\n\t// general case\n\tfcomp.expr(cond)\n\tfcomp.condjump(CJMP, t, f)\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/internal/compile/serial.go",
    "content": "package compile\n\n// This file defines functions to read and write a compile.Program to a file.\n//\n// It is the client's responsibility to avoid version skew between the\n// compiler used to produce a file and the interpreter that consumes it.\n// The version number is provided as a constant.\n// Incompatible protocol changes should also increment the version number.\n//\n// Encoding\n//\n// Program:\n//\t\"sky!\"\t\t[4]byte\t\t# magic number\n//\tstr\t\tuint32le\t# offset of <strings> section\n//\tversion\t\tvarint\t\t# must match Version\n//\tfilename\tstring\n//\tnumloads\tvarint\n//\tloads\t\t[]Ident\n//\tnumnames\tvarint\n//\tnames\t\t[]string\n//\tnumconsts\tvarint\n//\tconsts\t\t[]Constant\n//\tnumglobals\tvarint\n//\tglobals\t\t[]Ident\n//\ttoplevel\tFuncode\n//\tnumfuncs\tvarint\n//\tfuncs\t\t[]Funcode\n//\t<strings>\t[]byte\t\t# concatenation of all referenced strings\n//\tEOF\n//\n// Funcode:\n//\tid\t\tIdent\n//\tcode\t\t[]byte\n//\tpclinetablen\tvarint\n//\tpclinetab\t[]varint\n//\tnumlocals\tvarint\n//\tlocals\t\t[]Ident\n//\tnumcells\tvarint\n//\tcells\t\t[]int\n//\tnumfreevars\tvarint\n//\tfreevar\t\t[]Ident\n//\tmaxstack\tvarint\n//\tnumparams\tvarint\n//\tnumkwonlyparams\tvarint\n//\thasvarargs\tvarint (0 or 1)\n//\thaskwargs\tvarint (0 or 1)\n//\n// Ident:\n//\tfilename\tstring\n//\tline, col\tvarint\n//\n// Constant:                            # type      data\n//      type            varint          # 0=string  string\n//      data            ...             # 1=int     varint\n//                                      # 2=float   varint (bits as uint64)\n//                                      # 3=bigint  string (decimal ASCII text)\n//\n// The encoding starts with a four-byte magic number.\n// The next four bytes are a little-endian uint32\n// that provides the offset of the string section\n// at the end of the file, which contains the ordered\n// concatenation of all strings referenced by the\n// program. This design permits the decoder to read\n// the first and second parts of the file into different\n// memory allocations: the first (the encoded program)\n// is transient, but the second (the strings) persists\n// for the life of the Program.\n//\n// Within the encoded program, all strings are referred\n// to by their length. As the encoder and decoder process\n// the entire file sequentially, they are in lock step,\n// so the start offset of each string is implicit.\n//\n// Program.Code is represented as a []byte slice to permit\n// modification when breakpoints are set. All other strings\n// are represented as strings. They all (unsafely) share the\n// same backing byte slice.\n//\n// Aside from the str field, all integers are encoded as varints.\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\tdebugpkg \"runtime/debug\"\n\t\"unsafe\"\n\n\t\"go.starlark.net/syntax\"\n)\n\nconst magic = \"!sky\"\n\n// Encode encodes a compiled Starlark program.\nfunc (prog *Program) Encode() []byte {\n\tvar e encoder\n\te.p = append(e.p, magic...)\n\te.p = append(e.p, \"????\"...) // string data offset; filled in later\n\te.int(Version)\n\te.string(prog.Toplevel.Pos.Filename())\n\te.bindings(prog.Loads)\n\te.int(len(prog.Names))\n\tfor _, name := range prog.Names {\n\t\te.string(name)\n\t}\n\te.int(len(prog.Constants))\n\tfor _, c := range prog.Constants {\n\t\tswitch c := c.(type) {\n\t\tcase string:\n\t\t\te.int(0)\n\t\t\te.string(c)\n\t\tcase int64:\n\t\t\te.int(1)\n\t\t\te.int64(c)\n\t\tcase float64:\n\t\t\te.int(2)\n\t\t\te.uint64(math.Float64bits(c))\n\t\tcase *big.Int:\n\t\t\te.int(3)\n\t\t\te.string(c.Text(10))\n\t\t}\n\t}\n\te.bindings(prog.Globals)\n\te.function(prog.Toplevel)\n\te.int(len(prog.Functions))\n\tfor _, fn := range prog.Functions {\n\t\te.function(fn)\n\t}\n\n\t// Patch in the offset of the string data section.\n\tbinary.LittleEndian.PutUint32(e.p[4:8], uint32(len(e.p)))\n\n\treturn append(e.p, e.s...)\n}\n\ntype encoder struct {\n\tp   []byte // encoded program\n\ts   []byte // strings\n\ttmp [binary.MaxVarintLen64]byte\n}\n\nfunc (e *encoder) int(x int) {\n\te.int64(int64(x))\n}\n\nfunc (e *encoder) int64(x int64) {\n\tn := binary.PutVarint(e.tmp[:], x)\n\te.p = append(e.p, e.tmp[:n]...)\n}\n\nfunc (e *encoder) uint64(x uint64) {\n\tn := binary.PutUvarint(e.tmp[:], x)\n\te.p = append(e.p, e.tmp[:n]...)\n}\n\nfunc (e *encoder) string(s string) {\n\te.int(len(s))\n\te.s = append(e.s, s...)\n}\n\nfunc (e *encoder) bytes(b []byte) {\n\te.int(len(b))\n\te.s = append(e.s, b...)\n}\n\nfunc (e *encoder) binding(bind Binding) {\n\te.string(bind.Name)\n\te.int(int(bind.Pos.Line))\n\te.int(int(bind.Pos.Col))\n}\n\nfunc (e *encoder) bindings(binds []Binding) {\n\te.int(len(binds))\n\tfor _, bind := range binds {\n\t\te.binding(bind)\n\t}\n}\n\nfunc (e *encoder) function(fn *Funcode) {\n\te.binding(Binding{fn.Name, fn.Pos})\n\te.string(fn.Doc)\n\te.bytes(fn.Code)\n\te.int(len(fn.pclinetab))\n\tfor _, x := range fn.pclinetab {\n\t\te.int64(int64(x))\n\t}\n\te.bindings(fn.Locals)\n\te.int(len(fn.Cells))\n\tfor _, index := range fn.Cells {\n\t\te.int(index)\n\t}\n\te.bindings(fn.Freevars)\n\te.int(fn.MaxStack)\n\te.int(fn.NumParams)\n\te.int(fn.NumKwonlyParams)\n\te.int(b2i(fn.HasVarargs))\n\te.int(b2i(fn.HasKwargs))\n}\n\nfunc b2i(b bool) int {\n\tif b {\n\t\treturn 1\n\t} else {\n\t\treturn 0\n\t}\n}\n\n// DecodeProgram decodes a compiled Starlark program from data.\nfunc DecodeProgram(data []byte) (_ *Program, err error) {\n\tif len(data) < len(magic) {\n\t\treturn nil, fmt.Errorf(\"not a compiled module: no magic number\")\n\t}\n\tif got := string(data[:4]); got != magic {\n\t\treturn nil, fmt.Errorf(\"not a compiled module: got magic number %q, want %q\",\n\t\t\tgot, magic)\n\t}\n\tdefer func() {\n\t\tif x := recover(); x != nil {\n\t\t\tdebugpkg.PrintStack()\n\t\t\terr = fmt.Errorf(\"internal error while decoding program: %v\", x)\n\t\t}\n\t}()\n\n\toffset := binary.LittleEndian.Uint32(data[4:8])\n\td := decoder{\n\t\tp: data[8:offset],\n\t\ts: append([]byte(nil), data[offset:]...), // allocate a copy, which will persist\n\t}\n\n\tif v := d.int(); v != Version {\n\t\treturn nil, fmt.Errorf(\"version mismatch: read %d, want %d\", v, Version)\n\t}\n\n\tfilename := d.string()\n\td.filename = &filename\n\n\tloads := d.bindings()\n\n\tnames := make([]string, d.int())\n\tfor i := range names {\n\t\tnames[i] = d.string()\n\t}\n\n\t// constants\n\tconstants := make([]interface{}, d.int())\n\tfor i := range constants {\n\t\tvar c interface{}\n\t\tswitch d.int() {\n\t\tcase 0:\n\t\t\tc = d.string()\n\t\tcase 1:\n\t\t\tc = d.int64()\n\t\tcase 2:\n\t\t\tc = math.Float64frombits(d.uint64())\n\t\tcase 3:\n\t\t\tc, _ = new(big.Int).SetString(d.string(), 10)\n\t\t}\n\t\tconstants[i] = c\n\t}\n\n\tglobals := d.bindings()\n\ttoplevel := d.function()\n\tfuncs := make([]*Funcode, d.int())\n\tfor i := range funcs {\n\t\tfuncs[i] = d.function()\n\t}\n\n\tprog := &Program{\n\t\tLoads:     loads,\n\t\tNames:     names,\n\t\tConstants: constants,\n\t\tGlobals:   globals,\n\t\tFunctions: funcs,\n\t\tToplevel:  toplevel,\n\t}\n\ttoplevel.Prog = prog\n\tfor _, f := range funcs {\n\t\tf.Prog = prog\n\t}\n\n\tif len(d.p)+len(d.s) > 0 {\n\t\treturn nil, fmt.Errorf(\"internal error: unconsumed data during decoding\")\n\t}\n\n\treturn prog, nil\n}\n\ntype decoder struct {\n\tp        []byte  // encoded program\n\ts        []byte  // strings\n\tfilename *string // (indirect to avoid keeping decoder live)\n}\n\nfunc (d *decoder) int() int {\n\treturn int(d.int64())\n}\n\nfunc (d *decoder) int64() int64 {\n\tx, len := binary.Varint(d.p[:])\n\td.p = d.p[len:]\n\treturn x\n}\n\nfunc (d *decoder) uint64() uint64 {\n\tx, len := binary.Uvarint(d.p[:])\n\td.p = d.p[len:]\n\treturn x\n}\n\nfunc (d *decoder) string() (s string) {\n\tif slice := d.bytes(); len(slice) > 0 {\n\t\t// Avoid a memory allocation for each string\n\t\t// by unsafely aliasing slice.\n\t\ttype string struct {\n\t\t\tdata *byte\n\t\t\tlen  int\n\t\t}\n\t\tptr := (*string)(unsafe.Pointer(&s))\n\t\tptr.data = &slice[0]\n\t\tptr.len = len(slice)\n\t}\n\treturn s\n}\n\nfunc (d *decoder) bytes() []byte {\n\tlen := d.int()\n\tr := d.s[:len:len]\n\td.s = d.s[len:]\n\treturn r\n}\n\nfunc (d *decoder) binding() Binding {\n\tname := d.string()\n\tline := int32(d.int())\n\tcol := int32(d.int())\n\treturn Binding{Name: name, Pos: syntax.MakePosition(d.filename, line, col)}\n}\n\nfunc (d *decoder) bindings() []Binding {\n\tbindings := make([]Binding, d.int())\n\tfor i := range bindings {\n\t\tbindings[i] = d.binding()\n\t}\n\treturn bindings\n}\n\nfunc (d *decoder) ints() []int {\n\tints := make([]int, d.int())\n\tfor i := range ints {\n\t\tints[i] = d.int()\n\t}\n\treturn ints\n}\n\nfunc (d *decoder) bool() bool { return d.int() != 0 }\n\nfunc (d *decoder) function() *Funcode {\n\tid := d.binding()\n\tdoc := d.string()\n\tcode := d.bytes()\n\tpclinetab := make([]uint16, d.int())\n\tfor i := range pclinetab {\n\t\tpclinetab[i] = uint16(d.int())\n\t}\n\tlocals := d.bindings()\n\tcells := d.ints()\n\tfreevars := d.bindings()\n\tmaxStack := d.int()\n\tnumParams := d.int()\n\tnumKwonlyParams := d.int()\n\thasVarargs := d.int() != 0\n\thasKwargs := d.int() != 0\n\treturn &Funcode{\n\t\t// Prog is filled in later.\n\t\tPos:             id.Pos,\n\t\tName:            id.Name,\n\t\tDoc:             doc,\n\t\tCode:            code,\n\t\tpclinetab:       pclinetab,\n\t\tLocals:          locals,\n\t\tCells:           cells,\n\t\tFreevars:        freevars,\n\t\tMaxStack:        maxStack,\n\t\tNumParams:       numParams,\n\t\tNumKwonlyParams: numKwonlyParams,\n\t\tHasVarargs:      hasVarargs,\n\t\tHasKwargs:       hasKwargs,\n\t}\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/internal/spell/spell.go",
    "content": "// Package spell file defines a simple spelling checker for use in attribute errors\n// such as \"no such field .foo; did you mean .food?\".\npackage spell\n\nimport (\n\t\"strings\"\n\t\"unicode\"\n)\n\n// Nearest returns the element of candidates\n// nearest to x using the Levenshtein metric,\n// or \"\" if none were promising.\nfunc Nearest(x string, candidates []string) string {\n\t// Ignore underscores and case when matching.\n\tfold := func(s string) string {\n\t\treturn strings.Map(func(r rune) rune {\n\t\t\tif r == '_' {\n\t\t\t\treturn -1\n\t\t\t}\n\t\t\treturn unicode.ToLower(r)\n\t\t}, s)\n\t}\n\n\tx = fold(x)\n\n\tvar best string\n\tbestD := (len(x) + 1) / 2 // allow up to 50% typos\n\tfor _, c := range candidates {\n\t\td := levenshtein(x, fold(c), bestD)\n\t\tif d < bestD {\n\t\t\tbestD = d\n\t\t\tbest = c\n\t\t}\n\t}\n\treturn best\n}\n\n// levenshtein returns the non-negative Levenshtein edit distance\n// between the byte strings x and y.\n//\n// If the computed distance exceeds max,\n// the function may return early with an approximate value > max.\nfunc levenshtein(x, y string, max int) int {\n\t// This implementation is derived from one by Laurent Le Brun in\n\t// Bazel that uses the single-row space efficiency trick\n\t// described at bitbucket.org/clearer/iosifovich.\n\n\t// Let x be the shorter string.\n\tif len(x) > len(y) {\n\t\tx, y = y, x\n\t}\n\n\t// Remove common prefix.\n\tfor i := 0; i < len(x); i++ {\n\t\tif x[i] != y[i] {\n\t\t\tx = x[i:]\n\t\t\ty = y[i:]\n\t\t\tbreak\n\t\t}\n\t}\n\tif x == \"\" {\n\t\treturn len(y)\n\t}\n\n\tif d := abs(len(x) - len(y)); d > max {\n\t\treturn d // excessive length divergence\n\t}\n\n\trow := make([]int, len(y)+1)\n\tfor i := range row {\n\t\trow[i] = i\n\t}\n\n\tfor i := 1; i <= len(x); i++ {\n\t\trow[0] = i\n\t\tbest := i\n\t\tprev := i - 1\n\t\tfor j := 1; j <= len(y); j++ {\n\t\t\ta := prev + b2i(x[i-1] != y[j-1]) // substitution\n\t\t\tb := 1 + row[j-1]                 // deletion\n\t\t\tc := 1 + row[j]                   // insertion\n\t\t\tk := min(a, min(b, c))\n\t\t\tprev, row[j] = row[j], k\n\t\t\tbest = min(best, k)\n\t\t}\n\t\tif best > max {\n\t\t\treturn best\n\t\t}\n\t}\n\treturn row[len(y)]\n}\n\nfunc b2i(b bool) int {\n\tif b {\n\t\treturn 1\n\t} else {\n\t\treturn 0\n\t}\n}\n\nfunc min(x, y int) int {\n\tif x < y {\n\t\treturn x\n\t} else {\n\t\treturn y\n\t}\n}\n\nfunc abs(x int) int {\n\tif x >= 0 {\n\t\treturn x\n\t} else {\n\t\treturn -x\n\t}\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/resolve/binding.go",
    "content": "// Copyright 2019 The Bazel 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 resolve\n\nimport \"go.starlark.net/syntax\"\n\n// This file defines resolver data types saved in the syntax tree.\n// We cannot guarantee API stability for these types\n// as they are closely tied to the implementation.\n\n// A Binding contains resolver information about an identifer.\n// The resolver populates the Binding field of each syntax.Identifier.\n// The Binding ties together all identifiers that denote the same variable.\ntype Binding struct {\n\tScope Scope\n\n\t// Index records the index into the enclosing\n\t// - {DefStmt,File}.Locals, if Scope==Local\n\t// - DefStmt.FreeVars,      if Scope==Free\n\t// - File.Globals,          if Scope==Global.\n\t// It is zero if Scope is Predeclared, Universal, or Undefined.\n\tIndex int\n\n\tFirst *syntax.Ident // first binding use (iff Scope==Local/Free/Global)\n}\n\n// The Scope of Binding indicates what kind of scope it has.\ntype Scope uint8\n\nconst (\n\tUndefined   Scope = iota // name is not defined\n\tLocal                    // name is local to its function or file\n\tCell                     // name is function-local but shared with a nested function\n\tFree                     // name is cell of some enclosing function\n\tGlobal                   // name is global to module\n\tPredeclared              // name is predeclared for this module (e.g. glob)\n\tUniversal                // name is universal (e.g. len)\n)\n\nvar scopeNames = [...]string{\n\tUndefined:   \"undefined\",\n\tLocal:       \"local\",\n\tCell:        \"cell\",\n\tFree:        \"free\",\n\tGlobal:      \"global\",\n\tPredeclared: \"predeclared\",\n\tUniversal:   \"universal\",\n}\n\nfunc (scope Scope) String() string { return scopeNames[scope] }\n\n// A Module contains resolver information about a file.\n// The resolver populates the Module field of each syntax.File.\ntype Module struct {\n\tLocals  []*Binding // the file's (comprehension-)local variables\n\tGlobals []*Binding // the file's global variables\n}\n\n// A Function contains resolver information about a named or anonymous function.\n// The resolver populates the Function field of each syntax.DefStmt and syntax.LambdaExpr.\ntype Function struct {\n\tPos    syntax.Position // of DEF or LAMBDA\n\tName   string          // name of def, or \"lambda\"\n\tParams []syntax.Expr   // param = ident | ident=expr | * | *ident | **ident\n\tBody   []syntax.Stmt   // contains synthetic 'return expr' for lambda\n\n\tHasVarargs      bool       // whether params includes *args (convenience)\n\tHasKwargs       bool       // whether params includes **kwargs (convenience)\n\tNumKwonlyParams int        // number of keyword-only optional parameters\n\tLocals          []*Binding // this function's local/cell variables, parameters first\n\tFreeVars        []*Binding // enclosing cells to capture in closure\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/resolve/resolve.go",
    "content": "// Copyright 2017 The Bazel 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// Package resolve defines a name-resolution pass for Starlark abstract\n// syntax trees.\n//\n// The resolver sets the Locals and FreeVars arrays of each DefStmt and\n// the LocalIndex field of each syntax.Ident that refers to a local or\n// free variable.  It also sets the Locals array of a File for locals\n// bound by top-level comprehensions and load statements.\n// Identifiers for global variables do not get an index.\npackage resolve // import \"go.starlark.net/resolve\"\n\n// All references to names are statically resolved.  Names may be\n// predeclared, global, or local to a function or file.\n// File-local variables include those bound by top-level comprehensions\n// and by load statements. (\"Top-level\" means \"outside of any function\".)\n// The resolver maps each global name to a small integer and each local\n// name to a small integer; these integers enable a fast and compact\n// representation of globals and locals in the evaluator.\n//\n// As an optimization, the resolver classifies each predeclared name as\n// either universal (e.g. None, len) or per-module (e.g. glob in Bazel's\n// build language), enabling the evaluator to share the representation\n// of the universal environment across all modules.\n//\n// The lexical environment is a tree of blocks with the file block at\n// its root. The file's child blocks may be of two kinds: functions\n// and comprehensions, and these may have further children of either\n// kind.\n//\n// Python-style resolution requires multiple passes because a name is\n// determined to be local to a function only if the function contains a\n// \"binding\" use of it; similarly, a name is determined to be global (as\n// opposed to predeclared) if the module contains a top-level binding use.\n// Unlike ordinary top-level assignments, the bindings created by load\n// statements are local to the file block.\n// A non-binding use may lexically precede the binding to which it is resolved.\n// In the first pass, we inspect each function, recording in\n// 'uses' each identifier and the environment block in which it occurs.\n// If a use of a name is binding, such as a function parameter or\n// assignment, we add the name to the block's bindings mapping and add a\n// local variable to the enclosing function.\n//\n// As we finish resolving each function, we inspect all the uses within\n// that function and discard ones that were found to be function-local. The\n// remaining ones must be either free (local to some lexically enclosing\n// function), or top-level (global, predeclared, or file-local), but we cannot tell\n// which until we have finished inspecting the outermost enclosing\n// function. At that point, we can distinguish local from top-level names\n// (and this is when Python would compute free variables).\n//\n// However, Starlark additionally requires that all references to global\n// names are satisfied by some declaration in the current module;\n// Starlark permits a function to forward-reference a global or file-local\n// that has not\n// been declared yet so long as it is declared before the end of the\n// module.  So, instead of re-resolving the unresolved references after\n// each top-level function, we defer this until the end of the module\n// and ensure that all such references are satisfied by some definition.\n//\n// At the end of the module, we visit each of the nested function blocks\n// in bottom-up order, doing a recursive lexical lookup for each\n// unresolved name.  If the name is found to be local to some enclosing\n// function, we must create a DefStmt.FreeVar (capture) parameter for\n// each intervening function.  We enter these synthetic bindings into\n// the bindings map so that we create at most one freevar per name.  If\n// the name was not local, we check that it was defined at module level.\n//\n// We resolve all uses of locals in the module (due to load statements\n// and comprehensions) in a similar way and compute the file's set of\n// local variables.\n//\n// Starlark enforces that all global names are assigned at most once on\n// all control flow paths by forbidding if/else statements and loops at\n// top level. A global may be used before it is defined, leading to a\n// dynamic error. However, the AllowGlobalReassign flag (really: allow\n// top-level reassign) makes the resolver allow multiple to a variable\n// at top-level. It also allows if-, for-, and while-loops at top-level,\n// which in turn may make the evaluator dynamically assign multiple\n// values to a variable at top-level. (These two roles should be separated.)\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"go.starlark.net/internal/spell\"\n\t\"go.starlark.net/syntax\"\n)\n\nconst debug = false\nconst doesnt = \"this Starlark dialect does not \"\n\n// global options\n// These features are either not standard Starlark (yet), or deprecated\n// features of the BUILD language, so we put them behind flags.\nvar (\n\tAllowNestedDef      = false // allow def statements within function bodies\n\tAllowLambda         = false // allow lambda expressions\n\tAllowFloat          = false // allow floating point literals, the 'float' built-in, and x / y\n\tAllowSet            = false // allow the 'set' built-in\n\tAllowGlobalReassign = false // allow reassignment to top-level names; also, allow if/for/while at top-level\n\tAllowRecursion      = false // allow while statements and recursive functions\n\tAllowBitwise        = true  // obsolete; bitwise operations (&, |, ^, ~, <<, and >>) are always enabled\n\tLoadBindsGlobally   = false // load creates global not file-local bindings (deprecated)\n)\n\n// File resolves the specified file and records information about the\n// module in file.Module.\n//\n// The isPredeclared and isUniversal predicates report whether a name is\n// a pre-declared identifier (visible in the current module) or a\n// universal identifier (visible in every module).\n// Clients should typically pass predeclared.Has for the first and\n// starlark.Universe.Has for the second, where predeclared is the\n// module's StringDict of predeclared names and starlark.Universe is the\n// standard set of built-ins.\n// The isUniverse predicate is supplied a parameter to avoid a cyclic\n// dependency upon starlark.Universe, not because users should ever need\n// to redefine it.\nfunc File(file *syntax.File, isPredeclared, isUniversal func(name string) bool) error {\n\treturn REPLChunk(file, nil, isPredeclared, isUniversal)\n}\n\n// REPLChunk is a generalization of the File function that supports a\n// non-empty initial global block, as occurs in a REPL.\nfunc REPLChunk(file *syntax.File, isGlobal, isPredeclared, isUniversal func(name string) bool) error {\n\tr := newResolver(isGlobal, isPredeclared, isUniversal)\n\tr.stmts(file.Stmts)\n\n\tr.env.resolveLocalUses()\n\n\t// At the end of the module, resolve all non-local variable references,\n\t// computing closures.\n\t// Function bodies may contain forward references to later global declarations.\n\tr.resolveNonLocalUses(r.env)\n\n\tfile.Module = &Module{\n\t\tLocals:  r.moduleLocals,\n\t\tGlobals: r.moduleGlobals,\n\t}\n\n\tif len(r.errors) > 0 {\n\t\treturn r.errors\n\t}\n\treturn nil\n}\n\n// Expr resolves the specified expression.\n// It returns the local variables bound within the expression.\n//\n// The isPredeclared and isUniversal predicates behave as for the File function.\nfunc Expr(expr syntax.Expr, isPredeclared, isUniversal func(name string) bool) ([]*Binding, error) {\n\tr := newResolver(nil, isPredeclared, isUniversal)\n\tr.expr(expr)\n\tr.env.resolveLocalUses()\n\tr.resolveNonLocalUses(r.env) // globals & universals\n\tif len(r.errors) > 0 {\n\t\treturn nil, r.errors\n\t}\n\treturn r.moduleLocals, nil\n}\n\n// An ErrorList is a non-empty list of resolver error messages.\ntype ErrorList []Error // len > 0\n\nfunc (e ErrorList) Error() string { return e[0].Error() }\n\n// An Error describes the nature and position of a resolver error.\ntype Error struct {\n\tPos syntax.Position\n\tMsg string\n}\n\nfunc (e Error) Error() string { return e.Pos.String() + \": \" + e.Msg }\n\nfunc newResolver(isGlobal, isPredeclared, isUniversal func(name string) bool) *resolver {\n\tfile := new(block)\n\treturn &resolver{\n\t\tfile:          file,\n\t\tenv:           file,\n\t\tisGlobal:      isGlobal,\n\t\tisPredeclared: isPredeclared,\n\t\tisUniversal:   isUniversal,\n\t\tglobals:       make(map[string]*Binding),\n\t\tpredeclared:   make(map[string]*Binding),\n\t}\n}\n\ntype resolver struct {\n\t// env is the current local environment:\n\t// a linked list of blocks, innermost first.\n\t// The tail of the list is the file block.\n\tenv  *block\n\tfile *block // file block (contains load bindings)\n\n\t// moduleLocals contains the local variables of the module\n\t// (due to load statements and comprehensions outside any function).\n\t// moduleGlobals contains the global variables of the module.\n\tmoduleLocals  []*Binding\n\tmoduleGlobals []*Binding\n\n\t// globals maps each global name in the module to its binding.\n\t// predeclared does the same for predeclared and universal names.\n\tglobals     map[string]*Binding\n\tpredeclared map[string]*Binding\n\n\t// These predicates report whether a name is\n\t// pre-declared, either in this module or universally,\n\t// or already declared in the module globals (as in a REPL).\n\t// isGlobal may be nil.\n\tisGlobal, isPredeclared, isUniversal func(name string) bool\n\n\tloops int // number of enclosing for loops\n\n\terrors ErrorList\n}\n\n// container returns the innermost enclosing \"container\" block:\n// a function (function != nil) or file (function == nil).\n// Container blocks accumulate local variable bindings.\nfunc (r *resolver) container() *block {\n\tfor b := r.env; ; b = b.parent {\n\t\tif b.function != nil || b == r.file {\n\t\t\treturn b\n\t\t}\n\t}\n}\n\nfunc (r *resolver) push(b *block) {\n\tr.env.children = append(r.env.children, b)\n\tb.parent = r.env\n\tr.env = b\n}\n\nfunc (r *resolver) pop() { r.env = r.env.parent }\n\ntype block struct {\n\tparent *block // nil for file block\n\n\t// In the file (root) block, both these fields are nil.\n\tfunction *Function             // only for function blocks\n\tcomp     *syntax.Comprehension // only for comprehension blocks\n\n\t// bindings maps a name to its binding.\n\t// A local binding has an index into its innermost enclosing container's locals array.\n\t// A free binding has an index into its innermost enclosing function's freevars array.\n\tbindings map[string]*Binding\n\n\t// children records the child blocks of the current one.\n\tchildren []*block\n\n\t// uses records all identifiers seen in this container (function or file),\n\t// and a reference to the environment in which they appear.\n\t// As we leave each container block, we resolve them,\n\t// so that only free and global ones remain.\n\t// At the end of each top-level function we compute closures.\n\tuses []use\n}\n\nfunc (b *block) bind(name string, bind *Binding) {\n\tif b.bindings == nil {\n\t\tb.bindings = make(map[string]*Binding)\n\t}\n\tb.bindings[name] = bind\n}\n\nfunc (b *block) String() string {\n\tif b.function != nil {\n\t\treturn \"function block at \" + fmt.Sprint(b.function.Pos)\n\t}\n\tif b.comp != nil {\n\t\treturn \"comprehension block at \" + fmt.Sprint(b.comp.Span())\n\t}\n\treturn \"file block\"\n}\n\nfunc (r *resolver) errorf(posn syntax.Position, format string, args ...interface{}) {\n\tr.errors = append(r.errors, Error{posn, fmt.Sprintf(format, args...)})\n}\n\n// A use records an identifier and the environment in which it appears.\ntype use struct {\n\tid  *syntax.Ident\n\tenv *block\n}\n\n// bind creates a binding for id: a global (not file-local)\n// binding at top-level, a local binding otherwise.\n// At top-level, it reports an error if a global or file-local\n// binding already exists, unless AllowGlobalReassign.\n// It sets id.Binding to the binding (whether old or new),\n// and returns whether a binding already existed.\nfunc (r *resolver) bind(id *syntax.Ident) bool {\n\t// Binding outside any local (comprehension/function) block?\n\tif r.env == r.file {\n\t\tbind, ok := r.file.bindings[id.Name]\n\t\tif !ok {\n\t\t\tbind, ok = r.globals[id.Name]\n\t\t\tif !ok {\n\t\t\t\t// first global binding of this name\n\t\t\t\tbind = &Binding{\n\t\t\t\t\tFirst: id,\n\t\t\t\t\tScope: Global,\n\t\t\t\t\tIndex: len(r.moduleGlobals),\n\t\t\t\t}\n\t\t\t\tr.globals[id.Name] = bind\n\t\t\t\tr.moduleGlobals = append(r.moduleGlobals, bind)\n\t\t\t}\n\t\t}\n\t\tif ok && !AllowGlobalReassign {\n\t\t\tr.errorf(id.NamePos, \"cannot reassign %s %s declared at %s\",\n\t\t\t\tbind.Scope, id.Name, bind.First.NamePos)\n\t\t}\n\t\tid.Binding = bind\n\t\treturn ok\n\t}\n\n\treturn r.bindLocal(id)\n}\n\nfunc (r *resolver) bindLocal(id *syntax.Ident) bool {\n\t// Mark this name as local to current block.\n\t// Assign it a new local (positive) index in the current container.\n\t_, ok := r.env.bindings[id.Name]\n\tif !ok {\n\t\tvar locals *[]*Binding\n\t\tif fn := r.container().function; fn != nil {\n\t\t\tlocals = &fn.Locals\n\t\t} else {\n\t\t\tlocals = &r.moduleLocals\n\t\t}\n\t\tbind := &Binding{\n\t\t\tFirst: id,\n\t\t\tScope: Local,\n\t\t\tIndex: len(*locals),\n\t\t}\n\t\tr.env.bind(id.Name, bind)\n\t\t*locals = append(*locals, bind)\n\t}\n\n\tr.use(id)\n\treturn ok\n}\n\nfunc (r *resolver) use(id *syntax.Ident) {\n\tuse := use{id, r.env}\n\n\t// The spec says that if there is a global binding of a name\n\t// then all references to that name in that block refer to the\n\t// global, even if the use precedes the def---just as for locals.\n\t// For example, in this code,\n\t//\n\t//   print(len); len=1; print(len)\n\t//\n\t// both occurrences of len refer to the len=1 binding, which\n\t// completely shadows the predeclared len function.\n\t//\n\t// The rationale for these semantics, which differ from Python,\n\t// is that the static meaning of len (a reference to a global)\n\t// does not change depending on where it appears in the file.\n\t// Of course, its dynamic meaning does change, from an error\n\t// into a valid reference, so it's not clear these semantics\n\t// have any practical advantage.\n\t//\n\t// In any case, the Bazel implementation lags behind the spec\n\t// and follows Python behavior, so the first use of len refers\n\t// to the predeclared function.  This typically used in a BUILD\n\t// file that redefines a predeclared name half way through,\n\t// for example:\n\t//\n\t//\tproto_library(...) \t\t\t# built-in rule\n\t//      load(\"myproto.bzl\", \"proto_library\")\n\t//\tproto_library(...) \t\t\t# user-defined rule\n\t//\n\t// We will piggyback support for the legacy semantics on the\n\t// AllowGlobalReassign flag, which is loosely related and also\n\t// required for Bazel.\n\tif AllowGlobalReassign && r.env == r.file {\n\t\tr.useToplevel(use)\n\t\treturn\n\t}\n\n\tb := r.container()\n\tb.uses = append(b.uses, use)\n}\n\n// useToplevel resolves use.id as a reference to a name visible at top-level.\n// The use.env field captures the original environment for error reporting.\nfunc (r *resolver) useToplevel(use use) (bind *Binding) {\n\tid := use.id\n\n\tif prev, ok := r.file.bindings[id.Name]; ok {\n\t\t// use of load-defined name in file block\n\t\tbind = prev\n\t} else if prev, ok := r.globals[id.Name]; ok {\n\t\t// use of global declared by module\n\t\tbind = prev\n\t} else if r.isGlobal != nil && r.isGlobal(id.Name) {\n\t\t// use of global defined in a previous REPL chunk\n\t\tbind = &Binding{\n\t\t\tFirst: id, // wrong: this is not even a binding use\n\t\t\tScope: Global,\n\t\t\tIndex: len(r.moduleGlobals),\n\t\t}\n\t\tr.globals[id.Name] = bind\n\t\tr.moduleGlobals = append(r.moduleGlobals, bind)\n\t} else if prev, ok := r.predeclared[id.Name]; ok {\n\t\t// repeated use of predeclared or universal\n\t\tbind = prev\n\t} else if r.isPredeclared(id.Name) {\n\t\t// use of pre-declared name\n\t\tbind = &Binding{Scope: Predeclared}\n\t\tr.predeclared[id.Name] = bind // save it\n\t} else if r.isUniversal(id.Name) {\n\t\t// use of universal name\n\t\tif !AllowFloat && id.Name == \"float\" {\n\t\t\tr.errorf(id.NamePos, doesnt+\"support floating point\")\n\t\t}\n\t\tif !AllowSet && id.Name == \"set\" {\n\t\t\tr.errorf(id.NamePos, doesnt+\"support sets\")\n\t\t}\n\t\tbind = &Binding{Scope: Universal}\n\t\tr.predeclared[id.Name] = bind // save it\n\t} else {\n\t\tbind = &Binding{Scope: Undefined}\n\t\tvar hint string\n\t\tif n := r.spellcheck(use); n != \"\" {\n\t\t\thint = fmt.Sprintf(\" (did you mean %s?)\", n)\n\t\t}\n\t\tr.errorf(id.NamePos, \"undefined: %s%s\", id.Name, hint)\n\t}\n\tid.Binding = bind\n\treturn bind\n}\n\n// spellcheck returns the most likely misspelling of\n// the name use.id in the environment use.env.\nfunc (r *resolver) spellcheck(use use) string {\n\tvar names []string\n\n\t// locals\n\tfor b := use.env; b != nil; b = b.parent {\n\t\tfor name := range b.bindings {\n\t\t\tnames = append(names, name)\n\t\t}\n\t}\n\n\t// globals\n\t//\n\t// We have no way to enumerate the sets whose membership\n\t// tests are isPredeclared, isUniverse, and isGlobal,\n\t// which includes prior names in the REPL session.\n\tfor _, bind := range r.moduleGlobals {\n\t\tnames = append(names, bind.First.Name)\n\t}\n\n\tsort.Strings(names)\n\treturn spell.Nearest(use.id.Name, names)\n}\n\n// resolveLocalUses is called when leaving a container (function/module)\n// block.  It resolves all uses of locals/cells within that block.\nfunc (b *block) resolveLocalUses() {\n\tunresolved := b.uses[:0]\n\tfor _, use := range b.uses {\n\t\tif bind := lookupLocal(use); bind != nil && (bind.Scope == Local || bind.Scope == Cell) {\n\t\t\tuse.id.Binding = bind\n\t\t} else {\n\t\t\tunresolved = append(unresolved, use)\n\t\t}\n\t}\n\tb.uses = unresolved\n}\n\nfunc (r *resolver) stmts(stmts []syntax.Stmt) {\n\tfor _, stmt := range stmts {\n\t\tr.stmt(stmt)\n\t}\n}\n\nfunc (r *resolver) stmt(stmt syntax.Stmt) {\n\tswitch stmt := stmt.(type) {\n\tcase *syntax.ExprStmt:\n\t\tr.expr(stmt.X)\n\n\tcase *syntax.BranchStmt:\n\t\tif r.loops == 0 && (stmt.Token == syntax.BREAK || stmt.Token == syntax.CONTINUE) {\n\t\t\tr.errorf(stmt.TokenPos, \"%s not in a loop\", stmt.Token)\n\t\t}\n\n\tcase *syntax.IfStmt:\n\t\tif !AllowGlobalReassign && r.container().function == nil {\n\t\t\tr.errorf(stmt.If, \"if statement not within a function\")\n\t\t}\n\t\tr.expr(stmt.Cond)\n\t\tr.stmts(stmt.True)\n\t\tr.stmts(stmt.False)\n\n\tcase *syntax.AssignStmt:\n\t\tr.expr(stmt.RHS)\n\t\tisAugmented := stmt.Op != syntax.EQ\n\t\tr.assign(stmt.LHS, isAugmented)\n\n\tcase *syntax.DefStmt:\n\t\tif !AllowNestedDef && r.container().function != nil {\n\t\t\tr.errorf(stmt.Def, doesnt+\"support nested def\")\n\t\t}\n\t\tr.bind(stmt.Name)\n\t\tfn := &Function{\n\t\t\tName:   stmt.Name.Name,\n\t\t\tPos:    stmt.Def,\n\t\t\tParams: stmt.Params,\n\t\t\tBody:   stmt.Body,\n\t\t}\n\t\tstmt.Function = fn\n\t\tr.function(fn, stmt.Def)\n\n\tcase *syntax.ForStmt:\n\t\tif !AllowGlobalReassign && r.container().function == nil {\n\t\t\tr.errorf(stmt.For, \"for loop not within a function\")\n\t\t}\n\t\tr.expr(stmt.X)\n\t\tconst isAugmented = false\n\t\tr.assign(stmt.Vars, isAugmented)\n\t\tr.loops++\n\t\tr.stmts(stmt.Body)\n\t\tr.loops--\n\n\tcase *syntax.WhileStmt:\n\t\tif !AllowRecursion {\n\t\t\tr.errorf(stmt.While, doesnt+\"support while loops\")\n\t\t}\n\t\tif !AllowGlobalReassign && r.container().function == nil {\n\t\t\tr.errorf(stmt.While, \"while loop not within a function\")\n\t\t}\n\t\tr.expr(stmt.Cond)\n\t\tr.loops++\n\t\tr.stmts(stmt.Body)\n\t\tr.loops--\n\n\tcase *syntax.ReturnStmt:\n\t\tif r.container().function == nil {\n\t\t\tr.errorf(stmt.Return, \"return statement not within a function\")\n\t\t}\n\t\tif stmt.Result != nil {\n\t\t\tr.expr(stmt.Result)\n\t\t}\n\n\tcase *syntax.LoadStmt:\n\t\tif r.container().function != nil {\n\t\t\tr.errorf(stmt.Load, \"load statement within a function\")\n\t\t}\n\n\t\tfor i, from := range stmt.From {\n\t\t\tif from.Name == \"\" {\n\t\t\t\tr.errorf(from.NamePos, \"load: empty identifier\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif from.Name[0] == '_' {\n\t\t\t\tr.errorf(from.NamePos, \"load: names with leading underscores are not exported: %s\", from.Name)\n\t\t\t}\n\n\t\t\tid := stmt.To[i]\n\t\t\tif LoadBindsGlobally {\n\t\t\t\tr.bind(id)\n\t\t\t} else if r.bindLocal(id) && !AllowGlobalReassign {\n\t\t\t\t// \"Global\" in AllowGlobalReassign is a misnomer for \"toplevel\".\n\t\t\t\t// Sadly we can't report the previous declaration\n\t\t\t\t// as id.Binding may not be set yet.\n\t\t\t\tr.errorf(id.NamePos, \"cannot reassign top-level %s\", id.Name)\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\tlog.Panicf(\"unexpected stmt %T\", stmt)\n\t}\n}\n\nfunc (r *resolver) assign(lhs syntax.Expr, isAugmented bool) {\n\tswitch lhs := lhs.(type) {\n\tcase *syntax.Ident:\n\t\t// x = ...\n\t\tr.bind(lhs)\n\n\tcase *syntax.IndexExpr:\n\t\t// x[i] = ...\n\t\tr.expr(lhs.X)\n\t\tr.expr(lhs.Y)\n\n\tcase *syntax.DotExpr:\n\t\t// x.f = ...\n\t\tr.expr(lhs.X)\n\n\tcase *syntax.TupleExpr:\n\t\t// (x, y) = ...\n\t\tif len(lhs.List) == 0 {\n\t\t\tr.errorf(syntax.Start(lhs), \"can't assign to ()\")\n\t\t}\n\t\tif isAugmented {\n\t\t\tr.errorf(syntax.Start(lhs), \"can't use tuple expression in augmented assignment\")\n\t\t}\n\t\tfor _, elem := range lhs.List {\n\t\t\tr.assign(elem, isAugmented)\n\t\t}\n\n\tcase *syntax.ListExpr:\n\t\t// [x, y, z] = ...\n\t\tif len(lhs.List) == 0 {\n\t\t\tr.errorf(syntax.Start(lhs), \"can't assign to []\")\n\t\t}\n\t\tif isAugmented {\n\t\t\tr.errorf(syntax.Start(lhs), \"can't use list expression in augmented assignment\")\n\t\t}\n\t\tfor _, elem := range lhs.List {\n\t\t\tr.assign(elem, isAugmented)\n\t\t}\n\n\tcase *syntax.ParenExpr:\n\t\tr.assign(lhs.X, isAugmented)\n\n\tdefault:\n\t\tname := strings.ToLower(strings.TrimPrefix(fmt.Sprintf(\"%T\", lhs), \"*syntax.\"))\n\t\tr.errorf(syntax.Start(lhs), \"can't assign to %s\", name)\n\t}\n}\n\nfunc (r *resolver) expr(e syntax.Expr) {\n\tswitch e := e.(type) {\n\tcase *syntax.Ident:\n\t\tr.use(e)\n\n\tcase *syntax.Literal:\n\t\tif !AllowFloat && e.Token == syntax.FLOAT {\n\t\t\tr.errorf(e.TokenPos, doesnt+\"support floating point\")\n\t\t}\n\n\tcase *syntax.ListExpr:\n\t\tfor _, x := range e.List {\n\t\t\tr.expr(x)\n\t\t}\n\n\tcase *syntax.CondExpr:\n\t\tr.expr(e.Cond)\n\t\tr.expr(e.True)\n\t\tr.expr(e.False)\n\n\tcase *syntax.IndexExpr:\n\t\tr.expr(e.X)\n\t\tr.expr(e.Y)\n\n\tcase *syntax.DictEntry:\n\t\tr.expr(e.Key)\n\t\tr.expr(e.Value)\n\n\tcase *syntax.SliceExpr:\n\t\tr.expr(e.X)\n\t\tif e.Lo != nil {\n\t\t\tr.expr(e.Lo)\n\t\t}\n\t\tif e.Hi != nil {\n\t\t\tr.expr(e.Hi)\n\t\t}\n\t\tif e.Step != nil {\n\t\t\tr.expr(e.Step)\n\t\t}\n\n\tcase *syntax.Comprehension:\n\t\t// The 'in' operand of the first clause (always a ForClause)\n\t\t// is resolved in the outer block; consider: [x for x in x].\n\t\tclause := e.Clauses[0].(*syntax.ForClause)\n\t\tr.expr(clause.X)\n\n\t\t// A list/dict comprehension defines a new lexical block.\n\t\t// Locals defined within the block will be allotted\n\t\t// distinct slots in the locals array of the innermost\n\t\t// enclosing container (function/module) block.\n\t\tr.push(&block{comp: e})\n\n\t\tconst isAugmented = false\n\t\tr.assign(clause.Vars, isAugmented)\n\n\t\tfor _, clause := range e.Clauses[1:] {\n\t\t\tswitch clause := clause.(type) {\n\t\t\tcase *syntax.IfClause:\n\t\t\t\tr.expr(clause.Cond)\n\t\t\tcase *syntax.ForClause:\n\t\t\t\tr.assign(clause.Vars, isAugmented)\n\t\t\t\tr.expr(clause.X)\n\t\t\t}\n\t\t}\n\t\tr.expr(e.Body) // body may be *DictEntry\n\t\tr.pop()\n\n\tcase *syntax.TupleExpr:\n\t\tfor _, x := range e.List {\n\t\t\tr.expr(x)\n\t\t}\n\n\tcase *syntax.DictExpr:\n\t\tfor _, entry := range e.List {\n\t\t\tentry := entry.(*syntax.DictEntry)\n\t\t\tr.expr(entry.Key)\n\t\t\tr.expr(entry.Value)\n\t\t}\n\n\tcase *syntax.UnaryExpr:\n\t\tr.expr(e.X)\n\n\tcase *syntax.BinaryExpr:\n\t\tif !AllowFloat && e.Op == syntax.SLASH {\n\t\t\tr.errorf(e.OpPos, doesnt+\"support floating point (use //)\")\n\t\t}\n\t\tr.expr(e.X)\n\t\tr.expr(e.Y)\n\n\tcase *syntax.DotExpr:\n\t\tr.expr(e.X)\n\t\t// ignore e.Name\n\n\tcase *syntax.CallExpr:\n\t\tr.expr(e.Fn)\n\t\tvar seenVarargs, seenKwargs bool\n\t\tvar seenName map[string]bool\n\t\tvar n, p int\n\t\tfor _, arg := range e.Args {\n\t\t\tpos, _ := arg.Span()\n\t\t\tif unop, ok := arg.(*syntax.UnaryExpr); ok && unop.Op == syntax.STARSTAR {\n\t\t\t\t// **kwargs\n\t\t\t\tif seenKwargs {\n\t\t\t\t\tr.errorf(pos, \"multiple **kwargs not allowed\")\n\t\t\t\t}\n\t\t\t\tseenKwargs = true\n\t\t\t\tr.expr(arg)\n\t\t\t} else if ok && unop.Op == syntax.STAR {\n\t\t\t\t// *args\n\t\t\t\tif seenKwargs {\n\t\t\t\t\tr.errorf(pos, \"*args may not follow **kwargs\")\n\t\t\t\t} else if seenVarargs {\n\t\t\t\t\tr.errorf(pos, \"multiple *args not allowed\")\n\t\t\t\t}\n\t\t\t\tseenVarargs = true\n\t\t\t\tr.expr(arg)\n\t\t\t} else if binop, ok := arg.(*syntax.BinaryExpr); ok && binop.Op == syntax.EQ {\n\t\t\t\t// k=v\n\t\t\t\tn++\n\t\t\t\tif seenKwargs {\n\t\t\t\t\tr.errorf(pos, \"argument may not follow **kwargs\")\n\t\t\t\t}\n\t\t\t\tx := binop.X.(*syntax.Ident)\n\t\t\t\tif seenName[x.Name] {\n\t\t\t\t\tr.errorf(x.NamePos, \"keyword argument %s repeated\", x.Name)\n\t\t\t\t} else {\n\t\t\t\t\tif seenName == nil {\n\t\t\t\t\t\tseenName = make(map[string]bool)\n\t\t\t\t\t}\n\t\t\t\t\tseenName[x.Name] = true\n\t\t\t\t}\n\t\t\t\tr.expr(binop.Y)\n\t\t\t} else {\n\t\t\t\t// positional argument\n\t\t\t\tp++\n\t\t\t\tif seenVarargs {\n\t\t\t\t\tr.errorf(pos, \"argument may not follow *args\")\n\t\t\t\t} else if seenKwargs {\n\t\t\t\t\tr.errorf(pos, \"argument may not follow **kwargs\")\n\t\t\t\t} else if len(seenName) > 0 {\n\t\t\t\t\tr.errorf(pos, \"positional argument may not follow named\")\n\t\t\t\t}\n\t\t\t\tr.expr(arg)\n\t\t\t}\n\t\t}\n\n\t\t// Fail gracefully if compiler-imposed limit is exceeded.\n\t\tif p >= 256 {\n\t\t\tpos, _ := e.Span()\n\t\t\tr.errorf(pos, \"%v positional arguments in call, limit is 255\", p)\n\t\t}\n\t\tif n >= 256 {\n\t\t\tpos, _ := e.Span()\n\t\t\tr.errorf(pos, \"%v keyword arguments in call, limit is 255\", n)\n\t\t}\n\n\tcase *syntax.LambdaExpr:\n\t\tif !AllowLambda {\n\t\t\tr.errorf(e.Lambda, doesnt+\"support lambda\")\n\t\t}\n\t\tfn := &Function{\n\t\t\tName:   \"lambda\",\n\t\t\tPos:    e.Lambda,\n\t\t\tParams: e.Params,\n\t\t\tBody:   []syntax.Stmt{&syntax.ReturnStmt{Result: e.Body}},\n\t\t}\n\t\te.Function = fn\n\t\tr.function(fn, e.Lambda)\n\n\tcase *syntax.ParenExpr:\n\t\tr.expr(e.X)\n\n\tdefault:\n\t\tlog.Panicf(\"unexpected expr %T\", e)\n\t}\n}\n\nfunc (r *resolver) function(function *Function, pos syntax.Position) {\n\t// Resolve defaults in enclosing environment.\n\tfor _, param := range function.Params {\n\t\tif binary, ok := param.(*syntax.BinaryExpr); ok {\n\t\t\tr.expr(binary.Y)\n\t\t}\n\t}\n\n\t// Enter function block.\n\tb := &block{function: function}\n\tr.push(b)\n\n\tvar seenOptional bool\n\tvar star *syntax.UnaryExpr // * or *args param\n\tvar starStar *syntax.Ident // **kwargs ident\n\tvar numKwonlyParams int\n\tfor _, param := range function.Params {\n\t\tswitch param := param.(type) {\n\t\tcase *syntax.Ident:\n\t\t\t// e.g. x\n\t\t\tif starStar != nil {\n\t\t\t\tr.errorf(param.NamePos, \"required parameter may not follow **%s\", starStar.Name)\n\t\t\t} else if star != nil {\n\t\t\t\tnumKwonlyParams++\n\t\t\t} else if seenOptional {\n\t\t\t\tr.errorf(param.NamePos, \"required parameter may not follow optional\")\n\t\t\t}\n\t\t\tif r.bind(param) {\n\t\t\t\tr.errorf(param.NamePos, \"duplicate parameter: %s\", param.Name)\n\t\t\t}\n\n\t\tcase *syntax.BinaryExpr:\n\t\t\t// e.g. y=dflt\n\t\t\tif starStar != nil {\n\t\t\t\tr.errorf(param.OpPos, \"optional parameter may not follow **%s\", starStar.Name)\n\t\t\t} else if star != nil {\n\t\t\t\tnumKwonlyParams++\n\t\t\t}\n\t\t\tif id := param.X.(*syntax.Ident); r.bind(id) {\n\t\t\t\tr.errorf(param.OpPos, \"duplicate parameter: %s\", id.Name)\n\t\t\t}\n\t\t\tseenOptional = true\n\n\t\tcase *syntax.UnaryExpr:\n\t\t\t// * or *args or **kwargs\n\t\t\tif param.Op == syntax.STAR {\n\t\t\t\tif starStar != nil {\n\t\t\t\t\tr.errorf(param.OpPos, \"* parameter may not follow **%s\", starStar.Name)\n\t\t\t\t} else if star != nil {\n\t\t\t\t\tr.errorf(param.OpPos, \"multiple * parameters not allowed\")\n\t\t\t\t} else {\n\t\t\t\t\tstar = param\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif starStar != nil {\n\t\t\t\t\tr.errorf(param.OpPos, \"multiple ** parameters not allowed\")\n\t\t\t\t}\n\t\t\t\tstarStar = param.X.(*syntax.Ident)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Bind the *args and **kwargs parameters at the end,\n\t// so that regular parameters a/b/c are contiguous and\n\t// there is no hole for the \"*\":\n\t//   def f(a, b, *args, c=0, **kwargs)\n\t//   def f(a, b, *,     c=0, **kwargs)\n\tif star != nil {\n\t\tif id, _ := star.X.(*syntax.Ident); id != nil {\n\t\t\t// *args\n\t\t\tif r.bind(id) {\n\t\t\t\tr.errorf(id.NamePos, \"duplicate parameter: %s\", id.Name)\n\t\t\t}\n\t\t\tfunction.HasVarargs = true\n\t\t} else if numKwonlyParams == 0 {\n\t\t\tr.errorf(star.OpPos, \"bare * must be followed by keyword-only parameters\")\n\t\t}\n\t}\n\tif starStar != nil {\n\t\tif r.bind(starStar) {\n\t\t\tr.errorf(starStar.NamePos, \"duplicate parameter: %s\", starStar.Name)\n\t\t}\n\t\tfunction.HasKwargs = true\n\t}\n\n\tfunction.NumKwonlyParams = numKwonlyParams\n\tr.stmts(function.Body)\n\n\t// Resolve all uses of this function's local vars,\n\t// and keep just the remaining uses of free/global vars.\n\tb.resolveLocalUses()\n\n\t// Leave function block.\n\tr.pop()\n\n\t// References within the function body to globals are not\n\t// resolved until the end of the module.\n}\n\nfunc (r *resolver) resolveNonLocalUses(b *block) {\n\t// First resolve inner blocks.\n\tfor _, child := range b.children {\n\t\tr.resolveNonLocalUses(child)\n\t}\n\tfor _, use := range b.uses {\n\t\tuse.id.Binding = r.lookupLexical(use, use.env)\n\t}\n}\n\n// lookupLocal looks up an identifier within its immediately enclosing function.\nfunc lookupLocal(use use) *Binding {\n\tfor env := use.env; env != nil; env = env.parent {\n\t\tif bind, ok := env.bindings[use.id.Name]; ok {\n\t\t\tif bind.Scope == Free {\n\t\t\t\t// shouldn't exist till later\n\t\t\t\tlog.Panicf(\"%s: internal error: %s, %v\", use.id.NamePos, use.id.Name, bind)\n\t\t\t}\n\t\t\treturn bind // found\n\t\t}\n\t\tif env.function != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn nil // not found in this function\n}\n\n// lookupLexical looks up an identifier use.id within its lexically enclosing environment.\n// The use.env field captures the original environment for error reporting.\nfunc (r *resolver) lookupLexical(use use, env *block) (bind *Binding) {\n\tif debug {\n\t\tfmt.Printf(\"lookupLexical %s in %s = ...\\n\", use.id.Name, env)\n\t\tdefer func() { fmt.Printf(\"= %v\\n\", bind) }()\n\t}\n\n\t// Is this the file block?\n\tif env == r.file {\n\t\treturn r.useToplevel(use) // file-local, global, predeclared, or not found\n\t}\n\n\t// Defined in this block?\n\tbind, ok := env.bindings[use.id.Name]\n\tif !ok {\n\t\t// Defined in parent block?\n\t\tbind = r.lookupLexical(use, env.parent)\n\t\tif env.function != nil && (bind.Scope == Local || bind.Scope == Free || bind.Scope == Cell) {\n\t\t\t// Found in parent block, which belongs to enclosing function.\n\t\t\t// Add the parent's binding to the function's freevars,\n\t\t\t// and add a new 'free' binding to the inner function's block,\n\t\t\t// and turn the parent's local into cell.\n\t\t\tif bind.Scope == Local {\n\t\t\t\tbind.Scope = Cell\n\t\t\t}\n\t\t\tindex := len(env.function.FreeVars)\n\t\t\tenv.function.FreeVars = append(env.function.FreeVars, bind)\n\t\t\tbind = &Binding{\n\t\t\t\tFirst: bind.First,\n\t\t\t\tScope: Free,\n\t\t\t\tIndex: index,\n\t\t\t}\n\t\t\tif debug {\n\t\t\t\tfmt.Printf(\"creating freevar %v in function at %s: %s\\n\",\n\t\t\t\t\tlen(env.function.FreeVars), env.function.Pos, use.id.Name)\n\t\t\t}\n\t\t}\n\n\t\t// Memoize, to avoid duplicate free vars\n\t\t// and redundant global (failing) lookups.\n\t\tenv.bind(use.id.Name, bind)\n\t}\n\treturn bind\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/debug.go",
    "content": "package starlark\n\nimport \"go.starlark.net/syntax\"\n\n// This file defines an experimental API for the debugging tools.\n// Some of these declarations expose details of internal packages.\n// (The debugger makes liberal use of exported fields of unexported types.)\n// Breaking changes may occur without notice.\n\n// Local returns the value of the i'th local variable.\n// It may be nil if not yet assigned.\n//\n// Local may be called only for frames whose Callable is a *Function (a\n// function defined by Starlark source code), and only while the frame\n// is active; it will panic otherwise.\n//\n// This function is provided only for debugging tools.\n//\n// THIS API IS EXPERIMENTAL AND MAY CHANGE WITHOUT NOTICE.\nfunc (fr *frame) Local(i int) Value { return fr.locals[i] }\n\n// DebugFrame is the debugger API for a frame of the interpreter's call stack.\n//\n// Most applications have no need for this API; use CallFrame instead.\n//\n// Clients must not retain a DebugFrame nor call any of its methods once\n// the current built-in call has returned or execution has resumed\n// after a breakpoint as this may have unpredictable effects, including\n// but not limited to retention of object that would otherwise be garbage.\ntype DebugFrame interface {\n\tCallable() Callable        // returns the frame's function\n\tLocal(i int) Value         // returns the value of the (Starlark) frame's ith local variable\n\tPosition() syntax.Position // returns the current position of execution in this frame\n}\n\n// DebugFrame returns the debugger interface for\n// the specified frame of the interpreter's call stack.\n// Frame numbering is as for Thread.CallFrame.\n//\n// This function is intended for use in debugging tools.\n// Most applications should have no need for it; use CallFrame instead.\nfunc (thread *Thread) DebugFrame(depth int) DebugFrame { return thread.frameAt(depth) }\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/empty.s",
    "content": "// The presence of this file allows the package to use the\n// \"go:linkname\" hack to call non-exported functions in the\n// Go runtime, such as hardware-accelerated string hashing.\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/eval.go",
    "content": "// Copyright 2017 The Bazel 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 starlark\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"math\"\n\t\"math/big\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n\n\t\"go.starlark.net/internal/compile\"\n\t\"go.starlark.net/internal/spell\"\n\t\"go.starlark.net/resolve\"\n\t\"go.starlark.net/syntax\"\n)\n\n// A Thread contains the state of a Starlark thread,\n// such as its call stack and thread-local storage.\n// The Thread is threaded throughout the evaluator.\ntype Thread struct {\n\t// Name is an optional name that describes the thread, for debugging.\n\tName string\n\n\t// stack is the stack of (internal) call frames.\n\tstack []*frame\n\n\t// Print is the client-supplied implementation of the Starlark\n\t// 'print' function. If nil, fmt.Fprintln(os.Stderr, msg) is\n\t// used instead.\n\tPrint func(thread *Thread, msg string)\n\n\t// Load is the client-supplied implementation of module loading.\n\t// Repeated calls with the same module name must return the same\n\t// module environment or error.\n\t// The error message need not include the module name.\n\t//\n\t// See example_test.go for some example implementations of Load.\n\tLoad func(thread *Thread, module string) (StringDict, error)\n\n\t// locals holds arbitrary \"thread-local\" Go values belonging to the client.\n\t// They are accessible to the client but not to any Starlark program.\n\tlocals map[string]interface{}\n\n\t// proftime holds the accumulated execution time since the last profile event.\n\tproftime time.Duration\n}\n\n// SetLocal sets the thread-local value associated with the specified key.\n// It must not be called after execution begins.\nfunc (thread *Thread) SetLocal(key string, value interface{}) {\n\tif thread.locals == nil {\n\t\tthread.locals = make(map[string]interface{})\n\t}\n\tthread.locals[key] = value\n}\n\n// Local returns the thread-local value associated with the specified key.\nfunc (thread *Thread) Local(key string) interface{} {\n\treturn thread.locals[key]\n}\n\n// CallFrame returns a copy of the specified frame of the callstack.\n// It should only be used in built-ins called from Starlark code.\n// Depth 0 means the frame of the built-in itself, 1 is its caller, and so on.\n//\n// It is equivalent to CallStack().At(depth), but more efficient.\nfunc (thread *Thread) CallFrame(depth int) CallFrame {\n\treturn thread.frameAt(depth).asCallFrame()\n}\n\nfunc (thread *Thread) frameAt(depth int) *frame {\n\treturn thread.stack[len(thread.stack)-1-depth]\n}\n\n// CallStack returns a new slice containing the thread's stack of call frames.\nfunc (thread *Thread) CallStack() CallStack {\n\tframes := make([]CallFrame, len(thread.stack))\n\tfor i, fr := range thread.stack {\n\t\tframes[i] = fr.asCallFrame()\n\t}\n\treturn frames\n}\n\n// CallStackDepth returns the number of frames in the current call stack.\nfunc (thread *Thread) CallStackDepth() int { return len(thread.stack) }\n\n// A StringDict is a mapping from names to values, and represents\n// an environment such as the global variables of a module.\n// It is not a true starlark.Value.\ntype StringDict map[string]Value\n\n// Keys returns a new sorted slice of d's keys.\nfunc (d StringDict) Keys() []string {\n\tnames := make([]string, 0, len(d))\n\tfor name := range d {\n\t\tnames = append(names, name)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\nfunc (d StringDict) String() string {\n\tbuf := new(strings.Builder)\n\tbuf.WriteByte('{')\n\tsep := \"\"\n\tfor _, name := range d.Keys() {\n\t\tbuf.WriteString(sep)\n\t\tbuf.WriteString(name)\n\t\tbuf.WriteString(\": \")\n\t\twriteValue(buf, d[name], nil)\n\t\tsep = \", \"\n\t}\n\tbuf.WriteByte('}')\n\treturn buf.String()\n}\n\nfunc (d StringDict) Freeze() {\n\tfor _, v := range d {\n\t\tv.Freeze()\n\t}\n}\n\n// Has reports whether the dictionary contains the specified key.\nfunc (d StringDict) Has(key string) bool { _, ok := d[key]; return ok }\n\n// A frame records a call to a Starlark function (including module toplevel)\n// or a built-in function or method.\ntype frame struct {\n\tcallable  Callable // current function (or toplevel) or built-in\n\tpc        uint32   // program counter (Starlark frames only)\n\tlocals    []Value  // local variables (Starlark frames only)\n\tspanStart int64    // start time of current profiler span\n}\n\n// Position returns the source position of the current point of execution in this frame.\nfunc (fr *frame) Position() syntax.Position {\n\tswitch c := fr.callable.(type) {\n\tcase *Function:\n\t\t// Starlark function\n\t\treturn c.funcode.Position(fr.pc)\n\tcase callableWithPosition:\n\t\t// If a built-in Callable defines\n\t\t// a Position method, use it.\n\t\treturn c.Position()\n\t}\n\treturn syntax.MakePosition(&builtinFilename, 0, 0)\n}\n\nvar builtinFilename = \"<builtin>\"\n\n// Function returns the frame's function or built-in.\nfunc (fr *frame) Callable() Callable { return fr.callable }\n\n// A CallStack is a stack of call frames, outermost first.\ntype CallStack []CallFrame\n\n// At returns a copy of the frame at depth i.\n// At(0) returns the topmost frame.\nfunc (stack CallStack) At(i int) CallFrame { return stack[len(stack)-1-i] }\n\n// Pop removes and returns the topmost frame.\nfunc (stack *CallStack) Pop() CallFrame {\n\tlast := len(*stack) - 1\n\ttop := (*stack)[last]\n\t*stack = (*stack)[:last]\n\treturn top\n}\n\n// String returns a user-friendly description of the stack.\nfunc (stack CallStack) String() string {\n\tout := new(strings.Builder)\n\tfmt.Fprintf(out, \"Traceback (most recent call last):\\n\")\n\tfor _, fr := range stack {\n\t\tfmt.Fprintf(out, \"  %s: in %s\\n\", fr.Pos, fr.Name)\n\t}\n\treturn out.String()\n}\n\n// An EvalError is a Starlark evaluation error and\n// a copy of the thread's stack at the moment of the error.\ntype EvalError struct {\n\tMsg       string\n\tCallStack CallStack\n\tcause     error\n}\n\n// A CallFrame represents the function name and current\n// position of execution of an enclosing call frame.\ntype CallFrame struct {\n\tName string\n\tPos  syntax.Position\n}\n\nfunc (fr *frame) asCallFrame() CallFrame {\n\treturn CallFrame{\n\t\tName: fr.Callable().Name(),\n\t\tPos:  fr.Position(),\n\t}\n}\n\nfunc (thread *Thread) evalError(err error) *EvalError {\n\treturn &EvalError{\n\t\tMsg:       err.Error(),\n\t\tCallStack: thread.CallStack(),\n\t\tcause:     err,\n\t}\n}\n\nfunc (e *EvalError) Error() string { return e.Msg }\n\n// Backtrace returns a user-friendly error message describing the stack\n// of calls that led to this error.\nfunc (e *EvalError) Backtrace() string {\n\treturn fmt.Sprintf(\"%sError: %s\", e.CallStack, e.Msg)\n}\n\nfunc (e *EvalError) Unwrap() error { return e.cause }\n\n// A Program is a compiled Starlark program.\n//\n// Programs are immutable, and contain no Values.\n// A Program may be created by parsing a source file (see SourceProgram)\n// or by loading a previously saved compiled program (see CompiledProgram).\ntype Program struct {\n\tcompiled *compile.Program\n}\n\n// CompilerVersion is the version number of the protocol for compiled\n// files. Applications must not run programs compiled by one version\n// with an interpreter at another version, and should thus incorporate\n// the compiler version into the cache key when reusing compiled code.\nconst CompilerVersion = compile.Version\n\n// Filename returns the name of the file from which this program was loaded.\nfunc (prog *Program) Filename() string { return prog.compiled.Toplevel.Pos.Filename() }\n\nfunc (prog *Program) String() string { return prog.Filename() }\n\n// NumLoads returns the number of load statements in the compiled program.\nfunc (prog *Program) NumLoads() int { return len(prog.compiled.Loads) }\n\n// Load(i) returns the name and position of the i'th module directly\n// loaded by this one, where 0 <= i < NumLoads().\n// The name is unresolved---exactly as it appears in the source.\nfunc (prog *Program) Load(i int) (string, syntax.Position) {\n\tid := prog.compiled.Loads[i]\n\treturn id.Name, id.Pos\n}\n\n// WriteTo writes the compiled module to the specified output stream.\nfunc (prog *Program) Write(out io.Writer) error {\n\tdata := prog.compiled.Encode()\n\t_, err := out.Write(data)\n\treturn err\n}\n\n// ExecFile parses, resolves, and executes a Starlark file in the\n// specified global environment, which may be modified during execution.\n//\n// Thread is the state associated with the Starlark thread.\n//\n// The filename and src parameters are as for syntax.Parse:\n// filename is the name of the file to execute,\n// and the name that appears in error messages;\n// src is an optional source of bytes to use\n// instead of filename.\n//\n// predeclared defines the predeclared names specific to this module.\n// Execution does not modify this dictionary, though it may mutate\n// its values.\n//\n// If ExecFile fails during evaluation, it returns an *EvalError\n// containing a backtrace.\nfunc ExecFile(thread *Thread, filename string, src interface{}, predeclared StringDict) (StringDict, error) {\n\t// Parse, resolve, and compile a Starlark source file.\n\t_, mod, err := SourceProgram(filename, src, predeclared.Has)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tg, err := mod.Init(thread, predeclared)\n\tg.Freeze()\n\treturn g, err\n}\n\n// SourceProgram produces a new program by parsing, resolving,\n// and compiling a Starlark source file.\n// On success, it returns the parsed file and the compiled program.\n// The filename and src parameters are as for syntax.Parse.\n//\n// The isPredeclared predicate reports whether a name is\n// a pre-declared identifier of the current module.\n// Its typical value is predeclared.Has,\n// where predeclared is a StringDict of pre-declared values.\nfunc SourceProgram(filename string, src interface{}, isPredeclared func(string) bool) (*syntax.File, *Program, error) {\n\tf, err := syntax.Parse(filename, src, 0)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tprog, err := FileProgram(f, isPredeclared)\n\treturn f, prog, err\n}\n\n// FileProgram produces a new program by resolving,\n// and compiling the Starlark source file syntax tree.\n// On success, it returns the compiled program.\n//\n// Resolving a syntax tree mutates it.\n// Do not call FileProgram more than once on the same file.\n//\n// The isPredeclared predicate reports whether a name is\n// a pre-declared identifier of the current module.\n// Its typical value is predeclared.Has,\n// where predeclared is a StringDict of pre-declared values.\nfunc FileProgram(f *syntax.File, isPredeclared func(string) bool) (*Program, error) {\n\tif err := resolve.File(f, isPredeclared, Universe.Has); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar pos syntax.Position\n\tif len(f.Stmts) > 0 {\n\t\tpos = syntax.Start(f.Stmts[0])\n\t} else {\n\t\tpos = syntax.MakePosition(&f.Path, 1, 1)\n\t}\n\n\tmodule := f.Module.(*resolve.Module)\n\tcompiled := compile.File(f.Stmts, pos, \"<toplevel>\", module.Locals, module.Globals)\n\n\treturn &Program{compiled}, nil\n}\n\n// CompiledProgram produces a new program from the representation\n// of a compiled program previously saved by Program.Write.\nfunc CompiledProgram(in io.Reader) (*Program, error) {\n\tdata, err := ioutil.ReadAll(in)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcompiled, err := compile.DecodeProgram(data)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Program{compiled}, nil\n}\n\n// Init creates a set of global variables for the program,\n// executes the toplevel code of the specified program,\n// and returns a new, unfrozen dictionary of the globals.\nfunc (prog *Program) Init(thread *Thread, predeclared StringDict) (StringDict, error) {\n\ttoplevel := makeToplevelFunction(prog.compiled, predeclared)\n\n\t_, err := Call(thread, toplevel, nil, nil)\n\n\t// Convert the global environment to a map.\n\t// We return a (partial) map even in case of error.\n\treturn toplevel.Globals(), err\n}\n\n// ExecREPLChunk compiles and executes file f in the specified thread\n// and global environment. This is a variant of ExecFile specialized to\n// the needs of a REPL, in which a sequence of input chunks, each\n// syntactically a File, manipulates the same set of module globals,\n// which are not frozen after execution.\n//\n// This function is intended to support only go.starlark.net/repl.\n// Its API stability is not guaranteed.\nfunc ExecREPLChunk(f *syntax.File, thread *Thread, globals StringDict) error {\n\tvar predeclared StringDict\n\n\t// -- variant of FileProgram --\n\n\tif err := resolve.REPLChunk(f, globals.Has, predeclared.Has, Universe.Has); err != nil {\n\t\treturn err\n\t}\n\n\tvar pos syntax.Position\n\tif len(f.Stmts) > 0 {\n\t\tpos = syntax.Start(f.Stmts[0])\n\t} else {\n\t\tpos = syntax.MakePosition(&f.Path, 1, 1)\n\t}\n\n\tmodule := f.Module.(*resolve.Module)\n\tcompiled := compile.File(f.Stmts, pos, \"<toplevel>\", module.Locals, module.Globals)\n\tprog := &Program{compiled}\n\n\t// -- variant of Program.Init --\n\n\ttoplevel := makeToplevelFunction(prog.compiled, predeclared)\n\n\t// Initialize module globals from parameter.\n\tfor i, id := range prog.compiled.Globals {\n\t\tif v := globals[id.Name]; v != nil {\n\t\t\ttoplevel.module.globals[i] = v\n\t\t}\n\t}\n\n\t_, err := Call(thread, toplevel, nil, nil)\n\n\t// Reflect changes to globals back to parameter, even after an error.\n\tfor i, id := range prog.compiled.Globals {\n\t\tif v := toplevel.module.globals[i]; v != nil {\n\t\t\tglobals[id.Name] = v\n\t\t}\n\t}\n\n\treturn err\n}\n\nfunc makeToplevelFunction(prog *compile.Program, predeclared StringDict) *Function {\n\t// Create the Starlark value denoted by each program constant c.\n\tconstants := make([]Value, len(prog.Constants))\n\tfor i, c := range prog.Constants {\n\t\tvar v Value\n\t\tswitch c := c.(type) {\n\t\tcase int64:\n\t\t\tv = MakeInt64(c)\n\t\tcase *big.Int:\n\t\t\tv = MakeBigInt(c)\n\t\tcase string:\n\t\t\tv = String(c)\n\t\tcase float64:\n\t\t\tv = Float(c)\n\t\tdefault:\n\t\t\tlog.Panicf(\"unexpected constant %T: %v\", c, c)\n\t\t}\n\t\tconstants[i] = v\n\t}\n\n\treturn &Function{\n\t\tfuncode: prog.Toplevel,\n\t\tmodule: &module{\n\t\t\tprogram:     prog,\n\t\t\tpredeclared: predeclared,\n\t\t\tglobals:     make([]Value, len(prog.Globals)),\n\t\t\tconstants:   constants,\n\t\t},\n\t}\n}\n\n// Eval parses, resolves, and evaluates an expression within the\n// specified (predeclared) environment.\n//\n// Evaluation cannot mutate the environment dictionary itself,\n// though it may modify variables reachable from the dictionary.\n//\n// The filename and src parameters are as for syntax.Parse.\n//\n// If Eval fails during evaluation, it returns an *EvalError\n// containing a backtrace.\nfunc Eval(thread *Thread, filename string, src interface{}, env StringDict) (Value, error) {\n\texpr, err := syntax.ParseExpr(filename, src, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tf, err := makeExprFunc(expr, env)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn Call(thread, f, nil, nil)\n}\n\n// EvalExpr resolves and evaluates an expression within the\n// specified (predeclared) environment.\n// Evaluating a comma-separated list of expressions yields a tuple value.\n//\n// Resolving an expression mutates it.\n// Do not call EvalExpr more than once for the same expression.\n//\n// Evaluation cannot mutate the environment dictionary itself,\n// though it may modify variables reachable from the dictionary.\n//\n// If Eval fails during evaluation, it returns an *EvalError\n// containing a backtrace.\nfunc EvalExpr(thread *Thread, expr syntax.Expr, env StringDict) (Value, error) {\n\tfn, err := makeExprFunc(expr, env)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn Call(thread, fn, nil, nil)\n}\n\n// ExprFunc returns a no-argument function\n// that evaluates the expression whose source is src.\nfunc ExprFunc(filename string, src interface{}, env StringDict) (*Function, error) {\n\texpr, err := syntax.ParseExpr(filename, src, 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn makeExprFunc(expr, env)\n}\n\n// makeExprFunc returns a no-argument function whose body is expr.\nfunc makeExprFunc(expr syntax.Expr, env StringDict) (*Function, error) {\n\tlocals, err := resolve.Expr(expr, env.Has, Universe.Has)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn makeToplevelFunction(compile.Expr(expr, \"<expr>\", locals), env), nil\n}\n\n// The following functions are primitive operations of the byte code interpreter.\n\n// list += iterable\nfunc listExtend(x *List, y Iterable) {\n\tif ylist, ok := y.(*List); ok {\n\t\t// fast path: list += list\n\t\tx.elems = append(x.elems, ylist.elems...)\n\t} else {\n\t\titer := y.Iterate()\n\t\tdefer iter.Done()\n\t\tvar z Value\n\t\tfor iter.Next(&z) {\n\t\t\tx.elems = append(x.elems, z)\n\t\t}\n\t}\n}\n\n// getAttr implements x.dot.\nfunc getAttr(x Value, name string) (Value, error) {\n\thasAttr, ok := x.(HasAttrs)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"%s has no .%s field or method\", x.Type(), name)\n\t}\n\n\tvar errmsg string\n\tv, err := hasAttr.Attr(name)\n\tif err == nil {\n\t\tif v != nil {\n\t\t\treturn v, nil // success\n\t\t}\n\t\t// (nil, nil) => generic error\n\t\terrmsg = fmt.Sprintf(\"%s has no .%s field or method\", x.Type(), name)\n\t} else if nsa, ok := err.(NoSuchAttrError); ok {\n\t\terrmsg = string(nsa)\n\t} else {\n\t\treturn nil, err // return error as is\n\t}\n\n\t// add spelling hint\n\tif n := spell.Nearest(name, hasAttr.AttrNames()); n != \"\" {\n\t\terrmsg = fmt.Sprintf(\"%s (did you mean .%s?)\", errmsg, n)\n\t}\n\n\treturn nil, fmt.Errorf(\"%s\", errmsg)\n}\n\n// setField implements x.name = y.\nfunc setField(x Value, name string, y Value) error {\n\tif x, ok := x.(HasSetField); ok {\n\t\terr := x.SetField(name, y)\n\t\tif _, ok := err.(NoSuchAttrError); ok {\n\t\t\t// No such field: check spelling.\n\t\t\tif n := spell.Nearest(name, x.AttrNames()); n != \"\" {\n\t\t\t\terr = fmt.Errorf(\"%s (did you mean .%s?)\", err, n)\n\t\t\t}\n\t\t}\n\t\treturn err\n\t}\n\n\treturn fmt.Errorf(\"can't assign to .%s field of %s\", name, x.Type())\n}\n\n// getIndex implements x[y].\nfunc getIndex(x, y Value) (Value, error) {\n\tswitch x := x.(type) {\n\tcase Mapping: // dict\n\t\tz, found, err := x.Get(y)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !found {\n\t\t\treturn nil, fmt.Errorf(\"key %v not in %s\", y, x.Type())\n\t\t}\n\t\treturn z, nil\n\n\tcase Indexable: // string, list, tuple\n\t\tn := x.Len()\n\t\ti, err := AsInt32(y)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"%s index: %s\", x.Type(), err)\n\t\t}\n\t\torigI := i\n\t\tif i < 0 {\n\t\t\ti += n\n\t\t}\n\t\tif i < 0 || i >= n {\n\t\t\treturn nil, outOfRange(origI, n, x)\n\t\t}\n\t\treturn x.Index(i), nil\n\t}\n\treturn nil, fmt.Errorf(\"unhandled index operation %s[%s]\", x.Type(), y.Type())\n}\n\nfunc outOfRange(i, n int, x Value) error {\n\tif n == 0 {\n\t\treturn fmt.Errorf(\"index %d out of range: empty %s\", i, x.Type())\n\t} else {\n\t\treturn fmt.Errorf(\"%s index %d out of range [%d:%d]\", x.Type(), i, -n, n-1)\n\t}\n}\n\n// setIndex implements x[y] = z.\nfunc setIndex(x, y, z Value) error {\n\tswitch x := x.(type) {\n\tcase HasSetKey:\n\t\tif err := x.SetKey(y, z); err != nil {\n\t\t\treturn err\n\t\t}\n\n\tcase HasSetIndex:\n\t\tn := x.Len()\n\t\ti, err := AsInt32(y)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\torigI := i\n\t\tif i < 0 {\n\t\t\ti += n\n\t\t}\n\t\tif i < 0 || i >= n {\n\t\t\treturn outOfRange(origI, n, x)\n\t\t}\n\t\treturn x.SetIndex(i, z)\n\n\tdefault:\n\t\treturn fmt.Errorf(\"%s value does not support item assignment\", x.Type())\n\t}\n\treturn nil\n}\n\n// Unary applies a unary operator (+, -, ~, not) to its operand.\nfunc Unary(op syntax.Token, x Value) (Value, error) {\n\t// The NOT operator is not customizable.\n\tif op == syntax.NOT {\n\t\treturn !x.Truth(), nil\n\t}\n\n\t// Int, Float, and user-defined types\n\tif x, ok := x.(HasUnary); ok {\n\t\t// (nil, nil) => unhandled\n\t\ty, err := x.Unary(op)\n\t\tif y != nil || err != nil {\n\t\t\treturn y, err\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"unknown unary op: %s %s\", op, x.Type())\n}\n\n// Binary applies a strict binary operator (not AND or OR) to its operands.\n// For equality tests or ordered comparisons, use Compare instead.\nfunc Binary(op syntax.Token, x, y Value) (Value, error) {\n\tswitch op {\n\tcase syntax.PLUS:\n\t\tswitch x := x.(type) {\n\t\tcase String:\n\t\t\tif y, ok := y.(String); ok {\n\t\t\t\treturn x + y, nil\n\t\t\t}\n\t\tcase Int:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Int:\n\t\t\t\treturn x.Add(y), nil\n\t\t\tcase Float:\n\t\t\t\treturn x.Float() + y, nil\n\t\t\t}\n\t\tcase Float:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Float:\n\t\t\t\treturn x + y, nil\n\t\t\tcase Int:\n\t\t\t\treturn x + y.Float(), nil\n\t\t\t}\n\t\tcase *List:\n\t\t\tif y, ok := y.(*List); ok {\n\t\t\t\tz := make([]Value, 0, x.Len()+y.Len())\n\t\t\t\tz = append(z, x.elems...)\n\t\t\t\tz = append(z, y.elems...)\n\t\t\t\treturn NewList(z), nil\n\t\t\t}\n\t\tcase Tuple:\n\t\t\tif y, ok := y.(Tuple); ok {\n\t\t\t\tz := make(Tuple, 0, len(x)+len(y))\n\t\t\t\tz = append(z, x...)\n\t\t\t\tz = append(z, y...)\n\t\t\t\treturn z, nil\n\t\t\t}\n\t\t}\n\n\tcase syntax.MINUS:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Int:\n\t\t\t\treturn x.Sub(y), nil\n\t\t\tcase Float:\n\t\t\t\treturn x.Float() - y, nil\n\t\t\t}\n\t\tcase Float:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Float:\n\t\t\t\treturn x - y, nil\n\t\t\tcase Int:\n\t\t\t\treturn x - y.Float(), nil\n\t\t\t}\n\t\t}\n\n\tcase syntax.STAR:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Int:\n\t\t\t\treturn x.Mul(y), nil\n\t\t\tcase Float:\n\t\t\t\treturn x.Float() * y, nil\n\t\t\tcase String:\n\t\t\t\treturn stringRepeat(y, x)\n\t\t\tcase *List:\n\t\t\t\telems, err := tupleRepeat(Tuple(y.elems), x)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn NewList(elems), nil\n\t\t\tcase Tuple:\n\t\t\t\treturn tupleRepeat(y, x)\n\t\t\t}\n\t\tcase Float:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Float:\n\t\t\t\treturn x * y, nil\n\t\t\tcase Int:\n\t\t\t\treturn x * y.Float(), nil\n\t\t\t}\n\t\tcase String:\n\t\t\tif y, ok := y.(Int); ok {\n\t\t\t\treturn stringRepeat(x, y)\n\t\t\t}\n\t\tcase *List:\n\t\t\tif y, ok := y.(Int); ok {\n\t\t\t\telems, err := tupleRepeat(Tuple(x.elems), y)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn NewList(elems), nil\n\t\t\t}\n\t\tcase Tuple:\n\t\t\tif y, ok := y.(Int); ok {\n\t\t\t\treturn tupleRepeat(x, y)\n\t\t\t}\n\n\t\t}\n\n\tcase syntax.SLASH:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Int:\n\t\t\t\tyf := y.Float()\n\t\t\t\tif yf == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"real division by zero\")\n\t\t\t\t}\n\t\t\t\treturn x.Float() / yf, nil\n\t\t\tcase Float:\n\t\t\t\tif y == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"real division by zero\")\n\t\t\t\t}\n\t\t\t\treturn x.Float() / y, nil\n\t\t\t}\n\t\tcase Float:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Float:\n\t\t\t\tif y == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"real division by zero\")\n\t\t\t\t}\n\t\t\t\treturn x / y, nil\n\t\t\tcase Int:\n\t\t\t\tyf := y.Float()\n\t\t\t\tif yf == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"real division by zero\")\n\t\t\t\t}\n\t\t\t\treturn x / yf, nil\n\t\t\t}\n\t\t}\n\n\tcase syntax.SLASHSLASH:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Int:\n\t\t\t\tif y.Sign() == 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"floored division by zero\")\n\t\t\t\t}\n\t\t\t\treturn x.Div(y), nil\n\t\t\tcase Float:\n\t\t\t\tif y == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"floored division by zero\")\n\t\t\t\t}\n\t\t\t\treturn floor((x.Float() / y)), nil\n\t\t\t}\n\t\tcase Float:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Float:\n\t\t\t\tif y == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"floored division by zero\")\n\t\t\t\t}\n\t\t\t\treturn floor(x / y), nil\n\t\t\tcase Int:\n\t\t\t\tyf := y.Float()\n\t\t\t\tif yf == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"floored division by zero\")\n\t\t\t\t}\n\t\t\t\treturn floor(x / yf), nil\n\t\t\t}\n\t\t}\n\n\tcase syntax.PERCENT:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Int:\n\t\t\t\tif y.Sign() == 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"integer modulo by zero\")\n\t\t\t\t}\n\t\t\t\treturn x.Mod(y), nil\n\t\t\tcase Float:\n\t\t\t\tif y == 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"float modulo by zero\")\n\t\t\t\t}\n\t\t\t\treturn x.Float().Mod(y), nil\n\t\t\t}\n\t\tcase Float:\n\t\t\tswitch y := y.(type) {\n\t\t\tcase Float:\n\t\t\t\tif y == 0.0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"float modulo by zero\")\n\t\t\t\t}\n\t\t\t\treturn Float(math.Mod(float64(x), float64(y))), nil\n\t\t\tcase Int:\n\t\t\t\tif y.Sign() == 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"float modulo by zero\")\n\t\t\t\t}\n\t\t\t\treturn x.Mod(y.Float()), nil\n\t\t\t}\n\t\tcase String:\n\t\t\treturn interpolate(string(x), y)\n\t\t}\n\n\tcase syntax.NOT_IN:\n\t\tz, err := Binary(syntax.IN, x, y)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn !z.Truth(), nil\n\n\tcase syntax.IN:\n\t\tswitch y := y.(type) {\n\t\tcase *List:\n\t\t\tfor _, elem := range y.elems {\n\t\t\t\tif eq, err := Equal(elem, x); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t} else if eq {\n\t\t\t\t\treturn True, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn False, nil\n\t\tcase Tuple:\n\t\t\tfor _, elem := range y {\n\t\t\t\tif eq, err := Equal(elem, x); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t} else if eq {\n\t\t\t\t\treturn True, nil\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn False, nil\n\t\tcase Mapping: // e.g. dict\n\t\t\t// Ignore error from Get as we cannot distinguish true\n\t\t\t// errors (value cycle, type error) from \"key not found\".\n\t\t\t_, found, _ := y.Get(x)\n\t\t\treturn Bool(found), nil\n\t\tcase *Set:\n\t\t\tok, err := y.Has(x)\n\t\t\treturn Bool(ok), err\n\t\tcase String:\n\t\t\tneedle, ok := x.(String)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"'in <string>' requires string as left operand, not %s\", x.Type())\n\t\t\t}\n\t\t\treturn Bool(strings.Contains(string(y), string(needle))), nil\n\t\tcase rangeValue:\n\t\t\ti, err := NumberToInt(x)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"'in <range>' requires integer as left operand, not %s\", x.Type())\n\t\t\t}\n\t\t\treturn Bool(y.contains(i)), nil\n\t\t}\n\n\tcase syntax.PIPE:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tif y, ok := y.(Int); ok {\n\t\t\t\treturn x.Or(y), nil\n\t\t\t}\n\t\tcase *Set: // union\n\t\t\tif y, ok := y.(*Set); ok {\n\t\t\t\titer := Iterate(y)\n\t\t\t\tdefer iter.Done()\n\t\t\t\treturn x.Union(iter)\n\t\t\t}\n\t\t}\n\n\tcase syntax.AMP:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tif y, ok := y.(Int); ok {\n\t\t\t\treturn x.And(y), nil\n\t\t\t}\n\t\tcase *Set: // intersection\n\t\t\tif y, ok := y.(*Set); ok {\n\t\t\t\tset := new(Set)\n\t\t\t\tif x.Len() > y.Len() {\n\t\t\t\t\tx, y = y, x // opt: range over smaller set\n\t\t\t\t}\n\t\t\t\tfor _, xelem := range x.elems() {\n\t\t\t\t\t// Has, Insert cannot fail here.\n\t\t\t\t\tif found, _ := y.Has(xelem); found {\n\t\t\t\t\t\tset.Insert(xelem)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn set, nil\n\t\t\t}\n\t\t}\n\n\tcase syntax.CIRCUMFLEX:\n\t\tswitch x := x.(type) {\n\t\tcase Int:\n\t\t\tif y, ok := y.(Int); ok {\n\t\t\t\treturn x.Xor(y), nil\n\t\t\t}\n\t\tcase *Set: // symmetric difference\n\t\t\tif y, ok := y.(*Set); ok {\n\t\t\t\tset := new(Set)\n\t\t\t\tfor _, xelem := range x.elems() {\n\t\t\t\t\tif found, _ := y.Has(xelem); !found {\n\t\t\t\t\t\tset.Insert(xelem)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor _, yelem := range y.elems() {\n\t\t\t\t\tif found, _ := x.Has(yelem); !found {\n\t\t\t\t\t\tset.Insert(yelem)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn set, nil\n\t\t\t}\n\t\t}\n\n\tcase syntax.LTLT, syntax.GTGT:\n\t\tif x, ok := x.(Int); ok {\n\t\t\ty, err := AsInt32(y)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif y < 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"negative shift count: %v\", y)\n\t\t\t}\n\t\t\tif op == syntax.LTLT {\n\t\t\t\tif y >= 512 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"shift count too large: %v\", y)\n\t\t\t\t}\n\t\t\t\treturn x.Lsh(uint(y)), nil\n\t\t\t} else {\n\t\t\t\treturn x.Rsh(uint(y)), nil\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\t// unknown operator\n\t\tgoto unknown\n\t}\n\n\t// user-defined types\n\t// (nil, nil) => unhandled\n\tif x, ok := x.(HasBinary); ok {\n\t\tz, err := x.Binary(op, y, Left)\n\t\tif z != nil || err != nil {\n\t\t\treturn z, err\n\t\t}\n\t}\n\tif y, ok := y.(HasBinary); ok {\n\t\tz, err := y.Binary(op, x, Right)\n\t\tif z != nil || err != nil {\n\t\t\treturn z, err\n\t\t}\n\t}\n\n\t// unsupported operand types\nunknown:\n\treturn nil, fmt.Errorf(\"unknown binary op: %s %s %s\", x.Type(), op, y.Type())\n}\n\n// It's always possible to overeat in small bites but we'll\n// try to stop someone swallowing the world in one gulp.\nconst maxAlloc = 1 << 30\n\nfunc tupleRepeat(elems Tuple, n Int) (Tuple, error) {\n\tif len(elems) == 0 {\n\t\treturn nil, nil\n\t}\n\ti, err := AsInt32(n)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"repeat count %s too large\", n)\n\t}\n\tif i < 1 {\n\t\treturn nil, nil\n\t}\n\t// Inv: i > 0, len > 0\n\tsz := len(elems) * i\n\tif sz < 0 || sz >= maxAlloc { // sz < 0 => overflow\n\t\treturn nil, fmt.Errorf(\"excessive repeat (%d elements)\", sz)\n\t}\n\tres := make([]Value, sz)\n\t// copy elems into res, doubling each time\n\tx := copy(res, elems)\n\tfor x < len(res) {\n\t\tcopy(res[x:], res[:x])\n\t\tx *= 2\n\t}\n\treturn res, nil\n}\n\nfunc stringRepeat(s String, n Int) (String, error) {\n\tif s == \"\" {\n\t\treturn \"\", nil\n\t}\n\ti, err := AsInt32(n)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"repeat count %s too large\", n)\n\t}\n\tif i < 1 {\n\t\treturn \"\", nil\n\t}\n\t// Inv: i > 0, len > 0\n\tsz := len(s) * i\n\tif sz < 0 || sz >= maxAlloc { // sz < 0 => overflow\n\t\treturn \"\", fmt.Errorf(\"excessive repeat (%d elements)\", sz)\n\t}\n\treturn String(strings.Repeat(string(s), i)), nil\n}\n\n// Call calls the function fn with the specified positional and keyword arguments.\nfunc Call(thread *Thread, fn Value, args Tuple, kwargs []Tuple) (Value, error) {\n\tc, ok := fn.(Callable)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid call of non-function (%s)\", fn.Type())\n\t}\n\n\t// Allocate and push a new frame.\n\tvar fr *frame\n\t// Optimization: use slack portion of thread.stack\n\t// slice as a freelist of empty frames.\n\tif n := len(thread.stack); n < cap(thread.stack) {\n\t\tfr = thread.stack[n : n+1][0]\n\t}\n\tif fr == nil {\n\t\tfr = new(frame)\n\t}\n\tthread.stack = append(thread.stack, fr) // push\n\n\tfr.callable = c\n\n\tthread.beginProfSpan()\n\tresult, err := c.CallInternal(thread, args, kwargs)\n\tthread.endProfSpan()\n\n\t// Sanity check: nil is not a valid Starlark value.\n\tif result == nil && err == nil {\n\t\terr = fmt.Errorf(\"internal error: nil (not None) returned from %s\", fn)\n\t}\n\n\t// Always return an EvalError with an accurate frame.\n\tif err != nil {\n\t\tif _, ok := err.(*EvalError); !ok {\n\t\t\terr = thread.evalError(err)\n\t\t}\n\t}\n\n\t*fr = frame{}                                     // clear out any references\n\tthread.stack = thread.stack[:len(thread.stack)-1] // pop\n\n\treturn result, err\n}\n\nfunc slice(x, lo, hi, step_ Value) (Value, error) {\n\tsliceable, ok := x.(Sliceable)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"invalid slice operand %s\", x.Type())\n\t}\n\n\tn := sliceable.Len()\n\tstep := 1\n\tif step_ != None {\n\t\tvar err error\n\t\tstep, err = AsInt32(step_)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"got %s for slice step, want int\", step_.Type())\n\t\t}\n\t\tif step == 0 {\n\t\t\treturn nil, fmt.Errorf(\"zero is not a valid slice step\")\n\t\t}\n\t}\n\n\t// TODO(adonovan): opt: preallocate result array.\n\n\tvar start, end int\n\tif step > 0 {\n\t\t// positive stride\n\t\t// default indices are [0:n].\n\t\tvar err error\n\t\tstart, end, err = indices(lo, hi, n)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif end < start {\n\t\t\tend = start // => empty result\n\t\t}\n\t} else {\n\t\t// negative stride\n\t\t// default indices are effectively [n-1:-1], though to\n\t\t// get this effect using explicit indices requires\n\t\t// [n-1:-1-n:-1] because of the treatment of -ve values.\n\t\tstart = n - 1\n\t\tif err := asIndex(lo, n, &start); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid start index: %s\", err)\n\t\t}\n\t\tif start >= n {\n\t\t\tstart = n - 1\n\t\t}\n\n\t\tend = -1\n\t\tif err := asIndex(hi, n, &end); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid end index: %s\", err)\n\t\t}\n\t\tif end < -1 {\n\t\t\tend = -1\n\t\t}\n\n\t\tif start < end {\n\t\t\tstart = end // => empty result\n\t\t}\n\t}\n\n\treturn sliceable.Slice(start, end, step), nil\n}\n\n// From Hacker's Delight, section 2.8.\nfunc signum64(x int64) int { return int(uint64(x>>63) | uint64(-x)>>63) }\nfunc signum(x int) int     { return signum64(int64(x)) }\n\n// indices converts start_ and end_ to indices in the range [0:len].\n// The start index defaults to 0 and the end index defaults to len.\n// An index -len < i < 0 is treated like i+len.\n// All other indices outside the range are clamped to the nearest value in the range.\n// Beware: start may be greater than end.\n// This function is suitable only for slices with positive strides.\nfunc indices(start_, end_ Value, len int) (start, end int, err error) {\n\tstart = 0\n\tif err := asIndex(start_, len, &start); err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"invalid start index: %s\", err)\n\t}\n\t// Clamp to [0:len].\n\tif start < 0 {\n\t\tstart = 0\n\t} else if start > len {\n\t\tstart = len\n\t}\n\n\tend = len\n\tif err := asIndex(end_, len, &end); err != nil {\n\t\treturn 0, 0, fmt.Errorf(\"invalid end index: %s\", err)\n\t}\n\t// Clamp to [0:len].\n\tif end < 0 {\n\t\tend = 0\n\t} else if end > len {\n\t\tend = len\n\t}\n\n\treturn start, end, nil\n}\n\n// asIndex sets *result to the integer value of v, adding len to it\n// if it is negative.  If v is nil or None, *result is unchanged.\nfunc asIndex(v Value, len int, result *int) error {\n\tif v != nil && v != None {\n\t\tvar err error\n\t\t*result, err = AsInt32(v)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"got %s, want int\", v.Type())\n\t\t}\n\t\tif *result < 0 {\n\t\t\t*result += len\n\t\t}\n\t}\n\treturn nil\n}\n\n// setArgs sets the values of the formal parameters of function fn in\n// based on the actual parameter values in args and kwargs.\nfunc setArgs(locals []Value, fn *Function, args Tuple, kwargs []Tuple) error {\n\n\t// This is the general schema of a function:\n\t//\n\t//   def f(p1, p2=dp2, p3=dp3, *args, k1, k2=dk2, k3, **kwargs)\n\t//\n\t// The p parameters are non-kwonly, and may be specified positionally.\n\t// The k parameters are kwonly, and must be specified by name.\n\t// The defaults tuple is (dp2, dp3, mandatory, dk2, mandatory).\n\t//\n\t// Arguments are processed as follows:\n\t// - positional arguments are bound to a prefix of [p1, p2, p3].\n\t// - surplus positional arguments are bound to *args.\n\t// - keyword arguments are bound to any of {p1, p2, p3, k1, k2, k3};\n\t//   duplicate bindings are rejected.\n\t// - surplus keyword arguments are bound to **kwargs.\n\t// - defaults are bound to each parameter from p2 to k3 if no value was set.\n\t//   default values come from the tuple above.\n\t//   It is an error if the tuple entry for an unset parameter is 'mandatory'.\n\n\t// Nullary function?\n\tif fn.NumParams() == 0 {\n\t\tif nactual := len(args) + len(kwargs); nactual > 0 {\n\t\t\treturn fmt.Errorf(\"function %s accepts no arguments (%d given)\", fn.Name(), nactual)\n\t\t}\n\t\treturn nil\n\t}\n\n\tcond := func(x bool, y, z interface{}) interface{} {\n\t\tif x {\n\t\t\treturn y\n\t\t}\n\t\treturn z\n\t}\n\n\t// nparams is the number of ordinary parameters (sans *args and **kwargs).\n\tnparams := fn.NumParams()\n\tvar kwdict *Dict\n\tif fn.HasKwargs() {\n\t\tnparams--\n\t\tkwdict = new(Dict)\n\t\tlocals[nparams] = kwdict\n\t}\n\tif fn.HasVarargs() {\n\t\tnparams--\n\t}\n\n\t// nonkwonly is the number of non-kwonly parameters.\n\tnonkwonly := nparams - fn.NumKwonlyParams()\n\n\t// Too many positional args?\n\tn := len(args)\n\tif len(args) > nonkwonly {\n\t\tif !fn.HasVarargs() {\n\t\t\treturn fmt.Errorf(\"function %s accepts %s%d positional argument%s (%d given)\",\n\t\t\t\tfn.Name(),\n\t\t\t\tcond(len(fn.defaults) > fn.NumKwonlyParams(), \"at most \", \"\"),\n\t\t\t\tnonkwonly,\n\t\t\t\tcond(nonkwonly == 1, \"\", \"s\"),\n\t\t\t\tlen(args))\n\t\t}\n\t\tn = nonkwonly\n\t}\n\n\t// Bind positional arguments to non-kwonly parameters.\n\tfor i := 0; i < n; i++ {\n\t\tlocals[i] = args[i]\n\t}\n\n\t// Bind surplus positional arguments to *args parameter.\n\tif fn.HasVarargs() {\n\t\ttuple := make(Tuple, len(args)-n)\n\t\tfor i := n; i < len(args); i++ {\n\t\t\ttuple[i-n] = args[i]\n\t\t}\n\t\tlocals[nparams] = tuple\n\t}\n\n\t// Bind keyword arguments to parameters.\n\tparamIdents := fn.funcode.Locals[:nparams]\n\tfor _, pair := range kwargs {\n\t\tk, v := pair[0].(String), pair[1]\n\t\tif i := findParam(paramIdents, string(k)); i >= 0 {\n\t\t\tif locals[i] != nil {\n\t\t\t\treturn fmt.Errorf(\"function %s got multiple values for parameter %s\", fn.Name(), k)\n\t\t\t}\n\t\t\tlocals[i] = v\n\t\t\tcontinue\n\t\t}\n\t\tif kwdict == nil {\n\t\t\treturn fmt.Errorf(\"function %s got an unexpected keyword argument %s\", fn.Name(), k)\n\t\t}\n\t\toldlen := kwdict.Len()\n\t\tkwdict.SetKey(k, v)\n\t\tif kwdict.Len() == oldlen {\n\t\t\treturn fmt.Errorf(\"function %s got multiple values for parameter %s\", fn.Name(), k)\n\t\t}\n\t}\n\n\t// Are defaults required?\n\tif n < nparams || fn.NumKwonlyParams() > 0 {\n\t\tm := nparams - len(fn.defaults) // first default\n\n\t\t// Report errors for missing required arguments.\n\t\tvar missing []string\n\t\tvar i int\n\t\tfor i = n; i < m; i++ {\n\t\t\tif locals[i] == nil {\n\t\t\t\tmissing = append(missing, paramIdents[i].Name)\n\t\t\t}\n\t\t}\n\n\t\t// Bind default values to parameters.\n\t\tfor ; i < nparams; i++ {\n\t\t\tif locals[i] == nil {\n\t\t\t\tdflt := fn.defaults[i-m]\n\t\t\t\tif _, ok := dflt.(mandatory); ok {\n\t\t\t\t\tmissing = append(missing, paramIdents[i].Name)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tlocals[i] = dflt\n\t\t\t}\n\t\t}\n\n\t\tif missing != nil {\n\t\t\treturn fmt.Errorf(\"function %s missing %d argument%s (%s)\",\n\t\t\t\tfn.Name(), len(missing), cond(len(missing) > 1, \"s\", \"\"), strings.Join(missing, \", \"))\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc findParam(params []compile.Binding, name string) int {\n\tfor i, param := range params {\n\t\tif param.Name == name {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string-interpolation\nfunc interpolate(format string, x Value) (Value, error) {\n\tbuf := new(strings.Builder)\n\tindex := 0\n\tnargs := 1\n\tif tuple, ok := x.(Tuple); ok {\n\t\tnargs = len(tuple)\n\t}\n\tfor {\n\t\ti := strings.IndexByte(format, '%')\n\t\tif i < 0 {\n\t\t\tbuf.WriteString(format)\n\t\t\tbreak\n\t\t}\n\t\tbuf.WriteString(format[:i])\n\t\tformat = format[i+1:]\n\n\t\tif format != \"\" && format[0] == '%' {\n\t\t\tbuf.WriteByte('%')\n\t\t\tformat = format[1:]\n\t\t\tcontinue\n\t\t}\n\n\t\tvar arg Value\n\t\tif format != \"\" && format[0] == '(' {\n\t\t\t// keyword argument: %(name)s.\n\t\t\tformat = format[1:]\n\t\t\tj := strings.IndexByte(format, ')')\n\t\t\tif j < 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"incomplete format key\")\n\t\t\t}\n\t\t\tkey := format[:j]\n\t\t\tif dict, ok := x.(Mapping); !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"format requires a mapping\")\n\t\t\t} else if v, found, _ := dict.Get(String(key)); found {\n\t\t\t\targ = v\n\t\t\t} else {\n\t\t\t\treturn nil, fmt.Errorf(\"key not found: %s\", key)\n\t\t\t}\n\t\t\tformat = format[j+1:]\n\t\t} else {\n\t\t\t// positional argument: %s.\n\t\t\tif index >= nargs {\n\t\t\t\treturn nil, fmt.Errorf(\"not enough arguments for format string\")\n\t\t\t}\n\t\t\tif tuple, ok := x.(Tuple); ok {\n\t\t\t\targ = tuple[index]\n\t\t\t} else {\n\t\t\t\targ = x\n\t\t\t}\n\t\t}\n\n\t\t// NOTE: Starlark does not support any of these optional Python features:\n\t\t// - optional conversion flags: [#0- +], etc.\n\t\t// - optional minimum field width (number or *).\n\t\t// - optional precision (.123 or *)\n\t\t// - optional length modifier\n\n\t\t// conversion type\n\t\tif format == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"incomplete format\")\n\t\t}\n\t\tswitch c := format[0]; c {\n\t\tcase 's', 'r':\n\t\t\tif str, ok := AsString(arg); ok && c == 's' {\n\t\t\t\tbuf.WriteString(str)\n\t\t\t} else {\n\t\t\t\twriteValue(buf, arg, nil)\n\t\t\t}\n\t\tcase 'd', 'i', 'o', 'x', 'X':\n\t\t\ti, err := NumberToInt(arg)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%%%c format requires integer: %v\", c, err)\n\t\t\t}\n\t\t\tswitch c {\n\t\t\tcase 'd', 'i':\n\t\t\t\tfmt.Fprintf(buf, \"%d\", i)\n\t\t\tcase 'o':\n\t\t\t\tfmt.Fprintf(buf, \"%o\", i)\n\t\t\tcase 'x':\n\t\t\t\tfmt.Fprintf(buf, \"%x\", i)\n\t\t\tcase 'X':\n\t\t\t\tfmt.Fprintf(buf, \"%X\", i)\n\t\t\t}\n\t\tcase 'e', 'f', 'g', 'E', 'F', 'G':\n\t\t\tf, ok := AsFloat(arg)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"%%%c format requires float, not %s\", c, arg.Type())\n\t\t\t}\n\t\t\tswitch c {\n\t\t\tcase 'e':\n\t\t\t\tfmt.Fprintf(buf, \"%e\", f)\n\t\t\tcase 'f':\n\t\t\t\tfmt.Fprintf(buf, \"%f\", f)\n\t\t\tcase 'g':\n\t\t\t\tfmt.Fprintf(buf, \"%g\", f)\n\t\t\tcase 'E':\n\t\t\t\tfmt.Fprintf(buf, \"%E\", f)\n\t\t\tcase 'F':\n\t\t\t\tfmt.Fprintf(buf, \"%F\", f)\n\t\t\tcase 'G':\n\t\t\t\tfmt.Fprintf(buf, \"%G\", f)\n\t\t\t}\n\t\tcase 'c':\n\t\t\tswitch arg := arg.(type) {\n\t\t\tcase Int:\n\t\t\t\t// chr(int)\n\t\t\t\tr, err := AsInt32(arg)\n\t\t\t\tif err != nil || r < 0 || r > unicode.MaxRune {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%%c format requires a valid Unicode code point, got %s\", arg)\n\t\t\t\t}\n\t\t\t\tbuf.WriteRune(rune(r))\n\t\t\tcase String:\n\t\t\t\tr, size := utf8.DecodeRuneInString(string(arg))\n\t\t\t\tif size != len(arg) || len(arg) == 0 {\n\t\t\t\t\treturn nil, fmt.Errorf(\"%%c format requires a single-character string\")\n\t\t\t\t}\n\t\t\t\tbuf.WriteRune(r)\n\t\t\tdefault:\n\t\t\t\treturn nil, fmt.Errorf(\"%%c format requires int or single-character string, not %s\", arg.Type())\n\t\t\t}\n\t\tcase '%':\n\t\t\tbuf.WriteByte('%')\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"unknown conversion %%%c\", c)\n\t\t}\n\t\tformat = format[1:]\n\t\tindex++\n\t}\n\n\tif index < nargs {\n\t\treturn nil, fmt.Errorf(\"too many arguments for format string\")\n\t}\n\n\treturn String(buf.String()), nil\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/hashtable.go",
    "content": "// Copyright 2017 The Bazel 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 starlark\n\nimport (\n\t\"fmt\"\n\t_ \"unsafe\" // for go:linkname hack\n)\n\n// hashtable is used to represent Starlark dict and set values.\n// It is a hash table whose key/value entries form a doubly-linked list\n// in the order the entries were inserted.\ntype hashtable struct {\n\ttable     []bucket  // len is zero or a power of two\n\tbucket0   [1]bucket // inline allocation for small maps.\n\tlen       uint32\n\titercount uint32  // number of active iterators (ignored if frozen)\n\thead      *entry  // insertion order doubly-linked list; may be nil\n\ttailLink  **entry // address of nil link at end of list (perhaps &head)\n\tfrozen    bool\n}\n\nconst bucketSize = 8\n\ntype bucket struct {\n\tentries [bucketSize]entry\n\tnext    *bucket // linked list of buckets\n}\n\ntype entry struct {\n\thash       uint32 // nonzero => in use\n\tkey, value Value\n\tnext       *entry  // insertion order doubly-linked list; may be nil\n\tprevLink   **entry // address of link to this entry (perhaps &head)\n}\n\nfunc (ht *hashtable) init(size int) {\n\tif size < 0 {\n\t\tpanic(\"size < 0\")\n\t}\n\tnb := 1\n\tfor overloaded(size, nb) {\n\t\tnb = nb << 1\n\t}\n\tif nb < 2 {\n\t\tht.table = ht.bucket0[:1]\n\t} else {\n\t\tht.table = make([]bucket, nb)\n\t}\n\tht.tailLink = &ht.head\n}\n\nfunc (ht *hashtable) freeze() {\n\tif !ht.frozen {\n\t\tht.frozen = true\n\t\tfor i := range ht.table {\n\t\t\tfor p := &ht.table[i]; p != nil; p = p.next {\n\t\t\t\tfor i := range p.entries {\n\t\t\t\t\te := &p.entries[i]\n\t\t\t\t\tif e.hash != 0 {\n\t\t\t\t\t\te.key.Freeze()\n\t\t\t\t\t\te.value.Freeze()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (ht *hashtable) insert(k, v Value) error {\n\tif ht.frozen {\n\t\treturn fmt.Errorf(\"cannot insert into frozen hash table\")\n\t}\n\tif ht.itercount > 0 {\n\t\treturn fmt.Errorf(\"cannot insert into hash table during iteration\")\n\t}\n\tif ht.table == nil {\n\t\tht.init(1)\n\t}\n\th, err := k.Hash()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif h == 0 {\n\t\th = 1 // zero is reserved\n\t}\n\nretry:\n\tvar insert *entry\n\n\t// Inspect each bucket in the bucket list.\n\tp := &ht.table[h&(uint32(len(ht.table)-1))]\n\tfor {\n\t\tfor i := range p.entries {\n\t\t\te := &p.entries[i]\n\t\t\tif e.hash != h {\n\t\t\t\tif e.hash == 0 {\n\t\t\t\t\t// Found empty entry; make a note.\n\t\t\t\t\tinsert = e\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif eq, err := Equal(k, e.key); err != nil {\n\t\t\t\treturn err // e.g. excessively recursive tuple\n\t\t\t} else if !eq {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Key already present; update value.\n\t\t\te.value = v\n\t\t\treturn nil\n\t\t}\n\t\tif p.next == nil {\n\t\t\tbreak\n\t\t}\n\t\tp = p.next\n\t}\n\n\t// Key not found.  p points to the last bucket.\n\n\t// Does the number of elements exceed the buckets' load factor?\n\tif overloaded(int(ht.len), len(ht.table)) {\n\t\tht.grow()\n\t\tgoto retry\n\t}\n\n\tif insert == nil {\n\t\t// No space in existing buckets.  Add a new one to the bucket list.\n\t\tb := new(bucket)\n\t\tp.next = b\n\t\tinsert = &b.entries[0]\n\t}\n\n\t// Insert key/value pair.\n\tinsert.hash = h\n\tinsert.key = k\n\tinsert.value = v\n\n\t// Append entry to doubly-linked list.\n\tinsert.prevLink = ht.tailLink\n\t*ht.tailLink = insert\n\tht.tailLink = &insert.next\n\n\tht.len++\n\n\treturn nil\n}\n\nfunc overloaded(elems, buckets int) bool {\n\tconst loadFactor = 6.5 // just a guess\n\treturn elems >= bucketSize && float64(elems) >= loadFactor*float64(buckets)\n}\n\nfunc (ht *hashtable) grow() {\n\t// Double the number of buckets and rehash.\n\t// TODO(adonovan): opt:\n\t// - avoid reentrant calls to ht.insert, and specialize it.\n\t//   e.g. we know the calls to Equals will return false since\n\t//   there are no duplicates among the old keys.\n\t// - saving the entire hash in the bucket would avoid the need to\n\t//   recompute the hash.\n\t// - save the old buckets on a free list.\n\tht.table = make([]bucket, len(ht.table)<<1)\n\toldhead := ht.head\n\tht.head = nil\n\tht.tailLink = &ht.head\n\tht.len = 0\n\tfor e := oldhead; e != nil; e = e.next {\n\t\tht.insert(e.key, e.value)\n\t}\n\tht.bucket0[0] = bucket{} // clear out unused initial bucket\n}\n\nfunc (ht *hashtable) lookup(k Value) (v Value, found bool, err error) {\n\th, err := k.Hash()\n\tif err != nil {\n\t\treturn nil, false, err // unhashable\n\t}\n\tif h == 0 {\n\t\th = 1 // zero is reserved\n\t}\n\tif ht.table == nil {\n\t\treturn None, false, nil // empty\n\t}\n\n\t// Inspect each bucket in the bucket list.\n\tfor p := &ht.table[h&(uint32(len(ht.table)-1))]; p != nil; p = p.next {\n\t\tfor i := range p.entries {\n\t\t\te := &p.entries[i]\n\t\t\tif e.hash == h {\n\t\t\t\tif eq, err := Equal(k, e.key); err != nil {\n\t\t\t\t\treturn nil, false, err // e.g. excessively recursive tuple\n\t\t\t\t} else if eq {\n\t\t\t\t\treturn e.value, true, nil // found\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn None, false, nil // not found\n}\n\n// Items returns all the items in the map (as key/value pairs) in insertion order.\nfunc (ht *hashtable) items() []Tuple {\n\titems := make([]Tuple, 0, ht.len)\n\tarray := make([]Value, ht.len*2) // allocate a single backing array\n\tfor e := ht.head; e != nil; e = e.next {\n\t\tpair := Tuple(array[:2:2])\n\t\tarray = array[2:]\n\t\tpair[0] = e.key\n\t\tpair[1] = e.value\n\t\titems = append(items, pair)\n\t}\n\treturn items\n}\n\nfunc (ht *hashtable) first() (Value, bool) {\n\tif ht.head != nil {\n\t\treturn ht.head.key, true\n\t}\n\treturn None, false\n}\n\nfunc (ht *hashtable) keys() []Value {\n\tkeys := make([]Value, 0, ht.len)\n\tfor e := ht.head; e != nil; e = e.next {\n\t\tkeys = append(keys, e.key)\n\t}\n\treturn keys\n}\n\nfunc (ht *hashtable) delete(k Value) (v Value, found bool, err error) {\n\tif ht.frozen {\n\t\treturn nil, false, fmt.Errorf(\"cannot delete from frozen hash table\")\n\t}\n\tif ht.itercount > 0 {\n\t\treturn nil, false, fmt.Errorf(\"cannot delete from hash table during iteration\")\n\t}\n\tif ht.table == nil {\n\t\treturn None, false, nil // empty\n\t}\n\th, err := k.Hash()\n\tif err != nil {\n\t\treturn nil, false, err // unhashable\n\t}\n\tif h == 0 {\n\t\th = 1 // zero is reserved\n\t}\n\n\t// Inspect each bucket in the bucket list.\n\tfor p := &ht.table[h&(uint32(len(ht.table)-1))]; p != nil; p = p.next {\n\t\tfor i := range p.entries {\n\t\t\te := &p.entries[i]\n\t\t\tif e.hash == h {\n\t\t\t\tif eq, err := Equal(k, e.key); err != nil {\n\t\t\t\t\treturn nil, false, err\n\t\t\t\t} else if eq {\n\t\t\t\t\t// Remove e from doubly-linked list.\n\t\t\t\t\t*e.prevLink = e.next\n\t\t\t\t\tif e.next == nil {\n\t\t\t\t\t\tht.tailLink = e.prevLink // deletion of last entry\n\t\t\t\t\t} else {\n\t\t\t\t\t\te.next.prevLink = e.prevLink\n\t\t\t\t\t}\n\n\t\t\t\t\tv := e.value\n\t\t\t\t\t*e = entry{}\n\t\t\t\t\tht.len--\n\t\t\t\t\treturn v, true, nil // found\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// TODO(adonovan): opt: remove completely empty bucket from bucket list.\n\n\treturn None, false, nil // not found\n}\n\nfunc (ht *hashtable) clear() error {\n\tif ht.frozen {\n\t\treturn fmt.Errorf(\"cannot clear frozen hash table\")\n\t}\n\tif ht.itercount > 0 {\n\t\treturn fmt.Errorf(\"cannot clear hash table during iteration\")\n\t}\n\tif ht.table != nil {\n\t\tfor i := range ht.table {\n\t\t\tht.table[i] = bucket{}\n\t\t}\n\t}\n\tht.head = nil\n\tht.tailLink = &ht.head\n\tht.len = 0\n\treturn nil\n}\n\n// dump is provided as an aid to debugging.\nfunc (ht *hashtable) dump() {\n\tfmt.Printf(\"hashtable %p len=%d head=%p tailLink=%p\",\n\t\tht, ht.len, ht.head, ht.tailLink)\n\tif ht.tailLink != nil {\n\t\tfmt.Printf(\" *tailLink=%p\", *ht.tailLink)\n\t}\n\tfmt.Println()\n\tfor j := range ht.table {\n\t\tfmt.Printf(\"bucket chain %d\\n\", j)\n\t\tfor p := &ht.table[j]; p != nil; p = p.next {\n\t\t\tfmt.Printf(\"bucket %p\\n\", p)\n\t\t\tfor i := range p.entries {\n\t\t\t\te := &p.entries[i]\n\t\t\t\tfmt.Printf(\"\\tentry %d @ %p hash=%d key=%v value=%v\\n\",\n\t\t\t\t\ti, e, e.hash, e.key, e.value)\n\t\t\t\tfmt.Printf(\"\\t\\tnext=%p &next=%p prev=%p\",\n\t\t\t\t\te.next, &e.next, e.prevLink)\n\t\t\t\tif e.prevLink != nil {\n\t\t\t\t\tfmt.Printf(\" *prev=%p\", *e.prevLink)\n\t\t\t\t}\n\t\t\t\tfmt.Println()\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (ht *hashtable) iterate() *keyIterator {\n\tif !ht.frozen {\n\t\tht.itercount++\n\t}\n\treturn &keyIterator{ht: ht, e: ht.head}\n}\n\ntype keyIterator struct {\n\tht *hashtable\n\te  *entry\n}\n\nfunc (it *keyIterator) Next(k *Value) bool {\n\tif it.e != nil {\n\t\t*k = it.e.key\n\t\tit.e = it.e.next\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (it *keyIterator) Done() {\n\tif !it.ht.frozen {\n\t\tit.ht.itercount--\n\t}\n}\n\n// hashString computes the hash of s.\nfunc hashString(s string) uint32 {\n\tif len(s) >= 12 {\n\t\t// Call the Go runtime's optimized hash implementation,\n\t\t// which uses the AESENC instruction on amd64 machines.\n\t\treturn uint32(goStringHash(s, 0))\n\t}\n\treturn softHashString(s)\n}\n\n//go:linkname goStringHash runtime.stringHash\nfunc goStringHash(s string, seed uintptr) uintptr\n\n// softHashString computes the FNV hash of s in software.\nfunc softHashString(s string) uint32 {\n\tvar h uint32\n\tfor i := 0; i < len(s); i++ {\n\t\th ^= uint32(s[i])\n\t\th *= 16777619\n\t}\n\treturn h\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/int.go",
    "content": "// Copyright 2017 The Bazel 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 starlark\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\t\"strconv\"\n\n\t\"go.starlark.net/syntax\"\n)\n\n// Int is the type of a Starlark int.\ntype Int struct {\n\t// We use only the signed 32 bit range of small to ensure\n\t// that small+small and small*small do not overflow.\n\n\tsmall int64    // minint32 <= small <= maxint32\n\tbig   *big.Int // big != nil <=> value is not representable as int32\n}\n\n// newBig allocates a new big.Int.\nfunc newBig(x int64) *big.Int {\n\tif 0 <= x && int64(big.Word(x)) == x {\n\t\t// x is guaranteed to fit into a single big.Word.\n\t\t// Most starlark ints are small,\n\t\t// but math/big assumes that since you've chosen to use math/big,\n\t\t// your big.Ints will probably grow, so it over-allocates.\n\t\t// Avoid that over-allocation by manually constructing a single-word slice.\n\t\t// See https://golang.org/cl/150999, which will hopefully land in Go 1.13.\n\t\treturn new(big.Int).SetBits([]big.Word{big.Word(x)})\n\t}\n\treturn big.NewInt(x)\n}\n\n// MakeInt returns a Starlark int for the specified signed integer.\nfunc MakeInt(x int) Int { return MakeInt64(int64(x)) }\n\n// MakeInt64 returns a Starlark int for the specified int64.\nfunc MakeInt64(x int64) Int {\n\tif math.MinInt32 <= x && x <= math.MaxInt32 {\n\t\treturn Int{small: x}\n\t}\n\treturn Int{big: newBig(x)}\n}\n\n// MakeUint returns a Starlark int for the specified unsigned integer.\nfunc MakeUint(x uint) Int { return MakeUint64(uint64(x)) }\n\n// MakeUint64 returns a Starlark int for the specified uint64.\nfunc MakeUint64(x uint64) Int {\n\tif x <= math.MaxInt32 {\n\t\treturn Int{small: int64(x)}\n\t}\n\tif uint64(big.Word(x)) == x {\n\t\t// See comment in newBig for an explanation of this optimization.\n\t\treturn Int{big: new(big.Int).SetBits([]big.Word{big.Word(x)})}\n\t}\n\treturn Int{big: new(big.Int).SetUint64(x)}\n}\n\n// MakeBigInt returns a Starlark int for the specified big.Int.\n// The caller must not subsequently modify x.\nfunc MakeBigInt(x *big.Int) Int {\n\tif n := x.BitLen(); n < 32 || n == 32 && x.Int64() == math.MinInt32 {\n\t\treturn Int{small: x.Int64()}\n\t}\n\treturn Int{big: x}\n}\n\nvar (\n\tzero, one = Int{small: 0}, Int{small: 1}\n\toneBig    = newBig(1)\n\n\t_ HasUnary = Int{}\n)\n\n// Unary implements the operations +int, -int, and ~int.\nfunc (i Int) Unary(op syntax.Token) (Value, error) {\n\tswitch op {\n\tcase syntax.MINUS:\n\t\treturn zero.Sub(i), nil\n\tcase syntax.PLUS:\n\t\treturn i, nil\n\tcase syntax.TILDE:\n\t\treturn i.Not(), nil\n\t}\n\treturn nil, nil\n}\n\n// Int64 returns the value as an int64.\n// If it is not exactly representable the result is undefined and ok is false.\nfunc (i Int) Int64() (_ int64, ok bool) {\n\tif i.big != nil {\n\t\tx, acc := bigintToInt64(i.big)\n\t\tif acc != big.Exact {\n\t\t\treturn // inexact\n\t\t}\n\t\treturn x, true\n\t}\n\treturn i.small, true\n}\n\n// BigInt returns the value as a big.Int.\n// The returned variable must not be modified by the client.\nfunc (i Int) BigInt() *big.Int {\n\tif i.big != nil {\n\t\treturn i.big\n\t}\n\treturn newBig(i.small)\n}\n\n// Uint64 returns the value as a uint64.\n// If it is not exactly representable the result is undefined and ok is false.\nfunc (i Int) Uint64() (_ uint64, ok bool) {\n\tif i.big != nil {\n\t\tx, acc := bigintToUint64(i.big)\n\t\tif acc != big.Exact {\n\t\t\treturn // inexact\n\t\t}\n\t\treturn x, true\n\t}\n\tif i.small < 0 {\n\t\treturn // inexact\n\t}\n\treturn uint64(i.small), true\n}\n\n// The math/big API should provide this function.\nfunc bigintToInt64(i *big.Int) (int64, big.Accuracy) {\n\tsign := i.Sign()\n\tif sign > 0 {\n\t\tif i.Cmp(maxint64) > 0 {\n\t\t\treturn math.MaxInt64, big.Below\n\t\t}\n\t} else if sign < 0 {\n\t\tif i.Cmp(minint64) < 0 {\n\t\t\treturn math.MinInt64, big.Above\n\t\t}\n\t}\n\treturn i.Int64(), big.Exact\n}\n\n// The math/big API should provide this function.\nfunc bigintToUint64(i *big.Int) (uint64, big.Accuracy) {\n\tsign := i.Sign()\n\tif sign > 0 {\n\t\tif i.BitLen() > 64 {\n\t\t\treturn math.MaxUint64, big.Below\n\t\t}\n\t} else if sign < 0 {\n\t\treturn 0, big.Above\n\t}\n\treturn i.Uint64(), big.Exact\n}\n\nvar (\n\tminint64 = new(big.Int).SetInt64(math.MinInt64)\n\tmaxint64 = new(big.Int).SetInt64(math.MaxInt64)\n)\n\nfunc (i Int) Format(s fmt.State, ch rune) {\n\tif i.big != nil {\n\t\ti.big.Format(s, ch)\n\t\treturn\n\t}\n\tnewBig(i.small).Format(s, ch)\n}\nfunc (i Int) String() string {\n\tif i.big != nil {\n\t\treturn i.big.Text(10)\n\t}\n\treturn strconv.FormatInt(i.small, 10)\n}\nfunc (i Int) Type() string { return \"int\" }\nfunc (i Int) Freeze()      {} // immutable\nfunc (i Int) Truth() Bool  { return i.Sign() != 0 }\nfunc (i Int) Hash() (uint32, error) {\n\tvar lo big.Word\n\tif i.big != nil {\n\t\tlo = i.big.Bits()[0]\n\t} else {\n\t\tlo = big.Word(i.small)\n\t}\n\treturn 12582917 * uint32(lo+3), nil\n}\nfunc (x Int) CompareSameType(op syntax.Token, v Value, depth int) (bool, error) {\n\ty := v.(Int)\n\tif x.big != nil || y.big != nil {\n\t\treturn threeway(op, x.BigInt().Cmp(y.BigInt())), nil\n\t}\n\treturn threeway(op, signum64(x.small-y.small)), nil\n}\n\n// Float returns the float value nearest i.\nfunc (i Int) Float() Float {\n\tif i.big != nil {\n\t\tf, _ := new(big.Float).SetInt(i.big).Float64()\n\t\treturn Float(f)\n\t}\n\treturn Float(i.small)\n}\n\nfunc (x Int) Sign() int {\n\tif x.big != nil {\n\t\treturn x.big.Sign()\n\t}\n\treturn signum64(x.small)\n}\n\nfunc (x Int) Add(y Int) Int {\n\tif x.big != nil || y.big != nil {\n\t\treturn MakeBigInt(new(big.Int).Add(x.BigInt(), y.BigInt()))\n\t}\n\treturn MakeInt64(x.small + y.small)\n}\nfunc (x Int) Sub(y Int) Int {\n\tif x.big != nil || y.big != nil {\n\t\treturn MakeBigInt(new(big.Int).Sub(x.BigInt(), y.BigInt()))\n\t}\n\treturn MakeInt64(x.small - y.small)\n}\nfunc (x Int) Mul(y Int) Int {\n\tif x.big != nil || y.big != nil {\n\t\treturn MakeBigInt(new(big.Int).Mul(x.BigInt(), y.BigInt()))\n\t}\n\treturn MakeInt64(x.small * y.small)\n}\nfunc (x Int) Or(y Int) Int {\n\tif x.big != nil || y.big != nil {\n\t\treturn Int{big: new(big.Int).Or(x.BigInt(), y.BigInt())}\n\t}\n\treturn Int{small: x.small | y.small}\n}\nfunc (x Int) And(y Int) Int {\n\tif x.big != nil || y.big != nil {\n\t\treturn MakeBigInt(new(big.Int).And(x.BigInt(), y.BigInt()))\n\t}\n\treturn Int{small: x.small & y.small}\n}\nfunc (x Int) Xor(y Int) Int {\n\tif x.big != nil || y.big != nil {\n\t\treturn MakeBigInt(new(big.Int).Xor(x.BigInt(), y.BigInt()))\n\t}\n\treturn Int{small: x.small ^ y.small}\n}\nfunc (x Int) Not() Int {\n\tif x.big != nil {\n\t\treturn MakeBigInt(new(big.Int).Not(x.big))\n\t}\n\treturn Int{small: ^x.small}\n}\nfunc (x Int) Lsh(y uint) Int { return MakeBigInt(new(big.Int).Lsh(x.BigInt(), y)) }\nfunc (x Int) Rsh(y uint) Int { return MakeBigInt(new(big.Int).Rsh(x.BigInt(), y)) }\n\n// Precondition: y is nonzero.\nfunc (x Int) Div(y Int) Int {\n\t// http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html\n\tif x.big != nil || y.big != nil {\n\t\txb, yb := x.BigInt(), y.BigInt()\n\n\t\tvar quo, rem big.Int\n\t\tquo.QuoRem(xb, yb, &rem)\n\t\tif (xb.Sign() < 0) != (yb.Sign() < 0) && rem.Sign() != 0 {\n\t\t\tquo.Sub(&quo, oneBig)\n\t\t}\n\t\treturn MakeBigInt(&quo)\n\t}\n\tquo := x.small / y.small\n\trem := x.small % y.small\n\tif (x.small < 0) != (y.small < 0) && rem != 0 {\n\t\tquo -= 1\n\t}\n\treturn MakeInt64(quo)\n}\n\n// Precondition: y is nonzero.\nfunc (x Int) Mod(y Int) Int {\n\tif x.big != nil || y.big != nil {\n\t\txb, yb := x.BigInt(), y.BigInt()\n\n\t\tvar quo, rem big.Int\n\t\tquo.QuoRem(xb, yb, &rem)\n\t\tif (xb.Sign() < 0) != (yb.Sign() < 0) && rem.Sign() != 0 {\n\t\t\trem.Add(&rem, yb)\n\t\t}\n\t\treturn MakeBigInt(&rem)\n\t}\n\trem := x.small % y.small\n\tif (x.small < 0) != (y.small < 0) && rem != 0 {\n\t\trem += y.small\n\t}\n\treturn Int{small: rem}\n}\n\nfunc (i Int) rational() *big.Rat {\n\tif i.big != nil {\n\t\treturn new(big.Rat).SetInt(i.big)\n\t}\n\treturn new(big.Rat).SetInt64(i.small)\n}\n\n// AsInt32 returns the value of x if is representable as an int32.\nfunc AsInt32(x Value) (int, error) {\n\ti, ok := x.(Int)\n\tif !ok {\n\t\treturn 0, fmt.Errorf(\"got %s, want int\", x.Type())\n\t}\n\tif i.big != nil {\n\t\treturn 0, fmt.Errorf(\"%s out of range\", i)\n\t}\n\treturn int(i.small), nil\n}\n\n// NumberToInt converts a number x to an integer value.\n// An int is returned unchanged, a float is truncated towards zero.\n// NumberToInt reports an error for all other values.\nfunc NumberToInt(x Value) (Int, error) {\n\tswitch x := x.(type) {\n\tcase Int:\n\t\treturn x, nil\n\tcase Float:\n\t\tf := float64(x)\n\t\tif math.IsInf(f, 0) {\n\t\t\treturn zero, fmt.Errorf(\"cannot convert float infinity to integer\")\n\t\t} else if math.IsNaN(f) {\n\t\t\treturn zero, fmt.Errorf(\"cannot convert float NaN to integer\")\n\t\t}\n\t\treturn finiteFloatToInt(x), nil\n\n\t}\n\treturn zero, fmt.Errorf(\"cannot convert %s to int\", x.Type())\n}\n\n// finiteFloatToInt converts f to an Int, truncating towards zero.\n// f must be finite.\nfunc finiteFloatToInt(f Float) Int {\n\tif math.MinInt64 <= f && f <= math.MaxInt64 {\n\t\t// small values\n\t\treturn MakeInt64(int64(f))\n\t}\n\trat := f.rational()\n\tif rat == nil {\n\t\tpanic(f) // non-finite\n\t}\n\treturn MakeBigInt(new(big.Int).Div(rat.Num(), rat.Denom()))\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/interp.go",
    "content": "package starlark\n\n// This file defines the bytecode interpreter.\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"go.starlark.net/internal/compile\"\n\t\"go.starlark.net/internal/spell\"\n\t\"go.starlark.net/resolve\"\n\t\"go.starlark.net/syntax\"\n)\n\nconst vmdebug = false // TODO(adonovan): use a bitfield of specific kinds of error.\n\n// TODO(adonovan):\n// - optimize position table.\n// - opt: record MaxIterStack during compilation and preallocate the stack.\n\nfunc (fn *Function) CallInternal(thread *Thread, args Tuple, kwargs []Tuple) (Value, error) {\n\tif !resolve.AllowRecursion {\n\t\t// detect recursion\n\t\tfor _, fr := range thread.stack[:len(thread.stack)-1] {\n\t\t\t// We look for the same function code,\n\t\t\t// not function value, otherwise the user could\n\t\t\t// defeat the check by writing the Y combinator.\n\t\t\tif frfn, ok := fr.Callable().(*Function); ok && frfn.funcode == fn.funcode {\n\t\t\t\treturn nil, fmt.Errorf(\"function %s called recursively\", fn.Name())\n\t\t\t}\n\t\t}\n\t}\n\n\tf := fn.funcode\n\tfr := thread.frameAt(0)\n\n\t// Allocate space for stack and locals.\n\t// Logically these do not escape from this frame\n\t// (See https://github.com/golang/go/issues/20533.)\n\t//\n\t// This heap allocation looks expensive, but I was unable to get\n\t// more than 1% real time improvement in a large alloc-heavy\n\t// benchmark (in which this alloc was 8% of alloc-bytes)\n\t// by allocating space for 8 Values in each frame, or\n\t// by allocating stack by slicing an array held by the Thread\n\t// that is expanded in chunks of min(k, nspace), for k=256 or 1024.\n\tnlocals := len(f.Locals)\n\tnspace := nlocals + f.MaxStack\n\tspace := make([]Value, nspace)\n\tlocals := space[:nlocals:nlocals] // local variables, starting with parameters\n\tstack := space[nlocals:]          // operand stack\n\n\t// Digest arguments and set parameters.\n\terr := setArgs(locals, fn, args, kwargs)\n\tif err != nil {\n\t\treturn nil, thread.evalError(err)\n\t}\n\n\tfr.locals = locals\n\n\tif vmdebug {\n\t\tfmt.Printf(\"Entering %s @ %s\\n\", f.Name, f.Position(0))\n\t\tfmt.Printf(\"%d stack, %d locals\\n\", len(stack), len(locals))\n\t\tdefer fmt.Println(\"Leaving \", f.Name)\n\t}\n\n\t// Spill indicated locals to cells.\n\t// Each cell is a separate alloc to avoid spurious liveness.\n\tfor _, index := range f.Cells {\n\t\tlocals[index] = &cell{locals[index]}\n\t}\n\n\t// TODO(adonovan): add static check that beneath this point\n\t// - there is exactly one return statement\n\t// - there is no redefinition of 'err'.\n\n\tvar iterstack []Iterator // stack of active iterators\n\n\tsp := 0\n\tvar pc uint32\n\tvar result Value\n\tcode := f.Code\nloop:\n\tfor {\n\t\tfr.pc = pc\n\n\t\top := compile.Opcode(code[pc])\n\t\tpc++\n\t\tvar arg uint32\n\t\tif op >= compile.OpcodeArgMin {\n\t\t\t// TODO(adonovan): opt: profile this.\n\t\t\t// Perhaps compiling big endian would be less work to decode?\n\t\t\tfor s := uint(0); ; s += 7 {\n\t\t\t\tb := code[pc]\n\t\t\t\tpc++\n\t\t\t\targ |= uint32(b&0x7f) << s\n\t\t\t\tif b < 0x80 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif vmdebug {\n\t\t\tfmt.Fprintln(os.Stderr, stack[:sp]) // very verbose!\n\t\t\tcompile.PrintOp(f, fr.pc, op, arg)\n\t\t}\n\n\t\tswitch op {\n\t\tcase compile.NOP:\n\t\t\t// nop\n\n\t\tcase compile.DUP:\n\t\t\tstack[sp] = stack[sp-1]\n\t\t\tsp++\n\n\t\tcase compile.DUP2:\n\t\t\tstack[sp] = stack[sp-2]\n\t\t\tstack[sp+1] = stack[sp-1]\n\t\t\tsp += 2\n\n\t\tcase compile.POP:\n\t\t\tsp--\n\n\t\tcase compile.EXCH:\n\t\t\tstack[sp-2], stack[sp-1] = stack[sp-1], stack[sp-2]\n\n\t\tcase compile.EQL, compile.NEQ, compile.GT, compile.LT, compile.LE, compile.GE:\n\t\t\top := syntax.Token(op-compile.EQL) + syntax.EQL\n\t\t\ty := stack[sp-1]\n\t\t\tx := stack[sp-2]\n\t\t\tsp -= 2\n\t\t\tok, err2 := Compare(op, x, y)\n\t\t\tif err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp] = Bool(ok)\n\t\t\tsp++\n\n\t\tcase compile.PLUS,\n\t\t\tcompile.MINUS,\n\t\t\tcompile.STAR,\n\t\t\tcompile.SLASH,\n\t\t\tcompile.SLASHSLASH,\n\t\t\tcompile.PERCENT,\n\t\t\tcompile.AMP,\n\t\t\tcompile.PIPE,\n\t\t\tcompile.CIRCUMFLEX,\n\t\t\tcompile.LTLT,\n\t\t\tcompile.GTGT,\n\t\t\tcompile.IN:\n\t\t\tbinop := syntax.Token(op-compile.PLUS) + syntax.PLUS\n\t\t\tif op == compile.IN {\n\t\t\t\tbinop = syntax.IN // IN token is out of order\n\t\t\t}\n\t\t\ty := stack[sp-1]\n\t\t\tx := stack[sp-2]\n\t\t\tsp -= 2\n\t\t\tz, err2 := Binary(binop, x, y)\n\t\t\tif err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp] = z\n\t\t\tsp++\n\n\t\tcase compile.UPLUS, compile.UMINUS, compile.TILDE:\n\t\t\tvar unop syntax.Token\n\t\t\tif op == compile.TILDE {\n\t\t\t\tunop = syntax.TILDE\n\t\t\t} else {\n\t\t\t\tunop = syntax.Token(op-compile.UPLUS) + syntax.PLUS\n\t\t\t}\n\t\t\tx := stack[sp-1]\n\t\t\ty, err2 := Unary(unop, x)\n\t\t\tif err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp-1] = y\n\n\t\tcase compile.INPLACE_ADD:\n\t\t\ty := stack[sp-1]\n\t\t\tx := stack[sp-2]\n\t\t\tsp -= 2\n\n\t\t\t// It's possible that y is not Iterable but\n\t\t\t// nonetheless defines x+y, in which case we\n\t\t\t// should fall back to the general case.\n\t\t\tvar z Value\n\t\t\tif xlist, ok := x.(*List); ok {\n\t\t\t\tif yiter, ok := y.(Iterable); ok {\n\t\t\t\t\tif err = xlist.checkMutable(\"apply += to\"); err != nil {\n\t\t\t\t\t\tbreak loop\n\t\t\t\t\t}\n\t\t\t\t\tlistExtend(xlist, yiter)\n\t\t\t\t\tz = xlist\n\t\t\t\t}\n\t\t\t}\n\t\t\tif z == nil {\n\t\t\t\tz, err = Binary(syntax.PLUS, x, y)\n\t\t\t\tif err != nil {\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tstack[sp] = z\n\t\t\tsp++\n\n\t\tcase compile.NONE:\n\t\t\tstack[sp] = None\n\t\t\tsp++\n\n\t\tcase compile.TRUE:\n\t\t\tstack[sp] = True\n\t\t\tsp++\n\n\t\tcase compile.FALSE:\n\t\t\tstack[sp] = False\n\t\t\tsp++\n\n\t\tcase compile.MANDATORY:\n\t\t\tstack[sp] = mandatory{}\n\t\t\tsp++\n\n\t\tcase compile.JMP:\n\t\t\tpc = arg\n\n\t\tcase compile.CALL, compile.CALL_VAR, compile.CALL_KW, compile.CALL_VAR_KW:\n\t\t\tvar kwargs Value\n\t\t\tif op == compile.CALL_KW || op == compile.CALL_VAR_KW {\n\t\t\t\tkwargs = stack[sp-1]\n\t\t\t\tsp--\n\t\t\t}\n\n\t\t\tvar args Value\n\t\t\tif op == compile.CALL_VAR || op == compile.CALL_VAR_KW {\n\t\t\t\targs = stack[sp-1]\n\t\t\t\tsp--\n\t\t\t}\n\n\t\t\t// named args (pairs)\n\t\t\tvar kvpairs []Tuple\n\t\t\tif nkvpairs := int(arg & 0xff); nkvpairs > 0 {\n\t\t\t\tkvpairs = make([]Tuple, 0, nkvpairs)\n\t\t\t\tkvpairsAlloc := make(Tuple, 2*nkvpairs) // allocate a single backing array\n\t\t\t\tsp -= 2 * nkvpairs\n\t\t\t\tfor i := 0; i < nkvpairs; i++ {\n\t\t\t\t\tpair := kvpairsAlloc[:2:2]\n\t\t\t\t\tkvpairsAlloc = kvpairsAlloc[2:]\n\t\t\t\t\tpair[0] = stack[sp+2*i]   // name\n\t\t\t\t\tpair[1] = stack[sp+2*i+1] // value\n\t\t\t\t\tkvpairs = append(kvpairs, pair)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif kwargs != nil {\n\t\t\t\t// Add key/value items from **kwargs dictionary.\n\t\t\t\tdict, ok := kwargs.(IterableMapping)\n\t\t\t\tif !ok {\n\t\t\t\t\terr = fmt.Errorf(\"argument after ** must be a mapping, not %s\", kwargs.Type())\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t\titems := dict.Items()\n\t\t\t\tfor _, item := range items {\n\t\t\t\t\tif _, ok := item[0].(String); !ok {\n\t\t\t\t\t\terr = fmt.Errorf(\"keywords must be strings, not %s\", item[0].Type())\n\t\t\t\t\t\tbreak loop\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif len(kvpairs) == 0 {\n\t\t\t\t\tkvpairs = items\n\t\t\t\t} else {\n\t\t\t\t\tkvpairs = append(kvpairs, items...)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// positional args\n\t\t\tvar positional Tuple\n\t\t\tif npos := int(arg >> 8); npos > 0 {\n\t\t\t\tpositional = make(Tuple, npos)\n\t\t\t\tsp -= npos\n\t\t\t\tcopy(positional, stack[sp:])\n\t\t\t}\n\t\t\tif args != nil {\n\t\t\t\t// Add elements from *args sequence.\n\t\t\t\titer := Iterate(args)\n\t\t\t\tif iter == nil {\n\t\t\t\t\terr = fmt.Errorf(\"argument after * must be iterable, not %s\", args.Type())\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t\tvar elem Value\n\t\t\t\tfor iter.Next(&elem) {\n\t\t\t\t\tpositional = append(positional, elem)\n\t\t\t\t}\n\t\t\t\titer.Done()\n\t\t\t}\n\n\t\t\tfunction := stack[sp-1]\n\n\t\t\tif vmdebug {\n\t\t\t\tfmt.Printf(\"VM call %s args=%s kwargs=%s @%s\\n\",\n\t\t\t\t\tfunction, positional, kvpairs, f.Position(fr.pc))\n\t\t\t}\n\n\t\t\tthread.endProfSpan()\n\t\t\tz, err2 := Call(thread, function, positional, kvpairs)\n\t\t\tthread.beginProfSpan()\n\t\t\tif err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif vmdebug {\n\t\t\t\tfmt.Printf(\"Resuming %s @ %s\\n\", f.Name, f.Position(0))\n\t\t\t}\n\t\t\tstack[sp-1] = z\n\n\t\tcase compile.ITERPUSH:\n\t\t\tx := stack[sp-1]\n\t\t\tsp--\n\t\t\titer := Iterate(x)\n\t\t\tif iter == nil {\n\t\t\t\terr = fmt.Errorf(\"%s value is not iterable\", x.Type())\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\titerstack = append(iterstack, iter)\n\n\t\tcase compile.ITERJMP:\n\t\t\titer := iterstack[len(iterstack)-1]\n\t\t\tif iter.Next(&stack[sp]) {\n\t\t\t\tsp++\n\t\t\t} else {\n\t\t\t\tpc = arg\n\t\t\t}\n\n\t\tcase compile.ITERPOP:\n\t\t\tn := len(iterstack) - 1\n\t\t\titerstack[n].Done()\n\t\t\titerstack = iterstack[:n]\n\n\t\tcase compile.NOT:\n\t\t\tstack[sp-1] = !stack[sp-1].Truth()\n\n\t\tcase compile.RETURN:\n\t\t\tresult = stack[sp-1]\n\t\t\tbreak loop\n\n\t\tcase compile.SETINDEX:\n\t\t\tz := stack[sp-1]\n\t\t\ty := stack[sp-2]\n\t\t\tx := stack[sp-3]\n\t\t\tsp -= 3\n\t\t\terr = setIndex(x, y, z)\n\t\t\tif err != nil {\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase compile.INDEX:\n\t\t\ty := stack[sp-1]\n\t\t\tx := stack[sp-2]\n\t\t\tsp -= 2\n\t\t\tz, err2 := getIndex(x, y)\n\t\t\tif err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp] = z\n\t\t\tsp++\n\n\t\tcase compile.ATTR:\n\t\t\tx := stack[sp-1]\n\t\t\tname := f.Prog.Names[arg]\n\t\t\ty, err2 := getAttr(x, name)\n\t\t\tif err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp-1] = y\n\n\t\tcase compile.SETFIELD:\n\t\t\ty := stack[sp-1]\n\t\t\tx := stack[sp-2]\n\t\t\tsp -= 2\n\t\t\tname := f.Prog.Names[arg]\n\t\t\tif err2 := setField(x, name, y); err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase compile.MAKEDICT:\n\t\t\tstack[sp] = new(Dict)\n\t\t\tsp++\n\n\t\tcase compile.SETDICT, compile.SETDICTUNIQ:\n\t\t\tdict := stack[sp-3].(*Dict)\n\t\t\tk := stack[sp-2]\n\t\t\tv := stack[sp-1]\n\t\t\tsp -= 3\n\t\t\toldlen := dict.Len()\n\t\t\tif err2 := dict.SetKey(k, v); err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif op == compile.SETDICTUNIQ && dict.Len() == oldlen {\n\t\t\t\terr = fmt.Errorf(\"duplicate key: %v\", k)\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase compile.APPEND:\n\t\t\telem := stack[sp-1]\n\t\t\tlist := stack[sp-2].(*List)\n\t\t\tsp -= 2\n\t\t\tlist.elems = append(list.elems, elem)\n\n\t\tcase compile.SLICE:\n\t\t\tx := stack[sp-4]\n\t\t\tlo := stack[sp-3]\n\t\t\thi := stack[sp-2]\n\t\t\tstep := stack[sp-1]\n\t\t\tsp -= 4\n\t\t\tres, err2 := slice(x, lo, hi, step)\n\t\t\tif err2 != nil {\n\t\t\t\terr = err2\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp] = res\n\t\t\tsp++\n\n\t\tcase compile.UNPACK:\n\t\t\tn := int(arg)\n\t\t\titerable := stack[sp-1]\n\t\t\tsp--\n\t\t\titer := Iterate(iterable)\n\t\t\tif iter == nil {\n\t\t\t\terr = fmt.Errorf(\"got %s in sequence assignment\", iterable.Type())\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\ti := 0\n\t\t\tsp += n\n\t\t\tfor i < n && iter.Next(&stack[sp-1-i]) {\n\t\t\t\ti++\n\t\t\t}\n\t\t\tvar dummy Value\n\t\t\tif iter.Next(&dummy) {\n\t\t\t\t// NB: Len may return -1 here in obscure cases.\n\t\t\t\terr = fmt.Errorf(\"too many values to unpack (got %d, want %d)\", Len(iterable), n)\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\titer.Done()\n\t\t\tif i < n {\n\t\t\t\terr = fmt.Errorf(\"too few values to unpack (got %d, want %d)\", i, n)\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase compile.CJMP:\n\t\t\tif stack[sp-1].Truth() {\n\t\t\t\tpc = arg\n\t\t\t}\n\t\t\tsp--\n\n\t\tcase compile.CONSTANT:\n\t\t\tstack[sp] = fn.module.constants[arg]\n\t\t\tsp++\n\n\t\tcase compile.MAKETUPLE:\n\t\t\tn := int(arg)\n\t\t\ttuple := make(Tuple, n)\n\t\t\tsp -= n\n\t\t\tcopy(tuple, stack[sp:])\n\t\t\tstack[sp] = tuple\n\t\t\tsp++\n\n\t\tcase compile.MAKELIST:\n\t\t\tn := int(arg)\n\t\t\telems := make([]Value, n)\n\t\t\tsp -= n\n\t\t\tcopy(elems, stack[sp:])\n\t\t\tstack[sp] = NewList(elems)\n\t\t\tsp++\n\n\t\tcase compile.MAKEFUNC:\n\t\t\tfuncode := f.Prog.Functions[arg]\n\t\t\ttuple := stack[sp-1].(Tuple)\n\t\t\tn := len(tuple) - len(funcode.Freevars)\n\t\t\tdefaults := tuple[:n:n]\n\t\t\tfreevars := tuple[n:]\n\t\t\tstack[sp-1] = &Function{\n\t\t\t\tfuncode:  funcode,\n\t\t\t\tmodule:   fn.module,\n\t\t\t\tdefaults: defaults,\n\t\t\t\tfreevars: freevars,\n\t\t\t}\n\n\t\tcase compile.LOAD:\n\t\t\tn := int(arg)\n\t\t\tmodule := string(stack[sp-1].(String))\n\t\t\tsp--\n\n\t\t\tif thread.Load == nil {\n\t\t\t\terr = fmt.Errorf(\"load not implemented by this application\")\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\t\tthread.endProfSpan()\n\t\t\tdict, err2 := thread.Load(thread, module)\n\t\t\tthread.beginProfSpan()\n\t\t\tif err2 != nil {\n\t\t\t\terr = wrappedError{\n\t\t\t\t\tmsg:   fmt.Sprintf(\"cannot load %s: %v\", module, err2),\n\t\t\t\t\tcause: err2,\n\t\t\t\t}\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\tfrom := string(stack[sp-1-i].(String))\n\t\t\t\tv, ok := dict[from]\n\t\t\t\tif !ok {\n\t\t\t\t\terr = fmt.Errorf(\"load: name %s not found in module %s\", from, module)\n\t\t\t\t\tif n := spell.Nearest(from, dict.Keys()); n != \"\" {\n\t\t\t\t\t\terr = fmt.Errorf(\"%s (did you mean %s?)\", err, n)\n\t\t\t\t\t}\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t\tstack[sp-1-i] = v\n\t\t\t}\n\n\t\tcase compile.SETLOCAL:\n\t\t\tlocals[arg] = stack[sp-1]\n\t\t\tsp--\n\n\t\tcase compile.SETCELL:\n\t\t\tx := stack[sp-2]\n\t\t\ty := stack[sp-1]\n\t\t\tsp -= 2\n\t\t\ty.(*cell).v = x\n\n\t\tcase compile.SETGLOBAL:\n\t\t\tfn.module.globals[arg] = stack[sp-1]\n\t\t\tsp--\n\n\t\tcase compile.LOCAL:\n\t\t\tx := locals[arg]\n\t\t\tif x == nil {\n\t\t\t\terr = fmt.Errorf(\"local variable %s referenced before assignment\", f.Locals[arg].Name)\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp] = x\n\t\t\tsp++\n\n\t\tcase compile.FREE:\n\t\t\tstack[sp] = fn.freevars[arg]\n\t\t\tsp++\n\n\t\tcase compile.CELL:\n\t\t\tx := stack[sp-1]\n\t\t\tstack[sp-1] = x.(*cell).v\n\n\t\tcase compile.GLOBAL:\n\t\t\tx := fn.module.globals[arg]\n\t\t\tif x == nil {\n\t\t\t\terr = fmt.Errorf(\"global variable %s referenced before assignment\", f.Prog.Globals[arg].Name)\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp] = x\n\t\t\tsp++\n\n\t\tcase compile.PREDECLARED:\n\t\t\tname := f.Prog.Names[arg]\n\t\t\tx := fn.module.predeclared[name]\n\t\t\tif x == nil {\n\t\t\t\terr = fmt.Errorf(\"internal error: predeclared variable %s is uninitialized\", name)\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tstack[sp] = x\n\t\t\tsp++\n\n\t\tcase compile.UNIVERSAL:\n\t\t\tstack[sp] = Universe[f.Prog.Names[arg]]\n\t\t\tsp++\n\n\t\tdefault:\n\t\t\terr = fmt.Errorf(\"unimplemented: %s\", op)\n\t\t\tbreak loop\n\t\t}\n\t}\n\n\t// ITERPOP the rest of the iterator stack.\n\tfor _, iter := range iterstack {\n\t\titer.Done()\n\t}\n\n\tfr.locals = nil\n\n\treturn result, err\n}\n\ntype wrappedError struct {\n\tmsg   string\n\tcause error\n}\n\nfunc (e wrappedError) Error() string {\n\treturn e.msg\n}\n\n// Implements the xerrors.Wrapper interface\n// https://godoc.org/golang.org/x/xerrors#Wrapper\nfunc (e wrappedError) Unwrap() error {\n\treturn e.cause\n}\n\n// mandatory is a sentinel value used in a function's defaults tuple\n// to indicate that a (keyword-only) parameter is mandatory.\ntype mandatory struct{}\n\nfunc (mandatory) String() string        { return \"mandatory\" }\nfunc (mandatory) Type() string          { return \"mandatory\" }\nfunc (mandatory) Freeze()               {} // immutable\nfunc (mandatory) Truth() Bool           { return False }\nfunc (mandatory) Hash() (uint32, error) { return 0, nil }\n\n// A cell is a box containing a Value.\n// Local variables marked as cells hold their value indirectly\n// so that they may be shared by outer and inner nested functions.\n// Cells are always accessed using indirect CELL/SETCELL instructions.\n// The FreeVars tuple contains only cells.\n// The FREE instruction always yields a cell.\ntype cell struct{ v Value }\n\nfunc (c *cell) String() string { return \"cell\" }\nfunc (c *cell) Type() string   { return \"cell\" }\nfunc (c *cell) Freeze() {\n\tif c.v != nil {\n\t\tc.v.Freeze()\n\t}\n}\nfunc (c *cell) Truth() Bool           { panic(\"unreachable\") }\nfunc (c *cell) Hash() (uint32, error) { panic(\"unreachable\") }\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/library.go",
    "content": "// Copyright 2017 The Bazel 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 starlark\n\n// This file defines the library of built-ins.\n//\n// Built-ins must explicitly check the \"frozen\" flag before updating\n// mutable types such as lists and dicts.\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf16\"\n\t\"unicode/utf8\"\n\n\t\"go.starlark.net/syntax\"\n)\n\n// Universe defines the set of universal built-ins, such as None, True, and len.\n//\n// The Go application may add or remove items from the\n// universe dictionary before Starlark evaluation begins.\n// All values in the dictionary must be immutable.\n// Starlark programs cannot modify the dictionary.\nvar Universe StringDict\n\nfunc init() {\n\t// https://github.com/google/starlark-go/blob/master/doc/spec.md#built-in-constants-and-functions\n\tUniverse = StringDict{\n\t\t\"None\":      None,\n\t\t\"True\":      True,\n\t\t\"False\":     False,\n\t\t\"any\":       NewBuiltin(\"any\", any),\n\t\t\"all\":       NewBuiltin(\"all\", all),\n\t\t\"bool\":      NewBuiltin(\"bool\", bool_),\n\t\t\"chr\":       NewBuiltin(\"chr\", chr),\n\t\t\"dict\":      NewBuiltin(\"dict\", dict),\n\t\t\"dir\":       NewBuiltin(\"dir\", dir),\n\t\t\"enumerate\": NewBuiltin(\"enumerate\", enumerate),\n\t\t\"fail\":      NewBuiltin(\"fail\", fail),\n\t\t\"float\":     NewBuiltin(\"float\", float), // requires resolve.AllowFloat\n\t\t\"getattr\":   NewBuiltin(\"getattr\", getattr),\n\t\t\"hasattr\":   NewBuiltin(\"hasattr\", hasattr),\n\t\t\"hash\":      NewBuiltin(\"hash\", hash),\n\t\t\"int\":       NewBuiltin(\"int\", int_),\n\t\t\"len\":       NewBuiltin(\"len\", len_),\n\t\t\"list\":      NewBuiltin(\"list\", list),\n\t\t\"max\":       NewBuiltin(\"max\", minmax),\n\t\t\"min\":       NewBuiltin(\"min\", minmax),\n\t\t\"ord\":       NewBuiltin(\"ord\", ord),\n\t\t\"print\":     NewBuiltin(\"print\", print),\n\t\t\"range\":     NewBuiltin(\"range\", range_),\n\t\t\"repr\":      NewBuiltin(\"repr\", repr),\n\t\t\"reversed\":  NewBuiltin(\"reversed\", reversed),\n\t\t\"set\":       NewBuiltin(\"set\", set), // requires resolve.AllowSet\n\t\t\"sorted\":    NewBuiltin(\"sorted\", sorted),\n\t\t\"str\":       NewBuiltin(\"str\", str),\n\t\t\"tuple\":     NewBuiltin(\"tuple\", tuple),\n\t\t\"type\":      NewBuiltin(\"type\", type_),\n\t\t\"zip\":       NewBuiltin(\"zip\", zip),\n\t}\n}\n\n// methods of built-in types\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#built-in-methods\nvar (\n\tdictMethods = map[string]*Builtin{\n\t\t\"clear\":      NewBuiltin(\"clear\", dict_clear),\n\t\t\"get\":        NewBuiltin(\"get\", dict_get),\n\t\t\"items\":      NewBuiltin(\"items\", dict_items),\n\t\t\"keys\":       NewBuiltin(\"keys\", dict_keys),\n\t\t\"pop\":        NewBuiltin(\"pop\", dict_pop),\n\t\t\"popitem\":    NewBuiltin(\"popitem\", dict_popitem),\n\t\t\"setdefault\": NewBuiltin(\"setdefault\", dict_setdefault),\n\t\t\"update\":     NewBuiltin(\"update\", dict_update),\n\t\t\"values\":     NewBuiltin(\"values\", dict_values),\n\t}\n\n\tlistMethods = map[string]*Builtin{\n\t\t\"append\": NewBuiltin(\"append\", list_append),\n\t\t\"clear\":  NewBuiltin(\"clear\", list_clear),\n\t\t\"extend\": NewBuiltin(\"extend\", list_extend),\n\t\t\"index\":  NewBuiltin(\"index\", list_index),\n\t\t\"insert\": NewBuiltin(\"insert\", list_insert),\n\t\t\"pop\":    NewBuiltin(\"pop\", list_pop),\n\t\t\"remove\": NewBuiltin(\"remove\", list_remove),\n\t}\n\n\tstringMethods = map[string]*Builtin{\n\t\t\"capitalize\":     NewBuiltin(\"capitalize\", string_capitalize),\n\t\t\"codepoint_ords\": NewBuiltin(\"codepoint_ords\", string_iterable),\n\t\t\"codepoints\":     NewBuiltin(\"codepoints\", string_iterable), // sic\n\t\t\"count\":          NewBuiltin(\"count\", string_count),\n\t\t\"elem_ords\":      NewBuiltin(\"elem_ords\", string_iterable),\n\t\t\"elems\":          NewBuiltin(\"elems\", string_iterable),      // sic\n\t\t\"endswith\":       NewBuiltin(\"endswith\", string_startswith), // sic\n\t\t\"find\":           NewBuiltin(\"find\", string_find),\n\t\t\"format\":         NewBuiltin(\"format\", string_format),\n\t\t\"index\":          NewBuiltin(\"index\", string_index),\n\t\t\"isalnum\":        NewBuiltin(\"isalnum\", string_isalnum),\n\t\t\"isalpha\":        NewBuiltin(\"isalpha\", string_isalpha),\n\t\t\"isdigit\":        NewBuiltin(\"isdigit\", string_isdigit),\n\t\t\"islower\":        NewBuiltin(\"islower\", string_islower),\n\t\t\"isspace\":        NewBuiltin(\"isspace\", string_isspace),\n\t\t\"istitle\":        NewBuiltin(\"istitle\", string_istitle),\n\t\t\"isupper\":        NewBuiltin(\"isupper\", string_isupper),\n\t\t\"join\":           NewBuiltin(\"join\", string_join),\n\t\t\"lower\":          NewBuiltin(\"lower\", string_lower),\n\t\t\"lstrip\":         NewBuiltin(\"lstrip\", string_strip), // sic\n\t\t\"partition\":      NewBuiltin(\"partition\", string_partition),\n\t\t\"replace\":        NewBuiltin(\"replace\", string_replace),\n\t\t\"rfind\":          NewBuiltin(\"rfind\", string_rfind),\n\t\t\"rindex\":         NewBuiltin(\"rindex\", string_rindex),\n\t\t\"rpartition\":     NewBuiltin(\"rpartition\", string_partition), // sic\n\t\t\"rsplit\":         NewBuiltin(\"rsplit\", string_split),         // sic\n\t\t\"rstrip\":         NewBuiltin(\"rstrip\", string_strip),         // sic\n\t\t\"split\":          NewBuiltin(\"split\", string_split),\n\t\t\"splitlines\":     NewBuiltin(\"splitlines\", string_splitlines),\n\t\t\"startswith\":     NewBuiltin(\"startswith\", string_startswith),\n\t\t\"strip\":          NewBuiltin(\"strip\", string_strip),\n\t\t\"title\":          NewBuiltin(\"title\", string_title),\n\t\t\"upper\":          NewBuiltin(\"upper\", string_upper),\n\t}\n\n\tsetMethods = map[string]*Builtin{\n\t\t\"union\": NewBuiltin(\"union\", set_union),\n\t}\n)\n\nfunc builtinAttr(recv Value, name string, methods map[string]*Builtin) (Value, error) {\n\tb := methods[name]\n\tif b == nil {\n\t\treturn nil, nil // no such method\n\t}\n\treturn b.BindReceiver(recv), nil\n}\n\nfunc builtinAttrNames(methods map[string]*Builtin) []string {\n\tnames := make([]string, 0, len(methods))\n\tfor name := range methods {\n\t\tnames = append(names, name)\n\t}\n\tsort.Strings(names)\n\treturn names\n}\n\n// ---- built-in functions ----\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#all\nfunc all(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(\"all\", args, kwargs, 1, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\titer := iterable.Iterate()\n\tdefer iter.Done()\n\tvar x Value\n\tfor iter.Next(&x) {\n\t\tif !x.Truth() {\n\t\t\treturn False, nil\n\t\t}\n\t}\n\treturn True, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#any\nfunc any(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(\"any\", args, kwargs, 1, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\titer := iterable.Iterate()\n\tdefer iter.Done()\n\tvar x Value\n\tfor iter.Next(&x) {\n\t\tif x.Truth() {\n\t\t\treturn True, nil\n\t\t}\n\t}\n\treturn False, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#bool\nfunc bool_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar x Value = False\n\tif err := UnpackPositionalArgs(\"bool\", args, kwargs, 0, &x); err != nil {\n\t\treturn nil, err\n\t}\n\treturn x.Truth(), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#chr\nfunc chr(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(kwargs) > 0 {\n\t\treturn nil, fmt.Errorf(\"chr does not accept keyword arguments\")\n\t}\n\tif len(args) != 1 {\n\t\treturn nil, fmt.Errorf(\"chr: got %d arguments, want 1\", len(args))\n\t}\n\ti, err := AsInt32(args[0])\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"chr: got %s, want int\", args[0].Type())\n\t}\n\tif i < 0 {\n\t\treturn nil, fmt.Errorf(\"chr: Unicode code point %d out of range (<0)\", i)\n\t}\n\tif i > unicode.MaxRune {\n\t\treturn nil, fmt.Errorf(\"chr: Unicode code point U+%X out of range (>0x10FFFF)\", i)\n\t}\n\treturn String(string(i)), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict\nfunc dict(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(args) > 1 {\n\t\treturn nil, fmt.Errorf(\"dict: got %d arguments, want at most 1\", len(args))\n\t}\n\tdict := new(Dict)\n\tif err := updateDict(dict, args, kwargs); err != nil {\n\t\treturn nil, fmt.Errorf(\"dict: %v\", err)\n\t}\n\treturn dict, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dir\nfunc dir(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(kwargs) > 0 {\n\t\treturn nil, fmt.Errorf(\"dir does not accept keyword arguments\")\n\t}\n\tif len(args) != 1 {\n\t\treturn nil, fmt.Errorf(\"dir: got %d arguments, want 1\", len(args))\n\t}\n\n\tvar names []string\n\tif x, ok := args[0].(HasAttrs); ok {\n\t\tnames = x.AttrNames()\n\t}\n\tsort.Strings(names)\n\telems := make([]Value, len(names))\n\tfor i, name := range names {\n\t\telems[i] = String(name)\n\t}\n\treturn NewList(elems), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#enumerate\nfunc enumerate(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tvar start int\n\tif err := UnpackPositionalArgs(\"enumerate\", args, kwargs, 1, &iterable, &start); err != nil {\n\t\treturn nil, err\n\t}\n\n\titer := iterable.Iterate()\n\tif iter == nil {\n\t\treturn nil, fmt.Errorf(\"enumerate: got %s, want iterable\", iterable.Type())\n\t}\n\tdefer iter.Done()\n\n\tvar pairs []Value\n\tvar x Value\n\n\tif n := Len(iterable); n >= 0 {\n\t\t// common case: known length\n\t\tpairs = make([]Value, 0, n)\n\t\tarray := make(Tuple, 2*n) // allocate a single backing array\n\t\tfor i := 0; iter.Next(&x); i++ {\n\t\t\tpair := array[:2:2]\n\t\t\tarray = array[2:]\n\t\t\tpair[0] = MakeInt(start + i)\n\t\t\tpair[1] = x\n\t\t\tpairs = append(pairs, pair)\n\t\t}\n\t} else {\n\t\t// non-sequence (unknown length)\n\t\tfor i := 0; iter.Next(&x); i++ {\n\t\t\tpair := Tuple{MakeInt(start + i), x}\n\t\t\tpairs = append(pairs, pair)\n\t\t}\n\t}\n\n\treturn NewList(pairs), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#fail\nfunc fail(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tsep := \" \"\n\tif err := UnpackArgs(\"fail\", nil, kwargs, \"sep?\", &sep); err != nil {\n\t\treturn nil, err\n\t}\n\tbuf := new(strings.Builder)\n\tbuf.WriteString(\"fail: \")\n\tfor i, v := range args {\n\t\tif i > 0 {\n\t\t\tbuf.WriteString(sep)\n\t\t}\n\t\tif s, ok := AsString(v); ok {\n\t\t\tbuf.WriteString(s)\n\t\t} else {\n\t\t\twriteValue(buf, v, nil)\n\t\t}\n\t}\n\n\treturn nil, errors.New(buf.String())\n}\n\nfunc float(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(kwargs) > 0 {\n\t\treturn nil, fmt.Errorf(\"float does not accept keyword arguments\")\n\t}\n\tif len(args) == 0 {\n\t\treturn Float(0.0), nil\n\t}\n\tif len(args) != 1 {\n\t\treturn nil, fmt.Errorf(\"float got %d arguments, wants 1\", len(args))\n\t}\n\tswitch x := args[0].(type) {\n\tcase Bool:\n\t\tif x {\n\t\t\treturn Float(1.0), nil\n\t\t} else {\n\t\t\treturn Float(0.0), nil\n\t\t}\n\tcase Int:\n\t\treturn x.Float(), nil\n\tcase Float:\n\t\treturn x, nil\n\tcase String:\n\t\tf, err := strconv.ParseFloat(string(x), 64)\n\t\tif err != nil {\n\t\t\treturn nil, nameErr(b, err)\n\t\t}\n\t\treturn Float(f), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"float got %s, want number or string\", x.Type())\n\t}\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#getattr\nfunc getattr(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar object, dflt Value\n\tvar name string\n\tif err := UnpackPositionalArgs(\"getattr\", args, kwargs, 2, &object, &name, &dflt); err != nil {\n\t\treturn nil, err\n\t}\n\tif object, ok := object.(HasAttrs); ok {\n\t\tv, err := object.Attr(name)\n\t\tif err != nil {\n\t\t\t// An error could mean the field doesn't exist,\n\t\t\t// or it exists but could not be computed.\n\t\t\tif dflt != nil {\n\t\t\t\treturn dflt, nil\n\t\t\t}\n\t\t\treturn nil, nameErr(b, err)\n\t\t}\n\t\tif v != nil {\n\t\t\treturn v, nil\n\t\t}\n\t\t// (nil, nil) => no such field\n\t}\n\tif dflt != nil {\n\t\treturn dflt, nil\n\t}\n\treturn nil, fmt.Errorf(\"getattr: %s has no .%s field or method\", object.Type(), name)\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#hasattr\nfunc hasattr(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar object Value\n\tvar name string\n\tif err := UnpackPositionalArgs(\"hasattr\", args, kwargs, 2, &object, &name); err != nil {\n\t\treturn nil, err\n\t}\n\tif object, ok := object.(HasAttrs); ok {\n\t\tv, err := object.Attr(name)\n\t\tif err == nil {\n\t\t\treturn Bool(v != nil), nil\n\t\t}\n\n\t\t// An error does not conclusively indicate presence or\n\t\t// absence of a field: it could occur while computing\n\t\t// the value of a present attribute, or it could be a\n\t\t// \"no such attribute\" error with details.\n\t\tfor _, x := range object.AttrNames() {\n\t\t\tif x == name {\n\t\t\t\treturn True, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn False, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#hash\nfunc hash(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar s string\n\tif err := UnpackPositionalArgs(\"hash\", args, kwargs, 1, &s); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// The Starlark spec requires that the hash function be\n\t// deterministic across all runs, motivated by the need\n\t// for reproducibility of builds. Thus we cannot call\n\t// String.Hash, which uses the fastest implementation\n\t// available, because as varies across process restarts,\n\t// and may evolve with the implementation.\n\n\treturn MakeInt(int(javaStringHash(s))), nil\n}\n\n// javaStringHash returns the same hash as would be produced by\n// java.lang.String.hashCode. This requires transcoding the string to\n// UTF-16; transcoding may introduce Unicode replacement characters\n// U+FFFD if s does not contain valid UTF-8.\nfunc javaStringHash(s string) (h int32) {\n\tfor _, r := range s {\n\t\tif utf16.IsSurrogate(r) {\n\t\t\tc1, c2 := utf16.EncodeRune(r)\n\t\t\th = 31*h + c1\n\t\t\th = 31*h + c2\n\t\t} else {\n\t\t\th = 31*h + r // r may be U+FFFD\n\t\t}\n\t}\n\treturn h\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#int\nfunc int_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar x Value = zero\n\tvar base Value\n\tif err := UnpackArgs(\"int\", args, kwargs, \"x\", &x, \"base?\", &base); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// \"If x is not a number or base is given, x must be a string.\"\n\tif s, ok := AsString(x); ok {\n\t\tb := 10\n\t\tif base != nil {\n\t\t\tvar err error\n\t\t\tb, err = AsInt32(base)\n\t\t\tif err != nil || b != 0 && (b < 2 || b > 36) {\n\t\t\t\treturn nil, fmt.Errorf(\"int: base must be an integer >= 2 && <= 36\")\n\t\t\t}\n\t\t}\n\n\t\torig := s // save original for error message\n\n\t\t// remove sign\n\t\tvar neg bool\n\t\tif s != \"\" {\n\t\t\tif s[0] == '+' {\n\t\t\t\ts = s[1:]\n\t\t\t} else if s[0] == '-' {\n\t\t\t\tneg = true\n\t\t\t\ts = s[1:]\n\t\t\t}\n\t\t}\n\n\t\t// remove base prefix\n\t\tbaseprefix := 0\n\t\tif len(s) > 1 && s[0] == '0' {\n\t\t\tif len(s) > 2 {\n\t\t\t\tswitch s[1] {\n\t\t\t\tcase 'o', 'O':\n\t\t\t\t\ts = s[2:]\n\t\t\t\t\tbaseprefix = 8\n\t\t\t\tcase 'x', 'X':\n\t\t\t\t\ts = s[2:]\n\t\t\t\t\tbaseprefix = 16\n\t\t\t\tcase 'b', 'B':\n\t\t\t\t\ts = s[2:]\n\t\t\t\t\tbaseprefix = 2\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For automatic base detection,\n\t\t\t// a string starting with zero\n\t\t\t// must be all zeros.\n\t\t\t// Thus we reject int(\"0755\", 0).\n\t\t\tif baseprefix == 0 && b == 0 {\n\t\t\t\tfor i := 1; i < len(s); i++ {\n\t\t\t\t\tif s[i] != '0' {\n\t\t\t\t\t\tgoto invalid\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn zero, nil\n\t\t\t}\n\n\t\t\tif b != 0 && baseprefix != 0 && baseprefix != b {\n\t\t\t\t// Explicit base doesn't match prefix,\n\t\t\t\t// e.g. int(\"0o755\", 16).\n\t\t\t\tgoto invalid\n\t\t\t}\n\t\t}\n\n\t\t// select base\n\t\tif b == 0 {\n\t\t\tif baseprefix != 0 {\n\t\t\t\tb = baseprefix\n\t\t\t} else {\n\t\t\t\tb = 10\n\t\t\t}\n\t\t}\n\n\t\t// we explicitly handled sign above.\n\t\t// if a sign remains, it is invalid.\n\t\tif s != \"\" && (s[0] == '-' || s[0] == '+') {\n\t\t\tgoto invalid\n\t\t}\n\n\t\t// s has no sign or base prefix.\n\t\t//\n\t\t// int(x) permits arbitrary precision, unlike the scanner.\n\t\tif i, ok := new(big.Int).SetString(s, b); ok {\n\t\t\tres := MakeBigInt(i)\n\t\t\tif neg {\n\t\t\t\tres = zero.Sub(res)\n\t\t\t}\n\t\t\treturn res, nil\n\t\t}\n\n\tinvalid:\n\t\treturn nil, fmt.Errorf(\"int: invalid literal with base %d: %s\", b, orig)\n\t}\n\n\tif base != nil {\n\t\treturn nil, fmt.Errorf(\"int: can't convert non-string with explicit base\")\n\t}\n\n\tif b, ok := x.(Bool); ok {\n\t\tif b {\n\t\t\treturn one, nil\n\t\t} else {\n\t\t\treturn zero, nil\n\t\t}\n\t}\n\n\ti, err := NumberToInt(x)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"int: %s\", err)\n\t}\n\treturn i, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#len\nfunc len_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar x Value\n\tif err := UnpackPositionalArgs(\"len\", args, kwargs, 1, &x); err != nil {\n\t\treturn nil, err\n\t}\n\tlen := Len(x)\n\tif len < 0 {\n\t\treturn nil, fmt.Errorf(\"len: value of type %s has no len\", x.Type())\n\t}\n\treturn MakeInt(len), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list\nfunc list(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(\"list\", args, kwargs, 0, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\tvar elems []Value\n\tif iterable != nil {\n\t\titer := iterable.Iterate()\n\t\tdefer iter.Done()\n\t\tif n := Len(iterable); n > 0 {\n\t\t\telems = make([]Value, 0, n) // preallocate if length known\n\t\t}\n\t\tvar x Value\n\t\tfor iter.Next(&x) {\n\t\t\telems = append(elems, x)\n\t\t}\n\t}\n\treturn NewList(elems), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#min\nfunc minmax(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(args) == 0 {\n\t\treturn nil, fmt.Errorf(\"%s requires at least one positional argument\", b.Name())\n\t}\n\tvar keyFunc Callable\n\tif err := UnpackArgs(b.Name(), nil, kwargs, \"key?\", &keyFunc); err != nil {\n\t\treturn nil, err\n\t}\n\tvar op syntax.Token\n\tif b.Name() == \"max\" {\n\t\top = syntax.GT\n\t} else {\n\t\top = syntax.LT\n\t}\n\tvar iterable Value\n\tif len(args) == 1 {\n\t\titerable = args[0]\n\t} else {\n\t\titerable = args\n\t}\n\titer := Iterate(iterable)\n\tif iter == nil {\n\t\treturn nil, fmt.Errorf(\"%s: %s value is not iterable\", b.Name(), iterable.Type())\n\t}\n\tdefer iter.Done()\n\tvar extremum Value\n\tif !iter.Next(&extremum) {\n\t\treturn nil, nameErr(b, \"argument is an empty sequence\")\n\t}\n\n\tvar extremeKey Value\n\tvar keyargs Tuple\n\tif keyFunc == nil {\n\t\textremeKey = extremum\n\t} else {\n\t\tkeyargs = Tuple{extremum}\n\t\tres, err := Call(thread, keyFunc, keyargs, nil)\n\t\tif err != nil {\n\t\t\treturn nil, err // to preserve backtrace, don't modify error\n\t\t}\n\t\textremeKey = res\n\t}\n\n\tvar x Value\n\tfor iter.Next(&x) {\n\t\tvar key Value\n\t\tif keyFunc == nil {\n\t\t\tkey = x\n\t\t} else {\n\t\t\tkeyargs[0] = x\n\t\t\tres, err := Call(thread, keyFunc, keyargs, nil)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err // to preserve backtrace, don't modify error\n\t\t\t}\n\t\t\tkey = res\n\t\t}\n\n\t\tif ok, err := Compare(op, key, extremeKey); err != nil {\n\t\t\treturn nil, nameErr(b, err)\n\t\t} else if ok {\n\t\t\textremum = x\n\t\t\textremeKey = key\n\t\t}\n\t}\n\treturn extremum, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#ord\nfunc ord(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(kwargs) > 0 {\n\t\treturn nil, fmt.Errorf(\"ord does not accept keyword arguments\")\n\t}\n\tif len(args) != 1 {\n\t\treturn nil, fmt.Errorf(\"ord: got %d arguments, want 1\", len(args))\n\t}\n\ts, ok := AsString(args[0])\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"ord: got %s, want string\", args[0].Type())\n\t}\n\tr, sz := utf8.DecodeRuneInString(s)\n\tif sz == 0 || sz != len(s) {\n\t\tn := utf8.RuneCountInString(s)\n\t\treturn nil, fmt.Errorf(\"ord: string encodes %d Unicode code points, want 1\", n)\n\t}\n\treturn MakeInt(int(r)), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#print\nfunc print(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tsep := \" \"\n\tif err := UnpackArgs(\"print\", nil, kwargs, \"sep?\", &sep); err != nil {\n\t\treturn nil, err\n\t}\n\tbuf := new(strings.Builder)\n\tfor i, v := range args {\n\t\tif i > 0 {\n\t\t\tbuf.WriteString(sep)\n\t\t}\n\t\tif s, ok := AsString(v); ok {\n\t\t\tbuf.WriteString(s)\n\t\t} else {\n\t\t\twriteValue(buf, v, nil)\n\t\t}\n\t}\n\n\ts := buf.String()\n\tif thread.Print != nil {\n\t\tthread.Print(thread, s)\n\t} else {\n\t\tfmt.Fprintln(os.Stderr, s)\n\t}\n\treturn None, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#range\nfunc range_(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar start, stop, step int\n\tstep = 1\n\tif err := UnpackPositionalArgs(\"range\", args, kwargs, 1, &start, &stop, &step); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// TODO(adonovan): analyze overflow/underflows cases for 32-bit implementations.\n\tif len(args) == 1 {\n\t\t// range(stop)\n\t\tstart, stop = 0, start\n\t}\n\tif step == 0 {\n\t\t// we were given range(start, stop, 0)\n\t\treturn nil, nameErr(b, \"step argument must not be zero\")\n\t}\n\n\treturn rangeValue{start: start, stop: stop, step: step, len: rangeLen(start, stop, step)}, nil\n}\n\n// A rangeValue is a comparable, immutable, indexable sequence of integers\n// defined by the three parameters to a range(...) call.\n// Invariant: step != 0.\ntype rangeValue struct{ start, stop, step, len int }\n\nvar (\n\t_ Indexable  = rangeValue{}\n\t_ Sequence   = rangeValue{}\n\t_ Comparable = rangeValue{}\n\t_ Sliceable  = rangeValue{}\n)\n\nfunc (r rangeValue) Len() int          { return r.len }\nfunc (r rangeValue) Index(i int) Value { return MakeInt(r.start + i*r.step) }\nfunc (r rangeValue) Iterate() Iterator { return &rangeIterator{r, 0} }\n\n// rangeLen calculates the length of a range with the provided start, stop, and step.\n// caller must ensure that step is non-zero.\nfunc rangeLen(start, stop, step int) int {\n\tswitch {\n\tcase step > 0:\n\t\tif stop > start {\n\t\t\treturn (stop-1-start)/step + 1\n\t\t}\n\tcase step < 0:\n\t\tif start > stop {\n\t\t\treturn (start-1-stop)/-step + 1\n\t\t}\n\tdefault:\n\t\tpanic(\"rangeLen: zero step\")\n\t}\n\treturn 0\n}\n\nfunc (r rangeValue) Slice(start, end, step int) Value {\n\tnewStart := r.start + r.step*start\n\tnewStop := r.start + r.step*end\n\tnewStep := r.step * step\n\treturn rangeValue{\n\t\tstart: newStart,\n\t\tstop:  newStop,\n\t\tstep:  newStep,\n\t\tlen:   rangeLen(newStart, newStop, newStep),\n\t}\n}\n\nfunc (r rangeValue) Freeze() {} // immutable\nfunc (r rangeValue) String() string {\n\tif r.step != 1 {\n\t\treturn fmt.Sprintf(\"range(%d, %d, %d)\", r.start, r.stop, r.step)\n\t} else if r.start != 0 {\n\t\treturn fmt.Sprintf(\"range(%d, %d)\", r.start, r.stop)\n\t} else {\n\t\treturn fmt.Sprintf(\"range(%d)\", r.stop)\n\t}\n}\nfunc (r rangeValue) Type() string          { return \"range\" }\nfunc (r rangeValue) Truth() Bool           { return r.len > 0 }\nfunc (r rangeValue) Hash() (uint32, error) { return 0, fmt.Errorf(\"unhashable: range\") }\n\nfunc (x rangeValue) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(rangeValue)\n\tswitch op {\n\tcase syntax.EQL:\n\t\treturn rangeEqual(x, y), nil\n\tcase syntax.NEQ:\n\t\treturn !rangeEqual(x, y), nil\n\tdefault:\n\t\treturn false, fmt.Errorf(\"%s %s %s not implemented\", x.Type(), op, y.Type())\n\t}\n}\n\nfunc rangeEqual(x, y rangeValue) bool {\n\t// Two ranges compare equal if they denote the same sequence.\n\tif x.len != y.len {\n\t\treturn false // sequences differ in length\n\t}\n\tif x.len == 0 {\n\t\treturn true // both sequences are empty\n\t}\n\tif x.start != y.start {\n\t\treturn false // first element differs\n\t}\n\treturn x.len == 1 || x.step == y.step\n}\n\nfunc (r rangeValue) contains(x Int) bool {\n\tx32, err := AsInt32(x)\n\tif err != nil {\n\t\treturn false // out of range\n\t}\n\tdelta := x32 - r.start\n\tquo, rem := delta/r.step, delta%r.step\n\treturn rem == 0 && 0 <= quo && quo < r.len\n}\n\ntype rangeIterator struct {\n\tr rangeValue\n\ti int\n}\n\nfunc (it *rangeIterator) Next(p *Value) bool {\n\tif it.i < it.r.len {\n\t\t*p = it.r.Index(it.i)\n\t\tit.i++\n\t\treturn true\n\t}\n\treturn false\n}\nfunc (*rangeIterator) Done() {}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#repr\nfunc repr(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar x Value\n\tif err := UnpackPositionalArgs(\"repr\", args, kwargs, 1, &x); err != nil {\n\t\treturn nil, err\n\t}\n\treturn String(x.String()), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#reversed\nfunc reversed(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(\"reversed\", args, kwargs, 1, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\titer := iterable.Iterate()\n\tdefer iter.Done()\n\tvar elems []Value\n\tif n := Len(args[0]); n >= 0 {\n\t\telems = make([]Value, 0, n) // preallocate if length known\n\t}\n\tvar x Value\n\tfor iter.Next(&x) {\n\t\telems = append(elems, x)\n\t}\n\tn := len(elems)\n\tfor i := 0; i < n>>1; i++ {\n\t\telems[i], elems[n-1-i] = elems[n-1-i], elems[i]\n\t}\n\treturn NewList(elems), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#set\nfunc set(thread *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(\"set\", args, kwargs, 0, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\tset := new(Set)\n\tif iterable != nil {\n\t\titer := iterable.Iterate()\n\t\tdefer iter.Done()\n\t\tvar x Value\n\t\tfor iter.Next(&x) {\n\t\t\tif err := set.Insert(x); err != nil {\n\t\t\t\treturn nil, nameErr(b, err)\n\t\t\t}\n\t\t}\n\t}\n\treturn set, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#sorted\nfunc sorted(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\t// Oddly, Python's sorted permits all arguments to be positional, thus so do we.\n\tvar iterable Iterable\n\tvar key Callable\n\tvar reverse bool\n\tif err := UnpackArgs(\"sorted\", args, kwargs,\n\t\t\"iterable\", &iterable,\n\t\t\"key?\", &key,\n\t\t\"reverse?\", &reverse,\n\t); err != nil {\n\t\treturn nil, err\n\t}\n\n\titer := iterable.Iterate()\n\tdefer iter.Done()\n\tvar values []Value\n\tif n := Len(iterable); n > 0 {\n\t\tvalues = make(Tuple, 0, n) // preallocate if length is known\n\t}\n\tvar x Value\n\tfor iter.Next(&x) {\n\t\tvalues = append(values, x)\n\t}\n\n\t// Derive keys from values by applying key function.\n\tvar keys []Value\n\tif key != nil {\n\t\tkeys = make([]Value, len(values))\n\t\tfor i, v := range values {\n\t\t\tk, err := Call(thread, key, Tuple{v}, nil)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err // to preserve backtrace, don't modify error\n\t\t\t}\n\t\t\tkeys[i] = k\n\t\t}\n\t}\n\n\tslice := &sortSlice{keys: keys, values: values}\n\tif reverse {\n\t\tsort.Stable(sort.Reverse(slice))\n\t} else {\n\t\tsort.Stable(slice)\n\t}\n\treturn NewList(slice.values), slice.err\n}\n\ntype sortSlice struct {\n\tkeys   []Value // nil => values[i] is key\n\tvalues []Value\n\terr    error\n}\n\nfunc (s *sortSlice) Len() int { return len(s.values) }\nfunc (s *sortSlice) Less(i, j int) bool {\n\tkeys := s.keys\n\tif s.keys == nil {\n\t\tkeys = s.values\n\t}\n\tok, err := Compare(syntax.LT, keys[i], keys[j])\n\tif err != nil {\n\t\ts.err = err\n\t}\n\treturn ok\n}\nfunc (s *sortSlice) Swap(i, j int) {\n\tif s.keys != nil {\n\t\ts.keys[i], s.keys[j] = s.keys[j], s.keys[i]\n\t}\n\ts.values[i], s.values[j] = s.values[j], s.values[i]\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#str\nfunc str(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(kwargs) > 0 {\n\t\treturn nil, fmt.Errorf(\"str does not accept keyword arguments\")\n\t}\n\tif len(args) != 1 {\n\t\treturn nil, fmt.Errorf(\"str: got %d arguments, want exactly 1\", len(args))\n\t}\n\tx := args[0]\n\tif _, ok := AsString(x); !ok {\n\t\tx = String(x.String())\n\t}\n\treturn x, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#tuple\nfunc tuple(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(\"tuple\", args, kwargs, 0, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\tif len(args) == 0 {\n\t\treturn Tuple(nil), nil\n\t}\n\titer := iterable.Iterate()\n\tdefer iter.Done()\n\tvar elems Tuple\n\tif n := Len(iterable); n > 0 {\n\t\telems = make(Tuple, 0, n) // preallocate if length is known\n\t}\n\tvar x Value\n\tfor iter.Next(&x) {\n\t\telems = append(elems, x)\n\t}\n\treturn elems, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#type\nfunc type_(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(kwargs) > 0 {\n\t\treturn nil, fmt.Errorf(\"type does not accept keyword arguments\")\n\t}\n\tif len(args) != 1 {\n\t\treturn nil, fmt.Errorf(\"type: got %d arguments, want exactly 1\", len(args))\n\t}\n\treturn String(args[0].Type()), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#zip\nfunc zip(thread *Thread, _ *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(kwargs) > 0 {\n\t\treturn nil, fmt.Errorf(\"zip does not accept keyword arguments\")\n\t}\n\trows, cols := 0, len(args)\n\titers := make([]Iterator, cols)\n\tdefer func() {\n\t\tfor _, iter := range iters {\n\t\t\tif iter != nil {\n\t\t\t\titer.Done()\n\t\t\t}\n\t\t}\n\t}()\n\tfor i, seq := range args {\n\t\tit := Iterate(seq)\n\t\tif it == nil {\n\t\t\treturn nil, fmt.Errorf(\"zip: argument #%d is not iterable: %s\", i+1, seq.Type())\n\t\t}\n\t\titers[i] = it\n\t\tn := Len(seq)\n\t\tif i == 0 || n < rows {\n\t\t\trows = n // possibly -1\n\t\t}\n\t}\n\tvar result []Value\n\tif rows >= 0 {\n\t\t// length known\n\t\tresult = make([]Value, rows)\n\t\tarray := make(Tuple, cols*rows) // allocate a single backing array\n\t\tfor i := 0; i < rows; i++ {\n\t\t\ttuple := array[:cols:cols]\n\t\t\tarray = array[cols:]\n\t\t\tfor j, iter := range iters {\n\t\t\t\titer.Next(&tuple[j])\n\t\t\t}\n\t\t\tresult[i] = tuple\n\t\t}\n\t} else {\n\t\t// length not known\n\touter:\n\t\tfor {\n\t\t\ttuple := make(Tuple, cols)\n\t\t\tfor i, iter := range iters {\n\t\t\t\tif !iter.Next(&tuple[i]) {\n\t\t\t\t\tbreak outer\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult = append(result, tuple)\n\t\t}\n\t}\n\treturn NewList(result), nil\n}\n\n// ---- methods of built-in types ---\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·get\nfunc dict_get(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar key, dflt Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &key, &dflt); err != nil {\n\t\treturn nil, err\n\t}\n\tif v, ok, err := b.Receiver().(*Dict).Get(key); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t} else if ok {\n\t\treturn v, nil\n\t} else if dflt != nil {\n\t\treturn dflt, nil\n\t}\n\treturn None, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·clear\nfunc dict_clear(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\treturn None, b.Receiver().(*Dict).Clear()\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·items\nfunc dict_items(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\titems := b.Receiver().(*Dict).Items()\n\tres := make([]Value, len(items))\n\tfor i, item := range items {\n\t\tres[i] = item // convert [2]Value to Value\n\t}\n\treturn NewList(res), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·keys\nfunc dict_keys(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\treturn NewList(b.Receiver().(*Dict).Keys()), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·pop\nfunc dict_pop(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar k, d Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &k, &d); err != nil {\n\t\treturn nil, err\n\t}\n\tif v, found, err := b.Receiver().(*Dict).Delete(k); err != nil {\n\t\treturn nil, nameErr(b, err) // dict is frozen or key is unhashable\n\t} else if found {\n\t\treturn v, nil\n\t} else if d != nil {\n\t\treturn d, nil\n\t}\n\treturn nil, nameErr(b, \"missing key\")\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·popitem\nfunc dict_popitem(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := b.Receiver().(*Dict)\n\tk, ok := recv.ht.first()\n\tif !ok {\n\t\treturn nil, nameErr(b, \"empty dict\")\n\t}\n\tv, _, err := recv.Delete(k)\n\tif err != nil {\n\t\treturn nil, nameErr(b, err) // dict is frozen\n\t}\n\treturn Tuple{k, v}, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·setdefault\nfunc dict_setdefault(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar key, dflt Value = nil, None\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &key, &dflt); err != nil {\n\t\treturn nil, err\n\t}\n\tdict := b.Receiver().(*Dict)\n\tif v, ok, err := dict.Get(key); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t} else if ok {\n\t\treturn v, nil\n\t} else if err := dict.SetKey(key, dflt); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t} else {\n\t\treturn dflt, nil\n\t}\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·update\nfunc dict_update(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif len(args) > 1 {\n\t\treturn nil, fmt.Errorf(\"update: got %d arguments, want at most 1\", len(args))\n\t}\n\tif err := updateDict(b.Receiver().(*Dict), args, kwargs); err != nil {\n\t\treturn nil, fmt.Errorf(\"update: %v\", err)\n\t}\n\treturn None, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#dict·update\nfunc dict_values(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\titems := b.Receiver().(*Dict).Items()\n\tres := make([]Value, len(items))\n\tfor i, item := range items {\n\t\tres[i] = item[1]\n\t}\n\treturn NewList(res), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·append\nfunc list_append(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar object Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &object); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := b.Receiver().(*List)\n\tif err := recv.checkMutable(\"append to\"); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\trecv.elems = append(recv.elems, object)\n\treturn None, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·clear\nfunc list_clear(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := b.Receiver().(*List).Clear(); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\treturn None, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·extend\nfunc list_extend(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := b.Receiver().(*List)\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := recv.checkMutable(\"extend\"); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\tlistExtend(recv, iterable)\n\treturn None, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·index\nfunc list_index(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar value, start_, end_ Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &value, &start_, &end_); err != nil {\n\t\treturn nil, err\n\t}\n\n\trecv := b.Receiver().(*List)\n\tstart, end, err := indices(start_, end_, recv.Len())\n\tif err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\n\tfor i := start; i < end; i++ {\n\t\tif eq, err := Equal(recv.elems[i], value); err != nil {\n\t\t\treturn nil, nameErr(b, err)\n\t\t} else if eq {\n\t\t\treturn MakeInt(i), nil\n\t\t}\n\t}\n\treturn nil, nameErr(b, \"value not in list\")\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·insert\nfunc list_insert(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := b.Receiver().(*List)\n\tvar index int\n\tvar object Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 2, &index, &object); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := recv.checkMutable(\"insert into\"); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\n\tif index < 0 {\n\t\tindex += recv.Len()\n\t}\n\n\tif index >= recv.Len() {\n\t\t// end\n\t\trecv.elems = append(recv.elems, object)\n\t} else {\n\t\tif index < 0 {\n\t\t\tindex = 0 // start\n\t\t}\n\t\trecv.elems = append(recv.elems, nil)\n\t\tcopy(recv.elems[index+1:], recv.elems[index:]) // slide up one\n\t\trecv.elems[index] = object\n\t}\n\treturn None, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·remove\nfunc list_remove(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := b.Receiver().(*List)\n\tvar value Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &value); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := recv.checkMutable(\"remove from\"); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\tfor i, elem := range recv.elems {\n\t\tif eq, err := Equal(elem, value); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"remove: %v\", err)\n\t\t} else if eq {\n\t\t\trecv.elems = append(recv.elems[:i], recv.elems[i+1:]...)\n\t\t\treturn None, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"remove: element not found\")\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#list·pop\nfunc list_pop(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := b.Receiver()\n\tlist := recv.(*List)\n\tn := list.Len()\n\ti := n - 1\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &i); err != nil {\n\t\treturn nil, err\n\t}\n\torigI := i\n\tif i < 0 {\n\t\ti += n\n\t}\n\tif i < 0 || i >= n {\n\t\treturn nil, nameErr(b, outOfRange(origI, n, list))\n\t}\n\tif err := list.checkMutable(\"pop from\"); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\tres := list.elems[i]\n\tlist.elems = append(list.elems[:i], list.elems[i+1:]...)\n\treturn res, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·capitalize\nfunc string_capitalize(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\ts := string(b.Receiver().(String))\n\tres := new(strings.Builder)\n\tres.Grow(len(s))\n\tfor i, r := range s {\n\t\tif i == 0 {\n\t\t\tr = unicode.ToTitle(r)\n\t\t} else {\n\t\t\tr = unicode.ToLower(r)\n\t\t}\n\t\tres.WriteRune(r)\n\t}\n\treturn String(res.String()), nil\n}\n\n// string_iterable returns an unspecified iterable value whose iterator yields:\n// - elems: successive 1-byte substrings\n// - codepoints: successive substrings that encode a single Unicode code point.\n// - elem_ords: numeric values of successive bytes\n// - codepoint_ords: numeric values of successive Unicode code points\nfunc string_iterable(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\treturn stringIterable{\n\t\ts:          b.Receiver().(String),\n\t\tords:       b.Name()[len(b.Name())-2] == 'd',\n\t\tcodepoints: b.Name()[0] == 'c',\n\t}, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·count\nfunc string_count(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar sub string\n\tvar start_, end_ Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &sub, &start_, &end_); err != nil {\n\t\treturn nil, err\n\t}\n\n\trecv := string(b.Receiver().(String))\n\tstart, end, err := indices(start_, end_, len(recv))\n\tif err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\n\tvar slice string\n\tif start < end {\n\t\tslice = recv[start:end]\n\t}\n\treturn MakeInt(strings.Count(slice, sub)), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isalnum\nfunc string_isalnum(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\tfor _, r := range recv {\n\t\tif !unicode.IsLetter(r) && !unicode.IsDigit(r) {\n\t\t\treturn False, nil\n\t\t}\n\t}\n\treturn Bool(recv != \"\"), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isalpha\nfunc string_isalpha(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\tfor _, r := range recv {\n\t\tif !unicode.IsLetter(r) {\n\t\t\treturn False, nil\n\t\t}\n\t}\n\treturn Bool(recv != \"\"), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isdigit\nfunc string_isdigit(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\tfor _, r := range recv {\n\t\tif !unicode.IsDigit(r) {\n\t\t\treturn False, nil\n\t\t}\n\t}\n\treturn Bool(recv != \"\"), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·islower\nfunc string_islower(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\treturn Bool(isCasedString(recv) && recv == strings.ToLower(recv)), nil\n}\n\n// isCasedString reports whether its argument contains any cased code points.\nfunc isCasedString(s string) bool {\n\tfor _, r := range s {\n\t\tif isCasedRune(r) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isCasedRune(r rune) bool {\n\t// It's unclear what the correct behavior is for a rune such as 'ﬃ',\n\t// a lowercase letter with no upper or title case and no SimpleFold.\n\treturn 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || unicode.SimpleFold(r) != r\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isspace\nfunc string_isspace(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\tfor _, r := range recv {\n\t\tif !unicode.IsSpace(r) {\n\t\t\treturn False, nil\n\t\t}\n\t}\n\treturn Bool(recv != \"\"), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·istitle\nfunc string_istitle(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\n\t// Python semantics differ from x==strings.{To,}Title(x) in Go:\n\t// \"uppercase characters may only follow uncased characters and\n\t// lowercase characters only cased ones.\"\n\tvar cased, prevCased bool\n\tfor _, r := range recv {\n\t\tif 'A' <= r && r <= 'Z' || unicode.IsTitle(r) { // e.g. \"ǅ\"\n\t\t\tif prevCased {\n\t\t\t\treturn False, nil\n\t\t\t}\n\t\t\tprevCased = true\n\t\t\tcased = true\n\t\t} else if unicode.IsLower(r) {\n\t\t\tif !prevCased {\n\t\t\t\treturn False, nil\n\t\t\t}\n\t\t\tprevCased = true\n\t\t\tcased = true\n\t\t} else if unicode.IsUpper(r) {\n\t\t\treturn False, nil\n\t\t} else {\n\t\t\tprevCased = false\n\t\t}\n\t}\n\treturn Bool(cased), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·isupper\nfunc string_isupper(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\treturn Bool(isCasedString(recv) && recv == strings.ToUpper(recv)), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·find\nfunc string_find(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\treturn string_find_impl(b, args, kwargs, true, false)\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·format\nfunc string_format(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tformat := string(b.Receiver().(String))\n\tvar auto, manual bool // kinds of positional indexing used\n\tbuf := new(strings.Builder)\n\tindex := 0\n\tfor {\n\t\tliteral := format\n\t\ti := strings.IndexByte(format, '{')\n\t\tif i >= 0 {\n\t\t\tliteral = format[:i]\n\t\t}\n\n\t\t// Replace \"}}\" with \"}\" in non-field portion, rejecting a lone '}'.\n\t\tfor {\n\t\t\tj := strings.IndexByte(literal, '}')\n\t\t\tif j < 0 {\n\t\t\t\tbuf.WriteString(literal)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif len(literal) == j+1 || literal[j+1] != '}' {\n\t\t\t\treturn nil, fmt.Errorf(\"format: single '}' in format\")\n\t\t\t}\n\t\t\tbuf.WriteString(literal[:j+1])\n\t\t\tliteral = literal[j+2:]\n\t\t}\n\n\t\tif i < 0 {\n\t\t\tbreak // end of format string\n\t\t}\n\n\t\tif i+1 < len(format) && format[i+1] == '{' {\n\t\t\t// \"{{\" means a literal '{'\n\t\t\tbuf.WriteByte('{')\n\t\t\tformat = format[i+2:]\n\t\t\tcontinue\n\t\t}\n\n\t\tformat = format[i+1:]\n\t\ti = strings.IndexByte(format, '}')\n\t\tif i < 0 {\n\t\t\treturn nil, fmt.Errorf(\"format: unmatched '{' in format\")\n\t\t}\n\n\t\tvar arg Value\n\t\tconv := \"s\"\n\t\tvar spec string\n\n\t\tfield := format[:i]\n\t\tformat = format[i+1:]\n\n\t\tvar name string\n\t\tif i := strings.IndexByte(field, '!'); i < 0 {\n\t\t\t// \"name\" or \"name:spec\"\n\t\t\tif i := strings.IndexByte(field, ':'); i < 0 {\n\t\t\t\tname = field\n\t\t\t} else {\n\t\t\t\tname = field[:i]\n\t\t\t\tspec = field[i+1:]\n\t\t\t}\n\t\t} else {\n\t\t\t// \"name!conv\" or \"name!conv:spec\"\n\t\t\tname = field[:i]\n\t\t\tfield = field[i+1:]\n\t\t\t// \"conv\" or \"conv:spec\"\n\t\t\tif i := strings.IndexByte(field, ':'); i < 0 {\n\t\t\t\tconv = field\n\t\t\t} else {\n\t\t\t\tconv = field[:i]\n\t\t\t\tspec = field[i+1:]\n\t\t\t}\n\t\t}\n\n\t\tif name == \"\" {\n\t\t\t// \"{}\": automatic indexing\n\t\t\tif manual {\n\t\t\t\treturn nil, fmt.Errorf(\"format: cannot switch from manual field specification to automatic field numbering\")\n\t\t\t}\n\t\t\tauto = true\n\t\t\tif index >= len(args) {\n\t\t\t\treturn nil, fmt.Errorf(\"format: tuple index out of range\")\n\t\t\t}\n\t\t\targ = args[index]\n\t\t\tindex++\n\t\t} else if num, ok := decimal(name); ok {\n\t\t\t// positional argument\n\t\t\tif auto {\n\t\t\t\treturn nil, fmt.Errorf(\"format: cannot switch from automatic field numbering to manual field specification\")\n\t\t\t}\n\t\t\tmanual = true\n\t\t\tif num >= len(args) {\n\t\t\t\treturn nil, fmt.Errorf(\"format: tuple index out of range\")\n\t\t\t} else {\n\t\t\t\targ = args[num]\n\t\t\t}\n\t\t} else {\n\t\t\t// keyword argument\n\t\t\tfor _, kv := range kwargs {\n\t\t\t\tif string(kv[0].(String)) == name {\n\t\t\t\t\targ = kv[1]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif arg == nil {\n\t\t\t\t// Starlark does not support Python's x.y or a[i] syntaxes,\n\t\t\t\t// or nested use of {...}.\n\t\t\t\tif strings.Contains(name, \".\") {\n\t\t\t\t\treturn nil, fmt.Errorf(\"format: attribute syntax x.y is not supported in replacement fields: %s\", name)\n\t\t\t\t}\n\t\t\t\tif strings.Contains(name, \"[\") {\n\t\t\t\t\treturn nil, fmt.Errorf(\"format: element syntax a[i] is not supported in replacement fields: %s\", name)\n\t\t\t\t}\n\t\t\t\tif strings.Contains(name, \"{\") {\n\t\t\t\t\treturn nil, fmt.Errorf(\"format: nested replacement fields not supported\")\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"format: keyword %s not found\", name)\n\t\t\t}\n\t\t}\n\n\t\tif spec != \"\" {\n\t\t\t// Starlark does not support Python's format_spec features.\n\t\t\treturn nil, fmt.Errorf(\"format spec features not supported in replacement fields: %s\", spec)\n\t\t}\n\n\t\tswitch conv {\n\t\tcase \"s\":\n\t\t\tif str, ok := AsString(arg); ok {\n\t\t\t\tbuf.WriteString(str)\n\t\t\t} else {\n\t\t\t\twriteValue(buf, arg, nil)\n\t\t\t}\n\t\tcase \"r\":\n\t\t\twriteValue(buf, arg, nil)\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"format: unknown conversion %q\", conv)\n\t\t}\n\t}\n\treturn String(buf.String()), nil\n}\n\n// decimal interprets s as a sequence of decimal digits.\nfunc decimal(s string) (x int, ok bool) {\n\tn := len(s)\n\tfor i := 0; i < n; i++ {\n\t\tdigit := s[i] - '0'\n\t\tif digit > 9 {\n\t\t\treturn 0, false\n\t\t}\n\t\tx = x*10 + int(digit)\n\t\tif x < 0 {\n\t\t\treturn 0, false // underflow\n\t\t}\n\t}\n\treturn x, true\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·index\nfunc string_index(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\treturn string_find_impl(b, args, kwargs, false, false)\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·join\nfunc string_join(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := string(b.Receiver().(String))\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\titer := iterable.Iterate()\n\tdefer iter.Done()\n\tbuf := new(strings.Builder)\n\tvar x Value\n\tfor i := 0; iter.Next(&x); i++ {\n\t\tif i > 0 {\n\t\t\tbuf.WriteString(recv)\n\t\t}\n\t\ts, ok := AsString(x)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"join: in list, want string, got %s\", x.Type())\n\t\t}\n\t\tbuf.WriteString(s)\n\t}\n\treturn String(buf.String()), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·lower\nfunc string_lower(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\treturn String(strings.ToLower(string(b.Receiver().(String)))), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·partition\nfunc string_partition(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := string(b.Receiver().(String))\n\tvar sep string\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &sep); err != nil {\n\t\treturn nil, err\n\t}\n\tif sep == \"\" {\n\t\treturn nil, nameErr(b, \"empty separator\")\n\t}\n\tvar i int\n\tif b.Name()[0] == 'p' {\n\t\ti = strings.Index(recv, sep) // partition\n\t} else {\n\t\ti = strings.LastIndex(recv, sep) // rpartition\n\t}\n\ttuple := make(Tuple, 0, 3)\n\tif i < 0 {\n\t\tif b.Name()[0] == 'p' {\n\t\t\ttuple = append(tuple, String(recv), String(\"\"), String(\"\"))\n\t\t} else {\n\t\t\ttuple = append(tuple, String(\"\"), String(\"\"), String(recv))\n\t\t}\n\t} else {\n\t\ttuple = append(tuple, String(recv[:i]), String(sep), String(recv[i+len(sep):]))\n\t}\n\treturn tuple, nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·replace\nfunc string_replace(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := string(b.Receiver().(String))\n\tvar old, new string\n\tcount := -1\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 2, &old, &new, &count); err != nil {\n\t\treturn nil, err\n\t}\n\treturn String(strings.Replace(recv, old, new, count)), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rfind\nfunc string_rfind(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\treturn string_find_impl(b, args, kwargs, true, true)\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rindex\nfunc string_rindex(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\treturn string_find_impl(b, args, kwargs, false, true)\n}\n\n// https://github.com/google/starlark-go/starlark/blob/master/doc/spec.md#string·startswith\n// https://github.com/google/starlark-go/starlark/blob/master/doc/spec.md#string·endswith\nfunc string_startswith(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar x Value\n\tvar start, end Value = None, None\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &x, &start, &end); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// compute effective substring.\n\ts := string(b.Receiver().(String))\n\tif start, end, err := indices(start, end, len(s)); err != nil {\n\t\treturn nil, nameErr(b, err)\n\t} else {\n\t\tif end < start {\n\t\t\tend = start // => empty result\n\t\t}\n\t\ts = s[start:end]\n\t}\n\n\tf := strings.HasPrefix\n\tif b.Name()[0] == 'e' { // endswith\n\t\tf = strings.HasSuffix\n\t}\n\n\tswitch x := x.(type) {\n\tcase Tuple:\n\t\tfor i, x := range x {\n\t\t\tprefix, ok := AsString(x)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"%s: want string, got %s, for element %d\",\n\t\t\t\t\tb.Name(), x.Type(), i)\n\t\t\t}\n\t\t\tif f(s, prefix) {\n\t\t\t\treturn True, nil\n\t\t\t}\n\t\t}\n\t\treturn False, nil\n\tcase String:\n\t\treturn Bool(f(s, string(x))), nil\n\t}\n\treturn nil, fmt.Errorf(\"%s: got %s, want string or tuple of string\", b.Name(), x.Type())\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·strip\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·lstrip\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rstrip\nfunc string_strip(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar chars string\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &chars); err != nil {\n\t\treturn nil, err\n\t}\n\trecv := string(b.Receiver().(String))\n\tvar s string\n\tswitch b.Name()[0] {\n\tcase 's': // strip\n\t\tif chars != \"\" {\n\t\t\ts = strings.Trim(recv, chars)\n\t\t} else {\n\t\t\ts = strings.TrimSpace(recv)\n\t\t}\n\tcase 'l': // lstrip\n\t\tif chars != \"\" {\n\t\t\ts = strings.TrimLeft(recv, chars)\n\t\t} else {\n\t\t\ts = strings.TrimLeftFunc(recv, unicode.IsSpace)\n\t\t}\n\tcase 'r': // rstrip\n\t\tif chars != \"\" {\n\t\t\ts = strings.TrimRight(recv, chars)\n\t\t} else {\n\t\t\ts = strings.TrimRightFunc(recv, unicode.IsSpace)\n\t\t}\n\t}\n\treturn String(s), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·title\nfunc string_title(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\n\ts := string(b.Receiver().(String))\n\n\t// Python semantics differ from x==strings.{To,}Title(x) in Go:\n\t// \"uppercase characters may only follow uncased characters and\n\t// lowercase characters only cased ones.\"\n\tbuf := new(strings.Builder)\n\tbuf.Grow(len(s))\n\tvar prevCased bool\n\tfor _, r := range s {\n\t\tif prevCased {\n\t\t\tr = unicode.ToLower(r)\n\t\t} else {\n\t\t\tr = unicode.ToTitle(r)\n\t\t}\n\t\tprevCased = isCasedRune(r)\n\t\tbuf.WriteRune(r)\n\t}\n\treturn String(buf.String()), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·upper\nfunc string_upper(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0); err != nil {\n\t\treturn nil, err\n\t}\n\treturn String(strings.ToUpper(string(b.Receiver().(String)))), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·split\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·rsplit\nfunc string_split(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\trecv := string(b.Receiver().(String))\n\tvar sep_ Value\n\tmaxsplit := -1\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &sep_, &maxsplit); err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar res []string\n\n\tif sep_ == nil || sep_ == None {\n\t\t// special case: split on whitespace\n\t\tif maxsplit < 0 {\n\t\t\tres = strings.Fields(recv)\n\t\t} else if b.Name() == \"split\" {\n\t\t\tres = splitspace(recv, maxsplit)\n\t\t} else { // rsplit\n\t\t\tres = rsplitspace(recv, maxsplit)\n\t\t}\n\n\t} else if sep, ok := AsString(sep_); ok {\n\t\tif sep == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"split: empty separator\")\n\t\t}\n\t\t// usual case: split on non-empty separator\n\t\tif maxsplit < 0 {\n\t\t\tres = strings.Split(recv, sep)\n\t\t} else if b.Name() == \"split\" {\n\t\t\tres = strings.SplitN(recv, sep, maxsplit+1)\n\t\t} else { // rsplit\n\t\t\tres = strings.Split(recv, sep)\n\t\t\tif excess := len(res) - maxsplit; excess > 0 {\n\t\t\t\tres[0] = strings.Join(res[:excess], sep)\n\t\t\t\tres = append(res[:1], res[excess:]...)\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\treturn nil, fmt.Errorf(\"split: got %s for separator, want string\", sep_.Type())\n\t}\n\n\tlist := make([]Value, len(res))\n\tfor i, x := range res {\n\t\tlist[i] = String(x)\n\t}\n\treturn NewList(list), nil\n}\n\n// Precondition: max >= 0.\nfunc rsplitspace(s string, max int) []string {\n\tres := make([]string, 0, max+1)\n\tend := -1 // index of field end, or -1 in a region of spaces.\n\tfor i := len(s); i > 0; {\n\t\tr, sz := utf8.DecodeLastRuneInString(s[:i])\n\t\tif unicode.IsSpace(r) {\n\t\t\tif end >= 0 {\n\t\t\t\tif len(res) == max {\n\t\t\t\t\tbreak // let this field run to the start\n\t\t\t\t}\n\t\t\t\tres = append(res, s[i:end])\n\t\t\t\tend = -1\n\t\t\t}\n\t\t} else if end < 0 {\n\t\t\tend = i\n\t\t}\n\t\ti -= sz\n\t}\n\tif end >= 0 {\n\t\tres = append(res, s[:end])\n\t}\n\n\tresLen := len(res)\n\tfor i := 0; i < resLen/2; i++ {\n\t\tres[i], res[resLen-1-i] = res[resLen-1-i], res[i]\n\t}\n\n\treturn res\n}\n\n// Precondition: max >= 0.\nfunc splitspace(s string, max int) []string {\n\tvar res []string\n\tstart := -1 // index of field start, or -1 in a region of spaces\n\tfor i, r := range s {\n\t\tif unicode.IsSpace(r) {\n\t\t\tif start >= 0 {\n\t\t\t\tif len(res) == max {\n\t\t\t\t\tbreak // let this field run to the end\n\t\t\t\t}\n\t\t\t\tres = append(res, s[start:i])\n\t\t\t\tstart = -1\n\t\t\t}\n\t\t} else if start == -1 {\n\t\t\tstart = i\n\t\t}\n\t}\n\tif start >= 0 {\n\t\tres = append(res, s[start:])\n\t}\n\treturn res\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#string·splitlines\nfunc string_splitlines(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar keepends bool\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &keepends); err != nil {\n\t\treturn nil, err\n\t}\n\tvar lines []string\n\tif s := string(b.Receiver().(String)); s != \"\" {\n\t\t// TODO(adonovan): handle CRLF correctly.\n\t\tif keepends {\n\t\t\tlines = strings.SplitAfter(s, \"\\n\")\n\t\t} else {\n\t\t\tlines = strings.Split(s, \"\\n\")\n\t\t}\n\t\tif strings.HasSuffix(s, \"\\n\") {\n\t\t\tlines = lines[:len(lines)-1]\n\t\t}\n\t}\n\tlist := make([]Value, len(lines))\n\tfor i, x := range lines {\n\t\tlist[i] = String(x)\n\t}\n\treturn NewList(list), nil\n}\n\n// https://github.com/google/starlark-go/blob/master/doc/spec.md#set·union.\nfunc set_union(_ *Thread, b *Builtin, args Tuple, kwargs []Tuple) (Value, error) {\n\tvar iterable Iterable\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 0, &iterable); err != nil {\n\t\treturn nil, err\n\t}\n\titer := iterable.Iterate()\n\tdefer iter.Done()\n\tunion, err := b.Receiver().(*Set).Union(iter)\n\tif err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\treturn union, nil\n}\n\n// Common implementation of string_{r}{find,index}.\nfunc string_find_impl(b *Builtin, args Tuple, kwargs []Tuple, allowError, last bool) (Value, error) {\n\tvar sub string\n\tvar start_, end_ Value\n\tif err := UnpackPositionalArgs(b.Name(), args, kwargs, 1, &sub, &start_, &end_); err != nil {\n\t\treturn nil, err\n\t}\n\n\ts := string(b.Receiver().(String))\n\tstart, end, err := indices(start_, end_, len(s))\n\tif err != nil {\n\t\treturn nil, nameErr(b, err)\n\t}\n\tvar slice string\n\tif start < end {\n\t\tslice = s[start:end]\n\t}\n\n\tvar i int\n\tif last {\n\t\ti = strings.LastIndex(slice, sub)\n\t} else {\n\t\ti = strings.Index(slice, sub)\n\t}\n\tif i < 0 {\n\t\tif !allowError {\n\t\t\treturn nil, nameErr(b, \"substring not found\")\n\t\t}\n\t\treturn MakeInt(-1), nil\n\t}\n\treturn MakeInt(i + start), nil\n}\n\n// Common implementation of builtin dict function and dict.update method.\n// Precondition: len(updates) == 0 or 1.\nfunc updateDict(dict *Dict, updates Tuple, kwargs []Tuple) error {\n\tif len(updates) == 1 {\n\t\tswitch updates := updates[0].(type) {\n\t\tcase IterableMapping:\n\t\t\t// Iterate over dict's key/value pairs, not just keys.\n\t\t\tfor _, item := range updates.Items() {\n\t\t\t\tif err := dict.SetKey(item[0], item[1]); err != nil {\n\t\t\t\t\treturn err // dict is frozen\n\t\t\t\t}\n\t\t\t}\n\t\tdefault:\n\t\t\t// all other sequences\n\t\t\titer := Iterate(updates)\n\t\t\tif iter == nil {\n\t\t\t\treturn fmt.Errorf(\"got %s, want iterable\", updates.Type())\n\t\t\t}\n\t\t\tdefer iter.Done()\n\t\t\tvar pair Value\n\t\t\tfor i := 0; iter.Next(&pair); i++ {\n\t\t\t\titer2 := Iterate(pair)\n\t\t\t\tif iter2 == nil {\n\t\t\t\t\treturn fmt.Errorf(\"dictionary update sequence element #%d is not iterable (%s)\", i, pair.Type())\n\n\t\t\t\t}\n\t\t\t\tdefer iter2.Done()\n\t\t\t\tlen := Len(pair)\n\t\t\t\tif len < 0 {\n\t\t\t\t\treturn fmt.Errorf(\"dictionary update sequence element #%d has unknown length (%s)\", i, pair.Type())\n\t\t\t\t} else if len != 2 {\n\t\t\t\t\treturn fmt.Errorf(\"dictionary update sequence element #%d has length %d, want 2\", i, len)\n\t\t\t\t}\n\t\t\t\tvar k, v Value\n\t\t\t\titer2.Next(&k)\n\t\t\t\titer2.Next(&v)\n\t\t\t\tif err := dict.SetKey(k, v); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Then add the kwargs.\n\tbefore := dict.Len()\n\tfor _, pair := range kwargs {\n\t\tif err := dict.SetKey(pair[0], pair[1]); err != nil {\n\t\t\treturn err // dict is frozen\n\t\t}\n\t}\n\t// In the common case, each kwarg will add another dict entry.\n\t// If that's not so, check whether it is because there was a duplicate kwarg.\n\tif dict.Len() < before+len(kwargs) {\n\t\tkeys := make(map[String]bool, len(kwargs))\n\t\tfor _, kv := range kwargs {\n\t\t\tk := kv[0].(String)\n\t\t\tif keys[k] {\n\t\t\t\treturn fmt.Errorf(\"duplicate keyword arg: %v\", k)\n\t\t\t}\n\t\t\tkeys[k] = true\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// nameErr returns an error message of the form \"name: msg\"\n// where name is b.Name() and msg is a string or error.\nfunc nameErr(b *Builtin, msg interface{}) error {\n\treturn fmt.Errorf(\"%s: %v\", b.Name(), msg)\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/profile.go",
    "content": "// Copyright 2019 The Bazel 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 starlark\n\n// This file defines a simple execution-time profiler for Starlark.\n// It measures the wall time spent executing Starlark code, and emits a\n// gzipped protocol message in pprof format (github.com/google/pprof).\n//\n// When profiling is enabled, the interpreter calls the profiler to\n// indicate the start and end of each \"span\" or time interval. A leaf\n// function (whether Go or Starlark) has a single span. A function that\n// calls another function has spans for each interval in which it is the\n// top of the stack. (A LOAD instruction also ends a span.)\n//\n// At the start of a span, the interpreter records the current time in\n// the thread's topmost frame. At the end of the span, it obtains the\n// time again and subtracts the span start time. The difference is added\n// to an accumulator variable in the thread. If the accumulator exceeds\n// some fixed quantum (10ms, say), the profiler records the current call\n// stack and sends it to the profiler goroutine, along with the number\n// of quanta, which are subtracted. For example, if the accumulator\n// holds 3ms and then a completed span adds 25ms to it, its value is 28ms,\n// which exceeeds 10ms. The profiler records a stack with the value 20ms\n// (2 quanta), and the accumulator is left with 8ms.\n//\n// The profiler goroutine converts the stacks into the pprof format and\n// emits a gzip-compressed protocol message to the designated output\n// file. We use a hand-written streaming proto encoder to avoid\n// dependencies on pprof and proto, and to avoid the need to\n// materialize the profile data structure in memory.\n//\n// A limitation of this profiler is that it measures wall time, which\n// does not necessarily correspond to CPU time. A CPU profiler requires\n// that only running (not runnable) threads are sampled; this is\n// commonly achieved by having the kernel deliver a (PROF) signal to an\n// arbitrary running thread, through setitimer(2). The CPU profiler in the\n// Go runtime uses this mechanism, but it is not possible for a Go\n// application to register a SIGPROF handler, nor is it possible for a\n// Go handler for some other signal to read the stack pointer of\n// the interrupted thread.\n//\n// Two caveats:\n// (1) it is tempting to send the leaf Frame directly to the profiler\n// goroutine instead of making a copy of the stack, since a Frame is a\n// spaghetti stack--a linked list. However, as soon as execution\n// resumes, the stack's Frame.pc values may be mutated, so Frames are\n// not safe to share with the asynchronous profiler goroutine.\n// (2) it is tempting to use Callables as keys in a map when tabulating\n// the pprof protocols's Function entities. However, we cannot assume\n// that Callables are valid map keys, and furthermore we must not\n// pin function values in memory indefinitely as this may cause lambda\n// values to keep their free variables live much longer than necessary.\n\n// TODO(adonovan):\n// - make Start/Stop fully thread-safe.\n// - fix the pc hack.\n// - experiment with other values of quantum.\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"reflect\"\n\t\"sync/atomic\"\n\t\"time\"\n\t\"unsafe\"\n\n\t\"go.starlark.net/syntax\"\n)\n\n// StartProfile enables time profiling of all Starlark threads,\n// and writes a profile in pprof format to w.\n// It must be followed by a call to StopProfiler to stop\n// the profiler and finalize the profile.\n//\n// StartProfile returns an error if profiling was already enabled.\n//\n// StartProfile must not be called concurrently with Starlark execution.\nfunc StartProfile(w io.Writer) error {\n\tif !atomic.CompareAndSwapUint32(&profiler.on, 0, 1) {\n\t\treturn fmt.Errorf(\"profiler already running\")\n\t}\n\n\t// TODO(adonovan): make the API fully concurrency-safe.\n\t// The main challenge is racy reads/writes of profiler.events,\n\t// and of send/close races on the channel it refers to.\n\t// It's easy to solve them with a mutex but harder to do\n\t// it efficiently.\n\n\tprofiler.events = make(chan *profEvent, 1)\n\tprofiler.done = make(chan error)\n\n\tgo profile(w)\n\n\treturn nil\n}\n\n// StopProfiler stops the profiler started by a prior call to\n// StartProfile and finalizes the profile. It returns an error if the\n// profile could not be completed.\n//\n// StopProfiler must not be called concurrently with Starlark execution.\nfunc StopProfile() error {\n\t// Terminate the profiler goroutine and get its result.\n\tclose(profiler.events)\n\terr := <-profiler.done\n\n\tprofiler.done = nil\n\tprofiler.events = nil\n\tatomic.StoreUint32(&profiler.on, 0)\n\n\treturn err\n}\n\n// globals\nvar profiler struct {\n\ton     uint32          // nonzero => profiler running\n\tevents chan *profEvent // profile events from interpreter threads\n\tdone   chan error      // indicates profiler goroutine is ready\n}\n\nfunc (thread *Thread) beginProfSpan() {\n\tif profiler.events == nil {\n\t\treturn // profiling not enabled\n\t}\n\n\tthread.frameAt(0).spanStart = nanotime()\n}\n\n// TODO(adonovan): experiment with smaller values,\n// which trade space and time for greater precision.\nconst quantum = 10 * time.Millisecond\n\nfunc (thread *Thread) endProfSpan() {\n\tif profiler.events == nil {\n\t\treturn // profiling not enabled\n\t}\n\n\t// Add the span to the thread's accumulator.\n\tthread.proftime += time.Duration(nanotime() - thread.frameAt(0).spanStart)\n\tif thread.proftime < quantum {\n\t\treturn\n\t}\n\n\t// Only record complete quanta.\n\tn := thread.proftime / quantum\n\tthread.proftime -= n * quantum\n\n\t// Copy the stack.\n\t// (We can't save thread.frame because its pc will change.)\n\tev := &profEvent{\n\t\tthread: thread,\n\t\ttime:   n * quantum,\n\t}\n\tev.stack = ev.stackSpace[:0]\n\tfor i := range thread.stack {\n\t\tfr := thread.frameAt(i)\n\t\tev.stack = append(ev.stack, profFrame{\n\t\t\tpos: fr.Position(),\n\t\t\tfn:  fr.Callable(),\n\t\t\tpc:  fr.pc,\n\t\t})\n\t}\n\n\tprofiler.events <- ev\n}\n\ntype profEvent struct {\n\tthread     *Thread // currently unused\n\ttime       time.Duration\n\tstack      []profFrame\n\tstackSpace [8]profFrame // initial space for stack\n}\n\ntype profFrame struct {\n\tfn  Callable        // don't hold this live for too long (prevents GC of lambdas)\n\tpc  uint32          // program counter (Starlark frames only)\n\tpos syntax.Position // position of pc within this frame\n}\n\n// profile is the profiler goroutine.\n// It runs until StopProfiler is called.\nfunc profile(w io.Writer) {\n\t// Field numbers from pprof protocol.\n\t// See https://github.com/google/pprof/blob/master/proto/profile.proto\n\tconst (\n\t\tProfile_sample_type    = 1  // repeated ValueType\n\t\tProfile_sample         = 2  // repeated Sample\n\t\tProfile_mapping        = 3  // repeated Mapping\n\t\tProfile_location       = 4  // repeated Location\n\t\tProfile_function       = 5  // repeated Function\n\t\tProfile_string_table   = 6  // repeated string\n\t\tProfile_time_nanos     = 9  // int64\n\t\tProfile_duration_nanos = 10 // int64\n\t\tProfile_period_type    = 11 // ValueType\n\t\tProfile_period         = 12 // int64\n\n\t\tValueType_type = 1 // int64\n\t\tValueType_unit = 2 // int64\n\n\t\tSample_location_id = 1 // repeated uint64\n\t\tSample_value       = 2 // repeated int64\n\t\tSample_label       = 3 // repeated Label\n\n\t\tLabel_key      = 1 // int64\n\t\tLabel_str      = 2 // int64\n\t\tLabel_num      = 3 // int64\n\t\tLabel_num_unit = 4 // int64\n\n\t\tLocation_id         = 1 // uint64\n\t\tLocation_mapping_id = 2 // uint64\n\t\tLocation_address    = 3 // uint64\n\t\tLocation_line       = 4 // repeated Line\n\n\t\tLine_function_id = 1 // uint64\n\t\tLine_line        = 2 // int64\n\n\t\tFunction_id          = 1 // uint64\n\t\tFunction_name        = 2 // int64\n\t\tFunction_system_name = 3 // int64\n\t\tFunction_filename    = 4 // int64\n\t\tFunction_start_line  = 5 // int64\n\t)\n\n\tbufw := bufio.NewWriter(w) // write file in 4KB (not 240B flate-sized) chunks\n\tgz := gzip.NewWriter(bufw)\n\tenc := protoEncoder{w: gz}\n\n\t// strings\n\tstringIndex := make(map[string]int64)\n\tstr := func(s string) int64 {\n\t\ti, ok := stringIndex[s]\n\t\tif !ok {\n\t\t\ti = int64(len(stringIndex))\n\t\t\tenc.string(Profile_string_table, s)\n\t\t\tstringIndex[s] = i\n\t\t}\n\t\treturn i\n\t}\n\tstr(\"\") // entry 0\n\n\t// functions\n\t//\n\t// function returns the ID of a Callable for use in Line.FunctionId.\n\t// The ID is the same as the function's logical address,\n\t// which is supplied by the caller to avoid the need to recompute it.\n\tfunctionId := make(map[uintptr]uint64)\n\tfunction := func(fn Callable, addr uintptr) uint64 {\n\t\tid, ok := functionId[addr]\n\t\tif !ok {\n\t\t\tid = uint64(addr)\n\n\t\t\tvar pos syntax.Position\n\t\t\tif fn, ok := fn.(callableWithPosition); ok {\n\t\t\t\tpos = fn.Position()\n\t\t\t}\n\n\t\t\tname := fn.Name()\n\t\t\tif name == \"<toplevel>\" {\n\t\t\t\tname = pos.Filename()\n\t\t\t}\n\n\t\t\tnameIndex := str(name)\n\n\t\t\tfun := new(bytes.Buffer)\n\t\t\tfunenc := protoEncoder{w: fun}\n\t\t\tfunenc.uint(Function_id, id)\n\t\t\tfunenc.int(Function_name, nameIndex)\n\t\t\tfunenc.int(Function_system_name, nameIndex)\n\t\t\tfunenc.int(Function_filename, str(pos.Filename()))\n\t\t\tfunenc.int(Function_start_line, int64(pos.Line))\n\t\t\tenc.bytes(Profile_function, fun.Bytes())\n\n\t\t\tfunctionId[addr] = id\n\t\t}\n\t\treturn id\n\t}\n\n\t// locations\n\t//\n\t// location returns the ID of the location denoted by fr.\n\t// For Starlark frames, this is the Frame pc.\n\tlocationId := make(map[uintptr]uint64)\n\tlocation := func(fr profFrame) uint64 {\n\t\tfnAddr := profFuncAddr(fr.fn)\n\n\t\t// For Starlark functions, the frame position\n\t\t// represents the current PC value.\n\t\t// Mix it into the low bits of the address.\n\t\t// This is super hacky and may result in collisions\n\t\t// in large functions or if functions are numerous.\n\t\t// TODO(adonovan): fix: try making this cleaner by treating\n\t\t// each bytecode segment as a Profile.Mapping.\n\t\tpcAddr := fnAddr\n\t\tif _, ok := fr.fn.(*Function); ok {\n\t\t\tpcAddr = (pcAddr << 16) ^ uintptr(fr.pc)\n\t\t}\n\n\t\tid, ok := locationId[pcAddr]\n\t\tif !ok {\n\t\t\tid = uint64(pcAddr)\n\n\t\t\tline := new(bytes.Buffer)\n\t\t\tlineenc := protoEncoder{w: line}\n\t\t\tlineenc.uint(Line_function_id, function(fr.fn, fnAddr))\n\t\t\tlineenc.int(Line_line, int64(fr.pos.Line))\n\t\t\tloc := new(bytes.Buffer)\n\t\t\tlocenc := protoEncoder{w: loc}\n\t\t\tlocenc.uint(Location_id, id)\n\t\t\tlocenc.uint(Location_address, uint64(pcAddr))\n\t\t\tlocenc.bytes(Location_line, line.Bytes())\n\t\t\tenc.bytes(Profile_location, loc.Bytes())\n\n\t\t\tlocationId[pcAddr] = id\n\t\t}\n\t\treturn id\n\t}\n\n\twallNanos := new(bytes.Buffer)\n\twnenc := protoEncoder{w: wallNanos}\n\twnenc.int(ValueType_type, str(\"wall\"))\n\twnenc.int(ValueType_unit, str(\"nanoseconds\"))\n\n\t// informational fields of Profile\n\tenc.bytes(Profile_sample_type, wallNanos.Bytes())\n\tenc.int(Profile_period, quantum.Nanoseconds())     // magnitude of sampling period\n\tenc.bytes(Profile_period_type, wallNanos.Bytes())  // dimension and unit of period\n\tenc.int(Profile_time_nanos, time.Now().UnixNano()) // start (real) time of profile\n\n\tstartNano := nanotime()\n\n\t// Read profile events from the channel\n\t// until it is closed by StopProfiler.\n\tfor e := range profiler.events {\n\t\tsample := new(bytes.Buffer)\n\t\tsampleenc := protoEncoder{w: sample}\n\t\tsampleenc.int(Sample_value, e.time.Nanoseconds()) // wall nanoseconds\n\t\tfor _, fr := range e.stack {\n\t\t\tsampleenc.uint(Sample_location_id, location(fr))\n\t\t}\n\t\tenc.bytes(Profile_sample, sample.Bytes())\n\t}\n\n\tendNano := nanotime()\n\tenc.int(Profile_duration_nanos, endNano-startNano)\n\n\terr := gz.Close() // Close reports any prior write error\n\tif flushErr := bufw.Flush(); err == nil {\n\t\terr = flushErr\n\t}\n\tprofiler.done <- err\n}\n\n// nanotime returns the time in nanoseconds since epoch.\n// It is implemented by runtime.nanotime using the linkname hack;\n// runtime.nanotime is defined for all OSs/ARCHS and uses the\n// monotonic system clock, which there is no portable way to access.\n// Should that function ever go away, these alternatives exist:\n//\n// \t// POSIX only. REALTIME not MONOTONIC. 17ns.\n// \tvar tv syscall.Timeval\n// \tsyscall.Gettimeofday(&tv) // can't fail\n// \treturn tv.Nano()\n//\n// \t// Portable. REALTIME not MONOTONIC. 46ns.\n// \treturn time.Now().Nanoseconds()\n//\n//      // POSIX only. Adds a dependency.\n//\timport \"golang.org/x/sys/unix\"\n//\tvar ts unix.Timespec\n// \tunix.ClockGettime(CLOCK_MONOTONIC, &ts) // can't fail\n//\treturn unix.TimespecToNsec(ts)\n//\n//go:linkname nanotime runtime.nanotime\nfunc nanotime() int64\n\n// profFuncAddr returns the canonical \"address\"\n// of a Callable for use by the profiler.\nfunc profFuncAddr(fn Callable) uintptr {\n\tswitch fn := fn.(type) {\n\tcase *Builtin:\n\t\treturn reflect.ValueOf(fn.fn).Pointer()\n\tcase *Function:\n\t\treturn uintptr(unsafe.Pointer(fn.funcode))\n\t}\n\n\t// User-defined callable types are typically of\n\t// of kind pointer-to-struct. Handle them specially.\n\tif v := reflect.ValueOf(fn); v.Type().Kind() == reflect.Ptr {\n\t\treturn v.Pointer()\n\t}\n\n\t// Address zero is reserved by the protocol.\n\t// Use 1 for callables we don't recognize.\n\tlog.Printf(\"Starlark profiler: no address for Callable %T\", fn)\n\treturn 1\n}\n\n// We encode the protocol message by hand to avoid making\n// the interpreter depend on both github.com/google/pprof\n// and github.com/golang/protobuf.\n//\n// This also avoids the need to materialize a protocol message object\n// tree of unbounded size and serialize it all at the end.\n// The pprof format appears to have been designed to\n// permit streaming implementations such as this one.\n//\n// See https://developers.google.com/protocol-buffers/docs/encoding.\ntype protoEncoder struct {\n\tw   io.Writer // *bytes.Buffer or *gzip.Writer\n\ttmp [binary.MaxVarintLen64]byte\n}\n\nfunc (e *protoEncoder) uvarint(x uint64) {\n\tn := binary.PutUvarint(e.tmp[:], x)\n\te.w.Write(e.tmp[:n])\n}\n\nfunc (e *protoEncoder) tag(field, wire uint) {\n\te.uvarint(uint64(field<<3 | wire))\n}\n\nfunc (e *protoEncoder) string(field uint, s string) {\n\te.tag(field, 2) // length-delimited\n\te.uvarint(uint64(len(s)))\n\tio.WriteString(e.w, s)\n}\n\nfunc (e *protoEncoder) bytes(field uint, b []byte) {\n\te.tag(field, 2) // length-delimited\n\te.uvarint(uint64(len(b)))\n\te.w.Write(b)\n}\n\nfunc (e *protoEncoder) uint(field uint, x uint64) {\n\te.tag(field, 0) // varint\n\te.uvarint(x)\n}\n\nfunc (e *protoEncoder) int(field uint, x int64) {\n\te.tag(field, 0) // varint\n\te.uvarint(uint64(x))\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/unpack.go",
    "content": "package starlark\n\n// This file defines the Unpack helper functions used by\n// built-in functions to interpret their call arguments.\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"reflect\"\n\t\"strings\"\n)\n\n// UnpackArgs unpacks the positional and keyword arguments into the\n// supplied parameter variables.  pairs is an alternating list of names\n// and pointers to variables.\n//\n// If the variable is a bool, int, string, *List, *Dict, Callable,\n// Iterable, or user-defined implementation of Value,\n// UnpackArgs performs the appropriate type check.\n// An int uses the AsInt32 check.\n// If the parameter name ends with \"?\",\n// it and all following parameters are optional.\n//\n// If the variable implements Value, UnpackArgs may call\n// its Type() method while constructing the error message.\n//\n// Beware: an optional *List, *Dict, Callable, Iterable, or Value variable that is\n// not assigned is not a valid Starlark Value, so the caller must\n// explicitly handle such cases by interpreting nil as None or some\n// computed default.\nfunc UnpackArgs(fnname string, args Tuple, kwargs []Tuple, pairs ...interface{}) error {\n\tnparams := len(pairs) / 2\n\tvar defined intset\n\tdefined.init(nparams)\n\n\tparamName := func(x interface{}) string { // (no free variables)\n\t\tname := x.(string)\n\t\tif name[len(name)-1] == '?' {\n\t\t\tname = name[:len(name)-1]\n\t\t}\n\t\treturn name\n\t}\n\n\t// positional arguments\n\tif len(args) > nparams {\n\t\treturn fmt.Errorf(\"%s: got %d arguments, want at most %d\",\n\t\t\tfnname, len(args), nparams)\n\t}\n\tfor i, arg := range args {\n\t\tdefined.set(i)\n\t\tif err := unpackOneArg(arg, pairs[2*i+1]); err != nil {\n\t\t\tname := paramName(pairs[2*i])\n\t\t\treturn fmt.Errorf(\"%s: for parameter %s: %s\", fnname, name, err)\n\t\t}\n\t}\n\n\t// keyword arguments\nkwloop:\n\tfor _, item := range kwargs {\n\t\tname, arg := item[0].(String), item[1]\n\t\tfor i := 0; i < nparams; i++ {\n\t\t\tif paramName(pairs[2*i]) == string(name) {\n\t\t\t\t// found it\n\t\t\t\tif defined.set(i) {\n\t\t\t\t\treturn fmt.Errorf(\"%s: got multiple values for keyword argument %s\",\n\t\t\t\t\t\tfnname, name)\n\t\t\t\t}\n\t\t\t\tptr := pairs[2*i+1]\n\t\t\t\tif err := unpackOneArg(arg, ptr); err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"%s: for parameter %s: %s\", fnname, name, err)\n\t\t\t\t}\n\t\t\t\tcontinue kwloop\n\t\t\t}\n\t\t}\n\t\treturn fmt.Errorf(\"%s: unexpected keyword argument %s\", fnname, name)\n\t}\n\n\t// Check that all non-optional parameters are defined.\n\t// (We needn't check the first len(args).)\n\tfor i := len(args); i < nparams; i++ {\n\t\tname := pairs[2*i].(string)\n\t\tif strings.HasSuffix(name, \"?\") {\n\t\t\tbreak // optional\n\t\t}\n\t\tif !defined.get(i) {\n\t\t\treturn fmt.Errorf(\"%s: missing argument for %s\", fnname, name)\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// UnpackPositionalArgs unpacks the positional arguments into\n// corresponding variables.  Each element of vars is a pointer; see\n// UnpackArgs for allowed types and conversions.\n//\n// UnpackPositionalArgs reports an error if the number of arguments is\n// less than min or greater than len(vars), if kwargs is nonempty, or if\n// any conversion fails.\nfunc UnpackPositionalArgs(fnname string, args Tuple, kwargs []Tuple, min int, vars ...interface{}) error {\n\tif len(kwargs) > 0 {\n\t\treturn fmt.Errorf(\"%s: unexpected keyword arguments\", fnname)\n\t}\n\tmax := len(vars)\n\tif len(args) < min {\n\t\tvar atleast string\n\t\tif min < max {\n\t\t\tatleast = \"at least \"\n\t\t}\n\t\treturn fmt.Errorf(\"%s: got %d arguments, want %s%d\", fnname, len(args), atleast, min)\n\t}\n\tif len(args) > max {\n\t\tvar atmost string\n\t\tif max > min {\n\t\t\tatmost = \"at most \"\n\t\t}\n\t\treturn fmt.Errorf(\"%s: got %d arguments, want %s%d\", fnname, len(args), atmost, max)\n\t}\n\tfor i, arg := range args {\n\t\tif err := unpackOneArg(arg, vars[i]); err != nil {\n\t\t\treturn fmt.Errorf(\"%s: for parameter %d: %s\", fnname, i+1, err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc unpackOneArg(v Value, ptr interface{}) error {\n\t// On failure, don't clobber *ptr.\n\tswitch ptr := ptr.(type) {\n\tcase *Value:\n\t\t*ptr = v\n\tcase *string:\n\t\ts, ok := AsString(v)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"got %s, want string\", v.Type())\n\t\t}\n\t\t*ptr = s\n\tcase *bool:\n\t\tb, ok := v.(Bool)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"got %s, want bool\", v.Type())\n\t\t}\n\t\t*ptr = bool(b)\n\tcase *int:\n\t\ti, err := AsInt32(v)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t*ptr = i\n\tcase **List:\n\t\tlist, ok := v.(*List)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"got %s, want list\", v.Type())\n\t\t}\n\t\t*ptr = list\n\tcase **Dict:\n\t\tdict, ok := v.(*Dict)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"got %s, want dict\", v.Type())\n\t\t}\n\t\t*ptr = dict\n\tcase *Callable:\n\t\tf, ok := v.(Callable)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"got %s, want callable\", v.Type())\n\t\t}\n\t\t*ptr = f\n\tcase *Iterable:\n\t\tit, ok := v.(Iterable)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"got %s, want iterable\", v.Type())\n\t\t}\n\t\t*ptr = it\n\tdefault:\n\t\t// v must have type *V, where V is some subtype of starlark.Value.\n\t\tptrv := reflect.ValueOf(ptr)\n\t\tif ptrv.Kind() != reflect.Ptr {\n\t\t\tlog.Panicf(\"internal error: not a pointer: %T\", ptr)\n\t\t}\n\t\tparamVar := ptrv.Elem()\n\t\tif !reflect.TypeOf(v).AssignableTo(paramVar.Type()) {\n\t\t\t// The value is not assignable to the variable.\n\n\t\t\t// Detect a possible bug in the Go program that called Unpack:\n\t\t\t// If the variable *ptr is not a subtype of Value,\n\t\t\t// no value of v can possibly work.\n\t\t\tif !paramVar.Type().AssignableTo(reflect.TypeOf(new(Value)).Elem()) {\n\t\t\t\tlog.Panicf(\"pointer element type does not implement Value: %T\", ptr)\n\t\t\t}\n\n\t\t\t// Report Starlark dynamic type error.\n\t\t\t//\n\t\t\t// We prefer the Starlark Value.Type name over\n\t\t\t// its Go reflect.Type name, but calling the\n\t\t\t// Value.Type method on the variable is not safe\n\t\t\t// in general. If the variable is an interface,\n\t\t\t// the call will fail. Even if the variable has\n\t\t\t// a concrete type, it might not be safe to call\n\t\t\t// Type() on a zero instance. Thus we must use\n\t\t\t// recover.\n\n\t\t\t// Default to Go reflect.Type name\n\t\t\tparamType := paramVar.Type().String()\n\n\t\t\t// Attempt to call Value.Type method.\n\t\t\tfunc() {\n\t\t\t\tdefer func() { recover() }()\n\t\t\t\tparamType = paramVar.MethodByName(\"Type\").Call(nil)[0].String()\n\t\t\t}()\n\t\t\treturn fmt.Errorf(\"got %s, want %s\", v.Type(), paramType)\n\t\t}\n\t\tparamVar.Set(reflect.ValueOf(v))\n\t}\n\treturn nil\n}\n\ntype intset struct {\n\tsmall uint64       // bitset, used if n < 64\n\tlarge map[int]bool //    set, used if n >= 64\n}\n\nfunc (is *intset) init(n int) {\n\tif n >= 64 {\n\t\tis.large = make(map[int]bool)\n\t}\n}\n\nfunc (is *intset) set(i int) (prev bool) {\n\tif is.large == nil {\n\t\tprev = is.small&(1<<uint(i)) != 0\n\t\tis.small |= 1 << uint(i)\n\t} else {\n\t\tprev = is.large[i]\n\t\tis.large[i] = true\n\t}\n\treturn\n}\n\nfunc (is *intset) get(i int) bool {\n\tif is.large == nil {\n\t\treturn is.small&(1<<uint(i)) != 0\n\t}\n\treturn is.large[i]\n}\n\nfunc (is *intset) len() int {\n\tif is.large == nil {\n\t\t// Suboptimal, but used only for error reporting.\n\t\tlen := 0\n\t\tfor i := 0; i < 64; i++ {\n\t\t\tif is.small&(1<<uint(i)) != 0 {\n\t\t\t\tlen++\n\t\t\t}\n\t\t}\n\t\treturn len\n\t}\n\treturn len(is.large)\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlark/value.go",
    "content": "// Copyright 2017 The Bazel 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// Package starlark provides a Starlark interpreter.\n//\n// Starlark values are represented by the Value interface.\n// The following built-in Value types are known to the evaluator:\n//\n//      NoneType        -- NoneType\n//      Bool            -- bool\n//      Int             -- int\n//      Float           -- float\n//      String          -- string\n//      *List           -- list\n//      Tuple           -- tuple\n//      *Dict           -- dict\n//      *Set            -- set\n//      *Function       -- function (implemented in Starlark)\n//      *Builtin        -- builtin_function_or_method (function or method implemented in Go)\n//\n// Client applications may define new data types that satisfy at least\n// the Value interface.  Such types may provide additional operations by\n// implementing any of these optional interfaces:\n//\n//      Callable        -- value is callable like a function\n//      Comparable      -- value defines its own comparison operations\n//      Iterable        -- value is iterable using 'for' loops\n//      Sequence        -- value is iterable sequence of known length\n//      Indexable       -- value is sequence with efficient random access\n//      Mapping         -- value maps from keys to values, like a dictionary\n//      HasBinary       -- value defines binary operations such as * and +\n//      HasAttrs        -- value has readable fields or methods x.f\n//      HasSetField     -- value has settable fields x.f\n//      HasSetIndex     -- value supports element update using x[i]=y\n//      HasSetKey       -- value supports map update using x[k]=v\n//      HasUnary        -- value defines unary operations such as + and -\n//\n// Client applications may also define domain-specific functions in Go\n// and make them available to Starlark programs.  Use NewBuiltin to\n// construct a built-in value that wraps a Go function.  The\n// implementation of the Go function may use UnpackArgs to make sense of\n// the positional and keyword arguments provided by the caller.\n//\n// Starlark's None value is not equal to Go's nil. Go's nil is not a legal\n// Starlark value, but the compiler will not stop you from converting nil\n// to Value. Be careful to avoid allowing Go nil values to leak into\n// Starlark data structures.\n//\n// The Compare operation requires two arguments of the same\n// type, but this constraint cannot be expressed in Go's type system.\n// (This is the classic \"binary method problem\".)\n// So, each Value type's CompareSameType method is a partial function\n// that compares a value only against others of the same type.\n// Use the package's standalone Compare (or Equal) function to compare\n// an arbitrary pair of values.\n//\n// To parse and evaluate a Starlark source file, use ExecFile.  The Eval\n// function evaluates a single expression.  All evaluator functions\n// require a Thread parameter which defines the \"thread-local storage\"\n// of a Starlark thread and may be used to plumb application state\n// through Starlark code and into callbacks.  When evaluation fails it\n// returns an EvalError from which the application may obtain a\n// backtrace of active Starlark calls.\n//\npackage starlark // import \"go.starlark.net/starlark\"\n\n// This file defines the data types of Starlark and their basic operations.\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"math/big\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"go.starlark.net/internal/compile\"\n\t\"go.starlark.net/syntax\"\n)\n\n// Value is a value in the Starlark interpreter.\ntype Value interface {\n\t// String returns the string representation of the value.\n\t// Starlark string values are quoted as if by Python's repr.\n\tString() string\n\n\t// Type returns a short string describing the value's type.\n\tType() string\n\n\t// Freeze causes the value, and all values transitively\n\t// reachable from it through collections and closures, to be\n\t// marked as frozen.  All subsequent mutations to the data\n\t// structure through this API will fail dynamically, making the\n\t// data structure immutable and safe for publishing to other\n\t// Starlark interpreters running concurrently.\n\tFreeze()\n\n\t// Truth returns the truth value of an object.\n\tTruth() Bool\n\n\t// Hash returns a function of x such that Equals(x, y) => Hash(x) == Hash(y).\n\t// Hash may fail if the value's type is not hashable, or if the value\n\t// contains a non-hashable value. The hash is used only by dictionaries and\n\t// is not exposed to the Starlark program.\n\tHash() (uint32, error)\n}\n\n// A Comparable is a value that defines its own equivalence relation and\n// perhaps ordered comparisons.\ntype Comparable interface {\n\tValue\n\t// CompareSameType compares one value to another of the same Type().\n\t// The comparison operation must be one of EQL, NEQ, LT, LE, GT, or GE.\n\t// CompareSameType returns an error if an ordered comparison was\n\t// requested for a type that does not support it.\n\t//\n\t// Implementations that recursively compare subcomponents of\n\t// the value should use the CompareDepth function, not Compare, to\n\t// avoid infinite recursion on cyclic structures.\n\t//\n\t// The depth parameter is used to bound comparisons of cyclic\n\t// data structures.  Implementations should decrement depth\n\t// before calling CompareDepth and should return an error if depth\n\t// < 1.\n\t//\n\t// Client code should not call this method.  Instead, use the\n\t// standalone Compare or Equals functions, which are defined for\n\t// all pairs of operands.\n\tCompareSameType(op syntax.Token, y Value, depth int) (bool, error)\n}\n\nvar (\n\t_ Comparable = None\n\t_ Comparable = Int{}\n\t_ Comparable = False\n\t_ Comparable = Float(0)\n\t_ Comparable = String(\"\")\n\t_ Comparable = (*Dict)(nil)\n\t_ Comparable = (*List)(nil)\n\t_ Comparable = Tuple(nil)\n\t_ Comparable = (*Set)(nil)\n)\n\n// A Callable value f may be the operand of a function call, f(x).\n//\n// Clients should use the Call function, never the CallInternal method.\ntype Callable interface {\n\tValue\n\tName() string\n\tCallInternal(thread *Thread, args Tuple, kwargs []Tuple) (Value, error)\n}\n\ntype callableWithPosition interface {\n\tCallable\n\tPosition() syntax.Position\n}\n\nvar (\n\t_ Callable             = (*Builtin)(nil)\n\t_ Callable             = (*Function)(nil)\n\t_ callableWithPosition = (*Function)(nil)\n)\n\n// An Iterable abstracts a sequence of values.\n// An iterable value may be iterated over by a 'for' loop or used where\n// any other Starlark iterable is allowed.  Unlike a Sequence, the length\n// of an Iterable is not necessarily known in advance of iteration.\ntype Iterable interface {\n\tValue\n\tIterate() Iterator // must be followed by call to Iterator.Done\n}\n\n// A Sequence is a sequence of values of known length.\ntype Sequence interface {\n\tIterable\n\tLen() int\n}\n\nvar (\n\t_ Sequence = (*Dict)(nil)\n\t_ Sequence = (*Set)(nil)\n)\n\n// An Indexable is a sequence of known length that supports efficient random access.\n// It is not necessarily iterable.\ntype Indexable interface {\n\tValue\n\tIndex(i int) Value // requires 0 <= i < Len()\n\tLen() int\n}\n\n// A Sliceable is a sequence that can be cut into pieces with the slice operator (x[i:j:step]).\n//\n// All native indexable objects are sliceable.\n// This is a separate interface for backwards-compatibility.\ntype Sliceable interface {\n\tIndexable\n\t// For positive strides (step > 0), 0 <= start <= end <= n.\n\t// For negative strides (step < 0), -1 <= end <= start < n.\n\t// The caller must ensure that the start and end indices are valid\n\t// and that step is non-zero.\n\tSlice(start, end, step int) Value\n}\n\n// A HasSetIndex is an Indexable value whose elements may be assigned (x[i] = y).\n//\n// The implementation should not add Len to a negative index as the\n// evaluator does this before the call.\ntype HasSetIndex interface {\n\tIndexable\n\tSetIndex(index int, v Value) error\n}\n\nvar (\n\t_ HasSetIndex = (*List)(nil)\n\t_ Indexable   = Tuple(nil)\n\t_ Indexable   = String(\"\")\n\t_ Sliceable   = Tuple(nil)\n\t_ Sliceable   = String(\"\")\n\t_ Sliceable   = (*List)(nil)\n)\n\n// An Iterator provides a sequence of values to the caller.\n//\n// The caller must call Done when the iterator is no longer needed.\n// Operations that modify a sequence will fail if it has active iterators.\n//\n// Example usage:\n//\n// \titer := iterable.Iterator()\n//\tdefer iter.Done()\n//\tvar x Value\n//\tfor iter.Next(&x) {\n//\t\t...\n//\t}\n//\ntype Iterator interface {\n\t// If the iterator is exhausted, Next returns false.\n\t// Otherwise it sets *p to the current element of the sequence,\n\t// advances the iterator, and returns true.\n\tNext(p *Value) bool\n\tDone()\n}\n\n// A Mapping is a mapping from keys to values, such as a dictionary.\n//\n// If a type satisfies both Mapping and Iterable, the iterator yields\n// the keys of the mapping.\ntype Mapping interface {\n\tValue\n\t// Get returns the value corresponding to the specified key,\n\t// or !found if the mapping does not contain the key.\n\t//\n\t// Get also defines the behavior of \"v in mapping\".\n\t// The 'in' operator reports the 'found' component, ignoring errors.\n\tGet(Value) (v Value, found bool, err error)\n}\n\n// An IterableMapping is a mapping that supports key enumeration.\ntype IterableMapping interface {\n\tMapping\n\tIterate() Iterator // see Iterable interface\n\tItems() []Tuple    // a new slice containing all key/value pairs\n}\n\nvar _ IterableMapping = (*Dict)(nil)\n\n// A HasSetKey supports map update using x[k]=v syntax, like a dictionary.\ntype HasSetKey interface {\n\tMapping\n\tSetKey(k, v Value) error\n}\n\nvar _ HasSetKey = (*Dict)(nil)\n\n// A HasBinary value may be used as either operand of these binary operators:\n//     +   -   *   /   //   %   in   not in   |   &   ^   <<   >>\n//\n// The Side argument indicates whether the receiver is the left or right operand.\n//\n// An implementation may decline to handle an operation by returning (nil, nil).\n// For this reason, clients should always call the standalone Binary(op, x, y)\n// function rather than calling the method directly.\ntype HasBinary interface {\n\tValue\n\tBinary(op syntax.Token, y Value, side Side) (Value, error)\n}\n\ntype Side bool\n\nconst (\n\tLeft  Side = false\n\tRight Side = true\n)\n\n// A HasUnary value may be used as the operand of these unary operators:\n//     +   -   ~\n//\n// An implementation may decline to handle an operation by returning (nil, nil).\n// For this reason, clients should always call the standalone Unary(op, x)\n// function rather than calling the method directly.\ntype HasUnary interface {\n\tValue\n\tUnary(op syntax.Token) (Value, error)\n}\n\n// A HasAttrs value has fields or methods that may be read by a dot expression (y = x.f).\n// Attribute names may be listed using the built-in 'dir' function.\n//\n// For implementation convenience, a result of (nil, nil) from Attr is\n// interpreted as a \"no such field or method\" error. Implementations are\n// free to return a more precise error.\ntype HasAttrs interface {\n\tValue\n\tAttr(name string) (Value, error) // returns (nil, nil) if attribute not present\n\tAttrNames() []string             // callers must not modify the result.\n}\n\nvar (\n\t_ HasAttrs = String(\"\")\n\t_ HasAttrs = new(List)\n\t_ HasAttrs = new(Dict)\n\t_ HasAttrs = new(Set)\n)\n\n// A HasSetField value has fields that may be written by a dot expression (x.f = y).\n//\n// An implementation of SetField may return a NoSuchAttrError,\n// in which case the runtime may augment the error message to\n// warn of possible misspelling.\ntype HasSetField interface {\n\tHasAttrs\n\tSetField(name string, val Value) error\n}\n\n// A NoSuchAttrError may be returned by an implementation of\n// HasAttrs.Attr or HasSetField.SetField to indicate that no such field\n// exists. In that case the runtime may augment the error message to\n// warn of possible misspelling.\ntype NoSuchAttrError string\n\nfunc (e NoSuchAttrError) Error() string { return string(e) }\n\n// NoneType is the type of None.  Its only legal value is None.\n// (We represent it as a number, not struct{}, so that None may be constant.)\ntype NoneType byte\n\nconst None = NoneType(0)\n\nfunc (NoneType) String() string        { return \"None\" }\nfunc (NoneType) Type() string          { return \"NoneType\" }\nfunc (NoneType) Freeze()               {} // immutable\nfunc (NoneType) Truth() Bool           { return False }\nfunc (NoneType) Hash() (uint32, error) { return 0, nil }\nfunc (NoneType) CompareSameType(op syntax.Token, y Value, depth int) (bool, error) {\n\treturn threeway(op, 0), nil\n}\n\n// Bool is the type of a Starlark bool.\ntype Bool bool\n\nconst (\n\tFalse Bool = false\n\tTrue  Bool = true\n)\n\nfunc (b Bool) String() string {\n\tif b {\n\t\treturn \"True\"\n\t} else {\n\t\treturn \"False\"\n\t}\n}\nfunc (b Bool) Type() string          { return \"bool\" }\nfunc (b Bool) Freeze()               {} // immutable\nfunc (b Bool) Truth() Bool           { return b }\nfunc (b Bool) Hash() (uint32, error) { return uint32(b2i(bool(b))), nil }\nfunc (x Bool) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(Bool)\n\treturn threeway(op, b2i(bool(x))-b2i(bool(y))), nil\n}\n\n// Float is the type of a Starlark float.\ntype Float float64\n\nfunc (f Float) String() string { return strconv.FormatFloat(float64(f), 'g', 6, 64) }\nfunc (f Float) Type() string   { return \"float\" }\nfunc (f Float) Freeze()        {} // immutable\nfunc (f Float) Truth() Bool    { return f != 0.0 }\nfunc (f Float) Hash() (uint32, error) {\n\t// Equal float and int values must yield the same hash.\n\t// TODO(adonovan): opt: if f is non-integral, and thus not equal\n\t// to any Int, we can avoid the Int conversion and use a cheaper hash.\n\tif isFinite(float64(f)) {\n\t\treturn finiteFloatToInt(f).Hash()\n\t}\n\treturn 1618033, nil // NaN, +/-Inf\n}\n\nfunc floor(f Float) Float { return Float(math.Floor(float64(f))) }\n\n// isFinite reports whether f represents a finite rational value.\n// It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).\nfunc isFinite(f float64) bool {\n\treturn math.Abs(f) <= math.MaxFloat64\n}\n\nfunc (x Float) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(Float)\n\tswitch op {\n\tcase syntax.EQL:\n\t\treturn x == y, nil\n\tcase syntax.NEQ:\n\t\treturn x != y, nil\n\tcase syntax.LE:\n\t\treturn x <= y, nil\n\tcase syntax.LT:\n\t\treturn x < y, nil\n\tcase syntax.GE:\n\t\treturn x >= y, nil\n\tcase syntax.GT:\n\t\treturn x > y, nil\n\t}\n\tpanic(op)\n}\n\nfunc (f Float) rational() *big.Rat { return new(big.Rat).SetFloat64(float64(f)) }\n\n// AsFloat returns the float64 value closest to x.\n// The f result is undefined if x is not a float or int.\nfunc AsFloat(x Value) (f float64, ok bool) {\n\tswitch x := x.(type) {\n\tcase Float:\n\t\treturn float64(x), true\n\tcase Int:\n\t\treturn float64(x.Float()), true\n\t}\n\treturn 0, false\n}\n\nfunc (x Float) Mod(y Float) Float { return Float(math.Mod(float64(x), float64(y))) }\n\n// Unary implements the operations +float and -float.\nfunc (f Float) Unary(op syntax.Token) (Value, error) {\n\tswitch op {\n\tcase syntax.MINUS:\n\t\treturn -f, nil\n\tcase syntax.PLUS:\n\t\treturn +f, nil\n\t}\n\treturn nil, nil\n}\n\n// String is the type of a Starlark string.\n//\n// A String encapsulates an an immutable sequence of bytes,\n// but strings are not directly iterable. Instead, iterate\n// over the result of calling one of these four methods:\n// codepoints, codepoint_ords, elems, elem_ords.\n//\n// Warning: the contract of the Value interface's String method is that\n// it returns the value printed in Starlark notation,\n// so s.String() or fmt.Sprintf(\"%s\", s) returns a quoted string.\n// Use string(s) or s.GoString() or fmt.Sprintf(\"%#v\", s) to obtain the raw contents\n// of a Starlark string as a Go string.\ntype String string\n\nfunc (s String) String() string        { return strconv.Quote(string(s)) }\nfunc (s String) GoString() string      { return string(s) }\nfunc (s String) Type() string          { return \"string\" }\nfunc (s String) Freeze()               {} // immutable\nfunc (s String) Truth() Bool           { return len(s) > 0 }\nfunc (s String) Hash() (uint32, error) { return hashString(string(s)), nil }\nfunc (s String) Len() int              { return len(s) } // bytes\nfunc (s String) Index(i int) Value     { return s[i : i+1] }\n\nfunc (s String) Slice(start, end, step int) Value {\n\tif step == 1 {\n\t\treturn s[start:end]\n\t}\n\n\tsign := signum(step)\n\tvar str []byte\n\tfor i := start; signum(end-i) == sign; i += step {\n\t\tstr = append(str, s[i])\n\t}\n\treturn String(str)\n}\n\nfunc (s String) Attr(name string) (Value, error) { return builtinAttr(s, name, stringMethods) }\nfunc (s String) AttrNames() []string             { return builtinAttrNames(stringMethods) }\n\nfunc (x String) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(String)\n\treturn threeway(op, strings.Compare(string(x), string(y))), nil\n}\n\nfunc AsString(x Value) (string, bool) { v, ok := x.(String); return string(v), ok }\n\n// A stringIterable is an iterable whose iterator yields a sequence of\n// either Unicode code points or elements (bytes),\n// either numerically or as successive substrings.\ntype stringIterable struct {\n\ts          String\n\tords       bool\n\tcodepoints bool\n}\n\nvar _ Iterable = (*stringIterable)(nil)\n\nfunc (si stringIterable) String() string {\n\tvar etype string\n\tif si.codepoints {\n\t\tetype = \"codepoint\"\n\t} else {\n\t\tetype = \"elem\"\n\t}\n\tif si.ords {\n\t\treturn si.s.String() + \".\" + etype + \"_ords()\"\n\t} else {\n\t\treturn si.s.String() + \".\" + etype + \"s()\"\n\t}\n}\nfunc (si stringIterable) Type() string {\n\tif si.codepoints {\n\t\treturn \"codepoints\"\n\t} else {\n\t\treturn \"elems\"\n\t}\n}\nfunc (si stringIterable) Freeze()               {} // immutable\nfunc (si stringIterable) Truth() Bool           { return True }\nfunc (si stringIterable) Hash() (uint32, error) { return 0, fmt.Errorf(\"unhashable: %s\", si.Type()) }\nfunc (si stringIterable) Iterate() Iterator     { return &stringIterator{si, 0} }\n\ntype stringIterator struct {\n\tsi stringIterable\n\ti  int\n}\n\nfunc (it *stringIterator) Next(p *Value) bool {\n\ts := it.si.s[it.i:]\n\tif s == \"\" {\n\t\treturn false\n\t}\n\tif it.si.codepoints {\n\t\tr, sz := utf8.DecodeRuneInString(string(s))\n\t\tif !it.si.ords {\n\t\t\t*p = s[:sz]\n\t\t} else {\n\t\t\t*p = MakeInt(int(r))\n\t\t}\n\t\tit.i += sz\n\t} else {\n\t\tb := int(s[0])\n\t\tif !it.si.ords {\n\t\t\t*p = s[:1]\n\t\t} else {\n\t\t\t*p = MakeInt(b)\n\t\t}\n\t\tit.i += 1\n\t}\n\treturn true\n}\n\nfunc (*stringIterator) Done() {}\n\n// A Function is a function defined by a Starlark def statement or lambda expression.\n// The initialization behavior of a Starlark module is also represented by a Function.\ntype Function struct {\n\tfuncode  *compile.Funcode\n\tmodule   *module\n\tdefaults Tuple\n\tfreevars Tuple\n}\n\n// A module is the dynamic counterpart to a Program.\n// All functions in the same program share a module.\ntype module struct {\n\tprogram     *compile.Program\n\tpredeclared StringDict\n\tglobals     []Value\n\tconstants   []Value\n}\n\n// makeGlobalDict returns a new, unfrozen StringDict containing all global\n// variables so far defined in the module.\nfunc (m *module) makeGlobalDict() StringDict {\n\tr := make(StringDict, len(m.program.Globals))\n\tfor i, id := range m.program.Globals {\n\t\tif v := m.globals[i]; v != nil {\n\t\t\tr[id.Name] = v\n\t\t}\n\t}\n\treturn r\n}\n\nfunc (fn *Function) Name() string          { return fn.funcode.Name } // \"lambda\" for anonymous functions\nfunc (fn *Function) Doc() string           { return fn.funcode.Doc }\nfunc (fn *Function) Hash() (uint32, error) { return hashString(fn.funcode.Name), nil }\nfunc (fn *Function) Freeze()               { fn.defaults.Freeze(); fn.freevars.Freeze() }\nfunc (fn *Function) String() string        { return toString(fn) }\nfunc (fn *Function) Type() string          { return \"function\" }\nfunc (fn *Function) Truth() Bool           { return true }\n\n// Globals returns a new, unfrozen StringDict containing all global\n// variables so far defined in the function's module.\nfunc (fn *Function) Globals() StringDict { return fn.module.makeGlobalDict() }\n\nfunc (fn *Function) Position() syntax.Position { return fn.funcode.Pos }\nfunc (fn *Function) NumParams() int            { return fn.funcode.NumParams }\nfunc (fn *Function) NumKwonlyParams() int      { return fn.funcode.NumKwonlyParams }\n\n// Param returns the name and position of the ith parameter,\n// where 0 <= i < NumParams().\n// The *args and **kwargs parameters are at the end\n// even if there were optional parameters after *args.\nfunc (fn *Function) Param(i int) (string, syntax.Position) {\n\tif i >= fn.NumParams() {\n\t\tpanic(i)\n\t}\n\tid := fn.funcode.Locals[i]\n\treturn id.Name, id.Pos\n}\nfunc (fn *Function) HasVarargs() bool { return fn.funcode.HasVarargs }\nfunc (fn *Function) HasKwargs() bool  { return fn.funcode.HasKwargs }\n\n// A Builtin is a function implemented in Go.\ntype Builtin struct {\n\tname string\n\tfn   func(thread *Thread, fn *Builtin, args Tuple, kwargs []Tuple) (Value, error)\n\trecv Value // for bound methods (e.g. \"\".startswith)\n}\n\nfunc (b *Builtin) Name() string { return b.name }\nfunc (b *Builtin) Freeze() {\n\tif b.recv != nil {\n\t\tb.recv.Freeze()\n\t}\n}\nfunc (b *Builtin) Hash() (uint32, error) {\n\th := hashString(b.name)\n\tif b.recv != nil {\n\t\th ^= 5521\n\t}\n\treturn h, nil\n}\nfunc (b *Builtin) Receiver() Value { return b.recv }\nfunc (b *Builtin) String() string  { return toString(b) }\nfunc (b *Builtin) Type() string    { return \"builtin_function_or_method\" }\nfunc (b *Builtin) CallInternal(thread *Thread, args Tuple, kwargs []Tuple) (Value, error) {\n\treturn b.fn(thread, b, args, kwargs)\n}\nfunc (b *Builtin) Truth() Bool { return true }\n\n// NewBuiltin returns a new 'builtin_function_or_method' value with the specified name\n// and implementation.  It compares unequal with all other values.\nfunc NewBuiltin(name string, fn func(thread *Thread, fn *Builtin, args Tuple, kwargs []Tuple) (Value, error)) *Builtin {\n\treturn &Builtin{name: name, fn: fn}\n}\n\n// BindReceiver returns a new Builtin value representing a method\n// closure, that is, a built-in function bound to a receiver value.\n//\n// In the example below, the value of f is the string.index\n// built-in method bound to the receiver value \"abc\":\n//\n//     f = \"abc\".index; f(\"a\"); f(\"b\")\n//\n// In the common case, the receiver is bound only during the call,\n// but this still results in the creation of a temporary method closure:\n//\n//     \"abc\".index(\"a\")\n//\nfunc (b *Builtin) BindReceiver(recv Value) *Builtin {\n\treturn &Builtin{name: b.name, fn: b.fn, recv: recv}\n}\n\n// A *Dict represents a Starlark dictionary.\n// The zero value of Dict is a valid empty dictionary.\n// If you know the exact final number of entries,\n// it is more efficient to call NewDict.\ntype Dict struct {\n\tht hashtable\n}\n\n// NewDict returns a set with initial space for\n// at least size insertions before rehashing.\nfunc NewDict(size int) *Dict {\n\tdict := new(Dict)\n\tdict.ht.init(size)\n\treturn dict\n}\n\nfunc (d *Dict) Clear() error                                    { return d.ht.clear() }\nfunc (d *Dict) Delete(k Value) (v Value, found bool, err error) { return d.ht.delete(k) }\nfunc (d *Dict) Get(k Value) (v Value, found bool, err error)    { return d.ht.lookup(k) }\nfunc (d *Dict) Items() []Tuple                                  { return d.ht.items() }\nfunc (d *Dict) Keys() []Value                                   { return d.ht.keys() }\nfunc (d *Dict) Len() int                                        { return int(d.ht.len) }\nfunc (d *Dict) Iterate() Iterator                               { return d.ht.iterate() }\nfunc (d *Dict) SetKey(k, v Value) error                         { return d.ht.insert(k, v) }\nfunc (d *Dict) String() string                                  { return toString(d) }\nfunc (d *Dict) Type() string                                    { return \"dict\" }\nfunc (d *Dict) Freeze()                                         { d.ht.freeze() }\nfunc (d *Dict) Truth() Bool                                     { return d.Len() > 0 }\nfunc (d *Dict) Hash() (uint32, error)                           { return 0, fmt.Errorf(\"unhashable type: dict\") }\n\nfunc (d *Dict) Attr(name string) (Value, error) { return builtinAttr(d, name, dictMethods) }\nfunc (d *Dict) AttrNames() []string             { return builtinAttrNames(dictMethods) }\n\nfunc (x *Dict) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(*Dict)\n\tswitch op {\n\tcase syntax.EQL:\n\t\tok, err := dictsEqual(x, y, depth)\n\t\treturn ok, err\n\tcase syntax.NEQ:\n\t\tok, err := dictsEqual(x, y, depth)\n\t\treturn !ok, err\n\tdefault:\n\t\treturn false, fmt.Errorf(\"%s %s %s not implemented\", x.Type(), op, y.Type())\n\t}\n}\n\nfunc dictsEqual(x, y *Dict, depth int) (bool, error) {\n\tif x.Len() != y.Len() {\n\t\treturn false, nil\n\t}\n\tfor _, xitem := range x.Items() {\n\t\tkey, xval := xitem[0], xitem[1]\n\n\t\tif yval, found, _ := y.Get(key); !found {\n\t\t\treturn false, nil\n\t\t} else if eq, err := EqualDepth(xval, yval, depth-1); err != nil {\n\t\t\treturn false, err\n\t\t} else if !eq {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\treturn true, nil\n}\n\n// A *List represents a Starlark list value.\ntype List struct {\n\telems     []Value\n\tfrozen    bool\n\titercount uint32 // number of active iterators (ignored if frozen)\n}\n\n// NewList returns a list containing the specified elements.\n// Callers should not subsequently modify elems.\nfunc NewList(elems []Value) *List { return &List{elems: elems} }\n\nfunc (l *List) Freeze() {\n\tif !l.frozen {\n\t\tl.frozen = true\n\t\tfor _, elem := range l.elems {\n\t\t\telem.Freeze()\n\t\t}\n\t}\n}\n\n// checkMutable reports an error if the list should not be mutated.\n// verb+\" list\" should describe the operation.\nfunc (l *List) checkMutable(verb string) error {\n\tif l.frozen {\n\t\treturn fmt.Errorf(\"cannot %s frozen list\", verb)\n\t}\n\tif l.itercount > 0 {\n\t\treturn fmt.Errorf(\"cannot %s list during iteration\", verb)\n\t}\n\treturn nil\n}\n\nfunc (l *List) String() string        { return toString(l) }\nfunc (l *List) Type() string          { return \"list\" }\nfunc (l *List) Hash() (uint32, error) { return 0, fmt.Errorf(\"unhashable type: list\") }\nfunc (l *List) Truth() Bool           { return l.Len() > 0 }\nfunc (l *List) Len() int              { return len(l.elems) }\nfunc (l *List) Index(i int) Value     { return l.elems[i] }\n\nfunc (l *List) Slice(start, end, step int) Value {\n\tif step == 1 {\n\t\telems := append([]Value{}, l.elems[start:end]...)\n\t\treturn NewList(elems)\n\t}\n\n\tsign := signum(step)\n\tvar list []Value\n\tfor i := start; signum(end-i) == sign; i += step {\n\t\tlist = append(list, l.elems[i])\n\t}\n\treturn NewList(list)\n}\n\nfunc (l *List) Attr(name string) (Value, error) { return builtinAttr(l, name, listMethods) }\nfunc (l *List) AttrNames() []string             { return builtinAttrNames(listMethods) }\n\nfunc (l *List) Iterate() Iterator {\n\tif !l.frozen {\n\t\tl.itercount++\n\t}\n\treturn &listIterator{l: l}\n}\n\nfunc (x *List) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(*List)\n\t// It's tempting to check x == y as an optimization here,\n\t// but wrong because a list containing NaN is not equal to itself.\n\treturn sliceCompare(op, x.elems, y.elems, depth)\n}\n\nfunc sliceCompare(op syntax.Token, x, y []Value, depth int) (bool, error) {\n\t// Fast path: check length.\n\tif len(x) != len(y) && (op == syntax.EQL || op == syntax.NEQ) {\n\t\treturn op == syntax.NEQ, nil\n\t}\n\n\t// Find first element that is not equal in both lists.\n\tfor i := 0; i < len(x) && i < len(y); i++ {\n\t\tif eq, err := EqualDepth(x[i], y[i], depth-1); err != nil {\n\t\t\treturn false, err\n\t\t} else if !eq {\n\t\t\tswitch op {\n\t\t\tcase syntax.EQL:\n\t\t\t\treturn false, nil\n\t\t\tcase syntax.NEQ:\n\t\t\t\treturn true, nil\n\t\t\tdefault:\n\t\t\t\treturn CompareDepth(op, x[i], y[i], depth-1)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn threeway(op, len(x)-len(y)), nil\n}\n\ntype listIterator struct {\n\tl *List\n\ti int\n}\n\nfunc (it *listIterator) Next(p *Value) bool {\n\tif it.i < it.l.Len() {\n\t\t*p = it.l.elems[it.i]\n\t\tit.i++\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (it *listIterator) Done() {\n\tif !it.l.frozen {\n\t\tit.l.itercount--\n\t}\n}\n\nfunc (l *List) SetIndex(i int, v Value) error {\n\tif err := l.checkMutable(\"assign to element of\"); err != nil {\n\t\treturn err\n\t}\n\tl.elems[i] = v\n\treturn nil\n}\n\nfunc (l *List) Append(v Value) error {\n\tif err := l.checkMutable(\"append to\"); err != nil {\n\t\treturn err\n\t}\n\tl.elems = append(l.elems, v)\n\treturn nil\n}\n\nfunc (l *List) Clear() error {\n\tif err := l.checkMutable(\"clear\"); err != nil {\n\t\treturn err\n\t}\n\tfor i := range l.elems {\n\t\tl.elems[i] = nil // aid GC\n\t}\n\tl.elems = l.elems[:0]\n\treturn nil\n}\n\n// A Tuple represents a Starlark tuple value.\ntype Tuple []Value\n\nfunc (t Tuple) Len() int          { return len(t) }\nfunc (t Tuple) Index(i int) Value { return t[i] }\n\nfunc (t Tuple) Slice(start, end, step int) Value {\n\tif step == 1 {\n\t\treturn t[start:end]\n\t}\n\n\tsign := signum(step)\n\tvar tuple Tuple\n\tfor i := start; signum(end-i) == sign; i += step {\n\t\ttuple = append(tuple, t[i])\n\t}\n\treturn tuple\n}\n\nfunc (t Tuple) Iterate() Iterator { return &tupleIterator{elems: t} }\nfunc (t Tuple) Freeze() {\n\tfor _, elem := range t {\n\t\telem.Freeze()\n\t}\n}\nfunc (t Tuple) String() string { return toString(t) }\nfunc (t Tuple) Type() string   { return \"tuple\" }\nfunc (t Tuple) Truth() Bool    { return len(t) > 0 }\n\nfunc (x Tuple) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(Tuple)\n\treturn sliceCompare(op, x, y, depth)\n}\n\nfunc (t Tuple) Hash() (uint32, error) {\n\t// Use same algorithm as Python.\n\tvar x, mult uint32 = 0x345678, 1000003\n\tfor _, elem := range t {\n\t\ty, err := elem.Hash()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tx = x ^ y*mult\n\t\tmult += 82520 + uint32(len(t)+len(t))\n\t}\n\treturn x, nil\n}\n\ntype tupleIterator struct{ elems Tuple }\n\nfunc (it *tupleIterator) Next(p *Value) bool {\n\tif len(it.elems) > 0 {\n\t\t*p = it.elems[0]\n\t\tit.elems = it.elems[1:]\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (it *tupleIterator) Done() {}\n\n// A Set represents a Starlark set value.\n// The zero value of Set is a valid empty set.\n// If you know the exact final number of elements,\n// it is more efficient to call NewSet.\ntype Set struct {\n\tht hashtable // values are all None\n}\n\n// NewSet returns a dictionary with initial space for\n// at least size insertions before rehashing.\nfunc NewSet(size int) *Set {\n\tset := new(Set)\n\tset.ht.init(size)\n\treturn set\n}\n\nfunc (s *Set) Delete(k Value) (found bool, err error) { _, found, err = s.ht.delete(k); return }\nfunc (s *Set) Clear() error                           { return s.ht.clear() }\nfunc (s *Set) Has(k Value) (found bool, err error)    { _, found, err = s.ht.lookup(k); return }\nfunc (s *Set) Insert(k Value) error                   { return s.ht.insert(k, None) }\nfunc (s *Set) Len() int                               { return int(s.ht.len) }\nfunc (s *Set) Iterate() Iterator                      { return s.ht.iterate() }\nfunc (s *Set) String() string                         { return toString(s) }\nfunc (s *Set) Type() string                           { return \"set\" }\nfunc (s *Set) elems() []Value                         { return s.ht.keys() }\nfunc (s *Set) Freeze()                                { s.ht.freeze() }\nfunc (s *Set) Hash() (uint32, error)                  { return 0, fmt.Errorf(\"unhashable type: set\") }\nfunc (s *Set) Truth() Bool                            { return s.Len() > 0 }\n\nfunc (s *Set) Attr(name string) (Value, error) { return builtinAttr(s, name, setMethods) }\nfunc (s *Set) AttrNames() []string             { return builtinAttrNames(setMethods) }\n\nfunc (x *Set) CompareSameType(op syntax.Token, y_ Value, depth int) (bool, error) {\n\ty := y_.(*Set)\n\tswitch op {\n\tcase syntax.EQL:\n\t\tok, err := setsEqual(x, y, depth)\n\t\treturn ok, err\n\tcase syntax.NEQ:\n\t\tok, err := setsEqual(x, y, depth)\n\t\treturn !ok, err\n\tdefault:\n\t\treturn false, fmt.Errorf(\"%s %s %s not implemented\", x.Type(), op, y.Type())\n\t}\n}\n\nfunc setsEqual(x, y *Set, depth int) (bool, error) {\n\tif x.Len() != y.Len() {\n\t\treturn false, nil\n\t}\n\tfor _, elem := range x.elems() {\n\t\tif found, _ := y.Has(elem); !found {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\treturn true, nil\n}\n\nfunc (s *Set) Union(iter Iterator) (Value, error) {\n\tset := new(Set)\n\tfor _, elem := range s.elems() {\n\t\tset.Insert(elem) // can't fail\n\t}\n\tvar x Value\n\tfor iter.Next(&x) {\n\t\tif err := set.Insert(x); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn set, nil\n}\n\n// toString returns the string form of value v.\n// It may be more efficient than v.String() for larger values.\nfunc toString(v Value) string {\n\tbuf := new(strings.Builder)\n\twriteValue(buf, v, nil)\n\treturn buf.String()\n}\n\n// writeValue writes x to out.\n//\n// path is used to detect cycles.\n// It contains the list of *List and *Dict values we're currently printing.\n// (These are the only potentially cyclic structures.)\n// Callers should generally pass nil for path.\n// It is safe to re-use the same path slice for multiple calls.\nfunc writeValue(out *strings.Builder, x Value, path []Value) {\n\tswitch x := x.(type) {\n\tcase nil:\n\t\tout.WriteString(\"<nil>\") // indicates a bug\n\n\tcase NoneType:\n\t\tout.WriteString(\"None\")\n\n\tcase Int:\n\t\tout.WriteString(x.String())\n\n\tcase Bool:\n\t\tif x {\n\t\t\tout.WriteString(\"True\")\n\t\t} else {\n\t\t\tout.WriteString(\"False\")\n\t\t}\n\n\tcase String:\n\t\tfmt.Fprintf(out, \"%q\", string(x))\n\n\tcase *List:\n\t\tout.WriteByte('[')\n\t\tif pathContains(path, x) {\n\t\t\tout.WriteString(\"...\") // list contains itself\n\t\t} else {\n\t\t\tfor i, elem := range x.elems {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tout.WriteString(\", \")\n\t\t\t\t}\n\t\t\t\twriteValue(out, elem, append(path, x))\n\t\t\t}\n\t\t}\n\t\tout.WriteByte(']')\n\n\tcase Tuple:\n\t\tout.WriteByte('(')\n\t\tfor i, elem := range x {\n\t\t\tif i > 0 {\n\t\t\t\tout.WriteString(\", \")\n\t\t\t}\n\t\t\twriteValue(out, elem, path)\n\t\t}\n\t\tif len(x) == 1 {\n\t\t\tout.WriteByte(',')\n\t\t}\n\t\tout.WriteByte(')')\n\n\tcase *Function:\n\t\tfmt.Fprintf(out, \"<function %s>\", x.Name())\n\n\tcase *Builtin:\n\t\tif x.recv != nil {\n\t\t\tfmt.Fprintf(out, \"<built-in method %s of %s value>\", x.Name(), x.recv.Type())\n\t\t} else {\n\t\t\tfmt.Fprintf(out, \"<built-in function %s>\", x.Name())\n\t\t}\n\n\tcase *Dict:\n\t\tout.WriteByte('{')\n\t\tif pathContains(path, x) {\n\t\t\tout.WriteString(\"...\") // dict contains itself\n\t\t} else {\n\t\t\tsep := \"\"\n\t\t\tfor _, item := range x.Items() {\n\t\t\t\tk, v := item[0], item[1]\n\t\t\t\tout.WriteString(sep)\n\t\t\t\twriteValue(out, k, path)\n\t\t\t\tout.WriteString(\": \")\n\t\t\t\twriteValue(out, v, append(path, x)) // cycle check\n\t\t\t\tsep = \", \"\n\t\t\t}\n\t\t}\n\t\tout.WriteByte('}')\n\n\tcase *Set:\n\t\tout.WriteString(\"set([\")\n\t\tfor i, elem := range x.elems() {\n\t\t\tif i > 0 {\n\t\t\t\tout.WriteString(\", \")\n\t\t\t}\n\t\t\twriteValue(out, elem, path)\n\t\t}\n\t\tout.WriteString(\"])\")\n\n\tdefault:\n\t\tout.WriteString(x.String())\n\t}\n}\n\nfunc pathContains(path []Value, x Value) bool {\n\tfor _, y := range path {\n\t\tif x == y {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nconst maxdepth = 10\n\n// Equal reports whether two Starlark values are equal.\nfunc Equal(x, y Value) (bool, error) {\n\tif x, ok := x.(String); ok {\n\t\treturn x == y, nil // fast path for an important special case\n\t}\n\treturn EqualDepth(x, y, maxdepth)\n}\n\n// EqualDepth reports whether two Starlark values are equal.\n//\n// Recursive comparisons by implementations of Value.CompareSameType\n// should use EqualDepth to prevent infinite recursion.\nfunc EqualDepth(x, y Value, depth int) (bool, error) {\n\treturn CompareDepth(syntax.EQL, x, y, depth)\n}\n\n// Compare compares two Starlark values.\n// The comparison operation must be one of EQL, NEQ, LT, LE, GT, or GE.\n// Compare returns an error if an ordered comparison was\n// requested for a type that does not support it.\n//\n// Recursive comparisons by implementations of Value.CompareSameType\n// should use CompareDepth to prevent infinite recursion.\nfunc Compare(op syntax.Token, x, y Value) (bool, error) {\n\treturn CompareDepth(op, x, y, maxdepth)\n}\n\n// CompareDepth compares two Starlark values.\n// The comparison operation must be one of EQL, NEQ, LT, LE, GT, or GE.\n// CompareDepth returns an error if an ordered comparison was\n// requested for a pair of values that do not support it.\n//\n// The depth parameter limits the maximum depth of recursion\n// in cyclic data structures.\nfunc CompareDepth(op syntax.Token, x, y Value, depth int) (bool, error) {\n\tif depth < 1 {\n\t\treturn false, fmt.Errorf(\"comparison exceeded maximum recursion depth\")\n\t}\n\tif sameType(x, y) {\n\t\tif xcomp, ok := x.(Comparable); ok {\n\t\t\treturn xcomp.CompareSameType(op, y, depth)\n\t\t}\n\n\t\t// use identity comparison\n\t\tswitch op {\n\t\tcase syntax.EQL:\n\t\t\treturn x == y, nil\n\t\tcase syntax.NEQ:\n\t\t\treturn x != y, nil\n\t\t}\n\t\treturn false, fmt.Errorf(\"%s %s %s not implemented\", x.Type(), op, y.Type())\n\t}\n\n\t// different types\n\n\t// int/float ordered comparisons\n\tswitch x := x.(type) {\n\tcase Int:\n\t\tif y, ok := y.(Float); ok {\n\t\t\tif y != y {\n\t\t\t\treturn false, nil // y is NaN\n\t\t\t}\n\t\t\tvar cmp int\n\t\t\tif !math.IsInf(float64(y), 0) {\n\t\t\t\tcmp = x.rational().Cmp(y.rational()) // y is finite\n\t\t\t} else if y > 0 {\n\t\t\t\tcmp = -1 // y is +Inf\n\t\t\t} else {\n\t\t\t\tcmp = +1 // y is -Inf\n\t\t\t}\n\t\t\treturn threeway(op, cmp), nil\n\t\t}\n\tcase Float:\n\t\tif y, ok := y.(Int); ok {\n\t\t\tif x != x {\n\t\t\t\treturn false, nil // x is NaN\n\t\t\t}\n\t\t\tvar cmp int\n\t\t\tif !math.IsInf(float64(x), 0) {\n\t\t\t\tcmp = x.rational().Cmp(y.rational()) // x is finite\n\t\t\t} else if x > 0 {\n\t\t\t\tcmp = -1 // x is +Inf\n\t\t\t} else {\n\t\t\t\tcmp = +1 // x is -Inf\n\t\t\t}\n\t\t\treturn threeway(op, cmp), nil\n\t\t}\n\t}\n\n\t// All other values of different types compare unequal.\n\tswitch op {\n\tcase syntax.EQL:\n\t\treturn false, nil\n\tcase syntax.NEQ:\n\t\treturn true, nil\n\t}\n\treturn false, fmt.Errorf(\"%s %s %s not implemented\", x.Type(), op, y.Type())\n}\n\nfunc sameType(x, y Value) bool {\n\treturn reflect.TypeOf(x) == reflect.TypeOf(y) || x.Type() == y.Type()\n}\n\n// threeway interprets a three-way comparison value cmp (-1, 0, +1)\n// as a boolean comparison (e.g. x < y).\nfunc threeway(op syntax.Token, cmp int) bool {\n\tswitch op {\n\tcase syntax.EQL:\n\t\treturn cmp == 0\n\tcase syntax.NEQ:\n\t\treturn cmp != 0\n\tcase syntax.LE:\n\t\treturn cmp <= 0\n\tcase syntax.LT:\n\t\treturn cmp < 0\n\tcase syntax.GE:\n\t\treturn cmp >= 0\n\tcase syntax.GT:\n\t\treturn cmp > 0\n\t}\n\tpanic(op)\n}\n\nfunc b2i(b bool) int {\n\tif b {\n\t\treturn 1\n\t} else {\n\t\treturn 0\n\t}\n}\n\n// Len returns the length of a string or sequence value,\n// and -1 for all others.\n//\n// Warning: Len(x) >= 0 does not imply Iterate(x) != nil.\n// A string has a known length but is not directly iterable.\nfunc Len(x Value) int {\n\tswitch x := x.(type) {\n\tcase String:\n\t\treturn x.Len()\n\tcase Sequence:\n\t\treturn x.Len()\n\t}\n\treturn -1\n}\n\n// Iterate return a new iterator for the value if iterable, nil otherwise.\n// If the result is non-nil, the caller must call Done when finished with it.\n//\n// Warning: Iterate(x) != nil does not imply Len(x) >= 0.\n// Some iterables may have unknown length.\nfunc Iterate(x Value) Iterator {\n\tif x, ok := x.(Iterable); ok {\n\t\treturn x.Iterate()\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlarkstruct/module.go",
    "content": "package starlarkstruct\n\nimport (\n\t\"fmt\"\n\n\t\"go.starlark.net/starlark\"\n)\n\n// A Module is a named collection of values,\n// typically a suite of functions imported by a load statement.\n//\n// It differs from Struct primarily in that its string representation\n// does not enumerate its fields.\ntype Module struct {\n\tName    string\n\tMembers starlark.StringDict\n}\n\nvar _ starlark.HasAttrs = (*Module)(nil)\n\nfunc (m *Module) Attr(name string) (starlark.Value, error) { return m.Members[name], nil }\nfunc (m *Module) AttrNames() []string                      { return m.Members.Keys() }\nfunc (m *Module) Freeze()                                  { m.Members.Freeze() }\nfunc (m *Module) Hash() (uint32, error)                    { return 0, fmt.Errorf(\"unhashable: %s\", m.Type()) }\nfunc (m *Module) String() string                           { return fmt.Sprintf(\"<module %q>\", m.Name) }\nfunc (m *Module) Truth() starlark.Bool                     { return true }\nfunc (m *Module) Type() string                             { return \"module\" }\n\n// MakeModule may be used as the implementation of a Starlark built-in\n// function, module(name, **kwargs). It returns a new module with the\n// specified name and members.\nfunc MakeModule(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {\n\tvar name string\n\tif err := starlark.UnpackPositionalArgs(b.Name(), args, nil, 1, &name); err != nil {\n\t\treturn nil, err\n\t}\n\tmembers := make(starlark.StringDict, len(kwargs))\n\tfor _, kwarg := range kwargs {\n\t\tk := string(kwarg[0].(starlark.String))\n\t\tmembers[k] = kwarg[1]\n\t}\n\treturn &Module{name, members}, nil\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/starlarkstruct/struct.go",
    "content": "// Copyright 2017 The Bazel 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// Package starlarkstruct defines the Starlark types 'struct' and\n// 'module', both optional language extensions.\n//\npackage starlarkstruct // import \"go.starlark.net/starlarkstruct\"\n\n// It is tempting to introduce a variant of Struct that is a wrapper\n// around a Go struct value, for stronger typing guarantees and more\n// efficient and convenient field lookup. However:\n// 1) all fields of Starlark structs are optional, so we cannot represent\n//    them using more specific types such as String, Int, *Depset, and\n//    *File, as such types give no way to represent missing fields.\n// 2) the efficiency gain of direct struct field access is rather\n//    marginal: finding the index of a field by binary searching on the\n//    sorted list of field names is quite fast compared to the other\n//    overheads.\n// 3) the gains in compactness and spatial locality are also rather\n//    marginal: the array behind the []entry slice is (due to field name\n//    strings) only a factor of 2 larger than the corresponding Go struct\n//    would be, and, like the Go struct, requires only a single allocation.\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"go.starlark.net/starlark\"\n\t\"go.starlark.net/syntax\"\n)\n\n// Make is the implementation of a built-in function that instantiates\n// an immutable struct from the specified keyword arguments.\n//\n// An application can add 'struct' to the Starlark environment like so:\n//\n// \tglobals := starlark.StringDict{\n// \t\t\"struct\":  starlark.NewBuiltin(\"struct\", starlarkstruct.Make),\n// \t}\n//\nfunc Make(_ *starlark.Thread, _ *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {\n\tif len(args) > 0 {\n\t\treturn nil, fmt.Errorf(\"struct: unexpected positional arguments\")\n\t}\n\treturn FromKeywords(Default, kwargs), nil\n}\n\n// FromKeywords returns a new struct instance whose fields are specified by the\n// key/value pairs in kwargs.  (Each kwargs[i][0] must be a starlark.String.)\nfunc FromKeywords(constructor starlark.Value, kwargs []starlark.Tuple) *Struct {\n\tif constructor == nil {\n\t\tpanic(\"nil constructor\")\n\t}\n\ts := &Struct{\n\t\tconstructor: constructor,\n\t\tentries:     make(entries, 0, len(kwargs)),\n\t}\n\tfor _, kwarg := range kwargs {\n\t\tk := string(kwarg[0].(starlark.String))\n\t\tv := kwarg[1]\n\t\ts.entries = append(s.entries, entry{k, v})\n\t}\n\tsort.Sort(s.entries)\n\treturn s\n}\n\n// FromStringDict returns a whose elements are those of d.\n// The constructor parameter specifies the constructor; use Default for an ordinary struct.\nfunc FromStringDict(constructor starlark.Value, d starlark.StringDict) *Struct {\n\tif constructor == nil {\n\t\tpanic(\"nil constructor\")\n\t}\n\ts := &Struct{\n\t\tconstructor: constructor,\n\t\tentries:     make(entries, 0, len(d)),\n\t}\n\tfor k, v := range d {\n\t\ts.entries = append(s.entries, entry{k, v})\n\t}\n\tsort.Sort(s.entries)\n\treturn s\n}\n\n// Struct is an immutable Starlark type that maps field names to values.\n// It is not iterable and does not support len.\n//\n// A struct has a constructor, a distinct value that identifies a class\n// of structs, and which appears in the struct's string representation.\n//\n// Operations such as x+y fail if the constructors of the two operands\n// are not equal.\n//\n// The default constructor, Default, is the string \"struct\", but\n// clients may wish to 'brand' structs for their own purposes.\n// The constructor value appears in the printed form of the value,\n// and is accessible using the Constructor method.\n//\n// Use Attr to access its fields and AttrNames to enumerate them.\ntype Struct struct {\n\tconstructor starlark.Value\n\tentries     entries // sorted by name\n}\n\n// Default is the default constructor for structs.\n// It is merely the string \"struct\".\nconst Default = starlark.String(\"struct\")\n\ntype entries []entry\n\nfunc (a entries) Len() int           { return len(a) }\nfunc (a entries) Less(i, j int) bool { return a[i].name < a[j].name }\nfunc (a entries) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }\n\ntype entry struct {\n\tname  string\n\tvalue starlark.Value\n}\n\nvar (\n\t_ starlark.HasAttrs  = (*Struct)(nil)\n\t_ starlark.HasBinary = (*Struct)(nil)\n)\n\n// ToStringDict adds a name/value entry to d for each field of the struct.\nfunc (s *Struct) ToStringDict(d starlark.StringDict) {\n\tfor _, e := range s.entries {\n\t\td[e.name] = e.value\n\t}\n}\n\nfunc (s *Struct) String() string {\n\tbuf := new(strings.Builder)\n\tif s.constructor == Default {\n\t\t// NB: The Java implementation always prints struct\n\t\t// even for Bazel provider instances.\n\t\tbuf.WriteString(\"struct\") // avoid String()'s quotation\n\t} else {\n\t\tbuf.WriteString(s.constructor.String())\n\t}\n\tbuf.WriteByte('(')\n\tfor i, e := range s.entries {\n\t\tif i > 0 {\n\t\t\tbuf.WriteString(\", \")\n\t\t}\n\t\tbuf.WriteString(e.name)\n\t\tbuf.WriteString(\" = \")\n\t\tbuf.WriteString(e.value.String())\n\t}\n\tbuf.WriteByte(')')\n\treturn buf.String()\n}\n\n// Constructor returns the constructor used to create this struct.\nfunc (s *Struct) Constructor() starlark.Value { return s.constructor }\n\nfunc (s *Struct) Type() string         { return \"struct\" }\nfunc (s *Struct) Truth() starlark.Bool { return true } // even when empty\nfunc (s *Struct) Hash() (uint32, error) {\n\t// Same algorithm as Tuple.hash, but with different primes.\n\tvar x, m uint32 = 8731, 9839\n\tfor _, e := range s.entries {\n\t\tnamehash, _ := starlark.String(e.name).Hash()\n\t\tx = x ^ 3*namehash\n\t\ty, err := e.value.Hash()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tx = x ^ y*m\n\t\tm += 7349\n\t}\n\treturn x, nil\n}\nfunc (s *Struct) Freeze() {\n\tfor _, e := range s.entries {\n\t\te.value.Freeze()\n\t}\n}\n\nfunc (x *Struct) Binary(op syntax.Token, y starlark.Value, side starlark.Side) (starlark.Value, error) {\n\tif y, ok := y.(*Struct); ok && op == syntax.PLUS {\n\t\tif side == starlark.Right {\n\t\t\tx, y = y, x\n\t\t}\n\n\t\tif eq, err := starlark.Equal(x.constructor, y.constructor); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"in %s + %s: error comparing constructors: %v\",\n\t\t\t\tx.constructor, y.constructor, err)\n\t\t} else if !eq {\n\t\t\treturn nil, fmt.Errorf(\"cannot add structs of different constructors: %s + %s\",\n\t\t\t\tx.constructor, y.constructor)\n\t\t}\n\n\t\tz := make(starlark.StringDict, x.len()+y.len())\n\t\tfor _, e := range x.entries {\n\t\t\tz[e.name] = e.value\n\t\t}\n\t\tfor _, e := range y.entries {\n\t\t\tz[e.name] = e.value\n\t\t}\n\n\t\treturn FromStringDict(x.constructor, z), nil\n\t}\n\treturn nil, nil // unhandled\n}\n\n// Attr returns the value of the specified field.\nfunc (s *Struct) Attr(name string) (starlark.Value, error) {\n\t// Binary search the entries.\n\t// This implementation is a specialization of\n\t// sort.Search that avoids dynamic dispatch.\n\tn := len(s.entries)\n\ti, j := 0, n\n\tfor i < j {\n\t\th := int(uint(i+j) >> 1)\n\t\tif s.entries[h].name < name {\n\t\t\ti = h + 1\n\t\t} else {\n\t\t\tj = h\n\t\t}\n\t}\n\tif i < n && s.entries[i].name == name {\n\t\treturn s.entries[i].value, nil\n\t}\n\n\tvar ctor string\n\tif s.constructor != Default {\n\t\tctor = s.constructor.String() + \" \"\n\t}\n\treturn nil, starlark.NoSuchAttrError(\n\t\tfmt.Sprintf(\"%sstruct has no .%s attribute\", ctor, name))\n}\n\nfunc (s *Struct) len() int { return len(s.entries) }\n\n// AttrNames returns a new sorted list of the struct fields.\nfunc (s *Struct) AttrNames() []string {\n\tnames := make([]string, len(s.entries))\n\tfor i, e := range s.entries {\n\t\tnames[i] = e.name\n\t}\n\treturn names\n}\n\nfunc (x *Struct) CompareSameType(op syntax.Token, y_ starlark.Value, depth int) (bool, error) {\n\ty := y_.(*Struct)\n\tswitch op {\n\tcase syntax.EQL:\n\t\treturn structsEqual(x, y, depth)\n\tcase syntax.NEQ:\n\t\teq, err := structsEqual(x, y, depth)\n\t\treturn !eq, err\n\tdefault:\n\t\treturn false, fmt.Errorf(\"%s %s %s not implemented\", x.Type(), op, y.Type())\n\t}\n}\n\nfunc structsEqual(x, y *Struct, depth int) (bool, error) {\n\tif x.len() != y.len() {\n\t\treturn false, nil\n\t}\n\n\tif eq, err := starlark.Equal(x.constructor, y.constructor); err != nil {\n\t\treturn false, fmt.Errorf(\"error comparing struct constructors %v and %v: %v\",\n\t\t\tx.constructor, y.constructor, err)\n\t} else if !eq {\n\t\treturn false, nil\n\t}\n\n\tfor i, n := 0, x.len(); i < n; i++ {\n\t\tif x.entries[i].name != y.entries[i].name {\n\t\t\treturn false, nil\n\t\t} else if eq, err := starlark.EqualDepth(x.entries[i].value, y.entries[i].value, depth-1); err != nil {\n\t\t\treturn false, err\n\t\t} else if !eq {\n\t\t\treturn false, nil\n\t\t}\n\t}\n\treturn true, nil\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/syntax/grammar.txt",
    "content": "\nGrammar of Starlark\n==================\n\nFile = {Statement | newline} eof .\n\nStatement = DefStmt | IfStmt | ForStmt | WhileStmt | SimpleStmt .\n\nDefStmt = 'def' identifier '(' [Parameters [',']] ')' ':' Suite .\n\nParameters = Parameter {',' Parameter}.\n\nParameter = identifier | identifier '=' Test | '*' | '*' identifier | '**' identifier .\n\nIfStmt = 'if' Test ':' Suite {'elif' Test ':' Suite} ['else' ':' Suite] .\n\nForStmt = 'for' LoopVariables 'in' Expression ':' Suite .\n\nWhileStmt = 'while' Test ':' Suite .\n\nSuite = [newline indent {Statement} outdent] | SimpleStmt .\n\nSimpleStmt = SmallStmt {';' SmallStmt} [';'] '\\n' .\n# NOTE: '\\n' optional at EOF\n\nSmallStmt = ReturnStmt\n          | BreakStmt | ContinueStmt | PassStmt\n          | AssignStmt\n          | ExprStmt\n          | LoadStmt\n          .\n\nReturnStmt   = 'return' [Expression] .\nBreakStmt    = 'break' .\nContinueStmt = 'continue' .\nPassStmt     = 'pass' .\nAssignStmt   = Expression ('=' | '+=' | '-=' | '*=' | '/=' | '//=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=') Expression .\nExprStmt     = Expression .\n\nLoadStmt = 'load' '(' string {',' [identifier '='] string} [','] ')' .\n\nTest = LambdaExpr\n     | IfExpr\n     | PrimaryExpr\n     | UnaryExpr\n     | BinaryExpr\n     .\n\nLambdaExpr = 'lambda' [Parameters] ':' Test .\n\nIfExpr = Test 'if' Test 'else' Test .\n\nPrimaryExpr = Operand\n            | PrimaryExpr DotSuffix\n            | PrimaryExpr CallSuffix\n            | PrimaryExpr SliceSuffix\n            .\n\nOperand = identifier\n        | int | float | string\n        | ListExpr | ListComp\n        | DictExpr | DictComp\n        | '(' [Expression [',']] ')'\n        | ('-' | '+') PrimaryExpr\n        .\n\nDotSuffix   = '.' identifier .\nCallSuffix  = '(' [Arguments [',']] ')' .\nSliceSuffix = '[' [Expression] [':' Test [':' Test]] ']' .\n\nArguments = Argument {',' Argument} .\nArgument  = Test | identifier '=' Test | '*' Test | '**' Test .\n\nListExpr = '[' [Expression [',']] ']' .\nListComp = '[' Test {CompClause} ']'.\n\nDictExpr = '{' [Entries [',']] '}' .\nDictComp = '{' Entry {CompClause} '}' .\nEntries  = Entry {',' Entry} .\nEntry    = Test ':' Test .\n\nCompClause = 'for' LoopVariables 'in' Test | 'if' Test .\n\nUnaryExpr = 'not' Test .\n\nBinaryExpr = Test {Binop Test} .\n\nBinop = 'or'\n      | 'and'\n      | '==' | '!=' | '<' | '>' | '<=' | '>=' | 'in' | 'not' 'in'\n      | '|'\n      | '^'\n      | '&'\n      | '-' | '+'\n      | '*' | '%' | '/' | '//'\n      .\n\nExpression = Test {',' Test} .\n# NOTE: trailing comma permitted only when within [...] or (...).\n\nLoopVariables = PrimaryExpr {',' PrimaryExpr} .\n\n\n# Notation (similar to Go spec):\n- lowercase and 'quoted' items are lexical tokens.\n- Capitalized names denote grammar productions.\n- (...) implies grouping\n- x | y means either x or y.\n- [x] means x is optional\n- {x} means x is repeated zero or more times\n- The end of each declaration is marked with a period.\n\n# Tokens\n- spaces: newline, eof, indent, outdent.\n- identifier.\n- literals: string, int, float.\n- plus all quoted tokens such as '+=', 'return'.\n\n# Notes:\n- Ambiguity is resolved using operator precedence.\n- The grammar does not enforce the legal order of params and args,\n  nor that the first compclause must be a 'for'.\n\nTODO:\n- explain how the lexer generates indent, outdent, and newline tokens.\n- why is unary NOT separated from unary - and +?\n- the grammar is (mostly) in LL(1) style so, for example,\n  dot expressions are formed suffixes, not complete expressions,\n  which makes the spec harder to read.  Reorganize into non-LL(1) form?\n"
  },
  {
    "path": "vendor/go.starlark.net/syntax/parse.go",
    "content": "// Copyright 2017 The Bazel 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 syntax\n\n// This file defines a recursive-descent parser for Starlark.\n// The LL(1) grammar of Starlark and the names of many productions follow Python 2.7.\n//\n// TODO(adonovan): use syntax.Error more systematically throughout the\n// package.  Verify that error positions are correct using the\n// chunkedfile mechanism.\n\nimport \"log\"\n\n// Enable this flag to print the token stream and log.Fatal on the first error.\nconst debug = false\n\n// A Mode value is a set of flags (or 0) that controls optional parser functionality.\ntype Mode uint\n\nconst (\n\tRetainComments Mode = 1 << iota // retain comments in AST; see Node.Comments\n)\n\n// Parse parses the input data and returns the corresponding parse tree.\n//\n// If src != nil, ParseFile parses the source from src and the filename\n// is only used when recording position information.\n// The type of the argument for the src parameter must be string,\n// []byte, or io.Reader.\n// If src == nil, ParseFile parses the file specified by filename.\nfunc Parse(filename string, src interface{}, mode Mode) (f *File, err error) {\n\tin, err := newScanner(filename, src, mode&RetainComments != 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tp := parser{in: in}\n\tdefer p.in.recover(&err)\n\n\tp.nextToken() // read first lookahead token\n\tf = p.parseFile()\n\tif f != nil {\n\t\tf.Path = filename\n\t}\n\tp.assignComments(f)\n\treturn f, nil\n}\n\n// ParseCompoundStmt parses a single compound statement:\n// a blank line, a def, for, while, or if statement, or a\n// semicolon-separated list of simple statements followed\n// by a newline. These are the units on which the REPL operates.\n// ParseCompoundStmt does not consume any following input.\n// The parser calls the readline function each\n// time it needs a new line of input.\nfunc ParseCompoundStmt(filename string, readline func() ([]byte, error)) (f *File, err error) {\n\tin, err := newScanner(filename, readline, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tp := parser{in: in}\n\tdefer p.in.recover(&err)\n\n\tp.nextToken() // read first lookahead token\n\n\tvar stmts []Stmt\n\tswitch p.tok {\n\tcase DEF, IF, FOR, WHILE:\n\t\tstmts = p.parseStmt(stmts)\n\tcase NEWLINE:\n\t\t// blank line\n\tdefault:\n\t\tstmts = p.parseSimpleStmt(stmts, false)\n\t\t// Require but don't consume newline, to avoid blocking again.\n\t\tif p.tok != NEWLINE {\n\t\t\tp.in.errorf(p.in.pos, \"invalid syntax\")\n\t\t}\n\t}\n\n\treturn &File{Path: filename, Stmts: stmts}, nil\n}\n\n// ParseExpr parses a Starlark expression.\n// A comma-separated list of expressions is parsed as a tuple.\n// See Parse for explanation of parameters.\nfunc ParseExpr(filename string, src interface{}, mode Mode) (expr Expr, err error) {\n\tin, err := newScanner(filename, src, mode&RetainComments != 0)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tp := parser{in: in}\n\tdefer p.in.recover(&err)\n\n\tp.nextToken() // read first lookahead token\n\n\t// Use parseExpr, not parseTest, to permit an unparenthesized tuple.\n\texpr = p.parseExpr(false)\n\n\t// A following newline (e.g. \"f()\\n\") appears outside any brackets,\n\t// on a non-blank line, and thus results in a NEWLINE token.\n\tif p.tok == NEWLINE {\n\t\tp.nextToken()\n\t}\n\n\tif p.tok != EOF {\n\t\tp.in.errorf(p.in.pos, \"got %#v after expression, want EOF\", p.tok)\n\t}\n\tp.assignComments(expr)\n\treturn expr, nil\n}\n\ntype parser struct {\n\tin     *scanner\n\ttok    Token\n\ttokval tokenValue\n}\n\n// nextToken advances the scanner and returns the position of the\n// previous token.\nfunc (p *parser) nextToken() Position {\n\toldpos := p.tokval.pos\n\tp.tok = p.in.nextToken(&p.tokval)\n\t// enable to see the token stream\n\tif debug {\n\t\tlog.Printf(\"nextToken: %-20s%+v\\n\", p.tok, p.tokval.pos)\n\t}\n\treturn oldpos\n}\n\n// file_input = (NEWLINE | stmt)* EOF\nfunc (p *parser) parseFile() *File {\n\tvar stmts []Stmt\n\tfor p.tok != EOF {\n\t\tif p.tok == NEWLINE {\n\t\t\tp.nextToken()\n\t\t\tcontinue\n\t\t}\n\t\tstmts = p.parseStmt(stmts)\n\t}\n\treturn &File{Stmts: stmts}\n}\n\nfunc (p *parser) parseStmt(stmts []Stmt) []Stmt {\n\tif p.tok == DEF {\n\t\treturn append(stmts, p.parseDefStmt())\n\t} else if p.tok == IF {\n\t\treturn append(stmts, p.parseIfStmt())\n\t} else if p.tok == FOR {\n\t\treturn append(stmts, p.parseForStmt())\n\t} else if p.tok == WHILE {\n\t\treturn append(stmts, p.parseWhileStmt())\n\t}\n\treturn p.parseSimpleStmt(stmts, true)\n}\n\nfunc (p *parser) parseDefStmt() Stmt {\n\tdefpos := p.nextToken() // consume DEF\n\tid := p.parseIdent()\n\tp.consume(LPAREN)\n\tparams := p.parseParams()\n\tp.consume(RPAREN)\n\tp.consume(COLON)\n\tbody := p.parseSuite()\n\treturn &DefStmt{\n\t\tDef:    defpos,\n\t\tName:   id,\n\t\tParams: params,\n\t\tBody:   body,\n\t}\n}\n\nfunc (p *parser) parseIfStmt() Stmt {\n\tifpos := p.nextToken() // consume IF\n\tcond := p.parseTest()\n\tp.consume(COLON)\n\tbody := p.parseSuite()\n\tifStmt := &IfStmt{\n\t\tIf:   ifpos,\n\t\tCond: cond,\n\t\tTrue: body,\n\t}\n\ttail := ifStmt\n\tfor p.tok == ELIF {\n\t\telifpos := p.nextToken() // consume ELIF\n\t\tcond := p.parseTest()\n\t\tp.consume(COLON)\n\t\tbody := p.parseSuite()\n\t\telif := &IfStmt{\n\t\t\tIf:   elifpos,\n\t\t\tCond: cond,\n\t\t\tTrue: body,\n\t\t}\n\t\ttail.ElsePos = elifpos\n\t\ttail.False = []Stmt{elif}\n\t\ttail = elif\n\t}\n\tif p.tok == ELSE {\n\t\ttail.ElsePos = p.nextToken() // consume ELSE\n\t\tp.consume(COLON)\n\t\ttail.False = p.parseSuite()\n\t}\n\treturn ifStmt\n}\n\nfunc (p *parser) parseForStmt() Stmt {\n\tforpos := p.nextToken() // consume FOR\n\tvars := p.parseForLoopVariables()\n\tp.consume(IN)\n\tx := p.parseExpr(false)\n\tp.consume(COLON)\n\tbody := p.parseSuite()\n\treturn &ForStmt{\n\t\tFor:  forpos,\n\t\tVars: vars,\n\t\tX:    x,\n\t\tBody: body,\n\t}\n}\n\nfunc (p *parser) parseWhileStmt() Stmt {\n\twhilepos := p.nextToken() // consume WHILE\n\tcond := p.parseTest()\n\tp.consume(COLON)\n\tbody := p.parseSuite()\n\treturn &WhileStmt{\n\t\tWhile: whilepos,\n\t\tCond:  cond,\n\t\tBody:  body,\n\t}\n}\n\n// Equivalent to 'exprlist' production in Python grammar.\n//\n// loop_variables = primary_with_suffix (COMMA primary_with_suffix)* COMMA?\nfunc (p *parser) parseForLoopVariables() Expr {\n\t// Avoid parseExpr because it would consume the IN token\n\t// following x in \"for x in y: ...\".\n\tv := p.parsePrimaryWithSuffix()\n\tif p.tok != COMMA {\n\t\treturn v\n\t}\n\n\tlist := []Expr{v}\n\tfor p.tok == COMMA {\n\t\tp.nextToken()\n\t\tif terminatesExprList(p.tok) {\n\t\t\tbreak\n\t\t}\n\t\tlist = append(list, p.parsePrimaryWithSuffix())\n\t}\n\treturn &TupleExpr{List: list}\n}\n\n// simple_stmt = small_stmt (SEMI small_stmt)* SEMI? NEWLINE\n// In REPL mode, it does not consume the NEWLINE.\nfunc (p *parser) parseSimpleStmt(stmts []Stmt, consumeNL bool) []Stmt {\n\tfor {\n\t\tstmts = append(stmts, p.parseSmallStmt())\n\t\tif p.tok != SEMI {\n\t\t\tbreak\n\t\t}\n\t\tp.nextToken() // consume SEMI\n\t\tif p.tok == NEWLINE || p.tok == EOF {\n\t\t\tbreak\n\t\t}\n\t}\n\t// EOF without NEWLINE occurs in `if x: pass`, for example.\n\tif p.tok != EOF && consumeNL {\n\t\tp.consume(NEWLINE)\n\t}\n\n\treturn stmts\n}\n\n// small_stmt = RETURN expr?\n//            | PASS | BREAK | CONTINUE\n//            | LOAD ...\n//            | expr ('=' | '+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | '<<=' | '>>=') expr   // assign\n//            | expr\nfunc (p *parser) parseSmallStmt() Stmt {\n\tswitch p.tok {\n\tcase RETURN:\n\t\tpos := p.nextToken() // consume RETURN\n\t\tvar result Expr\n\t\tif p.tok != EOF && p.tok != NEWLINE && p.tok != SEMI {\n\t\t\tresult = p.parseExpr(false)\n\t\t}\n\t\treturn &ReturnStmt{Return: pos, Result: result}\n\n\tcase BREAK, CONTINUE, PASS:\n\t\ttok := p.tok\n\t\tpos := p.nextToken() // consume it\n\t\treturn &BranchStmt{Token: tok, TokenPos: pos}\n\n\tcase LOAD:\n\t\treturn p.parseLoadStmt()\n\t}\n\n\t// Assignment\n\tx := p.parseExpr(false)\n\tswitch p.tok {\n\tcase EQ, PLUS_EQ, MINUS_EQ, STAR_EQ, SLASH_EQ, SLASHSLASH_EQ, PERCENT_EQ, AMP_EQ, PIPE_EQ, CIRCUMFLEX_EQ, LTLT_EQ, GTGT_EQ:\n\t\top := p.tok\n\t\tpos := p.nextToken() // consume op\n\t\trhs := p.parseExpr(false)\n\t\treturn &AssignStmt{OpPos: pos, Op: op, LHS: x, RHS: rhs}\n\t}\n\n\t// Expression statement (e.g. function call, doc string).\n\treturn &ExprStmt{X: x}\n}\n\n// stmt = LOAD '(' STRING {',' (IDENT '=')? STRING} [','] ')'\nfunc (p *parser) parseLoadStmt() *LoadStmt {\n\tloadPos := p.nextToken() // consume LOAD\n\tlparen := p.consume(LPAREN)\n\n\tif p.tok != STRING {\n\t\tp.in.errorf(p.in.pos, \"first operand of load statement must be a string literal\")\n\t}\n\tmodule := p.parsePrimary().(*Literal)\n\n\tvar from, to []*Ident\n\tfor p.tok != RPAREN && p.tok != EOF {\n\t\tp.consume(COMMA)\n\t\tif p.tok == RPAREN {\n\t\t\tbreak // allow trailing comma\n\t\t}\n\t\tswitch p.tok {\n\t\tcase STRING:\n\t\t\t// load(\"module\", \"id\")\n\t\t\t// To name is same as original.\n\t\t\tlit := p.parsePrimary().(*Literal)\n\t\t\tid := &Ident{\n\t\t\t\tNamePos: lit.TokenPos.add(`\"`),\n\t\t\t\tName:    lit.Value.(string),\n\t\t\t}\n\t\t\tto = append(to, id)\n\t\t\tfrom = append(from, id)\n\n\t\tcase IDENT:\n\t\t\t// load(\"module\", to=\"from\")\n\t\t\tid := p.parseIdent()\n\t\t\tto = append(to, id)\n\t\t\tif p.tok != EQ {\n\t\t\t\tp.in.errorf(p.in.pos, `load operand must be \"%[1]s\" or %[1]s=\"originalname\" (want '=' after %[1]s)`, id.Name)\n\t\t\t}\n\t\t\tp.consume(EQ)\n\t\t\tif p.tok != STRING {\n\t\t\t\tp.in.errorf(p.in.pos, `original name of loaded symbol must be quoted: %s=\"originalname\"`, id.Name)\n\t\t\t}\n\t\t\tlit := p.parsePrimary().(*Literal)\n\t\t\tfrom = append(from, &Ident{\n\t\t\t\tNamePos: lit.TokenPos.add(`\"`),\n\t\t\t\tName:    lit.Value.(string),\n\t\t\t})\n\n\t\tcase RPAREN:\n\t\t\tp.in.errorf(p.in.pos, \"trailing comma in load statement\")\n\n\t\tdefault:\n\t\t\tp.in.errorf(p.in.pos, `load operand must be \"name\" or localname=\"name\" (got %#v)`, p.tok)\n\t\t}\n\t}\n\trparen := p.consume(RPAREN)\n\n\tif len(to) == 0 {\n\t\tp.in.errorf(lparen, \"load statement must import at least 1 symbol\")\n\t}\n\treturn &LoadStmt{\n\t\tLoad:   loadPos,\n\t\tModule: module,\n\t\tTo:     to,\n\t\tFrom:   from,\n\t\tRparen: rparen,\n\t}\n}\n\n// suite is typically what follows a COLON (e.g. after DEF or FOR).\n// suite = simple_stmt | NEWLINE INDENT stmt+ OUTDENT\nfunc (p *parser) parseSuite() []Stmt {\n\tif p.tok == NEWLINE {\n\t\tp.nextToken() // consume NEWLINE\n\t\tp.consume(INDENT)\n\t\tvar stmts []Stmt\n\t\tfor p.tok != OUTDENT && p.tok != EOF {\n\t\t\tstmts = p.parseStmt(stmts)\n\t\t}\n\t\tp.consume(OUTDENT)\n\t\treturn stmts\n\t}\n\n\treturn p.parseSimpleStmt(nil, true)\n}\n\nfunc (p *parser) parseIdent() *Ident {\n\tif p.tok != IDENT {\n\t\tp.in.error(p.in.pos, \"not an identifier\")\n\t}\n\tid := &Ident{\n\t\tNamePos: p.tokval.pos,\n\t\tName:    p.tokval.raw,\n\t}\n\tp.nextToken()\n\treturn id\n}\n\nfunc (p *parser) consume(t Token) Position {\n\tif p.tok != t {\n\t\tp.in.errorf(p.in.pos, \"got %#v, want %#v\", p.tok, t)\n\t}\n\treturn p.nextToken()\n}\n\n// params = (param COMMA)* param COMMA?\n//        |\n//\n// param = IDENT\n//       | IDENT EQ test\n//       | STAR\n//       | STAR IDENT\n//       | STARSTAR IDENT\n//\n// parseParams parses a parameter list.  The resulting expressions are of the form:\n//\n//      *Ident                                          x\n//      *Binary{Op: EQ, X: *Ident, Y: Expr}             x=y\n//      *Unary{Op: STAR}                                *\n//      *Unary{Op: STAR, X: *Ident}                     *args\n//      *Unary{Op: STARSTAR, X: *Ident}                 **kwargs\nfunc (p *parser) parseParams() []Expr {\n\tvar params []Expr\n\tfor p.tok != RPAREN && p.tok != COLON && p.tok != EOF {\n\t\tif len(params) > 0 {\n\t\t\tp.consume(COMMA)\n\t\t}\n\t\tif p.tok == RPAREN {\n\t\t\tbreak\n\t\t}\n\n\t\t// * or *args or **kwargs\n\t\tif p.tok == STAR || p.tok == STARSTAR {\n\t\t\top := p.tok\n\t\t\tpos := p.nextToken()\n\t\t\tvar x Expr\n\t\t\tif op == STARSTAR || p.tok == IDENT {\n\t\t\t\tx = p.parseIdent()\n\t\t\t}\n\t\t\tparams = append(params, &UnaryExpr{\n\t\t\t\tOpPos: pos,\n\t\t\t\tOp:    op,\n\t\t\t\tX:     x,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\t// IDENT\n\t\t// IDENT = test\n\t\tid := p.parseIdent()\n\t\tif p.tok == EQ { // default value\n\t\t\teq := p.nextToken()\n\t\t\tdflt := p.parseTest()\n\t\t\tparams = append(params, &BinaryExpr{\n\t\t\t\tX:     id,\n\t\t\t\tOpPos: eq,\n\t\t\t\tOp:    EQ,\n\t\t\t\tY:     dflt,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\tparams = append(params, id)\n\t}\n\treturn params\n}\n\n// parseExpr parses an expression, possible consisting of a\n// comma-separated list of 'test' expressions.\n//\n// In many cases we must use parseTest to avoid ambiguity such as\n// f(x, y) vs. f((x, y)).\nfunc (p *parser) parseExpr(inParens bool) Expr {\n\tx := p.parseTest()\n\tif p.tok != COMMA {\n\t\treturn x\n\t}\n\n\t// tuple\n\texprs := p.parseExprs([]Expr{x}, inParens)\n\treturn &TupleExpr{List: exprs}\n}\n\n// parseExprs parses a comma-separated list of expressions, starting with the comma.\n// It is used to parse tuples and list elements.\n// expr_list = (',' expr)* ','?\nfunc (p *parser) parseExprs(exprs []Expr, allowTrailingComma bool) []Expr {\n\tfor p.tok == COMMA {\n\t\tpos := p.nextToken()\n\t\tif terminatesExprList(p.tok) {\n\t\t\tif !allowTrailingComma {\n\t\t\t\tp.in.error(pos, \"unparenthesized tuple with trailing comma\")\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\texprs = append(exprs, p.parseTest())\n\t}\n\treturn exprs\n}\n\n// parseTest parses a 'test', a single-component expression.\nfunc (p *parser) parseTest() Expr {\n\tif p.tok == LAMBDA {\n\t\treturn p.parseLambda(true)\n\t}\n\n\tx := p.parseTestPrec(0)\n\n\t// conditional expression (t IF cond ELSE f)\n\tif p.tok == IF {\n\t\tifpos := p.nextToken()\n\t\tcond := p.parseTestPrec(0)\n\t\tif p.tok != ELSE {\n\t\t\tp.in.error(ifpos, \"conditional expression without else clause\")\n\t\t}\n\t\telsepos := p.nextToken()\n\t\telse_ := p.parseTest()\n\t\treturn &CondExpr{If: ifpos, Cond: cond, True: x, ElsePos: elsepos, False: else_}\n\t}\n\n\treturn x\n}\n\n// parseTestNoCond parses a a single-component expression without\n// consuming a trailing 'if expr else expr'.\nfunc (p *parser) parseTestNoCond() Expr {\n\tif p.tok == LAMBDA {\n\t\treturn p.parseLambda(false)\n\t}\n\treturn p.parseTestPrec(0)\n}\n\n// parseLambda parses a lambda expression.\n// The allowCond flag allows the body to be an 'a if b else c' conditional.\nfunc (p *parser) parseLambda(allowCond bool) Expr {\n\tlambda := p.nextToken()\n\tvar params []Expr\n\tif p.tok != COLON {\n\t\tparams = p.parseParams()\n\t}\n\tp.consume(COLON)\n\n\tvar body Expr\n\tif allowCond {\n\t\tbody = p.parseTest()\n\t} else {\n\t\tbody = p.parseTestNoCond()\n\t}\n\n\treturn &LambdaExpr{\n\t\tLambda: lambda,\n\t\tParams: params,\n\t\tBody:   body,\n\t}\n}\n\nfunc (p *parser) parseTestPrec(prec int) Expr {\n\tif prec >= len(preclevels) {\n\t\treturn p.parsePrimaryWithSuffix()\n\t}\n\n\t// expr = NOT expr\n\tif p.tok == NOT && prec == int(precedence[NOT]) {\n\t\tpos := p.nextToken()\n\t\tx := p.parseTestPrec(prec)\n\t\treturn &UnaryExpr{\n\t\t\tOpPos: pos,\n\t\t\tOp:    NOT,\n\t\t\tX:     x,\n\t\t}\n\t}\n\n\treturn p.parseBinopExpr(prec)\n}\n\n// expr = test (OP test)*\n// Uses precedence climbing; see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm#climbing.\nfunc (p *parser) parseBinopExpr(prec int) Expr {\n\tx := p.parseTestPrec(prec + 1)\n\tfor first := true; ; first = false {\n\t\tif p.tok == NOT {\n\t\t\tp.nextToken() // consume NOT\n\t\t\t// In this context, NOT must be followed by IN.\n\t\t\t// Replace NOT IN by a single NOT_IN token.\n\t\t\tif p.tok != IN {\n\t\t\t\tp.in.errorf(p.in.pos, \"got %#v, want in\", p.tok)\n\t\t\t}\n\t\t\tp.tok = NOT_IN\n\t\t}\n\n\t\t// Binary operator of specified precedence?\n\t\topprec := int(precedence[p.tok])\n\t\tif opprec < prec {\n\t\t\treturn x\n\t\t}\n\n\t\t// Comparisons are non-associative.\n\t\tif !first && opprec == int(precedence[EQL]) {\n\t\t\tp.in.errorf(p.in.pos, \"%s does not associate with %s (use parens)\",\n\t\t\t\tx.(*BinaryExpr).Op, p.tok)\n\t\t}\n\n\t\top := p.tok\n\t\tpos := p.nextToken()\n\t\ty := p.parseTestPrec(opprec + 1)\n\t\tx = &BinaryExpr{OpPos: pos, Op: op, X: x, Y: y}\n\t}\n}\n\n// precedence maps each operator to its precedence (0-7), or -1 for other tokens.\nvar precedence [maxToken]int8\n\n// preclevels groups operators of equal precedence.\n// Comparisons are nonassociative; other binary operators associate to the left.\n// Unary MINUS, unary PLUS, and TILDE have higher precedence so are handled in parsePrimary.\n// See https://github.com/google/starlark-go/blob/master/doc/spec.md#binary-operators\nvar preclevels = [...][]Token{\n\t{OR},                                   // or\n\t{AND},                                  // and\n\t{NOT},                                  // not (unary)\n\t{EQL, NEQ, LT, GT, LE, GE, IN, NOT_IN}, // == != < > <= >= in not in\n\t{PIPE},                                 // |\n\t{CIRCUMFLEX},                           // ^\n\t{AMP},                                  // &\n\t{LTLT, GTGT},                           // << >>\n\t{MINUS, PLUS},                          // -\n\t{STAR, PERCENT, SLASH, SLASHSLASH},     // * % / //\n}\n\nfunc init() {\n\t// populate precedence table\n\tfor i := range precedence {\n\t\tprecedence[i] = -1\n\t}\n\tfor level, tokens := range preclevels {\n\t\tfor _, tok := range tokens {\n\t\t\tprecedence[tok] = int8(level)\n\t\t}\n\t}\n}\n\n// primary_with_suffix = primary\n//                     | primary '.' IDENT\n//                     | primary slice_suffix\n//                     | primary call_suffix\nfunc (p *parser) parsePrimaryWithSuffix() Expr {\n\tx := p.parsePrimary()\n\tfor {\n\t\tswitch p.tok {\n\t\tcase DOT:\n\t\t\tdot := p.nextToken()\n\t\t\tid := p.parseIdent()\n\t\t\tx = &DotExpr{Dot: dot, X: x, Name: id}\n\t\tcase LBRACK:\n\t\t\tx = p.parseSliceSuffix(x)\n\t\tcase LPAREN:\n\t\t\tx = p.parseCallSuffix(x)\n\t\tdefault:\n\t\t\treturn x\n\t\t}\n\t}\n}\n\n// slice_suffix = '[' expr? ':' expr?  ':' expr? ']'\nfunc (p *parser) parseSliceSuffix(x Expr) Expr {\n\tlbrack := p.nextToken()\n\tvar lo, hi, step Expr\n\tif p.tok != COLON {\n\t\ty := p.parseExpr(false)\n\n\t\t// index x[y]\n\t\tif p.tok == RBRACK {\n\t\t\trbrack := p.nextToken()\n\t\t\treturn &IndexExpr{X: x, Lbrack: lbrack, Y: y, Rbrack: rbrack}\n\t\t}\n\n\t\tlo = y\n\t}\n\n\t// slice or substring x[lo:hi:step]\n\tif p.tok == COLON {\n\t\tp.nextToken()\n\t\tif p.tok != COLON && p.tok != RBRACK {\n\t\t\thi = p.parseTest()\n\t\t}\n\t}\n\tif p.tok == COLON {\n\t\tp.nextToken()\n\t\tif p.tok != RBRACK {\n\t\t\tstep = p.parseTest()\n\t\t}\n\t}\n\trbrack := p.consume(RBRACK)\n\treturn &SliceExpr{X: x, Lbrack: lbrack, Lo: lo, Hi: hi, Step: step, Rbrack: rbrack}\n}\n\n// call_suffix = '(' arg_list? ')'\nfunc (p *parser) parseCallSuffix(fn Expr) Expr {\n\tlparen := p.consume(LPAREN)\n\tvar rparen Position\n\tvar args []Expr\n\tif p.tok == RPAREN {\n\t\trparen = p.nextToken()\n\t} else {\n\t\targs = p.parseArgs()\n\t\trparen = p.consume(RPAREN)\n\t}\n\treturn &CallExpr{Fn: fn, Lparen: lparen, Args: args, Rparen: rparen}\n}\n\n// parseArgs parses a list of actual parameter values (arguments).\n// It mirrors the structure of parseParams.\n// arg_list = ((arg COMMA)* arg COMMA?)?\nfunc (p *parser) parseArgs() []Expr {\n\tvar args []Expr\n\tfor p.tok != RPAREN && p.tok != EOF {\n\t\tif len(args) > 0 {\n\t\t\tp.consume(COMMA)\n\t\t}\n\t\tif p.tok == RPAREN {\n\t\t\tbreak\n\t\t}\n\n\t\t// *args or **kwargs\n\t\tif p.tok == STAR || p.tok == STARSTAR {\n\t\t\top := p.tok\n\t\t\tpos := p.nextToken()\n\t\t\tx := p.parseTest()\n\t\t\targs = append(args, &UnaryExpr{\n\t\t\t\tOpPos: pos,\n\t\t\t\tOp:    op,\n\t\t\t\tX:     x,\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\n\t\t// We use a different strategy from Bazel here to stay within LL(1).\n\t\t// Instead of looking ahead two tokens (IDENT, EQ) we parse\n\t\t// 'test = test' then check that the first was an IDENT.\n\t\tx := p.parseTest()\n\n\t\tif p.tok == EQ {\n\t\t\t// name = value\n\t\t\tif _, ok := x.(*Ident); !ok {\n\t\t\t\tp.in.errorf(p.in.pos, \"keyword argument must have form name=expr\")\n\t\t\t}\n\t\t\teq := p.nextToken()\n\t\t\ty := p.parseTest()\n\t\t\tx = &BinaryExpr{\n\t\t\t\tX:     x,\n\t\t\t\tOpPos: eq,\n\t\t\t\tOp:    EQ,\n\t\t\t\tY:     y,\n\t\t\t}\n\t\t}\n\n\t\targs = append(args, x)\n\t}\n\treturn args\n}\n\n//  primary = IDENT\n//          | INT | FLOAT\n//          | STRING\n//          | '[' ...                    // list literal or comprehension\n//          | '{' ...                    // dict literal or comprehension\n//          | '(' ...                    // tuple or parenthesized expression\n//          | ('-'|'+'|'~') primary_with_suffix\nfunc (p *parser) parsePrimary() Expr {\n\tswitch p.tok {\n\tcase IDENT:\n\t\treturn p.parseIdent()\n\n\tcase INT, FLOAT, STRING:\n\t\tvar val interface{}\n\t\ttok := p.tok\n\t\tswitch tok {\n\t\tcase INT:\n\t\t\tif p.tokval.bigInt != nil {\n\t\t\t\tval = p.tokval.bigInt\n\t\t\t} else {\n\t\t\t\tval = p.tokval.int\n\t\t\t}\n\t\tcase FLOAT:\n\t\t\tval = p.tokval.float\n\t\tcase STRING:\n\t\t\tval = p.tokval.string\n\t\t}\n\t\traw := p.tokval.raw\n\t\tpos := p.nextToken()\n\t\treturn &Literal{Token: tok, TokenPos: pos, Raw: raw, Value: val}\n\n\tcase LBRACK:\n\t\treturn p.parseList()\n\n\tcase LBRACE:\n\t\treturn p.parseDict()\n\n\tcase LPAREN:\n\t\tlparen := p.nextToken()\n\t\tif p.tok == RPAREN {\n\t\t\t// empty tuple\n\t\t\trparen := p.nextToken()\n\t\t\treturn &TupleExpr{Lparen: lparen, Rparen: rparen}\n\t\t}\n\t\te := p.parseExpr(true) // allow trailing comma\n\t\trparen := p.consume(RPAREN)\n\t\treturn &ParenExpr{\n\t\t\tLparen: lparen,\n\t\t\tX:      e,\n\t\t\tRparen: rparen,\n\t\t}\n\n\tcase MINUS, PLUS, TILDE: // unary\n\t\ttok := p.tok\n\t\tpos := p.nextToken()\n\t\tx := p.parsePrimaryWithSuffix()\n\t\treturn &UnaryExpr{\n\t\t\tOpPos: pos,\n\t\t\tOp:    tok,\n\t\t\tX:     x,\n\t\t}\n\t}\n\tp.in.errorf(p.in.pos, \"got %#v, want primary expression\", p.tok)\n\tpanic(\"unreachable\")\n}\n\n// list = '[' ']'\n//      | '[' expr ']'\n//      | '[' expr expr_list ']'\n//      | '[' expr (FOR loop_variables IN expr)+ ']'\nfunc (p *parser) parseList() Expr {\n\tlbrack := p.nextToken()\n\tif p.tok == RBRACK {\n\t\t// empty List\n\t\trbrack := p.nextToken()\n\t\treturn &ListExpr{Lbrack: lbrack, Rbrack: rbrack}\n\t}\n\n\tx := p.parseTest()\n\n\tif p.tok == FOR {\n\t\t// list comprehension\n\t\treturn p.parseComprehensionSuffix(lbrack, x, RBRACK)\n\t}\n\n\texprs := []Expr{x}\n\tif p.tok == COMMA {\n\t\t// multi-item list literal\n\t\texprs = p.parseExprs(exprs, true) // allow trailing comma\n\t}\n\n\trbrack := p.consume(RBRACK)\n\treturn &ListExpr{Lbrack: lbrack, List: exprs, Rbrack: rbrack}\n}\n\n// dict = '{' '}'\n//      | '{' dict_entry_list '}'\n//      | '{' dict_entry FOR loop_variables IN expr '}'\nfunc (p *parser) parseDict() Expr {\n\tlbrace := p.nextToken()\n\tif p.tok == RBRACE {\n\t\t// empty dict\n\t\trbrace := p.nextToken()\n\t\treturn &DictExpr{Lbrace: lbrace, Rbrace: rbrace}\n\t}\n\n\tx := p.parseDictEntry()\n\n\tif p.tok == FOR {\n\t\t// dict comprehension\n\t\treturn p.parseComprehensionSuffix(lbrace, x, RBRACE)\n\t}\n\n\tentries := []Expr{x}\n\tfor p.tok == COMMA {\n\t\tp.nextToken()\n\t\tif p.tok == RBRACE {\n\t\t\tbreak\n\t\t}\n\t\tentries = append(entries, p.parseDictEntry())\n\t}\n\n\trbrace := p.consume(RBRACE)\n\treturn &DictExpr{Lbrace: lbrace, List: entries, Rbrace: rbrace}\n}\n\n// dict_entry = test ':' test\nfunc (p *parser) parseDictEntry() *DictEntry {\n\tk := p.parseTest()\n\tcolon := p.consume(COLON)\n\tv := p.parseTest()\n\treturn &DictEntry{Key: k, Colon: colon, Value: v}\n}\n\n// comp_suffix = FOR loopvars IN expr comp_suffix\n//             | IF expr comp_suffix\n//             | ']'  or  ')'                              (end)\n//\n// There can be multiple FOR/IF clauses; the first is always a FOR.\nfunc (p *parser) parseComprehensionSuffix(lbrace Position, body Expr, endBrace Token) Expr {\n\tvar clauses []Node\n\tfor p.tok != endBrace {\n\t\tif p.tok == FOR {\n\t\t\tpos := p.nextToken()\n\t\t\tvars := p.parseForLoopVariables()\n\t\t\tin := p.consume(IN)\n\t\t\t// Following Python 3, the operand of IN cannot be:\n\t\t\t// - a conditional expression ('x if y else z'),\n\t\t\t//   due to conflicts in Python grammar\n\t\t\t//  ('if' is used by the comprehension);\n\t\t\t// - a lambda expression\n\t\t\t// - an unparenthesized tuple.\n\t\t\tx := p.parseTestPrec(0)\n\t\t\tclauses = append(clauses, &ForClause{For: pos, Vars: vars, In: in, X: x})\n\t\t} else if p.tok == IF {\n\t\t\tpos := p.nextToken()\n\t\t\tcond := p.parseTestNoCond()\n\t\t\tclauses = append(clauses, &IfClause{If: pos, Cond: cond})\n\t\t} else {\n\t\t\tp.in.errorf(p.in.pos, \"got %#v, want '%s', for, or if\", p.tok, endBrace)\n\t\t}\n\t}\n\trbrace := p.nextToken()\n\n\treturn &Comprehension{\n\t\tCurly:   endBrace == RBRACE,\n\t\tLbrack:  lbrace,\n\t\tBody:    body,\n\t\tClauses: clauses,\n\t\tRbrack:  rbrace,\n\t}\n}\n\nfunc terminatesExprList(tok Token) bool {\n\tswitch tok {\n\tcase EOF, NEWLINE, EQ, RBRACE, RBRACK, RPAREN, SEMI:\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Comment assignment.\n// We build two lists of all subnodes, preorder and postorder.\n// The preorder list is ordered by start location, with outer nodes first.\n// The postorder list is ordered by end location, with outer nodes last.\n// We use the preorder list to assign each whole-line comment to the syntax\n// immediately following it, and we use the postorder list to assign each\n// end-of-line comment to the syntax immediately preceding it.\n\n// flattenAST returns the list of AST nodes, both in prefix order and in postfix\n// order.\nfunc flattenAST(root Node) (pre, post []Node) {\n\tstack := []Node{}\n\tWalk(root, func(n Node) bool {\n\t\tif n != nil {\n\t\t\tpre = append(pre, n)\n\t\t\tstack = append(stack, n)\n\t\t} else {\n\t\t\tpost = append(post, stack[len(stack)-1])\n\t\t\tstack = stack[:len(stack)-1]\n\t\t}\n\t\treturn true\n\t})\n\treturn pre, post\n}\n\n// assignComments attaches comments to nearby syntax.\nfunc (p *parser) assignComments(n Node) {\n\t// Leave early if there are no comments\n\tif len(p.in.lineComments)+len(p.in.suffixComments) == 0 {\n\t\treturn\n\t}\n\n\tpre, post := flattenAST(n)\n\n\t// Assign line comments to syntax immediately following.\n\tline := p.in.lineComments\n\tfor _, x := range pre {\n\t\tstart, _ := x.Span()\n\n\t\tswitch x.(type) {\n\t\tcase *File:\n\t\t\tcontinue\n\t\t}\n\n\t\tfor len(line) > 0 && !start.isBefore(line[0].Start) {\n\t\t\tx.AllocComments()\n\t\t\tx.Comments().Before = append(x.Comments().Before, line[0])\n\t\t\tline = line[1:]\n\t\t}\n\t}\n\n\t// Remaining line comments go at end of file.\n\tif len(line) > 0 {\n\t\tn.AllocComments()\n\t\tn.Comments().After = append(n.Comments().After, line...)\n\t}\n\n\t// Assign suffix comments to syntax immediately before.\n\tsuffix := p.in.suffixComments\n\tfor i := len(post) - 1; i >= 0; i-- {\n\t\tx := post[i]\n\n\t\t// Do not assign suffix comments to file\n\t\tswitch x.(type) {\n\t\tcase *File:\n\t\t\tcontinue\n\t\t}\n\n\t\t_, end := x.Span()\n\t\tif len(suffix) > 0 && end.isBefore(suffix[len(suffix)-1].Start) {\n\t\t\tx.AllocComments()\n\t\t\tx.Comments().Suffix = append(x.Comments().Suffix, suffix[len(suffix)-1])\n\t\t\tsuffix = suffix[:len(suffix)-1]\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/syntax/quote.go",
    "content": "// Copyright 2017 The Bazel 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 syntax\n\n// Starlark quoted string utilities.\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n)\n\n// unesc maps single-letter chars following \\ to their actual values.\nvar unesc = [256]byte{\n\t'a':  '\\a',\n\t'b':  '\\b',\n\t'f':  '\\f',\n\t'n':  '\\n',\n\t'r':  '\\r',\n\t't':  '\\t',\n\t'v':  '\\v',\n\t'\\\\': '\\\\',\n\t'\\'': '\\'',\n\t'\"':  '\"',\n}\n\n// esc maps escape-worthy bytes to the char that should follow \\.\nvar esc = [256]byte{\n\t'\\a': 'a',\n\t'\\b': 'b',\n\t'\\f': 'f',\n\t'\\n': 'n',\n\t'\\r': 'r',\n\t'\\t': 't',\n\t'\\v': 'v',\n\t'\\\\': '\\\\',\n\t'\\'': '\\'',\n\t'\"':  '\"',\n}\n\n// notEsc is a list of characters that can follow a \\ in a string value\n// without having to escape the \\. That is, since ( is in this list, we\n// quote the Go string \"foo\\\\(bar\" as the Python literal \"foo\\(bar\".\n// This really does happen in BUILD files, especially in strings\n// being used as shell arguments containing regular expressions.\nconst notEsc = \" !#$%&()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\"\n\n// unquote unquotes the quoted string, returning the actual\n// string value, whether the original was triple-quoted, and\n// an error describing invalid input.\nfunc unquote(quoted string) (s string, triple bool, err error) {\n\t// Check for raw prefix: means don't interpret the inner \\.\n\traw := false\n\tif strings.HasPrefix(quoted, \"r\") {\n\t\traw = true\n\t\tquoted = quoted[1:]\n\t}\n\n\tif len(quoted) < 2 {\n\t\terr = fmt.Errorf(\"string literal too short\")\n\t\treturn\n\t}\n\n\tif quoted[0] != '\"' && quoted[0] != '\\'' || quoted[0] != quoted[len(quoted)-1] {\n\t\terr = fmt.Errorf(\"string literal has invalid quotes\")\n\t\treturn\n\t}\n\n\t// Check for triple quoted string.\n\tquote := quoted[0]\n\tif len(quoted) >= 6 && quoted[1] == quote && quoted[2] == quote && quoted[:3] == quoted[len(quoted)-3:] {\n\t\ttriple = true\n\t\tquoted = quoted[3 : len(quoted)-3]\n\t} else {\n\t\tquoted = quoted[1 : len(quoted)-1]\n\t}\n\n\t// Now quoted is the quoted data, but no quotes.\n\t// If we're in raw mode or there are no escapes or\n\t// carriage returns, we're done.\n\tvar unquoteChars string\n\tif raw {\n\t\tunquoteChars = \"\\r\"\n\t} else {\n\t\tunquoteChars = \"\\\\\\r\"\n\t}\n\tif !strings.ContainsAny(quoted, unquoteChars) {\n\t\ts = quoted\n\t\treturn\n\t}\n\n\t// Otherwise process quoted string.\n\t// Each iteration processes one escape sequence along with the\n\t// plain text leading up to it.\n\tbuf := new(strings.Builder)\n\tfor {\n\t\t// Remove prefix before escape sequence.\n\t\ti := strings.IndexAny(quoted, unquoteChars)\n\t\tif i < 0 {\n\t\t\ti = len(quoted)\n\t\t}\n\t\tbuf.WriteString(quoted[:i])\n\t\tquoted = quoted[i:]\n\n\t\tif len(quoted) == 0 {\n\t\t\tbreak\n\t\t}\n\n\t\t// Process carriage return.\n\t\tif quoted[0] == '\\r' {\n\t\t\tbuf.WriteByte('\\n')\n\t\t\tif len(quoted) > 1 && quoted[1] == '\\n' {\n\t\t\t\tquoted = quoted[2:]\n\t\t\t} else {\n\t\t\t\tquoted = quoted[1:]\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\t// Process escape sequence.\n\t\tif len(quoted) == 1 {\n\t\t\terr = fmt.Errorf(`truncated escape sequence \\`)\n\t\t\treturn\n\t\t}\n\n\t\tswitch quoted[1] {\n\t\tdefault:\n\t\t\t// In Python, if \\z (for some byte z) is not a known escape sequence\n\t\t\t// then it appears as literal text in the string.\n\t\t\tbuf.WriteString(quoted[:2])\n\t\t\tquoted = quoted[2:]\n\n\t\tcase '\\n':\n\t\t\t// Ignore the escape and the line break.\n\t\t\tquoted = quoted[2:]\n\n\t\tcase 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\\\', '\\'', '\"':\n\t\t\t// One-char escape\n\t\t\tbuf.WriteByte(unesc[quoted[1]])\n\t\t\tquoted = quoted[2:]\n\n\t\tcase '0', '1', '2', '3', '4', '5', '6', '7':\n\t\t\t// Octal escape, up to 3 digits.\n\t\t\tn := int(quoted[1] - '0')\n\t\t\tquoted = quoted[2:]\n\t\t\tfor i := 1; i < 3; i++ {\n\t\t\t\tif len(quoted) == 0 || quoted[0] < '0' || '7' < quoted[0] {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tn = n*8 + int(quoted[0]-'0')\n\t\t\t\tquoted = quoted[1:]\n\t\t\t}\n\t\t\tif n >= 256 {\n\t\t\t\t// NOTE: Python silently discards the high bit,\n\t\t\t\t// so that '\\541' == '\\141' == 'a'.\n\t\t\t\t// Let's see if we can avoid doing that in BUILD files.\n\t\t\t\terr = fmt.Errorf(`invalid escape sequence \\%03o`, n)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbuf.WriteByte(byte(n))\n\n\t\tcase 'x':\n\t\t\t// Hexadecimal escape, exactly 2 digits.\n\t\t\tif len(quoted) < 4 {\n\t\t\t\terr = fmt.Errorf(`truncated escape sequence %s`, quoted)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tn, err1 := strconv.ParseUint(quoted[2:4], 16, 0)\n\t\t\tif err1 != nil {\n\t\t\t\terr = fmt.Errorf(`invalid escape sequence %s`, quoted[:4])\n\t\t\t\treturn\n\t\t\t}\n\t\t\tbuf.WriteByte(byte(n))\n\t\t\tquoted = quoted[4:]\n\t\t}\n\t}\n\n\ts = buf.String()\n\treturn\n}\n\n// indexByte returns the index of the first instance of b in s, or else -1.\nfunc indexByte(s string, b byte) int {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] == b {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\n// hex is a list of the hexadecimal digits, for use in quoting.\n// We always print lower-case hexadecimal.\nconst hex = \"0123456789abcdef\"\n\n// quote returns the quoted form of the string value \"x\".\n// If triple is true, quote uses the triple-quoted form \"\"\"x\"\"\".\nfunc quote(unquoted string, triple bool) string {\n\tq := `\"`\n\tif triple {\n\t\tq = `\"\"\"`\n\t}\n\n\tbuf := new(strings.Builder)\n\tbuf.WriteString(q)\n\n\tfor i := 0; i < len(unquoted); i++ {\n\t\tc := unquoted[i]\n\t\tif c == '\"' && triple && (i+1 < len(unquoted) && unquoted[i+1] != '\"' || i+2 < len(unquoted) && unquoted[i+2] != '\"') {\n\t\t\t// Can pass up to two quotes through, because they are followed by a non-quote byte.\n\t\t\tbuf.WriteByte(c)\n\t\t\tif i+1 < len(unquoted) && unquoted[i+1] == '\"' {\n\t\t\t\tbuf.WriteByte(c)\n\t\t\t\ti++\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif triple && c == '\\n' {\n\t\t\t// Can allow newline in triple-quoted string.\n\t\t\tbuf.WriteByte(c)\n\t\t\tcontinue\n\t\t}\n\t\tif c == '\\'' {\n\t\t\t// Can allow ' since we always use \".\n\t\t\tbuf.WriteByte(c)\n\t\t\tcontinue\n\t\t}\n\t\tif c == '\\\\' {\n\t\t\tif i+1 < len(unquoted) && indexByte(notEsc, unquoted[i+1]) >= 0 {\n\t\t\t\t// Can pass \\ through when followed by a byte that\n\t\t\t\t// known not to be a valid escape sequence and also\n\t\t\t\t// that does not trigger an escape sequence of its own.\n\t\t\t\t// Use this, because various BUILD files do.\n\t\t\t\tbuf.WriteByte('\\\\')\n\t\t\t\tbuf.WriteByte(unquoted[i+1])\n\t\t\t\ti++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif esc[c] != 0 {\n\t\t\tbuf.WriteByte('\\\\')\n\t\t\tbuf.WriteByte(esc[c])\n\t\t\tcontinue\n\t\t}\n\t\tif c < 0x20 || c >= 0x80 {\n\t\t\t// BUILD files are supposed to be Latin-1, so escape all control and high bytes.\n\t\t\t// I'd prefer to use \\x here, but Blaze does not implement\n\t\t\t// \\x in quoted strings (b/7272572).\n\t\t\tbuf.WriteByte('\\\\')\n\t\t\tbuf.WriteByte(hex[c>>6]) // actually octal but reusing hex digits 0-7.\n\t\t\tbuf.WriteByte(hex[(c>>3)&7])\n\t\t\tbuf.WriteByte(hex[c&7])\n\t\t\t/*\n\t\t\t\tbuf.WriteByte('\\\\')\n\t\t\t\tbuf.WriteByte('x')\n\t\t\t\tbuf.WriteByte(hex[c>>4])\n\t\t\t\tbuf.WriteByte(hex[c&0xF])\n\t\t\t*/\n\t\t\tcontinue\n\t\t}\n\t\tbuf.WriteByte(c)\n\t\tcontinue\n\t}\n\n\tbuf.WriteString(q)\n\treturn buf.String()\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/syntax/scan.go",
    "content": "// Copyright 2017 The Bazel 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 syntax\n\n// A lexical scanner for Starlark.\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"math/big\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\t\"unicode/utf8\"\n)\n\n// A Token represents a Starlark lexical token.\ntype Token int8\n\nconst (\n\tILLEGAL Token = iota\n\tEOF\n\n\tNEWLINE\n\tINDENT\n\tOUTDENT\n\n\t// Tokens with values\n\tIDENT  // x\n\tINT    // 123\n\tFLOAT  // 1.23e45\n\tSTRING // \"foo\" or 'foo' or '''foo''' or r'foo' or r\"foo\"\n\n\t// Punctuation\n\tPLUS          // +\n\tMINUS         // -\n\tSTAR          // *\n\tSLASH         // /\n\tSLASHSLASH    // //\n\tPERCENT       // %\n\tAMP           // &\n\tPIPE          // |\n\tCIRCUMFLEX    // ^\n\tLTLT          // <<\n\tGTGT          // >>\n\tTILDE         // ~\n\tDOT           // .\n\tCOMMA         // ,\n\tEQ            // =\n\tSEMI          // ;\n\tCOLON         // :\n\tLPAREN        // (\n\tRPAREN        // )\n\tLBRACK        // [\n\tRBRACK        // ]\n\tLBRACE        // {\n\tRBRACE        // }\n\tLT            // <\n\tGT            // >\n\tGE            // >=\n\tLE            // <=\n\tEQL           // ==\n\tNEQ           // !=\n\tPLUS_EQ       // +=    (keep order consistent with PLUS..GTGT)\n\tMINUS_EQ      // -=\n\tSTAR_EQ       // *=\n\tSLASH_EQ      // /=\n\tSLASHSLASH_EQ // //=\n\tPERCENT_EQ    // %=\n\tAMP_EQ        // &=\n\tPIPE_EQ       // |=\n\tCIRCUMFLEX_EQ // ^=\n\tLTLT_EQ       // <<=\n\tGTGT_EQ       // >>=\n\tSTARSTAR      // **\n\n\t// Keywords\n\tAND\n\tBREAK\n\tCONTINUE\n\tDEF\n\tELIF\n\tELSE\n\tFOR\n\tIF\n\tIN\n\tLAMBDA\n\tLOAD\n\tNOT\n\tNOT_IN // synthesized by parser from NOT IN\n\tOR\n\tPASS\n\tRETURN\n\tWHILE\n\n\tmaxToken\n)\n\nfunc (tok Token) String() string { return tokenNames[tok] }\n\n// GoString is like String but quotes punctuation tokens.\n// Use Sprintf(\"%#v\", tok) when constructing error messages.\nfunc (tok Token) GoString() string {\n\tif tok >= PLUS && tok <= STARSTAR {\n\t\treturn \"'\" + tokenNames[tok] + \"'\"\n\t}\n\treturn tokenNames[tok]\n}\n\nvar tokenNames = [...]string{\n\tILLEGAL:       \"illegal token\",\n\tEOF:           \"end of file\",\n\tNEWLINE:       \"newline\",\n\tINDENT:        \"indent\",\n\tOUTDENT:       \"outdent\",\n\tIDENT:         \"identifier\",\n\tINT:           \"int literal\",\n\tFLOAT:         \"float literal\",\n\tSTRING:        \"string literal\",\n\tPLUS:          \"+\",\n\tMINUS:         \"-\",\n\tSTAR:          \"*\",\n\tSLASH:         \"/\",\n\tSLASHSLASH:    \"//\",\n\tPERCENT:       \"%\",\n\tAMP:           \"&\",\n\tPIPE:          \"|\",\n\tCIRCUMFLEX:    \"^\",\n\tLTLT:          \"<<\",\n\tGTGT:          \">>\",\n\tTILDE:         \"~\",\n\tDOT:           \".\",\n\tCOMMA:         \",\",\n\tEQ:            \"=\",\n\tSEMI:          \";\",\n\tCOLON:         \":\",\n\tLPAREN:        \"(\",\n\tRPAREN:        \")\",\n\tLBRACK:        \"[\",\n\tRBRACK:        \"]\",\n\tLBRACE:        \"{\",\n\tRBRACE:        \"}\",\n\tLT:            \"<\",\n\tGT:            \">\",\n\tGE:            \">=\",\n\tLE:            \"<=\",\n\tEQL:           \"==\",\n\tNEQ:           \"!=\",\n\tPLUS_EQ:       \"+=\",\n\tMINUS_EQ:      \"-=\",\n\tSTAR_EQ:       \"*=\",\n\tSLASH_EQ:      \"/=\",\n\tSLASHSLASH_EQ: \"//=\",\n\tPERCENT_EQ:    \"%=\",\n\tAMP_EQ:        \"&=\",\n\tPIPE_EQ:       \"|=\",\n\tCIRCUMFLEX_EQ: \"^=\",\n\tLTLT_EQ:       \"<<=\",\n\tGTGT_EQ:       \">>=\",\n\tSTARSTAR:      \"**\",\n\tAND:           \"and\",\n\tBREAK:         \"break\",\n\tCONTINUE:      \"continue\",\n\tDEF:           \"def\",\n\tELIF:          \"elif\",\n\tELSE:          \"else\",\n\tFOR:           \"for\",\n\tIF:            \"if\",\n\tIN:            \"in\",\n\tLAMBDA:        \"lambda\",\n\tLOAD:          \"load\",\n\tNOT:           \"not\",\n\tNOT_IN:        \"not in\",\n\tOR:            \"or\",\n\tPASS:          \"pass\",\n\tRETURN:        \"return\",\n\tWHILE:         \"while\",\n}\n\n// A Position describes the location of a rune of input.\ntype Position struct {\n\tfile *string // filename (indirect for compactness)\n\tLine int32   // 1-based line number; 0 if line unknown\n\tCol  int32   // 1-based column (rune) number; 0 if column unknown\n}\n\n// IsValid reports whether the position is valid.\nfunc (p Position) IsValid() bool { return p.file != nil }\n\n// Filename returns the name of the file containing this position.\nfunc (p Position) Filename() string {\n\tif p.file != nil {\n\t\treturn *p.file\n\t}\n\treturn \"<invalid>\"\n}\n\n// MakePosition returns position with the specified components.\nfunc MakePosition(file *string, line, col int32) Position { return Position{file, line, col} }\n\n// add returns the position at the end of s, assuming it starts at p.\nfunc (p Position) add(s string) Position {\n\tif n := strings.Count(s, \"\\n\"); n > 0 {\n\t\tp.Line += int32(n)\n\t\ts = s[strings.LastIndex(s, \"\\n\")+1:]\n\t\tp.Col = 1\n\t}\n\tp.Col += int32(utf8.RuneCountInString(s))\n\treturn p\n}\n\nfunc (p Position) String() string {\n\tfile := p.Filename()\n\tif p.Line > 0 {\n\t\tif p.Col > 0 {\n\t\t\treturn fmt.Sprintf(\"%s:%d:%d\", file, p.Line, p.Col)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s:%d\", file, p.Line)\n\t}\n\treturn file\n}\n\nfunc (p Position) isBefore(q Position) bool {\n\tif p.Line != q.Line {\n\t\treturn p.Line < q.Line\n\t}\n\treturn p.Col < q.Col\n}\n\n// An scanner represents a single input file being parsed.\ntype scanner struct {\n\trest           []byte    // rest of input (in REPL, a line of input)\n\ttoken          []byte    // token being scanned\n\tpos            Position  // current input position\n\tdepth          int       // nesting of [ ] { } ( )\n\tindentstk      []int     // stack of indentation levels\n\tdents          int       // number of saved INDENT (>0) or OUTDENT (<0) tokens to return\n\tlineStart      bool      // after NEWLINE; convert spaces to indentation tokens\n\tkeepComments   bool      // accumulate comments in slice\n\tlineComments   []Comment // list of full line comments (if keepComments)\n\tsuffixComments []Comment // list of suffix comments (if keepComments)\n\n\treadline func() ([]byte, error) // read next line of input (REPL only)\n}\n\nfunc newScanner(filename string, src interface{}, keepComments bool) (*scanner, error) {\n\tsc := &scanner{\n\t\tpos:          Position{file: &filename, Line: 1, Col: 1},\n\t\tindentstk:    make([]int, 1, 10), // []int{0} + spare capacity\n\t\tlineStart:    true,\n\t\tkeepComments: keepComments,\n\t}\n\tsc.readline, _ = src.(func() ([]byte, error)) // REPL only\n\tif sc.readline == nil {\n\t\tdata, err := readSource(filename, src)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tsc.rest = data\n\t}\n\treturn sc, nil\n}\n\nfunc readSource(filename string, src interface{}) ([]byte, error) {\n\tswitch src := src.(type) {\n\tcase string:\n\t\treturn []byte(src), nil\n\tcase []byte:\n\t\treturn src, nil\n\tcase io.Reader:\n\t\tdata, err := ioutil.ReadAll(src)\n\t\tif err != nil {\n\t\t\terr = &os.PathError{Op: \"read\", Path: filename, Err: err}\n\t\t\treturn nil, err\n\t\t}\n\t\treturn data, nil\n\tcase nil:\n\t\treturn ioutil.ReadFile(filename)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"invalid source: %T\", src)\n\t}\n}\n\n// An Error describes the nature and position of a scanner or parser error.\ntype Error struct {\n\tPos Position\n\tMsg string\n}\n\nfunc (e Error) Error() string { return e.Pos.String() + \": \" + e.Msg }\n\n// errorf is called to report an error.\n// errorf does not return: it panics.\nfunc (sc *scanner) error(pos Position, s string) {\n\tpanic(Error{pos, s})\n}\n\nfunc (sc *scanner) errorf(pos Position, format string, args ...interface{}) {\n\tsc.error(pos, fmt.Sprintf(format, args...))\n}\n\nfunc (sc *scanner) recover(err *error) {\n\t// The scanner and parser panic both for routine errors like\n\t// syntax errors and for programmer bugs like array index\n\t// errors.  Turn both into error returns.  Catching bug panics\n\t// is especially important when processing many files.\n\tswitch e := recover().(type) {\n\tcase nil:\n\t\t// no panic\n\tcase Error:\n\t\t*err = e\n\tdefault:\n\t\t*err = Error{sc.pos, fmt.Sprintf(\"internal error: %v\", e)}\n\t\tif debug {\n\t\t\tlog.Fatal(*err)\n\t\t}\n\t}\n}\n\n// eof reports whether the input has reached end of file.\nfunc (sc *scanner) eof() bool {\n\treturn len(sc.rest) == 0 && !sc.readLine()\n}\n\n// readLine attempts to read another line of input.\n// Precondition: len(sc.rest)==0.\nfunc (sc *scanner) readLine() bool {\n\tif sc.readline != nil {\n\t\tvar err error\n\t\tsc.rest, err = sc.readline()\n\t\tif err != nil {\n\t\t\tsc.errorf(sc.pos, \"%v\", err) // EOF or ErrInterrupt\n\t\t}\n\t\treturn len(sc.rest) > 0\n\t}\n\treturn false\n}\n\n// peekRune returns the next rune in the input without consuming it.\n// Newlines in Unix, DOS, or Mac format are treated as one rune, '\\n'.\nfunc (sc *scanner) peekRune() rune {\n\t// TODO(adonovan): opt: measure and perhaps inline eof.\n\tif sc.eof() {\n\t\treturn 0\n\t}\n\n\t// fast path: ASCII\n\tif b := sc.rest[0]; b < utf8.RuneSelf {\n\t\tif b == '\\r' {\n\t\t\treturn '\\n'\n\t\t}\n\t\treturn rune(b)\n\t}\n\n\tr, _ := utf8.DecodeRune(sc.rest)\n\treturn r\n}\n\n// readRune consumes and returns the next rune in the input.\n// Newlines in Unix, DOS, or Mac format are treated as one rune, '\\n'.\nfunc (sc *scanner) readRune() rune {\n\t// eof() has been inlined here, both to avoid a call\n\t// and to establish len(rest)>0 to avoid a bounds check.\n\tif len(sc.rest) == 0 {\n\t\tif !sc.readLine() {\n\t\t\tsc.error(sc.pos, \"internal scanner error: readRune at EOF\")\n\t\t}\n\t\t// Redundant, but eliminates the bounds-check below.\n\t\tif len(sc.rest) == 0 {\n\t\t\treturn 0\n\t\t}\n\t}\n\n\t// fast path: ASCII\n\tif b := sc.rest[0]; b < utf8.RuneSelf {\n\t\tr := rune(b)\n\t\tsc.rest = sc.rest[1:]\n\t\tif r == '\\r' {\n\t\t\tif len(sc.rest) > 0 && sc.rest[0] == '\\n' {\n\t\t\t\tsc.rest = sc.rest[1:]\n\t\t\t}\n\t\t\tr = '\\n'\n\t\t}\n\t\tif r == '\\n' {\n\t\t\tsc.pos.Line++\n\t\t\tsc.pos.Col = 1\n\t\t} else {\n\t\t\tsc.pos.Col++\n\t\t}\n\t\treturn r\n\t}\n\n\tr, size := utf8.DecodeRune(sc.rest)\n\tsc.rest = sc.rest[size:]\n\tsc.pos.Col++\n\treturn r\n}\n\n// tokenValue records the position and value associated with each token.\ntype tokenValue struct {\n\traw    string   // raw text of token\n\tint    int64    // decoded int\n\tbigInt *big.Int // decoded integers > int64\n\tfloat  float64  // decoded float\n\tstring string   // decoded string\n\tpos    Position // start position of token\n}\n\n// startToken marks the beginning of the next input token.\n// It must be followed by a call to endToken once the token has\n// been consumed using readRune.\nfunc (sc *scanner) startToken(val *tokenValue) {\n\tsc.token = sc.rest\n\tval.raw = \"\"\n\tval.pos = sc.pos\n}\n\n// endToken marks the end of an input token.\n// It records the actual token string in val.raw if the caller\n// has not done that already.\nfunc (sc *scanner) endToken(val *tokenValue) {\n\tif val.raw == \"\" {\n\t\tval.raw = string(sc.token[:len(sc.token)-len(sc.rest)])\n\t}\n}\n\n// nextToken is called by the parser to obtain the next input token.\n// It returns the token value and sets val to the data associated with\n// the token.\n//\n// For all our input tokens, the associated data is val.pos (the\n// position where the token begins), val.raw (the input string\n// corresponding to the token).  For string and int tokens, the string\n// and int fields additionally contain the token's interpreted value.\nfunc (sc *scanner) nextToken(val *tokenValue) Token {\n\n\t// The following distribution of tokens guides case ordering:\n\t//\n\t//      COMMA          27   %\n\t//      STRING         23   %\n\t//      IDENT          15   %\n\t//      EQL            11   %\n\t//      LBRACK          5.5 %\n\t//      RBRACK          5.5 %\n\t//      NEWLINE         3   %\n\t//      LPAREN          2.9 %\n\t//      RPAREN          2.9 %\n\t//      INT             2   %\n\t//      others        < 1   %\n\t//\n\t// Although NEWLINE tokens are infrequent, and lineStart is\n\t// usually (~97%) false on entry, skipped newlines account for\n\t// about 50% of all iterations of the 'start' loop.\n\nstart:\n\tvar c rune\n\n\t// Deal with leading spaces and indentation.\n\tblank := false\n\tsavedLineStart := sc.lineStart\n\tif sc.lineStart {\n\t\tsc.lineStart = false\n\t\tcol := 0\n\t\tfor {\n\t\t\tc = sc.peekRune()\n\t\t\tif c == ' ' {\n\t\t\t\tcol++\n\t\t\t\tsc.readRune()\n\t\t\t} else if c == '\\t' {\n\t\t\t\tconst tab = 8\n\t\t\t\tcol += int(tab - (sc.pos.Col-1)%tab)\n\t\t\t\tsc.readRune()\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// The third clause matches EOF.\n\t\tif c == '#' || c == '\\n' || c == 0 {\n\t\t\tblank = true\n\t\t}\n\n\t\t// Compute indentation level for non-blank lines not\n\t\t// inside an expression.  This is not the common case.\n\t\tif !blank && sc.depth == 0 {\n\t\t\tcur := sc.indentstk[len(sc.indentstk)-1]\n\t\t\tif col > cur {\n\t\t\t\t// indent\n\t\t\t\tsc.dents++\n\t\t\t\tsc.indentstk = append(sc.indentstk, col)\n\t\t\t} else if col < cur {\n\t\t\t\t// outdent(s)\n\t\t\t\tfor len(sc.indentstk) > 0 && col < sc.indentstk[len(sc.indentstk)-1] {\n\t\t\t\t\tsc.dents--\n\t\t\t\t\tsc.indentstk = sc.indentstk[:len(sc.indentstk)-1] // pop\n\t\t\t\t}\n\t\t\t\tif col != sc.indentstk[len(sc.indentstk)-1] {\n\t\t\t\t\tsc.error(sc.pos, \"unindent does not match any outer indentation level\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return saved indentation tokens.\n\tif sc.dents != 0 {\n\t\tsc.startToken(val)\n\t\tsc.endToken(val)\n\t\tif sc.dents < 0 {\n\t\t\tsc.dents++\n\t\t\treturn OUTDENT\n\t\t} else {\n\t\t\tsc.dents--\n\t\t\treturn INDENT\n\t\t}\n\t}\n\n\t// start of line proper\n\tc = sc.peekRune()\n\n\t// Skip spaces.\n\tfor c == ' ' || c == '\\t' {\n\t\tsc.readRune()\n\t\tc = sc.peekRune()\n\t}\n\n\t// comment\n\tif c == '#' {\n\t\tif sc.keepComments {\n\t\t\tsc.startToken(val)\n\t\t}\n\t\t// Consume up to newline (included).\n\t\tfor c != 0 && c != '\\n' {\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t}\n\t\tif sc.keepComments {\n\t\t\tsc.endToken(val)\n\t\t\tif blank {\n\t\t\t\tsc.lineComments = append(sc.lineComments, Comment{val.pos, val.raw})\n\t\t\t} else {\n\t\t\t\tsc.suffixComments = append(sc.suffixComments, Comment{val.pos, val.raw})\n\t\t\t}\n\t\t}\n\t}\n\n\t// newline\n\tif c == '\\n' {\n\t\tsc.lineStart = true\n\n\t\t// Ignore newlines within expressions (common case).\n\t\tif sc.depth > 0 {\n\t\t\tsc.readRune()\n\t\t\tgoto start\n\t\t}\n\n\t\t// Ignore blank lines, except in the REPL,\n\t\t// where they emit OUTDENTs and NEWLINE.\n\t\tif blank {\n\t\t\tif sc.readline == nil {\n\t\t\t\tsc.readRune()\n\t\t\t\tgoto start\n\t\t\t} else if len(sc.indentstk) > 1 {\n\t\t\t\tsc.dents = 1 - len(sc.indentstk)\n\t\t\t\tsc.indentstk = sc.indentstk[:1]\n\t\t\t\tgoto start\n\t\t\t}\n\t\t}\n\n\t\t// At top-level (not in an expression).\n\t\tsc.startToken(val)\n\t\tsc.readRune()\n\t\tval.raw = \"\\n\"\n\t\treturn NEWLINE\n\t}\n\n\t// end of file\n\tif c == 0 {\n\t\t// Emit OUTDENTs for unfinished indentation,\n\t\t// preceded by a NEWLINE if we haven't just emitted one.\n\t\tif len(sc.indentstk) > 1 {\n\t\t\tif savedLineStart {\n\t\t\t\tsc.dents = 1 - len(sc.indentstk)\n\t\t\t\tsc.indentstk = sc.indentstk[:1]\n\t\t\t\tgoto start\n\t\t\t} else {\n\t\t\t\tsc.lineStart = true\n\t\t\t\tsc.startToken(val)\n\t\t\t\tval.raw = \"\\n\"\n\t\t\t\treturn NEWLINE\n\t\t\t}\n\t\t}\n\n\t\tsc.startToken(val)\n\t\tsc.endToken(val)\n\t\treturn EOF\n\t}\n\n\t// line continuation\n\tif c == '\\\\' {\n\t\tsc.readRune()\n\t\tif sc.peekRune() != '\\n' {\n\t\t\tsc.errorf(sc.pos, \"stray backslash in program\")\n\t\t}\n\t\tsc.readRune()\n\t\tgoto start\n\t}\n\n\t// start of the next token\n\tsc.startToken(val)\n\n\t// comma (common case)\n\tif c == ',' {\n\t\tsc.readRune()\n\t\tsc.endToken(val)\n\t\treturn COMMA\n\t}\n\n\t// string literal\n\tif c == '\"' || c == '\\'' {\n\t\treturn sc.scanString(val, c)\n\t}\n\n\t// identifier or keyword\n\tif isIdentStart(c) {\n\t\t// raw string literal\n\t\tif c == 'r' && len(sc.rest) > 1 && (sc.rest[1] == '\"' || sc.rest[1] == '\\'') {\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t\treturn sc.scanString(val, c)\n\t\t}\n\n\t\tfor isIdent(c) {\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t}\n\t\tsc.endToken(val)\n\t\tif k, ok := keywordToken[val.raw]; ok {\n\t\t\treturn k\n\t\t}\n\n\t\treturn IDENT\n\t}\n\n\t// brackets\n\tswitch c {\n\tcase '[', '(', '{':\n\t\tsc.depth++\n\t\tsc.readRune()\n\t\tsc.endToken(val)\n\t\tswitch c {\n\t\tcase '[':\n\t\t\treturn LBRACK\n\t\tcase '(':\n\t\t\treturn LPAREN\n\t\tcase '{':\n\t\t\treturn LBRACE\n\t\t}\n\t\tpanic(\"unreachable\")\n\n\tcase ']', ')', '}':\n\t\tif sc.depth == 0 {\n\t\t\tsc.errorf(sc.pos, \"unexpected %q\", c)\n\t\t} else {\n\t\t\tsc.depth--\n\t\t}\n\t\tsc.readRune()\n\t\tsc.endToken(val)\n\t\tswitch c {\n\t\tcase ']':\n\t\t\treturn RBRACK\n\t\tcase ')':\n\t\t\treturn RPAREN\n\t\tcase '}':\n\t\t\treturn RBRACE\n\t\t}\n\t\tpanic(\"unreachable\")\n\t}\n\n\t// int or float literal, or period\n\tif isdigit(c) || c == '.' {\n\t\treturn sc.scanNumber(val, c)\n\t}\n\n\t// other punctuation\n\tdefer sc.endToken(val)\n\tswitch c {\n\tcase '=', '<', '>', '!', '+', '-', '%', '/', '&', '|', '^': // possibly followed by '='\n\t\tstart := sc.pos\n\t\tsc.readRune()\n\t\tif sc.peekRune() == '=' {\n\t\t\tsc.readRune()\n\t\t\tswitch c {\n\t\t\tcase '<':\n\t\t\t\treturn LE\n\t\t\tcase '>':\n\t\t\t\treturn GE\n\t\t\tcase '=':\n\t\t\t\treturn EQL\n\t\t\tcase '!':\n\t\t\t\treturn NEQ\n\t\t\tcase '+':\n\t\t\t\treturn PLUS_EQ\n\t\t\tcase '-':\n\t\t\t\treturn MINUS_EQ\n\t\t\tcase '/':\n\t\t\t\treturn SLASH_EQ\n\t\t\tcase '%':\n\t\t\t\treturn PERCENT_EQ\n\t\t\tcase '&':\n\t\t\t\treturn AMP_EQ\n\t\t\tcase '|':\n\t\t\t\treturn PIPE_EQ\n\t\t\tcase '^':\n\t\t\t\treturn CIRCUMFLEX_EQ\n\t\t\t}\n\t\t}\n\t\tswitch c {\n\t\tcase '=':\n\t\t\treturn EQ\n\t\tcase '<':\n\t\t\tif sc.peekRune() == '<' {\n\t\t\t\tsc.readRune()\n\t\t\t\tif sc.peekRune() == '=' {\n\t\t\t\t\tsc.readRune()\n\t\t\t\t\treturn LTLT_EQ\n\t\t\t\t} else {\n\t\t\t\t\treturn LTLT\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn LT\n\t\tcase '>':\n\t\t\tif sc.peekRune() == '>' {\n\t\t\t\tsc.readRune()\n\t\t\t\tif sc.peekRune() == '=' {\n\t\t\t\t\tsc.readRune()\n\t\t\t\t\treturn GTGT_EQ\n\t\t\t\t} else {\n\t\t\t\t\treturn GTGT\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn GT\n\t\tcase '!':\n\t\t\tsc.error(start, \"unexpected input character '!'\")\n\t\tcase '+':\n\t\t\treturn PLUS\n\t\tcase '-':\n\t\t\treturn MINUS\n\t\tcase '/':\n\t\t\tif sc.peekRune() == '/' {\n\t\t\t\tsc.readRune()\n\t\t\t\tif sc.peekRune() == '=' {\n\t\t\t\t\tsc.readRune()\n\t\t\t\t\treturn SLASHSLASH_EQ\n\t\t\t\t} else {\n\t\t\t\t\treturn SLASHSLASH\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn SLASH\n\t\tcase '%':\n\t\t\treturn PERCENT\n\t\tcase '&':\n\t\t\treturn AMP\n\t\tcase '|':\n\t\t\treturn PIPE\n\t\tcase '^':\n\t\t\treturn CIRCUMFLEX\n\t\t}\n\t\tpanic(\"unreachable\")\n\n\tcase ':', ';', '~': // single-char tokens (except comma)\n\t\tsc.readRune()\n\t\tswitch c {\n\t\tcase ':':\n\t\t\treturn COLON\n\t\tcase ';':\n\t\t\treturn SEMI\n\t\tcase '~':\n\t\t\treturn TILDE\n\t\t}\n\t\tpanic(\"unreachable\")\n\n\tcase '*': // possibly followed by '*' or '='\n\t\tsc.readRune()\n\t\tswitch sc.peekRune() {\n\t\tcase '*':\n\t\t\tsc.readRune()\n\t\t\treturn STARSTAR\n\t\tcase '=':\n\t\t\tsc.readRune()\n\t\t\treturn STAR_EQ\n\t\t}\n\t\treturn STAR\n\t}\n\n\tsc.errorf(sc.pos, \"unexpected input character %#q\", c)\n\tpanic(\"unreachable\")\n}\n\nfunc (sc *scanner) scanString(val *tokenValue, quote rune) Token {\n\tstart := sc.pos\n\ttriple := len(sc.rest) >= 3 && sc.rest[0] == byte(quote) && sc.rest[1] == byte(quote) && sc.rest[2] == byte(quote)\n\tsc.readRune()\n\tif !triple {\n\t\t// Precondition: startToken was already called.\n\t\tfor {\n\t\t\tif sc.eof() {\n\t\t\t\tsc.error(val.pos, \"unexpected EOF in string\")\n\t\t\t}\n\t\t\tc := sc.readRune()\n\t\t\tif c == quote {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif c == '\\n' {\n\t\t\t\tsc.error(val.pos, \"unexpected newline in string\")\n\t\t\t}\n\t\t\tif c == '\\\\' {\n\t\t\t\tif sc.eof() {\n\t\t\t\t\tsc.error(val.pos, \"unexpected EOF in string\")\n\t\t\t\t}\n\t\t\t\tsc.readRune()\n\t\t\t}\n\t\t}\n\t\tsc.endToken(val)\n\t} else {\n\t\t// triple-quoted string literal\n\t\tsc.readRune()\n\t\tsc.readRune()\n\n\t\t// A triple-quoted string literal may span multiple\n\t\t// gulps of REPL input; it is the only such token.\n\t\t// Thus we must avoid {start,end}Token.\n\t\traw := new(strings.Builder)\n\n\t\t// Copy the prefix, e.g. r''' or \"\"\" (see startToken).\n\t\traw.Write(sc.token[:len(sc.token)-len(sc.rest)])\n\n\t\tquoteCount := 0\n\t\tfor {\n\t\t\tif sc.eof() {\n\t\t\t\tsc.error(val.pos, \"unexpected EOF in string\")\n\t\t\t}\n\t\t\tc := sc.readRune()\n\t\t\traw.WriteRune(c)\n\t\t\tif c == quote {\n\t\t\t\tquoteCount++\n\t\t\t\tif quoteCount == 3 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tquoteCount = 0\n\t\t\t}\n\t\t\tif c == '\\\\' {\n\t\t\t\tif sc.eof() {\n\t\t\t\t\tsc.error(val.pos, \"unexpected EOF in string\")\n\t\t\t\t}\n\t\t\t\tc = sc.readRune()\n\t\t\t\traw.WriteRune(c)\n\t\t\t}\n\t\t}\n\t\tval.raw = raw.String()\n\t}\n\n\ts, _, err := unquote(val.raw)\n\tif err != nil {\n\t\tsc.error(start, err.Error())\n\t}\n\tval.string = s\n\treturn STRING\n}\n\nfunc (sc *scanner) scanNumber(val *tokenValue, c rune) Token {\n\t// https://github.com/google/starlark-go/blob/master/doc/spec.md#lexical-elements\n\t//\n\t// Python features not supported:\n\t// - integer literals of >64 bits of precision\n\t// - 123L or 123l long suffix\n\t// - traditional octal: 0755\n\t// https://docs.python.org/2/reference/lexical_analysis.html#integer-and-long-integer-literals\n\n\tstart := sc.pos\n\tfraction, exponent := false, false\n\n\tif c == '.' {\n\t\t// dot or start of fraction\n\t\tsc.readRune()\n\t\tc = sc.peekRune()\n\t\tif !isdigit(c) {\n\t\t\tsc.endToken(val)\n\t\t\treturn DOT\n\t\t}\n\t\tfraction = true\n\t} else if c == '0' {\n\t\t// hex, octal, binary or float\n\t\tsc.readRune()\n\t\tc = sc.peekRune()\n\n\t\tif c == '.' {\n\t\t\tfraction = true\n\t\t} else if c == 'x' || c == 'X' {\n\t\t\t// hex\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t\tif !isxdigit(c) {\n\t\t\t\tsc.error(start, \"invalid hex literal\")\n\t\t\t}\n\t\t\tfor isxdigit(c) {\n\t\t\t\tsc.readRune()\n\t\t\t\tc = sc.peekRune()\n\t\t\t}\n\t\t} else if c == 'o' || c == 'O' {\n\t\t\t// octal\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t\tif !isodigit(c) {\n\t\t\t\tsc.error(sc.pos, \"invalid octal literal\")\n\t\t\t}\n\t\t\tfor isodigit(c) {\n\t\t\t\tsc.readRune()\n\t\t\t\tc = sc.peekRune()\n\t\t\t}\n\t\t} else if c == 'b' || c == 'B' {\n\t\t\t// binary\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t\tif !isbdigit(c) {\n\t\t\t\tsc.error(sc.pos, \"invalid binary literal\")\n\t\t\t}\n\t\t\tfor isbdigit(c) {\n\t\t\t\tsc.readRune()\n\t\t\t\tc = sc.peekRune()\n\t\t\t}\n\t\t} else {\n\t\t\t// float (or obsolete octal \"0755\")\n\t\t\tallzeros, octal := true, true\n\t\t\tfor isdigit(c) {\n\t\t\t\tif c != '0' {\n\t\t\t\t\tallzeros = false\n\t\t\t\t}\n\t\t\t\tif c > '7' {\n\t\t\t\t\toctal = false\n\t\t\t\t}\n\t\t\t\tsc.readRune()\n\t\t\t\tc = sc.peekRune()\n\t\t\t}\n\t\t\tif c == '.' {\n\t\t\t\tfraction = true\n\t\t\t} else if c == 'e' || c == 'E' {\n\t\t\t\texponent = true\n\t\t\t} else if octal && !allzeros {\n\t\t\t\tsc.endToken(val)\n\t\t\t\tsc.errorf(sc.pos, \"obsolete form of octal literal; use 0o%s\", val.raw[1:])\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// decimal\n\t\tfor isdigit(c) {\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t}\n\n\t\tif c == '.' {\n\t\t\tfraction = true\n\t\t} else if c == 'e' || c == 'E' {\n\t\t\texponent = true\n\t\t}\n\t}\n\n\tif fraction {\n\t\tsc.readRune() // consume '.'\n\t\tc = sc.peekRune()\n\t\tfor isdigit(c) {\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t}\n\n\t\tif c == 'e' || c == 'E' {\n\t\t\texponent = true\n\t\t}\n\t}\n\n\tif exponent {\n\t\tsc.readRune() // consume [eE]\n\t\tc = sc.peekRune()\n\t\tif c == '+' || c == '-' {\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t\tif !isdigit(c) {\n\t\t\t\tsc.error(sc.pos, \"invalid float literal\")\n\t\t\t}\n\t\t}\n\t\tfor isdigit(c) {\n\t\t\tsc.readRune()\n\t\t\tc = sc.peekRune()\n\t\t}\n\t}\n\n\tsc.endToken(val)\n\tif fraction || exponent {\n\t\tvar err error\n\t\tval.float, err = strconv.ParseFloat(val.raw, 64)\n\t\tif err != nil {\n\t\t\tsc.error(sc.pos, \"invalid float literal\")\n\t\t}\n\t\treturn FLOAT\n\t} else {\n\t\tvar err error\n\t\ts := val.raw\n\t\tval.bigInt = nil\n\t\tif len(s) > 2 && s[0] == '0' && (s[1] == 'o' || s[1] == 'O') {\n\t\t\tval.int, err = strconv.ParseInt(s[2:], 8, 64)\n\t\t} else if len(s) > 2 && s[0] == '0' && (s[1] == 'b' || s[1] == 'B') {\n\t\t\tval.int, err = strconv.ParseInt(s[2:], 2, 64)\n\t\t} else {\n\t\t\tval.int, err = strconv.ParseInt(s, 0, 64)\n\t\t\tif err != nil {\n\t\t\t\tnum := new(big.Int)\n\t\t\t\tvar ok bool\n\t\t\t\tval.bigInt, ok = num.SetString(s, 0)\n\t\t\t\tif ok {\n\t\t\t\t\terr = nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\tsc.error(start, \"invalid int literal\")\n\t\t}\n\t\treturn INT\n\t}\n}\n\n// isIdent reports whether c is an identifier rune.\nfunc isIdent(c rune) bool {\n\treturn isdigit(c) || isIdentStart(c)\n}\n\nfunc isIdentStart(c rune) bool {\n\treturn 'a' <= c && c <= 'z' ||\n\t\t'A' <= c && c <= 'Z' ||\n\t\tc == '_' ||\n\t\tunicode.IsLetter(c)\n}\n\nfunc isdigit(c rune) bool  { return '0' <= c && c <= '9' }\nfunc isodigit(c rune) bool { return '0' <= c && c <= '7' }\nfunc isxdigit(c rune) bool { return isdigit(c) || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f' }\nfunc isbdigit(c rune) bool { return '0' == c || c == '1' }\n\n// keywordToken records the special tokens for\n// strings that should not be treated as ordinary identifiers.\nvar keywordToken = map[string]Token{\n\t\"and\":      AND,\n\t\"break\":    BREAK,\n\t\"continue\": CONTINUE,\n\t\"def\":      DEF,\n\t\"elif\":     ELIF,\n\t\"else\":     ELSE,\n\t\"for\":      FOR,\n\t\"if\":       IF,\n\t\"in\":       IN,\n\t\"lambda\":   LAMBDA,\n\t\"load\":     LOAD,\n\t\"not\":      NOT,\n\t\"or\":       OR,\n\t\"pass\":     PASS,\n\t\"return\":   RETURN,\n\t\"while\":    WHILE,\n\n\t// reserved words:\n\t\"as\": ILLEGAL,\n\t// \"assert\":   ILLEGAL, // heavily used by our tests\n\t\"class\":    ILLEGAL,\n\t\"del\":      ILLEGAL,\n\t\"except\":   ILLEGAL,\n\t\"finally\":  ILLEGAL,\n\t\"from\":     ILLEGAL,\n\t\"global\":   ILLEGAL,\n\t\"import\":   ILLEGAL,\n\t\"is\":       ILLEGAL,\n\t\"nonlocal\": ILLEGAL,\n\t\"raise\":    ILLEGAL,\n\t\"try\":      ILLEGAL,\n\t\"with\":     ILLEGAL,\n\t\"yield\":    ILLEGAL,\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/syntax/syntax.go",
    "content": "// Copyright 2017 The Bazel 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// Package syntax provides a Starlark parser and abstract syntax tree.\npackage syntax // import \"go.starlark.net/syntax\"\n\n// A Node is a node in a Starlark syntax tree.\ntype Node interface {\n\t// Span returns the start and end position of the expression.\n\tSpan() (start, end Position)\n\n\t// Comments returns the comments associated with this node.\n\t// It returns nil if RetainComments was not specified during parsing,\n\t// or if AllocComments was not called.\n\tComments() *Comments\n\n\t// AllocComments allocates a new Comments node if there was none.\n\t// This makes possible to add new comments using Comments() method.\n\tAllocComments()\n}\n\n// A Comment represents a single # comment.\ntype Comment struct {\n\tStart Position\n\tText  string // without trailing newline\n}\n\n// Comments collects the comments associated with an expression.\ntype Comments struct {\n\tBefore []Comment // whole-line comments before this expression\n\tSuffix []Comment // end-of-line comments after this expression (up to 1)\n\n\t// For top-level expressions only, After lists whole-line\n\t// comments following the expression.\n\tAfter []Comment\n}\n\n// A commentsRef is a possibly-nil reference to a set of comments.\n// A commentsRef is embedded in each type of syntax node,\n// and provides its Comments and AllocComments methods.\ntype commentsRef struct{ ref *Comments }\n\n// Comments returns the comments associated with a syntax node,\n// or nil if AllocComments has not yet been called.\nfunc (cr commentsRef) Comments() *Comments { return cr.ref }\n\n// AllocComments enables comments to be associated with a syntax node.\nfunc (cr *commentsRef) AllocComments() {\n\tif cr.ref == nil {\n\t\tcr.ref = new(Comments)\n\t}\n}\n\n// Start returns the start position of the expression.\nfunc Start(n Node) Position {\n\tstart, _ := n.Span()\n\treturn start\n}\n\n// End returns the end position of the expression.\nfunc End(n Node) Position {\n\t_, end := n.Span()\n\treturn end\n}\n\n// A File represents a Starlark file.\ntype File struct {\n\tcommentsRef\n\tPath  string\n\tStmts []Stmt\n\n\tModule interface{} // a *resolve.Module, set by resolver\n}\n\nfunc (x *File) Span() (start, end Position) {\n\tif len(x.Stmts) == 0 {\n\t\treturn\n\t}\n\tstart, _ = x.Stmts[0].Span()\n\t_, end = x.Stmts[len(x.Stmts)-1].Span()\n\treturn start, end\n}\n\n// A Stmt is a Starlark statement.\ntype Stmt interface {\n\tNode\n\tstmt()\n}\n\nfunc (*AssignStmt) stmt() {}\nfunc (*BranchStmt) stmt() {}\nfunc (*DefStmt) stmt()    {}\nfunc (*ExprStmt) stmt()   {}\nfunc (*ForStmt) stmt()    {}\nfunc (*WhileStmt) stmt()  {}\nfunc (*IfStmt) stmt()     {}\nfunc (*LoadStmt) stmt()   {}\nfunc (*ReturnStmt) stmt() {}\n\n// An AssignStmt represents an assignment:\n//\tx = 0\n//\tx, y = y, x\n// \tx += 1\ntype AssignStmt struct {\n\tcommentsRef\n\tOpPos Position\n\tOp    Token // = EQ | {PLUS,MINUS,STAR,PERCENT}_EQ\n\tLHS   Expr\n\tRHS   Expr\n}\n\nfunc (x *AssignStmt) Span() (start, end Position) {\n\tstart, _ = x.LHS.Span()\n\t_, end = x.RHS.Span()\n\treturn\n}\n\n// A DefStmt represents a function definition.\ntype DefStmt struct {\n\tcommentsRef\n\tDef    Position\n\tName   *Ident\n\tParams []Expr // param = ident | ident=expr | * | *ident | **ident\n\tBody   []Stmt\n\n\tFunction interface{} // a *resolve.Function, set by resolver\n}\n\nfunc (x *DefStmt) Span() (start, end Position) {\n\t_, end = x.Body[len(x.Body)-1].Span()\n\treturn x.Def, end\n}\n\n// An ExprStmt is an expression evaluated for side effects.\ntype ExprStmt struct {\n\tcommentsRef\n\tX Expr\n}\n\nfunc (x *ExprStmt) Span() (start, end Position) {\n\treturn x.X.Span()\n}\n\n// An IfStmt is a conditional: If Cond: True; else: False.\n// 'elseif' is desugared into a chain of IfStmts.\ntype IfStmt struct {\n\tcommentsRef\n\tIf      Position // IF or ELIF\n\tCond    Expr\n\tTrue    []Stmt\n\tElsePos Position // ELSE or ELIF\n\tFalse   []Stmt   // optional\n}\n\nfunc (x *IfStmt) Span() (start, end Position) {\n\tbody := x.False\n\tif body == nil {\n\t\tbody = x.True\n\t}\n\t_, end = body[len(body)-1].Span()\n\treturn x.If, end\n}\n\n// A LoadStmt loads another module and binds names from it:\n// load(Module, \"x\", y=\"foo\").\n//\n// The AST is slightly unfaithful to the concrete syntax here because\n// Starlark's load statement, so that it can be implemented in Python,\n// binds some names (like y above) with an identifier and some (like x)\n// without.  For consistency we create fake identifiers for all the\n// strings.\ntype LoadStmt struct {\n\tcommentsRef\n\tLoad   Position\n\tModule *Literal // a string\n\tFrom   []*Ident // name defined in loading module\n\tTo     []*Ident // name in loaded module\n\tRparen Position\n}\n\nfunc (x *LoadStmt) Span() (start, end Position) {\n\treturn x.Load, x.Rparen\n}\n\n// ModuleName returns the name of the module loaded by this statement.\nfunc (x *LoadStmt) ModuleName() string { return x.Module.Value.(string) }\n\n// A BranchStmt changes the flow of control: break, continue, pass.\ntype BranchStmt struct {\n\tcommentsRef\n\tToken    Token // = BREAK | CONTINUE | PASS\n\tTokenPos Position\n}\n\nfunc (x *BranchStmt) Span() (start, end Position) {\n\treturn x.TokenPos, x.TokenPos.add(x.Token.String())\n}\n\n// A ReturnStmt returns from a function.\ntype ReturnStmt struct {\n\tcommentsRef\n\tReturn Position\n\tResult Expr // may be nil\n}\n\nfunc (x *ReturnStmt) Span() (start, end Position) {\n\tif x.Result == nil {\n\t\treturn x.Return, x.Return.add(\"return\")\n\t}\n\t_, end = x.Result.Span()\n\treturn x.Return, end\n}\n\n// An Expr is a Starlark expression.\ntype Expr interface {\n\tNode\n\texpr()\n}\n\nfunc (*BinaryExpr) expr()    {}\nfunc (*CallExpr) expr()      {}\nfunc (*Comprehension) expr() {}\nfunc (*CondExpr) expr()      {}\nfunc (*DictEntry) expr()     {}\nfunc (*DictExpr) expr()      {}\nfunc (*DotExpr) expr()       {}\nfunc (*Ident) expr()         {}\nfunc (*IndexExpr) expr()     {}\nfunc (*LambdaExpr) expr()    {}\nfunc (*ListExpr) expr()      {}\nfunc (*Literal) expr()       {}\nfunc (*ParenExpr) expr()     {}\nfunc (*SliceExpr) expr()     {}\nfunc (*TupleExpr) expr()     {}\nfunc (*UnaryExpr) expr()     {}\n\n// An Ident represents an identifier.\ntype Ident struct {\n\tcommentsRef\n\tNamePos Position\n\tName    string\n\n\tBinding interface{} // a *resolver.Binding, set by resolver\n}\n\nfunc (x *Ident) Span() (start, end Position) {\n\treturn x.NamePos, x.NamePos.add(x.Name)\n}\n\n// A Literal represents a literal string or number.\ntype Literal struct {\n\tcommentsRef\n\tToken    Token // = STRING | INT\n\tTokenPos Position\n\tRaw      string      // uninterpreted text\n\tValue    interface{} // = string | int64 | *big.Int\n}\n\nfunc (x *Literal) Span() (start, end Position) {\n\treturn x.TokenPos, x.TokenPos.add(x.Raw)\n}\n\n// A ParenExpr represents a parenthesized expression: (X).\ntype ParenExpr struct {\n\tcommentsRef\n\tLparen Position\n\tX      Expr\n\tRparen Position\n}\n\nfunc (x *ParenExpr) Span() (start, end Position) {\n\treturn x.Lparen, x.Rparen.add(\")\")\n}\n\n// A CallExpr represents a function call expression: Fn(Args).\ntype CallExpr struct {\n\tcommentsRef\n\tFn     Expr\n\tLparen Position\n\tArgs   []Expr // arg = expr | ident=expr | *expr | **expr\n\tRparen Position\n}\n\nfunc (x *CallExpr) Span() (start, end Position) {\n\tstart, _ = x.Fn.Span()\n\treturn start, x.Rparen.add(\")\")\n}\n\n// A DotExpr represents a field or method selector: X.Name.\ntype DotExpr struct {\n\tcommentsRef\n\tX       Expr\n\tDot     Position\n\tNamePos Position\n\tName    *Ident\n}\n\nfunc (x *DotExpr) Span() (start, end Position) {\n\tstart, _ = x.X.Span()\n\t_, end = x.Name.Span()\n\treturn\n}\n\n// A Comprehension represents a list or dict comprehension:\n// [Body for ... if ...] or {Body for ... if ...}\ntype Comprehension struct {\n\tcommentsRef\n\tCurly   bool // {x:y for ...} or {x for ...}, not [x for ...]\n\tLbrack  Position\n\tBody    Expr\n\tClauses []Node // = *ForClause | *IfClause\n\tRbrack  Position\n}\n\nfunc (x *Comprehension) Span() (start, end Position) {\n\treturn x.Lbrack, x.Rbrack.add(\"]\")\n}\n\n// A ForStmt represents a loop: for Vars in X: Body.\ntype ForStmt struct {\n\tcommentsRef\n\tFor  Position\n\tVars Expr // name, or tuple of names\n\tX    Expr\n\tBody []Stmt\n}\n\nfunc (x *ForStmt) Span() (start, end Position) {\n\t_, end = x.Body[len(x.Body)-1].Span()\n\treturn x.For, end\n}\n\n// A WhileStmt represents a while loop: while X: Body.\ntype WhileStmt struct {\n\tcommentsRef\n\tWhile Position\n\tCond  Expr\n\tBody  []Stmt\n}\n\nfunc (x *WhileStmt) Span() (start, end Position) {\n\t_, end = x.Body[len(x.Body)-1].Span()\n\treturn x.While, end\n}\n\n// A ForClause represents a for clause in a list comprehension: for Vars in X.\ntype ForClause struct {\n\tcommentsRef\n\tFor  Position\n\tVars Expr // name, or tuple of names\n\tIn   Position\n\tX    Expr\n}\n\nfunc (x *ForClause) Span() (start, end Position) {\n\t_, end = x.X.Span()\n\treturn x.For, end\n}\n\n// An IfClause represents an if clause in a list comprehension: if Cond.\ntype IfClause struct {\n\tcommentsRef\n\tIf   Position\n\tCond Expr\n}\n\nfunc (x *IfClause) Span() (start, end Position) {\n\t_, end = x.Cond.Span()\n\treturn x.If, end\n}\n\n// A DictExpr represents a dictionary literal: { List }.\ntype DictExpr struct {\n\tcommentsRef\n\tLbrace Position\n\tList   []Expr // all *DictEntrys\n\tRbrace Position\n}\n\nfunc (x *DictExpr) Span() (start, end Position) {\n\treturn x.Lbrace, x.Rbrace.add(\"}\")\n}\n\n// A DictEntry represents a dictionary entry: Key: Value.\n// Used only within a DictExpr.\ntype DictEntry struct {\n\tcommentsRef\n\tKey   Expr\n\tColon Position\n\tValue Expr\n}\n\nfunc (x *DictEntry) Span() (start, end Position) {\n\tstart, _ = x.Key.Span()\n\t_, end = x.Value.Span()\n\treturn start, end\n}\n\n// A LambdaExpr represents an inline function abstraction.\n//\n// Although they may be added in future, lambda expressions are not\n// currently part of the Starlark spec, so their use is controlled by the\n// resolver.AllowLambda flag.\ntype LambdaExpr struct {\n\tcommentsRef\n\tLambda Position\n\tParams []Expr // param = ident | ident=expr | * | *ident | **ident\n\tBody   Expr\n\n\tFunction interface{} // a *resolve.Function, set by resolver\n}\n\nfunc (x *LambdaExpr) Span() (start, end Position) {\n\t_, end = x.Body.Span()\n\treturn x.Lambda, end\n}\n\n// A ListExpr represents a list literal: [ List ].\ntype ListExpr struct {\n\tcommentsRef\n\tLbrack Position\n\tList   []Expr\n\tRbrack Position\n}\n\nfunc (x *ListExpr) Span() (start, end Position) {\n\treturn x.Lbrack, x.Rbrack.add(\"]\")\n}\n\n// CondExpr represents the conditional: X if COND else ELSE.\ntype CondExpr struct {\n\tcommentsRef\n\tIf      Position\n\tCond    Expr\n\tTrue    Expr\n\tElsePos Position\n\tFalse   Expr\n}\n\nfunc (x *CondExpr) Span() (start, end Position) {\n\tstart, _ = x.True.Span()\n\t_, end = x.False.Span()\n\treturn start, end\n}\n\n// A TupleExpr represents a tuple literal: (List).\ntype TupleExpr struct {\n\tcommentsRef\n\tLparen Position // optional (e.g. in x, y = 0, 1), but required if List is empty\n\tList   []Expr\n\tRparen Position\n}\n\nfunc (x *TupleExpr) Span() (start, end Position) {\n\tif x.Lparen.IsValid() {\n\t\treturn x.Lparen, x.Rparen\n\t} else {\n\t\treturn Start(x.List[0]), End(x.List[len(x.List)-1])\n\t}\n}\n\n// A UnaryExpr represents a unary expression: Op X.\n//\n// As a special case, UnaryOp{Op:Star} may also represent\n// the star parameter in def f(*args) or def f(*, x).\ntype UnaryExpr struct {\n\tcommentsRef\n\tOpPos Position\n\tOp    Token\n\tX     Expr // may be nil if Op==STAR\n}\n\nfunc (x *UnaryExpr) Span() (start, end Position) {\n\tif x.X != nil {\n\t\t_, end = x.X.Span()\n\t} else {\n\t\tend = x.OpPos.add(\"*\")\n\t}\n\treturn x.OpPos, end\n}\n\n// A BinaryExpr represents a binary expression: X Op Y.\n//\n// As a special case, BinaryExpr{Op:EQ} may also\n// represent a named argument in a call f(k=v)\n// or a named parameter in a function declaration\n// def f(param=default).\ntype BinaryExpr struct {\n\tcommentsRef\n\tX     Expr\n\tOpPos Position\n\tOp    Token\n\tY     Expr\n}\n\nfunc (x *BinaryExpr) Span() (start, end Position) {\n\tstart, _ = x.X.Span()\n\t_, end = x.Y.Span()\n\treturn start, end\n}\n\n// A SliceExpr represents a slice or substring expression: X[Lo:Hi:Step].\ntype SliceExpr struct {\n\tcommentsRef\n\tX            Expr\n\tLbrack       Position\n\tLo, Hi, Step Expr // all optional\n\tRbrack       Position\n}\n\nfunc (x *SliceExpr) Span() (start, end Position) {\n\tstart, _ = x.X.Span()\n\treturn start, x.Rbrack\n}\n\n// An IndexExpr represents an index expression: X[Y].\ntype IndexExpr struct {\n\tcommentsRef\n\tX      Expr\n\tLbrack Position\n\tY      Expr\n\tRbrack Position\n}\n\nfunc (x *IndexExpr) Span() (start, end Position) {\n\tstart, _ = x.X.Span()\n\treturn start, x.Rbrack\n}\n"
  },
  {
    "path": "vendor/go.starlark.net/syntax/walk.go",
    "content": "// Copyright 2017 The Bazel 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 syntax\n\n// Walk traverses a syntax tree in depth-first order.\n// It starts by calling f(n); n must not be nil.\n// If f returns true, Walk calls itself\n// recursively for each non-nil child of n.\n// Walk then calls f(nil).\nfunc Walk(n Node, f func(Node) bool) {\n\tif n == nil {\n\t\tpanic(\"nil\")\n\t}\n\tif !f(n) {\n\t\treturn\n\t}\n\n\t// TODO(adonovan): opt: order cases using profile data.\n\tswitch n := n.(type) {\n\tcase *File:\n\t\twalkStmts(n.Stmts, f)\n\n\tcase *ExprStmt:\n\t\tWalk(n.X, f)\n\n\tcase *BranchStmt:\n\t\t// no-op\n\n\tcase *IfStmt:\n\t\tWalk(n.Cond, f)\n\t\twalkStmts(n.True, f)\n\t\twalkStmts(n.False, f)\n\n\tcase *AssignStmt:\n\t\tWalk(n.LHS, f)\n\t\tWalk(n.RHS, f)\n\n\tcase *DefStmt:\n\t\tWalk(n.Name, f)\n\t\tfor _, param := range n.Params {\n\t\t\tWalk(param, f)\n\t\t}\n\t\twalkStmts(n.Body, f)\n\n\tcase *ForStmt:\n\t\tWalk(n.Vars, f)\n\t\tWalk(n.X, f)\n\t\twalkStmts(n.Body, f)\n\n\tcase *ReturnStmt:\n\t\tif n.Result != nil {\n\t\t\tWalk(n.Result, f)\n\t\t}\n\n\tcase *LoadStmt:\n\t\tWalk(n.Module, f)\n\t\tfor _, from := range n.From {\n\t\t\tWalk(from, f)\n\t\t}\n\t\tfor _, to := range n.To {\n\t\t\tWalk(to, f)\n\t\t}\n\n\tcase *Ident, *Literal:\n\t\t// no-op\n\n\tcase *ListExpr:\n\t\tfor _, x := range n.List {\n\t\t\tWalk(x, f)\n\t\t}\n\n\tcase *ParenExpr:\n\t\tWalk(n.X, f)\n\n\tcase *CondExpr:\n\t\tWalk(n.Cond, f)\n\t\tWalk(n.True, f)\n\t\tWalk(n.False, f)\n\n\tcase *IndexExpr:\n\t\tWalk(n.X, f)\n\t\tWalk(n.Y, f)\n\n\tcase *DictEntry:\n\t\tWalk(n.Key, f)\n\t\tWalk(n.Value, f)\n\n\tcase *SliceExpr:\n\t\tWalk(n.X, f)\n\t\tif n.Lo != nil {\n\t\t\tWalk(n.Lo, f)\n\t\t}\n\t\tif n.Hi != nil {\n\t\t\tWalk(n.Hi, f)\n\t\t}\n\t\tif n.Step != nil {\n\t\t\tWalk(n.Step, f)\n\t\t}\n\n\tcase *Comprehension:\n\t\tWalk(n.Body, f)\n\t\tfor _, clause := range n.Clauses {\n\t\t\tWalk(clause, f)\n\t\t}\n\n\tcase *IfClause:\n\t\tWalk(n.Cond, f)\n\n\tcase *ForClause:\n\t\tWalk(n.Vars, f)\n\t\tWalk(n.X, f)\n\n\tcase *TupleExpr:\n\t\tfor _, x := range n.List {\n\t\t\tWalk(x, f)\n\t\t}\n\n\tcase *DictExpr:\n\t\tfor _, entry := range n.List {\n\t\t\tentry := entry.(*DictEntry)\n\t\t\tWalk(entry.Key, f)\n\t\t\tWalk(entry.Value, f)\n\t\t}\n\n\tcase *UnaryExpr:\n\t\tif n.X != nil {\n\t\t\tWalk(n.X, f)\n\t\t}\n\n\tcase *BinaryExpr:\n\t\tWalk(n.X, f)\n\t\tWalk(n.Y, f)\n\n\tcase *DotExpr:\n\t\tWalk(n.X, f)\n\t\tWalk(n.Name, f)\n\n\tcase *CallExpr:\n\t\tWalk(n.Fn, f)\n\t\tfor _, arg := range n.Args {\n\t\t\tWalk(arg, f)\n\t\t}\n\n\tcase *LambdaExpr:\n\t\tfor _, param := range n.Params {\n\t\t\tWalk(param, f)\n\t\t}\n\t\tWalk(n.Body, f)\n\n\tdefault:\n\t\tpanic(n)\n\t}\n\n\tf(nil)\n}\n\nfunc walkStmts(stmts []Stmt, f func(Node) bool) {\n\tfor _, stmt := range stmts {\n\t\tWalk(stmt, f)\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * Neither the name of Google LLC 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": "vendor/golang.org/x/crypto/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/acme.go",
    "content": "// Copyright 2015 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// Package acme provides an implementation of the\n// Automatic Certificate Management Environment (ACME) spec,\n// most famously used by Let's Encrypt.\n//\n// The initial implementation of this package was based on an early version\n// of the spec. The current implementation supports only the modern\n// RFC 8555 but some of the old API surface remains for compatibility.\n// While code using the old API will still compile, it will return an error.\n// Note the deprecation comments to update your code.\n//\n// See https://tools.ietf.org/html/rfc8555 for the spec.\n//\n// Most common scenarios will want to use autocert subdirectory instead,\n// which provides automatic access to certificates from Let's Encrypt\n// and any other ACME-based CA.\npackage acme\n\nimport (\n\t\"context\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/sha256\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/asn1\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"net\"\n\t\"net/http\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n)\n\nconst (\n\t// LetsEncryptURL is the Directory endpoint of Let's Encrypt CA.\n\tLetsEncryptURL = \"https://acme-v02.api.letsencrypt.org/directory\"\n\n\t// ALPNProto is the ALPN protocol name used by a CA server when validating\n\t// tls-alpn-01 challenges.\n\t//\n\t// Package users must ensure their servers can negotiate the ACME ALPN in\n\t// order for tls-alpn-01 challenge verifications to succeed.\n\t// See the crypto/tls package's Config.NextProtos field.\n\tALPNProto = \"acme-tls/1\"\n)\n\n// idPeACMEIdentifier is the OID for the ACME extension for the TLS-ALPN challenge.\n// https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-05#section-5.1\nvar idPeACMEIdentifier = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 31}\n\nconst (\n\tmaxChainLen = 5       // max depth and breadth of a certificate chain\n\tmaxCertSize = 1 << 20 // max size of a certificate, in DER bytes\n\t// Used for decoding certs from application/pem-certificate-chain response,\n\t// the default when in RFC mode.\n\tmaxCertChainSize = maxCertSize * maxChainLen\n\n\t// Max number of collected nonces kept in memory.\n\t// Expect usual peak of 1 or 2.\n\tmaxNonces = 100\n)\n\n// Client is an ACME client.\n//\n// The only required field is Key. An example of creating a client with a new key\n// is as follows:\n//\n//\tkey, err := rsa.GenerateKey(rand.Reader, 2048)\n//\tif err != nil {\n//\t\tlog.Fatal(err)\n//\t}\n//\tclient := &Client{Key: key}\ntype Client struct {\n\t// Key is the account key used to register with a CA and sign requests.\n\t// Key.Public() must return a *rsa.PublicKey or *ecdsa.PublicKey.\n\t//\n\t// The following algorithms are supported:\n\t// RS256, ES256, ES384 and ES512.\n\t// See RFC 7518 for more details about the algorithms.\n\tKey crypto.Signer\n\n\t// HTTPClient optionally specifies an HTTP client to use\n\t// instead of http.DefaultClient.\n\tHTTPClient *http.Client\n\n\t// DirectoryURL points to the CA directory endpoint.\n\t// If empty, LetsEncryptURL is used.\n\t// Mutating this value after a successful call of Client's Discover method\n\t// will have no effect.\n\tDirectoryURL string\n\n\t// RetryBackoff computes the duration after which the nth retry of a failed request\n\t// should occur. The value of n for the first call on failure is 1.\n\t// The values of r and resp are the request and response of the last failed attempt.\n\t// If the returned value is negative or zero, no more retries are done and an error\n\t// is returned to the caller of the original method.\n\t//\n\t// Requests which result in a 4xx client error are not retried,\n\t// except for 400 Bad Request due to \"bad nonce\" errors and 429 Too Many Requests.\n\t//\n\t// If RetryBackoff is nil, a truncated exponential backoff algorithm\n\t// with the ceiling of 10 seconds is used, where each subsequent retry n\n\t// is done after either (\"Retry-After\" + jitter) or (2^n seconds + jitter),\n\t// preferring the former if \"Retry-After\" header is found in the resp.\n\t// The jitter is a random value up to 1 second.\n\tRetryBackoff func(n int, r *http.Request, resp *http.Response) time.Duration\n\n\t// UserAgent is prepended to the User-Agent header sent to the ACME server,\n\t// which by default is this package's name and version.\n\t//\n\t// Reusable libraries and tools in particular should set this value to be\n\t// identifiable by the server, in case they are causing issues.\n\tUserAgent string\n\n\tcacheMu sync.Mutex\n\tdir     *Directory // cached result of Client's Discover method\n\t// KID is the key identifier provided by the CA. If not provided it will be\n\t// retrieved from the CA by making a call to the registration endpoint.\n\tKID KeyID\n\n\tnoncesMu sync.Mutex\n\tnonces   map[string]struct{} // nonces collected from previous responses\n}\n\n// accountKID returns a key ID associated with c.Key, the account identity\n// provided by the CA during RFC based registration.\n// It assumes c.Discover has already been called.\n//\n// accountKID requires at most one network roundtrip.\n// It caches only successful result.\n//\n// When in pre-RFC mode or when c.getRegRFC responds with an error, accountKID\n// returns noKeyID.\nfunc (c *Client) accountKID(ctx context.Context) KeyID {\n\tc.cacheMu.Lock()\n\tdefer c.cacheMu.Unlock()\n\tif c.KID != noKeyID {\n\t\treturn c.KID\n\t}\n\ta, err := c.getRegRFC(ctx)\n\tif err != nil {\n\t\treturn noKeyID\n\t}\n\tc.KID = KeyID(a.URI)\n\treturn c.KID\n}\n\nvar errPreRFC = errors.New(\"acme: server does not support the RFC 8555 version of ACME\")\n\n// Discover performs ACME server discovery using c.DirectoryURL.\n//\n// It caches successful result. So, subsequent calls will not result in\n// a network round-trip. This also means mutating c.DirectoryURL after successful call\n// of this method will have no effect.\nfunc (c *Client) Discover(ctx context.Context) (Directory, error) {\n\tc.cacheMu.Lock()\n\tdefer c.cacheMu.Unlock()\n\tif c.dir != nil {\n\t\treturn *c.dir, nil\n\t}\n\n\tres, err := c.get(ctx, c.directoryURL(), wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn Directory{}, err\n\t}\n\tdefer res.Body.Close()\n\tc.addNonce(res.Header)\n\n\tvar v struct {\n\t\tReg       string `json:\"newAccount\"`\n\t\tAuthz     string `json:\"newAuthz\"`\n\t\tOrder     string `json:\"newOrder\"`\n\t\tRevoke    string `json:\"revokeCert\"`\n\t\tNonce     string `json:\"newNonce\"`\n\t\tKeyChange string `json:\"keyChange\"`\n\t\tMeta      struct {\n\t\t\tTerms        string   `json:\"termsOfService\"`\n\t\t\tWebsite      string   `json:\"website\"`\n\t\t\tCAA          []string `json:\"caaIdentities\"`\n\t\t\tExternalAcct bool     `json:\"externalAccountRequired\"`\n\t\t}\n\t}\n\tif err := json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn Directory{}, err\n\t}\n\tif v.Order == \"\" {\n\t\treturn Directory{}, errPreRFC\n\t}\n\tc.dir = &Directory{\n\t\tRegURL:                  v.Reg,\n\t\tAuthzURL:                v.Authz,\n\t\tOrderURL:                v.Order,\n\t\tRevokeURL:               v.Revoke,\n\t\tNonceURL:                v.Nonce,\n\t\tKeyChangeURL:            v.KeyChange,\n\t\tTerms:                   v.Meta.Terms,\n\t\tWebsite:                 v.Meta.Website,\n\t\tCAA:                     v.Meta.CAA,\n\t\tExternalAccountRequired: v.Meta.ExternalAcct,\n\t}\n\treturn *c.dir, nil\n}\n\nfunc (c *Client) directoryURL() string {\n\tif c.DirectoryURL != \"\" {\n\t\treturn c.DirectoryURL\n\t}\n\treturn LetsEncryptURL\n}\n\n// CreateCert was part of the old version of ACME. It is incompatible with RFC 8555.\n//\n// Deprecated: this was for the pre-RFC 8555 version of ACME. Callers should use CreateOrderCert.\nfunc (c *Client) CreateCert(ctx context.Context, csr []byte, exp time.Duration, bundle bool) (der [][]byte, certURL string, err error) {\n\treturn nil, \"\", errPreRFC\n}\n\n// FetchCert retrieves already issued certificate from the given url, in DER format.\n// It retries the request until the certificate is successfully retrieved,\n// context is cancelled by the caller or an error response is received.\n//\n// If the bundle argument is true, the returned value also contains the CA (issuer)\n// certificate chain.\n//\n// FetchCert returns an error if the CA's response or chain was unreasonably large.\n// Callers are encouraged to parse the returned value to ensure the certificate is valid\n// and has expected features.\nfunc (c *Client) FetchCert(ctx context.Context, url string, bundle bool) ([][]byte, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\treturn c.fetchCertRFC(ctx, url, bundle)\n}\n\n// RevokeCert revokes a previously issued certificate cert, provided in DER format.\n//\n// The key argument, used to sign the request, must be authorized\n// to revoke the certificate. It's up to the CA to decide which keys are authorized.\n// For instance, the key pair of the certificate may be authorized.\n// If the key is nil, c.Key is used instead.\nfunc (c *Client) RevokeCert(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn err\n\t}\n\treturn c.revokeCertRFC(ctx, key, cert, reason)\n}\n\n// AcceptTOS always returns true to indicate the acceptance of a CA's Terms of Service\n// during account registration. See Register method of Client for more details.\nfunc AcceptTOS(tosURL string) bool { return true }\n\n// Register creates a new account with the CA using c.Key.\n// It returns the registered account. The account acct is not modified.\n//\n// The registration may require the caller to agree to the CA's Terms of Service (TOS).\n// If so, and the account has not indicated the acceptance of the terms (see Account for details),\n// Register calls prompt with a TOS URL provided by the CA. Prompt should report\n// whether the caller agrees to the terms. To always accept the terms, the caller can use AcceptTOS.\n//\n// When interfacing with an RFC-compliant CA, non-RFC 8555 fields of acct are ignored\n// and prompt is called if Directory's Terms field is non-zero.\n// Also see Error's Instance field for when a CA requires already registered accounts to agree\n// to an updated Terms of Service.\nfunc (c *Client) Register(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) {\n\tif c.Key == nil {\n\t\treturn nil, errors.New(\"acme: client.Key must be set to Register\")\n\t}\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\treturn c.registerRFC(ctx, acct, prompt)\n}\n\n// GetReg retrieves an existing account associated with c.Key.\n//\n// The url argument is a legacy artifact of the pre-RFC 8555 API\n// and is ignored.\nfunc (c *Client) GetReg(ctx context.Context, url string) (*Account, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\treturn c.getRegRFC(ctx)\n}\n\n// UpdateReg updates an existing registration.\n// It returns an updated account copy. The provided account is not modified.\n//\n// The account's URI is ignored and the account URL associated with\n// c.Key is used instead.\nfunc (c *Client) UpdateReg(ctx context.Context, acct *Account) (*Account, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\treturn c.updateRegRFC(ctx, acct)\n}\n\n// AccountKeyRollover attempts to transition a client's account key to a new key.\n// On success client's Key is updated which is not concurrency safe.\n// On failure an error will be returned.\n// The new key is already registered with the ACME provider if the following is true:\n//   - error is of type acme.Error\n//   - StatusCode should be 409 (Conflict)\n//   - Location header will have the KID of the associated account\n//\n// More about account key rollover can be found at\n// https://tools.ietf.org/html/rfc8555#section-7.3.5.\nfunc (c *Client) AccountKeyRollover(ctx context.Context, newKey crypto.Signer) error {\n\treturn c.accountKeyRollover(ctx, newKey)\n}\n\n// Authorize performs the initial step in the pre-authorization flow,\n// as opposed to order-based flow.\n// The caller will then need to choose from and perform a set of returned\n// challenges using c.Accept in order to successfully complete authorization.\n//\n// Once complete, the caller can use AuthorizeOrder which the CA\n// should provision with the already satisfied authorization.\n// For pre-RFC CAs, the caller can proceed directly to requesting a certificate\n// using CreateCert method.\n//\n// If an authorization has been previously granted, the CA may return\n// a valid authorization which has its Status field set to StatusValid.\n//\n// More about pre-authorization can be found at\n// https://tools.ietf.org/html/rfc8555#section-7.4.1.\nfunc (c *Client) Authorize(ctx context.Context, domain string) (*Authorization, error) {\n\treturn c.authorize(ctx, \"dns\", domain)\n}\n\n// AuthorizeIP is the same as Authorize but requests IP address authorization.\n// Clients which successfully obtain such authorization may request to issue\n// a certificate for IP addresses.\n//\n// See the ACME spec extension for more details about IP address identifiers:\n// https://tools.ietf.org/html/draft-ietf-acme-ip.\nfunc (c *Client) AuthorizeIP(ctx context.Context, ipaddr string) (*Authorization, error) {\n\treturn c.authorize(ctx, \"ip\", ipaddr)\n}\n\nfunc (c *Client) authorize(ctx context.Context, typ, val string) (*Authorization, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\tif c.dir.AuthzURL == \"\" {\n\t\t// Pre-Authorization is unsupported\n\t\treturn nil, errPreAuthorizationNotSupported\n\t}\n\n\ttype authzID struct {\n\t\tType  string `json:\"type\"`\n\t\tValue string `json:\"value\"`\n\t}\n\treq := struct {\n\t\tResource   string  `json:\"resource\"`\n\t\tIdentifier authzID `json:\"identifier\"`\n\t}{\n\t\tResource:   \"new-authz\",\n\t\tIdentifier: authzID{Type: typ, Value: val},\n\t}\n\tres, err := c.post(ctx, nil, c.dir.AuthzURL, req, wantStatus(http.StatusCreated))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\n\tvar v wireAuthz\n\tif err := json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: invalid response: %v\", err)\n\t}\n\tif v.Status != StatusPending && v.Status != StatusValid {\n\t\treturn nil, fmt.Errorf(\"acme: unexpected status: %s\", v.Status)\n\t}\n\treturn v.authorization(res.Header.Get(\"Location\")), nil\n}\n\n// GetAuthorization retrieves an authorization identified by the given URL.\n//\n// If a caller needs to poll an authorization until its status is final,\n// see the WaitAuthorization method.\nfunc (c *Client) GetAuthorization(ctx context.Context, url string) (*Authorization, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\n\tres, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\tvar v wireAuthz\n\tif err := json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: invalid response: %v\", err)\n\t}\n\treturn v.authorization(url), nil\n}\n\n// RevokeAuthorization relinquishes an existing authorization identified\n// by the given URL.\n// The url argument is an Authorization.URI value.\n//\n// If successful, the caller will be required to obtain a new authorization\n// using the Authorize or AuthorizeOrder methods before being able to request\n// a new certificate for the domain associated with the authorization.\n//\n// It does not revoke existing certificates.\nfunc (c *Client) RevokeAuthorization(ctx context.Context, url string) error {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn err\n\t}\n\n\treq := struct {\n\t\tResource string `json:\"resource\"`\n\t\tStatus   string `json:\"status\"`\n\t\tDelete   bool   `json:\"delete\"`\n\t}{\n\t\tResource: \"authz\",\n\t\tStatus:   \"deactivated\",\n\t\tDelete:   true,\n\t}\n\tres, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer res.Body.Close()\n\treturn nil\n}\n\n// WaitAuthorization polls an authorization at the given URL\n// until it is in one of the final states, StatusValid or StatusInvalid,\n// the ACME CA responded with a 4xx error code, or the context is done.\n//\n// It returns a non-nil Authorization only if its Status is StatusValid.\n// In all other cases WaitAuthorization returns an error.\n// If the Status is StatusInvalid, the returned error is of type *AuthorizationError.\nfunc (c *Client) WaitAuthorization(ctx context.Context, url string) (*Authorization, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\tfor {\n\t\tres, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar raw wireAuthz\n\t\terr = json.NewDecoder(res.Body).Decode(&raw)\n\t\tres.Body.Close()\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\t// Skip and retry.\n\t\tcase raw.Status == StatusValid:\n\t\t\treturn raw.authorization(url), nil\n\t\tcase raw.Status == StatusInvalid:\n\t\t\treturn nil, raw.error(url)\n\t\t}\n\n\t\t// Exponential backoff is implemented in c.get above.\n\t\t// This is just to prevent continuously hitting the CA\n\t\t// while waiting for a final authorization status.\n\t\td := retryAfter(res.Header.Get(\"Retry-After\"))\n\t\tif d == 0 {\n\t\t\t// Given that the fastest challenges TLS-ALPN and HTTP-01\n\t\t\t// require a CA to make at least 1 network round trip\n\t\t\t// and most likely persist a challenge state,\n\t\t\t// this default delay seems reasonable.\n\t\t\td = time.Second\n\t\t}\n\t\tt := time.NewTimer(d)\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tt.Stop()\n\t\t\treturn nil, ctx.Err()\n\t\tcase <-t.C:\n\t\t\t// Retry.\n\t\t}\n\t}\n}\n\n// GetChallenge retrieves the current status of an challenge.\n//\n// A client typically polls a challenge status using this method.\nfunc (c *Client) GetChallenge(ctx context.Context, url string) (*Challenge, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\n\tres, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK, http.StatusAccepted))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer res.Body.Close()\n\tv := wireChallenge{URI: url}\n\tif err := json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: invalid response: %v\", err)\n\t}\n\treturn v.challenge(), nil\n}\n\n// Accept informs the server that the client accepts one of its challenges\n// previously obtained with c.Authorize.\n//\n// The server will then perform the validation asynchronously.\nfunc (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\n\tpayload := json.RawMessage(\"{}\")\n\tif len(chal.Payload) != 0 {\n\t\tpayload = chal.Payload\n\t}\n\tres, err := c.post(ctx, nil, chal.URI, payload, wantStatus(\n\t\thttp.StatusOK,       // according to the spec\n\t\thttp.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)\n\t))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\n\tvar v wireChallenge\n\tif err := json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: invalid response: %v\", err)\n\t}\n\treturn v.challenge(), nil\n}\n\n// DNS01ChallengeRecord returns a DNS record value for a dns-01 challenge response.\n// A TXT record containing the returned value must be provisioned under\n// \"_acme-challenge\" name of the domain being validated.\n//\n// The token argument is a Challenge.Token value.\nfunc (c *Client) DNS01ChallengeRecord(token string) (string, error) {\n\tka, err := keyAuth(c.Key.Public(), token)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tb := sha256.Sum256([]byte(ka))\n\treturn base64.RawURLEncoding.EncodeToString(b[:]), nil\n}\n\n// HTTP01ChallengeResponse returns the response for an http-01 challenge.\n// Servers should respond with the value to HTTP requests at the URL path\n// provided by HTTP01ChallengePath to validate the challenge and prove control\n// over a domain name.\n//\n// The token argument is a Challenge.Token value.\nfunc (c *Client) HTTP01ChallengeResponse(token string) (string, error) {\n\treturn keyAuth(c.Key.Public(), token)\n}\n\n// HTTP01ChallengePath returns the URL path at which the response for an http-01 challenge\n// should be provided by the servers.\n// The response value can be obtained with HTTP01ChallengeResponse.\n//\n// The token argument is a Challenge.Token value.\nfunc (c *Client) HTTP01ChallengePath(token string) string {\n\treturn \"/.well-known/acme-challenge/\" + token\n}\n\n// TLSSNI01ChallengeCert creates a certificate for TLS-SNI-01 challenge response.\n// Always returns an error.\n//\n// Deprecated: This challenge type was only present in pre-standardized ACME\n// protocol drafts and is insecure for use in shared hosting environments.\nfunc (c *Client) TLSSNI01ChallengeCert(token string, opt ...CertOption) (tls.Certificate, string, error) {\n\treturn tls.Certificate{}, \"\", errPreRFC\n}\n\n// TLSSNI02ChallengeCert creates a certificate for TLS-SNI-02 challenge response.\n// Always returns an error.\n//\n// Deprecated: This challenge type was only present in pre-standardized ACME\n// protocol drafts and is insecure for use in shared hosting environments.\nfunc (c *Client) TLSSNI02ChallengeCert(token string, opt ...CertOption) (tls.Certificate, string, error) {\n\treturn tls.Certificate{}, \"\", errPreRFC\n}\n\n// TLSALPN01ChallengeCert creates a certificate for TLS-ALPN-01 challenge response.\n// Servers can present the certificate to validate the challenge and prove control\n// over an identifier (either a DNS name or the textual form of an IPv4 or IPv6\n// address). For more details on TLS-ALPN-01 see\n// https://www.rfc-editor.org/rfc/rfc8737 and https://www.rfc-editor.org/rfc/rfc8738\n//\n// The token argument is a Challenge.Token value.\n// If a WithKey option is provided, its private part signs the returned cert,\n// and the public part is used to specify the signee.\n// If no WithKey option is provided, a new ECDSA key is generated using P-256 curve.\n//\n// The returned certificate is valid for the next 24 hours and must be presented only when\n// the server name in the TLS ClientHello matches the identifier, and the special acme-tls/1 ALPN protocol\n// has been specified.\n//\n// Validation requests for IP address identifiers will use the reverse DNS form in the server name\n// in the TLS ClientHello since the SNI extension is not supported for IP addresses.\n// See RFC 8738 Section 6 for more information.\nfunc (c *Client) TLSALPN01ChallengeCert(token, identifier string, opt ...CertOption) (cert tls.Certificate, err error) {\n\tka, err := keyAuth(c.Key.Public(), token)\n\tif err != nil {\n\t\treturn tls.Certificate{}, err\n\t}\n\tshasum := sha256.Sum256([]byte(ka))\n\textValue, err := asn1.Marshal(shasum[:])\n\tif err != nil {\n\t\treturn tls.Certificate{}, err\n\t}\n\tacmeExtension := pkix.Extension{\n\t\tId:       idPeACMEIdentifier,\n\t\tCritical: true,\n\t\tValue:    extValue,\n\t}\n\n\ttmpl := defaultTLSChallengeCertTemplate()\n\n\tvar newOpt []CertOption\n\tfor _, o := range opt {\n\t\tswitch o := o.(type) {\n\t\tcase *certOptTemplate:\n\t\t\tt := *(*x509.Certificate)(o) // shallow copy is ok\n\t\t\ttmpl = &t\n\t\tdefault:\n\t\t\tnewOpt = append(newOpt, o)\n\t\t}\n\t}\n\ttmpl.ExtraExtensions = append(tmpl.ExtraExtensions, acmeExtension)\n\tnewOpt = append(newOpt, WithTemplate(tmpl))\n\treturn tlsChallengeCert(identifier, newOpt)\n}\n\n// popNonce returns a nonce value previously stored with c.addNonce\n// or fetches a fresh one from c.dir.NonceURL.\n// If NonceURL is empty, it first tries c.directoryURL() and, failing that,\n// the provided url.\nfunc (c *Client) popNonce(ctx context.Context, url string) (string, error) {\n\tc.noncesMu.Lock()\n\tdefer c.noncesMu.Unlock()\n\tif len(c.nonces) == 0 {\n\t\tif c.dir != nil && c.dir.NonceURL != \"\" {\n\t\t\treturn c.fetchNonce(ctx, c.dir.NonceURL)\n\t\t}\n\t\tdirURL := c.directoryURL()\n\t\tv, err := c.fetchNonce(ctx, dirURL)\n\t\tif err != nil && url != dirURL {\n\t\t\tv, err = c.fetchNonce(ctx, url)\n\t\t}\n\t\treturn v, err\n\t}\n\tvar nonce string\n\tfor nonce = range c.nonces {\n\t\tdelete(c.nonces, nonce)\n\t\tbreak\n\t}\n\treturn nonce, nil\n}\n\n// clearNonces clears any stored nonces\nfunc (c *Client) clearNonces() {\n\tc.noncesMu.Lock()\n\tdefer c.noncesMu.Unlock()\n\tc.nonces = make(map[string]struct{})\n}\n\n// addNonce stores a nonce value found in h (if any) for future use.\nfunc (c *Client) addNonce(h http.Header) {\n\tv := nonceFromHeader(h)\n\tif v == \"\" {\n\t\treturn\n\t}\n\tc.noncesMu.Lock()\n\tdefer c.noncesMu.Unlock()\n\tif len(c.nonces) >= maxNonces {\n\t\treturn\n\t}\n\tif c.nonces == nil {\n\t\tc.nonces = make(map[string]struct{})\n\t}\n\tc.nonces[v] = struct{}{}\n}\n\nfunc (c *Client) fetchNonce(ctx context.Context, url string) (string, error) {\n\tr, err := http.NewRequestWithContext(ctx, \"HEAD\", url, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tresp, err := c.doNoRetry(ctx, r)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer resp.Body.Close()\n\tnonce := nonceFromHeader(resp.Header)\n\tif nonce == \"\" {\n\t\tif resp.StatusCode > 299 {\n\t\t\treturn \"\", responseError(resp)\n\t\t}\n\t\treturn \"\", errors.New(\"acme: nonce not found\")\n\t}\n\treturn nonce, nil\n}\n\nfunc nonceFromHeader(h http.Header) string {\n\treturn h.Get(\"Replay-Nonce\")\n}\n\n// linkHeader returns URI-Reference values of all Link headers\n// with relation-type rel.\n// See https://tools.ietf.org/html/rfc5988#section-5 for details.\nfunc linkHeader(h http.Header, rel string) []string {\n\tvar links []string\n\tfor _, v := range h[\"Link\"] {\n\t\tparts := strings.Split(v, \";\")\n\t\tfor _, p := range parts {\n\t\t\tp = strings.TrimSpace(p)\n\t\t\tif !strings.HasPrefix(p, \"rel=\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif v := strings.Trim(p[4:], `\"`); v == rel {\n\t\t\t\tlinks = append(links, strings.Trim(parts[0], \"<>\"))\n\t\t\t}\n\t\t}\n\t}\n\treturn links\n}\n\n// keyAuth generates a key authorization string for a given token.\nfunc keyAuth(pub crypto.PublicKey, token string) (string, error) {\n\tth, err := JWKThumbprint(pub)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn fmt.Sprintf(\"%s.%s\", token, th), nil\n}\n\n// defaultTLSChallengeCertTemplate is a template used to create challenge certs for TLS challenges.\nfunc defaultTLSChallengeCertTemplate() *x509.Certificate {\n\treturn &x509.Certificate{\n\t\tSerialNumber:          big.NewInt(1),\n\t\tNotBefore:             time.Now(),\n\t\tNotAfter:              time.Now().Add(24 * time.Hour),\n\t\tBasicConstraintsValid: true,\n\t\tKeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,\n\t\tExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},\n\t}\n}\n\n// tlsChallengeCert creates a temporary certificate for TLS-ALPN challenges\n// for the given identifier, using an auto-generated public/private key pair.\n//\n// If the provided identifier is a domain name, it will be used as a DNS type SAN and for the\n// subject common name. If the provided identifier is an IP address it will be used as an IP type\n// SAN.\n//\n// To create a cert with a custom key pair, specify WithKey option.\nfunc tlsChallengeCert(identifier string, opt []CertOption) (tls.Certificate, error) {\n\tvar key crypto.Signer\n\ttmpl := defaultTLSChallengeCertTemplate()\n\tfor _, o := range opt {\n\t\tswitch o := o.(type) {\n\t\tcase *certOptKey:\n\t\t\tif key != nil {\n\t\t\t\treturn tls.Certificate{}, errors.New(\"acme: duplicate key option\")\n\t\t\t}\n\t\t\tkey = o.key\n\t\tcase *certOptTemplate:\n\t\t\tt := *(*x509.Certificate)(o) // shallow copy is ok\n\t\t\ttmpl = &t\n\t\tdefault:\n\t\t\t// package's fault, if we let this happen:\n\t\t\tpanic(fmt.Sprintf(\"unsupported option type %T\", o))\n\t\t}\n\t}\n\tif key == nil {\n\t\tvar err error\n\t\tif key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil {\n\t\t\treturn tls.Certificate{}, err\n\t\t}\n\t}\n\n\tif ip := net.ParseIP(identifier); ip != nil {\n\t\ttmpl.IPAddresses = []net.IP{ip}\n\t} else {\n\t\ttmpl.DNSNames = []string{identifier}\n\t\ttmpl.Subject.CommonName = identifier\n\t}\n\n\tder, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key)\n\tif err != nil {\n\t\treturn tls.Certificate{}, err\n\t}\n\treturn tls.Certificate{\n\t\tCertificate: [][]byte{der},\n\t\tPrivateKey:  key,\n\t}, nil\n}\n\n// timeNow is time.Now, except in tests which can mess with it.\nvar timeNow = time.Now\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/autocert/autocert.go",
    "content": "// Copyright 2016 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// Package autocert provides automatic access to certificates from Let's Encrypt\n// and any other ACME-based CA.\n//\n// This package is a work in progress and makes no API stability promises.\npackage autocert\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/elliptic\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"crypto/x509/pkix\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\tmathrand \"math/rand\"\n\t\"net\"\n\t\"net/http\"\n\t\"path\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/crypto/acme\"\n\t\"golang.org/x/net/idna\"\n)\n\n// DefaultACMEDirectory is the default ACME Directory URL used when the Manager's Client is nil.\nconst DefaultACMEDirectory = \"https://acme-v02.api.letsencrypt.org/directory\"\n\n// createCertRetryAfter is how much time to wait before removing a failed state\n// entry due to an unsuccessful createCert call.\n// This is a variable instead of a const for testing.\n// TODO: Consider making it configurable or an exp backoff?\nvar createCertRetryAfter = time.Minute\n\n// pseudoRand is safe for concurrent use.\nvar pseudoRand *lockedMathRand\n\nvar errPreRFC = errors.New(\"autocert: ACME server doesn't support RFC 8555\")\n\nfunc init() {\n\tsrc := mathrand.NewSource(time.Now().UnixNano())\n\tpseudoRand = &lockedMathRand{rnd: mathrand.New(src)}\n}\n\n// AcceptTOS is a Manager.Prompt function that always returns true to\n// indicate acceptance of the CA's Terms of Service during account\n// registration.\nfunc AcceptTOS(tosURL string) bool { return true }\n\n// HostPolicy specifies which host names the Manager is allowed to respond to.\n// It returns a non-nil error if the host should be rejected.\n// The returned error is accessible via tls.Conn.Handshake and its callers.\n// See Manager's HostPolicy field and GetCertificate method docs for more details.\ntype HostPolicy func(ctx context.Context, host string) error\n\n// HostWhitelist returns a policy where only the specified host names are allowed.\n// Only exact matches are currently supported. Subdomains, regexp or wildcard\n// will not match.\n//\n// Note that all hosts will be converted to Punycode via idna.Lookup.ToASCII so that\n// Manager.GetCertificate can handle the Unicode IDN and mixedcase hosts correctly.\n// Invalid hosts will be silently ignored.\nfunc HostWhitelist(hosts ...string) HostPolicy {\n\twhitelist := make(map[string]bool, len(hosts))\n\tfor _, h := range hosts {\n\t\tif h, err := idna.Lookup.ToASCII(h); err == nil {\n\t\t\twhitelist[h] = true\n\t\t}\n\t}\n\treturn func(_ context.Context, host string) error {\n\t\tif !whitelist[host] {\n\t\t\treturn fmt.Errorf(\"acme/autocert: host %q not configured in HostWhitelist\", host)\n\t\t}\n\t\treturn nil\n\t}\n}\n\n// defaultHostPolicy is used when Manager.HostPolicy is not set.\nfunc defaultHostPolicy(context.Context, string) error {\n\treturn nil\n}\n\n// Manager is a stateful certificate manager built on top of acme.Client.\n// It obtains and refreshes certificates automatically using \"tls-alpn-01\"\n// or \"http-01\" challenge types, as well as providing them to a TLS server\n// via tls.Config.\n//\n// You must specify a cache implementation, such as DirCache,\n// to reuse obtained certificates across program restarts.\n// Otherwise your server is very likely to exceed the certificate\n// issuer's request rate limits.\ntype Manager struct {\n\t// Prompt specifies a callback function to conditionally accept a CA's Terms of Service (TOS).\n\t// The registration may require the caller to agree to the CA's TOS.\n\t// If so, Manager calls Prompt with a TOS URL provided by the CA. Prompt should report\n\t// whether the caller agrees to the terms.\n\t//\n\t// To always accept the terms, the callers can use AcceptTOS.\n\tPrompt func(tosURL string) bool\n\n\t// Cache optionally stores and retrieves previously-obtained certificates\n\t// and other state. If nil, certs will only be cached for the lifetime of\n\t// the Manager. Multiple Managers can share the same Cache.\n\t//\n\t// Using a persistent Cache, such as DirCache, is strongly recommended.\n\tCache Cache\n\n\t// HostPolicy controls which domains the Manager will attempt\n\t// to retrieve new certificates for. It does not affect cached certs.\n\t//\n\t// If non-nil, HostPolicy is called before requesting a new cert.\n\t// If nil, all hosts are currently allowed. This is not recommended,\n\t// as it opens a potential attack where clients connect to a server\n\t// by IP address and pretend to be asking for an incorrect host name.\n\t// Manager will attempt to obtain a certificate for that host, incorrectly,\n\t// eventually reaching the CA's rate limit for certificate requests\n\t// and making it impossible to obtain actual certificates.\n\t//\n\t// See GetCertificate for more details.\n\tHostPolicy HostPolicy\n\n\t// RenewBefore optionally specifies how early certificates should\n\t// be renewed before they expire.\n\t//\n\t// If zero, they're renewed at the lesser of 30 days or\n\t// 1/3 of the certificate lifetime.\n\tRenewBefore time.Duration\n\n\t// Client is used to perform low-level operations, such as account registration\n\t// and requesting new certificates.\n\t//\n\t// If Client is nil, a zero-value acme.Client is used with DefaultACMEDirectory\n\t// as the directory endpoint.\n\t// If the Client.Key is nil, a new ECDSA P-256 key is generated and,\n\t// if Cache is not nil, stored in cache.\n\t//\n\t// Mutating the field after the first call of GetCertificate method will have no effect.\n\tClient *acme.Client\n\n\t// Email optionally specifies a contact email address.\n\t// This is used by CAs, such as Let's Encrypt, to notify about problems\n\t// with issued certificates.\n\t//\n\t// If the Client's account key is already registered, Email is not used.\n\tEmail string\n\n\t// ForceRSA used to make the Manager generate RSA certificates. It is now ignored.\n\t//\n\t// Deprecated: the Manager will request the correct type of certificate based\n\t// on what each client supports.\n\tForceRSA bool\n\n\t// ExtraExtensions are used when generating a new CSR (Certificate Request),\n\t// thus allowing customization of the resulting certificate.\n\t// For instance, TLS Feature Extension (RFC 7633) can be used\n\t// to prevent an OCSP downgrade attack.\n\t//\n\t// The field value is passed to crypto/x509.CreateCertificateRequest\n\t// in the template's ExtraExtensions field as is.\n\tExtraExtensions []pkix.Extension\n\n\t// ExternalAccountBinding optionally represents an arbitrary binding to an\n\t// account of the CA to which the ACME server is tied.\n\t// See RFC 8555, Section 7.3.4 for more details.\n\tExternalAccountBinding *acme.ExternalAccountBinding\n\n\tclientMu sync.Mutex\n\tclient   *acme.Client // initialized by acmeClient method\n\n\tstateMu sync.Mutex\n\tstate   map[certKey]*certState\n\n\t// renewal tracks the set of domains currently running renewal timers.\n\trenewalMu sync.Mutex\n\trenewal   map[certKey]*domainRenewal\n\n\t// challengeMu guards tryHTTP01, certTokens and httpTokens.\n\tchallengeMu sync.RWMutex\n\t// tryHTTP01 indicates whether the Manager should try \"http-01\" challenge type\n\t// during the authorization flow.\n\ttryHTTP01 bool\n\t// httpTokens contains response body values for http-01 challenges\n\t// and is keyed by the URL path at which a challenge response is expected\n\t// to be provisioned.\n\t// The entries are stored for the duration of the authorization flow.\n\thttpTokens map[string][]byte\n\t// certTokens contains temporary certificates for tls-alpn-01 challenges\n\t// and is keyed by the domain name which matches the ClientHello server name.\n\t// The entries are stored for the duration of the authorization flow.\n\tcertTokens map[string]*tls.Certificate\n\n\t// nowFunc, if not nil, returns the current time. This may be set for\n\t// testing purposes.\n\tnowFunc func() time.Time\n}\n\n// certKey is the key by which certificates are tracked in state, renewal and cache.\ntype certKey struct {\n\tdomain  string // without trailing dot\n\tisRSA   bool   // RSA cert for legacy clients (as opposed to default ECDSA)\n\tisToken bool   // tls-based challenge token cert; key type is undefined regardless of isRSA\n}\n\nfunc (c certKey) String() string {\n\tif c.isToken {\n\t\treturn c.domain + \"+token\"\n\t}\n\tif c.isRSA {\n\t\treturn c.domain + \"+rsa\"\n\t}\n\treturn c.domain\n}\n\n// TLSConfig creates a new TLS config suitable for net/http.Server servers,\n// supporting HTTP/2 and the tls-alpn-01 ACME challenge type.\nfunc (m *Manager) TLSConfig() *tls.Config {\n\treturn &tls.Config{\n\t\tGetCertificate: m.GetCertificate,\n\t\tNextProtos: []string{\n\t\t\t\"h2\", \"http/1.1\", // enable HTTP/2\n\t\t\tacme.ALPNProto, // enable tls-alpn ACME challenges\n\t\t},\n\t}\n}\n\n// GetCertificate implements the tls.Config.GetCertificate hook.\n// It provides a TLS certificate for hello.ServerName host, including answering\n// tls-alpn-01 challenges.\n// All other fields of hello are ignored.\n//\n// If m.HostPolicy is non-nil, GetCertificate calls the policy before requesting\n// a new cert. A non-nil error returned from m.HostPolicy halts TLS negotiation.\n// The error is propagated back to the caller of GetCertificate and is user-visible.\n// This does not affect cached certs. See HostPolicy field description for more details.\n//\n// If GetCertificate is used directly, instead of via Manager.TLSConfig, package users will\n// also have to add acme.ALPNProto to NextProtos for tls-alpn-01, or use HTTPHandler for http-01.\nfunc (m *Manager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {\n\tif m.Prompt == nil {\n\t\treturn nil, errors.New(\"acme/autocert: Manager.Prompt not set\")\n\t}\n\n\tname := hello.ServerName\n\tif name == \"\" {\n\t\treturn nil, errors.New(\"acme/autocert: missing server name\")\n\t}\n\tif !strings.Contains(strings.Trim(name, \".\"), \".\") {\n\t\treturn nil, errors.New(\"acme/autocert: server name component count invalid\")\n\t}\n\n\t// Note that this conversion is necessary because some server names in the handshakes\n\t// started by some clients (such as cURL) are not converted to Punycode, which will\n\t// prevent us from obtaining certificates for them. In addition, we should also treat\n\t// example.com and EXAMPLE.COM as equivalent and return the same certificate for them.\n\t// Fortunately, this conversion also helped us deal with this kind of mixedcase problems.\n\t//\n\t// Due to the \"σςΣ\" problem (see https://unicode.org/faq/idn.html#22), we can't use\n\t// idna.Punycode.ToASCII (or just idna.ToASCII) here.\n\tname, err := idna.Lookup.ToASCII(name)\n\tif err != nil {\n\t\treturn nil, errors.New(\"acme/autocert: server name contains invalid character\")\n\t}\n\n\t// In the worst-case scenario, the timeout needs to account for caching, host policy,\n\t// domain ownership verification and certificate issuance.\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)\n\tdefer cancel()\n\n\t// Check whether this is a token cert requested for TLS-ALPN challenge.\n\tif wantsTokenCert(hello) {\n\t\tm.challengeMu.RLock()\n\t\tdefer m.challengeMu.RUnlock()\n\t\tif cert := m.certTokens[name]; cert != nil {\n\t\t\treturn cert, nil\n\t\t}\n\t\tif cert, err := m.cacheGet(ctx, certKey{domain: name, isToken: true}); err == nil {\n\t\t\treturn cert, nil\n\t\t}\n\t\t// TODO: cache error results?\n\t\treturn nil, fmt.Errorf(\"acme/autocert: no token cert for %q\", name)\n\t}\n\n\t// regular domain\n\tif err := m.hostPolicy()(ctx, name); err != nil {\n\t\treturn nil, err\n\t}\n\n\tck := certKey{\n\t\tdomain: strings.TrimSuffix(name, \".\"), // golang.org/issue/18114\n\t\tisRSA:  !supportsECDSA(hello),\n\t}\n\tcert, err := m.cert(ctx, ck)\n\tif err == nil {\n\t\treturn cert, nil\n\t}\n\tif err != ErrCacheMiss {\n\t\treturn nil, err\n\t}\n\n\t// first-time\n\tcert, err = m.createCert(ctx, ck)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tm.cachePut(ctx, ck, cert)\n\treturn cert, nil\n}\n\n// wantsTokenCert reports whether a TLS request with SNI is made by a CA server\n// for a challenge verification.\nfunc wantsTokenCert(hello *tls.ClientHelloInfo) bool {\n\t// tls-alpn-01\n\tif len(hello.SupportedProtos) == 1 && hello.SupportedProtos[0] == acme.ALPNProto {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc supportsECDSA(hello *tls.ClientHelloInfo) bool {\n\t// The \"signature_algorithms\" extension, if present, limits the key exchange\n\t// algorithms allowed by the cipher suites. See RFC 5246, section 7.4.1.4.1.\n\tif hello.SignatureSchemes != nil {\n\t\tecdsaOK := false\n\tschemeLoop:\n\t\tfor _, scheme := range hello.SignatureSchemes {\n\t\t\tconst tlsECDSAWithSHA1 tls.SignatureScheme = 0x0203 // constant added in Go 1.10\n\t\t\tswitch scheme {\n\t\t\tcase tlsECDSAWithSHA1, tls.ECDSAWithP256AndSHA256,\n\t\t\t\ttls.ECDSAWithP384AndSHA384, tls.ECDSAWithP521AndSHA512:\n\t\t\t\tecdsaOK = true\n\t\t\t\tbreak schemeLoop\n\t\t\t}\n\t\t}\n\t\tif !ecdsaOK {\n\t\t\treturn false\n\t\t}\n\t}\n\tif hello.SupportedCurves != nil {\n\t\tecdsaOK := false\n\t\tfor _, curve := range hello.SupportedCurves {\n\t\t\tif curve == tls.CurveP256 {\n\t\t\t\tecdsaOK = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !ecdsaOK {\n\t\t\treturn false\n\t\t}\n\t}\n\tfor _, suite := range hello.CipherSuites {\n\t\tswitch suite {\n\t\tcase tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,\n\t\t\ttls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// HTTPHandler configures the Manager to provision ACME \"http-01\" challenge responses.\n// It returns an http.Handler that responds to the challenges and must be\n// running on port 80. If it receives a request that is not an ACME challenge,\n// it delegates the request to the optional fallback handler.\n//\n// If fallback is nil, the returned handler redirects all GET and HEAD requests\n// to the default TLS port 443 with 302 Found status code, preserving the original\n// request path and query. It responds with 400 Bad Request to all other HTTP methods.\n// The fallback is not protected by the optional HostPolicy.\n//\n// Because the fallback handler is run with unencrypted port 80 requests,\n// the fallback should not serve TLS-only requests.\n//\n// If HTTPHandler is never called, the Manager will only use the \"tls-alpn-01\"\n// challenge for domain verification.\nfunc (m *Manager) HTTPHandler(fallback http.Handler) http.Handler {\n\tm.challengeMu.Lock()\n\tdefer m.challengeMu.Unlock()\n\tm.tryHTTP01 = true\n\n\tif fallback == nil {\n\t\tfallback = http.HandlerFunc(handleHTTPRedirect)\n\t}\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tif !strings.HasPrefix(r.URL.Path, \"/.well-known/acme-challenge/\") {\n\t\t\tfallback.ServeHTTP(w, r)\n\t\t\treturn\n\t\t}\n\t\t// A reasonable context timeout for cache and host policy only,\n\t\t// because we don't wait for a new certificate issuance here.\n\t\tctx, cancel := context.WithTimeout(r.Context(), time.Minute)\n\t\tdefer cancel()\n\t\tif err := m.hostPolicy()(ctx, r.Host); err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusForbidden)\n\t\t\treturn\n\t\t}\n\t\tdata, err := m.httpToken(ctx, r.URL.Path)\n\t\tif err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusNotFound)\n\t\t\treturn\n\t\t}\n\t\tw.Write(data)\n\t})\n}\n\nfunc handleHTTPRedirect(w http.ResponseWriter, r *http.Request) {\n\tif r.Method != \"GET\" && r.Method != \"HEAD\" {\n\t\thttp.Error(w, \"Use HTTPS\", http.StatusBadRequest)\n\t\treturn\n\t}\n\ttarget := \"https://\" + stripPort(r.Host) + r.URL.RequestURI()\n\thttp.Redirect(w, r, target, http.StatusFound)\n}\n\nfunc stripPort(hostport string) string {\n\thost, _, err := net.SplitHostPort(hostport)\n\tif err != nil {\n\t\treturn hostport\n\t}\n\treturn net.JoinHostPort(host, \"443\")\n}\n\n// cert returns an existing certificate either from m.state or cache.\n// If a certificate is found in cache but not in m.state, the latter will be filled\n// with the cached value.\nfunc (m *Manager) cert(ctx context.Context, ck certKey) (*tls.Certificate, error) {\n\tm.stateMu.Lock()\n\tif s, ok := m.state[ck]; ok {\n\t\tm.stateMu.Unlock()\n\t\ts.RLock()\n\t\tdefer s.RUnlock()\n\t\treturn s.tlscert()\n\t}\n\tdefer m.stateMu.Unlock()\n\tcert, err := m.cacheGet(ctx, ck)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsigner, ok := cert.PrivateKey.(crypto.Signer)\n\tif !ok {\n\t\treturn nil, errors.New(\"acme/autocert: private key cannot sign\")\n\t}\n\tif m.state == nil {\n\t\tm.state = make(map[certKey]*certState)\n\t}\n\ts := &certState{\n\t\tkey:  signer,\n\t\tcert: cert.Certificate,\n\t\tleaf: cert.Leaf,\n\t}\n\tm.state[ck] = s\n\tm.startRenew(ck, s.key, s.leaf.NotBefore, s.leaf.NotAfter)\n\treturn cert, nil\n}\n\n// cacheGet always returns a valid certificate, or an error otherwise.\n// If a cached certificate exists but is not valid, ErrCacheMiss is returned.\nfunc (m *Manager) cacheGet(ctx context.Context, ck certKey) (*tls.Certificate, error) {\n\tif m.Cache == nil {\n\t\treturn nil, ErrCacheMiss\n\t}\n\tdata, err := m.Cache.Get(ctx, ck.String())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// private\n\tpriv, pub := pem.Decode(data)\n\tif priv == nil || !strings.Contains(priv.Type, \"PRIVATE\") {\n\t\treturn nil, ErrCacheMiss\n\t}\n\tprivKey, err := parsePrivateKey(priv.Bytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// public\n\tvar pubDER [][]byte\n\tfor len(pub) > 0 {\n\t\tvar b *pem.Block\n\t\tb, pub = pem.Decode(pub)\n\t\tif b == nil {\n\t\t\tbreak\n\t\t}\n\t\tpubDER = append(pubDER, b.Bytes)\n\t}\n\tif len(pub) > 0 {\n\t\t// Leftover content not consumed by pem.Decode. Corrupt. Ignore.\n\t\treturn nil, ErrCacheMiss\n\t}\n\n\t// verify and create TLS cert\n\tleaf, err := validCert(ck, pubDER, privKey, m.now())\n\tif err != nil {\n\t\treturn nil, ErrCacheMiss\n\t}\n\ttlscert := &tls.Certificate{\n\t\tCertificate: pubDER,\n\t\tPrivateKey:  privKey,\n\t\tLeaf:        leaf,\n\t}\n\treturn tlscert, nil\n}\n\nfunc (m *Manager) cachePut(ctx context.Context, ck certKey, tlscert *tls.Certificate) error {\n\tif m.Cache == nil {\n\t\treturn nil\n\t}\n\n\t// contains PEM-encoded data\n\tvar buf bytes.Buffer\n\n\t// private\n\tswitch key := tlscert.PrivateKey.(type) {\n\tcase *ecdsa.PrivateKey:\n\t\tif err := encodeECDSAKey(&buf, key); err != nil {\n\t\t\treturn err\n\t\t}\n\tcase *rsa.PrivateKey:\n\t\tb := x509.MarshalPKCS1PrivateKey(key)\n\t\tpb := &pem.Block{Type: \"RSA PRIVATE KEY\", Bytes: b}\n\t\tif err := pem.Encode(&buf, pb); err != nil {\n\t\t\treturn err\n\t\t}\n\tdefault:\n\t\treturn errors.New(\"acme/autocert: unknown private key type\")\n\t}\n\n\t// public\n\tfor _, b := range tlscert.Certificate {\n\t\tpb := &pem.Block{Type: \"CERTIFICATE\", Bytes: b}\n\t\tif err := pem.Encode(&buf, pb); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn m.Cache.Put(ctx, ck.String(), buf.Bytes())\n}\n\nfunc encodeECDSAKey(w io.Writer, key *ecdsa.PrivateKey) error {\n\tb, err := x509.MarshalECPrivateKey(key)\n\tif err != nil {\n\t\treturn err\n\t}\n\tpb := &pem.Block{Type: \"EC PRIVATE KEY\", Bytes: b}\n\treturn pem.Encode(w, pb)\n}\n\n// createCert starts the domain ownership verification and returns a certificate\n// for that domain upon success.\n//\n// If the domain is already being verified, it waits for the existing verification to complete.\n// Either way, createCert blocks for the duration of the whole process.\nfunc (m *Manager) createCert(ctx context.Context, ck certKey) (*tls.Certificate, error) {\n\t// TODO: maybe rewrite this whole piece using sync.Once\n\tstate, err := m.certState(ck)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// state may exist if another goroutine is already working on it\n\t// in which case just wait for it to finish\n\tif !state.locked {\n\t\tstate.RLock()\n\t\tdefer state.RUnlock()\n\t\treturn state.tlscert()\n\t}\n\n\t// We are the first; state is locked.\n\t// Unblock the readers when domain ownership is verified\n\t// and we got the cert or the process failed.\n\tdefer state.Unlock()\n\tstate.locked = false\n\n\tder, leaf, err := m.authorizedCert(ctx, state.key, ck)\n\tif err != nil {\n\t\t// Remove the failed state after some time,\n\t\t// making the manager call createCert again on the following TLS hello.\n\t\tdidRemove := testDidRemoveState // The lifetime of this timer is untracked, so copy mutable local state to avoid races.\n\t\ttime.AfterFunc(createCertRetryAfter, func() {\n\t\t\tdefer didRemove(ck)\n\t\t\tm.stateMu.Lock()\n\t\t\tdefer m.stateMu.Unlock()\n\t\t\t// Verify the state hasn't changed and it's still invalid\n\t\t\t// before deleting.\n\t\t\ts, ok := m.state[ck]\n\t\t\tif !ok {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif _, err := validCert(ck, s.cert, s.key, m.now()); err == nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tdelete(m.state, ck)\n\t\t})\n\t\treturn nil, err\n\t}\n\tstate.cert = der\n\tstate.leaf = leaf\n\tm.startRenew(ck, state.key, state.leaf.NotBefore, state.leaf.NotAfter)\n\treturn state.tlscert()\n}\n\n// certState returns a new or existing certState.\n// If a new certState is returned, state.exist is false and the state is locked.\n// The returned error is non-nil only in the case where a new state could not be created.\nfunc (m *Manager) certState(ck certKey) (*certState, error) {\n\tm.stateMu.Lock()\n\tdefer m.stateMu.Unlock()\n\tif m.state == nil {\n\t\tm.state = make(map[certKey]*certState)\n\t}\n\t// existing state\n\tif state, ok := m.state[ck]; ok {\n\t\treturn state, nil\n\t}\n\n\t// new locked state\n\tvar (\n\t\terr error\n\t\tkey crypto.Signer\n\t)\n\tif ck.isRSA {\n\t\tkey, err = rsa.GenerateKey(rand.Reader, 2048)\n\t} else {\n\t\tkey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tstate := &certState{\n\t\tkey:    key,\n\t\tlocked: true,\n\t}\n\tstate.Lock() // will be unlocked by m.certState caller\n\tm.state[ck] = state\n\treturn state, nil\n}\n\n// authorizedCert starts the domain ownership verification process and requests a new cert upon success.\n// The key argument is the certificate private key.\nfunc (m *Manager) authorizedCert(ctx context.Context, key crypto.Signer, ck certKey) (der [][]byte, leaf *x509.Certificate, err error) {\n\tcsr, err := certRequest(key, ck.domain, m.ExtraExtensions)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tclient, err := m.acmeClient(ctx)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tdir, err := client.Discover(ctx)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tif dir.OrderURL == \"\" {\n\t\treturn nil, nil, errPreRFC\n\t}\n\n\to, err := m.verifyRFC(ctx, client, ck.domain)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tchain, _, err := client.CreateOrderCert(ctx, o.FinalizeURL, csr, true)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tleaf, err = validCert(ck, chain, key, m.now())\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn chain, leaf, nil\n}\n\n// verifyRFC runs the identifier (domain) order-based authorization flow for RFC compliant CAs\n// using each applicable ACME challenge type.\nfunc (m *Manager) verifyRFC(ctx context.Context, client *acme.Client, domain string) (*acme.Order, error) {\n\t// Try each supported challenge type starting with a new order each time.\n\t// The nextTyp index of the next challenge type to try is shared across\n\t// all order authorizations: if we've tried a challenge type once and it didn't work,\n\t// it will most likely not work on another order's authorization either.\n\tchallengeTypes := m.supportedChallengeTypes()\n\tnextTyp := 0 // challengeTypes index\nAuthorizeOrderLoop:\n\tfor {\n\t\to, err := client.AuthorizeOrder(ctx, acme.DomainIDs(domain))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\t// Remove all hanging authorizations to reduce rate limit quotas\n\t\t// after we're done.\n\t\tdefer func(urls []string) {\n\t\t\tgo m.deactivatePendingAuthz(urls)\n\t\t}(o.AuthzURLs)\n\n\t\t// Check if there's actually anything we need to do.\n\t\tswitch o.Status {\n\t\tcase acme.StatusReady:\n\t\t\t// Already authorized.\n\t\t\treturn o, nil\n\t\tcase acme.StatusPending:\n\t\t\t// Continue normal Order-based flow.\n\t\tdefault:\n\t\t\treturn nil, fmt.Errorf(\"acme/autocert: invalid new order status %q; order URL: %q\", o.Status, o.URI)\n\t\t}\n\n\t\t// Satisfy all pending authorizations.\n\t\tfor _, zurl := range o.AuthzURLs {\n\t\t\tz, err := client.GetAuthorization(ctx, zurl)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif z.Status != acme.StatusPending {\n\t\t\t\t// We are interested only in pending authorizations.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Pick the next preferred challenge.\n\t\t\tvar chal *acme.Challenge\n\t\t\tfor chal == nil && nextTyp < len(challengeTypes) {\n\t\t\t\tchal = pickChallenge(challengeTypes[nextTyp], z.Challenges)\n\t\t\t\tnextTyp++\n\t\t\t}\n\t\t\tif chal == nil {\n\t\t\t\treturn nil, fmt.Errorf(\"acme/autocert: unable to satisfy %q for domain %q: no viable challenge type found\", z.URI, domain)\n\t\t\t}\n\t\t\t// Respond to the challenge and wait for validation result.\n\t\t\tcleanup, err := m.fulfill(ctx, client, chal, domain)\n\t\t\tif err != nil {\n\t\t\t\tcontinue AuthorizeOrderLoop\n\t\t\t}\n\t\t\tdefer cleanup()\n\t\t\tif _, err := client.Accept(ctx, chal); err != nil {\n\t\t\t\tcontinue AuthorizeOrderLoop\n\t\t\t}\n\t\t\tif _, err := client.WaitAuthorization(ctx, z.URI); err != nil {\n\t\t\t\tcontinue AuthorizeOrderLoop\n\t\t\t}\n\t\t}\n\n\t\t// All authorizations are satisfied.\n\t\t// Wait for the CA to update the order status.\n\t\to, err = client.WaitOrder(ctx, o.URI)\n\t\tif err != nil {\n\t\t\tcontinue AuthorizeOrderLoop\n\t\t}\n\t\treturn o, nil\n\t}\n}\n\nfunc pickChallenge(typ string, chal []*acme.Challenge) *acme.Challenge {\n\tfor _, c := range chal {\n\t\tif c.Type == typ {\n\t\t\treturn c\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (m *Manager) supportedChallengeTypes() []string {\n\tm.challengeMu.RLock()\n\tdefer m.challengeMu.RUnlock()\n\ttyp := []string{\"tls-alpn-01\"}\n\tif m.tryHTTP01 {\n\t\ttyp = append(typ, \"http-01\")\n\t}\n\treturn typ\n}\n\n// deactivatePendingAuthz relinquishes all authorizations identified by the elements\n// of the provided uri slice which are in \"pending\" state.\n// It ignores revocation errors.\n//\n// deactivatePendingAuthz takes no context argument and instead runs with its own\n// \"detached\" context because deactivations are done in a goroutine separate from\n// that of the main issuance or renewal flow.\nfunc (m *Manager) deactivatePendingAuthz(uri []string) {\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)\n\tdefer cancel()\n\tclient, err := m.acmeClient(ctx)\n\tif err != nil {\n\t\treturn\n\t}\n\tfor _, u := range uri {\n\t\tz, err := client.GetAuthorization(ctx, u)\n\t\tif err == nil && z.Status == acme.StatusPending {\n\t\t\tclient.RevokeAuthorization(ctx, u)\n\t\t}\n\t}\n}\n\n// fulfill provisions a response to the challenge chal.\n// The cleanup is non-nil only if provisioning succeeded.\nfunc (m *Manager) fulfill(ctx context.Context, client *acme.Client, chal *acme.Challenge, domain string) (cleanup func(), err error) {\n\tswitch chal.Type {\n\tcase \"tls-alpn-01\":\n\t\tcert, err := client.TLSALPN01ChallengeCert(chal.Token, domain)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tm.putCertToken(ctx, domain, &cert)\n\t\treturn func() { go m.deleteCertToken(domain) }, nil\n\tcase \"http-01\":\n\t\tresp, err := client.HTTP01ChallengeResponse(chal.Token)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tp := client.HTTP01ChallengePath(chal.Token)\n\t\tm.putHTTPToken(ctx, p, resp)\n\t\treturn func() { go m.deleteHTTPToken(p) }, nil\n\t}\n\treturn nil, fmt.Errorf(\"acme/autocert: unknown challenge type %q\", chal.Type)\n}\n\n// putCertToken stores the token certificate with the specified name\n// in both m.certTokens map and m.Cache.\nfunc (m *Manager) putCertToken(ctx context.Context, name string, cert *tls.Certificate) {\n\tm.challengeMu.Lock()\n\tdefer m.challengeMu.Unlock()\n\tif m.certTokens == nil {\n\t\tm.certTokens = make(map[string]*tls.Certificate)\n\t}\n\tm.certTokens[name] = cert\n\tm.cachePut(ctx, certKey{domain: name, isToken: true}, cert)\n}\n\n// deleteCertToken removes the token certificate with the specified name\n// from both m.certTokens map and m.Cache.\nfunc (m *Manager) deleteCertToken(name string) {\n\tm.challengeMu.Lock()\n\tdefer m.challengeMu.Unlock()\n\tdelete(m.certTokens, name)\n\tif m.Cache != nil {\n\t\tck := certKey{domain: name, isToken: true}\n\t\tm.Cache.Delete(context.Background(), ck.String())\n\t}\n}\n\n// httpToken retrieves an existing http-01 token value from an in-memory map\n// or the optional cache.\nfunc (m *Manager) httpToken(ctx context.Context, tokenPath string) ([]byte, error) {\n\tm.challengeMu.RLock()\n\tdefer m.challengeMu.RUnlock()\n\tif v, ok := m.httpTokens[tokenPath]; ok {\n\t\treturn v, nil\n\t}\n\tif m.Cache == nil {\n\t\treturn nil, fmt.Errorf(\"acme/autocert: no token at %q\", tokenPath)\n\t}\n\treturn m.Cache.Get(ctx, httpTokenCacheKey(tokenPath))\n}\n\n// putHTTPToken stores an http-01 token value using tokenPath as key\n// in both in-memory map and the optional Cache.\n//\n// It ignores any error returned from Cache.Put.\nfunc (m *Manager) putHTTPToken(ctx context.Context, tokenPath, val string) {\n\tm.challengeMu.Lock()\n\tdefer m.challengeMu.Unlock()\n\tif m.httpTokens == nil {\n\t\tm.httpTokens = make(map[string][]byte)\n\t}\n\tb := []byte(val)\n\tm.httpTokens[tokenPath] = b\n\tif m.Cache != nil {\n\t\tm.Cache.Put(ctx, httpTokenCacheKey(tokenPath), b)\n\t}\n}\n\n// deleteHTTPToken removes an http-01 token value from both in-memory map\n// and the optional Cache, ignoring any error returned from the latter.\n//\n// If m.Cache is non-nil, it blocks until Cache.Delete returns without a timeout.\nfunc (m *Manager) deleteHTTPToken(tokenPath string) {\n\tm.challengeMu.Lock()\n\tdefer m.challengeMu.Unlock()\n\tdelete(m.httpTokens, tokenPath)\n\tif m.Cache != nil {\n\t\tm.Cache.Delete(context.Background(), httpTokenCacheKey(tokenPath))\n\t}\n}\n\n// httpTokenCacheKey returns a key at which an http-01 token value may be stored\n// in the Manager's optional Cache.\nfunc httpTokenCacheKey(tokenPath string) string {\n\treturn path.Base(tokenPath) + \"+http-01\"\n}\n\n// startRenew starts a cert renewal timer loop, one per domain.\n//\n// The loop is scheduled in two cases:\n// - a cert was fetched from cache for the first time (wasn't in m.state)\n// - a new cert was created by m.createCert\n//\n// The key argument is a certificate private key.\n// The exp argument is the cert expiration time (NotAfter).\nfunc (m *Manager) startRenew(ck certKey, key crypto.Signer, notBefore, notAfter time.Time) {\n\tm.renewalMu.Lock()\n\tdefer m.renewalMu.Unlock()\n\tif m.renewal[ck] != nil {\n\t\t// another goroutine is already on it\n\t\treturn\n\t}\n\tif m.renewal == nil {\n\t\tm.renewal = make(map[certKey]*domainRenewal)\n\t}\n\tdr := &domainRenewal{m: m, ck: ck, key: key}\n\tm.renewal[ck] = dr\n\tdr.start(notBefore, notAfter)\n}\n\n// stopRenew stops all currently running cert renewal timers.\n// The timers are not restarted during the lifetime of the Manager.\nfunc (m *Manager) stopRenew() {\n\tm.renewalMu.Lock()\n\tdefer m.renewalMu.Unlock()\n\tfor name, dr := range m.renewal {\n\t\tdelete(m.renewal, name)\n\t\tdr.stop()\n\t}\n}\n\nfunc (m *Manager) accountKey(ctx context.Context) (crypto.Signer, error) {\n\tconst keyName = \"acme_account+key\"\n\n\t// Previous versions of autocert stored the value under a different key.\n\tconst legacyKeyName = \"acme_account.key\"\n\n\tgenKey := func() (*ecdsa.PrivateKey, error) {\n\t\treturn ecdsa.GenerateKey(elliptic.P256(), rand.Reader)\n\t}\n\n\tif m.Cache == nil {\n\t\treturn genKey()\n\t}\n\n\tdata, err := m.Cache.Get(ctx, keyName)\n\tif err == ErrCacheMiss {\n\t\tdata, err = m.Cache.Get(ctx, legacyKeyName)\n\t}\n\tif err == ErrCacheMiss {\n\t\tkey, err := genKey()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tvar buf bytes.Buffer\n\t\tif err := encodeECDSAKey(&buf, key); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif err := m.Cache.Put(ctx, keyName, buf.Bytes()); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn key, nil\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tpriv, _ := pem.Decode(data)\n\tif priv == nil || !strings.Contains(priv.Type, \"PRIVATE\") {\n\t\treturn nil, errors.New(\"acme/autocert: invalid account key found in cache\")\n\t}\n\treturn parsePrivateKey(priv.Bytes)\n}\n\nfunc (m *Manager) acmeClient(ctx context.Context) (*acme.Client, error) {\n\tm.clientMu.Lock()\n\tdefer m.clientMu.Unlock()\n\tif m.client != nil {\n\t\treturn m.client, nil\n\t}\n\n\tclient := m.Client\n\tif client == nil {\n\t\tclient = &acme.Client{DirectoryURL: DefaultACMEDirectory}\n\t}\n\tif client.Key == nil {\n\t\tvar err error\n\t\tclient.Key, err = m.accountKey(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif client.UserAgent == \"\" {\n\t\tclient.UserAgent = \"autocert\"\n\t}\n\tvar contact []string\n\tif m.Email != \"\" {\n\t\tcontact = []string{\"mailto:\" + m.Email}\n\t}\n\ta := &acme.Account{Contact: contact, ExternalAccountBinding: m.ExternalAccountBinding}\n\t_, err := client.Register(ctx, a, m.Prompt)\n\tif err == nil || isAccountAlreadyExist(err) {\n\t\tm.client = client\n\t\terr = nil\n\t}\n\treturn m.client, err\n}\n\n// isAccountAlreadyExist reports whether the err, as returned from acme.Client.Register,\n// indicates the account has already been registered.\nfunc isAccountAlreadyExist(err error) bool {\n\tif err == acme.ErrAccountAlreadyExists {\n\t\treturn true\n\t}\n\tae, ok := err.(*acme.Error)\n\treturn ok && ae.StatusCode == http.StatusConflict\n}\n\nfunc (m *Manager) hostPolicy() HostPolicy {\n\tif m.HostPolicy != nil {\n\t\treturn m.HostPolicy\n\t}\n\treturn defaultHostPolicy\n}\n\nfunc (m *Manager) now() time.Time {\n\tif m.nowFunc != nil {\n\t\treturn m.nowFunc()\n\t}\n\treturn time.Now()\n}\n\n// certState is ready when its mutex is unlocked for reading.\ntype certState struct {\n\tsync.RWMutex\n\tlocked bool              // locked for read/write\n\tkey    crypto.Signer     // private key for cert\n\tcert   [][]byte          // DER encoding\n\tleaf   *x509.Certificate // parsed cert[0]; always non-nil if cert != nil\n}\n\n// tlscert creates a tls.Certificate from s.key and s.cert.\n// Callers should wrap it in s.RLock() and s.RUnlock().\nfunc (s *certState) tlscert() (*tls.Certificate, error) {\n\tif s.key == nil {\n\t\treturn nil, errors.New(\"acme/autocert: missing signer\")\n\t}\n\tif len(s.cert) == 0 {\n\t\treturn nil, errors.New(\"acme/autocert: missing certificate\")\n\t}\n\treturn &tls.Certificate{\n\t\tPrivateKey:  s.key,\n\t\tCertificate: s.cert,\n\t\tLeaf:        s.leaf,\n\t}, nil\n}\n\n// certRequest generates a CSR for the given common name.\nfunc certRequest(key crypto.Signer, name string, ext []pkix.Extension) ([]byte, error) {\n\treq := &x509.CertificateRequest{\n\t\tSubject:         pkix.Name{CommonName: name},\n\t\tDNSNames:        []string{name},\n\t\tExtraExtensions: ext,\n\t}\n\treturn x509.CreateCertificateRequest(rand.Reader, req, key)\n}\n\n// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates\n// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys.\n// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.\n//\n// Inspired by parsePrivateKey in crypto/tls/tls.go.\nfunc parsePrivateKey(der []byte) (crypto.Signer, error) {\n\tif key, err := x509.ParsePKCS1PrivateKey(der); err == nil {\n\t\treturn key, nil\n\t}\n\tif key, err := x509.ParsePKCS8PrivateKey(der); err == nil {\n\t\tswitch key := key.(type) {\n\t\tcase *rsa.PrivateKey:\n\t\t\treturn key, nil\n\t\tcase *ecdsa.PrivateKey:\n\t\t\treturn key, nil\n\t\tdefault:\n\t\t\treturn nil, errors.New(\"acme/autocert: unknown private key type in PKCS#8 wrapping\")\n\t\t}\n\t}\n\tif key, err := x509.ParseECPrivateKey(der); err == nil {\n\t\treturn key, nil\n\t}\n\n\treturn nil, errors.New(\"acme/autocert: failed to parse private key\")\n}\n\n// validCert parses a cert chain provided as der argument and verifies the leaf and der[0]\n// correspond to the private key, the domain and key type match, and expiration dates\n// are valid. It doesn't do any revocation checking.\n//\n// The returned value is the verified leaf cert.\nfunc validCert(ck certKey, der [][]byte, key crypto.Signer, now time.Time) (leaf *x509.Certificate, err error) {\n\t// parse public part(s)\n\tvar n int\n\tfor _, b := range der {\n\t\tn += len(b)\n\t}\n\tpub := make([]byte, n)\n\tn = 0\n\tfor _, b := range der {\n\t\tn += copy(pub[n:], b)\n\t}\n\tx509Cert, err := x509.ParseCertificates(pub)\n\tif err != nil || len(x509Cert) == 0 {\n\t\treturn nil, errors.New(\"acme/autocert: no public key found\")\n\t}\n\t// verify the leaf is not expired and matches the domain name\n\tleaf = x509Cert[0]\n\tif now.Before(leaf.NotBefore) {\n\t\treturn nil, errors.New(\"acme/autocert: certificate is not valid yet\")\n\t}\n\tif now.After(leaf.NotAfter) {\n\t\treturn nil, errors.New(\"acme/autocert: expired certificate\")\n\t}\n\tif err := leaf.VerifyHostname(ck.domain); err != nil {\n\t\treturn nil, err\n\t}\n\t// renew certificates revoked by Let's Encrypt in January 2022\n\tif isRevokedLetsEncrypt(leaf) {\n\t\treturn nil, errors.New(\"acme/autocert: certificate was probably revoked by Let's Encrypt\")\n\t}\n\t// ensure the leaf corresponds to the private key and matches the certKey type\n\tswitch pub := leaf.PublicKey.(type) {\n\tcase *rsa.PublicKey:\n\t\tprv, ok := key.(*rsa.PrivateKey)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"acme/autocert: private key type does not match public key type\")\n\t\t}\n\t\tif pub.N.Cmp(prv.N) != 0 {\n\t\t\treturn nil, errors.New(\"acme/autocert: private key does not match public key\")\n\t\t}\n\t\tif !ck.isRSA && !ck.isToken {\n\t\t\treturn nil, errors.New(\"acme/autocert: key type does not match expected value\")\n\t\t}\n\tcase *ecdsa.PublicKey:\n\t\tprv, ok := key.(*ecdsa.PrivateKey)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"acme/autocert: private key type does not match public key type\")\n\t\t}\n\t\tif pub.X.Cmp(prv.X) != 0 || pub.Y.Cmp(prv.Y) != 0 {\n\t\t\treturn nil, errors.New(\"acme/autocert: private key does not match public key\")\n\t\t}\n\t\tif ck.isRSA && !ck.isToken {\n\t\t\treturn nil, errors.New(\"acme/autocert: key type does not match expected value\")\n\t\t}\n\tdefault:\n\t\treturn nil, errors.New(\"acme/autocert: unknown public key algorithm\")\n\t}\n\treturn leaf, nil\n}\n\n// https://community.letsencrypt.org/t/2022-01-25-issue-with-tls-alpn-01-validation-method/170450\nvar letsEncryptFixDeployTime = time.Date(2022, time.January, 26, 00, 48, 0, 0, time.UTC)\n\n// isRevokedLetsEncrypt returns whether the certificate is likely to be part of\n// a batch of certificates revoked by Let's Encrypt in January 2022. This check\n// can be safely removed from May 2022.\nfunc isRevokedLetsEncrypt(cert *x509.Certificate) bool {\n\tO := cert.Issuer.Organization\n\treturn len(O) == 1 && O[0] == \"Let's Encrypt\" &&\n\t\tcert.NotBefore.Before(letsEncryptFixDeployTime)\n}\n\ntype lockedMathRand struct {\n\tsync.Mutex\n\trnd *mathrand.Rand\n}\n\nfunc (r *lockedMathRand) int63n(max int64) int64 {\n\tr.Lock()\n\tn := r.rnd.Int63n(max)\n\tr.Unlock()\n\treturn n\n}\n\n// For easier testing.\nvar (\n\t// Called when a state is removed.\n\ttestDidRemoveState = func(certKey) {}\n)\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/autocert/cache.go",
    "content": "// Copyright 2016 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 autocert\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n)\n\n// ErrCacheMiss is returned when a certificate is not found in cache.\nvar ErrCacheMiss = errors.New(\"acme/autocert: certificate cache miss\")\n\n// Cache is used by Manager to store and retrieve previously obtained certificates\n// and other account data as opaque blobs.\n//\n// Cache implementations should not rely on the key naming pattern. Keys can\n// include any printable ASCII characters, except the following: \\/:*?\"<>|\ntype Cache interface {\n\t// Get returns a certificate data for the specified key.\n\t// If there's no such key, Get returns ErrCacheMiss.\n\tGet(ctx context.Context, key string) ([]byte, error)\n\n\t// Put stores the data in the cache under the specified key.\n\t// Underlying implementations may use any data storage format,\n\t// as long as the reverse operation, Get, results in the original data.\n\tPut(ctx context.Context, key string, data []byte) error\n\n\t// Delete removes a certificate data from the cache under the specified key.\n\t// If there's no such key in the cache, Delete returns nil.\n\tDelete(ctx context.Context, key string) error\n}\n\n// DirCache implements Cache using a directory on the local filesystem.\n// If the directory does not exist, it will be created with 0700 permissions.\ntype DirCache string\n\n// Get reads a certificate data from the specified file name.\nfunc (d DirCache) Get(ctx context.Context, name string) ([]byte, error) {\n\tname = filepath.Join(string(d), filepath.Clean(\"/\"+name))\n\tvar (\n\t\tdata []byte\n\t\terr  error\n\t\tdone = make(chan struct{})\n\t)\n\tgo func() {\n\t\tdata, err = os.ReadFile(name)\n\t\tclose(done)\n\t}()\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn nil, ctx.Err()\n\tcase <-done:\n\t}\n\tif os.IsNotExist(err) {\n\t\treturn nil, ErrCacheMiss\n\t}\n\treturn data, err\n}\n\n// Put writes the certificate data to the specified file name.\n// The file will be created with 0600 permissions.\nfunc (d DirCache) Put(ctx context.Context, name string, data []byte) error {\n\tif err := os.MkdirAll(string(d), 0700); err != nil {\n\t\treturn err\n\t}\n\n\tdone := make(chan struct{})\n\tvar err error\n\tgo func() {\n\t\tdefer close(done)\n\t\tvar tmp string\n\t\tif tmp, err = d.writeTempFile(name, data); err != nil {\n\t\t\treturn\n\t\t}\n\t\tdefer os.Remove(tmp)\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\t// Don't overwrite the file if the context was canceled.\n\t\tdefault:\n\t\t\tnewName := filepath.Join(string(d), filepath.Clean(\"/\"+name))\n\t\t\terr = os.Rename(tmp, newName)\n\t\t}\n\t}()\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-done:\n\t}\n\treturn err\n}\n\n// Delete removes the specified file name.\nfunc (d DirCache) Delete(ctx context.Context, name string) error {\n\tname = filepath.Join(string(d), filepath.Clean(\"/\"+name))\n\tvar (\n\t\terr  error\n\t\tdone = make(chan struct{})\n\t)\n\tgo func() {\n\t\terr = os.Remove(name)\n\t\tclose(done)\n\t}()\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-done:\n\t}\n\tif err != nil && !os.IsNotExist(err) {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// writeTempFile writes b to a temporary file, closes the file and returns its path.\nfunc (d DirCache) writeTempFile(prefix string, b []byte) (name string, reterr error) {\n\t// TempFile uses 0600 permissions\n\tf, err := os.CreateTemp(string(d), prefix)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer func() {\n\t\tif reterr != nil {\n\t\t\tos.Remove(f.Name())\n\t\t}\n\t}()\n\tif _, err := f.Write(b); err != nil {\n\t\tf.Close()\n\t\treturn \"\", err\n\t}\n\treturn f.Name(), f.Close()\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/autocert/listener.go",
    "content": "// Copyright 2017 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 autocert\n\nimport (\n\t\"crypto/tls\"\n\t\"log\"\n\t\"net\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"time\"\n)\n\n// NewListener returns a net.Listener that listens on the standard TLS\n// port (443) on all interfaces and returns *tls.Conn connections with\n// LetsEncrypt certificates for the provided domain or domains.\n//\n// It enables one-line HTTPS servers:\n//\n//\tlog.Fatal(http.Serve(autocert.NewListener(\"example.com\"), handler))\n//\n// NewListener is a convenience function for a common configuration.\n// More complex or custom configurations can use the autocert.Manager\n// type instead.\n//\n// Use of this function implies acceptance of the LetsEncrypt Terms of\n// Service. If domains is not empty, the provided domains are passed\n// to HostWhitelist. If domains is empty, the listener will do\n// LetsEncrypt challenges for any requested domain, which is not\n// recommended.\n//\n// Certificates are cached in a \"golang-autocert\" directory under an\n// operating system-specific cache or temp directory. This may not\n// be suitable for servers spanning multiple machines.\n//\n// The returned listener uses a *tls.Config that enables HTTP/2, and\n// should only be used with servers that support HTTP/2.\n//\n// The returned Listener also enables TCP keep-alives on the accepted\n// connections. The returned *tls.Conn are returned before their TLS\n// handshake has completed.\nfunc NewListener(domains ...string) net.Listener {\n\tm := &Manager{\n\t\tPrompt: AcceptTOS,\n\t}\n\tif len(domains) > 0 {\n\t\tm.HostPolicy = HostWhitelist(domains...)\n\t}\n\tdir := cacheDir()\n\tif err := os.MkdirAll(dir, 0700); err != nil {\n\t\tlog.Printf(\"warning: autocert.NewListener not using a cache: %v\", err)\n\t} else {\n\t\tm.Cache = DirCache(dir)\n\t}\n\treturn m.Listener()\n}\n\n// Listener listens on the standard TLS port (443) on all interfaces\n// and returns a net.Listener returning *tls.Conn connections.\n//\n// The returned listener uses a *tls.Config that enables HTTP/2, and\n// should only be used with servers that support HTTP/2.\n//\n// The returned Listener also enables TCP keep-alives on the accepted\n// connections. The returned *tls.Conn are returned before their TLS\n// handshake has completed.\n//\n// Unlike NewListener, it is the caller's responsibility to initialize\n// the Manager m's Prompt, Cache, HostPolicy, and other desired options.\nfunc (m *Manager) Listener() net.Listener {\n\tln := &listener{\n\t\tconf: m.TLSConfig(),\n\t}\n\tln.tcpListener, ln.tcpListenErr = net.Listen(\"tcp\", \":443\")\n\treturn ln\n}\n\ntype listener struct {\n\tconf *tls.Config\n\n\ttcpListener  net.Listener\n\ttcpListenErr error\n}\n\nfunc (ln *listener) Accept() (net.Conn, error) {\n\tif ln.tcpListenErr != nil {\n\t\treturn nil, ln.tcpListenErr\n\t}\n\tconn, err := ln.tcpListener.Accept()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttcpConn := conn.(*net.TCPConn)\n\n\t// Because Listener is a convenience function, help out with\n\t// this too.  This is not possible for the caller to set once\n\t// we return a *tcp.Conn wrapping an inaccessible net.Conn.\n\t// If callers don't want this, they can do things the manual\n\t// way and tweak as needed. But this is what net/http does\n\t// itself, so copy that. If net/http changes, we can change\n\t// here too.\n\ttcpConn.SetKeepAlive(true)\n\ttcpConn.SetKeepAlivePeriod(3 * time.Minute)\n\n\treturn tls.Server(tcpConn, ln.conf), nil\n}\n\nfunc (ln *listener) Addr() net.Addr {\n\tif ln.tcpListener != nil {\n\t\treturn ln.tcpListener.Addr()\n\t}\n\t// net.Listen failed. Return something non-nil in case callers\n\t// call Addr before Accept:\n\treturn &net.TCPAddr{IP: net.IP{0, 0, 0, 0}, Port: 443}\n}\n\nfunc (ln *listener) Close() error {\n\tif ln.tcpListenErr != nil {\n\t\treturn ln.tcpListenErr\n\t}\n\treturn ln.tcpListener.Close()\n}\n\nfunc cacheDir() string {\n\tconst base = \"golang-autocert\"\n\tcache, err := os.UserCacheDir()\n\tif err != nil {\n\t\t// Fall back to the root directory.\n\t\tcache = \"/.cache\"\n\t}\n\n\treturn filepath.Join(cache, base)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/autocert/renewal.go",
    "content": "// Copyright 2016 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 autocert\n\nimport (\n\t\"context\"\n\t\"crypto\"\n\t\"sync\"\n\t\"time\"\n)\n\n// domainRenewal tracks the state used by the periodic timers\n// renewing a single domain's cert.\ntype domainRenewal struct {\n\tm   *Manager\n\tck  certKey\n\tkey crypto.Signer\n\n\ttimerMu    sync.Mutex\n\ttimer      *time.Timer\n\ttimerClose chan struct{} // if non-nil, renew closes this channel (and nils out the timer fields) instead of running\n}\n\n// start starts a cert renewal timer at the time\n// defined by the certificate expiration time exp.\n//\n// If the timer is already started, calling start is a noop.\nfunc (dr *domainRenewal) start(notBefore, notAfter time.Time) {\n\tdr.timerMu.Lock()\n\tdefer dr.timerMu.Unlock()\n\tif dr.timer != nil {\n\t\treturn\n\t}\n\tdr.timer = time.AfterFunc(dr.next(notBefore, notAfter), dr.renew)\n}\n\n// stop stops the cert renewal timer and waits for any in-flight calls to renew\n// to complete. If the timer is already stopped, calling stop is a noop.\nfunc (dr *domainRenewal) stop() {\n\tdr.timerMu.Lock()\n\tdefer dr.timerMu.Unlock()\n\tfor {\n\t\tif dr.timer == nil {\n\t\t\treturn\n\t\t}\n\t\tif dr.timer.Stop() {\n\t\t\tdr.timer = nil\n\t\t\treturn\n\t\t} else {\n\t\t\t// dr.timer fired, and we acquired dr.timerMu before the renew callback did.\n\t\t\t// (We know this because otherwise the renew callback would have reset dr.timer!)\n\t\t\ttimerClose := make(chan struct{})\n\t\t\tdr.timerClose = timerClose\n\t\t\tdr.timerMu.Unlock()\n\t\t\t<-timerClose\n\t\t\tdr.timerMu.Lock()\n\t\t}\n\t}\n}\n\n// renew is called periodically by a timer.\n// The first renew call is kicked off by dr.start.\nfunc (dr *domainRenewal) renew() {\n\tdr.timerMu.Lock()\n\tdefer dr.timerMu.Unlock()\n\tif dr.timerClose != nil {\n\t\tclose(dr.timerClose)\n\t\tdr.timer, dr.timerClose = nil, nil\n\t\treturn\n\t}\n\n\tctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)\n\tdefer cancel()\n\t// TODO: rotate dr.key at some point?\n\tnext, err := dr.do(ctx)\n\tif err != nil {\n\t\tnext = time.Hour / 2\n\t\tnext += time.Duration(pseudoRand.int63n(int64(next)))\n\t}\n\ttestDidRenewLoop(next, err)\n\tdr.timer = time.AfterFunc(next, dr.renew)\n}\n\n// updateState locks and replaces the relevant Manager.state item with the given\n// state. It additionally updates dr.key with the given state's key.\nfunc (dr *domainRenewal) updateState(state *certState) {\n\tdr.m.stateMu.Lock()\n\tdefer dr.m.stateMu.Unlock()\n\tdr.key = state.key\n\tdr.m.state[dr.ck] = state\n}\n\n// do is similar to Manager.createCert but it doesn't lock a Manager.state item.\n// Instead, it requests a new certificate independently and, upon success,\n// replaces dr.m.state item with a new one and updates cache for the given domain.\n//\n// It may lock and update the Manager.state if the expiration date of the currently\n// cached cert is far enough in the future.\n//\n// The returned value is a time interval after which the renewal should occur again.\nfunc (dr *domainRenewal) do(ctx context.Context) (time.Duration, error) {\n\t// a race is likely unavoidable in a distributed environment\n\t// but we try nonetheless\n\tif tlscert, err := dr.m.cacheGet(ctx, dr.ck); err == nil {\n\t\tnext := dr.next(tlscert.Leaf.NotBefore, tlscert.Leaf.NotAfter)\n\t\tif next > 0 {\n\t\t\tsigner, ok := tlscert.PrivateKey.(crypto.Signer)\n\t\t\tif ok {\n\t\t\t\tstate := &certState{\n\t\t\t\t\tkey:  signer,\n\t\t\t\t\tcert: tlscert.Certificate,\n\t\t\t\t\tleaf: tlscert.Leaf,\n\t\t\t\t}\n\t\t\t\tdr.updateState(state)\n\t\t\t\treturn next, nil\n\t\t\t}\n\t\t}\n\t}\n\n\tder, leaf, err := dr.m.authorizedCert(ctx, dr.key, dr.ck)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tstate := &certState{\n\t\tkey:  dr.key,\n\t\tcert: der,\n\t\tleaf: leaf,\n\t}\n\ttlscert, err := state.tlscert()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif err := dr.m.cachePut(ctx, dr.ck, tlscert); err != nil {\n\t\treturn 0, err\n\t}\n\tdr.updateState(state)\n\treturn dr.next(leaf.NotBefore, leaf.NotAfter), nil\n}\n\n// next returns the wait time before the next renewal should start.\n// If manager.RenewBefore is set, it uses that capped at 30 days,\n// otherwise it uses a default of 1/3 of the cert lifetime.\n// It builds in a jitter of 10% of the renew threshold, capped at 1 hour.\nfunc (dr *domainRenewal) next(notBefore, notAfter time.Time) time.Duration {\n\tthreshold := min(notAfter.Sub(notBefore)/3, 30*24*time.Hour)\n\tif dr.m.RenewBefore > 0 {\n\t\tthreshold = min(dr.m.RenewBefore, 30*24*time.Hour)\n\t}\n\tmaxJitter := min(threshold/10, time.Hour)\n\tjitter := pseudoRand.int63n(int64(maxJitter))\n\trenewAt := notAfter.Add(-(threshold - time.Duration(jitter)))\n\trenewWait := renewAt.Sub(dr.m.now())\n\treturn max(0, renewWait)\n}\n\nvar testDidRenewLoop = func(next time.Duration, err error) {}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/http.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\npackage acme\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"crypto\"\n\t\"crypto/rand\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"math/big\"\n\t\"net/http\"\n\t\"runtime/debug\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n)\n\n// retryTimer encapsulates common logic for retrying unsuccessful requests.\n// It is not safe for concurrent use.\ntype retryTimer struct {\n\t// backoffFn provides backoff delay sequence for retries.\n\t// See Client.RetryBackoff doc comment.\n\tbackoffFn func(n int, r *http.Request, res *http.Response) time.Duration\n\t// n is the current retry attempt.\n\tn int\n}\n\nfunc (t *retryTimer) inc() {\n\tt.n++\n}\n\n// backoff pauses the current goroutine as described in Client.RetryBackoff.\nfunc (t *retryTimer) backoff(ctx context.Context, r *http.Request, res *http.Response) error {\n\td := t.backoffFn(t.n, r, res)\n\tif d <= 0 {\n\t\treturn fmt.Errorf(\"acme: no more retries for %s; tried %d time(s)\", r.URL, t.n)\n\t}\n\twakeup := time.NewTimer(d)\n\tdefer wakeup.Stop()\n\tselect {\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-wakeup.C:\n\t\treturn nil\n\t}\n}\n\nfunc (c *Client) retryTimer() *retryTimer {\n\tf := c.RetryBackoff\n\tif f == nil {\n\t\tf = defaultBackoff\n\t}\n\treturn &retryTimer{backoffFn: f}\n}\n\n// defaultBackoff provides default Client.RetryBackoff implementation\n// using a truncated exponential backoff algorithm,\n// as described in Client.RetryBackoff.\n//\n// The n argument is always bounded between 1 and 30.\n// The returned value is always greater than 0.\nfunc defaultBackoff(n int, r *http.Request, res *http.Response) time.Duration {\n\tconst maxVal = 10 * time.Second\n\tvar jitter time.Duration\n\tif x, err := rand.Int(rand.Reader, big.NewInt(1000)); err == nil {\n\t\t// Set the minimum to 1ms to avoid a case where\n\t\t// an invalid Retry-After value is parsed into 0 below,\n\t\t// resulting in the 0 returned value which would unintentionally\n\t\t// stop the retries.\n\t\tjitter = (1 + time.Duration(x.Int64())) * time.Millisecond\n\t}\n\tif v, ok := res.Header[\"Retry-After\"]; ok {\n\t\treturn retryAfter(v[0]) + jitter\n\t}\n\n\tif n < 1 {\n\t\tn = 1\n\t}\n\tif n > 30 {\n\t\tn = 30\n\t}\n\td := time.Duration(1<<uint(n-1))*time.Second + jitter\n\treturn min(d, maxVal)\n}\n\n// retryAfter parses a Retry-After HTTP header value,\n// trying to convert v into an int (seconds) or use http.ParseTime otherwise.\n// It returns zero value if v cannot be parsed.\nfunc retryAfter(v string) time.Duration {\n\tif i, err := strconv.Atoi(v); err == nil {\n\t\treturn time.Duration(i) * time.Second\n\t}\n\tt, err := http.ParseTime(v)\n\tif err != nil {\n\t\treturn 0\n\t}\n\treturn t.Sub(timeNow())\n}\n\n// resOkay is a function that reports whether the provided response is okay.\n// It is expected to keep the response body unread.\ntype resOkay func(*http.Response) bool\n\n// wantStatus returns a function which reports whether the code\n// matches the status code of a response.\nfunc wantStatus(codes ...int) resOkay {\n\treturn func(res *http.Response) bool {\n\t\tfor _, code := range codes {\n\t\t\tif code == res.StatusCode {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n}\n\n// get issues an unsigned GET request to the specified URL.\n// It returns a non-error value only when ok reports true.\n//\n// get retries unsuccessful attempts according to c.RetryBackoff\n// until the context is done or a non-retriable error is received.\nfunc (c *Client) get(ctx context.Context, url string, ok resOkay) (*http.Response, error) {\n\tretry := c.retryTimer()\n\tfor {\n\t\treq, err := http.NewRequestWithContext(ctx, \"GET\", url, nil)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tres, err := c.doNoRetry(ctx, req)\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\treturn nil, err\n\t\tcase ok(res):\n\t\t\treturn res, nil\n\t\tcase isRetriable(res.StatusCode):\n\t\t\tretry.inc()\n\t\t\tresErr := responseError(res)\n\t\t\tres.Body.Close()\n\t\t\t// Ignore the error value from retry.backoff\n\t\t\t// and return the one from last retry, as received from the CA.\n\t\t\tif retry.backoff(ctx, req, res) != nil {\n\t\t\t\treturn nil, resErr\n\t\t\t}\n\t\tdefault:\n\t\t\tdefer res.Body.Close()\n\t\t\treturn nil, responseError(res)\n\t\t}\n\t}\n}\n\n// postAsGet is POST-as-GET, a replacement for GET in RFC 8555\n// as described in https://tools.ietf.org/html/rfc8555#section-6.3.\n// It makes a POST request in KID form with zero JWS payload.\n// See nopayload doc comments in jws.go.\nfunc (c *Client) postAsGet(ctx context.Context, url string, ok resOkay) (*http.Response, error) {\n\treturn c.post(ctx, nil, url, noPayload, ok)\n}\n\n// post issues a signed POST request in JWS format using the provided key\n// to the specified URL. If key is nil, c.Key is used instead.\n// It returns a non-error value only when ok reports true.\n//\n// post retries unsuccessful attempts according to c.RetryBackoff\n// until the context is done or a non-retriable error is received.\n// It uses postNoRetry to make individual requests.\nfunc (c *Client) post(ctx context.Context, key crypto.Signer, url string, body interface{}, ok resOkay) (*http.Response, error) {\n\tretry := c.retryTimer()\n\tfor {\n\t\tres, req, err := c.postNoRetry(ctx, key, url, body)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif ok(res) {\n\t\t\treturn res, nil\n\t\t}\n\t\tresErr := responseError(res)\n\t\tres.Body.Close()\n\t\tswitch {\n\t\t// Check for bad nonce before isRetriable because it may have been returned\n\t\t// with an unretriable response code such as 400 Bad Request.\n\t\tcase isBadNonce(resErr):\n\t\t\t// Consider any previously stored nonce values to be invalid.\n\t\t\tc.clearNonces()\n\t\tcase !isRetriable(res.StatusCode):\n\t\t\treturn nil, resErr\n\t\t}\n\t\tretry.inc()\n\t\t// Ignore the error value from retry.backoff\n\t\t// and return the one from last retry, as received from the CA.\n\t\tif err := retry.backoff(ctx, req, res); err != nil {\n\t\t\treturn nil, resErr\n\t\t}\n\t}\n}\n\n// postNoRetry signs the body with the given key and POSTs it to the provided url.\n// It is used by c.post to retry unsuccessful attempts.\n// The body argument must be JSON-serializable.\n//\n// If key argument is nil, c.Key is used to sign the request.\n// If key argument is nil and c.accountKID returns a non-zero keyID,\n// the request is sent in KID form. Otherwise, JWK form is used.\n//\n// In practice, when interfacing with RFC-compliant CAs most requests are sent in KID form\n// and JWK is used only when KID is unavailable: new account endpoint and certificate\n// revocation requests authenticated by a cert key.\n// See jwsEncodeJSON for other details.\nfunc (c *Client) postNoRetry(ctx context.Context, key crypto.Signer, url string, body interface{}) (*http.Response, *http.Request, error) {\n\tkid := noKeyID\n\tif key == nil {\n\t\tif c.Key == nil {\n\t\t\treturn nil, nil, errors.New(\"acme: Client.Key must be populated to make POST requests\")\n\t\t}\n\t\tkey = c.Key\n\t\tkid = c.accountKID(ctx)\n\t}\n\tnonce, err := c.popNonce(ctx, url)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tb, err := jwsEncodeJSON(body, key, kid, nonce, url)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treq, err := http.NewRequestWithContext(ctx, \"POST\", url, bytes.NewReader(b))\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/jose+json\")\n\tres, err := c.doNoRetry(ctx, req)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tc.addNonce(res.Header)\n\treturn res, req, nil\n}\n\n// doNoRetry issues a request req, replacing its context (if any) with ctx.\nfunc (c *Client) doNoRetry(ctx context.Context, req *http.Request) (*http.Response, error) {\n\treq.Header.Set(\"User-Agent\", c.userAgent())\n\tres, err := c.httpClient().Do(req.WithContext(ctx))\n\tif err != nil {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\t// Prefer the unadorned context error.\n\t\t\t// (The acme package had tests assuming this, previously from ctxhttp's\n\t\t\t// behavior, predating net/http supporting contexts natively)\n\t\t\t// TODO(bradfitz): reconsider this in the future. But for now this\n\t\t\t// requires no test updates.\n\t\t\treturn nil, ctx.Err()\n\t\tdefault:\n\t\t\treturn nil, err\n\t\t}\n\t}\n\treturn res, nil\n}\n\nfunc (c *Client) httpClient() *http.Client {\n\tif c.HTTPClient != nil {\n\t\treturn c.HTTPClient\n\t}\n\treturn http.DefaultClient\n}\n\n// packageVersion is the version of the module that contains this package, for\n// sending as part of the User-Agent header.\nvar packageVersion string\n\nfunc init() {\n\t// Set packageVersion if the binary was built in modules mode and x/crypto\n\t// was not replaced with a different module.\n\tinfo, ok := debug.ReadBuildInfo()\n\tif !ok {\n\t\treturn\n\t}\n\tfor _, m := range info.Deps {\n\t\tif m.Path != \"golang.org/x/crypto\" {\n\t\t\tcontinue\n\t\t}\n\t\tif m.Replace == nil {\n\t\t\tpackageVersion = m.Version\n\t\t}\n\t\tbreak\n\t}\n}\n\n// userAgent returns the User-Agent header value. It includes the package name,\n// the module version (if available), and the c.UserAgent value (if set).\nfunc (c *Client) userAgent() string {\n\tua := \"golang.org/x/crypto/acme\"\n\tif packageVersion != \"\" {\n\t\tua += \"@\" + packageVersion\n\t}\n\tif c.UserAgent != \"\" {\n\t\tua = c.UserAgent + \" \" + ua\n\t}\n\treturn ua\n}\n\n// isBadNonce reports whether err is an ACME \"badnonce\" error.\nfunc isBadNonce(err error) bool {\n\t// According to the spec badNonce is urn:ietf:params:acme:error:badNonce.\n\t// However, ACME servers in the wild return their versions of the error.\n\t// See https://tools.ietf.org/html/draft-ietf-acme-acme-02#section-5.4\n\t// and https://github.com/letsencrypt/boulder/blob/0e07eacb/docs/acme-divergences.md#section-66.\n\tae, ok := err.(*Error)\n\treturn ok && strings.HasSuffix(strings.ToLower(ae.ProblemType), \":badnonce\")\n}\n\n// isRetriable reports whether a request can be retried\n// based on the response status code.\n//\n// Note that a \"bad nonce\" error is returned with a non-retriable 400 Bad Request code.\n// Callers should parse the response and check with isBadNonce.\nfunc isRetriable(code int) bool {\n\treturn code <= 399 || code >= 500 || code == http.StatusTooManyRequests\n}\n\n// responseError creates an error of Error type from resp.\nfunc responseError(resp *http.Response) error {\n\t// don't care if ReadAll returns an error:\n\t// json.Unmarshal will fail in that case anyway\n\tb, _ := io.ReadAll(resp.Body)\n\te := &wireError{Status: resp.StatusCode}\n\tif err := json.Unmarshal(b, e); err != nil {\n\t\t// this is not a regular error response:\n\t\t// populate detail with anything we received,\n\t\t// e.Status will already contain HTTP response code value\n\t\te.Detail = string(b)\n\t\tif e.Detail == \"\" {\n\t\t\te.Detail = resp.Status\n\t\t}\n\t}\n\treturn e.error(resp.Header)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/jws.go",
    "content": "// Copyright 2015 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 acme\n\nimport (\n\t\"crypto\"\n\t\"crypto/ecdsa\"\n\t\"crypto/hmac\"\n\t\"crypto/rand\"\n\t\"crypto/rsa\"\n\t\"crypto/sha256\"\n\t_ \"crypto/sha512\" // need for EC keys\n\t\"encoding/asn1\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n)\n\n// KeyID is the account key identity provided by a CA during registration.\ntype KeyID string\n\n// noKeyID indicates that jwsEncodeJSON should compute and use JWK instead of a KID.\n// See jwsEncodeJSON for details.\nconst noKeyID = KeyID(\"\")\n\n// noPayload indicates jwsEncodeJSON will encode zero-length octet string\n// in a JWS request. This is called POST-as-GET in RFC 8555 and is used to make\n// authenticated GET requests via POSTing with an empty payload.\n// See https://tools.ietf.org/html/rfc8555#section-6.3 for more details.\nconst noPayload = \"\"\n\n// noNonce indicates that the nonce should be omitted from the protected header.\n// See jwsEncodeJSON for details.\nconst noNonce = \"\"\n\n// jsonWebSignature can be easily serialized into a JWS following\n// https://tools.ietf.org/html/rfc7515#section-3.2.\ntype jsonWebSignature struct {\n\tProtected string `json:\"protected\"`\n\tPayload   string `json:\"payload\"`\n\tSig       string `json:\"signature\"`\n}\n\n// jwsEncodeJSON signs claimset using provided key and a nonce.\n// The result is serialized in JSON format containing either kid or jwk\n// fields based on the provided KeyID value.\n//\n// The claimset is marshalled using json.Marshal unless it is a string.\n// In which case it is inserted directly into the message.\n//\n// If kid is non-empty, its quoted value is inserted in the protected header\n// as \"kid\" field value. Otherwise, JWK is computed using jwkEncode and inserted\n// as \"jwk\" field value. The \"jwk\" and \"kid\" fields are mutually exclusive.\n//\n// If nonce is non-empty, its quoted value is inserted in the protected header.\n//\n// See https://tools.ietf.org/html/rfc7515#section-7.\nfunc jwsEncodeJSON(claimset interface{}, key crypto.Signer, kid KeyID, nonce, url string) ([]byte, error) {\n\tif key == nil {\n\t\treturn nil, errors.New(\"nil key\")\n\t}\n\talg, sha := jwsHasher(key.Public())\n\tif alg == \"\" || !sha.Available() {\n\t\treturn nil, ErrUnsupportedKey\n\t}\n\theaders := struct {\n\t\tAlg   string          `json:\"alg\"`\n\t\tKID   string          `json:\"kid,omitempty\"`\n\t\tJWK   json.RawMessage `json:\"jwk,omitempty\"`\n\t\tNonce string          `json:\"nonce,omitempty\"`\n\t\tURL   string          `json:\"url\"`\n\t}{\n\t\tAlg:   alg,\n\t\tNonce: nonce,\n\t\tURL:   url,\n\t}\n\tswitch kid {\n\tcase noKeyID:\n\t\tjwk, err := jwkEncode(key.Public())\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\theaders.JWK = json.RawMessage(jwk)\n\tdefault:\n\t\theaders.KID = string(kid)\n\t}\n\tphJSON, err := json.Marshal(headers)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tphead := base64.RawURLEncoding.EncodeToString(phJSON)\n\tvar payload string\n\tif val, ok := claimset.(string); ok {\n\t\tpayload = val\n\t} else {\n\t\tcs, err := json.Marshal(claimset)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpayload = base64.RawURLEncoding.EncodeToString(cs)\n\t}\n\thash := sha.New()\n\thash.Write([]byte(phead + \".\" + payload))\n\tsig, err := jwsSign(key, sha, hash.Sum(nil))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tenc := jsonWebSignature{\n\t\tProtected: phead,\n\t\tPayload:   payload,\n\t\tSig:       base64.RawURLEncoding.EncodeToString(sig),\n\t}\n\treturn json.Marshal(&enc)\n}\n\n// jwsWithMAC creates and signs a JWS using the given key and the HS256\n// algorithm. kid and url are included in the protected header. rawPayload\n// should not be base64-URL-encoded.\nfunc jwsWithMAC(key []byte, kid, url string, rawPayload []byte) (*jsonWebSignature, error) {\n\tif len(key) == 0 {\n\t\treturn nil, errors.New(\"acme: cannot sign JWS with an empty MAC key\")\n\t}\n\theader := struct {\n\t\tAlgorithm string `json:\"alg\"`\n\t\tKID       string `json:\"kid\"`\n\t\tURL       string `json:\"url,omitempty\"`\n\t}{\n\t\t// Only HMAC-SHA256 is supported.\n\t\tAlgorithm: \"HS256\",\n\t\tKID:       kid,\n\t\tURL:       url,\n\t}\n\trawProtected, err := json.Marshal(header)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tprotected := base64.RawURLEncoding.EncodeToString(rawProtected)\n\tpayload := base64.RawURLEncoding.EncodeToString(rawPayload)\n\n\th := hmac.New(sha256.New, key)\n\tif _, err := h.Write([]byte(protected + \".\" + payload)); err != nil {\n\t\treturn nil, err\n\t}\n\tmac := h.Sum(nil)\n\n\treturn &jsonWebSignature{\n\t\tProtected: protected,\n\t\tPayload:   payload,\n\t\tSig:       base64.RawURLEncoding.EncodeToString(mac),\n\t}, nil\n}\n\n// jwkEncode encodes public part of an RSA or ECDSA key into a JWK.\n// The result is also suitable for creating a JWK thumbprint.\n// https://tools.ietf.org/html/rfc7517\nfunc jwkEncode(pub crypto.PublicKey) (string, error) {\n\tswitch pub := pub.(type) {\n\tcase *rsa.PublicKey:\n\t\t// https://tools.ietf.org/html/rfc7518#section-6.3.1\n\t\tn := pub.N\n\t\te := big.NewInt(int64(pub.E))\n\t\t// Field order is important.\n\t\t// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.\n\t\treturn fmt.Sprintf(`{\"e\":\"%s\",\"kty\":\"RSA\",\"n\":\"%s\"}`,\n\t\t\tbase64.RawURLEncoding.EncodeToString(e.Bytes()),\n\t\t\tbase64.RawURLEncoding.EncodeToString(n.Bytes()),\n\t\t), nil\n\tcase *ecdsa.PublicKey:\n\t\t// https://tools.ietf.org/html/rfc7518#section-6.2.1\n\t\tp := pub.Curve.Params()\n\t\tn := p.BitSize / 8\n\t\tif p.BitSize%8 != 0 {\n\t\t\tn++\n\t\t}\n\t\tx := pub.X.Bytes()\n\t\tif n > len(x) {\n\t\t\tx = append(make([]byte, n-len(x)), x...)\n\t\t}\n\t\ty := pub.Y.Bytes()\n\t\tif n > len(y) {\n\t\t\ty = append(make([]byte, n-len(y)), y...)\n\t\t}\n\t\t// Field order is important.\n\t\t// See https://tools.ietf.org/html/rfc7638#section-3.3 for details.\n\t\treturn fmt.Sprintf(`{\"crv\":\"%s\",\"kty\":\"EC\",\"x\":\"%s\",\"y\":\"%s\"}`,\n\t\t\tp.Name,\n\t\t\tbase64.RawURLEncoding.EncodeToString(x),\n\t\t\tbase64.RawURLEncoding.EncodeToString(y),\n\t\t), nil\n\t}\n\treturn \"\", ErrUnsupportedKey\n}\n\n// jwsSign signs the digest using the given key.\n// The hash is unused for ECDSA keys.\nfunc jwsSign(key crypto.Signer, hash crypto.Hash, digest []byte) ([]byte, error) {\n\tswitch pub := key.Public().(type) {\n\tcase *rsa.PublicKey:\n\t\treturn key.Sign(rand.Reader, digest, hash)\n\tcase *ecdsa.PublicKey:\n\t\tsigASN1, err := key.Sign(rand.Reader, digest, hash)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar rs struct{ R, S *big.Int }\n\t\tif _, err := asn1.Unmarshal(sigASN1, &rs); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\trb, sb := rs.R.Bytes(), rs.S.Bytes()\n\t\tsize := pub.Params().BitSize / 8\n\t\tif size%8 > 0 {\n\t\t\tsize++\n\t\t}\n\t\tsig := make([]byte, size*2)\n\t\tcopy(sig[size-len(rb):], rb)\n\t\tcopy(sig[size*2-len(sb):], sb)\n\t\treturn sig, nil\n\t}\n\treturn nil, ErrUnsupportedKey\n}\n\n// jwsHasher indicates suitable JWS algorithm name and a hash function\n// to use for signing a digest with the provided key.\n// It returns (\"\", 0) if the key is not supported.\nfunc jwsHasher(pub crypto.PublicKey) (string, crypto.Hash) {\n\tswitch pub := pub.(type) {\n\tcase *rsa.PublicKey:\n\t\treturn \"RS256\", crypto.SHA256\n\tcase *ecdsa.PublicKey:\n\t\tswitch pub.Params().Name {\n\t\tcase \"P-256\":\n\t\t\treturn \"ES256\", crypto.SHA256\n\t\tcase \"P-384\":\n\t\t\treturn \"ES384\", crypto.SHA384\n\t\tcase \"P-521\":\n\t\t\treturn \"ES512\", crypto.SHA512\n\t\t}\n\t}\n\treturn \"\", 0\n}\n\n// JWKThumbprint creates a JWK thumbprint out of pub\n// as specified in https://tools.ietf.org/html/rfc7638.\nfunc JWKThumbprint(pub crypto.PublicKey) (string, error) {\n\tjwk, err := jwkEncode(pub)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tb := sha256.Sum256([]byte(jwk))\n\treturn base64.RawURLEncoding.EncodeToString(b[:]), nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/rfc8555.go",
    "content": "// Copyright 2019 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 acme\n\nimport (\n\t\"context\"\n\t\"crypto\"\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"encoding/pem\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// DeactivateReg permanently disables an existing account associated with c.Key.\n// A deactivated account can no longer request certificate issuance or access\n// resources related to the account, such as orders or authorizations.\n//\n// It only works with CAs implementing RFC 8555.\nfunc (c *Client) DeactivateReg(ctx context.Context) error {\n\tif _, err := c.Discover(ctx); err != nil { // required by c.accountKID\n\t\treturn err\n\t}\n\turl := string(c.accountKID(ctx))\n\tif url == \"\" {\n\t\treturn ErrNoAccount\n\t}\n\treq := json.RawMessage(`{\"status\": \"deactivated\"}`)\n\tres, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn err\n\t}\n\tres.Body.Close()\n\treturn nil\n}\n\n// registerRFC is equivalent to c.Register but for CAs implementing RFC 8555.\n// It expects c.Discover to have already been called.\nfunc (c *Client) registerRFC(ctx context.Context, acct *Account, prompt func(tosURL string) bool) (*Account, error) {\n\tc.cacheMu.Lock() // guard c.kid access\n\tdefer c.cacheMu.Unlock()\n\n\treq := struct {\n\t\tTermsAgreed            bool              `json:\"termsOfServiceAgreed,omitempty\"`\n\t\tContact                []string          `json:\"contact,omitempty\"`\n\t\tExternalAccountBinding *jsonWebSignature `json:\"externalAccountBinding,omitempty\"`\n\t}{\n\t\tContact: acct.Contact,\n\t}\n\tif c.dir.Terms != \"\" {\n\t\treq.TermsAgreed = prompt(c.dir.Terms)\n\t}\n\n\t// set 'externalAccountBinding' field if requested\n\tif acct.ExternalAccountBinding != nil {\n\t\teabJWS, err := c.encodeExternalAccountBinding(acct.ExternalAccountBinding)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"acme: failed to encode external account binding: %v\", err)\n\t\t}\n\t\treq.ExternalAccountBinding = eabJWS\n\t}\n\n\tres, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(\n\t\thttp.StatusOK,      // account with this key already registered\n\t\thttp.StatusCreated, // new account created\n\t))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer res.Body.Close()\n\ta, err := responseAccount(res)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// Cache Account URL even if we return an error to the caller.\n\t// It is by all means a valid and usable \"kid\" value for future requests.\n\tc.KID = KeyID(a.URI)\n\tif res.StatusCode == http.StatusOK {\n\t\treturn nil, ErrAccountAlreadyExists\n\t}\n\treturn a, nil\n}\n\n// encodeExternalAccountBinding will encode an external account binding stanza\n// as described in https://tools.ietf.org/html/rfc8555#section-7.3.4.\nfunc (c *Client) encodeExternalAccountBinding(eab *ExternalAccountBinding) (*jsonWebSignature, error) {\n\tjwk, err := jwkEncode(c.Key.Public())\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn jwsWithMAC(eab.Key, eab.KID, c.dir.RegURL, []byte(jwk))\n}\n\n// updateRegRFC is equivalent to c.UpdateReg but for CAs implementing RFC 8555.\n// It expects c.Discover to have already been called.\nfunc (c *Client) updateRegRFC(ctx context.Context, a *Account) (*Account, error) {\n\turl := string(c.accountKID(ctx))\n\tif url == \"\" {\n\t\treturn nil, ErrNoAccount\n\t}\n\treq := struct {\n\t\tContact []string `json:\"contact,omitempty\"`\n\t}{\n\t\tContact: a.Contact,\n\t}\n\tres, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\treturn responseAccount(res)\n}\n\n// getRegRFC is equivalent to c.GetReg but for CAs implementing RFC 8555.\n// It expects c.Discover to have already been called.\nfunc (c *Client) getRegRFC(ctx context.Context) (*Account, error) {\n\treq := json.RawMessage(`{\"onlyReturnExisting\": true}`)\n\tres, err := c.post(ctx, c.Key, c.dir.RegURL, req, wantStatus(http.StatusOK))\n\tif e, ok := err.(*Error); ok && e.ProblemType == \"urn:ietf:params:acme:error:accountDoesNotExist\" {\n\t\treturn nil, ErrNoAccount\n\t}\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdefer res.Body.Close()\n\treturn responseAccount(res)\n}\n\nfunc responseAccount(res *http.Response) (*Account, error) {\n\tvar v struct {\n\t\tStatus  string\n\t\tContact []string\n\t\tOrders  string\n\t}\n\tif err := json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: invalid account response: %v\", err)\n\t}\n\treturn &Account{\n\t\tURI:       res.Header.Get(\"Location\"),\n\t\tStatus:    v.Status,\n\t\tContact:   v.Contact,\n\t\tOrdersURL: v.Orders,\n\t}, nil\n}\n\n// accountKeyRollover attempts to perform account key rollover.\n// On success it will change client.Key to the new key.\nfunc (c *Client) accountKeyRollover(ctx context.Context, newKey crypto.Signer) error {\n\tdir, err := c.Discover(ctx) // Also required by c.accountKID\n\tif err != nil {\n\t\treturn err\n\t}\n\tkid := c.accountKID(ctx)\n\tif kid == noKeyID {\n\t\treturn ErrNoAccount\n\t}\n\toldKey, err := jwkEncode(c.Key.Public())\n\tif err != nil {\n\t\treturn err\n\t}\n\tpayload := struct {\n\t\tAccount string          `json:\"account\"`\n\t\tOldKey  json.RawMessage `json:\"oldKey\"`\n\t}{\n\t\tAccount: string(kid),\n\t\tOldKey:  json.RawMessage(oldKey),\n\t}\n\tinner, err := jwsEncodeJSON(payload, newKey, noKeyID, noNonce, dir.KeyChangeURL)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tres, err := c.post(ctx, nil, dir.KeyChangeURL, base64.RawURLEncoding.EncodeToString(inner), wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer res.Body.Close()\n\tc.Key = newKey\n\treturn nil\n}\n\n// AuthorizeOrder initiates the order-based application for certificate issuance,\n// as opposed to pre-authorization in Authorize.\n// It is only supported by CAs implementing RFC 8555.\n//\n// The caller then needs to fetch each authorization with GetAuthorization,\n// identify those with StatusPending status and fulfill a challenge using Accept.\n// Once all authorizations are satisfied, the caller will typically want to poll\n// order status using WaitOrder until it's in StatusReady state.\n// To finalize the order and obtain a certificate, the caller submits a CSR with CreateOrderCert.\nfunc (c *Client) AuthorizeOrder(ctx context.Context, id []AuthzID, opt ...OrderOption) (*Order, error) {\n\tdir, err := c.Discover(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq := struct {\n\t\tIdentifiers []wireAuthzID `json:\"identifiers\"`\n\t\tNotBefore   string        `json:\"notBefore,omitempty\"`\n\t\tNotAfter    string        `json:\"notAfter,omitempty\"`\n\t}{}\n\tfor _, v := range id {\n\t\treq.Identifiers = append(req.Identifiers, wireAuthzID{\n\t\t\tType:  v.Type,\n\t\t\tValue: v.Value,\n\t\t})\n\t}\n\tfor _, o := range opt {\n\t\tswitch o := o.(type) {\n\t\tcase orderNotBeforeOpt:\n\t\t\treq.NotBefore = time.Time(o).Format(time.RFC3339)\n\t\tcase orderNotAfterOpt:\n\t\t\treq.NotAfter = time.Time(o).Format(time.RFC3339)\n\t\tdefault:\n\t\t\t// Package's fault if we let this happen.\n\t\t\tpanic(fmt.Sprintf(\"unsupported order option type %T\", o))\n\t\t}\n\t}\n\n\tres, err := c.post(ctx, nil, dir.OrderURL, req, wantStatus(http.StatusCreated))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\treturn responseOrder(res)\n}\n\n// GetOrder retrieves an order identified by the given URL.\n// For orders created with AuthorizeOrder, the url value is Order.URI.\n//\n// If a caller needs to poll an order until its status is final,\n// see the WaitOrder method.\nfunc (c *Client) GetOrder(ctx context.Context, url string) (*Order, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\n\tres, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\treturn responseOrder(res)\n}\n\n// WaitOrder polls an order from the given URL until it is in one of the final states,\n// StatusReady, StatusValid or StatusInvalid, the CA responded with a non-retryable error\n// or the context is done.\n//\n// It returns a non-nil Order only if its Status is StatusReady or StatusValid.\n// In all other cases WaitOrder returns an error.\n// If the Status is StatusInvalid, the returned error is of type *OrderError.\nfunc (c *Client) WaitOrder(ctx context.Context, url string) (*Order, error) {\n\tif _, err := c.Discover(ctx); err != nil {\n\t\treturn nil, err\n\t}\n\tfor {\n\t\tres, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\to, err := responseOrder(res)\n\t\tres.Body.Close()\n\t\tswitch {\n\t\tcase err != nil:\n\t\t\t// Skip and retry.\n\t\tcase o.Status == StatusInvalid:\n\t\t\treturn nil, &OrderError{OrderURL: o.URI, Status: o.Status, Problem: o.Error}\n\t\tcase o.Status == StatusReady || o.Status == StatusValid:\n\t\t\treturn o, nil\n\t\t}\n\n\t\td := retryAfter(res.Header.Get(\"Retry-After\"))\n\t\tif d == 0 {\n\t\t\t// Default retry-after.\n\t\t\t// Same reasoning as in WaitAuthorization.\n\t\t\td = time.Second\n\t\t}\n\t\tt := time.NewTimer(d)\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\tt.Stop()\n\t\t\treturn nil, ctx.Err()\n\t\tcase <-t.C:\n\t\t\t// Retry.\n\t\t}\n\t}\n}\n\nfunc responseOrder(res *http.Response) (*Order, error) {\n\tvar v struct {\n\t\tStatus         string\n\t\tExpires        time.Time\n\t\tIdentifiers    []wireAuthzID\n\t\tNotBefore      time.Time\n\t\tNotAfter       time.Time\n\t\tError          *wireError\n\t\tAuthorizations []string\n\t\tFinalize       string\n\t\tCertificate    string\n\t}\n\tif err := json.NewDecoder(res.Body).Decode(&v); err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: error reading order: %v\", err)\n\t}\n\to := &Order{\n\t\tURI:         res.Header.Get(\"Location\"),\n\t\tStatus:      v.Status,\n\t\tExpires:     v.Expires,\n\t\tNotBefore:   v.NotBefore,\n\t\tNotAfter:    v.NotAfter,\n\t\tAuthzURLs:   v.Authorizations,\n\t\tFinalizeURL: v.Finalize,\n\t\tCertURL:     v.Certificate,\n\t}\n\tfor _, id := range v.Identifiers {\n\t\to.Identifiers = append(o.Identifiers, AuthzID{Type: id.Type, Value: id.Value})\n\t}\n\tif v.Error != nil {\n\t\to.Error = v.Error.error(nil /* headers */)\n\t}\n\treturn o, nil\n}\n\n// CreateOrderCert submits the CSR (Certificate Signing Request) to a CA at the specified URL.\n// The URL is the FinalizeURL field of an Order created with AuthorizeOrder.\n//\n// If the bundle argument is true, the returned value also contain the CA (issuer)\n// certificate chain. Otherwise, only a leaf certificate is returned.\n// The returned URL can be used to re-fetch the certificate using FetchCert.\n//\n// This method is only supported by CAs implementing RFC 8555. See CreateCert for pre-RFC CAs.\n//\n// CreateOrderCert returns an error if the CA's response is unreasonably large.\n// Callers are encouraged to parse the returned value to ensure the certificate is valid and has the expected features.\nfunc (c *Client) CreateOrderCert(ctx context.Context, url string, csr []byte, bundle bool) (der [][]byte, certURL string, err error) {\n\tif _, err := c.Discover(ctx); err != nil { // required by c.accountKID\n\t\treturn nil, \"\", err\n\t}\n\n\t// RFC describes this as \"finalize order\" request.\n\treq := struct {\n\t\tCSR string `json:\"csr\"`\n\t}{\n\t\tCSR: base64.RawURLEncoding.EncodeToString(csr),\n\t}\n\tres, err := c.post(ctx, nil, url, req, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tdefer res.Body.Close()\n\to, err := responseOrder(res)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\n\t// Wait for CA to issue the cert if they haven't.\n\tif o.Status != StatusValid {\n\t\to, err = c.WaitOrder(ctx, o.URI)\n\t}\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\t// The only acceptable status post finalize and WaitOrder is \"valid\".\n\tif o.Status != StatusValid {\n\t\treturn nil, \"\", &OrderError{OrderURL: o.URI, Status: o.Status, Problem: o.Error}\n\t}\n\tcrt, err := c.fetchCertRFC(ctx, o.CertURL, bundle)\n\treturn crt, o.CertURL, err\n}\n\n// fetchCertRFC downloads issued certificate from the given URL.\n// It expects the CA to respond with PEM-encoded certificate chain.\n//\n// The URL argument is the CertURL field of Order.\nfunc (c *Client) fetchCertRFC(ctx context.Context, url string, bundle bool) ([][]byte, error) {\n\tres, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\n\t// Get all the bytes up to a sane maximum.\n\t// Account very roughly for base64 overhead.\n\tconst max = maxCertChainSize + maxCertChainSize/33\n\tb, err := io.ReadAll(io.LimitReader(res.Body, max+1))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: fetch cert response stream: %v\", err)\n\t}\n\tif len(b) > max {\n\t\treturn nil, errors.New(\"acme: certificate chain is too big\")\n\t}\n\n\t// Decode PEM chain.\n\tvar chain [][]byte\n\tfor {\n\t\tvar p *pem.Block\n\t\tp, b = pem.Decode(b)\n\t\tif p == nil {\n\t\t\tbreak\n\t\t}\n\t\tif p.Type != \"CERTIFICATE\" {\n\t\t\treturn nil, fmt.Errorf(\"acme: invalid PEM cert type %q\", p.Type)\n\t\t}\n\n\t\tchain = append(chain, p.Bytes)\n\t\tif !bundle {\n\t\t\treturn chain, nil\n\t\t}\n\t\tif len(chain) > maxChainLen {\n\t\t\treturn nil, errors.New(\"acme: certificate chain is too long\")\n\t\t}\n\t}\n\tif len(chain) == 0 {\n\t\treturn nil, errors.New(\"acme: certificate chain is empty\")\n\t}\n\treturn chain, nil\n}\n\n// sends a cert revocation request in either JWK form when key is non-nil or KID form otherwise.\nfunc (c *Client) revokeCertRFC(ctx context.Context, key crypto.Signer, cert []byte, reason CRLReasonCode) error {\n\treq := &struct {\n\t\tCert   string `json:\"certificate\"`\n\t\tReason int    `json:\"reason\"`\n\t}{\n\t\tCert:   base64.RawURLEncoding.EncodeToString(cert),\n\t\tReason: int(reason),\n\t}\n\tres, err := c.post(ctx, key, c.dir.RevokeURL, req, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\tif isAlreadyRevoked(err) {\n\t\t\t// Assume it is not an error to revoke an already revoked cert.\n\t\t\treturn nil\n\t\t}\n\t\treturn err\n\t}\n\tdefer res.Body.Close()\n\treturn nil\n}\n\nfunc isAlreadyRevoked(err error) bool {\n\te, ok := err.(*Error)\n\treturn ok && e.ProblemType == \"urn:ietf:params:acme:error:alreadyRevoked\"\n}\n\n// ListCertAlternates retrieves any alternate certificate chain URLs for the\n// given certificate chain URL. These alternate URLs can be passed to FetchCert\n// in order to retrieve the alternate certificate chains.\n//\n// If there are no alternate issuer certificate chains, a nil slice will be\n// returned.\nfunc (c *Client) ListCertAlternates(ctx context.Context, url string) ([]string, error) {\n\tif _, err := c.Discover(ctx); err != nil { // required by c.accountKID\n\t\treturn nil, err\n\t}\n\n\tres, err := c.postAsGet(ctx, url, wantStatus(http.StatusOK))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer res.Body.Close()\n\n\t// We don't need the body but we need to discard it so we don't end up\n\t// preventing keep-alive\n\tif _, err := io.Copy(io.Discard, res.Body); err != nil {\n\t\treturn nil, fmt.Errorf(\"acme: cert alternates response stream: %v\", err)\n\t}\n\talts := linkHeader(res.Header, \"alternate\")\n\treturn alts, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/crypto/acme/types.go",
    "content": "// Copyright 2016 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 acme\n\nimport (\n\t\"crypto\"\n\t\"crypto/x509\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"strings\"\n\t\"time\"\n)\n\n// ACME status values of Account, Order, Authorization and Challenge objects.\n// See https://tools.ietf.org/html/rfc8555#section-7.1.6 for details.\nconst (\n\tStatusDeactivated = \"deactivated\"\n\tStatusExpired     = \"expired\"\n\tStatusInvalid     = \"invalid\"\n\tStatusPending     = \"pending\"\n\tStatusProcessing  = \"processing\"\n\tStatusReady       = \"ready\"\n\tStatusRevoked     = \"revoked\"\n\tStatusUnknown     = \"unknown\"\n\tStatusValid       = \"valid\"\n)\n\n// CRLReasonCode identifies the reason for a certificate revocation.\ntype CRLReasonCode int\n\n// CRL reason codes as defined in RFC 5280.\nconst (\n\tCRLReasonUnspecified          CRLReasonCode = 0\n\tCRLReasonKeyCompromise        CRLReasonCode = 1\n\tCRLReasonCACompromise         CRLReasonCode = 2\n\tCRLReasonAffiliationChanged   CRLReasonCode = 3\n\tCRLReasonSuperseded           CRLReasonCode = 4\n\tCRLReasonCessationOfOperation CRLReasonCode = 5\n\tCRLReasonCertificateHold      CRLReasonCode = 6\n\tCRLReasonRemoveFromCRL        CRLReasonCode = 8\n\tCRLReasonPrivilegeWithdrawn   CRLReasonCode = 9\n\tCRLReasonAACompromise         CRLReasonCode = 10\n)\n\nvar (\n\t// ErrUnsupportedKey is returned when an unsupported key type is encountered.\n\tErrUnsupportedKey = errors.New(\"acme: unknown key type; only RSA and ECDSA are supported\")\n\n\t// ErrAccountAlreadyExists indicates that the Client's key has already been registered\n\t// with the CA. It is returned by Register method.\n\tErrAccountAlreadyExists = errors.New(\"acme: account already exists\")\n\n\t// ErrNoAccount indicates that the Client's key has not been registered with the CA.\n\tErrNoAccount = errors.New(\"acme: account does not exist\")\n\n\t// errPreAuthorizationNotSupported indicates that the server does not\n\t// support pre-authorization of identifiers.\n\terrPreAuthorizationNotSupported = errors.New(\"acme: pre-authorization is not supported\")\n)\n\n// A Subproblem describes an ACME subproblem as reported in an Error.\ntype Subproblem struct {\n\t// Type is a URI reference that identifies the problem type,\n\t// typically in a \"urn:acme:error:xxx\" form.\n\tType string\n\t// Detail is a human-readable explanation specific to this occurrence of the problem.\n\tDetail string\n\t// Instance indicates a URL that the client should direct a human user to visit\n\t// in order for instructions on how to agree to the updated Terms of Service.\n\t// In such an event CA sets StatusCode to 403, Type to\n\t// \"urn:ietf:params:acme:error:userActionRequired\", and adds a Link header with relation\n\t// \"terms-of-service\" containing the latest TOS URL.\n\tInstance string\n\t// Identifier may contain the ACME identifier that the error is for.\n\tIdentifier *AuthzID\n}\n\nfunc (sp Subproblem) String() string {\n\tstr := fmt.Sprintf(\"%s: \", sp.Type)\n\tif sp.Identifier != nil {\n\t\tstr += fmt.Sprintf(\"[%s: %s] \", sp.Identifier.Type, sp.Identifier.Value)\n\t}\n\tstr += sp.Detail\n\treturn str\n}\n\n// Error is an ACME error, defined in Problem Details for HTTP APIs doc\n// http://tools.ietf.org/html/draft-ietf-appsawg-http-problem.\ntype Error struct {\n\t// StatusCode is The HTTP status code generated by the origin server.\n\tStatusCode int\n\t// ProblemType is a URI reference that identifies the problem type,\n\t// typically in a \"urn:acme:error:xxx\" form.\n\tProblemType string\n\t// Detail is a human-readable explanation specific to this occurrence of the problem.\n\tDetail string\n\t// Instance indicates a URL that the client should direct a human user to visit\n\t// in order for instructions on how to agree to the updated Terms of Service.\n\t// In such an event CA sets StatusCode to 403, ProblemType to\n\t// \"urn:ietf:params:acme:error:userActionRequired\" and a Link header with relation\n\t// \"terms-of-service\" containing the latest TOS URL.\n\tInstance string\n\t// Header is the original server error response headers.\n\t// It may be nil.\n\tHeader http.Header\n\t// Subproblems may contain more detailed information about the individual problems\n\t// that caused the error. This field is only sent by RFC 8555 compatible ACME\n\t// servers. Defined in RFC 8555 Section 6.7.1.\n\tSubproblems []Subproblem\n}\n\nfunc (e *Error) Error() string {\n\tstr := fmt.Sprintf(\"%d %s: %s\", e.StatusCode, e.ProblemType, e.Detail)\n\tif len(e.Subproblems) > 0 {\n\t\tstr += fmt.Sprintf(\"; subproblems:\")\n\t\tfor _, sp := range e.Subproblems {\n\t\t\tstr += fmt.Sprintf(\"\\n\\t%s\", sp)\n\t\t}\n\t}\n\treturn str\n}\n\n// AuthorizationError indicates that an authorization for an identifier\n// did not succeed.\n// It contains all errors from Challenge items of the failed Authorization.\ntype AuthorizationError struct {\n\t// URI uniquely identifies the failed Authorization.\n\tURI string\n\n\t// Identifier is an AuthzID.Value of the failed Authorization.\n\tIdentifier string\n\n\t// Errors is a collection of non-nil error values of Challenge items\n\t// of the failed Authorization.\n\tErrors []error\n}\n\nfunc (a *AuthorizationError) Error() string {\n\te := make([]string, len(a.Errors))\n\tfor i, err := range a.Errors {\n\t\te[i] = err.Error()\n\t}\n\n\tif a.Identifier != \"\" {\n\t\treturn fmt.Sprintf(\"acme: authorization error for %s: %s\", a.Identifier, strings.Join(e, \"; \"))\n\t}\n\n\treturn fmt.Sprintf(\"acme: authorization error: %s\", strings.Join(e, \"; \"))\n}\n\n// OrderError is returned from Client's order related methods.\n// It indicates the order is unusable and the clients should start over with\n// AuthorizeOrder. A Problem description may be provided with details on\n// what caused the order to become unusable.\n//\n// The clients can still fetch the order object from CA using GetOrder\n// to inspect its state.\ntype OrderError struct {\n\tOrderURL string\n\tStatus   string\n\t// Problem is the error that occurred while processing the order.\n\tProblem *Error\n}\n\nfunc (oe *OrderError) Error() string {\n\treturn fmt.Sprintf(\"acme: order %s status: %s\", oe.OrderURL, oe.Status)\n}\n\n// RateLimit reports whether err represents a rate limit error and\n// any Retry-After duration returned by the server.\n//\n// See the following for more details on rate limiting:\n// https://tools.ietf.org/html/draft-ietf-acme-acme-05#section-5.6\nfunc RateLimit(err error) (time.Duration, bool) {\n\te, ok := err.(*Error)\n\tif !ok {\n\t\treturn 0, false\n\t}\n\t// Some CA implementations may return incorrect values.\n\t// Use case-insensitive comparison.\n\tif !strings.HasSuffix(strings.ToLower(e.ProblemType), \":ratelimited\") {\n\t\treturn 0, false\n\t}\n\tif e.Header == nil {\n\t\treturn 0, true\n\t}\n\treturn retryAfter(e.Header.Get(\"Retry-After\")), true\n}\n\n// Account is a user account. It is associated with a private key.\n// Non-RFC 8555 fields are empty when interfacing with a compliant CA.\ntype Account struct {\n\t// URI is the account unique ID, which is also a URL used to retrieve\n\t// account data from the CA.\n\t// When interfacing with RFC 8555-compliant CAs, URI is the \"kid\" field\n\t// value in JWS signed requests.\n\tURI string\n\n\t// Contact is a slice of contact info used during registration.\n\t// See https://tools.ietf.org/html/rfc8555#section-7.3 for supported\n\t// formats.\n\tContact []string\n\n\t// Status indicates current account status as returned by the CA.\n\t// Possible values are StatusValid, StatusDeactivated, and StatusRevoked.\n\tStatus string\n\n\t// OrdersURL is a URL from which a list of orders submitted by this account\n\t// can be fetched.\n\tOrdersURL string\n\n\t// The terms user has agreed to.\n\t// A value not matching CurrentTerms indicates that the user hasn't agreed\n\t// to the actual Terms of Service of the CA.\n\t//\n\t// It is non-RFC 8555 compliant. Package users can store the ToS they agree to\n\t// during Client's Register call in the prompt callback function.\n\tAgreedTerms string\n\n\t// Actual terms of a CA.\n\t//\n\t// It is non-RFC 8555 compliant. Use Directory's Terms field.\n\t// When a CA updates their terms and requires an account agreement,\n\t// a URL at which instructions to do so is available in Error's Instance field.\n\tCurrentTerms string\n\n\t// Authz is the authorization URL used to initiate a new authz flow.\n\t//\n\t// It is non-RFC 8555 compliant. Use Directory's AuthzURL or OrderURL.\n\tAuthz string\n\n\t// Authorizations is a URI from which a list of authorizations\n\t// granted to this account can be fetched via a GET request.\n\t//\n\t// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.\n\tAuthorizations string\n\n\t// Certificates is a URI from which a list of certificates\n\t// issued for this account can be fetched via a GET request.\n\t//\n\t// It is non-RFC 8555 compliant and is obsoleted by OrdersURL.\n\tCertificates string\n\n\t// ExternalAccountBinding represents an arbitrary binding to an account of\n\t// the CA which the ACME server is tied to.\n\t// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.\n\tExternalAccountBinding *ExternalAccountBinding\n}\n\n// ExternalAccountBinding contains the data needed to form a request with\n// an external account binding.\n// See https://tools.ietf.org/html/rfc8555#section-7.3.4 for more details.\ntype ExternalAccountBinding struct {\n\t// KID is the Key ID of the symmetric MAC key that the CA provides to\n\t// identify an external account from ACME.\n\tKID string\n\n\t// Key is the bytes of the symmetric key that the CA provides to identify\n\t// the account. Key must correspond to the KID.\n\tKey []byte\n}\n\nfunc (e *ExternalAccountBinding) String() string {\n\treturn fmt.Sprintf(\"&{KID: %q, Key: redacted}\", e.KID)\n}\n\n// Directory is ACME server discovery data.\n// See https://tools.ietf.org/html/rfc8555#section-7.1.1 for more details.\ntype Directory struct {\n\t// NonceURL indicates an endpoint where to fetch fresh nonce values from.\n\tNonceURL string\n\n\t// RegURL is an account endpoint URL, allowing for creating new accounts.\n\t// Pre-RFC 8555 CAs also allow modifying existing accounts at this URL.\n\tRegURL string\n\n\t// OrderURL is used to initiate the certificate issuance flow\n\t// as described in RFC 8555.\n\tOrderURL string\n\n\t// AuthzURL is used to initiate identifier pre-authorization flow.\n\t// Empty string indicates the flow is unsupported by the CA.\n\tAuthzURL string\n\n\t// CertURL is a new certificate issuance endpoint URL.\n\t// It is non-RFC 8555 compliant and is obsoleted by OrderURL.\n\tCertURL string\n\n\t// RevokeURL is used to initiate a certificate revocation flow.\n\tRevokeURL string\n\n\t// KeyChangeURL allows to perform account key rollover flow.\n\tKeyChangeURL string\n\n\t// Terms is a URI identifying the current terms of service.\n\tTerms string\n\n\t// Website is an HTTP or HTTPS URL locating a website\n\t// providing more information about the ACME server.\n\tWebsite string\n\n\t// CAA consists of lowercase hostname elements, which the ACME server\n\t// recognises as referring to itself for the purposes of CAA record validation\n\t// as defined in RFC 6844.\n\tCAA []string\n\n\t// ExternalAccountRequired indicates that the CA requires for all account-related\n\t// requests to include external account binding information.\n\tExternalAccountRequired bool\n}\n\n// Order represents a client's request for a certificate.\n// It tracks the request flow progress through to issuance.\ntype Order struct {\n\t// URI uniquely identifies an order.\n\tURI string\n\n\t// Status represents the current status of the order.\n\t// It indicates which action the client should take.\n\t//\n\t// Possible values are StatusPending, StatusReady, StatusProcessing, StatusValid and StatusInvalid.\n\t// Pending means the CA does not believe that the client has fulfilled the requirements.\n\t// Ready indicates that the client has fulfilled all the requirements and can submit a CSR\n\t// to obtain a certificate. This is done with Client's CreateOrderCert.\n\t// Processing means the certificate is being issued.\n\t// Valid indicates the CA has issued the certificate. It can be downloaded\n\t// from the Order's CertURL. This is done with Client's FetchCert.\n\t// Invalid means the certificate will not be issued. Users should consider this order\n\t// abandoned.\n\tStatus string\n\n\t// Expires is the timestamp after which CA considers this order invalid.\n\tExpires time.Time\n\n\t// Identifiers contains all identifier objects which the order pertains to.\n\tIdentifiers []AuthzID\n\n\t// NotBefore is the requested value of the notBefore field in the certificate.\n\tNotBefore time.Time\n\n\t// NotAfter is the requested value of the notAfter field in the certificate.\n\tNotAfter time.Time\n\n\t// AuthzURLs represents authorizations to complete before a certificate\n\t// for identifiers specified in the order can be issued.\n\t// It also contains unexpired authorizations that the client has completed\n\t// in the past.\n\t//\n\t// Authorization objects can be fetched using Client's GetAuthorization method.\n\t//\n\t// The required authorizations are dictated by CA policies.\n\t// There may not be a 1:1 relationship between the identifiers and required authorizations.\n\t// Required authorizations can be identified by their StatusPending status.\n\t//\n\t// For orders in the StatusValid or StatusInvalid state these are the authorizations\n\t// which were completed.\n\tAuthzURLs []string\n\n\t// FinalizeURL is the endpoint at which a CSR is submitted to obtain a certificate\n\t// once all the authorizations are satisfied.\n\tFinalizeURL string\n\n\t// CertURL points to the certificate that has been issued in response to this order.\n\tCertURL string\n\n\t// The error that occurred while processing the order as received from a CA, if any.\n\tError *Error\n}\n\n// OrderOption allows customizing Client.AuthorizeOrder call.\ntype OrderOption interface {\n\tprivateOrderOpt()\n}\n\n// WithOrderNotBefore sets order's NotBefore field.\nfunc WithOrderNotBefore(t time.Time) OrderOption {\n\treturn orderNotBeforeOpt(t)\n}\n\n// WithOrderNotAfter sets order's NotAfter field.\nfunc WithOrderNotAfter(t time.Time) OrderOption {\n\treturn orderNotAfterOpt(t)\n}\n\ntype orderNotBeforeOpt time.Time\n\nfunc (orderNotBeforeOpt) privateOrderOpt() {}\n\ntype orderNotAfterOpt time.Time\n\nfunc (orderNotAfterOpt) privateOrderOpt() {}\n\n// Authorization encodes an authorization response.\ntype Authorization struct {\n\t// URI uniquely identifies a authorization.\n\tURI string\n\n\t// Status is the current status of an authorization.\n\t// Possible values are StatusPending, StatusValid, StatusInvalid, StatusDeactivated,\n\t// StatusExpired and StatusRevoked.\n\tStatus string\n\n\t// Identifier is what the account is authorized to represent.\n\tIdentifier AuthzID\n\n\t// The timestamp after which the CA considers the authorization invalid.\n\tExpires time.Time\n\n\t// Wildcard is true for authorizations of a wildcard domain name.\n\tWildcard bool\n\n\t// Challenges that the client needs to fulfill in order to prove possession\n\t// of the identifier (for pending authorizations).\n\t// For valid authorizations, the challenge that was validated.\n\t// For invalid authorizations, the challenge that was attempted and failed.\n\t//\n\t// RFC 8555 compatible CAs require users to fuflfill only one of the challenges.\n\tChallenges []*Challenge\n\n\t// A collection of sets of challenges, each of which would be sufficient\n\t// to prove possession of the identifier.\n\t// Clients must complete a set of challenges that covers at least one set.\n\t// Challenges are identified by their indices in the challenges array.\n\t// If this field is empty, the client needs to complete all challenges.\n\t//\n\t// This field is unused in RFC 8555.\n\tCombinations [][]int\n}\n\n// AuthzID is an identifier that an account is authorized to represent.\ntype AuthzID struct {\n\tType  string // The type of identifier, \"dns\" or \"ip\".\n\tValue string // The identifier itself, e.g. \"example.org\".\n}\n\n// DomainIDs creates a slice of AuthzID with \"dns\" identifier type.\nfunc DomainIDs(names ...string) []AuthzID {\n\ta := make([]AuthzID, len(names))\n\tfor i, v := range names {\n\t\ta[i] = AuthzID{Type: \"dns\", Value: v}\n\t}\n\treturn a\n}\n\n// IPIDs creates a slice of AuthzID with \"ip\" identifier type.\n// Each element of addr is textual form of an address as defined\n// in RFC 1123 Section 2.1 for IPv4 and in RFC 5952 Section 4 for IPv6.\nfunc IPIDs(addr ...string) []AuthzID {\n\ta := make([]AuthzID, len(addr))\n\tfor i, v := range addr {\n\t\ta[i] = AuthzID{Type: \"ip\", Value: v}\n\t}\n\treturn a\n}\n\n// wireAuthzID is ACME JSON representation of authorization identifier objects.\ntype wireAuthzID struct {\n\tType  string `json:\"type\"`\n\tValue string `json:\"value\"`\n}\n\n// wireAuthz is ACME JSON representation of Authorization objects.\ntype wireAuthz struct {\n\tIdentifier   wireAuthzID\n\tStatus       string\n\tExpires      time.Time\n\tWildcard     bool\n\tChallenges   []wireChallenge\n\tCombinations [][]int\n\tError        *wireError\n}\n\nfunc (z *wireAuthz) authorization(uri string) *Authorization {\n\ta := &Authorization{\n\t\tURI:          uri,\n\t\tStatus:       z.Status,\n\t\tIdentifier:   AuthzID{Type: z.Identifier.Type, Value: z.Identifier.Value},\n\t\tExpires:      z.Expires,\n\t\tWildcard:     z.Wildcard,\n\t\tChallenges:   make([]*Challenge, len(z.Challenges)),\n\t\tCombinations: z.Combinations, // shallow copy\n\t}\n\tfor i, v := range z.Challenges {\n\t\ta.Challenges[i] = v.challenge()\n\t}\n\treturn a\n}\n\nfunc (z *wireAuthz) error(uri string) *AuthorizationError {\n\terr := &AuthorizationError{\n\t\tURI:        uri,\n\t\tIdentifier: z.Identifier.Value,\n\t}\n\n\tif z.Error != nil {\n\t\terr.Errors = append(err.Errors, z.Error.error(nil))\n\t}\n\n\tfor _, raw := range z.Challenges {\n\t\tif raw.Error != nil {\n\t\t\terr.Errors = append(err.Errors, raw.Error.error(nil))\n\t\t}\n\t}\n\n\treturn err\n}\n\n// Challenge encodes a returned CA challenge.\n// Its Error field may be non-nil if the challenge is part of an Authorization\n// with StatusInvalid.\ntype Challenge struct {\n\t// Type is the challenge type, e.g. \"http-01\", \"tls-alpn-01\", \"dns-01\".\n\tType string\n\n\t// URI is where a challenge response can be posted to.\n\tURI string\n\n\t// Token is a random value that uniquely identifies the challenge.\n\tToken string\n\n\t// Status identifies the status of this challenge.\n\t// In RFC 8555, possible values are StatusPending, StatusProcessing, StatusValid,\n\t// and StatusInvalid.\n\tStatus string\n\n\t// Validated is the time at which the CA validated this challenge.\n\t// Always zero value in pre-RFC 8555.\n\tValidated time.Time\n\n\t// Error indicates the reason for an authorization failure\n\t// when this challenge was used.\n\t// The type of a non-nil value is *Error.\n\tError error\n\n\t// Payload is the JSON-formatted payload that the client sends\n\t// to the server to indicate it is ready to respond to the challenge.\n\t// When unset, it defaults to an empty JSON object: {}.\n\t// For most challenges, the client must not set Payload,\n\t// see https://tools.ietf.org/html/rfc8555#section-7.5.1.\n\t// Payload is used only for newer challenges (such as \"device-attest-01\")\n\t// where the client must send additional data for the server to validate\n\t// the challenge.\n\tPayload json.RawMessage\n}\n\n// wireChallenge is ACME JSON challenge representation.\ntype wireChallenge struct {\n\tURL       string `json:\"url\"` // RFC\n\tURI       string `json:\"uri\"` // pre-RFC\n\tType      string\n\tToken     string\n\tStatus    string\n\tValidated time.Time\n\tError     *wireError\n}\n\nfunc (c *wireChallenge) challenge() *Challenge {\n\tv := &Challenge{\n\t\tURI:    c.URL,\n\t\tType:   c.Type,\n\t\tToken:  c.Token,\n\t\tStatus: c.Status,\n\t}\n\tif v.URI == \"\" {\n\t\tv.URI = c.URI // c.URL was empty; use legacy\n\t}\n\tif v.Status == \"\" {\n\t\tv.Status = StatusPending\n\t}\n\tif c.Error != nil {\n\t\tv.Error = c.Error.error(nil)\n\t}\n\treturn v\n}\n\n// wireError is a subset of fields of the Problem Details object\n// as described in https://tools.ietf.org/html/rfc7807#section-3.1.\ntype wireError struct {\n\tStatus      int\n\tType        string\n\tDetail      string\n\tInstance    string\n\tSubproblems []Subproblem\n}\n\nfunc (e *wireError) error(h http.Header) *Error {\n\terr := &Error{\n\t\tStatusCode:  e.Status,\n\t\tProblemType: e.Type,\n\t\tDetail:      e.Detail,\n\t\tInstance:    e.Instance,\n\t\tHeader:      h,\n\t\tSubproblems: e.Subproblems,\n\t}\n\treturn err\n}\n\n// CertOption is an optional argument type for the TLS ChallengeCert methods for\n// customizing a temporary certificate for TLS-based challenges.\ntype CertOption interface {\n\tprivateCertOpt()\n}\n\n// WithKey creates an option holding a private/public key pair.\n// The private part signs a certificate, and the public part represents the signee.\nfunc WithKey(key crypto.Signer) CertOption {\n\treturn &certOptKey{key}\n}\n\ntype certOptKey struct {\n\tkey crypto.Signer\n}\n\nfunc (*certOptKey) privateCertOpt() {}\n\n// WithTemplate creates an option for specifying a certificate template.\n// See x509.CreateCertificate for template usage details.\n//\n// In TLS ChallengeCert methods, the template is also used as parent,\n// resulting in a self-signed certificate.\n// The DNSNames or IPAddresses fields of t are always overwritten for tls-alpn challenge certs.\nfunc WithTemplate(t *x509.Certificate) CertOption {\n\treturn (*certOptTemplate)(t)\n}\n\ntype certOptTemplate x509.Certificate\n\nfunc (*certOptTemplate) privateCertOpt() {}\n"
  },
  {
    "path": "vendor/golang.org/x/mod/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * Neither the name of Google LLC 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": "vendor/golang.org/x/mod/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/mod/semver/semver.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// Package semver implements comparison of semantic version strings.\n// In this package, semantic version strings must begin with a leading \"v\",\n// as in \"v1.0.0\".\n//\n// The general form of a semantic version string accepted by this package is\n//\n//\tvMAJOR[.MINOR[.PATCH[-PRERELEASE][+BUILD]]]\n//\n// where square brackets indicate optional parts of the syntax;\n// MAJOR, MINOR, and PATCH are decimal integers without extra leading zeros;\n// PRERELEASE and BUILD are each a series of non-empty dot-separated identifiers\n// using only alphanumeric characters and hyphens; and\n// all-numeric PRERELEASE identifiers must not have leading zeros.\n//\n// This package follows Semantic Versioning 2.0.0 (see semver.org)\n// with two exceptions. First, it requires the \"v\" prefix. Second, it recognizes\n// vMAJOR and vMAJOR.MINOR (with no prerelease or build suffixes)\n// as shorthands for vMAJOR.0.0 and vMAJOR.MINOR.0.\npackage semver\n\nimport (\n\t\"slices\"\n\t\"strings\"\n)\n\n// parsed returns the parsed form of a semantic version string.\ntype parsed struct {\n\tmajor      string\n\tminor      string\n\tpatch      string\n\tshort      string\n\tprerelease string\n\tbuild      string\n}\n\n// IsValid reports whether v is a valid semantic version string.\nfunc IsValid(v string) bool {\n\t_, ok := parse(v)\n\treturn ok\n}\n\n// Canonical returns the canonical formatting of the semantic version v.\n// It fills in any missing .MINOR or .PATCH and discards build metadata.\n// Two semantic versions compare equal only if their canonical formattings\n// are identical strings.\n// The canonical invalid semantic version is the empty string.\nfunc Canonical(v string) string {\n\tp, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\tif p.build != \"\" {\n\t\treturn v[:len(v)-len(p.build)]\n\t}\n\tif p.short != \"\" {\n\t\treturn v + p.short\n\t}\n\treturn v\n}\n\n// Major returns the major version prefix of the semantic version v.\n// For example, Major(\"v2.1.0\") == \"v2\".\n// If v is an invalid semantic version string, Major returns the empty string.\nfunc Major(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn v[:1+len(pv.major)]\n}\n\n// MajorMinor returns the major.minor version prefix of the semantic version v.\n// For example, MajorMinor(\"v2.1.0\") == \"v2.1\".\n// If v is an invalid semantic version string, MajorMinor returns the empty string.\nfunc MajorMinor(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\ti := 1 + len(pv.major)\n\tif j := i + 1 + len(pv.minor); j <= len(v) && v[i] == '.' && v[i+1:j] == pv.minor {\n\t\treturn v[:j]\n\t}\n\treturn v[:i] + \".\" + pv.minor\n}\n\n// Prerelease returns the prerelease suffix of the semantic version v.\n// For example, Prerelease(\"v2.1.0-pre+meta\") == \"-pre\".\n// If v is an invalid semantic version string, Prerelease returns the empty string.\nfunc Prerelease(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn pv.prerelease\n}\n\n// Build returns the build suffix of the semantic version v.\n// For example, Build(\"v2.1.0+meta\") == \"+meta\".\n// If v is an invalid semantic version string, Build returns the empty string.\nfunc Build(v string) string {\n\tpv, ok := parse(v)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn pv.build\n}\n\n// Compare returns an integer comparing two versions according to\n// semantic version precedence.\n// The result will be 0 if v == w, -1 if v < w, or +1 if v > w.\n//\n// An invalid semantic version string is considered less than a valid one.\n// All invalid semantic version strings compare equal to each other.\nfunc Compare(v, w string) int {\n\tpv, ok1 := parse(v)\n\tpw, ok2 := parse(w)\n\tif !ok1 && !ok2 {\n\t\treturn 0\n\t}\n\tif !ok1 {\n\t\treturn -1\n\t}\n\tif !ok2 {\n\t\treturn +1\n\t}\n\tif c := compareInt(pv.major, pw.major); c != 0 {\n\t\treturn c\n\t}\n\tif c := compareInt(pv.minor, pw.minor); c != 0 {\n\t\treturn c\n\t}\n\tif c := compareInt(pv.patch, pw.patch); c != 0 {\n\t\treturn c\n\t}\n\treturn comparePrerelease(pv.prerelease, pw.prerelease)\n}\n\n// Max canonicalizes its arguments and then returns the version string\n// that compares greater.\n//\n// Deprecated: use [Compare] instead. In most cases, returning a canonicalized\n// version is not expected or desired.\nfunc Max(v, w string) string {\n\tv = Canonical(v)\n\tw = Canonical(w)\n\tif Compare(v, w) > 0 {\n\t\treturn v\n\t}\n\treturn w\n}\n\n// ByVersion implements [sort.Interface] for sorting semantic version strings.\ntype ByVersion []string\n\nfunc (vs ByVersion) Len() int           { return len(vs) }\nfunc (vs ByVersion) Swap(i, j int)      { vs[i], vs[j] = vs[j], vs[i] }\nfunc (vs ByVersion) Less(i, j int) bool { return compareVersion(vs[i], vs[j]) < 0 }\n\n// Sort sorts a list of semantic version strings using [Compare] and falls back\n// to use [strings.Compare] if both versions are considered equal.\nfunc Sort(list []string) {\n\tslices.SortFunc(list, compareVersion)\n}\n\nfunc compareVersion(a, b string) int {\n\tcmp := Compare(a, b)\n\tif cmp != 0 {\n\t\treturn cmp\n\t}\n\treturn strings.Compare(a, b)\n}\n\nfunc parse(v string) (p parsed, ok bool) {\n\tif v == \"\" || v[0] != 'v' {\n\t\treturn\n\t}\n\tp.major, v, ok = parseInt(v[1:])\n\tif !ok {\n\t\treturn\n\t}\n\tif v == \"\" {\n\t\tp.minor = \"0\"\n\t\tp.patch = \"0\"\n\t\tp.short = \".0.0\"\n\t\treturn\n\t}\n\tif v[0] != '.' {\n\t\tok = false\n\t\treturn\n\t}\n\tp.minor, v, ok = parseInt(v[1:])\n\tif !ok {\n\t\treturn\n\t}\n\tif v == \"\" {\n\t\tp.patch = \"0\"\n\t\tp.short = \".0\"\n\t\treturn\n\t}\n\tif v[0] != '.' {\n\t\tok = false\n\t\treturn\n\t}\n\tp.patch, v, ok = parseInt(v[1:])\n\tif !ok {\n\t\treturn\n\t}\n\tif len(v) > 0 && v[0] == '-' {\n\t\tp.prerelease, v, ok = parsePrerelease(v)\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\t}\n\tif len(v) > 0 && v[0] == '+' {\n\t\tp.build, v, ok = parseBuild(v)\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\t}\n\tif v != \"\" {\n\t\tok = false\n\t\treturn\n\t}\n\tok = true\n\treturn\n}\n\nfunc parseInt(v string) (t, rest string, ok bool) {\n\tif v == \"\" {\n\t\treturn\n\t}\n\tif v[0] < '0' || '9' < v[0] {\n\t\treturn\n\t}\n\ti := 1\n\tfor i < len(v) && '0' <= v[i] && v[i] <= '9' {\n\t\ti++\n\t}\n\tif v[0] == '0' && i != 1 {\n\t\treturn\n\t}\n\treturn v[:i], v[i:], true\n}\n\nfunc parsePrerelease(v string) (t, rest string, ok bool) {\n\t// \"A pre-release version MAY be denoted by appending a hyphen and\n\t// a series of dot separated identifiers immediately following the patch version.\n\t// Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-].\n\t// Identifiers MUST NOT be empty. Numeric identifiers MUST NOT include leading zeroes.\"\n\tif v == \"\" || v[0] != '-' {\n\t\treturn\n\t}\n\ti := 1\n\tstart := 1\n\tfor i < len(v) && v[i] != '+' {\n\t\tif !isIdentChar(v[i]) && v[i] != '.' {\n\t\t\treturn\n\t\t}\n\t\tif v[i] == '.' {\n\t\t\tif start == i || isBadNum(v[start:i]) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tstart = i + 1\n\t\t}\n\t\ti++\n\t}\n\tif start == i || isBadNum(v[start:i]) {\n\t\treturn\n\t}\n\treturn v[:i], v[i:], true\n}\n\nfunc parseBuild(v string) (t, rest string, ok bool) {\n\tif v == \"\" || v[0] != '+' {\n\t\treturn\n\t}\n\ti := 1\n\tstart := 1\n\tfor i < len(v) {\n\t\tif !isIdentChar(v[i]) && v[i] != '.' {\n\t\t\treturn\n\t\t}\n\t\tif v[i] == '.' {\n\t\t\tif start == i {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tstart = i + 1\n\t\t}\n\t\ti++\n\t}\n\tif start == i {\n\t\treturn\n\t}\n\treturn v[:i], v[i:], true\n}\n\nfunc isIdentChar(c byte) bool {\n\treturn 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-'\n}\n\nfunc isBadNum(v string) bool {\n\ti := 0\n\tfor i < len(v) && '0' <= v[i] && v[i] <= '9' {\n\t\ti++\n\t}\n\treturn i == len(v) && i > 1 && v[0] == '0'\n}\n\nfunc isNum(v string) bool {\n\ti := 0\n\tfor i < len(v) && '0' <= v[i] && v[i] <= '9' {\n\t\ti++\n\t}\n\treturn i == len(v)\n}\n\nfunc compareInt(x, y string) int {\n\tif x == y {\n\t\treturn 0\n\t}\n\tif len(x) < len(y) {\n\t\treturn -1\n\t}\n\tif len(x) > len(y) {\n\t\treturn +1\n\t}\n\tif x < y {\n\t\treturn -1\n\t} else {\n\t\treturn +1\n\t}\n}\n\nfunc comparePrerelease(x, y string) int {\n\t// \"When major, minor, and patch are equal, a pre-release version has\n\t// lower precedence than a normal version.\n\t// Example: 1.0.0-alpha < 1.0.0.\n\t// Precedence for two pre-release versions with the same major, minor,\n\t// and patch version MUST be determined by comparing each dot separated\n\t// identifier from left to right until a difference is found as follows:\n\t// identifiers consisting of only digits are compared numerically and\n\t// identifiers with letters or hyphens are compared lexically in ASCII\n\t// sort order. Numeric identifiers always have lower precedence than\n\t// non-numeric identifiers. A larger set of pre-release fields has a\n\t// higher precedence than a smaller set, if all of the preceding\n\t// identifiers are equal.\n\t// Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta <\n\t// 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.\"\n\tif x == y {\n\t\treturn 0\n\t}\n\tif x == \"\" {\n\t\treturn +1\n\t}\n\tif y == \"\" {\n\t\treturn -1\n\t}\n\tfor x != \"\" && y != \"\" {\n\t\tx = x[1:] // skip - or .\n\t\ty = y[1:] // skip - or .\n\t\tvar dx, dy string\n\t\tdx, x = nextIdent(x)\n\t\tdy, y = nextIdent(y)\n\t\tif dx != dy {\n\t\t\tix := isNum(dx)\n\t\t\tiy := isNum(dy)\n\t\t\tif ix != iy {\n\t\t\t\tif ix {\n\t\t\t\t\treturn -1\n\t\t\t\t} else {\n\t\t\t\t\treturn +1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ix {\n\t\t\t\tif len(dx) < len(dy) {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\t\tif len(dx) > len(dy) {\n\t\t\t\t\treturn +1\n\t\t\t\t}\n\t\t\t}\n\t\t\tif dx < dy {\n\t\t\t\treturn -1\n\t\t\t} else {\n\t\t\t\treturn +1\n\t\t\t}\n\t\t}\n\t}\n\tif x == \"\" {\n\t\treturn -1\n\t} else {\n\t\treturn +1\n\t}\n}\n\nfunc nextIdent(x string) (dx, rest string) {\n\ti := 0\n\tfor i < len(x) && x[i] != '.' {\n\t\ti++\n\t}\n\treturn x[:i], x[i:]\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/LICENSE",
    "content": "Copyright 2009 The Go Authors.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * 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   * Neither the name of Google LLC 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": "vendor/golang.org/x/net/PATENTS",
    "content": "Additional IP Rights Grant (Patents)\n\n\"This implementation\" means the copyrightable works distributed by\nGoogle as part of the Go project.\n\nGoogle hereby grants to You a perpetual, worldwide, non-exclusive,\nno-charge, royalty-free, irrevocable (except as stated in this section)\npatent license to make, have made, use, offer to sell, sell, import,\ntransfer and otherwise run, modify and propagate the contents of this\nimplementation of Go, where such license applies only to those patent\nclaims, both currently owned or controlled by Google and acquired in\nthe future, licensable by Google that are necessarily infringed by this\nimplementation of Go.  This grant does not include claims that would be\ninfringed only as a consequence of further modification of this\nimplementation.  If you or your agent or exclusive licensee institute or\norder or agree to the institution of patent litigation against any\nentity (including a cross-claim or counterclaim in a lawsuit) alleging\nthat this implementation of Go or any code incorporated within this\nimplementation of Go constitutes direct or contributory patent\ninfringement, or inducement of patent infringement, then any patent\nrights granted to you under this License for this implementation of Go\nshall terminate as of the date such litigation is filed.\n"
  },
  {
    "path": "vendor/golang.org/x/net/context/context.go",
    "content": "// Copyright 2014 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// Package context has been superseded by the standard library [context] package.\n//\n// Deprecated: Use the standard library context package instead.\npackage context\n\nimport (\n\t\"context\" // standard library's context, as of Go 1.7\n\t\"time\"\n)\n\n// A Context carries a deadline, a cancellation signal, and other values across\n// API boundaries.\n//\n// Context's methods may be called by multiple goroutines simultaneously.\n//\n//go:fix inline\ntype Context = context.Context\n\n// Canceled is the error returned by [Context.Err] when the context is canceled\n// for some reason other than its deadline passing.\n//\n//go:fix inline\nvar Canceled = context.Canceled\n\n// DeadlineExceeded is the error returned by [Context.Err] when the context is canceled\n// due to its deadline passing.\n//\n//go:fix inline\nvar DeadlineExceeded = context.DeadlineExceeded\n\n// Background returns a non-nil, empty Context. It is never canceled, has no\n// values, and has no deadline. It is typically used by the main function,\n// initialization, and tests, and as the top-level Context for incoming\n// requests.\n//\n//go:fix inline\nfunc Background() Context { return context.Background() }\n\n// TODO returns a non-nil, empty Context. Code should use context.TODO when\n// it's unclear which Context to use or it is not yet available (because the\n// surrounding function has not yet been extended to accept a Context\n// parameter).\n//\n//go:fix inline\nfunc TODO() Context { return context.TODO() }\n\n// A CancelFunc tells an operation to abandon its work.\n// A CancelFunc does not wait for the work to stop.\n// A CancelFunc may be called by multiple goroutines simultaneously.\n// After the first call, subsequent calls to a CancelFunc do nothing.\ntype CancelFunc = context.CancelFunc\n\n// WithCancel returns a derived context that points to the parent context\n// but has a new Done channel. The returned context's Done channel is closed\n// when the returned cancel function is called or when the parent context's\n// Done channel is closed, whichever happens first.\n//\n// Canceling this context releases resources associated with it, so code should\n// call cancel as soon as the operations running in this [Context] complete.\n//\n//go:fix inline\nfunc WithCancel(parent Context) (ctx Context, cancel CancelFunc) {\n\treturn context.WithCancel(parent)\n}\n\n// WithDeadline returns a derived context that points to the parent context\n// but has the deadline adjusted to be no later than d. If the parent's\n// deadline is already earlier than d, WithDeadline(parent, d) is semantically\n// equivalent to parent. The returned [Context.Done] channel is closed when\n// the deadline expires, when the returned cancel function is called,\n// or when the parent context's Done channel is closed, whichever happens first.\n//\n// Canceling this context releases resources associated with it, so code should\n// call cancel as soon as the operations running in this [Context] complete.\n//\n//go:fix inline\nfunc WithDeadline(parent Context, d time.Time) (Context, CancelFunc) {\n\treturn context.WithDeadline(parent, d)\n}\n\n// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)).\n//\n// Canceling this context releases resources associated with it, so code should\n// call cancel as soon as the operations running in this [Context] complete:\n//\n//\tfunc slowOperationWithTimeout(ctx context.Context) (Result, error) {\n//\t\tctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)\n//\t\tdefer cancel()  // releases resources if slowOperation completes before timeout elapses\n//\t\treturn slowOperation(ctx)\n//\t}\n//\n//go:fix inline\nfunc WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {\n\treturn context.WithTimeout(parent, timeout)\n}\n\n// WithValue returns a derived context that points to the parent Context.\n// In the derived context, the value associated with key is val.\n//\n// Use context Values only for request-scoped data that transits processes and\n// APIs, not for passing optional parameters to functions.\n//\n// The provided key must be comparable and should not be of type\n// string or any other built-in type to avoid collisions between\n// packages using context. Users of WithValue should define their own\n// types for keys. To avoid allocating when assigning to an\n// interface{}, context keys often have concrete type\n// struct{}. Alternatively, exported context key variables' static\n// type should be a pointer or interface.\n//\n//go:fix inline\nfunc WithValue(parent Context, key, val interface{}) Context {\n\treturn context.WithValue(parent, key, val)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/atom/atom.go",
    "content": "// Copyright 2012 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// Package atom provides integer codes (also known as atoms) for a fixed set of\n// frequently occurring HTML strings: tag names and attribute keys such as \"p\"\n// and \"id\".\n//\n// Sharing an atom's name between all elements with the same tag can result in\n// fewer string allocations when tokenizing and parsing HTML. Integer\n// comparisons are also generally faster than string comparisons.\n//\n// The value of an atom's particular code is not guaranteed to stay the same\n// between versions of this package. Neither is any ordering guaranteed:\n// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to\n// be dense. The only guarantees are that e.g. looking up \"div\" will yield\n// atom.Div, calling atom.Div.String will return \"div\", and atom.Div != 0.\npackage atom // import \"golang.org/x/net/html/atom\"\n\n// Atom is an integer code for a string. The zero value maps to \"\".\ntype Atom uint32\n\n// String returns the atom's name.\nfunc (a Atom) String() string {\n\tstart := uint32(a >> 8)\n\tn := uint32(a & 0xff)\n\tif start+n > uint32(len(atomText)) {\n\t\treturn \"\"\n\t}\n\treturn atomText[start : start+n]\n}\n\nfunc (a Atom) string() string {\n\treturn atomText[a>>8 : a>>8+a&0xff]\n}\n\n// fnv computes the FNV hash with an arbitrary starting value h.\nfunc fnv(h uint32, s []byte) uint32 {\n\tfor i := range s {\n\t\th ^= uint32(s[i])\n\t\th *= 16777619\n\t}\n\treturn h\n}\n\nfunc match(s string, t []byte) bool {\n\tfor i, c := range t {\n\t\tif s[i] != c {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// Lookup returns the atom whose name is s. It returns zero if there is no\n// such atom. The lookup is case sensitive.\nfunc Lookup(s []byte) Atom {\n\tif len(s) == 0 || len(s) > maxAtomLen {\n\t\treturn 0\n\t}\n\th := fnv(hash0, s)\n\tif a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) {\n\t\treturn a\n\t}\n\tif a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) {\n\t\treturn a\n\t}\n\treturn 0\n}\n\n// String returns a string whose contents are equal to s. In that sense, it is\n// equivalent to string(s) but may be more efficient.\nfunc String(s []byte) string {\n\tif a := Lookup(s); a != 0 {\n\t\treturn a.String()\n\t}\n\treturn string(s)\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/atom/table.go",
    "content": "// Code generated by go generate gen.go; DO NOT EDIT.\n\n//go:generate go run gen.go\n\npackage atom\n\nconst (\n\tA                         Atom = 0x1\n\tAbbr                      Atom = 0x4\n\tAccept                    Atom = 0x1a06\n\tAcceptCharset             Atom = 0x1a0e\n\tAccesskey                 Atom = 0x2c09\n\tAcronym                   Atom = 0xaa07\n\tAction                    Atom = 0x26506\n\tAddress                   Atom = 0x6f107\n\tAlign                     Atom = 0xb105\n\tAllowfullscreen           Atom = 0x3280f\n\tAllowpaymentrequest       Atom = 0xc113\n\tAllowusermedia            Atom = 0xdd0e\n\tAlt                       Atom = 0xf303\n\tAnnotation                Atom = 0x1c90a\n\tAnnotationXml             Atom = 0x1c90e\n\tApplet                    Atom = 0x30806\n\tArea                      Atom = 0x35004\n\tArticle                   Atom = 0x3f607\n\tAs                        Atom = 0x3c02\n\tAside                     Atom = 0x10705\n\tAsync                     Atom = 0xff05\n\tAudio                     Atom = 0x11505\n\tAutocomplete              Atom = 0x26b0c\n\tAutofocus                 Atom = 0x12109\n\tAutoplay                  Atom = 0x13c08\n\tB                         Atom = 0x101\n\tBase                      Atom = 0x3b04\n\tBasefont                  Atom = 0x3b08\n\tBdi                       Atom = 0xba03\n\tBdo                       Atom = 0x14b03\n\tBgsound                   Atom = 0x15e07\n\tBig                       Atom = 0x17003\n\tBlink                     Atom = 0x17305\n\tBlockquote                Atom = 0x1870a\n\tBody                      Atom = 0x2804\n\tBr                        Atom = 0x202\n\tButton                    Atom = 0x19106\n\tCanvas                    Atom = 0x10306\n\tCaption                   Atom = 0x22407\n\tCenter                    Atom = 0x21306\n\tChallenge                 Atom = 0x28e09\n\tCharset                   Atom = 0x2107\n\tChecked                   Atom = 0x5b507\n\tCite                      Atom = 0x19c04\n\tClass                     Atom = 0x55805\n\tCode                      Atom = 0x5ee04\n\tCol                       Atom = 0x1ab03\n\tColgroup                  Atom = 0x1ab08\n\tColor                     Atom = 0x1bf05\n\tCols                      Atom = 0x1c404\n\tColspan                   Atom = 0x1c407\n\tCommand                   Atom = 0x1d707\n\tContent                   Atom = 0x57b07\n\tContenteditable           Atom = 0x57b0f\n\tContextmenu               Atom = 0x37a0b\n\tControls                  Atom = 0x1de08\n\tCoords                    Atom = 0x1f006\n\tCrossorigin               Atom = 0x1fa0b\n\tData                      Atom = 0x49904\n\tDatalist                  Atom = 0x49908\n\tDatetime                  Atom = 0x2ab08\n\tDd                        Atom = 0x2bf02\n\tDefault                   Atom = 0x10a07\n\tDefer                     Atom = 0x5f005\n\tDel                       Atom = 0x44c03\n\tDesc                      Atom = 0x55504\n\tDetails                   Atom = 0x7207\n\tDfn                       Atom = 0x8703\n\tDialog                    Atom = 0xbb06\n\tDir                       Atom = 0x9303\n\tDirname                   Atom = 0x9307\n\tDisabled                  Atom = 0x16408\n\tDiv                       Atom = 0x16b03\n\tDl                        Atom = 0x5d602\n\tDownload                  Atom = 0x45d08\n\tDraggable                 Atom = 0x17a09\n\tDropzone                  Atom = 0x3ff08\n\tDt                        Atom = 0x64002\n\tEm                        Atom = 0x6e02\n\tEmbed                     Atom = 0x6e05\n\tEnctype                   Atom = 0x28007\n\tFace                      Atom = 0x21104\n\tFieldset                  Atom = 0x21908\n\tFigcaption                Atom = 0x2210a\n\tFigure                    Atom = 0x23b06\n\tFont                      Atom = 0x3f04\n\tFooter                    Atom = 0xf606\n\tFor                       Atom = 0x24703\n\tForeignObject             Atom = 0x2470d\n\tForeignobject             Atom = 0x2540d\n\tForm                      Atom = 0x26104\n\tFormaction                Atom = 0x2610a\n\tFormenctype               Atom = 0x27c0b\n\tFormmethod                Atom = 0x2970a\n\tFormnovalidate            Atom = 0x2a10e\n\tFormtarget                Atom = 0x2b30a\n\tFrame                     Atom = 0x8b05\n\tFrameset                  Atom = 0x8b08\n\tH1                        Atom = 0x15c02\n\tH2                        Atom = 0x56102\n\tH3                        Atom = 0x2cd02\n\tH4                        Atom = 0x2fc02\n\tH5                        Atom = 0x33f02\n\tH6                        Atom = 0x34902\n\tHead                      Atom = 0x32004\n\tHeader                    Atom = 0x32006\n\tHeaders                   Atom = 0x32007\n\tHeight                    Atom = 0x5206\n\tHgroup                    Atom = 0x64206\n\tHidden                    Atom = 0x2bd06\n\tHigh                      Atom = 0x2ca04\n\tHr                        Atom = 0x15702\n\tHref                      Atom = 0x2cf04\n\tHreflang                  Atom = 0x2cf08\n\tHtml                      Atom = 0x5604\n\tHttpEquiv                 Atom = 0x2d70a\n\tI                         Atom = 0x601\n\tIcon                      Atom = 0x57a04\n\tId                        Atom = 0x10902\n\tIframe                    Atom = 0x2eb06\n\tImage                     Atom = 0x2f105\n\tImg                       Atom = 0x2f603\n\tInput                     Atom = 0x44505\n\tInputmode                 Atom = 0x44509\n\tIns                       Atom = 0x20303\n\tIntegrity                 Atom = 0x23209\n\tIs                        Atom = 0x16502\n\tIsindex                   Atom = 0x2fe07\n\tIsmap                     Atom = 0x30505\n\tItemid                    Atom = 0x38506\n\tItemprop                  Atom = 0x19d08\n\tItemref                   Atom = 0x3c707\n\tItemscope                 Atom = 0x66f09\n\tItemtype                  Atom = 0x30e08\n\tKbd                       Atom = 0xb903\n\tKeygen                    Atom = 0x3206\n\tKeytype                   Atom = 0xd607\n\tKind                      Atom = 0x17704\n\tLabel                     Atom = 0x5905\n\tLang                      Atom = 0x2d304\n\tLegend                    Atom = 0x18106\n\tLi                        Atom = 0xb202\n\tLink                      Atom = 0x17404\n\tList                      Atom = 0x49d04\n\tListing                   Atom = 0x49d07\n\tLoop                      Atom = 0x5d04\n\tLow                       Atom = 0xc303\n\tMain                      Atom = 0x1004\n\tMalignmark                Atom = 0xb00a\n\tManifest                  Atom = 0x6d508\n\tMap                       Atom = 0x30703\n\tMark                      Atom = 0xb604\n\tMarquee                   Atom = 0x31607\n\tMath                      Atom = 0x31d04\n\tMax                       Atom = 0x33703\n\tMaxlength                 Atom = 0x33709\n\tMedia                     Atom = 0xe605\n\tMediagroup                Atom = 0xe60a\n\tMenu                      Atom = 0x38104\n\tMenuitem                  Atom = 0x38108\n\tMeta                      Atom = 0x4ac04\n\tMeter                     Atom = 0x9805\n\tMethod                    Atom = 0x29b06\n\tMglyph                    Atom = 0x2f706\n\tMi                        Atom = 0x34102\n\tMin                       Atom = 0x34103\n\tMinlength                 Atom = 0x34109\n\tMn                        Atom = 0x2a402\n\tMo                        Atom = 0xa402\n\tMs                        Atom = 0x67202\n\tMtext                     Atom = 0x34b05\n\tMultiple                  Atom = 0x35908\n\tMuted                     Atom = 0x36105\n\tName                      Atom = 0x9604\n\tNav                       Atom = 0x1303\n\tNobr                      Atom = 0x3704\n\tNoembed                   Atom = 0x6c07\n\tNoframes                  Atom = 0x8908\n\tNomodule                  Atom = 0xa208\n\tNonce                     Atom = 0x1a605\n\tNoscript                  Atom = 0x2c208\n\tNovalidate                Atom = 0x2a50a\n\tObject                    Atom = 0x25b06\n\tOl                        Atom = 0x13702\n\tOnabort                   Atom = 0x19507\n\tOnafterprint              Atom = 0x2290c\n\tOnautocomplete            Atom = 0x2690e\n\tOnautocompleteerror       Atom = 0x26913\n\tOnauxclick                Atom = 0x6140a\n\tOnbeforeprint             Atom = 0x69c0d\n\tOnbeforeunload            Atom = 0x6e50e\n\tOnblur                    Atom = 0x1ea06\n\tOncancel                  Atom = 0x11908\n\tOncanplay                 Atom = 0x14d09\n\tOncanplaythrough          Atom = 0x14d10\n\tOnchange                  Atom = 0x41508\n\tOnclick                   Atom = 0x2e407\n\tOnclose                   Atom = 0x36607\n\tOncontextmenu             Atom = 0x3780d\n\tOncopy                    Atom = 0x38b06\n\tOncuechange               Atom = 0x3910b\n\tOncut                     Atom = 0x39c05\n\tOndblclick                Atom = 0x3a10a\n\tOndrag                    Atom = 0x3ab06\n\tOndragend                 Atom = 0x3ab09\n\tOndragenter               Atom = 0x3b40b\n\tOndragexit                Atom = 0x3bf0a\n\tOndragleave               Atom = 0x3d90b\n\tOndragover                Atom = 0x3e40a\n\tOndragstart               Atom = 0x3ee0b\n\tOndrop                    Atom = 0x3fd06\n\tOndurationchange          Atom = 0x40d10\n\tOnemptied                 Atom = 0x40409\n\tOnended                   Atom = 0x41d07\n\tOnerror                   Atom = 0x42407\n\tOnfocus                   Atom = 0x42b07\n\tOnhashchange              Atom = 0x4370c\n\tOninput                   Atom = 0x44307\n\tOninvalid                 Atom = 0x44f09\n\tOnkeydown                 Atom = 0x45809\n\tOnkeypress                Atom = 0x4650a\n\tOnkeyup                   Atom = 0x47407\n\tOnlanguagechange          Atom = 0x48110\n\tOnload                    Atom = 0x49106\n\tOnloadeddata              Atom = 0x4910c\n\tOnloadedmetadata          Atom = 0x4a410\n\tOnloadend                 Atom = 0x4ba09\n\tOnloadstart               Atom = 0x4c30b\n\tOnmessage                 Atom = 0x4ce09\n\tOnmessageerror            Atom = 0x4ce0e\n\tOnmousedown               Atom = 0x4dc0b\n\tOnmouseenter              Atom = 0x4e70c\n\tOnmouseleave              Atom = 0x4f30c\n\tOnmousemove               Atom = 0x4ff0b\n\tOnmouseout                Atom = 0x50a0a\n\tOnmouseover               Atom = 0x5170b\n\tOnmouseup                 Atom = 0x52209\n\tOnmousewheel              Atom = 0x5300c\n\tOnoffline                 Atom = 0x53c09\n\tOnonline                  Atom = 0x54508\n\tOnpagehide                Atom = 0x54d0a\n\tOnpageshow                Atom = 0x5630a\n\tOnpaste                   Atom = 0x56f07\n\tOnpause                   Atom = 0x58a07\n\tOnplay                    Atom = 0x59406\n\tOnplaying                 Atom = 0x59409\n\tOnpopstate                Atom = 0x59d0a\n\tOnprogress                Atom = 0x5a70a\n\tOnratechange              Atom = 0x5bc0c\n\tOnrejectionhandled        Atom = 0x5c812\n\tOnreset                   Atom = 0x5da07\n\tOnresize                  Atom = 0x5e108\n\tOnscroll                  Atom = 0x5f508\n\tOnsecuritypolicyviolation Atom = 0x5fd19\n\tOnseeked                  Atom = 0x61e08\n\tOnseeking                 Atom = 0x62609\n\tOnselect                  Atom = 0x62f08\n\tOnshow                    Atom = 0x63906\n\tOnsort                    Atom = 0x64d06\n\tOnstalled                 Atom = 0x65709\n\tOnstorage                 Atom = 0x66009\n\tOnsubmit                  Atom = 0x66908\n\tOnsuspend                 Atom = 0x67909\n\tOntimeupdate              Atom = 0x400c\n\tOntoggle                  Atom = 0x68208\n\tOnunhandledrejection      Atom = 0x68a14\n\tOnunload                  Atom = 0x6a908\n\tOnvolumechange            Atom = 0x6b10e\n\tOnwaiting                 Atom = 0x6bf09\n\tOnwheel                   Atom = 0x6c807\n\tOpen                      Atom = 0x1a304\n\tOptgroup                  Atom = 0x5f08\n\tOptimum                   Atom = 0x6cf07\n\tOption                    Atom = 0x6e106\n\tOutput                    Atom = 0x51106\n\tP                         Atom = 0xc01\n\tParam                     Atom = 0xc05\n\tPattern                   Atom = 0x6607\n\tPicture                   Atom = 0x7b07\n\tPing                      Atom = 0xef04\n\tPlaceholder               Atom = 0x1310b\n\tPlaintext                 Atom = 0x1b209\n\tPlaysinline               Atom = 0x1400b\n\tPoster                    Atom = 0x64706\n\tPre                       Atom = 0x46a03\n\tPreload                   Atom = 0x47a07\n\tProgress                  Atom = 0x5a908\n\tPrompt                    Atom = 0x52a06\n\tPublic                    Atom = 0x57606\n\tQ                         Atom = 0xcf01\n\tRadiogroup                Atom = 0x30a\n\tRb                        Atom = 0x3a02\n\tReadonly                  Atom = 0x35108\n\tReferrerpolicy            Atom = 0x3cb0e\n\tRel                       Atom = 0x47b03\n\tRequired                  Atom = 0x23f08\n\tReversed                  Atom = 0x8008\n\tRows                      Atom = 0x9c04\n\tRowspan                   Atom = 0x9c07\n\tRp                        Atom = 0x22f02\n\tRt                        Atom = 0x19a02\n\tRtc                       Atom = 0x19a03\n\tRuby                      Atom = 0xfb04\n\tS                         Atom = 0x2501\n\tSamp                      Atom = 0x7804\n\tSandbox                   Atom = 0x12907\n\tScope                     Atom = 0x67305\n\tScoped                    Atom = 0x67306\n\tScript                    Atom = 0x2c406\n\tSeamless                  Atom = 0x36b08\n\tSearch                    Atom = 0x55c06\n\tSection                   Atom = 0x1e507\n\tSelect                    Atom = 0x63106\n\tSelected                  Atom = 0x63108\n\tShape                     Atom = 0x1f505\n\tSize                      Atom = 0x5e504\n\tSizes                     Atom = 0x5e505\n\tSlot                      Atom = 0x20504\n\tSmall                     Atom = 0x32605\n\tSortable                  Atom = 0x64f08\n\tSorted                    Atom = 0x37206\n\tSource                    Atom = 0x43106\n\tSpacer                    Atom = 0x46e06\n\tSpan                      Atom = 0x9f04\n\tSpellcheck                Atom = 0x5b00a\n\tSrc                       Atom = 0x5e903\n\tSrcdoc                    Atom = 0x5e906\n\tSrclang                   Atom = 0x6f707\n\tSrcset                    Atom = 0x6fe06\n\tStart                     Atom = 0x3f405\n\tStep                      Atom = 0x57304\n\tStrike                    Atom = 0xd206\n\tStrong                    Atom = 0x6db06\n\tStyle                     Atom = 0x70405\n\tSub                       Atom = 0x66b03\n\tSummary                   Atom = 0x70907\n\tSup                       Atom = 0x71003\n\tSvg                       Atom = 0x71303\n\tSystem                    Atom = 0x71606\n\tTabindex                  Atom = 0x4b208\n\tTable                     Atom = 0x58505\n\tTarget                    Atom = 0x2b706\n\tTbody                     Atom = 0x2705\n\tTd                        Atom = 0x9202\n\tTemplate                  Atom = 0x71908\n\tTextarea                  Atom = 0x34c08\n\tTfoot                     Atom = 0xf505\n\tTh                        Atom = 0x15602\n\tThead                     Atom = 0x31f05\n\tTime                      Atom = 0x4204\n\tTitle                     Atom = 0x11005\n\tTr                        Atom = 0xcc02\n\tTrack                     Atom = 0x1ba05\n\tTranslate                 Atom = 0x20809\n\tTt                        Atom = 0x6802\n\tType                      Atom = 0xd904\n\tTypemustmatch             Atom = 0x2830d\n\tU                         Atom = 0xb01\n\tUl                        Atom = 0xa702\n\tUpdateviacache            Atom = 0x460e\n\tUsemap                    Atom = 0x58e06\n\tValue                     Atom = 0x1505\n\tVar                       Atom = 0x16d03\n\tVideo                     Atom = 0x2e005\n\tWbr                       Atom = 0x56c03\n\tWidth                     Atom = 0x63e05\n\tWorkertype                Atom = 0x7210a\n\tWrap                      Atom = 0x72b04\n\tXmp                       Atom = 0x12f03\n)\n\nconst hash0 = 0x84f70e16\n\nconst maxAtomLen = 25\n\nvar table = [1 << 9]Atom{\n\t0x1:   0x3ff08, // dropzone\n\t0x2:   0x3b08,  // basefont\n\t0x3:   0x23209, // integrity\n\t0x4:   0x43106, // source\n\t0x5:   0x2c09,  // accesskey\n\t0x6:   0x1a06,  // accept\n\t0x7:   0x6c807, // onwheel\n\t0xb:   0x47407, // onkeyup\n\t0xc:   0x32007, // headers\n\t0xd:   0x67306, // scoped\n\t0xe:   0x67909, // onsuspend\n\t0xf:   0x8908,  // noframes\n\t0x10:  0x1fa0b, // crossorigin\n\t0x11:  0x2e407, // onclick\n\t0x12:  0x3f405, // start\n\t0x13:  0x37a0b, // contextmenu\n\t0x14:  0x5e903, // src\n\t0x15:  0x1c404, // cols\n\t0x16:  0xbb06,  // dialog\n\t0x17:  0x47a07, // preload\n\t0x18:  0x3c707, // itemref\n\t0x1b:  0x2f105, // image\n\t0x1d:  0x4ba09, // onloadend\n\t0x1e:  0x45d08, // download\n\t0x1f:  0x46a03, // pre\n\t0x23:  0x2970a, // formmethod\n\t0x24:  0x71303, // svg\n\t0x25:  0xcf01,  // q\n\t0x26:  0x64002, // dt\n\t0x27:  0x1de08, // controls\n\t0x2a:  0x2804,  // body\n\t0x2b:  0xd206,  // strike\n\t0x2c:  0x3910b, // oncuechange\n\t0x2d:  0x4c30b, // onloadstart\n\t0x2e:  0x2fe07, // isindex\n\t0x2f:  0xb202,  // li\n\t0x30:  0x1400b, // playsinline\n\t0x31:  0x34102, // mi\n\t0x32:  0x30806, // applet\n\t0x33:  0x4ce09, // onmessage\n\t0x35:  0x13702, // ol\n\t0x36:  0x1a304, // open\n\t0x39:  0x14d09, // oncanplay\n\t0x3a:  0x6bf09, // onwaiting\n\t0x3b:  0x11908, // oncancel\n\t0x3c:  0x6a908, // onunload\n\t0x3e:  0x53c09, // onoffline\n\t0x3f:  0x1a0e,  // accept-charset\n\t0x40:  0x32004, // head\n\t0x42:  0x3ab09, // ondragend\n\t0x43:  0x1310b, // placeholder\n\t0x44:  0x2b30a, // formtarget\n\t0x45:  0x2540d, // foreignobject\n\t0x47:  0x400c,  // ontimeupdate\n\t0x48:  0xdd0e,  // allowusermedia\n\t0x4a:  0x69c0d, // onbeforeprint\n\t0x4b:  0x5604,  // html\n\t0x4c:  0x9f04,  // span\n\t0x4d:  0x64206, // hgroup\n\t0x4e:  0x16408, // disabled\n\t0x4f:  0x4204,  // time\n\t0x51:  0x42b07, // onfocus\n\t0x53:  0xb00a,  // malignmark\n\t0x55:  0x4650a, // onkeypress\n\t0x56:  0x55805, // class\n\t0x57:  0x1ab08, // colgroup\n\t0x58:  0x33709, // maxlength\n\t0x59:  0x5a908, // progress\n\t0x5b:  0x70405, // style\n\t0x5c:  0x2a10e, // formnovalidate\n\t0x5e:  0x38b06, // oncopy\n\t0x60:  0x26104, // form\n\t0x61:  0xf606,  // footer\n\t0x64:  0x30a,   // radiogroup\n\t0x66:  0xfb04,  // ruby\n\t0x67:  0x4ff0b, // onmousemove\n\t0x68:  0x19d08, // itemprop\n\t0x69:  0x2d70a, // http-equiv\n\t0x6a:  0x15602, // th\n\t0x6c:  0x6e02,  // em\n\t0x6d:  0x38108, // menuitem\n\t0x6e:  0x63106, // select\n\t0x6f:  0x48110, // onlanguagechange\n\t0x70:  0x31f05, // thead\n\t0x71:  0x15c02, // h1\n\t0x72:  0x5e906, // srcdoc\n\t0x75:  0x9604,  // name\n\t0x76:  0x19106, // button\n\t0x77:  0x55504, // desc\n\t0x78:  0x17704, // kind\n\t0x79:  0x1bf05, // color\n\t0x7c:  0x58e06, // usemap\n\t0x7d:  0x30e08, // itemtype\n\t0x7f:  0x6d508, // manifest\n\t0x81:  0x5300c, // onmousewheel\n\t0x82:  0x4dc0b, // onmousedown\n\t0x84:  0xc05,   // param\n\t0x85:  0x2e005, // video\n\t0x86:  0x4910c, // onloadeddata\n\t0x87:  0x6f107, // address\n\t0x8c:  0xef04,  // ping\n\t0x8d:  0x24703, // for\n\t0x8f:  0x62f08, // onselect\n\t0x90:  0x30703, // map\n\t0x92:  0xc01,   // p\n\t0x93:  0x8008,  // reversed\n\t0x94:  0x54d0a, // onpagehide\n\t0x95:  0x3206,  // keygen\n\t0x96:  0x34109, // minlength\n\t0x97:  0x3e40a, // ondragover\n\t0x98:  0x42407, // onerror\n\t0x9a:  0x2107,  // charset\n\t0x9b:  0x29b06, // method\n\t0x9c:  0x101,   // b\n\t0x9d:  0x68208, // ontoggle\n\t0x9e:  0x2bd06, // hidden\n\t0xa0:  0x3f607, // article\n\t0xa2:  0x63906, // onshow\n\t0xa3:  0x64d06, // onsort\n\t0xa5:  0x57b0f, // contenteditable\n\t0xa6:  0x66908, // onsubmit\n\t0xa8:  0x44f09, // oninvalid\n\t0xaa:  0x202,   // br\n\t0xab:  0x10902, // id\n\t0xac:  0x5d04,  // loop\n\t0xad:  0x5630a, // onpageshow\n\t0xb0:  0x2cf04, // href\n\t0xb2:  0x2210a, // figcaption\n\t0xb3:  0x2690e, // onautocomplete\n\t0xb4:  0x49106, // onload\n\t0xb6:  0x9c04,  // rows\n\t0xb7:  0x1a605, // nonce\n\t0xb8:  0x68a14, // onunhandledrejection\n\t0xbb:  0x21306, // center\n\t0xbc:  0x59406, // onplay\n\t0xbd:  0x33f02, // h5\n\t0xbe:  0x49d07, // listing\n\t0xbf:  0x57606, // public\n\t0xc2:  0x23b06, // figure\n\t0xc3:  0x57a04, // icon\n\t0xc4:  0x1ab03, // col\n\t0xc5:  0x47b03, // rel\n\t0xc6:  0xe605,  // media\n\t0xc7:  0x12109, // autofocus\n\t0xc8:  0x19a02, // rt\n\t0xca:  0x2d304, // lang\n\t0xcc:  0x49908, // datalist\n\t0xce:  0x2eb06, // iframe\n\t0xcf:  0x36105, // muted\n\t0xd0:  0x6140a, // onauxclick\n\t0xd2:  0x3c02,  // as\n\t0xd6:  0x3fd06, // ondrop\n\t0xd7:  0x1c90a, // annotation\n\t0xd8:  0x21908, // fieldset\n\t0xdb:  0x2cf08, // hreflang\n\t0xdc:  0x4e70c, // onmouseenter\n\t0xdd:  0x2a402, // mn\n\t0xde:  0xe60a,  // mediagroup\n\t0xdf:  0x9805,  // meter\n\t0xe0:  0x56c03, // wbr\n\t0xe2:  0x63e05, // width\n\t0xe3:  0x2290c, // onafterprint\n\t0xe4:  0x30505, // ismap\n\t0xe5:  0x1505,  // value\n\t0xe7:  0x1303,  // nav\n\t0xe8:  0x54508, // ononline\n\t0xe9:  0xb604,  // mark\n\t0xea:  0xc303,  // low\n\t0xeb:  0x3ee0b, // ondragstart\n\t0xef:  0x12f03, // xmp\n\t0xf0:  0x22407, // caption\n\t0xf1:  0xd904,  // type\n\t0xf2:  0x70907, // summary\n\t0xf3:  0x6802,  // tt\n\t0xf4:  0x20809, // translate\n\t0xf5:  0x1870a, // blockquote\n\t0xf8:  0x15702, // hr\n\t0xfa:  0x2705,  // tbody\n\t0xfc:  0x7b07,  // picture\n\t0xfd:  0x5206,  // height\n\t0xfe:  0x19c04, // cite\n\t0xff:  0x2501,  // s\n\t0x101: 0xff05,  // async\n\t0x102: 0x56f07, // onpaste\n\t0x103: 0x19507, // onabort\n\t0x104: 0x2b706, // target\n\t0x105: 0x14b03, // bdo\n\t0x106: 0x1f006, // coords\n\t0x107: 0x5e108, // onresize\n\t0x108: 0x71908, // template\n\t0x10a: 0x3a02,  // rb\n\t0x10b: 0x2a50a, // novalidate\n\t0x10c: 0x460e,  // updateviacache\n\t0x10d: 0x71003, // sup\n\t0x10e: 0x6c07,  // noembed\n\t0x10f: 0x16b03, // div\n\t0x110: 0x6f707, // srclang\n\t0x111: 0x17a09, // draggable\n\t0x112: 0x67305, // scope\n\t0x113: 0x5905,  // label\n\t0x114: 0x22f02, // rp\n\t0x115: 0x23f08, // required\n\t0x116: 0x3780d, // oncontextmenu\n\t0x117: 0x5e504, // size\n\t0x118: 0x5b00a, // spellcheck\n\t0x119: 0x3f04,  // font\n\t0x11a: 0x9c07,  // rowspan\n\t0x11b: 0x10a07, // default\n\t0x11d: 0x44307, // oninput\n\t0x11e: 0x38506, // itemid\n\t0x11f: 0x5ee04, // code\n\t0x120: 0xaa07,  // acronym\n\t0x121: 0x3b04,  // base\n\t0x125: 0x2470d, // foreignObject\n\t0x126: 0x2ca04, // high\n\t0x127: 0x3cb0e, // referrerpolicy\n\t0x128: 0x33703, // max\n\t0x129: 0x59d0a, // onpopstate\n\t0x12a: 0x2fc02, // h4\n\t0x12b: 0x4ac04, // meta\n\t0x12c: 0x17305, // blink\n\t0x12e: 0x5f508, // onscroll\n\t0x12f: 0x59409, // onplaying\n\t0x130: 0xc113,  // allowpaymentrequest\n\t0x131: 0x19a03, // rtc\n\t0x132: 0x72b04, // wrap\n\t0x134: 0x8b08,  // frameset\n\t0x135: 0x32605, // small\n\t0x137: 0x32006, // header\n\t0x138: 0x40409, // onemptied\n\t0x139: 0x34902, // h6\n\t0x13a: 0x35908, // multiple\n\t0x13c: 0x52a06, // prompt\n\t0x13f: 0x28e09, // challenge\n\t0x141: 0x4370c, // onhashchange\n\t0x142: 0x57b07, // content\n\t0x143: 0x1c90e, // annotation-xml\n\t0x144: 0x36607, // onclose\n\t0x145: 0x14d10, // oncanplaythrough\n\t0x148: 0x5170b, // onmouseover\n\t0x149: 0x64f08, // sortable\n\t0x14a: 0xa402,  // mo\n\t0x14b: 0x2cd02, // h3\n\t0x14c: 0x2c406, // script\n\t0x14d: 0x41d07, // onended\n\t0x14f: 0x64706, // poster\n\t0x150: 0x7210a, // workertype\n\t0x153: 0x1f505, // shape\n\t0x154: 0x4,     // abbr\n\t0x155: 0x1,     // a\n\t0x156: 0x2bf02, // dd\n\t0x157: 0x71606, // system\n\t0x158: 0x4ce0e, // onmessageerror\n\t0x159: 0x36b08, // seamless\n\t0x15a: 0x2610a, // formaction\n\t0x15b: 0x6e106, // option\n\t0x15c: 0x31d04, // math\n\t0x15d: 0x62609, // onseeking\n\t0x15e: 0x39c05, // oncut\n\t0x15f: 0x44c03, // del\n\t0x160: 0x11005, // title\n\t0x161: 0x11505, // audio\n\t0x162: 0x63108, // selected\n\t0x165: 0x3b40b, // ondragenter\n\t0x166: 0x46e06, // spacer\n\t0x167: 0x4a410, // onloadedmetadata\n\t0x168: 0x44505, // input\n\t0x16a: 0x58505, // table\n\t0x16b: 0x41508, // onchange\n\t0x16e: 0x5f005, // defer\n\t0x171: 0x50a0a, // onmouseout\n\t0x172: 0x20504, // slot\n\t0x175: 0x3704,  // nobr\n\t0x177: 0x1d707, // command\n\t0x17a: 0x7207,  // details\n\t0x17b: 0x38104, // menu\n\t0x17c: 0xb903,  // kbd\n\t0x17d: 0x57304, // step\n\t0x17e: 0x20303, // ins\n\t0x17f: 0x13c08, // autoplay\n\t0x182: 0x34103, // min\n\t0x183: 0x17404, // link\n\t0x185: 0x40d10, // ondurationchange\n\t0x186: 0x9202,  // td\n\t0x187: 0x8b05,  // frame\n\t0x18a: 0x2ab08, // datetime\n\t0x18b: 0x44509, // inputmode\n\t0x18c: 0x35108, // readonly\n\t0x18d: 0x21104, // face\n\t0x18f: 0x5e505, // sizes\n\t0x191: 0x4b208, // tabindex\n\t0x192: 0x6db06, // strong\n\t0x193: 0xba03,  // bdi\n\t0x194: 0x6fe06, // srcset\n\t0x196: 0x67202, // ms\n\t0x197: 0x5b507, // checked\n\t0x198: 0xb105,  // align\n\t0x199: 0x1e507, // section\n\t0x19b: 0x6e05,  // embed\n\t0x19d: 0x15e07, // bgsound\n\t0x1a2: 0x49d04, // list\n\t0x1a3: 0x61e08, // onseeked\n\t0x1a4: 0x66009, // onstorage\n\t0x1a5: 0x2f603, // img\n\t0x1a6: 0xf505,  // tfoot\n\t0x1a9: 0x26913, // onautocompleteerror\n\t0x1aa: 0x5fd19, // onsecuritypolicyviolation\n\t0x1ad: 0x9303,  // dir\n\t0x1ae: 0x9307,  // dirname\n\t0x1b0: 0x5a70a, // onprogress\n\t0x1b2: 0x65709, // onstalled\n\t0x1b5: 0x66f09, // itemscope\n\t0x1b6: 0x49904, // data\n\t0x1b7: 0x3d90b, // ondragleave\n\t0x1b8: 0x56102, // h2\n\t0x1b9: 0x2f706, // mglyph\n\t0x1ba: 0x16502, // is\n\t0x1bb: 0x6e50e, // onbeforeunload\n\t0x1bc: 0x2830d, // typemustmatch\n\t0x1bd: 0x3ab06, // ondrag\n\t0x1be: 0x5da07, // onreset\n\t0x1c0: 0x51106, // output\n\t0x1c1: 0x12907, // sandbox\n\t0x1c2: 0x1b209, // plaintext\n\t0x1c4: 0x34c08, // textarea\n\t0x1c7: 0xd607,  // keytype\n\t0x1c8: 0x34b05, // mtext\n\t0x1c9: 0x6b10e, // onvolumechange\n\t0x1ca: 0x1ea06, // onblur\n\t0x1cb: 0x58a07, // onpause\n\t0x1cd: 0x5bc0c, // onratechange\n\t0x1ce: 0x10705, // aside\n\t0x1cf: 0x6cf07, // optimum\n\t0x1d1: 0x45809, // onkeydown\n\t0x1d2: 0x1c407, // colspan\n\t0x1d3: 0x1004,  // main\n\t0x1d4: 0x66b03, // sub\n\t0x1d5: 0x25b06, // object\n\t0x1d6: 0x55c06, // search\n\t0x1d7: 0x37206, // sorted\n\t0x1d8: 0x17003, // big\n\t0x1d9: 0xb01,   // u\n\t0x1db: 0x26b0c, // autocomplete\n\t0x1dc: 0xcc02,  // tr\n\t0x1dd: 0xf303,  // alt\n\t0x1df: 0x7804,  // samp\n\t0x1e0: 0x5c812, // onrejectionhandled\n\t0x1e1: 0x4f30c, // onmouseleave\n\t0x1e2: 0x28007, // enctype\n\t0x1e3: 0xa208,  // nomodule\n\t0x1e5: 0x3280f, // allowfullscreen\n\t0x1e6: 0x5f08,  // optgroup\n\t0x1e8: 0x27c0b, // formenctype\n\t0x1e9: 0x18106, // legend\n\t0x1ea: 0x10306, // canvas\n\t0x1eb: 0x6607,  // pattern\n\t0x1ec: 0x2c208, // noscript\n\t0x1ed: 0x601,   // i\n\t0x1ee: 0x5d602, // dl\n\t0x1ef: 0xa702,  // ul\n\t0x1f2: 0x52209, // onmouseup\n\t0x1f4: 0x1ba05, // track\n\t0x1f7: 0x3a10a, // ondblclick\n\t0x1f8: 0x3bf0a, // ondragexit\n\t0x1fa: 0x8703,  // dfn\n\t0x1fc: 0x26506, // action\n\t0x1fd: 0x35004, // area\n\t0x1fe: 0x31607, // marquee\n\t0x1ff: 0x16d03, // var\n}\n\nconst atomText = \"abbradiogrouparamainavalueaccept-charsetbodyaccesskeygenobrb\" +\n\t\"asefontimeupdateviacacheightmlabelooptgroupatternoembedetail\" +\n\t\"sampictureversedfnoframesetdirnameterowspanomoduleacronymali\" +\n\t\"gnmarkbdialogallowpaymentrequestrikeytypeallowusermediagroup\" +\n\t\"ingaltfooterubyasyncanvasidefaultitleaudioncancelautofocusan\" +\n\t\"dboxmplaceholderautoplaysinlinebdoncanplaythrough1bgsoundisa\" +\n\t\"bledivarbigblinkindraggablegendblockquotebuttonabortcitempro\" +\n\t\"penoncecolgrouplaintextrackcolorcolspannotation-xmlcommandco\" +\n\t\"ntrolsectionblurcoordshapecrossoriginslotranslatefacenterfie\" +\n\t\"ldsetfigcaptionafterprintegrityfigurequiredforeignObjectfore\" +\n\t\"ignobjectformactionautocompleteerrorformenctypemustmatchalle\" +\n\t\"ngeformmethodformnovalidatetimeformtargethiddenoscripthigh3h\" +\n\t\"reflanghttp-equivideonclickiframeimageimglyph4isindexismappl\" +\n\t\"etitemtypemarqueematheadersmallowfullscreenmaxlength5minleng\" +\n\t\"th6mtextareadonlymultiplemutedoncloseamlessortedoncontextmen\" +\n\t\"uitemidoncopyoncuechangeoncutondblclickondragendondragentero\" +\n\t\"ndragexitemreferrerpolicyondragleaveondragoverondragstarticl\" +\n\t\"eondropzonemptiedondurationchangeonendedonerroronfocusourceo\" +\n\t\"nhashchangeoninputmodeloninvalidonkeydownloadonkeypresspacer\" +\n\t\"onkeyupreloadonlanguagechangeonloadeddatalistingonloadedmeta\" +\n\t\"databindexonloadendonloadstartonmessageerroronmousedownonmou\" +\n\t\"seenteronmouseleaveonmousemoveonmouseoutputonmouseoveronmous\" +\n\t\"eupromptonmousewheelonofflineononlineonpagehidesclassearch2o\" +\n\t\"npageshowbronpastepublicontenteditableonpausemaponplayingonp\" +\n\t\"opstateonprogresspellcheckedonratechangeonrejectionhandledon\" +\n\t\"resetonresizesrcdocodeferonscrollonsecuritypolicyviolationau\" +\n\t\"xclickonseekedonseekingonselectedonshowidthgrouposteronsorta\" +\n\t\"bleonstalledonstorageonsubmitemscopedonsuspendontoggleonunha\" +\n\t\"ndledrejectionbeforeprintonunloadonvolumechangeonwaitingonwh\" +\n\t\"eeloptimumanifestrongoptionbeforeunloaddressrclangsrcsetstyl\" +\n\t\"esummarysupsvgsystemplateworkertypewrap\"\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/charset/charset.go",
    "content": "// Copyright 2013 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// Package charset provides common text encodings for HTML documents.\n//\n// The mapping from encoding labels to encodings is defined at\n// https://encoding.spec.whatwg.org/.\npackage charset // import \"golang.org/x/net/html/charset\"\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"mime\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"golang.org/x/net/html\"\n\t\"golang.org/x/text/encoding\"\n\t\"golang.org/x/text/encoding/charmap\"\n\t\"golang.org/x/text/encoding/htmlindex\"\n\t\"golang.org/x/text/transform\"\n)\n\n// Lookup returns the encoding with the specified label, and its canonical\n// name. It returns nil and the empty string if label is not one of the\n// standard encodings for HTML. Matching is case-insensitive and ignores\n// leading and trailing whitespace. Encoders will use HTML escape sequences for\n// runes that are not supported by the character set.\nfunc Lookup(label string) (e encoding.Encoding, name string) {\n\te, err := htmlindex.Get(label)\n\tif err != nil {\n\t\treturn nil, \"\"\n\t}\n\tname, _ = htmlindex.Name(e)\n\treturn &htmlEncoding{e}, name\n}\n\ntype htmlEncoding struct{ encoding.Encoding }\n\nfunc (h *htmlEncoding) NewEncoder() *encoding.Encoder {\n\t// HTML requires a non-terminating legacy encoder. We use HTML escapes to\n\t// substitute unsupported code points.\n\treturn encoding.HTMLEscapeUnsupported(h.Encoding.NewEncoder())\n}\n\n// DetermineEncoding determines the encoding of an HTML document by examining\n// up to the first 1024 bytes of content and the declared Content-Type.\n//\n// See http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding\nfunc DetermineEncoding(content []byte, contentType string) (e encoding.Encoding, name string, certain bool) {\n\tif len(content) > 1024 {\n\t\tcontent = content[:1024]\n\t}\n\n\tfor _, b := range boms {\n\t\tif bytes.HasPrefix(content, b.bom) {\n\t\t\te, name = Lookup(b.enc)\n\t\t\treturn e, name, true\n\t\t}\n\t}\n\n\tif _, params, err := mime.ParseMediaType(contentType); err == nil {\n\t\tif cs, ok := params[\"charset\"]; ok {\n\t\t\tif e, name = Lookup(cs); e != nil {\n\t\t\t\treturn e, name, true\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(content) > 0 {\n\t\te, name = prescan(content)\n\t\tif e != nil {\n\t\t\treturn e, name, false\n\t\t}\n\t}\n\n\t// Try to detect UTF-8.\n\t// First eliminate any partial rune at the end.\n\tfor i := len(content) - 1; i >= 0 && i > len(content)-4; i-- {\n\t\tb := content[i]\n\t\tif b < 0x80 {\n\t\t\tbreak\n\t\t}\n\t\tif utf8.RuneStart(b) {\n\t\t\tcontent = content[:i]\n\t\t\tbreak\n\t\t}\n\t}\n\thasHighBit := false\n\tfor _, c := range content {\n\t\tif c >= 0x80 {\n\t\t\thasHighBit = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif hasHighBit && utf8.Valid(content) {\n\t\treturn encoding.Nop, \"utf-8\", false\n\t}\n\n\t// TODO: change default depending on user's locale?\n\treturn charmap.Windows1252, \"windows-1252\", false\n}\n\n// NewReader returns an io.Reader that converts the content of r to UTF-8.\n// It calls DetermineEncoding to find out what r's encoding is.\nfunc NewReader(r io.Reader, contentType string) (io.Reader, error) {\n\tpreview := make([]byte, 1024)\n\tn, err := io.ReadFull(r, preview)\n\tswitch {\n\tcase err == io.ErrUnexpectedEOF:\n\t\tpreview = preview[:n]\n\t\tr = bytes.NewReader(preview)\n\tcase err != nil:\n\t\treturn nil, err\n\tdefault:\n\t\tr = io.MultiReader(bytes.NewReader(preview), r)\n\t}\n\n\tif e, _, _ := DetermineEncoding(preview, contentType); e != encoding.Nop {\n\t\tr = transform.NewReader(r, e.NewDecoder())\n\t}\n\treturn r, nil\n}\n\n// NewReaderLabel returns a reader that converts from the specified charset to\n// UTF-8. It uses Lookup to find the encoding that corresponds to label, and\n// returns an error if Lookup returns nil. It is suitable for use as\n// encoding/xml.Decoder's CharsetReader function.\nfunc NewReaderLabel(label string, input io.Reader) (io.Reader, error) {\n\te, _ := Lookup(label)\n\tif e == nil {\n\t\treturn nil, fmt.Errorf(\"unsupported charset: %q\", label)\n\t}\n\treturn transform.NewReader(input, e.NewDecoder()), nil\n}\n\nfunc prescan(content []byte) (e encoding.Encoding, name string) {\n\tz := html.NewTokenizer(bytes.NewReader(content))\n\tfor {\n\t\tswitch z.Next() {\n\t\tcase html.ErrorToken:\n\t\t\treturn nil, \"\"\n\n\t\tcase html.StartTagToken, html.SelfClosingTagToken:\n\t\t\ttagName, hasAttr := z.TagName()\n\t\t\tif !bytes.Equal(tagName, []byte(\"meta\")) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tattrList := make(map[string]bool)\n\t\t\tgotPragma := false\n\n\t\t\tconst (\n\t\t\t\tdontKnow = iota\n\t\t\t\tdoNeedPragma\n\t\t\t\tdoNotNeedPragma\n\t\t\t)\n\t\t\tneedPragma := dontKnow\n\n\t\t\tname = \"\"\n\t\t\te = nil\n\t\t\tfor hasAttr {\n\t\t\t\tvar key, val []byte\n\t\t\t\tkey, val, hasAttr = z.TagAttr()\n\t\t\t\tks := string(key)\n\t\t\t\tif attrList[ks] {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tattrList[ks] = true\n\t\t\t\tfor i, c := range val {\n\t\t\t\t\tif 'A' <= c && c <= 'Z' {\n\t\t\t\t\t\tval[i] = c + 0x20\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tswitch ks {\n\t\t\t\tcase \"http-equiv\":\n\t\t\t\t\tif bytes.Equal(val, []byte(\"content-type\")) {\n\t\t\t\t\t\tgotPragma = true\n\t\t\t\t\t}\n\n\t\t\t\tcase \"content\":\n\t\t\t\t\tif e == nil {\n\t\t\t\t\t\tname = fromMetaElement(string(val))\n\t\t\t\t\t\tif name != \"\" {\n\t\t\t\t\t\t\te, name = Lookup(name)\n\t\t\t\t\t\t\tif e != nil {\n\t\t\t\t\t\t\t\tneedPragma = doNeedPragma\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"charset\":\n\t\t\t\t\te, name = Lookup(string(val))\n\t\t\t\t\tneedPragma = doNotNeedPragma\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif needPragma == dontKnow || needPragma == doNeedPragma && !gotPragma {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(name, \"utf-16\") {\n\t\t\t\tname = \"utf-8\"\n\t\t\t\te = encoding.Nop\n\t\t\t}\n\n\t\t\tif e != nil {\n\t\t\t\treturn e, name\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc fromMetaElement(s string) string {\n\tfor s != \"\" {\n\t\tcsLoc := strings.Index(s, \"charset\")\n\t\tif csLoc == -1 {\n\t\t\treturn \"\"\n\t\t}\n\t\ts = s[csLoc+len(\"charset\"):]\n\t\ts = strings.TrimLeft(s, \" \\t\\n\\f\\r\")\n\t\tif !strings.HasPrefix(s, \"=\") {\n\t\t\tcontinue\n\t\t}\n\t\ts = s[1:]\n\t\ts = strings.TrimLeft(s, \" \\t\\n\\f\\r\")\n\t\tif s == \"\" {\n\t\t\treturn \"\"\n\t\t}\n\t\tif q := s[0]; q == '\"' || q == '\\'' {\n\t\t\ts = s[1:]\n\t\t\tcloseQuote := strings.IndexRune(s, rune(q))\n\t\t\tif closeQuote == -1 {\n\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\treturn s[:closeQuote]\n\t\t}\n\n\t\tend := strings.IndexAny(s, \"; \\t\\n\\f\\r\")\n\t\tif end == -1 {\n\t\t\tend = len(s)\n\t\t}\n\t\treturn s[:end]\n\t}\n\treturn \"\"\n}\n\nvar boms = []struct {\n\tbom []byte\n\tenc string\n}{\n\t{[]byte{0xfe, 0xff}, \"utf-16be\"},\n\t{[]byte{0xff, 0xfe}, \"utf-16le\"},\n\t{[]byte{0xef, 0xbb, 0xbf}, \"utf-8\"},\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/const.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 html\n\n// Section 12.2.4.2 of the HTML5 specification says \"The following elements\n// have varying levels of special parsing rules\".\n// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements\nvar isSpecialElementMap = map[string]bool{\n\t\"address\":    true,\n\t\"applet\":     true,\n\t\"area\":       true,\n\t\"article\":    true,\n\t\"aside\":      true,\n\t\"base\":       true,\n\t\"basefont\":   true,\n\t\"bgsound\":    true,\n\t\"blockquote\": true,\n\t\"body\":       true,\n\t\"br\":         true,\n\t\"button\":     true,\n\t\"caption\":    true,\n\t\"center\":     true,\n\t\"col\":        true,\n\t\"colgroup\":   true,\n\t\"dd\":         true,\n\t\"details\":    true,\n\t\"dir\":        true,\n\t\"div\":        true,\n\t\"dl\":         true,\n\t\"dt\":         true,\n\t\"embed\":      true,\n\t\"fieldset\":   true,\n\t\"figcaption\": true,\n\t\"figure\":     true,\n\t\"footer\":     true,\n\t\"form\":       true,\n\t\"frame\":      true,\n\t\"frameset\":   true,\n\t\"h1\":         true,\n\t\"h2\":         true,\n\t\"h3\":         true,\n\t\"h4\":         true,\n\t\"h5\":         true,\n\t\"h6\":         true,\n\t\"head\":       true,\n\t\"header\":     true,\n\t\"hgroup\":     true,\n\t\"hr\":         true,\n\t\"html\":       true,\n\t\"iframe\":     true,\n\t\"img\":        true,\n\t\"input\":      true,\n\t\"keygen\":     true, // \"keygen\" has been removed from the spec, but are kept here for backwards compatibility.\n\t\"li\":         true,\n\t\"link\":       true,\n\t\"listing\":    true,\n\t\"main\":       true,\n\t\"marquee\":    true,\n\t\"menu\":       true,\n\t\"meta\":       true,\n\t\"nav\":        true,\n\t\"noembed\":    true,\n\t\"noframes\":   true,\n\t\"noscript\":   true,\n\t\"object\":     true,\n\t\"ol\":         true,\n\t\"p\":          true,\n\t\"param\":      true,\n\t\"plaintext\":  true,\n\t\"pre\":        true,\n\t\"script\":     true,\n\t\"section\":    true,\n\t\"select\":     true,\n\t\"source\":     true,\n\t\"style\":      true,\n\t\"summary\":    true,\n\t\"table\":      true,\n\t\"tbody\":      true,\n\t\"td\":         true,\n\t\"template\":   true,\n\t\"textarea\":   true,\n\t\"tfoot\":      true,\n\t\"th\":         true,\n\t\"thead\":      true,\n\t\"title\":      true,\n\t\"tr\":         true,\n\t\"track\":      true,\n\t\"ul\":         true,\n\t\"wbr\":        true,\n\t\"xmp\":        true,\n}\n\nfunc isSpecialElement(element *Node) bool {\n\tswitch element.Namespace {\n\tcase \"\", \"html\":\n\t\treturn isSpecialElementMap[element.Data]\n\tcase \"math\":\n\t\tswitch element.Data {\n\t\tcase \"mi\", \"mo\", \"mn\", \"ms\", \"mtext\", \"annotation-xml\":\n\t\t\treturn true\n\t\t}\n\tcase \"svg\":\n\t\tswitch element.Data {\n\t\tcase \"foreignObject\", \"desc\", \"title\":\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/doc.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/*\nPackage html implements an HTML5-compliant tokenizer and parser.\n\nTokenization is done by creating a Tokenizer for an io.Reader r. It is the\ncaller's responsibility to ensure that r provides UTF-8 encoded HTML.\n\n\tz := html.NewTokenizer(r)\n\nGiven a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(),\nwhich parses the next token and returns its type, or an error:\n\n\tfor {\n\t\ttt := z.Next()\n\t\tif tt == html.ErrorToken {\n\t\t\t// ...\n\t\t\treturn ...\n\t\t}\n\t\t// Process the current token.\n\t}\n\nThere are two APIs for retrieving the current token. The high-level API is to\ncall Token; the low-level API is to call Text or TagName / TagAttr. Both APIs\nallow optionally calling Raw after Next but before Token, Text, TagName, or\nTagAttr. In EBNF notation, the valid call sequence per token is:\n\n\tNext {Raw} [ Token | Text | TagName {TagAttr} ]\n\nToken returns an independent data structure that completely describes a token.\nEntities (such as \"&lt;\") are unescaped, tag names and attribute keys are\nlower-cased, and attributes are collected into a []Attribute. For example:\n\n\tfor {\n\t\tif z.Next() == html.ErrorToken {\n\t\t\t// Returning io.EOF indicates success.\n\t\t\treturn z.Err()\n\t\t}\n\t\temitToken(z.Token())\n\t}\n\nThe low-level API performs fewer allocations and copies, but the contents of\nthe []byte values returned by Text, TagName and TagAttr may change on the next\ncall to Next. For example, to extract an HTML page's anchor text:\n\n\tdepth := 0\n\tfor {\n\t\ttt := z.Next()\n\t\tswitch tt {\n\t\tcase html.ErrorToken:\n\t\t\treturn z.Err()\n\t\tcase html.TextToken:\n\t\t\tif depth > 0 {\n\t\t\t\t// emitBytes should copy the []byte it receives,\n\t\t\t\t// if it doesn't process it immediately.\n\t\t\t\temitBytes(z.Text())\n\t\t\t}\n\t\tcase html.StartTagToken, html.EndTagToken:\n\t\t\ttn, _ := z.TagName()\n\t\t\tif len(tn) == 1 && tn[0] == 'a' {\n\t\t\t\tif tt == html.StartTagToken {\n\t\t\t\t\tdepth++\n\t\t\t\t} else {\n\t\t\t\t\tdepth--\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\nParsing is done by calling Parse with an io.Reader, which returns the root of\nthe parse tree (the document element) as a *Node. It is the caller's\nresponsibility to ensure that the Reader provides UTF-8 encoded HTML. For\nexample, to process each anchor node in depth-first order:\n\n\tdoc, err := html.Parse(r)\n\tif err != nil {\n\t\t// ...\n\t}\n\tfor n := range doc.Descendants() {\n\t\tif n.Type == html.ElementNode && n.Data == \"a\" {\n\t\t\t// Do something with n...\n\t\t}\n\t}\n\nThe relevant specifications include:\nhttps://html.spec.whatwg.org/multipage/syntax.html and\nhttps://html.spec.whatwg.org/multipage/syntax.html#tokenization\n\n# Security Considerations\n\nCare should be taken when parsing and interpreting HTML, whether full documents\nor fragments, within the framework of the HTML specification, especially with\nregard to untrusted inputs.\n\nThis package provides both a tokenizer and a parser, which implement the\ntokenization, and tokenization and tree construction stages of the WHATWG HTML\nparsing specification respectively. While the tokenizer parses and normalizes\nindividual HTML tokens, only the parser constructs the DOM tree from the\ntokenized HTML, as described in the tree construction stage of the\nspecification, dynamically modifying or extending the document's DOM tree.\n\nIf your use case requires semantically well-formed HTML documents, as defined by\nthe WHATWG specification, the parser should be used rather than the tokenizer.\n\nIn security contexts, if trust decisions are being made using the tokenized or\nparsed content, the input must be re-serialized (for instance by using Render or\nToken.String) in order for those trust decisions to hold, as the process of\ntokenization or parsing may alter the content.\n*/\npackage html // import \"golang.org/x/net/html\"\n\n// The tokenization algorithm implemented by this package is not a line-by-line\n// transliteration of the relatively verbose state-machine in the WHATWG\n// specification. A more direct approach is used instead, where the program\n// counter implies the state, such as whether it is tokenizing a tag or a text\n// node. Specification compliance is verified by checking expected and actual\n// outputs over a test suite rather than aiming for algorithmic fidelity.\n\n// TODO(nigeltao): Does a DOM API belong in this package or a separate one?\n// TODO(nigeltao): How does parsing interact with a JavaScript engine?\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/doctype.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 html\n\nimport (\n\t\"strings\"\n)\n\n// parseDoctype parses the data from a DoctypeToken into a name,\n// public identifier, and system identifier. It returns a Node whose Type\n// is DoctypeNode, whose Data is the name, and which has attributes\n// named \"system\" and \"public\" for the two identifiers if they were present.\n// quirks is whether the document should be parsed in \"quirks mode\".\nfunc parseDoctype(s string) (n *Node, quirks bool) {\n\tn = &Node{Type: DoctypeNode}\n\n\t// Find the name.\n\tspace := strings.IndexAny(s, whitespace)\n\tif space == -1 {\n\t\tspace = len(s)\n\t}\n\tn.Data = s[:space]\n\t// The comparison to \"html\" is case-sensitive.\n\tif n.Data != \"html\" {\n\t\tquirks = true\n\t}\n\tn.Data = strings.ToLower(n.Data)\n\ts = strings.TrimLeft(s[space:], whitespace)\n\n\tif len(s) < 6 {\n\t\t// It can't start with \"PUBLIC\" or \"SYSTEM\".\n\t\t// Ignore the rest of the string.\n\t\treturn n, quirks || s != \"\"\n\t}\n\n\tkey := strings.ToLower(s[:6])\n\ts = s[6:]\n\tfor key == \"public\" || key == \"system\" {\n\t\ts = strings.TrimLeft(s, whitespace)\n\t\tif s == \"\" {\n\t\t\tbreak\n\t\t}\n\t\tquote := s[0]\n\t\tif quote != '\"' && quote != '\\'' {\n\t\t\tbreak\n\t\t}\n\t\ts = s[1:]\n\t\tq := strings.IndexRune(s, rune(quote))\n\t\tvar id string\n\t\tif q == -1 {\n\t\t\tid = s\n\t\t\ts = \"\"\n\t\t} else {\n\t\t\tid = s[:q]\n\t\t\ts = s[q+1:]\n\t\t}\n\t\tn.Attr = append(n.Attr, Attribute{Key: key, Val: id})\n\t\tif key == \"public\" {\n\t\t\tkey = \"system\"\n\t\t} else {\n\t\t\tkey = \"\"\n\t\t}\n\t}\n\n\tif key != \"\" || s != \"\" {\n\t\tquirks = true\n\t} else if len(n.Attr) > 0 {\n\t\tif n.Attr[0].Key == \"public\" {\n\t\t\tpublic := strings.ToLower(n.Attr[0].Val)\n\t\t\tswitch public {\n\t\t\tcase \"-//w3o//dtd w3 html strict 3.0//en//\", \"-/w3d/dtd html 4.0 transitional/en\", \"html\":\n\t\t\t\tquirks = true\n\t\t\tdefault:\n\t\t\t\tfor _, q := range quirkyIDs {\n\t\t\t\t\tif strings.HasPrefix(public, q) {\n\t\t\t\t\t\tquirks = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// The following two public IDs only cause quirks mode if there is no system ID.\n\t\t\tif len(n.Attr) == 1 && (strings.HasPrefix(public, \"-//w3c//dtd html 4.01 frameset//\") ||\n\t\t\t\tstrings.HasPrefix(public, \"-//w3c//dtd html 4.01 transitional//\")) {\n\t\t\t\tquirks = true\n\t\t\t}\n\t\t}\n\t\tif lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == \"system\" &&\n\t\t\tstrings.EqualFold(lastAttr.Val, \"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd\") {\n\t\t\tquirks = true\n\t\t}\n\t}\n\n\treturn n, quirks\n}\n\n// quirkyIDs is a list of public doctype identifiers that cause a document\n// to be interpreted in quirks mode. The identifiers should be in lower case.\nvar quirkyIDs = []string{\n\t\"+//silmaril//dtd html pro v0r11 19970101//\",\n\t\"-//advasoft ltd//dtd html 3.0 aswedit + extensions//\",\n\t\"-//as//dtd html 3.0 aswedit + extensions//\",\n\t\"-//ietf//dtd html 2.0 level 1//\",\n\t\"-//ietf//dtd html 2.0 level 2//\",\n\t\"-//ietf//dtd html 2.0 strict level 1//\",\n\t\"-//ietf//dtd html 2.0 strict level 2//\",\n\t\"-//ietf//dtd html 2.0 strict//\",\n\t\"-//ietf//dtd html 2.0//\",\n\t\"-//ietf//dtd html 2.1e//\",\n\t\"-//ietf//dtd html 3.0//\",\n\t\"-//ietf//dtd html 3.2 final//\",\n\t\"-//ietf//dtd html 3.2//\",\n\t\"-//ietf//dtd html 3//\",\n\t\"-//ietf//dtd html level 0//\",\n\t\"-//ietf//dtd html level 1//\",\n\t\"-//ietf//dtd html level 2//\",\n\t\"-//ietf//dtd html level 3//\",\n\t\"-//ietf//dtd html strict level 0//\",\n\t\"-//ietf//dtd html strict level 1//\",\n\t\"-//ietf//dtd html strict level 2//\",\n\t\"-//ietf//dtd html strict level 3//\",\n\t\"-//ietf//dtd html strict//\",\n\t\"-//ietf//dtd html//\",\n\t\"-//metrius//dtd metrius presentational//\",\n\t\"-//microsoft//dtd internet explorer 2.0 html strict//\",\n\t\"-//microsoft//dtd internet explorer 2.0 html//\",\n\t\"-//microsoft//dtd internet explorer 2.0 tables//\",\n\t\"-//microsoft//dtd internet explorer 3.0 html strict//\",\n\t\"-//microsoft//dtd internet explorer 3.0 html//\",\n\t\"-//microsoft//dtd internet explorer 3.0 tables//\",\n\t\"-//netscape comm. corp.//dtd html//\",\n\t\"-//netscape comm. corp.//dtd strict html//\",\n\t\"-//o'reilly and associates//dtd html 2.0//\",\n\t\"-//o'reilly and associates//dtd html extended 1.0//\",\n\t\"-//o'reilly and associates//dtd html extended relaxed 1.0//\",\n\t\"-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//\",\n\t\"-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//\",\n\t\"-//spyglass//dtd html 2.0 extended//\",\n\t\"-//sq//dtd html 2.0 hotmetal + extensions//\",\n\t\"-//sun microsystems corp.//dtd hotjava html//\",\n\t\"-//sun microsystems corp.//dtd hotjava strict html//\",\n\t\"-//w3c//dtd html 3 1995-03-24//\",\n\t\"-//w3c//dtd html 3.2 draft//\",\n\t\"-//w3c//dtd html 3.2 final//\",\n\t\"-//w3c//dtd html 3.2//\",\n\t\"-//w3c//dtd html 3.2s draft//\",\n\t\"-//w3c//dtd html 4.0 frameset//\",\n\t\"-//w3c//dtd html 4.0 transitional//\",\n\t\"-//w3c//dtd html experimental 19960712//\",\n\t\"-//w3c//dtd html experimental 970421//\",\n\t\"-//w3c//dtd w3 html//\",\n\t\"-//w3o//dtd w3 html 3.0//\",\n\t\"-//webtechs//dtd mozilla html 2.0//\",\n\t\"-//webtechs//dtd mozilla html//\",\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/entity.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 html\n\n// All entities that do not end with ';' are 6 or fewer bytes long.\nconst longestEntityWithoutSemicolon = 6\n\n// entity is a map from HTML entity names to their values. The semicolon matters:\n// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references\n// lists both \"amp\" and \"amp;\" as two separate entries.\n//\n// Note that the HTML5 list is larger than the HTML4 list at\n// http://www.w3.org/TR/html4/sgml/entities.html\nvar entity = map[string]rune{\n\t\"AElig;\":                           '\\U000000C6',\n\t\"AMP;\":                             '\\U00000026',\n\t\"Aacute;\":                          '\\U000000C1',\n\t\"Abreve;\":                          '\\U00000102',\n\t\"Acirc;\":                           '\\U000000C2',\n\t\"Acy;\":                             '\\U00000410',\n\t\"Afr;\":                             '\\U0001D504',\n\t\"Agrave;\":                          '\\U000000C0',\n\t\"Alpha;\":                           '\\U00000391',\n\t\"Amacr;\":                           '\\U00000100',\n\t\"And;\":                             '\\U00002A53',\n\t\"Aogon;\":                           '\\U00000104',\n\t\"Aopf;\":                            '\\U0001D538',\n\t\"ApplyFunction;\":                   '\\U00002061',\n\t\"Aring;\":                           '\\U000000C5',\n\t\"Ascr;\":                            '\\U0001D49C',\n\t\"Assign;\":                          '\\U00002254',\n\t\"Atilde;\":                          '\\U000000C3',\n\t\"Auml;\":                            '\\U000000C4',\n\t\"Backslash;\":                       '\\U00002216',\n\t\"Barv;\":                            '\\U00002AE7',\n\t\"Barwed;\":                          '\\U00002306',\n\t\"Bcy;\":                             '\\U00000411',\n\t\"Because;\":                         '\\U00002235',\n\t\"Bernoullis;\":                      '\\U0000212C',\n\t\"Beta;\":                            '\\U00000392',\n\t\"Bfr;\":                             '\\U0001D505',\n\t\"Bopf;\":                            '\\U0001D539',\n\t\"Breve;\":                           '\\U000002D8',\n\t\"Bscr;\":                            '\\U0000212C',\n\t\"Bumpeq;\":                          '\\U0000224E',\n\t\"CHcy;\":                            '\\U00000427',\n\t\"COPY;\":                            '\\U000000A9',\n\t\"Cacute;\":                          '\\U00000106',\n\t\"Cap;\":                             '\\U000022D2',\n\t\"CapitalDifferentialD;\":            '\\U00002145',\n\t\"Cayleys;\":                         '\\U0000212D',\n\t\"Ccaron;\":                          '\\U0000010C',\n\t\"Ccedil;\":                          '\\U000000C7',\n\t\"Ccirc;\":                           '\\U00000108',\n\t\"Cconint;\":                         '\\U00002230',\n\t\"Cdot;\":                            '\\U0000010A',\n\t\"Cedilla;\":                         '\\U000000B8',\n\t\"CenterDot;\":                       '\\U000000B7',\n\t\"Cfr;\":                             '\\U0000212D',\n\t\"Chi;\":                             '\\U000003A7',\n\t\"CircleDot;\":                       '\\U00002299',\n\t\"CircleMinus;\":                     '\\U00002296',\n\t\"CirclePlus;\":                      '\\U00002295',\n\t\"CircleTimes;\":                     '\\U00002297',\n\t\"ClockwiseContourIntegral;\":        '\\U00002232',\n\t\"CloseCurlyDoubleQuote;\":           '\\U0000201D',\n\t\"CloseCurlyQuote;\":                 '\\U00002019',\n\t\"Colon;\":                           '\\U00002237',\n\t\"Colone;\":                          '\\U00002A74',\n\t\"Congruent;\":                       '\\U00002261',\n\t\"Conint;\":                          '\\U0000222F',\n\t\"ContourIntegral;\":                 '\\U0000222E',\n\t\"Copf;\":                            '\\U00002102',\n\t\"Coproduct;\":                       '\\U00002210',\n\t\"CounterClockwiseContourIntegral;\": '\\U00002233',\n\t\"Cross;\":                           '\\U00002A2F',\n\t\"Cscr;\":                            '\\U0001D49E',\n\t\"Cup;\":                             '\\U000022D3',\n\t\"CupCap;\":                          '\\U0000224D',\n\t\"DD;\":                              '\\U00002145',\n\t\"DDotrahd;\":                        '\\U00002911',\n\t\"DJcy;\":                            '\\U00000402',\n\t\"DScy;\":                            '\\U00000405',\n\t\"DZcy;\":                            '\\U0000040F',\n\t\"Dagger;\":                          '\\U00002021',\n\t\"Darr;\":                            '\\U000021A1',\n\t\"Dashv;\":                           '\\U00002AE4',\n\t\"Dcaron;\":                          '\\U0000010E',\n\t\"Dcy;\":                             '\\U00000414',\n\t\"Del;\":                             '\\U00002207',\n\t\"Delta;\":                           '\\U00000394',\n\t\"Dfr;\":                             '\\U0001D507',\n\t\"DiacriticalAcute;\":                '\\U000000B4',\n\t\"DiacriticalDot;\":                  '\\U000002D9',\n\t\"DiacriticalDoubleAcute;\":          '\\U000002DD',\n\t\"DiacriticalGrave;\":                '\\U00000060',\n\t\"DiacriticalTilde;\":                '\\U000002DC',\n\t\"Diamond;\":                         '\\U000022C4',\n\t\"DifferentialD;\":                   '\\U00002146',\n\t\"Dopf;\":                            '\\U0001D53B',\n\t\"Dot;\":                             '\\U000000A8',\n\t\"DotDot;\":                          '\\U000020DC',\n\t\"DotEqual;\":                        '\\U00002250',\n\t\"DoubleContourIntegral;\":           '\\U0000222F',\n\t\"DoubleDot;\":                       '\\U000000A8',\n\t\"DoubleDownArrow;\":                 '\\U000021D3',\n\t\"DoubleLeftArrow;\":                 '\\U000021D0',\n\t\"DoubleLeftRightArrow;\":            '\\U000021D4',\n\t\"DoubleLeftTee;\":                   '\\U00002AE4',\n\t\"DoubleLongLeftArrow;\":             '\\U000027F8',\n\t\"DoubleLongLeftRightArrow;\":        '\\U000027FA',\n\t\"DoubleLongRightArrow;\":            '\\U000027F9',\n\t\"DoubleRightArrow;\":                '\\U000021D2',\n\t\"DoubleRightTee;\":                  '\\U000022A8',\n\t\"DoubleUpArrow;\":                   '\\U000021D1',\n\t\"DoubleUpDownArrow;\":               '\\U000021D5',\n\t\"DoubleVerticalBar;\":               '\\U00002225',\n\t\"DownArrow;\":                       '\\U00002193',\n\t\"DownArrowBar;\":                    '\\U00002913',\n\t\"DownArrowUpArrow;\":                '\\U000021F5',\n\t\"DownBreve;\":                       '\\U00000311',\n\t\"DownLeftRightVector;\":             '\\U00002950',\n\t\"DownLeftTeeVector;\":               '\\U0000295E',\n\t\"DownLeftVector;\":                  '\\U000021BD',\n\t\"DownLeftVectorBar;\":               '\\U00002956',\n\t\"DownRightTeeVector;\":              '\\U0000295F',\n\t\"DownRightVector;\":                 '\\U000021C1',\n\t\"DownRightVectorBar;\":              '\\U00002957',\n\t\"DownTee;\":                         '\\U000022A4',\n\t\"DownTeeArrow;\":                    '\\U000021A7',\n\t\"Downarrow;\":                       '\\U000021D3',\n\t\"Dscr;\":                            '\\U0001D49F',\n\t\"Dstrok;\":                          '\\U00000110',\n\t\"ENG;\":                             '\\U0000014A',\n\t\"ETH;\":                             '\\U000000D0',\n\t\"Eacute;\":                          '\\U000000C9',\n\t\"Ecaron;\":                          '\\U0000011A',\n\t\"Ecirc;\":                           '\\U000000CA',\n\t\"Ecy;\":                             '\\U0000042D',\n\t\"Edot;\":                            '\\U00000116',\n\t\"Efr;\":                             '\\U0001D508',\n\t\"Egrave;\":                          '\\U000000C8',\n\t\"Element;\":                         '\\U00002208',\n\t\"Emacr;\":                           '\\U00000112',\n\t\"EmptySmallSquare;\":                '\\U000025FB',\n\t\"EmptyVerySmallSquare;\":            '\\U000025AB',\n\t\"Eogon;\":                           '\\U00000118',\n\t\"Eopf;\":                            '\\U0001D53C',\n\t\"Epsilon;\":                         '\\U00000395',\n\t\"Equal;\":                           '\\U00002A75',\n\t\"EqualTilde;\":                      '\\U00002242',\n\t\"Equilibrium;\":                     '\\U000021CC',\n\t\"Escr;\":                            '\\U00002130',\n\t\"Esim;\":                            '\\U00002A73',\n\t\"Eta;\":                             '\\U00000397',\n\t\"Euml;\":                            '\\U000000CB',\n\t\"Exists;\":                          '\\U00002203',\n\t\"ExponentialE;\":                    '\\U00002147',\n\t\"Fcy;\":                             '\\U00000424',\n\t\"Ffr;\":                             '\\U0001D509',\n\t\"FilledSmallSquare;\":               '\\U000025FC',\n\t\"FilledVerySmallSquare;\":           '\\U000025AA',\n\t\"Fopf;\":                            '\\U0001D53D',\n\t\"ForAll;\":                          '\\U00002200',\n\t\"Fouriertrf;\":                      '\\U00002131',\n\t\"Fscr;\":                            '\\U00002131',\n\t\"GJcy;\":                            '\\U00000403',\n\t\"GT;\":                              '\\U0000003E',\n\t\"Gamma;\":                           '\\U00000393',\n\t\"Gammad;\":                          '\\U000003DC',\n\t\"Gbreve;\":                          '\\U0000011E',\n\t\"Gcedil;\":                          '\\U00000122',\n\t\"Gcirc;\":                           '\\U0000011C',\n\t\"Gcy;\":                             '\\U00000413',\n\t\"Gdot;\":                            '\\U00000120',\n\t\"Gfr;\":                             '\\U0001D50A',\n\t\"Gg;\":                              '\\U000022D9',\n\t\"Gopf;\":                            '\\U0001D53E',\n\t\"GreaterEqual;\":                    '\\U00002265',\n\t\"GreaterEqualLess;\":                '\\U000022DB',\n\t\"GreaterFullEqual;\":                '\\U00002267',\n\t\"GreaterGreater;\":                  '\\U00002AA2',\n\t\"GreaterLess;\":                     '\\U00002277',\n\t\"GreaterSlantEqual;\":               '\\U00002A7E',\n\t\"GreaterTilde;\":                    '\\U00002273',\n\t\"Gscr;\":                            '\\U0001D4A2',\n\t\"Gt;\":                              '\\U0000226B',\n\t\"HARDcy;\":                          '\\U0000042A',\n\t\"Hacek;\":                           '\\U000002C7',\n\t\"Hat;\":                             '\\U0000005E',\n\t\"Hcirc;\":                           '\\U00000124',\n\t\"Hfr;\":                             '\\U0000210C',\n\t\"HilbertSpace;\":                    '\\U0000210B',\n\t\"Hopf;\":                            '\\U0000210D',\n\t\"HorizontalLine;\":                  '\\U00002500',\n\t\"Hscr;\":                            '\\U0000210B',\n\t\"Hstrok;\":                          '\\U00000126',\n\t\"HumpDownHump;\":                    '\\U0000224E',\n\t\"HumpEqual;\":                       '\\U0000224F',\n\t\"IEcy;\":                            '\\U00000415',\n\t\"IJlig;\":                           '\\U00000132',\n\t\"IOcy;\":                            '\\U00000401',\n\t\"Iacute;\":                          '\\U000000CD',\n\t\"Icirc;\":                           '\\U000000CE',\n\t\"Icy;\":                             '\\U00000418',\n\t\"Idot;\":                            '\\U00000130',\n\t\"Ifr;\":                             '\\U00002111',\n\t\"Igrave;\":                          '\\U000000CC',\n\t\"Im;\":                              '\\U00002111',\n\t\"Imacr;\":                           '\\U0000012A',\n\t\"ImaginaryI;\":                      '\\U00002148',\n\t\"Implies;\":                         '\\U000021D2',\n\t\"Int;\":                             '\\U0000222C',\n\t\"Integral;\":                        '\\U0000222B',\n\t\"Intersection;\":                    '\\U000022C2',\n\t\"InvisibleComma;\":                  '\\U00002063',\n\t\"InvisibleTimes;\":                  '\\U00002062',\n\t\"Iogon;\":                           '\\U0000012E',\n\t\"Iopf;\":                            '\\U0001D540',\n\t\"Iota;\":                            '\\U00000399',\n\t\"Iscr;\":                            '\\U00002110',\n\t\"Itilde;\":                          '\\U00000128',\n\t\"Iukcy;\":                           '\\U00000406',\n\t\"Iuml;\":                            '\\U000000CF',\n\t\"Jcirc;\":                           '\\U00000134',\n\t\"Jcy;\":                             '\\U00000419',\n\t\"Jfr;\":                             '\\U0001D50D',\n\t\"Jopf;\":                            '\\U0001D541',\n\t\"Jscr;\":                            '\\U0001D4A5',\n\t\"Jsercy;\":                          '\\U00000408',\n\t\"Jukcy;\":                           '\\U00000404',\n\t\"KHcy;\":                            '\\U00000425',\n\t\"KJcy;\":                            '\\U0000040C',\n\t\"Kappa;\":                           '\\U0000039A',\n\t\"Kcedil;\":                          '\\U00000136',\n\t\"Kcy;\":                             '\\U0000041A',\n\t\"Kfr;\":                             '\\U0001D50E',\n\t\"Kopf;\":                            '\\U0001D542',\n\t\"Kscr;\":                            '\\U0001D4A6',\n\t\"LJcy;\":                            '\\U00000409',\n\t\"LT;\":                              '\\U0000003C',\n\t\"Lacute;\":                          '\\U00000139',\n\t\"Lambda;\":                          '\\U0000039B',\n\t\"Lang;\":                            '\\U000027EA',\n\t\"Laplacetrf;\":                      '\\U00002112',\n\t\"Larr;\":                            '\\U0000219E',\n\t\"Lcaron;\":                          '\\U0000013D',\n\t\"Lcedil;\":                          '\\U0000013B',\n\t\"Lcy;\":                             '\\U0000041B',\n\t\"LeftAngleBracket;\":                '\\U000027E8',\n\t\"LeftArrow;\":                       '\\U00002190',\n\t\"LeftArrowBar;\":                    '\\U000021E4',\n\t\"LeftArrowRightArrow;\":             '\\U000021C6',\n\t\"LeftCeiling;\":                     '\\U00002308',\n\t\"LeftDoubleBracket;\":               '\\U000027E6',\n\t\"LeftDownTeeVector;\":               '\\U00002961',\n\t\"LeftDownVector;\":                  '\\U000021C3',\n\t\"LeftDownVectorBar;\":               '\\U00002959',\n\t\"LeftFloor;\":                       '\\U0000230A',\n\t\"LeftRightArrow;\":                  '\\U00002194',\n\t\"LeftRightVector;\":                 '\\U0000294E',\n\t\"LeftTee;\":                         '\\U000022A3',\n\t\"LeftTeeArrow;\":                    '\\U000021A4',\n\t\"LeftTeeVector;\":                   '\\U0000295A',\n\t\"LeftTriangle;\":                    '\\U000022B2',\n\t\"LeftTriangleBar;\":                 '\\U000029CF',\n\t\"LeftTriangleEqual;\":               '\\U000022B4',\n\t\"LeftUpDownVector;\":                '\\U00002951',\n\t\"LeftUpTeeVector;\":                 '\\U00002960',\n\t\"LeftUpVector;\":                    '\\U000021BF',\n\t\"LeftUpVectorBar;\":                 '\\U00002958',\n\t\"LeftVector;\":                      '\\U000021BC',\n\t\"LeftVectorBar;\":                   '\\U00002952',\n\t\"Leftarrow;\":                       '\\U000021D0',\n\t\"Leftrightarrow;\":                  '\\U000021D4',\n\t\"LessEqualGreater;\":                '\\U000022DA',\n\t\"LessFullEqual;\":                   '\\U00002266',\n\t\"LessGreater;\":                     '\\U00002276',\n\t\"LessLess;\":                        '\\U00002AA1',\n\t\"LessSlantEqual;\":                  '\\U00002A7D',\n\t\"LessTilde;\":                       '\\U00002272',\n\t\"Lfr;\":                             '\\U0001D50F',\n\t\"Ll;\":                              '\\U000022D8',\n\t\"Lleftarrow;\":                      '\\U000021DA',\n\t\"Lmidot;\":                          '\\U0000013F',\n\t\"LongLeftArrow;\":                   '\\U000027F5',\n\t\"LongLeftRightArrow;\":              '\\U000027F7',\n\t\"LongRightArrow;\":                  '\\U000027F6',\n\t\"Longleftarrow;\":                   '\\U000027F8',\n\t\"Longleftrightarrow;\":              '\\U000027FA',\n\t\"Longrightarrow;\":                  '\\U000027F9',\n\t\"Lopf;\":                            '\\U0001D543',\n\t\"LowerLeftArrow;\":                  '\\U00002199',\n\t\"LowerRightArrow;\":                 '\\U00002198',\n\t\"Lscr;\":                            '\\U00002112',\n\t\"Lsh;\":                             '\\U000021B0',\n\t\"Lstrok;\":                          '\\U00000141',\n\t\"Lt;\":                              '\\U0000226A',\n\t\"Map;\":                             '\\U00002905',\n\t\"Mcy;\":                             '\\U0000041C',\n\t\"MediumSpace;\":                     '\\U0000205F',\n\t\"Mellintrf;\":                       '\\U00002133',\n\t\"Mfr;\":                             '\\U0001D510',\n\t\"MinusPlus;\":                       '\\U00002213',\n\t\"Mopf;\":                            '\\U0001D544',\n\t\"Mscr;\":                            '\\U00002133',\n\t\"Mu;\":                              '\\U0000039C',\n\t\"NJcy;\":                            '\\U0000040A',\n\t\"Nacute;\":                          '\\U00000143',\n\t\"Ncaron;\":                          '\\U00000147',\n\t\"Ncedil;\":                          '\\U00000145',\n\t\"Ncy;\":                             '\\U0000041D',\n\t\"NegativeMediumSpace;\":             '\\U0000200B',\n\t\"NegativeThickSpace;\":              '\\U0000200B',\n\t\"NegativeThinSpace;\":               '\\U0000200B',\n\t\"NegativeVeryThinSpace;\":           '\\U0000200B',\n\t\"NestedGreaterGreater;\":            '\\U0000226B',\n\t\"NestedLessLess;\":                  '\\U0000226A',\n\t\"NewLine;\":                         '\\U0000000A',\n\t\"Nfr;\":                             '\\U0001D511',\n\t\"NoBreak;\":                         '\\U00002060',\n\t\"NonBreakingSpace;\":                '\\U000000A0',\n\t\"Nopf;\":                            '\\U00002115',\n\t\"Not;\":                             '\\U00002AEC',\n\t\"NotCongruent;\":                    '\\U00002262',\n\t\"NotCupCap;\":                       '\\U0000226D',\n\t\"NotDoubleVerticalBar;\":            '\\U00002226',\n\t\"NotElement;\":                      '\\U00002209',\n\t\"NotEqual;\":                        '\\U00002260',\n\t\"NotExists;\":                       '\\U00002204',\n\t\"NotGreater;\":                      '\\U0000226F',\n\t\"NotGreaterEqual;\":                 '\\U00002271',\n\t\"NotGreaterLess;\":                  '\\U00002279',\n\t\"NotGreaterTilde;\":                 '\\U00002275',\n\t\"NotLeftTriangle;\":                 '\\U000022EA',\n\t\"NotLeftTriangleEqual;\":            '\\U000022EC',\n\t\"NotLess;\":                         '\\U0000226E',\n\t\"NotLessEqual;\":                    '\\U00002270',\n\t\"NotLessGreater;\":                  '\\U00002278',\n\t\"NotLessTilde;\":                    '\\U00002274',\n\t\"NotPrecedes;\":                     '\\U00002280',\n\t\"NotPrecedesSlantEqual;\":           '\\U000022E0',\n\t\"NotReverseElement;\":               '\\U0000220C',\n\t\"NotRightTriangle;\":                '\\U000022EB',\n\t\"NotRightTriangleEqual;\":           '\\U000022ED',\n\t\"NotSquareSubsetEqual;\":            '\\U000022E2',\n\t\"NotSquareSupersetEqual;\":          '\\U000022E3',\n\t\"NotSubsetEqual;\":                  '\\U00002288',\n\t\"NotSucceeds;\":                     '\\U00002281',\n\t\"NotSucceedsSlantEqual;\":           '\\U000022E1',\n\t\"NotSupersetEqual;\":                '\\U00002289',\n\t\"NotTilde;\":                        '\\U00002241',\n\t\"NotTildeEqual;\":                   '\\U00002244',\n\t\"NotTildeFullEqual;\":               '\\U00002247',\n\t\"NotTildeTilde;\":                   '\\U00002249',\n\t\"NotVerticalBar;\":                  '\\U00002224',\n\t\"Nscr;\":                            '\\U0001D4A9',\n\t\"Ntilde;\":                          '\\U000000D1',\n\t\"Nu;\":                              '\\U0000039D',\n\t\"OElig;\":                           '\\U00000152',\n\t\"Oacute;\":                          '\\U000000D3',\n\t\"Ocirc;\":                           '\\U000000D4',\n\t\"Ocy;\":                             '\\U0000041E',\n\t\"Odblac;\":                          '\\U00000150',\n\t\"Ofr;\":                             '\\U0001D512',\n\t\"Ograve;\":                          '\\U000000D2',\n\t\"Omacr;\":                           '\\U0000014C',\n\t\"Omega;\":                           '\\U000003A9',\n\t\"Omicron;\":                         '\\U0000039F',\n\t\"Oopf;\":                            '\\U0001D546',\n\t\"OpenCurlyDoubleQuote;\":            '\\U0000201C',\n\t\"OpenCurlyQuote;\":                  '\\U00002018',\n\t\"Or;\":                              '\\U00002A54',\n\t\"Oscr;\":                            '\\U0001D4AA',\n\t\"Oslash;\":                          '\\U000000D8',\n\t\"Otilde;\":                          '\\U000000D5',\n\t\"Otimes;\":                          '\\U00002A37',\n\t\"Ouml;\":                            '\\U000000D6',\n\t\"OverBar;\":                         '\\U0000203E',\n\t\"OverBrace;\":                       '\\U000023DE',\n\t\"OverBracket;\":                     '\\U000023B4',\n\t\"OverParenthesis;\":                 '\\U000023DC',\n\t\"PartialD;\":                        '\\U00002202',\n\t\"Pcy;\":                             '\\U0000041F',\n\t\"Pfr;\":                             '\\U0001D513',\n\t\"Phi;\":                             '\\U000003A6',\n\t\"Pi;\":                              '\\U000003A0',\n\t\"PlusMinus;\":                       '\\U000000B1',\n\t\"Poincareplane;\":                   '\\U0000210C',\n\t\"Popf;\":                            '\\U00002119',\n\t\"Pr;\":                              '\\U00002ABB',\n\t\"Precedes;\":                        '\\U0000227A',\n\t\"PrecedesEqual;\":                   '\\U00002AAF',\n\t\"PrecedesSlantEqual;\":              '\\U0000227C',\n\t\"PrecedesTilde;\":                   '\\U0000227E',\n\t\"Prime;\":                           '\\U00002033',\n\t\"Product;\":                         '\\U0000220F',\n\t\"Proportion;\":                      '\\U00002237',\n\t\"Proportional;\":                    '\\U0000221D',\n\t\"Pscr;\":                            '\\U0001D4AB',\n\t\"Psi;\":                             '\\U000003A8',\n\t\"QUOT;\":                            '\\U00000022',\n\t\"Qfr;\":                             '\\U0001D514',\n\t\"Qopf;\":                            '\\U0000211A',\n\t\"Qscr;\":                            '\\U0001D4AC',\n\t\"RBarr;\":                           '\\U00002910',\n\t\"REG;\":                             '\\U000000AE',\n\t\"Racute;\":                          '\\U00000154',\n\t\"Rang;\":                            '\\U000027EB',\n\t\"Rarr;\":                            '\\U000021A0',\n\t\"Rarrtl;\":                          '\\U00002916',\n\t\"Rcaron;\":                          '\\U00000158',\n\t\"Rcedil;\":                          '\\U00000156',\n\t\"Rcy;\":                             '\\U00000420',\n\t\"Re;\":                              '\\U0000211C',\n\t\"ReverseElement;\":                  '\\U0000220B',\n\t\"ReverseEquilibrium;\":              '\\U000021CB',\n\t\"ReverseUpEquilibrium;\":            '\\U0000296F',\n\t\"Rfr;\":                             '\\U0000211C',\n\t\"Rho;\":                             '\\U000003A1',\n\t\"RightAngleBracket;\":               '\\U000027E9',\n\t\"RightArrow;\":                      '\\U00002192',\n\t\"RightArrowBar;\":                   '\\U000021E5',\n\t\"RightArrowLeftArrow;\":             '\\U000021C4',\n\t\"RightCeiling;\":                    '\\U00002309',\n\t\"RightDoubleBracket;\":              '\\U000027E7',\n\t\"RightDownTeeVector;\":              '\\U0000295D',\n\t\"RightDownVector;\":                 '\\U000021C2',\n\t\"RightDownVectorBar;\":              '\\U00002955',\n\t\"RightFloor;\":                      '\\U0000230B',\n\t\"RightTee;\":                        '\\U000022A2',\n\t\"RightTeeArrow;\":                   '\\U000021A6',\n\t\"RightTeeVector;\":                  '\\U0000295B',\n\t\"RightTriangle;\":                   '\\U000022B3',\n\t\"RightTriangleBar;\":                '\\U000029D0',\n\t\"RightTriangleEqual;\":              '\\U000022B5',\n\t\"RightUpDownVector;\":               '\\U0000294F',\n\t\"RightUpTeeVector;\":                '\\U0000295C',\n\t\"RightUpVector;\":                   '\\U000021BE',\n\t\"RightUpVectorBar;\":                '\\U00002954',\n\t\"RightVector;\":                     '\\U000021C0',\n\t\"RightVectorBar;\":                  '\\U00002953',\n\t\"Rightarrow;\":                      '\\U000021D2',\n\t\"Ropf;\":                            '\\U0000211D',\n\t\"RoundImplies;\":                    '\\U00002970',\n\t\"Rrightarrow;\":                     '\\U000021DB',\n\t\"Rscr;\":                            '\\U0000211B',\n\t\"Rsh;\":                             '\\U000021B1',\n\t\"RuleDelayed;\":                     '\\U000029F4',\n\t\"SHCHcy;\":                          '\\U00000429',\n\t\"SHcy;\":                            '\\U00000428',\n\t\"SOFTcy;\":                          '\\U0000042C',\n\t\"Sacute;\":                          '\\U0000015A',\n\t\"Sc;\":                              '\\U00002ABC',\n\t\"Scaron;\":                          '\\U00000160',\n\t\"Scedil;\":                          '\\U0000015E',\n\t\"Scirc;\":                           '\\U0000015C',\n\t\"Scy;\":                             '\\U00000421',\n\t\"Sfr;\":                             '\\U0001D516',\n\t\"ShortDownArrow;\":                  '\\U00002193',\n\t\"ShortLeftArrow;\":                  '\\U00002190',\n\t\"ShortRightArrow;\":                 '\\U00002192',\n\t\"ShortUpArrow;\":                    '\\U00002191',\n\t\"Sigma;\":                           '\\U000003A3',\n\t\"SmallCircle;\":                     '\\U00002218',\n\t\"Sopf;\":                            '\\U0001D54A',\n\t\"Sqrt;\":                            '\\U0000221A',\n\t\"Square;\":                          '\\U000025A1',\n\t\"SquareIntersection;\":              '\\U00002293',\n\t\"SquareSubset;\":                    '\\U0000228F',\n\t\"SquareSubsetEqual;\":               '\\U00002291',\n\t\"SquareSuperset;\":                  '\\U00002290',\n\t\"SquareSupersetEqual;\":             '\\U00002292',\n\t\"SquareUnion;\":                     '\\U00002294',\n\t\"Sscr;\":                            '\\U0001D4AE',\n\t\"Star;\":                            '\\U000022C6',\n\t\"Sub;\":                             '\\U000022D0',\n\t\"Subset;\":                          '\\U000022D0',\n\t\"SubsetEqual;\":                     '\\U00002286',\n\t\"Succeeds;\":                        '\\U0000227B',\n\t\"SucceedsEqual;\":                   '\\U00002AB0',\n\t\"SucceedsSlantEqual;\":              '\\U0000227D',\n\t\"SucceedsTilde;\":                   '\\U0000227F',\n\t\"SuchThat;\":                        '\\U0000220B',\n\t\"Sum;\":                             '\\U00002211',\n\t\"Sup;\":                             '\\U000022D1',\n\t\"Superset;\":                        '\\U00002283',\n\t\"SupersetEqual;\":                   '\\U00002287',\n\t\"Supset;\":                          '\\U000022D1',\n\t\"THORN;\":                           '\\U000000DE',\n\t\"TRADE;\":                           '\\U00002122',\n\t\"TSHcy;\":                           '\\U0000040B',\n\t\"TScy;\":                            '\\U00000426',\n\t\"Tab;\":                             '\\U00000009',\n\t\"Tau;\":                             '\\U000003A4',\n\t\"Tcaron;\":                          '\\U00000164',\n\t\"Tcedil;\":                          '\\U00000162',\n\t\"Tcy;\":                             '\\U00000422',\n\t\"Tfr;\":                             '\\U0001D517',\n\t\"Therefore;\":                       '\\U00002234',\n\t\"Theta;\":                           '\\U00000398',\n\t\"ThinSpace;\":                       '\\U00002009',\n\t\"Tilde;\":                           '\\U0000223C',\n\t\"TildeEqual;\":                      '\\U00002243',\n\t\"TildeFullEqual;\":                  '\\U00002245',\n\t\"TildeTilde;\":                      '\\U00002248',\n\t\"Topf;\":                            '\\U0001D54B',\n\t\"TripleDot;\":                       '\\U000020DB',\n\t\"Tscr;\":                            '\\U0001D4AF',\n\t\"Tstrok;\":                          '\\U00000166',\n\t\"Uacute;\":                          '\\U000000DA',\n\t\"Uarr;\":                            '\\U0000219F',\n\t\"Uarrocir;\":                        '\\U00002949',\n\t\"Ubrcy;\":                           '\\U0000040E',\n\t\"Ubreve;\":                          '\\U0000016C',\n\t\"Ucirc;\":                           '\\U000000DB',\n\t\"Ucy;\":                             '\\U00000423',\n\t\"Udblac;\":                          '\\U00000170',\n\t\"Ufr;\":                             '\\U0001D518',\n\t\"Ugrave;\":                          '\\U000000D9',\n\t\"Umacr;\":                           '\\U0000016A',\n\t\"UnderBar;\":                        '\\U0000005F',\n\t\"UnderBrace;\":                      '\\U000023DF',\n\t\"UnderBracket;\":                    '\\U000023B5',\n\t\"UnderParenthesis;\":                '\\U000023DD',\n\t\"Union;\":                           '\\U000022C3',\n\t\"UnionPlus;\":                       '\\U0000228E',\n\t\"Uogon;\":                           '\\U00000172',\n\t\"Uopf;\":                            '\\U0001D54C',\n\t\"UpArrow;\":                         '\\U00002191',\n\t\"UpArrowBar;\":                      '\\U00002912',\n\t\"UpArrowDownArrow;\":                '\\U000021C5',\n\t\"UpDownArrow;\":                     '\\U00002195',\n\t\"UpEquilibrium;\":                   '\\U0000296E',\n\t\"UpTee;\":                           '\\U000022A5',\n\t\"UpTeeArrow;\":                      '\\U000021A5',\n\t\"Uparrow;\":                         '\\U000021D1',\n\t\"Updownarrow;\":                     '\\U000021D5',\n\t\"UpperLeftArrow;\":                  '\\U00002196',\n\t\"UpperRightArrow;\":                 '\\U00002197',\n\t\"Upsi;\":                            '\\U000003D2',\n\t\"Upsilon;\":                         '\\U000003A5',\n\t\"Uring;\":                           '\\U0000016E',\n\t\"Uscr;\":                            '\\U0001D4B0',\n\t\"Utilde;\":                          '\\U00000168',\n\t\"Uuml;\":                            '\\U000000DC',\n\t\"VDash;\":                           '\\U000022AB',\n\t\"Vbar;\":                            '\\U00002AEB',\n\t\"Vcy;\":                             '\\U00000412',\n\t\"Vdash;\":                           '\\U000022A9',\n\t\"Vdashl;\":                          '\\U00002AE6',\n\t\"Vee;\":                             '\\U000022C1',\n\t\"Verbar;\":                          '\\U00002016',\n\t\"Vert;\":                            '\\U00002016',\n\t\"VerticalBar;\":                     '\\U00002223',\n\t\"VerticalLine;\":                    '\\U0000007C',\n\t\"VerticalSeparator;\":               '\\U00002758',\n\t\"VerticalTilde;\":                   '\\U00002240',\n\t\"VeryThinSpace;\":                   '\\U0000200A',\n\t\"Vfr;\":                             '\\U0001D519',\n\t\"Vopf;\":                            '\\U0001D54D',\n\t\"Vscr;\":                            '\\U0001D4B1',\n\t\"Vvdash;\":                          '\\U000022AA',\n\t\"Wcirc;\":                           '\\U00000174',\n\t\"Wedge;\":                           '\\U000022C0',\n\t\"Wfr;\":                             '\\U0001D51A',\n\t\"Wopf;\":                            '\\U0001D54E',\n\t\"Wscr;\":                            '\\U0001D4B2',\n\t\"Xfr;\":                             '\\U0001D51B',\n\t\"Xi;\":                              '\\U0000039E',\n\t\"Xopf;\":                            '\\U0001D54F',\n\t\"Xscr;\":                            '\\U0001D4B3',\n\t\"YAcy;\":                            '\\U0000042F',\n\t\"YIcy;\":                            '\\U00000407',\n\t\"YUcy;\":                            '\\U0000042E',\n\t\"Yacute;\":                          '\\U000000DD',\n\t\"Ycirc;\":                           '\\U00000176',\n\t\"Ycy;\":                             '\\U0000042B',\n\t\"Yfr;\":                             '\\U0001D51C',\n\t\"Yopf;\":                            '\\U0001D550',\n\t\"Yscr;\":                            '\\U0001D4B4',\n\t\"Yuml;\":                            '\\U00000178',\n\t\"ZHcy;\":                            '\\U00000416',\n\t\"Zacute;\":                          '\\U00000179',\n\t\"Zcaron;\":                          '\\U0000017D',\n\t\"Zcy;\":                             '\\U00000417',\n\t\"Zdot;\":                            '\\U0000017B',\n\t\"ZeroWidthSpace;\":                  '\\U0000200B',\n\t\"Zeta;\":                            '\\U00000396',\n\t\"Zfr;\":                             '\\U00002128',\n\t\"Zopf;\":                            '\\U00002124',\n\t\"Zscr;\":                            '\\U0001D4B5',\n\t\"aacute;\":                          '\\U000000E1',\n\t\"abreve;\":                          '\\U00000103',\n\t\"ac;\":                              '\\U0000223E',\n\t\"acd;\":                             '\\U0000223F',\n\t\"acirc;\":                           '\\U000000E2',\n\t\"acute;\":                           '\\U000000B4',\n\t\"acy;\":                             '\\U00000430',\n\t\"aelig;\":                           '\\U000000E6',\n\t\"af;\":                              '\\U00002061',\n\t\"afr;\":                             '\\U0001D51E',\n\t\"agrave;\":                          '\\U000000E0',\n\t\"alefsym;\":                         '\\U00002135',\n\t\"aleph;\":                           '\\U00002135',\n\t\"alpha;\":                           '\\U000003B1',\n\t\"amacr;\":                           '\\U00000101',\n\t\"amalg;\":                           '\\U00002A3F',\n\t\"amp;\":                             '\\U00000026',\n\t\"and;\":                             '\\U00002227',\n\t\"andand;\":                          '\\U00002A55',\n\t\"andd;\":                            '\\U00002A5C',\n\t\"andslope;\":                        '\\U00002A58',\n\t\"andv;\":                            '\\U00002A5A',\n\t\"ang;\":                             '\\U00002220',\n\t\"ange;\":                            '\\U000029A4',\n\t\"angle;\":                           '\\U00002220',\n\t\"angmsd;\":                          '\\U00002221',\n\t\"angmsdaa;\":                        '\\U000029A8',\n\t\"angmsdab;\":                        '\\U000029A9',\n\t\"angmsdac;\":                        '\\U000029AA',\n\t\"angmsdad;\":                        '\\U000029AB',\n\t\"angmsdae;\":                        '\\U000029AC',\n\t\"angmsdaf;\":                        '\\U000029AD',\n\t\"angmsdag;\":                        '\\U000029AE',\n\t\"angmsdah;\":                        '\\U000029AF',\n\t\"angrt;\":                           '\\U0000221F',\n\t\"angrtvb;\":                         '\\U000022BE',\n\t\"angrtvbd;\":                        '\\U0000299D',\n\t\"angsph;\":                          '\\U00002222',\n\t\"angst;\":                           '\\U000000C5',\n\t\"angzarr;\":                         '\\U0000237C',\n\t\"aogon;\":                           '\\U00000105',\n\t\"aopf;\":                            '\\U0001D552',\n\t\"ap;\":                              '\\U00002248',\n\t\"apE;\":                             '\\U00002A70',\n\t\"apacir;\":                          '\\U00002A6F',\n\t\"ape;\":                             '\\U0000224A',\n\t\"apid;\":                            '\\U0000224B',\n\t\"apos;\":                            '\\U00000027',\n\t\"approx;\":                          '\\U00002248',\n\t\"approxeq;\":                        '\\U0000224A',\n\t\"aring;\":                           '\\U000000E5',\n\t\"ascr;\":                            '\\U0001D4B6',\n\t\"ast;\":                             '\\U0000002A',\n\t\"asymp;\":                           '\\U00002248',\n\t\"asympeq;\":                         '\\U0000224D',\n\t\"atilde;\":                          '\\U000000E3',\n\t\"auml;\":                            '\\U000000E4',\n\t\"awconint;\":                        '\\U00002233',\n\t\"awint;\":                           '\\U00002A11',\n\t\"bNot;\":                            '\\U00002AED',\n\t\"backcong;\":                        '\\U0000224C',\n\t\"backepsilon;\":                     '\\U000003F6',\n\t\"backprime;\":                       '\\U00002035',\n\t\"backsim;\":                         '\\U0000223D',\n\t\"backsimeq;\":                       '\\U000022CD',\n\t\"barvee;\":                          '\\U000022BD',\n\t\"barwed;\":                          '\\U00002305',\n\t\"barwedge;\":                        '\\U00002305',\n\t\"bbrk;\":                            '\\U000023B5',\n\t\"bbrktbrk;\":                        '\\U000023B6',\n\t\"bcong;\":                           '\\U0000224C',\n\t\"bcy;\":                             '\\U00000431',\n\t\"bdquo;\":                           '\\U0000201E',\n\t\"becaus;\":                          '\\U00002235',\n\t\"because;\":                         '\\U00002235',\n\t\"bemptyv;\":                         '\\U000029B0',\n\t\"bepsi;\":                           '\\U000003F6',\n\t\"bernou;\":                          '\\U0000212C',\n\t\"beta;\":                            '\\U000003B2',\n\t\"beth;\":                            '\\U00002136',\n\t\"between;\":                         '\\U0000226C',\n\t\"bfr;\":                             '\\U0001D51F',\n\t\"bigcap;\":                          '\\U000022C2',\n\t\"bigcirc;\":                         '\\U000025EF',\n\t\"bigcup;\":                          '\\U000022C3',\n\t\"bigodot;\":                         '\\U00002A00',\n\t\"bigoplus;\":                        '\\U00002A01',\n\t\"bigotimes;\":                       '\\U00002A02',\n\t\"bigsqcup;\":                        '\\U00002A06',\n\t\"bigstar;\":                         '\\U00002605',\n\t\"bigtriangledown;\":                 '\\U000025BD',\n\t\"bigtriangleup;\":                   '\\U000025B3',\n\t\"biguplus;\":                        '\\U00002A04',\n\t\"bigvee;\":                          '\\U000022C1',\n\t\"bigwedge;\":                        '\\U000022C0',\n\t\"bkarow;\":                          '\\U0000290D',\n\t\"blacklozenge;\":                    '\\U000029EB',\n\t\"blacksquare;\":                     '\\U000025AA',\n\t\"blacktriangle;\":                   '\\U000025B4',\n\t\"blacktriangledown;\":               '\\U000025BE',\n\t\"blacktriangleleft;\":               '\\U000025C2',\n\t\"blacktriangleright;\":              '\\U000025B8',\n\t\"blank;\":                           '\\U00002423',\n\t\"blk12;\":                           '\\U00002592',\n\t\"blk14;\":                           '\\U00002591',\n\t\"blk34;\":                           '\\U00002593',\n\t\"block;\":                           '\\U00002588',\n\t\"bnot;\":                            '\\U00002310',\n\t\"bopf;\":                            '\\U0001D553',\n\t\"bot;\":                             '\\U000022A5',\n\t\"bottom;\":                          '\\U000022A5',\n\t\"bowtie;\":                          '\\U000022C8',\n\t\"boxDL;\":                           '\\U00002557',\n\t\"boxDR;\":                           '\\U00002554',\n\t\"boxDl;\":                           '\\U00002556',\n\t\"boxDr;\":                           '\\U00002553',\n\t\"boxH;\":                            '\\U00002550',\n\t\"boxHD;\":                           '\\U00002566',\n\t\"boxHU;\":                           '\\U00002569',\n\t\"boxHd;\":                           '\\U00002564',\n\t\"boxHu;\":                           '\\U00002567',\n\t\"boxUL;\":                           '\\U0000255D',\n\t\"boxUR;\":                           '\\U0000255A',\n\t\"boxUl;\":                           '\\U0000255C',\n\t\"boxUr;\":                           '\\U00002559',\n\t\"boxV;\":                            '\\U00002551',\n\t\"boxVH;\":                           '\\U0000256C',\n\t\"boxVL;\":                           '\\U00002563',\n\t\"boxVR;\":                           '\\U00002560',\n\t\"boxVh;\":                           '\\U0000256B',\n\t\"boxVl;\":                           '\\U00002562',\n\t\"boxVr;\":                           '\\U0000255F',\n\t\"boxbox;\":                          '\\U000029C9',\n\t\"boxdL;\":                           '\\U00002555',\n\t\"boxdR;\":                           '\\U00002552',\n\t\"boxdl;\":                           '\\U00002510',\n\t\"boxdr;\":                           '\\U0000250C',\n\t\"boxh;\":                            '\\U00002500',\n\t\"boxhD;\":                           '\\U00002565',\n\t\"boxhU;\":                           '\\U00002568',\n\t\"boxhd;\":                           '\\U0000252C',\n\t\"boxhu;\":                           '\\U00002534',\n\t\"boxminus;\":                        '\\U0000229F',\n\t\"boxplus;\":                         '\\U0000229E',\n\t\"boxtimes;\":                        '\\U000022A0',\n\t\"boxuL;\":                           '\\U0000255B',\n\t\"boxuR;\":                           '\\U00002558',\n\t\"boxul;\":                           '\\U00002518',\n\t\"boxur;\":                           '\\U00002514',\n\t\"boxv;\":                            '\\U00002502',\n\t\"boxvH;\":                           '\\U0000256A',\n\t\"boxvL;\":                           '\\U00002561',\n\t\"boxvR;\":                           '\\U0000255E',\n\t\"boxvh;\":                           '\\U0000253C',\n\t\"boxvl;\":                           '\\U00002524',\n\t\"boxvr;\":                           '\\U0000251C',\n\t\"bprime;\":                          '\\U00002035',\n\t\"breve;\":                           '\\U000002D8',\n\t\"brvbar;\":                          '\\U000000A6',\n\t\"bscr;\":                            '\\U0001D4B7',\n\t\"bsemi;\":                           '\\U0000204F',\n\t\"bsim;\":                            '\\U0000223D',\n\t\"bsime;\":                           '\\U000022CD',\n\t\"bsol;\":                            '\\U0000005C',\n\t\"bsolb;\":                           '\\U000029C5',\n\t\"bsolhsub;\":                        '\\U000027C8',\n\t\"bull;\":                            '\\U00002022',\n\t\"bullet;\":                          '\\U00002022',\n\t\"bump;\":                            '\\U0000224E',\n\t\"bumpE;\":                           '\\U00002AAE',\n\t\"bumpe;\":                           '\\U0000224F',\n\t\"bumpeq;\":                          '\\U0000224F',\n\t\"cacute;\":                          '\\U00000107',\n\t\"cap;\":                             '\\U00002229',\n\t\"capand;\":                          '\\U00002A44',\n\t\"capbrcup;\":                        '\\U00002A49',\n\t\"capcap;\":                          '\\U00002A4B',\n\t\"capcup;\":                          '\\U00002A47',\n\t\"capdot;\":                          '\\U00002A40',\n\t\"caret;\":                           '\\U00002041',\n\t\"caron;\":                           '\\U000002C7',\n\t\"ccaps;\":                           '\\U00002A4D',\n\t\"ccaron;\":                          '\\U0000010D',\n\t\"ccedil;\":                          '\\U000000E7',\n\t\"ccirc;\":                           '\\U00000109',\n\t\"ccups;\":                           '\\U00002A4C',\n\t\"ccupssm;\":                         '\\U00002A50',\n\t\"cdot;\":                            '\\U0000010B',\n\t\"cedil;\":                           '\\U000000B8',\n\t\"cemptyv;\":                         '\\U000029B2',\n\t\"cent;\":                            '\\U000000A2',\n\t\"centerdot;\":                       '\\U000000B7',\n\t\"cfr;\":                             '\\U0001D520',\n\t\"chcy;\":                            '\\U00000447',\n\t\"check;\":                           '\\U00002713',\n\t\"checkmark;\":                       '\\U00002713',\n\t\"chi;\":                             '\\U000003C7',\n\t\"cir;\":                             '\\U000025CB',\n\t\"cirE;\":                            '\\U000029C3',\n\t\"circ;\":                            '\\U000002C6',\n\t\"circeq;\":                          '\\U00002257',\n\t\"circlearrowleft;\":                 '\\U000021BA',\n\t\"circlearrowright;\":                '\\U000021BB',\n\t\"circledR;\":                        '\\U000000AE',\n\t\"circledS;\":                        '\\U000024C8',\n\t\"circledast;\":                      '\\U0000229B',\n\t\"circledcirc;\":                     '\\U0000229A',\n\t\"circleddash;\":                     '\\U0000229D',\n\t\"cire;\":                            '\\U00002257',\n\t\"cirfnint;\":                        '\\U00002A10',\n\t\"cirmid;\":                          '\\U00002AEF',\n\t\"cirscir;\":                         '\\U000029C2',\n\t\"clubs;\":                           '\\U00002663',\n\t\"clubsuit;\":                        '\\U00002663',\n\t\"colon;\":                           '\\U0000003A',\n\t\"colone;\":                          '\\U00002254',\n\t\"coloneq;\":                         '\\U00002254',\n\t\"comma;\":                           '\\U0000002C',\n\t\"commat;\":                          '\\U00000040',\n\t\"comp;\":                            '\\U00002201',\n\t\"compfn;\":                          '\\U00002218',\n\t\"complement;\":                      '\\U00002201',\n\t\"complexes;\":                       '\\U00002102',\n\t\"cong;\":                            '\\U00002245',\n\t\"congdot;\":                         '\\U00002A6D',\n\t\"conint;\":                          '\\U0000222E',\n\t\"copf;\":                            '\\U0001D554',\n\t\"coprod;\":                          '\\U00002210',\n\t\"copy;\":                            '\\U000000A9',\n\t\"copysr;\":                          '\\U00002117',\n\t\"crarr;\":                           '\\U000021B5',\n\t\"cross;\":                           '\\U00002717',\n\t\"cscr;\":                            '\\U0001D4B8',\n\t\"csub;\":                            '\\U00002ACF',\n\t\"csube;\":                           '\\U00002AD1',\n\t\"csup;\":                            '\\U00002AD0',\n\t\"csupe;\":                           '\\U00002AD2',\n\t\"ctdot;\":                           '\\U000022EF',\n\t\"cudarrl;\":                         '\\U00002938',\n\t\"cudarrr;\":                         '\\U00002935',\n\t\"cuepr;\":                           '\\U000022DE',\n\t\"cuesc;\":                           '\\U000022DF',\n\t\"cularr;\":                          '\\U000021B6',\n\t\"cularrp;\":                         '\\U0000293D',\n\t\"cup;\":                             '\\U0000222A',\n\t\"cupbrcap;\":                        '\\U00002A48',\n\t\"cupcap;\":                          '\\U00002A46',\n\t\"cupcup;\":                          '\\U00002A4A',\n\t\"cupdot;\":                          '\\U0000228D',\n\t\"cupor;\":                           '\\U00002A45',\n\t\"curarr;\":                          '\\U000021B7',\n\t\"curarrm;\":                         '\\U0000293C',\n\t\"curlyeqprec;\":                     '\\U000022DE',\n\t\"curlyeqsucc;\":                     '\\U000022DF',\n\t\"curlyvee;\":                        '\\U000022CE',\n\t\"curlywedge;\":                      '\\U000022CF',\n\t\"curren;\":                          '\\U000000A4',\n\t\"curvearrowleft;\":                  '\\U000021B6',\n\t\"curvearrowright;\":                 '\\U000021B7',\n\t\"cuvee;\":                           '\\U000022CE',\n\t\"cuwed;\":                           '\\U000022CF',\n\t\"cwconint;\":                        '\\U00002232',\n\t\"cwint;\":                           '\\U00002231',\n\t\"cylcty;\":                          '\\U0000232D',\n\t\"dArr;\":                            '\\U000021D3',\n\t\"dHar;\":                            '\\U00002965',\n\t\"dagger;\":                          '\\U00002020',\n\t\"daleth;\":                          '\\U00002138',\n\t\"darr;\":                            '\\U00002193',\n\t\"dash;\":                            '\\U00002010',\n\t\"dashv;\":                           '\\U000022A3',\n\t\"dbkarow;\":                         '\\U0000290F',\n\t\"dblac;\":                           '\\U000002DD',\n\t\"dcaron;\":                          '\\U0000010F',\n\t\"dcy;\":                             '\\U00000434',\n\t\"dd;\":                              '\\U00002146',\n\t\"ddagger;\":                         '\\U00002021',\n\t\"ddarr;\":                           '\\U000021CA',\n\t\"ddotseq;\":                         '\\U00002A77',\n\t\"deg;\":                             '\\U000000B0',\n\t\"delta;\":                           '\\U000003B4',\n\t\"demptyv;\":                         '\\U000029B1',\n\t\"dfisht;\":                          '\\U0000297F',\n\t\"dfr;\":                             '\\U0001D521',\n\t\"dharl;\":                           '\\U000021C3',\n\t\"dharr;\":                           '\\U000021C2',\n\t\"diam;\":                            '\\U000022C4',\n\t\"diamond;\":                         '\\U000022C4',\n\t\"diamondsuit;\":                     '\\U00002666',\n\t\"diams;\":                           '\\U00002666',\n\t\"die;\":                             '\\U000000A8',\n\t\"digamma;\":                         '\\U000003DD',\n\t\"disin;\":                           '\\U000022F2',\n\t\"div;\":                             '\\U000000F7',\n\t\"divide;\":                          '\\U000000F7',\n\t\"divideontimes;\":                   '\\U000022C7',\n\t\"divonx;\":                          '\\U000022C7',\n\t\"djcy;\":                            '\\U00000452',\n\t\"dlcorn;\":                          '\\U0000231E',\n\t\"dlcrop;\":                          '\\U0000230D',\n\t\"dollar;\":                          '\\U00000024',\n\t\"dopf;\":                            '\\U0001D555',\n\t\"dot;\":                             '\\U000002D9',\n\t\"doteq;\":                           '\\U00002250',\n\t\"doteqdot;\":                        '\\U00002251',\n\t\"dotminus;\":                        '\\U00002238',\n\t\"dotplus;\":                         '\\U00002214',\n\t\"dotsquare;\":                       '\\U000022A1',\n\t\"doublebarwedge;\":                  '\\U00002306',\n\t\"downarrow;\":                       '\\U00002193',\n\t\"downdownarrows;\":                  '\\U000021CA',\n\t\"downharpoonleft;\":                 '\\U000021C3',\n\t\"downharpoonright;\":                '\\U000021C2',\n\t\"drbkarow;\":                        '\\U00002910',\n\t\"drcorn;\":                          '\\U0000231F',\n\t\"drcrop;\":                          '\\U0000230C',\n\t\"dscr;\":                            '\\U0001D4B9',\n\t\"dscy;\":                            '\\U00000455',\n\t\"dsol;\":                            '\\U000029F6',\n\t\"dstrok;\":                          '\\U00000111',\n\t\"dtdot;\":                           '\\U000022F1',\n\t\"dtri;\":                            '\\U000025BF',\n\t\"dtrif;\":                           '\\U000025BE',\n\t\"duarr;\":                           '\\U000021F5',\n\t\"duhar;\":                           '\\U0000296F',\n\t\"dwangle;\":                         '\\U000029A6',\n\t\"dzcy;\":                            '\\U0000045F',\n\t\"dzigrarr;\":                        '\\U000027FF',\n\t\"eDDot;\":                           '\\U00002A77',\n\t\"eDot;\":                            '\\U00002251',\n\t\"eacute;\":                          '\\U000000E9',\n\t\"easter;\":                          '\\U00002A6E',\n\t\"ecaron;\":                          '\\U0000011B',\n\t\"ecir;\":                            '\\U00002256',\n\t\"ecirc;\":                           '\\U000000EA',\n\t\"ecolon;\":                          '\\U00002255',\n\t\"ecy;\":                             '\\U0000044D',\n\t\"edot;\":                            '\\U00000117',\n\t\"ee;\":                              '\\U00002147',\n\t\"efDot;\":                           '\\U00002252',\n\t\"efr;\":                             '\\U0001D522',\n\t\"eg;\":                              '\\U00002A9A',\n\t\"egrave;\":                          '\\U000000E8',\n\t\"egs;\":                             '\\U00002A96',\n\t\"egsdot;\":                          '\\U00002A98',\n\t\"el;\":                              '\\U00002A99',\n\t\"elinters;\":                        '\\U000023E7',\n\t\"ell;\":                             '\\U00002113',\n\t\"els;\":                             '\\U00002A95',\n\t\"elsdot;\":                          '\\U00002A97',\n\t\"emacr;\":                           '\\U00000113',\n\t\"empty;\":                           '\\U00002205',\n\t\"emptyset;\":                        '\\U00002205',\n\t\"emptyv;\":                          '\\U00002205',\n\t\"emsp;\":                            '\\U00002003',\n\t\"emsp13;\":                          '\\U00002004',\n\t\"emsp14;\":                          '\\U00002005',\n\t\"eng;\":                             '\\U0000014B',\n\t\"ensp;\":                            '\\U00002002',\n\t\"eogon;\":                           '\\U00000119',\n\t\"eopf;\":                            '\\U0001D556',\n\t\"epar;\":                            '\\U000022D5',\n\t\"eparsl;\":                          '\\U000029E3',\n\t\"eplus;\":                           '\\U00002A71',\n\t\"epsi;\":                            '\\U000003B5',\n\t\"epsilon;\":                         '\\U000003B5',\n\t\"epsiv;\":                           '\\U000003F5',\n\t\"eqcirc;\":                          '\\U00002256',\n\t\"eqcolon;\":                         '\\U00002255',\n\t\"eqsim;\":                           '\\U00002242',\n\t\"eqslantgtr;\":                      '\\U00002A96',\n\t\"eqslantless;\":                     '\\U00002A95',\n\t\"equals;\":                          '\\U0000003D',\n\t\"equest;\":                          '\\U0000225F',\n\t\"equiv;\":                           '\\U00002261',\n\t\"equivDD;\":                         '\\U00002A78',\n\t\"eqvparsl;\":                        '\\U000029E5',\n\t\"erDot;\":                           '\\U00002253',\n\t\"erarr;\":                           '\\U00002971',\n\t\"escr;\":                            '\\U0000212F',\n\t\"esdot;\":                           '\\U00002250',\n\t\"esim;\":                            '\\U00002242',\n\t\"eta;\":                             '\\U000003B7',\n\t\"eth;\":                             '\\U000000F0',\n\t\"euml;\":                            '\\U000000EB',\n\t\"euro;\":                            '\\U000020AC',\n\t\"excl;\":                            '\\U00000021',\n\t\"exist;\":                           '\\U00002203',\n\t\"expectation;\":                     '\\U00002130',\n\t\"exponentiale;\":                    '\\U00002147',\n\t\"fallingdotseq;\":                   '\\U00002252',\n\t\"fcy;\":                             '\\U00000444',\n\t\"female;\":                          '\\U00002640',\n\t\"ffilig;\":                          '\\U0000FB03',\n\t\"fflig;\":                           '\\U0000FB00',\n\t\"ffllig;\":                          '\\U0000FB04',\n\t\"ffr;\":                             '\\U0001D523',\n\t\"filig;\":                           '\\U0000FB01',\n\t\"flat;\":                            '\\U0000266D',\n\t\"fllig;\":                           '\\U0000FB02',\n\t\"fltns;\":                           '\\U000025B1',\n\t\"fnof;\":                            '\\U00000192',\n\t\"fopf;\":                            '\\U0001D557',\n\t\"forall;\":                          '\\U00002200',\n\t\"fork;\":                            '\\U000022D4',\n\t\"forkv;\":                           '\\U00002AD9',\n\t\"fpartint;\":                        '\\U00002A0D',\n\t\"frac12;\":                          '\\U000000BD',\n\t\"frac13;\":                          '\\U00002153',\n\t\"frac14;\":                          '\\U000000BC',\n\t\"frac15;\":                          '\\U00002155',\n\t\"frac16;\":                          '\\U00002159',\n\t\"frac18;\":                          '\\U0000215B',\n\t\"frac23;\":                          '\\U00002154',\n\t\"frac25;\":                          '\\U00002156',\n\t\"frac34;\":                          '\\U000000BE',\n\t\"frac35;\":                          '\\U00002157',\n\t\"frac38;\":                          '\\U0000215C',\n\t\"frac45;\":                          '\\U00002158',\n\t\"frac56;\":                          '\\U0000215A',\n\t\"frac58;\":                          '\\U0000215D',\n\t\"frac78;\":                          '\\U0000215E',\n\t\"frasl;\":                           '\\U00002044',\n\t\"frown;\":                           '\\U00002322',\n\t\"fscr;\":                            '\\U0001D4BB',\n\t\"gE;\":                              '\\U00002267',\n\t\"gEl;\":                             '\\U00002A8C',\n\t\"gacute;\":                          '\\U000001F5',\n\t\"gamma;\":                           '\\U000003B3',\n\t\"gammad;\":                          '\\U000003DD',\n\t\"gap;\":                             '\\U00002A86',\n\t\"gbreve;\":                          '\\U0000011F',\n\t\"gcirc;\":                           '\\U0000011D',\n\t\"gcy;\":                             '\\U00000433',\n\t\"gdot;\":                            '\\U00000121',\n\t\"ge;\":                              '\\U00002265',\n\t\"gel;\":                             '\\U000022DB',\n\t\"geq;\":                             '\\U00002265',\n\t\"geqq;\":                            '\\U00002267',\n\t\"geqslant;\":                        '\\U00002A7E',\n\t\"ges;\":                             '\\U00002A7E',\n\t\"gescc;\":                           '\\U00002AA9',\n\t\"gesdot;\":                          '\\U00002A80',\n\t\"gesdoto;\":                         '\\U00002A82',\n\t\"gesdotol;\":                        '\\U00002A84',\n\t\"gesles;\":                          '\\U00002A94',\n\t\"gfr;\":                             '\\U0001D524',\n\t\"gg;\":                              '\\U0000226B',\n\t\"ggg;\":                             '\\U000022D9',\n\t\"gimel;\":                           '\\U00002137',\n\t\"gjcy;\":                            '\\U00000453',\n\t\"gl;\":                              '\\U00002277',\n\t\"glE;\":                             '\\U00002A92',\n\t\"gla;\":                             '\\U00002AA5',\n\t\"glj;\":                             '\\U00002AA4',\n\t\"gnE;\":                             '\\U00002269',\n\t\"gnap;\":                            '\\U00002A8A',\n\t\"gnapprox;\":                        '\\U00002A8A',\n\t\"gne;\":                             '\\U00002A88',\n\t\"gneq;\":                            '\\U00002A88',\n\t\"gneqq;\":                           '\\U00002269',\n\t\"gnsim;\":                           '\\U000022E7',\n\t\"gopf;\":                            '\\U0001D558',\n\t\"grave;\":                           '\\U00000060',\n\t\"gscr;\":                            '\\U0000210A',\n\t\"gsim;\":                            '\\U00002273',\n\t\"gsime;\":                           '\\U00002A8E',\n\t\"gsiml;\":                           '\\U00002A90',\n\t\"gt;\":                              '\\U0000003E',\n\t\"gtcc;\":                            '\\U00002AA7',\n\t\"gtcir;\":                           '\\U00002A7A',\n\t\"gtdot;\":                           '\\U000022D7',\n\t\"gtlPar;\":                          '\\U00002995',\n\t\"gtquest;\":                         '\\U00002A7C',\n\t\"gtrapprox;\":                       '\\U00002A86',\n\t\"gtrarr;\":                          '\\U00002978',\n\t\"gtrdot;\":                          '\\U000022D7',\n\t\"gtreqless;\":                       '\\U000022DB',\n\t\"gtreqqless;\":                      '\\U00002A8C',\n\t\"gtrless;\":                         '\\U00002277',\n\t\"gtrsim;\":                          '\\U00002273',\n\t\"hArr;\":                            '\\U000021D4',\n\t\"hairsp;\":                          '\\U0000200A',\n\t\"half;\":                            '\\U000000BD',\n\t\"hamilt;\":                          '\\U0000210B',\n\t\"hardcy;\":                          '\\U0000044A',\n\t\"harr;\":                            '\\U00002194',\n\t\"harrcir;\":                         '\\U00002948',\n\t\"harrw;\":                           '\\U000021AD',\n\t\"hbar;\":                            '\\U0000210F',\n\t\"hcirc;\":                           '\\U00000125',\n\t\"hearts;\":                          '\\U00002665',\n\t\"heartsuit;\":                       '\\U00002665',\n\t\"hellip;\":                          '\\U00002026',\n\t\"hercon;\":                          '\\U000022B9',\n\t\"hfr;\":                             '\\U0001D525',\n\t\"hksearow;\":                        '\\U00002925',\n\t\"hkswarow;\":                        '\\U00002926',\n\t\"hoarr;\":                           '\\U000021FF',\n\t\"homtht;\":                          '\\U0000223B',\n\t\"hookleftarrow;\":                   '\\U000021A9',\n\t\"hookrightarrow;\":                  '\\U000021AA',\n\t\"hopf;\":                            '\\U0001D559',\n\t\"horbar;\":                          '\\U00002015',\n\t\"hscr;\":                            '\\U0001D4BD',\n\t\"hslash;\":                          '\\U0000210F',\n\t\"hstrok;\":                          '\\U00000127',\n\t\"hybull;\":                          '\\U00002043',\n\t\"hyphen;\":                          '\\U00002010',\n\t\"iacute;\":                          '\\U000000ED',\n\t\"ic;\":                              '\\U00002063',\n\t\"icirc;\":                           '\\U000000EE',\n\t\"icy;\":                             '\\U00000438',\n\t\"iecy;\":                            '\\U00000435',\n\t\"iexcl;\":                           '\\U000000A1',\n\t\"iff;\":                             '\\U000021D4',\n\t\"ifr;\":                             '\\U0001D526',\n\t\"igrave;\":                          '\\U000000EC',\n\t\"ii;\":                              '\\U00002148',\n\t\"iiiint;\":                          '\\U00002A0C',\n\t\"iiint;\":                           '\\U0000222D',\n\t\"iinfin;\":                          '\\U000029DC',\n\t\"iiota;\":                           '\\U00002129',\n\t\"ijlig;\":                           '\\U00000133',\n\t\"imacr;\":                           '\\U0000012B',\n\t\"image;\":                           '\\U00002111',\n\t\"imagline;\":                        '\\U00002110',\n\t\"imagpart;\":                        '\\U00002111',\n\t\"imath;\":                           '\\U00000131',\n\t\"imof;\":                            '\\U000022B7',\n\t\"imped;\":                           '\\U000001B5',\n\t\"in;\":                              '\\U00002208',\n\t\"incare;\":                          '\\U00002105',\n\t\"infin;\":                           '\\U0000221E',\n\t\"infintie;\":                        '\\U000029DD',\n\t\"inodot;\":                          '\\U00000131',\n\t\"int;\":                             '\\U0000222B',\n\t\"intcal;\":                          '\\U000022BA',\n\t\"integers;\":                        '\\U00002124',\n\t\"intercal;\":                        '\\U000022BA',\n\t\"intlarhk;\":                        '\\U00002A17',\n\t\"intprod;\":                         '\\U00002A3C',\n\t\"iocy;\":                            '\\U00000451',\n\t\"iogon;\":                           '\\U0000012F',\n\t\"iopf;\":                            '\\U0001D55A',\n\t\"iota;\":                            '\\U000003B9',\n\t\"iprod;\":                           '\\U00002A3C',\n\t\"iquest;\":                          '\\U000000BF',\n\t\"iscr;\":                            '\\U0001D4BE',\n\t\"isin;\":                            '\\U00002208',\n\t\"isinE;\":                           '\\U000022F9',\n\t\"isindot;\":                         '\\U000022F5',\n\t\"isins;\":                           '\\U000022F4',\n\t\"isinsv;\":                          '\\U000022F3',\n\t\"isinv;\":                           '\\U00002208',\n\t\"it;\":                              '\\U00002062',\n\t\"itilde;\":                          '\\U00000129',\n\t\"iukcy;\":                           '\\U00000456',\n\t\"iuml;\":                            '\\U000000EF',\n\t\"jcirc;\":                           '\\U00000135',\n\t\"jcy;\":                             '\\U00000439',\n\t\"jfr;\":                             '\\U0001D527',\n\t\"jmath;\":                           '\\U00000237',\n\t\"jopf;\":                            '\\U0001D55B',\n\t\"jscr;\":                            '\\U0001D4BF',\n\t\"jsercy;\":                          '\\U00000458',\n\t\"jukcy;\":                           '\\U00000454',\n\t\"kappa;\":                           '\\U000003BA',\n\t\"kappav;\":                          '\\U000003F0',\n\t\"kcedil;\":                          '\\U00000137',\n\t\"kcy;\":                             '\\U0000043A',\n\t\"kfr;\":                             '\\U0001D528',\n\t\"kgreen;\":                          '\\U00000138',\n\t\"khcy;\":                            '\\U00000445',\n\t\"kjcy;\":                            '\\U0000045C',\n\t\"kopf;\":                            '\\U0001D55C',\n\t\"kscr;\":                            '\\U0001D4C0',\n\t\"lAarr;\":                           '\\U000021DA',\n\t\"lArr;\":                            '\\U000021D0',\n\t\"lAtail;\":                          '\\U0000291B',\n\t\"lBarr;\":                           '\\U0000290E',\n\t\"lE;\":                              '\\U00002266',\n\t\"lEg;\":                             '\\U00002A8B',\n\t\"lHar;\":                            '\\U00002962',\n\t\"lacute;\":                          '\\U0000013A',\n\t\"laemptyv;\":                        '\\U000029B4',\n\t\"lagran;\":                          '\\U00002112',\n\t\"lambda;\":                          '\\U000003BB',\n\t\"lang;\":                            '\\U000027E8',\n\t\"langd;\":                           '\\U00002991',\n\t\"langle;\":                          '\\U000027E8',\n\t\"lap;\":                             '\\U00002A85',\n\t\"laquo;\":                           '\\U000000AB',\n\t\"larr;\":                            '\\U00002190',\n\t\"larrb;\":                           '\\U000021E4',\n\t\"larrbfs;\":                         '\\U0000291F',\n\t\"larrfs;\":                          '\\U0000291D',\n\t\"larrhk;\":                          '\\U000021A9',\n\t\"larrlp;\":                          '\\U000021AB',\n\t\"larrpl;\":                          '\\U00002939',\n\t\"larrsim;\":                         '\\U00002973',\n\t\"larrtl;\":                          '\\U000021A2',\n\t\"lat;\":                             '\\U00002AAB',\n\t\"latail;\":                          '\\U00002919',\n\t\"late;\":                            '\\U00002AAD',\n\t\"lbarr;\":                           '\\U0000290C',\n\t\"lbbrk;\":                           '\\U00002772',\n\t\"lbrace;\":                          '\\U0000007B',\n\t\"lbrack;\":                          '\\U0000005B',\n\t\"lbrke;\":                           '\\U0000298B',\n\t\"lbrksld;\":                         '\\U0000298F',\n\t\"lbrkslu;\":                         '\\U0000298D',\n\t\"lcaron;\":                          '\\U0000013E',\n\t\"lcedil;\":                          '\\U0000013C',\n\t\"lceil;\":                           '\\U00002308',\n\t\"lcub;\":                            '\\U0000007B',\n\t\"lcy;\":                             '\\U0000043B',\n\t\"ldca;\":                            '\\U00002936',\n\t\"ldquo;\":                           '\\U0000201C',\n\t\"ldquor;\":                          '\\U0000201E',\n\t\"ldrdhar;\":                         '\\U00002967',\n\t\"ldrushar;\":                        '\\U0000294B',\n\t\"ldsh;\":                            '\\U000021B2',\n\t\"le;\":                              '\\U00002264',\n\t\"leftarrow;\":                       '\\U00002190',\n\t\"leftarrowtail;\":                   '\\U000021A2',\n\t\"leftharpoondown;\":                 '\\U000021BD',\n\t\"leftharpoonup;\":                   '\\U000021BC',\n\t\"leftleftarrows;\":                  '\\U000021C7',\n\t\"leftrightarrow;\":                  '\\U00002194',\n\t\"leftrightarrows;\":                 '\\U000021C6',\n\t\"leftrightharpoons;\":               '\\U000021CB',\n\t\"leftrightsquigarrow;\":             '\\U000021AD',\n\t\"leftthreetimes;\":                  '\\U000022CB',\n\t\"leg;\":                             '\\U000022DA',\n\t\"leq;\":                             '\\U00002264',\n\t\"leqq;\":                            '\\U00002266',\n\t\"leqslant;\":                        '\\U00002A7D',\n\t\"les;\":                             '\\U00002A7D',\n\t\"lescc;\":                           '\\U00002AA8',\n\t\"lesdot;\":                          '\\U00002A7F',\n\t\"lesdoto;\":                         '\\U00002A81',\n\t\"lesdotor;\":                        '\\U00002A83',\n\t\"lesges;\":                          '\\U00002A93',\n\t\"lessapprox;\":                      '\\U00002A85',\n\t\"lessdot;\":                         '\\U000022D6',\n\t\"lesseqgtr;\":                       '\\U000022DA',\n\t\"lesseqqgtr;\":                      '\\U00002A8B',\n\t\"lessgtr;\":                         '\\U00002276',\n\t\"lesssim;\":                         '\\U00002272',\n\t\"lfisht;\":                          '\\U0000297C',\n\t\"lfloor;\":                          '\\U0000230A',\n\t\"lfr;\":                             '\\U0001D529',\n\t\"lg;\":                              '\\U00002276',\n\t\"lgE;\":                             '\\U00002A91',\n\t\"lhard;\":                           '\\U000021BD',\n\t\"lharu;\":                           '\\U000021BC',\n\t\"lharul;\":                          '\\U0000296A',\n\t\"lhblk;\":                           '\\U00002584',\n\t\"ljcy;\":                            '\\U00000459',\n\t\"ll;\":                              '\\U0000226A',\n\t\"llarr;\":                           '\\U000021C7',\n\t\"llcorner;\":                        '\\U0000231E',\n\t\"llhard;\":                          '\\U0000296B',\n\t\"lltri;\":                           '\\U000025FA',\n\t\"lmidot;\":                          '\\U00000140',\n\t\"lmoust;\":                          '\\U000023B0',\n\t\"lmoustache;\":                      '\\U000023B0',\n\t\"lnE;\":                             '\\U00002268',\n\t\"lnap;\":                            '\\U00002A89',\n\t\"lnapprox;\":                        '\\U00002A89',\n\t\"lne;\":                             '\\U00002A87',\n\t\"lneq;\":                            '\\U00002A87',\n\t\"lneqq;\":                           '\\U00002268',\n\t\"lnsim;\":                           '\\U000022E6',\n\t\"loang;\":                           '\\U000027EC',\n\t\"loarr;\":                           '\\U000021FD',\n\t\"lobrk;\":                           '\\U000027E6',\n\t\"longleftarrow;\":                   '\\U000027F5',\n\t\"longleftrightarrow;\":              '\\U000027F7',\n\t\"longmapsto;\":                      '\\U000027FC',\n\t\"longrightarrow;\":                  '\\U000027F6',\n\t\"looparrowleft;\":                   '\\U000021AB',\n\t\"looparrowright;\":                  '\\U000021AC',\n\t\"lopar;\":                           '\\U00002985',\n\t\"lopf;\":                            '\\U0001D55D',\n\t\"loplus;\":                          '\\U00002A2D',\n\t\"lotimes;\":                         '\\U00002A34',\n\t\"lowast;\":                          '\\U00002217',\n\t\"lowbar;\":                          '\\U0000005F',\n\t\"loz;\":                             '\\U000025CA',\n\t\"lozenge;\":                         '\\U000025CA',\n\t\"lozf;\":                            '\\U000029EB',\n\t\"lpar;\":                            '\\U00000028',\n\t\"lparlt;\":                          '\\U00002993',\n\t\"lrarr;\":                           '\\U000021C6',\n\t\"lrcorner;\":                        '\\U0000231F',\n\t\"lrhar;\":                           '\\U000021CB',\n\t\"lrhard;\":                          '\\U0000296D',\n\t\"lrm;\":                             '\\U0000200E',\n\t\"lrtri;\":                           '\\U000022BF',\n\t\"lsaquo;\":                          '\\U00002039',\n\t\"lscr;\":                            '\\U0001D4C1',\n\t\"lsh;\":                             '\\U000021B0',\n\t\"lsim;\":                            '\\U00002272',\n\t\"lsime;\":                           '\\U00002A8D',\n\t\"lsimg;\":                           '\\U00002A8F',\n\t\"lsqb;\":                            '\\U0000005B',\n\t\"lsquo;\":                           '\\U00002018',\n\t\"lsquor;\":                          '\\U0000201A',\n\t\"lstrok;\":                          '\\U00000142',\n\t\"lt;\":                              '\\U0000003C',\n\t\"ltcc;\":                            '\\U00002AA6',\n\t\"ltcir;\":                           '\\U00002A79',\n\t\"ltdot;\":                           '\\U000022D6',\n\t\"lthree;\":                          '\\U000022CB',\n\t\"ltimes;\":                          '\\U000022C9',\n\t\"ltlarr;\":                          '\\U00002976',\n\t\"ltquest;\":                         '\\U00002A7B',\n\t\"ltrPar;\":                          '\\U00002996',\n\t\"ltri;\":                            '\\U000025C3',\n\t\"ltrie;\":                           '\\U000022B4',\n\t\"ltrif;\":                           '\\U000025C2',\n\t\"lurdshar;\":                        '\\U0000294A',\n\t\"luruhar;\":                         '\\U00002966',\n\t\"mDDot;\":                           '\\U0000223A',\n\t\"macr;\":                            '\\U000000AF',\n\t\"male;\":                            '\\U00002642',\n\t\"malt;\":                            '\\U00002720',\n\t\"maltese;\":                         '\\U00002720',\n\t\"map;\":                             '\\U000021A6',\n\t\"mapsto;\":                          '\\U000021A6',\n\t\"mapstodown;\":                      '\\U000021A7',\n\t\"mapstoleft;\":                      '\\U000021A4',\n\t\"mapstoup;\":                        '\\U000021A5',\n\t\"marker;\":                          '\\U000025AE',\n\t\"mcomma;\":                          '\\U00002A29',\n\t\"mcy;\":                             '\\U0000043C',\n\t\"mdash;\":                           '\\U00002014',\n\t\"measuredangle;\":                   '\\U00002221',\n\t\"mfr;\":                             '\\U0001D52A',\n\t\"mho;\":                             '\\U00002127',\n\t\"micro;\":                           '\\U000000B5',\n\t\"mid;\":                             '\\U00002223',\n\t\"midast;\":                          '\\U0000002A',\n\t\"midcir;\":                          '\\U00002AF0',\n\t\"middot;\":                          '\\U000000B7',\n\t\"minus;\":                           '\\U00002212',\n\t\"minusb;\":                          '\\U0000229F',\n\t\"minusd;\":                          '\\U00002238',\n\t\"minusdu;\":                         '\\U00002A2A',\n\t\"mlcp;\":                            '\\U00002ADB',\n\t\"mldr;\":                            '\\U00002026',\n\t\"mnplus;\":                          '\\U00002213',\n\t\"models;\":                          '\\U000022A7',\n\t\"mopf;\":                            '\\U0001D55E',\n\t\"mp;\":                              '\\U00002213',\n\t\"mscr;\":                            '\\U0001D4C2',\n\t\"mstpos;\":                          '\\U0000223E',\n\t\"mu;\":                              '\\U000003BC',\n\t\"multimap;\":                        '\\U000022B8',\n\t\"mumap;\":                           '\\U000022B8',\n\t\"nLeftarrow;\":                      '\\U000021CD',\n\t\"nLeftrightarrow;\":                 '\\U000021CE',\n\t\"nRightarrow;\":                     '\\U000021CF',\n\t\"nVDash;\":                          '\\U000022AF',\n\t\"nVdash;\":                          '\\U000022AE',\n\t\"nabla;\":                           '\\U00002207',\n\t\"nacute;\":                          '\\U00000144',\n\t\"nap;\":                             '\\U00002249',\n\t\"napos;\":                           '\\U00000149',\n\t\"napprox;\":                         '\\U00002249',\n\t\"natur;\":                           '\\U0000266E',\n\t\"natural;\":                         '\\U0000266E',\n\t\"naturals;\":                        '\\U00002115',\n\t\"nbsp;\":                            '\\U000000A0',\n\t\"ncap;\":                            '\\U00002A43',\n\t\"ncaron;\":                          '\\U00000148',\n\t\"ncedil;\":                          '\\U00000146',\n\t\"ncong;\":                           '\\U00002247',\n\t\"ncup;\":                            '\\U00002A42',\n\t\"ncy;\":                             '\\U0000043D',\n\t\"ndash;\":                           '\\U00002013',\n\t\"ne;\":                              '\\U00002260',\n\t\"neArr;\":                           '\\U000021D7',\n\t\"nearhk;\":                          '\\U00002924',\n\t\"nearr;\":                           '\\U00002197',\n\t\"nearrow;\":                         '\\U00002197',\n\t\"nequiv;\":                          '\\U00002262',\n\t\"nesear;\":                          '\\U00002928',\n\t\"nexist;\":                          '\\U00002204',\n\t\"nexists;\":                         '\\U00002204',\n\t\"nfr;\":                             '\\U0001D52B',\n\t\"nge;\":                             '\\U00002271',\n\t\"ngeq;\":                            '\\U00002271',\n\t\"ngsim;\":                           '\\U00002275',\n\t\"ngt;\":                             '\\U0000226F',\n\t\"ngtr;\":                            '\\U0000226F',\n\t\"nhArr;\":                           '\\U000021CE',\n\t\"nharr;\":                           '\\U000021AE',\n\t\"nhpar;\":                           '\\U00002AF2',\n\t\"ni;\":                              '\\U0000220B',\n\t\"nis;\":                             '\\U000022FC',\n\t\"nisd;\":                            '\\U000022FA',\n\t\"niv;\":                             '\\U0000220B',\n\t\"njcy;\":                            '\\U0000045A',\n\t\"nlArr;\":                           '\\U000021CD',\n\t\"nlarr;\":                           '\\U0000219A',\n\t\"nldr;\":                            '\\U00002025',\n\t\"nle;\":                             '\\U00002270',\n\t\"nleftarrow;\":                      '\\U0000219A',\n\t\"nleftrightarrow;\":                 '\\U000021AE',\n\t\"nleq;\":                            '\\U00002270',\n\t\"nless;\":                           '\\U0000226E',\n\t\"nlsim;\":                           '\\U00002274',\n\t\"nlt;\":                             '\\U0000226E',\n\t\"nltri;\":                           '\\U000022EA',\n\t\"nltrie;\":                          '\\U000022EC',\n\t\"nmid;\":                            '\\U00002224',\n\t\"nopf;\":                            '\\U0001D55F',\n\t\"not;\":                             '\\U000000AC',\n\t\"notin;\":                           '\\U00002209',\n\t\"notinva;\":                         '\\U00002209',\n\t\"notinvb;\":                         '\\U000022F7',\n\t\"notinvc;\":                         '\\U000022F6',\n\t\"notni;\":                           '\\U0000220C',\n\t\"notniva;\":                         '\\U0000220C',\n\t\"notnivb;\":                         '\\U000022FE',\n\t\"notnivc;\":                         '\\U000022FD',\n\t\"npar;\":                            '\\U00002226',\n\t\"nparallel;\":                       '\\U00002226',\n\t\"npolint;\":                         '\\U00002A14',\n\t\"npr;\":                             '\\U00002280',\n\t\"nprcue;\":                          '\\U000022E0',\n\t\"nprec;\":                           '\\U00002280',\n\t\"nrArr;\":                           '\\U000021CF',\n\t\"nrarr;\":                           '\\U0000219B',\n\t\"nrightarrow;\":                     '\\U0000219B',\n\t\"nrtri;\":                           '\\U000022EB',\n\t\"nrtrie;\":                          '\\U000022ED',\n\t\"nsc;\":                             '\\U00002281',\n\t\"nsccue;\":                          '\\U000022E1',\n\t\"nscr;\":                            '\\U0001D4C3',\n\t\"nshortmid;\":                       '\\U00002224',\n\t\"nshortparallel;\":                  '\\U00002226',\n\t\"nsim;\":                            '\\U00002241',\n\t\"nsime;\":                           '\\U00002244',\n\t\"nsimeq;\":                          '\\U00002244',\n\t\"nsmid;\":                           '\\U00002224',\n\t\"nspar;\":                           '\\U00002226',\n\t\"nsqsube;\":                         '\\U000022E2',\n\t\"nsqsupe;\":                         '\\U000022E3',\n\t\"nsub;\":                            '\\U00002284',\n\t\"nsube;\":                           '\\U00002288',\n\t\"nsubseteq;\":                       '\\U00002288',\n\t\"nsucc;\":                           '\\U00002281',\n\t\"nsup;\":                            '\\U00002285',\n\t\"nsupe;\":                           '\\U00002289',\n\t\"nsupseteq;\":                       '\\U00002289',\n\t\"ntgl;\":                            '\\U00002279',\n\t\"ntilde;\":                          '\\U000000F1',\n\t\"ntlg;\":                            '\\U00002278',\n\t\"ntriangleleft;\":                   '\\U000022EA',\n\t\"ntrianglelefteq;\":                 '\\U000022EC',\n\t\"ntriangleright;\":                  '\\U000022EB',\n\t\"ntrianglerighteq;\":                '\\U000022ED',\n\t\"nu;\":                              '\\U000003BD',\n\t\"num;\":                             '\\U00000023',\n\t\"numero;\":                          '\\U00002116',\n\t\"numsp;\":                           '\\U00002007',\n\t\"nvDash;\":                          '\\U000022AD',\n\t\"nvHarr;\":                          '\\U00002904',\n\t\"nvdash;\":                          '\\U000022AC',\n\t\"nvinfin;\":                         '\\U000029DE',\n\t\"nvlArr;\":                          '\\U00002902',\n\t\"nvrArr;\":                          '\\U00002903',\n\t\"nwArr;\":                           '\\U000021D6',\n\t\"nwarhk;\":                          '\\U00002923',\n\t\"nwarr;\":                           '\\U00002196',\n\t\"nwarrow;\":                         '\\U00002196',\n\t\"nwnear;\":                          '\\U00002927',\n\t\"oS;\":                              '\\U000024C8',\n\t\"oacute;\":                          '\\U000000F3',\n\t\"oast;\":                            '\\U0000229B',\n\t\"ocir;\":                            '\\U0000229A',\n\t\"ocirc;\":                           '\\U000000F4',\n\t\"ocy;\":                             '\\U0000043E',\n\t\"odash;\":                           '\\U0000229D',\n\t\"odblac;\":                          '\\U00000151',\n\t\"odiv;\":                            '\\U00002A38',\n\t\"odot;\":                            '\\U00002299',\n\t\"odsold;\":                          '\\U000029BC',\n\t\"oelig;\":                           '\\U00000153',\n\t\"ofcir;\":                           '\\U000029BF',\n\t\"ofr;\":                             '\\U0001D52C',\n\t\"ogon;\":                            '\\U000002DB',\n\t\"ograve;\":                          '\\U000000F2',\n\t\"ogt;\":                             '\\U000029C1',\n\t\"ohbar;\":                           '\\U000029B5',\n\t\"ohm;\":                             '\\U000003A9',\n\t\"oint;\":                            '\\U0000222E',\n\t\"olarr;\":                           '\\U000021BA',\n\t\"olcir;\":                           '\\U000029BE',\n\t\"olcross;\":                         '\\U000029BB',\n\t\"oline;\":                           '\\U0000203E',\n\t\"olt;\":                             '\\U000029C0',\n\t\"omacr;\":                           '\\U0000014D',\n\t\"omega;\":                           '\\U000003C9',\n\t\"omicron;\":                         '\\U000003BF',\n\t\"omid;\":                            '\\U000029B6',\n\t\"ominus;\":                          '\\U00002296',\n\t\"oopf;\":                            '\\U0001D560',\n\t\"opar;\":                            '\\U000029B7',\n\t\"operp;\":                           '\\U000029B9',\n\t\"oplus;\":                           '\\U00002295',\n\t\"or;\":                              '\\U00002228',\n\t\"orarr;\":                           '\\U000021BB',\n\t\"ord;\":                             '\\U00002A5D',\n\t\"order;\":                           '\\U00002134',\n\t\"orderof;\":                         '\\U00002134',\n\t\"ordf;\":                            '\\U000000AA',\n\t\"ordm;\":                            '\\U000000BA',\n\t\"origof;\":                          '\\U000022B6',\n\t\"oror;\":                            '\\U00002A56',\n\t\"orslope;\":                         '\\U00002A57',\n\t\"orv;\":                             '\\U00002A5B',\n\t\"oscr;\":                            '\\U00002134',\n\t\"oslash;\":                          '\\U000000F8',\n\t\"osol;\":                            '\\U00002298',\n\t\"otilde;\":                          '\\U000000F5',\n\t\"otimes;\":                          '\\U00002297',\n\t\"otimesas;\":                        '\\U00002A36',\n\t\"ouml;\":                            '\\U000000F6',\n\t\"ovbar;\":                           '\\U0000233D',\n\t\"par;\":                             '\\U00002225',\n\t\"para;\":                            '\\U000000B6',\n\t\"parallel;\":                        '\\U00002225',\n\t\"parsim;\":                          '\\U00002AF3',\n\t\"parsl;\":                           '\\U00002AFD',\n\t\"part;\":                            '\\U00002202',\n\t\"pcy;\":                             '\\U0000043F',\n\t\"percnt;\":                          '\\U00000025',\n\t\"period;\":                          '\\U0000002E',\n\t\"permil;\":                          '\\U00002030',\n\t\"perp;\":                            '\\U000022A5',\n\t\"pertenk;\":                         '\\U00002031',\n\t\"pfr;\":                             '\\U0001D52D',\n\t\"phi;\":                             '\\U000003C6',\n\t\"phiv;\":                            '\\U000003D5',\n\t\"phmmat;\":                          '\\U00002133',\n\t\"phone;\":                           '\\U0000260E',\n\t\"pi;\":                              '\\U000003C0',\n\t\"pitchfork;\":                       '\\U000022D4',\n\t\"piv;\":                             '\\U000003D6',\n\t\"planck;\":                          '\\U0000210F',\n\t\"planckh;\":                         '\\U0000210E',\n\t\"plankv;\":                          '\\U0000210F',\n\t\"plus;\":                            '\\U0000002B',\n\t\"plusacir;\":                        '\\U00002A23',\n\t\"plusb;\":                           '\\U0000229E',\n\t\"pluscir;\":                         '\\U00002A22',\n\t\"plusdo;\":                          '\\U00002214',\n\t\"plusdu;\":                          '\\U00002A25',\n\t\"pluse;\":                           '\\U00002A72',\n\t\"plusmn;\":                          '\\U000000B1',\n\t\"plussim;\":                         '\\U00002A26',\n\t\"plustwo;\":                         '\\U00002A27',\n\t\"pm;\":                              '\\U000000B1',\n\t\"pointint;\":                        '\\U00002A15',\n\t\"popf;\":                            '\\U0001D561',\n\t\"pound;\":                           '\\U000000A3',\n\t\"pr;\":                              '\\U0000227A',\n\t\"prE;\":                             '\\U00002AB3',\n\t\"prap;\":                            '\\U00002AB7',\n\t\"prcue;\":                           '\\U0000227C',\n\t\"pre;\":                             '\\U00002AAF',\n\t\"prec;\":                            '\\U0000227A',\n\t\"precapprox;\":                      '\\U00002AB7',\n\t\"preccurlyeq;\":                     '\\U0000227C',\n\t\"preceq;\":                          '\\U00002AAF',\n\t\"precnapprox;\":                     '\\U00002AB9',\n\t\"precneqq;\":                        '\\U00002AB5',\n\t\"precnsim;\":                        '\\U000022E8',\n\t\"precsim;\":                         '\\U0000227E',\n\t\"prime;\":                           '\\U00002032',\n\t\"primes;\":                          '\\U00002119',\n\t\"prnE;\":                            '\\U00002AB5',\n\t\"prnap;\":                           '\\U00002AB9',\n\t\"prnsim;\":                          '\\U000022E8',\n\t\"prod;\":                            '\\U0000220F',\n\t\"profalar;\":                        '\\U0000232E',\n\t\"profline;\":                        '\\U00002312',\n\t\"profsurf;\":                        '\\U00002313',\n\t\"prop;\":                            '\\U0000221D',\n\t\"propto;\":                          '\\U0000221D',\n\t\"prsim;\":                           '\\U0000227E',\n\t\"prurel;\":                          '\\U000022B0',\n\t\"pscr;\":                            '\\U0001D4C5',\n\t\"psi;\":                             '\\U000003C8',\n\t\"puncsp;\":                          '\\U00002008',\n\t\"qfr;\":                             '\\U0001D52E',\n\t\"qint;\":                            '\\U00002A0C',\n\t\"qopf;\":                            '\\U0001D562',\n\t\"qprime;\":                          '\\U00002057',\n\t\"qscr;\":                            '\\U0001D4C6',\n\t\"quaternions;\":                     '\\U0000210D',\n\t\"quatint;\":                         '\\U00002A16',\n\t\"quest;\":                           '\\U0000003F',\n\t\"questeq;\":                         '\\U0000225F',\n\t\"quot;\":                            '\\U00000022',\n\t\"rAarr;\":                           '\\U000021DB',\n\t\"rArr;\":                            '\\U000021D2',\n\t\"rAtail;\":                          '\\U0000291C',\n\t\"rBarr;\":                           '\\U0000290F',\n\t\"rHar;\":                            '\\U00002964',\n\t\"racute;\":                          '\\U00000155',\n\t\"radic;\":                           '\\U0000221A',\n\t\"raemptyv;\":                        '\\U000029B3',\n\t\"rang;\":                            '\\U000027E9',\n\t\"rangd;\":                           '\\U00002992',\n\t\"range;\":                           '\\U000029A5',\n\t\"rangle;\":                          '\\U000027E9',\n\t\"raquo;\":                           '\\U000000BB',\n\t\"rarr;\":                            '\\U00002192',\n\t\"rarrap;\":                          '\\U00002975',\n\t\"rarrb;\":                           '\\U000021E5',\n\t\"rarrbfs;\":                         '\\U00002920',\n\t\"rarrc;\":                           '\\U00002933',\n\t\"rarrfs;\":                          '\\U0000291E',\n\t\"rarrhk;\":                          '\\U000021AA',\n\t\"rarrlp;\":                          '\\U000021AC',\n\t\"rarrpl;\":                          '\\U00002945',\n\t\"rarrsim;\":                         '\\U00002974',\n\t\"rarrtl;\":                          '\\U000021A3',\n\t\"rarrw;\":                           '\\U0000219D',\n\t\"ratail;\":                          '\\U0000291A',\n\t\"ratio;\":                           '\\U00002236',\n\t\"rationals;\":                       '\\U0000211A',\n\t\"rbarr;\":                           '\\U0000290D',\n\t\"rbbrk;\":                           '\\U00002773',\n\t\"rbrace;\":                          '\\U0000007D',\n\t\"rbrack;\":                          '\\U0000005D',\n\t\"rbrke;\":                           '\\U0000298C',\n\t\"rbrksld;\":                         '\\U0000298E',\n\t\"rbrkslu;\":                         '\\U00002990',\n\t\"rcaron;\":                          '\\U00000159',\n\t\"rcedil;\":                          '\\U00000157',\n\t\"rceil;\":                           '\\U00002309',\n\t\"rcub;\":                            '\\U0000007D',\n\t\"rcy;\":                             '\\U00000440',\n\t\"rdca;\":                            '\\U00002937',\n\t\"rdldhar;\":                         '\\U00002969',\n\t\"rdquo;\":                           '\\U0000201D',\n\t\"rdquor;\":                          '\\U0000201D',\n\t\"rdsh;\":                            '\\U000021B3',\n\t\"real;\":                            '\\U0000211C',\n\t\"realine;\":                         '\\U0000211B',\n\t\"realpart;\":                        '\\U0000211C',\n\t\"reals;\":                           '\\U0000211D',\n\t\"rect;\":                            '\\U000025AD',\n\t\"reg;\":                             '\\U000000AE',\n\t\"rfisht;\":                          '\\U0000297D',\n\t\"rfloor;\":                          '\\U0000230B',\n\t\"rfr;\":                             '\\U0001D52F',\n\t\"rhard;\":                           '\\U000021C1',\n\t\"rharu;\":                           '\\U000021C0',\n\t\"rharul;\":                          '\\U0000296C',\n\t\"rho;\":                             '\\U000003C1',\n\t\"rhov;\":                            '\\U000003F1',\n\t\"rightarrow;\":                      '\\U00002192',\n\t\"rightarrowtail;\":                  '\\U000021A3',\n\t\"rightharpoondown;\":                '\\U000021C1',\n\t\"rightharpoonup;\":                  '\\U000021C0',\n\t\"rightleftarrows;\":                 '\\U000021C4',\n\t\"rightleftharpoons;\":               '\\U000021CC',\n\t\"rightrightarrows;\":                '\\U000021C9',\n\t\"rightsquigarrow;\":                 '\\U0000219D',\n\t\"rightthreetimes;\":                 '\\U000022CC',\n\t\"ring;\":                            '\\U000002DA',\n\t\"risingdotseq;\":                    '\\U00002253',\n\t\"rlarr;\":                           '\\U000021C4',\n\t\"rlhar;\":                           '\\U000021CC',\n\t\"rlm;\":                             '\\U0000200F',\n\t\"rmoust;\":                          '\\U000023B1',\n\t\"rmoustache;\":                      '\\U000023B1',\n\t\"rnmid;\":                           '\\U00002AEE',\n\t\"roang;\":                           '\\U000027ED',\n\t\"roarr;\":                           '\\U000021FE',\n\t\"robrk;\":                           '\\U000027E7',\n\t\"ropar;\":                           '\\U00002986',\n\t\"ropf;\":                            '\\U0001D563',\n\t\"roplus;\":                          '\\U00002A2E',\n\t\"rotimes;\":                         '\\U00002A35',\n\t\"rpar;\":                            '\\U00000029',\n\t\"rpargt;\":                          '\\U00002994',\n\t\"rppolint;\":                        '\\U00002A12',\n\t\"rrarr;\":                           '\\U000021C9',\n\t\"rsaquo;\":                          '\\U0000203A',\n\t\"rscr;\":                            '\\U0001D4C7',\n\t\"rsh;\":                             '\\U000021B1',\n\t\"rsqb;\":                            '\\U0000005D',\n\t\"rsquo;\":                           '\\U00002019',\n\t\"rsquor;\":                          '\\U00002019',\n\t\"rthree;\":                          '\\U000022CC',\n\t\"rtimes;\":                          '\\U000022CA',\n\t\"rtri;\":                            '\\U000025B9',\n\t\"rtrie;\":                           '\\U000022B5',\n\t\"rtrif;\":                           '\\U000025B8',\n\t\"rtriltri;\":                        '\\U000029CE',\n\t\"ruluhar;\":                         '\\U00002968',\n\t\"rx;\":                              '\\U0000211E',\n\t\"sacute;\":                          '\\U0000015B',\n\t\"sbquo;\":                           '\\U0000201A',\n\t\"sc;\":                              '\\U0000227B',\n\t\"scE;\":                             '\\U00002AB4',\n\t\"scap;\":                            '\\U00002AB8',\n\t\"scaron;\":                          '\\U00000161',\n\t\"sccue;\":                           '\\U0000227D',\n\t\"sce;\":                             '\\U00002AB0',\n\t\"scedil;\":                          '\\U0000015F',\n\t\"scirc;\":                           '\\U0000015D',\n\t\"scnE;\":                            '\\U00002AB6',\n\t\"scnap;\":                           '\\U00002ABA',\n\t\"scnsim;\":                          '\\U000022E9',\n\t\"scpolint;\":                        '\\U00002A13',\n\t\"scsim;\":                           '\\U0000227F',\n\t\"scy;\":                             '\\U00000441',\n\t\"sdot;\":                            '\\U000022C5',\n\t\"sdotb;\":                           '\\U000022A1',\n\t\"sdote;\":                           '\\U00002A66',\n\t\"seArr;\":                           '\\U000021D8',\n\t\"searhk;\":                          '\\U00002925',\n\t\"searr;\":                           '\\U00002198',\n\t\"searrow;\":                         '\\U00002198',\n\t\"sect;\":                            '\\U000000A7',\n\t\"semi;\":                            '\\U0000003B',\n\t\"seswar;\":                          '\\U00002929',\n\t\"setminus;\":                        '\\U00002216',\n\t\"setmn;\":                           '\\U00002216',\n\t\"sext;\":                            '\\U00002736',\n\t\"sfr;\":                             '\\U0001D530',\n\t\"sfrown;\":                          '\\U00002322',\n\t\"sharp;\":                           '\\U0000266F',\n\t\"shchcy;\":                          '\\U00000449',\n\t\"shcy;\":                            '\\U00000448',\n\t\"shortmid;\":                        '\\U00002223',\n\t\"shortparallel;\":                   '\\U00002225',\n\t\"shy;\":                             '\\U000000AD',\n\t\"sigma;\":                           '\\U000003C3',\n\t\"sigmaf;\":                          '\\U000003C2',\n\t\"sigmav;\":                          '\\U000003C2',\n\t\"sim;\":                             '\\U0000223C',\n\t\"simdot;\":                          '\\U00002A6A',\n\t\"sime;\":                            '\\U00002243',\n\t\"simeq;\":                           '\\U00002243',\n\t\"simg;\":                            '\\U00002A9E',\n\t\"simgE;\":                           '\\U00002AA0',\n\t\"siml;\":                            '\\U00002A9D',\n\t\"simlE;\":                           '\\U00002A9F',\n\t\"simne;\":                           '\\U00002246',\n\t\"simplus;\":                         '\\U00002A24',\n\t\"simrarr;\":                         '\\U00002972',\n\t\"slarr;\":                           '\\U00002190',\n\t\"smallsetminus;\":                   '\\U00002216',\n\t\"smashp;\":                          '\\U00002A33',\n\t\"smeparsl;\":                        '\\U000029E4',\n\t\"smid;\":                            '\\U00002223',\n\t\"smile;\":                           '\\U00002323',\n\t\"smt;\":                             '\\U00002AAA',\n\t\"smte;\":                            '\\U00002AAC',\n\t\"softcy;\":                          '\\U0000044C',\n\t\"sol;\":                             '\\U0000002F',\n\t\"solb;\":                            '\\U000029C4',\n\t\"solbar;\":                          '\\U0000233F',\n\t\"sopf;\":                            '\\U0001D564',\n\t\"spades;\":                          '\\U00002660',\n\t\"spadesuit;\":                       '\\U00002660',\n\t\"spar;\":                            '\\U00002225',\n\t\"sqcap;\":                           '\\U00002293',\n\t\"sqcup;\":                           '\\U00002294',\n\t\"sqsub;\":                           '\\U0000228F',\n\t\"sqsube;\":                          '\\U00002291',\n\t\"sqsubset;\":                        '\\U0000228F',\n\t\"sqsubseteq;\":                      '\\U00002291',\n\t\"sqsup;\":                           '\\U00002290',\n\t\"sqsupe;\":                          '\\U00002292',\n\t\"sqsupset;\":                        '\\U00002290',\n\t\"sqsupseteq;\":                      '\\U00002292',\n\t\"squ;\":                             '\\U000025A1',\n\t\"square;\":                          '\\U000025A1',\n\t\"squarf;\":                          '\\U000025AA',\n\t\"squf;\":                            '\\U000025AA',\n\t\"srarr;\":                           '\\U00002192',\n\t\"sscr;\":                            '\\U0001D4C8',\n\t\"ssetmn;\":                          '\\U00002216',\n\t\"ssmile;\":                          '\\U00002323',\n\t\"sstarf;\":                          '\\U000022C6',\n\t\"star;\":                            '\\U00002606',\n\t\"starf;\":                           '\\U00002605',\n\t\"straightepsilon;\":                 '\\U000003F5',\n\t\"straightphi;\":                     '\\U000003D5',\n\t\"strns;\":                           '\\U000000AF',\n\t\"sub;\":                             '\\U00002282',\n\t\"subE;\":                            '\\U00002AC5',\n\t\"subdot;\":                          '\\U00002ABD',\n\t\"sube;\":                            '\\U00002286',\n\t\"subedot;\":                         '\\U00002AC3',\n\t\"submult;\":                         '\\U00002AC1',\n\t\"subnE;\":                           '\\U00002ACB',\n\t\"subne;\":                           '\\U0000228A',\n\t\"subplus;\":                         '\\U00002ABF',\n\t\"subrarr;\":                         '\\U00002979',\n\t\"subset;\":                          '\\U00002282',\n\t\"subseteq;\":                        '\\U00002286',\n\t\"subseteqq;\":                       '\\U00002AC5',\n\t\"subsetneq;\":                       '\\U0000228A',\n\t\"subsetneqq;\":                      '\\U00002ACB',\n\t\"subsim;\":                          '\\U00002AC7',\n\t\"subsub;\":                          '\\U00002AD5',\n\t\"subsup;\":                          '\\U00002AD3',\n\t\"succ;\":                            '\\U0000227B',\n\t\"succapprox;\":                      '\\U00002AB8',\n\t\"succcurlyeq;\":                     '\\U0000227D',\n\t\"succeq;\":                          '\\U00002AB0',\n\t\"succnapprox;\":                     '\\U00002ABA',\n\t\"succneqq;\":                        '\\U00002AB6',\n\t\"succnsim;\":                        '\\U000022E9',\n\t\"succsim;\":                         '\\U0000227F',\n\t\"sum;\":                             '\\U00002211',\n\t\"sung;\":                            '\\U0000266A',\n\t\"sup;\":                             '\\U00002283',\n\t\"sup1;\":                            '\\U000000B9',\n\t\"sup2;\":                            '\\U000000B2',\n\t\"sup3;\":                            '\\U000000B3',\n\t\"supE;\":                            '\\U00002AC6',\n\t\"supdot;\":                          '\\U00002ABE',\n\t\"supdsub;\":                         '\\U00002AD8',\n\t\"supe;\":                            '\\U00002287',\n\t\"supedot;\":                         '\\U00002AC4',\n\t\"suphsol;\":                         '\\U000027C9',\n\t\"suphsub;\":                         '\\U00002AD7',\n\t\"suplarr;\":                         '\\U0000297B',\n\t\"supmult;\":                         '\\U00002AC2',\n\t\"supnE;\":                           '\\U00002ACC',\n\t\"supne;\":                           '\\U0000228B',\n\t\"supplus;\":                         '\\U00002AC0',\n\t\"supset;\":                          '\\U00002283',\n\t\"supseteq;\":                        '\\U00002287',\n\t\"supseteqq;\":                       '\\U00002AC6',\n\t\"supsetneq;\":                       '\\U0000228B',\n\t\"supsetneqq;\":                      '\\U00002ACC',\n\t\"supsim;\":                          '\\U00002AC8',\n\t\"supsub;\":                          '\\U00002AD4',\n\t\"supsup;\":                          '\\U00002AD6',\n\t\"swArr;\":                           '\\U000021D9',\n\t\"swarhk;\":                          '\\U00002926',\n\t\"swarr;\":                           '\\U00002199',\n\t\"swarrow;\":                         '\\U00002199',\n\t\"swnwar;\":                          '\\U0000292A',\n\t\"szlig;\":                           '\\U000000DF',\n\t\"target;\":                          '\\U00002316',\n\t\"tau;\":                             '\\U000003C4',\n\t\"tbrk;\":                            '\\U000023B4',\n\t\"tcaron;\":                          '\\U00000165',\n\t\"tcedil;\":                          '\\U00000163',\n\t\"tcy;\":                             '\\U00000442',\n\t\"tdot;\":                            '\\U000020DB',\n\t\"telrec;\":                          '\\U00002315',\n\t\"tfr;\":                             '\\U0001D531',\n\t\"there4;\":                          '\\U00002234',\n\t\"therefore;\":                       '\\U00002234',\n\t\"theta;\":                           '\\U000003B8',\n\t\"thetasym;\":                        '\\U000003D1',\n\t\"thetav;\":                          '\\U000003D1',\n\t\"thickapprox;\":                     '\\U00002248',\n\t\"thicksim;\":                        '\\U0000223C',\n\t\"thinsp;\":                          '\\U00002009',\n\t\"thkap;\":                           '\\U00002248',\n\t\"thksim;\":                          '\\U0000223C',\n\t\"thorn;\":                           '\\U000000FE',\n\t\"tilde;\":                           '\\U000002DC',\n\t\"times;\":                           '\\U000000D7',\n\t\"timesb;\":                          '\\U000022A0',\n\t\"timesbar;\":                        '\\U00002A31',\n\t\"timesd;\":                          '\\U00002A30',\n\t\"tint;\":                            '\\U0000222D',\n\t\"toea;\":                            '\\U00002928',\n\t\"top;\":                             '\\U000022A4',\n\t\"topbot;\":                          '\\U00002336',\n\t\"topcir;\":                          '\\U00002AF1',\n\t\"topf;\":                            '\\U0001D565',\n\t\"topfork;\":                         '\\U00002ADA',\n\t\"tosa;\":                            '\\U00002929',\n\t\"tprime;\":                          '\\U00002034',\n\t\"trade;\":                           '\\U00002122',\n\t\"triangle;\":                        '\\U000025B5',\n\t\"triangledown;\":                    '\\U000025BF',\n\t\"triangleleft;\":                    '\\U000025C3',\n\t\"trianglelefteq;\":                  '\\U000022B4',\n\t\"triangleq;\":                       '\\U0000225C',\n\t\"triangleright;\":                   '\\U000025B9',\n\t\"trianglerighteq;\":                 '\\U000022B5',\n\t\"tridot;\":                          '\\U000025EC',\n\t\"trie;\":                            '\\U0000225C',\n\t\"triminus;\":                        '\\U00002A3A',\n\t\"triplus;\":                         '\\U00002A39',\n\t\"trisb;\":                           '\\U000029CD',\n\t\"tritime;\":                         '\\U00002A3B',\n\t\"trpezium;\":                        '\\U000023E2',\n\t\"tscr;\":                            '\\U0001D4C9',\n\t\"tscy;\":                            '\\U00000446',\n\t\"tshcy;\":                           '\\U0000045B',\n\t\"tstrok;\":                          '\\U00000167',\n\t\"twixt;\":                           '\\U0000226C',\n\t\"twoheadleftarrow;\":                '\\U0000219E',\n\t\"twoheadrightarrow;\":               '\\U000021A0',\n\t\"uArr;\":                            '\\U000021D1',\n\t\"uHar;\":                            '\\U00002963',\n\t\"uacute;\":                          '\\U000000FA',\n\t\"uarr;\":                            '\\U00002191',\n\t\"ubrcy;\":                           '\\U0000045E',\n\t\"ubreve;\":                          '\\U0000016D',\n\t\"ucirc;\":                           '\\U000000FB',\n\t\"ucy;\":                             '\\U00000443',\n\t\"udarr;\":                           '\\U000021C5',\n\t\"udblac;\":                          '\\U00000171',\n\t\"udhar;\":                           '\\U0000296E',\n\t\"ufisht;\":                          '\\U0000297E',\n\t\"ufr;\":                             '\\U0001D532',\n\t\"ugrave;\":                          '\\U000000F9',\n\t\"uharl;\":                           '\\U000021BF',\n\t\"uharr;\":                           '\\U000021BE',\n\t\"uhblk;\":                           '\\U00002580',\n\t\"ulcorn;\":                          '\\U0000231C',\n\t\"ulcorner;\":                        '\\U0000231C',\n\t\"ulcrop;\":                          '\\U0000230F',\n\t\"ultri;\":                           '\\U000025F8',\n\t\"umacr;\":                           '\\U0000016B',\n\t\"uml;\":                             '\\U000000A8',\n\t\"uogon;\":                           '\\U00000173',\n\t\"uopf;\":                            '\\U0001D566',\n\t\"uparrow;\":                         '\\U00002191',\n\t\"updownarrow;\":                     '\\U00002195',\n\t\"upharpoonleft;\":                   '\\U000021BF',\n\t\"upharpoonright;\":                  '\\U000021BE',\n\t\"uplus;\":                           '\\U0000228E',\n\t\"upsi;\":                            '\\U000003C5',\n\t\"upsih;\":                           '\\U000003D2',\n\t\"upsilon;\":                         '\\U000003C5',\n\t\"upuparrows;\":                      '\\U000021C8',\n\t\"urcorn;\":                          '\\U0000231D',\n\t\"urcorner;\":                        '\\U0000231D',\n\t\"urcrop;\":                          '\\U0000230E',\n\t\"uring;\":                           '\\U0000016F',\n\t\"urtri;\":                           '\\U000025F9',\n\t\"uscr;\":                            '\\U0001D4CA',\n\t\"utdot;\":                           '\\U000022F0',\n\t\"utilde;\":                          '\\U00000169',\n\t\"utri;\":                            '\\U000025B5',\n\t\"utrif;\":                           '\\U000025B4',\n\t\"uuarr;\":                           '\\U000021C8',\n\t\"uuml;\":                            '\\U000000FC',\n\t\"uwangle;\":                         '\\U000029A7',\n\t\"vArr;\":                            '\\U000021D5',\n\t\"vBar;\":                            '\\U00002AE8',\n\t\"vBarv;\":                           '\\U00002AE9',\n\t\"vDash;\":                           '\\U000022A8',\n\t\"vangrt;\":                          '\\U0000299C',\n\t\"varepsilon;\":                      '\\U000003F5',\n\t\"varkappa;\":                        '\\U000003F0',\n\t\"varnothing;\":                      '\\U00002205',\n\t\"varphi;\":                          '\\U000003D5',\n\t\"varpi;\":                           '\\U000003D6',\n\t\"varpropto;\":                       '\\U0000221D',\n\t\"varr;\":                            '\\U00002195',\n\t\"varrho;\":                          '\\U000003F1',\n\t\"varsigma;\":                        '\\U000003C2',\n\t\"vartheta;\":                        '\\U000003D1',\n\t\"vartriangleleft;\":                 '\\U000022B2',\n\t\"vartriangleright;\":                '\\U000022B3',\n\t\"vcy;\":                             '\\U00000432',\n\t\"vdash;\":                           '\\U000022A2',\n\t\"vee;\":                             '\\U00002228',\n\t\"veebar;\":                          '\\U000022BB',\n\t\"veeeq;\":                           '\\U0000225A',\n\t\"vellip;\":                          '\\U000022EE',\n\t\"verbar;\":                          '\\U0000007C',\n\t\"vert;\":                            '\\U0000007C',\n\t\"vfr;\":                             '\\U0001D533',\n\t\"vltri;\":                           '\\U000022B2',\n\t\"vopf;\":                            '\\U0001D567',\n\t\"vprop;\":                           '\\U0000221D',\n\t\"vrtri;\":                           '\\U000022B3',\n\t\"vscr;\":                            '\\U0001D4CB',\n\t\"vzigzag;\":                         '\\U0000299A',\n\t\"wcirc;\":                           '\\U00000175',\n\t\"wedbar;\":                          '\\U00002A5F',\n\t\"wedge;\":                           '\\U00002227',\n\t\"wedgeq;\":                          '\\U00002259',\n\t\"weierp;\":                          '\\U00002118',\n\t\"wfr;\":                             '\\U0001D534',\n\t\"wopf;\":                            '\\U0001D568',\n\t\"wp;\":                              '\\U00002118',\n\t\"wr;\":                              '\\U00002240',\n\t\"wreath;\":                          '\\U00002240',\n\t\"wscr;\":                            '\\U0001D4CC',\n\t\"xcap;\":                            '\\U000022C2',\n\t\"xcirc;\":                           '\\U000025EF',\n\t\"xcup;\":                            '\\U000022C3',\n\t\"xdtri;\":                           '\\U000025BD',\n\t\"xfr;\":                             '\\U0001D535',\n\t\"xhArr;\":                           '\\U000027FA',\n\t\"xharr;\":                           '\\U000027F7',\n\t\"xi;\":                              '\\U000003BE',\n\t\"xlArr;\":                           '\\U000027F8',\n\t\"xlarr;\":                           '\\U000027F5',\n\t\"xmap;\":                            '\\U000027FC',\n\t\"xnis;\":                            '\\U000022FB',\n\t\"xodot;\":                           '\\U00002A00',\n\t\"xopf;\":                            '\\U0001D569',\n\t\"xoplus;\":                          '\\U00002A01',\n\t\"xotime;\":                          '\\U00002A02',\n\t\"xrArr;\":                           '\\U000027F9',\n\t\"xrarr;\":                           '\\U000027F6',\n\t\"xscr;\":                            '\\U0001D4CD',\n\t\"xsqcup;\":                          '\\U00002A06',\n\t\"xuplus;\":                          '\\U00002A04',\n\t\"xutri;\":                           '\\U000025B3',\n\t\"xvee;\":                            '\\U000022C1',\n\t\"xwedge;\":                          '\\U000022C0',\n\t\"yacute;\":                          '\\U000000FD',\n\t\"yacy;\":                            '\\U0000044F',\n\t\"ycirc;\":                           '\\U00000177',\n\t\"ycy;\":                             '\\U0000044B',\n\t\"yen;\":                             '\\U000000A5',\n\t\"yfr;\":                             '\\U0001D536',\n\t\"yicy;\":                            '\\U00000457',\n\t\"yopf;\":                            '\\U0001D56A',\n\t\"yscr;\":                            '\\U0001D4CE',\n\t\"yucy;\":                            '\\U0000044E',\n\t\"yuml;\":                            '\\U000000FF',\n\t\"zacute;\":                          '\\U0000017A',\n\t\"zcaron;\":                          '\\U0000017E',\n\t\"zcy;\":                             '\\U00000437',\n\t\"zdot;\":                            '\\U0000017C',\n\t\"zeetrf;\":                          '\\U00002128',\n\t\"zeta;\":                            '\\U000003B6',\n\t\"zfr;\":                             '\\U0001D537',\n\t\"zhcy;\":                            '\\U00000436',\n\t\"zigrarr;\":                         '\\U000021DD',\n\t\"zopf;\":                            '\\U0001D56B',\n\t\"zscr;\":                            '\\U0001D4CF',\n\t\"zwj;\":                             '\\U0000200D',\n\t\"zwnj;\":                            '\\U0000200C',\n\t\"AElig\":                            '\\U000000C6',\n\t\"AMP\":                              '\\U00000026',\n\t\"Aacute\":                           '\\U000000C1',\n\t\"Acirc\":                            '\\U000000C2',\n\t\"Agrave\":                           '\\U000000C0',\n\t\"Aring\":                            '\\U000000C5',\n\t\"Atilde\":                           '\\U000000C3',\n\t\"Auml\":                             '\\U000000C4',\n\t\"COPY\":                             '\\U000000A9',\n\t\"Ccedil\":                           '\\U000000C7',\n\t\"ETH\":                              '\\U000000D0',\n\t\"Eacute\":                           '\\U000000C9',\n\t\"Ecirc\":                            '\\U000000CA',\n\t\"Egrave\":                           '\\U000000C8',\n\t\"Euml\":                             '\\U000000CB',\n\t\"GT\":                               '\\U0000003E',\n\t\"Iacute\":                           '\\U000000CD',\n\t\"Icirc\":                            '\\U000000CE',\n\t\"Igrave\":                           '\\U000000CC',\n\t\"Iuml\":                             '\\U000000CF',\n\t\"LT\":                               '\\U0000003C',\n\t\"Ntilde\":                           '\\U000000D1',\n\t\"Oacute\":                           '\\U000000D3',\n\t\"Ocirc\":                            '\\U000000D4',\n\t\"Ograve\":                           '\\U000000D2',\n\t\"Oslash\":                           '\\U000000D8',\n\t\"Otilde\":                           '\\U000000D5',\n\t\"Ouml\":                             '\\U000000D6',\n\t\"QUOT\":                             '\\U00000022',\n\t\"REG\":                              '\\U000000AE',\n\t\"THORN\":                            '\\U000000DE',\n\t\"Uacute\":                           '\\U000000DA',\n\t\"Ucirc\":                            '\\U000000DB',\n\t\"Ugrave\":                           '\\U000000D9',\n\t\"Uuml\":                             '\\U000000DC',\n\t\"Yacute\":                           '\\U000000DD',\n\t\"aacute\":                           '\\U000000E1',\n\t\"acirc\":                            '\\U000000E2',\n\t\"acute\":                            '\\U000000B4',\n\t\"aelig\":                            '\\U000000E6',\n\t\"agrave\":                           '\\U000000E0',\n\t\"amp\":                              '\\U00000026',\n\t\"aring\":                            '\\U000000E5',\n\t\"atilde\":                           '\\U000000E3',\n\t\"auml\":                             '\\U000000E4',\n\t\"brvbar\":                           '\\U000000A6',\n\t\"ccedil\":                           '\\U000000E7',\n\t\"cedil\":                            '\\U000000B8',\n\t\"cent\":                             '\\U000000A2',\n\t\"copy\":                             '\\U000000A9',\n\t\"curren\":                           '\\U000000A4',\n\t\"deg\":                              '\\U000000B0',\n\t\"divide\":                           '\\U000000F7',\n\t\"eacute\":                           '\\U000000E9',\n\t\"ecirc\":                            '\\U000000EA',\n\t\"egrave\":                           '\\U000000E8',\n\t\"eth\":                              '\\U000000F0',\n\t\"euml\":                             '\\U000000EB',\n\t\"frac12\":                           '\\U000000BD',\n\t\"frac14\":                           '\\U000000BC',\n\t\"frac34\":                           '\\U000000BE',\n\t\"gt\":                               '\\U0000003E',\n\t\"iacute\":                           '\\U000000ED',\n\t\"icirc\":                            '\\U000000EE',\n\t\"iexcl\":                            '\\U000000A1',\n\t\"igrave\":                           '\\U000000EC',\n\t\"iquest\":                           '\\U000000BF',\n\t\"iuml\":                             '\\U000000EF',\n\t\"laquo\":                            '\\U000000AB',\n\t\"lt\":                               '\\U0000003C',\n\t\"macr\":                             '\\U000000AF',\n\t\"micro\":                            '\\U000000B5',\n\t\"middot\":                           '\\U000000B7',\n\t\"nbsp\":                             '\\U000000A0',\n\t\"not\":                              '\\U000000AC',\n\t\"ntilde\":                           '\\U000000F1',\n\t\"oacute\":                           '\\U000000F3',\n\t\"ocirc\":                            '\\U000000F4',\n\t\"ograve\":                           '\\U000000F2',\n\t\"ordf\":                             '\\U000000AA',\n\t\"ordm\":                             '\\U000000BA',\n\t\"oslash\":                           '\\U000000F8',\n\t\"otilde\":                           '\\U000000F5',\n\t\"ouml\":                             '\\U000000F6',\n\t\"para\":                             '\\U000000B6',\n\t\"plusmn\":                           '\\U000000B1',\n\t\"pound\":                            '\\U000000A3',\n\t\"quot\":                             '\\U00000022',\n\t\"raquo\":                            '\\U000000BB',\n\t\"reg\":                              '\\U000000AE',\n\t\"sect\":                             '\\U000000A7',\n\t\"shy\":                              '\\U000000AD',\n\t\"sup1\":                             '\\U000000B9',\n\t\"sup2\":                             '\\U000000B2',\n\t\"sup3\":                             '\\U000000B3',\n\t\"szlig\":                            '\\U000000DF',\n\t\"thorn\":                            '\\U000000FE',\n\t\"times\":                            '\\U000000D7',\n\t\"uacute\":                           '\\U000000FA',\n\t\"ucirc\":                            '\\U000000FB',\n\t\"ugrave\":                           '\\U000000F9',\n\t\"uml\":                              '\\U000000A8',\n\t\"uuml\":                             '\\U000000FC',\n\t\"yacute\":                           '\\U000000FD',\n\t\"yen\":                              '\\U000000A5',\n\t\"yuml\":                             '\\U000000FF',\n}\n\n// HTML entities that are two unicode codepoints.\nvar entity2 = map[string][2]rune{\n\t// TODO(nigeltao): Handle replacements that are wider than their names.\n\t// \"nLt;\":                     {'\\u226A', '\\u20D2'},\n\t// \"nGt;\":                     {'\\u226B', '\\u20D2'},\n\t\"NotEqualTilde;\":           {'\\u2242', '\\u0338'},\n\t\"NotGreaterFullEqual;\":     {'\\u2267', '\\u0338'},\n\t\"NotGreaterGreater;\":       {'\\u226B', '\\u0338'},\n\t\"NotGreaterSlantEqual;\":    {'\\u2A7E', '\\u0338'},\n\t\"NotHumpDownHump;\":         {'\\u224E', '\\u0338'},\n\t\"NotHumpEqual;\":            {'\\u224F', '\\u0338'},\n\t\"NotLeftTriangleBar;\":      {'\\u29CF', '\\u0338'},\n\t\"NotLessLess;\":             {'\\u226A', '\\u0338'},\n\t\"NotLessSlantEqual;\":       {'\\u2A7D', '\\u0338'},\n\t\"NotNestedGreaterGreater;\": {'\\u2AA2', '\\u0338'},\n\t\"NotNestedLessLess;\":       {'\\u2AA1', '\\u0338'},\n\t\"NotPrecedesEqual;\":        {'\\u2AAF', '\\u0338'},\n\t\"NotRightTriangleBar;\":     {'\\u29D0', '\\u0338'},\n\t\"NotSquareSubset;\":         {'\\u228F', '\\u0338'},\n\t\"NotSquareSuperset;\":       {'\\u2290', '\\u0338'},\n\t\"NotSubset;\":               {'\\u2282', '\\u20D2'},\n\t\"NotSucceedsEqual;\":        {'\\u2AB0', '\\u0338'},\n\t\"NotSucceedsTilde;\":        {'\\u227F', '\\u0338'},\n\t\"NotSuperset;\":             {'\\u2283', '\\u20D2'},\n\t\"ThickSpace;\":              {'\\u205F', '\\u200A'},\n\t\"acE;\":                     {'\\u223E', '\\u0333'},\n\t\"bne;\":                     {'\\u003D', '\\u20E5'},\n\t\"bnequiv;\":                 {'\\u2261', '\\u20E5'},\n\t\"caps;\":                    {'\\u2229', '\\uFE00'},\n\t\"cups;\":                    {'\\u222A', '\\uFE00'},\n\t\"fjlig;\":                   {'\\u0066', '\\u006A'},\n\t\"gesl;\":                    {'\\u22DB', '\\uFE00'},\n\t\"gvertneqq;\":               {'\\u2269', '\\uFE00'},\n\t\"gvnE;\":                    {'\\u2269', '\\uFE00'},\n\t\"lates;\":                   {'\\u2AAD', '\\uFE00'},\n\t\"lesg;\":                    {'\\u22DA', '\\uFE00'},\n\t\"lvertneqq;\":               {'\\u2268', '\\uFE00'},\n\t\"lvnE;\":                    {'\\u2268', '\\uFE00'},\n\t\"nGg;\":                     {'\\u22D9', '\\u0338'},\n\t\"nGtv;\":                    {'\\u226B', '\\u0338'},\n\t\"nLl;\":                     {'\\u22D8', '\\u0338'},\n\t\"nLtv;\":                    {'\\u226A', '\\u0338'},\n\t\"nang;\":                    {'\\u2220', '\\u20D2'},\n\t\"napE;\":                    {'\\u2A70', '\\u0338'},\n\t\"napid;\":                   {'\\u224B', '\\u0338'},\n\t\"nbump;\":                   {'\\u224E', '\\u0338'},\n\t\"nbumpe;\":                  {'\\u224F', '\\u0338'},\n\t\"ncongdot;\":                {'\\u2A6D', '\\u0338'},\n\t\"nedot;\":                   {'\\u2250', '\\u0338'},\n\t\"nesim;\":                   {'\\u2242', '\\u0338'},\n\t\"ngE;\":                     {'\\u2267', '\\u0338'},\n\t\"ngeqq;\":                   {'\\u2267', '\\u0338'},\n\t\"ngeqslant;\":               {'\\u2A7E', '\\u0338'},\n\t\"nges;\":                    {'\\u2A7E', '\\u0338'},\n\t\"nlE;\":                     {'\\u2266', '\\u0338'},\n\t\"nleqq;\":                   {'\\u2266', '\\u0338'},\n\t\"nleqslant;\":               {'\\u2A7D', '\\u0338'},\n\t\"nles;\":                    {'\\u2A7D', '\\u0338'},\n\t\"notinE;\":                  {'\\u22F9', '\\u0338'},\n\t\"notindot;\":                {'\\u22F5', '\\u0338'},\n\t\"nparsl;\":                  {'\\u2AFD', '\\u20E5'},\n\t\"npart;\":                   {'\\u2202', '\\u0338'},\n\t\"npre;\":                    {'\\u2AAF', '\\u0338'},\n\t\"npreceq;\":                 {'\\u2AAF', '\\u0338'},\n\t\"nrarrc;\":                  {'\\u2933', '\\u0338'},\n\t\"nrarrw;\":                  {'\\u219D', '\\u0338'},\n\t\"nsce;\":                    {'\\u2AB0', '\\u0338'},\n\t\"nsubE;\":                   {'\\u2AC5', '\\u0338'},\n\t\"nsubset;\":                 {'\\u2282', '\\u20D2'},\n\t\"nsubseteqq;\":              {'\\u2AC5', '\\u0338'},\n\t\"nsucceq;\":                 {'\\u2AB0', '\\u0338'},\n\t\"nsupE;\":                   {'\\u2AC6', '\\u0338'},\n\t\"nsupset;\":                 {'\\u2283', '\\u20D2'},\n\t\"nsupseteqq;\":              {'\\u2AC6', '\\u0338'},\n\t\"nvap;\":                    {'\\u224D', '\\u20D2'},\n\t\"nvge;\":                    {'\\u2265', '\\u20D2'},\n\t\"nvgt;\":                    {'\\u003E', '\\u20D2'},\n\t\"nvle;\":                    {'\\u2264', '\\u20D2'},\n\t\"nvlt;\":                    {'\\u003C', '\\u20D2'},\n\t\"nvltrie;\":                 {'\\u22B4', '\\u20D2'},\n\t\"nvrtrie;\":                 {'\\u22B5', '\\u20D2'},\n\t\"nvsim;\":                   {'\\u223C', '\\u20D2'},\n\t\"race;\":                    {'\\u223D', '\\u0331'},\n\t\"smtes;\":                   {'\\u2AAC', '\\uFE00'},\n\t\"sqcaps;\":                  {'\\u2293', '\\uFE00'},\n\t\"sqcups;\":                  {'\\u2294', '\\uFE00'},\n\t\"varsubsetneq;\":            {'\\u228A', '\\uFE00'},\n\t\"varsubsetneqq;\":           {'\\u2ACB', '\\uFE00'},\n\t\"varsupsetneq;\":            {'\\u228B', '\\uFE00'},\n\t\"varsupsetneqq;\":           {'\\u2ACC', '\\uFE00'},\n\t\"vnsub;\":                   {'\\u2282', '\\u20D2'},\n\t\"vnsup;\":                   {'\\u2283', '\\u20D2'},\n\t\"vsubnE;\":                  {'\\u2ACB', '\\uFE00'},\n\t\"vsubne;\":                  {'\\u228A', '\\uFE00'},\n\t\"vsupnE;\":                  {'\\u2ACC', '\\uFE00'},\n\t\"vsupne;\":                  {'\\u228B', '\\uFE00'},\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/escape.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 html\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\n// These replacements permit compatibility with old numeric entities that\n// assumed Windows-1252 encoding.\n// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference\nvar replacementTable = [...]rune{\n\t'\\u20AC', // First entry is what 0x80 should be replaced with.\n\t'\\u0081',\n\t'\\u201A',\n\t'\\u0192',\n\t'\\u201E',\n\t'\\u2026',\n\t'\\u2020',\n\t'\\u2021',\n\t'\\u02C6',\n\t'\\u2030',\n\t'\\u0160',\n\t'\\u2039',\n\t'\\u0152',\n\t'\\u008D',\n\t'\\u017D',\n\t'\\u008F',\n\t'\\u0090',\n\t'\\u2018',\n\t'\\u2019',\n\t'\\u201C',\n\t'\\u201D',\n\t'\\u2022',\n\t'\\u2013',\n\t'\\u2014',\n\t'\\u02DC',\n\t'\\u2122',\n\t'\\u0161',\n\t'\\u203A',\n\t'\\u0153',\n\t'\\u009D',\n\t'\\u017E',\n\t'\\u0178', // Last entry is 0x9F.\n\t// 0x00->'\\uFFFD' is handled programmatically.\n\t// 0x0D->'\\u000D' is a no-op.\n}\n\n// unescapeEntity reads an entity like \"&lt;\" from b[src:] and writes the\n// corresponding \"<\" to b[dst:], returning the incremented dst and src cursors.\n// Precondition: b[src] == '&' && dst <= src.\n// attribute should be true if parsing an attribute value.\nfunc unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {\n\t// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference\n\n\t// i starts at 1 because we already know that s[0] == '&'.\n\ti, s := 1, b[src:]\n\n\tif len(s) <= 1 {\n\t\tb[dst] = b[src]\n\t\treturn dst + 1, src + 1\n\t}\n\n\tif s[i] == '#' {\n\t\tif len(s) <= 3 { // We need to have at least \"&#.\".\n\t\t\tb[dst] = b[src]\n\t\t\treturn dst + 1, src + 1\n\t\t}\n\t\ti++\n\t\tc := s[i]\n\t\thex := false\n\t\tif c == 'x' || c == 'X' {\n\t\t\thex = true\n\t\t\ti++\n\t\t}\n\n\t\tx := '\\x00'\n\t\tfor i < len(s) {\n\t\t\tc = s[i]\n\t\t\ti++\n\t\t\tif hex {\n\t\t\t\tif '0' <= c && c <= '9' {\n\t\t\t\t\tx = 16*x + rune(c) - '0'\n\t\t\t\t\tcontinue\n\t\t\t\t} else if 'a' <= c && c <= 'f' {\n\t\t\t\t\tx = 16*x + rune(c) - 'a' + 10\n\t\t\t\t\tcontinue\n\t\t\t\t} else if 'A' <= c && c <= 'F' {\n\t\t\t\t\tx = 16*x + rune(c) - 'A' + 10\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t} else if '0' <= c && c <= '9' {\n\t\t\t\tx = 10*x + rune(c) - '0'\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c != ';' {\n\t\t\t\ti--\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tif i <= 3 { // No characters matched.\n\t\t\tb[dst] = b[src]\n\t\t\treturn dst + 1, src + 1\n\t\t}\n\n\t\tif 0x80 <= x && x <= 0x9F {\n\t\t\t// Replace characters from Windows-1252 with UTF-8 equivalents.\n\t\t\tx = replacementTable[x-0x80]\n\t\t} else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF {\n\t\t\t// Replace invalid characters with the replacement character.\n\t\t\tx = '\\uFFFD'\n\t\t}\n\n\t\treturn dst + utf8.EncodeRune(b[dst:], x), src + i\n\t}\n\n\t// Consume the maximum number of characters possible, with the\n\t// consumed characters matching one of the named references.\n\n\tfor i < len(s) {\n\t\tc := s[i]\n\t\ti++\n\t\t// Lower-cased characters are more common in entities, so we check for them first.\n\t\tif 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {\n\t\t\tcontinue\n\t\t}\n\t\tif c != ';' {\n\t\t\ti--\n\t\t}\n\t\tbreak\n\t}\n\n\tentityName := string(s[1:i])\n\tif entityName == \"\" {\n\t\t// No-op.\n\t} else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {\n\t\t// No-op.\n\t} else if x := entity[entityName]; x != 0 {\n\t\treturn dst + utf8.EncodeRune(b[dst:], x), src + i\n\t} else if x := entity2[entityName]; x[0] != 0 {\n\t\tdst1 := dst + utf8.EncodeRune(b[dst:], x[0])\n\t\treturn dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i\n\t} else if !attribute {\n\t\tmaxLen := len(entityName) - 1\n\t\tif maxLen > longestEntityWithoutSemicolon {\n\t\t\tmaxLen = longestEntityWithoutSemicolon\n\t\t}\n\t\tfor j := maxLen; j > 1; j-- {\n\t\t\tif x := entity[entityName[:j]]; x != 0 {\n\t\t\t\treturn dst + utf8.EncodeRune(b[dst:], x), src + j + 1\n\t\t\t}\n\t\t}\n\t}\n\n\tdst1, src1 = dst+i, src+i\n\tcopy(b[dst:dst1], b[src:src1])\n\treturn dst1, src1\n}\n\n// unescape unescapes b's entities in-place, so that \"a&lt;b\" becomes \"a<b\".\n// attribute should be true if parsing an attribute value.\nfunc unescape(b []byte, attribute bool) []byte {\n\tfor i, c := range b {\n\t\tif c == '&' {\n\t\t\tdst, src := unescapeEntity(b, i, i, attribute)\n\t\t\tfor src < len(b) {\n\t\t\t\tc := b[src]\n\t\t\t\tif c == '&' {\n\t\t\t\t\tdst, src = unescapeEntity(b, dst, src, attribute)\n\t\t\t\t} else {\n\t\t\t\t\tb[dst] = c\n\t\t\t\t\tdst, src = dst+1, src+1\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn b[0:dst]\n\t\t}\n\t}\n\treturn b\n}\n\n// lower lower-cases the A-Z bytes in b in-place, so that \"aBc\" becomes \"abc\".\nfunc lower(b []byte) []byte {\n\tfor i, c := range b {\n\t\tif 'A' <= c && c <= 'Z' {\n\t\t\tb[i] = c + 'a' - 'A'\n\t\t}\n\t}\n\treturn b\n}\n\n// escapeComment is like func escape but escapes its input bytes less often.\n// Per https://github.com/golang/go/issues/58246 some HTML comments are (1)\n// meaningful and (2) contain angle brackets that we'd like to avoid escaping\n// unless we have to.\n//\n// \"We have to\" includes the '&' byte, since that introduces other escapes.\n//\n// It also includes those bytes (not including EOF) that would otherwise end\n// the comment. Per the summary table at the bottom of comment_test.go, this is\n// the '>' byte that, per above, we'd like to avoid escaping unless we have to.\n//\n// Studying the summary table (and T actions in its '>' column) closely, we\n// only need to escape in states 43, 44, 49, 51 and 52. State 43 is at the\n// start of the comment data. State 52 is after a '!'. The other three states\n// are after a '-'.\n//\n// Our algorithm is thus to escape every '&' and to escape '>' if and only if:\n//   - The '>' is after a '!' or '-' (in the unescaped data) or\n//   - The '>' is at the start of the comment data (after the opening \"<!--\").\nfunc escapeComment(w writer, s string) error {\n\t// When modifying this function, consider manually increasing the\n\t// maxSuffixLen constant in func TestComments, from 6 to e.g. 9 or more.\n\t// That increase should only be temporary, not committed, as it\n\t// exponentially affects the test running time.\n\n\tif len(s) == 0 {\n\t\treturn nil\n\t}\n\n\t// Loop:\n\t//   - Grow j such that s[i:j] does not need escaping.\n\t//   - If s[j] does need escaping, output s[i:j] and an escaped s[j],\n\t//     resetting i and j to point past that s[j] byte.\n\ti := 0\n\tfor j := 0; j < len(s); j++ {\n\t\tescaped := \"\"\n\t\tswitch s[j] {\n\t\tcase '&':\n\t\t\tescaped = \"&amp;\"\n\n\t\tcase '>':\n\t\t\tif j > 0 {\n\t\t\t\tif prev := s[j-1]; (prev != '!') && (prev != '-') {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tescaped = \"&gt;\"\n\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\n\t\tif i < j {\n\t\t\tif _, err := w.WriteString(s[i:j]); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif _, err := w.WriteString(escaped); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ti = j + 1\n\t}\n\n\tif i < len(s) {\n\t\tif _, err := w.WriteString(s[i:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// escapeCommentString is to EscapeString as escapeComment is to escape.\nfunc escapeCommentString(s string) string {\n\tif strings.IndexAny(s, \"&>\") == -1 {\n\t\treturn s\n\t}\n\tvar buf bytes.Buffer\n\tescapeComment(&buf, s)\n\treturn buf.String()\n}\n\nconst escapedChars = \"&'<>\\\"\\r\"\n\nfunc escape(w writer, s string) error {\n\ti := strings.IndexAny(s, escapedChars)\n\tfor i != -1 {\n\t\tif _, err := w.WriteString(s[:i]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tvar esc string\n\t\tswitch s[i] {\n\t\tcase '&':\n\t\t\tesc = \"&amp;\"\n\t\tcase '\\'':\n\t\t\t// \"&#39;\" is shorter than \"&apos;\" and apos was not in HTML until HTML5.\n\t\t\tesc = \"&#39;\"\n\t\tcase '<':\n\t\t\tesc = \"&lt;\"\n\t\tcase '>':\n\t\t\tesc = \"&gt;\"\n\t\tcase '\"':\n\t\t\t// \"&#34;\" is shorter than \"&quot;\".\n\t\t\tesc = \"&#34;\"\n\t\tcase '\\r':\n\t\t\tesc = \"&#13;\"\n\t\tdefault:\n\t\t\tpanic(\"html: unrecognized escape character\")\n\t\t}\n\t\ts = s[i+1:]\n\t\tif _, err := w.WriteString(esc); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ti = strings.IndexAny(s, escapedChars)\n\t}\n\t_, err := w.WriteString(s)\n\treturn err\n}\n\n// EscapeString escapes special characters like \"<\" to become \"&lt;\". It\n// escapes only five such characters: <, >, &, ' and \".\n// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't\n// always true.\nfunc EscapeString(s string) string {\n\tif strings.IndexAny(s, escapedChars) == -1 {\n\t\treturn s\n\t}\n\tvar buf bytes.Buffer\n\tescape(&buf, s)\n\treturn buf.String()\n}\n\n// UnescapeString unescapes entities like \"&lt;\" to become \"<\". It unescapes a\n// larger range of entities than EscapeString escapes. For example, \"&aacute;\"\n// unescapes to \"á\", as does \"&#225;\" and \"&xE1;\".\n// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't\n// always true.\nfunc UnescapeString(s string) string {\n\tfor _, c := range s {\n\t\tif c == '&' {\n\t\t\treturn string(unescape([]byte(s), false))\n\t\t}\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/foreign.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 html\n\nimport (\n\t\"strings\"\n)\n\nfunc adjustAttributeNames(aa []Attribute, nameMap map[string]string) {\n\tfor i := range aa {\n\t\tif newName, ok := nameMap[aa[i].Key]; ok {\n\t\t\taa[i].Key = newName\n\t\t}\n\t}\n}\n\nfunc adjustForeignAttributes(aa []Attribute) {\n\tfor i, a := range aa {\n\t\tif a.Key == \"\" || a.Key[0] != 'x' {\n\t\t\tcontinue\n\t\t}\n\t\tswitch a.Key {\n\t\tcase \"xlink:actuate\", \"xlink:arcrole\", \"xlink:href\", \"xlink:role\", \"xlink:show\",\n\t\t\t\"xlink:title\", \"xlink:type\", \"xml:base\", \"xml:lang\", \"xml:space\", \"xmlns:xlink\":\n\t\t\tj := strings.Index(a.Key, \":\")\n\t\t\taa[i].Namespace = a.Key[:j]\n\t\t\taa[i].Key = a.Key[j+1:]\n\t\t}\n\t}\n}\n\nfunc htmlIntegrationPoint(n *Node) bool {\n\tif n.Type != ElementNode {\n\t\treturn false\n\t}\n\tswitch n.Namespace {\n\tcase \"math\":\n\t\tif n.Data == \"annotation-xml\" {\n\t\t\tfor _, a := range n.Attr {\n\t\t\t\tif a.Key == \"encoding\" {\n\t\t\t\t\tif strings.EqualFold(a.Val, \"text/html\") || strings.EqualFold(a.Val, \"application/xhtml+xml\") {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tcase \"svg\":\n\t\tswitch n.Data {\n\t\tcase \"desc\", \"foreignObject\", \"title\":\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc mathMLTextIntegrationPoint(n *Node) bool {\n\tif n.Namespace != \"math\" {\n\t\treturn false\n\t}\n\tswitch n.Data {\n\tcase \"mi\", \"mo\", \"mn\", \"ms\", \"mtext\":\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Section 12.2.6.5.\nvar breakout = map[string]bool{\n\t\"b\":          true,\n\t\"big\":        true,\n\t\"blockquote\": true,\n\t\"body\":       true,\n\t\"br\":         true,\n\t\"center\":     true,\n\t\"code\":       true,\n\t\"dd\":         true,\n\t\"div\":        true,\n\t\"dl\":         true,\n\t\"dt\":         true,\n\t\"em\":         true,\n\t\"embed\":      true,\n\t\"h1\":         true,\n\t\"h2\":         true,\n\t\"h3\":         true,\n\t\"h4\":         true,\n\t\"h5\":         true,\n\t\"h6\":         true,\n\t\"head\":       true,\n\t\"hr\":         true,\n\t\"i\":          true,\n\t\"img\":        true,\n\t\"li\":         true,\n\t\"listing\":    true,\n\t\"menu\":       true,\n\t\"meta\":       true,\n\t\"nobr\":       true,\n\t\"ol\":         true,\n\t\"p\":          true,\n\t\"pre\":        true,\n\t\"ruby\":       true,\n\t\"s\":          true,\n\t\"small\":      true,\n\t\"span\":       true,\n\t\"strong\":     true,\n\t\"strike\":     true,\n\t\"sub\":        true,\n\t\"sup\":        true,\n\t\"table\":      true,\n\t\"tt\":         true,\n\t\"u\":          true,\n\t\"ul\":         true,\n\t\"var\":        true,\n}\n\n// Section 12.2.6.5.\nvar svgTagNameAdjustments = map[string]string{\n\t\"altglyph\":            \"altGlyph\",\n\t\"altglyphdef\":         \"altGlyphDef\",\n\t\"altglyphitem\":        \"altGlyphItem\",\n\t\"animatecolor\":        \"animateColor\",\n\t\"animatemotion\":       \"animateMotion\",\n\t\"animatetransform\":    \"animateTransform\",\n\t\"clippath\":            \"clipPath\",\n\t\"feblend\":             \"feBlend\",\n\t\"fecolormatrix\":       \"feColorMatrix\",\n\t\"fecomponenttransfer\": \"feComponentTransfer\",\n\t\"fecomposite\":         \"feComposite\",\n\t\"feconvolvematrix\":    \"feConvolveMatrix\",\n\t\"fediffuselighting\":   \"feDiffuseLighting\",\n\t\"fedisplacementmap\":   \"feDisplacementMap\",\n\t\"fedistantlight\":      \"feDistantLight\",\n\t\"feflood\":             \"feFlood\",\n\t\"fefunca\":             \"feFuncA\",\n\t\"fefuncb\":             \"feFuncB\",\n\t\"fefuncg\":             \"feFuncG\",\n\t\"fefuncr\":             \"feFuncR\",\n\t\"fegaussianblur\":      \"feGaussianBlur\",\n\t\"feimage\":             \"feImage\",\n\t\"femerge\":             \"feMerge\",\n\t\"femergenode\":         \"feMergeNode\",\n\t\"femorphology\":        \"feMorphology\",\n\t\"feoffset\":            \"feOffset\",\n\t\"fepointlight\":        \"fePointLight\",\n\t\"fespecularlighting\":  \"feSpecularLighting\",\n\t\"fespotlight\":         \"feSpotLight\",\n\t\"fetile\":              \"feTile\",\n\t\"feturbulence\":        \"feTurbulence\",\n\t\"foreignobject\":       \"foreignObject\",\n\t\"glyphref\":            \"glyphRef\",\n\t\"lineargradient\":      \"linearGradient\",\n\t\"radialgradient\":      \"radialGradient\",\n\t\"textpath\":            \"textPath\",\n}\n\n// Section 12.2.6.1\nvar mathMLAttributeAdjustments = map[string]string{\n\t\"definitionurl\": \"definitionURL\",\n}\n\nvar svgAttributeAdjustments = map[string]string{\n\t\"attributename\":       \"attributeName\",\n\t\"attributetype\":       \"attributeType\",\n\t\"basefrequency\":       \"baseFrequency\",\n\t\"baseprofile\":         \"baseProfile\",\n\t\"calcmode\":            \"calcMode\",\n\t\"clippathunits\":       \"clipPathUnits\",\n\t\"diffuseconstant\":     \"diffuseConstant\",\n\t\"edgemode\":            \"edgeMode\",\n\t\"filterunits\":         \"filterUnits\",\n\t\"glyphref\":            \"glyphRef\",\n\t\"gradienttransform\":   \"gradientTransform\",\n\t\"gradientunits\":       \"gradientUnits\",\n\t\"kernelmatrix\":        \"kernelMatrix\",\n\t\"kernelunitlength\":    \"kernelUnitLength\",\n\t\"keypoints\":           \"keyPoints\",\n\t\"keysplines\":          \"keySplines\",\n\t\"keytimes\":            \"keyTimes\",\n\t\"lengthadjust\":        \"lengthAdjust\",\n\t\"limitingconeangle\":   \"limitingConeAngle\",\n\t\"markerheight\":        \"markerHeight\",\n\t\"markerunits\":         \"markerUnits\",\n\t\"markerwidth\":         \"markerWidth\",\n\t\"maskcontentunits\":    \"maskContentUnits\",\n\t\"maskunits\":           \"maskUnits\",\n\t\"numoctaves\":          \"numOctaves\",\n\t\"pathlength\":          \"pathLength\",\n\t\"patterncontentunits\": \"patternContentUnits\",\n\t\"patterntransform\":    \"patternTransform\",\n\t\"patternunits\":        \"patternUnits\",\n\t\"pointsatx\":           \"pointsAtX\",\n\t\"pointsaty\":           \"pointsAtY\",\n\t\"pointsatz\":           \"pointsAtZ\",\n\t\"preservealpha\":       \"preserveAlpha\",\n\t\"preserveaspectratio\": \"preserveAspectRatio\",\n\t\"primitiveunits\":      \"primitiveUnits\",\n\t\"refx\":                \"refX\",\n\t\"refy\":                \"refY\",\n\t\"repeatcount\":         \"repeatCount\",\n\t\"repeatdur\":           \"repeatDur\",\n\t\"requiredextensions\":  \"requiredExtensions\",\n\t\"requiredfeatures\":    \"requiredFeatures\",\n\t\"specularconstant\":    \"specularConstant\",\n\t\"specularexponent\":    \"specularExponent\",\n\t\"spreadmethod\":        \"spreadMethod\",\n\t\"startoffset\":         \"startOffset\",\n\t\"stddeviation\":        \"stdDeviation\",\n\t\"stitchtiles\":         \"stitchTiles\",\n\t\"surfacescale\":        \"surfaceScale\",\n\t\"systemlanguage\":      \"systemLanguage\",\n\t\"tablevalues\":         \"tableValues\",\n\t\"targetx\":             \"targetX\",\n\t\"targety\":             \"targetY\",\n\t\"textlength\":          \"textLength\",\n\t\"viewbox\":             \"viewBox\",\n\t\"viewtarget\":          \"viewTarget\",\n\t\"xchannelselector\":    \"xChannelSelector\",\n\t\"ychannelselector\":    \"yChannelSelector\",\n\t\"zoomandpan\":          \"zoomAndPan\",\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/iter.go",
    "content": "// Copyright 2024 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 go1.23\n\npackage html\n\nimport \"iter\"\n\n// Ancestors returns an iterator over the ancestors of n, starting with n.Parent.\n//\n// Mutating a Node or its parents while iterating may have unexpected results.\nfunc (n *Node) Ancestors() iter.Seq[*Node] {\n\t_ = n.Parent // eager nil check\n\n\treturn func(yield func(*Node) bool) {\n\t\tfor p := n.Parent; p != nil && yield(p); p = p.Parent {\n\t\t}\n\t}\n}\n\n// ChildNodes returns an iterator over the immediate children of n,\n// starting with n.FirstChild.\n//\n// Mutating a Node or its children while iterating may have unexpected results.\nfunc (n *Node) ChildNodes() iter.Seq[*Node] {\n\t_ = n.FirstChild // eager nil check\n\n\treturn func(yield func(*Node) bool) {\n\t\tfor c := n.FirstChild; c != nil && yield(c); c = c.NextSibling {\n\t\t}\n\t}\n\n}\n\n// Descendants returns an iterator over all nodes recursively beneath\n// n, excluding n itself. Nodes are visited in depth-first preorder.\n//\n// Mutating a Node or its descendants while iterating may have unexpected results.\nfunc (n *Node) Descendants() iter.Seq[*Node] {\n\t_ = n.FirstChild // eager nil check\n\n\treturn func(yield func(*Node) bool) {\n\t\tn.descendants(yield)\n\t}\n}\n\nfunc (n *Node) descendants(yield func(*Node) bool) bool {\n\tfor c := range n.ChildNodes() {\n\t\tif !yield(c) || !c.descendants(yield) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/node.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 html\n\nimport (\n\t\"golang.org/x/net/html/atom\"\n)\n\n// A NodeType is the type of a Node.\ntype NodeType uint32\n\nconst (\n\tErrorNode NodeType = iota\n\tTextNode\n\tDocumentNode\n\tElementNode\n\tCommentNode\n\tDoctypeNode\n\t// RawNode nodes are not returned by the parser, but can be part of the\n\t// Node tree passed to func Render to insert raw HTML (without escaping).\n\t// If so, this package makes no guarantee that the rendered HTML is secure\n\t// (from e.g. Cross Site Scripting attacks) or well-formed.\n\tRawNode\n\tscopeMarkerNode\n)\n\n// Section 12.2.4.3 says \"The markers are inserted when entering applet,\n// object, marquee, template, td, th, and caption elements, and are used\n// to prevent formatting from \"leaking\" into applet, object, marquee,\n// template, td, th, and caption elements\".\nvar scopeMarker = Node{Type: scopeMarkerNode}\n\n// A Node consists of a NodeType and some Data (tag name for element nodes,\n// content for text) and are part of a tree of Nodes. Element nodes may also\n// have a Namespace and contain a slice of Attributes. Data is unescaped, so\n// that it looks like \"a<b\" rather than \"a&lt;b\". For element nodes, DataAtom\n// is the atom for Data, or zero if Data is not a known tag name.\n//\n// Node trees may be navigated using the link fields (Parent,\n// FirstChild, and so on) or a range loop over iterators such as\n// [Node.Descendants].\n//\n// An empty Namespace implies a \"http://www.w3.org/1999/xhtml\" namespace.\n// Similarly, \"math\" is short for \"http://www.w3.org/1998/Math/MathML\", and\n// \"svg\" is short for \"http://www.w3.org/2000/svg\".\ntype Node struct {\n\tParent, FirstChild, LastChild, PrevSibling, NextSibling *Node\n\n\tType      NodeType\n\tDataAtom  atom.Atom\n\tData      string\n\tNamespace string\n\tAttr      []Attribute\n}\n\n// InsertBefore inserts newChild as a child of n, immediately before oldChild\n// in the sequence of n's children. oldChild may be nil, in which case newChild\n// is appended to the end of n's children.\n//\n// It will panic if newChild already has a parent or siblings.\nfunc (n *Node) InsertBefore(newChild, oldChild *Node) {\n\tif newChild.Parent != nil || newChild.PrevSibling != nil || newChild.NextSibling != nil {\n\t\tpanic(\"html: InsertBefore called for an attached child Node\")\n\t}\n\tvar prev, next *Node\n\tif oldChild != nil {\n\t\tprev, next = oldChild.PrevSibling, oldChild\n\t} else {\n\t\tprev = n.LastChild\n\t}\n\tif prev != nil {\n\t\tprev.NextSibling = newChild\n\t} else {\n\t\tn.FirstChild = newChild\n\t}\n\tif next != nil {\n\t\tnext.PrevSibling = newChild\n\t} else {\n\t\tn.LastChild = newChild\n\t}\n\tnewChild.Parent = n\n\tnewChild.PrevSibling = prev\n\tnewChild.NextSibling = next\n}\n\n// AppendChild adds a node c as a child of n.\n//\n// It will panic if c already has a parent or siblings.\nfunc (n *Node) AppendChild(c *Node) {\n\tif c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil {\n\t\tpanic(\"html: AppendChild called for an attached child Node\")\n\t}\n\tlast := n.LastChild\n\tif last != nil {\n\t\tlast.NextSibling = c\n\t} else {\n\t\tn.FirstChild = c\n\t}\n\tn.LastChild = c\n\tc.Parent = n\n\tc.PrevSibling = last\n}\n\n// RemoveChild removes a node c that is a child of n. Afterwards, c will have\n// no parent and no siblings.\n//\n// It will panic if c's parent is not n.\nfunc (n *Node) RemoveChild(c *Node) {\n\tif c.Parent != n {\n\t\tpanic(\"html: RemoveChild called for a non-child Node\")\n\t}\n\tif n.FirstChild == c {\n\t\tn.FirstChild = c.NextSibling\n\t}\n\tif c.NextSibling != nil {\n\t\tc.NextSibling.PrevSibling = c.PrevSibling\n\t}\n\tif n.LastChild == c {\n\t\tn.LastChild = c.PrevSibling\n\t}\n\tif c.PrevSibling != nil {\n\t\tc.PrevSibling.NextSibling = c.NextSibling\n\t}\n\tc.Parent = nil\n\tc.PrevSibling = nil\n\tc.NextSibling = nil\n}\n\n// reparentChildren reparents all of src's child nodes to dst.\nfunc reparentChildren(dst, src *Node) {\n\tfor {\n\t\tchild := src.FirstChild\n\t\tif child == nil {\n\t\t\tbreak\n\t\t}\n\t\tsrc.RemoveChild(child)\n\t\tdst.AppendChild(child)\n\t}\n}\n\n// clone returns a new node with the same type, data and attributes.\n// The clone has no parent, no siblings and no children.\nfunc (n *Node) clone() *Node {\n\tm := &Node{\n\t\tType:     n.Type,\n\t\tDataAtom: n.DataAtom,\n\t\tData:     n.Data,\n\t\tAttr:     make([]Attribute, len(n.Attr)),\n\t}\n\tcopy(m.Attr, n.Attr)\n\treturn m\n}\n\n// nodeStack is a stack of nodes.\ntype nodeStack []*Node\n\n// pop pops the stack. It will panic if s is empty.\nfunc (s *nodeStack) pop() *Node {\n\ti := len(*s)\n\tn := (*s)[i-1]\n\t*s = (*s)[:i-1]\n\treturn n\n}\n\n// top returns the most recently pushed node, or nil if s is empty.\nfunc (s *nodeStack) top() *Node {\n\tif i := len(*s); i > 0 {\n\t\treturn (*s)[i-1]\n\t}\n\treturn nil\n}\n\n// index returns the index of the top-most occurrence of n in the stack, or -1\n// if n is not present.\nfunc (s *nodeStack) index(n *Node) int {\n\tfor i := len(*s) - 1; i >= 0; i-- {\n\t\tif (*s)[i] == n {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\n// contains returns whether a is within s.\nfunc (s *nodeStack) contains(a atom.Atom) bool {\n\tfor _, n := range *s {\n\t\tif n.DataAtom == a && n.Namespace == \"\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// insert inserts a node at the given index.\nfunc (s *nodeStack) insert(i int, n *Node) {\n\t(*s) = append(*s, nil)\n\tcopy((*s)[i+1:], (*s)[i:])\n\t(*s)[i] = n\n}\n\n// remove removes a node from the stack. It is a no-op if n is not present.\nfunc (s *nodeStack) remove(n *Node) {\n\ti := s.index(n)\n\tif i == -1 {\n\t\treturn\n\t}\n\tcopy((*s)[i:], (*s)[i+1:])\n\tj := len(*s) - 1\n\t(*s)[j] = nil\n\t*s = (*s)[:j]\n}\n\ntype insertionModeStack []insertionMode\n\nfunc (s *insertionModeStack) pop() (im insertionMode) {\n\ti := len(*s)\n\tim = (*s)[i-1]\n\t*s = (*s)[:i-1]\n\treturn im\n}\n\nfunc (s *insertionModeStack) top() insertionMode {\n\tif i := len(*s); i > 0 {\n\t\treturn (*s)[i-1]\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/parse.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 html\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\ta \"golang.org/x/net/html/atom\"\n)\n\n// A parser implements the HTML5 parsing algorithm:\n// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction\ntype parser struct {\n\t// tokenizer provides the tokens for the parser.\n\ttokenizer *Tokenizer\n\t// tok is the most recently read token.\n\ttok Token\n\t// Self-closing tags like <hr/> are treated as start tags, except that\n\t// hasSelfClosingToken is set while they are being processed.\n\thasSelfClosingToken bool\n\t// doc is the document root element.\n\tdoc *Node\n\t// The stack of open elements (section 12.2.4.2) and active formatting\n\t// elements (section 12.2.4.3).\n\toe, afe nodeStack\n\t// Element pointers (section 12.2.4.4).\n\thead, form *Node\n\t// Other parsing state flags (section 12.2.4.5).\n\tscripting, framesetOK bool\n\t// The stack of template insertion modes\n\ttemplateStack insertionModeStack\n\t// im is the current insertion mode.\n\tim insertionMode\n\t// originalIM is the insertion mode to go back to after completing a text\n\t// or inTableText insertion mode.\n\toriginalIM insertionMode\n\t// fosterParenting is whether new elements should be inserted according to\n\t// the foster parenting rules (section 12.2.6.1).\n\tfosterParenting bool\n\t// quirks is whether the parser is operating in \"quirks mode.\"\n\tquirks bool\n\t// fragment is whether the parser is parsing an HTML fragment.\n\tfragment bool\n\t// context is the context element when parsing an HTML fragment\n\t// (section 12.4).\n\tcontext *Node\n}\n\nfunc (p *parser) top() *Node {\n\tif n := p.oe.top(); n != nil {\n\t\treturn n\n\t}\n\treturn p.doc\n}\n\n// Stop tags for use in popUntil. These come from section 12.2.4.2.\nvar (\n\tdefaultScopeStopTags = map[string][]a.Atom{\n\t\t\"\":     {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template},\n\t\t\"math\": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},\n\t\t\"svg\":  {a.Desc, a.ForeignObject, a.Title},\n\t}\n)\n\ntype scope int\n\nconst (\n\tdefaultScope scope = iota\n\tlistItemScope\n\tbuttonScope\n\ttableScope\n\ttableRowScope\n\ttableBodyScope\n\tselectScope\n)\n\n// popUntil pops the stack of open elements at the highest element whose tag\n// is in matchTags, provided there is no higher element in the scope's stop\n// tags (as defined in section 12.2.4.2). It returns whether or not there was\n// such an element. If there was not, popUntil leaves the stack unchanged.\n//\n// For example, the set of stop tags for table scope is: \"html\", \"table\". If\n// the stack was:\n// [\"html\", \"body\", \"font\", \"table\", \"b\", \"i\", \"u\"]\n// then popUntil(tableScope, \"font\") would return false, but\n// popUntil(tableScope, \"i\") would return true and the stack would become:\n// [\"html\", \"body\", \"font\", \"table\", \"b\"]\n//\n// If an element's tag is in both the stop tags and matchTags, then the stack\n// will be popped and the function returns true (provided, of course, there was\n// no higher element in the stack that was also in the stop tags). For example,\n// popUntil(tableScope, \"table\") returns true and leaves:\n// [\"html\", \"body\", \"font\"]\nfunc (p *parser) popUntil(s scope, matchTags ...a.Atom) bool {\n\tif i := p.indexOfElementInScope(s, matchTags...); i != -1 {\n\t\tp.oe = p.oe[:i]\n\t\treturn true\n\t}\n\treturn false\n}\n\n// indexOfElementInScope returns the index in p.oe of the highest element whose\n// tag is in matchTags that is in scope. If no matching element is in scope, it\n// returns -1.\nfunc (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\ttagAtom := p.oe[i].DataAtom\n\t\tif p.oe[i].Namespace == \"\" {\n\t\t\tfor _, t := range matchTags {\n\t\t\t\tif t == tagAtom {\n\t\t\t\t\treturn i\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch s {\n\t\t\tcase defaultScope:\n\t\t\t\t// No-op.\n\t\t\tcase listItemScope:\n\t\t\t\tif tagAtom == a.Ol || tagAtom == a.Ul {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tcase buttonScope:\n\t\t\t\tif tagAtom == a.Button {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tcase tableScope:\n\t\t\t\tif tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tcase selectScope:\n\t\t\t\tif tagAtom != a.Optgroup && tagAtom != a.Option {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tpanic(fmt.Sprintf(\"html: internal error: indexOfElementInScope unknown scope: %d\", s))\n\t\t\t}\n\t\t}\n\t\tswitch s {\n\t\tcase defaultScope, listItemScope, buttonScope:\n\t\t\tfor _, t := range defaultScopeStopTags[p.oe[i].Namespace] {\n\t\t\t\tif t == tagAtom {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn -1\n}\n\n// elementInScope is like popUntil, except that it doesn't modify the stack of\n// open elements.\nfunc (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool {\n\treturn p.indexOfElementInScope(s, matchTags...) != -1\n}\n\n// clearStackToContext pops elements off the stack of open elements until a\n// scope-defined element is found.\nfunc (p *parser) clearStackToContext(s scope) {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\ttagAtom := p.oe[i].DataAtom\n\t\tswitch s {\n\t\tcase tableScope:\n\t\t\tif tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\treturn\n\t\t\t}\n\t\tcase tableRowScope:\n\t\t\tif tagAtom == a.Html || tagAtom == a.Tr || tagAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\treturn\n\t\t\t}\n\t\tcase tableBodyScope:\n\t\t\tif tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead || tagAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\treturn\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"html: internal error: clearStackToContext unknown scope: %d\", s))\n\t\t}\n\t}\n}\n\n// parseGenericRawTextElement implements the generic raw text element parsing\n// algorithm defined in 12.2.6.2.\n// https://html.spec.whatwg.org/multipage/parsing.html#parsing-elements-that-contain-only-text\n// TODO: Since both RAWTEXT and RCDATA states are treated as tokenizer's part\n// officially, need to make tokenizer consider both states.\nfunc (p *parser) parseGenericRawTextElement() {\n\tp.addElement()\n\tp.originalIM = p.im\n\tp.im = textIM\n}\n\n// generateImpliedEndTags pops nodes off the stack of open elements as long as\n// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc.\n// If exceptions are specified, nodes with that name will not be popped off.\nfunc (p *parser) generateImpliedEndTags(exceptions ...string) {\n\tvar i int\nloop:\n\tfor i = len(p.oe) - 1; i >= 0; i-- {\n\t\tn := p.oe[i]\n\t\tif n.Type != ElementNode {\n\t\t\tbreak\n\t\t}\n\t\tswitch n.DataAtom {\n\t\tcase a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc:\n\t\t\tfor _, except := range exceptions {\n\t\t\t\tif n.Data == except {\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tbreak\n\t}\n\n\tp.oe = p.oe[:i+1]\n}\n\n// addChild adds a child node n to the top element, and pushes n onto the stack\n// of open elements if it is an element node.\nfunc (p *parser) addChild(n *Node) {\n\tif p.shouldFosterParent() {\n\t\tp.fosterParent(n)\n\t} else {\n\t\tp.top().AppendChild(n)\n\t}\n\n\tif n.Type == ElementNode {\n\t\tp.insertOpenElement(n)\n\t}\n}\n\nfunc (p *parser) insertOpenElement(n *Node) {\n\tp.oe = append(p.oe, n)\n\tif len(p.oe) > 512 {\n\t\tpanic(\"html: open stack of elements exceeds 512 nodes\")\n\t}\n}\n\n// shouldFosterParent returns whether the next node to be added should be\n// foster parented.\nfunc (p *parser) shouldFosterParent() bool {\n\tif p.fosterParenting {\n\t\tswitch p.top().DataAtom {\n\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// fosterParent adds a child node according to the foster parenting rules.\n// Section 12.2.6.1, \"foster parenting\".\nfunc (p *parser) fosterParent(n *Node) {\n\tvar table, parent, prev, template *Node\n\tvar i int\n\tfor i = len(p.oe) - 1; i >= 0; i-- {\n\t\tif p.oe[i].DataAtom == a.Table {\n\t\t\ttable = p.oe[i]\n\t\t\tbreak\n\t\t}\n\t}\n\n\tvar j int\n\tfor j = len(p.oe) - 1; j >= 0; j-- {\n\t\tif p.oe[j].DataAtom == a.Template {\n\t\t\ttemplate = p.oe[j]\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif template != nil && (table == nil || j > i) {\n\t\ttemplate.AppendChild(n)\n\t\treturn\n\t}\n\n\tif table == nil {\n\t\t// The foster parent is the html element.\n\t\tparent = p.oe[0]\n\t} else {\n\t\tparent = table.Parent\n\t}\n\tif parent == nil {\n\t\tparent = p.oe[i-1]\n\t}\n\n\tif table != nil {\n\t\tprev = table.PrevSibling\n\t} else {\n\t\tprev = parent.LastChild\n\t}\n\tif prev != nil && prev.Type == TextNode && n.Type == TextNode {\n\t\tprev.Data += n.Data\n\t\treturn\n\t}\n\n\tparent.InsertBefore(n, table)\n}\n\n// addText adds text to the preceding node if it is a text node, or else it\n// calls addChild with a new text node.\nfunc (p *parser) addText(text string) {\n\tif text == \"\" {\n\t\treturn\n\t}\n\n\tif p.shouldFosterParent() {\n\t\tp.fosterParent(&Node{\n\t\t\tType: TextNode,\n\t\t\tData: text,\n\t\t})\n\t\treturn\n\t}\n\n\tt := p.top()\n\tif n := t.LastChild; n != nil && n.Type == TextNode {\n\t\tn.Data += text\n\t\treturn\n\t}\n\tp.addChild(&Node{\n\t\tType: TextNode,\n\t\tData: text,\n\t})\n}\n\n// addElement adds a child element based on the current token.\nfunc (p *parser) addElement() {\n\tp.addChild(&Node{\n\t\tType:     ElementNode,\n\t\tDataAtom: p.tok.DataAtom,\n\t\tData:     p.tok.Data,\n\t\tAttr:     p.tok.Attr,\n\t})\n}\n\n// Section 12.2.4.3.\nfunc (p *parser) addFormattingElement() {\n\ttagAtom, attr := p.tok.DataAtom, p.tok.Attr\n\tp.addElement()\n\n\t// Implement the Noah's Ark clause, but with three per family instead of two.\n\tidenticalElements := 0\nfindIdenticalElements:\n\tfor i := len(p.afe) - 1; i >= 0; i-- {\n\t\tn := p.afe[i]\n\t\tif n.Type == scopeMarkerNode {\n\t\t\tbreak\n\t\t}\n\t\tif n.Type != ElementNode {\n\t\t\tcontinue\n\t\t}\n\t\tif n.Namespace != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif n.DataAtom != tagAtom {\n\t\t\tcontinue\n\t\t}\n\t\tif len(n.Attr) != len(attr) {\n\t\t\tcontinue\n\t\t}\n\tcompareAttributes:\n\t\tfor _, t0 := range n.Attr {\n\t\t\tfor _, t1 := range attr {\n\t\t\t\tif t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val {\n\t\t\t\t\t// Found a match for this attribute, continue with the next attribute.\n\t\t\t\t\tcontinue compareAttributes\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we get here, there is no attribute that matches a.\n\t\t\t// Therefore the element is not identical to the new one.\n\t\t\tcontinue findIdenticalElements\n\t\t}\n\n\t\tidenticalElements++\n\t\tif identicalElements >= 3 {\n\t\t\tp.afe.remove(n)\n\t\t}\n\t}\n\n\tp.afe = append(p.afe, p.top())\n}\n\n// Section 12.2.4.3.\nfunc (p *parser) clearActiveFormattingElements() {\n\tfor {\n\t\tif n := p.afe.pop(); len(p.afe) == 0 || n.Type == scopeMarkerNode {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// Section 12.2.4.3.\nfunc (p *parser) reconstructActiveFormattingElements() {\n\tn := p.afe.top()\n\tif n == nil {\n\t\treturn\n\t}\n\tif n.Type == scopeMarkerNode || p.oe.index(n) != -1 {\n\t\treturn\n\t}\n\ti := len(p.afe) - 1\n\tfor n.Type != scopeMarkerNode && p.oe.index(n) == -1 {\n\t\tif i == 0 {\n\t\t\ti = -1\n\t\t\tbreak\n\t\t}\n\t\ti--\n\t\tn = p.afe[i]\n\t}\n\tfor {\n\t\ti++\n\t\tclone := p.afe[i].clone()\n\t\tp.addChild(clone)\n\t\tp.afe[i] = clone\n\t\tif i == len(p.afe)-1 {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Section 12.2.5.\nfunc (p *parser) acknowledgeSelfClosingTag() {\n\tp.hasSelfClosingToken = false\n}\n\n// An insertion mode (section 12.2.4.1) is the state transition function from\n// a particular state in the HTML5 parser's state machine. It updates the\n// parser's fields depending on parser.tok (where ErrorToken means EOF).\n// It returns whether the token was consumed.\ntype insertionMode func(*parser) bool\n\n// setOriginalIM sets the insertion mode to return to after completing a text or\n// inTableText insertion mode.\n// Section 12.2.4.1, \"using the rules for\".\nfunc (p *parser) setOriginalIM() {\n\tif p.originalIM != nil {\n\t\tpanic(\"html: bad parser state: originalIM was set twice\")\n\t}\n\tp.originalIM = p.im\n}\n\n// Section 12.2.4.1, \"reset the insertion mode\".\nfunc (p *parser) resetInsertionMode() {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\tn := p.oe[i]\n\t\tlast := i == 0\n\t\tif last && p.context != nil {\n\t\t\tn = p.context\n\t\t}\n\n\t\tswitch n.DataAtom {\n\t\tcase a.Select:\n\t\t\tif !last {\n\t\t\t\tfor ancestor, first := n, p.oe[0]; ancestor != first; {\n\t\t\t\t\tancestor = p.oe[p.oe.index(ancestor)-1]\n\t\t\t\t\tswitch ancestor.DataAtom {\n\t\t\t\t\tcase a.Template:\n\t\t\t\t\t\tp.im = inSelectIM\n\t\t\t\t\t\treturn\n\t\t\t\t\tcase a.Table:\n\t\t\t\t\t\tp.im = inSelectInTableIM\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.im = inSelectIM\n\t\tcase a.Td, a.Th:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\t\tp.im = inCellIM\n\t\tcase a.Tr:\n\t\t\tp.im = inRowIM\n\t\tcase a.Tbody, a.Thead, a.Tfoot:\n\t\t\tp.im = inTableBodyIM\n\t\tcase a.Caption:\n\t\t\tp.im = inCaptionIM\n\t\tcase a.Colgroup:\n\t\t\tp.im = inColumnGroupIM\n\t\tcase a.Table:\n\t\t\tp.im = inTableIM\n\t\tcase a.Template:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\tif n.Namespace != \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tp.im = p.templateStack.top()\n\t\tcase a.Head:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\t\tp.im = inHeadIM\n\t\tcase a.Body:\n\t\t\tp.im = inBodyIM\n\t\tcase a.Frameset:\n\t\t\tp.im = inFramesetIM\n\t\tcase a.Html:\n\t\t\tif p.head == nil {\n\t\t\t\tp.im = beforeHeadIM\n\t\t\t} else {\n\t\t\t\tp.im = afterHeadIM\n\t\t\t}\n\t\tdefault:\n\t\t\tif last {\n\t\t\t\tp.im = inBodyIM\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\treturn\n\t}\n}\n\nconst whitespace = \" \\t\\r\\n\\f\"\n\n// Section 12.2.6.4.1.\nfunc initialIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tp.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(p.tok.Data) == 0 {\n\t\t\t// It was all whitespace, so ignore it.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\tn, quirks := parseDoctype(p.tok.Data)\n\t\tp.doc.AppendChild(n)\n\t\tp.quirks = quirks\n\t\tp.im = beforeHTMLIM\n\t\treturn true\n\t}\n\tp.quirks = true\n\tp.im = beforeHTMLIM\n\treturn false\n}\n\n// Section 12.2.6.4.2.\nfunc beforeHTMLIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase TextToken:\n\t\tp.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(p.tok.Data) == 0 {\n\t\t\t// It was all whitespace, so ignore it.\n\t\t\treturn true\n\t\t}\n\tcase StartTagToken:\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\tp.addElement()\n\t\t\tp.im = beforeHeadIM\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Head, a.Body, a.Html, a.Br:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Html, a.Html.String())\n\t\t\treturn false\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\t}\n\tp.parseImpliedToken(StartTagToken, a.Html, a.Html.String())\n\treturn false\n}\n\n// Section 12.2.6.4.3.\nfunc beforeHeadIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tp.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(p.tok.Data) == 0 {\n\t\t\t// It was all whitespace, so ignore it.\n\t\t\treturn true\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Head:\n\t\t\tp.addElement()\n\t\t\tp.head = p.top()\n\t\t\tp.im = inHeadIM\n\t\t\treturn true\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Head, a.Body, a.Html, a.Br:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Head, a.Head.String())\n\t\t\treturn false\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\t}\n\n\tp.parseImpliedToken(StartTagToken, a.Head, a.Head.String())\n\treturn false\n}\n\n// Section 12.2.6.4.4.\nfunc inHeadIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) < len(p.tok.Data) {\n\t\t\t// Add the initial whitespace to the current node.\n\t\t\tp.addText(p.tok.Data[:len(p.tok.Data)-len(s)])\n\t\t\tif s == \"\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.tok.Data = s\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\treturn true\n\t\tcase a.Noscript:\n\t\t\tif p.scripting {\n\t\t\t\tp.parseGenericRawTextElement()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tp.im = inHeadNoscriptIM\n\t\t\t// Don't let the tokenizer go into raw text mode when scripting is disabled.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\treturn true\n\t\tcase a.Script, a.Title:\n\t\t\tp.addElement()\n\t\t\tp.setOriginalIM()\n\t\t\tp.im = textIM\n\t\t\treturn true\n\t\tcase a.Noframes, a.Style:\n\t\t\tp.parseGenericRawTextElement()\n\t\t\treturn true\n\t\tcase a.Head:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// We don't handle all of the corner cases when mixing foreign\n\t\t\t// content (i.e. <math> or <svg>) with <template>. Without this\n\t\t\t// early return, we can get into an infinite loop, possibly because\n\t\t\t// of the \"TODO... further divergence\" a little below.\n\t\t\t//\n\t\t\t// As a workaround, if we are mixing foreign content and templates,\n\t\t\t// just ignore the rest of the HTML. Foreign content is rare and a\n\t\t\t// relatively old HTML feature. Templates are also rare and a\n\t\t\t// relatively new HTML feature. Their combination is very rare.\n\t\t\tfor _, e := range p.oe {\n\t\t\t\tif e.Namespace != \"\" {\n\t\t\t\t\tp.im = ignoreTheRemainingTokens\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.addElement()\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inTemplateIM\n\t\t\tp.templateStack = append(p.templateStack, inTemplateIM)\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Head:\n\t\t\tp.oe.pop()\n\t\t\tp.im = afterHeadIM\n\t\t\treturn true\n\t\tcase a.Body, a.Html, a.Br:\n\t\t\tp.parseImpliedToken(EndTagToken, a.Head, a.Head.String())\n\t\t\treturn false\n\t\tcase a.Template:\n\t\t\tif !p.oe.contains(a.Template) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// TODO: remove this further divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\t\tp.generateImpliedEndTags()\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tif n := p.oe[i]; n.Namespace == \"\" && n.DataAtom == a.Template {\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.templateStack.pop()\n\t\t\tp.resetInsertionMode()\n\t\t\treturn true\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\t}\n\n\tp.parseImpliedToken(EndTagToken, a.Head, a.Head.String())\n\treturn false\n}\n\n// Section 12.2.6.4.5.\nfunc inHeadNoscriptIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Style:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Head:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Noscript:\n\t\t\t// Don't let the tokenizer go into raw text mode even when a <noscript>\n\t\t\t// tag is in \"in head noscript\" insertion mode.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Noscript, a.Br:\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) == 0 {\n\t\t\t// It was all whitespace.\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase CommentToken:\n\t\treturn inHeadIM(p)\n\t}\n\tp.oe.pop()\n\tif p.top().DataAtom != a.Head {\n\t\tpanic(\"html: the new current node will be a head element.\")\n\t}\n\tp.im = inHeadIM\n\tif p.tok.DataAtom == a.Noscript {\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Section 12.2.6.4.6.\nfunc afterHeadIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) < len(p.tok.Data) {\n\t\t\t// Add the initial whitespace to the current node.\n\t\t\tp.addText(p.tok.Data[:len(p.tok.Data)-len(s)])\n\t\t\tif s == \"\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.tok.Data = s\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Body:\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inBodyIM\n\t\t\treturn true\n\t\tcase a.Frameset:\n\t\t\tp.addElement()\n\t\t\tp.im = inFramesetIM\n\t\t\treturn true\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:\n\t\t\tp.insertOpenElement(p.head)\n\t\t\tdefer p.oe.remove(p.head)\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Head:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Body, a.Html, a.Br:\n\t\t\t// Drop down to creating an implied <body> tag.\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\t}\n\n\tp.parseImpliedToken(StartTagToken, a.Body, a.Body.String())\n\tp.framesetOK = true\n\tif p.tok.Type == ErrorToken {\n\t\t// Stop parsing.\n\t\treturn true\n\t}\n\treturn false\n}\n\n// copyAttributes copies attributes of src not found on dst to dst.\nfunc copyAttributes(dst *Node, src Token) {\n\tif len(src.Attr) == 0 {\n\t\treturn\n\t}\n\tattr := map[string]string{}\n\tfor _, t := range dst.Attr {\n\t\tattr[t.Key] = t.Val\n\t}\n\tfor _, t := range src.Attr {\n\t\tif _, ok := attr[t.Key]; !ok {\n\t\t\tdst.Attr = append(dst.Attr, t)\n\t\t\tattr[t.Key] = t.Val\n\t\t}\n\t}\n}\n\n// Section 12.2.6.4.7.\nfunc inBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\td := p.tok.Data\n\t\tswitch n := p.oe.top(); n.DataAtom {\n\t\tcase a.Pre, a.Listing:\n\t\t\tif n.FirstChild == nil {\n\t\t\t\t// Ignore a newline at the start of a <pre> block.\n\t\t\t\tif d != \"\" && d[0] == '\\r' {\n\t\t\t\t\td = d[1:]\n\t\t\t\t}\n\t\t\t\tif d != \"\" && d[0] == '\\n' {\n\t\t\t\t\td = d[1:]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\td = strings.Replace(d, \"\\x00\", \"\", -1)\n\t\tif d == \"\" {\n\t\t\treturn true\n\t\t}\n\t\tp.reconstructActiveFormattingElements()\n\t\tp.addText(d)\n\t\tif p.framesetOK && strings.TrimLeft(d, whitespace) != \"\" {\n\t\t\t// There were non-whitespace characters inserted.\n\t\t\tp.framesetOK = false\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\tif p.oe.contains(a.Template) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcopyAttributes(p.oe[0], p.tok)\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Body:\n\t\t\tif p.oe.contains(a.Template) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif len(p.oe) >= 2 {\n\t\t\t\tbody := p.oe[1]\n\t\t\t\tif body.Type == ElementNode && body.DataAtom == a.Body {\n\t\t\t\t\tp.framesetOK = false\n\t\t\t\t\tcopyAttributes(body, p.tok)\n\t\t\t\t}\n\t\t\t}\n\t\tcase a.Frameset:\n\t\t\tif !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tbody := p.oe[1]\n\t\t\tif body.Parent != nil {\n\t\t\t\tbody.Parent.RemoveChild(body)\n\t\t\t}\n\t\t\tp.oe = p.oe[:1]\n\t\t\tp.addElement()\n\t\t\tp.im = inFramesetIM\n\t\t\treturn true\n\t\tcase a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Main, a.Menu, a.Nav, a.Ol, a.P, a.Search, a.Section, a.Summary, a.Ul:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tswitch n := p.top(); n.DataAtom {\n\t\t\tcase a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Pre, a.Listing:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\t\t// The newline, if any, will be dealt with by the TextToken case.\n\t\t\tp.framesetOK = false\n\t\tcase a.Form:\n\t\t\tif p.form != nil && !p.oe.contains(a.Template) {\n\t\t\t\t// Ignore the token\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\t\tif !p.oe.contains(a.Template) {\n\t\t\t\tp.form = p.top()\n\t\t\t}\n\t\tcase a.Li:\n\t\t\tp.framesetOK = false\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tnode := p.oe[i]\n\t\t\t\tswitch node.DataAtom {\n\t\t\t\tcase a.Li:\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\tcase a.Address, a.Div, a.P:\n\t\t\t\t\tcontinue\n\t\t\t\tdefault:\n\t\t\t\t\tif !isSpecialElement(node) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.Dd, a.Dt:\n\t\t\tp.framesetOK = false\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tnode := p.oe[i]\n\t\t\t\tswitch node.DataAtom {\n\t\t\t\tcase a.Dd, a.Dt:\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\tcase a.Address, a.Div, a.P:\n\t\t\t\t\tcontinue\n\t\t\t\tdefault:\n\t\t\t\t\tif !isSpecialElement(node) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.Plaintext:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.Button:\n\t\t\tp.popUntil(defaultScope, a.Button)\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\tcase a.A:\n\t\t\tfor i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {\n\t\t\t\tif n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {\n\t\t\t\t\tp.inBodyEndTagFormatting(a.A, \"a\")\n\t\t\t\t\tp.oe.remove(n)\n\t\t\t\t\tp.afe.remove(n)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addFormattingElement()\n\t\tcase a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addFormattingElement()\n\t\tcase a.Nobr:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tif p.elementInScope(defaultScope, a.Nobr) {\n\t\t\t\tp.inBodyEndTagFormatting(a.Nobr, \"nobr\")\n\t\t\t\tp.reconstructActiveFormattingElements()\n\t\t\t}\n\t\t\tp.addFormattingElement()\n\t\tcase a.Applet, a.Marquee, a.Object:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.framesetOK = false\n\t\tcase a.Table:\n\t\t\tif !p.quirks {\n\t\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inTableIM\n\t\t\treturn true\n\t\tcase a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\tif p.tok.DataAtom == a.Input {\n\t\t\t\tfor _, t := range p.tok.Attr {\n\t\t\t\t\tif t.Key == \"type\" {\n\t\t\t\t\t\tif strings.EqualFold(t.Val, \"hidden\") {\n\t\t\t\t\t\t\t// Skip setting framesetOK = false\n\t\t\t\t\t\t\treturn true\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\tp.framesetOK = false\n\t\tcase a.Param, a.Source, a.Track:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\tcase a.Hr:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\tp.framesetOK = false\n\t\tcase a.Image:\n\t\t\tp.tok.DataAtom = a.Img\n\t\t\tp.tok.Data = a.Img.String()\n\t\t\treturn false\n\t\tcase a.Textarea:\n\t\t\tp.addElement()\n\t\t\tp.setOriginalIM()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = textIM\n\t\tcase a.Xmp:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.framesetOK = false\n\t\t\tp.parseGenericRawTextElement()\n\t\tcase a.Iframe:\n\t\t\tp.framesetOK = false\n\t\t\tp.parseGenericRawTextElement()\n\t\tcase a.Noembed:\n\t\t\tp.parseGenericRawTextElement()\n\t\tcase a.Noscript:\n\t\t\tif p.scripting {\n\t\t\t\tp.parseGenericRawTextElement()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\t// Don't let the tokenizer go into raw text mode when scripting is disabled.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectIM\n\t\t\treturn true\n\t\tcase a.Optgroup, a.Option:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\tcase a.Rb, a.Rtc:\n\t\t\tif p.elementInScope(defaultScope, a.Ruby) {\n\t\t\t\tp.generateImpliedEndTags()\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Rp, a.Rt:\n\t\t\tif p.elementInScope(defaultScope, a.Ruby) {\n\t\t\t\tp.generateImpliedEndTags(\"rtc\")\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Math, a.Svg:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tif p.tok.DataAtom == a.Math {\n\t\t\t\tadjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)\n\t\t\t} else {\n\t\t\t\tadjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)\n\t\t\t}\n\t\t\tadjustForeignAttributes(p.tok.Attr)\n\t\t\tp.addElement()\n\t\t\tp.top().Namespace = p.tok.Data\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:\n\t\t\t// Ignore the token.\n\t\tdefault:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Body:\n\t\t\tif p.elementInScope(defaultScope, a.Body) {\n\t\t\t\tp.im = afterBodyIM\n\t\t\t}\n\t\tcase a.Html:\n\t\t\tif p.elementInScope(defaultScope, a.Body) {\n\t\t\t\tp.parseImpliedToken(EndTagToken, a.Body, a.Body.String())\n\t\t\t\treturn false\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Main, a.Menu, a.Nav, a.Ol, a.Pre, a.Search, a.Section, a.Summary, a.Ul:\n\t\t\tp.popUntil(defaultScope, p.tok.DataAtom)\n\t\tcase a.Form:\n\t\t\tif p.oe.contains(a.Template) {\n\t\t\t\ti := p.indexOfElementInScope(defaultScope, a.Form)\n\t\t\t\tif i == -1 {\n\t\t\t\t\t// Ignore the token.\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tp.generateImpliedEndTags()\n\t\t\t\tif p.oe[i].DataAtom != a.Form {\n\t\t\t\t\t// Ignore the token.\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tp.popUntil(defaultScope, a.Form)\n\t\t\t} else {\n\t\t\t\tnode := p.form\n\t\t\t\tp.form = nil\n\t\t\t\ti := p.indexOfElementInScope(defaultScope, a.Form)\n\t\t\t\tif node == nil || i == -1 || p.oe[i] != node {\n\t\t\t\t\t// Ignore the token.\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tp.generateImpliedEndTags()\n\t\t\t\tp.oe.remove(node)\n\t\t\t}\n\t\tcase a.P:\n\t\t\tif !p.elementInScope(buttonScope, a.P) {\n\t\t\t\tp.parseImpliedToken(StartTagToken, a.P, a.P.String())\n\t\t\t}\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\tcase a.Li:\n\t\t\tp.popUntil(listItemScope, a.Li)\n\t\tcase a.Dd, a.Dt:\n\t\t\tp.popUntil(defaultScope, p.tok.DataAtom)\n\t\tcase a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:\n\t\t\tp.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)\n\t\tcase a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:\n\t\t\tp.inBodyEndTagFormatting(p.tok.DataAtom, p.tok.Data)\n\t\tcase a.Applet, a.Marquee, a.Object:\n\t\t\tif p.popUntil(defaultScope, p.tok.DataAtom) {\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t}\n\t\tcase a.Br:\n\t\t\tp.tok.Type = StartTagToken\n\t\t\treturn false\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tdefault:\n\t\t\tp.inBodyEndTagOther(p.tok.DataAtom, p.tok.Data)\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\tcase ErrorToken:\n\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\tif len(p.templateStack) > 0 {\n\t\t\tp.im = inTemplateIM\n\t\t\treturn false\n\t\t}\n\t\tfor _, e := range p.oe {\n\t\t\tswitch e.DataAtom {\n\t\t\tcase a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,\n\t\t\t\ta.Thead, a.Tr, a.Body, a.Html:\n\t\t\tdefault:\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\nfunc (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {\n\t// This is the \"adoption agency\" algorithm, described at\n\t// https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency\n\n\t// TODO: this is a fairly literal line-by-line translation of that algorithm.\n\t// Once the code successfully parses the comprehensive test suite, we should\n\t// refactor this code to be more idiomatic.\n\n\t// Steps 1-2\n\tif current := p.oe.top(); current.Data == tagName && p.afe.index(current) == -1 {\n\t\tp.oe.pop()\n\t\treturn\n\t}\n\n\t// Steps 3-5. The outer loop.\n\tfor i := 0; i < 8; i++ {\n\t\t// Step 6. Find the formatting element.\n\t\tvar formattingElement *Node\n\t\tfor j := len(p.afe) - 1; j >= 0; j-- {\n\t\t\tif p.afe[j].Type == scopeMarkerNode {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif p.afe[j].DataAtom == tagAtom {\n\t\t\t\tformattingElement = p.afe[j]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif formattingElement == nil {\n\t\t\tp.inBodyEndTagOther(tagAtom, tagName)\n\t\t\treturn\n\t\t}\n\n\t\t// Step 7. Ignore the tag if formatting element is not in the stack of open elements.\n\t\tfeIndex := p.oe.index(formattingElement)\n\t\tif feIndex == -1 {\n\t\t\tp.afe.remove(formattingElement)\n\t\t\treturn\n\t\t}\n\t\t// Step 8. Ignore the tag if formatting element is not in the scope.\n\t\tif !p.elementInScope(defaultScope, tagAtom) {\n\t\t\t// Ignore the tag.\n\t\t\treturn\n\t\t}\n\n\t\t// Step 9. This step is omitted because it's just a parse error but no need to return.\n\n\t\t// Steps 10-11. Find the furthest block.\n\t\tvar furthestBlock *Node\n\t\tfor _, e := range p.oe[feIndex:] {\n\t\t\tif isSpecialElement(e) {\n\t\t\t\tfurthestBlock = e\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif furthestBlock == nil {\n\t\t\te := p.oe.pop()\n\t\t\tfor e != formattingElement {\n\t\t\t\te = p.oe.pop()\n\t\t\t}\n\t\t\tp.afe.remove(e)\n\t\t\treturn\n\t\t}\n\n\t\t// Steps 12-13. Find the common ancestor and bookmark node.\n\t\tcommonAncestor := p.oe[feIndex-1]\n\t\tbookmark := p.afe.index(formattingElement)\n\n\t\t// Step 14. The inner loop. Find the lastNode to reparent.\n\t\tlastNode := furthestBlock\n\t\tnode := furthestBlock\n\t\tx := p.oe.index(node)\n\t\t// Step 14.1.\n\t\tj := 0\n\t\tfor {\n\t\t\t// Step 14.2.\n\t\t\tj++\n\t\t\t// Step. 14.3.\n\t\t\tx--\n\t\t\tnode = p.oe[x]\n\t\t\t// Step 14.4. Go to the next step if node is formatting element.\n\t\t\tif node == formattingElement {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// Step 14.5. Remove node from the list of active formatting elements if\n\t\t\t// inner loop counter is greater than three and node is in the list of\n\t\t\t// active formatting elements.\n\t\t\tif ni := p.afe.index(node); j > 3 && ni > -1 {\n\t\t\t\tp.afe.remove(node)\n\t\t\t\t// If any element of the list of active formatting elements is removed,\n\t\t\t\t// we need to take care whether bookmark should be decremented or not.\n\t\t\t\t// This is because the value of bookmark may exceed the size of the\n\t\t\t\t// list by removing elements from the list.\n\t\t\t\tif ni <= bookmark {\n\t\t\t\t\tbookmark--\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Step 14.6. Continue the next inner loop if node is not in the list of\n\t\t\t// active formatting elements.\n\t\t\tif p.afe.index(node) == -1 {\n\t\t\t\tp.oe.remove(node)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Step 14.7.\n\t\t\tclone := node.clone()\n\t\t\tp.afe[p.afe.index(node)] = clone\n\t\t\tp.oe[p.oe.index(node)] = clone\n\t\t\tnode = clone\n\t\t\t// Step 14.8.\n\t\t\tif lastNode == furthestBlock {\n\t\t\t\tbookmark = p.afe.index(node) + 1\n\t\t\t}\n\t\t\t// Step 14.9.\n\t\t\tif lastNode.Parent != nil {\n\t\t\t\tlastNode.Parent.RemoveChild(lastNode)\n\t\t\t}\n\t\t\tnode.AppendChild(lastNode)\n\t\t\t// Step 14.10.\n\t\t\tlastNode = node\n\t\t}\n\n\t\t// Step 15. Reparent lastNode to the common ancestor,\n\t\t// or for misnested table nodes, to the foster parent.\n\t\tif lastNode.Parent != nil {\n\t\t\tlastNode.Parent.RemoveChild(lastNode)\n\t\t}\n\t\tswitch commonAncestor.DataAtom {\n\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\tp.fosterParent(lastNode)\n\t\tdefault:\n\t\t\tcommonAncestor.AppendChild(lastNode)\n\t\t}\n\n\t\t// Steps 16-18. Reparent nodes from the furthest block's children\n\t\t// to a clone of the formatting element.\n\t\tclone := formattingElement.clone()\n\t\treparentChildren(clone, furthestBlock)\n\t\tfurthestBlock.AppendChild(clone)\n\n\t\t// Step 19. Fix up the list of active formatting elements.\n\t\tif oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {\n\t\t\t// Move the bookmark with the rest of the list.\n\t\t\tbookmark--\n\t\t}\n\t\tp.afe.remove(formattingElement)\n\t\tp.afe.insert(bookmark, clone)\n\n\t\t// Step 20. Fix up the stack of open elements.\n\t\tp.oe.remove(formattingElement)\n\t\tp.oe.insert(p.oe.index(furthestBlock)+1, clone)\n\t}\n}\n\n// inBodyEndTagOther performs the \"any other end tag\" algorithm for inBodyIM.\n// \"Any other end tag\" handling from 12.2.6.5 The rules for parsing tokens in foreign content\n// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign\nfunc (p *parser) inBodyEndTagOther(tagAtom a.Atom, tagName string) {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t// Two element nodes have the same tag if they have the same Data (a\n\t\t// string-typed field). As an optimization, for common HTML tags, each\n\t\t// Data string is assigned a unique, non-zero DataAtom (a uint32-typed\n\t\t// field), since integer comparison is faster than string comparison.\n\t\t// Uncommon (custom) tags get a zero DataAtom.\n\t\t//\n\t\t// The if condition here is equivalent to (p.oe[i].Data == tagName).\n\t\tif (p.oe[i].DataAtom == tagAtom) &&\n\t\t\t((tagAtom != 0) || (p.oe[i].Data == tagName)) {\n\t\t\tp.oe = p.oe[:i]\n\t\t\tbreak\n\t\t}\n\t\tif isSpecialElement(p.oe[i]) {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Section 12.2.6.4.8.\nfunc textIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase ErrorToken:\n\t\tp.oe.pop()\n\tcase TextToken:\n\t\td := p.tok.Data\n\t\tif n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {\n\t\t\t// Ignore a newline at the start of a <textarea> block.\n\t\t\tif d != \"\" && d[0] == '\\r' {\n\t\t\t\td = d[1:]\n\t\t\t}\n\t\t\tif d != \"\" && d[0] == '\\n' {\n\t\t\t\td = d[1:]\n\t\t\t}\n\t\t}\n\t\tif d == \"\" {\n\t\t\treturn true\n\t\t}\n\t\tp.addText(d)\n\t\treturn true\n\tcase EndTagToken:\n\t\tp.oe.pop()\n\t}\n\tp.im = p.originalIM\n\tp.originalIM = nil\n\treturn p.tok.Type == EndTagToken\n}\n\n// Section 12.2.6.4.9.\nfunc inTableIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tp.tok.Data = strings.Replace(p.tok.Data, \"\\x00\", \"\", -1)\n\t\tswitch p.oe.top().DataAtom {\n\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\tif strings.Trim(p.tok.Data, whitespace) == \"\" {\n\t\t\t\tp.addText(p.tok.Data)\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Caption:\n\t\t\tp.clearStackToContext(tableScope)\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.addElement()\n\t\t\tp.im = inCaptionIM\n\t\t\treturn true\n\t\tcase a.Colgroup:\n\t\t\tp.clearStackToContext(tableScope)\n\t\t\tp.addElement()\n\t\t\tp.im = inColumnGroupIM\n\t\t\treturn true\n\t\tcase a.Col:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Colgroup, a.Colgroup.String())\n\t\t\treturn false\n\t\tcase a.Tbody, a.Tfoot, a.Thead:\n\t\t\tp.clearStackToContext(tableScope)\n\t\t\tp.addElement()\n\t\t\tp.im = inTableBodyIM\n\t\t\treturn true\n\t\tcase a.Td, a.Th, a.Tr:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Tbody, a.Tbody.String())\n\t\t\treturn false\n\t\tcase a.Table:\n\t\t\tif p.popUntil(tableScope, a.Table) {\n\t\t\t\tp.resetInsertionMode()\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Style, a.Script, a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Input:\n\t\t\tfor _, t := range p.tok.Attr {\n\t\t\t\tif t.Key == \"type\" && strings.EqualFold(t.Val, \"hidden\") {\n\t\t\t\t\tp.addElement()\n\t\t\t\t\tp.oe.pop()\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Otherwise drop down to the default action.\n\t\tcase a.Form:\n\t\t\tif p.oe.contains(a.Template) || p.form != nil {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tp.form = p.oe.pop()\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tswitch p.top().DataAtom {\n\t\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\t\tp.fosterParenting = true\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tp.fosterParenting = false\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectInTableIM\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Table:\n\t\t\tif p.popUntil(tableScope, a.Table) {\n\t\t\t\tp.resetInsertionMode()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase ErrorToken:\n\t\treturn inBodyIM(p)\n\t}\n\n\tp.fosterParenting = true\n\tdefer func() { p.fosterParenting = false }()\n\n\treturn inBodyIM(p)\n}\n\n// Section 12.2.6.4.11.\nfunc inCaptionIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Thead, a.Tr:\n\t\t\tif !p.popUntil(tableScope, a.Caption) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.im = inTableIM\n\t\t\treturn false\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectInTableIM\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Caption:\n\t\t\tif p.popUntil(tableScope, a.Caption) {\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t\tp.im = inTableIM\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Table:\n\t\t\tif !p.popUntil(tableScope, a.Caption) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.im = inTableIM\n\t\t\treturn false\n\t\tcase a.Body, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\t}\n\treturn inBodyIM(p)\n}\n\n// Section 12.2.6.4.12.\nfunc inColumnGroupIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) < len(p.tok.Data) {\n\t\t\t// Add the initial whitespace to the current node.\n\t\t\tp.addText(p.tok.Data[:len(p.tok.Data)-len(s)])\n\t\t\tif s == \"\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.tok.Data = s\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Col:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Colgroup:\n\t\t\tif p.oe.top().DataAtom == a.Colgroup {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableIM\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Col:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase ErrorToken:\n\t\treturn inBodyIM(p)\n\t}\n\tif p.oe.top().DataAtom != a.Colgroup {\n\t\treturn true\n\t}\n\tp.oe.pop()\n\tp.im = inTableIM\n\treturn false\n}\n\n// Section 12.2.6.4.13.\nfunc inTableBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Tr:\n\t\t\tp.clearStackToContext(tableBodyScope)\n\t\t\tp.addElement()\n\t\t\tp.im = inRowIM\n\t\t\treturn true\n\t\tcase a.Td, a.Th:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Tr, a.Tr.String())\n\t\t\treturn false\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:\n\t\t\tif p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) {\n\t\t\t\tp.im = inTableIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Tbody, a.Tfoot, a.Thead:\n\t\t\tif p.elementInScope(tableScope, p.tok.DataAtom) {\n\t\t\t\tp.clearStackToContext(tableBodyScope)\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableIM\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Table:\n\t\t\tif p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) {\n\t\t\t\tp.im = inTableIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th, a.Tr:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\t}\n\n\treturn inTableIM(p)\n}\n\n// Section 13.2.6.4.14.\nfunc inRowIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Td, a.Th:\n\t\t\tp.clearStackToContext(tableRowScope)\n\t\t\tp.addElement()\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.im = inCellIM\n\t\t\treturn true\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\tif p.elementInScope(tableScope, a.Tr) {\n\t\t\t\tp.clearStackToContext(tableRowScope)\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableBodyIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Tr:\n\t\t\tif p.elementInScope(tableScope, a.Tr) {\n\t\t\t\tp.clearStackToContext(tableRowScope)\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableBodyIM\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Table:\n\t\t\tif p.elementInScope(tableScope, a.Tr) {\n\t\t\t\tp.clearStackToContext(tableRowScope)\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableBodyIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Tbody, a.Tfoot, a.Thead:\n\t\t\tif p.elementInScope(tableScope, p.tok.DataAtom) && p.elementInScope(tableScope, a.Tr) {\n\t\t\t\tp.clearStackToContext(tableRowScope)\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableBodyIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn inTableIM(p)\n}\n\n// Section 12.2.6.4.15.\nfunc inCellIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:\n\t\t\tif p.popUntil(tableScope, a.Td, a.Th) {\n\t\t\t\t// Close the cell and reprocess.\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t\tp.im = inRowIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectInTableIM\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Td, a.Th:\n\t\t\tif !p.popUntil(tableScope, p.tok.DataAtom) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.im = inRowIM\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\tif !p.elementInScope(tableScope, p.tok.DataAtom) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Close the cell and reprocess.\n\t\t\tif p.popUntil(tableScope, a.Td, a.Th) {\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t}\n\t\t\tp.im = inRowIM\n\t\t\treturn false\n\t\t}\n\t}\n\treturn inBodyIM(p)\n}\n\n// Section 12.2.6.4.16.\nfunc inSelectIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tp.addText(strings.Replace(p.tok.Data, \"\\x00\", \"\", -1))\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Option:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Optgroup:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tif p.top().DataAtom == a.Optgroup {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Select:\n\t\t\tif !p.popUntil(selectScope, a.Select) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.resetInsertionMode()\n\t\tcase a.Input, a.Keygen, a.Textarea:\n\t\t\tif p.elementInScope(selectScope, a.Select) {\n\t\t\t\tp.parseImpliedToken(EndTagToken, a.Select, a.Select.String())\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// In order to properly ignore <textarea>, we need to change the tokenizer mode.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Script, a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Iframe, a.Noembed, a.Noframes, a.Noscript, a.Plaintext, a.Style, a.Title, a.Xmp:\n\t\t\t// Don't let the tokenizer go into raw text mode when there are raw tags\n\t\t\t// to be ignored. These tags should be ignored from the tokenizer\n\t\t\t// properly.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Option:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\tcase a.Optgroup:\n\t\t\ti := len(p.oe) - 1\n\t\t\tif p.oe[i].DataAtom == a.Option {\n\t\t\t\ti--\n\t\t\t}\n\t\t\tif p.oe[i].DataAtom == a.Optgroup {\n\t\t\t\tp.oe = p.oe[:i]\n\t\t\t}\n\t\tcase a.Select:\n\t\t\tif !p.popUntil(selectScope, a.Select) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.resetInsertionMode()\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase ErrorToken:\n\t\treturn inBodyIM(p)\n\t}\n\n\treturn true\n}\n\n// Section 12.2.6.4.17.\nfunc inSelectInTableIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken, EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th:\n\t\t\tif p.tok.Type == EndTagToken && !p.elementInScope(tableScope, p.tok.DataAtom) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// This is like p.popUntil(selectScope, a.Select), but it also\n\t\t\t// matches <math select>, not just <select>. Matching the MathML\n\t\t\t// tag is arguably incorrect (conceptually), but it mimics what\n\t\t\t// Chromium does.\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tif n := p.oe[i]; n.DataAtom == a.Select {\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.resetInsertionMode()\n\t\t\treturn false\n\t\t}\n\t}\n\treturn inSelectIM(p)\n}\n\n// Section 12.2.6.4.18.\nfunc inTemplateIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken, CommentToken, DoctypeToken:\n\t\treturn inBodyIM(p)\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Caption, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inTableIM)\n\t\t\tp.im = inTableIM\n\t\t\treturn false\n\t\tcase a.Col:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inColumnGroupIM)\n\t\t\tp.im = inColumnGroupIM\n\t\t\treturn false\n\t\tcase a.Tr:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inTableBodyIM)\n\t\t\tp.im = inTableBodyIM\n\t\t\treturn false\n\t\tcase a.Td, a.Th:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inRowIM)\n\t\t\tp.im = inRowIM\n\t\t\treturn false\n\t\tdefault:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inBodyIM)\n\t\t\tp.im = inBodyIM\n\t\t\treturn false\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase ErrorToken:\n\t\tif !p.oe.contains(a.Template) {\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t//\n\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\tp.generateImpliedEndTags()\n\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\tif n := p.oe[i]; n.Namespace == \"\" && n.DataAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tp.clearActiveFormattingElements()\n\t\tp.templateStack.pop()\n\t\tp.resetInsertionMode()\n\t\treturn false\n\t}\n\treturn false\n}\n\n// Section 12.2.6.4.19.\nfunc afterBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase ErrorToken:\n\t\t// Stop parsing.\n\t\treturn true\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) == 0 {\n\t\t\t// It was all whitespace.\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase StartTagToken:\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\tif !p.fragment {\n\t\t\t\tp.im = afterAfterBodyIM\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\t// The comment is attached to the <html> element.\n\t\tif len(p.oe) < 1 || p.oe[0].DataAtom != a.Html {\n\t\t\tpanic(\"html: bad parser state: <html> element not found, in the after-body insertion mode\")\n\t\t}\n\t\tp.oe[0].AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\t}\n\tp.im = inBodyIM\n\treturn false\n}\n\n// Section 12.2.6.4.20.\nfunc inFramesetIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\tcase TextToken:\n\t\t// Ignore all text but whitespace.\n\t\ts := strings.Map(func(c rune) rune {\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\t', '\\n', '\\f', '\\r':\n\t\t\t\treturn c\n\t\t\t}\n\t\t\treturn -1\n\t\t}, p.tok.Data)\n\t\tif s != \"\" {\n\t\t\tp.addText(s)\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Frameset:\n\t\t\tp.addElement()\n\t\tcase a.Frame:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\tcase a.Noframes:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Frameset:\n\t\t\tif p.oe.top().DataAtom != a.Html {\n\t\t\t\tp.oe.pop()\n\t\t\t\tif p.oe.top().DataAtom != a.Frameset {\n\t\t\t\t\tp.im = afterFramesetIM\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\n// Section 12.2.6.4.21.\nfunc afterFramesetIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\tcase TextToken:\n\t\t// Ignore all text but whitespace.\n\t\ts := strings.Map(func(c rune) rune {\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\t', '\\n', '\\f', '\\r':\n\t\t\t\treturn c\n\t\t\t}\n\t\t\treturn -1\n\t\t}, p.tok.Data)\n\t\tif s != \"\" {\n\t\t\tp.addText(s)\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Noframes:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\tp.im = afterAfterFramesetIM\n\t\t\treturn true\n\t\t}\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\n// Section 12.2.6.4.22.\nfunc afterAfterBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase ErrorToken:\n\t\t// Stop parsing.\n\t\treturn true\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) == 0 {\n\t\t\t// It was all whitespace.\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase StartTagToken:\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\treturn inBodyIM(p)\n\t}\n\tp.im = inBodyIM\n\treturn false\n}\n\n// Section 12.2.6.4.23.\nfunc afterAfterFramesetIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\tcase TextToken:\n\t\t// Ignore all text but whitespace.\n\t\ts := strings.Map(func(c rune) rune {\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\t', '\\n', '\\f', '\\r':\n\t\t\t\treturn c\n\t\t\t}\n\t\t\treturn -1\n\t\t}, p.tok.Data)\n\t\tif s != \"\" {\n\t\t\tp.tok.Data = s\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Noframes:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase DoctypeToken:\n\t\treturn inBodyIM(p)\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\nfunc ignoreTheRemainingTokens(p *parser) bool {\n\treturn true\n}\n\nconst whitespaceOrNUL = whitespace + \"\\x00\"\n\n// Section 12.2.6.5\nfunc parseForeignContent(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tif p.framesetOK {\n\t\t\tp.framesetOK = strings.TrimLeft(p.tok.Data, whitespaceOrNUL) == \"\"\n\t\t}\n\t\tp.tok.Data = strings.Replace(p.tok.Data, \"\\x00\", \"\\ufffd\", -1)\n\t\tp.addText(p.tok.Data)\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t})\n\tcase StartTagToken:\n\t\tif !p.fragment {\n\t\t\tb := breakout[p.tok.Data]\n\t\t\tif p.tok.DataAtom == a.Font {\n\t\t\tloop:\n\t\t\t\tfor _, attr := range p.tok.Attr {\n\t\t\t\t\tswitch attr.Key {\n\t\t\t\t\tcase \"color\", \"face\", \"size\":\n\t\t\t\t\t\tb = true\n\t\t\t\t\t\tbreak loop\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif b {\n\t\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\t\tn := p.oe[i]\n\t\t\t\t\tif n.Namespace == \"\" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {\n\t\t\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tcurrent := p.adjustedCurrentNode()\n\t\tswitch current.Namespace {\n\t\tcase \"math\":\n\t\t\tadjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)\n\t\tcase \"svg\":\n\t\t\t// Adjust SVG tag names. The tokenizer lower-cases tag names, but\n\t\t\t// SVG wants e.g. \"foreignObject\" with a capital second \"O\".\n\t\t\tif x := svgTagNameAdjustments[p.tok.Data]; x != \"\" {\n\t\t\t\tp.tok.DataAtom = a.Lookup([]byte(x))\n\t\t\t\tp.tok.Data = x\n\t\t\t}\n\t\t\tadjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)\n\t\tdefault:\n\t\t\tpanic(\"html: bad parser state: unexpected namespace\")\n\t\t}\n\t\tadjustForeignAttributes(p.tok.Attr)\n\t\tnamespace := current.Namespace\n\t\tp.addElement()\n\t\tp.top().Namespace = namespace\n\t\tif namespace != \"\" {\n\t\t\t// Don't let the tokenizer go into raw text mode in foreign content\n\t\t\t// (e.g. in an SVG <title> tag).\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t}\n\t\tif p.hasSelfClosingToken {\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t}\n\tcase EndTagToken:\n\t\tif strings.EqualFold(p.oe[len(p.oe)-1].Data, p.tok.Data) {\n\t\t\tp.oe = p.oe[:len(p.oe)-1]\n\t\t\treturn true\n\t\t}\n\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\tif strings.EqualFold(p.oe[i].Data, p.tok.Data) {\n\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif i > 0 && p.oe[i-1].Namespace == \"\" {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn p.im(p)\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\n// Section 12.2.4.2.\nfunc (p *parser) adjustedCurrentNode() *Node {\n\tif len(p.oe) == 1 && p.fragment && p.context != nil {\n\t\treturn p.context\n\t}\n\treturn p.oe.top()\n}\n\n// Section 12.2.6.\nfunc (p *parser) inForeignContent() bool {\n\tif len(p.oe) == 0 {\n\t\treturn false\n\t}\n\tn := p.adjustedCurrentNode()\n\tif n.Namespace == \"\" {\n\t\treturn false\n\t}\n\tif mathMLTextIntegrationPoint(n) {\n\t\tif p.tok.Type == StartTagToken && p.tok.DataAtom != a.Mglyph && p.tok.DataAtom != a.Malignmark {\n\t\t\treturn false\n\t\t}\n\t\tif p.tok.Type == TextToken {\n\t\t\treturn false\n\t\t}\n\t}\n\tif n.Namespace == \"math\" && n.DataAtom == a.AnnotationXml && p.tok.Type == StartTagToken && p.tok.DataAtom == a.Svg {\n\t\treturn false\n\t}\n\tif htmlIntegrationPoint(n) && (p.tok.Type == StartTagToken || p.tok.Type == TextToken) {\n\t\treturn false\n\t}\n\tif p.tok.Type == ErrorToken {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// parseImpliedToken parses a token as though it had appeared in the parser's\n// input.\nfunc (p *parser) parseImpliedToken(t TokenType, dataAtom a.Atom, data string) {\n\trealToken, selfClosing := p.tok, p.hasSelfClosingToken\n\tp.tok = Token{\n\t\tType:     t,\n\t\tDataAtom: dataAtom,\n\t\tData:     data,\n\t}\n\tp.hasSelfClosingToken = false\n\tp.parseCurrentToken()\n\tp.tok, p.hasSelfClosingToken = realToken, selfClosing\n}\n\n// parseCurrentToken runs the current token through the parsing routines\n// until it is consumed.\nfunc (p *parser) parseCurrentToken() {\n\tif p.tok.Type == SelfClosingTagToken {\n\t\tp.hasSelfClosingToken = true\n\t\tp.tok.Type = StartTagToken\n\t}\n\n\tconsumed := false\n\tfor !consumed {\n\t\tif p.inForeignContent() {\n\t\t\tconsumed = parseForeignContent(p)\n\t\t} else {\n\t\t\tconsumed = p.im(p)\n\t\t}\n\t}\n\n\tif p.hasSelfClosingToken {\n\t\t// This is a parse error, but ignore it.\n\t\tp.hasSelfClosingToken = false\n\t}\n}\n\nfunc (p *parser) parse() (err error) {\n\tdefer func() {\n\t\tif panicErr := recover(); panicErr != nil {\n\t\t\terr = fmt.Errorf(\"%s\", panicErr)\n\t\t}\n\t}()\n\t// Iterate until EOF. Any other error will cause an early return.\n\tfor err != io.EOF {\n\t\t// CDATA sections are allowed only in foreign content.\n\t\tn := p.oe.top()\n\t\tp.tokenizer.AllowCDATA(n != nil && n.Namespace != \"\")\n\t\t// Read and parse the next token.\n\t\tp.tokenizer.Next()\n\t\tp.tok = p.tokenizer.Token()\n\t\tif p.tok.Type == ErrorToken {\n\t\t\terr = p.tokenizer.Err()\n\t\t\tif err != nil && err != io.EOF {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tp.parseCurrentToken()\n\t}\n\treturn nil\n}\n\n// Parse returns the parse tree for the HTML from the given Reader.\n//\n// It implements the HTML5 parsing algorithm\n// (https://html.spec.whatwg.org/multipage/syntax.html#tree-construction),\n// which is very complicated. The resultant tree can contain implicitly created\n// nodes that have no explicit <tag> listed in r's data, and nodes' parents can\n// differ from the nesting implied by a naive processing of start and end\n// <tag>s. Conversely, explicit <tag>s in r's data can be silently dropped,\n// with no corresponding node in the resulting tree.\n//\n// Parse will reject HTML that is nested deeper than 512 elements.\n//\n// The input is assumed to be UTF-8 encoded.\nfunc Parse(r io.Reader) (*Node, error) {\n\treturn ParseWithOptions(r)\n}\n\n// ParseFragment parses a fragment of HTML and returns the nodes that were\n// found. If the fragment is the InnerHTML for an existing element, pass that\n// element in context.\n//\n// It has the same intricacies as Parse.\nfunc ParseFragment(r io.Reader, context *Node) ([]*Node, error) {\n\treturn ParseFragmentWithOptions(r, context)\n}\n\n// ParseOption configures a parser.\ntype ParseOption func(p *parser)\n\n// ParseOptionEnableScripting configures the scripting flag.\n// https://html.spec.whatwg.org/multipage/webappapis.html#enabling-and-disabling-scripting\n//\n// By default, scripting is enabled.\nfunc ParseOptionEnableScripting(enable bool) ParseOption {\n\treturn func(p *parser) {\n\t\tp.scripting = enable\n\t}\n}\n\n// ParseWithOptions is like Parse, with options.\nfunc ParseWithOptions(r io.Reader, opts ...ParseOption) (*Node, error) {\n\tp := &parser{\n\t\ttokenizer: NewTokenizer(r),\n\t\tdoc: &Node{\n\t\t\tType: DocumentNode,\n\t\t},\n\t\tscripting:  true,\n\t\tframesetOK: true,\n\t\tim:         initialIM,\n\t}\n\n\tfor _, f := range opts {\n\t\tf(p)\n\t}\n\n\tif err := p.parse(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn p.doc, nil\n}\n\n// ParseFragmentWithOptions is like ParseFragment, with options.\nfunc ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) ([]*Node, error) {\n\tcontextTag := \"\"\n\tif context != nil {\n\t\tif context.Type != ElementNode {\n\t\t\treturn nil, errors.New(\"html: ParseFragment of non-element Node\")\n\t\t}\n\t\t// The next check isn't just context.DataAtom.String() == context.Data because\n\t\t// it is valid to pass an element whose tag isn't a known atom. For example,\n\t\t// DataAtom == 0 and Data = \"tagfromthefuture\" is perfectly consistent.\n\t\tif context.DataAtom != a.Lookup([]byte(context.Data)) {\n\t\t\treturn nil, fmt.Errorf(\"html: inconsistent Node: DataAtom=%q, Data=%q\", context.DataAtom, context.Data)\n\t\t}\n\t\tcontextTag = context.DataAtom.String()\n\t}\n\tp := &parser{\n\t\tdoc: &Node{\n\t\t\tType: DocumentNode,\n\t\t},\n\t\tscripting: true,\n\t\tfragment:  true,\n\t\tcontext:   context,\n\t}\n\tif context != nil && context.Namespace != \"\" {\n\t\tp.tokenizer = NewTokenizer(r)\n\t} else {\n\t\tp.tokenizer = NewTokenizerFragment(r, contextTag)\n\t}\n\n\tfor _, f := range opts {\n\t\tf(p)\n\t}\n\n\troot := &Node{\n\t\tType:     ElementNode,\n\t\tDataAtom: a.Html,\n\t\tData:     a.Html.String(),\n\t}\n\tp.doc.AppendChild(root)\n\tp.oe = nodeStack{root}\n\tif context != nil && context.DataAtom == a.Template {\n\t\tp.templateStack = append(p.templateStack, inTemplateIM)\n\t}\n\tp.resetInsertionMode()\n\n\tfor n := context; n != nil; n = n.Parent {\n\t\tif n.Type == ElementNode && n.DataAtom == a.Form {\n\t\t\tp.form = n\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif err := p.parse(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tparent := p.doc\n\tif context != nil {\n\t\tparent = root\n\t}\n\n\tvar result []*Node\n\tfor c := parent.FirstChild; c != nil; {\n\t\tnext := c.NextSibling\n\t\tparent.RemoveChild(c)\n\t\tresult = append(result, c)\n\t\tc = next\n\t}\n\treturn result, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/render.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 html\n\nimport (\n\t\"bufio\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\ntype writer interface {\n\tio.Writer\n\tio.ByteWriter\n\tWriteString(string) (int, error)\n}\n\n// Render renders the parse tree n to the given writer.\n//\n// Rendering is done on a 'best effort' basis: calling Parse on the output of\n// Render will always result in something similar to the original tree, but it\n// is not necessarily an exact clone unless the original tree was 'well-formed'.\n// 'Well-formed' is not easily specified; the HTML5 specification is\n// complicated.\n//\n// Calling Parse on arbitrary input typically results in a 'well-formed' parse\n// tree. However, it is possible for Parse to yield a 'badly-formed' parse tree.\n// For example, in a 'well-formed' parse tree, no <a> element is a child of\n// another <a> element: parsing \"<a><a>\" results in two sibling elements.\n// Similarly, in a 'well-formed' parse tree, no <a> element is a child of a\n// <table> element: parsing \"<p><table><a>\" results in a <p> with two sibling\n// children; the <a> is reparented to the <table>'s parent. However, calling\n// Parse on \"<a><table><a>\" does not return an error, but the result has an <a>\n// element with an <a> child, and is therefore not 'well-formed'.\n//\n// Programmatically constructed trees are typically also 'well-formed', but it\n// is possible to construct a tree that looks innocuous but, when rendered and\n// re-parsed, results in a different tree. A simple example is that a solitary\n// text node would become a tree containing <html>, <head> and <body> elements.\n// Another example is that the programmatic equivalent of \"a<head>b</head>c\"\n// becomes \"<html><head><head/><body>abc</body></html>\".\nfunc Render(w io.Writer, n *Node) error {\n\tif x, ok := w.(writer); ok {\n\t\treturn render(x, n)\n\t}\n\tbuf := bufio.NewWriter(w)\n\tif err := render(buf, n); err != nil {\n\t\treturn err\n\t}\n\treturn buf.Flush()\n}\n\n// plaintextAbort is returned from render1 when a <plaintext> element\n// has been rendered. No more end tags should be rendered after that.\nvar plaintextAbort = errors.New(\"html: internal error (plaintext abort)\")\n\nfunc render(w writer, n *Node) error {\n\terr := render1(w, n)\n\tif err == plaintextAbort {\n\t\terr = nil\n\t}\n\treturn err\n}\n\nfunc render1(w writer, n *Node) error {\n\t// Render non-element nodes; these are the easy cases.\n\tswitch n.Type {\n\tcase ErrorNode:\n\t\treturn errors.New(\"html: cannot render an ErrorNode node\")\n\tcase TextNode:\n\t\treturn escape(w, n.Data)\n\tcase DocumentNode:\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif err := render1(w, c); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\tcase ElementNode:\n\t\t// No-op.\n\tcase CommentNode:\n\t\tif _, err := w.WriteString(\"<!--\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := escapeComment(w, n.Data); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := w.WriteString(\"-->\"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\tcase DoctypeNode:\n\t\tif _, err := w.WriteString(\"<!DOCTYPE \"); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := escape(w, n.Data); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif n.Attr != nil {\n\t\t\tvar p, s string\n\t\t\tfor _, a := range n.Attr {\n\t\t\t\tswitch a.Key {\n\t\t\t\tcase \"public\":\n\t\t\t\t\tp = a.Val\n\t\t\t\tcase \"system\":\n\t\t\t\t\ts = a.Val\n\t\t\t\t}\n\t\t\t}\n\t\t\tif p != \"\" {\n\t\t\t\tif _, err := w.WriteString(\" PUBLIC \"); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := writeQuoted(w, p); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif s != \"\" {\n\t\t\t\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t\tif err := writeQuoted(w, s); err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if s != \"\" {\n\t\t\t\tif _, err := w.WriteString(\" SYSTEM \"); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := writeQuoted(w, s); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn w.WriteByte('>')\n\tcase RawNode:\n\t\t_, err := w.WriteString(n.Data)\n\t\treturn err\n\tdefault:\n\t\treturn errors.New(\"html: unknown node type\")\n\t}\n\n\t// Render the <xxx> opening tag.\n\tif err := w.WriteByte('<'); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.WriteString(n.Data); err != nil {\n\t\treturn err\n\t}\n\tfor _, a := range n.Attr {\n\t\tif err := w.WriteByte(' '); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif a.Namespace != \"\" {\n\t\t\tif _, err := w.WriteString(a.Namespace); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := w.WriteByte(':'); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif _, err := w.WriteString(a.Key); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif _, err := w.WriteString(`=\"`); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := escape(w, a.Val); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := w.WriteByte('\"'); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tif voidElements[n.Data] {\n\t\tif n.FirstChild != nil {\n\t\t\treturn fmt.Errorf(\"html: void element <%s> has child nodes\", n.Data)\n\t\t}\n\t\t_, err := w.WriteString(\"/>\")\n\t\treturn err\n\t}\n\tif err := w.WriteByte('>'); err != nil {\n\t\treturn err\n\t}\n\n\t// Add initial newline where there is danger of a newline being ignored.\n\tif c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, \"\\n\") {\n\t\tswitch n.Data {\n\t\tcase \"pre\", \"listing\", \"textarea\":\n\t\t\tif err := w.WriteByte('\\n'); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\t// Render any child nodes\n\tif childTextNodesAreLiteral(n) {\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif c.Type == TextNode {\n\t\t\t\tif _, err := w.WriteString(c.Data); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err := render1(w, c); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif n.Data == \"plaintext\" {\n\t\t\t// Don't render anything else. <plaintext> must be the\n\t\t\t// last element in the file, with no closing tag.\n\t\t\treturn plaintextAbort\n\t\t}\n\t} else {\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif err := render1(w, c); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\n\t// Render the </xxx> closing tag.\n\tif _, err := w.WriteString(\"</\"); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.WriteString(n.Data); err != nil {\n\t\treturn err\n\t}\n\treturn w.WriteByte('>')\n}\n\nfunc childTextNodesAreLiteral(n *Node) bool {\n\t// Per WHATWG HTML 13.3, if the parent of the current node is a style,\n\t// script, xmp, iframe, noembed, noframes, or plaintext element, and the\n\t// current node is a text node, append the value of the node's data\n\t// literally. The specification is not explicit about it, but we only\n\t// enforce this if we are in the HTML namespace (i.e. when the namespace is\n\t// \"\").\n\t// NOTE: we also always include noscript elements, although the\n\t// specification states that they should only be rendered as such if\n\t// scripting is enabled for the node (which is not something we track).\n\tif n.Namespace != \"\" {\n\t\treturn false\n\t}\n\tswitch n.Data {\n\tcase \"iframe\", \"noembed\", \"noframes\", \"noscript\", \"plaintext\", \"script\", \"style\", \"xmp\":\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// writeQuoted writes s to w surrounded by quotes. Normally it will use double\n// quotes, but if s contains a double quote, it will use single quotes.\n// It is used for writing the identifiers in a doctype declaration.\n// In valid HTML, they can't contain both types of quotes.\nfunc writeQuoted(w writer, s string) error {\n\tvar q byte = '\"'\n\tif strings.Contains(s, `\"`) {\n\t\tq = '\\''\n\t}\n\tif err := w.WriteByte(q); err != nil {\n\t\treturn err\n\t}\n\tif _, err := w.WriteString(s); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte(q); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Section 12.1.2, \"Elements\", gives this list of void elements. Void elements\n// are those that can't have any contents.\nvar voidElements = map[string]bool{\n\t\"area\":   true,\n\t\"base\":   true,\n\t\"br\":     true,\n\t\"col\":    true,\n\t\"embed\":  true,\n\t\"hr\":     true,\n\t\"img\":    true,\n\t\"input\":  true,\n\t\"keygen\": true, // \"keygen\" has been removed from the spec, but are kept here for backwards compatibility.\n\t\"link\":   true,\n\t\"meta\":   true,\n\t\"param\":  true,\n\t\"source\": true,\n\t\"track\":  true,\n\t\"wbr\":    true,\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/html/token.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 html\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"golang.org/x/net/html/atom\"\n)\n\n// A TokenType is the type of a Token.\ntype TokenType uint32\n\nconst (\n\t// ErrorToken means that an error occurred during tokenization.\n\tErrorToken TokenType = iota\n\t// TextToken means a text node.\n\tTextToken\n\t// A StartTagToken looks like <a>.\n\tStartTagToken\n\t// An EndTagToken looks like </a>.\n\tEndTagToken\n\t// A SelfClosingTagToken tag looks like <br/>.\n\tSelfClosingTagToken\n\t// A CommentToken looks like <!--x-->.\n\tCommentToken\n\t// A DoctypeToken looks like <!DOCTYPE x>\n\tDoctypeToken\n)\n\n// ErrBufferExceeded means that the buffering limit was exceeded.\nvar ErrBufferExceeded = errors.New(\"max buffer exceeded\")\n\n// String returns a string representation of the TokenType.\nfunc (t TokenType) String() string {\n\tswitch t {\n\tcase ErrorToken:\n\t\treturn \"Error\"\n\tcase TextToken:\n\t\treturn \"Text\"\n\tcase StartTagToken:\n\t\treturn \"StartTag\"\n\tcase EndTagToken:\n\t\treturn \"EndTag\"\n\tcase SelfClosingTagToken:\n\t\treturn \"SelfClosingTag\"\n\tcase CommentToken:\n\t\treturn \"Comment\"\n\tcase DoctypeToken:\n\t\treturn \"Doctype\"\n\t}\n\treturn \"Invalid(\" + strconv.Itoa(int(t)) + \")\"\n}\n\n// An Attribute is an attribute namespace-key-value triple. Namespace is\n// non-empty for foreign attributes like xlink, Key is alphabetic (and hence\n// does not contain escapable characters like '&', '<' or '>'), and Val is\n// unescaped (it looks like \"a<b\" rather than \"a&lt;b\").\n//\n// Namespace is only used by the parser, not the tokenizer.\ntype Attribute struct {\n\tNamespace, Key, Val string\n}\n\n// A Token consists of a TokenType and some Data (tag name for start and end\n// tags, content for text, comments and doctypes). A tag Token may also contain\n// a slice of Attributes. Data is unescaped for all Tokens (it looks like \"a<b\"\n// rather than \"a&lt;b\"). For tag Tokens, DataAtom is the atom for Data, or\n// zero if Data is not a known tag name.\ntype Token struct {\n\tType     TokenType\n\tDataAtom atom.Atom\n\tData     string\n\tAttr     []Attribute\n}\n\n// tagString returns a string representation of a tag Token's Data and Attr.\nfunc (t Token) tagString() string {\n\tif len(t.Attr) == 0 {\n\t\treturn t.Data\n\t}\n\tbuf := bytes.NewBufferString(t.Data)\n\tfor _, a := range t.Attr {\n\t\tbuf.WriteByte(' ')\n\t\tbuf.WriteString(a.Key)\n\t\tbuf.WriteString(`=\"`)\n\t\tescape(buf, a.Val)\n\t\tbuf.WriteByte('\"')\n\t}\n\treturn buf.String()\n}\n\n// String returns a string representation of the Token.\nfunc (t Token) String() string {\n\tswitch t.Type {\n\tcase ErrorToken:\n\t\treturn \"\"\n\tcase TextToken:\n\t\treturn EscapeString(t.Data)\n\tcase StartTagToken:\n\t\treturn \"<\" + t.tagString() + \">\"\n\tcase EndTagToken:\n\t\treturn \"</\" + t.tagString() + \">\"\n\tcase SelfClosingTagToken:\n\t\treturn \"<\" + t.tagString() + \"/>\"\n\tcase CommentToken:\n\t\treturn \"<!--\" + escapeCommentString(t.Data) + \"-->\"\n\tcase DoctypeToken:\n\t\treturn \"<!DOCTYPE \" + EscapeString(t.Data) + \">\"\n\t}\n\treturn \"Invalid(\" + strconv.Itoa(int(t.Type)) + \")\"\n}\n\n// span is a range of bytes in a Tokenizer's buffer. The start is inclusive,\n// the end is exclusive.\ntype span struct {\n\tstart, end int\n}\n\n// A Tokenizer returns a stream of HTML Tokens.\ntype Tokenizer struct {\n\t// r is the source of the HTML text.\n\tr io.Reader\n\t// tt is the TokenType of the current token.\n\ttt TokenType\n\t// err is the first error encountered during tokenization. It is possible\n\t// for tt != Error && err != nil to hold: this means that Next returned a\n\t// valid token but the subsequent Next call will return an error token.\n\t// For example, if the HTML text input was just \"plain\", then the first\n\t// Next call would set z.err to io.EOF but return a TextToken, and all\n\t// subsequent Next calls would return an ErrorToken.\n\t// err is never reset. Once it becomes non-nil, it stays non-nil.\n\terr error\n\t// readErr is the error returned by the io.Reader r. It is separate from\n\t// err because it is valid for an io.Reader to return (n int, err1 error)\n\t// such that n > 0 && err1 != nil, and callers should always process the\n\t// n > 0 bytes before considering the error err1.\n\treadErr error\n\t// buf[raw.start:raw.end] holds the raw bytes of the current token.\n\t// buf[raw.end:] is buffered input that will yield future tokens.\n\traw span\n\tbuf []byte\n\t// maxBuf limits the data buffered in buf. A value of 0 means unlimited.\n\tmaxBuf int\n\t// buf[data.start:data.end] holds the raw bytes of the current token's data:\n\t// a text token's text, a tag token's tag name, etc.\n\tdata span\n\t// pendingAttr is the attribute key and value currently being tokenized.\n\t// When complete, pendingAttr is pushed onto attr. nAttrReturned is\n\t// incremented on each call to TagAttr.\n\tpendingAttr   [2]span\n\tattr          [][2]span\n\tnAttrReturned int\n\t// rawTag is the \"script\" in \"</script>\" that closes the next token. If\n\t// non-empty, the subsequent call to Next will return a raw or RCDATA text\n\t// token: one that treats \"<p>\" as text instead of an element.\n\t// rawTag's contents are lower-cased.\n\trawTag string\n\t// textIsRaw is whether the current text token's data is not escaped.\n\ttextIsRaw bool\n\t// convertNUL is whether NUL bytes in the current token's data should\n\t// be converted into \\ufffd replacement characters.\n\tconvertNUL bool\n\t// allowCDATA is whether CDATA sections are allowed in the current context.\n\tallowCDATA bool\n}\n\n// AllowCDATA sets whether or not the tokenizer recognizes <![CDATA[foo]]> as\n// the text \"foo\". The default value is false, which means to recognize it as\n// a bogus comment \"<!-- [CDATA[foo]] -->\" instead.\n//\n// Strictly speaking, an HTML5 compliant tokenizer should allow CDATA if and\n// only if tokenizing foreign content, such as MathML and SVG. However,\n// tracking foreign-contentness is difficult to do purely in the tokenizer,\n// as opposed to the parser, due to HTML integration points: an <svg> element\n// can contain a <foreignObject> that is foreign-to-SVG but not foreign-to-\n// HTML. For strict compliance with the HTML5 tokenization algorithm, it is the\n// responsibility of the user of a tokenizer to call AllowCDATA as appropriate.\n// In practice, if using the tokenizer without caring whether MathML or SVG\n// CDATA is text or comments, such as tokenizing HTML to find all the anchor\n// text, it is acceptable to ignore this responsibility.\nfunc (z *Tokenizer) AllowCDATA(allowCDATA bool) {\n\tz.allowCDATA = allowCDATA\n}\n\n// NextIsNotRawText instructs the tokenizer that the next token should not be\n// considered as 'raw text'. Some elements, such as script and title elements,\n// normally require the next token after the opening tag to be 'raw text' that\n// has no child elements. For example, tokenizing \"<title>a<b>c</b>d</title>\"\n// yields a start tag token for \"<title>\", a text token for \"a<b>c</b>d\", and\n// an end tag token for \"</title>\". There are no distinct start tag or end tag\n// tokens for the \"<b>\" and \"</b>\".\n//\n// This tokenizer implementation will generally look for raw text at the right\n// times. Strictly speaking, an HTML5 compliant tokenizer should not look for\n// raw text if in foreign content: <title> generally needs raw text, but a\n// <title> inside an <svg> does not. Another example is that a <textarea>\n// generally needs raw text, but a <textarea> is not allowed as an immediate\n// child of a <select>; in normal parsing, a <textarea> implies </select>, but\n// one cannot close the implicit element when parsing a <select>'s InnerHTML.\n// Similarly to AllowCDATA, tracking the correct moment to override raw-text-\n// ness is difficult to do purely in the tokenizer, as opposed to the parser.\n// For strict compliance with the HTML5 tokenization algorithm, it is the\n// responsibility of the user of a tokenizer to call NextIsNotRawText as\n// appropriate. In practice, like AllowCDATA, it is acceptable to ignore this\n// responsibility for basic usage.\n//\n// Note that this 'raw text' concept is different from the one offered by the\n// Tokenizer.Raw method.\nfunc (z *Tokenizer) NextIsNotRawText() {\n\tz.rawTag = \"\"\n}\n\n// Err returns the error associated with the most recent ErrorToken token.\n// This is typically io.EOF, meaning the end of tokenization.\nfunc (z *Tokenizer) Err() error {\n\tif z.tt != ErrorToken {\n\t\treturn nil\n\t}\n\treturn z.err\n}\n\n// readByte returns the next byte from the input stream, doing a buffered read\n// from z.r into z.buf if necessary. z.buf[z.raw.start:z.raw.end] remains a contiguous byte\n// slice that holds all the bytes read so far for the current token.\n// It sets z.err if the underlying reader returns an error.\n// Pre-condition: z.err == nil.\nfunc (z *Tokenizer) readByte() byte {\n\tif z.raw.end >= len(z.buf) {\n\t\t// Our buffer is exhausted and we have to read from z.r. Check if the\n\t\t// previous read resulted in an error.\n\t\tif z.readErr != nil {\n\t\t\tz.err = z.readErr\n\t\t\treturn 0\n\t\t}\n\t\t// We copy z.buf[z.raw.start:z.raw.end] to the beginning of z.buf. If the length\n\t\t// z.raw.end - z.raw.start is more than half the capacity of z.buf, then we\n\t\t// allocate a new buffer before the copy.\n\t\tc := cap(z.buf)\n\t\td := z.raw.end - z.raw.start\n\t\tvar buf1 []byte\n\t\tif 2*d > c {\n\t\t\tbuf1 = make([]byte, d, 2*c)\n\t\t} else {\n\t\t\tbuf1 = z.buf[:d]\n\t\t}\n\t\tcopy(buf1, z.buf[z.raw.start:z.raw.end])\n\t\tif x := z.raw.start; x != 0 {\n\t\t\t// Adjust the data/attr spans to refer to the same contents after the copy.\n\t\t\tz.data.start -= x\n\t\t\tz.data.end -= x\n\t\t\tz.pendingAttr[0].start -= x\n\t\t\tz.pendingAttr[0].end -= x\n\t\t\tz.pendingAttr[1].start -= x\n\t\t\tz.pendingAttr[1].end -= x\n\t\t\tfor i := range z.attr {\n\t\t\t\tz.attr[i][0].start -= x\n\t\t\t\tz.attr[i][0].end -= x\n\t\t\t\tz.attr[i][1].start -= x\n\t\t\t\tz.attr[i][1].end -= x\n\t\t\t}\n\t\t}\n\t\tz.raw.start, z.raw.end, z.buf = 0, d, buf1[:d]\n\t\t// Now that we have copied the live bytes to the start of the buffer,\n\t\t// we read from z.r into the remainder.\n\t\tvar n int\n\t\tn, z.readErr = readAtLeastOneByte(z.r, buf1[d:cap(buf1)])\n\t\tif n == 0 {\n\t\t\tz.err = z.readErr\n\t\t\treturn 0\n\t\t}\n\t\tz.buf = buf1[:d+n]\n\t}\n\tx := z.buf[z.raw.end]\n\tz.raw.end++\n\tif z.maxBuf > 0 && z.raw.end-z.raw.start >= z.maxBuf {\n\t\tz.err = ErrBufferExceeded\n\t\treturn 0\n\t}\n\treturn x\n}\n\n// Buffered returns a slice containing data buffered but not yet tokenized.\nfunc (z *Tokenizer) Buffered() []byte {\n\treturn z.buf[z.raw.end:]\n}\n\n// readAtLeastOneByte wraps an io.Reader so that reading cannot return (0, nil).\n// It returns io.ErrNoProgress if the underlying r.Read method returns (0, nil)\n// too many times in succession.\nfunc readAtLeastOneByte(r io.Reader, b []byte) (int, error) {\n\tfor i := 0; i < 100; i++ {\n\t\tif n, err := r.Read(b); n != 0 || err != nil {\n\t\t\treturn n, err\n\t\t}\n\t}\n\treturn 0, io.ErrNoProgress\n}\n\n// skipWhiteSpace skips past any white space.\nfunc (z *Tokenizer) skipWhiteSpace() {\n\tif z.err != nil {\n\t\treturn\n\t}\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase ' ', '\\n', '\\r', '\\t', '\\f':\n\t\t\t// No-op.\n\t\tdefault:\n\t\t\tz.raw.end--\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readRawOrRCDATA reads until the next \"</foo>\", where \"foo\" is z.rawTag and\n// is typically something like \"script\" or \"textarea\".\nfunc (z *Tokenizer) readRawOrRCDATA() {\n\tif z.rawTag == \"script\" {\n\t\tz.readScript()\n\t\tz.textIsRaw = true\n\t\tz.rawTag = \"\"\n\t\treturn\n\t}\nloop:\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tif c != '<' {\n\t\t\tcontinue loop\n\t\t}\n\t\tc = z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tif c != '/' {\n\t\t\tz.raw.end--\n\t\t\tcontinue loop\n\t\t}\n\t\tif z.readRawEndTag() || z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\t}\n\tz.data.end = z.raw.end\n\t// A textarea's or title's RCDATA can contain escaped entities.\n\tz.textIsRaw = z.rawTag != \"textarea\" && z.rawTag != \"title\"\n\tz.rawTag = \"\"\n}\n\n// readRawEndTag attempts to read a tag like \"</foo>\", where \"foo\" is z.rawTag.\n// If it succeeds, it backs up the input position to reconsume the tag and\n// returns true. Otherwise it returns false. The opening \"</\" has already been\n// consumed.\nfunc (z *Tokenizer) readRawEndTag() bool {\n\tfor i := 0; i < len(z.rawTag); i++ {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\treturn false\n\t\t}\n\t\tif c != z.rawTag[i] && c != z.rawTag[i]-('a'-'A') {\n\t\t\tz.raw.end--\n\t\t\treturn false\n\t\t}\n\t}\n\tc := z.readByte()\n\tif z.err != nil {\n\t\treturn false\n\t}\n\tswitch c {\n\tcase ' ', '\\n', '\\r', '\\t', '\\f', '/', '>':\n\t\t// The 3 is 2 for the leading \"</\" plus 1 for the trailing character c.\n\t\tz.raw.end -= 3 + len(z.rawTag)\n\t\treturn true\n\t}\n\tz.raw.end--\n\treturn false\n}\n\n// readScript reads until the next </script> tag, following the byzantine\n// rules for escaping/hiding the closing tag.\nfunc (z *Tokenizer) readScript() {\n\tdefer func() {\n\t\tz.data.end = z.raw.end\n\t}()\n\tvar c byte\n\nscriptData:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tif c == '<' {\n\t\tgoto scriptDataLessThanSign\n\t}\n\tgoto scriptData\n\nscriptDataLessThanSign:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase '/':\n\t\tgoto scriptDataEndTagOpen\n\tcase '!':\n\t\tgoto scriptDataEscapeStart\n\t}\n\tz.raw.end--\n\tgoto scriptData\n\nscriptDataEndTagOpen:\n\tif z.readRawEndTag() || z.err != nil {\n\t\treturn\n\t}\n\tgoto scriptData\n\nscriptDataEscapeStart:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tif c == '-' {\n\t\tgoto scriptDataEscapeStartDash\n\t}\n\tz.raw.end--\n\tgoto scriptData\n\nscriptDataEscapeStartDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tif c == '-' {\n\t\tgoto scriptDataEscapedDashDash\n\t}\n\tz.raw.end--\n\tgoto scriptData\n\nscriptDataEscaped:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataEscapedDash\n\tcase '<':\n\t\tgoto scriptDataEscapedLessThanSign\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataEscapedDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataEscapedLessThanSign\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataEscapedDashDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataEscapedLessThanSign\n\tcase '>':\n\t\tgoto scriptData\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataEscapedLessThanSign:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tif c == '/' {\n\t\tgoto scriptDataEscapedEndTagOpen\n\t}\n\tif 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' {\n\t\tgoto scriptDataDoubleEscapeStart\n\t}\n\tz.raw.end--\n\tgoto scriptData\n\nscriptDataEscapedEndTagOpen:\n\tif z.readRawEndTag() || z.err != nil {\n\t\treturn\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataDoubleEscapeStart:\n\tz.raw.end--\n\tfor i := 0; i < len(\"script\"); i++ {\n\t\tc = z.readByte()\n\t\tif z.err != nil {\n\t\t\treturn\n\t\t}\n\t\tif c != \"script\"[i] && c != \"SCRIPT\"[i] {\n\t\t\tz.raw.end--\n\t\t\tgoto scriptDataEscaped\n\t\t}\n\t}\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase ' ', '\\n', '\\r', '\\t', '\\f', '/', '>':\n\t\tgoto scriptDataDoubleEscaped\n\t}\n\tz.raw.end--\n\tgoto scriptDataEscaped\n\nscriptDataDoubleEscaped:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataDoubleEscapedDash\n\tcase '<':\n\t\tgoto scriptDataDoubleEscapedLessThanSign\n\t}\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapedDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataDoubleEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataDoubleEscapedLessThanSign\n\t}\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapedDashDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataDoubleEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataDoubleEscapedLessThanSign\n\tcase '>':\n\t\tgoto scriptData\n\t}\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapedLessThanSign:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tif c == '/' {\n\t\tgoto scriptDataDoubleEscapeEnd\n\t}\n\tz.raw.end--\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapeEnd:\n\tif z.readRawEndTag() {\n\t\tz.raw.end += len(\"</script>\")\n\t\tgoto scriptDataEscaped\n\t}\n\tif z.err != nil {\n\t\treturn\n\t}\n\tgoto scriptDataDoubleEscaped\n}\n\n// readComment reads the next comment token starting with \"<!--\". The opening\n// \"<!--\" has already been consumed.\nfunc (z *Tokenizer) readComment() {\n\t// When modifying this function, consider manually increasing the\n\t// maxSuffixLen constant in func TestComments, from 6 to e.g. 9 or more.\n\t// That increase should only be temporary, not committed, as it\n\t// exponentially affects the test running time.\n\n\tz.data.start = z.raw.end\n\tdefer func() {\n\t\tif z.data.end < z.data.start {\n\t\t\t// It's a comment with no data, like <!-->.\n\t\t\tz.data.end = z.data.start\n\t\t}\n\t}()\n\n\tvar dashCount int\n\tbeginning := true\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.end = z.calculateAbruptCommentDataEnd()\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase '-':\n\t\t\tdashCount++\n\t\t\tcontinue\n\t\tcase '>':\n\t\t\tif dashCount >= 2 || beginning {\n\t\t\t\tz.data.end = z.raw.end - len(\"-->\")\n\t\t\t\treturn\n\t\t\t}\n\t\tcase '!':\n\t\t\tif dashCount >= 2 {\n\t\t\t\tc = z.readByte()\n\t\t\t\tif z.err != nil {\n\t\t\t\t\tz.data.end = z.calculateAbruptCommentDataEnd()\n\t\t\t\t\treturn\n\t\t\t\t} else if c == '>' {\n\t\t\t\t\tz.data.end = z.raw.end - len(\"--!>\")\n\t\t\t\t\treturn\n\t\t\t\t} else if c == '-' {\n\t\t\t\t\tdashCount = 1\n\t\t\t\t\tbeginning = false\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdashCount = 0\n\t\tbeginning = false\n\t}\n}\n\nfunc (z *Tokenizer) calculateAbruptCommentDataEnd() int {\n\traw := z.Raw()\n\tconst prefixLen = len(\"<!--\")\n\tif len(raw) >= prefixLen {\n\t\traw = raw[prefixLen:]\n\t\tif hasSuffix(raw, \"--!\") {\n\t\t\treturn z.raw.end - 3\n\t\t} else if hasSuffix(raw, \"--\") {\n\t\t\treturn z.raw.end - 2\n\t\t} else if hasSuffix(raw, \"-\") {\n\t\t\treturn z.raw.end - 1\n\t\t}\n\t}\n\treturn z.raw.end\n}\n\nfunc hasSuffix(b []byte, suffix string) bool {\n\tif len(b) < len(suffix) {\n\t\treturn false\n\t}\n\tb = b[len(b)-len(suffix):]\n\tfor i := range b {\n\t\tif b[i] != suffix[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// readUntilCloseAngle reads until the next \">\".\nfunc (z *Tokenizer) readUntilCloseAngle() {\n\tz.data.start = z.raw.end\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn\n\t\t}\n\t\tif c == '>' {\n\t\t\tz.data.end = z.raw.end - len(\">\")\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readMarkupDeclaration reads the next token starting with \"<!\". It might be\n// a \"<!--comment-->\", a \"<!DOCTYPE foo>\", a \"<![CDATA[section]]>\" or\n// \"<!a bogus comment\". The opening \"<!\" has already been consumed.\nfunc (z *Tokenizer) readMarkupDeclaration() TokenType {\n\tz.data.start = z.raw.end\n\tvar c [2]byte\n\tfor i := 0; i < 2; i++ {\n\t\tc[i] = z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn CommentToken\n\t\t}\n\t}\n\tif c[0] == '-' && c[1] == '-' {\n\t\tz.readComment()\n\t\treturn CommentToken\n\t}\n\tz.raw.end -= 2\n\tif z.readDoctype() {\n\t\treturn DoctypeToken\n\t}\n\tif z.allowCDATA && z.readCDATA() {\n\t\tz.convertNUL = true\n\t\treturn TextToken\n\t}\n\t// It's a bogus comment.\n\tz.readUntilCloseAngle()\n\treturn CommentToken\n}\n\n// readDoctype attempts to read a doctype declaration and returns true if\n// successful. The opening \"<!\" has already been consumed.\nfunc (z *Tokenizer) readDoctype() bool {\n\tconst s = \"DOCTYPE\"\n\tfor i := 0; i < len(s); i++ {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn false\n\t\t}\n\t\tif c != s[i] && c != s[i]+('a'-'A') {\n\t\t\t// Back up to read the fragment of \"DOCTYPE\" again.\n\t\t\tz.raw.end = z.data.start\n\t\t\treturn false\n\t\t}\n\t}\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\tz.data.start = z.raw.end\n\t\tz.data.end = z.raw.end\n\t\treturn true\n\t}\n\tz.readUntilCloseAngle()\n\treturn true\n}\n\n// readCDATA attempts to read a CDATA section and returns true if\n// successful. The opening \"<!\" has already been consumed.\nfunc (z *Tokenizer) readCDATA() bool {\n\tconst s = \"[CDATA[\"\n\tfor i := 0; i < len(s); i++ {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn false\n\t\t}\n\t\tif c != s[i] {\n\t\t\t// Back up to read the fragment of \"[CDATA[\" again.\n\t\t\tz.raw.end = z.data.start\n\t\t\treturn false\n\t\t}\n\t}\n\tz.data.start = z.raw.end\n\tbrackets := 0\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn true\n\t\t}\n\t\tswitch c {\n\t\tcase ']':\n\t\t\tbrackets++\n\t\tcase '>':\n\t\t\tif brackets >= 2 {\n\t\t\t\tz.data.end = z.raw.end - len(\"]]>\")\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tbrackets = 0\n\t\tdefault:\n\t\t\tbrackets = 0\n\t\t}\n\t}\n}\n\n// startTagIn returns whether the start tag in z.buf[z.data.start:z.data.end]\n// case-insensitively matches any element of ss.\nfunc (z *Tokenizer) startTagIn(ss ...string) bool {\nloop:\n\tfor _, s := range ss {\n\t\tif z.data.end-z.data.start != len(s) {\n\t\t\tcontinue loop\n\t\t}\n\t\tfor i := 0; i < len(s); i++ {\n\t\t\tc := z.buf[z.data.start+i]\n\t\t\tif 'A' <= c && c <= 'Z' {\n\t\t\t\tc += 'a' - 'A'\n\t\t\t}\n\t\t\tif c != s[i] {\n\t\t\t\tcontinue loop\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\n// readStartTag reads the next start tag token. The opening \"<a\" has already\n// been consumed, where 'a' means anything in [A-Za-z].\nfunc (z *Tokenizer) readStartTag() TokenType {\n\tz.readTag(true)\n\tif z.err != nil {\n\t\treturn ErrorToken\n\t}\n\t// Several tags flag the tokenizer's next token as raw.\n\tc, raw := z.buf[z.data.start], false\n\tif 'A' <= c && c <= 'Z' {\n\t\tc += 'a' - 'A'\n\t}\n\tswitch c {\n\tcase 'i':\n\t\traw = z.startTagIn(\"iframe\")\n\tcase 'n':\n\t\traw = z.startTagIn(\"noembed\", \"noframes\", \"noscript\")\n\tcase 'p':\n\t\traw = z.startTagIn(\"plaintext\")\n\tcase 's':\n\t\traw = z.startTagIn(\"script\", \"style\")\n\tcase 't':\n\t\traw = z.startTagIn(\"textarea\", \"title\")\n\tcase 'x':\n\t\traw = z.startTagIn(\"xmp\")\n\t}\n\tif raw {\n\t\tz.rawTag = strings.ToLower(string(z.buf[z.data.start:z.data.end]))\n\t}\n\t// Look for a self-closing token (e.g. <br/>).\n\t//\n\t// Originally, we did this by just checking that the last character of the\n\t// tag (ignoring the closing bracket) was a solidus (/) character, but this\n\t// is not always accurate.\n\t//\n\t// We need to be careful that we don't misinterpret a non-self-closing tag\n\t// as self-closing, as can happen if the tag contains unquoted attribute\n\t// values (i.e. <p a=/>).\n\t//\n\t// To avoid this, we check that the last non-bracket character of the tag\n\t// (z.raw.end-2) isn't the same character as the last non-quote character of\n\t// the last attribute of the tag (z.pendingAttr[1].end-1), if the tag has\n\t// attributes.\n\tnAttrs := len(z.attr)\n\tif z.err == nil && z.buf[z.raw.end-2] == '/' && (nAttrs == 0 || z.raw.end-2 != z.attr[nAttrs-1][1].end-1) {\n\t\treturn SelfClosingTagToken\n\t}\n\treturn StartTagToken\n}\n\n// readTag reads the next tag token and its attributes. If saveAttr, those\n// attributes are saved in z.attr, otherwise z.attr is set to an empty slice.\n// The opening \"<a\" or \"</a\" has already been consumed, where 'a' means anything\n// in [A-Za-z].\nfunc (z *Tokenizer) readTag(saveAttr bool) {\n\tz.attr = z.attr[:0]\n\tz.nAttrReturned = 0\n\t// Read the tag name and attribute key/value pairs.\n\tz.readTagName()\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\treturn\n\t}\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil || c == '>' {\n\t\t\tbreak\n\t\t}\n\t\tz.raw.end--\n\t\tz.readTagAttrKey()\n\t\tz.readTagAttrVal()\n\t\t// Save pendingAttr if saveAttr and that attribute has a non-empty key.\n\t\tif saveAttr && z.pendingAttr[0].start != z.pendingAttr[0].end {\n\t\t\tz.attr = append(z.attr, z.pendingAttr)\n\t\t}\n\t\tif z.skipWhiteSpace(); z.err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// readTagName sets z.data to the \"div\" in \"<div k=v>\". The reader (z.raw.end)\n// is positioned such that the first byte of the tag name (the \"d\" in \"<div\")\n// has already been consumed.\nfunc (z *Tokenizer) readTagName() {\n\tz.data.start = z.raw.end - 1\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase ' ', '\\n', '\\r', '\\t', '\\f':\n\t\t\tz.data.end = z.raw.end - 1\n\t\t\treturn\n\t\tcase '/', '>':\n\t\t\tz.raw.end--\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readTagAttrKey sets z.pendingAttr[0] to the \"k\" in \"<div k=v>\".\n// Precondition: z.err == nil.\nfunc (z *Tokenizer) readTagAttrKey() {\n\tz.pendingAttr[0].start = z.raw.end\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.pendingAttr[0].end = z.raw.end\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase '=':\n\t\t\tif z.pendingAttr[0].start+1 == z.raw.end {\n\t\t\t\t// WHATWG 13.2.5.32, if we see an equals sign before the attribute name\n\t\t\t\t// begins, we treat it as a character in the attribute name and continue.\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfallthrough\n\t\tcase ' ', '\\n', '\\r', '\\t', '\\f', '/', '>':\n\t\t\t// WHATWG 13.2.5.33 Attribute name state\n\t\t\t// We need to reconsume the char in the after attribute name state to support the / character\n\t\t\tz.raw.end--\n\t\t\tz.pendingAttr[0].end = z.raw.end\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readTagAttrVal sets z.pendingAttr[1] to the \"v\" in \"<div k=v>\".\nfunc (z *Tokenizer) readTagAttrVal() {\n\tz.pendingAttr[1].start = z.raw.end\n\tz.pendingAttr[1].end = z.raw.end\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\treturn\n\t}\n\tc := z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tif c == '/' {\n\t\t// WHATWG 13.2.5.34 After attribute name state\n\t\t// U+002F SOLIDUS (/) - Switch to the self-closing start tag state.\n\t\treturn\n\t}\n\tif c != '=' {\n\t\tz.raw.end--\n\t\treturn\n\t}\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\treturn\n\t}\n\tquote := z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch quote {\n\tcase '>':\n\t\tz.raw.end--\n\t\treturn\n\n\tcase '\\'', '\"':\n\t\tz.pendingAttr[1].start = z.raw.end\n\t\tfor {\n\t\t\tc := z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tz.pendingAttr[1].end = z.raw.end\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif c == quote {\n\t\t\t\tz.pendingAttr[1].end = z.raw.end - 1\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\tz.pendingAttr[1].start = z.raw.end - 1\n\t\tfor {\n\t\t\tc := z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tz.pendingAttr[1].end = z.raw.end\n\t\t\t\treturn\n\t\t\t}\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\n', '\\r', '\\t', '\\f':\n\t\t\t\tz.pendingAttr[1].end = z.raw.end - 1\n\t\t\t\treturn\n\t\t\tcase '>':\n\t\t\t\tz.raw.end--\n\t\t\t\tz.pendingAttr[1].end = z.raw.end\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Next scans the next token and returns its type.\nfunc (z *Tokenizer) Next() TokenType {\n\tz.raw.start = z.raw.end\n\tz.data.start = z.raw.end\n\tz.data.end = z.raw.end\n\tif z.err != nil {\n\t\tz.tt = ErrorToken\n\t\treturn z.tt\n\t}\n\tif z.rawTag != \"\" {\n\t\tif z.rawTag == \"plaintext\" {\n\t\t\t// Read everything up to EOF.\n\t\t\tfor z.err == nil {\n\t\t\t\tz.readByte()\n\t\t\t}\n\t\t\tz.data.end = z.raw.end\n\t\t\tz.textIsRaw = true\n\t\t} else {\n\t\t\tz.readRawOrRCDATA()\n\t\t}\n\t\tif z.data.end > z.data.start {\n\t\t\tz.tt = TextToken\n\t\t\tz.convertNUL = true\n\t\t\treturn z.tt\n\t\t}\n\t}\n\tz.textIsRaw = false\n\tz.convertNUL = false\n\nloop:\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tif c != '<' {\n\t\t\tcontinue loop\n\t\t}\n\n\t\t// Check if the '<' we have just read is part of a tag, comment\n\t\t// or doctype. If not, it's part of the accumulated text token.\n\t\tc = z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tvar tokenType TokenType\n\t\tswitch {\n\t\tcase 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':\n\t\t\ttokenType = StartTagToken\n\t\tcase c == '/':\n\t\t\ttokenType = EndTagToken\n\t\tcase c == '!' || c == '?':\n\t\t\t// We use CommentToken to mean any of \"<!--actual comments-->\",\n\t\t\t// \"<!DOCTYPE declarations>\" and \"<?xml processing instructions?>\".\n\t\t\ttokenType = CommentToken\n\t\tdefault:\n\t\t\t// Reconsume the current character.\n\t\t\tz.raw.end--\n\t\t\tcontinue\n\t\t}\n\n\t\t// We have a non-text token, but we might have accumulated some text\n\t\t// before that. If so, we return the text first, and return the non-\n\t\t// text token on the subsequent call to Next.\n\t\tif x := z.raw.end - len(\"<a\"); z.raw.start < x {\n\t\t\tz.raw.end = x\n\t\t\tz.data.end = x\n\t\t\tz.tt = TextToken\n\t\t\treturn z.tt\n\t\t}\n\t\tswitch tokenType {\n\t\tcase StartTagToken:\n\t\t\tz.tt = z.readStartTag()\n\t\t\treturn z.tt\n\t\tcase EndTagToken:\n\t\t\tc = z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif c == '>' {\n\t\t\t\t// \"</>\" does not generate a token at all. Generate an empty comment\n\t\t\t\t// to allow passthrough clients to pick up the data using Raw.\n\t\t\t\t// Reset the tokenizer state and start again.\n\t\t\t\tz.tt = CommentToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tif 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' {\n\t\t\t\tz.readTag(false)\n\t\t\t\tif z.err != nil {\n\t\t\t\t\tz.tt = ErrorToken\n\t\t\t\t} else {\n\t\t\t\t\tz.tt = EndTagToken\n\t\t\t\t}\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.raw.end--\n\t\t\tz.readUntilCloseAngle()\n\t\t\tz.tt = CommentToken\n\t\t\treturn z.tt\n\t\tcase CommentToken:\n\t\t\tif c == '!' {\n\t\t\t\tz.tt = z.readMarkupDeclaration()\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.raw.end--\n\t\t\tz.readUntilCloseAngle()\n\t\t\tz.tt = CommentToken\n\t\t\treturn z.tt\n\t\t}\n\t}\n\tif z.raw.start < z.raw.end {\n\t\tz.data.end = z.raw.end\n\t\tz.tt = TextToken\n\t\treturn z.tt\n\t}\n\tz.tt = ErrorToken\n\treturn z.tt\n}\n\n// Raw returns the unmodified text of the current token. Calling Next, Token,\n// Text, TagName or TagAttr may change the contents of the returned slice.\n//\n// The token stream's raw bytes partition the byte stream (up until an\n// ErrorToken). There are no overlaps or gaps between two consecutive token's\n// raw bytes. One implication is that the byte offset of the current token is\n// the sum of the lengths of all previous tokens' raw bytes.\nfunc (z *Tokenizer) Raw() []byte {\n\treturn z.buf[z.raw.start:z.raw.end]\n}\n\n// convertNewlines converts \"\\r\" and \"\\r\\n\" in s to \"\\n\".\n// The conversion happens in place, but the resulting slice may be shorter.\nfunc convertNewlines(s []byte) []byte {\n\tfor i, c := range s {\n\t\tif c != '\\r' {\n\t\t\tcontinue\n\t\t}\n\n\t\tsrc := i + 1\n\t\tif src >= len(s) || s[src] != '\\n' {\n\t\t\ts[i] = '\\n'\n\t\t\tcontinue\n\t\t}\n\n\t\tdst := i\n\t\tfor src < len(s) {\n\t\t\tif s[src] == '\\r' {\n\t\t\t\tif src+1 < len(s) && s[src+1] == '\\n' {\n\t\t\t\t\tsrc++\n\t\t\t\t}\n\t\t\t\ts[dst] = '\\n'\n\t\t\t} else {\n\t\t\t\ts[dst] = s[src]\n\t\t\t}\n\t\t\tsrc++\n\t\t\tdst++\n\t\t}\n\t\treturn s[:dst]\n\t}\n\treturn s\n}\n\nvar (\n\tnul         = []byte(\"\\x00\")\n\treplacement = []byte(\"\\ufffd\")\n)\n\n// Text returns the unescaped text of a text, comment or doctype token. The\n// contents of the returned slice may change on the next call to Next.\nfunc (z *Tokenizer) Text() []byte {\n\tswitch z.tt {\n\tcase TextToken, CommentToken, DoctypeToken:\n\t\ts := z.buf[z.data.start:z.data.end]\n\t\tz.data.start = z.raw.end\n\t\tz.data.end = z.raw.end\n\t\ts = convertNewlines(s)\n\t\tif (z.convertNUL || z.tt == CommentToken) && bytes.Contains(s, nul) {\n\t\t\ts = bytes.Replace(s, nul, replacement, -1)\n\t\t}\n\t\tif !z.textIsRaw {\n\t\t\ts = unescape(s, false)\n\t\t}\n\t\treturn s\n\t}\n\treturn nil\n}\n\n// TagName returns the lower-cased name of a tag token (the `img` out of\n// `<IMG SRC=\"foo\">`) and whether the tag has attributes.\n// The contents of the returned slice may change on the next call to Next.\nfunc (z *Tokenizer) TagName() (name []byte, hasAttr bool) {\n\tif z.data.start < z.data.end {\n\t\tswitch z.tt {\n\t\tcase StartTagToken, EndTagToken, SelfClosingTagToken:\n\t\t\ts := z.buf[z.data.start:z.data.end]\n\t\t\tz.data.start = z.raw.end\n\t\t\tz.data.end = z.raw.end\n\t\t\treturn lower(s), z.nAttrReturned < len(z.attr)\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// TagAttr returns the lower-cased key and unescaped value of the next unparsed\n// attribute for the current tag token and whether there are more attributes.\n// The contents of the returned slices may change on the next call to Next.\nfunc (z *Tokenizer) TagAttr() (key, val []byte, moreAttr bool) {\n\tif z.nAttrReturned < len(z.attr) {\n\t\tswitch z.tt {\n\t\tcase StartTagToken, SelfClosingTagToken:\n\t\t\tx := z.attr[z.nAttrReturned]\n\t\t\tz.nAttrReturned++\n\t\t\tkey = z.buf[x[0].start:x[0].end]\n\t\t\tval = z.buf[x[1].start:x[1].end]\n\t\t\treturn lower(key), unescape(convertNewlines(val), true), z.nAttrReturned < len(z.attr)\n\t\t}\n\t}\n\treturn nil, nil, false\n}\n\n// Token returns the current Token. The result's Data and Attr values remain\n// valid after subsequent Next calls.\nfunc (z *Tokenizer) Token() Token {\n\tt := Token{Type: z.tt}\n\tswitch z.tt {\n\tcase TextToken, CommentToken, DoctypeToken:\n\t\tt.Data = string(z.Text())\n\tcase StartTagToken, SelfClosingTagToken, EndTagToken:\n\t\tname, moreAttr := z.TagName()\n\t\tfor moreAttr {\n\t\t\tvar key, val []byte\n\t\t\tkey, val, moreAttr = z.TagAttr()\n\t\t\tt.Attr = append(t.Attr, Attribute{\"\", atom.String(key), string(val)})\n\t\t}\n\t\tif a := atom.Lookup(name); a != 0 {\n\t\t\tt.DataAtom, t.Data = a, a.String()\n\t\t} else {\n\t\t\tt.DataAtom, t.Data = 0, string(name)\n\t\t}\n\t}\n\treturn t\n}\n\n// SetMaxBuf sets a limit on the amount of data buffered during tokenization.\n// A value of 0 means unlimited.\nfunc (z *Tokenizer) SetMaxBuf(n int) {\n\tz.maxBuf = n\n}\n\n// NewTokenizer returns a new HTML Tokenizer for the given Reader.\n// The input is assumed to be UTF-8 encoded.\nfunc NewTokenizer(r io.Reader) *Tokenizer {\n\treturn NewTokenizerFragment(r, \"\")\n}\n\n// NewTokenizerFragment returns a new HTML Tokenizer for the given Reader, for\n// tokenizing an existing element's InnerHTML fragment. contextTag is that\n// element's tag, such as \"div\" or \"iframe\".\n//\n// For example, how the InnerHTML \"a<b\" is tokenized depends on whether it is\n// for a <p> tag or a <script> tag.\n//\n// The input is assumed to be UTF-8 encoded.\nfunc NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer {\n\tz := &Tokenizer{\n\t\tr:   r,\n\t\tbuf: make([]byte, 0, 4096),\n\t}\n\tif contextTag != \"\" {\n\t\tswitch s := strings.ToLower(contextTag); s {\n\t\tcase \"iframe\", \"noembed\", \"noframes\", \"noscript\", \"plaintext\", \"script\", \"style\", \"title\", \"textarea\", \"xmp\":\n\t\t\tz.rawTag = s\n\t\t}\n\t}\n\treturn z\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http/httpguts/guts.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// Package httpguts provides functions implementing various details\n// of the HTTP specification.\n//\n// This package is shared by the standard library (which vendors it)\n// and x/net/http2. It comes with no API stability promise.\npackage httpguts\n\nimport (\n\t\"net/textproto\"\n\t\"strings\"\n)\n\n// ValidTrailerHeader reports whether name is a valid header field name to appear\n// in trailers.\n// See RFC 7230, Section 4.1.2\nfunc ValidTrailerHeader(name string) bool {\n\tname = textproto.CanonicalMIMEHeaderKey(name)\n\tif strings.HasPrefix(name, \"If-\") || badTrailer[name] {\n\t\treturn false\n\t}\n\treturn true\n}\n\nvar badTrailer = map[string]bool{\n\t\"Authorization\":       true,\n\t\"Cache-Control\":       true,\n\t\"Connection\":          true,\n\t\"Content-Encoding\":    true,\n\t\"Content-Length\":      true,\n\t\"Content-Range\":       true,\n\t\"Content-Type\":        true,\n\t\"Expect\":              true,\n\t\"Host\":                true,\n\t\"Keep-Alive\":          true,\n\t\"Max-Forwards\":        true,\n\t\"Pragma\":              true,\n\t\"Proxy-Authenticate\":  true,\n\t\"Proxy-Authorization\": true,\n\t\"Proxy-Connection\":    true,\n\t\"Range\":               true,\n\t\"Realm\":               true,\n\t\"Te\":                  true,\n\t\"Trailer\":             true,\n\t\"Transfer-Encoding\":   true,\n\t\"Www-Authenticate\":    true,\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http/httpguts/httplex.go",
    "content": "// Copyright 2016 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 httpguts\n\nimport (\n\t\"net\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"golang.org/x/net/idna\"\n)\n\nvar isTokenTable = [256]bool{\n\t'!':  true,\n\t'#':  true,\n\t'$':  true,\n\t'%':  true,\n\t'&':  true,\n\t'\\'': true,\n\t'*':  true,\n\t'+':  true,\n\t'-':  true,\n\t'.':  true,\n\t'0':  true,\n\t'1':  true,\n\t'2':  true,\n\t'3':  true,\n\t'4':  true,\n\t'5':  true,\n\t'6':  true,\n\t'7':  true,\n\t'8':  true,\n\t'9':  true,\n\t'A':  true,\n\t'B':  true,\n\t'C':  true,\n\t'D':  true,\n\t'E':  true,\n\t'F':  true,\n\t'G':  true,\n\t'H':  true,\n\t'I':  true,\n\t'J':  true,\n\t'K':  true,\n\t'L':  true,\n\t'M':  true,\n\t'N':  true,\n\t'O':  true,\n\t'P':  true,\n\t'Q':  true,\n\t'R':  true,\n\t'S':  true,\n\t'T':  true,\n\t'U':  true,\n\t'W':  true,\n\t'V':  true,\n\t'X':  true,\n\t'Y':  true,\n\t'Z':  true,\n\t'^':  true,\n\t'_':  true,\n\t'`':  true,\n\t'a':  true,\n\t'b':  true,\n\t'c':  true,\n\t'd':  true,\n\t'e':  true,\n\t'f':  true,\n\t'g':  true,\n\t'h':  true,\n\t'i':  true,\n\t'j':  true,\n\t'k':  true,\n\t'l':  true,\n\t'm':  true,\n\t'n':  true,\n\t'o':  true,\n\t'p':  true,\n\t'q':  true,\n\t'r':  true,\n\t's':  true,\n\t't':  true,\n\t'u':  true,\n\t'v':  true,\n\t'w':  true,\n\t'x':  true,\n\t'y':  true,\n\t'z':  true,\n\t'|':  true,\n\t'~':  true,\n}\n\nfunc IsTokenRune(r rune) bool {\n\treturn r < utf8.RuneSelf && isTokenTable[byte(r)]\n}\n\n// HeaderValuesContainsToken reports whether any string in values\n// contains the provided token, ASCII case-insensitively.\nfunc HeaderValuesContainsToken(values []string, token string) bool {\n\tfor _, v := range values {\n\t\tif headerValueContainsToken(v, token) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// isOWS reports whether b is an optional whitespace byte, as defined\n// by RFC 7230 section 3.2.3.\nfunc isOWS(b byte) bool { return b == ' ' || b == '\\t' }\n\n// trimOWS returns x with all optional whitespace removes from the\n// beginning and end.\nfunc trimOWS(x string) string {\n\t// TODO: consider using strings.Trim(x, \" \\t\") instead,\n\t// if and when it's fast enough. See issue 10292.\n\t// But this ASCII-only code will probably always beat UTF-8\n\t// aware code.\n\tfor len(x) > 0 && isOWS(x[0]) {\n\t\tx = x[1:]\n\t}\n\tfor len(x) > 0 && isOWS(x[len(x)-1]) {\n\t\tx = x[:len(x)-1]\n\t}\n\treturn x\n}\n\n// headerValueContainsToken reports whether v (assumed to be a\n// 0#element, in the ABNF extension described in RFC 7230 section 7)\n// contains token amongst its comma-separated tokens, ASCII\n// case-insensitively.\nfunc headerValueContainsToken(v string, token string) bool {\n\tfor comma := strings.IndexByte(v, ','); comma != -1; comma = strings.IndexByte(v, ',') {\n\t\tif tokenEqual(trimOWS(v[:comma]), token) {\n\t\t\treturn true\n\t\t}\n\t\tv = v[comma+1:]\n\t}\n\treturn tokenEqual(trimOWS(v), token)\n}\n\n// lowerASCII returns the ASCII lowercase version of b.\nfunc lowerASCII(b byte) byte {\n\tif 'A' <= b && b <= 'Z' {\n\t\treturn b + ('a' - 'A')\n\t}\n\treturn b\n}\n\n// tokenEqual reports whether t1 and t2 are equal, ASCII case-insensitively.\nfunc tokenEqual(t1, t2 string) bool {\n\tif len(t1) != len(t2) {\n\t\treturn false\n\t}\n\tfor i, b := range t1 {\n\t\tif b >= utf8.RuneSelf {\n\t\t\t// No UTF-8 or non-ASCII allowed in tokens.\n\t\t\treturn false\n\t\t}\n\t\tif lowerASCII(byte(b)) != lowerASCII(t2[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// isLWS reports whether b is linear white space, according\n// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2\n//\n//\tLWS            = [CRLF] 1*( SP | HT )\nfunc isLWS(b byte) bool { return b == ' ' || b == '\\t' }\n\n// isCTL reports whether b is a control byte, according\n// to http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2\n//\n//\tCTL            = <any US-ASCII control character\n//\t                 (octets 0 - 31) and DEL (127)>\nfunc isCTL(b byte) bool {\n\tconst del = 0x7f // a CTL\n\treturn b < ' ' || b == del\n}\n\n// ValidHeaderFieldName reports whether v is a valid HTTP/1.x header name.\n// HTTP/2 imposes the additional restriction that uppercase ASCII\n// letters are not allowed.\n//\n// RFC 7230 says:\n//\n//\theader-field   = field-name \":\" OWS field-value OWS\n//\tfield-name     = token\n//\ttoken          = 1*tchar\n//\ttchar = \"!\" / \"#\" / \"$\" / \"%\" / \"&\" / \"'\" / \"*\" / \"+\" / \"-\" / \".\" /\n//\t        \"^\" / \"_\" / \"`\" / \"|\" / \"~\" / DIGIT / ALPHA\nfunc ValidHeaderFieldName(v string) bool {\n\tif len(v) == 0 {\n\t\treturn false\n\t}\n\tfor i := 0; i < len(v); i++ {\n\t\tif !isTokenTable[v[i]] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// ValidHostHeader reports whether h is a valid host header.\nfunc ValidHostHeader(h string) bool {\n\t// The latest spec is actually this:\n\t//\n\t// http://tools.ietf.org/html/rfc7230#section-5.4\n\t//     Host = uri-host [ \":\" port ]\n\t//\n\t// Where uri-host is:\n\t//     http://tools.ietf.org/html/rfc3986#section-3.2.2\n\t//\n\t// But we're going to be much more lenient for now and just\n\t// search for any byte that's not a valid byte in any of those\n\t// expressions.\n\tfor i := 0; i < len(h); i++ {\n\t\tif !validHostByte[h[i]] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// See the validHostHeader comment.\nvar validHostByte = [256]bool{\n\t'0': true, '1': true, '2': true, '3': true, '4': true, '5': true, '6': true, '7': true,\n\t'8': true, '9': true,\n\n\t'a': true, 'b': true, 'c': true, 'd': true, 'e': true, 'f': true, 'g': true, 'h': true,\n\t'i': true, 'j': true, 'k': true, 'l': true, 'm': true, 'n': true, 'o': true, 'p': true,\n\t'q': true, 'r': true, 's': true, 't': true, 'u': true, 'v': true, 'w': true, 'x': true,\n\t'y': true, 'z': true,\n\n\t'A': true, 'B': true, 'C': true, 'D': true, 'E': true, 'F': true, 'G': true, 'H': true,\n\t'I': true, 'J': true, 'K': true, 'L': true, 'M': true, 'N': true, 'O': true, 'P': true,\n\t'Q': true, 'R': true, 'S': true, 'T': true, 'U': true, 'V': true, 'W': true, 'X': true,\n\t'Y': true, 'Z': true,\n\n\t'!':  true, // sub-delims\n\t'$':  true, // sub-delims\n\t'%':  true, // pct-encoded (and used in IPv6 zones)\n\t'&':  true, // sub-delims\n\t'(':  true, // sub-delims\n\t')':  true, // sub-delims\n\t'*':  true, // sub-delims\n\t'+':  true, // sub-delims\n\t',':  true, // sub-delims\n\t'-':  true, // unreserved\n\t'.':  true, // unreserved\n\t':':  true, // IPv6address + Host expression's optional port\n\t';':  true, // sub-delims\n\t'=':  true, // sub-delims\n\t'[':  true,\n\t'\\'': true, // sub-delims\n\t']':  true,\n\t'_':  true, // unreserved\n\t'~':  true, // unreserved\n}\n\n// ValidHeaderFieldValue reports whether v is a valid \"field-value\" according to\n// http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 :\n//\n//\tmessage-header = field-name \":\" [ field-value ]\n//\tfield-value    = *( field-content | LWS )\n//\tfield-content  = <the OCTETs making up the field-value\n//\t                 and consisting of either *TEXT or combinations\n//\t                 of token, separators, and quoted-string>\n//\n// http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 :\n//\n//\tTEXT           = <any OCTET except CTLs,\n//\t                  but including LWS>\n//\tLWS            = [CRLF] 1*( SP | HT )\n//\tCTL            = <any US-ASCII control character\n//\t                 (octets 0 - 31) and DEL (127)>\n//\n// RFC 7230 says:\n//\n//\tfield-value    = *( field-content / obs-fold )\n//\tobj-fold       =  N/A to http2, and deprecated\n//\tfield-content  = field-vchar [ 1*( SP / HTAB ) field-vchar ]\n//\tfield-vchar    = VCHAR / obs-text\n//\tobs-text       = %x80-FF\n//\tVCHAR          = \"any visible [USASCII] character\"\n//\n// http2 further says: \"Similarly, HTTP/2 allows header field values\n// that are not valid. While most of the values that can be encoded\n// will not alter header field parsing, carriage return (CR, ASCII\n// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII\n// 0x0) might be exploited by an attacker if they are translated\n// verbatim. Any request or response that contains a character not\n// permitted in a header field value MUST be treated as malformed\n// (Section 8.1.2.6). Valid characters are defined by the\n// field-content ABNF rule in Section 3.2 of [RFC7230].\"\n//\n// This function does not (yet?) properly handle the rejection of\n// strings that begin or end with SP or HTAB.\nfunc ValidHeaderFieldValue(v string) bool {\n\tfor i := 0; i < len(v); i++ {\n\t\tb := v[i]\n\t\tif isCTL(b) && !isLWS(b) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc isASCII(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] >= utf8.RuneSelf {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// PunycodeHostPort returns the IDNA Punycode version\n// of the provided \"host\" or \"host:port\" string.\nfunc PunycodeHostPort(v string) (string, error) {\n\tif isASCII(v) {\n\t\treturn v, nil\n\t}\n\n\thost, port, err := net.SplitHostPort(v)\n\tif err != nil {\n\t\t// The input 'v' argument was just a \"host\" argument,\n\t\t// without a port. This error should not be returned\n\t\t// to the caller.\n\t\thost = v\n\t\tport = \"\"\n\t}\n\thost, err = idna.ToASCII(host)\n\tif err != nil {\n\t\t// Non-UTF-8? Not representable in Punycode, in any\n\t\t// case.\n\t\treturn \"\", err\n\t}\n\tif port == \"\" {\n\t\treturn host, nil\n\t}\n\treturn net.JoinHostPort(host, port), nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/.gitignore",
    "content": "*~\nh2i/h2i\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/ascii.go",
    "content": "// Copyright 2021 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 http2\n\nimport \"strings\"\n\n// The HTTP protocols are defined in terms of ASCII, not Unicode. This file\n// contains helper functions which may use Unicode-aware functions which would\n// otherwise be unsafe and could introduce vulnerabilities if used improperly.\n\n// asciiEqualFold is strings.EqualFold, ASCII only. It reports whether s and t\n// are equal, ASCII-case-insensitively.\nfunc asciiEqualFold(s, t string) bool {\n\tif len(s) != len(t) {\n\t\treturn false\n\t}\n\tfor i := 0; i < len(s); i++ {\n\t\tif lower(s[i]) != lower(t[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// lower returns the ASCII lowercase version of b.\nfunc lower(b byte) byte {\n\tif 'A' <= b && b <= 'Z' {\n\t\treturn b + ('a' - 'A')\n\t}\n\treturn b\n}\n\n// isASCIIPrint returns whether s is ASCII and printable according to\n// https://tools.ietf.org/html/rfc20#section-4.2.\nfunc isASCIIPrint(s string) bool {\n\tfor i := 0; i < len(s); i++ {\n\t\tif s[i] < ' ' || s[i] > '~' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\n// asciiToLower returns the lowercase version of s if s is ASCII and printable,\n// and whether or not it was.\nfunc asciiToLower(s string) (lower string, ok bool) {\n\tif !isASCIIPrint(s) {\n\t\treturn \"\", false\n\t}\n\treturn strings.ToLower(s), true\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/ciphers.go",
    "content": "// Copyright 2017 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 http2\n\n// A list of the possible cipher suite ids. Taken from\n// https://www.iana.org/assignments/tls-parameters/tls-parameters.txt\n\nconst (\n\tcipher_TLS_NULL_WITH_NULL_NULL               uint16 = 0x0000\n\tcipher_TLS_RSA_WITH_NULL_MD5                 uint16 = 0x0001\n\tcipher_TLS_RSA_WITH_NULL_SHA                 uint16 = 0x0002\n\tcipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5        uint16 = 0x0003\n\tcipher_TLS_RSA_WITH_RC4_128_MD5              uint16 = 0x0004\n\tcipher_TLS_RSA_WITH_RC4_128_SHA              uint16 = 0x0005\n\tcipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5    uint16 = 0x0006\n\tcipher_TLS_RSA_WITH_IDEA_CBC_SHA             uint16 = 0x0007\n\tcipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA     uint16 = 0x0008\n\tcipher_TLS_RSA_WITH_DES_CBC_SHA              uint16 = 0x0009\n\tcipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA         uint16 = 0x000A\n\tcipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA  uint16 = 0x000B\n\tcipher_TLS_DH_DSS_WITH_DES_CBC_SHA           uint16 = 0x000C\n\tcipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA      uint16 = 0x000D\n\tcipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA  uint16 = 0x000E\n\tcipher_TLS_DH_RSA_WITH_DES_CBC_SHA           uint16 = 0x000F\n\tcipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA      uint16 = 0x0010\n\tcipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0011\n\tcipher_TLS_DHE_DSS_WITH_DES_CBC_SHA          uint16 = 0x0012\n\tcipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA     uint16 = 0x0013\n\tcipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0014\n\tcipher_TLS_DHE_RSA_WITH_DES_CBC_SHA          uint16 = 0x0015\n\tcipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA     uint16 = 0x0016\n\tcipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5    uint16 = 0x0017\n\tcipher_TLS_DH_anon_WITH_RC4_128_MD5          uint16 = 0x0018\n\tcipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA uint16 = 0x0019\n\tcipher_TLS_DH_anon_WITH_DES_CBC_SHA          uint16 = 0x001A\n\tcipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA     uint16 = 0x001B\n\t// Reserved uint16 =  0x001C-1D\n\tcipher_TLS_KRB5_WITH_DES_CBC_SHA             uint16 = 0x001E\n\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA        uint16 = 0x001F\n\tcipher_TLS_KRB5_WITH_RC4_128_SHA             uint16 = 0x0020\n\tcipher_TLS_KRB5_WITH_IDEA_CBC_SHA            uint16 = 0x0021\n\tcipher_TLS_KRB5_WITH_DES_CBC_MD5             uint16 = 0x0022\n\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5        uint16 = 0x0023\n\tcipher_TLS_KRB5_WITH_RC4_128_MD5             uint16 = 0x0024\n\tcipher_TLS_KRB5_WITH_IDEA_CBC_MD5            uint16 = 0x0025\n\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA   uint16 = 0x0026\n\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA   uint16 = 0x0027\n\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA       uint16 = 0x0028\n\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5   uint16 = 0x0029\n\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5   uint16 = 0x002A\n\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5       uint16 = 0x002B\n\tcipher_TLS_PSK_WITH_NULL_SHA                 uint16 = 0x002C\n\tcipher_TLS_DHE_PSK_WITH_NULL_SHA             uint16 = 0x002D\n\tcipher_TLS_RSA_PSK_WITH_NULL_SHA             uint16 = 0x002E\n\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA          uint16 = 0x002F\n\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA       uint16 = 0x0030\n\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA       uint16 = 0x0031\n\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA      uint16 = 0x0032\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA      uint16 = 0x0033\n\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA      uint16 = 0x0034\n\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA          uint16 = 0x0035\n\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA       uint16 = 0x0036\n\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA       uint16 = 0x0037\n\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA      uint16 = 0x0038\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA      uint16 = 0x0039\n\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA      uint16 = 0x003A\n\tcipher_TLS_RSA_WITH_NULL_SHA256              uint16 = 0x003B\n\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA256       uint16 = 0x003C\n\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA256       uint16 = 0x003D\n\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256    uint16 = 0x003E\n\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256    uint16 = 0x003F\n\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256   uint16 = 0x0040\n\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA     uint16 = 0x0041\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA  uint16 = 0x0042\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA  uint16 = 0x0043\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0044\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0045\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA uint16 = 0x0046\n\t// Reserved uint16 =  0x0047-4F\n\t// Reserved uint16 =  0x0050-58\n\t// Reserved uint16 =  0x0059-5C\n\t// Unassigned uint16 =  0x005D-5F\n\t// Reserved uint16 =  0x0060-66\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x0067\n\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256  uint16 = 0x0068\n\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256  uint16 = 0x0069\n\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 uint16 = 0x006A\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 uint16 = 0x006B\n\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256 uint16 = 0x006C\n\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256 uint16 = 0x006D\n\t// Unassigned uint16 =  0x006E-83\n\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA        uint16 = 0x0084\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA     uint16 = 0x0085\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA     uint16 = 0x0086\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA    uint16 = 0x0087\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA    uint16 = 0x0088\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA    uint16 = 0x0089\n\tcipher_TLS_PSK_WITH_RC4_128_SHA                 uint16 = 0x008A\n\tcipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA            uint16 = 0x008B\n\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA             uint16 = 0x008C\n\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA             uint16 = 0x008D\n\tcipher_TLS_DHE_PSK_WITH_RC4_128_SHA             uint16 = 0x008E\n\tcipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA        uint16 = 0x008F\n\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA         uint16 = 0x0090\n\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA         uint16 = 0x0091\n\tcipher_TLS_RSA_PSK_WITH_RC4_128_SHA             uint16 = 0x0092\n\tcipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA        uint16 = 0x0093\n\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA         uint16 = 0x0094\n\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA         uint16 = 0x0095\n\tcipher_TLS_RSA_WITH_SEED_CBC_SHA                uint16 = 0x0096\n\tcipher_TLS_DH_DSS_WITH_SEED_CBC_SHA             uint16 = 0x0097\n\tcipher_TLS_DH_RSA_WITH_SEED_CBC_SHA             uint16 = 0x0098\n\tcipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA            uint16 = 0x0099\n\tcipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA            uint16 = 0x009A\n\tcipher_TLS_DH_anon_WITH_SEED_CBC_SHA            uint16 = 0x009B\n\tcipher_TLS_RSA_WITH_AES_128_GCM_SHA256          uint16 = 0x009C\n\tcipher_TLS_RSA_WITH_AES_256_GCM_SHA384          uint16 = 0x009D\n\tcipher_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256      uint16 = 0x009E\n\tcipher_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384      uint16 = 0x009F\n\tcipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256       uint16 = 0x00A0\n\tcipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384       uint16 = 0x00A1\n\tcipher_TLS_DHE_DSS_WITH_AES_128_GCM_SHA256      uint16 = 0x00A2\n\tcipher_TLS_DHE_DSS_WITH_AES_256_GCM_SHA384      uint16 = 0x00A3\n\tcipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256       uint16 = 0x00A4\n\tcipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384       uint16 = 0x00A5\n\tcipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256      uint16 = 0x00A6\n\tcipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384      uint16 = 0x00A7\n\tcipher_TLS_PSK_WITH_AES_128_GCM_SHA256          uint16 = 0x00A8\n\tcipher_TLS_PSK_WITH_AES_256_GCM_SHA384          uint16 = 0x00A9\n\tcipher_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256      uint16 = 0x00AA\n\tcipher_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384      uint16 = 0x00AB\n\tcipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256      uint16 = 0x00AC\n\tcipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384      uint16 = 0x00AD\n\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA256          uint16 = 0x00AE\n\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA384          uint16 = 0x00AF\n\tcipher_TLS_PSK_WITH_NULL_SHA256                 uint16 = 0x00B0\n\tcipher_TLS_PSK_WITH_NULL_SHA384                 uint16 = 0x00B1\n\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256      uint16 = 0x00B2\n\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384      uint16 = 0x00B3\n\tcipher_TLS_DHE_PSK_WITH_NULL_SHA256             uint16 = 0x00B4\n\tcipher_TLS_DHE_PSK_WITH_NULL_SHA384             uint16 = 0x00B5\n\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256      uint16 = 0x00B6\n\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384      uint16 = 0x00B7\n\tcipher_TLS_RSA_PSK_WITH_NULL_SHA256             uint16 = 0x00B8\n\tcipher_TLS_RSA_PSK_WITH_NULL_SHA384             uint16 = 0x00B9\n\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256     uint16 = 0x00BA\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256  uint16 = 0x00BB\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256  uint16 = 0x00BC\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BD\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BE\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0x00BF\n\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256     uint16 = 0x00C0\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256  uint16 = 0x00C1\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256  uint16 = 0x00C2\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C3\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C4\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 uint16 = 0x00C5\n\t// Unassigned uint16 =  0x00C6-FE\n\tcipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV uint16 = 0x00FF\n\t// Unassigned uint16 =  0x01-55,*\n\tcipher_TLS_FALLBACK_SCSV uint16 = 0x5600\n\t// Unassigned                                   uint16 = 0x5601 - 0xC000\n\tcipher_TLS_ECDH_ECDSA_WITH_NULL_SHA                 uint16 = 0xC001\n\tcipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA              uint16 = 0xC002\n\tcipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA         uint16 = 0xC003\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA          uint16 = 0xC004\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA          uint16 = 0xC005\n\tcipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA                uint16 = 0xC006\n\tcipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA             uint16 = 0xC007\n\tcipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA        uint16 = 0xC008\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA         uint16 = 0xC009\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA         uint16 = 0xC00A\n\tcipher_TLS_ECDH_RSA_WITH_NULL_SHA                   uint16 = 0xC00B\n\tcipher_TLS_ECDH_RSA_WITH_RC4_128_SHA                uint16 = 0xC00C\n\tcipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0xC00D\n\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA            uint16 = 0xC00E\n\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA            uint16 = 0xC00F\n\tcipher_TLS_ECDHE_RSA_WITH_NULL_SHA                  uint16 = 0xC010\n\tcipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA               uint16 = 0xC011\n\tcipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA          uint16 = 0xC012\n\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA           uint16 = 0xC013\n\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA           uint16 = 0xC014\n\tcipher_TLS_ECDH_anon_WITH_NULL_SHA                  uint16 = 0xC015\n\tcipher_TLS_ECDH_anon_WITH_RC4_128_SHA               uint16 = 0xC016\n\tcipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA          uint16 = 0xC017\n\tcipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA           uint16 = 0xC018\n\tcipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA           uint16 = 0xC019\n\tcipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA            uint16 = 0xC01A\n\tcipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA        uint16 = 0xC01B\n\tcipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA        uint16 = 0xC01C\n\tcipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA             uint16 = 0xC01D\n\tcipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA         uint16 = 0xC01E\n\tcipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA         uint16 = 0xC01F\n\tcipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA             uint16 = 0xC020\n\tcipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA         uint16 = 0xC021\n\tcipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA         uint16 = 0xC022\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256      uint16 = 0xC023\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384      uint16 = 0xC024\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256       uint16 = 0xC025\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384       uint16 = 0xC026\n\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256        uint16 = 0xC027\n\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384        uint16 = 0xC028\n\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256         uint16 = 0xC029\n\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384         uint16 = 0xC02A\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256      uint16 = 0xC02B\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384      uint16 = 0xC02C\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256       uint16 = 0xC02D\n\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384       uint16 = 0xC02E\n\tcipher_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256        uint16 = 0xC02F\n\tcipher_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384        uint16 = 0xC030\n\tcipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256         uint16 = 0xC031\n\tcipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384         uint16 = 0xC032\n\tcipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA               uint16 = 0xC033\n\tcipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA          uint16 = 0xC034\n\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA           uint16 = 0xC035\n\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA           uint16 = 0xC036\n\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256        uint16 = 0xC037\n\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384        uint16 = 0xC038\n\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA                  uint16 = 0xC039\n\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA256               uint16 = 0xC03A\n\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA384               uint16 = 0xC03B\n\tcipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256             uint16 = 0xC03C\n\tcipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384             uint16 = 0xC03D\n\tcipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256          uint16 = 0xC03E\n\tcipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384          uint16 = 0xC03F\n\tcipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256          uint16 = 0xC040\n\tcipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384          uint16 = 0xC041\n\tcipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC042\n\tcipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC043\n\tcipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC044\n\tcipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC045\n\tcipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC046\n\tcipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC047\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256     uint16 = 0xC048\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384     uint16 = 0xC049\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256      uint16 = 0xC04A\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384      uint16 = 0xC04B\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256       uint16 = 0xC04C\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384       uint16 = 0xC04D\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256        uint16 = 0xC04E\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384        uint16 = 0xC04F\n\tcipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256             uint16 = 0xC050\n\tcipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384             uint16 = 0xC051\n\tcipher_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC052\n\tcipher_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC053\n\tcipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256          uint16 = 0xC054\n\tcipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384          uint16 = 0xC055\n\tcipher_TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC056\n\tcipher_TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC057\n\tcipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256          uint16 = 0xC058\n\tcipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384          uint16 = 0xC059\n\tcipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC05A\n\tcipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC05B\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256     uint16 = 0xC05C\n\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384     uint16 = 0xC05D\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256      uint16 = 0xC05E\n\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384      uint16 = 0xC05F\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256       uint16 = 0xC060\n\tcipher_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384       uint16 = 0xC061\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256        uint16 = 0xC062\n\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384        uint16 = 0xC063\n\tcipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256             uint16 = 0xC064\n\tcipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384             uint16 = 0xC065\n\tcipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC066\n\tcipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC067\n\tcipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256         uint16 = 0xC068\n\tcipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384         uint16 = 0xC069\n\tcipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256             uint16 = 0xC06A\n\tcipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384             uint16 = 0xC06B\n\tcipher_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC06C\n\tcipher_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC06D\n\tcipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256         uint16 = 0xC06E\n\tcipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384         uint16 = 0xC06F\n\tcipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256       uint16 = 0xC070\n\tcipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384       uint16 = 0xC071\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 uint16 = 0xC072\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 uint16 = 0xC073\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256  uint16 = 0xC074\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384  uint16 = 0xC075\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256   uint16 = 0xC076\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384   uint16 = 0xC077\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256    uint16 = 0xC078\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384    uint16 = 0xC079\n\tcipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256         uint16 = 0xC07A\n\tcipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384         uint16 = 0xC07B\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC07C\n\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC07D\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256      uint16 = 0xC07E\n\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384      uint16 = 0xC07F\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC080\n\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC081\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256      uint16 = 0xC082\n\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384      uint16 = 0xC083\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC084\n\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC085\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 uint16 = 0xC086\n\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 uint16 = 0xC087\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256  uint16 = 0xC088\n\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384  uint16 = 0xC089\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256   uint16 = 0xC08A\n\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384   uint16 = 0xC08B\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256    uint16 = 0xC08C\n\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384    uint16 = 0xC08D\n\tcipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256         uint16 = 0xC08E\n\tcipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384         uint16 = 0xC08F\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC090\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC091\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256     uint16 = 0xC092\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384     uint16 = 0xC093\n\tcipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256         uint16 = 0xC094\n\tcipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384         uint16 = 0xC095\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256     uint16 = 0xC096\n\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384     uint16 = 0xC097\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256     uint16 = 0xC098\n\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384     uint16 = 0xC099\n\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256   uint16 = 0xC09A\n\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384   uint16 = 0xC09B\n\tcipher_TLS_RSA_WITH_AES_128_CCM                     uint16 = 0xC09C\n\tcipher_TLS_RSA_WITH_AES_256_CCM                     uint16 = 0xC09D\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CCM                 uint16 = 0xC09E\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CCM                 uint16 = 0xC09F\n\tcipher_TLS_RSA_WITH_AES_128_CCM_8                   uint16 = 0xC0A0\n\tcipher_TLS_RSA_WITH_AES_256_CCM_8                   uint16 = 0xC0A1\n\tcipher_TLS_DHE_RSA_WITH_AES_128_CCM_8               uint16 = 0xC0A2\n\tcipher_TLS_DHE_RSA_WITH_AES_256_CCM_8               uint16 = 0xC0A3\n\tcipher_TLS_PSK_WITH_AES_128_CCM                     uint16 = 0xC0A4\n\tcipher_TLS_PSK_WITH_AES_256_CCM                     uint16 = 0xC0A5\n\tcipher_TLS_DHE_PSK_WITH_AES_128_CCM                 uint16 = 0xC0A6\n\tcipher_TLS_DHE_PSK_WITH_AES_256_CCM                 uint16 = 0xC0A7\n\tcipher_TLS_PSK_WITH_AES_128_CCM_8                   uint16 = 0xC0A8\n\tcipher_TLS_PSK_WITH_AES_256_CCM_8                   uint16 = 0xC0A9\n\tcipher_TLS_PSK_DHE_WITH_AES_128_CCM_8               uint16 = 0xC0AA\n\tcipher_TLS_PSK_DHE_WITH_AES_256_CCM_8               uint16 = 0xC0AB\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM             uint16 = 0xC0AC\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM             uint16 = 0xC0AD\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8           uint16 = 0xC0AE\n\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8           uint16 = 0xC0AF\n\t// Unassigned uint16 =  0xC0B0-FF\n\t// Unassigned uint16 =  0xC1-CB,*\n\t// Unassigned uint16 =  0xCC00-A7\n\tcipher_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256   uint16 = 0xCCA8\n\tcipher_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xCCA9\n\tcipher_TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256     uint16 = 0xCCAA\n\tcipher_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256         uint16 = 0xCCAB\n\tcipher_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256   uint16 = 0xCCAC\n\tcipher_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256     uint16 = 0xCCAD\n\tcipher_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256     uint16 = 0xCCAE\n)\n\n// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec.\n// References:\n// https://tools.ietf.org/html/rfc7540#appendix-A\n// Reject cipher suites from Appendix A.\n// \"This list includes those cipher suites that do not\n// offer an ephemeral key exchange and those that are\n// based on the TLS null, stream or block cipher type\"\nfunc isBadCipher(cipher uint16) bool {\n\tswitch cipher {\n\tcase cipher_TLS_NULL_WITH_NULL_NULL,\n\t\tcipher_TLS_RSA_WITH_NULL_MD5,\n\t\tcipher_TLS_RSA_WITH_NULL_SHA,\n\t\tcipher_TLS_RSA_EXPORT_WITH_RC4_40_MD5,\n\t\tcipher_TLS_RSA_WITH_RC4_128_MD5,\n\t\tcipher_TLS_RSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,\n\t\tcipher_TLS_RSA_WITH_IDEA_CBC_SHA,\n\t\tcipher_TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DH_anon_EXPORT_WITH_RC4_40_MD5,\n\t\tcipher_TLS_DH_anon_WITH_RC4_128_MD5,\n\t\tcipher_TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_DES_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_RC4_128_SHA,\n\t\tcipher_TLS_KRB5_WITH_IDEA_CBC_SHA,\n\t\tcipher_TLS_KRB5_WITH_DES_CBC_MD5,\n\t\tcipher_TLS_KRB5_WITH_3DES_EDE_CBC_MD5,\n\t\tcipher_TLS_KRB5_WITH_RC4_128_MD5,\n\t\tcipher_TLS_KRB5_WITH_IDEA_CBC_MD5,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_SHA,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5,\n\t\tcipher_TLS_KRB5_EXPORT_WITH_RC4_40_MD5,\n\t\tcipher_TLS_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_NULL_SHA256,\n\t\tcipher_TLS_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_AES_256_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA,\n\t\tcipher_TLS_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DH_DSS_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DH_RSA_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DHE_DSS_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DHE_RSA_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_DH_anon_WITH_SEED_CBC_SHA,\n\t\tcipher_TLS_RSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_PSK_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256,\n\t\tcipher_TLS_EMPTY_RENEGOTIATION_INFO_SCSV,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDH_anon_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_RC4_128_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA,\n\t\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_NULL_SHA384,\n\t\tcipher_TLS_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_PSK_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_PSK_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256,\n\t\tcipher_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384,\n\t\tcipher_TLS_RSA_WITH_AES_128_CCM,\n\t\tcipher_TLS_RSA_WITH_AES_256_CCM,\n\t\tcipher_TLS_RSA_WITH_AES_128_CCM_8,\n\t\tcipher_TLS_RSA_WITH_AES_256_CCM_8,\n\t\tcipher_TLS_PSK_WITH_AES_128_CCM,\n\t\tcipher_TLS_PSK_WITH_AES_256_CCM,\n\t\tcipher_TLS_PSK_WITH_AES_128_CCM_8,\n\t\tcipher_TLS_PSK_WITH_AES_256_CCM_8:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/client_conn_pool.go",
    "content": "// Copyright 2015 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// Transport code's client connection pooling.\n\npackage http2\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net\"\n\t\"net/http\"\n\t\"sync\"\n)\n\n// ClientConnPool manages a pool of HTTP/2 client connections.\ntype ClientConnPool interface {\n\t// GetClientConn returns a specific HTTP/2 connection (usually\n\t// a TLS-TCP connection) to an HTTP/2 server. On success, the\n\t// returned ClientConn accounts for the upcoming RoundTrip\n\t// call, so the caller should not omit it. If the caller needs\n\t// to, ClientConn.RoundTrip can be called with a bogus\n\t// new(http.Request) to release the stream reservation.\n\tGetClientConn(req *http.Request, addr string) (*ClientConn, error)\n\tMarkDead(*ClientConn)\n}\n\n// clientConnPoolIdleCloser is the interface implemented by ClientConnPool\n// implementations which can close their idle connections.\ntype clientConnPoolIdleCloser interface {\n\tClientConnPool\n\tcloseIdleConnections()\n}\n\nvar (\n\t_ clientConnPoolIdleCloser = (*clientConnPool)(nil)\n\t_ clientConnPoolIdleCloser = noDialClientConnPool{}\n)\n\n// TODO: use singleflight for dialing and addConnCalls?\ntype clientConnPool struct {\n\tt *Transport\n\n\tmu sync.Mutex // TODO: maybe switch to RWMutex\n\t// TODO: add support for sharing conns based on cert names\n\t// (e.g. share conn for googleapis.com and appspot.com)\n\tconns        map[string][]*ClientConn // key is host:port\n\tdialing      map[string]*dialCall     // currently in-flight dials\n\tkeys         map[*ClientConn][]string\n\taddConnCalls map[string]*addConnCall // in-flight addConnIfNeeded calls\n}\n\nfunc (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {\n\treturn p.getClientConn(req, addr, dialOnMiss)\n}\n\nconst (\n\tdialOnMiss   = true\n\tnoDialOnMiss = false\n)\n\nfunc (p *clientConnPool) getClientConn(req *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {\n\t// TODO(dneil): Dial a new connection when t.DisableKeepAlives is set?\n\tif isConnectionCloseRequest(req) && dialOnMiss {\n\t\t// It gets its own connection.\n\t\ttraceGetConn(req, addr)\n\t\tconst singleUse = true\n\t\tcc, err := p.t.dialClientConn(req.Context(), addr, singleUse)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn cc, nil\n\t}\n\tfor {\n\t\tp.mu.Lock()\n\t\tfor _, cc := range p.conns[addr] {\n\t\t\tif cc.ReserveNewRequest() {\n\t\t\t\t// When a connection is presented to us by the net/http package,\n\t\t\t\t// the GetConn hook has already been called.\n\t\t\t\t// Don't call it a second time here.\n\t\t\t\tif !cc.getConnCalled {\n\t\t\t\t\ttraceGetConn(req, addr)\n\t\t\t\t}\n\t\t\t\tcc.getConnCalled = false\n\t\t\t\tp.mu.Unlock()\n\t\t\t\treturn cc, nil\n\t\t\t}\n\t\t}\n\t\tif !dialOnMiss {\n\t\t\tp.mu.Unlock()\n\t\t\treturn nil, ErrNoCachedConn\n\t\t}\n\t\ttraceGetConn(req, addr)\n\t\tcall := p.getStartDialLocked(req.Context(), addr)\n\t\tp.mu.Unlock()\n\t\t<-call.done\n\t\tif shouldRetryDial(call, req) {\n\t\t\tcontinue\n\t\t}\n\t\tcc, err := call.res, call.err\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif cc.ReserveNewRequest() {\n\t\t\treturn cc, nil\n\t\t}\n\t}\n}\n\n// dialCall is an in-flight Transport dial call to a host.\ntype dialCall struct {\n\t_ incomparable\n\tp *clientConnPool\n\t// the context associated with the request\n\t// that created this dialCall\n\tctx  context.Context\n\tdone chan struct{} // closed when done\n\tres  *ClientConn   // valid after done is closed\n\terr  error         // valid after done is closed\n}\n\n// requires p.mu is held.\nfunc (p *clientConnPool) getStartDialLocked(ctx context.Context, addr string) *dialCall {\n\tif call, ok := p.dialing[addr]; ok {\n\t\t// A dial is already in-flight. Don't start another.\n\t\treturn call\n\t}\n\tcall := &dialCall{p: p, done: make(chan struct{}), ctx: ctx}\n\tif p.dialing == nil {\n\t\tp.dialing = make(map[string]*dialCall)\n\t}\n\tp.dialing[addr] = call\n\tgo call.dial(call.ctx, addr)\n\treturn call\n}\n\n// run in its own goroutine.\nfunc (c *dialCall) dial(ctx context.Context, addr string) {\n\tconst singleUse = false // shared conn\n\tc.res, c.err = c.p.t.dialClientConn(ctx, addr, singleUse)\n\n\tc.p.mu.Lock()\n\tdelete(c.p.dialing, addr)\n\tif c.err == nil {\n\t\tc.p.addConnLocked(addr, c.res)\n\t}\n\tc.p.mu.Unlock()\n\n\tclose(c.done)\n}\n\n// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't\n// already exist. It coalesces concurrent calls with the same key.\n// This is used by the http1 Transport code when it creates a new connection. Because\n// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know\n// the protocol), it can get into a situation where it has multiple TLS connections.\n// This code decides which ones live or die.\n// The return value used is whether c was used.\n// c is never closed.\nfunc (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c net.Conn) (used bool, err error) {\n\tp.mu.Lock()\n\tfor _, cc := range p.conns[key] {\n\t\tif cc.CanTakeNewRequest() {\n\t\t\tp.mu.Unlock()\n\t\t\treturn false, nil\n\t\t}\n\t}\n\tcall, dup := p.addConnCalls[key]\n\tif !dup {\n\t\tif p.addConnCalls == nil {\n\t\t\tp.addConnCalls = make(map[string]*addConnCall)\n\t\t}\n\t\tcall = &addConnCall{\n\t\t\tp:    p,\n\t\t\tdone: make(chan struct{}),\n\t\t}\n\t\tp.addConnCalls[key] = call\n\t\tgo call.run(t, key, c)\n\t}\n\tp.mu.Unlock()\n\n\t<-call.done\n\tif call.err != nil {\n\t\treturn false, call.err\n\t}\n\treturn !dup, nil\n}\n\ntype addConnCall struct {\n\t_    incomparable\n\tp    *clientConnPool\n\tdone chan struct{} // closed when done\n\terr  error\n}\n\nfunc (c *addConnCall) run(t *Transport, key string, nc net.Conn) {\n\tcc, err := t.NewClientConn(nc)\n\n\tp := c.p\n\tp.mu.Lock()\n\tif err != nil {\n\t\tc.err = err\n\t} else {\n\t\tcc.getConnCalled = true // already called by the net/http package\n\t\tp.addConnLocked(key, cc)\n\t}\n\tdelete(p.addConnCalls, key)\n\tp.mu.Unlock()\n\tclose(c.done)\n}\n\n// p.mu must be held\nfunc (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {\n\tfor _, v := range p.conns[key] {\n\t\tif v == cc {\n\t\t\treturn\n\t\t}\n\t}\n\tif p.conns == nil {\n\t\tp.conns = make(map[string][]*ClientConn)\n\t}\n\tif p.keys == nil {\n\t\tp.keys = make(map[*ClientConn][]string)\n\t}\n\tp.conns[key] = append(p.conns[key], cc)\n\tp.keys[cc] = append(p.keys[cc], key)\n}\n\nfunc (p *clientConnPool) MarkDead(cc *ClientConn) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tfor _, key := range p.keys[cc] {\n\t\tvv, ok := p.conns[key]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tnewList := filterOutClientConn(vv, cc)\n\t\tif len(newList) > 0 {\n\t\t\tp.conns[key] = newList\n\t\t} else {\n\t\t\tdelete(p.conns, key)\n\t\t}\n\t}\n\tdelete(p.keys, cc)\n}\n\nfunc (p *clientConnPool) closeIdleConnections() {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\t// TODO: don't close a cc if it was just added to the pool\n\t// milliseconds ago and has never been used. There's currently\n\t// a small race window with the HTTP/1 Transport's integration\n\t// where it can add an idle conn just before using it, and\n\t// somebody else can concurrently call CloseIdleConns and\n\t// break some caller's RoundTrip.\n\tfor _, vv := range p.conns {\n\t\tfor _, cc := range vv {\n\t\t\tcc.closeIfIdle()\n\t\t}\n\t}\n}\n\nfunc filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {\n\tout := in[:0]\n\tfor _, v := range in {\n\t\tif v != exclude {\n\t\t\tout = append(out, v)\n\t\t}\n\t}\n\t// If we filtered it out, zero out the last item to prevent\n\t// the GC from seeing it.\n\tif len(in) != len(out) {\n\t\tin[len(in)-1] = nil\n\t}\n\treturn out\n}\n\n// noDialClientConnPool is an implementation of http2.ClientConnPool\n// which never dials. We let the HTTP/1.1 client dial and use its TLS\n// connection instead.\ntype noDialClientConnPool struct{ *clientConnPool }\n\nfunc (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {\n\treturn p.getClientConn(req, addr, noDialOnMiss)\n}\n\n// shouldRetryDial reports whether the current request should\n// retry dialing after the call finished unsuccessfully, for example\n// if the dial was canceled because of a context cancellation or\n// deadline expiry.\nfunc shouldRetryDial(call *dialCall, req *http.Request) bool {\n\tif call.err == nil {\n\t\t// No error, no need to retry\n\t\treturn false\n\t}\n\tif call.ctx == req.Context() {\n\t\t// If the call has the same context as the request, the dial\n\t\t// should not be retried, since any cancellation will have come\n\t\t// from this request.\n\t\treturn false\n\t}\n\tif !errors.Is(call.err, context.Canceled) && !errors.Is(call.err, context.DeadlineExceeded) {\n\t\t// If the call error is not because of a context cancellation or a deadline expiry,\n\t\t// the dial should not be retried.\n\t\treturn false\n\t}\n\t// Only retry if the error is a context cancellation error or deadline expiry\n\t// and the context associated with the call was canceled or expired.\n\treturn call.ctx.Err() != nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/config.go",
    "content": "// Copyright 2024 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 http2\n\nimport (\n\t\"math\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// http2Config is a package-internal version of net/http.HTTP2Config.\n//\n// http.HTTP2Config was added in Go 1.24.\n// When running with a version of net/http that includes HTTP2Config,\n// we merge the configuration with the fields in Transport or Server\n// to produce an http2Config.\n//\n// Zero valued fields in http2Config are interpreted as in the\n// net/http.HTTPConfig documentation.\n//\n// Precedence order for reconciling configurations is:\n//\n//   - Use the net/http.{Server,Transport}.HTTP2Config value, when non-zero.\n//   - Otherwise use the http2.{Server.Transport} value.\n//   - If the resulting value is zero or out of range, use a default.\ntype http2Config struct {\n\tMaxConcurrentStreams         uint32\n\tStrictMaxConcurrentRequests  bool\n\tMaxDecoderHeaderTableSize    uint32\n\tMaxEncoderHeaderTableSize    uint32\n\tMaxReadFrameSize             uint32\n\tMaxUploadBufferPerConnection int32\n\tMaxUploadBufferPerStream     int32\n\tSendPingTimeout              time.Duration\n\tPingTimeout                  time.Duration\n\tWriteByteTimeout             time.Duration\n\tPermitProhibitedCipherSuites bool\n\tCountError                   func(errType string)\n}\n\n// configFromServer merges configuration settings from\n// net/http.Server.HTTP2Config and http2.Server.\nfunc configFromServer(h1 *http.Server, h2 *Server) http2Config {\n\tconf := http2Config{\n\t\tMaxConcurrentStreams:         h2.MaxConcurrentStreams,\n\t\tMaxEncoderHeaderTableSize:    h2.MaxEncoderHeaderTableSize,\n\t\tMaxDecoderHeaderTableSize:    h2.MaxDecoderHeaderTableSize,\n\t\tMaxReadFrameSize:             h2.MaxReadFrameSize,\n\t\tMaxUploadBufferPerConnection: h2.MaxUploadBufferPerConnection,\n\t\tMaxUploadBufferPerStream:     h2.MaxUploadBufferPerStream,\n\t\tSendPingTimeout:              h2.ReadIdleTimeout,\n\t\tPingTimeout:                  h2.PingTimeout,\n\t\tWriteByteTimeout:             h2.WriteByteTimeout,\n\t\tPermitProhibitedCipherSuites: h2.PermitProhibitedCipherSuites,\n\t\tCountError:                   h2.CountError,\n\t}\n\tfillNetHTTPConfig(&conf, h1.HTTP2)\n\tsetConfigDefaults(&conf, true)\n\treturn conf\n}\n\n// configFromTransport merges configuration settings from h2 and h2.t1.HTTP2\n// (the net/http Transport).\nfunc configFromTransport(h2 *Transport) http2Config {\n\tconf := http2Config{\n\t\tStrictMaxConcurrentRequests: h2.StrictMaxConcurrentStreams,\n\t\tMaxEncoderHeaderTableSize:   h2.MaxEncoderHeaderTableSize,\n\t\tMaxDecoderHeaderTableSize:   h2.MaxDecoderHeaderTableSize,\n\t\tMaxReadFrameSize:            h2.MaxReadFrameSize,\n\t\tSendPingTimeout:             h2.ReadIdleTimeout,\n\t\tPingTimeout:                 h2.PingTimeout,\n\t\tWriteByteTimeout:            h2.WriteByteTimeout,\n\t}\n\n\t// Unlike most config fields, where out-of-range values revert to the default,\n\t// Transport.MaxReadFrameSize clips.\n\tif conf.MaxReadFrameSize < minMaxFrameSize {\n\t\tconf.MaxReadFrameSize = minMaxFrameSize\n\t} else if conf.MaxReadFrameSize > maxFrameSize {\n\t\tconf.MaxReadFrameSize = maxFrameSize\n\t}\n\n\tif h2.t1 != nil {\n\t\tfillNetHTTPConfig(&conf, h2.t1.HTTP2)\n\t}\n\tsetConfigDefaults(&conf, false)\n\treturn conf\n}\n\nfunc setDefault[T ~int | ~int32 | ~uint32 | ~int64](v *T, minval, maxval, defval T) {\n\tif *v < minval || *v > maxval {\n\t\t*v = defval\n\t}\n}\n\nfunc setConfigDefaults(conf *http2Config, server bool) {\n\tsetDefault(&conf.MaxConcurrentStreams, 1, math.MaxUint32, defaultMaxStreams)\n\tsetDefault(&conf.MaxEncoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize)\n\tsetDefault(&conf.MaxDecoderHeaderTableSize, 1, math.MaxUint32, initialHeaderTableSize)\n\tif server {\n\t\tsetDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, 1<<20)\n\t} else {\n\t\tsetDefault(&conf.MaxUploadBufferPerConnection, initialWindowSize, math.MaxInt32, transportDefaultConnFlow)\n\t}\n\tif server {\n\t\tsetDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, 1<<20)\n\t} else {\n\t\tsetDefault(&conf.MaxUploadBufferPerStream, 1, math.MaxInt32, transportDefaultStreamFlow)\n\t}\n\tsetDefault(&conf.MaxReadFrameSize, minMaxFrameSize, maxFrameSize, defaultMaxReadFrameSize)\n\tsetDefault(&conf.PingTimeout, 1, math.MaxInt64, 15*time.Second)\n}\n\n// adjustHTTP1MaxHeaderSize converts a limit in bytes on the size of an HTTP/1 header\n// to an HTTP/2 MAX_HEADER_LIST_SIZE value.\nfunc adjustHTTP1MaxHeaderSize(n int64) int64 {\n\t// http2's count is in a slightly different unit and includes 32 bytes per pair.\n\t// So, take the net/http.Server value and pad it up a bit, assuming 10 headers.\n\tconst perFieldOverhead = 32 // per http2 spec\n\tconst typicalHeaders = 10   // conservative\n\treturn n + typicalHeaders*perFieldOverhead\n}\n\nfunc fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) {\n\tif h2 == nil {\n\t\treturn\n\t}\n\tif h2.MaxConcurrentStreams != 0 {\n\t\tconf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)\n\t}\n\tif http2ConfigStrictMaxConcurrentRequests(h2) {\n\t\tconf.StrictMaxConcurrentRequests = true\n\t}\n\tif h2.MaxEncoderHeaderTableSize != 0 {\n\t\tconf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize)\n\t}\n\tif h2.MaxDecoderHeaderTableSize != 0 {\n\t\tconf.MaxDecoderHeaderTableSize = uint32(h2.MaxDecoderHeaderTableSize)\n\t}\n\tif h2.MaxConcurrentStreams != 0 {\n\t\tconf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)\n\t}\n\tif h2.MaxReadFrameSize != 0 {\n\t\tconf.MaxReadFrameSize = uint32(h2.MaxReadFrameSize)\n\t}\n\tif h2.MaxReceiveBufferPerConnection != 0 {\n\t\tconf.MaxUploadBufferPerConnection = int32(h2.MaxReceiveBufferPerConnection)\n\t}\n\tif h2.MaxReceiveBufferPerStream != 0 {\n\t\tconf.MaxUploadBufferPerStream = int32(h2.MaxReceiveBufferPerStream)\n\t}\n\tif h2.SendPingTimeout != 0 {\n\t\tconf.SendPingTimeout = h2.SendPingTimeout\n\t}\n\tif h2.PingTimeout != 0 {\n\t\tconf.PingTimeout = h2.PingTimeout\n\t}\n\tif h2.WriteByteTimeout != 0 {\n\t\tconf.WriteByteTimeout = h2.WriteByteTimeout\n\t}\n\tif h2.PermitProhibitedCipherSuites {\n\t\tconf.PermitProhibitedCipherSuites = true\n\t}\n\tif h2.CountError != nil {\n\t\tconf.CountError = h2.CountError\n\t}\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/config_go125.go",
    "content": "// Copyright 2025 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 !go1.26\n\npackage http2\n\nimport (\n\t\"net/http\"\n)\n\nfunc http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool {\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/config_go126.go",
    "content": "// Copyright 2025 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 go1.26\n\npackage http2\n\nimport (\n\t\"net/http\"\n)\n\nfunc http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool {\n\treturn h2.StrictMaxConcurrentRequests\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/databuffer.go",
    "content": "// Copyright 2014 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 http2\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n)\n\n// Buffer chunks are allocated from a pool to reduce pressure on GC.\n// The maximum wasted space per dataBuffer is 2x the largest size class,\n// which happens when the dataBuffer has multiple chunks and there is\n// one unread byte in both the first and last chunks. We use a few size\n// classes to minimize overheads for servers that typically receive very\n// small request bodies.\n//\n// TODO: Benchmark to determine if the pools are necessary. The GC may have\n// improved enough that we can instead allocate chunks like this:\n// make([]byte, max(16<<10, expectedBytesRemaining))\nvar dataChunkPools = [...]sync.Pool{\n\t{New: func() interface{} { return new([1 << 10]byte) }},\n\t{New: func() interface{} { return new([2 << 10]byte) }},\n\t{New: func() interface{} { return new([4 << 10]byte) }},\n\t{New: func() interface{} { return new([8 << 10]byte) }},\n\t{New: func() interface{} { return new([16 << 10]byte) }},\n}\n\nfunc getDataBufferChunk(size int64) []byte {\n\tswitch {\n\tcase size <= 1<<10:\n\t\treturn dataChunkPools[0].Get().(*[1 << 10]byte)[:]\n\tcase size <= 2<<10:\n\t\treturn dataChunkPools[1].Get().(*[2 << 10]byte)[:]\n\tcase size <= 4<<10:\n\t\treturn dataChunkPools[2].Get().(*[4 << 10]byte)[:]\n\tcase size <= 8<<10:\n\t\treturn dataChunkPools[3].Get().(*[8 << 10]byte)[:]\n\tdefault:\n\t\treturn dataChunkPools[4].Get().(*[16 << 10]byte)[:]\n\t}\n}\n\nfunc putDataBufferChunk(p []byte) {\n\tswitch len(p) {\n\tcase 1 << 10:\n\t\tdataChunkPools[0].Put((*[1 << 10]byte)(p))\n\tcase 2 << 10:\n\t\tdataChunkPools[1].Put((*[2 << 10]byte)(p))\n\tcase 4 << 10:\n\t\tdataChunkPools[2].Put((*[4 << 10]byte)(p))\n\tcase 8 << 10:\n\t\tdataChunkPools[3].Put((*[8 << 10]byte)(p))\n\tcase 16 << 10:\n\t\tdataChunkPools[4].Put((*[16 << 10]byte)(p))\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unexpected buffer len=%v\", len(p)))\n\t}\n}\n\n// dataBuffer is an io.ReadWriter backed by a list of data chunks.\n// Each dataBuffer is used to read DATA frames on a single stream.\n// The buffer is divided into chunks so the server can limit the\n// total memory used by a single connection without limiting the\n// request body size on any single stream.\ntype dataBuffer struct {\n\tchunks   [][]byte\n\tr        int   // next byte to read is chunks[0][r]\n\tw        int   // next byte to write is chunks[len(chunks)-1][w]\n\tsize     int   // total buffered bytes\n\texpected int64 // we expect at least this many bytes in future Write calls (ignored if <= 0)\n}\n\nvar errReadEmpty = errors.New(\"read from empty dataBuffer\")\n\n// Read copies bytes from the buffer into p.\n// It is an error to read when no data is available.\nfunc (b *dataBuffer) Read(p []byte) (int, error) {\n\tif b.size == 0 {\n\t\treturn 0, errReadEmpty\n\t}\n\tvar ntotal int\n\tfor len(p) > 0 && b.size > 0 {\n\t\treadFrom := b.bytesFromFirstChunk()\n\t\tn := copy(p, readFrom)\n\t\tp = p[n:]\n\t\tntotal += n\n\t\tb.r += n\n\t\tb.size -= n\n\t\t// If the first chunk has been consumed, advance to the next chunk.\n\t\tif b.r == len(b.chunks[0]) {\n\t\t\tputDataBufferChunk(b.chunks[0])\n\t\t\tend := len(b.chunks) - 1\n\t\t\tcopy(b.chunks[:end], b.chunks[1:])\n\t\t\tb.chunks[end] = nil\n\t\t\tb.chunks = b.chunks[:end]\n\t\t\tb.r = 0\n\t\t}\n\t}\n\treturn ntotal, nil\n}\n\nfunc (b *dataBuffer) bytesFromFirstChunk() []byte {\n\tif len(b.chunks) == 1 {\n\t\treturn b.chunks[0][b.r:b.w]\n\t}\n\treturn b.chunks[0][b.r:]\n}\n\n// Len returns the number of bytes of the unread portion of the buffer.\nfunc (b *dataBuffer) Len() int {\n\treturn b.size\n}\n\n// Write appends p to the buffer.\nfunc (b *dataBuffer) Write(p []byte) (int, error) {\n\tntotal := len(p)\n\tfor len(p) > 0 {\n\t\t// If the last chunk is empty, allocate a new chunk. Try to allocate\n\t\t// enough to fully copy p plus any additional bytes we expect to\n\t\t// receive. However, this may allocate less than len(p).\n\t\twant := int64(len(p))\n\t\tif b.expected > want {\n\t\t\twant = b.expected\n\t\t}\n\t\tchunk := b.lastChunkOrAlloc(want)\n\t\tn := copy(chunk[b.w:], p)\n\t\tp = p[n:]\n\t\tb.w += n\n\t\tb.size += n\n\t\tb.expected -= int64(n)\n\t}\n\treturn ntotal, nil\n}\n\nfunc (b *dataBuffer) lastChunkOrAlloc(want int64) []byte {\n\tif len(b.chunks) != 0 {\n\t\tlast := b.chunks[len(b.chunks)-1]\n\t\tif b.w < len(last) {\n\t\t\treturn last\n\t\t}\n\t}\n\tchunk := getDataBufferChunk(want)\n\tb.chunks = append(b.chunks, chunk)\n\tb.w = 0\n\treturn chunk\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/errors.go",
    "content": "// Copyright 2014 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 http2\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\n// An ErrCode is an unsigned 32-bit error code as defined in the HTTP/2 spec.\ntype ErrCode uint32\n\nconst (\n\tErrCodeNo                 ErrCode = 0x0\n\tErrCodeProtocol           ErrCode = 0x1\n\tErrCodeInternal           ErrCode = 0x2\n\tErrCodeFlowControl        ErrCode = 0x3\n\tErrCodeSettingsTimeout    ErrCode = 0x4\n\tErrCodeStreamClosed       ErrCode = 0x5\n\tErrCodeFrameSize          ErrCode = 0x6\n\tErrCodeRefusedStream      ErrCode = 0x7\n\tErrCodeCancel             ErrCode = 0x8\n\tErrCodeCompression        ErrCode = 0x9\n\tErrCodeConnect            ErrCode = 0xa\n\tErrCodeEnhanceYourCalm    ErrCode = 0xb\n\tErrCodeInadequateSecurity ErrCode = 0xc\n\tErrCodeHTTP11Required     ErrCode = 0xd\n)\n\nvar errCodeName = map[ErrCode]string{\n\tErrCodeNo:                 \"NO_ERROR\",\n\tErrCodeProtocol:           \"PROTOCOL_ERROR\",\n\tErrCodeInternal:           \"INTERNAL_ERROR\",\n\tErrCodeFlowControl:        \"FLOW_CONTROL_ERROR\",\n\tErrCodeSettingsTimeout:    \"SETTINGS_TIMEOUT\",\n\tErrCodeStreamClosed:       \"STREAM_CLOSED\",\n\tErrCodeFrameSize:          \"FRAME_SIZE_ERROR\",\n\tErrCodeRefusedStream:      \"REFUSED_STREAM\",\n\tErrCodeCancel:             \"CANCEL\",\n\tErrCodeCompression:        \"COMPRESSION_ERROR\",\n\tErrCodeConnect:            \"CONNECT_ERROR\",\n\tErrCodeEnhanceYourCalm:    \"ENHANCE_YOUR_CALM\",\n\tErrCodeInadequateSecurity: \"INADEQUATE_SECURITY\",\n\tErrCodeHTTP11Required:     \"HTTP_1_1_REQUIRED\",\n}\n\nfunc (e ErrCode) String() string {\n\tif s, ok := errCodeName[e]; ok {\n\t\treturn s\n\t}\n\treturn fmt.Sprintf(\"unknown error code 0x%x\", uint32(e))\n}\n\nfunc (e ErrCode) stringToken() string {\n\tif s, ok := errCodeName[e]; ok {\n\t\treturn s\n\t}\n\treturn fmt.Sprintf(\"ERR_UNKNOWN_%d\", uint32(e))\n}\n\n// ConnectionError is an error that results in the termination of the\n// entire connection.\ntype ConnectionError ErrCode\n\nfunc (e ConnectionError) Error() string { return fmt.Sprintf(\"connection error: %s\", ErrCode(e)) }\n\n// StreamError is an error that only affects one stream within an\n// HTTP/2 connection.\ntype StreamError struct {\n\tStreamID uint32\n\tCode     ErrCode\n\tCause    error // optional additional detail\n}\n\n// errFromPeer is a sentinel error value for StreamError.Cause to\n// indicate that the StreamError was sent from the peer over the wire\n// and wasn't locally generated in the Transport.\nvar errFromPeer = errors.New(\"received from peer\")\n\nfunc streamError(id uint32, code ErrCode) StreamError {\n\treturn StreamError{StreamID: id, Code: code}\n}\n\nfunc (e StreamError) Error() string {\n\tif e.Cause != nil {\n\t\treturn fmt.Sprintf(\"stream error: stream ID %d; %v; %v\", e.StreamID, e.Code, e.Cause)\n\t}\n\treturn fmt.Sprintf(\"stream error: stream ID %d; %v\", e.StreamID, e.Code)\n}\n\n// 6.9.1 The Flow Control Window\n// \"If a sender receives a WINDOW_UPDATE that causes a flow control\n// window to exceed this maximum it MUST terminate either the stream\n// or the connection, as appropriate. For streams, [...]; for the\n// connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code.\"\ntype goAwayFlowError struct{}\n\nfunc (goAwayFlowError) Error() string { return \"connection exceeded flow control window size\" }\n\n// connError represents an HTTP/2 ConnectionError error code, along\n// with a string (for debugging) explaining why.\n//\n// Errors of this type are only returned by the frame parser functions\n// and converted into ConnectionError(Code), after stashing away\n// the Reason into the Framer's errDetail field, accessible via\n// the (*Framer).ErrorDetail method.\ntype connError struct {\n\tCode   ErrCode // the ConnectionError error code\n\tReason string  // additional reason\n}\n\nfunc (e connError) Error() string {\n\treturn fmt.Sprintf(\"http2: connection error: %v: %v\", e.Code, e.Reason)\n}\n\ntype pseudoHeaderError string\n\nfunc (e pseudoHeaderError) Error() string {\n\treturn fmt.Sprintf(\"invalid pseudo-header %q\", string(e))\n}\n\ntype duplicatePseudoHeaderError string\n\nfunc (e duplicatePseudoHeaderError) Error() string {\n\treturn fmt.Sprintf(\"duplicate pseudo-header %q\", string(e))\n}\n\ntype headerFieldNameError string\n\nfunc (e headerFieldNameError) Error() string {\n\treturn fmt.Sprintf(\"invalid header field name %q\", string(e))\n}\n\ntype headerFieldValueError string\n\nfunc (e headerFieldValueError) Error() string {\n\treturn fmt.Sprintf(\"invalid header field value for %q\", string(e))\n}\n\nvar (\n\terrMixPseudoHeaderTypes = errors.New(\"mix of request and response pseudo headers\")\n\terrPseudoAfterRegular   = errors.New(\"pseudo header field after regular\")\n)\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/flow.go",
    "content": "// Copyright 2014 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// Flow control\n\npackage http2\n\n// inflowMinRefresh is the minimum number of bytes we'll send for a\n// flow control window update.\nconst inflowMinRefresh = 4 << 10\n\n// inflow accounts for an inbound flow control window.\n// It tracks both the latest window sent to the peer (used for enforcement)\n// and the accumulated unsent window.\ntype inflow struct {\n\tavail  int32\n\tunsent int32\n}\n\n// init sets the initial window.\nfunc (f *inflow) init(n int32) {\n\tf.avail = n\n}\n\n// add adds n bytes to the window, with a maximum window size of max,\n// indicating that the peer can now send us more data.\n// For example, the user read from a {Request,Response} body and consumed\n// some of the buffered data, so the peer can now send more.\n// It returns the number of bytes to send in a WINDOW_UPDATE frame to the peer.\n// Window updates are accumulated and sent when the unsent capacity\n// is at least inflowMinRefresh or will at least double the peer's available window.\nfunc (f *inflow) add(n int) (connAdd int32) {\n\tif n < 0 {\n\t\tpanic(\"negative update\")\n\t}\n\tunsent := int64(f.unsent) + int64(n)\n\t// \"A sender MUST NOT allow a flow-control window to exceed 2^31-1 octets.\"\n\t// RFC 7540 Section 6.9.1.\n\tconst maxWindow = 1<<31 - 1\n\tif unsent+int64(f.avail) > maxWindow {\n\t\tpanic(\"flow control update exceeds maximum window size\")\n\t}\n\tf.unsent = int32(unsent)\n\tif f.unsent < inflowMinRefresh && f.unsent < f.avail {\n\t\t// If there aren't at least inflowMinRefresh bytes of window to send,\n\t\t// and this update won't at least double the window, buffer the update for later.\n\t\treturn 0\n\t}\n\tf.avail += f.unsent\n\tf.unsent = 0\n\treturn int32(unsent)\n}\n\n// take attempts to take n bytes from the peer's flow control window.\n// It reports whether the window has available capacity.\nfunc (f *inflow) take(n uint32) bool {\n\tif n > uint32(f.avail) {\n\t\treturn false\n\t}\n\tf.avail -= int32(n)\n\treturn true\n}\n\n// takeInflows attempts to take n bytes from two inflows,\n// typically connection-level and stream-level flows.\n// It reports whether both windows have available capacity.\nfunc takeInflows(f1, f2 *inflow, n uint32) bool {\n\tif n > uint32(f1.avail) || n > uint32(f2.avail) {\n\t\treturn false\n\t}\n\tf1.avail -= int32(n)\n\tf2.avail -= int32(n)\n\treturn true\n}\n\n// outflow is the outbound flow control window's size.\ntype outflow struct {\n\t_ incomparable\n\n\t// n is the number of DATA bytes we're allowed to send.\n\t// An outflow is kept both on a conn and a per-stream.\n\tn int32\n\n\t// conn points to the shared connection-level outflow that is\n\t// shared by all streams on that conn. It is nil for the outflow\n\t// that's on the conn directly.\n\tconn *outflow\n}\n\nfunc (f *outflow) setConnFlow(cf *outflow) { f.conn = cf }\n\nfunc (f *outflow) available() int32 {\n\tn := f.n\n\tif f.conn != nil && f.conn.n < n {\n\t\tn = f.conn.n\n\t}\n\treturn n\n}\n\nfunc (f *outflow) take(n int32) {\n\tif n > f.available() {\n\t\tpanic(\"internal error: took too much\")\n\t}\n\tf.n -= n\n\tif f.conn != nil {\n\t\tf.conn.n -= n\n\t}\n}\n\n// add adds n bytes (positive or negative) to the flow control window.\n// It returns false if the sum would exceed 2^31-1.\nfunc (f *outflow) add(n int32) bool {\n\tsum := f.n + n\n\tif (sum > n) == (f.n > 0) {\n\t\tf.n = sum\n\t\treturn true\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/frame.go",
    "content": "// Copyright 2014 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 http2\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"golang.org/x/net/http/httpguts\"\n\t\"golang.org/x/net/http2/hpack\"\n)\n\nconst frameHeaderLen = 9\n\nvar padZeros = make([]byte, 255) // zeros for padding\n\n// A FrameType is a registered frame type as defined in\n// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2\ntype FrameType uint8\n\nconst (\n\tFrameData         FrameType = 0x0\n\tFrameHeaders      FrameType = 0x1\n\tFramePriority     FrameType = 0x2\n\tFrameRSTStream    FrameType = 0x3\n\tFrameSettings     FrameType = 0x4\n\tFramePushPromise  FrameType = 0x5\n\tFramePing         FrameType = 0x6\n\tFrameGoAway       FrameType = 0x7\n\tFrameWindowUpdate FrameType = 0x8\n\tFrameContinuation FrameType = 0x9\n)\n\nvar frameNames = [...]string{\n\tFrameData:         \"DATA\",\n\tFrameHeaders:      \"HEADERS\",\n\tFramePriority:     \"PRIORITY\",\n\tFrameRSTStream:    \"RST_STREAM\",\n\tFrameSettings:     \"SETTINGS\",\n\tFramePushPromise:  \"PUSH_PROMISE\",\n\tFramePing:         \"PING\",\n\tFrameGoAway:       \"GOAWAY\",\n\tFrameWindowUpdate: \"WINDOW_UPDATE\",\n\tFrameContinuation: \"CONTINUATION\",\n}\n\nfunc (t FrameType) String() string {\n\tif int(t) < len(frameNames) {\n\t\treturn frameNames[t]\n\t}\n\treturn fmt.Sprintf(\"UNKNOWN_FRAME_TYPE_%d\", t)\n}\n\n// Flags is a bitmask of HTTP/2 flags.\n// The meaning of flags varies depending on the frame type.\ntype Flags uint8\n\n// Has reports whether f contains all (0 or more) flags in v.\nfunc (f Flags) Has(v Flags) bool {\n\treturn (f & v) == v\n}\n\n// Frame-specific FrameHeader flag bits.\nconst (\n\t// Data Frame\n\tFlagDataEndStream Flags = 0x1\n\tFlagDataPadded    Flags = 0x8\n\n\t// Headers Frame\n\tFlagHeadersEndStream  Flags = 0x1\n\tFlagHeadersEndHeaders Flags = 0x4\n\tFlagHeadersPadded     Flags = 0x8\n\tFlagHeadersPriority   Flags = 0x20\n\n\t// Settings Frame\n\tFlagSettingsAck Flags = 0x1\n\n\t// Ping Frame\n\tFlagPingAck Flags = 0x1\n\n\t// Continuation Frame\n\tFlagContinuationEndHeaders Flags = 0x4\n\n\tFlagPushPromiseEndHeaders Flags = 0x4\n\tFlagPushPromisePadded     Flags = 0x8\n)\n\nvar flagName = map[FrameType]map[Flags]string{\n\tFrameData: {\n\t\tFlagDataEndStream: \"END_STREAM\",\n\t\tFlagDataPadded:    \"PADDED\",\n\t},\n\tFrameHeaders: {\n\t\tFlagHeadersEndStream:  \"END_STREAM\",\n\t\tFlagHeadersEndHeaders: \"END_HEADERS\",\n\t\tFlagHeadersPadded:     \"PADDED\",\n\t\tFlagHeadersPriority:   \"PRIORITY\",\n\t},\n\tFrameSettings: {\n\t\tFlagSettingsAck: \"ACK\",\n\t},\n\tFramePing: {\n\t\tFlagPingAck: \"ACK\",\n\t},\n\tFrameContinuation: {\n\t\tFlagContinuationEndHeaders: \"END_HEADERS\",\n\t},\n\tFramePushPromise: {\n\t\tFlagPushPromiseEndHeaders: \"END_HEADERS\",\n\t\tFlagPushPromisePadded:     \"PADDED\",\n\t},\n}\n\n// a frameParser parses a frame given its FrameHeader and payload\n// bytes. The length of payload will always equal fh.Length (which\n// might be 0).\ntype frameParser func(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error)\n\nvar frameParsers = [...]frameParser{\n\tFrameData:         parseDataFrame,\n\tFrameHeaders:      parseHeadersFrame,\n\tFramePriority:     parsePriorityFrame,\n\tFrameRSTStream:    parseRSTStreamFrame,\n\tFrameSettings:     parseSettingsFrame,\n\tFramePushPromise:  parsePushPromise,\n\tFramePing:         parsePingFrame,\n\tFrameGoAway:       parseGoAwayFrame,\n\tFrameWindowUpdate: parseWindowUpdateFrame,\n\tFrameContinuation: parseContinuationFrame,\n}\n\nfunc typeFrameParser(t FrameType) frameParser {\n\tif int(t) < len(frameParsers) {\n\t\treturn frameParsers[t]\n\t}\n\treturn parseUnknownFrame\n}\n\n// A FrameHeader is the 9 byte header of all HTTP/2 frames.\n//\n// See https://httpwg.org/specs/rfc7540.html#FrameHeader\ntype FrameHeader struct {\n\tvalid bool // caller can access []byte fields in the Frame\n\n\t// Type is the 1 byte frame type. There are ten standard frame\n\t// types, but extension frame types may be written by WriteRawFrame\n\t// and will be returned by ReadFrame (as UnknownFrame).\n\tType FrameType\n\n\t// Flags are the 1 byte of 8 potential bit flags per frame.\n\t// They are specific to the frame type.\n\tFlags Flags\n\n\t// Length is the length of the frame, not including the 9 byte header.\n\t// The maximum size is one byte less than 16MB (uint24), but only\n\t// frames up to 16KB are allowed without peer agreement.\n\tLength uint32\n\n\t// StreamID is which stream this frame is for. Certain frames\n\t// are not stream-specific, in which case this field is 0.\n\tStreamID uint32\n}\n\n// Header returns h. It exists so FrameHeaders can be embedded in other\n// specific frame types and implement the Frame interface.\nfunc (h FrameHeader) Header() FrameHeader { return h }\n\nfunc (h FrameHeader) String() string {\n\tvar buf bytes.Buffer\n\tbuf.WriteString(\"[FrameHeader \")\n\th.writeDebug(&buf)\n\tbuf.WriteByte(']')\n\treturn buf.String()\n}\n\nfunc (h FrameHeader) writeDebug(buf *bytes.Buffer) {\n\tbuf.WriteString(h.Type.String())\n\tif h.Flags != 0 {\n\t\tbuf.WriteString(\" flags=\")\n\t\tset := 0\n\t\tfor i := uint8(0); i < 8; i++ {\n\t\t\tif h.Flags&(1<<i) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tset++\n\t\t\tif set > 1 {\n\t\t\t\tbuf.WriteByte('|')\n\t\t\t}\n\t\t\tname := flagName[h.Type][Flags(1<<i)]\n\t\t\tif name != \"\" {\n\t\t\t\tbuf.WriteString(name)\n\t\t\t} else {\n\t\t\t\tfmt.Fprintf(buf, \"0x%x\", 1<<i)\n\t\t\t}\n\t\t}\n\t}\n\tif h.StreamID != 0 {\n\t\tfmt.Fprintf(buf, \" stream=%d\", h.StreamID)\n\t}\n\tfmt.Fprintf(buf, \" len=%d\", h.Length)\n}\n\nfunc (h *FrameHeader) checkValid() {\n\tif !h.valid {\n\t\tpanic(\"Frame accessor called on non-owned Frame\")\n\t}\n}\n\nfunc (h *FrameHeader) invalidate() { h.valid = false }\n\n// frame header bytes.\n// Used only by ReadFrameHeader.\nvar fhBytes = sync.Pool{\n\tNew: func() interface{} {\n\t\tbuf := make([]byte, frameHeaderLen)\n\t\treturn &buf\n\t},\n}\n\nfunc invalidHTTP1LookingFrameHeader() FrameHeader {\n\tfh, _ := readFrameHeader(make([]byte, frameHeaderLen), strings.NewReader(\"HTTP/1.1 \"))\n\treturn fh\n}\n\n// ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.\n// Most users should use Framer.ReadFrame instead.\nfunc ReadFrameHeader(r io.Reader) (FrameHeader, error) {\n\tbufp := fhBytes.Get().(*[]byte)\n\tdefer fhBytes.Put(bufp)\n\treturn readFrameHeader(*bufp, r)\n}\n\nfunc readFrameHeader(buf []byte, r io.Reader) (FrameHeader, error) {\n\t_, err := io.ReadFull(r, buf[:frameHeaderLen])\n\tif err != nil {\n\t\treturn FrameHeader{}, err\n\t}\n\treturn FrameHeader{\n\t\tLength:   (uint32(buf[0])<<16 | uint32(buf[1])<<8 | uint32(buf[2])),\n\t\tType:     FrameType(buf[3]),\n\t\tFlags:    Flags(buf[4]),\n\t\tStreamID: binary.BigEndian.Uint32(buf[5:]) & (1<<31 - 1),\n\t\tvalid:    true,\n\t}, nil\n}\n\n// A Frame is the base interface implemented by all frame types.\n// Callers will generally type-assert the specific frame type:\n// *HeadersFrame, *SettingsFrame, *WindowUpdateFrame, etc.\n//\n// Frames are only valid until the next call to Framer.ReadFrame.\ntype Frame interface {\n\tHeader() FrameHeader\n\n\t// invalidate is called by Framer.ReadFrame to make this\n\t// frame's buffers as being invalid, since the subsequent\n\t// frame will reuse them.\n\tinvalidate()\n}\n\n// A Framer reads and writes Frames.\ntype Framer struct {\n\tr         io.Reader\n\tlastFrame Frame\n\terrDetail error\n\n\t// countError is a non-nil func that's called on a frame parse\n\t// error with some unique error path token. It's initialized\n\t// from Transport.CountError or Server.CountError.\n\tcountError func(errToken string)\n\n\t// lastHeaderStream is non-zero if the last frame was an\n\t// unfinished HEADERS/CONTINUATION.\n\tlastHeaderStream uint32\n\t// lastFrameType holds the type of the last frame for verifying frame order.\n\tlastFrameType FrameType\n\n\tmaxReadSize uint32\n\theaderBuf   [frameHeaderLen]byte\n\n\t// TODO: let getReadBuf be configurable, and use a less memory-pinning\n\t// allocator in server.go to minimize memory pinned for many idle conns.\n\t// Will probably also need to make frame invalidation have a hook too.\n\tgetReadBuf func(size uint32) []byte\n\treadBuf    []byte // cache for default getReadBuf\n\n\tmaxWriteSize uint32 // zero means unlimited; TODO: implement\n\n\tw    io.Writer\n\twbuf []byte\n\n\t// AllowIllegalWrites permits the Framer's Write methods to\n\t// write frames that do not conform to the HTTP/2 spec. This\n\t// permits using the Framer to test other HTTP/2\n\t// implementations' conformance to the spec.\n\t// If false, the Write methods will prefer to return an error\n\t// rather than comply.\n\tAllowIllegalWrites bool\n\n\t// AllowIllegalReads permits the Framer's ReadFrame method\n\t// to return non-compliant frames or frame orders.\n\t// This is for testing and permits using the Framer to test\n\t// other HTTP/2 implementations' conformance to the spec.\n\t// It is not compatible with ReadMetaHeaders.\n\tAllowIllegalReads bool\n\n\t// ReadMetaHeaders if non-nil causes ReadFrame to merge\n\t// HEADERS and CONTINUATION frames together and return\n\t// MetaHeadersFrame instead.\n\tReadMetaHeaders *hpack.Decoder\n\n\t// MaxHeaderListSize is the http2 MAX_HEADER_LIST_SIZE.\n\t// It's used only if ReadMetaHeaders is set; 0 means a sane default\n\t// (currently 16MB)\n\t// If the limit is hit, MetaHeadersFrame.Truncated is set true.\n\tMaxHeaderListSize uint32\n\n\t// TODO: track which type of frame & with which flags was sent\n\t// last. Then return an error (unless AllowIllegalWrites) if\n\t// we're in the middle of a header block and a\n\t// non-Continuation or Continuation on a different stream is\n\t// attempted to be written.\n\n\tlogReads, logWrites bool\n\n\tdebugFramer       *Framer // only use for logging written writes\n\tdebugFramerBuf    *bytes.Buffer\n\tdebugReadLoggerf  func(string, ...interface{})\n\tdebugWriteLoggerf func(string, ...interface{})\n\n\tframeCache *frameCache // nil if frames aren't reused (default)\n}\n\nfunc (fr *Framer) maxHeaderListSize() uint32 {\n\tif fr.MaxHeaderListSize == 0 {\n\t\treturn 16 << 20 // sane default, per docs\n\t}\n\treturn fr.MaxHeaderListSize\n}\n\nfunc (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {\n\t// Write the FrameHeader.\n\tf.wbuf = append(f.wbuf[:0],\n\t\t0, // 3 bytes of length, filled in endWrite\n\t\t0,\n\t\t0,\n\t\tbyte(ftype),\n\t\tbyte(flags),\n\t\tbyte(streamID>>24),\n\t\tbyte(streamID>>16),\n\t\tbyte(streamID>>8),\n\t\tbyte(streamID))\n}\n\nfunc (f *Framer) endWrite() error {\n\t// Now that we know the final size, fill in the FrameHeader in\n\t// the space previously reserved for it. Abuse append.\n\tlength := len(f.wbuf) - frameHeaderLen\n\tif length >= (1 << 24) {\n\t\treturn ErrFrameTooLarge\n\t}\n\t_ = append(f.wbuf[:0],\n\t\tbyte(length>>16),\n\t\tbyte(length>>8),\n\t\tbyte(length))\n\tif f.logWrites {\n\t\tf.logWrite()\n\t}\n\n\tn, err := f.w.Write(f.wbuf)\n\tif err == nil && n != len(f.wbuf) {\n\t\terr = io.ErrShortWrite\n\t}\n\treturn err\n}\n\nfunc (f *Framer) logWrite() {\n\tif f.debugFramer == nil {\n\t\tf.debugFramerBuf = new(bytes.Buffer)\n\t\tf.debugFramer = NewFramer(nil, f.debugFramerBuf)\n\t\tf.debugFramer.logReads = false // we log it ourselves, saying \"wrote\" below\n\t\t// Let us read anything, even if we accidentally wrote it\n\t\t// in the wrong order:\n\t\tf.debugFramer.AllowIllegalReads = true\n\t}\n\tf.debugFramerBuf.Write(f.wbuf)\n\tfr, err := f.debugFramer.ReadFrame()\n\tif err != nil {\n\t\tf.debugWriteLoggerf(\"http2: Framer %p: failed to decode just-written frame\", f)\n\t\treturn\n\t}\n\tf.debugWriteLoggerf(\"http2: Framer %p: wrote %v\", f, summarizeFrame(fr))\n}\n\nfunc (f *Framer) writeByte(v byte)     { f.wbuf = append(f.wbuf, v) }\nfunc (f *Framer) writeBytes(v []byte)  { f.wbuf = append(f.wbuf, v...) }\nfunc (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }\nfunc (f *Framer) writeUint32(v uint32) {\n\tf.wbuf = append(f.wbuf, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))\n}\n\nconst (\n\tminMaxFrameSize = 1 << 14\n\tmaxFrameSize    = 1<<24 - 1\n)\n\n// SetReuseFrames allows the Framer to reuse Frames.\n// If called on a Framer, Frames returned by calls to ReadFrame are only\n// valid until the next call to ReadFrame.\nfunc (fr *Framer) SetReuseFrames() {\n\tif fr.frameCache != nil {\n\t\treturn\n\t}\n\tfr.frameCache = &frameCache{}\n}\n\ntype frameCache struct {\n\tdataFrame DataFrame\n}\n\nfunc (fc *frameCache) getDataFrame() *DataFrame {\n\tif fc == nil {\n\t\treturn &DataFrame{}\n\t}\n\treturn &fc.dataFrame\n}\n\n// NewFramer returns a Framer that writes frames to w and reads them from r.\nfunc NewFramer(w io.Writer, r io.Reader) *Framer {\n\tfr := &Framer{\n\t\tw:                 w,\n\t\tr:                 r,\n\t\tcountError:        func(string) {},\n\t\tlogReads:          logFrameReads,\n\t\tlogWrites:         logFrameWrites,\n\t\tdebugReadLoggerf:  log.Printf,\n\t\tdebugWriteLoggerf: log.Printf,\n\t}\n\tfr.getReadBuf = func(size uint32) []byte {\n\t\tif cap(fr.readBuf) >= int(size) {\n\t\t\treturn fr.readBuf[:size]\n\t\t}\n\t\tfr.readBuf = make([]byte, size)\n\t\treturn fr.readBuf\n\t}\n\tfr.SetMaxReadFrameSize(maxFrameSize)\n\treturn fr\n}\n\n// SetMaxReadFrameSize sets the maximum size of a frame\n// that will be read by a subsequent call to ReadFrame.\n// It is the caller's responsibility to advertise this\n// limit with a SETTINGS frame.\nfunc (fr *Framer) SetMaxReadFrameSize(v uint32) {\n\tif v > maxFrameSize {\n\t\tv = maxFrameSize\n\t}\n\tfr.maxReadSize = v\n}\n\n// ErrorDetail returns a more detailed error of the last error\n// returned by Framer.ReadFrame. For instance, if ReadFrame\n// returns a StreamError with code PROTOCOL_ERROR, ErrorDetail\n// will say exactly what was invalid. ErrorDetail is not guaranteed\n// to return a non-nil value and like the rest of the http2 package,\n// its return value is not protected by an API compatibility promise.\n// ErrorDetail is reset after the next call to ReadFrame.\nfunc (fr *Framer) ErrorDetail() error {\n\treturn fr.errDetail\n}\n\n// ErrFrameTooLarge is returned from Framer.ReadFrame when the peer\n// sends a frame that is larger than declared with SetMaxReadFrameSize.\nvar ErrFrameTooLarge = errors.New(\"http2: frame too large\")\n\n// terminalReadFrameError reports whether err is an unrecoverable\n// error from ReadFrame and no other frames should be read.\nfunc terminalReadFrameError(err error) bool {\n\tif _, ok := err.(StreamError); ok {\n\t\treturn false\n\t}\n\treturn err != nil\n}\n\n// ReadFrameHeader reads the header of the next frame.\n// It reads the 9-byte fixed frame header, and does not read any portion of the\n// frame payload. The caller is responsible for consuming the payload, either\n// with ReadFrameForHeader or directly from the Framer's io.Reader.\n//\n// If the frame is larger than previously set with SetMaxReadFrameSize, it\n// returns the frame header and ErrFrameTooLarge.\n//\n// If the returned FrameHeader.StreamID is non-zero, it indicates the stream\n// responsible for the error.\nfunc (fr *Framer) ReadFrameHeader() (FrameHeader, error) {\n\tfr.errDetail = nil\n\tfh, err := readFrameHeader(fr.headerBuf[:], fr.r)\n\tif err != nil {\n\t\treturn fh, err\n\t}\n\tif fh.Length > fr.maxReadSize {\n\t\tif fh == invalidHTTP1LookingFrameHeader() {\n\t\t\treturn fh, fmt.Errorf(\"http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header\", ErrFrameTooLarge)\n\t\t}\n\t\treturn fh, ErrFrameTooLarge\n\t}\n\tif err := fr.checkFrameOrder(fh); err != nil {\n\t\treturn fh, err\n\t}\n\treturn fh, nil\n}\n\n// ReadFrameForHeader reads the payload for the frame with the given FrameHeader.\n//\n// It behaves identically to ReadFrame, other than not checking the maximum\n// frame size.\nfunc (fr *Framer) ReadFrameForHeader(fh FrameHeader) (Frame, error) {\n\tif fr.lastFrame != nil {\n\t\tfr.lastFrame.invalidate()\n\t}\n\tpayload := fr.getReadBuf(fh.Length)\n\tif _, err := io.ReadFull(fr.r, payload); err != nil {\n\t\tif fh == invalidHTTP1LookingFrameHeader() {\n\t\t\treturn nil, fmt.Errorf(\"http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header\", err)\n\t\t}\n\t\treturn nil, err\n\t}\n\tf, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)\n\tif err != nil {\n\t\tif ce, ok := err.(connError); ok {\n\t\t\treturn nil, fr.connError(ce.Code, ce.Reason)\n\t\t}\n\t\treturn nil, err\n\t}\n\tfr.lastFrame = f\n\tif fr.logReads {\n\t\tfr.debugReadLoggerf(\"http2: Framer %p: read %v\", fr, summarizeFrame(f))\n\t}\n\tif fh.Type == FrameHeaders && fr.ReadMetaHeaders != nil {\n\t\treturn fr.readMetaFrame(f.(*HeadersFrame))\n\t}\n\treturn f, nil\n}\n\n// ReadFrame reads a single frame. The returned Frame is only valid\n// until the next call to ReadFrame or ReadFrameBodyForHeader.\n//\n// If the frame is larger than previously set with SetMaxReadFrameSize, the\n// returned error is ErrFrameTooLarge. Other errors may be of type\n// ConnectionError, StreamError, or anything else from the underlying\n// reader.\n//\n// If ReadFrame returns an error and a non-nil Frame, the Frame's StreamID\n// indicates the stream responsible for the error.\nfunc (fr *Framer) ReadFrame() (Frame, error) {\n\tfh, err := fr.ReadFrameHeader()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn fr.ReadFrameForHeader(fh)\n}\n\n// connError returns ConnectionError(code) but first\n// stashes away a public reason to the caller can optionally relay it\n// to the peer before hanging up on them. This might help others debug\n// their implementations.\nfunc (fr *Framer) connError(code ErrCode, reason string) error {\n\tfr.errDetail = errors.New(reason)\n\treturn ConnectionError(code)\n}\n\n// checkFrameOrder reports an error if f is an invalid frame to return\n// next from ReadFrame. Mostly it checks whether HEADERS and\n// CONTINUATION frames are contiguous.\nfunc (fr *Framer) checkFrameOrder(fh FrameHeader) error {\n\tlastType := fr.lastFrameType\n\tfr.lastFrameType = fh.Type\n\tif fr.AllowIllegalReads {\n\t\treturn nil\n\t}\n\n\tif fr.lastHeaderStream != 0 {\n\t\tif fh.Type != FrameContinuation {\n\t\t\treturn fr.connError(ErrCodeProtocol,\n\t\t\t\tfmt.Sprintf(\"got %s for stream %d; expected CONTINUATION following %s for stream %d\",\n\t\t\t\t\tfh.Type, fh.StreamID,\n\t\t\t\t\tlastType, fr.lastHeaderStream))\n\t\t}\n\t\tif fh.StreamID != fr.lastHeaderStream {\n\t\t\treturn fr.connError(ErrCodeProtocol,\n\t\t\t\tfmt.Sprintf(\"got CONTINUATION for stream %d; expected stream %d\",\n\t\t\t\t\tfh.StreamID, fr.lastHeaderStream))\n\t\t}\n\t} else if fh.Type == FrameContinuation {\n\t\treturn fr.connError(ErrCodeProtocol, fmt.Sprintf(\"unexpected CONTINUATION for stream %d\", fh.StreamID))\n\t}\n\n\tswitch fh.Type {\n\tcase FrameHeaders, FrameContinuation:\n\t\tif fh.Flags.Has(FlagHeadersEndHeaders) {\n\t\t\tfr.lastHeaderStream = 0\n\t\t} else {\n\t\t\tfr.lastHeaderStream = fh.StreamID\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// A DataFrame conveys arbitrary, variable-length sequences of octets\n// associated with a stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1\ntype DataFrame struct {\n\tFrameHeader\n\tdata []byte\n}\n\nfunc (f *DataFrame) StreamEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagDataEndStream)\n}\n\n// Data returns the frame's data octets, not including any padding\n// size byte or padding suffix bytes.\n// The caller must not retain the returned memory past the next\n// call to ReadFrame.\nfunc (f *DataFrame) Data() []byte {\n\tf.checkValid()\n\treturn f.data\n}\n\nfunc parseDataFrame(fc *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {\n\tif fh.StreamID == 0 {\n\t\t// DATA frames MUST be associated with a stream. If a\n\t\t// DATA frame is received whose stream identifier\n\t\t// field is 0x0, the recipient MUST respond with a\n\t\t// connection error (Section 5.4.1) of type\n\t\t// PROTOCOL_ERROR.\n\t\tcountError(\"frame_data_stream_0\")\n\t\treturn nil, connError{ErrCodeProtocol, \"DATA frame with stream ID 0\"}\n\t}\n\tf := fc.getDataFrame()\n\tf.FrameHeader = fh\n\n\tvar padSize byte\n\tif fh.Flags.Has(FlagDataPadded) {\n\t\tvar err error\n\t\tpayload, padSize, err = readByte(payload)\n\t\tif err != nil {\n\t\t\tcountError(\"frame_data_pad_byte_short\")\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif int(padSize) > len(payload) {\n\t\t// If the length of the padding is greater than the\n\t\t// length of the frame payload, the recipient MUST\n\t\t// treat this as a connection error.\n\t\t// Filed: https://github.com/http2/http2-spec/issues/610\n\t\tcountError(\"frame_data_pad_too_big\")\n\t\treturn nil, connError{ErrCodeProtocol, \"pad size larger than data payload\"}\n\t}\n\tf.data = payload[:len(payload)-int(padSize)]\n\treturn f, nil\n}\n\nvar (\n\terrStreamID    = errors.New(\"invalid stream ID\")\n\terrDepStreamID = errors.New(\"invalid dependent stream ID\")\n\terrPadLength   = errors.New(\"pad length too large\")\n\terrPadBytes    = errors.New(\"padding bytes must all be zeros unless AllowIllegalWrites is enabled\")\n)\n\nfunc validStreamIDOrZero(streamID uint32) bool {\n\treturn streamID&(1<<31) == 0\n}\n\nfunc validStreamID(streamID uint32) bool {\n\treturn streamID != 0 && streamID&(1<<31) == 0\n}\n\n// WriteData writes a DATA frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility not to violate the maximum frame size\n// and to not call other Write methods concurrently.\nfunc (f *Framer) WriteData(streamID uint32, endStream bool, data []byte) error {\n\treturn f.WriteDataPadded(streamID, endStream, data, nil)\n}\n\n// WriteDataPadded writes a DATA frame with optional padding.\n//\n// If pad is nil, the padding bit is not sent.\n// The length of pad must not exceed 255 bytes.\n// The bytes of pad must all be zero, unless f.AllowIllegalWrites is set.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility not to violate the maximum frame size\n// and to not call other Write methods concurrently.\nfunc (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {\n\tif err := f.startWriteDataPadded(streamID, endStream, data, pad); err != nil {\n\t\treturn err\n\t}\n\treturn f.endWrite()\n}\n\n// startWriteDataPadded is WriteDataPadded, but only writes the frame to the Framer's internal buffer.\n// The caller should call endWrite to flush the frame to the underlying writer.\nfunc (f *Framer) startWriteDataPadded(streamID uint32, endStream bool, data, pad []byte) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tif len(pad) > 0 {\n\t\tif len(pad) > 255 {\n\t\t\treturn errPadLength\n\t\t}\n\t\tif !f.AllowIllegalWrites {\n\t\t\tfor _, b := range pad {\n\t\t\t\tif b != 0 {\n\t\t\t\t\t// \"Padding octets MUST be set to zero when sending.\"\n\t\t\t\t\treturn errPadBytes\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tvar flags Flags\n\tif endStream {\n\t\tflags |= FlagDataEndStream\n\t}\n\tif pad != nil {\n\t\tflags |= FlagDataPadded\n\t}\n\tf.startWrite(FrameData, flags, streamID)\n\tif pad != nil {\n\t\tf.wbuf = append(f.wbuf, byte(len(pad)))\n\t}\n\tf.wbuf = append(f.wbuf, data...)\n\tf.wbuf = append(f.wbuf, pad...)\n\treturn nil\n}\n\n// A SettingsFrame conveys configuration parameters that affect how\n// endpoints communicate, such as preferences and constraints on peer\n// behavior.\n//\n// See https://httpwg.org/specs/rfc7540.html#SETTINGS\ntype SettingsFrame struct {\n\tFrameHeader\n\tp []byte\n}\n\nfunc parseSettingsFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif fh.Flags.Has(FlagSettingsAck) && fh.Length > 0 {\n\t\t// When this (ACK 0x1) bit is set, the payload of the\n\t\t// SETTINGS frame MUST be empty. Receipt of a\n\t\t// SETTINGS frame with the ACK flag set and a length\n\t\t// field value other than 0 MUST be treated as a\n\t\t// connection error (Section 5.4.1) of type\n\t\t// FRAME_SIZE_ERROR.\n\t\tcountError(\"frame_settings_ack_with_length\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tif fh.StreamID != 0 {\n\t\t// SETTINGS frames always apply to a connection,\n\t\t// never a single stream. The stream identifier for a\n\t\t// SETTINGS frame MUST be zero (0x0).  If an endpoint\n\t\t// receives a SETTINGS frame whose stream identifier\n\t\t// field is anything other than 0x0, the endpoint MUST\n\t\t// respond with a connection error (Section 5.4.1) of\n\t\t// type PROTOCOL_ERROR.\n\t\tcountError(\"frame_settings_has_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tif len(p)%6 != 0 {\n\t\tcountError(\"frame_settings_mod_6\")\n\t\t// Expecting even number of 6 byte settings.\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tf := &SettingsFrame{FrameHeader: fh, p: p}\n\tif v, ok := f.Value(SettingInitialWindowSize); ok && v > (1<<31)-1 {\n\t\tcountError(\"frame_settings_window_size_too_big\")\n\t\t// Values above the maximum flow control window size of 2^31 - 1 MUST\n\t\t// be treated as a connection error (Section 5.4.1) of type\n\t\t// FLOW_CONTROL_ERROR.\n\t\treturn nil, ConnectionError(ErrCodeFlowControl)\n\t}\n\treturn f, nil\n}\n\nfunc (f *SettingsFrame) IsAck() bool {\n\treturn f.FrameHeader.Flags.Has(FlagSettingsAck)\n}\n\nfunc (f *SettingsFrame) Value(id SettingID) (v uint32, ok bool) {\n\tf.checkValid()\n\tfor i := 0; i < f.NumSettings(); i++ {\n\t\tif s := f.Setting(i); s.ID == id {\n\t\t\treturn s.Val, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// Setting returns the setting from the frame at the given 0-based index.\n// The index must be >= 0 and less than f.NumSettings().\nfunc (f *SettingsFrame) Setting(i int) Setting {\n\tbuf := f.p\n\treturn Setting{\n\t\tID:  SettingID(binary.BigEndian.Uint16(buf[i*6 : i*6+2])),\n\t\tVal: binary.BigEndian.Uint32(buf[i*6+2 : i*6+6]),\n\t}\n}\n\nfunc (f *SettingsFrame) NumSettings() int { return len(f.p) / 6 }\n\n// HasDuplicates reports whether f contains any duplicate setting IDs.\nfunc (f *SettingsFrame) HasDuplicates() bool {\n\tnum := f.NumSettings()\n\tif num == 0 {\n\t\treturn false\n\t}\n\t// If it's small enough (the common case), just do the n^2\n\t// thing and avoid a map allocation.\n\tif num < 10 {\n\t\tfor i := 0; i < num; i++ {\n\t\t\tidi := f.Setting(i).ID\n\t\t\tfor j := i + 1; j < num; j++ {\n\t\t\t\tidj := f.Setting(j).ID\n\t\t\t\tif idi == idj {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\tseen := map[SettingID]bool{}\n\tfor i := 0; i < num; i++ {\n\t\tid := f.Setting(i).ID\n\t\tif seen[id] {\n\t\t\treturn true\n\t\t}\n\t\tseen[id] = true\n\t}\n\treturn false\n}\n\n// ForeachSetting runs fn for each setting.\n// It stops and returns the first error.\nfunc (f *SettingsFrame) ForeachSetting(fn func(Setting) error) error {\n\tf.checkValid()\n\tfor i := 0; i < f.NumSettings(); i++ {\n\t\tif err := fn(f.Setting(i)); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\n// WriteSettings writes a SETTINGS frame with zero or more settings\n// specified and the ACK bit not set.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteSettings(settings ...Setting) error {\n\tf.startWrite(FrameSettings, 0, 0)\n\tfor _, s := range settings {\n\t\tf.writeUint16(uint16(s.ID))\n\t\tf.writeUint32(s.Val)\n\t}\n\treturn f.endWrite()\n}\n\n// WriteSettingsAck writes an empty SETTINGS frame with the ACK bit set.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteSettingsAck() error {\n\tf.startWrite(FrameSettings, FlagSettingsAck, 0)\n\treturn f.endWrite()\n}\n\n// A PingFrame is a mechanism for measuring a minimal round trip time\n// from the sender, as well as determining whether an idle connection\n// is still functional.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7\ntype PingFrame struct {\n\tFrameHeader\n\tData [8]byte\n}\n\nfunc (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }\n\nfunc parsePingFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {\n\tif len(payload) != 8 {\n\t\tcountError(\"frame_ping_length\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tif fh.StreamID != 0 {\n\t\tcountError(\"frame_ping_has_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tf := &PingFrame{FrameHeader: fh}\n\tcopy(f.Data[:], payload)\n\treturn f, nil\n}\n\nfunc (f *Framer) WritePing(ack bool, data [8]byte) error {\n\tvar flags Flags\n\tif ack {\n\t\tflags = FlagPingAck\n\t}\n\tf.startWrite(FramePing, flags, 0)\n\tf.writeBytes(data[:])\n\treturn f.endWrite()\n}\n\n// A GoAwayFrame informs the remote peer to stop creating streams on this connection.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8\ntype GoAwayFrame struct {\n\tFrameHeader\n\tLastStreamID uint32\n\tErrCode      ErrCode\n\tdebugData    []byte\n}\n\n// DebugData returns any debug data in the GOAWAY frame. Its contents\n// are not defined.\n// The caller must not retain the returned memory past the next\n// call to ReadFrame.\nfunc (f *GoAwayFrame) DebugData() []byte {\n\tf.checkValid()\n\treturn f.debugData\n}\n\nfunc parseGoAwayFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif fh.StreamID != 0 {\n\t\tcountError(\"frame_goaway_has_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tif len(p) < 8 {\n\t\tcountError(\"frame_goaway_short\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\treturn &GoAwayFrame{\n\t\tFrameHeader:  fh,\n\t\tLastStreamID: binary.BigEndian.Uint32(p[:4]) & (1<<31 - 1),\n\t\tErrCode:      ErrCode(binary.BigEndian.Uint32(p[4:8])),\n\t\tdebugData:    p[8:],\n\t}, nil\n}\n\nfunc (f *Framer) WriteGoAway(maxStreamID uint32, code ErrCode, debugData []byte) error {\n\tf.startWrite(FrameGoAway, 0, 0)\n\tf.writeUint32(maxStreamID & (1<<31 - 1))\n\tf.writeUint32(uint32(code))\n\tf.writeBytes(debugData)\n\treturn f.endWrite()\n}\n\n// An UnknownFrame is the frame type returned when the frame type is unknown\n// or no specific frame type parser exists.\ntype UnknownFrame struct {\n\tFrameHeader\n\tp []byte\n}\n\n// Payload returns the frame's payload (after the header).  It is not\n// valid to call this method after a subsequent call to\n// Framer.ReadFrame, nor is it valid to retain the returned slice.\n// The memory is owned by the Framer and is invalidated when the next\n// frame is read.\nfunc (f *UnknownFrame) Payload() []byte {\n\tf.checkValid()\n\treturn f.p\n}\n\nfunc parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\treturn &UnknownFrame{fh, p}, nil\n}\n\n// A WindowUpdateFrame is used to implement flow control.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9\ntype WindowUpdateFrame struct {\n\tFrameHeader\n\tIncrement uint32 // never read with high bit set\n}\n\nfunc parseWindowUpdateFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif len(p) != 4 {\n\t\tcountError(\"frame_windowupdate_bad_len\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tinc := binary.BigEndian.Uint32(p[:4]) & 0x7fffffff // mask off high reserved bit\n\tif inc == 0 {\n\t\t// A receiver MUST treat the receipt of a\n\t\t// WINDOW_UPDATE frame with an flow control window\n\t\t// increment of 0 as a stream error (Section 5.4.2) of\n\t\t// type PROTOCOL_ERROR; errors on the connection flow\n\t\t// control window MUST be treated as a connection\n\t\t// error (Section 5.4.1).\n\t\tif fh.StreamID == 0 {\n\t\t\tcountError(\"frame_windowupdate_zero_inc_conn\")\n\t\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t\t}\n\t\tcountError(\"frame_windowupdate_zero_inc_stream\")\n\t\treturn nil, streamError(fh.StreamID, ErrCodeProtocol)\n\t}\n\treturn &WindowUpdateFrame{\n\t\tFrameHeader: fh,\n\t\tIncrement:   inc,\n\t}, nil\n}\n\n// WriteWindowUpdate writes a WINDOW_UPDATE frame.\n// The increment value must be between 1 and 2,147,483,647, inclusive.\n// If the Stream ID is zero, the window update applies to the\n// connection as a whole.\nfunc (f *Framer) WriteWindowUpdate(streamID, incr uint32) error {\n\t// \"The legal range for the increment to the flow control window is 1 to 2^31-1 (2,147,483,647) octets.\"\n\tif (incr < 1 || incr > 2147483647) && !f.AllowIllegalWrites {\n\t\treturn errors.New(\"illegal window increment value\")\n\t}\n\tf.startWrite(FrameWindowUpdate, 0, streamID)\n\tf.writeUint32(incr)\n\treturn f.endWrite()\n}\n\n// A HeadersFrame is used to open a stream and additionally carries a\n// header block fragment.\ntype HeadersFrame struct {\n\tFrameHeader\n\n\t// Priority is set if FlagHeadersPriority is set in the FrameHeader.\n\tPriority PriorityParam\n\n\theaderFragBuf []byte // not owned\n}\n\nfunc (f *HeadersFrame) HeaderBlockFragment() []byte {\n\tf.checkValid()\n\treturn f.headerFragBuf\n}\n\nfunc (f *HeadersFrame) HeadersEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagHeadersEndHeaders)\n}\n\nfunc (f *HeadersFrame) StreamEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagHeadersEndStream)\n}\n\nfunc (f *HeadersFrame) HasPriority() bool {\n\treturn f.FrameHeader.Flags.Has(FlagHeadersPriority)\n}\n\nfunc parseHeadersFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {\n\thf := &HeadersFrame{\n\t\tFrameHeader: fh,\n\t}\n\tif fh.StreamID == 0 {\n\t\t// HEADERS frames MUST be associated with a stream. If a HEADERS frame\n\t\t// is received whose stream identifier field is 0x0, the recipient MUST\n\t\t// respond with a connection error (Section 5.4.1) of type\n\t\t// PROTOCOL_ERROR.\n\t\tcountError(\"frame_headers_zero_stream\")\n\t\treturn nil, connError{ErrCodeProtocol, \"HEADERS frame with stream ID 0\"}\n\t}\n\tvar padLength uint8\n\tif fh.Flags.Has(FlagHeadersPadded) {\n\t\tif p, padLength, err = readByte(p); err != nil {\n\t\t\tcountError(\"frame_headers_pad_short\")\n\t\t\treturn\n\t\t}\n\t}\n\tif fh.Flags.Has(FlagHeadersPriority) {\n\t\tvar v uint32\n\t\tp, v, err = readUint32(p)\n\t\tif err != nil {\n\t\t\tcountError(\"frame_headers_prio_short\")\n\t\t\treturn nil, err\n\t\t}\n\t\thf.Priority.StreamDep = v & 0x7fffffff\n\t\thf.Priority.Exclusive = (v != hf.Priority.StreamDep) // high bit was set\n\t\tp, hf.Priority.Weight, err = readByte(p)\n\t\tif err != nil {\n\t\t\tcountError(\"frame_headers_prio_weight_short\")\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif len(p)-int(padLength) < 0 {\n\t\tcountError(\"frame_headers_pad_too_big\")\n\t\treturn nil, streamError(fh.StreamID, ErrCodeProtocol)\n\t}\n\thf.headerFragBuf = p[:len(p)-int(padLength)]\n\treturn hf, nil\n}\n\n// HeadersFrameParam are the parameters for writing a HEADERS frame.\ntype HeadersFrameParam struct {\n\t// StreamID is the required Stream ID to initiate.\n\tStreamID uint32\n\t// BlockFragment is part (or all) of a Header Block.\n\tBlockFragment []byte\n\n\t// EndStream indicates that the header block is the last that\n\t// the endpoint will send for the identified stream. Setting\n\t// this flag causes the stream to enter one of \"half closed\"\n\t// states.\n\tEndStream bool\n\n\t// EndHeaders indicates that this frame contains an entire\n\t// header block and is not followed by any\n\t// CONTINUATION frames.\n\tEndHeaders bool\n\n\t// PadLength is the optional number of bytes of zeros to add\n\t// to this frame.\n\tPadLength uint8\n\n\t// Priority, if non-zero, includes stream priority information\n\t// in the HEADER frame.\n\tPriority PriorityParam\n}\n\n// WriteHeaders writes a single HEADERS frame.\n//\n// This is a low-level header writing method. Encoding headers and\n// splitting them into any necessary CONTINUATION frames is handled\n// elsewhere.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteHeaders(p HeadersFrameParam) error {\n\tif !validStreamID(p.StreamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tvar flags Flags\n\tif p.PadLength != 0 {\n\t\tflags |= FlagHeadersPadded\n\t}\n\tif p.EndStream {\n\t\tflags |= FlagHeadersEndStream\n\t}\n\tif p.EndHeaders {\n\t\tflags |= FlagHeadersEndHeaders\n\t}\n\tif !p.Priority.IsZero() {\n\t\tflags |= FlagHeadersPriority\n\t}\n\tf.startWrite(FrameHeaders, flags, p.StreamID)\n\tif p.PadLength != 0 {\n\t\tf.writeByte(p.PadLength)\n\t}\n\tif !p.Priority.IsZero() {\n\t\tv := p.Priority.StreamDep\n\t\tif !validStreamIDOrZero(v) && !f.AllowIllegalWrites {\n\t\t\treturn errDepStreamID\n\t\t}\n\t\tif p.Priority.Exclusive {\n\t\t\tv |= 1 << 31\n\t\t}\n\t\tf.writeUint32(v)\n\t\tf.writeByte(p.Priority.Weight)\n\t}\n\tf.wbuf = append(f.wbuf, p.BlockFragment...)\n\tf.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)\n\treturn f.endWrite()\n}\n\n// A PriorityFrame specifies the sender-advised priority of a stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3\ntype PriorityFrame struct {\n\tFrameHeader\n\tPriorityParam\n}\n\nvar defaultRFC9218Priority = PriorityParam{\n\tincremental: 0,\n\turgency:     3,\n}\n\n// Note that HTTP/2 has had two different prioritization schemes, and\n// PriorityParam struct below is a superset of both schemes. The exported\n// symbols are from RFC 7540 and the non-exported ones are from RFC 9218.\n\n// PriorityParam are the stream prioritization parameters.\ntype PriorityParam struct {\n\t// StreamDep is a 31-bit stream identifier for the\n\t// stream that this stream depends on. Zero means no\n\t// dependency.\n\tStreamDep uint32\n\n\t// Exclusive is whether the dependency is exclusive.\n\tExclusive bool\n\n\t// Weight is the stream's zero-indexed weight. It should be\n\t// set together with StreamDep, or neither should be set. Per\n\t// the spec, \"Add one to the value to obtain a weight between\n\t// 1 and 256.\"\n\tWeight uint8\n\n\t// \"The urgency (u) parameter value is Integer (see Section 3.3.1 of\n\t// [STRUCTURED-FIELDS]), between 0 and 7 inclusive, in descending order of\n\t// priority. The default is 3.\"\n\turgency uint8\n\n\t// \"The incremental (i) parameter value is Boolean (see Section 3.3.6 of\n\t// [STRUCTURED-FIELDS]). It indicates if an HTTP response can be processed\n\t// incrementally, i.e., provide some meaningful output as chunks of the\n\t// response arrive.\"\n\t//\n\t// We use uint8 (i.e. 0 is false, 1 is true) instead of bool so we can\n\t// avoid unnecessary type conversions and because either type takes 1 byte.\n\tincremental uint8\n}\n\nfunc (p PriorityParam) IsZero() bool {\n\treturn p == PriorityParam{}\n}\n\nfunc parsePriorityFrame(_ *frameCache, fh FrameHeader, countError func(string), payload []byte) (Frame, error) {\n\tif fh.StreamID == 0 {\n\t\tcountError(\"frame_priority_zero_stream\")\n\t\treturn nil, connError{ErrCodeProtocol, \"PRIORITY frame with stream ID 0\"}\n\t}\n\tif len(payload) != 5 {\n\t\tcountError(\"frame_priority_bad_length\")\n\t\treturn nil, connError{ErrCodeFrameSize, fmt.Sprintf(\"PRIORITY frame payload size was %d; want 5\", len(payload))}\n\t}\n\tv := binary.BigEndian.Uint32(payload[:4])\n\tstreamID := v & 0x7fffffff // mask off high bit\n\treturn &PriorityFrame{\n\t\tFrameHeader: fh,\n\t\tPriorityParam: PriorityParam{\n\t\t\tWeight:    payload[4],\n\t\t\tStreamDep: streamID,\n\t\t\tExclusive: streamID != v, // was high bit set?\n\t\t},\n\t}, nil\n}\n\n// WritePriority writes a PRIORITY frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WritePriority(streamID uint32, p PriorityParam) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tif !validStreamIDOrZero(p.StreamDep) {\n\t\treturn errDepStreamID\n\t}\n\tf.startWrite(FramePriority, 0, streamID)\n\tv := p.StreamDep\n\tif p.Exclusive {\n\t\tv |= 1 << 31\n\t}\n\tf.writeUint32(v)\n\tf.writeByte(p.Weight)\n\treturn f.endWrite()\n}\n\n// A RSTStreamFrame allows for abnormal termination of a stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4\ntype RSTStreamFrame struct {\n\tFrameHeader\n\tErrCode ErrCode\n}\n\nfunc parseRSTStreamFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif len(p) != 4 {\n\t\tcountError(\"frame_rststream_bad_len\")\n\t\treturn nil, ConnectionError(ErrCodeFrameSize)\n\t}\n\tif fh.StreamID == 0 {\n\t\tcountError(\"frame_rststream_zero_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\treturn &RSTStreamFrame{fh, ErrCode(binary.BigEndian.Uint32(p[:4]))}, nil\n}\n\n// WriteRSTStream writes a RST_STREAM frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tf.startWrite(FrameRSTStream, 0, streamID)\n\tf.writeUint32(uint32(code))\n\treturn f.endWrite()\n}\n\n// A ContinuationFrame is used to continue a sequence of header block fragments.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10\ntype ContinuationFrame struct {\n\tFrameHeader\n\theaderFragBuf []byte\n}\n\nfunc parseContinuationFrame(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (Frame, error) {\n\tif fh.StreamID == 0 {\n\t\tcountError(\"frame_continuation_zero_stream\")\n\t\treturn nil, connError{ErrCodeProtocol, \"CONTINUATION frame with stream ID 0\"}\n\t}\n\treturn &ContinuationFrame{fh, p}, nil\n}\n\nfunc (f *ContinuationFrame) HeaderBlockFragment() []byte {\n\tf.checkValid()\n\treturn f.headerFragBuf\n}\n\nfunc (f *ContinuationFrame) HeadersEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagContinuationEndHeaders)\n}\n\n// WriteContinuation writes a CONTINUATION frame.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlockFragment []byte) error {\n\tif !validStreamID(streamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tvar flags Flags\n\tif endHeaders {\n\t\tflags |= FlagContinuationEndHeaders\n\t}\n\tf.startWrite(FrameContinuation, flags, streamID)\n\tf.wbuf = append(f.wbuf, headerBlockFragment...)\n\treturn f.endWrite()\n}\n\n// A PushPromiseFrame is used to initiate a server stream.\n// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6\ntype PushPromiseFrame struct {\n\tFrameHeader\n\tPromiseID     uint32\n\theaderFragBuf []byte // not owned\n}\n\nfunc (f *PushPromiseFrame) HeaderBlockFragment() []byte {\n\tf.checkValid()\n\treturn f.headerFragBuf\n}\n\nfunc (f *PushPromiseFrame) HeadersEnded() bool {\n\treturn f.FrameHeader.Flags.Has(FlagPushPromiseEndHeaders)\n}\n\nfunc parsePushPromise(_ *frameCache, fh FrameHeader, countError func(string), p []byte) (_ Frame, err error) {\n\tpp := &PushPromiseFrame{\n\t\tFrameHeader: fh,\n\t}\n\tif pp.StreamID == 0 {\n\t\t// PUSH_PROMISE frames MUST be associated with an existing,\n\t\t// peer-initiated stream. The stream identifier of a\n\t\t// PUSH_PROMISE frame indicates the stream it is associated\n\t\t// with. If the stream identifier field specifies the value\n\t\t// 0x0, a recipient MUST respond with a connection error\n\t\t// (Section 5.4.1) of type PROTOCOL_ERROR.\n\t\tcountError(\"frame_pushpromise_zero_stream\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\t// The PUSH_PROMISE frame includes optional padding.\n\t// Padding fields and flags are identical to those defined for DATA frames\n\tvar padLength uint8\n\tif fh.Flags.Has(FlagPushPromisePadded) {\n\t\tif p, padLength, err = readByte(p); err != nil {\n\t\t\tcountError(\"frame_pushpromise_pad_short\")\n\t\t\treturn\n\t\t}\n\t}\n\n\tp, pp.PromiseID, err = readUint32(p)\n\tif err != nil {\n\t\tcountError(\"frame_pushpromise_promiseid_short\")\n\t\treturn\n\t}\n\tpp.PromiseID = pp.PromiseID & (1<<31 - 1)\n\n\tif int(padLength) > len(p) {\n\t\t// like the DATA frame, error out if padding is longer than the body.\n\t\tcountError(\"frame_pushpromise_pad_too_big\")\n\t\treturn nil, ConnectionError(ErrCodeProtocol)\n\t}\n\tpp.headerFragBuf = p[:len(p)-int(padLength)]\n\treturn pp, nil\n}\n\n// PushPromiseParam are the parameters for writing a PUSH_PROMISE frame.\ntype PushPromiseParam struct {\n\t// StreamID is the required Stream ID to initiate.\n\tStreamID uint32\n\n\t// PromiseID is the required Stream ID which this\n\t// Push Promises\n\tPromiseID uint32\n\n\t// BlockFragment is part (or all) of a Header Block.\n\tBlockFragment []byte\n\n\t// EndHeaders indicates that this frame contains an entire\n\t// header block and is not followed by any\n\t// CONTINUATION frames.\n\tEndHeaders bool\n\n\t// PadLength is the optional number of bytes of zeros to add\n\t// to this frame.\n\tPadLength uint8\n}\n\n// WritePushPromise writes a single PushPromise Frame.\n//\n// As with Header Frames, This is the low level call for writing\n// individual frames. Continuation frames are handled elsewhere.\n//\n// It will perform exactly one Write to the underlying Writer.\n// It is the caller's responsibility to not call other Write methods concurrently.\nfunc (f *Framer) WritePushPromise(p PushPromiseParam) error {\n\tif !validStreamID(p.StreamID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tvar flags Flags\n\tif p.PadLength != 0 {\n\t\tflags |= FlagPushPromisePadded\n\t}\n\tif p.EndHeaders {\n\t\tflags |= FlagPushPromiseEndHeaders\n\t}\n\tf.startWrite(FramePushPromise, flags, p.StreamID)\n\tif p.PadLength != 0 {\n\t\tf.writeByte(p.PadLength)\n\t}\n\tif !validStreamID(p.PromiseID) && !f.AllowIllegalWrites {\n\t\treturn errStreamID\n\t}\n\tf.writeUint32(p.PromiseID)\n\tf.wbuf = append(f.wbuf, p.BlockFragment...)\n\tf.wbuf = append(f.wbuf, padZeros[:p.PadLength]...)\n\treturn f.endWrite()\n}\n\n// WriteRawFrame writes a raw frame. This can be used to write\n// extension frames unknown to this package.\nfunc (f *Framer) WriteRawFrame(t FrameType, flags Flags, streamID uint32, payload []byte) error {\n\tf.startWrite(t, flags, streamID)\n\tf.writeBytes(payload)\n\treturn f.endWrite()\n}\n\nfunc readByte(p []byte) (remain []byte, b byte, err error) {\n\tif len(p) == 0 {\n\t\treturn nil, 0, io.ErrUnexpectedEOF\n\t}\n\treturn p[1:], p[0], nil\n}\n\nfunc readUint32(p []byte) (remain []byte, v uint32, err error) {\n\tif len(p) < 4 {\n\t\treturn nil, 0, io.ErrUnexpectedEOF\n\t}\n\treturn p[4:], binary.BigEndian.Uint32(p[:4]), nil\n}\n\ntype streamEnder interface {\n\tStreamEnded() bool\n}\n\ntype headersEnder interface {\n\tHeadersEnded() bool\n}\n\ntype headersOrContinuation interface {\n\theadersEnder\n\tHeaderBlockFragment() []byte\n}\n\n// A MetaHeadersFrame is the representation of one HEADERS frame and\n// zero or more contiguous CONTINUATION frames and the decoding of\n// their HPACK-encoded contents.\n//\n// This type of frame does not appear on the wire and is only returned\n// by the Framer when Framer.ReadMetaHeaders is set.\ntype MetaHeadersFrame struct {\n\t*HeadersFrame\n\n\t// Fields are the fields contained in the HEADERS and\n\t// CONTINUATION frames. The underlying slice is owned by the\n\t// Framer and must not be retained after the next call to\n\t// ReadFrame.\n\t//\n\t// Fields are guaranteed to be in the correct http2 order and\n\t// not have unknown pseudo header fields or invalid header\n\t// field names or values. Required pseudo header fields may be\n\t// missing, however. Use the MetaHeadersFrame.Pseudo accessor\n\t// method access pseudo headers.\n\tFields []hpack.HeaderField\n\n\t// Truncated is whether the max header list size limit was hit\n\t// and Fields is incomplete. The hpack decoder state is still\n\t// valid, however.\n\tTruncated bool\n}\n\n// PseudoValue returns the given pseudo header field's value.\n// The provided pseudo field should not contain the leading colon.\nfunc (mh *MetaHeadersFrame) PseudoValue(pseudo string) string {\n\tfor _, hf := range mh.Fields {\n\t\tif !hf.IsPseudo() {\n\t\t\treturn \"\"\n\t\t}\n\t\tif hf.Name[1:] == pseudo {\n\t\t\treturn hf.Value\n\t\t}\n\t}\n\treturn \"\"\n}\n\n// RegularFields returns the regular (non-pseudo) header fields of mh.\n// The caller does not own the returned slice.\nfunc (mh *MetaHeadersFrame) RegularFields() []hpack.HeaderField {\n\tfor i, hf := range mh.Fields {\n\t\tif !hf.IsPseudo() {\n\t\t\treturn mh.Fields[i:]\n\t\t}\n\t}\n\treturn nil\n}\n\n// PseudoFields returns the pseudo header fields of mh.\n// The caller does not own the returned slice.\nfunc (mh *MetaHeadersFrame) PseudoFields() []hpack.HeaderField {\n\tfor i, hf := range mh.Fields {\n\t\tif !hf.IsPseudo() {\n\t\t\treturn mh.Fields[:i]\n\t\t}\n\t}\n\treturn mh.Fields\n}\n\nfunc (mh *MetaHeadersFrame) checkPseudos() error {\n\tvar isRequest, isResponse bool\n\tpf := mh.PseudoFields()\n\tfor i, hf := range pf {\n\t\tswitch hf.Name {\n\t\tcase \":method\", \":path\", \":scheme\", \":authority\", \":protocol\":\n\t\t\tisRequest = true\n\t\tcase \":status\":\n\t\t\tisResponse = true\n\t\tdefault:\n\t\t\treturn pseudoHeaderError(hf.Name)\n\t\t}\n\t\t// Check for duplicates.\n\t\t// This would be a bad algorithm, but N is 5.\n\t\t// And this doesn't allocate.\n\t\tfor _, hf2 := range pf[:i] {\n\t\t\tif hf.Name == hf2.Name {\n\t\t\t\treturn duplicatePseudoHeaderError(hf.Name)\n\t\t\t}\n\t\t}\n\t}\n\tif isRequest && isResponse {\n\t\treturn errMixPseudoHeaderTypes\n\t}\n\treturn nil\n}\n\nfunc (fr *Framer) maxHeaderStringLen() int {\n\tv := int(fr.maxHeaderListSize())\n\tif v < 0 {\n\t\t// If maxHeaderListSize overflows an int, use no limit (0).\n\t\treturn 0\n\t}\n\treturn v\n}\n\n// readMetaFrame returns 0 or more CONTINUATION frames from fr and\n// merge them into the provided hf and returns a MetaHeadersFrame\n// with the decoded hpack values.\nfunc (fr *Framer) readMetaFrame(hf *HeadersFrame) (Frame, error) {\n\tif fr.AllowIllegalReads {\n\t\treturn nil, errors.New(\"illegal use of AllowIllegalReads with ReadMetaHeaders\")\n\t}\n\tmh := &MetaHeadersFrame{\n\t\tHeadersFrame: hf,\n\t}\n\tvar remainSize = fr.maxHeaderListSize()\n\tvar sawRegular bool\n\n\tvar invalid error // pseudo header field errors\n\thdec := fr.ReadMetaHeaders\n\thdec.SetEmitEnabled(true)\n\thdec.SetMaxStringLength(fr.maxHeaderStringLen())\n\thdec.SetEmitFunc(func(hf hpack.HeaderField) {\n\t\tif VerboseLogs && fr.logReads {\n\t\t\tfr.debugReadLoggerf(\"http2: decoded hpack field %+v\", hf)\n\t\t}\n\t\tif !httpguts.ValidHeaderFieldValue(hf.Value) {\n\t\t\t// Don't include the value in the error, because it may be sensitive.\n\t\t\tinvalid = headerFieldValueError(hf.Name)\n\t\t}\n\t\tisPseudo := strings.HasPrefix(hf.Name, \":\")\n\t\tif isPseudo {\n\t\t\tif sawRegular {\n\t\t\t\tinvalid = errPseudoAfterRegular\n\t\t\t}\n\t\t} else {\n\t\t\tsawRegular = true\n\t\t\tif !validWireHeaderFieldName(hf.Name) {\n\t\t\t\tinvalid = headerFieldNameError(hf.Name)\n\t\t\t}\n\t\t}\n\n\t\tif invalid != nil {\n\t\t\thdec.SetEmitEnabled(false)\n\t\t\treturn\n\t\t}\n\n\t\tsize := hf.Size()\n\t\tif size > remainSize {\n\t\t\thdec.SetEmitEnabled(false)\n\t\t\tmh.Truncated = true\n\t\t\tremainSize = 0\n\t\t\treturn\n\t\t}\n\t\tremainSize -= size\n\n\t\tmh.Fields = append(mh.Fields, hf)\n\t})\n\t// Lose reference to MetaHeadersFrame:\n\tdefer hdec.SetEmitFunc(func(hf hpack.HeaderField) {})\n\n\tvar hc headersOrContinuation = hf\n\tfor {\n\t\tfrag := hc.HeaderBlockFragment()\n\n\t\t// Avoid parsing large amounts of headers that we will then discard.\n\t\t// If the sender exceeds the max header list size by too much,\n\t\t// skip parsing the fragment and close the connection.\n\t\t//\n\t\t// \"Too much\" is either any CONTINUATION frame after we've already\n\t\t// exceeded the max header list size (in which case remainSize is 0),\n\t\t// or a frame whose encoded size is more than twice the remaining\n\t\t// header list bytes we're willing to accept.\n\t\tif int64(len(frag)) > int64(2*remainSize) {\n\t\t\tif VerboseLogs {\n\t\t\t\tlog.Printf(\"http2: header list too large\")\n\t\t\t}\n\t\t\t// It would be nice to send a RST_STREAM before sending the GOAWAY,\n\t\t\t// but the structure of the server's frame writer makes this difficult.\n\t\t\treturn mh, ConnectionError(ErrCodeProtocol)\n\t\t}\n\n\t\t// Also close the connection after any CONTINUATION frame following an\n\t\t// invalid header, since we stop tracking the size of the headers after\n\t\t// an invalid one.\n\t\tif invalid != nil {\n\t\t\tif VerboseLogs {\n\t\t\t\tlog.Printf(\"http2: invalid header: %v\", invalid)\n\t\t\t}\n\t\t\t// It would be nice to send a RST_STREAM before sending the GOAWAY,\n\t\t\t// but the structure of the server's frame writer makes this difficult.\n\t\t\treturn mh, ConnectionError(ErrCodeProtocol)\n\t\t}\n\n\t\tif _, err := hdec.Write(frag); err != nil {\n\t\t\treturn mh, ConnectionError(ErrCodeCompression)\n\t\t}\n\n\t\tif hc.HeadersEnded() {\n\t\t\tbreak\n\t\t}\n\t\tif f, err := fr.ReadFrame(); err != nil {\n\t\t\treturn nil, err\n\t\t} else {\n\t\t\thc = f.(*ContinuationFrame) // guaranteed by checkFrameOrder\n\t\t}\n\t}\n\n\tmh.HeadersFrame.headerFragBuf = nil\n\tmh.HeadersFrame.invalidate()\n\n\tif err := hdec.Close(); err != nil {\n\t\treturn mh, ConnectionError(ErrCodeCompression)\n\t}\n\tif invalid != nil {\n\t\tfr.errDetail = invalid\n\t\tif VerboseLogs {\n\t\t\tlog.Printf(\"http2: invalid header: %v\", invalid)\n\t\t}\n\t\treturn nil, StreamError{mh.StreamID, ErrCodeProtocol, invalid}\n\t}\n\tif err := mh.checkPseudos(); err != nil {\n\t\tfr.errDetail = err\n\t\tif VerboseLogs {\n\t\t\tlog.Printf(\"http2: invalid pseudo headers: %v\", err)\n\t\t}\n\t\treturn nil, StreamError{mh.StreamID, ErrCodeProtocol, err}\n\t}\n\treturn mh, nil\n}\n\nfunc summarizeFrame(f Frame) string {\n\tvar buf bytes.Buffer\n\tf.Header().writeDebug(&buf)\n\tswitch f := f.(type) {\n\tcase *SettingsFrame:\n\t\tn := 0\n\t\tf.ForeachSetting(func(s Setting) error {\n\t\t\tn++\n\t\t\tif n == 1 {\n\t\t\t\tbuf.WriteString(\", settings:\")\n\t\t\t}\n\t\t\tfmt.Fprintf(&buf, \" %v=%v,\", s.ID, s.Val)\n\t\t\treturn nil\n\t\t})\n\t\tif n > 0 {\n\t\t\tbuf.Truncate(buf.Len() - 1) // remove trailing comma\n\t\t}\n\tcase *DataFrame:\n\t\tdata := f.Data()\n\t\tconst max = 256\n\t\tif len(data) > max {\n\t\t\tdata = data[:max]\n\t\t}\n\t\tfmt.Fprintf(&buf, \" data=%q\", data)\n\t\tif len(f.Data()) > max {\n\t\t\tfmt.Fprintf(&buf, \" (%d bytes omitted)\", len(f.Data())-max)\n\t\t}\n\tcase *WindowUpdateFrame:\n\t\tif f.StreamID == 0 {\n\t\t\tbuf.WriteString(\" (conn)\")\n\t\t}\n\t\tfmt.Fprintf(&buf, \" incr=%v\", f.Increment)\n\tcase *PingFrame:\n\t\tfmt.Fprintf(&buf, \" ping=%q\", f.Data[:])\n\tcase *GoAwayFrame:\n\t\tfmt.Fprintf(&buf, \" LastStreamID=%v ErrCode=%v Debug=%q\",\n\t\t\tf.LastStreamID, f.ErrCode, f.debugData)\n\tcase *RSTStreamFrame:\n\t\tfmt.Fprintf(&buf, \" ErrCode=%v\", f.ErrCode)\n\t}\n\treturn buf.String()\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/gotrack.go",
    "content": "// Copyright 2014 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// Defensive debug-only utility to track that functions run on the\n// goroutine that they're supposed to.\n\npackage http2\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"sync\"\n\t\"sync/atomic\"\n)\n\nvar DebugGoroutines = os.Getenv(\"DEBUG_HTTP2_GOROUTINES\") == \"1\"\n\n// Setting DebugGoroutines to false during a test to disable goroutine debugging\n// results in race detector complaints when a test leaves goroutines running before\n// returning. Tests shouldn't do this, of course, but when they do it generally shows\n// up as infrequent, hard-to-debug flakes. (See #66519.)\n//\n// Disable goroutine debugging during individual tests with an atomic bool.\n// (Note that it's safe to enable/disable debugging mid-test, so the actual race condition\n// here is harmless.)\nvar disableDebugGoroutines atomic.Bool\n\ntype goroutineLock uint64\n\nfunc newGoroutineLock() goroutineLock {\n\tif !DebugGoroutines || disableDebugGoroutines.Load() {\n\t\treturn 0\n\t}\n\treturn goroutineLock(curGoroutineID())\n}\n\nfunc (g goroutineLock) check() {\n\tif !DebugGoroutines || disableDebugGoroutines.Load() {\n\t\treturn\n\t}\n\tif curGoroutineID() != uint64(g) {\n\t\tpanic(\"running on the wrong goroutine\")\n\t}\n}\n\nfunc (g goroutineLock) checkNotOn() {\n\tif !DebugGoroutines || disableDebugGoroutines.Load() {\n\t\treturn\n\t}\n\tif curGoroutineID() == uint64(g) {\n\t\tpanic(\"running on the wrong goroutine\")\n\t}\n}\n\nvar goroutineSpace = []byte(\"goroutine \")\n\nfunc curGoroutineID() uint64 {\n\tbp := littleBuf.Get().(*[]byte)\n\tdefer littleBuf.Put(bp)\n\tb := *bp\n\tb = b[:runtime.Stack(b, false)]\n\t// Parse the 4707 out of \"goroutine 4707 [\"\n\tb = bytes.TrimPrefix(b, goroutineSpace)\n\ti := bytes.IndexByte(b, ' ')\n\tif i < 0 {\n\t\tpanic(fmt.Sprintf(\"No space found in %q\", b))\n\t}\n\tb = b[:i]\n\tn, err := parseUintBytes(b, 10, 64)\n\tif err != nil {\n\t\tpanic(fmt.Sprintf(\"Failed to parse goroutine ID out of %q: %v\", b, err))\n\t}\n\treturn n\n}\n\nvar littleBuf = sync.Pool{\n\tNew: func() interface{} {\n\t\tbuf := make([]byte, 64)\n\t\treturn &buf\n\t},\n}\n\n// parseUintBytes is like strconv.ParseUint, but using a []byte.\nfunc parseUintBytes(s []byte, base int, bitSize int) (n uint64, err error) {\n\tvar cutoff, maxVal uint64\n\n\tif bitSize == 0 {\n\t\tbitSize = int(strconv.IntSize)\n\t}\n\n\ts0 := s\n\tswitch {\n\tcase len(s) < 1:\n\t\terr = strconv.ErrSyntax\n\t\tgoto Error\n\n\tcase 2 <= base && base <= 36:\n\t\t// valid base; nothing to do\n\n\tcase base == 0:\n\t\t// Look for octal, hex prefix.\n\t\tswitch {\n\t\tcase s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):\n\t\t\tbase = 16\n\t\t\ts = s[2:]\n\t\t\tif len(s) < 1 {\n\t\t\t\terr = strconv.ErrSyntax\n\t\t\t\tgoto Error\n\t\t\t}\n\t\tcase s[0] == '0':\n\t\t\tbase = 8\n\t\tdefault:\n\t\t\tbase = 10\n\t\t}\n\n\tdefault:\n\t\terr = errors.New(\"invalid base \" + strconv.Itoa(base))\n\t\tgoto Error\n\t}\n\n\tn = 0\n\tcutoff = cutoff64(base)\n\tmaxVal = 1<<uint(bitSize) - 1\n\n\tfor i := 0; i < len(s); i++ {\n\t\tvar v byte\n\t\td := s[i]\n\t\tswitch {\n\t\tcase '0' <= d && d <= '9':\n\t\t\tv = d - '0'\n\t\tcase 'a' <= d && d <= 'z':\n\t\t\tv = d - 'a' + 10\n\t\tcase 'A' <= d && d <= 'Z':\n\t\t\tv = d - 'A' + 10\n\t\tdefault:\n\t\t\tn = 0\n\t\t\terr = strconv.ErrSyntax\n\t\t\tgoto Error\n\t\t}\n\t\tif int(v) >= base {\n\t\t\tn = 0\n\t\t\terr = strconv.ErrSyntax\n\t\t\tgoto Error\n\t\t}\n\n\t\tif n >= cutoff {\n\t\t\t// n*base overflows\n\t\t\tn = 1<<64 - 1\n\t\t\terr = strconv.ErrRange\n\t\t\tgoto Error\n\t\t}\n\t\tn *= uint64(base)\n\n\t\tn1 := n + uint64(v)\n\t\tif n1 < n || n1 > maxVal {\n\t\t\t// n+v overflows\n\t\t\tn = 1<<64 - 1\n\t\t\terr = strconv.ErrRange\n\t\t\tgoto Error\n\t\t}\n\t\tn = n1\n\t}\n\n\treturn n, nil\n\nError:\n\treturn n, &strconv.NumError{Func: \"ParseUint\", Num: string(s0), Err: err}\n}\n\n// Return the first number n such that n*base >= 1<<64.\nfunc cutoff64(base int) uint64 {\n\tif base < 2 {\n\t\treturn 0\n\t}\n\treturn (1<<64-1)/uint64(base) + 1\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/encode.go",
    "content": "// Copyright 2014 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 hpack\n\nimport (\n\t\"io\"\n)\n\nconst (\n\tuint32Max              = ^uint32(0)\n\tinitialHeaderTableSize = 4096\n)\n\ntype Encoder struct {\n\tdynTab dynamicTable\n\t// minSize is the minimum table size set by\n\t// SetMaxDynamicTableSize after the previous Header Table Size\n\t// Update.\n\tminSize uint32\n\t// maxSizeLimit is the maximum table size this encoder\n\t// supports. This will protect the encoder from too large\n\t// size.\n\tmaxSizeLimit uint32\n\t// tableSizeUpdate indicates whether \"Header Table Size\n\t// Update\" is required.\n\ttableSizeUpdate bool\n\tw               io.Writer\n\tbuf             []byte\n}\n\n// NewEncoder returns a new Encoder which performs HPACK encoding. An\n// encoded data is written to w.\nfunc NewEncoder(w io.Writer) *Encoder {\n\te := &Encoder{\n\t\tminSize:         uint32Max,\n\t\tmaxSizeLimit:    initialHeaderTableSize,\n\t\ttableSizeUpdate: false,\n\t\tw:               w,\n\t}\n\te.dynTab.table.init()\n\te.dynTab.setMaxSize(initialHeaderTableSize)\n\treturn e\n}\n\n// WriteField encodes f into a single Write to e's underlying Writer.\n// This function may also produce bytes for \"Header Table Size Update\"\n// if necessary. If produced, it is done before encoding f.\nfunc (e *Encoder) WriteField(f HeaderField) error {\n\te.buf = e.buf[:0]\n\n\tif e.tableSizeUpdate {\n\t\te.tableSizeUpdate = false\n\t\tif e.minSize < e.dynTab.maxSize {\n\t\t\te.buf = appendTableSize(e.buf, e.minSize)\n\t\t}\n\t\te.minSize = uint32Max\n\t\te.buf = appendTableSize(e.buf, e.dynTab.maxSize)\n\t}\n\n\tidx, nameValueMatch := e.searchTable(f)\n\tif nameValueMatch {\n\t\te.buf = appendIndexed(e.buf, idx)\n\t} else {\n\t\tindexing := e.shouldIndex(f)\n\t\tif indexing {\n\t\t\te.dynTab.add(f)\n\t\t}\n\n\t\tif idx == 0 {\n\t\t\te.buf = appendNewName(e.buf, f, indexing)\n\t\t} else {\n\t\t\te.buf = appendIndexedName(e.buf, f, idx, indexing)\n\t\t}\n\t}\n\tn, err := e.w.Write(e.buf)\n\tif err == nil && n != len(e.buf) {\n\t\terr = io.ErrShortWrite\n\t}\n\treturn err\n}\n\n// searchTable searches f in both stable and dynamic header tables.\n// The static header table is searched first. Only when there is no\n// exact match for both name and value, the dynamic header table is\n// then searched. If there is no match, i is 0. If both name and value\n// match, i is the matched index and nameValueMatch becomes true. If\n// only name matches, i points to that index and nameValueMatch\n// becomes false.\nfunc (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) {\n\ti, nameValueMatch = staticTable.search(f)\n\tif nameValueMatch {\n\t\treturn i, true\n\t}\n\n\tj, nameValueMatch := e.dynTab.table.search(f)\n\tif nameValueMatch || (i == 0 && j != 0) {\n\t\treturn j + uint64(staticTable.len()), nameValueMatch\n\t}\n\n\treturn i, false\n}\n\n// SetMaxDynamicTableSize changes the dynamic header table size to v.\n// The actual size is bounded by the value passed to\n// SetMaxDynamicTableSizeLimit.\nfunc (e *Encoder) SetMaxDynamicTableSize(v uint32) {\n\tif v > e.maxSizeLimit {\n\t\tv = e.maxSizeLimit\n\t}\n\tif v < e.minSize {\n\t\te.minSize = v\n\t}\n\te.tableSizeUpdate = true\n\te.dynTab.setMaxSize(v)\n}\n\n// MaxDynamicTableSize returns the current dynamic header table size.\nfunc (e *Encoder) MaxDynamicTableSize() (v uint32) {\n\treturn e.dynTab.maxSize\n}\n\n// SetMaxDynamicTableSizeLimit changes the maximum value that can be\n// specified in SetMaxDynamicTableSize to v. By default, it is set to\n// 4096, which is the same size of the default dynamic header table\n// size described in HPACK specification. If the current maximum\n// dynamic header table size is strictly greater than v, \"Header Table\n// Size Update\" will be done in the next WriteField call and the\n// maximum dynamic header table size is truncated to v.\nfunc (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) {\n\te.maxSizeLimit = v\n\tif e.dynTab.maxSize > v {\n\t\te.tableSizeUpdate = true\n\t\te.dynTab.setMaxSize(v)\n\t}\n}\n\n// shouldIndex reports whether f should be indexed.\nfunc (e *Encoder) shouldIndex(f HeaderField) bool {\n\treturn !f.Sensitive && f.Size() <= e.dynTab.maxSize\n}\n\n// appendIndexed appends index i, as encoded in \"Indexed Header Field\"\n// representation, to dst and returns the extended buffer.\nfunc appendIndexed(dst []byte, i uint64) []byte {\n\tfirst := len(dst)\n\tdst = appendVarInt(dst, 7, i)\n\tdst[first] |= 0x80\n\treturn dst\n}\n\n// appendNewName appends f, as encoded in one of \"Literal Header field\n// - New Name\" representation variants, to dst and returns the\n// extended buffer.\n//\n// If f.Sensitive is true, \"Never Indexed\" representation is used. If\n// f.Sensitive is false and indexing is true, \"Incremental Indexing\"\n// representation is used.\nfunc appendNewName(dst []byte, f HeaderField, indexing bool) []byte {\n\tdst = append(dst, encodeTypeByte(indexing, f.Sensitive))\n\tdst = appendHpackString(dst, f.Name)\n\treturn appendHpackString(dst, f.Value)\n}\n\n// appendIndexedName appends f and index i referring indexed name\n// entry, as encoded in one of \"Literal Header field - Indexed Name\"\n// representation variants, to dst and returns the extended buffer.\n//\n// If f.Sensitive is true, \"Never Indexed\" representation is used. If\n// f.Sensitive is false and indexing is true, \"Incremental Indexing\"\n// representation is used.\nfunc appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte {\n\tfirst := len(dst)\n\tvar n byte\n\tif indexing {\n\t\tn = 6\n\t} else {\n\t\tn = 4\n\t}\n\tdst = appendVarInt(dst, n, i)\n\tdst[first] |= encodeTypeByte(indexing, f.Sensitive)\n\treturn appendHpackString(dst, f.Value)\n}\n\n// appendTableSize appends v, as encoded in \"Header Table Size Update\"\n// representation, to dst and returns the extended buffer.\nfunc appendTableSize(dst []byte, v uint32) []byte {\n\tfirst := len(dst)\n\tdst = appendVarInt(dst, 5, uint64(v))\n\tdst[first] |= 0x20\n\treturn dst\n}\n\n// appendVarInt appends i, as encoded in variable integer form using n\n// bit prefix, to dst and returns the extended buffer.\n//\n// See\n// https://httpwg.org/specs/rfc7541.html#integer.representation\nfunc appendVarInt(dst []byte, n byte, i uint64) []byte {\n\tk := uint64((1 << n) - 1)\n\tif i < k {\n\t\treturn append(dst, byte(i))\n\t}\n\tdst = append(dst, byte(k))\n\ti -= k\n\tfor ; i >= 128; i >>= 7 {\n\t\tdst = append(dst, byte(0x80|(i&0x7f)))\n\t}\n\treturn append(dst, byte(i))\n}\n\n// appendHpackString appends s, as encoded in \"String Literal\"\n// representation, to dst and returns the extended buffer.\n//\n// s will be encoded in Huffman codes only when it produces strictly\n// shorter byte string.\nfunc appendHpackString(dst []byte, s string) []byte {\n\thuffmanLength := HuffmanEncodeLength(s)\n\tif huffmanLength < uint64(len(s)) {\n\t\tfirst := len(dst)\n\t\tdst = appendVarInt(dst, 7, huffmanLength)\n\t\tdst = AppendHuffmanString(dst, s)\n\t\tdst[first] |= 0x80\n\t} else {\n\t\tdst = appendVarInt(dst, 7, uint64(len(s)))\n\t\tdst = append(dst, s...)\n\t}\n\treturn dst\n}\n\n// encodeTypeByte returns type byte. If sensitive is true, type byte\n// for \"Never Indexed\" representation is returned. If sensitive is\n// false and indexing is true, type byte for \"Incremental Indexing\"\n// representation is returned. Otherwise, type byte for \"Without\n// Indexing\" is returned.\nfunc encodeTypeByte(indexing, sensitive bool) byte {\n\tif sensitive {\n\t\treturn 0x10\n\t}\n\tif indexing {\n\t\treturn 0x40\n\t}\n\treturn 0\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/hpack.go",
    "content": "// Copyright 2014 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// Package hpack implements HPACK, a compression format for\n// efficiently representing HTTP header fields in the context of HTTP/2.\n//\n// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09\npackage hpack\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n)\n\n// A DecodingError is something the spec defines as a decoding error.\ntype DecodingError struct {\n\tErr error\n}\n\nfunc (de DecodingError) Error() string {\n\treturn fmt.Sprintf(\"decoding error: %v\", de.Err)\n}\n\n// An InvalidIndexError is returned when an encoder references a table\n// entry before the static table or after the end of the dynamic table.\ntype InvalidIndexError int\n\nfunc (e InvalidIndexError) Error() string {\n\treturn fmt.Sprintf(\"invalid indexed representation index %d\", int(e))\n}\n\n// A HeaderField is a name-value pair. Both the name and value are\n// treated as opaque sequences of octets.\ntype HeaderField struct {\n\tName, Value string\n\n\t// Sensitive means that this header field should never be\n\t// indexed.\n\tSensitive bool\n}\n\n// IsPseudo reports whether the header field is an http2 pseudo header.\n// That is, it reports whether it starts with a colon.\n// It is not otherwise guaranteed to be a valid pseudo header field,\n// though.\nfunc (hf HeaderField) IsPseudo() bool {\n\treturn len(hf.Name) != 0 && hf.Name[0] == ':'\n}\n\nfunc (hf HeaderField) String() string {\n\tvar suffix string\n\tif hf.Sensitive {\n\t\tsuffix = \" (sensitive)\"\n\t}\n\treturn fmt.Sprintf(\"header field %q = %q%s\", hf.Name, hf.Value, suffix)\n}\n\n// Size returns the size of an entry per RFC 7541 section 4.1.\nfunc (hf HeaderField) Size() uint32 {\n\t// https://httpwg.org/specs/rfc7541.html#rfc.section.4.1\n\t// \"The size of the dynamic table is the sum of the size of\n\t// its entries. The size of an entry is the sum of its name's\n\t// length in octets (as defined in Section 5.2), its value's\n\t// length in octets (see Section 5.2), plus 32.  The size of\n\t// an entry is calculated using the length of the name and\n\t// value without any Huffman encoding applied.\"\n\n\t// This can overflow if somebody makes a large HeaderField\n\t// Name and/or Value by hand, but we don't care, because that\n\t// won't happen on the wire because the encoding doesn't allow\n\t// it.\n\treturn uint32(len(hf.Name) + len(hf.Value) + 32)\n}\n\n// A Decoder is the decoding context for incremental processing of\n// header blocks.\ntype Decoder struct {\n\tdynTab dynamicTable\n\temit   func(f HeaderField)\n\n\temitEnabled bool // whether calls to emit are enabled\n\tmaxStrLen   int  // 0 means unlimited\n\n\t// buf is the unparsed buffer. It's only written to\n\t// saveBuf if it was truncated in the middle of a header\n\t// block. Because it's usually not owned, we can only\n\t// process it under Write.\n\tbuf []byte // not owned; only valid during Write\n\n\t// saveBuf is previous data passed to Write which we weren't able\n\t// to fully parse before. Unlike buf, we own this data.\n\tsaveBuf bytes.Buffer\n\n\tfirstField bool // processing the first field of the header block\n}\n\n// NewDecoder returns a new decoder with the provided maximum dynamic\n// table size. The emitFunc will be called for each valid field\n// parsed, in the same goroutine as calls to Write, before Write returns.\nfunc NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder {\n\td := &Decoder{\n\t\temit:        emitFunc,\n\t\temitEnabled: true,\n\t\tfirstField:  true,\n\t}\n\td.dynTab.table.init()\n\td.dynTab.allowedMaxSize = maxDynamicTableSize\n\td.dynTab.setMaxSize(maxDynamicTableSize)\n\treturn d\n}\n\n// ErrStringLength is returned by Decoder.Write when the max string length\n// (as configured by Decoder.SetMaxStringLength) would be violated.\nvar ErrStringLength = errors.New(\"hpack: string too long\")\n\n// SetMaxStringLength sets the maximum size of a HeaderField name or\n// value string. If a string exceeds this length (even after any\n// decompression), Write will return ErrStringLength.\n// A value of 0 means unlimited and is the default from NewDecoder.\nfunc (d *Decoder) SetMaxStringLength(n int) {\n\td.maxStrLen = n\n}\n\n// SetEmitFunc changes the callback used when new header fields\n// are decoded.\n// It must be non-nil. It does not affect EmitEnabled.\nfunc (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) {\n\td.emit = emitFunc\n}\n\n// SetEmitEnabled controls whether the emitFunc provided to NewDecoder\n// should be called. The default is true.\n//\n// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE\n// while still decoding and keeping in-sync with decoder state, but\n// without doing unnecessary decompression or generating unnecessary\n// garbage for header fields past the limit.\nfunc (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v }\n\n// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder\n// are currently enabled. The default is true.\nfunc (d *Decoder) EmitEnabled() bool { return d.emitEnabled }\n\n// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their\n// underlying buffers for garbage reasons.\n\nfunc (d *Decoder) SetMaxDynamicTableSize(v uint32) {\n\td.dynTab.setMaxSize(v)\n}\n\n// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded\n// stream (via dynamic table size updates) may set the maximum size\n// to.\nfunc (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) {\n\td.dynTab.allowedMaxSize = v\n}\n\ntype dynamicTable struct {\n\t// https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2\n\ttable          headerFieldTable\n\tsize           uint32 // in bytes\n\tmaxSize        uint32 // current maxSize\n\tallowedMaxSize uint32 // maxSize may go up to this, inclusive\n}\n\nfunc (dt *dynamicTable) setMaxSize(v uint32) {\n\tdt.maxSize = v\n\tdt.evict()\n}\n\nfunc (dt *dynamicTable) add(f HeaderField) {\n\tdt.table.addEntry(f)\n\tdt.size += f.Size()\n\tdt.evict()\n}\n\n// If we're too big, evict old stuff.\nfunc (dt *dynamicTable) evict() {\n\tvar n int\n\tfor dt.size > dt.maxSize && n < dt.table.len() {\n\t\tdt.size -= dt.table.ents[n].Size()\n\t\tn++\n\t}\n\tdt.table.evictOldest(n)\n}\n\nfunc (d *Decoder) maxTableIndex() int {\n\t// This should never overflow. RFC 7540 Section 6.5.2 limits the size of\n\t// the dynamic table to 2^32 bytes, where each entry will occupy more than\n\t// one byte. Further, the staticTable has a fixed, small length.\n\treturn d.dynTab.table.len() + staticTable.len()\n}\n\nfunc (d *Decoder) at(i uint64) (hf HeaderField, ok bool) {\n\t// See Section 2.3.3.\n\tif i == 0 {\n\t\treturn\n\t}\n\tif i <= uint64(staticTable.len()) {\n\t\treturn staticTable.ents[i-1], true\n\t}\n\tif i > uint64(d.maxTableIndex()) {\n\t\treturn\n\t}\n\t// In the dynamic table, newer entries have lower indices.\n\t// However, dt.ents[0] is the oldest entry. Hence, dt.ents is\n\t// the reversed dynamic table.\n\tdt := d.dynTab.table\n\treturn dt.ents[dt.len()-(int(i)-staticTable.len())], true\n}\n\n// DecodeFull decodes an entire block.\n//\n// TODO: remove this method and make it incremental later? This is\n// easier for debugging now.\nfunc (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) {\n\tvar hf []HeaderField\n\tsaveFunc := d.emit\n\tdefer func() { d.emit = saveFunc }()\n\td.emit = func(f HeaderField) { hf = append(hf, f) }\n\tif _, err := d.Write(p); err != nil {\n\t\treturn nil, err\n\t}\n\tif err := d.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn hf, nil\n}\n\n// Close declares that the decoding is complete and resets the Decoder\n// to be reused again for a new header block. If there is any remaining\n// data in the decoder's buffer, Close returns an error.\nfunc (d *Decoder) Close() error {\n\tif d.saveBuf.Len() > 0 {\n\t\td.saveBuf.Reset()\n\t\treturn DecodingError{errors.New(\"truncated headers\")}\n\t}\n\td.firstField = true\n\treturn nil\n}\n\nfunc (d *Decoder) Write(p []byte) (n int, err error) {\n\tif len(p) == 0 {\n\t\t// Prevent state machine CPU attacks (making us redo\n\t\t// work up to the point of finding out we don't have\n\t\t// enough data)\n\t\treturn\n\t}\n\t// Only copy the data if we have to. Optimistically assume\n\t// that p will contain a complete header block.\n\tif d.saveBuf.Len() == 0 {\n\t\td.buf = p\n\t} else {\n\t\td.saveBuf.Write(p)\n\t\td.buf = d.saveBuf.Bytes()\n\t\td.saveBuf.Reset()\n\t}\n\n\tfor len(d.buf) > 0 {\n\t\terr = d.parseHeaderFieldRepr()\n\t\tif err == errNeedMore {\n\t\t\t// Extra paranoia, making sure saveBuf won't\n\t\t\t// get too large. All the varint and string\n\t\t\t// reading code earlier should already catch\n\t\t\t// overlong things and return ErrStringLength,\n\t\t\t// but keep this as a last resort.\n\t\t\tconst varIntOverhead = 8 // conservative\n\t\t\tif d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) {\n\t\t\t\treturn 0, ErrStringLength\n\t\t\t}\n\t\t\td.saveBuf.Write(d.buf)\n\t\t\treturn len(p), nil\n\t\t}\n\t\td.firstField = false\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn len(p), err\n}\n\n// errNeedMore is an internal sentinel error value that means the\n// buffer is truncated and we need to read more data before we can\n// continue parsing.\nvar errNeedMore = errors.New(\"need more data\")\n\ntype indexType int\n\nconst (\n\tindexedTrue indexType = iota\n\tindexedFalse\n\tindexedNever\n)\n\nfunc (v indexType) indexed() bool   { return v == indexedTrue }\nfunc (v indexType) sensitive() bool { return v == indexedNever }\n\n// returns errNeedMore if there isn't enough data available.\n// any other error is fatal.\n// consumes d.buf iff it returns nil.\n// precondition: must be called with len(d.buf) > 0\nfunc (d *Decoder) parseHeaderFieldRepr() error {\n\tb := d.buf[0]\n\tswitch {\n\tcase b&128 != 0:\n\t\t// Indexed representation.\n\t\t// High bit set?\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.1\n\t\treturn d.parseFieldIndexed()\n\tcase b&192 == 64:\n\t\t// 6.2.1 Literal Header Field with Incremental Indexing\n\t\t// 0b10xxxxxx: top two bits are 10\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1\n\t\treturn d.parseFieldLiteral(6, indexedTrue)\n\tcase b&240 == 0:\n\t\t// 6.2.2 Literal Header Field without Indexing\n\t\t// 0b0000xxxx: top four bits are 0000\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2\n\t\treturn d.parseFieldLiteral(4, indexedFalse)\n\tcase b&240 == 16:\n\t\t// 6.2.3 Literal Header Field never Indexed\n\t\t// 0b0001xxxx: top four bits are 0001\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3\n\t\treturn d.parseFieldLiteral(4, indexedNever)\n\tcase b&224 == 32:\n\t\t// 6.3 Dynamic Table Size Update\n\t\t// Top three bits are '001'.\n\t\t// https://httpwg.org/specs/rfc7541.html#rfc.section.6.3\n\t\treturn d.parseDynamicTableSizeUpdate()\n\t}\n\n\treturn DecodingError{errors.New(\"invalid encoding\")}\n}\n\n// (same invariants and behavior as parseHeaderFieldRepr)\nfunc (d *Decoder) parseFieldIndexed() error {\n\tbuf := d.buf\n\tidx, buf, err := readVarInt(7, buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\thf, ok := d.at(idx)\n\tif !ok {\n\t\treturn DecodingError{InvalidIndexError(idx)}\n\t}\n\td.buf = buf\n\treturn d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value})\n}\n\n// (same invariants and behavior as parseHeaderFieldRepr)\nfunc (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {\n\tbuf := d.buf\n\tnameIdx, buf, err := readVarInt(n, buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar hf HeaderField\n\twantStr := d.emitEnabled || it.indexed()\n\tvar undecodedName undecodedString\n\tif nameIdx > 0 {\n\t\tihf, ok := d.at(nameIdx)\n\t\tif !ok {\n\t\t\treturn DecodingError{InvalidIndexError(nameIdx)}\n\t\t}\n\t\thf.Name = ihf.Name\n\t} else {\n\t\tundecodedName, buf, err = d.readString(buf)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tundecodedValue, buf, err := d.readString(buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif wantStr {\n\t\tif nameIdx <= 0 {\n\t\t\thf.Name, err = d.decodeString(undecodedName)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\thf.Value, err = d.decodeString(undecodedValue)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\td.buf = buf\n\tif it.indexed() {\n\t\td.dynTab.add(hf)\n\t}\n\thf.Sensitive = it.sensitive()\n\treturn d.callEmit(hf)\n}\n\nfunc (d *Decoder) callEmit(hf HeaderField) error {\n\tif d.maxStrLen != 0 {\n\t\tif len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen {\n\t\t\treturn ErrStringLength\n\t\t}\n\t}\n\tif d.emitEnabled {\n\t\td.emit(hf)\n\t}\n\treturn nil\n}\n\n// (same invariants and behavior as parseHeaderFieldRepr)\nfunc (d *Decoder) parseDynamicTableSizeUpdate() error {\n\t// RFC 7541, sec 4.2: This dynamic table size update MUST occur at the\n\t// beginning of the first header block following the change to the dynamic table size.\n\tif !d.firstField && d.dynTab.size > 0 {\n\t\treturn DecodingError{errors.New(\"dynamic table size update MUST occur at the beginning of a header block\")}\n\t}\n\n\tbuf := d.buf\n\tsize, buf, err := readVarInt(5, buf)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif size > uint64(d.dynTab.allowedMaxSize) {\n\t\treturn DecodingError{errors.New(\"dynamic table size update too large\")}\n\t}\n\td.dynTab.setMaxSize(uint32(size))\n\td.buf = buf\n\treturn nil\n}\n\nvar errVarintOverflow = DecodingError{errors.New(\"varint integer overflow\")}\n\n// readVarInt reads an unsigned variable length integer off the\n// beginning of p. n is the parameter as described in\n// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1.\n//\n// n must always be between 1 and 8.\n//\n// The returned remain buffer is either a smaller suffix of p, or err != nil.\n// The error is errNeedMore if p doesn't contain a complete integer.\nfunc readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {\n\tif n < 1 || n > 8 {\n\t\tpanic(\"bad n\")\n\t}\n\tif len(p) == 0 {\n\t\treturn 0, p, errNeedMore\n\t}\n\ti = uint64(p[0])\n\tif n < 8 {\n\t\ti &= (1 << uint64(n)) - 1\n\t}\n\tif i < (1<<uint64(n))-1 {\n\t\treturn i, p[1:], nil\n\t}\n\n\torigP := p\n\tp = p[1:]\n\tvar m uint64\n\tfor len(p) > 0 {\n\t\tb := p[0]\n\t\tp = p[1:]\n\t\ti += uint64(b&127) << m\n\t\tif b&128 == 0 {\n\t\t\treturn i, p, nil\n\t\t}\n\t\tm += 7\n\t\tif m >= 63 { // TODO: proper overflow check. making this up.\n\t\t\treturn 0, origP, errVarintOverflow\n\t\t}\n\t}\n\treturn 0, origP, errNeedMore\n}\n\n// readString reads an hpack string from p.\n//\n// It returns a reference to the encoded string data to permit deferring decode costs\n// until after the caller verifies all data is present.\nfunc (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) {\n\tif len(p) == 0 {\n\t\treturn u, p, errNeedMore\n\t}\n\tisHuff := p[0]&128 != 0\n\tstrLen, p, err := readVarInt(7, p)\n\tif err != nil {\n\t\treturn u, p, err\n\t}\n\tif d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {\n\t\t// Returning an error here means Huffman decoding errors\n\t\t// for non-indexed strings past the maximum string length\n\t\t// are ignored, but the server is returning an error anyway\n\t\t// and because the string is not indexed the error will not\n\t\t// affect the decoding state.\n\t\treturn u, nil, ErrStringLength\n\t}\n\tif uint64(len(p)) < strLen {\n\t\treturn u, p, errNeedMore\n\t}\n\tu.isHuff = isHuff\n\tu.b = p[:strLen]\n\treturn u, p[strLen:], nil\n}\n\ntype undecodedString struct {\n\tisHuff bool\n\tb      []byte\n}\n\nfunc (d *Decoder) decodeString(u undecodedString) (string, error) {\n\tif !u.isHuff {\n\t\treturn string(u.b), nil\n\t}\n\tbuf := bufPool.Get().(*bytes.Buffer)\n\tbuf.Reset() // don't trust others\n\tvar s string\n\terr := huffmanDecode(buf, d.maxStrLen, u.b)\n\tif err == nil {\n\t\ts = buf.String()\n\t}\n\tbuf.Reset() // be nice to GC\n\tbufPool.Put(buf)\n\treturn s, err\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/huffman.go",
    "content": "// Copyright 2014 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 hpack\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n)\n\nvar bufPool = sync.Pool{\n\tNew: func() interface{} { return new(bytes.Buffer) },\n}\n\n// HuffmanDecode decodes the string in v and writes the expanded\n// result to w, returning the number of bytes written to w and the\n// Write call's return value. At most one Write call is made.\nfunc HuffmanDecode(w io.Writer, v []byte) (int, error) {\n\tbuf := bufPool.Get().(*bytes.Buffer)\n\tbuf.Reset()\n\tdefer bufPool.Put(buf)\n\tif err := huffmanDecode(buf, 0, v); err != nil {\n\t\treturn 0, err\n\t}\n\treturn w.Write(buf.Bytes())\n}\n\n// HuffmanDecodeToString decodes the string in v.\nfunc HuffmanDecodeToString(v []byte) (string, error) {\n\tbuf := bufPool.Get().(*bytes.Buffer)\n\tbuf.Reset()\n\tdefer bufPool.Put(buf)\n\tif err := huffmanDecode(buf, 0, v); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn buf.String(), nil\n}\n\n// ErrInvalidHuffman is returned for errors found decoding\n// Huffman-encoded strings.\nvar ErrInvalidHuffman = errors.New(\"hpack: invalid Huffman-encoded data\")\n\n// huffmanDecode decodes v to buf.\n// If maxLen is greater than 0, attempts to write more to buf than\n// maxLen bytes will return ErrStringLength.\nfunc huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error {\n\trootHuffmanNode := getRootHuffmanNode()\n\tn := rootHuffmanNode\n\t// cur is the bit buffer that has not been fed into n.\n\t// cbits is the number of low order bits in cur that are valid.\n\t// sbits is the number of bits of the symbol prefix being decoded.\n\tcur, cbits, sbits := uint(0), uint8(0), uint8(0)\n\tfor _, b := range v {\n\t\tcur = cur<<8 | uint(b)\n\t\tcbits += 8\n\t\tsbits += 8\n\t\tfor cbits >= 8 {\n\t\t\tidx := byte(cur >> (cbits - 8))\n\t\t\tn = n.children[idx]\n\t\t\tif n == nil {\n\t\t\t\treturn ErrInvalidHuffman\n\t\t\t}\n\t\t\tif n.children == nil {\n\t\t\t\tif maxLen != 0 && buf.Len() == maxLen {\n\t\t\t\t\treturn ErrStringLength\n\t\t\t\t}\n\t\t\t\tbuf.WriteByte(n.sym)\n\t\t\t\tcbits -= n.codeLen\n\t\t\t\tn = rootHuffmanNode\n\t\t\t\tsbits = cbits\n\t\t\t} else {\n\t\t\t\tcbits -= 8\n\t\t\t}\n\t\t}\n\t}\n\tfor cbits > 0 {\n\t\tn = n.children[byte(cur<<(8-cbits))]\n\t\tif n == nil {\n\t\t\treturn ErrInvalidHuffman\n\t\t}\n\t\tif n.children != nil || n.codeLen > cbits {\n\t\t\tbreak\n\t\t}\n\t\tif maxLen != 0 && buf.Len() == maxLen {\n\t\t\treturn ErrStringLength\n\t\t}\n\t\tbuf.WriteByte(n.sym)\n\t\tcbits -= n.codeLen\n\t\tn = rootHuffmanNode\n\t\tsbits = cbits\n\t}\n\tif sbits > 7 {\n\t\t// Either there was an incomplete symbol, or overlong padding.\n\t\t// Both are decoding errors per RFC 7541 section 5.2.\n\t\treturn ErrInvalidHuffman\n\t}\n\tif mask := uint(1<<cbits - 1); cur&mask != mask {\n\t\t// Trailing bits must be a prefix of EOS per RFC 7541 section 5.2.\n\t\treturn ErrInvalidHuffman\n\t}\n\n\treturn nil\n}\n\n// incomparable is a zero-width, non-comparable type. Adding it to a struct\n// makes that struct also non-comparable, and generally doesn't add\n// any size (as long as it's first).\ntype incomparable [0]func()\n\ntype node struct {\n\t_ incomparable\n\n\t// children is non-nil for internal nodes\n\tchildren *[256]*node\n\n\t// The following are only valid if children is nil:\n\tcodeLen uint8 // number of bits that led to the output of sym\n\tsym     byte  // output symbol\n}\n\nfunc newInternalNode() *node {\n\treturn &node{children: new([256]*node)}\n}\n\nvar (\n\tbuildRootOnce       sync.Once\n\tlazyRootHuffmanNode *node\n)\n\nfunc getRootHuffmanNode() *node {\n\tbuildRootOnce.Do(buildRootHuffmanNode)\n\treturn lazyRootHuffmanNode\n}\n\nfunc buildRootHuffmanNode() {\n\tif len(huffmanCodes) != 256 {\n\t\tpanic(\"unexpected size\")\n\t}\n\tlazyRootHuffmanNode = newInternalNode()\n\t// allocate a leaf node for each of the 256 symbols\n\tleaves := new([256]node)\n\n\tfor sym, code := range huffmanCodes {\n\t\tcodeLen := huffmanCodeLen[sym]\n\n\t\tcur := lazyRootHuffmanNode\n\t\tfor codeLen > 8 {\n\t\t\tcodeLen -= 8\n\t\t\ti := uint8(code >> codeLen)\n\t\t\tif cur.children[i] == nil {\n\t\t\t\tcur.children[i] = newInternalNode()\n\t\t\t}\n\t\t\tcur = cur.children[i]\n\t\t}\n\t\tshift := 8 - codeLen\n\t\tstart, end := int(uint8(code<<shift)), int(1<<shift)\n\n\t\tleaves[sym].sym = byte(sym)\n\t\tleaves[sym].codeLen = codeLen\n\t\tfor i := start; i < start+end; i++ {\n\t\t\tcur.children[i] = &leaves[sym]\n\t\t}\n\t}\n}\n\n// AppendHuffmanString appends s, as encoded in Huffman codes, to dst\n// and returns the extended buffer.\nfunc AppendHuffmanString(dst []byte, s string) []byte {\n\t// This relies on the maximum huffman code length being 30 (See tables.go huffmanCodeLen array)\n\t// So if a uint64 buffer has less than 32 valid bits can always accommodate another huffmanCode.\n\tvar (\n\t\tx uint64 // buffer\n\t\tn uint   // number valid of bits present in x\n\t)\n\tfor i := 0; i < len(s); i++ {\n\t\tc := s[i]\n\t\tn += uint(huffmanCodeLen[c])\n\t\tx <<= huffmanCodeLen[c] % 64\n\t\tx |= uint64(huffmanCodes[c])\n\t\tif n >= 32 {\n\t\t\tn %= 32             // Normally would be -= 32 but %= 32 informs compiler 0 <= n <= 31 for upcoming shift\n\t\t\ty := uint32(x >> n) // Compiler doesn't combine memory writes if y isn't uint32\n\t\t\tdst = append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))\n\t\t}\n\t}\n\t// Add padding bits if necessary\n\tif over := n % 8; over > 0 {\n\t\tconst (\n\t\t\teosCode    = 0x3fffffff\n\t\t\teosNBits   = 30\n\t\t\teosPadByte = eosCode >> (eosNBits - 8)\n\t\t)\n\t\tpad := 8 - over\n\t\tx = (x << pad) | (eosPadByte >> over)\n\t\tn += pad // 8 now divides into n exactly\n\t}\n\t// n in (0, 8, 16, 24, 32)\n\tswitch n / 8 {\n\tcase 0:\n\t\treturn dst\n\tcase 1:\n\t\treturn append(dst, byte(x))\n\tcase 2:\n\t\ty := uint16(x)\n\t\treturn append(dst, byte(y>>8), byte(y))\n\tcase 3:\n\t\ty := uint16(x >> 8)\n\t\treturn append(dst, byte(y>>8), byte(y), byte(x))\n\t}\n\t//\tcase 4:\n\ty := uint32(x)\n\treturn append(dst, byte(y>>24), byte(y>>16), byte(y>>8), byte(y))\n}\n\n// HuffmanEncodeLength returns the number of bytes required to encode\n// s in Huffman codes. The result is round up to byte boundary.\nfunc HuffmanEncodeLength(s string) uint64 {\n\tn := uint64(0)\n\tfor i := 0; i < len(s); i++ {\n\t\tn += uint64(huffmanCodeLen[s[i]])\n\t}\n\treturn (n + 7) / 8\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/static_table.go",
    "content": "// go generate gen.go\n// Code generated by the command above; DO NOT EDIT.\n\npackage hpack\n\nvar staticTable = &headerFieldTable{\n\tevictCount: 0,\n\tbyName: map[string]uint64{\n\t\t\":authority\":                  1,\n\t\t\":method\":                     3,\n\t\t\":path\":                       5,\n\t\t\":scheme\":                     7,\n\t\t\":status\":                     14,\n\t\t\"accept-charset\":              15,\n\t\t\"accept-encoding\":             16,\n\t\t\"accept-language\":             17,\n\t\t\"accept-ranges\":               18,\n\t\t\"accept\":                      19,\n\t\t\"access-control-allow-origin\": 20,\n\t\t\"age\":                         21,\n\t\t\"allow\":                       22,\n\t\t\"authorization\":               23,\n\t\t\"cache-control\":               24,\n\t\t\"content-disposition\":         25,\n\t\t\"content-encoding\":            26,\n\t\t\"content-language\":            27,\n\t\t\"content-length\":              28,\n\t\t\"content-location\":            29,\n\t\t\"content-range\":               30,\n\t\t\"content-type\":                31,\n\t\t\"cookie\":                      32,\n\t\t\"date\":                        33,\n\t\t\"etag\":                        34,\n\t\t\"expect\":                      35,\n\t\t\"expires\":                     36,\n\t\t\"from\":                        37,\n\t\t\"host\":                        38,\n\t\t\"if-match\":                    39,\n\t\t\"if-modified-since\":           40,\n\t\t\"if-none-match\":               41,\n\t\t\"if-range\":                    42,\n\t\t\"if-unmodified-since\":         43,\n\t\t\"last-modified\":               44,\n\t\t\"link\":                        45,\n\t\t\"location\":                    46,\n\t\t\"max-forwards\":                47,\n\t\t\"proxy-authenticate\":          48,\n\t\t\"proxy-authorization\":         49,\n\t\t\"range\":                       50,\n\t\t\"referer\":                     51,\n\t\t\"refresh\":                     52,\n\t\t\"retry-after\":                 53,\n\t\t\"server\":                      54,\n\t\t\"set-cookie\":                  55,\n\t\t\"strict-transport-security\":   56,\n\t\t\"transfer-encoding\":           57,\n\t\t\"user-agent\":                  58,\n\t\t\"vary\":                        59,\n\t\t\"via\":                         60,\n\t\t\"www-authenticate\":            61,\n\t},\n\tbyNameValue: map[pairNameValue]uint64{\n\t\t{name: \":authority\", value: \"\"}:                   1,\n\t\t{name: \":method\", value: \"GET\"}:                   2,\n\t\t{name: \":method\", value: \"POST\"}:                  3,\n\t\t{name: \":path\", value: \"/\"}:                       4,\n\t\t{name: \":path\", value: \"/index.html\"}:             5,\n\t\t{name: \":scheme\", value: \"http\"}:                  6,\n\t\t{name: \":scheme\", value: \"https\"}:                 7,\n\t\t{name: \":status\", value: \"200\"}:                   8,\n\t\t{name: \":status\", value: \"204\"}:                   9,\n\t\t{name: \":status\", value: \"206\"}:                   10,\n\t\t{name: \":status\", value: \"304\"}:                   11,\n\t\t{name: \":status\", value: \"400\"}:                   12,\n\t\t{name: \":status\", value: \"404\"}:                   13,\n\t\t{name: \":status\", value: \"500\"}:                   14,\n\t\t{name: \"accept-charset\", value: \"\"}:               15,\n\t\t{name: \"accept-encoding\", value: \"gzip, deflate\"}: 16,\n\t\t{name: \"accept-language\", value: \"\"}:              17,\n\t\t{name: \"accept-ranges\", value: \"\"}:                18,\n\t\t{name: \"accept\", value: \"\"}:                       19,\n\t\t{name: \"access-control-allow-origin\", value: \"\"}:  20,\n\t\t{name: \"age\", value: \"\"}:                          21,\n\t\t{name: \"allow\", value: \"\"}:                        22,\n\t\t{name: \"authorization\", value: \"\"}:                23,\n\t\t{name: \"cache-control\", value: \"\"}:                24,\n\t\t{name: \"content-disposition\", value: \"\"}:          25,\n\t\t{name: \"content-encoding\", value: \"\"}:             26,\n\t\t{name: \"content-language\", value: \"\"}:             27,\n\t\t{name: \"content-length\", value: \"\"}:               28,\n\t\t{name: \"content-location\", value: \"\"}:             29,\n\t\t{name: \"content-range\", value: \"\"}:                30,\n\t\t{name: \"content-type\", value: \"\"}:                 31,\n\t\t{name: \"cookie\", value: \"\"}:                       32,\n\t\t{name: \"date\", value: \"\"}:                         33,\n\t\t{name: \"etag\", value: \"\"}:                         34,\n\t\t{name: \"expect\", value: \"\"}:                       35,\n\t\t{name: \"expires\", value: \"\"}:                      36,\n\t\t{name: \"from\", value: \"\"}:                         37,\n\t\t{name: \"host\", value: \"\"}:                         38,\n\t\t{name: \"if-match\", value: \"\"}:                     39,\n\t\t{name: \"if-modified-since\", value: \"\"}:            40,\n\t\t{name: \"if-none-match\", value: \"\"}:                41,\n\t\t{name: \"if-range\", value: \"\"}:                     42,\n\t\t{name: \"if-unmodified-since\", value: \"\"}:          43,\n\t\t{name: \"last-modified\", value: \"\"}:                44,\n\t\t{name: \"link\", value: \"\"}:                         45,\n\t\t{name: \"location\", value: \"\"}:                     46,\n\t\t{name: \"max-forwards\", value: \"\"}:                 47,\n\t\t{name: \"proxy-authenticate\", value: \"\"}:           48,\n\t\t{name: \"proxy-authorization\", value: \"\"}:          49,\n\t\t{name: \"range\", value: \"\"}:                        50,\n\t\t{name: \"referer\", value: \"\"}:                      51,\n\t\t{name: \"refresh\", value: \"\"}:                      52,\n\t\t{name: \"retry-after\", value: \"\"}:                  53,\n\t\t{name: \"server\", value: \"\"}:                       54,\n\t\t{name: \"set-cookie\", value: \"\"}:                   55,\n\t\t{name: \"strict-transport-security\", value: \"\"}:    56,\n\t\t{name: \"transfer-encoding\", value: \"\"}:            57,\n\t\t{name: \"user-agent\", value: \"\"}:                   58,\n\t\t{name: \"vary\", value: \"\"}:                         59,\n\t\t{name: \"via\", value: \"\"}:                          60,\n\t\t{name: \"www-authenticate\", value: \"\"}:             61,\n\t},\n\tents: []HeaderField{\n\t\t{Name: \":authority\", Value: \"\", Sensitive: false},\n\t\t{Name: \":method\", Value: \"GET\", Sensitive: false},\n\t\t{Name: \":method\", Value: \"POST\", Sensitive: false},\n\t\t{Name: \":path\", Value: \"/\", Sensitive: false},\n\t\t{Name: \":path\", Value: \"/index.html\", Sensitive: false},\n\t\t{Name: \":scheme\", Value: \"http\", Sensitive: false},\n\t\t{Name: \":scheme\", Value: \"https\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"200\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"204\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"206\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"304\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"400\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"404\", Sensitive: false},\n\t\t{Name: \":status\", Value: \"500\", Sensitive: false},\n\t\t{Name: \"accept-charset\", Value: \"\", Sensitive: false},\n\t\t{Name: \"accept-encoding\", Value: \"gzip, deflate\", Sensitive: false},\n\t\t{Name: \"accept-language\", Value: \"\", Sensitive: false},\n\t\t{Name: \"accept-ranges\", Value: \"\", Sensitive: false},\n\t\t{Name: \"accept\", Value: \"\", Sensitive: false},\n\t\t{Name: \"access-control-allow-origin\", Value: \"\", Sensitive: false},\n\t\t{Name: \"age\", Value: \"\", Sensitive: false},\n\t\t{Name: \"allow\", Value: \"\", Sensitive: false},\n\t\t{Name: \"authorization\", Value: \"\", Sensitive: false},\n\t\t{Name: \"cache-control\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-disposition\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-encoding\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-language\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-length\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-location\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-range\", Value: \"\", Sensitive: false},\n\t\t{Name: \"content-type\", Value: \"\", Sensitive: false},\n\t\t{Name: \"cookie\", Value: \"\", Sensitive: false},\n\t\t{Name: \"date\", Value: \"\", Sensitive: false},\n\t\t{Name: \"etag\", Value: \"\", Sensitive: false},\n\t\t{Name: \"expect\", Value: \"\", Sensitive: false},\n\t\t{Name: \"expires\", Value: \"\", Sensitive: false},\n\t\t{Name: \"from\", Value: \"\", Sensitive: false},\n\t\t{Name: \"host\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-match\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-modified-since\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-none-match\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-range\", Value: \"\", Sensitive: false},\n\t\t{Name: \"if-unmodified-since\", Value: \"\", Sensitive: false},\n\t\t{Name: \"last-modified\", Value: \"\", Sensitive: false},\n\t\t{Name: \"link\", Value: \"\", Sensitive: false},\n\t\t{Name: \"location\", Value: \"\", Sensitive: false},\n\t\t{Name: \"max-forwards\", Value: \"\", Sensitive: false},\n\t\t{Name: \"proxy-authenticate\", Value: \"\", Sensitive: false},\n\t\t{Name: \"proxy-authorization\", Value: \"\", Sensitive: false},\n\t\t{Name: \"range\", Value: \"\", Sensitive: false},\n\t\t{Name: \"referer\", Value: \"\", Sensitive: false},\n\t\t{Name: \"refresh\", Value: \"\", Sensitive: false},\n\t\t{Name: \"retry-after\", Value: \"\", Sensitive: false},\n\t\t{Name: \"server\", Value: \"\", Sensitive: false},\n\t\t{Name: \"set-cookie\", Value: \"\", Sensitive: false},\n\t\t{Name: \"strict-transport-security\", Value: \"\", Sensitive: false},\n\t\t{Name: \"transfer-encoding\", Value: \"\", Sensitive: false},\n\t\t{Name: \"user-agent\", Value: \"\", Sensitive: false},\n\t\t{Name: \"vary\", Value: \"\", Sensitive: false},\n\t\t{Name: \"via\", Value: \"\", Sensitive: false},\n\t\t{Name: \"www-authenticate\", Value: \"\", Sensitive: false},\n\t},\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/hpack/tables.go",
    "content": "// Copyright 2014 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 hpack\n\nimport (\n\t\"fmt\"\n)\n\n// headerFieldTable implements a list of HeaderFields.\n// This is used to implement the static and dynamic tables.\ntype headerFieldTable struct {\n\t// For static tables, entries are never evicted.\n\t//\n\t// For dynamic tables, entries are evicted from ents[0] and added to the end.\n\t// Each entry has a unique id that starts at one and increments for each\n\t// entry that is added. This unique id is stable across evictions, meaning\n\t// it can be used as a pointer to a specific entry. As in hpack, unique ids\n\t// are 1-based. The unique id for ents[k] is k + evictCount + 1.\n\t//\n\t// Zero is not a valid unique id.\n\t//\n\t// evictCount should not overflow in any remotely practical situation. In\n\t// practice, we will have one dynamic table per HTTP/2 connection. If we\n\t// assume a very powerful server that handles 1M QPS per connection and each\n\t// request adds (then evicts) 100 entries from the table, it would still take\n\t// 2M years for evictCount to overflow.\n\tents       []HeaderField\n\tevictCount uint64\n\n\t// byName maps a HeaderField name to the unique id of the newest entry with\n\t// the same name. See above for a definition of \"unique id\".\n\tbyName map[string]uint64\n\n\t// byNameValue maps a HeaderField name/value pair to the unique id of the newest\n\t// entry with the same name and value. See above for a definition of \"unique id\".\n\tbyNameValue map[pairNameValue]uint64\n}\n\ntype pairNameValue struct {\n\tname, value string\n}\n\nfunc (t *headerFieldTable) init() {\n\tt.byName = make(map[string]uint64)\n\tt.byNameValue = make(map[pairNameValue]uint64)\n}\n\n// len reports the number of entries in the table.\nfunc (t *headerFieldTable) len() int {\n\treturn len(t.ents)\n}\n\n// addEntry adds a new entry.\nfunc (t *headerFieldTable) addEntry(f HeaderField) {\n\tid := uint64(t.len()) + t.evictCount + 1\n\tt.byName[f.Name] = id\n\tt.byNameValue[pairNameValue{f.Name, f.Value}] = id\n\tt.ents = append(t.ents, f)\n}\n\n// evictOldest evicts the n oldest entries in the table.\nfunc (t *headerFieldTable) evictOldest(n int) {\n\tif n > t.len() {\n\t\tpanic(fmt.Sprintf(\"evictOldest(%v) on table with %v entries\", n, t.len()))\n\t}\n\tfor k := 0; k < n; k++ {\n\t\tf := t.ents[k]\n\t\tid := t.evictCount + uint64(k) + 1\n\t\tif t.byName[f.Name] == id {\n\t\t\tdelete(t.byName, f.Name)\n\t\t}\n\t\tif p := (pairNameValue{f.Name, f.Value}); t.byNameValue[p] == id {\n\t\t\tdelete(t.byNameValue, p)\n\t\t}\n\t}\n\tcopy(t.ents, t.ents[n:])\n\tfor k := t.len() - n; k < t.len(); k++ {\n\t\tt.ents[k] = HeaderField{} // so strings can be garbage collected\n\t}\n\tt.ents = t.ents[:t.len()-n]\n\tif t.evictCount+uint64(n) < t.evictCount {\n\t\tpanic(\"evictCount overflow\")\n\t}\n\tt.evictCount += uint64(n)\n}\n\n// search finds f in the table. If there is no match, i is 0.\n// If both name and value match, i is the matched index and nameValueMatch\n// becomes true. If only name matches, i points to that index and\n// nameValueMatch becomes false.\n//\n// The returned index is a 1-based HPACK index. For dynamic tables, HPACK says\n// that index 1 should be the newest entry, but t.ents[0] is the oldest entry,\n// meaning t.ents is reversed for dynamic tables. Hence, when t is a dynamic\n// table, the return value i actually refers to the entry t.ents[t.len()-i].\n//\n// All tables are assumed to be a dynamic tables except for the global staticTable.\n//\n// See Section 2.3.3.\nfunc (t *headerFieldTable) search(f HeaderField) (i uint64, nameValueMatch bool) {\n\tif !f.Sensitive {\n\t\tif id := t.byNameValue[pairNameValue{f.Name, f.Value}]; id != 0 {\n\t\t\treturn t.idToIndex(id), true\n\t\t}\n\t}\n\tif id := t.byName[f.Name]; id != 0 {\n\t\treturn t.idToIndex(id), false\n\t}\n\treturn 0, false\n}\n\n// idToIndex converts a unique id to an HPACK index.\n// See Section 2.3.3.\nfunc (t *headerFieldTable) idToIndex(id uint64) uint64 {\n\tif id <= t.evictCount {\n\t\tpanic(fmt.Sprintf(\"id (%v) <= evictCount (%v)\", id, t.evictCount))\n\t}\n\tk := id - t.evictCount - 1 // convert id to an index t.ents[k]\n\tif t != staticTable {\n\t\treturn uint64(t.len()) - k // dynamic table\n\t}\n\treturn k + 1\n}\n\nvar huffmanCodes = [256]uint32{\n\t0x1ff8,\n\t0x7fffd8,\n\t0xfffffe2,\n\t0xfffffe3,\n\t0xfffffe4,\n\t0xfffffe5,\n\t0xfffffe6,\n\t0xfffffe7,\n\t0xfffffe8,\n\t0xffffea,\n\t0x3ffffffc,\n\t0xfffffe9,\n\t0xfffffea,\n\t0x3ffffffd,\n\t0xfffffeb,\n\t0xfffffec,\n\t0xfffffed,\n\t0xfffffee,\n\t0xfffffef,\n\t0xffffff0,\n\t0xffffff1,\n\t0xffffff2,\n\t0x3ffffffe,\n\t0xffffff3,\n\t0xffffff4,\n\t0xffffff5,\n\t0xffffff6,\n\t0xffffff7,\n\t0xffffff8,\n\t0xffffff9,\n\t0xffffffa,\n\t0xffffffb,\n\t0x14,\n\t0x3f8,\n\t0x3f9,\n\t0xffa,\n\t0x1ff9,\n\t0x15,\n\t0xf8,\n\t0x7fa,\n\t0x3fa,\n\t0x3fb,\n\t0xf9,\n\t0x7fb,\n\t0xfa,\n\t0x16,\n\t0x17,\n\t0x18,\n\t0x0,\n\t0x1,\n\t0x2,\n\t0x19,\n\t0x1a,\n\t0x1b,\n\t0x1c,\n\t0x1d,\n\t0x1e,\n\t0x1f,\n\t0x5c,\n\t0xfb,\n\t0x7ffc,\n\t0x20,\n\t0xffb,\n\t0x3fc,\n\t0x1ffa,\n\t0x21,\n\t0x5d,\n\t0x5e,\n\t0x5f,\n\t0x60,\n\t0x61,\n\t0x62,\n\t0x63,\n\t0x64,\n\t0x65,\n\t0x66,\n\t0x67,\n\t0x68,\n\t0x69,\n\t0x6a,\n\t0x6b,\n\t0x6c,\n\t0x6d,\n\t0x6e,\n\t0x6f,\n\t0x70,\n\t0x71,\n\t0x72,\n\t0xfc,\n\t0x73,\n\t0xfd,\n\t0x1ffb,\n\t0x7fff0,\n\t0x1ffc,\n\t0x3ffc,\n\t0x22,\n\t0x7ffd,\n\t0x3,\n\t0x23,\n\t0x4,\n\t0x24,\n\t0x5,\n\t0x25,\n\t0x26,\n\t0x27,\n\t0x6,\n\t0x74,\n\t0x75,\n\t0x28,\n\t0x29,\n\t0x2a,\n\t0x7,\n\t0x2b,\n\t0x76,\n\t0x2c,\n\t0x8,\n\t0x9,\n\t0x2d,\n\t0x77,\n\t0x78,\n\t0x79,\n\t0x7a,\n\t0x7b,\n\t0x7ffe,\n\t0x7fc,\n\t0x3ffd,\n\t0x1ffd,\n\t0xffffffc,\n\t0xfffe6,\n\t0x3fffd2,\n\t0xfffe7,\n\t0xfffe8,\n\t0x3fffd3,\n\t0x3fffd4,\n\t0x3fffd5,\n\t0x7fffd9,\n\t0x3fffd6,\n\t0x7fffda,\n\t0x7fffdb,\n\t0x7fffdc,\n\t0x7fffdd,\n\t0x7fffde,\n\t0xffffeb,\n\t0x7fffdf,\n\t0xffffec,\n\t0xffffed,\n\t0x3fffd7,\n\t0x7fffe0,\n\t0xffffee,\n\t0x7fffe1,\n\t0x7fffe2,\n\t0x7fffe3,\n\t0x7fffe4,\n\t0x1fffdc,\n\t0x3fffd8,\n\t0x7fffe5,\n\t0x3fffd9,\n\t0x7fffe6,\n\t0x7fffe7,\n\t0xffffef,\n\t0x3fffda,\n\t0x1fffdd,\n\t0xfffe9,\n\t0x3fffdb,\n\t0x3fffdc,\n\t0x7fffe8,\n\t0x7fffe9,\n\t0x1fffde,\n\t0x7fffea,\n\t0x3fffdd,\n\t0x3fffde,\n\t0xfffff0,\n\t0x1fffdf,\n\t0x3fffdf,\n\t0x7fffeb,\n\t0x7fffec,\n\t0x1fffe0,\n\t0x1fffe1,\n\t0x3fffe0,\n\t0x1fffe2,\n\t0x7fffed,\n\t0x3fffe1,\n\t0x7fffee,\n\t0x7fffef,\n\t0xfffea,\n\t0x3fffe2,\n\t0x3fffe3,\n\t0x3fffe4,\n\t0x7ffff0,\n\t0x3fffe5,\n\t0x3fffe6,\n\t0x7ffff1,\n\t0x3ffffe0,\n\t0x3ffffe1,\n\t0xfffeb,\n\t0x7fff1,\n\t0x3fffe7,\n\t0x7ffff2,\n\t0x3fffe8,\n\t0x1ffffec,\n\t0x3ffffe2,\n\t0x3ffffe3,\n\t0x3ffffe4,\n\t0x7ffffde,\n\t0x7ffffdf,\n\t0x3ffffe5,\n\t0xfffff1,\n\t0x1ffffed,\n\t0x7fff2,\n\t0x1fffe3,\n\t0x3ffffe6,\n\t0x7ffffe0,\n\t0x7ffffe1,\n\t0x3ffffe7,\n\t0x7ffffe2,\n\t0xfffff2,\n\t0x1fffe4,\n\t0x1fffe5,\n\t0x3ffffe8,\n\t0x3ffffe9,\n\t0xffffffd,\n\t0x7ffffe3,\n\t0x7ffffe4,\n\t0x7ffffe5,\n\t0xfffec,\n\t0xfffff3,\n\t0xfffed,\n\t0x1fffe6,\n\t0x3fffe9,\n\t0x1fffe7,\n\t0x1fffe8,\n\t0x7ffff3,\n\t0x3fffea,\n\t0x3fffeb,\n\t0x1ffffee,\n\t0x1ffffef,\n\t0xfffff4,\n\t0xfffff5,\n\t0x3ffffea,\n\t0x7ffff4,\n\t0x3ffffeb,\n\t0x7ffffe6,\n\t0x3ffffec,\n\t0x3ffffed,\n\t0x7ffffe7,\n\t0x7ffffe8,\n\t0x7ffffe9,\n\t0x7ffffea,\n\t0x7ffffeb,\n\t0xffffffe,\n\t0x7ffffec,\n\t0x7ffffed,\n\t0x7ffffee,\n\t0x7ffffef,\n\t0x7fffff0,\n\t0x3ffffee,\n}\n\nvar huffmanCodeLen = [256]uint8{\n\t13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28,\n\t28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28,\n\t6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6,\n\t5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10,\n\t13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n\t7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6,\n\t15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5,\n\t6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28,\n\t20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23,\n\t24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24,\n\t22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23,\n\t21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23,\n\t26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25,\n\t19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27,\n\t20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23,\n\t26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26,\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/http2.go",
    "content": "// Copyright 2014 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// Package http2 implements the HTTP/2 protocol.\n//\n// This package is low-level and intended to be used directly by very\n// few people. Most users will use it indirectly through the automatic\n// use by the net/http package (from Go 1.6 and later).\n// For use in earlier Go versions see ConfigureServer. (Transport support\n// requires Go 1.6 or later)\n//\n// See https://http2.github.io/ for more information on HTTP/2.\npackage http2 // import \"golang.org/x/net/http2\"\n\nimport (\n\t\"bufio\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"net\"\n\t\"net/http\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/net/http/httpguts\"\n)\n\nvar (\n\tVerboseLogs    bool\n\tlogFrameWrites bool\n\tlogFrameReads  bool\n\n\t// Enabling extended CONNECT by causes browsers to attempt to use\n\t// WebSockets-over-HTTP/2. This results in problems when the server's websocket\n\t// package doesn't support extended CONNECT.\n\t//\n\t// Disable extended CONNECT by default for now.\n\t//\n\t// Issue #71128.\n\tdisableExtendedConnectProtocol = true\n)\n\nfunc init() {\n\te := os.Getenv(\"GODEBUG\")\n\tif strings.Contains(e, \"http2debug=1\") {\n\t\tVerboseLogs = true\n\t}\n\tif strings.Contains(e, \"http2debug=2\") {\n\t\tVerboseLogs = true\n\t\tlogFrameWrites = true\n\t\tlogFrameReads = true\n\t}\n\tif strings.Contains(e, \"http2xconnect=1\") {\n\t\tdisableExtendedConnectProtocol = false\n\t}\n}\n\nconst (\n\t// ClientPreface is the string that must be sent by new\n\t// connections from clients.\n\tClientPreface = \"PRI * HTTP/2.0\\r\\n\\r\\nSM\\r\\n\\r\\n\"\n\n\t// SETTINGS_MAX_FRAME_SIZE default\n\t// https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2\n\tinitialMaxFrameSize = 16384\n\n\t// NextProtoTLS is the NPN/ALPN protocol negotiated during\n\t// HTTP/2's TLS setup.\n\tNextProtoTLS = \"h2\"\n\n\t// https://httpwg.org/specs/rfc7540.html#SettingValues\n\tinitialHeaderTableSize = 4096\n\n\tinitialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size\n\n\tdefaultMaxReadFrameSize = 1 << 20\n)\n\nvar (\n\tclientPreface = []byte(ClientPreface)\n)\n\ntype streamState int\n\n// HTTP/2 stream states.\n//\n// See http://tools.ietf.org/html/rfc7540#section-5.1.\n//\n// For simplicity, the server code merges \"reserved (local)\" into\n// \"half-closed (remote)\". This is one less state transition to track.\n// The only downside is that we send PUSH_PROMISEs slightly less\n// liberally than allowable. More discussion here:\n// https://lists.w3.org/Archives/Public/ietf-http-wg/2016JulSep/0599.html\n//\n// \"reserved (remote)\" is omitted since the client code does not\n// support server push.\nconst (\n\tstateIdle streamState = iota\n\tstateOpen\n\tstateHalfClosedLocal\n\tstateHalfClosedRemote\n\tstateClosed\n)\n\nvar stateName = [...]string{\n\tstateIdle:             \"Idle\",\n\tstateOpen:             \"Open\",\n\tstateHalfClosedLocal:  \"HalfClosedLocal\",\n\tstateHalfClosedRemote: \"HalfClosedRemote\",\n\tstateClosed:           \"Closed\",\n}\n\nfunc (st streamState) String() string {\n\treturn stateName[st]\n}\n\n// Setting is a setting parameter: which setting it is, and its value.\ntype Setting struct {\n\t// ID is which setting is being set.\n\t// See https://httpwg.org/specs/rfc7540.html#SettingFormat\n\tID SettingID\n\n\t// Val is the value.\n\tVal uint32\n}\n\nfunc (s Setting) String() string {\n\treturn fmt.Sprintf(\"[%v = %d]\", s.ID, s.Val)\n}\n\n// Valid reports whether the setting is valid.\nfunc (s Setting) Valid() error {\n\t// Limits and error codes from 6.5.2 Defined SETTINGS Parameters\n\tswitch s.ID {\n\tcase SettingEnablePush:\n\t\tif s.Val != 1 && s.Val != 0 {\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\tcase SettingInitialWindowSize:\n\t\tif s.Val > 1<<31-1 {\n\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t}\n\tcase SettingMaxFrameSize:\n\t\tif s.Val < 16384 || s.Val > 1<<24-1 {\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\tcase SettingEnableConnectProtocol:\n\t\tif s.Val != 1 && s.Val != 0 {\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\t}\n\treturn nil\n}\n\n// A SettingID is an HTTP/2 setting as defined in\n// https://httpwg.org/specs/rfc7540.html#iana-settings\ntype SettingID uint16\n\nconst (\n\tSettingHeaderTableSize       SettingID = 0x1\n\tSettingEnablePush            SettingID = 0x2\n\tSettingMaxConcurrentStreams  SettingID = 0x3\n\tSettingInitialWindowSize     SettingID = 0x4\n\tSettingMaxFrameSize          SettingID = 0x5\n\tSettingMaxHeaderListSize     SettingID = 0x6\n\tSettingEnableConnectProtocol SettingID = 0x8\n)\n\nvar settingName = map[SettingID]string{\n\tSettingHeaderTableSize:       \"HEADER_TABLE_SIZE\",\n\tSettingEnablePush:            \"ENABLE_PUSH\",\n\tSettingMaxConcurrentStreams:  \"MAX_CONCURRENT_STREAMS\",\n\tSettingInitialWindowSize:     \"INITIAL_WINDOW_SIZE\",\n\tSettingMaxFrameSize:          \"MAX_FRAME_SIZE\",\n\tSettingMaxHeaderListSize:     \"MAX_HEADER_LIST_SIZE\",\n\tSettingEnableConnectProtocol: \"ENABLE_CONNECT_PROTOCOL\",\n}\n\nfunc (s SettingID) String() string {\n\tif v, ok := settingName[s]; ok {\n\t\treturn v\n\t}\n\treturn fmt.Sprintf(\"UNKNOWN_SETTING_%d\", uint16(s))\n}\n\n// validWireHeaderFieldName reports whether v is a valid header field\n// name (key). See httpguts.ValidHeaderName for the base rules.\n//\n// Further, http2 says:\n//\n//\t\"Just as in HTTP/1.x, header field names are strings of ASCII\n//\tcharacters that are compared in a case-insensitive\n//\tfashion. However, header field names MUST be converted to\n//\tlowercase prior to their encoding in HTTP/2. \"\nfunc validWireHeaderFieldName(v string) bool {\n\tif len(v) == 0 {\n\t\treturn false\n\t}\n\tfor _, r := range v {\n\t\tif !httpguts.IsTokenRune(r) {\n\t\t\treturn false\n\t\t}\n\t\tif 'A' <= r && r <= 'Z' {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc httpCodeString(code int) string {\n\tswitch code {\n\tcase 200:\n\t\treturn \"200\"\n\tcase 404:\n\t\treturn \"404\"\n\t}\n\treturn strconv.Itoa(code)\n}\n\n// from pkg io\ntype stringWriter interface {\n\tWriteString(s string) (n int, err error)\n}\n\n// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed).\ntype closeWaiter chan struct{}\n\n// Init makes a closeWaiter usable.\n// It exists because so a closeWaiter value can be placed inside a\n// larger struct and have the Mutex and Cond's memory in the same\n// allocation.\nfunc (cw *closeWaiter) Init() {\n\t*cw = make(chan struct{})\n}\n\n// Close marks the closeWaiter as closed and unblocks any waiters.\nfunc (cw closeWaiter) Close() {\n\tclose(cw)\n}\n\n// Wait waits for the closeWaiter to become closed.\nfunc (cw closeWaiter) Wait() {\n\t<-cw\n}\n\n// bufferedWriter is a buffered writer that writes to w.\n// Its buffered writer is lazily allocated as needed, to minimize\n// idle memory usage with many connections.\ntype bufferedWriter struct {\n\t_           incomparable\n\tconn        net.Conn      // immutable\n\tbw          *bufio.Writer // non-nil when data is buffered\n\tbyteTimeout time.Duration // immutable, WriteByteTimeout\n}\n\nfunc newBufferedWriter(conn net.Conn, timeout time.Duration) *bufferedWriter {\n\treturn &bufferedWriter{\n\t\tconn:        conn,\n\t\tbyteTimeout: timeout,\n\t}\n}\n\n// bufWriterPoolBufferSize is the size of bufio.Writer's\n// buffers created using bufWriterPool.\n//\n// TODO: pick a less arbitrary value? this is a bit under\n// (3 x typical 1500 byte MTU) at least. Other than that,\n// not much thought went into it.\nconst bufWriterPoolBufferSize = 4 << 10\n\nvar bufWriterPool = sync.Pool{\n\tNew: func() interface{} {\n\t\treturn bufio.NewWriterSize(nil, bufWriterPoolBufferSize)\n\t},\n}\n\nfunc (w *bufferedWriter) Available() int {\n\tif w.bw == nil {\n\t\treturn bufWriterPoolBufferSize\n\t}\n\treturn w.bw.Available()\n}\n\nfunc (w *bufferedWriter) Write(p []byte) (n int, err error) {\n\tif w.bw == nil {\n\t\tbw := bufWriterPool.Get().(*bufio.Writer)\n\t\tbw.Reset((*bufferedWriterTimeoutWriter)(w))\n\t\tw.bw = bw\n\t}\n\treturn w.bw.Write(p)\n}\n\nfunc (w *bufferedWriter) Flush() error {\n\tbw := w.bw\n\tif bw == nil {\n\t\treturn nil\n\t}\n\terr := bw.Flush()\n\tbw.Reset(nil)\n\tbufWriterPool.Put(bw)\n\tw.bw = nil\n\treturn err\n}\n\ntype bufferedWriterTimeoutWriter bufferedWriter\n\nfunc (w *bufferedWriterTimeoutWriter) Write(p []byte) (n int, err error) {\n\treturn writeWithByteTimeout(w.conn, w.byteTimeout, p)\n}\n\n// writeWithByteTimeout writes to conn.\n// If more than timeout passes without any bytes being written to the connection,\n// the write fails.\nfunc writeWithByteTimeout(conn net.Conn, timeout time.Duration, p []byte) (n int, err error) {\n\tif timeout <= 0 {\n\t\treturn conn.Write(p)\n\t}\n\tfor {\n\t\tconn.SetWriteDeadline(time.Now().Add(timeout))\n\t\tnn, err := conn.Write(p[n:])\n\t\tn += nn\n\t\tif n == len(p) || nn == 0 || !errors.Is(err, os.ErrDeadlineExceeded) {\n\t\t\t// Either we finished the write, made no progress, or hit the deadline.\n\t\t\t// Whichever it is, we're done now.\n\t\t\tconn.SetWriteDeadline(time.Time{})\n\t\t\treturn n, err\n\t\t}\n\t}\n}\n\nfunc mustUint31(v int32) uint32 {\n\tif v < 0 || v > 2147483647 {\n\t\tpanic(\"out of range\")\n\t}\n\treturn uint32(v)\n}\n\n// bodyAllowedForStatus reports whether a given response status code\n// permits a body. See RFC 7230, section 3.3.\nfunc bodyAllowedForStatus(status int) bool {\n\tswitch {\n\tcase status >= 100 && status <= 199:\n\t\treturn false\n\tcase status == 204:\n\t\treturn false\n\tcase status == 304:\n\t\treturn false\n\t}\n\treturn true\n}\n\ntype httpError struct {\n\t_       incomparable\n\tmsg     string\n\ttimeout bool\n}\n\nfunc (e *httpError) Error() string   { return e.msg }\nfunc (e *httpError) Timeout() bool   { return e.timeout }\nfunc (e *httpError) Temporary() bool { return true }\n\nvar errTimeout error = &httpError{msg: \"http2: timeout awaiting response headers\", timeout: true}\n\ntype connectionStater interface {\n\tConnectionState() tls.ConnectionState\n}\n\nvar sorterPool = sync.Pool{New: func() interface{} { return new(sorter) }}\n\ntype sorter struct {\n\tv []string // owned by sorter\n}\n\nfunc (s *sorter) Len() int           { return len(s.v) }\nfunc (s *sorter) Swap(i, j int)      { s.v[i], s.v[j] = s.v[j], s.v[i] }\nfunc (s *sorter) Less(i, j int) bool { return s.v[i] < s.v[j] }\n\n// Keys returns the sorted keys of h.\n//\n// The returned slice is only valid until s used again or returned to\n// its pool.\nfunc (s *sorter) Keys(h http.Header) []string {\n\tkeys := s.v[:0]\n\tfor k := range h {\n\t\tkeys = append(keys, k)\n\t}\n\ts.v = keys\n\tsort.Sort(s)\n\treturn keys\n}\n\nfunc (s *sorter) SortStrings(ss []string) {\n\t// Our sorter works on s.v, which sorter owns, so\n\t// stash it away while we sort the user's buffer.\n\tsave := s.v\n\ts.v = ss\n\tsort.Sort(s)\n\ts.v = save\n}\n\n// incomparable is a zero-width, non-comparable type. Adding it to a struct\n// makes that struct also non-comparable, and generally doesn't add\n// any size (as long as it's first).\ntype incomparable [0]func()\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/pipe.go",
    "content": "// Copyright 2014 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 http2\n\nimport (\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n)\n\n// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like\n// io.Pipe except there are no PipeReader/PipeWriter halves, and the\n// underlying buffer is an interface. (io.Pipe is always unbuffered)\ntype pipe struct {\n\tmu       sync.Mutex\n\tc        sync.Cond     // c.L lazily initialized to &p.mu\n\tb        pipeBuffer    // nil when done reading\n\tunread   int           // bytes unread when done\n\terr      error         // read error once empty. non-nil means closed.\n\tbreakErr error         // immediate read error (caller doesn't see rest of b)\n\tdonec    chan struct{} // closed on error\n\treadFn   func()        // optional code to run in Read before error\n}\n\ntype pipeBuffer interface {\n\tLen() int\n\tio.Writer\n\tio.Reader\n}\n\n// setBuffer initializes the pipe buffer.\n// It has no effect if the pipe is already closed.\nfunc (p *pipe) setBuffer(b pipeBuffer) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.err != nil || p.breakErr != nil {\n\t\treturn\n\t}\n\tp.b = b\n}\n\nfunc (p *pipe) Len() int {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.b == nil {\n\t\treturn p.unread\n\t}\n\treturn p.b.Len()\n}\n\n// Read waits until data is available and copies bytes\n// from the buffer into p.\nfunc (p *pipe) Read(d []byte) (n int, err error) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.c.L == nil {\n\t\tp.c.L = &p.mu\n\t}\n\tfor {\n\t\tif p.breakErr != nil {\n\t\t\treturn 0, p.breakErr\n\t\t}\n\t\tif p.b != nil && p.b.Len() > 0 {\n\t\t\treturn p.b.Read(d)\n\t\t}\n\t\tif p.err != nil {\n\t\t\tif p.readFn != nil {\n\t\t\t\tp.readFn()     // e.g. copy trailers\n\t\t\t\tp.readFn = nil // not sticky like p.err\n\t\t\t}\n\t\t\tp.b = nil\n\t\t\treturn 0, p.err\n\t\t}\n\t\tp.c.Wait()\n\t}\n}\n\nvar (\n\terrClosedPipeWrite        = errors.New(\"write on closed buffer\")\n\terrUninitializedPipeWrite = errors.New(\"write on uninitialized buffer\")\n)\n\n// Write copies bytes from p into the buffer and wakes a reader.\n// It is an error to write more data than the buffer can hold.\nfunc (p *pipe) Write(d []byte) (n int, err error) {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.c.L == nil {\n\t\tp.c.L = &p.mu\n\t}\n\tdefer p.c.Signal()\n\tif p.err != nil || p.breakErr != nil {\n\t\treturn 0, errClosedPipeWrite\n\t}\n\t// pipe.setBuffer is never invoked, leaving the buffer uninitialized.\n\t// We shouldn't try to write to an uninitialized pipe,\n\t// but returning an error is better than panicking.\n\tif p.b == nil {\n\t\treturn 0, errUninitializedPipeWrite\n\t}\n\treturn p.b.Write(d)\n}\n\n// CloseWithError causes the next Read (waking up a current blocked\n// Read if needed) to return the provided err after all data has been\n// read.\n//\n// The error must be non-nil.\nfunc (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) }\n\n// BreakWithError causes the next Read (waking up a current blocked\n// Read if needed) to return the provided err immediately, without\n// waiting for unread data.\nfunc (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) }\n\n// closeWithErrorAndCode is like CloseWithError but also sets some code to run\n// in the caller's goroutine before returning the error.\nfunc (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) }\n\nfunc (p *pipe) closeWithError(dst *error, err error, fn func()) {\n\tif err == nil {\n\t\tpanic(\"err must be non-nil\")\n\t}\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.c.L == nil {\n\t\tp.c.L = &p.mu\n\t}\n\tdefer p.c.Signal()\n\tif *dst != nil {\n\t\t// Already been done.\n\t\treturn\n\t}\n\tp.readFn = fn\n\tif dst == &p.breakErr {\n\t\tif p.b != nil {\n\t\t\tp.unread += p.b.Len()\n\t\t}\n\t\tp.b = nil\n\t}\n\t*dst = err\n\tp.closeDoneLocked()\n}\n\n// requires p.mu be held.\nfunc (p *pipe) closeDoneLocked() {\n\tif p.donec == nil {\n\t\treturn\n\t}\n\t// Close if unclosed. This isn't racy since we always\n\t// hold p.mu while closing.\n\tselect {\n\tcase <-p.donec:\n\tdefault:\n\t\tclose(p.donec)\n\t}\n}\n\n// Err returns the error (if any) first set by BreakWithError or CloseWithError.\nfunc (p *pipe) Err() error {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.breakErr != nil {\n\t\treturn p.breakErr\n\t}\n\treturn p.err\n}\n\n// Done returns a channel which is closed if and when this pipe is closed\n// with CloseWithError.\nfunc (p *pipe) Done() <-chan struct{} {\n\tp.mu.Lock()\n\tdefer p.mu.Unlock()\n\tif p.donec == nil {\n\t\tp.donec = make(chan struct{})\n\t\tif p.err != nil || p.breakErr != nil {\n\t\t\t// Already hit an error.\n\t\t\tp.closeDoneLocked()\n\t\t}\n\t}\n\treturn p.donec\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/transport.go",
    "content": "// Copyright 2015 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// Transport code.\n\npackage http2\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/flate\"\n\t\"compress/gzip\"\n\t\"context\"\n\t\"crypto/rand\"\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/fs\"\n\t\"log\"\n\t\"math\"\n\t\"math/bits\"\n\tmathrand \"math/rand\"\n\t\"net\"\n\t\"net/http\"\n\t\"net/http/httptrace\"\n\t\"net/textproto\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\t\"golang.org/x/net/http/httpguts\"\n\t\"golang.org/x/net/http2/hpack\"\n\t\"golang.org/x/net/idna\"\n\t\"golang.org/x/net/internal/httpcommon\"\n)\n\nconst (\n\t// transportDefaultConnFlow is how many connection-level flow control\n\t// tokens we give the server at start-up, past the default 64k.\n\ttransportDefaultConnFlow = 1 << 30\n\n\t// transportDefaultStreamFlow is how many stream-level flow\n\t// control tokens we announce to the peer, and how many bytes\n\t// we buffer per stream.\n\ttransportDefaultStreamFlow = 4 << 20\n\n\tdefaultUserAgent = \"Go-http-client/2.0\"\n\n\t// initialMaxConcurrentStreams is a connections maxConcurrentStreams until\n\t// it's received servers initial SETTINGS frame, which corresponds with the\n\t// spec's minimum recommended value.\n\tinitialMaxConcurrentStreams = 100\n\n\t// defaultMaxConcurrentStreams is a connections default maxConcurrentStreams\n\t// if the server doesn't include one in its initial SETTINGS frame.\n\tdefaultMaxConcurrentStreams = 1000\n)\n\n// Transport is an HTTP/2 Transport.\n//\n// A Transport internally caches connections to servers. It is safe\n// for concurrent use by multiple goroutines.\ntype Transport struct {\n\t// DialTLSContext specifies an optional dial function with context for\n\t// creating TLS connections for requests.\n\t//\n\t// If DialTLSContext and DialTLS is nil, tls.Dial is used.\n\t//\n\t// If the returned net.Conn has a ConnectionState method like tls.Conn,\n\t// it will be used to set http.Response.TLS.\n\tDialTLSContext func(ctx context.Context, network, addr string, cfg *tls.Config) (net.Conn, error)\n\n\t// DialTLS specifies an optional dial function for creating\n\t// TLS connections for requests.\n\t//\n\t// If DialTLSContext and DialTLS is nil, tls.Dial is used.\n\t//\n\t// Deprecated: Use DialTLSContext instead, which allows the transport\n\t// to cancel dials as soon as they are no longer needed.\n\t// If both are set, DialTLSContext takes priority.\n\tDialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error)\n\n\t// TLSClientConfig specifies the TLS configuration to use with\n\t// tls.Client. If nil, the default configuration is used.\n\tTLSClientConfig *tls.Config\n\n\t// ConnPool optionally specifies an alternate connection pool to use.\n\t// If nil, the default is used.\n\tConnPool ClientConnPool\n\n\t// DisableCompression, if true, prevents the Transport from\n\t// requesting compression with an \"Accept-Encoding: gzip\"\n\t// request header when the Request contains no existing\n\t// Accept-Encoding value. If the Transport requests gzip on\n\t// its own and gets a gzipped response, it's transparently\n\t// decoded in the Response.Body. However, if the user\n\t// explicitly requested gzip it is not automatically\n\t// uncompressed.\n\tDisableCompression bool\n\n\t// AllowHTTP, if true, permits HTTP/2 requests using the insecure,\n\t// plain-text \"http\" scheme. Note that this does not enable h2c support.\n\tAllowHTTP bool\n\n\t// MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to\n\t// send in the initial settings frame. It is how many bytes\n\t// of response headers are allowed. Unlike the http2 spec, zero here\n\t// means to use a default limit (currently 10MB). If you actually\n\t// want to advertise an unlimited value to the peer, Transport\n\t// interprets the highest possible value here (0xffffffff or 1<<32-1)\n\t// to mean no limit.\n\tMaxHeaderListSize uint32\n\n\t// MaxReadFrameSize is the http2 SETTINGS_MAX_FRAME_SIZE to send in the\n\t// initial settings frame. It is the size in bytes of the largest frame\n\t// payload that the sender is willing to receive. If 0, no setting is\n\t// sent, and the value is provided by the peer, which should be 16384\n\t// according to the spec:\n\t// https://datatracker.ietf.org/doc/html/rfc7540#section-6.5.2.\n\t// Values are bounded in the range 16k to 16M.\n\tMaxReadFrameSize uint32\n\n\t// MaxDecoderHeaderTableSize optionally specifies the http2\n\t// SETTINGS_HEADER_TABLE_SIZE to send in the initial settings frame. It\n\t// informs the remote endpoint of the maximum size of the header compression\n\t// table used to decode header blocks, in octets. If zero, the default value\n\t// of 4096 is used.\n\tMaxDecoderHeaderTableSize uint32\n\n\t// MaxEncoderHeaderTableSize optionally specifies an upper limit for the\n\t// header compression table used for encoding request headers. Received\n\t// SETTINGS_HEADER_TABLE_SIZE settings are capped at this limit. If zero,\n\t// the default value of 4096 is used.\n\tMaxEncoderHeaderTableSize uint32\n\n\t// StrictMaxConcurrentStreams controls whether the server's\n\t// SETTINGS_MAX_CONCURRENT_STREAMS should be respected\n\t// globally. If false, new TCP connections are created to the\n\t// server as needed to keep each under the per-connection\n\t// SETTINGS_MAX_CONCURRENT_STREAMS limit. If true, the\n\t// server's SETTINGS_MAX_CONCURRENT_STREAMS is interpreted as\n\t// a global limit and callers of RoundTrip block when needed,\n\t// waiting for their turn.\n\tStrictMaxConcurrentStreams bool\n\n\t// IdleConnTimeout is the maximum amount of time an idle\n\t// (keep-alive) connection will remain idle before closing\n\t// itself.\n\t// Zero means no limit.\n\tIdleConnTimeout time.Duration\n\n\t// ReadIdleTimeout is the timeout after which a health check using ping\n\t// frame will be carried out if no frame is received on the connection.\n\t// Note that a ping response will is considered a received frame, so if\n\t// there is no other traffic on the connection, the health check will\n\t// be performed every ReadIdleTimeout interval.\n\t// If zero, no health check is performed.\n\tReadIdleTimeout time.Duration\n\n\t// PingTimeout is the timeout after which the connection will be closed\n\t// if a response to Ping is not received.\n\t// Defaults to 15s.\n\tPingTimeout time.Duration\n\n\t// WriteByteTimeout is the timeout after which the connection will be\n\t// closed no data can be written to it. The timeout begins when data is\n\t// available to write, and is extended whenever any bytes are written.\n\tWriteByteTimeout time.Duration\n\n\t// CountError, if non-nil, is called on HTTP/2 transport errors.\n\t// It's intended to increment a metric for monitoring, such\n\t// as an expvar or Prometheus metric.\n\t// The errType consists of only ASCII word characters.\n\tCountError func(errType string)\n\n\t// t1, if non-nil, is the standard library Transport using\n\t// this transport. Its settings are used (but not its\n\t// RoundTrip method, etc).\n\tt1 *http.Transport\n\n\tconnPoolOnce  sync.Once\n\tconnPoolOrDef ClientConnPool // non-nil version of ConnPool\n\n\t*transportTestHooks\n}\n\n// Hook points used for testing.\n// Outside of tests, t.transportTestHooks is nil and these all have minimal implementations.\n// Inside tests, see the testSyncHooks function docs.\n\ntype transportTestHooks struct {\n\tnewclientconn func(*ClientConn)\n}\n\nfunc (t *Transport) maxHeaderListSize() uint32 {\n\tn := int64(t.MaxHeaderListSize)\n\tif t.t1 != nil && t.t1.MaxResponseHeaderBytes != 0 {\n\t\tn = t.t1.MaxResponseHeaderBytes\n\t\tif n > 0 {\n\t\t\tn = adjustHTTP1MaxHeaderSize(n)\n\t\t}\n\t}\n\tif n <= 0 {\n\t\treturn 10 << 20\n\t}\n\tif n >= 0xffffffff {\n\t\treturn 0\n\t}\n\treturn uint32(n)\n}\n\nfunc (t *Transport) disableCompression() bool {\n\treturn t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression)\n}\n\n// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2.\n// It returns an error if t1 has already been HTTP/2-enabled.\n//\n// Use ConfigureTransports instead to configure the HTTP/2 Transport.\nfunc ConfigureTransport(t1 *http.Transport) error {\n\t_, err := ConfigureTransports(t1)\n\treturn err\n}\n\n// ConfigureTransports configures a net/http HTTP/1 Transport to use HTTP/2.\n// It returns a new HTTP/2 Transport for further configuration.\n// It returns an error if t1 has already been HTTP/2-enabled.\nfunc ConfigureTransports(t1 *http.Transport) (*Transport, error) {\n\treturn configureTransports(t1)\n}\n\nfunc configureTransports(t1 *http.Transport) (*Transport, error) {\n\tconnPool := new(clientConnPool)\n\tt2 := &Transport{\n\t\tConnPool: noDialClientConnPool{connPool},\n\t\tt1:       t1,\n\t}\n\tconnPool.t = t2\n\tif err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {\n\t\treturn nil, err\n\t}\n\tif t1.TLSClientConfig == nil {\n\t\tt1.TLSClientConfig = new(tls.Config)\n\t}\n\tif !strSliceContains(t1.TLSClientConfig.NextProtos, \"h2\") {\n\t\tt1.TLSClientConfig.NextProtos = append([]string{\"h2\"}, t1.TLSClientConfig.NextProtos...)\n\t}\n\tif !strSliceContains(t1.TLSClientConfig.NextProtos, \"http/1.1\") {\n\t\tt1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, \"http/1.1\")\n\t}\n\tupgradeFn := func(scheme, authority string, c net.Conn) http.RoundTripper {\n\t\taddr := authorityAddr(scheme, authority)\n\t\tif used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {\n\t\t\tgo c.Close()\n\t\t\treturn erringRoundTripper{err}\n\t\t} else if !used {\n\t\t\t// Turns out we don't need this c.\n\t\t\t// For example, two goroutines made requests to the same host\n\t\t\t// at the same time, both kicking off TCP dials. (since protocol\n\t\t\t// was unknown)\n\t\t\tgo c.Close()\n\t\t}\n\t\tif scheme == \"http\" {\n\t\t\treturn (*unencryptedTransport)(t2)\n\t\t}\n\t\treturn t2\n\t}\n\tif t1.TLSNextProto == nil {\n\t\tt1.TLSNextProto = make(map[string]func(string, *tls.Conn) http.RoundTripper)\n\t}\n\tt1.TLSNextProto[NextProtoTLS] = func(authority string, c *tls.Conn) http.RoundTripper {\n\t\treturn upgradeFn(\"https\", authority, c)\n\t}\n\t// The \"unencrypted_http2\" TLSNextProto key is used to pass off non-TLS HTTP/2 conns.\n\tt1.TLSNextProto[nextProtoUnencryptedHTTP2] = func(authority string, c *tls.Conn) http.RoundTripper {\n\t\tnc, err := unencryptedNetConnFromTLSConn(c)\n\t\tif err != nil {\n\t\t\tgo c.Close()\n\t\t\treturn erringRoundTripper{err}\n\t\t}\n\t\treturn upgradeFn(\"http\", authority, nc)\n\t}\n\treturn t2, nil\n}\n\n// unencryptedTransport is a Transport with a RoundTrip method that\n// always permits http:// URLs.\ntype unencryptedTransport Transport\n\nfunc (t *unencryptedTransport) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn (*Transport)(t).RoundTripOpt(req, RoundTripOpt{allowHTTP: true})\n}\n\nfunc (t *Transport) connPool() ClientConnPool {\n\tt.connPoolOnce.Do(t.initConnPool)\n\treturn t.connPoolOrDef\n}\n\nfunc (t *Transport) initConnPool() {\n\tif t.ConnPool != nil {\n\t\tt.connPoolOrDef = t.ConnPool\n\t} else {\n\t\tt.connPoolOrDef = &clientConnPool{t: t}\n\t}\n}\n\n// ClientConn is the state of a single HTTP/2 client connection to an\n// HTTP/2 server.\ntype ClientConn struct {\n\tt             *Transport\n\ttconn         net.Conn             // usually *tls.Conn, except specialized impls\n\ttlsState      *tls.ConnectionState // nil only for specialized impls\n\tatomicReused  uint32               // whether conn is being reused; atomic\n\tsingleUse     bool                 // whether being used for a single http.Request\n\tgetConnCalled bool                 // used by clientConnPool\n\n\t// readLoop goroutine fields:\n\treaderDone chan struct{} // closed on error\n\treaderErr  error         // set before readerDone is closed\n\n\tidleTimeout time.Duration // or 0 for never\n\tidleTimer   *time.Timer\n\n\tmu               sync.Mutex // guards following\n\tcond             *sync.Cond // hold mu; broadcast on flow/closed changes\n\tflow             outflow    // our conn-level flow control quota (cs.outflow is per stream)\n\tinflow           inflow     // peer's conn-level flow control\n\tdoNotReuse       bool       // whether conn is marked to not be reused for any future requests\n\tclosing          bool\n\tclosed           bool\n\tclosedOnIdle     bool                     // true if conn was closed for idleness\n\tseenSettings     bool                     // true if we've seen a settings frame, false otherwise\n\tseenSettingsChan chan struct{}            // closed when seenSettings is true or frame reading fails\n\twantSettingsAck  bool                     // we sent a SETTINGS frame and haven't heard back\n\tgoAway           *GoAwayFrame             // if non-nil, the GoAwayFrame we received\n\tgoAwayDebug      string                   // goAway frame's debug data, retained as a string\n\tstreams          map[uint32]*clientStream // client-initiated\n\tstreamsReserved  int                      // incr by ReserveNewRequest; decr on RoundTrip\n\tnextStreamID     uint32\n\tpendingRequests  int                       // requests blocked and waiting to be sent because len(streams) == maxConcurrentStreams\n\tpings            map[[8]byte]chan struct{} // in flight ping data to notification channel\n\tbr               *bufio.Reader\n\tlastActive       time.Time\n\tlastIdle         time.Time // time last idle\n\t// Settings from peer: (also guarded by wmu)\n\tmaxFrameSize                uint32\n\tmaxConcurrentStreams        uint32\n\tpeerMaxHeaderListSize       uint64\n\tpeerMaxHeaderTableSize      uint32\n\tinitialWindowSize           uint32\n\tinitialStreamRecvWindowSize int32\n\treadIdleTimeout             time.Duration\n\tpingTimeout                 time.Duration\n\textendedConnectAllowed      bool\n\tstrictMaxConcurrentStreams  bool\n\n\t// rstStreamPingsBlocked works around an unfortunate gRPC behavior.\n\t// gRPC strictly limits the number of PING frames that it will receive.\n\t// The default is two pings per two hours, but the limit resets every time\n\t// the gRPC endpoint sends a HEADERS or DATA frame. See golang/go#70575.\n\t//\n\t// rstStreamPingsBlocked is set after receiving a response to a PING frame\n\t// bundled with an RST_STREAM (see pendingResets below), and cleared after\n\t// receiving a HEADERS or DATA frame.\n\trstStreamPingsBlocked bool\n\n\t// pendingResets is the number of RST_STREAM frames we have sent to the peer,\n\t// without confirming that the peer has received them. When we send a RST_STREAM,\n\t// we bundle it with a PING frame, unless a PING is already in flight. We count\n\t// the reset stream against the connection's concurrency limit until we get\n\t// a PING response. This limits the number of requests we'll try to send to a\n\t// completely unresponsive connection.\n\tpendingResets int\n\n\t// reqHeaderMu is a 1-element semaphore channel controlling access to sending new requests.\n\t// Write to reqHeaderMu to lock it, read from it to unlock.\n\t// Lock reqmu BEFORE mu or wmu.\n\treqHeaderMu chan struct{}\n\n\t// wmu is held while writing.\n\t// Acquire BEFORE mu when holding both, to avoid blocking mu on network writes.\n\t// Only acquire both at the same time when changing peer settings.\n\twmu  sync.Mutex\n\tbw   *bufio.Writer\n\tfr   *Framer\n\twerr error        // first write error that has occurred\n\thbuf bytes.Buffer // HPACK encoder writes into this\n\thenc *hpack.Encoder\n}\n\n// clientStream is the state for a single HTTP/2 stream. One of these\n// is created for each Transport.RoundTrip call.\ntype clientStream struct {\n\tcc *ClientConn\n\n\t// Fields of Request that we may access even after the response body is closed.\n\tctx       context.Context\n\treqCancel <-chan struct{}\n\n\ttrace         *httptrace.ClientTrace // or nil\n\tID            uint32\n\tbufPipe       pipe // buffered pipe with the flow-controlled response payload\n\trequestedGzip bool\n\tisHead        bool\n\n\tabortOnce sync.Once\n\tabort     chan struct{} // closed to signal stream should end immediately\n\tabortErr  error         // set if abort is closed\n\n\tpeerClosed chan struct{} // closed when the peer sends an END_STREAM flag\n\tdonec      chan struct{} // closed after the stream is in the closed state\n\ton100      chan struct{} // buffered; written to if a 100 is received\n\n\trespHeaderRecv chan struct{}  // closed when headers are received\n\tres            *http.Response // set if respHeaderRecv is closed\n\n\tflow        outflow // guarded by cc.mu\n\tinflow      inflow  // guarded by cc.mu\n\tbytesRemain int64   // -1 means unknown; owned by transportResponseBody.Read\n\treadErr     error   // sticky read error; owned by transportResponseBody.Read\n\n\treqBody              io.ReadCloser\n\treqBodyContentLength int64         // -1 means unknown\n\treqBodyClosed        chan struct{} // guarded by cc.mu; non-nil on Close, closed when done\n\n\t// owned by writeRequest:\n\tsentEndStream bool // sent an END_STREAM flag to the peer\n\tsentHeaders   bool\n\n\t// owned by clientConnReadLoop:\n\tfirstByte       bool  // got the first response byte\n\tpastHeaders     bool  // got first MetaHeadersFrame (actual headers)\n\tpastTrailers    bool  // got optional second MetaHeadersFrame (trailers)\n\treadClosed      bool  // peer sent an END_STREAM flag\n\treadAborted     bool  // read loop reset the stream\n\ttotalHeaderSize int64 // total size of 1xx headers seen\n\n\ttrailer    http.Header  // accumulated trailers\n\tresTrailer *http.Header // client's Response.Trailer\n}\n\nvar got1xxFuncForTests func(int, textproto.MIMEHeader) error\n\n// get1xxTraceFunc returns the value of request's httptrace.ClientTrace.Got1xxResponse func,\n// if any. It returns nil if not set or if the Go version is too old.\nfunc (cs *clientStream) get1xxTraceFunc() func(int, textproto.MIMEHeader) error {\n\tif fn := got1xxFuncForTests; fn != nil {\n\t\treturn fn\n\t}\n\treturn traceGot1xxResponseFunc(cs.trace)\n}\n\nfunc (cs *clientStream) abortStream(err error) {\n\tcs.cc.mu.Lock()\n\tdefer cs.cc.mu.Unlock()\n\tcs.abortStreamLocked(err)\n}\n\nfunc (cs *clientStream) abortStreamLocked(err error) {\n\tcs.abortOnce.Do(func() {\n\t\tcs.abortErr = err\n\t\tclose(cs.abort)\n\t})\n\tif cs.reqBody != nil {\n\t\tcs.closeReqBodyLocked()\n\t}\n\t// TODO(dneil): Clean up tests where cs.cc.cond is nil.\n\tif cs.cc.cond != nil {\n\t\t// Wake up writeRequestBody if it is waiting on flow control.\n\t\tcs.cc.cond.Broadcast()\n\t}\n}\n\nfunc (cs *clientStream) abortRequestBodyWrite() {\n\tcc := cs.cc\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tif cs.reqBody != nil && cs.reqBodyClosed == nil {\n\t\tcs.closeReqBodyLocked()\n\t\tcc.cond.Broadcast()\n\t}\n}\n\nfunc (cs *clientStream) closeReqBodyLocked() {\n\tif cs.reqBodyClosed != nil {\n\t\treturn\n\t}\n\tcs.reqBodyClosed = make(chan struct{})\n\treqBodyClosed := cs.reqBodyClosed\n\tgo func() {\n\t\tcs.reqBody.Close()\n\t\tclose(reqBodyClosed)\n\t}()\n}\n\ntype stickyErrWriter struct {\n\tconn    net.Conn\n\ttimeout time.Duration\n\terr     *error\n}\n\nfunc (sew stickyErrWriter) Write(p []byte) (n int, err error) {\n\tif *sew.err != nil {\n\t\treturn 0, *sew.err\n\t}\n\tn, err = writeWithByteTimeout(sew.conn, sew.timeout, p)\n\t*sew.err = err\n\treturn n, err\n}\n\n// noCachedConnError is the concrete type of ErrNoCachedConn, which\n// needs to be detected by net/http regardless of whether it's its\n// bundled version (in h2_bundle.go with a rewritten type name) or\n// from a user's x/net/http2. As such, as it has a unique method name\n// (IsHTTP2NoCachedConnError) that net/http sniffs for via func\n// isNoCachedConnError.\ntype noCachedConnError struct{}\n\nfunc (noCachedConnError) IsHTTP2NoCachedConnError() {}\nfunc (noCachedConnError) Error() string             { return \"http2: no cached connection was available\" }\n\n// isNoCachedConnError reports whether err is of type noCachedConnError\n// or its equivalent renamed type in net/http2's h2_bundle.go. Both types\n// may coexist in the same running program.\nfunc isNoCachedConnError(err error) bool {\n\t_, ok := err.(interface{ IsHTTP2NoCachedConnError() })\n\treturn ok\n}\n\nvar ErrNoCachedConn error = noCachedConnError{}\n\n// RoundTripOpt are options for the Transport.RoundTripOpt method.\ntype RoundTripOpt struct {\n\t// OnlyCachedConn controls whether RoundTripOpt may\n\t// create a new TCP connection. If set true and\n\t// no cached connection is available, RoundTripOpt\n\t// will return ErrNoCachedConn.\n\tOnlyCachedConn bool\n\n\tallowHTTP bool // allow http:// URLs\n}\n\nfunc (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn t.RoundTripOpt(req, RoundTripOpt{})\n}\n\n// authorityAddr returns a given authority (a host/IP, or host:port / ip:port)\n// and returns a host:port. The port 443 is added if needed.\nfunc authorityAddr(scheme string, authority string) (addr string) {\n\thost, port, err := net.SplitHostPort(authority)\n\tif err != nil { // authority didn't have a port\n\t\thost = authority\n\t\tport = \"\"\n\t}\n\tif port == \"\" { // authority's port was empty\n\t\tport = \"443\"\n\t\tif scheme == \"http\" {\n\t\t\tport = \"80\"\n\t\t}\n\t}\n\tif a, err := idna.ToASCII(host); err == nil {\n\t\thost = a\n\t}\n\t// IPv6 address literal, without a port:\n\tif strings.HasPrefix(host, \"[\") && strings.HasSuffix(host, \"]\") {\n\t\treturn host + \":\" + port\n\t}\n\treturn net.JoinHostPort(host, port)\n}\n\n// RoundTripOpt is like RoundTrip, but takes options.\nfunc (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {\n\tswitch req.URL.Scheme {\n\tcase \"https\":\n\t\t// Always okay.\n\tcase \"http\":\n\t\tif !t.AllowHTTP && !opt.allowHTTP {\n\t\t\treturn nil, errors.New(\"http2: unencrypted HTTP/2 not enabled\")\n\t\t}\n\tdefault:\n\t\treturn nil, errors.New(\"http2: unsupported scheme\")\n\t}\n\n\taddr := authorityAddr(req.URL.Scheme, req.URL.Host)\n\tfor retry := 0; ; retry++ {\n\t\tcc, err := t.connPool().GetClientConn(req, addr)\n\t\tif err != nil {\n\t\t\tt.vlogf(\"http2: Transport failed to get client conn for %s: %v\", addr, err)\n\t\t\treturn nil, err\n\t\t}\n\t\treused := !atomic.CompareAndSwapUint32(&cc.atomicReused, 0, 1)\n\t\ttraceGotConn(req, cc, reused)\n\t\tres, err := cc.RoundTrip(req)\n\t\tif err != nil && retry <= 6 {\n\t\t\troundTripErr := err\n\t\t\tif req, err = shouldRetryRequest(req, err); err == nil {\n\t\t\t\t// After the first retry, do exponential backoff with 10% jitter.\n\t\t\t\tif retry == 0 {\n\t\t\t\t\tt.vlogf(\"RoundTrip retrying after failure: %v\", roundTripErr)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tbackoff := float64(uint(1) << (uint(retry) - 1))\n\t\t\t\tbackoff += backoff * (0.1 * mathrand.Float64())\n\t\t\t\td := time.Second * time.Duration(backoff)\n\t\t\t\ttm := time.NewTimer(d)\n\t\t\t\tselect {\n\t\t\t\tcase <-tm.C:\n\t\t\t\t\tt.vlogf(\"RoundTrip retrying after failure: %v\", roundTripErr)\n\t\t\t\t\tcontinue\n\t\t\t\tcase <-req.Context().Done():\n\t\t\t\t\ttm.Stop()\n\t\t\t\t\terr = req.Context().Err()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif err == errClientConnNotEstablished {\n\t\t\t// This ClientConn was created recently,\n\t\t\t// this is the first request to use it,\n\t\t\t// and the connection is closed and not usable.\n\t\t\t//\n\t\t\t// In this state, cc.idleTimer will remove the conn from the pool\n\t\t\t// when it fires. Stop the timer and remove it here so future requests\n\t\t\t// won't try to use this connection.\n\t\t\t//\n\t\t\t// If the timer has already fired and we're racing it, the redundant\n\t\t\t// call to MarkDead is harmless.\n\t\t\tif cc.idleTimer != nil {\n\t\t\t\tcc.idleTimer.Stop()\n\t\t\t}\n\t\t\tt.connPool().MarkDead(cc)\n\t\t}\n\t\tif err != nil {\n\t\t\tt.vlogf(\"RoundTrip failure: %v\", err)\n\t\t\treturn nil, err\n\t\t}\n\t\treturn res, nil\n\t}\n}\n\n// CloseIdleConnections closes any connections which were previously\n// connected from previous requests but are now sitting idle.\n// It does not interrupt any connections currently in use.\nfunc (t *Transport) CloseIdleConnections() {\n\tif cp, ok := t.connPool().(clientConnPoolIdleCloser); ok {\n\t\tcp.closeIdleConnections()\n\t}\n}\n\nvar (\n\terrClientConnClosed         = errors.New(\"http2: client conn is closed\")\n\terrClientConnUnusable       = errors.New(\"http2: client conn not usable\")\n\terrClientConnNotEstablished = errors.New(\"http2: client conn could not be established\")\n\terrClientConnGotGoAway      = errors.New(\"http2: Transport received Server's graceful shutdown GOAWAY\")\n\terrClientConnForceClosed    = errors.New(\"http2: client connection force closed via ClientConn.Close\")\n)\n\n// shouldRetryRequest is called by RoundTrip when a request fails to get\n// response headers. It is always called with a non-nil error.\n// It returns either a request to retry (either the same request, or a\n// modified clone), or an error if the request can't be replayed.\nfunc shouldRetryRequest(req *http.Request, err error) (*http.Request, error) {\n\tif !canRetryError(err) {\n\t\treturn nil, err\n\t}\n\t// If the Body is nil (or http.NoBody), it's safe to reuse\n\t// this request and its Body.\n\tif req.Body == nil || req.Body == http.NoBody {\n\t\treturn req, nil\n\t}\n\n\t// If the request body can be reset back to its original\n\t// state via the optional req.GetBody, do that.\n\tif req.GetBody != nil {\n\t\tbody, err := req.GetBody()\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tnewReq := *req\n\t\tnewReq.Body = body\n\t\treturn &newReq, nil\n\t}\n\n\t// The Request.Body can't reset back to the beginning, but we\n\t// don't seem to have started to read from it yet, so reuse\n\t// the request directly.\n\tif err == errClientConnUnusable {\n\t\treturn req, nil\n\t}\n\n\treturn nil, fmt.Errorf(\"http2: Transport: cannot retry err [%v] after Request.Body was written; define Request.GetBody to avoid this error\", err)\n}\n\nfunc canRetryError(err error) bool {\n\tif err == errClientConnUnusable || err == errClientConnGotGoAway {\n\t\treturn true\n\t}\n\tif se, ok := err.(StreamError); ok {\n\t\tif se.Code == ErrCodeProtocol && se.Cause == errFromPeer {\n\t\t\t// See golang/go#47635, golang/go#42777\n\t\t\treturn true\n\t\t}\n\t\treturn se.Code == ErrCodeRefusedStream\n\t}\n\treturn false\n}\n\nfunc (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {\n\tif t.transportTestHooks != nil {\n\t\treturn t.newClientConn(nil, singleUse)\n\t}\n\thost, _, err := net.SplitHostPort(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttconn, err := t.dialTLS(ctx, \"tcp\", addr, t.newTLSConfig(host))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn t.newClientConn(tconn, singleUse)\n}\n\nfunc (t *Transport) newTLSConfig(host string) *tls.Config {\n\tcfg := new(tls.Config)\n\tif t.TLSClientConfig != nil {\n\t\t*cfg = *t.TLSClientConfig.Clone()\n\t}\n\tif !strSliceContains(cfg.NextProtos, NextProtoTLS) {\n\t\tcfg.NextProtos = append([]string{NextProtoTLS}, cfg.NextProtos...)\n\t}\n\tif cfg.ServerName == \"\" {\n\t\tcfg.ServerName = host\n\t}\n\treturn cfg\n}\n\nfunc (t *Transport) dialTLS(ctx context.Context, network, addr string, tlsCfg *tls.Config) (net.Conn, error) {\n\tif t.DialTLSContext != nil {\n\t\treturn t.DialTLSContext(ctx, network, addr, tlsCfg)\n\t} else if t.DialTLS != nil {\n\t\treturn t.DialTLS(network, addr, tlsCfg)\n\t}\n\n\ttlsCn, err := t.dialTLSWithContext(ctx, network, addr, tlsCfg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstate := tlsCn.ConnectionState()\n\tif p := state.NegotiatedProtocol; p != NextProtoTLS {\n\t\treturn nil, fmt.Errorf(\"http2: unexpected ALPN protocol %q; want %q\", p, NextProtoTLS)\n\t}\n\tif !state.NegotiatedProtocolIsMutual {\n\t\treturn nil, errors.New(\"http2: could not negotiate protocol mutually\")\n\t}\n\treturn tlsCn, nil\n}\n\n// disableKeepAlives reports whether connections should be closed as\n// soon as possible after handling the first request.\nfunc (t *Transport) disableKeepAlives() bool {\n\treturn t.t1 != nil && t.t1.DisableKeepAlives\n}\n\nfunc (t *Transport) expectContinueTimeout() time.Duration {\n\tif t.t1 == nil {\n\t\treturn 0\n\t}\n\treturn t.t1.ExpectContinueTimeout\n}\n\nfunc (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {\n\treturn t.newClientConn(c, t.disableKeepAlives())\n}\n\nfunc (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {\n\tconf := configFromTransport(t)\n\tcc := &ClientConn{\n\t\tt:                           t,\n\t\ttconn:                       c,\n\t\treaderDone:                  make(chan struct{}),\n\t\tnextStreamID:                1,\n\t\tmaxFrameSize:                16 << 10, // spec default\n\t\tinitialWindowSize:           65535,    // spec default\n\t\tinitialStreamRecvWindowSize: conf.MaxUploadBufferPerStream,\n\t\tmaxConcurrentStreams:        initialMaxConcurrentStreams, // \"infinite\", per spec. Use a smaller value until we have received server settings.\n\t\tstrictMaxConcurrentStreams:  conf.StrictMaxConcurrentRequests,\n\t\tpeerMaxHeaderListSize:       0xffffffffffffffff, // \"infinite\", per spec. Use 2^64-1 instead.\n\t\tstreams:                     make(map[uint32]*clientStream),\n\t\tsingleUse:                   singleUse,\n\t\tseenSettingsChan:            make(chan struct{}),\n\t\twantSettingsAck:             true,\n\t\treadIdleTimeout:             conf.SendPingTimeout,\n\t\tpingTimeout:                 conf.PingTimeout,\n\t\tpings:                       make(map[[8]byte]chan struct{}),\n\t\treqHeaderMu:                 make(chan struct{}, 1),\n\t\tlastActive:                  time.Now(),\n\t}\n\tif t.transportTestHooks != nil {\n\t\tt.transportTestHooks.newclientconn(cc)\n\t\tc = cc.tconn\n\t}\n\tif VerboseLogs {\n\t\tt.vlogf(\"http2: Transport creating client conn %p to %v\", cc, c.RemoteAddr())\n\t}\n\n\tcc.cond = sync.NewCond(&cc.mu)\n\tcc.flow.add(int32(initialWindowSize))\n\n\t// TODO: adjust this writer size to account for frame size +\n\t// MTU + crypto/tls record padding.\n\tcc.bw = bufio.NewWriter(stickyErrWriter{\n\t\tconn:    c,\n\t\ttimeout: conf.WriteByteTimeout,\n\t\terr:     &cc.werr,\n\t})\n\tcc.br = bufio.NewReader(c)\n\tcc.fr = NewFramer(cc.bw, cc.br)\n\tcc.fr.SetMaxReadFrameSize(conf.MaxReadFrameSize)\n\tif t.CountError != nil {\n\t\tcc.fr.countError = t.CountError\n\t}\n\tmaxHeaderTableSize := conf.MaxDecoderHeaderTableSize\n\tcc.fr.ReadMetaHeaders = hpack.NewDecoder(maxHeaderTableSize, nil)\n\tcc.fr.MaxHeaderListSize = t.maxHeaderListSize()\n\n\tcc.henc = hpack.NewEncoder(&cc.hbuf)\n\tcc.henc.SetMaxDynamicTableSizeLimit(conf.MaxEncoderHeaderTableSize)\n\tcc.peerMaxHeaderTableSize = initialHeaderTableSize\n\n\tif cs, ok := c.(connectionStater); ok {\n\t\tstate := cs.ConnectionState()\n\t\tcc.tlsState = &state\n\t}\n\n\tinitialSettings := []Setting{\n\t\t{ID: SettingEnablePush, Val: 0},\n\t\t{ID: SettingInitialWindowSize, Val: uint32(cc.initialStreamRecvWindowSize)},\n\t}\n\tinitialSettings = append(initialSettings, Setting{ID: SettingMaxFrameSize, Val: conf.MaxReadFrameSize})\n\tif max := t.maxHeaderListSize(); max != 0 {\n\t\tinitialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max})\n\t}\n\tif maxHeaderTableSize != initialHeaderTableSize {\n\t\tinitialSettings = append(initialSettings, Setting{ID: SettingHeaderTableSize, Val: maxHeaderTableSize})\n\t}\n\n\tcc.bw.Write(clientPreface)\n\tcc.fr.WriteSettings(initialSettings...)\n\tcc.fr.WriteWindowUpdate(0, uint32(conf.MaxUploadBufferPerConnection))\n\tcc.inflow.init(conf.MaxUploadBufferPerConnection + initialWindowSize)\n\tcc.bw.Flush()\n\tif cc.werr != nil {\n\t\tcc.Close()\n\t\treturn nil, cc.werr\n\t}\n\n\t// Start the idle timer after the connection is fully initialized.\n\tif d := t.idleConnTimeout(); d != 0 {\n\t\tcc.idleTimeout = d\n\t\tcc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)\n\t}\n\n\tgo cc.readLoop()\n\treturn cc, nil\n}\n\nfunc (cc *ClientConn) healthCheck() {\n\tpingTimeout := cc.pingTimeout\n\t// We don't need to periodically ping in the health check, because the readLoop of ClientConn will\n\t// trigger the healthCheck again if there is no frame received.\n\tctx, cancel := context.WithTimeout(context.Background(), pingTimeout)\n\tdefer cancel()\n\tcc.vlogf(\"http2: Transport sending health check\")\n\terr := cc.Ping(ctx)\n\tif err != nil {\n\t\tcc.vlogf(\"http2: Transport health check failure: %v\", err)\n\t\tcc.closeForLostPing()\n\t} else {\n\t\tcc.vlogf(\"http2: Transport health check success\")\n\t}\n}\n\n// SetDoNotReuse marks cc as not reusable for future HTTP requests.\nfunc (cc *ClientConn) SetDoNotReuse() {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tcc.doNotReuse = true\n}\n\nfunc (cc *ClientConn) setGoAway(f *GoAwayFrame) {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\n\told := cc.goAway\n\tcc.goAway = f\n\n\t// Merge the previous and current GoAway error frames.\n\tif cc.goAwayDebug == \"\" {\n\t\tcc.goAwayDebug = string(f.DebugData())\n\t}\n\tif old != nil && old.ErrCode != ErrCodeNo {\n\t\tcc.goAway.ErrCode = old.ErrCode\n\t}\n\tlast := f.LastStreamID\n\tfor streamID, cs := range cc.streams {\n\t\tif streamID <= last {\n\t\t\t// The server's GOAWAY indicates that it received this stream.\n\t\t\t// It will either finish processing it, or close the connection\n\t\t\t// without doing so. Either way, leave the stream alone for now.\n\t\t\tcontinue\n\t\t}\n\t\tif streamID == 1 && cc.goAway.ErrCode != ErrCodeNo {\n\t\t\t// Don't retry the first stream on a connection if we get a non-NO error.\n\t\t\t// If the server is sending an error on a new connection,\n\t\t\t// retrying the request on a new one probably isn't going to work.\n\t\t\tcs.abortStreamLocked(fmt.Errorf(\"http2: Transport received GOAWAY from server ErrCode:%v\", cc.goAway.ErrCode))\n\t\t} else {\n\t\t\t// Aborting the stream with errClentConnGotGoAway indicates that\n\t\t\t// the request should be retried on a new connection.\n\t\t\tcs.abortStreamLocked(errClientConnGotGoAway)\n\t\t}\n\t}\n}\n\n// CanTakeNewRequest reports whether the connection can take a new request,\n// meaning it has not been closed or received or sent a GOAWAY.\n//\n// If the caller is going to immediately make a new request on this\n// connection, use ReserveNewRequest instead.\nfunc (cc *ClientConn) CanTakeNewRequest() bool {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn cc.canTakeNewRequestLocked()\n}\n\n// ReserveNewRequest is like CanTakeNewRequest but also reserves a\n// concurrent stream in cc. The reservation is decremented on the\n// next call to RoundTrip.\nfunc (cc *ClientConn) ReserveNewRequest() bool {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tif st := cc.idleStateLocked(); !st.canTakeNewRequest {\n\t\treturn false\n\t}\n\tcc.streamsReserved++\n\treturn true\n}\n\n// ClientConnState describes the state of a ClientConn.\ntype ClientConnState struct {\n\t// Closed is whether the connection is closed.\n\tClosed bool\n\n\t// Closing is whether the connection is in the process of\n\t// closing. It may be closing due to shutdown, being a\n\t// single-use connection, being marked as DoNotReuse, or\n\t// having received a GOAWAY frame.\n\tClosing bool\n\n\t// StreamsActive is how many streams are active.\n\tStreamsActive int\n\n\t// StreamsReserved is how many streams have been reserved via\n\t// ClientConn.ReserveNewRequest.\n\tStreamsReserved int\n\n\t// StreamsPending is how many requests have been sent in excess\n\t// of the peer's advertised MaxConcurrentStreams setting and\n\t// are waiting for other streams to complete.\n\tStreamsPending int\n\n\t// MaxConcurrentStreams is how many concurrent streams the\n\t// peer advertised as acceptable. Zero means no SETTINGS\n\t// frame has been received yet.\n\tMaxConcurrentStreams uint32\n\n\t// LastIdle, if non-zero, is when the connection last\n\t// transitioned to idle state.\n\tLastIdle time.Time\n}\n\n// State returns a snapshot of cc's state.\nfunc (cc *ClientConn) State() ClientConnState {\n\tcc.wmu.Lock()\n\tmaxConcurrent := cc.maxConcurrentStreams\n\tif !cc.seenSettings {\n\t\tmaxConcurrent = 0\n\t}\n\tcc.wmu.Unlock()\n\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn ClientConnState{\n\t\tClosed:               cc.closed,\n\t\tClosing:              cc.closing || cc.singleUse || cc.doNotReuse || cc.goAway != nil,\n\t\tStreamsActive:        len(cc.streams) + cc.pendingResets,\n\t\tStreamsReserved:      cc.streamsReserved,\n\t\tStreamsPending:       cc.pendingRequests,\n\t\tLastIdle:             cc.lastIdle,\n\t\tMaxConcurrentStreams: maxConcurrent,\n\t}\n}\n\n// clientConnIdleState describes the suitability of a client\n// connection to initiate a new RoundTrip request.\ntype clientConnIdleState struct {\n\tcanTakeNewRequest bool\n}\n\nfunc (cc *ClientConn) idleState() clientConnIdleState {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn cc.idleStateLocked()\n}\n\nfunc (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {\n\tif cc.singleUse && cc.nextStreamID > 1 {\n\t\treturn\n\t}\n\tvar maxConcurrentOkay bool\n\tif cc.strictMaxConcurrentStreams {\n\t\t// We'll tell the caller we can take a new request to\n\t\t// prevent the caller from dialing a new TCP\n\t\t// connection, but then we'll block later before\n\t\t// writing it.\n\t\tmaxConcurrentOkay = true\n\t} else {\n\t\t// We can take a new request if the total of\n\t\t//   - active streams;\n\t\t//   - reservation slots for new streams; and\n\t\t//   - streams for which we have sent a RST_STREAM and a PING,\n\t\t//     but received no subsequent frame\n\t\t// is less than the concurrency limit.\n\t\tmaxConcurrentOkay = cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams)\n\t}\n\n\tst.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&\n\t\t!cc.doNotReuse &&\n\t\tint64(cc.nextStreamID)+2*int64(cc.pendingRequests) < math.MaxInt32 &&\n\t\t!cc.tooIdleLocked()\n\n\t// If this connection has never been used for a request and is closed,\n\t// then let it take a request (which will fail).\n\t// If the conn was closed for idleness, we're racing the idle timer;\n\t// don't try to use the conn. (Issue #70515.)\n\t//\n\t// This avoids a situation where an error early in a connection's lifetime\n\t// goes unreported.\n\tif cc.nextStreamID == 1 && cc.streamsReserved == 0 && cc.closed && !cc.closedOnIdle {\n\t\tst.canTakeNewRequest = true\n\t}\n\n\treturn\n}\n\n// currentRequestCountLocked reports the number of concurrency slots currently in use,\n// including active streams, reserved slots, and reset streams waiting for acknowledgement.\nfunc (cc *ClientConn) currentRequestCountLocked() int {\n\treturn len(cc.streams) + cc.streamsReserved + cc.pendingResets\n}\n\nfunc (cc *ClientConn) canTakeNewRequestLocked() bool {\n\tst := cc.idleStateLocked()\n\treturn st.canTakeNewRequest\n}\n\n// tooIdleLocked reports whether this connection has been been sitting idle\n// for too much wall time.\nfunc (cc *ClientConn) tooIdleLocked() bool {\n\t// The Round(0) strips the monontonic clock reading so the\n\t// times are compared based on their wall time. We don't want\n\t// to reuse a connection that's been sitting idle during\n\t// VM/laptop suspend if monotonic time was also frozen.\n\treturn cc.idleTimeout != 0 && !cc.lastIdle.IsZero() && time.Since(cc.lastIdle.Round(0)) > cc.idleTimeout\n}\n\n// onIdleTimeout is called from a time.AfterFunc goroutine. It will\n// only be called when we're idle, but because we're coming from a new\n// goroutine, there could be a new request coming in at the same time,\n// so this simply calls the synchronized closeIfIdle to shut down this\n// connection. The timer could just call closeIfIdle, but this is more\n// clear.\nfunc (cc *ClientConn) onIdleTimeout() {\n\tcc.closeIfIdle()\n}\n\nfunc (cc *ClientConn) closeConn() {\n\tt := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)\n\tdefer t.Stop()\n\tcc.tconn.Close()\n}\n\n// A tls.Conn.Close can hang for a long time if the peer is unresponsive.\n// Try to shut it down more aggressively.\nfunc (cc *ClientConn) forceCloseConn() {\n\ttc, ok := cc.tconn.(*tls.Conn)\n\tif !ok {\n\t\treturn\n\t}\n\tif nc := tc.NetConn(); nc != nil {\n\t\tnc.Close()\n\t}\n}\n\nfunc (cc *ClientConn) closeIfIdle() {\n\tcc.mu.Lock()\n\tif len(cc.streams) > 0 || cc.streamsReserved > 0 {\n\t\tcc.mu.Unlock()\n\t\treturn\n\t}\n\tcc.closed = true\n\tcc.closedOnIdle = true\n\tnextID := cc.nextStreamID\n\t// TODO: do clients send GOAWAY too? maybe? Just Close:\n\tcc.mu.Unlock()\n\n\tif VerboseLogs {\n\t\tcc.vlogf(\"http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)\", cc, cc.singleUse, nextID-2)\n\t}\n\tcc.closeConn()\n}\n\nfunc (cc *ClientConn) isDoNotReuseAndIdle() bool {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\treturn cc.doNotReuse && len(cc.streams) == 0\n}\n\nvar shutdownEnterWaitStateHook = func() {}\n\n// Shutdown gracefully closes the client connection, waiting for running streams to complete.\nfunc (cc *ClientConn) Shutdown(ctx context.Context) error {\n\tif err := cc.sendGoAway(); err != nil {\n\t\treturn err\n\t}\n\t// Wait for all in-flight streams to complete or connection to close\n\tdone := make(chan struct{})\n\tcancelled := false // guarded by cc.mu\n\tgo func() {\n\t\tcc.mu.Lock()\n\t\tdefer cc.mu.Unlock()\n\t\tfor {\n\t\t\tif len(cc.streams) == 0 || cc.closed {\n\t\t\t\tcc.closed = true\n\t\t\t\tclose(done)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif cancelled {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcc.cond.Wait()\n\t\t}\n\t}()\n\tshutdownEnterWaitStateHook()\n\tselect {\n\tcase <-done:\n\t\tcc.closeConn()\n\t\treturn nil\n\tcase <-ctx.Done():\n\t\tcc.mu.Lock()\n\t\t// Free the goroutine above\n\t\tcancelled = true\n\t\tcc.cond.Broadcast()\n\t\tcc.mu.Unlock()\n\t\treturn ctx.Err()\n\t}\n}\n\nfunc (cc *ClientConn) sendGoAway() error {\n\tcc.mu.Lock()\n\tclosing := cc.closing\n\tcc.closing = true\n\tmaxStreamID := cc.nextStreamID\n\tcc.mu.Unlock()\n\tif closing {\n\t\t// GOAWAY sent already\n\t\treturn nil\n\t}\n\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\t// Send a graceful shutdown frame to server\n\tif err := cc.fr.WriteGoAway(maxStreamID, ErrCodeNo, nil); err != nil {\n\t\treturn err\n\t}\n\tif err := cc.bw.Flush(); err != nil {\n\t\treturn err\n\t}\n\t// Prevent new requests\n\treturn nil\n}\n\n// closes the client connection immediately. In-flight requests are interrupted.\n// err is sent to streams.\nfunc (cc *ClientConn) closeForError(err error) {\n\tcc.mu.Lock()\n\tcc.closed = true\n\tfor _, cs := range cc.streams {\n\t\tcs.abortStreamLocked(err)\n\t}\n\tcc.cond.Broadcast()\n\tcc.mu.Unlock()\n\tcc.closeConn()\n}\n\n// Close closes the client connection immediately.\n//\n// In-flight requests are interrupted. For a graceful shutdown, use Shutdown instead.\nfunc (cc *ClientConn) Close() error {\n\tcc.closeForError(errClientConnForceClosed)\n\treturn nil\n}\n\n// closes the client connection immediately. In-flight requests are interrupted.\nfunc (cc *ClientConn) closeForLostPing() {\n\terr := errors.New(\"http2: client connection lost\")\n\tif f := cc.t.CountError; f != nil {\n\t\tf(\"conn_close_lost_ping\")\n\t}\n\tcc.closeForError(err)\n}\n\n// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not\n// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests.\nvar errRequestCanceled = errors.New(\"net/http: request canceled\")\n\nfunc (cc *ClientConn) responseHeaderTimeout() time.Duration {\n\tif cc.t.t1 != nil {\n\t\treturn cc.t.t1.ResponseHeaderTimeout\n\t}\n\t// No way to do this (yet?) with just an http2.Transport. Probably\n\t// no need. Request.Cancel this is the new way. We only need to support\n\t// this for compatibility with the old http.Transport fields when\n\t// we're doing transparent http2.\n\treturn 0\n}\n\n// actualContentLength returns a sanitized version of\n// req.ContentLength, where 0 actually means zero (not unknown) and -1\n// means unknown.\nfunc actualContentLength(req *http.Request) int64 {\n\tif req.Body == nil || req.Body == http.NoBody {\n\t\treturn 0\n\t}\n\tif req.ContentLength != 0 {\n\t\treturn req.ContentLength\n\t}\n\treturn -1\n}\n\nfunc (cc *ClientConn) decrStreamReservations() {\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tcc.decrStreamReservationsLocked()\n}\n\nfunc (cc *ClientConn) decrStreamReservationsLocked() {\n\tif cc.streamsReserved > 0 {\n\t\tcc.streamsReserved--\n\t}\n}\n\nfunc (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {\n\treturn cc.roundTrip(req, nil)\n}\n\nfunc (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) {\n\tctx := req.Context()\n\tcs := &clientStream{\n\t\tcc:                   cc,\n\t\tctx:                  ctx,\n\t\treqCancel:            req.Cancel,\n\t\tisHead:               req.Method == \"HEAD\",\n\t\treqBody:              req.Body,\n\t\treqBodyContentLength: actualContentLength(req),\n\t\ttrace:                httptrace.ContextClientTrace(ctx),\n\t\tpeerClosed:           make(chan struct{}),\n\t\tabort:                make(chan struct{}),\n\t\trespHeaderRecv:       make(chan struct{}),\n\t\tdonec:                make(chan struct{}),\n\t}\n\n\tcs.requestedGzip = httpcommon.IsRequestGzip(req.Method, req.Header, cc.t.disableCompression())\n\n\tgo cs.doRequest(req, streamf)\n\n\twaitDone := func() error {\n\t\tselect {\n\t\tcase <-cs.donec:\n\t\t\treturn nil\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-cs.reqCancel:\n\t\t\treturn errRequestCanceled\n\t\t}\n\t}\n\n\thandleResponseHeaders := func() (*http.Response, error) {\n\t\tres := cs.res\n\t\tif res.StatusCode > 299 {\n\t\t\t// On error or status code 3xx, 4xx, 5xx, etc abort any\n\t\t\t// ongoing write, assuming that the server doesn't care\n\t\t\t// about our request body. If the server replied with 1xx or\n\t\t\t// 2xx, however, then assume the server DOES potentially\n\t\t\t// want our body (e.g. full-duplex streaming:\n\t\t\t// golang.org/issue/13444). If it turns out the server\n\t\t\t// doesn't, they'll RST_STREAM us soon enough. This is a\n\t\t\t// heuristic to avoid adding knobs to Transport. Hopefully\n\t\t\t// we can keep it.\n\t\t\tcs.abortRequestBodyWrite()\n\t\t}\n\t\tres.Request = req\n\t\tres.TLS = cc.tlsState\n\t\tif res.Body == noBody && actualContentLength(req) == 0 {\n\t\t\t// If there isn't a request or response body still being\n\t\t\t// written, then wait for the stream to be closed before\n\t\t\t// RoundTrip returns.\n\t\t\tif err := waitDone(); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\t\treturn res, nil\n\t}\n\n\tcancelRequest := func(cs *clientStream, err error) error {\n\t\tcs.cc.mu.Lock()\n\t\tbodyClosed := cs.reqBodyClosed\n\t\tcs.cc.mu.Unlock()\n\t\t// Wait for the request body to be closed.\n\t\t//\n\t\t// If nothing closed the body before now, abortStreamLocked\n\t\t// will have started a goroutine to close it.\n\t\t//\n\t\t// Closing the body before returning avoids a race condition\n\t\t// with net/http checking its readTrackingBody to see if the\n\t\t// body was read from or closed. See golang/go#60041.\n\t\t//\n\t\t// The body is closed in a separate goroutine without the\n\t\t// connection mutex held, but dropping the mutex before waiting\n\t\t// will keep us from holding it indefinitely if the body\n\t\t// close is slow for some reason.\n\t\tif bodyClosed != nil {\n\t\t\t<-bodyClosed\n\t\t}\n\t\treturn err\n\t}\n\n\tfor {\n\t\tselect {\n\t\tcase <-cs.respHeaderRecv:\n\t\t\treturn handleResponseHeaders()\n\t\tcase <-cs.abort:\n\t\t\tselect {\n\t\t\tcase <-cs.respHeaderRecv:\n\t\t\t\t// If both cs.respHeaderRecv and cs.abort are signaling,\n\t\t\t\t// pick respHeaderRecv. The server probably wrote the\n\t\t\t\t// response and immediately reset the stream.\n\t\t\t\t// golang.org/issue/49645\n\t\t\t\treturn handleResponseHeaders()\n\t\t\tdefault:\n\t\t\t\twaitDone()\n\t\t\t\treturn nil, cs.abortErr\n\t\t\t}\n\t\tcase <-ctx.Done():\n\t\t\terr := ctx.Err()\n\t\t\tcs.abortStream(err)\n\t\t\treturn nil, cancelRequest(cs, err)\n\t\tcase <-cs.reqCancel:\n\t\t\tcs.abortStream(errRequestCanceled)\n\t\t\treturn nil, cancelRequest(cs, errRequestCanceled)\n\t\t}\n\t}\n}\n\n// doRequest runs for the duration of the request lifetime.\n//\n// It sends the request and performs post-request cleanup (closing Request.Body, etc.).\nfunc (cs *clientStream) doRequest(req *http.Request, streamf func(*clientStream)) {\n\terr := cs.writeRequest(req, streamf)\n\tcs.cleanupWriteRequest(err)\n}\n\nvar errExtendedConnectNotSupported = errors.New(\"net/http: extended connect not supported by peer\")\n\n// writeRequest sends a request.\n//\n// It returns nil after the request is written, the response read,\n// and the request stream is half-closed by the peer.\n//\n// It returns non-nil if the request ends otherwise.\n// If the returned error is StreamError, the error Code may be used in resetting the stream.\nfunc (cs *clientStream) writeRequest(req *http.Request, streamf func(*clientStream)) (err error) {\n\tcc := cs.cc\n\tctx := cs.ctx\n\n\t// wait for setting frames to be received, a server can change this value later,\n\t// but we just wait for the first settings frame\n\tvar isExtendedConnect bool\n\tif req.Method == \"CONNECT\" && req.Header.Get(\":protocol\") != \"\" {\n\t\tisExtendedConnect = true\n\t}\n\n\t// Acquire the new-request lock by writing to reqHeaderMu.\n\t// This lock guards the critical section covering allocating a new stream ID\n\t// (requires mu) and creating the stream (requires wmu).\n\tif cc.reqHeaderMu == nil {\n\t\tpanic(\"RoundTrip on uninitialized ClientConn\") // for tests\n\t}\n\tif isExtendedConnect {\n\t\tselect {\n\t\tcase <-cs.reqCancel:\n\t\t\treturn errRequestCanceled\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-cc.seenSettingsChan:\n\t\t\tif !cc.extendedConnectAllowed {\n\t\t\t\treturn errExtendedConnectNotSupported\n\t\t\t}\n\t\t}\n\t}\n\tselect {\n\tcase cc.reqHeaderMu <- struct{}{}:\n\tcase <-cs.reqCancel:\n\t\treturn errRequestCanceled\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\t}\n\n\tcc.mu.Lock()\n\tif cc.idleTimer != nil {\n\t\tcc.idleTimer.Stop()\n\t}\n\tcc.decrStreamReservationsLocked()\n\tif err := cc.awaitOpenSlotForStreamLocked(cs); err != nil {\n\t\tcc.mu.Unlock()\n\t\t<-cc.reqHeaderMu\n\t\treturn err\n\t}\n\tcc.addStreamLocked(cs) // assigns stream ID\n\tif isConnectionCloseRequest(req) {\n\t\tcc.doNotReuse = true\n\t}\n\tcc.mu.Unlock()\n\n\tif streamf != nil {\n\t\tstreamf(cs)\n\t}\n\n\tcontinueTimeout := cc.t.expectContinueTimeout()\n\tif continueTimeout != 0 {\n\t\tif !httpguts.HeaderValuesContainsToken(req.Header[\"Expect\"], \"100-continue\") {\n\t\t\tcontinueTimeout = 0\n\t\t} else {\n\t\t\tcs.on100 = make(chan struct{}, 1)\n\t\t}\n\t}\n\n\t// Past this point (where we send request headers), it is possible for\n\t// RoundTrip to return successfully. Since the RoundTrip contract permits\n\t// the caller to \"mutate or reuse\" the Request after closing the Response's Body,\n\t// we must take care when referencing the Request from here on.\n\terr = cs.encodeAndWriteHeaders(req)\n\t<-cc.reqHeaderMu\n\tif err != nil {\n\t\treturn err\n\t}\n\n\thasBody := cs.reqBodyContentLength != 0\n\tif !hasBody {\n\t\tcs.sentEndStream = true\n\t} else {\n\t\tif continueTimeout != 0 {\n\t\t\ttraceWait100Continue(cs.trace)\n\t\t\ttimer := time.NewTimer(continueTimeout)\n\t\t\tselect {\n\t\t\tcase <-timer.C:\n\t\t\t\terr = nil\n\t\t\tcase <-cs.on100:\n\t\t\t\terr = nil\n\t\t\tcase <-cs.abort:\n\t\t\t\terr = cs.abortErr\n\t\t\tcase <-ctx.Done():\n\t\t\t\terr = ctx.Err()\n\t\t\tcase <-cs.reqCancel:\n\t\t\t\terr = errRequestCanceled\n\t\t\t}\n\t\t\ttimer.Stop()\n\t\t\tif err != nil {\n\t\t\t\ttraceWroteRequest(cs.trace, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tif err = cs.writeRequestBody(req); err != nil {\n\t\t\tif err != errStopReqBodyWrite {\n\t\t\t\ttraceWroteRequest(cs.trace, err)\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tcs.sentEndStream = true\n\t\t}\n\t}\n\n\ttraceWroteRequest(cs.trace, err)\n\n\tvar respHeaderTimer <-chan time.Time\n\tvar respHeaderRecv chan struct{}\n\tif d := cc.responseHeaderTimeout(); d != 0 {\n\t\ttimer := time.NewTimer(d)\n\t\tdefer timer.Stop()\n\t\trespHeaderTimer = timer.C\n\t\trespHeaderRecv = cs.respHeaderRecv\n\t}\n\t// Wait until the peer half-closes its end of the stream,\n\t// or until the request is aborted (via context, error, or otherwise),\n\t// whichever comes first.\n\tfor {\n\t\tselect {\n\t\tcase <-cs.peerClosed:\n\t\t\treturn nil\n\t\tcase <-respHeaderTimer:\n\t\t\treturn errTimeout\n\t\tcase <-respHeaderRecv:\n\t\t\trespHeaderRecv = nil\n\t\t\trespHeaderTimer = nil // keep waiting for END_STREAM\n\t\tcase <-cs.abort:\n\t\t\treturn cs.abortErr\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-cs.reqCancel:\n\t\t\treturn errRequestCanceled\n\t\t}\n\t}\n}\n\nfunc (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error {\n\tcc := cs.cc\n\tctx := cs.ctx\n\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\n\t// If the request was canceled while waiting for cc.mu, just quit.\n\tselect {\n\tcase <-cs.abort:\n\t\treturn cs.abortErr\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-cs.reqCancel:\n\t\treturn errRequestCanceled\n\tdefault:\n\t}\n\n\t// Encode headers.\n\t//\n\t// we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is\n\t// sent by writeRequestBody below, along with any Trailers,\n\t// again in form HEADERS{1}, CONTINUATION{0,})\n\tcc.hbuf.Reset()\n\tres, err := encodeRequestHeaders(req, cs.requestedGzip, cc.peerMaxHeaderListSize, func(name, value string) {\n\t\tcc.writeHeader(name, value)\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"http2: %w\", err)\n\t}\n\thdrs := cc.hbuf.Bytes()\n\n\t// Write the request.\n\tendStream := !res.HasBody && !res.HasTrailers\n\tcs.sentHeaders = true\n\terr = cc.writeHeaders(cs.ID, endStream, int(cc.maxFrameSize), hdrs)\n\ttraceWroteHeaders(cs.trace)\n\treturn err\n}\n\nfunc encodeRequestHeaders(req *http.Request, addGzipHeader bool, peerMaxHeaderListSize uint64, headerf func(name, value string)) (httpcommon.EncodeHeadersResult, error) {\n\treturn httpcommon.EncodeHeaders(req.Context(), httpcommon.EncodeHeadersParam{\n\t\tRequest: httpcommon.Request{\n\t\t\tHeader:              req.Header,\n\t\t\tTrailer:             req.Trailer,\n\t\t\tURL:                 req.URL,\n\t\t\tHost:                req.Host,\n\t\t\tMethod:              req.Method,\n\t\t\tActualContentLength: actualContentLength(req),\n\t\t},\n\t\tAddGzipHeader:         addGzipHeader,\n\t\tPeerMaxHeaderListSize: peerMaxHeaderListSize,\n\t\tDefaultUserAgent:      defaultUserAgent,\n\t}, headerf)\n}\n\n// cleanupWriteRequest performs post-request tasks.\n//\n// If err (the result of writeRequest) is non-nil and the stream is not closed,\n// cleanupWriteRequest will send a reset to the peer.\nfunc (cs *clientStream) cleanupWriteRequest(err error) {\n\tcc := cs.cc\n\n\tif cs.ID == 0 {\n\t\t// We were canceled before creating the stream, so return our reservation.\n\t\tcc.decrStreamReservations()\n\t}\n\n\t// TODO: write h12Compare test showing whether\n\t// Request.Body is closed by the Transport,\n\t// and in multiple cases: server replies <=299 and >299\n\t// while still writing request body\n\tcc.mu.Lock()\n\tmustCloseBody := false\n\tif cs.reqBody != nil && cs.reqBodyClosed == nil {\n\t\tmustCloseBody = true\n\t\tcs.reqBodyClosed = make(chan struct{})\n\t}\n\tbodyClosed := cs.reqBodyClosed\n\tcloseOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil\n\tcc.mu.Unlock()\n\tif mustCloseBody {\n\t\tcs.reqBody.Close()\n\t\tclose(bodyClosed)\n\t}\n\tif bodyClosed != nil {\n\t\t<-bodyClosed\n\t}\n\n\tif err != nil && cs.sentEndStream {\n\t\t// If the connection is closed immediately after the response is read,\n\t\t// we may be aborted before finishing up here. If the stream was closed\n\t\t// cleanly on both sides, there is no error.\n\t\tselect {\n\t\tcase <-cs.peerClosed:\n\t\t\terr = nil\n\t\tdefault:\n\t\t}\n\t}\n\tif err != nil {\n\t\tcs.abortStream(err) // possibly redundant, but harmless\n\t\tif cs.sentHeaders {\n\t\t\tif se, ok := err.(StreamError); ok {\n\t\t\t\tif se.Cause != errFromPeer {\n\t\t\t\t\tcc.writeStreamReset(cs.ID, se.Code, false, err)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We're cancelling an in-flight request.\n\t\t\t\t//\n\t\t\t\t// This could be due to the server becoming unresponsive.\n\t\t\t\t// To avoid sending too many requests on a dead connection,\n\t\t\t\t// we let the request continue to consume a concurrency slot\n\t\t\t\t// until we can confirm the server is still responding.\n\t\t\t\t// We do this by sending a PING frame along with the RST_STREAM\n\t\t\t\t// (unless a ping is already in flight).\n\t\t\t\t//\n\t\t\t\t// For simplicity, we don't bother tracking the PING payload:\n\t\t\t\t// We reset cc.pendingResets any time we receive a PING ACK.\n\t\t\t\t//\n\t\t\t\t// We skip this if the conn is going to be closed on idle,\n\t\t\t\t// because it's short lived and will probably be closed before\n\t\t\t\t// we get the ping response.\n\t\t\t\tping := false\n\t\t\t\tif !closeOnIdle {\n\t\t\t\t\tcc.mu.Lock()\n\t\t\t\t\t// rstStreamPingsBlocked works around a gRPC behavior:\n\t\t\t\t\t// see comment on the field for details.\n\t\t\t\t\tif !cc.rstStreamPingsBlocked {\n\t\t\t\t\t\tif cc.pendingResets == 0 {\n\t\t\t\t\t\t\tping = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcc.pendingResets++\n\t\t\t\t\t}\n\t\t\t\t\tcc.mu.Unlock()\n\t\t\t\t}\n\t\t\t\tcc.writeStreamReset(cs.ID, ErrCodeCancel, ping, err)\n\t\t\t}\n\t\t}\n\t\tcs.bufPipe.CloseWithError(err) // no-op if already closed\n\t} else {\n\t\tif cs.sentHeaders && !cs.sentEndStream {\n\t\t\tcc.writeStreamReset(cs.ID, ErrCodeNo, false, nil)\n\t\t}\n\t\tcs.bufPipe.CloseWithError(errRequestCanceled)\n\t}\n\tif cs.ID != 0 {\n\t\tcc.forgetStreamID(cs.ID)\n\t}\n\n\tcc.wmu.Lock()\n\twerr := cc.werr\n\tcc.wmu.Unlock()\n\tif werr != nil {\n\t\tcc.Close()\n\t}\n\n\tclose(cs.donec)\n}\n\n// awaitOpenSlotForStreamLocked waits until len(streams) < maxConcurrentStreams.\n// Must hold cc.mu.\nfunc (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error {\n\tfor {\n\t\tif cc.closed && cc.nextStreamID == 1 && cc.streamsReserved == 0 {\n\t\t\t// This is the very first request sent to this connection.\n\t\t\t// Return a fatal error which aborts the retry loop.\n\t\t\treturn errClientConnNotEstablished\n\t\t}\n\t\tcc.lastActive = time.Now()\n\t\tif cc.closed || !cc.canTakeNewRequestLocked() {\n\t\t\treturn errClientConnUnusable\n\t\t}\n\t\tcc.lastIdle = time.Time{}\n\t\tif cc.currentRequestCountLocked() < int(cc.maxConcurrentStreams) {\n\t\t\treturn nil\n\t\t}\n\t\tcc.pendingRequests++\n\t\tcc.cond.Wait()\n\t\tcc.pendingRequests--\n\t\tselect {\n\t\tcase <-cs.abort:\n\t\t\treturn cs.abortErr\n\t\tdefault:\n\t\t}\n\t}\n}\n\n// requires cc.wmu be held\nfunc (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, maxFrameSize int, hdrs []byte) error {\n\tfirst := true // first frame written (HEADERS is first, then CONTINUATION)\n\tfor len(hdrs) > 0 && cc.werr == nil {\n\t\tchunk := hdrs\n\t\tif len(chunk) > maxFrameSize {\n\t\t\tchunk = chunk[:maxFrameSize]\n\t\t}\n\t\thdrs = hdrs[len(chunk):]\n\t\tendHeaders := len(hdrs) == 0\n\t\tif first {\n\t\t\tcc.fr.WriteHeaders(HeadersFrameParam{\n\t\t\t\tStreamID:      streamID,\n\t\t\t\tBlockFragment: chunk,\n\t\t\t\tEndStream:     endStream,\n\t\t\t\tEndHeaders:    endHeaders,\n\t\t\t})\n\t\t\tfirst = false\n\t\t} else {\n\t\t\tcc.fr.WriteContinuation(streamID, endHeaders, chunk)\n\t\t}\n\t}\n\tcc.bw.Flush()\n\treturn cc.werr\n}\n\n// internal error values; they don't escape to callers\nvar (\n\t// abort request body write; don't send cancel\n\terrStopReqBodyWrite = errors.New(\"http2: aborting request body write\")\n\n\t// abort request body write, but send stream reset of cancel.\n\terrStopReqBodyWriteAndCancel = errors.New(\"http2: canceling request\")\n\n\terrReqBodyTooLong = errors.New(\"http2: request body larger than specified content length\")\n)\n\n// frameScratchBufferLen returns the length of a buffer to use for\n// outgoing request bodies to read/write to/from.\n//\n// It returns max(1, min(peer's advertised max frame size,\n// Request.ContentLength+1, 512KB)).\nfunc (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int {\n\tconst max = 512 << 10\n\tn := int64(maxFrameSize)\n\tif n > max {\n\t\tn = max\n\t}\n\tif cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n {\n\t\t// Add an extra byte past the declared content-length to\n\t\t// give the caller's Request.Body io.Reader a chance to\n\t\t// give us more bytes than they declared, so we can catch it\n\t\t// early.\n\t\tn = cl + 1\n\t}\n\tif n < 1 {\n\t\treturn 1\n\t}\n\treturn int(n) // doesn't truncate; max is 512K\n}\n\n// Seven bufPools manage different frame sizes. This helps to avoid scenarios where long-running\n// streaming requests using small frame sizes occupy large buffers initially allocated for prior\n// requests needing big buffers. The size ranges are as follows:\n// {0 KB, 16 KB], {16 KB, 32 KB], {32 KB, 64 KB], {64 KB, 128 KB], {128 KB, 256 KB],\n// {256 KB, 512 KB], {512 KB, infinity}\n// In practice, the maximum scratch buffer size should not exceed 512 KB due to\n// frameScratchBufferLen(maxFrameSize), thus the \"infinity pool\" should never be used.\n// It exists mainly as a safety measure, for potential future increases in max buffer size.\nvar bufPools [7]sync.Pool // of *[]byte\nfunc bufPoolIndex(size int) int {\n\tif size <= 16384 {\n\t\treturn 0\n\t}\n\tsize -= 1\n\tbits := bits.Len(uint(size))\n\tindex := bits - 14\n\tif index >= len(bufPools) {\n\t\treturn len(bufPools) - 1\n\t}\n\treturn index\n}\n\nfunc (cs *clientStream) writeRequestBody(req *http.Request) (err error) {\n\tcc := cs.cc\n\tbody := cs.reqBody\n\tsentEnd := false // whether we sent the final DATA frame w/ END_STREAM\n\n\thasTrailers := req.Trailer != nil\n\tremainLen := cs.reqBodyContentLength\n\thasContentLen := remainLen != -1\n\n\tcc.mu.Lock()\n\tmaxFrameSize := int(cc.maxFrameSize)\n\tcc.mu.Unlock()\n\n\t// Scratch buffer for reading into & writing from.\n\tscratchLen := cs.frameScratchBufferLen(maxFrameSize)\n\tvar buf []byte\n\tindex := bufPoolIndex(scratchLen)\n\tif bp, ok := bufPools[index].Get().(*[]byte); ok && len(*bp) >= scratchLen {\n\t\tdefer bufPools[index].Put(bp)\n\t\tbuf = *bp\n\t} else {\n\t\tbuf = make([]byte, scratchLen)\n\t\tdefer bufPools[index].Put(&buf)\n\t}\n\n\tvar sawEOF bool\n\tfor !sawEOF {\n\t\tn, err := body.Read(buf)\n\t\tif hasContentLen {\n\t\t\tremainLen -= int64(n)\n\t\t\tif remainLen == 0 && err == nil {\n\t\t\t\t// The request body's Content-Length was predeclared and\n\t\t\t\t// we just finished reading it all, but the underlying io.Reader\n\t\t\t\t// returned the final chunk with a nil error (which is one of\n\t\t\t\t// the two valid things a Reader can do at EOF). Because we'd prefer\n\t\t\t\t// to send the END_STREAM bit early, double-check that we're actually\n\t\t\t\t// at EOF. Subsequent reads should return (0, EOF) at this point.\n\t\t\t\t// If either value is different, we return an error in one of two ways below.\n\t\t\t\tvar scratch [1]byte\n\t\t\t\tvar n1 int\n\t\t\t\tn1, err = body.Read(scratch[:])\n\t\t\t\tremainLen -= int64(n1)\n\t\t\t}\n\t\t\tif remainLen < 0 {\n\t\t\t\terr = errReqBodyTooLong\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tif err != nil {\n\t\t\tcc.mu.Lock()\n\t\t\tbodyClosed := cs.reqBodyClosed != nil\n\t\t\tcc.mu.Unlock()\n\t\t\tswitch {\n\t\t\tcase bodyClosed:\n\t\t\t\treturn errStopReqBodyWrite\n\t\t\tcase err == io.EOF:\n\t\t\t\tsawEOF = true\n\t\t\t\terr = nil\n\t\t\tdefault:\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\tremain := buf[:n]\n\t\tfor len(remain) > 0 && err == nil {\n\t\t\tvar allowed int32\n\t\t\tallowed, err = cs.awaitFlowControl(len(remain))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tcc.wmu.Lock()\n\t\t\tdata := remain[:allowed]\n\t\t\tremain = remain[allowed:]\n\t\t\tsentEnd = sawEOF && len(remain) == 0 && !hasTrailers\n\t\t\terr = cc.fr.WriteData(cs.ID, sentEnd, data)\n\t\t\tif err == nil {\n\t\t\t\t// TODO(bradfitz): this flush is for latency, not bandwidth.\n\t\t\t\t// Most requests won't need this. Make this opt-in or\n\t\t\t\t// opt-out?  Use some heuristic on the body type? Nagel-like\n\t\t\t\t// timers?  Based on 'n'? Only last chunk of this for loop,\n\t\t\t\t// unless flow control tokens are low? For now, always.\n\t\t\t\t// If we change this, see comment below.\n\t\t\t\terr = cc.bw.Flush()\n\t\t\t}\n\t\t\tcc.wmu.Unlock()\n\t\t}\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif sentEnd {\n\t\t// Already sent END_STREAM (which implies we have no\n\t\t// trailers) and flushed, because currently all\n\t\t// WriteData frames above get a flush. So we're done.\n\t\treturn nil\n\t}\n\n\t// Since the RoundTrip contract permits the caller to \"mutate or reuse\"\n\t// a request after the Response's Body is closed, verify that this hasn't\n\t// happened before accessing the trailers.\n\tcc.mu.Lock()\n\ttrailer := req.Trailer\n\terr = cs.abortErr\n\tcc.mu.Unlock()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\tvar trls []byte\n\tif len(trailer) > 0 {\n\t\ttrls, err = cc.encodeTrailers(trailer)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\t// Two ways to send END_STREAM: either with trailers, or\n\t// with an empty DATA frame.\n\tif len(trls) > 0 {\n\t\terr = cc.writeHeaders(cs.ID, true, maxFrameSize, trls)\n\t} else {\n\t\terr = cc.fr.WriteData(cs.ID, true, nil)\n\t}\n\tif ferr := cc.bw.Flush(); ferr != nil && err == nil {\n\t\terr = ferr\n\t}\n\treturn err\n}\n\n// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow\n// control tokens from the server.\n// It returns either the non-zero number of tokens taken or an error\n// if the stream is dead.\nfunc (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {\n\tcc := cs.cc\n\tctx := cs.ctx\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\tfor {\n\t\tif cc.closed {\n\t\t\treturn 0, errClientConnClosed\n\t\t}\n\t\tif cs.reqBodyClosed != nil {\n\t\t\treturn 0, errStopReqBodyWrite\n\t\t}\n\t\tselect {\n\t\tcase <-cs.abort:\n\t\t\treturn 0, cs.abortErr\n\t\tcase <-ctx.Done():\n\t\t\treturn 0, ctx.Err()\n\t\tcase <-cs.reqCancel:\n\t\t\treturn 0, errRequestCanceled\n\t\tdefault:\n\t\t}\n\t\tif a := cs.flow.available(); a > 0 {\n\t\t\ttake := a\n\t\t\tif int(take) > maxBytes {\n\n\t\t\t\ttake = int32(maxBytes) // can't truncate int; take is int32\n\t\t\t}\n\t\t\tif take > int32(cc.maxFrameSize) {\n\t\t\t\ttake = int32(cc.maxFrameSize)\n\t\t\t}\n\t\t\tcs.flow.take(take)\n\t\t\treturn take, nil\n\t\t}\n\t\tcc.cond.Wait()\n\t}\n}\n\n// requires cc.wmu be held.\nfunc (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) {\n\tcc.hbuf.Reset()\n\n\thlSize := uint64(0)\n\tfor k, vv := range trailer {\n\t\tfor _, v := range vv {\n\t\t\thf := hpack.HeaderField{Name: k, Value: v}\n\t\t\thlSize += uint64(hf.Size())\n\t\t}\n\t}\n\tif hlSize > cc.peerMaxHeaderListSize {\n\t\treturn nil, errRequestHeaderListSize\n\t}\n\n\tfor k, vv := range trailer {\n\t\tlowKey, ascii := httpcommon.LowerHeader(k)\n\t\tif !ascii {\n\t\t\t// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header\n\t\t\t// field names have to be ASCII characters (just as in HTTP/1.x).\n\t\t\tcontinue\n\t\t}\n\t\t// Transfer-Encoding, etc.. have already been filtered at the\n\t\t// start of RoundTrip\n\t\tfor _, v := range vv {\n\t\t\tcc.writeHeader(lowKey, v)\n\t\t}\n\t}\n\treturn cc.hbuf.Bytes(), nil\n}\n\nfunc (cc *ClientConn) writeHeader(name, value string) {\n\tif VerboseLogs {\n\t\tlog.Printf(\"http2: Transport encoding header %q = %q\", name, value)\n\t}\n\tcc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})\n}\n\ntype resAndError struct {\n\t_   incomparable\n\tres *http.Response\n\terr error\n}\n\n// requires cc.mu be held.\nfunc (cc *ClientConn) addStreamLocked(cs *clientStream) {\n\tcs.flow.add(int32(cc.initialWindowSize))\n\tcs.flow.setConnFlow(&cc.flow)\n\tcs.inflow.init(cc.initialStreamRecvWindowSize)\n\tcs.ID = cc.nextStreamID\n\tcc.nextStreamID += 2\n\tcc.streams[cs.ID] = cs\n\tif cs.ID == 0 {\n\t\tpanic(\"assigned stream ID 0\")\n\t}\n}\n\nfunc (cc *ClientConn) forgetStreamID(id uint32) {\n\tcc.mu.Lock()\n\tslen := len(cc.streams)\n\tdelete(cc.streams, id)\n\tif len(cc.streams) != slen-1 {\n\t\tpanic(\"forgetting unknown stream id\")\n\t}\n\tcc.lastActive = time.Now()\n\tif len(cc.streams) == 0 && cc.idleTimer != nil {\n\t\tcc.idleTimer.Reset(cc.idleTimeout)\n\t\tcc.lastIdle = time.Now()\n\t}\n\t// Wake up writeRequestBody via clientStream.awaitFlowControl and\n\t// wake up RoundTrip if there is a pending request.\n\tcc.cond.Broadcast()\n\n\tcloseOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil\n\tif closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {\n\t\tif VerboseLogs {\n\t\t\tcc.vlogf(\"http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)\", cc, cc.singleUse, cc.nextStreamID-2)\n\t\t}\n\t\tcc.closed = true\n\t\tdefer cc.closeConn()\n\t}\n\n\tcc.mu.Unlock()\n}\n\n// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop.\ntype clientConnReadLoop struct {\n\t_  incomparable\n\tcc *ClientConn\n}\n\n// readLoop runs in its own goroutine and reads and dispatches frames.\nfunc (cc *ClientConn) readLoop() {\n\trl := &clientConnReadLoop{cc: cc}\n\tdefer rl.cleanup()\n\tcc.readerErr = rl.run()\n\tif ce, ok := cc.readerErr.(ConnectionError); ok {\n\t\tcc.wmu.Lock()\n\t\tcc.fr.WriteGoAway(0, ErrCode(ce), nil)\n\t\tcc.wmu.Unlock()\n\t}\n}\n\n// GoAwayError is returned by the Transport when the server closes the\n// TCP connection after sending a GOAWAY frame.\ntype GoAwayError struct {\n\tLastStreamID uint32\n\tErrCode      ErrCode\n\tDebugData    string\n}\n\nfunc (e GoAwayError) Error() string {\n\treturn fmt.Sprintf(\"http2: server sent GOAWAY and closed the connection; LastStreamID=%v, ErrCode=%v, debug=%q\",\n\t\te.LastStreamID, e.ErrCode, e.DebugData)\n}\n\nfunc isEOFOrNetReadError(err error) bool {\n\tif err == io.EOF {\n\t\treturn true\n\t}\n\tne, ok := err.(*net.OpError)\n\treturn ok && ne.Op == \"read\"\n}\n\nfunc (rl *clientConnReadLoop) cleanup() {\n\tcc := rl.cc\n\tdefer cc.closeConn()\n\tdefer close(cc.readerDone)\n\n\tif cc.idleTimer != nil {\n\t\tcc.idleTimer.Stop()\n\t}\n\n\t// Close any response bodies if the server closes prematurely.\n\t// TODO: also do this if we've written the headers but not\n\t// gotten a response yet.\n\terr := cc.readerErr\n\tcc.mu.Lock()\n\tif cc.goAway != nil && isEOFOrNetReadError(err) {\n\t\terr = GoAwayError{\n\t\t\tLastStreamID: cc.goAway.LastStreamID,\n\t\t\tErrCode:      cc.goAway.ErrCode,\n\t\t\tDebugData:    cc.goAwayDebug,\n\t\t}\n\t} else if err == io.EOF {\n\t\terr = io.ErrUnexpectedEOF\n\t}\n\tcc.closed = true\n\n\t// If the connection has never been used, and has been open for only a short time,\n\t// leave it in the connection pool for a little while.\n\t//\n\t// This avoids a situation where new connections are constantly created,\n\t// added to the pool, fail, and are removed from the pool, without any error\n\t// being surfaced to the user.\n\tunusedWaitTime := 5 * time.Second\n\tif cc.idleTimeout > 0 && unusedWaitTime > cc.idleTimeout {\n\t\tunusedWaitTime = cc.idleTimeout\n\t}\n\tidleTime := time.Now().Sub(cc.lastActive)\n\tif atomic.LoadUint32(&cc.atomicReused) == 0 && idleTime < unusedWaitTime && !cc.closedOnIdle {\n\t\tcc.idleTimer = time.AfterFunc(unusedWaitTime-idleTime, func() {\n\t\t\tcc.t.connPool().MarkDead(cc)\n\t\t})\n\t} else {\n\t\tcc.mu.Unlock() // avoid any deadlocks in MarkDead\n\t\tcc.t.connPool().MarkDead(cc)\n\t\tcc.mu.Lock()\n\t}\n\n\tfor _, cs := range cc.streams {\n\t\tselect {\n\t\tcase <-cs.peerClosed:\n\t\t\t// The server closed the stream before closing the conn,\n\t\t\t// so no need to interrupt it.\n\t\tdefault:\n\t\t\tcs.abortStreamLocked(err)\n\t\t}\n\t}\n\tcc.cond.Broadcast()\n\tcc.mu.Unlock()\n\n\tif !cc.seenSettings {\n\t\t// If we have a pending request that wants extended CONNECT,\n\t\t// let it continue and fail with the connection error.\n\t\tcc.extendedConnectAllowed = true\n\t\tclose(cc.seenSettingsChan)\n\t}\n}\n\n// countReadFrameError calls Transport.CountError with a string\n// representing err.\nfunc (cc *ClientConn) countReadFrameError(err error) {\n\tf := cc.t.CountError\n\tif f == nil || err == nil {\n\t\treturn\n\t}\n\tif ce, ok := err.(ConnectionError); ok {\n\t\terrCode := ErrCode(ce)\n\t\tf(fmt.Sprintf(\"read_frame_conn_error_%s\", errCode.stringToken()))\n\t\treturn\n\t}\n\tif errors.Is(err, io.EOF) {\n\t\tf(\"read_frame_eof\")\n\t\treturn\n\t}\n\tif errors.Is(err, io.ErrUnexpectedEOF) {\n\t\tf(\"read_frame_unexpected_eof\")\n\t\treturn\n\t}\n\tif errors.Is(err, ErrFrameTooLarge) {\n\t\tf(\"read_frame_too_large\")\n\t\treturn\n\t}\n\tf(\"read_frame_other\")\n}\n\nfunc (rl *clientConnReadLoop) run() error {\n\tcc := rl.cc\n\tgotSettings := false\n\treadIdleTimeout := cc.readIdleTimeout\n\tvar t *time.Timer\n\tif readIdleTimeout != 0 {\n\t\tt = time.AfterFunc(readIdleTimeout, cc.healthCheck)\n\t}\n\tfor {\n\t\tf, err := cc.fr.ReadFrame()\n\t\tif t != nil {\n\t\t\tt.Reset(readIdleTimeout)\n\t\t}\n\t\tif err != nil {\n\t\t\tcc.vlogf(\"http2: Transport readFrame error on conn %p: (%T) %v\", cc, err, err)\n\t\t}\n\t\tif se, ok := err.(StreamError); ok {\n\t\t\tif cs := rl.streamByID(se.StreamID, notHeaderOrDataFrame); cs != nil {\n\t\t\t\tif se.Cause == nil {\n\t\t\t\t\tse.Cause = cc.fr.errDetail\n\t\t\t\t}\n\t\t\t\trl.endStreamError(cs, se)\n\t\t\t}\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\tcc.countReadFrameError(err)\n\t\t\treturn err\n\t\t}\n\t\tif VerboseLogs {\n\t\t\tcc.vlogf(\"http2: Transport received %s\", summarizeFrame(f))\n\t\t}\n\t\tif !gotSettings {\n\t\t\tif _, ok := f.(*SettingsFrame); !ok {\n\t\t\t\tcc.logf(\"protocol error: received %T before a SETTINGS frame\", f)\n\t\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t\t}\n\t\t\tgotSettings = true\n\t\t}\n\n\t\tswitch f := f.(type) {\n\t\tcase *MetaHeadersFrame:\n\t\t\terr = rl.processHeaders(f)\n\t\tcase *DataFrame:\n\t\t\terr = rl.processData(f)\n\t\tcase *GoAwayFrame:\n\t\t\terr = rl.processGoAway(f)\n\t\tcase *RSTStreamFrame:\n\t\t\terr = rl.processResetStream(f)\n\t\tcase *SettingsFrame:\n\t\t\terr = rl.processSettings(f)\n\t\tcase *PushPromiseFrame:\n\t\t\terr = rl.processPushPromise(f)\n\t\tcase *WindowUpdateFrame:\n\t\t\terr = rl.processWindowUpdate(f)\n\t\tcase *PingFrame:\n\t\t\terr = rl.processPing(f)\n\t\tdefault:\n\t\t\tcc.logf(\"Transport: unhandled response frame type %T\", f)\n\t\t}\n\t\tif err != nil {\n\t\t\tif VerboseLogs {\n\t\t\t\tcc.vlogf(\"http2: Transport conn %p received error from processing frame %v: %v\", cc, summarizeFrame(f), err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n}\n\nfunc (rl *clientConnReadLoop) processHeaders(f *MetaHeadersFrame) error {\n\tcs := rl.streamByID(f.StreamID, headerOrDataFrame)\n\tif cs == nil {\n\t\t// We'd get here if we canceled a request while the\n\t\t// server had its response still in flight. So if this\n\t\t// was just something we canceled, ignore it.\n\t\treturn nil\n\t}\n\tif cs.readClosed {\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t\tCause:    errors.New(\"protocol error: headers after END_STREAM\"),\n\t\t})\n\t\treturn nil\n\t}\n\tif !cs.firstByte {\n\t\tif cs.trace != nil {\n\t\t\t// TODO(bradfitz): move first response byte earlier,\n\t\t\t// when we first read the 9 byte header, not waiting\n\t\t\t// until all the HEADERS+CONTINUATION frames have been\n\t\t\t// merged. This works for now.\n\t\t\ttraceFirstResponseByte(cs.trace)\n\t\t}\n\t\tcs.firstByte = true\n\t}\n\tif !cs.pastHeaders {\n\t\tcs.pastHeaders = true\n\t} else {\n\t\treturn rl.processTrailers(cs, f)\n\t}\n\n\tres, err := rl.handleResponse(cs, f)\n\tif err != nil {\n\t\tif _, ok := err.(ConnectionError); ok {\n\t\t\treturn err\n\t\t}\n\t\t// Any other error type is a stream error.\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t\tCause:    err,\n\t\t})\n\t\treturn nil // return nil from process* funcs to keep conn alive\n\t}\n\tif res == nil {\n\t\t// (nil, nil) special case. See handleResponse docs.\n\t\treturn nil\n\t}\n\tcs.resTrailer = &res.Trailer\n\tcs.res = res\n\tclose(cs.respHeaderRecv)\n\tif f.StreamEnded() {\n\t\trl.endStream(cs)\n\t}\n\treturn nil\n}\n\n// may return error types nil, or ConnectionError. Any other error value\n// is a StreamError of type ErrCodeProtocol. The returned error in that case\n// is the detail.\n//\n// As a special case, handleResponse may return (nil, nil) to skip the\n// frame (currently only used for 1xx responses).\nfunc (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFrame) (*http.Response, error) {\n\tif f.Truncated {\n\t\treturn nil, errResponseHeaderListSize\n\t}\n\n\tstatus := f.PseudoValue(\"status\")\n\tif status == \"\" {\n\t\treturn nil, errors.New(\"malformed response from server: missing status pseudo header\")\n\t}\n\tstatusCode, err := strconv.Atoi(status)\n\tif err != nil {\n\t\treturn nil, errors.New(\"malformed response from server: malformed non-numeric status pseudo header\")\n\t}\n\n\tregularFields := f.RegularFields()\n\tstrs := make([]string, len(regularFields))\n\theader := make(http.Header, len(regularFields))\n\tres := &http.Response{\n\t\tProto:      \"HTTP/2.0\",\n\t\tProtoMajor: 2,\n\t\tHeader:     header,\n\t\tStatusCode: statusCode,\n\t\tStatus:     status + \" \" + http.StatusText(statusCode),\n\t}\n\tfor _, hf := range regularFields {\n\t\tkey := httpcommon.CanonicalHeader(hf.Name)\n\t\tif key == \"Trailer\" {\n\t\t\tt := res.Trailer\n\t\t\tif t == nil {\n\t\t\t\tt = make(http.Header)\n\t\t\t\tres.Trailer = t\n\t\t\t}\n\t\t\tforeachHeaderElement(hf.Value, func(v string) {\n\t\t\t\tt[httpcommon.CanonicalHeader(v)] = nil\n\t\t\t})\n\t\t} else {\n\t\t\tvv := header[key]\n\t\t\tif vv == nil && len(strs) > 0 {\n\t\t\t\t// More than likely this will be a single-element key.\n\t\t\t\t// Most headers aren't multi-valued.\n\t\t\t\t// Set the capacity on strs[0] to 1, so any future append\n\t\t\t\t// won't extend the slice into the other strings.\n\t\t\t\tvv, strs = strs[:1:1], strs[1:]\n\t\t\t\tvv[0] = hf.Value\n\t\t\t\theader[key] = vv\n\t\t\t} else {\n\t\t\t\theader[key] = append(vv, hf.Value)\n\t\t\t}\n\t\t}\n\t}\n\n\tif statusCode >= 100 && statusCode <= 199 {\n\t\tif f.StreamEnded() {\n\t\t\treturn nil, errors.New(\"1xx informational response with END_STREAM flag\")\n\t\t}\n\t\tif fn := cs.get1xxTraceFunc(); fn != nil {\n\t\t\t// If the 1xx response is being delivered to the user,\n\t\t\t// then they're responsible for limiting the number\n\t\t\t// of responses.\n\t\t\tif err := fn(statusCode, textproto.MIMEHeader(header)); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t} else {\n\t\t\t// If the user didn't examine the 1xx response, then we\n\t\t\t// limit the size of all 1xx headers.\n\t\t\t//\n\t\t\t// This differs a bit from the HTTP/1 implementation, which\n\t\t\t// limits the size of all 1xx headers plus the final response.\n\t\t\t// Use the larger limit of MaxHeaderListSize and\n\t\t\t// net/http.Transport.MaxResponseHeaderBytes.\n\t\t\tlimit := int64(cs.cc.t.maxHeaderListSize())\n\t\t\tif t1 := cs.cc.t.t1; t1 != nil && t1.MaxResponseHeaderBytes > limit {\n\t\t\t\tlimit = t1.MaxResponseHeaderBytes\n\t\t\t}\n\t\t\tfor _, h := range f.Fields {\n\t\t\t\tcs.totalHeaderSize += int64(h.Size())\n\t\t\t}\n\t\t\tif cs.totalHeaderSize > limit {\n\t\t\t\tif VerboseLogs {\n\t\t\t\t\tlog.Printf(\"http2: 1xx informational responses too large\")\n\t\t\t\t}\n\t\t\t\treturn nil, errors.New(\"header list too large\")\n\t\t\t}\n\t\t}\n\t\tif statusCode == 100 {\n\t\t\ttraceGot100Continue(cs.trace)\n\t\t\tselect {\n\t\t\tcase cs.on100 <- struct{}{}:\n\t\t\tdefault:\n\t\t\t}\n\t\t}\n\t\tcs.pastHeaders = false // do it all again\n\t\treturn nil, nil\n\t}\n\n\tres.ContentLength = -1\n\tif clens := res.Header[\"Content-Length\"]; len(clens) == 1 {\n\t\tif cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {\n\t\t\tres.ContentLength = int64(cl)\n\t\t} else {\n\t\t\t// TODO: care? unlike http/1, it won't mess up our framing, so it's\n\t\t\t// more safe smuggling-wise to ignore.\n\t\t}\n\t} else if len(clens) > 1 {\n\t\t// TODO: care? unlike http/1, it won't mess up our framing, so it's\n\t\t// more safe smuggling-wise to ignore.\n\t} else if f.StreamEnded() && !cs.isHead {\n\t\tres.ContentLength = 0\n\t}\n\n\tif cs.isHead {\n\t\tres.Body = noBody\n\t\treturn res, nil\n\t}\n\n\tif f.StreamEnded() {\n\t\tif res.ContentLength > 0 {\n\t\t\tres.Body = missingBody{}\n\t\t} else {\n\t\t\tres.Body = noBody\n\t\t}\n\t\treturn res, nil\n\t}\n\n\tcs.bufPipe.setBuffer(&dataBuffer{expected: res.ContentLength})\n\tcs.bytesRemain = res.ContentLength\n\tres.Body = transportResponseBody{cs}\n\n\tif cs.requestedGzip && asciiEqualFold(res.Header.Get(\"Content-Encoding\"), \"gzip\") {\n\t\tres.Header.Del(\"Content-Encoding\")\n\t\tres.Header.Del(\"Content-Length\")\n\t\tres.ContentLength = -1\n\t\tres.Body = &gzipReader{body: res.Body}\n\t\tres.Uncompressed = true\n\t}\n\treturn res, nil\n}\n\nfunc (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFrame) error {\n\tif cs.pastTrailers {\n\t\t// Too many HEADERS frames for this stream.\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\tcs.pastTrailers = true\n\tif !f.StreamEnded() {\n\t\t// We expect that any headers for trailers also\n\t\t// has END_STREAM.\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\tif len(f.PseudoFields()) > 0 {\n\t\t// No pseudo header fields are defined for trailers.\n\t\t// TODO: ConnectionError might be overly harsh? Check.\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\n\ttrailer := make(http.Header)\n\tfor _, hf := range f.RegularFields() {\n\t\tkey := httpcommon.CanonicalHeader(hf.Name)\n\t\ttrailer[key] = append(trailer[key], hf.Value)\n\t}\n\tcs.trailer = trailer\n\n\trl.endStream(cs)\n\treturn nil\n}\n\n// transportResponseBody is the concrete type of Transport.RoundTrip's\n// Response.Body. It is an io.ReadCloser.\ntype transportResponseBody struct {\n\tcs *clientStream\n}\n\nfunc (b transportResponseBody) Read(p []byte) (n int, err error) {\n\tcs := b.cs\n\tcc := cs.cc\n\n\tif cs.readErr != nil {\n\t\treturn 0, cs.readErr\n\t}\n\tn, err = b.cs.bufPipe.Read(p)\n\tif cs.bytesRemain != -1 {\n\t\tif int64(n) > cs.bytesRemain {\n\t\t\tn = int(cs.bytesRemain)\n\t\t\tif err == nil {\n\t\t\t\terr = errors.New(\"net/http: server replied with more than declared Content-Length; truncated\")\n\t\t\t\tcs.abortStream(err)\n\t\t\t}\n\t\t\tcs.readErr = err\n\t\t\treturn int(cs.bytesRemain), err\n\t\t}\n\t\tcs.bytesRemain -= int64(n)\n\t\tif err == io.EOF && cs.bytesRemain > 0 {\n\t\t\terr = io.ErrUnexpectedEOF\n\t\t\tcs.readErr = err\n\t\t\treturn n, err\n\t\t}\n\t}\n\tif n == 0 {\n\t\t// No flow control tokens to send back.\n\t\treturn\n\t}\n\n\tcc.mu.Lock()\n\tconnAdd := cc.inflow.add(n)\n\tvar streamAdd int32\n\tif err == nil { // No need to refresh if the stream is over or failed.\n\t\tstreamAdd = cs.inflow.add(n)\n\t}\n\tcc.mu.Unlock()\n\n\tif connAdd != 0 || streamAdd != 0 {\n\t\tcc.wmu.Lock()\n\t\tdefer cc.wmu.Unlock()\n\t\tif connAdd != 0 {\n\t\t\tcc.fr.WriteWindowUpdate(0, mustUint31(connAdd))\n\t\t}\n\t\tif streamAdd != 0 {\n\t\t\tcc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd))\n\t\t}\n\t\tcc.bw.Flush()\n\t}\n\treturn\n}\n\nvar errClosedResponseBody = errors.New(\"http2: response body closed\")\n\nfunc (b transportResponseBody) Close() error {\n\tcs := b.cs\n\tcc := cs.cc\n\n\tcs.bufPipe.BreakWithError(errClosedResponseBody)\n\tcs.abortStream(errClosedResponseBody)\n\n\tunread := cs.bufPipe.Len()\n\tif unread > 0 {\n\t\tcc.mu.Lock()\n\t\t// Return connection-level flow control.\n\t\tconnAdd := cc.inflow.add(unread)\n\t\tcc.mu.Unlock()\n\n\t\t// TODO(dneil): Acquiring this mutex can block indefinitely.\n\t\t// Move flow control return to a goroutine?\n\t\tcc.wmu.Lock()\n\t\t// Return connection-level flow control.\n\t\tif connAdd > 0 {\n\t\t\tcc.fr.WriteWindowUpdate(0, uint32(connAdd))\n\t\t}\n\t\tcc.bw.Flush()\n\t\tcc.wmu.Unlock()\n\t}\n\n\tselect {\n\tcase <-cs.donec:\n\tcase <-cs.ctx.Done():\n\t\t// See golang/go#49366: The net/http package can cancel the\n\t\t// request context after the response body is fully read.\n\t\t// Don't treat this as an error.\n\t\treturn nil\n\tcase <-cs.reqCancel:\n\t\treturn errRequestCanceled\n\t}\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processData(f *DataFrame) error {\n\tcc := rl.cc\n\tcs := rl.streamByID(f.StreamID, headerOrDataFrame)\n\tdata := f.Data()\n\tif cs == nil {\n\t\tcc.mu.Lock()\n\t\tneverSent := cc.nextStreamID\n\t\tcc.mu.Unlock()\n\t\tif f.StreamID >= neverSent {\n\t\t\t// We never asked for this.\n\t\t\tcc.logf(\"http2: Transport received unsolicited DATA frame; closing connection\")\n\t\t\treturn ConnectionError(ErrCodeProtocol)\n\t\t}\n\t\t// We probably did ask for this, but canceled. Just ignore it.\n\t\t// TODO: be stricter here? only silently ignore things which\n\t\t// we canceled, but not things which were closed normally\n\t\t// by the peer? Tough without accumulating too much state.\n\n\t\t// But at least return their flow control:\n\t\tif f.Length > 0 {\n\t\t\tcc.mu.Lock()\n\t\t\tok := cc.inflow.take(f.Length)\n\t\t\tconnAdd := cc.inflow.add(int(f.Length))\n\t\t\tcc.mu.Unlock()\n\t\t\tif !ok {\n\t\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t\t}\n\t\t\tif connAdd > 0 {\n\t\t\t\tcc.wmu.Lock()\n\t\t\t\tcc.fr.WriteWindowUpdate(0, uint32(connAdd))\n\t\t\t\tcc.bw.Flush()\n\t\t\t\tcc.wmu.Unlock()\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\tif cs.readClosed {\n\t\tcc.logf(\"protocol error: received DATA after END_STREAM\")\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t})\n\t\treturn nil\n\t}\n\tif !cs.pastHeaders {\n\t\tcc.logf(\"protocol error: received DATA before a HEADERS frame\")\n\t\trl.endStreamError(cs, StreamError{\n\t\t\tStreamID: f.StreamID,\n\t\t\tCode:     ErrCodeProtocol,\n\t\t})\n\t\treturn nil\n\t}\n\tif f.Length > 0 {\n\t\tif cs.isHead && len(data) > 0 {\n\t\t\tcc.logf(\"protocol error: received DATA on a HEAD request\")\n\t\t\trl.endStreamError(cs, StreamError{\n\t\t\t\tStreamID: f.StreamID,\n\t\t\t\tCode:     ErrCodeProtocol,\n\t\t\t})\n\t\t\treturn nil\n\t\t}\n\t\t// Check connection-level flow control.\n\t\tcc.mu.Lock()\n\t\tif !takeInflows(&cc.inflow, &cs.inflow, f.Length) {\n\t\t\tcc.mu.Unlock()\n\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t}\n\t\t// Return any padded flow control now, since we won't\n\t\t// refund it later on body reads.\n\t\tvar refund int\n\t\tif pad := int(f.Length) - len(data); pad > 0 {\n\t\t\trefund += pad\n\t\t}\n\n\t\tdidReset := false\n\t\tvar err error\n\t\tif len(data) > 0 {\n\t\t\tif _, err = cs.bufPipe.Write(data); err != nil {\n\t\t\t\t// Return len(data) now if the stream is already closed,\n\t\t\t\t// since data will never be read.\n\t\t\t\tdidReset = true\n\t\t\t\trefund += len(data)\n\t\t\t}\n\t\t}\n\n\t\tsendConn := cc.inflow.add(refund)\n\t\tvar sendStream int32\n\t\tif !didReset {\n\t\t\tsendStream = cs.inflow.add(refund)\n\t\t}\n\t\tcc.mu.Unlock()\n\n\t\tif sendConn > 0 || sendStream > 0 {\n\t\t\tcc.wmu.Lock()\n\t\t\tif sendConn > 0 {\n\t\t\t\tcc.fr.WriteWindowUpdate(0, uint32(sendConn))\n\t\t\t}\n\t\t\tif sendStream > 0 {\n\t\t\t\tcc.fr.WriteWindowUpdate(cs.ID, uint32(sendStream))\n\t\t\t}\n\t\t\tcc.bw.Flush()\n\t\t\tcc.wmu.Unlock()\n\t\t}\n\n\t\tif err != nil {\n\t\t\trl.endStreamError(cs, err)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\tif f.StreamEnded() {\n\t\trl.endStream(cs)\n\t}\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) endStream(cs *clientStream) {\n\t// TODO: check that any declared content-length matches, like\n\t// server.go's (*stream).endStream method.\n\tif !cs.readClosed {\n\t\tcs.readClosed = true\n\t\t// Close cs.bufPipe and cs.peerClosed with cc.mu held to avoid a\n\t\t// race condition: The caller can read io.EOF from Response.Body\n\t\t// and close the body before we close cs.peerClosed, causing\n\t\t// cleanupWriteRequest to send a RST_STREAM.\n\t\trl.cc.mu.Lock()\n\t\tdefer rl.cc.mu.Unlock()\n\t\tcs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers)\n\t\tclose(cs.peerClosed)\n\t}\n}\n\nfunc (rl *clientConnReadLoop) endStreamError(cs *clientStream, err error) {\n\tcs.readAborted = true\n\tcs.abortStream(err)\n}\n\n// Constants passed to streamByID for documentation purposes.\nconst (\n\theaderOrDataFrame    = true\n\tnotHeaderOrDataFrame = false\n)\n\n// streamByID returns the stream with the given id, or nil if no stream has that id.\n// If headerOrData is true, it clears rst.StreamPingsBlocked.\nfunc (rl *clientConnReadLoop) streamByID(id uint32, headerOrData bool) *clientStream {\n\trl.cc.mu.Lock()\n\tdefer rl.cc.mu.Unlock()\n\tif headerOrData {\n\t\t// Work around an unfortunate gRPC behavior.\n\t\t// See comment on ClientConn.rstStreamPingsBlocked for details.\n\t\trl.cc.rstStreamPingsBlocked = false\n\t}\n\tcs := rl.cc.streams[id]\n\tif cs != nil && !cs.readAborted {\n\t\treturn cs\n\t}\n\treturn nil\n}\n\nfunc (cs *clientStream) copyTrailers() {\n\tfor k, vv := range cs.trailer {\n\t\tt := cs.resTrailer\n\t\tif *t == nil {\n\t\t\t*t = make(http.Header)\n\t\t}\n\t\t(*t)[k] = vv\n\t}\n}\n\nfunc (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error {\n\tcc := rl.cc\n\tcc.t.connPool().MarkDead(cc)\n\tif f.ErrCode != 0 {\n\t\t// TODO: deal with GOAWAY more. particularly the error code\n\t\tcc.vlogf(\"transport got GOAWAY with error code = %v\", f.ErrCode)\n\t\tif fn := cc.t.CountError; fn != nil {\n\t\t\tfn(\"recv_goaway_\" + f.ErrCode.stringToken())\n\t\t}\n\t}\n\tcc.setGoAway(f)\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error {\n\tcc := rl.cc\n\t// Locking both mu and wmu here allows frame encoding to read settings with only wmu held.\n\t// Acquiring wmu when f.IsAck() is unnecessary, but convenient and mostly harmless.\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\n\tif err := rl.processSettingsNoWrite(f); err != nil {\n\t\treturn err\n\t}\n\tif !f.IsAck() {\n\t\tcc.fr.WriteSettingsAck()\n\t\tcc.bw.Flush()\n\t}\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error {\n\tcc := rl.cc\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\n\tif f.IsAck() {\n\t\tif cc.wantSettingsAck {\n\t\t\tcc.wantSettingsAck = false\n\t\t\treturn nil\n\t\t}\n\t\treturn ConnectionError(ErrCodeProtocol)\n\t}\n\n\tvar seenMaxConcurrentStreams bool\n\terr := f.ForeachSetting(func(s Setting) error {\n\t\tswitch s.ID {\n\t\tcase SettingMaxFrameSize:\n\t\t\tcc.maxFrameSize = s.Val\n\t\tcase SettingMaxConcurrentStreams:\n\t\t\tcc.maxConcurrentStreams = s.Val\n\t\t\tseenMaxConcurrentStreams = true\n\t\tcase SettingMaxHeaderListSize:\n\t\t\tcc.peerMaxHeaderListSize = uint64(s.Val)\n\t\tcase SettingInitialWindowSize:\n\t\t\t// Values above the maximum flow-control\n\t\t\t// window size of 2^31-1 MUST be treated as a\n\t\t\t// connection error (Section 5.4.1) of type\n\t\t\t// FLOW_CONTROL_ERROR.\n\t\t\tif s.Val > math.MaxInt32 {\n\t\t\t\treturn ConnectionError(ErrCodeFlowControl)\n\t\t\t}\n\n\t\t\t// Adjust flow control of currently-open\n\t\t\t// frames by the difference of the old initial\n\t\t\t// window size and this one.\n\t\t\tdelta := int32(s.Val) - int32(cc.initialWindowSize)\n\t\t\tfor _, cs := range cc.streams {\n\t\t\t\tcs.flow.add(delta)\n\t\t\t}\n\t\t\tcc.cond.Broadcast()\n\n\t\t\tcc.initialWindowSize = s.Val\n\t\tcase SettingHeaderTableSize:\n\t\t\tcc.henc.SetMaxDynamicTableSize(s.Val)\n\t\t\tcc.peerMaxHeaderTableSize = s.Val\n\t\tcase SettingEnableConnectProtocol:\n\t\t\tif err := s.Valid(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// If the peer wants to send us SETTINGS_ENABLE_CONNECT_PROTOCOL,\n\t\t\t// we require that it do so in the first SETTINGS frame.\n\t\t\t//\n\t\t\t// When we attempt to use extended CONNECT, we wait for the first\n\t\t\t// SETTINGS frame to see if the server supports it. If we let the\n\t\t\t// server enable the feature with a later SETTINGS frame, then\n\t\t\t// users will see inconsistent results depending on whether we've\n\t\t\t// seen that frame or not.\n\t\t\tif !cc.seenSettings {\n\t\t\t\tcc.extendedConnectAllowed = s.Val == 1\n\t\t\t}\n\t\tdefault:\n\t\t\tcc.vlogf(\"Unhandled Setting: %v\", s)\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif !cc.seenSettings {\n\t\tif !seenMaxConcurrentStreams {\n\t\t\t// This was the servers initial SETTINGS frame and it\n\t\t\t// didn't contain a MAX_CONCURRENT_STREAMS field so\n\t\t\t// increase the number of concurrent streams this\n\t\t\t// connection can establish to our default.\n\t\t\tcc.maxConcurrentStreams = defaultMaxConcurrentStreams\n\t\t}\n\t\tclose(cc.seenSettingsChan)\n\t\tcc.seenSettings = true\n\t}\n\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {\n\tcc := rl.cc\n\tcs := rl.streamByID(f.StreamID, notHeaderOrDataFrame)\n\tif f.StreamID != 0 && cs == nil {\n\t\treturn nil\n\t}\n\n\tcc.mu.Lock()\n\tdefer cc.mu.Unlock()\n\n\tfl := &cc.flow\n\tif cs != nil {\n\t\tfl = &cs.flow\n\t}\n\tif !fl.add(int32(f.Increment)) {\n\t\t// For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR\n\t\tif cs != nil {\n\t\t\trl.endStreamError(cs, StreamError{\n\t\t\t\tStreamID: f.StreamID,\n\t\t\t\tCode:     ErrCodeFlowControl,\n\t\t\t})\n\t\t\treturn nil\n\t\t}\n\n\t\treturn ConnectionError(ErrCodeFlowControl)\n\t}\n\tcc.cond.Broadcast()\n\treturn nil\n}\n\nfunc (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error {\n\tcs := rl.streamByID(f.StreamID, notHeaderOrDataFrame)\n\tif cs == nil {\n\t\t// TODO: return error if server tries to RST_STREAM an idle stream\n\t\treturn nil\n\t}\n\tserr := streamError(cs.ID, f.ErrCode)\n\tserr.Cause = errFromPeer\n\tif f.ErrCode == ErrCodeProtocol {\n\t\trl.cc.SetDoNotReuse()\n\t}\n\tif fn := cs.cc.t.CountError; fn != nil {\n\t\tfn(\"recv_rststream_\" + f.ErrCode.stringToken())\n\t}\n\tcs.abortStream(serr)\n\n\tcs.bufPipe.CloseWithError(serr)\n\treturn nil\n}\n\n// Ping sends a PING frame to the server and waits for the ack.\nfunc (cc *ClientConn) Ping(ctx context.Context) error {\n\tc := make(chan struct{})\n\t// Generate a random payload\n\tvar p [8]byte\n\tfor {\n\t\tif _, err := rand.Read(p[:]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tcc.mu.Lock()\n\t\t// check for dup before insert\n\t\tif _, found := cc.pings[p]; !found {\n\t\t\tcc.pings[p] = c\n\t\t\tcc.mu.Unlock()\n\t\t\tbreak\n\t\t}\n\t\tcc.mu.Unlock()\n\t}\n\tvar pingError error\n\terrc := make(chan struct{})\n\tgo func() {\n\t\tcc.wmu.Lock()\n\t\tdefer cc.wmu.Unlock()\n\t\tif pingError = cc.fr.WritePing(false, p); pingError != nil {\n\t\t\tclose(errc)\n\t\t\treturn\n\t\t}\n\t\tif pingError = cc.bw.Flush(); pingError != nil {\n\t\t\tclose(errc)\n\t\t\treturn\n\t\t}\n\t}()\n\tselect {\n\tcase <-c:\n\t\treturn nil\n\tcase <-errc:\n\t\treturn pingError\n\tcase <-ctx.Done():\n\t\treturn ctx.Err()\n\tcase <-cc.readerDone:\n\t\t// connection closed\n\t\treturn cc.readerErr\n\t}\n}\n\nfunc (rl *clientConnReadLoop) processPing(f *PingFrame) error {\n\tif f.IsAck() {\n\t\tcc := rl.cc\n\t\tcc.mu.Lock()\n\t\tdefer cc.mu.Unlock()\n\t\t// If ack, notify listener if any\n\t\tif c, ok := cc.pings[f.Data]; ok {\n\t\t\tclose(c)\n\t\t\tdelete(cc.pings, f.Data)\n\t\t}\n\t\tif cc.pendingResets > 0 {\n\t\t\t// See clientStream.cleanupWriteRequest.\n\t\t\tcc.pendingResets = 0\n\t\t\tcc.rstStreamPingsBlocked = true\n\t\t\tcc.cond.Broadcast()\n\t\t}\n\t\treturn nil\n\t}\n\tcc := rl.cc\n\tcc.wmu.Lock()\n\tdefer cc.wmu.Unlock()\n\tif err := cc.fr.WritePing(true, f.Data); err != nil {\n\t\treturn err\n\t}\n\treturn cc.bw.Flush()\n}\n\nfunc (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error {\n\t// We told the peer we don't want them.\n\t// Spec says:\n\t// \"PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH\n\t// setting of the peer endpoint is set to 0. An endpoint that\n\t// has set this setting and has received acknowledgement MUST\n\t// treat the receipt of a PUSH_PROMISE frame as a connection\n\t// error (Section 5.4.1) of type PROTOCOL_ERROR.\"\n\treturn ConnectionError(ErrCodeProtocol)\n}\n\n// writeStreamReset sends a RST_STREAM frame.\n// When ping is true, it also sends a PING frame with a random payload.\nfunc (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, ping bool, err error) {\n\t// TODO: map err to more interesting error codes, once the\n\t// HTTP community comes up with some. But currently for\n\t// RST_STREAM there's no equivalent to GOAWAY frame's debug\n\t// data, and the error codes are all pretty vague (\"cancel\").\n\tcc.wmu.Lock()\n\tcc.fr.WriteRSTStream(streamID, code)\n\tif ping {\n\t\tvar payload [8]byte\n\t\trand.Read(payload[:])\n\t\tcc.fr.WritePing(false, payload)\n\t}\n\tcc.bw.Flush()\n\tcc.wmu.Unlock()\n}\n\nvar (\n\terrResponseHeaderListSize = errors.New(\"http2: response header list larger than advertised limit\")\n\terrRequestHeaderListSize  = httpcommon.ErrRequestHeaderListSize\n)\n\nfunc (cc *ClientConn) logf(format string, args ...interface{}) {\n\tcc.t.logf(format, args...)\n}\n\nfunc (cc *ClientConn) vlogf(format string, args ...interface{}) {\n\tcc.t.vlogf(format, args...)\n}\n\nfunc (t *Transport) vlogf(format string, args ...interface{}) {\n\tif VerboseLogs {\n\t\tt.logf(format, args...)\n\t}\n}\n\nfunc (t *Transport) logf(format string, args ...interface{}) {\n\tlog.Printf(format, args...)\n}\n\nvar noBody io.ReadCloser = noBodyReader{}\n\ntype noBodyReader struct{}\n\nfunc (noBodyReader) Close() error             { return nil }\nfunc (noBodyReader) Read([]byte) (int, error) { return 0, io.EOF }\n\ntype missingBody struct{}\n\nfunc (missingBody) Close() error             { return nil }\nfunc (missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF }\n\nfunc strSliceContains(ss []string, s string) bool {\n\tfor _, v := range ss {\n\t\tif v == s {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype erringRoundTripper struct{ err error }\n\nfunc (rt erringRoundTripper) RoundTripErr() error                             { return rt.err }\nfunc (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err }\n\nvar errConcurrentReadOnResBody = errors.New(\"http2: concurrent read on response body\")\n\n// gzipReader wraps a response body so it can lazily\n// get gzip.Reader from the pool on the first call to Read.\n// After Close is called it puts gzip.Reader to the pool immediately\n// if there is no Read in progress or later when Read completes.\ntype gzipReader struct {\n\t_    incomparable\n\tbody io.ReadCloser // underlying Response.Body\n\tmu   sync.Mutex    // guards zr and zerr\n\tzr   *gzip.Reader  // stores gzip reader from the pool between reads\n\tzerr error         // sticky gzip reader init error or sentinel value to detect concurrent read and read after close\n}\n\ntype eofReader struct{}\n\nfunc (eofReader) Read([]byte) (int, error) { return 0, io.EOF }\nfunc (eofReader) ReadByte() (byte, error)  { return 0, io.EOF }\n\nvar gzipPool = sync.Pool{New: func() any { return new(gzip.Reader) }}\n\n// gzipPoolGet gets a gzip.Reader from the pool and resets it to read from r.\nfunc gzipPoolGet(r io.Reader) (*gzip.Reader, error) {\n\tzr := gzipPool.Get().(*gzip.Reader)\n\tif err := zr.Reset(r); err != nil {\n\t\tgzipPoolPut(zr)\n\t\treturn nil, err\n\t}\n\treturn zr, nil\n}\n\n// gzipPoolPut puts a gzip.Reader back into the pool.\nfunc gzipPoolPut(zr *gzip.Reader) {\n\t// Reset will allocate bufio.Reader if we pass it anything\n\t// other than a flate.Reader, so ensure that it's getting one.\n\tvar r flate.Reader = eofReader{}\n\tzr.Reset(r)\n\tgzipPool.Put(zr)\n}\n\n// acquire returns a gzip.Reader for reading response body.\n// The reader must be released after use.\nfunc (gz *gzipReader) acquire() (*gzip.Reader, error) {\n\tgz.mu.Lock()\n\tdefer gz.mu.Unlock()\n\tif gz.zerr != nil {\n\t\treturn nil, gz.zerr\n\t}\n\tif gz.zr == nil {\n\t\tgz.zr, gz.zerr = gzipPoolGet(gz.body)\n\t\tif gz.zerr != nil {\n\t\t\treturn nil, gz.zerr\n\t\t}\n\t}\n\tret := gz.zr\n\tgz.zr, gz.zerr = nil, errConcurrentReadOnResBody\n\treturn ret, nil\n}\n\n// release returns the gzip.Reader to the pool if Close was called during Read.\nfunc (gz *gzipReader) release(zr *gzip.Reader) {\n\tgz.mu.Lock()\n\tdefer gz.mu.Unlock()\n\tif gz.zerr == errConcurrentReadOnResBody {\n\t\tgz.zr, gz.zerr = zr, nil\n\t} else { // fs.ErrClosed\n\t\tgzipPoolPut(zr)\n\t}\n}\n\n// close returns the gzip.Reader to the pool immediately or\n// signals release to do so after Read completes.\nfunc (gz *gzipReader) close() {\n\tgz.mu.Lock()\n\tdefer gz.mu.Unlock()\n\tif gz.zerr == nil && gz.zr != nil {\n\t\tgzipPoolPut(gz.zr)\n\t\tgz.zr = nil\n\t}\n\tgz.zerr = fs.ErrClosed\n}\n\nfunc (gz *gzipReader) Read(p []byte) (n int, err error) {\n\tzr, err := gz.acquire()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tdefer gz.release(zr)\n\n\treturn zr.Read(p)\n}\n\nfunc (gz *gzipReader) Close() error {\n\tgz.close()\n\n\treturn gz.body.Close()\n}\n\ntype errorReader struct{ err error }\n\nfunc (r errorReader) Read(p []byte) (int, error) { return 0, r.err }\n\n// isConnectionCloseRequest reports whether req should use its own\n// connection for a single request and then close the connection.\nfunc isConnectionCloseRequest(req *http.Request) bool {\n\treturn req.Close || httpguts.HeaderValuesContainsToken(req.Header[\"Connection\"], \"close\")\n}\n\n// registerHTTPSProtocol calls Transport.RegisterProtocol but\n// converting panics into errors.\nfunc registerHTTPSProtocol(t *http.Transport, rt noDialH2RoundTripper) (err error) {\n\tdefer func() {\n\t\tif e := recover(); e != nil {\n\t\t\terr = fmt.Errorf(\"%v\", e)\n\t\t}\n\t}()\n\tt.RegisterProtocol(\"https\", rt)\n\treturn nil\n}\n\n// noDialH2RoundTripper is a RoundTripper which only tries to complete the request\n// if there's already has a cached connection to the host.\n// (The field is exported so it can be accessed via reflect from net/http; tested\n// by TestNoDialH2RoundTripperType)\ntype noDialH2RoundTripper struct{ *Transport }\n\nfunc (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {\n\tres, err := rt.Transport.RoundTrip(req)\n\tif isNoCachedConnError(err) {\n\t\treturn nil, http.ErrSkipAltProtocol\n\t}\n\treturn res, err\n}\n\nfunc (t *Transport) idleConnTimeout() time.Duration {\n\t// to keep things backwards compatible, we use non-zero values of\n\t// IdleConnTimeout, followed by using the IdleConnTimeout on the underlying\n\t// http1 transport, followed by 0\n\tif t.IdleConnTimeout != 0 {\n\t\treturn t.IdleConnTimeout\n\t}\n\n\tif t.t1 != nil {\n\t\treturn t.t1.IdleConnTimeout\n\t}\n\n\treturn 0\n}\n\nfunc traceGetConn(req *http.Request, hostPort string) {\n\ttrace := httptrace.ContextClientTrace(req.Context())\n\tif trace == nil || trace.GetConn == nil {\n\t\treturn\n\t}\n\ttrace.GetConn(hostPort)\n}\n\nfunc traceGotConn(req *http.Request, cc *ClientConn, reused bool) {\n\ttrace := httptrace.ContextClientTrace(req.Context())\n\tif trace == nil || trace.GotConn == nil {\n\t\treturn\n\t}\n\tci := httptrace.GotConnInfo{Conn: cc.tconn}\n\tci.Reused = reused\n\tcc.mu.Lock()\n\tci.WasIdle = len(cc.streams) == 0 && reused\n\tif ci.WasIdle && !cc.lastActive.IsZero() {\n\t\tci.IdleTime = time.Since(cc.lastActive)\n\t}\n\tcc.mu.Unlock()\n\n\ttrace.GotConn(ci)\n}\n\nfunc traceWroteHeaders(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.WroteHeaders != nil {\n\t\ttrace.WroteHeaders()\n\t}\n}\n\nfunc traceGot100Continue(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.Got100Continue != nil {\n\t\ttrace.Got100Continue()\n\t}\n}\n\nfunc traceWait100Continue(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.Wait100Continue != nil {\n\t\ttrace.Wait100Continue()\n\t}\n}\n\nfunc traceWroteRequest(trace *httptrace.ClientTrace, err error) {\n\tif trace != nil && trace.WroteRequest != nil {\n\t\ttrace.WroteRequest(httptrace.WroteRequestInfo{Err: err})\n\t}\n}\n\nfunc traceFirstResponseByte(trace *httptrace.ClientTrace) {\n\tif trace != nil && trace.GotFirstResponseByte != nil {\n\t\ttrace.GotFirstResponseByte()\n\t}\n}\n\nfunc traceGot1xxResponseFunc(trace *httptrace.ClientTrace) func(int, textproto.MIMEHeader) error {\n\tif trace != nil {\n\t\treturn trace.Got1xxResponse\n\t}\n\treturn nil\n}\n\n// dialTLSWithContext uses tls.Dialer, added in Go 1.15, to open a TLS\n// connection.\nfunc (t *Transport) dialTLSWithContext(ctx context.Context, network, addr string, cfg *tls.Config) (*tls.Conn, error) {\n\tdialer := &tls.Dialer{\n\t\tConfig: cfg,\n\t}\n\tcn, err := dialer.DialContext(ctx, network, addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\ttlsCn := cn.(*tls.Conn) // DialContext comment promises this will always succeed\n\treturn tlsCn, nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/unencrypted.go",
    "content": "// Copyright 2024 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 http2\n\nimport (\n\t\"crypto/tls\"\n\t\"errors\"\n\t\"net\"\n)\n\nconst nextProtoUnencryptedHTTP2 = \"unencrypted_http2\"\n\n// unencryptedNetConnFromTLSConn retrieves a net.Conn wrapped in a *tls.Conn.\n//\n// TLSNextProto functions accept a *tls.Conn.\n//\n// When passing an unencrypted HTTP/2 connection to a TLSNextProto function,\n// we pass a *tls.Conn with an underlying net.Conn containing the unencrypted connection.\n// To be extra careful about mistakes (accidentally dropping TLS encryption in a place\n// where we want it), the tls.Conn contains a net.Conn with an UnencryptedNetConn method\n// that returns the actual connection we want to use.\nfunc unencryptedNetConnFromTLSConn(tc *tls.Conn) (net.Conn, error) {\n\tconner, ok := tc.NetConn().(interface {\n\t\tUnencryptedNetConn() net.Conn\n\t})\n\tif !ok {\n\t\treturn nil, errors.New(\"http2: TLS conn unexpectedly found in unencrypted handoff\")\n\t}\n\treturn conner.UnencryptedNetConn(), nil\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/writesched_random.go",
    "content": "// Copyright 2014 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 http2\n\nimport \"math\"\n\n// NewRandomWriteScheduler constructs a WriteScheduler that ignores HTTP/2\n// priorities. Control frames like SETTINGS and PING are written before DATA\n// frames, but if no control frames are queued and multiple streams have queued\n// HEADERS or DATA frames, Pop selects a ready stream arbitrarily.\nfunc NewRandomWriteScheduler() WriteScheduler {\n\treturn &randomWriteScheduler{sq: make(map[uint32]*writeQueue)}\n}\n\ntype randomWriteScheduler struct {\n\t// zero are frames not associated with a specific stream.\n\tzero writeQueue\n\n\t// sq contains the stream-specific queues, keyed by stream ID.\n\t// When a stream is idle, closed, or emptied, it's deleted\n\t// from the map.\n\tsq map[uint32]*writeQueue\n\n\t// pool of empty queues for reuse.\n\tqueuePool writeQueuePool\n}\n\nfunc (ws *randomWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {\n\t// no-op: idle streams are not tracked\n}\n\nfunc (ws *randomWriteScheduler) CloseStream(streamID uint32) {\n\tq, ok := ws.sq[streamID]\n\tif !ok {\n\t\treturn\n\t}\n\tdelete(ws.sq, streamID)\n\tws.queuePool.put(q)\n}\n\nfunc (ws *randomWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {\n\t// no-op: priorities are ignored\n}\n\nfunc (ws *randomWriteScheduler) Push(wr FrameWriteRequest) {\n\tif wr.isControl() {\n\t\tws.zero.push(wr)\n\t\treturn\n\t}\n\tid := wr.StreamID()\n\tq, ok := ws.sq[id]\n\tif !ok {\n\t\tq = ws.queuePool.get()\n\t\tws.sq[id] = q\n\t}\n\tq.push(wr)\n}\n\nfunc (ws *randomWriteScheduler) Pop() (FrameWriteRequest, bool) {\n\t// Control and RST_STREAM frames first.\n\tif !ws.zero.empty() {\n\t\treturn ws.zero.shift(), true\n\t}\n\t// Iterate over all non-idle streams until finding one that can be consumed.\n\tfor streamID, q := range ws.sq {\n\t\tif wr, ok := q.consume(math.MaxInt32); ok {\n\t\t\tif q.empty() {\n\t\t\t\tdelete(ws.sq, streamID)\n\t\t\t\tws.queuePool.put(q)\n\t\t\t}\n\t\t\treturn wr, true\n\t\t}\n\t}\n\treturn FrameWriteRequest{}, false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/http2/writesched_roundrobin.go",
    "content": "// Copyright 2023 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 http2\n\nimport (\n\t\"fmt\"\n\t\"math\"\n)\n\ntype roundRobinWriteScheduler struct {\n\t// control contains control frames (SETTINGS, PING, etc.).\n\tcontrol writeQueue\n\n\t// streams maps stream ID to a queue.\n\tstreams map[uint32]*writeQueue\n\n\t// stream queues are stored in a circular linked list.\n\t// head is the next stream to write, or nil if there are no streams open.\n\thead *writeQueue\n\n\t// pool of empty queues for reuse.\n\tqueuePool writeQueuePool\n}\n\n// newRoundRobinWriteScheduler constructs a new write scheduler.\n// The round robin scheduler prioritizes control frames\n// like SETTINGS and PING over DATA frames.\n// When there are no control frames to send, it performs a round-robin\n// selection from the ready streams.\nfunc newRoundRobinWriteScheduler() WriteScheduler {\n\tws := &roundRobinWriteScheduler{\n\t\tstreams: make(map[uint32]*writeQueue),\n\t}\n\treturn ws\n}\n\nfunc (ws *roundRobinWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {\n\tif ws.streams[streamID] != nil {\n\t\tpanic(fmt.Errorf(\"stream %d already opened\", streamID))\n\t}\n\tq := ws.queuePool.get()\n\tws.streams[streamID] = q\n\tif ws.head == nil {\n\t\tws.head = q\n\t\tq.next = q\n\t\tq.prev = q\n\t} else {\n\t\t// Queues are stored in a ring.\n\t\t// Insert the new stream before ws.head, putting it at the end of the list.\n\t\tq.prev = ws.head.prev\n\t\tq.next = ws.head\n\t\tq.prev.next = q\n\t\tq.next.prev = q\n\t}\n}\n\nfunc (ws *roundRobinWriteScheduler) CloseStream(streamID uint32) {\n\tq := ws.streams[streamID]\n\tif q == nil {\n\t\treturn\n\t}\n\tif q.next == q {\n\t\t// This was the only open stream.\n\t\tws.head = nil\n\t} else {\n\t\tq.prev.next = q.next\n\t\tq.next.prev = q.prev\n\t\tif ws.head == q {\n\t\t\tws.head = q.next\n\t\t}\n\t}\n\tdelete(ws.streams, streamID)\n\tws.queuePool.put(q)\n}\n\nfunc (ws *roundRobinWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {}\n\nfunc (ws *roundRobinWriteScheduler) Push(wr FrameWriteRequest) {\n\tif wr.isControl() {\n\t\tws.control.push(wr)\n\t\treturn\n\t}\n\tq := ws.streams[wr.StreamID()]\n\tif q == nil {\n\t\t// This is a closed stream.\n\t\t// wr should not be a HEADERS or DATA frame.\n\t\t// We push the request onto the control queue.\n\t\tif wr.DataSize() > 0 {\n\t\t\tpanic(\"add DATA on non-open stream\")\n\t\t}\n\t\tws.control.push(wr)\n\t\treturn\n\t}\n\tq.push(wr)\n}\n\nfunc (ws *roundRobinWriteScheduler) Pop() (FrameWriteRequest, bool) {\n\t// Control and RST_STREAM frames first.\n\tif !ws.control.empty() {\n\t\treturn ws.control.shift(), true\n\t}\n\tif ws.head == nil {\n\t\treturn FrameWriteRequest{}, false\n\t}\n\tq := ws.head\n\tfor {\n\t\tif wr, ok := q.consume(math.MaxInt32); ok {\n\t\t\tws.head = q.next\n\t\t\treturn wr, true\n\t\t}\n\t\tq = q.next\n\t\tif q == ws.head {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn FrameWriteRequest{}, false\n}\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables11.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build go1.13 && !go1.14\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"11.0.0\"\n\nvar mappings string = \"\" + // Size: 8175 bytes\n\t\"\\x00\\x01 \\x03 ̈\\x01a\\x03 ̄\\x012\\x013\\x03 ́\\x03 ̧\\x011\\x01o\\x051⁄4\\x051⁄2\" +\n\t\"\\x053⁄4\\x03i̇\\x03l·\\x03ʼn\\x01s\\x03dž\\x03ⱥ\\x03ⱦ\\x01h\\x01j\\x01r\\x01w\\x01y\" +\n\t\"\\x03 ̆\\x03 ̇\\x03 ̊\\x03 ̨\\x03 ̃\\x03 ̋\\x01l\\x01x\\x04̈́\\x03 ι\\x01;\\x05 ̈́\" +\n\t\"\\x04եւ\\x04اٴ\\x04وٴ\\x04ۇٴ\\x04يٴ\\x06क़\\x06ख़\\x06ग़\\x06ज़\\x06ड़\\x06ढ़\\x06फ़\" +\n\t\"\\x06य़\\x06ড়\\x06ঢ়\\x06য়\\x06ਲ਼\\x06ਸ਼\\x06ਖ਼\\x06ਗ਼\\x06ਜ਼\\x06ਫ਼\\x06ଡ଼\\x06ଢ଼\" +\n\t\"\\x06ํา\\x06ໍາ\\x06ຫນ\\x06ຫມ\\x06གྷ\\x06ཌྷ\\x06དྷ\\x06བྷ\\x06ཛྷ\\x06ཀྵ\\x06ཱི\\x06ཱུ\" +\n\t\"\\x06ྲྀ\\x09ྲཱྀ\\x06ླྀ\\x09ླཱྀ\\x06ཱྀ\\x06ྒྷ\\x06ྜྷ\\x06ྡྷ\\x06ྦྷ\\x06ྫྷ\\x06ྐྵ\\x02\" +\n\t\"в\\x02д\\x02о\\x02с\\x02т\\x02ъ\\x02ѣ\\x02æ\\x01b\\x01d\\x01e\\x02ǝ\\x01g\\x01i\\x01k\" +\n\t\"\\x01m\\x01n\\x02ȣ\\x01p\\x01t\\x01u\\x02ɐ\\x02ɑ\\x02ə\\x02ɛ\\x02ɜ\\x02ŋ\\x02ɔ\\x02ɯ\" +\n\t\"\\x01v\\x02β\\x02γ\\x02δ\\x02φ\\x02χ\\x02ρ\\x02н\\x02ɒ\\x01c\\x02ɕ\\x02ð\\x01f\\x02ɟ\" +\n\t\"\\x02ɡ\\x02ɥ\\x02ɨ\\x02ɩ\\x02ɪ\\x02ʝ\\x02ɭ\\x02ʟ\\x02ɱ\\x02ɰ\\x02ɲ\\x02ɳ\\x02ɴ\\x02ɵ\" +\n\t\"\\x02ɸ\\x02ʂ\\x02ʃ\\x02ƫ\\x02ʉ\\x02ʊ\\x02ʋ\\x02ʌ\\x01z\\x02ʐ\\x02ʑ\\x02ʒ\\x02θ\\x02ss\" +\n\t\"\\x02ά\\x02έ\\x02ή\\x02ί\\x02ό\\x02ύ\\x02ώ\\x05ἀι\\x05ἁι\\x05ἂι\\x05ἃι\\x05ἄι\\x05ἅι\" +\n\t\"\\x05ἆι\\x05ἇι\\x05ἠι\\x05ἡι\\x05ἢι\\x05ἣι\\x05ἤι\\x05ἥι\\x05ἦι\\x05ἧι\\x05ὠι\\x05ὡι\" +\n\t\"\\x05ὢι\\x05ὣι\\x05ὤι\\x05ὥι\\x05ὦι\\x05ὧι\\x05ὰι\\x04αι\\x04άι\\x05ᾶι\\x02ι\\x05 ̈͂\" +\n\t\"\\x05ὴι\\x04ηι\\x04ήι\\x05ῆι\\x05 ̓̀\\x05 ̓́\\x05 ̓͂\\x02ΐ\\x05 ̔̀\\x05 ̔́\\x05 ̔͂\" +\n\t\"\\x02ΰ\\x05 ̈̀\\x01`\\x05ὼι\\x04ωι\\x04ώι\\x05ῶι\\x06′′\\x09′′′\\x06‵‵\\x09‵‵‵\\x02!\" +\n\t\"!\\x02??\\x02?!\\x02!?\\x0c′′′′\\x010\\x014\\x015\\x016\\x017\\x018\\x019\\x01+\\x01=\" +\n\t\"\\x01(\\x01)\\x02rs\\x02ħ\\x02no\\x01q\\x02sm\\x02tm\\x02ω\\x02å\\x02א\\x02ב\\x02ג\" +\n\t\"\\x02ד\\x02π\\x051⁄7\\x051⁄9\\x061⁄10\\x051⁄3\\x052⁄3\\x051⁄5\\x052⁄5\\x053⁄5\\x054\" +\n\t\"⁄5\\x051⁄6\\x055⁄6\\x051⁄8\\x053⁄8\\x055⁄8\\x057⁄8\\x041⁄\\x02ii\\x02iv\\x02vi\" +\n\t\"\\x04viii\\x02ix\\x02xi\\x050⁄3\\x06∫∫\\x09∫∫∫\\x06∮∮\\x09∮∮∮\\x0210\\x0211\\x0212\" +\n\t\"\\x0213\\x0214\\x0215\\x0216\\x0217\\x0218\\x0219\\x0220\\x04(10)\\x04(11)\\x04(12)\" +\n\t\"\\x04(13)\\x04(14)\\x04(15)\\x04(16)\\x04(17)\\x04(18)\\x04(19)\\x04(20)\\x0c∫∫∫∫\" +\n\t\"\\x02==\\x05⫝̸\\x02ɫ\\x02ɽ\\x02ȿ\\x02ɀ\\x01.\\x04 ゙\\x04 ゚\\x06より\\x06コト\\x05(ᄀ)\\x05\" +\n\t\"(ᄂ)\\x05(ᄃ)\\x05(ᄅ)\\x05(ᄆ)\\x05(ᄇ)\\x05(ᄉ)\\x05(ᄋ)\\x05(ᄌ)\\x05(ᄎ)\\x05(ᄏ)\\x05(ᄐ\" +\n\t\")\\x05(ᄑ)\\x05(ᄒ)\\x05(가)\\x05(나)\\x05(다)\\x05(라)\\x05(마)\\x05(바)\\x05(사)\\x05(아)\" +\n\t\"\\x05(자)\\x05(차)\\x05(카)\\x05(타)\\x05(파)\\x05(하)\\x05(주)\\x08(오전)\\x08(오후)\\x05(一)\" +\n\t\"\\x05(二)\\x05(三)\\x05(四)\\x05(五)\\x05(六)\\x05(七)\\x05(八)\\x05(九)\\x05(十)\\x05(月)\" +\n\t\"\\x05(火)\\x05(水)\\x05(木)\\x05(金)\\x05(土)\\x05(日)\\x05(株)\\x05(有)\\x05(社)\\x05(名)\" +\n\t\"\\x05(特)\\x05(財)\\x05(祝)\\x05(労)\\x05(代)\\x05(呼)\\x05(学)\\x05(監)\\x05(企)\\x05(資)\" +\n\t\"\\x05(協)\\x05(祭)\\x05(休)\\x05(自)\\x05(至)\\x0221\\x0222\\x0223\\x0224\\x0225\\x0226\" +\n\t\"\\x0227\\x0228\\x0229\\x0230\\x0231\\x0232\\x0233\\x0234\\x0235\\x06참고\\x06주의\\x0236\" +\n\t\"\\x0237\\x0238\\x0239\\x0240\\x0241\\x0242\\x0243\\x0244\\x0245\\x0246\\x0247\\x0248\" +\n\t\"\\x0249\\x0250\\x041月\\x042月\\x043月\\x044月\\x045月\\x046月\\x047月\\x048月\\x049月\\x0510\" +\n\t\"月\\x0511月\\x0512月\\x02hg\\x02ev\\x0cアパート\\x0cアルファ\\x0cアンペア\\x09アール\\x0cイニング\\x09\" +\n\t\"インチ\\x09ウォン\\x0fエスクード\\x0cエーカー\\x09オンス\\x09オーム\\x09カイリ\\x0cカラット\\x0cカロリー\\x09ガロ\" +\n\t\"ン\\x09ガンマ\\x06ギガ\\x09ギニー\\x0cキュリー\\x0cギルダー\\x06キロ\\x0fキログラム\\x12キロメートル\\x0fキロワッ\" +\n\t\"ト\\x09グラム\\x0fグラムトン\\x0fクルゼイロ\\x0cクローネ\\x09ケース\\x09コルナ\\x09コーポ\\x0cサイクル\\x0fサンチ\" +\n\t\"ーム\\x0cシリング\\x09センチ\\x09セント\\x09ダース\\x06デシ\\x06ドル\\x06トン\\x06ナノ\\x09ノット\\x09ハイツ\" +\n\t\"\\x0fパーセント\\x09パーツ\\x0cバーレル\\x0fピアストル\\x09ピクル\\x06ピコ\\x06ビル\\x0fファラッド\\x0cフィート\" +\n\t\"\\x0fブッシェル\\x09フラン\\x0fヘクタール\\x06ペソ\\x09ペニヒ\\x09ヘルツ\\x09ペンス\\x09ページ\\x09ベータ\\x0cポイ\" +\n\t\"ント\\x09ボルト\\x06ホン\\x09ポンド\\x09ホール\\x09ホーン\\x0cマイクロ\\x09マイル\\x09マッハ\\x09マルク\\x0fマ\" +\n\t\"ンション\\x0cミクロン\\x06ミリ\\x0fミリバール\\x06メガ\\x0cメガトン\\x0cメートル\\x09ヤード\\x09ヤール\\x09ユアン\" +\n\t\"\\x0cリットル\\x06リラ\\x09ルピー\\x0cルーブル\\x06レム\\x0fレントゲン\\x09ワット\\x040点\\x041点\\x042点\" +\n\t\"\\x043点\\x044点\\x045点\\x046点\\x047点\\x048点\\x049点\\x0510点\\x0511点\\x0512点\\x0513点\" +\n\t\"\\x0514点\\x0515点\\x0516点\\x0517点\\x0518点\\x0519点\\x0520点\\x0521点\\x0522点\\x0523点\" +\n\t\"\\x0524点\\x02da\\x02au\\x02ov\\x02pc\\x02dm\\x02iu\\x06平成\\x06昭和\\x06大正\\x06明治\\x0c株\" +\n\t\"式会社\\x02pa\\x02na\\x02ma\\x02ka\\x02kb\\x02mb\\x02gb\\x04kcal\\x02pf\\x02nf\\x02m\" +\n\t\"g\\x02kg\\x02hz\\x02ml\\x02dl\\x02kl\\x02fm\\x02nm\\x02mm\\x02cm\\x02km\\x02m2\\x02m\" +\n\t\"3\\x05m∕s\\x06m∕s2\\x07rad∕s\\x08rad∕s2\\x02ps\\x02ns\\x02ms\\x02pv\\x02nv\\x02mv\" +\n\t\"\\x02kv\\x02pw\\x02nw\\x02mw\\x02kw\\x02bq\\x02cc\\x02cd\\x06c∕kg\\x02db\\x02gy\\x02\" +\n\t\"ha\\x02hp\\x02in\\x02kk\\x02kt\\x02lm\\x02ln\\x02lx\\x02ph\\x02pr\\x02sr\\x02sv\\x02\" +\n\t\"wb\\x05v∕m\\x05a∕m\\x041日\\x042日\\x043日\\x044日\\x045日\\x046日\\x047日\\x048日\\x049日\" +\n\t\"\\x0510日\\x0511日\\x0512日\\x0513日\\x0514日\\x0515日\\x0516日\\x0517日\\x0518日\\x0519日\" +\n\t\"\\x0520日\\x0521日\\x0522日\\x0523日\\x0524日\\x0525日\\x0526日\\x0527日\\x0528日\\x0529日\" +\n\t\"\\x0530日\\x0531日\\x02ь\\x02ɦ\\x02ɬ\\x02ʞ\\x02ʇ\\x02œ\\x04𤋮\\x04𢡊\\x04𢡄\\x04𣏕\\x04𥉉\" +\n\t\"\\x04𥳐\\x04𧻓\\x02ff\\x02fi\\x02fl\\x02st\\x04մն\\x04մե\\x04մի\\x04վն\\x04մխ\\x04יִ\" +\n\t\"\\x04ײַ\\x02ע\\x02ה\\x02כ\\x02ל\\x02ם\\x02ר\\x02ת\\x04שׁ\\x04שׂ\\x06שּׁ\\x06שּׂ\\x04א\" +\n\t\"ַ\\x04אָ\\x04אּ\\x04בּ\\x04גּ\\x04דּ\\x04הּ\\x04וּ\\x04זּ\\x04טּ\\x04יּ\\x04ךּ\\x04\" +\n\t\"כּ\\x04לּ\\x04מּ\\x04נּ\\x04סּ\\x04ףּ\\x04פּ\\x04צּ\\x04קּ\\x04רּ\\x04שּ\\x04תּ\" +\n\t\"\\x04וֹ\\x04בֿ\\x04כֿ\\x04פֿ\\x04אל\\x02ٱ\\x02ٻ\\x02پ\\x02ڀ\\x02ٺ\\x02ٿ\\x02ٹ\\x02ڤ\" +\n\t\"\\x02ڦ\\x02ڄ\\x02ڃ\\x02چ\\x02ڇ\\x02ڍ\\x02ڌ\\x02ڎ\\x02ڈ\\x02ژ\\x02ڑ\\x02ک\\x02گ\\x02ڳ\" +\n\t\"\\x02ڱ\\x02ں\\x02ڻ\\x02ۀ\\x02ہ\\x02ھ\\x02ے\\x02ۓ\\x02ڭ\\x02ۇ\\x02ۆ\\x02ۈ\\x02ۋ\\x02ۅ\" +\n\t\"\\x02ۉ\\x02ې\\x02ى\\x04ئا\\x04ئە\\x04ئو\\x04ئۇ\\x04ئۆ\\x04ئۈ\\x04ئې\\x04ئى\\x02ی\\x04\" +\n\t\"ئج\\x04ئح\\x04ئم\\x04ئي\\x04بج\\x04بح\\x04بخ\\x04بم\\x04بى\\x04بي\\x04تج\\x04تح\" +\n\t\"\\x04تخ\\x04تم\\x04تى\\x04تي\\x04ثج\\x04ثم\\x04ثى\\x04ثي\\x04جح\\x04جم\\x04حج\\x04حم\" +\n\t\"\\x04خج\\x04خح\\x04خم\\x04سج\\x04سح\\x04سخ\\x04سم\\x04صح\\x04صم\\x04ضج\\x04ضح\\x04ضخ\" +\n\t\"\\x04ضم\\x04طح\\x04طم\\x04ظم\\x04عج\\x04عم\\x04غج\\x04غم\\x04فج\\x04فح\\x04فخ\\x04فم\" +\n\t\"\\x04فى\\x04في\\x04قح\\x04قم\\x04قى\\x04قي\\x04كا\\x04كج\\x04كح\\x04كخ\\x04كل\\x04كم\" +\n\t\"\\x04كى\\x04كي\\x04لج\\x04لح\\x04لخ\\x04لم\\x04لى\\x04لي\\x04مج\\x04مح\\x04مخ\\x04مم\" +\n\t\"\\x04مى\\x04مي\\x04نج\\x04نح\\x04نخ\\x04نم\\x04نى\\x04ني\\x04هج\\x04هم\\x04هى\\x04هي\" +\n\t\"\\x04يج\\x04يح\\x04يخ\\x04يم\\x04يى\\x04يي\\x04ذٰ\\x04رٰ\\x04ىٰ\\x05 ٌّ\\x05 ٍّ\\x05\" +\n\t\" َّ\\x05 ُّ\\x05 ِّ\\x05 ّٰ\\x04ئر\\x04ئز\\x04ئن\\x04بر\\x04بز\\x04بن\\x04تر\\x04تز\" +\n\t\"\\x04تن\\x04ثر\\x04ثز\\x04ثن\\x04ما\\x04نر\\x04نز\\x04نن\\x04ير\\x04يز\\x04ين\\x04ئخ\" +\n\t\"\\x04ئه\\x04به\\x04ته\\x04صخ\\x04له\\x04نه\\x04هٰ\\x04يه\\x04ثه\\x04سه\\x04شم\\x04شه\" +\n\t\"\\x06ـَّ\\x06ـُّ\\x06ـِّ\\x04طى\\x04طي\\x04عى\\x04عي\\x04غى\\x04غي\\x04سى\\x04سي\" +\n\t\"\\x04شى\\x04شي\\x04حى\\x04حي\\x04جى\\x04جي\\x04خى\\x04خي\\x04صى\\x04صي\\x04ضى\\x04ضي\" +\n\t\"\\x04شج\\x04شح\\x04شخ\\x04شر\\x04سر\\x04صر\\x04ضر\\x04اً\\x06تجم\\x06تحج\\x06تحم\" +\n\t\"\\x06تخم\\x06تمج\\x06تمح\\x06تمخ\\x06جمح\\x06حمي\\x06حمى\\x06سحج\\x06سجح\\x06سجى\" +\n\t\"\\x06سمح\\x06سمج\\x06سمم\\x06صحح\\x06صمم\\x06شحم\\x06شجي\\x06شمخ\\x06شمم\\x06ضحى\" +\n\t\"\\x06ضخم\\x06طمح\\x06طمم\\x06طمي\\x06عجم\\x06عمم\\x06عمى\\x06غمم\\x06غمي\\x06غمى\" +\n\t\"\\x06فخم\\x06قمح\\x06قمم\\x06لحم\\x06لحي\\x06لحى\\x06لجج\\x06لخم\\x06لمح\\x06محج\" +\n\t\"\\x06محم\\x06محي\\x06مجح\\x06مجم\\x06مخج\\x06مخم\\x06مجخ\\x06همج\\x06همم\\x06نحم\" +\n\t\"\\x06نحى\\x06نجم\\x06نجى\\x06نمي\\x06نمى\\x06يمم\\x06بخي\\x06تجي\\x06تجى\\x06تخي\" +\n\t\"\\x06تخى\\x06تمي\\x06تمى\\x06جمي\\x06جحى\\x06جمى\\x06سخى\\x06صحي\\x06شحي\\x06ضحي\" +\n\t\"\\x06لجي\\x06لمي\\x06يحي\\x06يجي\\x06يمي\\x06ممي\\x06قمي\\x06نحي\\x06عمي\\x06كمي\" +\n\t\"\\x06نجح\\x06مخي\\x06لجم\\x06كمم\\x06جحي\\x06حجي\\x06مجي\\x06فمي\\x06بحي\\x06سخي\" +\n\t\"\\x06نجي\\x06صلے\\x06قلے\\x08الله\\x08اكبر\\x08محمد\\x08صلعم\\x08رسول\\x08عليه\" +\n\t\"\\x08وسلم\\x06صلى!صلى الله عليه وسلم\\x0fجل جلاله\\x08ریال\\x01,\\x01:\\x01!\" +\n\t\"\\x01?\\x01_\\x01{\\x01}\\x01[\\x01]\\x01#\\x01&\\x01*\\x01-\\x01<\\x01>\\x01\\\\\\x01$\" +\n\t\"\\x01%\\x01@\\x04ـً\\x04ـَ\\x04ـُ\\x04ـِ\\x04ـّ\\x04ـْ\\x02ء\\x02آ\\x02أ\\x02ؤ\\x02إ\" +\n\t\"\\x02ئ\\x02ا\\x02ب\\x02ة\\x02ت\\x02ث\\x02ج\\x02ح\\x02خ\\x02د\\x02ذ\\x02ر\\x02ز\\x02س\" +\n\t\"\\x02ش\\x02ص\\x02ض\\x02ط\\x02ظ\\x02ع\\x02غ\\x02ف\\x02ق\\x02ك\\x02ل\\x02م\\x02ن\\x02ه\" +\n\t\"\\x02و\\x02ي\\x04لآ\\x04لأ\\x04لإ\\x04لا\\x01\\x22\\x01'\\x01/\\x01^\\x01|\\x01~\\x02¢\" +\n\t\"\\x02£\\x02¬\\x02¦\\x02¥\\x08𝅗𝅥\\x08𝅘𝅥\\x0c𝅘𝅥𝅮\\x0c𝅘𝅥𝅯\\x0c𝅘𝅥𝅰\\x0c𝅘𝅥𝅱\\x0c𝅘𝅥𝅲\\x08𝆹\" +\n\t\"𝅥\\x08𝆺𝅥\\x0c𝆹𝅥𝅮\\x0c𝆺𝅥𝅮\\x0c𝆹𝅥𝅯\\x0c𝆺𝅥𝅯\\x02ı\\x02ȷ\\x02α\\x02ε\\x02ζ\\x02η\\x02\" +\n\t\"κ\\x02λ\\x02μ\\x02ν\\x02ξ\\x02ο\\x02σ\\x02τ\\x02υ\\x02ψ\\x03∇\\x03∂\\x02ϝ\\x02ٮ\\x02ڡ\" +\n\t\"\\x02ٯ\\x020,\\x021,\\x022,\\x023,\\x024,\\x025,\\x026,\\x027,\\x028,\\x029,\\x03(a)\" +\n\t\"\\x03(b)\\x03(c)\\x03(d)\\x03(e)\\x03(f)\\x03(g)\\x03(h)\\x03(i)\\x03(j)\\x03(k)\" +\n\t\"\\x03(l)\\x03(m)\\x03(n)\\x03(o)\\x03(p)\\x03(q)\\x03(r)\\x03(s)\\x03(t)\\x03(u)\" +\n\t\"\\x03(v)\\x03(w)\\x03(x)\\x03(y)\\x03(z)\\x07〔s〕\\x02wz\\x02hv\\x02sd\\x03ppv\\x02w\" +\n\t\"c\\x02mc\\x02md\\x02dj\\x06ほか\\x06ココ\\x03サ\\x03手\\x03字\\x03双\\x03デ\\x03二\\x03多\\x03解\" +\n\t\"\\x03天\\x03交\\x03映\\x03無\\x03料\\x03前\\x03後\\x03再\\x03新\\x03初\\x03終\\x03生\\x03販\\x03声\" +\n\t\"\\x03吹\\x03演\\x03投\\x03捕\\x03一\\x03三\\x03遊\\x03左\\x03中\\x03右\\x03指\\x03走\\x03打\\x03禁\" +\n\t\"\\x03空\\x03合\\x03満\\x03有\\x03月\\x03申\\x03割\\x03営\\x03配\\x09〔本〕\\x09〔三〕\\x09〔二〕\\x09〔安\" +\n\t\"〕\\x09〔点〕\\x09〔打〕\\x09〔盗〕\\x09〔勝〕\\x09〔敗〕\\x03得\\x03可\\x03丽\\x03丸\\x03乁\\x03你\\x03\" +\n\t\"侮\\x03侻\\x03倂\\x03偺\\x03備\\x03僧\\x03像\\x03㒞\\x03免\\x03兔\\x03兤\\x03具\\x03㒹\\x03內\\x03\" +\n\t\"冗\\x03冤\\x03仌\\x03冬\\x03况\\x03凵\\x03刃\\x03㓟\\x03刻\\x03剆\\x03剷\\x03㔕\\x03勇\\x03勉\\x03\" +\n\t\"勤\\x03勺\\x03包\\x03匆\\x03北\\x03卉\\x03卑\\x03博\\x03即\\x03卽\\x03卿\\x03灰\\x03及\\x03叟\\x03\" +\n\t\"叫\\x03叱\\x03吆\\x03咞\\x03吸\\x03呈\\x03周\\x03咢\\x03哶\\x03唐\\x03啓\\x03啣\\x03善\\x03喙\\x03\" +\n\t\"喫\\x03喳\\x03嗂\\x03圖\\x03嘆\\x03圗\\x03噑\\x03噴\\x03切\\x03壮\\x03城\\x03埴\\x03堍\\x03型\\x03\" +\n\t\"堲\\x03報\\x03墬\\x03売\\x03壷\\x03夆\\x03夢\\x03奢\\x03姬\\x03娛\\x03娧\\x03姘\\x03婦\\x03㛮\\x03\" +\n\t\"嬈\\x03嬾\\x03寃\\x03寘\\x03寧\\x03寳\\x03寿\\x03将\\x03尢\\x03㞁\\x03屠\\x03屮\\x03峀\\x03岍\\x03\" +\n\t\"嵃\\x03嵮\\x03嵫\\x03嵼\\x03巡\\x03巢\\x03㠯\\x03巽\\x03帨\\x03帽\\x03幩\\x03㡢\\x03㡼\\x03庰\\x03\" +\n\t\"庳\\x03庶\\x03廊\\x03廾\\x03舁\\x03弢\\x03㣇\\x03形\\x03彫\\x03㣣\\x03徚\\x03忍\\x03志\\x03忹\\x03\" +\n\t\"悁\\x03㤺\\x03㤜\\x03悔\\x03惇\\x03慈\\x03慌\\x03慎\\x03慺\\x03憎\\x03憲\\x03憤\\x03憯\\x03懞\\x03\" +\n\t\"懲\\x03懶\\x03成\\x03戛\\x03扝\\x03抱\\x03拔\\x03捐\\x03挽\\x03拼\\x03捨\\x03掃\\x03揤\\x03搢\\x03\" +\n\t\"揅\\x03掩\\x03㨮\\x03摩\\x03摾\\x03撝\\x03摷\\x03㩬\\x03敏\\x03敬\\x03旣\\x03書\\x03晉\\x03㬙\\x03\" +\n\t\"暑\\x03㬈\\x03㫤\\x03冒\\x03冕\\x03最\\x03暜\\x03肭\\x03䏙\\x03朗\\x03望\\x03朡\\x03杞\\x03杓\\x03\" +\n\t\"㭉\\x03柺\\x03枅\\x03桒\\x03梅\\x03梎\\x03栟\\x03椔\\x03㮝\\x03楂\\x03榣\\x03槪\\x03檨\\x03櫛\\x03\" +\n\t\"㰘\\x03次\\x03歔\\x03㱎\\x03歲\\x03殟\\x03殺\\x03殻\\x03汎\\x03沿\\x03泍\\x03汧\\x03洖\\x03派\\x03\" +\n\t\"海\\x03流\\x03浩\\x03浸\\x03涅\\x03洴\\x03港\\x03湮\\x03㴳\\x03滋\\x03滇\\x03淹\\x03潮\\x03濆\\x03\" +\n\t\"瀹\\x03瀞\\x03瀛\\x03㶖\\x03灊\\x03災\\x03灷\\x03炭\\x03煅\\x03熜\\x03爨\\x03爵\\x03牐\\x03犀\\x03\" +\n\t\"犕\\x03獺\\x03王\\x03㺬\\x03玥\\x03㺸\\x03瑇\\x03瑜\\x03瑱\\x03璅\\x03瓊\\x03㼛\\x03甤\\x03甾\\x03\" +\n\t\"異\\x03瘐\\x03㿼\\x03䀈\\x03直\\x03眞\\x03真\\x03睊\\x03䀹\\x03瞋\\x03䁆\\x03䂖\\x03硎\\x03碌\\x03\" +\n\t\"磌\\x03䃣\\x03祖\\x03福\\x03秫\\x03䄯\\x03穀\\x03穊\\x03穏\\x03䈂\\x03篆\\x03築\\x03䈧\\x03糒\\x03\" +\n\t\"䊠\\x03糨\\x03糣\\x03紀\\x03絣\\x03䌁\\x03緇\\x03縂\\x03繅\\x03䌴\\x03䍙\\x03罺\\x03羕\\x03翺\\x03\" +\n\t\"者\\x03聠\\x03聰\\x03䏕\\x03育\\x03脃\\x03䐋\\x03脾\\x03媵\\x03舄\\x03辞\\x03䑫\\x03芑\\x03芋\\x03\" +\n\t\"芝\\x03劳\\x03花\\x03芳\\x03芽\\x03苦\\x03若\\x03茝\\x03荣\\x03莭\\x03茣\\x03莽\\x03菧\\x03著\\x03\" +\n\t\"荓\\x03菊\\x03菌\\x03菜\\x03䔫\\x03蓱\\x03蓳\\x03蔖\\x03蕤\\x03䕝\\x03䕡\\x03䕫\\x03虐\\x03虜\\x03\" +\n\t\"虧\\x03虩\\x03蚩\\x03蚈\\x03蜎\\x03蛢\\x03蝹\\x03蜨\\x03蝫\\x03螆\\x03蟡\\x03蠁\\x03䗹\\x03衠\\x03\" +\n\t\"衣\\x03裗\\x03裞\\x03䘵\\x03裺\\x03㒻\\x03䚾\\x03䛇\\x03誠\\x03諭\\x03變\\x03豕\\x03貫\\x03賁\\x03\" +\n\t\"贛\\x03起\\x03跋\\x03趼\\x03跰\\x03軔\\x03輸\\x03邔\\x03郱\\x03鄑\\x03鄛\\x03鈸\\x03鋗\\x03鋘\\x03\" +\n\t\"鉼\\x03鏹\\x03鐕\\x03開\\x03䦕\\x03閷\\x03䧦\\x03雃\\x03嶲\\x03霣\\x03䩮\\x03䩶\\x03韠\\x03䪲\\x03\" +\n\t\"頋\\x03頩\\x03飢\\x03䬳\\x03餩\\x03馧\\x03駂\\x03駾\\x03䯎\\x03鬒\\x03鱀\\x03鳽\\x03䳎\\x03䳭\\x03\" +\n\t\"鵧\\x03䳸\\x03麻\\x03䵖\\x03黹\\x03黾\\x03鼅\\x03鼏\\x03鼖\\x03鼻\"\n\nvar xorData string = \"\" + // Size: 4855 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\\x03\\x1c\\x02\" +\n\t\"\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\\xc1r\\x02\" +\n\t\"\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\\x03\\xc1s*\" +\n\t\"\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\\x83\\xab\" +\n\t\"\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\\xe1\\xcd\" +\n\t\"\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\\x9a\\xec\" +\n\t\"\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c!\\x03\" +\n\t\"\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03ʦ\\x93\" +\n\t\"\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\\x03\" +\n\t\"\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\\xfa\" +\n\t\"\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\\x03\" +\n\t\"\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\\xe3\" +\n\t\"\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\\x03\" +\n\t\"\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\\xe8\" +\n\t\"\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\\x0b\" +\n\t\"\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\\x05\" +\n\t\"\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\\x0786\" +\n\t\"\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\\x03\" +\n\t\"\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\\x03\" +\n\t\"\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\\x03\" +\n\t\"\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\\x07\" +\n\t\"\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\\x07\" +\n\t\"\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\\x07\" +\n\t\"\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\\x0a\" +\n\t\"\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\\x07\" +\n\t\"\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\\x03\" +\n\t\"\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\\x04\" +\n\t\"4\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\\x04+ \" +\n\t\"\\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\\x22\" +\n\t\"\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\\x03\" +\n\t\"\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\\x03\" +\n\t\"\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\\x054\" +\n\t\"\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\\x05)\" +\n\t\":\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\\x1e\" +\n\t\"\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\\x03\" +\n\t\"\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\\x1b\" +\n\t\"\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\\x03\" +\n\t\"\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\\x06\" +\n\t\"\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\\x03\" +\n\t\"\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\\x0a6\" +\n\t\"\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\\x1f\" +\n\t\"\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\\x0a\" +\n\t\"\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\\x02\" +\n\t\"\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\\x03\" +\n\t\"\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\\x00\" +\n\t\"\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\\x10\" +\n\t\"\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#<\" +\n\t\"\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\\x00\" +\n\t\"\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\\x03\" +\n\t\"\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\\x22\" +\n\t\"\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\\x12\" +\n\t\"\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05<\" +\n\t\"\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\\x10\\x03\\x0b!0\" +\n\t\"\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\\x03\\x09\\x1f\" +\n\t\"\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\\x03\\x0a\\x01\" +\n\t\"\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\\x08='\\x03\" +\n\t\"\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\\x09\\x0c\" +\n\t\"\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06!3\\x03\" +\n\t\"\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\\x03\\x07\" +\n\t\"<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\\x01\\x00\" +\n\t\"\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\\x09\\x11\" +\n\t\"\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\\x0a/1\" +\n\t\"\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\\x07<3\" +\n\t\"\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\\x13\\x00\" +\n\t\"\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(;\\x03\" +\n\t\"\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\\x14$\" +\n\t\"\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\\x0a\" +\n\t\"\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\\x01\" +\n\t\"\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\\x03\" +\n\t\"\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\\x07\" +\n\t\"\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\\x0a\" +\n\t\"\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\\x0b\" +\n\t\"\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\\x08\" +\n\t\"\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\\x03\" +\n\t\"\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\\x03\" +\n\t\"\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\\x09\" +\n\t\"\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a.\" +\n\t\"\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x01\\x1e\\x03\\x0f$!\\x03\" +\n\t\"\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\\x18\\x03\\x0f\" +\n\t\"\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\\x03\\x0e\\x0d)\" +\n\t\"\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\\x03\\x0d. \\x03\" +\n\t\"\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\\x0d\\x0d\\x0f\\x03\" +\n\t\"\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\\x0c\\x09:\\x03\\x0e\" +\n\t\"\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\\x03\\x0c\\x1f\\x1c\" +\n\t\"\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\\x0b<+\\x03\\x0b8\" +\n\t\"\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\\x22&\\x03\\x0b\\x1a\" +\n\t\"\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\\x0a!\\x1a\\x03\\x0a!\" +\n\t\"7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\\x0a\\x00 \\x03\\x0a\" +\n\t\"\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\\x1b-\\x03\\x09-\" +\n\t\"\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\\x1f\\x03\\x093\" +\n\t\"\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\\x16\\x03\\x09\" +\n\t\"\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\\x03\\x09\\x1a\" +\n\t\"\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\\x08\\x02*\" +\n\t\"\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\\x070\\x0c\" +\n\t\"\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x0671\\x03\" +\n\t\"\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \\x1d\\x03\" +\n\t\"\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 29404 bytes (28.71 KiB). Checksum: 848c45acb5f7991c.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 125:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 125\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 127 blocks, 8128 entries, 16256 bytes\n// The third block is the zero block.\nvar idnaValues = [8128]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,\n\t0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,\n\t0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,\n\t0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,\n\t0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,\n\t0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,\n\t0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,\n\t0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808,\n\t0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,\n\t0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,\n\t0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,\n\t0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,\n\t0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,\n\t0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,\n\t0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,\n\t0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,\n\t0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,\n\t0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,\n\t0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1,\n\t0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,\n\t0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,\n\t0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,\n\t0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,\n\t0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,\n\t0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,\n\t0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,\n\t0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,\n\t0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,\n\t0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,\n\t0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,\n\t0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,\n\t0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,\n\t0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,\n\t0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,\n\t0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,\n\t0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1,\n\t0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,\n\t0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,\n\t0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,\n\t0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,\n\t0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,\n\t0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,\n\t0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,\n\t0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,\n\t0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,\n\t0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008,\n\t0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,\n\t0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,\n\t0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,\n\t0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,\n\t0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,\n\t0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040,\n\t0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,\n\t0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,\n\t0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,\n\t0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,\n\t0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,\n\t0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,\n\t0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,\n\t0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,\n\t0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,\n\t0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,\n\t0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,\n\t0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,\n\t0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,\n\t0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,\n\t0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,\n\t0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,\n\t0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,\n\t0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,\n\t0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,\n\t0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,\n\t0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,\n\t0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,\n\t0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,\n\t0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,\n\t0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,\n\t0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,\n\t0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,\n\t0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008,\n\t0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9,\n\t0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,\n\t0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,\n\t0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,\n\t0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,\n\t0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,\n\t0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,\n\t0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,\n\t0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,\n\t0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,\n\t0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,\n\t0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,\n\t0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,\n\t0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,\n\t0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,\n\t0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,\n\t0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,\n\t0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,\n\t0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,\n\t0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,\n\t0x836: 0x0040, 0x837: 0x0040, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,\n\t0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008,\n\t0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,\n\t0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,\n\t0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,\n\t0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,\n\t0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,\n\t0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,\n\t0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,\n\t0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,\n\t0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,\n\t0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,\n\t0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,\n\t0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,\n\t0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,\n\t0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,\n\t0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,\n\t0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,\n\t0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,\n\t0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,\n\t0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,\n\t0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,\n\t0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,\n\t0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,\n\t0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,\n\t0x906: 0x0040, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0040, 0x90a: 0x0008, 0x90b: 0x0040,\n\t0x90c: 0x0040, 0x90d: 0x0008, 0x90e: 0x0040, 0x90f: 0x0040, 0x910: 0x0040, 0x911: 0x0040,\n\t0x912: 0x0040, 0x913: 0x0040, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,\n\t0x918: 0x0040, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,\n\t0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0040, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,\n\t0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0040, 0x929: 0x0040,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0040, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,\n\t0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308,\n\t0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x0040, 0x93b: 0x3308,\n\t0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008,\n\t0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,\n\t0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,\n\t0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79,\n\t0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008,\n\t0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,\n\t0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9,\n\t0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,\n\t0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59,\n\t0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,\n\t0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,\n\t0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,\n\t0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11,\n\t0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308,\n\t0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308,\n\t0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,\n\t0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,\n\t0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308,\n\t0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,\n\t0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,\n\t0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,\n\t0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,\n\t0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,\n\t0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,\n\t0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,\n\t0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008,\n\t0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41,\n\t0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008,\n\t0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1,\n\t0xa06: 0x059d, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011,\n\t0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041,\n\t0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05b5, 0xa15: 0x05b5, 0xa16: 0x0f99, 0xa17: 0x0fa9,\n\t0xa18: 0x0fb9, 0xa19: 0x059d, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05cd, 0xa1d: 0x1099,\n\t0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269,\n\t0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1,\n\t0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,\n\t0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,\n\t0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,\n\t0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,\n\t0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,\n\t0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,\n\t0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,\n\t0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169,\n\t0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9,\n\t0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05e5, 0xa68: 0x1239, 0xa69: 0x1251,\n\t0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9,\n\t0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359,\n\t0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x05fd, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1,\n\t0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,\n\t0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,\n\t0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,\n\t0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,\n\t0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,\n\t0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,\n\t0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,\n\t0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,\n\t0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,\n\t0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,\n\t0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,\n\t0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,\n\t0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,\n\t0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,\n\t0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x0615, 0xadb: 0x0635, 0xadc: 0x0008, 0xadd: 0x0008,\n\t0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,\n\t0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,\n\t0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,\n\t0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,\n\t0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,\n\t0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,\n\t0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,\n\t0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,\n\t0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,\n\t0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,\n\t0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,\n\t0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,\n\t0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,\n\t0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489,\n\t0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1,\n\t0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1,\n\t0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591,\n\t0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1,\n\t0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1,\n\t0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771,\n\t0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891,\n\t0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831,\n\t0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951,\n\t0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040,\n\t0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x064d, 0xb7b: 0x1459,\n\t0xb7c: 0x19b1, 0xb7d: 0x0666, 0xb7e: 0x1a31, 0xb7f: 0x0686,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x06a6, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040,\n\t0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06c5, 0xb89: 0x1471, 0xb8a: 0x06dd, 0xb8b: 0x1489,\n\t0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008,\n\t0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,\n\t0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x06f5, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2,\n\t0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61,\n\t0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,\n\t0xbaa: 0x070d, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa,\n\t0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040,\n\t0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x0725, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9,\n\t0xbbc: 0x1ce9, 0xbbd: 0x073e, 0xbbe: 0x075e, 0xbbf: 0x0040,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,\n\t0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,\n\t0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,\n\t0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x077e,\n\t0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,\n\t0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,\n\t0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,\n\t0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,\n\t0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018,\n\t0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,\n\t0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x079e, 0xbff: 0x0018,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,\n\t0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018,\n\t0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,\n\t0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9,\n\t0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,\n\t0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,\n\t0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,\n\t0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,\n\t0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61,\n\t0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07bd,\n\t0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61,\n\t0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07d5,\n\t0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09,\n\t0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359,\n\t0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040,\n\t0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,\n\t0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018,\n\t0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,\n\t0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,\n\t0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,\n\t0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x07ee, 0xc81: 0x080e, 0xc82: 0x1159, 0xc83: 0x082d, 0xc84: 0x0018, 0xc85: 0x084e,\n\t0xc86: 0x086e, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x088d, 0xc8a: 0x0f31, 0xc8b: 0x0249,\n\t0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41,\n\t0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018,\n\t0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269,\n\t0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08ad, 0xca2: 0x2061, 0xca3: 0x0018,\n\t0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018,\n\t0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09,\n\t0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9,\n\t0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08cd,\n\t0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x08ed, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9,\n\t0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018,\n\t0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151,\n\t0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279,\n\t0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399,\n\t0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x0905, 0xce3: 0x2439,\n\t0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x0925, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369,\n\t0xcea: 0x24a9, 0xceb: 0x0945, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61,\n\t0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x0965, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451,\n\t0xcf6: 0x0985, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09a5,\n\t0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,\n\t0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,\n\t0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,\n\t0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,\n\t0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,\n\t0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51,\n\t0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601,\n\t0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691,\n\t0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a06, 0xd35: 0x0a26,\n\t0xd36: 0x0a46, 0xd37: 0x0a66, 0xd38: 0x0a86, 0xd39: 0x0aa6, 0xd3a: 0x0ac6, 0xd3b: 0x0ae6,\n\t0xd3c: 0x0b06, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a,\n\t0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,\n\t0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,\n\t0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,\n\t0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b26, 0xd5d: 0x0b46,\n\t0xd5e: 0x0b66, 0xd5f: 0x0b86, 0xd60: 0x0ba6, 0xd61: 0x0bc6, 0xd62: 0x0be6, 0xd63: 0x0c06,\n\t0xd64: 0x0c26, 0xd65: 0x0c46, 0xd66: 0x0c66, 0xd67: 0x0c86, 0xd68: 0x0ca6, 0xd69: 0x0cc6,\n\t0xd6a: 0x0ce6, 0xd6b: 0x0d06, 0xd6c: 0x0d26, 0xd6d: 0x0d46, 0xd6e: 0x0d66, 0xd6f: 0x0d86,\n\t0xd70: 0x0da6, 0xd71: 0x0dc6, 0xd72: 0x0de6, 0xd73: 0x0e06, 0xd74: 0x0e26, 0xd75: 0x0e46,\n\t0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199,\n\t0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99,\n\t0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089,\n\t0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9,\n\t0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249,\n\t0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71,\n\t0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9,\n\t0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1,\n\t0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,\n\t0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,\n\t0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,\n\t0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,\n\t0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,\n\t0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,\n\t0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,\n\t0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,\n\t0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ebd,\n\t0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,\n\t0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9,\n\t0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,\n\t0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,\n\t0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,\n\t0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,\n\t0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,\n\t0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,\n\t0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,\n\t0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,\n\t0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,\n\t0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,\n\t0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,\n\t0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,\n\t0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0x26fd, 0xe41: 0x271d, 0xe42: 0x273d, 0xe43: 0x275d, 0xe44: 0x277d, 0xe45: 0x279d,\n\t0xe46: 0x27bd, 0xe47: 0x27dd, 0xe48: 0x27fd, 0xe49: 0x281d, 0xe4a: 0x283d, 0xe4b: 0x285d,\n\t0xe4c: 0x287d, 0xe4d: 0x289d, 0xe4e: 0x28bd, 0xe4f: 0x28dd, 0xe50: 0x28fd, 0xe51: 0x291d,\n\t0xe52: 0x293d, 0xe53: 0x295d, 0xe54: 0x297d, 0xe55: 0x299d, 0xe56: 0x0040, 0xe57: 0x0040,\n\t0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,\n\t0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,\n\t0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,\n\t0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,\n\t0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,\n\t0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,\n\t0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,\n\t0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,\n\t0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,\n\t0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,\n\t0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,\n\t0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,\n\t0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,\n\t0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,\n\t0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,\n\t0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29bd, 0xeb9: 0x29dd, 0xeba: 0x29fd, 0xebb: 0x0018,\n\t0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x2b3d, 0xec1: 0x2b5d, 0xec2: 0x2b7d, 0xec3: 0x2b9d, 0xec4: 0x2bbd, 0xec5: 0x2bdd,\n\t0xec6: 0x2bdd, 0xec7: 0x2bdd, 0xec8: 0x2bfd, 0xec9: 0x2bfd, 0xeca: 0x2bfd, 0xecb: 0x2bfd,\n\t0xecc: 0x2c1d, 0xecd: 0x2c1d, 0xece: 0x2c1d, 0xecf: 0x2c3d, 0xed0: 0x2c5d, 0xed1: 0x2c5d,\n\t0xed2: 0x2a7d, 0xed3: 0x2a7d, 0xed4: 0x2c5d, 0xed5: 0x2c5d, 0xed6: 0x2c7d, 0xed7: 0x2c7d,\n\t0xed8: 0x2c5d, 0xed9: 0x2c5d, 0xeda: 0x2a7d, 0xedb: 0x2a7d, 0xedc: 0x2c5d, 0xedd: 0x2c5d,\n\t0xede: 0x2c3d, 0xedf: 0x2c3d, 0xee0: 0x2c9d, 0xee1: 0x2c9d, 0xee2: 0x2cbd, 0xee3: 0x2cbd,\n\t0xee4: 0x0040, 0xee5: 0x2cdd, 0xee6: 0x2cfd, 0xee7: 0x2d1d, 0xee8: 0x2d1d, 0xee9: 0x2d3d,\n\t0xeea: 0x2d5d, 0xeeb: 0x2d7d, 0xeec: 0x2d9d, 0xeed: 0x2dbd, 0xeee: 0x2ddd, 0xeef: 0x2dfd,\n\t0xef0: 0x2e1d, 0xef1: 0x2e3d, 0xef2: 0x2e3d, 0xef3: 0x2e5d, 0xef4: 0x2e7d, 0xef5: 0x2e7d,\n\t0xef6: 0x2e9d, 0xef7: 0x2ebd, 0xef8: 0x2e5d, 0xef9: 0x2edd, 0xefa: 0x2efd, 0xefb: 0x2edd,\n\t0xefc: 0x2e5d, 0xefd: 0x2f1d, 0xefe: 0x2f3d, 0xeff: 0x2f5d,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x2f7d, 0xf01: 0x2f9d, 0xf02: 0x2cfd, 0xf03: 0x2cdd, 0xf04: 0x2fbd, 0xf05: 0x2fdd,\n\t0xf06: 0x2ffd, 0xf07: 0x301d, 0xf08: 0x303d, 0xf09: 0x305d, 0xf0a: 0x307d, 0xf0b: 0x309d,\n\t0xf0c: 0x30bd, 0xf0d: 0x30dd, 0xf0e: 0x30fd, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,\n\t0xf12: 0x311d, 0xf13: 0x313d, 0xf14: 0x315d, 0xf15: 0x317d, 0xf16: 0x319d, 0xf17: 0x31bd,\n\t0xf18: 0x31dd, 0xf19: 0x31fd, 0xf1a: 0x321d, 0xf1b: 0x323d, 0xf1c: 0x315d, 0xf1d: 0x325d,\n\t0xf1e: 0x327d, 0xf1f: 0x329d, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,\n\t0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,\n\t0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,\n\t0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,\n\t0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040,\n\t0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32bd, 0xf45: 0x32dd,\n\t0xf46: 0x32fd, 0xf47: 0x331d, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,\n\t0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x333d, 0xf51: 0x3761,\n\t0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1,\n\t0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881,\n\t0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x335d, 0xf61: 0x337d, 0xf62: 0x339d, 0xf63: 0x33bd,\n\t0xf64: 0x33dd, 0xf65: 0x33dd, 0xf66: 0x33fd, 0xf67: 0x341d, 0xf68: 0x343d, 0xf69: 0x345d,\n\t0xf6a: 0x347d, 0xf6b: 0x349d, 0xf6c: 0x34bd, 0xf6d: 0x34dd, 0xf6e: 0x34fd, 0xf6f: 0x351d,\n\t0xf70: 0x353d, 0xf71: 0x355d, 0xf72: 0x357d, 0xf73: 0x359d, 0xf74: 0x35bd, 0xf75: 0x35dd,\n\t0xf76: 0x35fd, 0xf77: 0x361d, 0xf78: 0x363d, 0xf79: 0x365d, 0xf7a: 0x367d, 0xf7b: 0x369d,\n\t0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36bd, 0xf7f: 0x0018,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x36dd, 0xf81: 0x36fd, 0xf82: 0x371d, 0xf83: 0x373d, 0xf84: 0x375d, 0xf85: 0x377d,\n\t0xf86: 0x379d, 0xf87: 0x37bd, 0xf88: 0x37dd, 0xf89: 0x37fd, 0xf8a: 0x381d, 0xf8b: 0x383d,\n\t0xf8c: 0x385d, 0xf8d: 0x387d, 0xf8e: 0x389d, 0xf8f: 0x38bd, 0xf90: 0x38dd, 0xf91: 0x38fd,\n\t0xf92: 0x391d, 0xf93: 0x393d, 0xf94: 0x395d, 0xf95: 0x397d, 0xf96: 0x399d, 0xf97: 0x39bd,\n\t0xf98: 0x39dd, 0xf99: 0x39fd, 0xf9a: 0x3a1d, 0xf9b: 0x3a3d, 0xf9c: 0x3a5d, 0xf9d: 0x3a7d,\n\t0xf9e: 0x3a9d, 0xf9f: 0x3abd, 0xfa0: 0x3add, 0xfa1: 0x3afd, 0xfa2: 0x3b1d, 0xfa3: 0x3b3d,\n\t0xfa4: 0x3b5d, 0xfa5: 0x3b7d, 0xfa6: 0x127d, 0xfa7: 0x3b9d, 0xfa8: 0x3bbd, 0xfa9: 0x3bdd,\n\t0xfaa: 0x3bfd, 0xfab: 0x3c1d, 0xfac: 0x3c3d, 0xfad: 0x3c5d, 0xfae: 0x239d, 0xfaf: 0x3c7d,\n\t0xfb0: 0x3c9d, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999,\n\t0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29,\n\t0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69,\n\t0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69,\n\t0xfcc: 0x3c99, 0xfcd: 0x3cbd, 0xfce: 0x3cb1, 0xfcf: 0x3cdd, 0xfd0: 0x3cfd, 0xfd1: 0x3d15,\n\t0xfd2: 0x3d2d, 0xfd3: 0x3d45, 0xfd4: 0x3d5d, 0xfd5: 0x3d5d, 0xfd6: 0x3d45, 0xfd7: 0x3d75,\n\t0xfd8: 0x07bd, 0xfd9: 0x3d8d, 0xfda: 0x3da5, 0xfdb: 0x3dbd, 0xfdc: 0x3dd5, 0xfdd: 0x3ded,\n\t0xfde: 0x3e05, 0xfdf: 0x3e1d, 0xfe0: 0x3e35, 0xfe1: 0x3e4d, 0xfe2: 0x3e65, 0xfe3: 0x3e7d,\n\t0xfe4: 0x3e95, 0xfe5: 0x3e95, 0xfe6: 0x3ead, 0xfe7: 0x3ead, 0xfe8: 0x3ec5, 0xfe9: 0x3ec5,\n\t0xfea: 0x3edd, 0xfeb: 0x3ef5, 0xfec: 0x3f0d, 0xfed: 0x3f25, 0xfee: 0x3f3d, 0xfef: 0x3f3d,\n\t0xff0: 0x3f55, 0xff1: 0x3f55, 0xff2: 0x3f55, 0xff3: 0x3f6d, 0xff4: 0x3f85, 0xff5: 0x3f9d,\n\t0xff6: 0x3fb5, 0xff7: 0x3f9d, 0xff8: 0x3fcd, 0xff9: 0x3fe5, 0xffa: 0x3f6d, 0xffb: 0x3ffd,\n\t0xffc: 0x4015, 0xffd: 0x4015, 0xffe: 0x4015, 0xfff: 0x0040,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9,\n\t0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1,\n\t0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9,\n\t0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549,\n\t0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1,\n\t0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11,\n\t0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91,\n\t0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9,\n\t0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011,\n\t0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209,\n\t0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541,\n\t0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781,\n\t0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979,\n\t0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89,\n\t0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1,\n\t0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99,\n\t0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9,\n\t0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9,\n\t0x1070: 0x6009, 0x1071: 0x402d, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x404d, 0x1075: 0x6069,\n\t0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x406d, 0x1079: 0x406d, 0x107a: 0x60b1, 0x107b: 0x60c9,\n\t0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x408d, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271,\n\t0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40ad, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9,\n\t0x108c: 0x40cd, 0x108d: 0x40cd, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x40ed,\n\t0x1092: 0x410d, 0x1093: 0x412d, 0x1094: 0x414d, 0x1095: 0x416d, 0x1096: 0x6359, 0x1097: 0x6371,\n\t0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x418d, 0x109c: 0x63d1, 0x109d: 0x63e9,\n\t0x109e: 0x6401, 0x109f: 0x41ad, 0x10a0: 0x41cd, 0x10a1: 0x6419, 0x10a2: 0x41ed, 0x10a3: 0x420d,\n\t0x10a4: 0x422d, 0x10a5: 0x6431, 0x10a6: 0x424d, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211,\n\t0x10aa: 0x426d, 0x10ab: 0x428d, 0x10ac: 0x42ad, 0x10ad: 0x42cd, 0x10ae: 0x64b1, 0x10af: 0x64f1,\n\t0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x42ed, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599,\n\t0x10b6: 0x430d, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9,\n\t0x10bc: 0x432d, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0x434d, 0x10c1: 0x436d, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671,\n\t0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709,\n\t0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781,\n\t0x10d2: 0x438d, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43ad, 0x10d6: 0x43cd, 0x10d7: 0x67b1,\n\t0x10d8: 0x0040, 0x10d9: 0x43ed, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811,\n\t0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901,\n\t0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1,\n\t0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11,\n\t0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31,\n\t0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51,\n\t0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x440d,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,\n\t0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,\n\t0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,\n\t0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,\n\t0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008,\n\t0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008,\n\t0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,\n\t0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308,\n\t0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308,\n\t0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308,\n\t0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,\n\t0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,\n\t0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,\n\t0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,\n\t0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11,\n\t0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008,\n\t0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008,\n\t0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008,\n\t0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,\n\t0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008,\n\t0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018,\n\t0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018,\n\t0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018,\n\t0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008,\n\t0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008,\n\t0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,\n\t0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008,\n\t0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,\n\t0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,\n\t0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008,\n\t0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,\n\t0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,\n\t0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,\n\t0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,\n\t0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,\n\t0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008,\n\t0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008,\n\t0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d,\n\t0x11fc: 0x0008, 0x11fd: 0x442d, 0x11fe: 0xe00d, 0x11ff: 0x0008,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008,\n\t0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d,\n\t0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008,\n\t0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,\n\t0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008,\n\t0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008,\n\t0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008,\n\t0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0008,\n\t0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x444d, 0x1234: 0xe00d, 0x1235: 0x0008,\n\t0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0x0040, 0x1239: 0x0008, 0x123a: 0x0040, 0x123b: 0x0040,\n\t0x123c: 0x0040, 0x123d: 0x0040, 0x123e: 0x0040, 0x123f: 0x0040,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x64d5, 0x1241: 0x64f5, 0x1242: 0x6515, 0x1243: 0x6535, 0x1244: 0x6555, 0x1245: 0x6575,\n\t0x1246: 0x6595, 0x1247: 0x65b5, 0x1248: 0x65d5, 0x1249: 0x65f5, 0x124a: 0x6615, 0x124b: 0x6635,\n\t0x124c: 0x6655, 0x124d: 0x6675, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x6695, 0x1251: 0x0008,\n\t0x1252: 0x66b5, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x66d5, 0x1256: 0x66f5, 0x1257: 0x6715,\n\t0x1258: 0x6735, 0x1259: 0x6755, 0x125a: 0x6775, 0x125b: 0x6795, 0x125c: 0x67b5, 0x125d: 0x67d5,\n\t0x125e: 0x67f5, 0x125f: 0x0008, 0x1260: 0x6815, 0x1261: 0x0008, 0x1262: 0x6835, 0x1263: 0x0008,\n\t0x1264: 0x0008, 0x1265: 0x6855, 0x1266: 0x6875, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,\n\t0x126a: 0x6895, 0x126b: 0x68b5, 0x126c: 0x68d5, 0x126d: 0x68f5, 0x126e: 0x6915, 0x126f: 0x6935,\n\t0x1270: 0x6955, 0x1271: 0x6975, 0x1272: 0x6995, 0x1273: 0x69b5, 0x1274: 0x69d5, 0x1275: 0x69f5,\n\t0x1276: 0x6a15, 0x1277: 0x6a35, 0x1278: 0x6a55, 0x1279: 0x6a75, 0x127a: 0x6a95, 0x127b: 0x6ab5,\n\t0x127c: 0x6ad5, 0x127d: 0x6af5, 0x127e: 0x6b15, 0x127f: 0x6b35,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x7a95, 0x1281: 0x7ab5, 0x1282: 0x7ad5, 0x1283: 0x7af5, 0x1284: 0x7b15, 0x1285: 0x7b35,\n\t0x1286: 0x7b55, 0x1287: 0x7b75, 0x1288: 0x7b95, 0x1289: 0x7bb5, 0x128a: 0x7bd5, 0x128b: 0x7bf5,\n\t0x128c: 0x7c15, 0x128d: 0x7c35, 0x128e: 0x7c55, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19,\n\t0x1292: 0x7c75, 0x1293: 0x7c95, 0x1294: 0x7cb5, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91,\n\t0x1298: 0x7cd5, 0x1299: 0x7cf5, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,\n\t0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,\n\t0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,\n\t0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,\n\t0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,\n\t0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,\n\t0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d15, 0x12c4: 0x7d35, 0x12c5: 0x7001,\n\t0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,\n\t0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,\n\t0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9,\n\t0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1,\n\t0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149,\n\t0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2,\n\t0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1,\n\t0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1,\n\t0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479,\n\t0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040,\n\t0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659,\n\t0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721,\n\t0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751,\n\t0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769,\n\t0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799,\n\t0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1,\n\t0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1,\n\t0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9,\n\t0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829,\n\t0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871,\n\t0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9,\n\t0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9,\n\t0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919,\n\t0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931,\n\t0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961,\n\t0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991,\n\t0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1,\n\t0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,\n\t0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,\n\t0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,\n\t0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,\n\t0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,\n\t0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09,\n\t0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479,\n\t0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81,\n\t0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1,\n\t0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19,\n\t0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91,\n\t0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1,\n\t0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1,\n\t0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1,\n\t0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1,\n\t0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991,\n\t0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81,\n\t0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a,\n\t0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99,\n\t0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89,\n\t0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79,\n\t0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19,\n\t0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649,\n\t0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9,\n\t0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49,\n\t0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21,\n\t0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9,\n\t0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01,\n\t0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91,\n\t0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9,\n\t0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171,\n\t0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289,\n\t0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1,\n\t0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621,\n\t0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739,\n\t0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1,\n\t0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9,\n\t0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29,\n\t0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079,\n\t0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1,\n\t0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171,\n\t0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261,\n\t0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1,\n\t0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1,\n\t0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171,\n\t0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261,\n\t0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351,\n\t0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441,\n\t0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509,\n\t0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1,\n\t0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081,\n\t0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239,\n\t0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040,\n\t0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,\n\t0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609,\n\t0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721,\n\t0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839,\n\t0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919,\n\t0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9,\n\t0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9,\n\t0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9,\n\t0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1,\n\t0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989,\n\t0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,\n\t0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040,\n\t0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,\n\t0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,\n\t0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,\n\t0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,\n\t0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,\n\t0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9,\n\t0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12,\n\t0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,\n\t0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,\n\t0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d55,\n\t0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7d75,\n\t0x1558: 0x7d95, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,\n\t0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,\n\t0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,\n\t0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,\n\t0x1570: 0x0040, 0x1571: 0x7db5, 0x1572: 0x7dd5, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2,\n\t0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7df5, 0x157a: 0x7e15, 0x157b: 0x7e35,\n\t0x157c: 0x7df5, 0x157d: 0x7e55, 0x157e: 0x7e75, 0x157f: 0x7e55,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0x7e95, 0x1581: 0x7eb5, 0x1582: 0x7ed5, 0x1583: 0x7eb5, 0x1584: 0x7ef5, 0x1585: 0x0018,\n\t0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f16, 0x158a: 0x7f36, 0x158b: 0x7f56,\n\t0x158c: 0x7f76, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7f95,\n\t0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa,\n\t0x1598: 0x7fb5, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7e95,\n\t0x159e: 0x7ef5, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99,\n\t0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda,\n\t0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,\n\t0x15b0: 0x7fd6, 0x15b1: 0xb009, 0x15b2: 0x7ff6, 0x15b3: 0x0808, 0x15b4: 0x8016, 0x15b5: 0x0040,\n\t0x15b6: 0x8036, 0x15b7: 0xb031, 0x15b8: 0x8056, 0x15b9: 0xb059, 0x15ba: 0x8076, 0x15bb: 0xb081,\n\t0x15bc: 0x8096, 0x15bd: 0xb0a9, 0x15be: 0x80b6, 0x15bf: 0xb0d1,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141,\n\t0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171,\n\t0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1,\n\t0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1,\n\t0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201,\n\t0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219,\n\t0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249,\n\t0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291,\n\t0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1,\n\t0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9,\n\t0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321,\n\t0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339,\n\t0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369,\n\t0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381,\n\t0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1,\n\t0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9,\n\t0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9,\n\t0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1,\n\t0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441,\n\t0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9,\n\t0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea,\n\t0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2,\n\t0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9,\n\t0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81,\n\t0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2,\n\t0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159,\n\t0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41,\n\t0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9,\n\t0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9,\n\t0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a,\n\t0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09,\n\t0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51,\n\t0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039,\n\t0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279,\n\t0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a,\n\t0x169e: 0xb532, 0x169f: 0x80d5, 0x16a0: 0x80f5, 0x16a1: 0x29d1, 0x16a2: 0x8115, 0x16a3: 0x8115,\n\t0x16a4: 0x8135, 0x16a5: 0x8155, 0x16a6: 0x8175, 0x16a7: 0x8195, 0x16a8: 0x81b5, 0x16a9: 0x81d5,\n\t0x16aa: 0x81f5, 0x16ab: 0x8215, 0x16ac: 0x8235, 0x16ad: 0x8255, 0x16ae: 0x8275, 0x16af: 0x8295,\n\t0x16b0: 0x82b5, 0x16b1: 0x82d5, 0x16b2: 0x82f5, 0x16b3: 0x8315, 0x16b4: 0x8335, 0x16b5: 0x8355,\n\t0x16b6: 0x8375, 0x16b7: 0x8395, 0x16b8: 0x83b5, 0x16b9: 0x83d5, 0x16ba: 0x83f5, 0x16bb: 0x8415,\n\t0x16bc: 0x81b5, 0x16bd: 0x8435, 0x16be: 0x8455, 0x16bf: 0x8215,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x8475, 0x16c1: 0x8495, 0x16c2: 0x84b5, 0x16c3: 0x84d5, 0x16c4: 0x84f5, 0x16c5: 0x8515,\n\t0x16c6: 0x8535, 0x16c7: 0x8555, 0x16c8: 0x84d5, 0x16c9: 0x8575, 0x16ca: 0x84d5, 0x16cb: 0x8595,\n\t0x16cc: 0x8595, 0x16cd: 0x85b5, 0x16ce: 0x85b5, 0x16cf: 0x85d5, 0x16d0: 0x8515, 0x16d1: 0x85f5,\n\t0x16d2: 0x8615, 0x16d3: 0x85f5, 0x16d4: 0x8635, 0x16d5: 0x8615, 0x16d6: 0x8655, 0x16d7: 0x8655,\n\t0x16d8: 0x8675, 0x16d9: 0x8675, 0x16da: 0x8695, 0x16db: 0x8695, 0x16dc: 0x8615, 0x16dd: 0x8115,\n\t0x16de: 0x86b5, 0x16df: 0x86d5, 0x16e0: 0x0040, 0x16e1: 0x86f5, 0x16e2: 0x8715, 0x16e3: 0x8735,\n\t0x16e4: 0x8755, 0x16e5: 0x8735, 0x16e6: 0x8775, 0x16e7: 0x8795, 0x16e8: 0x87b5, 0x16e9: 0x87b5,\n\t0x16ea: 0x87d5, 0x16eb: 0x87d5, 0x16ec: 0x87f5, 0x16ed: 0x87f5, 0x16ee: 0x87d5, 0x16ef: 0x87d5,\n\t0x16f0: 0x8815, 0x16f1: 0x8835, 0x16f2: 0x8855, 0x16f3: 0x8875, 0x16f4: 0x8895, 0x16f5: 0x88b5,\n\t0x16f6: 0x88b5, 0x16f7: 0x88b5, 0x16f8: 0x88d5, 0x16f9: 0x88d5, 0x16fa: 0x88d5, 0x16fb: 0x88d5,\n\t0x16fc: 0x87b5, 0x16fd: 0x87b5, 0x16fe: 0x87b5, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x8715, 0x1703: 0x86f5, 0x1704: 0x88f5, 0x1705: 0x86f5,\n\t0x1706: 0x8715, 0x1707: 0x86f5, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x8915, 0x170b: 0x8715,\n\t0x170c: 0x8935, 0x170d: 0x88f5, 0x170e: 0x8935, 0x170f: 0x8715, 0x1710: 0x0040, 0x1711: 0x0040,\n\t0x1712: 0x8955, 0x1713: 0x8975, 0x1714: 0x8875, 0x1715: 0x8935, 0x1716: 0x88f5, 0x1717: 0x8935,\n\t0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x8995, 0x171b: 0x89b5, 0x171c: 0x8995, 0x171d: 0x0040,\n\t0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x89d6,\n\t0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x89f5, 0x1727: 0x0040, 0x1728: 0x8a15, 0x1729: 0x8a35,\n\t0x172a: 0x8a55, 0x172b: 0x8a35, 0x172c: 0x8a75, 0x172d: 0x8a95, 0x172e: 0x8ab5, 0x172f: 0x0040,\n\t0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,\n\t0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08,\n\t0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808,\n\t0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08,\n\t0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908,\n\t0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08,\n\t0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808,\n\t0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,\n\t0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18,\n\t0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818,\n\t0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,\n\t0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08,\n\t0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08,\n\t0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08,\n\t0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040,\n\t0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040,\n\t0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040,\n\t0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18,\n\t0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818,\n\t0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040,\n\t0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,\n\t0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008,\n\t0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008,\n\t0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040,\n\t0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008,\n\t0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,\n\t0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,\n\t0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040,\n\t0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,\n\t0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008,\n\t0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308,\n\t0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040,\n\t0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008,\n\t0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040,\n\t0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008,\n\t0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008,\n\t0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008,\n\t0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308,\n\t0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040,\n\t0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040,\n\t0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,\n\t0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199,\n\t0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359,\n\t0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269,\n\t0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369,\n\t0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9,\n\t0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259,\n\t0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99,\n\t0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089,\n\t0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9,\n\t0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249,\n\t0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269,\n\t0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369,\n\t0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9,\n\t0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259,\n\t0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99,\n\t0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089,\n\t0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9,\n\t0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249,\n\t0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71,\n\t0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9,\n\t0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9,\n\t0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259,\n\t0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99,\n\t0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089,\n\t0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040,\n\t0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040,\n\t0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71,\n\t0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9,\n\t0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1,\n\t0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199,\n\t0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99,\n\t0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089,\n\t0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9,\n\t0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249,\n\t0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71,\n\t0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9,\n\t0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1,\n\t0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199,\n\t0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359,\n\t0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269,\n\t0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9,\n\t0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040,\n\t0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71,\n\t0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9,\n\t0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040,\n\t0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199,\n\t0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359,\n\t0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269,\n\t0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369,\n\t0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9,\n\t0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040,\n\t0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9,\n\t0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040,\n\t0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199,\n\t0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359,\n\t0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269,\n\t0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369,\n\t0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9,\n\t0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259,\n\t0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99,\n\t0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1,\n\t0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199,\n\t0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359,\n\t0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269,\n\t0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369,\n\t0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9,\n\t0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259,\n\t0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99,\n\t0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089,\n\t0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9,\n\t0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359,\n\t0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269,\n\t0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369,\n\t0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9,\n\t0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259,\n\t0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99,\n\t0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089,\n\t0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9,\n\t0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249,\n\t0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71,\n\t0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369,\n\t0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9,\n\t0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259,\n\t0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99,\n\t0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089,\n\t0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9,\n\t0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249,\n\t0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71,\n\t0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9,\n\t0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1,\n\t0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259,\n\t0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99,\n\t0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089,\n\t0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9,\n\t0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249,\n\t0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71,\n\t0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9,\n\t0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1,\n\t0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199,\n\t0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359,\n\t0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089,\n\t0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9,\n\t0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249,\n\t0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71,\n\t0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9,\n\t0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1,\n\t0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099,\n\t0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429,\n\t0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71,\n\t0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9,\n\t0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9,\n\t0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11,\n\t0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109,\n\t0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1,\n\t0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429,\n\t0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099,\n\t0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429,\n\t0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71,\n\t0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9,\n\t0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01,\n\t0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11,\n\t0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109,\n\t0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1,\n\t0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429,\n\t0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099,\n\t0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429,\n\t0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71,\n\t0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9,\n\t0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01,\n\t0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1,\n\t0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109,\n\t0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1,\n\t0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429,\n\t0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099,\n\t0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429,\n\t0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71,\n\t0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9,\n\t0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01,\n\t0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1,\n\t0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41,\n\t0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1,\n\t0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429,\n\t0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099,\n\t0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429,\n\t0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71,\n\t0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9,\n\t0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01,\n\t0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1,\n\t0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41,\n\t0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1,\n\t0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429,\n\t0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41,\n\t0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079,\n\t0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1,\n\t0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61,\n\t0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9,\n\t0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81,\n\t0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079,\n\t0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1,\n\t0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61,\n\t0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115,\n\t0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135,\n\t0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115,\n\t0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175,\n\t0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115,\n\t0x1c5e: 0x8b05, 0x1c5f: 0x8b05, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08,\n\t0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08,\n\t0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08,\n\t0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08,\n\t0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08,\n\t0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411,\n\t0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1,\n\t0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,\n\t0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,\n\t0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949,\n\t0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040,\n\t0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429,\n\t0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,\n\t0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,\n\t0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351,\n\t0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040,\n\t0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1,\n\t0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9,\n\t0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231,\n\t0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949,\n\t0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040,\n\t0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429,\n\t0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339,\n\t0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1,\n\t0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351,\n\t0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411,\n\t0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1,\n\t0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9,\n\t0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231,\n\t0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040,\n\t0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249,\n\t0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429,\n\t0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339,\n\t0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1,\n\t0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351,\n\t0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02,\n\t0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018,\n\t0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2,\n\t0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72,\n\t0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32,\n\t0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2,\n\t0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2,\n\t0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0018,\n\t0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199,\n\t0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359,\n\t0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089,\n\t0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1,\n\t0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018,\n\t0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018,\n\t0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018,\n\t0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018,\n\t0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018,\n\t0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0x0040, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040,\n\t0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018,\n\t0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018,\n\t0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0xc1d9, 0x1dc1: 0xc211, 0x1dc2: 0xc249, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040,\n\t0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040,\n\t0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc269, 0x1dd1: 0xc289,\n\t0x1dd2: 0xc2a9, 0x1dd3: 0xc2c9, 0x1dd4: 0xc2e9, 0x1dd5: 0xc309, 0x1dd6: 0xc329, 0x1dd7: 0xc349,\n\t0x1dd8: 0xc369, 0x1dd9: 0xc389, 0x1dda: 0xc3a9, 0x1ddb: 0xc3c9, 0x1ddc: 0xc3e9, 0x1ddd: 0xc409,\n\t0x1dde: 0xc429, 0x1ddf: 0xc449, 0x1de0: 0xc469, 0x1de1: 0xc489, 0x1de2: 0xc4a9, 0x1de3: 0xc4c9,\n\t0x1de4: 0xc4e9, 0x1de5: 0xc509, 0x1de6: 0xc529, 0x1de7: 0xc549, 0x1de8: 0xc569, 0x1de9: 0xc589,\n\t0x1dea: 0xc5a9, 0x1deb: 0xc5c9, 0x1dec: 0xc5e9, 0x1ded: 0xc609, 0x1dee: 0xc629, 0x1def: 0xc649,\n\t0x1df0: 0xc669, 0x1df1: 0xc689, 0x1df2: 0xc6a9, 0x1df3: 0xc6c9, 0x1df4: 0xc6e9, 0x1df5: 0xc709,\n\t0x1df6: 0xc729, 0x1df7: 0xc749, 0x1df8: 0xc769, 0x1df9: 0xc789, 0x1dfa: 0xc7a9, 0x1dfb: 0xc7c9,\n\t0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0xcaf9, 0x1e01: 0xcb19, 0x1e02: 0xcb39, 0x1e03: 0x8b1d, 0x1e04: 0xcb59, 0x1e05: 0xcb79,\n\t0x1e06: 0xcb99, 0x1e07: 0xcbb9, 0x1e08: 0xcbd9, 0x1e09: 0xcbf9, 0x1e0a: 0xcc19, 0x1e0b: 0xcc39,\n\t0x1e0c: 0xcc59, 0x1e0d: 0x8b3d, 0x1e0e: 0xcc79, 0x1e0f: 0xcc99, 0x1e10: 0xccb9, 0x1e11: 0xccd9,\n\t0x1e12: 0x8b5d, 0x1e13: 0xccf9, 0x1e14: 0xcd19, 0x1e15: 0xc429, 0x1e16: 0x8b7d, 0x1e17: 0xcd39,\n\t0x1e18: 0xcd59, 0x1e19: 0xcd79, 0x1e1a: 0xcd99, 0x1e1b: 0xcdb9, 0x1e1c: 0x8b9d, 0x1e1d: 0xcdd9,\n\t0x1e1e: 0xcdf9, 0x1e1f: 0xce19, 0x1e20: 0xce39, 0x1e21: 0xce59, 0x1e22: 0xc789, 0x1e23: 0xce79,\n\t0x1e24: 0xce99, 0x1e25: 0xceb9, 0x1e26: 0xced9, 0x1e27: 0xcef9, 0x1e28: 0xcf19, 0x1e29: 0xcf39,\n\t0x1e2a: 0xcf59, 0x1e2b: 0xcf79, 0x1e2c: 0xcf99, 0x1e2d: 0xcfb9, 0x1e2e: 0xcfd9, 0x1e2f: 0xcff9,\n\t0x1e30: 0xd019, 0x1e31: 0xd039, 0x1e32: 0xd039, 0x1e33: 0xd039, 0x1e34: 0x8bbd, 0x1e35: 0xd059,\n\t0x1e36: 0xd079, 0x1e37: 0xd099, 0x1e38: 0x8bdd, 0x1e39: 0xd0b9, 0x1e3a: 0xd0d9, 0x1e3b: 0xd0f9,\n\t0x1e3c: 0xd119, 0x1e3d: 0xd139, 0x1e3e: 0xd159, 0x1e3f: 0xd179,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0xd199, 0x1e41: 0xd1b9, 0x1e42: 0xd1d9, 0x1e43: 0xd1f9, 0x1e44: 0xd219, 0x1e45: 0xd239,\n\t0x1e46: 0xd239, 0x1e47: 0xd259, 0x1e48: 0xd279, 0x1e49: 0xd299, 0x1e4a: 0xd2b9, 0x1e4b: 0xd2d9,\n\t0x1e4c: 0xd2f9, 0x1e4d: 0xd319, 0x1e4e: 0xd339, 0x1e4f: 0xd359, 0x1e50: 0xd379, 0x1e51: 0xd399,\n\t0x1e52: 0xd3b9, 0x1e53: 0xd3d9, 0x1e54: 0xd3f9, 0x1e55: 0xd419, 0x1e56: 0xd439, 0x1e57: 0xd459,\n\t0x1e58: 0xd479, 0x1e59: 0x8bfd, 0x1e5a: 0xd499, 0x1e5b: 0xd4b9, 0x1e5c: 0xd4d9, 0x1e5d: 0xc309,\n\t0x1e5e: 0xd4f9, 0x1e5f: 0xd519, 0x1e60: 0x8c1d, 0x1e61: 0x8c3d, 0x1e62: 0xd539, 0x1e63: 0xd559,\n\t0x1e64: 0xd579, 0x1e65: 0xd599, 0x1e66: 0xd5b9, 0x1e67: 0xd5d9, 0x1e68: 0x2040, 0x1e69: 0xd5f9,\n\t0x1e6a: 0xd619, 0x1e6b: 0xd619, 0x1e6c: 0x8c5d, 0x1e6d: 0xd639, 0x1e6e: 0xd659, 0x1e6f: 0xd679,\n\t0x1e70: 0xd699, 0x1e71: 0x8c7d, 0x1e72: 0xd6b9, 0x1e73: 0xd6d9, 0x1e74: 0x2040, 0x1e75: 0xd6f9,\n\t0x1e76: 0xd719, 0x1e77: 0xd739, 0x1e78: 0xd759, 0x1e79: 0xd779, 0x1e7a: 0xd799, 0x1e7b: 0x8c9d,\n\t0x1e7c: 0xd7b9, 0x1e7d: 0x8cbd, 0x1e7e: 0xd7d9, 0x1e7f: 0xd7f9,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0xd819, 0x1e81: 0xd839, 0x1e82: 0xd859, 0x1e83: 0xd879, 0x1e84: 0xd899, 0x1e85: 0xd8b9,\n\t0x1e86: 0xd8d9, 0x1e87: 0xd8f9, 0x1e88: 0xd919, 0x1e89: 0x8cdd, 0x1e8a: 0xd939, 0x1e8b: 0xd959,\n\t0x1e8c: 0xd979, 0x1e8d: 0xd999, 0x1e8e: 0xd9b9, 0x1e8f: 0x8cfd, 0x1e90: 0xd9d9, 0x1e91: 0x8d1d,\n\t0x1e92: 0x8d3d, 0x1e93: 0xd9f9, 0x1e94: 0xda19, 0x1e95: 0xda19, 0x1e96: 0xda39, 0x1e97: 0x8d5d,\n\t0x1e98: 0x8d7d, 0x1e99: 0xda59, 0x1e9a: 0xda79, 0x1e9b: 0xda99, 0x1e9c: 0xdab9, 0x1e9d: 0xdad9,\n\t0x1e9e: 0xdaf9, 0x1e9f: 0xdb19, 0x1ea0: 0xdb39, 0x1ea1: 0xdb59, 0x1ea2: 0xdb79, 0x1ea3: 0xdb99,\n\t0x1ea4: 0x8d9d, 0x1ea5: 0xdbb9, 0x1ea6: 0xdbd9, 0x1ea7: 0xdbf9, 0x1ea8: 0xdc19, 0x1ea9: 0xdbf9,\n\t0x1eaa: 0xdc39, 0x1eab: 0xdc59, 0x1eac: 0xdc79, 0x1ead: 0xdc99, 0x1eae: 0xdcb9, 0x1eaf: 0xdcd9,\n\t0x1eb0: 0xdcf9, 0x1eb1: 0xdd19, 0x1eb2: 0xdd39, 0x1eb3: 0xdd59, 0x1eb4: 0xdd79, 0x1eb5: 0xdd99,\n\t0x1eb6: 0xddb9, 0x1eb7: 0xddd9, 0x1eb8: 0x8dbd, 0x1eb9: 0xddf9, 0x1eba: 0xde19, 0x1ebb: 0xde39,\n\t0x1ebc: 0xde59, 0x1ebd: 0xde79, 0x1ebe: 0x8ddd, 0x1ebf: 0xde99,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0xe599, 0x1ec1: 0xe5b9, 0x1ec2: 0xe5d9, 0x1ec3: 0xe5f9, 0x1ec4: 0xe619, 0x1ec5: 0xe639,\n\t0x1ec6: 0x8efd, 0x1ec7: 0xe659, 0x1ec8: 0xe679, 0x1ec9: 0xe699, 0x1eca: 0xe6b9, 0x1ecb: 0xe6d9,\n\t0x1ecc: 0xe6f9, 0x1ecd: 0x8f1d, 0x1ece: 0xe719, 0x1ecf: 0xe739, 0x1ed0: 0x8f3d, 0x1ed1: 0x8f5d,\n\t0x1ed2: 0xe759, 0x1ed3: 0xe779, 0x1ed4: 0xe799, 0x1ed5: 0xe7b9, 0x1ed6: 0xe7d9, 0x1ed7: 0xe7f9,\n\t0x1ed8: 0xe819, 0x1ed9: 0xe839, 0x1eda: 0xe859, 0x1edb: 0x8f7d, 0x1edc: 0xe879, 0x1edd: 0x8f9d,\n\t0x1ede: 0xe899, 0x1edf: 0x2040, 0x1ee0: 0xe8b9, 0x1ee1: 0xe8d9, 0x1ee2: 0xe8f9, 0x1ee3: 0x8fbd,\n\t0x1ee4: 0xe919, 0x1ee5: 0xe939, 0x1ee6: 0x8fdd, 0x1ee7: 0x8ffd, 0x1ee8: 0xe959, 0x1ee9: 0xe979,\n\t0x1eea: 0xe999, 0x1eeb: 0xe9b9, 0x1eec: 0xe9d9, 0x1eed: 0xe9d9, 0x1eee: 0xe9f9, 0x1eef: 0xea19,\n\t0x1ef0: 0xea39, 0x1ef1: 0xea59, 0x1ef2: 0xea79, 0x1ef3: 0xea99, 0x1ef4: 0xeab9, 0x1ef5: 0x901d,\n\t0x1ef6: 0xead9, 0x1ef7: 0x903d, 0x1ef8: 0xeaf9, 0x1ef9: 0x905d, 0x1efa: 0xeb19, 0x1efb: 0x907d,\n\t0x1efc: 0x909d, 0x1efd: 0x90bd, 0x1efe: 0xeb39, 0x1eff: 0xeb59,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0xeb79, 0x1f01: 0x90dd, 0x1f02: 0x90fd, 0x1f03: 0x911d, 0x1f04: 0x913d, 0x1f05: 0xeb99,\n\t0x1f06: 0xebb9, 0x1f07: 0xebb9, 0x1f08: 0xebd9, 0x1f09: 0xebf9, 0x1f0a: 0xec19, 0x1f0b: 0xec39,\n\t0x1f0c: 0xec59, 0x1f0d: 0x915d, 0x1f0e: 0xec79, 0x1f0f: 0xec99, 0x1f10: 0xecb9, 0x1f11: 0xecd9,\n\t0x1f12: 0x917d, 0x1f13: 0xecf9, 0x1f14: 0x919d, 0x1f15: 0x91bd, 0x1f16: 0xed19, 0x1f17: 0xed39,\n\t0x1f18: 0xed59, 0x1f19: 0xed79, 0x1f1a: 0xed99, 0x1f1b: 0xedb9, 0x1f1c: 0x91dd, 0x1f1d: 0x91fd,\n\t0x1f1e: 0x921d, 0x1f1f: 0x2040, 0x1f20: 0xedd9, 0x1f21: 0x923d, 0x1f22: 0xedf9, 0x1f23: 0xee19,\n\t0x1f24: 0xee39, 0x1f25: 0x925d, 0x1f26: 0xee59, 0x1f27: 0xee79, 0x1f28: 0xee99, 0x1f29: 0xeeb9,\n\t0x1f2a: 0xeed9, 0x1f2b: 0x927d, 0x1f2c: 0xeef9, 0x1f2d: 0xef19, 0x1f2e: 0xef39, 0x1f2f: 0xef59,\n\t0x1f30: 0xef79, 0x1f31: 0xef99, 0x1f32: 0x929d, 0x1f33: 0x92bd, 0x1f34: 0xefb9, 0x1f35: 0x92dd,\n\t0x1f36: 0xefd9, 0x1f37: 0x92fd, 0x1f38: 0xeff9, 0x1f39: 0xf019, 0x1f3a: 0xf039, 0x1f3b: 0x931d,\n\t0x1f3c: 0x933d, 0x1f3d: 0xf059, 0x1f3e: 0x935d, 0x1f3f: 0xf079,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0xf6b9, 0x1f41: 0xf6d9, 0x1f42: 0xf6f9, 0x1f43: 0xf719, 0x1f44: 0xf739, 0x1f45: 0x951d,\n\t0x1f46: 0xf759, 0x1f47: 0xf779, 0x1f48: 0xf799, 0x1f49: 0xf7b9, 0x1f4a: 0xf7d9, 0x1f4b: 0x953d,\n\t0x1f4c: 0x955d, 0x1f4d: 0xf7f9, 0x1f4e: 0xf819, 0x1f4f: 0xf839, 0x1f50: 0xf859, 0x1f51: 0xf879,\n\t0x1f52: 0xf899, 0x1f53: 0x957d, 0x1f54: 0xf8b9, 0x1f55: 0xf8d9, 0x1f56: 0xf8f9, 0x1f57: 0xf919,\n\t0x1f58: 0x959d, 0x1f59: 0x95bd, 0x1f5a: 0xf939, 0x1f5b: 0xf959, 0x1f5c: 0xf979, 0x1f5d: 0x95dd,\n\t0x1f5e: 0xf999, 0x1f5f: 0xf9b9, 0x1f60: 0x6815, 0x1f61: 0x95fd, 0x1f62: 0xf9d9, 0x1f63: 0xf9f9,\n\t0x1f64: 0xfa19, 0x1f65: 0x961d, 0x1f66: 0xfa39, 0x1f67: 0xfa59, 0x1f68: 0xfa79, 0x1f69: 0xfa99,\n\t0x1f6a: 0xfab9, 0x1f6b: 0xfad9, 0x1f6c: 0xfaf9, 0x1f6d: 0x963d, 0x1f6e: 0xfb19, 0x1f6f: 0xfb39,\n\t0x1f70: 0xfb59, 0x1f71: 0x965d, 0x1f72: 0xfb79, 0x1f73: 0xfb99, 0x1f74: 0xfbb9, 0x1f75: 0xfbd9,\n\t0x1f76: 0x7b35, 0x1f77: 0x967d, 0x1f78: 0xfbf9, 0x1f79: 0xfc19, 0x1f7a: 0xfc39, 0x1f7b: 0x969d,\n\t0x1f7c: 0xfc59, 0x1f7d: 0x96bd, 0x1f7e: 0xfc79, 0x1f7f: 0xfc79,\n\t// Block 0x7e, offset 0x1f80\n\t0x1f80: 0xfc99, 0x1f81: 0x96dd, 0x1f82: 0xfcb9, 0x1f83: 0xfcd9, 0x1f84: 0xfcf9, 0x1f85: 0xfd19,\n\t0x1f86: 0xfd39, 0x1f87: 0xfd59, 0x1f88: 0xfd79, 0x1f89: 0x96fd, 0x1f8a: 0xfd99, 0x1f8b: 0xfdb9,\n\t0x1f8c: 0xfdd9, 0x1f8d: 0xfdf9, 0x1f8e: 0xfe19, 0x1f8f: 0xfe39, 0x1f90: 0x971d, 0x1f91: 0xfe59,\n\t0x1f92: 0x973d, 0x1f93: 0x975d, 0x1f94: 0x977d, 0x1f95: 0xfe79, 0x1f96: 0xfe99, 0x1f97: 0xfeb9,\n\t0x1f98: 0xfed9, 0x1f99: 0xfef9, 0x1f9a: 0xff19, 0x1f9b: 0xff39, 0x1f9c: 0xff59, 0x1f9d: 0x979d,\n\t0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040,\n\t0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040,\n\t0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040,\n\t0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040,\n\t0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040,\n\t0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040,\n}\n\n// idnaIndex: 36 blocks, 2304 entries, 4608 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2304]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,\n\t0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,\n\t0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d,\n\t0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91,\n\t0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e,\n\t0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6,\n\t0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f,\n\t0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae,\n\t0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6,\n\t0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe,\n\t0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3,\n\t0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b,\n\t0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b,\n\t0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,\n\t0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,\n\t0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,\n\t0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0xd0,\n\t0x1b0: 0xd1, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd2, 0x1b5: 0xd3, 0x1b6: 0xd4, 0x1b7: 0xd5,\n\t0x1b8: 0xd6, 0x1b9: 0xd7, 0x1ba: 0xd8, 0x1bb: 0xd9, 0x1bc: 0xda, 0x1bd: 0xdb, 0x1be: 0xdc, 0x1bf: 0x37,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x38, 0x1c1: 0xdd, 0x1c2: 0xde, 0x1c3: 0xdf, 0x1c4: 0xe0, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe1,\n\t0x1c8: 0xe2, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41,\n\t0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f,\n\t0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f,\n\t0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f,\n\t0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f,\n\t0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f,\n\t0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f,\n\t// Block 0x8, offset 0x200\n\t0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f,\n\t0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f,\n\t0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f,\n\t0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f,\n\t0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f,\n\t0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f,\n\t0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b,\n\t0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f,\n\t0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f,\n\t0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f,\n\t0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f,\n\t0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f,\n\t0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f,\n\t0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f,\n\t0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f,\n\t0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f,\n\t0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f,\n\t0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f,\n\t0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f,\n\t0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f,\n\t0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f,\n\t0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe3,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f,\n\t0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f,\n\t0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe4, 0x2d3: 0xe5, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f,\n\t0x2d8: 0xe6, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe7, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe8,\n\t0x2e0: 0xe9, 0x2e1: 0xea, 0x2e2: 0xeb, 0x2e3: 0xec, 0x2e4: 0xed, 0x2e5: 0xee, 0x2e6: 0xef, 0x2e7: 0xf0,\n\t0x2e8: 0xf1, 0x2e9: 0xf2, 0x2ea: 0xf3, 0x2eb: 0xf4, 0x2ec: 0xf5, 0x2ed: 0xf6, 0x2ee: 0xf7, 0x2ef: 0xf8,\n\t0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f,\n\t0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f,\n\t0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f,\n\t0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f,\n\t0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf9, 0x31f: 0xfa,\n\t// Block 0xd, offset 0x340\n\t0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba,\n\t0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba,\n\t0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba,\n\t0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba,\n\t0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba,\n\t0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba,\n\t0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba,\n\t0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba,\n\t0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba,\n\t0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba,\n\t0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba,\n\t0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfb, 0x3a5: 0xfc, 0x3a6: 0xfd, 0x3a7: 0xfe,\n\t0x3a8: 0x47, 0x3a9: 0xff, 0x3aa: 0x100, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c,\n\t0x3b0: 0x101, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x102, 0x3b7: 0x52,\n\t0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x103, 0x3c1: 0x104, 0x3c2: 0x9f, 0x3c3: 0x105, 0x3c4: 0x106, 0x3c5: 0x9b, 0x3c6: 0x107, 0x3c7: 0x108,\n\t0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x109, 0x3cb: 0x10a, 0x3cc: 0x10b, 0x3cd: 0x10c, 0x3ce: 0x10d, 0x3cf: 0x10e,\n\t0x3d0: 0x10f, 0x3d1: 0x9f, 0x3d2: 0x110, 0x3d3: 0x111, 0x3d4: 0x112, 0x3d5: 0x113, 0x3d6: 0xba, 0x3d7: 0xba,\n\t0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x114, 0x3dd: 0x115, 0x3de: 0xba, 0x3df: 0xba,\n\t0x3e0: 0x116, 0x3e1: 0x117, 0x3e2: 0x118, 0x3e3: 0x119, 0x3e4: 0x11a, 0x3e5: 0xba, 0x3e6: 0x11b, 0x3e7: 0x11c,\n\t0x3e8: 0x11d, 0x3e9: 0x11e, 0x3ea: 0x11f, 0x3eb: 0x5b, 0x3ec: 0x120, 0x3ed: 0x121, 0x3ee: 0x5c, 0x3ef: 0xba,\n\t0x3f0: 0x122, 0x3f1: 0x123, 0x3f2: 0x124, 0x3f3: 0x125, 0x3f4: 0x126, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba,\n\t0x3f8: 0xba, 0x3f9: 0x127, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0x128, 0x3fd: 0x129, 0x3fe: 0xba, 0x3ff: 0xba,\n\t// Block 0x10, offset 0x400\n\t0x400: 0x12a, 0x401: 0x12b, 0x402: 0x12c, 0x403: 0x12d, 0x404: 0x12e, 0x405: 0x12f, 0x406: 0x130, 0x407: 0x131,\n\t0x408: 0x132, 0x409: 0xba, 0x40a: 0x133, 0x40b: 0x134, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba,\n\t0x410: 0x135, 0x411: 0x136, 0x412: 0x137, 0x413: 0x138, 0x414: 0xba, 0x415: 0xba, 0x416: 0x139, 0x417: 0x13a,\n\t0x418: 0x13b, 0x419: 0x13c, 0x41a: 0x13d, 0x41b: 0x13e, 0x41c: 0x13f, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba,\n\t0x420: 0x140, 0x421: 0xba, 0x422: 0x141, 0x423: 0x142, 0x424: 0xba, 0x425: 0xba, 0x426: 0xba, 0x427: 0xba,\n\t0x428: 0x143, 0x429: 0x144, 0x42a: 0x145, 0x42b: 0x146, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba,\n\t0x430: 0x147, 0x431: 0x148, 0x432: 0x149, 0x433: 0xba, 0x434: 0x14a, 0x435: 0x14b, 0x436: 0x14c, 0x437: 0xba,\n\t0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0x14d, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0xba,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f,\n\t0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x14e, 0x44f: 0xba,\n\t0x450: 0x9b, 0x451: 0x14f, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x150, 0x456: 0xba, 0x457: 0xba,\n\t0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba,\n\t0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba,\n\t0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba,\n\t0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba,\n\t0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f,\n\t0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f,\n\t0x490: 0x151, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba,\n\t0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba,\n\t0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba,\n\t0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba,\n\t0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba,\n\t0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba,\n\t0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba,\n\t0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f,\n\t0x4d8: 0x9f, 0x4d9: 0x152, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba,\n\t0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba,\n\t0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba,\n\t0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba,\n\t0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba,\n\t0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba,\n\t0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba,\n\t0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba,\n\t0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f,\n\t0x528: 0x146, 0x529: 0x153, 0x52a: 0xba, 0x52b: 0x154, 0x52c: 0x155, 0x52d: 0x156, 0x52e: 0x157, 0x52f: 0xba,\n\t0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba,\n\t0x538: 0xba, 0x539: 0x158, 0x53a: 0x159, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x15a, 0x53e: 0x15b, 0x53f: 0x15c,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f,\n\t0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f,\n\t0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f,\n\t0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x15d,\n\t0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f,\n\t0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x15e, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba,\n\t0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba,\n\t0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x15f, 0x585: 0x160, 0x586: 0x9f, 0x587: 0x9f,\n\t0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x161, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba,\n\t0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba,\n\t0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba,\n\t0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba,\n\t0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba,\n\t0x5b0: 0x9f, 0x5b1: 0x162, 0x5b2: 0x163, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba,\n\t0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x164, 0x5c4: 0x165, 0x5c5: 0x166, 0x5c6: 0x167, 0x5c7: 0x168,\n\t0x5c8: 0x9b, 0x5c9: 0x169, 0x5ca: 0xba, 0x5cb: 0x16a, 0x5cc: 0x9b, 0x5cd: 0x16b, 0x5ce: 0xba, 0x5cf: 0xba,\n\t0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66,\n\t0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e,\n\t0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,\n\t0x5e8: 0x16c, 0x5e9: 0x16d, 0x5ea: 0x16e, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba,\n\t0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba,\n\t0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x16f, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0xba, 0x605: 0xba, 0x606: 0xba, 0x607: 0xba,\n\t0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0xba, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba,\n\t0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba,\n\t0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba,\n\t0x620: 0x122, 0x621: 0x122, 0x622: 0x122, 0x623: 0x170, 0x624: 0x6f, 0x625: 0x171, 0x626: 0xba, 0x627: 0xba,\n\t0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba,\n\t0x630: 0xba, 0x631: 0x172, 0x632: 0x173, 0x633: 0xba, 0x634: 0xba, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba,\n\t0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x174, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x175, 0x641: 0x9b, 0x642: 0x176, 0x643: 0x177, 0x644: 0x73, 0x645: 0x74, 0x646: 0x178, 0x647: 0x179,\n\t0x648: 0x75, 0x649: 0x17a, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,\n\t0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,\n\t0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x17b, 0x65c: 0x9b, 0x65d: 0x17c, 0x65e: 0x9b, 0x65f: 0x17d,\n\t0x660: 0x17e, 0x661: 0x17f, 0x662: 0x180, 0x663: 0xba, 0x664: 0x181, 0x665: 0x182, 0x666: 0x183, 0x667: 0x184,\n\t0x668: 0xba, 0x669: 0x185, 0x66a: 0xba, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba,\n\t0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba,\n\t0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f,\n\t0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f,\n\t0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f,\n\t0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x186, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f,\n\t0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f,\n\t0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f,\n\t0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f,\n\t0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f,\n\t0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f,\n\t0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f,\n\t0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x187, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f,\n\t0x6e0: 0x188, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f,\n\t0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f,\n\t0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f,\n\t0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f,\n\t0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f,\n\t0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f,\n\t0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f,\n\t0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f,\n\t0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f,\n\t0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f,\n\t0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x189, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f,\n\t0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f,\n\t0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f,\n\t0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f,\n\t0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f,\n\t0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x18a,\n\t0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba,\n\t0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba,\n\t0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba,\n\t0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba,\n\t0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba,\n\t0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x18b, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x18c, 0x7a7: 0x7b,\n\t0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba,\n\t0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba,\n\t0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba,\n\t// Block 0x1f, offset 0x7c0\n\t0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07,\n\t0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17,\n\t0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07,\n\t0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c,\n\t0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,\n\t0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b,\n\t0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b,\n\t0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b,\n\t0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b,\n\t0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b,\n\t0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b,\n\t0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,\n\t0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x18d, 0x841: 0x18e, 0x842: 0xba, 0x843: 0xba, 0x844: 0x18f, 0x845: 0x18f, 0x846: 0x18f, 0x847: 0x190,\n\t0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba,\n\t0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba,\n\t0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba,\n\t0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba,\n\t0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba,\n\t0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba,\n\t0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,\n\t0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,\n\t0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b,\n\t0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b,\n\t0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b,\n\t0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b,\n\t0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b,\n\t0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,\n\t0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,\n}\n\n// idnaSparseOffset: 276 entries, 552 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x86, 0x8b, 0x94, 0xa4, 0xb2, 0xbe, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x224, 0x22e, 0x23a, 0x246, 0x252, 0x25a, 0x25f, 0x269, 0x27a, 0x27e, 0x289, 0x28d, 0x296, 0x29e, 0x2a4, 0x2a9, 0x2ac, 0x2b0, 0x2b6, 0x2ba, 0x2be, 0x2c2, 0x2c7, 0x2cd, 0x2d5, 0x2dc, 0x2e7, 0x2f1, 0x2f5, 0x2f8, 0x2fe, 0x302, 0x304, 0x307, 0x309, 0x30c, 0x316, 0x319, 0x328, 0x32c, 0x331, 0x334, 0x338, 0x33d, 0x342, 0x348, 0x34e, 0x35d, 0x363, 0x367, 0x376, 0x37b, 0x383, 0x38d, 0x398, 0x3a0, 0x3b1, 0x3ba, 0x3ca, 0x3d7, 0x3e1, 0x3e6, 0x3f3, 0x3f7, 0x3fc, 0x3fe, 0x402, 0x404, 0x408, 0x411, 0x417, 0x41b, 0x42b, 0x435, 0x43a, 0x43d, 0x443, 0x44a, 0x44f, 0x453, 0x459, 0x45e, 0x467, 0x46c, 0x472, 0x479, 0x480, 0x487, 0x48b, 0x490, 0x493, 0x498, 0x4a4, 0x4aa, 0x4af, 0x4b6, 0x4be, 0x4c3, 0x4c7, 0x4d7, 0x4de, 0x4e2, 0x4e6, 0x4ed, 0x4ef, 0x4f2, 0x4f5, 0x4f9, 0x502, 0x506, 0x50e, 0x516, 0x51c, 0x525, 0x531, 0x538, 0x541, 0x54b, 0x552, 0x560, 0x56d, 0x57a, 0x583, 0x587, 0x596, 0x59e, 0x5a9, 0x5b2, 0x5b8, 0x5c0, 0x5c9, 0x5d3, 0x5d6, 0x5e2, 0x5eb, 0x5ee, 0x5f3, 0x5fe, 0x607, 0x613, 0x616, 0x620, 0x629, 0x635, 0x642, 0x64f, 0x65d, 0x664, 0x667, 0x66c, 0x66f, 0x672, 0x675, 0x67c, 0x683, 0x687, 0x692, 0x695, 0x698, 0x69b, 0x6a1, 0x6a6, 0x6aa, 0x6ad, 0x6b0, 0x6b3, 0x6b6, 0x6b9, 0x6be, 0x6c8, 0x6cb, 0x6cf, 0x6de, 0x6ea, 0x6ee, 0x6f3, 0x6f7, 0x6fc, 0x700, 0x705, 0x70e, 0x719, 0x71f, 0x727, 0x72a, 0x72d, 0x731, 0x735, 0x73b, 0x741, 0x746, 0x749, 0x759, 0x760, 0x763, 0x766, 0x76a, 0x770, 0x775, 0x77a, 0x782, 0x787, 0x78b, 0x78f, 0x792, 0x795, 0x799, 0x79d, 0x7a0, 0x7b0, 0x7c1, 0x7c6, 0x7c8, 0x7ca}\n\n// idnaSparseValues: 1997 entries, 7988 bytes\nvar idnaSparseValues = [1997]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0249, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0259, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0269, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0279, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0289, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x6, offset 0x33\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0401, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xae},\n\t{value: 0x0808, lo: 0xaf, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x62\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbf},\n\t// Block 0xc, offset 0x6c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x78\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0a08, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0c08, lo: 0xaa, hi: 0xac},\n\t{value: 0x0808, lo: 0xad, hi: 0xad},\n\t{value: 0x0c08, lo: 0xae, hi: 0xae},\n\t{value: 0x0a08, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0a08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xe, offset 0x86\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0xf, offset 0x8b\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x10, offset 0x94\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x11, offset 0xa4\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x12, offset 0xb2\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x3b08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbe\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x14, offset 0xca\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x15, offset 0xdb\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x08f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x16, offset 0xe5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x17, offset 0xec\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0961, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0999, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x18, offset 0xf9\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x19, offset 0x10a\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x1a, offset 0x111\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1b, offset 0x11c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1c, offset 0x12b\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1d, offset 0x139\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1e, offset 0x143\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x1f, offset 0x145\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x20, offset 0x14a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x21, offset 0x14d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x22, offset 0x150\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x23, offset 0x152\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x24, offset 0x15e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x25, offset 0x169\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x26, offset 0x171\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x27, offset 0x177\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x28, offset 0x17d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x29, offset 0x182\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x2a, offset 0x187\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2b, offset 0x18a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2c, offset 0x18e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2d, offset 0x194\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2e, offset 0x199\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x30, offset 0x1af\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x31, offset 0x1b5\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x32, offset 0x1c6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x33, offset 0x1d0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x34, offset 0x1d3\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x35, offset 0x1db\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x36, offset 0x1de\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x37, offset 0x1eb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x38, offset 0x1f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x39, offset 0x1f7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x3a, offset 0x1fe\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3b, offset 0x206\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3c, offset 0x216\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3d, offset 0x222\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x3e, offset 0x224\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x3f, offset 0x22e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x40, offset 0x23a\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x41, offset 0x246\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x42, offset 0x252\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x43, offset 0x25a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x44, offset 0x25f\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0e29, lo: 0x80, hi: 0x80},\n\t{value: 0x0e41, lo: 0x81, hi: 0x81},\n\t{value: 0x0e59, lo: 0x82, hi: 0x82},\n\t{value: 0x0e71, lo: 0x83, hi: 0x83},\n\t{value: 0x0e89, lo: 0x84, hi: 0x85},\n\t{value: 0x0ea1, lo: 0x86, hi: 0x86},\n\t{value: 0x0eb9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0x45, offset 0x269\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x46, offset 0x27a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x47, offset 0x27e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x48, offset 0x289\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x49, offset 0x28d\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x24c1, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x4a, offset 0x296\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x24f1, lo: 0xac, hi: 0xac},\n\t{value: 0x2529, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x2579, lo: 0xaf, hi: 0xaf},\n\t{value: 0x25b1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4b, offset 0x29e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4c, offset 0x2a4\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09c5, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09e5, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4d, offset 0x2a9\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x4e, offset 0x2ac\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x28c1, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x4f, offset 0x2b0\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e66, lo: 0xb4, hi: 0xb4},\n\t{value: 0x292a, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e86, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x50, offset 0x2b6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x2941, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x51, offset 0x2ba\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x52, offset 0x2be\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0xbf},\n\t// Block 0x53, offset 0x2c2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x54, offset 0x2c7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ea5, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x55, offset 0x2cd\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x56, offset 0x2d5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x57, offset 0x2dc\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x58, offset 0x2e7\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x59, offset 0x2f1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5a, offset 0x2f5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0xbf},\n\t// Block 0x5b, offset 0x2f8\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0edd, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5c, offset 0x2fe\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0efd, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5d, offset 0x302\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f1d, lo: 0x80, hi: 0xbf},\n\t// Block 0x5e, offset 0x304\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x171d, lo: 0x80, hi: 0x8f},\n\t{value: 0x18fd, lo: 0x90, hi: 0xbf},\n\t// Block 0x5f, offset 0x307\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1efd, lo: 0x80, hi: 0xbf},\n\t// Block 0x60, offset 0x309\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x61, offset 0x30c\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x29e2, lo: 0x9b, hi: 0x9b},\n\t{value: 0x2a0a, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x2a31, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x62, offset 0x316\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x2a69, lo: 0xbf, hi: 0xbf},\n\t// Block 0x63, offset 0x319\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb0},\n\t{value: 0x2a1d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a3d, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a5d, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a7d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a5d, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2a9d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2abd, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2add, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2afd, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b1d, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2afd, lo: 0xbe, hi: 0xbf},\n\t// Block 0x64, offset 0x328\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x65, offset 0x32c\n\t{value: 0x0030, lo: 0x04},\n\t{value: 0x2aa2, lo: 0x80, hi: 0x9d},\n\t{value: 0x305a, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x30a2, lo: 0xa0, hi: 0xbf},\n\t// Block 0x66, offset 0x331\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x67, offset 0x334\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x68, offset 0x338\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x69, offset 0x33d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x6a, offset 0x342\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6b, offset 0x348\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2009, lo: 0xb8, hi: 0xb8},\n\t{value: 0x6e89, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xbf},\n\t// Block 0x6c, offset 0x34e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6d, offset 0x35d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6e, offset 0x363\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x6f, offset 0x367\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x70, offset 0x376\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x71, offset 0x37b\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x72, offset 0x383\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x73, offset 0x38d\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x74, offset 0x398\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x75, offset 0x3a0\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x76, offset 0x3b1\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x77, offset 0x3ba\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x78, offset 0x3ca\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x79, offset 0x3d7\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x4465, lo: 0x9c, hi: 0x9c},\n\t{value: 0x447d, lo: 0x9d, hi: 0x9d},\n\t{value: 0x2971, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xaf},\n\t{value: 0x4495, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7a, offset 0x3e1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44b5, lo: 0x80, hi: 0x8f},\n\t{value: 0x44d5, lo: 0x90, hi: 0x9f},\n\t{value: 0x44f5, lo: 0xa0, hi: 0xaf},\n\t{value: 0x44d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7b, offset 0x3e6\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x7c, offset 0x3f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7d, offset 0x3f7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x7e, offset 0x3fc\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x4515, lo: 0x80, hi: 0xbf},\n\t// Block 0x7f, offset 0x3fe\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d15, lo: 0x80, hi: 0x94},\n\t{value: 0x4ad5, lo: 0x95, hi: 0x95},\n\t{value: 0x4fb5, lo: 0x96, hi: 0xbf},\n\t// Block 0x80, offset 0x402\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x54f5, lo: 0x80, hi: 0xbf},\n\t// Block 0x81, offset 0x404\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5cf5, lo: 0x80, hi: 0x84},\n\t{value: 0x5655, lo: 0x85, hi: 0x85},\n\t{value: 0x5d95, lo: 0x86, hi: 0xbf},\n\t// Block 0x82, offset 0x408\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b55, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d15, lo: 0x90, hi: 0x90},\n\t{value: 0x6d55, lo: 0x91, hi: 0xab},\n\t{value: 0x6ea1, lo: 0xac, hi: 0xac},\n\t{value: 0x70b5, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x70d5, lo: 0xb0, hi: 0xbf},\n\t// Block 0x83, offset 0x411\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x72d5, lo: 0x80, hi: 0xad},\n\t{value: 0x6535, lo: 0xae, hi: 0xae},\n\t{value: 0x7895, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f55, lo: 0xb6, hi: 0xb6},\n\t{value: 0x7975, lo: 0xb7, hi: 0xbf},\n\t// Block 0x84, offset 0x417\n\t{value: 0x0028, lo: 0x03},\n\t{value: 0x7c21, lo: 0x80, hi: 0x82},\n\t{value: 0x7be1, lo: 0x83, hi: 0x83},\n\t{value: 0x7c99, lo: 0x84, hi: 0xbf},\n\t// Block 0x85, offset 0x41b\n\t{value: 0x0038, lo: 0x0f},\n\t{value: 0x9db1, lo: 0x80, hi: 0x83},\n\t{value: 0x9e59, lo: 0x84, hi: 0x85},\n\t{value: 0x9e91, lo: 0x86, hi: 0x87},\n\t{value: 0x9ec9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0xa089, lo: 0x92, hi: 0x97},\n\t{value: 0xa1a1, lo: 0x98, hi: 0x9c},\n\t{value: 0xa281, lo: 0x9d, hi: 0xb3},\n\t{value: 0x9d41, lo: 0xb4, hi: 0xb4},\n\t{value: 0x9db1, lo: 0xb5, hi: 0xb5},\n\t{value: 0xa789, lo: 0xb6, hi: 0xbb},\n\t{value: 0xa869, lo: 0xbc, hi: 0xbc},\n\t{value: 0xa7f9, lo: 0xbd, hi: 0xbd},\n\t{value: 0xa8d9, lo: 0xbe, hi: 0xbf},\n\t// Block 0x86, offset 0x42b\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x87, offset 0x435\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x88, offset 0x43a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x89, offset 0x43d\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x8a, offset 0x443\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x8b, offset 0x44a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8c, offset 0x44f\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8d, offset 0x453\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x8e, offset 0x459\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xbf},\n\t// Block 0x8f, offset 0x45e\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x90, offset 0x467\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x91, offset 0x46c\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x92, offset 0x472\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8ad5, lo: 0x98, hi: 0x9f},\n\t{value: 0x8aed, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x93, offset 0x479\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8aed, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8ad5, lo: 0xb8, hi: 0xbf},\n\t// Block 0x94, offset 0x480\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x95, offset 0x487\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x96, offset 0x48b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xae},\n\t{value: 0x0018, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x97, offset 0x490\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x98, offset 0x493\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x99, offset 0x498\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9a, offset 0x4a4\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9b, offset 0x4aa\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x9c, offset 0x4af\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9d, offset 0x4b6\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9e, offset 0x4be\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0x9f, offset 0x4c3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0xa0, offset 0x4c7\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa1, offset 0x4d7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0xa2, offset 0x4de\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa3, offset 0x4e2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa4, offset 0x4e6\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa5, offset 0x4ed\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa6, offset 0x4ef\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa7, offset 0x4f2\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xa8, offset 0x4f5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xa9, offset 0x4f9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0908, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0xa1},\n\t{value: 0x0c08, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0a08, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xaa, offset 0x502\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xab, offset 0x506\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0xa6},\n\t{value: 0x0808, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0a08, lo: 0xb4, hi: 0xbf},\n\t// Block 0xac, offset 0x50e\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x84},\n\t{value: 0x0808, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x90},\n\t{value: 0x0a18, lo: 0x91, hi: 0x93},\n\t{value: 0x0c18, lo: 0x94, hi: 0x94},\n\t{value: 0x0818, lo: 0x95, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xad, offset 0x516\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xae, offset 0x51c\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xaf, offset 0x525\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xb0, offset 0x531\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb1, offset 0x538\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xb2, offset 0x541\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb3, offset 0x54b\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb4, offset 0x552\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xb5, offset 0x560\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb6, offset 0x56d\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xb7, offset 0x57a\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb8, offset 0x583\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xb9, offset 0x587\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xba, offset 0x596\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbb, offset 0x59e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xbc, offset 0x5a9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbd, offset 0x5b2\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xbe, offset 0x5b8\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbf, offset 0x5c0\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xc0, offset 0x5c9\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xc1, offset 0x5d3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xc2, offset 0x5d6\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc3, offset 0x5e2\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xc4, offset 0x5eb\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xc5, offset 0x5ee\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc6, offset 0x5f3\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc7, offset 0x5fe\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x3b08, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0xbf},\n\t// Block 0xc8, offset 0x607\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x98},\n\t{value: 0x3b08, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xbf},\n\t// Block 0xc9, offset 0x613\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xca, offset 0x616\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xcb, offset 0x620\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xcc, offset 0x629\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xcd, offset 0x635\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xce, offset 0x642\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xcf, offset 0x64f\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x3008, lo: 0x93, hi: 0x94},\n\t{value: 0x3308, lo: 0x95, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x96},\n\t{value: 0x3b08, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd0, offset 0x65d\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd1, offset 0x664\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xd2, offset 0x667\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xd3, offset 0x66c\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xd4, offset 0x66f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xbf},\n\t// Block 0xd5, offset 0x672\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xd6, offset 0x675\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xd7, offset 0x67c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xd8, offset 0x683\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xd9, offset 0x687\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xda, offset 0x692\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xdb, offset 0x695\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0xdc, offset 0x698\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0xdd, offset 0x69b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xde, offset 0x6a1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xdf, offset 0x6a6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xbf},\n\t// Block 0xe0, offset 0x6aa\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xe1, offset 0x6ad\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xe2, offset 0x6b0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xe3, offset 0x6b3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe4, offset 0x6b6\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xe5, offset 0x6b9\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xe6, offset 0x6be\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xe7, offset 0x6c8\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xe8, offset 0x6cb\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xe9, offset 0x6cf\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0xb5b9, lo: 0x9e, hi: 0x9e},\n\t{value: 0xb601, lo: 0x9f, hi: 0x9f},\n\t{value: 0xb649, lo: 0xa0, hi: 0xa0},\n\t{value: 0xb6b1, lo: 0xa1, hi: 0xa1},\n\t{value: 0xb719, lo: 0xa2, hi: 0xa2},\n\t{value: 0xb781, lo: 0xa3, hi: 0xa3},\n\t{value: 0xb7e9, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xea, offset 0x6de\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0xb851, lo: 0xbb, hi: 0xbb},\n\t{value: 0xb899, lo: 0xbc, hi: 0xbc},\n\t{value: 0xb8e1, lo: 0xbd, hi: 0xbd},\n\t{value: 0xb949, lo: 0xbe, hi: 0xbe},\n\t{value: 0xb9b1, lo: 0xbf, hi: 0xbf},\n\t// Block 0xeb, offset 0x6ea\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0xba19, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xbf},\n\t// Block 0xec, offset 0x6ee\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0xed, offset 0x6f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0xee, offset 0x6f7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xef, offset 0x6fc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0xf0, offset 0x700\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0xf1, offset 0x705\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf2, offset 0x70e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xf3, offset 0x719\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xf4, offset 0x71f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xf5, offset 0x727\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xb0},\n\t{value: 0x0818, lo: 0xb1, hi: 0xbf},\n\t// Block 0xf6, offset 0x72a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0818, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xf7, offset 0x72d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xf8, offset 0x731\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf9, offset 0x735\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0xfa, offset 0x73b\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xfb, offset 0x741\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0xc1c1, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xfc, offset 0x746\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0xfd, offset 0x749\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0xc7e9, lo: 0x80, hi: 0x80},\n\t{value: 0xc839, lo: 0x81, hi: 0x81},\n\t{value: 0xc889, lo: 0x82, hi: 0x82},\n\t{value: 0xc8d9, lo: 0x83, hi: 0x83},\n\t{value: 0xc929, lo: 0x84, hi: 0x84},\n\t{value: 0xc979, lo: 0x85, hi: 0x85},\n\t{value: 0xc9c9, lo: 0x86, hi: 0x86},\n\t{value: 0xca19, lo: 0x87, hi: 0x87},\n\t{value: 0xca69, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0xcab9, lo: 0x90, hi: 0x90},\n\t{value: 0xcad9, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xbf},\n\t// Block 0xfe, offset 0x759\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xff, offset 0x760\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x100, offset 0x763\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0xbf},\n\t// Block 0x101, offset 0x766\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x102, offset 0x76a\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x103, offset 0x770\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x104, offset 0x775\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x105, offset 0x77a\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0018, lo: 0xb3, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x106, offset 0x782\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x107, offset 0x787\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x108, offset 0x78b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x109, offset 0x78f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0x10a, offset 0x792\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x10b, offset 0x795\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x10c, offset 0x799\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x10d, offset 0x79d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x10e, offset 0x7a0\n\t{value: 0x0020, lo: 0x0f},\n\t{value: 0xdeb9, lo: 0x80, hi: 0x89},\n\t{value: 0x8dfd, lo: 0x8a, hi: 0x8a},\n\t{value: 0xdff9, lo: 0x8b, hi: 0x9c},\n\t{value: 0x8e1d, lo: 0x9d, hi: 0x9d},\n\t{value: 0xe239, lo: 0x9e, hi: 0xa2},\n\t{value: 0x8e3d, lo: 0xa3, hi: 0xa3},\n\t{value: 0xe2d9, lo: 0xa4, hi: 0xab},\n\t{value: 0x7ed5, lo: 0xac, hi: 0xac},\n\t{value: 0xe3d9, lo: 0xad, hi: 0xaf},\n\t{value: 0x8e5d, lo: 0xb0, hi: 0xb0},\n\t{value: 0xe439, lo: 0xb1, hi: 0xb6},\n\t{value: 0x8e7d, lo: 0xb7, hi: 0xb9},\n\t{value: 0xe4f9, lo: 0xba, hi: 0xba},\n\t{value: 0x8edd, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe519, lo: 0xbc, hi: 0xbf},\n\t// Block 0x10f, offset 0x7b0\n\t{value: 0x0020, lo: 0x10},\n\t{value: 0x937d, lo: 0x80, hi: 0x80},\n\t{value: 0xf099, lo: 0x81, hi: 0x86},\n\t{value: 0x939d, lo: 0x87, hi: 0x8a},\n\t{value: 0xd9f9, lo: 0x8b, hi: 0x8b},\n\t{value: 0xf159, lo: 0x8c, hi: 0x96},\n\t{value: 0x941d, lo: 0x97, hi: 0x97},\n\t{value: 0xf2b9, lo: 0x98, hi: 0xa3},\n\t{value: 0x943d, lo: 0xa4, hi: 0xa6},\n\t{value: 0xf439, lo: 0xa7, hi: 0xaa},\n\t{value: 0x949d, lo: 0xab, hi: 0xab},\n\t{value: 0xf4b9, lo: 0xac, hi: 0xac},\n\t{value: 0x94bd, lo: 0xad, hi: 0xad},\n\t{value: 0xf4d9, lo: 0xae, hi: 0xaf},\n\t{value: 0x94dd, lo: 0xb0, hi: 0xb1},\n\t{value: 0xf519, lo: 0xb2, hi: 0xbe},\n\t{value: 0x2040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x110, offset 0x7c1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0x111, offset 0x7c6\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x112, offset 0x7c8\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x113, offset 0x7ca\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 42466 bytes (41KiB); checksum: 355A58A4\n"
  },
  {
    "path": "vendor/golang.org/x/net/idna/tables12.0.0.go",
    "content": "// Code generated by running \"go generate\" in golang.org/x/text. DO NOT EDIT.\n\n//go:build go1.14 && !go1.16\n\npackage idna\n\n// UnicodeVersion is the Unicode version from which the tables in this package are derived.\nconst UnicodeVersion = \"12.0.0\"\n\nvar mappings string = \"\" + // Size: 8178 bytes\n\t\"\\x00\\x01 \\x03 ̈\\x01a\\x03 ̄\\x012\\x013\\x03 ́\\x03 ̧\\x011\\x01o\\x051⁄4\\x051⁄2\" +\n\t\"\\x053⁄4\\x03i̇\\x03l·\\x03ʼn\\x01s\\x03dž\\x03ⱥ\\x03ⱦ\\x01h\\x01j\\x01r\\x01w\\x01y\" +\n\t\"\\x03 ̆\\x03 ̇\\x03 ̊\\x03 ̨\\x03 ̃\\x03 ̋\\x01l\\x01x\\x04̈́\\x03 ι\\x01;\\x05 ̈́\" +\n\t\"\\x04եւ\\x04اٴ\\x04وٴ\\x04ۇٴ\\x04يٴ\\x06क़\\x06ख़\\x06ग़\\x06ज़\\x06ड़\\x06ढ़\\x06फ़\" +\n\t\"\\x06य़\\x06ড়\\x06ঢ়\\x06য়\\x06ਲ਼\\x06ਸ਼\\x06ਖ਼\\x06ਗ਼\\x06ਜ਼\\x06ਫ਼\\x06ଡ଼\\x06ଢ଼\" +\n\t\"\\x06ํา\\x06ໍາ\\x06ຫນ\\x06ຫມ\\x06གྷ\\x06ཌྷ\\x06དྷ\\x06བྷ\\x06ཛྷ\\x06ཀྵ\\x06ཱི\\x06ཱུ\" +\n\t\"\\x06ྲྀ\\x09ྲཱྀ\\x06ླྀ\\x09ླཱྀ\\x06ཱྀ\\x06ྒྷ\\x06ྜྷ\\x06ྡྷ\\x06ྦྷ\\x06ྫྷ\\x06ྐྵ\\x02\" +\n\t\"в\\x02д\\x02о\\x02с\\x02т\\x02ъ\\x02ѣ\\x02æ\\x01b\\x01d\\x01e\\x02ǝ\\x01g\\x01i\\x01k\" +\n\t\"\\x01m\\x01n\\x02ȣ\\x01p\\x01t\\x01u\\x02ɐ\\x02ɑ\\x02ə\\x02ɛ\\x02ɜ\\x02ŋ\\x02ɔ\\x02ɯ\" +\n\t\"\\x01v\\x02β\\x02γ\\x02δ\\x02φ\\x02χ\\x02ρ\\x02н\\x02ɒ\\x01c\\x02ɕ\\x02ð\\x01f\\x02ɟ\" +\n\t\"\\x02ɡ\\x02ɥ\\x02ɨ\\x02ɩ\\x02ɪ\\x02ʝ\\x02ɭ\\x02ʟ\\x02ɱ\\x02ɰ\\x02ɲ\\x02ɳ\\x02ɴ\\x02ɵ\" +\n\t\"\\x02ɸ\\x02ʂ\\x02ʃ\\x02ƫ\\x02ʉ\\x02ʊ\\x02ʋ\\x02ʌ\\x01z\\x02ʐ\\x02ʑ\\x02ʒ\\x02θ\\x02ss\" +\n\t\"\\x02ά\\x02έ\\x02ή\\x02ί\\x02ό\\x02ύ\\x02ώ\\x05ἀι\\x05ἁι\\x05ἂι\\x05ἃι\\x05ἄι\\x05ἅι\" +\n\t\"\\x05ἆι\\x05ἇι\\x05ἠι\\x05ἡι\\x05ἢι\\x05ἣι\\x05ἤι\\x05ἥι\\x05ἦι\\x05ἧι\\x05ὠι\\x05ὡι\" +\n\t\"\\x05ὢι\\x05ὣι\\x05ὤι\\x05ὥι\\x05ὦι\\x05ὧι\\x05ὰι\\x04αι\\x04άι\\x05ᾶι\\x02ι\\x05 ̈͂\" +\n\t\"\\x05ὴι\\x04ηι\\x04ήι\\x05ῆι\\x05 ̓̀\\x05 ̓́\\x05 ̓͂\\x02ΐ\\x05 ̔̀\\x05 ̔́\\x05 ̔͂\" +\n\t\"\\x02ΰ\\x05 ̈̀\\x01`\\x05ὼι\\x04ωι\\x04ώι\\x05ῶι\\x06′′\\x09′′′\\x06‵‵\\x09‵‵‵\\x02!\" +\n\t\"!\\x02??\\x02?!\\x02!?\\x0c′′′′\\x010\\x014\\x015\\x016\\x017\\x018\\x019\\x01+\\x01=\" +\n\t\"\\x01(\\x01)\\x02rs\\x02ħ\\x02no\\x01q\\x02sm\\x02tm\\x02ω\\x02å\\x02א\\x02ב\\x02ג\" +\n\t\"\\x02ד\\x02π\\x051⁄7\\x051⁄9\\x061⁄10\\x051⁄3\\x052⁄3\\x051⁄5\\x052⁄5\\x053⁄5\\x054\" +\n\t\"⁄5\\x051⁄6\\x055⁄6\\x051⁄8\\x053⁄8\\x055⁄8\\x057⁄8\\x041⁄\\x02ii\\x02iv\\x02vi\" +\n\t\"\\x04viii\\x02ix\\x02xi\\x050⁄3\\x06∫∫\\x09∫∫∫\\x06∮∮\\x09∮∮∮\\x0210\\x0211\\x0212\" +\n\t\"\\x0213\\x0214\\x0215\\x0216\\x0217\\x0218\\x0219\\x0220\\x04(10)\\x04(11)\\x04(12)\" +\n\t\"\\x04(13)\\x04(14)\\x04(15)\\x04(16)\\x04(17)\\x04(18)\\x04(19)\\x04(20)\\x0c∫∫∫∫\" +\n\t\"\\x02==\\x05⫝̸\\x02ɫ\\x02ɽ\\x02ȿ\\x02ɀ\\x01.\\x04 ゙\\x04 ゚\\x06より\\x06コト\\x05(ᄀ)\\x05\" +\n\t\"(ᄂ)\\x05(ᄃ)\\x05(ᄅ)\\x05(ᄆ)\\x05(ᄇ)\\x05(ᄉ)\\x05(ᄋ)\\x05(ᄌ)\\x05(ᄎ)\\x05(ᄏ)\\x05(ᄐ\" +\n\t\")\\x05(ᄑ)\\x05(ᄒ)\\x05(가)\\x05(나)\\x05(다)\\x05(라)\\x05(마)\\x05(바)\\x05(사)\\x05(아)\" +\n\t\"\\x05(자)\\x05(차)\\x05(카)\\x05(타)\\x05(파)\\x05(하)\\x05(주)\\x08(오전)\\x08(오후)\\x05(一)\" +\n\t\"\\x05(二)\\x05(三)\\x05(四)\\x05(五)\\x05(六)\\x05(七)\\x05(八)\\x05(九)\\x05(十)\\x05(月)\" +\n\t\"\\x05(火)\\x05(水)\\x05(木)\\x05(金)\\x05(土)\\x05(日)\\x05(株)\\x05(有)\\x05(社)\\x05(名)\" +\n\t\"\\x05(特)\\x05(財)\\x05(祝)\\x05(労)\\x05(代)\\x05(呼)\\x05(学)\\x05(監)\\x05(企)\\x05(資)\" +\n\t\"\\x05(協)\\x05(祭)\\x05(休)\\x05(自)\\x05(至)\\x0221\\x0222\\x0223\\x0224\\x0225\\x0226\" +\n\t\"\\x0227\\x0228\\x0229\\x0230\\x0231\\x0232\\x0233\\x0234\\x0235\\x06참고\\x06주의\\x0236\" +\n\t\"\\x0237\\x0238\\x0239\\x0240\\x0241\\x0242\\x0243\\x0244\\x0245\\x0246\\x0247\\x0248\" +\n\t\"\\x0249\\x0250\\x041月\\x042月\\x043月\\x044月\\x045月\\x046月\\x047月\\x048月\\x049月\\x0510\" +\n\t\"月\\x0511月\\x0512月\\x02hg\\x02ev\\x0cアパート\\x0cアルファ\\x0cアンペア\\x09アール\\x0cイニング\\x09\" +\n\t\"インチ\\x09ウォン\\x0fエスクード\\x0cエーカー\\x09オンス\\x09オーム\\x09カイリ\\x0cカラット\\x0cカロリー\\x09ガロ\" +\n\t\"ン\\x09ガンマ\\x06ギガ\\x09ギニー\\x0cキュリー\\x0cギルダー\\x06キロ\\x0fキログラム\\x12キロメートル\\x0fキロワッ\" +\n\t\"ト\\x09グラム\\x0fグラムトン\\x0fクルゼイロ\\x0cクローネ\\x09ケース\\x09コルナ\\x09コーポ\\x0cサイクル\\x0fサンチ\" +\n\t\"ーム\\x0cシリング\\x09センチ\\x09セント\\x09ダース\\x06デシ\\x06ドル\\x06トン\\x06ナノ\\x09ノット\\x09ハイツ\" +\n\t\"\\x0fパーセント\\x09パーツ\\x0cバーレル\\x0fピアストル\\x09ピクル\\x06ピコ\\x06ビル\\x0fファラッド\\x0cフィート\" +\n\t\"\\x0fブッシェル\\x09フラン\\x0fヘクタール\\x06ペソ\\x09ペニヒ\\x09ヘルツ\\x09ペンス\\x09ページ\\x09ベータ\\x0cポイ\" +\n\t\"ント\\x09ボルト\\x06ホン\\x09ポンド\\x09ホール\\x09ホーン\\x0cマイクロ\\x09マイル\\x09マッハ\\x09マルク\\x0fマ\" +\n\t\"ンション\\x0cミクロン\\x06ミリ\\x0fミリバール\\x06メガ\\x0cメガトン\\x0cメートル\\x09ヤード\\x09ヤール\\x09ユアン\" +\n\t\"\\x0cリットル\\x06リラ\\x09ルピー\\x0cルーブル\\x06レム\\x0fレントゲン\\x09ワット\\x040点\\x041点\\x042点\" +\n\t\"\\x043点\\x044点\\x045点\\x046点\\x047点\\x048点\\x049点\\x0510点\\x0511点\\x0512点\\x0513点\" +\n\t\"\\x0514点\\x0515点\\x0516点\\x0517点\\x0518点\\x0519点\\x0520点\\x0521点\\x0522点\\x0523点\" +\n\t\"\\x0524点\\x02da\\x02au\\x02ov\\x02pc\\x02dm\\x02iu\\x06平成\\x06昭和\\x06大正\\x06明治\\x0c株\" +\n\t\"式会社\\x02pa\\x02na\\x02ma\\x02ka\\x02kb\\x02mb\\x02gb\\x04kcal\\x02pf\\x02nf\\x02m\" +\n\t\"g\\x02kg\\x02hz\\x02ml\\x02dl\\x02kl\\x02fm\\x02nm\\x02mm\\x02cm\\x02km\\x02m2\\x02m\" +\n\t\"3\\x05m∕s\\x06m∕s2\\x07rad∕s\\x08rad∕s2\\x02ps\\x02ns\\x02ms\\x02pv\\x02nv\\x02mv\" +\n\t\"\\x02kv\\x02pw\\x02nw\\x02mw\\x02kw\\x02bq\\x02cc\\x02cd\\x06c∕kg\\x02db\\x02gy\\x02\" +\n\t\"ha\\x02hp\\x02in\\x02kk\\x02kt\\x02lm\\x02ln\\x02lx\\x02ph\\x02pr\\x02sr\\x02sv\\x02\" +\n\t\"wb\\x05v∕m\\x05a∕m\\x041日\\x042日\\x043日\\x044日\\x045日\\x046日\\x047日\\x048日\\x049日\" +\n\t\"\\x0510日\\x0511日\\x0512日\\x0513日\\x0514日\\x0515日\\x0516日\\x0517日\\x0518日\\x0519日\" +\n\t\"\\x0520日\\x0521日\\x0522日\\x0523日\\x0524日\\x0525日\\x0526日\\x0527日\\x0528日\\x0529日\" +\n\t\"\\x0530日\\x0531日\\x02ь\\x02ɦ\\x02ɬ\\x02ʞ\\x02ʇ\\x02œ\\x04𤋮\\x04𢡊\\x04𢡄\\x04𣏕\\x04𥉉\" +\n\t\"\\x04𥳐\\x04𧻓\\x02ff\\x02fi\\x02fl\\x02st\\x04մն\\x04մե\\x04մի\\x04վն\\x04մխ\\x04יִ\" +\n\t\"\\x04ײַ\\x02ע\\x02ה\\x02כ\\x02ל\\x02ם\\x02ר\\x02ת\\x04שׁ\\x04שׂ\\x06שּׁ\\x06שּׂ\\x04א\" +\n\t\"ַ\\x04אָ\\x04אּ\\x04בּ\\x04גּ\\x04דּ\\x04הּ\\x04וּ\\x04זּ\\x04טּ\\x04יּ\\x04ךּ\\x04\" +\n\t\"כּ\\x04לּ\\x04מּ\\x04נּ\\x04סּ\\x04ףּ\\x04פּ\\x04צּ\\x04קּ\\x04רּ\\x04שּ\\x04תּ\" +\n\t\"\\x04וֹ\\x04בֿ\\x04כֿ\\x04פֿ\\x04אל\\x02ٱ\\x02ٻ\\x02پ\\x02ڀ\\x02ٺ\\x02ٿ\\x02ٹ\\x02ڤ\" +\n\t\"\\x02ڦ\\x02ڄ\\x02ڃ\\x02چ\\x02ڇ\\x02ڍ\\x02ڌ\\x02ڎ\\x02ڈ\\x02ژ\\x02ڑ\\x02ک\\x02گ\\x02ڳ\" +\n\t\"\\x02ڱ\\x02ں\\x02ڻ\\x02ۀ\\x02ہ\\x02ھ\\x02ے\\x02ۓ\\x02ڭ\\x02ۇ\\x02ۆ\\x02ۈ\\x02ۋ\\x02ۅ\" +\n\t\"\\x02ۉ\\x02ې\\x02ى\\x04ئا\\x04ئە\\x04ئو\\x04ئۇ\\x04ئۆ\\x04ئۈ\\x04ئې\\x04ئى\\x02ی\\x04\" +\n\t\"ئج\\x04ئح\\x04ئم\\x04ئي\\x04بج\\x04بح\\x04بخ\\x04بم\\x04بى\\x04بي\\x04تج\\x04تح\" +\n\t\"\\x04تخ\\x04تم\\x04تى\\x04تي\\x04ثج\\x04ثم\\x04ثى\\x04ثي\\x04جح\\x04جم\\x04حج\\x04حم\" +\n\t\"\\x04خج\\x04خح\\x04خم\\x04سج\\x04سح\\x04سخ\\x04سم\\x04صح\\x04صم\\x04ضج\\x04ضح\\x04ضخ\" +\n\t\"\\x04ضم\\x04طح\\x04طم\\x04ظم\\x04عج\\x04عم\\x04غج\\x04غم\\x04فج\\x04فح\\x04فخ\\x04فم\" +\n\t\"\\x04فى\\x04في\\x04قح\\x04قم\\x04قى\\x04قي\\x04كا\\x04كج\\x04كح\\x04كخ\\x04كل\\x04كم\" +\n\t\"\\x04كى\\x04كي\\x04لج\\x04لح\\x04لخ\\x04لم\\x04لى\\x04لي\\x04مج\\x04مح\\x04مخ\\x04مم\" +\n\t\"\\x04مى\\x04مي\\x04نج\\x04نح\\x04نخ\\x04نم\\x04نى\\x04ني\\x04هج\\x04هم\\x04هى\\x04هي\" +\n\t\"\\x04يج\\x04يح\\x04يخ\\x04يم\\x04يى\\x04يي\\x04ذٰ\\x04رٰ\\x04ىٰ\\x05 ٌّ\\x05 ٍّ\\x05\" +\n\t\" َّ\\x05 ُّ\\x05 ِّ\\x05 ّٰ\\x04ئر\\x04ئز\\x04ئن\\x04بر\\x04بز\\x04بن\\x04تر\\x04تز\" +\n\t\"\\x04تن\\x04ثر\\x04ثز\\x04ثن\\x04ما\\x04نر\\x04نز\\x04نن\\x04ير\\x04يز\\x04ين\\x04ئخ\" +\n\t\"\\x04ئه\\x04به\\x04ته\\x04صخ\\x04له\\x04نه\\x04هٰ\\x04يه\\x04ثه\\x04سه\\x04شم\\x04شه\" +\n\t\"\\x06ـَّ\\x06ـُّ\\x06ـِّ\\x04طى\\x04طي\\x04عى\\x04عي\\x04غى\\x04غي\\x04سى\\x04سي\" +\n\t\"\\x04شى\\x04شي\\x04حى\\x04حي\\x04جى\\x04جي\\x04خى\\x04خي\\x04صى\\x04صي\\x04ضى\\x04ضي\" +\n\t\"\\x04شج\\x04شح\\x04شخ\\x04شر\\x04سر\\x04صر\\x04ضر\\x04اً\\x06تجم\\x06تحج\\x06تحم\" +\n\t\"\\x06تخم\\x06تمج\\x06تمح\\x06تمخ\\x06جمح\\x06حمي\\x06حمى\\x06سحج\\x06سجح\\x06سجى\" +\n\t\"\\x06سمح\\x06سمج\\x06سمم\\x06صحح\\x06صمم\\x06شحم\\x06شجي\\x06شمخ\\x06شمم\\x06ضحى\" +\n\t\"\\x06ضخم\\x06طمح\\x06طمم\\x06طمي\\x06عجم\\x06عمم\\x06عمى\\x06غمم\\x06غمي\\x06غمى\" +\n\t\"\\x06فخم\\x06قمح\\x06قمم\\x06لحم\\x06لحي\\x06لحى\\x06لجج\\x06لخم\\x06لمح\\x06محج\" +\n\t\"\\x06محم\\x06محي\\x06مجح\\x06مجم\\x06مخج\\x06مخم\\x06مجخ\\x06همج\\x06همم\\x06نحم\" +\n\t\"\\x06نحى\\x06نجم\\x06نجى\\x06نمي\\x06نمى\\x06يمم\\x06بخي\\x06تجي\\x06تجى\\x06تخي\" +\n\t\"\\x06تخى\\x06تمي\\x06تمى\\x06جمي\\x06جحى\\x06جمى\\x06سخى\\x06صحي\\x06شحي\\x06ضحي\" +\n\t\"\\x06لجي\\x06لمي\\x06يحي\\x06يجي\\x06يمي\\x06ممي\\x06قمي\\x06نحي\\x06عمي\\x06كمي\" +\n\t\"\\x06نجح\\x06مخي\\x06لجم\\x06كمم\\x06جحي\\x06حجي\\x06مجي\\x06فمي\\x06بحي\\x06سخي\" +\n\t\"\\x06نجي\\x06صلے\\x06قلے\\x08الله\\x08اكبر\\x08محمد\\x08صلعم\\x08رسول\\x08عليه\" +\n\t\"\\x08وسلم\\x06صلى!صلى الله عليه وسلم\\x0fجل جلاله\\x08ریال\\x01,\\x01:\\x01!\" +\n\t\"\\x01?\\x01_\\x01{\\x01}\\x01[\\x01]\\x01#\\x01&\\x01*\\x01-\\x01<\\x01>\\x01\\\\\\x01$\" +\n\t\"\\x01%\\x01@\\x04ـً\\x04ـَ\\x04ـُ\\x04ـِ\\x04ـّ\\x04ـْ\\x02ء\\x02آ\\x02أ\\x02ؤ\\x02إ\" +\n\t\"\\x02ئ\\x02ا\\x02ب\\x02ة\\x02ت\\x02ث\\x02ج\\x02ح\\x02خ\\x02د\\x02ذ\\x02ر\\x02ز\\x02س\" +\n\t\"\\x02ش\\x02ص\\x02ض\\x02ط\\x02ظ\\x02ع\\x02غ\\x02ف\\x02ق\\x02ك\\x02ل\\x02م\\x02ن\\x02ه\" +\n\t\"\\x02و\\x02ي\\x04لآ\\x04لأ\\x04لإ\\x04لا\\x01\\x22\\x01'\\x01/\\x01^\\x01|\\x01~\\x02¢\" +\n\t\"\\x02£\\x02¬\\x02¦\\x02¥\\x08𝅗𝅥\\x08𝅘𝅥\\x0c𝅘𝅥𝅮\\x0c𝅘𝅥𝅯\\x0c𝅘𝅥𝅰\\x0c𝅘𝅥𝅱\\x0c𝅘𝅥𝅲\\x08𝆹\" +\n\t\"𝅥\\x08𝆺𝅥\\x0c𝆹𝅥𝅮\\x0c𝆺𝅥𝅮\\x0c𝆹𝅥𝅯\\x0c𝆺𝅥𝅯\\x02ı\\x02ȷ\\x02α\\x02ε\\x02ζ\\x02η\\x02\" +\n\t\"κ\\x02λ\\x02μ\\x02ν\\x02ξ\\x02ο\\x02σ\\x02τ\\x02υ\\x02ψ\\x03∇\\x03∂\\x02ϝ\\x02ٮ\\x02ڡ\" +\n\t\"\\x02ٯ\\x020,\\x021,\\x022,\\x023,\\x024,\\x025,\\x026,\\x027,\\x028,\\x029,\\x03(a)\" +\n\t\"\\x03(b)\\x03(c)\\x03(d)\\x03(e)\\x03(f)\\x03(g)\\x03(h)\\x03(i)\\x03(j)\\x03(k)\" +\n\t\"\\x03(l)\\x03(m)\\x03(n)\\x03(o)\\x03(p)\\x03(q)\\x03(r)\\x03(s)\\x03(t)\\x03(u)\" +\n\t\"\\x03(v)\\x03(w)\\x03(x)\\x03(y)\\x03(z)\\x07〔s〕\\x02wz\\x02hv\\x02sd\\x03ppv\\x02w\" +\n\t\"c\\x02mc\\x02md\\x02mr\\x02dj\\x06ほか\\x06ココ\\x03サ\\x03手\\x03字\\x03双\\x03デ\\x03二\\x03多\" +\n\t\"\\x03解\\x03天\\x03交\\x03映\\x03無\\x03料\\x03前\\x03後\\x03再\\x03新\\x03初\\x03終\\x03生\\x03販\" +\n\t\"\\x03声\\x03吹\\x03演\\x03投\\x03捕\\x03一\\x03三\\x03遊\\x03左\\x03中\\x03右\\x03指\\x03走\\x03打\" +\n\t\"\\x03禁\\x03空\\x03合\\x03満\\x03有\\x03月\\x03申\\x03割\\x03営\\x03配\\x09〔本〕\\x09〔三〕\\x09〔二〕\" +\n\t\"\\x09〔安〕\\x09〔点〕\\x09〔打〕\\x09〔盗〕\\x09〔勝〕\\x09〔敗〕\\x03得\\x03可\\x03丽\\x03丸\\x03乁\\x03你\" +\n\t\"\\x03侮\\x03侻\\x03倂\\x03偺\\x03備\\x03僧\\x03像\\x03㒞\\x03免\\x03兔\\x03兤\\x03具\\x03㒹\\x03內\" +\n\t\"\\x03冗\\x03冤\\x03仌\\x03冬\\x03况\\x03凵\\x03刃\\x03㓟\\x03刻\\x03剆\\x03剷\\x03㔕\\x03勇\\x03勉\" +\n\t\"\\x03勤\\x03勺\\x03包\\x03匆\\x03北\\x03卉\\x03卑\\x03博\\x03即\\x03卽\\x03卿\\x03灰\\x03及\\x03叟\" +\n\t\"\\x03叫\\x03叱\\x03吆\\x03咞\\x03吸\\x03呈\\x03周\\x03咢\\x03哶\\x03唐\\x03啓\\x03啣\\x03善\\x03喙\" +\n\t\"\\x03喫\\x03喳\\x03嗂\\x03圖\\x03嘆\\x03圗\\x03噑\\x03噴\\x03切\\x03壮\\x03城\\x03埴\\x03堍\\x03型\" +\n\t\"\\x03堲\\x03報\\x03墬\\x03売\\x03壷\\x03夆\\x03夢\\x03奢\\x03姬\\x03娛\\x03娧\\x03姘\\x03婦\\x03㛮\" +\n\t\"\\x03嬈\\x03嬾\\x03寃\\x03寘\\x03寧\\x03寳\\x03寿\\x03将\\x03尢\\x03㞁\\x03屠\\x03屮\\x03峀\\x03岍\" +\n\t\"\\x03嵃\\x03嵮\\x03嵫\\x03嵼\\x03巡\\x03巢\\x03㠯\\x03巽\\x03帨\\x03帽\\x03幩\\x03㡢\\x03㡼\\x03庰\" +\n\t\"\\x03庳\\x03庶\\x03廊\\x03廾\\x03舁\\x03弢\\x03㣇\\x03形\\x03彫\\x03㣣\\x03徚\\x03忍\\x03志\\x03忹\" +\n\t\"\\x03悁\\x03㤺\\x03㤜\\x03悔\\x03惇\\x03慈\\x03慌\\x03慎\\x03慺\\x03憎\\x03憲\\x03憤\\x03憯\\x03懞\" +\n\t\"\\x03懲\\x03懶\\x03成\\x03戛\\x03扝\\x03抱\\x03拔\\x03捐\\x03挽\\x03拼\\x03捨\\x03掃\\x03揤\\x03搢\" +\n\t\"\\x03揅\\x03掩\\x03㨮\\x03摩\\x03摾\\x03撝\\x03摷\\x03㩬\\x03敏\\x03敬\\x03旣\\x03書\\x03晉\\x03㬙\" +\n\t\"\\x03暑\\x03㬈\\x03㫤\\x03冒\\x03冕\\x03最\\x03暜\\x03肭\\x03䏙\\x03朗\\x03望\\x03朡\\x03杞\\x03杓\" +\n\t\"\\x03㭉\\x03柺\\x03枅\\x03桒\\x03梅\\x03梎\\x03栟\\x03椔\\x03㮝\\x03楂\\x03榣\\x03槪\\x03檨\\x03櫛\" +\n\t\"\\x03㰘\\x03次\\x03歔\\x03㱎\\x03歲\\x03殟\\x03殺\\x03殻\\x03汎\\x03沿\\x03泍\\x03汧\\x03洖\\x03派\" +\n\t\"\\x03海\\x03流\\x03浩\\x03浸\\x03涅\\x03洴\\x03港\\x03湮\\x03㴳\\x03滋\\x03滇\\x03淹\\x03潮\\x03濆\" +\n\t\"\\x03瀹\\x03瀞\\x03瀛\\x03㶖\\x03灊\\x03災\\x03灷\\x03炭\\x03煅\\x03熜\\x03爨\\x03爵\\x03牐\\x03犀\" +\n\t\"\\x03犕\\x03獺\\x03王\\x03㺬\\x03玥\\x03㺸\\x03瑇\\x03瑜\\x03瑱\\x03璅\\x03瓊\\x03㼛\\x03甤\\x03甾\" +\n\t\"\\x03異\\x03瘐\\x03㿼\\x03䀈\\x03直\\x03眞\\x03真\\x03睊\\x03䀹\\x03瞋\\x03䁆\\x03䂖\\x03硎\\x03碌\" +\n\t\"\\x03磌\\x03䃣\\x03祖\\x03福\\x03秫\\x03䄯\\x03穀\\x03穊\\x03穏\\x03䈂\\x03篆\\x03築\\x03䈧\\x03糒\" +\n\t\"\\x03䊠\\x03糨\\x03糣\\x03紀\\x03絣\\x03䌁\\x03緇\\x03縂\\x03繅\\x03䌴\\x03䍙\\x03罺\\x03羕\\x03翺\" +\n\t\"\\x03者\\x03聠\\x03聰\\x03䏕\\x03育\\x03脃\\x03䐋\\x03脾\\x03媵\\x03舄\\x03辞\\x03䑫\\x03芑\\x03芋\" +\n\t\"\\x03芝\\x03劳\\x03花\\x03芳\\x03芽\\x03苦\\x03若\\x03茝\\x03荣\\x03莭\\x03茣\\x03莽\\x03菧\\x03著\" +\n\t\"\\x03荓\\x03菊\\x03菌\\x03菜\\x03䔫\\x03蓱\\x03蓳\\x03蔖\\x03蕤\\x03䕝\\x03䕡\\x03䕫\\x03虐\\x03虜\" +\n\t\"\\x03虧\\x03虩\\x03蚩\\x03蚈\\x03蜎\\x03蛢\\x03蝹\\x03蜨\\x03蝫\\x03螆\\x03蟡\\x03蠁\\x03䗹\\x03衠\" +\n\t\"\\x03衣\\x03裗\\x03裞\\x03䘵\\x03裺\\x03㒻\\x03䚾\\x03䛇\\x03誠\\x03諭\\x03變\\x03豕\\x03貫\\x03賁\" +\n\t\"\\x03贛\\x03起\\x03跋\\x03趼\\x03跰\\x03軔\\x03輸\\x03邔\\x03郱\\x03鄑\\x03鄛\\x03鈸\\x03鋗\\x03鋘\" +\n\t\"\\x03鉼\\x03鏹\\x03鐕\\x03開\\x03䦕\\x03閷\\x03䧦\\x03雃\\x03嶲\\x03霣\\x03䩮\\x03䩶\\x03韠\\x03䪲\" +\n\t\"\\x03頋\\x03頩\\x03飢\\x03䬳\\x03餩\\x03馧\\x03駂\\x03駾\\x03䯎\\x03鬒\\x03鱀\\x03鳽\\x03䳎\\x03䳭\" +\n\t\"\\x03鵧\\x03䳸\\x03麻\\x03䵖\\x03黹\\x03黾\\x03鼅\\x03鼏\\x03鼖\\x03鼻\"\n\nvar xorData string = \"\" + // Size: 4862 bytes\n\t\"\\x02\\x0c\\x09\\x02\\xb0\\xec\\x02\\xad\\xd8\\x02\\xad\\xd9\\x02\\x06\\x07\\x02\\x0f\\x12\" +\n\t\"\\x02\\x0f\\x1f\\x02\\x0f\\x1d\\x02\\x01\\x13\\x02\\x0f\\x16\\x02\\x0f\\x0b\\x02\\x0f3\" +\n\t\"\\x02\\x0f7\\x02\\x0f?\\x02\\x0f/\\x02\\x0f*\\x02\\x0c&\\x02\\x0c*\\x02\\x0c;\\x02\\x0c9\" +\n\t\"\\x02\\x0c%\\x02\\xab\\xed\\x02\\xab\\xe2\\x02\\xab\\xe3\\x02\\xa9\\xe0\\x02\\xa9\\xe1\" +\n\t\"\\x02\\xa9\\xe6\\x02\\xa3\\xcb\\x02\\xa3\\xc8\\x02\\xa3\\xc9\\x02\\x01#\\x02\\x01\\x08\" +\n\t\"\\x02\\x0e>\\x02\\x0e'\\x02\\x0f\\x03\\x02\\x03\\x0d\\x02\\x03\\x09\\x02\\x03\\x17\\x02\" +\n\t\"\\x03\\x0e\\x02\\x02\\x03\\x02\\x011\\x02\\x01\\x00\\x02\\x01\\x10\\x02\\x03<\\x02\\x07\" +\n\t\"\\x0d\\x02\\x02\\x0c\\x02\\x0c0\\x02\\x01\\x03\\x02\\x01\\x01\\x02\\x01 \\x02\\x01\\x22\" +\n\t\"\\x02\\x01)\\x02\\x01\\x0a\\x02\\x01\\x0c\\x02\\x02\\x06\\x02\\x02\\x02\\x02\\x03\\x10\" +\n\t\"\\x03\\x037 \\x03\\x0b+\\x03\\x021\\x00\\x02\\x01\\x04\\x02\\x01\\x02\\x02\\x019\\x02\" +\n\t\"\\x03\\x1c\\x02\\x02$\\x03\\x80p$\\x02\\x03:\\x02\\x03\\x0a\\x03\\xc1r.\\x03\\xc1r,\\x03\" +\n\t\"\\xc1r\\x02\\x02\\x02:\\x02\\x02>\\x02\\x02,\\x02\\x02\\x10\\x02\\x02\\x00\\x03\\xc1s<\" +\n\t\"\\x03\\xc1s*\\x03\\xc2L$\\x03\\xc2L;\\x02\\x09)\\x02\\x0a\\x19\\x03\\x83\\xab\\xe3\\x03\" +\n\t\"\\x83\\xab\\xf2\\x03 4\\xe0\\x03\\x81\\xab\\xea\\x03\\x81\\xab\\xf3\\x03 4\\xef\\x03\\x96\" +\n\t\"\\xe1\\xcd\\x03\\x84\\xe5\\xc3\\x02\\x0d\\x11\\x03\\x8b\\xec\\xcb\\x03\\x94\\xec\\xcf\\x03\" +\n\t\"\\x9a\\xec\\xc2\\x03\\x8b\\xec\\xdb\\x03\\x94\\xec\\xdf\\x03\\x9a\\xec\\xd2\\x03\\x01\\x0c\" +\n\t\"!\\x03\\x01\\x0c#\\x03ʠ\\x9d\\x03ʣ\\x9c\\x03ʢ\\x9f\\x03ʥ\\x9e\\x03ʤ\\x91\\x03ʧ\\x90\\x03\" +\n\t\"ʦ\\x93\\x03ʩ\\x92\\x03ʨ\\x95\\x03\\xca\\xf3\\xb5\\x03\\xca\\xf0\\xb4\\x03\\xca\\xf1\\xb7\" +\n\t\"\\x03\\xca\\xf6\\xb6\\x03\\xca\\xf7\\x89\\x03\\xca\\xf4\\x88\\x03\\xca\\xf5\\x8b\\x03\\xca\" +\n\t\"\\xfa\\x8a\\x03\\xca\\xfb\\x8d\\x03\\xca\\xf8\\x8c\\x03\\xca\\xf9\\x8f\\x03\\xca\\xfe\\x8e\" +\n\t\"\\x03\\xca\\xff\\x81\\x03\\xca\\xfc\\x80\\x03\\xca\\xfd\\x83\\x03\\xca\\xe2\\x82\\x03\\xca\" +\n\t\"\\xe3\\x85\\x03\\xca\\xe0\\x84\\x03\\xca\\xe1\\x87\\x03\\xca\\xe6\\x86\\x03\\xca\\xe7\\x99\" +\n\t\"\\x03\\xca\\xe4\\x98\\x03\\xca\\xe5\\x9b\\x03\\xca\\xea\\x9a\\x03\\xca\\xeb\\x9d\\x03\\xca\" +\n\t\"\\xe8\\x9c\\x03ؓ\\x89\\x03ߔ\\x8b\\x02\\x010\\x03\\x03\\x04\\x1e\\x03\\x04\\x15\\x12\\x03\" +\n\t\"\\x0b\\x05,\\x03\\x06\\x04\\x00\\x03\\x06\\x04)\\x03\\x06\\x044\\x03\\x06\\x04<\\x03\\x06\" +\n\t\"\\x05\\x1d\\x03\\x06\\x06\\x00\\x03\\x06\\x06\\x0a\\x03\\x06\\x06'\\x03\\x06\\x062\\x03\" +\n\t\"\\x0786\\x03\\x079/\\x03\\x079 \\x03\\x07:\\x0e\\x03\\x07:\\x1b\\x03\\x07:%\\x03\\x07;/\" +\n\t\"\\x03\\x07;%\\x03\\x074\\x11\\x03\\x076\\x09\\x03\\x077*\\x03\\x070\\x01\\x03\\x070\\x0f\" +\n\t\"\\x03\\x070.\\x03\\x071\\x16\\x03\\x071\\x04\\x03\\x0710\\x03\\x072\\x18\\x03\\x072-\" +\n\t\"\\x03\\x073\\x14\\x03\\x073>\\x03\\x07'\\x09\\x03\\x07 \\x00\\x03\\x07\\x1f\\x0b\\x03\" +\n\t\"\\x07\\x18#\\x03\\x07\\x18(\\x03\\x07\\x186\\x03\\x07\\x18\\x03\\x03\\x07\\x19\\x16\\x03\" +\n\t\"\\x07\\x116\\x03\\x07\\x12'\\x03\\x07\\x13\\x10\\x03\\x07\\x0c&\\x03\\x07\\x0c\\x08\\x03\" +\n\t\"\\x07\\x0c\\x13\\x03\\x07\\x0d\\x02\\x03\\x07\\x0d\\x1c\\x03\\x07\\x0b5\\x03\\x07\\x0b\" +\n\t\"\\x0a\\x03\\x07\\x0b\\x01\\x03\\x07\\x0b\\x0f\\x03\\x07\\x05\\x00\\x03\\x07\\x05\\x09\\x03\" +\n\t\"\\x07\\x05\\x0b\\x03\\x07\\x07\\x01\\x03\\x07\\x07\\x08\\x03\\x07\\x00<\\x03\\x07\\x00+\" +\n\t\"\\x03\\x07\\x01)\\x03\\x07\\x01\\x1b\\x03\\x07\\x01\\x08\\x03\\x07\\x03?\\x03\\x0445\\x03\" +\n\t\"\\x044\\x08\\x03\\x0454\\x03\\x04)/\\x03\\x04)5\\x03\\x04+\\x05\\x03\\x04+\\x14\\x03\" +\n\t\"\\x04+ \\x03\\x04+<\\x03\\x04*&\\x03\\x04*\\x22\\x03\\x04&8\\x03\\x04!\\x01\\x03\\x04!\" +\n\t\"\\x22\\x03\\x04\\x11+\\x03\\x04\\x10.\\x03\\x04\\x104\\x03\\x04\\x13=\\x03\\x04\\x12\\x04\" +\n\t\"\\x03\\x04\\x12\\x0a\\x03\\x04\\x0d\\x1d\\x03\\x04\\x0d\\x07\\x03\\x04\\x0d \\x03\\x05<>\" +\n\t\"\\x03\\x055<\\x03\\x055!\\x03\\x055#\\x03\\x055&\\x03\\x054\\x1d\\x03\\x054\\x02\\x03\" +\n\t\"\\x054\\x07\\x03\\x0571\\x03\\x053\\x1a\\x03\\x053\\x16\\x03\\x05.<\\x03\\x05.\\x07\\x03\" +\n\t\"\\x05):\\x03\\x05)<\\x03\\x05)\\x0c\\x03\\x05)\\x15\\x03\\x05+-\\x03\\x05+5\\x03\\x05$\" +\n\t\"\\x1e\\x03\\x05$\\x14\\x03\\x05'\\x04\\x03\\x05'\\x14\\x03\\x05&\\x02\\x03\\x05\\x226\" +\n\t\"\\x03\\x05\\x22\\x0c\\x03\\x05\\x22\\x1c\\x03\\x05\\x19\\x0a\\x03\\x05\\x1b\\x09\\x03\\x05\" +\n\t\"\\x1b\\x0c\\x03\\x05\\x14\\x07\\x03\\x05\\x16?\\x03\\x05\\x16\\x0c\\x03\\x05\\x0c\\x05\" +\n\t\"\\x03\\x05\\x0e\\x0f\\x03\\x05\\x01\\x0e\\x03\\x05\\x00(\\x03\\x05\\x030\\x03\\x05\\x03\" +\n\t\"\\x06\\x03\\x0a==\\x03\\x0a=1\\x03\\x0a=,\\x03\\x0a=\\x0c\\x03\\x0a??\\x03\\x0a<\\x08\" +\n\t\"\\x03\\x0a9!\\x03\\x0a9)\\x03\\x0a97\\x03\\x0a99\\x03\\x0a6\\x0a\\x03\\x0a6\\x1c\\x03\" +\n\t\"\\x0a6\\x17\\x03\\x0a7'\\x03\\x0a78\\x03\\x0a73\\x03\\x0a'\\x01\\x03\\x0a'&\\x03\\x0a\" +\n\t\"\\x1f\\x0e\\x03\\x0a\\x1f\\x03\\x03\\x0a\\x1f3\\x03\\x0a\\x1b/\\x03\\x0a\\x18\\x19\\x03\" +\n\t\"\\x0a\\x19\\x01\\x03\\x0a\\x16\\x14\\x03\\x0a\\x0e\\x22\\x03\\x0a\\x0f\\x10\\x03\\x0a\\x0f\" +\n\t\"\\x02\\x03\\x0a\\x0f \\x03\\x0a\\x0c\\x04\\x03\\x0a\\x0b>\\x03\\x0a\\x0b+\\x03\\x0a\\x08/\" +\n\t\"\\x03\\x0a\\x046\\x03\\x0a\\x05\\x14\\x03\\x0a\\x00\\x04\\x03\\x0a\\x00\\x10\\x03\\x0a\" +\n\t\"\\x00\\x14\\x03\\x0b<3\\x03\\x0b;*\\x03\\x0b9\\x22\\x03\\x0b9)\\x03\\x0b97\\x03\\x0b+\" +\n\t\"\\x10\\x03\\x0b((\\x03\\x0b&5\\x03\\x0b$\\x1c\\x03\\x0b$\\x12\\x03\\x0b%\\x04\\x03\\x0b#\" +\n\t\"<\\x03\\x0b#0\\x03\\x0b#\\x0d\\x03\\x0b#\\x19\\x03\\x0b!:\\x03\\x0b!\\x1f\\x03\\x0b!\" +\n\t\"\\x00\\x03\\x0b\\x1e5\\x03\\x0b\\x1c\\x1d\\x03\\x0b\\x1d-\\x03\\x0b\\x1d(\\x03\\x0b\\x18.\" +\n\t\"\\x03\\x0b\\x18 \\x03\\x0b\\x18\\x16\\x03\\x0b\\x14\\x13\\x03\\x0b\\x15$\\x03\\x0b\\x15\" +\n\t\"\\x22\\x03\\x0b\\x12\\x1b\\x03\\x0b\\x12\\x10\\x03\\x0b\\x132\\x03\\x0b\\x13=\\x03\\x0b\" +\n\t\"\\x12\\x18\\x03\\x0b\\x0c&\\x03\\x0b\\x061\\x03\\x0b\\x06:\\x03\\x0b\\x05#\\x03\\x0b\\x05\" +\n\t\"<\\x03\\x0b\\x04\\x0b\\x03\\x0b\\x04\\x04\\x03\\x0b\\x04\\x1b\\x03\\x0b\\x042\\x03\\x0b\" +\n\t\"\\x041\\x03\\x0b\\x03\\x03\\x03\\x0b\\x03\\x1d\\x03\\x0b\\x03/\\x03\\x0b\\x03+\\x03\\x0b\" +\n\t\"\\x02\\x1b\\x03\\x0b\\x02\\x00\\x03\\x0b\\x01\\x1e\\x03\\x0b\\x01\\x08\\x03\\x0b\\x015\" +\n\t\"\\x03\\x06\\x0d9\\x03\\x06\\x0d=\\x03\\x06\\x0d?\\x03\\x02\\x001\\x03\\x02\\x003\\x03\" +\n\t\"\\x02\\x02\\x19\\x03\\x02\\x006\\x03\\x02\\x02\\x1b\\x03\\x02\\x004\\x03\\x02\\x00<\\x03\" +\n\t\"\\x02\\x02\\x0a\\x03\\x02\\x02\\x0e\\x03\\x02\\x01\\x1a\\x03\\x02\\x01\\x07\\x03\\x02\\x01\" +\n\t\"\\x05\\x03\\x02\\x01\\x0b\\x03\\x02\\x01%\\x03\\x02\\x01\\x0c\\x03\\x02\\x01\\x04\\x03\" +\n\t\"\\x02\\x01\\x1c\\x03\\x02\\x00.\\x03\\x02\\x002\\x03\\x02\\x00>\\x03\\x02\\x00\\x12\\x03\" +\n\t\"\\x02\\x00\\x16\\x03\\x02\\x011\\x03\\x02\\x013\\x03\\x02\\x02 \\x03\\x02\\x02%\\x03\\x02\" +\n\t\"\\x02$\\x03\\x02\\x028\\x03\\x02\\x02;\\x03\\x02\\x024\\x03\\x02\\x012\\x03\\x02\\x022\" +\n\t\"\\x03\\x02\\x02/\\x03\\x02\\x01,\\x03\\x02\\x01\\x13\\x03\\x02\\x01\\x16\\x03\\x02\\x01\" +\n\t\"\\x11\\x03\\x02\\x01\\x1e\\x03\\x02\\x01\\x15\\x03\\x02\\x01\\x17\\x03\\x02\\x01\\x0f\\x03\" +\n\t\"\\x02\\x01\\x08\\x03\\x02\\x00?\\x03\\x02\\x03\\x07\\x03\\x02\\x03\\x0d\\x03\\x02\\x03\" +\n\t\"\\x13\\x03\\x02\\x03\\x1d\\x03\\x02\\x03\\x1f\\x03\\x02\\x00\\x03\\x03\\x02\\x00\\x0d\\x03\" +\n\t\"\\x02\\x00\\x01\\x03\\x02\\x00\\x1b\\x03\\x02\\x00\\x19\\x03\\x02\\x00\\x18\\x03\\x02\\x00\" +\n\t\"\\x13\\x03\\x02\\x00/\\x03\\x07>\\x12\\x03\\x07<\\x1f\\x03\\x07>\\x1d\\x03\\x06\\x1d\\x0e\" +\n\t\"\\x03\\x07>\\x1c\\x03\\x07>:\\x03\\x07>\\x13\\x03\\x04\\x12+\\x03\\x07?\\x03\\x03\\x07>\" +\n\t\"\\x02\\x03\\x06\\x224\\x03\\x06\\x1a.\\x03\\x07<%\\x03\\x06\\x1c\\x0b\\x03\\x0609\\x03\" +\n\t\"\\x05\\x1f\\x01\\x03\\x04'\\x08\\x03\\x93\\xfd\\xf5\\x03\\x02\\x0d \\x03\\x02\\x0d#\\x03\" +\n\t\"\\x02\\x0d!\\x03\\x02\\x0d&\\x03\\x02\\x0d\\x22\\x03\\x02\\x0d/\\x03\\x02\\x0d,\\x03\\x02\" +\n\t\"\\x0d$\\x03\\x02\\x0d'\\x03\\x02\\x0d%\\x03\\x02\\x0d;\\x03\\x02\\x0d=\\x03\\x02\\x0d?\" +\n\t\"\\x03\\x099.\\x03\\x08\\x0b7\\x03\\x08\\x02\\x14\\x03\\x08\\x14\\x0d\\x03\\x08.:\\x03\" +\n\t\"\\x089'\\x03\\x0f\\x0b\\x18\\x03\\x0f\\x1c1\\x03\\x0f\\x17&\\x03\\x0f9\\x1f\\x03\\x0f0\" +\n\t\"\\x0c\\x03\\x0e\\x0a9\\x03\\x0e\\x056\\x03\\x0e\\x1c#\\x03\\x0f\\x13\\x0e\\x03\\x072\\x00\" +\n\t\"\\x03\\x070\\x0d\\x03\\x072\\x0b\\x03\\x06\\x11\\x18\\x03\\x070\\x10\\x03\\x06\\x0f(\\x03\" +\n\t\"\\x072\\x05\\x03\\x06\\x0f,\\x03\\x073\\x15\\x03\\x06\\x07\\x08\\x03\\x05\\x16\\x02\\x03\" +\n\t\"\\x04\\x0b \\x03\\x05:8\\x03\\x05\\x16%\\x03\\x0a\\x0d\\x1f\\x03\\x06\\x16\\x10\\x03\\x05\" +\n\t\"\\x1d5\\x03\\x05*;\\x03\\x05\\x16\\x1b\\x03\\x04.-\\x03\\x06\\x1a\\x19\\x03\\x04\\x03,\" +\n\t\"\\x03\\x0b87\\x03\\x04/\\x0a\\x03\\x06\\x00,\\x03\\x04-\\x01\\x03\\x04\\x1e-\\x03\\x06/(\" +\n\t\"\\x03\\x0a\\x0b5\\x03\\x06\\x0e7\\x03\\x06\\x07.\\x03\\x0597\\x03\\x0a*%\\x03\\x0760\" +\n\t\"\\x03\\x06\\x0c;\\x03\\x05'\\x00\\x03\\x072.\\x03\\x072\\x08\\x03\\x06=\\x01\\x03\\x06\" +\n\t\"\\x05\\x1b\\x03\\x06\\x06\\x12\\x03\\x06$=\\x03\\x06'\\x0d\\x03\\x04\\x11\\x0f\\x03\\x076\" +\n\t\",\\x03\\x06\\x07;\\x03\\x06.,\\x03\\x86\\xf9\\xea\\x03\\x8f\\xff\\xeb\\x02\\x092\\x02\" +\n\t\"\\x095\\x02\\x094\\x02\\x09;\\x02\\x09>\\x02\\x098\\x02\\x09*\\x02\\x09/\\x02\\x09,\\x02\" +\n\t\"\\x09%\\x02\\x09&\\x02\\x09#\\x02\\x09 \\x02\\x08!\\x02\\x08%\\x02\\x08$\\x02\\x08+\\x02\" +\n\t\"\\x08.\\x02\\x08*\\x02\\x08&\\x02\\x088\\x02\\x08>\\x02\\x084\\x02\\x086\\x02\\x080\\x02\" +\n\t\"\\x08\\x10\\x02\\x08\\x17\\x02\\x08\\x12\\x02\\x08\\x1d\\x02\\x08\\x1f\\x02\\x08\\x13\\x02\" +\n\t\"\\x08\\x15\\x02\\x08\\x14\\x02\\x08\\x0c\\x03\\x8b\\xfd\\xd0\\x03\\x81\\xec\\xc6\\x03\\x87\" +\n\t\"\\xe0\\x8a\\x03-2\\xe3\\x03\\x80\\xef\\xe4\\x03-2\\xea\\x03\\x88\\xe6\\xeb\\x03\\x8e\\xe6\" +\n\t\"\\xe8\\x03\\x84\\xe6\\xe9\\x03\\x97\\xe6\\xee\\x03-2\\xf9\\x03-2\\xf6\\x03\\x8e\\xe3\\xad\" +\n\t\"\\x03\\x80\\xe3\\x92\\x03\\x88\\xe3\\x90\\x03\\x8e\\xe3\\x90\\x03\\x80\\xe3\\x97\\x03\\x88\" +\n\t\"\\xe3\\x95\\x03\\x88\\xfe\\xcb\\x03\\x8e\\xfe\\xca\\x03\\x84\\xfe\\xcd\\x03\\x91\\xef\\xc9\" +\n\t\"\\x03-2\\xc1\\x03-2\\xc0\\x03-2\\xcb\\x03\\x88@\\x09\\x03\\x8e@\\x08\\x03\\x8f\\xe0\\xf5\" +\n\t\"\\x03\\x8e\\xe6\\xf9\\x03\\x8e\\xe0\\xfa\\x03\\x93\\xff\\xf4\\x03\\x84\\xee\\xd3\\x03\\x0b\" +\n\t\"(\\x04\\x023 \\x03\\x0b)\\x08\\x021;\\x02\\x01*\\x03\\x0b#\\x10\\x03\\x0b 0\\x03\\x0b!\" +\n\t\"\\x10\\x03\\x0b!0\\x03\\x07\\x15\\x08\\x03\\x09?5\\x03\\x07\\x1f\\x08\\x03\\x07\\x17\\x0b\" +\n\t\"\\x03\\x09\\x1f\\x15\\x03\\x0b\\x1c7\\x03\\x0a+#\\x03\\x06\\x1a\\x1b\\x03\\x06\\x1a\\x14\" +\n\t\"\\x03\\x0a\\x01\\x18\\x03\\x06#\\x1b\\x03\\x0a2\\x0c\\x03\\x0a\\x01\\x04\\x03\\x09#;\\x03\" +\n\t\"\\x08='\\x03\\x08\\x1a\\x0a\\x03\\x07</\\x03\\x07:+\\x03\\x07\\x07*\\x03\\x06&\\x1c\\x03\" +\n\t\"\\x09\\x0c\\x16\\x03\\x09\\x10\\x0e\\x03\\x08'\\x0f\\x03\\x08+\\x09\\x03\\x074%\\x03\\x06\" +\n\t\"!3\\x03\\x06\\x03+\\x03\\x0b\\x1e\\x19\\x03\\x0a))\\x03\\x09\\x08\\x19\\x03\\x08,\\x05\" +\n\t\"\\x03\\x07<2\\x03\\x06\\x1c>\\x03\\x0a\\x111\\x03\\x09\\x1b\\x09\\x03\\x073.\\x03\\x07\" +\n\t\"\\x01\\x00\\x03\\x09/,\\x03\\x07#>\\x03\\x07\\x048\\x03\\x0a\\x1f\\x22\\x03\\x098>\\x03\" +\n\t\"\\x09\\x11\\x00\\x03\\x08/\\x17\\x03\\x06'\\x22\\x03\\x0b\\x1a+\\x03\\x0a\\x22\\x19\\x03\" +\n\t\"\\x0a/1\\x03\\x0974\\x03\\x09\\x0f\\x22\\x03\\x08,\\x22\\x03\\x08?\\x14\\x03\\x07$5\\x03\" +\n\t\"\\x07<3\\x03\\x07=*\\x03\\x07\\x13\\x18\\x03\\x068\\x0a\\x03\\x06\\x09\\x16\\x03\\x06\" +\n\t\"\\x13\\x00\\x03\\x08\\x067\\x03\\x08\\x01\\x03\\x03\\x08\\x12\\x1d\\x03\\x07+7\\x03\\x06(\" +\n\t\";\\x03\\x06\\x1c?\\x03\\x07\\x0e\\x17\\x03\\x0a\\x06\\x1d\\x03\\x0a\\x19\\x07\\x03\\x08\" +\n\t\"\\x14$\\x03\\x07$;\\x03\\x08,$\\x03\\x08\\x06\\x0d\\x03\\x07\\x16\\x0a\\x03\\x06>>\\x03\" +\n\t\"\\x0a\\x06\\x12\\x03\\x0a\\x14)\\x03\\x09\\x0d\\x1f\\x03\\x09\\x12\\x17\\x03\\x09\\x19\" +\n\t\"\\x01\\x03\\x08\\x11 \\x03\\x08\\x1d'\\x03\\x06<\\x1a\\x03\\x0a.\\x00\\x03\\x07'\\x18\" +\n\t\"\\x03\\x0a\\x22\\x08\\x03\\x08\\x0d\\x0a\\x03\\x08\\x13)\\x03\\x07*)\\x03\\x06<,\\x03\" +\n\t\"\\x07\\x0b\\x1a\\x03\\x09.\\x14\\x03\\x09\\x0d\\x1e\\x03\\x07\\x0e#\\x03\\x0b\\x1d'\\x03\" +\n\t\"\\x0a\\x0a8\\x03\\x09%2\\x03\\x08+&\\x03\\x080\\x12\\x03\\x0a)4\\x03\\x08\\x06\\x1f\\x03\" +\n\t\"\\x0b\\x1b\\x1a\\x03\\x0a\\x1b\\x0f\\x03\\x0b\\x1d*\\x03\\x09\\x16$\\x03\\x090\\x11\\x03\" +\n\t\"\\x08\\x11\\x08\\x03\\x0a*(\\x03\\x0a\\x042\\x03\\x089,\\x03\\x074'\\x03\\x07\\x0f\\x05\" +\n\t\"\\x03\\x09\\x0b\\x0a\\x03\\x07\\x1b\\x01\\x03\\x09\\x17:\\x03\\x09.\\x0d\\x03\\x07.\\x11\" +\n\t\"\\x03\\x09+\\x15\\x03\\x080\\x13\\x03\\x0b\\x1f\\x19\\x03\\x0a \\x11\\x03\\x0a\\x220\\x03\" +\n\t\"\\x09\\x07;\\x03\\x08\\x16\\x1c\\x03\\x07,\\x13\\x03\\x07\\x0e/\\x03\\x06\\x221\\x03\\x0a\" +\n\t\".\\x0a\\x03\\x0a7\\x02\\x03\\x0a\\x032\\x03\\x0a\\x1d.\\x03\\x091\\x06\\x03\\x09\\x19:\" +\n\t\"\\x03\\x08\\x02/\\x03\\x060+\\x03\\x06\\x0f-\\x03\\x06\\x1c\\x1f\\x03\\x06\\x1d\\x07\\x03\" +\n\t\"\\x0a,\\x11\\x03\\x09=\\x0d\\x03\\x09\\x0b;\\x03\\x07\\x1b/\\x03\\x0a\\x1f:\\x03\\x09 \" +\n\t\"\\x1f\\x03\\x09.\\x10\\x03\\x094\\x0b\\x03\\x09\\x1a1\\x03\\x08#\\x1a\\x03\\x084\\x1d\" +\n\t\"\\x03\\x08\\x01\\x1f\\x03\\x08\\x11\\x22\\x03\\x07'8\\x03\\x07\\x1a>\\x03\\x0757\\x03\" +\n\t\"\\x06&9\\x03\\x06+\\x11\\x03\\x0a.\\x0b\\x03\\x0a,>\\x03\\x0a4#\\x03\\x08%\\x17\\x03\" +\n\t\"\\x07\\x05\\x22\\x03\\x07\\x0c\\x0b\\x03\\x0a\\x1d+\\x03\\x0a\\x19\\x16\\x03\\x09+\\x1f\" +\n\t\"\\x03\\x09\\x08\\x0b\\x03\\x08\\x16\\x18\\x03\\x08+\\x12\\x03\\x0b\\x1d\\x0c\\x03\\x0a=\" +\n\t\"\\x10\\x03\\x0a\\x09\\x0d\\x03\\x0a\\x10\\x11\\x03\\x09&0\\x03\\x08(\\x1f\\x03\\x087\\x07\" +\n\t\"\\x03\\x08\\x185\\x03\\x07'6\\x03\\x06.\\x05\\x03\\x06=\\x04\\x03\\x06;;\\x03\\x06\\x06,\" +\n\t\"\\x03\\x0b\\x18>\\x03\\x08\\x00\\x18\\x03\\x06 \\x03\\x03\\x06<\\x00\\x03\\x09%\\x18\\x03\" +\n\t\"\\x0b\\x1c<\\x03\\x0a%!\\x03\\x0a\\x09\\x12\\x03\\x0a\\x16\\x02\\x03\\x090'\\x03\\x09\" +\n\t\"\\x0e=\\x03\\x08 \\x0e\\x03\\x08>\\x03\\x03\\x074>\\x03\\x06&?\\x03\\x06\\x19\\x09\\x03\" +\n\t\"\\x06?(\\x03\\x0a-\\x0e\\x03\\x09:3\\x03\\x098:\\x03\\x09\\x12\\x0b\\x03\\x09\\x1d\\x17\" +\n\t\"\\x03\\x087\\x05\\x03\\x082\\x14\\x03\\x08\\x06%\\x03\\x08\\x13\\x1f\\x03\\x06\\x06\\x0e\" +\n\t\"\\x03\\x0a\\x22<\\x03\\x09/<\\x03\\x06>+\\x03\\x0a'?\\x03\\x0a\\x13\\x0c\\x03\\x09\\x10<\" +\n\t\"\\x03\\x07\\x1b=\\x03\\x0a\\x19\\x13\\x03\\x09\\x22\\x1d\\x03\\x09\\x07\\x0d\\x03\\x08)\" +\n\t\"\\x1c\\x03\\x06=\\x1a\\x03\\x0a/4\\x03\\x0a7\\x11\\x03\\x0a\\x16:\\x03\\x09?3\\x03\\x09:\" +\n\t\"/\\x03\\x09\\x05\\x0a\\x03\\x09\\x14\\x06\\x03\\x087\\x22\\x03\\x080\\x07\\x03\\x08\\x1a\" +\n\t\"\\x1f\\x03\\x07\\x04(\\x03\\x07\\x04\\x09\\x03\\x06 %\\x03\\x06<\\x08\\x03\\x0a+\\x14\" +\n\t\"\\x03\\x09\\x1d\\x16\\x03\\x0a70\\x03\\x08 >\\x03\\x0857\\x03\\x070\\x0a\\x03\\x06=\\x12\" +\n\t\"\\x03\\x06\\x16%\\x03\\x06\\x1d,\\x03\\x099#\\x03\\x09\\x10>\\x03\\x07 \\x1e\\x03\\x08\" +\n\t\"\\x0c<\\x03\\x08\\x0b\\x18\\x03\\x08\\x15+\\x03\\x08,:\\x03\\x08%\\x22\\x03\\x07\\x0a$\" +\n\t\"\\x03\\x0b\\x1c=\\x03\\x07+\\x08\\x03\\x0a/\\x05\\x03\\x0a \\x07\\x03\\x0a\\x12'\\x03\" +\n\t\"\\x09#\\x11\\x03\\x08\\x1b\\x15\\x03\\x0a\\x06\\x01\\x03\\x09\\x1c\\x1b\\x03\\x0922\\x03\" +\n\t\"\\x07\\x14<\\x03\\x07\\x09\\x04\\x03\\x061\\x04\\x03\\x07\\x0e\\x01\\x03\\x0a\\x13\\x18\" +\n\t\"\\x03\\x0a-\\x0c\\x03\\x0a?\\x0d\\x03\\x0a\\x09\\x0a\\x03\\x091&\\x03\\x0a/\\x0b\\x03\" +\n\t\"\\x08$<\\x03\\x083\\x1d\\x03\\x08\\x0c$\\x03\\x08\\x0d\\x07\\x03\\x08\\x0d?\\x03\\x08\" +\n\t\"\\x0e\\x14\\x03\\x065\\x0a\\x03\\x08\\x1a#\\x03\\x08\\x16#\\x03\\x0702\\x03\\x07\\x03\" +\n\t\"\\x1a\\x03\\x06(\\x1d\\x03\\x06+\\x1b\\x03\\x06\\x0b\\x05\\x03\\x06\\x0b\\x17\\x03\\x06\" +\n\t\"\\x0c\\x04\\x03\\x06\\x1e\\x19\\x03\\x06+0\\x03\\x062\\x18\\x03\\x0b\\x16\\x1e\\x03\\x0a+\" +\n\t\"\\x16\\x03\\x0a-?\\x03\\x0a#:\\x03\\x0a#\\x10\\x03\\x0a%$\\x03\\x0a>+\\x03\\x0a01\\x03\" +\n\t\"\\x0a1\\x10\\x03\\x0a\\x099\\x03\\x0a\\x0a\\x12\\x03\\x0a\\x19\\x1f\\x03\\x0a\\x19\\x12\" +\n\t\"\\x03\\x09*)\\x03\\x09-\\x16\\x03\\x09.1\\x03\\x09.2\\x03\\x09<\\x0e\\x03\\x09> \\x03\" +\n\t\"\\x093\\x12\\x03\\x09\\x0b\\x01\\x03\\x09\\x1c2\\x03\\x09\\x11\\x1c\\x03\\x09\\x15%\\x03\" +\n\t\"\\x08,&\\x03\\x08!\\x22\\x03\\x089(\\x03\\x08\\x0b\\x1a\\x03\\x08\\x0d2\\x03\\x08\\x0c\" +\n\t\"\\x04\\x03\\x08\\x0c\\x06\\x03\\x08\\x0c\\x1f\\x03\\x08\\x0c\\x0c\\x03\\x08\\x0f\\x1f\\x03\" +\n\t\"\\x08\\x0f\\x1d\\x03\\x08\\x00\\x14\\x03\\x08\\x03\\x14\\x03\\x08\\x06\\x16\\x03\\x08\\x1e\" +\n\t\"#\\x03\\x08\\x11\\x11\\x03\\x08\\x10\\x18\\x03\\x08\\x14(\\x03\\x07)\\x1e\\x03\\x07.1\" +\n\t\"\\x03\\x07 $\\x03\\x07 '\\x03\\x078\\x08\\x03\\x07\\x0d0\\x03\\x07\\x0f7\\x03\\x07\\x05#\" +\n\t\"\\x03\\x07\\x05\\x1a\\x03\\x07\\x1a7\\x03\\x07\\x1d-\\x03\\x07\\x17\\x10\\x03\\x06)\\x1f\" +\n\t\"\\x03\\x062\\x0b\\x03\\x066\\x16\\x03\\x06\\x09\\x11\\x03\\x09(\\x1e\\x03\\x07!5\\x03\" +\n\t\"\\x0b\\x11\\x16\\x03\\x0a/\\x04\\x03\\x0a,\\x1a\\x03\\x0b\\x173\\x03\\x0a,1\\x03\\x0a/5\" +\n\t\"\\x03\\x0a\\x221\\x03\\x0a\\x22\\x0d\\x03\\x0a?%\\x03\\x0a<,\\x03\\x0a?#\\x03\\x0a>\\x19\" +\n\t\"\\x03\\x0a\\x08&\\x03\\x0a\\x0b\\x0e\\x03\\x0a\\x0c:\\x03\\x0a\\x0c+\\x03\\x0a\\x03\\x22\" +\n\t\"\\x03\\x0a\\x06)\\x03\\x0a\\x11\\x10\\x03\\x0a\\x11\\x1a\\x03\\x0a\\x17-\\x03\\x0a\\x14(\" +\n\t\"\\x03\\x09)\\x1e\\x03\\x09/\\x09\\x03\\x09.\\x00\\x03\\x09,\\x07\\x03\\x09/*\\x03\\x09-9\" +\n\t\"\\x03\\x09\\x228\\x03\\x09%\\x09\\x03\\x09:\\x12\\x03\\x09;\\x1d\\x03\\x09?\\x06\\x03\" +\n\t\"\\x093%\\x03\\x096\\x05\\x03\\x096\\x08\\x03\\x097\\x02\\x03\\x09\\x07,\\x03\\x09\\x04,\" +\n\t\"\\x03\\x09\\x1f\\x16\\x03\\x09\\x11\\x03\\x03\\x09\\x11\\x12\\x03\\x09\\x168\\x03\\x08*\" +\n\t\"\\x05\\x03\\x08/2\\x03\\x084:\\x03\\x08\\x22+\\x03\\x08 0\\x03\\x08&\\x0a\\x03\\x08;\" +\n\t\"\\x10\\x03\\x08>$\\x03\\x08>\\x18\\x03\\x0829\\x03\\x082:\\x03\\x081,\\x03\\x081<\\x03\" +\n\t\"\\x081\\x1c\\x03\\x087#\\x03\\x087*\\x03\\x08\\x09'\\x03\\x08\\x00\\x1d\\x03\\x08\\x05-\" +\n\t\"\\x03\\x08\\x1f4\\x03\\x08\\x1d\\x04\\x03\\x08\\x16\\x0f\\x03\\x07*7\\x03\\x07'!\\x03\" +\n\t\"\\x07%\\x1b\\x03\\x077\\x0c\\x03\\x07\\x0c1\\x03\\x07\\x0c.\\x03\\x07\\x00\\x06\\x03\\x07\" +\n\t\"\\x01\\x02\\x03\\x07\\x010\\x03\\x07\\x06=\\x03\\x07\\x01\\x03\\x03\\x07\\x01\\x13\\x03\" +\n\t\"\\x07\\x06\\x06\\x03\\x07\\x05\\x0a\\x03\\x07\\x1f\\x09\\x03\\x07\\x17:\\x03\\x06*1\\x03\" +\n\t\"\\x06-\\x1d\\x03\\x06\\x223\\x03\\x062:\\x03\\x060$\\x03\\x066\\x1e\\x03\\x064\\x12\\x03\" +\n\t\"\\x0645\\x03\\x06\\x0b\\x00\\x03\\x06\\x0b7\\x03\\x06\\x07\\x1f\\x03\\x06\\x15\\x12\\x03\" +\n\t\"\\x0c\\x05\\x0f\\x03\\x0b+\\x0b\\x03\\x0b+-\\x03\\x06\\x16\\x1b\\x03\\x06\\x15\\x17\\x03\" +\n\t\"\\x89\\xca\\xea\\x03\\x89\\xca\\xe8\\x03\\x0c8\\x10\\x03\\x0c8\\x01\\x03\\x0c8\\x0f\\x03\" +\n\t\"\\x0d8%\\x03\\x0d8!\\x03\\x0c8-\\x03\\x0c8/\\x03\\x0c8+\\x03\\x0c87\\x03\\x0c85\\x03\" +\n\t\"\\x0c9\\x09\\x03\\x0c9\\x0d\\x03\\x0c9\\x0f\\x03\\x0c9\\x0b\\x03\\xcfu\\x0c\\x03\\xcfu\" +\n\t\"\\x0f\\x03\\xcfu\\x0e\\x03\\xcfu\\x09\\x03\\x0c9\\x10\\x03\\x0d9\\x0c\\x03\\xcf`;\\x03\" +\n\t\"\\xcf`>\\x03\\xcf`9\\x03\\xcf`8\\x03\\xcf`7\\x03\\xcf`*\\x03\\xcf`-\\x03\\xcf`,\\x03\" +\n\t\"\\x0d\\x1b\\x1a\\x03\\x0d\\x1b&\\x03\\x0c=.\\x03\\x0c=%\\x03\\x0c>\\x1e\\x03\\x0c>\\x14\" +\n\t\"\\x03\\x0c?\\x06\\x03\\x0c?\\x0b\\x03\\x0c?\\x0c\\x03\\x0c?\\x0d\\x03\\x0c?\\x02\\x03\" +\n\t\"\\x0c>\\x0f\\x03\\x0c>\\x08\\x03\\x0c>\\x09\\x03\\x0c>,\\x03\\x0c>\\x0c\\x03\\x0c?\\x13\" +\n\t\"\\x03\\x0c?\\x16\\x03\\x0c?\\x15\\x03\\x0c?\\x1c\\x03\\x0c?\\x1f\\x03\\x0c?\\x1d\\x03\" +\n\t\"\\x0c?\\x1a\\x03\\x0c?\\x17\\x03\\x0c?\\x08\\x03\\x0c?\\x09\\x03\\x0c?\\x0e\\x03\\x0c?\" +\n\t\"\\x04\\x03\\x0c?\\x05\\x03\\x0c<?\\x03\\x0c=\\x00\\x03\\x0c=\\x06\\x03\\x0c=\\x05\\x03\" +\n\t\"\\x0c=\\x0c\\x03\\x0c=\\x0f\\x03\\x0c=\\x0d\\x03\\x0c=\\x0b\\x03\\x0c=\\x07\\x03\\x0c=\" +\n\t\"\\x19\\x03\\x0c=\\x15\\x03\\x0c=\\x11\\x03\\x0c=1\\x03\\x0c=3\\x03\\x0c=0\\x03\\x0c=>\" +\n\t\"\\x03\\x0c=2\\x03\\x0c=6\\x03\\x0c<\\x07\\x03\\x0c<\\x05\\x03\\x0e:!\\x03\\x0e:#\\x03\" +\n\t\"\\x0e8\\x09\\x03\\x0e:&\\x03\\x0e8\\x0b\\x03\\x0e:$\\x03\\x0e:,\\x03\\x0e8\\x1a\\x03\" +\n\t\"\\x0e8\\x1e\\x03\\x0e:*\\x03\\x0e:7\\x03\\x0e:5\\x03\\x0e:;\\x03\\x0e:\\x15\\x03\\x0e:<\" +\n\t\"\\x03\\x0e:4\\x03\\x0e:'\\x03\\x0e:-\\x03\\x0e:%\\x03\\x0e:?\\x03\\x0e:=\\x03\\x0e:)\" +\n\t\"\\x03\\x0e:/\\x03\\xcfs'\\x03\\x0d=\\x0f\\x03\\x0d+*\\x03\\x0d99\\x03\\x0d9;\\x03\\x0d9\" +\n\t\"?\\x03\\x0d)\\x0d\\x03\\x0d(%\\x02\\x01\\x18\\x02\\x01(\\x02\\x01\\x1e\\x03\\x0f$!\\x03\" +\n\t\"\\x0f87\\x03\\x0f4\\x0e\\x03\\x0f5\\x1d\\x03\\x06'\\x03\\x03\\x0f\\x08\\x18\\x03\\x0f\" +\n\t\"\\x0d\\x1b\\x03\\x0e2=\\x03\\x0e;\\x08\\x03\\x0e:\\x0b\\x03\\x0e\\x06$\\x03\\x0e\\x0d)\" +\n\t\"\\x03\\x0e\\x16\\x1f\\x03\\x0e\\x16\\x1b\\x03\\x0d$\\x0a\\x03\\x05,\\x1d\\x03\\x0d. \\x03\" +\n\t\"\\x0d.#\\x03\\x0c(/\\x03\\x09%\\x02\\x03\\x0d90\\x03\\x0d\\x0e4\\x03\\x0d\\x0d\\x0f\\x03\" +\n\t\"\\x0c#\\x00\\x03\\x0c,\\x1e\\x03\\x0c2\\x0e\\x03\\x0c\\x01\\x17\\x03\\x0c\\x09:\\x03\\x0e\" +\n\t\"\\x173\\x03\\x0c\\x08\\x03\\x03\\x0c\\x11\\x07\\x03\\x0c\\x10\\x18\\x03\\x0c\\x1f\\x1c\" +\n\t\"\\x03\\x0c\\x19\\x0e\\x03\\x0c\\x1a\\x1f\\x03\\x0f0>\\x03\\x0b->\\x03\\x0b<+\\x03\\x0b8\" +\n\t\"\\x13\\x03\\x0b\\x043\\x03\\x0b\\x14\\x03\\x03\\x0b\\x16%\\x03\\x0d\\x22&\\x03\\x0b\\x1a\" +\n\t\"\\x1a\\x03\\x0b\\x1a\\x04\\x03\\x0a%9\\x03\\x0a&2\\x03\\x0a&0\\x03\\x0a!\\x1a\\x03\\x0a!\" +\n\t\"7\\x03\\x0a5\\x10\\x03\\x0a=4\\x03\\x0a?\\x0e\\x03\\x0a>\\x10\\x03\\x0a\\x00 \\x03\\x0a\" +\n\t\"\\x0f:\\x03\\x0a\\x0f9\\x03\\x0a\\x0b\\x0a\\x03\\x0a\\x17%\\x03\\x0a\\x1b-\\x03\\x09-\" +\n\t\"\\x1a\\x03\\x09,4\\x03\\x09.,\\x03\\x09)\\x09\\x03\\x096!\\x03\\x091\\x1f\\x03\\x093\" +\n\t\"\\x16\\x03\\x0c+\\x1f\\x03\\x098 \\x03\\x098=\\x03\\x0c(\\x1a\\x03\\x0c(\\x16\\x03\\x09\" +\n\t\"\\x0a+\\x03\\x09\\x16\\x12\\x03\\x09\\x13\\x0e\\x03\\x09\\x153\\x03\\x08)!\\x03\\x09\\x1a\" +\n\t\"\\x01\\x03\\x09\\x18\\x01\\x03\\x08%#\\x03\\x08>\\x22\\x03\\x08\\x05%\\x03\\x08\\x02*\" +\n\t\"\\x03\\x08\\x15;\\x03\\x08\\x1b7\\x03\\x0f\\x07\\x1d\\x03\\x0f\\x04\\x03\\x03\\x070\\x0c\" +\n\t\"\\x03\\x07;\\x0b\\x03\\x07\\x08\\x17\\x03\\x07\\x12\\x06\\x03\\x06/-\\x03\\x0671\\x03\" +\n\t\"\\x065+\\x03\\x06>7\\x03\\x06\\x049\\x03\\x05+\\x1e\\x03\\x05,\\x17\\x03\\x05 \\x1d\\x03\" +\n\t\"\\x05\\x22\\x05\\x03\\x050\\x1d\"\n\n// lookup returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookup(s []byte) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupUnsafe(s []byte) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// lookupString returns the trie value for the first UTF-8 encoding in s and\n// the width in bytes of this encoding. The size will be 0 if s does not\n// hold enough bytes to complete the encoding. len(s) must be greater than 0.\nfunc (t *idnaTrie) lookupString(s string) (v uint16, sz int) {\n\tc0 := s[0]\n\tswitch {\n\tcase c0 < 0x80: // is ASCII\n\t\treturn idnaValues[c0], 1\n\tcase c0 < 0xC2:\n\t\treturn 0, 1 // Illegal UTF-8: not a starter, not ASCII.\n\tcase c0 < 0xE0: // 2-byte UTF-8\n\t\tif len(s) < 2 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c1), 2\n\tcase c0 < 0xF0: // 3-byte UTF-8\n\t\tif len(s) < 3 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c2), 3\n\tcase c0 < 0xF8: // 4-byte UTF-8\n\t\tif len(s) < 4 {\n\t\t\treturn 0, 0\n\t\t}\n\t\ti := idnaIndex[c0]\n\t\tc1 := s[1]\n\t\tif c1 < 0x80 || 0xC0 <= c1 {\n\t\t\treturn 0, 1 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to := uint32(i)<<6 + uint32(c1)\n\t\ti = idnaIndex[o]\n\t\tc2 := s[2]\n\t\tif c2 < 0x80 || 0xC0 <= c2 {\n\t\t\treturn 0, 2 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\to = uint32(i)<<6 + uint32(c2)\n\t\ti = idnaIndex[o]\n\t\tc3 := s[3]\n\t\tif c3 < 0x80 || 0xC0 <= c3 {\n\t\t\treturn 0, 3 // Illegal UTF-8: not a continuation byte.\n\t\t}\n\t\treturn t.lookupValue(uint32(i), c3), 4\n\t}\n\t// Illegal rune\n\treturn 0, 1\n}\n\n// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s.\n// s must start with a full and valid UTF-8 encoded rune.\nfunc (t *idnaTrie) lookupStringUnsafe(s string) uint16 {\n\tc0 := s[0]\n\tif c0 < 0x80 { // is ASCII\n\t\treturn idnaValues[c0]\n\t}\n\ti := idnaIndex[c0]\n\tif c0 < 0xE0 { // 2-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[1])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[1])]\n\tif c0 < 0xF0 { // 3-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[2])\n\t}\n\ti = idnaIndex[uint32(i)<<6+uint32(s[2])]\n\tif c0 < 0xF8 { // 4-byte UTF-8\n\t\treturn t.lookupValue(uint32(i), s[3])\n\t}\n\treturn 0\n}\n\n// idnaTrie. Total size: 29708 bytes (29.01 KiB). Checksum: c3ecc76d8fffa6e6.\ntype idnaTrie struct{}\n\nfunc newIdnaTrie(i int) *idnaTrie {\n\treturn &idnaTrie{}\n}\n\n// lookupValue determines the type of block n and looks up the value for b.\nfunc (t *idnaTrie) lookupValue(n uint32, b byte) uint16 {\n\tswitch {\n\tcase n < 125:\n\t\treturn uint16(idnaValues[n<<6+uint32(b)])\n\tdefault:\n\t\tn -= 125\n\t\treturn uint16(idnaSparse.lookup(n, b))\n\t}\n}\n\n// idnaValues: 127 blocks, 8128 entries, 16256 bytes\n// The third block is the zero block.\nvar idnaValues = [8128]uint16{\n\t// Block 0x0, offset 0x0\n\t0x00: 0x0080, 0x01: 0x0080, 0x02: 0x0080, 0x03: 0x0080, 0x04: 0x0080, 0x05: 0x0080,\n\t0x06: 0x0080, 0x07: 0x0080, 0x08: 0x0080, 0x09: 0x0080, 0x0a: 0x0080, 0x0b: 0x0080,\n\t0x0c: 0x0080, 0x0d: 0x0080, 0x0e: 0x0080, 0x0f: 0x0080, 0x10: 0x0080, 0x11: 0x0080,\n\t0x12: 0x0080, 0x13: 0x0080, 0x14: 0x0080, 0x15: 0x0080, 0x16: 0x0080, 0x17: 0x0080,\n\t0x18: 0x0080, 0x19: 0x0080, 0x1a: 0x0080, 0x1b: 0x0080, 0x1c: 0x0080, 0x1d: 0x0080,\n\t0x1e: 0x0080, 0x1f: 0x0080, 0x20: 0x0080, 0x21: 0x0080, 0x22: 0x0080, 0x23: 0x0080,\n\t0x24: 0x0080, 0x25: 0x0080, 0x26: 0x0080, 0x27: 0x0080, 0x28: 0x0080, 0x29: 0x0080,\n\t0x2a: 0x0080, 0x2b: 0x0080, 0x2c: 0x0080, 0x2d: 0x0008, 0x2e: 0x0008, 0x2f: 0x0080,\n\t0x30: 0x0008, 0x31: 0x0008, 0x32: 0x0008, 0x33: 0x0008, 0x34: 0x0008, 0x35: 0x0008,\n\t0x36: 0x0008, 0x37: 0x0008, 0x38: 0x0008, 0x39: 0x0008, 0x3a: 0x0080, 0x3b: 0x0080,\n\t0x3c: 0x0080, 0x3d: 0x0080, 0x3e: 0x0080, 0x3f: 0x0080,\n\t// Block 0x1, offset 0x40\n\t0x40: 0x0080, 0x41: 0xe105, 0x42: 0xe105, 0x43: 0xe105, 0x44: 0xe105, 0x45: 0xe105,\n\t0x46: 0xe105, 0x47: 0xe105, 0x48: 0xe105, 0x49: 0xe105, 0x4a: 0xe105, 0x4b: 0xe105,\n\t0x4c: 0xe105, 0x4d: 0xe105, 0x4e: 0xe105, 0x4f: 0xe105, 0x50: 0xe105, 0x51: 0xe105,\n\t0x52: 0xe105, 0x53: 0xe105, 0x54: 0xe105, 0x55: 0xe105, 0x56: 0xe105, 0x57: 0xe105,\n\t0x58: 0xe105, 0x59: 0xe105, 0x5a: 0xe105, 0x5b: 0x0080, 0x5c: 0x0080, 0x5d: 0x0080,\n\t0x5e: 0x0080, 0x5f: 0x0080, 0x60: 0x0080, 0x61: 0x0008, 0x62: 0x0008, 0x63: 0x0008,\n\t0x64: 0x0008, 0x65: 0x0008, 0x66: 0x0008, 0x67: 0x0008, 0x68: 0x0008, 0x69: 0x0008,\n\t0x6a: 0x0008, 0x6b: 0x0008, 0x6c: 0x0008, 0x6d: 0x0008, 0x6e: 0x0008, 0x6f: 0x0008,\n\t0x70: 0x0008, 0x71: 0x0008, 0x72: 0x0008, 0x73: 0x0008, 0x74: 0x0008, 0x75: 0x0008,\n\t0x76: 0x0008, 0x77: 0x0008, 0x78: 0x0008, 0x79: 0x0008, 0x7a: 0x0008, 0x7b: 0x0080,\n\t0x7c: 0x0080, 0x7d: 0x0080, 0x7e: 0x0080, 0x7f: 0x0080,\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040,\n\t0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040,\n\t0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040,\n\t0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040,\n\t0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040,\n\t0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x000a, 0xe1: 0x0018, 0xe2: 0x0018, 0xe3: 0x0018,\n\t0xe4: 0x0018, 0xe5: 0x0018, 0xe6: 0x0018, 0xe7: 0x0018, 0xe8: 0x001a, 0xe9: 0x0018,\n\t0xea: 0x0039, 0xeb: 0x0018, 0xec: 0x0018, 0xed: 0x03c0, 0xee: 0x0018, 0xef: 0x004a,\n\t0xf0: 0x0018, 0xf1: 0x0018, 0xf2: 0x0069, 0xf3: 0x0079, 0xf4: 0x008a, 0xf5: 0x0005,\n\t0xf6: 0x0018, 0xf7: 0x0008, 0xf8: 0x00aa, 0xf9: 0x00c9, 0xfa: 0x00d9, 0xfb: 0x0018,\n\t0xfc: 0x00e9, 0xfd: 0x0119, 0xfe: 0x0149, 0xff: 0x0018,\n\t// Block 0x4, offset 0x100\n\t0x100: 0xe00d, 0x101: 0x0008, 0x102: 0xe00d, 0x103: 0x0008, 0x104: 0xe00d, 0x105: 0x0008,\n\t0x106: 0xe00d, 0x107: 0x0008, 0x108: 0xe00d, 0x109: 0x0008, 0x10a: 0xe00d, 0x10b: 0x0008,\n\t0x10c: 0xe00d, 0x10d: 0x0008, 0x10e: 0xe00d, 0x10f: 0x0008, 0x110: 0xe00d, 0x111: 0x0008,\n\t0x112: 0xe00d, 0x113: 0x0008, 0x114: 0xe00d, 0x115: 0x0008, 0x116: 0xe00d, 0x117: 0x0008,\n\t0x118: 0xe00d, 0x119: 0x0008, 0x11a: 0xe00d, 0x11b: 0x0008, 0x11c: 0xe00d, 0x11d: 0x0008,\n\t0x11e: 0xe00d, 0x11f: 0x0008, 0x120: 0xe00d, 0x121: 0x0008, 0x122: 0xe00d, 0x123: 0x0008,\n\t0x124: 0xe00d, 0x125: 0x0008, 0x126: 0xe00d, 0x127: 0x0008, 0x128: 0xe00d, 0x129: 0x0008,\n\t0x12a: 0xe00d, 0x12b: 0x0008, 0x12c: 0xe00d, 0x12d: 0x0008, 0x12e: 0xe00d, 0x12f: 0x0008,\n\t0x130: 0x0179, 0x131: 0x0008, 0x132: 0x0035, 0x133: 0x004d, 0x134: 0xe00d, 0x135: 0x0008,\n\t0x136: 0xe00d, 0x137: 0x0008, 0x138: 0x0008, 0x139: 0xe01d, 0x13a: 0x0008, 0x13b: 0xe03d,\n\t0x13c: 0x0008, 0x13d: 0xe01d, 0x13e: 0x0008, 0x13f: 0x0199,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x0199, 0x141: 0xe01d, 0x142: 0x0008, 0x143: 0xe03d, 0x144: 0x0008, 0x145: 0xe01d,\n\t0x146: 0x0008, 0x147: 0xe07d, 0x148: 0x0008, 0x149: 0x01b9, 0x14a: 0xe00d, 0x14b: 0x0008,\n\t0x14c: 0xe00d, 0x14d: 0x0008, 0x14e: 0xe00d, 0x14f: 0x0008, 0x150: 0xe00d, 0x151: 0x0008,\n\t0x152: 0xe00d, 0x153: 0x0008, 0x154: 0xe00d, 0x155: 0x0008, 0x156: 0xe00d, 0x157: 0x0008,\n\t0x158: 0xe00d, 0x159: 0x0008, 0x15a: 0xe00d, 0x15b: 0x0008, 0x15c: 0xe00d, 0x15d: 0x0008,\n\t0x15e: 0xe00d, 0x15f: 0x0008, 0x160: 0xe00d, 0x161: 0x0008, 0x162: 0xe00d, 0x163: 0x0008,\n\t0x164: 0xe00d, 0x165: 0x0008, 0x166: 0xe00d, 0x167: 0x0008, 0x168: 0xe00d, 0x169: 0x0008,\n\t0x16a: 0xe00d, 0x16b: 0x0008, 0x16c: 0xe00d, 0x16d: 0x0008, 0x16e: 0xe00d, 0x16f: 0x0008,\n\t0x170: 0xe00d, 0x171: 0x0008, 0x172: 0xe00d, 0x173: 0x0008, 0x174: 0xe00d, 0x175: 0x0008,\n\t0x176: 0xe00d, 0x177: 0x0008, 0x178: 0x0065, 0x179: 0xe01d, 0x17a: 0x0008, 0x17b: 0xe03d,\n\t0x17c: 0x0008, 0x17d: 0xe01d, 0x17e: 0x0008, 0x17f: 0x01d9,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x0008, 0x181: 0x007d, 0x182: 0xe00d, 0x183: 0x0008, 0x184: 0xe00d, 0x185: 0x0008,\n\t0x186: 0x007d, 0x187: 0xe07d, 0x188: 0x0008, 0x189: 0x0095, 0x18a: 0x00ad, 0x18b: 0xe03d,\n\t0x18c: 0x0008, 0x18d: 0x0008, 0x18e: 0x00c5, 0x18f: 0x00dd, 0x190: 0x00f5, 0x191: 0xe01d,\n\t0x192: 0x0008, 0x193: 0x010d, 0x194: 0x0125, 0x195: 0x0008, 0x196: 0x013d, 0x197: 0x013d,\n\t0x198: 0xe00d, 0x199: 0x0008, 0x19a: 0x0008, 0x19b: 0x0008, 0x19c: 0x010d, 0x19d: 0x0155,\n\t0x19e: 0x0008, 0x19f: 0x016d, 0x1a0: 0xe00d, 0x1a1: 0x0008, 0x1a2: 0xe00d, 0x1a3: 0x0008,\n\t0x1a4: 0xe00d, 0x1a5: 0x0008, 0x1a6: 0x0185, 0x1a7: 0xe07d, 0x1a8: 0x0008, 0x1a9: 0x019d,\n\t0x1aa: 0x0008, 0x1ab: 0x0008, 0x1ac: 0xe00d, 0x1ad: 0x0008, 0x1ae: 0x0185, 0x1af: 0xe0fd,\n\t0x1b0: 0x0008, 0x1b1: 0x01b5, 0x1b2: 0x01cd, 0x1b3: 0xe03d, 0x1b4: 0x0008, 0x1b5: 0xe01d,\n\t0x1b6: 0x0008, 0x1b7: 0x01e5, 0x1b8: 0xe00d, 0x1b9: 0x0008, 0x1ba: 0x0008, 0x1bb: 0x0008,\n\t0x1bc: 0xe00d, 0x1bd: 0x0008, 0x1be: 0x0008, 0x1bf: 0x0008,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x0008, 0x1c1: 0x0008, 0x1c2: 0x0008, 0x1c3: 0x0008, 0x1c4: 0x01e9, 0x1c5: 0x01e9,\n\t0x1c6: 0x01e9, 0x1c7: 0x01fd, 0x1c8: 0x0215, 0x1c9: 0x022d, 0x1ca: 0x0245, 0x1cb: 0x025d,\n\t0x1cc: 0x0275, 0x1cd: 0xe01d, 0x1ce: 0x0008, 0x1cf: 0xe0fd, 0x1d0: 0x0008, 0x1d1: 0xe01d,\n\t0x1d2: 0x0008, 0x1d3: 0xe03d, 0x1d4: 0x0008, 0x1d5: 0xe01d, 0x1d6: 0x0008, 0x1d7: 0xe07d,\n\t0x1d8: 0x0008, 0x1d9: 0xe01d, 0x1da: 0x0008, 0x1db: 0xe03d, 0x1dc: 0x0008, 0x1dd: 0x0008,\n\t0x1de: 0xe00d, 0x1df: 0x0008, 0x1e0: 0xe00d, 0x1e1: 0x0008, 0x1e2: 0xe00d, 0x1e3: 0x0008,\n\t0x1e4: 0xe00d, 0x1e5: 0x0008, 0x1e6: 0xe00d, 0x1e7: 0x0008, 0x1e8: 0xe00d, 0x1e9: 0x0008,\n\t0x1ea: 0xe00d, 0x1eb: 0x0008, 0x1ec: 0xe00d, 0x1ed: 0x0008, 0x1ee: 0xe00d, 0x1ef: 0x0008,\n\t0x1f0: 0x0008, 0x1f1: 0x028d, 0x1f2: 0x02a5, 0x1f3: 0x02bd, 0x1f4: 0xe00d, 0x1f5: 0x0008,\n\t0x1f6: 0x02d5, 0x1f7: 0x02ed, 0x1f8: 0xe00d, 0x1f9: 0x0008, 0x1fa: 0xe00d, 0x1fb: 0x0008,\n\t0x1fc: 0xe00d, 0x1fd: 0x0008, 0x1fe: 0xe00d, 0x1ff: 0x0008,\n\t// Block 0x8, offset 0x200\n\t0x200: 0xe00d, 0x201: 0x0008, 0x202: 0xe00d, 0x203: 0x0008, 0x204: 0xe00d, 0x205: 0x0008,\n\t0x206: 0xe00d, 0x207: 0x0008, 0x208: 0xe00d, 0x209: 0x0008, 0x20a: 0xe00d, 0x20b: 0x0008,\n\t0x20c: 0xe00d, 0x20d: 0x0008, 0x20e: 0xe00d, 0x20f: 0x0008, 0x210: 0xe00d, 0x211: 0x0008,\n\t0x212: 0xe00d, 0x213: 0x0008, 0x214: 0xe00d, 0x215: 0x0008, 0x216: 0xe00d, 0x217: 0x0008,\n\t0x218: 0xe00d, 0x219: 0x0008, 0x21a: 0xe00d, 0x21b: 0x0008, 0x21c: 0xe00d, 0x21d: 0x0008,\n\t0x21e: 0xe00d, 0x21f: 0x0008, 0x220: 0x0305, 0x221: 0x0008, 0x222: 0xe00d, 0x223: 0x0008,\n\t0x224: 0xe00d, 0x225: 0x0008, 0x226: 0xe00d, 0x227: 0x0008, 0x228: 0xe00d, 0x229: 0x0008,\n\t0x22a: 0xe00d, 0x22b: 0x0008, 0x22c: 0xe00d, 0x22d: 0x0008, 0x22e: 0xe00d, 0x22f: 0x0008,\n\t0x230: 0xe00d, 0x231: 0x0008, 0x232: 0xe00d, 0x233: 0x0008, 0x234: 0x0008, 0x235: 0x0008,\n\t0x236: 0x0008, 0x237: 0x0008, 0x238: 0x0008, 0x239: 0x0008, 0x23a: 0x0209, 0x23b: 0xe03d,\n\t0x23c: 0x0008, 0x23d: 0x031d, 0x23e: 0x0229, 0x23f: 0x0008,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x0008, 0x241: 0x0008, 0x242: 0x0018, 0x243: 0x0018, 0x244: 0x0018, 0x245: 0x0018,\n\t0x246: 0x0008, 0x247: 0x0008, 0x248: 0x0008, 0x249: 0x0008, 0x24a: 0x0008, 0x24b: 0x0008,\n\t0x24c: 0x0008, 0x24d: 0x0008, 0x24e: 0x0008, 0x24f: 0x0008, 0x250: 0x0008, 0x251: 0x0008,\n\t0x252: 0x0018, 0x253: 0x0018, 0x254: 0x0018, 0x255: 0x0018, 0x256: 0x0018, 0x257: 0x0018,\n\t0x258: 0x029a, 0x259: 0x02ba, 0x25a: 0x02da, 0x25b: 0x02fa, 0x25c: 0x031a, 0x25d: 0x033a,\n\t0x25e: 0x0018, 0x25f: 0x0018, 0x260: 0x03ad, 0x261: 0x0359, 0x262: 0x01d9, 0x263: 0x0369,\n\t0x264: 0x03c5, 0x265: 0x0018, 0x266: 0x0018, 0x267: 0x0018, 0x268: 0x0018, 0x269: 0x0018,\n\t0x26a: 0x0018, 0x26b: 0x0018, 0x26c: 0x0008, 0x26d: 0x0018, 0x26e: 0x0008, 0x26f: 0x0018,\n\t0x270: 0x0018, 0x271: 0x0018, 0x272: 0x0018, 0x273: 0x0018, 0x274: 0x0018, 0x275: 0x0018,\n\t0x276: 0x0018, 0x277: 0x0018, 0x278: 0x0018, 0x279: 0x0018, 0x27a: 0x0018, 0x27b: 0x0018,\n\t0x27c: 0x0018, 0x27d: 0x0018, 0x27e: 0x0018, 0x27f: 0x0018,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x03dd, 0x281: 0x03dd, 0x282: 0x3308, 0x283: 0x03f5, 0x284: 0x0379, 0x285: 0x040d,\n\t0x286: 0x3308, 0x287: 0x3308, 0x288: 0x3308, 0x289: 0x3308, 0x28a: 0x3308, 0x28b: 0x3308,\n\t0x28c: 0x3308, 0x28d: 0x3308, 0x28e: 0x3308, 0x28f: 0x33c0, 0x290: 0x3308, 0x291: 0x3308,\n\t0x292: 0x3308, 0x293: 0x3308, 0x294: 0x3308, 0x295: 0x3308, 0x296: 0x3308, 0x297: 0x3308,\n\t0x298: 0x3308, 0x299: 0x3308, 0x29a: 0x3308, 0x29b: 0x3308, 0x29c: 0x3308, 0x29d: 0x3308,\n\t0x29e: 0x3308, 0x29f: 0x3308, 0x2a0: 0x3308, 0x2a1: 0x3308, 0x2a2: 0x3308, 0x2a3: 0x3308,\n\t0x2a4: 0x3308, 0x2a5: 0x3308, 0x2a6: 0x3308, 0x2a7: 0x3308, 0x2a8: 0x3308, 0x2a9: 0x3308,\n\t0x2aa: 0x3308, 0x2ab: 0x3308, 0x2ac: 0x3308, 0x2ad: 0x3308, 0x2ae: 0x3308, 0x2af: 0x3308,\n\t0x2b0: 0xe00d, 0x2b1: 0x0008, 0x2b2: 0xe00d, 0x2b3: 0x0008, 0x2b4: 0x0425, 0x2b5: 0x0008,\n\t0x2b6: 0xe00d, 0x2b7: 0x0008, 0x2b8: 0x0040, 0x2b9: 0x0040, 0x2ba: 0x03a2, 0x2bb: 0x0008,\n\t0x2bc: 0x0008, 0x2bd: 0x0008, 0x2be: 0x03c2, 0x2bf: 0x043d,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x0040, 0x2c1: 0x0040, 0x2c2: 0x0040, 0x2c3: 0x0040, 0x2c4: 0x008a, 0x2c5: 0x03d2,\n\t0x2c6: 0xe155, 0x2c7: 0x0455, 0x2c8: 0xe12d, 0x2c9: 0xe13d, 0x2ca: 0xe12d, 0x2cb: 0x0040,\n\t0x2cc: 0x03dd, 0x2cd: 0x0040, 0x2ce: 0x046d, 0x2cf: 0x0485, 0x2d0: 0x0008, 0x2d1: 0xe105,\n\t0x2d2: 0xe105, 0x2d3: 0xe105, 0x2d4: 0xe105, 0x2d5: 0xe105, 0x2d6: 0xe105, 0x2d7: 0xe105,\n\t0x2d8: 0xe105, 0x2d9: 0xe105, 0x2da: 0xe105, 0x2db: 0xe105, 0x2dc: 0xe105, 0x2dd: 0xe105,\n\t0x2de: 0xe105, 0x2df: 0xe105, 0x2e0: 0x049d, 0x2e1: 0x049d, 0x2e2: 0x0040, 0x2e3: 0x049d,\n\t0x2e4: 0x049d, 0x2e5: 0x049d, 0x2e6: 0x049d, 0x2e7: 0x049d, 0x2e8: 0x049d, 0x2e9: 0x049d,\n\t0x2ea: 0x049d, 0x2eb: 0x049d, 0x2ec: 0x0008, 0x2ed: 0x0008, 0x2ee: 0x0008, 0x2ef: 0x0008,\n\t0x2f0: 0x0008, 0x2f1: 0x0008, 0x2f2: 0x0008, 0x2f3: 0x0008, 0x2f4: 0x0008, 0x2f5: 0x0008,\n\t0x2f6: 0x0008, 0x2f7: 0x0008, 0x2f8: 0x0008, 0x2f9: 0x0008, 0x2fa: 0x0008, 0x2fb: 0x0008,\n\t0x2fc: 0x0008, 0x2fd: 0x0008, 0x2fe: 0x0008, 0x2ff: 0x0008,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x0008, 0x301: 0x0008, 0x302: 0xe00f, 0x303: 0x0008, 0x304: 0x0008, 0x305: 0x0008,\n\t0x306: 0x0008, 0x307: 0x0008, 0x308: 0x0008, 0x309: 0x0008, 0x30a: 0x0008, 0x30b: 0x0008,\n\t0x30c: 0x0008, 0x30d: 0x0008, 0x30e: 0x0008, 0x30f: 0xe0c5, 0x310: 0x04b5, 0x311: 0x04cd,\n\t0x312: 0xe0bd, 0x313: 0xe0f5, 0x314: 0xe0fd, 0x315: 0xe09d, 0x316: 0xe0b5, 0x317: 0x0008,\n\t0x318: 0xe00d, 0x319: 0x0008, 0x31a: 0xe00d, 0x31b: 0x0008, 0x31c: 0xe00d, 0x31d: 0x0008,\n\t0x31e: 0xe00d, 0x31f: 0x0008, 0x320: 0xe00d, 0x321: 0x0008, 0x322: 0xe00d, 0x323: 0x0008,\n\t0x324: 0xe00d, 0x325: 0x0008, 0x326: 0xe00d, 0x327: 0x0008, 0x328: 0xe00d, 0x329: 0x0008,\n\t0x32a: 0xe00d, 0x32b: 0x0008, 0x32c: 0xe00d, 0x32d: 0x0008, 0x32e: 0xe00d, 0x32f: 0x0008,\n\t0x330: 0x04e5, 0x331: 0xe185, 0x332: 0xe18d, 0x333: 0x0008, 0x334: 0x04fd, 0x335: 0x03dd,\n\t0x336: 0x0018, 0x337: 0xe07d, 0x338: 0x0008, 0x339: 0xe1d5, 0x33a: 0xe00d, 0x33b: 0x0008,\n\t0x33c: 0x0008, 0x33d: 0x0515, 0x33e: 0x052d, 0x33f: 0x052d,\n\t// Block 0xd, offset 0x340\n\t0x340: 0x0008, 0x341: 0x0008, 0x342: 0x0008, 0x343: 0x0008, 0x344: 0x0008, 0x345: 0x0008,\n\t0x346: 0x0008, 0x347: 0x0008, 0x348: 0x0008, 0x349: 0x0008, 0x34a: 0x0008, 0x34b: 0x0008,\n\t0x34c: 0x0008, 0x34d: 0x0008, 0x34e: 0x0008, 0x34f: 0x0008, 0x350: 0x0008, 0x351: 0x0008,\n\t0x352: 0x0008, 0x353: 0x0008, 0x354: 0x0008, 0x355: 0x0008, 0x356: 0x0008, 0x357: 0x0008,\n\t0x358: 0x0008, 0x359: 0x0008, 0x35a: 0x0008, 0x35b: 0x0008, 0x35c: 0x0008, 0x35d: 0x0008,\n\t0x35e: 0x0008, 0x35f: 0x0008, 0x360: 0xe00d, 0x361: 0x0008, 0x362: 0xe00d, 0x363: 0x0008,\n\t0x364: 0xe00d, 0x365: 0x0008, 0x366: 0xe00d, 0x367: 0x0008, 0x368: 0xe00d, 0x369: 0x0008,\n\t0x36a: 0xe00d, 0x36b: 0x0008, 0x36c: 0xe00d, 0x36d: 0x0008, 0x36e: 0xe00d, 0x36f: 0x0008,\n\t0x370: 0xe00d, 0x371: 0x0008, 0x372: 0xe00d, 0x373: 0x0008, 0x374: 0xe00d, 0x375: 0x0008,\n\t0x376: 0xe00d, 0x377: 0x0008, 0x378: 0xe00d, 0x379: 0x0008, 0x37a: 0xe00d, 0x37b: 0x0008,\n\t0x37c: 0xe00d, 0x37d: 0x0008, 0x37e: 0xe00d, 0x37f: 0x0008,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xe00d, 0x381: 0x0008, 0x382: 0x0018, 0x383: 0x3308, 0x384: 0x3308, 0x385: 0x3308,\n\t0x386: 0x3308, 0x387: 0x3308, 0x388: 0x3318, 0x389: 0x3318, 0x38a: 0xe00d, 0x38b: 0x0008,\n\t0x38c: 0xe00d, 0x38d: 0x0008, 0x38e: 0xe00d, 0x38f: 0x0008, 0x390: 0xe00d, 0x391: 0x0008,\n\t0x392: 0xe00d, 0x393: 0x0008, 0x394: 0xe00d, 0x395: 0x0008, 0x396: 0xe00d, 0x397: 0x0008,\n\t0x398: 0xe00d, 0x399: 0x0008, 0x39a: 0xe00d, 0x39b: 0x0008, 0x39c: 0xe00d, 0x39d: 0x0008,\n\t0x39e: 0xe00d, 0x39f: 0x0008, 0x3a0: 0xe00d, 0x3a1: 0x0008, 0x3a2: 0xe00d, 0x3a3: 0x0008,\n\t0x3a4: 0xe00d, 0x3a5: 0x0008, 0x3a6: 0xe00d, 0x3a7: 0x0008, 0x3a8: 0xe00d, 0x3a9: 0x0008,\n\t0x3aa: 0xe00d, 0x3ab: 0x0008, 0x3ac: 0xe00d, 0x3ad: 0x0008, 0x3ae: 0xe00d, 0x3af: 0x0008,\n\t0x3b0: 0xe00d, 0x3b1: 0x0008, 0x3b2: 0xe00d, 0x3b3: 0x0008, 0x3b4: 0xe00d, 0x3b5: 0x0008,\n\t0x3b6: 0xe00d, 0x3b7: 0x0008, 0x3b8: 0xe00d, 0x3b9: 0x0008, 0x3ba: 0xe00d, 0x3bb: 0x0008,\n\t0x3bc: 0xe00d, 0x3bd: 0x0008, 0x3be: 0xe00d, 0x3bf: 0x0008,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x0040, 0x3c1: 0xe01d, 0x3c2: 0x0008, 0x3c3: 0xe03d, 0x3c4: 0x0008, 0x3c5: 0xe01d,\n\t0x3c6: 0x0008, 0x3c7: 0xe07d, 0x3c8: 0x0008, 0x3c9: 0xe01d, 0x3ca: 0x0008, 0x3cb: 0xe03d,\n\t0x3cc: 0x0008, 0x3cd: 0xe01d, 0x3ce: 0x0008, 0x3cf: 0x0008, 0x3d0: 0xe00d, 0x3d1: 0x0008,\n\t0x3d2: 0xe00d, 0x3d3: 0x0008, 0x3d4: 0xe00d, 0x3d5: 0x0008, 0x3d6: 0xe00d, 0x3d7: 0x0008,\n\t0x3d8: 0xe00d, 0x3d9: 0x0008, 0x3da: 0xe00d, 0x3db: 0x0008, 0x3dc: 0xe00d, 0x3dd: 0x0008,\n\t0x3de: 0xe00d, 0x3df: 0x0008, 0x3e0: 0xe00d, 0x3e1: 0x0008, 0x3e2: 0xe00d, 0x3e3: 0x0008,\n\t0x3e4: 0xe00d, 0x3e5: 0x0008, 0x3e6: 0xe00d, 0x3e7: 0x0008, 0x3e8: 0xe00d, 0x3e9: 0x0008,\n\t0x3ea: 0xe00d, 0x3eb: 0x0008, 0x3ec: 0xe00d, 0x3ed: 0x0008, 0x3ee: 0xe00d, 0x3ef: 0x0008,\n\t0x3f0: 0xe00d, 0x3f1: 0x0008, 0x3f2: 0xe00d, 0x3f3: 0x0008, 0x3f4: 0xe00d, 0x3f5: 0x0008,\n\t0x3f6: 0xe00d, 0x3f7: 0x0008, 0x3f8: 0xe00d, 0x3f9: 0x0008, 0x3fa: 0xe00d, 0x3fb: 0x0008,\n\t0x3fc: 0xe00d, 0x3fd: 0x0008, 0x3fe: 0xe00d, 0x3ff: 0x0008,\n\t// Block 0x10, offset 0x400\n\t0x400: 0xe00d, 0x401: 0x0008, 0x402: 0xe00d, 0x403: 0x0008, 0x404: 0xe00d, 0x405: 0x0008,\n\t0x406: 0xe00d, 0x407: 0x0008, 0x408: 0xe00d, 0x409: 0x0008, 0x40a: 0xe00d, 0x40b: 0x0008,\n\t0x40c: 0xe00d, 0x40d: 0x0008, 0x40e: 0xe00d, 0x40f: 0x0008, 0x410: 0xe00d, 0x411: 0x0008,\n\t0x412: 0xe00d, 0x413: 0x0008, 0x414: 0xe00d, 0x415: 0x0008, 0x416: 0xe00d, 0x417: 0x0008,\n\t0x418: 0xe00d, 0x419: 0x0008, 0x41a: 0xe00d, 0x41b: 0x0008, 0x41c: 0xe00d, 0x41d: 0x0008,\n\t0x41e: 0xe00d, 0x41f: 0x0008, 0x420: 0xe00d, 0x421: 0x0008, 0x422: 0xe00d, 0x423: 0x0008,\n\t0x424: 0xe00d, 0x425: 0x0008, 0x426: 0xe00d, 0x427: 0x0008, 0x428: 0xe00d, 0x429: 0x0008,\n\t0x42a: 0xe00d, 0x42b: 0x0008, 0x42c: 0xe00d, 0x42d: 0x0008, 0x42e: 0xe00d, 0x42f: 0x0008,\n\t0x430: 0x0040, 0x431: 0x03f5, 0x432: 0x03f5, 0x433: 0x03f5, 0x434: 0x03f5, 0x435: 0x03f5,\n\t0x436: 0x03f5, 0x437: 0x03f5, 0x438: 0x03f5, 0x439: 0x03f5, 0x43a: 0x03f5, 0x43b: 0x03f5,\n\t0x43c: 0x03f5, 0x43d: 0x03f5, 0x43e: 0x03f5, 0x43f: 0x03f5,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x0840, 0x441: 0x0840, 0x442: 0x0840, 0x443: 0x0840, 0x444: 0x0840, 0x445: 0x0840,\n\t0x446: 0x0018, 0x447: 0x0018, 0x448: 0x0818, 0x449: 0x0018, 0x44a: 0x0018, 0x44b: 0x0818,\n\t0x44c: 0x0018, 0x44d: 0x0818, 0x44e: 0x0018, 0x44f: 0x0018, 0x450: 0x3308, 0x451: 0x3308,\n\t0x452: 0x3308, 0x453: 0x3308, 0x454: 0x3308, 0x455: 0x3308, 0x456: 0x3308, 0x457: 0x3308,\n\t0x458: 0x3308, 0x459: 0x3308, 0x45a: 0x3308, 0x45b: 0x0818, 0x45c: 0x0b40, 0x45d: 0x0040,\n\t0x45e: 0x0818, 0x45f: 0x0818, 0x460: 0x0a08, 0x461: 0x0808, 0x462: 0x0c08, 0x463: 0x0c08,\n\t0x464: 0x0c08, 0x465: 0x0c08, 0x466: 0x0a08, 0x467: 0x0c08, 0x468: 0x0a08, 0x469: 0x0c08,\n\t0x46a: 0x0a08, 0x46b: 0x0a08, 0x46c: 0x0a08, 0x46d: 0x0a08, 0x46e: 0x0a08, 0x46f: 0x0c08,\n\t0x470: 0x0c08, 0x471: 0x0c08, 0x472: 0x0c08, 0x473: 0x0a08, 0x474: 0x0a08, 0x475: 0x0a08,\n\t0x476: 0x0a08, 0x477: 0x0a08, 0x478: 0x0a08, 0x479: 0x0a08, 0x47a: 0x0a08, 0x47b: 0x0a08,\n\t0x47c: 0x0a08, 0x47d: 0x0a08, 0x47e: 0x0a08, 0x47f: 0x0a08,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x0818, 0x481: 0x0a08, 0x482: 0x0a08, 0x483: 0x0a08, 0x484: 0x0a08, 0x485: 0x0a08,\n\t0x486: 0x0a08, 0x487: 0x0a08, 0x488: 0x0c08, 0x489: 0x0a08, 0x48a: 0x0a08, 0x48b: 0x3308,\n\t0x48c: 0x3308, 0x48d: 0x3308, 0x48e: 0x3308, 0x48f: 0x3308, 0x490: 0x3308, 0x491: 0x3308,\n\t0x492: 0x3308, 0x493: 0x3308, 0x494: 0x3308, 0x495: 0x3308, 0x496: 0x3308, 0x497: 0x3308,\n\t0x498: 0x3308, 0x499: 0x3308, 0x49a: 0x3308, 0x49b: 0x3308, 0x49c: 0x3308, 0x49d: 0x3308,\n\t0x49e: 0x3308, 0x49f: 0x3308, 0x4a0: 0x0808, 0x4a1: 0x0808, 0x4a2: 0x0808, 0x4a3: 0x0808,\n\t0x4a4: 0x0808, 0x4a5: 0x0808, 0x4a6: 0x0808, 0x4a7: 0x0808, 0x4a8: 0x0808, 0x4a9: 0x0808,\n\t0x4aa: 0x0018, 0x4ab: 0x0818, 0x4ac: 0x0818, 0x4ad: 0x0818, 0x4ae: 0x0a08, 0x4af: 0x0a08,\n\t0x4b0: 0x3308, 0x4b1: 0x0c08, 0x4b2: 0x0c08, 0x4b3: 0x0c08, 0x4b4: 0x0808, 0x4b5: 0x0429,\n\t0x4b6: 0x0451, 0x4b7: 0x0479, 0x4b8: 0x04a1, 0x4b9: 0x0a08, 0x4ba: 0x0a08, 0x4bb: 0x0a08,\n\t0x4bc: 0x0a08, 0x4bd: 0x0a08, 0x4be: 0x0a08, 0x4bf: 0x0a08,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0x0c08, 0x4c1: 0x0a08, 0x4c2: 0x0a08, 0x4c3: 0x0c08, 0x4c4: 0x0c08, 0x4c5: 0x0c08,\n\t0x4c6: 0x0c08, 0x4c7: 0x0c08, 0x4c8: 0x0c08, 0x4c9: 0x0c08, 0x4ca: 0x0c08, 0x4cb: 0x0c08,\n\t0x4cc: 0x0a08, 0x4cd: 0x0c08, 0x4ce: 0x0a08, 0x4cf: 0x0c08, 0x4d0: 0x0a08, 0x4d1: 0x0a08,\n\t0x4d2: 0x0c08, 0x4d3: 0x0c08, 0x4d4: 0x0818, 0x4d5: 0x0c08, 0x4d6: 0x3308, 0x4d7: 0x3308,\n\t0x4d8: 0x3308, 0x4d9: 0x3308, 0x4da: 0x3308, 0x4db: 0x3308, 0x4dc: 0x3308, 0x4dd: 0x0840,\n\t0x4de: 0x0018, 0x4df: 0x3308, 0x4e0: 0x3308, 0x4e1: 0x3308, 0x4e2: 0x3308, 0x4e3: 0x3308,\n\t0x4e4: 0x3308, 0x4e5: 0x0808, 0x4e6: 0x0808, 0x4e7: 0x3308, 0x4e8: 0x3308, 0x4e9: 0x0018,\n\t0x4ea: 0x3308, 0x4eb: 0x3308, 0x4ec: 0x3308, 0x4ed: 0x3308, 0x4ee: 0x0c08, 0x4ef: 0x0c08,\n\t0x4f0: 0x0008, 0x4f1: 0x0008, 0x4f2: 0x0008, 0x4f3: 0x0008, 0x4f4: 0x0008, 0x4f5: 0x0008,\n\t0x4f6: 0x0008, 0x4f7: 0x0008, 0x4f8: 0x0008, 0x4f9: 0x0008, 0x4fa: 0x0a08, 0x4fb: 0x0a08,\n\t0x4fc: 0x0a08, 0x4fd: 0x0808, 0x4fe: 0x0808, 0x4ff: 0x0a08,\n\t// Block 0x14, offset 0x500\n\t0x500: 0x0818, 0x501: 0x0818, 0x502: 0x0818, 0x503: 0x0818, 0x504: 0x0818, 0x505: 0x0818,\n\t0x506: 0x0818, 0x507: 0x0818, 0x508: 0x0818, 0x509: 0x0818, 0x50a: 0x0818, 0x50b: 0x0818,\n\t0x50c: 0x0818, 0x50d: 0x0818, 0x50e: 0x0040, 0x50f: 0x0b40, 0x510: 0x0c08, 0x511: 0x3308,\n\t0x512: 0x0a08, 0x513: 0x0a08, 0x514: 0x0a08, 0x515: 0x0c08, 0x516: 0x0c08, 0x517: 0x0c08,\n\t0x518: 0x0c08, 0x519: 0x0c08, 0x51a: 0x0a08, 0x51b: 0x0a08, 0x51c: 0x0a08, 0x51d: 0x0a08,\n\t0x51e: 0x0c08, 0x51f: 0x0a08, 0x520: 0x0a08, 0x521: 0x0a08, 0x522: 0x0a08, 0x523: 0x0a08,\n\t0x524: 0x0a08, 0x525: 0x0a08, 0x526: 0x0a08, 0x527: 0x0a08, 0x528: 0x0c08, 0x529: 0x0a08,\n\t0x52a: 0x0c08, 0x52b: 0x0a08, 0x52c: 0x0c08, 0x52d: 0x0a08, 0x52e: 0x0a08, 0x52f: 0x0c08,\n\t0x530: 0x3308, 0x531: 0x3308, 0x532: 0x3308, 0x533: 0x3308, 0x534: 0x3308, 0x535: 0x3308,\n\t0x536: 0x3308, 0x537: 0x3308, 0x538: 0x3308, 0x539: 0x3308, 0x53a: 0x3308, 0x53b: 0x3308,\n\t0x53c: 0x3308, 0x53d: 0x3308, 0x53e: 0x3308, 0x53f: 0x3308,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x0c08, 0x541: 0x0a08, 0x542: 0x0a08, 0x543: 0x0a08, 0x544: 0x0a08, 0x545: 0x0a08,\n\t0x546: 0x0c08, 0x547: 0x0c08, 0x548: 0x0a08, 0x549: 0x0c08, 0x54a: 0x0a08, 0x54b: 0x0a08,\n\t0x54c: 0x0a08, 0x54d: 0x0a08, 0x54e: 0x0a08, 0x54f: 0x0a08, 0x550: 0x0a08, 0x551: 0x0a08,\n\t0x552: 0x0a08, 0x553: 0x0a08, 0x554: 0x0c08, 0x555: 0x0a08, 0x556: 0x0808, 0x557: 0x0808,\n\t0x558: 0x0808, 0x559: 0x3308, 0x55a: 0x3308, 0x55b: 0x3308, 0x55c: 0x0040, 0x55d: 0x0040,\n\t0x55e: 0x0818, 0x55f: 0x0040, 0x560: 0x0a08, 0x561: 0x0808, 0x562: 0x0a08, 0x563: 0x0a08,\n\t0x564: 0x0a08, 0x565: 0x0a08, 0x566: 0x0808, 0x567: 0x0c08, 0x568: 0x0a08, 0x569: 0x0c08,\n\t0x56a: 0x0c08, 0x56b: 0x0040, 0x56c: 0x0040, 0x56d: 0x0040, 0x56e: 0x0040, 0x56f: 0x0040,\n\t0x570: 0x0040, 0x571: 0x0040, 0x572: 0x0040, 0x573: 0x0040, 0x574: 0x0040, 0x575: 0x0040,\n\t0x576: 0x0040, 0x577: 0x0040, 0x578: 0x0040, 0x579: 0x0040, 0x57a: 0x0040, 0x57b: 0x0040,\n\t0x57c: 0x0040, 0x57d: 0x0040, 0x57e: 0x0040, 0x57f: 0x0040,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x3008, 0x581: 0x3308, 0x582: 0x3308, 0x583: 0x3308, 0x584: 0x3308, 0x585: 0x3308,\n\t0x586: 0x3308, 0x587: 0x3308, 0x588: 0x3308, 0x589: 0x3008, 0x58a: 0x3008, 0x58b: 0x3008,\n\t0x58c: 0x3008, 0x58d: 0x3b08, 0x58e: 0x3008, 0x58f: 0x3008, 0x590: 0x0008, 0x591: 0x3308,\n\t0x592: 0x3308, 0x593: 0x3308, 0x594: 0x3308, 0x595: 0x3308, 0x596: 0x3308, 0x597: 0x3308,\n\t0x598: 0x04c9, 0x599: 0x0501, 0x59a: 0x0539, 0x59b: 0x0571, 0x59c: 0x05a9, 0x59d: 0x05e1,\n\t0x59e: 0x0619, 0x59f: 0x0651, 0x5a0: 0x0008, 0x5a1: 0x0008, 0x5a2: 0x3308, 0x5a3: 0x3308,\n\t0x5a4: 0x0018, 0x5a5: 0x0018, 0x5a6: 0x0008, 0x5a7: 0x0008, 0x5a8: 0x0008, 0x5a9: 0x0008,\n\t0x5aa: 0x0008, 0x5ab: 0x0008, 0x5ac: 0x0008, 0x5ad: 0x0008, 0x5ae: 0x0008, 0x5af: 0x0008,\n\t0x5b0: 0x0018, 0x5b1: 0x0008, 0x5b2: 0x0008, 0x5b3: 0x0008, 0x5b4: 0x0008, 0x5b5: 0x0008,\n\t0x5b6: 0x0008, 0x5b7: 0x0008, 0x5b8: 0x0008, 0x5b9: 0x0008, 0x5ba: 0x0008, 0x5bb: 0x0008,\n\t0x5bc: 0x0008, 0x5bd: 0x0008, 0x5be: 0x0008, 0x5bf: 0x0008,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x0008, 0x5c1: 0x3308, 0x5c2: 0x3008, 0x5c3: 0x3008, 0x5c4: 0x0040, 0x5c5: 0x0008,\n\t0x5c6: 0x0008, 0x5c7: 0x0008, 0x5c8: 0x0008, 0x5c9: 0x0008, 0x5ca: 0x0008, 0x5cb: 0x0008,\n\t0x5cc: 0x0008, 0x5cd: 0x0040, 0x5ce: 0x0040, 0x5cf: 0x0008, 0x5d0: 0x0008, 0x5d1: 0x0040,\n\t0x5d2: 0x0040, 0x5d3: 0x0008, 0x5d4: 0x0008, 0x5d5: 0x0008, 0x5d6: 0x0008, 0x5d7: 0x0008,\n\t0x5d8: 0x0008, 0x5d9: 0x0008, 0x5da: 0x0008, 0x5db: 0x0008, 0x5dc: 0x0008, 0x5dd: 0x0008,\n\t0x5de: 0x0008, 0x5df: 0x0008, 0x5e0: 0x0008, 0x5e1: 0x0008, 0x5e2: 0x0008, 0x5e3: 0x0008,\n\t0x5e4: 0x0008, 0x5e5: 0x0008, 0x5e6: 0x0008, 0x5e7: 0x0008, 0x5e8: 0x0008, 0x5e9: 0x0040,\n\t0x5ea: 0x0008, 0x5eb: 0x0008, 0x5ec: 0x0008, 0x5ed: 0x0008, 0x5ee: 0x0008, 0x5ef: 0x0008,\n\t0x5f0: 0x0008, 0x5f1: 0x0040, 0x5f2: 0x0008, 0x5f3: 0x0040, 0x5f4: 0x0040, 0x5f5: 0x0040,\n\t0x5f6: 0x0008, 0x5f7: 0x0008, 0x5f8: 0x0008, 0x5f9: 0x0008, 0x5fa: 0x0040, 0x5fb: 0x0040,\n\t0x5fc: 0x3308, 0x5fd: 0x0008, 0x5fe: 0x3008, 0x5ff: 0x3008,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x3008, 0x601: 0x3308, 0x602: 0x3308, 0x603: 0x3308, 0x604: 0x3308, 0x605: 0x0040,\n\t0x606: 0x0040, 0x607: 0x3008, 0x608: 0x3008, 0x609: 0x0040, 0x60a: 0x0040, 0x60b: 0x3008,\n\t0x60c: 0x3008, 0x60d: 0x3b08, 0x60e: 0x0008, 0x60f: 0x0040, 0x610: 0x0040, 0x611: 0x0040,\n\t0x612: 0x0040, 0x613: 0x0040, 0x614: 0x0040, 0x615: 0x0040, 0x616: 0x0040, 0x617: 0x3008,\n\t0x618: 0x0040, 0x619: 0x0040, 0x61a: 0x0040, 0x61b: 0x0040, 0x61c: 0x0689, 0x61d: 0x06c1,\n\t0x61e: 0x0040, 0x61f: 0x06f9, 0x620: 0x0008, 0x621: 0x0008, 0x622: 0x3308, 0x623: 0x3308,\n\t0x624: 0x0040, 0x625: 0x0040, 0x626: 0x0008, 0x627: 0x0008, 0x628: 0x0008, 0x629: 0x0008,\n\t0x62a: 0x0008, 0x62b: 0x0008, 0x62c: 0x0008, 0x62d: 0x0008, 0x62e: 0x0008, 0x62f: 0x0008,\n\t0x630: 0x0008, 0x631: 0x0008, 0x632: 0x0018, 0x633: 0x0018, 0x634: 0x0018, 0x635: 0x0018,\n\t0x636: 0x0018, 0x637: 0x0018, 0x638: 0x0018, 0x639: 0x0018, 0x63a: 0x0018, 0x63b: 0x0018,\n\t0x63c: 0x0008, 0x63d: 0x0018, 0x63e: 0x3308, 0x63f: 0x0040,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x0040, 0x641: 0x3308, 0x642: 0x3308, 0x643: 0x3008, 0x644: 0x0040, 0x645: 0x0008,\n\t0x646: 0x0008, 0x647: 0x0008, 0x648: 0x0008, 0x649: 0x0008, 0x64a: 0x0008, 0x64b: 0x0040,\n\t0x64c: 0x0040, 0x64d: 0x0040, 0x64e: 0x0040, 0x64f: 0x0008, 0x650: 0x0008, 0x651: 0x0040,\n\t0x652: 0x0040, 0x653: 0x0008, 0x654: 0x0008, 0x655: 0x0008, 0x656: 0x0008, 0x657: 0x0008,\n\t0x658: 0x0008, 0x659: 0x0008, 0x65a: 0x0008, 0x65b: 0x0008, 0x65c: 0x0008, 0x65d: 0x0008,\n\t0x65e: 0x0008, 0x65f: 0x0008, 0x660: 0x0008, 0x661: 0x0008, 0x662: 0x0008, 0x663: 0x0008,\n\t0x664: 0x0008, 0x665: 0x0008, 0x666: 0x0008, 0x667: 0x0008, 0x668: 0x0008, 0x669: 0x0040,\n\t0x66a: 0x0008, 0x66b: 0x0008, 0x66c: 0x0008, 0x66d: 0x0008, 0x66e: 0x0008, 0x66f: 0x0008,\n\t0x670: 0x0008, 0x671: 0x0040, 0x672: 0x0008, 0x673: 0x0731, 0x674: 0x0040, 0x675: 0x0008,\n\t0x676: 0x0769, 0x677: 0x0040, 0x678: 0x0008, 0x679: 0x0008, 0x67a: 0x0040, 0x67b: 0x0040,\n\t0x67c: 0x3308, 0x67d: 0x0040, 0x67e: 0x3008, 0x67f: 0x3008,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x3008, 0x681: 0x3308, 0x682: 0x3308, 0x683: 0x0040, 0x684: 0x0040, 0x685: 0x0040,\n\t0x686: 0x0040, 0x687: 0x3308, 0x688: 0x3308, 0x689: 0x0040, 0x68a: 0x0040, 0x68b: 0x3308,\n\t0x68c: 0x3308, 0x68d: 0x3b08, 0x68e: 0x0040, 0x68f: 0x0040, 0x690: 0x0040, 0x691: 0x3308,\n\t0x692: 0x0040, 0x693: 0x0040, 0x694: 0x0040, 0x695: 0x0040, 0x696: 0x0040, 0x697: 0x0040,\n\t0x698: 0x0040, 0x699: 0x07a1, 0x69a: 0x07d9, 0x69b: 0x0811, 0x69c: 0x0008, 0x69d: 0x0040,\n\t0x69e: 0x0849, 0x69f: 0x0040, 0x6a0: 0x0040, 0x6a1: 0x0040, 0x6a2: 0x0040, 0x6a3: 0x0040,\n\t0x6a4: 0x0040, 0x6a5: 0x0040, 0x6a6: 0x0008, 0x6a7: 0x0008, 0x6a8: 0x0008, 0x6a9: 0x0008,\n\t0x6aa: 0x0008, 0x6ab: 0x0008, 0x6ac: 0x0008, 0x6ad: 0x0008, 0x6ae: 0x0008, 0x6af: 0x0008,\n\t0x6b0: 0x3308, 0x6b1: 0x3308, 0x6b2: 0x0008, 0x6b3: 0x0008, 0x6b4: 0x0008, 0x6b5: 0x3308,\n\t0x6b6: 0x0018, 0x6b7: 0x0040, 0x6b8: 0x0040, 0x6b9: 0x0040, 0x6ba: 0x0040, 0x6bb: 0x0040,\n\t0x6bc: 0x0040, 0x6bd: 0x0040, 0x6be: 0x0040, 0x6bf: 0x0040,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x0040, 0x6c1: 0x3308, 0x6c2: 0x3308, 0x6c3: 0x3008, 0x6c4: 0x0040, 0x6c5: 0x0008,\n\t0x6c6: 0x0008, 0x6c7: 0x0008, 0x6c8: 0x0008, 0x6c9: 0x0008, 0x6ca: 0x0008, 0x6cb: 0x0008,\n\t0x6cc: 0x0008, 0x6cd: 0x0008, 0x6ce: 0x0040, 0x6cf: 0x0008, 0x6d0: 0x0008, 0x6d1: 0x0008,\n\t0x6d2: 0x0040, 0x6d3: 0x0008, 0x6d4: 0x0008, 0x6d5: 0x0008, 0x6d6: 0x0008, 0x6d7: 0x0008,\n\t0x6d8: 0x0008, 0x6d9: 0x0008, 0x6da: 0x0008, 0x6db: 0x0008, 0x6dc: 0x0008, 0x6dd: 0x0008,\n\t0x6de: 0x0008, 0x6df: 0x0008, 0x6e0: 0x0008, 0x6e1: 0x0008, 0x6e2: 0x0008, 0x6e3: 0x0008,\n\t0x6e4: 0x0008, 0x6e5: 0x0008, 0x6e6: 0x0008, 0x6e7: 0x0008, 0x6e8: 0x0008, 0x6e9: 0x0040,\n\t0x6ea: 0x0008, 0x6eb: 0x0008, 0x6ec: 0x0008, 0x6ed: 0x0008, 0x6ee: 0x0008, 0x6ef: 0x0008,\n\t0x6f0: 0x0008, 0x6f1: 0x0040, 0x6f2: 0x0008, 0x6f3: 0x0008, 0x6f4: 0x0040, 0x6f5: 0x0008,\n\t0x6f6: 0x0008, 0x6f7: 0x0008, 0x6f8: 0x0008, 0x6f9: 0x0008, 0x6fa: 0x0040, 0x6fb: 0x0040,\n\t0x6fc: 0x3308, 0x6fd: 0x0008, 0x6fe: 0x3008, 0x6ff: 0x3008,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x3008, 0x701: 0x3308, 0x702: 0x3308, 0x703: 0x3308, 0x704: 0x3308, 0x705: 0x3308,\n\t0x706: 0x0040, 0x707: 0x3308, 0x708: 0x3308, 0x709: 0x3008, 0x70a: 0x0040, 0x70b: 0x3008,\n\t0x70c: 0x3008, 0x70d: 0x3b08, 0x70e: 0x0040, 0x70f: 0x0040, 0x710: 0x0008, 0x711: 0x0040,\n\t0x712: 0x0040, 0x713: 0x0040, 0x714: 0x0040, 0x715: 0x0040, 0x716: 0x0040, 0x717: 0x0040,\n\t0x718: 0x0040, 0x719: 0x0040, 0x71a: 0x0040, 0x71b: 0x0040, 0x71c: 0x0040, 0x71d: 0x0040,\n\t0x71e: 0x0040, 0x71f: 0x0040, 0x720: 0x0008, 0x721: 0x0008, 0x722: 0x3308, 0x723: 0x3308,\n\t0x724: 0x0040, 0x725: 0x0040, 0x726: 0x0008, 0x727: 0x0008, 0x728: 0x0008, 0x729: 0x0008,\n\t0x72a: 0x0008, 0x72b: 0x0008, 0x72c: 0x0008, 0x72d: 0x0008, 0x72e: 0x0008, 0x72f: 0x0008,\n\t0x730: 0x0018, 0x731: 0x0018, 0x732: 0x0040, 0x733: 0x0040, 0x734: 0x0040, 0x735: 0x0040,\n\t0x736: 0x0040, 0x737: 0x0040, 0x738: 0x0040, 0x739: 0x0008, 0x73a: 0x3308, 0x73b: 0x3308,\n\t0x73c: 0x3308, 0x73d: 0x3308, 0x73e: 0x3308, 0x73f: 0x3308,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x0040, 0x741: 0x3308, 0x742: 0x3008, 0x743: 0x3008, 0x744: 0x0040, 0x745: 0x0008,\n\t0x746: 0x0008, 0x747: 0x0008, 0x748: 0x0008, 0x749: 0x0008, 0x74a: 0x0008, 0x74b: 0x0008,\n\t0x74c: 0x0008, 0x74d: 0x0040, 0x74e: 0x0040, 0x74f: 0x0008, 0x750: 0x0008, 0x751: 0x0040,\n\t0x752: 0x0040, 0x753: 0x0008, 0x754: 0x0008, 0x755: 0x0008, 0x756: 0x0008, 0x757: 0x0008,\n\t0x758: 0x0008, 0x759: 0x0008, 0x75a: 0x0008, 0x75b: 0x0008, 0x75c: 0x0008, 0x75d: 0x0008,\n\t0x75e: 0x0008, 0x75f: 0x0008, 0x760: 0x0008, 0x761: 0x0008, 0x762: 0x0008, 0x763: 0x0008,\n\t0x764: 0x0008, 0x765: 0x0008, 0x766: 0x0008, 0x767: 0x0008, 0x768: 0x0008, 0x769: 0x0040,\n\t0x76a: 0x0008, 0x76b: 0x0008, 0x76c: 0x0008, 0x76d: 0x0008, 0x76e: 0x0008, 0x76f: 0x0008,\n\t0x770: 0x0008, 0x771: 0x0040, 0x772: 0x0008, 0x773: 0x0008, 0x774: 0x0040, 0x775: 0x0008,\n\t0x776: 0x0008, 0x777: 0x0008, 0x778: 0x0008, 0x779: 0x0008, 0x77a: 0x0040, 0x77b: 0x0040,\n\t0x77c: 0x3308, 0x77d: 0x0008, 0x77e: 0x3008, 0x77f: 0x3308,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0x3008, 0x781: 0x3308, 0x782: 0x3308, 0x783: 0x3308, 0x784: 0x3308, 0x785: 0x0040,\n\t0x786: 0x0040, 0x787: 0x3008, 0x788: 0x3008, 0x789: 0x0040, 0x78a: 0x0040, 0x78b: 0x3008,\n\t0x78c: 0x3008, 0x78d: 0x3b08, 0x78e: 0x0040, 0x78f: 0x0040, 0x790: 0x0040, 0x791: 0x0040,\n\t0x792: 0x0040, 0x793: 0x0040, 0x794: 0x0040, 0x795: 0x0040, 0x796: 0x3308, 0x797: 0x3008,\n\t0x798: 0x0040, 0x799: 0x0040, 0x79a: 0x0040, 0x79b: 0x0040, 0x79c: 0x0881, 0x79d: 0x08b9,\n\t0x79e: 0x0040, 0x79f: 0x0008, 0x7a0: 0x0008, 0x7a1: 0x0008, 0x7a2: 0x3308, 0x7a3: 0x3308,\n\t0x7a4: 0x0040, 0x7a5: 0x0040, 0x7a6: 0x0008, 0x7a7: 0x0008, 0x7a8: 0x0008, 0x7a9: 0x0008,\n\t0x7aa: 0x0008, 0x7ab: 0x0008, 0x7ac: 0x0008, 0x7ad: 0x0008, 0x7ae: 0x0008, 0x7af: 0x0008,\n\t0x7b0: 0x0018, 0x7b1: 0x0008, 0x7b2: 0x0018, 0x7b3: 0x0018, 0x7b4: 0x0018, 0x7b5: 0x0018,\n\t0x7b6: 0x0018, 0x7b7: 0x0018, 0x7b8: 0x0040, 0x7b9: 0x0040, 0x7ba: 0x0040, 0x7bb: 0x0040,\n\t0x7bc: 0x0040, 0x7bd: 0x0040, 0x7be: 0x0040, 0x7bf: 0x0040,\n\t// Block 0x1f, offset 0x7c0\n\t0x7c0: 0x0040, 0x7c1: 0x0040, 0x7c2: 0x3308, 0x7c3: 0x0008, 0x7c4: 0x0040, 0x7c5: 0x0008,\n\t0x7c6: 0x0008, 0x7c7: 0x0008, 0x7c8: 0x0008, 0x7c9: 0x0008, 0x7ca: 0x0008, 0x7cb: 0x0040,\n\t0x7cc: 0x0040, 0x7cd: 0x0040, 0x7ce: 0x0008, 0x7cf: 0x0008, 0x7d0: 0x0008, 0x7d1: 0x0040,\n\t0x7d2: 0x0008, 0x7d3: 0x0008, 0x7d4: 0x0008, 0x7d5: 0x0008, 0x7d6: 0x0040, 0x7d7: 0x0040,\n\t0x7d8: 0x0040, 0x7d9: 0x0008, 0x7da: 0x0008, 0x7db: 0x0040, 0x7dc: 0x0008, 0x7dd: 0x0040,\n\t0x7de: 0x0008, 0x7df: 0x0008, 0x7e0: 0x0040, 0x7e1: 0x0040, 0x7e2: 0x0040, 0x7e3: 0x0008,\n\t0x7e4: 0x0008, 0x7e5: 0x0040, 0x7e6: 0x0040, 0x7e7: 0x0040, 0x7e8: 0x0008, 0x7e9: 0x0008,\n\t0x7ea: 0x0008, 0x7eb: 0x0040, 0x7ec: 0x0040, 0x7ed: 0x0040, 0x7ee: 0x0008, 0x7ef: 0x0008,\n\t0x7f0: 0x0008, 0x7f1: 0x0008, 0x7f2: 0x0008, 0x7f3: 0x0008, 0x7f4: 0x0008, 0x7f5: 0x0008,\n\t0x7f6: 0x0008, 0x7f7: 0x0008, 0x7f8: 0x0008, 0x7f9: 0x0008, 0x7fa: 0x0040, 0x7fb: 0x0040,\n\t0x7fc: 0x0040, 0x7fd: 0x0040, 0x7fe: 0x3008, 0x7ff: 0x3008,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x3308, 0x801: 0x3008, 0x802: 0x3008, 0x803: 0x3008, 0x804: 0x3008, 0x805: 0x0040,\n\t0x806: 0x3308, 0x807: 0x3308, 0x808: 0x3308, 0x809: 0x0040, 0x80a: 0x3308, 0x80b: 0x3308,\n\t0x80c: 0x3308, 0x80d: 0x3b08, 0x80e: 0x0040, 0x80f: 0x0040, 0x810: 0x0040, 0x811: 0x0040,\n\t0x812: 0x0040, 0x813: 0x0040, 0x814: 0x0040, 0x815: 0x3308, 0x816: 0x3308, 0x817: 0x0040,\n\t0x818: 0x0008, 0x819: 0x0008, 0x81a: 0x0008, 0x81b: 0x0040, 0x81c: 0x0040, 0x81d: 0x0040,\n\t0x81e: 0x0040, 0x81f: 0x0040, 0x820: 0x0008, 0x821: 0x0008, 0x822: 0x3308, 0x823: 0x3308,\n\t0x824: 0x0040, 0x825: 0x0040, 0x826: 0x0008, 0x827: 0x0008, 0x828: 0x0008, 0x829: 0x0008,\n\t0x82a: 0x0008, 0x82b: 0x0008, 0x82c: 0x0008, 0x82d: 0x0008, 0x82e: 0x0008, 0x82f: 0x0008,\n\t0x830: 0x0040, 0x831: 0x0040, 0x832: 0x0040, 0x833: 0x0040, 0x834: 0x0040, 0x835: 0x0040,\n\t0x836: 0x0040, 0x837: 0x0018, 0x838: 0x0018, 0x839: 0x0018, 0x83a: 0x0018, 0x83b: 0x0018,\n\t0x83c: 0x0018, 0x83d: 0x0018, 0x83e: 0x0018, 0x83f: 0x0018,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x0008, 0x841: 0x3308, 0x842: 0x3008, 0x843: 0x3008, 0x844: 0x0018, 0x845: 0x0008,\n\t0x846: 0x0008, 0x847: 0x0008, 0x848: 0x0008, 0x849: 0x0008, 0x84a: 0x0008, 0x84b: 0x0008,\n\t0x84c: 0x0008, 0x84d: 0x0040, 0x84e: 0x0008, 0x84f: 0x0008, 0x850: 0x0008, 0x851: 0x0040,\n\t0x852: 0x0008, 0x853: 0x0008, 0x854: 0x0008, 0x855: 0x0008, 0x856: 0x0008, 0x857: 0x0008,\n\t0x858: 0x0008, 0x859: 0x0008, 0x85a: 0x0008, 0x85b: 0x0008, 0x85c: 0x0008, 0x85d: 0x0008,\n\t0x85e: 0x0008, 0x85f: 0x0008, 0x860: 0x0008, 0x861: 0x0008, 0x862: 0x0008, 0x863: 0x0008,\n\t0x864: 0x0008, 0x865: 0x0008, 0x866: 0x0008, 0x867: 0x0008, 0x868: 0x0008, 0x869: 0x0040,\n\t0x86a: 0x0008, 0x86b: 0x0008, 0x86c: 0x0008, 0x86d: 0x0008, 0x86e: 0x0008, 0x86f: 0x0008,\n\t0x870: 0x0008, 0x871: 0x0008, 0x872: 0x0008, 0x873: 0x0008, 0x874: 0x0040, 0x875: 0x0008,\n\t0x876: 0x0008, 0x877: 0x0008, 0x878: 0x0008, 0x879: 0x0008, 0x87a: 0x0040, 0x87b: 0x0040,\n\t0x87c: 0x3308, 0x87d: 0x0008, 0x87e: 0x3008, 0x87f: 0x3308,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x3008, 0x881: 0x3008, 0x882: 0x3008, 0x883: 0x3008, 0x884: 0x3008, 0x885: 0x0040,\n\t0x886: 0x3308, 0x887: 0x3008, 0x888: 0x3008, 0x889: 0x0040, 0x88a: 0x3008, 0x88b: 0x3008,\n\t0x88c: 0x3308, 0x88d: 0x3b08, 0x88e: 0x0040, 0x88f: 0x0040, 0x890: 0x0040, 0x891: 0x0040,\n\t0x892: 0x0040, 0x893: 0x0040, 0x894: 0x0040, 0x895: 0x3008, 0x896: 0x3008, 0x897: 0x0040,\n\t0x898: 0x0040, 0x899: 0x0040, 0x89a: 0x0040, 0x89b: 0x0040, 0x89c: 0x0040, 0x89d: 0x0040,\n\t0x89e: 0x0008, 0x89f: 0x0040, 0x8a0: 0x0008, 0x8a1: 0x0008, 0x8a2: 0x3308, 0x8a3: 0x3308,\n\t0x8a4: 0x0040, 0x8a5: 0x0040, 0x8a6: 0x0008, 0x8a7: 0x0008, 0x8a8: 0x0008, 0x8a9: 0x0008,\n\t0x8aa: 0x0008, 0x8ab: 0x0008, 0x8ac: 0x0008, 0x8ad: 0x0008, 0x8ae: 0x0008, 0x8af: 0x0008,\n\t0x8b0: 0x0040, 0x8b1: 0x0008, 0x8b2: 0x0008, 0x8b3: 0x0040, 0x8b4: 0x0040, 0x8b5: 0x0040,\n\t0x8b6: 0x0040, 0x8b7: 0x0040, 0x8b8: 0x0040, 0x8b9: 0x0040, 0x8ba: 0x0040, 0x8bb: 0x0040,\n\t0x8bc: 0x0040, 0x8bd: 0x0040, 0x8be: 0x0040, 0x8bf: 0x0040,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x3008, 0x8c1: 0x3308, 0x8c2: 0x3308, 0x8c3: 0x3308, 0x8c4: 0x3308, 0x8c5: 0x0040,\n\t0x8c6: 0x3008, 0x8c7: 0x3008, 0x8c8: 0x3008, 0x8c9: 0x0040, 0x8ca: 0x3008, 0x8cb: 0x3008,\n\t0x8cc: 0x3008, 0x8cd: 0x3b08, 0x8ce: 0x0008, 0x8cf: 0x0018, 0x8d0: 0x0040, 0x8d1: 0x0040,\n\t0x8d2: 0x0040, 0x8d3: 0x0040, 0x8d4: 0x0008, 0x8d5: 0x0008, 0x8d6: 0x0008, 0x8d7: 0x3008,\n\t0x8d8: 0x0018, 0x8d9: 0x0018, 0x8da: 0x0018, 0x8db: 0x0018, 0x8dc: 0x0018, 0x8dd: 0x0018,\n\t0x8de: 0x0018, 0x8df: 0x0008, 0x8e0: 0x0008, 0x8e1: 0x0008, 0x8e2: 0x3308, 0x8e3: 0x3308,\n\t0x8e4: 0x0040, 0x8e5: 0x0040, 0x8e6: 0x0008, 0x8e7: 0x0008, 0x8e8: 0x0008, 0x8e9: 0x0008,\n\t0x8ea: 0x0008, 0x8eb: 0x0008, 0x8ec: 0x0008, 0x8ed: 0x0008, 0x8ee: 0x0008, 0x8ef: 0x0008,\n\t0x8f0: 0x0018, 0x8f1: 0x0018, 0x8f2: 0x0018, 0x8f3: 0x0018, 0x8f4: 0x0018, 0x8f5: 0x0018,\n\t0x8f6: 0x0018, 0x8f7: 0x0018, 0x8f8: 0x0018, 0x8f9: 0x0018, 0x8fa: 0x0008, 0x8fb: 0x0008,\n\t0x8fc: 0x0008, 0x8fd: 0x0008, 0x8fe: 0x0008, 0x8ff: 0x0008,\n\t// Block 0x24, offset 0x900\n\t0x900: 0x0040, 0x901: 0x0008, 0x902: 0x0008, 0x903: 0x0040, 0x904: 0x0008, 0x905: 0x0040,\n\t0x906: 0x0008, 0x907: 0x0008, 0x908: 0x0008, 0x909: 0x0008, 0x90a: 0x0008, 0x90b: 0x0040,\n\t0x90c: 0x0008, 0x90d: 0x0008, 0x90e: 0x0008, 0x90f: 0x0008, 0x910: 0x0008, 0x911: 0x0008,\n\t0x912: 0x0008, 0x913: 0x0008, 0x914: 0x0008, 0x915: 0x0008, 0x916: 0x0008, 0x917: 0x0008,\n\t0x918: 0x0008, 0x919: 0x0008, 0x91a: 0x0008, 0x91b: 0x0008, 0x91c: 0x0008, 0x91d: 0x0008,\n\t0x91e: 0x0008, 0x91f: 0x0008, 0x920: 0x0008, 0x921: 0x0008, 0x922: 0x0008, 0x923: 0x0008,\n\t0x924: 0x0040, 0x925: 0x0008, 0x926: 0x0040, 0x927: 0x0008, 0x928: 0x0008, 0x929: 0x0008,\n\t0x92a: 0x0008, 0x92b: 0x0008, 0x92c: 0x0008, 0x92d: 0x0008, 0x92e: 0x0008, 0x92f: 0x0008,\n\t0x930: 0x0008, 0x931: 0x3308, 0x932: 0x0008, 0x933: 0x0929, 0x934: 0x3308, 0x935: 0x3308,\n\t0x936: 0x3308, 0x937: 0x3308, 0x938: 0x3308, 0x939: 0x3308, 0x93a: 0x3b08, 0x93b: 0x3308,\n\t0x93c: 0x3308, 0x93d: 0x0008, 0x93e: 0x0040, 0x93f: 0x0040,\n\t// Block 0x25, offset 0x940\n\t0x940: 0x0008, 0x941: 0x0008, 0x942: 0x0008, 0x943: 0x09d1, 0x944: 0x0008, 0x945: 0x0008,\n\t0x946: 0x0008, 0x947: 0x0008, 0x948: 0x0040, 0x949: 0x0008, 0x94a: 0x0008, 0x94b: 0x0008,\n\t0x94c: 0x0008, 0x94d: 0x0a09, 0x94e: 0x0008, 0x94f: 0x0008, 0x950: 0x0008, 0x951: 0x0008,\n\t0x952: 0x0a41, 0x953: 0x0008, 0x954: 0x0008, 0x955: 0x0008, 0x956: 0x0008, 0x957: 0x0a79,\n\t0x958: 0x0008, 0x959: 0x0008, 0x95a: 0x0008, 0x95b: 0x0008, 0x95c: 0x0ab1, 0x95d: 0x0008,\n\t0x95e: 0x0008, 0x95f: 0x0008, 0x960: 0x0008, 0x961: 0x0008, 0x962: 0x0008, 0x963: 0x0008,\n\t0x964: 0x0008, 0x965: 0x0008, 0x966: 0x0008, 0x967: 0x0008, 0x968: 0x0008, 0x969: 0x0ae9,\n\t0x96a: 0x0008, 0x96b: 0x0008, 0x96c: 0x0008, 0x96d: 0x0040, 0x96e: 0x0040, 0x96f: 0x0040,\n\t0x970: 0x0040, 0x971: 0x3308, 0x972: 0x3308, 0x973: 0x0b21, 0x974: 0x3308, 0x975: 0x0b59,\n\t0x976: 0x0b91, 0x977: 0x0bc9, 0x978: 0x0c19, 0x979: 0x0c51, 0x97a: 0x3308, 0x97b: 0x3308,\n\t0x97c: 0x3308, 0x97d: 0x3308, 0x97e: 0x3308, 0x97f: 0x3008,\n\t// Block 0x26, offset 0x980\n\t0x980: 0x3308, 0x981: 0x0ca1, 0x982: 0x3308, 0x983: 0x3308, 0x984: 0x3b08, 0x985: 0x0018,\n\t0x986: 0x3308, 0x987: 0x3308, 0x988: 0x0008, 0x989: 0x0008, 0x98a: 0x0008, 0x98b: 0x0008,\n\t0x98c: 0x0008, 0x98d: 0x3308, 0x98e: 0x3308, 0x98f: 0x3308, 0x990: 0x3308, 0x991: 0x3308,\n\t0x992: 0x3308, 0x993: 0x0cd9, 0x994: 0x3308, 0x995: 0x3308, 0x996: 0x3308, 0x997: 0x3308,\n\t0x998: 0x0040, 0x999: 0x3308, 0x99a: 0x3308, 0x99b: 0x3308, 0x99c: 0x3308, 0x99d: 0x0d11,\n\t0x99e: 0x3308, 0x99f: 0x3308, 0x9a0: 0x3308, 0x9a1: 0x3308, 0x9a2: 0x0d49, 0x9a3: 0x3308,\n\t0x9a4: 0x3308, 0x9a5: 0x3308, 0x9a6: 0x3308, 0x9a7: 0x0d81, 0x9a8: 0x3308, 0x9a9: 0x3308,\n\t0x9aa: 0x3308, 0x9ab: 0x3308, 0x9ac: 0x0db9, 0x9ad: 0x3308, 0x9ae: 0x3308, 0x9af: 0x3308,\n\t0x9b0: 0x3308, 0x9b1: 0x3308, 0x9b2: 0x3308, 0x9b3: 0x3308, 0x9b4: 0x3308, 0x9b5: 0x3308,\n\t0x9b6: 0x3308, 0x9b7: 0x3308, 0x9b8: 0x3308, 0x9b9: 0x0df1, 0x9ba: 0x3308, 0x9bb: 0x3308,\n\t0x9bc: 0x3308, 0x9bd: 0x0040, 0x9be: 0x0018, 0x9bf: 0x0018,\n\t// Block 0x27, offset 0x9c0\n\t0x9c0: 0x0008, 0x9c1: 0x0008, 0x9c2: 0x0008, 0x9c3: 0x0008, 0x9c4: 0x0008, 0x9c5: 0x0008,\n\t0x9c6: 0x0008, 0x9c7: 0x0008, 0x9c8: 0x0008, 0x9c9: 0x0008, 0x9ca: 0x0008, 0x9cb: 0x0008,\n\t0x9cc: 0x0008, 0x9cd: 0x0008, 0x9ce: 0x0008, 0x9cf: 0x0008, 0x9d0: 0x0008, 0x9d1: 0x0008,\n\t0x9d2: 0x0008, 0x9d3: 0x0008, 0x9d4: 0x0008, 0x9d5: 0x0008, 0x9d6: 0x0008, 0x9d7: 0x0008,\n\t0x9d8: 0x0008, 0x9d9: 0x0008, 0x9da: 0x0008, 0x9db: 0x0008, 0x9dc: 0x0008, 0x9dd: 0x0008,\n\t0x9de: 0x0008, 0x9df: 0x0008, 0x9e0: 0x0008, 0x9e1: 0x0008, 0x9e2: 0x0008, 0x9e3: 0x0008,\n\t0x9e4: 0x0008, 0x9e5: 0x0008, 0x9e6: 0x0008, 0x9e7: 0x0008, 0x9e8: 0x0008, 0x9e9: 0x0008,\n\t0x9ea: 0x0008, 0x9eb: 0x0008, 0x9ec: 0x0039, 0x9ed: 0x0ed1, 0x9ee: 0x0ee9, 0x9ef: 0x0008,\n\t0x9f0: 0x0ef9, 0x9f1: 0x0f09, 0x9f2: 0x0f19, 0x9f3: 0x0f31, 0x9f4: 0x0249, 0x9f5: 0x0f41,\n\t0x9f6: 0x0259, 0x9f7: 0x0f51, 0x9f8: 0x0359, 0x9f9: 0x0f61, 0x9fa: 0x0f71, 0x9fb: 0x0008,\n\t0x9fc: 0x00d9, 0x9fd: 0x0f81, 0x9fe: 0x0f99, 0x9ff: 0x0269,\n\t// Block 0x28, offset 0xa00\n\t0xa00: 0x0fa9, 0xa01: 0x0fb9, 0xa02: 0x0279, 0xa03: 0x0039, 0xa04: 0x0fc9, 0xa05: 0x0fe1,\n\t0xa06: 0x05b5, 0xa07: 0x0ee9, 0xa08: 0x0ef9, 0xa09: 0x0f09, 0xa0a: 0x0ff9, 0xa0b: 0x1011,\n\t0xa0c: 0x1029, 0xa0d: 0x0f31, 0xa0e: 0x0008, 0xa0f: 0x0f51, 0xa10: 0x0f61, 0xa11: 0x1041,\n\t0xa12: 0x00d9, 0xa13: 0x1059, 0xa14: 0x05cd, 0xa15: 0x05cd, 0xa16: 0x0f99, 0xa17: 0x0fa9,\n\t0xa18: 0x0fb9, 0xa19: 0x05b5, 0xa1a: 0x1071, 0xa1b: 0x1089, 0xa1c: 0x05e5, 0xa1d: 0x1099,\n\t0xa1e: 0x10b1, 0xa1f: 0x10c9, 0xa20: 0x10e1, 0xa21: 0x10f9, 0xa22: 0x0f41, 0xa23: 0x0269,\n\t0xa24: 0x0fb9, 0xa25: 0x1089, 0xa26: 0x1099, 0xa27: 0x10b1, 0xa28: 0x1111, 0xa29: 0x10e1,\n\t0xa2a: 0x10f9, 0xa2b: 0x0008, 0xa2c: 0x0008, 0xa2d: 0x0008, 0xa2e: 0x0008, 0xa2f: 0x0008,\n\t0xa30: 0x0008, 0xa31: 0x0008, 0xa32: 0x0008, 0xa33: 0x0008, 0xa34: 0x0008, 0xa35: 0x0008,\n\t0xa36: 0x0008, 0xa37: 0x0008, 0xa38: 0x1129, 0xa39: 0x0008, 0xa3a: 0x0008, 0xa3b: 0x0008,\n\t0xa3c: 0x0008, 0xa3d: 0x0008, 0xa3e: 0x0008, 0xa3f: 0x0008,\n\t// Block 0x29, offset 0xa40\n\t0xa40: 0x0008, 0xa41: 0x0008, 0xa42: 0x0008, 0xa43: 0x0008, 0xa44: 0x0008, 0xa45: 0x0008,\n\t0xa46: 0x0008, 0xa47: 0x0008, 0xa48: 0x0008, 0xa49: 0x0008, 0xa4a: 0x0008, 0xa4b: 0x0008,\n\t0xa4c: 0x0008, 0xa4d: 0x0008, 0xa4e: 0x0008, 0xa4f: 0x0008, 0xa50: 0x0008, 0xa51: 0x0008,\n\t0xa52: 0x0008, 0xa53: 0x0008, 0xa54: 0x0008, 0xa55: 0x0008, 0xa56: 0x0008, 0xa57: 0x0008,\n\t0xa58: 0x0008, 0xa59: 0x0008, 0xa5a: 0x0008, 0xa5b: 0x1141, 0xa5c: 0x1159, 0xa5d: 0x1169,\n\t0xa5e: 0x1181, 0xa5f: 0x1029, 0xa60: 0x1199, 0xa61: 0x11a9, 0xa62: 0x11c1, 0xa63: 0x11d9,\n\t0xa64: 0x11f1, 0xa65: 0x1209, 0xa66: 0x1221, 0xa67: 0x05fd, 0xa68: 0x1239, 0xa69: 0x1251,\n\t0xa6a: 0xe17d, 0xa6b: 0x1269, 0xa6c: 0x1281, 0xa6d: 0x1299, 0xa6e: 0x12b1, 0xa6f: 0x12c9,\n\t0xa70: 0x12e1, 0xa71: 0x12f9, 0xa72: 0x1311, 0xa73: 0x1329, 0xa74: 0x1341, 0xa75: 0x1359,\n\t0xa76: 0x1371, 0xa77: 0x1389, 0xa78: 0x0615, 0xa79: 0x13a1, 0xa7a: 0x13b9, 0xa7b: 0x13d1,\n\t0xa7c: 0x13e1, 0xa7d: 0x13f9, 0xa7e: 0x1411, 0xa7f: 0x1429,\n\t// Block 0x2a, offset 0xa80\n\t0xa80: 0xe00d, 0xa81: 0x0008, 0xa82: 0xe00d, 0xa83: 0x0008, 0xa84: 0xe00d, 0xa85: 0x0008,\n\t0xa86: 0xe00d, 0xa87: 0x0008, 0xa88: 0xe00d, 0xa89: 0x0008, 0xa8a: 0xe00d, 0xa8b: 0x0008,\n\t0xa8c: 0xe00d, 0xa8d: 0x0008, 0xa8e: 0xe00d, 0xa8f: 0x0008, 0xa90: 0xe00d, 0xa91: 0x0008,\n\t0xa92: 0xe00d, 0xa93: 0x0008, 0xa94: 0xe00d, 0xa95: 0x0008, 0xa96: 0xe00d, 0xa97: 0x0008,\n\t0xa98: 0xe00d, 0xa99: 0x0008, 0xa9a: 0xe00d, 0xa9b: 0x0008, 0xa9c: 0xe00d, 0xa9d: 0x0008,\n\t0xa9e: 0xe00d, 0xa9f: 0x0008, 0xaa0: 0xe00d, 0xaa1: 0x0008, 0xaa2: 0xe00d, 0xaa3: 0x0008,\n\t0xaa4: 0xe00d, 0xaa5: 0x0008, 0xaa6: 0xe00d, 0xaa7: 0x0008, 0xaa8: 0xe00d, 0xaa9: 0x0008,\n\t0xaaa: 0xe00d, 0xaab: 0x0008, 0xaac: 0xe00d, 0xaad: 0x0008, 0xaae: 0xe00d, 0xaaf: 0x0008,\n\t0xab0: 0xe00d, 0xab1: 0x0008, 0xab2: 0xe00d, 0xab3: 0x0008, 0xab4: 0xe00d, 0xab5: 0x0008,\n\t0xab6: 0xe00d, 0xab7: 0x0008, 0xab8: 0xe00d, 0xab9: 0x0008, 0xaba: 0xe00d, 0xabb: 0x0008,\n\t0xabc: 0xe00d, 0xabd: 0x0008, 0xabe: 0xe00d, 0xabf: 0x0008,\n\t// Block 0x2b, offset 0xac0\n\t0xac0: 0xe00d, 0xac1: 0x0008, 0xac2: 0xe00d, 0xac3: 0x0008, 0xac4: 0xe00d, 0xac5: 0x0008,\n\t0xac6: 0xe00d, 0xac7: 0x0008, 0xac8: 0xe00d, 0xac9: 0x0008, 0xaca: 0xe00d, 0xacb: 0x0008,\n\t0xacc: 0xe00d, 0xacd: 0x0008, 0xace: 0xe00d, 0xacf: 0x0008, 0xad0: 0xe00d, 0xad1: 0x0008,\n\t0xad2: 0xe00d, 0xad3: 0x0008, 0xad4: 0xe00d, 0xad5: 0x0008, 0xad6: 0x0008, 0xad7: 0x0008,\n\t0xad8: 0x0008, 0xad9: 0x0008, 0xada: 0x062d, 0xadb: 0x064d, 0xadc: 0x0008, 0xadd: 0x0008,\n\t0xade: 0x1441, 0xadf: 0x0008, 0xae0: 0xe00d, 0xae1: 0x0008, 0xae2: 0xe00d, 0xae3: 0x0008,\n\t0xae4: 0xe00d, 0xae5: 0x0008, 0xae6: 0xe00d, 0xae7: 0x0008, 0xae8: 0xe00d, 0xae9: 0x0008,\n\t0xaea: 0xe00d, 0xaeb: 0x0008, 0xaec: 0xe00d, 0xaed: 0x0008, 0xaee: 0xe00d, 0xaef: 0x0008,\n\t0xaf0: 0xe00d, 0xaf1: 0x0008, 0xaf2: 0xe00d, 0xaf3: 0x0008, 0xaf4: 0xe00d, 0xaf5: 0x0008,\n\t0xaf6: 0xe00d, 0xaf7: 0x0008, 0xaf8: 0xe00d, 0xaf9: 0x0008, 0xafa: 0xe00d, 0xafb: 0x0008,\n\t0xafc: 0xe00d, 0xafd: 0x0008, 0xafe: 0xe00d, 0xaff: 0x0008,\n\t// Block 0x2c, offset 0xb00\n\t0xb00: 0x0008, 0xb01: 0x0008, 0xb02: 0x0008, 0xb03: 0x0008, 0xb04: 0x0008, 0xb05: 0x0008,\n\t0xb06: 0x0040, 0xb07: 0x0040, 0xb08: 0xe045, 0xb09: 0xe045, 0xb0a: 0xe045, 0xb0b: 0xe045,\n\t0xb0c: 0xe045, 0xb0d: 0xe045, 0xb0e: 0x0040, 0xb0f: 0x0040, 0xb10: 0x0008, 0xb11: 0x0008,\n\t0xb12: 0x0008, 0xb13: 0x0008, 0xb14: 0x0008, 0xb15: 0x0008, 0xb16: 0x0008, 0xb17: 0x0008,\n\t0xb18: 0x0040, 0xb19: 0xe045, 0xb1a: 0x0040, 0xb1b: 0xe045, 0xb1c: 0x0040, 0xb1d: 0xe045,\n\t0xb1e: 0x0040, 0xb1f: 0xe045, 0xb20: 0x0008, 0xb21: 0x0008, 0xb22: 0x0008, 0xb23: 0x0008,\n\t0xb24: 0x0008, 0xb25: 0x0008, 0xb26: 0x0008, 0xb27: 0x0008, 0xb28: 0xe045, 0xb29: 0xe045,\n\t0xb2a: 0xe045, 0xb2b: 0xe045, 0xb2c: 0xe045, 0xb2d: 0xe045, 0xb2e: 0xe045, 0xb2f: 0xe045,\n\t0xb30: 0x0008, 0xb31: 0x1459, 0xb32: 0x0008, 0xb33: 0x1471, 0xb34: 0x0008, 0xb35: 0x1489,\n\t0xb36: 0x0008, 0xb37: 0x14a1, 0xb38: 0x0008, 0xb39: 0x14b9, 0xb3a: 0x0008, 0xb3b: 0x14d1,\n\t0xb3c: 0x0008, 0xb3d: 0x14e9, 0xb3e: 0x0040, 0xb3f: 0x0040,\n\t// Block 0x2d, offset 0xb40\n\t0xb40: 0x1501, 0xb41: 0x1531, 0xb42: 0x1561, 0xb43: 0x1591, 0xb44: 0x15c1, 0xb45: 0x15f1,\n\t0xb46: 0x1621, 0xb47: 0x1651, 0xb48: 0x1501, 0xb49: 0x1531, 0xb4a: 0x1561, 0xb4b: 0x1591,\n\t0xb4c: 0x15c1, 0xb4d: 0x15f1, 0xb4e: 0x1621, 0xb4f: 0x1651, 0xb50: 0x1681, 0xb51: 0x16b1,\n\t0xb52: 0x16e1, 0xb53: 0x1711, 0xb54: 0x1741, 0xb55: 0x1771, 0xb56: 0x17a1, 0xb57: 0x17d1,\n\t0xb58: 0x1681, 0xb59: 0x16b1, 0xb5a: 0x16e1, 0xb5b: 0x1711, 0xb5c: 0x1741, 0xb5d: 0x1771,\n\t0xb5e: 0x17a1, 0xb5f: 0x17d1, 0xb60: 0x1801, 0xb61: 0x1831, 0xb62: 0x1861, 0xb63: 0x1891,\n\t0xb64: 0x18c1, 0xb65: 0x18f1, 0xb66: 0x1921, 0xb67: 0x1951, 0xb68: 0x1801, 0xb69: 0x1831,\n\t0xb6a: 0x1861, 0xb6b: 0x1891, 0xb6c: 0x18c1, 0xb6d: 0x18f1, 0xb6e: 0x1921, 0xb6f: 0x1951,\n\t0xb70: 0x0008, 0xb71: 0x0008, 0xb72: 0x1981, 0xb73: 0x19b1, 0xb74: 0x19d9, 0xb75: 0x0040,\n\t0xb76: 0x0008, 0xb77: 0x1a01, 0xb78: 0xe045, 0xb79: 0xe045, 0xb7a: 0x0665, 0xb7b: 0x1459,\n\t0xb7c: 0x19b1, 0xb7d: 0x067e, 0xb7e: 0x1a31, 0xb7f: 0x069e,\n\t// Block 0x2e, offset 0xb80\n\t0xb80: 0x06be, 0xb81: 0x1a4a, 0xb82: 0x1a79, 0xb83: 0x1aa9, 0xb84: 0x1ad1, 0xb85: 0x0040,\n\t0xb86: 0x0008, 0xb87: 0x1af9, 0xb88: 0x06dd, 0xb89: 0x1471, 0xb8a: 0x06f5, 0xb8b: 0x1489,\n\t0xb8c: 0x1aa9, 0xb8d: 0x1b2a, 0xb8e: 0x1b5a, 0xb8f: 0x1b8a, 0xb90: 0x0008, 0xb91: 0x0008,\n\t0xb92: 0x0008, 0xb93: 0x1bb9, 0xb94: 0x0040, 0xb95: 0x0040, 0xb96: 0x0008, 0xb97: 0x0008,\n\t0xb98: 0xe045, 0xb99: 0xe045, 0xb9a: 0x070d, 0xb9b: 0x14a1, 0xb9c: 0x0040, 0xb9d: 0x1bd2,\n\t0xb9e: 0x1c02, 0xb9f: 0x1c32, 0xba0: 0x0008, 0xba1: 0x0008, 0xba2: 0x0008, 0xba3: 0x1c61,\n\t0xba4: 0x0008, 0xba5: 0x0008, 0xba6: 0x0008, 0xba7: 0x0008, 0xba8: 0xe045, 0xba9: 0xe045,\n\t0xbaa: 0x0725, 0xbab: 0x14d1, 0xbac: 0xe04d, 0xbad: 0x1c7a, 0xbae: 0x03d2, 0xbaf: 0x1caa,\n\t0xbb0: 0x0040, 0xbb1: 0x0040, 0xbb2: 0x1cb9, 0xbb3: 0x1ce9, 0xbb4: 0x1d11, 0xbb5: 0x0040,\n\t0xbb6: 0x0008, 0xbb7: 0x1d39, 0xbb8: 0x073d, 0xbb9: 0x14b9, 0xbba: 0x0515, 0xbbb: 0x14e9,\n\t0xbbc: 0x1ce9, 0xbbd: 0x0756, 0xbbe: 0x0776, 0xbbf: 0x0040,\n\t// Block 0x2f, offset 0xbc0\n\t0xbc0: 0x000a, 0xbc1: 0x000a, 0xbc2: 0x000a, 0xbc3: 0x000a, 0xbc4: 0x000a, 0xbc5: 0x000a,\n\t0xbc6: 0x000a, 0xbc7: 0x000a, 0xbc8: 0x000a, 0xbc9: 0x000a, 0xbca: 0x000a, 0xbcb: 0x03c0,\n\t0xbcc: 0x0003, 0xbcd: 0x0003, 0xbce: 0x0340, 0xbcf: 0x0b40, 0xbd0: 0x0018, 0xbd1: 0xe00d,\n\t0xbd2: 0x0018, 0xbd3: 0x0018, 0xbd4: 0x0018, 0xbd5: 0x0018, 0xbd6: 0x0018, 0xbd7: 0x0796,\n\t0xbd8: 0x0018, 0xbd9: 0x0018, 0xbda: 0x0018, 0xbdb: 0x0018, 0xbdc: 0x0018, 0xbdd: 0x0018,\n\t0xbde: 0x0018, 0xbdf: 0x0018, 0xbe0: 0x0018, 0xbe1: 0x0018, 0xbe2: 0x0018, 0xbe3: 0x0018,\n\t0xbe4: 0x0040, 0xbe5: 0x0040, 0xbe6: 0x0040, 0xbe7: 0x0018, 0xbe8: 0x0040, 0xbe9: 0x0040,\n\t0xbea: 0x0340, 0xbeb: 0x0340, 0xbec: 0x0340, 0xbed: 0x0340, 0xbee: 0x0340, 0xbef: 0x000a,\n\t0xbf0: 0x0018, 0xbf1: 0x0018, 0xbf2: 0x0018, 0xbf3: 0x1d69, 0xbf4: 0x1da1, 0xbf5: 0x0018,\n\t0xbf6: 0x1df1, 0xbf7: 0x1e29, 0xbf8: 0x0018, 0xbf9: 0x0018, 0xbfa: 0x0018, 0xbfb: 0x0018,\n\t0xbfc: 0x1e7a, 0xbfd: 0x0018, 0xbfe: 0x07b6, 0xbff: 0x0018,\n\t// Block 0x30, offset 0xc00\n\t0xc00: 0x0018, 0xc01: 0x0018, 0xc02: 0x0018, 0xc03: 0x0018, 0xc04: 0x0018, 0xc05: 0x0018,\n\t0xc06: 0x0018, 0xc07: 0x1e92, 0xc08: 0x1eaa, 0xc09: 0x1ec2, 0xc0a: 0x0018, 0xc0b: 0x0018,\n\t0xc0c: 0x0018, 0xc0d: 0x0018, 0xc0e: 0x0018, 0xc0f: 0x0018, 0xc10: 0x0018, 0xc11: 0x0018,\n\t0xc12: 0x0018, 0xc13: 0x0018, 0xc14: 0x0018, 0xc15: 0x0018, 0xc16: 0x0018, 0xc17: 0x1ed9,\n\t0xc18: 0x0018, 0xc19: 0x0018, 0xc1a: 0x0018, 0xc1b: 0x0018, 0xc1c: 0x0018, 0xc1d: 0x0018,\n\t0xc1e: 0x0018, 0xc1f: 0x000a, 0xc20: 0x03c0, 0xc21: 0x0340, 0xc22: 0x0340, 0xc23: 0x0340,\n\t0xc24: 0x03c0, 0xc25: 0x0040, 0xc26: 0x0040, 0xc27: 0x0040, 0xc28: 0x0040, 0xc29: 0x0040,\n\t0xc2a: 0x0340, 0xc2b: 0x0340, 0xc2c: 0x0340, 0xc2d: 0x0340, 0xc2e: 0x0340, 0xc2f: 0x0340,\n\t0xc30: 0x1f41, 0xc31: 0x0f41, 0xc32: 0x0040, 0xc33: 0x0040, 0xc34: 0x1f51, 0xc35: 0x1f61,\n\t0xc36: 0x1f71, 0xc37: 0x1f81, 0xc38: 0x1f91, 0xc39: 0x1fa1, 0xc3a: 0x1fb2, 0xc3b: 0x07d5,\n\t0xc3c: 0x1fc2, 0xc3d: 0x1fd2, 0xc3e: 0x1fe2, 0xc3f: 0x0f71,\n\t// Block 0x31, offset 0xc40\n\t0xc40: 0x1f41, 0xc41: 0x00c9, 0xc42: 0x0069, 0xc43: 0x0079, 0xc44: 0x1f51, 0xc45: 0x1f61,\n\t0xc46: 0x1f71, 0xc47: 0x1f81, 0xc48: 0x1f91, 0xc49: 0x1fa1, 0xc4a: 0x1fb2, 0xc4b: 0x07ed,\n\t0xc4c: 0x1fc2, 0xc4d: 0x1fd2, 0xc4e: 0x1fe2, 0xc4f: 0x0040, 0xc50: 0x0039, 0xc51: 0x0f09,\n\t0xc52: 0x00d9, 0xc53: 0x0369, 0xc54: 0x0ff9, 0xc55: 0x0249, 0xc56: 0x0f51, 0xc57: 0x0359,\n\t0xc58: 0x0f61, 0xc59: 0x0f71, 0xc5a: 0x0f99, 0xc5b: 0x01d9, 0xc5c: 0x0fa9, 0xc5d: 0x0040,\n\t0xc5e: 0x0040, 0xc5f: 0x0040, 0xc60: 0x0018, 0xc61: 0x0018, 0xc62: 0x0018, 0xc63: 0x0018,\n\t0xc64: 0x0018, 0xc65: 0x0018, 0xc66: 0x0018, 0xc67: 0x0018, 0xc68: 0x1ff1, 0xc69: 0x0018,\n\t0xc6a: 0x0018, 0xc6b: 0x0018, 0xc6c: 0x0018, 0xc6d: 0x0018, 0xc6e: 0x0018, 0xc6f: 0x0018,\n\t0xc70: 0x0018, 0xc71: 0x0018, 0xc72: 0x0018, 0xc73: 0x0018, 0xc74: 0x0018, 0xc75: 0x0018,\n\t0xc76: 0x0018, 0xc77: 0x0018, 0xc78: 0x0018, 0xc79: 0x0018, 0xc7a: 0x0018, 0xc7b: 0x0018,\n\t0xc7c: 0x0018, 0xc7d: 0x0018, 0xc7e: 0x0018, 0xc7f: 0x0018,\n\t// Block 0x32, offset 0xc80\n\t0xc80: 0x0806, 0xc81: 0x0826, 0xc82: 0x1159, 0xc83: 0x0845, 0xc84: 0x0018, 0xc85: 0x0866,\n\t0xc86: 0x0886, 0xc87: 0x1011, 0xc88: 0x0018, 0xc89: 0x08a5, 0xc8a: 0x0f31, 0xc8b: 0x0249,\n\t0xc8c: 0x0249, 0xc8d: 0x0249, 0xc8e: 0x0249, 0xc8f: 0x2009, 0xc90: 0x0f41, 0xc91: 0x0f41,\n\t0xc92: 0x0359, 0xc93: 0x0359, 0xc94: 0x0018, 0xc95: 0x0f71, 0xc96: 0x2021, 0xc97: 0x0018,\n\t0xc98: 0x0018, 0xc99: 0x0f99, 0xc9a: 0x2039, 0xc9b: 0x0269, 0xc9c: 0x0269, 0xc9d: 0x0269,\n\t0xc9e: 0x0018, 0xc9f: 0x0018, 0xca0: 0x2049, 0xca1: 0x08c5, 0xca2: 0x2061, 0xca3: 0x0018,\n\t0xca4: 0x13d1, 0xca5: 0x0018, 0xca6: 0x2079, 0xca7: 0x0018, 0xca8: 0x13d1, 0xca9: 0x0018,\n\t0xcaa: 0x0f51, 0xcab: 0x2091, 0xcac: 0x0ee9, 0xcad: 0x1159, 0xcae: 0x0018, 0xcaf: 0x0f09,\n\t0xcb0: 0x0f09, 0xcb1: 0x1199, 0xcb2: 0x0040, 0xcb3: 0x0f61, 0xcb4: 0x00d9, 0xcb5: 0x20a9,\n\t0xcb6: 0x20c1, 0xcb7: 0x20d9, 0xcb8: 0x20f1, 0xcb9: 0x0f41, 0xcba: 0x0018, 0xcbb: 0x08e5,\n\t0xcbc: 0x2109, 0xcbd: 0x10b1, 0xcbe: 0x10b1, 0xcbf: 0x2109,\n\t// Block 0x33, offset 0xcc0\n\t0xcc0: 0x0905, 0xcc1: 0x0018, 0xcc2: 0x0018, 0xcc3: 0x0018, 0xcc4: 0x0018, 0xcc5: 0x0ef9,\n\t0xcc6: 0x0ef9, 0xcc7: 0x0f09, 0xcc8: 0x0f41, 0xcc9: 0x0259, 0xcca: 0x0018, 0xccb: 0x0018,\n\t0xccc: 0x0018, 0xccd: 0x0018, 0xcce: 0x0008, 0xccf: 0x0018, 0xcd0: 0x2121, 0xcd1: 0x2151,\n\t0xcd2: 0x2181, 0xcd3: 0x21b9, 0xcd4: 0x21e9, 0xcd5: 0x2219, 0xcd6: 0x2249, 0xcd7: 0x2279,\n\t0xcd8: 0x22a9, 0xcd9: 0x22d9, 0xcda: 0x2309, 0xcdb: 0x2339, 0xcdc: 0x2369, 0xcdd: 0x2399,\n\t0xcde: 0x23c9, 0xcdf: 0x23f9, 0xce0: 0x0f41, 0xce1: 0x2421, 0xce2: 0x091d, 0xce3: 0x2439,\n\t0xce4: 0x1089, 0xce5: 0x2451, 0xce6: 0x093d, 0xce7: 0x2469, 0xce8: 0x2491, 0xce9: 0x0369,\n\t0xcea: 0x24a9, 0xceb: 0x095d, 0xcec: 0x0359, 0xced: 0x1159, 0xcee: 0x0ef9, 0xcef: 0x0f61,\n\t0xcf0: 0x0f41, 0xcf1: 0x2421, 0xcf2: 0x097d, 0xcf3: 0x2439, 0xcf4: 0x1089, 0xcf5: 0x2451,\n\t0xcf6: 0x099d, 0xcf7: 0x2469, 0xcf8: 0x2491, 0xcf9: 0x0369, 0xcfa: 0x24a9, 0xcfb: 0x09bd,\n\t0xcfc: 0x0359, 0xcfd: 0x1159, 0xcfe: 0x0ef9, 0xcff: 0x0f61,\n\t// Block 0x34, offset 0xd00\n\t0xd00: 0x0018, 0xd01: 0x0018, 0xd02: 0x0018, 0xd03: 0x0018, 0xd04: 0x0018, 0xd05: 0x0018,\n\t0xd06: 0x0018, 0xd07: 0x0018, 0xd08: 0x0018, 0xd09: 0x0018, 0xd0a: 0x0018, 0xd0b: 0x0040,\n\t0xd0c: 0x0040, 0xd0d: 0x0040, 0xd0e: 0x0040, 0xd0f: 0x0040, 0xd10: 0x0040, 0xd11: 0x0040,\n\t0xd12: 0x0040, 0xd13: 0x0040, 0xd14: 0x0040, 0xd15: 0x0040, 0xd16: 0x0040, 0xd17: 0x0040,\n\t0xd18: 0x0040, 0xd19: 0x0040, 0xd1a: 0x0040, 0xd1b: 0x0040, 0xd1c: 0x0040, 0xd1d: 0x0040,\n\t0xd1e: 0x0040, 0xd1f: 0x0040, 0xd20: 0x00c9, 0xd21: 0x0069, 0xd22: 0x0079, 0xd23: 0x1f51,\n\t0xd24: 0x1f61, 0xd25: 0x1f71, 0xd26: 0x1f81, 0xd27: 0x1f91, 0xd28: 0x1fa1, 0xd29: 0x2601,\n\t0xd2a: 0x2619, 0xd2b: 0x2631, 0xd2c: 0x2649, 0xd2d: 0x2661, 0xd2e: 0x2679, 0xd2f: 0x2691,\n\t0xd30: 0x26a9, 0xd31: 0x26c1, 0xd32: 0x26d9, 0xd33: 0x26f1, 0xd34: 0x0a1e, 0xd35: 0x0a3e,\n\t0xd36: 0x0a5e, 0xd37: 0x0a7e, 0xd38: 0x0a9e, 0xd39: 0x0abe, 0xd3a: 0x0ade, 0xd3b: 0x0afe,\n\t0xd3c: 0x0b1e, 0xd3d: 0x270a, 0xd3e: 0x2732, 0xd3f: 0x275a,\n\t// Block 0x35, offset 0xd40\n\t0xd40: 0x2782, 0xd41: 0x27aa, 0xd42: 0x27d2, 0xd43: 0x27fa, 0xd44: 0x2822, 0xd45: 0x284a,\n\t0xd46: 0x2872, 0xd47: 0x289a, 0xd48: 0x0040, 0xd49: 0x0040, 0xd4a: 0x0040, 0xd4b: 0x0040,\n\t0xd4c: 0x0040, 0xd4d: 0x0040, 0xd4e: 0x0040, 0xd4f: 0x0040, 0xd50: 0x0040, 0xd51: 0x0040,\n\t0xd52: 0x0040, 0xd53: 0x0040, 0xd54: 0x0040, 0xd55: 0x0040, 0xd56: 0x0040, 0xd57: 0x0040,\n\t0xd58: 0x0040, 0xd59: 0x0040, 0xd5a: 0x0040, 0xd5b: 0x0040, 0xd5c: 0x0b3e, 0xd5d: 0x0b5e,\n\t0xd5e: 0x0b7e, 0xd5f: 0x0b9e, 0xd60: 0x0bbe, 0xd61: 0x0bde, 0xd62: 0x0bfe, 0xd63: 0x0c1e,\n\t0xd64: 0x0c3e, 0xd65: 0x0c5e, 0xd66: 0x0c7e, 0xd67: 0x0c9e, 0xd68: 0x0cbe, 0xd69: 0x0cde,\n\t0xd6a: 0x0cfe, 0xd6b: 0x0d1e, 0xd6c: 0x0d3e, 0xd6d: 0x0d5e, 0xd6e: 0x0d7e, 0xd6f: 0x0d9e,\n\t0xd70: 0x0dbe, 0xd71: 0x0dde, 0xd72: 0x0dfe, 0xd73: 0x0e1e, 0xd74: 0x0e3e, 0xd75: 0x0e5e,\n\t0xd76: 0x0039, 0xd77: 0x0ee9, 0xd78: 0x1159, 0xd79: 0x0ef9, 0xd7a: 0x0f09, 0xd7b: 0x1199,\n\t0xd7c: 0x0f31, 0xd7d: 0x0249, 0xd7e: 0x0f41, 0xd7f: 0x0259,\n\t// Block 0x36, offset 0xd80\n\t0xd80: 0x0f51, 0xd81: 0x0359, 0xd82: 0x0f61, 0xd83: 0x0f71, 0xd84: 0x00d9, 0xd85: 0x0f99,\n\t0xd86: 0x2039, 0xd87: 0x0269, 0xd88: 0x01d9, 0xd89: 0x0fa9, 0xd8a: 0x0fb9, 0xd8b: 0x1089,\n\t0xd8c: 0x0279, 0xd8d: 0x0369, 0xd8e: 0x0289, 0xd8f: 0x13d1, 0xd90: 0x0039, 0xd91: 0x0ee9,\n\t0xd92: 0x1159, 0xd93: 0x0ef9, 0xd94: 0x0f09, 0xd95: 0x1199, 0xd96: 0x0f31, 0xd97: 0x0249,\n\t0xd98: 0x0f41, 0xd99: 0x0259, 0xd9a: 0x0f51, 0xd9b: 0x0359, 0xd9c: 0x0f61, 0xd9d: 0x0f71,\n\t0xd9e: 0x00d9, 0xd9f: 0x0f99, 0xda0: 0x2039, 0xda1: 0x0269, 0xda2: 0x01d9, 0xda3: 0x0fa9,\n\t0xda4: 0x0fb9, 0xda5: 0x1089, 0xda6: 0x0279, 0xda7: 0x0369, 0xda8: 0x0289, 0xda9: 0x13d1,\n\t0xdaa: 0x1f41, 0xdab: 0x0018, 0xdac: 0x0018, 0xdad: 0x0018, 0xdae: 0x0018, 0xdaf: 0x0018,\n\t0xdb0: 0x0018, 0xdb1: 0x0018, 0xdb2: 0x0018, 0xdb3: 0x0018, 0xdb4: 0x0018, 0xdb5: 0x0018,\n\t0xdb6: 0x0018, 0xdb7: 0x0018, 0xdb8: 0x0018, 0xdb9: 0x0018, 0xdba: 0x0018, 0xdbb: 0x0018,\n\t0xdbc: 0x0018, 0xdbd: 0x0018, 0xdbe: 0x0018, 0xdbf: 0x0018,\n\t// Block 0x37, offset 0xdc0\n\t0xdc0: 0x0008, 0xdc1: 0x0008, 0xdc2: 0x0008, 0xdc3: 0x0008, 0xdc4: 0x0008, 0xdc5: 0x0008,\n\t0xdc6: 0x0008, 0xdc7: 0x0008, 0xdc8: 0x0008, 0xdc9: 0x0008, 0xdca: 0x0008, 0xdcb: 0x0008,\n\t0xdcc: 0x0008, 0xdcd: 0x0008, 0xdce: 0x0008, 0xdcf: 0x0008, 0xdd0: 0x0008, 0xdd1: 0x0008,\n\t0xdd2: 0x0008, 0xdd3: 0x0008, 0xdd4: 0x0008, 0xdd5: 0x0008, 0xdd6: 0x0008, 0xdd7: 0x0008,\n\t0xdd8: 0x0008, 0xdd9: 0x0008, 0xdda: 0x0008, 0xddb: 0x0008, 0xddc: 0x0008, 0xddd: 0x0008,\n\t0xdde: 0x0008, 0xddf: 0x0040, 0xde0: 0xe00d, 0xde1: 0x0008, 0xde2: 0x2971, 0xde3: 0x0ed5,\n\t0xde4: 0x2989, 0xde5: 0x0008, 0xde6: 0x0008, 0xde7: 0xe07d, 0xde8: 0x0008, 0xde9: 0xe01d,\n\t0xdea: 0x0008, 0xdeb: 0xe03d, 0xdec: 0x0008, 0xded: 0x0fe1, 0xdee: 0x1281, 0xdef: 0x0fc9,\n\t0xdf0: 0x1141, 0xdf1: 0x0008, 0xdf2: 0xe00d, 0xdf3: 0x0008, 0xdf4: 0x0008, 0xdf5: 0xe01d,\n\t0xdf6: 0x0008, 0xdf7: 0x0008, 0xdf8: 0x0008, 0xdf9: 0x0008, 0xdfa: 0x0008, 0xdfb: 0x0008,\n\t0xdfc: 0x0259, 0xdfd: 0x1089, 0xdfe: 0x29a1, 0xdff: 0x29b9,\n\t// Block 0x38, offset 0xe00\n\t0xe00: 0xe00d, 0xe01: 0x0008, 0xe02: 0xe00d, 0xe03: 0x0008, 0xe04: 0xe00d, 0xe05: 0x0008,\n\t0xe06: 0xe00d, 0xe07: 0x0008, 0xe08: 0xe00d, 0xe09: 0x0008, 0xe0a: 0xe00d, 0xe0b: 0x0008,\n\t0xe0c: 0xe00d, 0xe0d: 0x0008, 0xe0e: 0xe00d, 0xe0f: 0x0008, 0xe10: 0xe00d, 0xe11: 0x0008,\n\t0xe12: 0xe00d, 0xe13: 0x0008, 0xe14: 0xe00d, 0xe15: 0x0008, 0xe16: 0xe00d, 0xe17: 0x0008,\n\t0xe18: 0xe00d, 0xe19: 0x0008, 0xe1a: 0xe00d, 0xe1b: 0x0008, 0xe1c: 0xe00d, 0xe1d: 0x0008,\n\t0xe1e: 0xe00d, 0xe1f: 0x0008, 0xe20: 0xe00d, 0xe21: 0x0008, 0xe22: 0xe00d, 0xe23: 0x0008,\n\t0xe24: 0x0008, 0xe25: 0x0018, 0xe26: 0x0018, 0xe27: 0x0018, 0xe28: 0x0018, 0xe29: 0x0018,\n\t0xe2a: 0x0018, 0xe2b: 0xe03d, 0xe2c: 0x0008, 0xe2d: 0xe01d, 0xe2e: 0x0008, 0xe2f: 0x3308,\n\t0xe30: 0x3308, 0xe31: 0x3308, 0xe32: 0xe00d, 0xe33: 0x0008, 0xe34: 0x0040, 0xe35: 0x0040,\n\t0xe36: 0x0040, 0xe37: 0x0040, 0xe38: 0x0040, 0xe39: 0x0018, 0xe3a: 0x0018, 0xe3b: 0x0018,\n\t0xe3c: 0x0018, 0xe3d: 0x0018, 0xe3e: 0x0018, 0xe3f: 0x0018,\n\t// Block 0x39, offset 0xe40\n\t0xe40: 0x2715, 0xe41: 0x2735, 0xe42: 0x2755, 0xe43: 0x2775, 0xe44: 0x2795, 0xe45: 0x27b5,\n\t0xe46: 0x27d5, 0xe47: 0x27f5, 0xe48: 0x2815, 0xe49: 0x2835, 0xe4a: 0x2855, 0xe4b: 0x2875,\n\t0xe4c: 0x2895, 0xe4d: 0x28b5, 0xe4e: 0x28d5, 0xe4f: 0x28f5, 0xe50: 0x2915, 0xe51: 0x2935,\n\t0xe52: 0x2955, 0xe53: 0x2975, 0xe54: 0x2995, 0xe55: 0x29b5, 0xe56: 0x0040, 0xe57: 0x0040,\n\t0xe58: 0x0040, 0xe59: 0x0040, 0xe5a: 0x0040, 0xe5b: 0x0040, 0xe5c: 0x0040, 0xe5d: 0x0040,\n\t0xe5e: 0x0040, 0xe5f: 0x0040, 0xe60: 0x0040, 0xe61: 0x0040, 0xe62: 0x0040, 0xe63: 0x0040,\n\t0xe64: 0x0040, 0xe65: 0x0040, 0xe66: 0x0040, 0xe67: 0x0040, 0xe68: 0x0040, 0xe69: 0x0040,\n\t0xe6a: 0x0040, 0xe6b: 0x0040, 0xe6c: 0x0040, 0xe6d: 0x0040, 0xe6e: 0x0040, 0xe6f: 0x0040,\n\t0xe70: 0x0040, 0xe71: 0x0040, 0xe72: 0x0040, 0xe73: 0x0040, 0xe74: 0x0040, 0xe75: 0x0040,\n\t0xe76: 0x0040, 0xe77: 0x0040, 0xe78: 0x0040, 0xe79: 0x0040, 0xe7a: 0x0040, 0xe7b: 0x0040,\n\t0xe7c: 0x0040, 0xe7d: 0x0040, 0xe7e: 0x0040, 0xe7f: 0x0040,\n\t// Block 0x3a, offset 0xe80\n\t0xe80: 0x000a, 0xe81: 0x0018, 0xe82: 0x29d1, 0xe83: 0x0018, 0xe84: 0x0018, 0xe85: 0x0008,\n\t0xe86: 0x0008, 0xe87: 0x0008, 0xe88: 0x0018, 0xe89: 0x0018, 0xe8a: 0x0018, 0xe8b: 0x0018,\n\t0xe8c: 0x0018, 0xe8d: 0x0018, 0xe8e: 0x0018, 0xe8f: 0x0018, 0xe90: 0x0018, 0xe91: 0x0018,\n\t0xe92: 0x0018, 0xe93: 0x0018, 0xe94: 0x0018, 0xe95: 0x0018, 0xe96: 0x0018, 0xe97: 0x0018,\n\t0xe98: 0x0018, 0xe99: 0x0018, 0xe9a: 0x0018, 0xe9b: 0x0018, 0xe9c: 0x0018, 0xe9d: 0x0018,\n\t0xe9e: 0x0018, 0xe9f: 0x0018, 0xea0: 0x0018, 0xea1: 0x0018, 0xea2: 0x0018, 0xea3: 0x0018,\n\t0xea4: 0x0018, 0xea5: 0x0018, 0xea6: 0x0018, 0xea7: 0x0018, 0xea8: 0x0018, 0xea9: 0x0018,\n\t0xeaa: 0x3308, 0xeab: 0x3308, 0xeac: 0x3308, 0xead: 0x3308, 0xeae: 0x3018, 0xeaf: 0x3018,\n\t0xeb0: 0x0018, 0xeb1: 0x0018, 0xeb2: 0x0018, 0xeb3: 0x0018, 0xeb4: 0x0018, 0xeb5: 0x0018,\n\t0xeb6: 0xe125, 0xeb7: 0x0018, 0xeb8: 0x29d5, 0xeb9: 0x29f5, 0xeba: 0x2a15, 0xebb: 0x0018,\n\t0xebc: 0x0008, 0xebd: 0x0018, 0xebe: 0x0018, 0xebf: 0x0018,\n\t// Block 0x3b, offset 0xec0\n\t0xec0: 0x2b55, 0xec1: 0x2b75, 0xec2: 0x2b95, 0xec3: 0x2bb5, 0xec4: 0x2bd5, 0xec5: 0x2bf5,\n\t0xec6: 0x2bf5, 0xec7: 0x2bf5, 0xec8: 0x2c15, 0xec9: 0x2c15, 0xeca: 0x2c15, 0xecb: 0x2c15,\n\t0xecc: 0x2c35, 0xecd: 0x2c35, 0xece: 0x2c35, 0xecf: 0x2c55, 0xed0: 0x2c75, 0xed1: 0x2c75,\n\t0xed2: 0x2a95, 0xed3: 0x2a95, 0xed4: 0x2c75, 0xed5: 0x2c75, 0xed6: 0x2c95, 0xed7: 0x2c95,\n\t0xed8: 0x2c75, 0xed9: 0x2c75, 0xeda: 0x2a95, 0xedb: 0x2a95, 0xedc: 0x2c75, 0xedd: 0x2c75,\n\t0xede: 0x2c55, 0xedf: 0x2c55, 0xee0: 0x2cb5, 0xee1: 0x2cb5, 0xee2: 0x2cd5, 0xee3: 0x2cd5,\n\t0xee4: 0x0040, 0xee5: 0x2cf5, 0xee6: 0x2d15, 0xee7: 0x2d35, 0xee8: 0x2d35, 0xee9: 0x2d55,\n\t0xeea: 0x2d75, 0xeeb: 0x2d95, 0xeec: 0x2db5, 0xeed: 0x2dd5, 0xeee: 0x2df5, 0xeef: 0x2e15,\n\t0xef0: 0x2e35, 0xef1: 0x2e55, 0xef2: 0x2e55, 0xef3: 0x2e75, 0xef4: 0x2e95, 0xef5: 0x2e95,\n\t0xef6: 0x2eb5, 0xef7: 0x2ed5, 0xef8: 0x2e75, 0xef9: 0x2ef5, 0xefa: 0x2f15, 0xefb: 0x2ef5,\n\t0xefc: 0x2e75, 0xefd: 0x2f35, 0xefe: 0x2f55, 0xeff: 0x2f75,\n\t// Block 0x3c, offset 0xf00\n\t0xf00: 0x2f95, 0xf01: 0x2fb5, 0xf02: 0x2d15, 0xf03: 0x2cf5, 0xf04: 0x2fd5, 0xf05: 0x2ff5,\n\t0xf06: 0x3015, 0xf07: 0x3035, 0xf08: 0x3055, 0xf09: 0x3075, 0xf0a: 0x3095, 0xf0b: 0x30b5,\n\t0xf0c: 0x30d5, 0xf0d: 0x30f5, 0xf0e: 0x3115, 0xf0f: 0x0040, 0xf10: 0x0018, 0xf11: 0x0018,\n\t0xf12: 0x3135, 0xf13: 0x3155, 0xf14: 0x3175, 0xf15: 0x3195, 0xf16: 0x31b5, 0xf17: 0x31d5,\n\t0xf18: 0x31f5, 0xf19: 0x3215, 0xf1a: 0x3235, 0xf1b: 0x3255, 0xf1c: 0x3175, 0xf1d: 0x3275,\n\t0xf1e: 0x3295, 0xf1f: 0x32b5, 0xf20: 0x0008, 0xf21: 0x0008, 0xf22: 0x0008, 0xf23: 0x0008,\n\t0xf24: 0x0008, 0xf25: 0x0008, 0xf26: 0x0008, 0xf27: 0x0008, 0xf28: 0x0008, 0xf29: 0x0008,\n\t0xf2a: 0x0008, 0xf2b: 0x0008, 0xf2c: 0x0008, 0xf2d: 0x0008, 0xf2e: 0x0008, 0xf2f: 0x0008,\n\t0xf30: 0x0008, 0xf31: 0x0008, 0xf32: 0x0008, 0xf33: 0x0008, 0xf34: 0x0008, 0xf35: 0x0008,\n\t0xf36: 0x0008, 0xf37: 0x0008, 0xf38: 0x0008, 0xf39: 0x0008, 0xf3a: 0x0008, 0xf3b: 0x0040,\n\t0xf3c: 0x0040, 0xf3d: 0x0040, 0xf3e: 0x0040, 0xf3f: 0x0040,\n\t// Block 0x3d, offset 0xf40\n\t0xf40: 0x36a2, 0xf41: 0x36d2, 0xf42: 0x3702, 0xf43: 0x3732, 0xf44: 0x32d5, 0xf45: 0x32f5,\n\t0xf46: 0x3315, 0xf47: 0x3335, 0xf48: 0x0018, 0xf49: 0x0018, 0xf4a: 0x0018, 0xf4b: 0x0018,\n\t0xf4c: 0x0018, 0xf4d: 0x0018, 0xf4e: 0x0018, 0xf4f: 0x0018, 0xf50: 0x3355, 0xf51: 0x3761,\n\t0xf52: 0x3779, 0xf53: 0x3791, 0xf54: 0x37a9, 0xf55: 0x37c1, 0xf56: 0x37d9, 0xf57: 0x37f1,\n\t0xf58: 0x3809, 0xf59: 0x3821, 0xf5a: 0x3839, 0xf5b: 0x3851, 0xf5c: 0x3869, 0xf5d: 0x3881,\n\t0xf5e: 0x3899, 0xf5f: 0x38b1, 0xf60: 0x3375, 0xf61: 0x3395, 0xf62: 0x33b5, 0xf63: 0x33d5,\n\t0xf64: 0x33f5, 0xf65: 0x33f5, 0xf66: 0x3415, 0xf67: 0x3435, 0xf68: 0x3455, 0xf69: 0x3475,\n\t0xf6a: 0x3495, 0xf6b: 0x34b5, 0xf6c: 0x34d5, 0xf6d: 0x34f5, 0xf6e: 0x3515, 0xf6f: 0x3535,\n\t0xf70: 0x3555, 0xf71: 0x3575, 0xf72: 0x3595, 0xf73: 0x35b5, 0xf74: 0x35d5, 0xf75: 0x35f5,\n\t0xf76: 0x3615, 0xf77: 0x3635, 0xf78: 0x3655, 0xf79: 0x3675, 0xf7a: 0x3695, 0xf7b: 0x36b5,\n\t0xf7c: 0x38c9, 0xf7d: 0x3901, 0xf7e: 0x36d5, 0xf7f: 0x0018,\n\t// Block 0x3e, offset 0xf80\n\t0xf80: 0x36f5, 0xf81: 0x3715, 0xf82: 0x3735, 0xf83: 0x3755, 0xf84: 0x3775, 0xf85: 0x3795,\n\t0xf86: 0x37b5, 0xf87: 0x37d5, 0xf88: 0x37f5, 0xf89: 0x3815, 0xf8a: 0x3835, 0xf8b: 0x3855,\n\t0xf8c: 0x3875, 0xf8d: 0x3895, 0xf8e: 0x38b5, 0xf8f: 0x38d5, 0xf90: 0x38f5, 0xf91: 0x3915,\n\t0xf92: 0x3935, 0xf93: 0x3955, 0xf94: 0x3975, 0xf95: 0x3995, 0xf96: 0x39b5, 0xf97: 0x39d5,\n\t0xf98: 0x39f5, 0xf99: 0x3a15, 0xf9a: 0x3a35, 0xf9b: 0x3a55, 0xf9c: 0x3a75, 0xf9d: 0x3a95,\n\t0xf9e: 0x3ab5, 0xf9f: 0x3ad5, 0xfa0: 0x3af5, 0xfa1: 0x3b15, 0xfa2: 0x3b35, 0xfa3: 0x3b55,\n\t0xfa4: 0x3b75, 0xfa5: 0x3b95, 0xfa6: 0x1295, 0xfa7: 0x3bb5, 0xfa8: 0x3bd5, 0xfa9: 0x3bf5,\n\t0xfaa: 0x3c15, 0xfab: 0x3c35, 0xfac: 0x3c55, 0xfad: 0x3c75, 0xfae: 0x23b5, 0xfaf: 0x3c95,\n\t0xfb0: 0x3cb5, 0xfb1: 0x3939, 0xfb2: 0x3951, 0xfb3: 0x3969, 0xfb4: 0x3981, 0xfb5: 0x3999,\n\t0xfb6: 0x39b1, 0xfb7: 0x39c9, 0xfb8: 0x39e1, 0xfb9: 0x39f9, 0xfba: 0x3a11, 0xfbb: 0x3a29,\n\t0xfbc: 0x3a41, 0xfbd: 0x3a59, 0xfbe: 0x3a71, 0xfbf: 0x3a89,\n\t// Block 0x3f, offset 0xfc0\n\t0xfc0: 0x3aa1, 0xfc1: 0x3ac9, 0xfc2: 0x3af1, 0xfc3: 0x3b19, 0xfc4: 0x3b41, 0xfc5: 0x3b69,\n\t0xfc6: 0x3b91, 0xfc7: 0x3bb9, 0xfc8: 0x3be1, 0xfc9: 0x3c09, 0xfca: 0x3c39, 0xfcb: 0x3c69,\n\t0xfcc: 0x3c99, 0xfcd: 0x3cd5, 0xfce: 0x3cb1, 0xfcf: 0x3cf5, 0xfd0: 0x3d15, 0xfd1: 0x3d2d,\n\t0xfd2: 0x3d45, 0xfd3: 0x3d5d, 0xfd4: 0x3d75, 0xfd5: 0x3d75, 0xfd6: 0x3d5d, 0xfd7: 0x3d8d,\n\t0xfd8: 0x07d5, 0xfd9: 0x3da5, 0xfda: 0x3dbd, 0xfdb: 0x3dd5, 0xfdc: 0x3ded, 0xfdd: 0x3e05,\n\t0xfde: 0x3e1d, 0xfdf: 0x3e35, 0xfe0: 0x3e4d, 0xfe1: 0x3e65, 0xfe2: 0x3e7d, 0xfe3: 0x3e95,\n\t0xfe4: 0x3ead, 0xfe5: 0x3ead, 0xfe6: 0x3ec5, 0xfe7: 0x3ec5, 0xfe8: 0x3edd, 0xfe9: 0x3edd,\n\t0xfea: 0x3ef5, 0xfeb: 0x3f0d, 0xfec: 0x3f25, 0xfed: 0x3f3d, 0xfee: 0x3f55, 0xfef: 0x3f55,\n\t0xff0: 0x3f6d, 0xff1: 0x3f6d, 0xff2: 0x3f6d, 0xff3: 0x3f85, 0xff4: 0x3f9d, 0xff5: 0x3fb5,\n\t0xff6: 0x3fcd, 0xff7: 0x3fb5, 0xff8: 0x3fe5, 0xff9: 0x3ffd, 0xffa: 0x3f85, 0xffb: 0x4015,\n\t0xffc: 0x402d, 0xffd: 0x402d, 0xffe: 0x402d, 0xfff: 0x0040,\n\t// Block 0x40, offset 0x1000\n\t0x1000: 0x3cc9, 0x1001: 0x3d31, 0x1002: 0x3d99, 0x1003: 0x3e01, 0x1004: 0x3e51, 0x1005: 0x3eb9,\n\t0x1006: 0x3f09, 0x1007: 0x3f59, 0x1008: 0x3fd9, 0x1009: 0x4041, 0x100a: 0x4091, 0x100b: 0x40e1,\n\t0x100c: 0x4131, 0x100d: 0x4199, 0x100e: 0x4201, 0x100f: 0x4251, 0x1010: 0x42a1, 0x1011: 0x42d9,\n\t0x1012: 0x4329, 0x1013: 0x4391, 0x1014: 0x43f9, 0x1015: 0x4431, 0x1016: 0x44b1, 0x1017: 0x4549,\n\t0x1018: 0x45c9, 0x1019: 0x4619, 0x101a: 0x4699, 0x101b: 0x4719, 0x101c: 0x4781, 0x101d: 0x47d1,\n\t0x101e: 0x4821, 0x101f: 0x4871, 0x1020: 0x48d9, 0x1021: 0x4959, 0x1022: 0x49c1, 0x1023: 0x4a11,\n\t0x1024: 0x4a61, 0x1025: 0x4ab1, 0x1026: 0x4ae9, 0x1027: 0x4b21, 0x1028: 0x4b59, 0x1029: 0x4b91,\n\t0x102a: 0x4be1, 0x102b: 0x4c31, 0x102c: 0x4cb1, 0x102d: 0x4d01, 0x102e: 0x4d69, 0x102f: 0x4de9,\n\t0x1030: 0x4e39, 0x1031: 0x4e71, 0x1032: 0x4ea9, 0x1033: 0x4f29, 0x1034: 0x4f91, 0x1035: 0x5011,\n\t0x1036: 0x5061, 0x1037: 0x50e1, 0x1038: 0x5119, 0x1039: 0x5169, 0x103a: 0x51b9, 0x103b: 0x5209,\n\t0x103c: 0x5259, 0x103d: 0x52a9, 0x103e: 0x5311, 0x103f: 0x5361,\n\t// Block 0x41, offset 0x1040\n\t0x1040: 0x5399, 0x1041: 0x53e9, 0x1042: 0x5439, 0x1043: 0x5489, 0x1044: 0x54f1, 0x1045: 0x5541,\n\t0x1046: 0x5591, 0x1047: 0x55e1, 0x1048: 0x5661, 0x1049: 0x56c9, 0x104a: 0x5701, 0x104b: 0x5781,\n\t0x104c: 0x57b9, 0x104d: 0x5821, 0x104e: 0x5889, 0x104f: 0x58d9, 0x1050: 0x5929, 0x1051: 0x5979,\n\t0x1052: 0x59e1, 0x1053: 0x5a19, 0x1054: 0x5a69, 0x1055: 0x5ad1, 0x1056: 0x5b09, 0x1057: 0x5b89,\n\t0x1058: 0x5bd9, 0x1059: 0x5c01, 0x105a: 0x5c29, 0x105b: 0x5c51, 0x105c: 0x5c79, 0x105d: 0x5ca1,\n\t0x105e: 0x5cc9, 0x105f: 0x5cf1, 0x1060: 0x5d19, 0x1061: 0x5d41, 0x1062: 0x5d69, 0x1063: 0x5d99,\n\t0x1064: 0x5dc9, 0x1065: 0x5df9, 0x1066: 0x5e29, 0x1067: 0x5e59, 0x1068: 0x5e89, 0x1069: 0x5eb9,\n\t0x106a: 0x5ee9, 0x106b: 0x5f19, 0x106c: 0x5f49, 0x106d: 0x5f79, 0x106e: 0x5fa9, 0x106f: 0x5fd9,\n\t0x1070: 0x6009, 0x1071: 0x4045, 0x1072: 0x6039, 0x1073: 0x6051, 0x1074: 0x4065, 0x1075: 0x6069,\n\t0x1076: 0x6081, 0x1077: 0x6099, 0x1078: 0x4085, 0x1079: 0x4085, 0x107a: 0x60b1, 0x107b: 0x60c9,\n\t0x107c: 0x6101, 0x107d: 0x6139, 0x107e: 0x6171, 0x107f: 0x61a9,\n\t// Block 0x42, offset 0x1080\n\t0x1080: 0x6211, 0x1081: 0x6229, 0x1082: 0x40a5, 0x1083: 0x6241, 0x1084: 0x6259, 0x1085: 0x6271,\n\t0x1086: 0x6289, 0x1087: 0x62a1, 0x1088: 0x40c5, 0x1089: 0x62b9, 0x108a: 0x62e1, 0x108b: 0x62f9,\n\t0x108c: 0x40e5, 0x108d: 0x40e5, 0x108e: 0x6311, 0x108f: 0x6329, 0x1090: 0x6341, 0x1091: 0x4105,\n\t0x1092: 0x4125, 0x1093: 0x4145, 0x1094: 0x4165, 0x1095: 0x4185, 0x1096: 0x6359, 0x1097: 0x6371,\n\t0x1098: 0x6389, 0x1099: 0x63a1, 0x109a: 0x63b9, 0x109b: 0x41a5, 0x109c: 0x63d1, 0x109d: 0x63e9,\n\t0x109e: 0x6401, 0x109f: 0x41c5, 0x10a0: 0x41e5, 0x10a1: 0x6419, 0x10a2: 0x4205, 0x10a3: 0x4225,\n\t0x10a4: 0x4245, 0x10a5: 0x6431, 0x10a6: 0x4265, 0x10a7: 0x6449, 0x10a8: 0x6479, 0x10a9: 0x6211,\n\t0x10aa: 0x4285, 0x10ab: 0x42a5, 0x10ac: 0x42c5, 0x10ad: 0x42e5, 0x10ae: 0x64b1, 0x10af: 0x64f1,\n\t0x10b0: 0x6539, 0x10b1: 0x6551, 0x10b2: 0x4305, 0x10b3: 0x6569, 0x10b4: 0x6581, 0x10b5: 0x6599,\n\t0x10b6: 0x4325, 0x10b7: 0x65b1, 0x10b8: 0x65c9, 0x10b9: 0x65b1, 0x10ba: 0x65e1, 0x10bb: 0x65f9,\n\t0x10bc: 0x4345, 0x10bd: 0x6611, 0x10be: 0x6629, 0x10bf: 0x6611,\n\t// Block 0x43, offset 0x10c0\n\t0x10c0: 0x4365, 0x10c1: 0x4385, 0x10c2: 0x0040, 0x10c3: 0x6641, 0x10c4: 0x6659, 0x10c5: 0x6671,\n\t0x10c6: 0x6689, 0x10c7: 0x0040, 0x10c8: 0x66c1, 0x10c9: 0x66d9, 0x10ca: 0x66f1, 0x10cb: 0x6709,\n\t0x10cc: 0x6721, 0x10cd: 0x6739, 0x10ce: 0x6401, 0x10cf: 0x6751, 0x10d0: 0x6769, 0x10d1: 0x6781,\n\t0x10d2: 0x43a5, 0x10d3: 0x6799, 0x10d4: 0x6289, 0x10d5: 0x43c5, 0x10d6: 0x43e5, 0x10d7: 0x67b1,\n\t0x10d8: 0x0040, 0x10d9: 0x4405, 0x10da: 0x67c9, 0x10db: 0x67e1, 0x10dc: 0x67f9, 0x10dd: 0x6811,\n\t0x10de: 0x6829, 0x10df: 0x6859, 0x10e0: 0x6889, 0x10e1: 0x68b1, 0x10e2: 0x68d9, 0x10e3: 0x6901,\n\t0x10e4: 0x6929, 0x10e5: 0x6951, 0x10e6: 0x6979, 0x10e7: 0x69a1, 0x10e8: 0x69c9, 0x10e9: 0x69f1,\n\t0x10ea: 0x6a21, 0x10eb: 0x6a51, 0x10ec: 0x6a81, 0x10ed: 0x6ab1, 0x10ee: 0x6ae1, 0x10ef: 0x6b11,\n\t0x10f0: 0x6b41, 0x10f1: 0x6b71, 0x10f2: 0x6ba1, 0x10f3: 0x6bd1, 0x10f4: 0x6c01, 0x10f5: 0x6c31,\n\t0x10f6: 0x6c61, 0x10f7: 0x6c91, 0x10f8: 0x6cc1, 0x10f9: 0x6cf1, 0x10fa: 0x6d21, 0x10fb: 0x6d51,\n\t0x10fc: 0x6d81, 0x10fd: 0x6db1, 0x10fe: 0x6de1, 0x10ff: 0x4425,\n\t// Block 0x44, offset 0x1100\n\t0x1100: 0xe00d, 0x1101: 0x0008, 0x1102: 0xe00d, 0x1103: 0x0008, 0x1104: 0xe00d, 0x1105: 0x0008,\n\t0x1106: 0xe00d, 0x1107: 0x0008, 0x1108: 0xe00d, 0x1109: 0x0008, 0x110a: 0xe00d, 0x110b: 0x0008,\n\t0x110c: 0xe00d, 0x110d: 0x0008, 0x110e: 0xe00d, 0x110f: 0x0008, 0x1110: 0xe00d, 0x1111: 0x0008,\n\t0x1112: 0xe00d, 0x1113: 0x0008, 0x1114: 0xe00d, 0x1115: 0x0008, 0x1116: 0xe00d, 0x1117: 0x0008,\n\t0x1118: 0xe00d, 0x1119: 0x0008, 0x111a: 0xe00d, 0x111b: 0x0008, 0x111c: 0xe00d, 0x111d: 0x0008,\n\t0x111e: 0xe00d, 0x111f: 0x0008, 0x1120: 0xe00d, 0x1121: 0x0008, 0x1122: 0xe00d, 0x1123: 0x0008,\n\t0x1124: 0xe00d, 0x1125: 0x0008, 0x1126: 0xe00d, 0x1127: 0x0008, 0x1128: 0xe00d, 0x1129: 0x0008,\n\t0x112a: 0xe00d, 0x112b: 0x0008, 0x112c: 0xe00d, 0x112d: 0x0008, 0x112e: 0x0008, 0x112f: 0x3308,\n\t0x1130: 0x3318, 0x1131: 0x3318, 0x1132: 0x3318, 0x1133: 0x0018, 0x1134: 0x3308, 0x1135: 0x3308,\n\t0x1136: 0x3308, 0x1137: 0x3308, 0x1138: 0x3308, 0x1139: 0x3308, 0x113a: 0x3308, 0x113b: 0x3308,\n\t0x113c: 0x3308, 0x113d: 0x3308, 0x113e: 0x0018, 0x113f: 0x0008,\n\t// Block 0x45, offset 0x1140\n\t0x1140: 0xe00d, 0x1141: 0x0008, 0x1142: 0xe00d, 0x1143: 0x0008, 0x1144: 0xe00d, 0x1145: 0x0008,\n\t0x1146: 0xe00d, 0x1147: 0x0008, 0x1148: 0xe00d, 0x1149: 0x0008, 0x114a: 0xe00d, 0x114b: 0x0008,\n\t0x114c: 0xe00d, 0x114d: 0x0008, 0x114e: 0xe00d, 0x114f: 0x0008, 0x1150: 0xe00d, 0x1151: 0x0008,\n\t0x1152: 0xe00d, 0x1153: 0x0008, 0x1154: 0xe00d, 0x1155: 0x0008, 0x1156: 0xe00d, 0x1157: 0x0008,\n\t0x1158: 0xe00d, 0x1159: 0x0008, 0x115a: 0xe00d, 0x115b: 0x0008, 0x115c: 0x0ea1, 0x115d: 0x6e11,\n\t0x115e: 0x3308, 0x115f: 0x3308, 0x1160: 0x0008, 0x1161: 0x0008, 0x1162: 0x0008, 0x1163: 0x0008,\n\t0x1164: 0x0008, 0x1165: 0x0008, 0x1166: 0x0008, 0x1167: 0x0008, 0x1168: 0x0008, 0x1169: 0x0008,\n\t0x116a: 0x0008, 0x116b: 0x0008, 0x116c: 0x0008, 0x116d: 0x0008, 0x116e: 0x0008, 0x116f: 0x0008,\n\t0x1170: 0x0008, 0x1171: 0x0008, 0x1172: 0x0008, 0x1173: 0x0008, 0x1174: 0x0008, 0x1175: 0x0008,\n\t0x1176: 0x0008, 0x1177: 0x0008, 0x1178: 0x0008, 0x1179: 0x0008, 0x117a: 0x0008, 0x117b: 0x0008,\n\t0x117c: 0x0008, 0x117d: 0x0008, 0x117e: 0x0008, 0x117f: 0x0008,\n\t// Block 0x46, offset 0x1180\n\t0x1180: 0x0018, 0x1181: 0x0018, 0x1182: 0x0018, 0x1183: 0x0018, 0x1184: 0x0018, 0x1185: 0x0018,\n\t0x1186: 0x0018, 0x1187: 0x0018, 0x1188: 0x0018, 0x1189: 0x0018, 0x118a: 0x0018, 0x118b: 0x0018,\n\t0x118c: 0x0018, 0x118d: 0x0018, 0x118e: 0x0018, 0x118f: 0x0018, 0x1190: 0x0018, 0x1191: 0x0018,\n\t0x1192: 0x0018, 0x1193: 0x0018, 0x1194: 0x0018, 0x1195: 0x0018, 0x1196: 0x0018, 0x1197: 0x0008,\n\t0x1198: 0x0008, 0x1199: 0x0008, 0x119a: 0x0008, 0x119b: 0x0008, 0x119c: 0x0008, 0x119d: 0x0008,\n\t0x119e: 0x0008, 0x119f: 0x0008, 0x11a0: 0x0018, 0x11a1: 0x0018, 0x11a2: 0xe00d, 0x11a3: 0x0008,\n\t0x11a4: 0xe00d, 0x11a5: 0x0008, 0x11a6: 0xe00d, 0x11a7: 0x0008, 0x11a8: 0xe00d, 0x11a9: 0x0008,\n\t0x11aa: 0xe00d, 0x11ab: 0x0008, 0x11ac: 0xe00d, 0x11ad: 0x0008, 0x11ae: 0xe00d, 0x11af: 0x0008,\n\t0x11b0: 0x0008, 0x11b1: 0x0008, 0x11b2: 0xe00d, 0x11b3: 0x0008, 0x11b4: 0xe00d, 0x11b5: 0x0008,\n\t0x11b6: 0xe00d, 0x11b7: 0x0008, 0x11b8: 0xe00d, 0x11b9: 0x0008, 0x11ba: 0xe00d, 0x11bb: 0x0008,\n\t0x11bc: 0xe00d, 0x11bd: 0x0008, 0x11be: 0xe00d, 0x11bf: 0x0008,\n\t// Block 0x47, offset 0x11c0\n\t0x11c0: 0xe00d, 0x11c1: 0x0008, 0x11c2: 0xe00d, 0x11c3: 0x0008, 0x11c4: 0xe00d, 0x11c5: 0x0008,\n\t0x11c6: 0xe00d, 0x11c7: 0x0008, 0x11c8: 0xe00d, 0x11c9: 0x0008, 0x11ca: 0xe00d, 0x11cb: 0x0008,\n\t0x11cc: 0xe00d, 0x11cd: 0x0008, 0x11ce: 0xe00d, 0x11cf: 0x0008, 0x11d0: 0xe00d, 0x11d1: 0x0008,\n\t0x11d2: 0xe00d, 0x11d3: 0x0008, 0x11d4: 0xe00d, 0x11d5: 0x0008, 0x11d6: 0xe00d, 0x11d7: 0x0008,\n\t0x11d8: 0xe00d, 0x11d9: 0x0008, 0x11da: 0xe00d, 0x11db: 0x0008, 0x11dc: 0xe00d, 0x11dd: 0x0008,\n\t0x11de: 0xe00d, 0x11df: 0x0008, 0x11e0: 0xe00d, 0x11e1: 0x0008, 0x11e2: 0xe00d, 0x11e3: 0x0008,\n\t0x11e4: 0xe00d, 0x11e5: 0x0008, 0x11e6: 0xe00d, 0x11e7: 0x0008, 0x11e8: 0xe00d, 0x11e9: 0x0008,\n\t0x11ea: 0xe00d, 0x11eb: 0x0008, 0x11ec: 0xe00d, 0x11ed: 0x0008, 0x11ee: 0xe00d, 0x11ef: 0x0008,\n\t0x11f0: 0xe0fd, 0x11f1: 0x0008, 0x11f2: 0x0008, 0x11f3: 0x0008, 0x11f4: 0x0008, 0x11f5: 0x0008,\n\t0x11f6: 0x0008, 0x11f7: 0x0008, 0x11f8: 0x0008, 0x11f9: 0xe01d, 0x11fa: 0x0008, 0x11fb: 0xe03d,\n\t0x11fc: 0x0008, 0x11fd: 0x4445, 0x11fe: 0xe00d, 0x11ff: 0x0008,\n\t// Block 0x48, offset 0x1200\n\t0x1200: 0xe00d, 0x1201: 0x0008, 0x1202: 0xe00d, 0x1203: 0x0008, 0x1204: 0xe00d, 0x1205: 0x0008,\n\t0x1206: 0xe00d, 0x1207: 0x0008, 0x1208: 0x0008, 0x1209: 0x0018, 0x120a: 0x0018, 0x120b: 0xe03d,\n\t0x120c: 0x0008, 0x120d: 0x11d9, 0x120e: 0x0008, 0x120f: 0x0008, 0x1210: 0xe00d, 0x1211: 0x0008,\n\t0x1212: 0xe00d, 0x1213: 0x0008, 0x1214: 0x0008, 0x1215: 0x0008, 0x1216: 0xe00d, 0x1217: 0x0008,\n\t0x1218: 0xe00d, 0x1219: 0x0008, 0x121a: 0xe00d, 0x121b: 0x0008, 0x121c: 0xe00d, 0x121d: 0x0008,\n\t0x121e: 0xe00d, 0x121f: 0x0008, 0x1220: 0xe00d, 0x1221: 0x0008, 0x1222: 0xe00d, 0x1223: 0x0008,\n\t0x1224: 0xe00d, 0x1225: 0x0008, 0x1226: 0xe00d, 0x1227: 0x0008, 0x1228: 0xe00d, 0x1229: 0x0008,\n\t0x122a: 0x6e29, 0x122b: 0x1029, 0x122c: 0x11c1, 0x122d: 0x6e41, 0x122e: 0x1221, 0x122f: 0x0008,\n\t0x1230: 0x6e59, 0x1231: 0x6e71, 0x1232: 0x1239, 0x1233: 0x4465, 0x1234: 0xe00d, 0x1235: 0x0008,\n\t0x1236: 0xe00d, 0x1237: 0x0008, 0x1238: 0xe00d, 0x1239: 0x0008, 0x123a: 0xe00d, 0x123b: 0x0008,\n\t0x123c: 0xe00d, 0x123d: 0x0008, 0x123e: 0xe00d, 0x123f: 0x0008,\n\t// Block 0x49, offset 0x1240\n\t0x1240: 0x650d, 0x1241: 0x652d, 0x1242: 0x654d, 0x1243: 0x656d, 0x1244: 0x658d, 0x1245: 0x65ad,\n\t0x1246: 0x65cd, 0x1247: 0x65ed, 0x1248: 0x660d, 0x1249: 0x662d, 0x124a: 0x664d, 0x124b: 0x666d,\n\t0x124c: 0x668d, 0x124d: 0x66ad, 0x124e: 0x0008, 0x124f: 0x0008, 0x1250: 0x66cd, 0x1251: 0x0008,\n\t0x1252: 0x66ed, 0x1253: 0x0008, 0x1254: 0x0008, 0x1255: 0x670d, 0x1256: 0x672d, 0x1257: 0x674d,\n\t0x1258: 0x676d, 0x1259: 0x678d, 0x125a: 0x67ad, 0x125b: 0x67cd, 0x125c: 0x67ed, 0x125d: 0x680d,\n\t0x125e: 0x682d, 0x125f: 0x0008, 0x1260: 0x684d, 0x1261: 0x0008, 0x1262: 0x686d, 0x1263: 0x0008,\n\t0x1264: 0x0008, 0x1265: 0x688d, 0x1266: 0x68ad, 0x1267: 0x0008, 0x1268: 0x0008, 0x1269: 0x0008,\n\t0x126a: 0x68cd, 0x126b: 0x68ed, 0x126c: 0x690d, 0x126d: 0x692d, 0x126e: 0x694d, 0x126f: 0x696d,\n\t0x1270: 0x698d, 0x1271: 0x69ad, 0x1272: 0x69cd, 0x1273: 0x69ed, 0x1274: 0x6a0d, 0x1275: 0x6a2d,\n\t0x1276: 0x6a4d, 0x1277: 0x6a6d, 0x1278: 0x6a8d, 0x1279: 0x6aad, 0x127a: 0x6acd, 0x127b: 0x6aed,\n\t0x127c: 0x6b0d, 0x127d: 0x6b2d, 0x127e: 0x6b4d, 0x127f: 0x6b6d,\n\t// Block 0x4a, offset 0x1280\n\t0x1280: 0x7acd, 0x1281: 0x7aed, 0x1282: 0x7b0d, 0x1283: 0x7b2d, 0x1284: 0x7b4d, 0x1285: 0x7b6d,\n\t0x1286: 0x7b8d, 0x1287: 0x7bad, 0x1288: 0x7bcd, 0x1289: 0x7bed, 0x128a: 0x7c0d, 0x128b: 0x7c2d,\n\t0x128c: 0x7c4d, 0x128d: 0x7c6d, 0x128e: 0x7c8d, 0x128f: 0x6ec9, 0x1290: 0x6ef1, 0x1291: 0x6f19,\n\t0x1292: 0x7cad, 0x1293: 0x7ccd, 0x1294: 0x7ced, 0x1295: 0x6f41, 0x1296: 0x6f69, 0x1297: 0x6f91,\n\t0x1298: 0x7d0d, 0x1299: 0x7d2d, 0x129a: 0x0040, 0x129b: 0x0040, 0x129c: 0x0040, 0x129d: 0x0040,\n\t0x129e: 0x0040, 0x129f: 0x0040, 0x12a0: 0x0040, 0x12a1: 0x0040, 0x12a2: 0x0040, 0x12a3: 0x0040,\n\t0x12a4: 0x0040, 0x12a5: 0x0040, 0x12a6: 0x0040, 0x12a7: 0x0040, 0x12a8: 0x0040, 0x12a9: 0x0040,\n\t0x12aa: 0x0040, 0x12ab: 0x0040, 0x12ac: 0x0040, 0x12ad: 0x0040, 0x12ae: 0x0040, 0x12af: 0x0040,\n\t0x12b0: 0x0040, 0x12b1: 0x0040, 0x12b2: 0x0040, 0x12b3: 0x0040, 0x12b4: 0x0040, 0x12b5: 0x0040,\n\t0x12b6: 0x0040, 0x12b7: 0x0040, 0x12b8: 0x0040, 0x12b9: 0x0040, 0x12ba: 0x0040, 0x12bb: 0x0040,\n\t0x12bc: 0x0040, 0x12bd: 0x0040, 0x12be: 0x0040, 0x12bf: 0x0040,\n\t// Block 0x4b, offset 0x12c0\n\t0x12c0: 0x6fb9, 0x12c1: 0x6fd1, 0x12c2: 0x6fe9, 0x12c3: 0x7d4d, 0x12c4: 0x7d6d, 0x12c5: 0x7001,\n\t0x12c6: 0x7001, 0x12c7: 0x0040, 0x12c8: 0x0040, 0x12c9: 0x0040, 0x12ca: 0x0040, 0x12cb: 0x0040,\n\t0x12cc: 0x0040, 0x12cd: 0x0040, 0x12ce: 0x0040, 0x12cf: 0x0040, 0x12d0: 0x0040, 0x12d1: 0x0040,\n\t0x12d2: 0x0040, 0x12d3: 0x7019, 0x12d4: 0x7041, 0x12d5: 0x7069, 0x12d6: 0x7091, 0x12d7: 0x70b9,\n\t0x12d8: 0x0040, 0x12d9: 0x0040, 0x12da: 0x0040, 0x12db: 0x0040, 0x12dc: 0x0040, 0x12dd: 0x70e1,\n\t0x12de: 0x3308, 0x12df: 0x7109, 0x12e0: 0x7131, 0x12e1: 0x20a9, 0x12e2: 0x20f1, 0x12e3: 0x7149,\n\t0x12e4: 0x7161, 0x12e5: 0x7179, 0x12e6: 0x7191, 0x12e7: 0x71a9, 0x12e8: 0x71c1, 0x12e9: 0x1fb2,\n\t0x12ea: 0x71d9, 0x12eb: 0x7201, 0x12ec: 0x7229, 0x12ed: 0x7261, 0x12ee: 0x7299, 0x12ef: 0x72c1,\n\t0x12f0: 0x72e9, 0x12f1: 0x7311, 0x12f2: 0x7339, 0x12f3: 0x7361, 0x12f4: 0x7389, 0x12f5: 0x73b1,\n\t0x12f6: 0x73d9, 0x12f7: 0x0040, 0x12f8: 0x7401, 0x12f9: 0x7429, 0x12fa: 0x7451, 0x12fb: 0x7479,\n\t0x12fc: 0x74a1, 0x12fd: 0x0040, 0x12fe: 0x74c9, 0x12ff: 0x0040,\n\t// Block 0x4c, offset 0x1300\n\t0x1300: 0x74f1, 0x1301: 0x7519, 0x1302: 0x0040, 0x1303: 0x7541, 0x1304: 0x7569, 0x1305: 0x0040,\n\t0x1306: 0x7591, 0x1307: 0x75b9, 0x1308: 0x75e1, 0x1309: 0x7609, 0x130a: 0x7631, 0x130b: 0x7659,\n\t0x130c: 0x7681, 0x130d: 0x76a9, 0x130e: 0x76d1, 0x130f: 0x76f9, 0x1310: 0x7721, 0x1311: 0x7721,\n\t0x1312: 0x7739, 0x1313: 0x7739, 0x1314: 0x7739, 0x1315: 0x7739, 0x1316: 0x7751, 0x1317: 0x7751,\n\t0x1318: 0x7751, 0x1319: 0x7751, 0x131a: 0x7769, 0x131b: 0x7769, 0x131c: 0x7769, 0x131d: 0x7769,\n\t0x131e: 0x7781, 0x131f: 0x7781, 0x1320: 0x7781, 0x1321: 0x7781, 0x1322: 0x7799, 0x1323: 0x7799,\n\t0x1324: 0x7799, 0x1325: 0x7799, 0x1326: 0x77b1, 0x1327: 0x77b1, 0x1328: 0x77b1, 0x1329: 0x77b1,\n\t0x132a: 0x77c9, 0x132b: 0x77c9, 0x132c: 0x77c9, 0x132d: 0x77c9, 0x132e: 0x77e1, 0x132f: 0x77e1,\n\t0x1330: 0x77e1, 0x1331: 0x77e1, 0x1332: 0x77f9, 0x1333: 0x77f9, 0x1334: 0x77f9, 0x1335: 0x77f9,\n\t0x1336: 0x7811, 0x1337: 0x7811, 0x1338: 0x7811, 0x1339: 0x7811, 0x133a: 0x7829, 0x133b: 0x7829,\n\t0x133c: 0x7829, 0x133d: 0x7829, 0x133e: 0x7841, 0x133f: 0x7841,\n\t// Block 0x4d, offset 0x1340\n\t0x1340: 0x7841, 0x1341: 0x7841, 0x1342: 0x7859, 0x1343: 0x7859, 0x1344: 0x7871, 0x1345: 0x7871,\n\t0x1346: 0x7889, 0x1347: 0x7889, 0x1348: 0x78a1, 0x1349: 0x78a1, 0x134a: 0x78b9, 0x134b: 0x78b9,\n\t0x134c: 0x78d1, 0x134d: 0x78d1, 0x134e: 0x78e9, 0x134f: 0x78e9, 0x1350: 0x78e9, 0x1351: 0x78e9,\n\t0x1352: 0x7901, 0x1353: 0x7901, 0x1354: 0x7901, 0x1355: 0x7901, 0x1356: 0x7919, 0x1357: 0x7919,\n\t0x1358: 0x7919, 0x1359: 0x7919, 0x135a: 0x7931, 0x135b: 0x7931, 0x135c: 0x7931, 0x135d: 0x7931,\n\t0x135e: 0x7949, 0x135f: 0x7949, 0x1360: 0x7961, 0x1361: 0x7961, 0x1362: 0x7961, 0x1363: 0x7961,\n\t0x1364: 0x7979, 0x1365: 0x7979, 0x1366: 0x7991, 0x1367: 0x7991, 0x1368: 0x7991, 0x1369: 0x7991,\n\t0x136a: 0x79a9, 0x136b: 0x79a9, 0x136c: 0x79a9, 0x136d: 0x79a9, 0x136e: 0x79c1, 0x136f: 0x79c1,\n\t0x1370: 0x79d9, 0x1371: 0x79d9, 0x1372: 0x0818, 0x1373: 0x0818, 0x1374: 0x0818, 0x1375: 0x0818,\n\t0x1376: 0x0818, 0x1377: 0x0818, 0x1378: 0x0818, 0x1379: 0x0818, 0x137a: 0x0818, 0x137b: 0x0818,\n\t0x137c: 0x0818, 0x137d: 0x0818, 0x137e: 0x0818, 0x137f: 0x0818,\n\t// Block 0x4e, offset 0x1380\n\t0x1380: 0x0818, 0x1381: 0x0818, 0x1382: 0x0040, 0x1383: 0x0040, 0x1384: 0x0040, 0x1385: 0x0040,\n\t0x1386: 0x0040, 0x1387: 0x0040, 0x1388: 0x0040, 0x1389: 0x0040, 0x138a: 0x0040, 0x138b: 0x0040,\n\t0x138c: 0x0040, 0x138d: 0x0040, 0x138e: 0x0040, 0x138f: 0x0040, 0x1390: 0x0040, 0x1391: 0x0040,\n\t0x1392: 0x0040, 0x1393: 0x79f1, 0x1394: 0x79f1, 0x1395: 0x79f1, 0x1396: 0x79f1, 0x1397: 0x7a09,\n\t0x1398: 0x7a09, 0x1399: 0x7a21, 0x139a: 0x7a21, 0x139b: 0x7a39, 0x139c: 0x7a39, 0x139d: 0x0479,\n\t0x139e: 0x7a51, 0x139f: 0x7a51, 0x13a0: 0x7a69, 0x13a1: 0x7a69, 0x13a2: 0x7a81, 0x13a3: 0x7a81,\n\t0x13a4: 0x7a99, 0x13a5: 0x7a99, 0x13a6: 0x7a99, 0x13a7: 0x7a99, 0x13a8: 0x7ab1, 0x13a9: 0x7ab1,\n\t0x13aa: 0x7ac9, 0x13ab: 0x7ac9, 0x13ac: 0x7af1, 0x13ad: 0x7af1, 0x13ae: 0x7b19, 0x13af: 0x7b19,\n\t0x13b0: 0x7b41, 0x13b1: 0x7b41, 0x13b2: 0x7b69, 0x13b3: 0x7b69, 0x13b4: 0x7b91, 0x13b5: 0x7b91,\n\t0x13b6: 0x7bb9, 0x13b7: 0x7bb9, 0x13b8: 0x7bb9, 0x13b9: 0x7be1, 0x13ba: 0x7be1, 0x13bb: 0x7be1,\n\t0x13bc: 0x7c09, 0x13bd: 0x7c09, 0x13be: 0x7c09, 0x13bf: 0x7c09,\n\t// Block 0x4f, offset 0x13c0\n\t0x13c0: 0x85f9, 0x13c1: 0x8621, 0x13c2: 0x8649, 0x13c3: 0x8671, 0x13c4: 0x8699, 0x13c5: 0x86c1,\n\t0x13c6: 0x86e9, 0x13c7: 0x8711, 0x13c8: 0x8739, 0x13c9: 0x8761, 0x13ca: 0x8789, 0x13cb: 0x87b1,\n\t0x13cc: 0x87d9, 0x13cd: 0x8801, 0x13ce: 0x8829, 0x13cf: 0x8851, 0x13d0: 0x8879, 0x13d1: 0x88a1,\n\t0x13d2: 0x88c9, 0x13d3: 0x88f1, 0x13d4: 0x8919, 0x13d5: 0x8941, 0x13d6: 0x8969, 0x13d7: 0x8991,\n\t0x13d8: 0x89b9, 0x13d9: 0x89e1, 0x13da: 0x8a09, 0x13db: 0x8a31, 0x13dc: 0x8a59, 0x13dd: 0x8a81,\n\t0x13de: 0x8aaa, 0x13df: 0x8ada, 0x13e0: 0x8b0a, 0x13e1: 0x8b3a, 0x13e2: 0x8b6a, 0x13e3: 0x8b9a,\n\t0x13e4: 0x8bc9, 0x13e5: 0x8bf1, 0x13e6: 0x7c71, 0x13e7: 0x8c19, 0x13e8: 0x7be1, 0x13e9: 0x7c99,\n\t0x13ea: 0x8c41, 0x13eb: 0x8c69, 0x13ec: 0x7d39, 0x13ed: 0x8c91, 0x13ee: 0x7d61, 0x13ef: 0x7d89,\n\t0x13f0: 0x8cb9, 0x13f1: 0x8ce1, 0x13f2: 0x7e29, 0x13f3: 0x8d09, 0x13f4: 0x7e51, 0x13f5: 0x7e79,\n\t0x13f6: 0x8d31, 0x13f7: 0x8d59, 0x13f8: 0x7ec9, 0x13f9: 0x8d81, 0x13fa: 0x7ef1, 0x13fb: 0x7f19,\n\t0x13fc: 0x83a1, 0x13fd: 0x83c9, 0x13fe: 0x8441, 0x13ff: 0x8469,\n\t// Block 0x50, offset 0x1400\n\t0x1400: 0x8491, 0x1401: 0x8531, 0x1402: 0x8559, 0x1403: 0x8581, 0x1404: 0x85a9, 0x1405: 0x8649,\n\t0x1406: 0x8671, 0x1407: 0x8699, 0x1408: 0x8da9, 0x1409: 0x8739, 0x140a: 0x8dd1, 0x140b: 0x8df9,\n\t0x140c: 0x8829, 0x140d: 0x8e21, 0x140e: 0x8851, 0x140f: 0x8879, 0x1410: 0x8a81, 0x1411: 0x8e49,\n\t0x1412: 0x8e71, 0x1413: 0x89b9, 0x1414: 0x8e99, 0x1415: 0x89e1, 0x1416: 0x8a09, 0x1417: 0x7c21,\n\t0x1418: 0x7c49, 0x1419: 0x8ec1, 0x141a: 0x7c71, 0x141b: 0x8ee9, 0x141c: 0x7cc1, 0x141d: 0x7ce9,\n\t0x141e: 0x7d11, 0x141f: 0x7d39, 0x1420: 0x8f11, 0x1421: 0x7db1, 0x1422: 0x7dd9, 0x1423: 0x7e01,\n\t0x1424: 0x7e29, 0x1425: 0x8f39, 0x1426: 0x7ec9, 0x1427: 0x7f41, 0x1428: 0x7f69, 0x1429: 0x7f91,\n\t0x142a: 0x7fb9, 0x142b: 0x7fe1, 0x142c: 0x8031, 0x142d: 0x8059, 0x142e: 0x8081, 0x142f: 0x80a9,\n\t0x1430: 0x80d1, 0x1431: 0x80f9, 0x1432: 0x8f61, 0x1433: 0x8121, 0x1434: 0x8149, 0x1435: 0x8171,\n\t0x1436: 0x8199, 0x1437: 0x81c1, 0x1438: 0x81e9, 0x1439: 0x8239, 0x143a: 0x8261, 0x143b: 0x8289,\n\t0x143c: 0x82b1, 0x143d: 0x82d9, 0x143e: 0x8301, 0x143f: 0x8329,\n\t// Block 0x51, offset 0x1440\n\t0x1440: 0x8351, 0x1441: 0x8379, 0x1442: 0x83f1, 0x1443: 0x8419, 0x1444: 0x84b9, 0x1445: 0x84e1,\n\t0x1446: 0x8509, 0x1447: 0x8531, 0x1448: 0x8559, 0x1449: 0x85d1, 0x144a: 0x85f9, 0x144b: 0x8621,\n\t0x144c: 0x8649, 0x144d: 0x8f89, 0x144e: 0x86c1, 0x144f: 0x86e9, 0x1450: 0x8711, 0x1451: 0x8739,\n\t0x1452: 0x87b1, 0x1453: 0x87d9, 0x1454: 0x8801, 0x1455: 0x8829, 0x1456: 0x8fb1, 0x1457: 0x88a1,\n\t0x1458: 0x88c9, 0x1459: 0x8fd9, 0x145a: 0x8941, 0x145b: 0x8969, 0x145c: 0x8991, 0x145d: 0x89b9,\n\t0x145e: 0x9001, 0x145f: 0x7c71, 0x1460: 0x8ee9, 0x1461: 0x7d39, 0x1462: 0x8f11, 0x1463: 0x7e29,\n\t0x1464: 0x8f39, 0x1465: 0x7ec9, 0x1466: 0x9029, 0x1467: 0x80d1, 0x1468: 0x9051, 0x1469: 0x9079,\n\t0x146a: 0x90a1, 0x146b: 0x8531, 0x146c: 0x8559, 0x146d: 0x8649, 0x146e: 0x8829, 0x146f: 0x8fb1,\n\t0x1470: 0x89b9, 0x1471: 0x9001, 0x1472: 0x90c9, 0x1473: 0x9101, 0x1474: 0x9139, 0x1475: 0x9171,\n\t0x1476: 0x9199, 0x1477: 0x91c1, 0x1478: 0x91e9, 0x1479: 0x9211, 0x147a: 0x9239, 0x147b: 0x9261,\n\t0x147c: 0x9289, 0x147d: 0x92b1, 0x147e: 0x92d9, 0x147f: 0x9301,\n\t// Block 0x52, offset 0x1480\n\t0x1480: 0x9329, 0x1481: 0x9351, 0x1482: 0x9379, 0x1483: 0x93a1, 0x1484: 0x93c9, 0x1485: 0x93f1,\n\t0x1486: 0x9419, 0x1487: 0x9441, 0x1488: 0x9469, 0x1489: 0x9491, 0x148a: 0x94b9, 0x148b: 0x94e1,\n\t0x148c: 0x9079, 0x148d: 0x9509, 0x148e: 0x9531, 0x148f: 0x9559, 0x1490: 0x9581, 0x1491: 0x9171,\n\t0x1492: 0x9199, 0x1493: 0x91c1, 0x1494: 0x91e9, 0x1495: 0x9211, 0x1496: 0x9239, 0x1497: 0x9261,\n\t0x1498: 0x9289, 0x1499: 0x92b1, 0x149a: 0x92d9, 0x149b: 0x9301, 0x149c: 0x9329, 0x149d: 0x9351,\n\t0x149e: 0x9379, 0x149f: 0x93a1, 0x14a0: 0x93c9, 0x14a1: 0x93f1, 0x14a2: 0x9419, 0x14a3: 0x9441,\n\t0x14a4: 0x9469, 0x14a5: 0x9491, 0x14a6: 0x94b9, 0x14a7: 0x94e1, 0x14a8: 0x9079, 0x14a9: 0x9509,\n\t0x14aa: 0x9531, 0x14ab: 0x9559, 0x14ac: 0x9581, 0x14ad: 0x9491, 0x14ae: 0x94b9, 0x14af: 0x94e1,\n\t0x14b0: 0x9079, 0x14b1: 0x9051, 0x14b2: 0x90a1, 0x14b3: 0x8211, 0x14b4: 0x8059, 0x14b5: 0x8081,\n\t0x14b6: 0x80a9, 0x14b7: 0x9491, 0x14b8: 0x94b9, 0x14b9: 0x94e1, 0x14ba: 0x8211, 0x14bb: 0x8239,\n\t0x14bc: 0x95a9, 0x14bd: 0x95a9, 0x14be: 0x0018, 0x14bf: 0x0018,\n\t// Block 0x53, offset 0x14c0\n\t0x14c0: 0x0040, 0x14c1: 0x0040, 0x14c2: 0x0040, 0x14c3: 0x0040, 0x14c4: 0x0040, 0x14c5: 0x0040,\n\t0x14c6: 0x0040, 0x14c7: 0x0040, 0x14c8: 0x0040, 0x14c9: 0x0040, 0x14ca: 0x0040, 0x14cb: 0x0040,\n\t0x14cc: 0x0040, 0x14cd: 0x0040, 0x14ce: 0x0040, 0x14cf: 0x0040, 0x14d0: 0x95d1, 0x14d1: 0x9609,\n\t0x14d2: 0x9609, 0x14d3: 0x9641, 0x14d4: 0x9679, 0x14d5: 0x96b1, 0x14d6: 0x96e9, 0x14d7: 0x9721,\n\t0x14d8: 0x9759, 0x14d9: 0x9759, 0x14da: 0x9791, 0x14db: 0x97c9, 0x14dc: 0x9801, 0x14dd: 0x9839,\n\t0x14de: 0x9871, 0x14df: 0x98a9, 0x14e0: 0x98a9, 0x14e1: 0x98e1, 0x14e2: 0x9919, 0x14e3: 0x9919,\n\t0x14e4: 0x9951, 0x14e5: 0x9951, 0x14e6: 0x9989, 0x14e7: 0x99c1, 0x14e8: 0x99c1, 0x14e9: 0x99f9,\n\t0x14ea: 0x9a31, 0x14eb: 0x9a31, 0x14ec: 0x9a69, 0x14ed: 0x9a69, 0x14ee: 0x9aa1, 0x14ef: 0x9ad9,\n\t0x14f0: 0x9ad9, 0x14f1: 0x9b11, 0x14f2: 0x9b11, 0x14f3: 0x9b49, 0x14f4: 0x9b81, 0x14f5: 0x9bb9,\n\t0x14f6: 0x9bf1, 0x14f7: 0x9bf1, 0x14f8: 0x9c29, 0x14f9: 0x9c61, 0x14fa: 0x9c99, 0x14fb: 0x9cd1,\n\t0x14fc: 0x9d09, 0x14fd: 0x9d09, 0x14fe: 0x9d41, 0x14ff: 0x9d79,\n\t// Block 0x54, offset 0x1500\n\t0x1500: 0xa949, 0x1501: 0xa981, 0x1502: 0xa9b9, 0x1503: 0xa8a1, 0x1504: 0x9bb9, 0x1505: 0x9989,\n\t0x1506: 0xa9f1, 0x1507: 0xaa29, 0x1508: 0x0040, 0x1509: 0x0040, 0x150a: 0x0040, 0x150b: 0x0040,\n\t0x150c: 0x0040, 0x150d: 0x0040, 0x150e: 0x0040, 0x150f: 0x0040, 0x1510: 0x0040, 0x1511: 0x0040,\n\t0x1512: 0x0040, 0x1513: 0x0040, 0x1514: 0x0040, 0x1515: 0x0040, 0x1516: 0x0040, 0x1517: 0x0040,\n\t0x1518: 0x0040, 0x1519: 0x0040, 0x151a: 0x0040, 0x151b: 0x0040, 0x151c: 0x0040, 0x151d: 0x0040,\n\t0x151e: 0x0040, 0x151f: 0x0040, 0x1520: 0x0040, 0x1521: 0x0040, 0x1522: 0x0040, 0x1523: 0x0040,\n\t0x1524: 0x0040, 0x1525: 0x0040, 0x1526: 0x0040, 0x1527: 0x0040, 0x1528: 0x0040, 0x1529: 0x0040,\n\t0x152a: 0x0040, 0x152b: 0x0040, 0x152c: 0x0040, 0x152d: 0x0040, 0x152e: 0x0040, 0x152f: 0x0040,\n\t0x1530: 0xaa61, 0x1531: 0xaa99, 0x1532: 0xaad1, 0x1533: 0xab19, 0x1534: 0xab61, 0x1535: 0xaba9,\n\t0x1536: 0xabf1, 0x1537: 0xac39, 0x1538: 0xac81, 0x1539: 0xacc9, 0x153a: 0xad02, 0x153b: 0xae12,\n\t0x153c: 0xae91, 0x153d: 0x0018, 0x153e: 0x0040, 0x153f: 0x0040,\n\t// Block 0x55, offset 0x1540\n\t0x1540: 0x33c0, 0x1541: 0x33c0, 0x1542: 0x33c0, 0x1543: 0x33c0, 0x1544: 0x33c0, 0x1545: 0x33c0,\n\t0x1546: 0x33c0, 0x1547: 0x33c0, 0x1548: 0x33c0, 0x1549: 0x33c0, 0x154a: 0x33c0, 0x154b: 0x33c0,\n\t0x154c: 0x33c0, 0x154d: 0x33c0, 0x154e: 0x33c0, 0x154f: 0x33c0, 0x1550: 0xaeda, 0x1551: 0x7d8d,\n\t0x1552: 0x0040, 0x1553: 0xaeea, 0x1554: 0x03c2, 0x1555: 0xaefa, 0x1556: 0xaf0a, 0x1557: 0x7dad,\n\t0x1558: 0x7dcd, 0x1559: 0x0040, 0x155a: 0x0040, 0x155b: 0x0040, 0x155c: 0x0040, 0x155d: 0x0040,\n\t0x155e: 0x0040, 0x155f: 0x0040, 0x1560: 0x3308, 0x1561: 0x3308, 0x1562: 0x3308, 0x1563: 0x3308,\n\t0x1564: 0x3308, 0x1565: 0x3308, 0x1566: 0x3308, 0x1567: 0x3308, 0x1568: 0x3308, 0x1569: 0x3308,\n\t0x156a: 0x3308, 0x156b: 0x3308, 0x156c: 0x3308, 0x156d: 0x3308, 0x156e: 0x3308, 0x156f: 0x3308,\n\t0x1570: 0x0040, 0x1571: 0x7ded, 0x1572: 0x7e0d, 0x1573: 0xaf1a, 0x1574: 0xaf1a, 0x1575: 0x1fd2,\n\t0x1576: 0x1fe2, 0x1577: 0xaf2a, 0x1578: 0xaf3a, 0x1579: 0x7e2d, 0x157a: 0x7e4d, 0x157b: 0x7e6d,\n\t0x157c: 0x7e2d, 0x157d: 0x7e8d, 0x157e: 0x7ead, 0x157f: 0x7e8d,\n\t// Block 0x56, offset 0x1580\n\t0x1580: 0x7ecd, 0x1581: 0x7eed, 0x1582: 0x7f0d, 0x1583: 0x7eed, 0x1584: 0x7f2d, 0x1585: 0x0018,\n\t0x1586: 0x0018, 0x1587: 0xaf4a, 0x1588: 0xaf5a, 0x1589: 0x7f4e, 0x158a: 0x7f6e, 0x158b: 0x7f8e,\n\t0x158c: 0x7fae, 0x158d: 0xaf1a, 0x158e: 0xaf1a, 0x158f: 0xaf1a, 0x1590: 0xaeda, 0x1591: 0x7fcd,\n\t0x1592: 0x0040, 0x1593: 0x0040, 0x1594: 0x03c2, 0x1595: 0xaeea, 0x1596: 0xaf0a, 0x1597: 0xaefa,\n\t0x1598: 0x7fed, 0x1599: 0x1fd2, 0x159a: 0x1fe2, 0x159b: 0xaf2a, 0x159c: 0xaf3a, 0x159d: 0x7ecd,\n\t0x159e: 0x7f2d, 0x159f: 0xaf6a, 0x15a0: 0xaf7a, 0x15a1: 0xaf8a, 0x15a2: 0x1fb2, 0x15a3: 0xaf99,\n\t0x15a4: 0xafaa, 0x15a5: 0xafba, 0x15a6: 0x1fc2, 0x15a7: 0x0040, 0x15a8: 0xafca, 0x15a9: 0xafda,\n\t0x15aa: 0xafea, 0x15ab: 0xaffa, 0x15ac: 0x0040, 0x15ad: 0x0040, 0x15ae: 0x0040, 0x15af: 0x0040,\n\t0x15b0: 0x800e, 0x15b1: 0xb009, 0x15b2: 0x802e, 0x15b3: 0x0808, 0x15b4: 0x804e, 0x15b5: 0x0040,\n\t0x15b6: 0x806e, 0x15b7: 0xb031, 0x15b8: 0x808e, 0x15b9: 0xb059, 0x15ba: 0x80ae, 0x15bb: 0xb081,\n\t0x15bc: 0x80ce, 0x15bd: 0xb0a9, 0x15be: 0x80ee, 0x15bf: 0xb0d1,\n\t// Block 0x57, offset 0x15c0\n\t0x15c0: 0xb0f9, 0x15c1: 0xb111, 0x15c2: 0xb111, 0x15c3: 0xb129, 0x15c4: 0xb129, 0x15c5: 0xb141,\n\t0x15c6: 0xb141, 0x15c7: 0xb159, 0x15c8: 0xb159, 0x15c9: 0xb171, 0x15ca: 0xb171, 0x15cb: 0xb171,\n\t0x15cc: 0xb171, 0x15cd: 0xb189, 0x15ce: 0xb189, 0x15cf: 0xb1a1, 0x15d0: 0xb1a1, 0x15d1: 0xb1a1,\n\t0x15d2: 0xb1a1, 0x15d3: 0xb1b9, 0x15d4: 0xb1b9, 0x15d5: 0xb1d1, 0x15d6: 0xb1d1, 0x15d7: 0xb1d1,\n\t0x15d8: 0xb1d1, 0x15d9: 0xb1e9, 0x15da: 0xb1e9, 0x15db: 0xb1e9, 0x15dc: 0xb1e9, 0x15dd: 0xb201,\n\t0x15de: 0xb201, 0x15df: 0xb201, 0x15e0: 0xb201, 0x15e1: 0xb219, 0x15e2: 0xb219, 0x15e3: 0xb219,\n\t0x15e4: 0xb219, 0x15e5: 0xb231, 0x15e6: 0xb231, 0x15e7: 0xb231, 0x15e8: 0xb231, 0x15e9: 0xb249,\n\t0x15ea: 0xb249, 0x15eb: 0xb261, 0x15ec: 0xb261, 0x15ed: 0xb279, 0x15ee: 0xb279, 0x15ef: 0xb291,\n\t0x15f0: 0xb291, 0x15f1: 0xb2a9, 0x15f2: 0xb2a9, 0x15f3: 0xb2a9, 0x15f4: 0xb2a9, 0x15f5: 0xb2c1,\n\t0x15f6: 0xb2c1, 0x15f7: 0xb2c1, 0x15f8: 0xb2c1, 0x15f9: 0xb2d9, 0x15fa: 0xb2d9, 0x15fb: 0xb2d9,\n\t0x15fc: 0xb2d9, 0x15fd: 0xb2f1, 0x15fe: 0xb2f1, 0x15ff: 0xb2f1,\n\t// Block 0x58, offset 0x1600\n\t0x1600: 0xb2f1, 0x1601: 0xb309, 0x1602: 0xb309, 0x1603: 0xb309, 0x1604: 0xb309, 0x1605: 0xb321,\n\t0x1606: 0xb321, 0x1607: 0xb321, 0x1608: 0xb321, 0x1609: 0xb339, 0x160a: 0xb339, 0x160b: 0xb339,\n\t0x160c: 0xb339, 0x160d: 0xb351, 0x160e: 0xb351, 0x160f: 0xb351, 0x1610: 0xb351, 0x1611: 0xb369,\n\t0x1612: 0xb369, 0x1613: 0xb369, 0x1614: 0xb369, 0x1615: 0xb381, 0x1616: 0xb381, 0x1617: 0xb381,\n\t0x1618: 0xb381, 0x1619: 0xb399, 0x161a: 0xb399, 0x161b: 0xb399, 0x161c: 0xb399, 0x161d: 0xb3b1,\n\t0x161e: 0xb3b1, 0x161f: 0xb3b1, 0x1620: 0xb3b1, 0x1621: 0xb3c9, 0x1622: 0xb3c9, 0x1623: 0xb3c9,\n\t0x1624: 0xb3c9, 0x1625: 0xb3e1, 0x1626: 0xb3e1, 0x1627: 0xb3e1, 0x1628: 0xb3e1, 0x1629: 0xb3f9,\n\t0x162a: 0xb3f9, 0x162b: 0xb3f9, 0x162c: 0xb3f9, 0x162d: 0xb411, 0x162e: 0xb411, 0x162f: 0x7ab1,\n\t0x1630: 0x7ab1, 0x1631: 0xb429, 0x1632: 0xb429, 0x1633: 0xb429, 0x1634: 0xb429, 0x1635: 0xb441,\n\t0x1636: 0xb441, 0x1637: 0xb469, 0x1638: 0xb469, 0x1639: 0xb491, 0x163a: 0xb491, 0x163b: 0xb4b9,\n\t0x163c: 0xb4b9, 0x163d: 0x0040, 0x163e: 0x0040, 0x163f: 0x03c0,\n\t// Block 0x59, offset 0x1640\n\t0x1640: 0x0040, 0x1641: 0xaefa, 0x1642: 0xb4e2, 0x1643: 0xaf6a, 0x1644: 0xafda, 0x1645: 0xafea,\n\t0x1646: 0xaf7a, 0x1647: 0xb4f2, 0x1648: 0x1fd2, 0x1649: 0x1fe2, 0x164a: 0xaf8a, 0x164b: 0x1fb2,\n\t0x164c: 0xaeda, 0x164d: 0xaf99, 0x164e: 0x29d1, 0x164f: 0xb502, 0x1650: 0x1f41, 0x1651: 0x00c9,\n\t0x1652: 0x0069, 0x1653: 0x0079, 0x1654: 0x1f51, 0x1655: 0x1f61, 0x1656: 0x1f71, 0x1657: 0x1f81,\n\t0x1658: 0x1f91, 0x1659: 0x1fa1, 0x165a: 0xaeea, 0x165b: 0x03c2, 0x165c: 0xafaa, 0x165d: 0x1fc2,\n\t0x165e: 0xafba, 0x165f: 0xaf0a, 0x1660: 0xaffa, 0x1661: 0x0039, 0x1662: 0x0ee9, 0x1663: 0x1159,\n\t0x1664: 0x0ef9, 0x1665: 0x0f09, 0x1666: 0x1199, 0x1667: 0x0f31, 0x1668: 0x0249, 0x1669: 0x0f41,\n\t0x166a: 0x0259, 0x166b: 0x0f51, 0x166c: 0x0359, 0x166d: 0x0f61, 0x166e: 0x0f71, 0x166f: 0x00d9,\n\t0x1670: 0x0f99, 0x1671: 0x2039, 0x1672: 0x0269, 0x1673: 0x01d9, 0x1674: 0x0fa9, 0x1675: 0x0fb9,\n\t0x1676: 0x1089, 0x1677: 0x0279, 0x1678: 0x0369, 0x1679: 0x0289, 0x167a: 0x13d1, 0x167b: 0xaf4a,\n\t0x167c: 0xafca, 0x167d: 0xaf5a, 0x167e: 0xb512, 0x167f: 0xaf1a,\n\t// Block 0x5a, offset 0x1680\n\t0x1680: 0x1caa, 0x1681: 0x0039, 0x1682: 0x0ee9, 0x1683: 0x1159, 0x1684: 0x0ef9, 0x1685: 0x0f09,\n\t0x1686: 0x1199, 0x1687: 0x0f31, 0x1688: 0x0249, 0x1689: 0x0f41, 0x168a: 0x0259, 0x168b: 0x0f51,\n\t0x168c: 0x0359, 0x168d: 0x0f61, 0x168e: 0x0f71, 0x168f: 0x00d9, 0x1690: 0x0f99, 0x1691: 0x2039,\n\t0x1692: 0x0269, 0x1693: 0x01d9, 0x1694: 0x0fa9, 0x1695: 0x0fb9, 0x1696: 0x1089, 0x1697: 0x0279,\n\t0x1698: 0x0369, 0x1699: 0x0289, 0x169a: 0x13d1, 0x169b: 0xaf2a, 0x169c: 0xb522, 0x169d: 0xaf3a,\n\t0x169e: 0xb532, 0x169f: 0x810d, 0x16a0: 0x812d, 0x16a1: 0x29d1, 0x16a2: 0x814d, 0x16a3: 0x814d,\n\t0x16a4: 0x816d, 0x16a5: 0x818d, 0x16a6: 0x81ad, 0x16a7: 0x81cd, 0x16a8: 0x81ed, 0x16a9: 0x820d,\n\t0x16aa: 0x822d, 0x16ab: 0x824d, 0x16ac: 0x826d, 0x16ad: 0x828d, 0x16ae: 0x82ad, 0x16af: 0x82cd,\n\t0x16b0: 0x82ed, 0x16b1: 0x830d, 0x16b2: 0x832d, 0x16b3: 0x834d, 0x16b4: 0x836d, 0x16b5: 0x838d,\n\t0x16b6: 0x83ad, 0x16b7: 0x83cd, 0x16b8: 0x83ed, 0x16b9: 0x840d, 0x16ba: 0x842d, 0x16bb: 0x844d,\n\t0x16bc: 0x81ed, 0x16bd: 0x846d, 0x16be: 0x848d, 0x16bf: 0x824d,\n\t// Block 0x5b, offset 0x16c0\n\t0x16c0: 0x84ad, 0x16c1: 0x84cd, 0x16c2: 0x84ed, 0x16c3: 0x850d, 0x16c4: 0x852d, 0x16c5: 0x854d,\n\t0x16c6: 0x856d, 0x16c7: 0x858d, 0x16c8: 0x850d, 0x16c9: 0x85ad, 0x16ca: 0x850d, 0x16cb: 0x85cd,\n\t0x16cc: 0x85cd, 0x16cd: 0x85ed, 0x16ce: 0x85ed, 0x16cf: 0x860d, 0x16d0: 0x854d, 0x16d1: 0x862d,\n\t0x16d2: 0x864d, 0x16d3: 0x862d, 0x16d4: 0x866d, 0x16d5: 0x864d, 0x16d6: 0x868d, 0x16d7: 0x868d,\n\t0x16d8: 0x86ad, 0x16d9: 0x86ad, 0x16da: 0x86cd, 0x16db: 0x86cd, 0x16dc: 0x864d, 0x16dd: 0x814d,\n\t0x16de: 0x86ed, 0x16df: 0x870d, 0x16e0: 0x0040, 0x16e1: 0x872d, 0x16e2: 0x874d, 0x16e3: 0x876d,\n\t0x16e4: 0x878d, 0x16e5: 0x876d, 0x16e6: 0x87ad, 0x16e7: 0x87cd, 0x16e8: 0x87ed, 0x16e9: 0x87ed,\n\t0x16ea: 0x880d, 0x16eb: 0x880d, 0x16ec: 0x882d, 0x16ed: 0x882d, 0x16ee: 0x880d, 0x16ef: 0x880d,\n\t0x16f0: 0x884d, 0x16f1: 0x886d, 0x16f2: 0x888d, 0x16f3: 0x88ad, 0x16f4: 0x88cd, 0x16f5: 0x88ed,\n\t0x16f6: 0x88ed, 0x16f7: 0x88ed, 0x16f8: 0x890d, 0x16f9: 0x890d, 0x16fa: 0x890d, 0x16fb: 0x890d,\n\t0x16fc: 0x87ed, 0x16fd: 0x87ed, 0x16fe: 0x87ed, 0x16ff: 0x0040,\n\t// Block 0x5c, offset 0x1700\n\t0x1700: 0x0040, 0x1701: 0x0040, 0x1702: 0x874d, 0x1703: 0x872d, 0x1704: 0x892d, 0x1705: 0x872d,\n\t0x1706: 0x874d, 0x1707: 0x872d, 0x1708: 0x0040, 0x1709: 0x0040, 0x170a: 0x894d, 0x170b: 0x874d,\n\t0x170c: 0x896d, 0x170d: 0x892d, 0x170e: 0x896d, 0x170f: 0x874d, 0x1710: 0x0040, 0x1711: 0x0040,\n\t0x1712: 0x898d, 0x1713: 0x89ad, 0x1714: 0x88ad, 0x1715: 0x896d, 0x1716: 0x892d, 0x1717: 0x896d,\n\t0x1718: 0x0040, 0x1719: 0x0040, 0x171a: 0x89cd, 0x171b: 0x89ed, 0x171c: 0x89cd, 0x171d: 0x0040,\n\t0x171e: 0x0040, 0x171f: 0x0040, 0x1720: 0xb541, 0x1721: 0xb559, 0x1722: 0xb571, 0x1723: 0x8a0e,\n\t0x1724: 0xb589, 0x1725: 0xb5a1, 0x1726: 0x8a2d, 0x1727: 0x0040, 0x1728: 0x8a4d, 0x1729: 0x8a6d,\n\t0x172a: 0x8a8d, 0x172b: 0x8a6d, 0x172c: 0x8aad, 0x172d: 0x8acd, 0x172e: 0x8aed, 0x172f: 0x0040,\n\t0x1730: 0x0040, 0x1731: 0x0040, 0x1732: 0x0040, 0x1733: 0x0040, 0x1734: 0x0040, 0x1735: 0x0040,\n\t0x1736: 0x0040, 0x1737: 0x0040, 0x1738: 0x0040, 0x1739: 0x0340, 0x173a: 0x0340, 0x173b: 0x0340,\n\t0x173c: 0x0040, 0x173d: 0x0040, 0x173e: 0x0040, 0x173f: 0x0040,\n\t// Block 0x5d, offset 0x1740\n\t0x1740: 0x0a08, 0x1741: 0x0a08, 0x1742: 0x0a08, 0x1743: 0x0a08, 0x1744: 0x0a08, 0x1745: 0x0c08,\n\t0x1746: 0x0808, 0x1747: 0x0c08, 0x1748: 0x0818, 0x1749: 0x0c08, 0x174a: 0x0c08, 0x174b: 0x0808,\n\t0x174c: 0x0808, 0x174d: 0x0908, 0x174e: 0x0c08, 0x174f: 0x0c08, 0x1750: 0x0c08, 0x1751: 0x0c08,\n\t0x1752: 0x0c08, 0x1753: 0x0a08, 0x1754: 0x0a08, 0x1755: 0x0a08, 0x1756: 0x0a08, 0x1757: 0x0908,\n\t0x1758: 0x0a08, 0x1759: 0x0a08, 0x175a: 0x0a08, 0x175b: 0x0a08, 0x175c: 0x0a08, 0x175d: 0x0c08,\n\t0x175e: 0x0a08, 0x175f: 0x0a08, 0x1760: 0x0a08, 0x1761: 0x0c08, 0x1762: 0x0808, 0x1763: 0x0808,\n\t0x1764: 0x0c08, 0x1765: 0x3308, 0x1766: 0x3308, 0x1767: 0x0040, 0x1768: 0x0040, 0x1769: 0x0040,\n\t0x176a: 0x0040, 0x176b: 0x0a18, 0x176c: 0x0a18, 0x176d: 0x0a18, 0x176e: 0x0a18, 0x176f: 0x0c18,\n\t0x1770: 0x0818, 0x1771: 0x0818, 0x1772: 0x0818, 0x1773: 0x0818, 0x1774: 0x0818, 0x1775: 0x0818,\n\t0x1776: 0x0818, 0x1777: 0x0040, 0x1778: 0x0040, 0x1779: 0x0040, 0x177a: 0x0040, 0x177b: 0x0040,\n\t0x177c: 0x0040, 0x177d: 0x0040, 0x177e: 0x0040, 0x177f: 0x0040,\n\t// Block 0x5e, offset 0x1780\n\t0x1780: 0x0a08, 0x1781: 0x0c08, 0x1782: 0x0a08, 0x1783: 0x0c08, 0x1784: 0x0c08, 0x1785: 0x0c08,\n\t0x1786: 0x0a08, 0x1787: 0x0a08, 0x1788: 0x0a08, 0x1789: 0x0c08, 0x178a: 0x0a08, 0x178b: 0x0a08,\n\t0x178c: 0x0c08, 0x178d: 0x0a08, 0x178e: 0x0c08, 0x178f: 0x0c08, 0x1790: 0x0a08, 0x1791: 0x0c08,\n\t0x1792: 0x0040, 0x1793: 0x0040, 0x1794: 0x0040, 0x1795: 0x0040, 0x1796: 0x0040, 0x1797: 0x0040,\n\t0x1798: 0x0040, 0x1799: 0x0818, 0x179a: 0x0818, 0x179b: 0x0818, 0x179c: 0x0818, 0x179d: 0x0040,\n\t0x179e: 0x0040, 0x179f: 0x0040, 0x17a0: 0x0040, 0x17a1: 0x0040, 0x17a2: 0x0040, 0x17a3: 0x0040,\n\t0x17a4: 0x0040, 0x17a5: 0x0040, 0x17a6: 0x0040, 0x17a7: 0x0040, 0x17a8: 0x0040, 0x17a9: 0x0c18,\n\t0x17aa: 0x0c18, 0x17ab: 0x0c18, 0x17ac: 0x0c18, 0x17ad: 0x0a18, 0x17ae: 0x0a18, 0x17af: 0x0818,\n\t0x17b0: 0x0040, 0x17b1: 0x0040, 0x17b2: 0x0040, 0x17b3: 0x0040, 0x17b4: 0x0040, 0x17b5: 0x0040,\n\t0x17b6: 0x0040, 0x17b7: 0x0040, 0x17b8: 0x0040, 0x17b9: 0x0040, 0x17ba: 0x0040, 0x17bb: 0x0040,\n\t0x17bc: 0x0040, 0x17bd: 0x0040, 0x17be: 0x0040, 0x17bf: 0x0040,\n\t// Block 0x5f, offset 0x17c0\n\t0x17c0: 0x3308, 0x17c1: 0x3308, 0x17c2: 0x3008, 0x17c3: 0x3008, 0x17c4: 0x0040, 0x17c5: 0x0008,\n\t0x17c6: 0x0008, 0x17c7: 0x0008, 0x17c8: 0x0008, 0x17c9: 0x0008, 0x17ca: 0x0008, 0x17cb: 0x0008,\n\t0x17cc: 0x0008, 0x17cd: 0x0040, 0x17ce: 0x0040, 0x17cf: 0x0008, 0x17d0: 0x0008, 0x17d1: 0x0040,\n\t0x17d2: 0x0040, 0x17d3: 0x0008, 0x17d4: 0x0008, 0x17d5: 0x0008, 0x17d6: 0x0008, 0x17d7: 0x0008,\n\t0x17d8: 0x0008, 0x17d9: 0x0008, 0x17da: 0x0008, 0x17db: 0x0008, 0x17dc: 0x0008, 0x17dd: 0x0008,\n\t0x17de: 0x0008, 0x17df: 0x0008, 0x17e0: 0x0008, 0x17e1: 0x0008, 0x17e2: 0x0008, 0x17e3: 0x0008,\n\t0x17e4: 0x0008, 0x17e5: 0x0008, 0x17e6: 0x0008, 0x17e7: 0x0008, 0x17e8: 0x0008, 0x17e9: 0x0040,\n\t0x17ea: 0x0008, 0x17eb: 0x0008, 0x17ec: 0x0008, 0x17ed: 0x0008, 0x17ee: 0x0008, 0x17ef: 0x0008,\n\t0x17f0: 0x0008, 0x17f1: 0x0040, 0x17f2: 0x0008, 0x17f3: 0x0008, 0x17f4: 0x0040, 0x17f5: 0x0008,\n\t0x17f6: 0x0008, 0x17f7: 0x0008, 0x17f8: 0x0008, 0x17f9: 0x0008, 0x17fa: 0x0040, 0x17fb: 0x3308,\n\t0x17fc: 0x3308, 0x17fd: 0x0008, 0x17fe: 0x3008, 0x17ff: 0x3008,\n\t// Block 0x60, offset 0x1800\n\t0x1800: 0x3308, 0x1801: 0x3008, 0x1802: 0x3008, 0x1803: 0x3008, 0x1804: 0x3008, 0x1805: 0x0040,\n\t0x1806: 0x0040, 0x1807: 0x3008, 0x1808: 0x3008, 0x1809: 0x0040, 0x180a: 0x0040, 0x180b: 0x3008,\n\t0x180c: 0x3008, 0x180d: 0x3808, 0x180e: 0x0040, 0x180f: 0x0040, 0x1810: 0x0008, 0x1811: 0x0040,\n\t0x1812: 0x0040, 0x1813: 0x0040, 0x1814: 0x0040, 0x1815: 0x0040, 0x1816: 0x0040, 0x1817: 0x3008,\n\t0x1818: 0x0040, 0x1819: 0x0040, 0x181a: 0x0040, 0x181b: 0x0040, 0x181c: 0x0040, 0x181d: 0x0008,\n\t0x181e: 0x0008, 0x181f: 0x0008, 0x1820: 0x0008, 0x1821: 0x0008, 0x1822: 0x3008, 0x1823: 0x3008,\n\t0x1824: 0x0040, 0x1825: 0x0040, 0x1826: 0x3308, 0x1827: 0x3308, 0x1828: 0x3308, 0x1829: 0x3308,\n\t0x182a: 0x3308, 0x182b: 0x3308, 0x182c: 0x3308, 0x182d: 0x0040, 0x182e: 0x0040, 0x182f: 0x0040,\n\t0x1830: 0x3308, 0x1831: 0x3308, 0x1832: 0x3308, 0x1833: 0x3308, 0x1834: 0x3308, 0x1835: 0x0040,\n\t0x1836: 0x0040, 0x1837: 0x0040, 0x1838: 0x0040, 0x1839: 0x0040, 0x183a: 0x0040, 0x183b: 0x0040,\n\t0x183c: 0x0040, 0x183d: 0x0040, 0x183e: 0x0040, 0x183f: 0x0040,\n\t// Block 0x61, offset 0x1840\n\t0x1840: 0x0039, 0x1841: 0x0ee9, 0x1842: 0x1159, 0x1843: 0x0ef9, 0x1844: 0x0f09, 0x1845: 0x1199,\n\t0x1846: 0x0f31, 0x1847: 0x0249, 0x1848: 0x0f41, 0x1849: 0x0259, 0x184a: 0x0f51, 0x184b: 0x0359,\n\t0x184c: 0x0f61, 0x184d: 0x0f71, 0x184e: 0x00d9, 0x184f: 0x0f99, 0x1850: 0x2039, 0x1851: 0x0269,\n\t0x1852: 0x01d9, 0x1853: 0x0fa9, 0x1854: 0x0fb9, 0x1855: 0x1089, 0x1856: 0x0279, 0x1857: 0x0369,\n\t0x1858: 0x0289, 0x1859: 0x13d1, 0x185a: 0x0039, 0x185b: 0x0ee9, 0x185c: 0x1159, 0x185d: 0x0ef9,\n\t0x185e: 0x0f09, 0x185f: 0x1199, 0x1860: 0x0f31, 0x1861: 0x0249, 0x1862: 0x0f41, 0x1863: 0x0259,\n\t0x1864: 0x0f51, 0x1865: 0x0359, 0x1866: 0x0f61, 0x1867: 0x0f71, 0x1868: 0x00d9, 0x1869: 0x0f99,\n\t0x186a: 0x2039, 0x186b: 0x0269, 0x186c: 0x01d9, 0x186d: 0x0fa9, 0x186e: 0x0fb9, 0x186f: 0x1089,\n\t0x1870: 0x0279, 0x1871: 0x0369, 0x1872: 0x0289, 0x1873: 0x13d1, 0x1874: 0x0039, 0x1875: 0x0ee9,\n\t0x1876: 0x1159, 0x1877: 0x0ef9, 0x1878: 0x0f09, 0x1879: 0x1199, 0x187a: 0x0f31, 0x187b: 0x0249,\n\t0x187c: 0x0f41, 0x187d: 0x0259, 0x187e: 0x0f51, 0x187f: 0x0359,\n\t// Block 0x62, offset 0x1880\n\t0x1880: 0x0f61, 0x1881: 0x0f71, 0x1882: 0x00d9, 0x1883: 0x0f99, 0x1884: 0x2039, 0x1885: 0x0269,\n\t0x1886: 0x01d9, 0x1887: 0x0fa9, 0x1888: 0x0fb9, 0x1889: 0x1089, 0x188a: 0x0279, 0x188b: 0x0369,\n\t0x188c: 0x0289, 0x188d: 0x13d1, 0x188e: 0x0039, 0x188f: 0x0ee9, 0x1890: 0x1159, 0x1891: 0x0ef9,\n\t0x1892: 0x0f09, 0x1893: 0x1199, 0x1894: 0x0f31, 0x1895: 0x0040, 0x1896: 0x0f41, 0x1897: 0x0259,\n\t0x1898: 0x0f51, 0x1899: 0x0359, 0x189a: 0x0f61, 0x189b: 0x0f71, 0x189c: 0x00d9, 0x189d: 0x0f99,\n\t0x189e: 0x2039, 0x189f: 0x0269, 0x18a0: 0x01d9, 0x18a1: 0x0fa9, 0x18a2: 0x0fb9, 0x18a3: 0x1089,\n\t0x18a4: 0x0279, 0x18a5: 0x0369, 0x18a6: 0x0289, 0x18a7: 0x13d1, 0x18a8: 0x0039, 0x18a9: 0x0ee9,\n\t0x18aa: 0x1159, 0x18ab: 0x0ef9, 0x18ac: 0x0f09, 0x18ad: 0x1199, 0x18ae: 0x0f31, 0x18af: 0x0249,\n\t0x18b0: 0x0f41, 0x18b1: 0x0259, 0x18b2: 0x0f51, 0x18b3: 0x0359, 0x18b4: 0x0f61, 0x18b5: 0x0f71,\n\t0x18b6: 0x00d9, 0x18b7: 0x0f99, 0x18b8: 0x2039, 0x18b9: 0x0269, 0x18ba: 0x01d9, 0x18bb: 0x0fa9,\n\t0x18bc: 0x0fb9, 0x18bd: 0x1089, 0x18be: 0x0279, 0x18bf: 0x0369,\n\t// Block 0x63, offset 0x18c0\n\t0x18c0: 0x0289, 0x18c1: 0x13d1, 0x18c2: 0x0039, 0x18c3: 0x0ee9, 0x18c4: 0x1159, 0x18c5: 0x0ef9,\n\t0x18c6: 0x0f09, 0x18c7: 0x1199, 0x18c8: 0x0f31, 0x18c9: 0x0249, 0x18ca: 0x0f41, 0x18cb: 0x0259,\n\t0x18cc: 0x0f51, 0x18cd: 0x0359, 0x18ce: 0x0f61, 0x18cf: 0x0f71, 0x18d0: 0x00d9, 0x18d1: 0x0f99,\n\t0x18d2: 0x2039, 0x18d3: 0x0269, 0x18d4: 0x01d9, 0x18d5: 0x0fa9, 0x18d6: 0x0fb9, 0x18d7: 0x1089,\n\t0x18d8: 0x0279, 0x18d9: 0x0369, 0x18da: 0x0289, 0x18db: 0x13d1, 0x18dc: 0x0039, 0x18dd: 0x0040,\n\t0x18de: 0x1159, 0x18df: 0x0ef9, 0x18e0: 0x0040, 0x18e1: 0x0040, 0x18e2: 0x0f31, 0x18e3: 0x0040,\n\t0x18e4: 0x0040, 0x18e5: 0x0259, 0x18e6: 0x0f51, 0x18e7: 0x0040, 0x18e8: 0x0040, 0x18e9: 0x0f71,\n\t0x18ea: 0x00d9, 0x18eb: 0x0f99, 0x18ec: 0x2039, 0x18ed: 0x0040, 0x18ee: 0x01d9, 0x18ef: 0x0fa9,\n\t0x18f0: 0x0fb9, 0x18f1: 0x1089, 0x18f2: 0x0279, 0x18f3: 0x0369, 0x18f4: 0x0289, 0x18f5: 0x13d1,\n\t0x18f6: 0x0039, 0x18f7: 0x0ee9, 0x18f8: 0x1159, 0x18f9: 0x0ef9, 0x18fa: 0x0040, 0x18fb: 0x1199,\n\t0x18fc: 0x0040, 0x18fd: 0x0249, 0x18fe: 0x0f41, 0x18ff: 0x0259,\n\t// Block 0x64, offset 0x1900\n\t0x1900: 0x0f51, 0x1901: 0x0359, 0x1902: 0x0f61, 0x1903: 0x0f71, 0x1904: 0x0040, 0x1905: 0x0f99,\n\t0x1906: 0x2039, 0x1907: 0x0269, 0x1908: 0x01d9, 0x1909: 0x0fa9, 0x190a: 0x0fb9, 0x190b: 0x1089,\n\t0x190c: 0x0279, 0x190d: 0x0369, 0x190e: 0x0289, 0x190f: 0x13d1, 0x1910: 0x0039, 0x1911: 0x0ee9,\n\t0x1912: 0x1159, 0x1913: 0x0ef9, 0x1914: 0x0f09, 0x1915: 0x1199, 0x1916: 0x0f31, 0x1917: 0x0249,\n\t0x1918: 0x0f41, 0x1919: 0x0259, 0x191a: 0x0f51, 0x191b: 0x0359, 0x191c: 0x0f61, 0x191d: 0x0f71,\n\t0x191e: 0x00d9, 0x191f: 0x0f99, 0x1920: 0x2039, 0x1921: 0x0269, 0x1922: 0x01d9, 0x1923: 0x0fa9,\n\t0x1924: 0x0fb9, 0x1925: 0x1089, 0x1926: 0x0279, 0x1927: 0x0369, 0x1928: 0x0289, 0x1929: 0x13d1,\n\t0x192a: 0x0039, 0x192b: 0x0ee9, 0x192c: 0x1159, 0x192d: 0x0ef9, 0x192e: 0x0f09, 0x192f: 0x1199,\n\t0x1930: 0x0f31, 0x1931: 0x0249, 0x1932: 0x0f41, 0x1933: 0x0259, 0x1934: 0x0f51, 0x1935: 0x0359,\n\t0x1936: 0x0f61, 0x1937: 0x0f71, 0x1938: 0x00d9, 0x1939: 0x0f99, 0x193a: 0x2039, 0x193b: 0x0269,\n\t0x193c: 0x01d9, 0x193d: 0x0fa9, 0x193e: 0x0fb9, 0x193f: 0x1089,\n\t// Block 0x65, offset 0x1940\n\t0x1940: 0x0279, 0x1941: 0x0369, 0x1942: 0x0289, 0x1943: 0x13d1, 0x1944: 0x0039, 0x1945: 0x0ee9,\n\t0x1946: 0x0040, 0x1947: 0x0ef9, 0x1948: 0x0f09, 0x1949: 0x1199, 0x194a: 0x0f31, 0x194b: 0x0040,\n\t0x194c: 0x0040, 0x194d: 0x0259, 0x194e: 0x0f51, 0x194f: 0x0359, 0x1950: 0x0f61, 0x1951: 0x0f71,\n\t0x1952: 0x00d9, 0x1953: 0x0f99, 0x1954: 0x2039, 0x1955: 0x0040, 0x1956: 0x01d9, 0x1957: 0x0fa9,\n\t0x1958: 0x0fb9, 0x1959: 0x1089, 0x195a: 0x0279, 0x195b: 0x0369, 0x195c: 0x0289, 0x195d: 0x0040,\n\t0x195e: 0x0039, 0x195f: 0x0ee9, 0x1960: 0x1159, 0x1961: 0x0ef9, 0x1962: 0x0f09, 0x1963: 0x1199,\n\t0x1964: 0x0f31, 0x1965: 0x0249, 0x1966: 0x0f41, 0x1967: 0x0259, 0x1968: 0x0f51, 0x1969: 0x0359,\n\t0x196a: 0x0f61, 0x196b: 0x0f71, 0x196c: 0x00d9, 0x196d: 0x0f99, 0x196e: 0x2039, 0x196f: 0x0269,\n\t0x1970: 0x01d9, 0x1971: 0x0fa9, 0x1972: 0x0fb9, 0x1973: 0x1089, 0x1974: 0x0279, 0x1975: 0x0369,\n\t0x1976: 0x0289, 0x1977: 0x13d1, 0x1978: 0x0039, 0x1979: 0x0ee9, 0x197a: 0x0040, 0x197b: 0x0ef9,\n\t0x197c: 0x0f09, 0x197d: 0x1199, 0x197e: 0x0f31, 0x197f: 0x0040,\n\t// Block 0x66, offset 0x1980\n\t0x1980: 0x0f41, 0x1981: 0x0259, 0x1982: 0x0f51, 0x1983: 0x0359, 0x1984: 0x0f61, 0x1985: 0x0040,\n\t0x1986: 0x00d9, 0x1987: 0x0040, 0x1988: 0x0040, 0x1989: 0x0040, 0x198a: 0x01d9, 0x198b: 0x0fa9,\n\t0x198c: 0x0fb9, 0x198d: 0x1089, 0x198e: 0x0279, 0x198f: 0x0369, 0x1990: 0x0289, 0x1991: 0x0040,\n\t0x1992: 0x0039, 0x1993: 0x0ee9, 0x1994: 0x1159, 0x1995: 0x0ef9, 0x1996: 0x0f09, 0x1997: 0x1199,\n\t0x1998: 0x0f31, 0x1999: 0x0249, 0x199a: 0x0f41, 0x199b: 0x0259, 0x199c: 0x0f51, 0x199d: 0x0359,\n\t0x199e: 0x0f61, 0x199f: 0x0f71, 0x19a0: 0x00d9, 0x19a1: 0x0f99, 0x19a2: 0x2039, 0x19a3: 0x0269,\n\t0x19a4: 0x01d9, 0x19a5: 0x0fa9, 0x19a6: 0x0fb9, 0x19a7: 0x1089, 0x19a8: 0x0279, 0x19a9: 0x0369,\n\t0x19aa: 0x0289, 0x19ab: 0x13d1, 0x19ac: 0x0039, 0x19ad: 0x0ee9, 0x19ae: 0x1159, 0x19af: 0x0ef9,\n\t0x19b0: 0x0f09, 0x19b1: 0x1199, 0x19b2: 0x0f31, 0x19b3: 0x0249, 0x19b4: 0x0f41, 0x19b5: 0x0259,\n\t0x19b6: 0x0f51, 0x19b7: 0x0359, 0x19b8: 0x0f61, 0x19b9: 0x0f71, 0x19ba: 0x00d9, 0x19bb: 0x0f99,\n\t0x19bc: 0x2039, 0x19bd: 0x0269, 0x19be: 0x01d9, 0x19bf: 0x0fa9,\n\t// Block 0x67, offset 0x19c0\n\t0x19c0: 0x0fb9, 0x19c1: 0x1089, 0x19c2: 0x0279, 0x19c3: 0x0369, 0x19c4: 0x0289, 0x19c5: 0x13d1,\n\t0x19c6: 0x0039, 0x19c7: 0x0ee9, 0x19c8: 0x1159, 0x19c9: 0x0ef9, 0x19ca: 0x0f09, 0x19cb: 0x1199,\n\t0x19cc: 0x0f31, 0x19cd: 0x0249, 0x19ce: 0x0f41, 0x19cf: 0x0259, 0x19d0: 0x0f51, 0x19d1: 0x0359,\n\t0x19d2: 0x0f61, 0x19d3: 0x0f71, 0x19d4: 0x00d9, 0x19d5: 0x0f99, 0x19d6: 0x2039, 0x19d7: 0x0269,\n\t0x19d8: 0x01d9, 0x19d9: 0x0fa9, 0x19da: 0x0fb9, 0x19db: 0x1089, 0x19dc: 0x0279, 0x19dd: 0x0369,\n\t0x19de: 0x0289, 0x19df: 0x13d1, 0x19e0: 0x0039, 0x19e1: 0x0ee9, 0x19e2: 0x1159, 0x19e3: 0x0ef9,\n\t0x19e4: 0x0f09, 0x19e5: 0x1199, 0x19e6: 0x0f31, 0x19e7: 0x0249, 0x19e8: 0x0f41, 0x19e9: 0x0259,\n\t0x19ea: 0x0f51, 0x19eb: 0x0359, 0x19ec: 0x0f61, 0x19ed: 0x0f71, 0x19ee: 0x00d9, 0x19ef: 0x0f99,\n\t0x19f0: 0x2039, 0x19f1: 0x0269, 0x19f2: 0x01d9, 0x19f3: 0x0fa9, 0x19f4: 0x0fb9, 0x19f5: 0x1089,\n\t0x19f6: 0x0279, 0x19f7: 0x0369, 0x19f8: 0x0289, 0x19f9: 0x13d1, 0x19fa: 0x0039, 0x19fb: 0x0ee9,\n\t0x19fc: 0x1159, 0x19fd: 0x0ef9, 0x19fe: 0x0f09, 0x19ff: 0x1199,\n\t// Block 0x68, offset 0x1a00\n\t0x1a00: 0x0f31, 0x1a01: 0x0249, 0x1a02: 0x0f41, 0x1a03: 0x0259, 0x1a04: 0x0f51, 0x1a05: 0x0359,\n\t0x1a06: 0x0f61, 0x1a07: 0x0f71, 0x1a08: 0x00d9, 0x1a09: 0x0f99, 0x1a0a: 0x2039, 0x1a0b: 0x0269,\n\t0x1a0c: 0x01d9, 0x1a0d: 0x0fa9, 0x1a0e: 0x0fb9, 0x1a0f: 0x1089, 0x1a10: 0x0279, 0x1a11: 0x0369,\n\t0x1a12: 0x0289, 0x1a13: 0x13d1, 0x1a14: 0x0039, 0x1a15: 0x0ee9, 0x1a16: 0x1159, 0x1a17: 0x0ef9,\n\t0x1a18: 0x0f09, 0x1a19: 0x1199, 0x1a1a: 0x0f31, 0x1a1b: 0x0249, 0x1a1c: 0x0f41, 0x1a1d: 0x0259,\n\t0x1a1e: 0x0f51, 0x1a1f: 0x0359, 0x1a20: 0x0f61, 0x1a21: 0x0f71, 0x1a22: 0x00d9, 0x1a23: 0x0f99,\n\t0x1a24: 0x2039, 0x1a25: 0x0269, 0x1a26: 0x01d9, 0x1a27: 0x0fa9, 0x1a28: 0x0fb9, 0x1a29: 0x1089,\n\t0x1a2a: 0x0279, 0x1a2b: 0x0369, 0x1a2c: 0x0289, 0x1a2d: 0x13d1, 0x1a2e: 0x0039, 0x1a2f: 0x0ee9,\n\t0x1a30: 0x1159, 0x1a31: 0x0ef9, 0x1a32: 0x0f09, 0x1a33: 0x1199, 0x1a34: 0x0f31, 0x1a35: 0x0249,\n\t0x1a36: 0x0f41, 0x1a37: 0x0259, 0x1a38: 0x0f51, 0x1a39: 0x0359, 0x1a3a: 0x0f61, 0x1a3b: 0x0f71,\n\t0x1a3c: 0x00d9, 0x1a3d: 0x0f99, 0x1a3e: 0x2039, 0x1a3f: 0x0269,\n\t// Block 0x69, offset 0x1a40\n\t0x1a40: 0x01d9, 0x1a41: 0x0fa9, 0x1a42: 0x0fb9, 0x1a43: 0x1089, 0x1a44: 0x0279, 0x1a45: 0x0369,\n\t0x1a46: 0x0289, 0x1a47: 0x13d1, 0x1a48: 0x0039, 0x1a49: 0x0ee9, 0x1a4a: 0x1159, 0x1a4b: 0x0ef9,\n\t0x1a4c: 0x0f09, 0x1a4d: 0x1199, 0x1a4e: 0x0f31, 0x1a4f: 0x0249, 0x1a50: 0x0f41, 0x1a51: 0x0259,\n\t0x1a52: 0x0f51, 0x1a53: 0x0359, 0x1a54: 0x0f61, 0x1a55: 0x0f71, 0x1a56: 0x00d9, 0x1a57: 0x0f99,\n\t0x1a58: 0x2039, 0x1a59: 0x0269, 0x1a5a: 0x01d9, 0x1a5b: 0x0fa9, 0x1a5c: 0x0fb9, 0x1a5d: 0x1089,\n\t0x1a5e: 0x0279, 0x1a5f: 0x0369, 0x1a60: 0x0289, 0x1a61: 0x13d1, 0x1a62: 0x0039, 0x1a63: 0x0ee9,\n\t0x1a64: 0x1159, 0x1a65: 0x0ef9, 0x1a66: 0x0f09, 0x1a67: 0x1199, 0x1a68: 0x0f31, 0x1a69: 0x0249,\n\t0x1a6a: 0x0f41, 0x1a6b: 0x0259, 0x1a6c: 0x0f51, 0x1a6d: 0x0359, 0x1a6e: 0x0f61, 0x1a6f: 0x0f71,\n\t0x1a70: 0x00d9, 0x1a71: 0x0f99, 0x1a72: 0x2039, 0x1a73: 0x0269, 0x1a74: 0x01d9, 0x1a75: 0x0fa9,\n\t0x1a76: 0x0fb9, 0x1a77: 0x1089, 0x1a78: 0x0279, 0x1a79: 0x0369, 0x1a7a: 0x0289, 0x1a7b: 0x13d1,\n\t0x1a7c: 0x0039, 0x1a7d: 0x0ee9, 0x1a7e: 0x1159, 0x1a7f: 0x0ef9,\n\t// Block 0x6a, offset 0x1a80\n\t0x1a80: 0x0f09, 0x1a81: 0x1199, 0x1a82: 0x0f31, 0x1a83: 0x0249, 0x1a84: 0x0f41, 0x1a85: 0x0259,\n\t0x1a86: 0x0f51, 0x1a87: 0x0359, 0x1a88: 0x0f61, 0x1a89: 0x0f71, 0x1a8a: 0x00d9, 0x1a8b: 0x0f99,\n\t0x1a8c: 0x2039, 0x1a8d: 0x0269, 0x1a8e: 0x01d9, 0x1a8f: 0x0fa9, 0x1a90: 0x0fb9, 0x1a91: 0x1089,\n\t0x1a92: 0x0279, 0x1a93: 0x0369, 0x1a94: 0x0289, 0x1a95: 0x13d1, 0x1a96: 0x0039, 0x1a97: 0x0ee9,\n\t0x1a98: 0x1159, 0x1a99: 0x0ef9, 0x1a9a: 0x0f09, 0x1a9b: 0x1199, 0x1a9c: 0x0f31, 0x1a9d: 0x0249,\n\t0x1a9e: 0x0f41, 0x1a9f: 0x0259, 0x1aa0: 0x0f51, 0x1aa1: 0x0359, 0x1aa2: 0x0f61, 0x1aa3: 0x0f71,\n\t0x1aa4: 0x00d9, 0x1aa5: 0x0f99, 0x1aa6: 0x2039, 0x1aa7: 0x0269, 0x1aa8: 0x01d9, 0x1aa9: 0x0fa9,\n\t0x1aaa: 0x0fb9, 0x1aab: 0x1089, 0x1aac: 0x0279, 0x1aad: 0x0369, 0x1aae: 0x0289, 0x1aaf: 0x13d1,\n\t0x1ab0: 0x0039, 0x1ab1: 0x0ee9, 0x1ab2: 0x1159, 0x1ab3: 0x0ef9, 0x1ab4: 0x0f09, 0x1ab5: 0x1199,\n\t0x1ab6: 0x0f31, 0x1ab7: 0x0249, 0x1ab8: 0x0f41, 0x1ab9: 0x0259, 0x1aba: 0x0f51, 0x1abb: 0x0359,\n\t0x1abc: 0x0f61, 0x1abd: 0x0f71, 0x1abe: 0x00d9, 0x1abf: 0x0f99,\n\t// Block 0x6b, offset 0x1ac0\n\t0x1ac0: 0x2039, 0x1ac1: 0x0269, 0x1ac2: 0x01d9, 0x1ac3: 0x0fa9, 0x1ac4: 0x0fb9, 0x1ac5: 0x1089,\n\t0x1ac6: 0x0279, 0x1ac7: 0x0369, 0x1ac8: 0x0289, 0x1ac9: 0x13d1, 0x1aca: 0x0039, 0x1acb: 0x0ee9,\n\t0x1acc: 0x1159, 0x1acd: 0x0ef9, 0x1ace: 0x0f09, 0x1acf: 0x1199, 0x1ad0: 0x0f31, 0x1ad1: 0x0249,\n\t0x1ad2: 0x0f41, 0x1ad3: 0x0259, 0x1ad4: 0x0f51, 0x1ad5: 0x0359, 0x1ad6: 0x0f61, 0x1ad7: 0x0f71,\n\t0x1ad8: 0x00d9, 0x1ad9: 0x0f99, 0x1ada: 0x2039, 0x1adb: 0x0269, 0x1adc: 0x01d9, 0x1add: 0x0fa9,\n\t0x1ade: 0x0fb9, 0x1adf: 0x1089, 0x1ae0: 0x0279, 0x1ae1: 0x0369, 0x1ae2: 0x0289, 0x1ae3: 0x13d1,\n\t0x1ae4: 0xba81, 0x1ae5: 0xba99, 0x1ae6: 0x0040, 0x1ae7: 0x0040, 0x1ae8: 0xbab1, 0x1ae9: 0x1099,\n\t0x1aea: 0x10b1, 0x1aeb: 0x10c9, 0x1aec: 0xbac9, 0x1aed: 0xbae1, 0x1aee: 0xbaf9, 0x1aef: 0x1429,\n\t0x1af0: 0x1a31, 0x1af1: 0xbb11, 0x1af2: 0xbb29, 0x1af3: 0xbb41, 0x1af4: 0xbb59, 0x1af5: 0xbb71,\n\t0x1af6: 0xbb89, 0x1af7: 0x2109, 0x1af8: 0x1111, 0x1af9: 0x1429, 0x1afa: 0xbba1, 0x1afb: 0xbbb9,\n\t0x1afc: 0xbbd1, 0x1afd: 0x10e1, 0x1afe: 0x10f9, 0x1aff: 0xbbe9,\n\t// Block 0x6c, offset 0x1b00\n\t0x1b00: 0x2079, 0x1b01: 0xbc01, 0x1b02: 0xbab1, 0x1b03: 0x1099, 0x1b04: 0x10b1, 0x1b05: 0x10c9,\n\t0x1b06: 0xbac9, 0x1b07: 0xbae1, 0x1b08: 0xbaf9, 0x1b09: 0x1429, 0x1b0a: 0x1a31, 0x1b0b: 0xbb11,\n\t0x1b0c: 0xbb29, 0x1b0d: 0xbb41, 0x1b0e: 0xbb59, 0x1b0f: 0xbb71, 0x1b10: 0xbb89, 0x1b11: 0x2109,\n\t0x1b12: 0x1111, 0x1b13: 0xbba1, 0x1b14: 0xbba1, 0x1b15: 0xbbb9, 0x1b16: 0xbbd1, 0x1b17: 0x10e1,\n\t0x1b18: 0x10f9, 0x1b19: 0xbbe9, 0x1b1a: 0x2079, 0x1b1b: 0xbc21, 0x1b1c: 0xbac9, 0x1b1d: 0x1429,\n\t0x1b1e: 0xbb11, 0x1b1f: 0x10e1, 0x1b20: 0x1111, 0x1b21: 0x2109, 0x1b22: 0xbab1, 0x1b23: 0x1099,\n\t0x1b24: 0x10b1, 0x1b25: 0x10c9, 0x1b26: 0xbac9, 0x1b27: 0xbae1, 0x1b28: 0xbaf9, 0x1b29: 0x1429,\n\t0x1b2a: 0x1a31, 0x1b2b: 0xbb11, 0x1b2c: 0xbb29, 0x1b2d: 0xbb41, 0x1b2e: 0xbb59, 0x1b2f: 0xbb71,\n\t0x1b30: 0xbb89, 0x1b31: 0x2109, 0x1b32: 0x1111, 0x1b33: 0x1429, 0x1b34: 0xbba1, 0x1b35: 0xbbb9,\n\t0x1b36: 0xbbd1, 0x1b37: 0x10e1, 0x1b38: 0x10f9, 0x1b39: 0xbbe9, 0x1b3a: 0x2079, 0x1b3b: 0xbc01,\n\t0x1b3c: 0xbab1, 0x1b3d: 0x1099, 0x1b3e: 0x10b1, 0x1b3f: 0x10c9,\n\t// Block 0x6d, offset 0x1b40\n\t0x1b40: 0xbac9, 0x1b41: 0xbae1, 0x1b42: 0xbaf9, 0x1b43: 0x1429, 0x1b44: 0x1a31, 0x1b45: 0xbb11,\n\t0x1b46: 0xbb29, 0x1b47: 0xbb41, 0x1b48: 0xbb59, 0x1b49: 0xbb71, 0x1b4a: 0xbb89, 0x1b4b: 0x2109,\n\t0x1b4c: 0x1111, 0x1b4d: 0xbba1, 0x1b4e: 0xbba1, 0x1b4f: 0xbbb9, 0x1b50: 0xbbd1, 0x1b51: 0x10e1,\n\t0x1b52: 0x10f9, 0x1b53: 0xbbe9, 0x1b54: 0x2079, 0x1b55: 0xbc21, 0x1b56: 0xbac9, 0x1b57: 0x1429,\n\t0x1b58: 0xbb11, 0x1b59: 0x10e1, 0x1b5a: 0x1111, 0x1b5b: 0x2109, 0x1b5c: 0xbab1, 0x1b5d: 0x1099,\n\t0x1b5e: 0x10b1, 0x1b5f: 0x10c9, 0x1b60: 0xbac9, 0x1b61: 0xbae1, 0x1b62: 0xbaf9, 0x1b63: 0x1429,\n\t0x1b64: 0x1a31, 0x1b65: 0xbb11, 0x1b66: 0xbb29, 0x1b67: 0xbb41, 0x1b68: 0xbb59, 0x1b69: 0xbb71,\n\t0x1b6a: 0xbb89, 0x1b6b: 0x2109, 0x1b6c: 0x1111, 0x1b6d: 0x1429, 0x1b6e: 0xbba1, 0x1b6f: 0xbbb9,\n\t0x1b70: 0xbbd1, 0x1b71: 0x10e1, 0x1b72: 0x10f9, 0x1b73: 0xbbe9, 0x1b74: 0x2079, 0x1b75: 0xbc01,\n\t0x1b76: 0xbab1, 0x1b77: 0x1099, 0x1b78: 0x10b1, 0x1b79: 0x10c9, 0x1b7a: 0xbac9, 0x1b7b: 0xbae1,\n\t0x1b7c: 0xbaf9, 0x1b7d: 0x1429, 0x1b7e: 0x1a31, 0x1b7f: 0xbb11,\n\t// Block 0x6e, offset 0x1b80\n\t0x1b80: 0xbb29, 0x1b81: 0xbb41, 0x1b82: 0xbb59, 0x1b83: 0xbb71, 0x1b84: 0xbb89, 0x1b85: 0x2109,\n\t0x1b86: 0x1111, 0x1b87: 0xbba1, 0x1b88: 0xbba1, 0x1b89: 0xbbb9, 0x1b8a: 0xbbd1, 0x1b8b: 0x10e1,\n\t0x1b8c: 0x10f9, 0x1b8d: 0xbbe9, 0x1b8e: 0x2079, 0x1b8f: 0xbc21, 0x1b90: 0xbac9, 0x1b91: 0x1429,\n\t0x1b92: 0xbb11, 0x1b93: 0x10e1, 0x1b94: 0x1111, 0x1b95: 0x2109, 0x1b96: 0xbab1, 0x1b97: 0x1099,\n\t0x1b98: 0x10b1, 0x1b99: 0x10c9, 0x1b9a: 0xbac9, 0x1b9b: 0xbae1, 0x1b9c: 0xbaf9, 0x1b9d: 0x1429,\n\t0x1b9e: 0x1a31, 0x1b9f: 0xbb11, 0x1ba0: 0xbb29, 0x1ba1: 0xbb41, 0x1ba2: 0xbb59, 0x1ba3: 0xbb71,\n\t0x1ba4: 0xbb89, 0x1ba5: 0x2109, 0x1ba6: 0x1111, 0x1ba7: 0x1429, 0x1ba8: 0xbba1, 0x1ba9: 0xbbb9,\n\t0x1baa: 0xbbd1, 0x1bab: 0x10e1, 0x1bac: 0x10f9, 0x1bad: 0xbbe9, 0x1bae: 0x2079, 0x1baf: 0xbc01,\n\t0x1bb0: 0xbab1, 0x1bb1: 0x1099, 0x1bb2: 0x10b1, 0x1bb3: 0x10c9, 0x1bb4: 0xbac9, 0x1bb5: 0xbae1,\n\t0x1bb6: 0xbaf9, 0x1bb7: 0x1429, 0x1bb8: 0x1a31, 0x1bb9: 0xbb11, 0x1bba: 0xbb29, 0x1bbb: 0xbb41,\n\t0x1bbc: 0xbb59, 0x1bbd: 0xbb71, 0x1bbe: 0xbb89, 0x1bbf: 0x2109,\n\t// Block 0x6f, offset 0x1bc0\n\t0x1bc0: 0x1111, 0x1bc1: 0xbba1, 0x1bc2: 0xbba1, 0x1bc3: 0xbbb9, 0x1bc4: 0xbbd1, 0x1bc5: 0x10e1,\n\t0x1bc6: 0x10f9, 0x1bc7: 0xbbe9, 0x1bc8: 0x2079, 0x1bc9: 0xbc21, 0x1bca: 0xbac9, 0x1bcb: 0x1429,\n\t0x1bcc: 0xbb11, 0x1bcd: 0x10e1, 0x1bce: 0x1111, 0x1bcf: 0x2109, 0x1bd0: 0xbab1, 0x1bd1: 0x1099,\n\t0x1bd2: 0x10b1, 0x1bd3: 0x10c9, 0x1bd4: 0xbac9, 0x1bd5: 0xbae1, 0x1bd6: 0xbaf9, 0x1bd7: 0x1429,\n\t0x1bd8: 0x1a31, 0x1bd9: 0xbb11, 0x1bda: 0xbb29, 0x1bdb: 0xbb41, 0x1bdc: 0xbb59, 0x1bdd: 0xbb71,\n\t0x1bde: 0xbb89, 0x1bdf: 0x2109, 0x1be0: 0x1111, 0x1be1: 0x1429, 0x1be2: 0xbba1, 0x1be3: 0xbbb9,\n\t0x1be4: 0xbbd1, 0x1be5: 0x10e1, 0x1be6: 0x10f9, 0x1be7: 0xbbe9, 0x1be8: 0x2079, 0x1be9: 0xbc01,\n\t0x1bea: 0xbab1, 0x1beb: 0x1099, 0x1bec: 0x10b1, 0x1bed: 0x10c9, 0x1bee: 0xbac9, 0x1bef: 0xbae1,\n\t0x1bf0: 0xbaf9, 0x1bf1: 0x1429, 0x1bf2: 0x1a31, 0x1bf3: 0xbb11, 0x1bf4: 0xbb29, 0x1bf5: 0xbb41,\n\t0x1bf6: 0xbb59, 0x1bf7: 0xbb71, 0x1bf8: 0xbb89, 0x1bf9: 0x2109, 0x1bfa: 0x1111, 0x1bfb: 0xbba1,\n\t0x1bfc: 0xbba1, 0x1bfd: 0xbbb9, 0x1bfe: 0xbbd1, 0x1bff: 0x10e1,\n\t// Block 0x70, offset 0x1c00\n\t0x1c00: 0x10f9, 0x1c01: 0xbbe9, 0x1c02: 0x2079, 0x1c03: 0xbc21, 0x1c04: 0xbac9, 0x1c05: 0x1429,\n\t0x1c06: 0xbb11, 0x1c07: 0x10e1, 0x1c08: 0x1111, 0x1c09: 0x2109, 0x1c0a: 0xbc41, 0x1c0b: 0xbc41,\n\t0x1c0c: 0x0040, 0x1c0d: 0x0040, 0x1c0e: 0x1f41, 0x1c0f: 0x00c9, 0x1c10: 0x0069, 0x1c11: 0x0079,\n\t0x1c12: 0x1f51, 0x1c13: 0x1f61, 0x1c14: 0x1f71, 0x1c15: 0x1f81, 0x1c16: 0x1f91, 0x1c17: 0x1fa1,\n\t0x1c18: 0x1f41, 0x1c19: 0x00c9, 0x1c1a: 0x0069, 0x1c1b: 0x0079, 0x1c1c: 0x1f51, 0x1c1d: 0x1f61,\n\t0x1c1e: 0x1f71, 0x1c1f: 0x1f81, 0x1c20: 0x1f91, 0x1c21: 0x1fa1, 0x1c22: 0x1f41, 0x1c23: 0x00c9,\n\t0x1c24: 0x0069, 0x1c25: 0x0079, 0x1c26: 0x1f51, 0x1c27: 0x1f61, 0x1c28: 0x1f71, 0x1c29: 0x1f81,\n\t0x1c2a: 0x1f91, 0x1c2b: 0x1fa1, 0x1c2c: 0x1f41, 0x1c2d: 0x00c9, 0x1c2e: 0x0069, 0x1c2f: 0x0079,\n\t0x1c30: 0x1f51, 0x1c31: 0x1f61, 0x1c32: 0x1f71, 0x1c33: 0x1f81, 0x1c34: 0x1f91, 0x1c35: 0x1fa1,\n\t0x1c36: 0x1f41, 0x1c37: 0x00c9, 0x1c38: 0x0069, 0x1c39: 0x0079, 0x1c3a: 0x1f51, 0x1c3b: 0x1f61,\n\t0x1c3c: 0x1f71, 0x1c3d: 0x1f81, 0x1c3e: 0x1f91, 0x1c3f: 0x1fa1,\n\t// Block 0x71, offset 0x1c40\n\t0x1c40: 0xe115, 0x1c41: 0xe115, 0x1c42: 0xe135, 0x1c43: 0xe135, 0x1c44: 0xe115, 0x1c45: 0xe115,\n\t0x1c46: 0xe175, 0x1c47: 0xe175, 0x1c48: 0xe115, 0x1c49: 0xe115, 0x1c4a: 0xe135, 0x1c4b: 0xe135,\n\t0x1c4c: 0xe115, 0x1c4d: 0xe115, 0x1c4e: 0xe1f5, 0x1c4f: 0xe1f5, 0x1c50: 0xe115, 0x1c51: 0xe115,\n\t0x1c52: 0xe135, 0x1c53: 0xe135, 0x1c54: 0xe115, 0x1c55: 0xe115, 0x1c56: 0xe175, 0x1c57: 0xe175,\n\t0x1c58: 0xe115, 0x1c59: 0xe115, 0x1c5a: 0xe135, 0x1c5b: 0xe135, 0x1c5c: 0xe115, 0x1c5d: 0xe115,\n\t0x1c5e: 0x8b3d, 0x1c5f: 0x8b3d, 0x1c60: 0x04b5, 0x1c61: 0x04b5, 0x1c62: 0x0a08, 0x1c63: 0x0a08,\n\t0x1c64: 0x0a08, 0x1c65: 0x0a08, 0x1c66: 0x0a08, 0x1c67: 0x0a08, 0x1c68: 0x0a08, 0x1c69: 0x0a08,\n\t0x1c6a: 0x0a08, 0x1c6b: 0x0a08, 0x1c6c: 0x0a08, 0x1c6d: 0x0a08, 0x1c6e: 0x0a08, 0x1c6f: 0x0a08,\n\t0x1c70: 0x0a08, 0x1c71: 0x0a08, 0x1c72: 0x0a08, 0x1c73: 0x0a08, 0x1c74: 0x0a08, 0x1c75: 0x0a08,\n\t0x1c76: 0x0a08, 0x1c77: 0x0a08, 0x1c78: 0x0a08, 0x1c79: 0x0a08, 0x1c7a: 0x0a08, 0x1c7b: 0x0a08,\n\t0x1c7c: 0x0a08, 0x1c7d: 0x0a08, 0x1c7e: 0x0a08, 0x1c7f: 0x0a08,\n\t// Block 0x72, offset 0x1c80\n\t0x1c80: 0xb189, 0x1c81: 0xb1a1, 0x1c82: 0xb201, 0x1c83: 0xb249, 0x1c84: 0x0040, 0x1c85: 0xb411,\n\t0x1c86: 0xb291, 0x1c87: 0xb219, 0x1c88: 0xb309, 0x1c89: 0xb429, 0x1c8a: 0xb399, 0x1c8b: 0xb3b1,\n\t0x1c8c: 0xb3c9, 0x1c8d: 0xb3e1, 0x1c8e: 0xb2a9, 0x1c8f: 0xb339, 0x1c90: 0xb369, 0x1c91: 0xb2d9,\n\t0x1c92: 0xb381, 0x1c93: 0xb279, 0x1c94: 0xb2c1, 0x1c95: 0xb1d1, 0x1c96: 0xb1e9, 0x1c97: 0xb231,\n\t0x1c98: 0xb261, 0x1c99: 0xb2f1, 0x1c9a: 0xb321, 0x1c9b: 0xb351, 0x1c9c: 0xbc59, 0x1c9d: 0x7949,\n\t0x1c9e: 0xbc71, 0x1c9f: 0xbc89, 0x1ca0: 0x0040, 0x1ca1: 0xb1a1, 0x1ca2: 0xb201, 0x1ca3: 0x0040,\n\t0x1ca4: 0xb3f9, 0x1ca5: 0x0040, 0x1ca6: 0x0040, 0x1ca7: 0xb219, 0x1ca8: 0x0040, 0x1ca9: 0xb429,\n\t0x1caa: 0xb399, 0x1cab: 0xb3b1, 0x1cac: 0xb3c9, 0x1cad: 0xb3e1, 0x1cae: 0xb2a9, 0x1caf: 0xb339,\n\t0x1cb0: 0xb369, 0x1cb1: 0xb2d9, 0x1cb2: 0xb381, 0x1cb3: 0x0040, 0x1cb4: 0xb2c1, 0x1cb5: 0xb1d1,\n\t0x1cb6: 0xb1e9, 0x1cb7: 0xb231, 0x1cb8: 0x0040, 0x1cb9: 0xb2f1, 0x1cba: 0x0040, 0x1cbb: 0xb351,\n\t0x1cbc: 0x0040, 0x1cbd: 0x0040, 0x1cbe: 0x0040, 0x1cbf: 0x0040,\n\t// Block 0x73, offset 0x1cc0\n\t0x1cc0: 0x0040, 0x1cc1: 0x0040, 0x1cc2: 0xb201, 0x1cc3: 0x0040, 0x1cc4: 0x0040, 0x1cc5: 0x0040,\n\t0x1cc6: 0x0040, 0x1cc7: 0xb219, 0x1cc8: 0x0040, 0x1cc9: 0xb429, 0x1cca: 0x0040, 0x1ccb: 0xb3b1,\n\t0x1ccc: 0x0040, 0x1ccd: 0xb3e1, 0x1cce: 0xb2a9, 0x1ccf: 0xb339, 0x1cd0: 0x0040, 0x1cd1: 0xb2d9,\n\t0x1cd2: 0xb381, 0x1cd3: 0x0040, 0x1cd4: 0xb2c1, 0x1cd5: 0x0040, 0x1cd6: 0x0040, 0x1cd7: 0xb231,\n\t0x1cd8: 0x0040, 0x1cd9: 0xb2f1, 0x1cda: 0x0040, 0x1cdb: 0xb351, 0x1cdc: 0x0040, 0x1cdd: 0x7949,\n\t0x1cde: 0x0040, 0x1cdf: 0xbc89, 0x1ce0: 0x0040, 0x1ce1: 0xb1a1, 0x1ce2: 0xb201, 0x1ce3: 0x0040,\n\t0x1ce4: 0xb3f9, 0x1ce5: 0x0040, 0x1ce6: 0x0040, 0x1ce7: 0xb219, 0x1ce8: 0xb309, 0x1ce9: 0xb429,\n\t0x1cea: 0xb399, 0x1ceb: 0x0040, 0x1cec: 0xb3c9, 0x1ced: 0xb3e1, 0x1cee: 0xb2a9, 0x1cef: 0xb339,\n\t0x1cf0: 0xb369, 0x1cf1: 0xb2d9, 0x1cf2: 0xb381, 0x1cf3: 0x0040, 0x1cf4: 0xb2c1, 0x1cf5: 0xb1d1,\n\t0x1cf6: 0xb1e9, 0x1cf7: 0xb231, 0x1cf8: 0x0040, 0x1cf9: 0xb2f1, 0x1cfa: 0xb321, 0x1cfb: 0xb351,\n\t0x1cfc: 0xbc59, 0x1cfd: 0x0040, 0x1cfe: 0xbc71, 0x1cff: 0x0040,\n\t// Block 0x74, offset 0x1d00\n\t0x1d00: 0xb189, 0x1d01: 0xb1a1, 0x1d02: 0xb201, 0x1d03: 0xb249, 0x1d04: 0xb3f9, 0x1d05: 0xb411,\n\t0x1d06: 0xb291, 0x1d07: 0xb219, 0x1d08: 0xb309, 0x1d09: 0xb429, 0x1d0a: 0x0040, 0x1d0b: 0xb3b1,\n\t0x1d0c: 0xb3c9, 0x1d0d: 0xb3e1, 0x1d0e: 0xb2a9, 0x1d0f: 0xb339, 0x1d10: 0xb369, 0x1d11: 0xb2d9,\n\t0x1d12: 0xb381, 0x1d13: 0xb279, 0x1d14: 0xb2c1, 0x1d15: 0xb1d1, 0x1d16: 0xb1e9, 0x1d17: 0xb231,\n\t0x1d18: 0xb261, 0x1d19: 0xb2f1, 0x1d1a: 0xb321, 0x1d1b: 0xb351, 0x1d1c: 0x0040, 0x1d1d: 0x0040,\n\t0x1d1e: 0x0040, 0x1d1f: 0x0040, 0x1d20: 0x0040, 0x1d21: 0xb1a1, 0x1d22: 0xb201, 0x1d23: 0xb249,\n\t0x1d24: 0x0040, 0x1d25: 0xb411, 0x1d26: 0xb291, 0x1d27: 0xb219, 0x1d28: 0xb309, 0x1d29: 0xb429,\n\t0x1d2a: 0x0040, 0x1d2b: 0xb3b1, 0x1d2c: 0xb3c9, 0x1d2d: 0xb3e1, 0x1d2e: 0xb2a9, 0x1d2f: 0xb339,\n\t0x1d30: 0xb369, 0x1d31: 0xb2d9, 0x1d32: 0xb381, 0x1d33: 0xb279, 0x1d34: 0xb2c1, 0x1d35: 0xb1d1,\n\t0x1d36: 0xb1e9, 0x1d37: 0xb231, 0x1d38: 0xb261, 0x1d39: 0xb2f1, 0x1d3a: 0xb321, 0x1d3b: 0xb351,\n\t0x1d3c: 0x0040, 0x1d3d: 0x0040, 0x1d3e: 0x0040, 0x1d3f: 0x0040,\n\t// Block 0x75, offset 0x1d40\n\t0x1d40: 0x0040, 0x1d41: 0xbca2, 0x1d42: 0xbcba, 0x1d43: 0xbcd2, 0x1d44: 0xbcea, 0x1d45: 0xbd02,\n\t0x1d46: 0xbd1a, 0x1d47: 0xbd32, 0x1d48: 0xbd4a, 0x1d49: 0xbd62, 0x1d4a: 0xbd7a, 0x1d4b: 0x0018,\n\t0x1d4c: 0x0018, 0x1d4d: 0x0040, 0x1d4e: 0x0040, 0x1d4f: 0x0040, 0x1d50: 0xbd92, 0x1d51: 0xbdb2,\n\t0x1d52: 0xbdd2, 0x1d53: 0xbdf2, 0x1d54: 0xbe12, 0x1d55: 0xbe32, 0x1d56: 0xbe52, 0x1d57: 0xbe72,\n\t0x1d58: 0xbe92, 0x1d59: 0xbeb2, 0x1d5a: 0xbed2, 0x1d5b: 0xbef2, 0x1d5c: 0xbf12, 0x1d5d: 0xbf32,\n\t0x1d5e: 0xbf52, 0x1d5f: 0xbf72, 0x1d60: 0xbf92, 0x1d61: 0xbfb2, 0x1d62: 0xbfd2, 0x1d63: 0xbff2,\n\t0x1d64: 0xc012, 0x1d65: 0xc032, 0x1d66: 0xc052, 0x1d67: 0xc072, 0x1d68: 0xc092, 0x1d69: 0xc0b2,\n\t0x1d6a: 0xc0d1, 0x1d6b: 0x1159, 0x1d6c: 0x0269, 0x1d6d: 0x6671, 0x1d6e: 0xc111, 0x1d6f: 0x0018,\n\t0x1d70: 0x0039, 0x1d71: 0x0ee9, 0x1d72: 0x1159, 0x1d73: 0x0ef9, 0x1d74: 0x0f09, 0x1d75: 0x1199,\n\t0x1d76: 0x0f31, 0x1d77: 0x0249, 0x1d78: 0x0f41, 0x1d79: 0x0259, 0x1d7a: 0x0f51, 0x1d7b: 0x0359,\n\t0x1d7c: 0x0f61, 0x1d7d: 0x0f71, 0x1d7e: 0x00d9, 0x1d7f: 0x0f99,\n\t// Block 0x76, offset 0x1d80\n\t0x1d80: 0x2039, 0x1d81: 0x0269, 0x1d82: 0x01d9, 0x1d83: 0x0fa9, 0x1d84: 0x0fb9, 0x1d85: 0x1089,\n\t0x1d86: 0x0279, 0x1d87: 0x0369, 0x1d88: 0x0289, 0x1d89: 0x13d1, 0x1d8a: 0xc129, 0x1d8b: 0x65b1,\n\t0x1d8c: 0xc141, 0x1d8d: 0x1441, 0x1d8e: 0xc159, 0x1d8f: 0xc179, 0x1d90: 0x0018, 0x1d91: 0x0018,\n\t0x1d92: 0x0018, 0x1d93: 0x0018, 0x1d94: 0x0018, 0x1d95: 0x0018, 0x1d96: 0x0018, 0x1d97: 0x0018,\n\t0x1d98: 0x0018, 0x1d99: 0x0018, 0x1d9a: 0x0018, 0x1d9b: 0x0018, 0x1d9c: 0x0018, 0x1d9d: 0x0018,\n\t0x1d9e: 0x0018, 0x1d9f: 0x0018, 0x1da0: 0x0018, 0x1da1: 0x0018, 0x1da2: 0x0018, 0x1da3: 0x0018,\n\t0x1da4: 0x0018, 0x1da5: 0x0018, 0x1da6: 0x0018, 0x1da7: 0x0018, 0x1da8: 0x0018, 0x1da9: 0x0018,\n\t0x1daa: 0xc191, 0x1dab: 0xc1a9, 0x1dac: 0xc1c1, 0x1dad: 0x0040, 0x1dae: 0x0040, 0x1daf: 0x0040,\n\t0x1db0: 0x0018, 0x1db1: 0x0018, 0x1db2: 0x0018, 0x1db3: 0x0018, 0x1db4: 0x0018, 0x1db5: 0x0018,\n\t0x1db6: 0x0018, 0x1db7: 0x0018, 0x1db8: 0x0018, 0x1db9: 0x0018, 0x1dba: 0x0018, 0x1dbb: 0x0018,\n\t0x1dbc: 0x0018, 0x1dbd: 0x0018, 0x1dbe: 0x0018, 0x1dbf: 0x0018,\n\t// Block 0x77, offset 0x1dc0\n\t0x1dc0: 0xc1f1, 0x1dc1: 0xc229, 0x1dc2: 0xc261, 0x1dc3: 0x0040, 0x1dc4: 0x0040, 0x1dc5: 0x0040,\n\t0x1dc6: 0x0040, 0x1dc7: 0x0040, 0x1dc8: 0x0040, 0x1dc9: 0x0040, 0x1dca: 0x0040, 0x1dcb: 0x0040,\n\t0x1dcc: 0x0040, 0x1dcd: 0x0040, 0x1dce: 0x0040, 0x1dcf: 0x0040, 0x1dd0: 0xc281, 0x1dd1: 0xc2a1,\n\t0x1dd2: 0xc2c1, 0x1dd3: 0xc2e1, 0x1dd4: 0xc301, 0x1dd5: 0xc321, 0x1dd6: 0xc341, 0x1dd7: 0xc361,\n\t0x1dd8: 0xc381, 0x1dd9: 0xc3a1, 0x1dda: 0xc3c1, 0x1ddb: 0xc3e1, 0x1ddc: 0xc401, 0x1ddd: 0xc421,\n\t0x1dde: 0xc441, 0x1ddf: 0xc461, 0x1de0: 0xc481, 0x1de1: 0xc4a1, 0x1de2: 0xc4c1, 0x1de3: 0xc4e1,\n\t0x1de4: 0xc501, 0x1de5: 0xc521, 0x1de6: 0xc541, 0x1de7: 0xc561, 0x1de8: 0xc581, 0x1de9: 0xc5a1,\n\t0x1dea: 0xc5c1, 0x1deb: 0xc5e1, 0x1dec: 0xc601, 0x1ded: 0xc621, 0x1dee: 0xc641, 0x1def: 0xc661,\n\t0x1df0: 0xc681, 0x1df1: 0xc6a1, 0x1df2: 0xc6c1, 0x1df3: 0xc6e1, 0x1df4: 0xc701, 0x1df5: 0xc721,\n\t0x1df6: 0xc741, 0x1df7: 0xc761, 0x1df8: 0xc781, 0x1df9: 0xc7a1, 0x1dfa: 0xc7c1, 0x1dfb: 0xc7e1,\n\t0x1dfc: 0x0040, 0x1dfd: 0x0040, 0x1dfe: 0x0040, 0x1dff: 0x0040,\n\t// Block 0x78, offset 0x1e00\n\t0x1e00: 0xcb11, 0x1e01: 0xcb31, 0x1e02: 0xcb51, 0x1e03: 0x8b55, 0x1e04: 0xcb71, 0x1e05: 0xcb91,\n\t0x1e06: 0xcbb1, 0x1e07: 0xcbd1, 0x1e08: 0xcbf1, 0x1e09: 0xcc11, 0x1e0a: 0xcc31, 0x1e0b: 0xcc51,\n\t0x1e0c: 0xcc71, 0x1e0d: 0x8b75, 0x1e0e: 0xcc91, 0x1e0f: 0xccb1, 0x1e10: 0xccd1, 0x1e11: 0xccf1,\n\t0x1e12: 0x8b95, 0x1e13: 0xcd11, 0x1e14: 0xcd31, 0x1e15: 0xc441, 0x1e16: 0x8bb5, 0x1e17: 0xcd51,\n\t0x1e18: 0xcd71, 0x1e19: 0xcd91, 0x1e1a: 0xcdb1, 0x1e1b: 0xcdd1, 0x1e1c: 0x8bd5, 0x1e1d: 0xcdf1,\n\t0x1e1e: 0xce11, 0x1e1f: 0xce31, 0x1e20: 0xce51, 0x1e21: 0xce71, 0x1e22: 0xc7a1, 0x1e23: 0xce91,\n\t0x1e24: 0xceb1, 0x1e25: 0xced1, 0x1e26: 0xcef1, 0x1e27: 0xcf11, 0x1e28: 0xcf31, 0x1e29: 0xcf51,\n\t0x1e2a: 0xcf71, 0x1e2b: 0xcf91, 0x1e2c: 0xcfb1, 0x1e2d: 0xcfd1, 0x1e2e: 0xcff1, 0x1e2f: 0xd011,\n\t0x1e30: 0xd031, 0x1e31: 0xd051, 0x1e32: 0xd051, 0x1e33: 0xd051, 0x1e34: 0x8bf5, 0x1e35: 0xd071,\n\t0x1e36: 0xd091, 0x1e37: 0xd0b1, 0x1e38: 0x8c15, 0x1e39: 0xd0d1, 0x1e3a: 0xd0f1, 0x1e3b: 0xd111,\n\t0x1e3c: 0xd131, 0x1e3d: 0xd151, 0x1e3e: 0xd171, 0x1e3f: 0xd191,\n\t// Block 0x79, offset 0x1e40\n\t0x1e40: 0xd1b1, 0x1e41: 0xd1d1, 0x1e42: 0xd1f1, 0x1e43: 0xd211, 0x1e44: 0xd231, 0x1e45: 0xd251,\n\t0x1e46: 0xd251, 0x1e47: 0xd271, 0x1e48: 0xd291, 0x1e49: 0xd2b1, 0x1e4a: 0xd2d1, 0x1e4b: 0xd2f1,\n\t0x1e4c: 0xd311, 0x1e4d: 0xd331, 0x1e4e: 0xd351, 0x1e4f: 0xd371, 0x1e50: 0xd391, 0x1e51: 0xd3b1,\n\t0x1e52: 0xd3d1, 0x1e53: 0xd3f1, 0x1e54: 0xd411, 0x1e55: 0xd431, 0x1e56: 0xd451, 0x1e57: 0xd471,\n\t0x1e58: 0xd491, 0x1e59: 0x8c35, 0x1e5a: 0xd4b1, 0x1e5b: 0xd4d1, 0x1e5c: 0xd4f1, 0x1e5d: 0xc321,\n\t0x1e5e: 0xd511, 0x1e5f: 0xd531, 0x1e60: 0x8c55, 0x1e61: 0x8c75, 0x1e62: 0xd551, 0x1e63: 0xd571,\n\t0x1e64: 0xd591, 0x1e65: 0xd5b1, 0x1e66: 0xd5d1, 0x1e67: 0xd5f1, 0x1e68: 0x2040, 0x1e69: 0xd611,\n\t0x1e6a: 0xd631, 0x1e6b: 0xd631, 0x1e6c: 0x8c95, 0x1e6d: 0xd651, 0x1e6e: 0xd671, 0x1e6f: 0xd691,\n\t0x1e70: 0xd6b1, 0x1e71: 0x8cb5, 0x1e72: 0xd6d1, 0x1e73: 0xd6f1, 0x1e74: 0x2040, 0x1e75: 0xd711,\n\t0x1e76: 0xd731, 0x1e77: 0xd751, 0x1e78: 0xd771, 0x1e79: 0xd791, 0x1e7a: 0xd7b1, 0x1e7b: 0x8cd5,\n\t0x1e7c: 0xd7d1, 0x1e7d: 0x8cf5, 0x1e7e: 0xd7f1, 0x1e7f: 0xd811,\n\t// Block 0x7a, offset 0x1e80\n\t0x1e80: 0xd831, 0x1e81: 0xd851, 0x1e82: 0xd871, 0x1e83: 0xd891, 0x1e84: 0xd8b1, 0x1e85: 0xd8d1,\n\t0x1e86: 0xd8f1, 0x1e87: 0xd911, 0x1e88: 0xd931, 0x1e89: 0x8d15, 0x1e8a: 0xd951, 0x1e8b: 0xd971,\n\t0x1e8c: 0xd991, 0x1e8d: 0xd9b1, 0x1e8e: 0xd9d1, 0x1e8f: 0x8d35, 0x1e90: 0xd9f1, 0x1e91: 0x8d55,\n\t0x1e92: 0x8d75, 0x1e93: 0xda11, 0x1e94: 0xda31, 0x1e95: 0xda31, 0x1e96: 0xda51, 0x1e97: 0x8d95,\n\t0x1e98: 0x8db5, 0x1e99: 0xda71, 0x1e9a: 0xda91, 0x1e9b: 0xdab1, 0x1e9c: 0xdad1, 0x1e9d: 0xdaf1,\n\t0x1e9e: 0xdb11, 0x1e9f: 0xdb31, 0x1ea0: 0xdb51, 0x1ea1: 0xdb71, 0x1ea2: 0xdb91, 0x1ea3: 0xdbb1,\n\t0x1ea4: 0x8dd5, 0x1ea5: 0xdbd1, 0x1ea6: 0xdbf1, 0x1ea7: 0xdc11, 0x1ea8: 0xdc31, 0x1ea9: 0xdc11,\n\t0x1eaa: 0xdc51, 0x1eab: 0xdc71, 0x1eac: 0xdc91, 0x1ead: 0xdcb1, 0x1eae: 0xdcd1, 0x1eaf: 0xdcf1,\n\t0x1eb0: 0xdd11, 0x1eb1: 0xdd31, 0x1eb2: 0xdd51, 0x1eb3: 0xdd71, 0x1eb4: 0xdd91, 0x1eb5: 0xddb1,\n\t0x1eb6: 0xddd1, 0x1eb7: 0xddf1, 0x1eb8: 0x8df5, 0x1eb9: 0xde11, 0x1eba: 0xde31, 0x1ebb: 0xde51,\n\t0x1ebc: 0xde71, 0x1ebd: 0xde91, 0x1ebe: 0x8e15, 0x1ebf: 0xdeb1,\n\t// Block 0x7b, offset 0x1ec0\n\t0x1ec0: 0xe5b1, 0x1ec1: 0xe5d1, 0x1ec2: 0xe5f1, 0x1ec3: 0xe611, 0x1ec4: 0xe631, 0x1ec5: 0xe651,\n\t0x1ec6: 0x8f35, 0x1ec7: 0xe671, 0x1ec8: 0xe691, 0x1ec9: 0xe6b1, 0x1eca: 0xe6d1, 0x1ecb: 0xe6f1,\n\t0x1ecc: 0xe711, 0x1ecd: 0x8f55, 0x1ece: 0xe731, 0x1ecf: 0xe751, 0x1ed0: 0x8f75, 0x1ed1: 0x8f95,\n\t0x1ed2: 0xe771, 0x1ed3: 0xe791, 0x1ed4: 0xe7b1, 0x1ed5: 0xe7d1, 0x1ed6: 0xe7f1, 0x1ed7: 0xe811,\n\t0x1ed8: 0xe831, 0x1ed9: 0xe851, 0x1eda: 0xe871, 0x1edb: 0x8fb5, 0x1edc: 0xe891, 0x1edd: 0x8fd5,\n\t0x1ede: 0xe8b1, 0x1edf: 0x2040, 0x1ee0: 0xe8d1, 0x1ee1: 0xe8f1, 0x1ee2: 0xe911, 0x1ee3: 0x8ff5,\n\t0x1ee4: 0xe931, 0x1ee5: 0xe951, 0x1ee6: 0x9015, 0x1ee7: 0x9035, 0x1ee8: 0xe971, 0x1ee9: 0xe991,\n\t0x1eea: 0xe9b1, 0x1eeb: 0xe9d1, 0x1eec: 0xe9f1, 0x1eed: 0xe9f1, 0x1eee: 0xea11, 0x1eef: 0xea31,\n\t0x1ef0: 0xea51, 0x1ef1: 0xea71, 0x1ef2: 0xea91, 0x1ef3: 0xeab1, 0x1ef4: 0xead1, 0x1ef5: 0x9055,\n\t0x1ef6: 0xeaf1, 0x1ef7: 0x9075, 0x1ef8: 0xeb11, 0x1ef9: 0x9095, 0x1efa: 0xeb31, 0x1efb: 0x90b5,\n\t0x1efc: 0x90d5, 0x1efd: 0x90f5, 0x1efe: 0xeb51, 0x1eff: 0xeb71,\n\t// Block 0x7c, offset 0x1f00\n\t0x1f00: 0xeb91, 0x1f01: 0x9115, 0x1f02: 0x9135, 0x1f03: 0x9155, 0x1f04: 0x9175, 0x1f05: 0xebb1,\n\t0x1f06: 0xebd1, 0x1f07: 0xebd1, 0x1f08: 0xebf1, 0x1f09: 0xec11, 0x1f0a: 0xec31, 0x1f0b: 0xec51,\n\t0x1f0c: 0xec71, 0x1f0d: 0x9195, 0x1f0e: 0xec91, 0x1f0f: 0xecb1, 0x1f10: 0xecd1, 0x1f11: 0xecf1,\n\t0x1f12: 0x91b5, 0x1f13: 0xed11, 0x1f14: 0x91d5, 0x1f15: 0x91f5, 0x1f16: 0xed31, 0x1f17: 0xed51,\n\t0x1f18: 0xed71, 0x1f19: 0xed91, 0x1f1a: 0xedb1, 0x1f1b: 0xedd1, 0x1f1c: 0x9215, 0x1f1d: 0x9235,\n\t0x1f1e: 0x9255, 0x1f1f: 0x2040, 0x1f20: 0xedf1, 0x1f21: 0x9275, 0x1f22: 0xee11, 0x1f23: 0xee31,\n\t0x1f24: 0xee51, 0x1f25: 0x9295, 0x1f26: 0xee71, 0x1f27: 0xee91, 0x1f28: 0xeeb1, 0x1f29: 0xeed1,\n\t0x1f2a: 0xeef1, 0x1f2b: 0x92b5, 0x1f2c: 0xef11, 0x1f2d: 0xef31, 0x1f2e: 0xef51, 0x1f2f: 0xef71,\n\t0x1f30: 0xef91, 0x1f31: 0xefb1, 0x1f32: 0x92d5, 0x1f33: 0x92f5, 0x1f34: 0xefd1, 0x1f35: 0x9315,\n\t0x1f36: 0xeff1, 0x1f37: 0x9335, 0x1f38: 0xf011, 0x1f39: 0xf031, 0x1f3a: 0xf051, 0x1f3b: 0x9355,\n\t0x1f3c: 0x9375, 0x1f3d: 0xf071, 0x1f3e: 0x9395, 0x1f3f: 0xf091,\n\t// Block 0x7d, offset 0x1f40\n\t0x1f40: 0xf6d1, 0x1f41: 0xf6f1, 0x1f42: 0xf711, 0x1f43: 0xf731, 0x1f44: 0xf751, 0x1f45: 0x9555,\n\t0x1f46: 0xf771, 0x1f47: 0xf791, 0x1f48: 0xf7b1, 0x1f49: 0xf7d1, 0x1f4a: 0xf7f1, 0x1f4b: 0x9575,\n\t0x1f4c: 0x9595, 0x1f4d: 0xf811, 0x1f4e: 0xf831, 0x1f4f: 0xf851, 0x1f50: 0xf871, 0x1f51: 0xf891,\n\t0x1f52: 0xf8b1, 0x1f53: 0x95b5, 0x1f54: 0xf8d1, 0x1f55: 0xf8f1, 0x1f56: 0xf911, 0x1f57: 0xf931,\n\t0x1f58: 0x95d5, 0x1f59: 0x95f5, 0x1f5a: 0xf951, 0x1f5b: 0xf971, 0x1f5c: 0xf991, 0x1f5d: 0x9615,\n\t0x1f5e: 0xf9b1, 0x1f5f: 0xf9d1, 0x1f60: 0x684d, 0x1f61: 0x9635, 0x1f62: 0xf9f1, 0x1f63: 0xfa11,\n\t0x1f64: 0xfa31, 0x1f65: 0x9655, 0x1f66: 0xfa51, 0x1f67: 0xfa71, 0x1f68: 0xfa91, 0x1f69: 0xfab1,\n\t0x1f6a: 0xfad1, 0x1f6b: 0xfaf1, 0x1f6c: 0xfb11, 0x1f6d: 0x9675, 0x1f6e: 0xfb31, 0x1f6f: 0xfb51,\n\t0x1f70: 0xfb71, 0x1f71: 0x9695, 0x1f72: 0xfb91, 0x1f73: 0xfbb1, 0x1f74: 0xfbd1, 0x1f75: 0xfbf1,\n\t0x1f76: 0x7b6d, 0x1f77: 0x96b5, 0x1f78: 0xfc11, 0x1f79: 0xfc31, 0x1f7a: 0xfc51, 0x1f7b: 0x96d5,\n\t0x1f7c: 0xfc71, 0x1f7d: 0x96f5, 0x1f7e: 0xfc91, 0x1f7f: 0xfc91,\n\t// Block 0x7e, offset 0x1f80\n\t0x1f80: 0xfcb1, 0x1f81: 0x9715, 0x1f82: 0xfcd1, 0x1f83: 0xfcf1, 0x1f84: 0xfd11, 0x1f85: 0xfd31,\n\t0x1f86: 0xfd51, 0x1f87: 0xfd71, 0x1f88: 0xfd91, 0x1f89: 0x9735, 0x1f8a: 0xfdb1, 0x1f8b: 0xfdd1,\n\t0x1f8c: 0xfdf1, 0x1f8d: 0xfe11, 0x1f8e: 0xfe31, 0x1f8f: 0xfe51, 0x1f90: 0x9755, 0x1f91: 0xfe71,\n\t0x1f92: 0x9775, 0x1f93: 0x9795, 0x1f94: 0x97b5, 0x1f95: 0xfe91, 0x1f96: 0xfeb1, 0x1f97: 0xfed1,\n\t0x1f98: 0xfef1, 0x1f99: 0xff11, 0x1f9a: 0xff31, 0x1f9b: 0xff51, 0x1f9c: 0xff71, 0x1f9d: 0x97d5,\n\t0x1f9e: 0x0040, 0x1f9f: 0x0040, 0x1fa0: 0x0040, 0x1fa1: 0x0040, 0x1fa2: 0x0040, 0x1fa3: 0x0040,\n\t0x1fa4: 0x0040, 0x1fa5: 0x0040, 0x1fa6: 0x0040, 0x1fa7: 0x0040, 0x1fa8: 0x0040, 0x1fa9: 0x0040,\n\t0x1faa: 0x0040, 0x1fab: 0x0040, 0x1fac: 0x0040, 0x1fad: 0x0040, 0x1fae: 0x0040, 0x1faf: 0x0040,\n\t0x1fb0: 0x0040, 0x1fb1: 0x0040, 0x1fb2: 0x0040, 0x1fb3: 0x0040, 0x1fb4: 0x0040, 0x1fb5: 0x0040,\n\t0x1fb6: 0x0040, 0x1fb7: 0x0040, 0x1fb8: 0x0040, 0x1fb9: 0x0040, 0x1fba: 0x0040, 0x1fbb: 0x0040,\n\t0x1fbc: 0x0040, 0x1fbd: 0x0040, 0x1fbe: 0x0040, 0x1fbf: 0x0040,\n}\n\n// idnaIndex: 36 blocks, 2304 entries, 4608 bytes\n// Block 0 is the zero block.\nvar idnaIndex = [2304]uint16{\n\t// Block 0x0, offset 0x0\n\t// Block 0x1, offset 0x40\n\t// Block 0x2, offset 0x80\n\t// Block 0x3, offset 0xc0\n\t0xc2: 0x01, 0xc3: 0x7d, 0xc4: 0x02, 0xc5: 0x03, 0xc6: 0x04, 0xc7: 0x05,\n\t0xc8: 0x06, 0xc9: 0x7e, 0xca: 0x7f, 0xcb: 0x07, 0xcc: 0x80, 0xcd: 0x08, 0xce: 0x09, 0xcf: 0x0a,\n\t0xd0: 0x81, 0xd1: 0x0b, 0xd2: 0x0c, 0xd3: 0x0d, 0xd4: 0x0e, 0xd5: 0x82, 0xd6: 0x83, 0xd7: 0x84,\n\t0xd8: 0x0f, 0xd9: 0x10, 0xda: 0x85, 0xdb: 0x11, 0xdc: 0x12, 0xdd: 0x86, 0xde: 0x87, 0xdf: 0x88,\n\t0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07,\n\t0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x07, 0xec: 0x07, 0xed: 0x0a, 0xee: 0x0b, 0xef: 0x0c,\n\t0xf0: 0x1d, 0xf1: 0x1e, 0xf2: 0x1e, 0xf3: 0x20, 0xf4: 0x21,\n\t// Block 0x4, offset 0x100\n\t0x120: 0x89, 0x121: 0x13, 0x122: 0x8a, 0x123: 0x8b, 0x124: 0x8c, 0x125: 0x14, 0x126: 0x15, 0x127: 0x16,\n\t0x128: 0x17, 0x129: 0x18, 0x12a: 0x19, 0x12b: 0x1a, 0x12c: 0x1b, 0x12d: 0x1c, 0x12e: 0x1d, 0x12f: 0x8d,\n\t0x130: 0x8e, 0x131: 0x1e, 0x132: 0x1f, 0x133: 0x20, 0x134: 0x8f, 0x135: 0x21, 0x136: 0x90, 0x137: 0x91,\n\t0x138: 0x92, 0x139: 0x93, 0x13a: 0x22, 0x13b: 0x94, 0x13c: 0x95, 0x13d: 0x23, 0x13e: 0x24, 0x13f: 0x96,\n\t// Block 0x5, offset 0x140\n\t0x140: 0x97, 0x141: 0x98, 0x142: 0x99, 0x143: 0x9a, 0x144: 0x9b, 0x145: 0x9c, 0x146: 0x9d, 0x147: 0x9e,\n\t0x148: 0x9f, 0x149: 0xa0, 0x14a: 0xa1, 0x14b: 0xa2, 0x14c: 0xa3, 0x14d: 0xa4, 0x14e: 0xa5, 0x14f: 0xa6,\n\t0x150: 0xa7, 0x151: 0x9f, 0x152: 0x9f, 0x153: 0x9f, 0x154: 0x9f, 0x155: 0x9f, 0x156: 0x9f, 0x157: 0x9f,\n\t0x158: 0x9f, 0x159: 0xa8, 0x15a: 0xa9, 0x15b: 0xaa, 0x15c: 0xab, 0x15d: 0xac, 0x15e: 0xad, 0x15f: 0xae,\n\t0x160: 0xaf, 0x161: 0xb0, 0x162: 0xb1, 0x163: 0xb2, 0x164: 0xb3, 0x165: 0xb4, 0x166: 0xb5, 0x167: 0xb6,\n\t0x168: 0xb7, 0x169: 0xb8, 0x16a: 0xb9, 0x16b: 0xba, 0x16c: 0xbb, 0x16d: 0xbc, 0x16e: 0xbd, 0x16f: 0xbe,\n\t0x170: 0xbf, 0x171: 0xc0, 0x172: 0xc1, 0x173: 0xc2, 0x174: 0x25, 0x175: 0x26, 0x176: 0x27, 0x177: 0xc3,\n\t0x178: 0x28, 0x179: 0x28, 0x17a: 0x29, 0x17b: 0x28, 0x17c: 0xc4, 0x17d: 0x2a, 0x17e: 0x2b, 0x17f: 0x2c,\n\t// Block 0x6, offset 0x180\n\t0x180: 0x2d, 0x181: 0x2e, 0x182: 0x2f, 0x183: 0xc5, 0x184: 0x30, 0x185: 0x31, 0x186: 0xc6, 0x187: 0x9b,\n\t0x188: 0xc7, 0x189: 0xc8, 0x18a: 0x9b, 0x18b: 0x9b, 0x18c: 0xc9, 0x18d: 0x9b, 0x18e: 0x9b, 0x18f: 0x9b,\n\t0x190: 0xca, 0x191: 0x32, 0x192: 0x33, 0x193: 0x34, 0x194: 0x9b, 0x195: 0x9b, 0x196: 0x9b, 0x197: 0x9b,\n\t0x198: 0x9b, 0x199: 0x9b, 0x19a: 0x9b, 0x19b: 0x9b, 0x19c: 0x9b, 0x19d: 0x9b, 0x19e: 0x9b, 0x19f: 0x9b,\n\t0x1a0: 0x9b, 0x1a1: 0x9b, 0x1a2: 0x9b, 0x1a3: 0x9b, 0x1a4: 0x9b, 0x1a5: 0x9b, 0x1a6: 0x9b, 0x1a7: 0x9b,\n\t0x1a8: 0xcb, 0x1a9: 0xcc, 0x1aa: 0x9b, 0x1ab: 0xcd, 0x1ac: 0x9b, 0x1ad: 0xce, 0x1ae: 0xcf, 0x1af: 0x9b,\n\t0x1b0: 0xd0, 0x1b1: 0x35, 0x1b2: 0x28, 0x1b3: 0x36, 0x1b4: 0xd1, 0x1b5: 0xd2, 0x1b6: 0xd3, 0x1b7: 0xd4,\n\t0x1b8: 0xd5, 0x1b9: 0xd6, 0x1ba: 0xd7, 0x1bb: 0xd8, 0x1bc: 0xd9, 0x1bd: 0xda, 0x1be: 0xdb, 0x1bf: 0x37,\n\t// Block 0x7, offset 0x1c0\n\t0x1c0: 0x38, 0x1c1: 0xdc, 0x1c2: 0xdd, 0x1c3: 0xde, 0x1c4: 0xdf, 0x1c5: 0x39, 0x1c6: 0x3a, 0x1c7: 0xe0,\n\t0x1c8: 0xe1, 0x1c9: 0x3b, 0x1ca: 0x3c, 0x1cb: 0x3d, 0x1cc: 0x3e, 0x1cd: 0x3f, 0x1ce: 0x40, 0x1cf: 0x41,\n\t0x1d0: 0x9f, 0x1d1: 0x9f, 0x1d2: 0x9f, 0x1d3: 0x9f, 0x1d4: 0x9f, 0x1d5: 0x9f, 0x1d6: 0x9f, 0x1d7: 0x9f,\n\t0x1d8: 0x9f, 0x1d9: 0x9f, 0x1da: 0x9f, 0x1db: 0x9f, 0x1dc: 0x9f, 0x1dd: 0x9f, 0x1de: 0x9f, 0x1df: 0x9f,\n\t0x1e0: 0x9f, 0x1e1: 0x9f, 0x1e2: 0x9f, 0x1e3: 0x9f, 0x1e4: 0x9f, 0x1e5: 0x9f, 0x1e6: 0x9f, 0x1e7: 0x9f,\n\t0x1e8: 0x9f, 0x1e9: 0x9f, 0x1ea: 0x9f, 0x1eb: 0x9f, 0x1ec: 0x9f, 0x1ed: 0x9f, 0x1ee: 0x9f, 0x1ef: 0x9f,\n\t0x1f0: 0x9f, 0x1f1: 0x9f, 0x1f2: 0x9f, 0x1f3: 0x9f, 0x1f4: 0x9f, 0x1f5: 0x9f, 0x1f6: 0x9f, 0x1f7: 0x9f,\n\t0x1f8: 0x9f, 0x1f9: 0x9f, 0x1fa: 0x9f, 0x1fb: 0x9f, 0x1fc: 0x9f, 0x1fd: 0x9f, 0x1fe: 0x9f, 0x1ff: 0x9f,\n\t// Block 0x8, offset 0x200\n\t0x200: 0x9f, 0x201: 0x9f, 0x202: 0x9f, 0x203: 0x9f, 0x204: 0x9f, 0x205: 0x9f, 0x206: 0x9f, 0x207: 0x9f,\n\t0x208: 0x9f, 0x209: 0x9f, 0x20a: 0x9f, 0x20b: 0x9f, 0x20c: 0x9f, 0x20d: 0x9f, 0x20e: 0x9f, 0x20f: 0x9f,\n\t0x210: 0x9f, 0x211: 0x9f, 0x212: 0x9f, 0x213: 0x9f, 0x214: 0x9f, 0x215: 0x9f, 0x216: 0x9f, 0x217: 0x9f,\n\t0x218: 0x9f, 0x219: 0x9f, 0x21a: 0x9f, 0x21b: 0x9f, 0x21c: 0x9f, 0x21d: 0x9f, 0x21e: 0x9f, 0x21f: 0x9f,\n\t0x220: 0x9f, 0x221: 0x9f, 0x222: 0x9f, 0x223: 0x9f, 0x224: 0x9f, 0x225: 0x9f, 0x226: 0x9f, 0x227: 0x9f,\n\t0x228: 0x9f, 0x229: 0x9f, 0x22a: 0x9f, 0x22b: 0x9f, 0x22c: 0x9f, 0x22d: 0x9f, 0x22e: 0x9f, 0x22f: 0x9f,\n\t0x230: 0x9f, 0x231: 0x9f, 0x232: 0x9f, 0x233: 0x9f, 0x234: 0x9f, 0x235: 0x9f, 0x236: 0xb2, 0x237: 0x9b,\n\t0x238: 0x9f, 0x239: 0x9f, 0x23a: 0x9f, 0x23b: 0x9f, 0x23c: 0x9f, 0x23d: 0x9f, 0x23e: 0x9f, 0x23f: 0x9f,\n\t// Block 0x9, offset 0x240\n\t0x240: 0x9f, 0x241: 0x9f, 0x242: 0x9f, 0x243: 0x9f, 0x244: 0x9f, 0x245: 0x9f, 0x246: 0x9f, 0x247: 0x9f,\n\t0x248: 0x9f, 0x249: 0x9f, 0x24a: 0x9f, 0x24b: 0x9f, 0x24c: 0x9f, 0x24d: 0x9f, 0x24e: 0x9f, 0x24f: 0x9f,\n\t0x250: 0x9f, 0x251: 0x9f, 0x252: 0x9f, 0x253: 0x9f, 0x254: 0x9f, 0x255: 0x9f, 0x256: 0x9f, 0x257: 0x9f,\n\t0x258: 0x9f, 0x259: 0x9f, 0x25a: 0x9f, 0x25b: 0x9f, 0x25c: 0x9f, 0x25d: 0x9f, 0x25e: 0x9f, 0x25f: 0x9f,\n\t0x260: 0x9f, 0x261: 0x9f, 0x262: 0x9f, 0x263: 0x9f, 0x264: 0x9f, 0x265: 0x9f, 0x266: 0x9f, 0x267: 0x9f,\n\t0x268: 0x9f, 0x269: 0x9f, 0x26a: 0x9f, 0x26b: 0x9f, 0x26c: 0x9f, 0x26d: 0x9f, 0x26e: 0x9f, 0x26f: 0x9f,\n\t0x270: 0x9f, 0x271: 0x9f, 0x272: 0x9f, 0x273: 0x9f, 0x274: 0x9f, 0x275: 0x9f, 0x276: 0x9f, 0x277: 0x9f,\n\t0x278: 0x9f, 0x279: 0x9f, 0x27a: 0x9f, 0x27b: 0x9f, 0x27c: 0x9f, 0x27d: 0x9f, 0x27e: 0x9f, 0x27f: 0x9f,\n\t// Block 0xa, offset 0x280\n\t0x280: 0x9f, 0x281: 0x9f, 0x282: 0x9f, 0x283: 0x9f, 0x284: 0x9f, 0x285: 0x9f, 0x286: 0x9f, 0x287: 0x9f,\n\t0x288: 0x9f, 0x289: 0x9f, 0x28a: 0x9f, 0x28b: 0x9f, 0x28c: 0x9f, 0x28d: 0x9f, 0x28e: 0x9f, 0x28f: 0x9f,\n\t0x290: 0x9f, 0x291: 0x9f, 0x292: 0x9f, 0x293: 0x9f, 0x294: 0x9f, 0x295: 0x9f, 0x296: 0x9f, 0x297: 0x9f,\n\t0x298: 0x9f, 0x299: 0x9f, 0x29a: 0x9f, 0x29b: 0x9f, 0x29c: 0x9f, 0x29d: 0x9f, 0x29e: 0x9f, 0x29f: 0x9f,\n\t0x2a0: 0x9f, 0x2a1: 0x9f, 0x2a2: 0x9f, 0x2a3: 0x9f, 0x2a4: 0x9f, 0x2a5: 0x9f, 0x2a6: 0x9f, 0x2a7: 0x9f,\n\t0x2a8: 0x9f, 0x2a9: 0x9f, 0x2aa: 0x9f, 0x2ab: 0x9f, 0x2ac: 0x9f, 0x2ad: 0x9f, 0x2ae: 0x9f, 0x2af: 0x9f,\n\t0x2b0: 0x9f, 0x2b1: 0x9f, 0x2b2: 0x9f, 0x2b3: 0x9f, 0x2b4: 0x9f, 0x2b5: 0x9f, 0x2b6: 0x9f, 0x2b7: 0x9f,\n\t0x2b8: 0x9f, 0x2b9: 0x9f, 0x2ba: 0x9f, 0x2bb: 0x9f, 0x2bc: 0x9f, 0x2bd: 0x9f, 0x2be: 0x9f, 0x2bf: 0xe2,\n\t// Block 0xb, offset 0x2c0\n\t0x2c0: 0x9f, 0x2c1: 0x9f, 0x2c2: 0x9f, 0x2c3: 0x9f, 0x2c4: 0x9f, 0x2c5: 0x9f, 0x2c6: 0x9f, 0x2c7: 0x9f,\n\t0x2c8: 0x9f, 0x2c9: 0x9f, 0x2ca: 0x9f, 0x2cb: 0x9f, 0x2cc: 0x9f, 0x2cd: 0x9f, 0x2ce: 0x9f, 0x2cf: 0x9f,\n\t0x2d0: 0x9f, 0x2d1: 0x9f, 0x2d2: 0xe3, 0x2d3: 0xe4, 0x2d4: 0x9f, 0x2d5: 0x9f, 0x2d6: 0x9f, 0x2d7: 0x9f,\n\t0x2d8: 0xe5, 0x2d9: 0x42, 0x2da: 0x43, 0x2db: 0xe6, 0x2dc: 0x44, 0x2dd: 0x45, 0x2de: 0x46, 0x2df: 0xe7,\n\t0x2e0: 0xe8, 0x2e1: 0xe9, 0x2e2: 0xea, 0x2e3: 0xeb, 0x2e4: 0xec, 0x2e5: 0xed, 0x2e6: 0xee, 0x2e7: 0xef,\n\t0x2e8: 0xf0, 0x2e9: 0xf1, 0x2ea: 0xf2, 0x2eb: 0xf3, 0x2ec: 0xf4, 0x2ed: 0xf5, 0x2ee: 0xf6, 0x2ef: 0xf7,\n\t0x2f0: 0x9f, 0x2f1: 0x9f, 0x2f2: 0x9f, 0x2f3: 0x9f, 0x2f4: 0x9f, 0x2f5: 0x9f, 0x2f6: 0x9f, 0x2f7: 0x9f,\n\t0x2f8: 0x9f, 0x2f9: 0x9f, 0x2fa: 0x9f, 0x2fb: 0x9f, 0x2fc: 0x9f, 0x2fd: 0x9f, 0x2fe: 0x9f, 0x2ff: 0x9f,\n\t// Block 0xc, offset 0x300\n\t0x300: 0x9f, 0x301: 0x9f, 0x302: 0x9f, 0x303: 0x9f, 0x304: 0x9f, 0x305: 0x9f, 0x306: 0x9f, 0x307: 0x9f,\n\t0x308: 0x9f, 0x309: 0x9f, 0x30a: 0x9f, 0x30b: 0x9f, 0x30c: 0x9f, 0x30d: 0x9f, 0x30e: 0x9f, 0x30f: 0x9f,\n\t0x310: 0x9f, 0x311: 0x9f, 0x312: 0x9f, 0x313: 0x9f, 0x314: 0x9f, 0x315: 0x9f, 0x316: 0x9f, 0x317: 0x9f,\n\t0x318: 0x9f, 0x319: 0x9f, 0x31a: 0x9f, 0x31b: 0x9f, 0x31c: 0x9f, 0x31d: 0x9f, 0x31e: 0xf8, 0x31f: 0xf9,\n\t// Block 0xd, offset 0x340\n\t0x340: 0xba, 0x341: 0xba, 0x342: 0xba, 0x343: 0xba, 0x344: 0xba, 0x345: 0xba, 0x346: 0xba, 0x347: 0xba,\n\t0x348: 0xba, 0x349: 0xba, 0x34a: 0xba, 0x34b: 0xba, 0x34c: 0xba, 0x34d: 0xba, 0x34e: 0xba, 0x34f: 0xba,\n\t0x350: 0xba, 0x351: 0xba, 0x352: 0xba, 0x353: 0xba, 0x354: 0xba, 0x355: 0xba, 0x356: 0xba, 0x357: 0xba,\n\t0x358: 0xba, 0x359: 0xba, 0x35a: 0xba, 0x35b: 0xba, 0x35c: 0xba, 0x35d: 0xba, 0x35e: 0xba, 0x35f: 0xba,\n\t0x360: 0xba, 0x361: 0xba, 0x362: 0xba, 0x363: 0xba, 0x364: 0xba, 0x365: 0xba, 0x366: 0xba, 0x367: 0xba,\n\t0x368: 0xba, 0x369: 0xba, 0x36a: 0xba, 0x36b: 0xba, 0x36c: 0xba, 0x36d: 0xba, 0x36e: 0xba, 0x36f: 0xba,\n\t0x370: 0xba, 0x371: 0xba, 0x372: 0xba, 0x373: 0xba, 0x374: 0xba, 0x375: 0xba, 0x376: 0xba, 0x377: 0xba,\n\t0x378: 0xba, 0x379: 0xba, 0x37a: 0xba, 0x37b: 0xba, 0x37c: 0xba, 0x37d: 0xba, 0x37e: 0xba, 0x37f: 0xba,\n\t// Block 0xe, offset 0x380\n\t0x380: 0xba, 0x381: 0xba, 0x382: 0xba, 0x383: 0xba, 0x384: 0xba, 0x385: 0xba, 0x386: 0xba, 0x387: 0xba,\n\t0x388: 0xba, 0x389: 0xba, 0x38a: 0xba, 0x38b: 0xba, 0x38c: 0xba, 0x38d: 0xba, 0x38e: 0xba, 0x38f: 0xba,\n\t0x390: 0xba, 0x391: 0xba, 0x392: 0xba, 0x393: 0xba, 0x394: 0xba, 0x395: 0xba, 0x396: 0xba, 0x397: 0xba,\n\t0x398: 0xba, 0x399: 0xba, 0x39a: 0xba, 0x39b: 0xba, 0x39c: 0xba, 0x39d: 0xba, 0x39e: 0xba, 0x39f: 0xba,\n\t0x3a0: 0xba, 0x3a1: 0xba, 0x3a2: 0xba, 0x3a3: 0xba, 0x3a4: 0xfa, 0x3a5: 0xfb, 0x3a6: 0xfc, 0x3a7: 0xfd,\n\t0x3a8: 0x47, 0x3a9: 0xfe, 0x3aa: 0xff, 0x3ab: 0x48, 0x3ac: 0x49, 0x3ad: 0x4a, 0x3ae: 0x4b, 0x3af: 0x4c,\n\t0x3b0: 0x100, 0x3b1: 0x4d, 0x3b2: 0x4e, 0x3b3: 0x4f, 0x3b4: 0x50, 0x3b5: 0x51, 0x3b6: 0x101, 0x3b7: 0x52,\n\t0x3b8: 0x53, 0x3b9: 0x54, 0x3ba: 0x55, 0x3bb: 0x56, 0x3bc: 0x57, 0x3bd: 0x58, 0x3be: 0x59, 0x3bf: 0x5a,\n\t// Block 0xf, offset 0x3c0\n\t0x3c0: 0x102, 0x3c1: 0x103, 0x3c2: 0x9f, 0x3c3: 0x104, 0x3c4: 0x105, 0x3c5: 0x9b, 0x3c6: 0x106, 0x3c7: 0x107,\n\t0x3c8: 0xba, 0x3c9: 0xba, 0x3ca: 0x108, 0x3cb: 0x109, 0x3cc: 0x10a, 0x3cd: 0x10b, 0x3ce: 0x10c, 0x3cf: 0x10d,\n\t0x3d0: 0x10e, 0x3d1: 0x9f, 0x3d2: 0x10f, 0x3d3: 0x110, 0x3d4: 0x111, 0x3d5: 0x112, 0x3d6: 0xba, 0x3d7: 0xba,\n\t0x3d8: 0x9f, 0x3d9: 0x9f, 0x3da: 0x9f, 0x3db: 0x9f, 0x3dc: 0x113, 0x3dd: 0x114, 0x3de: 0xba, 0x3df: 0xba,\n\t0x3e0: 0x115, 0x3e1: 0x116, 0x3e2: 0x117, 0x3e3: 0x118, 0x3e4: 0x119, 0x3e5: 0xba, 0x3e6: 0x11a, 0x3e7: 0x11b,\n\t0x3e8: 0x11c, 0x3e9: 0x11d, 0x3ea: 0x11e, 0x3eb: 0x5b, 0x3ec: 0x11f, 0x3ed: 0x120, 0x3ee: 0x5c, 0x3ef: 0xba,\n\t0x3f0: 0x121, 0x3f1: 0x122, 0x3f2: 0x123, 0x3f3: 0x124, 0x3f4: 0x125, 0x3f5: 0xba, 0x3f6: 0xba, 0x3f7: 0xba,\n\t0x3f8: 0xba, 0x3f9: 0x126, 0x3fa: 0xba, 0x3fb: 0xba, 0x3fc: 0x127, 0x3fd: 0x128, 0x3fe: 0xba, 0x3ff: 0x129,\n\t// Block 0x10, offset 0x400\n\t0x400: 0x12a, 0x401: 0x12b, 0x402: 0x12c, 0x403: 0x12d, 0x404: 0x12e, 0x405: 0x12f, 0x406: 0x130, 0x407: 0x131,\n\t0x408: 0x132, 0x409: 0xba, 0x40a: 0x133, 0x40b: 0x134, 0x40c: 0x5d, 0x40d: 0x5e, 0x40e: 0xba, 0x40f: 0xba,\n\t0x410: 0x135, 0x411: 0x136, 0x412: 0x137, 0x413: 0x138, 0x414: 0xba, 0x415: 0xba, 0x416: 0x139, 0x417: 0x13a,\n\t0x418: 0x13b, 0x419: 0x13c, 0x41a: 0x13d, 0x41b: 0x13e, 0x41c: 0x13f, 0x41d: 0xba, 0x41e: 0xba, 0x41f: 0xba,\n\t0x420: 0x140, 0x421: 0xba, 0x422: 0x141, 0x423: 0x142, 0x424: 0xba, 0x425: 0xba, 0x426: 0x143, 0x427: 0x144,\n\t0x428: 0x145, 0x429: 0x146, 0x42a: 0x147, 0x42b: 0x148, 0x42c: 0xba, 0x42d: 0xba, 0x42e: 0xba, 0x42f: 0xba,\n\t0x430: 0x149, 0x431: 0x14a, 0x432: 0x14b, 0x433: 0xba, 0x434: 0x14c, 0x435: 0x14d, 0x436: 0x14e, 0x437: 0xba,\n\t0x438: 0xba, 0x439: 0xba, 0x43a: 0xba, 0x43b: 0x14f, 0x43c: 0xba, 0x43d: 0xba, 0x43e: 0xba, 0x43f: 0x150,\n\t// Block 0x11, offset 0x440\n\t0x440: 0x9f, 0x441: 0x9f, 0x442: 0x9f, 0x443: 0x9f, 0x444: 0x9f, 0x445: 0x9f, 0x446: 0x9f, 0x447: 0x9f,\n\t0x448: 0x9f, 0x449: 0x9f, 0x44a: 0x9f, 0x44b: 0x9f, 0x44c: 0x9f, 0x44d: 0x9f, 0x44e: 0x151, 0x44f: 0xba,\n\t0x450: 0x9b, 0x451: 0x152, 0x452: 0x9f, 0x453: 0x9f, 0x454: 0x9f, 0x455: 0x153, 0x456: 0xba, 0x457: 0xba,\n\t0x458: 0xba, 0x459: 0xba, 0x45a: 0xba, 0x45b: 0xba, 0x45c: 0xba, 0x45d: 0xba, 0x45e: 0xba, 0x45f: 0xba,\n\t0x460: 0xba, 0x461: 0xba, 0x462: 0xba, 0x463: 0xba, 0x464: 0xba, 0x465: 0xba, 0x466: 0xba, 0x467: 0xba,\n\t0x468: 0xba, 0x469: 0xba, 0x46a: 0xba, 0x46b: 0xba, 0x46c: 0xba, 0x46d: 0xba, 0x46e: 0xba, 0x46f: 0xba,\n\t0x470: 0xba, 0x471: 0xba, 0x472: 0xba, 0x473: 0xba, 0x474: 0xba, 0x475: 0xba, 0x476: 0xba, 0x477: 0xba,\n\t0x478: 0xba, 0x479: 0xba, 0x47a: 0xba, 0x47b: 0xba, 0x47c: 0xba, 0x47d: 0xba, 0x47e: 0xba, 0x47f: 0xba,\n\t// Block 0x12, offset 0x480\n\t0x480: 0x9f, 0x481: 0x9f, 0x482: 0x9f, 0x483: 0x9f, 0x484: 0x9f, 0x485: 0x9f, 0x486: 0x9f, 0x487: 0x9f,\n\t0x488: 0x9f, 0x489: 0x9f, 0x48a: 0x9f, 0x48b: 0x9f, 0x48c: 0x9f, 0x48d: 0x9f, 0x48e: 0x9f, 0x48f: 0x9f,\n\t0x490: 0x154, 0x491: 0xba, 0x492: 0xba, 0x493: 0xba, 0x494: 0xba, 0x495: 0xba, 0x496: 0xba, 0x497: 0xba,\n\t0x498: 0xba, 0x499: 0xba, 0x49a: 0xba, 0x49b: 0xba, 0x49c: 0xba, 0x49d: 0xba, 0x49e: 0xba, 0x49f: 0xba,\n\t0x4a0: 0xba, 0x4a1: 0xba, 0x4a2: 0xba, 0x4a3: 0xba, 0x4a4: 0xba, 0x4a5: 0xba, 0x4a6: 0xba, 0x4a7: 0xba,\n\t0x4a8: 0xba, 0x4a9: 0xba, 0x4aa: 0xba, 0x4ab: 0xba, 0x4ac: 0xba, 0x4ad: 0xba, 0x4ae: 0xba, 0x4af: 0xba,\n\t0x4b0: 0xba, 0x4b1: 0xba, 0x4b2: 0xba, 0x4b3: 0xba, 0x4b4: 0xba, 0x4b5: 0xba, 0x4b6: 0xba, 0x4b7: 0xba,\n\t0x4b8: 0xba, 0x4b9: 0xba, 0x4ba: 0xba, 0x4bb: 0xba, 0x4bc: 0xba, 0x4bd: 0xba, 0x4be: 0xba, 0x4bf: 0xba,\n\t// Block 0x13, offset 0x4c0\n\t0x4c0: 0xba, 0x4c1: 0xba, 0x4c2: 0xba, 0x4c3: 0xba, 0x4c4: 0xba, 0x4c5: 0xba, 0x4c6: 0xba, 0x4c7: 0xba,\n\t0x4c8: 0xba, 0x4c9: 0xba, 0x4ca: 0xba, 0x4cb: 0xba, 0x4cc: 0xba, 0x4cd: 0xba, 0x4ce: 0xba, 0x4cf: 0xba,\n\t0x4d0: 0x9f, 0x4d1: 0x9f, 0x4d2: 0x9f, 0x4d3: 0x9f, 0x4d4: 0x9f, 0x4d5: 0x9f, 0x4d6: 0x9f, 0x4d7: 0x9f,\n\t0x4d8: 0x9f, 0x4d9: 0x155, 0x4da: 0xba, 0x4db: 0xba, 0x4dc: 0xba, 0x4dd: 0xba, 0x4de: 0xba, 0x4df: 0xba,\n\t0x4e0: 0xba, 0x4e1: 0xba, 0x4e2: 0xba, 0x4e3: 0xba, 0x4e4: 0xba, 0x4e5: 0xba, 0x4e6: 0xba, 0x4e7: 0xba,\n\t0x4e8: 0xba, 0x4e9: 0xba, 0x4ea: 0xba, 0x4eb: 0xba, 0x4ec: 0xba, 0x4ed: 0xba, 0x4ee: 0xba, 0x4ef: 0xba,\n\t0x4f0: 0xba, 0x4f1: 0xba, 0x4f2: 0xba, 0x4f3: 0xba, 0x4f4: 0xba, 0x4f5: 0xba, 0x4f6: 0xba, 0x4f7: 0xba,\n\t0x4f8: 0xba, 0x4f9: 0xba, 0x4fa: 0xba, 0x4fb: 0xba, 0x4fc: 0xba, 0x4fd: 0xba, 0x4fe: 0xba, 0x4ff: 0xba,\n\t// Block 0x14, offset 0x500\n\t0x500: 0xba, 0x501: 0xba, 0x502: 0xba, 0x503: 0xba, 0x504: 0xba, 0x505: 0xba, 0x506: 0xba, 0x507: 0xba,\n\t0x508: 0xba, 0x509: 0xba, 0x50a: 0xba, 0x50b: 0xba, 0x50c: 0xba, 0x50d: 0xba, 0x50e: 0xba, 0x50f: 0xba,\n\t0x510: 0xba, 0x511: 0xba, 0x512: 0xba, 0x513: 0xba, 0x514: 0xba, 0x515: 0xba, 0x516: 0xba, 0x517: 0xba,\n\t0x518: 0xba, 0x519: 0xba, 0x51a: 0xba, 0x51b: 0xba, 0x51c: 0xba, 0x51d: 0xba, 0x51e: 0xba, 0x51f: 0xba,\n\t0x520: 0x9f, 0x521: 0x9f, 0x522: 0x9f, 0x523: 0x9f, 0x524: 0x9f, 0x525: 0x9f, 0x526: 0x9f, 0x527: 0x9f,\n\t0x528: 0x148, 0x529: 0x156, 0x52a: 0xba, 0x52b: 0x157, 0x52c: 0x158, 0x52d: 0x159, 0x52e: 0x15a, 0x52f: 0xba,\n\t0x530: 0xba, 0x531: 0xba, 0x532: 0xba, 0x533: 0xba, 0x534: 0xba, 0x535: 0xba, 0x536: 0xba, 0x537: 0xba,\n\t0x538: 0xba, 0x539: 0x15b, 0x53a: 0x15c, 0x53b: 0xba, 0x53c: 0x9f, 0x53d: 0x15d, 0x53e: 0x15e, 0x53f: 0x15f,\n\t// Block 0x15, offset 0x540\n\t0x540: 0x9f, 0x541: 0x9f, 0x542: 0x9f, 0x543: 0x9f, 0x544: 0x9f, 0x545: 0x9f, 0x546: 0x9f, 0x547: 0x9f,\n\t0x548: 0x9f, 0x549: 0x9f, 0x54a: 0x9f, 0x54b: 0x9f, 0x54c: 0x9f, 0x54d: 0x9f, 0x54e: 0x9f, 0x54f: 0x9f,\n\t0x550: 0x9f, 0x551: 0x9f, 0x552: 0x9f, 0x553: 0x9f, 0x554: 0x9f, 0x555: 0x9f, 0x556: 0x9f, 0x557: 0x9f,\n\t0x558: 0x9f, 0x559: 0x9f, 0x55a: 0x9f, 0x55b: 0x9f, 0x55c: 0x9f, 0x55d: 0x9f, 0x55e: 0x9f, 0x55f: 0x160,\n\t0x560: 0x9f, 0x561: 0x9f, 0x562: 0x9f, 0x563: 0x9f, 0x564: 0x9f, 0x565: 0x9f, 0x566: 0x9f, 0x567: 0x9f,\n\t0x568: 0x9f, 0x569: 0x9f, 0x56a: 0x9f, 0x56b: 0x161, 0x56c: 0xba, 0x56d: 0xba, 0x56e: 0xba, 0x56f: 0xba,\n\t0x570: 0xba, 0x571: 0xba, 0x572: 0xba, 0x573: 0xba, 0x574: 0xba, 0x575: 0xba, 0x576: 0xba, 0x577: 0xba,\n\t0x578: 0xba, 0x579: 0xba, 0x57a: 0xba, 0x57b: 0xba, 0x57c: 0xba, 0x57d: 0xba, 0x57e: 0xba, 0x57f: 0xba,\n\t// Block 0x16, offset 0x580\n\t0x580: 0x9f, 0x581: 0x9f, 0x582: 0x9f, 0x583: 0x9f, 0x584: 0x162, 0x585: 0x163, 0x586: 0x9f, 0x587: 0x9f,\n\t0x588: 0x9f, 0x589: 0x9f, 0x58a: 0x9f, 0x58b: 0x164, 0x58c: 0xba, 0x58d: 0xba, 0x58e: 0xba, 0x58f: 0xba,\n\t0x590: 0xba, 0x591: 0xba, 0x592: 0xba, 0x593: 0xba, 0x594: 0xba, 0x595: 0xba, 0x596: 0xba, 0x597: 0xba,\n\t0x598: 0xba, 0x599: 0xba, 0x59a: 0xba, 0x59b: 0xba, 0x59c: 0xba, 0x59d: 0xba, 0x59e: 0xba, 0x59f: 0xba,\n\t0x5a0: 0xba, 0x5a1: 0xba, 0x5a2: 0xba, 0x5a3: 0xba, 0x5a4: 0xba, 0x5a5: 0xba, 0x5a6: 0xba, 0x5a7: 0xba,\n\t0x5a8: 0xba, 0x5a9: 0xba, 0x5aa: 0xba, 0x5ab: 0xba, 0x5ac: 0xba, 0x5ad: 0xba, 0x5ae: 0xba, 0x5af: 0xba,\n\t0x5b0: 0x9f, 0x5b1: 0x165, 0x5b2: 0x166, 0x5b3: 0xba, 0x5b4: 0xba, 0x5b5: 0xba, 0x5b6: 0xba, 0x5b7: 0xba,\n\t0x5b8: 0xba, 0x5b9: 0xba, 0x5ba: 0xba, 0x5bb: 0xba, 0x5bc: 0xba, 0x5bd: 0xba, 0x5be: 0xba, 0x5bf: 0xba,\n\t// Block 0x17, offset 0x5c0\n\t0x5c0: 0x9b, 0x5c1: 0x9b, 0x5c2: 0x9b, 0x5c3: 0x167, 0x5c4: 0x168, 0x5c5: 0x169, 0x5c6: 0x16a, 0x5c7: 0x16b,\n\t0x5c8: 0x9b, 0x5c9: 0x16c, 0x5ca: 0xba, 0x5cb: 0x16d, 0x5cc: 0x9b, 0x5cd: 0x16e, 0x5ce: 0xba, 0x5cf: 0xba,\n\t0x5d0: 0x5f, 0x5d1: 0x60, 0x5d2: 0x61, 0x5d3: 0x62, 0x5d4: 0x63, 0x5d5: 0x64, 0x5d6: 0x65, 0x5d7: 0x66,\n\t0x5d8: 0x67, 0x5d9: 0x68, 0x5da: 0x69, 0x5db: 0x6a, 0x5dc: 0x6b, 0x5dd: 0x6c, 0x5de: 0x6d, 0x5df: 0x6e,\n\t0x5e0: 0x9b, 0x5e1: 0x9b, 0x5e2: 0x9b, 0x5e3: 0x9b, 0x5e4: 0x9b, 0x5e5: 0x9b, 0x5e6: 0x9b, 0x5e7: 0x9b,\n\t0x5e8: 0x16f, 0x5e9: 0x170, 0x5ea: 0x171, 0x5eb: 0xba, 0x5ec: 0xba, 0x5ed: 0xba, 0x5ee: 0xba, 0x5ef: 0xba,\n\t0x5f0: 0xba, 0x5f1: 0xba, 0x5f2: 0xba, 0x5f3: 0xba, 0x5f4: 0xba, 0x5f5: 0xba, 0x5f6: 0xba, 0x5f7: 0xba,\n\t0x5f8: 0xba, 0x5f9: 0xba, 0x5fa: 0xba, 0x5fb: 0xba, 0x5fc: 0xba, 0x5fd: 0xba, 0x5fe: 0xba, 0x5ff: 0xba,\n\t// Block 0x18, offset 0x600\n\t0x600: 0x172, 0x601: 0xba, 0x602: 0xba, 0x603: 0xba, 0x604: 0x173, 0x605: 0x174, 0x606: 0xba, 0x607: 0xba,\n\t0x608: 0xba, 0x609: 0xba, 0x60a: 0xba, 0x60b: 0x175, 0x60c: 0xba, 0x60d: 0xba, 0x60e: 0xba, 0x60f: 0xba,\n\t0x610: 0xba, 0x611: 0xba, 0x612: 0xba, 0x613: 0xba, 0x614: 0xba, 0x615: 0xba, 0x616: 0xba, 0x617: 0xba,\n\t0x618: 0xba, 0x619: 0xba, 0x61a: 0xba, 0x61b: 0xba, 0x61c: 0xba, 0x61d: 0xba, 0x61e: 0xba, 0x61f: 0xba,\n\t0x620: 0x121, 0x621: 0x121, 0x622: 0x121, 0x623: 0x176, 0x624: 0x6f, 0x625: 0x177, 0x626: 0xba, 0x627: 0xba,\n\t0x628: 0xba, 0x629: 0xba, 0x62a: 0xba, 0x62b: 0xba, 0x62c: 0xba, 0x62d: 0xba, 0x62e: 0xba, 0x62f: 0xba,\n\t0x630: 0xba, 0x631: 0x178, 0x632: 0x179, 0x633: 0xba, 0x634: 0x17a, 0x635: 0xba, 0x636: 0xba, 0x637: 0xba,\n\t0x638: 0x70, 0x639: 0x71, 0x63a: 0x72, 0x63b: 0x17b, 0x63c: 0xba, 0x63d: 0xba, 0x63e: 0xba, 0x63f: 0xba,\n\t// Block 0x19, offset 0x640\n\t0x640: 0x17c, 0x641: 0x9b, 0x642: 0x17d, 0x643: 0x17e, 0x644: 0x73, 0x645: 0x74, 0x646: 0x17f, 0x647: 0x180,\n\t0x648: 0x75, 0x649: 0x181, 0x64a: 0xba, 0x64b: 0xba, 0x64c: 0x9b, 0x64d: 0x9b, 0x64e: 0x9b, 0x64f: 0x9b,\n\t0x650: 0x9b, 0x651: 0x9b, 0x652: 0x9b, 0x653: 0x9b, 0x654: 0x9b, 0x655: 0x9b, 0x656: 0x9b, 0x657: 0x9b,\n\t0x658: 0x9b, 0x659: 0x9b, 0x65a: 0x9b, 0x65b: 0x182, 0x65c: 0x9b, 0x65d: 0x183, 0x65e: 0x9b, 0x65f: 0x184,\n\t0x660: 0x185, 0x661: 0x186, 0x662: 0x187, 0x663: 0xba, 0x664: 0x188, 0x665: 0x189, 0x666: 0x18a, 0x667: 0x18b,\n\t0x668: 0x9b, 0x669: 0x18c, 0x66a: 0x18d, 0x66b: 0xba, 0x66c: 0xba, 0x66d: 0xba, 0x66e: 0xba, 0x66f: 0xba,\n\t0x670: 0xba, 0x671: 0xba, 0x672: 0xba, 0x673: 0xba, 0x674: 0xba, 0x675: 0xba, 0x676: 0xba, 0x677: 0xba,\n\t0x678: 0xba, 0x679: 0xba, 0x67a: 0xba, 0x67b: 0xba, 0x67c: 0xba, 0x67d: 0xba, 0x67e: 0xba, 0x67f: 0xba,\n\t// Block 0x1a, offset 0x680\n\t0x680: 0x9f, 0x681: 0x9f, 0x682: 0x9f, 0x683: 0x9f, 0x684: 0x9f, 0x685: 0x9f, 0x686: 0x9f, 0x687: 0x9f,\n\t0x688: 0x9f, 0x689: 0x9f, 0x68a: 0x9f, 0x68b: 0x9f, 0x68c: 0x9f, 0x68d: 0x9f, 0x68e: 0x9f, 0x68f: 0x9f,\n\t0x690: 0x9f, 0x691: 0x9f, 0x692: 0x9f, 0x693: 0x9f, 0x694: 0x9f, 0x695: 0x9f, 0x696: 0x9f, 0x697: 0x9f,\n\t0x698: 0x9f, 0x699: 0x9f, 0x69a: 0x9f, 0x69b: 0x18e, 0x69c: 0x9f, 0x69d: 0x9f, 0x69e: 0x9f, 0x69f: 0x9f,\n\t0x6a0: 0x9f, 0x6a1: 0x9f, 0x6a2: 0x9f, 0x6a3: 0x9f, 0x6a4: 0x9f, 0x6a5: 0x9f, 0x6a6: 0x9f, 0x6a7: 0x9f,\n\t0x6a8: 0x9f, 0x6a9: 0x9f, 0x6aa: 0x9f, 0x6ab: 0x9f, 0x6ac: 0x9f, 0x6ad: 0x9f, 0x6ae: 0x9f, 0x6af: 0x9f,\n\t0x6b0: 0x9f, 0x6b1: 0x9f, 0x6b2: 0x9f, 0x6b3: 0x9f, 0x6b4: 0x9f, 0x6b5: 0x9f, 0x6b6: 0x9f, 0x6b7: 0x9f,\n\t0x6b8: 0x9f, 0x6b9: 0x9f, 0x6ba: 0x9f, 0x6bb: 0x9f, 0x6bc: 0x9f, 0x6bd: 0x9f, 0x6be: 0x9f, 0x6bf: 0x9f,\n\t// Block 0x1b, offset 0x6c0\n\t0x6c0: 0x9f, 0x6c1: 0x9f, 0x6c2: 0x9f, 0x6c3: 0x9f, 0x6c4: 0x9f, 0x6c5: 0x9f, 0x6c6: 0x9f, 0x6c7: 0x9f,\n\t0x6c8: 0x9f, 0x6c9: 0x9f, 0x6ca: 0x9f, 0x6cb: 0x9f, 0x6cc: 0x9f, 0x6cd: 0x9f, 0x6ce: 0x9f, 0x6cf: 0x9f,\n\t0x6d0: 0x9f, 0x6d1: 0x9f, 0x6d2: 0x9f, 0x6d3: 0x9f, 0x6d4: 0x9f, 0x6d5: 0x9f, 0x6d6: 0x9f, 0x6d7: 0x9f,\n\t0x6d8: 0x9f, 0x6d9: 0x9f, 0x6da: 0x9f, 0x6db: 0x9f, 0x6dc: 0x18f, 0x6dd: 0x9f, 0x6de: 0x9f, 0x6df: 0x9f,\n\t0x6e0: 0x190, 0x6e1: 0x9f, 0x6e2: 0x9f, 0x6e3: 0x9f, 0x6e4: 0x9f, 0x6e5: 0x9f, 0x6e6: 0x9f, 0x6e7: 0x9f,\n\t0x6e8: 0x9f, 0x6e9: 0x9f, 0x6ea: 0x9f, 0x6eb: 0x9f, 0x6ec: 0x9f, 0x6ed: 0x9f, 0x6ee: 0x9f, 0x6ef: 0x9f,\n\t0x6f0: 0x9f, 0x6f1: 0x9f, 0x6f2: 0x9f, 0x6f3: 0x9f, 0x6f4: 0x9f, 0x6f5: 0x9f, 0x6f6: 0x9f, 0x6f7: 0x9f,\n\t0x6f8: 0x9f, 0x6f9: 0x9f, 0x6fa: 0x9f, 0x6fb: 0x9f, 0x6fc: 0x9f, 0x6fd: 0x9f, 0x6fe: 0x9f, 0x6ff: 0x9f,\n\t// Block 0x1c, offset 0x700\n\t0x700: 0x9f, 0x701: 0x9f, 0x702: 0x9f, 0x703: 0x9f, 0x704: 0x9f, 0x705: 0x9f, 0x706: 0x9f, 0x707: 0x9f,\n\t0x708: 0x9f, 0x709: 0x9f, 0x70a: 0x9f, 0x70b: 0x9f, 0x70c: 0x9f, 0x70d: 0x9f, 0x70e: 0x9f, 0x70f: 0x9f,\n\t0x710: 0x9f, 0x711: 0x9f, 0x712: 0x9f, 0x713: 0x9f, 0x714: 0x9f, 0x715: 0x9f, 0x716: 0x9f, 0x717: 0x9f,\n\t0x718: 0x9f, 0x719: 0x9f, 0x71a: 0x9f, 0x71b: 0x9f, 0x71c: 0x9f, 0x71d: 0x9f, 0x71e: 0x9f, 0x71f: 0x9f,\n\t0x720: 0x9f, 0x721: 0x9f, 0x722: 0x9f, 0x723: 0x9f, 0x724: 0x9f, 0x725: 0x9f, 0x726: 0x9f, 0x727: 0x9f,\n\t0x728: 0x9f, 0x729: 0x9f, 0x72a: 0x9f, 0x72b: 0x9f, 0x72c: 0x9f, 0x72d: 0x9f, 0x72e: 0x9f, 0x72f: 0x9f,\n\t0x730: 0x9f, 0x731: 0x9f, 0x732: 0x9f, 0x733: 0x9f, 0x734: 0x9f, 0x735: 0x9f, 0x736: 0x9f, 0x737: 0x9f,\n\t0x738: 0x9f, 0x739: 0x9f, 0x73a: 0x191, 0x73b: 0x9f, 0x73c: 0x9f, 0x73d: 0x9f, 0x73e: 0x9f, 0x73f: 0x9f,\n\t// Block 0x1d, offset 0x740\n\t0x740: 0x9f, 0x741: 0x9f, 0x742: 0x9f, 0x743: 0x9f, 0x744: 0x9f, 0x745: 0x9f, 0x746: 0x9f, 0x747: 0x9f,\n\t0x748: 0x9f, 0x749: 0x9f, 0x74a: 0x9f, 0x74b: 0x9f, 0x74c: 0x9f, 0x74d: 0x9f, 0x74e: 0x9f, 0x74f: 0x9f,\n\t0x750: 0x9f, 0x751: 0x9f, 0x752: 0x9f, 0x753: 0x9f, 0x754: 0x9f, 0x755: 0x9f, 0x756: 0x9f, 0x757: 0x9f,\n\t0x758: 0x9f, 0x759: 0x9f, 0x75a: 0x9f, 0x75b: 0x9f, 0x75c: 0x9f, 0x75d: 0x9f, 0x75e: 0x9f, 0x75f: 0x9f,\n\t0x760: 0x9f, 0x761: 0x9f, 0x762: 0x9f, 0x763: 0x9f, 0x764: 0x9f, 0x765: 0x9f, 0x766: 0x9f, 0x767: 0x9f,\n\t0x768: 0x9f, 0x769: 0x9f, 0x76a: 0x9f, 0x76b: 0x9f, 0x76c: 0x9f, 0x76d: 0x9f, 0x76e: 0x9f, 0x76f: 0x192,\n\t0x770: 0xba, 0x771: 0xba, 0x772: 0xba, 0x773: 0xba, 0x774: 0xba, 0x775: 0xba, 0x776: 0xba, 0x777: 0xba,\n\t0x778: 0xba, 0x779: 0xba, 0x77a: 0xba, 0x77b: 0xba, 0x77c: 0xba, 0x77d: 0xba, 0x77e: 0xba, 0x77f: 0xba,\n\t// Block 0x1e, offset 0x780\n\t0x780: 0xba, 0x781: 0xba, 0x782: 0xba, 0x783: 0xba, 0x784: 0xba, 0x785: 0xba, 0x786: 0xba, 0x787: 0xba,\n\t0x788: 0xba, 0x789: 0xba, 0x78a: 0xba, 0x78b: 0xba, 0x78c: 0xba, 0x78d: 0xba, 0x78e: 0xba, 0x78f: 0xba,\n\t0x790: 0xba, 0x791: 0xba, 0x792: 0xba, 0x793: 0xba, 0x794: 0xba, 0x795: 0xba, 0x796: 0xba, 0x797: 0xba,\n\t0x798: 0xba, 0x799: 0xba, 0x79a: 0xba, 0x79b: 0xba, 0x79c: 0xba, 0x79d: 0xba, 0x79e: 0xba, 0x79f: 0xba,\n\t0x7a0: 0x76, 0x7a1: 0x77, 0x7a2: 0x78, 0x7a3: 0x193, 0x7a4: 0x79, 0x7a5: 0x7a, 0x7a6: 0x194, 0x7a7: 0x7b,\n\t0x7a8: 0x7c, 0x7a9: 0xba, 0x7aa: 0xba, 0x7ab: 0xba, 0x7ac: 0xba, 0x7ad: 0xba, 0x7ae: 0xba, 0x7af: 0xba,\n\t0x7b0: 0xba, 0x7b1: 0xba, 0x7b2: 0xba, 0x7b3: 0xba, 0x7b4: 0xba, 0x7b5: 0xba, 0x7b6: 0xba, 0x7b7: 0xba,\n\t0x7b8: 0xba, 0x7b9: 0xba, 0x7ba: 0xba, 0x7bb: 0xba, 0x7bc: 0xba, 0x7bd: 0xba, 0x7be: 0xba, 0x7bf: 0xba,\n\t// Block 0x1f, offset 0x7c0\n\t0x7d0: 0x0d, 0x7d1: 0x0e, 0x7d2: 0x0f, 0x7d3: 0x10, 0x7d4: 0x11, 0x7d5: 0x0b, 0x7d6: 0x12, 0x7d7: 0x07,\n\t0x7d8: 0x13, 0x7d9: 0x0b, 0x7da: 0x0b, 0x7db: 0x14, 0x7dc: 0x0b, 0x7dd: 0x15, 0x7de: 0x16, 0x7df: 0x17,\n\t0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07,\n\t0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x18, 0x7eb: 0x19, 0x7ec: 0x1a, 0x7ed: 0x07, 0x7ee: 0x1b, 0x7ef: 0x1c,\n\t0x7f0: 0x0b, 0x7f1: 0x0b, 0x7f2: 0x0b, 0x7f3: 0x0b, 0x7f4: 0x0b, 0x7f5: 0x0b, 0x7f6: 0x0b, 0x7f7: 0x0b,\n\t0x7f8: 0x0b, 0x7f9: 0x0b, 0x7fa: 0x0b, 0x7fb: 0x0b, 0x7fc: 0x0b, 0x7fd: 0x0b, 0x7fe: 0x0b, 0x7ff: 0x0b,\n\t// Block 0x20, offset 0x800\n\t0x800: 0x0b, 0x801: 0x0b, 0x802: 0x0b, 0x803: 0x0b, 0x804: 0x0b, 0x805: 0x0b, 0x806: 0x0b, 0x807: 0x0b,\n\t0x808: 0x0b, 0x809: 0x0b, 0x80a: 0x0b, 0x80b: 0x0b, 0x80c: 0x0b, 0x80d: 0x0b, 0x80e: 0x0b, 0x80f: 0x0b,\n\t0x810: 0x0b, 0x811: 0x0b, 0x812: 0x0b, 0x813: 0x0b, 0x814: 0x0b, 0x815: 0x0b, 0x816: 0x0b, 0x817: 0x0b,\n\t0x818: 0x0b, 0x819: 0x0b, 0x81a: 0x0b, 0x81b: 0x0b, 0x81c: 0x0b, 0x81d: 0x0b, 0x81e: 0x0b, 0x81f: 0x0b,\n\t0x820: 0x0b, 0x821: 0x0b, 0x822: 0x0b, 0x823: 0x0b, 0x824: 0x0b, 0x825: 0x0b, 0x826: 0x0b, 0x827: 0x0b,\n\t0x828: 0x0b, 0x829: 0x0b, 0x82a: 0x0b, 0x82b: 0x0b, 0x82c: 0x0b, 0x82d: 0x0b, 0x82e: 0x0b, 0x82f: 0x0b,\n\t0x830: 0x0b, 0x831: 0x0b, 0x832: 0x0b, 0x833: 0x0b, 0x834: 0x0b, 0x835: 0x0b, 0x836: 0x0b, 0x837: 0x0b,\n\t0x838: 0x0b, 0x839: 0x0b, 0x83a: 0x0b, 0x83b: 0x0b, 0x83c: 0x0b, 0x83d: 0x0b, 0x83e: 0x0b, 0x83f: 0x0b,\n\t// Block 0x21, offset 0x840\n\t0x840: 0x195, 0x841: 0x196, 0x842: 0xba, 0x843: 0xba, 0x844: 0x197, 0x845: 0x197, 0x846: 0x197, 0x847: 0x198,\n\t0x848: 0xba, 0x849: 0xba, 0x84a: 0xba, 0x84b: 0xba, 0x84c: 0xba, 0x84d: 0xba, 0x84e: 0xba, 0x84f: 0xba,\n\t0x850: 0xba, 0x851: 0xba, 0x852: 0xba, 0x853: 0xba, 0x854: 0xba, 0x855: 0xba, 0x856: 0xba, 0x857: 0xba,\n\t0x858: 0xba, 0x859: 0xba, 0x85a: 0xba, 0x85b: 0xba, 0x85c: 0xba, 0x85d: 0xba, 0x85e: 0xba, 0x85f: 0xba,\n\t0x860: 0xba, 0x861: 0xba, 0x862: 0xba, 0x863: 0xba, 0x864: 0xba, 0x865: 0xba, 0x866: 0xba, 0x867: 0xba,\n\t0x868: 0xba, 0x869: 0xba, 0x86a: 0xba, 0x86b: 0xba, 0x86c: 0xba, 0x86d: 0xba, 0x86e: 0xba, 0x86f: 0xba,\n\t0x870: 0xba, 0x871: 0xba, 0x872: 0xba, 0x873: 0xba, 0x874: 0xba, 0x875: 0xba, 0x876: 0xba, 0x877: 0xba,\n\t0x878: 0xba, 0x879: 0xba, 0x87a: 0xba, 0x87b: 0xba, 0x87c: 0xba, 0x87d: 0xba, 0x87e: 0xba, 0x87f: 0xba,\n\t// Block 0x22, offset 0x880\n\t0x880: 0x0b, 0x881: 0x0b, 0x882: 0x0b, 0x883: 0x0b, 0x884: 0x0b, 0x885: 0x0b, 0x886: 0x0b, 0x887: 0x0b,\n\t0x888: 0x0b, 0x889: 0x0b, 0x88a: 0x0b, 0x88b: 0x0b, 0x88c: 0x0b, 0x88d: 0x0b, 0x88e: 0x0b, 0x88f: 0x0b,\n\t0x890: 0x0b, 0x891: 0x0b, 0x892: 0x0b, 0x893: 0x0b, 0x894: 0x0b, 0x895: 0x0b, 0x896: 0x0b, 0x897: 0x0b,\n\t0x898: 0x0b, 0x899: 0x0b, 0x89a: 0x0b, 0x89b: 0x0b, 0x89c: 0x0b, 0x89d: 0x0b, 0x89e: 0x0b, 0x89f: 0x0b,\n\t0x8a0: 0x1f, 0x8a1: 0x0b, 0x8a2: 0x0b, 0x8a3: 0x0b, 0x8a4: 0x0b, 0x8a5: 0x0b, 0x8a6: 0x0b, 0x8a7: 0x0b,\n\t0x8a8: 0x0b, 0x8a9: 0x0b, 0x8aa: 0x0b, 0x8ab: 0x0b, 0x8ac: 0x0b, 0x8ad: 0x0b, 0x8ae: 0x0b, 0x8af: 0x0b,\n\t0x8b0: 0x0b, 0x8b1: 0x0b, 0x8b2: 0x0b, 0x8b3: 0x0b, 0x8b4: 0x0b, 0x8b5: 0x0b, 0x8b6: 0x0b, 0x8b7: 0x0b,\n\t0x8b8: 0x0b, 0x8b9: 0x0b, 0x8ba: 0x0b, 0x8bb: 0x0b, 0x8bc: 0x0b, 0x8bd: 0x0b, 0x8be: 0x0b, 0x8bf: 0x0b,\n\t// Block 0x23, offset 0x8c0\n\t0x8c0: 0x0b, 0x8c1: 0x0b, 0x8c2: 0x0b, 0x8c3: 0x0b, 0x8c4: 0x0b, 0x8c5: 0x0b, 0x8c6: 0x0b, 0x8c7: 0x0b,\n\t0x8c8: 0x0b, 0x8c9: 0x0b, 0x8ca: 0x0b, 0x8cb: 0x0b, 0x8cc: 0x0b, 0x8cd: 0x0b, 0x8ce: 0x0b, 0x8cf: 0x0b,\n}\n\n// idnaSparseOffset: 284 entries, 568 bytes\nvar idnaSparseOffset = []uint16{0x0, 0x8, 0x19, 0x25, 0x27, 0x2c, 0x33, 0x3e, 0x4a, 0x4e, 0x5d, 0x62, 0x6c, 0x78, 0x86, 0x8b, 0x94, 0xa4, 0xb2, 0xbe, 0xca, 0xdb, 0xe5, 0xec, 0xf9, 0x10a, 0x111, 0x11c, 0x12b, 0x139, 0x143, 0x145, 0x14a, 0x14d, 0x150, 0x152, 0x15e, 0x169, 0x171, 0x177, 0x17d, 0x182, 0x187, 0x18a, 0x18e, 0x194, 0x199, 0x1a5, 0x1af, 0x1b5, 0x1c6, 0x1d0, 0x1d3, 0x1db, 0x1de, 0x1eb, 0x1f3, 0x1f7, 0x1fe, 0x206, 0x216, 0x222, 0x224, 0x22e, 0x23a, 0x246, 0x252, 0x25a, 0x25f, 0x26c, 0x27d, 0x281, 0x28c, 0x290, 0x299, 0x2a1, 0x2a7, 0x2ac, 0x2af, 0x2b3, 0x2b9, 0x2bd, 0x2c1, 0x2c5, 0x2cb, 0x2d3, 0x2da, 0x2e5, 0x2ef, 0x2f3, 0x2f6, 0x2fc, 0x300, 0x302, 0x305, 0x307, 0x30a, 0x314, 0x317, 0x326, 0x32a, 0x32f, 0x332, 0x336, 0x33b, 0x340, 0x346, 0x352, 0x361, 0x367, 0x36b, 0x37a, 0x37f, 0x387, 0x391, 0x39c, 0x3a4, 0x3b5, 0x3be, 0x3ce, 0x3db, 0x3e5, 0x3ea, 0x3f7, 0x3fb, 0x400, 0x402, 0x406, 0x408, 0x40c, 0x415, 0x41b, 0x41f, 0x42f, 0x439, 0x43e, 0x441, 0x447, 0x44e, 0x453, 0x457, 0x45d, 0x462, 0x46b, 0x470, 0x476, 0x47d, 0x484, 0x48b, 0x48f, 0x494, 0x497, 0x49c, 0x4a8, 0x4ae, 0x4b3, 0x4ba, 0x4c2, 0x4c7, 0x4cb, 0x4db, 0x4e2, 0x4e6, 0x4ea, 0x4f1, 0x4f3, 0x4f6, 0x4f9, 0x4fd, 0x506, 0x50a, 0x512, 0x51a, 0x51e, 0x524, 0x52d, 0x539, 0x540, 0x549, 0x553, 0x55a, 0x568, 0x575, 0x582, 0x58b, 0x58f, 0x59f, 0x5a7, 0x5b2, 0x5bb, 0x5c1, 0x5c9, 0x5d2, 0x5dd, 0x5e0, 0x5ec, 0x5f5, 0x5f8, 0x5fd, 0x602, 0x60f, 0x61a, 0x623, 0x62d, 0x630, 0x63a, 0x643, 0x64f, 0x65c, 0x669, 0x677, 0x67e, 0x682, 0x685, 0x68a, 0x68d, 0x692, 0x695, 0x69c, 0x6a3, 0x6a7, 0x6b2, 0x6b5, 0x6b8, 0x6bb, 0x6c1, 0x6c7, 0x6cd, 0x6d0, 0x6d3, 0x6d6, 0x6dd, 0x6e0, 0x6e5, 0x6ef, 0x6f2, 0x6f6, 0x705, 0x711, 0x715, 0x71a, 0x71e, 0x723, 0x727, 0x72c, 0x735, 0x740, 0x746, 0x74c, 0x752, 0x758, 0x761, 0x764, 0x767, 0x76b, 0x76f, 0x773, 0x779, 0x77f, 0x784, 0x787, 0x797, 0x79e, 0x7a1, 0x7a6, 0x7aa, 0x7b0, 0x7b5, 0x7b9, 0x7bf, 0x7c5, 0x7c9, 0x7d2, 0x7d7, 0x7da, 0x7dd, 0x7e1, 0x7e5, 0x7e8, 0x7f8, 0x809, 0x80e, 0x810, 0x812}\n\n// idnaSparseValues: 2069 entries, 8276 bytes\nvar idnaSparseValues = [2069]valueRange{\n\t// Block 0x0, offset 0x0\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0xe105, lo: 0x80, hi: 0x96},\n\t{value: 0x0018, lo: 0x97, hi: 0x97},\n\t{value: 0xe105, lo: 0x98, hi: 0x9e},\n\t{value: 0x001f, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbf},\n\t// Block 0x1, offset 0x8\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0xe01d, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0335, lo: 0x83, hi: 0x83},\n\t{value: 0x034d, lo: 0x84, hi: 0x84},\n\t{value: 0x0365, lo: 0x85, hi: 0x85},\n\t{value: 0xe00d, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0xe00d, lo: 0x88, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x89},\n\t{value: 0xe00d, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe00d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0x8d},\n\t{value: 0xe00d, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0xbf},\n\t// Block 0x2, offset 0x19\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0249, lo: 0xb0, hi: 0xb0},\n\t{value: 0x037d, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0259, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0269, lo: 0xb3, hi: 0xb3},\n\t{value: 0x034d, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0395, lo: 0xb5, hi: 0xb5},\n\t{value: 0xe1bd, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0279, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0289, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbf},\n\t// Block 0x3, offset 0x25\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x3308, lo: 0x80, hi: 0xbf},\n\t// Block 0x4, offset 0x27\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x03f5, lo: 0x80, hi: 0x8f},\n\t{value: 0xe105, lo: 0x90, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x5, offset 0x2c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x0545, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x0008, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x6, offset 0x33\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0401, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0018, lo: 0x89, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x7, offset 0x3e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0818, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x82},\n\t{value: 0x0818, lo: 0x83, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x85},\n\t{value: 0x0818, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xae},\n\t{value: 0x0808, lo: 0xaf, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x8, offset 0x4a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0a08, lo: 0x80, hi: 0x87},\n\t{value: 0x0c08, lo: 0x88, hi: 0x99},\n\t{value: 0x0a08, lo: 0x9a, hi: 0xbf},\n\t// Block 0x9, offset 0x4e\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3308, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0c08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0a08, lo: 0x8e, hi: 0x98},\n\t{value: 0x0c08, lo: 0x99, hi: 0x9b},\n\t{value: 0x0a08, lo: 0x9c, hi: 0xaa},\n\t{value: 0x0c08, lo: 0xab, hi: 0xac},\n\t{value: 0x0a08, lo: 0xad, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0a08, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0a08, lo: 0xb5, hi: 0xb7},\n\t{value: 0x0c08, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbf},\n\t// Block 0xa, offset 0x5d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xb0},\n\t{value: 0x0808, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xb, offset 0x62\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0808, lo: 0x80, hi: 0x89},\n\t{value: 0x0a08, lo: 0x8a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0818, lo: 0xbe, hi: 0xbf},\n\t// Block 0xc, offset 0x6c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x99},\n\t{value: 0x0808, lo: 0x9a, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa3},\n\t{value: 0x0808, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa7},\n\t{value: 0x0808, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0818, lo: 0xb0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd, offset 0x78\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0a08, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0c08, lo: 0xaa, hi: 0xac},\n\t{value: 0x0808, lo: 0xad, hi: 0xad},\n\t{value: 0x0c08, lo: 0xae, hi: 0xae},\n\t{value: 0x0a08, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0c08, lo: 0xb1, hi: 0xb2},\n\t{value: 0x0a08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0a08, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0c08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0a08, lo: 0xba, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xe, offset 0x86\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0xa1},\n\t{value: 0x0840, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xbf},\n\t// Block 0xf, offset 0x8b\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x10, offset 0x94\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x85},\n\t{value: 0x3008, lo: 0x86, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8c},\n\t{value: 0x3b08, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x11, offset 0xa4\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x12, offset 0xb2\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0xba},\n\t{value: 0x3b08, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x13, offset 0xbe\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x14, offset 0xca\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x89},\n\t{value: 0x3b08, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x3008, lo: 0x98, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x15, offset 0xdb\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb2},\n\t{value: 0x08f1, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb9},\n\t{value: 0x3b08, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0x16, offset 0xe5\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0xbf},\n\t// Block 0x17, offset 0xec\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0961, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0999, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0008, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x18, offset 0xf9\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0x8b},\n\t{value: 0xe03d, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x19, offset 0x10a\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0x1a, offset 0x111\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x1b, offset 0x11c\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3008, lo: 0xa2, hi: 0xa4},\n\t{value: 0x0008, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xbf},\n\t// Block 0x1c, offset 0x12b\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x8c},\n\t{value: 0x3308, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x3008, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x3008, lo: 0x9a, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0x1d, offset 0x139\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0040, lo: 0x80, hi: 0x86},\n\t{value: 0x055d, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8c},\n\t{value: 0x055d, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe105, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x1e, offset 0x143\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0018, lo: 0x80, hi: 0xbf},\n\t// Block 0x1f, offset 0x145\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa0},\n\t{value: 0x2018, lo: 0xa1, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x20, offset 0x14a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa7},\n\t{value: 0x2018, lo: 0xa8, hi: 0xbf},\n\t// Block 0x21, offset 0x14d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x2018, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0xbf},\n\t// Block 0x22, offset 0x150\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0008, lo: 0x80, hi: 0xbf},\n\t// Block 0x23, offset 0x152\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x99},\n\t{value: 0x0008, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x24, offset 0x15e\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x25, offset 0x169\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x26, offset 0x171\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0x0008, lo: 0x92, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbf},\n\t// Block 0x27, offset 0x177\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x28, offset 0x17d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x29, offset 0x182\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x2a, offset 0x187\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x2b, offset 0x18a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xbf},\n\t// Block 0x2c, offset 0x18e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x2d, offset 0x194\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x2e, offset 0x199\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x3b08, lo: 0x94, hi: 0x94},\n\t{value: 0x0040, lo: 0x95, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x2f, offset 0x1a5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x30, offset 0x1af\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xb3},\n\t{value: 0x3340, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x31, offset 0x1b5\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x3008, lo: 0x80, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x3008, lo: 0x87, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x91},\n\t{value: 0x3b08, lo: 0x92, hi: 0x92},\n\t{value: 0x3308, lo: 0x93, hi: 0x93},\n\t{value: 0x0018, lo: 0x94, hi: 0x96},\n\t{value: 0x0008, lo: 0x97, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x32, offset 0x1c6\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x86},\n\t{value: 0x0218, lo: 0x87, hi: 0x87},\n\t{value: 0x0018, lo: 0x88, hi: 0x8a},\n\t{value: 0x33c0, lo: 0x8b, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0208, lo: 0xa0, hi: 0xbf},\n\t// Block 0x33, offset 0x1d0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0208, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0x34, offset 0x1d3\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0208, lo: 0x87, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0208, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x35, offset 0x1db\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x36, offset 0x1de\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3308, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x37, offset 0x1eb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0x80},\n\t{value: 0x0040, lo: 0x81, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x38, offset 0x1f3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x39, offset 0x1f7\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0028, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xbf},\n\t// Block 0x3a, offset 0x1fe\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x3308, lo: 0x97, hi: 0x98},\n\t{value: 0x3008, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x3b, offset 0x206\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x94},\n\t{value: 0x3008, lo: 0x95, hi: 0x95},\n\t{value: 0x3308, lo: 0x96, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xac},\n\t{value: 0x3008, lo: 0xad, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3c, offset 0x216\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xbd},\n\t{value: 0x3318, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x3d, offset 0x222\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0040, lo: 0x80, hi: 0xbf},\n\t// Block 0x3e, offset 0x224\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3008, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbf},\n\t// Block 0x3f, offset 0x22e\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x3808, lo: 0x84, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x40, offset 0x23a\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3808, lo: 0xaa, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xbf},\n\t// Block 0x41, offset 0x246\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa9},\n\t{value: 0x3008, lo: 0xaa, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3808, lo: 0xb2, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbf},\n\t// Block 0x42, offset 0x252\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbf},\n\t// Block 0x43, offset 0x25a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x44, offset 0x25f\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0e29, lo: 0x80, hi: 0x80},\n\t{value: 0x0e41, lo: 0x81, hi: 0x81},\n\t{value: 0x0e59, lo: 0x82, hi: 0x82},\n\t{value: 0x0e71, lo: 0x83, hi: 0x83},\n\t{value: 0x0e89, lo: 0x84, hi: 0x85},\n\t{value: 0x0ea1, lo: 0x86, hi: 0x86},\n\t{value: 0x0eb9, lo: 0x87, hi: 0x87},\n\t{value: 0x057d, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x059d, lo: 0x90, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbc},\n\t{value: 0x059d, lo: 0xbd, hi: 0xbf},\n\t// Block 0x45, offset 0x26c\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x92},\n\t{value: 0x0018, lo: 0x93, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0xa0},\n\t{value: 0x3008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa8},\n\t{value: 0x0008, lo: 0xa9, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x0008, lo: 0xae, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x46, offset 0x27d\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0x47, offset 0x281\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x87},\n\t{value: 0xe045, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0xe045, lo: 0x98, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0xe045, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb7},\n\t{value: 0xe045, lo: 0xb8, hi: 0xbf},\n\t// Block 0x48, offset 0x28c\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x3318, lo: 0x90, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbf},\n\t// Block 0x49, offset 0x290\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x24c1, lo: 0x89, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x4a, offset 0x299\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x24f1, lo: 0xac, hi: 0xac},\n\t{value: 0x2529, lo: 0xad, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xae},\n\t{value: 0x2579, lo: 0xaf, hi: 0xaf},\n\t{value: 0x25b1, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x4b, offset 0x2a1\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x9f},\n\t{value: 0x0080, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xad},\n\t{value: 0x0080, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x4c, offset 0x2a7\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xa8},\n\t{value: 0x09dd, lo: 0xa9, hi: 0xa9},\n\t{value: 0x09fd, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xbf},\n\t// Block 0x4d, offset 0x2ac\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xbf},\n\t// Block 0x4e, offset 0x2af\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x28c1, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x4f, offset 0x2b3\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0e7e, lo: 0xb4, hi: 0xb4},\n\t{value: 0x292a, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0e9e, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x50, offset 0x2b9\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x9b},\n\t{value: 0x2941, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0xbf},\n\t// Block 0x51, offset 0x2bd\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0x52, offset 0x2c1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0018, lo: 0x98, hi: 0xbf},\n\t// Block 0x53, offset 0x2c5\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0xe185, lo: 0x80, hi: 0x8f},\n\t{value: 0x03f5, lo: 0x90, hi: 0x9f},\n\t{value: 0x0ebd, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x54, offset 0x2cb\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x55, offset 0x2d3\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xae},\n\t{value: 0xe075, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0040, lo: 0xb1, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0x56, offset 0x2da\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x57, offset 0x2e5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xbf},\n\t// Block 0x58, offset 0x2ef\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x59, offset 0x2f3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0x5a, offset 0x2f6\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9e},\n\t{value: 0x0ef5, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x5b, offset 0x2fc\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb2},\n\t{value: 0x0f15, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x5c, offset 0x300\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x0f35, lo: 0x80, hi: 0xbf},\n\t// Block 0x5d, offset 0x302\n\t{value: 0x0020, lo: 0x02},\n\t{value: 0x1735, lo: 0x80, hi: 0x8f},\n\t{value: 0x1915, lo: 0x90, hi: 0xbf},\n\t// Block 0x5e, offset 0x305\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x1f15, lo: 0x80, hi: 0xbf},\n\t// Block 0x5f, offset 0x307\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0xbf},\n\t// Block 0x60, offset 0x30a\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9a},\n\t{value: 0x29e2, lo: 0x9b, hi: 0x9b},\n\t{value: 0x2a0a, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9e},\n\t{value: 0x2a31, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xbf},\n\t// Block 0x61, offset 0x314\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbe},\n\t{value: 0x2a69, lo: 0xbf, hi: 0xbf},\n\t// Block 0x62, offset 0x317\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0040, lo: 0x80, hi: 0x84},\n\t{value: 0x0008, lo: 0x85, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xb0},\n\t{value: 0x2a35, lo: 0xb1, hi: 0xb1},\n\t{value: 0x2a55, lo: 0xb2, hi: 0xb2},\n\t{value: 0x2a75, lo: 0xb3, hi: 0xb3},\n\t{value: 0x2a95, lo: 0xb4, hi: 0xb4},\n\t{value: 0x2a75, lo: 0xb5, hi: 0xb5},\n\t{value: 0x2ab5, lo: 0xb6, hi: 0xb6},\n\t{value: 0x2ad5, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2af5, lo: 0xb8, hi: 0xb9},\n\t{value: 0x2b15, lo: 0xba, hi: 0xbb},\n\t{value: 0x2b35, lo: 0xbc, hi: 0xbd},\n\t{value: 0x2b15, lo: 0xbe, hi: 0xbf},\n\t// Block 0x63, offset 0x326\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x64, offset 0x32a\n\t{value: 0x0030, lo: 0x04},\n\t{value: 0x2aa2, lo: 0x80, hi: 0x9d},\n\t{value: 0x305a, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x30a2, lo: 0xa0, hi: 0xbf},\n\t// Block 0x65, offset 0x32f\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x66, offset 0x332\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0040, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x67, offset 0x336\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0x68, offset 0x33b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x69, offset 0x340\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0018, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6a, offset 0x346\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0040, lo: 0x80, hi: 0x81},\n\t{value: 0xe00d, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x83},\n\t{value: 0x03f5, lo: 0x84, hi: 0x84},\n\t{value: 0x1329, lo: 0x85, hi: 0x85},\n\t{value: 0x447d, lo: 0x86, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xb7},\n\t{value: 0x2009, lo: 0xb8, hi: 0xb8},\n\t{value: 0x6e89, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xbf},\n\t// Block 0x6b, offset 0x352\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0008, lo: 0x80, hi: 0x81},\n\t{value: 0x3308, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x3308, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0008, lo: 0x8c, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3008, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0018, lo: 0xa8, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x6c, offset 0x361\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0208, lo: 0x80, hi: 0xb1},\n\t{value: 0x0108, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0008, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0x6d, offset 0x367\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xbf},\n\t// Block 0x6e, offset 0x36b\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x3008, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8d},\n\t{value: 0x0018, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0018, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0x6f, offset 0x37a\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x70, offset 0x37f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x91},\n\t{value: 0x3008, lo: 0x92, hi: 0x92},\n\t{value: 0x3808, lo: 0x93, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0x71, offset 0x387\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x3008, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb9},\n\t{value: 0x3008, lo: 0xba, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x72, offset 0x391\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x73, offset 0x39c\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xa8},\n\t{value: 0x3308, lo: 0xa9, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x74, offset 0x3a4\n\t{value: 0x0000, lo: 0x10},\n\t{value: 0x0008, lo: 0x80, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8c},\n\t{value: 0x3008, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbc},\n\t{value: 0x3008, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0008, lo: 0xbe, hi: 0xbf},\n\t// Block 0x75, offset 0x3b5\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb0},\n\t{value: 0x0008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb4},\n\t{value: 0x0008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0008, lo: 0xb9, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbf},\n\t// Block 0x76, offset 0x3be\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x9a},\n\t{value: 0x0008, lo: 0x9b, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xaa},\n\t{value: 0x3008, lo: 0xab, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3b08, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x77, offset 0x3ce\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x88},\n\t{value: 0x0008, lo: 0x89, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x90},\n\t{value: 0x0008, lo: 0x91, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x78, offset 0x3db\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x449d, lo: 0x9c, hi: 0x9c},\n\t{value: 0x44b5, lo: 0x9d, hi: 0x9d},\n\t{value: 0x2971, lo: 0x9e, hi: 0x9e},\n\t{value: 0xe06d, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x44cd, lo: 0xb0, hi: 0xbf},\n\t// Block 0x79, offset 0x3e5\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x44ed, lo: 0x80, hi: 0x8f},\n\t{value: 0x450d, lo: 0x90, hi: 0x9f},\n\t{value: 0x452d, lo: 0xa0, hi: 0xaf},\n\t{value: 0x450d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7a, offset 0x3ea\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0xa2},\n\t{value: 0x3008, lo: 0xa3, hi: 0xa4},\n\t{value: 0x3308, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa7},\n\t{value: 0x3308, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xaa},\n\t{value: 0x0018, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3b08, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0x7b, offset 0x3f7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x7c, offset 0x3fb\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x7d, offset 0x400\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x454d, lo: 0x80, hi: 0xbf},\n\t// Block 0x7e, offset 0x402\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x4d4d, lo: 0x80, hi: 0x94},\n\t{value: 0x4b0d, lo: 0x95, hi: 0x95},\n\t{value: 0x4fed, lo: 0x96, hi: 0xbf},\n\t// Block 0x7f, offset 0x406\n\t{value: 0x0020, lo: 0x01},\n\t{value: 0x552d, lo: 0x80, hi: 0xbf},\n\t// Block 0x80, offset 0x408\n\t{value: 0x0020, lo: 0x03},\n\t{value: 0x5d2d, lo: 0x80, hi: 0x84},\n\t{value: 0x568d, lo: 0x85, hi: 0x85},\n\t{value: 0x5dcd, lo: 0x86, hi: 0xbf},\n\t// Block 0x81, offset 0x40c\n\t{value: 0x0020, lo: 0x08},\n\t{value: 0x6b8d, lo: 0x80, hi: 0x8f},\n\t{value: 0x6d4d, lo: 0x90, hi: 0x90},\n\t{value: 0x6d8d, lo: 0x91, hi: 0xab},\n\t{value: 0x6ea1, lo: 0xac, hi: 0xac},\n\t{value: 0x70ed, lo: 0xad, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x710d, lo: 0xb0, hi: 0xbf},\n\t// Block 0x82, offset 0x415\n\t{value: 0x0020, lo: 0x05},\n\t{value: 0x730d, lo: 0x80, hi: 0xad},\n\t{value: 0x656d, lo: 0xae, hi: 0xae},\n\t{value: 0x78cd, lo: 0xaf, hi: 0xb5},\n\t{value: 0x6f8d, lo: 0xb6, hi: 0xb6},\n\t{value: 0x79ad, lo: 0xb7, hi: 0xbf},\n\t// Block 0x83, offset 0x41b\n\t{value: 0x0028, lo: 0x03},\n\t{value: 0x7c21, lo: 0x80, hi: 0x82},\n\t{value: 0x7be1, lo: 0x83, hi: 0x83},\n\t{value: 0x7c99, lo: 0x84, hi: 0xbf},\n\t// Block 0x84, offset 0x41f\n\t{value: 0x0038, lo: 0x0f},\n\t{value: 0x9db1, lo: 0x80, hi: 0x83},\n\t{value: 0x9e59, lo: 0x84, hi: 0x85},\n\t{value: 0x9e91, lo: 0x86, hi: 0x87},\n\t{value: 0x9ec9, lo: 0x88, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x91},\n\t{value: 0xa089, lo: 0x92, hi: 0x97},\n\t{value: 0xa1a1, lo: 0x98, hi: 0x9c},\n\t{value: 0xa281, lo: 0x9d, hi: 0xb3},\n\t{value: 0x9d41, lo: 0xb4, hi: 0xb4},\n\t{value: 0x9db1, lo: 0xb5, hi: 0xb5},\n\t{value: 0xa789, lo: 0xb6, hi: 0xbb},\n\t{value: 0xa869, lo: 0xbc, hi: 0xbc},\n\t{value: 0xa7f9, lo: 0xbd, hi: 0xbd},\n\t{value: 0xa8d9, lo: 0xbe, hi: 0xbf},\n\t// Block 0x85, offset 0x42f\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0008, lo: 0x8d, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0008, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0x86, offset 0x439\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0x87, offset 0x43e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x88, offset 0x441\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0x89, offset 0x447\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x8a, offset 0x44e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0x8b, offset 0x453\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9c},\n\t{value: 0x0040, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x8c, offset 0x457\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x0040, lo: 0x91, hi: 0x9f},\n\t{value: 0x3308, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x8d, offset 0x45d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xac},\n\t{value: 0x0008, lo: 0xad, hi: 0xbf},\n\t// Block 0x8e, offset 0x462\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x81},\n\t{value: 0x0008, lo: 0x82, hi: 0x89},\n\t{value: 0x0018, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x8f, offset 0x46b\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x90, offset 0x470\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x91, offset 0x476\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x97},\n\t{value: 0x8b0d, lo: 0x98, hi: 0x9f},\n\t{value: 0x8b25, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0008, lo: 0xa8, hi: 0xbf},\n\t// Block 0x92, offset 0x47d\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x8b25, lo: 0xb0, hi: 0xb7},\n\t{value: 0x8b0d, lo: 0xb8, hi: 0xbf},\n\t// Block 0x93, offset 0x484\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0xe145, lo: 0x80, hi: 0x87},\n\t{value: 0xe1c5, lo: 0x88, hi: 0x8f},\n\t{value: 0xe145, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0x94, offset 0x48b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x95, offset 0x48f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xae},\n\t{value: 0x0018, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x96, offset 0x494\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0x97, offset 0x497\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xbf},\n\t// Block 0x98, offset 0x49c\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0808, lo: 0x80, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x87},\n\t{value: 0x0808, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0808, lo: 0x8a, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0808, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbb},\n\t{value: 0x0808, lo: 0xbc, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbe},\n\t{value: 0x0808, lo: 0xbf, hi: 0xbf},\n\t// Block 0x99, offset 0x4a8\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x96},\n\t{value: 0x0818, lo: 0x97, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0818, lo: 0xb7, hi: 0xbf},\n\t// Block 0x9a, offset 0x4ae\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xa6},\n\t{value: 0x0818, lo: 0xa7, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0x9b, offset 0x4b3\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0808, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xba},\n\t{value: 0x0818, lo: 0xbb, hi: 0xbf},\n\t// Block 0x9c, offset 0x4ba\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0818, lo: 0x96, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0818, lo: 0xbf, hi: 0xbf},\n\t// Block 0x9d, offset 0x4c2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0808, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbb},\n\t{value: 0x0818, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0808, lo: 0xbe, hi: 0xbf},\n\t// Block 0x9e, offset 0x4c7\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0818, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x0818, lo: 0x92, hi: 0xbf},\n\t// Block 0x9f, offset 0x4cb\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x0808, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0x84},\n\t{value: 0x3308, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8b},\n\t{value: 0x3308, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x94},\n\t{value: 0x0808, lo: 0x95, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x98},\n\t{value: 0x0808, lo: 0x99, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xa0, offset 0x4db\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0818, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0818, lo: 0x90, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xbc},\n\t{value: 0x0818, lo: 0xbd, hi: 0xbf},\n\t// Block 0xa1, offset 0x4e2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xa2, offset 0x4e6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb8},\n\t{value: 0x0018, lo: 0xb9, hi: 0xbf},\n\t// Block 0xa3, offset 0x4ea\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0808, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x97},\n\t{value: 0x0818, lo: 0x98, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb7},\n\t{value: 0x0818, lo: 0xb8, hi: 0xbf},\n\t// Block 0xa4, offset 0x4f1\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0808, lo: 0x80, hi: 0xbf},\n\t// Block 0xa5, offset 0x4f3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0808, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0xbf},\n\t// Block 0xa6, offset 0x4f6\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x03dd, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xa7, offset 0x4f9\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0808, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xb9},\n\t{value: 0x0818, lo: 0xba, hi: 0xbf},\n\t// Block 0xa8, offset 0x4fd\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0908, lo: 0x80, hi: 0x80},\n\t{value: 0x0a08, lo: 0x81, hi: 0xa1},\n\t{value: 0x0c08, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0a08, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3308, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0808, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xa9, offset 0x506\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0818, lo: 0xa0, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xaa, offset 0x50a\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0808, lo: 0x80, hi: 0x9c},\n\t{value: 0x0818, lo: 0x9d, hi: 0xa6},\n\t{value: 0x0808, lo: 0xa7, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0a08, lo: 0xb0, hi: 0xb2},\n\t{value: 0x0c08, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0a08, lo: 0xb4, hi: 0xbf},\n\t// Block 0xab, offset 0x512\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0a08, lo: 0x80, hi: 0x84},\n\t{value: 0x0808, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x90},\n\t{value: 0x0a18, lo: 0x91, hi: 0x93},\n\t{value: 0x0c18, lo: 0x94, hi: 0x94},\n\t{value: 0x0818, lo: 0x95, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xac, offset 0x51a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0808, lo: 0xa0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xad, offset 0x51e\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xae, offset 0x524\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x85},\n\t{value: 0x3b08, lo: 0x86, hi: 0x86},\n\t{value: 0x0018, lo: 0x87, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x91},\n\t{value: 0x0018, lo: 0x92, hi: 0xa5},\n\t{value: 0x0008, lo: 0xa6, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xaf, offset 0x52d\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb6},\n\t{value: 0x3008, lo: 0xb7, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbd},\n\t{value: 0x0018, lo: 0xbe, hi: 0xbf},\n\t// Block 0xb0, offset 0x539\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb1, offset 0x540\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xb2},\n\t{value: 0x3b08, lo: 0xb3, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xbf},\n\t// Block 0xb2, offset 0x549\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x0018, lo: 0xb4, hi: 0xb5},\n\t{value: 0x0008, lo: 0xb6, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xb3, offset 0x553\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x3308, lo: 0x80, hi: 0x81},\n\t{value: 0x3008, lo: 0x82, hi: 0x82},\n\t{value: 0x0008, lo: 0x83, hi: 0xb2},\n\t{value: 0x3008, lo: 0xb3, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xbe},\n\t{value: 0x3008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb4, offset 0x55a\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x3808, lo: 0x80, hi: 0x80},\n\t{value: 0x0008, lo: 0x81, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x88},\n\t{value: 0x3308, lo: 0x89, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0018, lo: 0xa1, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xb5, offset 0x568\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3008, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3308, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3808, lo: 0xb5, hi: 0xb5},\n\t{value: 0x3308, lo: 0xb6, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3308, lo: 0xbe, hi: 0xbe},\n\t{value: 0x0040, lo: 0xbf, hi: 0xbf},\n\t// Block 0xb6, offset 0x575\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0040, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0008, lo: 0x8f, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xb7, offset 0x582\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x3308, lo: 0x9f, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa9},\n\t{value: 0x3b08, lo: 0xaa, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbf},\n\t// Block 0xb8, offset 0x58b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbf},\n\t// Block 0xb9, offset 0x58f\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0x3008, lo: 0x80, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x84},\n\t{value: 0x3008, lo: 0x85, hi: 0x85},\n\t{value: 0x3308, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x8a},\n\t{value: 0x0018, lo: 0x8b, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0x9b},\n\t{value: 0x0040, lo: 0x9c, hi: 0x9c},\n\t{value: 0x0018, lo: 0x9d, hi: 0x9d},\n\t{value: 0x3308, lo: 0x9e, hi: 0x9e},\n\t{value: 0x0008, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xba, offset 0x59f\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbb, offset 0x5a7\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x3008, lo: 0x81, hi: 0x81},\n\t{value: 0x3b08, lo: 0x82, hi: 0x82},\n\t{value: 0x3308, lo: 0x83, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x85},\n\t{value: 0x0018, lo: 0x86, hi: 0x86},\n\t{value: 0x0008, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xbc, offset 0x5b2\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbd, offset 0x5bb\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x9b},\n\t{value: 0x3308, lo: 0x9c, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0xbf},\n\t// Block 0xbe, offset 0x5c1\n\t{value: 0x0000, lo: 0x07},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3008, lo: 0xb0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xba},\n\t{value: 0x3008, lo: 0xbb, hi: 0xbc},\n\t{value: 0x3308, lo: 0xbd, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xbf, offset 0x5c9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x3308, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x83},\n\t{value: 0x0008, lo: 0x84, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0xc0, offset 0x5d2\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x3308, lo: 0xab, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xac},\n\t{value: 0x3308, lo: 0xad, hi: 0xad},\n\t{value: 0x3008, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb5},\n\t{value: 0x3808, lo: 0xb6, hi: 0xb6},\n\t{value: 0x3308, lo: 0xb7, hi: 0xb7},\n\t{value: 0x0008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xc1, offset 0x5dd\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0xbf},\n\t// Block 0xc2, offset 0x5e0\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9f},\n\t{value: 0x3008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x3308, lo: 0xa2, hi: 0xa5},\n\t{value: 0x3008, lo: 0xa6, hi: 0xa6},\n\t{value: 0x3308, lo: 0xa7, hi: 0xaa},\n\t{value: 0x3b08, lo: 0xab, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0xc3, offset 0x5ec\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3008, lo: 0xac, hi: 0xae},\n\t{value: 0x3308, lo: 0xaf, hi: 0xb7},\n\t{value: 0x3008, lo: 0xb8, hi: 0xb8},\n\t{value: 0x3b08, lo: 0xb9, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0018, lo: 0xbb, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xc4, offset 0x5f5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x049d, lo: 0xa0, hi: 0xbf},\n\t// Block 0xc5, offset 0x5f8\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbe},\n\t{value: 0x0008, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc6, offset 0x5fd\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xc7, offset 0x602\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0x93},\n\t{value: 0x3308, lo: 0x94, hi: 0x97},\n\t{value: 0x0040, lo: 0x98, hi: 0x99},\n\t{value: 0x3308, lo: 0x9a, hi: 0x9b},\n\t{value: 0x3008, lo: 0x9c, hi: 0x9f},\n\t{value: 0x3b08, lo: 0xa0, hi: 0xa0},\n\t{value: 0x0008, lo: 0xa1, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x3008, lo: 0xa4, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xbf},\n\t// Block 0xc8, offset 0x60f\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x3308, lo: 0x81, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb3},\n\t{value: 0x3b08, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb8},\n\t{value: 0x3008, lo: 0xb9, hi: 0xb9},\n\t{value: 0x0008, lo: 0xba, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xc9, offset 0x61a\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x86},\n\t{value: 0x3b08, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3308, lo: 0x91, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x98},\n\t{value: 0x3308, lo: 0x99, hi: 0x9b},\n\t{value: 0x0008, lo: 0x9c, hi: 0xbf},\n\t// Block 0xca, offset 0x623\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3308, lo: 0x8a, hi: 0x96},\n\t{value: 0x3008, lo: 0x97, hi: 0x97},\n\t{value: 0x3308, lo: 0x98, hi: 0x98},\n\t{value: 0x3b08, lo: 0x99, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0x9c},\n\t{value: 0x0008, lo: 0x9d, hi: 0x9d},\n\t{value: 0x0018, lo: 0x9e, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xbf},\n\t// Block 0xcb, offset 0x62d\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xcc, offset 0x630\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x89},\n\t{value: 0x0008, lo: 0x8a, hi: 0xae},\n\t{value: 0x3008, lo: 0xaf, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb7},\n\t{value: 0x3308, lo: 0xb8, hi: 0xbd},\n\t{value: 0x3008, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3b08, lo: 0xbf, hi: 0xbf},\n\t// Block 0xcd, offset 0x63a\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0008, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0018, lo: 0x9a, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0008, lo: 0xb2, hi: 0xbf},\n\t// Block 0xce, offset 0x643\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x91},\n\t{value: 0x3308, lo: 0x92, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xa8},\n\t{value: 0x3008, lo: 0xa9, hi: 0xa9},\n\t{value: 0x3308, lo: 0xaa, hi: 0xb0},\n\t{value: 0x3008, lo: 0xb1, hi: 0xb1},\n\t{value: 0x3308, lo: 0xb2, hi: 0xb3},\n\t{value: 0x3008, lo: 0xb4, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xbf},\n\t// Block 0xcf, offset 0x64f\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x0008, lo: 0x88, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8a},\n\t{value: 0x0008, lo: 0x8b, hi: 0xb0},\n\t{value: 0x3308, lo: 0xb1, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x3308, lo: 0xba, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbb},\n\t{value: 0x3308, lo: 0xbc, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbe},\n\t{value: 0x3308, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd0, offset 0x65c\n\t{value: 0x0000, lo: 0x0c},\n\t{value: 0x3308, lo: 0x80, hi: 0x83},\n\t{value: 0x3b08, lo: 0x84, hi: 0x85},\n\t{value: 0x0008, lo: 0x86, hi: 0x86},\n\t{value: 0x3308, lo: 0x87, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xa6},\n\t{value: 0x0008, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xa9},\n\t{value: 0x0008, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd1, offset 0x669\n\t{value: 0x0000, lo: 0x0d},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x3008, lo: 0x8a, hi: 0x8e},\n\t{value: 0x0040, lo: 0x8f, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x92},\n\t{value: 0x3008, lo: 0x93, hi: 0x94},\n\t{value: 0x3308, lo: 0x95, hi: 0x95},\n\t{value: 0x3008, lo: 0x96, hi: 0x96},\n\t{value: 0x3b08, lo: 0x97, hi: 0x97},\n\t{value: 0x0008, lo: 0x98, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xbf},\n\t// Block 0xd2, offset 0x677\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xb2},\n\t{value: 0x3308, lo: 0xb3, hi: 0xb4},\n\t{value: 0x3008, lo: 0xb5, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd3, offset 0x67e\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xd4, offset 0x682\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0xbf},\n\t// Block 0xd5, offset 0x685\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xd6, offset 0x68a\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0040, lo: 0x84, hi: 0xbf},\n\t// Block 0xd7, offset 0x68d\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xaf},\n\t{value: 0x0340, lo: 0xb0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xd8, offset 0x692\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0xbf},\n\t// Block 0xd9, offset 0x695\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa9},\n\t{value: 0x0040, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xda, offset 0x69c\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb4},\n\t{value: 0x0018, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xdb, offset 0x6a3\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xbf},\n\t// Block 0xdc, offset 0x6a7\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x0008, lo: 0x80, hi: 0x83},\n\t{value: 0x0018, lo: 0x84, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9a},\n\t{value: 0x0018, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbc},\n\t{value: 0x0008, lo: 0xbd, hi: 0xbf},\n\t// Block 0xdd, offset 0x6b2\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xde, offset 0x6b5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0xe105, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0xdf, offset 0x6b8\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0x9a},\n\t{value: 0x0040, lo: 0x9b, hi: 0xbf},\n\t// Block 0xe0, offset 0x6bb\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x90},\n\t{value: 0x3008, lo: 0x91, hi: 0xbf},\n\t// Block 0xe1, offset 0x6c1\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x3008, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8e},\n\t{value: 0x3308, lo: 0x8f, hi: 0x92},\n\t{value: 0x0008, lo: 0x93, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xe2, offset 0x6c7\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xa1},\n\t{value: 0x0018, lo: 0xa2, hi: 0xa2},\n\t{value: 0x0008, lo: 0xa3, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xe3, offset 0x6cd\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb7},\n\t{value: 0x0040, lo: 0xb8, hi: 0xbf},\n\t// Block 0xe4, offset 0x6d0\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb2},\n\t{value: 0x0040, lo: 0xb3, hi: 0xbf},\n\t// Block 0xe5, offset 0x6d3\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x9e},\n\t{value: 0x0040, lo: 0x9f, hi: 0xbf},\n\t// Block 0xe6, offset 0x6d6\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0040, lo: 0x80, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x92},\n\t{value: 0x0040, lo: 0x93, hi: 0xa3},\n\t{value: 0x0008, lo: 0xa4, hi: 0xa7},\n\t{value: 0x0040, lo: 0xa8, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0xe7, offset 0x6dd\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xbb},\n\t{value: 0x0040, lo: 0xbc, hi: 0xbf},\n\t// Block 0xe8, offset 0x6e0\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0008, lo: 0x80, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbc},\n\t{value: 0x0040, lo: 0xbd, hi: 0xbf},\n\t// Block 0xe9, offset 0x6e5\n\t{value: 0x0000, lo: 0x09},\n\t{value: 0x0008, lo: 0x80, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0x0008, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9b},\n\t{value: 0x0018, lo: 0x9c, hi: 0x9c},\n\t{value: 0x3308, lo: 0x9d, hi: 0x9e},\n\t{value: 0x0018, lo: 0x9f, hi: 0x9f},\n\t{value: 0x03c0, lo: 0xa0, hi: 0xa3},\n\t{value: 0x0040, lo: 0xa4, hi: 0xbf},\n\t// Block 0xea, offset 0x6ef\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0xeb, offset 0x6f2\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xa6},\n\t{value: 0x0040, lo: 0xa7, hi: 0xa8},\n\t{value: 0x0018, lo: 0xa9, hi: 0xbf},\n\t// Block 0xec, offset 0x6f6\n\t{value: 0x0000, lo: 0x0e},\n\t{value: 0x0018, lo: 0x80, hi: 0x9d},\n\t{value: 0xb5b9, lo: 0x9e, hi: 0x9e},\n\t{value: 0xb601, lo: 0x9f, hi: 0x9f},\n\t{value: 0xb649, lo: 0xa0, hi: 0xa0},\n\t{value: 0xb6b1, lo: 0xa1, hi: 0xa1},\n\t{value: 0xb719, lo: 0xa2, hi: 0xa2},\n\t{value: 0xb781, lo: 0xa3, hi: 0xa3},\n\t{value: 0xb7e9, lo: 0xa4, hi: 0xa4},\n\t{value: 0x3018, lo: 0xa5, hi: 0xa6},\n\t{value: 0x3318, lo: 0xa7, hi: 0xa9},\n\t{value: 0x0018, lo: 0xaa, hi: 0xac},\n\t{value: 0x3018, lo: 0xad, hi: 0xb2},\n\t{value: 0x0340, lo: 0xb3, hi: 0xba},\n\t{value: 0x3318, lo: 0xbb, hi: 0xbf},\n\t// Block 0xed, offset 0x705\n\t{value: 0x0000, lo: 0x0b},\n\t{value: 0x3318, lo: 0x80, hi: 0x82},\n\t{value: 0x0018, lo: 0x83, hi: 0x84},\n\t{value: 0x3318, lo: 0x85, hi: 0x8b},\n\t{value: 0x0018, lo: 0x8c, hi: 0xa9},\n\t{value: 0x3318, lo: 0xaa, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xba},\n\t{value: 0xb851, lo: 0xbb, hi: 0xbb},\n\t{value: 0xb899, lo: 0xbc, hi: 0xbc},\n\t{value: 0xb8e1, lo: 0xbd, hi: 0xbd},\n\t{value: 0xb949, lo: 0xbe, hi: 0xbe},\n\t{value: 0xb9b1, lo: 0xbf, hi: 0xbf},\n\t// Block 0xee, offset 0x711\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0xba19, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0xa8},\n\t{value: 0x0040, lo: 0xa9, hi: 0xbf},\n\t// Block 0xef, offset 0x715\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x81},\n\t{value: 0x3318, lo: 0x82, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x85},\n\t{value: 0x0040, lo: 0x86, hi: 0xbf},\n\t// Block 0xf0, offset 0x71a\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0xf1, offset 0x71e\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xb8},\n\t{value: 0x0040, lo: 0xb9, hi: 0xbf},\n\t// Block 0xf2, offset 0x723\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x3308, lo: 0x80, hi: 0xb6},\n\t{value: 0x0018, lo: 0xb7, hi: 0xba},\n\t{value: 0x3308, lo: 0xbb, hi: 0xbf},\n\t// Block 0xf3, offset 0x727\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x3308, lo: 0x80, hi: 0xac},\n\t{value: 0x0018, lo: 0xad, hi: 0xb4},\n\t{value: 0x3308, lo: 0xb5, hi: 0xb5},\n\t{value: 0x0018, lo: 0xb6, hi: 0xbf},\n\t// Block 0xf4, offset 0x72c\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x84},\n\t{value: 0x0018, lo: 0x85, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xa0},\n\t{value: 0x3308, lo: 0xa1, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n\t// Block 0xf5, offset 0x735\n\t{value: 0x0000, lo: 0x0a},\n\t{value: 0x3308, lo: 0x80, hi: 0x86},\n\t{value: 0x0040, lo: 0x87, hi: 0x87},\n\t{value: 0x3308, lo: 0x88, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9a},\n\t{value: 0x3308, lo: 0x9b, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xa2},\n\t{value: 0x3308, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0040, lo: 0xa5, hi: 0xa5},\n\t{value: 0x3308, lo: 0xa6, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xbf},\n\t// Block 0xf6, offset 0x740\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x3308, lo: 0xb0, hi: 0xb6},\n\t{value: 0x0008, lo: 0xb7, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xf7, offset 0x746\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0x89},\n\t{value: 0x0040, lo: 0x8a, hi: 0x8d},\n\t{value: 0x0008, lo: 0x8e, hi: 0x8e},\n\t{value: 0x0018, lo: 0x8f, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0xbf},\n\t// Block 0xf8, offset 0x74c\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0008, lo: 0x80, hi: 0xab},\n\t{value: 0x3308, lo: 0xac, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xb9},\n\t{value: 0x0040, lo: 0xba, hi: 0xbe},\n\t{value: 0x0018, lo: 0xbf, hi: 0xbf},\n\t// Block 0xf9, offset 0x752\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0808, lo: 0x80, hi: 0x84},\n\t{value: 0x0040, lo: 0x85, hi: 0x86},\n\t{value: 0x0818, lo: 0x87, hi: 0x8f},\n\t{value: 0x3308, lo: 0x90, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0xfa, offset 0x758\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0a08, lo: 0x80, hi: 0x83},\n\t{value: 0x3308, lo: 0x84, hi: 0x8a},\n\t{value: 0x0b08, lo: 0x8b, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0808, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9d},\n\t{value: 0x0818, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0040, lo: 0xa0, hi: 0xbf},\n\t// Block 0xfb, offset 0x761\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xb0},\n\t{value: 0x0818, lo: 0xb1, hi: 0xbf},\n\t// Block 0xfc, offset 0x764\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0818, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0xfd, offset 0x767\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0818, lo: 0x81, hi: 0xbd},\n\t{value: 0x0040, lo: 0xbe, hi: 0xbf},\n\t// Block 0xfe, offset 0x76b\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0040, lo: 0x80, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xbf},\n\t// Block 0xff, offset 0x76f\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xbf},\n\t// Block 0x100, offset 0x773\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xae},\n\t{value: 0x0040, lo: 0xaf, hi: 0xb0},\n\t{value: 0x0018, lo: 0xb1, hi: 0xbf},\n\t// Block 0x101, offset 0x779\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0018, lo: 0x81, hi: 0x8f},\n\t{value: 0x0040, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xb5},\n\t{value: 0x0040, lo: 0xb6, hi: 0xbf},\n\t// Block 0x102, offset 0x77f\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x8f},\n\t{value: 0xc1d9, lo: 0x90, hi: 0x90},\n\t{value: 0x0018, lo: 0x91, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xbf},\n\t// Block 0x103, offset 0x784\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0040, lo: 0x80, hi: 0xa5},\n\t{value: 0x0018, lo: 0xa6, hi: 0xbf},\n\t// Block 0x104, offset 0x787\n\t{value: 0x0000, lo: 0x0f},\n\t{value: 0xc801, lo: 0x80, hi: 0x80},\n\t{value: 0xc851, lo: 0x81, hi: 0x81},\n\t{value: 0xc8a1, lo: 0x82, hi: 0x82},\n\t{value: 0xc8f1, lo: 0x83, hi: 0x83},\n\t{value: 0xc941, lo: 0x84, hi: 0x84},\n\t{value: 0xc991, lo: 0x85, hi: 0x85},\n\t{value: 0xc9e1, lo: 0x86, hi: 0x86},\n\t{value: 0xca31, lo: 0x87, hi: 0x87},\n\t{value: 0xca81, lo: 0x88, hi: 0x88},\n\t{value: 0x0040, lo: 0x89, hi: 0x8f},\n\t{value: 0xcad1, lo: 0x90, hi: 0x90},\n\t{value: 0xcaf1, lo: 0x91, hi: 0x91},\n\t{value: 0x0040, lo: 0x92, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xa5},\n\t{value: 0x0040, lo: 0xa6, hi: 0xbf},\n\t// Block 0x105, offset 0x797\n\t{value: 0x0000, lo: 0x06},\n\t{value: 0x0018, lo: 0x80, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xac},\n\t{value: 0x0040, lo: 0xad, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x106, offset 0x79e\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0018, lo: 0x80, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xbf},\n\t// Block 0x107, offset 0x7a1\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x98},\n\t{value: 0x0040, lo: 0x99, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xab},\n\t{value: 0x0040, lo: 0xac, hi: 0xbf},\n\t// Block 0x108, offset 0x7a6\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xbf},\n\t// Block 0x109, offset 0x7aa\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x99},\n\t{value: 0x0040, lo: 0x9a, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xbf},\n\t// Block 0x10a, offset 0x7b0\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x87},\n\t{value: 0x0040, lo: 0x88, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xbf},\n\t// Block 0x10b, offset 0x7b5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8b},\n\t{value: 0x0040, lo: 0x8c, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x10c, offset 0x7b9\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xb1},\n\t{value: 0x0040, lo: 0xb2, hi: 0xb2},\n\t{value: 0x0018, lo: 0xb3, hi: 0xb6},\n\t{value: 0x0040, lo: 0xb7, hi: 0xb9},\n\t{value: 0x0018, lo: 0xba, hi: 0xbf},\n\t// Block 0x10d, offset 0x7bf\n\t{value: 0x0000, lo: 0x05},\n\t{value: 0x0018, lo: 0x80, hi: 0xa2},\n\t{value: 0x0040, lo: 0xa3, hi: 0xa4},\n\t{value: 0x0018, lo: 0xa5, hi: 0xaa},\n\t{value: 0x0040, lo: 0xab, hi: 0xad},\n\t{value: 0x0018, lo: 0xae, hi: 0xbf},\n\t// Block 0x10e, offset 0x7c5\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0018, lo: 0x80, hi: 0x8a},\n\t{value: 0x0040, lo: 0x8b, hi: 0x8c},\n\t{value: 0x0018, lo: 0x8d, hi: 0xbf},\n\t// Block 0x10f, offset 0x7c9\n\t{value: 0x0000, lo: 0x08},\n\t{value: 0x0018, lo: 0x80, hi: 0x93},\n\t{value: 0x0040, lo: 0x94, hi: 0x9f},\n\t{value: 0x0018, lo: 0xa0, hi: 0xad},\n\t{value: 0x0040, lo: 0xae, hi: 0xaf},\n\t{value: 0x0018, lo: 0xb0, hi: 0xb3},\n\t{value: 0x0040, lo: 0xb4, hi: 0xb7},\n\t{value: 0x0018, lo: 0xb8, hi: 0xba},\n\t{value: 0x0040, lo: 0xbb, hi: 0xbf},\n\t// Block 0x110, offset 0x7d2\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0018, lo: 0x80, hi: 0x82},\n\t{value: 0x0040, lo: 0x83, hi: 0x8f},\n\t{value: 0x0018, lo: 0x90, hi: 0x95},\n\t{value: 0x0040, lo: 0x96, hi: 0xbf},\n\t// Block 0x111, offset 0x7d7\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0x96},\n\t{value: 0x0040, lo: 0x97, hi: 0xbf},\n\t// Block 0x112, offset 0x7da\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xb4},\n\t{value: 0x0040, lo: 0xb5, hi: 0xbf},\n\t// Block 0x113, offset 0x7dd\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0x9d},\n\t{value: 0x0040, lo: 0x9e, hi: 0x9f},\n\t{value: 0x0008, lo: 0xa0, hi: 0xbf},\n\t// Block 0x114, offset 0x7e1\n\t{value: 0x0000, lo: 0x03},\n\t{value: 0x0008, lo: 0x80, hi: 0xa1},\n\t{value: 0x0040, lo: 0xa2, hi: 0xaf},\n\t{value: 0x0008, lo: 0xb0, hi: 0xbf},\n\t// Block 0x115, offset 0x7e5\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x0008, lo: 0x80, hi: 0xa0},\n\t{value: 0x0040, lo: 0xa1, hi: 0xbf},\n\t// Block 0x116, offset 0x7e8\n\t{value: 0x0020, lo: 0x0f},\n\t{value: 0xded1, lo: 0x80, hi: 0x89},\n\t{value: 0x8e35, lo: 0x8a, hi: 0x8a},\n\t{value: 0xe011, lo: 0x8b, hi: 0x9c},\n\t{value: 0x8e55, lo: 0x9d, hi: 0x9d},\n\t{value: 0xe251, lo: 0x9e, hi: 0xa2},\n\t{value: 0x8e75, lo: 0xa3, hi: 0xa3},\n\t{value: 0xe2f1, lo: 0xa4, hi: 0xab},\n\t{value: 0x7f0d, lo: 0xac, hi: 0xac},\n\t{value: 0xe3f1, lo: 0xad, hi: 0xaf},\n\t{value: 0x8e95, lo: 0xb0, hi: 0xb0},\n\t{value: 0xe451, lo: 0xb1, hi: 0xb6},\n\t{value: 0x8eb5, lo: 0xb7, hi: 0xb9},\n\t{value: 0xe511, lo: 0xba, hi: 0xba},\n\t{value: 0x8f15, lo: 0xbb, hi: 0xbb},\n\t{value: 0xe531, lo: 0xbc, hi: 0xbf},\n\t// Block 0x117, offset 0x7f8\n\t{value: 0x0020, lo: 0x10},\n\t{value: 0x93b5, lo: 0x80, hi: 0x80},\n\t{value: 0xf0b1, lo: 0x81, hi: 0x86},\n\t{value: 0x93d5, lo: 0x87, hi: 0x8a},\n\t{value: 0xda11, lo: 0x8b, hi: 0x8b},\n\t{value: 0xf171, lo: 0x8c, hi: 0x96},\n\t{value: 0x9455, lo: 0x97, hi: 0x97},\n\t{value: 0xf2d1, lo: 0x98, hi: 0xa3},\n\t{value: 0x9475, lo: 0xa4, hi: 0xa6},\n\t{value: 0xf451, lo: 0xa7, hi: 0xaa},\n\t{value: 0x94d5, lo: 0xab, hi: 0xab},\n\t{value: 0xf4d1, lo: 0xac, hi: 0xac},\n\t{value: 0x94f5, lo: 0xad, hi: 0xad},\n\t{value: 0xf4f1, lo: 0xae, hi: 0xaf},\n\t{value: 0x9515, lo: 0xb0, hi: 0xb1},\n\t{value: 0xf531, lo: 0xb2, hi: 0xbe},\n\t{value: 0x2040, lo: 0xbf, hi: 0xbf},\n\t// Block 0x118, offset 0x809\n\t{value: 0x0000, lo: 0x04},\n\t{value: 0x0040, lo: 0x80, hi: 0x80},\n\t{value: 0x0340, lo: 0x81, hi: 0x81},\n\t{value: 0x0040, lo: 0x82, hi: 0x9f},\n\t{value: 0x0340, lo: 0xa0, hi: 0xbf},\n\t// Block 0x119, offset 0x80e\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x0340, lo: 0x80, hi: 0xbf},\n\t// Block 0x11a, offset 0x810\n\t{value: 0x0000, lo: 0x01},\n\t{value: 0x33c0, lo: 0x80, hi: 0xbf},\n\t// Block 0x11b, offset 0x812\n\t{value: 0x0000, lo: 0x02},\n\t{value: 0x33c0, lo: 0x80, hi: 0xaf},\n\t{value: 0x0040, lo: 0xb0, hi: 0xbf},\n}\n\n// Total table size 42780 bytes (41KiB); checksum: 29936AB9\n"
  }
]